[
  {
    "path": ".config/configuration.vsEnterprise.winget",
    "content": "# yaml-language-server: $schema=https://aka.ms/configuration-dsc-schema/0.2\n# Reference: https://github.com/microsoft/winget-cli#building-the-client\nproperties:\n  resources:\n    - resource: Microsoft.Windows.Settings/WindowsSettings\n      directives:\n        description: Enable Developer Mode\n        # Requires elevation for the set operation\n        securityContext: elevated\n        allowPrerelease: true\n      settings:\n        DeveloperMode: true\n    - resource: Microsoft.WinGet.DSC/WinGetPackage\n      id: vsPackage\n      directives:\n        description: Install Visual Studio 2022 Enterprise\n        # Requires elevation for the set operation\n        securityContext: elevated\n      settings:\n        id: Microsoft.VisualStudio.2022.Enterprise\n        source: winget\n    - resource: Microsoft.VisualStudio.DSC/VSComponents\n      dependsOn:\n        - vsPackage\n      directives:\n        description: Install required VS workloads from project .vsconfig file\n        # Requires elevation for the get and set operations\n        securityContext: elevated\n        allowPrerelease: true\n      settings:\n        productId: Microsoft.VisualStudio.Product.Enterprise\n        channelId: VisualStudio.17.Release\n        vsConfigFile: '${WinGetConfigRoot}\\..\\.vsconfig'\n  configurationVersion: 0.2.0\n"
  },
  {
    "path": ".config/configuration.vsProfessional.winget",
    "content": "# yaml-language-server: $schema=https://aka.ms/configuration-dsc-schema/0.2\n# Reference: https://github.com/microsoft/winget-cli#building-the-client\nproperties:\n  resources:\n    - resource: Microsoft.Windows.Settings/WindowsSettings\n      directives:\n        description: Enable Developer Mode\n        # Requires elevation for the set operation\n        securityContext: elevated\n        allowPrerelease: true\n      settings:\n        DeveloperMode: true\n    - resource: Microsoft.WinGet.DSC/WinGetPackage\n      id: vsPackage\n      directives:\n        description: Install Visual Studio 2022 Professional\n        # Requires elevation for the set operation\n        securityContext: elevated\n      settings:\n        id: Microsoft.VisualStudio.2022.Professional\n        source: winget\n    - resource: Microsoft.VisualStudio.DSC/VSComponents\n      dependsOn:\n        - vsPackage\n      directives:\n        description: Install required VS workloads from project .vsconfig file\n        # Requires elevation for the get and set operations\n        securityContext: elevated\n        allowPrerelease: true\n      settings:\n        productId: Microsoft.VisualStudio.Product.Professional\n        channelId: VisualStudio.17.Release\n        vsConfigFile: '${WinGetConfigRoot}\\..\\.vsconfig'\n  configurationVersion: 0.2.0\n"
  },
  {
    "path": ".config/configuration.winget",
    "content": "# yaml-language-server: $schema=https://aka.ms/configuration-dsc-schema/0.2\n# Reference: https://github.com/microsoft/winget-cli#building-the-client\nproperties:\n  resources:\n    - resource: Microsoft.Windows.Settings/WindowsSettings\n      directives:\n        description: Enable Developer Mode\n        # Requires elevation for the set operation\n        securityContext: elevated\n        allowPrerelease: true\n      settings:\n        DeveloperMode: true\n    - resource: Microsoft.WinGet.DSC/WinGetPackage\n      id: vsPackage\n      directives:\n        description: Install Visual Studio 2022 Community\n        # Requires elevation for the set operation\n        securityContext: elevated\n      settings:\n        id: Microsoft.VisualStudio.2022.Community\n        source: winget\n    - resource: Microsoft.VisualStudio.DSC/VSComponents\n      dependsOn:\n        - vsPackage\n      directives:\n        description: Install required VS workloads from project .vsconfig file\n        # Requires elevation for the get and set operations\n        securityContext: elevated\n        allowPrerelease: true\n      settings:\n        productId: Microsoft.VisualStudio.Product.Community\n        channelId: VisualStudio.17.Release\n        vsConfigFile: '${WinGetConfigRoot}\\..\\.vsconfig'\n  configurationVersion: 0.2.0\n"
  },
  {
    "path": ".editorconfig",
    "content": "# top-most EditorConfig file\nroot=true\n\n# Apply Windows-style newlines with a newline ending on every file, using UTF-8, and removing extra whitespace before newlines\n[*]\nend_of_line = crlf\ninsert_final_newline = true\ncharset = utf-8\ntrim_trailing_whitespace = true\n\n# Overrides for Yaml Files - Use two spaces for indents\n# editorconfig/editorconfig#329\n[*.{yml,yaml}]\nindent_style = space\nindent_size = 2\n\n# Overrides for Markdown Files - Use tab for indents (accessibility)\n[*.md]\nindent_style = tab\n\n[{allow.txt,excludes.txt,patterns.txt,expect.txt}]\nend_of_line = lf\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/Bug_Report.yml",
    "content": "name: '🐛 Bug Report'\ndescription: Report errors or unexpected behavior.\nlabels:\n- Issue-Bug\n- Needs-Triage\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        > This bug tracker is monitored by the Windows Package Manager development team and other technical folks.\n        >\n        > **Important: When reporting BSODs or security issues, DO NOT attach memory dumps, logs, or traces to GitHub issues**.\n        > Instead, send dumps/traces to secure@microsoft.com, referencing this GitHub issue.\n        >\n        > If this is an application crash, please provide a Feedback Hub submission link if possible so we can find your diagnostic data on the backend.\n        > You can open the Feedback Hub directly to the prepopulated form at https://aka.ms/winget-feedback\n        > Alternatively, use the category \"Apps > Windows Package Manager\" and choose \"Share My Feedback\" after submission to get the link.\n        >\n        > Please use this form and describe your issue, concisely but precisely, with as much detail as possible.\n  - type: dropdown\n    attributes:\n      label: Relevant area(s)\n      description: What things had an issue? Check all that apply.\n      multiple: true\n      options:\n        - WinGet CLI\n        - PowerShell Module\n        - COM API\n        - DSC Resource\n      default: 0\n    validations:\n      required: true\n  - type: dropdown\n    attributes:\n      label: Relevant command(s)\n      description: If you selected 'WinGet CLI' above, specify the command(s) that had an issue.\n      multiple: true\n      options:\n        - winget configure\n        - winget download\n        - winget dscv3\n        - winget export\n        - winget features\n        - winget font\n        - winget hash\n        - winget import\n        - winget install\n        - winget list\n        - winget mcp\n        - winget pin\n        - winget repair\n        - winget search\n        - winget settings\n        - winget show\n        - winget source\n        - winget uninstall\n        - winget upgrade\n        - winget validate\n    validations:\n      required: false\n  - type: textarea\n    attributes:\n      label: Brief description of your issue\n      placeholder: Briefly describe your issue here.\n    validations:\n      required: true\n  - type: textarea\n    attributes:\n      label: Steps to reproduce\n      placeholder: A description of how to trigger this bug\n    validations:\n      required: true\n  - type: textarea\n    attributes:\n      label: Expected behavior\n      placeholder: What did you expect to happen?\n    validations:\n      required: true\n  - type: textarea\n    attributes:\n      label: Actual behavior\n      placeholder: What is currently happening?\n    validations:\n      required: true\n  - type: textarea\n    attributes:\n      label: Environment\n      placeholder: |\n        [winget --info]\n        Windows Package Manager version\n        Windows: Windows.Desktop version\n        Package: Microsoft.DesktopAppInstaller version\n\n        Any other software?\n      render: shell\n    validations:\n      required: true\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/Documentation_Issue.yml",
    "content": "name: '📚 Documentation Issue'\ndescription: Report issues in our documentation.\nlabels:\n- Issue-Docs\n- Needs-Triage\nbody:\n  - type: textarea\n    attributes:\n      label: Brief description of your issue\n      placeholder: Briefly describe which document needs to be corrected and why.\n    validations:\n      required: true\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/Feature_Request.yml",
    "content": "name: '🚀 Feature Request / Idea'\ndescription: Suggest a new feature or improvement (this does not mean you have to implement it).\nlabels:\n- Issue-Feature\n- Needs-Triage\nbody:\n  - type: dropdown\n    attributes:\n      label: Relevant area(s)\n      description: What area does this feature request relate to? Check all that apply.\n      multiple: true\n      options:\n        - WinGet CLI\n        - PowerShell Module\n        - COM API\n        - DSC Resource\n      default: 0\n    validations:\n      required: true\n  - type: textarea\n    attributes:\n      label: Description of the new feature / enhancement\n      placeholder: |\n        A clear and concise description of what the problem is that the new feature would solve.\n        Describe why and how a user would use this new functionality (if applicable).\n    validations:\n      required: true\n  - type: textarea\n    attributes:\n      label: Proposed technical implementation details\n      placeholder: A clear and concise description of what you want to happen.\n    validations:\n      required: false\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: true\ncontact_links:\n  - name: Package issues\n    url: https://github.com/microsoft/winget-pkgs/issues\n    about: Please create issues related to the packages here.\n  - name: General Question\n    url: https://github.com/microsoft/winget-cli/discussions/new\n    about: Have a question on something? Start a new discussion thread.\n  - name: Review open issues\n    url: https://github.com/microsoft/winget-cli/issues\n    about: Please check if your issue or a similar issue has already been submitted.\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "<!-- To check a checkbox place an \"x\" between the brackets. e.g: [x] -->\n\n- [ ] I have signed the [Contributor License Agreement](https://cla.opensource.microsoft.com/microsoft/winget-pkgs).\n- [ ] I have updated the [Release Notes](../doc/ReleaseNotes.md).\n- [ ] This pull request is related to an issue.\n\n-----\n"
  },
  {
    "path": ".github/actions/spelling/README.md",
    "content": "# check-spelling/check-spelling configuration\n\nFile | Purpose | Format | Info\n-|-|-|-\n[dictionary.txt](dictionary.txt) | Replacement dictionary (creating this file will override the default dictionary) | one word per line | [dictionary](https://github.com/check-spelling/check-spelling/wiki/Configuration#dictionary)\n[allow.txt](allow.txt) | Add words to the dictionary | one word per line (only letters and `'`s allowed) | [allow](https://github.com/check-spelling/check-spelling/wiki/Configuration#allow)\n[reject.txt](reject.txt) | Remove words from the dictionary (after allow) | grep pattern matching whole dictionary words | [reject](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-reject)\n[excludes.txt](excludes.txt) | Files to ignore entirely | perl regular expression | [excludes](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-excludes)\n[only.txt](only.txt) | Only check matching files (applied after excludes) | perl regular expression | [only](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-only)\n[patterns.txt](patterns.txt) | Patterns to ignore from checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns)\n[candidate.patterns](candidate.patterns) | Patterns that might be worth adding to [patterns.txt](patterns.txt) | perl regular expression with optional comment block introductions (all matches will be suggested) | [candidates](https://github.com/check-spelling/check-spelling/wiki/Feature:-Suggest-patterns)\n[line_forbidden.patterns](line_forbidden.patterns) | Patterns to flag in checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns)\n[expect.txt](expect.txt) | Expected words that aren't in the dictionary | one word per line (sorted, alphabetically) | [expect](https://github.com/check-spelling/check-spelling/wiki/Configuration#expect)\n[advice.md](advice.md) | Supplement for GitHub comment when unrecognized words are found | GitHub Markdown | [advice](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice)\n\nNote: you can replace any of these files with a directory by the same name (minus the suffix)\nand then include multiple files inside that directory (with that suffix) to merge multiple files together.\n"
  },
  {
    "path": ".github/actions/spelling/advice.md",
    "content": "<!-- See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice --> <!-- markdownlint-disable MD033 MD041 -->\n<details><summary>If the flagged items are :exploding_head: false positives</summary>\n\nIf items relate to a ...\n* binary file (or some other file you wouldn't want to check at all).\n\n  Please add a file path to the `excludes.txt` file matching the containing file.\n\n  File paths are Perl 5 Regular Expressions - you can [test](\nhttps://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your files.\n\n  `^` refers to the file's path from the root of the repository, so `^README\\.md$` would exclude [README.md](\n../tree/HEAD/README.md) (on whichever branch you're using).\n\n* well-formed pattern.\n\n  If you can write a [pattern](\nhttps://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns\n) that would match it,\n  try adding it to the `patterns.txt` file.\n\n  Patterns are Perl 5 Regular Expressions - you can [test](\nhttps://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your lines.\n\n  Note that patterns can't match multiline strings.\n\n</details>\n<!--\ntemplate: check-spelling\n-->\n"
  },
  {
    "path": ".github/actions/spelling/allow.txt",
    "content": "ACTIONDATA\nACTIONSTART\nactivatable\naddfile\naddmanifest\naddpin\naddportablefile\naddstore\nadmins\nAFX\nappinstaller\nappmodel\nappxbundle\nappxbundles\nappxrecipe\nappxsdk\nAPSTUDIO\nARRAYSIZE\nartifactstagingdirectory\nAsn\naspirational\nAuthenticode\nAUTOLISTEN\nazureedge\nbinlog\nbinver\nbstr\nBUILDNUMBER\nbytearray\ncdn\ncer\ncertutil\ncfr\ncguid\ncheckbox\ncla\nCLASSNOTAVAILABLE\nclsids\ncmake\nCNG\nCOMMANDBARFLYOUT\nCOMMONDATA\ncomparand\nconemu\ncontoso\nCOSTDEFERRED\ncotaskmem\ncpprest\ncpprestsdk\ncppwinrt\ncreatenew\ncreatepintable\ncreateportabletable\ncreatetables\nCRTDECL\nCRYPTPROTECT\nCTLs\ncurated\nCURSORPOSITON\nCUSTOMHEADER\ncvd\ndatatelemetry\ndatetime\ndbconn\nDBId\ndebugbreak\ndedup\ndefaultlocale\ndelstore\nDemitrius\ndenelon\ndepersist\ndifferentpath\nDIRECTONLY\nDISMAPI\ndistro\ndllmain\ndotnet\ndownloaders\ndsx\nDWORDLONG\nemoji\nENDDIALOG\nensureandinsert\nensurepathexists\nentra\nENU\nEOAC\nerrorlevel\nESRP\netstandard\nETW\nEULA\nEVENTTAG\nEWX\nexeenus\nexeinteractive\nexelog\nexesilent\nexeswp\nEXTRADEBUG\nEXTRAFLAGS\nFAILIFTHERE\nfakeswitch\nFATALEXIT\nFIELDTAG\nFILEFLAGS\nFILEFLAGSMASK\nFILEOS\nFILESINUSE\nFILESUBTYPE\nFILEVERSION\nflorelis\nFLUSHEACHLINE\nfnt\nforcerestart\ngdi\ngenai\nHCCE\nhcertstore\nHCRYPTMSG\nHGlobal\nHGLOBAL\nHIDECANCEL\nhinternet\nHKCU\nHKLM\nhresult\nHRSRC\nhstring\nIAppx\nICheckpoint\nIConfiguration\nIFACEMETHOD\nifspec\nIInspectable\ninapplicabilities\ninheritdoc\ninno\nInq\ninstallertype\nInstalleruniqueness\ninstalllocation\nINSTALLLOGATTRIBUTES\nINSTALLLOGMODE\nINSTALLPATH\nINSTALLUILEVEL\nINVALIDARG\nINVALIDSID\niot\nIPinning\nipmo\nIPortable\nISAPPROVEDFOROUTPUT\nIUnknown\nJDKs\nlangutil\nlastwritetime\nLCIDTo\nlnk\nLOGONLYONERROR\nLOGPATH\nLOGPERFORMANCE\nlogsql\nlogto\nLPCGUID\nLPCSTR\nLuid\nmakeappx\nMAKEINTRESOURCE\nmakemsix\nMANIFESTSCHEMA\nMANIFESTVERSION\nmcp\nMemberwise\nmeme\nmetadatas\nMinimatch\nMoq\nmotw\nmrm\nmsdata\nMSHCTX\nMSHLFLAGS\nmsiexec\nmsix\nmsixbundle\nmsixinfo\nmsixsdk\nmsixsdkx\nmsixtest\nmsrc\nMultifile\nMultimatch\nncacn\nNelon\nnetstandard\nnewid\nNOCASE\nNOCLOSEPROCESS\nnodiscard\nNOMINMAX\nnonexistentsetting\nnorestart\nnormalizednameandpublisher\nnormalizedpackagenameandpublisher\nnotcontains\nNTAPI\nNTSTATUS\nnullsoft\nnunit\nnupkg\nOAuth\nODR\nopencode\nopenxmlformats\nOSVERSIONINFOEXW\notf\nOUTOFDISKSPACE\nOUTOFPROC\npackagefamilyname\npackageidentifier\npackagename\nPACKAGESSCHEMA\npaket\nParams\nparams\nparentidx\npathpart\nPathto\nPBYTE\npch\nPCWSTR\npelikhan\nPEVENT\npfns\npfp\nPII\npinnable\npinningindex\npipssource\nPkcs\nportableindex\npowertoys\npplx\nppv\nPRECONFIG\npreindexed\nprepareforpackaging\nprepopulate\nprepopulated\nprioritization\nprocessthreadsapi\nPRODUCTNAME\nPRODUCTVERSION\nPROGRESSONLY\npromptrestart\nPROPERTYDUMP\nprotseq\nPTOKEN\npubliccontainer\nPUCHAR\npwa\nQCol\nQspectre\nrclsid\nREBOOTPROMPT\nRedistributable\nREFCLSID\nremovemanifest\nremovepin\nremoveportablefile\nrepolibtest\nrequeue\nrescap\nresetpins\nresheader\nresmimetype\nRESOLVESOURCE\nRESTAPI\nRESTARTAPPS\nresw\nresx\nrethrowing\nroadmap\nrobuffer\nrowcount\nrowids\nrubengustorage\nruleset\nrunas\nrunsettings\nSANITIZERS\nScreenshot\nscreenshots\nSCROLLVIEWER\nseinfo\nSERVICEPACKMAJOR\nSERVICEPACKMINOR\nsetschemaversion\nsetupexitcodes\nsetvariable\nshcore\nSHELLEXEC\nSHELLEXECUTEINFOW\nshlobj\nShlwapi\nSHTDN\nshtypes\nsigntool\nsilentwithprogress\nSilverlight\nsimplesave\nsimpletest\nsixel\nsixels\nsln\nsqlbuilder\nsqliteicu\nsqliteindex\nsqliteindexsource\nsqlitewrapper\nsrwlock\nSTARTUPINFO\nSTATEACTION\nSTATFLAG\nSTATSTG\nSTDAPI\nSTGM\nstoreedgefd\nstpkgmanvalwestustest\nstringable\nSTRINGID\nSTRINGIZE\nSTRSAFE\nsubcontext\nSUBLANG\nsubresource\nsubselect\nsubstr\nSUPPRESSMSGBOXES\nSWIPECONTROL\nSYMED\nsymlinktarget\nTARGETDIR\ntargetentrypoint\ntargetnametoken\ntdbuild\ntdd\ntempdb\nterabyte\ntestcontainer\ntestmoniker\nTESTPORTABLEFILE\nTestrun\ntestsettingname\nTEXTFORMAT\nTEXTINCLUDE\nthreadpool\ntpl\nTRACELOGGING\ntriaged\nTRUSTEDPEOPLE\nUAC\nUACONLY\nuap\nUBool\nUBreak\nubrk\nucol\nUCollation\nUCollator\nUError\nUIF\nULARGE\nund\nUNICODESTRING\nuninstalling\nUnmarshal\nunskipped\nunstash\nuntimes\nupdatefile\nupdatemanifest\nupdatepin\nupdateportablefile\nUPLEVEL\nuregex\nURegular\nurlmon\nUSEREXIT\nuserguide\nusersources\nutext\nvalijson\nvcpkg\nvcvars\nvcxitems\nVERYSILENT\nVFT\nvisualstudio\nVOS\nvso\nwapproj\nwcsicmp\nwebpage\nwebsites\nWHOLECHAIN\nwil\nwincrypt\nwindbg\nWINEVENT\nwinget\nwinhttp\nwininet\nwinmd\nwinmeta\nwinres\nwinrt\nwinsqlite\nWINTRUST\nwix\nwmain\nWNS\nwoah\nworkflows\nwpfn\nwrl\nWTD\nwtypesbase\nXamarin\nXbox\nXElement\nXlang\nXResource\nXTOKEN\nxunit\n"
  },
  {
    "path": ".github/actions/spelling/candidate.patterns",
    "content": "# marker to ignore all code on line\n^.*/\\* #no-spell-check-line \\*/.*$\n# marker for ignoring a comment to the end of the line\n// #no-spell-check.*$\n# marker to ignore all code on line\n^.*\\bno-spell-check(?:-line|)(?:\\s.*|)$\n\n# https://cspell.org/configuration/document-settings/\n# cspell inline\n^.*\\b[Cc][Ss][Pp][Ee][Ll]{2}:\\s*[Dd][Ii][Ss][Aa][Bb][Ll][Ee]-[Ll][Ii][Nn][Ee]\\b\n\n# patch hunk comments\n^@@ -\\d+(?:,\\d+|) \\+\\d+(?:,\\d+|) @@ .*\n# git index header\nindex (?:[0-9a-z]{7,40},|)[0-9a-z]{7,40}\\.\\.[0-9a-z]{7,40}\n\n# file permissions\n['\"`\\s][-bcdLlpsw](?:[-r][-w][-Ssx]){2}[-r][-w][-SsTtx]\\+?['\"`\\s]\n\n# css url wrappings\n\\burl\\([^)]+\\)\n\n# cid urls\n(['\"])cid:.*?\\g{-1}\n\n# data url in parens\n\\(data:(?:[^) ][^)]*?|)(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})[^)]*\\)\n# data url in quotes\n([`'\"])data:(?:[^ `'\"].*?|)(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,}).*\\g{-1}\n# data url\n\\bdata:[-a-zA-Z=;:/0-9+]*,\\S*\n\n# https/http/file urls\n#(?:\\b(?:https?|ftp|file)://)[-A-Za-z0-9+&@#/*%?=~_|!:,.;]+[-A-Za-z0-9+&@#/*%=~_|]\n\n# mailto urls\nmailto:[-a-zA-Z=;:/?%&0-9+@._]{3,}\n\n# magnet urls\nmagnet:[?=:\\w]+\n\n# magnet urls\n\"magnet:[^\"]+\"\n\n# obs:\n\"obs:[^\"]*\"\n\n# The `\\b` here means a break, it's the fancy way to handle urls, but it makes things harder to read\n# In this examples content, I'm using a number of different ways to match things to show various approaches\n# asciinema\n\\basciinema\\.org/a/[0-9a-zA-Z]+\n\n# asciinema v2\n^\\[\\d+\\.\\d+, \"[io]\", \".*\"\\]$\n\n# apple\n\\bdeveloper\\.apple\\.com/[-\\w?=/]+\n# Apple music\n\\bembed\\.music\\.apple\\.com/fr/playlist/usr-share/[-\\w.]+\n\n# appveyor api\n\\bci\\.appveyor\\.com/api/projects/status/[0-9a-z]+\n# appveyor project\n\\bci\\.appveyor\\.com/project/(?:[^/\\s\"]*/){2}builds?/\\d+/job/[0-9a-z]+\n\n# Amazon\n\n# Amazon\n\\bamazon\\.com/[-\\w]+/(?:dp/[0-9A-Z]+|)\n# AWS S3\n\\b\\w*\\.s3[^.]*\\.amazonaws\\.com/[-\\w/&#%_?:=]*\n# AWS execute-api\n\\b[0-9a-z]{10}\\.execute-api\\.[-0-9a-z]+\\.amazonaws\\.com\\b\n# AWS ELB\n\\b\\w+\\.[-0-9a-z]+\\.elb\\.amazonaws\\.com\\b\n# AWS SNS\n\\bsns\\.[-0-9a-z]+.amazonaws\\.com/[-\\w/&#%_?:=]*\n# AWS VPC\nvpc-\\w+\n\n# While you could try to match `http://` and `https://` by using `s?` in `https?://`, sometimes there\n# YouTube url\n\\b(?:(?:www\\.|)youtube\\.com|youtu.be)/(?:channel/|embed/|user/|playlist\\?list=|watch\\?v=|v/|)[-a-zA-Z0-9?&=_%]*\n# YouTube music\n\\bmusic\\.youtube\\.com/youtubei/v1/browse(?:[?&]\\w+=[-a-zA-Z0-9?&=_]*)\n# YouTube tag\n<\\s*youtube\\s+id=['\"][-a-zA-Z0-9?_]*['\"]\n# YouTube image\n\\bimg\\.youtube\\.com/vi/[-a-zA-Z0-9?&=_]*\n# Google Accounts\n\\baccounts.google.com/[-_/?=.:;+%&0-9a-zA-Z]*\n# Google Analytics\n\\bgoogle-analytics\\.com/collect.[-0-9a-zA-Z?%=&_.~]*\n# Google APIs\n\\bgoogleapis\\.(?:com|dev)/[a-z]+/(?:v\\d+/|)[a-z]+/[-@:./?=\\w+|&]+\n# Google Storage\n\\b[-a-zA-Z0-9.]*\\bstorage\\d*\\.googleapis\\.com(?:/\\S*|)\n# Google Calendar\n\\bcalendar\\.google\\.com/calendar(?:/u/\\d+|)/embed\\?src=[@./?=\\w&%]+\n\\w+\\@group\\.calendar\\.google\\.com\\b\n# Google DataStudio\n\\bdatastudio\\.google\\.com/(?:(?:c/|)u/\\d+/|)(?:embed/|)(?:open|reporting|datasources|s)/[-0-9a-zA-Z]+(?:/page/[-0-9a-zA-Z]+|)\n# The leading `/` here is as opposed to the `\\b` above\n# ... a short way to match `https://` or `http://` since most urls have one of those prefixes\n# Google Docs\n/docs\\.google\\.com/[a-z]+/(?:ccc\\?key=\\w+|(?:u/\\d+|d/(?:e/|)[0-9a-zA-Z_-]+/)?(?:edit\\?[-\\w=#.]*|/\\?[\\w=&]*|))\n# Google Drive\n\\bdrive\\.google\\.com/(?:file/d/|open)[-0-9a-zA-Z_?=]*\n# Google Groups\n\\bgroups\\.google\\.com(?:/[a-z]+/(?:#!|)[^/\\s\"]+)*\n# Google Maps\n\\bmaps\\.google\\.com/maps\\?[\\w&;=]*\n# Google themes\nthemes\\.googleusercontent\\.com/static/fonts/[^/\\s\"]+/v\\d+/[^.]+.\n# Google CDN\n\\bclients2\\.google(?:usercontent|)\\.com[-0-9a-zA-Z/.]*\n# Goo.gl\n/goo\\.gl/[a-zA-Z0-9]+\n# Google Chrome Store\n\\bchrome\\.google\\.com/webstore/detail/[-\\w]*(?:/\\w*|)\n# Google Books\n\\bgoogle\\.(?:\\w{2,4})/books(?:/\\w+)*\\?[-\\w\\d=&#.]*\n# Google Fonts\n\\bfonts\\.(?:googleapis|gstatic)\\.com/[-/?=:;+&0-9a-zA-Z]*\n# Google Forms\n\\bforms\\.gle/\\w+\n# Google Scholar\n\\bscholar\\.google\\.com/citations\\?user=[A-Za-z0-9_]+\n# Google Colab Research Drive\n\\bcolab\\.research\\.google\\.com/drive/[-0-9a-zA-Z_?=]*\n\n# GitHub SHAs (api)\n\\bapi.github\\.com/repos(?:/[^/\\s\"]+){3}/[0-9a-f]+\\b\n# GitHub SHAs (markdown)\n(?:\\[`?[0-9a-f]+`?\\]\\(https:/|)/(?:www\\.|)github\\.com(?:/[^/\\s\"]+){2,}(?:/[^/\\s\")]+)(?:[0-9a-f]+(?:[-0-9a-zA-Z/#.]*|)\\b|)\n# GitHub SHAs\n\\bgithub\\.com(?:/[^/\\s\"]+){2}[@#][0-9a-f]+\\b\n# GitHub SHA refs\n\\[([0-9a-f]+)\\]\\(https://(?:www\\.|)github.com/[-\\w]+/[-\\w]+/commit/\\g{-1}[0-9a-f]*\n# GitHub wiki\n\\bgithub\\.com/(?:[^/]+/){2}wiki/(?:(?:[^/]+/|)_history|[^/]+(?:/_compare|)/[0-9a-f.]{40,})\\b\n# githubusercontent\n/[-a-z0-9]+\\.githubusercontent\\.com/[-a-zA-Z0-9?&=_\\/.]*\n# githubassets\n\\bgithubassets.com/[0-9a-f]+(?:[-/\\w.]+)\n# gist github\n\\bgist\\.github\\.com/[^/\\s\"]+/[0-9a-f]+\n# git.io\n\\bgit\\.io/[0-9a-zA-Z]+\n# GitHub JSON\n\"node_id\": \"[-a-zA-Z=;:/0-9+_]*\"\n# Contributor\n\\[[^\\]]+\\]\\(https://github\\.com/[^/\\s\"]+/?\\)\n# GHSA\nGHSA(?:-[0-9a-z]{4}){3}\n\n# GitHub actions\n\\buses:\\s+[-\\w.]+/[-\\w./]+@[-\\w.]+\n\n# GitLab commit\n\\bgitlab\\.[^/\\s\"]*/\\S+/\\S+/commit/[0-9a-f]{7,16}#[0-9a-f]{40}\\b\n# GitLab merge requests\n\\bgitlab\\.[^/\\s\"]*/\\S+/\\S+/-/merge_requests/\\d+/diffs#[0-9a-f]{40}\\b\n# GitLab uploads\n\\bgitlab\\.[^/\\s\"]*/uploads/[-a-zA-Z=;:/0-9+]*\n# GitLab commits\n\\bgitlab\\.[^/\\s\"]*/(?:[^/\\s\"]+/){2}commits?/[0-9a-f]+\\b\n\n# binance\naccounts\\.binance\\.com/[a-z/]*oauth/authorize\\?[-0-9a-zA-Z&%]*\n\n# bitbucket diff\n\\bapi\\.bitbucket\\.org/\\d+\\.\\d+/repositories/(?:[^/\\s\"]+/){2}diff(?:stat|)(?:/[^/\\s\"]+){2}:[0-9a-f]+\n# bitbucket repositories commits\n\\bapi\\.bitbucket\\.org/\\d+\\.\\d+/repositories/(?:[^/\\s\"]+/){2}commits?/[0-9a-f]+\n# bitbucket commits\n\\bbitbucket\\.org/(?:[^/\\s\"]+/){2}commits?/[0-9a-f]+\n\n# bit.ly\n\\bbit\\.ly/\\w+\n\n# bitrise\n\\bapp\\.bitrise\\.io/app/[0-9a-f]*/[\\w.?=&]*\n\n# bootstrapcdn.com\n\\bbootstrapcdn\\.com/[-./\\w]+\n\n# cdn.cloudflare.com\n\\bcdnjs\\.cloudflare\\.com/[./\\w]+\n\n# circleci\n\\bcircleci\\.com/gh(?:/[^/\\s\"]+){1,5}.[a-z]+\\?[-0-9a-zA-Z=&]+\n\n# gitter\n\\bgitter\\.im(?:/[^/\\s\"]+){2}\\?at=[0-9a-f]+\n\n# gravatar\n\\bgravatar\\.com/avatar/[0-9a-f]+\n\n# ibm\n[a-z.]*ibm\\.com/[-_#=:%!?~.\\\\/\\d\\w]*\n\n# imgur\n\\bimgur\\.com/[^.]+\n\n# Internet Archive\n\\barchive\\.org/web/\\d+/(?:[-\\w.?,'/\\\\+&%$#_:]*)\n\n# discord\n/discord(?:app\\.com|\\.gg)/(?:invite/)?[a-zA-Z0-9]{7,}\n\n# Disqus\n\\bdisqus\\.com/[-\\w/%.()!?&=_]*\n\n# medium link\n\\blink\\.medium\\.com/[a-zA-Z0-9]+\n# medium\n\\bmedium\\.com/@?[^/\\s\"]+/[-\\w]+\n\n# microsoft\n\\b(?:https?://|)(?:(?:(?:blogs|download\\.visualstudio|docs|msdn2?|research)\\.|)microsoft|blogs\\.msdn)\\.co(?:m|\\.\\w\\w)/[-_a-zA-Z0-9()=./%]*\n# powerbi\n\\bapp\\.powerbi\\.com/reportEmbed/[^\"' ]*\n# vs devops\n\\bvisualstudio.com(?::443|)/[-\\w/?=%&.]*\n# microsoft store\n\\bmicrosoft\\.com/store/apps/\\w+\n\n# mvnrepository.com\n\\bmvnrepository\\.com/[-0-9a-z./]+\n\n# now.sh\n/[0-9a-z-.]+\\.now\\.sh\\b\n\n# oracle\n\\bdocs\\.oracle\\.com/[-0-9a-zA-Z./_?#&=]*\n\n# chromatic.com\n/\\S+.chromatic.com\\S*[\")]\n\n# codacy\n\\bapi\\.codacy\\.com/project/badge/Grade/[0-9a-f]+\n\n# compai\n\\bcompai\\.pub/v1/png/[0-9a-f]+\n\n# mailgun api\n\\.api\\.mailgun\\.net/v3/domains/[0-9a-z]+\\.mailgun.org/messages/[0-9a-zA-Z=@]*\n# mailgun\n\\b[0-9a-z]+.mailgun.org\n\n# /message-id/\n/message-id/[-\\w@./%]+\n\n# Reddit\n\\breddit\\.com/r/[/\\w_]*\n\n# requestb.in\n\\brequestb\\.in/[0-9a-z]+\n\n# sched\n\\b[a-z0-9]+\\.sched\\.com\\b\n\n# Slack url\nslack://[a-zA-Z0-9?&=]+\n# Slack\n\\bslack\\.com/[-0-9a-zA-Z/_~?&=.]*\n# Slack edge\n\\bslack-edge\\.com/[-a-zA-Z0-9?&=%./]+\n# Slack images\n\\bslack-imgs\\.com/[-a-zA-Z0-9?&=%.]+\n\n# shields.io\n\\bshields\\.io/[-\\w/%?=&.:+;,]*\n\n# stackexchange -- https://stackexchange.com/feeds/sites\n\\b(?:askubuntu|serverfault|stack(?:exchange|overflow)|superuser).com/(?:questions/\\w+/[-\\w]+|a/)\n\n# Sentry\n[0-9a-f]{32}\\@o\\d+\\.ingest\\.sentry\\.io\\b\n\n# Twitter markdown\n\\[@[^[/\\]:]*?\\]\\(https://twitter.com/[^/\\s\"')]*(?:/status/\\d+(?:\\?[-_0-9a-zA-Z&=]*|)|)\\)\n# Twitter hashtag\n\\btwitter\\.com/hashtag/[\\w?_=&]*\n# Twitter status\n\\btwitter\\.com/[^/\\s\"')]*(?:/status/\\d+(?:\\?[-_0-9a-zA-Z&=]*|)|)\n# Twitter profile images\n\\btwimg\\.com/profile_images/[_\\w./]*\n# Twitter media\n\\btwimg\\.com/media/[-_\\w./?=]*\n# Twitter link shortened\n\\bt\\.co/\\w+\n\n# facebook\n\\bfburl\\.com/[0-9a-z_]+\n# facebook CDN\n\\bfbcdn\\.net/[\\w/.,]*\n# facebook watch\n\\bfb\\.watch/[0-9A-Za-z]+\n\n# dropbox\n\\bdropbox\\.com/sh?/[^/\\s\"]+/[-0-9A-Za-z_.%?=&;]+\n\n# ipfs protocol\nipfs://[0-9a-zA-Z]{3,}\n# ipfs url\n/ipfs/[0-9a-zA-Z]{3,}\n\n# w3\n\\bw3\\.org/[-0-9a-zA-Z/#.]+\n\n# loom\n\\bloom\\.com/embed/[0-9a-f]+\n\n# regex101\n\\bregex101\\.com/r/[^/\\s\"]+/\\d+\n\n# figma\n\\bfigma\\.com/file(?:/[0-9a-zA-Z]+/)+\n\n# freecodecamp.org\n\\bfreecodecamp\\.org/[-\\w/.]+\n\n# image.tmdb.org\n\\bimage\\.tmdb\\.org/[/\\w.]+\n\n# mermaid\n\\bmermaid\\.ink/img/[-\\w]+|\\bmermaid-js\\.github\\.io/mermaid-live-editor/#/edit/[-\\w]+\n\n# Wikipedia\n\\ben\\.wikipedia\\.org/wiki/[-\\w%.#]+\n\n# gitweb\n[^\"\\s]+/gitweb/\\S+;h=[0-9a-f]+\n\n# HyperKitty lists\n/archives/list/[^@/]+@[^/\\s\"]*/message/[^/\\s\"]*/\n\n# lists\n/thread\\.html/[^\"\\s]+\n\n# list-management\n\\blist-manage\\.com/subscribe(?:[?&](?:u|id)=[0-9a-f]+)+\n\n# kubectl.kubernetes.io/last-applied-configuration\n\"kubectl.kubernetes.io/last-applied-configuration\": \".*\"\n\n# pgp\n\\bgnupg\\.net/pks/lookup[?&=0-9a-zA-Z]*\n\n# Spotify\n\\bopen\\.spotify\\.com/embed/playlist/\\w+\n\n# Mastodon\n\\bmastodon\\.[-a-z.]*/(?:media/|@)[?&=0-9a-zA-Z_]*\n\n# scastie\n\\bscastie\\.scala-lang\\.org/[^/]+/\\w+\n\n# images.unsplash.com\n\\bimages\\.unsplash\\.com/(?:(?:flagged|reserve)/|)[-\\w./%?=%&.;]+\n\n# pastebin\n\\bpastebin\\.com/[\\w/]+\n\n# heroku\n\\b\\w+\\.heroku\\.com/source/archive/\\w+\n\n# quip\n\\b\\w+\\.quip\\.com/\\w+(?:(?:#|/issues/)\\w+)?\n\n# badgen.net\n\\bbadgen\\.net/badge/[^\")\\]'\\s]+\n\n# statuspage.io\n\\w+\\.statuspage\\.io\\b\n\n# media.giphy.com\n\\bmedia\\.giphy\\.com/media/[^/]+/[\\w.?&=]+\n\n# tinyurl\n\\btinyurl\\.com/\\w+\n\n# codepen\n\\bcodepen\\.io/[\\w/]+\n\n# registry.npmjs.org\n\\bregistry\\.npmjs\\.org/(?:@[^/\"']+/|)[^/\"']+/-/[-\\w@.]+\n\n# getopts\n\\bgetopts\\s+(?:\"[^\"]+\"|'[^']+')\n\n# ANSI color codes\n(?:\\\\(?:u00|x)1[Bb]|\\x1b|\\\\u\\{1[Bb]\\})\\[\\d+(?:;\\d+|)m\n\n# URL escaped characters\n%[0-9A-F][A-F](?=[A-Za-z])\n# lower URL escaped characters\n%[0-9a-f][a-f](?=[a-z]{2,})\n# IPv6\n\\b(?:[0-9a-fA-F]{0,4}:){3,7}[0-9a-fA-F]{0,4}\\b\n# c99 hex digits (not the full format, just one I've seen)\n0x[0-9a-fA-F](?:\\.[0-9a-fA-F]*|)[pP]\n# Punycode\n\\bxn--[-0-9a-z]+\n# sha\nsha\\d+:[0-9a-f]*?[a-f]{3,}[0-9a-f]*\n# sha-... -- uses a fancy capture\n(\\\\?['\"]|&quot;)[0-9a-f]{40,}\\g{-1}\n# hex runs\n\\b[0-9a-fA-F]{16,}\\b\n# hex in url queries\n=[0-9a-fA-F]*?(?:[A-F]{3,}|[a-f]{3,})[0-9a-fA-F]*?&\n# ssh\n(?:ssh-\\S+|-nistp256) [-a-zA-Z=;:/0-9+]{12,}\n\n# PGP\n\\b(?:[0-9A-F]{4} ){9}[0-9A-F]{4}\\b\n# GPG keys\n\\b(?:[0-9A-F]{4} ){5}(?: [0-9A-F]{4}){5}\\b\n# Well known gpg keys\n.well-known/openpgpkey/[\\w./]+\n\n# pki\n-----BEGIN.*-----END\n\n# pki (base64)\nLS0tLS1CRUdJT.*\n\n# uuid:\n\\b[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\\b\n# hex digits including css/html color classes:\n(?:[\\\\0][xX]|\\\\u|[uU]\\+|#x?|%23)[0-9_a-fA-FgGrR]*?[a-fA-FgGrR]{2,}[0-9_a-fA-FgGrR]*(?:[uUlL]{0,3}|[iu]\\d+)\\b\n# integrity\nintegrity=(['\"])(?:\\s*sha\\d+-[-a-zA-Z=;:/0-9+]{40,})+\\g{-1}\n\n# https://www.gnu.org/software/groff/manual/groff.html\n# man troff content\n\\\\f[BCIPR]\n# '/\"\n\\\\\\([ad]q\n\n# .desktop mime types\n^MimeTypes?=.*$\n# .desktop localized entries\n^[A-Z][a-z]+\\[[a-z]+\\]=.*$\n# Localized .desktop content\nName\\[[^\\]]+\\]=.*\n\n# IServiceProvider / isAThing\n(?:\\b|_)(?:(?:ns|)I|isA)(?=(?:[A-Z][a-z]{2,})+(?:[A-Z\\d]|\\b))\n\n# crypt\n(['\"])\\$2[ayb]\\$.{56}\\g{-1}\n\n# apache/old crypt\n(['\"]|)\\$+(?:apr|)1\\$+.{8}\\$+.{22}\\g{-1}\n\n# sha1 hash\n\\{SHA\\}[-a-zA-Z=;:/0-9+]{3,}\n\n# machine learning (?)\n#\\b(?i)ml(?=[a-z]{2,})\n\n# python\n\\b(?i)py(?!gments|gmy|lon|ramid|ro|th)(?=[a-z]{2,})\n\n# scrypt / argon\n\\$(?:scrypt|argon\\d+[di]*)\\$\\S+\n\n# go.sum\n\\bh1:\\S+\n\n# scala imports\n^import (?:[\\w.]|\\{\\w*?(?:,\\s*(?:\\w*|\\*))+\\})+\n\n# scala modules\n(\"[^\"]+\"\\s*%%?\\s*){2,3}\"[^\"]+\"\n\n# container images\nimage: [-\\w./:@]+\n\n# Docker images\n^\\s*FROM\\s+\\S+:\\S+(?:\\s+AS\\s+\\S+|)\n\n# `docker images` REPOSITORY TAG IMAGE ID CREATED SIZE\n\\s*\\S+/\\S+\\s+\\S+\\s+[0-9a-f]{8,}\\s+\\d+\\s+(?:hour|day|week)s ago\\s+[\\d.]+[KMGT]B\n\n# Intel intrinsics\n_mm_(?!dd)\\w+\n\n# Input to GitHub JSON\ncontent: (['\"])[-a-zA-Z=;:/0-9+]*=\\g{-1}\n\n# This does not cover multiline strings, if your repository has them,\n# you'll want to remove the `(?=.*?\")` suffix.\n# The `(?=.*?\")` suffix should limit the false positives rate\n# printf\n%(?:(?:(?:hh?|ll?|[jzt])?[diuoxn]|l?[cs]|L?[fega]|p)(?=[a-z]{2,})|(?:X|L?[FEGA])(?=[a-zA-Z]{2,}))(?!%)(?=[_a-zA-Z]+(?!%)\\b)(?=.*?['\"])\n\n# Alternative printf\n# %s\n%(?:s(?=[a-z]{2,}))(?!%)(?=[_a-zA-Z]+(?!%[^s])\\b)(?=.*?['\"])\n\n# Python string prefix / binary prefix\n# Note that there's a high false positive rate, remove the `?=` and search for the regex to see if the matches seem like reasonable strings\n#(?<!['\"])\\b(?:B|BR|Br|F|FR|Fr|R|RB|RF|Rb|Rf|U|UR|Ur|b|bR|br|f|fR|fr|r|rB|rF|rb|rf|u|uR|ur)['\"](?=[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})\n\n# Regular expressions for (P|p)assword\n\\([A-Z]\\|[a-z]\\)[a-z]+\n\n# JavaScript regular expressions\n# javascript test regex\n/.{3,}/[gim]*\\.test\\(\n# javascript match regex\n\\.match\\(/[^/\\s\"]{3,}/[gim]*\\s*\n# javascript match regex\n\\.match\\(/\\\\[b].{3,}?/[gim]*\\s*\\)(?:;|$)\n# javascript regex\n^\\s*/\\\\[b].{3,}?/[gim]*\\s*(?:\\)(?:;|$)|,$)\n# javascript replace regex\n\\.replace\\(/[^/\\s\"]{3,}/[gim]*\\s*,\n# assign regex\n= /[^*].*?(?:[a-z]{3,}|[A-Z]{3,}|[A-Z][a-z]{2,}).*/[gi]?(?=\\W|$)\n# perl regex test\n[!=]~ (?:/.*/|m\\{.*?\\}|m<.*?>|m([|!/@#,;']).*?\\g{-1})\n\n# perl qr regex\n(?<!\\$)\\bqr(?:\\{.*?\\}|<.*?>|\\(.*?\\)|([|!/@#,;']).*?\\g{-1})\n\n# perl run\nperl(?:\\s+-[a-zA-Z]\\w*)+\n\n# C network byte conversions\n#(?:\\d|\\bh)to(?!ken)(?=[a-z])|to(?=[adhiklpun]\\()\n\n# Go regular expressions\nregexp?\\.MustCompile\\(`[^`]*`\\)\n\n# regex choice\n\\(\\?:[^)]+\\|[^)]+\\)\n\n# proto\n^\\s*(\\w+)\\s\\g{-1} =\n\n# sed regular expressions\nsed 's/(?:[^/]*?[a-zA-Z]{3,}[^/]*?/){2}\n\n# node packages\n([\"'])@[^/'\" ]+/[^/'\" ]+\\g{-1}\n\n# go install\ngo install(?:\\s+[a-z]+\\.[-@\\w/.]+)+\n\n# pom.xml\n<(?:group|artifact)Id>.*?<\n\n# jetbrains schema https://youtrack.jetbrains.com/issue/RSRP-489571\nurn:shemas-jetbrains-com\n\n# Debian changelog severity\n[-\\w]+ \\(.*\\) (?:\\w+|baseline|unstable|experimental); urgency=(?:low|medium|high|emergency|critical)\\b\n\n# kubernetes pod status lists\n# https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase\n\\w+(?:-\\w+)+\\s+\\d+/\\d+\\s+(?:Running|Pending|Succeeded|Failed|Unknown)\\s+\n\n# kubectl - pods in CrashLoopBackOff\n\\w+-[0-9a-f]+-\\w+\\s+\\d+/\\d+\\s+CrashLoopBackOff\\s+\n\n# kubernetes applications\n\\.apps/[-\\w]+\n\n# kubernetes object suffix\n-[0-9a-f]{10}-\\w{5}\\s\n\n# kubernetes crd patterns\n^\\s*pattern: .*$\n\n# posthog secrets\n([`'\"])phc_[^\"',]+\\g{-1}\n\n# xcode\n\n# xcodeproject scenes\n(?:Controller|destination|ID|id)=\"\\w{3}-\\w{2}-\\w{3}\"\n\n# xcode api botches\ncustomObjectInstantitationMethod\n\n# msvc api botches\nPrependWithABINamepsace\n\n# configure flags\n.* \\| --\\w{2,}.*?(?=\\w+\\s\\w+)\n\n# font awesome classes\n\\.fa-[-a-z0-9]+\n\n# bearer auth\n(['\"])[Bb]ear[e][r] .*?\\g{-1}\n\n# bearer auth\n\\b[Bb]ear[e][r]:? [-a-zA-Z=;:/0-9+.]+\n\n# basic auth\n(['\"])[Bb]asic [-a-zA-Z=;:/0-9+]{3,}\\g{-1}\n\n# base64 encoded content\n#([`'\"])[-a-zA-Z=;:/0-9+]{3,}=\\g{-1}\n# base64 encoded content in xml/sgml\n>[-a-zA-Z=;:/0-9+]{3,}=</\n# base64 encoded content, possibly wrapped in mime\n#(?:^|[\\s=;:?])[-a-zA-Z=;:/0-9+]{50,}(?:[\\s=;:?]|$)\n# base64 encoded json\n\\beyJ[-a-zA-Z=;:/0-9+]+\n# base64 encoded pkcs\n\\bMII[-a-zA-Z=;:/0-9+]+\n\n# DNS rr data\n(?:\\d+\\s+){3}(?:[-+/=.\\w]{2,}\\s*){1,2}\n\n# encoded-word\n=\\?[-a-zA-Z0-9\"*%]+\\?[BQ]\\?[^?]{0,75}\\?=\n\n# numerator\n\\bnumer\\b(?=.*denom)\n\n# Time Zones\n\\b(?:Africa|Atlantic|America|Antarctica|Asia|Australia|Europe|Indian|Pacific)(?:/\\w+)+\n\n# linux kernel info\n^(?:bugs|flags|Features)\\s+:.*\n\n# systemd mode\nsystemd.*?running in system mode \\([-+].*\\)$\n\n# Lorem\n# Update Lorem based on your content (requires `ge` and `w` from https://github.com/jsoref/spelling; and `review` from https://github.com/check-spelling/check-spelling/wiki/Looking-for-items-locally )\n# grep '^[^#].*lorem' .github/actions/spelling/patterns.txt|perl -pne 's/.*i..\\?://;s/\\).*//' |tr '|' \"\\n\"|sort -f |xargs -n1 ge|perl -pne 's/^[^:]*://'|sort -u|w|sed -e 's/ .*//'|w|review -\n# Warning, while `(?i)` is very neat and fancy, if you have some binary files that aren't proper unicode, you might run into:\n# ... Operation \"substitution (s///)\" returns its argument for non-Unicode code point 0x1C19AE (the code point will vary).\n# ... You could manually change `(?i)X...` to use `[Xx]...`\n# ... or you could add the files to your `excludes` file (a version after 0.0.19 should identify the file path)\n(?:(?:\\w|\\s|[,.])*\\b(?i)(?:amet|consectetur|cursus|dolor|eros|ipsum|lacus|libero|ligula|lorem|magna|neque|nulla|suscipit|tempus)\\b(?:\\w|\\s|[,.])*)\n\n# Non-English\n# Even repositories expecting pure English content can unintentionally have Non-English content... People will occasionally mistakenly enter [homoglyphs](https://en.wikipedia.org/wiki/Homoglyph) which are essentially typos, and using this pattern will mean check-spelling will not complain about them.\n#\n# If the content to be checked should be written in English and the only Non-English items will be people's names, then you can consider adding this.\n#\n# Alternatively, if you're using check-spelling v0.0.25+, and you would like to _check_ the Non-English content for spelling errors, you can. For information on how to do so, see:\n# https://docs.check-spelling.dev/Feature:-Configurable-word-characters.html#unicode\n[a-zA-Z]*[ÀÁÂÃÄÅÆČÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæčçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź][a-zA-Z]{3}[a-zA-ZÀÁÂÃÄÅÆČÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæčçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź]*|[a-zA-Z]{3,}[ÀÁÂÃÄÅÆČÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæčçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź]|[ÀÁÂÃÄÅÆČÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæčçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź][a-zA-Z]{3,}\n\n# highlighted letters\n\\[[A-Z]\\][a-z]+\n\n# French\n# This corpus only had capital letters, but you probably want lowercase ones as well.\n\\b[LN]'+[a-z]{2,}\\b\n\n# latex (check-spelling >= 0.0.22)\n\\\\\\w{2,}\\{\n\n# American Mathematical Society (AMS) / Doxygen\nTeX/AMS\n\n# File extensions\n\\*\\.[+\\w]+,\n\n# eslint\n\"varsIgnorePattern\": \".+\"\n\n# nolint\nnolint:\\w+\n\n# Windows short paths\n[/\\\\][^/\\\\]{5,6}~\\d{1,2}(?=[/\\\\])\n\n# Windows Resources with accelerators\n\\b[A-Z]&[a-z]+\\b(?!;)\n\n# cygwin paths\n/cygdrive/[a-zA-Z]/(?:Program Files(?: \\(.*?\\)| ?)(?:/[-+.~\\\\/()\\w ]+)*|[-+.~\\\\/()\\w])+\n\n# in check-spelling@v0.0.22+, printf markers aren't automatically consumed\n# printf markers\n#(?<!\\\\)\\\\[nrt](?=[a-z]{2,})\n# alternate printf markers if you run into latex and friends\n#(?<!\\\\)\\\\[nrt](?=[a-z]{2,})(?=.*['\"`])\n\n# Markdown anchor links\n\\(#\\S*?[a-zA-Z]\\S*?\\)\n\n# apache\na2(?:en|dis)\n\n# weak e-tag\nW/\"[^\"]+\"\n\n# authors/credits\n^\\*(?: [A-Z](?:\\w+|\\.)){2,} (?=\\[|$)\n\n# the negative lookahead here is to allow catching 'templatesz' as a misspelling\n# but to otherwise recognize a Windows path with \\templates\\foo.template or similar:\n\\\\(?:necessary|r(?:elease|eport|esolve[dr]?|esult)|t(?:arget|emplates?))(?![a-z])\n# ignore long runs of a single character:\n\\b([A-Za-z])\\g{-1}{3,}\\b\n\n# version suffix <word>v#\n(?:(?<=[A-Z]{2})V|(?<=[a-z]{2}|[A-Z]{2})v)\\d+(?:\\b|(?=[a-zA-Z_]))\n\n# Compiler flags (Unix, Java/Scala)\n# Use if you have things like `-Pdocker` and want to treat them as `docker`\n#(?:^|[\\t ,>\"'`=(])-(?:(?:J-|)[DPWXY]|[Llf])(?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})\n\n# Compiler flags (Windows / PowerShell)\n# This is a subset of the more general compiler flags pattern.\n# It avoids matching `-Path` to prevent it from being treated as `ath`\n#(?:^|[\\t ,\"'`=(])-(?:[DPL](?=[A-Z]{2,})|[WXYlf](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,}))\n\n# Compiler flags (linker)\n,-B\n\n# libraries\n(?:\\b|_)lib(?:re(?=office)|)(?!era[lt]|ero|erty|rar(?:i(?:an|es)|y))(?=[a-z])\n\n# WWNN/WWPN (NAA identifiers)\n\\b(?:0x)?10[0-9a-f]{14}\\b|\\b(?:0x|3)?[25][0-9a-f]{15}\\b|\\b(?:0x|3)?6[0-9a-f]{31}\\b\n\n# iSCSI iqn (approximate regex)\n\\biqn\\.[0-9]{4}-[0-9]{2}(?:[\\.-][a-z][a-z0-9]*)*\\b\n\n# curl arguments\n\\b(?:\\\\n|)curl(?:\\.exe|)(?:\\s+-[a-zA-Z]{1,2}\\b)*(?:\\s+-[a-zA-Z]{3,})(?:\\s+-[a-zA-Z]+)*\n# set arguments\n\\b(?:bash|sh|set)(?:\\s+-[abefimouxE]{1,2})*\\s+-[abefimouxE]{3,}(?:\\s+-[abefimouxE]+)*\n# tar arguments\n\\b(?:\\\\n|)g?tar(?:\\.exe|)(?:(?:\\s+--[-a-zA-Z]+|\\s+-[a-zA-Z]+|\\s[ABGJMOPRSUWZacdfh-pr-xz]+\\b)(?:=[^ ]*|))+\n# tput arguments -- https://man7.org/linux/man-pages/man5/terminfo.5.html -- technically they can be more than 5 chars long...\n\\btput\\s+(?:(?:-[SV]|-T\\s*\\w+)\\s+)*\\w{3,5}\\b\n# macOS temp folders\n/var/folders/\\w\\w/[+\\w]+/(?:T|-Caches-)/\n# github runner temp folders\n/home/runner/work/_temp/[-_/a-z0-9]+\n"
  },
  {
    "path": ".github/actions/spelling/excludes.txt",
    "content": "# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-excludes\n(?:^|/)(?i)COPYRIGHT\n(?:^|/)(?i)LICEN[CS]E\n(?:^|/)(?i)third[-_]?party/\n(?:^|/)3rdparty/\n(?:^|/)generated/\n(?:^|/)go\\.sum$\n(?:^|/)Microsoft\\.Management\\.Deployment\\.winmd$\n(?:^|/)package(?:-lock|)\\.json$\n(?:^|/)Pipfile$\n(?:^|/)PSGet\\.Resource\\.psd1$\n(?:^|/)pyproject.toml\n(?:^|/)vendor/\n(?:^|/|\\b)requirements(?:-dev|-doc|-test|)\\.txt$\n/ExternalModules/\n/TestData/\n[^/]\\.msi$\n\\.a$\n\\.ai$\n\\.all-contributorsrc$\n\\.avi$\n\\.bmp$\n\\.bz2$\n\\.cert?$|\\.crt$\n\\.class$\n\\.coveragerc$\n\\.crl$\n\\.csr$\n\\.dll$\n\\.docx?$\n\\.drawio$\n\\.DS_Store$\n\\.eot$\n\\.eps$\n\\.exe$\n\\.fnt$\n\\.gif$\n\\.git-blame-ignore-revs$\n\\.gitattributes$\n\\.gitkeep$\n\\.graffle$\n\\.gz$\n\\.icns$\n\\.ico$\n\\.ipynb$\n\\.jar$\n\\.jks$\n\\.jpe?g$\n\\.key$\n\\.lib$\n\\.lock$\n\\.map$\n\\.min\\..\n\\.mo$\n\\.mod$\n\\.mp[34]$\n\\.o$\n\\.ocf$\n\\.otf$\n\\.otc$\n\\.p12$\n\\.parquet$\n\\.pdf$\n\\.pem$\n\\.pfx$\n\\.png$\n\\.psd$\n\\.pyc$\n\\.pylintrc$\n\\.qm$\n\\.s$\n\\.sig$\n\\.sln$\n\\.so$\n\\.svgz?$\n\\.sys$\n\\.tar$\n\\.tgz$\n\\.tiff?$\n\\.ttc$\n\\.ttf$\n\\.vcxitems$\n\\.vcxproj$\n\\.vcxproj\\.filters$\n\\.vdproj$\n\\.wapproj$\n\\.wav$\n\\.webm$\n\\.webp$\n\\.woff2?$\n\\.wprp$\n\\.xcf$\n\\.xlsx?$\n\\.xpm$\n\\.xz$\n\\.zip$\n^\\.github/actions/spelling/\n^\\.github/policies/\n^\\.github/workflows/spelling\\d*\\.yml$\n^cgmanifest\\.json$\n^Localization/\n^NOTICE\n^src/AppInstallerCLICore/Commands/ExperimentalCommand\\.cpp$\n^src/Microsoft.Management.Configuration.Processor/Microsoft.Management.Configuration.Processor.csproj$\n^src/PowerShell/Help/markdownlint\\.yaml$\n^src/PowerShell/Microsoft.WinGet.Client.Engine/Microsoft.WinGet.Client.Engine.csproj$\n^src/PureLib/\n^src/SfsClient/\n^src/Xlang/\n^src/VcpkgPortOverlay/\n^src/WinGetMCPServer/WinGetMCPServer.csproj$\nignore$\n"
  },
  {
    "path": ".github/actions/spelling/expect.txt",
    "content": "AAD\nABCD\nabi\nABORTIFHUNG\naccepteula\nACCESSDENIED\nACCESSTOKEN\nacl\nadjacents\nadml\nadmx\nAFAIK\naicli\nAICLIC\nallusers\nalreadyinstalled\nAMap\nAmd\namrutha\nansistring\nanyissuer\nAot\nAPARTMENTTHREADED\napfn\napicontract\napiset\nappdata\nappinstallertest\napplic\nappname\nappshutdown\nAPPTERMINATION\narchs\nARMNT\narp\narphelper\nasan\nASequence\nashpatil\nAshwini\nASwitch\nASYNCRTIMP\nAtest\nATL\nauxdata\nawgpm\nawgs\nazurewebsites\nbak\nBaz\nbbb\nbcp\nBEBOM\nBEFACEF\nbfd\nBFirst\nbigcatalog\nBITMAPINFOHEADER\nbitmask\nBKMG\nbkup\nblargle\nblockedbypolicy\nblogs\nbluetooth\nBomgar\nBOMs\nboop\nboundparms\nbpp\nbrk\nBrowsable\nBSODs\nBuf\nbuildtransitive\nbuildtrees\ncancelledbyuser\ncasemap\ncasemappings\nccc\ncch\ncentralus\ncertmgr\ncerts\ncgi\ncinq\nCLASSNOTREG\nCLOSEAPP\ncloudapp\nclsctx\ncmpwgc\nCMSG\ncnwgc\nCODEOWNERS\ncodepage\nCOINIT\nCOMGLB\ncommandline\ncompressapi\nconcurrencysal\nconstexpr\ncontactsupport\ncontentfiles\ncontosoinstaller\ncontractversion\ncopyable\ncorecrt\ncount'th\ncountof\ncountryregion\nCov\nCPIL\ncreatemanifestmetadata\ncrt\ncswinrt\nctc\nCTL\nctwgcy\ncurrentuser\ndacl\ndatetimeoffset\nDbg\nDcom\nDCPPREST\ndebian\ndecompressor\ndedupe\ndefaultlib\nDEFT\ndeigh\ndeleteifnotneeded\ndeliveryoptimization\ndeliveryoptimizationerrors\nDENYWR\ndesktopappinstaller\ndevblogs\ndevhome\nDFX\nDHAVE\ndic\ndiskfull\nDISPLAYCATALOG\nDMC\ndnld\nDns\nDobbeleer\nDONOT\ndsc\ndustojnikhummer\ndvinns\ndwgs\ndwrite\nDYAML\necfr\necfrbrowse\nEFGH\nENDSESSION\nEQU\nERANGE\nerrcode\nerrmsg\nERRORONEXIT\nerrstr\nESRB\netl\nevtx\newgp\newgs\nexecustom\nEXEHASH\nexperimentalfeatures\nXPRESS\nfdw\nfdwgp\nFECAFEB\nfedorapeople\nfileinuse\nfilemode\nFiletime\nFiltercriteria\nFinalizers\nfintimes\nflargle\nflexera\nFOF\nFOLDERID\nFONTCHANGE\nFONTHASH\nFORPARSING\nfoundfr\nfsanitize\nFULLMUTEX\nFULLWIDTH\nfundraiser\nfuzzer\nfzanollo\ngcpi\nGDK\nGES\nGESMBH\ngetwinget\nGHS\ngithub\ngitlab\ngity\ngoku\nGRPICONDIR\nGRPICONDIRENTRY\nguiddef\nGumbalapura\ngwgc\ngwgcd\ngwgp\ngwgse\ngwgso\ngwgus\ngwgv\nHackathon\nhashtables\nhelplib\nhelplibrary\nhhx\nhighcontrast\nHINSTANCE\nhkey\nhlocal\nhmac\nhmodule\nHostx\nHowto\nhre\nhresults\nhwnd\nhybridcrt\nHyperlink\nIARP\nIAttachment\nICONDIR\nICONDIRENTRY\nICONIMAGE\nicu\nidl\nIDSC\nidx\nIFACEMETHODIMP\niid\nimg\ninet\ninnererror\ninproc\nInsta\ninstallinprogress\nINSTALLPROPERTY\ninstallshield\ninstream\ninsufficientmemory\nIntelli\nINTRESOURCE\ninvalidparameter\nishelp\nISQ\nISVs\niswgp\nitr\niwgc\nIWIC\niwr\nJArray\nJDictionary\nJDK\njfearn\nJObject\njpalardy\nJREs\njrsoftware\njsoncpp\nJToken\nJValue\nKaido\nKNOWNFOLDERID\nkool\nktf\nLCID\nlearnxinyminutes\nLEBOM\nlhs\nLIBYAML\nliv\nliwpx\nlocalizationpriority\nlocalsource\nLogon\nLONGLONG\nLOWORD\nLPARAM\nLPBYTE\nLPCWSTR\nlpdw\nLPDWORD\nlpfn\nLPGRPICONDIR\nLPGRPICONDIRENTRY\nLPICONDIR\nLPICONDIRENTRY\nLPICONIMAGE\nlpitemidlist\nLPSTR\nlpsz\nLPVOID\nLPW\nLPWCH\nLPWSTR\nLRESULT\nLSTATUS\nLTDA\nluffy\nLuffytaro\nmaclachlan\nMadhusudhan\nMAJORVERSION\nmalware\nmapdatafolding\nMaxed\nMAXLENGTH\nmaxvalue\nmaybenull\nMBH\nMBs\nmcr\nmday\nmdmp\nmdmpto\nMDs\nmegamorf\nmicrosoftentraid\nmicrosoftentraidforazureblobstorage\nmidl\nminidump\nMINORVERSION\nmissingdependency\nmkgmtime\nMMmmbbbb\nMODULEENTRY\nmof\nmonicka\nMPNS\nmsdownload\nmsft\nmsftrubengu\nMSIHASH\nMSIXHASH\nMSIXSTRM\nmsstore\nMSZIP\nmszyml\nmta\nMugiwara\nMultideclaration\nmysource\nnativehandle\nNBLGGH\nncreate\nNESTEDINSTALLER\nnetlify\nNETSDK\nNewtonsoft\nnlohmann\nNNS\nNOAGGREGATION\nNOCLOSE\nNOCRLF\nNOEXPAND\nNOLINKINFO\nnomem\nNONAME\nnonetwork\nNONFOLDERS\nnonterminated\nNOREMOVE\nnormer\nNOSEARCH\nnotalostreference\nNOTIMPL\nNOTRACK\nNOUPDATE\nnowarn\nnpmjs\nnsis\nNTFS\nobjbase\nobjidl\noctokitnet\nofile\noid\nomus\nonefuzz\noop\nopensource\nOPTOUT\nosfhandle\noss\noutfile\nOUTOFMEMORY\nOutptr\nOVERLAPPEDWINDOW\nOWC\npackageinuse\npackageinusebyapplication\nPACL\nPARAMETERMAP\npathparts\npathtree\nPatil\npbstr\npcb\nPCCERT\nPCs\npcwsz\npdb\nPDWORD\npeetdev\nPEGI\npfn\npgp\nPherson\npid\npidl\npidlist\nPKCS\npkgmgr\npkindex\npkix\nplaceholders\nPMS\npositionals\nposix\npostuninstall\npowershellgallery\nPPROCESS\npri\nPRIMARYKEY\nprocessthreads\nproductcode\nPRODUCTICON\npropkey\nPROPVARIANT\nproxystub\npsapi\npscustomobject\npseudocode\nPSHOST\npsobject\npsz\nptstr\npublickey\nPVD\npvk\npvm\npwabuilder\nPWAs\nPWSTR\npwsz\nQUERYENDSESSION\nqword\nRAII\nranm\nrebootinitiated\nrebootrequiredforinstall\nrebootrequiredtofinish\nredirector\nRedist\nREFIID\nREGDB\nregexes\nREGSAM\nremoting\nremovefile\nreparse\nrepeatedkey\nREQS\nrequirenonleaf\nrestsource\nRGBQUAD\nrgp\nrgpsz\nrhs\nriid\nroapi\nRoblox\nronomon\nrowid\nroy\nrpwgpm\nRRF\nrrr\nrswgs\nRTTI\nrunspace\nruntimeclass\nruntimes\nrwgch\nrwgs\nryfu\nsacl\nsancov\nSARL\nsavepoint\nsawgc\nschematab\nScm\nsddl\nsecureobject\nsecurestring\nseekp\nseof\nservercert\nservercertificate\nsetmetadatabymanifestid\nSETTINGCHANGE\nSETTINGMAPPING\nsfs\nsfsclient\nSHCONTF\nshellapi\nSHGDN\nSHOWNORMAL\nsid\nSideload\nSIGNATUREHASH\nsilentpreferred\nSINGLETHREADED\nSkipx\nsku\nSLAPI\nSMTO\nSNAME\nSNAPMODULE\nSNAPTHREAD\nsortof\nsourceforge\nSOURCESDIRECTORY\nsourceversion\nspamming\nSPAPI\nspwgc\nsqlite\nSrinivasan\nSRL\nsrs\nSTDMETHODCALLTYPE\nstoreapps\nstoreorigin\nSTRRET\nstylecop\nsubdir\nsubkey\nSudarshan\nsuperstring\nswgus\nSYD\nSYG\nsystemnotsupported\nTagit\nTARG\ntaskhostw\ntcreate\ntcs\ntellp\ntemppath\ntestexampleinstaller\nthiscouldbeapc\nTHREADENTRY\nthreehundred\ntimespan\nTlg\ntlhelp\nTLSCAs\ntombstoned\nToolhelp\ntransitioning\ntrimstart\nttl\ntwgc\ntwgus\ntypedef\nUCase\nucasemap\nUChars\nucnv\nucrt\nudwgp\nuec\nULONGLONG\nUNAVAIL\nuninitialize\nunins\nuninstallation\nuninstaller\nuninstallprevious\nuninstalls\nunknwn\nUnknwnbase\nUNMARSHALING\nunparsable\nUnregisters\nunvirtualized\nUParse\nupgradable\nupgradecode\nURLZONE\nUSEDEFAULT\nuserfilesetting\nuserprofile\nuswgp\nuwp\nVALUENAMECASE\nvclib\nversioned\nVERSIONINFO\nvns\nvsconfig\nvstest\nwaitable\nwal\nwcex\nWDAG\nwebpages\nWebserver\nwebsite\nwesome\nwfsopen\nwgetenv\nWHATIF\nWIC\nwildcards\nWINAPI\nwincodec\nwindir\nwindowsdeveloper\nwinerror\nwinevt\nwingdi\nwingetconfigroot\nwingetcreate\nwingetdev\nwingetutil\nwinreg\nwinrtact\nwinstring\nWMI\nwmmc\nwnd\nWNDCLASS\nWNDCLASSEX\nworkaround\nWPARAM\nWpp\nwpr\nwprp\nwputenv\nwsb\nwsl\nwsv\nwto\nwwinmain\nWZDNCRFJ\nxcopy\nXes\nXFile\nXManifest\nXMUGIWARAMODULE\nXName\nXPLATSTR\nXRESOURCEZORO\nxsi\nyamato\nyao\nZanollo\nZIPHASH\nzoro\n"
  },
  {
    "path": ".github/actions/spelling/line_forbidden.patterns",
    "content": "# reject `m_data` as VxWorks defined it and that breaks things if it's used elsewhere\n# see [fprime](https://github.com/nasa/fprime/commit/d589f0a25c59ea9a800d851ea84c2f5df02fb529)\n# and [Qt](https://github.com/qtproject/qt-solutions/blame/fb7bc42bfcc578ff3fa3b9ca21a41e96eb37c1c7/qtscriptclassic/src/qscriptbuffer_p.h#L46)\n#\\bm_data\\b\n\n# Were you debugging using a framework with `fit()`?\n# If you have a framework that uses `it()` for testing and `fit()` for debugging a specific test,\n# you might not want to check in code where you skip all the other tests.\n#\\bfit\\(\n\n# Should be `HH:MM:SS`\n\\bHH:SS:MM\\b\n\n# Should be `86400` (seconds in a standard day)\n\\b84600\\b(?:.*\\bday\\b)\n\n# Should probably be `2006-01-02` (yyyy-mm-dd)\n# Assuming that the time is being passed to https://go.dev/src/time/format.go\n\\b2006-02-01\\b\n\n# Should probably be `YYYYMMDD`\n\\b[Yy]{4}[Dd]{2}[Mm]{2}(?!.*[Yy]{4}[Dd]{2}[Mm]{2}).*$\n\n# Should be `a priori` or `and prior`\n(?i)(?<!posteriori)\\sand priori\\s\n\n# Should only be one of `a`, `an`, or `the`\n\\b(?:(?:an?|the)\\s+){2,}\\b\n\n# Should be `anymore`\n\\bany more[,.]\n\n# Should be `'`\n(?i)\\b(?:(?:i|s?he|they|what|who|you)\"ll|(?:are|ca|did|do|does|ha[ds]|have|is|should|were|wo|would)n\"t|(?:s?he|let|that|there|what|where|who)\"s|(?:i|they|we|what|who|you)\"ve)\\b\n\n# Should be `briefcase`\n\\bbrief-case\\b\n\n# Should be `can, not only ..., ... also...`\n\\bcan not only.*can also\\b\n\n# Should be `cannot` (or `can't`)\n# See https://www.grammarly.com/blog/cannot-or-can-not/\n# > Don't use `can not` when you mean `cannot`. The only time you're likely to see `can not` written as separate words is when the word `can` happens to precede some other phrase that happens to start with `not`.\n# > `Can't` is a contraction of `cannot`, and it's best suited for informal writing.\n# > In formal writing and where contractions are frowned upon, use `cannot`.\n# > It is possible to write `can not`, but you generally find it only as part of some other construction, such as `not only . . . but also.`\n# - if you encounter such a case, add a pattern for that case to patterns.txt.\n\\b[Cc]an not\\b\n\n# Do not use `(click) here` links\n# For more information, see:\n# * https://www.w3.org/QA/Tips/noClickHere\n# * https://webaim.org/techniques/hypertext/link_text\n# * https://granicus.com/blog/why-click-here-links-are-bad/\n# * https://heyoka.medium.com/dont-use-click-here-f32f445d1021\n(?:>|\\[)(?:(?:click |)here|link|(?:read |)more)(?:</|\\]\\()(?!value>)\n\n# Should be `equals` to `is equal to`\n\\bequals to\\b\n\n# Should be `GitHub`\n(?<![&*.]|// |\\b(?:from|import|type) )\\bGithub\\b(?![{()])\n\n# Should be `GitLab`\n(?<![&*.]|// |\\b(?:from|import|type) )\\bGitlab\\b(?![{()])\n\n# Should probably be `https://`...\n# Markdown generally doesn't assume that links are to urls\n\\]\\(www\\.\\w\n\n# Should be `JavaScript`\n\\bJavascript\\b\n\n# Should be `macOS` or `Mac OS X` or ...\n\\bMacOS\\b\n\n# Should be `Microsoft`\n\\bMicroSoft\\b\n\n# Should be `OAuth`\n(?:^|[^-/*$])[ '\"]oAuth(?: [a-z]|\\d+ |[^ a-zA-Z0-9:;_.()])\n\n# Should be `RabbitMQ`\n\\bRabbitmq\\b\n\n# Should be `TypeScript`\n\\bTypescript\\b\n\n# Should be `another`\n\\ban[- ]other\\b\n\n# Should be `case-(in)sensitive`\n\\bcase (?:in|)sensitive\\b\n\n# Should be `coinciding`\n\\bco-inciding\\b\n\n# Should be `deprecation warning(s)`\n\\b[Dd]epreciation [Ww]arnings?\\b\n\n# Should be `greater than`\n\\bgreater then\\b\n\n# Should be `has`\n\\b[Ii]t only have\\b\n\n# Should be `here-in`, `the`, `them`, `this`, `these` or reworded in some other way\n\\bthe here(?:\\.|,| (?!and|defined))\n\n# Should be `greater than`\n#\\bhigher than\\b\n\n# Should be `ID`\n#\\bId\\b\n\n# Should be `in front of`\n\\bin from of\\b\n\n# Should be `into`\n# when not phrasal and when `in order to` would be wrong:\n# https://thewritepractice.com/into-vs-in-to/\n#\\sin to\\s(?!if\\b)\n\n# Should be `use`\n\\sin used by\\b\n\n# Should be `is obsolete`\n\\bis obsolescent\\b\n\n# Should be `it's` or `its`\n\\bits['’]\n\n# Should be `its`\n\\bit's(?= own\\b)\n\n# Should be `log in`\n\\blogin to the\n\n# Should be `long-standing`\n\\blong standing\\b\n\n# Should probably be a person named `Nick` or the abbreviation `NIC`\n\\bNic\\b\n\n# Should be `not supposed`\n\\bsupposed not\\b\n\n# Should probably be `much more`\n\\bmore much\\b\n\n# Should be `perform its`\n\\bperform it's\\b\n\n# Should be `opt-in`\n#(?<!\\scan|for)(?<!\\sif)\\sopt in\\s\n\n# Should be `less than`\n\\bless then\\b\n\n# Should be `load balancer`\n\\b[Ll]oud balancer\n\n# Should be `moot`\n\\bmute point\\b\n\n# Should be `one of`\n(?<!-)\\bon of\\b\n\n# Should be `on the other hand`\n\\b(?i)on another hand\\b\n\n# Most people only have two hands. Reword.\n\\b(?i)on the third hand\\b\n\n# Should be `otherwise`\n\\bother[- ]wise\\b\n\n# Should be `or (more|less)`\n\\bore (?:more|less)\\b\n\n# Should be `rather than`\n\\brather then\\b\n\n# Should be `regardless, ...` or `regardless of (whether)`\n\\b[Rr]egardless if you\\b\n\n# Should be `no longer needed`\n\\bno more needed\\b(?! than\\b)\n\n# Should be `did not exist`\n\\bwere not existent\\b\n\n# Should be `nonexistent`\n\\bnon existing\\b\n\n# Should be `nonexistent`\n\\b[Nn]o[nt][- ]existent\\b\n\n# Should be `@brief` / `@details` / `@param` / `@return` / `@retval`\n(?:^\\s*|(?:\\*|//|/*)\\s+`)[\\\\@](?:breif|(?:detail|detials)|(?:params(?!\\.)|prama?)|ret(?:uns?)|retvl)\\b\n\n# Should be `preexisting`\n[Pp]re[- ]existing\n\n# Should be `preempt`\n[Pp]re[- ]empt\\b\n\n# Should be `preemptively`\n[Pp]re[- ]emptively\n\n# Should be `prepopulate`\n[Pp]re[- ]populate\n\n# Should be `prerequisite`\n[Pp]re[- ]requisite\n\n# Should be `recently changed` or `recent changes`\n[Rr]ecent changed\n\n# Should be `reentrancy`\n[Rr]e[- ]entrancy\n\n# Should be `reentrant`\n[Rr]e[- ]entrant\n\n# Should be `strong suit`\n\\b(?:my|his|her|their) strong suite\\b\n\n# Should be `understand`\n\\bunder stand\\b\n\n# Should be `URI` or `uri` unless it refers to a person named `Uri`\n#(?<!\\.)\\bUri\\b(?![(])\n\n# Should be `it uses is`\n/\\bis uses is\\b/\n\n# Should be `uses it as`\n(?:^|\\. |and )uses is as (?!an?\\b|follows|livestock|[^.]+\\s+as\\b)\n\n# Should be `was`\n\\bhas been(?= removed in v?\\d)\n\n# Should be `where`\n\\bwere they are\\b\n\n# should be `vCenter`\n\\bV[Cc]enter\\b\n\n# Should be `VM`\n\\bVm\\b\n\n# Should be `workarounds`\n#\\bwork[- ]arounds\\b\n\n# Should be `workaround`\n(?:(?:[Aa]|[Tt]he|ugly)\\swork[- ]around\\b|\\swork[- ]around\\s+for)\n\n# Should be `worst`\n(?i)worse-case\n\n# Should be `you are not` or reworded\n\\byour not\\b\n\n# Should be `(coarse|fine)-grained`\n\\b(?:coarse|fine) grained\\b\n\n# Homoglyph (Cyrillic) should be `A`/`B`/`C`/`E`/`H`/`I`/`I`/`J`/`K`/`M`/`O`/`P`/`S`/`T`/`Y`\n# It's possible that your content is intentionally mixing Cyrllic and Latin scripts, but if it isn't, you definitely want to correct this.\n(?<=[A-Z]{2})[АВСЕНІӀЈКМОРЅТУ]|[АВСЕНІӀЈКМОРЅТУ](?=[A-Z]+(?:\\b|[a-z]+)|[a-z]+(?:[^a-z]|$))\n\n# Homoglyph (Cyrillic) should be `a`/`b`/`e`\n# It's possible that your content is intentionally mixing Cyrllic and Latin scripts, but if it isn't, you definitely want to correct this.\n[аве](?=[A-Za-z]{2,})|(?<=[A-Za-z]{2})[аве]|(?<=[A-Za-z])[аве](?=[A-Za-z])\n\n# Should be `neither/nor` -- or reword\n#(?!<do )\\bnot\\b([^.?!\"/(](?!neither|,.*?,))+\\bnor\\b\n\n# Should be `neither/nor` (plus rewording the beginning)\n# This is probably a double negative...\n#\\bnot\\b[^.?!\"/(]*\\bneither\\b[^.?!\"/(]*\\bnor\\b\n\n# In English, duplicated words are generally mistakes\n# There are a few exceptions (e.g. \"that that\").\n# If the highlighted doubled word pair is in:\n# * code, write a pattern to mask it.\n# * prose, have someone read the English before you dismiss this error.\n\\s([A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})\\s\\g{-1}\\s\n"
  },
  {
    "path": ".github/actions/spelling/patterns.txt",
    "content": "# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns\n\nREQUIRE(?:[_A-Z]*)\\(.*\\)\n\n\\bR(?:\"\\(.*\\)\"|\".*?\")\n\n\"ContinuationToken\"\\s*:\\s*\"[^\"]+\"\n\n8wekyb3d8bbwe\n_tisf_sqliteReturnValue\n\nEl proyecto .* diferentes\n\n# Package family names and package full names\n\\b[-_~.A-Za-z0-9]+_[a-z0-9]{13}\\b\n\n# Locales for name normalization\n\\b\\p{Lu}{2,3}(?:-(?:CANS|CYRL|LATN|MONG))?-\\p{Lu}{2}(?![A-Z])(?:-VALENCIA)?\\b\n\n# Azure pipeline tasks\n- task: .*\n\n# schema regex\n\"pattern\": .*$\n\n# doc/.../manifest.md\n^ShortDescription: Le nouveau.*$\n\n# Ignore test patterns\nGetRestAPIBaseUri\\(\".*\"\\) == L\".*\"\n\n# some forms of `any more` are correct\n\\battempt any more\\b\n\n# Sample store product id for App Installer\n9nblggh4nns1\n9NVTPZWRC6KQ\n9PCX3HX4HZ0Z\n\n# Automatically suggested patterns\n\n# hit-count: 3076 file-count: 503\n# IServiceProvider / isAThing\n(?:\\b|_)(?:(?:ns|)I|isA|T)(?=(?:[A-Z][a-z]{2,})+(?:[A-Z\\d]|\\b))\n\n# hit-count: 1396 file-count: 96\n# uuid:\n\\b[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\\b\n\n# hit-count: 366 file-count: 148\n# hex runs\n\\b[0-9a-fA-F]{16,}\\b\n\n# hit-count: 337 file-count: 135\n# microsoft\n\\b(?:https?://|)(?:(?:(?:apps|blogs|download\\.visualstudio|docs|msdn2?|research)\\.|)microsoft|blogs\\.msdn)\\.co(?:m|\\.\\w\\w)/[-_a-zA-Z0-9()=./%?&:#]*\n\n# hit-count: 296 file-count: 23\n# version suffix <word>v#\n(?:(?<=[A-Z]{2})V|(?<=[a-z]{2}|[A-Z]{2})v)\\d+(?:\\b|(?=[a-zA-Z_]))\n\n# hit-count: 171 file-count: 25\n# hex digits including css/html color classes:\n(?:[\\\\0][xX]|\\\\u|[uU]\\+|#x?|%23)[0-9_a-fA-FgGrR]*?[a-fA-FgGrR]{2,}[0-9_a-fA-FgGrR]*(?:[uUlL]{0,3}|[iu]\\d+)\\b\n\n# hit-count: 157 file-count: 75\n# GitHub SHAs (markdown)\n(?:\\[`?[0-9a-f]+`?\\]\\(https:/|)/(?:www\\.|)github\\.com(?:/[^/\\s\"]+){2,}(?:/[^/\\s\")]+)(?:[0-9a-f]+(?:[-0-9a-zA-Z/#.]*|)\\b|)\n\n# hit-count: 46 file-count: 17\n# base64 encoded pkcs\n\\bMII[-a-zA-Z=;:/0-9+]+\n\n# hit-count: 35 file-count: 7\n# libraries\n(?:\\b|_)lib(?:re(?=office)|)(?!elous|era[lt]|ero|erty|rar(?:i(?:an|es)|y))(?=[a-z])\n\n# hit-count: 14 file-count: 7\n# w3\n\\bw3\\.org/[-0-9a-zA-Z/#.]+\n\n# hit-count: 13 file-count: 6\n# Alternatively, if you're using check-spelling v0.0.25+, and you would like to _check_ the Non-English content for spelling errors, you can. For information on how to do so, see:\n# https://docs.check-spelling.dev/Feature:-Configurable-word-characters.html#unicode\n[a-zA-Z]*[ÀÁÂÃÄÅÆČÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæčçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź][a-zA-Z]{3}[a-zA-ZÀÁÂÃÄÅÆČÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæčçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź]*|[a-zA-Z]{3,}[ÀÁÂÃÄÅÆČÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæčçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź]|[ÀÁÂÃÄÅÆČÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæčçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź][a-zA-Z]{3,}\n\n# hit-count: 10 file-count: 3\n# URL escaped characters\n%[0-9A-F][A-F](?=[A-Za-z])\n\n# hit-count: 7 file-count: 3\n# Contributor\n\\[[^\\]]+\\]\\(https://github\\.com/[^/\\s\"]+/?\\)\n\n# hit-count: 6 file-count: 4\n# Markdown anchor links\n\\(#\\S*?[a-zA-Z]\\S*?\\)\n\n# hit-count: 4 file-count: 4\n# python\n\\b(?i)py(?!gments|gmy|lon|ramid|ro|th)(?=[a-z]{2,})\n\n# hit-count: 3 file-count: 3\n# mailto urls\nmailto:[-a-zA-Z=;:/?%&0-9+@._]{3,}\n\n# hit-count: 3 file-count: 3\n# githubusercontent\n/[-a-z0-9]+\\.githubusercontent\\.com/[-a-zA-Z0-9?&=_\\/.]*\n\n# hit-count: 1 file-count: 1\n# hex in url queries\n=[0-9a-fA-F]*?(?:[A-F]{3,}|[a-f]{3,})[0-9a-fA-F]*?&\n\nE2E\n\n# first-letter-bracketed-remainder\n\\b\\w\\[[A-Za-z]{3,}\\]\n\n# Questionably acceptable forms of `in to`\n# Personally, I prefer `log into`, but people object\n# https://www.tprteaching.com/log-into-log-in-to-login/\n\\b(?:(?:[Ll]og(?:g(?=[a-z])|)|[Ss]ign)(?:ed|ing)?) in to\\b\n\n# to opt in\n\\bto opt in\\b\n\n# acceptable duplicates\n# ls directory listings\n[-bcdlpsw](?:[-r][-w][-SsTtx]){3}[\\.+*]?\\s+\\d+\\s+\\S+\\s+\\S+\\s+[.\\d]+(?:[KMGT]|)\\s+\n# mount\n\\bmount\\s+-t\\s+(\\w+)\\s+\\g{-1}\\b\n# C types and repeated CSS values\n\\s(Architecture|auto|buffalo|center|div|inherit|long|LONG|none|normal|solid|thin|transparent|very)(?: \\g{-1})+\\s\n# C enum and struct\n\\b(?:enum|struct)\\s+(\\w+)\\s+\\g{-1}\\b\n# go templates\n\\s(\\w+)\\s+\\g{-1}\\s+\\`(?:graphql|inject|json|yaml):\n# doxygen / javadoc / .net\n(?:[\\\\@](?:brief|defgroup|groupname|link|t?param|return|retval)|(?:public|private|\\[Parameter(?:\\(.+\\)|)\\])(?:\\s+(?:static|override|readonly|required|virtual))*)(?:\\s+\\{\\w+\\}|)\\s+(\\w+)\\s+\\g{-1}\\s\n\n# macOS file path\n(?:Contents\\W+|(?!iOS)/)MacOS\\b\n\n# Python package registry has incorrect spelling for macOS / Mac OS X\n\"Operating System :: MacOS :: MacOS X\"\n\n# \"company\" in Germany\n\\bGmbH\\b\n\n# IntelliJ\n\\bIntelliJ\\b\n\n# Commit message -- Signed-off-by and friends\n^\\s*(?:(?:Based-on-patch|Co-authored|Helped|Mentored|Reported|Reviewed|Signed-off)-by|Thanks-to): (?:[^<]*<[^>]*>|[^<]*)\\s*$\n\n# Autogenerated revert commit message\n^This reverts commit [0-9a-f]{40}\\.$\n\n# ignore long runs of a single character:\n\\b([A-Za-z])\\g{-1}{3,}\\b\n\n# devil fruits\n\\s([A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})\\s\\g{-1}\\sno Mi\n\n# PowerShell Aliases defined in .cs files (not those in AliasesToExport in psd1 files)\n\\[Alias\\(\"[a-z]+\"\\)\\]\n"
  },
  {
    "path": ".github/actions/spelling/reject.txt",
    "content": "^attache$\n^bellow$\nbenefitting\noccurences?\n^dependan.*\n^diables?$\n^oer$\nSorce\n^[Ss]pae.*\n^Teh$\n^untill$\n^untilling$\n^wether.*\n"
  },
  {
    "path": ".github/copilot-instructions.md",
    "content": "# WinGet CLI Development Guide\r\n\r\n## Project Overview\r\n\r\nThis is the Windows Package Manager (WinGet) CLI client - a native Windows application for discovering and installing packages. The codebase consists of:\r\n\r\n- **C++/WinRT client** (`src/AppInstallerCLI*`) - The main CLI and core logic\r\n- **COM API** (`src/Microsoft.Management.Deployment`) - Public Windows Runtime API for programmatic access\r\n- **PowerShell modules** (`src/PowerShell`) - Microsoft.WinGet.Client and Microsoft.WinGet.Configuration cmdlets\r\n- **Configuration system** - DSC-based system configuration using WinGet\r\n\r\n## Building, Testing, and Running\r\n\r\n### Initial Setup\r\n\r\nUse a configuration file in `.config` as in `winget configure .config/configuration.winget` (alternatives provided for other VS SKUs).\r\n\r\nManual steps:\r\n\r\n1. Install Visual Studio 2022 with required workloads (see `.vsconfig`)\r\n2. Install Windows SDK 10.0.26100: `winget install Microsoft.WindowsSDK.10.0.26100`\r\n3. Enable developer mode in Windows\r\n4. Run `vcpkg integrate install` from Developer Command Prompt\r\n\r\n### Building\r\n\r\nOpen `src\\AppInstallerCLI.sln` in Visual Studio and build the solution (Ctrl+Shift+B) or use msbuild.exe to build from the command line.\r\n\r\nThe solution uses:\r\n- MSBuild\r\n- vcpkg for C++ dependencies\r\n- NuGet for C++ and .NET dependencies\r\n\r\n### Running/Debugging\r\n\r\n1. Deploy solution: Build > Deploy Solution\r\n2. Run from command line: `wingetdev`\r\n3. For debugging:\r\n   - Right-click `AppInstallerCLIPackage` > Properties > Debug tab\r\n   - Set Debugger type to \"Native Only\" for both Application and Background task processes\r\n   - Select \"Do not launch, but debug my code when it starts\"\r\n   - Press F5 and run `wingetdev` in a separate terminal\r\n\r\nEntry point: `src/AppInstallerCLI/main.cpp`\r\n\r\n### Testing\r\n\r\n#### C++ Unit Tests (Catch2)\r\nLocated in `AppInstallerCLITests` project. After building:\r\n\r\n```powershell\r\n# Run all tests\r\nsrc\\<ARCH>\\<Debug|Release>\\AppInstallerCLITests\\AppInstallerCLITests.exe\r\n\r\n# Run specific test\r\nsrc\\<ARCH>\\<Debug|Release>\\AppInstallerCLITests\\AppInstallerCLITests.exe TestName\r\n\r\n# Available options\r\nAppInstallerCLITests.exe --help\r\n```\r\n\r\n#### .NET Tests\r\n- `Microsoft.WinGet.UnitTests` - PowerShell module tests\r\n- `Microsoft.Management.Configuration.UnitTests` - Configuration system tests\r\n- `WinGetUtilInterop.UnitTests` - Interop layer tests\r\n\r\n#### E2E Tests\r\n`AppInstallerCLIE2ETests` project contains end-to-end integration tests.\r\n\r\n## Architecture\r\n\r\n### Core Components\r\n\r\n**AppInstallerCLICore** - Core CLI logic organized around:\r\n- **ExecutionContext**: State container that flows through workflows. Contains arguments, reporter, flags, and data (ExecutionContextData.h)\r\n- **Workflows**: Composable functions that take ExecutionContext and perform operations (e.g., InstallFlow, UpdateFlow, SearchFlow)\r\n- **Commands**: Parse arguments and orchestrate workflows\r\n- **Reporter**: Handles all user output (ExecutionReporter.h)\r\n\r\n**AppInstallerRepositoryCore** - Package source abstraction:\r\n- Interfaces for different source types (REST, SQLite index, Microsoft Store, composite)\r\n- Search, match, and correlation logic\r\n- Package version selection and dependencies\r\n\r\n**AppInstallerCommonCore** - Shared utilities:\r\n- Manifest parsing (YAML/JSON)\r\n- Settings and group policy\r\n- Telemetry and logging\r\n- HTTP client, downloader, archive handling\r\n\r\n**Microsoft.Management.Deployment** - COM API surface:\r\n- IDL definitions in `PackageManager.idl`\r\n- WinRT projections for external consumption\r\n- Used by PowerShell modules and third-party integrations\r\n\r\n**AppInstallerCLIPackage** - Dev MSIX package definition:\r\n- Models the release package definition as closely as possible.\r\n- Contains localized string resources at src\\AppInstallerCLIPackage\\Shared\\Strings\\en-us\\winget.resw\r\n\r\n### Key Patterns\r\n\r\n**Workflow Pattern**: Functions that operate on ExecutionContext:\r\n```cpp\r\nvoid WorkflowTask(Execution::Context& context)\r\n{\r\n    // Check if already terminated\r\n    AICLI_RETURN_IF_TERMINATED(context);\r\n    \r\n    // Access data\r\n    auto& data = context.Get<Data::Installer>();\r\n    \r\n    // Report to user\r\n    context.Reporter.Info() << \"Doing something\";\r\n    \r\n    // Store data for next workflow\r\n    context.Add<Data::SomeResult>(result);\r\n    \r\n    // Terminate on error\r\n    if (failed)\r\n    {\r\n        AICLI_TERMINATE_CONTEXT(HRESULT);\r\n    }\r\n}\r\n```\r\n\r\n**Source Composition**: Multiple package sources can be composed:\r\n- CompositeSource combines multiple sources with conflict resolution\r\n- Installed source tracks locally installed packages\r\n- Available sources provide packages to install\r\n\r\n**Manifest Schema**: Package manifests use versioned YAML schemas:\r\n- Schema definitions in `schemas/JSON/manifests/`\r\n- Parsing in `AppInstallerCommonCore/Manifest/`\r\n- Multi-file manifests: installer, locale, version, defaultLocale\r\n\r\n## Naming Conventions\r\n\r\n- **Namespace structure**: `AppInstaller::<Area>[::<Subarea>]`\r\n  - `AppInstaller::CLI::Execution` - CLI execution context\r\n  - `AppInstaller::CLI::Workflow` - Workflow functions\r\n  - `AppInstaller::Repository` - Repository/source logic\r\n  - `AppInstaller::Manifest` - Manifest types\r\n  - `AppInstaller::Settings` - User/admin settings\r\n\r\n- **Macros**: Prefixed with `AICLI_` for CLI, `WINGET_` for general\r\n- **Data keys**: ExecutionContextData uses enum keys to type-safely store/retrieve data\r\n\r\n## Windows-Specific Considerations\r\n\r\n- Use Windows-style paths with backslashes (`\\`)\r\n- Leverage WinRT APIs via C++/WinRT projections\r\n- COM threading models matter - client uses multi-threaded apartment (MTA)\r\n- Package deployment uses Windows App SDK / MSIX infrastructure\r\n- Requires Windows 10 1809+ (build 17763)\r\n\r\n## Contributing\r\n\r\n- Review `CONTRIBUTING.md` for workflow\r\n- File/discuss issues before starting work\r\n- Specs required for features (stored in `doc/specs/`)\r\n- Follow existing code style (see `stylecop.json`)\r\n- CI runs on Azure Pipelines (`azure-pipelines.yml`)\r\n\r\n## Useful Commands\r\n\r\n```powershell\r\n# Get WinGet client info\r\nwingetdev --info\r\n\r\n# Show experimental features\r\nwingetdev features\r\n\r\n# Check sources\r\nwingetdev source list\r\n```\r\n"
  },
  {
    "path": ".github/images/README.md",
    "content": "This directory is intended to host images for use in GitHub markdown files.\n"
  },
  {
    "path": ".github/policies/automergeTriggers.yml",
    "content": "id: automergeTriggers\nname: GitOps.PullRequestIssueManagement\ndescription: Handles enabling / disabling automerge\nowner:\nresource: repository\ndisabled: false\nwhere:\nconfiguration:\n  resourceManagementConfiguration:\n    eventResponderTasks:\n      - description: Enable Auto Merge when the \"AutoMerge\" label is present\n        if:\n          - payloadType: Pull_Request\n          - hasLabel:\n              label: AutoMerge\n        then:\n          - enableAutoMerge:\n              mergeMethod: Squash\n      - description: Disable Auto Merge when the \"AutoMerge\" label is not present\n        if:\n          - payloadType: Pull_Request\n          - or:\n              - labelRemoved:\n                  label: AutoMerge\n              - not:\n                  hasLabel:\n                    label: AutoMerge\n        then:\n          - disableAutoMerge\nonFailure:\nonSuccess:\n"
  },
  {
    "path": ".github/policies/labelAdded.noRecentActivity.yml",
    "content": "id: labelAdded.noRecentActivity\nname: GitOps.PullRequestIssueManagement\ndescription: Handlers when \"No-Recent-Activity\" label is added\nowner:\nresource: repository\ndisabled: false\nwhere:\nconfiguration:\n  resourceManagementConfiguration:\n    eventResponderTasks:\n      - description: >-\n          When the label \"No-Recent-Activity\" is added to a pull request\n          * Add the PR specific reply notifying the issue author of pending closure\n        if:\n          - payloadType: Pull_Request\n          - labelAdded:\n              label: No-Recent-Activity\n        then:\n          - addReply:\n              reply: >-\n                Hello @${issueAuthor},\n\n\n                This pull request has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for **7 days**. It will be closed if no further activity occurs **within 7 days of this comment**.\n\n\n                Template: msftbot/noRecentActivity\n        # The policy service should trigger even when the label was added by the policy service\n        triggerOnOwnActions: true\n      - description: >-\n          When the label \"No-Recent-Activity\" is added to an issue\n          * Add the issue specific reply notifying the issue author of pending closure\n        if:\n          - payloadType: Issues\n          - labelAdded:\n              label: No-Recent-Activity\n        then:\n          - addReply:\n              reply: >-\n                Hello @${issueAuthor},\n\n\n                This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for **7 days**. It will be closed if no further activity occurs **within 7 days of this comment**.\n\n\n                Template: msftbot/noRecentActivity\n        # The policy service should trigger even when the label was added by the policy service\n        triggerOnOwnActions: true\nonFailure:\nonSuccess:\n"
  },
  {
    "path": ".github/policies/labelManagement.issueClosed.yml",
    "content": "id: labelManagement.issueClosed\nname: GitOps.PullRequestIssueManagement\ndescription: Handlers when an issue gets closed\nowner:\nresource: repository\ndisabled: false\nwhere:\nconfiguration:\n  resourceManagementConfiguration:\n    eventResponderTasks:\n      - description: Remove labels when an issue is closed\n        if:\n          - payloadType: Issues\n          - isAction:\n              action: Closed\n        then:\n          - removeLabel:\n              label: Needs-Triage\n          - removeLabel:\n              label: Needs-Attention\n          - removeLabel:\n              label: Needs-Author-Feedback\n          - removeLabel:\n              label: Help-Wanted\n        ## TODO: Unassign author\n      - description: Remove labels when a pull request is closed\n        if:\n          - payloadType: Pull_Request\n          - isAction:\n              action: Closed\n        then:\n          - removeLabel:\n              label: Needs-Attention\n          - removeLabel:\n              label: Needs-Author-Feedback\n        ## TODO: Unassign Users\nonFailure:\nonSuccess:\n"
  },
  {
    "path": ".github/policies/labelManagement.issueOpened.yml",
    "content": "id: labelManagement.issueOpened\nname: GitOps.PullRequestIssueManagement\ndescription: Handlers for when an issue is first opened\nowner:\nresource: repository\ndisabled: false\nwhere:\nconfiguration:\n  resourceManagementConfiguration:\n    eventResponderTasks:\n      - description: Add CodeFlow link to new PRs\n        if:\n          - payloadType: Pull_Request\n          - isAction:\n              action: Opened\n        then:\n          - addCodeFlowLink\n      - description: Add Needs-Triage to new issues\n        if:\n          - payloadType: Issues\n          - isAction:\n              action: Opened\n        then:\n          - addLabel:\n              label: Needs-Triage\n      ### Area Labels\n      - description: Add area label for PowerShell Module\n        if:\n          - payloadType: Issues\n          - isAction:\n              action: Opened\n          - bodyContains:\n              pattern: 'Relevant area\\(s\\)\\s*\\n.*PowerShell Module'\n              isRegex: True\n        then:\n          - addLabel:\n              label: PowerShell\n      - description: Add area label for COM API\n        if:\n          - payloadType: Issues\n          - isAction:\n              action: Opened\n          - bodyContains:\n              pattern: 'Relevant area\\(s\\)\\s*\\n.*COM API'\n              isRegex: True\n        then:\n          - addLabel:\n              label: Area-COM-API\n      - description: Add area label for WinGet DSC Resources\n        if:\n          - payloadType: Issues\n          - isAction:\n              action: Opened\n          - bodyContains:\n              pattern: 'Relevant area\\(s\\)\\s*\\n.*DSC Resource'\n              isRegex: True\n        then:\n          - addLabel:\n              label: DSC-Resource\n      ### Commands Labels\n      - description: Add command label for 'winget configure'\n        if:\n          - payloadType: Issues\n          - isAction:\n              action: Opened\n          - bodyContains:\n              pattern: 'Relevant command\\(s\\)\\s*\\n.*winget configure'\n              isRegex: True\n        then:\n          - addLabel:\n              label: Command-Configure\n      - description: Add command label for 'winget download'\n        if:\n          - payloadType: Issues\n          - isAction:\n              action: Opened\n          - bodyContains:\n              pattern: 'Relevant command\\(s\\)\\s*\\n.*winget download'\n              isRegex: True\n        then:\n          - addLabel:\n              label: Command-Download\n      - description: Add command label for 'winget dscv3'\n        if:\n          - payloadType: Issues\n          - isAction:\n              action: Opened\n          - bodyContains:\n              pattern: 'Relevant command\\(s\\)\\s*\\n.*winget dscv3'\n              isRegex: True\n        then:\n          - addLabel:\n              label: Command-DSCv3\n      - description: Add command label for 'winget export'\n        if:\n          - payloadType: Issues\n          - isAction:\n              action: Opened\n          - bodyContains:\n              pattern: 'Relevant command\\(s\\)\\s*\\n.*winget export'\n              isRegex: True\n        then:\n          - addLabel:\n              label: Command-Export\n      - description: Add command label for 'winget features'\n        if:\n          - payloadType: Issues\n          - isAction:\n              action: Opened\n          - bodyContains:\n              pattern: 'Relevant command\\(s\\)\\s*\\n.*winget features'\n              isRegex: True\n        then:\n          - addLabel:\n              label: Command-Features\n      - description: Add command label for 'winget font'\n        if:\n          - payloadType: Issues\n          - isAction:\n              action: Opened\n          - bodyContains:\n              pattern: 'Relevant command\\(s\\)\\s*\\n.*winget font'\n              isRegex: True\n        then:\n          - addLabel:\n              label: Command-Font\n      - description: Add command label for 'winget hash'\n        if:\n          - payloadType: Issues\n          - isAction:\n              action: Opened\n          - bodyContains:\n              pattern: 'Relevant command\\(s\\)\\s*\\n.*winget hash'\n              isRegex: True\n        then:\n          - addLabel:\n              label: Command-Hash\n      - description: Add command label for 'winget import'\n        if:\n          - payloadType: Issues\n          - isAction:\n              action: Opened\n          - bodyContains:\n              pattern: 'Relevant command\\(s\\)\\s*\\n.*winget import'\n              isRegex: True\n        then:\n          - addLabel:\n              label: Command-Import\n      - description: Add command label for 'winget install'\n        if:\n          - payloadType: Issues\n          - isAction:\n              action: Opened\n          - bodyContains:\n              pattern: 'Relevant command\\(s\\)\\s*\\n.*winget install'\n              isRegex: True\n        then:\n          - addLabel:\n              label: Command-Install\n      - description: Add command label for 'winget list'\n        if:\n          - payloadType: Issues\n          - isAction:\n              action: Opened\n          - bodyContains:\n              pattern: 'Relevant command\\(s\\)\\s*\\n.*winget list'\n              isRegex: True\n        then:\n          - addLabel:\n              label: Command-List\n      - description: Add command label for 'winget mcp'\n        if:\n          - payloadType: Issues\n          - isAction:\n              action: Opened\n          - bodyContains:\n              pattern: 'Relevant command\\(s\\)\\s*\\n.*winget mcp'\n              isRegex: True\n        then:\n          - addLabel:\n              label: Command-MCP\n      - description: Add command label for 'winget pin'\n        if:\n          - payloadType: Issues\n          - isAction:\n              action: Opened\n          - bodyContains:\n              pattern: 'Relevant command\\(s\\)\\s*\\n.*winget pin'\n              isRegex: True\n        then:\n          - addLabel:\n              label: Command-Pin\n      - description: Add command label for 'winget repair'\n        if:\n          - payloadType: Issues\n          - isAction:\n              action: Opened\n          - bodyContains:\n              pattern: 'Relevant command\\(s\\)\\s*\\n.*winget repair'\n              isRegex: True\n        then:\n          - addLabel:\n              label: Command-Repair\n      - description: Add command label for 'winget search'\n        if:\n          - payloadType: Issues\n          - isAction:\n              action: Opened\n          - bodyContains:\n              pattern: 'Relevant command\\(s\\)\\s*\\n.*winget search'\n              isRegex: True\n        then:\n          - addLabel:\n              label: Command-Search\n      - description: Add command label for 'winget settings'\n        if:\n          - payloadType: Issues\n          - isAction:\n              action: Opened\n          - bodyContains:\n              pattern: 'Relevant command\\(s\\)\\s*\\n.*winget settings'\n              isRegex: True\n        then:\n          - addLabel:\n              label: Command-Settings\n      - description: Add command label for 'winget show'\n        if:\n          - payloadType: Issues\n          - isAction:\n              action: Opened\n          - bodyContains:\n              pattern: 'Relevant command\\(s\\)\\s*\\n.*winget show'\n              isRegex: True\n        then:\n          - addLabel:\n              label: Command-Show\n      - description: Add command label for 'winget source'\n        if:\n          - payloadType: Issues\n          - isAction:\n              action: Opened\n          - bodyContains:\n              pattern: 'Relevant command\\(s\\)\\s*\\n.*winget source'\n              isRegex: True\n        then:\n          - addLabel:\n              label: Command-Source\n      - description: Add command label for 'winget uninstall'\n        if:\n          - payloadType: Issues\n          - isAction:\n              action: Opened\n          - bodyContains:\n              pattern: 'Relevant command\\(s\\)\\s*\\n.*winget uninstall'\n              isRegex: True\n        then:\n          - addLabel:\n              label: Command-Uninstall\n      - description: Add command label for 'winget upgrade'\n        if:\n          - payloadType: Issues\n          - isAction:\n              action: Opened\n          - bodyContains:\n              pattern: 'Relevant command\\(s\\)\\s*\\n.*winget upgrade'\n              isRegex: True\n        then:\n          - addLabel:\n              label: Command-Upgrade\n      - description: Add command label for 'winget validate'\n        if:\n          - payloadType: Issues\n          - isAction:\n              action: Opened\n          - bodyContains:\n              pattern: 'Relevant command\\(s\\)\\s*\\n.*winget validate'\n              isRegex: True\n        then:\n          - addLabel:\n              label: Command-Validate\nonFailure:\nonSuccess:\n"
  },
  {
    "path": ".github/policies/labelManagement.issueUpdated.yml",
    "content": "id: labelManagement.issueUpdated\nname: GitOps.PullRequestIssueManagement\ndescription: >-\n  Handlers for when an issue is updated and not closed\n  This primarily includes handlers for comments, reviews, and re-runs\nowner:\nresource: repository\ndisabled: false\nwhere:\nconfiguration:\n  resourceManagementConfiguration:\n    eventResponderTasks:\n      - description: Remove \"No-Recent-Activity\" when a pull request or issue is updated\n        if:\n          - or:\n              - payloadType: Pull_Request\n              - payloadType: Pull_Request_Review\n              - payloadType: Pull_Request_Review_Comment\n              - payloadType: Issue_Comment\n              - payloadType: Issues\n          - not:\n              isAction:\n                action: Closed\n          - hasLabel:\n              label: No-Recent-Activity\n        then:\n          - removeLabel:\n              label: No-Recent-Activity\n        # The policy service should not trigger itself here, or else the label would be removed immediately after being added\n        triggerOnOwnActions: False\n      - description: Clean email replies on every comment\n        if:\n          - payloadType: Issue_Comment\n        then:\n          - cleanEmailReply\n      - description: Remove \"Help-Wanted\" label when an issue goes into PR\n        if:\n          - payloadType: Issues\n          - labelAdded:\n              label: In-PR\n          - hasLabel:\n              label: Help-Wanted\n        then:\n          - removeLabel:\n              label: Help-Wanted\n      - description: >-\n          If an author responds to an issue which needs author feedback\n          * Remove the Needs-Author-Feedback Label\n          * Add the Needs-Attention Label\n        if:\n          - or:\n              - payloadType: Pull_Request_Review\n              - payloadType: Pull_Request_Review_Comment\n              - payloadType: Issue_Comment\n          - isActivitySender:\n              issueAuthor: True\n          - hasLabel:\n              label: Needs-Author-Feedback\n          - not:\n              isAction:\n                action: Synchronize\n        then:\n          - removeLabel:\n              label: Needs-Author-Feedback\n          - addLabel:\n              label: Needs-Attention\n      - description: >-\n          When changes are requested on a pull request\n          * Disable automerge\n          * Assign to the author\n          * Label with Needs-Author-Feedback\n        if:\n          - payloadType: Pull_Request_Review\n          - isAction:\n              action: Submitted\n          - isReviewState:\n              reviewState: Changes_requested\n        then:\n          - disableAutoMerge\n          - assignTo:\n              author: True\n          - addLabel:\n              label: Needs-Author-Feedback\n      - description: Sync labels from issues on all pull request events\n        if:\n          - payloadType: Pull_Request\n        then:\n          - labelSync:\n              pattern: Issue-\n          - labelSync:\n              pattern: Area-\n          - labelSync:\n              pattern: Priority-\n          - labelSync:\n              pattern: Product-\n          - labelSync:\n              pattern: Severity-\n          - labelSync:\n              pattern: Impact-\n          - inPrLabel:\n              label: In-PR\nonFailure:\nonSuccess:\n"
  },
  {
    "path": ".github/policies/labelManagement.needsFeedbackHub.yml",
    "content": "id: labelManagement.needsFeedbackHub\nname: GitOps.PullRequestIssueManagement\ndescription: Handlers when feedback hub is needed\nowner:\nresource: repository\ndisabled: false\nwhere:\nconfiguration:\n  resourceManagementConfiguration:\n    eventResponderTasks:\n      - description: >-\n          When the label \"Needs-Feedback-Hub\" is added to an issue or a repo admin comments /feedback\n          * Add a reply notifying the issue author\n          * Assign to the author\n          * Label with Needs-Author-Feedback\n          * Remove Needs-Feedback-Hub label\n        if:\n          - or:\n              # Trigger by label add\n              - and:\n                  - payloadType: Issues\n                  - labelAdded:\n                      label: Needs-Feedback-Hub\n              # Trigger by comment\n              - and:\n                  - payloadType: Issue_Comment\n                  - commentContains:\n                      pattern: '\\/feedback'\n                      isRegex: True\n                  - or:\n                      - activitySenderHasPermission:\n                          permission: Admin\n                      - activitySenderHasPermission:\n                          permission: Write\n        then:\n          - addReply:\n              reply: >-\n                Hello @${issueAuthor},\n\n\n                Please send us feedback with the Feedback Hub [Windows]+[f] with this issue and paste the link here so we can more easily find your crash information on the back end.\n\n                Please use \"Apps\" and \"Windows Package Manager\" for the Category.\n\n\n                The link on the bottom of the feedback report will provide the URL to paste in this Issue to share with us.\n\n\n                Template: msftbot/feedbackHub\n          - assignTo:\n              author: True\n          - addLabel:\n              label: Needs-Author-Feedback\n          - removeLabel:\n              label: Needs-Feedback-Hub\nonFailure:\nonSuccess:\n"
  },
  {
    "path": ".github/policies/labelManagement.triageLabels.yml",
    "content": "id: labelAdded.triageLabels\nname: GitOps.PullRequestIssueManagement\ndescription: Handlers for triaging issues when various labels are applied from Triage\nowner:\nresource: repository\ndisabled: false\nwhere:\nconfiguration:\n  resourceManagementConfiguration:\n    eventResponderTasks:\n      - description: >-\n          When specific labels are added to an issue\n          * Remove the Needs-Triage label\n        if:\n          - payloadType: Issues\n          - or:\n              - labelAdded:\n                  label: Area-Accessibility\n              - labelAdded:\n                  label: Area-Architecture\n              - labelAdded:\n                  label: Area-Build\n              - labelAdded:\n                  label: Area-External\n              - labelAdded:\n                  label: Area-GPO\n              - labelAdded:\n                  label: Area-Input\n              - labelAdded:\n                  label: Area-Localization\n              - labelAdded:\n                  label: Area-Manifest\n              - labelAdded:\n                  label: Area-Matching\n              - labelAdded:\n                  label: Area-Output\n              - labelAdded:\n                  label: Area-Path\n              - labelAdded:\n                  label: Area-Performance\n              - labelAdded:\n                  label: Area-Scope\n              - labelAdded:\n                  label: Area-Settings\n              - labelAdded:\n                  label: Area-Sorting\n              - labelAdded:\n                  label: Area-User-Interface\n              - labelAdded:\n                  label: Blocking-Issue\n              - labelAdded:\n                  label: Breaking-Change\n              - labelAdded:\n                  label: Dependencies\n              - labelAdded:\n                  label: Experimental\n              - labelAdded:\n                  label: Hardware\n              - labelAdded:\n                  label: In-PR\n              - labelAdded:\n                  label: Interactive-Only-Installer\n              - labelAdded:\n                  label: msstore\n              - labelAdded:\n                  label: Needs-Attention\n              - labelAdded:\n                  label: Needs-Author-Feedback\n              - labelAdded:\n                  label: Portable\n              - labelAdded:\n                  label: Public-Service-Announcement\n              - labelAdded:\n                  label: Side-By-Side\n              - labelAdded:\n                  label: Zipped-Binary\n        then:\n          - removeLabel:\n              label: Needs-Triage\n        # The policy service should trigger even when the label was added by the policy service\n        triggerOnOwnActions: true\nonFailure:\nonSuccess:\n"
  },
  {
    "path": ".github/policies/moderatorTriggers.yml",
    "content": "id: moderatorTriggers\nname: GitOps.PullRequestIssueManagement\ndescription: Defines the users and permissions for the moderators\nowner:\nresource: repository\ndisabled: false\nwhere:\nconfiguration:\n  resourceManagementConfiguration:\n    eventResponderTasks:\n      - if:\n          # If the activity sender is any one of the moderators, has Admin permission on the repo, or has Write permissions on the repo. . .\n          - or:\n              - activitySenderHasPermission:\n                  permission: Admin\n              - activitySenderHasPermission:\n                  permission: Write\n              - isActivitySender:\n                  user: stephengillie\n                  issueAuthor: False\n              - isActivitySender:\n                  user: ImJoakim\n                  issueAuthor: False\n              - isActivitySender:\n                  user: ItzLevvie\n                  issueAuthor: False\n              - isActivitySender:\n                  user: jedieaston\n                  issueAuthor: False\n              - isActivitySender:\n                  user: KaranKad\n                  issueAuthor: False\n              - isActivitySender:\n                  user: OfficialEsco\n                  issueAuthor: False\n              - isActivitySender:\n                  user: quhxl\n                  issueAuthor: False\n              - isActivitySender:\n                  user: Trenly\n                  issueAuthor: False\n              - isActivitySender:\n                  user: mdanish-kh\n                  issueAuthor: False\n              - isActivitySender:\n                  user: russellbanks\n                  issueAuthor: False\n        then:\n          # If the payload is an issue_Comment or a Pull_Request_Review_Comment\n          - if:\n              - or:\n                  - payloadType: Issue_Comment\n                  - payloadType: Pull_Request_Review_Comment\n            # Remove the Needs-Triage label\n            # Take different actions based on the comment pattern\n            then:\n              - removeLabel:\n                  label: Needs-Triage\n              # Area-Accessibility\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[aA]rea[\\s-][aA]ccessibility'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Area-Accessibility\n              # Area-Architecture\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[aA]rea[\\s-][aA]rchitecture'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Area-Architecture\n              # Area-Build\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[aA]rea[\\s-][bB]uild'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Area-Build\n              # Area-COM-API\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[aA]rea[\\s-][cC][oO][mM][\\s-][aA][pP][iI]'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Area-COM-API\n              # Area-External\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[aA]rea[\\s-][eE]xternal'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Area-External\n              # Area-GPO\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[aA]rea[\\s-][gG][pP][oO]'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Area-GPO\n              # Area-Input\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[aA]rea[\\s-][iI]nput'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Area-Input\n              # Area-Localization\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[aA]rea[\\s-][lL]ocalization'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Area-Localization\n              # Area-Manifest\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[aA]rea[\\s-][mM]anifest'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Area-Manifest\n              # Area-Matching\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[aA]rea[\\s-][mM]atching'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Area-Matching\n              # Area-Output\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[aA]rea[\\s-][oO]utput'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Area-Output\n              # Area-Path\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[aA]rea[\\s-][pP]ath'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Area-Path\n              # Area-Performance\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[aA]rea[\\s-][pP]erformance'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Area-Performance\n              # Area-Scope\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[aA]rea[\\s-][sS]cope'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Area-Scope\n              # Area-Settings\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[aA]rea[\\s-][sS]ettings'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Area-Settings\n              # Area-Sorting\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[aA]rea[\\s-][sS]orting'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Area-Sorting\n              # Area-User-Interface\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[aA]rea[\\s-][uU]ser[\\s-][iI]nterface'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Area-User-Interface\n              # Blocking-Issue\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[bB]locking[\\s-][iI]ssue'\n                      isRegex: True\n                then:\n                  - removeLabel:\n                      label: Needs-Author-Feedback\n                  - removeLabel:\n                      label: Needs-Attention\n                  - addLabel:\n                      label: Blocking-Issue\n              # Breaking-Change\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[bB]reaking[\\s-][cC]hange'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Breaking-Change\n              # Command-Configure\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[cC]ommand[\\s-][cC]onfigure'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Command-Configure\n              # Command-Download\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[cC]ommand[\\s-][dD]ownload'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Command-Download\n              # Command-Export\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[cC]ommand[\\s-][eE]xport'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Command-Export\n              # Command-Import\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[cC]ommand[\\s-][iI]mport'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Command-Import\n              # Command-Install\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[cC]ommand[\\s-][iI]nstall'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Command-Install\n              # Command-List\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[cC]ommand[\\s-][lL]ist'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Command-List\n              # Command-Pin\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[cC]ommand[\\s-][pP]in'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Command-Pin\n              # Command-Search\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[cC]ommand[\\s-][sS]earch'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Command-Search\n              # Command-Show\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[cC]ommand[\\s-][sS]how'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Command-Show\n              # Command-Source\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[cC]ommand[\\s-][sS]ource'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Command-Source\n              # Command-Uninstall\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[cC]ommand[\\s-][uU]ninstall'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Command-Uninstall\n              # Command-Upgrade\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[cC]ommand[\\s-][uU]pgrade'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Command-Upgrade\n              # Command-Validate\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[cC]ommand[\\s-][vV]alidate'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Command-Validate\n              # Context-Elevated-User\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[cC]ontext[\\s-][eE]levated([\\s-][uU]ser)?'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Context-Elevated-User\n              # Context-User\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[cC]ontext[\\s-][uU]ser'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Context-User\n              # Context-System\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[cC]ontext[\\s-][sS]ystem'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Context-System\n              # Dependencies\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[dD]ependencies'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Dependencies\n              # DSC-Resource\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[dD][sS][cC][\\s-][rR]esource'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: DSC-Resource\n              # Experimental\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[eE]xperimental'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Experimental\n              # Hardware\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[hH]ardware'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Hardware\n              # Interactive-Only-Installer\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[iI]nteractive[\\s-][oO]nly([\\s-][iI]nstaller)?'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Interactive-Only-Installer\n              # Issue-Bug\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[iI]ssue[\\s-][bB]ug'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Issue-Bug\n              # Issue-Docs\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[iI]ssue[\\s-][dD]ocs'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Issue-Docs\n              # Issue-Feature\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[iI]ssue[\\s-][fF]eature'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Issue-Feature\n              # msstore\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[mM][sS][sS]tore'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: msstore\n              # Needs-Attention\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[Nn]eeds[\\s-][Aa]ttention'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Needs-Attention\n              # Needs-Author-Feedback\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[Nn]eeds[\\s-][Aa]uthor[\\s-][fF]eedback'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Needs-Author-Feedback\n              # Needs-Repro\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[Nn]eeds[\\s-][Rr]epro'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Needs-Repro\n              # Portable\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[pP]ortable'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Portable\n              # PowerShell\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[pP]ower[sS]hell'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: PowerShell\n              # PSA\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[Pp][Ss][Aa]'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Public-Service-Announcement\n              # Side-By-Side\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[sS]ide[\\s-][bB]y[\\s-][sS]ide'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Side-By-Side\n              # Zipped-Binary\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[zZ]ip(ped)?[\\s-][bB]inary'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Zipped-Binary\n              # Zipped-Binary\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+([wW]indows[\\s-])?[sS]andbox'\n                      isRegex: True\n                then:\n                  - addLabel:\n                      label: Windows-Sandbox\n              # Unblocked\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[uU]nblocked'\n                      isRegex: True\n                then:\n                  - removeLabel:\n                      label: Blocking-Issue\n              # Duplicate of #\n              - if:\n                  - commentContains:\n                      pattern: Duplicate\\s+of\\s+\\#?\\s*\\d+\n                      isRegex: True\n                then:\n                  - addReply:\n                      reply: >-\n                        Hello @${issueAuthor},\n\n\n                        We've identified this as a duplicate of another issue or PR that already exists. This specific instance is being closed in favor of the linked issue. Please add your 👍 to the other issue to raise its priority. Thanks for your contribution!\n\n\n                        Template: msftbot/duplicate/closed\n                  - closeIssue\n                  - removeLabel:\n                      label: Needs-Triage\n                  - removeLabel:\n                      label: Needs-Attention\n                  - removeLabel:\n                      label: Needs-Feedback-Hub\n                  - removeLabel:\n                      label: Needs-Author-Feedback\n                  - addLabel:\n                      label: Resolution-Duplicate\n              # Close with reason <>;\n              - if:\n                  - commentContains:\n                      pattern: \"[cC]lose\\\\s+[wW]ith\\\\s+[rR]eason\\\\s*:[\\\\w\\\\s\\\\-\\\\(\\\\)\\\\[\\\\]\\\\{\\\\}\\\\\\\\\\\\/.+=@\\\\#$%&^*`~|'\\\",<>?]*(?=;)\"\n                      isRegex: True\n                then:\n                  - closeIssue\n                  - removeLabel:\n                      label: Needs-Triage\n                  - removeLabel:\n                      label: Needs-Attention\n                  - removeLabel:\n                      label: Needs-Feedback-Hub\n                  - removeLabel:\n                      label: Needs-Author-Feedback\n              # Reopen with reason <>;\n              - if:\n                  - commentContains:\n                      pattern: \"[rR]eopen\\\\s+[wW]ith\\\\s+[rR]eason\\\\s*:[\\\\w\\\\s\\\\-\\\\(\\\\)\\\\[\\\\]\\\\{\\\\}\\\\\\\\\\\\/.+=@\\\\#$%&^*`~|'\\\",<>?]*(?=;)\"\n                      isRegex: True\n                then:\n                  - reopenIssue\n                  - removeLabel:\n                      label: Resolution-Duplicate\n                  - removeLabel:\n                      label: No-Recent-Activity\n              # Reset-Feedback\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[rR]eset\\s+[fF]eedback'\n                      isRegex: True\n                then:\n                  - removeLabel:\n                      label: Needs-Author-Feedback\n                  - removeLabel:\n                      label: Needs-Attention\n              # Reset-Labels\n              - if:\n                  - commentContains:\n                      pattern: '\\[[Pp]olicy\\]\\s+[rR]eset\\s+[lL]abels'\n                      isRegex: True\n                then:\n                  - removeLabel:\n                      label: Area-Accessibility\n                  - removeLabel:\n                      label: Area-Architecture\n                  - removeLabel:\n                      label: Area-Build\n                  - removeLabel:\n                      label: Area-COM-API\n                  - removeLabel:\n                      label: Area-External\n                  - removeLabel:\n                      label: Area-GPO\n                  - removeLabel:\n                      label: Area-Input\n                  - removeLabel:\n                      label: Area-Localization\n                  - removeLabel:\n                      label: Area-Manifest\n                  - removeLabel:\n                      label: Area-Matching\n                  - removeLabel:\n                      label: Area-Output\n                  - removeLabel:\n                      label: Area-Path\n                  - removeLabel:\n                      label: Area-Performance\n                  - removeLabel:\n                      label: Area-Scope\n                  - removeLabel:\n                      label: Area-Settings\n                  - removeLabel:\n                      label: Area-Sorting\n                  - removeLabel:\n                      label: Area-User-Interface\n                  - removeLabel:\n                      label: Blocking-Issue\n                  - removeLabel:\n                      label: Breaking-Change\n                  - removeLabel:\n                      label: Command-Configure\n                  - removeLabel:\n                      label: Command-Download\n                  - removeLabel:\n                      label: Command-Export\n                  - removeLabel:\n                      label: Command-Import\n                  - removeLabel:\n                      label: Command-Install\n                  - removeLabel:\n                      label: Command-List\n                  - removeLabel:\n                      label: Command-Pin\n                  - removeLabel:\n                      label: Command-Search\n                  - removeLabel:\n                      label: Command-Show\n                  - removeLabel:\n                      label: Command-Source\n                  - removeLabel:\n                      label: Command-Uninstall\n                  - removeLabel:\n                      label: Command-Upgrade\n                  - removeLabel:\n                      label: Command-Validate\n                  - removeLabel:\n                      label: Context-Elevated-User\n                  - removeLabel:\n                      label: Context-User\n                  - removeLabel:\n                      label: Context-System\n                  - removeLabel:\n                      label: Dependencies\n                  - removeLabel:\n                      label: DSC-Resource\n                  - removeLabel:\n                      label: Experimental\n                  - removeLabel:\n                      label: Hardware\n                  - removeLabel:\n                      label: In-PR\n                  - removeLabel:\n                      label: Interactive-Only-Installer\n                  - removeLabel:\n                      label: Issue-Bug\n                  - removeLabel:\n                      label: Issue-Docs\n                  - removeLabel:\n                      label: Issue-Feature\n                  - removeLabel:\n                      label: msstore\n                  - removeLabel:\n                      label: Needs-Attention\n                  - removeLabel:\n                      label: Needs-Author-Feedback\n                  - removeLabel:\n                      label: Portable\n                  - removeLabel:\n                      label: PowerShell\n                  - removeLabel:\n                      label: Public-Service-Announcement\n                  - removeLabel:\n                      label: Side-By-Side\n                  - removeLabel:\n                      label: Windows-Sandbox\n                  - removeLabel:\n                      label: Zipped-Binary\nonFailure:\nonSuccess:\n"
  },
  {
    "path": ".github/policies/scheduledSearch.closeNoRecentActivity.yml",
    "content": "id: scheduledSearch.closeNoRecentActivity\nname: GitOps.PullRequestIssueManagement\ndescription: Closes issues that are inactive\nowner:\nresource: repository\ndisabled: false\nwhere:\nconfiguration:\n  resourceManagementConfiguration:\n    scheduledSearches:\n      - description: >-\n          Search for PR where -\n          * Pull Request is Open\n          * Pull request has the label No-Recent-Activity\n          * Pull request has the label Needs-Author-Feedback\n          * Pull request does not have the label Blocking-Issue\n          * Has not had activity in the last 7 days\n\n          Then -\n          * Close the PR\n        frequencies:\n          - hourly:\n              hour: 6\n        filters:\n          - isPullRequest\n          - isOpen\n          - hasLabel:\n              label: No-Recent-Activity\n          - hasLabel:\n              label: Needs-Author-Feedback\n          - isNotLabeledWith:\n              label: Blocking-Issue\n          - noActivitySince:\n              days: 7\n        actions:\n          - closeIssue\n      - description: >-\n          Search for Issues where -\n          * Issue is Open\n          * Issue has the label No-Recent-Activity\n          * Issue has the label Needs-Author-Feedback\n          * Issue does not have the label Blocking-Issue\n          * Issue does not have the label Issue-Feature\n          * Has not had activity in the last 7 days\n\n          Then -\n          * Close the Issue\n        frequencies:\n          - hourly:\n              hour: 6\n        filters:\n          - isIssue\n          - isOpen\n          - hasLabel:\n              label: No-Recent-Activity\n          - hasLabel:\n              label: Needs-Author-Feedback\n          - isNotLabeledWith:\n              label: Blocking-Issue\n          - isNotLabeledWith:\n              label: Issue-Feature\n          - noActivitySince:\n              days: 7\n        actions:\n          - closeIssue\nonFailure:\nonSuccess:\n"
  },
  {
    "path": ".github/policies/scheduledSearch.markNoRecentActivity.yml",
    "content": "id: scheduledSearch.closeNoRecentActivity\nname: GitOps.PullRequestIssueManagement\ndescription: Markss issues that are inactive\nowner:\nresource: repository\ndisabled: false\nwhere:\nconfiguration:\n  resourceManagementConfiguration:\n    scheduledSearches:\n      - description: >-\n          Search for PR where -\n          * Pull Request is Open\n          * Pull request does not have the label No-Recent-Activity\n          * Pull request does not have the label Blocking-Issue\n          * Pull request has the label Needs-Author-Feedback\n          * Has not had activity in the last 7 days\n\n          Then -\n          * Add No-Recent-Activity label\n        frequencies:\n          - hourly:\n              hour: 6\n        filters:\n          - isPullRequest\n          - isOpen\n          - isNotLabeledWith:\n              label: No-Recent-Activity\n          - isNotLabeledWith:\n              label: Blocking-Issue\n          - hasLabel:\n              label: Needs-Author-Feedback\n          - noActivitySince:\n              days: 7\n        actions:\n          - addLabel:\n              label: No-Recent-Activity\n      - description: >-\n          Search for Issues where -\n          * Issue is Open\n          * Issue has the label Needs-Author-Feedback\n          * Issue does not have the label No-Recent-Activity\n          * Issue does not have the label Blocking-Issue\n          * Issue does not have the label Issue-Feature\n          * Has not had activity in the last 7 days\n\n          Then -\n          * Close the Issue\n        frequencies:\n          - hourly:\n              hour: 6\n        filters:\n          - isIssue\n          - isOpen\n          - hasLabel:\n              label: Needs-Author-Feedback\n          - isNotLabeledWith:\n              label: No-Recent-Activity\n          - isNotLabeledWith:\n              label: Blocking-Issue\n          - isNotLabeledWith:\n              label: Issue-Feature\n          - noActivitySince:\n              days: 7\n        actions:\n          - addLabel:\n              label: No-Recent-Activity\nonFailure:\nonSuccess:\n"
  },
  {
    "path": ".github/workflows/automatic-issue-deduplication.yml",
    "content": "name: Automatic New Issue Deduplication\non:\n  issues:\n    types: [opened, reopened]\npermissions:\n  models: read\n  issues: write\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.event.issue.number }}\n  cancel-in-progress: true\njobs:\n  deduplicate:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Run Deduplicate Action\n        uses: pelikhan/action-genai-issue-dedup@v0\n        with:\n          github_token: ${{ secrets.GITHUB_TOKEN }}\n          label_as_duplicate: false\n"
  },
  {
    "path": ".github/workflows/spelling.yml",
    "content": "# spelling.yml is disabled per https://github.com/check-spelling/check-spelling/security/advisories/GHSA-g86g-chm8-7r2p\r\nname: Workflow should not run!\r\non:\r\n  push:\r\n    branches: ''\r\n\r\njobs:\r\n  placeholder:\r\n    name: Should be disabled\r\n    runs-on: ubuntu-latest\r\n    if: false\r\n    steps:\r\n      - name: Task\r\n        run: |\r\n          echo 'Running this task would be bad'\r\n          exit 1\r\n"
  },
  {
    "path": ".github/workflows/spelling2.yml",
    "content": "# spelling.yml is disabled per https://github.com/check-spelling/check-spelling/security/advisories/GHSA-p8r9-69g4-jwqq\r\nname: Workflow should not run!\r\non:\r\n  push:\r\n    branches: ''\r\n\r\njobs:\r\n  placeholder:\r\n    name: Should be disabled\r\n    runs-on: ubuntu-latest\r\n    if: false\r\n    steps:\r\n      - name: Task\r\n        run: |\r\n          echo 'Running this task would be bad'\r\n          exit 1\r\n"
  },
  {
    "path": ".github/workflows/spelling3.yml",
    "content": "# spelling.yml is blocked per https://github.com/check-spelling/check-spelling/security/advisories/GHSA-g86g-chm8-7r2p\n# spelling2.yml is blocked per https://github.com/check-spelling/check-spelling/security/advisories/GHSA-p8r9-69g4-jwqq\n\nname: Check Spelling\n\n# Comment management is handled through a secondary job, for details see:\n# https://github.com/check-spelling/check-spelling/wiki/Feature%3A-Restricted-Permissions\n#\n# `jobs.comment-push` runs when a push is made to a repository and the `jobs.spelling` job needs to make a comment\n#   (in odd cases, it might actually run just to collapse a comment, but that's fairly rare)\n#   it needs `contents: write` in order to add a comment.\n#\n# `jobs.comment-pr` runs when a pull_request is made to a repository and the `jobs.spelling` job needs to make a comment\n#   or collapse a comment (in the case where it had previously made a comment and now no longer needs to show a comment)\n#   it needs `pull-requests: write` in order to manipulate those comments.\n\n# Updating pull request branches is managed via comment handling.\n# For details, see: https://github.com/check-spelling/check-spelling/wiki/Feature:-Update-expect-list\n#\n# These elements work together to make it happen:\n#\n# `on.issue_comment`\n#   This event listens to comments by users asking to update the metadata.\n#\n# `jobs.update`\n#   This job runs in response to an issue_comment and will push a new commit\n#   to update the spelling metadata.\n#\n# `with.experimental_apply_changes_via_bot`\n#   Tells the action to support and generate messages that enable it\n#   to make a commit to update the spelling metadata.\n#\n# `with.ssh_key`\n#   In order to trigger workflows when the commit is made, you can provide a\n#   secret (typically, a write-enabled github deploy key).\n#\n#   For background, see: https://github.com/check-spelling/check-spelling/wiki/Feature:-Update-with-deploy-key\n\n# SARIF reporting\n#\n# Access to SARIF reports is generally restricted (by GitHub) to members of the repository.\n#\n# Requires enabling `security-events: write`\n# and configuring the action with `use_sarif: 1`\n#\n#   For information on the feature, see: https://github.com/check-spelling/check-spelling/wiki/Feature:-SARIF-output\n\n# Minimal workflow structure:\n#\n# on:\n#   push:\n#     ...\n#   pull_request_target:\n#     ...\n# jobs:\n#   # you only want the spelling job, all others should be omitted\n#   spelling:\n#     # remove `security-events: write` and `use_sarif: 1`\n#     # remove `experimental_apply_changes_via_bot: 1`\n#     ... otherwise adjust the `with:` as you wish\n\non:\n  push:\n    branches:\n      - \"**\"\n    tags-ignore:\n      - \"**\"\n  pull_request_target:\n    branches:\n      - \"**\"\n    types:\n      - \"opened\"\n      - \"reopened\"\n      - \"synchronize\"\n\njobs:\n  spelling:\n    name: Check Spelling\n    permissions:\n      contents: read\n      pull-requests: read\n      actions: read\n    outputs:\n      followup: ${{ steps.spelling.outputs.followup }}\n    runs-on: ubuntu-latest\n    if: ${{ contains(github.event_name, 'pull_request') || github.event_name == 'push' }}\n    concurrency:\n      group: spelling-${{ github.event.pull_request.number || github.ref }}\n      # note: If you use only_check_changed_files, you do not want cancel-in-progress\n      cancel-in-progress: true\n    steps:\n      - name: check-spelling\n        id: spelling\n        uses: check-spelling/check-spelling@v0.0.24\n        with:\n          suppress_push_for_open_pull_request: ${{ github.actor != 'dependabot[bot]' && 1 }}\n          checkout: true\n          check_file_names: 1\n          post_comment: 0\n          use_magic_file: 1\n          warnings: bad-regex,binary-file,deprecated-feature,ignored-expect-variant,large-file,limited-references,no-newline-at-eof,noisy-file,non-alpha-in-dictionary,token-is-substring,unexpected-line-ending,whitespace-in-dictionary,minified-file,unsupported-configuration,no-files-to-check,unclosed-block-ignore-begin,unclosed-block-ignore-end\n          check_extra_dictionaries: \"\"\n          dictionary_source_prefixes: >\n            {\n            \"cspell\": \"https://raw.githubusercontent.com/check-spelling/cspell-dicts/v20241114/dictionaries/\"\n            }\n          extra_dictionaries: |\n            cspell:software-terms/softwareTerms.txt\n            cspell:cpp/stdlib-cpp.txt\n            cspell:filetypes/filetypes.txt\n            cspell:cpp/stdlib-c.txt\n            cspell:php/php.txt\n            cspell:python/python/python-lib.txt\n            cspell:dotnet/dotnet.txt\n            cspell:golang/go.txt\n            cspell:cpp/compiler-msvc.txt\n            cspell:dart/dart.txt\n            cspell:html/html.txt\n            cspell:powershell/powershell.txt\n            cspell:aws/aws.txt\n            cspell:python/common/extra.txt\n            cspell:node/node.txt\n            cspell:npm/npm.txt\n            cspell:fullstack/fullstack.txt\n            cspell:java/java.txt\n            cspell:csharp/csharp.txt\n            cspell:cpp/ecosystem.txt\n            cspell:typescript/typescript.txt\n            cspell:cpp/lang-keywords.txt\n\n  comment-pr:\n    name: Report (PR)\n    # If you workflow isn't running on pull_request*, you can remove this job\n    runs-on: ubuntu-latest\n    needs: spelling\n    permissions:\n      actions: read\n      contents: read\n      pull-requests: write\n    if: (success() || failure()) && needs.spelling.outputs.followup && contains(github.event_name, 'pull_request')\n    steps:\n      - name: comment\n        uses: check-spelling/check-spelling@v0.0.24\n        with:\n          checkout: true\n          task: ${{ needs.spelling.outputs.followup }}\n"
  },
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n##\n## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore\n\n# User-specific files\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\nsettings.json\n\n# User-specific files (MonoDevelop/Xamarin Studio)\n*.userprefs\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]elease[Ss]tatic/\n[Rr]eleases/\nx64/\nx86/\narm64/\nAnyCPU/\nFuzzing/\nbld/\n[Bb]in/\n[Oo]bj/\n[Ll]og/\n\n# Visual Studio 2015/2017 cache/options directory\n.vs/\n# Uncomment if you have tasks that create the project's static files in wwwroot\n#wwwroot/\n\n# Visual Studio 2017 auto generated files\nGenerated\\ Files/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n# NUNIT\n*.VisualState.xml\nTestResult.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n# Benchmark Results\nBenchmarkDotNet.Artifacts/\n\n# .NET Core\nproject.lock.json\nproject.fragment.lock.json\nartifacts/\n**/Properties/launchSettings.json\n\n# StyleCop\nStyleCopReport.xml\n\n# Files built by Visual Studio\n*_i.c\n*_p.c\n*_i.h\n*.ilk\n*.meta\n*.obj\n*.iobj\n*.pch\n*.pdb\n*.ipdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opendb\n*.opensdf\n*.sdf\n*.cachefile\n*.VC.db\n*.VC.VC.opendb\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n*.sap\n\n# Visual Studio Trace Files\n*.e2e\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# JustCode is a .NET coding add-in\n.JustCode\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# AxoCover is a Code Coverage Tool\n.axoCover/*\n!.axoCover/settings.json\n\n# Visual Studio code coverage results\n*.coverage\n*.coveragexml\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\nnCrunchTemp_*\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n# Note: Comment the next line if you want to check in your web deploy settings,\n# but database connection strings (with potential passwords) will be unencrypted\n*.pubxml\n*.publishproj\n\n# Microsoft Azure Web App publish settings. Comment the next line if you want to\n# check in your Azure Web App publish settings, but sensitive information contained\n# in these scripts will be unencrypted\nPublishScripts/\n\n# NuGet Packages\n*.nupkg\n# The packages folder can be ignored because of Package Restore\n**/[Pp]ackages/*\n# except build/, which is used as an MSBuild target.\n!**/[Pp]ackages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/[Pp]ackages/repositories.config\n# NuGet v3's project.json files produces more ignorable files\n*.nuget.props\n*.nuget.targets\n\n# Vcpkg install directory\n**/vcpkg_installed/*\n\n# Microsoft Azure Build Output\ncsx/\n*.build.csdef\n\n# Microsoft Azure Emulator\necf/\nrcf/\n\n# Windows Store app package directories and files\nAppPackages/\nBundleArtifacts/\nPackage.StoreAssociation.xml\n_pkginfo.txt\n*.appx\n\n# Visual Studio cache files\n# files ending in .cache can be ignored\n*.[Cc]ache\n# but keep track of directories ending in .cache\n!*.[Cc]ache/\n\n# Others\nClientBin/\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.jfm\n*.pfx\n*.publishsettings\norleans.codegen.cs\n\n# Including strong name files can present a security risk \n# (https://github.com/github/gitignore/pull/2483#issue-259490424)\n#*.snk\n\n# Since there are multiple workflows, uncomment next line to ignore bower_components\n# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)\n#bower_components/\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\nServiceFabricBackup/\n*.rptproj.bak\n\n# SQL Server files\n*.mdf\n*.ldf\n*.ndf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n*.rptproj.rsuser\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# GhostDoc plugin setting file\n*.GhostDoc.xml\n\n# Node.js Tools for Visual Studio\n.ntvs_analysis.dat\nnode_modules/\n\n# Visual Studio 6 build log\n*.plg\n\n# Visual Studio 6 workspace options file\n*.opt\n\n# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)\n*.vbw\n\n# Visual Studio LightSwitch build output\n**/*.HTMLClient/GeneratedArtifacts\n**/*.DesktopClient/GeneratedArtifacts\n**/*.DesktopClient/ModelManifest.xml\n**/*.Server/GeneratedArtifacts\n**/*.Server/ModelManifest.xml\n_Pvt_Extensions\n\n# Paket dependency manager\n.paket/paket.exe\npaket-files/\n\n# FAKE - F# Make\n.fake/\n\n# JetBrains Rider\n.idea/\n*.sln.iml\n\n# CodeRush\n.cr/\n\n# Python Tools for Visual Studio (PTVS)\n__pycache__/\n*.pyc\n\n# Cake - Uncomment if you are using it\n# tools/**\n# !tools/packages.config\n\n# Tabs Studio\n*.tss\n\n# Telerik's JustMock configuration file\n*.jmconfig\n\n# BizTalk build output\n*.btp.cs\n*.btm.cs\n*.odx.cs\n*.xsd.cs\n\n# OpenCover UI analysis results\nOpenCover/\n\n# Azure Stream Analytics local run output \nASALocalRun/\n\n# MSBuild Binary and Structured Log\n*.binlog\n\n# NVidia Nsight GPU debugger configuration file\n*.nvuser\n\n# MFractors (Xamarin productivity tool) working folder \n.mfractor/\n\n# Generated files from WinGetServer.idl\n**/WinGetServer/WinGetServer.h\n**/WinGetServer/WinGetServer_c.c\n**/WinGetServer/WinGetServer_s.c\n\n# Crescendo generated module files\nsrc/PowerShell/Microsoft.WinGet.Client/Crescendo/*.psd1\nsrc/PowerShell/Microsoft.WinGet.Client/Crescendo/*.psm1\n\n# Dev PowerShell module path\nsrc/PowerShell/scripts/Module\n\n# Interop nuget\nsrc/WinGetUtilInterop/scripts/Nuget*\n"
  },
  {
    "path": ".vsconfig",
    "content": "{\n  \"version\": \"1.0\",\n  \"components\": [\n    \"Microsoft.VisualStudio.Component.CoreEditor\",\n    \"Microsoft.VisualStudio.Workload.CoreEditor\",\n    \"Microsoft.Net.Component.4.8.SDK\",\n    \"Microsoft.Net.Component.4.7.2.TargetingPack\",\n    \"Microsoft.Net.ComponentGroup.DevelopmentPrerequisites\",\n    \"Microsoft.VisualStudio.Component.TypeScript.TSServer\",\n    \"Microsoft.VisualStudio.ComponentGroup.WebToolsExtensions\",\n    \"Microsoft.VisualStudio.Component.JavaScript.TypeScript\",\n    \"Microsoft.VisualStudio.Component.Roslyn.Compiler\",\n    \"Microsoft.Component.MSBuild\",\n    \"Microsoft.VisualStudio.Component.Roslyn.LanguageServices\",\n    \"Microsoft.VisualStudio.Component.TextTemplating\",\n    \"Microsoft.VisualStudio.Component.NuGet\",\n    \"Microsoft.VisualStudio.Component.SQL.CLR\",\n    \"Microsoft.Component.ClickOnce\",\n    \"Microsoft.VisualStudio.Component.ManagedDesktop.Core\",\n    \"Microsoft.NetCore.Component.Runtime.6.0\",\n    \"Microsoft.NetCore.Component.SDK\",\n    \"Microsoft.VisualStudio.Component.FSharp\",\n    \"Microsoft.ComponentGroup.ClickOnce.Publish\",\n    \"Microsoft.NetCore.Component.DevelopmentTools\",\n    \"Microsoft.VisualStudio.Component.AppInsights.Tools\",\n    \"Microsoft.Net.Component.4.8.TargetingPack\",\n    \"Microsoft.Net.ComponentGroup.4.8.DeveloperTools\",\n    \"Microsoft.VisualStudio.Component.DiagnosticTools\",\n    \"Microsoft.VisualStudio.Component.EntityFramework\",\n    \"Microsoft.VisualStudio.Component.Debugger.JustInTime\",\n    \"Component.Microsoft.VisualStudio.LiveShare.2022\",\n    \"Microsoft.VisualStudio.Component.IntelliCode\",\n    \"Microsoft.VisualStudio.Component.VC.CoreIde\",\n    \"Microsoft.VisualStudio.Component.VC.Tools.x86.x64\",\n    \"Microsoft.VisualStudio.Component.Graphics.Tools\",\n    \"Microsoft.VisualStudio.Component.VC.DiagnosticTools\",\n    \"Microsoft.VisualStudio.ComponentGroup.MSIX.Packaging\",\n    \"Microsoft.VisualStudio.Component.ManagedDesktop.Prerequisites\",\n    \"Microsoft.VisualStudio.Component.DotNetModelBuilder\",\n    \"Microsoft.ComponentGroup.Blend\",\n    \"Microsoft.VisualStudio.Workload.ManagedDesktop\",\n    \"Microsoft.VisualStudio.Component.VC.ATL\",\n    \"Microsoft.VisualStudio.Component.VC.Tools.ARM64\",\n    \"Microsoft.VisualStudio.Component.VC.Redist.14.Latest\",\n    \"Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Core\",\n    \"Microsoft.VisualStudio.ComponentGroup.WebToolsExtensions.CMake\",\n    \"Microsoft.VisualStudio.Component.VC.CMake.Project\",\n    \"Microsoft.VisualStudio.Component.VC.TestAdapterForBoostTest\",\n    \"Microsoft.VisualStudio.Component.VC.TestAdapterForGoogleTest\",\n    \"Microsoft.VisualStudio.Component.VC.ASAN\",\n    \"Microsoft.VisualStudio.Component.Vcpkg\",\n    \"Microsoft.VisualStudio.Component.Windows10SDK.19041\",\n    \"Microsoft.VisualStudio.Component.Windows11SDK.26100\",\n    \"Microsoft.VisualStudio.Workload.NativeDesktop\",\n    \"Microsoft.Component.NetFX.Native\",\n    \"Microsoft.VisualStudio.ComponentGroup.UWP.NetCoreAndStandard\",\n    \"Microsoft.VisualStudio.Component.Graphics\",\n    \"Microsoft.VisualStudio.ComponentGroup.UWP.Xamarin\",\n    \"Microsoft.VisualStudio.ComponentGroup.UWP.Support\",\n    \"Microsoft.VisualStudio.Workload.Universal\",\n    \"Microsoft.VisualStudio.Component.VC.Runtimes.ARM64.Spectre\",\n    \"Microsoft.VisualStudio.Component.VC.Runtimes.x86.x64.Spectre\",\n    \"Microsoft.NetCore.Component.Runtime.3.1\"\n  ]\n}"
  },
  {
    "path": "CODEOWNERS",
    "content": "* @microsoft/winget-developers\r\n\r\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Microsoft Open Source Code of Conduct\r\n\r\nThis project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).\r\n\r\nResources:\r\n\r\n- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)\r\n- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)\r\n- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns.\r\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Windows Package Manager Contributor's Guide\n\nBelow is our guidance for how to report issues, propose new features, and submit contributions via Pull Requests (PRs).\n\n## Open Development Workflow\n\nThe Windows Package Manager team is VERY active in this GitHub Repository. In fact, we live in it all day long and carry out all our development in the open!\n\nWhen the team finds issues we file them in the repository. When we propose new ideas or think up new features, we file new feature requests. When we work on fixes or features, we create branches and work on those improvements. And when PRs are reviewed, we review them in public - including all the good, the bad, and the ugly parts.\n\nThe point of doing all this work in public is to ensure that we are holding ourselves to a high degree of transparency, and so that the community sees that we apply the same processes and hold ourselves to the same quality bar as we do to community-submitted issues and PRs. We also want to make sure that we expose our team culture and \"tribal knowledge\" that is inherent in any closely-knit team, which often contains considerable value to those new to the project who are trying to figure out \"why the heck does this thing look/work like this???\"\n\n### Repository Bot\n\nThe team triages new issues several times a week. During triage, the team uses labels to categorize, manage, and drive the project workflow.\n\nWe employ a bot to help us automate common processes within our workflow.\n\nWe drive the bot by tagging issues with specific labels which cause the bot engine to close issues, merge branches, etc. This bot engine helps us keep the repository clean by automating the process of notifying appropriate parties if/when information/follow-up is needed, and closing stale issues/PRs after reminders have remained unanswered for several days.\n\nTherefore, if you do file issues, or create PRs, please keep an eye on your GitHub notifications. If you do not respond to requests for information, your issues/PRs may be closed automatically.\n\n---\n## Reporting Security Issues\n\n**Please do not report security vulnerabilities through public GitHub issues.** Instead, please report them to the Microsoft Security Response Center (MSRC). See [SECURITY.md](./SECURITY.md) for more information.\n\n## Before you start, file an issue\n\nPlease follow this simple rule to help us eliminate any unnecessary wasted effort & frustration, and ensure an efficient and effective use of everyone's time - yours, ours, and other community members':\n\n> 👉 If you have a question, think you've discovered an issue, would like to propose a new feature, etc., then find/file an issue **BEFORE** starting work to fix/implement it.\n\n### Search existing issues first\n\nBefore filing a new issue, search existing open and closed issues first: This project is moving fast! It is likely someone else has found the problem you're seeing, and someone may be working on or have already contributed a fix!\n\nIf no existing item describes your issue/feature, great - please file a new issue:\n\n### File a new Issue\n\n* Don't know whether you're reporting an issue or requesting a feature? File an issue\n* Have a question that you don't see answered in docs, videos, etc.? File an issue\n* Want to know if we're planning on building a particular feature? Create a discussion\n* Got a great idea for a new feature? File an issue/request/idea\n* Don't understand how to do something? Create a discussion\n* Found an existing issue that describes yours? Great - upvote and add additional commentary / info / repro-steps / etc.\n\nWhen you hit \"New Issue\", select the type of issue closest to what you want to report/ask/request:\n\n### Complete the template\n\n**Complete the information requested in the issue template, providing as much information as possible**. The more information you provide, the more likely your issue/ask will be understood and implemented. Helpful information includes:\n\n  👉 Tip: Run the following command\n\n  `winget --info`\n\n* What tools and apps you're using (e.g. VS 2019, VSCode, etc.)\n* Don't assume we're experts in setting up YOUR environment and don't assume we are experts in `<your distro/tool of choice>`. Teach us to help you!\n* **We LOVE detailed reproduction steps!** What steps do we need to take to reproduce the issue? Assume we love to read reproduction steps. As much detail as you can stand is probably _barely_ enough detail for us!\n* Prefer error message text where possible or screenshots of errors if text cannot be captured.\n* We MUCH prefer text command-line script than screenshots of command-line script.\n* **If you intend to implement the fix/feature yourself then say so!** If you do not indicate otherwise we will assume that the issue is our to solve, or may label the issue as `Help-Wanted`.\n\n### DO NOT post \"+1\" comments\n\n> ⚠ DO NOT post \"+1\", \"me too\", or similar comments - they just add noise to an issue.\n\nIf you don't have any additional info/context to add but would like to indicate that you're affected by the issue, upvote the original issue by clicking its [+😊] button and hitting 👍 (+1) icon. This way we can actually measure how impactful an issue is.\n\n---\n\n## Contributing fixes / features\n\nFor those able & willing to help fix issues and/or implement features ...\n\n### To Spec or not to Spec\n\nSome issues/features may be quick and simple to describe and understand. For such scenarios, once a team member has agreed with your approach, skip ahead to the section headed \"Fork, Branch, and Create your PR\", below.\n\nSmall issues that do not require a spec will be labeled Issue-Bug or Issue-Task.\n\nHowever, some issues/features will require careful thought & formal design before implementation. For these scenarios, we'll request that a spec is written and the associated issue will be labeled Issue-Feature.\n\nSpecs help collaborators discuss different approaches to solving a problem, describe how the feature will behave, how the feature will impact the user, what happens if something goes wrong, etc. Driving towards agreement in a spec, before any code is written, often results in simpler code, and less wasted effort in the long run.\n\nSpecs will be managed in a very similar manner as code contributions so please follow the \"Fork, Branch, and Create your PR\" below.\n\n### Writing / Contributing-to a Spec\n\nTo write/contribute to a spec: fork, branch, and commit via PRs, as you would with any code changes.\n\nSpecs are written in markdown, stored under the `/doc/specs` folder, and named `[issue id] - [spec description].md`.\n\n👉 **It is important to follow the spec templates and complete the requested information**. The available spec templates will help ensure that specs contain the minimum information & decisions necessary to permit development to begin. In particular, specs require you to confirm that you've already discussed the issue/idea with the team in an issue and that you provide the issue ID for reference.\n\nTeam members will be happy to help review specs and guide them to completion.\n\n### Help Wanted\n\nOnce the team has approved an issue/spec, development can proceed. If no developers are immediately available, the spec can be parked ready for a developer to get started. Parked specs' issues will be labeled \"Help Wanted\". To find a list of development opportunities waiting for developer involvement, visit the Issues and filter on [the Help-Wanted label](https://github.com/microsoft/winget-cli/labels/Help%20Wanted).\n\n---\n\n## Development\n\n### Fork, Clone, Branch and Create your PR\n\nOnce you've discussed your proposed feature/fix/etc. with a team member, and you've agreed an approach or a spec has been written and approved, it's time to start development:\n\n1. Fork the repository if you haven't already.\n1. Clone your fork locally.\n1. Create & push a feature branch.\n1. Create a [Draft Pull Request (PR)](https://github.blog/2019-02-14-introducing-draft-pull-requests/).\n1. Work on your changes.\n1. Build and see if it works.\n\n### Testing\n\nTesting is a key component in the development workflow.\n\n### Code Review\n\nWhen you'd like the team to take a look, (even if the work is not yet fully-complete), mark the Draft PR as 'Ready For Review' so that the team can review your work and provide comments, suggestions, and request changes. It may take several cycles, but the result will be solid, testable, conformant code that is safe for us to merge.\n\n> ⚠ Remember: **changes you make may affect both the Windows Package Manager and the schema support implemented in our validation pipelines!** Because of this, we will treat community PRs with the same level of scrutiny and rigor as commits submitted to the official Windows source by team members and partners.\n\n### Merge\n\nOnce your code has been reviewed and approved by the requisite number of team members, it will be merged into the main branch. Once merged, your PR will be automatically closed.\n\n---\n\n## Thank you\n\nThank you in advance for your contribution! Now, [what's next on the list](https://github.com/microsoft/winget-cli/labels/Help%20Wanted)? 😜\n"
  },
  {
    "path": "LICENSE",
    "content": "    MIT License\r\n\r\n    Copyright (c) Microsoft Corporation. All rights reserved.\r\n\r\n    Permission is hereby granted, free of charge, to any person obtaining a copy\r\n    of this software and associated documentation files (the \"Software\"), to deal\r\n    in the Software without restriction, including without limitation the rights\r\n    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n    copies of the Software, and to permit persons to whom the Software is\r\n    furnished to do so, subject to the following conditions:\r\n\r\n    The above copyright notice and this permission notice shall be included in all\r\n    copies or substantial portions of the Software.\r\n\r\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n    SOFTWARE\r\n"
  },
  {
    "path": "Localization/Policies/de-DE/DesktopAppInstaller.adml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (c) Microsoft Corporation.\n     Licensed under the MIT License. -->\n<policyDefinitionResources xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" revision=\"1.0\" schemaVersion=\"1.0\" xmlns=\"http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions\">\n  <displayName>App-Installer</displayName>\n  <description>App-Installer</description>\n  <resources>\n    <stringTable>\n      <string id=\"AppInstaller\">Desktop-App-Installer</string>\n      <string id=\"EnableAppInstaller\">Windows-Paket-Manager aktivieren</string>\n      <string id=\"EnableAppInstallerExplanation\">Mit dieser Richt Linie wird gesteuert, ob der Windows-Paket-Manager von Benutzern verwendet werden kann.\n\nWenn Sie diese Einstellung aktivieren oder nicht konfigurieren, können Benutzer die Windows-Paket-Manager verwenden.\n\nWenn Sie diese Einstellung deaktivieren, können Benutzer den Windows-Paket-Manager nicht verwenden.</string>\n      <string id=\"EnableSettings\">Einstellungen des Windows-Paket-Manager aktivieren</string>\n      <string id=\"EnableSettingsExplanation\">Mit dieser Richt Linie wird gesteuert, ob Benutzer Ihre Einstellungen ändern können.\n\nWenn Sie diese Einstellung aktivieren oder nicht konfigurieren, können Benutzer Einstellungen für die Windows-Paket-Manager ändern.\n\nWenn Sie diese Einstellung deaktivieren, können Benutzer Einstellungen für die Windows-Paket-Manager nicht ändern.</string>\n      <string id=\"EnableExperimentalFeatures\">Windows-Paket-Manager experimentelle Features aktivieren</string>\n      <string id=\"EnableExperimentalFeaturesExplanation\">Mit dieser Richt Linie wird gesteuert, ob Benutzer Experiment elle Funktionen in der Windows-Paket-Manager aktivieren können.\n\nWenn Sie diese Einstellung aktivieren oder nicht konfigurieren, können Benutzer Experiment elle Features für die Windows-Paket-Manager aktivieren.\n\nWenn Sie diese Einstellung deaktivieren, können Benutzer Experiment elle Features für die Windows-Paket-Manager nicht aktivieren.</string>\n      <string id=\"EnableLocalManifestFiles\">Lokale Manifestdateien Windows-Paket-Manager aktivieren</string>\n      <string id=\"EnableLocalManifestFilesExplanation\">Mit dieser Richt Linie wird gesteuert, ob Benutzer Pakete mit lokalen Manifestdateien installieren können.\n\nWenn Sie diese Einstellung aktivieren oder nicht konfigurieren, können Benutzer Pakete mit lokalen Manifeste mithilfe des Windows-Paket-Manager installieren.\n\nWenn Sie diese Einstellung deaktivieren, können Benutzer keine Pakete mit lokalen Manifeste unter Verwendung des Windows-Paket-Manager installieren.</string>\n      <string id=\"EnableBypassCertificatePinningForMicrosoftStore\">Umgehung der Quellzertifikatsüberprüfung des Windows-Paket-Managers im Microsoft Store</string>\n      <string id=\"EnableBypassCertificatePinningForMicrosoftStoreExplanation\">Diese Richtlinie steuert, ob der Windows-Paket-Manager beim Initiieren einer Verbindung mit der Microsoft Speicherquelle überprüft, ob der Microsoft Speicherzertifikathash mit einem bekannten Microsoft Speicherzertifikat übereinstimmt. \nWenn Sie diese Richtlinie aktivieren, umgehen die Windows-Paket-Manager die Überprüfung des Microsoft Speicherzertifikats. \n\nWenn Sie diese Richtlinie deaktivieren, überprüft der Windows-Paket-Manager, ob das verwendete Microsoft Speicherzertifikat gültig ist und zum Microsoft Speicher gehört, bevor mit der Microsoft Store-Quelle kommuniziert wird.\n\nWenn Sie diese Richtlinie nicht konfigurieren, werden die Windows-Paket-Manager Administratoreinstellungen eingehalten.</string>\n      <string id=\"EnableHashOverride\">Außerkraftsetzung von Windows-Paket-Manager-Hash aktivieren</string>\n      <string id=\"EnableHashOverrideExplanation\">Diese Richtlinie steuert, ob der Windows-Paket-Manager so konfiguriert werden kann, dass die Fähigkeit „SHA256-Sicherheitsvalidierung überschreiben“ in den Einstellungen aktiviert werden kann.\n\nWenn Sie diese Richtlinie aktivieren oder nicht konfigurieren, können Benutzer die Fähigkeit „SHA256-Sicherheitsvalidierung überschreiben“ in den Windows-Paket-Manager-Einstellungen aktivieren.\n\nWenn Sie diese Richtlinie deaktivieren, können Benutzer die Fähigkeit „SHA256-Sicherheitsvalidierung überschreiben“ in den Windows-Paket-Manager-Einstellungen nicht aktivieren.</string>\n      <string id=\"EnableLocalArchiveMalwareScanOverride\">Außerkraftsetzung des Malware-Scans für lokale Archive im Windows-Paket-Manager aktivieren</string>\n      <string id=\"EnableLocalArchiveMalwareScanOverrideExplanation\">Diese Richtlinie steuert die Möglichkeit, Überprüfungen auf Sicherheitsrisiken durch Schadsoftware außer Kraft zu setzen, wenn eine Archivdatei mithilfe eines lokalen Manifests mithilfe der Befehlszeilenargumente installiert wird.\nWenn Sie diese Richtlinie aktivieren, können Benutzer die Überprüfung auf Schadsoftware außer Kraft setzen, wenn sie eine lokale Manifestinstallation einer Archivdatei ausführen.\n\nWenn Sie diese Richtlinie deaktivieren, können Benutzer die Schadsoftwareüberprüfung einer Archivdatei bei der Installation mithilfe eines lokalen Manifests nicht außer Kraft setzen.\n\nWenn Sie diese Richtlinie nicht konfigurieren, werden die Windows-Paket-Manager Administratoreinstellungen eingehalten.</string>\n      <string id=\"EnableDefaultSource\">Windows-Paket-Manager-Standardquelle aktivieren</string>\n      <string id=\"EnableDefaultSourceExplanation\">Diese Richtlinie steuert die Standardquelle, die im Windows-Paket-Manager enthalten ist.\n\nWenn Sie diese Einstellung nicht konfigurieren, ist die Standardquelle für den Windows-Paket-Manager verfügbar und kann entfernt werden.\n\nWenn Sie diese Einstellung aktivieren, ist die Standardquelle für den Windows-Paket-Manager verfügbar und kann nicht entfernt werden.\n\nWenn Sie diese Einstellung deaktivieren, ist die Standardquelle für den Windows-Paket-Manager nicht verfügbar.</string>\n      <string id=\"EnableMicrosoftStoreSource\">Microsoft Store-Quelle des Windows-Paket-Managers aktivieren</string>\n      <string id=\"EnableMicrosoftStoreSourceExplanation\">Diese Richtlinie steuert die Microsoft Store-Quelle, die im Windows-Paket-Manager enthalten ist.\n\nWenn Sie diese Einstellung nicht konfigurieren, ist die Microsoft Store-Quelle für den Windows-Paket-Manager verfügbar und kann entfernt werden.\n\nWenn Sie diese Einstellung aktivieren, ist die Microsoft Store-Quelle für den Windows-Paket-Manager verfügbar und kann nicht entfernt werden.\n\nWenn Sie diese Einstellung deaktivieren, ist die Microsoft Store-Quelle für den Windows-Paket-Manager nicht verfügbar.</string>\n      <string id=\"EnableFontSource\">Windows-Paket-Manager-Schriftartquelle aktivieren</string>\n      <string id=\"EnableFontSourceExplanation\">\n        Diese Richtlinie steuert die im Windows-Paket-Manager enthaltene Schriftartquelle.\n\n        Wenn Sie diese Einstellung nicht konfigurieren, ist die Schriftartquelle für den Windows-Paket-Manager verfügbar und kann entfernt werden.\n\n        Wenn Sie diese Einstellung aktivieren, ist die Schriftartquelle für den Windows-Paket-Manager verfügbar und kann nicht entfernt werden.\n\n        Wenn Sie diese Einstellung deaktivieren, ist die Schriftartquelle für den Windows-Paket-Manager nicht verfügbar.\n      </string>\n      <string id=\"SourceAutoUpdateInterval\">Intervall für das automatische Aktualisieren der Windows-Paket-Manager-Quelle in Minuten festlegen</string>\n      <string id=\"SourceAutoUpdateIntervalExplanation\">Diese Richtlinie steuert das Intervall für die automatische Aktualisierung paketbasierter Quellen. Die Standardquelle für Windows-Paket-Manager ist so konfiguriert, dass ein Index der Pakete auf dem lokalen Computer zwischengespeichert wird. Der Index wird heruntergeladen, wenn ein Benutzer einen Befehl aufruft und das Intervall abgelaufen ist.\n\nWenn Sie diese Einstellung deaktivieren oder nicht konfigurieren, wird das Standardintervall oder der in den Windows-Paket-Manager Einstellungen angegebene Wert verwendet.\n\nWenn Sie diese Einstellung aktivieren, wird die angegebene Anzahl von Minuten vom Windows-Paket-Manager verwendet.</string>\n      <string id=\"EnableAdditionalSources\">Windows-Paket-Manager zusätzliche Quellen aktivieren</string>\n      <string id=\"EnableAdditionalSourcesExplanation\">Diese Richtlinie steuert zusätzliche Quellen, die vom IT-Administrator des Unternehmens bereitgestellt werden.\n\nWenn Sie diese Richtlinie nicht konfigurieren, werden keine zusätzlichen Quellen für den Windows-Paket-Manager konfiguriert.\n\nWenn Sie diese Richtlinie aktivieren, werden die zusätzlichen Quellen dem Windows-Paket-Manager hinzugefügt und können nicht entfernt werden. Die Repräsentation für jede zusätzliche Quelle kann aus den installierten Quellen mit „winget source export“ bezogen werden.\n\nWenn Sie diese Richtlinie deaktivieren, können keine zusätzlichen Quellen für den Windows-Paket-Manager konfiguriert werden.</string>\n      <string id=\"EnableAllowedSources\">Windows-Paket-Manager zulässige Quellen aktivieren</string>\n      <string id=\"EnableAllowedSourcesExplanation\">Diese Richtlinie steuert zusätzliche Quellen, die vom IT-Administrator des Unternehmens zugelassen werden.\n\nWenn Sie diese Richtlinie nicht konfigurieren, können Benutzer zusätzliche Quellen neben den in der Richtlinie konfigurierten hinzufügen oder entfernen.\n\nWenn Sie diese Richtlinie aktivieren, können nur die angegebenen Quellen dem Windows-Paket-Manager hinzugefügt oder von ihm entfernt werden. Die Repräsentation für jede erlaubte Quelle kann aus den installierten Quellen mit „winget source export“ bezogen werden.\n\nWenn Sie diese Richtlinie deaktivieren, können keine zusätzlichen Quellen für den Windows-Paket-Manager konfiguriert werden.</string>\n      <string id=\"EnableMSAppInstallerProtocol\">Aktivieren des ms-appinstaller-Protokolls für den App-Installer</string>\n      <string id=\"EnableMSAppInstallerProtocolExplanation\">Diese Richtlinie steuert, ob Benutzer Pakete von einer Website installieren können, die das ms-appinstaller-Protokoll verwendet.\n\nWenn Sie diese Einstellung aktivieren, können Benutzer Pakete von Websites installieren, die dieses Protokoll verwenden.\n\nWenn Sie diese Einstellung deaktivieren oder nicht konfigurieren, können Benutzer keine Pakete von Websites installieren, die dieses Protokoll verwenden.</string>\n      <string id=\"EnableWindowsPackageManagerCommandLineInterfaces\">Aktivieren der Windows-Paketmanager-Befehlszeilenschnittstellen</string>\n      <string id=\"EnableWindowsPackageManagerCommandLineInterfacesExplanation\">Diese Richtlinie legt fest, ob ein Benutzer eine Aktion mit dem Windows-Paketmanager über eine Befehlszeilenschnittstelle (WinGet CLI oder WinGet PowerShell) durchführen kann.\n\n        Wenn Sie diese Richtlinie deaktivieren, können Benutzer die Windows-Paketverwaltungs-CLI und PowerShell-Cmdlets nicht ausführen.\n\n        Wenn Sie diese Richtlinie aktivieren oder nicht konfigurieren, können Benutzer die CLI-Befehle des Windows-Paket-Managers und PowerShell-Cmdlets ausführen. (Vorausgesetzt, die Richtlinie „App Installer aktivieren“ ist nicht deaktiviert.)\n\n        Diese Richtlinie setzt die Richtlinie „App-Installer aktivieren“ nicht außer Kraft.</string>\n      <string id=\"EnableWindowsPackageManagerConfiguration\">Aktivieren der Windows-Paket-Manager-Konfiguration</string>\n      <string id=\"EnableWindowsPackageManagerConfigurationExplanation\">Diese Richtlinie steuert, ob das Windows-Paket-Manager Konfigurationsfeature von Benutzern verwendet werden kann.\n\nWenn Sie diese Einstellung aktivieren oder nicht konfigurieren, können Benutzer das Konfigurationsfeature Windows-Paket-Manager verwenden.\n\nWenn Sie diese Einstellung deaktivieren, können Benutzer das Konfigurationsfeature Windows-Paket-Manager nicht verwenden.</string>\n      <string id=\"EnableWindowsPackageManagerProxyCommandLineOptions\">Befehlszeilenoptionen für Windows-Paket-Manager Proxy aktivieren</string>\n      <string id=\"EnableWindowsPackageManagerProxyCommandLineOptionsExplanation\">\n        Diese Richtlinie steuert, ob die Windows-Paket-Manager Verwendung des Proxys von Benutzern über die Befehlszeile konfiguriert werden kann.\n\nWenn Sie diese Einstellung aktivieren, können Benutzer die Verwendung des Proxys durch die Windows-Paket-Manager über die Befehlszeile konfigurieren.\n\nWenn Sie diese Einstellung deaktivieren oder nicht konfigurieren, können Benutzer die Verwendung des Proxys durch die Windows-Paket-Manager über die Befehlszeile nicht konfigurieren.</string>\n      <string id=\"EnableWindowsPackageManagerMcpServer\">MCP-Server für den Windows-Paket-Manager aktivieren</string>\n      <string id=\"EnableWindowsPackageManagerMcpServerExplanation\">\n        Diese Richtlinie steuert, ob der Model Context Protocol (MCP)-Server des Windows-Paket-Managers verwendet werden kann.\n\n        Wenn Sie diese Einstellung aktivieren oder nicht konfigurieren, können Benutzer den Windows-Paket-Manager verwenden.\n\n        Wenn Sie diese Einstellung deaktivieren, können Benutzer den Windows-Paket-Manager nicht verwenden.</string>\n      <string id=\"WindowsPackageManagerDefaultProxy\">Standardproxy für den Windows-Paket-Manager festlegen</string>\n      <string id=\"WindowsPackageManagerDefaultProxyExplanation\">Diese Richtlinie steuert den Standardproxy, der vom Windows-Paket-Manager verwendet wird.\n\nWenn Sie diese Einstellung deaktivieren oder nicht konfigurieren, wird standardmäßig kein Proxy verwendet.\n\nWenn Sie diese Einstellung aktivieren, wird der angegebene Proxy standardmäßig verwendet.</string>\n      <string id=\"EnableMsixAllowedZones\">App-Installer zugelassene Zonen für MSIX-Pakete aktivieren</string>\n      <string id=\"EnableMsixAllowedZonesExplanation\">Diese Richtlinie steuert, ob App-Installer die Installation von Paketen aus bestimmten URL-Zonen zulässt. Der Ursprung eines Pakets wird durch seinen URI bestimmt und ob ein Mart-of-the-Web (MotW) vorhanden ist. Wenn mehrere URIs beteiligt sind, werden alle berücksichtigt; z. B. bei Verwendung einer .appinstaller-Datei, die umleitungsbezieht.\n\nWenn Sie diese Richtlinie aktivieren, können Benutzer MSIX-Pakete gemäß der Konfiguration für jede Zone installieren.\n\nWenn Sie diese Richtlinie deaktivieren oder nicht konfigurieren, können Benutzer MSIX-Pakete aus einer beliebigen Zone installieren, mit Ausnahme von \"Nicht vertrauenswürdig\".</string>\n      <string id=\"ZoneAllowed\">Zulassen</string>\n      <string id=\"ZoneBlocked\">Blockieren</string>\n      <string id=\"EnableMsixSmartScreenCheck\">Microsoft SmartScreen-Überprüfungen für MSIX-Pakete aktivieren</string>\n      <string id=\"EnableMsixSmartScreenCheckExplanation\">Diese Richtlinie steuert, ob App-Installer bei der Installation von MSIX-Paketen Microsoft SmartScreen-Überprüfungen durchführt.\n\nWenn Sie diese Richtlinie aktivieren oder nicht konfigurieren, wird der Paket-URI vor der Installation mit Microsoft SmartScreen ausgewertet. Diese Überprüfung wird nur für Pakete durchgeführt, die aus dem Internet stammen.\n\nWenn Sie diese Option deaktivieren, wird Microsoft SmartScreen vor der Installation eines Pakets nicht abgefragt.</string>\n    </stringTable>\n    <presentationTable>\n      <presentation id=\"SourceAutoUpdateInterval\">\n        <decimalTextBox refId=\"SourceAutoUpdateInterval\" defaultValue=\"5\">Intervall für automatische Aktualisierung der Quelle in Minuten</decimalTextBox>\n      </presentation>\n      <presentation id=\"AdditionalSources\">\n        <listBox refId=\"AdditionalSources\" required=\"false\">Zusätzliche Quellen: </listBox>\n      </presentation>\n      <presentation id=\"AllowedSources\">\n        <listBox refId=\"AllowedSources\" required=\"false\">Erlaubte Quellen: </listBox>\n      </presentation>\n      <presentation id=\"WindowsPackageManagerDefaultProxy\">\n        <textBox refId=\"WindowsPackageManagerDefaultProxy\">\n          <label>Standardproxy</label>\n        </textBox>\n      </presentation>\n      <presentation id=\"MsixAllowedZones\">\n        <dropdownList refId=\"LocalMachine\" noSort=\"true\" defaultItem=\"1\">Lokaler Computer</dropdownList>\n        <dropdownList refId=\"Intranet\" noSort=\"true\" defaultItem=\"1\">Intranet</dropdownList>\n        <dropdownList refId=\"TrustedSites\" noSort=\"true\" defaultItem=\"1\">Vertrauenswürdige Sites</dropdownList>\n        <dropdownList refId=\"Internet\" noSort=\"true\" defaultItem=\"1\">Internet</dropdownList>\n        <dropdownList refId=\"UntrustedSites\" noSort=\"true\" defaultItem=\"0\">Nicht vertrauenswürdige Websites</dropdownList>\n      </presentation>\n    </presentationTable>\n  </resources>\n</policyDefinitionResources>\n"
  },
  {
    "path": "Localization/Policies/es-ES/DesktopAppInstaller.adml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (c) Microsoft Corporation.\n     Licensed under the MIT License. -->\n<policyDefinitionResources xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" revision=\"1.0\" schemaVersion=\"1.0\" xmlns=\"http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions\">\n  <displayName>Instalador de aplicación</displayName>\n  <description>Instalador de aplicación</description>\n  <resources>\n    <stringTable>\n      <string id=\"AppInstaller\">Instalador de aplicaciones de escritorio</string>\n      <string id=\"EnableAppInstaller\">Habilitar el Administrador de paquetes de Windows</string>\n      <string id=\"EnableAppInstallerExplanation\">Esta directiva controla si los usuarios pueden usar el administrador de paquetes de Windows.\n\nSi habilitas o no estableces esta configuración, los usuarios podrán usar el administrador de paquetes de Windows.\n\nSi deshabilitas esta configuración, los usuarios no podrán usar el administrador de paquetes de Windows.</string>\n      <string id=\"EnableSettings\">Habilitar la configuración del Administrador de paquetes de Windows</string>\n      <string id=\"EnableSettingsExplanation\">Esta directiva controla si los usuarios pueden cambiar su configuración.\n\nSi habilita o no establece esta configuración, los usuarios podrán cambiar la configuración del administrador de paquetes de Windows.\n\nSi deshabilitas esta configuración, los usuarios no podrán cambiar la configuración del administrador de paquetes de Windows.</string>\n      <string id=\"EnableExperimentalFeatures\">Habilitar Administrador de paquetes de Windows características experimentales</string>\n      <string id=\"EnableExperimentalFeaturesExplanation\">Esta directiva controla si los usuarios pueden habilitar características experimentales en el administrador de paquetes de Windows.\n\nSi habilitas o no configuras esta opción, los usuarios podrán habilitar las características experimentales para el administrador de paquetes de Windows.\n\nSi deshabilitas esta configuración, los usuarios no podrán habilitar las características experimentales para el administrador de paquetes de Windows.</string>\n      <string id=\"EnableLocalManifestFiles\">Habilitar Administrador de paquetes de Windows archivos de manifiesto local</string>\n      <string id=\"EnableLocalManifestFilesExplanation\">Esta directiva controla si los usuarios pueden instalar paquetes con archivos de manifiesto locales.\n\nSi habilitas o no configuras esta opción, los usuarios podrán instalar paquetes con manifiestos locales mediante el administrador de paquetes de Windows.\n\nSi deshabilitas esta configuración, los usuarios no podrán instalar paquetes con manifiestos locales mediante el administrador de paquetes de Windows.</string>\n      <string id=\"EnableBypassCertificatePinningForMicrosoftStore\">Habilitar Administrador de paquetes de Windows Microsoft Store omisión de validación de certificado de origen</string>\n      <string id=\"EnableBypassCertificatePinningForMicrosoftStoreExplanation\">Esta directiva controla si el Administrador de paquetes de Windows validará las coincidencias del hash del certificado de Microsoft Store con un certificado de Microsoft Store conocido al iniciar una conexión con el origen de Microsoft Store. \nSi habilita esta directiva, el Administrador de paquetes de Windows omitirá la validación del certificado de Microsoft Store. \n\nSi deshabilita esta directiva, el Administrador de paquetes de Windows validará que el certificado de Microsoft Store usado es válido y pertenece a Microsoft Store antes de comunicarse con el origen de Microsoft Store.\n\nSi no establece esta directiva, se usará la configuración de administrador del Administrador de paquetes de Windows.</string>\n      <string id=\"EnableHashOverride\">Habilitar invalidación de hash de Administrador de paquetes de Windows</string>\n      <string id=\"EnableHashOverrideExplanation\">Esta directiva controla si se puede configurar el administrador de paquetes de Windows para que permita revertir la validación de seguridad SHA256 en la configuración.\n\nSi habilita o no configura esta directiva, los usuarios podrán habilitar la capacidad de revertir la validación de seguridad SHA256 en la configuración del administrador de paquetes de Windows.\n\nSi deshabilita esta directiva, los usuarios no podrán habilitar la capacidad de revertir la validación de seguridad SHA256 en la configuración del administrador de paquetes de Windows.</string>\n      <string id=\"EnableLocalArchiveMalwareScanOverride\">Habilitar Administrador de paquetes de Windows invalidación del examen de malware de archivo local</string>\n      <string id=\"EnableLocalArchiveMalwareScanOverrideExplanation\">Esta directiva controla la capacidad de invalidar los exámenes de vulnerabilidades de malware al instalar un archivo de almacenamiento mediante un manifiesto local mediante los argumentos de la línea de comandos.\nSi habilita esta directiva, los usuarios pueden invalidar el examen de malware al realizar una instalación de manifiesto local de un archivo de almacenamiento.\n\nSi deshabilita esta directiva, los usuarios no podrán invalidar el examen de malware de un archivo de almacenamiento al instalarlo mediante un manifiesto local.\n\nSi no establece esta directiva, se cumplirá la configuración de administrador de Administrador de paquetes de Windows.</string>\n      <string id=\"EnableDefaultSource\">Habilitar Administrador de paquetes de Windows origen predeterminado</string>\n      <string id=\"EnableDefaultSourceExplanation\">Esta directiva controla la fuente predeterminada incluida con el Administrador de paquetes de Windows.\n\nSi no configura esta opción, el origen predeterminado para el Administrador de paquetes de Windows estará disponible y podrá eliminarse.\n\nSi habilita esta configuración, el origen predeterminado para el Administrador de paquetes de Windows estará disponible y no se podrá eliminar.\n\nSi desactiva esta configuración, la fuente por defecto para el Administrador de Paquetes de Windows no estará disponible.</string>\n      <string id=\"EnableMicrosoftStoreSource\">Habilitar Administrador de paquetes de Windows origen de Microsoft Store</string>\n      <string id=\"EnableMicrosoftStoreSourceExplanation\">Esta directiva controla la fuente de la Tienda Microsoft incluida en el Administrador de paquetes de Windows.\n\nSi no configura esta opción, el origen de la Tienda Microsoft para el Administrador de paquetes de Windows estará disponible y se podrá elimina.\n\nSi habilita esta configuración, el origen de Microsoft Store para el Administrador de paquetes de Windows estará disponible y no se podrá eliminar.\n\nSi desactiva esta configuración, el origen de la Tienda Microsoft para el Administrador de paquetes de Windows no estará disponible.</string>\n      <string id=\"EnableFontSource\">Habilitar el origen de la fuente de Administrador de paquetes de Windows</string>\n      <string id=\"EnableFontSourceExplanation\">\n        Esta directiva controla la fuente de la fuente incluida en el Administrador de paquetes de Windows.\n\n        Si no configuras esta opción, el origen de la fuente para el Administrador de paquetes de Windows estará disponible y se podrá elimina.\n\n        Si habilitas esta configuración, el origen de la fuente para el Administrador de paquetes de Windows estará disponible y no se podrá eliminar.\n\n        Si desactivas esta configuración, el origen de la fuente para el Administrador de paquetes de Windows no estará disponible.\n      </string>\n      <string id=\"SourceAutoUpdateInterval\">Establecer el intervalo de actualización automática del origen del Administrador de paquetes de Windows en minutos</string>\n      <string id=\"SourceAutoUpdateIntervalExplanation\">Esta directiva controla el intervalo de actualización automática para orígenes basados en paquetes. El origen predeterminado para Administrador de paquetes de Windows está configurado de forma que un índice de los paquetes se almacena en caché en el equipo local. El índice se descarga cuando un usuario invoca un comando y el intervalo ha pasado.\n\nSi deshabilita o no establece esta configuración, se usará el intervalo predeterminado o el valor especificado en la configuración de Administrador de paquetes de Windows.\n\nSi habilita esta configuración, el Administrador de paquetes de Windows usará el número de minutos especificado.</string>\n      <string id=\"EnableAdditionalSources\">Habilitar Administrador de paquetes de Windows orígenes adicionales</string>\n      <string id=\"EnableAdditionalSourcesExplanation\">Esta directiva controla los orígenes adicionales proporcionados por el administrador de TI de la empresa.\n\nSi no configura esta directiva, los orígenes adicionales no se podrán configurar para el Administrador de paquetes de Windows.\n\nSi habilita esta directiva, los orígenes adicionales se agregarán al Administrador de paquetes de Windows y no se podrán eliminar. La representación de cada origen adicional puede obtenerse de las fuentes instaladas mediante \"winget source export\".\n\nSi desactiva esta directiva, no se podrán configurar orígenes adicionales para el Administrador de paquetes de Windows.</string>\n      <string id=\"EnableAllowedSources\">Habilitar Administrador de paquetes de Windows orígenes permitidos</string>\n      <string id=\"EnableAllowedSourcesExplanation\">Esta directiva controla los orígenes adicionales permitidos por el administrador de TI de la empresa\n\nSi no configura esta directiva, los usuarios podrán agregar o eliminar fuentes adicionales distintas de las configuradas por la directiva.\n\nSi habilita esta directiva, sólo las fuentes especificadas podrán agregarse o eliminarse del Administrador de paquetes de Windows. La representación de cada fuente permitida puede obtenerse de las fuentes instaladas mediante \"winget source export\".\n\nSi desactiva esta directiva, no se pueden configurar fuentes adicionales para el Administrador de paquetes de Windows.</string>\n      <string id=\"EnableMSAppInstallerProtocol\">Habilitar protocolo ms-appinstaller del instalador de aplicaciones</string>\n      <string id=\"EnableMSAppInstallerProtocolExplanation\">Esta directiva controla si los usuarios pueden instalar paquetes desde un sitio web que usa el protocolo ms-appinstaller.\n\nSi habilita esta configuración, los usuarios podrán instalar paquetes de sitios web que usen este protocolo.\n\nSi deshabilita o no establece esta configuración, los usuarios no podrán instalar paquetes de sitios web que usen este protocolo.</string>\n      <string id=\"EnableWindowsPackageManagerCommandLineInterfaces\">Habilitar Administrador de paquetes de Windows interfaces de línea de comandos</string>\n      <string id=\"EnableWindowsPackageManagerCommandLineInterfacesExplanation\">Esta directiva determina si un usuario puede realizar una acción mediante el Administrador de paquetes de Windows a través de una interfaz de línea de comandos (CLI de WinGet o WinGet PowerShell).\n\n        Si deshabilita esta directiva, los usuarios no podrán ejecutar la CLI de Administrador de paquetes de Windows y los cmdlets de PowerShell.\n\n        Si habilita o no configura esta directiva, los usuarios podrán ejecutar los comandos de la CLI de Administrador de paquetes de Windows y los cmdlets de PowerShell. (Proporcionado “Habilitar Instalador de aplicación” directiva no está deshabilitada).\n\n        Esta directiva no invalida la directiva “Habilitar Instalador de aplicación”.</string>\n      <string id=\"EnableWindowsPackageManagerConfiguration\">Habilitar configuración de Administrador de paquetes de Windows</string>\n      <string id=\"EnableWindowsPackageManagerConfigurationExplanation\">Esta directiva controla si los usuarios pueden usar la característica de configuración Administrador de paquetes de Windows.\n\nSi habilita o no establece esta configuración, los usuarios podrán usar la característica de configuración Administrador de paquetes de Windows.\n\nSi deshabilita esta configuración, los usuarios no podrán usar la característica de configuración Administrador de paquetes de Windows.</string>\n      <string id=\"EnableWindowsPackageManagerProxyCommandLineOptions\">Habilitar Administrador de paquetes de Windows opciones de la línea de comandos del proxy</string>\n      <string id=\"EnableWindowsPackageManagerProxyCommandLineOptionsExplanation\">\n        Esta directiva controla si los usuarios pueden configurar el uso Administrador de paquetes de Windows del proxy a través de la línea de comandos.\n\nSi habilita esta configuración, los usuarios podrán configurar el uso del proxy del Administrador de paquetes de Windows a través de la línea de comandos.\n\nSi deshabilita o no establece esta configuración, los usuarios no podrán configurar el uso del proxy del Administrador de paquetes de Windows a través de la línea de comandos.</string>\n      <string id=\"EnableWindowsPackageManagerMcpServer\">Habilitar el servidor MCP para el Administrador de paquetes de Windows</string>\n      <string id=\"EnableWindowsPackageManagerMcpServerExplanation\">\n        Esta directiva controla si se puede usar el servidor del Protocolo de contexto de modelo de Administrador de paquetes de Windows (MCP).\n\nSi habilita o no establece esta configuración, los usuarios podrán usar el servidor MCP del Administrador de paquetes de Windows.\n\nSi deshabilita esta configuración, los usuarios no podrán usar el servidor MCP del Administrador de paquetes de Windows.</string>\n      <string id=\"WindowsPackageManagerDefaultProxy\">Establecer Administrador de paquetes de Windows proxy predeterminado</string>\n      <string id=\"WindowsPackageManagerDefaultProxyExplanation\">Esta directiva controla el proxy predeterminado que usa el Administrador de paquetes de Windows.\n\nSi deshabilita o no establece esta configuración, no se usará ningún proxy de forma predeterminada.\n\nSi habilita esta configuración, el proxy especificado se usará de forma predeterminada.</string>\n      <string id=\"EnableMsixAllowedZones\">Habilitar Instalador de aplicación zonas permitidas para paquetes MSIX</string>\n      <string id=\"EnableMsixAllowedZonesExplanation\">Esta directiva controla si Instalador de aplicación permite instalar paquetes procedentes de zonas URL específicas. El origen de un paquete está determinado por su URI y si hay presente un Mart-of-the-Web (MotW). Si hay varios URI implicados, se consideran todos; por ejemplo, cuando se usa un archivo .appinstaller que implica redirección.\n\nSi habilita esta directiva, los usuarios podrán instalar paquetes MSIX según la configuración de cada zona.\n\nSi deshabilitas o no configuras esta directiva, los usuarios podrán instalar paquetes MSIX desde cualquier zona excepto si no son de confianza.</string>\n      <string id=\"ZoneAllowed\">Permitir</string>\n      <string id=\"ZoneBlocked\">Bloquear</string>\n      <string id=\"EnableMsixSmartScreenCheck\">Habilitar las comprobaciones de Microsoft SmartScreen para paquetes MSIX</string>\n      <string id=\"EnableMsixSmartScreenCheckExplanation\">Esta directiva controla si Instalador de aplicación realiza comprobaciones de SmartScreen de Microsoft al instalar paquetes MSIX.\n\nSi habilitas o no configuras esta directiva, el URI del paquete se evaluará con Microsoft SmartScreen antes de la instalación. Esta comprobación solo se realiza para los paquetes procedentes de Internet.\n\nSi lo deshabilita, no se consultará a Microsoft SmartScreen antes de instalar un paquete.</string>\n    </stringTable>\n    <presentationTable>\n      <presentation id=\"SourceAutoUpdateInterval\">\n        <decimalTextBox refId=\"SourceAutoUpdateInterval\" defaultValue=\"5\">Intervalo de actualización automática de la fuente en minutos</decimalTextBox>\n      </presentation>\n      <presentation id=\"AdditionalSources\">\n        <listBox refId=\"AdditionalSources\" required=\"false\">Orígenes adicionales: </listBox>\n      </presentation>\n      <presentation id=\"AllowedSources\">\n        <listBox refId=\"AllowedSources\" required=\"false\">Orígenes permitidos: </listBox>\n      </presentation>\n      <presentation id=\"WindowsPackageManagerDefaultProxy\">\n        <textBox refId=\"WindowsPackageManagerDefaultProxy\">\n          <label>Proxy predeterminado</label>\n        </textBox>\n      </presentation>\n      <presentation id=\"MsixAllowedZones\">\n        <dropdownList refId=\"LocalMachine\" noSort=\"true\" defaultItem=\"1\">Equipo local</dropdownList>\n        <dropdownList refId=\"Intranet\" noSort=\"true\" defaultItem=\"1\">Intranet</dropdownList>\n        <dropdownList refId=\"TrustedSites\" noSort=\"true\" defaultItem=\"1\">Sitios de confianza</dropdownList>\n        <dropdownList refId=\"Internet\" noSort=\"true\" defaultItem=\"1\">Internet</dropdownList>\n        <dropdownList refId=\"UntrustedSites\" noSort=\"true\" defaultItem=\"0\">Sitio que no es de confianza</dropdownList>\n      </presentation>\n    </presentationTable>\n  </resources>\n</policyDefinitionResources>\n"
  },
  {
    "path": "Localization/Policies/fr-FR/DesktopAppInstaller.adml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (c) Microsoft Corporation.\n     Licensed under the MIT License. -->\n<policyDefinitionResources xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" revision=\"1.0\" schemaVersion=\"1.0\" xmlns=\"http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions\">\n  <displayName>Programme d'installation d'application</displayName>\n  <description>Programme d'installation d'application</description>\n  <resources>\n    <stringTable>\n      <string id=\"AppInstaller\">Programme d’installation des applications de bureau</string>\n      <string id=\"EnableAppInstaller\">Activer le Gestionnaire de package Windows</string>\n      <string id=\"EnableAppInstallerExplanation\">Cette stratégie contrôle si le gestionnaire de packages Windows peut être utilisé par les utilisateurs.\n\nSi vous activez ou ne configurez pas ce paramètre, les utilisateurs peuvent utiliser le gestionnaire de packages Windows.\n\nSi vous désactivez ce paramètre, les utilisateurs ne peuvent pas utiliser le gestionnaire de packages Windows.</string>\n      <string id=\"EnableSettings\">Activer les paramètres du Gestionnaire de package Windows</string>\n      <string id=\"EnableSettingsExplanation\">Cette stratégie contrôle si les utilisateurs peuvent modifier leurs paramètres.\n\nSi vous activez ou ne configurez pas ce paramètre, les utilisateurs peuvent modifier les paramètres du gestionnaire de packages Windows.\n\nSi vous désactivez ce paramètre, les utilisateurs ne peuvent pas modifier les paramètres du gestionnaire de packages Windows.</string>\n      <string id=\"EnableExperimentalFeatures\">Activer les fonctionnalités expérimentales du Gestionnaire de package Windows</string>\n      <string id=\"EnableExperimentalFeaturesExplanation\">Cette stratégie contrôle si les utilisateurs peuvent activer les fonctionnalités expérimentales dans le gestionnaire de packages Windows.\n\nSi vous activez ou ne configurez pas ce paramètre, les utilisateurs peuvent activer des fonctionnalités expérimentales pour le gestionnaire de package Windows.\n\nSi vous désactivez ce paramètre, les utilisateurs ne peuvent pas activer les fonctionnalités expérimentales pour le gestionnaire de package Windows.</string>\n      <string id=\"EnableLocalManifestFiles\">Activer les fichiers manifeste locaux du Gestionnaire de package Windows</string>\n      <string id=\"EnableLocalManifestFilesExplanation\">Cette stratégie contrôle si les utilisateurs peuvent installer des packages avec des fichiers de manifeste locaux.\n\nSi vous activez ou ne configurez pas ce paramètre, les utilisateurs peuvent installer des packages avec des manifestes locaux à l’aide du gestionnaire de packages Windows.\n\nSi vous désactivez ce paramètre, les utilisateurs ne peuvent pas installer de packages avec des manifestes locaux à l’aide du gestionnaire de packages Windows.</string>\n      <string id=\"EnableBypassCertificatePinningForMicrosoftStore\">Activer le contournement de validation du certificat source Microsoft Store du Gestionnaire de package Windows</string>\n      <string id=\"EnableBypassCertificatePinningForMicrosoftStoreExplanation\">Cette stratégie contrôle si le Gestionnaire de package Windows validera si les correspondances de hachage de certificat Microsoft Store correspond à un certificat Microsoft Store connu lors de l’initialisation d’une connexion à la source Microsoft Store. \nSi vous activez cette stratégie, le Gestionnaire de package Windows contourne la validation du certificat Microsoft Store. \n\nSi vous désactivez cette stratégie, le Gestionnaire de package Windows vérifie que le certificat Microsoft Store utilisé est valide et appartient au Microsoft Store avant de communiquer avec la source Microsoft Store.\n\nSi vous ne configurez pas cette stratégie, les paramètres d’administrateur Gestionnaire de package Windows sont respectés.</string>\n      <string id=\"EnableHashOverride\">Activer le remplacement de hachage du Gestionnaire de package Windows</string>\n      <string id=\"EnableHashOverrideExplanation\">Cette stratégie détermine si les utilisateurs peuvent configurer le Gestionnaire de package Windows ou non pour activer la fonction de remplacement de la validation de sécurité SHA256 dans les paramètres.\n\nSi vous activez ou ne configurez pas cette stratégie, les utilisateurs pourront activer la fonction de remplacement la validation de sécurité SHA256 dans les paramètres du Gestionnaire de package Windows.\n\nSi vous désactivez cette stratégie, les utilisateurs ne pourront pas activer la fonction de remplacement la validation de sécurité SHA256 dans les paramètres du Gestionnaire de package Windows.</string>\n      <string id=\"EnableLocalArchiveMalwareScanOverride\">Activer le remplacement de l’analyse des programmes malveillants des archives locales du Gestionnaire de package Windows</string>\n      <string id=\"EnableLocalArchiveMalwareScanOverrideExplanation\">Cette stratégie contrôle la possibilité de remplacer les analyses de vulnérabilités de programmes malveillants lors de l’installation d’un fichier d’archive à l’aide d’un manifeste local à l’aide des arguments de ligne de commande.\nSi vous activez ce paramètre de stratégie, les utilisateurs peuvent remplacer l’analyse des programmes malveillants lors de l’installation d’un manifeste local d’un fichier d’archive.\n\nSi vous désactivez cette stratégie, les utilisateurs ne peuvent pas remplacer l’analyse des programmes malveillants d’un fichier d’archive lors de l’installation à l’aide d’un manifeste local.\n\nSi vous ne configurez pas cette stratégie, les paramètres d’administrateur Gestionnaire de package Windows sont conformes.</string>\n      <string id=\"EnableDefaultSource\">Activer la source par défaut du Gestionnaire de package Windows</string>\n      <string id=\"EnableDefaultSourceExplanation\">Cette stratégie contrôle la source par défaut incluse dans le Gestionnaire de package Windows.\n\nSi vous ne configurez pas ce paramètre, la source par défaut pour le Gestionnaire de package Windows est disponible et peut être supprimée.\n\nSi vous activez ce paramètre, la source par défaut pour le Gestionnaire de package Windows est disponible et ne peut pas être supprimée.\n\nSi vous désactivez ce paramètre, la source par défaut pour le Gestionnaire de package Windows n’est pas disponible.</string>\n      <string id=\"EnableMicrosoftStoreSource\">Activer la source du Microsoft Store du Gestionnaire de package Windows</string>\n      <string id=\"EnableMicrosoftStoreSourceExplanation\">Cette stratégie contrôle la source du Microsoft Store incluse dans le Gestionnaire de package Windows.\n\nSi vous ne configurez pas ce paramètre, la source du Microsoft Store pour le Gestionnaire de package Windows est disponible et peut être supprimée.\n\nSi vous activez ce paramètre, la source du Microsoft Store pour le Gestionnaire de package Windows est disponible et ne peut pas être supprimée.\n\nSi vous désactivez ce paramètre, la source du Microsoft Store pour le Gestionnaire de package Windows n’est pas disponible.</string>\n      <string id=\"EnableFontSource\">Activer la source de polices du Gestionnaire de package Windows</string>\n      <string id=\"EnableFontSourceExplanation\">\n        Cette stratégie contrôle la source des polices incluse dans le Gestionnaire de package Windows.\n\n        Si vous ne configurez pas ce paramètre, la source de polices pour le Gestionnaire de package Windows sera disponible et pourra être supprimée.\n\n        Si vous activez ce paramètre, la source de polices pour le Gestionnaire de package Windows sera disponible et ne pourra pas être supprimée.\n\n        Si vous désactivez ce paramètre, la source de polices pour le Gestionnaire de package Windows ne sera pas disponible.\n      </string>\n      <string id=\"SourceAutoUpdateInterval\">Définir l’intervalle en minutes de la mise à jour automatique source du Gestionnaire de package Windows</string>\n      <string id=\"SourceAutoUpdateIntervalExplanation\">Cette stratégie contrôle l’intervalle de mise à jour automatique pour les sources basées sur les packages. La source par défaut de Gestionnaire de package Windows est configurée de sorte qu’un index des packages soit mis en cache sur l’ordinateur local. L’index est téléchargé lorsqu’un utilisateur appelle une commande et que l’intervalle est écoulé.\n\nSi vous désactivez ou ne configurez pas ce paramètre, l’intervalle par défaut ou la valeur spécifié dans les paramètres de Gestionnaire de package Windows sont utilisés.\n\nSi vous activez ce paramètre, le nombre de minutes spécifié est utilisé par le Gestionnaire de package Windows.</string>\n      <string id=\"EnableAdditionalSources\">Activer les sources supplémentaires du Gestionnaire de package Windows</string>\n      <string id=\"EnableAdditionalSourcesExplanation\">Cette stratégie contrôle les sources supplémentaires offertes par l’administrateur informatique de l’entreprise.\n\nSi vous ne configurez pas ce paramètre de stratégie, aucune source supplémentaire n’est configurée pour le Gestionnaire de package Windows.\n\nSi vous activez ce paramètre de stratégie, les sources supplémentaires sont ajoutées au Gestionnaire de package Windows et ne peuvent pas être supprimées. La représentation de chaque source supplémentaire peut être obtenue à partir de sources installées à l’aide de « Winget source export ».\n\nSi vous désactivez ce paramètre de stratégie, aucune source supplémentaire ne peut être configurée pour le Gestionnaire de package Windows.</string>\n      <string id=\"EnableAllowedSources\">Activer les sources autorisées du Gestionnaire de package Windows</string>\n      <string id=\"EnableAllowedSourcesExplanation\">Cette stratégie contrôle les sources supplémentaires autorisées par l’administrateur informatique de l’entreprise.\n\nSi vous ne configurez pas ce paramètre de stratégie, les utilisateurs pourront ajouter ou supprimer des sources supplémentaires autres que celles configurées par la stratégie Si\n\nSi vous activez cette stratégie, seules les sources spécifiées peuvent être ajoutées ou supprimées du Gestionnaire de package Windows. La représentation de chaque source autorisée peut être obtenue à partir de sources installées à l’aide de « Winget source export ».\n\nSi vous désactivez ce paramètre de stratégie, aucune source supplémentaire ne peut être configurée pour le Gestionnaire de package Windows.</string>\n      <string id=\"EnableMSAppInstallerProtocol\">Activer le protocole ms-appinstaller du Programme d'installation d'application</string>\n      <string id=\"EnableMSAppInstallerProtocolExplanation\">Cette stratégie contrôle si les utilisateurs peuvent installer des packages à partir d’un site web qui utilise le protocole ms-appinstaller.\n\nSi vous activez ce paramètre, les utilisateurs peuvent installer des packages à partir de sites web qui utilisent ce protocole.\n\nSi vous désactivez ou ne configurez pas ce paramètre, les utilisateurs ne peuvent pas installer de packages à partir de sites web qui utilisent ce protocole.</string>\n      <string id=\"EnableWindowsPackageManagerCommandLineInterfaces\">Activer les interfaces de ligne de commande Gestionnaire de package Windows</string>\n      <string id=\"EnableWindowsPackageManagerCommandLineInterfacesExplanation\">Cette stratégie détermine si un utilisateur peut effectuer une action à l’aide du Gestionnaire de package Windows via une interface de ligne de commande (WinGet CLI ou WinGet PowerShell).\n\n        Si vous désactivez cette stratégie, les utilisateurs ne pourront pas exécuter l’interface CLI Gestionnaire de package Windows et les cmdlets PowerShell.\n\n        Si vous activez ou ne configurez pas cette stratégie, les utilisateurs peuvent exécuter les commandes Gestionnaire de package Windows CLI et les cmdlets PowerShell. (La stratégie « Activer Programme d'installation d'application » fournie n’est pas désactivée).\n\n        Cette stratégie ne remplace pas la stratégie « Activer Programme d'installation d'application ».</string>\n      <string id=\"EnableWindowsPackageManagerConfiguration\">Activer la configuration Gestionnaire de package Windows</string>\n      <string id=\"EnableWindowsPackageManagerConfigurationExplanation\">Cette stratégie contrôle si la fonctionnalité de configuration Gestionnaire de package Windows peut être utilisée par les utilisateurs.\n\nSi vous activez ou ne configurez pas ce paramètre, les utilisateurs peuvent utiliser la fonctionnalité de configuration Gestionnaire de package Windows.\n\nSi vous désactivez ce paramètre, les utilisateurs ne peuvent pas utiliser la fonctionnalité de configuration Gestionnaire de package Windows.</string>\n      <string id=\"EnableWindowsPackageManagerProxyCommandLineOptions\">Activer les options de ligne de commande du proxy Gestionnaire de package Windows</string>\n      <string id=\"EnableWindowsPackageManagerProxyCommandLineOptionsExplanation\">\n        Cette stratégie contrôle si l’utilisation Gestionnaire de package Windows proxy peut être configurée par les utilisateurs via la ligne de commande.\n\nSi vous activez ce paramètre, les utilisateurs peuvent configurer l’utilisation du proxy par le Gestionnaire de package Windows via la ligne de commande.\n\nSi vous désactivez ou ne configurez pas ce paramètre, les utilisateurs ne peuvent pas configurer l’utilisation du proxy par le Gestionnaire de package Windows via la ligne de commande.</string>\n      <string id=\"EnableWindowsPackageManagerMcpServer\">Activer le serveur MCP pour le Gestionnaire de package Windows</string>\n      <string id=\"EnableWindowsPackageManagerMcpServerExplanation\">\n        Cette stratégie contrôle si le serveur MCP (Model Context Protocol) Gestionnaire de package Windows peut être utilisé.\n\nSi vous activez ou ne configurez pas ce paramètre, les utilisateurs peuvent utiliser le serveur MCP du Gestionnaire de package Windows.\n\nSi vous désactivez ce paramètre, les utilisateurs ne peuvent pas utiliser le serveur MCP du Gestionnaire de package Windows.</string>\n      <string id=\"WindowsPackageManagerDefaultProxy\">Définir Gestionnaire de package Windows proxy par défaut</string>\n      <string id=\"WindowsPackageManagerDefaultProxyExplanation\">Cette stratégie contrôle le proxy par défaut utilisé par le Gestionnaire de package Windows.\n\nSi vous désactivez ou ne configurez pas ce paramètre, aucun proxy n’est utilisé par défaut.\n\nSi vous activez ce paramètre, le proxy spécifié est utilisé par défaut.</string>\n      <string id=\"EnableMsixAllowedZones\">Activer les zones autorisées du programme d’installation d’application pour les packages MSIX</string>\n      <string id=\"EnableMsixAllowedZonesExplanation\">Cette stratégie contrôle si Programme d'installation d'application autorise l’installation de packages provenant de zones URL spécifiques. L’origine d’un package est déterminée par son URI et si un Mart-of-the-Web (MotW) est présent. Si plusieurs URI sont impliqués, tous sont pris en compte ; par exemple, lors de l’utilisation d’un fichier .appinstaller qui implique une redirection.\n\nSi vous activez cette stratégie, les utilisateurs peuvent installer des packages MSIX en fonction de la configuration de chaque zone.\n\nSi vous désactivez ou ne configurez pas cette stratégie, les utilisateurs peuvent installer des packages MSIX à partir de n’importe quelle zone, sauf pour les packages non approuvés.</string>\n      <string id=\"ZoneAllowed\">Autoriser</string>\n      <string id=\"ZoneBlocked\">Bloquer</string>\n      <string id=\"EnableMsixSmartScreenCheck\">Activer les vérifications Microsoft SmartScreen pour les packages MSIX</string>\n      <string id=\"EnableMsixSmartScreenCheckExplanation\">Cette stratégie contrôle si Programme d'installation d'application effectue des vérifications Microsoft SmartScreen lors de l’installation des packages MSIX.\n\nSi vous activez ou ne configurez pas cette stratégie, l’URI du package est évalué avec Microsoft SmartScreen avant l’installation. Cette case activée est effectuée uniquement pour les packages provenant d’Internet.\n\nSi vous désactivez, Microsoft SmartScreen n’est pas consulté avant d’installer un package.</string>\n    </stringTable>\n    <presentationTable>\n      <presentation id=\"SourceAutoUpdateInterval\">\n        <decimalTextBox refId=\"SourceAutoUpdateInterval\" defaultValue=\"5\">Intervalle en minutes de mise à jour automatique de source</decimalTextBox>\n      </presentation>\n      <presentation id=\"AdditionalSources\">\n        <listBox refId=\"AdditionalSources\" required=\"false\">Sources supplémentaires : </listBox>\n      </presentation>\n      <presentation id=\"AllowedSources\">\n        <listBox refId=\"AllowedSources\" required=\"false\">Sources autorisées : </listBox>\n      </presentation>\n      <presentation id=\"WindowsPackageManagerDefaultProxy\">\n        <textBox refId=\"WindowsPackageManagerDefaultProxy\">\n          <label>Proxy par défaut</label>\n        </textBox>\n      </presentation>\n      <presentation id=\"MsixAllowedZones\">\n        <dropdownList refId=\"LocalMachine\" noSort=\"true\" defaultItem=\"1\">Ordinateur local</dropdownList>\n        <dropdownList refId=\"Intranet\" noSort=\"true\" defaultItem=\"1\">Intranet</dropdownList>\n        <dropdownList refId=\"TrustedSites\" noSort=\"true\" defaultItem=\"1\">Sites de confiance</dropdownList>\n        <dropdownList refId=\"Internet\" noSort=\"true\" defaultItem=\"1\">Internet</dropdownList>\n        <dropdownList refId=\"UntrustedSites\" noSort=\"true\" defaultItem=\"0\">Sites non approuvés</dropdownList>\n      </presentation>\n    </presentationTable>\n  </resources>\n</policyDefinitionResources>\n"
  },
  {
    "path": "Localization/Policies/it-IT/DesktopAppInstaller.adml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (c) Microsoft Corporation.\n     Licensed under the MIT License. -->\n<policyDefinitionResources xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" revision=\"1.0\" schemaVersion=\"1.0\" xmlns=\"http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions\">\n  <displayName>Programma di installazione app</displayName>\n  <description>Programma di installazione app</description>\n  <resources>\n    <stringTable>\n      <string id=\"AppInstaller\">Programma di installazione app desktop</string>\n      <string id=\"EnableAppInstaller\">Abilita Gestione pacchetti Windows</string>\n      <string id=\"EnableAppInstallerExplanation\">Questo criterio Controlla se Windows Gestione pacchetti può essere utilizzato dagli utenti.\n\nSe si Abilita o non si configura questa impostazione, gli utenti potranno utilizzare Windows Gestione pacchetti.\n\nSe si disabilita questa impostazione, gli utenti non potranno utilizzare Windows Gestione pacchetti.</string>\n      <string id=\"EnableSettings\">Abilita le impostazioni di Gestione pacchetti Windows</string>\n      <string id=\"EnableSettingsExplanation\">Questo criterio Controlla se gli utenti possono modificare le impostazioni.\n\nSe si Abilita o non si configura questa impostazione, gli utenti potranno modificare le impostazioni di Windows Gestione pacchetti.\n\nSe si disabilita questa impostazione, gli utenti non saranno in grado di modificare le impostazioni per Windows Gestione pacchetti.</string>\n      <string id=\"EnableExperimentalFeatures\">Abilita le funzionalità sperimentali di Gestione pacchetti Windows</string>\n      <string id=\"EnableExperimentalFeaturesExplanation\">Questo criterio Controlla se gli utenti possono abilitare le funzionalità sperimentali in Windows Gestione pacchetti.\n\nSe si Abilita o non si configura questa impostazione, gli utenti potranno abilitare le funzionalità sperimentali per Windows Gestione pacchetti.\n\nSe si disabilita questa impostazione, gli utenti non saranno in grado di abilitare le funzionalità sperimentali per Windows Gestione pacchetti.</string>\n      <string id=\"EnableLocalManifestFiles\">Abilita i file manifesto locali di Gestione pacchetti Windows</string>\n      <string id=\"EnableLocalManifestFilesExplanation\">Questo criterio Controlla se gli utenti possono installare pacchetti con file di manifesto locali.\n\nSe si Abilita o non si configura questa impostazione, gli utenti potranno installare pacchetti con manifesti locali tramite Windows Gestione pacchetti.\n\nSe si disabilita questa impostazione, gli utenti non saranno in grado di installare pacchetti con manifesti locali tramite Windows Gestione pacchetti.</string>\n      <string id=\"EnableBypassCertificatePinningForMicrosoftStore\">Abilita il bypass di convalida del certificato di Microsoft Store di Gestione pacchetti Windows</string>\n      <string id=\"EnableBypassCertificatePinningForMicrosoftStoreExplanation\">Questo criterio consente di stabilire se Gestione pacchetti Windows convaliderà la corrispondenza dell'hash del certificato Microsoft Store con un certificato Microsoft Store noto quando si avvia una connessione all'origine Microsoft Store. \nSe si abilita questo criterio, Gestione pacchetti Windows ignorerà la convalida del certificato Microsoft Store. \n\nSe si disabilita questo criterio, Gestione pacchetti Windows convaliderà il certificato Microsoft Store usato affinché sia valido e appartenga a Microsoft Store prima di comunicare con l'origine Microsoft Store.\n\nSe non si configura questo criterio, verranno rispettate le impostazioni dell'amministratore di Gestione pacchetti Windows.</string>\n      <string id=\"EnableHashOverride\">Abilita l’override dell’hash di Gestione pacchetti Windows</string>\n      <string id=\"EnableHashOverrideExplanation\">Questa impostazione dei criteri consente di specificare se Windows Gestione pacchetti può essere configurato per abilitare la possibilità di ignorare la convalida di sicurezza SHA256 nelle impostazioni.\n\nSe si Abilita o non si configura questa impostazione dei criteri, gli utenti potranno abilitare la funzionalità di poter ignorare la convalida della sicurezza SHA256 nelle impostazioni di Windows Gestione pacchetti.\n\nSe si disabilita questa impostazione dei criteri, gli utenti non potranno abilitare la funzionalità di ignorare la convalida della sicurezza SHA256 nelle impostazioni di Windows Gestione pacchetti.</string>\n      <string id=\"EnableLocalArchiveMalwareScanOverride\">Abilita l'override dell'analisi malware dell'archivio locale di Gestione pacchetti Windows</string>\n      <string id=\"EnableLocalArchiveMalwareScanOverrideExplanation\">Questo criterio consente di controllare la possibilità di eseguire l'override delle analisi di vulnerabilità malware durante l'installazione di un file di archivio usando un manifesto locale usando gli argomenti della riga di comando.\nSe si abilita questo criterio, gli utenti potranno eseguire l'override dell'analisi antimalware durante l'installazione di un manifesto locale di un file di archivio.\n\nSe si disabilita questo criterio, gli utenti non potranno eseguire l'override dell'analisi malware di un file di archivio durante l'installazione con un manifesto locale.\n\nSe non si configura questo criterio, le impostazioni dell'amministratore di Gestione pacchetti Windows saranno conformi.</string>\n      <string id=\"EnableDefaultSource\">Abilita l’origine predefinita di Gestione pacchetti Windows</string>\n      <string id=\"EnableDefaultSourceExplanation\">Questo criterio controlla l'origine predefinita inclusa in Gestione pacchetti Windows.\n\nSe non si configura questa impostazione, l'origine predefinita per il gestore dei pacchetti di Windows sarà disponibile e potrà essere rimossa.\n\nSe si abilita questa impostazione, l'origine predefinita per Windows Gestione pacchetti sarà disponibile e non potrà essere rimossa.\n\nSe si disabilita questa impostazione, l'origine predefinita per Windows Gestione pacchetti non sarà disponibile.</string>\n      <string id=\"EnableMicrosoftStoreSource\">Abilita l’origine di Microsoft Store di Gestione pacchetti Windows</string>\n      <string id=\"EnableMicrosoftStoreSourceExplanation\">Questo criterio controlla l'origine Microsoft Store inclusa in Windows Gestione pacchetti.\n\nSe non si configura questa impostazione, l'origine Microsoft Store per il gestore dei pacchetti di Windows sarà disponibile e potrà essere rimossa.\n\nSe si abilita questa impostazione, l'origine Microsoft Store per Windows Gestione pacchetti sarà disponibile e non potrà essere rimossa.\n\nSe si disabilita questa impostazione, l'origine Microsoft Store per Windows Gestione pacchetti non sarà disponibile.</string>\n      <string id=\"EnableFontSource\">Abilita origine carattere Gestione pacchetti Windows</string>\n      <string id=\"EnableFontSourceExplanation\">\n        Questo criterio controlla l'origine carattere inclusa nel Gestione pacchetti Windows.\n\n        Se non si configura questa impostazione, l'origine del tipo di carattere per Gestione pacchetti Windows sarà disponibile e può essere rimossa.\n\n        Se si abilita questa impostazione, l'origine carattere per il Gestione pacchetti Windows sarà disponibile e non potrà essere rimossa.\n\n        Se si disabilita questa impostazione, l'origine carattere per il Gestione pacchetti Windows non sarà disponibile.\n      </string>\n      <string id=\"SourceAutoUpdateInterval\">Imposta l’intervallo di aggiornamento automatico di origine Gestione pacchetti Windows in minuti</string>\n      <string id=\"SourceAutoUpdateIntervalExplanation\">Questo criterio controlla l'intervallo di aggiornamento automatico per le origini basate su pacchetto. L'origine predefinita per Gestione pacchetti Windows è configurata in modo che un indice dei pacchetti venga memorizzato nella cache nel computer locale. L'indice viene scaricato quando un utente richiama un comando e l'intervallo è passato.\n\nSe si disabilita o non si configura questa impostazione, verrà utilizzato l'intervallo predefinito o il valore specificato nelle impostazioni Gestione pacchetti Windows.\n\nSe si abilita questa impostazione, il numero di minuti specificato verrà utilizzato dal Gestione pacchetti Windows.</string>\n      <string id=\"EnableAdditionalSources\">Abilita le origini aggiuntive di Gestione pacchetti Windows</string>\n      <string id=\"EnableAdditionalSourcesExplanation\">Questo criterio controlla le origini aggiuntive fornite dall'amministratore IT dell'organizzazione.\n\nSe non si configura questa impostazione dei criteri, non verrà configurata alcuna origine aggiuntiva per Windows Gestione pacchetti.\n\nSe si Abilita questo criterio, le origini aggiuntive verranno aggiunte a Windows Gestione pacchetti e non potranno essere rimosse. È possibile ottenere la rappresentazione di ogni origine aggiuntiva dalle origini installate usando 'esportazione di origine winget'.\n\nSe si disabilita questo criterio, non sarà possibile configurare altre origini per Windows Gestione pacchetti.</string>\n      <string id=\"EnableAllowedSources\">Abilita le origini consentite di Gestione pacchetti Windows</string>\n      <string id=\"EnableAllowedSourcesExplanation\">Questo criterio controlla le origini aggiuntive fornite dall'amministratore IT dell'organizzazione.\n\nSe non si configura questa impostazione dei criteri, gli utenti potranno aggiungere o rimuovere ulteriori origini oltre quelle configurate dal criterio.\n\nSe si Abilita questo criterio, solo le origini specificate possono essere aggiunte o rimosse a Windows Gestione pacchetti. È possibile ottenere la rappresentazione di ogni origine aggiuntiva dalle origini installate usando 'esportazione di origine winget'.\n\nSe si disabilita questo criterio, non sarà possibile configurare altre origini per Windows Gestione pacchetti.</string>\n      <string id=\"EnableMSAppInstallerProtocol\">Abilita protocollo del programma di installazione app ms-appinstaller</string>\n      <string id=\"EnableMSAppInstallerProtocolExplanation\">Questo criterio controlla se gli utenti possono installare pacchetti da un sito Web che usa il protocollo ms-appinstaller.\n\nSe si abilita questa impostazione, gli utenti potranno installare pacchetti da siti Web che utilizzano questo protocollo.\n\nSe si disabilita o non si configura questa impostazione, gli utenti non potranno installare pacchetti da siti Web che utilizzano questo protocollo.</string>\n      <string id=\"EnableWindowsPackageManagerCommandLineInterfaces\">Abilita Gestione interfacce della riga di comando dei pacchetti Windows</string>\n      <string id=\"EnableWindowsPackageManagerCommandLineInterfacesExplanation\">Questo criterio determina se un utente può eseguire un'azione usando Gestione pacchetti Windows tramite un'interfaccia della riga di comando (interfaccia della riga di comando di WinGet o WinGet PowerShell).\n\n        Se si disabilita questo criterio, gli utenti non saranno in grado di eseguire l'interfaccia della riga di comando Gestione pacchetti Windows e i cmdlet di PowerShell.\n\n        Se si abilita o non si configura questo criterio, gli utenti non saranno in grado di eseguire l'interfaccia della riga di comando Gestione pacchetti Windows e i cmdlet di PowerShell. (se il criterio \"Abilita programma di installazione app\" non è disabilitato).\n\n        Questo criterio non sostituisce il criterio \"Abilita programma di installazione app\".</string>\n      <string id=\"EnableWindowsPackageManagerConfiguration\">Abilita la configurazione di Gestione pacchetti</string>\n      <string id=\"EnableWindowsPackageManagerConfigurationExplanation\">Questo criterio controlla se la funzionalità di configurazione Gestione pacchetti Windows può essere usata dagli utenti.\n\nSe si abilita o non si configura questa impostazione, gli utenti potranno usare la funzionalità di configurazione Gestione pacchetti Windows.\n\nSe si disabilita questa impostazione, gli utenti non potranno usare la funzionalità di configurazione Gestione pacchetti Windows.</string>\n      <string id=\"EnableWindowsPackageManagerProxyCommandLineOptions\">Abilita le opzioni della riga di comando del proxy Gestione pacchetti Windows</string>\n      <string id=\"EnableWindowsPackageManagerProxyCommandLineOptionsExplanation\">\n        Questo criterio controlla se l'utilizzo Gestione pacchetti Windows del proxy può essere configurato dagli utenti tramite la riga di comando.\n\nSe si abilita questa impostazione, gli utenti potranno configurare l'uso del proxy da parte del Gestione pacchetti Windows tramite la riga di comando.\n\nSe si disabilita o non si configura questa impostazione, gli utenti non potranno configurare l'utilizzo del proxy da parte del Gestione pacchetti Windows tramite la riga di comando.</string>\n      <string id=\"EnableWindowsPackageManagerMcpServer\">Abilitare il server MCP per Gestione pacchetti Windows</string>\n      <string id=\"EnableWindowsPackageManagerMcpServerExplanation\">\n        Questo criterio controlla se è possibile utilizzare il server MCP (Model Context Protocol) Gestione pacchetti Windows.\n\nSe si abilita o non si configura questa impostazione, gli utenti potranno utilizzare il server MCP del Gestione pacchetti Windows.\n\nSe si disabilita questa impostazione, gli utenti non potranno utilizzare il server MCP del Gestione pacchetti Windows.</string>\n      <string id=\"WindowsPackageManagerDefaultProxy\">Imposta proxy predefinito Gestione pacchetti Windows</string>\n      <string id=\"WindowsPackageManagerDefaultProxyExplanation\">Questo criterio controlla il proxy predefinito utilizzato dal Gestione pacchetti Windows.\n\nSe si disabilita o non si configura questa impostazione, per impostazione predefinita non verrà utilizzato alcun proxy.\n\nSe si abilita questa impostazione, per impostazione predefinita verrà utilizzato il proxy specificato.</string>\n      <string id=\"EnableMsixAllowedZones\">Abilita le zone consentite del programma di installazione app per i pacchetti MSIX</string>\n      <string id=\"EnableMsixAllowedZonesExplanation\">Questo criterio controlla se Programma di installazione app consente l'installazione di pacchetti provenienti da aree URL specifiche. L'origine di un pacchetto è determinata dal relativo URI e dalla presenza di un Mart-of-the-Web (MotW). Se sono coinvolti più URI, vengono considerati tutti; ad esempio, quando si utilizza un file con estensione appinstaller che implica il reindirizzamento.\n\nSe si abilita questo criterio, gli utenti potranno installare i pacchetti MSIX in base alla configurazione per ogni area.\n\nSe si disabilita o non si configura questo criterio, gli utenti potranno installare pacchetti MSIX da qualsiasi area, ad eccezione di Non attendibili.</string>\n      <string id=\"ZoneAllowed\">Consenti</string>\n      <string id=\"ZoneBlocked\">Blocca</string>\n      <string id=\"EnableMsixSmartScreenCheck\">Abilita i controlli di Microsoft SmartScreen per i pacchetti MSIX</string>\n      <string id=\"EnableMsixSmartScreenCheckExplanation\">Questo criterio controlla se Programma di installazione app esegue controlli Microsoft SmartScreen durante l'installazione dei pacchetti MSIX.\n\nSe si abilita o non si configura questo criterio, l'URI del pacchetto verrà valutato con Microsoft SmartScreen prima dell'installazione. Questo controllo viene eseguito solo per i pacchetti provenienti da Internet.\n\nSe si disabilita, Microsoft SmartScreen non verrà avvisato prima di installare un pacchetto.</string>\n    </stringTable>\n    <presentationTable>\n      <presentation id=\"SourceAutoUpdateInterval\">\n        <decimalTextBox refId=\"SourceAutoUpdateInterval\" defaultValue=\"5\">Intervallo di aggiornamento automatico di origine in minuti</decimalTextBox>\n      </presentation>\n      <presentation id=\"AdditionalSources\">\n        <listBox refId=\"AdditionalSources\" required=\"false\">Origini aggiuntive: </listBox>\n      </presentation>\n      <presentation id=\"AllowedSources\">\n        <listBox refId=\"AllowedSources\" required=\"false\">Origini consentite: </listBox>\n      </presentation>\n      <presentation id=\"WindowsPackageManagerDefaultProxy\">\n        <textBox refId=\"WindowsPackageManagerDefaultProxy\">\n          <label>Proxy predefinito</label>\n        </textBox>\n      </presentation>\n      <presentation id=\"MsixAllowedZones\">\n        <dropdownList refId=\"LocalMachine\" noSort=\"true\" defaultItem=\"1\">Computer locale</dropdownList>\n        <dropdownList refId=\"Intranet\" noSort=\"true\" defaultItem=\"1\">Intranet</dropdownList>\n        <dropdownList refId=\"TrustedSites\" noSort=\"true\" defaultItem=\"1\">Siti attendibili</dropdownList>\n        <dropdownList refId=\"Internet\" noSort=\"true\" defaultItem=\"1\">Internet</dropdownList>\n        <dropdownList refId=\"UntrustedSites\" noSort=\"true\" defaultItem=\"0\">Siti non attendibili</dropdownList>\n      </presentation>\n    </presentationTable>\n  </resources>\n</policyDefinitionResources>\n"
  },
  {
    "path": "Localization/Policies/ja-JP/DesktopAppInstaller.adml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (c) Microsoft Corporation.\n     Licensed under the MIT License. -->\n<policyDefinitionResources xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" revision=\"1.0\" schemaVersion=\"1.0\" xmlns=\"http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions\">\n  <displayName>アプリ インストーラー</displayName>\n  <description>アプリ インストーラー</description>\n  <resources>\n    <stringTable>\n      <string id=\"AppInstaller\">デスクトップ アプリ インストーラー</string>\n      <string id=\"EnableAppInstaller\">Windows パッケージ マネージャーを有効にする</string>\n      <string id=\"EnableAppInstallerExplanation\">このポリシーでは、ユーザーが Windows パッケージマネージャーを使用できるかどうかを制御します。\n\nこの設定を有効にした場合、または構成しなかった場合、ユーザーは Windows パッケージマネージャーを使用できます。\n\nこの設定を無効にした場合、ユーザーは Windows パッケージマネージャーを使用できなくなります。</string>\n      <string id=\"EnableSettings\">Windows パッケージ マネージャーを有効にする</string>\n      <string id=\"EnableSettingsExplanation\">このポリシーでは、ユーザーが設定を変更できるかどうかを制御します。\n\nこの設定を有効にした場合、または構成しなかった場合、ユーザーは Windows パッケージマネージャーの設定を変更することができます。\n\nこの設定を無効にした場合、ユーザーは Windows パッケージマネージャーの設定を変更できなくなります。</string>\n      <string id=\"EnableExperimentalFeatures\">Windows パッケージ マネージャーの試験的な機能を有効にする</string>\n      <string id=\"EnableExperimentalFeaturesExplanation\">このポリシーでは、ユーザーが Windows パッケージマネージャーで試験的な機能を有効にできるかどうかを制御します。\n\nこの設定を有効にした場合、または構成しなかった場合、ユーザーは Windows パッケージマネージャーに対して実験的な機能を有効にすることができます。\n\nこの設定を無効にした場合、ユーザーは Windows パッケージマネージャーの実験的な機能を有効にできなくなります。</string>\n      <string id=\"EnableLocalManifestFiles\">Windows パッケージ マネージャーのローカル マニフェスト ファイルを有効にする</string>\n      <string id=\"EnableLocalManifestFilesExplanation\">このポリシーでは、ローカルマニフェストファイルを含むパッケージをユーザーがインストールできるかどうかを制御します。\n\nこの設定を有効にした場合、または構成しなかった場合、ユーザーは Windows パッケージマネージャーを使用してローカルのマニフェストを含むパッケージをインストールできます。\n\nこの設定を無効にした場合、ユーザーは Windows パッケージマネージャーを使用してローカルのマニフェストを含むパッケージをインストールできなくなります。</string>\n      <string id=\"EnableBypassCertificatePinningForMicrosoftStore\">Windows パッケージ マネージャーでの Microsoft Store ソースの証明書検証バイパスを有効にする</string>\n      <string id=\"EnableBypassCertificatePinningForMicrosoftStoreExplanation\">このポリシーでは、Microsoft Store ソースへの接続を開始するときに、Windows パッケージ マネージャーが既知の Microsoft Store 証明書と一致する Microsoft Store 証明書ハッシュを検証するかどうかを制御します。\nこのポリシーを有効にした場合、Windows パッケージ マネージャーは Microsoft Store 証明書の検証をバイパスします。\n\nこのポリシーを無効にした場合、Windows パッケージ マネージャーは、Microsoft Store ソースと通信する前に、使用されている Microsoft Store 証明書が有効であり、Microsoft Store に属していることを検証します。\n\nこのポリシーを構成しなかった場合は、Windows パッケージ マネージャー管理者の設定が適用されます。</string>\n      <string id=\"EnableHashOverride\">Windows パッケージ マネージャーのハッシュ オーバーライドを有効にする</string>\n      <string id=\"EnableHashOverrideExplanation\">このポリシーでは、設定の SHA256 セキュリティ検証を上書きする機能を有効にできるように Windows パッケージ マネージャーを構成できるかどうかを制御します。\n\nこのポリシーを有効にした場合、または構成しなかった場合、ユーザーは Windows パッケージ マネージャーの設定で SHA256 セキュリティ検証を上書きする機能を有効にすることができます。\n\nこのポリシーを無効にした場合、ユーザーは Windows パッケージ マネージャーの設定で SHA256 セキュリティ検証を上書きする機能を有効することができなくなります。</string>\n      <string id=\"EnableLocalArchiveMalwareScanOverride\">Windows パッケージ マネージャーでのローカル アーカイブ マルウェア スキャンのオーバーライドを有効にする</string>\n      <string id=\"EnableLocalArchiveMalwareScanOverrideExplanation\">このポリシーでは、コマンド ライン引数を使用してローカル マニフェストを使用してアーカイブ ファイルをインストールするときに、マルウェアの脆弱性スキャンをオーバーライドする機能を制御します。\nこのポリシーを有効にした場合、アーカイブ ファイルのローカル マニフェストのインストールを実行するときに、ユーザーはマルウェア スキャンをオーバーライドできます。\n\nこのポリシーを無効にすると、ユーザーはローカル マニフェストを使用してインストールするときにアーカイブ ファイルのマルウェア スキャンをオーバーライドできなくなります。\n\nこのポリシーを構成しなかった場合は、Windows パッケージ マネージャー管理者の設定が適用されます。</string>\n      <string id=\"EnableDefaultSource\">Windows パッケージ マネージャーの既定のソースを有効にする</string>\n      <string id=\"EnableDefaultSourceExplanation\">このポリシーでは、Windows パッケージ マネージャーに含まれている 既定ソースを制御します。\n\nこの設定を構成しなかった場合、Windows パッケージ マネージャーの 既定ソースが利用可能になり、削除できるようになります。\n\nこの設定を有効にした場合、Windows パッケージ マネージャーの 既定ソースが利用できるようになり、削除できなくなります。\n\nこの設定を無効にした場合、Windows パッケージマ ネージャーの 既定ソースは利用できなくなります。</string>\n      <string id=\"EnableMicrosoftStoreSource\">Windows パッケージ マネージャーの Microsoft Store ソースを有効にする</string>\n      <string id=\"EnableMicrosoftStoreSourceExplanation\">このポリシーでは、Windows パッケージ マネージャーに含まれている Microsoft Store ソースを制御します。\n\nこの設定を構成しなかった場合、Windows パッケージ マネージャーの Microsoft Store ソースが利用可能になり、削除できるようになります。\n\nこの設定を有効にした場合、Windows パッケージ マネージャーの Microsoft Store ソースが利用できるようになり、削除できなくなります。\n\nこの設定を無効にした場合、Windows パッケージマ ネージャーの Microsoft Store ソースは利用できなくなります。</string>\n      <string id=\"EnableFontSource\">Windows パッケージ マネージャーのフォントのソースを有効にする</string>\n      <string id=\"EnableFontSourceExplanation\">\n        このポリシーでは、Windows パッケージ マネージャーに含まれているフォント ソースを制御します。\n\n        この設定を構成しなかった場合、Windows パッケージ マネージャーのフォント ソースが利用可能になり、削除できるようになります。\n\n        この設定を有効にした場合、Windows パッケージ マネージャーのフォント ソースが利用できるようになり、削除できなくなります。\n\n        この設定を無効にした場合、Windows パッケージ マネージャーのフォント ソースは利用できなくなります。\n      </string>\n      <string id=\"SourceAutoUpdateInterval\">Windows パッケージ マネージャーのソース自動更新間隔を分単位で設定する</string>\n      <string id=\"SourceAutoUpdateIntervalExplanation\">このポリシーは、パッケージ ベースのソースの自動更新間隔を制御します。Windows パッケージ マネージャーの既定のソースは、パッケージのインデックスがローカル コンピューターにキャッシュされるように構成されています。インデックスは、ユーザーがコマンドを呼び出し、間隔が過ぎたときにダウンロードされます。\n\nこの設定を無効にした場合、または構成しなかった場合は、既定の間隔またはWindows パッケージ マネージャー設定で指定された値が使用されます。\n\nこの設定を有効にした場合、指定した分数がWindows パッケージ マネージャーで使用されます。</string>\n      <string id=\"EnableAdditionalSources\">Windows パッケージ マネージャーの追加のソースを有効にする</string>\n      <string id=\"EnableAdditionalSourcesExplanation\">このポリシーは、エンタープライズIT管理者によって提供される追加のソースを制御します。\n\nこのポリシーを構成しない場合、Windows パッケージ マネージャー用に追加のソースは構成されません。\n\nこのポリシーを有効にすると、追加のソースが Windows パッケージ マネージャーに追加され、削除できなくなります。 追加の各ソースの表現は、「wingetsourceexport」を使用してインストールされたソースから取得できます。\n\nこのポリシーを無効にすると、Windows パッケージ マネージャーに追加のソースを構成できなくなります。</string>\n      <string id=\"EnableAllowedSources\">Windows パッケージ マネージャーの許可されたソースを有効にする</string>\n      <string id=\"EnableAllowedSourcesExplanation\">このポリシーは、エンタープライズ IT 管理者が許可する追加のソースを制御します。\n\nこのポリシーを構成しない場合、ユーザーはポリシーで構成されたソース以外のソースを追加または削除できます。\n\nこのポリシーを有効にすると、指定したソースのみを Windows パッケージ マネージャーに追加または Windows パッケージ マネージャーから削除できます。 許可された各ソースの表現は、「wingetsourceexport」を使用してインストールされたソースから取得できます。\n\nこのポリシーを無効にすると、Windows パッケージ マネージャーに追加のソースを構成できなくなります。</string>\n      <string id=\"EnableMSAppInstallerProtocol\">アプリ インストーラーの ms-appinstaller プロトコルを有効にする</string>\n      <string id=\"EnableMSAppInstallerProtocolExplanation\">このポリシーでは、ユーザーが ms-appinstaller プロトコルを使用している Web サイトからパッケージをインストールできるかどうかを制御します。\n\nこの設定を有効にした場合、ユーザーは、このプロトコルを使用する Web サイトからパッケージをインストールできます。\n\nこの設定を無効にするか、未構成にした場合、ユーザーはこのプロトコルを使用する Web サイトからパッケージをインストールできなくなります。</string>\n      <string id=\"EnableWindowsPackageManagerCommandLineInterfaces\">Windows パッケージ マネージャーのコマンド ライン インターフェイスを有効にする</string>\n      <string id=\"EnableWindowsPackageManagerCommandLineInterfacesExplanation\">このポリシーは、ユーザーがコマンド ライン インターフェイス (WinGet CLI または WinGet PowerShell) を使用してWindows パッケージ マネージャーを使用してアクションを実行できるかどうかを決定します。\n\n       このポリシーを無効にすると、ユーザーは Windows パッケージ マネージャー CLI と PowerShell コマンドレットを実行できなくなります。\n\n       このポリシーを有効にした場合、または構成しなかった場合、ユーザーは Windows パッケージ マネージャー CLI コマンドと PowerShell コマンドレットを実行できます。(ただし、\"アプリ インストーラーを有効にする\" ポリシーが無効になっていない場合に限ります)。\n\n       このポリシーは、\"アプリ インストーラーを有効にする\" ポリシーをオーバーライドしません。</string>\n      <string id=\"EnableWindowsPackageManagerConfiguration\">Windows パッケージ マネージャーの構成を有効にする</string>\n      <string id=\"EnableWindowsPackageManagerConfigurationExplanation\">このポリシーでは、Windows パッケージ マネージャー構成機能をユーザーが使用できるかどうかを制御します。\n\nこの設定を有効にした場合、または構成しなかった場合、ユーザーはWindows パッケージ マネージャー構成機能を使用できます。\n\nこの設定を無効にすると、ユーザーはWindows パッケージ マネージャー構成機能を使用できなくなります。</string>\n      <string id=\"EnableWindowsPackageManagerProxyCommandLineOptions\">Windows パッケージ マネージャー Proxy コマンド ライン オプションを有効にする</string>\n      <string id=\"EnableWindowsPackageManagerProxyCommandLineOptionsExplanation\">\n        このポリシーでは、ユーザーがコマンド ラインでプロキシのWindows パッケージ マネージャーの使用を構成できるかどうかを制御します。\n\nこの設定を有効にした場合、ユーザーはコマンド ラインを使用してWindows パッケージ マネージャーのプロキシの使用を構成できます。\n\nこの設定を無効にした場合、または構成しなかった場合、ユーザーはコマンド ラインでWindows パッケージ マネージャーのプロキシの使用を構成できなくなります。</string>\n      <string id=\"EnableWindowsPackageManagerMcpServer\">Windows パッケージ マネージャーの MCP サーバーを有効にする</string>\n      <string id=\"EnableWindowsPackageManagerMcpServerExplanation\">\n        このポリシーでは、Windows パッケージ マネージャー モデル コンテキスト プロトコル (MCP) サーバーを使用できるかどうかを制御します。\n\nこの設定を有効にするか、未構成にした場合、ユーザーはWindows パッケージ マネージャーの MCP サーバーを使用できます。\n\nこの設定を無効にすると、ユーザーはWindows パッケージ マネージャーの MCP サーバーを使用できなくなります。</string>\n      <string id=\"WindowsPackageManagerDefaultProxy\">Windows パッケージ マネージャーの既定のプロキシを設定する</string>\n      <string id=\"WindowsPackageManagerDefaultProxyExplanation\">このポリシーは、Windows パッケージ マネージャーで使用される既定のプロキシを制御します。\n\nこの設定を無効にした場合、または構成しなかった場合、既定ではプロキシは使用されません。\n\nこの設定を有効にした場合、指定したプロキシが既定で使用されます。</string>\n      <string id=\"EnableMsixAllowedZones\">MSIX パッケージアプリ インストーラー許可されたゾーンを有効にする</string>\n      <string id=\"EnableMsixAllowedZonesExplanation\">このポリシーでは、アプリ インストーラーが特定の URL ゾーンからのパッケージのインストールを許可するかどうかを制御します。パッケージの配信元は、その URI と、Mart-of-the-Web (MotW) が存在するかどうかによって決まります。複数の URI が含まれている場合、すべてが考慮されます。たとえば、リダイレクトを含む .appinstaller ファイルを使用する場合などです。\n\nこのポリシーを有効にした場合、ユーザーは各ゾーンの構成に従って MSIX パッケージをインストールできます。\n\nこのポリシーを無効にするか、未構成にした場合、ユーザーは信頼されていないゾーン以外のゾーンから MSIX パッケージをインストールできます。</string>\n      <string id=\"ZoneAllowed\">許可</string>\n      <string id=\"ZoneBlocked\">ブロック</string>\n      <string id=\"EnableMsixSmartScreenCheck\">MSIX パッケージの Microsoft SmartScreen チェックを有効にする</string>\n      <string id=\"EnableMsixSmartScreenCheckExplanation\">このポリシーでは、MSIX パッケージのインストール時にアプリ インストーラーが Microsoft SmartScreen チェックを実行するかどうかを制御します。\n\nこのポリシーを有効にするか、未構成にした場合、インストール前にパッケージ URI が Microsoft SmartScreen で評価されます。このチェックは、インターネットからのパッケージに対してのみ実行されます。\n\n無効にした場合、パッケージをインストールする前に Microsoft SmartScreen に問い合わせてください。</string>\n    </stringTable>\n    <presentationTable>\n      <presentation id=\"SourceAutoUpdateInterval\">\n        <decimalTextBox refId=\"SourceAutoUpdateInterval\" defaultValue=\"5\">ソースの自動更新間隔 (分)</decimalTextBox>\n      </presentation>\n      <presentation id=\"AdditionalSources\">\n        <listBox refId=\"AdditionalSources\" required=\"false\">追加ソース: </listBox>\n      </presentation>\n      <presentation id=\"AllowedSources\">\n        <listBox refId=\"AllowedSources\" required=\"false\">許可されたソース: </listBox>\n      </presentation>\n      <presentation id=\"WindowsPackageManagerDefaultProxy\">\n        <textBox refId=\"WindowsPackageManagerDefaultProxy\">\n          <label>既定のプロキシ</label>\n        </textBox>\n      </presentation>\n      <presentation id=\"MsixAllowedZones\">\n        <dropdownList refId=\"LocalMachine\" noSort=\"true\" defaultItem=\"1\">ローカル コンピューター</dropdownList>\n        <dropdownList refId=\"Intranet\" noSort=\"true\" defaultItem=\"1\">イントラネット</dropdownList>\n        <dropdownList refId=\"TrustedSites\" noSort=\"true\" defaultItem=\"1\">信頼済みサイト</dropdownList>\n        <dropdownList refId=\"Internet\" noSort=\"true\" defaultItem=\"1\">インターネット</dropdownList>\n        <dropdownList refId=\"UntrustedSites\" noSort=\"true\" defaultItem=\"0\">信頼できないサイト</dropdownList>\n      </presentation>\n    </presentationTable>\n  </resources>\n</policyDefinitionResources>\n"
  },
  {
    "path": "Localization/Policies/ko-KR/DesktopAppInstaller.adml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (c) Microsoft Corporation.\n     Licensed under the MIT License. -->\n<policyDefinitionResources xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" revision=\"1.0\" schemaVersion=\"1.0\" xmlns=\"http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions\">\n  <displayName>앱 설치 관리자</displayName>\n  <description>앱 설치 관리자</description>\n  <resources>\n    <stringTable>\n      <string id=\"AppInstaller\">데스크톱 앱 설치 관리자</string>\n      <string id=\"EnableAppInstaller\">Windows 패키지 관리자 사용</string>\n      <string id=\"EnableAppInstallerExplanation\">이 정책은 사용자가 Windows 패키지 관리자를 사용할 수 있는지 여부를 제어합니다.\n\n이 설정을 사용하거나 구성하지 않으면 사용자가 Windows 패키지 관리자를 사용할 수 있습니다.\n\n이 설정을 사용하지 않으면 사용자가 Windows 패키지 관리자를 사용할 수 없습니다.</string>\n      <string id=\"EnableSettings\">Windows 패키지 관리자 설정 사용</string>\n      <string id=\"EnableSettingsExplanation\">이 정책은 사용자가 설정을 변경할 수 있는지 여부를 제어합니다.\n\n이 설정을 사용하도록 설정하거나 구성하지 않으면 사용자가 Windows 패키지 관리자의 설정을 변경할 수 있습니다.\n\n이 설정을 사용하지 않으면 사용자가 Windows 패키지 관리자의 설정을 변경할 수 없습니다.</string>\n      <string id=\"EnableExperimentalFeatures\">Windows 패키지 관리자 실험적 기능 사용</string>\n      <string id=\"EnableExperimentalFeaturesExplanation\">이 정책은 사용자가 Windows 패키지 관리자에서 실험적인 기능을 사용하도록 설정할 수 있는지 여부를 제어합니다.\n\n이 설정을 사용하거나 구성하지 않으면 사용자가 Windows 패키지 관리자를 위해 실험적 기능을 사용할 수 있습니다.\n\n이 설정을 사용하지 않도록 설정하면 사용자가 Windows 패키지 관리자를 위해 실험적 기능을 사용할 수 없습니다.</string>\n      <string id=\"EnableLocalManifestFiles\">Windows 패키지 관리자 로컬 매니페스트 파일 사용</string>\n      <string id=\"EnableLocalManifestFilesExplanation\">이 정책은 사용자가 로컬 매니페스트 파일을 사용하여 패키지를 설치할 수 있는지 여부를 제어합니다.\n\n이 설정을 사용하거나 구성하지 않으면 사용자는 Windows 패키지 관리자를 사용하여 로컬 매니페스트와 함께 패키지를 설치할 수 있습니다.\n\n이 설정을 사용하지 않으면 사용자는 Windows 패키지 관리자를 사용하여 로컬 매니페스트를 통해 패키지를 설치할 수 없습니다.</string>\n      <string id=\"EnableBypassCertificatePinningForMicrosoftStore\">Windows 패키지 관리자 Microsoft Store 원본 인증서 유효성 검사 바이패스 사용</string>\n      <string id=\"EnableBypassCertificatePinningForMicrosoftStoreExplanation\">이 정책은 Windows 패키지 관리자가 Microsoft 저장소 원본에 대한 연결을 시작할 때 알려진 Microsoft Store 인증서와 일치하는 Microsoft 저장소 인증서 해시의 유효성을 검사할지 여부를 제어합니다. \n이 정책을 사용하면 Windows 패키지 관리자는 Microsoft 저장소 인증서 유효성 검사를 무시합니다. \n\n이 정책을 사용하지 않으면 Windows 패키지 관리자는 Microsoft Store 원본과 통신하기 전에 사용된 Microsoft 저장소 인증서가 유효하고 Microsoft 저장소에 속하는지 확인합니다.\n\n이 정책을 구성하지 않으면 Windows 패키지 관리자의 관리자 설정이 적용됩니다.</string>\n      <string id=\"EnableHashOverride\">Windows 패키지 관리자 해시 재정의 사용</string>\n      <string id=\"EnableHashOverrideExplanation\">이 정책은 설정에서 SHA256 보안 유효성 검사를 재정의하도록 Windows 패키지 관리자를 구성할 수 있는지 여부를 제어합니다.\n\n이 정책을 실행하거나 구성하지 않으면 Windows 패키지 관리자 설정에서 SHA256 보안 유효성 검사를 재정의하는 기능을 사용할 수 있습니다.\n\n이 정책을 실행 중지하면 Windows 패키지 관리자 설정에서 SHA256 보안 유효성 검사를 재정의하는 기능을 사용자가 사용하도록 설정할 수 없습니다.</string>\n      <string id=\"EnableLocalArchiveMalwareScanOverride\">Windows 패키지 관리자 로컬 보관 맬웨어 검사 재정의 사용</string>\n      <string id=\"EnableLocalArchiveMalwareScanOverrideExplanation\">이 정책은 명령줄 인수를 사용하여 로컬 매니페스트를 사용하여 보관 파일을 설치할 때 맬웨어 취약성 검사를 재정의하는 기능을 제어합니다.\n이 정책을 사용하면 사용자가 보관 파일의 로컬 매니페스트 설치를 수행할 때 맬웨어 검사를 재정의할 수 있습니다.\n\n이 정책을 사용하지 않으면 로컬 매니페스트를 사용하여 설치할 때 사용자가 보관 파일의 맬웨어 검사를 재정의할 수 없습니다.\n\n이 정책을 구성하지 않으면 Windows 패키지 관리자 관리자 설정이 적용됩니다.</string>\n      <string id=\"EnableDefaultSource\">Windows 패키지 관리자 기본 원본 사용</string>\n      <string id=\"EnableDefaultSourceExplanation\">이 정책은 Windows 패키지 관리자에 포함된 기본 원본을 제어합니다.\n\n이 설정을 구성하지 않는 경우 Windows 패키지 관리자의 기본 원본을 사용할 수 있으며 제거할 수 있습니다.\n\n이 설정을 사용하면 Windows 패키지 관리자의 기본 원본을 사용할 수 있으며 제거할 수 없습니다.\n\n이 설정을 사용하지 않도록 설정하면 Windows 패키지 관리자의 기본 원본을 사용할 수 없습니다.</string>\n      <string id=\"EnableMicrosoftStoreSource\">Windows 패키지 관리자 Microsoft Store 원본 사용</string>\n      <string id=\"EnableMicrosoftStoreSourceExplanation\">이 정책은 Windows 패키지 관리자에 포함된 Microsoft 스토어 원본을 제어합니다.\n\n이 설정을 구성하지 않는 경우 Windows 패키지 관리자의 Microsoft 스토어 원본을 사용할 수 있으며 제거할 수 있습니다.\n\n이 설정을 사용하면 Windows 패키지 관리자용 Microsoft 스토어 원본을 사용할 수 있으며 제거할 수 없습니다.\n\n이 설정을 사용 중지하면 Windows 패키지 관리자용 Microsoft 스토어 원본을 사용할 수 없습니다.</string>\n      <string id=\"EnableFontSource\">Windows 패키지 관리자 글꼴 원본 활성화</string>\n      <string id=\"EnableFontSourceExplanation\">\n        이 정책은 Windows 패키지 관리자에 포함된 글꼴 원본을 제어합니다.\n\n        이 설정을 구성하지 않는 경우 Windows 패키지 관리자의 글꼴 원본을 사용할 수 있으며 제거할 수 있습니다.\n\n        이 설정을 사용하면 Windows 패키지 관리자용 글꼴 원본을 사용할 수 있으며 제거할 수 없습니다.\n\n        이 설정을 사용 중지하면 Windows 패키지 관리자용 글꼴 원본을 사용할 수 없습니다.\n      </string>\n      <string id=\"SourceAutoUpdateInterval\">Windows 패키지 관리자 원본 자동 업데이트 간격(분) 설정</string>\n      <string id=\"SourceAutoUpdateIntervalExplanation\">이 정책은 패키지 기반 원본의 자동 업데이트 간격을 제어합니다. 패키지의 인덱스가 로컬 컴퓨터에 캐시되도록 Windows 패키지 관리자 기본 원본이 구성됩니다. 사용자가 명령을 호출하고 간격이 지나면 인덱스가 다운로드됩니다.\n\n이 설정을 사용하지 않거나 구성하지 않으면 Windows 패키지 관리자 설정에 지정된 기본 간격 또는 값이 사용됩니다.\n\n이 설정을 사용하면 지정한 시간(분)이 Windows 패키지 관리자 사용됩니다.</string>\n      <string id=\"EnableAdditionalSources\">Windows 패키지 관리자 추가 원본 사용</string>\n      <string id=\"EnableAdditionalSourcesExplanation\">이 정책은 엔터프라이즈 IT 관리자가 제공하는 추가 원본을 제어합니다.\n\n정책을 구성하지 않는 경우 Windows 패키지 관리자에 대해 추가 원본이 구성되지 않습니다.\n\n정책을 사용하도록 설정하면 추가 원본이 Windows 패키지 관리자에 추가되고 제거할 수 없습니다. 'winget 원본 내보내기'를 사용하여 설치된 원본에서 각 추가 원본에 대한 표현을 얻을 수 있습니다.\n\n이 정책을 사용하지 않도록 설정하는 경우 Windows 패키지 관리자에 대해 추가 원본을 구성할 수 없습니다.</string>\n      <string id=\"EnableAllowedSources\">Windows 패키지 관리자 허용된 원본 사용</string>\n      <string id=\"EnableAllowedSourcesExplanation\">이 정책은 엔터프라이즈 IT 관리자가 허용하는 추가 원본을 제어합니다.\n\n이 정책을 구성하지 않는 경우 사용자는 정책에 의해 구성된 원본 외의 다른 원본을 추가하거나 제거할 수 있습니다.\n\n정책을 사용하도록 설정하는 경우 지정된 원본만 Windows 패키지 관리자에서 추가하거나 제거할 수 있습니다. 허용된 각 원본에 대한 표현은 'winget 원본 내보내기'를 사용하여 설치된 원본에서 구할 수 있습니다.\n\n이 정책을 사용하지 않도록 설정하는 경우 Windows 패키지 관리자에 대해 추가 원본을 구성할 수 없습니다.</string>\n      <string id=\"EnableMSAppInstallerProtocol\">앱 설치 관리자 ms-appinstaller 프로토콜 사용</string>\n      <string id=\"EnableMSAppInstallerProtocolExplanation\">이 정책은 사용자가 ms-appinstaller 프로토콜을 사용하는 웹 사이트에서 패키지를 설치할 수 있는지 여부를 제어합니다.\n\n이 설정을 사용하면 사용자가 이 프로토콜을 사용하는 웹 사이트의 패키지를 설치할 수 있습니다.\n\n이 설정을 사용하지 않거나 구성하지 않으면 사용자가 이 프로토콜을 사용하는 웹 사이트의 패키지를 설치할 수 없습니다.</string>\n      <string id=\"EnableWindowsPackageManagerCommandLineInterfaces\">Windows 패키지 관리자 명령줄 인터페이스 활성화</string>\n      <string id=\"EnableWindowsPackageManagerCommandLineInterfacesExplanation\">이 정책은 사용자가 명령줄 인터페이스(WinGet CLI 또는 WinGet PowerShell)를 통해 Windows 패키지 관리자를 사용하여 작업을 수행할 수 있는지 여부를 결정합니다.\n\n        이 정책을 사용하지 않도록 설정하면 사용자는 Windows 패키지 관리자 CLI 및 PowerShell cmdlet을 실행할 수 없습니다.\n\n        이 정책을 사용하도록 설정하거나 구성하지 않을 경우 사용자는 Windows 패키지 관리자 CLI 명령 및 PowerShell cmdlet을 실행할 수 없습니다. (제공된 “앱 설치 관리자 사용” 정책을 사용하지 않도록 설정할 수 없습니다.)\n\n        이 정책은 “앱 설치 관리자 사용” 정책을 재정의하지 않습니다.</string>\n      <string id=\"EnableWindowsPackageManagerConfiguration\">Windows 패키지 관리자 구성 사용</string>\n      <string id=\"EnableWindowsPackageManagerConfigurationExplanation\">이 정책은 사용자가 Windows 패키지 관리자 구성 기능을 사용할 수 있는지 여부를 제어합니다.\n\n이 설정을 사용하거나 구성하지 않으면 사용자가 Windows 패키지 관리자 구성 기능을 사용할 수 있습니다.\n\n이 설정을 사용하지 않으면 사용자가 Windows 패키지 관리자 구성 기능을 사용할 수 없습니다.</string>\n      <string id=\"EnableWindowsPackageManagerProxyCommandLineOptions\">프록시 Windows 패키지 관리자 명령줄 옵션 사용</string>\n      <string id=\"EnableWindowsPackageManagerProxyCommandLineOptionsExplanation\">\n        이 정책은 명령줄을 통해 사용자가 프록시의 Windows 패키지 관리자 사용을 구성할 수 있는지 여부를 제어합니다.\n\n이 설정을 사용하면 사용자가 명령줄을 통해 Windows 패키지 관리자 프록시 사용을 구성할 수 있습니다.\n\n이 설정을 사용하지 않거나 구성하지 않으면 사용자가 명령줄을 통해 Windows 패키지 관리자 프록시 사용을 구성할 수 없습니다.</string>\n      <string id=\"EnableWindowsPackageManagerMcpServer\">Windows 패키지 관리자용 MCP 서버 활성화</string>\n      <string id=\"EnableWindowsPackageManagerMcpServerExplanation\">\n        이 정책은 MCP(Windows 패키지 관리자 모델 컨텍스트 프로토콜) 서버를 사용할 수 있는지 여부를 제어합니다.\n\n이 설정을 사용하거나 구성하지 않으면 사용자가 Windows 패키지 관리자 MCP 서버를 사용할 수 있습니다.\n\n이 설정을 사용하지 않으면 사용자가 Windows 패키지 관리자 MCP 서버를 사용할 수 없습니다.</string>\n      <string id=\"WindowsPackageManagerDefaultProxy\">Windows 패키지 관리자 기본 프록시 설정</string>\n      <string id=\"WindowsPackageManagerDefaultProxyExplanation\">이 정책은 Windows 패키지 관리자 사용하는 기본 프록시를 제어합니다.\n\n이 설정을 사용하지 않거나 구성하지 않으면 기본적으로 프록시가 사용되지 않습니다.\n\n이 설정을 사용하면 지정된 프록시가 기본적으로 사용됩니다.</string>\n      <string id=\"EnableMsixAllowedZones\">MSIX 패키지에 대해 앱 설치 관리자 허용된 영역 사용</string>\n      <string id=\"EnableMsixAllowedZonesExplanation\">이 정책은 앱 설치 관리자 특정 URL 영역에서 시작되는 패키지를 설치할 수 있는지 여부를 제어합니다. 패키지의 원본은 해당 URI에 따라 결정되며 MotW(Mart-of-the-Web)가 있는지 여부를 결정합니다. 여러 URI가 관련된 경우 모두 고려됩니다. 예를 들어 리디렉션과 관련된 .appinstaller 파일을 사용하는 경우\n\n이 정책을 사용하면 사용자가 각 영역의 구성에 따라 MSIX 패키지를 설치할 수 있습니다.\n\n이 정책을 사용하지 않거나 구성하지 않으면 신뢰할 수 없음을 제외한 모든 영역에서 MSIX 패키지를 설치할 수 있습니다.</string>\n      <string id=\"ZoneAllowed\">허용</string>\n      <string id=\"ZoneBlocked\">차단</string>\n      <string id=\"EnableMsixSmartScreenCheck\">MSIX 패키지에 Microsoft SmartScreen 검사 사용</string>\n      <string id=\"EnableMsixSmartScreenCheckExplanation\">이 정책은 MSIX 패키지를 설치할 때 앱 설치 관리자 Microsoft SmartScreen 검사를 수행할지 여부를 제어합니다.\n\n이 정책을 사용하거나 구성하지 않으면 설치 전에 Microsoft SmartScreen을 사용하여 패키지 URI가 평가됩니다. 이 검사 인터넷에서 가져온 패키지에 대해서만 수행됩니다.\n\n사용하지 않도록 설정하면 패키지를 설치하기 전에 Microsoft SmartScreen을 참조하지 않습니다.</string>\n    </stringTable>\n    <presentationTable>\n      <presentation id=\"SourceAutoUpdateInterval\">\n        <decimalTextBox refId=\"SourceAutoUpdateInterval\" defaultValue=\"5\">원본 자동 업데이트 간격(분)</decimalTextBox>\n      </presentation>\n      <presentation id=\"AdditionalSources\">\n        <listBox refId=\"AdditionalSources\" required=\"false\">추가 원본: </listBox>\n      </presentation>\n      <presentation id=\"AllowedSources\">\n        <listBox refId=\"AllowedSources\" required=\"false\">허용된 원본: </listBox>\n      </presentation>\n      <presentation id=\"WindowsPackageManagerDefaultProxy\">\n        <textBox refId=\"WindowsPackageManagerDefaultProxy\">\n          <label>기본 프록시</label>\n        </textBox>\n      </presentation>\n      <presentation id=\"MsixAllowedZones\">\n        <dropdownList refId=\"LocalMachine\" noSort=\"true\" defaultItem=\"1\">로컬 컴퓨터</dropdownList>\n        <dropdownList refId=\"Intranet\" noSort=\"true\" defaultItem=\"1\">인트라넷</dropdownList>\n        <dropdownList refId=\"TrustedSites\" noSort=\"true\" defaultItem=\"1\">신뢰할 수 있는 사이트</dropdownList>\n        <dropdownList refId=\"Internet\" noSort=\"true\" defaultItem=\"1\">인터넷</dropdownList>\n        <dropdownList refId=\"UntrustedSites\" noSort=\"true\" defaultItem=\"0\">신뢰할 수 없는 사이트</dropdownList>\n      </presentation>\n    </presentationTable>\n  </resources>\n</policyDefinitionResources>\n"
  },
  {
    "path": "Localization/Policies/pt-BR/DesktopAppInstaller.adml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (c) Microsoft Corporation.\n     Licensed under the MIT License. -->\n<policyDefinitionResources xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" revision=\"1.0\" schemaVersion=\"1.0\" xmlns=\"http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions\">\n  <displayName>Instalador de Aplicativo</displayName>\n  <description>Instalador de Aplicativo</description>\n  <resources>\n    <stringTable>\n      <string id=\"AppInstaller\">Instalador de Aplicativos de Área de Trabalho</string>\n      <string id=\"EnableAppInstaller\">Habilitar o Gerenciador de Pacotes do Windows</string>\n      <string id=\"EnableAppInstallerExplanation\">Esta política controla se o Gerenciador de pacotes do Windows pode ser usado por usuários.\n\nSe você habilitar ou não definir essa configuração, os usuários poderão usar o Gerenciador de pacotes do Windows.\n\nSe você desabilitar essa configuração, os usuários não poderão usar o Gerenciador de pacotes do Windows.</string>\n      <string id=\"EnableSettings\">Habilitar as Configurações do Gerenciador de Pacotes do Windows</string>\n      <string id=\"EnableSettingsExplanation\">Esta política controla se os usuários podem alterar suas configurações.\n\nSe você habilitar ou não definir essa configuração, os usuários poderão alterar as configurações do Gerenciador de pacotes do Windows.\n\nSe você desabilitar essa configuração, os usuários não poderão alterar configurações para o Gerenciador de pacotes do Windows.</string>\n      <string id=\"EnableExperimentalFeatures\">Habilitar Recursos Experimentais do Gerenciador de Pacotes do Windows</string>\n      <string id=\"EnableExperimentalFeaturesExplanation\">Essa política controla se os usuários podem habilitar recursos experimentais no Gerenciador de pacotes do Windows.\n\nSe você habilitar ou não definir essa configuração, os usuários poderão habilitar recursos experimentais para o Gerenciador de pacotes do Windows.\n\nSe você desabilitar essa configuração, os usuários não poderão habilitar os recursos experimentais do Gerenciador de pacotes do Windows.</string>\n      <string id=\"EnableLocalManifestFiles\">Habilitar Arquivos de Manifesto Local do Gerenciador de Pacotes do Windows</string>\n      <string id=\"EnableLocalManifestFilesExplanation\">Essa política controla se os usuários podem instalar pacotes com arquivos de manifesto locais.\n\nSe você habilitar ou não definir essa configuração, os usuários poderão instalar pacotes com manifestos locais usando o Gerenciador de pacotes do Windows.\n\nSe você desabilitar essa configuração, os usuários não poderão instalar pacotes com manifestos locais usando o Gerenciador de pacotes do Windows.</string>\n      <string id=\"EnableBypassCertificatePinningForMicrosoftStore\">Habilitar Bypass Gerenciador de Pacotes do Windows Microsoft Store Certificado de Origem</string>\n      <string id=\"EnableBypassCertificatePinningForMicrosoftStoreExplanation\">Essa política controla se o Gerenciador de Pacotes do Windows validará se o hash do certificado Microsoft Store corresponde a um certificado Microsoft Store conhecido ao iniciar uma conexão com a Origem da Microsoft Store. \nSe você habilitar essa política, o Gerenciador de Pacotes do Windows ignorará a validação do certificado da Microsoft Store. \n\nSe você desabilitar essa política, o Gerenciador de Pacotes do Windows validará se o certificado Microsoft Store usado é válido e pertence ao Microsoft Store antes de se comunicar com a origem da Microsoft Store.\n\nSe você não definir essa política, as configurações de administrador do Gerenciador de Pacotes do Windows serão aderidas.</string>\n      <string id=\"EnableHashOverride\">Habilitar a Substituição de Hash do Gerenciador de Pacotes do Windows</string>\n      <string id=\"EnableHashOverrideExplanation\">Esta política controla se o Gerenciador de Pacotes do Windows pode ou não ser configurado para permitir a capacidade de substituição da validação de segurança SHA256 nas configurações.\n\nSe você habilitar ou não configurar esta política, os usuários poderão habilitar a capacidade de substituição da validação de segurança SHA256 nas configurações do Gerenciador de Pacotes do Windows.\n\nSe você desabilitar esta política, os usuários não poderão habilitar a capacidade de substituição da validação de segurança SHA256 nas configurações do Gerenciador de Pacotes do Windows.</string>\n      <string id=\"EnableLocalArchiveMalwareScanOverride\">Habilitar Gerenciador de Pacotes do Windows Verificação de Malware de Arquivo Morto Local</string>\n      <string id=\"EnableLocalArchiveMalwareScanOverrideExplanation\">Esta política controla a capacidade de substituir verificações de vulnerabilidade de malware ao instalar um arquivo morto usando um manifesto local usando os argumentos de linha de comando.\nSe você habilitar essa política, os usuários poderão substituir a verificação de malware ao executar uma instalação de manifesto local de um arquivo morto.\n\nSe você desabilitar essa política, os usuários não poderão substituir a verificação de malware de um arquivo morto durante a instalação usando um manifesto local.\n\nSe você não configurar essa política, as configurações Gerenciador de Pacotes do Windows administrador serão aderidas.</string>\n      <string id=\"EnableDefaultSource\">Habilitar a Fonte Padrão do Gerenciador de Pacotes do Windows</string>\n      <string id=\"EnableDefaultSourceExplanation\">Esta política controla a fonte padrão incluída no Gerenciador de Pacotes do Windows.\n\nSe você não definir essa configuração, a fonte padrão do Gerenciador de Pacotes do Windows estará disponível e poderá ser removida.\n\nSe você habilitar essa configuração, a fonte padrão para o Gerenciador de Pacotes do Windows estará disponível e não poderá ser removida.\n\nSe você desabilitar esta configuração, a fonte padrão para o Gerenciador de Pacotes do Windows não estará disponível.</string>\n      <string id=\"EnableMicrosoftStoreSource\">Habilitar a Fonte da Microsoft Store do Gerenciador de Pacotes do Windows</string>\n      <string id=\"EnableMicrosoftStoreSourceExplanation\">Esta política controla a fonte da Microsoft Store incluída com o Gerenciador de Pacotes do Windows.\n\nSe você não definir essa configuração, a fonte da Microsoft Store para o Gerenciador do Pacote Windows estará disponível e poderá ser removida.\n\nSe você habilitar essa configuração, a fonte da Microsoft Store para o Gerenciador de Pacotes do Windows estará disponível e não poderá ser removida.\n\nSe você desabilitar esta configuração, a fonte da Microsoft Store para o Gerenciador de Pacotes do Windows não estará disponível.</string>\n      <string id=\"EnableFontSource\">Habilitar origem da fonte do Gerenciador de pacotes do Windows</string>\n      <string id=\"EnableFontSourceExplanation\">\n        Essa política controla a origem da fonte incluída no Gerenciador de pacotes do Windows.\n\n        Se você não definir essa configuração, a origem da fonte do Gerenciador de pacotes do Windows ficará disponível e poderá ser removida.\n\n        Se você habilitar essa configuração, a origem da fonte do Gerenciador de pacotes do Windows ficará disponível e não poderá ser removida.\n\n        Se você desabilitar essa configuração, a origem da fonte do Gerenciador de pacotes do Windows não ficará disponível.\n      </string>\n      <string id=\"SourceAutoUpdateInterval\">Definir o Intervalo de Atualização Automática da Fonte do Gerenciador de Pacotes do Windows em Minutos</string>\n      <string id=\"SourceAutoUpdateIntervalExplanation\">Esta política controla o intervalo de atualização automática para origens baseadas em pacote. A fonte padrão para Gerenciador de Pacotes do Windows é configurada de modo que um índice dos pacotes seja armazenado em cache no computador local. O índice é baixado quando um usuário invoca um comando e o intervalo é passado.\n\nSe você desabilitar ou não definir essa configuração, o intervalo padrão ou o valor especificado na Gerenciador de Pacotes do Windows configurações serão usadas.\n\nSe você habilitar essa configuração, o número de minutos especificado será usado pelo Gerenciador de Pacotes do Windows.</string>\n      <string id=\"EnableAdditionalSources\">Habilitar Fontes Adicionais do Gerenciador de Pacotes do Windows</string>\n      <string id=\"EnableAdditionalSourcesExplanation\">Esta política controla as fontes adicionais fornecidas pelo administrador de TI da empresa.\n\nSe você não configurar esta política, nenhuma fonte adicional será configurada para o Gerenciador de Pacotes do Windows.\n\nSe você habilitar essa política, as fontes adicionais serão adicionadas ao Gerenciador de Pacotes do Windows e não poderão ser removidas. A representação de cada fonte adicional poderá ser obtida a partir das fontes instaladas usando a 'exportação de fonte de winget'.\n\nSe você desabilitar esta política, nenhuma fonte adicional poderá ser configurada para o Gerenciador de Pacotes do Windows.</string>\n      <string id=\"EnableAllowedSources\">Habilitar Fontes Permitidas do Gerenciador de Pacotes do Windows</string>\n      <string id=\"EnableAllowedSourcesExplanation\">Esta política controla as fontes adicionais permitidas pelo administrador de TI da empresa.\n\nSe você não configurar esta política, os usuários poderão adicionar ou remover fontes adicionais além daquelas configuradas pela política.\n\nSe você habilitar essa política, apenas as fontes especificadas poderão ser adicionadas ou removidas do Gerenciador de Pacotes do Windows. A representação de cada fonte permitida pode ser obtida a partir das fontes instaladas usando a 'exportação de fonte de winget'.\n\nSe você desabilitar esta política, nenhuma fonte adicional poderá ser configurada para o Gerenciador de Pacotes do Windows.</string>\n      <string id=\"EnableMSAppInstallerProtocol\">Ativar o protocolo ms-appinstaller do Instalador de Aplicativo</string>\n      <string id=\"EnableMSAppInstallerProtocolExplanation\">Esta política controla se os usuários podem instalar pacotes de um site que esteja usando o protocolo ms-appinstaller.\n\nSe você habilitar essa configuração, os usuários poderão instalar pacotes de sites que usam esse protocolo.\n\nSe você desabilitar ou não definir essa configuração, os usuários não poderão instalar pacotes de sites que usam esse protocolo.</string>\n      <string id=\"EnableWindowsPackageManagerCommandLineInterfaces\">Habilitar interfaces de linha de comando do Gerenciador de Pacotes do Windows</string>\n      <string id=\"EnableWindowsPackageManagerCommandLineInterfacesExplanation\">Essa política determina se um usuário pode executar uma ação usando o Gerenciador de Pacotes do Windows por meio de uma interface de linha de comando (CLI do WinGet ou WinGet PowerShell).\n\n        Se você desabilitar essa política, os usuários não poderão executar a CLI do Gerenciador de Pacotes do Windows e os cmdlets do PowerShell.\n\n        Se você habilitar ou não configurar essa política, os usuários poderão executar os comandos CLI do Gerenciador de Pacotes do Windows e os cmdlets do PowerShell. (A política “Habilitar Instalador de Aplicativo” fornecida não está desabilitada).\n\n        Essa política não substitui a política \"Habilitar Instalador de Aplicativo\".</string>\n      <string id=\"EnableWindowsPackageManagerConfiguration\">Habilitar as Configurações do Gerenciador de Pacotes do Windows</string>\n      <string id=\"EnableWindowsPackageManagerConfigurationExplanation\">Esta política controla se o Gerenciador de Pacotes do Windows de configuração pode ser usado pelos usuários.\n\nSe você habilitar ou não definir essa configuração, os usuários poderão usar o recurso Gerenciador de Pacotes do Windows configuração.\n\nSe você desabilitar essa configuração, os usuários não poderão usar o recurso Gerenciador de Pacotes do Windows configuração.</string>\n      <string id=\"EnableWindowsPackageManagerProxyCommandLineOptions\">Habilitar Gerenciador de Pacotes do Windows de linha de comando proxy</string>\n      <string id=\"EnableWindowsPackageManagerProxyCommandLineOptionsExplanation\">\n        Esta política controla se o uso Gerenciador de Pacotes do Windows proxy pode ser configurado pelos usuários por meio da linha de comando.\n\nSe você habilitar essa configuração, os usuários poderão configurar o Gerenciador de Pacotes do Windows do proxy por meio da linha de comando.\n\nSe você desabilitar ou não definir essa configuração, os usuários não poderão configurar o uso Gerenciador de Pacotes do Windows do proxy por meio da linha de comando.</string>\n      <string id=\"EnableWindowsPackageManagerMcpServer\">Habilitar o servidor MCP para o Gerenciador de pacotes do Windows</string>\n      <string id=\"EnableWindowsPackageManagerMcpServerExplanation\">\n        Esta política controla se o servidor Gerenciador de Pacotes do Windows MCP (Protocolo de Contexto de Modelo) pode ser usado.\n\nSe você habilitar ou não definir essa configuração, os usuários poderão usar o Gerenciador de Pacotes do Windows MCP do servidor.\n\nSe você desabilitar essa configuração, os usuários não poderão usar o Gerenciador de Pacotes do Windows MCP do servidor.</string>\n      <string id=\"WindowsPackageManagerDefaultProxy\">Definir Proxy Padrão do Gerenciador de Pacotes do Windows</string>\n      <string id=\"WindowsPackageManagerDefaultProxyExplanation\">Esta política controla o proxy padrão usado pelo Gerenciador de Pacotes do Windows.\n\nSe você desabilitar ou não definir essa configuração, nenhum proxy será usado por padrão.\n\nSe você habilitar essa configuração, o proxy especificado será usado por padrão.</string>\n      <string id=\"EnableMsixAllowedZones\">Habilitar Zonas Permitidas do Instalador de Aplicativo para Pacotes MSIX</string>\n      <string id=\"EnableMsixAllowedZonesExplanation\">Esta política controla se Instalador de Aplicativo permite a instalação de pacotes originados de Zonas de URL específicas. A origem de um pacote é determinada por seu URI e se um Mart-of-the-Web (MotW) está presente. Se vários URIs forem envolvidos, todos eles serão considerados; por exemplo, ao usar um arquivo .appinstaller que envolve redirecionamento.\n\nSe você habilitar essa política, os usuários poderão instalar pacotes MSIX de acordo com a configuração de cada zona.\n\nSe você desabilitar ou não configurar esta política, os usuários poderão instalar pacotes MSIX de qualquer zona, exceto por Não Confiável.</string>\n      <string id=\"ZoneAllowed\">Permitir</string>\n      <string id=\"ZoneBlocked\">Bloquear</string>\n      <string id=\"EnableMsixSmartScreenCheck\">Habilitar verificações do Microsoft SmartScreen para Pacotes MSIX</string>\n      <string id=\"EnableMsixSmartScreenCheckExplanation\">Esta política controla se Instalador de Aplicativo verificações do Microsoft SmartScreen ao instalar pacotes MSIX.\n\nSe você habilitar ou não configurar essa política, o URI do pacote será avaliado com o Microsoft SmartScreen antes da instalação. Este marcar é feito somente para pacotes provenientes da Internet.\n\nSe você desabilitar, o Microsoft SmartScreen não será consultado antes de instalar um pacote.</string>\n    </stringTable>\n    <presentationTable>\n      <presentation id=\"SourceAutoUpdateInterval\">\n        <decimalTextBox refId=\"SourceAutoUpdateInterval\" defaultValue=\"5\">Intervalo de atualização automática da fonte em minutos</decimalTextBox>\n      </presentation>\n      <presentation id=\"AdditionalSources\">\n        <listBox refId=\"AdditionalSources\" required=\"false\">Fontes Adicionais: </listBox>\n      </presentation>\n      <presentation id=\"AllowedSources\">\n        <listBox refId=\"AllowedSources\" required=\"false\">Fontes Permitidas: </listBox>\n      </presentation>\n      <presentation id=\"WindowsPackageManagerDefaultProxy\">\n        <textBox refId=\"WindowsPackageManagerDefaultProxy\">\n          <label>Proxy Padrão</label>\n        </textBox>\n      </presentation>\n      <presentation id=\"MsixAllowedZones\">\n        <dropdownList refId=\"LocalMachine\" noSort=\"true\" defaultItem=\"1\">Computador Local</dropdownList>\n        <dropdownList refId=\"Intranet\" noSort=\"true\" defaultItem=\"1\">Intranet</dropdownList>\n        <dropdownList refId=\"TrustedSites\" noSort=\"true\" defaultItem=\"1\">Sites Confiáveis</dropdownList>\n        <dropdownList refId=\"Internet\" noSort=\"true\" defaultItem=\"1\">Internet</dropdownList>\n        <dropdownList refId=\"UntrustedSites\" noSort=\"true\" defaultItem=\"0\">Sites Não Confiáveis</dropdownList>\n      </presentation>\n    </presentationTable>\n  </resources>\n</policyDefinitionResources>\n"
  },
  {
    "path": "Localization/Policies/ru-RU/DesktopAppInstaller.adml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (c) Microsoft Corporation.\n     Licensed under the MIT License. -->\n<policyDefinitionResources xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" revision=\"1.0\" schemaVersion=\"1.0\" xmlns=\"http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions\">\n  <displayName>Установщик приложений</displayName>\n  <description>Установщик приложений</description>\n  <resources>\n    <stringTable>\n      <string id=\"AppInstaller\">Установщик классических приложений</string>\n      <string id=\"EnableAppInstaller\">Включить Диспетчер пакетов Windows</string>\n      <string id=\"EnableAppInstallerExplanation\">Эта политика определяет, могут ли пользователи использовать Диспетчер пакетов Windows.\n\nЕсли включить или не настроить этот параметр, пользователи смогут использовать Диспетчер пакетов Windows.\n\nЕсли отключить этот параметр, пользователи не смогут использовать Диспетчер пакетов Windows.</string>\n      <string id=\"EnableSettings\">Включить параметры Диспетчера пакетов Windows</string>\n      <string id=\"EnableSettingsExplanation\">Эта политика определяет, могут ли пользователи изменять свои параметры.\n\nЕсли включить или не настроить этот параметр, пользователи смогут изменять параметры Диспетчера пакетов Windows.\n\nЕсли отключить этот параметр, пользователи не смогут изменять параметры Диспетчера пакетов Windows.</string>\n      <string id=\"EnableExperimentalFeatures\">Включить экспериментальные функции Диспетчера пакетов Windows</string>\n      <string id=\"EnableExperimentalFeaturesExplanation\">Этот параметр политики определяет, могут ли пользователи включать экспериментальные функции в диспетчер пакетов Windows.\n\nЕсли включить или не настроить этот параметр, пользователи смогут включать экспериментальные функции для диспетчер пакетов Windows.\n\nЕсли этот параметр отключен, пользователи не смогут включать экспериментальные функции для диспетчер пакетов Windows.</string>\n      <string id=\"EnableLocalManifestFiles\">Включить файлы локальных манифестов Диспетчера пакетов Windows</string>\n      <string id=\"EnableLocalManifestFilesExplanation\">Эта политика определяет, могут ли пользователи устанавливать пакеты с локальными файлами манифестов.\n\nЕсли включить или не настроить этот параметр, пользователи смогут устанавливать пакеты с локальными манифестами с помощью Диспетчера пакетов Windows.\n\nЕсли отключить этот параметр, пользователи не смогут устанавливать пакеты с локальными манифестами с помощью Диспетчера пакетов Windows.</string>\n      <string id=\"EnableBypassCertificatePinningForMicrosoftStore\">Включить обход проверки сертификата источника Microsoft Store в Диспетчере пакетов Windows</string>\n      <string id=\"EnableBypassCertificatePinningForMicrosoftStoreExplanation\">Эта политика определяет, будет ли Диспетчер пакетов Windows проверять соответствие хэша сертификата Microsoft Store известному сертификату Microsoft Store при инициации подключения к источнику Microsoft Store. \nПри включении этой политики диспетчер пакетов Windows будет обходить проверку сертификата Microsoft Store. \n\nПри отключении этой политики диспетчер пакетов Windows будет проверять принадлежность используемого сертификата Microsoft Store и его действительность, прежде чем связываться с источником Microsoft Store..\n\nЕсли эта политика не настроена, будут соблюдаться параметры администратора диспетчера пакетов Windows.</string>\n      <string id=\"EnableHashOverride\">Включить переопределение хэша Диспетчера пакетов Windows</string>\n      <string id=\"EnableHashOverrideExplanation\">Этот параметр политики определяет, можно ли настроить Диспетчер пакетов Windows, чтобы включить возможность переопределения параметров проверки безопасности SHA256 в настройках.\n\nЕсли данный параметр политики включен или не настроен, пользователи получат возможность переопределять проверку безопасности SHA256 в параметрах Диспетчера пакетов Windows.\n\nЕсли данный параметр политики отключен, пользователи не смогут переопределять проверку безопасности SHA256 в параметрах Диспетчера пакетов Windows.</string>\n      <string id=\"EnableLocalArchiveMalwareScanOverride\">Включить переопределение сканирования вредоносных программ в локальном архиве Диспетчера пакетов Windows</string>\n      <string id=\"EnableLocalArchiveMalwareScanOverrideExplanation\">Эта политика управляет возможностью переопределения сканирования уязвимостей вредоносных программ при установке файла архива с использованием локального манифеста с использованием аргументов командной строки.\nПри включении этой политики пользователи смогут переопределять сканирование вредоносных программ при выполнении локальной установки манифеста архивного файла.\n\nПри отключении этой политики пользователи не смогут переопределять сканирование архивного файла на наличие вредоносных программ при установке с использованием локального манифеста.\n\nЕсли эта политика не настроена, будут соблюдаться параметры администратора диспетчера пакетов Windows.</string>\n      <string id=\"EnableDefaultSource\">Включить источник по умолчанию для Диспетчера пакетов Windows</string>\n      <string id=\"EnableDefaultSourceExplanation\">Эта политика управляет источником по умолчанию, входящим в состав Диспетчера пакетов Windows.\n\nЕсли не задать этот параметр, источник по умолчанию для Диспетчера пакетов Windows будет доступен, и его можно будет удалить.\n\nЕсли включить этот параметр, источник по умолчанию для Диспетчера пакетов Windows будет доступен, и его нельзя будет удалить.\n\nЕсли отключить этот параметр, источник по умолчанию для Диспетчера пакетов Windows будет недоступен.</string>\n      <string id=\"EnableMicrosoftStoreSource\">Включить источник Microsoft Store в Диспетчере пакетов Windows</string>\n      <string id=\"EnableMicrosoftStoreSourceExplanation\">Эта политика управляет источником Microsoft Store, входящим в состав Диспетчера пакетов Windows.\n\nЕсли не задать этот параметр, источник Microsoft Store для Диспетчера пакетов Windows будет доступен, и его можно будет удалить.\n\nЕсли включить этот параметр, источник Microsoft Store для Диспетчера пакетов Windows будет доступен, и его нельзя будет удалить.\n\nЕсли отключить этот параметр, источник Microsoft Store для Диспетчера пакетов Windows будет недоступен.</string>\n      <string id=\"EnableFontSource\">Включить источник шрифтов для Диспетчера пакетов Windows</string>\n      <string id=\"EnableFontSourceExplanation\">\n        Эта политика управляет источником шрифтов, входящим в состав Диспетчера пакетов Windows.\n\n        Если этот параметр не настроен, источник шрифтов для Диспетчера пакетов Windows будет доступен, и его можно будет удалить.\n\n        Если этот параметр включен, источник шрифтов для Диспетчера пакетов Windows будет доступен, и его нельзя будет удалить.\n\n        Если этот параметр отключен, источник шрифтов для Диспетчера пакетов Windows будет недоступен.\n      </string>\n      <string id=\"SourceAutoUpdateInterval\">Задать интервал автоматического обновления источника Диспетчера пакетов Windows в минутах</string>\n      <string id=\"SourceAutoUpdateIntervalExplanation\">Эта политика управляет интервалом автоматического обновления для источников на основе пакетов. Источник по умолчанию для Диспетчера пакетов Windows настроен таким образом, что индекс пакетов кэшируется на локальном компьютере. Индекс скачивается при вызове команды пользователем и завершении интервала.\n\nЕсли этот параметр отключен или не настроен, будет использоваться интервал по умолчанию или значение, указанное в параметрах Диспетчера пакетов Windows.\n\nЕсли этот параметр включен, указанное число минут будет использоваться Диспетчером пакетов Windows.</string>\n      <string id=\"EnableAdditionalSources\">Включить дополнительные источники Диспетчера пакетов Windows</string>\n      <string id=\"EnableAdditionalSourcesExplanation\">Эта политика управляет дополнительными источниками, предоставленными ИТ-администратором предприятия.\n\nЕсли не настроить эту политику, дополнительные источники для Диспетчера пакетов Windows не будут настроены.\n\nЕсли включить эту политику, дополнительные источники будут добавлены в Диспетчер пакетов Windows, и их нельзя будет удалить. Представление для каждого дополнительного источника можно получить из установленных источников с помощью команды \"winget source export\".\n\nЕсли отключить эту политику, задать дополнительные источники для Диспетчера пакетов Windows будет невозможно.</string>\n      <string id=\"EnableAllowedSources\">Включить разрешенные источники Диспетчера пакетов Windows</string>\n      <string id=\"EnableAllowedSourcesExplanation\">Эта политика управляет дополнительными источниками, разрешенными ИТ-администратором предприятия.\n\nЕсли не настроить эту политику, пользователи смогут добавлять и удалять дополнительные источники помимо заданных в политике.\n\nЕсли включить эту политику, добавлять и удалять из Диспетчера пакетов Windows можно будет только указанные источники,. Представление для каждого разрешенного можно получить из установленных источников с помощью команды \"winget source export\".\n\nЕсли отключить эту политику, задать дополнительные источники для Диспетчера пакетов Windows будет невозможно.</string>\n      <string id=\"EnableMSAppInstallerProtocol\">Включить протокол Установщика приложений ms-appinstaller</string>\n      <string id=\"EnableMSAppInstallerProtocolExplanation\">Эта политика определяет, могут ли пользователи устанавливать пакеты с веб-сайта, который использует протокол ms-appinstaller.\n\nЕсли включить этот, пользователи смогут устанавливать пакеты с веб-сайтов, которые используют этот протокол.\n\nЕсли отключить или не настраивать этот параметр, пользователи не смогут устанавливать пакеты с веб-сайтов, которые используют этот протокол.</string>\n      <string id=\"EnableWindowsPackageManagerCommandLineInterfaces\">Включить интерфейсы командной строки Диспетчера пакетов Windows</string>\n      <string id=\"EnableWindowsPackageManagerCommandLineInterfacesExplanation\">Эта политика определяет, может ли пользователь выполнять действие с помощью диспетчера пакетов Windows через интерфейс командной строки (WinGet CLI или WinGet PowerShell).\n\n        Если вы отключите эту политику, пользователи не смогут выполнять CLI диспетчера пакетов Windows и командлеты PowerShell.\n\n        Если вы включите или не настроите эту политику, пользователи смогут выполнять команды CLI диспетчера пакетов Windows и командлеты PowerShell. (При условии, что политика \"Включить установщик приложений\" не отключена).\n\n        Эта политика не отменяет политику \"Включить установщик приложений\".</string>\n      <string id=\"EnableWindowsPackageManagerConfiguration\">Включить конфигурацию Диспетчера пакетов Windows</string>\n      <string id=\"EnableWindowsPackageManagerConfigurationExplanation\">Эта политика определяет, Диспетчер пакетов Windows ли пользователи могут использовать эту Диспетчер пакетов Windows конфигурацию.\n\nЕсли этот параметр включен или не настроен, пользователи смогут использовать Диспетчер пакетов Windows конфигурации.\n\nЕсли этот параметр отключен, пользователи не смогут использовать Диспетчер пакетов Windows конфигурации.</string>\n      <string id=\"EnableWindowsPackageManagerProxyCommandLineOptions\">Включить Диспетчер пакетов Windows командной строки прокси-сервера</string>\n      <string id=\"EnableWindowsPackageManagerProxyCommandLineOptionsExplanation\">\n        Эта политика определяет, может ли Диспетчер пакетов Windows использование прокси-сервера настраивать пользователи с помощью командной строки.\n\nЕсли этот параметр включен, пользователи смогут Диспетчер пакетов Windows использовать прокси-сервер в командной строке.\n\nЕсли вы отключаете или не настраиваете этот параметр политики, пользователи не смогут Диспетчер пакетов Windows использовать прокси-сервер в командной строке.</string>\n      <string id=\"EnableWindowsPackageManagerMcpServer\">Включить сервер MCP для Диспетчера пакетов Windows</string>\n      <string id=\"EnableWindowsPackageManagerMcpServerExplanation\">\n        Эта политика управляет тем, можно ли использовать сервер протокола контекста модели (MCP) Диспетчера пакетов Windows.\n\n        Если этот параметр включен или не настроен, пользователи смогут применять сервер MCP Диспетчера пакетов Windows.\n\n        Если этот параметр отключен, пользователи не смогут применять сервер MCP Диспетчера пакетов Windows.</string>\n      <string id=\"WindowsPackageManagerDefaultProxy\">Задать прокси по умолчанию для Диспетчера пакетов Windows</string>\n      <string id=\"WindowsPackageManagerDefaultProxyExplanation\">Эта политика управляет прокси-сервером по умолчанию, используемым Диспетчер пакетов Windows.\n\nЕсли этот параметр отключен или не настроен, по умолчанию прокси-сервер не будет использоваться.\n\nЕсли этот параметр включен, указанный прокси-сервер будет использоваться по умолчанию.</string>\n      <string id=\"EnableMsixAllowedZones\">Включить разрешенные зоны Установщика приложений для пакетов MSIX</string>\n      <string id=\"EnableMsixAllowedZonesExplanation\">Эта политика определяет, Установщик приложений ли установка пакетов, полученных из определенных зон URL-адресов. Источник пакета определяется его URI и наличием киоска в Интернете (MotW). Если включено несколько URI, все они считаются; например, при использовании appinstaller-файла, который включает перенаправление.\n\nЕсли эта политика включена, пользователи смогут устанавливать пакеты MSIX в соответствии с конфигурацией для каждой зоны.\n\nЕсли эта политика отключена или не настроена, пользователи смогут устанавливать пакеты MSIX из любой зоны, кроме ненадежных.</string>\n      <string id=\"ZoneAllowed\">Разрешить</string>\n      <string id=\"ZoneBlocked\">Блокировать</string>\n      <string id=\"EnableMsixSmartScreenCheck\">Включить проверки Microsoft SmartScreen для пакетов MSIX</string>\n      <string id=\"EnableMsixSmartScreenCheckExplanation\">Эта политика определяет, Установщик приложений ли фильтр SmartScreen (Майкрософт) при установке пакетов MSIX.\n\nЕсли эта политика включена или не настроена, URI пакета будет проверяться с помощью фильтра SmartScreen (Майкрософт) перед установкой. Эта проверка только для пакетов, поступающих из Интернета.\n\nЕсли отключить этот параметр, microsoft SmartScreen не будет проверяться перед установкой пакета.</string>\n    </stringTable>\n    <presentationTable>\n      <presentation id=\"SourceAutoUpdateInterval\">\n        <decimalTextBox refId=\"SourceAutoUpdateInterval\" defaultValue=\"5\">Интервал автоматического обновления источника в минутах</decimalTextBox>\n      </presentation>\n      <presentation id=\"AdditionalSources\">\n        <listBox refId=\"AdditionalSources\" required=\"false\">Дополнительные источники: </listBox>\n      </presentation>\n      <presentation id=\"AllowedSources\">\n        <listBox refId=\"AllowedSources\" required=\"false\">Разрешенные источники: </listBox>\n      </presentation>\n      <presentation id=\"WindowsPackageManagerDefaultProxy\">\n        <textBox refId=\"WindowsPackageManagerDefaultProxy\">\n          <label>Прокси по умолчанию</label>\n        </textBox>\n      </presentation>\n      <presentation id=\"MsixAllowedZones\">\n        <dropdownList refId=\"LocalMachine\" noSort=\"true\" defaultItem=\"1\">Локальный компьютер</dropdownList>\n        <dropdownList refId=\"Intranet\" noSort=\"true\" defaultItem=\"1\">Интрасеть</dropdownList>\n        <dropdownList refId=\"TrustedSites\" noSort=\"true\" defaultItem=\"1\">Надежные сайты</dropdownList>\n        <dropdownList refId=\"Internet\" noSort=\"true\" defaultItem=\"1\">Интернет</dropdownList>\n        <dropdownList refId=\"UntrustedSites\" noSort=\"true\" defaultItem=\"0\">Ненадежные сайты</dropdownList>\n      </presentation>\n    </presentationTable>\n  </resources>\n</policyDefinitionResources>\n"
  },
  {
    "path": "Localization/Policies/zh-CN/DesktopAppInstaller.adml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (c) Microsoft Corporation.\n     Licensed under the MIT License. -->\n<policyDefinitionResources xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" revision=\"1.0\" schemaVersion=\"1.0\" xmlns=\"http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions\">\n  <displayName>应用安装程序</displayName>\n  <description>应用安装程序</description>\n  <resources>\n    <stringTable>\n      <string id=\"AppInstaller\">桌面应用安装程序</string>\n      <string id=\"EnableAppInstaller\">启用 Windows 程序包管理器</string>\n      <string id=\"EnableAppInstallerExplanation\">此策略控制用户是否可以使用 Windows 程序包管理器。\n\n如果启用或未配置此设置，则用户可以使用 Windows 程序包管理器。\n\n如果禁用此设置，则用户将无法使用 Windows 程序包管理器。</string>\n      <string id=\"EnableSettings\">启用 Windows 程序包管理器设置</string>\n      <string id=\"EnableSettingsExplanation\">此策略控制用户是否可以更改其设置。\n\n如果启用或未配置此设置，则用户可以更改 Windows 程序包管理器的设置。\n\n如果禁用此设置，则用户将无法更改 Windows 程序包管理器的设置。</string>\n      <string id=\"EnableExperimentalFeatures\">启用 Windows 程序包管理器实验性功能</string>\n      <string id=\"EnableExperimentalFeaturesExplanation\">此策略控制用户是否可以在 Windows 程序包管理器中启用实验性功能。\n\n如果启用或未配置此设置，则用户将能够为 Windows 包管理器启用实验性功能。\n\n如果禁用此设置，则用户将无法启用 Windows 包管理器的实验性功能。</string>\n      <string id=\"EnableLocalManifestFiles\">启用 Windows 程序包管理器本地清单文件</string>\n      <string id=\"EnableLocalManifestFilesExplanation\">此策略控制用户是否可以使用本地清单文件安装程序包。\n\n如果启用或未配置此设置，则用户可以使用 Windows 程序包管理器在本地清单中安装包。\n\n如果禁用此设置，则用户将无法使用 Windows 程序包管理器在本地清单中安装包。</string>\n      <string id=\"EnableBypassCertificatePinningForMicrosoftStore\">启用Windows 程序包管理器Microsoft Store源证书验证绕过</string>\n      <string id=\"EnableBypassCertificatePinningForMicrosoftStoreExplanation\">此策略控制 Windows 程序包管理器在发起与 Microsoft Store 源的连接时是否验证 Microsoft Store 证书哈希与已知的 Microsoft Store 证书的匹配情况。\n如果启用此策略，Windows 程序包管理器将绕过 Microsoft Store 证书验证。\n\n如果禁用此策略，则 Windows 程序包管理器在与 Microsoft Store 源通信之前，将验证所使用的 Microsoft Store 证书是否有效且属于 Microsoft Store。\n\n如果未配置此策略，则将遵循 Windows 程序包管理器的管理员设置。</string>\n      <string id=\"EnableHashOverride\">启用 Windows 程序包管理器哈希替代</string>\n      <string id=\"EnableHashOverrideExplanation\">此策略控制是否可以配置 Windows 程序包管理器，以便在设置中启用覆盖 SHA256 安全验证的能力。\n\n如果启用或未配置此策略，则用户将能够在 Windows 程序包管理器设置中启用覆盖 SHA256 安全验证的能力。\n\n如果禁用此策略，则用户将无法在 Windows 程序包管理器设置中启用覆盖 SHA256 安全验证的能力。</string>\n      <string id=\"EnableLocalArchiveMalwareScanOverride\">启用Windows 程序包管理器本地存档恶意软件扫描替代</string>\n      <string id=\"EnableLocalArchiveMalwareScanOverrideExplanation\">此策略控制在使用命令行参数通过本地清单安装存档文件时替代恶意软件漏洞扫描的能力。\n如果启用此策略，则用户可以在对存档文件执行本地清单安装时替代恶意软件扫描。\n\n如果禁用此策略，则在使用本地清单进行安装时，用户将无法替代对存档文件的恶意软件扫描。\n\n如果未配置此策略，则将遵循 Windows 程序包管理器的管理员设置。</string>\n      <string id=\"EnableDefaultSource\">启用 Windows 程序包管理器默认源</string>\n      <string id=\"EnableDefaultSourceExplanation\">此策略控制 Windows 程序包管理器中包含的默认源。\n\n如果未配置此设置，Windows 程序包管理器的默认源将可用并可删除。\n\n如果启用此设置，Windows 程序包管理器的默认源将可用，无法删除。\n\n如果禁用此设置，Windows 程序包管理器的默认源将不可用。</string>\n      <string id=\"EnableMicrosoftStoreSource\">启用 Windows 程序包管理器 Microsoft Store 源</string>\n      <string id=\"EnableMicrosoftStoreSourceExplanation\">此策略控制 Windows 程序包管理器中包含的 Microsoft Store 源。\n\n如果未配置此设置，Windows 程序包管理器的 Microsoft Store 源将可用并可删除。\n\n如果启用此设置，Windows 程序包管理器的 Microsoft Store 源将可用，无法删除。\n\n如果禁用此设置，Windows 程序包管理器的 Microsoft Store 源将不可用。</string>\n      <string id=\"EnableFontSource\">启用 Windows 程序包管理器字体源</string>\n      <string id=\"EnableFontSourceExplanation\">\n        此策略控制 Windows 程序包管理器中包含的字体源。\n\n        如果未配置此设置，则 Windows 程序包管理器的字体源将可用并且可以移除。\n\n        如果启用此设置，则 Windows 程序包管理器的字体源将可用且无法移除。\n\n        如果禁用此设置，则 Windows 程序包管理器的字体源将不可用。\n      </string>\n      <string id=\"SourceAutoUpdateInterval\">设置 Windows 程序包管理器源自动更新间隔(分钟)</string>\n      <string id=\"SourceAutoUpdateIntervalExplanation\">此策略控制基于程序包的源的自动更新间隔。配置Windows 程序包管理器的默认源，以便在本地计算机上缓存包索引。当用户调用命令并且间隔已过时，将下载索引。\n\n如果禁用或未配置此设置，将使用Windows 程序包管理器设置中指定的默认间隔或值。\n\n如果启用此设置，则Windows 程序包管理器将使用指定的分钟数。</string>\n      <string id=\"EnableAdditionalSources\">启用 Windows 程序包管理器其他源</string>\n      <string id=\"EnableAdditionalSourcesExplanation\">此策略控制企业 IT 管理员提供的其他源。\n\n如果未配置此策略，则将不会为 Windows 程序包管理器配置其他源。\n\n如果启用此策略，则将向 Windows 程序包管理器添加其他源并且这些源不可删除。可使用“winget source export”从已安装的源获取每个其他源的表示形式。\n\n如果禁用此策略，则不能为 Windows 程序包管理器配置其他源。</string>\n      <string id=\"EnableAllowedSources\">启用 Windows 程序包管理器允许的源</string>\n      <string id=\"EnableAllowedSourcesExplanation\">此策略控制企业 IT 管理员允许的其他源。\n\n如果未配置此策略，用户将能够添加或删除策略配置的源之外的其他源。\n\n如果启用此策略，则只能从 Windows 程序包管理器中添加或删除指定的源。可使用“winget source export”从已安装的源获取每个允许的源的表示形式。\n\n如果禁用此策略，则不能为 Windows 程序包管理器配置其他源。</string>\n      <string id=\"EnableMSAppInstallerProtocol\">启用应用安装程序 ms-appinstaller 协议</string>\n      <string id=\"EnableMSAppInstallerProtocolExplanation\">此策略控制用户是否可以从使用 ms-appinstaller 协议的网站安装包。\n\n如果启用此设置，则用户将能够安装来自使用此协议的网站的包。\n\n如果禁用或未配置此设置，则用户将无法安装来自使用此协议的网站的包。</string>\n      <string id=\"EnableWindowsPackageManagerCommandLineInterfaces\">启用 Windows 程序包管理器命令行接口</string>\n      <string id=\"EnableWindowsPackageManagerCommandLineInterfacesExplanation\">此策略确定用户是否可以通过命令行界面（WinGet CLI 或 WinGet PowerShell）使用 Windows 程序包管理器执行操作。\n\n       如果禁用此策略，用户将无法执行 Windows 程序包管理器 CLI 和 PowerShell cmdlet。\n\n       如果启用或未配置此策略，用户将能够执行 Windows 程序包管理器 CLI 命令和 PowerShell cmdlet。（前提是 “启用应用安装程序” 策略未禁用）。\n\n       此策略不会替代 “启用应用安装程序” 策略。</string>\n      <string id=\"EnableWindowsPackageManagerConfiguration\">启用 Windows 程序包管理器配置</string>\n      <string id=\"EnableWindowsPackageManagerConfigurationExplanation\">此策略控制用户是否可以使用Windows 程序包管理器配置功能。\n\n如果启用或未配置此设置，则用户将能够使用Windows 程序包管理器配置功能。\n\n如果禁用此设置，则用户将无法使用Windows 程序包管理器配置功能。</string>\n      <string id=\"EnableWindowsPackageManagerProxyCommandLineOptions\">启用Windows 程序包管理器代理命令行选项</string>\n      <string id=\"EnableWindowsPackageManagerProxyCommandLineOptionsExplanation\">\n        此策略控制用户是否可以通过命令行配置代理的Windows 程序包管理器使用情况。\n\n如果启用此设置，则用户将能够通过命令行配置Windows 程序包管理器使用代理。\n\n如果禁用或未配置此设置，则用户将无法通过命令行配置Windows 程序包管理器使用代理。</string>\n      <string id=\"EnableWindowsPackageManagerMcpServer\">为 Windows 程序包管理器启用 MCP 服务器</string>\n      <string id=\"EnableWindowsPackageManagerMcpServerExplanation\">\n        此策略控制是否可以使用Windows 程序包管理器模型上下文协议 (MCP) 服务器。\n\n如果启用或未配置此设置，则用户将能够使用Windows 程序包管理器的 MCP 服务器。\n\n如果禁用此设置，则用户将无法使用Windows 程序包管理器的 MCP 服务器。</string>\n      <string id=\"WindowsPackageManagerDefaultProxy\">设置 Windows 程序包管理器默认代理</string>\n      <string id=\"WindowsPackageManagerDefaultProxyExplanation\">此策略控制Windows 程序包管理器使用的默认代理。\n\n如果禁用或未配置此设置，则默认情况下不会使用任何代理。\n\n如果启用此设置，则默认情况下将使用指定的代理。</string>\n      <string id=\"EnableMsixAllowedZones\">为 MSIX 包启用应用安装程序允许的区域</string>\n      <string id=\"EnableMsixAllowedZonesExplanation\">此策略控制应用安装程序是否允许安装源自特定 URL 区域的包。包的来源由其 URI 以及是否存在 Mart-of-the-Web (MotW) 来确定。如果涉及多个 URI，则会考虑所有这些 URI;例如，使用涉及重定向的 .appinstaller 文件时。\n\n如果启用此策略，则用户将能够根据每个区域的配置安装 MSIX 包。\n\n如果禁用或未配置此策略，则用户将能够从除不受信任之外的任何区域安装 MSIX 包。</string>\n      <string id=\"ZoneAllowed\">允许</string>\n      <string id=\"ZoneBlocked\">阻止</string>\n      <string id=\"EnableMsixSmartScreenCheck\">为 MSIX 包启用 Microsoft SmartScreen 检查</string>\n      <string id=\"EnableMsixSmartScreenCheckExplanation\">此策略控制应用安装程序在安装 MSIX 包时是否执行Microsoft SmartScreen 检查。\n\n如果启用或未配置此策略，则在安装之前，将使用 Microsoft SmartScreen 评估包 URI。此检查仅适用于来自 Internet 的程序包。\n\n如果禁用，则在安装包之前，不会咨询Microsoft SmartScreen。</string>\n    </stringTable>\n    <presentationTable>\n      <presentation id=\"SourceAutoUpdateInterval\">\n        <decimalTextBox refId=\"SourceAutoUpdateInterval\" defaultValue=\"5\">源自动更新间隔(分钟)</decimalTextBox>\n      </presentation>\n      <presentation id=\"AdditionalSources\">\n        <listBox refId=\"AdditionalSources\" required=\"false\">其他源: </listBox>\n      </presentation>\n      <presentation id=\"AllowedSources\">\n        <listBox refId=\"AllowedSources\" required=\"false\">允许的源: </listBox>\n      </presentation>\n      <presentation id=\"WindowsPackageManagerDefaultProxy\">\n        <textBox refId=\"WindowsPackageManagerDefaultProxy\">\n          <label>默认代理</label>\n        </textBox>\n      </presentation>\n      <presentation id=\"MsixAllowedZones\">\n        <dropdownList refId=\"LocalMachine\" noSort=\"true\" defaultItem=\"1\">本地计算机</dropdownList>\n        <dropdownList refId=\"Intranet\" noSort=\"true\" defaultItem=\"1\">Intranet</dropdownList>\n        <dropdownList refId=\"TrustedSites\" noSort=\"true\" defaultItem=\"1\">受信任的站点</dropdownList>\n        <dropdownList refId=\"Internet\" noSort=\"true\" defaultItem=\"1\">Internet</dropdownList>\n        <dropdownList refId=\"UntrustedSites\" noSort=\"true\" defaultItem=\"0\">不受信任的站点</dropdownList>\n      </presentation>\n    </presentationTable>\n  </resources>\n</policyDefinitionResources>\n"
  },
  {
    "path": "Localization/Policies/zh-TW/DesktopAppInstaller.adml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (c) Microsoft Corporation.\n     Licensed under the MIT License. -->\n<policyDefinitionResources xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" revision=\"1.0\" schemaVersion=\"1.0\" xmlns=\"http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions\">\n  <displayName>應用程式安裝程式</displayName>\n  <description>應用程式安裝程式</description>\n  <resources>\n    <stringTable>\n      <string id=\"AppInstaller\">傳統型應用程式安裝程式</string>\n      <string id=\"EnableAppInstaller\">啟用 Windows 封裝管理員</string>\n      <string id=\"EnableAppInstallerExplanation\">此原則可控制使用者是否可以使用 Windows 套件管理員。\n\n如果您啟用或未設定這個設定，使用者將可以使用 Windows 套件管理員。\n\n如果停用此設定，使用者將無法使用 Windows 套件管理員。</string>\n      <string id=\"EnableSettings\">啟用 Windows 封裝管理員設定</string>\n      <string id=\"EnableSettingsExplanation\">此原則可控制使用者是否可以變更其設定。\n\n如果您啟用或未設定這個設定，使用者將可以變更 Windows 套件管理員的設定。\n\n如果停用此設定，使用者將無法變更 Windows 套件管理員的設定。</string>\n      <string id=\"EnableExperimentalFeatures\">啟用 Windows 封裝管理員實驗性功能</string>\n      <string id=\"EnableExperimentalFeaturesExplanation\">此原則可控制使用者是否能在 Windows 套件管理員中啟用實驗性功能。\n\n如果啟用或未設定此設定，使用者將能夠啟用 Windows 套件管理員的實驗性功能。\n\n如果停用此設定，使用者將無法啟用 Windows 套件管理員的實驗性功能。</string>\n      <string id=\"EnableLocalManifestFiles\">啟用 Windows 封裝管理員本機資訊清單檔案</string>\n      <string id=\"EnableLocalManifestFilesExplanation\">此原則可控制使用者是否能安裝具有本機資訊清單檔案的套件。\n\n如果您啟用或未設定這個設定，使用者將可以使用 Windows 套件管理員來安裝具有本機資訊清單的套件。\n\n若停用此設定，使用者將無法使用 Windows 套件管理員來安裝具有本機資訊清單的套件。</string>\n      <string id=\"EnableBypassCertificatePinningForMicrosoftStore\">啟用 Windows 封裝管理員 Microsoft Store來源憑證驗證略過</string>\n      <string id=\"EnableBypassCertificatePinningForMicrosoftStoreExplanation\">此原則可控制 Windows 封裝管理員在起始 Microsoft Store 來源的連線時，是否要驗證與已知 Microsoft Store 憑證相符的 Microsoft Store 憑證雜湊。\n如果您啟用這個原則，Windows 封裝管理員將會略過 Microsoft Store 憑證驗證。\n\n如果停用此原則，則 Windows 封裝管理員會在與 Microsoft Store 來源通訊之前，驗證使用的 Microsoft Store 憑證有效且屬於 Microsoft Store。\n\n如果您未設定這個原則，則會遵循 Windows 封裝管理員系統管理員設定。</string>\n      <string id=\"EnableHashOverride\">啟用 Windows 封裝管理員雜湊覆寫</string>\n      <string id=\"EnableHashOverrideExplanation\">此原則會控制 Windows 封裝管理員是否可以設定以便啟用在設定中覆寫 SHA256 安全性驗證的能力。\n\n如果您啟用或未設定此原則，使用者就可以在 Windows 封裝管理員設定中啟用覆寫 SHA256 安全性驗證的能力。\n\n如果您停用此原則，使用者就無法在 Windows 封裝管理員設定中啟用覆寫 SHA256 安全性驗證的能力。</string>\n      <string id=\"EnableLocalArchiveMalwareScanOverride\">啟用 Windows 封裝管理員 本機封存惡意代碼掃描覆寫</string>\n      <string id=\"EnableLocalArchiveMalwareScanOverrideExplanation\">此原則控制在使用本機資訊清單使用命令列引數安裝封存檔案時，是否可以覆寫惡意程式碼弱點掃描。\n如果您啟用這個原則，使用者可以在執行封存檔案的本機資訊清單安裝時覆寫惡意程式碼掃描。\n\n如果您停用這個原則，使用者將無法在使用本機資訊清單安裝時覆寫封存檔案的惡意程式碼掃描。\n\n如果您未設定這個原則，則會遵循Windows 封裝管理員系統管理員設定。</string>\n      <string id=\"EnableDefaultSource\">設定 Windows 封裝管理員預設來源</string>\n      <string id=\"EnableDefaultSourceExplanation\">此原則控制 Windows 封裝管理員隨附的預設來源。\n\n如果您未設定此設定，Windows 封裝管理員的預設來源將可供使用，而且可以移除。\n\n如果您啟用此設定，Windows 封裝管理員的預設來源將可供使用，且無法移除。\n\n如果您停用此設定，Windows 封裝管理員的預設來源將無法使用。</string>\n      <string id=\"EnableMicrosoftStoreSource\">啟用 Windows 封裝管理員 Microsoft Store 來源</string>\n      <string id=\"EnableMicrosoftStoreSourceExplanation\">此原則控制 Windows 封裝管理員隨附的 Microsoft Store 來源。\n\n如果您未設定此設定，Windows 封裝管理員的 Microsoft Store 來源將可供使用，而且可以移除。\n\n如果您啟用此設定，Windows 封裝管理員的 Microsoft Store 來源將可供使用，且無法移除。\n\n如果您停用此設定，Windows 封裝管理員的 Microsoft Store 來源將無法使用。</string>\n      <string id=\"EnableFontSource\">設定 Windows 封裝管理員字型來源</string>\n      <string id=\"EnableFontSourceExplanation\">\n        此原則控制 Windows 封裝管理員隨附的字型來源。\n\n        如果您未設定此設定，Windows 封裝管理員的字型來源將可供使用，而且可以移除。\n\n        如果您啟用此設定，Windows 封裝管理員的字型來源將可供使用，且無法移除。\n\n        如果您停用此設定，Windows 封裝管理員的字型來源將無法使用。\n      </string>\n      <string id=\"SourceAutoUpdateInterval\">設定 Windows 封裝管理員來源自動更新間隔 (分鐘)</string>\n      <string id=\"SourceAutoUpdateIntervalExplanation\">此原則控制封裝型來源的自動更新間隔時間。Windows 封裝管理員的預設來源設定為本機電腦上快取的套件索引。當使用者調用命令且間隔已過時，下載索引。\n\n如果您停用或不設定此設定，將會使用 Windows 封裝管理員設定中指定的預設間隔或值。\n\n如果您啟用此設定，Windows 封裝管理員將會使用指定的分鐘數。</string>\n      <string id=\"EnableAdditionalSources\">啟用 Windows 封裝管理員其他來源</string>\n      <string id=\"EnableAdditionalSourcesExplanation\">此原則控制企業 IT 系統管理員提供的其他來源。\n\n如果您未設定此原則，將不會為 Windows 封裝管理員設定其他來源。\n\n如果您啟用此原則，其他來源將會新增到 Windows 封裝管理員，而且無法移除。每個其他來源的標記法都可以使用 'winget 來源匯出' 從已安裝的來源取得。\n\n如果您停用此原則，則 Windows 封裝管理員無法為其他來源進行設定。</string>\n      <string id=\"EnableAllowedSources\">設定 Windows 封裝管理員允許來源</string>\n      <string id=\"EnableAllowedSourcesExplanation\">此原則控制企業 IT 系統管理員允許的其他來源。\n\n如果您未設定此原則，使用者將可以新增或移除其他非此原則設定的來源。\n\n如果您啟用此原則，僅可以從 Windows 封裝管理員新增或移除指定的來源。每個允許來源的代表都可以從使用 'winget 來源匯出' 的已安裝來源取得。\n\n如果您停用此原則，則 Windows 封裝管理員無法為其他來源進行配置。</string>\n      <string id=\"EnableMSAppInstallerProtocol\">啟用應用程式安裝程式 ms-appinstaller 通訊協定</string>\n      <string id=\"EnableMSAppInstallerProtocolExplanation\">此原則控制使用者是否可以從使用 ms-appinstaller 通訊協定的網站安裝套件。\n\n如果您啟用這個設定，使用者將可以從使用此通訊協定的網站安裝套件。\n\n如果您停用或未設定這個設定，使用者將無法從使用此通訊協定的網站安裝套件。</string>\n      <string id=\"EnableWindowsPackageManagerCommandLineInterfaces\">啟用 Windows 封裝管理員命令列介面</string>\n      <string id=\"EnableWindowsPackageManagerCommandLineInterfacesExplanation\">此原則會判斷使用者是否可透過命令列介面 (WinGet CLI 或 WinGet PowerShell) 使用 Windows 封裝管理員執行動作。\n\n       如果停用此原則，使用者將無法執行 Windows 封裝管理員 CLI 和 PowerShell Cmdlet。\n\n       如果啟用或未設定此原則，使用者將可以執行 Windows 封裝管理員 CLI 命令和 PowerShell Cmdlet。(未停用提供的 [啟用應用程式安裝程式] 原則)。\n\n       此原則不會覆寫 [啟用應用程式安裝程式] 原則。</string>\n      <string id=\"EnableWindowsPackageManagerConfiguration\">啟用 Windows 封裝管理員設定</string>\n      <string id=\"EnableWindowsPackageManagerConfigurationExplanation\">此原則控制使用者是否可以使用Windows 封裝管理員設定功能。\n\n如果您啟用或未設定這個設定，使用者將可以使用Windows 封裝管理員設定功能。\n\n如果您停用這個設定，使用者將無法使用Windows 封裝管理員設定功能。</string>\n      <string id=\"EnableWindowsPackageManagerProxyCommandLineOptions\">啟用Windows 封裝管理員 Proxy 命令行選項</string>\n      <string id=\"EnableWindowsPackageManagerProxyCommandLineOptionsExplanation\">\n        此原則控制使用者是否可以透過命令行設定 proxy 的Windows 封裝管理員使用方式。\n\n如果您啟用這個設定，使用者將可以透過命令行設定Windows 封裝管理員使用 Proxy。\n\n如果您停用或未設定這個設定，用戶將無法透過命令行設定Windows 封裝管理員使用 Proxy。</string>\n      <string id=\"EnableWindowsPackageManagerMcpServer\">啟用 Windows 封裝管理員的 MCP 伺服器</string>\n      <string id=\"EnableWindowsPackageManagerMcpServerExplanation\">\n        此原則用來控制是否允許使用 Windows 封裝管理員的模型內容通訊協定 (MCP) 伺服器。\n\n        如果您啟用或未設定此原則，使用者將能使用 Windows 封裝管理員的 MCP 伺服器。\n\n        如果您停用此原則，使用者將無法使用 Windows 封裝管理員的 MCP 伺服器。</string>\n      <string id=\"WindowsPackageManagerDefaultProxy\">設定 Windows 封裝管理員預設 Proxy</string>\n      <string id=\"WindowsPackageManagerDefaultProxyExplanation\">此原則控制Windows 封裝管理員使用的預設 Proxy。\n\n如果停用或未設定此設定，則預設不會使用任何 Proxy。\n\n如果您啟用這個設定，預設會使用指定的 Proxy。</string>\n      <string id=\"EnableMsixAllowedZones\">為 MSIX 套件啟用應用程式安裝程式允許的區域</string>\n      <string id=\"EnableMsixAllowedZonesExplanation\">此原則控制應用程式安裝程式是否允許安裝來自特定 URL 區域的套件。套件的來源取決於其 URI，以及是否存在 Mart-of the Web (MotW)。如果涉及多個 URI，則會考慮所有 URI;例如，使用涉及重新導向的 .appinstaller 檔案時。\n\n如果您啟用這個原則，使用者將可以根據每個區域的設定來安裝 MSIX 套件。\n\n如果您停用或未設定這個原則，除了不受信任之外，使用者將可以從任何區域安裝 MSIX 套件。</string>\n      <string id=\"ZoneAllowed\">允許</string>\n      <string id=\"ZoneBlocked\">阻止</string>\n      <string id=\"EnableMsixSmartScreenCheck\">啟用 MSIX 套件的 Microsoft SmartScreen 檢查</string>\n      <string id=\"EnableMsixSmartScreenCheckExplanation\">此原則可控制應用程式安裝程式在安裝 MSIX 套件時是否執行Microsoft SmartScreen 檢查。\n\n如果啟用或未設定此原則，則會在安裝前使用 Microsoft SmartScreen 評估套件 URI。這項檢查只會針對來自因特網的套件執行。\n\n如果停用，Microsoft安裝套件前將不會詢問 SmartScreen。</string>\n    </stringTable>\n    <presentationTable>\n      <presentation id=\"SourceAutoUpdateInterval\">\n        <decimalTextBox refId=\"SourceAutoUpdateInterval\" defaultValue=\"5\">來源自動更新間隔 (分鐘)</decimalTextBox>\n      </presentation>\n      <presentation id=\"AdditionalSources\">\n        <listBox refId=\"AdditionalSources\" required=\"false\">其他來源： </listBox>\n      </presentation>\n      <presentation id=\"AllowedSources\">\n        <listBox refId=\"AllowedSources\" required=\"false\">允許的來源： </listBox>\n      </presentation>\n      <presentation id=\"WindowsPackageManagerDefaultProxy\">\n        <textBox refId=\"WindowsPackageManagerDefaultProxy\">\n          <label>預設 Proxy</label>\n        </textBox>\n      </presentation>\n      <presentation id=\"MsixAllowedZones\">\n        <dropdownList refId=\"LocalMachine\" noSort=\"true\" defaultItem=\"1\">本機電腦</dropdownList>\n        <dropdownList refId=\"Intranet\" noSort=\"true\" defaultItem=\"1\">內部網路</dropdownList>\n        <dropdownList refId=\"TrustedSites\" noSort=\"true\" defaultItem=\"1\">信任的網站</dropdownList>\n        <dropdownList refId=\"Internet\" noSort=\"true\" defaultItem=\"1\">網際網路</dropdownList>\n        <dropdownList refId=\"UntrustedSites\" noSort=\"true\" defaultItem=\"0\">未受信任的網站</dropdownList>\n      </presentation>\n    </presentationTable>\n  </resources>\n</policyDefinitionResources>\n"
  },
  {
    "path": "Localization/Resources/de-DE/Resources.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "Localization/Resources/de-DE/winget.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"AdjoinedNotFlagError\" xml:space=\"preserve\">\n    <value>Angrenzender Alias ist kein Kennzeichen: „{0}“</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an adjoined alias that is not a flag argument. {0} is a placeholder replaced by the user input argument (e.g. '-ab').</comment>\n  </data>\n  <data name=\"AdjoinedNotFoundError\" xml:space=\"preserve\">\n    <value>Angrenzender Kennzeichenalias nicht gefunden: „{0}“</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an adjoined flag alias argument that was not found. {0} is a placeholder replaced by the user input argument (e.g. '-ab').</comment>\n  </data>\n  <data name=\"AvailableArguments\" xml:space=\"preserve\">\n    <value>Die folgenden Argumente sind verfügbar:</value>\n    <comment>Message displayed to inform the user about the available command line arguments.</comment>\n  </data>\n  <data name=\"AvailableCommandAliases\" xml:space=\"preserve\">\n    <value>Die folgenden Befehlsaliase sind verfügbar:</value>\n    <comment>Message displayed to inform the user about the available command line alias arguments.</comment>\n  </data>\n  <data name=\"AvailableCommands\" xml:space=\"preserve\">\n    <value>Folgende Befehle sind verfügbar:</value>\n    <comment>Title displayed to inform the user about the available commands.</comment>\n  </data>\n  <data name=\"AvailableHeader\" xml:space=\"preserve\">\n    <value>Verfügbar</value>\n    <comment>As in \"a new version is available to upgrade to\".</comment>\n  </data>\n  <data name=\"AvailableOptions\" xml:space=\"preserve\">\n    <value>Die folgenden Optionen stehen zur Verfügung:</value>\n    <comment>Message displayed to inform the user about the available options.</comment>\n  </data>\n  <data name=\"AvailableSubcommands\" xml:space=\"preserve\">\n    <value>Folgende Unterbefehle sind verfügbar:</value>\n    <comment>Message displayed to inform the user about the available nested commands that run in context of the selected command.</comment>\n  </data>\n  <data name=\"AvailableUpgrades\" xml:space=\"preserve\">\n    <value>{0} Aktualisierungen verfügbar.</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about available package upgrades. {0} is a placeholder replaced by the number of package upgrades.</comment>\n  </data>\n  <data name=\"ChannelArgumentDescription\" xml:space=\"preserve\">\n    <value>Verwendet den angegebenen Kanal. Der Standard ist die allgemeine Benutzergruppe</value>\n  </data>\n  <data name=\"Command\" xml:space=\"preserve\">\n    <value>Befehl</value>\n    <comment>Label displayed for a command to give the software.</comment>\n  </data>\n  <data name=\"CommandArgumentDescription\" xml:space=\"preserve\">\n    <value>Ergebnisse nach Befehl filtern</value>\n    <comment>Description message displayed to inform the user about filtering the search results by a package command.</comment>\n  </data>\n  <data name=\"CommandLineArgumentDescription\" xml:space=\"preserve\">\n    <value>Die vollständige Befehlszeile zur Vervollständigung</value>\n  </data>\n  <data name=\"CommandRequiresAdmin\" xml:space=\"preserve\">\n    <value>Zum Ausführen dieses Befehls sind Administratorberechtigungen erforderlich.</value>\n  </data>\n  <data name=\"CompleteCommandLongDescription\" xml:space=\"preserve\">\n    <value>Dieser Befehl kann verwendet werden, um eine kontextbezogene Befehlszeilenvervollständigung anzufordern. Die Befehlszeile, die Cursorposition und das zu vervollständigende Wort werden übergeben. Die Ausgabe ist eine Reihe potenzieller Werte basierend auf den Eingaben, mit einem möglichen Wert pro Zeile.</value>\n  </data>\n  <data name=\"CompleteCommandShortDescription\" xml:space=\"preserve\">\n    <value>Aktiviert die kontextbezogene Befehlszeilenvervollständigung.</value>\n  </data>\n  <data name=\"CountArgumentDescription\" xml:space=\"preserve\">\n    <value>Nicht mehr als die angegebene Anzahl von Ergebnissen anzeigen (zwischen 1 und 1000)</value>\n  </data>\n  <data name=\"Done\" xml:space=\"preserve\">\n    <value>Fertig</value>\n    <comment>Label displayed when an operation completes or is done executing.</comment>\n  </data>\n  <data name=\"ExactArgumentDescription\" xml:space=\"preserve\">\n    <value>Suchen eines Pakets mithilfe exakter Übereinstimmung</value>\n    <comment>Description message displayed to inform the user about finding an application package using an exact matching criteria.</comment>\n  </data>\n  <data name=\"ExperimentalArgumentDescription\" xml:space=\"preserve\">\n    <value>Experimentelles Argument für Demonstrationszwecke</value>\n  </data>\n  <data name=\"ExperimentalCommandLongDescription\" xml:space=\"preserve\">\n    <value>Dieser Befehl ist ein Beispiel für das Implementieren eines experimentellen Features. Rufen Sie zum Aktivieren “winget settings” auf und aktivieren Sie “experimentalCmd” oder “experimentalArg”-Features.</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"ExperimentalCommandShortDescription\" xml:space=\"preserve\">\n    <value>Beispiel eines experimentellen Features</value>\n  </data>\n  <data name=\"ExtraPositionalError\" xml:space=\"preserve\">\n    <value>Ein positionelles Argument wurde gefunden, obwohl keines erwartet wurde: „{0}“</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an extra positional argument when none was expected. {0} is a placeholder replaced by the user's extra argument input.</comment>\n  </data>\n  <data name=\"FeatureDisabledMessage\" xml:space=\"preserve\">\n    <value>Diese Funktion ist noch in Entwicklung und kann in Zukunft geändert oder entfernt werden. Um sie zu aktivieren, bearbeiten Sie Ihre Einstellungen („winget settings“) und fügen Sie das experimentelle Feature hinzu: „{0}“</value>\n    <comment>{Locked=\"winget settings\",\"{0}\"}. Error message displayed when the user uses an experimental feature that is disabled. {0} is a placeholder replaced by the experimental feature name.</comment>\n  </data>\n  <data name=\"FeaturesCommandLongDescription\" xml:space=\"preserve\">\n    <value>Zeigt den Status von experimentellen Features an. Experimentelle Features können mithilfe von “winget settings” aktiviert werden.</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"FeaturesCommandShortDescription\" xml:space=\"preserve\">\n    <value>Zeigt den Status von experimentellen Features an</value>\n  </data>\n  <data name=\"FeaturesDisabled\" xml:space=\"preserve\">\n    <value>Deaktiviert</value>\n  </data>\n  <data name=\"FeaturesEnabled\" xml:space=\"preserve\">\n    <value>Aktiviert</value>\n  </data>\n  <data name=\"FeaturesFeature\" xml:space=\"preserve\">\n    <value>Funktion</value>\n  </data>\n  <data name=\"FeaturesLink\" xml:space=\"preserve\">\n    <value>Link</value>\n  </data>\n  <data name=\"FeaturesMessage\" xml:space=\"preserve\">\n    <value>Die folgenden experimentellen Features werden zurzeit ausgeführt.\nSie können über die Einstellungsdatei „winget settings“ konfiguriert werden.</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"FeaturesProperty\" xml:space=\"preserve\">\n    <value>Eigenschaft</value>\n  </data>\n  <data name=\"FeaturesStatus\" xml:space=\"preserve\">\n    <value>Status</value>\n  </data>\n  <data name=\"FileArgumentDescription\" xml:space=\"preserve\">\n    <value>Zu hashende Datei</value>\n  </data>\n  <data name=\"FlagContainAdjoinedError\" xml:space=\"preserve\">\n    <value>Flagargument darf keinen angrenzenden Wert enthalten: „{0}“</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a flag argument containing an unexpected adjoined value. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"HashCommandLongDescription\" xml:space=\"preserve\">\n    <value>Berechnet den Hash einer lokalen Datei, die für den Eintrag in ein Manifest geeignet ist. Es kann auch der Hash der Signaturdatei eines MSIX-Pakets berechnet werden, um Streaming-Installationen zu ermöglichen.</value>\n  </data>\n  <data name=\"HashCommandShortDescription\" xml:space=\"preserve\">\n    <value>Hilfsprogramm zum Hashen von Installationsdateien</value>\n  </data>\n  <data name=\"HelpArgumentDescription\" xml:space=\"preserve\">\n    <value>Zeigt Hilfe zum ausgewählten Befehl an</value>\n  </data>\n  <data name=\"HelpForDetails\" xml:space=\"preserve\">\n    <value>Wenn Sie weitere Details zu einem bestimmten Befehl erfahren möchten, übergeben Sie ihm das Hilfe-Argument.</value>\n  </data>\n  <data name=\"HelpLinkPreamble\" xml:space=\"preserve\">\n    <value>Weitere Hilfe finden Sie unter: „{0}“</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a link where they can learn more about the subject context. {0} is a placeholder replaced by a website address.</comment>\n  </data>\n  <data name=\"IdArgumentDescription\" xml:space=\"preserve\">\n    <value>Ergebnisse nach ID filtern</value>\n  </data>\n  <data name=\"IgnoreWarningsArgumentDescription\" xml:space=\"preserve\">\n    <value>Unterdrückt Warnungsausgaben.</value>\n  </data>\n  <data name=\"InstallationDisclaimer1\" xml:space=\"preserve\">\n    <value>Diese Anwendung wird von ihrem Besitzer an Sie lizenziert.</value>\n  </data>\n  <data name=\"InstallationDisclaimer2\" xml:space=\"preserve\">\n    <value>Microsoft ist nicht verantwortlich und erteilt keine Lizenzen für Pakete von Drittanbietern.</value>\n  </data>\n  <data name=\"InstallationDisclaimerMSStore\" xml:space=\"preserve\">\n    <value>Dieses Paket wird über den Microsoft Store bereitgestellt. “winget” muss das Paket möglicherweise im Auftrag des aktuellen Benutzers aus dem Microsoft Store abrufen.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"InstallCommandLongDescription\" xml:space=\"preserve\">\n    <value>Installiert das ausgewählte Paket, entweder durch Durchsuchen einer konfigurierten Quelle oder direkt aus einem Manifest. Standardmäßig muss die Abfrage ohne Berücksichtigung der Groß- und Kleinschreibung mit id, name oder moniker des Pakets übereinstimmen. Andere Felder können verwendet werden, indem die entsprechende Option übergeben wird. Standardmäßig überprüft der Installationsbefehl den Installationsstatus des Pakets und versucht allenfalls ein Upgrade durchzuführen. Setzen Sie dies mit „--force“ außer Kraft, um eine direkte Installation auszuführen.</value>\n    <comment>{Locked=\"--force\"}; id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"InstallCommandShortDescription\" xml:space=\"preserve\">\n    <value>Installiert das angegebene Paket</value>\n  </data>\n  <data name=\"InstallerHashMismatchAdminBlock\" xml:space=\"preserve\">\n    <value>Der Installer-Hash stimmt nicht überein. Dies kann nicht außer Kraft gesetzt werden, wenn Sie ihn als Administrator ausführen.</value>\n  </data>\n  <data name=\"InstallerHashMismatchOverridden\" xml:space=\"preserve\">\n    <value>Der Hash des Installationsprogramms stimmt nicht überein. Aufgrund von „--ignore-security-hash“ wird fortgefahren.</value>\n    <comment>{Locked=\"--ignore-security-hash\"}</comment>\n  </data>\n  <data name=\"InstallerHashMismatchOverrideRequired\" xml:space=\"preserve\">\n    <value>Der Hash des Installationsprogramms stimmt nicht überein. Um diese Überprüfung außer Kraft zu setzen, verwenden Sie „--ignore-security-hash“.</value>\n    <comment>{Locked=\"--ignore-security-hash\"}</comment>\n  </data>\n  <data name=\"InstallerHashVerified\" xml:space=\"preserve\">\n    <value>Der Installer-Hash wurde erfolgreich überprüft</value>\n  </data>\n  <data name=\"InstallFlowInstallSuccess\" xml:space=\"preserve\">\n    <value>Erfolgreich installiert</value>\n  </data>\n  <data name=\"InstallFlowStartingPackageInstall\" xml:space=\"preserve\">\n    <value>Paketinstallation wird gestartet...</value>\n  </data>\n  <data name=\"HashOverrideArgumentDescription\" xml:space=\"preserve\">\n    <value>Fehler bei der Hashüberprüfung des Installers ignorieren</value>\n  </data>\n  <data name=\"IgnoreLocalArchiveMalwareScanArgumentDescription\" xml:space=\"preserve\">\n    <value>Bei der Installation eines Archivtyppakets aus dem lokalen Manifest ausgeführte Schadsoftwareüberprüfung ignorieren</value>\n  </data>\n  <data name=\"InteractiveArgumentDescription\" xml:space=\"preserve\">\n    <value>Interaktive Installation anfordern; möglicherweise sind Benutzereingaben erforderlich.</value>\n  </data>\n  <data name=\"InvalidAliasError\" xml:space=\"preserve\">\n    <value>Der Argument-Alias wurde für den aktuellen Befehl nicht erkannt: „{0}“</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a command line argument alias that was not recognized for a selected command. {0} is a placeholder replaced by the user's argument alias input (e.g. '-a').</comment>\n  </data>\n  <data name=\"InvalidArgumentSpecifierError\" xml:space=\"preserve\">\n    <value>Ungültige Spezifikation des Arguments: „{0}“</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an invalid argument specifier. {0} is a placeholder replaced by an argument specifier (e.g. '-').</comment>\n  </data>\n  <data name=\"InvalidNameError\" xml:space=\"preserve\">\n    <value>Argumentname wurde für den aktuellen Befehl nicht erkannt: „{0}“</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an unrecognized command line argument name for the selected command. {0} is a placeholder replaced by the user's argument name input (e.g. '--example').</comment>\n  </data>\n  <data name=\"KeyDirectoriesHeader\" xml:space=\"preserve\">\n    <value>WinGet-Verzeichnisse</value>\n    <comment>Header for a table detailing the directories Winget uses for key operations like logging and portable installs</comment>\n  </data>\n  <data name=\"LocaleArgumentDescription\" xml:space=\"preserve\">\n    <value>Zu verwendendes Gebietsschema (BCP47-Format)</value>\n    <comment>{Locked=\"BCP47\"}</comment>\n  </data>\n  <data name=\"LicenseAgreement\" xml:space=\"preserve\">\n    <value>Lizenzvereinbarung</value>\n  </data>\n  <data name=\"Links\" xml:space=\"preserve\">\n    <value>Links</value>\n    <comment>Links to different webpages</comment>\n  </data>\n  <data name=\"ListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Der Befehl „list“ zeigt die auf dem System installierten Pakete an und ob ein Upgrade verfügbar ist. Weitere Optionen können zum Filtern der Ausgabe angegeben werden, ähnlich wie der Befehl „search“.</value>\n    <comment>{Locked=\"list\",\"search\"}</comment>\n  </data>\n  <data name=\"ListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Installierte Pakete anzeigen</value>\n  </data>\n  <data name=\"LocationArgumentDescription\" xml:space=\"preserve\">\n    <value>Installationsspeicherort (falls unterstützt)</value>\n  </data>\n  <data name=\"LogArgumentDescription\" xml:space=\"preserve\">\n    <value>Log-Speicherort (sofern unterstützt)</value>\n  </data>\n  <data name=\"MainCopyrightNotice\" xml:space=\"preserve\">\n    <value>Copyright (c) Microsoft Corporation. Alle Rechte vorbehalten.</value>\n  </data>\n  <data name=\"MainHomepage\" xml:space=\"preserve\">\n    <value>Startseite</value>\n    <comment>The primary webpage for the software</comment>\n  </data>\n  <data name=\"ManifestArgumentDescription\" xml:space=\"preserve\">\n    <value>Der Pfad zum Manifest des Pakets</value>\n  </data>\n  <data name=\"ManifestValidationFail\" xml:space=\"preserve\">\n    <value>Fehler bei der Manifestüberprüfung.</value>\n  </data>\n  <data name=\"ManifestValidationSuccess\" xml:space=\"preserve\">\n    <value>Die Manifestüberprüfung war erfolgreich.</value>\n  </data>\n  <data name=\"ManifestValidationWarning\" xml:space=\"preserve\">\n    <value>Die Manifestüberprüfung war mit Warnungen erfolgreich.</value>\n  </data>\n  <data name=\"MissingArgumentError\" xml:space=\"preserve\">\n    <value>Wert des Arguments erforderlich, aber nicht gefunden: „{0}“</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user does not provide a required command line argument value. {0} is a placeholder replaced by the argument name.</comment>\n  </data>\n  <data name=\"MonikerArgumentDescription\" xml:space=\"preserve\">\n    <value>Ergebnisse nach Moniker filtern</value>\n  </data>\n  <data name=\"MsixArgumentDescription\" xml:space=\"preserve\">\n    <value>Eingabedatei wird als msix behandelt. Signatur-Hash wird bereitgestellt, falls signiert</value>\n  </data>\n  <data name=\"MsixSignatureHashFailed\" xml:space=\"preserve\">\n    <value>Fehler beim Berechnen des MSIX-Signaturhashs.</value>\n  </data>\n  <data name=\"MSStoreAppBlocked\" xml:space=\"preserve\">\n    <value>Installation oder Upgrade des Microsoft Store-Pakets ist fehlgeschlagen, da die betreffende App von einer Richtlinie blockiert wird.</value>\n  </data>\n  <data name=\"MSStoreInstallOrUpdateFailed\" xml:space=\"preserve\">\n    <value>Installation oder Upgrade des Microsoft Store-Pakets ist fehlgeschlagen. Fehlercode: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Microsoft Store application package fails to install or upgrade. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"MSStoreStoreClientBlocked\" xml:space=\"preserve\">\n    <value>Installation oder Upgrade des Microsoft Store-Pakets ist fehlgeschlagen, da der Microsoft Store-Client von einer Richtlinie blockiert wird.</value>\n  </data>\n  <data name=\"MSStoreInstallTryGetEntitlement\" xml:space=\"preserve\">\n    <value>Überprüfen/anfordern der Paketübernahme</value>\n  </data>\n  <data name=\"MultipleInstalledPackagesFound\" xml:space=\"preserve\">\n    <value>Mehrere installierte Pakete mit übereinstimmenden Eingabekriterien gefunden. Bitte verfeinern Sie die Eingabe.</value>\n  </data>\n  <data name=\"MultiplePackagesFound\" xml:space=\"preserve\">\n    <value>Mehrere Pakete mit übereinstimmenden Eingabekriterien gefunden. Bitte verfeinern Sie die Eingabe.</value>\n  </data>\n  <data name=\"NameArgumentDescription\" xml:space=\"preserve\">\n    <value>Ergebnisse nach Name filtern</value>\n  </data>\n  <data name=\"NoApplicableInstallers\" xml:space=\"preserve\">\n    <value>Es wurde kein anwendbarer Installer gefunden. Weitere Informationen finden Sie in den Protokollen.</value>\n  </data>\n  <data name=\"NoExperimentalFeaturesMessage\" xml:space=\"preserve\">\n    <value>Derzeit sind keine experimentellen Funktionen verfügbar. </value>\n  </data>\n  <data name=\"NoInstalledPackageFound\" xml:space=\"preserve\">\n    <value>Es wurde kein installiertes Paket gefunden, das den Eingabekriterien entspricht.</value>\n  </data>\n  <data name=\"NoPackageFound\" xml:space=\"preserve\">\n    <value>Es wurde kein Paket gefunden, das den Eingabekriterien entspricht.</value>\n  </data>\n  <data name=\"NoVTArgumentDescription\" xml:space=\"preserve\">\n    <value>Deaktiviert VirtualTerminal-Anzeige</value>\n    <comment>{Locked=\"VirtualTerminal\"}</comment>\n  </data>\n  <data name=\"OpenLogsArgumentDescription\" xml:space=\"preserve\">\n    <value>Öffnen des Standardspeicherorts für Protokolle</value>\n  </data>\n  <data name=\"Options\" xml:space=\"preserve\">\n    <value>Optionen</value>\n    <comment>Options to change how a command works</comment>\n  </data>\n  <data name=\"OverrideArgumentDescription\" xml:space=\"preserve\">\n    <value>Außerkraftsetzungsargumente, die an das Installationsprogramm weitergegeben werden sollen</value>\n  </data>\n  <data name=\"Package\" xml:space=\"preserve\">\n    <value>Paket: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for a software package. {0} is a placeholder replaced by the software package name.</comment>\n  </data>\n  <data name=\"PendingWorkError\" xml:space=\"preserve\">\n    <value>Hoppla, das haben wir vergessen...</value>\n  </data>\n  <data name=\"PositionArgumentDescription\" xml:space=\"preserve\">\n    <value>Die Position des Cursors innerhalb der Befehlszeile</value>\n  </data>\n  <data name=\"PrivacyStatement\" xml:space=\"preserve\">\n    <value>Datenschutzerklärung</value>\n  </data>\n  <data name=\"QueryArgumentDescription\" xml:space=\"preserve\">\n    <value>Die Abfrage, mit der nach einem Paket gesucht wird</value>\n  </data>\n  <data name=\"RainbowArgumentDescription\" xml:space=\"preserve\">\n    <value>Statusanzeige in Regenbogenfarben</value>\n  </data>\n  <data name=\"RequiredArgError\" xml:space=\"preserve\">\n    <value>Erforderliches Argument nicht angegeben: „{0}“</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user does not provide a required command line argument. {0} is a placeholder replaced by an argument name.</comment>\n  </data>\n  <data name=\"RetroArgumentDescription\" xml:space=\"preserve\">\n    <value>Statusanzeige in Standardfarbe</value>\n  </data>\n  <data name=\"SearchCommandLongDescription\" xml:space=\"preserve\">\n    <value>Sucht nach Paketen aus konfigurierten Quellen.</value>\n  </data>\n  <data name=\"SearchCommandShortDescription\" xml:space=\"preserve\">\n    <value>Suchen und Anzeigen grundlegender Informationen zu Paketen</value>\n  </data>\n  <data name=\"SearchId\" xml:space=\"preserve\">\n    <value>ID</value>\n    <comment>Abbreviation of Identifier.</comment>\n  </data>\n  <data name=\"SearchMatch\" xml:space=\"preserve\">\n    <value>Übereinstimmung</value>\n  </data>\n  <data name=\"SearchName\" xml:space=\"preserve\">\n    <value>Name</value>\n  </data>\n  <data name=\"SearchSource\" xml:space=\"preserve\">\n    <value>Quelle</value>\n  </data>\n  <data name=\"SearchTruncated\" xml:space=\"preserve\">\n    <value>zusätzliche Einträge wegen Ergebnisgrenzwert abgeschnitten</value>\n  </data>\n  <data name=\"SearchVersion\" xml:space=\"preserve\">\n    <value>Version</value>\n  </data>\n  <data name=\"SettingLoadFailure\" xml:space=\"preserve\">\n    <value>Die folgenden Fehler wurden beim Überprüfen der Einstellungen gefunden:</value>\n  </data>\n  <data name=\"SettingsCommandLongDescription\" xml:space=\"preserve\">\n    <value>Öffnen Sie Einstellungen im standardmäßigen JSON-Text-Editor. Wenn kein Editor konfiguriert ist, werden die Einstellungen im Editor geöffnet. Verfügbare Einstellungen finden Sie unter „https://aka.ms/winget-settings“. Dieser Befehl kann auch zum Festlegen von Administratoreinstellungen verwendet werden, indem das Argument „--enable“ oder „--disable“ angegeben wird.</value>\n    <comment>{Locked=\"--enable\"} {Locked=\"--disable\"}</comment>\n  </data>\n  <data name=\"SettingsCommandShortDescription\" xml:space=\"preserve\">\n    <value>Einstellungen öffnen oder Administratoreinstellungen festlegen</value>\n  </data>\n  <data name=\"SettingsWarnings\" xml:space=\"preserve\">\n    <value>Unerwarteter Fehler beim Laden der Einstellungen. Überprüfen Sie Ihre Einstellungen, indem Sie den Befehl \"'settings'\" ausführen.</value>\n    <comment>{Locked=\"'settings'\"}</comment>\n  </data>\n  <data name=\"ShowChannel\" xml:space=\"preserve\">\n    <value>Kanal</value>\n  </data>\n  <data name=\"ShowCommandLongDescription\" xml:space=\"preserve\">\n    <value>Zeigt Informationen zu einem bestimmten Paket an. Standardmäßig muss die Abfrage ohne Berücksichtigung der Groß-/Kleinschreibung mit der ID, dem Namen oder dem Moniker des Pakets übereinstimmen. Andere Felder können verwendet werden, indem Sie Ihre entsprechende Option übergeben.</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"ShowCommandShortDescription\" xml:space=\"preserve\">\n    <value>Zeigt Informationen zu einem Paket an</value>\n  </data>\n  <data name=\"ShowVersion\" xml:space=\"preserve\">\n    <value>Version</value>\n  </data>\n  <data name=\"SilentArgumentDescription\" xml:space=\"preserve\">\n    <value>Automatische Installation anfordern</value>\n  </data>\n  <data name=\"SingleCharAfterDashError\" xml:space=\"preserve\">\n    <value>Auf einen einzelnen Bindestrich muss ein Alias aus einem einzelnen Zeichen folgen: „{0}“</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides more than a single character command line alias argument after an alias argument specifier '-'. {0} is a placeholder replaced by the user's argument input.</comment>\n  </data>\n  <data name=\"SourceAddAlreadyExistsDifferentArg\" xml:space=\"preserve\">\n    <value>Eine Quelle mit dem angegebenen Namen ist bereits vorhanden und verweist auf einen anderen Speicherort:</value>\n  </data>\n  <data name=\"SourceAddAlreadyExistsDifferentName\" xml:space=\"preserve\">\n    <value>Eine Quelle mit einem anderen Namen verweist bereits auf diesen Speicherort:</value>\n  </data>\n  <data name=\"SourceAddAlreadyExistsMatch\" xml:space=\"preserve\">\n    <value>Eine Quelle mit dem angegebenen Namen ist bereits vorhanden und bezieht sich auf den gleichen Speicherort:</value>\n  </data>\n  <data name=\"SourceAddBegin\" xml:space=\"preserve\">\n    <value>Quelle wird hinzugefügt:</value>\n  </data>\n  <data name=\"SourceAddCommandLongDescription\" xml:space=\"preserve\">\n    <value>Fügen Sie eine neue Quelle hinzu. Eine Quelle stellt die Daten bereit, mit denen Sie Pakete ermitteln und installieren können. Fügen Sie eine neue Quelle nur hinzu, wenn Sie sie für einen sicheren Ort halten.</value>\n  </data>\n  <data name=\"SourceAddCommandShortDescription\" xml:space=\"preserve\">\n    <value>Eine neue Quelle hinzufügen</value>\n  </data>\n  <data name=\"SourceArgArgumentDescription\" xml:space=\"preserve\">\n    <value>Argument, das an die Quelle übergeben wird</value>\n  </data>\n  <data name=\"SourceArgumentDescription\" xml:space=\"preserve\">\n    <value>Suchen eines Pakets mithilfe der angegebenen Quelle</value>\n  </data>\n  <data name=\"SourceCommandLongDescription\" xml:space=\"preserve\">\n    <value>Verwalten Sie Quellen mit den Unterbefehlen. Eine Quelle stellt die Daten bereit, mit denen Sie Pakete ermitteln und installieren können. Fügen Sie eine neue Quelle nur hinzu, wenn Sie sie für einen sicheren Ort halten.</value>\n  </data>\n  <data name=\"SourceCommandShortDescription\" xml:space=\"preserve\">\n    <value>Verwalten von Paketquellen</value>\n  </data>\n  <data name=\"SourceEditCommandLongDescription\" xml:space=\"preserve\">\n    <value>Eigenschaften einer vorhandenen Quelle bearbeiten. Eine Quelle stellt die Daten bereit, mit denen Sie Pakete ermitteln und installieren können.</value>\n  </data>\n  <data name=\"SourceEditCommandShortDescription\" xml:space=\"preserve\">\n    <value>Eigenschaften einer Quelle bearbeiten</value>\n  </data>\n  <data name=\"SourceEditOne\" xml:space=\"preserve\">\n    <value>Quelle wird bearbeitet: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being edited. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceEditNoChanges\" xml:space=\"preserve\">\n    <value>Die Quelle mit dem Namen „{0}“ befindet sich bereits im gewünschten Zustand.</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being edited. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceListArg\" xml:space=\"preserve\">\n    <value>Argument</value>\n    <comment>Value given to source.</comment>\n  </data>\n  <data name=\"SourceListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Liste aller aktuellen Quellen oder vollständiger Details einer bestimmten Quelle.</value>\n  </data>\n  <data name=\"SourceListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Aktuelle Quellen auflisten</value>\n  </data>\n  <data name=\"SourceListData\" xml:space=\"preserve\">\n    <value>Daten</value>\n    <comment>Data stored by the source.</comment>\n  </data>\n  <data name=\"SourceListField\" xml:space=\"preserve\">\n    <value>Bereich</value>\n    <comment>The name of a piece of information about a source.</comment>\n  </data>\n  <data name=\"SourceListName\" xml:space=\"preserve\">\n    <value>Name</value>\n    <comment>The name of the source.</comment>\n  </data>\n  <data name=\"SourceListIdentifier\" xml:space=\"preserve\">\n    <value>Bezeichner</value>\n    <comment>The source's unique identifier.</comment>\n  </data>\n  <data name=\"SourceListNoneFound\" xml:space=\"preserve\">\n    <value>Es wurde keine Quelle mit dem folgenden Namen gefunden: {0}</value>\n    <comment>Error message displayed when the user provides a repository source name that was not found. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"SourceListNoSources\" xml:space=\"preserve\">\n    <value>Es wurden keine Quellen konfiguriert.</value>\n  </data>\n  <data name=\"SourceListType\" xml:space=\"preserve\">\n    <value>Typ</value>\n    <comment>The kind of source.</comment>\n  </data>\n  <data name=\"SourceListUpdated\" xml:space=\"preserve\">\n    <value>Aktualisiert</value>\n    <comment>The last time the source was updated.</comment>\n  </data>\n  <data name=\"SourceListUpdatedNever\" xml:space=\"preserve\">\n    <value>Nie</value>\n    <comment>The source has never been updated.</comment>\n  </data>\n  <data name=\"SourceListValue\" xml:space=\"preserve\">\n    <value>Wert</value>\n    <comment>The value of information about a source.</comment>\n  </data>\n  <data name=\"SourceNameArgumentDescription\" xml:space=\"preserve\">\n    <value>Name der Quelle</value>\n  </data>\n  <data name=\"SourceOpenFailedSuggestion\" xml:space=\"preserve\">\n    <value>Fehler beim Öffnen der Quelle(n): Probieren Sie den Befehl \"source reset\" aus, wenn das Problem weiterhin besteht.</value>\n    <comment>{Locked=\"source reset\"}</comment>\n  </data>\n  <data name=\"SourceOpenPredefinedFailedSuggestion\" xml:space=\"preserve\">\n    <value>Fehler beim Öffnen der vordefinierten Quelle. Bitte melden Sie dieses Problem an die Entwickler von winget.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"SourceRemoveAll\" xml:space=\"preserve\">\n    <value>Alle Quellen werden entfernt...</value>\n  </data>\n  <data name=\"SourceRemoveCommandLongDescription\" xml:space=\"preserve\">\n    <value>Eine bestimmte Quelle entfernen.</value>\n  </data>\n  <data name=\"SourceRemoveCommandShortDescription\" xml:space=\"preserve\">\n    <value>Aktuelle Quellen entfernen</value>\n  </data>\n  <data name=\"SourceRemoveOne\" xml:space=\"preserve\">\n    <value>Quelle wird entfernt: {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being removed. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceResetAll\" xml:space=\"preserve\">\n    <value>Alle Quellen werden zurückgesetzt...</value>\n  </data>\n  <data name=\"SourceResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>Mit diesem Befehl werden vorhandene Quellen verworfen, wodurch potenziell lokale Daten zurückgelassen werden. Ohne Argument werden alle Quellen verworfen und die Standardwerte hinzugefügt. Wenn eine benannte Quelle bereitgestellt wird, wird nur diese Quelle verworfen.</value>\n  </data>\n  <data name=\"SourceResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>Quellen zurücksetzen</value>\n  </data>\n  <data name=\"SourceResetForceArgumentDescription\" xml:space=\"preserve\">\n    <value>Erzwingt das Zurücksetzen der Quellen</value>\n  </data>\n  <data name=\"SourceResetListAndOverridePreamble\" xml:space=\"preserve\">\n    <value>Die folgenden Quellen werden zurückgesetzt, wenn die Option „--force“ angegeben ist:</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"SourceResetOne\" xml:space=\"preserve\">\n    <value>Quelle wird zurückgesetzt: {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a repository source that is currently being reset. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceTypeArgumentDescription\" xml:space=\"preserve\">\n    <value>Typ der Quelle</value>\n  </data>\n  <data name=\"SourceUpdateAll\" xml:space=\"preserve\">\n    <value>Alle Quellen werden aktualisiert...</value>\n  </data>\n  <data name=\"SourceUpdateCommandLongDescription\" xml:space=\"preserve\">\n    <value>Aktualisieren aller Quellen oder nur einer bestimmten Quelle.</value>\n  </data>\n  <data name=\"SourceUpdateCommandShortDescription\" xml:space=\"preserve\">\n    <value>Aktuelle Quellen aktualisieren</value>\n  </data>\n  <data name=\"SourceUpdateOne\" xml:space=\"preserve\">\n    <value>Quelle wird aktualisiert: {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being updated. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"TagArgumentDescription\" xml:space=\"preserve\">\n    <value>Ergebnisse nach Bezeichnung filtern</value>\n  </data>\n  <data name=\"ThankYou\" xml:space=\"preserve\">\n    <value>Vielen Dank, dass Sie WinGet nutzen</value>\n  </data>\n  <data name=\"ThirdPartSoftwareNotices\" xml:space=\"preserve\">\n    <value>Hinweise von Drittanbietern</value>\n  </data>\n  <data name=\"ToolDescription\" xml:space=\"preserve\">\n    <value>Das “winget”-Befehlszeilenprogramm ermöglicht das Installieren von Anwendungen und anderen Paketen mithilfe der Befehlszeile.</value>\n  </data>\n  <data name=\"ToolInfoArgumentDescription\" xml:space=\"preserve\">\n    <value>Allgemeine Informationen zum Tool anzeigen</value>\n  </data>\n  <data name=\"ToolVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>Version des Tools anzeigen</value>\n  </data>\n  <data name=\"TooManyArgError\" xml:space=\"preserve\">\n    <value>Argument wurde öfter angegeben als zulässig: „{0}“</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a command line argument more times than it is allowed. {0} is a placeholder replaced by the user's argument name input.</comment>\n  </data>\n  <data name=\"TooManyBehaviorsError\" xml:space=\"preserve\">\n    <value>Es wurde mehr als ein Argument zur Ausführung angegeben: „{0}“</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides more than one execution behavior argument when installing an application package. {0} is a placeholder replaced by the user specified execution behaviors (e.g. 'silent|interactive').</comment>\n  </data>\n  <data name=\"UnexpectedErrorExecutingCommand\" xml:space=\"preserve\">\n    <value>Unerwarteter Fehler beim Ausführen des Befehls:</value>\n  </data>\n  <data name=\"UninstallPreviousArgumentDescription\" xml:space=\"preserve\">\n    <value>Vorherige Version des Pakets während des Upgrades deinstallieren</value>\n  </data>\n  <data name=\"UnrecognizedCommand\" xml:space=\"preserve\">\n    <value>Nicht erkannter Befehl: „{0}“</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an unrecognized command. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"UpdateAllArgumentDescription\" xml:space=\"preserve\">\n    <value>Upgraden aller installierten Pakete auf den neuesten Stand, falls verfügbar</value>\n  </data>\n  <data name=\"UpdateNotApplicable\" xml:space=\"preserve\">\n    <value>Es wurde kein anwendbares Upgrade gefunden.</value>\n  </data>\n  <data name=\"UpdateNotApplicableReason\" xml:space=\"preserve\">\n    <value>In einer konfigurierten Quelle ist eine neuere Paketversion verfügbar, die jedoch nicht auf Ihr System oder Ihre Anforderungen zutrifft.</value>\n  </data>\n  <data name=\"UpdateNoPackagesFound\" xml:space=\"preserve\">\n    <value>Kein verfügbares Upgrade gefunden.</value>\n  </data>\n  <data name=\"UpdateNoPackagesFoundReason\" xml:space=\"preserve\">\n    <value>In den konfigurierten Quellen sind keine neueren Paketversionen verfügbar.</value>\n  </data>\n  <data name=\"UpgradeCommandLongDescription\" xml:space=\"preserve\">\n    <value>Aktualisiert das ausgewählte Paket, entweder durch Durchsuchen der Liste der installierten Pakete oder direkt aus einem Manifest. Standardmäßig muss die Abfrage ohne Berücksichtigung der Groß-/Kleinschreibung mit der ID, dem Namen oder dem Linkpfad des Pakets übereinstimmen. Andere Felder können verwendet werden, indem sie die entsprechende Option übergeben. Wenn keine Argumente angegeben werden, werden die Pakete mit verfügbaren Upgrades angezeigt.</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"UpgradeCommandShortDescription\" xml:space=\"preserve\">\n    <value>Zeigt verfügbare Upgrades an und führt sie aus.</value>\n  </data>\n  <data name=\"Usage\" xml:space=\"preserve\">\n    <value>Verwendung: {0} {1}</value>\n    <comment>{Locked=\"{0} {1}\"} Message displayed to provide the user with instructions on how to use a command. {0} is a placeholder replaced by the program name (e.g. 'winget'). {1} is a placeholder replaced by the pattern for using the selected command.</comment>\n  </data>\n  <data name=\"ValidateCommandLongDescription\" xml:space=\"preserve\">\n    <value>Überprüft ein Manifest anhand strikter Richtlinien. Hiermit können Sie das Manifest überprüfen, bevor Sie es an ein Repository senden.</value>\n  </data>\n  <data name=\"ValidateCommandShortDescription\" xml:space=\"preserve\">\n    <value>Überprüft eine Manifestdatei</value>\n  </data>\n  <data name=\"ValidateManifestArgumentDescription\" xml:space=\"preserve\">\n    <value>Der Pfad des zu überprüfenden Manifests</value>\n  </data>\n  <data name=\"VerboseLogsArgumentDescription\" xml:space=\"preserve\">\n    <value>Aktiviert die ausführliche Protokollierung für WinGet</value>\n  </data>\n  <data name=\"VerifyFileSignedMsix\" xml:space=\"preserve\">\n    <value>Überprüfen Sie, ob die Eingabedatei eine gültige, signierte MSIX-Datei ist.</value>\n  </data>\n  <data name=\"VersionArgumentDescription\" xml:space=\"preserve\">\n    <value>Die angegebene Version verwenden, Standard ist die neueste Version</value>\n  </data>\n  <data name=\"VersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Verfügbare Versionen des Pakets anzeigen</value>\n  </data>\n  <data name=\"WordArgumentDescription\" xml:space=\"preserve\">\n    <value>Der vor der Vervollständigung angegebene Wert wird angefordert.</value>\n  </data>\n  <data name=\"GetManifestResultVersionNotFound\" xml:space=\"preserve\">\n    <value>Es wurde keine übereinstimmende Version gefunden: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to upgrade an application package to a version that was not found. {0} is a placeholder replaced by the user's provided upgrade package version.</comment>\n  </data>\n  <data name=\"OpenSourceFailedNoMatch\" xml:space=\"preserve\">\n    <value>Keine Quellen entsprechen dem angegebenen Wert: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to install or upgrade an application package from a repository source that was not found. {0} is a placeholder replaced by the user's repository source name input.</comment>\n  </data>\n  <data name=\"OpenSourceFailedNoMatchHelp\" xml:space=\"preserve\">\n    <value>Die konfigurierten Quellen sind:</value>\n  </data>\n  <data name=\"OpenSourceFailedNoSourceDefined\" xml:space=\"preserve\">\n    <value>Keine Quellen definiert; fügen Sie eine mit 'source add' hinzu, oder setzen Sie mittels 'source reset' auf die Standardwerte zurück</value>\n    <comment>{Locked=\"source add\",\"source reset\"}</comment>\n  </data>\n  <data name=\"ReportIdentityFound\" xml:space=\"preserve\">\n    <value>Gefunden</value>\n  </data>\n  <data name=\"VerifyFileFailedIsDirectory\" xml:space=\"preserve\">\n    <value>Pfad ist ein Verzeichnis: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system path that is a directory. {0} is a placeholder replaced by the provided directory path.</comment>\n  </data>\n  <data name=\"VerifyFileFailedNotExist\" xml:space=\"preserve\">\n    <value>Die Datei konnte nicht gefunden werden: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system file that does not exist. {0} is a placeholder replaced by the provided file path.</comment>\n  </data>\n  <data name=\"BothManifestAndSearchQueryProvided\" xml:space=\"preserve\">\n    <value>Es werden sowohl lokale Manifeste als auch die Suchabfragenargumente bereitgestellt.</value>\n  </data>\n  <data name=\"Logs\" xml:space=\"preserve\">\n    <value>Protokolle</value>\n    <comment>Label displayed for diagnostic files containing information about the application use.</comment>\n  </data>\n  <data name=\"InstallerBlockedByPolicy\" xml:space=\"preserve\">\n    <value>Der Installer wird von einer Richtlinie blockiert.</value>\n  </data>\n  <data name=\"InstallerFailedSecurityCheck\" xml:space=\"preserve\">\n    <value>Fehler bei der Sicherheitsprüfung des Installationsprogramms</value>\n  </data>\n  <data name=\"InstallerFailedVirusScan\" xml:space=\"preserve\">\n    <value>Ein Antivirenprodukt meldet eine Infektion im Installationsprogramm</value>\n  </data>\n  <data name=\"SourceOpenWithFailedUpdate\" xml:space=\"preserve\">\n    <value>Fehler beim Versuch, die Quelle zu aktualisieren: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to update the repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"UninstallCommandLongDescription\" xml:space=\"preserve\">\n    <value>Deinstalliert das ausgewählte Paket, das entweder durch Suchen der Liste der installierten Pakete oder direkt aus einem Manifest gefunden wurde. Standardmäßig muss die Abfrage ohne Berücksichtigung der Groß-/Kleinschreibung mit der ID, dem Namen oder dem Moniker des Pakets übereinstimmen. Andere Felder können verwendet werden, indem Sie Ihre entsprechende Option übergeben.</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"UninstallCommandShortDescription\" xml:space=\"preserve\">\n    <value>Deinstalliert das angegebene Paket</value>\n  </data>\n  <data name=\"UninstallFlowStartingPackageUninstall\" xml:space=\"preserve\">\n    <value>Paket-Deinstallation wird gestartet...</value>\n  </data>\n  <data name=\"UninstallFlowUninstallSuccess\" xml:space=\"preserve\">\n    <value>Erfolgreich deinstalliert</value>\n  </data>\n  <data name=\"NoUninstallInfoFound\" xml:space=\"preserve\">\n    <value>Das „winget“-Tool kann den Deinstallationsbefehl für dieses Paket nicht finden. Bitte wenden Sie sich an den Herausgeber des Pakets, um Unterstützung zu erhalten.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"UninstallAbandoned\" xml:space=\"preserve\">\n    <value>Deinstallation abgebrochen</value>\n  </data>\n  <data name=\"UninstallFailedWithCode\" xml:space=\"preserve\">\n    <value>Deinstallation fehlgeschlagen mit Exitcode: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to uninstall an application package fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"ExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Exportiert eine Liste der installierten Pakete</value>\n  </data>\n  <data name=\"ImportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Installiert alle in einer Datei aufgeführten Pakete.</value>\n  </data>\n  <data name=\"ImportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Installiert alle Pakete in einer Datei</value>\n  </data>\n  <data name=\"OutputFileArgumentDescription\" xml:space=\"preserve\">\n    <value>Datei, in der das Ergebnis geschrieben werden soll</value>\n  </data>\n  <data name=\"ImportFileArgumentDescription\" xml:space=\"preserve\">\n    <value>Datei, die die zu installierenden Pakete beschreibt</value>\n  </data>\n  <data name=\"ExportSourceArgumentDescription\" xml:space=\"preserve\">\n    <value>Pakete aus der angegebenen Quelle exportieren</value>\n  </data>\n  <data name=\"ExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Schreibt eine Liste der installierten Pakete in eine Datei. Die Pakete können dann mit dem Befehl \"import\" installiert werden.</value>\n    <comment>{Locked=\"import\"}</comment>\n  </data>\n  <data name=\"ImportInstallFailed\" xml:space=\"preserve\">\n    <value>Eine oder mehrere importierte Pakete konnten nicht installiert werden</value>\n  </data>\n  <data name=\"ImportSourceNotInstalled\" xml:space=\"preserve\">\n    <value>Die für den Import erforderliche Quelle ist nicht installiert: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to import application package(s) from a repository source that is not installed. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"InstalledPackageNotAvailable\" xml:space=\"preserve\">\n    <value>Das installierte Paket ist in keiner Quelle verfügbar: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when the user attempts to export an installed application package that is not available from any repository source. {0} is a placeholder replaced by the installed package name.</comment>\n  </data>\n  <data name=\"InstalledPackageVersionNotAvailable\" xml:space=\"preserve\">\n    <value>Die installierte Version des Pakets ist in keiner Quelle verfügbar: {0} {1} {2}</value>\n    <comment>{Locked=\"{0} {1} {2}\"} Warning message displayed when the user attempts to export an installed application package with a version that is not available from any repository source. {0} is a placeholder replaced by the installed package identifier. {1} is a placeholder replaced by the installed package version. {2} is a placeholder replaced by the installed package channel.</comment>\n  </data>\n  <data name=\"NoPackagesInImportFile\" xml:space=\"preserve\">\n    <value>In der Importdatei wurden keine Pakete gefunden</value>\n  </data>\n  <data name=\"InvalidJsonFile\" xml:space=\"preserve\">\n    <value>Die JSON-Datei ist ungültig</value>\n  </data>\n  <data name=\"MultiQueryPackageAlreadyInstalled\" xml:space=\"preserve\">\n    <value>Das Paket ist bereits installiert: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user that an application package is already installed. {0} is a placeholder replaced by the package identifier or search query.</comment>\n  </data>\n  <data name=\"ImportIgnoreUnavailableArgumentDescription\" xml:space=\"preserve\">\n    <value>Nicht verfügbare Pakete ignorieren</value>\n  </data>\n  <data name=\"ExportIncludeVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Paketversionen in Exportdatei einschließen</value>\n  </data>\n  <data name=\"ImportIgnoreVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Paketversionen aus Importdatei ignorieren</value>\n  </data>\n  <data name=\"VerifyPathFailedNotExist\" xml:space=\"preserve\">\n    <value>Der Pfad ist nicht vorhanden: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system path argument value that does not exist. {0} is a placeholder replaced by the user's provided path.</comment>\n  </data>\n  <data name=\"ImportFileHasInvalidSchema\" xml:space=\"preserve\">\n    <value>In der JSON-Datei ist kein bekanntes Schema angegeben.</value>\n  </data>\n  <data name=\"InstallScopeDescription\" xml:space=\"preserve\">\n    <value>Installationsbereich auswählen (user oder machine)</value>\n    <comment>{Locked=\"user\",\"machine\"} This argument allows the user to select between installing for just the user or for the entire machine.</comment>\n  </data>\n  <data name=\"InvalidArgumentValueError\" xml:space=\"preserve\">\n    <value>Der für das Argument `{0}` angegebene Wert ist ungültig. Gültige Werte sind: {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message displayed when the user provides an invalid command line argument value. {0} is a placeholder replaced by the argument name. {1} is a placeholder replaced by a list of valid options.</comment>\n  </data>\n  <data name=\"DisabledByGroupPolicy\" xml:space=\"preserve\">\n    <value>Dieser Vorgang wird von Gruppenrichtlinie deaktiviert: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user performs a command operation that is disabled by a group policy. {0} is a placeholder replaced by a group policy description.</comment>\n  </data>\n  <data name=\"PolicyAdditionalSources\" xml:space=\"preserve\">\n    <value>Zusätzliche Windows-App-Installer-Quellen aktivieren</value>\n  </data>\n  <data name=\"PolicyAllowedSources\" xml:space=\"preserve\">\n    <value>Zulässige Quellen für Windows-App-Installer aktivieren</value>\n  </data>\n  <data name=\"PolicyEnableDefaultSource\" xml:space=\"preserve\">\n    <value>Standardquelle für den Windows-App-Installer aktivieren</value>\n  </data>\n  <data name=\"PolicyEnableExperimentalFeatures\" xml:space=\"preserve\">\n    <value>Experimentelle Features für den Windows-App-Installer aktivieren</value>\n  </data>\n  <data name=\"PolicyEnableMSStoreSource\" xml:space=\"preserve\">\n    <value>Microsoft Store-Quelle für den Windows-App-Installer aktivieren</value>\n  </data>\n  <data name=\"PolicyEnableFontSource\" xml:space=\"preserve\">\n    <value>Schriftartquelle für Windows App-Installer aktivieren</value>\n  </data>\n  <data name=\"PolicyEnableWinGetSettings\" xml:space=\"preserve\">\n    <value>Einstellungen des Windows-Paket-Manager aktivieren</value>\n  </data>\n  <data name=\"PolicyEnableWinGet\" xml:space=\"preserve\">\n    <value>Windows-Paket-Manager aktivieren</value>\n  </data>\n  <data name=\"PolicyEnableWindowsPackageManagerCommandLineInterfaces\" xml:space=\"preserve\">\n    <value>Windows-Paket-Manager-Befehlszeilenschnittstellen aktivieren</value>\n  </data>\n  <data name=\"PolicySourceAutoUpdateInterval\" xml:space=\"preserve\">\n    <value>Intervall für das automatische Aktualisieren der Windows-Paket-Manager-Quelle in Minuten festlegen</value>\n  </data>\n  <data name=\"PoliciesPolicy\" xml:space=\"preserve\">\n    <value>Gruppenrichtlinie</value>\n    <comment>Header for a table listing active Group Policies</comment>\n  </data>\n  <data name=\"PolicyEnableLocalManifests\" xml:space=\"preserve\">\n    <value>Lokale Manifestdateien für Windows-App-Installer aktivieren</value>\n  </data>\n  <data name=\"PolicyEnableBypassCertificatePinningForMicrosoftStore\" xml:space=\"preserve\">\n    <value>Aktivieren der Umgehung von angehefteten Zertifikaten für die Microsoft Store-Quelle für den Windows App-Installer</value>\n  </data>\n  <data name=\"PolicyEnableLocalArchiveMalwareScanOverride\" xml:space=\"preserve\">\n    <value>Außerkraftsetzung der Schadsoftwareüberprüfung im lokalen Archiv durch Windows App-Installationsprogramm aktivieren</value>\n  </data>\n  <data name=\"SettingsWarningField\" xml:space=\"preserve\">\n    <value>Bereich: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when a user setting field has invalid syntax or semantics. {0} is a placeholder replaced by the setting field path.</comment>\n  </data>\n  <data name=\"SettingsWarningInvalidFieldFormat\" xml:space=\"preserve\">\n    <value>Ungültiges Feldformat.</value>\n  </data>\n  <data name=\"SettingsWarningInvalidFieldValue\" xml:space=\"preserve\">\n    <value>Ungültiger Feldwert.</value>\n  </data>\n  <data name=\"SettingsWarningInvalidValueFromPolicy\" xml:space=\"preserve\">\n    <value>Ungültige Einstellung aus der Gruppenrichtlinie.</value>\n  </data>\n  <data name=\"SettingsWarningLoadedBackupSettings\" xml:space=\"preserve\">\n    <value>Einstellungen wurden aus der Sicherungsdatei geladen.</value>\n  </data>\n  <data name=\"SettingsWarningParseError\" xml:space=\"preserve\">\n    <value>Fehler beim Analysieren der Datei:</value>\n  </data>\n  <data name=\"SettingsWarningValue\" xml:space=\"preserve\">\n    <value>Wert: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when a user setting value has invalid syntax or semantics. {0} is a placeholder replaced by the setting data value.</comment>\n  </data>\n  <data name=\"FeaturesMessageDisabledByPolicy\" xml:space=\"preserve\">\n    <value>Die folgenden experimentellen Features werden zurzeit ausgeführt.\nDie Konfiguration ist aufgrund der Gruppenrichtlinie deaktiviert.</value>\n  </data>\n  <data name=\"InstallerHashMismatchError\" xml:space=\"preserve\">\n    <value>Der Hash-Wert des Installers stimmt nicht überein.</value>\n  </data>\n  <data name=\"PolicyEnableHashOverride\" xml:space=\"preserve\">\n    <value>Hash-Überschreibung für den Windows-App-Installer aktivieren</value>\n  </data>\n  <data name=\"SourceExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Aktuelle Quellen als JSON für die Gruppenrichtlinie exportieren.</value>\n  </data>\n  <data name=\"SourceExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Aktuelle Quellen exportieren</value>\n  </data>\n  <data name=\"SourceListAdditionalSource\" xml:space=\"preserve\">\n    <value>Zusätzliche Quelle</value>\n    <comment>An additional source required by policy.</comment>\n  </data>\n  <data name=\"SourceListAllowedSource\" xml:space=\"preserve\">\n    <value>Zulässige Quelle</value>\n    <comment>A source that the user is allowed to add.</comment>\n  </data>\n  <data name=\"InvalidArgumentValueErrorWithoutValidValues\" xml:space=\"preserve\">\n    <value>Der für das Argument \"{0}\" angegebene Wert ist ungültig.</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an invalid command line argument value. {0} is a placeholder replaced by the argument name.</comment>\n  </data>\n  <data name=\"Cancelled\" xml:space=\"preserve\">\n    <value>Abgebrochen</value>\n  </data>\n  <data name=\"ExternalDependencies\" xml:space=\"preserve\">\n    <value>Extern</value>\n  </data>\n  <data name=\"ImportCommandReportDependencies\" xml:space=\"preserve\">\n    <value>Die Pakete, die in diesem Import gefunden wurden, weisen die folgenden Abhängigkeiten auf:</value>\n    <comment>Import command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"PackageRequiresDependencies\" xml:space=\"preserve\">\n    <value>Dieses Paket erfordert folgende Abhängigkeiten:</value>\n    <comment>Message shown before reporting dependencies</comment>\n  </data>\n  <data name=\"DependenciesFlowInstall\" xml:space=\"preserve\">\n    <value>Abhängigkeiten werden installiert:</value>\n  </data>\n  <data name=\"DependenciesFlowSourceNotFound\" xml:space=\"preserve\">\n    <value>Abhängigkeitsquelle nicht gefunden</value>\n  </data>\n  <data name=\"DependenciesFlowSourceTooManyMatches\" xml:space=\"preserve\">\n    <value>Die Paketsuche ergab mehr als ein Ergebnis: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when application packages search yield more than one result. {0} is a placeholder replaced by the dependency package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowPackageVersionNotFound\" xml:space=\"preserve\">\n    <value>Die neueste Version für das Paket wurde nicht gefunden: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when no suitable version found for the specific application package. {0} is a placeholder replaced by the package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoInstallerFound\" xml:space=\"preserve\">\n    <value>Keine Installationsprogramme gefunden: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when no installer found for a manifest. {0} is a placeholder replaced by the manifest identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoMinVersion\" xml:space=\"preserve\">\n    <value>Die mindestens erforderliche Version ist für das Paket nicht verfügbar: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the minimum required version is not available for an application package. {0} is a placeholder replaced by the package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoMatches\" xml:space=\"preserve\">\n    <value>Keine Übereinstimmungen</value>\n    <comment>When package search yields no matches</comment>\n  </data>\n  <data name=\"DependenciesFlowContainsLoop\" xml:space=\"preserve\">\n    <value>Hat Schleife</value>\n    <comment>Dependency graph has loop</comment>\n  </data>\n  <data name=\"DependenciesFlowNoSuitableInstallerFound\" xml:space=\"preserve\">\n    <value>Für das Manifest wurde kein geeigneter Installer gefunden: {0} Version {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message displayed when an attempt to get a preferred installer for a manifest fails. {0} is a placeholder replaced by the manifest identifier. {1} is a placeholder replaced by the manifest version.</comment>\n  </data>\n  <data name=\"DependenciesManagementError\" xml:space=\"preserve\">\n    <value>Fehler beim Verarbeiten der Paketabhängigkeiten. Möchten Sie die Installation fortsetzen?</value>\n    <comment>Prompt message shown when dependencies processing yields errors.</comment>\n  </data>\n  <data name=\"DependenciesManagementExitMessage\" xml:space=\"preserve\">\n    <value>Fehler beim Verarbeiten der Paketabhängigkeiten. Beenden...</value>\n  </data>\n  <data name=\"PackageDependencies\" xml:space=\"preserve\">\n    <value>Pakete</value>\n  </data>\n  <data name=\"UninstallCommandReportDependencies\" xml:space=\"preserve\">\n    <value>Dieses Paket hat Abhängigkeiten, die möglicherweise nicht mehr benötigt werden:</value>\n    <comment>Uninstall command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"ValidateCommandReportDependencies\" xml:space=\"preserve\">\n    <value>Das Manifest weist folgende Abhängigkeiten auf, die nicht überprüft wurden; stellen Sie sicher, dass sie gültig sind:</value>\n    <comment>Validate command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"WindowsFeaturesDependencies\" xml:space=\"preserve\">\n    <value>Windows-Features</value>\n  </data>\n  <data name=\"WindowsLibrariesDependencies\" xml:space=\"preserve\">\n    <value>Windows-Bibliotheken</value>\n  </data>\n  <data name=\"DependencySourceArgumentDescription\" xml:space=\"preserve\">\n    <value>Paketabhängigkeiten mithilfe der angegebenen Quelle suchen</value>\n    <comment>For getting package type dependencies when installing from a local manifest</comment>\n  </data>\n  <data name=\"WindowsStoreTerms\" xml:space=\"preserve\">\n    <value>Windows Store-Nutzungsbedingungen</value>\n  </data>\n  <data name=\"AcceptPackageAgreementsArgumentDescription\" xml:space=\"preserve\">\n    <value>Akzeptieren aller Lizenzvereinbarungen für Pakete</value>\n  </data>\n  <data name=\"ExportedPackageRequiresLicenseAgreement\" xml:space=\"preserve\">\n    <value>Die exportierten Pakete erfordern eine Lizenzvereinbarung um diese zu installieren: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when an exported application package requires license agreement to install. {0} is a placeholder replaced by the package name.</comment>\n  </data>\n  <data name=\"PackageAgreementsPrompt\" xml:space=\"preserve\">\n    <value>Der Herausgeber verlangt, dass Sie die oben genannten Informationen anzeigen und den Vereinbarungen vor der Installation zustimmen.\nStimmen Sie den Bedingungen zu?</value>\n  </data>\n  <data name=\"PackageAgreementsNotAgreedTo\" xml:space=\"preserve\">\n    <value>Paketvereinbarungen wurden nicht akzeptiert. Der Vorgang wurde abgebrochen.</value>\n  </data>\n  <data name=\"ShowLabelAgreements\" xml:space=\"preserve\">\n    <value>Vereinbarungen:</value>\n  </data>\n  <data name=\"ShowLabelAuthor\" xml:space=\"preserve\">\n    <value>Autor:</value>\n  </data>\n  <data name=\"ShowLabelDescription\" xml:space=\"preserve\">\n    <value>Beschreibung:</value>\n  </data>\n  <data name=\"ShowLabelInstaller\" xml:space=\"preserve\">\n    <value>Installationsprogramm:</value>\n  </data>\n  <data name=\"ShowLabelInstallerLocale\" xml:space=\"preserve\">\n    <value>Installer-Gebietsschema:</value>\n  </data>\n  <data name=\"ShowLabelInstallerProductId\" xml:space=\"preserve\">\n    <value>Store-Produkt-ID:</value>\n  </data>\n  <data name=\"ShowLabelInstallerSha256\" xml:space=\"preserve\">\n    <value>Sha256-Installer:</value>\n  </data>\n  <data name=\"ShowLabelInstallerType\" xml:space=\"preserve\">\n    <value>Installertyp:</value>\n  </data>\n  <data name=\"ShowLabelInstallerUrl\" xml:space=\"preserve\">\n    <value>Installer-URL:</value>\n  </data>\n  <data name=\"ShowLabelLicense\" xml:space=\"preserve\">\n    <value>Lizenz:</value>\n  </data>\n  <data name=\"ShowLabelLicenseUrl\" xml:space=\"preserve\">\n    <value>Lizenz-URL:</value>\n  </data>\n  <data name=\"ShowLabelMoniker\" xml:space=\"preserve\">\n    <value>Moniker:</value>\n  </data>\n  <data name=\"ShowLabelPackageUrl\" xml:space=\"preserve\">\n    <value>Startseite:</value>\n  </data>\n  <data name=\"ShowLabelPublisher\" xml:space=\"preserve\">\n    <value>Herausgeber:</value>\n  </data>\n  <data name=\"ShowLabelTags\" xml:space=\"preserve\">\n    <value>Markierungen:</value>\n  </data>\n  <data name=\"ShowLabelVersion\" xml:space=\"preserve\">\n    <value>Version:</value>\n  </data>\n  <data name=\"ShowLabelDependencies\" xml:space=\"preserve\">\n    <value>Abhängigkeiten:</value>\n  </data>\n  <data name=\"ShowLabelWindowsFeaturesDependencies\" xml:space=\"preserve\">\n    <value>Windows-Features:</value>\n  </data>\n  <data name=\"ShowLabelWindowsLibrariesDependencies\" xml:space=\"preserve\">\n    <value>Windows-Bibliotheken:</value>\n  </data>\n  <data name=\"ShowLabelPackageDependencies\" xml:space=\"preserve\">\n    <value>Paketabhängigkeiten:</value>\n  </data>\n  <data name=\"ShowLabelExternalDependencies\" xml:space=\"preserve\">\n    <value>Externe Abhängigkeiten:</value>\n  </data>\n  <data name=\"PromptOptionNo\" xml:space=\"preserve\">\n    <value>Nein</value>\n  </data>\n  <data name=\"PromptOptionYes\" xml:space=\"preserve\">\n    <value>Ja</value>\n  </data>\n  <data name=\"SourceAddOpenSourceFailed\" xml:space=\"preserve\">\n    <value>Fehler beim Öffnen der hinzugefügten Quelle.</value>\n  </data>\n  <data name=\"AcceptSourceAgreementsArgumentDescription\" xml:space=\"preserve\">\n    <value>Alle Quellvereinbarungen während Quellvorgängen akzeptieren</value>\n  </data>\n  <data name=\"SourceAgreementsTitle\" xml:space=\"preserve\">\n    <value>Die Quelle \"{0}\" erfordert, dass Sie die folgenden Vereinbarungen vor der Verwendung anzeigen.</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user that a repository source requires viewing agreements before using. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceAgreementsPrompt\" xml:space=\"preserve\">\n    <value>Stimmen Sie allen Nutzungsbedingungen der Quelle zu?</value>\n  </data>\n  <data name=\"SourceAgreementsNotAgreedTo\" xml:space=\"preserve\">\n    <value>Mindestens einer der Quellvereinbarungen wurde nicht zugestimmt. Vorgang abgebrochen. Akzeptieren Sie bitte die Quellvereinbarungen, oder entfernen Sie die entsprechenden Quellen.</value>\n  </data>\n  <data name=\"SourceAgreementsMarketMessage\" xml:space=\"preserve\">\n    <value>Die Quelle erfordert, dass die geografische Region des aktuellen Computers aus 2 Buchstaben an den Back-End-Dienst gesendet wird, damit er ordnungsgemäß funktioniert (z. B. „US“).</value>\n  </data>\n  <data name=\"InstallFlowRegistrationDeferred\" xml:space=\"preserve\">\n    <value>Die Installation war erfolgreich. Starten Sie die Anwendung neu, um das Upgrade abzuschließen.</value>\n  </data>\n  <data name=\"HeaderArgumentDescription\" xml:space=\"preserve\">\n    <value>Optionaler HTTP-Kopfzeile der REST-Quelle für Windows-Paket-Manager</value>\n  </data>\n  <data name=\"HeaderArgumentNotApplicableForNonRestSourceWarning\" xml:space=\"preserve\">\n    <value>Die optionale Kopfzeile wird ignoriert, da sie für diese Quelle nicht anwendbar ist.</value>\n  </data>\n  <data name=\"HeaderArgumentNotApplicableWithoutSource\" xml:space=\"preserve\">\n    <value>Die optionale Kopfzeile ist nicht anwendbar, ohne eine Quelle anzugeben: „{0}“</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user performs an operation (e.g install) and provides the HTTP 'header' argument without specifying the repository source. {0} is a placeholder replaced by the header argument name.</comment>\n  </data>\n  <data name=\"ShowLabelInstallerReleaseDate\" xml:space=\"preserve\">\n    <value>Freigabedatum:</value>\n  </data>\n  <data name=\"ShowLabelInstallerOfflineDistributionSupported\" xml:space=\"preserve\">\n    <value>Unterstützte Offlineverteilung:</value>\n  </data>\n  <data name=\"ShowLabelPublisherUrl\" xml:space=\"preserve\">\n    <value>Herausgeber-URL:</value>\n  </data>\n  <data name=\"ShowLabelPurchaseUrl\" xml:space=\"preserve\">\n    <value>Kauf-URL:</value>\n  </data>\n  <data name=\"ShowLabelPublisherSupportUrl\" xml:space=\"preserve\">\n    <value>Herausgeber-Support-URL:</value>\n  </data>\n  <data name=\"ShowLabelPrivacyUrl\" xml:space=\"preserve\">\n    <value>Datenschutz-URL:</value>\n  </data>\n  <data name=\"ShowLabelCopyright\" xml:space=\"preserve\">\n    <value>Copyright:</value>\n  </data>\n  <data name=\"ShowLabelCopyrightUrl\" xml:space=\"preserve\">\n    <value>Copyright-URL:</value>\n  </data>\n  <data name=\"ShowLabelReleaseNotes\" xml:space=\"preserve\">\n    <value>Versionshinweise:</value>\n  </data>\n  <data name=\"ShowLabelReleaseNotesUrl\" xml:space=\"preserve\">\n    <value>URL der Versionshinweise:</value>\n  </data>\n  <data name=\"SearchFailureWarning\" xml:space=\"preserve\">\n    <value>Fehler beim Durchsuchen der Quelle. Ergebnisse werden nicht einbezogen: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when searching a repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SearchFailureError\" xml:space=\"preserve\">\n    <value>Fehler beim Durchsuchen der Quelle: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when searching a repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"FeatureDisabledByAdminSettingMessage\" xml:space=\"preserve\">\n    <value>Dieses Feature muss von Administratoren aktiviert werden. Führen Sie als Administrator zum Aktivieren „winget settings --enable {0}“ aus.</value>\n    <comment>{Locked=\"winget settings --enable\", \"{0}\"}. Error message displayed when the user uses a feature that needs to be enabled by administrators. {0} is a placeholder replaced by the admin setting.</comment>\n  </data>\n  <data name=\"AdminSettingEnableDescription\" xml:space=\"preserve\">\n    <value>Aktiviert die spezifische Administratoreinstellung.</value>\n  </data>\n  <data name=\"AdminSettingDisableDescription\" xml:space=\"preserve\">\n    <value>Deaktiviert die spezifische Administratoreinstellung.</value>\n  </data>\n  <data name=\"AdminSettingEnabled\" xml:space=\"preserve\">\n    <value>Administratoreinstellung \"{0}\" aktiviert.</value>\n    <comment>{Locked=\"{0}\"} Message displayed when the user enables an admin setting. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"AdminSettingDisabled\" xml:space=\"preserve\">\n    <value>Administratoreinstellung \"{0}\" deaktiviert.</value>\n    <comment>{Locked=\"{0}\"} Message displayed when the user disables an admin setting. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"AdminSettingHeader\" xml:space=\"preserve\">\n    <value>Administratoreinstellung</value>\n    <comment>Header for a table displaying admin settings.</comment>\n  </data>\n  <data name=\"InstallFlowReturnCodePackageInUse\" xml:space=\"preserve\">\n    <value>Die Anwendung wird zurzeit ausgeführt. Beenden Sie die Anwendung, und versuchen Sie es noch mal.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodePackageInUseByApplication\" xml:space=\"preserve\">\n    <value>Vom Installationsprogramm geänderte Dateien werden zurzeit von einer anderen Anwendung verwendet. Beenden Sie die Anwendungen, und versuchen Sie es noch mal.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInstallInProgress\" xml:space=\"preserve\">\n    <value>Es wird bereits eine andere Installation ausgeführt. Versuchen Sie es später noch mal.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeFileInUse\" xml:space=\"preserve\">\n    <value>Mindestens eine Datei wird verwendet. Beenden Sie die Anwendung, und versuchen Sie es noch mal.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeMissingDependency\" xml:space=\"preserve\">\n    <value>Für dieses Paket fehlt eine Abhängigkeit im System.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeDiskFull\" xml:space=\"preserve\">\n    <value>Auf Ihrem PC ist kein Speicherplatz mehr vorhanden. Geben Sie Speicherplatz frei, und versuchen Sie es noch mal.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInsufficientMemory\" xml:space=\"preserve\">\n    <value>Es ist nicht genügend Arbeitsspeicher für die Installation verfügbar. Schließen Sie andere Anwendungen, und wiederholen Sie dann den Vorgang.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInvalidParameter\" xml:space=\"preserve\">\n    <value>Einer der Installationsparameter ist ungültig. Das Paketinstallationsprotokoll enthält möglicherweise zusätzliche Details.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeNoNetwork\" xml:space=\"preserve\">\n    <value>Diese Anwendung erfordert Internetkonnektivität. Stellen Sie eine Netzwerkverbindung her, und versuchen Sie es noch mal.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeContactSupport\" xml:space=\"preserve\">\n    <value>Bei dieser Anwendung ist während der Installation ein Fehler aufgetreten. Wenden Sie sich an den Support.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootRequiredToFinish\" xml:space=\"preserve\">\n    <value>Starten Sie den PC neu, um die Installation abzuschließen.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootRequiredForInstall\" xml:space=\"preserve\">\n    <value>Ihr PC wird neu gestartet, um die Installation abzuschließen.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootInitiated\" xml:space=\"preserve\">\n    <value>Fehler bei der Installation. Starten Sie Ihren PC neu, und versuchen Sie es noch mal.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeCancelledByUser\" xml:space=\"preserve\">\n    <value>Sie haben die Installation abgebrochen.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeAlreadyInstalled\" xml:space=\"preserve\">\n    <value>Eine andere Version dieser Anwendung ist bereits installiert.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeDowngrade\" xml:space=\"preserve\">\n    <value>Eine höhere Version dieser Anwendung ist bereits installiert.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeBlockedByPolicy\" xml:space=\"preserve\">\n    <value>Die Installation wird durch Organisationsrichtlinien verhindert. Wenden Sie sich an Ihren Administrator.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeSystemNotSupported\" xml:space=\"preserve\">\n    <value>Die Installation dieses Pakets wird von der aktuellen Systemkonfiguration nicht unterstützt.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeCustomError\" xml:space=\"preserve\">\n    <value>Fehler bei der Installation des benutzerdefinierten Installationsprogramms. Wenden Sie sich an den Paketsupport.</value>\n  </data>\n  <data name=\"InstallAbandoned\" xml:space=\"preserve\">\n    <value>Deinstallation abgebrochen</value>\n  </data>\n  <data name=\"InstallerFailedWithCode\" xml:space=\"preserve\">\n    <value>Installation fehlgeschlagen mit Exitcode: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the application installer fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"InstallerLogAvailable\" xml:space=\"preserve\">\n    <value>Das Installationsprotokoll ist verfügbar unter: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about the system path of a diagnostic files containing information about the installer. {0} is a placeholder replaced by the diagnostic file system path.</comment>\n  </data>\n  <data name=\"SearchFailureErrorListMatches\" xml:space=\"preserve\">\n    <value>Die folgenden Pakete wurden in den Arbeitsquellen gefunden.\nGeben Sie eine Option für --source an, um den Vorgang fortzusetzen.</value>\n    <comment>{Locked=\"--source\"} \"working sources\" as in \"sources that are working correctly\"</comment>\n  </data>\n  <data name=\"SearchFailureErrorNoMatches\" xml:space=\"preserve\">\n    <value>Unter den Arbeitsquellen wurden keine Pakete gefunden.</value>\n    <comment>\"working sources\" as in \"sources that are working correctly\"</comment>\n  </data>\n  <data name=\"FeaturesMessageDisabledByBuild\" xml:space=\"preserve\">\n    <value>Dies ist eine stabile Version von Windows-Paket-Manager. Wenn Sie experimentelle Features ausprobieren möchten, installieren Sie bitte eine Vorabversion. Anweisungen finden Sie auf GitHub unter https://github.com/microsoft/winget-cli.</value>\n    <comment>{Locked=\"https://github.com/microsoft/winget-cli\"}</comment>\n  </data>\n  <data name=\"WindowsPackageManager\" xml:space=\"preserve\">\n    <value>Windows-Paket-Manager v{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying the product name and version. {0} is a placeholder replaced by the product version.</comment>\n  </data>\n  <data name=\"ImportIgnorePackageVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Paketversionen in Importdatei ignorieren</value>\n  </data>\n  <data name=\"CountOutOfBoundsError\" xml:space=\"preserve\">\n    <value>Die angeforderte Anzahl von Ergebnissen muss zwischen 1 und 1000 betragen.</value>\n  </data>\n  <data name=\"CustomSwitchesArgumentDescription\" xml:space=\"preserve\">\n    <value>Argumente, die zusätzlich zu den Standardwerten an das Installationsprogramm übergeben werden sollen</value>\n  </data>\n  <data name=\"UpgradeDifferentInstallTechnologyInNewerVersions\" xml:space=\"preserve\">\n    <value>Es wurde eine neuere Version gefunden, die Installationstechnologie unterscheidet sich jedoch von der aktuellen installierten Version. Deinstallieren Sie das Paket, und installieren Sie die neuere Version.</value>\n  </data>\n  <data name=\"UpgradeDifferentInstallTechnology\" xml:space=\"preserve\">\n    <value>Die Installationstechnologie der angegebenen neueren Version unterscheidet sich von der aktuell installierten Version. Deinstallieren Sie das Paket, und installieren Sie die neuere Version.</value>\n  </data>\n  <data name=\"WindowsPackageManagerPreview\" xml:space=\"preserve\">\n    <value>Windows-Paket-Manager (Vorschau) v{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying the preview product name and pre-release version. {0} is a placeholder replaced by the product version.</comment>\n  </data>\n  <data name=\"ArchitectureArgumentDescription\" xml:space=\"preserve\">\n    <value>Architektur auswählen</value>\n  </data>\n  <data name=\"IncludeUnknownArgumentDescription\" xml:space=\"preserve\">\n    <value>Pakete auch dann aktualisieren, wenn ihre aktuelle Version nicht bestimmt werden kann</value>\n  </data>\n  <data name=\"IncludeUnknownInListArgumentDescription\" xml:space=\"preserve\">\n    <value>Listet Pakete auf, auch wenn deren aktuelle Version nicht ermittelt werden kann. Kann nur mit dem Argument „--upgrade-available“ verwendet werden</value>\n    <comment>{Locked=\"--upgrade-available\"}</comment>\n  </data>\n  <data name=\"UpgradeUnknownVersionExplanation\" xml:space=\"preserve\">\n    <value>Die Versionsnummer dieses Pakets kann nicht bestimmt werden. Um trotzdem ein Upgrade durchzuführen, fügen Sie dem vorherigen Befehl das Argument „--include-unknown“ hinzu.</value>\n    <comment>{Locked=\"--include-unknown\"}</comment>\n  </data>\n  <data name=\"UpgradeUnknownVersionCount\" xml:space=\"preserve\">\n    <value>Mindestens {0} Paket verfügt über Versionsnummern, die nicht ermittelt werden können. Verwenden Sie „--include-unknown“, um alle Ergebnisse anzuzeigen.</value>\n    <comment>{Locked=\"{0}\",\"--include-unknown\"} {0} is a placeholder that is replaced by an integer number of packages that do not have notated versions. </comment>\n  </data>\n  <data name=\"UpgradeRequireExplicitCount\" xml:space=\"preserve\">\n    <value>{0} Pakete sind angeheftet und müssen explizit aktualisiert werden.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by an integer number of packages that require explicit upgrades.</comment>\n  </data>\n  <data name=\"InvalidArgumentWithoutQueryError\" xml:space=\"preserve\">\n    <value>Die angegebenen Argumente können nur mit einer Abfrage verwendet werden.</value>\n  </data>\n  <data name=\"SystemArchitecture\" xml:space=\"preserve\">\n    <value>Systemarchitektur: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for the system architecture. {0} is a placeholder replaced by the value of the system architecture (e.g. X64).</comment>\n  </data>\n  <data name=\"PreserveArgumentDescription\" xml:space=\"preserve\">\n    <value>Behält alle vom Paket erstellten Dateien und Verzeichnisse bei (portabel)</value>\n  </data>\n  <data name=\"PurgeArgumentDescription\" xml:space=\"preserve\">\n    <value>Löscht alle Dateien und Verzeichnisse im Paketverzeichnis (portabel)</value>\n  </data>\n  <data name=\"PressEnterToContinue\" xml:space=\"preserve\">\n    <value>Drücken Sie die EINGABETASTE, um fortzufahren</value>\n  </data>\n  <data name=\"RenameArgumentDescription\" xml:space=\"preserve\">\n    <value>Der Wert zum Umbenennen der ausführbaren Datei (portabel)</value>\n  </data>\n  <data name=\"WaitArgumentDescription\" xml:space=\"preserve\">\n    <value>Fordert den Benutzer auf, vor dem Beenden eine beliebige Taste zu drücken</value>\n  </data>\n  <data name=\"InstallerElevationExpected\" xml:space=\"preserve\">\n    <value>Das Installationsprogramm fordert die Ausführung als Administrator an. Es wird ein Prompt erwartet.</value>\n  </data>\n  <data name=\"InstallerProhibitsElevation\" xml:space=\"preserve\">\n    <value>Das Installationsprogramm kann nicht in einem Administratorkontext ausgeführt werden.</value>\n  </data>\n  <data name=\"ModifiedPathRequiresShellRestart\" xml:space=\"preserve\">\n    <value>Pfadumgebungsvariable geändert; Starten Sie Ihre Shell neu, um den neuen Wert zu verwenden.</value>\n  </data>\n  <data name=\"ProductCodeArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtert nach dem Produktcode</value>\n  </data>\n  <data name=\"PortableRegistryCollisionOverridden\" xml:space=\"preserve\">\n    <value>Es existiert bereits ein portables Paket mit demselben Namen, aber aus einer anderen Quelle; Fortfahren wegen --force</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"ReparsePointsNotSupportedError\" xml:space=\"preserve\">\n    <value>Das Volume unterstützt keine Analysepunkte</value>\n  </data>\n  <data name=\"ReservedFilenameError\" xml:space=\"preserve\">\n    <value>Der angegebene Dateiname ist kein gültiger Dateiname.</value>\n  </data>\n  <data name=\"OverwritingExistingFileAtMessage\" xml:space=\"preserve\">\n    <value>Vorhandene Datei überschreiben: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed to inform the user that an existing file is being overwritten. {0} is a placeholder replaced by the file system path.</comment>\n  </data>\n  <data name=\"NoPackageSelectionArgumentProvided\" xml:space=\"preserve\">\n    <value>Es wurde kein Paketauswahlargument angegeben; Einzelheiten zum Suchen eines Pakets finden Sie in der Hilfe.</value>\n  </data>\n  <data name=\"PortableAliasAdded\" xml:space=\"preserve\">\n    <value>Befehlszeilenalias hinzugefügt:</value>\n  </data>\n  <data name=\"PortableLinksMachine\" xml:space=\"preserve\">\n    <value>Portables Linkverzeichnis (Computer)</value>\n  </data>\n  <data name=\"PortableLinksUser\" xml:space=\"preserve\">\n    <value>Verzeichnis für portierbare Links (Benutzer)</value>\n  </data>\n  <data name=\"PortableRootUser\" xml:space=\"preserve\">\n    <value>Portierbarer Paketstamm (Benutzer)</value>\n  </data>\n  <data name=\"PortableRoot\" xml:space=\"preserve\">\n    <value>Portierbarer Paketstamm</value>\n  </data>\n  <data name=\"PortableRoot86\" xml:space=\"preserve\">\n    <value>Portierbares Paketstamm (x86)</value>\n  </data>\n  <data name=\"PortableInstallFailed\" xml:space=\"preserve\">\n    <value>Portable Installation fehlgeschlagen; Aufräumen...</value>\n  </data>\n  <data name=\"PortableHashMismatchOverridden\" xml:space=\"preserve\">\n    <value>Das Portable-Paket wurde geändert. Aufgrund von „--force“ wird fortgefahren</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"PortableHashMismatchOverrideRequired\" xml:space=\"preserve\">\n    <value>Das Portable-Paket kann nicht entfernt werden, da es geändert wurde. Um dies außer Kraft zu setzen, verwenden Sie „--force“</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"FilesRemainInInstallDirectory\" xml:space=\"preserve\">\n    <value>Dateien verbleiben im Installationsverzeichnis: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when files remain in install directory. {0} is a placeholder replaced by the directory path.</comment>\n  </data>\n  <data name=\"PurgeInstallDirectory\" xml:space=\"preserve\">\n    <value>Installationsverzeichnis löschen...</value>\n  </data>\n  <data name=\"UnableToPurgeInstallDirectory\" xml:space=\"preserve\">\n    <value>Installationsverzeichnis kann nicht gelöscht werden, da es nicht von WinGet erstellt wurde</value>\n  </data>\n  <data name=\"RelatedLink\" xml:space=\"preserve\">\n    <value>Verwandter Link</value>\n  </data>\n  <data name=\"ShowLabelDocumentation\" xml:space=\"preserve\">\n    <value>Dokumentation:</value>\n  </data>\n  <data name=\"Notes\" xml:space=\"preserve\">\n    <value>Hinweise: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for installation notes. {0} is a placeholder replaced by installation notes.</comment>\n  </data>\n  <data name=\"ShowLabelInstallationNotes\" xml:space=\"preserve\">\n    <value>Installationshinweise:</value>\n  </data>\n  <data name=\"UnsupportedArgument\" xml:space=\"preserve\">\n    <value>Ein angegebenes Argument ist für dieses Paket nicht unterstützt</value>\n  </data>\n  <data name=\"ExtractArchiveFailed\" xml:space=\"preserve\">\n    <value>Fehler beim Extrahieren der Inhalte des Archivs</value>\n  </data>\n  <data name=\"NestedInstallerNotFound\" xml:space=\"preserve\">\n    <value>Die geschachtelte Installerdatei ist nicht vorhanden. Stellen Sie sicher, dass der angegebene relative Pfad des geschachtelten Installers übereinstimmt: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when nested installer file does not exist. {0} is a placeholder replaced by the nested installer file path.</comment>\n  </data>\n  <data name=\"InvalidPathToNestedInstaller\" xml:space=\"preserve\">\n    <value>Ungültiger relativer Dateipfad zum geschachtelten Installer. Der Pfad verweist auf einen Speicherort außerhalb des Installationsverzeichnisses</value>\n  </data>\n  <data name=\"NestedInstallerNotSpecified\" xml:space=\"preserve\">\n    <value>Für dieses Paket wurden keine geschachtelten Installers angegeben.</value>\n  </data>\n  <data name=\"MultipleUnsupportedNestedInstallersSpecified\" xml:space=\"preserve\">\n    <value>Für ein Archivinstallationsprogramm kann nur ein verschachteltes Installationsprogramm angegeben werden, es sei denn, es handelt sich um ein portierbares oder ein geschachteltes Schriftarteninstallationsprogramm.</value>\n  </data>\n  <data name=\"IncompatibleArgumentsProvided\" xml:space=\"preserve\">\n    <value>Inkompatible Befehlszeilenargumente bereitgestellt</value>\n  </data>\n  <data name=\"UpgradeArgumentDescription\" xml:space=\"preserve\">\n    <value>Listet nur Pakete auf, für die ein Upgrade verfügbar ist</value>\n  </data>\n  <data name=\"UpgradeAvailableForPinned\" xml:space=\"preserve\">\n    <value>Für die folgenden Pakete ist ein Upgrade verfügbar, für das Upgrade ist jedoch eine explizite Zielgruppenadressierung erforderlich:</value>\n    <comment>\"require explicit targeting for upgrade\" means that the package will not be upgraded with all others unless an extra flag is added, or the package is mentioned explicitly</comment>\n  </data>\n  <data name=\"Downloading\" xml:space=\"preserve\">\n    <value>Download läuft</value>\n    <comment>Label displayed while downloading an application installer.</comment>\n  </data>\n  <data name=\"NestedInstallerNotSupported\" xml:space=\"preserve\">\n    <value>Der geschachtelte Installertyp wird nicht unterstützt.</value>\n  </data>\n  <data name=\"InstallerAbortsTerminal\" xml:space=\"preserve\">\n    <value>Dieser Installer ist dafür bekannt, dass er das Terminal oder die Shell neu startet</value>\n  </data>\n  <data name=\"InstallerRequiresInstallLocation\" xml:space=\"preserve\">\n    <value>Für dieses Paket ist ein Installationsspeicherort erforderlich</value>\n  </data>\n  <data name=\"InstallersAbortTerminal\" xml:space=\"preserve\">\n    <value>Die folgenden Installationsprogramme sind dafür bekannt, dass sie das Terminal oder die Shell neu starten:</value>\n  </data>\n  <data name=\"InstallersRequireInstallLocation\" xml:space=\"preserve\">\n    <value>Für die folgenden Installationsprogramme ist ein Installationsspeicherort erforderlich:</value>\n  </data>\n  <data name=\"PromptForInstallRoot\" xml:space=\"preserve\">\n    <value>Geben Sie das Installationsstammverzeichnis an:</value>\n  </data>\n  <data name=\"PromptToProceed\" xml:space=\"preserve\">\n    <value>Möchten Sie den Vorgang fortsetzen?</value>\n  </data>\n  <data name=\"ReportIdentityForAgreements\" xml:space=\"preserve\">\n    <value>Vereinbarungen für</value>\n    <comment>This will be followed by a package name, and then a list of license agreements</comment>\n  </data>\n  <data name=\"InstallLocationNotProvided\" xml:space=\"preserve\">\n    <value>Der Installationsspeicherort ist für das Paket erforderlich, wurde jedoch nicht angegeben.</value>\n  </data>\n  <data name=\"DisableInteractivityArgumentDescription\" xml:space=\"preserve\">\n    <value>Interaktive Eingabeaufforderungen deaktivieren</value>\n    <comment>Description for a command line argument, shown next to it in the help</comment>\n  </data>\n  <data name=\"ConvertInstallFlowToUpgrade\" xml:space=\"preserve\">\n    <value>Es wurde bereits ein vorhandenes Paket gefunden. Es wird versucht, das installierte Paket zu aktualisieren...</value>\n  </data>\n  <data name=\"ForceArgumentDescription\" xml:space=\"preserve\">\n    <value>Führen Sie den Befehl direkt aus, und fahren Sie mit nicht sicherheitsrelevanten Problemen fort.</value>\n    <comment>Description for a command line argument, shown next to it in the help</comment>\n  </data>\n  <data name=\"PortablePackageAlreadyExists\" xml:space=\"preserve\">\n    <value>Ein portables Paket aus einer anderen Quelle ist bereits vorhanden</value>\n  </data>\n  <data name=\"ExtractArchiveSucceeded\" xml:space=\"preserve\">\n    <value>Archiv erfolgreich extrahiert</value>\n  </data>\n  <data name=\"ExtractingArchive\" xml:space=\"preserve\">\n    <value>Archiv wird extrahiert...</value>\n  </data>\n  <data name=\"ArchiveFailedMalwareScan\" xml:space=\"preserve\">\n    <value>Bei der Archivüberprüfung wurde Schadsoftware erkannt. Verwenden Sie --ignore-local-archive-malware-scan, um diese Überprüfung außer Kraft zu setzen.</value>\n    <comment>{Locked=\"--ignore-local-archive-malware-scan\"}</comment>\n  </data>\n  <data name=\"ArchiveFailedMalwareScanOverridden\" xml:space=\"preserve\">\n    <value>Bei der Archivüberprüfung wurde Schadsoftware erkannt. Vorgang wird aufgrund --ignore-local-archive-malware-scan</value>\n    <comment>{Locked=\"--ignore-local-archive-malware-scan\"}</comment>\n  </data>\n  <data name=\"NoUpgradeArgumentDescription\" xml:space=\"preserve\">\n    <value>Überspringt das Upgrade, wenn bereits eine installierte Version vorhanden ist.</value>\n  </data>\n  <data name=\"PackageAlreadyInstalled\" xml:space=\"preserve\">\n    <value>Eine Paketversion ist bereits installiert. Die Installation wurde abgebrochen.</value>\n  </data>\n  <data name=\"EnableAdminSettingFailed\" xml:space=\"preserve\">\n    <value>{0} kann nicht aktiviert werden. Diese Einstellung wird durch eine Richtlinie gesteuert. Wenden Sie sich an den Systemadministrator, um weitere Informationen zu erfahren.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"DisableAdminSettingFailed\" xml:space=\"preserve\">\n    <value>{0} kann nicht deaktiviert werden. Diese Einstellung wird durch eine Richtlinie gesteuert. Wenden Sie sich an den Systemadministrator, um weitere Informationen zu erfahren.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"PinAddCommandLongDescription\" xml:space=\"preserve\">\n    <value>Heften Sie ein Paket an. Dadurch kann Windows-Paket-Manager beim Upgrade eines Pakets auf bestimmte Versionen eingeschränkt werden, oder das Upgrade des Pakets kann vollständig verhindert werden. Ein angeheftetes Paket kann trotzdem eigenständig von außerhalb des Windows-Paket-Managers aktualisiert werden. Standardmäßig kann ein angeheftetes Paket aktualisiert werden, indem es explizit im Befehl \"upgrade\" erwähnt wird oder indem das Flag \"--include-pinned\" zu \"winget upgrade --all\" hinzugefügt wird.</value>\n    <comment>{Locked{\"'upgrade'\"} Locked{\"--include-pinned\"} Locked{\"winget upgrade --all\"}</comment>\n  </data>\n  <data name=\"PinAddCommandShortDescription\" xml:space=\"preserve\">\n    <value>Neue PIN hinzufügen</value>\n  </data>\n  <data name=\"PinCommandLongDescription\" xml:space=\"preserve\">\n    <value>Verwalten Sie angeheftete Pakete mit den Unterbefehlen. Wird ein Paket angeheftet, kann Windows-Paket-Manager beim Upgrade eines Pakets auf bestimmte Versionen eingeschränkt werden, oder das Upgrade des Pakets kann vollständig verhindert werden. Ein angeheftetes Paket kann trotzdem eigenständig von außerhalb des Windows-Paket-Managers aktualisiert werden.</value>\n  </data>\n  <data name=\"PinCommandShortDescription\" xml:space=\"preserve\">\n    <value>Paketpins verwalten</value>\n  </data>\n  <data name=\"PinListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Listet alle aktuellen Pins oder vollständige Details eines bestimmten Pins auf.</value>\n  </data>\n  <data name=\"PinListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Aktuelle Pins auflisten</value>\n  </data>\n  <data name=\"PinRemoveCommandLongDescription\" xml:space=\"preserve\">\n    <value>Entfernen Sie eine bestimmte Paket-PIN.</value>\n  </data>\n  <data name=\"PinRemoveCommandShortDescription\" xml:space=\"preserve\">\n    <value>Paket-PIN entfernen</value>\n  </data>\n  <data name=\"PinResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>Alle vorhandenen Pins zurücksetzen.</value>\n  </data>\n  <data name=\"PinResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>Pins zurücksetzen</value>\n  </data>\n  <data name=\"GatedVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>Version, an die das Paket angeheftet werden soll. Der Platzhalter \"*\" kann als letzter Versionsteil verwendet werden.</value>\n  </data>\n  <data name=\"PinAddBlockingArgumentDescription\" xml:space=\"preserve\">\n    <value>Upgrade blockieren, bis der Pin entfernt wird, wodurch Außerkraftsetzungsargumente verhindert werden</value>\n  </data>\n  <data name=\"PinInstalledArgumentDescription\" xml:space=\"preserve\">\n    <value>Bestimmte installierte Version anheften</value>\n  </data>\n  <data name=\"PinInstalledSource\" xml:space=\"preserve\">\n    <value>Installiert</value>\n    <comment>Value used in a table to indicate that a package comes from the list of packages installed in the machine</comment>\n  </data>\n  <data name=\"SettingsExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Einstellungen als JSON exportieren</value>\n  </data>\n  <data name=\"SettingsExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Einstellungen exportieren</value>\n  </data>\n  <data name=\"UserSettings\" xml:space=\"preserve\">\n    <value>Benutzereinstellungen</value>\n    <comment>Label displayed for the file containing the user settings.</comment>\n  </data>\n  <data name=\"SettingsWarningUsingDefault\" xml:space=\"preserve\">\n    <value>Die Einstellungsdatei konnte nicht geladen werden. Standardwerte werden verwendet.</value>\n  </data>\n  <data name=\"InstalledScopeArgumentDescription\" xml:space=\"preserve\">\n    <value>Bereichsfilter für das installierte Paket auswählen (user oder machine)</value>\n    <comment>{Locked=\"user\",\"machine\"} This argument allows the user to select installed packages for just the user or for the entire machine.</comment>\n  </data>\n  <data name=\"PinAdded\" xml:space=\"preserve\">\n    <value>Pin erfolgreich hinzugefügt</value>\n  </data>\n  <data name=\"PinAlreadyExists\" xml:space=\"preserve\">\n    <value>Für das Paket {0} ist bereits eine PIN vorhanden.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that will be replaced by a package name. The message is shown when attempting to add a pin for a package that is already pinned.</comment>\n  </data>\n  <data name=\"PinExistsOverwriting\" xml:space=\"preserve\">\n    <value>Für das Paket {0} ist bereits eine PIN vorhanden. Überschreiben aufgrund des --force Arguments.</value>\n    <comment>{Locked=\"--force\"}{Locked=\"--force\",\"{0}\"} {0} is a placeholder that will be replaced by a package name.</comment>\n  </data>\n  <data name=\"PinExistsUseForceArg\" xml:space=\"preserve\">\n    <value>Für das Paket {0} ist bereits eine PIN vorhanden. Verwenden Sie das --force Argument, um es zu überschreiben.</value>\n    <comment>{Locked=\"--force\",\"{0}\"} {0} is a placeholder that will be replaced by a package name.</comment>\n  </data>\n  <data name=\"PinResettingAll\" xml:space=\"preserve\">\n    <value>Alle aktuellen Pins werden zurückgesetzt.</value>\n  </data>\n  <data name=\"PinResetUseForceArg\" xml:space=\"preserve\">\n    <value>Verwenden Sie das argument --force, um alle Pins zurückzusetzen. Die folgenden Pins würden entfernt:</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"PinType\" xml:space=\"preserve\">\n    <value>Stecknadeltyp</value>\n  </data>\n  <data name=\"PinDoesNotExist\" xml:space=\"preserve\">\n    <value>Für das Paket {0} ist keine PIN vorhanden</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that will be replaced by a package name. The message is shown when attempting to delete a pin for a package that is not pinned.</comment>\n  </data>\n  <data name=\"PinNoPinsExist\" xml:space=\"preserve\">\n    <value>Es sind keine Pins konfiguriert.</value>\n    <comment>Shown when listing or modifying existing pins if there are none.</comment>\n  </data>\n  <data name=\"PinResetSuccessful\" xml:space=\"preserve\">\n    <value>Pins erfolgreich zurückgesetzt</value>\n    <comment>Shown after resetting (deleting) all the pins</comment>\n  </data>\n  <data name=\"PinCannotOpenIndex\" xml:space=\"preserve\">\n    <value>Pin-Datenbank kann nicht geöffnet werden.</value>\n    <comment>Error message for when we cannot open the database containing package pins.</comment>\n  </data>\n  <data name=\"ArgumentForSinglePackageProvidedWithMultipleQueries\" xml:space=\"preserve\">\n    <value>Es wurde ein Argument angegeben, das nur für ein einzelnes Paket verwendet werden kann.</value>\n  </data>\n  <data name=\"MultipleExclusiveArgumentsProvided\" xml:space=\"preserve\">\n    <value>Es wurden mehrere Argumente angegeben, die sich gegenseitig ausschließen: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message shown when mutually incompatible command line arguments are used. {0} is a placeholder replaced by the arguments that cannot be specified together</comment>\n  </data>\n  <data name=\"DependencyArgumentMissing\" xml:space=\"preserve\">\n    <value>Argument {0} kann nur mit {1} verwendet werden.</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message shown when having an argument needs another to be present, but that is missing. {0} and {1} are replaced by the arguments. For example \"Argument --include-unknown can only be used with --upgrade\"</comment>\n  </data>\n  <data name=\"StateDisabled\" xml:space=\"preserve\">\n    <value>Deaktiviert</value>\n    <comment>As in enabled/disabled</comment>\n  </data>\n  <data name=\"StateEnabled\" xml:space=\"preserve\">\n    <value>Aktiviert</value>\n    <comment>As in enabled/disabled</comment>\n  </data>\n  <data name=\"StateHeader\" xml:space=\"preserve\">\n    <value>Status</value>\n    <comment>Header for a table listing the state (enabled/disabled) of Group Policies and Settings</comment>\n  </data>\n  <data name=\"MultiQueryArgumentDescription\" xml:space=\"preserve\">\n    <value>Die Abfrage, mit der nach einem Paket gesucht wird</value>\n  </data>\n  <data name=\"MultiQueryPackageNotFound\" xml:space=\"preserve\">\n    <value>Paket nicht gefunden: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches returns no results. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"MultiQuerySearchFoundMultiple\" xml:space=\"preserve\">\n    <value>Mehrere Pakete gefunden für: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches returns more than one result. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"MultiQuerySearchFailed\" xml:space=\"preserve\">\n    <value>Fehler bei der Suche nach: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches fails. This message is for generic failures, we have more specific messages for when the search returns no results, or when it returns more than one result. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"UpgradeBlockedByPinCount\" xml:space=\"preserve\">\n    <value>{0} Pakete verfügen über einen Pin, der vor dem Upgrade entfernt werden muss</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by an integer number of packages with pins that prevent upgrade</comment>\n  </data>\n  <data name=\"UpgradeBlockedByManifest\" xml:space=\"preserve\">\n    <value>Das Paket kann nicht mit winget aktualisiert werden. Verwenden Sie die vom Herausgeber bereitgestellte Methode zum Aktualisieren dieses Pakets.</value>\n  </data>\n  <data name=\"IncludePinnedArgumentDescription\" xml:space=\"preserve\">\n    <value>Aktualisieren von Paketen auch dann, wenn sie über einen nicht blockierenden Pin verfügen</value>\n  </data>\n  <data name=\"IncludePinnedInListArgumentDescription\" xml:space=\"preserve\">\n    <value>Listet Pakete auf, auch wenn sie einen Pin haben, der ein Upgrade verhindert. Kann nur mit dem Argument „--upgrade-available“ verwendet werden</value>\n    <comment>{Locked=\"--upgrade-available\"}</comment>\n  </data>\n  <data name=\"PinRemovedSuccessfully\" xml:space=\"preserve\">\n    <value>Pin erfolgreich entfernt</value>\n  </data>\n  <data name=\"UpgradeIsPinned\" xml:space=\"preserve\">\n    <value>Es wurde eine neuere Version gefunden, das Paket verfügt jedoch über eine PIN, die ein Upgrade verhindert.</value>\n  </data>\n  <data name=\"PackageIsPinned\" xml:space=\"preserve\">\n    <value>Das Paket ist angeheftet und kann nicht aktualisiert werden. Verwenden Sie den Befehl \"winget pin\", um Pins anzuzeigen und zu bearbeiten. Einige Stecknadeltypen können mit dem Argument \"--include-pinned\" umgangen werden.</value>\n    <comment>{Locked=\"winget pin\",\"--include-pinned\"} Error shown when we block an upgrade due to the package being pinned</comment>\n  </data>\n  <data name=\"UpgradePinnedByUserCount\" xml:space=\"preserve\">\n    <value>{0} Pakete verfügen über Pins, die ein Upgrade verhindern. Verwenden Sie den Befehl \"winget pin\", um Pins anzuzeigen und zu bearbeiten. Wenn Sie das --include-pinned-Argument verwenden, werden möglicherweise weitere Ergebnisse angezeigt.</value>\n    <comment>{Locked=\"winget pin\",\"--include-pinned\"} {0} is a placeholder replaced by an integer number of packages</comment>\n  </data>\n  <data name=\"ConfigureCommandLongDescription\" xml:space=\"preserve\">\n    <value>Stellt sicher, dass das System dem gewünschten Zustand entspricht, wie in der angegebenen Konfiguration beschrieben. Kann Prozessoren herunterladen/ausführen, um den gewünschten Zustand zu erreichen. Die Konfiguration und die Prozessoren sollten überprüft werden, um sicherzustellen, dass sie vertrauenswürdig sind, bevor sie angewendet werden.</value>\n  </data>\n  <data name=\"ConfigureCommandShortDescription\" xml:space=\"preserve\">\n    <value>Konfiguriert das System in einem gewünschten Zustand</value>\n  </data>\n  <data name=\"ConfigureShowCommandLongDescription\" xml:space=\"preserve\">\n    <value>Zeigt Details zur angegebenen Konfiguration an. Standardmäßig wird das System nicht geändert, aber einige Optionen führen dazu, dass Dateien heruntergeladen und/oder geladen werden.</value>\n  </data>\n  <data name=\"ConfigureShowCommandShortDescription\" xml:space=\"preserve\">\n    <value>Zeigt Details einer Konfiguration an</value>\n  </data>\n  <data name=\"ConfigureTestCommandLongDescription\" xml:space=\"preserve\">\n    <value>Überprüft, ob das System mit dem gewünschten Zustand übereinstimmt, wie in der angegebenen Konfiguration beschrieben. Kann Prozessoren herunterladen/ausführen, um den gewünschten Zustand zu testen. Die Konfiguration und die Prozessoren sollten überprüft werden, um sicherzustellen, dass sie vertrauenswürdig sind, bevor Sie sie ausführen.</value>\n  </data>\n  <data name=\"ConfigureTestCommandShortDescription\" xml:space=\"preserve\">\n    <value>Überprüft das System anhand eines gewünschten Zustands.</value>\n  </data>\n  <data name=\"ConfigureValidateCommandLongDescription\" xml:space=\"preserve\">\n    <value>Überprüft eine Konfigurationsdatei auf Richtigkeit.</value>\n  </data>\n  <data name=\"ConfigureValidateCommandShortDescription\" xml:space=\"preserve\">\n    <value>Überprüft eine Konfigurationsdatei</value>\n  </data>\n  <data name=\"ConfigurationFieldInvalidType\" xml:space=\"preserve\">\n    <value>Das Feld '{0}' in der Konfigurationsdatei weist den falschen Typ auf.</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the field name from the file.</comment>\n  </data>\n  <data name=\"ConfigurationFileArgumentDescription\" xml:space=\"preserve\">\n    <value>Der Pfad zur Konfigurationsdatei</value>\n  </data>\n  <data name=\"ConfigurationFileInvalid\" xml:space=\"preserve\">\n    <value>Die Konfigurationsdatei ist ungültig.</value>\n  </data>\n  <data name=\"ConfigurationFileVersionUnknown\" xml:space=\"preserve\">\n    <value>Die Konfigurationsdateiversion {0} ist nicht bekannt.</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the version of the configuration file.</comment>\n  </data>\n  <data name=\"ConfigurationAcceptWarningArgumentDescription\" xml:space=\"preserve\">\n    <value>Akzeptiert die Konfigurationswarnung und verhindert eine interaktive Eingabeaufforderung</value>\n  </data>\n  <data name=\"ConfigurationApply\" xml:space=\"preserve\">\n    <value>Anwenden</value>\n    <comment>Indicates that this item is used to write state</comment>\n  </data>\n  <data name=\"ConfigurationAssert\" xml:space=\"preserve\">\n    <value>Bestätigen</value>\n    <comment>Indicates that this item is used to check/assert the state rather than write to it</comment>\n  </data>\n  <data name=\"ConfigurationDependencies\" xml:space=\"preserve\">\n    <value>Abhängigkeiten:{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying a list of dependencies. {0} is replaced with a space separated list of identifiers referencing other items.</comment>\n  </data>\n  <data name=\"ConfigurationFailedToApply\" xml:space=\"preserve\">\n    <value>Ein Teil der Konfiguration wurde nicht erfolgreich angewendet.</value>\n  </data>\n  <data name=\"ConfigurationFailedToGetDetails\" xml:space=\"preserve\">\n    <value>Fehler beim Abrufen detaillierter Informationen zur Konfiguration.</value>\n  </data>\n  <data name=\"ConfigurationInform\" xml:space=\"preserve\">\n    <value>Informieren</value>\n    <comment>Indicates that this item is used to retrieve values for future use rather than writing them</comment>\n  </data>\n  <data name=\"ConfigurationLocal\" xml:space=\"preserve\">\n    <value>Lokal</value>\n    <comment>Used to indicate that the item is present on the device.</comment>\n  </data>\n  <data name=\"ConfigurationModuleNameOnly\" xml:space=\"preserve\">\n    <value>Modul: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying a module name. {0} is replaced with the name of the module from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationModuleWithDetails\" xml:space=\"preserve\">\n    <value>Modul: {0} von {1} [{2}]</value>\n    <comment>{Locked=\"{0}\",\"{1}\",\"{2}\"} Label displaying module information. {0} is replaced by the module name. {1} is replaced by the module author. {2} is replaced by a string indicating the source of the module.</comment>\n  </data>\n  <data name=\"ConfigurationSettings\" xml:space=\"preserve\">\n    <value>Einstellungen:</value>\n    <comment>Label for the values that are used as inputs for this item when applying state</comment>\n  </data>\n  <data name=\"ConfigurationSuccessfullyApplied\" xml:space=\"preserve\">\n    <value>Die Konfiguration wurde erfolgreich angewendet.</value>\n  </data>\n  <data name=\"ConfigurationUnitSuccessfullyApplied\" xml:space=\"preserve\">\n    <value>Die Einheit wurde erfolgreich angewendet.</value>\n  </data>\n  <data name=\"ConfigurationWaitingOnAnother\" xml:space=\"preserve\">\n    <value>Eine andere Konfiguration wird auf das System angewendet. Diese Konfiguration wird so bald wie möglich fortgesetzt...</value>\n  </data>\n  <data name=\"ConfigurationWarning\" xml:space=\"preserve\">\n    <value>Sie sind dafür verantwortlich, die Konfigurationseinstellungen zu verstehen, die Sie ausführen möchten. Microsoft ist nicht für die von Ihnen erstellte oder importierte Konfigurationsdatei verantwortlich. Diese Konfiguration kann Einstellungen in Windows ändern, Software installieren, Softwareeinstellungen (einschließlich Sicherheitseinstellungen) ändern und Benutzervereinbarungen für Pakete und Dienste von Drittanbietern in Ihrem Namen akzeptieren. Indem Sie diese Konfigurationsdatei ausführen, bestätigen Sie, dass Sie diese Ressourcen und Einstellungen verstehen und ihnen zustimmen. Alle installierten Anwendungen werden an Sie von ihren Besitzern lizenziert. Microsoft ist weder für Pakete oder Dienste von Drittanbietern verantwortlich noch gewährt es Lizenzen für diese.</value>\n    <comment>Legal approved. Do not change without approval.</comment>\n  </data>\n  <data name=\"ConfigurationWarningPromptApply\" xml:space=\"preserve\">\n    <value>Haben Sie die Konfiguration überprüft und möchten sie auf das System anwenden?</value>\n    <comment>PM approved.</comment>\n  </data>\n  <data name=\"ConfigurationFileEmpty\" xml:space=\"preserve\">\n    <value>Die Konfiguration ist leer.</value>\n  </data>\n  <data name=\"WindowsFeatureNotFound\" xml:space=\"preserve\">\n    <value>Das Feature [{0}] wurde nicht gefunden.</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Windows feature was not found on the system.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeatureOverrideRequired\" xml:space=\"preserve\">\n    <value>Fehler beim Aktivieren von Windows-Featureabhängigkeiten. Verwenden Sie '--force', um mit der Installation fortzufahren.</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"RebootRequiredToEnableWindowsFeatureOverrideRequired\" xml:space=\"preserve\">\n    <value>Neustart erforderlich, um das/die Windows-Feature(s) vollständig zu aktivieren; um diese Prüfung außer Kraft zu setzen, verwenden Sie '--force'.</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeatureOverridden\" xml:space=\"preserve\">\n    <value>Aktivieren von Windows Feature-Abhängigkeiten fehlgeschlagen; Fortfahren aufgrund von --force</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.\n{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"EnablingWindowsFeature\" xml:space=\"preserve\">\n    <value>[{0}] wird aktiviert...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to the user regarding which Windows Feature is being enabled.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeature\" xml:space=\"preserve\">\n    <value>Fehler beim Aktivieren des [{0}]-Features: {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"}  An error when enabling a Windows Feature. {0} is a placeholder for the name of the Windows Feature.\n{1} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"RebootRequiredToEnableWindowsFeatureOverridden\" xml:space=\"preserve\">\n    <value>Ein Neustart ist erforderlich, um das/die Windows-Feature(s) vollständig zu aktivieren; wird aufgrund von --force durchgeführt</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.</comment>\n  </data>\n  <data name=\"InstallWaitingOnAnother\" xml:space=\"preserve\">\n    <value>Es wird auf den Abschluss einer weiteren Installation/Deinstallation gewartet...</value>\n  </data>\n  <data name=\"PinVersion\" xml:space=\"preserve\">\n    <value>Angeheftete Version</value>\n    <comment>Table header for the version to which a package is pinned; meaning it should not update from that version.</comment>\n  </data>\n  <data name=\"ConfigurationDescriptionWasTruncated\" xml:space=\"preserve\">\n    <value>&lt;Weitere Informationen finden Sie in der Protokolldatei&gt;</value>\n    <comment>The brackets are intended to make the value stand out from other text which it will follow. Any locale appropriate mechanism that achieves this is acceptable.</comment>\n  </data>\n  <data name=\"ConfigurationGettingDetails\" xml:space=\"preserve\">\n    <value>Konfigurationsdetails werden abgerufen</value>\n  </data>\n  <data name=\"ConfigurationInitializing\" xml:space=\"preserve\">\n    <value>Das Konfigurationssystem wird initialisiert.</value>\n  </data>\n  <data name=\"ConfigurationReadingConfigFile\" xml:space=\"preserve\">\n    <value>Konfigurationsdatei wird gelesen</value>\n  </data>\n  <data name=\"ConfigurationUnitAssertHadNegativeResult\" xml:space=\"preserve\">\n    <value>Das System befindet sich nicht im gewünschten Zustand, der von der Konfiguration bestätigt wird.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailed\" xml:space=\"preserve\">\n    <value>Fehler bei dieser Konfigurationseinheit aus unbekanntem Grund: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedConfigSet\" xml:space=\"preserve\">\n    <value>Fehler bei der Konfigurationseinheit aufgrund der folgenden Konfiguration: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringGet\" xml:space=\"preserve\">\n    <value>Fehler der Konfigurationseinheit beim Abrufen des aktuellen Systemstatus.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringSet\" xml:space=\"preserve\">\n    <value>Fehler bei der Konfigurationseinheit beim Anwenden des gewünschten Zustands.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringTest\" xml:space=\"preserve\">\n    <value>Fehler bei der Konfigurationseinheit beim Versuch, den aktuellen Systemstatus zu testen.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedInternal\" xml:space=\"preserve\">\n    <value>Fehler bei der Konfigurationseinheit aufgrund eines internen Fehlers: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedPrecondition\" xml:space=\"preserve\">\n    <value>Fehler bei der Konfigurationseinheit aufgrund einer ungültigen Vorbedingung: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedSystemState\" xml:space=\"preserve\">\n    <value>Fehler bei der Konfigurationseinheit aufgrund des Systemstatus: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedUnitProcessing\" xml:space=\"preserve\">\n    <value>Fehler bei der Ausführung der Konfigurationseinheit: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitHasDuplicateIdentifier\" xml:space=\"preserve\">\n    <value>Die Konfiguration enthält den Bezeichner \"{0}\" mehrmals.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by the identifier string from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationUnitHasMissingDependency\" xml:space=\"preserve\">\n    <value>Die Abhängigkeit \"{0}\" wurde in der Konfiguration nicht gefunden.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by the identifier string from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationUnitManuallySkipped\" xml:space=\"preserve\">\n    <value>Diese Konfigurationseinheit wurde manuell übersprungen.</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleConflict\" xml:space=\"preserve\">\n    <value>Das Modul für die Konfigurationseinheit ist an mehreren Speicherorten mit derselben Version verfügbar.</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleImportFailed\" xml:space=\"preserve\">\n    <value>Fehler beim Laden des Moduls für die Konfigurationseinheit.</value>\n  </data>\n  <data name=\"ConfigurationUnitMultipleMatches\" xml:space=\"preserve\">\n    <value>Für die Konfigurationseinheit wurden mehrere Übereinstimmungen gefunden. geben Sie das Modul an, um das richtige auszuwählen.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotFound\" xml:space=\"preserve\">\n    <value>Die Konfigurationseinheit wurde nicht gefunden.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotFoundInModule\" xml:space=\"preserve\">\n    <value>Die Konfigurationseinheit befand sich nicht wie erwartet im Modul.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotRunDueToDependency\" xml:space=\"preserve\">\n    <value>Diese Konfigurationseinheit wurde nicht ausgeführt, da eine Abhängigkeit fehlgeschlagen ist oder nicht ausgeführt wurde.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotRunDueToFailedAssert\" xml:space=\"preserve\">\n    <value>Diese Konfigurationseinheit wurde nicht ausgeführt, da ein Assertfehler aufgetreten ist oder falsch war.</value>\n  </data>\n  <data name=\"ConfigurationUnitReturnedInvalidResult\" xml:space=\"preserve\">\n    <value>Die Konfigurationseinheit hat während der Ausführung ein unerwartetes Ergebnis zurückgegeben.</value>\n  </data>\n  <data name=\"ConfigurationUnitSkipped\" xml:space=\"preserve\">\n    <value>Diese Konfigurationseinheit wurde aus unbekanntem Grund nicht ausgeführt: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationFieldInvalidValue\" xml:space=\"preserve\">\n    <value>Das Feld '{0}' weist einen ungültigen Wert auf: {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} An error in reading a configuration file. {0} is a placeholder replaced by the field name from the file. {1} is a placeholder for the invalid value.</comment>\n  </data>\n  <data name=\"ConfigurationFieldMissing\" xml:space=\"preserve\">\n    <value>Das Feld '{0}' fehlt oder ist leer.</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the expected field name from the file.</comment>\n  </data>\n  <data name=\"SeeLineAndColumn\" xml:space=\"preserve\">\n    <value>Siehe Zeile {0}, Spalte {1} in der Datei.</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Indicates the file location of the error, {0} and {1} are placeholders for numbers of the line and column, respectively.</comment>\n  </data>\n  <data name=\"CancellingOperation\" xml:space=\"preserve\">\n    <value>Vorgang wird abgebrochen</value>\n  </data>\n  <data name=\"InstallStubPackageDescription\" xml:space=\"preserve\">\n    <value>Installieren Sie das Stub-Paket für AppInstaller</value>\n  </data>\n  <data name=\"InstallFullPackageDescription\" xml:space=\"preserve\">\n    <value>Installieren Sie das vollständige Paket für AppInstaller</value>\n  </data>\n  <data name=\"ExtendedFeaturesEnableMessage\" xml:space=\"preserve\">\n    <value>Aktivieren Sie erweiterte Features. Erfordert Zugriff auf den Store.</value>\n  </data>\n  <data name=\"ExtendedFeaturesEnableArgumentError\" xml:space=\"preserve\">\n    <value>Die Option '--enable' und '--disable' kann nicht mit anderen Argumenten verwendet werden.</value>\n    <comment>{Locked=\"--enable\", \"--disable\"}</comment>\n  </data>\n  <data name=\"ExtendedFeaturesEnablingMessage\" xml:space=\"preserve\">\n    <value>Erweiterte Features werden aktiviert. Erfordert Zugriff auf den Store.</value>\n  </data>\n  <data name=\"ExtendedFeaturesNotEnabledMessage\" xml:space=\"preserve\">\n    <value>Erweiterte Features sind nicht aktiviert. Führen Sie \"winget configure --enable\" aus, um sie zu aktivieren.</value>\n    <comment>{Locked=\"winget configure --enable\"}</comment>\n  </data>\n  <data name=\"ExtendedFeaturesEnabledMessage\" xml:space=\"preserve\">\n    <value>Erweiterte Features sind aktiviert.</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisableMessage\" xml:space=\"preserve\">\n    <value>Deaktivieren Sie erweiterte Features. Erfordert Zugriff auf den Store.</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisablingMessage\" xml:space=\"preserve\">\n    <value>Deaktivieren erweiterter Features. Erfordert Zugriff auf den Store.</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisabledMessage\" xml:space=\"preserve\">\n    <value>Erweiterte Features sind deaktiviert.</value>\n  </data>\n  <data name=\"SkipDependenciesArgumentDescription\" xml:space=\"preserve\">\n    <value>Überspringt die Verarbeitung von Paketabhängigkeiten und Windows-Features.</value>\n  </data>\n  <data name=\"DependenciesSkippedMessage\" xml:space=\"preserve\">\n    <value>Abhängigkeiten übersprungen.</value>\n  </data>\n  <data name=\"FailedToRefreshPathWarning\" xml:space=\"preserve\">\n    <value>Fehler beim Aktualisieren der PATH-Variablen für den Prozess. Nachfolgende Installationen, die von Änderungen an der PATH-Variablen abhängen, können fehlschlagen.</value>\n    <comment>{Locked=\"PATH\"}</comment>\n  </data>\n  <data name=\"ConfigurationFailedToTest\" xml:space=\"preserve\">\n    <value>Einige der Konfigurationseinheiten fielen beim Testen ihres Zustands aus.</value>\n  </data>\n  <data name=\"ConfigurationInDesiredState\" xml:space=\"preserve\">\n    <value>Das System befindet sich im beschriebenen Konfigurationszustand.</value>\n  </data>\n  <data name=\"ConfigurationNoTestRun\" xml:space=\"preserve\">\n    <value>Der Konfigurationsstatus wurde nicht getestet.</value>\n  </data>\n  <data name=\"ConfigurationNotInDesiredState\" xml:space=\"preserve\">\n    <value>Das System befindet sich nicht im beschriebenen Konfigurationszustand.</value>\n  </data>\n  <data name=\"ConfigurationUnexpectedTestResult\" xml:space=\"preserve\">\n    <value>Unerwartetes Testergebnis: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message. {0} will be replaced with the unexpected value (a number).</comment>\n  </data>\n  <data name=\"ConfigurationWarningPromptTest\" xml:space=\"preserve\">\n    <value>Haben Sie die Konfiguration überprüft und möchten Sie sie anhand des Systems verifizieren?</value>\n  </data>\n  <data name=\"ConfigurationFileInvalidYAML\" xml:space=\"preserve\">\n    <value>Die Konfigurationsdatei ist keine gültige YAML Datei.</value>\n    <comment>{Locked=\"YAML\"} YAML is a file format name.</comment>\n  </data>\n  <data name=\"ConfigurationUnitIsPartOfDependencyCycle\" xml:space=\"preserve\">\n    <value>Diese Konfigurationseinheit ist Teil eines Abhängigkeitszyklus.</value>\n  </data>\n  <data name=\"ConfigurationValidationFoundNoIssues\" xml:space=\"preserve\">\n    <value>Bei der Überprüfung wurden keine Probleme gefunden.</value>\n  </data>\n  <data name=\"ConfigurationUnitNeedsPrereleaseWarning\" xml:space=\"preserve\">\n    <value>Die Konfigurationseinheit ist nur als Vorabversion verfügbar, aber in der Konfiguration ist sie nicht als solche gekennzeichnet. Fügen Sie `allowPrerelease: true` zu den `directives` hinzu.</value>\n    <comment>{Locked=\"allowPrerelease: true\",\"directives\"} These are values in the configuration file that are not localized.</comment>\n  </data>\n  <data name=\"ConfigurationUnitNotInCatalogWarning\" xml:space=\"preserve\">\n    <value>Die Konfigurationseinheit wurde lokal gefunden, aber in keinem konfigurierten Katalog gefunden. Stellen Sie sicher, dass sie auf allen Systemen vorhanden ist, bevor Sie die Konfiguration anwenden.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotPublicWarning\" xml:space=\"preserve\">\n    <value>Die Konfigurationseinheit ist nicht öffentlich zugänglich; stellen Sie sicher, dass jeder, der diese Konfiguration verwenden wird, Zugriff darauf hat.</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleNotProvidedWarning\" xml:space=\"preserve\">\n    <value>Das Modul wurde nicht angegeben. Die Angabe des Moduls verbessert die Leistung und verhindert zukünftige Namenskonflikte.</value>\n  </data>\n  <data name=\"DownloadCommandLongDescription\" xml:space=\"preserve\">\n    <value>Lädt den Installer aus dem ausgewählten Paket herunter, entweder durch Durchsuchen einer konfigurierten Quelle oder direkt aus einem Manifest. Standardmäßig muss die Abfrage ohne Berücksichtigung der Groß-/Kleinschreibung mit der ID, dem Namen oder dem Moniker des Pakets übereinstimmen. Andere Felder können verwendet werden, indem sie die entsprechende Option übergeben. Standardmäßig wird der entsprechende Installer über den Downloadbefehl in den Ordner \"Downloads\" des Benutzers heruntergeladen.</value>\n  </data>\n  <data name=\"DownloadCommandShortDescription\" xml:space=\"preserve\">\n    <value>Lädt das Installationsprogramm aus einem bestimmten Paket herunter.</value>\n  </data>\n  <data name=\"DownloadDirectoryArgumentDescription\" xml:space=\"preserve\">\n    <value>Verzeichnis, in das die Installationsprogramme heruntergeladen werden</value>\n  </data>\n  <data name=\"DependenciesFlowDownload\" xml:space=\"preserve\">\n    <value>Abhängigkeiten werden heruntergeladen:</value>\n  </data>\n  <data name=\"InstallerDownloaded\" xml:space=\"preserve\">\n    <value>Installationsprogramm heruntergeladen: {0}</value>\n    <comment>{Locked=\"{0}\"} Full path of the downloaded installer.</comment>\n  </data>\n  <data name=\"InstallerTypeArgumentDescription\" xml:space=\"preserve\">\n    <value>Wählen Sie den Installationsprogrammtyp aus</value>\n  </data>\n  <data name=\"InstallerDownloads\" xml:space=\"preserve\">\n    <value>Installationsprogrammdownloads</value>\n  </data>\n  <data name=\"InstallerDownloadCommandProhibited\" xml:space=\"preserve\">\n    <value>Das Herunterladen des Installationsprogramms für eine spätere Offlineinstallation ist nicht zulässig. </value>\n  </data>\n  <data name=\"ConfigurationAllUsersElevated\" xml:space=\"preserve\">\n    <value>`--module-path allusers` erfordert Administratorrechte, um ausgeführt zu werden.</value>\n    <comment>{Locked=\"--module-path allusers\"}</comment>\n  </data>\n  <data name=\"ConfigurationModulePath\" xml:space=\"preserve\">\n    <value>Gibt den Speicherort auf dem lokalen Computer zum Speichern von Modulen an. Standard %LOCALAPPDATA%\\Microsoft\\WinGet\\Configuration\\Modules</value>\n    <comment>{Locked=\"%LOCALAPPDATA%\\Microsoft\\WinGet\\Configuration\\Modules\"}</comment>\n  </data>\n  <data name=\"ConfigurationModulePathArgError\" xml:space=\"preserve\">\n    <value>Der Wert „--module-path“ muss „currentuser“, „allusers“, „default“ oder ein absoluter Pfad sein.</value>\n    <comment>{Locked=\"{--module-path}, {currentuser}, {allusers}, {default}}</comment>\n  </data>\n  <data name=\"PolicyEnableWinGetConfiguration\" xml:space=\"preserve\">\n    <value>Windows-Paket-Manager-Konfiguration aktivieren</value>\n  </data>\n  <data name=\"ErrorCommandLongDescription\" xml:space=\"preserve\">\n    <value>Hiermit werden Informationen zu Fehlern abgerufen. Bei Angabe einer Zahl enthält die Ausgabe Details zum Fehler, einschließlich des Symbolnamens, wenn es sich um einen wingetspezifischen Fehler handelt. Bei Angabe einer Zeichenfolge werden die wingetspezifischen Fehler nach diesem Wert durchsucht.</value>\n  </data>\n  <data name=\"ErrorCommandShortDescription\" xml:space=\"preserve\">\n    <value>Informationen zu Fehlern abrufen</value>\n  </data>\n  <data name=\"ErrorInputArgumentDescription\" xml:space=\"preserve\">\n    <value>Ein Wert, der in den Fehlerinformationen gesucht werden soll</value>\n  </data>\n  <data name=\"ErrorNumberIsTooLarge\" xml:space=\"preserve\">\n    <value>Die angegebene Zahl ist zu groß, um ein HRESULT zu sein.</value>\n  </data>\n  <data name=\"UnknownErrorCode\" xml:space=\"preserve\">\n    <value>Unbekannter Fehlercode</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INTERNAL_ERROR\" xml:space=\"preserve\">\n    <value>Interner Fehler</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS\" xml:space=\"preserve\">\n    <value>Ungültige Befehlszeilenargumente</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMMAND_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Ausführen des Befehls</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Öffnen des Manifests</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CTRL_SIGNAL_RECEIVED\" xml:space=\"preserve\">\n    <value>Abbruchsignal empfangen</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SHELLEXEC_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Ausführen von ShellExecute</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_MANIFESTVERSION\" xml:space=\"preserve\">\n    <value>Das Manifest kann nicht verarbeitet werden. Die Manifestversion ist höher als unterstützt. Aktualisieren Sie den Client.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Herunterladen des Installationsprogramms</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX\" xml:space=\"preserve\">\n    <value>In index kann nicht geschrieben werden; es sich um eine höhere Schemaversion handelt.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INDEX_INTEGRITY_COMPROMISED\" xml:space=\"preserve\">\n    <value>Der Index ist beschädigt</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCES_INVALID\" xml:space=\"preserve\">\n    <value>Die konfigurierten Quellinformationen sind fehlerhaft</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NAME_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>Der Quellname ist bereits konfiguriert</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_SOURCE_TYPE\" xml:space=\"preserve\">\n    <value>Der Quelltyp ist ungültig</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_BUNDLE\" xml:space=\"preserve\">\n    <value>Die MSIX-Datei ist ein Bündel, kein Paket</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_DATA_MISSING\" xml:space=\"preserve\">\n    <value>Von der Quelle benötigte Daten fehlen</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER\" xml:space=\"preserve\">\n    <value>Keines der Installationsprogramme ist für das aktuelle System anwendbar.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_HASH_MISMATCH\" xml:space=\"preserve\">\n    <value>Der Hash der Installationsprogrammdatei stimmt nicht mit dem Manifest überein</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NAME_DOES_NOT_EXIST\" xml:space=\"preserve\">\n    <value>Der Quellname ist nicht vorhanden</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_ARG_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>Der Quellspeicherort ist bereits unter einem anderen Namen konfiguriert.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICATIONS_FOUND\" xml:space=\"preserve\">\n    <value>Es wurden keine Pakete gefunden</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_SOURCES_DEFINED\" xml:space=\"preserve\">\n    <value>Es sind keine Quellen konfiguriert</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_APPLICATIONS_FOUND\" xml:space=\"preserve\">\n    <value>Es wurden mehrere Pakete gefunden, die den Kriterien entsprechen</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_MANIFEST_FOUND\" xml:space=\"preserve\">\n    <value>Es wurde kein Manifest gefunden, das den Kriterien entspricht</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXTENSION_PUBLIC_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Abrufen des öffentlichen Ordners aus dem Quellpaket</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMMAND_REQUIRES_ADMIN\" xml:space=\"preserve\">\n    <value>Zum Ausführen des Befehls sind Administratorrechte erforderlich</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NOT_SECURE\" xml:space=\"preserve\">\n    <value>Der Quellspeicherort ist nicht sicher</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>Der Microsoft Store Client wird durch eine Richtlinie blockiert</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_APP_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>Die Microsoft Store-App wird durch eine Richtlinie blockiert</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXPERIMENTAL_FEATURE_DISABLED\" xml:space=\"preserve\">\n    <value>Das Feature befindet sich zurzeit in der Entwicklung. Sie kann mithilfe von Wingeteinstellungen aktiviert werden.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Installieren der Microsoft Store-App</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMPLETE_INPUT_BAD\" xml:space=\"preserve\">\n    <value>Fehler beim Ausführen der automatischen Vervollständigung</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Initialisieren des XML-Parsers</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_MAPPING_KEY\" xml:space=\"preserve\">\n    <value>Es wurde ein ungültiger YAML-Schlüssel gefunden</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY\" xml:space=\"preserve\">\n    <value>Es wurde ein doppelter YAML-Schlüssel gefunden</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_OPERATION\" xml:space=\"preserve\">\n    <value>Ungültiger YAML-Vorgang</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_DOC_BUILD_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Erstellen des YAML-Dokuments</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_EMITTER_STATE\" xml:space=\"preserve\">\n    <value>Ungültiger YAML-Senderzustand</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_DATA\" xml:space=\"preserve\">\n    <value>Ungültige YAML-Daten</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LIBYAML_ERROR\" xml:space=\"preserve\">\n    <value>LibYAML-Fehler</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_WARNING\" xml:space=\"preserve\">\n    <value>Die Manifestüberprüfung war mit Warnung erfolgreich</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_FAILURE\" xml:space=\"preserve\">\n    <value>Fehler bei der Manifestüberprüfung</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_MANIFEST\" xml:space=\"preserve\">\n    <value>Das Manifest ist ungültig</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>Es wurden keine anwendbaren Aktualisierungen gefunden</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPDATE_ALL_HAS_FAILURE\" xml:space=\"preserve\">\n    <value>winget-Upgrade – vollständig mit Fehlern abgeschlossen</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_SECURITY_CHECK_FAILED\" xml:space=\"preserve\">\n    <value>Installationsprogramm hat Sicherheitsprüfung nicht bestanden</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_SIZE_MISMATCH\" xml:space=\"preserve\">\n    <value>Die Downloadgröße stimmt nicht mit der erwarteten Inhaltslänge überein</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_UNINSTALL_INFO_FOUND\" xml:space=\"preserve\">\n    <value>Der Deinstallationsbefehl wurde nicht gefunden</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXEC_UNINSTALL_COMMAND_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Ausführen des Deinstallationsbefehls</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_BREAK_ITERATOR_ERROR\" xml:space=\"preserve\">\n    <value>ICU-Unterbrechungsiteratorfehler</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_CASEMAP_ERROR\" xml:space=\"preserve\">\n    <value>ICU-Fallzuordnungsfehler</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_REGEX_ERROR\" xml:space=\"preserve\">\n    <value>ICU-RegEx-Fehler</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_IMPORT_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Installieren mindestens eines importierten Pakets.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NOT_ALL_PACKAGES_FOUND\" xml:space=\"preserve\">\n    <value>Mindestens ein angefordertes Paket wurde nicht gefunden.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE\" xml:space=\"preserve\">\n    <value>Die JSON-Datei ist ungültig</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NOT_REMOTE\" xml:space=\"preserve\">\n    <value>Der Quellspeicherort ist nicht remote</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE\" xml:space=\"preserve\">\n    <value>Die konfigurierte REST-Quelle wird nicht unterstützt.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA\" xml:space=\"preserve\">\n    <value>Von der REST-Quelle wurden ungültige Daten zurückgegeben</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>Der Vorgang wird durch Gruppenrichtlinie blockiert</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_INTERNAL_ERROR\" xml:space=\"preserve\">\n    <value>Interner Fehler der REST-API</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_URL\" xml:space=\"preserve\">\n    <value>Ungültige REST-Quell-URL</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_UNSUPPORTED_MIME_TYPE\" xml:space=\"preserve\">\n    <value>Nicht unterstützter MIME-Typ, der von der REST-API zurückgegeben wird</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_VERSION\" xml:space=\"preserve\">\n    <value>Ungültige Version des REST-Quellvertrags</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE\" xml:space=\"preserve\">\n    <value>Die Quelldaten sind beschädigt oder manipuliert.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_STREAM_READ_FAILURE\" xml:space=\"preserve\">\n    <value>Fehler beim Lesen aus dem Datenstrom.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>Paketvereinbarungen wurden nicht vereinbart</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PROMPT_INPUT_ERROR\" xml:space=\"preserve\">\n    <value>Fehler beim Lesen der Eingabe in der Eingabeaufforderung</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST\" xml:space=\"preserve\">\n    <value>Die Suchanforderung wird von mindestens einer Quelle nicht unterstützt.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_ENDPOINT_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Der REST-API-Endpunkt wurde nicht gefunden.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_OPEN_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Öffnen der Quelle.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>Quellvereinbarungen wurde nicht zugestimmt</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CUSTOMHEADER_EXCEEDS_MAXLENGTH\" xml:space=\"preserve\">\n    <value>Die Headergröße überschreitet den zulässigen Grenzwert von 1024 Zeichen. Verringern Sie die Größe, und versuchen Sie es noch mal.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MISSING_RESOURCE_FILE\" xml:space=\"preserve\">\n    <value>Fehlende Ressourcendatei</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSI_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Ausführen der MSI-Installation</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT\" xml:space=\"preserve\">\n    <value>Argumente für msiexec sind ungültig</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FAILED_TO_OPEN_ALL_SOURCES\" xml:space=\"preserve\">\n    <value>Fehler beim Öffnen einer oder mehrerer Quellen</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Überprüfen von Abhängigkeiten</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MISSING_PACKAGE\" xml:space=\"preserve\">\n    <value>Mindestens ein Paket fehlt</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_TABLE_COLUMN\" xml:space=\"preserve\">\n    <value>Ungültige Tabellenspalte</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_NOT_NEWER\" xml:space=\"preserve\">\n    <value>Die Upgradeversion ist nicht neuer als die installierte Version.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_UNKNOWN\" xml:space=\"preserve\">\n    <value>Die Upgradeversion ist unbekannt, und es wurde keine Außerkraftsetzung angegeben</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_CONVERSION_ERROR\" xml:space=\"preserve\">\n    <value>ICU-Konvertierungsfehler</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Installieren des portierbaren Pakets</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_REPARSE_POINT_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Das Volume unterstützt keine Analysepunkte</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_PACKAGE_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>Ein portierbares Paket aus einer anderen Quelle ist bereits vorhanden.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_SYMLINK_PATH_IS_DIRECTORY\" xml:space=\"preserve\">\n    <value>Symlink kann nicht erstellt werden. Der Pfad verweist auf ein Verzeichnis.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_PROHIBITS_ELEVATION\" xml:space=\"preserve\">\n    <value>Das Installationsprogramm kann nicht in einem Administratorkontext ausgeführt werden.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Deinstallieren des portierbaren Pakets</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ARP_VERSION_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Überprüfen der DisplayVersion-Werte anhand des Indexes.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_ARGUMENT\" xml:space=\"preserve\">\n    <value>Mindestens ein Argument wird nicht unterstützt.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_BIND_WITH_EMBEDDED_NULL\" xml:space=\"preserve\">\n    <value>Eingebettete Null-Zeichen sind für SQLite nicht zulässig</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Fehler beim Suchen des geschachtelten Installationsprogramms im Archiv.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXTRACT_ARCHIVE_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Extrahieren des Archivs.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_INVALID_PATH\" xml:space=\"preserve\">\n    <value>Es wurde ein ungültiger relativer Dateipfad zum geschachtelten Installationsprogramm angegeben.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PINNED_CERTIFICATE_MISMATCH\" xml:space=\"preserve\">\n    <value>Das Serverzertifikat stimmte mit keinem der erwarteten Werte überein.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_LOCATION_REQUIRED\" xml:space=\"preserve\">\n    <value>Der Installationsspeicherort muss angegeben werden.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ARCHIVE_SCAN_FAILED\" xml:space=\"preserve\">\n    <value>Archiv-Malware-Scan fehlgeschlagen.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>Es wurde mindestens eine Version des installierten Pakets gefunden.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PIN_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>Für das Paket ist bereits eine PIN vorhanden.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PIN_DOES_NOT_EXIST\" xml:space=\"preserve\">\n    <value>Für das Paket ist keine PIN vorhanden.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_OPEN_PINNING_INDEX\" xml:space=\"preserve\">\n    <value>Die PIN-Datenbank kann nicht geöffnet werden.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Mindestens eine Anwendung konnte nicht installiert werden</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Mindestens eine Anwendung konnte nicht deinstalliert werden</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NOT_ALL_QUERIES_FOUND_SINGLE\" xml:space=\"preserve\">\n    <value>Mindestens eine Abfrage hat nicht genau eine Übereinstimmung zurückgegeben.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_PINNED\" xml:space=\"preserve\">\n    <value>Das Paket verfügt über eine PIN, die ein Upgrade verhindert.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB\" xml:space=\"preserve\">\n    <value>Das derzeit installierte Paket ist das Stubpaket</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_APPTERMINATION_RECEIVED\" xml:space=\"preserve\">\n    <value>Signal zum Herunterfahren der Anwendung empfangen</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_DEPENDENCIES\" xml:space=\"preserve\">\n    <value>Fehler beim Herunterladen von Paketabhängigkeiten.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_COMMAND_PROHIBITED\" xml:space=\"preserve\">\n    <value>Fehler beim Herunterladen des Pakets. Das Herunterladen für die Offlineinstallation ist nicht zulässig.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SERVICE_UNAVAILABLE\" xml:space=\"preserve\">\n    <value>Ein erforderlicher Dienst ist ausgelastet oder nicht verfügbar. Versuchen Sie es später noch einmal.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESUME_ID_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Die angegebene GUID entspricht keinem gültigen Fortsetzungszustand.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CLIENT_VERSION_MISMATCH\" xml:space=\"preserve\">\n    <value>Die aktuelle Clientversion stimmte nicht mit der Clientversion des gespeicherten Zustands überein.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_RESUME_STATE\" xml:space=\"preserve\">\n    <value>Die Daten zum Fortsetzungszustand sind ungültig.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_OPEN_CHECKPOINT_INDEX\" xml:space=\"preserve\">\n    <value>Die Prüfpunktdatenbank kann nicht geöffnet werden.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESUME_LIMIT_EXCEEDED\" xml:space=\"preserve\">\n    <value>Das maximale Fortsetzungslimit wurde überschritten.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_AUTHENTICATION_INFO\" xml:space=\"preserve\">\n    <value>Ungültige Authentifizierungsinformationen.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Authentifizierungsmethode nicht unterstützt.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED\" xml:space=\"preserve\">\n    <value>Fehler bei der Authentifizierung.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_INTERACTIVE_REQUIRED\" xml:space=\"preserve\">\n    <value>Fehler bei der Authentifizierung. Interaktive Authentifizierung erforderlich.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_CANCELLED_BY_USER\" xml:space=\"preserve\">\n    <value>Fehler bei der Authentifizierung. Abbruch durch Benutzer.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_INCORRECT_ACCOUNT\" xml:space=\"preserve\">\n    <value>Fehler bei der Authentifizierung. Das authentifizierte Konto ist nicht das gewünschte Konto.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE\" xml:space=\"preserve\">\n    <value>Die Anwendung wird zurzeit ausgeführt. Beenden Sie die Anwendung, und versuchen Sie es noch mal.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INSTALL_IN_PROGRESS\" xml:space=\"preserve\">\n    <value>Es wird bereits eine andere Installation ausgeführt. Versuchen Sie es später noch mal.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_FILE_IN_USE\" xml:space=\"preserve\">\n    <value>Mindestens eine Datei wird verwendet. Beenden Sie die Anwendung, und versuchen Sie es noch mal.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_MISSING_DEPENDENCY\" xml:space=\"preserve\">\n    <value>Für dieses Paket fehlt eine Abhängigkeit im System.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DISK_FULL\" xml:space=\"preserve\">\n    <value>Auf Ihrem PC ist kein Speicherplatz mehr vorhanden. Geben Sie Speicherplatz frei, und versuchen Sie es noch mal.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INSUFFICIENT_MEMORY\" xml:space=\"preserve\">\n    <value>Es ist nicht genügend Arbeitsspeicher für die Installation verfügbar. Schließen Sie andere Anwendungen, und wiederholen Sie dann den Vorgang.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_NO_NETWORK\" xml:space=\"preserve\">\n    <value>Diese Anwendung erfordert Internetkonnektivität. Stellen Sie eine Netzwerkverbindung her, und versuchen Sie es noch mal.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CONTACT_SUPPORT\" xml:space=\"preserve\">\n    <value>Bei dieser Anwendung ist während der Installation ein Fehler aufgetreten. Wenden Sie sich an den Support.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_TO_FINISH\" xml:space=\"preserve\">\n    <value>Starten Sie den PC neu, um die Installation abzuschließen.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_FOR_INSTALL\" xml:space=\"preserve\">\n    <value>Fehler bei der Installation. Starten Sie Ihren PC neu, und versuchen Sie es noch mal.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_INITIATED\" xml:space=\"preserve\">\n    <value>Ihr PC wird neu gestartet, um die Installation abzuschließen.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CANCELLED_BY_USER\" xml:space=\"preserve\">\n    <value>Sie haben die Installation abgebrochen.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>Eine andere Version dieser Anwendung ist bereits installiert.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DOWNGRADE\" xml:space=\"preserve\">\n    <value>Eine höhere Version dieser Anwendung ist bereits installiert.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>Die Installation wird durch Organisationsrichtlinien verhindert. Wenden Sie sich an Ihren Administrator.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DEPENDENCIES\" xml:space=\"preserve\">\n    <value>Fehler beim Installieren der Paketabhängigkeiten.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE_BY_APPLICATION\" xml:space=\"preserve\">\n    <value>Die Anwendung wird zurzeit von einer anderen Anwendung verwendet.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INVALID_PARAMETER\" xml:space=\"preserve\">\n    <value>Unzulässiger Parameter.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Das Paket wird vom System nicht unterstützt.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_UPGRADE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Das Upgrade eines vorhandenen Pakets wird vom Installationsprogramm nicht unterstützt.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CUSTOM_ERROR\" xml:space=\"preserve\">\n    <value>Die Installation ist mit einem Fehler des benutzerdefinierten Installationsprogramms fehlgeschlagen.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_ARP_ENTRY_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Der Eintrag \"Apps und Features\" für das Paket wurde nicht gefunden.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>Der Installationsspeicherort ist nicht anwendbar.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Der Installationsspeicherort wurde nicht gefunden.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_HASH_MISMATCH\" xml:space=\"preserve\">\n    <value>Der Hash der vorhandenen Datei stimmte nicht überein.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Datei nicht gefunden.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK\" xml:space=\"preserve\">\n    <value>Die Datei wurde gefunden, aber der Hash wurde nicht überprüft.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_ACCESS_ERROR\" xml:space=\"preserve\">\n    <value>Auf die Datei konnte nicht zugegriffen werden.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE\" xml:space=\"preserve\">\n    <value>Die Konfigurationsdatei ist ungültig.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_YAML\" xml:space=\"preserve\">\n    <value>Die YAML-Syntax ist ungültig.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_FIELD_TYPE\" xml:space=\"preserve\">\n    <value>Ein Konfigurationsfeld weist einen ungültigen Typ auf.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION\" xml:space=\"preserve\">\n    <value>Die Konfiguration weist eine unbekannte Version auf.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_SET_APPLY_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Anwenden der Konfiguration.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER\" xml:space=\"preserve\">\n    <value>Die Konfiguration enthält einen doppelten Bezeichner.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MISSING_DEPENDENCY\" xml:space=\"preserve\">\n    <value>In der Konfiguration fehlt eine Abhängigkeit.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED\" xml:space=\"preserve\">\n    <value>Die Konfiguration weist eine nicht erfüllte Abhängigkeit auf.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_ASSERTION_FAILED\" xml:space=\"preserve\">\n    <value>Fehler bei einer Assertion für die Konfigurationseinheit.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MANUALLY_SKIPPED\" xml:space=\"preserve\">\n    <value>Die Konfiguration wurde manuell übersprungen.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_WARNING_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>Der Benutzer hat die Fortsetzung der Ausführung abgelehnt.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_SET_DEPENDENCY_CYCLE\" xml:space=\"preserve\">\n    <value>Die Abhängigkeitsdiagramm enthält einen Zyklus, der nicht aufgelöst werden kann.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_FIELD_VALUE\" xml:space=\"preserve\">\n    <value>Die Konfiguration weist einen ungültigen Feldwert auf.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MISSING_FIELD\" xml:space=\"preserve\">\n    <value>In der Konfiguration fehlt ein Feld.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_TEST_FAILED\" xml:space=\"preserve\">\n    <value>Einige der Konfigurationseinheiten fielen beim Testen ihres Zustands aus.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_TEST_NOT_RUN\" xml:space=\"preserve\">\n    <value>Der Konfigurationsstatus wurde nicht getestet.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_NOT_INSTALLED\" xml:space=\"preserve\">\n    <value>Die Konfigurationseinheit wurde nicht installiert.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_NOT_FOUND_REPOSITORY\" xml:space=\"preserve\">\n    <value>Die Konfigurationseinheit wurde nicht gefunden.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_MULTIPLE_MATCHES\" xml:space=\"preserve\">\n    <value>Für die Konfigurationseinheit wurden mehrere Übereinstimmungen gefunden. geben Sie das Modul an, um das richtige auszuwählen.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_GET\" xml:space=\"preserve\">\n    <value>Fehler der Konfigurationseinheit beim Abrufen des aktuellen Systemstatus.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_TEST\" xml:space=\"preserve\">\n    <value>Fehler bei der Konfigurationseinheit beim Versuch, den aktuellen Systemstatus zu testen.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_SET\" xml:space=\"preserve\">\n    <value>Fehler bei der Konfigurationseinheit beim Anwenden des gewünschten Zustands.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_MODULE_CONFLICT\" xml:space=\"preserve\">\n    <value>Das Modul für die Konfigurationseinheit ist an mehreren Speicherorten mit derselben Version verfügbar.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE\" xml:space=\"preserve\">\n    <value>Fehler beim Laden des Moduls für die Konfigurationseinheit.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_INVALID_RESULT\" xml:space=\"preserve\">\n    <value>Die Konfigurationseinheit hat während der Ausführung ein unerwartetes Ergebnis zurückgegeben.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_SETTING_CONFIG_ROOT\" xml:space=\"preserve\">\n    <value>Eine Einheit enthält eine Einstellung, die den Konfigurationsstamm erfordert.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR\" xml:space=\"preserve\">\n    <value>Der Vorgang wird vom Konfigurationsprozessor nicht unterstützt.</value>\n  </data>\n  <data name=\"Unavailable\" xml:space=\"preserve\">\n    <value>Nicht verfügbar</value>\n  </data>\n  <data name=\"EnableWindowsFeaturesSuccess\" xml:space=\"preserve\">\n    <value>Windows-Featureabhängigkeiten erfolgreich aktiviert</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE_ADMIN\" xml:space=\"preserve\">\n    <value>Fehler beim Laden des Moduls für die Konfigurationseinheit, da für die Ausführung Administratorrechte erforderlich sind.</value>\n  </data>\n  <data name=\"ConfigurationUnitSettingConfigRoot\" xml:space=\"preserve\">\n    <value>Eine Einheit enthält eine Einstellung, die den Konfigurationsstamm erfordert.</value>\n  </data>\n  <data name=\"ConfigurationUnitImportModuleAdmin\" xml:space=\"preserve\">\n    <value>Fehler beim Laden des Moduls für die Konfigurationseinheit, da für die Ausführung Administratorrechte erforderlich sind.</value>\n  </data>\n  <data name=\"ResumeCommandLongDescription\" xml:space=\"preserve\">\n    <value>Setzt die Ausführung eines zuvor gespeicherten Befehls fort, indem der eindeutige Bezeichner des gespeicherten Befehls übergeben wird. Wird verwendet, um einen ausgeführten Befehl fortzusetzen, der möglicherweise aufgrund eines Neustarts beendet wurde.</value>\n  </data>\n  <data name=\"ResumeCommandShortDescription\" xml:space=\"preserve\">\n    <value>Setzt die Ausführung eines zuvor gespeicherten Befehls fort.</value>\n  </data>\n  <data name=\"ResumeIdArgumentDescription\" xml:space=\"preserve\">\n    <value>Der eindeutige Bezeichner des gespeicherten Zustands, der fortgesetzt werden soll</value>\n  </data>\n  <data name=\"ClientVersionMismatchError\" xml:space=\"preserve\">\n    <value>Das Fortsetzen des Status von einer anderen Clientversion wird nicht unterstützt: {0}</value>\n    <comment>{Locked= \"{0}\"} Message displayed to inform the user that the client version of the resume state does not match the current client version. {0} is a placeholder for the client version that created the resume state.</comment>\n  </data>\n  <data name=\"ResumeIdNotFoundError\" xml:space=\"preserve\">\n    <value>Der Fortsetzungszustand ist nicht vorhanden: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a guid that does not correspond to a valid saved state. {0} is a placeholder replaced by the provided guid string.</comment>\n  </data>\n  <data name=\"ResumeStateDataNotFoundError\" xml:space=\"preserve\">\n    <value>Im Fortsetzungszustand wurden keine Daten gefunden.</value>\n  </data>\n  <data name=\"CommandDoesNotSupportResumeMessage\" xml:space=\"preserve\">\n    <value>Dieser Befehl unterstützt das Fortsetzen nicht.</value>\n  </data>\n  <data name=\"AllowRebootArgumentDescription\" xml:space=\"preserve\">\n    <value>Ermöglicht ggf. einen Neustart</value>\n  </data>\n  <data name=\"InitiatingReboot\" xml:space=\"preserve\">\n    <value>Der Neustart zum Abschließen des Vorgangs wird initiiert...</value>\n  </data>\n  <data name=\"FailedToInitiateReboot\" xml:space=\"preserve\">\n    <value>Fehler beim Initiieren eines Neustarts.</value>\n  </data>\n  <data name=\"ResumeLimitExceeded\" xml:space=\"preserve\">\n    <value>Der Fortsetzungsvorgang überschreitet das zulässige Limit von {0} Fortsetzungen. Führen Sie den Befehl \"{1}\" aus, um den Vorgang manuell fortzusetzen.</value>\n    <comment>{Locked=\"{0}\", \"{1}\"} {0} is a placeholder that is replaced by an integer number of the number of allowed resumes. {1} is a placeholder for the command to run to perform a manual resume.</comment>\n  </data>\n  <data name=\"IgnoreResumeLimitArgumentDescription\" xml:space=\"preserve\">\n    <value>Grenzwert beim Fortsetzen eines gespeicherten Zustands ignorieren</value>\n  </data>\n  <data name=\"UriSchemeNotSupported\" xml:space=\"preserve\">\n    <value>Das URI-Schema wird nicht unterstützt: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the provided uri is not supported. {0} is a placeholder replaced by the provided uri.</comment>\n  </data>\n  <data name=\"UriNotWellFormed\" xml:space=\"preserve\">\n    <value>URI nicht wohlgeformt: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the provided uri is not well formed. {0} is a placeholder replaced by the provided uri.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitEmptyContent\" xml:space=\"preserve\">\n    <value>Fehler beim Analysieren {0} Inhalt der Konfigurationseinheitseinstellungen, oder der Einstellungsinhalt ist leer.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder replaced by the input winget configure resource unit type.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitMissingRequiredArg\" xml:space=\"preserve\">\n    <value>{0} Konfigurationseinheit fehlt das erforderliche Argument: {1}</value>\n    <comment>{Locked=\"{0},{1}\"} {0} is a placeholder for the input winget configure resource unit type. {1} is placeholder for the missing arg.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitMissingRecommendedArg\" xml:space=\"preserve\">\n    <value>{0} Konfigurationseinheit fehlt das empfohlene Argument: {1}</value>\n    <comment>{Locked=\"{0},{1}\"} {0} is a placeholder for the input winget configure resource unit type. {1} is placeholder for the missing arg.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitKnownSourceConfliction\" xml:space=\"preserve\">\n    <value>Die WinGetSource-Konfigurationseinheit steht in Konflikt mit einer bekannten Quelle: {0}</value>\n    <comment>{Locked=\"WinGetSource,{0}\"} {0} is a placeholder for the input winget source in the configuration unit settings.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitThirdPartySourceAssertion\" xml:space=\"preserve\">\n    <value>Die WinGetSource-Konfigurationseinheit wird für eine Drittanbieterquelle bestätigt: {0}</value>\n    <comment>{Locked=\"WinGetSource,{0}\"} {0} is a placeholder for the input winget source in the configuration unit settings.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitBothPackageVersionAndUseLatest\" xml:space=\"preserve\">\n    <value>WinGetPackage deklariert sowohl UseLatest als auch Version. Paket-ID: {0}</value>\n    <comment>{Locked=\"WinGetPackage,UseLatest,Version,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitThirdPartySourceAssertionForPackage\" xml:space=\"preserve\">\n    <value>Die WinGetPackage-Konfigurationseinheit bestätigt ein Paket aus einer Drittanbieterquelle. Paket-ID: {0}; Quelle: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitDependencySourceNotConfigured\" xml:space=\"preserve\">\n    <value>Das Paket der WinGetPackage-Konfigurationseinheit ist von einer Drittanbieterquelle abhängig, die noch nicht konfiguriert wurde. Paket-ID: {0}; Quelle: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitDependencySourceNotDeclaredAsDependency\" xml:space=\"preserve\">\n    <value>Das Paket der WinGetPackage-Konfigurationseinheit ist von einer Drittanbieterquelle abhängig. Es wird empfohlen, die Abhängigkeit im Abschnitt \"uni dependsOn\" zu deklarieren. Paket-ID: {0}; Quelle: {1}</value>\n    <comment>{Locked=\"WinGetPackage,dependsOn,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageSourceOpenFailed\" xml:space=\"preserve\">\n    <value>Das Paket der WinGetPackage-Konfigurationseinheit kann nicht überprüft werden. Fehler beim Öffnen der Quelle. Paket-ID: {0}; Quelle: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageNotFound\" xml:space=\"preserve\">\n    <value>Das Paket der WinGetPackage-Konfigurationseinheit kann nicht überprüft werden. Das Paket wurde nicht gefunden. Paket-ID: {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageMultipleFound\" xml:space=\"preserve\">\n    <value>Das Paket der WinGetPackage-Konfigurationseinheit kann nicht überprüft werden. Es wurden mehrere Pakete gefunden. Paket-ID: {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageVersionNotFound\" xml:space=\"preserve\">\n    <value>Das Paket der WinGetPackage-Konfigurationseinheit kann nicht überprüft werden. Die Paketversion wurde nicht gefunden. Paket-ID: {0}; Version {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitPackageVersionSpecifiedWithOnlyOnePackageVersion\" xml:space=\"preserve\">\n    <value>Das Paket der WinGetPackage-Konfigurationseinheit wurde mit einer bestimmten Version angegeben, es ist jedoch nur eine Paketversion verfügbar. Paket-ID:{0}; Version: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackage\" xml:space=\"preserve\">\n    <value>Das Paket der WinGetPackage-Konfigurationseinheit kann nicht überprüft werden. Paket-ID: {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"AuthenticationModeArgumentDescription\" xml:space=\"preserve\">\n    <value>Einstellung für Authentifizierungsfenster angeben („silent“, „silentPreferred“ oder „interactive“)</value>\n    <comment>{Locked=\"silent\",\"silentPreferred\",\"interactive\"} This argument allows the user to select authentication window popup behavior.</comment>\n  </data>\n  <data name=\"AuthenticationAccountArgumentDescription\" xml:space=\"preserve\">\n    <value>Geben Sie das Konto an, das für die Authentifizierung verwendet werden soll</value>\n  </data>\n  <data name=\"SourceAddFailedAuthenticationNotSupported\" xml:space=\"preserve\">\n    <value>Fehler beim Hinzufügen der Quelle. Diese winget Version unterstützt die Authentifizierungsmethode der Quelle nicht. Versuchen Sie, ein Upgrade auf die neueste winget Version durchzuführen.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"SourceRequiresAuthentication\" xml:space=\"preserve\">\n    <value>Für die {0} Quelle ist eine Authentifizierung erforderlich. Bei Bedarf wird möglicherweise eine Authentifizierungsaufforderung angezeigt. Authentifizierte Informationen werden für die Zugriffsautorisierung mit der Quelle geteilt.</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"RepairCommandLongDescription\" xml:space=\"preserve\">\n    <value>Repariert das ausgewählte Paket, entweder durch Durchsuchen der Liste der installierten Pakete oder direkt aus einem Manifest. Standardmäßig muss die Abfrage ohne Berücksichtigung der Groß-/Kleinschreibung mit der ID, dem Namen oder dem Moniker des Pakets übereinstimmen. Andere Felder können verwendet werden, indem sie die entsprechende Option übergeben.</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"RepairCommandShortDescription\" xml:space=\"preserve\">\n    <value>Repariert das ausgewählte Paket</value>\n  </data>\n  <data name=\"NoRepairInfoFound\" xml:space=\"preserve\">\n    <value>Der Reparaturbefehl für dieses Paket wurde nicht gefunden. Wenden Sie sich an den Paketherausgeber, um Unterstützung zu erfahren.</value>\n  </data>\n  <data name=\"RepairDifferentInstallTechnology\" xml:space=\"preserve\">\n    <value>Die verwendete Installertechnologie stimmt nicht mit der derzeit installierten Version überein.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_REPAIR_INFO_FOUND\" xml:space=\"preserve\">\n    <value>Der Reparaturbefehl wurde nicht gefunden.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_REPAIR_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Die verwendete Installationstechnologie unterstützt keine Reparatur.</value>\n  </data>\n  <data name=\"RepairFlowRepairSuccess\" xml:space=\"preserve\">\n    <value>Der Reparaturvorgang wurde erfolgreich abgeschlossen.</value>\n  </data>\n  <data name=\"RepairAbandoned\" xml:space=\"preserve\">\n    <value>Reparatur abgebrochen</value>\n  </data>\n  <data name=\"RepairFlowStartingPackageRepair\" xml:space=\"preserve\">\n    <value>Paketreparatur wird gestartet...</value>\n  </data>\n  <data name=\"MSStoreRepairFailed\" xml:space=\"preserve\">\n    <value>Fehler beim Reparieren des Microsoft Store-Pakets. Fehlercode: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Microsoft Store application package fails to repair. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXEC_REPAIR_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Reparaturvorgang.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_REPAIR_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>Der Reparaturvorgang ist nicht anwendbar.</value>\n  </data>\n  <data name=\"RepairFlowNoMatchingVersion\" xml:space=\"preserve\">\n    <value>In den konfigurierten Quellen sind keine übereinstimmenden Paketversionen verfügbar.</value>\n  </data>\n  <data name=\"RepairFlowReturnCodeSystemNotSupported\" xml:space=\"preserve\">\n    <value>Die Reparatur dieses Pakets wird von der aktuellen Systemkonfiguration nicht unterstützt.</value>\n  </data>\n  <data name=\"RepairOperationNotSupported\" xml:space=\"preserve\">\n    <value>Die verwendete Installationstechnologie unterstützt keine Reparatur.</value>\n  </data>\n  <data name=\"NoAdminRepairForUserScopePackage\" xml:space=\"preserve\">\n    <value>Das für den Benutzerbereich installierte Paket kann nicht repariert werden, wenn es mit Administratorrechten ausgeführt wird.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED\" xml:space=\"preserve\">\n    <value>Reparaturvorgänge mit Administratorrechten sind für Pakete, die innerhalb des Benutzerbereichs installiert sind, nicht zulässig.</value>\n  </data>\n  <data name=\"RepairFailedWithCode\" xml:space=\"preserve\">\n    <value>Fehler bei der Reparatur mit Exitcode: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to repair an application package fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SQLITE_CONNECTION_TERMINATED\" xml:space=\"preserve\">\n    <value>Die SQLite-Verbindung wurde beendet, um Beschädigungen zu verhindern.</value>\n  </data>\n  <data name=\"UninstallAllVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Alle Versionen deinstallieren</value>\n  </data>\n  <data name=\"TargetVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>Die Version, auf die reagiert werden soll</value>\n  </data>\n  <data name=\"UninstallFailedDueToMultipleVersions\" xml:space=\"preserve\">\n    <value>Mehrere Versionen dieses Pakets sind installiert. Verfeinern Sie die Suche, übergeben Sie das Argument \"--version\", um eines auszuwählen, oder übergeben Sie das Flag \"--all-versions\", um alle zu deinstallieren.</value>\n    <comment>{Locked=\"--version,--all-versions\"}</comment>\n  </data>\n  <data name=\"PolicyEnableProxyCommandLineOptions\" xml:space=\"preserve\">\n    <value>Befehlszeilenoptionen für Windows-Paket-Manager Proxy aktivieren</value>\n    <comment>Describes a Group Policy that can enable the use of the --proxy option to set a proxy</comment>\n  </data>\n  <data name=\"ProxyArgumentDescription\" xml:space=\"preserve\">\n    <value>Legen Sie einen Proxy fest, der für diese Ausführung verwendet werden soll.</value>\n  </data>\n  <data name=\"NoProxyArgumentDescription\" xml:space=\"preserve\">\n    <value>Verwendung des Proxys für diese Ausführung deaktivieren</value>\n  </data>\n  <data name=\"ResetAdminSettingFailed\" xml:space=\"preserve\">\n    <value>{0} kann nicht zurückgesetzt werden. Diese Einstellung wird durch eine Richtlinie gesteuert. Wenden Sie sich an den Systemadministrator, um weitere Informationen zu erfahren.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"ResetAdminSettingSucceeded\" xml:space=\"preserve\">\n    <value>Administratoreinstellung „{0}“ zurücksetzen.</value>\n    <comment>{Locked=\"{0}\"} Message displayed after the user resets an admin setting to its default value. Reset is used as verb in past tense. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"SetAdminSettingFailed\" xml:space=\"preserve\">\n    <value>{0} kann nicht festgelegt werden. Diese Einstellung wird durch eine Richtlinie gesteuert. Wenden Sie sich an den Systemadministrator, um weitere Informationen zu erfahren.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"SetAdminSettingSucceeded\" xml:space=\"preserve\">\n    <value>Legen Sie die Administratoreinstellung „{0}“ auf „{1}“ fest.</value>\n    <comment>{Locked=\"{0}\"} Message displayed after the user sets the value of an admin setting. Set is used as a verb in past tense. {0} is a placeholder replaced by the setting name. {1} is a placeholder replaced </comment>\n  </data>\n  <data name=\"SettingNameArgumentDescription\" xml:space=\"preserve\">\n    <value>Name der zu ändernden Einstellung</value>\n  </data>\n  <data name=\"SettingValueArgumentDescription\" xml:space=\"preserve\">\n    <value>Wert, der für die Einstellung festgelegt werden soll.</value>\n  </data>\n  <data name=\"SettingsResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>Setzt eine Administratoreinstellung auf den Standardwert zurück.</value>\n  </data>\n  <data name=\"SettingsResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>Setzt eine Administratoreinstellung auf den Standardwert zurück.</value>\n  </data>\n  <data name=\"SettingsSetCommandLongDescription\" xml:space=\"preserve\">\n    <value>Legt den Wert einer Administratoreinstellung fest.</value>\n  </data>\n  <data name=\"SettingsSetCommandShortDescription\" xml:space=\"preserve\">\n    <value>Legt den Wert einer Administratoreinstellung fest.</value>\n  </data>\n  <data name=\"SourceExplicitArgumentDescription\" xml:space=\"preserve\">\n    <value>Schließt eine Quelle aus der Ermittlung aus, sofern keine Angabe erfolgt.</value>\n  </data>\n  <data name=\"SourceEditExplicitArgumentDescription\" xml:space=\"preserve\">\n    <value>Schließt eine Quelle aus der Ermittlung aus (TRUE oder FALSE).</value>\n  </data>\n  <data name=\"SourceListExplicit\" xml:space=\"preserve\">\n    <value>Anstößig</value>\n  </data>\n  <data name=\"SourceTrustLevelArgumentDescription\" xml:space=\"preserve\">\n    <value>Vertrauensebene der Quelle (keine oder vertrauenswürdig)</value>\n  </data>\n  <data name=\"SourceListTrustLevel\" xml:space=\"preserve\">\n    <value>Vertrauensebene</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DISPLAYCATALOG_API_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Abrufen des Microsoft Store-Paketkatalogs.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_DISPLAYCATALOG_PACKAGE\" xml:space=\"preserve\">\n    <value>In Microsoft Store-Paketkatalog wurde kein anwendbares Microsoft Store-Paket gefunden.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SFSCLIENT_API_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Abrufen von Microsoft Store Paketdownloadinformationen.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_SFSCLIENT_PACKAGE\" xml:space=\"preserve\">\n    <value>Es wurde kein anwendbares Microsoft Store Paket zum Download gefunden.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Abrufen der Microsoft Store-Paketlizenz.</value>\n  </data>\n  <data name=\"MSStoreDownloadNoApplicablePackageFound\" xml:space=\"preserve\">\n    <value>Es wurde kein anwendbares Microsoft Store-Paket gefunden.</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageHashVerified\" xml:space=\"preserve\">\n    <value>Der Pakethash für Microsoft Store wurde erfolgreich überprüft.</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageHashMismatch\" xml:space=\"preserve\">\n    <value>Microsoft Store Pakethashkonflikt</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloaded\" xml:space=\"preserve\">\n    <value>Microsoft Store heruntergeladenes Paket: {0}</value>\n    <comment>{Locked=\"{0}\"} Full path of the downloaded package.</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadFailed\" xml:space=\"preserve\">\n    <value>Fehler beim Herunterladen des Microsoft Store-Pakets: {0}</value>\n    <comment>{Locked=\"{0}\"} Package name.</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadSuccess\" xml:space=\"preserve\">\n    <value>Microsoft Store-Paketdownload abgeschlossen</value>\n  </data>\n  <data name=\"MSStoreDownloadMainPackages\" xml:space=\"preserve\">\n    <value>Hauptpakete werden von Microsoft Store heruntergeladen...</value>\n  </data>\n  <data name=\"MSStoreDownloadDependencyPackages\" xml:space=\"preserve\">\n    <value>Abhängigkeitspakete werden von Microsoft Store heruntergeladen...</value>\n  </data>\n  <data name=\"MSStoreDownloadGetDownloadInfo\" xml:space=\"preserve\">\n    <value>Microsoft Store-Paketdownloadinformationen werden abgerufen</value>\n  </data>\n  <data name=\"MSStoreDownloadGetDownloadInfoFailed\" xml:space=\"preserve\">\n    <value>Fehler beim Abrufen von Microsoft Store Paketdownloadinformationen</value>\n  </data>\n  <data name=\"MSStoreDownloadGetLicense\" xml:space=\"preserve\">\n    <value>Microsoft Store Paketlizenz wird abgerufen</value>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseSuccess\" xml:space=\"preserve\">\n    <value>Microsoft Store-Paketlizenz gespeichert: {0}</value>\n    <comment>{Locked=\"{0}\"} License file full path.</comment>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseFailed\" xml:space=\"preserve\">\n    <value>Fehler beim Abrufen der Microsoft Store-Paketlizenz</value>\n  </data>\n  <data name=\"MSStoreDownloadRenameNotSupported\" xml:space=\"preserve\">\n    <value>Microsoft Store Paketdownload unterstützt das Argument --rename nicht. Microsoft Store-Paket verwendet Namen, die von Microsoft Store-Katalog bereitgestellt werden.</value>\n    <comment>{Locked=\"--rename\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadAuthenticationNotice\" xml:space=\"preserve\">\n    <value>Microsoft Store Paketdownload erfordert Microsoft Entra-ID-Authentifizierung. Bei Bedarf wird möglicherweise eine Authentifizierungsaufforderung angezeigt. Authentifizierte Informationen werden für Microsoft-Dienste zur Zugriffsautorisierung freigegeben. Für Microsoft Store Paketlizenzierung muss das Microsoft Entra-ID-Konto Mitglied des globalen Administrators, Benutzeradministrators oder Lizenzadministrators sein.</value>\n    <comment>{Locked=\"Global Administrator,User Administrator,License Administrator\"}</comment>\n  </data>\n  <data name=\"SkipMicrosoftStorePackageLicenseArgumentDescription\" xml:space=\"preserve\">\n    <value>Überspringt das Abrufen der Offlinelizenz des Microsoft Store-Pakets</value>\n  </data>\n  <data name=\"PlatformArgumentDescription\" xml:space=\"preserve\">\n    <value>Zielplattform auswählen</value>\n  </data>\n  <data name=\"ConfigurationExportAddingToFile\" xml:space=\"preserve\">\n    <value>Konfigurationsdatei wird hinzugefügt: {0}</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportSuccessful\" xml:space=\"preserve\">\n    <value>Erfolgreich exportiert</value>\n  </data>\n  <data name=\"ConfigurationGettingResourceSettings\" xml:space=\"preserve\">\n    <value>Konfigurationseinstellungen werden abgerufen...</value>\n  </data>\n  <data name=\"ConfigureExportArgumentRequiredError\" xml:space=\"preserve\">\n    <value>Es müssen mindestens „--packageId“ und/oder „--module“ mit „--resource“ angegeben werden. Alternativ können Sie „--all“ verwenden, um alle Paketkonfigurationen zu exportieren.</value>\n    <comment>{Locked=\"--packageId,--module, --resource, --all\"}</comment>\n  </data>\n  <data name=\"ConfigureExportArgumentConflictWithAllError\" xml:space=\"preserve\">\n    <value>Die Argumente „--packageId“, „--module“ und „--resource“ können nicht zusammen mit „--all“ verwendet werden.</value>\n    <comment>{Locked=\"--packageId,--module, --resource, --all\"}</comment>\n  </data>\n  <data name=\"ConfigureExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Exportiert Konfigurationsressourcen in eine Konfigurationsdatei. Bei Verwendung mit \"--all\" werden alle Paketkonfigurationen exportiert. Bei Verwendung mit \"--packageId\" wird eine WinGetPackage-Ressource der angegebenen Paket-ID exportiert. Bei Verwendung mit \"--module\" und \"--resource\" werden die Einstellungen der Ressource abgerufen und in die Konfigurationsdatei exportiert. Wenn die Ausgabekonfigurationsdatei bereits vorhanden ist, werden die exportierten Konfigurationsressourcen angefügt.</value>\n    <comment>{Locked=\"WinGetPackage,--packageId,--module, --resource\"}</comment>\n  </data>\n  <data name=\"ConfigureExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Exportiert Konfigurationsressourcen in eine Konfigurationsdatei.</value>\n  </data>\n  <data name=\"ConfigureExportModule\" xml:space=\"preserve\">\n    <value>Das Modul der zu exportierenden Ressource.</value>\n  </data>\n  <data name=\"ConfigureExportPackageId\" xml:space=\"preserve\">\n    <value>Der zu exportierende Paketbezeichner.</value>\n  </data>\n  <data name=\"ConfigureExportResource\" xml:space=\"preserve\">\n    <value>Die zu exportierende Konfigurationsressource.</value>\n  </data>\n  <data name=\"ConfigureExportAll\" xml:space=\"preserve\">\n    <value>Exportiert alle Paketkonfigurationen.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_GET_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Abrufen der Eigenschaften der Konfigurationseinheit.</value>\n  </data>\n  <data name=\"ConfigurationExportFailed\" xml:space=\"preserve\">\n    <value>Fehler beim Exportieren der Konfiguration.</value>\n  </data>\n  <data name=\"ConfigureExportUnitDescription\" xml:space=\"preserve\">\n    <value>\"{0}\" konfigurieren</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigureExportUnitInstallDescription\" xml:space=\"preserve\">\n    <value>{0}Installieren</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationWarningSetViewTruncated\" xml:space=\"preserve\">\n    <value>Einige der in der Konfigurationsdatei vorhandenen Daten wurden für diese Ausgabe abgeschnitten. überprüfen Sie den Dateiinhalt auf den vollständigen Inhalt.</value>\n  </data>\n  <data name=\"ConfigurationWarningValueTruncated\" xml:space=\"preserve\">\n    <value>&lt;dieser Wert wurde abgeschnitten; überprüfen Sie den Dateiinhalt auf den vollständigen Text&gt;</value>\n    <comment>Keep some form of separator like the \"&lt;&gt;\" around the text so that it stands out from the preceding text.</comment>\n  </data>\n  <data name=\"ConfigureListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Zeigt die Details der obersten Ebene für Konfigurationen an, die auf das System angewendet wurden. Diese Daten können dann mit `configure` Befehlen verwendet werden, um weitere Details zu erhalten.</value>\n    <comment>{Locked=\"`configure`\"}</comment>\n  </data>\n  <data name=\"ConfigureListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Zeigt den Konfigurationsverlauf an.</value>\n  </data>\n  <data name=\"ConfigurationHistoryEmpty\" xml:space=\"preserve\">\n    <value>Im Verlauf sind keine Konfigurationen vorhanden.</value>\n  </data>\n  <data name=\"ConfigurationHistoryItemArgumentDescription\" xml:space=\"preserve\">\n    <value>Elemente aus dem Verlauf auswählen</value>\n  </data>\n  <data name=\"ConfigurationHistoryItemNotFound\" xml:space=\"preserve\">\n    <value>Es wurde keine einzelne Konfiguration gefunden, die mit den angegebenen Daten übereinstimmt. Geben Sie entweder den vollständigen Namen oder einen Teil des Bezeichners an, der eindeutig mit der gewünschten Konfiguration übereinstimmt.</value>\n  </data>\n  <data name=\"ConfigurationHistoryRemoveArgumentDescription\" xml:space=\"preserve\">\n    <value>Element aus Verlauf entfernen</value>\n  </data>\n  <data name=\"ConfigureListFirstApplied\" xml:space=\"preserve\">\n    <value>Zuerst angewendet</value>\n    <comment>Column header for date values indicating when a configuration was first applied to the system.</comment>\n  </data>\n  <data name=\"ConfigureListIdentifier\" xml:space=\"preserve\">\n    <value>Bezeichner</value>\n  </data>\n  <data name=\"ConfigureListName\" xml:space=\"preserve\">\n    <value>Name</value>\n  </data>\n  <data name=\"ConfigureListOrigin\" xml:space=\"preserve\">\n    <value>Ursprung</value>\n  </data>\n  <data name=\"ConfigureListPath\" xml:space=\"preserve\">\n    <value>Pfad</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_HISTORY_ITEM_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Die angegebene Konfiguration wurde nicht gefunden.</value>\n  </data>\n  <data name=\"ConfigurationSetStateCompleted\" xml:space=\"preserve\">\n    <value>Abgeschlossen</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStateInProgress\" xml:space=\"preserve\">\n    <value>In Bearbeitung</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStatePending\" xml:space=\"preserve\">\n    <value>Ausstehend</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStateUnknown\" xml:space=\"preserve\">\n    <value>Unbekannt</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationStatusWatchArgumentDescription\" xml:space=\"preserve\">\n    <value>Konfigurationsstatus überwachen.</value>\n    <comment>As in \"to monitor the status of a configuration being applied\".</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateCompleted\" xml:space=\"preserve\">\n    <value>Abgeschlossen</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateInProgress\" xml:space=\"preserve\">\n    <value>In Bearbeitung</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStatePending\" xml:space=\"preserve\">\n    <value>Ausstehend</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateSkipped\" xml:space=\"preserve\">\n    <value>Übersprungen</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateUnknown\" xml:space=\"preserve\">\n    <value>Unbekannt</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigureListApplyBegun\" xml:space=\"preserve\">\n    <value>Gestartet anwenden</value>\n    <comment>When the configuration application started.</comment>\n  </data>\n  <data name=\"ConfigureListApplyEnded\" xml:space=\"preserve\">\n    <value>Beendet anwenden</value>\n    <comment>When the configuration application ended.</comment>\n  </data>\n  <data name=\"ConfigureListResult\" xml:space=\"preserve\">\n    <value>Ergebnis</value>\n  </data>\n  <data name=\"ConfigureListResultDescription\" xml:space=\"preserve\">\n    <value>Details</value>\n  </data>\n  <data name=\"ConfigureListState\" xml:space=\"preserve\">\n    <value>Bundesland</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigureListUnit\" xml:space=\"preserve\">\n    <value>Einheit</value>\n  </data>\n  <data name=\"StoreInstall_PackageNotAvailableForCurrentSystem\" xml:space=\"preserve\">\n    <value>Das Paket ist nicht mit der aktuellen Windows-Version oder -Plattform kompatibel.</value>\n  </data>\n  <data name=\"ConfigurationSuppressPrologueArgumentDescription\" xml:space=\"preserve\">\n    <value>Anzeige von Details zur Erstkonfiguration nach Möglichkeit unterdrücken</value>\n  </data>\n  <data name=\"MSStoreDownloadMultiplePackagesNotice\" xml:space=\"preserve\">\n    <value>Mehrere Microsoft Store können für unterschiedliche Plattformen und Architekturen heruntergeladen werden. --platform, --architecture kann zum Filtern der Pakete verwendet werden.</value>\n    <comment>{Locked=\"--platform--architecture\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseForbidden\" xml:space=\"preserve\">\n    <value>Fehler beim Abrufen Microsoft Store Paketlizenz. Das Microsoft Entra-ID-Konto ist kein Mitglied des globalen Administrators, Benutzeradministrators oder Lizenzadministrators. Verwenden Sie \"--skip-license\", um das Abrufen Microsoft Store Paketlizenz zu überspringen.</value>\n    <comment>{Locked=\"Global Administrator,User Administrator,License Administrator,--skip-license\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadNotSupported\" xml:space=\"preserve\">\n    <value>Das Microsoft Store Paket unterstützt keinen Download.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SFSCLIENT_PACKAGE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Das Microsoft Store Paket unterstützt keinen Download.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED_FORBIDDEN\" xml:space=\"preserve\">\n    <value>Fehler beim Abrufen Microsoft Store Paketlizenz. Das Microsoft Entra-ID-Konto verfügt nicht über die erforderlichen Berechtigungen.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_PARAMETER_INTEGRITY_BOUNDARY\" xml:space=\"preserve\">\n    <value>Der Parameter kann nicht über die Integritätsgrenze hinweg übergeben werden.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_ZERO_BYTE_FILE\" xml:space=\"preserve\">\n    <value>Das Zero-Byte-Installationsprogramm wurde heruntergeladen. stellen Sie sicher, dass die Netzwerkverbindung ordnungsgemäß funktioniert.</value>\n  </data>\n  <data name=\"InstallerZeroByteFile\" xml:space=\"preserve\">\n    <value>Das Zero-Byte-Installationsprogramm wurde heruntergeladen. stellen Sie sicher, dass die Netzwerkverbindung ordnungsgemäß funktioniert.</value>\n  </data>\n  <data name=\"FontCommandShortDescription\" xml:space=\"preserve\">\n    <value>Schriftarten verwalten</value>\n  </data>\n  <data name=\"FontCommandLongDescription\" xml:space=\"preserve\">\n    <value>Verwalten sie Schriftarten mit Unterbefehlen. Schriftarten können ähnlich wie Pakete installiert, aktualisiert oder deinstalliert werden. </value>\n  </data>\n  <data name=\"FontFamily\" xml:space=\"preserve\">\n    <value>Familie</value>\n  </data>\n  <data name=\"FontFaces\" xml:space=\"preserve\">\n    <value>Gesichter</value>\n    <comment>\"Faces\" represents the typeface of the font family such as 'Bold' or 'Italic'</comment>\n  </data>\n  <data name=\"FontFamilyNameArgumentDescription\" xml:space=\"preserve\">\n    <value>Ergebnisse nach Familienname filtern</value>\n  </data>\n  <data name=\"FontFace\" xml:space=\"preserve\">\n    <value>Gesicht</value>\n    <comment>\"Face\" represents the typeface of a font family such as 'Bold' or 'Italic'</comment>\n  </data>\n  <data name=\"FontFilePaths\" xml:space=\"preserve\">\n    <value>Pfade</value>\n  </data>\n  <data name=\"NoInstalledFontFound\" xml:space=\"preserve\">\n    <value>Es wurde keine installierte Schriftart gefunden, die den Eingabekriterien entspricht.</value>\n  </data>\n  <data name=\"FontListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Installierte Schriftarten auflisten</value>\n  </data>\n  <data name=\"FontListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Listet alle installierten Schriftarten, alle Schriftartdateien oder vollständige Details einer bestimmten Schriftart auf.</value>\n  </data>\n  <data name=\"FontVersion\" xml:space=\"preserve\">\n    <value>Version</value>\n  </data>\n  <data name=\"ConfigurationModules\" xml:space=\"preserve\">\n    <value>Konfigurationsmodule</value>\n    <comment>PowerShell Modules that are used for the Configuration feature</comment>\n  </data>\n  <data name=\"InstallerDownloadRequiresAuthentication\" xml:space=\"preserve\">\n    <value>Das Paketinstallationsprogramm erfordert eine Authentifizierung. Bei Bedarf wird möglicherweise eine Authentifizierungsaufforderung angezeigt. Authentifizierte Informationen werden mit der Download-URL des Installers geteilt.</value>\n  </data>\n  <data name=\"InstallerDownloadAuthenticationNotSupported\" xml:space=\"preserve\">\n    <value>Fehler beim Herunterladen des Installers. Diese winget Version unterstützt die Downloadauthentifizierungsmethode des Installers nicht. Versuchen Sie, ein Upgrade auf die neueste winget Version durchzuführen.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"InstallerDownloadAuthenticationFailed\" xml:space=\"preserve\">\n    <value>Fehler beim Herunterladen des Installationsprogramms. Fehler bei der Authentifizierung.</value>\n  </data>\n  <data name=\"ConfigurationProcessorPath\" xml:space=\"preserve\">\n    <value>Pfad zum Konfigurationsprozessor angeben</value>\n  </data>\n  <data name=\"DscCommandShortDescription\" xml:space=\"preserve\">\n    <value>DSC v3-Ressourcenbefehle</value>\n    <comment>DSC stands for \"Desired State Configuration\". It should already have a locked translation.</comment>\n  </data>\n  <data name=\"DscCommandLongDescription\" xml:space=\"preserve\">\n    <value>Die untergeordneten Befehle implementieren Desired State Configuration (DSC) v3-Ressourcen zur Konfiguration von WinGet und Paketen.</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionGet\" xml:space=\"preserve\">\n    <value>Abrufen des Ressourcenstatus</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionSet\" xml:space=\"preserve\">\n    <value>Festlegen des Ressourcenstatus</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionWhatIf\" xml:space=\"preserve\">\n    <value>Beschreiben erforderlicher Zustandsänderungen</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionTest\" xml:space=\"preserve\">\n    <value>Testen des Ressourcenstatus</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionDelete\" xml:space=\"preserve\">\n    <value>Löschen des Ressourcenstatus</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionExport\" xml:space=\"preserve\">\n    <value>Abrufen aller Zustandsinstanzen</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionValidate\" xml:space=\"preserve\">\n    <value>Überprüfen von Gruppeninhalten</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionResolve\" xml:space=\"preserve\">\n    <value>Externen Zustand auflösen</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionAdapter\" xml:space=\"preserve\">\n    <value>Ausführen des Adapters</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionSchema\" xml:space=\"preserve\">\n    <value>Abrufen des Ressourcenschemas</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionManifest\" xml:space=\"preserve\">\n    <value>Abrufen des Ressourcenmanifests</value>\n  </data>\n  <data name=\"DscPackageResourceShortDescription\" xml:space=\"preserve\">\n    <value>Paketstatus verwalten</value>\n  </data>\n  <data name=\"DscPackageResourceLongDescription\" xml:space=\"preserve\">\n    <value>Pakete über WinGet verwalten.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionExist\" xml:space=\"preserve\">\n    <value>Gibt an, ob eine Instanz vorhanden oder vorhanden sein soll.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionInDesiredState\" xml:space=\"preserve\">\n    <value>Gibt an, ob sich eine Instanz im gewünschten Zustand befindet.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageId\" xml:space=\"preserve\">\n    <value>Der Bezeichner des Pakets.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageSource\" xml:space=\"preserve\">\n    <value>Die Quelle des Pakets.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageVersion\" xml:space=\"preserve\">\n    <value>Die Version des Pakets.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageMatchOption\" xml:space=\"preserve\">\n    <value>Die Methode zum Abgleichen des Bezeichners mit einem Paket.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageUseLatest\" xml:space=\"preserve\">\n    <value>Geben Sie an, dass die neueste verfügbare Version des Pakets installiert werden soll.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageInstallMode\" xml:space=\"preserve\">\n    <value>Der Installationsmodus, der bei Bedarf verwendet werden soll.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageScope\" xml:space=\"preserve\">\n    <value>Der Zielbereich des Pakets.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionAcceptAgreements\" xml:space=\"preserve\">\n    <value>Gibt an, ob Vereinbarungen für Quellen und Pakete akzeptiert werden sollen.</value>\n  </data>\n  <data name=\"DscUserSettingsFileShortDescription\" xml:space=\"preserve\">\n    <value>Verwalten der Benutzereinstellungsdatei</value>\n  </data>\n  <data name=\"DscUserSettingsFileLongDescription\" xml:space=\"preserve\">\n    <value>Verwalten Sie die Benutzereinstellungen von WinGet.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionUserSettingsFileSettings\" xml:space=\"preserve\">\n    <value>Der Inhalt der JSON-Einstellungsdatei.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionUserSettingsFileAction\" xml:space=\"preserve\">\n    <value>Die Aktion, die zum Anwenden der Einstellungen verwendet wird.</value>\n  </data>\n  <data name=\"CorrelationArgumentDescription\" xml:space=\"preserve\">\n    <value>Der Wert wird zur Korrelation protokolliert.</value>\n  </data>\n  <data name=\"DscSourceResourceShortDescription\" xml:space=\"preserve\">\n    <value>Quellkonfiguration verwalten</value>\n  </data>\n  <data name=\"DscSourceResourceLongDescription\" xml:space=\"preserve\">\n    <value>Verwalten Sie die Quellen von WinGet.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceName\" xml:space=\"preserve\">\n    <value>Der Name, der für die Quelle verwendet werden soll.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceArgument\" xml:space=\"preserve\">\n    <value>Das Argument für die Quelle.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceType\" xml:space=\"preserve\">\n    <value>Der Typ der Quelle.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceTrustLevel\" xml:space=\"preserve\">\n    <value>Die Vertrauensebene der Quelle.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceExplicit\" xml:space=\"preserve\">\n    <value>Gibt an, ob die Quelle eingeschlossen wird, wenn anrufe keine Quelle angeben.</value>\n  </data>\n  <data name=\"ConfigurationApplyingUnit\" xml:space=\"preserve\">\n    <value>Konfigurationseinheit wird angewendet...</value>\n  </data>\n  <data name=\"ConfigurationExportingUnit\" xml:space=\"preserve\">\n    <value>Konfigurationseinheit wird exportiert...</value>\n  </data>\n  <data name=\"ConfigurationGettingUnitProcessors\" xml:space=\"preserve\">\n    <value>Prozessoren der Konfigurationseinheit werden abgerufen...</value>\n  </data>\n  <data name=\"ConfigurationExportInstallRequiredModule\" xml:space=\"preserve\">\n    <value>Erforderliches Modul für den Export [{0}] sicherstellen</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportInstallRequiredModuleFailed\" xml:space=\"preserve\">\n    <value>Fehler beim Testen oder Abrufen des erforderlichen Moduls. Verwandte Einstellungen werden nicht exportiert.</value>\n  </data>\n  <data name=\"ConfigurationExportUnitStart\" xml:space=\"preserve\">\n    <value>Export [{0}]</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportUnitFailed\" xml:space=\"preserve\">\n    <value>Fehler beim Exportieren der Ressource.</value>\n  </data>\n  <data name=\"ConfigurationExportFailedToGetUnitProcessors\" xml:space=\"preserve\">\n    <value>Fehler beim Abrufen von Einheitenprozessoren. Einzelne Paketeinstellungen werden nicht exportiert.</value>\n  </data>\n  <data name=\"OutputDirectoryArgumentDescription\" xml:space=\"preserve\">\n    <value>Verzeichnis, in das die Ergebnisse geschrieben werden sollen</value>\n  </data>\n  <data name=\"ConfigurationInstallDscPackage\" xml:space=\"preserve\">\n    <value>Desired State Configuration Paket wurde im System nicht gefunden. Paket wird installiert...</value>\n  </data>\n  <data name=\"ConfigurationInstallDscPackageFailed\" xml:space=\"preserve\">\n    <value>Fehler beim Installieren Desired State Configuration Pakets. Installieren Sie das Paket manuell, oder geben Sie den Pfad zum dsc.exe über --processor-path Argument an.</value>\n    <comment>{Locked=\"dsc.exe\",\"--processor-path\"}</comment>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionAdminSettingsSettings\" xml:space=\"preserve\">\n    <value>Ein Objekt, das die Administratoreinstellungen und deren Werte enthält.</value>\n  </data>\n  <data name=\"DscAdminSettingsResourceShortDescription\" xml:space=\"preserve\">\n    <value>Administratoreinstellungen verwalten</value>\n  </data>\n  <data name=\"DscAdminSettingsResourceLongDescription\" xml:space=\"preserve\">\n    <value>Verwalten Sie die Administratoreinstellungen von WinGet.</value>\n  </data>\n  <data name=\"ResetAllAdminSettingsArgumentDescription\" xml:space=\"preserve\">\n    <value>Setzt alle Administratoreinstellungen zurück.</value>\n  </data>\n  <data name=\"ResetAllAdminSettingsSucceeded\" xml:space=\"preserve\">\n    <value>Alle Administratoreinstellungen zurückgesetzt.</value>\n  </data>\n  <data name=\"McpCommandShortDescription\" xml:space=\"preserve\">\n    <value>MCP-Informationen</value>\n    <comment>MCP stands for Model Context Protocol and should probably remain as-is</comment>\n  </data>\n  <data name=\"McpCommandLongDescription\" xml:space=\"preserve\">\n    <value>MCP(Model Context Protocol)-Informationen für die Windows-Paket-Manager.</value>\n  </data>\n  <data name=\"McpConfigurationPreamble\" xml:space=\"preserve\">\n    <value>Verwenden Sie das folgende JSON-Fragment im `servers` Objekt, um den Windows-Paket-Manager-MCP-Server manuell mit Ihrem MCP-Client zu konfigurieren:</value>\n    <comment>{Locked=\"`servers`\"}\nMCP stands for Model Context Protocol and should probably remain as-is.\nAn unlocalized JSON fragment will follow on another line.</comment>\n  </data>\n  <data name=\"PolicyEnableMcpServer\" xml:space=\"preserve\">\n    <value>MCP-Server des Windows-Paket-Manager aktivieren</value>\n  </data>\n  <data name=\"OSVersionDescription\" xml:space=\"preserve\">\n    <value>Zielbetriebssystemversion</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Installieren einer oder mehrerer Schriftarten.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Die Schriftartdatei wird nicht unterstützt und kann nicht installiert werden.</value>\n  </data>\n  <data name=\"FontFileNotSupported\" xml:space=\"preserve\">\n    <value>Mindestens eine Schriftart im Schriftartenpaket wird nicht unterstützt und kann nicht installiert werden.</value>\n  </data>\n  <data name=\"FontInstallFailed\" xml:space=\"preserve\">\n    <value>Fehler bei der Installation der Schriftart; Bereinigung.</value>\n  </data>\n  <data name=\"FontAlreadyInstalled\" xml:space=\"preserve\">\n    <value>Schriftart bereits installiert.</value>\n  </data>\n  <data name=\"FontPackage\" xml:space=\"preserve\">\n    <value>Paket-ID</value>\n  </data>\n  <data name=\"FontWinGetSupported\" xml:space=\"preserve\">\n    <value>WinGet unterstützt</value>\n  </data>\n  <data name=\"FontTitle\" xml:space=\"preserve\">\n    <value>Titel</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Die Schriftartdatei wurde nicht gefunden.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Deinstallieren der Schriftart. Die Schriftart befindet sich möglicherweise nicht in einem guten Zustand. Versuchen Sie, die Deinstallation nach einem Neustart durchzuführen.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>Fehler bei der Schriftartüberprüfung.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_ROLLBACK_FAILED\" xml:space=\"preserve\">\n    <value>Fehler beim Zurücksetzen der Schriftart. Die Schriftart befindet sich möglicherweise nicht in einem guten Zustand. Versuchen Sie, die Deinstallation nach einem Neustart durchzuführen.</value>\n  </data>\n  <data name=\"FontDetailsArgumentDescription\" xml:space=\"preserve\">\n    <value>Detaillierte Informationen zur Schriftartdatei anzeigen.</value>\n  </data>\n  <data name=\"FontValidationFailed\" xml:space=\"preserve\">\n    <value>Fehler bei der Überprüfung des Schriftartenpakets.</value>\n  </data>\n  <data name=\"FontRollbackFailed\" xml:space=\"preserve\">\n    <value>Der Rollbackversuch für die fehlerhafte Schriftartinstallation war nicht erfolgreich. Möglicherweise ist ein Neustart erforderlich, um die Schriftart erfolgreich zu deinstallieren.</value>\n  </data>\n  <data name=\"FontUninstallFailed\" xml:space=\"preserve\">\n    <value>Fehler beim Deinstallieren des Schriftartenpakets. Dies liegt häufig an den Schriftarten, die vom System oder einer Anwendung verwendet werden. Die Deinstallation ist nach dem Neustart des Computers möglicherweise erfolgreich.</value>\n  </data>\n  <data name=\"FontStatusOK\" xml:space=\"preserve\">\n    <value>OK</value>\n    <comment>\"OK\" means the font is in a good healthy state</comment>\n  </data>\n  <data name=\"FontStatusCorrupt\" xml:space=\"preserve\">\n    <value>Beschädigt</value>\n    <comment>\"Corrupt\" refers to an install that is in a corrupted or bad state, and needs repair.</comment>\n  </data>\n  <data name=\"FontStatus\" xml:space=\"preserve\">\n    <value>Status</value>\n  </data>\n  <data name=\"FontStatusUnknown\" xml:space=\"preserve\">\n    <value>Unbekannt</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>Das Schriftartpaket ist bereits installiert.</value>\n  </data>\n  <data name=\"ListDetailsArgumentDescription\" xml:space=\"preserve\">\n    <value>Detaillierte Informationen zu Paketen anzeigen</value>\n    <comment>Providing this argument causes the CLI to output additional details about installed application packages.</comment>\n  </data>\n  <data name=\"ShowLabelChannel\" xml:space=\"preserve\">\n    <value>Kanal:</value>\n    <comment>Precedes a string value that names the delivery channel for the software package (ex. stable, beta).</comment>\n  </data>\n  <data name=\"ShowListLocalIdentifier\" xml:space=\"preserve\">\n    <value>Lokaler Bezeichner:</value>\n    <comment>Precedes a value that is the unique identifier for the installed package on the local system.</comment>\n  </data>\n  <data name=\"ShowListPackageFamilyName\" xml:space=\"preserve\">\n    <value>Paketfamilienname:</value>\n    <comment>Precedes a value that is the APPX/MSIX package family name of the installed package.</comment>\n  </data>\n  <data name=\"ShowListProductCode\" xml:space=\"preserve\">\n    <value>Produktcode:</value>\n    <comment>Precedes a value that is the Add/Remove Programs identifier in the registry. This is also the Product Code value as defined in MSI installers.</comment>\n  </data>\n  <data name=\"ShowListUpgradeCode\" xml:space=\"preserve\">\n    <value>Upgrade-Code:</value>\n    <comment>Precedes a value that is the MSI Upgrade Code for the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledScope\" xml:space=\"preserve\">\n    <value>Installierter Bereich:</value>\n    <comment>Precedes a value that is the scope of the installation of the package (ex. user, machine).</comment>\n  </data>\n  <data name=\"ShowListInstalledArchitecture\" xml:space=\"preserve\">\n    <value>Installierte Architektur:</value>\n    <comment>Precedes a value that is the installed architecture of the package (ex. x86, x64, ARM64).</comment>\n  </data>\n  <data name=\"ShowListInstalledLocale\" xml:space=\"preserve\">\n    <value>Installiertes Gebietsschema:</value>\n    <comment>Precedes a value that is the locale of the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledLocation\" xml:space=\"preserve\">\n    <value>Installationsspeicherort:</value>\n    <comment>Precedes a value that is the directory path to the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledSource\" xml:space=\"preserve\">\n    <value>Ursprungsquelle:</value>\n    <comment>Precedes a value that names the package source where the installed package originated from.</comment>\n  </data>\n  <data name=\"ShowListAvailableUpgrades\" xml:space=\"preserve\">\n    <value>Verfügbare Upgrades:</value>\n    <comment>Precedes a list of package upgrades available for the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstallerCategory\" xml:space=\"preserve\">\n    <value>Installer-Kategorie:</value>\n    <comment>Precedes a value that indicates the category of the installer for the installed package (ex. exe, msi, msix).</comment>\n  </data>\n  <data name=\"SourceEditOldValue\" xml:space=\"preserve\">\n    <value>Alter Wert</value>\n    <comment>Column title for listing edit changes.</comment>\n  </data>\n  <data name=\"SourceEditNewValue\" xml:space=\"preserve\">\n    <value>Neuer Wert</value>\n    <comment>Column title for listing the new value.</comment>\n  </data>\n</root>"
  },
  {
    "path": "Localization/Resources/es-ES/Resources.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "Localization/Resources/es-ES/winget.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"AdjoinedNotFlagError\" xml:space=\"preserve\">\n    <value>El alias contiguo no es una marca: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an adjoined alias that is not a flag argument. {0} is a placeholder replaced by the user input argument (e.g. '-ab').</comment>\n  </data>\n  <data name=\"AdjoinedNotFoundError\" xml:space=\"preserve\">\n    <value>Alias de marca contiguo no encontrado: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an adjoined flag alias argument that was not found. {0} is a placeholder replaced by the user input argument (e.g. '-ab').</comment>\n  </data>\n  <data name=\"AvailableArguments\" xml:space=\"preserve\">\n    <value>Los siguientes argumentos están disponibles:</value>\n    <comment>Message displayed to inform the user about the available command line arguments.</comment>\n  </data>\n  <data name=\"AvailableCommandAliases\" xml:space=\"preserve\">\n    <value>Están disponibles los siguientes alias de comando:</value>\n    <comment>Message displayed to inform the user about the available command line alias arguments.</comment>\n  </data>\n  <data name=\"AvailableCommands\" xml:space=\"preserve\">\n    <value>Los siguientes comandos están disponibles:</value>\n    <comment>Title displayed to inform the user about the available commands.</comment>\n  </data>\n  <data name=\"AvailableHeader\" xml:space=\"preserve\">\n    <value>Disponible</value>\n    <comment>As in \"a new version is available to upgrade to\".</comment>\n  </data>\n  <data name=\"AvailableOptions\" xml:space=\"preserve\">\n    <value>Están disponibles las siguientes opciones:</value>\n    <comment>Message displayed to inform the user about the available options.</comment>\n  </data>\n  <data name=\"AvailableSubcommands\" xml:space=\"preserve\">\n    <value>Los siguientes subcomandos están disponibles:</value>\n    <comment>Message displayed to inform the user about the available nested commands that run in context of the selected command.</comment>\n  </data>\n  <data name=\"AvailableUpgrades\" xml:space=\"preserve\">\n    <value>{0} actualizaciones disponibles.</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about available package upgrades. {0} is a placeholder replaced by the number of package upgrades.</comment>\n  </data>\n  <data name=\"ChannelArgumentDescription\" xml:space=\"preserve\">\n    <value>Usar el canal especificado; el valor predeterminado es público general</value>\n  </data>\n  <data name=\"Command\" xml:space=\"preserve\">\n    <value>comando</value>\n    <comment>Label displayed for a command to give the software.</comment>\n  </data>\n  <data name=\"CommandArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtrar resultados por comando</value>\n    <comment>Description message displayed to inform the user about filtering the search results by a package command.</comment>\n  </data>\n  <data name=\"CommandLineArgumentDescription\" xml:space=\"preserve\">\n    <value>Línea de comandos completa para la finalización</value>\n  </data>\n  <data name=\"CommandRequiresAdmin\" xml:space=\"preserve\">\n    <value>Este comando requiere que se ejecuten privilegios de administrador.</value>\n  </data>\n  <data name=\"CompleteCommandLongDescription\" xml:space=\"preserve\">\n    <value>Este comando puede usarse para solicitar la finalización sensible al contexto de la línea de comandos. Se pasan la línea de comandos, la posición del cursor y la palabra que se debe completar. El resultado es un conjunto de valores potenciales basado en las entradas, con un valor posible por línea.</value>\n  </data>\n  <data name=\"CompleteCommandShortDescription\" xml:space=\"preserve\">\n    <value>Habilita la finalización sensible al contexto de la línea de comandos</value>\n  </data>\n  <data name=\"CountArgumentDescription\" xml:space=\"preserve\">\n    <value>No mostrar más del número de resultados especificado (entre 1 y 1000)</value>\n  </data>\n  <data name=\"Done\" xml:space=\"preserve\">\n    <value>Listo</value>\n    <comment>Label displayed when an operation completes or is done executing.</comment>\n  </data>\n  <data name=\"ExactArgumentDescription\" xml:space=\"preserve\">\n    <value>Buscar paquete usando la coincidencia exacta</value>\n    <comment>Description message displayed to inform the user about finding an application package using an exact matching criteria.</comment>\n  </data>\n  <data name=\"ExperimentalArgumentDescription\" xml:space=\"preserve\">\n    <value>Argumento experimental para propósitos de demostración</value>\n  </data>\n  <data name=\"ExperimentalCommandLongDescription\" xml:space=\"preserve\">\n    <value>Este comando es un ejemplo de cómo implementar una característica experimental. Para activar, ve a 'winget settings' y habilita las características experimentalCmd o experimentalArg.</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"ExperimentalCommandShortDescription\" xml:space=\"preserve\">\n    <value>Ejemplo de característica experimental</value>\n  </data>\n  <data name=\"ExtraPositionalError\" xml:space=\"preserve\">\n    <value>Se encontró un argumento posicional cuando no se esperaba nada: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an extra positional argument when none was expected. {0} is a placeholder replaced by the user's extra argument input.</comment>\n  </data>\n  <data name=\"FeatureDisabledMessage\" xml:space=\"preserve\">\n    <value>Esta característica es un trabajo en curso y puede cambiar drásticamente o quitarse por completo en el futuro. Para habilitarlo, edita la configuración (\"winget settings\") para incluir la característica experimental.'{0}'</value>\n    <comment>{Locked=\"winget settings\",\"{0}\"}. Error message displayed when the user uses an experimental feature that is disabled. {0} is a placeholder replaced by the experimental feature name.</comment>\n  </data>\n  <data name=\"FeaturesCommandLongDescription\" xml:space=\"preserve\">\n    <value>Muestra el estado de las características experimentales. Las características experimentales se pueden activar a través de \"winget settings\".</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"FeaturesCommandShortDescription\" xml:space=\"preserve\">\n    <value>Muestra el estado de las características experimentales</value>\n  </data>\n  <data name=\"FeaturesDisabled\" xml:space=\"preserve\">\n    <value>Deshabilitado</value>\n  </data>\n  <data name=\"FeaturesEnabled\" xml:space=\"preserve\">\n    <value>Habilitado</value>\n  </data>\n  <data name=\"FeaturesFeature\" xml:space=\"preserve\">\n    <value>Característica</value>\n  </data>\n  <data name=\"FeaturesLink\" xml:space=\"preserve\">\n    <value>Vínculo</value>\n  </data>\n  <data name=\"FeaturesMessage\" xml:space=\"preserve\">\n    <value>Las siguientes características experimentales están en curso.\nSe pueden configurar mediante el archivo de configuración \"winget settings\".</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"FeaturesProperty\" xml:space=\"preserve\">\n    <value>Propiedad</value>\n  </data>\n  <data name=\"FeaturesStatus\" xml:space=\"preserve\">\n    <value>Estado</value>\n  </data>\n  <data name=\"FileArgumentDescription\" xml:space=\"preserve\">\n    <value>Archivo al que se va a aplicar un algoritmo hash</value>\n  </data>\n  <data name=\"FlagContainAdjoinedError\" xml:space=\"preserve\">\n    <value>El argumento de marca no puede contener un valor adjunto:'{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a flag argument containing an unexpected adjoined value. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"HashCommandLongDescription\" xml:space=\"preserve\">\n    <value>Calcula el hash de un archivo local, apropiado para la entrada en un manifiesto.  También puede calcular el hash del archivo de firma de un paquete MSIX para habilitar las instalaciones en streaming.</value>\n  </data>\n  <data name=\"HashCommandShortDescription\" xml:space=\"preserve\">\n    <value>Aplicación auxiliar para aplicar un algoritmo hash a los archivos instaladores</value>\n  </data>\n  <data name=\"HelpArgumentDescription\" xml:space=\"preserve\">\n    <value>Muestra la ayuda sobre el comando seleccionado</value>\n  </data>\n  <data name=\"HelpForDetails\" xml:space=\"preserve\">\n    <value>Para más información sobre un comando específico, pásalo el argumento de ayuda.</value>\n  </data>\n  <data name=\"HelpLinkPreamble\" xml:space=\"preserve\">\n    <value>Puedes encontrar más ayuda en:'{0}'</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a link where they can learn more about the subject context. {0} is a placeholder replaced by a website address.</comment>\n  </data>\n  <data name=\"IdArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtrar resultados por id</value>\n  </data>\n  <data name=\"IgnoreWarningsArgumentDescription\" xml:space=\"preserve\">\n    <value>Suprime las salidas de advertencia</value>\n  </data>\n  <data name=\"InstallationDisclaimer1\" xml:space=\"preserve\">\n    <value>El propietario de esta aplicación le concede una licencia.</value>\n  </data>\n  <data name=\"InstallationDisclaimer2\" xml:space=\"preserve\">\n    <value>Microsoft no es responsable, ni tampoco concede ninguna licencia de paquetes de terceros.</value>\n  </data>\n  <data name=\"InstallationDisclaimerMSStore\" xml:space=\"preserve\">\n    <value>Este paquete se proporciona a través de Microsoft Store. Es posible que winget necesite adquirir el paquete de Microsoft Store en nombre del usuario actual.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"InstallCommandLongDescription\" xml:space=\"preserve\">\n    <value>Instala el paquete seleccionado, ya sea buscando en un origen configurado o directamente desde un manifiesto. De forma predeterminada, la consulta debe coincidir sin distinción entre mayúsculas y minúsculas con el id, el name o el moniker del paquete. Se pueden usar otros campos pasando su opción adecuada. De forma predeterminada, el comando install comprobará el estado de instalación del paquete e intentará realizar una actualización si procede. Reemplácelo por --force para realizar una instalación directa.</value>\n    <comment>{Locked=\"--force\"}; id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"InstallCommandShortDescription\" xml:space=\"preserve\">\n    <value>Instala el paquete proporcionado</value>\n  </data>\n  <data name=\"InstallerHashMismatchAdminBlock\" xml:space=\"preserve\">\n    <value>El hash del instalador no coincide; esto no se puede sobreescribir al ejecutarse como administrador</value>\n  </data>\n  <data name=\"InstallerHashMismatchOverridden\" xml:space=\"preserve\">\n    <value>El hash del instalador no coincide; se puede continuar debido a --ignore-security-hash</value>\n    <comment>{Locked=\"--ignore-security-hash\"}</comment>\n  </data>\n  <data name=\"InstallerHashMismatchOverrideRequired\" xml:space=\"preserve\">\n    <value>El hash del instalador no coincide; para invalidar esta comprobación, use --ignore-security-hash</value>\n    <comment>{Locked=\"--ignore-security-hash\"}</comment>\n  </data>\n  <data name=\"InstallerHashVerified\" xml:space=\"preserve\">\n    <value>El hash del instalador se verificó correctamente</value>\n  </data>\n  <data name=\"InstallFlowInstallSuccess\" xml:space=\"preserve\">\n    <value>Instalado correctamente</value>\n  </data>\n  <data name=\"InstallFlowStartingPackageInstall\" xml:space=\"preserve\">\n    <value>Iniciando instalación de paquete...</value>\n  </data>\n  <data name=\"HashOverrideArgumentDescription\" xml:space=\"preserve\">\n    <value>Omitir el error de comprobación de hash del instalador</value>\n  </data>\n  <data name=\"IgnoreLocalArchiveMalwareScanArgumentDescription\" xml:space=\"preserve\">\n    <value>Omitir el examen de malware realizado como parte de la instalación de un paquete de tipo de archivo desde el manifiesto local</value>\n  </data>\n  <data name=\"InteractiveArgumentDescription\" xml:space=\"preserve\">\n    <value>Solicitar instalación interactiva; es posible que se necesite la participación del usuario</value>\n  </data>\n  <data name=\"InvalidAliasError\" xml:space=\"preserve\">\n    <value>No se reconoció el alias de argumento para el comando actual: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a command line argument alias that was not recognized for a selected command. {0} is a placeholder replaced by the user's argument alias input (e.g. '-a').</comment>\n  </data>\n  <data name=\"InvalidArgumentSpecifierError\" xml:space=\"preserve\">\n    <value>Especificador de argumento no válido:'{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an invalid argument specifier. {0} is a placeholder replaced by an argument specifier (e.g. '-').</comment>\n  </data>\n  <data name=\"InvalidNameError\" xml:space=\"preserve\">\n    <value>No se reconoció el nombre del argumento para el comando actual: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an unrecognized command line argument name for the selected command. {0} is a placeholder replaced by the user's argument name input (e.g. '--example').</comment>\n  </data>\n  <data name=\"KeyDirectoriesHeader\" xml:space=\"preserve\">\n    <value>Directorios de WinGet</value>\n    <comment>Header for a table detailing the directories Winget uses for key operations like logging and portable installs</comment>\n  </data>\n  <data name=\"LocaleArgumentDescription\" xml:space=\"preserve\">\n    <value>Configuración regional para usar (formato BCP47)</value>\n    <comment>{Locked=\"BCP47\"}</comment>\n  </data>\n  <data name=\"LicenseAgreement\" xml:space=\"preserve\">\n    <value>Contrato de licencia</value>\n  </data>\n  <data name=\"Links\" xml:space=\"preserve\">\n    <value>Vínculos</value>\n    <comment>Links to different webpages</comment>\n  </data>\n  <data name=\"ListCommandLongDescription\" xml:space=\"preserve\">\n    <value>El comando \"list\" muestra los paquetes instalados en el sistema, así como si existe una actualización disponible. Se pueden proporcionar opciones adicionales para filtrar el resultado, como con el comando \"search\".</value>\n    <comment>{Locked=\"list\",\"search\"}</comment>\n  </data>\n  <data name=\"ListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Mostrar paquetes instalados</value>\n  </data>\n  <data name=\"LocationArgumentDescription\" xml:space=\"preserve\">\n    <value>Ubicación en la que instalar (si es posible)</value>\n  </data>\n  <data name=\"LogArgumentDescription\" xml:space=\"preserve\">\n    <value>Ubicación del registro (si es posible)</value>\n  </data>\n  <data name=\"MainCopyrightNotice\" xml:space=\"preserve\">\n    <value>Copyright (c) Microsoft Corporation. Todos los derechos reservados.</value>\n  </data>\n  <data name=\"MainHomepage\" xml:space=\"preserve\">\n    <value>Página principal</value>\n    <comment>The primary webpage for the software</comment>\n  </data>\n  <data name=\"ManifestArgumentDescription\" xml:space=\"preserve\">\n    <value>La ruta de acceso al manifiesto del paquete</value>\n  </data>\n  <data name=\"ManifestValidationFail\" xml:space=\"preserve\">\n    <value>Error de validación de manifiesto.</value>\n  </data>\n  <data name=\"ManifestValidationSuccess\" xml:space=\"preserve\">\n    <value>Validación del manifiesto correcta.</value>\n  </data>\n  <data name=\"ManifestValidationWarning\" xml:space=\"preserve\">\n    <value>Validación del manifiesto correcta con advertencias.</value>\n  </data>\n  <data name=\"MissingArgumentError\" xml:space=\"preserve\">\n    <value>El argumento necesita un valor, pero no se encuentra ninguno: '{0}''</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user does not provide a required command line argument value. {0} is a placeholder replaced by the argument name.</comment>\n  </data>\n  <data name=\"MonikerArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtrar resultados por moniker</value>\n  </data>\n  <data name=\"MsixArgumentDescription\" xml:space=\"preserve\">\n    <value>El archivo de entrada será tratado como msix; Si está firmado, se proporcionará hash de firma</value>\n  </data>\n  <data name=\"MsixSignatureHashFailed\" xml:space=\"preserve\">\n    <value>No se pudo calcular el hash de firma MSIX.</value>\n  </data>\n  <data name=\"MSStoreAppBlocked\" xml:space=\"preserve\">\n    <value>Error al instalar o actualizar el paquete de Microsoft Store porque la aplicación específica está bloqueada por la directiva</value>\n  </data>\n  <data name=\"MSStoreInstallOrUpdateFailed\" xml:space=\"preserve\">\n    <value>Error al instalar o actualizar el paquete de Microsoft Store. Código de error: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Microsoft Store application package fails to install or upgrade. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"MSStoreStoreClientBlocked\" xml:space=\"preserve\">\n    <value>Error al instalar o actualizar el paquete de Microsoft Store porque el cliente de Microsoft Store está bloqueado por la directiva</value>\n  </data>\n  <data name=\"MSStoreInstallTryGetEntitlement\" xml:space=\"preserve\">\n    <value>Comprobando o solicitando la adquisición del paquete...</value>\n  </data>\n  <data name=\"MultipleInstalledPackagesFound\" xml:space=\"preserve\">\n    <value>Se encontraron varios paquetes instalados que coinciden con los criterios de entrada. Por favor, reajusta tu búsqueda.</value>\n  </data>\n  <data name=\"MultiplePackagesFound\" xml:space=\"preserve\">\n    <value>Se encontraron varios paquetes coincidentes con los criterios de entrada. Por favor, reajusta tu búsqueda.</value>\n  </data>\n  <data name=\"NameArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtrar resultados por nombre</value>\n  </data>\n  <data name=\"NoApplicableInstallers\" xml:space=\"preserve\">\n    <value>No se ha encontrado ningún instalador aplicable; consulte los registros para obtener más detalles.</value>\n  </data>\n  <data name=\"NoExperimentalFeaturesMessage\" xml:space=\"preserve\">\n    <value>Actualmente, no hay ninguna característica experimental disponible.</value>\n  </data>\n  <data name=\"NoInstalledPackageFound\" xml:space=\"preserve\">\n    <value>No se encontró ningún paquete que coincida con los criterios de entrada.</value>\n  </data>\n  <data name=\"NoPackageFound\" xml:space=\"preserve\">\n    <value>No se encontró ningún paquete coincidente con los criterios de busqueda.</value>\n  </data>\n  <data name=\"NoVTArgumentDescription\" xml:space=\"preserve\">\n    <value>Deshabilita la pantalla VirtualTerminal</value>\n    <comment>{Locked=\"VirtualTerminal\"}</comment>\n  </data>\n  <data name=\"OpenLogsArgumentDescription\" xml:space=\"preserve\">\n    <value>Abrir la ubicación de registros predeterminada</value>\n  </data>\n  <data name=\"Options\" xml:space=\"preserve\">\n    <value>opciones</value>\n    <comment>Options to change how a command works</comment>\n  </data>\n  <data name=\"OverrideArgumentDescription\" xml:space=\"preserve\">\n    <value>Sobreescribir argumentos pasados al instalador</value>\n  </data>\n  <data name=\"Package\" xml:space=\"preserve\">\n    <value>Paquete: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for a software package. {0} is a placeholder replaced by the software package name.</comment>\n  </data>\n  <data name=\"PendingWorkError\" xml:space=\"preserve\">\n    <value>Vaya, olvidamos hacer esto...</value>\n  </data>\n  <data name=\"PositionArgumentDescription\" xml:space=\"preserve\">\n    <value>La posición del cursor en la línea de comandos</value>\n  </data>\n  <data name=\"PrivacyStatement\" xml:space=\"preserve\">\n    <value>Declaración de privacidad</value>\n  </data>\n  <data name=\"QueryArgumentDescription\" xml:space=\"preserve\">\n    <value>La consulta usada para buscar un paquete</value>\n  </data>\n  <data name=\"RainbowArgumentDescription\" xml:space=\"preserve\">\n    <value>Progreso que muestra un arco iris de colores</value>\n  </data>\n  <data name=\"RequiredArgError\" xml:space=\"preserve\">\n    <value>No se proporcionó un argumento necesario: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user does not provide a required command line argument. {0} is a placeholder replaced by an argument name.</comment>\n  </data>\n  <data name=\"RetroArgumentDescription\" xml:space=\"preserve\">\n    <value>Pantalla de progreso como color predeterminado</value>\n  </data>\n  <data name=\"SearchCommandLongDescription\" xml:space=\"preserve\">\n    <value>Busca paquetes de orígenes configurados.</value>\n  </data>\n  <data name=\"SearchCommandShortDescription\" xml:space=\"preserve\">\n    <value>Buscar y mostrar información básica de paquetes</value>\n  </data>\n  <data name=\"SearchId\" xml:space=\"preserve\">\n    <value>Id</value>\n    <comment>Abbreviation of Identifier.</comment>\n  </data>\n  <data name=\"SearchMatch\" xml:space=\"preserve\">\n    <value>Coincidencia</value>\n  </data>\n  <data name=\"SearchName\" xml:space=\"preserve\">\n    <value>Nombre</value>\n  </data>\n  <data name=\"SearchSource\" xml:space=\"preserve\">\n    <value>Origen</value>\n  </data>\n  <data name=\"SearchTruncated\" xml:space=\"preserve\">\n    <value>se omitieron otras entradas por el límite de resultados</value>\n  </data>\n  <data name=\"SearchVersion\" xml:space=\"preserve\">\n    <value>Versión</value>\n  </data>\n  <data name=\"SettingLoadFailure\" xml:space=\"preserve\">\n    <value>Se encontraron los siguientes errores al validar la configuración:</value>\n  </data>\n  <data name=\"SettingsCommandLongDescription\" xml:space=\"preserve\">\n    <value>Abra la configuración en el editor de texto JSON predeterminado. Si no hay un editor configurado, abra la configuración en el bloc de notas. Para conocer la configuración disponible, consulte https://aka.ms/winget-settings. Este comando también se puede utilizar para establecer la configuración del administrador proporcionando los argumentos --enable o --disable.</value>\n    <comment>{Locked=\"--enable\"} {Locked=\"--disable\"}</comment>\n  </data>\n  <data name=\"SettingsCommandShortDescription\" xml:space=\"preserve\">\n    <value>Abrir la configuración o establecer la configuración del administrador</value>\n  </data>\n  <data name=\"SettingsWarnings\" xml:space=\"preserve\">\n    <value>Error inesperado al cargar la configuración. Para comprobar la configuración, ejecute el comando 'settings'.</value>\n    <comment>{Locked=\"'settings'\"}</comment>\n  </data>\n  <data name=\"ShowChannel\" xml:space=\"preserve\">\n    <value>Canal</value>\n  </data>\n  <data name=\"ShowCommandLongDescription\" xml:space=\"preserve\">\n    <value>Muestra información sobre un paquete específico. De forma predeterminada, la consulta debe coincidir con el id, nombre o el moniker del paquete sin distinguir entre mayúsculas y minúsculas. Puede usar otros campos si pasa su opción adecuada.</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"ShowCommandShortDescription\" xml:space=\"preserve\">\n    <value>Muestra información sobre un paquete</value>\n  </data>\n  <data name=\"ShowVersion\" xml:space=\"preserve\">\n    <value>Versión</value>\n  </data>\n  <data name=\"SilentArgumentDescription\" xml:space=\"preserve\">\n    <value>Solicitar instalación silenciosa</value>\n  </data>\n  <data name=\"SingleCharAfterDashError\" xml:space=\"preserve\">\n    <value>Solo el alias de un solo carácter puede aparecer después de un solo -: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides more than a single character command line alias argument after an alias argument specifier '-'. {0} is a placeholder replaced by the user's argument input.</comment>\n  </data>\n  <data name=\"SourceAddAlreadyExistsDifferentArg\" xml:space=\"preserve\">\n    <value>Ya existe un origen con el nombre proporcionado y hace referencia a una ubicación diferente:</value>\n  </data>\n  <data name=\"SourceAddAlreadyExistsDifferentName\" xml:space=\"preserve\">\n    <value>Ya hay un origen con otro nombre que hace referencia a esta ubicación:</value>\n  </data>\n  <data name=\"SourceAddAlreadyExistsMatch\" xml:space=\"preserve\">\n    <value>Ya existe un origen con el nombre proporcionado y hace referencia a la misma ubicación:</value>\n  </data>\n  <data name=\"SourceAddBegin\" xml:space=\"preserve\">\n    <value>Agregando origen:</value>\n  </data>\n  <data name=\"SourceAddCommandLongDescription\" xml:space=\"preserve\">\n    <value>Agrega un nuevo origen. Un origen proporciona los datos para que puedas detectar e instalar paquetes. Agrega un origen nuevo solo si confías que será una ubicación segura.</value>\n  </data>\n  <data name=\"SourceAddCommandShortDescription\" xml:space=\"preserve\">\n    <value>Agregar un nuevo origen</value>\n  </data>\n  <data name=\"SourceArgArgumentDescription\" xml:space=\"preserve\">\n    <value>El argumento dado al origen</value>\n  </data>\n  <data name=\"SourceArgumentDescription\" xml:space=\"preserve\">\n    <value>Buscar paquete usando el origen especificado</value>\n  </data>\n  <data name=\"SourceCommandLongDescription\" xml:space=\"preserve\">\n    <value>Administrar orígenes con los subcomandos. Un origen proporciona los datos para que puedas detectar e instalar paquetes. Agrega un origen nuevo solo si confías en él como una ubicación segura.</value>\n  </data>\n  <data name=\"SourceCommandShortDescription\" xml:space=\"preserve\">\n    <value>Administrar orígenes de paquetes</value>\n  </data>\n  <data name=\"SourceEditCommandLongDescription\" xml:space=\"preserve\">\n    <value>Edite las propiedades de un origen existente. Un origen proporciona los datos para que pueda detectar e instalar paquetes.</value>\n  </data>\n  <data name=\"SourceEditCommandShortDescription\" xml:space=\"preserve\">\n    <value>Editar propiedades de un origen</value>\n  </data>\n  <data name=\"SourceEditOne\" xml:space=\"preserve\">\n    <value>Editando origen: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being edited. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceEditNoChanges\" xml:space=\"preserve\">\n    <value>El origen denominado '{0}' ya está en el estado deseado.</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being edited. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceListArg\" xml:space=\"preserve\">\n    <value>Argumento</value>\n    <comment>Value given to source.</comment>\n  </data>\n  <data name=\"SourceListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Enumerar todos los orígenes actuales o detalles completos de un origen específico.</value>\n  </data>\n  <data name=\"SourceListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Enumerar orígenes actuales</value>\n  </data>\n  <data name=\"SourceListData\" xml:space=\"preserve\">\n    <value>Datos</value>\n    <comment>Data stored by the source.</comment>\n  </data>\n  <data name=\"SourceListField\" xml:space=\"preserve\">\n    <value>Campo</value>\n    <comment>The name of a piece of information about a source.</comment>\n  </data>\n  <data name=\"SourceListName\" xml:space=\"preserve\">\n    <value>Nombre</value>\n    <comment>The name of the source.</comment>\n  </data>\n  <data name=\"SourceListIdentifier\" xml:space=\"preserve\">\n    <value>Identificador</value>\n    <comment>The source's unique identifier.</comment>\n  </data>\n  <data name=\"SourceListNoneFound\" xml:space=\"preserve\">\n    <value>No se encontró un origen con nombre: {0}</value>\n    <comment>Error message displayed when the user provides a repository source name that was not found. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"SourceListNoSources\" xml:space=\"preserve\">\n    <value>No hay ningún origen configurado.</value>\n  </data>\n  <data name=\"SourceListType\" xml:space=\"preserve\">\n    <value>Tipo</value>\n    <comment>The kind of source.</comment>\n  </data>\n  <data name=\"SourceListUpdated\" xml:space=\"preserve\">\n    <value>Actualizado</value>\n    <comment>The last time the source was updated.</comment>\n  </data>\n  <data name=\"SourceListUpdatedNever\" xml:space=\"preserve\">\n    <value>nunca</value>\n    <comment>The source has never been updated.</comment>\n  </data>\n  <data name=\"SourceListValue\" xml:space=\"preserve\">\n    <value>Valor</value>\n    <comment>The value of information about a source.</comment>\n  </data>\n  <data name=\"SourceNameArgumentDescription\" xml:space=\"preserve\">\n    <value>Nombre del origen</value>\n  </data>\n  <data name=\"SourceOpenFailedSuggestion\" xml:space=\"preserve\">\n    <value>Error al abrir los orígenes, pruebe el comando \"source reset\" si el problema persiste.</value>\n    <comment>{Locked=\"source reset\"}</comment>\n  </data>\n  <data name=\"SourceOpenPredefinedFailedSuggestion\" xml:space=\"preserve\">\n    <value>No se pudo abrir el origen predefinido; por favor informa a los mantenedores de winget.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"SourceRemoveAll\" xml:space=\"preserve\">\n    <value>Eliminando todos los orígenes...</value>\n  </data>\n  <data name=\"SourceRemoveCommandLongDescription\" xml:space=\"preserve\">\n    <value>Quitar un origen específico.</value>\n  </data>\n  <data name=\"SourceRemoveCommandShortDescription\" xml:space=\"preserve\">\n    <value>Quitar orígenes actuales</value>\n  </data>\n  <data name=\"SourceRemoveOne\" xml:space=\"preserve\">\n    <value>Quitando origen: {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being removed. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceResetAll\" xml:space=\"preserve\">\n    <value>Restableciendo todos los orígenes...</value>\n  </data>\n  <data name=\"SourceResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>Este comando quita los orígenes existentes lo que puede dejar atrás información local. Sin argumentos, eliminará todos los orígenes y agregará los valores predeterminados. Si se proporciona el nombre de un origen, solo se eliminará ese origen.</value>\n  </data>\n  <data name=\"SourceResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>Restablecer orígenes</value>\n  </data>\n  <data name=\"SourceResetForceArgumentDescription\" xml:space=\"preserve\">\n    <value>Fuerza el restablecimiento de los orígenes</value>\n  </data>\n  <data name=\"SourceResetListAndOverridePreamble\" xml:space=\"preserve\">\n    <value>Se restablecerán los siguientes orígenes si se proporciona la opción --force:</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"SourceResetOne\" xml:space=\"preserve\">\n    <value>Restableciendo origen: {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a repository source that is currently being reset. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceTypeArgumentDescription\" xml:space=\"preserve\">\n    <value>Tipo del origen</value>\n  </data>\n  <data name=\"SourceUpdateAll\" xml:space=\"preserve\">\n    <value>Actualizando todos los orígenes...</value>\n  </data>\n  <data name=\"SourceUpdateCommandLongDescription\" xml:space=\"preserve\">\n    <value>Actualizar todos los orígenes o solo un origen específico.</value>\n  </data>\n  <data name=\"SourceUpdateCommandShortDescription\" xml:space=\"preserve\">\n    <value>Actualizar orígenes actuales</value>\n  </data>\n  <data name=\"SourceUpdateOne\" xml:space=\"preserve\">\n    <value>Actualizando origen: {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being updated. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"TagArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtrar resultados por etiqueta</value>\n  </data>\n  <data name=\"ThankYou\" xml:space=\"preserve\">\n    <value>Gracias por usar winget</value>\n  </data>\n  <data name=\"ThirdPartSoftwareNotices\" xml:space=\"preserve\">\n    <value>Avisos de terceros</value>\n  </data>\n  <data name=\"ToolDescription\" xml:space=\"preserve\">\n    <value>La utilidad de línea de comandos winget permite instalar aplicaciones y otros paquetes desde la línea de comandos.</value>\n  </data>\n  <data name=\"ToolInfoArgumentDescription\" xml:space=\"preserve\">\n    <value>Mostrar información general de la herramienta</value>\n  </data>\n  <data name=\"ToolVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>Mostrar la versión de la herramienta</value>\n  </data>\n  <data name=\"TooManyArgError\" xml:space=\"preserve\">\n    <value>Se proporcionó el argumento más veces de las permitidas: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a command line argument more times than it is allowed. {0} is a placeholder replaced by the user's argument name input.</comment>\n  </data>\n  <data name=\"TooManyBehaviorsError\" xml:space=\"preserve\">\n    <value>Se proporcionó más de un argumento de comportamiento de ejecución: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides more than one execution behavior argument when installing an application package. {0} is a placeholder replaced by the user specified execution behaviors (e.g. 'silent|interactive').</comment>\n  </data>\n  <data name=\"UnexpectedErrorExecutingCommand\" xml:space=\"preserve\">\n    <value>Se ha producido un error inesperado al ejecutar el comando:</value>\n  </data>\n  <data name=\"UninstallPreviousArgumentDescription\" xml:space=\"preserve\">\n    <value>Desinstalar la versión anterior del paquete durante la actualización</value>\n  </data>\n  <data name=\"UnrecognizedCommand\" xml:space=\"preserve\">\n    <value>Comando no reconocido: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an unrecognized command. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"UpdateAllArgumentDescription\" xml:space=\"preserve\">\n    <value>Actualizar todos los paquetes instalados a la versión más reciente si está disponible</value>\n  </data>\n  <data name=\"UpdateNotApplicable\" xml:space=\"preserve\">\n    <value>No se ha encontrado ninguna actualización aplicable.</value>\n  </data>\n  <data name=\"UpdateNotApplicableReason\" xml:space=\"preserve\">\n    <value>Una versión más reciente del paquete está disponible en una fuente configurada, pero no se aplica a su sistema o requisitos.</value>\n  </data>\n  <data name=\"UpdateNoPackagesFound\" xml:space=\"preserve\">\n    <value>No se ha encontrado ninguna actualización disponible.</value>\n  </data>\n  <data name=\"UpdateNoPackagesFoundReason\" xml:space=\"preserve\">\n    <value>No hay versiones más recientes del paquete disponibles en las fuentes configuradas.</value>\n  </data>\n  <data name=\"UpgradeCommandLongDescription\" xml:space=\"preserve\">\n    <value>Actualiza el paquete seleccionado, ya sea buscando en la lista de paquetes instalados o directamente desde un manifiesto. De forma predeterminada, la consulta debe coincidir sin distinción entre mayúsculas y minúsculas con el identificador, el nombre o el moniker del paquete. Se pueden usar otros campos pasando su opción adecuada. Cuando no se proporciona ningún argumento, muestra los paquetes con actualizaciones disponibles</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"UpgradeCommandShortDescription\" xml:space=\"preserve\">\n    <value>Muestra y realiza actualizaciones disponibles</value>\n  </data>\n  <data name=\"Usage\" xml:space=\"preserve\">\n    <value>uso: {0} {1}</value>\n    <comment>{Locked=\"{0} {1}\"} Message displayed to provide the user with instructions on how to use a command. {0} is a placeholder replaced by the program name (e.g. 'winget'). {1} is a placeholder replaced by the pattern for using the selected command.</comment>\n  </data>\n  <data name=\"ValidateCommandLongDescription\" xml:space=\"preserve\">\n    <value>Valida un manifiesto usando un conjunto estricto de instrucciones. El propósito es permitirle comprobar el manifiesto antes de enviarlo a un repositorio.</value>\n  </data>\n  <data name=\"ValidateCommandShortDescription\" xml:space=\"preserve\">\n    <value>Valida un archivo de manifiesto</value>\n  </data>\n  <data name=\"ValidateManifestArgumentDescription\" xml:space=\"preserve\">\n    <value>La ruta de acceso al manifiesto que se va a validar</value>\n  </data>\n  <data name=\"VerboseLogsArgumentDescription\" xml:space=\"preserve\">\n    <value>Permite el registro detallado para winget</value>\n  </data>\n  <data name=\"VerifyFileSignedMsix\" xml:space=\"preserve\">\n    <value>Compruebe que el archivo de entrada es un archivo de tipo MSIX válido y firmado.</value>\n  </data>\n  <data name=\"VersionArgumentDescription\" xml:space=\"preserve\">\n    <value>Usar la versión especificada. El valor predeterminado es la última versión</value>\n  </data>\n  <data name=\"VersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Mostrar las versiones disponibles del paquete</value>\n  </data>\n  <data name=\"WordArgumentDescription\" xml:space=\"preserve\">\n    <value>Se pide el valor proporcionado antes de la finalización</value>\n  </data>\n  <data name=\"GetManifestResultVersionNotFound\" xml:space=\"preserve\">\n    <value>No se encontró ninguna versión que coincida: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to upgrade an application package to a version that was not found. {0} is a placeholder replaced by the user's provided upgrade package version.</comment>\n  </data>\n  <data name=\"OpenSourceFailedNoMatch\" xml:space=\"preserve\">\n    <value>Ninguna fuente coincide con el valor especificado: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to install or upgrade an application package from a repository source that was not found. {0} is a placeholder replaced by the user's repository source name input.</comment>\n  </data>\n  <data name=\"OpenSourceFailedNoMatchHelp\" xml:space=\"preserve\">\n    <value>Los orígenes configurados son:</value>\n  </data>\n  <data name=\"OpenSourceFailedNoSourceDefined\" xml:space=\"preserve\">\n    <value>No se definió ningún origen. Agregue uno con \"source add\" o restablezca el valor predeterminado con \"source reset\"</value>\n    <comment>{Locked=\"source add\",\"source reset\"}</comment>\n  </data>\n  <data name=\"ReportIdentityFound\" xml:space=\"preserve\">\n    <value>Encontrado</value>\n  </data>\n  <data name=\"VerifyFileFailedIsDirectory\" xml:space=\"preserve\">\n    <value>La ruta de acceso es un directorio: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system path that is a directory. {0} is a placeholder replaced by the provided directory path.</comment>\n  </data>\n  <data name=\"VerifyFileFailedNotExist\" xml:space=\"preserve\">\n    <value>El archivo “{0}” no existe.</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system file that does not exist. {0} is a placeholder replaced by the provided file path.</comment>\n  </data>\n  <data name=\"BothManifestAndSearchQueryProvided\" xml:space=\"preserve\">\n    <value>Se proporcionan los argumentos de consulta de búsqueda y manifiesto local</value>\n  </data>\n  <data name=\"Logs\" xml:space=\"preserve\">\n    <value>Registros</value>\n    <comment>Label displayed for diagnostic files containing information about the application use.</comment>\n  </data>\n  <data name=\"InstallerBlockedByPolicy\" xml:space=\"preserve\">\n    <value>El instalador está bloqueado debido a una directiva</value>\n  </data>\n  <data name=\"InstallerFailedSecurityCheck\" xml:space=\"preserve\">\n    <value>El instalador falló la comprobación de seguridad</value>\n  </data>\n  <data name=\"InstallerFailedVirusScan\" xml:space=\"preserve\">\n    <value>Un producto antivirus informa de una infección en el instalador</value>\n  </data>\n  <data name=\"SourceOpenWithFailedUpdate\" xml:space=\"preserve\">\n    <value>Error al intentar actualizar el origen: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to update the repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"UninstallCommandLongDescription\" xml:space=\"preserve\">\n    <value>Desinstala el paquete seleccionado, encontrado al buscar en una lista de paquetes instalados o bien, directamente desde un manifiesto. De forma predeterminada, la consulta debe coincidir con el id, nombre o el moniker del paquete sin distinguir entre mayúsculas y minúsculas. Se pueden usar otros campos usando la opción apropiada.</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"UninstallCommandShortDescription\" xml:space=\"preserve\">\n    <value>Desinstala el paquete proporcionado</value>\n  </data>\n  <data name=\"UninstallFlowStartingPackageUninstall\" xml:space=\"preserve\">\n    <value>Iniciando la desinstalación de paquete...</value>\n  </data>\n  <data name=\"UninstallFlowUninstallSuccess\" xml:space=\"preserve\">\n    <value>Desinstalación realizada con éxito</value>\n  </data>\n  <data name=\"NoUninstallInfoFound\" xml:space=\"preserve\">\n    <value>winget no encuentra el comando de desinstalación de este paquete. Póngase en contacto con el anunciante del paquete para obtener ayuda.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"UninstallAbandoned\" xml:space=\"preserve\">\n    <value>Desinstalación abandonada</value>\n  </data>\n  <data name=\"UninstallFailedWithCode\" xml:space=\"preserve\">\n    <value>Error de desinstalación con el código de salida: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to uninstall an application package fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"ExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Exporta una lista de los paquetes instalados</value>\n  </data>\n  <data name=\"ImportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Instala todos los paquetes enumerados en un archivo.</value>\n  </data>\n  <data name=\"ImportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Instala todos los paquetes en un archivo.</value>\n  </data>\n  <data name=\"OutputFileArgumentDescription\" xml:space=\"preserve\">\n    <value>Archivo en el que se va a escribir el resultado</value>\n  </data>\n  <data name=\"ImportFileArgumentDescription\" xml:space=\"preserve\">\n    <value>Archivo que describe los paquetes que se instalarán</value>\n  </data>\n  <data name=\"ExportSourceArgumentDescription\" xml:space=\"preserve\">\n    <value>Exportar paquetes del origen especificado</value>\n  </data>\n  <data name=\"ExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Escribe una lista de los paquetes instalados en un archivo. Los paquetes se pueden instalar con el comando import.</value>\n    <comment>{Locked=\"import\"}</comment>\n  </data>\n  <data name=\"ImportInstallFailed\" xml:space=\"preserve\">\n    <value>No se pudieron instalar uno o más paquetes importados</value>\n  </data>\n  <data name=\"ImportSourceNotInstalled\" xml:space=\"preserve\">\n    <value>El origen necesario para la importación no está instalado: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to import application package(s) from a repository source that is not installed. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"InstalledPackageNotAvailable\" xml:space=\"preserve\">\n    <value>El paquete instalado no está disponible desde ningún origen: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when the user attempts to export an installed application package that is not available from any repository source. {0} is a placeholder replaced by the installed package name.</comment>\n  </data>\n  <data name=\"InstalledPackageVersionNotAvailable\" xml:space=\"preserve\">\n    <value>La versión instalada del paquete no está disponible de ningún origen: {0} {1} {2}</value>\n    <comment>{Locked=\"{0} {1} {2}\"} Warning message displayed when the user attempts to export an installed application package with a version that is not available from any repository source. {0} is a placeholder replaced by the installed package identifier. {1} is a placeholder replaced by the installed package version. {2} is a placeholder replaced by the installed package channel.</comment>\n  </data>\n  <data name=\"NoPackagesInImportFile\" xml:space=\"preserve\">\n    <value>No se encontraron paquetes en archivo de importación</value>\n  </data>\n  <data name=\"InvalidJsonFile\" xml:space=\"preserve\">\n    <value>El archivo JSON no es válido.</value>\n  </data>\n  <data name=\"MultiQueryPackageAlreadyInstalled\" xml:space=\"preserve\">\n    <value>El paquete ya está instalado: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user that an application package is already installed. {0} is a placeholder replaced by the package identifier or search query.</comment>\n  </data>\n  <data name=\"ImportIgnoreUnavailableArgumentDescription\" xml:space=\"preserve\">\n    <value>Omitir los paquetes no disponibles</value>\n  </data>\n  <data name=\"ExportIncludeVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Incluir versiones de paquete en el archivo de exportación</value>\n  </data>\n  <data name=\"ImportIgnoreVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Omitir las versiones del paquete del archivo de importación</value>\n  </data>\n  <data name=\"VerifyPathFailedNotExist\" xml:space=\"preserve\">\n    <value>La ruta de acceso no existe: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system path argument value that does not exist. {0} is a placeholder replaced by the user's provided path.</comment>\n  </data>\n  <data name=\"ImportFileHasInvalidSchema\" xml:space=\"preserve\">\n    <value>El archivo JSON no especifica un esquema reconocido.</value>\n  </data>\n  <data name=\"InstallScopeDescription\" xml:space=\"preserve\">\n    <value>Seleccione el ámbito de la instalación (user o machine)</value>\n    <comment>{Locked=\"user\",\"machine\"} This argument allows the user to select between installing for just the user or for the entire machine.</comment>\n  </data>\n  <data name=\"InvalidArgumentValueError\" xml:space=\"preserve\">\n    <value>El valor proporcionado para el argumento '{0}' no es válido; los valores válidos son: {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message displayed when the user provides an invalid command line argument value. {0} is a placeholder replaced by the argument name. {1} is a placeholder replaced by a list of valid options.</comment>\n  </data>\n  <data name=\"DisabledByGroupPolicy\" xml:space=\"preserve\">\n    <value>Esta operación está deshabilitada por directiva de grupo: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user performs a command operation that is disabled by a group policy. {0} is a placeholder replaced by a group policy description.</comment>\n  </data>\n  <data name=\"PolicyAdditionalSources\" xml:space=\"preserve\">\n    <value>Habilitar orígenes adicionales del instalador de aplicaciones de Windows</value>\n  </data>\n  <data name=\"PolicyAllowedSources\" xml:space=\"preserve\">\n    <value>Habilitar orígenes permitidos del instalador de aplicaciones de Windows</value>\n  </data>\n  <data name=\"PolicyEnableDefaultSource\" xml:space=\"preserve\">\n    <value>Habilitar el origen predeterminada del instalador de aplicaciones de Windows</value>\n  </data>\n  <data name=\"PolicyEnableExperimentalFeatures\" xml:space=\"preserve\">\n    <value>Habilitar las funciones experimentales del instalador de aplicaciones de Windows</value>\n  </data>\n  <data name=\"PolicyEnableMSStoreSource\" xml:space=\"preserve\">\n    <value>Habilitar el origen Microsoft Store del instalador de aplicaciones de Windows</value>\n  </data>\n  <data name=\"PolicyEnableFontSource\" xml:space=\"preserve\">\n    <value>Habilitar origen de fuente de Windows App Instalador</value>\n  </data>\n  <data name=\"PolicyEnableWinGetSettings\" xml:space=\"preserve\">\n    <value>Habilitar la configuración del Administrador de paquetes de Windows</value>\n  </data>\n  <data name=\"PolicyEnableWinGet\" xml:space=\"preserve\">\n    <value>Habilitar el Administrador de paquetes de Windows</value>\n  </data>\n  <data name=\"PolicyEnableWindowsPackageManagerCommandLineInterfaces\" xml:space=\"preserve\">\n    <value>Habilitar Administrador de paquetes de Windows interfaces de línea de comandos</value>\n  </data>\n  <data name=\"PolicySourceAutoUpdateInterval\" xml:space=\"preserve\">\n    <value>Establecer el intervalo de actualización automática del origen del Administrador de paquetes de Windows en minutos</value>\n  </data>\n  <data name=\"PoliciesPolicy\" xml:space=\"preserve\">\n    <value>Directiva de grupo</value>\n    <comment>Header for a table listing active Group Policies</comment>\n  </data>\n  <data name=\"PolicyEnableLocalManifests\" xml:space=\"preserve\">\n    <value>Habilitar los archivos locales de manifiesto del instalador de aplicaciones de Windows</value>\n  </data>\n  <data name=\"PolicyEnableBypassCertificatePinningForMicrosoftStore\" xml:space=\"preserve\">\n    <value>Habilitar omisión del certificado anclado de origen del instalador de aplicación de Windows para Microsoft Store</value>\n  </data>\n  <data name=\"PolicyEnableLocalArchiveMalwareScanOverride\" xml:space=\"preserve\">\n    <value>Habilitar invalidación de examen de malware de archivo local de Windows Instalador de aplicación</value>\n  </data>\n  <data name=\"SettingsWarningField\" xml:space=\"preserve\">\n    <value>Campo: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when a user setting field has invalid syntax or semantics. {0} is a placeholder replaced by the setting field path.</comment>\n  </data>\n  <data name=\"SettingsWarningInvalidFieldFormat\" xml:space=\"preserve\">\n    <value>Formato de campo no válido.</value>\n  </data>\n  <data name=\"SettingsWarningInvalidFieldValue\" xml:space=\"preserve\">\n    <value>Valor de campo no válido.</value>\n  </data>\n  <data name=\"SettingsWarningInvalidValueFromPolicy\" xml:space=\"preserve\">\n    <value>Configuración no válida de la directiva de grupo.</value>\n  </data>\n  <data name=\"SettingsWarningLoadedBackupSettings\" xml:space=\"preserve\">\n    <value>Se ha cargado la configuración desde el archivo de copia de seguridad.</value>\n  </data>\n  <data name=\"SettingsWarningParseError\" xml:space=\"preserve\">\n    <value>Error al analizar el archivo:</value>\n  </data>\n  <data name=\"SettingsWarningValue\" xml:space=\"preserve\">\n    <value>Valor: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when a user setting value has invalid syntax or semantics. {0} is a placeholder replaced by the setting data value.</comment>\n  </data>\n  <data name=\"FeaturesMessageDisabledByPolicy\" xml:space=\"preserve\">\n    <value>Las siguientes características experimentales están en curso.\nLa configuración está deshabilitada debido a la Directiva de grupo.</value>\n  </data>\n  <data name=\"InstallerHashMismatchError\" xml:space=\"preserve\">\n    <value>El hash del instalador no coincide.</value>\n  </data>\n  <data name=\"PolicyEnableHashOverride\" xml:space=\"preserve\">\n    <value>Habilitar la sobreescritura del hash del instalador de aplicaciones de Windows</value>\n  </data>\n  <data name=\"SourceExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Exportar los orígenes actuales como JSON para la directiva de grupo.</value>\n  </data>\n  <data name=\"SourceExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Exportar los orígenes actuales</value>\n  </data>\n  <data name=\"SourceListAdditionalSource\" xml:space=\"preserve\">\n    <value>Origen adicional</value>\n    <comment>An additional source required by policy.</comment>\n  </data>\n  <data name=\"SourceListAllowedSource\" xml:space=\"preserve\">\n    <value>Origen permitido</value>\n    <comment>A source that the user is allowed to add.</comment>\n  </data>\n  <data name=\"InvalidArgumentValueErrorWithoutValidValues\" xml:space=\"preserve\">\n    <value>El valor proporcionado para el argumento '{0}' no es válido</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an invalid command line argument value. {0} is a placeholder replaced by the argument name.</comment>\n  </data>\n  <data name=\"Cancelled\" xml:space=\"preserve\">\n    <value>Cancelado</value>\n  </data>\n  <data name=\"ExternalDependencies\" xml:space=\"preserve\">\n    <value>Externo</value>\n  </data>\n  <data name=\"ImportCommandReportDependencies\" xml:space=\"preserve\">\n    <value>Los paquetes encontrados en esta importación tienen las siguientes dependencias:</value>\n    <comment>Import command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"PackageRequiresDependencies\" xml:space=\"preserve\">\n    <value>Este paquete requiere las siguientes dependencias:</value>\n    <comment>Message shown before reporting dependencies</comment>\n  </data>\n  <data name=\"DependenciesFlowInstall\" xml:space=\"preserve\">\n    <value>Instalando dependencias:</value>\n  </data>\n  <data name=\"DependenciesFlowSourceNotFound\" xml:space=\"preserve\">\n    <value>No se encontró el origen de la dependencia</value>\n  </data>\n  <data name=\"DependenciesFlowSourceTooManyMatches\" xml:space=\"preserve\">\n    <value>La búsqueda de paquetes produce más de un resultado: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when application packages search yield more than one result. {0} is a placeholder replaced by the dependency package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowPackageVersionNotFound\" xml:space=\"preserve\">\n    <value>No se encontró la última versión del paquete: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when no suitable version found for the specific application package. {0} is a placeholder replaced by the package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoInstallerFound\" xml:space=\"preserve\">\n    <value>No se encontraron instaladores: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when no installer found for a manifest. {0} is a placeholder replaced by the manifest identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoMinVersion\" xml:space=\"preserve\">\n    <value>Versión mínima requerida no disponible para el paquete: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the minimum required version is not available for an application package. {0} is a placeholder replaced by the package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoMatches\" xml:space=\"preserve\">\n    <value>Sin coincidencias</value>\n    <comment>When package search yields no matches</comment>\n  </data>\n  <data name=\"DependenciesFlowContainsLoop\" xml:space=\"preserve\">\n    <value>Tiene bucle</value>\n    <comment>Dependency graph has loop</comment>\n  </data>\n  <data name=\"DependenciesFlowNoSuitableInstallerFound\" xml:space=\"preserve\">\n    <value>No se encontró ningún instalador adecuado para el manifiesto: {0} versión {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message displayed when an attempt to get a preferred installer for a manifest fails. {0} is a placeholder replaced by the manifest identifier. {1} is a placeholder replaced by the manifest version.</comment>\n  </data>\n  <data name=\"DependenciesManagementError\" xml:space=\"preserve\">\n    <value>Error al procesar las dependencias del paquete. ¿Desea continuar con la instalación?</value>\n    <comment>Prompt message shown when dependencies processing yields errors.</comment>\n  </data>\n  <data name=\"DependenciesManagementExitMessage\" xml:space=\"preserve\">\n    <value>Error al procesar las dependencias del paquete. Saliendo...</value>\n  </data>\n  <data name=\"PackageDependencies\" xml:space=\"preserve\">\n    <value>Paquetes</value>\n  </data>\n  <data name=\"UninstallCommandReportDependencies\" xml:space=\"preserve\">\n    <value>Este paquete tenía dependencias que es posible que ya no sean necesarias:</value>\n    <comment>Uninstall command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"ValidateCommandReportDependencies\" xml:space=\"preserve\">\n    <value>El manifiesto tiene las siguientes dependencias que no se validaron; asegúrese de que son válidas:</value>\n    <comment>Validate command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"WindowsFeaturesDependencies\" xml:space=\"preserve\">\n    <value>Características de Windows</value>\n  </data>\n  <data name=\"WindowsLibrariesDependencies\" xml:space=\"preserve\">\n    <value>Bibliotecas de Windows</value>\n  </data>\n  <data name=\"DependencySourceArgumentDescription\" xml:space=\"preserve\">\n    <value>Buscar dependencias de paquete con el origen especificado</value>\n    <comment>For getting package type dependencies when installing from a local manifest</comment>\n  </data>\n  <data name=\"WindowsStoreTerms\" xml:space=\"preserve\">\n    <value>Términos de Microsoft Store</value>\n  </data>\n  <data name=\"AcceptPackageAgreementsArgumentDescription\" xml:space=\"preserve\">\n    <value>Aceptar todos los contratos de licencia para paquetes</value>\n  </data>\n  <data name=\"ExportedPackageRequiresLicenseAgreement\" xml:space=\"preserve\">\n    <value>El paquete exportado requiere un contrato de licencia para instalar: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when an exported application package requires license agreement to install. {0} is a placeholder replaced by the package name.</comment>\n  </data>\n  <data name=\"PackageAgreementsPrompt\" xml:space=\"preserve\">\n    <value>El editor requiere que vea la información anterior y acepte los contratos antes de la instalación.\n¿Acepta los términos?</value>\n  </data>\n  <data name=\"PackageAgreementsNotAgreedTo\" xml:space=\"preserve\">\n    <value>No se han aceptado los acuerdos de paquete. Operación cancelada.</value>\n  </data>\n  <data name=\"ShowLabelAgreements\" xml:space=\"preserve\">\n    <value>Acuerdos:</value>\n  </data>\n  <data name=\"ShowLabelAuthor\" xml:space=\"preserve\">\n    <value>Autor:</value>\n  </data>\n  <data name=\"ShowLabelDescription\" xml:space=\"preserve\">\n    <value>Descripción:</value>\n  </data>\n  <data name=\"ShowLabelInstaller\" xml:space=\"preserve\">\n    <value>Instalador:</value>\n  </data>\n  <data name=\"ShowLabelInstallerLocale\" xml:space=\"preserve\">\n    <value>Configuración regional del instalador:</value>\n  </data>\n  <data name=\"ShowLabelInstallerProductId\" xml:space=\"preserve\">\n    <value>Id. de producto de Store:</value>\n  </data>\n  <data name=\"ShowLabelInstallerSha256\" xml:space=\"preserve\">\n    <value>Instalador SHA256:</value>\n  </data>\n  <data name=\"ShowLabelInstallerType\" xml:space=\"preserve\">\n    <value>Tipo de instalador:</value>\n  </data>\n  <data name=\"ShowLabelInstallerUrl\" xml:space=\"preserve\">\n    <value>Dirección URL del instalador:</value>\n  </data>\n  <data name=\"ShowLabelLicense\" xml:space=\"preserve\">\n    <value>Licencia:</value>\n  </data>\n  <data name=\"ShowLabelLicenseUrl\" xml:space=\"preserve\">\n    <value>Dirección URL de la licencia:</value>\n  </data>\n  <data name=\"ShowLabelMoniker\" xml:space=\"preserve\">\n    <value>Moniker:</value>\n  </data>\n  <data name=\"ShowLabelPackageUrl\" xml:space=\"preserve\">\n    <value>Página principal:</value>\n  </data>\n  <data name=\"ShowLabelPublisher\" xml:space=\"preserve\">\n    <value>Editor:</value>\n  </data>\n  <data name=\"ShowLabelTags\" xml:space=\"preserve\">\n    <value>Etiquetas:</value>\n  </data>\n  <data name=\"ShowLabelVersion\" xml:space=\"preserve\">\n    <value>Versión:</value>\n  </data>\n  <data name=\"ShowLabelDependencies\" xml:space=\"preserve\">\n    <value>Dependencias:</value>\n  </data>\n  <data name=\"ShowLabelWindowsFeaturesDependencies\" xml:space=\"preserve\">\n    <value>Características de Windows:</value>\n  </data>\n  <data name=\"ShowLabelWindowsLibrariesDependencies\" xml:space=\"preserve\">\n    <value>Bibliotecas de Windows:</value>\n  </data>\n  <data name=\"ShowLabelPackageDependencies\" xml:space=\"preserve\">\n    <value>Dependencias de paquete:</value>\n  </data>\n  <data name=\"ShowLabelExternalDependencies\" xml:space=\"preserve\">\n    <value>Dependencias externas:</value>\n  </data>\n  <data name=\"PromptOptionNo\" xml:space=\"preserve\">\n    <value>No</value>\n  </data>\n  <data name=\"PromptOptionYes\" xml:space=\"preserve\">\n    <value>Sí</value>\n  </data>\n  <data name=\"SourceAddOpenSourceFailed\" xml:space=\"preserve\">\n    <value>No se pudo abrir el origen agregado.</value>\n  </data>\n  <data name=\"AcceptSourceAgreementsArgumentDescription\" xml:space=\"preserve\">\n    <value>Aceptar todos los contratos de origen durante las operaciones de origen</value>\n  </data>\n  <data name=\"SourceAgreementsTitle\" xml:space=\"preserve\">\n    <value>El origen '{0}' requiere que vea los siguientes contratos antes de usarlo.</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user that a repository source requires viewing agreements before using. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceAgreementsPrompt\" xml:space=\"preserve\">\n    <value>¿Está de acuerdo con todos los términos de los contratos de origen?</value>\n  </data>\n  <data name=\"SourceAgreementsNotAgreedTo\" xml:space=\"preserve\">\n    <value>No se han aceptado uno o varios de los contratos de origen. Operación cancelada. Acepte los contratos de origen o quite los orígenes correspondientes.</value>\n  </data>\n  <data name=\"SourceAgreementsMarketMessage\" xml:space=\"preserve\">\n    <value>El origen requiere que la región geográfica de dos letras de la máquina actual se envíe al servicio back-end para que funcione correctamente (por ejemplo, \"EE. UU.\").</value>\n  </data>\n  <data name=\"InstallFlowRegistrationDeferred\" xml:space=\"preserve\">\n    <value>Se instaló correctamente. Reinicie la aplicación para completar la actualización.</value>\n  </data>\n  <data name=\"HeaderArgumentDescription\" xml:space=\"preserve\">\n    <value>Encabezado HTTP de origen REST opcional de Windows-Package-Manager</value>\n  </data>\n  <data name=\"HeaderArgumentNotApplicableForNonRestSourceWarning\" xml:space=\"preserve\">\n    <value>Omitiendo el encabezado opcional porque no es aplicable para este origen.</value>\n  </data>\n  <data name=\"HeaderArgumentNotApplicableWithoutSource\" xml:space=\"preserve\">\n    <value>El encabezado opcional no es aplicable sin especificar un origen: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user performs an operation (e.g install) and provides the HTTP 'header' argument without specifying the repository source. {0} is a placeholder replaced by the header argument name.</comment>\n  </data>\n  <data name=\"ShowLabelInstallerReleaseDate\" xml:space=\"preserve\">\n    <value>Fecha de lanzamiento:</value>\n  </data>\n  <data name=\"ShowLabelInstallerOfflineDistributionSupported\" xml:space=\"preserve\">\n    <value>Distribución sin conexión admitida:</value>\n  </data>\n  <data name=\"ShowLabelPublisherUrl\" xml:space=\"preserve\">\n    <value>Dirección URL del editor:</value>\n  </data>\n  <data name=\"ShowLabelPurchaseUrl\" xml:space=\"preserve\">\n    <value>Dirección URL de compra:</value>\n  </data>\n  <data name=\"ShowLabelPublisherSupportUrl\" xml:space=\"preserve\">\n    <value>Dirección URL de soporte del editor:</value>\n  </data>\n  <data name=\"ShowLabelPrivacyUrl\" xml:space=\"preserve\">\n    <value>Dirección URL de privacidad:</value>\n  </data>\n  <data name=\"ShowLabelCopyright\" xml:space=\"preserve\">\n    <value>Copyright:</value>\n  </data>\n  <data name=\"ShowLabelCopyrightUrl\" xml:space=\"preserve\">\n    <value>Dirección URL de copyright:</value>\n  </data>\n  <data name=\"ShowLabelReleaseNotes\" xml:space=\"preserve\">\n    <value>Notas de la versión:</value>\n  </data>\n  <data name=\"ShowLabelReleaseNotesUrl\" xml:space=\"preserve\">\n    <value>Dirección URL de notas de la versión:</value>\n  </data>\n  <data name=\"SearchFailureWarning\" xml:space=\"preserve\">\n    <value>Error al buscar en el origen, los resultados no se incluirán: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when searching a repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SearchFailureError\" xml:space=\"preserve\">\n    <value>Error al buscar en el origen: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when searching a repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"FeatureDisabledByAdminSettingMessage\" xml:space=\"preserve\">\n    <value>Esta función debe ser activada por los administradores. Para activarla, ejecute 'winget settings --enable {0}' como administrador.</value>\n    <comment>{Locked=\"winget settings --enable\", \"{0}\"}. Error message displayed when the user uses a feature that needs to be enabled by administrators. {0} is a placeholder replaced by the admin setting.</comment>\n  </data>\n  <data name=\"AdminSettingEnableDescription\" xml:space=\"preserve\">\n    <value>Habilita la configuración de administrador específica</value>\n  </data>\n  <data name=\"AdminSettingDisableDescription\" xml:space=\"preserve\">\n    <value>Deshabilita la configuración de administrador específica</value>\n  </data>\n  <data name=\"AdminSettingEnabled\" xml:space=\"preserve\">\n    <value>Configuración de administrador habilitada \"{0}\".</value>\n    <comment>{Locked=\"{0}\"} Message displayed when the user enables an admin setting. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"AdminSettingDisabled\" xml:space=\"preserve\">\n    <value>Configuración de administrador deshabilitada \"{0}\".</value>\n    <comment>{Locked=\"{0}\"} Message displayed when the user disables an admin setting. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"AdminSettingHeader\" xml:space=\"preserve\">\n    <value>Configuración de administrador</value>\n    <comment>Header for a table displaying admin settings.</comment>\n  </data>\n  <data name=\"InstallFlowReturnCodePackageInUse\" xml:space=\"preserve\">\n    <value>La aplicación se está ejecutando actualmente. Salga de la aplicación e inténtelo de nuevo.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodePackageInUseByApplication\" xml:space=\"preserve\">\n    <value>Otra aplicación está usando los archivos modificados por el instalador. Salga de las aplicaciones e inténtelo de nuevo.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInstallInProgress\" xml:space=\"preserve\">\n    <value>Ya hay otra instalación en curso. Inténtelo de nuevo más tarde.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeFileInUse\" xml:space=\"preserve\">\n    <value>Se están usando uno o varios archivos. Salga de la aplicación e inténtelo de nuevo.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeMissingDependency\" xml:space=\"preserve\">\n    <value>Falta una dependencia de este paquete en el sistema.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeDiskFull\" xml:space=\"preserve\">\n    <value>No hay más espacio en el equipo. Haga espacio e inténtelo de nuevo.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInsufficientMemory\" xml:space=\"preserve\">\n    <value>No hay suficiente memoria disponible para instalar. Cierre otras aplicaciones e inténtelo de nuevo.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInvalidParameter\" xml:space=\"preserve\">\n    <value>Uno de los parámetros de instalación no es válido. Es posible que el registro de instalación del paquete tenga detalles adicionales.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeNoNetwork\" xml:space=\"preserve\">\n    <value>Esta aplicación requiere conectividad a Internet. Conéctese a una red e inténtelo de nuevo.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeContactSupport\" xml:space=\"preserve\">\n    <value>Esta aplicación encontró un error durante la instalación. Póngase en contacto con el soporte técnico.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootRequiredToFinish\" xml:space=\"preserve\">\n    <value>Reinicie el equipo para finalizar la instalación.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootRequiredForInstall\" xml:space=\"preserve\">\n    <value>El equipo se reiniciará para finalizar la instalación.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootInitiated\" xml:space=\"preserve\">\n    <value>Error en la instalación. Reinicia el equipo e inténtalo de nuevo.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeCancelledByUser\" xml:space=\"preserve\">\n    <value>Ha cancelado la instalación.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeAlreadyInstalled\" xml:space=\"preserve\">\n    <value>Ya hay otra versión de esta aplicación instalada.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeDowngrade\" xml:space=\"preserve\">\n    <value>Ya hay instalada una versión posterior de esta aplicación.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeBlockedByPolicy\" xml:space=\"preserve\">\n    <value>Las directivas de la organización impiden la instalación. Póngase en contacto con su administrador.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeSystemNotSupported\" xml:space=\"preserve\">\n    <value>La configuración del sistema actual no admite la instalación de este paquete.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeCustomError\" xml:space=\"preserve\">\n    <value>La instalación falló debido a un error del instalador personalizado. Póngase en contacto con la asistencia técnica del paquete.</value>\n  </data>\n  <data name=\"InstallAbandoned\" xml:space=\"preserve\">\n    <value>Instalación abandonada</value>\n  </data>\n  <data name=\"InstallerFailedWithCode\" xml:space=\"preserve\">\n    <value>Error del instalador con el código de salida: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the application installer fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"InstallerLogAvailable\" xml:space=\"preserve\">\n    <value>El registro del instalador está disponible en: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about the system path of a diagnostic files containing information about the installer. {0} is a placeholder replaced by the diagnostic file system path.</comment>\n  </data>\n  <data name=\"SearchFailureErrorListMatches\" xml:space=\"preserve\">\n    <value>Se encontraron los siguientes paquetes entre los orígenes que funcionan.\nEspecifique uno de ellos con la opción --source para continuar.</value>\n    <comment>{Locked=\"--source\"} \"working sources\" as in \"sources that are working correctly\"</comment>\n  </data>\n  <data name=\"SearchFailureErrorNoMatches\" xml:space=\"preserve\">\n    <value>No se encontraron paquetes entre los orígenes que funcionan.</value>\n    <comment>\"working sources\" as in \"sources that are working correctly\"</comment>\n  </data>\n  <data name=\"FeaturesMessageDisabledByBuild\" xml:space=\"preserve\">\n    <value>Esto es una versión estable del Administrador de paquetes de Windows. Si desea probar las características experimentales, instale una compilación de versión preliminar. Las instrucciones están disponibles en GitHub en https://github.com/microsoft/winget-cli.</value>\n    <comment>{Locked=\"https://github.com/microsoft/winget-cli\"}</comment>\n  </data>\n  <data name=\"WindowsPackageManager\" xml:space=\"preserve\">\n    <value>Administrador de paquetes de Windows v{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying the product name and version. {0} is a placeholder replaced by the product version.</comment>\n  </data>\n  <data name=\"ImportIgnorePackageVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Omitir las versiones del paquete de la importación del archivo</value>\n  </data>\n  <data name=\"CountOutOfBoundsError\" xml:space=\"preserve\">\n    <value>El número de resultados solicitado debe estar entre 1 y 1000.</value>\n  </data>\n  <data name=\"CustomSwitchesArgumentDescription\" xml:space=\"preserve\">\n    <value>Argumentos que se van a pasar al instalador además de los valores predeterminados</value>\n  </data>\n  <data name=\"UpgradeDifferentInstallTechnologyInNewerVersions\" xml:space=\"preserve\">\n    <value>Se encontró una versión más reciente, pero la tecnología de instalación es diferente de la versión actual instalada. Desinstale el paquete e instale la versión más reciente.</value>\n  </data>\n  <data name=\"UpgradeDifferentInstallTechnology\" xml:space=\"preserve\">\n    <value>La tecnología de instalación de la versión más reciente especificada es diferente de la versión actual instalada. Desinstale el paquete e instale la versión más reciente.</value>\n  </data>\n  <data name=\"WindowsPackageManagerPreview\" xml:space=\"preserve\">\n    <value>Administrador de paquetes de Windows (Versión preliminar) v{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying the preview product name and pre-release version. {0} is a placeholder replaced by the product version.</comment>\n  </data>\n  <data name=\"ArchitectureArgumentDescription\" xml:space=\"preserve\">\n    <value>Selección de la arquitectura</value>\n  </data>\n  <data name=\"IncludeUnknownArgumentDescription\" xml:space=\"preserve\">\n    <value>Actualizar paquetes aunque no se pueda determinar su versión actual</value>\n  </data>\n  <data name=\"IncludeUnknownInListArgumentDescription\" xml:space=\"preserve\">\n    <value>Enumere los paquetes incluso si no se puede determinar su versión actual. Solo se puede usar con el argumento --upgrade-available</value>\n    <comment>{Locked=\"--upgrade-available\"}</comment>\n  </data>\n  <data name=\"UpgradeUnknownVersionExplanation\" xml:space=\"preserve\">\n    <value>No se puede determinar el número de versión de este paquete. Para actualizarlo de todos modos, agregue el argumento --include-unknown al comando anterior.</value>\n    <comment>{Locked=\"--include-unknown\"}</comment>\n  </data>\n  <data name=\"UpgradeUnknownVersionCount\" xml:space=\"preserve\">\n    <value>{0} paquete(s) tienen números de versión que no se pueden determinar. Use --include-unknown para ver todos los resultados.</value>\n    <comment>{Locked=\"{0}\",\"--include-unknown\"} {0} is a placeholder that is replaced by an integer number of packages that do not have notated versions. </comment>\n  </data>\n  <data name=\"UpgradeRequireExplicitCount\" xml:space=\"preserve\">\n    <value>{0} paquetes están anclados y deben actualizarse explícitamente.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by an integer number of packages that require explicit upgrades.</comment>\n  </data>\n  <data name=\"InvalidArgumentWithoutQueryError\" xml:space=\"preserve\">\n    <value>Los argumentos proporcionados solo se pueden usar con una consulta.</value>\n  </data>\n  <data name=\"SystemArchitecture\" xml:space=\"preserve\">\n    <value>Arquitectura del sistema: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for the system architecture. {0} is a placeholder replaced by the value of the system architecture (e.g. X64).</comment>\n  </data>\n  <data name=\"PreserveArgumentDescription\" xml:space=\"preserve\">\n    <value>Conserva todos los archivos y directorios creados por el paquete (portable)</value>\n  </data>\n  <data name=\"PurgeArgumentDescription\" xml:space=\"preserve\">\n    <value>Elimina todos los archivos y directorios del directorio del paquete (portable)</value>\n  </data>\n  <data name=\"PressEnterToContinue\" xml:space=\"preserve\">\n    <value>Presione Entrar para continuar . . .</value>\n  </data>\n  <data name=\"RenameArgumentDescription\" xml:space=\"preserve\">\n    <value>Valor para cambiar el nombre del archivo ejecutable (portable)</value>\n  </data>\n  <data name=\"WaitArgumentDescription\" xml:space=\"preserve\">\n    <value>Pide al usuario que presione cualquier tecla antes de salir</value>\n  </data>\n  <data name=\"InstallerElevationExpected\" xml:space=\"preserve\">\n    <value>El instalador solicitará que se ejecute como administrador. Espere una indicación.</value>\n  </data>\n  <data name=\"InstallerProhibitsElevation\" xml:space=\"preserve\">\n    <value>El instalador no se puede ejecutar desde un contexto de administrador.</value>\n  </data>\n  <data name=\"ModifiedPathRequiresShellRestart\" xml:space=\"preserve\">\n    <value>Variable de entorno PATH modificada; reinicie el shell para usar el nuevo valor.</value>\n  </data>\n  <data name=\"ProductCodeArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtra con el código de producto</value>\n  </data>\n  <data name=\"PortableRegistryCollisionOverridden\" xml:space=\"preserve\">\n    <value>Ya existe un paquete portable con el mismo nombre pero de otro origen; continuando debido a --force</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"ReparsePointsNotSupportedError\" xml:space=\"preserve\">\n    <value>El volumen no admite puntos de análisis</value>\n  </data>\n  <data name=\"ReservedFilenameError\" xml:space=\"preserve\">\n    <value>El nombre de archivo especificado no es un nombre de archivo válido</value>\n  </data>\n  <data name=\"OverwritingExistingFileAtMessage\" xml:space=\"preserve\">\n    <value>Sobrescribiendo archivo existente: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed to inform the user that an existing file is being overwritten. {0} is a placeholder replaced by the file system path.</comment>\n  </data>\n  <data name=\"NoPackageSelectionArgumentProvided\" xml:space=\"preserve\">\n    <value>No se ha proporcionado ningún argumento de selección de paquete; vea la ayuda para obtener más información sobre cómo buscar un paquete.</value>\n  </data>\n  <data name=\"PortableAliasAdded\" xml:space=\"preserve\">\n    <value>Alias de línea de comandos agregado:</value>\n  </data>\n  <data name=\"PortableLinksMachine\" xml:space=\"preserve\">\n    <value>Directorio de vínculos portátiles (equipo)</value>\n  </data>\n  <data name=\"PortableLinksUser\" xml:space=\"preserve\">\n    <value>Directorio de vínculos portátiles (usuario)</value>\n  </data>\n  <data name=\"PortableRootUser\" xml:space=\"preserve\">\n    <value>Raíz de paquete portátil (usuario)</value>\n  </data>\n  <data name=\"PortableRoot\" xml:space=\"preserve\">\n    <value>Raíz de paquete portátil</value>\n  </data>\n  <data name=\"PortableRoot86\" xml:space=\"preserve\">\n    <value>Raíz de paquete portátil (x86)</value>\n  </data>\n  <data name=\"PortableInstallFailed\" xml:space=\"preserve\">\n    <value>Error en la instalación portable. Limpiando...</value>\n  </data>\n  <data name=\"PortableHashMismatchOverridden\" xml:space=\"preserve\">\n    <value>Se ha modificado el paquete portátil; se puede continuar debido a --force</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"PortableHashMismatchOverrideRequired\" xml:space=\"preserve\">\n    <value>No se puede quitar el paquete portátil porque se ha modificado; para invalidar esta comprobación, use --force</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"FilesRemainInInstallDirectory\" xml:space=\"preserve\">\n    <value>Quedan archivos en el directorio de instalación: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when files remain in install directory. {0} is a placeholder replaced by the directory path.</comment>\n  </data>\n  <data name=\"PurgeInstallDirectory\" xml:space=\"preserve\">\n    <value>Purgando directorio de instalación...</value>\n  </data>\n  <data name=\"UnableToPurgeInstallDirectory\" xml:space=\"preserve\">\n    <value>No se puede purgar el directorio de instalación porque WinGet no lo ha creado</value>\n  </data>\n  <data name=\"RelatedLink\" xml:space=\"preserve\">\n    <value>Vínculo relacionado</value>\n  </data>\n  <data name=\"ShowLabelDocumentation\" xml:space=\"preserve\">\n    <value>Documentación:</value>\n  </data>\n  <data name=\"Notes\" xml:space=\"preserve\">\n    <value>Notas: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for installation notes. {0} is a placeholder replaced by installation notes.</comment>\n  </data>\n  <data name=\"ShowLabelInstallationNotes\" xml:space=\"preserve\">\n    <value>Notas de instalación:</value>\n  </data>\n  <data name=\"UnsupportedArgument\" xml:space=\"preserve\">\n    <value>No se admite un argumento proporcionado para este paquete</value>\n  </data>\n  <data name=\"ExtractArchiveFailed\" xml:space=\"preserve\">\n    <value>No se pudo extraer el contenido del archivo</value>\n  </data>\n  <data name=\"NestedInstallerNotFound\" xml:space=\"preserve\">\n    <value>El archivo de instalador anidado no existe. Asegúrese de que la ruta de acceso relativa especificada del instalador anidado coincide con: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when nested installer file does not exist. {0} is a placeholder replaced by the nested installer file path.</comment>\n  </data>\n  <data name=\"InvalidPathToNestedInstaller\" xml:space=\"preserve\">\n    <value>Ruta de acceso relativa de archivo no válida para el instalador anidado; la ruta de acceso señala a una ubicación fuera del directorio de instalación</value>\n  </data>\n  <data name=\"NestedInstallerNotSpecified\" xml:space=\"preserve\">\n    <value>No se ha especificado ningún instalador anidado para este paquete</value>\n  </data>\n  <data name=\"MultipleUnsupportedNestedInstallersSpecified\" xml:space=\"preserve\">\n    <value>Solo se puede especificar un instalador anidado para un instalador de archivo a menos que sea un instalador anidado de fuente o portátil</value>\n  </data>\n  <data name=\"IncompatibleArgumentsProvided\" xml:space=\"preserve\">\n    <value>Argumentos de línea de comandos no compatibles proporcionados</value>\n  </data>\n  <data name=\"UpgradeArgumentDescription\" xml:space=\"preserve\">\n    <value>Enumere solo los paquetes que tienen una actualización disponible</value>\n  </data>\n  <data name=\"UpgradeAvailableForPinned\" xml:space=\"preserve\">\n    <value>Los siguientes paquetes tienen una actualización disponible, pero requieren un destino explícito para la actualización:</value>\n    <comment>\"require explicit targeting for upgrade\" means that the package will not be upgraded with all others unless an extra flag is added, or the package is mentioned explicitly</comment>\n  </data>\n  <data name=\"Downloading\" xml:space=\"preserve\">\n    <value>Descargando</value>\n    <comment>Label displayed while downloading an application installer.</comment>\n  </data>\n  <data name=\"NestedInstallerNotSupported\" xml:space=\"preserve\">\n    <value>No se admite el tipo de instalador anidado</value>\n  </data>\n  <data name=\"InstallerAbortsTerminal\" xml:space=\"preserve\">\n    <value>Se sabe que este instalador reinicia el terminal o el shell</value>\n  </data>\n  <data name=\"InstallerRequiresInstallLocation\" xml:space=\"preserve\">\n    <value>Este paquete requiere una ubicación de instalación</value>\n  </data>\n  <data name=\"InstallersAbortTerminal\" xml:space=\"preserve\">\n    <value>Se sabe que los instaladores siguientes reinician el terminal o el shell:</value>\n  </data>\n  <data name=\"InstallersRequireInstallLocation\" xml:space=\"preserve\">\n    <value>Los instaladores siguientes requieren una ubicación de instalación:</value>\n  </data>\n  <data name=\"PromptForInstallRoot\" xml:space=\"preserve\">\n    <value>Especifique la raíz de instalación:</value>\n  </data>\n  <data name=\"PromptToProceed\" xml:space=\"preserve\">\n    <value>¿Desea continuar?</value>\n  </data>\n  <data name=\"ReportIdentityForAgreements\" xml:space=\"preserve\">\n    <value>Contratos para</value>\n    <comment>This will be followed by a package name, and then a list of license agreements</comment>\n  </data>\n  <data name=\"InstallLocationNotProvided\" xml:space=\"preserve\">\n    <value>El paquete requiere la ubicación de instalación, pero no se ha proporcionado</value>\n  </data>\n  <data name=\"DisableInteractivityArgumentDescription\" xml:space=\"preserve\">\n    <value>Deshabilitar mensajes interactivos</value>\n    <comment>Description for a command line argument, shown next to it in the help</comment>\n  </data>\n  <data name=\"ConvertInstallFlowToUpgrade\" xml:space=\"preserve\">\n    <value>Se encontró un paquete existente ya instalado. Intentando actualizar el paquete instalado...</value>\n  </data>\n  <data name=\"ForceArgumentDescription\" xml:space=\"preserve\">\n    <value>Ejecutar directamente el comando y continuar con problemas no relacionados con la seguridad</value>\n    <comment>Description for a command line argument, shown next to it in the help</comment>\n  </data>\n  <data name=\"PortablePackageAlreadyExists\" xml:space=\"preserve\">\n    <value>Ya existe un paquete portátil de otro origen</value>\n  </data>\n  <data name=\"ExtractArchiveSucceeded\" xml:space=\"preserve\">\n    <value>Archivo extraído correctamente</value>\n  </data>\n  <data name=\"ExtractingArchive\" xml:space=\"preserve\">\n    <value>Extrayendo archivo...</value>\n  </data>\n  <data name=\"ArchiveFailedMalwareScan\" xml:space=\"preserve\">\n    <value>El examen de archivo detectó malware. Para invalidar esta comprobación, use --ignore-local-archive-malware-scan</value>\n    <comment>{Locked=\"--ignore-local-archive-malware-scan\"}</comment>\n  </data>\n  <data name=\"ArchiveFailedMalwareScanOverridden\" xml:space=\"preserve\">\n    <value>El examen de archivo detectó malware. Continuar debido a --ignore-local-archive-malware-scan</value>\n    <comment>{Locked=\"--ignore-local-archive-malware-scan\"}</comment>\n  </data>\n  <data name=\"NoUpgradeArgumentDescription\" xml:space=\"preserve\">\n    <value>Omite la actualización si ya existe una versión instalada</value>\n  </data>\n  <data name=\"PackageAlreadyInstalled\" xml:space=\"preserve\">\n    <value>Ya hay instalada una versión del paquete. Instalación cancelada.</value>\n  </data>\n  <data name=\"EnableAdminSettingFailed\" xml:space=\"preserve\">\n    <value>No se puede habilitar {0}. Esta configuración está controlada por la directiva. Para obtener más información, póngase en contacto con el administrador del sistema.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"DisableAdminSettingFailed\" xml:space=\"preserve\">\n    <value>No se puede deshabilitar {0}. Esta configuración está controlada por la directiva. Para obtener más información, póngase en contacto con el administrador del sistema.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"PinAddCommandLongDescription\" xml:space=\"preserve\">\n    <value>Agrega un nuevo PIN. Un PIN puede limitar el Administrador de paquetes de Windows de actualizar un paquete a intervalos específicos de versiones, o puede impedir que se actualice el paquete por completo. Es posible que un paquete anclado aún se actualice por sí solo y se actualice desde fuera del Administrador de paquetes de Windows. De forma predeterminada, un paquete anclado se puede actualizar mencionándolo explícitamente en el comando \"upgrade\" o agregando la marca \"--include-pinned\" a \"winget upgrade --all\".</value>\n    <comment>{Locked{\"'upgrade'\"} Locked{\"--include-pinned\"} Locked{\"winget upgrade --all\"}</comment>\n  </data>\n  <data name=\"PinAddCommandShortDescription\" xml:space=\"preserve\">\n    <value>Crear un nuevo PIN</value>\n  </data>\n  <data name=\"PinCommandLongDescription\" xml:space=\"preserve\">\n    <value>Administre los pines de paquete con los submenses. Un PIN puede limitar el Administrador de paquetes de Windows de actualizar un paquete a intervalos específicos de versiones, o puede impedir que se actualice el paquete por completo. Un paquete anclado aún puede actualizarse por sí solo y actualizarse desde fuera del Administrador de paquetes de Windows.</value>\n  </data>\n  <data name=\"PinCommandShortDescription\" xml:space=\"preserve\">\n    <value>Administrar PIN de paquete</value>\n  </data>\n  <data name=\"PinListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Enumere todos los PIN actuales o detalles completos de un PIN específico.</value>\n  </data>\n  <data name=\"PinListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Lista de PIN actuales</value>\n  </data>\n  <data name=\"PinRemoveCommandLongDescription\" xml:space=\"preserve\">\n    <value>Quite un PIN de paquete específico.</value>\n  </data>\n  <data name=\"PinRemoveCommandShortDescription\" xml:space=\"preserve\">\n    <value>Quitar un PIN de paquete</value>\n  </data>\n  <data name=\"PinResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>Restablecer todos los PIN existentes.</value>\n  </data>\n  <data name=\"PinResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>Restablecer PIN</value>\n  </data>\n  <data name=\"GatedVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>Versión a la que se ancla el paquete. El carácter comodín \"*\" se puede usar como parte de la última versión.</value>\n  </data>\n  <data name=\"PinAddBlockingArgumentDescription\" xml:space=\"preserve\">\n    <value>Impedir que se actualice hasta que se quite el PIN, lo que impide invalidar argumentos</value>\n  </data>\n  <data name=\"PinInstalledArgumentDescription\" xml:space=\"preserve\">\n    <value>Anclar una versión instalada específica</value>\n  </data>\n  <data name=\"PinInstalledSource\" xml:space=\"preserve\">\n    <value>Instalado</value>\n    <comment>Value used in a table to indicate that a package comes from the list of packages installed in the machine</comment>\n  </data>\n  <data name=\"SettingsExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Exportar configuración como JSON</value>\n  </data>\n  <data name=\"SettingsExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Exportar configuración</value>\n  </data>\n  <data name=\"UserSettings\" xml:space=\"preserve\">\n    <value>Configuración de usuario</value>\n    <comment>Label displayed for the file containing the user settings.</comment>\n  </data>\n  <data name=\"SettingsWarningUsingDefault\" xml:space=\"preserve\">\n    <value>No se pudo cargar el archivo de configuración. Se usarán los valores predeterminados.</value>\n  </data>\n  <data name=\"InstalledScopeArgumentDescription\" xml:space=\"preserve\">\n    <value>Seleccionar filtro de ámbito de paquete instalado (user o machine)</value>\n    <comment>{Locked=\"user\",\"machine\"} This argument allows the user to select installed packages for just the user or for the entire machine.</comment>\n  </data>\n  <data name=\"PinAdded\" xml:space=\"preserve\">\n    <value>Anclaje agregado correctamente</value>\n  </data>\n  <data name=\"PinAlreadyExists\" xml:space=\"preserve\">\n    <value>Ya hay un PIN para el paquete {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that will be replaced by a package name. The message is shown when attempting to add a pin for a package that is already pinned.</comment>\n  </data>\n  <data name=\"PinExistsOverwriting\" xml:space=\"preserve\">\n    <value>Ya existe un PIN para el paquete {0}. Sobrescribiendo debido al argumento --force.</value>\n    <comment>{Locked=\"--force\"}{Locked=\"--force\",\"{0}\"} {0} is a placeholder that will be replaced by a package name.</comment>\n  </data>\n  <data name=\"PinExistsUseForceArg\" xml:space=\"preserve\">\n    <value>Ya existe un PIN para el paquete {0}. Use el argumento --force para sobrescribirlo.</value>\n    <comment>{Locked=\"--force\",\"{0}\"} {0} is a placeholder that will be replaced by a package name.</comment>\n  </data>\n  <data name=\"PinResettingAll\" xml:space=\"preserve\">\n    <value>Restableciendo todos los anclajes actuales.</value>\n  </data>\n  <data name=\"PinResetUseForceArg\" xml:space=\"preserve\">\n    <value>Use el argumento --force para restablecer todos los anclajes. Se quitarán los siguientes anclajes:</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"PinType\" xml:space=\"preserve\">\n    <value>Tipo de anclaje</value>\n  </data>\n  <data name=\"PinDoesNotExist\" xml:space=\"preserve\">\n    <value>No hay ningún anclaje para el paquete {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that will be replaced by a package name. The message is shown when attempting to delete a pin for a package that is not pinned.</comment>\n  </data>\n  <data name=\"PinNoPinsExist\" xml:space=\"preserve\">\n    <value>No hay anclajes configurados.</value>\n    <comment>Shown when listing or modifying existing pins if there are none.</comment>\n  </data>\n  <data name=\"PinResetSuccessful\" xml:space=\"preserve\">\n    <value>Los anclajes se restablecieron correctamente</value>\n    <comment>Shown after resetting (deleting) all the pins</comment>\n  </data>\n  <data name=\"PinCannotOpenIndex\" xml:space=\"preserve\">\n    <value>No se puede abrir la base de datos de anclaje.</value>\n    <comment>Error message for when we cannot open the database containing package pins.</comment>\n  </data>\n  <data name=\"ArgumentForSinglePackageProvidedWithMultipleQueries\" xml:space=\"preserve\">\n    <value>Se proporcionó un argumento que solo se puede usar para un solo paquete</value>\n  </data>\n  <data name=\"MultipleExclusiveArgumentsProvided\" xml:space=\"preserve\">\n    <value>Se proporcionaron varios argumentos mutuamente excluyentes: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message shown when mutually incompatible command line arguments are used. {0} is a placeholder replaced by the arguments that cannot be specified together</comment>\n  </data>\n  <data name=\"DependencyArgumentMissing\" xml:space=\"preserve\">\n    <value>La {0} de argumentos solo se puede usar con {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message shown when having an argument needs another to be present, but that is missing. {0} and {1} are replaced by the arguments. For example \"Argument --include-unknown can only be used with --upgrade\"</comment>\n  </data>\n  <data name=\"StateDisabled\" xml:space=\"preserve\">\n    <value>Deshabilitado</value>\n    <comment>As in enabled/disabled</comment>\n  </data>\n  <data name=\"StateEnabled\" xml:space=\"preserve\">\n    <value>Habilitado</value>\n    <comment>As in enabled/disabled</comment>\n  </data>\n  <data name=\"StateHeader\" xml:space=\"preserve\">\n    <value>Estado</value>\n    <comment>Header for a table listing the state (enabled/disabled) of Group Policies and Settings</comment>\n  </data>\n  <data name=\"MultiQueryArgumentDescription\" xml:space=\"preserve\">\n    <value>La consulta usada para buscar un paquete</value>\n  </data>\n  <data name=\"MultiQueryPackageNotFound\" xml:space=\"preserve\">\n    <value>No se encontró el paquete: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches returns no results. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"MultiQuerySearchFoundMultiple\" xml:space=\"preserve\">\n    <value>Se encontraron varios paquetes para: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches returns more than one result. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"MultiQuerySearchFailed\" xml:space=\"preserve\">\n    <value>Error en la búsqueda de: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches fails. This message is for generic failures, we have more specific messages for when the search returns no results, or when it returns more than one result. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"UpgradeBlockedByPinCount\" xml:space=\"preserve\">\n    <value>{0} paquetes tienen un pin que debe quitarse antes de la actualización</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by an integer number of packages with pins that prevent upgrade</comment>\n  </data>\n  <data name=\"UpgradeBlockedByManifest\" xml:space=\"preserve\">\n    <value>No se puede actualizar el paquete con winget. Use el método proporcionado por el publicador para actualizar este paquete.</value>\n  </data>\n  <data name=\"IncludePinnedArgumentDescription\" xml:space=\"preserve\">\n    <value>Actualizar paquetes aunque tengan un PIN que no sea de bloqueo</value>\n  </data>\n  <data name=\"IncludePinnedInListArgumentDescription\" xml:space=\"preserve\">\n    <value>Enumere los paquetes incluso si tienen un pin que impide la actualización. Solo se puede usar con el argumento --upgrade-available</value>\n    <comment>{Locked=\"--upgrade-available\"}</comment>\n  </data>\n  <data name=\"PinRemovedSuccessfully\" xml:space=\"preserve\">\n    <value>El anclaje se quitó correctamente</value>\n  </data>\n  <data name=\"UpgradeIsPinned\" xml:space=\"preserve\">\n    <value>Se encontró una versión más reciente, pero el paquete tiene un PIN que impide su actualización.</value>\n  </data>\n  <data name=\"PackageIsPinned\" xml:space=\"preserve\">\n    <value>El paquete está anclado y no se puede actualizar. Use el comando \"winget pin\" para ver y editar anclajes. Algunos tipos de anclaje se pueden omitir con el argumento --include-pinned.</value>\n    <comment>{Locked=\"winget pin\",\"--include-pinned\"} Error shown when we block an upgrade due to the package being pinned</comment>\n  </data>\n  <data name=\"UpgradePinnedByUserCount\" xml:space=\"preserve\">\n    <value>{0} paquetes tienen anclajes que impiden la actualización. Use el comando \"winget pin\" para ver y editar los anclajes. Si usa el argumento --include-pinned puede mostrar más resultados.</value>\n    <comment>{Locked=\"winget pin\",\"--include-pinned\"} {0} is a placeholder replaced by an integer number of packages</comment>\n  </data>\n  <data name=\"ConfigureCommandLongDescription\" xml:space=\"preserve\">\n    <value>Garantiza que el sistema coincida con el estado deseado tal y como se describe en la configuración proporcionada. Puede descargar o ejecutar procesadores para lograr el estado deseado. La configuración y los procesadores deben comprobarse para asegurarse de que son de confianza antes de aplicarlos.</value>\n  </data>\n  <data name=\"ConfigureCommandShortDescription\" xml:space=\"preserve\">\n    <value>Configura el sistema en el estado deseado</value>\n  </data>\n  <data name=\"ConfigureShowCommandLongDescription\" xml:space=\"preserve\">\n    <value>Muestra los detalles de la configuración proporcionada. De forma predeterminada, no se modificará el sistema, pero algunas opciones harán que los archivos se descarguen o carguen.</value>\n  </data>\n  <data name=\"ConfigureShowCommandShortDescription\" xml:space=\"preserve\">\n    <value>Muestra los detalles de una configuración</value>\n  </data>\n  <data name=\"ConfigureTestCommandLongDescription\" xml:space=\"preserve\">\n    <value>Comprueba que el sistema coincide con el estado deseado tal y como se describe en la configuración proporcionada. Puede descargar o ejecutar procesadores para probar el estado deseado. La configuración y los procesadores deben comprobarse para asegurarse de que son de confianza antes de ejecutarlos.</value>\n  </data>\n  <data name=\"ConfigureTestCommandShortDescription\" xml:space=\"preserve\">\n    <value>Comprueba el sistema con respecto a un estado deseado</value>\n  </data>\n  <data name=\"ConfigureValidateCommandLongDescription\" xml:space=\"preserve\">\n    <value>Valida que un archivo de configuración sea correcto.</value>\n  </data>\n  <data name=\"ConfigureValidateCommandShortDescription\" xml:space=\"preserve\">\n    <value>Valida un archivo de configuración</value>\n  </data>\n  <data name=\"ConfigurationFieldInvalidType\" xml:space=\"preserve\">\n    <value>El campo '{0}' en el archivo de configuración no es del tipo correcto.</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the field name from the file.</comment>\n  </data>\n  <data name=\"ConfigurationFileArgumentDescription\" xml:space=\"preserve\">\n    <value>La ruta al archivo de configuración</value>\n  </data>\n  <data name=\"ConfigurationFileInvalid\" xml:space=\"preserve\">\n    <value>El archivo de configuración no es válido.</value>\n  </data>\n  <data name=\"ConfigurationFileVersionUnknown\" xml:space=\"preserve\">\n    <value>Se desconoce la versión {0} del archivo de configuración.</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the version of the configuration file.</comment>\n  </data>\n  <data name=\"ConfigurationAcceptWarningArgumentDescription\" xml:space=\"preserve\">\n    <value>Acepta la advertencia de configuración, evitando un aviso interactivo</value>\n  </data>\n  <data name=\"ConfigurationApply\" xml:space=\"preserve\">\n    <value>Aplicar</value>\n    <comment>Indicates that this item is used to write state</comment>\n  </data>\n  <data name=\"ConfigurationAssert\" xml:space=\"preserve\">\n    <value>Aserción</value>\n    <comment>Indicates that this item is used to check/assert the state rather than write to it</comment>\n  </data>\n  <data name=\"ConfigurationDependencies\" xml:space=\"preserve\">\n    <value>Dependencias:{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying a list of dependencies. {0} is replaced with a space separated list of identifiers referencing other items.</comment>\n  </data>\n  <data name=\"ConfigurationFailedToApply\" xml:space=\"preserve\">\n    <value>Parte de la configuración no se aplicó correctamente.</value>\n  </data>\n  <data name=\"ConfigurationFailedToGetDetails\" xml:space=\"preserve\">\n    <value>No se pudo obtener información detallada sobre la configuración.</value>\n  </data>\n  <data name=\"ConfigurationInform\" xml:space=\"preserve\">\n    <value>informar</value>\n    <comment>Indicates that this item is used to retrieve values for future use rather than writing them</comment>\n  </data>\n  <data name=\"ConfigurationLocal\" xml:space=\"preserve\">\n    <value>Local</value>\n    <comment>Used to indicate that the item is present on the device.</comment>\n  </data>\n  <data name=\"ConfigurationModuleNameOnly\" xml:space=\"preserve\">\n    <value>Módulo: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying a module name. {0} is replaced with the name of the module from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationModuleWithDetails\" xml:space=\"preserve\">\n    <value>Módulo: {0} por {1} [{2}]</value>\n    <comment>{Locked=\"{0}\",\"{1}\",\"{2}\"} Label displaying module information. {0} is replaced by the module name. {1} is replaced by the module author. {2} is replaced by a string indicating the source of the module.</comment>\n  </data>\n  <data name=\"ConfigurationSettings\" xml:space=\"preserve\">\n    <value>Configuración:</value>\n    <comment>Label for the values that are used as inputs for this item when applying state</comment>\n  </data>\n  <data name=\"ConfigurationSuccessfullyApplied\" xml:space=\"preserve\">\n    <value>Configuración aplicada correctamente.</value>\n  </data>\n  <data name=\"ConfigurationUnitSuccessfullyApplied\" xml:space=\"preserve\">\n    <value>La unidad se ha aplicado correctamente.</value>\n  </data>\n  <data name=\"ConfigurationWaitingOnAnother\" xml:space=\"preserve\">\n    <value>Se está aplicando otra configuración al sistema. Esta configuración continuará tan pronto como sea posible...</value>\n  </data>\n  <data name=\"ConfigurationWarning\" xml:space=\"preserve\">\n    <value>Es responsable de comprender las opciones de configuración que va a ejecutar. Microsoft no es responsable del archivo de configuración que ha creado o importado. Esta configuración puede cambiar la configuración en Windows, instalar software, cambiar la configuración del software (incluida la configuración de seguridad) y aceptar contratos de usuario para paquetes y servicios de terceros en su nombre.  Al ejecutar este archivo de configuración, reconoce que comprende y acepta estos recursos y configuraciones. Sus propietarios le conceden licencia para todas las aplicaciones instaladas. Microsoft no es responsable ni concede licencias a paquetes o servicios de terceros.</value>\n    <comment>Legal approved. Do not change without approval.</comment>\n  </data>\n  <data name=\"ConfigurationWarningPromptApply\" xml:space=\"preserve\">\n    <value>¿Ha revisado la configuración y desea proceder a aplicarla al sistema?</value>\n    <comment>PM approved.</comment>\n  </data>\n  <data name=\"ConfigurationFileEmpty\" xml:space=\"preserve\">\n    <value>La configuración está vacía.</value>\n  </data>\n  <data name=\"WindowsFeatureNotFound\" xml:space=\"preserve\">\n    <value>No se ha encontrado la característica [{0}].</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Windows feature was not found on the system.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeatureOverrideRequired\" xml:space=\"preserve\">\n    <value>No se han podido habilitar las dependencias de características de Windows. Para continuar con la instalación, use \"--force\".</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"RebootRequiredToEnableWindowsFeatureOverrideRequired\" xml:space=\"preserve\">\n    <value>Es necesario reiniciar para habilitar completamente las características de Windows; para anular esta comprobación use \"--force\".</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeatureOverridden\" xml:space=\"preserve\">\n    <value>No se han podido habilitar las dependencias de características de Windows; procediendo debido a --force</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.\n{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"EnablingWindowsFeature\" xml:space=\"preserve\">\n    <value>Habilitando [{0}]...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to the user regarding which Windows Feature is being enabled.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeature\" xml:space=\"preserve\">\n    <value>No se ha podido habilitar la característica [{0}]: {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"}  An error when enabling a Windows Feature. {0} is a placeholder for the name of the Windows Feature.\n{1} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"RebootRequiredToEnableWindowsFeatureOverridden\" xml:space=\"preserve\">\n    <value>Es necesario reiniciar para habilitar completamente las características de Windows. continuar debido a --force</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.</comment>\n  </data>\n  <data name=\"InstallWaitingOnAnother\" xml:space=\"preserve\">\n    <value>Esperando a que se complete otra instalación/desinstalación...</value>\n  </data>\n  <data name=\"PinVersion\" xml:space=\"preserve\">\n    <value>Versión anclada</value>\n    <comment>Table header for the version to which a package is pinned; meaning it should not update from that version.</comment>\n  </data>\n  <data name=\"ConfigurationDescriptionWasTruncated\" xml:space=\"preserve\">\n    <value>&lt;Para más detalles, consulte el archivo de registro&gt;</value>\n    <comment>The brackets are intended to make the value stand out from other text which it will follow. Any locale appropriate mechanism that achieves this is acceptable.</comment>\n  </data>\n  <data name=\"ConfigurationGettingDetails\" xml:space=\"preserve\">\n    <value>Recuperando detalles de configuración</value>\n  </data>\n  <data name=\"ConfigurationInitializing\" xml:space=\"preserve\">\n    <value>Inicializando el sistema de configuración</value>\n  </data>\n  <data name=\"ConfigurationReadingConfigFile\" xml:space=\"preserve\">\n    <value>Leyendo archivo de configuración</value>\n  </data>\n  <data name=\"ConfigurationUnitAssertHadNegativeResult\" xml:space=\"preserve\">\n    <value>El sistema no está en el estado deseado establecido por la configuración.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailed\" xml:space=\"preserve\">\n    <value>Error en esta unidad de configuración por una razón desconocida: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedConfigSet\" xml:space=\"preserve\">\n    <value>Error en la unidad de configuración debido a la configuración: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringGet\" xml:space=\"preserve\">\n    <value>Error de la unidad de configuración al intentar obtener el estado actual del sistema.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringSet\" xml:space=\"preserve\">\n    <value>Error de la unidad de configuración al intentar aplicar el estado deseado.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringTest\" xml:space=\"preserve\">\n    <value>Error de la unidad de configuración al intentar probar el estado actual del sistema.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedInternal\" xml:space=\"preserve\">\n    <value>Error interno en la unidad de configuración: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedPrecondition\" xml:space=\"preserve\">\n    <value>Error en la unidad de configuración porque una condición previa no es válida: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedSystemState\" xml:space=\"preserve\">\n    <value>Error en la unidad de configuración debido al estado del sistema: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedUnitProcessing\" xml:space=\"preserve\">\n    <value>Error de la unidad de configuración al intentar ejecutar: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitHasDuplicateIdentifier\" xml:space=\"preserve\">\n    <value>La configuración contiene el identificador '{0}' varias veces.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by the identifier string from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationUnitHasMissingDependency\" xml:space=\"preserve\">\n    <value>No se encontró la dependencia '{0}' en la configuración.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by the identifier string from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationUnitManuallySkipped\" xml:space=\"preserve\">\n    <value>Esta unidad de configuración se omitió manualmente.</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleConflict\" xml:space=\"preserve\">\n    <value>El módulo de la unidad de configuración está disponible en varias ubicaciones con la misma versión.</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleImportFailed\" xml:space=\"preserve\">\n    <value>Error al cargar el módulo para la unidad de configuración.</value>\n  </data>\n  <data name=\"ConfigurationUnitMultipleMatches\" xml:space=\"preserve\">\n    <value>Se encontraron varias coincidencias para la unidad de configuración; especifique el módulo para seleccionar el correcto.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotFound\" xml:space=\"preserve\">\n    <value>No se encontró la unidad de configuración.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotFoundInModule\" xml:space=\"preserve\">\n    <value>La unidad de configuración no estaba en el módulo como se esperaba.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotRunDueToDependency\" xml:space=\"preserve\">\n    <value>Esta unidad de configuración no se ejecutó porque se produjo un error en una dependencia o no se ejecutó.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotRunDueToFailedAssert\" xml:space=\"preserve\">\n    <value>Esta unidad de configuración no se ha ejecutado porque se produjo un error en una aserción o era falsa.</value>\n  </data>\n  <data name=\"ConfigurationUnitReturnedInvalidResult\" xml:space=\"preserve\">\n    <value>La unidad de configuración devolvió un resultado inesperado durante la ejecución.</value>\n  </data>\n  <data name=\"ConfigurationUnitSkipped\" xml:space=\"preserve\">\n    <value>Esta unidad de configuración no se ejecutó por una razón desconocida: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationFieldInvalidValue\" xml:space=\"preserve\">\n    <value>El campo '{0}' tiene un valor no válido: {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} An error in reading a configuration file. {0} is a placeholder replaced by the field name from the file. {1} is a placeholder for the invalid value.</comment>\n  </data>\n  <data name=\"ConfigurationFieldMissing\" xml:space=\"preserve\">\n    <value>Falta el campo ''{0}'' o está vacío.</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the expected field name from the file.</comment>\n  </data>\n  <data name=\"SeeLineAndColumn\" xml:space=\"preserve\">\n    <value>Vea la línea {0}, columna {1} en el archivo.</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Indicates the file location of the error, {0} and {1} are placeholders for numbers of the line and column, respectively.</comment>\n  </data>\n  <data name=\"CancellingOperation\" xml:space=\"preserve\">\n    <value>Cancelando operación</value>\n  </data>\n  <data name=\"InstallStubPackageDescription\" xml:space=\"preserve\">\n    <value>Instalación del paquete de código auxiliar para AppInstaller</value>\n  </data>\n  <data name=\"InstallFullPackageDescription\" xml:space=\"preserve\">\n    <value>Instalar el paquete completo para AppInstaller</value>\n  </data>\n  <data name=\"ExtendedFeaturesEnableMessage\" xml:space=\"preserve\">\n    <value>Habilite las características extendidas. Requiere acceso a la tienda.</value>\n  </data>\n  <data name=\"ExtendedFeaturesEnableArgumentError\" xml:space=\"preserve\">\n    <value>Las opciones '--enable' y '--disable' no se pueden usar con otros argumentos.</value>\n    <comment>{Locked=\"--enable\", \"--disable\"}</comment>\n  </data>\n  <data name=\"ExtendedFeaturesEnablingMessage\" xml:space=\"preserve\">\n    <value>Habilitación de características extendidas. Requiere acceso a la tienda.</value>\n  </data>\n  <data name=\"ExtendedFeaturesNotEnabledMessage\" xml:space=\"preserve\">\n    <value>Las características extendidas no están habilitadas. Ejecute \"winget configure --enable\" para habilitarlos.</value>\n    <comment>{Locked=\"winget configure --enable\"}</comment>\n  </data>\n  <data name=\"ExtendedFeaturesEnabledMessage\" xml:space=\"preserve\">\n    <value>Las características extendidas están habilitadas.</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisableMessage\" xml:space=\"preserve\">\n    <value>Deshabilite las características extendidas. Requiere acceso a la tienda.</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisablingMessage\" xml:space=\"preserve\">\n    <value>Deshabilitando las características extendidas. Requiere acceso a la tienda.</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisabledMessage\" xml:space=\"preserve\">\n    <value>Las características extendidas están deshabilitadas.</value>\n  </data>\n  <data name=\"SkipDependenciesArgumentDescription\" xml:space=\"preserve\">\n    <value>Omite el procesamiento de las dependencias del paquete y las características de Windows</value>\n  </data>\n  <data name=\"DependenciesSkippedMessage\" xml:space=\"preserve\">\n    <value>Dependencias omitidas.</value>\n  </data>\n  <data name=\"FailedToRefreshPathWarning\" xml:space=\"preserve\">\n    <value>No se pudo actualizar PATH variable para el proceso. Las instalaciones posteriores que dependen de los cambios en la variable de PATH pueden generar errores.</value>\n    <comment>{Locked=\"PATH\"}</comment>\n  </data>\n  <data name=\"ConfigurationFailedToTest\" xml:space=\"preserve\">\n    <value>Error de algunas unidades de configuración al probar su estado.</value>\n  </data>\n  <data name=\"ConfigurationInDesiredState\" xml:space=\"preserve\">\n    <value>El sistema se encuentra en el estado de configuración descrito.</value>\n  </data>\n  <data name=\"ConfigurationNoTestRun\" xml:space=\"preserve\">\n    <value>No se probó el estado de configuración.</value>\n  </data>\n  <data name=\"ConfigurationNotInDesiredState\" xml:space=\"preserve\">\n    <value>El sistema no se encuentra en el estado de configuración descrito.</value>\n  </data>\n  <data name=\"ConfigurationUnexpectedTestResult\" xml:space=\"preserve\">\n    <value>Resultado de prueba inesperado: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message. {0} will be replaced with the unexpected value (a number).</comment>\n  </data>\n  <data name=\"ConfigurationWarningPromptTest\" xml:space=\"preserve\">\n    <value>¿Ha revisado la configuración y desea continuar con la comprobación en el sistema?</value>\n  </data>\n  <data name=\"ConfigurationFileInvalidYAML\" xml:space=\"preserve\">\n    <value>El archivo de configuración no es un archivo de YAML válido.</value>\n    <comment>{Locked=\"YAML\"} YAML is a file format name.</comment>\n  </data>\n  <data name=\"ConfigurationUnitIsPartOfDependencyCycle\" xml:space=\"preserve\">\n    <value>Esta unidad de configuración forma parte de un ciclo de dependencia.</value>\n  </data>\n  <data name=\"ConfigurationValidationFoundNoIssues\" xml:space=\"preserve\">\n    <value>La validación no encontró ningún problema.</value>\n  </data>\n  <data name=\"ConfigurationUnitNeedsPrereleaseWarning\" xml:space=\"preserve\">\n    <value>La unidad de configuración solo está disponible como versión preliminar, pero no está marcada de esa manera en la configuración. Agregue \"allowPrerelease: true\" a las \"directives\".</value>\n    <comment>{Locked=\"allowPrerelease: true\",\"directives\"} These are values in the configuration file that are not localized.</comment>\n  </data>\n  <data name=\"ConfigurationUnitNotInCatalogWarning\" xml:space=\"preserve\">\n    <value>La unidad de configuración se encontró localmente, pero no se encontró en ningún catálogo configurado. Asegúrese de que está presente en cualquier sistema antes de aplicar la configuración.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotPublicWarning\" xml:space=\"preserve\">\n    <value>La unidad de configuración no está disponible públicamente; asegúrese de que cualquier persona que vaya a usar esta configuración tenga acceso a ella.</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleNotProvidedWarning\" xml:space=\"preserve\">\n    <value>No se proporcionó el módulo. Especificar el módulo mejora el rendimiento y evita futuras colisiones de nombres.</value>\n  </data>\n  <data name=\"DownloadCommandLongDescription\" xml:space=\"preserve\">\n    <value>Descarga el instalador del paquete seleccionado, ya sea buscando en un origen configurado o directamente desde un manifiesto. De forma predeterminada, la consulta debe coincidir sin distinción de mayúsculas y minúsculas con el identificador, nombre o moniker del paquete. Otros campos se pueden usar pasando su opción apropiada. De forma predeterminada, el comando de descarga descargará el instalador adecuado en la carpeta Descargas del usuario.</value>\n  </data>\n  <data name=\"DownloadCommandShortDescription\" xml:space=\"preserve\">\n    <value>Descarga el instalador de un paquete determinado</value>\n  </data>\n  <data name=\"DownloadDirectoryArgumentDescription\" xml:space=\"preserve\">\n    <value>Directorio en el que se descargan los instaladores</value>\n  </data>\n  <data name=\"DependenciesFlowDownload\" xml:space=\"preserve\">\n    <value>Descargando dependencias:</value>\n  </data>\n  <data name=\"InstallerDownloaded\" xml:space=\"preserve\">\n    <value>Instalador descargado: {0}</value>\n    <comment>{Locked=\"{0}\"} Full path of the downloaded installer.</comment>\n  </data>\n  <data name=\"InstallerTypeArgumentDescription\" xml:space=\"preserve\">\n    <value>Seleccionar el tipo de instalador</value>\n  </data>\n  <data name=\"InstallerDownloads\" xml:space=\"preserve\">\n    <value>Descargas del instalador</value>\n  </data>\n  <data name=\"InstallerDownloadCommandProhibited\" xml:space=\"preserve\">\n    <value>Se prohíbe que el instalador se descargue para una instalación sin conexión posterior. </value>\n  </data>\n  <data name=\"ConfigurationAllUsersElevated\" xml:space=\"preserve\">\n    <value>`--module-path allusers` requiere privilegios de administrador para ejecutarse.</value>\n    <comment>{Locked=\"--module-path allusers\"}</comment>\n  </data>\n  <data name=\"ConfigurationModulePath\" xml:space=\"preserve\">\n    <value>Especifica la ubicación en el equipo local para almacenar módulos. La predeterminada es %LOCALAPPDATA%\\Microsoft\\WinGet\\Configuration\\Modules</value>\n    <comment>{Locked=\"%LOCALAPPDATA%\\Microsoft\\WinGet\\Configuration\\Modules\"}</comment>\n  </data>\n  <data name=\"ConfigurationModulePathArgError\" xml:space=\"preserve\">\n    <value>El valor de `--module-path allusers` debe ser `currentuser`, `allusers`, `default` o una ruta de acceso absoluta.</value>\n    <comment>{Locked=\"{--module-path}, {currentuser}, {allusers}, {default}}</comment>\n  </data>\n  <data name=\"PolicyEnableWinGetConfiguration\" xml:space=\"preserve\">\n    <value>Habilitar configuración de Administrador de paquetes de Windows</value>\n  </data>\n  <data name=\"ErrorCommandLongDescription\" xml:space=\"preserve\">\n    <value>Recuperar información sobre errores. Dado un número, la salida contendrá detalles sobre el error, incluido el nombre del símbolo si se trata de un error específico de WinGet. Dado una cadena, se busca este valor en los errores específicos de WinGet.</value>\n  </data>\n  <data name=\"ErrorCommandShortDescription\" xml:space=\"preserve\">\n    <value>Obtener información sobre errores</value>\n  </data>\n  <data name=\"ErrorInputArgumentDescription\" xml:space=\"preserve\">\n    <value>Valor para buscar en la información de error</value>\n  </data>\n  <data name=\"ErrorNumberIsTooLarge\" xml:space=\"preserve\">\n    <value>El número especificado es demasiado grande para ser HRESULT.</value>\n  </data>\n  <data name=\"UnknownErrorCode\" xml:space=\"preserve\">\n    <value>Código de error desconocido</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INTERNAL_ERROR\" xml:space=\"preserve\">\n    <value>Error interno</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS\" xml:space=\"preserve\">\n    <value>Los argumentos de la línea de comandos no son válidos</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMMAND_FAILED\" xml:space=\"preserve\">\n    <value>Error al ejecutar el comando</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_FAILED\" xml:space=\"preserve\">\n    <value>Error al abrir el manifiesto</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CTRL_SIGNAL_RECEIVED\" xml:space=\"preserve\">\n    <value>Señal de cancelación recibida</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SHELLEXEC_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Error al ejecutar ShellExecute</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_MANIFESTVERSION\" xml:space=\"preserve\">\n    <value>No se puede procesar el manifiesto. La versión del manifiesto es posterior a la admitida. Actualice el cliente.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_FAILED\" xml:space=\"preserve\">\n    <value>Error al descargar el instalador</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX\" xml:space=\"preserve\">\n    <value>No se puede escribir en el índice; es una versión de esquema superior</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INDEX_INTEGRITY_COMPROMISED\" xml:space=\"preserve\">\n    <value>El índice está dañado</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCES_INVALID\" xml:space=\"preserve\">\n    <value>La información de origen configurada está dañada</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NAME_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>El nombre de origen ya está configurado</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_SOURCE_TYPE\" xml:space=\"preserve\">\n    <value>El tipo de origen no es válido</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_BUNDLE\" xml:space=\"preserve\">\n    <value>El archivo MSIX es una agrupación, no un paquete</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_DATA_MISSING\" xml:space=\"preserve\">\n    <value>Faltan los datos requeridos por el origen</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER\" xml:space=\"preserve\">\n    <value>Ninguno de los instaladores es aplicable para el sistema actual</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_HASH_MISMATCH\" xml:space=\"preserve\">\n    <value>El hash del archivo del instalador no coincide con el manifiesto</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NAME_DOES_NOT_EXIST\" xml:space=\"preserve\">\n    <value>El nombre de origen no existe</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_ARG_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>La ubicación de origen ya está configurada con otro nombre</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICATIONS_FOUND\" xml:space=\"preserve\">\n    <value>No se encontraron paquetes</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_SOURCES_DEFINED\" xml:space=\"preserve\">\n    <value>No hay orígenes configurados</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_APPLICATIONS_FOUND\" xml:space=\"preserve\">\n    <value>Se encontraron varios paquetes que coinciden con los criterios</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_MANIFEST_FOUND\" xml:space=\"preserve\">\n    <value>No se encontró ningún manifiesto que coincida con los criterios</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXTENSION_PUBLIC_FAILED\" xml:space=\"preserve\">\n    <value>No se pudo obtener la carpeta pública del paquete de origen</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMMAND_REQUIRES_ADMIN\" xml:space=\"preserve\">\n    <value>El comando requiere privilegios de administrador para ejecutarse</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NOT_SECURE\" xml:space=\"preserve\">\n    <value>La ubicación de origen no es segura</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>La directiva bloquea el cliente de Microsoft Store</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_APP_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>La directiva bloquea la aplicación Microsoft Store</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXPERIMENTAL_FEATURE_DISABLED\" xml:space=\"preserve\">\n    <value>La característica está actualmente en desarrollo. Se puede habilitar con la configuración de winget.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Error al instalar la aplicación Microsoft Store</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMPLETE_INPUT_BAD\" xml:space=\"preserve\">\n    <value>Error al autocompletar</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED\" xml:space=\"preserve\">\n    <value>Error al inicializar el analizador YAML</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_MAPPING_KEY\" xml:space=\"preserve\">\n    <value>Se encontró una clave YAML no válida</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY\" xml:space=\"preserve\">\n    <value>Se encontró una clave YAML duplicada</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_OPERATION\" xml:space=\"preserve\">\n    <value>Operación YAML no válida</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_DOC_BUILD_FAILED\" xml:space=\"preserve\">\n    <value>Error al compilar el documento YAML</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_EMITTER_STATE\" xml:space=\"preserve\">\n    <value>Estado de emisor YAML no válido</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_DATA\" xml:space=\"preserve\">\n    <value>Datos YAML no válidos</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LIBYAML_ERROR\" xml:space=\"preserve\">\n    <value>Error de LibYAML</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_WARNING\" xml:space=\"preserve\">\n    <value>Validación del manifiesto correcta con advertencia.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_FAILURE\" xml:space=\"preserve\">\n    <value>Error de validación de manifiesto.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_MANIFEST\" xml:space=\"preserve\">\n    <value>El manifiesto no es válido</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>No se encontraron actualizaciones aplicables</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPDATE_ALL_HAS_FAILURE\" xml:space=\"preserve\">\n    <value>actualización de WinGet: todas completadas con errores</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_SECURITY_CHECK_FAILED\" xml:space=\"preserve\">\n    <value>Error en la comprobación de seguridad del instalador</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_SIZE_MISMATCH\" xml:space=\"preserve\">\n    <value>El tamaño de descarga no coincide con la longitud de contenido esperada</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_UNINSTALL_INFO_FOUND\" xml:space=\"preserve\">\n    <value>No se encontró el comando de desinstalación</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXEC_UNINSTALL_COMMAND_FAILED\" xml:space=\"preserve\">\n    <value>Error al ejecutar el comando de desinstalación</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_BREAK_ITERATOR_ERROR\" xml:space=\"preserve\">\n    <value>Error de iterador de interrupción de ICU</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_CASEMAP_ERROR\" xml:space=\"preserve\">\n    <value>Error de asignación de caso de ICU</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_REGEX_ERROR\" xml:space=\"preserve\">\n    <value>Error de regex de ICU</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_IMPORT_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>No se pudieron instalar uno o varios paquetes importados</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NOT_ALL_PACKAGES_FOUND\" xml:space=\"preserve\">\n    <value>No se encontraron uno o varios paquetes solicitados</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE\" xml:space=\"preserve\">\n    <value>El archivo JSON no es válido</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NOT_REMOTE\" xml:space=\"preserve\">\n    <value>La ubicación de origen no es remota</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE\" xml:space=\"preserve\">\n    <value>No se admite el origen REST configurado</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA\" xml:space=\"preserve\">\n    <value>Datos no válidos devueltos por el origen REST</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>La operación está bloqueada por la directiva de grupo</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_INTERNAL_ERROR\" xml:space=\"preserve\">\n    <value>Error interno de la API de REST</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_URL\" xml:space=\"preserve\">\n    <value>Dirección URL de origen REST no válida</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_UNSUPPORTED_MIME_TYPE\" xml:space=\"preserve\">\n    <value>Tipo MIME no admitido devuelto por la API de REST</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_VERSION\" xml:space=\"preserve\">\n    <value>Versión del contrato de origen REST no válida</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE\" xml:space=\"preserve\">\n    <value>Los datos de origen están dañados o manipulados</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_STREAM_READ_FAILURE\" xml:space=\"preserve\">\n    <value>Error al leer de la secuencia</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>No se han aceptado los contratos de paquete</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PROMPT_INPUT_ERROR\" xml:space=\"preserve\">\n    <value>Error al leer la entrada en el símbolo del sistema</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST\" xml:space=\"preserve\">\n    <value>Uno o varios orígenes no admiten la solicitud de búsqueda.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_ENDPOINT_NOT_FOUND\" xml:space=\"preserve\">\n    <value>No se encuentra el punto de conexión de API de REST.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_OPEN_FAILED\" xml:space=\"preserve\">\n    <value>Error al abrir el origen.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>No se han aceptado los contratos de origen</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CUSTOMHEADER_EXCEEDS_MAXLENGTH\" xml:space=\"preserve\">\n    <value>El tamaño del encabezado supera el límite permitido de 1024 caracteres. Reduzca el tamaño e inténtelo de nuevo.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MISSING_RESOURCE_FILE\" xml:space=\"preserve\">\n    <value>Falta el archivo de recursos</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSI_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Error al ejecutar la instalación de MSI</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT\" xml:space=\"preserve\">\n    <value>Los argumentos de msiexec no son válidos</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FAILED_TO_OPEN_ALL_SOURCES\" xml:space=\"preserve\">\n    <value>Error al abrir uno o varios orígenes</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>Error al validar las dependencias</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MISSING_PACKAGE\" xml:space=\"preserve\">\n    <value>Falta uno o varios paquetes</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_TABLE_COLUMN\" xml:space=\"preserve\">\n    <value>Columna de tabla no válida</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_NOT_NEWER\" xml:space=\"preserve\">\n    <value>La versión de actualización no es más reciente que la versión instalada</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_UNKNOWN\" xml:space=\"preserve\">\n    <value>La versión de actualización es desconocida y no se especificó la invalidación</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_CONVERSION_ERROR\" xml:space=\"preserve\">\n    <value>Error de conversión de ICU</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Error al instalar el paquete portátil</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_REPARSE_POINT_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>El volumen no admite puntos de análisis</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_PACKAGE_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>Ya existe un paquete portátil de otro origen.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_SYMLINK_PATH_IS_DIRECTORY\" xml:space=\"preserve\">\n    <value>No se puede crear symlink. La ruta de acceso apunta a un directorio.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_PROHIBITS_ELEVATION\" xml:space=\"preserve\">\n    <value>El instalador no se puede ejecutar desde un contexto de administrador.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Error al desinstalar el paquete portátil</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ARP_VERSION_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>Error al validar los valores de DisplayVersion con el índice.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_ARGUMENT\" xml:space=\"preserve\">\n    <value>No se admiten uno o varios argumentos.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_BIND_WITH_EMBEDDED_NULL\" xml:space=\"preserve\">\n    <value>No se permiten caracteres nulos incrustados para SQLite</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_NOT_FOUND\" xml:space=\"preserve\">\n    <value>No se pudo encontrar el instalador anidado en el archivo.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXTRACT_ARCHIVE_FAILED\" xml:space=\"preserve\">\n    <value>Error al extraer el archivo.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_INVALID_PATH\" xml:space=\"preserve\">\n    <value>Se proporcionó una ruta de acceso de archivo relativa no válida al instalador anidado.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PINNED_CERTIFICATE_MISMATCH\" xml:space=\"preserve\">\n    <value>El certificado de servidor no coincide con ninguno de los valores esperados.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_LOCATION_REQUIRED\" xml:space=\"preserve\">\n    <value>Debe proporcionarse la ubicación de instalación.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ARCHIVE_SCAN_FAILED\" xml:space=\"preserve\">\n    <value>Error al analizar el malware de archivo.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>Se encontró al menos una versión del paquete instalada.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PIN_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>Ya existe un pin para el paquete.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PIN_DOES_NOT_EXIST\" xml:space=\"preserve\">\n    <value>No hay ningún pin para el paquete.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_OPEN_PINNING_INDEX\" xml:space=\"preserve\">\n    <value>No se puede abrir la base de datos del pin.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Error al instalar una o varias aplicaciones</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Error al desinstalar una o varias aplicaciones</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NOT_ALL_QUERIES_FOUND_SINGLE\" xml:space=\"preserve\">\n    <value>Una o varias consultas no devolvieron exactamente una coincidencia</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_PINNED\" xml:space=\"preserve\">\n    <value>El paquete tiene un PIN que impide la actualización.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB\" xml:space=\"preserve\">\n    <value>El paquete instalado actualmente es el paquete de código auxiliar</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_APPTERMINATION_RECEIVED\" xml:space=\"preserve\">\n    <value>Señal de apagado de la aplicación recibida</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_DEPENDENCIES\" xml:space=\"preserve\">\n    <value>Error al descargar las dependencias del paquete.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_COMMAND_PROHIBITED\" xml:space=\"preserve\">\n    <value>No se pudo descargar el paquete. La descarga para la instalación sin conexión está prohibida.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SERVICE_UNAVAILABLE\" xml:space=\"preserve\">\n    <value>Un servicio necesario está ocupado o no está disponible. Vuelve a intentarlo más tarde.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESUME_ID_NOT_FOUND\" xml:space=\"preserve\">\n    <value>El GUID proporcionado no corresponde a un estado de reanudación válido.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CLIENT_VERSION_MISMATCH\" xml:space=\"preserve\">\n    <value>La versión del cliente actual no coincide con la versión del cliente del estado guardado.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_RESUME_STATE\" xml:space=\"preserve\">\n    <value>Los datos de estado de reanudación no son válidos.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_OPEN_CHECKPOINT_INDEX\" xml:space=\"preserve\">\n    <value>No se puede abrir la base de datos de punto de control.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESUME_LIMIT_EXCEEDED\" xml:space=\"preserve\">\n    <value>Se superó el límite máximo de reanudación.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_AUTHENTICATION_INFO\" xml:space=\"preserve\">\n    <value>Información de autenticación no válida.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Método de autenticación no permitido.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED\" xml:space=\"preserve\">\n    <value>Error de autenticación.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_INTERACTIVE_REQUIRED\" xml:space=\"preserve\">\n    <value>Error de autenticación. Se requiere autenticación interactiva.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_CANCELLED_BY_USER\" xml:space=\"preserve\">\n    <value>Error de autenticación. Cancelado por el usuario.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_INCORRECT_ACCOUNT\" xml:space=\"preserve\">\n    <value>Error de autenticación. La cuenta autenticada no es la cuenta deseada.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE\" xml:space=\"preserve\">\n    <value>La aplicación se está ejecutando actualmente. Salga de la aplicación e inténtelo de nuevo.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INSTALL_IN_PROGRESS\" xml:space=\"preserve\">\n    <value>Ya hay otra instalación en curso. Inténtelo de nuevo más tarde.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_FILE_IN_USE\" xml:space=\"preserve\">\n    <value>Se está usando uno o varios archivos. Salga de la aplicación e inténtelo de nuevo.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_MISSING_DEPENDENCY\" xml:space=\"preserve\">\n    <value>Falta una dependencia de este paquete en el sistema.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DISK_FULL\" xml:space=\"preserve\">\n    <value>No hay más espacio en el equipo. Haga espacio e inténtelo de nuevo.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INSUFFICIENT_MEMORY\" xml:space=\"preserve\">\n    <value>No hay suficiente memoria disponible para instalar. Cierre otras aplicaciones e inténtelo de nuevo.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_NO_NETWORK\" xml:space=\"preserve\">\n    <value>Esta aplicación requiere conectividad a Internet. Conéctese a una red e inténtelo de nuevo.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CONTACT_SUPPORT\" xml:space=\"preserve\">\n    <value>Esta aplicación encontró un error durante la instalación. Póngase en contacto con el soporte técnico.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_TO_FINISH\" xml:space=\"preserve\">\n    <value>Reinicie el equipo para finalizar la instalación.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_FOR_INSTALL\" xml:space=\"preserve\">\n    <value>Error en la instalación. Reinicia el equipo e inténtalo de nuevo.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_INITIATED\" xml:space=\"preserve\">\n    <value>El equipo se reiniciará para finalizar la instalación.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CANCELLED_BY_USER\" xml:space=\"preserve\">\n    <value>Ha cancelado la instalación.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>Ya hay otra versión de esta aplicación instalada.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DOWNGRADE\" xml:space=\"preserve\">\n    <value>Ya hay instalada una versión posterior de esta aplicación.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>Las directivas de la organización impiden la instalación. Póngase en contacto con su administrador.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DEPENDENCIES\" xml:space=\"preserve\">\n    <value>Error al instalar las dependencias de paquetes.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE_BY_APPLICATION\" xml:space=\"preserve\">\n    <value>Otra aplicación está usando actualmente la aplicación.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INVALID_PARAMETER\" xml:space=\"preserve\">\n    <value>Parámetro no válido.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Paquete no compatible con el sistema.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_UPGRADE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>El instalador no admite la actualización de un paquete existente.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CUSTOM_ERROR\" xml:space=\"preserve\">\n    <value>La instalación falló debido a un error del instalador personalizado.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_ARP_ENTRY_NOT_FOUND\" xml:space=\"preserve\">\n    <value>No se encontró la entrada de aplicaciones y características para el paquete.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>La ubicación de instalación no es aplicable.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_FOUND\" xml:space=\"preserve\">\n    <value>No se encontró la ubicación de instalación.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_HASH_MISMATCH\" xml:space=\"preserve\">\n    <value>El hash del archivo existente no coincide.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Archivo no encontrado.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK\" xml:space=\"preserve\">\n    <value>Se encontró el archivo, pero no se comprobó el hash.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_ACCESS_ERROR\" xml:space=\"preserve\">\n    <value>No se pudo tener acceso al archivo.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE\" xml:space=\"preserve\">\n    <value>El archivo de configuración no es válido.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_YAML\" xml:space=\"preserve\">\n    <value>La sintaxis YAML no es válida.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_FIELD_TYPE\" xml:space=\"preserve\">\n    <value>Un campo de configuración tiene un tipo no válido.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION\" xml:space=\"preserve\">\n    <value>La configuración tiene una versión desconocida.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_SET_APPLY_FAILED\" xml:space=\"preserve\">\n    <value>Error al aplicar la configuración.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER\" xml:space=\"preserve\">\n    <value>La configuración contiene un identificador duplicado.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MISSING_DEPENDENCY\" xml:space=\"preserve\">\n    <value>Falta una dependencia en la configuración.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED\" xml:space=\"preserve\">\n    <value>La configuración tiene una dependencia no atendida.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_ASSERTION_FAILED\" xml:space=\"preserve\">\n    <value>Error en una aserción para la unidad de configuración.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MANUALLY_SKIPPED\" xml:space=\"preserve\">\n    <value>La configuración se omitió manualmente.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_WARNING_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>El usuario rechazó continuar la ejecución.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_SET_DEPENDENCY_CYCLE\" xml:space=\"preserve\">\n    <value>El gráfico de dependencias contiene un ciclo que no se puede resolver.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_FIELD_VALUE\" xml:space=\"preserve\">\n    <value>La configuración tiene un valor de campo no válido.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MISSING_FIELD\" xml:space=\"preserve\">\n    <value>Falta un campo en la configuración.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_TEST_FAILED\" xml:space=\"preserve\">\n    <value>Error de algunas unidades de configuración al probar su estado.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_TEST_NOT_RUN\" xml:space=\"preserve\">\n    <value>No se probó el estado de configuración.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_NOT_INSTALLED\" xml:space=\"preserve\">\n    <value>No se instaló la unidad de configuración.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_NOT_FOUND_REPOSITORY\" xml:space=\"preserve\">\n    <value>No se encontró la unidad de configuración.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_MULTIPLE_MATCHES\" xml:space=\"preserve\">\n    <value>Se encontraron varias coincidencias para la unidad de configuración; especifique el módulo para seleccionar el correcto.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_GET\" xml:space=\"preserve\">\n    <value>Error de la unidad de configuración al intentar obtener el estado actual del sistema.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_TEST\" xml:space=\"preserve\">\n    <value>Error de la unidad de configuración al intentar probar el estado actual del sistema.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_SET\" xml:space=\"preserve\">\n    <value>Error de la unidad de configuración al intentar aplicar el estado deseado.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_MODULE_CONFLICT\" xml:space=\"preserve\">\n    <value>El módulo de la unidad de configuración está disponible en varias ubicaciones con la misma versión.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE\" xml:space=\"preserve\">\n    <value>Error al cargar el módulo para la unidad de configuración.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_INVALID_RESULT\" xml:space=\"preserve\">\n    <value>La unidad de configuración devolvió un resultado inesperado durante la ejecución.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_SETTING_CONFIG_ROOT\" xml:space=\"preserve\">\n    <value>Una unidad contiene una configuración que requiere la raíz de configuración.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR\" xml:space=\"preserve\">\n    <value>El procesador de configuración no admite la operación.</value>\n  </data>\n  <data name=\"Unavailable\" xml:space=\"preserve\">\n    <value>No disponible</value>\n  </data>\n  <data name=\"EnableWindowsFeaturesSuccess\" xml:space=\"preserve\">\n    <value>Dependencias de características de Windows habilitadas correctamente</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE_ADMIN\" xml:space=\"preserve\">\n    <value>Error al cargar el módulo para la unidad de configuración porque requiere privilegios de administrador para ejecutarse.</value>\n  </data>\n  <data name=\"ConfigurationUnitSettingConfigRoot\" xml:space=\"preserve\">\n    <value>Una unidad contiene una configuración que requiere la raíz de configuración.</value>\n  </data>\n  <data name=\"ConfigurationUnitImportModuleAdmin\" xml:space=\"preserve\">\n    <value>Error al cargar el módulo para la unidad de configuración porque requiere privilegios de administrador para ejecutarse.</value>\n  </data>\n  <data name=\"ResumeCommandLongDescription\" xml:space=\"preserve\">\n    <value>Reanuda la ejecución de un comando guardado anteriormente pasando el identificador único del comando guardado. Se usa para reanudar un comando ejecutado que puede haberse terminado debido a un reinicio.</value>\n  </data>\n  <data name=\"ResumeCommandShortDescription\" xml:space=\"preserve\">\n    <value>Reanuda la ejecución de un comando guardado previamente.</value>\n  </data>\n  <data name=\"ResumeIdArgumentDescription\" xml:space=\"preserve\">\n    <value>Identificador único del estado guardado que se va a reanudar</value>\n  </data>\n  <data name=\"ClientVersionMismatchError\" xml:space=\"preserve\">\n    <value>No se admite la reanudación del estado desde una versión de cliente diferente: {0}</value>\n    <comment>{Locked= \"{0}\"} Message displayed to inform the user that the client version of the resume state does not match the current client version. {0} is a placeholder for the client version that created the resume state.</comment>\n  </data>\n  <data name=\"ResumeIdNotFoundError\" xml:space=\"preserve\">\n    <value>El estado de reanudación no existe: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a guid that does not correspond to a valid saved state. {0} is a placeholder replaced by the provided guid string.</comment>\n  </data>\n  <data name=\"ResumeStateDataNotFoundError\" xml:space=\"preserve\">\n    <value>No se encontraron datos en el estado de reanudación.</value>\n  </data>\n  <data name=\"CommandDoesNotSupportResumeMessage\" xml:space=\"preserve\">\n    <value>Este comando no admite la reanudación.</value>\n  </data>\n  <data name=\"AllowRebootArgumentDescription\" xml:space=\"preserve\">\n    <value>Permite un reinicio si procede</value>\n  </data>\n  <data name=\"InitiatingReboot\" xml:space=\"preserve\">\n    <value>Iniciando reinicio para completar la operación...</value>\n  </data>\n  <data name=\"FailedToInitiateReboot\" xml:space=\"preserve\">\n    <value>Error al iniciar un reinicio.</value>\n  </data>\n  <data name=\"ResumeLimitExceeded\" xml:space=\"preserve\">\n    <value>La operación de reanudación supera el límite permitido de reanudaciones {0}. Para reanudar manualmente, ejecute el comando '{1}'.</value>\n    <comment>{Locked=\"{0}\", \"{1}\"} {0} is a placeholder that is replaced by an integer number of the number of allowed resumes. {1} is a placeholder for the command to run to perform a manual resume.</comment>\n  </data>\n  <data name=\"IgnoreResumeLimitArgumentDescription\" xml:space=\"preserve\">\n    <value>Omitir el límite de reanudación de un estado guardado</value>\n  </data>\n  <data name=\"UriSchemeNotSupported\" xml:space=\"preserve\">\n    <value>Esquema URI no admitido: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the provided uri is not supported. {0} is a placeholder replaced by the provided uri.</comment>\n  </data>\n  <data name=\"UriNotWellFormed\" xml:space=\"preserve\">\n    <value>URI no bien formado: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the provided uri is not well formed. {0} is a placeholder replaced by the provided uri.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitEmptyContent\" xml:space=\"preserve\">\n    <value>No se pudo analizar {0} contenido de configuración de la unidad de configuración o el contenido de configuración está vacío.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder replaced by the input winget configure resource unit type.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitMissingRequiredArg\" xml:space=\"preserve\">\n    <value>{0} unidad de configuración no tiene el argumento necesario: {1}</value>\n    <comment>{Locked=\"{0},{1}\"} {0} is a placeholder for the input winget configure resource unit type. {1} is placeholder for the missing arg.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitMissingRecommendedArg\" xml:space=\"preserve\">\n    <value>{0} unidad de configuración no tiene el argumento recomendado: {1}</value>\n    <comment>{Locked=\"{0},{1}\"} {0} is a placeholder for the input winget configure resource unit type. {1} is placeholder for the missing arg.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitKnownSourceConfliction\" xml:space=\"preserve\">\n    <value>La unidad de configuración de WinGetSource está en conflicto con un origen conocido: {0}</value>\n    <comment>{Locked=\"WinGetSource,{0}\"} {0} is a placeholder for the input winget source in the configuration unit settings.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitThirdPartySourceAssertion\" xml:space=\"preserve\">\n    <value>La unidad de configuración de WinGetSource aserciones en un origen de terceros: {0}</value>\n    <comment>{Locked=\"WinGetSource,{0}\"} {0} is a placeholder for the input winget source in the configuration unit settings.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitBothPackageVersionAndUseLatest\" xml:space=\"preserve\">\n    <value>WinGetPackage declara UseLatest y Version. Id. de paquete: {0}</value>\n    <comment>{Locked=\"WinGetPackage,UseLatest,Version,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitThirdPartySourceAssertionForPackage\" xml:space=\"preserve\">\n    <value>La unidad de configuración WinGetPackage aserciones en un paquete de origen de terceros. Id. de paquete: {0}; Origen: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitDependencySourceNotConfigured\" xml:space=\"preserve\">\n    <value>El paquete de la unidad de configuración WinGetPackage depende de un origen de terceros no configurado previamente. Id. de paquete: {0}; Origen: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitDependencySourceNotDeclaredAsDependency\" xml:space=\"preserve\">\n    <value>El paquete de unidad de configuración de WinGetPackage depende de un origen de terceros. Se recomienda declarar la dependencia en la sección uni dependsOn. Id. de paquete: {0}; Origen: {1}</value>\n    <comment>{Locked=\"WinGetPackage,dependsOn,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageSourceOpenFailed\" xml:space=\"preserve\">\n    <value>No se puede validar el paquete de la unidad de configuración de WinGetPackage. Error al abrir el origen. Id. de paquete: {0}; Origen: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageNotFound\" xml:space=\"preserve\">\n    <value>No se puede validar el paquete de la unidad de configuración de WinGetPackage. No se encontró el paquete. Id. de paquete: {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageMultipleFound\" xml:space=\"preserve\">\n    <value>No se puede validar el paquete de la unidad de configuración de WinGetPackage. Se encontró más de un paquete. Id. de paquete: {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageVersionNotFound\" xml:space=\"preserve\">\n    <value>No se puede validar el paquete de la unidad de configuración de WinGetPackage. No se encontró la versión del paquete. Id. de paquete: {0}; Versión {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitPackageVersionSpecifiedWithOnlyOnePackageVersion\" xml:space=\"preserve\">\n    <value>Paquete de unidad de configuración WinGetPackage especificado con una versión específica mientras que sólo una versión del paquete está disponible. Id. de paquete: {0}; Versión: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackage\" xml:space=\"preserve\">\n    <value>No se puede validar el paquete de la unidad de configuración de WinGetPackage. Id. de paquete: {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"AuthenticationModeArgumentDescription\" xml:space=\"preserve\">\n    <value>Especificar la preferencia de ventana de autenticación (silent, silentPreferred, or interactive)</value>\n    <comment>{Locked=\"silent\",\"silentPreferred\",\"interactive\"} This argument allows the user to select authentication window popup behavior.</comment>\n  </data>\n  <data name=\"AuthenticationAccountArgumentDescription\" xml:space=\"preserve\">\n    <value>Especifique la cuenta que se usará para la autenticación</value>\n  </data>\n  <data name=\"SourceAddFailedAuthenticationNotSupported\" xml:space=\"preserve\">\n    <value>No se pudo agregar el origen. Esta versión de winget no admite el método de autenticación del origen. Intente actualizar a la versión de winget más reciente.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"SourceRequiresAuthentication\" xml:space=\"preserve\">\n    <value>El origen de {0} requiere autenticación. La solicitud de autenticación puede aparecer cuando sea necesario. La información autenticada se compartirá con el origen para la autorización de acceso.</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"RepairCommandLongDescription\" xml:space=\"preserve\">\n    <value>Repara el paquete seleccionado, encontrado al buscar en una lista de paquetes instalados o bien, directamente desde un manifiesto. De forma predeterminada, la consulta debe coincidir con el id, nombre o el moniker del paquete sin distinguir entre mayúsculas y minúsculas. Se pueden usar otros campos usando la opción apropiada.</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"RepairCommandShortDescription\" xml:space=\"preserve\">\n    <value>Repara el paquete seleccionado</value>\n  </data>\n  <data name=\"NoRepairInfoFound\" xml:space=\"preserve\">\n    <value>No se encuentra el comando de reparación para este paquete. Póngase en contacto con el anunciante del paquete para obtener soporte técnico.</value>\n  </data>\n  <data name=\"RepairDifferentInstallTechnology\" xml:space=\"preserve\">\n    <value>La tecnología del instalador en uso no coincide con la versión instalada actualmente.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_REPAIR_INFO_FOUND\" xml:space=\"preserve\">\n    <value>No se encontró el comando de reparación.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_REPAIR_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>La tecnología del instalador en uso no es compatible con la reparación.</value>\n  </data>\n  <data name=\"RepairFlowRepairSuccess\" xml:space=\"preserve\">\n    <value>La operación de reparación se completó correctamente.</value>\n  </data>\n  <data name=\"RepairAbandoned\" xml:space=\"preserve\">\n    <value>Reparación abandonada</value>\n  </data>\n  <data name=\"RepairFlowStartingPackageRepair\" xml:space=\"preserve\">\n    <value>Iniciando reparación del paquete...</value>\n  </data>\n  <data name=\"MSStoreRepairFailed\" xml:space=\"preserve\">\n    <value>Error al reparar el paquete de Microsoft Store. Código de error: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Microsoft Store application package fails to repair. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXEC_REPAIR_FAILED\" xml:space=\"preserve\">\n    <value>Error en la operación de reparación.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_REPAIR_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>La operación de reparación no es aplicable.</value>\n  </data>\n  <data name=\"RepairFlowNoMatchingVersion\" xml:space=\"preserve\">\n    <value>No hay versiones de paquete coincidentes disponibles en los orígenes configurados.</value>\n  </data>\n  <data name=\"RepairFlowReturnCodeSystemNotSupported\" xml:space=\"preserve\">\n    <value>La configuración del sistema actual no admite la reparación de este paquete.</value>\n  </data>\n  <data name=\"RepairOperationNotSupported\" xml:space=\"preserve\">\n    <value>La tecnología del instalador en uso no admite la reparación.</value>\n  </data>\n  <data name=\"NoAdminRepairForUserScopePackage\" xml:space=\"preserve\">\n    <value>El paquete instalado para el ámbito de usuario no se puede reparar cuando se ejecuta con privilegios de administrador.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED\" xml:space=\"preserve\">\n    <value>No se permiten operaciones de reparación que requieran privilegios de administrador en paquetes instalados dentro del ámbito de usuario.</value>\n  </data>\n  <data name=\"RepairFailedWithCode\" xml:space=\"preserve\">\n    <value>Error de reparación con el código de salida: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to repair an application package fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SQLITE_CONNECTION_TERMINATED\" xml:space=\"preserve\">\n    <value>La conexión de SQLite finalizó para evitar daños.</value>\n  </data>\n  <data name=\"UninstallAllVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Desinstalar todas las versiones</value>\n  </data>\n  <data name=\"TargetVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>La versión sobre la que actuar</value>\n  </data>\n  <data name=\"UninstallFailedDueToMultipleVersions\" xml:space=\"preserve\">\n    <value>Hay varias versiones de este paquete instaladas. Restrinja la búsqueda, pase el argumento \"--version\" para seleccionar una o pase la marca \"--all-versions\" para desinstalarlas todas.</value>\n    <comment>{Locked=\"--version,--all-versions\"}</comment>\n  </data>\n  <data name=\"PolicyEnableProxyCommandLineOptions\" xml:space=\"preserve\">\n    <value>Habilitar Administrador de paquetes de Windows opciones de la línea de comandos del proxy</value>\n    <comment>Describes a Group Policy that can enable the use of the --proxy option to set a proxy</comment>\n  </data>\n  <data name=\"ProxyArgumentDescription\" xml:space=\"preserve\">\n    <value>Establecer un proxy para usar para esta ejecución</value>\n  </data>\n  <data name=\"NoProxyArgumentDescription\" xml:space=\"preserve\">\n    <value>Deshabilitar el uso del proxy para esta ejecución</value>\n  </data>\n  <data name=\"ResetAdminSettingFailed\" xml:space=\"preserve\">\n    <value>No se puede restablecer {0}. Esta configuración está controlada por la directiva. Para obtener más información, póngase en contacto con el administrador del sistema.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"ResetAdminSettingSucceeded\" xml:space=\"preserve\">\n    <value>Restablezca la configuración de administrador \"{0}\".</value>\n    <comment>{Locked=\"{0}\"} Message displayed after the user resets an admin setting to its default value. Reset is used as verb in past tense. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"SetAdminSettingFailed\" xml:space=\"preserve\">\n    <value>No se puede establecer {0}. Esta configuración está controlada por la directiva. Para obtener más información, póngase en contacto con el administrador del sistema.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"SetAdminSettingSucceeded\" xml:space=\"preserve\">\n    <value>Establezca la configuración de administrador \"{0}\" en \"{1}\".</value>\n    <comment>{Locked=\"{0}\"} Message displayed after the user sets the value of an admin setting. Set is used as a verb in past tense. {0} is a placeholder replaced by the setting name. {1} is a placeholder replaced </comment>\n  </data>\n  <data name=\"SettingNameArgumentDescription\" xml:space=\"preserve\">\n    <value>Nombre de la configuración que se va a modificar</value>\n  </data>\n  <data name=\"SettingValueArgumentDescription\" xml:space=\"preserve\">\n    <value>Valor que se va a establecer para la configuración.</value>\n  </data>\n  <data name=\"SettingsResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>Restablece una configuración de administración a su valor predeterminado.</value>\n  </data>\n  <data name=\"SettingsResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>Restablece una configuración de administración a su valor predeterminado.</value>\n  </data>\n  <data name=\"SettingsSetCommandLongDescription\" xml:space=\"preserve\">\n    <value>Establece el valor de una configuración de administrador.</value>\n  </data>\n  <data name=\"SettingsSetCommandShortDescription\" xml:space=\"preserve\">\n    <value>Establece el valor de una configuración de administrador.</value>\n  </data>\n  <data name=\"SourceExplicitArgumentDescription\" xml:space=\"preserve\">\n    <value>Excluye un origen de la detección a menos que se especifique</value>\n  </data>\n  <data name=\"SourceEditExplicitArgumentDescription\" xml:space=\"preserve\">\n    <value>Excluye un origen de la detección (true o false)</value>\n  </data>\n  <data name=\"SourceListExplicit\" xml:space=\"preserve\">\n    <value>Explícito</value>\n  </data>\n  <data name=\"SourceTrustLevelArgumentDescription\" xml:space=\"preserve\">\n    <value>Nivel de confianza del origen (ninguno o de confianza)</value>\n  </data>\n  <data name=\"SourceListTrustLevel\" xml:space=\"preserve\">\n    <value>Nivel de confianza</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DISPLAYCATALOG_API_FAILED\" xml:space=\"preserve\">\n    <value>Error al obtener el catálogo de paquetes de Microsoft Store.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_DISPLAYCATALOG_PACKAGE\" xml:space=\"preserve\">\n    <value>No se encontró ningún paquete de Microsoft Store aplicable en el catálogo de paquetes de Microsoft Store.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SFSCLIENT_API_FAILED\" xml:space=\"preserve\">\n    <value>Error al obtener la información de descarga del paquete Microsoft Store.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_SFSCLIENT_PACKAGE\" xml:space=\"preserve\">\n    <value>No se encontró ningún paquete de Microsoft Store aplicable para descargar.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED\" xml:space=\"preserve\">\n    <value>Error al recuperar la licencia del paquete de Microsoft Store.</value>\n  </data>\n  <data name=\"MSStoreDownloadNoApplicablePackageFound\" xml:space=\"preserve\">\n    <value>No se encontró ningún paquete de Microsoft Store aplicable.</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageHashVerified\" xml:space=\"preserve\">\n    <value>Hash de paquete de Microsoft Store comprobado correctamente</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageHashMismatch\" xml:space=\"preserve\">\n    <value>Error de coincidencia del hash del paquete Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloaded\" xml:space=\"preserve\">\n    <value>Paquete de Microsoft Store descargado: {0}</value>\n    <comment>{Locked=\"{0}\"} Full path of the downloaded package.</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadFailed\" xml:space=\"preserve\">\n    <value>Error al descargar el paquete de Microsoft Store: {0}</value>\n    <comment>{Locked=\"{0}\"} Package name.</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadSuccess\" xml:space=\"preserve\">\n    <value>Descarga del paquete de Microsoft Store completada</value>\n  </data>\n  <data name=\"MSStoreDownloadMainPackages\" xml:space=\"preserve\">\n    <value>Descargando paquetes principales de Microsoft Store...</value>\n  </data>\n  <data name=\"MSStoreDownloadDependencyPackages\" xml:space=\"preserve\">\n    <value>Descargando paquetes de dependencias de Microsoft Store...</value>\n  </data>\n  <data name=\"MSStoreDownloadGetDownloadInfo\" xml:space=\"preserve\">\n    <value>Recuperando información de descarga del paquete de Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadGetDownloadInfoFailed\" xml:space=\"preserve\">\n    <value>Error al recuperar la información de descarga del paquete Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadGetLicense\" xml:space=\"preserve\">\n    <value>Recuperar la licencia del paquete de Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseSuccess\" xml:space=\"preserve\">\n    <value>Se guardó la licencia del paquete de Microsoft Store: {0}</value>\n    <comment>{Locked=\"{0}\"} License file full path.</comment>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseFailed\" xml:space=\"preserve\">\n    <value>Error al recuperar la licencia del paquete de Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadRenameNotSupported\" xml:space=\"preserve\">\n    <value>La descarga del paquete de Microsoft Store no admite el argumento --rename. El paquete de Microsoft Store usará nombres proporcionados por el catálogo de Microsoft Store.</value>\n    <comment>{Locked=\"--rename\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadAuthenticationNotice\" xml:space=\"preserve\">\n    <value>Microsoft Store descarga del paquete requiere la autenticación de id. de Microsoft Entra. La solicitud de autenticación puede aparecer cuando sea necesario. La información autenticada se compartirá con servicios Microsoft para la autorización de acceso. Para Microsoft Store licencias de paquetes, la cuenta de id. de Microsoft Entra debe ser miembro de Administrador global, Administrador de usuarios o Administrador de licencias.</value>\n    <comment>{Locked=\"Global Administrator,User Administrator,License Administrator\"}</comment>\n  </data>\n  <data name=\"SkipMicrosoftStorePackageLicenseArgumentDescription\" xml:space=\"preserve\">\n    <value>Omite la recuperación de la licencia sin conexión del paquete de Microsoft Store</value>\n  </data>\n  <data name=\"PlatformArgumentDescription\" xml:space=\"preserve\">\n    <value>Seleccionar la plataforma de destino</value>\n  </data>\n  <data name=\"ConfigurationExportAddingToFile\" xml:space=\"preserve\">\n    <value>Agregando archivo de configuración: {0}</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportSuccessful\" xml:space=\"preserve\">\n    <value>Se ha exportado correctamente</value>\n  </data>\n  <data name=\"ConfigurationGettingResourceSettings\" xml:space=\"preserve\">\n    <value>Obteniendo opciones de configuración...</value>\n  </data>\n  <data name=\"ConfigureExportArgumentRequiredError\" xml:space=\"preserve\">\n    <value>Se debe proporcionar al menos --packageId o --module con --resource. O use --all para exportar todas las configuraciones de paquete.</value>\n    <comment>{Locked=\"--packageId,--module, --resource, --all\"}</comment>\n  </data>\n  <data name=\"ConfigureExportArgumentConflictWithAllError\" xml:space=\"preserve\">\n    <value>Los argumentos --packageId, --module y --resource no se pueden usar con --all.</value>\n    <comment>{Locked=\"--packageId,--module, --resource, --all\"}</comment>\n  </data>\n  <data name=\"ConfigureExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Exporta recursos de configuración a un archivo de configuración. Cuando se usa con --all, exporta todas las configuraciones de paquete. Cuando se usa con --packageId, exporta un recurso WinGetPackage del identificador de paquete dado. Cuando se usa con --module y --resource, obtiene la configuración del recurso y lo exporta al archivo de configuración. Si el archivo de configuración de salida ya existe, anexa los recursos de configuración exportados.</value>\n    <comment>{Locked=\"WinGetPackage,--packageId,--module, --resource\"}</comment>\n  </data>\n  <data name=\"ConfigureExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Exporta recursos de configuración a un archivo de configuración.</value>\n  </data>\n  <data name=\"ConfigureExportModule\" xml:space=\"preserve\">\n    <value>Módulo del recurso que se va a exportar.</value>\n  </data>\n  <data name=\"ConfigureExportPackageId\" xml:space=\"preserve\">\n    <value>Identificador del paquete que se va a exportar.</value>\n  </data>\n  <data name=\"ConfigureExportResource\" xml:space=\"preserve\">\n    <value>Recurso de configuración que se va a exportar.</value>\n  </data>\n  <data name=\"ConfigureExportAll\" xml:space=\"preserve\">\n    <value>Exporta todas las configuraciones del paquete.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_GET_FAILED\" xml:space=\"preserve\">\n    <value>La unidad de configuración no pudo obtener sus propiedades.</value>\n  </data>\n  <data name=\"ConfigurationExportFailed\" xml:space=\"preserve\">\n    <value>Error al exportar la configuración.</value>\n  </data>\n  <data name=\"ConfigureExportUnitDescription\" xml:space=\"preserve\">\n    <value>Configurar {0}</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigureExportUnitInstallDescription\" xml:space=\"preserve\">\n    <value>Instalar {0}</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationWarningSetViewTruncated\" xml:space=\"preserve\">\n    <value>Algunos de los datos presentes en el archivo de configuración se truncaron para esta salida; inspeccionar el contenido del archivo para obtener el contenido completo.</value>\n  </data>\n  <data name=\"ConfigurationWarningValueTruncated\" xml:space=\"preserve\">\n    <value>&lt;este valor se ha truncado; inspeccionar el contenido del archivo para ver el texto completo&gt;</value>\n    <comment>Keep some form of separator like the \"&lt;&gt;\" around the text so that it stands out from the preceding text.</comment>\n  </data>\n  <data name=\"ConfigureListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Muestra los detalles de alto nivel de las configuraciones que se han aplicado al sistema. Estos datos se pueden usar con `configure` comandos para obtener más detalles.</value>\n    <comment>{Locked=\"`configure`\"}</comment>\n  </data>\n  <data name=\"ConfigureListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Muestra el historial de configuración</value>\n  </data>\n  <data name=\"ConfigurationHistoryEmpty\" xml:space=\"preserve\">\n    <value>No hay ninguna configuración en el historial.</value>\n  </data>\n  <data name=\"ConfigurationHistoryItemArgumentDescription\" xml:space=\"preserve\">\n    <value>Seleccionar elementos del historial</value>\n  </data>\n  <data name=\"ConfigurationHistoryItemNotFound\" xml:space=\"preserve\">\n    <value>No se encontró ninguna configuración única que coincida con los datos proporcionados. Proporcione el nombre completo o parte del identificador que coincida sin ambigüedad con la configuración deseada.</value>\n  </data>\n  <data name=\"ConfigurationHistoryRemoveArgumentDescription\" xml:space=\"preserve\">\n    <value>Quitar el elemento del historial</value>\n  </data>\n  <data name=\"ConfigureListFirstApplied\" xml:space=\"preserve\">\n    <value>Primera aplicación</value>\n    <comment>Column header for date values indicating when a configuration was first applied to the system.</comment>\n  </data>\n  <data name=\"ConfigureListIdentifier\" xml:space=\"preserve\">\n    <value>Identificador</value>\n  </data>\n  <data name=\"ConfigureListName\" xml:space=\"preserve\">\n    <value>Nombre</value>\n  </data>\n  <data name=\"ConfigureListOrigin\" xml:space=\"preserve\">\n    <value>Origen</value>\n  </data>\n  <data name=\"ConfigureListPath\" xml:space=\"preserve\">\n    <value>Ruta de acceso</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_HISTORY_ITEM_NOT_FOUND\" xml:space=\"preserve\">\n    <value>No se encontró la configuración especificada.</value>\n  </data>\n  <data name=\"ConfigurationSetStateCompleted\" xml:space=\"preserve\">\n    <value>Completadas</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStateInProgress\" xml:space=\"preserve\">\n    <value>En curso</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStatePending\" xml:space=\"preserve\">\n    <value>Pendiente</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStateUnknown\" xml:space=\"preserve\">\n    <value>Desconocido</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationStatusWatchArgumentDescription\" xml:space=\"preserve\">\n    <value>Supervisar el estado de configuración.</value>\n    <comment>As in \"to monitor the status of a configuration being applied\".</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateCompleted\" xml:space=\"preserve\">\n    <value>Completadas</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateInProgress\" xml:space=\"preserve\">\n    <value>En curso</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStatePending\" xml:space=\"preserve\">\n    <value>Pendiente</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateSkipped\" xml:space=\"preserve\">\n    <value>Omitido</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateUnknown\" xml:space=\"preserve\">\n    <value>Desconocido</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigureListApplyBegun\" xml:space=\"preserve\">\n    <value>Aplicación iniciada</value>\n    <comment>When the configuration application started.</comment>\n  </data>\n  <data name=\"ConfigureListApplyEnded\" xml:space=\"preserve\">\n    <value>Aplicación finalizada</value>\n    <comment>When the configuration application ended.</comment>\n  </data>\n  <data name=\"ConfigureListResult\" xml:space=\"preserve\">\n    <value>Resultado</value>\n  </data>\n  <data name=\"ConfigureListResultDescription\" xml:space=\"preserve\">\n    <value>Detalles</value>\n  </data>\n  <data name=\"ConfigureListState\" xml:space=\"preserve\">\n    <value>Estado</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigureListUnit\" xml:space=\"preserve\">\n    <value>Unidad</value>\n  </data>\n  <data name=\"StoreInstall_PackageNotAvailableForCurrentSystem\" xml:space=\"preserve\">\n    <value>El paquete no es compatible con la plataforma o la versión actual de Windows.</value>\n  </data>\n  <data name=\"ConfigurationSuppressPrologueArgumentDescription\" xml:space=\"preserve\">\n    <value>Suprimir la visualización de los detalles de configuración inicial cuando sea posible</value>\n  </data>\n  <data name=\"MSStoreDownloadMultiplePackagesNotice\" xml:space=\"preserve\">\n    <value>Se pueden descargar varios paquetes de Microsoft Store destinados a diferentes plataformas y arquitecturas. --platform, --architecture se puede usar para filtrar los paquetes.</value>\n    <comment>{Locked=\"--platform--architecture\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseForbidden\" xml:space=\"preserve\">\n    <value>No se pudo recuperar Microsoft Store licencia del paquete. La cuenta de id. de Microsoft Entra no es miembro de Administrador global, Administrador de usuarios o Administrador de licencias. Use --skip-license para omitir la recuperación de Microsoft Store licencia del paquete.</value>\n    <comment>{Locked=\"Global Administrator,User Administrator,License Administrator,--skip-license\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadNotSupported\" xml:space=\"preserve\">\n    <value>El paquete Microsoft Store no admite descargas.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SFSCLIENT_PACKAGE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>El paquete Microsoft Store no admite descargas.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED_FORBIDDEN\" xml:space=\"preserve\">\n    <value>No se pudo recuperar Microsoft Store licencia del paquete. La cuenta de id. de Microsoft Entra no tiene el privilegio necesario.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_PARAMETER_INTEGRITY_BOUNDARY\" xml:space=\"preserve\">\n    <value>El parámetro no se puede pasar a través del límite de integridad.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_ZERO_BYTE_FILE\" xml:space=\"preserve\">\n    <value>Instalador de cero bytes descargado; asegúrese de que la conexión de red funciona correctamente.</value>\n  </data>\n  <data name=\"InstallerZeroByteFile\" xml:space=\"preserve\">\n    <value>Instalador de cero bytes descargado; asegúrese de que la conexión de red funciona correctamente.</value>\n  </data>\n  <data name=\"FontCommandShortDescription\" xml:space=\"preserve\">\n    <value>Administrar fuentes</value>\n  </data>\n  <data name=\"FontCommandLongDescription\" xml:space=\"preserve\">\n    <value>Administrar fuentes con submenses. Las fuentes se pueden instalar, actualizar o desinstalar de forma similar a packages. </value>\n  </data>\n  <data name=\"FontFamily\" xml:space=\"preserve\">\n    <value>Familia</value>\n  </data>\n  <data name=\"FontFaces\" xml:space=\"preserve\">\n    <value>Formato</value>\n    <comment>\"Faces\" represents the typeface of the font family such as 'Bold' or 'Italic'</comment>\n  </data>\n  <data name=\"FontFamilyNameArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtrar resultados por nombre de familia</value>\n  </data>\n  <data name=\"FontFace\" xml:space=\"preserve\">\n    <value>Cara</value>\n    <comment>\"Face\" represents the typeface of a font family such as 'Bold' or 'Italic'</comment>\n  </data>\n  <data name=\"FontFilePaths\" xml:space=\"preserve\">\n    <value>Rutas de acceso</value>\n  </data>\n  <data name=\"NoInstalledFontFound\" xml:space=\"preserve\">\n    <value>No se encontró ninguna fuente que coincida con los criterios de entrada.</value>\n  </data>\n  <data name=\"FontListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Lista de fuentes instaladas</value>\n  </data>\n  <data name=\"FontListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Muestra todas las fuentes instaladas, todos los archivos de fuente o todos los detalles de una fuente específica.</value>\n  </data>\n  <data name=\"FontVersion\" xml:space=\"preserve\">\n    <value>Versión</value>\n  </data>\n  <data name=\"ConfigurationModules\" xml:space=\"preserve\">\n    <value>Módulos de configuración</value>\n    <comment>PowerShell Modules that are used for the Configuration feature</comment>\n  </data>\n  <data name=\"InstallerDownloadRequiresAuthentication\" xml:space=\"preserve\">\n    <value>El instalador del paquete requiere autenticación. La solicitud de autenticación puede aparecer cuando sea necesario. La información autenticada se compartirá con la dirección URL de descarga del instalador.</value>\n  </data>\n  <data name=\"InstallerDownloadAuthenticationNotSupported\" xml:space=\"preserve\">\n    <value>No se pudo descargar el instalador. Esta versión de winget no admite el método de autenticación de descarga del instalador. Intente actualizar a la versión de winget más reciente.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"InstallerDownloadAuthenticationFailed\" xml:space=\"preserve\">\n    <value>Error al descargar el instalador. Error de autenticación.</value>\n  </data>\n  <data name=\"ConfigurationProcessorPath\" xml:space=\"preserve\">\n    <value>Especificar la ruta al procesador de configuración</value>\n  </data>\n  <data name=\"DscCommandShortDescription\" xml:space=\"preserve\">\n    <value>Comandos de recursos de DSC v3</value>\n    <comment>DSC stands for \"Desired State Configuration\". It should already have a locked translation.</comment>\n  </data>\n  <data name=\"DscCommandLongDescription\" xml:space=\"preserve\">\n    <value>Los subcomandos aquí implementan recursos de Desired State Configuration (DSC) v3 para configurar WinGet y paquetes.</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionGet\" xml:space=\"preserve\">\n    <value>Obtener el estado del recurso</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionSet\" xml:space=\"preserve\">\n    <value>Establecer el estado del recurso</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionWhatIf\" xml:space=\"preserve\">\n    <value>Describir los cambios de estado necesarios</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionTest\" xml:space=\"preserve\">\n    <value>Probar el estado del recurso</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionDelete\" xml:space=\"preserve\">\n    <value>Eliminar el estado del recurso</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionExport\" xml:space=\"preserve\">\n    <value>Obtener todas las instancias de estado</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionValidate\" xml:space=\"preserve\">\n    <value>Validar el contenido del grupo</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionResolve\" xml:space=\"preserve\">\n    <value>Resolver el estado externo</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionAdapter\" xml:space=\"preserve\">\n    <value>Ejecutar el adaptador</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionSchema\" xml:space=\"preserve\">\n    <value>Obtener el esquema de recursos</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionManifest\" xml:space=\"preserve\">\n    <value>Obtener el manifiesto del recurso</value>\n  </data>\n  <data name=\"DscPackageResourceShortDescription\" xml:space=\"preserve\">\n    <value>Administrar el estado del paquete</value>\n  </data>\n  <data name=\"DscPackageResourceLongDescription\" xml:space=\"preserve\">\n    <value>Administrar paquetes mediante WinGet.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionExist\" xml:space=\"preserve\">\n    <value>Indica si una instancia debe existir o no.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionInDesiredState\" xml:space=\"preserve\">\n    <value>Indica si una instancia se encuentra en el estado deseado.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageId\" xml:space=\"preserve\">\n    <value>El identificador del paquete.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageSource\" xml:space=\"preserve\">\n    <value>El origen del paquete.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageVersion\" xml:space=\"preserve\">\n    <value>La versión del paquete.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageMatchOption\" xml:space=\"preserve\">\n    <value>Método para hacer coincidir el identificador con un paquete.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageUseLatest\" xml:space=\"preserve\">\n    <value>Indica que se debe instalar la última versión disponible del paquete.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageInstallMode\" xml:space=\"preserve\">\n    <value>El modo de instalación que se utilizará si es necesario.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageScope\" xml:space=\"preserve\">\n    <value>El ámbito de destino del paquete.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionAcceptAgreements\" xml:space=\"preserve\">\n    <value>Indica si se aceptan acuerdos para orígenes y paquetes.</value>\n  </data>\n  <data name=\"DscUserSettingsFileShortDescription\" xml:space=\"preserve\">\n    <value>Administrar el archivo de configuración del usuario</value>\n  </data>\n  <data name=\"DscUserSettingsFileLongDescription\" xml:space=\"preserve\">\n    <value>Administrar la configuración del usuario de WinGet.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionUserSettingsFileSettings\" xml:space=\"preserve\">\n    <value>Contenido del archivo JSON de configuración.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionUserSettingsFileAction\" xml:space=\"preserve\">\n    <value>La acción utilizada para aplicar la configuración.</value>\n  </data>\n  <data name=\"CorrelationArgumentDescription\" xml:space=\"preserve\">\n    <value>El valor se ha registrado para la correlación</value>\n  </data>\n  <data name=\"DscSourceResourceShortDescription\" xml:space=\"preserve\">\n    <value>Administrar la configuración de origen</value>\n  </data>\n  <data name=\"DscSourceResourceLongDescription\" xml:space=\"preserve\">\n    <value>Administrar las fuentes de WinGet.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceName\" xml:space=\"preserve\">\n    <value>El nombre que se utilizará para el origen.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceArgument\" xml:space=\"preserve\">\n    <value>El argumento para el origen.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceType\" xml:space=\"preserve\">\n    <value>El tipo de origen.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceTrustLevel\" xml:space=\"preserve\">\n    <value>El nivel de confianza del origen.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceExplicit\" xml:space=\"preserve\">\n    <value>Indica si el origen se incluye cuando las llamadas no especifican un origen.</value>\n  </data>\n  <data name=\"ConfigurationApplyingUnit\" xml:space=\"preserve\">\n    <value>Aplicando la unidad de configuración...</value>\n  </data>\n  <data name=\"ConfigurationExportingUnit\" xml:space=\"preserve\">\n    <value>Exportando la unidad de configuración...</value>\n  </data>\n  <data name=\"ConfigurationGettingUnitProcessors\" xml:space=\"preserve\">\n    <value>Obteniendo procesadores de unidad de configuración...</value>\n  </data>\n  <data name=\"ConfigurationExportInstallRequiredModule\" xml:space=\"preserve\">\n    <value>Asegúrese de que el módulo requerido para la exportación [{0}] esté disponible</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportInstallRequiredModuleFailed\" xml:space=\"preserve\">\n    <value>No se pudo probar o adquirir el módulo requerido. La configuración relacionada no se exportará.</value>\n  </data>\n  <data name=\"ConfigurationExportUnitStart\" xml:space=\"preserve\">\n    <value>Exportar [{0}]</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportUnitFailed\" xml:space=\"preserve\">\n    <value>No se pudo exportar el recurso.</value>\n  </data>\n  <data name=\"ConfigurationExportFailedToGetUnitProcessors\" xml:space=\"preserve\">\n    <value>No se pudieron obtener los procesadores de unidad. La configuración del paquete individual no se exportará.</value>\n  </data>\n  <data name=\"OutputDirectoryArgumentDescription\" xml:space=\"preserve\">\n    <value>Directorio donde se escribirán los resultados</value>\n  </data>\n  <data name=\"ConfigurationInstallDscPackage\" xml:space=\"preserve\">\n    <value>Desired State Configuration paquete no se encuentra en el sistema. Instalando el paquete...</value>\n  </data>\n  <data name=\"ConfigurationInstallDscPackageFailed\" xml:space=\"preserve\">\n    <value>No se pudo instalar Desired State Configuration paquete. Instale el paquete manualmente o proporcione la ruta de acceso a dsc.exe mediante --processor-path argumento.</value>\n    <comment>{Locked=\"dsc.exe\",\"--processor-path\"}</comment>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionAdminSettingsSettings\" xml:space=\"preserve\">\n    <value>Objeto que contiene la configuración de administrador y sus valores.</value>\n  </data>\n  <data name=\"DscAdminSettingsResourceShortDescription\" xml:space=\"preserve\">\n    <value>Administrar la configuración del administrador</value>\n  </data>\n  <data name=\"DscAdminSettingsResourceLongDescription\" xml:space=\"preserve\">\n    <value>Administrar la configuración del administrador de WinGet.</value>\n  </data>\n  <data name=\"ResetAllAdminSettingsArgumentDescription\" xml:space=\"preserve\">\n    <value>Restablecer todas las configuraciones de administración</value>\n  </data>\n  <data name=\"ResetAllAdminSettingsSucceeded\" xml:space=\"preserve\">\n    <value>Se han restablecido todas las configuraciones de administración.</value>\n  </data>\n  <data name=\"McpCommandShortDescription\" xml:space=\"preserve\">\n    <value>Información de MCP</value>\n    <comment>MCP stands for Model Context Protocol and should probably remain as-is</comment>\n  </data>\n  <data name=\"McpCommandLongDescription\" xml:space=\"preserve\">\n    <value>Información de MCP (Protocolo de contexto de modelo) para el Administrador de paquetes de Windows.</value>\n  </data>\n  <data name=\"McpConfigurationPreamble\" xml:space=\"preserve\">\n    <value>Para configurar manualmente el Administrador de paquetes de Windows servidor MCP con el cliente MCP, use el siguiente fragmento JSON en el objeto `servers`:</value>\n    <comment>{Locked=\"`servers`\"}\nMCP stands for Model Context Protocol and should probably remain as-is.\nAn unlocalized JSON fragment will follow on another line.</comment>\n  </data>\n  <data name=\"PolicyEnableMcpServer\" xml:space=\"preserve\">\n    <value>Habilitar Administrador de paquetes de Windows (servidor MCP)</value>\n  </data>\n  <data name=\"OSVersionDescription\" xml:space=\"preserve\">\n    <value>Versión del sistema operativo de destino</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Error al instalar una o varias fuentes.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>El archivo de fuente no es compatible y no se puede instalar.</value>\n  </data>\n  <data name=\"FontFileNotSupported\" xml:space=\"preserve\">\n    <value>Una o varias fuentes del paquete de fuentes no se admiten y no se pueden instalar.</value>\n  </data>\n  <data name=\"FontInstallFailed\" xml:space=\"preserve\">\n    <value>Error al instalar la fuente; limpiando.</value>\n  </data>\n  <data name=\"FontAlreadyInstalled\" xml:space=\"preserve\">\n    <value>Fuente ya instalada.</value>\n  </data>\n  <data name=\"FontPackage\" xml:space=\"preserve\">\n    <value>Id. de paquete</value>\n  </data>\n  <data name=\"FontWinGetSupported\" xml:space=\"preserve\">\n    <value>WinGet admitido</value>\n  </data>\n  <data name=\"FontTitle\" xml:space=\"preserve\">\n    <value>Título</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_FOUND\" xml:space=\"preserve\">\n    <value>No se encontró el archivo de fuente.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Error al desinstalar la fuente. Es posible que la fuente no esté en buen estado. Intente desinstalar después de reiniciar.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>Error de validación de fuente.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_ROLLBACK_FAILED\" xml:space=\"preserve\">\n    <value>Error al revertir la fuente. Es posible que la fuente no esté en buen estado. Intente desinstalar después de reiniciar.</value>\n  </data>\n  <data name=\"FontDetailsArgumentDescription\" xml:space=\"preserve\">\n    <value>Mostrar información detallada del archivo de fuente.</value>\n  </data>\n  <data name=\"FontValidationFailed\" xml:space=\"preserve\">\n    <value>Error en la validación del paquete de fuentes.</value>\n  </data>\n  <data name=\"FontRollbackFailed\" xml:space=\"preserve\">\n    <value>El intento de reversión de la instalación de fuentes con error no se realizó correctamente. Es posible que sea necesario reiniciar para desinstalar correctamente la fuente.</value>\n  </data>\n  <data name=\"FontUninstallFailed\" xml:space=\"preserve\">\n    <value>Error al desinstalar el paquete de fuentes. Esto suele deberse a que el sistema o una aplicación están usando fuentes. Es posible que la desinstalación se haya realizado correctamente después de reiniciar el equipo.</value>\n  </data>\n  <data name=\"FontStatusOK\" xml:space=\"preserve\">\n    <value>Aceptar</value>\n    <comment>\"OK\" means the font is in a good healthy state</comment>\n  </data>\n  <data name=\"FontStatusCorrupt\" xml:space=\"preserve\">\n    <value>Dañada</value>\n    <comment>\"Corrupt\" refers to an install that is in a corrupted or bad state, and needs repair.</comment>\n  </data>\n  <data name=\"FontStatus\" xml:space=\"preserve\">\n    <value>Estado</value>\n  </data>\n  <data name=\"FontStatusUnknown\" xml:space=\"preserve\">\n    <value>Desconocido</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>El paquete de fuentes ya está instalado.</value>\n  </data>\n  <data name=\"ListDetailsArgumentDescription\" xml:space=\"preserve\">\n    <value>Mostrar información detallada sobre los paquetes</value>\n    <comment>Providing this argument causes the CLI to output additional details about installed application packages.</comment>\n  </data>\n  <data name=\"ShowLabelChannel\" xml:space=\"preserve\">\n    <value>Canal:</value>\n    <comment>Precedes a string value that names the delivery channel for the software package (ex. stable, beta).</comment>\n  </data>\n  <data name=\"ShowListLocalIdentifier\" xml:space=\"preserve\">\n    <value>Identificador local:</value>\n    <comment>Precedes a value that is the unique identifier for the installed package on the local system.</comment>\n  </data>\n  <data name=\"ShowListPackageFamilyName\" xml:space=\"preserve\">\n    <value>Nombre de familia de paquete:</value>\n    <comment>Precedes a value that is the APPX/MSIX package family name of the installed package.</comment>\n  </data>\n  <data name=\"ShowListProductCode\" xml:space=\"preserve\">\n    <value>Código de producto:</value>\n    <comment>Precedes a value that is the Add/Remove Programs identifier in the registry. This is also the Product Code value as defined in MSI installers.</comment>\n  </data>\n  <data name=\"ShowListUpgradeCode\" xml:space=\"preserve\">\n    <value>Código de actualización:</value>\n    <comment>Precedes a value that is the MSI Upgrade Code for the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledScope\" xml:space=\"preserve\">\n    <value>Ámbito de la instalación:</value>\n    <comment>Precedes a value that is the scope of the installation of the package (ex. user, machine).</comment>\n  </data>\n  <data name=\"ShowListInstalledArchitecture\" xml:space=\"preserve\">\n    <value>Arquitectura instalada:</value>\n    <comment>Precedes a value that is the installed architecture of the package (ex. x86, x64, ARM64).</comment>\n  </data>\n  <data name=\"ShowListInstalledLocale\" xml:space=\"preserve\">\n    <value>Configuración regional instalada:</value>\n    <comment>Precedes a value that is the locale of the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledLocation\" xml:space=\"preserve\">\n    <value>Ubicación instalada:</value>\n    <comment>Precedes a value that is the directory path to the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledSource\" xml:space=\"preserve\">\n    <value>Fuente de origen:</value>\n    <comment>Precedes a value that names the package source where the installed package originated from.</comment>\n  </data>\n  <data name=\"ShowListAvailableUpgrades\" xml:space=\"preserve\">\n    <value>Actualizaciones disponibles:</value>\n    <comment>Precedes a list of package upgrades available for the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstallerCategory\" xml:space=\"preserve\">\n    <value>Categoría del instalador:</value>\n    <comment>Precedes a value that indicates the category of the installer for the installed package (ex. exe, msi, msix).</comment>\n  </data>\n  <data name=\"SourceEditOldValue\" xml:space=\"preserve\">\n    <value>Valor antiguo</value>\n    <comment>Column title for listing edit changes.</comment>\n  </data>\n  <data name=\"SourceEditNewValue\" xml:space=\"preserve\">\n    <value>Nuevo valor</value>\n    <comment>Column title for listing the new value.</comment>\n  </data>\n</root>"
  },
  {
    "path": "Localization/Resources/fr-FR/Resources.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "Localization/Resources/fr-FR/winget.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"AdjoinedNotFlagError\" xml:space=\"preserve\">\n    <value>L’alias contigu n’est pas un indicateur : '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an adjoined alias that is not a flag argument. {0} is a placeholder replaced by the user input argument (e.g. '-ab').</comment>\n  </data>\n  <data name=\"AdjoinedNotFoundError\" xml:space=\"preserve\">\n    <value>Alias de drapeau contigu introuvable : '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an adjoined flag alias argument that was not found. {0} is a placeholder replaced by the user input argument (e.g. '-ab').</comment>\n  </data>\n  <data name=\"AvailableArguments\" xml:space=\"preserve\">\n    <value>Les arguments suivants sont disponibles :</value>\n    <comment>Message displayed to inform the user about the available command line arguments.</comment>\n  </data>\n  <data name=\"AvailableCommandAliases\" xml:space=\"preserve\">\n    <value>Les alias de commande suivants sont disponibles :</value>\n    <comment>Message displayed to inform the user about the available command line alias arguments.</comment>\n  </data>\n  <data name=\"AvailableCommands\" xml:space=\"preserve\">\n    <value>Les commandes suivantes sont disponibles :</value>\n    <comment>Title displayed to inform the user about the available commands.</comment>\n  </data>\n  <data name=\"AvailableHeader\" xml:space=\"preserve\">\n    <value>Disponible</value>\n    <comment>As in \"a new version is available to upgrade to\".</comment>\n  </data>\n  <data name=\"AvailableOptions\" xml:space=\"preserve\">\n    <value>Les options suivantes sont disponibles :</value>\n    <comment>Message displayed to inform the user about the available options.</comment>\n  </data>\n  <data name=\"AvailableSubcommands\" xml:space=\"preserve\">\n    <value>Les sous-commandes suivantes sont disponibles :</value>\n    <comment>Message displayed to inform the user about the available nested commands that run in context of the selected command.</comment>\n  </data>\n  <data name=\"AvailableUpgrades\" xml:space=\"preserve\">\n    <value>{0} mises à niveau disponibles.</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about available package upgrades. {0} is a placeholder replaced by the number of package upgrades.</comment>\n  </data>\n  <data name=\"ChannelArgumentDescription\" xml:space=\"preserve\">\n    <value>Utiliser le canal spécifié; par défaut, il s’agit du grand public</value>\n  </data>\n  <data name=\"Command\" xml:space=\"preserve\">\n    <value>commande</value>\n    <comment>Label displayed for a command to give the software.</comment>\n  </data>\n  <data name=\"CommandArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtrer les résultats par commande</value>\n    <comment>Description message displayed to inform the user about filtering the search results by a package command.</comment>\n  </data>\n  <data name=\"CommandLineArgumentDescription\" xml:space=\"preserve\">\n    <value>La ligne de commande complète pour l’achèvement</value>\n  </data>\n  <data name=\"CommandRequiresAdmin\" xml:space=\"preserve\">\n    <value>Cette commande nécessite des privilèges d'administrateur pour être exécutée.</value>\n  </data>\n  <data name=\"CompleteCommandLongDescription\" xml:space=\"preserve\">\n    <value>Cette commande peut être utilisée pour demander la saisie semi-automatique de la ligne de commande sensible au contexte. La ligne de commande, la position du curseur et le mot à terminer sont transmis. La sortie est un ensemble de valeurs potentielles basées sur les entrées, avec une valeur possible par ligne.</value>\n  </data>\n  <data name=\"CompleteCommandShortDescription\" xml:space=\"preserve\">\n    <value>Active l’achèvement de la ligne de commande sensible au contexte</value>\n  </data>\n  <data name=\"CountArgumentDescription\" xml:space=\"preserve\">\n    <value>Afficher au maximum le nombre spécifié de résultats (entre 1 et 1 000)</value>\n  </data>\n  <data name=\"Done\" xml:space=\"preserve\">\n    <value>Terminé</value>\n    <comment>Label displayed when an operation completes or is done executing.</comment>\n  </data>\n  <data name=\"ExactArgumentDescription\" xml:space=\"preserve\">\n    <value>Rechercher un package en utilisant une correspondance exacte</value>\n    <comment>Description message displayed to inform the user about finding an application package using an exact matching criteria.</comment>\n  </data>\n  <data name=\"ExperimentalArgumentDescription\" xml:space=\"preserve\">\n    <value>Argument expérimental à des fins de démonstration</value>\n  </data>\n  <data name=\"ExperimentalCommandLongDescription\" xml:space=\"preserve\">\n    <value>Cette commande illustre comment implémenter une fonctionnalité expérimentale. Pour l’activer, accédez à « winget settings » et activez les fonctionnalités experimentalCmd ou experimentalArg.</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"ExperimentalCommandShortDescription\" xml:space=\"preserve\">\n    <value>Exemple de fonctionnalité expérimentale</value>\n  </data>\n  <data name=\"ExtraPositionalError\" xml:space=\"preserve\">\n    <value>Un argument positionnel a été trouvé lorsque aucune valeur n’était attendue : '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an extra positional argument when none was expected. {0} is a placeholder replaced by the user's extra argument input.</comment>\n  </data>\n  <data name=\"FeatureDisabledMessage\" xml:space=\"preserve\">\n    <value>Cette fonctionnalité est un travail en cours et peut être modifiée considérablement ou supprimée à l’avenir. Pour l’activer, modifiez vos paramètres ('winget settings') pour inclure la fonctionnalité expérimentale : '{0}'</value>\n    <comment>{Locked=\"winget settings\",\"{0}\"}. Error message displayed when the user uses an experimental feature that is disabled. {0} is a placeholder replaced by the experimental feature name.</comment>\n  </data>\n  <data name=\"FeaturesCommandLongDescription\" xml:space=\"preserve\">\n    <value>Affiche le statut des fonctionnalités expérimentales. Les fonctionnalités expérimentales peuvent être activées via « winget settings ».</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"FeaturesCommandShortDescription\" xml:space=\"preserve\">\n    <value>Affiche le statut des fonctionnalités expérimentales</value>\n  </data>\n  <data name=\"FeaturesDisabled\" xml:space=\"preserve\">\n    <value>Désactivé</value>\n  </data>\n  <data name=\"FeaturesEnabled\" xml:space=\"preserve\">\n    <value>Activé</value>\n  </data>\n  <data name=\"FeaturesFeature\" xml:space=\"preserve\">\n    <value>Fonctionnalité</value>\n  </data>\n  <data name=\"FeaturesLink\" xml:space=\"preserve\">\n    <value>Lien</value>\n  </data>\n  <data name=\"FeaturesMessage\" xml:space=\"preserve\">\n    <value>Les fonctionnalités expérimentales suivantes sont en cours.\nElles peuvent être configurées par le biais du fichier de paramètres « winget settings ».</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"FeaturesProperty\" xml:space=\"preserve\">\n    <value>Propriété</value>\n  </data>\n  <data name=\"FeaturesStatus\" xml:space=\"preserve\">\n    <value>Statut</value>\n  </data>\n  <data name=\"FileArgumentDescription\" xml:space=\"preserve\">\n    <value>Fichier à hacher</value>\n  </data>\n  <data name=\"FlagContainAdjoinedError\" xml:space=\"preserve\">\n    <value>L’argument indicateur ne peut pas contenir de valeur contigüe : '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a flag argument containing an unexpected adjoined value. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"HashCommandLongDescription\" xml:space=\"preserve\">\n    <value>Calcule le hachage d’un fichier local, approprié pour l’entrée dans un manifeste.  Il peut également calculer le hachage du fichier de signature d’un paquet MSIX afin d’activer les installations en continu.</value>\n  </data>\n  <data name=\"HashCommandShortDescription\" xml:space=\"preserve\">\n    <value>Assistant pour le hachage des fichiers d’installation</value>\n  </data>\n  <data name=\"HelpArgumentDescription\" xml:space=\"preserve\">\n    <value>Affiche l’aide sur la commande sélectionnée</value>\n  </data>\n  <data name=\"HelpForDetails\" xml:space=\"preserve\">\n    <value>Pour en savoir plus sur une commande spécifique, passez-la à l’argument aide.</value>\n  </data>\n  <data name=\"HelpLinkPreamble\" xml:space=\"preserve\">\n    <value>Vous trouverez de l’aide supplémentaire sur : '{0}'</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a link where they can learn more about the subject context. {0} is a placeholder replaced by a website address.</comment>\n  </data>\n  <data name=\"IdArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtrer les résultats par identifiant</value>\n  </data>\n  <data name=\"IgnoreWarningsArgumentDescription\" xml:space=\"preserve\">\n    <value>Supprime les sorties d'avertissement</value>\n  </data>\n  <data name=\"InstallationDisclaimer1\" xml:space=\"preserve\">\n    <value>La licence d’utilisation de cette application vous est octroyée par son propriétaire.</value>\n  </data>\n  <data name=\"InstallationDisclaimer2\" xml:space=\"preserve\">\n    <value>Microsoft n’est pas responsable des paquets tiers et n’accorde pas de licences à ceux-ci.</value>\n  </data>\n  <data name=\"InstallationDisclaimerMSStore\" xml:space=\"preserve\">\n    <value>Ce package est fourni via Microsoft Store. Le winget devra peut-être acquérir le package à partir du Microsoft Store pour le compte de l’utilisateur actuel.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"InstallCommandLongDescription\" xml:space=\"preserve\">\n    <value>Installe le package sélectionné, trouvé en recherchant une source configurée ou directement à partir d’un manifeste. Par défaut, la requête doit correspondre à l’id, name ou moniker du package sans respecter la casse. D’autres champs peuvent être utilisés en passant leur option appropriée. Par défaut, la commande install vérifie l’état d’installation du package et tente d’effectuer une mise à niveau, le cas échéant. Remplacez par --force pour effectuer une installation directe.</value>\n    <comment>{Locked=\"--force\"}; id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"InstallCommandShortDescription\" xml:space=\"preserve\">\n    <value>Installe le package donné</value>\n  </data>\n  <data name=\"InstallerHashMismatchAdminBlock\" xml:space=\"preserve\">\n    <value>Le code de hachage de l’installation ne correspond pas ; ceci ne peut pas être contourné lors d’une exécution en tant qu’administrateur</value>\n  </data>\n  <data name=\"InstallerHashMismatchOverridden\" xml:space=\"preserve\">\n    <value>Le hachage du programme d’installation ne correspond pas ; continuer en raison de --ignore-security-hash</value>\n    <comment>{Locked=\"--ignore-security-hash\"}</comment>\n  </data>\n  <data name=\"InstallerHashMismatchOverrideRequired\" xml:space=\"preserve\">\n    <value>Le hachage de l'installateur ne correspond pas ; pour remplacer cette vérification, utilisez --ignore-security-hash.</value>\n    <comment>{Locked=\"--ignore-security-hash\"}</comment>\n  </data>\n  <data name=\"InstallerHashVerified\" xml:space=\"preserve\">\n    <value>Le code de hachage de l’installation a été vérifié avec succès</value>\n  </data>\n  <data name=\"InstallFlowInstallSuccess\" xml:space=\"preserve\">\n    <value>Installé correctement</value>\n  </data>\n  <data name=\"InstallFlowStartingPackageInstall\" xml:space=\"preserve\">\n    <value>Démarrage du package d’installation... Merci de patienter.</value>\n  </data>\n  <data name=\"HashOverrideArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignorer l’échec de la vérification de hachage du programme d’installation</value>\n  </data>\n  <data name=\"IgnoreLocalArchiveMalwareScanArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignorer l’analyse des programmes malveillants effectuée dans le cadre de l’installation d’un package de type archive à partir du manifeste local</value>\n  </data>\n  <data name=\"InteractiveArgumentDescription\" xml:space=\"preserve\">\n    <value>Demander une installation interactive; l’intervention de l’utilisateur peut être nécessaire</value>\n  </data>\n  <data name=\"InvalidAliasError\" xml:space=\"preserve\">\n    <value>L’alias d’argument n’a pas été reconnu pour la commande actuelle : '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a command line argument alias that was not recognized for a selected command. {0} is a placeholder replaced by the user's argument alias input (e.g. '-a').</comment>\n  </data>\n  <data name=\"InvalidArgumentSpecifierError\" xml:space=\"preserve\">\n    <value>Spécificateur d’argument non valide : '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an invalid argument specifier. {0} is a placeholder replaced by an argument specifier (e.g. '-').</comment>\n  </data>\n  <data name=\"InvalidNameError\" xml:space=\"preserve\">\n    <value>Le nom de l’argument n’a pas été reconnu pour la commande actuelle : '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an unrecognized command line argument name for the selected command. {0} is a placeholder replaced by the user's argument name input (e.g. '--example').</comment>\n  </data>\n  <data name=\"KeyDirectoriesHeader\" xml:space=\"preserve\">\n    <value>Répertoires Winget</value>\n    <comment>Header for a table detailing the directories Winget uses for key operations like logging and portable installs</comment>\n  </data>\n  <data name=\"LocaleArgumentDescription\" xml:space=\"preserve\">\n    <value>Paramètres régionaux à utiliser (format BCP47)</value>\n    <comment>{Locked=\"BCP47\"}</comment>\n  </data>\n  <data name=\"LicenseAgreement\" xml:space=\"preserve\">\n    <value>Contrat de licence</value>\n  </data>\n  <data name=\"Links\" xml:space=\"preserve\">\n    <value>Liens</value>\n    <comment>Links to different webpages</comment>\n  </data>\n  <data name=\"ListCommandLongDescription\" xml:space=\"preserve\">\n    <value>La commande list affiche les packages installés sur le système, et indique si une mise à niveau est disponible. Des options supplémentaires peuvent être proposées pour filtrer la sortie, comme pour la commande search.</value>\n    <comment>{Locked=\"list\",\"search\"}</comment>\n  </data>\n  <data name=\"ListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Afficher les packages installés</value>\n  </data>\n  <data name=\"LocationArgumentDescription\" xml:space=\"preserve\">\n    <value>Emplacement d’installation (si pris en charge)</value>\n  </data>\n  <data name=\"LogArgumentDescription\" xml:space=\"preserve\">\n    <value>Emplacement du journal (si pris en charge)</value>\n  </data>\n  <data name=\"MainCopyrightNotice\" xml:space=\"preserve\">\n    <value>Copyright (c) Microsoft Corporation. Tous droits réservés.</value>\n  </data>\n  <data name=\"MainHomepage\" xml:space=\"preserve\">\n    <value>Page d’accueil</value>\n    <comment>The primary webpage for the software</comment>\n  </data>\n  <data name=\"ManifestArgumentDescription\" xml:space=\"preserve\">\n    <value>Chemin d’accès au manifeste du package</value>\n  </data>\n  <data name=\"ManifestValidationFail\" xml:space=\"preserve\">\n    <value>La validation du manifeste a échoué.</value>\n  </data>\n  <data name=\"ManifestValidationSuccess\" xml:space=\"preserve\">\n    <value>La validation du manifeste a réussi.</value>\n  </data>\n  <data name=\"ManifestValidationWarning\" xml:space=\"preserve\">\n    <value>La validation des manifestes a réussi avec des avertissements.</value>\n  </data>\n  <data name=\"MissingArgumentError\" xml:space=\"preserve\">\n    <value>Valeur d’argument requise, mais aucune trouvé : '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user does not provide a required command line argument value. {0} is a placeholder replaced by the argument name.</comment>\n  </data>\n  <data name=\"MonikerArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtrer les résultats par nom</value>\n  </data>\n  <data name=\"MsixArgumentDescription\" xml:space=\"preserve\">\n    <value>Le fichier d’entrée sera traité en tant que MSIX; le hachage de la signature sera fourni s’il est signé</value>\n  </data>\n  <data name=\"MsixSignatureHashFailed\" xml:space=\"preserve\">\n    <value>Impossible de calculer le hachage de la signature MSIX.</value>\n  </data>\n  <data name=\"MSStoreAppBlocked\" xml:space=\"preserve\">\n    <value>Échec de l’installation ou de la mise à niveau du package Microsoft Store en raison du blocage de l’application en question par une stratégie</value>\n  </data>\n  <data name=\"MSStoreInstallOrUpdateFailed\" xml:space=\"preserve\">\n    <value>Échec de l’installation ou de la mise à niveau du package Microsoft Store. Code d’erreur : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Microsoft Store application package fails to install or upgrade. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"MSStoreStoreClientBlocked\" xml:space=\"preserve\">\n    <value>Échec de l’installation ou de la mise à niveau du package Microsoft Store en raison du blocage du client Microsoft Store par une stratégie</value>\n  </data>\n  <data name=\"MSStoreInstallTryGetEntitlement\" xml:space=\"preserve\">\n    <value>Vérification/demande en cours relative à l’acquisition du package...</value>\n  </data>\n  <data name=\"MultipleInstalledPackagesFound\" xml:space=\"preserve\">\n    <value>Plusieurs packages installés correspondent à vos critères saisis. Veuillez affiner votre recherche.</value>\n  </data>\n  <data name=\"MultiplePackagesFound\" xml:space=\"preserve\">\n    <value>Plusieurs packages correspondent à vos critères. Veuillez affiner votre recherche.</value>\n  </data>\n  <data name=\"NameArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtrer les résultats par nom</value>\n  </data>\n  <data name=\"NoApplicableInstallers\" xml:space=\"preserve\">\n    <value>Aucun programme d’installation applicable n’a été trouvé. Pour plus d’informations, consultez les journaux.</value>\n  </data>\n  <data name=\"NoExperimentalFeaturesMessage\" xml:space=\"preserve\">\n    <value>Aucune fonctionnalité expérimentale n’est actuellement disponible. </value>\n  </data>\n  <data name=\"NoInstalledPackageFound\" xml:space=\"preserve\">\n    <value>Aucun package installé ne correspond aux critères saisis.</value>\n  </data>\n  <data name=\"NoPackageFound\" xml:space=\"preserve\">\n    <value>Aucun package ne correspond aux critères sélectionnés.</value>\n  </data>\n  <data name=\"NoVTArgumentDescription\" xml:space=\"preserve\">\n    <value>Désactive l’affichage VirtualTerminal</value>\n    <comment>{Locked=\"VirtualTerminal\"}</comment>\n  </data>\n  <data name=\"OpenLogsArgumentDescription\" xml:space=\"preserve\">\n    <value>Ouvrir l’emplacement des journaux par défaut</value>\n  </data>\n  <data name=\"Options\" xml:space=\"preserve\">\n    <value>options</value>\n    <comment>Options to change how a command works</comment>\n  </data>\n  <data name=\"OverrideArgumentDescription\" xml:space=\"preserve\">\n    <value>Remplacer les arguments à transmettre au programme d’installation</value>\n  </data>\n  <data name=\"Package\" xml:space=\"preserve\">\n    <value>Package : {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for a software package. {0} is a placeholder replaced by the software package name.</comment>\n  </data>\n  <data name=\"PendingWorkError\" xml:space=\"preserve\">\n    <value>Désolé... nous avons oublié de le faire...</value>\n  </data>\n  <data name=\"PositionArgumentDescription\" xml:space=\"preserve\">\n    <value>Position du curseur dans la ligne de commande</value>\n  </data>\n  <data name=\"PrivacyStatement\" xml:space=\"preserve\">\n    <value>Déclaration de confidentialité</value>\n  </data>\n  <data name=\"QueryArgumentDescription\" xml:space=\"preserve\">\n    <value>Requête utilisée pour rechercher un package</value>\n  </data>\n  <data name=\"RainbowArgumentDescription\" xml:space=\"preserve\">\n    <value>La progression affiche un arc-en-ciel de couleurs</value>\n  </data>\n  <data name=\"RequiredArgError\" xml:space=\"preserve\">\n    <value>Argument obligatoire non fourni : '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user does not provide a required command line argument. {0} is a placeholder replaced by an argument name.</comment>\n  </data>\n  <data name=\"RetroArgumentDescription\" xml:space=\"preserve\">\n    <value>Affichage de l’avancement comme couleur par défaut</value>\n  </data>\n  <data name=\"SearchCommandLongDescription\" xml:space=\"preserve\">\n    <value>Recherches de packages à partir de sources configurées.</value>\n  </data>\n  <data name=\"SearchCommandShortDescription\" xml:space=\"preserve\">\n    <value>Rechercher et afficher des informations de base sur les packages</value>\n  </data>\n  <data name=\"SearchId\" xml:space=\"preserve\">\n    <value>ID</value>\n    <comment>Abbreviation of Identifier.</comment>\n  </data>\n  <data name=\"SearchMatch\" xml:space=\"preserve\">\n    <value>Correspondance</value>\n  </data>\n  <data name=\"SearchName\" xml:space=\"preserve\">\n    <value>Nom</value>\n  </data>\n  <data name=\"SearchSource\" xml:space=\"preserve\">\n    <value>Source</value>\n  </data>\n  <data name=\"SearchTruncated\" xml:space=\"preserve\">\n    <value>entrées supplémentaires tronquées en raison de la limite de résultats</value>\n  </data>\n  <data name=\"SearchVersion\" xml:space=\"preserve\">\n    <value>Version</value>\n  </data>\n  <data name=\"SettingLoadFailure\" xml:space=\"preserve\">\n    <value>Les erreurs suivantes ont été détectées lors de la validation des paramètres :</value>\n  </data>\n  <data name=\"SettingsCommandLongDescription\" xml:space=\"preserve\">\n    <value>Ouvrez les paramètres dans l’éditeur de texte JSON par défaut. Si aucun éditeur n’est configuré, ouvre les paramètres dans le bloc-notes. Pour les paramètres disponibles, consultez https://aka.ms/winget-settings Cette commande peut également être utilisée pour définir les paramètres de l’administrateur en fournissant un argument '---enable' ou '---disable'.</value>\n    <comment>{Locked=\"--enable\"} {Locked=\"--disable\"}</comment>\n  </data>\n  <data name=\"SettingsCommandShortDescription\" xml:space=\"preserve\">\n    <value>Ouvrir les paramètres ou définir les paramètres d’administrateur</value>\n  </data>\n  <data name=\"SettingsWarnings\" xml:space=\"preserve\">\n    <value>Erreur inattendue lors du chargement des paramètres. Vérifiez vos paramètres en exécutant la commande 'settings'.</value>\n    <comment>{Locked=\"'settings'\"}</comment>\n  </data>\n  <data name=\"ShowChannel\" xml:space=\"preserve\">\n    <value>Canal</value>\n  </data>\n  <data name=\"ShowCommandLongDescription\" xml:space=\"preserve\">\n    <value>Affiche des informations sur un package spécifique. Par défaut, la requête doit correspondre de façon non sensible à la casse à l’ID, au nom ou au moniker du package. D’autres champs peuvent être utilisés en passant l’option appropriée.</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"ShowCommandShortDescription\" xml:space=\"preserve\">\n    <value>Affiche des informations sur un package</value>\n  </data>\n  <data name=\"ShowVersion\" xml:space=\"preserve\">\n    <value>Version</value>\n  </data>\n  <data name=\"SilentArgumentDescription\" xml:space=\"preserve\">\n    <value>Demander une installation sans assistance</value>\n  </data>\n  <data name=\"SingleCharAfterDashError\" xml:space=\"preserve\">\n    <value>Seul l’alias de caractère peut se produire après une seule – : '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides more than a single character command line alias argument after an alias argument specifier '-'. {0} is a placeholder replaced by the user's argument input.</comment>\n  </data>\n  <data name=\"SourceAddAlreadyExistsDifferentArg\" xml:space=\"preserve\">\n    <value>Une source avec le nom spécifié existe déjà et fait référence à un autre emplacement :</value>\n  </data>\n  <data name=\"SourceAddAlreadyExistsDifferentName\" xml:space=\"preserve\">\n    <value>Une source portant un nom différent fait déjà référence à cet emplacement :</value>\n  </data>\n  <data name=\"SourceAddAlreadyExistsMatch\" xml:space=\"preserve\">\n    <value>Une source avec le nom spécifié existe déjà et fait référence au même emplacement :</value>\n  </data>\n  <data name=\"SourceAddBegin\" xml:space=\"preserve\">\n    <value>Ajout de la source :</value>\n  </data>\n  <data name=\"SourceAddCommandLongDescription\" xml:space=\"preserve\">\n    <value>Ajoutez une nouvelle source. Une source fournit les données vous permettant de découvrir et d’installer des packages. Ajoutez une nouvelle source uniquement si elle est fiable en tant qu’emplacement sécurisé.</value>\n  </data>\n  <data name=\"SourceAddCommandShortDescription\" xml:space=\"preserve\">\n    <value>Ajouter une nouvelle source</value>\n  </data>\n  <data name=\"SourceArgArgumentDescription\" xml:space=\"preserve\">\n    <value>Argument donné à la source</value>\n  </data>\n  <data name=\"SourceArgumentDescription\" xml:space=\"preserve\">\n    <value>Rechercher un package à l’aide de la source indiquée</value>\n  </data>\n  <data name=\"SourceCommandLongDescription\" xml:space=\"preserve\">\n    <value>Gérer les sources à l’aide des sous-commandes. Une source fournit les données vous permettant de découvrir et d’installer des packages. Ajoutez une nouvelle source uniquement si elle est fiable en tant qu’emplacement sécurisé.</value>\n  </data>\n  <data name=\"SourceCommandShortDescription\" xml:space=\"preserve\">\n    <value>Gérer les sources des packages</value>\n  </data>\n  <data name=\"SourceEditCommandLongDescription\" xml:space=\"preserve\">\n    <value>Modifiez les propriétés d’une source existante. Une source fournit les données pour vous permettre de découvrir et d’installer des packages.</value>\n  </data>\n  <data name=\"SourceEditCommandShortDescription\" xml:space=\"preserve\">\n    <value>Modifier les propriétés d’une source</value>\n  </data>\n  <data name=\"SourceEditOne\" xml:space=\"preserve\">\n    <value>Source de modification : {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being edited. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceEditNoChanges\" xml:space=\"preserve\">\n    <value>La source nommée '{0}' est déjà dans l’état souhaité.</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being edited. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceListArg\" xml:space=\"preserve\">\n    <value>Argument</value>\n    <comment>Value given to source.</comment>\n  </data>\n  <data name=\"SourceListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Répertorier toutes les sources actuelles ou tous les détails d’une source précise.</value>\n  </data>\n  <data name=\"SourceListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Répertorier les sources actuelles</value>\n  </data>\n  <data name=\"SourceListData\" xml:space=\"preserve\">\n    <value>Données</value>\n    <comment>Data stored by the source.</comment>\n  </data>\n  <data name=\"SourceListField\" xml:space=\"preserve\">\n    <value>Champ</value>\n    <comment>The name of a piece of information about a source.</comment>\n  </data>\n  <data name=\"SourceListName\" xml:space=\"preserve\">\n    <value>Nom</value>\n    <comment>The name of the source.</comment>\n  </data>\n  <data name=\"SourceListIdentifier\" xml:space=\"preserve\">\n    <value>Identificateur</value>\n    <comment>The source's unique identifier.</comment>\n  </data>\n  <data name=\"SourceListNoneFound\" xml:space=\"preserve\">\n    <value>Désolé... Nous n’avons pas pu trouver la source nommée : {0}</value>\n    <comment>Error message displayed when the user provides a repository source name that was not found. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"SourceListNoSources\" xml:space=\"preserve\">\n    <value>Aucune source n’est configurée.</value>\n  </data>\n  <data name=\"SourceListType\" xml:space=\"preserve\">\n    <value>Type</value>\n    <comment>The kind of source.</comment>\n  </data>\n  <data name=\"SourceListUpdated\" xml:space=\"preserve\">\n    <value>Mis(e) à jour</value>\n    <comment>The last time the source was updated.</comment>\n  </data>\n  <data name=\"SourceListUpdatedNever\" xml:space=\"preserve\">\n    <value>jamais</value>\n    <comment>The source has never been updated.</comment>\n  </data>\n  <data name=\"SourceListValue\" xml:space=\"preserve\">\n    <value>Valeur</value>\n    <comment>The value of information about a source.</comment>\n  </data>\n  <data name=\"SourceNameArgumentDescription\" xml:space=\"preserve\">\n    <value>Nom de la source</value>\n  </data>\n  <data name=\"SourceOpenFailedSuggestion\" xml:space=\"preserve\">\n    <value>Échec lors de l’ouverture de la ou des sources ; essayez la commande « source reset» si le problème persiste.</value>\n    <comment>{Locked=\"source reset\"}</comment>\n  </data>\n  <data name=\"SourceOpenPredefinedFailedSuggestion\" xml:space=\"preserve\">\n    <value>Échec de l’ouverture de la source prédéfinie ; veuillez le signaler aux chargés de maintenance winget.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"SourceRemoveAll\" xml:space=\"preserve\">\n    <value>Suppression en cours de toutes les sources... Merci de patienter.</value>\n  </data>\n  <data name=\"SourceRemoveCommandLongDescription\" xml:space=\"preserve\">\n    <value>Supprimer une source précise.</value>\n  </data>\n  <data name=\"SourceRemoveCommandShortDescription\" xml:space=\"preserve\">\n    <value>Supprimer les sources actuelles</value>\n  </data>\n  <data name=\"SourceRemoveOne\" xml:space=\"preserve\">\n    <value>Suppression de la source : {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being removed. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceResetAll\" xml:space=\"preserve\">\n    <value>Réinitialisation en cours de toutes les sources... Merci de patienter.</value>\n  </data>\n  <data name=\"SourceResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>Cette commande supprime les sources existantes, en conservant éventuellement les données locales. Utilisée sans argument, elle supprime toutes les sources et ajoute les sources par défaut. Si une source nommée est fournie, seule cette source est supprimée.</value>\n  </data>\n  <data name=\"SourceResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>Réinitialiser les sources</value>\n  </data>\n  <data name=\"SourceResetForceArgumentDescription\" xml:space=\"preserve\">\n    <value>Force la réinitialisation des sources</value>\n  </data>\n  <data name=\"SourceResetListAndOverridePreamble\" xml:space=\"preserve\">\n    <value>Les sources suivantes seront réinitialisées si l’option --force est proposée :</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"SourceResetOne\" xml:space=\"preserve\">\n    <value>Réinitialisation de la source : {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a repository source that is currently being reset. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceTypeArgumentDescription\" xml:space=\"preserve\">\n    <value>Type de la source</value>\n  </data>\n  <data name=\"SourceUpdateAll\" xml:space=\"preserve\">\n    <value>Mise à jour en cours de toutes les sources... Merci de patienter.</value>\n  </data>\n  <data name=\"SourceUpdateCommandLongDescription\" xml:space=\"preserve\">\n    <value>Mettre à jour toutes les sources ou uniquement une source précise.</value>\n  </data>\n  <data name=\"SourceUpdateCommandShortDescription\" xml:space=\"preserve\">\n    <value>Mettre à jour les sources actuelles</value>\n  </data>\n  <data name=\"SourceUpdateOne\" xml:space=\"preserve\">\n    <value>Mise à jour de la source : {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being updated. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"TagArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtrer les résultats par mot-clé</value>\n  </data>\n  <data name=\"ThankYou\" xml:space=\"preserve\">\n    <value>Merci d’utiliser winget</value>\n  </data>\n  <data name=\"ThirdPartSoftwareNotices\" xml:space=\"preserve\">\n    <value>Avis de tiers</value>\n  </data>\n  <data name=\"ToolDescription\" xml:space=\"preserve\">\n    <value>L’utilitaire de ligne de commande winget permet d’installer des applications et d’autres packages à partir de la ligne de commande.</value>\n  </data>\n  <data name=\"ToolInfoArgumentDescription\" xml:space=\"preserve\">\n    <value>Afficher les informations générales de l’outil</value>\n  </data>\n  <data name=\"ToolVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>Afficher la version de l’outil</value>\n  </data>\n  <data name=\"TooManyArgError\" xml:space=\"preserve\">\n    <value>Argument fourni plus de fois que le nombre autorisé : '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a command line argument more times than it is allowed. {0} is a placeholder replaced by the user's argument name input.</comment>\n  </data>\n  <data name=\"TooManyBehaviorsError\" xml:space=\"preserve\">\n    <value>Plusieurs arguments de comportement d’exécution fournis : '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides more than one execution behavior argument when installing an application package. {0} is a placeholder replaced by the user specified execution behaviors (e.g. 'silent|interactive').</comment>\n  </data>\n  <data name=\"UnexpectedErrorExecutingCommand\" xml:space=\"preserve\">\n    <value>Une erreur inattendue s'est produite lors de l'exécution de la commande :</value>\n  </data>\n  <data name=\"UninstallPreviousArgumentDescription\" xml:space=\"preserve\">\n    <value>Désinstaller la version précédente du package pendant la mise à niveau</value>\n  </data>\n  <data name=\"UnrecognizedCommand\" xml:space=\"preserve\">\n    <value>Commande non reconnue : '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an unrecognized command. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"UpdateAllArgumentDescription\" xml:space=\"preserve\">\n    <value>Mettre à jour tous les paquets installés vers la dernière version si disponible</value>\n  </data>\n  <data name=\"UpdateNotApplicable\" xml:space=\"preserve\">\n    <value>Aucune mise à niveau applicable trouvée.</value>\n  </data>\n  <data name=\"UpdateNotApplicableReason\" xml:space=\"preserve\">\n    <value>Une version de package plus récente est disponible dans une source configurée, mais elle ne s’applique pas à votre système ou à la configuration requise.</value>\n  </data>\n  <data name=\"UpdateNoPackagesFound\" xml:space=\"preserve\">\n    <value>Mise à niveau disponible introuvable.</value>\n  </data>\n  <data name=\"UpdateNoPackagesFoundReason\" xml:space=\"preserve\">\n    <value>Aucune version de package plus récente n’est disponible à partir des sources configurées.</value>\n  </data>\n  <data name=\"UpgradeCommandLongDescription\" xml:space=\"preserve\">\n    <value>Mises à niveau du paquet sélectionné, trouvé en recherchant les paquets installés ou directement à partir d'un manifeste. Par défaut, la requête doit correspondre, sans respect de la casse, à l’identification, au nom ou au moniker du paquet. D’autres champs peuvent être utilisés en passant leur option appropriée. Si aucun argument n'est fourni, affiche les paquets avec des mises à jour disponibles.</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"UpgradeCommandShortDescription\" xml:space=\"preserve\">\n    <value>Affiche et effectue les mises à niveau disponibles.</value>\n  </data>\n  <data name=\"Usage\" xml:space=\"preserve\">\n    <value>Utilisation : {0} {1}</value>\n    <comment>{Locked=\"{0} {1}\"} Message displayed to provide the user with instructions on how to use a command. {0} is a placeholder replaced by the program name (e.g. 'winget'). {1} is a placeholder replaced by the pattern for using the selected command.</comment>\n  </data>\n  <data name=\"ValidateCommandLongDescription\" xml:space=\"preserve\">\n    <value>Valide un manifeste à l’aide d’un ensemble de directives strict. Ceci est destiné à vous permettre de vérifier le manifeste avant de l’envoyer à un référentiel.</value>\n  </data>\n  <data name=\"ValidateCommandShortDescription\" xml:space=\"preserve\">\n    <value>Valide un fichier manifeste</value>\n  </data>\n  <data name=\"ValidateManifestArgumentDescription\" xml:space=\"preserve\">\n    <value>Chemin d’accès au manifeste à valider</value>\n  </data>\n  <data name=\"VerboseLogsArgumentDescription\" xml:space=\"preserve\">\n    <value>Active la journalisation détaillée pour WinGet</value>\n  </data>\n  <data name=\"VerifyFileSignedMsix\" xml:space=\"preserve\">\n    <value>Veuillez vérifier que le fichier d’entrée est un MSIX signé valide.</value>\n  </data>\n  <data name=\"VersionArgumentDescription\" xml:space=\"preserve\">\n    <value>Utiliser la version indiquée; la version par défaut est la dernière version</value>\n  </data>\n  <data name=\"VersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Afficher les versions disponibles du package</value>\n  </data>\n  <data name=\"WordArgumentDescription\" xml:space=\"preserve\">\n    <value>La valeur fournie avant l’achèvement est demandée</value>\n  </data>\n  <data name=\"GetManifestResultVersionNotFound\" xml:space=\"preserve\">\n    <value>Aucune version correspondante trouvée : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to upgrade an application package to a version that was not found. {0} is a placeholder replaced by the user's provided upgrade package version.</comment>\n  </data>\n  <data name=\"OpenSourceFailedNoMatch\" xml:space=\"preserve\">\n    <value>Aucune source ne correspond à la valeur spécifiée : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to install or upgrade an application package from a repository source that was not found. {0} is a placeholder replaced by the user's repository source name input.</comment>\n  </data>\n  <data name=\"OpenSourceFailedNoMatchHelp\" xml:space=\"preserve\">\n    <value>Les sources configurées sont :</value>\n  </data>\n  <data name=\"OpenSourceFailedNoSourceDefined\" xml:space=\"preserve\">\n    <value>Aucune source définie ; ajoutez-en une avec « source add » ou rétablissez les valeurs par défaut de « source reset »</value>\n    <comment>{Locked=\"source add\",\"source reset\"}</comment>\n  </data>\n  <data name=\"ReportIdentityFound\" xml:space=\"preserve\">\n    <value>Trouvé</value>\n  </data>\n  <data name=\"VerifyFileFailedIsDirectory\" xml:space=\"preserve\">\n    <value>Le chemin d’accès est un répertoire : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system path that is a directory. {0} is a placeholder replaced by the provided directory path.</comment>\n  </data>\n  <data name=\"VerifyFileFailedNotExist\" xml:space=\"preserve\">\n    <value>Le fichier n'existe pas : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system file that does not exist. {0} is a placeholder replaced by the provided file path.</comment>\n  </data>\n  <data name=\"BothManifestAndSearchQueryProvided\" xml:space=\"preserve\">\n    <value>Les arguments manifeste et requête de recherche locaux sont tous deux fournis</value>\n  </data>\n  <data name=\"Logs\" xml:space=\"preserve\">\n    <value>Journaux</value>\n    <comment>Label displayed for diagnostic files containing information about the application use.</comment>\n  </data>\n  <data name=\"InstallerBlockedByPolicy\" xml:space=\"preserve\">\n    <value>Le programme d’installation est bloqué par une stratégie</value>\n  </data>\n  <data name=\"InstallerFailedSecurityCheck\" xml:space=\"preserve\">\n    <value>Le programme d’installation a échoué vérification de sécurité</value>\n  </data>\n  <data name=\"InstallerFailedVirusScan\" xml:space=\"preserve\">\n    <value>Un produit antivirus signale une infection dans le programme d’installation</value>\n  </data>\n  <data name=\"SourceOpenWithFailedUpdate\" xml:space=\"preserve\">\n    <value>Échec de la tentative de mise à jour de la source : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to update the repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"UninstallCommandLongDescription\" xml:space=\"preserve\">\n    <value>Désinstalle le package sélectionné, que vous avez trouvé en effectuant une recherche dans la liste des packages installés ou directement à partir d’un manifeste. Par défaut, la requête doit correspondre de façon non sensible à la casse à l’ID, au nom ou au moniker du package. D’autres champs peuvent être utilisés en passant l’option appropriée.</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"UninstallCommandShortDescription\" xml:space=\"preserve\">\n    <value>Désinstallation du paquet donné</value>\n  </data>\n  <data name=\"UninstallFlowStartingPackageUninstall\" xml:space=\"preserve\">\n    <value>Début de la désinstallation du paquet...</value>\n  </data>\n  <data name=\"UninstallFlowUninstallSuccess\" xml:space=\"preserve\">\n    <value>Désinstallé avec succès</value>\n  </data>\n  <data name=\"NoUninstallInfoFound\" xml:space=\"preserve\">\n    <value>winget ne peut pas trouver la commande de désinstallation pour ce package. Veuillez contacter l’éditeur du package pour obtenir de l’aide.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"UninstallAbandoned\" xml:space=\"preserve\">\n    <value>Désinstallation abandonnée</value>\n  </data>\n  <data name=\"UninstallFailedWithCode\" xml:space=\"preserve\">\n    <value>Échec du programme de désinstallation avec le code de sortie : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to uninstall an application package fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"ExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Exporte une liste des packages installés</value>\n  </data>\n  <data name=\"ImportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Installe tous les packages listés dans un fichier.</value>\n  </data>\n  <data name=\"ImportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Installe tous les packages dans un fichier</value>\n  </data>\n  <data name=\"OutputFileArgumentDescription\" xml:space=\"preserve\">\n    <value>Fichier dans lequel le résultat doit être écrit</value>\n  </data>\n  <data name=\"ImportFileArgumentDescription\" xml:space=\"preserve\">\n    <value>Fichier décrivant les packages à installer</value>\n  </data>\n  <data name=\"ExportSourceArgumentDescription\" xml:space=\"preserve\">\n    <value>Exporter les packages à partir de la source spécifiée</value>\n  </data>\n  <data name=\"ExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Écrit une liste des packages installés dans un fichier. Les packages peuvent ensuite être installés à l’aide de la commande import.</value>\n    <comment>{Locked=\"import\"}</comment>\n  </data>\n  <data name=\"ImportInstallFailed\" xml:space=\"preserve\">\n    <value>L’installation d’un ou plusieurs packages importés a échoué</value>\n  </data>\n  <data name=\"ImportSourceNotInstalled\" xml:space=\"preserve\">\n    <value>La source requise pour l’importation n’est pas installée : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to import application package(s) from a repository source that is not installed. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"InstalledPackageNotAvailable\" xml:space=\"preserve\">\n    <value>Le package installé n’est pas disponible à partir d’une source : {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when the user attempts to export an installed application package that is not available from any repository source. {0} is a placeholder replaced by the installed package name.</comment>\n  </data>\n  <data name=\"InstalledPackageVersionNotAvailable\" xml:space=\"preserve\">\n    <value>La version installée du package n’est pas disponible à partir d’aucune source : {0} {1} {2}</value>\n    <comment>{Locked=\"{0} {1} {2}\"} Warning message displayed when the user attempts to export an installed application package with a version that is not available from any repository source. {0} is a placeholder replaced by the installed package identifier. {1} is a placeholder replaced by the installed package version. {2} is a placeholder replaced by the installed package channel.</comment>\n  </data>\n  <data name=\"NoPackagesInImportFile\" xml:space=\"preserve\">\n    <value>Aucun package n’a été trouvé dans le fichier d’importation</value>\n  </data>\n  <data name=\"InvalidJsonFile\" xml:space=\"preserve\">\n    <value>Le fichier JSON n'est pas valide</value>\n  </data>\n  <data name=\"MultiQueryPackageAlreadyInstalled\" xml:space=\"preserve\">\n    <value>Le package est déjà installé : {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user that an application package is already installed. {0} is a placeholder replaced by the package identifier or search query.</comment>\n  </data>\n  <data name=\"ImportIgnoreUnavailableArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignorer les packages non disponibles</value>\n  </data>\n  <data name=\"ExportIncludeVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Inclure les versions de paquets dans le fichier d’exportation</value>\n  </data>\n  <data name=\"ImportIgnoreVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignorer les versions de package du fichier d’importation</value>\n  </data>\n  <data name=\"VerifyPathFailedNotExist\" xml:space=\"preserve\">\n    <value>Le chemin d’accès n’existe pas : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system path argument value that does not exist. {0} is a placeholder replaced by the user's provided path.</comment>\n  </data>\n  <data name=\"ImportFileHasInvalidSchema\" xml:space=\"preserve\">\n    <value>Le fichier JSON ne spécifie pas de schéma reconnu.</value>\n  </data>\n  <data name=\"InstallScopeDescription\" xml:space=\"preserve\">\n    <value>Sélectionner l’étendue d’installation (user ou machine)</value>\n    <comment>{Locked=\"user\",\"machine\"} This argument allows the user to select between installing for just the user or for the entire machine.</comment>\n  </data>\n  <data name=\"InvalidArgumentValueError\" xml:space=\"preserve\">\n    <value>La valeur fournie pour l’argument '{0}' n’est pas valide ; les valeurs valides sont : {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message displayed when the user provides an invalid command line argument value. {0} is a placeholder replaced by the argument name. {1} is a placeholder replaced by a list of valid options.</comment>\n  </data>\n  <data name=\"DisabledByGroupPolicy\" xml:space=\"preserve\">\n    <value>Cette opération est désactivée par stratégie de groupe : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user performs a command operation that is disabled by a group policy. {0} is a placeholder replaced by a group policy description.</comment>\n  </data>\n  <data name=\"PolicyAdditionalSources\" xml:space=\"preserve\">\n    <value>Activer les sources supplémentaires du Programme d’installation de l’application Windows</value>\n  </data>\n  <data name=\"PolicyAllowedSources\" xml:space=\"preserve\">\n    <value>Activer les sources autorisées du Programme d’installation de l’application Windows</value>\n  </data>\n  <data name=\"PolicyEnableDefaultSource\" xml:space=\"preserve\">\n    <value>Activer la source par défaut du Programme d’installation de l’application Windows</value>\n  </data>\n  <data name=\"PolicyEnableExperimentalFeatures\" xml:space=\"preserve\">\n    <value>Activer les fonctionnalités expérimentales du Programme d’installation de l’application Windows</value>\n  </data>\n  <data name=\"PolicyEnableMSStoreSource\" xml:space=\"preserve\">\n    <value>Activer la source Microsoft Store du Programme d’installation d’application Windows</value>\n  </data>\n  <data name=\"PolicyEnableFontSource\" xml:space=\"preserve\">\n    <value>Activer la source de polices Windows App Installer</value>\n  </data>\n  <data name=\"PolicyEnableWinGetSettings\" xml:space=\"preserve\">\n    <value>Activer les paramètres du Gestionnaire de package Windows</value>\n  </data>\n  <data name=\"PolicyEnableWinGet\" xml:space=\"preserve\">\n    <value>Activer le Gestionnaire de package Windows</value>\n  </data>\n  <data name=\"PolicyEnableWindowsPackageManagerCommandLineInterfaces\" xml:space=\"preserve\">\n    <value>Activer les interfaces de ligne de commande Gestionnaire de package Windows</value>\n  </data>\n  <data name=\"PolicySourceAutoUpdateInterval\" xml:space=\"preserve\">\n    <value>Définir l’intervalle en minutes de la mise à jour automatique source du Gestionnaire de package Windows</value>\n  </data>\n  <data name=\"PoliciesPolicy\" xml:space=\"preserve\">\n    <value>Stratégie de groupe</value>\n    <comment>Header for a table listing active Group Policies</comment>\n  </data>\n  <data name=\"PolicyEnableLocalManifests\" xml:space=\"preserve\">\n    <value>Activer les fichiers de manifeste locaux du Programme d'installation de l'application Windows</value>\n  </data>\n  <data name=\"PolicyEnableBypassCertificatePinningForMicrosoftStore\" xml:space=\"preserve\">\n    <value>Activer le contournement de certificat épinglé de la source Microsoft Store de l’Installeur d'applications Windows</value>\n  </data>\n  <data name=\"PolicyEnableLocalArchiveMalwareScanOverride\" xml:space=\"preserve\">\n    <value>Activer le remplacement de l’analyse des programmes malveillants des archives locales Windows Programme d'installation d'application</value>\n  </data>\n  <data name=\"SettingsWarningField\" xml:space=\"preserve\">\n    <value>Champ : {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when a user setting field has invalid syntax or semantics. {0} is a placeholder replaced by the setting field path.</comment>\n  </data>\n  <data name=\"SettingsWarningInvalidFieldFormat\" xml:space=\"preserve\">\n    <value>Format de champ non valide.</value>\n  </data>\n  <data name=\"SettingsWarningInvalidFieldValue\" xml:space=\"preserve\">\n    <value>Valeur de champ non valide.</value>\n  </data>\n  <data name=\"SettingsWarningInvalidValueFromPolicy\" xml:space=\"preserve\">\n    <value>Paramètre non valide dans la stratégie de groupe.</value>\n  </data>\n  <data name=\"SettingsWarningLoadedBackupSettings\" xml:space=\"preserve\">\n    <value>Paramètres chargés à partir du fichier de sauvegarde.</value>\n  </data>\n  <data name=\"SettingsWarningParseError\" xml:space=\"preserve\">\n    <value>Erreur lors de l’analyse du message :</value>\n  </data>\n  <data name=\"SettingsWarningValue\" xml:space=\"preserve\">\n    <value>Valeur : {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when a user setting value has invalid syntax or semantics. {0} is a placeholder replaced by the setting data value.</comment>\n  </data>\n  <data name=\"FeaturesMessageDisabledByPolicy\" xml:space=\"preserve\">\n    <value>Les fonctionnalités expérimentales suivantes sont en cours.\nLa configuration est désactivée en raison d’une stratégie de groupe.</value>\n  </data>\n  <data name=\"InstallerHashMismatchError\" xml:space=\"preserve\">\n    <value>Le code de hachage du programme d’installation ne correspond pas.</value>\n  </data>\n  <data name=\"PolicyEnableHashOverride\" xml:space=\"preserve\">\n    <value>Activer le remplacement de code de hachage du Programme d’installation de l’application Windows</value>\n  </data>\n  <data name=\"SourceExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Exportez les sources actuelles en tant que JSON pour la stratégie de groupe.</value>\n  </data>\n  <data name=\"SourceExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Exporter les sources actuelles</value>\n  </data>\n  <data name=\"SourceListAdditionalSource\" xml:space=\"preserve\">\n    <value>Source supplémentaire</value>\n    <comment>An additional source required by policy.</comment>\n  </data>\n  <data name=\"SourceListAllowedSource\" xml:space=\"preserve\">\n    <value>Source autorisée</value>\n    <comment>A source that the user is allowed to add.</comment>\n  </data>\n  <data name=\"InvalidArgumentValueErrorWithoutValidValues\" xml:space=\"preserve\">\n    <value>La valeur fournie pour l’argument '{0}' n’est pas valide</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an invalid command line argument value. {0} is a placeholder replaced by the argument name.</comment>\n  </data>\n  <data name=\"Cancelled\" xml:space=\"preserve\">\n    <value>Annulé</value>\n  </data>\n  <data name=\"ExternalDependencies\" xml:space=\"preserve\">\n    <value>Externe</value>\n  </data>\n  <data name=\"ImportCommandReportDependencies\" xml:space=\"preserve\">\n    <value>Les packages trouvés dans cette importation ont les dépendances suivantes :</value>\n    <comment>Import command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"PackageRequiresDependencies\" xml:space=\"preserve\">\n    <value>Ce package nécessite les dépendances suivantes :</value>\n    <comment>Message shown before reporting dependencies</comment>\n  </data>\n  <data name=\"DependenciesFlowInstall\" xml:space=\"preserve\">\n    <value>Installation des dépendances</value>\n  </data>\n  <data name=\"DependenciesFlowSourceNotFound\" xml:space=\"preserve\">\n    <value>Source de dépendance introuvable</value>\n  </data>\n  <data name=\"DependenciesFlowSourceTooManyMatches\" xml:space=\"preserve\">\n    <value>La recherche de package produit plusieurs résultats : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when application packages search yield more than one result. {0} is a placeholder replaced by the dependency package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowPackageVersionNotFound\" xml:space=\"preserve\">\n    <value>Dernière version introuvable pour le package : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when no suitable version found for the specific application package. {0} is a placeholder replaced by the package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoInstallerFound\" xml:space=\"preserve\">\n    <value>Aucun programme d’installation trouvé : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when no installer found for a manifest. {0} is a placeholder replaced by the manifest identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoMinVersion\" xml:space=\"preserve\">\n    <value>Version minimale requise non disponible pour le package : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the minimum required version is not available for an application package. {0} is a placeholder replaced by the package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoMatches\" xml:space=\"preserve\">\n    <value>Aucun résultat trouvé</value>\n    <comment>When package search yields no matches</comment>\n  </data>\n  <data name=\"DependenciesFlowContainsLoop\" xml:space=\"preserve\">\n    <value>A une boucle</value>\n    <comment>Dependency graph has loop</comment>\n  </data>\n  <data name=\"DependenciesFlowNoSuitableInstallerFound\" xml:space=\"preserve\">\n    <value>Aucun programme d’installation approprié n’a été trouvé pour le manifeste : {0} version {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message displayed when an attempt to get a preferred installer for a manifest fails. {0} is a placeholder replaced by the manifest identifier. {1} is a placeholder replaced by the manifest version.</comment>\n  </data>\n  <data name=\"DependenciesManagementError\" xml:space=\"preserve\">\n    <value>Erreur lors du traitement des dépendances de package. Voulez-vous continuer l’installation ?</value>\n    <comment>Prompt message shown when dependencies processing yields errors.</comment>\n  </data>\n  <data name=\"DependenciesManagementExitMessage\" xml:space=\"preserve\">\n    <value>Erreur lors du traitement des dépendances de package. Sortie...</value>\n  </data>\n  <data name=\"PackageDependencies\" xml:space=\"preserve\">\n    <value>Packages</value>\n  </data>\n  <data name=\"UninstallCommandReportDependencies\" xml:space=\"preserve\">\n    <value>Ce package comportait des dépendances qui n’étaient peut-être plus nécessaires :</value>\n    <comment>Uninstall command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"ValidateCommandReportDependencies\" xml:space=\"preserve\">\n    <value>Le manifeste a les dépendances suivantes qui n’ont pas été validées ; vérifiez qu’ils sont valides :</value>\n    <comment>Validate command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"WindowsFeaturesDependencies\" xml:space=\"preserve\">\n    <value>Fonctionnalités de Windows</value>\n  </data>\n  <data name=\"WindowsLibrariesDependencies\" xml:space=\"preserve\">\n    <value>Bibliothèques Windows</value>\n  </data>\n  <data name=\"DependencySourceArgumentDescription\" xml:space=\"preserve\">\n    <value>Rechercher les dépendances de package à l’aide de la source spécifiée</value>\n    <comment>For getting package type dependencies when installing from a local manifest</comment>\n  </data>\n  <data name=\"WindowsStoreTerms\" xml:space=\"preserve\">\n    <value>Conditions générales du Windows Store</value>\n  </data>\n  <data name=\"AcceptPackageAgreementsArgumentDescription\" xml:space=\"preserve\">\n    <value>Accepter tous les contrats de licence pour les packages</value>\n  </data>\n  <data name=\"ExportedPackageRequiresLicenseAgreement\" xml:space=\"preserve\">\n    <value>L’installation du package exporté nécessite un contrat de licence : {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when an exported application package requires license agreement to install. {0} is a placeholder replaced by the package name.</comment>\n  </data>\n  <data name=\"PackageAgreementsPrompt\" xml:space=\"preserve\">\n    <value>L’éditeur exige que vous consultiez les informations ci-dessus et acceptiez les contrats avant de procéder à l’installation.\nAcceptez-vous les conditions ?</value>\n  </data>\n  <data name=\"PackageAgreementsNotAgreedTo\" xml:space=\"preserve\">\n    <value>Les contrats de package n’ont pas été acceptés. Opération annulée.</value>\n  </data>\n  <data name=\"ShowLabelAgreements\" xml:space=\"preserve\">\n    <value>Contrats :</value>\n  </data>\n  <data name=\"ShowLabelAuthor\" xml:space=\"preserve\">\n    <value>Auteur :</value>\n  </data>\n  <data name=\"ShowLabelDescription\" xml:space=\"preserve\">\n    <value>Description :</value>\n  </data>\n  <data name=\"ShowLabelInstaller\" xml:space=\"preserve\">\n    <value>Programme d'installation :</value>\n  </data>\n  <data name=\"ShowLabelInstallerLocale\" xml:space=\"preserve\">\n    <value>Paramètres régionaux du programme d’installation :</value>\n  </data>\n  <data name=\"ShowLabelInstallerProductId\" xml:space=\"preserve\">\n    <value>ID de produit du Store :</value>\n  </data>\n  <data name=\"ShowLabelInstallerSha256\" xml:space=\"preserve\">\n    <value>SHA256 du programme d’installation :</value>\n  </data>\n  <data name=\"ShowLabelInstallerType\" xml:space=\"preserve\">\n    <value>Type du programme d’installation :</value>\n  </data>\n  <data name=\"ShowLabelInstallerUrl\" xml:space=\"preserve\">\n    <value>URL du programme d’installation :</value>\n  </data>\n  <data name=\"ShowLabelLicense\" xml:space=\"preserve\">\n    <value>Licence :</value>\n  </data>\n  <data name=\"ShowLabelLicenseUrl\" xml:space=\"preserve\">\n    <value>URL de la licence :</value>\n  </data>\n  <data name=\"ShowLabelMoniker\" xml:space=\"preserve\">\n    <value>Moniker :</value>\n  </data>\n  <data name=\"ShowLabelPackageUrl\" xml:space=\"preserve\">\n    <value>Page d’accueil :</value>\n  </data>\n  <data name=\"ShowLabelPublisher\" xml:space=\"preserve\">\n    <value>Publisher :</value>\n  </data>\n  <data name=\"ShowLabelTags\" xml:space=\"preserve\">\n    <value>Mots-clés :</value>\n  </data>\n  <data name=\"ShowLabelVersion\" xml:space=\"preserve\">\n    <value>Version :</value>\n  </data>\n  <data name=\"ShowLabelDependencies\" xml:space=\"preserve\">\n    <value>Dépendances :</value>\n  </data>\n  <data name=\"ShowLabelWindowsFeaturesDependencies\" xml:space=\"preserve\">\n    <value>Fonctionnalités de Windows :</value>\n  </data>\n  <data name=\"ShowLabelWindowsLibrariesDependencies\" xml:space=\"preserve\">\n    <value>Bibliothèques Windows :</value>\n  </data>\n  <data name=\"ShowLabelPackageDependencies\" xml:space=\"preserve\">\n    <value>Dépendances de package :</value>\n  </data>\n  <data name=\"ShowLabelExternalDependencies\" xml:space=\"preserve\">\n    <value>Dépendances externes :</value>\n  </data>\n  <data name=\"PromptOptionNo\" xml:space=\"preserve\">\n    <value>Non</value>\n  </data>\n  <data name=\"PromptOptionYes\" xml:space=\"preserve\">\n    <value>Oui</value>\n  </data>\n  <data name=\"SourceAddOpenSourceFailed\" xml:space=\"preserve\">\n    <value>Échec de l’ouverture de la source ajoutée.</value>\n  </data>\n  <data name=\"AcceptSourceAgreementsArgumentDescription\" xml:space=\"preserve\">\n    <value>Accepter tous les contrats sources pendant les opérations sources</value>\n  </data>\n  <data name=\"SourceAgreementsTitle\" xml:space=\"preserve\">\n    <value>La source '{0}' nécessite que vous consultiez les contrats suivants avant de l’utiliser.</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user that a repository source requires viewing agreements before using. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceAgreementsPrompt\" xml:space=\"preserve\">\n    <value>Acceptez-vous toutes les conditions des contrats sources ?</value>\n  </data>\n  <data name=\"SourceAgreementsNotAgreedTo\" xml:space=\"preserve\">\n    <value>Un ou plusieurs contrats sources n’ont pas été acceptés. Opération annulée. Acceptez les contrats sources ou supprimez les sources correspondantes.</value>\n  </data>\n  <data name=\"SourceAgreementsMarketMessage\" xml:space=\"preserve\">\n    <value>La source nécessite que la région géographique à 2 lettres de l’ordinateur actuel soit envoyée au service principal pour fonctionner correctement (par exemple, « ÉTATS-UNIS »).</value>\n  </data>\n  <data name=\"InstallFlowRegistrationDeferred\" xml:space=\"preserve\">\n    <value>Installation réussie. Redémarrez l’application pour terminer la mise à niveau.</value>\n  </data>\n  <data name=\"HeaderArgumentDescription\" xml:space=\"preserve\">\n    <value>Optional Windows-Package-Manager REST source HTTP header</value>\n  </data>\n  <data name=\"HeaderArgumentNotApplicableForNonRestSourceWarning\" xml:space=\"preserve\">\n    <value>Ignorer l'en-tête facultatif car il n'est pas applicable pour cette source.</value>\n  </data>\n  <data name=\"HeaderArgumentNotApplicableWithoutSource\" xml:space=\"preserve\">\n    <value>L’en-tête facultatif n’est pas applicable sans spécifier de source : '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user performs an operation (e.g install) and provides the HTTP 'header' argument without specifying the repository source. {0} is a placeholder replaced by the header argument name.</comment>\n  </data>\n  <data name=\"ShowLabelInstallerReleaseDate\" xml:space=\"preserve\">\n    <value>Date de version :</value>\n  </data>\n  <data name=\"ShowLabelInstallerOfflineDistributionSupported\" xml:space=\"preserve\">\n    <value>Distribution hors ligne prise en charge :</value>\n  </data>\n  <data name=\"ShowLabelPublisherUrl\" xml:space=\"preserve\">\n    <value>ID de l’Editeur</value>\n  </data>\n  <data name=\"ShowLabelPurchaseUrl\" xml:space=\"preserve\">\n    <value>URL d’achat :</value>\n  </data>\n  <data name=\"ShowLabelPublisherSupportUrl\" xml:space=\"preserve\">\n    <value>URL de support de l’éditeur :</value>\n  </data>\n  <data name=\"ShowLabelPrivacyUrl\" xml:space=\"preserve\">\n    <value>URL de confidentialité :</value>\n  </data>\n  <data name=\"ShowLabelCopyright\" xml:space=\"preserve\">\n    <value>Copyright :</value>\n  </data>\n  <data name=\"ShowLabelCopyrightUrl\" xml:space=\"preserve\">\n    <value>URL de copyright :</value>\n  </data>\n  <data name=\"ShowLabelReleaseNotes\" xml:space=\"preserve\">\n    <value>Notes de publication :</value>\n  </data>\n  <data name=\"ShowLabelReleaseNotesUrl\" xml:space=\"preserve\">\n    <value>URL des notes de publication :</value>\n  </data>\n  <data name=\"SearchFailureWarning\" xml:space=\"preserve\">\n    <value>Échec lors de la recherche de la source ; les résultats ne seront pas inclus : {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when searching a repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SearchFailureError\" xml:space=\"preserve\">\n    <value>Échec lors de la recherche de la source : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when searching a repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"FeatureDisabledByAdminSettingMessage\" xml:space=\"preserve\">\n    <value>Cette fonctionnalité doit être activée par les administrateurs. Pour l’activer, exécutez « winget settings --enable {0} » en tant qu’administrateur.</value>\n    <comment>{Locked=\"winget settings --enable\", \"{0}\"}. Error message displayed when the user uses a feature that needs to be enabled by administrators. {0} is a placeholder replaced by the admin setting.</comment>\n  </data>\n  <data name=\"AdminSettingEnableDescription\" xml:space=\"preserve\">\n    <value>Active le paramètre d’administrateur spécifique</value>\n  </data>\n  <data name=\"AdminSettingDisableDescription\" xml:space=\"preserve\">\n    <value>Désactive le paramètre d’administrateur spécifique.</value>\n  </data>\n  <data name=\"AdminSettingEnabled\" xml:space=\"preserve\">\n    <value>Paramètre d’administration « {0} » activé.</value>\n    <comment>{Locked=\"{0}\"} Message displayed when the user enables an admin setting. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"AdminSettingDisabled\" xml:space=\"preserve\">\n    <value>Paramètre d’administration « {0} » désactivé.</value>\n    <comment>{Locked=\"{0}\"} Message displayed when the user disables an admin setting. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"AdminSettingHeader\" xml:space=\"preserve\">\n    <value>Paramètre administrateur</value>\n    <comment>Header for a table displaying admin settings.</comment>\n  </data>\n  <data name=\"InstallFlowReturnCodePackageInUse\" xml:space=\"preserve\">\n    <value>L’application est en cours d’exécution. Quittez l’application, puis réessayez.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodePackageInUseByApplication\" xml:space=\"preserve\">\n    <value>Les fichiers modifiés par le programme d’installation sont actuellement utilisés par une autre application. Quittez les applications, puis réessayez.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInstallInProgress\" xml:space=\"preserve\">\n    <value>Une autre installation est déjà en cours. Veuillez réessayez.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeFileInUse\" xml:space=\"preserve\">\n    <value>Un ou plusieurs fichiers sont en cours d’utilisation. Quittez l’application, puis réessayez.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeMissingDependency\" xml:space=\"preserve\">\n    <value>Ce package a une dépendance manquante dans votre système.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeDiskFull\" xml:space=\"preserve\">\n    <value>Votre PC n’a plus d’espace disponible. Libérez de l’espace, puis réessayez.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInsufficientMemory\" xml:space=\"preserve\">\n    <value>Mémoire disponible insuffisante pour l’installation. Fermez les autres applications, puis réessayez.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInvalidParameter\" xml:space=\"preserve\">\n    <value>L’un des paramètres d’installation n’est pas valide. Le journal d’installation du package peut contenir des détails supplémentaires.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeNoNetwork\" xml:space=\"preserve\">\n    <value>Cette application nécessite une connectivité Internet. Connectez-vous à un réseau, puis réessayez.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeContactSupport\" xml:space=\"preserve\">\n    <value>Cette application a rencontré une erreur lors de l’installation. Contactez le support.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootRequiredToFinish\" xml:space=\"preserve\">\n    <value>Redémarrez votre PC pour terminer l’installation.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootRequiredForInstall\" xml:space=\"preserve\">\n    <value>Votre PC redémarrera pour terminer l’installation.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootInitiated\" xml:space=\"preserve\">\n    <value>Échec de l’installation. Redémarrez votre PC, puis réessayez.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeCancelledByUser\" xml:space=\"preserve\">\n    <value>L’installation a été annulée par l’utilisateur.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeAlreadyInstalled\" xml:space=\"preserve\">\n    <value>Une autre version de cette application est déjà installée.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeDowngrade\" xml:space=\"preserve\">\n    <value>Une version supérieure de cette application est déjà installée.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeBlockedByPolicy\" xml:space=\"preserve\">\n    <value>Les stratégies d’organisation empêchent l’installation. Contactez votre administrateur.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeSystemNotSupported\" xml:space=\"preserve\">\n    <value>La configuration système actuelle ne prend pas en charge l’installation de ce package.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeCustomError\" xml:space=\"preserve\">\n    <value>Échec de l’installation avec une erreur du programme d’installation personnalisé. Contactez le support du package.</value>\n  </data>\n  <data name=\"InstallAbandoned\" xml:space=\"preserve\">\n    <value>L’installation a été abandonnée</value>\n  </data>\n  <data name=\"InstallerFailedWithCode\" xml:space=\"preserve\">\n    <value>Échec du programme d’installation avec le code de sortie : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the application installer fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"InstallerLogAvailable\" xml:space=\"preserve\">\n    <value>Le journal du programme d’installation est disponible à l’adresse suivante : {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about the system path of a diagnostic files containing information about the installer. {0} is a placeholder replaced by the diagnostic file system path.</comment>\n  </data>\n  <data name=\"SearchFailureErrorListMatches\" xml:space=\"preserve\">\n    <value>Les packages suivants ont été trouvés parmi les sources de travail.\nSpécifiez l’un d’entre eux à l’aide de l’option --source pour continuer.</value>\n    <comment>{Locked=\"--source\"} \"working sources\" as in \"sources that are working correctly\"</comment>\n  </data>\n  <data name=\"SearchFailureErrorNoMatches\" xml:space=\"preserve\">\n    <value>Aucun package n’a été trouvé parmi les sources de travail.</value>\n    <comment>\"working sources\" as in \"sources that are working correctly\"</comment>\n  </data>\n  <data name=\"FeaturesMessageDisabledByBuild\" xml:space=\"preserve\">\n    <value>Il s’agit d’une version stable du Gestionnaire de package Windows. Si vous voulez essayer des fonctionnalités expérimentales, installez une version préliminaire. Des instructions sont disponibles sur GitHub : https://github.com/microsoft/winget-cli.</value>\n    <comment>{Locked=\"https://github.com/microsoft/winget-cli\"}</comment>\n  </data>\n  <data name=\"WindowsPackageManager\" xml:space=\"preserve\">\n    <value>Gestionnaire de package Windows v{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying the product name and version. {0} is a placeholder replaced by the product version.</comment>\n  </data>\n  <data name=\"ImportIgnorePackageVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignorer les versions de paquets dans le fichier d’importation</value>\n  </data>\n  <data name=\"CountOutOfBoundsError\" xml:space=\"preserve\">\n    <value>Le nombre de résultats demandé doit être compris entre 1 et 1 000.</value>\n  </data>\n  <data name=\"CustomSwitchesArgumentDescription\" xml:space=\"preserve\">\n    <value>Arguments à passer au programme d’installation en plus des valeurs par défaut</value>\n  </data>\n  <data name=\"UpgradeDifferentInstallTechnologyInNewerVersions\" xml:space=\"preserve\">\n    <value>Une version plus récente a été trouvée, mais la technologie d’installation est différente de la version actuelle installée. Désinstallez le package et installez la version la plus récente.</value>\n  </data>\n  <data name=\"UpgradeDifferentInstallTechnology\" xml:space=\"preserve\">\n    <value>La technologie d’installation de la version la plus récente spécifiée est différente de la version actuelle installée. Désinstallez le package et installez la version la plus récente.</value>\n  </data>\n  <data name=\"WindowsPackageManagerPreview\" xml:space=\"preserve\">\n    <value>Gestionnaire de package Windows (Préversion) v{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying the preview product name and pre-release version. {0} is a placeholder replaced by the product version.</comment>\n  </data>\n  <data name=\"ArchitectureArgumentDescription\" xml:space=\"preserve\">\n    <value>Sélectionner l’architecture</value>\n  </data>\n  <data name=\"IncludeUnknownArgumentDescription\" xml:space=\"preserve\">\n    <value>Mettre à niveau les packages même si leur version actuelle ne peut pas être déterminée</value>\n  </data>\n  <data name=\"IncludeUnknownInListArgumentDescription\" xml:space=\"preserve\">\n    <value>Répertorie les packages même si leur version actuelle ne peut pas être déterminée. Ne peut être utilisé qu’avec l’argument --upgrade-available</value>\n    <comment>{Locked=\"--upgrade-available\"}</comment>\n  </data>\n  <data name=\"UpgradeUnknownVersionExplanation\" xml:space=\"preserve\">\n    <value>Impossible de déterminer le numéro de version de ce package. Pour le mettre à niveau quand même, ajoutez l’argument --include-unknown à votre commande précédente.</value>\n    <comment>{Locked=\"--include-unknown\"}</comment>\n  </data>\n  <data name=\"UpgradeUnknownVersionCount\" xml:space=\"preserve\">\n    <value>{0} package(s) a(ont) des numéros de version qui ne peuvent pas être déterminés. Utilisez --include-unknown pour afficher tous les résultats.</value>\n    <comment>{Locked=\"{0}\",\"--include-unknown\"} {0} is a placeholder that is replaced by an integer number of packages that do not have notated versions. </comment>\n  </data>\n  <data name=\"UpgradeRequireExplicitCount\" xml:space=\"preserve\">\n    <value>{0} package(s) sont épinglé(s) et doit(doivent) être explicitement mis à niveau.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by an integer number of packages that require explicit upgrades.</comment>\n  </data>\n  <data name=\"InvalidArgumentWithoutQueryError\" xml:space=\"preserve\">\n    <value>Les arguments fournis ne peuvent être utilisés qu’avec une requête.</value>\n  </data>\n  <data name=\"SystemArchitecture\" xml:space=\"preserve\">\n    <value>Architecture du système : {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for the system architecture. {0} is a placeholder replaced by the value of the system architecture (e.g. X64).</comment>\n  </data>\n  <data name=\"PreserveArgumentDescription\" xml:space=\"preserve\">\n    <value>Conserve tous les fichiers et répertoires créés par le package (portables)</value>\n  </data>\n  <data name=\"PurgeArgumentDescription\" xml:space=\"preserve\">\n    <value>Supprimer tous les fichiers et répertoires du répertoire du package (portable)</value>\n  </data>\n  <data name=\"PressEnterToContinue\" xml:space=\"preserve\">\n    <value>Appuyez sur Entrée pour continuer . . .</value>\n  </data>\n  <data name=\"RenameArgumentDescription\" xml:space=\"preserve\">\n    <value>Valeur pour renommer le fichier exécutable (portable)</value>\n  </data>\n  <data name=\"WaitArgumentDescription\" xml:space=\"preserve\">\n    <value>Invite l’utilisateur à appuyer sur une touche avant de quitter</value>\n  </data>\n  <data name=\"InstallerElevationExpected\" xml:space=\"preserve\">\n    <value>Le programme d’installation demande à s’exécuter en tant qu’administrateur. Attendez-vous à une invite.</value>\n  </data>\n  <data name=\"InstallerProhibitsElevation\" xml:space=\"preserve\">\n    <value>Le programme d’installation ne peut pas être exécuté à partir d’un contexte d’administrateur.</value>\n  </data>\n  <data name=\"ModifiedPathRequiresShellRestart\" xml:space=\"preserve\">\n    <value>Variable d’environnement de chemin modifiée ; redémarrez votre interpréteur de commandes pour utiliser la nouvelle valeur.</value>\n  </data>\n  <data name=\"ProductCodeArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtres à l’aide du code de produit</value>\n  </data>\n  <data name=\"PortableRegistryCollisionOverridden\" xml:space=\"preserve\">\n    <value>Un package portable portant le même nom mais provenant d’une source différente existe déjà ; poursuite en raison de --force</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"ReparsePointsNotSupportedError\" xml:space=\"preserve\">\n    <value>Le volume ne prend pas en charge les points d’analyse</value>\n  </data>\n  <data name=\"ReservedFilenameError\" xml:space=\"preserve\">\n    <value>Le nom de fichier spécifié n’est pas un nom de fichier valide</value>\n  </data>\n  <data name=\"OverwritingExistingFileAtMessage\" xml:space=\"preserve\">\n    <value>Remplacement du fichier existant : {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed to inform the user that an existing file is being overwritten. {0} is a placeholder replaced by the file system path.</comment>\n  </data>\n  <data name=\"NoPackageSelectionArgumentProvided\" xml:space=\"preserve\">\n    <value>Aucun argument de sélection de package n’a été fourni ; consultez l’aide pour plus d’informations sur la recherche d’un package.</value>\n  </data>\n  <data name=\"PortableAliasAdded\" xml:space=\"preserve\">\n    <value>Alias de ligne de commande ajouté :</value>\n  </data>\n  <data name=\"PortableLinksMachine\" xml:space=\"preserve\">\n    <value>Répertoire des liens portables (ordinateur)</value>\n  </data>\n  <data name=\"PortableLinksUser\" xml:space=\"preserve\">\n    <value>Répertoire des liens portables (utilisateur)</value>\n  </data>\n  <data name=\"PortableRootUser\" xml:space=\"preserve\">\n    <value>Racine de package portable (utilisateur)</value>\n  </data>\n  <data name=\"PortableRoot\" xml:space=\"preserve\">\n    <value>Racine du package portable</value>\n  </data>\n  <data name=\"PortableRoot86\" xml:space=\"preserve\">\n    <value>Racine de package portable (x86)</value>\n  </data>\n  <data name=\"PortableInstallFailed\" xml:space=\"preserve\">\n    <value>Échec de l’installation portable ; Nettoyage en cours...</value>\n  </data>\n  <data name=\"PortableHashMismatchOverridden\" xml:space=\"preserve\">\n    <value>Le package Portable a été modifié ; continuer en raison de --force</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"PortableHashMismatchOverrideRequired\" xml:space=\"preserve\">\n    <value>Impossible de supprimer le package Portable, car il a été modifié ; pour remplacer cette vérification, utilisez : --force</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"FilesRemainInInstallDirectory\" xml:space=\"preserve\">\n    <value>Les fichiers restent dans le répertoire d’installation : {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when files remain in install directory. {0} is a placeholder replaced by the directory path.</comment>\n  </data>\n  <data name=\"PurgeInstallDirectory\" xml:space=\"preserve\">\n    <value>Purge du répertoire d’installation...</value>\n  </data>\n  <data name=\"UnableToPurgeInstallDirectory\" xml:space=\"preserve\">\n    <value>Impossible de vider le répertoire d’installation, car il n’a pas été créé par WinGet</value>\n  </data>\n  <data name=\"RelatedLink\" xml:space=\"preserve\">\n    <value>Lien associé</value>\n  </data>\n  <data name=\"ShowLabelDocumentation\" xml:space=\"preserve\">\n    <value>Documentation :</value>\n  </data>\n  <data name=\"Notes\" xml:space=\"preserve\">\n    <value>Remarques : {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for installation notes. {0} is a placeholder replaced by installation notes.</comment>\n  </data>\n  <data name=\"ShowLabelInstallationNotes\" xml:space=\"preserve\">\n    <value>Notes d’installation :</value>\n  </data>\n  <data name=\"UnsupportedArgument\" xml:space=\"preserve\">\n    <value>Un argument fourni n’est pas pris en charge pour ce package</value>\n  </data>\n  <data name=\"ExtractArchiveFailed\" xml:space=\"preserve\">\n    <value>Échec de l’extraction du contenu de l’archive</value>\n  </data>\n  <data name=\"NestedInstallerNotFound\" xml:space=\"preserve\">\n    <value>Le fichier d’installation imbriqué n’existe pas. Vérifiez que le chemin d’accès relatif spécifié du programme d’installation imbriqué correspond à : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when nested installer file does not exist. {0} is a placeholder replaced by the nested installer file path.</comment>\n  </data>\n  <data name=\"InvalidPathToNestedInstaller\" xml:space=\"preserve\">\n    <value>Chemin de fichier relatif non valide pour le programme d’installation imbriqué ; le chemin pointe vers un emplacement en dehors du répertoire d’installation</value>\n  </data>\n  <data name=\"NestedInstallerNotSpecified\" xml:space=\"preserve\">\n    <value>Aucun programme d’installation imbriqué spécifié pour ce package</value>\n  </data>\n  <data name=\"MultipleUnsupportedNestedInstallersSpecified\" xml:space=\"preserve\">\n    <value>Un seul programme d’installation imbriqué peut être spécifié pour un programme d’installation d’archive, sauf s’il s’agit d’un programme d’installation imbriqué portable ou de police</value>\n  </data>\n  <data name=\"IncompatibleArgumentsProvided\" xml:space=\"preserve\">\n    <value>Arguments de ligne de commande fournis incompatibles</value>\n  </data>\n  <data name=\"UpgradeArgumentDescription\" xml:space=\"preserve\">\n    <value>Répertorie uniquement les packages pour lesquels une mise à niveau est disponible</value>\n  </data>\n  <data name=\"UpgradeAvailableForPinned\" xml:space=\"preserve\">\n    <value>Les packages suivants ont une mise à niveau disponible, mais nécessitent un ciblage explicite pour la mise à niveau :</value>\n    <comment>\"require explicit targeting for upgrade\" means that the package will not be upgraded with all others unless an extra flag is added, or the package is mentioned explicitly</comment>\n  </data>\n  <data name=\"Downloading\" xml:space=\"preserve\">\n    <value>Téléchargement en cours</value>\n    <comment>Label displayed while downloading an application installer.</comment>\n  </data>\n  <data name=\"NestedInstallerNotSupported\" xml:space=\"preserve\">\n    <value>Le type de programme d’installation imbriqué n’est pas pris en charge</value>\n  </data>\n  <data name=\"InstallerAbortsTerminal\" xml:space=\"preserve\">\n    <value>Ce programme d’installation est connu pour redémarrer le terminal ou l’interpréteur de commandes</value>\n  </data>\n  <data name=\"InstallerRequiresInstallLocation\" xml:space=\"preserve\">\n    <value>Ce package nécessite un emplacement d’installation</value>\n  </data>\n  <data name=\"InstallersAbortTerminal\" xml:space=\"preserve\">\n    <value>Les programmes d’installation suivants sont connus pour redémarrer le terminal ou l’interpréteur de commandes :</value>\n  </data>\n  <data name=\"InstallersRequireInstallLocation\" xml:space=\"preserve\">\n    <value>Les programmes d’installation suivants nécessitent un emplacement d’installation :</value>\n  </data>\n  <data name=\"PromptForInstallRoot\" xml:space=\"preserve\">\n    <value>Spécifier la racine d’installation :</value>\n  </data>\n  <data name=\"PromptToProceed\" xml:space=\"preserve\">\n    <value>Voulez-vous continuer ?</value>\n  </data>\n  <data name=\"ReportIdentityForAgreements\" xml:space=\"preserve\">\n    <value>Contrats pour</value>\n    <comment>This will be followed by a package name, and then a list of license agreements</comment>\n  </data>\n  <data name=\"InstallLocationNotProvided\" xml:space=\"preserve\">\n    <value>L’emplacement d’installation est requis par le package, mais il n’a pas été fourni</value>\n  </data>\n  <data name=\"DisableInteractivityArgumentDescription\" xml:space=\"preserve\">\n    <value>Désactiver les invites interactives</value>\n    <comment>Description for a command line argument, shown next to it in the help</comment>\n  </data>\n  <data name=\"ConvertInstallFlowToUpgrade\" xml:space=\"preserve\">\n    <value>Un package existant a déjà été installé. Tentative de mise à niveau du package installé...</value>\n  </data>\n  <data name=\"ForceArgumentDescription\" xml:space=\"preserve\">\n    <value>Exécuter directement la commande et continuer avec des problèmes non liés à la sécurité</value>\n    <comment>Description for a command line argument, shown next to it in the help</comment>\n  </data>\n  <data name=\"PortablePackageAlreadyExists\" xml:space=\"preserve\">\n    <value>Un package portable d’une autre source existe déjà</value>\n  </data>\n  <data name=\"ExtractArchiveSucceeded\" xml:space=\"preserve\">\n    <value>Extraction de l’archive réussie</value>\n  </data>\n  <data name=\"ExtractingArchive\" xml:space=\"preserve\">\n    <value>Extraction des archives...</value>\n  </data>\n  <data name=\"ArchiveFailedMalwareScan\" xml:space=\"preserve\">\n    <value>L’analyse de l’archive a détecté un programme malveillant. Pour remplacer cette vérification, utilisez ---ignore-local-archive-malware-scan</value>\n    <comment>{Locked=\"--ignore-local-archive-malware-scan\"}</comment>\n  </data>\n  <data name=\"ArchiveFailedMalwareScanOverridden\" xml:space=\"preserve\">\n    <value>L’analyse de l’archive a détecté un programme malveillant. Continuer en raison de ---ignore-local-archive-malware-scan</value>\n    <comment>{Locked=\"--ignore-local-archive-malware-scan\"}</comment>\n  </data>\n  <data name=\"NoUpgradeArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignore la mise à niveau si une version installée existe déjà</value>\n  </data>\n  <data name=\"PackageAlreadyInstalled\" xml:space=\"preserve\">\n    <value>Une version de package est déjà installée. Installation annulée.</value>\n  </data>\n  <data name=\"EnableAdminSettingFailed\" xml:space=\"preserve\">\n    <value>Impossible d’activer {0}. Ce paramètre est contrôlé par la stratégie. Pour plus d’informations, contactez votre administrateur système.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"DisableAdminSettingFailed\" xml:space=\"preserve\">\n    <value>Impossible de désactiver {0}. Ce paramètre est contrôlé par la stratégie. Pour plus d’informations, contactez votre administrateur système.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"PinAddCommandLongDescription\" xml:space=\"preserve\">\n    <value>Ajoutez une nouvelle épingle. Une épingle peut limiter la mise à niveau par le Gestionnaire de package Windows d’un package vers des plages de versions spécifiques, ou l’empêcher de mettre à niveau le package. Un package épinglé peut toujours être mis à niveau seul et être mis à niveau depuis l’extérieur du Gestionnaire de package Windows. Par défaut, un package épinglé peut être mis à niveau en le mentionnant explicitement dans la commande « upgrade » ou en ajoutant l’indicateur « include-pinned » à« winget upgrade all ».</value>\n    <comment>{Locked{\"'upgrade'\"} Locked{\"--include-pinned\"} Locked{\"winget upgrade --all\"}</comment>\n  </data>\n  <data name=\"PinAddCommandShortDescription\" xml:space=\"preserve\">\n    <value>Ajouter une nouvelle broche</value>\n  </data>\n  <data name=\"PinCommandLongDescription\" xml:space=\"preserve\">\n    <value>Gérez les épingles de package avec les sous-commandes. Une épingle peut limiter la mise à niveau par le Gestionnaire de package Windows d’un package vers des plages de versions spécifiques, ou l’empêcher de mettre à niveau le package. Un package épinglé peut toujours être mis à niveau seul et être mis à niveau depuis l’extérieur du Gestionnaire de package Windows.</value>\n  </data>\n  <data name=\"PinCommandShortDescription\" xml:space=\"preserve\">\n    <value>Gérer les broches de package</value>\n  </data>\n  <data name=\"PinListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Répertoriez toutes les broches actuelles ou les détails complets d’un code confidentiel spécifique.</value>\n  </data>\n  <data name=\"PinListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Répertorier les épingles actuelles</value>\n  </data>\n  <data name=\"PinRemoveCommandLongDescription\" xml:space=\"preserve\">\n    <value>Supprimez un code confidentiel de package spécifique.</value>\n  </data>\n  <data name=\"PinRemoveCommandShortDescription\" xml:space=\"preserve\">\n    <value>Supprimer une broche de package</value>\n  </data>\n  <data name=\"PinResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>Réinitialisez toutes les broches existantes.</value>\n  </data>\n  <data name=\"PinResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>Réinitialiser les codes confidentiels ?</value>\n  </data>\n  <data name=\"GatedVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>Version à laquelle épingler le package. Le caractère générique « * » peut être utilisé comme dernière partie de version</value>\n  </data>\n  <data name=\"PinAddBlockingArgumentDescription\" xml:space=\"preserve\">\n    <value>Bloquer la mise à niveau jusqu’à ce que l’épingle soit supprimée, empêchant ainsi les arguments de remplacement</value>\n  </data>\n  <data name=\"PinInstalledArgumentDescription\" xml:space=\"preserve\">\n    <value>Épingler une version installée spécifique</value>\n  </data>\n  <data name=\"PinInstalledSource\" xml:space=\"preserve\">\n    <value>Installé</value>\n    <comment>Value used in a table to indicate that a package comes from the list of packages installed in the machine</comment>\n  </data>\n  <data name=\"SettingsExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Exporter les paramètres au format JSON</value>\n  </data>\n  <data name=\"SettingsExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Exporter les paramètres</value>\n  </data>\n  <data name=\"UserSettings\" xml:space=\"preserve\">\n    <value>Paramètres utilisateurs</value>\n    <comment>Label displayed for the file containing the user settings.</comment>\n  </data>\n  <data name=\"SettingsWarningUsingDefault\" xml:space=\"preserve\">\n    <value>Impossible de charger le fichier de paramètres. Utilisation des valeurs par défaut.</value>\n  </data>\n  <data name=\"InstalledScopeArgumentDescription\" xml:space=\"preserve\">\n    <value>Sélectionner le filtre d’étendue de package installé (user ou machine)</value>\n    <comment>{Locked=\"user\",\"machine\"} This argument allows the user to select installed packages for just the user or for the entire machine.</comment>\n  </data>\n  <data name=\"PinAdded\" xml:space=\"preserve\">\n    <value>Épingle ajoutée avec succès</value>\n  </data>\n  <data name=\"PinAlreadyExists\" xml:space=\"preserve\">\n    <value>Il existe déjà une épingle pour le package {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that will be replaced by a package name. The message is shown when attempting to add a pin for a package that is already pinned.</comment>\n  </data>\n  <data name=\"PinExistsOverwriting\" xml:space=\"preserve\">\n    <value>Une épingle existe déjà pour le package {0}. Remplacement en raison de l’argument --force.</value>\n    <comment>{Locked=\"--force\"}{Locked=\"--force\",\"{0}\"} {0} is a placeholder that will be replaced by a package name.</comment>\n  </data>\n  <data name=\"PinExistsUseForceArg\" xml:space=\"preserve\">\n    <value>Un code confidentiel existe déjà pour le package {0}. Utilisez l’argument --force pour le remplacer.</value>\n    <comment>{Locked=\"--force\",\"{0}\"} {0} is a placeholder that will be replaced by a package name.</comment>\n  </data>\n  <data name=\"PinResettingAll\" xml:space=\"preserve\">\n    <value>Réinitialisation de toutes les épingles actives.</value>\n  </data>\n  <data name=\"PinResetUseForceArg\" xml:space=\"preserve\">\n    <value>Utilisez l’argument --force pour réinitialiser toutes les épingles. Les épingles suivantes seront supprimées :</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"PinType\" xml:space=\"preserve\">\n    <value>Type d’épingle</value>\n  </data>\n  <data name=\"PinDoesNotExist\" xml:space=\"preserve\">\n    <value>Il n’existe pas d’épingle pour le package {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that will be replaced by a package name. The message is shown when attempting to delete a pin for a package that is not pinned.</comment>\n  </data>\n  <data name=\"PinNoPinsExist\" xml:space=\"preserve\">\n    <value>Aucune épingle n’est configurée.</value>\n    <comment>Shown when listing or modifying existing pins if there are none.</comment>\n  </data>\n  <data name=\"PinResetSuccessful\" xml:space=\"preserve\">\n    <value>Réinitialisé correcte des épingles</value>\n    <comment>Shown after resetting (deleting) all the pins</comment>\n  </data>\n  <data name=\"PinCannotOpenIndex\" xml:space=\"preserve\">\n    <value>Impossible d’ouvrir la base de données épinglée.</value>\n    <comment>Error message for when we cannot open the database containing package pins.</comment>\n  </data>\n  <data name=\"ArgumentForSinglePackageProvidedWithMultipleQueries\" xml:space=\"preserve\">\n    <value>Un argument fourni ne peut être utilisé que pour un seul package</value>\n  </data>\n  <data name=\"MultipleExclusiveArgumentsProvided\" xml:space=\"preserve\">\n    <value>Plusieurs arguments mutuellement exclusifs ont été fournis : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message shown when mutually incompatible command line arguments are used. {0} is a placeholder replaced by the arguments that cannot be specified together</comment>\n  </data>\n  <data name=\"DependencyArgumentMissing\" xml:space=\"preserve\">\n    <value>L’argument {0} ne peut être utilisé qu’avec {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message shown when having an argument needs another to be present, but that is missing. {0} and {1} are replaced by the arguments. For example \"Argument --include-unknown can only be used with --upgrade\"</comment>\n  </data>\n  <data name=\"StateDisabled\" xml:space=\"preserve\">\n    <value>Désactivé</value>\n    <comment>As in enabled/disabled</comment>\n  </data>\n  <data name=\"StateEnabled\" xml:space=\"preserve\">\n    <value>Activé</value>\n    <comment>As in enabled/disabled</comment>\n  </data>\n  <data name=\"StateHeader\" xml:space=\"preserve\">\n    <value>État</value>\n    <comment>Header for a table listing the state (enabled/disabled) of Group Policies and Settings</comment>\n  </data>\n  <data name=\"MultiQueryArgumentDescription\" xml:space=\"preserve\">\n    <value>Requête utilisée pour rechercher un package</value>\n  </data>\n  <data name=\"MultiQueryPackageNotFound\" xml:space=\"preserve\">\n    <value>Le package « {0} » est introuvable</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches returns no results. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"MultiQuerySearchFoundMultiple\" xml:space=\"preserve\">\n    <value>Plusieurs packages trouvés pour : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches returns more than one result. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"MultiQuerySearchFailed\" xml:space=\"preserve\">\n    <value>Échec de la recherche pour : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches fails. This message is for generic failures, we have more specific messages for when the search returns no results, or when it returns more than one result. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"UpgradeBlockedByPinCount\" xml:space=\"preserve\">\n    <value>{0} package(s) ont une épingle qui doit être supprimée avant la mise à niveau</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by an integer number of packages with pins that prevent upgrade</comment>\n  </data>\n  <data name=\"UpgradeBlockedByManifest\" xml:space=\"preserve\">\n    <value>Impossible de mettre à niveau le package à l’aide de Winget. Utilisez la méthode fournie par l’éditeur pour mettre à niveau ce package.</value>\n  </data>\n  <data name=\"IncludePinnedArgumentDescription\" xml:space=\"preserve\">\n    <value>Mettre à niveau les packages même s’ils ont une épingle non bloquante</value>\n  </data>\n  <data name=\"IncludePinnedInListArgumentDescription\" xml:space=\"preserve\">\n    <value>Répertorie les packages même s’ils ont un code confidentiel qui empêche la mise à niveau. Ne peut être utilisé qu’avec l’argument --upgrade-available</value>\n    <comment>{Locked=\"--upgrade-available\"}</comment>\n  </data>\n  <data name=\"PinRemovedSuccessfully\" xml:space=\"preserve\">\n    <value>L’épingle a été supprimée avec succès</value>\n  </data>\n  <data name=\"UpgradeIsPinned\" xml:space=\"preserve\">\n    <value>Une version plus récente a été trouvée, mais le package a une épingle qui empêche sa mise à niveau.</value>\n  </data>\n  <data name=\"PackageIsPinned\" xml:space=\"preserve\">\n    <value>Le package est épinglé et ne peut pas être mis à niveau. Utilisez la commande « winget pin » pour afficher et modifier des épingles. Certains types d’épingle peuvent être ignorés avec l’argument --include-pinned.</value>\n    <comment>{Locked=\"winget pin\",\"--include-pinned\"} Error shown when we block an upgrade due to the package being pinned</comment>\n  </data>\n  <data name=\"UpgradePinnedByUserCount\" xml:space=\"preserve\">\n    <value>{0} package(s) ont des épingles qui empêchent la mise à niveau. Utilisez la commande « winget pin » pour afficher et modifier les épingles. L’utilisation de l’argument --include-pinned peut afficher plus de résultats.</value>\n    <comment>{Locked=\"winget pin\",\"--include-pinned\"} {0} is a placeholder replaced by an integer number of packages</comment>\n  </data>\n  <data name=\"ConfigureCommandLongDescription\" xml:space=\"preserve\">\n    <value>Garantit que le système correspond à l’état souhaité comme décrit par la configuration fournie. Peut télécharger/exécuter des processeurs pour atteindre l’état souhaité. La configuration et les processeurs doivent être vérifiés pour s’assurer qu’ils sont dignes de confiance avant de les appliquer.</value>\n  </data>\n  <data name=\"ConfigureCommandShortDescription\" xml:space=\"preserve\">\n    <value>Configure le système dans un état souhaité</value>\n  </data>\n  <data name=\"ConfigureShowCommandLongDescription\" xml:space=\"preserve\">\n    <value>Affiche les détails de la configuration fournie. Par défaut, le système ne sera pas modifié, mais certaines options entraîneront le téléchargement et/ou le chargement des fichiers.</value>\n  </data>\n  <data name=\"ConfigureShowCommandShortDescription\" xml:space=\"preserve\">\n    <value>Affiche les détails d’une configuration</value>\n  </data>\n  <data name=\"ConfigureTestCommandLongDescription\" xml:space=\"preserve\">\n    <value>Vérifie que le système correspond à l’état souhaité comme décrit par la configuration fournie. Peut télécharger/exécuter des processeurs pour tester l’état souhaité. La configuration et les processeurs doivent être vérifiés pour s’assurer qu’ils sont dignes de confiance avant de les exécuter.</value>\n  </data>\n  <data name=\"ConfigureTestCommandShortDescription\" xml:space=\"preserve\">\n    <value>Vérifie l’état souhaité du système</value>\n  </data>\n  <data name=\"ConfigureValidateCommandLongDescription\" xml:space=\"preserve\">\n    <value>Valide l’exactitude d’un fichier de configuration.</value>\n  </data>\n  <data name=\"ConfigureValidateCommandShortDescription\" xml:space=\"preserve\">\n    <value>Valide un fichier de configuration</value>\n  </data>\n  <data name=\"ConfigurationFieldInvalidType\" xml:space=\"preserve\">\n    <value>Le type du champ '{0}' dans le fichier de configuration est incorrect.</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the field name from the file.</comment>\n  </data>\n  <data name=\"ConfigurationFileArgumentDescription\" xml:space=\"preserve\">\n    <value>Chemin d’accès au fichier de configuration</value>\n  </data>\n  <data name=\"ConfigurationFileInvalid\" xml:space=\"preserve\">\n    <value>Le fichier de configuration n’est pas valide.</value>\n  </data>\n  <data name=\"ConfigurationFileVersionUnknown\" xml:space=\"preserve\">\n    <value>La version du fichier de configuration {0} est inconnue.</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the version of the configuration file.</comment>\n  </data>\n  <data name=\"ConfigurationAcceptWarningArgumentDescription\" xml:space=\"preserve\">\n    <value>Accepte l’avertissement de configuration, empêchant une invite interactive</value>\n  </data>\n  <data name=\"ConfigurationApply\" xml:space=\"preserve\">\n    <value>Appliquer</value>\n    <comment>Indicates that this item is used to write state</comment>\n  </data>\n  <data name=\"ConfigurationAssert\" xml:space=\"preserve\">\n    <value>Affirmer</value>\n    <comment>Indicates that this item is used to check/assert the state rather than write to it</comment>\n  </data>\n  <data name=\"ConfigurationDependencies\" xml:space=\"preserve\">\n    <value>Dépendances :{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying a list of dependencies. {0} is replaced with a space separated list of identifiers referencing other items.</comment>\n  </data>\n  <data name=\"ConfigurationFailedToApply\" xml:space=\"preserve\">\n    <value>Une partie de la configuration n’a pas été appliquée correctement.</value>\n  </data>\n  <data name=\"ConfigurationFailedToGetDetails\" xml:space=\"preserve\">\n    <value>Échec de l’obtention d’informations détaillées sur la configuration.</value>\n  </data>\n  <data name=\"ConfigurationInform\" xml:space=\"preserve\">\n    <value>informer</value>\n    <comment>Indicates that this item is used to retrieve values for future use rather than writing them</comment>\n  </data>\n  <data name=\"ConfigurationLocal\" xml:space=\"preserve\">\n    <value>Local</value>\n    <comment>Used to indicate that the item is present on the device.</comment>\n  </data>\n  <data name=\"ConfigurationModuleNameOnly\" xml:space=\"preserve\">\n    <value>Module : {0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying a module name. {0} is replaced with the name of the module from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationModuleWithDetails\" xml:space=\"preserve\">\n    <value>Module : {0} par {1} [{2}]</value>\n    <comment>{Locked=\"{0}\",\"{1}\",\"{2}\"} Label displaying module information. {0} is replaced by the module name. {1} is replaced by the module author. {2} is replaced by a string indicating the source of the module.</comment>\n  </data>\n  <data name=\"ConfigurationSettings\" xml:space=\"preserve\">\n    <value>Paramètres :</value>\n    <comment>Label for the values that are used as inputs for this item when applying state</comment>\n  </data>\n  <data name=\"ConfigurationSuccessfullyApplied\" xml:space=\"preserve\">\n    <value>La configuration a été correctement appliquée.</value>\n  </data>\n  <data name=\"ConfigurationUnitSuccessfullyApplied\" xml:space=\"preserve\">\n    <value>L'unité a bien été appliquée.</value>\n  </data>\n  <data name=\"ConfigurationWaitingOnAnother\" xml:space=\"preserve\">\n    <value>Une autre configuration est appliquée au système. Cette configuration se poursuivra dès que possible...</value>\n  </data>\n  <data name=\"ConfigurationWarning\" xml:space=\"preserve\">\n    <value>Vous êtes responsable de la compréhension des paramètres de configuration que vous choisissez d'exécuter. Microsoft n'est pas responsable du fichier de configuration que vous avez créé ou importé. Cette configuration peut modifier les paramètres de Windows, installer des logiciels, modifier les paramètres des logiciels (y compris les paramètres de sécurité) et accepter les accords d'utilisation des packages et services tiers en votre nom. En exécutant ce fichier de configuration, vous reconnaissez que vous comprenez et acceptez ces ressources et paramètres. Toutes les applications installées vous sont concédées sous licence par leurs propriétaires. Microsoft n'est pas responsable des packages ou services tiers et n'accorde aucune licence à ceux-ci.</value>\n    <comment>Legal approved. Do not change without approval.</comment>\n  </data>\n  <data name=\"ConfigurationWarningPromptApply\" xml:space=\"preserve\">\n    <value>Avez-vous examiné la configuration et souhaitez-vous continuer à l’appliquer au système ?</value>\n    <comment>PM approved.</comment>\n  </data>\n  <data name=\"ConfigurationFileEmpty\" xml:space=\"preserve\">\n    <value>La configuration est vide.</value>\n  </data>\n  <data name=\"WindowsFeatureNotFound\" xml:space=\"preserve\">\n    <value>La fonctionnalité [{0}] est introuvable.</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Windows feature was not found on the system.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeatureOverrideRequired\" xml:space=\"preserve\">\n    <value>Échec de l’activation des dépendances de fonctionnalité Windows. Pour poursuivre l’installation, utilisez '--force'.</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"RebootRequiredToEnableWindowsFeatureOverrideRequired\" xml:space=\"preserve\">\n    <value>Redémarrage requis pour activer entièrement la ou les fonctionnalités Windows; pour remplacer cette vérification, utilisez « --force ».</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeatureOverridden\" xml:space=\"preserve\">\n    <value>Échec de l’activation des dépendances de fonctionnalité Windows ; continuer en raison de --force</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.\n{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"EnablingWindowsFeature\" xml:space=\"preserve\">\n    <value>Activation [{0}]...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to the user regarding which Windows Feature is being enabled.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeature\" xml:space=\"preserve\">\n    <value>Échec de l’activation [{0}] de la fonctionnalité : {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"}  An error when enabling a Windows Feature. {0} is a placeholder for the name of the Windows Feature.\n{1} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"RebootRequiredToEnableWindowsFeatureOverridden\" xml:space=\"preserve\">\n    <value>Redémarrage requis pour activer entièrement la ou les fonctionnalités Windows; continuer en raison de --force</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.</comment>\n  </data>\n  <data name=\"InstallWaitingOnAnother\" xml:space=\"preserve\">\n    <value>En attente de la fin d’une autre installation/désinstallation...</value>\n  </data>\n  <data name=\"PinVersion\" xml:space=\"preserve\">\n    <value>Version épinglée</value>\n    <comment>Table header for the version to which a package is pinned; meaning it should not update from that version.</comment>\n  </data>\n  <data name=\"ConfigurationDescriptionWasTruncated\" xml:space=\"preserve\">\n    <value>&lt;Consultez le fichier journal pour obtenir des détails supplémentaires&gt;</value>\n    <comment>The brackets are intended to make the value stand out from other text which it will follow. Any locale appropriate mechanism that achieves this is acceptable.</comment>\n  </data>\n  <data name=\"ConfigurationGettingDetails\" xml:space=\"preserve\">\n    <value>Récupération des détails de la configuration</value>\n  </data>\n  <data name=\"ConfigurationInitializing\" xml:space=\"preserve\">\n    <value>Initialisation du système de configuration</value>\n  </data>\n  <data name=\"ConfigurationReadingConfigFile\" xml:space=\"preserve\">\n    <value>Lecture du fichier de configuration</value>\n  </data>\n  <data name=\"ConfigurationUnitAssertHadNegativeResult\" xml:space=\"preserve\">\n    <value>Le système n’est pas dans l’état souhaité déclaré par la configuration.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailed\" xml:space=\"preserve\">\n    <value>Cette unité de configuration a échoué pour une raison inconnue : {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedConfigSet\" xml:space=\"preserve\">\n    <value>Échec de l’unité de configuration en raison de la configuration : {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringGet\" xml:space=\"preserve\">\n    <value>Échec de l’unité de configuration lors de la tentative d’obtention de l’état actuel du système.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringSet\" xml:space=\"preserve\">\n    <value>Échec de l’unité de configuration lors de la tentative d’application de l’état souhaité.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringTest\" xml:space=\"preserve\">\n    <value>Échec de l’unité de configuration lors de la tentative de test de l’état actuel du système.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedInternal\" xml:space=\"preserve\">\n    <value>Échec de l’unité de configuration en raison d’une erreur interne : {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedPrecondition\" xml:space=\"preserve\">\n    <value>L’unité de configuration a échoué car une condition préalable n’est pas valide : {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedSystemState\" xml:space=\"preserve\">\n    <value>Échec de l’unité de configuration en raison de l’état du système : {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedUnitProcessing\" xml:space=\"preserve\">\n    <value>Échec de l’unité de configuration lors de la tentative d’exécution : {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitHasDuplicateIdentifier\" xml:space=\"preserve\">\n    <value>La configuration contient l’identificateur '{0}' plusieurs fois.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by the identifier string from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationUnitHasMissingDependency\" xml:space=\"preserve\">\n    <value>La dépendance «{0}» est introuvable dans la configuration.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by the identifier string from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationUnitManuallySkipped\" xml:space=\"preserve\">\n    <value>Cette unité de configuration a été ignorée manuellement.</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleConflict\" xml:space=\"preserve\">\n    <value>Le module de l’unité de configuration est disponible dans plusieurs emplacements avec la même version.</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleImportFailed\" xml:space=\"preserve\">\n    <value>Échec du chargement du module pour l’unité de configuration.</value>\n  </data>\n  <data name=\"ConfigurationUnitMultipleMatches\" xml:space=\"preserve\">\n    <value>Plusieurs correspondances ont été trouvées pour l’unité de configuration ; spécifiez le module pour sélectionner le module approprié.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotFound\" xml:space=\"preserve\">\n    <value>L’unité de configuration est introuvable.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotFoundInModule\" xml:space=\"preserve\">\n    <value>L’unité de configuration n’était pas dans le module comme prévu.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotRunDueToDependency\" xml:space=\"preserve\">\n    <value>Cette unité de configuration n’a pas été exécutée car une dépendance a échoué ou n’a pas été exécutée.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotRunDueToFailedAssert\" xml:space=\"preserve\">\n    <value>Cette unité de configuration n’a pas été exécutée car une assertion a échoué ou a la valeur false.</value>\n  </data>\n  <data name=\"ConfigurationUnitReturnedInvalidResult\" xml:space=\"preserve\">\n    <value>L’unité de configuration a retourné un résultat inattendu lors de l’exécution.</value>\n  </data>\n  <data name=\"ConfigurationUnitSkipped\" xml:space=\"preserve\">\n    <value>Cette unité de configuration n’a pas été exécutée pour une raison inconnue : {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationFieldInvalidValue\" xml:space=\"preserve\">\n    <value>La valeur du champ '{0}' n’est pas valide : {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} An error in reading a configuration file. {0} is a placeholder replaced by the field name from the file. {1} is a placeholder for the invalid value.</comment>\n  </data>\n  <data name=\"ConfigurationFieldMissing\" xml:space=\"preserve\">\n    <value>Le champ « {0} » est manquant ou vide.</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the expected field name from the file.</comment>\n  </data>\n  <data name=\"SeeLineAndColumn\" xml:space=\"preserve\">\n    <value>Voir {0} de ligne, {1} de colonne dans le fichier.</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Indicates the file location of the error, {0} and {1} are placeholders for numbers of the line and column, respectively.</comment>\n  </data>\n  <data name=\"CancellingOperation\" xml:space=\"preserve\">\n    <value>Annulation de l’opération</value>\n  </data>\n  <data name=\"InstallStubPackageDescription\" xml:space=\"preserve\">\n    <value>Installer le package stub pour AppInstaller</value>\n  </data>\n  <data name=\"InstallFullPackageDescription\" xml:space=\"preserve\">\n    <value>Installer le package complet pour AppInstaller</value>\n  </data>\n  <data name=\"ExtendedFeaturesEnableMessage\" xml:space=\"preserve\">\n    <value>Activer les fonctionnalités étendues. Nécessite l’accès au store.</value>\n  </data>\n  <data name=\"ExtendedFeaturesEnableArgumentError\" xml:space=\"preserve\">\n    <value>L’option '--enable' et '--disable' ne peuvent pas être utilisées avec d’autres arguments.</value>\n    <comment>{Locked=\"--enable\", \"--disable\"}</comment>\n  </data>\n  <data name=\"ExtendedFeaturesEnablingMessage\" xml:space=\"preserve\">\n    <value>Activation des fonctionnalités étendues. Nécessite l’accès au store.</value>\n  </data>\n  <data name=\"ExtendedFeaturesNotEnabledMessage\" xml:space=\"preserve\">\n    <value>Les fonctionnalités étendues ne sont pas activées. Exécutez 'winget configure --enable' pour les activer.</value>\n    <comment>{Locked=\"winget configure --enable\"}</comment>\n  </data>\n  <data name=\"ExtendedFeaturesEnabledMessage\" xml:space=\"preserve\">\n    <value>Les fonctionnalités étendues sont activées.</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisableMessage\" xml:space=\"preserve\">\n    <value>Désactiver les fonctionnalités étendues. Nécessite l’accès au store.</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisablingMessage\" xml:space=\"preserve\">\n    <value>Désactivation des fonctionnalités étendues. Nécessite l’accès au store.</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisabledMessage\" xml:space=\"preserve\">\n    <value>Les fonctionnalités étendues sont désactivées.</value>\n  </data>\n  <data name=\"SkipDependenciesArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignore le traitement des dépendances de package et des fonctionnalités Windows</value>\n  </data>\n  <data name=\"DependenciesSkippedMessage\" xml:space=\"preserve\">\n    <value>Dépendances ignorées.</value>\n  </data>\n  <data name=\"FailedToRefreshPathWarning\" xml:space=\"preserve\">\n    <value>Échec de l’actualisation de la variable PATH pour le processus. Les installations suivantes qui dépendent des modifications apportées à la variable PATH risquent d’échouer.</value>\n    <comment>{Locked=\"PATH\"}</comment>\n  </data>\n  <data name=\"ConfigurationFailedToTest\" xml:space=\"preserve\">\n    <value>Certaines unités de configuration ont échoué lors du test de leur état.</value>\n  </data>\n  <data name=\"ConfigurationInDesiredState\" xml:space=\"preserve\">\n    <value>Le système est dans l’état de configuration décrit.</value>\n  </data>\n  <data name=\"ConfigurationNoTestRun\" xml:space=\"preserve\">\n    <value>L’état de configuration n’a pas été testé.</value>\n  </data>\n  <data name=\"ConfigurationNotInDesiredState\" xml:space=\"preserve\">\n    <value>Le système n’est pas dans l’état de configuration décrit.</value>\n  </data>\n  <data name=\"ConfigurationUnexpectedTestResult\" xml:space=\"preserve\">\n    <value>Résultat de test inattendu : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message. {0} will be replaced with the unexpected value (a number).</comment>\n  </data>\n  <data name=\"ConfigurationWarningPromptTest\" xml:space=\"preserve\">\n    <value>Avez-vous examiné la configuration et souhaitez-vous continuer à la vérifier sur le système ?</value>\n  </data>\n  <data name=\"ConfigurationFileInvalidYAML\" xml:space=\"preserve\">\n    <value>Le fichier de configuration n’est pas un fichier YAML valide.</value>\n    <comment>{Locked=\"YAML\"} YAML is a file format name.</comment>\n  </data>\n  <data name=\"ConfigurationUnitIsPartOfDependencyCycle\" xml:space=\"preserve\">\n    <value>Cette unité de configuration fait partie d’un cycle de dépendance.</value>\n  </data>\n  <data name=\"ConfigurationValidationFoundNoIssues\" xml:space=\"preserve\">\n    <value>La validation n’a détecté aucun problème.</value>\n  </data>\n  <data name=\"ConfigurationUnitNeedsPrereleaseWarning\" xml:space=\"preserve\">\n    <value>L’unité de configuration n’est disponible qu’en version préliminaire, mais elle n’est pas marquée de cette façon dans la configuration. Ajoutez 'allowPrerelease: true' au 'directives'.</value>\n    <comment>{Locked=\"allowPrerelease: true\",\"directives\"} These are values in the configuration file that are not localized.</comment>\n  </data>\n  <data name=\"ConfigurationUnitNotInCatalogWarning\" xml:space=\"preserve\">\n    <value>L’unité de configuration a été trouvée localement, mais elle est introuvable dans un catalogue configuré. Vérifiez qu’il est présent sur n’importe quel système avant d’appliquer la configuration.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotPublicWarning\" xml:space=\"preserve\">\n    <value>L’unité de configuration n’est pas disponible publiquement ; vérifiez que toute personne qui utilisera cette configuration y aura accès.</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleNotProvidedWarning\" xml:space=\"preserve\">\n    <value>Le module n’a pas été fourni. La spécification du module améliore les performances et empêche les collisions de noms futures.</value>\n  </data>\n  <data name=\"DownloadCommandLongDescription\" xml:space=\"preserve\">\n    <value>Télécharge le programme d’installation à partir du package sélectionné, trouvé en recherchant une source configurée ou directement à partir d’un manifeste. Par défaut, la requête doit correspondre, sans respect de la casse, à l’ID, au nom ou au moniker du package. D’autres champs peuvent être utilisés en passant leur option appropriée. Par défaut, la commande download télécharge le programme d’installation approprié dans le dossier Téléchargements de l’utilisateur.</value>\n  </data>\n  <data name=\"DownloadCommandShortDescription\" xml:space=\"preserve\">\n    <value>Télécharge le programme d’installation à partir d’un package donné</value>\n  </data>\n  <data name=\"DownloadDirectoryArgumentDescription\" xml:space=\"preserve\">\n    <value>Répertoire dans lequel les installateurs sont téléchargés</value>\n  </data>\n  <data name=\"DependenciesFlowDownload\" xml:space=\"preserve\">\n    <value>Téléchargement des dépendances :</value>\n  </data>\n  <data name=\"InstallerDownloaded\" xml:space=\"preserve\">\n    <value>Programme d’installation téléchargé : {0}</value>\n    <comment>{Locked=\"{0}\"} Full path of the downloaded installer.</comment>\n  </data>\n  <data name=\"InstallerTypeArgumentDescription\" xml:space=\"preserve\">\n    <value>Sélectionner le type de programme d’installation</value>\n  </data>\n  <data name=\"InstallerDownloads\" xml:space=\"preserve\">\n    <value>Téléchargements du programme d’installation</value>\n  </data>\n  <data name=\"InstallerDownloadCommandProhibited\" xml:space=\"preserve\">\n    <value>Le programme d’installation ne peut pas être téléchargé pour une installation hors connexion ultérieure. </value>\n  </data>\n  <data name=\"ConfigurationAllUsersElevated\" xml:space=\"preserve\">\n    <value>« --module-path allusers » nécessite des privilèges d’administrateur pour s’exécuter.</value>\n    <comment>{Locked=\"--module-path allusers\"}</comment>\n  </data>\n  <data name=\"ConfigurationModulePath\" xml:space=\"preserve\">\n    <value>Spécifie l’emplacement de stockage des modules sur l’ordinateur local. %LOCALAPPDATA%\\Microsoft\\WinGet\\Configuration\\Modules par défaut</value>\n    <comment>{Locked=\"%LOCALAPPDATA%\\Microsoft\\WinGet\\Configuration\\Modules\"}</comment>\n  </data>\n  <data name=\"ConfigurationModulePathArgError\" xml:space=\"preserve\">\n    <value>La valeur '--module-path' doit être 'currentuser', 'allusers', 'default' ou un chemin absolu.</value>\n    <comment>{Locked=\"{--module-path}, {currentuser}, {allusers}, {default}}</comment>\n  </data>\n  <data name=\"PolicyEnableWinGetConfiguration\" xml:space=\"preserve\">\n    <value>Activer la configuration Gestionnaire de package Windows</value>\n  </data>\n  <data name=\"ErrorCommandLongDescription\" xml:space=\"preserve\">\n    <value>Récupérez des informations sur les erreurs. En fonction d’un nombre, la sortie contiendra des détails sur l’erreur, y compris le nom du symbole s’il s’agit d’une erreur spécifique à winget. En fonction d’une chaîne, les erreurs spécifiques à winget sont recherchées pour cette valeur.</value>\n  </data>\n  <data name=\"ErrorCommandShortDescription\" xml:space=\"preserve\">\n    <value>Obtenir des informations sur les erreurs</value>\n  </data>\n  <data name=\"ErrorInputArgumentDescription\" xml:space=\"preserve\">\n    <value>Valeur à rechercher dans les informations sur l’erreur</value>\n  </data>\n  <data name=\"ErrorNumberIsTooLarge\" xml:space=\"preserve\">\n    <value>Le nombre donné est trop grand pour être un HRESULT.</value>\n  </data>\n  <data name=\"UnknownErrorCode\" xml:space=\"preserve\">\n    <value>Code d’erreur inconnu</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INTERNAL_ERROR\" xml:space=\"preserve\">\n    <value>Erreur interne</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS\" xml:space=\"preserve\">\n    <value>Arguments de ligne de commande non valides</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMMAND_FAILED\" xml:space=\"preserve\">\n    <value>Échec de l’exécution de la commande</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_FAILED\" xml:space=\"preserve\">\n    <value>Échec de l’ouverture du manifeste</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CTRL_SIGNAL_RECEIVED\" xml:space=\"preserve\">\n    <value>Signal d’annulation reçu</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SHELLEXEC_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Échec de l’exécution de ShellExecute</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_MANIFESTVERSION\" xml:space=\"preserve\">\n    <value>Impossible de traiter le manifeste. La version du manifeste est supérieure à la version prise en charge. Mettez à jour le client.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_FAILED\" xml:space=\"preserve\">\n    <value>Échec du téléchargement du programme d’installation</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX\" xml:space=\"preserve\">\n    <value>Impossible d’écrire dans l’index ; il s’agit d’une version de schéma supérieure</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INDEX_INTEGRITY_COMPROMISED\" xml:space=\"preserve\">\n    <value>L’index est endommagé</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCES_INVALID\" xml:space=\"preserve\">\n    <value>Les informations sources configurées sont endommagées</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NAME_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>Le nom de la source est déjà configuré</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_SOURCE_TYPE\" xml:space=\"preserve\">\n    <value>Le type de source n’est pas valide</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_BUNDLE\" xml:space=\"preserve\">\n    <value>Le fichier MSIX est un pack, et non un package</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_DATA_MISSING\" xml:space=\"preserve\">\n    <value>Il manque des données requises par la source</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER\" xml:space=\"preserve\">\n    <value>Aucun des installateurs n’est applicable pour le système actuel</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_HASH_MISMATCH\" xml:space=\"preserve\">\n    <value>Le hachage du fichier du programme d’installation ne correspond pas au manifeste</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NAME_DOES_NOT_EXIST\" xml:space=\"preserve\">\n    <value>Le nom de la source n’existe pas</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_ARG_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>L’emplacement source est déjà configuré sous un autre nom</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICATIONS_FOUND\" xml:space=\"preserve\">\n    <value>Aucun package n’a été trouvé</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_SOURCES_DEFINED\" xml:space=\"preserve\">\n    <value>Aucune source n’est configurée</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_APPLICATIONS_FOUND\" xml:space=\"preserve\">\n    <value>Plusieurs packages trouvés correspondant aux critères</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_MANIFEST_FOUND\" xml:space=\"preserve\">\n    <value>Aucun manifeste trouvé correspondant aux critères</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXTENSION_PUBLIC_FAILED\" xml:space=\"preserve\">\n    <value>Échec de l’obtention du dossier public à partir du package source</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMMAND_REQUIRES_ADMIN\" xml:space=\"preserve\">\n    <value>La commande requiert des privilèges d’administrateur pour s’exécuter</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NOT_SECURE\" xml:space=\"preserve\">\n    <value>L’emplacement source n’est pas sécurisé</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>Le client Microsoft Store est bloqué par la stratégie</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_APP_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>L’application Microsoft Store est bloquée par la stratégie</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXPERIMENTAL_FEATURE_DISABLED\" xml:space=\"preserve\">\n    <value>La fonctionnalité est en cours de développement. Il peut être activé à l’aide des paramètres winget.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Échec de l’installation de l’application Microsoft Store</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMPLETE_INPUT_BAD\" xml:space=\"preserve\">\n    <value>Échec de l’exécution de la saisie semi-automatique</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED\" xml:space=\"preserve\">\n    <value>Échec de l’initialisation de l’analyseur YAML</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_MAPPING_KEY\" xml:space=\"preserve\">\n    <value>Une clé YAML non valide a été rencontrée</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY\" xml:space=\"preserve\">\n    <value>Une clé YAML dupliquée a été rencontrée</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_OPERATION\" xml:space=\"preserve\">\n    <value>Opération YAML non valide</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_DOC_BUILD_FAILED\" xml:space=\"preserve\">\n    <value>Échec de la génération du document YAML</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_EMITTER_STATE\" xml:space=\"preserve\">\n    <value>État de l’émetteur YAML non valide</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_DATA\" xml:space=\"preserve\">\n    <value>Données YAML non valides</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LIBYAML_ERROR\" xml:space=\"preserve\">\n    <value>Erreur LibYAML</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_WARNING\" xml:space=\"preserve\">\n    <value>La validation des manifestes a réussi avec des avertissements</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_FAILURE\" xml:space=\"preserve\">\n    <value>La validation du manifeste a échoué</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_MANIFEST\" xml:space=\"preserve\">\n    <value>Le manifeste n’est pas valide</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>Aucune mise à jour applicable trouvée</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPDATE_ALL_HAS_FAILURE\" xml:space=\"preserve\">\n    <value>mises à niveau WinGet – toutes terminées sur des échecs</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_SECURITY_CHECK_FAILED\" xml:space=\"preserve\">\n    <value>Désolé, Nous n’avons pas pu effectuer la vérification de sécurité du programme d’installation</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_SIZE_MISMATCH\" xml:space=\"preserve\">\n    <value>La taille du téléchargement ne correspond pas à la longueur de contenu attendue</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_UNINSTALL_INFO_FOUND\" xml:space=\"preserve\">\n    <value>Commande de désinstallation introuvable</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXEC_UNINSTALL_COMMAND_FAILED\" xml:space=\"preserve\">\n    <value>Échec de l’exécution de la commande de désinstallation</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_BREAK_ITERATOR_ERROR\" xml:space=\"preserve\">\n    <value>Erreur d’itérateur d’arrêt ICU</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_CASEMAP_ERROR\" xml:space=\"preserve\">\n    <value>Erreur ICU casemap</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_REGEX_ERROR\" xml:space=\"preserve\">\n    <value>Erreur d’expression régulière ICU</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_IMPORT_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Échec de l’installation d’un ou de plusieurs packages importés</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NOT_ALL_PACKAGES_FOUND\" xml:space=\"preserve\">\n    <value>Impossible de trouver un ou plusieurs packages demandés</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE\" xml:space=\"preserve\">\n    <value>Le fichier JSON n’est pas valide</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NOT_REMOTE\" xml:space=\"preserve\">\n    <value>L’emplacement source n’est pas distant</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE\" xml:space=\"preserve\">\n    <value>La source rest configurée n’est pas prise en charge</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA\" xml:space=\"preserve\">\n    <value>Données non valides retournées par la source rest</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>L’opération est bloquée par la stratégie de groupe</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_INTERNAL_ERROR\" xml:space=\"preserve\">\n    <value>Erreur interne de l'API Rest</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_URL\" xml:space=\"preserve\">\n    <value>URL de source rest non valide</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_UNSUPPORTED_MIME_TYPE\" xml:space=\"preserve\">\n    <value>Type MIME non supporté renvoyé par l'API restante</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_VERSION\" xml:space=\"preserve\">\n    <value>Version de contrat source rest non valide</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE\" xml:space=\"preserve\">\n    <value>Les données sources sont endommagées ou falsifiées</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_STREAM_READ_FAILURE\" xml:space=\"preserve\">\n    <value>Erreur de lecture à partir du flux</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>Les contrats du package n’ont pas été acceptés</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PROMPT_INPUT_ERROR\" xml:space=\"preserve\">\n    <value>Erreur lors de la lecture de l’entrée dans l’invite</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST\" xml:space=\"preserve\">\n    <value>La demande de recherche n’est pas prise en charge par une ou plusieurs sources</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_ENDPOINT_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Le point de terminaison de l'API de repos est introuvable.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_OPEN_FAILED\" xml:space=\"preserve\">\n    <value>Échec de l’ouverture de la source.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>Les contrats sources n’ont pas été acceptés</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CUSTOMHEADER_EXCEEDS_MAXLENGTH\" xml:space=\"preserve\">\n    <value>La taille de l’en-tête dépasse la limite autorisée de 1 024 caractères. Réduisez la taille et réessayez.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MISSING_RESOURCE_FILE\" xml:space=\"preserve\">\n    <value>Fichier de ressources manquant</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSI_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Échec de l’exécution de l’installation de MSI</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT\" xml:space=\"preserve\">\n    <value>Les arguments pour msiexec ne sont pas valides</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FAILED_TO_OPEN_ALL_SOURCES\" xml:space=\"preserve\">\n    <value>Échec de l’ouverture d’une ou de plusieurs sources</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>Échec de la validation des dépendances</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MISSING_PACKAGE\" xml:space=\"preserve\">\n    <value>Un ou plusieurs packages sont manquants</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_TABLE_COLUMN\" xml:space=\"preserve\">\n    <value>Colonne de table non valide</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_NOT_NEWER\" xml:space=\"preserve\">\n    <value>La version de mise à niveau n’est pas plus récente que la version installée</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_UNKNOWN\" xml:space=\"preserve\">\n    <value>La version de mise à niveau est inconnue et le remplacement n’est pas spécifié</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_CONVERSION_ERROR\" xml:space=\"preserve\">\n    <value>Erreur de conversion de l’ICU</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Échec de l’installation du package portable</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_REPARSE_POINT_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Le volume ne prend pas en charge les points d’analyse</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_PACKAGE_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>Un package portable d’une autre source existe déjà.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_SYMLINK_PATH_IS_DIRECTORY\" xml:space=\"preserve\">\n    <value>Impossible de créer le lien symbolique. Le chemin pointe vers un répertoire.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_PROHIBITS_ELEVATION\" xml:space=\"preserve\">\n    <value>Le programme d’installation ne peut pas être exécuté à partir d’un contexte d’administrateur.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Échec de la désinstallation du package portable</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ARP_VERSION_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>Échec de la validation des valeurs DisplayVersion par rapport à l’index.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_ARGUMENT\" xml:space=\"preserve\">\n    <value>Un ou plusieurs arguments ne sont pas pris en charge.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_BIND_WITH_EMBEDDED_NULL\" xml:space=\"preserve\">\n    <value>Les caractères Null incorporés ne sont pas autorisés pour SQLite</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Impossible de trouver le programme d’installation imbriqué dans l’archive.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXTRACT_ARCHIVE_FAILED\" xml:space=\"preserve\">\n    <value>Échec de l’extraction de l’archive.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_INVALID_PATH\" xml:space=\"preserve\">\n    <value>Chemin de fichier relatif non valide fourni pour le programme d’installation imbriqué.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PINNED_CERTIFICATE_MISMATCH\" xml:space=\"preserve\">\n    <value>Le certificat de serveur ne correspond à aucune des valeurs attendues.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_LOCATION_REQUIRED\" xml:space=\"preserve\">\n    <value>L’emplacement d’installation doit être fourni.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ARCHIVE_SCAN_FAILED\" xml:space=\"preserve\">\n    <value>Échec de l’analyse des programmes malveillants d’archivage.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>Au moins une version du package installée a été trouvée.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PIN_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>Un code PIN existe déjà pour le package.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PIN_DOES_NOT_EXIST\" xml:space=\"preserve\">\n    <value>Il n’y a pas de code PIN pour le package.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_OPEN_PINNING_INDEX\" xml:space=\"preserve\">\n    <value>Impossible d’ouvrir la base de données des codes PIN.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Une ou plusieurs applications n’ont pas pu être installées</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Une ou plusieurs applications n’ont pas pu être désinstallés</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NOT_ALL_QUERIES_FOUND_SINGLE\" xml:space=\"preserve\">\n    <value>Une ou plusieurs requêtes n’ont pas retourné exactement une correspondance</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_PINNED\" xml:space=\"preserve\">\n    <value>Le package a une broche qui empêche la mise à niveau.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB\" xml:space=\"preserve\">\n    <value>Le package actuellement installé est le package stub</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_APPTERMINATION_RECEIVED\" xml:space=\"preserve\">\n    <value>Signal d’arrêt de l’application reçu</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_DEPENDENCIES\" xml:space=\"preserve\">\n    <value>Échec du téléchargement des dépendances de package.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_COMMAND_PROHIBITED\" xml:space=\"preserve\">\n    <value>Échec du téléchargement du package. Le téléchargement pour une installation hors connexion est interdit.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SERVICE_UNAVAILABLE\" xml:space=\"preserve\">\n    <value>Un service requis est occupé ou indisponible. Réessayez plus tard.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESUME_ID_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Le GUID fourni ne correspond pas à un état de reprise valide.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CLIENT_VERSION_MISMATCH\" xml:space=\"preserve\">\n    <value>La version actuelle du client ne correspondait pas à la version du client de l’état enregistré.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_RESUME_STATE\" xml:space=\"preserve\">\n    <value>Les données d’état de reprise ne sont pas valides.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_OPEN_CHECKPOINT_INDEX\" xml:space=\"preserve\">\n    <value>Impossible d’ouvrir la base de données de point de contrôle.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESUME_LIMIT_EXCEEDED\" xml:space=\"preserve\">\n    <value>Limite de reprise maximale dépassée.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_AUTHENTICATION_INFO\" xml:space=\"preserve\">\n    <value>Informations d’authentification non valides.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Méthode d’authentification non prise en charge.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED\" xml:space=\"preserve\">\n    <value>Échec de l'authentification.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_INTERACTIVE_REQUIRED\" xml:space=\"preserve\">\n    <value>Échec de l’authentification. Authentification interactive requise.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_CANCELLED_BY_USER\" xml:space=\"preserve\">\n    <value>Échec de l’authentification. Annulé par l’utilisateur.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_INCORRECT_ACCOUNT\" xml:space=\"preserve\">\n    <value>Échec de l’authentification. Le compte authentifié n’est pas le compte souhaité.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE\" xml:space=\"preserve\">\n    <value>L’application est en cours d’exécution. Quittez l’application, puis réessayez.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INSTALL_IN_PROGRESS\" xml:space=\"preserve\">\n    <value>Une autre installation est déjà en cours. Veuillez réessayez.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_FILE_IN_USE\" xml:space=\"preserve\">\n    <value>Un ou plusieurs fichiers sont en cours d’utilisation. Quittez l’application, puis réessayez.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_MISSING_DEPENDENCY\" xml:space=\"preserve\">\n    <value>Ce package a une dépendance manquante dans votre système.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DISK_FULL\" xml:space=\"preserve\">\n    <value>Votre PC n’a plus d’espace disponible. Libérez de l’espace, puis réessayez.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INSUFFICIENT_MEMORY\" xml:space=\"preserve\">\n    <value>Mémoire disponible insuffisante pour l’installation. Fermez les autres applications, puis réessayez.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_NO_NETWORK\" xml:space=\"preserve\">\n    <value>Cette application nécessite une connectivité Internet. Connectez-vous à un réseau, puis réessayez.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CONTACT_SUPPORT\" xml:space=\"preserve\">\n    <value>Cette application a rencontré une erreur lors de l’installation. Contactez le support.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_TO_FINISH\" xml:space=\"preserve\">\n    <value>Redémarrez votre PC pour terminer l’installation.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_FOR_INSTALL\" xml:space=\"preserve\">\n    <value>Échec de l’installation. Redémarrez votre PC, puis réessayez.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_INITIATED\" xml:space=\"preserve\">\n    <value>Votre PC redémarrera pour terminer l’installation.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CANCELLED_BY_USER\" xml:space=\"preserve\">\n    <value>L’installation a été annulée par l’utilisateur.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>Une autre version de cette application est déjà installée.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DOWNGRADE\" xml:space=\"preserve\">\n    <value>Une version supérieure de cette application est déjà installée.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>Les stratégies d’organisation empêchent l’installation. Contactez votre administrateur.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DEPENDENCIES\" xml:space=\"preserve\">\n    <value>Échec de l'installation des dépendances de package.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE_BY_APPLICATION\" xml:space=\"preserve\">\n    <value>L’application est actuellement utilisée par une autre application.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INVALID_PARAMETER\" xml:space=\"preserve\">\n    <value>Paramètre non valide.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Package non pris en charge par le système.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_UPGRADE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Le programme d’installation ne prend pas en charge la mise à niveau d’un package existant.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CUSTOM_ERROR\" xml:space=\"preserve\">\n    <value>L'installation a échoué en raison d'une erreur du programme d'installation personnalisé.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_ARP_ENTRY_NOT_FOUND\" xml:space=\"preserve\">\n    <value>L’entrée Applications et fonctionnalités du package est introuvable.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>L’emplacement de l’installation n’est pas applicable.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_FOUND\" xml:space=\"preserve\">\n    <value>L’emplacement de l’installation est introuvable.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_HASH_MISMATCH\" xml:space=\"preserve\">\n    <value>Le hachage du fichier existant ne correspond pas.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Fichier introuvable.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK\" xml:space=\"preserve\">\n    <value>Nous avons trouvé le fichier, mais n’avons pas vérifié le hachage.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_ACCESS_ERROR\" xml:space=\"preserve\">\n    <value>Désolé... Nous n’avons pas pu accéder au fichier.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE\" xml:space=\"preserve\">\n    <value>Le fichier de configuration n’est pas valide.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_YAML\" xml:space=\"preserve\">\n    <value>La syntaxe YAML n’est pas valide.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_FIELD_TYPE\" xml:space=\"preserve\">\n    <value>Un champ de configuration a un type non valide.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION\" xml:space=\"preserve\">\n    <value>La configuration présente une version inconnue.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_SET_APPLY_FAILED\" xml:space=\"preserve\">\n    <value>Une erreur s’est produite lors de l’application de la configuration.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER\" xml:space=\"preserve\">\n    <value>La configuration contient un identificateur en double.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MISSING_DEPENDENCY\" xml:space=\"preserve\">\n    <value>Il manque une dépendance à la configuration.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED\" xml:space=\"preserve\">\n    <value>La configuration a une dépendance non satisfaite.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_ASSERTION_FAILED\" xml:space=\"preserve\">\n    <value>Échec d’une assertion pour l’unité de configuration.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MANUALLY_SKIPPED\" xml:space=\"preserve\">\n    <value>La configuration a été ignorée manuellement.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_WARNING_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>L’utilisateur a refusé de poursuivre l’exécution.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_SET_DEPENDENCY_CYCLE\" xml:space=\"preserve\">\n    <value>Le graphe des dépendances contient un cycle qui ne peut pas être résolu.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_FIELD_VALUE\" xml:space=\"preserve\">\n    <value>La configuration a une valeur de champ non valide.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MISSING_FIELD\" xml:space=\"preserve\">\n    <value>Un champ manque à la configuration.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_TEST_FAILED\" xml:space=\"preserve\">\n    <value>Certaines unités de configuration ont échoué lors du test de leur état.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_TEST_NOT_RUN\" xml:space=\"preserve\">\n    <value>L’état de configuration n’a pas été testé.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_NOT_INSTALLED\" xml:space=\"preserve\">\n    <value>Désolé... Nous n’avons pas pu installer l’unité de configuration.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_NOT_FOUND_REPOSITORY\" xml:space=\"preserve\">\n    <value>L’unité de configuration est introuvable.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_MULTIPLE_MATCHES\" xml:space=\"preserve\">\n    <value>Plusieurs correspondances ont été trouvées pour l’unité de configuration ; spécifiez le module pour sélectionner le module approprié.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_GET\" xml:space=\"preserve\">\n    <value>Échec de l’unité de configuration lors de la tentative d’obtention de l’état actuel du système.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_TEST\" xml:space=\"preserve\">\n    <value>Échec de l’unité de configuration lors de la tentative de test de l’état actuel du système.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_SET\" xml:space=\"preserve\">\n    <value>Échec de l’unité de configuration lors de la tentative d’application de l’état souhaité.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_MODULE_CONFLICT\" xml:space=\"preserve\">\n    <value>Le module de l’unité de configuration est disponible dans plusieurs emplacements avec la même version.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE\" xml:space=\"preserve\">\n    <value>Échec du chargement du module pour l’unité de configuration.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_INVALID_RESULT\" xml:space=\"preserve\">\n    <value>L’unité de configuration a retourné un résultat inattendu lors de l’exécution.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_SETTING_CONFIG_ROOT\" xml:space=\"preserve\">\n    <value>Une unité contient un paramètre qui nécessite la racine de configuration.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR\" xml:space=\"preserve\">\n    <value>L’opération n’est pas prise en charge par le processeur de configuration.</value>\n  </data>\n  <data name=\"Unavailable\" xml:space=\"preserve\">\n    <value>Non disponible</value>\n  </data>\n  <data name=\"EnableWindowsFeaturesSuccess\" xml:space=\"preserve\">\n    <value>Dépendances des fonctionnalités Windows activées</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE_ADMIN\" xml:space=\"preserve\">\n    <value>Échec du chargement du module pour l’unité de configuration, car il nécessite des privilèges d’administrateur pour s’exécuter.</value>\n  </data>\n  <data name=\"ConfigurationUnitSettingConfigRoot\" xml:space=\"preserve\">\n    <value>Une unité contient un paramètre qui nécessite la racine de configuration.</value>\n  </data>\n  <data name=\"ConfigurationUnitImportModuleAdmin\" xml:space=\"preserve\">\n    <value>Échec du chargement du module pour l’unité de configuration, car il nécessite des privilèges d’administrateur pour s’exécuter.</value>\n  </data>\n  <data name=\"ResumeCommandLongDescription\" xml:space=\"preserve\">\n    <value>Reprend l’exécution d’une commande précédemment enregistrée en passant l’identificateur unique de la commande enregistrée. Permet de reprendre une commande exécutée qui a peut-être été arrêtée en raison d’un redémarrage.</value>\n  </data>\n  <data name=\"ResumeCommandShortDescription\" xml:space=\"preserve\">\n    <value>Reprend l’exécution d’une commande précédemment enregistrée.</value>\n  </data>\n  <data name=\"ResumeIdArgumentDescription\" xml:space=\"preserve\">\n    <value>Identificateur unique de l’état enregistré à reprendre</value>\n  </data>\n  <data name=\"ClientVersionMismatchError\" xml:space=\"preserve\">\n    <value>La reprise de l’état à partir d’une version de client différente n’est pas prise en charge : {0}</value>\n    <comment>{Locked= \"{0}\"} Message displayed to inform the user that the client version of the resume state does not match the current client version. {0} is a placeholder for the client version that created the resume state.</comment>\n  </data>\n  <data name=\"ResumeIdNotFoundError\" xml:space=\"preserve\">\n    <value>L’état de reprise n’existe pas : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a guid that does not correspond to a valid saved state. {0} is a placeholder replaced by the provided guid string.</comment>\n  </data>\n  <data name=\"ResumeStateDataNotFoundError\" xml:space=\"preserve\">\n    <value>Données introuvables dans l’état de reprise.</value>\n  </data>\n  <data name=\"CommandDoesNotSupportResumeMessage\" xml:space=\"preserve\">\n    <value>Cette commande ne prend pas en charge la reprise.</value>\n  </data>\n  <data name=\"AllowRebootArgumentDescription\" xml:space=\"preserve\">\n    <value>Autorise un redémarrage le cas échéant</value>\n  </data>\n  <data name=\"InitiatingReboot\" xml:space=\"preserve\">\n    <value>Lancement du redémarrage pour terminer l’opération...</value>\n  </data>\n  <data name=\"FailedToInitiateReboot\" xml:space=\"preserve\">\n    <value>Échec du lancement d’un redémarrage.</value>\n  </data>\n  <data name=\"ResumeLimitExceeded\" xml:space=\"preserve\">\n    <value>L’opération de reprise dépasse la limite autorisée de {0} reprise(s). Pour reprendre manuellement, exécutez la commande '{1}'.</value>\n    <comment>{Locked=\"{0}\", \"{1}\"} {0} is a placeholder that is replaced by an integer number of the number of allowed resumes. {1} is a placeholder for the command to run to perform a manual resume.</comment>\n  </data>\n  <data name=\"IgnoreResumeLimitArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignorer la limite de reprise d’un état enregistré</value>\n  </data>\n  <data name=\"UriSchemeNotSupported\" xml:space=\"preserve\">\n    <value>Schéma d’URI non pris en charge : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the provided uri is not supported. {0} is a placeholder replaced by the provided uri.</comment>\n  </data>\n  <data name=\"UriNotWellFormed\" xml:space=\"preserve\">\n    <value>URI mal formé : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the provided uri is not well formed. {0} is a placeholder replaced by the provided uri.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitEmptyContent\" xml:space=\"preserve\">\n    <value>Échec de l’analyse {0} contenu des paramètres ou du contenu des paramètres de l’unité de configuration est vide.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder replaced by the input winget configure resource unit type.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitMissingRequiredArg\" xml:space=\"preserve\">\n    <value>l’argument requis est manquant dans l’unité de configuration {0} : {1}</value>\n    <comment>{Locked=\"{0},{1}\"} {0} is a placeholder for the input winget configure resource unit type. {1} is placeholder for the missing arg.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitMissingRecommendedArg\" xml:space=\"preserve\">\n    <value>{0}'unité de configuration n’a pas d’argument recommandé : {1}</value>\n    <comment>{Locked=\"{0},{1}\"} {0} is a placeholder for the input winget configure resource unit type. {1} is placeholder for the missing arg.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitKnownSourceConfliction\" xml:space=\"preserve\">\n    <value>L’unité de configuration WinGetSource est en conflit avec une source connue : {0}</value>\n    <comment>{Locked=\"WinGetSource,{0}\"} {0} is a placeholder for the input winget source in the configuration unit settings.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitThirdPartySourceAssertion\" xml:space=\"preserve\">\n    <value>Assertions de l’unité de configuration WinGetSource sur une source tierce : {0}</value>\n    <comment>{Locked=\"WinGetSource,{0}\"} {0} is a placeholder for the input winget source in the configuration unit settings.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitBothPackageVersionAndUseLatest\" xml:space=\"preserve\">\n    <value>WinGetPackage déclare UseLatest et Version. ID du package : {0}</value>\n    <comment>{Locked=\"WinGetPackage,UseLatest,Version,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitThirdPartySourceAssertionForPackage\" xml:space=\"preserve\">\n    <value>L’unité de configuration WinGetPackage déclare sur un package à partir d’une source tierce. ID du package : {0} ; Source : {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitDependencySourceNotConfigured\" xml:space=\"preserve\">\n    <value>Le package d’unité de configuration WinGetPackage dépend d’une source tierce qui n’a pas été configurée précédemment. ID du package : {0} ; Source : {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitDependencySourceNotDeclaredAsDependency\" xml:space=\"preserve\">\n    <value>Le package d’unité de configuration WinGetPackage dépend d’une source tierce. Il est recommandé de déclarer la dépendance dans la section uni dependsOn. ID du package : {0} ; Source : {1}</value>\n    <comment>{Locked=\"WinGetPackage,dependsOn,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageSourceOpenFailed\" xml:space=\"preserve\">\n    <value>Impossible de valider le package d’unité de configuration WinGetPackage. Échec de l’ouverture de la source. ID du package : {0} ; Source : {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageNotFound\" xml:space=\"preserve\">\n    <value>Impossible de valider le package d’unité de configuration WinGetPackage. Package introuvable. ID du package : {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageMultipleFound\" xml:space=\"preserve\">\n    <value>Impossible de valider le package d’unité de configuration WinGetPackage. Plusieurs packages trouvés. ID du package : {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageVersionNotFound\" xml:space=\"preserve\">\n    <value>Impossible de valider le package d’unité de configuration WinGetPackage. Version de package introuvable. ID du package : {0} ; {1} de version</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitPackageVersionSpecifiedWithOnlyOnePackageVersion\" xml:space=\"preserve\">\n    <value>Package d’unité de configuration WinGetPackage spécifié avec une version spécifique alors qu’une seule version du package est disponible. ID du package :{0} ; version : {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackage\" xml:space=\"preserve\">\n    <value>Impossible de valider le package d’unité de configuration WinGetPackage. ID du package : {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"AuthenticationModeArgumentDescription\" xml:space=\"preserve\">\n    <value>Spécifier la préférence de fenêtre d’authentification (silent, silentPreferred ou interactive)</value>\n    <comment>{Locked=\"silent\",\"silentPreferred\",\"interactive\"} This argument allows the user to select authentication window popup behavior.</comment>\n  </data>\n  <data name=\"AuthenticationAccountArgumentDescription\" xml:space=\"preserve\">\n    <value>Spécifier le compte à utiliser pour l’authentification</value>\n  </data>\n  <data name=\"SourceAddFailedAuthenticationNotSupported\" xml:space=\"preserve\">\n    <value>Échec de l’ajout de la source. Cette version winget ne prend pas en charge la méthode d’authentification de la source. Essayez de mettre à niveau vers la dernière version winget.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"SourceRequiresAuthentication\" xml:space=\"preserve\">\n    <value>La source {0} requiert une authentification. L’invite d’authentification peut s’afficher en cas de besoin. Les informations authentifiées seront partagées avec la source pour l’autorisation d’accès.</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"RepairCommandLongDescription\" xml:space=\"preserve\">\n    <value>Répare le package sélectionné, trouvé en effectuant une recherche dans la liste des packages installés ou directement à partir d’un manifeste. Par défaut, la requête doit correspondre, sans respect de la casse, à l’ID, au nom ou au moniker du package. D’autres champs peuvent être utilisés en passant leur option appropriée.</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"RepairCommandShortDescription\" xml:space=\"preserve\">\n    <value>Répare le package sélectionné</value>\n  </data>\n  <data name=\"NoRepairInfoFound\" xml:space=\"preserve\">\n    <value>La commande de réparation de ce package est introuvable. Contactez l’éditeur du package pour obtenir de l’aide.</value>\n  </data>\n  <data name=\"RepairDifferentInstallTechnology\" xml:space=\"preserve\">\n    <value>La technologie du programme d’installation utilisée ne correspond pas à la version actuellement installée.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_REPAIR_INFO_FOUND\" xml:space=\"preserve\">\n    <value>Commande de réparation introuvable.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_REPAIR_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>La technologie du programme d’installation en cours d’utilisation ne prend pas en charge la réparation.</value>\n  </data>\n  <data name=\"RepairFlowRepairSuccess\" xml:space=\"preserve\">\n    <value>L’opération de réparation s’est terminée correctement.</value>\n  </data>\n  <data name=\"RepairAbandoned\" xml:space=\"preserve\">\n    <value>Réparation abandonnée</value>\n  </data>\n  <data name=\"RepairFlowStartingPackageRepair\" xml:space=\"preserve\">\n    <value>Démarrage de la réparation du package...</value>\n  </data>\n  <data name=\"MSStoreRepairFailed\" xml:space=\"preserve\">\n    <value>Échec de la réparation du package Microsoft Store. Code d'erreur : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Microsoft Store application package fails to repair. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXEC_REPAIR_FAILED\" xml:space=\"preserve\">\n    <value>Échec de l’opération de réparation.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_REPAIR_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>L’opération de réparation n’est pas applicable.</value>\n  </data>\n  <data name=\"RepairFlowNoMatchingVersion\" xml:space=\"preserve\">\n    <value>Aucune version de package correspondante n’est disponible à partir des sources configurées.</value>\n  </data>\n  <data name=\"RepairFlowReturnCodeSystemNotSupported\" xml:space=\"preserve\">\n    <value>La configuration système actuelle ne prend pas en charge la réparation de ce package.</value>\n  </data>\n  <data name=\"RepairOperationNotSupported\" xml:space=\"preserve\">\n    <value>La technologie de programme d’installation utilisée ne prend pas en charge la réparation.</value>\n  </data>\n  <data name=\"NoAdminRepairForUserScopePackage\" xml:space=\"preserve\">\n    <value>Le package installé pour l’étendue de l’utilisateur ne peut pas être réparé en cas d’exécution avec des privilèges d’administrateur.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED\" xml:space=\"preserve\">\n    <value>Les opérations de réparation impliquant des privilèges d’administrateur ne sont pas autorisées sur les packages installés dans l’étendue utilisateur.</value>\n  </data>\n  <data name=\"RepairFailedWithCode\" xml:space=\"preserve\">\n    <value>Échec de la réparation avec le code de sortie : {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to repair an application package fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SQLITE_CONNECTION_TERMINATED\" xml:space=\"preserve\">\n    <value>La connexion SQLite a été interrompue pour éviter toute altération.</value>\n  </data>\n  <data name=\"UninstallAllVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Désinstaller toutes les versions</value>\n  </data>\n  <data name=\"TargetVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>La version à suivre</value>\n  </data>\n  <data name=\"UninstallFailedDueToMultipleVersions\" xml:space=\"preserve\">\n    <value>Plusieurs versions de ce paquet sont installées. Soit vous affinez la recherche, soit vous passez l'argument `--version` pour en sélectionner une, soit vous passez l'option `--all-versions` pour les désinstaller toutes.</value>\n    <comment>{Locked=\"--version,--all-versions\"}</comment>\n  </data>\n  <data name=\"PolicyEnableProxyCommandLineOptions\" xml:space=\"preserve\">\n    <value>Activer les options de ligne de commande du gestionnaire de paquets Windows</value>\n    <comment>Describes a Group Policy that can enable the use of the --proxy option to set a proxy</comment>\n  </data>\n  <data name=\"ProxyArgumentDescription\" xml:space=\"preserve\">\n    <value>Définir un proxy à utiliser pour cette exécution</value>\n  </data>\n  <data name=\"NoProxyArgumentDescription\" xml:space=\"preserve\">\n    <value>Désactiver l’utilisation du proxy pour cette exécution</value>\n  </data>\n  <data name=\"ResetAdminSettingFailed\" xml:space=\"preserve\">\n    <value>Impossible de réinitialiser {0}. Ce paramètre est contrôlé par la stratégie. Pour plus d’informations, contactez votre administrateur système.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"ResetAdminSettingSucceeded\" xml:space=\"preserve\">\n    <value>Réinitialiser les paramètres administratifs '{0}'.</value>\n    <comment>{Locked=\"{0}\"} Message displayed after the user resets an admin setting to its default value. Reset is used as verb in past tense. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"SetAdminSettingFailed\" xml:space=\"preserve\">\n    <value>Impossible de définir {0}. Ce paramètre est contrôlé par la stratégie. Pour plus d’informations, contactez votre administrateur système.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"SetAdminSettingSucceeded\" xml:space=\"preserve\">\n    <value>Régler le paramètre d'administration '{0}' sur '{1}'.</value>\n    <comment>{Locked=\"{0}\"} Message displayed after the user sets the value of an admin setting. Set is used as a verb in past tense. {0} is a placeholder replaced by the setting name. {1} is a placeholder replaced </comment>\n  </data>\n  <data name=\"SettingNameArgumentDescription\" xml:space=\"preserve\">\n    <value>Nom du paramètre à modifier</value>\n  </data>\n  <data name=\"SettingValueArgumentDescription\" xml:space=\"preserve\">\n    <value>Valeur à définir pour le paramètre.</value>\n  </data>\n  <data name=\"SettingsResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>Rétablit la valeur par défaut d’un paramètre d’administrateur.</value>\n  </data>\n  <data name=\"SettingsResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>Rétablit la valeur par défaut d’un paramètre d’administrateur.</value>\n  </data>\n  <data name=\"SettingsSetCommandLongDescription\" xml:space=\"preserve\">\n    <value>Définit la valeur d'un paramètre administratif.</value>\n  </data>\n  <data name=\"SettingsSetCommandShortDescription\" xml:space=\"preserve\">\n    <value>Définit la valeur d'un paramètre administratif.</value>\n  </data>\n  <data name=\"SourceExplicitArgumentDescription\" xml:space=\"preserve\">\n    <value>Exclut une source de la recherche, sauf indication contraire</value>\n  </data>\n  <data name=\"SourceEditExplicitArgumentDescription\" xml:space=\"preserve\">\n    <value>Exclut une source de la découverte (true ou false)</value>\n  </data>\n  <data name=\"SourceListExplicit\" xml:space=\"preserve\">\n    <value>Contenu explicite</value>\n  </data>\n  <data name=\"SourceTrustLevelArgumentDescription\" xml:space=\"preserve\">\n    <value>Niveau de confiance de la source (aucun ou approuvé)</value>\n  </data>\n  <data name=\"SourceListTrustLevel\" xml:space=\"preserve\">\n    <value>Niveau de confiance</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DISPLAYCATALOG_API_FAILED\" xml:space=\"preserve\">\n    <value>Échec de l'obtention du catalogue de paquets Microsoft Store.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_DISPLAYCATALOG_PACKAGE\" xml:space=\"preserve\">\n    <value>Aucun paquet Microsoft Store applicable n'a été trouvé dans le catalogue de paquets Microsoft Store.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SFSCLIENT_API_FAILED\" xml:space=\"preserve\">\n    <value>Échec de l'obtention des informations de téléchargement du paquet Microsoft Store.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_SFSCLIENT_PACKAGE\" xml:space=\"preserve\">\n    <value>Aucun package Microsoft Store applicable n’a été trouvé pour le téléchargement.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED\" xml:space=\"preserve\">\n    <value>Échec de la récupération de la licence du paquet Microsoft Store.</value>\n  </data>\n  <data name=\"MSStoreDownloadNoApplicablePackageFound\" xml:space=\"preserve\">\n    <value>Aucun paquet Microsoft Store applicable n’a été trouvé.</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageHashVerified\" xml:space=\"preserve\">\n    <value>Vérification réussie du hachage du paquet Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageHashMismatch\" xml:space=\"preserve\">\n    <value>Mauvaise correspondance du hachage du paquet Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloaded\" xml:space=\"preserve\">\n    <value>Paquet Microsoft Store téléchargé : {0}</value>\n    <comment>{Locked=\"{0}\"} Full path of the downloaded package.</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadFailed\" xml:space=\"preserve\">\n    <value>Le téléchargement du paquet Microsoft Store a échoué : {0}</value>\n    <comment>{Locked=\"{0}\"} Package name.</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadSuccess\" xml:space=\"preserve\">\n    <value>Le téléchargement du paquet Microsoft Store est terminé</value>\n  </data>\n  <data name=\"MSStoreDownloadMainPackages\" xml:space=\"preserve\">\n    <value>Téléchargement des principaux paquets à partir du Microsoft Store...</value>\n  </data>\n  <data name=\"MSStoreDownloadDependencyPackages\" xml:space=\"preserve\">\n    <value>Téléchargement de paquets de dépendances à partir du Microsoft Store...</value>\n  </data>\n  <data name=\"MSStoreDownloadGetDownloadInfo\" xml:space=\"preserve\">\n    <value>Récupération des informations de téléchargement des paquets Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadGetDownloadInfoFailed\" xml:space=\"preserve\">\n    <value>Échec de la récupération des informations de téléchargement du paquet Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadGetLicense\" xml:space=\"preserve\">\n    <value>Récupération de la licence du paquet Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseSuccess\" xml:space=\"preserve\">\n    <value>Licence du paquet Microsoft Store sauvegardée : {0}</value>\n    <comment>{Locked=\"{0}\"} License file full path.</comment>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseFailed\" xml:space=\"preserve\">\n    <value>Échec de la récupération de la licence du paquet Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadRenameNotSupported\" xml:space=\"preserve\">\n    <value>Le téléchargement du paquet Microsoft Store ne prend pas en charge l'argument --rename. Le paquet Microsoft Store utilisera les noms fournis par le catalogue Microsoft Store.</value>\n    <comment>{Locked=\"--rename\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadAuthenticationNotice\" xml:space=\"preserve\">\n    <value>Microsoft Store téléchargement du package nécessite une authentification par ID Microsoft Entra. L’invite d’authentification peut s’afficher en cas de besoin. Les informations authentifiées seront partagées avec services Microsoft pour l’autorisation d’accès. Pour Microsoft Store licence de package, le compte d’ID Microsoft Entra doit être membre de l’administrateur général, de l’administrateur utilisateur ou de l’administrateur de licences.</value>\n    <comment>{Locked=\"Global Administrator,User Administrator,License Administrator\"}</comment>\n  </data>\n  <data name=\"SkipMicrosoftStorePackageLicenseArgumentDescription\" xml:space=\"preserve\">\n    <value>Ne pas récupérer la licence hors ligne du paquet Microsoft Store</value>\n  </data>\n  <data name=\"PlatformArgumentDescription\" xml:space=\"preserve\">\n    <value>Sélectionner la plate-forme cible</value>\n  </data>\n  <data name=\"ConfigurationExportAddingToFile\" xml:space=\"preserve\">\n    <value>Ajout d'un fichier de configuration : {0}</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportSuccessful\" xml:space=\"preserve\">\n    <value>Exportation réussie</value>\n  </data>\n  <data name=\"ConfigurationGettingResourceSettings\" xml:space=\"preserve\">\n    <value>Obtenir les paramètres de configuration...</value>\n  </data>\n  <data name=\"ConfigureExportArgumentRequiredError\" xml:space=\"preserve\">\n    <value>Au moins --packageId et/ou --module avec --resource doit être fourni. Ou utilisez --all pour exporter toutes les configurations de package.</value>\n    <comment>{Locked=\"--packageId,--module, --resource, --all\"}</comment>\n  </data>\n  <data name=\"ConfigureExportArgumentConflictWithAllError\" xml:space=\"preserve\">\n    <value>Vous ne pouvez pas utiliser les arguments --packageId, --module et --resource avec --all.</value>\n    <comment>{Locked=\"--packageId,--module, --resource, --all\"}</comment>\n  </data>\n  <data name=\"ConfigureExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Exporte les ressources de configuration vers un fichier de configuration. Lorsqu’il est utilisé avec --all, exporte toutes les configurations de package. Lorsqu’il est utilisé avec --packageId, exporte une ressource WinGetPackage de l’ID de package donné. Lorsqu’il est utilisé avec --module et --resource, obtient les paramètres de la ressource et l’exporte vers le fichier de configuration. Si le fichier de configuration de sortie existe déjà, ajoute les ressources de configuration exportées.</value>\n    <comment>{Locked=\"WinGetPackage,--packageId,--module, --resource\"}</comment>\n  </data>\n  <data name=\"ConfigureExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Exporte les ressources de configuration vers un fichier de configuration.</value>\n  </data>\n  <data name=\"ConfigureExportModule\" xml:space=\"preserve\">\n    <value>Le module de la ressource à exporter.</value>\n  </data>\n  <data name=\"ConfigureExportPackageId\" xml:space=\"preserve\">\n    <value>L'identifiant du paquet à exporter.</value>\n  </data>\n  <data name=\"ConfigureExportResource\" xml:space=\"preserve\">\n    <value>La ressource de configuration à exporter.</value>\n  </data>\n  <data name=\"ConfigureExportAll\" xml:space=\"preserve\">\n    <value>Permet d’exporter toutes les configurations de package.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_GET_FAILED\" xml:space=\"preserve\">\n    <value>L'unité de configuration n'a pas réussi à obtenir ses propriétés.</value>\n  </data>\n  <data name=\"ConfigurationExportFailed\" xml:space=\"preserve\">\n    <value>Échec de l'exportation de la configuration.</value>\n  </data>\n  <data name=\"ConfigureExportUnitDescription\" xml:space=\"preserve\">\n    <value>Configuration de {0}</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigureExportUnitInstallDescription\" xml:space=\"preserve\">\n    <value>Installer {0}</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationWarningSetViewTruncated\" xml:space=\"preserve\">\n    <value>Certaines données présentes dans le fichier de configuration ont été tronquées pour cette sortie ; inspecter le contenu du fichier pour en obtenir le contenu complet.</value>\n  </data>\n  <data name=\"ConfigurationWarningValueTruncated\" xml:space=\"preserve\">\n    <value>&lt;cette valeur a été tronquée ; consultez le contenu du fichier pour obtenir le texte complet&gt;</value>\n    <comment>Keep some form of separator like the \"&lt;&gt;\" around the text so that it stands out from the preceding text.</comment>\n  </data>\n  <data name=\"ConfigureListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Affiche les détails de niveau supérieur pour les configurations qui ont été appliquées au système. Ces données peuvent ensuite être utilisées avec des commandes `configure` pour obtenir plus de détails.</value>\n    <comment>{Locked=\"`configure`\"}</comment>\n  </data>\n  <data name=\"ConfigureListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Affiche l’historique de configuration</value>\n  </data>\n  <data name=\"ConfigurationHistoryEmpty\" xml:space=\"preserve\">\n    <value>On ne trouve aucune configuration dans l'historique.</value>\n  </data>\n  <data name=\"ConfigurationHistoryItemArgumentDescription\" xml:space=\"preserve\">\n    <value>Sélectionner des éléments de l’historique</value>\n  </data>\n  <data name=\"ConfigurationHistoryItemNotFound\" xml:space=\"preserve\">\n    <value>Aucune configuration unique correspondant aux données fournies n’a été trouvée. Fournissez le nom complet ou une partie de l’identificateur qui correspond sans ambiguïté à la configuration souhaitée.</value>\n  </data>\n  <data name=\"ConfigurationHistoryRemoveArgumentDescription\" xml:space=\"preserve\">\n    <value>Supprimer l’élément de l’historique</value>\n  </data>\n  <data name=\"ConfigureListFirstApplied\" xml:space=\"preserve\">\n    <value>Première application</value>\n    <comment>Column header for date values indicating when a configuration was first applied to the system.</comment>\n  </data>\n  <data name=\"ConfigureListIdentifier\" xml:space=\"preserve\">\n    <value>Identificateur</value>\n  </data>\n  <data name=\"ConfigureListName\" xml:space=\"preserve\">\n    <value>Nom</value>\n  </data>\n  <data name=\"ConfigureListOrigin\" xml:space=\"preserve\">\n    <value>Origine</value>\n  </data>\n  <data name=\"ConfigureListPath\" xml:space=\"preserve\">\n    <value>Chemin d'accès</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_HISTORY_ITEM_NOT_FOUND\" xml:space=\"preserve\">\n    <value>La configuration spécifiée est introuvable.</value>\n  </data>\n  <data name=\"ConfigurationSetStateCompleted\" xml:space=\"preserve\">\n    <value>Terminé</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStateInProgress\" xml:space=\"preserve\">\n    <value>En cours</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStatePending\" xml:space=\"preserve\">\n    <value>En attente</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStateUnknown\" xml:space=\"preserve\">\n    <value>Inconnu</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationStatusWatchArgumentDescription\" xml:space=\"preserve\">\n    <value>Surveiller l’état de la configuration.</value>\n    <comment>As in \"to monitor the status of a configuration being applied\".</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateCompleted\" xml:space=\"preserve\">\n    <value>Terminé</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateInProgress\" xml:space=\"preserve\">\n    <value>En cours</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStatePending\" xml:space=\"preserve\">\n    <value>En attente</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateSkipped\" xml:space=\"preserve\">\n    <value>Ignoré</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateUnknown\" xml:space=\"preserve\">\n    <value>Inconnu</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigureListApplyBegun\" xml:space=\"preserve\">\n    <value>Application démarrée</value>\n    <comment>When the configuration application started.</comment>\n  </data>\n  <data name=\"ConfigureListApplyEnded\" xml:space=\"preserve\">\n    <value>Fin de l’application</value>\n    <comment>When the configuration application ended.</comment>\n  </data>\n  <data name=\"ConfigureListResult\" xml:space=\"preserve\">\n    <value>Résultat</value>\n  </data>\n  <data name=\"ConfigureListResultDescription\" xml:space=\"preserve\">\n    <value>Détails</value>\n  </data>\n  <data name=\"ConfigureListState\" xml:space=\"preserve\">\n    <value>État</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigureListUnit\" xml:space=\"preserve\">\n    <value>Unité</value>\n  </data>\n  <data name=\"StoreInstall_PackageNotAvailableForCurrentSystem\" xml:space=\"preserve\">\n    <value>Le package n’est pas compatible avec la version ou la plateforme Windows actuelle.</value>\n  </data>\n  <data name=\"ConfigurationSuppressPrologueArgumentDescription\" xml:space=\"preserve\">\n    <value>Supprimer l’affichage des détails de configuration initiale lorsque cela est possible</value>\n  </data>\n  <data name=\"MSStoreDownloadMultiplePackagesNotice\" xml:space=\"preserve\">\n    <value>Vous pouvez télécharger plusieurs packages Microsoft Store ciblant différentes plateformes et architectures. --platform, --architecture peuvent être utilisés pour filtrer les packages.</value>\n    <comment>{Locked=\"--platform--architecture\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseForbidden\" xml:space=\"preserve\">\n    <value>Échec de la récupération de Microsoft Store licence de package. Le compte d’ID Microsoft Entra n’est pas membre de l’administrateur général, de l’administrateur d’utilisateurs ou de l’administrateur de licences. Utilisez --skip-license pour ignorer la récupération Microsoft Store licence de package.</value>\n    <comment>{Locked=\"Global Administrator,User Administrator,License Administrator,--skip-license\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadNotSupported\" xml:space=\"preserve\">\n    <value>Le package Microsoft Store ne prend pas en charge le téléchargement.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SFSCLIENT_PACKAGE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Le package Microsoft Store ne prend pas en charge le téléchargement.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED_FORBIDDEN\" xml:space=\"preserve\">\n    <value>Échec de la récupération de Microsoft Store licence de package. Le compte d’ID Microsoft Entra ne dispose pas des privilèges requis.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_PARAMETER_INTEGRITY_BOUNDARY\" xml:space=\"preserve\">\n    <value>Le paramètre ne peut pas être transmis au-delà de la limite d’intégrité.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_ZERO_BYTE_FILE\" xml:space=\"preserve\">\n    <value>Programme d’installation zéro octet téléchargé ; vérifiez que votre connexion réseau fonctionne correctement.</value>\n  </data>\n  <data name=\"InstallerZeroByteFile\" xml:space=\"preserve\">\n    <value>Programme d’installation zéro octet téléchargé ; vérifiez que votre connexion réseau fonctionne correctement.</value>\n  </data>\n  <data name=\"FontCommandShortDescription\" xml:space=\"preserve\">\n    <value>Gérer les polices</value>\n  </data>\n  <data name=\"FontCommandLongDescription\" xml:space=\"preserve\">\n    <value>Gérez les polices avec des sous-commandes. Les polices peuvent être installées, mises à niveau ou désinstallées similaires à packages. </value>\n  </data>\n  <data name=\"FontFamily\" xml:space=\"preserve\">\n    <value>Famille</value>\n  </data>\n  <data name=\"FontFaces\" xml:space=\"preserve\">\n    <value>Visages</value>\n    <comment>\"Faces\" represents the typeface of the font family such as 'Bold' or 'Italic'</comment>\n  </data>\n  <data name=\"FontFamilyNameArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtrer les résultats par nom de famille</value>\n  </data>\n  <data name=\"FontFace\" xml:space=\"preserve\">\n    <value>Visage</value>\n    <comment>\"Face\" represents the typeface of a font family such as 'Bold' or 'Italic'</comment>\n  </data>\n  <data name=\"FontFilePaths\" xml:space=\"preserve\">\n    <value>Chemins d'accès</value>\n  </data>\n  <data name=\"NoInstalledFontFound\" xml:space=\"preserve\">\n    <value>Aucune police installée ne correspond aux critères d'entrée.</value>\n  </data>\n  <data name=\"FontListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Répertorier les polices installées</value>\n  </data>\n  <data name=\"FontListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Répertoriez toutes les polices installées, tous les fichiers de police ou tous les détails d’une police spécifique.</value>\n  </data>\n  <data name=\"FontVersion\" xml:space=\"preserve\">\n    <value>Version</value>\n  </data>\n  <data name=\"ConfigurationModules\" xml:space=\"preserve\">\n    <value>Modules de configuration</value>\n    <comment>PowerShell Modules that are used for the Configuration feature</comment>\n  </data>\n  <data name=\"InstallerDownloadRequiresAuthentication\" xml:space=\"preserve\">\n    <value>Le programme d’installation du package nécessite une authentification. L’invite d’authentification peut s’afficher en cas de besoin. Les informations authentifiées seront partagées avec l’URL de téléchargement du programme d’installation.</value>\n  </data>\n  <data name=\"InstallerDownloadAuthenticationNotSupported\" xml:space=\"preserve\">\n    <value>Échec du téléchargement du programme d’installation. Cette version winget ne prend pas en charge la méthode d’authentification de téléchargement du programme d’installation. Essayez de mettre à niveau vers la dernière version winget.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"InstallerDownloadAuthenticationFailed\" xml:space=\"preserve\">\n    <value>Le téléchargement du programme d'installation a échoué. L'authentification a échoué.</value>\n  </data>\n  <data name=\"ConfigurationProcessorPath\" xml:space=\"preserve\">\n    <value>Spécifiez le chemin d’accès au processeur de configuration</value>\n  </data>\n  <data name=\"DscCommandShortDescription\" xml:space=\"preserve\">\n    <value>Commandes de ressources DSC v3</value>\n    <comment>DSC stands for \"Desired State Configuration\". It should already have a locked translation.</comment>\n  </data>\n  <data name=\"DscCommandLongDescription\" xml:space=\"preserve\">\n    <value>Les sous-commandes implémentent ici des ressources Desired State Configuration (DSC) v3 pour configurer winget et packages.</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionGet\" xml:space=\"preserve\">\n    <value>Obtenir l’état de la ressource</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionSet\" xml:space=\"preserve\">\n    <value>Définir l’état de la ressource</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionWhatIf\" xml:space=\"preserve\">\n    <value>Décrire les changements d’état requis</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionTest\" xml:space=\"preserve\">\n    <value>Tester l’état de la ressource</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionDelete\" xml:space=\"preserve\">\n    <value>Supprimer l’état de la ressource</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionExport\" xml:space=\"preserve\">\n    <value>Obtenir toutes les instances d’état</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionValidate\" xml:space=\"preserve\">\n    <value>Valider le contenu du groupe</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionResolve\" xml:space=\"preserve\">\n    <value>Résoudre l’état externe</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionAdapter\" xml:space=\"preserve\">\n    <value>Exécuter l’adaptateur</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionSchema\" xml:space=\"preserve\">\n    <value>Obtenir le schéma de ressource</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionManifest\" xml:space=\"preserve\">\n    <value>Obtenir le manifeste de ressource</value>\n  </data>\n  <data name=\"DscPackageResourceShortDescription\" xml:space=\"preserve\">\n    <value>Gérer l’état du package</value>\n  </data>\n  <data name=\"DscPackageResourceLongDescription\" xml:space=\"preserve\">\n    <value>Gérez les packages via WinGet.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionExist\" xml:space=\"preserve\">\n    <value>Indique si un instance doit ou existe.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionInDesiredState\" xml:space=\"preserve\">\n    <value>Indique si un instance est dans l’état souhaité.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageId\" xml:space=\"preserve\">\n    <value>Identificateur du package.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageSource\" xml:space=\"preserve\">\n    <value>Source du package.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageVersion\" xml:space=\"preserve\">\n    <value>Version du package.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageMatchOption\" xml:space=\"preserve\">\n    <value>Méthode de mise en correspondance de l’identificateur avec un package.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageUseLatest\" xml:space=\"preserve\">\n    <value>Indiquez que la dernière version disponible du package doit être installée.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageInstallMode\" xml:space=\"preserve\">\n    <value>Mode d’installation à utiliser si nécessaire.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageScope\" xml:space=\"preserve\">\n    <value>Étendue cible du package.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionAcceptAgreements\" xml:space=\"preserve\">\n    <value>Indique s’il faut accepter les contrats pour les sources et les packages.</value>\n  </data>\n  <data name=\"DscUserSettingsFileShortDescription\" xml:space=\"preserve\">\n    <value>Gérer le fichier de paramètres utilisateur</value>\n  </data>\n  <data name=\"DscUserSettingsFileLongDescription\" xml:space=\"preserve\">\n    <value>Gérez les paramètres utilisateur de WinGet.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionUserSettingsFileSettings\" xml:space=\"preserve\">\n    <value>Contenu du fichier JSON des paramètres.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionUserSettingsFileAction\" xml:space=\"preserve\">\n    <value>Action utilisée pour appliquer les paramètres.</value>\n  </data>\n  <data name=\"CorrelationArgumentDescription\" xml:space=\"preserve\">\n    <value>La valeur est journalisée pour corrélation</value>\n  </data>\n  <data name=\"DscSourceResourceShortDescription\" xml:space=\"preserve\">\n    <value>Gérer la configuration de la source</value>\n  </data>\n  <data name=\"DscSourceResourceLongDescription\" xml:space=\"preserve\">\n    <value>Gérez les sources de WinGet.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceName\" xml:space=\"preserve\">\n    <value>Nom à utiliser pour la source.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceArgument\" xml:space=\"preserve\">\n    <value>Argument de la source.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceType\" xml:space=\"preserve\">\n    <value>Type de la source.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceTrustLevel\" xml:space=\"preserve\">\n    <value>Niveau de confiance de la source.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceExplicit\" xml:space=\"preserve\">\n    <value>Indique si la source est incluse lorsque les appels ne spécifient pas de source.</value>\n  </data>\n  <data name=\"ConfigurationApplyingUnit\" xml:space=\"preserve\">\n    <value>Application de l’unité de configuration...</value>\n  </data>\n  <data name=\"ConfigurationExportingUnit\" xml:space=\"preserve\">\n    <value>Exportation de l’unité de configuration...</value>\n  </data>\n  <data name=\"ConfigurationGettingUnitProcessors\" xml:space=\"preserve\">\n    <value>Obtention des processeurs d’unité de configuration...</value>\n  </data>\n  <data name=\"ConfigurationExportInstallRequiredModule\" xml:space=\"preserve\">\n    <value>Vérifier le module requis pour l’exportation [{0}]</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportInstallRequiredModuleFailed\" xml:space=\"preserve\">\n    <value>Échec du test ou de l’acquisition du module requis. Les paramètres associés ne seront pas exportés.</value>\n  </data>\n  <data name=\"ConfigurationExportUnitStart\" xml:space=\"preserve\">\n    <value>Exporter [{0}]</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportUnitFailed\" xml:space=\"preserve\">\n    <value>Échec de l’exportation de la ressource.</value>\n  </data>\n  <data name=\"ConfigurationExportFailedToGetUnitProcessors\" xml:space=\"preserve\">\n    <value>Échec de l’obtention des processeurs d’unités. Les paramètres de package individuels ne seront pas exportés.</value>\n  </data>\n  <data name=\"OutputDirectoryArgumentDescription\" xml:space=\"preserve\">\n    <value>Répertoire dans lequel les résultats doivent être écrits</value>\n  </data>\n  <data name=\"ConfigurationInstallDscPackage\" xml:space=\"preserve\">\n    <value>Desired State Configuration package introuvable sur le système. Installation du package...</value>\n  </data>\n  <data name=\"ConfigurationInstallDscPackageFailed\" xml:space=\"preserve\">\n    <value>Échec de l’installation du package Desired State Configuration. Installez le package manuellement ou indiquez le chemin d’accès à dsc.exe via --processor-path argument.</value>\n    <comment>{Locked=\"dsc.exe\",\"--processor-path\"}</comment>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionAdminSettingsSettings\" xml:space=\"preserve\">\n    <value>Objet contenant les paramètres de l’administrateur et leurs valeurs.</value>\n  </data>\n  <data name=\"DscAdminSettingsResourceShortDescription\" xml:space=\"preserve\">\n    <value>Gérer les paramètres de l’administrateur</value>\n  </data>\n  <data name=\"DscAdminSettingsResourceLongDescription\" xml:space=\"preserve\">\n    <value>Gérez les paramètres d’administrateur de WinGet.</value>\n  </data>\n  <data name=\"ResetAllAdminSettingsArgumentDescription\" xml:space=\"preserve\">\n    <value>Réinitialise tous les paramètres d’administration</value>\n  </data>\n  <data name=\"ResetAllAdminSettingsSucceeded\" xml:space=\"preserve\">\n    <value>Tous les paramètres d’administration ont été réinitialisés.</value>\n  </data>\n  <data name=\"McpCommandShortDescription\" xml:space=\"preserve\">\n    <value>Informations MCP</value>\n    <comment>MCP stands for Model Context Protocol and should probably remain as-is</comment>\n  </data>\n  <data name=\"McpCommandLongDescription\" xml:space=\"preserve\">\n    <value>Informations MCP (Model Context Protocol) pour le Gestionnaire de package Windows.</value>\n  </data>\n  <data name=\"McpConfigurationPreamble\" xml:space=\"preserve\">\n    <value>Pour configurer manuellement le serveur Gestionnaire de package Windows MCP avec votre client MCP, utilisez le fragment JSON suivant dans l’objet `servers` :</value>\n    <comment>{Locked=\"`servers`\"}\nMCP stands for Model Context Protocol and should probably remain as-is.\nAn unlocalized JSON fragment will follow on another line.</comment>\n  </data>\n  <data name=\"PolicyEnableMcpServer\" xml:space=\"preserve\">\n    <value>Activer le serveur MCP du Gestionnaire de package Windows</value>\n  </data>\n  <data name=\"OSVersionDescription\" xml:space=\"preserve\">\n    <value>Version du système d’exploitation cible</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Désolé, échec de l’installation d’une ou plusieurs polices.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Désolé, le fichier de police n’est pas pris en charge et ne peut pas être installé.</value>\n  </data>\n  <data name=\"FontFileNotSupported\" xml:space=\"preserve\">\n    <value>Une ou plusieurs polices du package de polices ne sont pas prises en charge et ne peuvent pas être installées.</value>\n  </data>\n  <data name=\"FontInstallFailed\" xml:space=\"preserve\">\n    <value>Désolé, nous n’avons pas pu effectuer l’installation; nettoyage en cours.</value>\n  </data>\n  <data name=\"FontAlreadyInstalled\" xml:space=\"preserve\">\n    <value>La police est déjà installée.</value>\n  </data>\n  <data name=\"FontPackage\" xml:space=\"preserve\">\n    <value>ID de package</value>\n  </data>\n  <data name=\"FontWinGetSupported\" xml:space=\"preserve\">\n    <value>WinGet pris en charge</value>\n  </data>\n  <data name=\"FontTitle\" xml:space=\"preserve\">\n    <value>Titre</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Fichier de police introuvable.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Échec de la désinstallation de la police. La police n’est peut-être pas en bon état. Essayez de désinstaller après un redémarrage.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>La validation de la police a échoué.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_ROLLBACK_FAILED\" xml:space=\"preserve\">\n    <value>Échec de la restauration de police. La police n’est peut-être pas en bon état. Essayez de désinstaller après un redémarrage.</value>\n  </data>\n  <data name=\"FontDetailsArgumentDescription\" xml:space=\"preserve\">\n    <value>Afficher les informations détaillées du fichier de police.</value>\n  </data>\n  <data name=\"FontValidationFailed\" xml:space=\"preserve\">\n    <value>Désolé, échec de la validation du package de polices.</value>\n  </data>\n  <data name=\"FontRollbackFailed\" xml:space=\"preserve\">\n    <value>La tentative de restauration de l’installation de police ayant échoué a échoué. Un redémarrage peut être nécessaire pour désinstaller la police.</value>\n  </data>\n  <data name=\"FontUninstallFailed\" xml:space=\"preserve\">\n    <value>Échec de la désinstallation du package de polices. Cela est souvent dû aux polices utilisées par le système ou une application. La désinstallation peut réussir après le redémarrage de votre ordinateur.</value>\n  </data>\n  <data name=\"FontStatusOK\" xml:space=\"preserve\">\n    <value>OK</value>\n    <comment>\"OK\" means the font is in a good healthy state</comment>\n  </data>\n  <data name=\"FontStatusCorrupt\" xml:space=\"preserve\">\n    <value>Endommagé</value>\n    <comment>\"Corrupt\" refers to an install that is in a corrupted or bad state, and needs repair.</comment>\n  </data>\n  <data name=\"FontStatus\" xml:space=\"preserve\">\n    <value>Statut</value>\n  </data>\n  <data name=\"FontStatusUnknown\" xml:space=\"preserve\">\n    <value>Inconnu</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>Le package de polices est déjà installé.</value>\n  </data>\n  <data name=\"ListDetailsArgumentDescription\" xml:space=\"preserve\">\n    <value>Afficher des informations détaillées sur les packages</value>\n    <comment>Providing this argument causes the CLI to output additional details about installed application packages.</comment>\n  </data>\n  <data name=\"ShowLabelChannel\" xml:space=\"preserve\">\n    <value>Canal :</value>\n    <comment>Precedes a string value that names the delivery channel for the software package (ex. stable, beta).</comment>\n  </data>\n  <data name=\"ShowListLocalIdentifier\" xml:space=\"preserve\">\n    <value>Identifiant local :</value>\n    <comment>Precedes a value that is the unique identifier for the installed package on the local system.</comment>\n  </data>\n  <data name=\"ShowListPackageFamilyName\" xml:space=\"preserve\">\n    <value>Nom de la famille de packages :</value>\n    <comment>Precedes a value that is the APPX/MSIX package family name of the installed package.</comment>\n  </data>\n  <data name=\"ShowListProductCode\" xml:space=\"preserve\">\n    <value>Code du produit :</value>\n    <comment>Precedes a value that is the Add/Remove Programs identifier in the registry. This is also the Product Code value as defined in MSI installers.</comment>\n  </data>\n  <data name=\"ShowListUpgradeCode\" xml:space=\"preserve\">\n    <value>Code de mise à niveau :</value>\n    <comment>Precedes a value that is the MSI Upgrade Code for the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledScope\" xml:space=\"preserve\">\n    <value>Étendue de l’installation :</value>\n    <comment>Precedes a value that is the scope of the installation of the package (ex. user, machine).</comment>\n  </data>\n  <data name=\"ShowListInstalledArchitecture\" xml:space=\"preserve\">\n    <value>Architecture installée :</value>\n    <comment>Precedes a value that is the installed architecture of the package (ex. x86, x64, ARM64).</comment>\n  </data>\n  <data name=\"ShowListInstalledLocale\" xml:space=\"preserve\">\n    <value>Paramètres régionaux de l’installation :</value>\n    <comment>Precedes a value that is the locale of the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledLocation\" xml:space=\"preserve\">\n    <value>Emplacement de l’installation :</value>\n    <comment>Precedes a value that is the directory path to the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledSource\" xml:space=\"preserve\">\n    <value>Source d’origine :</value>\n    <comment>Precedes a value that names the package source where the installed package originated from.</comment>\n  </data>\n  <data name=\"ShowListAvailableUpgrades\" xml:space=\"preserve\">\n    <value>Mises à niveau disponibles :</value>\n    <comment>Precedes a list of package upgrades available for the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstallerCategory\" xml:space=\"preserve\">\n    <value>Catégorie du programme d’installation :</value>\n    <comment>Precedes a value that indicates the category of the installer for the installed package (ex. exe, msi, msix).</comment>\n  </data>\n  <data name=\"SourceEditOldValue\" xml:space=\"preserve\">\n    <value>Ancienne valeur</value>\n    <comment>Column title for listing edit changes.</comment>\n  </data>\n  <data name=\"SourceEditNewValue\" xml:space=\"preserve\">\n    <value>Nouvelle valeur</value>\n    <comment>Column title for listing the new value.</comment>\n  </data>\n</root>"
  },
  {
    "path": "Localization/Resources/it-IT/Resources.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "Localization/Resources/it-IT/winget.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"AdjoinedNotFlagError\" xml:space=\"preserve\">\n    <value>L'alias adiacente non è un contrassegno: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an adjoined alias that is not a flag argument. {0} is a placeholder replaced by the user input argument (e.g. '-ab').</comment>\n  </data>\n  <data name=\"AdjoinedNotFoundError\" xml:space=\"preserve\">\n    <value>Alias del contrassegno adiacente non trovato: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an adjoined flag alias argument that was not found. {0} is a placeholder replaced by the user input argument (e.g. '-ab').</comment>\n  </data>\n  <data name=\"AvailableArguments\" xml:space=\"preserve\">\n    <value>Sono disponibili i seguenti argomenti:</value>\n    <comment>Message displayed to inform the user about the available command line arguments.</comment>\n  </data>\n  <data name=\"AvailableCommandAliases\" xml:space=\"preserve\">\n    <value>Sono disponibili gli alias di comando seguenti:</value>\n    <comment>Message displayed to inform the user about the available command line alias arguments.</comment>\n  </data>\n  <data name=\"AvailableCommands\" xml:space=\"preserve\">\n    <value>Sono disponibili i seguenti comandi:</value>\n    <comment>Title displayed to inform the user about the available commands.</comment>\n  </data>\n  <data name=\"AvailableHeader\" xml:space=\"preserve\">\n    <value>Disponibile</value>\n    <comment>As in \"a new version is available to upgrade to\".</comment>\n  </data>\n  <data name=\"AvailableOptions\" xml:space=\"preserve\">\n    <value>Sono disponibili le seguenti opzioni:</value>\n    <comment>Message displayed to inform the user about the available options.</comment>\n  </data>\n  <data name=\"AvailableSubcommands\" xml:space=\"preserve\">\n    <value>Sono disponibili i seguenti comandi secondari:</value>\n    <comment>Message displayed to inform the user about the available nested commands that run in context of the selected command.</comment>\n  </data>\n  <data name=\"AvailableUpgrades\" xml:space=\"preserve\">\n    <value>{0} aggiornamenti disponibili.</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about available package upgrades. {0} is a placeholder replaced by the number of package upgrades.</comment>\n  </data>\n  <data name=\"ChannelArgumentDescription\" xml:space=\"preserve\">\n    <value>Usa il canale specificato; l'impostazione predefinita è General Audience (adatto a tutte le età)</value>\n  </data>\n  <data name=\"Command\" xml:space=\"preserve\">\n    <value>comando</value>\n    <comment>Label displayed for a command to give the software.</comment>\n  </data>\n  <data name=\"CommandArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtra i risultati per comando</value>\n    <comment>Description message displayed to inform the user about filtering the search results by a package command.</comment>\n  </data>\n  <data name=\"CommandLineArgumentDescription\" xml:space=\"preserve\">\n    <value>Riga di comando completa per il completamento</value>\n  </data>\n  <data name=\"CommandRequiresAdmin\" xml:space=\"preserve\">\n    <value>Questo comando richiede i privilegi di amministratore per l'esecuzione.</value>\n  </data>\n  <data name=\"CompleteCommandLongDescription\" xml:space=\"preserve\">\n    <value>Questo comando può essere utilizzato per richiedere il completamento della riga di comando sensibile al contesto. Vengono inseriti i dati della riga di comando, della posizione del cursore e della parola da completare. L'output è un insieme di valori possibili in base agli input, con un valore possibile per riga.</value>\n  </data>\n  <data name=\"CompleteCommandShortDescription\" xml:space=\"preserve\">\n    <value>Abilita il completamento della riga di comando con contesto</value>\n  </data>\n  <data name=\"CountArgumentDescription\" xml:space=\"preserve\">\n    <value>Non mostra più del numero di risultati specificato (compreso tra 1 e 1000)</value>\n  </data>\n  <data name=\"Done\" xml:space=\"preserve\">\n    <value>Fatto</value>\n    <comment>Label displayed when an operation completes or is done executing.</comment>\n  </data>\n  <data name=\"ExactArgumentDescription\" xml:space=\"preserve\">\n    <value>Trova pacchetto con corrispondenza esatta</value>\n    <comment>Description message displayed to inform the user about finding an application package using an exact matching criteria.</comment>\n  </data>\n  <data name=\"ExperimentalArgumentDescription\" xml:space=\"preserve\">\n    <value>Argomento sperimentale a scopo dimostrativo</value>\n  </data>\n  <data name=\"ExperimentalCommandLongDescription\" xml:space=\"preserve\">\n    <value>Questo comando è un esempio su come implementare una funzionalità sperimentale. Per attivare l'opzione “winget settings” e abilitare le funzionalità experimentalCmd o experimentalArg.</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"ExperimentalCommandShortDescription\" xml:space=\"preserve\">\n    <value>Esempio di funzionalità sperimentale</value>\n  </data>\n  <data name=\"ExtraPositionalError\" xml:space=\"preserve\">\n    <value>È stato trovato un argomento posizionale quando non ne era previsto nessuno: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an extra positional argument when none was expected. {0} is a placeholder replaced by the user's extra argument input.</comment>\n  </data>\n  <data name=\"FeatureDisabledMessage\" xml:space=\"preserve\">\n    <value>Questa funzionalità è in fase di sviluppo e potrebbe essere modificata completamente o rimossa del tutto in futuro. Per abilitarla, modificare le impostazioni ('winget settings') per includere la funzionalità sperimentale: '{0}'</value>\n    <comment>{Locked=\"winget settings\",\"{0}\"}. Error message displayed when the user uses an experimental feature that is disabled. {0} is a placeholder replaced by the experimental feature name.</comment>\n  </data>\n  <data name=\"FeaturesCommandLongDescription\" xml:space=\"preserve\">\n    <value>Mostra lo stato delle funzionalità sperimentali. Le funzionalità sperimentali possono essere attivate tramite 'winget settings'.</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"FeaturesCommandShortDescription\" xml:space=\"preserve\">\n    <value>Mostra lo stato delle funzionalità sperimentali</value>\n  </data>\n  <data name=\"FeaturesDisabled\" xml:space=\"preserve\">\n    <value>Disabilitate</value>\n  </data>\n  <data name=\"FeaturesEnabled\" xml:space=\"preserve\">\n    <value>Abilitata</value>\n  </data>\n  <data name=\"FeaturesFeature\" xml:space=\"preserve\">\n    <value>Funzionalità</value>\n  </data>\n  <data name=\"FeaturesLink\" xml:space=\"preserve\">\n    <value>Collegamento</value>\n  </data>\n  <data name=\"FeaturesMessage\" xml:space=\"preserve\">\n    <value>Le seguenti funzionalità sperimentali sono in corso.\nPossono essere configurati tramite il file di impostazioni ' winget settings '.</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"FeaturesProperty\" xml:space=\"preserve\">\n    <value>Proprietà</value>\n  </data>\n  <data name=\"FeaturesStatus\" xml:space=\"preserve\">\n    <value>Stato</value>\n  </data>\n  <data name=\"FileArgumentDescription\" xml:space=\"preserve\">\n    <value>File su cui eseguire l'hashing</value>\n  </data>\n  <data name=\"FlagContainAdjoinedError\" xml:space=\"preserve\">\n    <value>L'argomento del contrassegno non può contenere un valore adiacente: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a flag argument containing an unexpected adjoined value. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"HashCommandLongDescription\" xml:space=\"preserve\">\n    <value>Calcola l'hash di un file locale, appropriato per l'ingresso in un manifesto. Può anche calcolare l'hash del file della firma di un pacchetto MSIX per abilitare le installazioni di streaming multimediale.</value>\n  </data>\n  <data name=\"HashCommandShortDescription\" xml:space=\"preserve\">\n    <value>Helper per eseguire l'hashing dei file di installazione</value>\n  </data>\n  <data name=\"HelpArgumentDescription\" xml:space=\"preserve\">\n    <value>Mostra la guida per il comando selezionato</value>\n  </data>\n  <data name=\"HelpForDetails\" xml:space=\"preserve\">\n    <value>Per altre informazioni su un comando specifico, passa alla Guida degli argomenti.</value>\n  </data>\n  <data name=\"HelpLinkPreamble\" xml:space=\"preserve\">\n    <value>Altre informazioni sono disponibili alla pagina: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a link where they can learn more about the subject context. {0} is a placeholder replaced by a website address.</comment>\n  </data>\n  <data name=\"IdArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtra i risultati per ID</value>\n  </data>\n  <data name=\"IgnoreWarningsArgumentDescription\" xml:space=\"preserve\">\n    <value>Elimina gli output di avviso</value>\n  </data>\n  <data name=\"InstallationDisclaimer1\" xml:space=\"preserve\">\n    <value>Questa applicazione viene concessa in licenza dal proprietario.</value>\n  </data>\n  <data name=\"InstallationDisclaimer2\" xml:space=\"preserve\">\n    <value>Microsoft non è responsabile né concede alcuna licenza a pacchetti di terze parti.</value>\n  </data>\n  <data name=\"InstallationDisclaimerMSStore\" xml:space=\"preserve\">\n    <value>Questo pacchetto è stato fornito tramite Microsoft Store. winget potrebbe dover acquisire il pacchetto da Microsoft Store per conto dell'utente corrente.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"InstallCommandLongDescription\" xml:space=\"preserve\">\n    <value>Installa il pacchetto selezionato, trovato eseguendo una ricerca in un'origine configurata o direttamente da un manifesto. Per impostazione predefinita, la query deve corrispondere senza distinzione tra maiuscole e minuscole all'id, name o moniker del pacchetto. È possibile usare altri campi passando l'opzione appropriata. Per impostazione predefinita, il comando install controllerà lo stato di installazione del pacchetto e tenterà di eseguire un aggiornamento, se applicabile. Eseguire l'override con --force per eseguire un'installazione diretta.</value>\n    <comment>{Locked=\"--force\"}; id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"InstallCommandShortDescription\" xml:space=\"preserve\">\n    <value>Installa il pacchetto specificato</value>\n  </data>\n  <data name=\"InstallerHashMismatchAdminBlock\" xml:space=\"preserve\">\n    <value>Hash di installazione non corrispondente. Questo non può essere ignorato durante l'esecuzione come amministratore</value>\n  </data>\n  <data name=\"InstallerHashMismatchOverridden\" xml:space=\"preserve\">\n    <value>L’hash di installazione non corrisponde. Procedendo a causa di --ignore-security-hash</value>\n    <comment>{Locked=\"--ignore-security-hash\"}</comment>\n  </data>\n  <data name=\"InstallerHashMismatchOverrideRequired\" xml:space=\"preserve\">\n    <value>Hash di installazione non corrispondente; Per eseguire l’override, seleziona use --ignore-security-hash</value>\n    <comment>{Locked=\"--ignore-security-hash\"}</comment>\n  </data>\n  <data name=\"InstallerHashVerified\" xml:space=\"preserve\">\n    <value>Verifica dell'hash di installazione completata</value>\n  </data>\n  <data name=\"InstallFlowInstallSuccess\" xml:space=\"preserve\">\n    <value>Installazione riuscita</value>\n  </data>\n  <data name=\"InstallFlowStartingPackageInstall\" xml:space=\"preserve\">\n    <value>Avvio installazione pacchetto in corso...</value>\n  </data>\n  <data name=\"HashOverrideArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignora l'errore di controllo hash del programma di installazione</value>\n  </data>\n  <data name=\"IgnoreLocalArchiveMalwareScanArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignora l'analisi malware eseguita durante l'installazione di un pacchetto di tipo di archivio dal manifesto locale</value>\n  </data>\n  <data name=\"InteractiveArgumentDescription\" xml:space=\"preserve\">\n    <value>Richiedi l'installazione interattiva; l'input dell'utente potrebbe essere necessario</value>\n  </data>\n  <data name=\"InvalidAliasError\" xml:space=\"preserve\">\n    <value>Alias di argomento non riconosciuto per il comando corrente: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a command line argument alias that was not recognized for a selected command. {0} is a placeholder replaced by the user's argument alias input (e.g. '-a').</comment>\n  </data>\n  <data name=\"InvalidArgumentSpecifierError\" xml:space=\"preserve\">\n    <value>Identificatore di argomento non valido: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an invalid argument specifier. {0} is a placeholder replaced by an argument specifier (e.g. '-').</comment>\n  </data>\n  <data name=\"InvalidNameError\" xml:space=\"preserve\">\n    <value>Nome argomento non riconosciuto per il comando corrente: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an unrecognized command line argument name for the selected command. {0} is a placeholder replaced by the user's argument name input (e.g. '--example').</comment>\n  </data>\n  <data name=\"KeyDirectoriesHeader\" xml:space=\"preserve\">\n    <value>Directory WinGet</value>\n    <comment>Header for a table detailing the directories Winget uses for key operations like logging and portable installs</comment>\n  </data>\n  <data name=\"LocaleArgumentDescription\" xml:space=\"preserve\">\n    <value>Impostazioni locali da usare (formato BCP47)</value>\n    <comment>{Locked=\"BCP47\"}</comment>\n  </data>\n  <data name=\"LicenseAgreement\" xml:space=\"preserve\">\n    <value>Contratto di licenza</value>\n  </data>\n  <data name=\"Links\" xml:space=\"preserve\">\n    <value>Collegamenti</value>\n    <comment>Links to different webpages</comment>\n  </data>\n  <data name=\"ListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Il comando list mostra i pacchetti installati nel sistema nonché la disponibilità di un aggiornamento. È possibile fornire opzioni aggiuntive per filtrare l'output, molto simili al comando search.</value>\n    <comment>{Locked=\"list\",\"search\"}</comment>\n  </data>\n  <data name=\"ListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Visualizza pacchetti installati</value>\n  </data>\n  <data name=\"LocationArgumentDescription\" xml:space=\"preserve\">\n    <value>Percorso di installazione (se supportato)</value>\n  </data>\n  <data name=\"LogArgumentDescription\" xml:space=\"preserve\">\n    <value>Percorso log (se supportato)</value>\n  </data>\n  <data name=\"MainCopyrightNotice\" xml:space=\"preserve\">\n    <value>Copyright (c) Microsoft Corporation. Tutti i diritti sono riservati.</value>\n  </data>\n  <data name=\"MainHomepage\" xml:space=\"preserve\">\n    <value>Home page</value>\n    <comment>The primary webpage for the software</comment>\n  </data>\n  <data name=\"ManifestArgumentDescription\" xml:space=\"preserve\">\n    <value>Percorso del manifesto del pacchetto</value>\n  </data>\n  <data name=\"ManifestValidationFail\" xml:space=\"preserve\">\n    <value>Convalida del manifesto non riuscita.</value>\n  </data>\n  <data name=\"ManifestValidationSuccess\" xml:space=\"preserve\">\n    <value>Convalida del manifesto riuscita.</value>\n  </data>\n  <data name=\"ManifestValidationWarning\" xml:space=\"preserve\">\n    <value>La convalida del manifesto è stata effettuata con avvisi.</value>\n  </data>\n  <data name=\"MissingArgumentError\" xml:space=\"preserve\">\n    <value>Il valore dell'argomento necessario risulta mancante: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user does not provide a required command line argument value. {0} is a placeholder replaced by the argument name.</comment>\n  </data>\n  <data name=\"MonikerArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtra i risultati in base al moniker</value>\n  </data>\n  <data name=\"MsixArgumentDescription\" xml:space=\"preserve\">\n    <value>Il file di input verrà considerato come MSIX; l'hash della firma verrà fornito se firmato</value>\n  </data>\n  <data name=\"MsixSignatureHashFailed\" xml:space=\"preserve\">\n    <value>Non è possibile calcolare l'hash della firma MSIX.</value>\n  </data>\n  <data name=\"MSStoreAppBlocked\" xml:space=\"preserve\">\n    <value>Non è stato possibile installare o aggiornare il pacchetto di Microsoft Store perché l'app specifica è bloccata dai criteri</value>\n  </data>\n  <data name=\"MSStoreInstallOrUpdateFailed\" xml:space=\"preserve\">\n    <value>Non è stato possibile installare o aggiornare il pacchetto di Microsoft Store. Codice di errore: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Microsoft Store application package fails to install or upgrade. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"MSStoreStoreClientBlocked\" xml:space=\"preserve\">\n    <value>Non è stato possibile installare o aggiornare il pacchetto Microsoft Store perché il client Microsoft Store è bloccato dai criteri</value>\n  </data>\n  <data name=\"MSStoreInstallTryGetEntitlement\" xml:space=\"preserve\">\n    <value>Verifica/richiesta di acquisizione pacchetti...</value>\n  </data>\n  <data name=\"MultipleInstalledPackagesFound\" xml:space=\"preserve\">\n    <value>Trovati più pacchetti installati corrispondenti ai criteri di input. Ridefinire l'input.</value>\n  </data>\n  <data name=\"MultiplePackagesFound\" xml:space=\"preserve\">\n    <value>Multipli pacchetti hanno trovato criteri di input corrispondenti. Ridefinisci l'input.</value>\n  </data>\n  <data name=\"NameArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtra i risultati per nome</value>\n  </data>\n  <data name=\"NoApplicableInstallers\" xml:space=\"preserve\">\n    <value>Nessun programma di installazione applicabile trovato. Per ulteriori dettagli, vedere i log.</value>\n  </data>\n  <data name=\"NoExperimentalFeaturesMessage\" xml:space=\"preserve\">\n    <value>Al momento non sono disponibili funzionalità sperimentali.</value>\n  </data>\n  <data name=\"NoInstalledPackageFound\" xml:space=\"preserve\">\n    <value>Non è stato trovato alcun pacchetto installato corrispondente ai criteri di input.</value>\n  </data>\n  <data name=\"NoPackageFound\" xml:space=\"preserve\">\n    <value>Nessun pacchetto trovato con criteri di input corrispondenti.</value>\n  </data>\n  <data name=\"NoVTArgumentDescription\" xml:space=\"preserve\">\n    <value>Disabilita la visualizzazione di VirtualTerminal</value>\n    <comment>{Locked=\"VirtualTerminal\"}</comment>\n  </data>\n  <data name=\"OpenLogsArgumentDescription\" xml:space=\"preserve\">\n    <value>Apri il percorso predefinito dei log</value>\n  </data>\n  <data name=\"Options\" xml:space=\"preserve\">\n    <value>opzioni</value>\n    <comment>Options to change how a command works</comment>\n  </data>\n  <data name=\"OverrideArgumentDescription\" xml:space=\"preserve\">\n    <value>Sostituisci gli argomenti da trasmettere al programma di installazione</value>\n  </data>\n  <data name=\"Package\" xml:space=\"preserve\">\n    <value>Pacchetto: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for a software package. {0} is a placeholder replaced by the software package name.</comment>\n  </data>\n  <data name=\"PendingWorkError\" xml:space=\"preserve\">\n    <value>Ci siamo dimenticati di farlo...</value>\n  </data>\n  <data name=\"PositionArgumentDescription\" xml:space=\"preserve\">\n    <value>Posizione del cursore nella riga di comando</value>\n  </data>\n  <data name=\"PrivacyStatement\" xml:space=\"preserve\">\n    <value>Informativa sulla privacy</value>\n  </data>\n  <data name=\"QueryArgumentDescription\" xml:space=\"preserve\">\n    <value>Query usata per cercare un'app</value>\n  </data>\n  <data name=\"RainbowArgumentDescription\" xml:space=\"preserve\">\n    <value>Lo stato di avanzamento mostra un arcobaleno di colori</value>\n  </data>\n  <data name=\"RequiredArgError\" xml:space=\"preserve\">\n    <value>L'argomento obbligatorio non è stato fornito: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user does not provide a required command line argument. {0} is a placeholder replaced by an argument name.</comment>\n  </data>\n  <data name=\"RetroArgumentDescription\" xml:space=\"preserve\">\n    <value>Lo stato di avanzamento viene mostrato come il colore predefinito</value>\n  </data>\n  <data name=\"SearchCommandLongDescription\" xml:space=\"preserve\">\n    <value>Esegue ricerche di pacchetti da origini configurate.</value>\n  </data>\n  <data name=\"SearchCommandShortDescription\" xml:space=\"preserve\">\n    <value>Trova e mostra le informazioni di base dei pacchetti</value>\n  </data>\n  <data name=\"SearchId\" xml:space=\"preserve\">\n    <value>Id</value>\n    <comment>Abbreviation of Identifier.</comment>\n  </data>\n  <data name=\"SearchMatch\" xml:space=\"preserve\">\n    <value>Corrispondenza</value>\n  </data>\n  <data name=\"SearchName\" xml:space=\"preserve\">\n    <value>Nome</value>\n  </data>\n  <data name=\"SearchSource\" xml:space=\"preserve\">\n    <value>Origine</value>\n  </data>\n  <data name=\"SearchTruncated\" xml:space=\"preserve\">\n    <value>voci aggiuntive troncate a causa del limite dei risultati</value>\n  </data>\n  <data name=\"SearchVersion\" xml:space=\"preserve\">\n    <value>Versione</value>\n  </data>\n  <data name=\"SettingLoadFailure\" xml:space=\"preserve\">\n    <value>Sono stati trovati i seguenti errori durante la convalida delle impostazioni:</value>\n  </data>\n  <data name=\"SettingsCommandLongDescription\" xml:space=\"preserve\">\n    <value>Aprire le impostazioni nell'editor di testo json predefinito. Se nessun editor è configurato, apre le impostazioni nel blocco note. Per le impostazioni disponibili, vedi https://aka.ms/winget-settings. Questo comando può essere usato anche per impostare le impostazioni dell'amministratore, fornendo gli argomenti --enable o --disable</value>\n    <comment>{Locked=\"--enable\"} {Locked=\"--disable\"}</comment>\n  </data>\n  <data name=\"SettingsCommandShortDescription\" xml:space=\"preserve\">\n    <value>Aprire le impostazioni o predisporre le impostazioni di amministratore</value>\n  </data>\n  <data name=\"SettingsWarnings\" xml:space=\"preserve\">\n    <value>Errore imprevisto durante il caricamento delle impostazioni. Verificare le impostazioni eseguendo il comando 'settings'.</value>\n    <comment>{Locked=\"'settings'\"}</comment>\n  </data>\n  <data name=\"ShowChannel\" xml:space=\"preserve\">\n    <value>Canale</value>\n  </data>\n  <data name=\"ShowCommandLongDescription\" xml:space=\"preserve\">\n    <value>Visualizza informazioni su un pacchetto specifico. Per impostazione predefinita, la query deve essere insensitively con l'ID, il nome o il moniker del pacchetto. Altri campi possono essere utilizzati passando l'opzione appropriata.</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"ShowCommandShortDescription\" xml:space=\"preserve\">\n    <value>Mostra informazioni su un pacchetto</value>\n  </data>\n  <data name=\"ShowVersion\" xml:space=\"preserve\">\n    <value>Versione</value>\n  </data>\n  <data name=\"SilentArgumentDescription\" xml:space=\"preserve\">\n    <value>Richiedi l'installazione invisibile all'utente</value>\n  </data>\n  <data name=\"SingleCharAfterDashError\" xml:space=\"preserve\">\n    <value>Solo l'alias a carattere singolo può apparire dopo un singolo -: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides more than a single character command line alias argument after an alias argument specifier '-'. {0} is a placeholder replaced by the user's argument input.</comment>\n  </data>\n  <data name=\"SourceAddAlreadyExistsDifferentArg\" xml:space=\"preserve\">\n    <value>Esiste già un'origine con il nome specificato e si riferisce a un percorso diverso:</value>\n  </data>\n  <data name=\"SourceAddAlreadyExistsDifferentName\" xml:space=\"preserve\">\n    <value>Una fonte con un nome diverso fa già riferimento a questa posizione:</value>\n  </data>\n  <data name=\"SourceAddAlreadyExistsMatch\" xml:space=\"preserve\">\n    <value>Esiste già un'origine con il nome specificato e si riferisce allo stesso percorso:</value>\n  </data>\n  <data name=\"SourceAddBegin\" xml:space=\"preserve\">\n    <value>Aggiunta origine:</value>\n  </data>\n  <data name=\"SourceAddCommandLongDescription\" xml:space=\"preserve\">\n    <value>Aggiungi una nuova origine. Un'origine fornisce i dati per individuare e installare i pacchetti. Aggiungi una nuova origine solo se la consideri attendibile.</value>\n  </data>\n  <data name=\"SourceAddCommandShortDescription\" xml:space=\"preserve\">\n    <value>Aggiungi una nuova origine</value>\n  </data>\n  <data name=\"SourceArgArgumentDescription\" xml:space=\"preserve\">\n    <value>Argomento assegnato all'origine</value>\n  </data>\n  <data name=\"SourceArgumentDescription\" xml:space=\"preserve\">\n    <value>Trova il pacchetto usando l'origine specificata</value>\n  </data>\n  <data name=\"SourceCommandLongDescription\" xml:space=\"preserve\">\n    <value>Gestisci le origini con i comandi secondari. Un'origine fornisce i dati per individuare e installare i pacchetti. Aggiungi una nuova origine solo se la consideri attendibile.</value>\n  </data>\n  <data name=\"SourceCommandShortDescription\" xml:space=\"preserve\">\n    <value>Gestisci le origini dei pacchetti</value>\n  </data>\n  <data name=\"SourceEditCommandLongDescription\" xml:space=\"preserve\">\n    <value>Modifica le proprietà di un'origine esistente. Un'origine fornisce i dati per l'individuazione e l'installazione dei pacchetti.</value>\n  </data>\n  <data name=\"SourceEditCommandShortDescription\" xml:space=\"preserve\">\n    <value>Modifica proprietà di un'origine</value>\n  </data>\n  <data name=\"SourceEditOne\" xml:space=\"preserve\">\n    <value>Modifica origine: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being edited. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceEditNoChanges\" xml:space=\"preserve\">\n    <value>L'origine denominata '{0}' si trova già nello stato desiderato.</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being edited. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceListArg\" xml:space=\"preserve\">\n    <value>Argomento</value>\n    <comment>Value given to source.</comment>\n  </data>\n  <data name=\"SourceListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Elenca tutte le origini correnti o tutti i dettagli di un'origine specifica.</value>\n  </data>\n  <data name=\"SourceListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Elenca le origini correnti</value>\n  </data>\n  <data name=\"SourceListData\" xml:space=\"preserve\">\n    <value>Dati</value>\n    <comment>Data stored by the source.</comment>\n  </data>\n  <data name=\"SourceListField\" xml:space=\"preserve\">\n    <value>Campo</value>\n    <comment>The name of a piece of information about a source.</comment>\n  </data>\n  <data name=\"SourceListName\" xml:space=\"preserve\">\n    <value>Nome</value>\n    <comment>The name of the source.</comment>\n  </data>\n  <data name=\"SourceListIdentifier\" xml:space=\"preserve\">\n    <value>Identificatore</value>\n    <comment>The source's unique identifier.</comment>\n  </data>\n  <data name=\"SourceListNoneFound\" xml:space=\"preserve\">\n    <value>Non è stata trovata un'origine denominata: {0}</value>\n    <comment>Error message displayed when the user provides a repository source name that was not found. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"SourceListNoSources\" xml:space=\"preserve\">\n    <value>Nessuna origine configurata.</value>\n  </data>\n  <data name=\"SourceListType\" xml:space=\"preserve\">\n    <value>Tipo</value>\n    <comment>The kind of source.</comment>\n  </data>\n  <data name=\"SourceListUpdated\" xml:space=\"preserve\">\n    <value>Aggiornato</value>\n    <comment>The last time the source was updated.</comment>\n  </data>\n  <data name=\"SourceListUpdatedNever\" xml:space=\"preserve\">\n    <value>mai</value>\n    <comment>The source has never been updated.</comment>\n  </data>\n  <data name=\"SourceListValue\" xml:space=\"preserve\">\n    <value>Valore</value>\n    <comment>The value of information about a source.</comment>\n  </data>\n  <data name=\"SourceNameArgumentDescription\" xml:space=\"preserve\">\n    <value>Nome dell'origine</value>\n  </data>\n  <data name=\"SourceOpenFailedSuggestion\" xml:space=\"preserve\">\n    <value>Errore durante l'apertura della/e origine/i; provare il comando 'source reset' se il problema persiste.</value>\n    <comment>{Locked=\"source reset\"}</comment>\n  </data>\n  <data name=\"SourceOpenPredefinedFailedSuggestion\" xml:space=\"preserve\">\n    <value>Non è stato possibile aprire l'origine predefinita. Informare i gestori winget</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"SourceRemoveAll\" xml:space=\"preserve\">\n    <value>Rimozione di tutte le origini in corso...</value>\n  </data>\n  <data name=\"SourceRemoveCommandLongDescription\" xml:space=\"preserve\">\n    <value>Rimuovi un'origine specifica.</value>\n  </data>\n  <data name=\"SourceRemoveCommandShortDescription\" xml:space=\"preserve\">\n    <value>Rimuovi le origini correnti</value>\n  </data>\n  <data name=\"SourceRemoveOne\" xml:space=\"preserve\">\n    <value>Rimozione origine in corso: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being removed. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceResetAll\" xml:space=\"preserve\">\n    <value>Reimpostazione di tutte le origini in corso...</value>\n  </data>\n  <data name=\"SourceResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>Questo comando elimina le origini esistenti, ad esclusione dei dati locali. Senza alcun argomento, eliminerà tutte le origini e aggiungerà quelle predefinite. Se viene fornito il nome di un'origine specifica, verrà eliminata solo quella.</value>\n  </data>\n  <data name=\"SourceResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>Reimposta origini</value>\n  </data>\n  <data name=\"SourceResetForceArgumentDescription\" xml:space=\"preserve\">\n    <value>Forza il reset delle origini</value>\n  </data>\n  <data name=\"SourceResetListAndOverridePreamble\" xml:space=\"preserve\">\n    <value>Le origini seguenti verranno reimpostate se viene specificata l'opzione--force:</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"SourceResetOne\" xml:space=\"preserve\">\n    <value>Reimpostazione origine in corso: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a repository source that is currently being reset. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceTypeArgumentDescription\" xml:space=\"preserve\">\n    <value>Tipo di origine</value>\n  </data>\n  <data name=\"SourceUpdateAll\" xml:space=\"preserve\">\n    <value>Aggiornamento di tutte le origini...</value>\n  </data>\n  <data name=\"SourceUpdateCommandLongDescription\" xml:space=\"preserve\">\n    <value>Aggiorna tutte le origini o solo un'origine specifica.</value>\n  </data>\n  <data name=\"SourceUpdateCommandShortDescription\" xml:space=\"preserve\">\n    <value>Aggiorna le origini correnti</value>\n  </data>\n  <data name=\"SourceUpdateOne\" xml:space=\"preserve\">\n    <value>Aggiornamento origine in corso: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being updated. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"TagArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtra i risultati per tag</value>\n  </data>\n  <data name=\"ThankYou\" xml:space=\"preserve\">\n    <value>Grazie per aver usato WinGet</value>\n  </data>\n  <data name=\"ThirdPartSoftwareNotices\" xml:space=\"preserve\">\n    <value>Comunicazioni di terze parti</value>\n  </data>\n  <data name=\"ToolDescription\" xml:space=\"preserve\">\n    <value>L'utilità della riga di comando di Winget consente di installare le applicazioni e altri pacchetti dalla riga di comando.</value>\n  </data>\n  <data name=\"ToolInfoArgumentDescription\" xml:space=\"preserve\">\n    <value>Visualizza le informazioni generali dello strumento</value>\n  </data>\n  <data name=\"ToolVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>Mostra la versione dello strumento</value>\n  </data>\n  <data name=\"TooManyArgError\" xml:space=\"preserve\">\n    <value>Argomento fornito più volte di quanto consentito: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a command line argument more times than it is allowed. {0} is a placeholder replaced by the user's argument name input.</comment>\n  </data>\n  <data name=\"TooManyBehaviorsError\" xml:space=\"preserve\">\n    <value>Sono stati specificati più argomenti del comportamento di esecuzione: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides more than one execution behavior argument when installing an application package. {0} is a placeholder replaced by the user specified execution behaviors (e.g. 'silent|interactive').</comment>\n  </data>\n  <data name=\"UnexpectedErrorExecutingCommand\" xml:space=\"preserve\">\n    <value>Si è verificato un errore imprevisto durante l'esecuzione del comando:</value>\n  </data>\n  <data name=\"UninstallPreviousArgumentDescription\" xml:space=\"preserve\">\n    <value>Disinstalla la versione precedente del pacchetto durante l'aggiornamento</value>\n  </data>\n  <data name=\"UnrecognizedCommand\" xml:space=\"preserve\">\n    <value>Comando non riconosciuto: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an unrecognized command. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"UpdateAllArgumentDescription\" xml:space=\"preserve\">\n    <value>Aggiorna tutti i pacchetti installati alla versione più recente se disponibile</value>\n  </data>\n  <data name=\"UpdateNotApplicable\" xml:space=\"preserve\">\n    <value>Non è stato trovato alcun aggiornamento applicabile.</value>\n  </data>\n  <data name=\"UpdateNotApplicableReason\" xml:space=\"preserve\">\n    <value>Una versione più recente del pacchetto è disponibile in un'origine configurata, ma non si applica al sistema o ai requisiti.</value>\n  </data>\n  <data name=\"UpdateNoPackagesFound\" xml:space=\"preserve\">\n    <value>Non sono stati trovati aggiornamenti disponibili.</value>\n  </data>\n  <data name=\"UpdateNoPackagesFoundReason\" xml:space=\"preserve\">\n    <value>Non sono disponibili versioni più recenti del pacchetto dalle origini configurate.</value>\n  </data>\n  <data name=\"UpgradeCommandLongDescription\" xml:space=\"preserve\">\n    <value>Aggiorna il pacchetto selezionato, trovato eseguendo la ricerca nell'elenco dei pacchetti installati o direttamente da un manifesto. Per impostazione predefinita, la query deve essere insensitively con l'ID, il nome o il moniker del pacchetto. Altri campi possono essere utilizzati passando l'opzione appropriata. Quando non vengono forniti argomenti, mostra i pacchetti con aggiornamenti disponibili</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"UpgradeCommandShortDescription\" xml:space=\"preserve\">\n    <value>Mostra ed esegue gli aggiornamenti disponibili</value>\n  </data>\n  <data name=\"Usage\" xml:space=\"preserve\">\n    <value>utilizzo: {0} {1}</value>\n    <comment>{Locked=\"{0} {1}\"} Message displayed to provide the user with instructions on how to use a command. {0} is a placeholder replaced by the program name (e.g. 'winget'). {1} is a placeholder replaced by the pattern for using the selected command.</comment>\n  </data>\n  <data name=\"ValidateCommandLongDescription\" xml:space=\"preserve\">\n    <value>Convalida un manifesto con un insieme di linee guida rigorose. Queste hanno lo scopo di consentirti di controllare il tuo manifesto prima di inviarlo a un repository.</value>\n  </data>\n  <data name=\"ValidateCommandShortDescription\" xml:space=\"preserve\">\n    <value>Convalida un file manifesto</value>\n  </data>\n  <data name=\"ValidateManifestArgumentDescription\" xml:space=\"preserve\">\n    <value>Il percorso del manifesto da convalidare</value>\n  </data>\n  <data name=\"VerboseLogsArgumentDescription\" xml:space=\"preserve\">\n    <value>Abilita la registrazione dettagliata per winget</value>\n  </data>\n  <data name=\"VerifyFileSignedMsix\" xml:space=\"preserve\">\n    <value>Verifica che il file di input sia un MSIX valido e firmato.</value>\n  </data>\n  <data name=\"VersionArgumentDescription\" xml:space=\"preserve\">\n    <value>Usa la versione specificata; la versione predefinita è quella più recente</value>\n  </data>\n  <data name=\"VersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Mostra le versioni disponibili del pacchetto</value>\n  </data>\n  <data name=\"WordArgumentDescription\" xml:space=\"preserve\">\n    <value>È richiesto il valore specificato prima del completamento</value>\n  </data>\n  <data name=\"GetManifestResultVersionNotFound\" xml:space=\"preserve\">\n    <value>Non sono state trovate versioni corrispondenti: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to upgrade an application package to a version that was not found. {0} is a placeholder replaced by the user's provided upgrade package version.</comment>\n  </data>\n  <data name=\"OpenSourceFailedNoMatch\" xml:space=\"preserve\">\n    <value>Nessuna origine corrisponde al valore specificato: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to install or upgrade an application package from a repository source that was not found. {0} is a placeholder replaced by the user's repository source name input.</comment>\n  </data>\n  <data name=\"OpenSourceFailedNoMatchHelp\" xml:space=\"preserve\">\n    <value>Le origini configurate sono:</value>\n  </data>\n  <data name=\"OpenSourceFailedNoSourceDefined\" xml:space=\"preserve\">\n    <value>Non è stata definita alcuna origine. Aggiungerne una con \"source add\" o ripristinare i valori predefiniti con \"source reset\"</value>\n    <comment>{Locked=\"source add\",\"source reset\"}</comment>\n  </data>\n  <data name=\"ReportIdentityFound\" xml:space=\"preserve\">\n    <value>Trovato</value>\n  </data>\n  <data name=\"VerifyFileFailedIsDirectory\" xml:space=\"preserve\">\n    <value>Il percorso è una directory: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system path that is a directory. {0} is a placeholder replaced by the provided directory path.</comment>\n  </data>\n  <data name=\"VerifyFileFailedNotExist\" xml:space=\"preserve\">\n    <value>Il file non esiste: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system file that does not exist. {0} is a placeholder replaced by the provided file path.</comment>\n  </data>\n  <data name=\"BothManifestAndSearchQueryProvided\" xml:space=\"preserve\">\n    <value>Sono forniti argomenti sia per il manifesto locale che per la query di ricerca.</value>\n  </data>\n  <data name=\"Logs\" xml:space=\"preserve\">\n    <value>Log</value>\n    <comment>Label displayed for diagnostic files containing information about the application use.</comment>\n  </data>\n  <data name=\"InstallerBlockedByPolicy\" xml:space=\"preserve\">\n    <value>Programma di installazione bloccato dai criteri</value>\n  </data>\n  <data name=\"InstallerFailedSecurityCheck\" xml:space=\"preserve\">\n    <value>Non è stato possibile eseguire il controllo di sicurezza per il programma di installazione</value>\n  </data>\n  <data name=\"InstallerFailedVirusScan\" xml:space=\"preserve\">\n    <value>Un antivirus ha rilevato una infezione nel programma di installazione</value>\n  </data>\n  <data name=\"SourceOpenWithFailedUpdate\" xml:space=\"preserve\">\n    <value>Non è stato possibile aggiornare l'origine: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to update the repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"UninstallCommandLongDescription\" xml:space=\"preserve\">\n    <value>Disinstalla il pacchetto selezionato, trovato mediante la ricerca dell'elenco dei pacchetti installati o direttamente da un manifesto. Per impostazione predefinita, la query deve essere insensitively con l'ID, il nome o il moniker del pacchetto. Altri campi possono essere utilizzati passando l'opzione appropriata.</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"UninstallCommandShortDescription\" xml:space=\"preserve\">\n    <value>Disinstalla il pacchetto specificato</value>\n  </data>\n  <data name=\"UninstallFlowStartingPackageUninstall\" xml:space=\"preserve\">\n    <value>Avvio disinstallazione pacchetto in corso...</value>\n  </data>\n  <data name=\"UninstallFlowUninstallSuccess\" xml:space=\"preserve\">\n    <value>Disinstallazione completata</value>\n  </data>\n  <data name=\"NoUninstallInfoFound\" xml:space=\"preserve\">\n    <value>winget non riesce a individuare il comando di disinstallazione per questo pacchetto. Contattare l'autore del pacchetto per chiedere supporto.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"UninstallAbandoned\" xml:space=\"preserve\">\n    <value>Disinstallazione interrotta</value>\n  </data>\n  <data name=\"UninstallFailedWithCode\" xml:space=\"preserve\">\n    <value>Disinstallazione non riuscita con codice di uscita: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to uninstall an application package fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"ExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Esporta un elenco dei pacchetti installati</value>\n  </data>\n  <data name=\"ImportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Installa tutti i pacchetti elencati in un file.</value>\n  </data>\n  <data name=\"ImportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Installa tutti i pacchetti in un file</value>\n  </data>\n  <data name=\"OutputFileArgumentDescription\" xml:space=\"preserve\">\n    <value>File in cui deve essere scritto il risultato</value>\n  </data>\n  <data name=\"ImportFileArgumentDescription\" xml:space=\"preserve\">\n    <value>File che descrive i pacchetti da installare</value>\n  </data>\n  <data name=\"ExportSourceArgumentDescription\" xml:space=\"preserve\">\n    <value>Esporta pacchetti dall'origine specificata</value>\n  </data>\n  <data name=\"ExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Scrive un elenco dei pacchetti installati in un file. I pacchetti possono quindi essere installati con il comando import.</value>\n    <comment>{Locked=\"import\"}</comment>\n  </data>\n  <data name=\"ImportInstallFailed\" xml:space=\"preserve\">\n    <value>Impossibile installare uno o più pacchetti importati</value>\n  </data>\n  <data name=\"ImportSourceNotInstalled\" xml:space=\"preserve\">\n    <value>L'origine necessaria per l'importazione non è installata: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to import application package(s) from a repository source that is not installed. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"InstalledPackageNotAvailable\" xml:space=\"preserve\">\n    <value>Il pacchetto installato non è disponibile in alcuna origine: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when the user attempts to export an installed application package that is not available from any repository source. {0} is a placeholder replaced by the installed package name.</comment>\n  </data>\n  <data name=\"InstalledPackageVersionNotAvailable\" xml:space=\"preserve\">\n    <value>La versione installata del pacchetto non è disponibile in alcuna origine: {0} {1} {2}</value>\n    <comment>{Locked=\"{0} {1} {2}\"} Warning message displayed when the user attempts to export an installed application package with a version that is not available from any repository source. {0} is a placeholder replaced by the installed package identifier. {1} is a placeholder replaced by the installed package version. {2} is a placeholder replaced by the installed package channel.</comment>\n  </data>\n  <data name=\"NoPackagesInImportFile\" xml:space=\"preserve\">\n    <value>Nessun pacchetto trovato nel file di importazione</value>\n  </data>\n  <data name=\"InvalidJsonFile\" xml:space=\"preserve\">\n    <value>Il file JSON non è valido</value>\n  </data>\n  <data name=\"MultiQueryPackageAlreadyInstalled\" xml:space=\"preserve\">\n    <value>Il pacchetto è già installato: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user that an application package is already installed. {0} is a placeholder replaced by the package identifier or search query.</comment>\n  </data>\n  <data name=\"ImportIgnoreUnavailableArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignora pacchetti non disponibili</value>\n  </data>\n  <data name=\"ExportIncludeVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Includi versioni del pacchetto nel file di esportazione</value>\n  </data>\n  <data name=\"ImportIgnoreVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignora versioni del pacchetto dal file di importazione</value>\n  </data>\n  <data name=\"VerifyPathFailedNotExist\" xml:space=\"preserve\">\n    <value>Il percorso non esiste: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system path argument value that does not exist. {0} is a placeholder replaced by the user's provided path.</comment>\n  </data>\n  <data name=\"ImportFileHasInvalidSchema\" xml:space=\"preserve\">\n    <value>Il file JSON non specifica uno schema riconosciuto.</value>\n  </data>\n  <data name=\"InstallScopeDescription\" xml:space=\"preserve\">\n    <value>Seleziona ambito di installazione (user o machine)</value>\n    <comment>{Locked=\"user\",\"machine\"} This argument allows the user to select between installing for just the user or for the entire machine.</comment>\n  </data>\n  <data name=\"InvalidArgumentValueError\" xml:space=\"preserve\">\n    <value>Il valore specificato per l'argomento '{0}' non è valido. i valori validi sono: {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message displayed when the user provides an invalid command line argument value. {0} is a placeholder replaced by the argument name. {1} is a placeholder replaced by a list of valid options.</comment>\n  </data>\n  <data name=\"DisabledByGroupPolicy\" xml:space=\"preserve\">\n    <value>Operazione disabilitata da Criteri di gruppo: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user performs a command operation that is disabled by a group policy. {0} is a placeholder replaced by a group policy description.</comment>\n  </data>\n  <data name=\"PolicyAdditionalSources\" xml:space=\"preserve\">\n    <value>Abilita altre origini di programma di installazione app di Windows</value>\n  </data>\n  <data name=\"PolicyAllowedSources\" xml:space=\"preserve\">\n    <value>Abilita le origini consentite del programma di installazione app di Windows</value>\n  </data>\n  <data name=\"PolicyEnableDefaultSource\" xml:space=\"preserve\">\n    <value>Abilita origine predefinita del programma di installazione app di Windows</value>\n  </data>\n  <data name=\"PolicyEnableExperimentalFeatures\" xml:space=\"preserve\">\n    <value>Abilita funzionalità sperimentali del programma di installazione app di Windows</value>\n  </data>\n  <data name=\"PolicyEnableMSStoreSource\" xml:space=\"preserve\">\n    <value>Abilita l'origine Microsoft Store del programma di installazione app di Windows</value>\n  </data>\n  <data name=\"PolicyEnableFontSource\" xml:space=\"preserve\">\n    <value>Abilita l'origine del carattere di Programma di installazione Windows App</value>\n  </data>\n  <data name=\"PolicyEnableWinGetSettings\" xml:space=\"preserve\">\n    <value>Abilita le impostazioni di Gestione pacchetti Windows</value>\n  </data>\n  <data name=\"PolicyEnableWinGet\" xml:space=\"preserve\">\n    <value>Abilita Gestione pacchetti Windows</value>\n  </data>\n  <data name=\"PolicyEnableWindowsPackageManagerCommandLineInterfaces\" xml:space=\"preserve\">\n    <value>Abilita Gestione interfacce della riga di comando dei pacchetti Windows</value>\n  </data>\n  <data name=\"PolicySourceAutoUpdateInterval\" xml:space=\"preserve\">\n    <value>Imposta l’intervallo di aggiornamento automatico di origine Gestione pacchetti Windows in minuti</value>\n  </data>\n  <data name=\"PoliciesPolicy\" xml:space=\"preserve\">\n    <value>Criteri di gruppo</value>\n    <comment>Header for a table listing active Group Policies</comment>\n  </data>\n  <data name=\"PolicyEnableLocalManifests\" xml:space=\"preserve\">\n    <value>Abilita file manifesto locali del programma di installazione app di Windows</value>\n  </data>\n  <data name=\"PolicyEnableBypassCertificatePinningForMicrosoftStore\" xml:space=\"preserve\">\n    <value>Abilita il bypass del certificato aggiunto di origine di Windows Programma di installazione app Microsoft Store</value>\n  </data>\n  <data name=\"PolicyEnableLocalArchiveMalwareScanOverride\" xml:space=\"preserve\">\n    <value>Abilita l'override dell'analisi malware dell'archivio locale di Programma di installazione app di Windows</value>\n  </data>\n  <data name=\"SettingsWarningField\" xml:space=\"preserve\">\n    <value>Campo: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when a user setting field has invalid syntax or semantics. {0} is a placeholder replaced by the setting field path.</comment>\n  </data>\n  <data name=\"SettingsWarningInvalidFieldFormat\" xml:space=\"preserve\">\n    <value>Formato del campo non valido.</value>\n  </data>\n  <data name=\"SettingsWarningInvalidFieldValue\" xml:space=\"preserve\">\n    <value>Valore campo non valido.</value>\n  </data>\n  <data name=\"SettingsWarningInvalidValueFromPolicy\" xml:space=\"preserve\">\n    <value>Impostazione non valida dai criteri di gruppo.</value>\n  </data>\n  <data name=\"SettingsWarningLoadedBackupSettings\" xml:space=\"preserve\">\n    <value>Caricamento delle impostazioni dal file di backup completato.</value>\n  </data>\n  <data name=\"SettingsWarningParseError\" xml:space=\"preserve\">\n    <value>Errore durante l'analisi del file:</value>\n  </data>\n  <data name=\"SettingsWarningValue\" xml:space=\"preserve\">\n    <value>Valore: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when a user setting value has invalid syntax or semantics. {0} is a placeholder replaced by the setting data value.</comment>\n  </data>\n  <data name=\"FeaturesMessageDisabledByPolicy\" xml:space=\"preserve\">\n    <value>Le seguenti funzionalità sperimentali sono in corso.\nLa configurazione è disabilitata a causa dei criteri di gruppo.</value>\n  </data>\n  <data name=\"InstallerHashMismatchError\" xml:space=\"preserve\">\n    <value>L'hash del programma di installazione non corrisponde.</value>\n  </data>\n  <data name=\"PolicyEnableHashOverride\" xml:space=\"preserve\">\n    <value>Abilita sostituzione hash del programma di installazione app di Windows</value>\n  </data>\n  <data name=\"SourceExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Esporta origini correnti come JSON per criteri di gruppo.</value>\n  </data>\n  <data name=\"SourceExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Esporta le origini correnti</value>\n  </data>\n  <data name=\"SourceListAdditionalSource\" xml:space=\"preserve\">\n    <value>Origine aggiuntiva</value>\n    <comment>An additional source required by policy.</comment>\n  </data>\n  <data name=\"SourceListAllowedSource\" xml:space=\"preserve\">\n    <value>Origine consentita</value>\n    <comment>A source that the user is allowed to add.</comment>\n  </data>\n  <data name=\"InvalidArgumentValueErrorWithoutValidValues\" xml:space=\"preserve\">\n    <value>Il valore specificato per l'argomento '{0}' non è valido</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an invalid command line argument value. {0} is a placeholder replaced by the argument name.</comment>\n  </data>\n  <data name=\"Cancelled\" xml:space=\"preserve\">\n    <value>Annullato</value>\n  </data>\n  <data name=\"ExternalDependencies\" xml:space=\"preserve\">\n    <value>Esterno</value>\n  </data>\n  <data name=\"ImportCommandReportDependencies\" xml:space=\"preserve\">\n    <value>I pacchetti trovati in questa importazione hanno le dipendenze seguenti:</value>\n    <comment>Import command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"PackageRequiresDependencies\" xml:space=\"preserve\">\n    <value>Questo pacchetto richiede le dipendenze seguenti:</value>\n    <comment>Message shown before reporting dependencies</comment>\n  </data>\n  <data name=\"DependenciesFlowInstall\" xml:space=\"preserve\">\n    <value>Installazione delle dipendenze:</value>\n  </data>\n  <data name=\"DependenciesFlowSourceNotFound\" xml:space=\"preserve\">\n    <value>L'origine delle dipendenze non è stata trovata</value>\n  </data>\n  <data name=\"DependenciesFlowSourceTooManyMatches\" xml:space=\"preserve\">\n    <value>La ricerca del pacchetto ha restituito più di un risultato: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when application packages search yield more than one result. {0} is a placeholder replaced by the dependency package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowPackageVersionNotFound\" xml:space=\"preserve\">\n    <value>Ultima versione non trovata per il pacchetto: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when no suitable version found for the specific application package. {0} is a placeholder replaced by the package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoInstallerFound\" xml:space=\"preserve\">\n    <value>Non sono stati trovati programmi di installazione: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when no installer found for a manifest. {0} is a placeholder replaced by the manifest identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoMinVersion\" xml:space=\"preserve\">\n    <value>Versione minima richiesta non disponibile per il pacchetto: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the minimum required version is not available for an application package. {0} is a placeholder replaced by the package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoMatches\" xml:space=\"preserve\">\n    <value>Nessuna corrispondenza</value>\n    <comment>When package search yields no matches</comment>\n  </data>\n  <data name=\"DependenciesFlowContainsLoop\" xml:space=\"preserve\">\n    <value>Con ciclo</value>\n    <comment>Dependency graph has loop</comment>\n  </data>\n  <data name=\"DependenciesFlowNoSuitableInstallerFound\" xml:space=\"preserve\">\n    <value>Non è stato trovato alcun programma di installazione adatto per il manifesto: {0} versione {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message displayed when an attempt to get a preferred installer for a manifest fails. {0} is a placeholder replaced by the manifest identifier. {1} is a placeholder replaced by the manifest version.</comment>\n  </data>\n  <data name=\"DependenciesManagementError\" xml:space=\"preserve\">\n    <value>Errore durante l'elaborazione delle dipendenze del pacchetto. Vuoi continuare l'installazione?</value>\n    <comment>Prompt message shown when dependencies processing yields errors.</comment>\n  </data>\n  <data name=\"DependenciesManagementExitMessage\" xml:space=\"preserve\">\n    <value>Errore durante l'elaborazione delle dipendenze del pacchetto. Uscita in corso...</value>\n  </data>\n  <data name=\"PackageDependencies\" xml:space=\"preserve\">\n    <value>Pacchetti</value>\n  </data>\n  <data name=\"UninstallCommandReportDependencies\" xml:space=\"preserve\">\n    <value>Questo pacchetto contiene dipendenze che potrebbero non essere più necessarie:</value>\n    <comment>Uninstall command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"ValidateCommandReportDependencies\" xml:space=\"preserve\">\n    <value>Il manifesto contiene le seguenti dipendenze che non sono state convalidate; assicurarsi che siano valide:</value>\n    <comment>Validate command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"WindowsFeaturesDependencies\" xml:space=\"preserve\">\n    <value>Funzionalità Windows</value>\n  </data>\n  <data name=\"WindowsLibrariesDependencies\" xml:space=\"preserve\">\n    <value>Raccolte di Windows</value>\n  </data>\n  <data name=\"DependencySourceArgumentDescription\" xml:space=\"preserve\">\n    <value>Trova le dipendenze del pacchetto con l'origine specificata</value>\n    <comment>For getting package type dependencies when installing from a local manifest</comment>\n  </data>\n  <data name=\"WindowsStoreTerms\" xml:space=\"preserve\">\n    <value>Condizioni di Windows Store</value>\n  </data>\n  <data name=\"AcceptPackageAgreementsArgumentDescription\" xml:space=\"preserve\">\n    <value>Accetta tutti i contratti di licenza per i pacchetti</value>\n  </data>\n  <data name=\"ExportedPackageRequiresLicenseAgreement\" xml:space=\"preserve\">\n    <value>Il pacchetto esportato richiede il contratto di licenza per l'installazione: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when an exported application package requires license agreement to install. {0} is a placeholder replaced by the package name.</comment>\n  </data>\n  <data name=\"PackageAgreementsPrompt\" xml:space=\"preserve\">\n    <value>L'editore richiede la visualizzazione delle informazioni precedenti e l'accettazione dei contratti prima dell'installazione.\nAccetti le condizioni?</value>\n  </data>\n  <data name=\"PackageAgreementsNotAgreedTo\" xml:space=\"preserve\">\n    <value>Contratti del pacchetto non accettati. Operazione annullata.</value>\n  </data>\n  <data name=\"ShowLabelAgreements\" xml:space=\"preserve\">\n    <value>Contratti:</value>\n  </data>\n  <data name=\"ShowLabelAuthor\" xml:space=\"preserve\">\n    <value>Autore:</value>\n  </data>\n  <data name=\"ShowLabelDescription\" xml:space=\"preserve\">\n    <value>Descrizione:</value>\n  </data>\n  <data name=\"ShowLabelInstaller\" xml:space=\"preserve\">\n    <value>Programma di installazione:</value>\n  </data>\n  <data name=\"ShowLabelInstallerLocale\" xml:space=\"preserve\">\n    <value>Impostazioni locali del programma di installazione:</value>\n  </data>\n  <data name=\"ShowLabelInstallerProductId\" xml:space=\"preserve\">\n    <value>ID prodotto dello Store:</value>\n  </data>\n  <data name=\"ShowLabelInstallerSha256\" xml:space=\"preserve\">\n    <value>SHA256 del programma di installazione:</value>\n  </data>\n  <data name=\"ShowLabelInstallerType\" xml:space=\"preserve\">\n    <value>Tipo di programma di installazione:</value>\n  </data>\n  <data name=\"ShowLabelInstallerUrl\" xml:space=\"preserve\">\n    <value>URL del programma di installazione:</value>\n  </data>\n  <data name=\"ShowLabelLicense\" xml:space=\"preserve\">\n    <value>Licenza:</value>\n  </data>\n  <data name=\"ShowLabelLicenseUrl\" xml:space=\"preserve\">\n    <value>URL licenza:</value>\n  </data>\n  <data name=\"ShowLabelMoniker\" xml:space=\"preserve\">\n    <value>Moniker:</value>\n  </data>\n  <data name=\"ShowLabelPackageUrl\" xml:space=\"preserve\">\n    <value>Home page:</value>\n  </data>\n  <data name=\"ShowLabelPublisher\" xml:space=\"preserve\">\n    <value>Editore:</value>\n  </data>\n  <data name=\"ShowLabelTags\" xml:space=\"preserve\">\n    <value>Tag:</value>\n  </data>\n  <data name=\"ShowLabelVersion\" xml:space=\"preserve\">\n    <value>Versione:</value>\n  </data>\n  <data name=\"ShowLabelDependencies\" xml:space=\"preserve\">\n    <value>Dipendenze:</value>\n  </data>\n  <data name=\"ShowLabelWindowsFeaturesDependencies\" xml:space=\"preserve\">\n    <value>Funzionalità Windows:</value>\n  </data>\n  <data name=\"ShowLabelWindowsLibrariesDependencies\" xml:space=\"preserve\">\n    <value>Raccolte di Windows:</value>\n  </data>\n  <data name=\"ShowLabelPackageDependencies\" xml:space=\"preserve\">\n    <value>Dipendenze dei pacchetti:</value>\n  </data>\n  <data name=\"ShowLabelExternalDependencies\" xml:space=\"preserve\">\n    <value>Dipendenze esterne:</value>\n  </data>\n  <data name=\"PromptOptionNo\" xml:space=\"preserve\">\n    <value>No</value>\n  </data>\n  <data name=\"PromptOptionYes\" xml:space=\"preserve\">\n    <value>Sì</value>\n  </data>\n  <data name=\"SourceAddOpenSourceFailed\" xml:space=\"preserve\">\n    <value>Non è stato possibile aprire l'origine aggiunta.</value>\n  </data>\n  <data name=\"AcceptSourceAgreementsArgumentDescription\" xml:space=\"preserve\">\n    <value>Accetta tutti i contratti di origine durante le operazioni di origine</value>\n  </data>\n  <data name=\"SourceAgreementsTitle\" xml:space=\"preserve\">\n    <value>Prima di usare l'origine `{0}`, è necessario visualizzare i contratti seguenti.</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user that a repository source requires viewing agreements before using. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceAgreementsPrompt\" xml:space=\"preserve\">\n    <value>Accetti tutte le condizioni dei contratti di origine?</value>\n  </data>\n  <data name=\"SourceAgreementsNotAgreedTo\" xml:space=\"preserve\">\n    <value>Uno o più contratti di origine non sono stati accettati. Operazione annullata. Accettare i contratti di origine o rimuovere le origini corrispondenti.</value>\n  </data>\n  <data name=\"SourceAgreementsMarketMessage\" xml:space=\"preserve\">\n    <value>L'origine richiede che l'area geografica di 2 lettere del computer corrente venga inviata al servizio back-end per funzionare correttamente ,ad esempio \"STATI Uniti\".</value>\n  </data>\n  <data name=\"InstallFlowRegistrationDeferred\" xml:space=\"preserve\">\n    <value>Installazione completata. Riavviare l'applicazione per completare l'aggiornamento.</value>\n  </data>\n  <data name=\"HeaderArgumentDescription\" xml:space=\"preserve\">\n    <value>Intestazione HTTP di origine REST di Windows-Package-Manager facoltativa</value>\n  </data>\n  <data name=\"HeaderArgumentNotApplicableForNonRestSourceWarning\" xml:space=\"preserve\">\n    <value>L'intestazione facoltativa verrà ignorata perché non è applicabile per questa origine.</value>\n  </data>\n  <data name=\"HeaderArgumentNotApplicableWithoutSource\" xml:space=\"preserve\">\n    <value>L'intestazione facoltativa non è applicabile senza specificare un'origine: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user performs an operation (e.g install) and provides the HTTP 'header' argument without specifying the repository source. {0} is a placeholder replaced by the header argument name.</comment>\n  </data>\n  <data name=\"ShowLabelInstallerReleaseDate\" xml:space=\"preserve\">\n    <value>Data di rilascio:</value>\n  </data>\n  <data name=\"ShowLabelInstallerOfflineDistributionSupported\" xml:space=\"preserve\">\n    <value>Distribuzione offline supportata:</value>\n  </data>\n  <data name=\"ShowLabelPublisherUrl\" xml:space=\"preserve\">\n    <value>URL editore:</value>\n  </data>\n  <data name=\"ShowLabelPurchaseUrl\" xml:space=\"preserve\">\n    <value>URL acquisto:</value>\n  </data>\n  <data name=\"ShowLabelPublisherSupportUrl\" xml:space=\"preserve\">\n    <value>URL supporto editore:</value>\n  </data>\n  <data name=\"ShowLabelPrivacyUrl\" xml:space=\"preserve\">\n    <value>URL privacy:</value>\n  </data>\n  <data name=\"ShowLabelCopyright\" xml:space=\"preserve\">\n    <value>Copyright:</value>\n  </data>\n  <data name=\"ShowLabelCopyrightUrl\" xml:space=\"preserve\">\n    <value>URL copyright:</value>\n  </data>\n  <data name=\"ShowLabelReleaseNotes\" xml:space=\"preserve\">\n    <value>Note sulla versione:</value>\n  </data>\n  <data name=\"ShowLabelReleaseNotesUrl\" xml:space=\"preserve\">\n    <value>URL note sulla versione:</value>\n  </data>\n  <data name=\"SearchFailureWarning\" xml:space=\"preserve\">\n    <value>Errore durante la ricerca nell'origine; i risultati non verranno inclusi: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when searching a repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SearchFailureError\" xml:space=\"preserve\">\n    <value>Errore durante la ricerca nell'origine: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when searching a repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"FeatureDisabledByAdminSettingMessage\" xml:space=\"preserve\">\n    <value>Questa funzionalità deve essere abilitata dagli amministratori. Per abilitarlo, eseguire 'winget settings --enable {0}' come amministratore.</value>\n    <comment>{Locked=\"winget settings --enable\", \"{0}\"}. Error message displayed when the user uses a feature that needs to be enabled by administrators. {0} is a placeholder replaced by the admin setting.</comment>\n  </data>\n  <data name=\"AdminSettingEnableDescription\" xml:space=\"preserve\">\n    <value>Abilita l'impostazione amministratore specifica</value>\n  </data>\n  <data name=\"AdminSettingDisableDescription\" xml:space=\"preserve\">\n    <value>Disabilita l'impostazione di amministratore specifica</value>\n  </data>\n  <data name=\"AdminSettingEnabled\" xml:space=\"preserve\">\n    <value>Impostazione amministratore '{0}' abilitata.</value>\n    <comment>{Locked=\"{0}\"} Message displayed when the user enables an admin setting. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"AdminSettingDisabled\" xml:space=\"preserve\">\n    <value>Impostazione amministratore '{0}' disabilitata.</value>\n    <comment>{Locked=\"{0}\"} Message displayed when the user disables an admin setting. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"AdminSettingHeader\" xml:space=\"preserve\">\n    <value>Impostazione amministrazione</value>\n    <comment>Header for a table displaying admin settings.</comment>\n  </data>\n  <data name=\"InstallFlowReturnCodePackageInUse\" xml:space=\"preserve\">\n    <value>L'applicazione è attualmente in esecuzione. Uscire dall'applicazione, quindi riprovare.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodePackageInUseByApplication\" xml:space=\"preserve\">\n    <value>I file modificati dal programma di installazione sono attualmente utilizzati da un'applicazione diversa. Chiudere le applicazioni, quindi riprovare.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInstallInProgress\" xml:space=\"preserve\">\n    <value>È già in corso un'altra installazione. Riprova più tardi.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeFileInUse\" xml:space=\"preserve\">\n    <value>È in uso uno o più file. Uscire dall'applicazione, quindi riprovare.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeMissingDependency\" xml:space=\"preserve\">\n    <value>Nel sistema manca una dipendenza per questo pacchetto.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeDiskFull\" xml:space=\"preserve\">\n    <value>Non c'è più spazio nel PC. Liberare spazio, quindi riprovare.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInsufficientMemory\" xml:space=\"preserve\">\n    <value>Memoria insufficiente per l'installazione. Chiudi le altre applicazioni, quindi riprova.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInvalidParameter\" xml:space=\"preserve\">\n    <value>Uno dei parametri di installazione non è valido. Il log di installazione del pacchetto potrebbe contenere ulteriori dettagli.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeNoNetwork\" xml:space=\"preserve\">\n    <value>Questa applicazione richiede la connettività Internet. Connettiti a una rete e riprova.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeContactSupport\" xml:space=\"preserve\">\n    <value>Errore dell'applicazione durante l'installazione. Contattare il supporto tecnico.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootRequiredToFinish\" xml:space=\"preserve\">\n    <value>Riavvia il PC per completare l'installazione..</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootRequiredForInstall\" xml:space=\"preserve\">\n    <value>Il PC verrà riavviato per completare l'installazione.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootInitiated\" xml:space=\"preserve\">\n    <value>Installazione non riuscita. Riavvia il PC e riprova.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeCancelledByUser\" xml:space=\"preserve\">\n    <value>Hai annullato l’installazione.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeAlreadyInstalled\" xml:space=\"preserve\">\n    <value>È già installata un'altra versione di questa applicazione.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeDowngrade\" xml:space=\"preserve\">\n    <value>È già installata una versione successiva di questa applicazione.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeBlockedByPolicy\" xml:space=\"preserve\">\n    <value>I criteri dell'organizzazione impediscono l'installazione. Contattare l'amministratore.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeSystemNotSupported\" xml:space=\"preserve\">\n    <value>La configurazione di sistema corrente non supporta l'installazione di questo pacchetto.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeCustomError\" xml:space=\"preserve\">\n    <value>L'installazione non è riuscita con un errore del programma di installazione personalizzato. Contattare il supporto per i pacchetti.</value>\n  </data>\n  <data name=\"InstallAbandoned\" xml:space=\"preserve\">\n    <value>Installazione interrotta</value>\n  </data>\n  <data name=\"InstallerFailedWithCode\" xml:space=\"preserve\">\n    <value>Programma di installazione non riuscito con codice di uscita: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the application installer fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"InstallerLogAvailable\" xml:space=\"preserve\">\n    <value>Il log del programma di installazione è disponibile in: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about the system path of a diagnostic files containing information about the installer. {0} is a placeholder replaced by the diagnostic file system path.</comment>\n  </data>\n  <data name=\"SearchFailureErrorListMatches\" xml:space=\"preserve\">\n    <value>Sono stati trovati i pacchetti seguenti tra le origini di lavoro.\nSpecificarne uno utilizzando l'opzione --source per continuare.</value>\n    <comment>{Locked=\"--source\"} \"working sources\" as in \"sources that are working correctly\"</comment>\n  </data>\n  <data name=\"SearchFailureErrorNoMatches\" xml:space=\"preserve\">\n    <value>Non sono stati trovati pacchetti tra le origini di lavoro.</value>\n    <comment>\"working sources\" as in \"sources that are working correctly\"</comment>\n  </data>\n  <data name=\"FeaturesMessageDisabledByBuild\" xml:space=\"preserve\">\n    <value>Questa è una release stabile di Gestione pacchetti Windows. Se desideri provare funzionalità sperimentali, installa una build preliminare. Istruzioni disponibili su GitHub all'indirizzo https://github.com/microsoft/winget-cli.</value>\n    <comment>{Locked=\"https://github.com/microsoft/winget-cli\"}</comment>\n  </data>\n  <data name=\"WindowsPackageManager\" xml:space=\"preserve\">\n    <value>Gestione pacchetti Windows v{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying the product name and version. {0} is a placeholder replaced by the product version.</comment>\n  </data>\n  <data name=\"ImportIgnorePackageVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignora versioni del pacchetto dal file di importazione</value>\n  </data>\n  <data name=\"CountOutOfBoundsError\" xml:space=\"preserve\">\n    <value>Il numero di risultati richiesto deve essere compreso tra 1 e 1000.</value>\n  </data>\n  <data name=\"CustomSwitchesArgumentDescription\" xml:space=\"preserve\">\n    <value>Argomenti da passare al programma di installazione oltre ai valori predefiniti</value>\n  </data>\n  <data name=\"UpgradeDifferentInstallTechnologyInNewerVersions\" xml:space=\"preserve\">\n    <value>È stata trovata una versione più recente, ma la tecnologia di installazione è diversa dalla versione corrente installata. Disinstallare il pacchetto e installare la versione più recente.</value>\n  </data>\n  <data name=\"UpgradeDifferentInstallTechnology\" xml:space=\"preserve\">\n    <value>La tecnologia di installazione della versione più recente specificata è diversa dalla versione corrente installata. Disinstallare il pacchetto e installare la versione più recente.</value>\n  </data>\n  <data name=\"WindowsPackageManagerPreview\" xml:space=\"preserve\">\n    <value>Gestione pacchetti Windows (Anteprima) v{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying the preview product name and pre-release version. {0} is a placeholder replaced by the product version.</comment>\n  </data>\n  <data name=\"ArchitectureArgumentDescription\" xml:space=\"preserve\">\n    <value>Selezionare l'architettura</value>\n  </data>\n  <data name=\"IncludeUnknownArgumentDescription\" xml:space=\"preserve\">\n    <value>Aggiorna i pacchetti anche se non è possibile determinare la versione corrente</value>\n  </data>\n  <data name=\"IncludeUnknownInListArgumentDescription\" xml:space=\"preserve\">\n    <value>Elenca i pacchetti anche se non è possibile determinare la versione corrente. Può essere utilizzato solo con l'argomento --upgrade-available</value>\n    <comment>{Locked=\"--upgrade-available\"}</comment>\n  </data>\n  <data name=\"UpgradeUnknownVersionExplanation\" xml:space=\"preserve\">\n    <value>Non è possibile determinare il numero di versione di questo pacchetto. Per aggiornarlo comunque, aggiungere l'argomento --include-unknown al comando precedente.</value>\n    <comment>{Locked=\"--include-unknown\"}</comment>\n  </data>\n  <data name=\"UpgradeUnknownVersionCount\" xml:space=\"preserve\">\n    <value>{0} pacchetti contengono numeri di versione che non possono essere determinati. Usare --include-unknown per visualizzare tutti i risultati.</value>\n    <comment>{Locked=\"{0}\",\"--include-unknown\"} {0} is a placeholder that is replaced by an integer number of packages that do not have notated versions. </comment>\n  </data>\n  <data name=\"UpgradeRequireExplicitCount\" xml:space=\"preserve\">\n    <value>{0} pacchetti sono aggiunti e devono essere aggiornati in modo esplicito.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by an integer number of packages that require explicit upgrades.</comment>\n  </data>\n  <data name=\"InvalidArgumentWithoutQueryError\" xml:space=\"preserve\">\n    <value>Gli argomenti specificati possono essere usati solo con una query.</value>\n  </data>\n  <data name=\"SystemArchitecture\" xml:space=\"preserve\">\n    <value>Architettura di sistema: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for the system architecture. {0} is a placeholder replaced by the value of the system architecture (e.g. X64).</comment>\n  </data>\n  <data name=\"PreserveArgumentDescription\" xml:space=\"preserve\">\n    <value>Conserva tutti i file e le directory creati dal pacchetto (portabile)</value>\n  </data>\n  <data name=\"PurgeArgumentDescription\" xml:space=\"preserve\">\n    <value>Elimina tutti i file e le directory nella directory dei pacchetti (portabile)</value>\n  </data>\n  <data name=\"PressEnterToContinue\" xml:space=\"preserve\">\n    <value>Premi INVIO per continuare</value>\n  </data>\n  <data name=\"RenameArgumentDescription\" xml:space=\"preserve\">\n    <value>Valore per rinominare il file eseguibile (portabile)</value>\n  </data>\n  <data name=\"WaitArgumentDescription\" xml:space=\"preserve\">\n    <value>Richiede all'utente di premere un tasto qualsiasi prima di uscire</value>\n  </data>\n  <data name=\"InstallerElevationExpected\" xml:space=\"preserve\">\n    <value>Il programma di installazione richiederà l'esecuzione come amministratore. È previsto un prompt.</value>\n  </data>\n  <data name=\"InstallerProhibitsElevation\" xml:space=\"preserve\">\n    <value>Impossibile eseguire il programma di installazione da un contesto di amministratore.</value>\n  </data>\n  <data name=\"ModifiedPathRequiresShellRestart\" xml:space=\"preserve\">\n    <value>Variabile di ambiente del percorso modificata; riavviare la shell per usare il nuovo valore.</value>\n  </data>\n  <data name=\"ProductCodeArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtri che usano il codice prodotto</value>\n  </data>\n  <data name=\"PortableRegistryCollisionOverridden\" xml:space=\"preserve\">\n    <value>Esiste già un pacchetto portabile con lo stesso nome ma proveniente da un'origine diversa; procedi a causa di --force</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"ReparsePointsNotSupportedError\" xml:space=\"preserve\">\n    <value>Il volume non supporta i dati reparse point</value>\n  </data>\n  <data name=\"ReservedFilenameError\" xml:space=\"preserve\">\n    <value>Il nome file specificato non è un nome di file valido</value>\n  </data>\n  <data name=\"OverwritingExistingFileAtMessage\" xml:space=\"preserve\">\n    <value>Sovrascrittura file esistente: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed to inform the user that an existing file is being overwritten. {0} is a placeholder replaced by the file system path.</comment>\n  </data>\n  <data name=\"NoPackageSelectionArgumentProvided\" xml:space=\"preserve\">\n    <value>Non è stato specificato alcun argomento di selezione pacchetto; per informazioni dettagliate sulla ricerca di un pacchetto, vedere la Guida.</value>\n  </data>\n  <data name=\"PortableAliasAdded\" xml:space=\"preserve\">\n    <value>Alias della riga di comando aggiunto:</value>\n  </data>\n  <data name=\"PortableLinksMachine\" xml:space=\"preserve\">\n    <value>Directory collegamenti portabili (computer)</value>\n  </data>\n  <data name=\"PortableLinksUser\" xml:space=\"preserve\">\n    <value>Directory collegamenti portabili (utente)</value>\n  </data>\n  <data name=\"PortableRootUser\" xml:space=\"preserve\">\n    <value>Radice pacchetto portabile (utente)</value>\n  </data>\n  <data name=\"PortableRoot\" xml:space=\"preserve\">\n    <value>Radice pacchetto portabile</value>\n  </data>\n  <data name=\"PortableRoot86\" xml:space=\"preserve\">\n    <value>Radice pacchetto portabile (x86)</value>\n  </data>\n  <data name=\"PortableInstallFailed\" xml:space=\"preserve\">\n    <value>Installazione portabile non riuscita; Pulizia...</value>\n  </data>\n  <data name=\"PortableHashMismatchOverridden\" xml:space=\"preserve\">\n    <value>Il pacchetto portatile è stato modificato; procedimento causato da --force</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"PortableHashMismatchOverrideRequired\" xml:space=\"preserve\">\n    <value>Impossibile rimuovere il pacchetto portabile perché è stato modificato; per eseguire la sostituzione di questo controllo usare --force</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"FilesRemainInInstallDirectory\" xml:space=\"preserve\">\n    <value>I file rimangono nella directory di installazione: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when files remain in install directory. {0} is a placeholder replaced by the directory path.</comment>\n  </data>\n  <data name=\"PurgeInstallDirectory\" xml:space=\"preserve\">\n    <value>Eliminazione della directory di installazione in corso...</value>\n  </data>\n  <data name=\"UnableToPurgeInstallDirectory\" xml:space=\"preserve\">\n    <value>Non è possibile eliminare la directory di installazione, poiché non è stata creata da WinGet.</value>\n  </data>\n  <data name=\"RelatedLink\" xml:space=\"preserve\">\n    <value>Collegamento correlato</value>\n  </data>\n  <data name=\"ShowLabelDocumentation\" xml:space=\"preserve\">\n    <value>Documentazione:</value>\n  </data>\n  <data name=\"Notes\" xml:space=\"preserve\">\n    <value>Note: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for installation notes. {0} is a placeholder replaced by installation notes.</comment>\n  </data>\n  <data name=\"ShowLabelInstallationNotes\" xml:space=\"preserve\">\n    <value>Note sull'installazione:</value>\n  </data>\n  <data name=\"UnsupportedArgument\" xml:space=\"preserve\">\n    <value>Un argomento specificato non è supportato per questo pacchetto</value>\n  </data>\n  <data name=\"ExtractArchiveFailed\" xml:space=\"preserve\">\n    <value>Non è stato possibile estrarre il contenuto dell'archivio</value>\n  </data>\n  <data name=\"NestedInstallerNotFound\" xml:space=\"preserve\">\n    <value>Il file del programma di installazione annidato non esiste. Assicurarsi che il percorso relativo specificato del programma di installazione annidato corrisponda a: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when nested installer file does not exist. {0} is a placeholder replaced by the nested installer file path.</comment>\n  </data>\n  <data name=\"InvalidPathToNestedInstaller\" xml:space=\"preserve\">\n    <value>Il percorso relativo del file del programma di installazione annidato non è valido. il percorso punta a un percorso esterno alla directory di installazione</value>\n  </data>\n  <data name=\"NestedInstallerNotSpecified\" xml:space=\"preserve\">\n    <value>Nessun programma di installazione annidato specificato per questo pacchetto</value>\n  </data>\n  <data name=\"MultipleUnsupportedNestedInstallersSpecified\" xml:space=\"preserve\">\n    <value>È possibile specificare un solo programma di installazione annidato per un programma di installazione di archivio, a meno che non si tratti di un programma di installazione portatile o annidato del tipo di carattere</value>\n  </data>\n  <data name=\"IncompatibleArgumentsProvided\" xml:space=\"preserve\">\n    <value>Sono stati specificati argomenti della riga di comando incompatibili</value>\n  </data>\n  <data name=\"UpgradeArgumentDescription\" xml:space=\"preserve\">\n    <value>Elenca solo i pacchetti con un aggiornamento disponibile</value>\n  </data>\n  <data name=\"UpgradeAvailableForPinned\" xml:space=\"preserve\">\n    <value>Per i pacchetti seguenti è disponibile un aggiornamento, ma è necessario un targeting esplicito per l'aggiornamento:</value>\n    <comment>\"require explicit targeting for upgrade\" means that the package will not be upgraded with all others unless an extra flag is added, or the package is mentioned explicitly</comment>\n  </data>\n  <data name=\"Downloading\" xml:space=\"preserve\">\n    <value>Download in corso</value>\n    <comment>Label displayed while downloading an application installer.</comment>\n  </data>\n  <data name=\"NestedInstallerNotSupported\" xml:space=\"preserve\">\n    <value>Il tipo di programma di installazione annidato non è supportato</value>\n  </data>\n  <data name=\"InstallerAbortsTerminal\" xml:space=\"preserve\">\n    <value>Questo programma di installazione riavvia il terminale o la shell</value>\n  </data>\n  <data name=\"InstallerRequiresInstallLocation\" xml:space=\"preserve\">\n    <value>Questo pacchetto richiede un percorso di installazione</value>\n  </data>\n  <data name=\"InstallersAbortTerminal\" xml:space=\"preserve\">\n    <value>I programmi di installazione seguenti riavviano il terminale o la shell:</value>\n  </data>\n  <data name=\"InstallersRequireInstallLocation\" xml:space=\"preserve\">\n    <value>I seguenti programmi di installazione richiedono un percorso di installazione:</value>\n  </data>\n  <data name=\"PromptForInstallRoot\" xml:space=\"preserve\">\n    <value>Specificare la radice di installazione:</value>\n  </data>\n  <data name=\"PromptToProceed\" xml:space=\"preserve\">\n    <value>Continuare?</value>\n  </data>\n  <data name=\"ReportIdentityForAgreements\" xml:space=\"preserve\">\n    <value>Accordi per</value>\n    <comment>This will be followed by a package name, and then a list of license agreements</comment>\n  </data>\n  <data name=\"InstallLocationNotProvided\" xml:space=\"preserve\">\n    <value>Il percorso di installazione è richiesto dal pacchetto, ma non è stato specificato</value>\n  </data>\n  <data name=\"DisableInteractivityArgumentDescription\" xml:space=\"preserve\">\n    <value>Disabilita prompt interattivi</value>\n    <comment>Description for a command line argument, shown next to it in the help</comment>\n  </data>\n  <data name=\"ConvertInstallFlowToUpgrade\" xml:space=\"preserve\">\n    <value>È stato trovato un pacchetto esistente già installato. Tentativo di aggiornamento del pacchetto installato...</value>\n  </data>\n  <data name=\"ForceArgumentDescription\" xml:space=\"preserve\">\n    <value>Esegui direttamente il comando e continua con problemi non correlati alla sicurezza</value>\n    <comment>Description for a command line argument, shown next to it in the help</comment>\n  </data>\n  <data name=\"PortablePackageAlreadyExists\" xml:space=\"preserve\">\n    <value>Esiste già un pacchetto portabile da un'origine diversa</value>\n  </data>\n  <data name=\"ExtractArchiveSucceeded\" xml:space=\"preserve\">\n    <value>Estrazione del file compresso completata con successo.</value>\n  </data>\n  <data name=\"ExtractingArchive\" xml:space=\"preserve\">\n    <value>Estrazione del file compresso</value>\n  </data>\n  <data name=\"ArchiveFailedMalwareScan\" xml:space=\"preserve\">\n    <value>L'analisi dell'archivio ha rilevato malware. Per eseguire l'override di questo controllo, usare --ignore-local-archive-malware-scan</value>\n    <comment>{Locked=\"--ignore-local-archive-malware-scan\"}</comment>\n  </data>\n  <data name=\"ArchiveFailedMalwareScanOverridden\" xml:space=\"preserve\">\n    <value>L’analisi dell'archivio ha rilevato un malware. Operazione in corso a causa di --ignore-local-archive-malware-scan</value>\n    <comment>{Locked=\"--ignore-local-archive-malware-scan\"}</comment>\n  </data>\n  <data name=\"NoUpgradeArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignora l'aggiornamento se esiste già una versione installata</value>\n  </data>\n  <data name=\"PackageAlreadyInstalled\" xml:space=\"preserve\">\n    <value>È già installata una versione del pacchetto. Installazione annullata.</value>\n  </data>\n  <data name=\"EnableAdminSettingFailed\" xml:space=\"preserve\">\n    <value>Impossibile abilitare {0}. Questa impostazione è controllata dai criteri. Per ulteriori informazioni, contattare l'amministratore di sistema.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"DisableAdminSettingFailed\" xml:space=\"preserve\">\n    <value>Impossibile disabilitare {0}. Questa impostazione è controllata dai criteri. Per ulteriori informazioni, contattare l'amministratore di sistema.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"PinAddCommandLongDescription\" xml:space=\"preserve\">\n    <value>Aggiungi un nuovo PIN. Un PIN può limitare il Gestione pacchetti Windows dall'aggiornamento di un pacchetto a intervalli di versioni specifici o impedire l'aggiornamento del pacchetto. Un pacchetto aggiunto potrebbe ancora essere aggiornato autonomamente ed essere aggiornato dall'esterno del Gestione pacchetti Windows. Per impostazione predefinita, è possibile aggiornare un pacchetto aggiunto menzionandolo in modo esplicito nel comando 'upgrade' o aggiungendo il flag '--include-pinned' a 'winget upgrade --all'.</value>\n    <comment>{Locked{\"'upgrade'\"} Locked{\"--include-pinned\"} Locked{\"winget upgrade --all\"}</comment>\n  </data>\n  <data name=\"PinAddCommandShortDescription\" xml:space=\"preserve\">\n    <value>Aggiungi un nuovo pin</value>\n  </data>\n  <data name=\"PinCommandLongDescription\" xml:space=\"preserve\">\n    <value>Gestione dei pin dei pacchetti con i sotto-comandi. Il pin può limitare l'aggiornamento di un pacchetto da parte di Gestione pacchetti Windows a intervalli specifici di versioni o può impedire l'aggiornamento del pacchetto stesso. Un pacchetto con il pin può comunque aggiornarsi da solo ed essere aggiornato dall'esterno di Gestione pacchetti Windows.</value>\n  </data>\n  <data name=\"PinCommandShortDescription\" xml:space=\"preserve\">\n    <value>Gestisci i pin del pacchetto</value>\n  </data>\n  <data name=\"PinListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Elenca tutti i pin correnti o i dettagli completi di un pin specifico.</value>\n  </data>\n  <data name=\"PinListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Elenca i pin correnti</value>\n  </data>\n  <data name=\"PinRemoveCommandLongDescription\" xml:space=\"preserve\">\n    <value>Rimuovi un pin specifico del pacchetto.</value>\n  </data>\n  <data name=\"PinRemoveCommandShortDescription\" xml:space=\"preserve\">\n    <value>Rimuovi un pin del pacchetto</value>\n  </data>\n  <data name=\"PinResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>Reimposta tutti i pin esistenti.</value>\n  </data>\n  <data name=\"PinResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>Reimposta i pin</value>\n  </data>\n  <data name=\"GatedVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>Versione a cui aggiungere il pacchetto. È possibile usare il carattere jolly '*' come ultima parte della versione</value>\n  </data>\n  <data name=\"PinAddBlockingArgumentDescription\" xml:space=\"preserve\">\n    <value>Blocca l'aggiornamento fino a quando il pin non viene rimosso, evitando la sostituzione degli argomenti</value>\n  </data>\n  <data name=\"PinInstalledArgumentDescription\" xml:space=\"preserve\">\n    <value>Aggiungi una versione installata specifica</value>\n  </data>\n  <data name=\"PinInstalledSource\" xml:space=\"preserve\">\n    <value>Installato</value>\n    <comment>Value used in a table to indicate that a package comes from the list of packages installed in the machine</comment>\n  </data>\n  <data name=\"SettingsExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Esporta le impostazioni come JSON</value>\n  </data>\n  <data name=\"SettingsExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Impostazioni di esportazione</value>\n  </data>\n  <data name=\"UserSettings\" xml:space=\"preserve\">\n    <value>Impostazioni utente</value>\n    <comment>Label displayed for the file containing the user settings.</comment>\n  </data>\n  <data name=\"SettingsWarningUsingDefault\" xml:space=\"preserve\">\n    <value>Non è stato possibile caricare il file delle impostazioni. Utilizzo dei valori predefiniti.</value>\n  </data>\n  <data name=\"InstalledScopeArgumentDescription\" xml:space=\"preserve\">\n    <value>Selezionare il filtro dell'ambito del pacchetto installato (user o machine)</value>\n    <comment>{Locked=\"user\",\"machine\"} This argument allows the user to select installed packages for just the user or for the entire machine.</comment>\n  </data>\n  <data name=\"PinAdded\" xml:space=\"preserve\">\n    <value>Aggiunta del pin completata</value>\n  </data>\n  <data name=\"PinAlreadyExists\" xml:space=\"preserve\">\n    <value>È già presente un PIN per il pacchetto {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that will be replaced by a package name. The message is shown when attempting to add a pin for a package that is already pinned.</comment>\n  </data>\n  <data name=\"PinExistsOverwriting\" xml:space=\"preserve\">\n    <value>Per il pacchetto {0} esiste già un PIN. Sovrascrittura a causa dell'argomento --force.</value>\n    <comment>{Locked=\"--force\"}{Locked=\"--force\",\"{0}\"} {0} is a placeholder that will be replaced by a package name.</comment>\n  </data>\n  <data name=\"PinExistsUseForceArg\" xml:space=\"preserve\">\n    <value>Per il pacchetto {0} esiste già un PIN. Utilizzare l'argomento --force per sovrascriverlo.</value>\n    <comment>{Locked=\"--force\",\"{0}\"} {0} is a placeholder that will be replaced by a package name.</comment>\n  </data>\n  <data name=\"PinResettingAll\" xml:space=\"preserve\">\n    <value>Reimpostazione di tutti i pin correnti.</value>\n  </data>\n  <data name=\"PinResetUseForceArg\" xml:space=\"preserve\">\n    <value>Utilizza l'argomento --force per reimpostare tutti i pin. I pin seguenti verranno rimossi:</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"PinType\" xml:space=\"preserve\">\n    <value>Tipo di pin</value>\n  </data>\n  <data name=\"PinDoesNotExist\" xml:space=\"preserve\">\n    <value>Nessun PIN per il pacchetto {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that will be replaced by a package name. The message is shown when attempting to delete a pin for a package that is not pinned.</comment>\n  </data>\n  <data name=\"PinNoPinsExist\" xml:space=\"preserve\">\n    <value>Nessun PIN configurato.</value>\n    <comment>Shown when listing or modifying existing pins if there are none.</comment>\n  </data>\n  <data name=\"PinResetSuccessful\" xml:space=\"preserve\">\n    <value>Reimpostazione dei pin completata</value>\n    <comment>Shown after resetting (deleting) all the pins</comment>\n  </data>\n  <data name=\"PinCannotOpenIndex\" xml:space=\"preserve\">\n    <value>Impossibile aprire il database pin.</value>\n    <comment>Error message for when we cannot open the database containing package pins.</comment>\n  </data>\n  <data name=\"ArgumentForSinglePackageProvidedWithMultipleQueries\" xml:space=\"preserve\">\n    <value>È stato specificato un argomento che può essere usato solo per un pacchetto singolo</value>\n  </data>\n  <data name=\"MultipleExclusiveArgumentsProvided\" xml:space=\"preserve\">\n    <value>Sono stati specificati più argomenti che si escludono a vicenda: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message shown when mutually incompatible command line arguments are used. {0} is a placeholder replaced by the arguments that cannot be specified together</comment>\n  </data>\n  <data name=\"DependencyArgumentMissing\" xml:space=\"preserve\">\n    <value>L'argomento {0} può essere utilizzato solo con {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message shown when having an argument needs another to be present, but that is missing. {0} and {1} are replaced by the arguments. For example \"Argument --include-unknown can only be used with --upgrade\"</comment>\n  </data>\n  <data name=\"StateDisabled\" xml:space=\"preserve\">\n    <value>Disabilitate</value>\n    <comment>As in enabled/disabled</comment>\n  </data>\n  <data name=\"StateEnabled\" xml:space=\"preserve\">\n    <value>Abilitata</value>\n    <comment>As in enabled/disabled</comment>\n  </data>\n  <data name=\"StateHeader\" xml:space=\"preserve\">\n    <value>Stato</value>\n    <comment>Header for a table listing the state (enabled/disabled) of Group Policies and Settings</comment>\n  </data>\n  <data name=\"MultiQueryArgumentDescription\" xml:space=\"preserve\">\n    <value>Query usata per cercare un'app</value>\n  </data>\n  <data name=\"MultiQueryPackageNotFound\" xml:space=\"preserve\">\n    <value>Pacchetto non trovato: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches returns no results. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"MultiQuerySearchFoundMultiple\" xml:space=\"preserve\">\n    <value>Sono stati trovati più pacchetti per: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches returns more than one result. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"MultiQuerySearchFailed\" xml:space=\"preserve\">\n    <value>Ricerca non riuscita per: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches fails. This message is for generic failures, we have more specific messages for when the search returns no results, or when it returns more than one result. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"UpgradeBlockedByPinCount\" xml:space=\"preserve\">\n    <value>{0} pacchetti hanno un PIN che deve essere rimosso prima dell'aggiornamento</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by an integer number of packages with pins that prevent upgrade</comment>\n  </data>\n  <data name=\"UpgradeBlockedByManifest\" xml:space=\"preserve\">\n    <value>Non è possibile aggiornare il pacchetto con WinGet. Usare il metodo fornito dal server di pubblicazione per l'aggiornamento di questo pacchetto.</value>\n  </data>\n  <data name=\"IncludePinnedArgumentDescription\" xml:space=\"preserve\">\n    <value>Aggiorna i pacchetti anche se hanno un PIN non bloccante</value>\n  </data>\n  <data name=\"IncludePinnedInListArgumentDescription\" xml:space=\"preserve\">\n    <value>Elenca i pacchetti anche se hanno un PIN che impedisce l'aggiornamento. Può essere utilizzato solo con l'argomento --upgrade-available</value>\n    <comment>{Locked=\"--upgrade-available\"}</comment>\n  </data>\n  <data name=\"PinRemovedSuccessfully\" xml:space=\"preserve\">\n    <value>L'aggiunta è stata rimossa</value>\n  </data>\n  <data name=\"UpgradeIsPinned\" xml:space=\"preserve\">\n    <value>È stata trovata una versione più recente, ma il pacchetto contiene un PIN che impedisce l'aggiornamento.</value>\n  </data>\n  <data name=\"PackageIsPinned\" xml:space=\"preserve\">\n    <value>Il pacchetto è bloccato e non può essere aggiornato. Utilizza il comando 'winget pin' per visualizzare e modificare le scelte. Alcuni tipi di PIN possono essere ignorati con l'argomento --include-pinned.</value>\n    <comment>{Locked=\"winget pin\",\"--include-pinned\"} Error shown when we block an upgrade due to the package being pinned</comment>\n  </data>\n  <data name=\"UpgradePinnedByUserCount\" xml:space=\"preserve\">\n    <value>{0} pacchetti contiene pin che impediscono l'aggiornamento. Utilizza il comando 'winget pin' per visualizzare e modificare le scelte. L'utilizzo dell'argomento --include-pinned può mostrare più risultati.</value>\n    <comment>{Locked=\"winget pin\",\"--include-pinned\"} {0} is a placeholder replaced by an integer number of packages</comment>\n  </data>\n  <data name=\"ConfigureCommandLongDescription\" xml:space=\"preserve\">\n    <value>Assicura che il sistema corrisponda allo stato desiderato, come descritto dalla configurazione fornita. Può scaricare/eseguire i processori per ottenere lo stato desiderato. La configurazione e i processori devono essere controllati per verificarne l'attendibilità prima di applicarli.</value>\n  </data>\n  <data name=\"ConfigureCommandShortDescription\" xml:space=\"preserve\">\n    <value>Configura il sistema in uno stato desiderato</value>\n  </data>\n  <data name=\"ConfigureShowCommandLongDescription\" xml:space=\"preserve\">\n    <value>Mostra i dettagli della configurazione fornita. Per impostazione predefinita, il sistema non verrà modificato, ma alcune opzioni determineranno il download e/o il caricamento dei file.</value>\n  </data>\n  <data name=\"ConfigureShowCommandShortDescription\" xml:space=\"preserve\">\n    <value>Mostra i dettagli di una configurazione</value>\n  </data>\n  <data name=\"ConfigureTestCommandLongDescription\" xml:space=\"preserve\">\n    <value>Controlla che il sistema corrisponda allo stato desiderato come descritto dalla configurazione fornita. Può scaricare/eseguire processori per testare lo stato desiderato. Verificare che la configurazione e i processori siano attendibili prima di eseguirli.</value>\n  </data>\n  <data name=\"ConfigureTestCommandShortDescription\" xml:space=\"preserve\">\n    <value>Controlla il sistema rispetto a uno stato desiderato</value>\n  </data>\n  <data name=\"ConfigureValidateCommandLongDescription\" xml:space=\"preserve\">\n    <value>Convalida un file di configurazione per la correttezza.</value>\n  </data>\n  <data name=\"ConfigureValidateCommandShortDescription\" xml:space=\"preserve\">\n    <value>Convalida un file di configurazione</value>\n  </data>\n  <data name=\"ConfigurationFieldInvalidType\" xml:space=\"preserve\">\n    <value>Il tipo del campo '{0}' nel file di configurazione non è corretto.</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the field name from the file.</comment>\n  </data>\n  <data name=\"ConfigurationFileArgumentDescription\" xml:space=\"preserve\">\n    <value>Percorso del file di configurazione</value>\n  </data>\n  <data name=\"ConfigurationFileInvalid\" xml:space=\"preserve\">\n    <value>Il file di configurazione non è valido.</value>\n  </data>\n  <data name=\"ConfigurationFileVersionUnknown\" xml:space=\"preserve\">\n    <value>La versione del file di configurazione {0} non è nota.</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the version of the configuration file.</comment>\n  </data>\n  <data name=\"ConfigurationAcceptWarningArgumentDescription\" xml:space=\"preserve\">\n    <value>Accetta l'avviso di configurazione, impedendo un prompt interattivo</value>\n  </data>\n  <data name=\"ConfigurationApply\" xml:space=\"preserve\">\n    <value>Applica</value>\n    <comment>Indicates that this item is used to write state</comment>\n  </data>\n  <data name=\"ConfigurationAssert\" xml:space=\"preserve\">\n    <value>Asserzione</value>\n    <comment>Indicates that this item is used to check/assert the state rather than write to it</comment>\n  </data>\n  <data name=\"ConfigurationDependencies\" xml:space=\"preserve\">\n    <value>Dipendenze:{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying a list of dependencies. {0} is replaced with a space separated list of identifiers referencing other items.</comment>\n  </data>\n  <data name=\"ConfigurationFailedToApply\" xml:space=\"preserve\">\n    <value>Parte della configurazione non è stata applicata correttamente.</value>\n  </data>\n  <data name=\"ConfigurationFailedToGetDetails\" xml:space=\"preserve\">\n    <value>Impossibile ottenere informazioni dettagliate sulla configurazione.</value>\n  </data>\n  <data name=\"ConfigurationInform\" xml:space=\"preserve\">\n    <value>Informare</value>\n    <comment>Indicates that this item is used to retrieve values for future use rather than writing them</comment>\n  </data>\n  <data name=\"ConfigurationLocal\" xml:space=\"preserve\">\n    <value>Locale</value>\n    <comment>Used to indicate that the item is present on the device.</comment>\n  </data>\n  <data name=\"ConfigurationModuleNameOnly\" xml:space=\"preserve\">\n    <value>Modulo: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying a module name. {0} is replaced with the name of the module from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationModuleWithDetails\" xml:space=\"preserve\">\n    <value>Modulo: {0} per {1} [{2}]</value>\n    <comment>{Locked=\"{0}\",\"{1}\",\"{2}\"} Label displaying module information. {0} is replaced by the module name. {1} is replaced by the module author. {2} is replaced by a string indicating the source of the module.</comment>\n  </data>\n  <data name=\"ConfigurationSettings\" xml:space=\"preserve\">\n    <value>Impostazioni:</value>\n    <comment>Label for the values that are used as inputs for this item when applying state</comment>\n  </data>\n  <data name=\"ConfigurationSuccessfullyApplied\" xml:space=\"preserve\">\n    <value>La configurazione è stata applicata.</value>\n  </data>\n  <data name=\"ConfigurationUnitSuccessfullyApplied\" xml:space=\"preserve\">\n    <value>Unità applicata correttamente.</value>\n  </data>\n  <data name=\"ConfigurationWaitingOnAnother\" xml:space=\"preserve\">\n    <value>È in corso l'applicazione di un'altra configurazione al sistema. Questa configurazione continuerà non appena possibile...</value>\n  </data>\n  <data name=\"ConfigurationWarning\" xml:space=\"preserve\">\n    <value>È tua responsabilità comprendere le impostazioni di configurazione che scegli di eseguire. Microsoft non è responsabile del file di configurazione creato o importato. Questa configurazione può modificare le impostazioni in Windows, installare software, modificare le impostazioni del software (incluse le impostazioni di sicurezza) e accettare contratti utente per i pacchetti e i servizi di terze parti per conto dell'utente.  Eseguendo questo file di configurazione, riconosci e accetti queste risorse e impostazioni. Tutte le applicazioni installate sono concesse in licenza dai proprietari. Microsoft non è responsabile né concede alcuna licenza a pacchetti o servizi di terze parti.</value>\n    <comment>Legal approved. Do not change without approval.</comment>\n  </data>\n  <data name=\"ConfigurationWarningPromptApply\" xml:space=\"preserve\">\n    <value>La configurazione è stata esaminata e si desidera procedere con l'applicazione al sistema?</value>\n    <comment>PM approved.</comment>\n  </data>\n  <data name=\"ConfigurationFileEmpty\" xml:space=\"preserve\">\n    <value>La configurazione è vuota.</value>\n  </data>\n  <data name=\"WindowsFeatureNotFound\" xml:space=\"preserve\">\n    <value>La funzionalità [{0}] non è stata trovata.</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Windows feature was not found on the system.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeatureOverrideRequired\" xml:space=\"preserve\">\n    <value>Non è stato possibile abilitare le dipendenze delle funzionalità di Windows. Per procedere con l'installazione, usare '--force'.</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"RebootRequiredToEnableWindowsFeatureOverrideRequired\" xml:space=\"preserve\">\n    <value>Riavvio richiesto per abilitare completamente le funzioni di Windows; per ignorare questo controllo, usare '--force'.</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeatureOverridden\" xml:space=\"preserve\">\n    <value>Non è stato possibile abilitare le dipendenze delle funzionalità di Windows; in corso a causa di --force</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.\n{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"EnablingWindowsFeature\" xml:space=\"preserve\">\n    <value>Abilitazione di [{0}] in corso...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to the user regarding which Windows Feature is being enabled.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeature\" xml:space=\"preserve\">\n    <value>Non è stato possibile abilitare la funzionalità [{0}]: {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"}  An error when enabling a Windows Feature. {0} is a placeholder for the name of the Windows Feature.\n{1} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"RebootRequiredToEnableWindowsFeatureOverridden\" xml:space=\"preserve\">\n    <value>È necessario riavviare il sistema per abilitare completamente le funzionalità di Windows. procedi a causa di --force</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.</comment>\n  </data>\n  <data name=\"InstallWaitingOnAnother\" xml:space=\"preserve\">\n    <value>In attesa del completamento di un'altra installazione/disinstallazione...</value>\n  </data>\n  <data name=\"PinVersion\" xml:space=\"preserve\">\n    <value>Versione aggiunta</value>\n    <comment>Table header for the version to which a package is pinned; meaning it should not update from that version.</comment>\n  </data>\n  <data name=\"ConfigurationDescriptionWasTruncated\" xml:space=\"preserve\">\n    <value>&lt;Per ulteriori dettagli vedi il file di log&gt;</value>\n    <comment>The brackets are intended to make the value stand out from other text which it will follow. Any locale appropriate mechanism that achieves this is acceptable.</comment>\n  </data>\n  <data name=\"ConfigurationGettingDetails\" xml:space=\"preserve\">\n    <value>Recupero dei dettagli della configurazione</value>\n  </data>\n  <data name=\"ConfigurationInitializing\" xml:space=\"preserve\">\n    <value>Inizializzazione del sistema di configurazione</value>\n  </data>\n  <data name=\"ConfigurationReadingConfigFile\" xml:space=\"preserve\">\n    <value>Lettura del file di configurazione</value>\n  </data>\n  <data name=\"ConfigurationUnitAssertHadNegativeResult\" xml:space=\"preserve\">\n    <value>Il sistema non si trova nello stato desiderato dichiarato dalla configurazione.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailed\" xml:space=\"preserve\">\n    <value>L'unità di configurazione non è riuscita per un motivo sconosciuto: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedConfigSet\" xml:space=\"preserve\">\n    <value>L'unità di configurazione non è riuscita a causa della configurazione: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringGet\" xml:space=\"preserve\">\n    <value>Errore dell'unità di configurazione durante il tentativo di ottenere lo stato corrente del sistema.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringSet\" xml:space=\"preserve\">\n    <value>Errore dell'unità di configurazione durante il tentativo di applicare lo stato desiderato.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringTest\" xml:space=\"preserve\">\n    <value>Errore dell'unità di configurazione durante il tentativo di testare lo stato corrente del sistema.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedInternal\" xml:space=\"preserve\">\n    <value>L'unità di configurazione non è riuscita a causa di un errore interno: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedPrecondition\" xml:space=\"preserve\">\n    <value>L'unità di configurazione non è riuscita perché una condizione preliminare non è valida: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedSystemState\" xml:space=\"preserve\">\n    <value>L'unità di configurazione non è riuscita a causa dello stato del sistema: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedUnitProcessing\" xml:space=\"preserve\">\n    <value>Errore dell'unità di configurazione durante il tentativo di esecuzione: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitHasDuplicateIdentifier\" xml:space=\"preserve\">\n    <value>La configurazione contiene l'identificatore '{0}' più volte.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by the identifier string from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationUnitHasMissingDependency\" xml:space=\"preserve\">\n    <value>La dipendenza '{0}' non è stata trovata nella configurazione.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by the identifier string from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationUnitManuallySkipped\" xml:space=\"preserve\">\n    <value>Questa unità di configurazione è stata ignorata manualmente.</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleConflict\" xml:space=\"preserve\">\n    <value>Il modulo per l'unità di configurazione è disponibile in più località con la stessa versione.</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleImportFailed\" xml:space=\"preserve\">\n    <value>Caricamento del modulo per l'unità di configurazione non riuscito.</value>\n  </data>\n  <data name=\"ConfigurationUnitMultipleMatches\" xml:space=\"preserve\">\n    <value>Sono state trovate più corrispondenze per l'unità di configurazione; specificare il modulo per selezionare quello corretto.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotFound\" xml:space=\"preserve\">\n    <value>Impossibile trovare l'unità di configurazione.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotFoundInModule\" xml:space=\"preserve\">\n    <value>L'unità di configurazione non si trovava nel modulo come previsto.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotRunDueToDependency\" xml:space=\"preserve\">\n    <value>L'unità di configurazione non è stata eseguita perché una dipendenza non è riuscita o non è stata eseguita.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotRunDueToFailedAssert\" xml:space=\"preserve\">\n    <value>L'unità di configurazione non è stata eseguita perché un'asserzione non è riuscita o è false.</value>\n  </data>\n  <data name=\"ConfigurationUnitReturnedInvalidResult\" xml:space=\"preserve\">\n    <value>L'unità di configurazione ha restituito un risultato imprevisto durante l'esecuzione.</value>\n  </data>\n  <data name=\"ConfigurationUnitSkipped\" xml:space=\"preserve\">\n    <value>L'unità di configurazione non è stata eseguita per un motivo sconosciuto: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationFieldInvalidValue\" xml:space=\"preserve\">\n    <value>Il campo '{0}' ha un valore non valido: {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} An error in reading a configuration file. {0} is a placeholder replaced by the field name from the file. {1} is a placeholder for the invalid value.</comment>\n  </data>\n  <data name=\"ConfigurationFieldMissing\" xml:space=\"preserve\">\n    <value>Il campo '{0}' è mancante o vuoto.</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the expected field name from the file.</comment>\n  </data>\n  <data name=\"SeeLineAndColumn\" xml:space=\"preserve\">\n    <value>Vedere la riga {0}, la colonna {1} nel file.</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Indicates the file location of the error, {0} and {1} are placeholders for numbers of the line and column, respectively.</comment>\n  </data>\n  <data name=\"CancellingOperation\" xml:space=\"preserve\">\n    <value>Annullamento dell'operazione</value>\n  </data>\n  <data name=\"InstallStubPackageDescription\" xml:space=\"preserve\">\n    <value>Installa il pacchetto di stub per AppInstaller</value>\n  </data>\n  <data name=\"InstallFullPackageDescription\" xml:space=\"preserve\">\n    <value>Installa il pacchetto completo per AppInstaller</value>\n  </data>\n  <data name=\"ExtendedFeaturesEnableMessage\" xml:space=\"preserve\">\n    <value>Abilita le funzionalità estese. Richiede l'accesso all'archivio.</value>\n  </data>\n  <data name=\"ExtendedFeaturesEnableArgumentError\" xml:space=\"preserve\">\n    <value>Non è possibile usare le opzioni \"--enable\" e \"--disable\" con altri argomenti.</value>\n    <comment>{Locked=\"--enable\", \"--disable\"}</comment>\n  </data>\n  <data name=\"ExtendedFeaturesEnablingMessage\" xml:space=\"preserve\">\n    <value>Abilitazione delle funzionalità estese. Richiede l'accesso all'archivio.</value>\n  </data>\n  <data name=\"ExtendedFeaturesNotEnabledMessage\" xml:space=\"preserve\">\n    <value>Le funzionalità estese non sono abilitate. Eseguire \"winget configure --enable\" per abilitarli.</value>\n    <comment>{Locked=\"winget configure --enable\"}</comment>\n  </data>\n  <data name=\"ExtendedFeaturesEnabledMessage\" xml:space=\"preserve\">\n    <value>Le funzionalità estese sono abilitate.</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisableMessage\" xml:space=\"preserve\">\n    <value>Disabilitare le funzionalità estese. Richiede l'accesso all'archivio.</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisablingMessage\" xml:space=\"preserve\">\n    <value>Disabilitazione delle funzionalità estese. Richiede l'accesso all'archivio.</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisabledMessage\" xml:space=\"preserve\">\n    <value>Le funzionalità estese sono disabilitate.</value>\n  </data>\n  <data name=\"SkipDependenciesArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignora l'elaborazione delle dipendenze dei pacchetti e delle funzionalità di Windows</value>\n  </data>\n  <data name=\"DependenciesSkippedMessage\" xml:space=\"preserve\">\n    <value>Dipendenze ignorate.</value>\n  </data>\n  <data name=\"FailedToRefreshPathWarning\" xml:space=\"preserve\">\n    <value>Non è stato possibile aggiornare la variabile PATH per il processo. Le installazioni successive che dipendono dalle modifiche apportate alla variabile PATH potrebbero non riuscire.</value>\n    <comment>{Locked=\"PATH\"}</comment>\n  </data>\n  <data name=\"ConfigurationFailedToTest\" xml:space=\"preserve\">\n    <value>Errore di alcune unità di configurazione durante il test dello stato.</value>\n  </data>\n  <data name=\"ConfigurationInDesiredState\" xml:space=\"preserve\">\n    <value>Il sistema si trova nello stato di configurazione descritto.</value>\n  </data>\n  <data name=\"ConfigurationNoTestRun\" xml:space=\"preserve\">\n    <value>Lo stato della configurazione non è stato testato.</value>\n  </data>\n  <data name=\"ConfigurationNotInDesiredState\" xml:space=\"preserve\">\n    <value>Il sistema non si trova nello stato di configurazione descritto.</value>\n  </data>\n  <data name=\"ConfigurationUnexpectedTestResult\" xml:space=\"preserve\">\n    <value>Risultato del test imprevisto: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message. {0} will be replaced with the unexpected value (a number).</comment>\n  </data>\n  <data name=\"ConfigurationWarningPromptTest\" xml:space=\"preserve\">\n    <value>La configurazione è stata esaminata e si desidera procedere con la verifica del sistema?</value>\n  </data>\n  <data name=\"ConfigurationFileInvalidYAML\" xml:space=\"preserve\">\n    <value>Il file di configurazione non è un file di YAML valido.</value>\n    <comment>{Locked=\"YAML\"} YAML is a file format name.</comment>\n  </data>\n  <data name=\"ConfigurationUnitIsPartOfDependencyCycle\" xml:space=\"preserve\">\n    <value>Questa unità di configurazione fa parte di un ciclo di dipendenze.</value>\n  </data>\n  <data name=\"ConfigurationValidationFoundNoIssues\" xml:space=\"preserve\">\n    <value>La convalida non ha rilevato problemi.</value>\n  </data>\n  <data name=\"ConfigurationUnitNeedsPrereleaseWarning\" xml:space=\"preserve\">\n    <value>L'unità di configurazione è disponibile solo come versione preliminare, ma non è contrassegnata in questo modo nella configurazione. Aggiungi 'allowPrerelease: true' alladirectives'.</value>\n    <comment>{Locked=\"allowPrerelease: true\",\"directives\"} These are values in the configuration file that are not localized.</comment>\n  </data>\n  <data name=\"ConfigurationUnitNotInCatalogWarning\" xml:space=\"preserve\">\n    <value>L'unità di configurazione è stata trovata localmente, ma non è stata trovata in alcun catalogo configurato. Verifica che sia presente in qualsiasi sistema prima di applicare la configurazione.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotPublicWarning\" xml:space=\"preserve\">\n    <value>L'unità di configurazione non è disponibile pubblicamente; assicurati che chiunque usi questa configurazione abbia accesso a tale configurazione.</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleNotProvidedWarning\" xml:space=\"preserve\">\n    <value>Il modulo non è stato specificato. La specifica del modulo migliora le prestazioni e impedisce future collisioni di nomi.</value>\n  </data>\n  <data name=\"DownloadCommandLongDescription\" xml:space=\"preserve\">\n    <value>Scarica il programma di installazione dal pacchetto selezionato, trovato eseguendo una ricerca in un'origine configurata o direttamente da un manifesto. Per impostazione predefinita, la query deve corrispondere senza distinzione tra maiuscole e minuscole all'ID, al nome o al moniker del pacchetto. È possibile usare altri campi passando l'opzione appropriata. Per impostazione predefinita, il comando download scaricherà il programma di installazione appropriato nella cartella Download dell'utente.</value>\n  </data>\n  <data name=\"DownloadCommandShortDescription\" xml:space=\"preserve\">\n    <value>Scarica il programma di installazione da un pacchetto specifico</value>\n  </data>\n  <data name=\"DownloadDirectoryArgumentDescription\" xml:space=\"preserve\">\n    <value>Directory in cui vengono scaricati i programmi di installazione</value>\n  </data>\n  <data name=\"DependenciesFlowDownload\" xml:space=\"preserve\">\n    <value>Download delle dipendenze:</value>\n  </data>\n  <data name=\"InstallerDownloaded\" xml:space=\"preserve\">\n    <value>Programma di installazione scaricato: {0}</value>\n    <comment>{Locked=\"{0}\"} Full path of the downloaded installer.</comment>\n  </data>\n  <data name=\"InstallerTypeArgumentDescription\" xml:space=\"preserve\">\n    <value>Seleziona il tipo di programma di installazione</value>\n  </data>\n  <data name=\"InstallerDownloads\" xml:space=\"preserve\">\n    <value>Download del programma di installazione</value>\n  </data>\n  <data name=\"InstallerDownloadCommandProhibited\" xml:space=\"preserve\">\n    <value>Non è consentito scaricare il programma di installazione per un'installazione offline successiva. </value>\n  </data>\n  <data name=\"ConfigurationAllUsersElevated\" xml:space=\"preserve\">\n    <value>'--module-path allusers' richiede privilegi di amministratore per l'esecuzione.</value>\n    <comment>{Locked=\"--module-path allusers\"}</comment>\n  </data>\n  <data name=\"ConfigurationModulePath\" xml:space=\"preserve\">\n    <value>Specifica il percorso nel computer locale in cui archiviare i moduli. %LOCALAPPDATA%\\Microsoft\\WinGet\\Configuration\\Modules predefinito</value>\n    <comment>{Locked=\"%LOCALAPPDATA%\\Microsoft\\WinGet\\Configuration\\Modules\"}</comment>\n  </data>\n  <data name=\"ConfigurationModulePathArgError\" xml:space=\"preserve\">\n    <value>Il valore di '--module-path' deve essere 'currentuser', 'allusers', 'default' o un percorso assoluto.</value>\n    <comment>{Locked=\"{--module-path}, {currentuser}, {allusers}, {default}}</comment>\n  </data>\n  <data name=\"PolicyEnableWinGetConfiguration\" xml:space=\"preserve\">\n    <value>Abilita la configurazione di Gestione pacchetti</value>\n  </data>\n  <data name=\"ErrorCommandLongDescription\" xml:space=\"preserve\">\n    <value>Recupera informazioni sugli errori. Dato un numero, l'output conterrà i dettagli sull'errore, incluso il nome del simbolo se si tratta di un errore specifico di WinGet. In base a una stringa, viene eseguita la ricerca di questo valore negli errori specifici di WinGet.</value>\n  </data>\n  <data name=\"ErrorCommandShortDescription\" xml:space=\"preserve\">\n    <value>Ottenere informazioni sugli errori</value>\n  </data>\n  <data name=\"ErrorInputArgumentDescription\" xml:space=\"preserve\">\n    <value>Valore da cercare nelle informazioni sull'errore</value>\n  </data>\n  <data name=\"ErrorNumberIsTooLarge\" xml:space=\"preserve\">\n    <value>Il numero specificato è troppo grande per essere un HRESULT.</value>\n  </data>\n  <data name=\"UnknownErrorCode\" xml:space=\"preserve\">\n    <value>Codice di errore sconosciuto</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INTERNAL_ERROR\" xml:space=\"preserve\">\n    <value>Errore interno</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS\" xml:space=\"preserve\">\n    <value>Argomenti della riga di comando non validi</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMMAND_FAILED\" xml:space=\"preserve\">\n    <value>L'esecuzione del comando non è riuscita</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_FAILED\" xml:space=\"preserve\">\n    <value>Apertura del manifesto non riuscita</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CTRL_SIGNAL_RECEIVED\" xml:space=\"preserve\">\n    <value>Segnale di annullamento ricevuto</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SHELLEXEC_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>L'esecuzione di ShellExecute non è riuscita</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_MANIFESTVERSION\" xml:space=\"preserve\">\n    <value>Impossibile elaborare il manifesto. La versione del manifesto è superiore a quella supportata. Aggiornare il client.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_FAILED\" xml:space=\"preserve\">\n    <value>Download del programma di installazione non riuscito</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX\" xml:space=\"preserve\">\n    <value>Impossibile scrivere nell'indice; è una versione dello schema superiore</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INDEX_INTEGRITY_COMPROMISED\" xml:space=\"preserve\">\n    <value>L'indice è danneggiato</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCES_INVALID\" xml:space=\"preserve\">\n    <value>Le informazioni di origine configurate sono danneggiate</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NAME_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>Il nome dell'origine è già configurato</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_SOURCE_TYPE\" xml:space=\"preserve\">\n    <value>Il tipo di origine non è valido</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_BUNDLE\" xml:space=\"preserve\">\n    <value>Il file MSIX è un bundle, non un pacchetto</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_DATA_MISSING\" xml:space=\"preserve\">\n    <value>Mancano i dati richiesti dall'origine</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER\" xml:space=\"preserve\">\n    <value>Nessuno dei programmi di installazione è applicabile al sistema corrente</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_HASH_MISMATCH\" xml:space=\"preserve\">\n    <value>L'hash del file del programma di installazione non corrisponde al manifesto</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NAME_DOES_NOT_EXIST\" xml:space=\"preserve\">\n    <value>Il nome di origine non esiste</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_ARG_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>Il percorso di origine è già configurato con un altro nome</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICATIONS_FOUND\" xml:space=\"preserve\">\n    <value>Nessun pacchetto trovato</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_SOURCES_DEFINED\" xml:space=\"preserve\">\n    <value>Nessuna origine configurata</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_APPLICATIONS_FOUND\" xml:space=\"preserve\">\n    <value>Sono stati trovati più pacchetti corrispondenti ai criteri</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_MANIFEST_FOUND\" xml:space=\"preserve\">\n    <value>Nessun manifesto trovato corrispondente ai criteri</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXTENSION_PUBLIC_FAILED\" xml:space=\"preserve\">\n    <value>Non è stato possibile ottenere la cartella pubblica dal pacchetto di origine</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMMAND_REQUIRES_ADMIN\" xml:space=\"preserve\">\n    <value>Il comando richiede i privilegi di amministratore per essere eseguito</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NOT_SECURE\" xml:space=\"preserve\">\n    <value>Il percorso di origine non è sicuro</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>Il client Microsoft Store è bloccato dai criteri</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_APP_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>L'applicazione Microsoft Store è bloccata dai criteri</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXPERIMENTAL_FEATURE_DISABLED\" xml:space=\"preserve\">\n    <value>La funzionalità è attualmente in fase di sviluppo. Può essere abilitato con le impostazioni di WinGet.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Non è stato possibile installare l'app Microsoft Store</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMPLETE_INPUT_BAD\" xml:space=\"preserve\">\n    <value>Non è stato possibile eseguire il completamento automatico</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED\" xml:space=\"preserve\">\n    <value>Non è stato possibile inizializzare il parser YAML</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_MAPPING_KEY\" xml:space=\"preserve\">\n    <value>È stata rilevata una chiave YAML non valida</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY\" xml:space=\"preserve\">\n    <value>È stata rilevata una chiave YAML duplicata</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_OPERATION\" xml:space=\"preserve\">\n    <value>Operazione YAML non valida</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_DOC_BUILD_FAILED\" xml:space=\"preserve\">\n    <value>Non è stato possibile compilare il documento YAML</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_EMITTER_STATE\" xml:space=\"preserve\">\n    <value>Stato dell'emettitore YAML non valido</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_DATA\" xml:space=\"preserve\">\n    <value>Dati YAML non validi</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LIBYAML_ERROR\" xml:space=\"preserve\">\n    <value>Errore LibYAML</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_WARNING\" xml:space=\"preserve\">\n    <value>Convalida del manifesto riuscita con avviso</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_FAILURE\" xml:space=\"preserve\">\n    <value>Convalida del manifesto non riuscita</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_MANIFEST\" xml:space=\"preserve\">\n    <value>Il manifesto non è valido</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>Non è stato trovato alcun aggiornamento applicabile</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPDATE_ALL_HAS_FAILURE\" xml:space=\"preserve\">\n    <value>aggiornamento di winget -- tutto completato con errori</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_SECURITY_CHECK_FAILED\" xml:space=\"preserve\">\n    <value>Non è stato possibile eseguire il controllo di sicurezza per il programma di installazione</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_SIZE_MISMATCH\" xml:space=\"preserve\">\n    <value>La dimensione del download non corrisponde alla lunghezza prevista del contenuto</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_UNINSTALL_INFO_FOUND\" xml:space=\"preserve\">\n    <value>Comando di disinstallazione non trovato</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXEC_UNINSTALL_COMMAND_FAILED\" xml:space=\"preserve\">\n    <value>L'esecuzione del comando di disinstallazione non è riuscita</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_BREAK_ITERATOR_ERROR\" xml:space=\"preserve\">\n    <value>Errore iteratore di interruzione dell'ICU</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_CASEMAP_ERROR\" xml:space=\"preserve\">\n    <value>Errore casemap ICU</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_REGEX_ERROR\" xml:space=\"preserve\">\n    <value>Errore regex ICU</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_IMPORT_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Non è stato possibile installare uno o più pacchetti importati</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NOT_ALL_PACKAGES_FOUND\" xml:space=\"preserve\">\n    <value>Non è stato possibile trovare uno o più pacchetti richiesti</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE\" xml:space=\"preserve\">\n    <value>Il file Json non è valido</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NOT_REMOTE\" xml:space=\"preserve\">\n    <value>Il percorso di origine non è remoto</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE\" xml:space=\"preserve\">\n    <value>L'origine rest configurata non è supportata</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA\" xml:space=\"preserve\">\n    <value>Dati non validi restituiti dall'origine rest</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>L'operazione è bloccata da Criteri di gruppo</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_INTERNAL_ERROR\" xml:space=\"preserve\">\n    <value>Errore interno dell'API Rest</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_URL\" xml:space=\"preserve\">\n    <value>L'URL dell'origine rest non è valido</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_UNSUPPORTED_MIME_TYPE\" xml:space=\"preserve\">\n    <value>Tipo MIME non supportato restituito dall'API REST</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_VERSION\" xml:space=\"preserve\">\n    <value>Versione del contratto di origine rest non valida</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE\" xml:space=\"preserve\">\n    <value>I dati di origine sono danneggiati o manomessi</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_STREAM_READ_FAILURE\" xml:space=\"preserve\">\n    <value>Errore nella lettura del flusso</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>I contratti del pacchetto non sono stati concordati</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PROMPT_INPUT_ERROR\" xml:space=\"preserve\">\n    <value>Errore durante la lettura dell'input nel prompt</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST\" xml:space=\"preserve\">\n    <value>La richiesta di ricerca non è supportata da una o più origini</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_ENDPOINT_NOT_FOUND\" xml:space=\"preserve\">\n    <value>L'endpoint dell'API REST non è stato trovato.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_OPEN_FAILED\" xml:space=\"preserve\">\n    <value>Impossibile aprire l'origine.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>Contratti di origine non accettati</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CUSTOMHEADER_EXCEEDS_MAXLENGTH\" xml:space=\"preserve\">\n    <value>Le dimensioni dell'intestazione superano il limite consentito di 1024 caratteri. Ridurre le dimensioni e riprovare.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MISSING_RESOURCE_FILE\" xml:space=\"preserve\">\n    <value>File di risorse mancante</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSI_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>L'esecuzione dell'installazione MSI non è riuscita</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT\" xml:space=\"preserve\">\n    <value>Gli argomenti per msiexec non sono validi</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FAILED_TO_OPEN_ALL_SOURCES\" xml:space=\"preserve\">\n    <value>Non è stato possibile aprire una o più origini</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>Non è stato possibile convalidare le dipendenze</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MISSING_PACKAGE\" xml:space=\"preserve\">\n    <value>Uno o più pacchetti mancanti</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_TABLE_COLUMN\" xml:space=\"preserve\">\n    <value>Colonna tabella non valida</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_NOT_NEWER\" xml:space=\"preserve\">\n    <value>La versione di aggiornamento non è più recente della versione installata</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_UNKNOWN\" xml:space=\"preserve\">\n    <value>La versione dell'aggiornamento è sconosciuta e l'override non è specificato</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_CONVERSION_ERROR\" xml:space=\"preserve\">\n    <value>Errore di conversione ICU</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Non è stato possibile installare il pacchetto portabile</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_REPARSE_POINT_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Il volume non supporta i punti di reparse</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_PACKAGE_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>Esiste già un pacchetto portabile di un'origine diversa.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_SYMLINK_PATH_IS_DIRECTORY\" xml:space=\"preserve\">\n    <value>Impossibile creare il collegamento simbolico. Il percorso punta a una directory.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_PROHIBITS_ELEVATION\" xml:space=\"preserve\">\n    <value>Impossibile eseguire il programma di installazione da un contesto di amministratore.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Non è stato possibile disinstallare il pacchetto portabile</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ARP_VERSION_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>Non è stato possibile convalidare i valori DisplayVersion rispetto all'indice.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_ARGUMENT\" xml:space=\"preserve\">\n    <value>Uno o più argomenti non sono supportati.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_BIND_WITH_EMBEDDED_NULL\" xml:space=\"preserve\">\n    <value>I caratteri null incorporati non sono consentiti in SQLite</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Impossibile trovare il programma di installazione annidato nell'archivio.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXTRACT_ARCHIVE_FAILED\" xml:space=\"preserve\">\n    <value>Impossibile estrarre l'archivio.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_INVALID_PATH\" xml:space=\"preserve\">\n    <value>È stato specificato un percorso di file relativo non valido per il programma di installazione annidato.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PINNED_CERTIFICATE_MISMATCH\" xml:space=\"preserve\">\n    <value>Il certificato del server non corrisponde ad alcun valore previsto.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_LOCATION_REQUIRED\" xml:space=\"preserve\">\n    <value>È necessario specificare il percorso di installazione.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ARCHIVE_SCAN_FAILED\" xml:space=\"preserve\">\n    <value>L'analisi del malware dell'archivio non è riuscita.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>È stata trovata almeno una versione del pacchetto installato.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PIN_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>Esiste già un pin per il pacchetto.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PIN_DOES_NOT_EXIST\" xml:space=\"preserve\">\n    <value>Nessun pin per il pacchetto.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_OPEN_PINNING_INDEX\" xml:space=\"preserve\">\n    <value>Impossibile aprire il database dei pin.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Installazione di una o più applicazioni non riuscita</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Non è stato possibile disinstallare una o più applicazioni</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NOT_ALL_QUERIES_FOUND_SINGLE\" xml:space=\"preserve\">\n    <value>Una o più query non hanno restituito esattamente una corrispondenza</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_PINNED\" xml:space=\"preserve\">\n    <value>Il pacchetto contiene un PIN che impedisce l'aggiornamento.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB\" xml:space=\"preserve\">\n    <value>Il pacchetto attualmente installato è il pacchetto stub</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_APPTERMINATION_RECEIVED\" xml:space=\"preserve\">\n    <value>Segnale di arresto dell'applicazione ricevuto</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_DEPENDENCIES\" xml:space=\"preserve\">\n    <value>Non è stato possibile scaricare le dipendenze del pacchetto.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_COMMAND_PROHIBITED\" xml:space=\"preserve\">\n    <value>Non è stato possibile scaricare il pacchetto. Il download per l'installazione offline non è consentito.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SERVICE_UNAVAILABLE\" xml:space=\"preserve\">\n    <value>Un servizio richiesto è occupato o non disponibile. Riprova più tardi.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESUME_ID_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Il GUID specificato non corrisponde a uno stato di ripresa valido.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CLIENT_VERSION_MISMATCH\" xml:space=\"preserve\">\n    <value>La versione corrente del client non corrisponde alla versione client dello stato salvato.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_RESUME_STATE\" xml:space=\"preserve\">\n    <value>I dati sullo stato di ripresa non sono validi.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_OPEN_CHECKPOINT_INDEX\" xml:space=\"preserve\">\n    <value>Impossibile aprire il database del checkpoint.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESUME_LIMIT_EXCEEDED\" xml:space=\"preserve\">\n    <value>È stato superato il limite massimo di ripresa.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_AUTHENTICATION_INFO\" xml:space=\"preserve\">\n    <value>Informazioni di autenticazione non valide.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Metodo di autenticazione non supportato.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED\" xml:space=\"preserve\">\n    <value>Autenticazione non riuscita.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_INTERACTIVE_REQUIRED\" xml:space=\"preserve\">\n    <value>Impossibile eseguire l'autenticazione. È richiesta l'autenticazione interattiva.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_CANCELLED_BY_USER\" xml:space=\"preserve\">\n    <value>Impossibile eseguire l'autenticazione. Annullato dall'utente.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_INCORRECT_ACCOUNT\" xml:space=\"preserve\">\n    <value>Autenticazione non riuscita. L'account autenticato non è l'account desiderato.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE\" xml:space=\"preserve\">\n    <value>L'applicazione è attualmente in esecuzione. Uscire dall'applicazione, quindi riprovare.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INSTALL_IN_PROGRESS\" xml:space=\"preserve\">\n    <value>È già in corso un'altra installazione. Riprova più tardi.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_FILE_IN_USE\" xml:space=\"preserve\">\n    <value>È in uso uno o più file. Uscire dall'applicazione, quindi riprovare.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_MISSING_DEPENDENCY\" xml:space=\"preserve\">\n    <value>Nel sistema manca una dipendenza per questo pacchetto.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DISK_FULL\" xml:space=\"preserve\">\n    <value>Non c'è più spazio nel PC. Liberare spazio, quindi riprovare.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INSUFFICIENT_MEMORY\" xml:space=\"preserve\">\n    <value>Memoria insufficiente per l'installazione. Chiudi le altre applicazioni, quindi riprova.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_NO_NETWORK\" xml:space=\"preserve\">\n    <value>Questa applicazione richiede la connettività Internet. Connettiti a una rete e riprova.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CONTACT_SUPPORT\" xml:space=\"preserve\">\n    <value>Errore dell'applicazione durante l'installazione. Contattare il supporto tecnico.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_TO_FINISH\" xml:space=\"preserve\">\n    <value>Riavvia il PC per completare l'installazione..</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_FOR_INSTALL\" xml:space=\"preserve\">\n    <value>Installazione non riuscita. Riavvia il PC e riprova.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_INITIATED\" xml:space=\"preserve\">\n    <value>Il PC verrà riavviato per completare l'installazione.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CANCELLED_BY_USER\" xml:space=\"preserve\">\n    <value>Hai annullato l’installazione.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>È già installata un'altra versione di questa applicazione.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DOWNGRADE\" xml:space=\"preserve\">\n    <value>È già installata una versione successiva di questa applicazione.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>I criteri dell'organizzazione impediscono l'installazione. Contattare l'amministratore.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DEPENDENCIES\" xml:space=\"preserve\">\n    <value>Non è stato possibile installare le dipendenze del pacchetto.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE_BY_APPLICATION\" xml:space=\"preserve\">\n    <value>L'applicazione è attualmente utilizzata da un'altra applicazione.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INVALID_PARAMETER\" xml:space=\"preserve\">\n    <value>Parametro non valido.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Pacchetto non supportato dal sistema.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_UPGRADE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Il programma di installazione non supporta l'aggiornamento di un pacchetto esistente.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CUSTOM_ERROR\" xml:space=\"preserve\">\n    <value>Installazione non riuscita a causa di un errore del programma di installazione personalizzato.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_ARP_ENTRY_NOT_FOUND\" xml:space=\"preserve\">\n    <value>La voce App e funzionalità per il pacchetto non è stata trovata.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>Il percorso di installazione non è applicabile.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Il percorso di installazione non è stato trovato.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_HASH_MISMATCH\" xml:space=\"preserve\">\n    <value>L'hash del file esistente non corrisponde.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_NOT_FOUND\" xml:space=\"preserve\">\n    <value>File non trovato.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK\" xml:space=\"preserve\">\n    <value>Il file è stato trovato ma l'hash non è stato controllato.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_ACCESS_ERROR\" xml:space=\"preserve\">\n    <value>Impossibile accedere al file.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE\" xml:space=\"preserve\">\n    <value>Il file di configurazione non è valido.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_YAML\" xml:space=\"preserve\">\n    <value>Sintassi YAML non valida.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_FIELD_TYPE\" xml:space=\"preserve\">\n    <value>Un campo di configurazione ha un tipo non valido.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION\" xml:space=\"preserve\">\n    <value>La versione della configurazione è sconosciuta.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_SET_APPLY_FAILED\" xml:space=\"preserve\">\n    <value>Errore durante l'applicazione della configurazione.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER\" xml:space=\"preserve\">\n    <value>La configurazione contiene un identificatore duplicato.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MISSING_DEPENDENCY\" xml:space=\"preserve\">\n    <value>Nella configurazione manca una dipendenza.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED\" xml:space=\"preserve\">\n    <value>La configurazione ha una dipendenza non soddisfatta.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_ASSERTION_FAILED\" xml:space=\"preserve\">\n    <value>Un'asserzione per l'unità di configurazione non è riuscita.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MANUALLY_SKIPPED\" xml:space=\"preserve\">\n    <value>La configurazione è stata ignorata manualmente.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_WARNING_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>L'utente ha rifiutato di continuare l'esecuzione.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_SET_DEPENDENCY_CYCLE\" xml:space=\"preserve\">\n    <value>Il grafico delle dipendenze contiene un ciclo che non può essere risolto.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_FIELD_VALUE\" xml:space=\"preserve\">\n    <value>La configurazione contiene un valore di campo non valido.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MISSING_FIELD\" xml:space=\"preserve\">\n    <value>Nella configurazione manca un campo.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_TEST_FAILED\" xml:space=\"preserve\">\n    <value>Errore di alcune unità di configurazione durante il test dello stato.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_TEST_NOT_RUN\" xml:space=\"preserve\">\n    <value>Lo stato della configurazione non è stato testato.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_NOT_INSTALLED\" xml:space=\"preserve\">\n    <value>L'unità di configurazione non è stata installata.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_NOT_FOUND_REPOSITORY\" xml:space=\"preserve\">\n    <value>Impossibile trovare l'unità di configurazione.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_MULTIPLE_MATCHES\" xml:space=\"preserve\">\n    <value>Sono state trovate più corrispondenze per l'unità di configurazione; specificare il modulo per selezionare quello corretto.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_GET\" xml:space=\"preserve\">\n    <value>Errore dell'unità di configurazione durante il tentativo di ottenere lo stato corrente del sistema.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_TEST\" xml:space=\"preserve\">\n    <value>Errore dell'unità di configurazione durante il tentativo di testare lo stato corrente del sistema.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_SET\" xml:space=\"preserve\">\n    <value>Errore dell'unità di configurazione durante il tentativo di applicare lo stato desiderato.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_MODULE_CONFLICT\" xml:space=\"preserve\">\n    <value>Il modulo per l'unità di configurazione è disponibile in più località con la stessa versione.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE\" xml:space=\"preserve\">\n    <value>Caricamento del modulo per l'unità di configurazione non riuscito.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_INVALID_RESULT\" xml:space=\"preserve\">\n    <value>L'unità di configurazione ha restituito un risultato imprevisto durante l'esecuzione.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_SETTING_CONFIG_ROOT\" xml:space=\"preserve\">\n    <value>Un'unità contiene un'impostazione che richiede la radice di configurazione.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR\" xml:space=\"preserve\">\n    <value>Operazione non supportata dal processore di configurazione.</value>\n  </data>\n  <data name=\"Unavailable\" xml:space=\"preserve\">\n    <value>Non disponibile</value>\n  </data>\n  <data name=\"EnableWindowsFeaturesSuccess\" xml:space=\"preserve\">\n    <value>Le dipendenze delle funzioni di Windows sono state abilitate</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE_ADMIN\" xml:space=\"preserve\">\n    <value>Il caricamento del modulo per l'unità di configurazione non è riuscito perché richiede privilegi di amministratore per l'esecuzione.</value>\n  </data>\n  <data name=\"ConfigurationUnitSettingConfigRoot\" xml:space=\"preserve\">\n    <value>Un'unità contiene un'impostazione che richiede la radice di configurazione.</value>\n  </data>\n  <data name=\"ConfigurationUnitImportModuleAdmin\" xml:space=\"preserve\">\n    <value>Il caricamento del modulo per l'unità di configurazione non è riuscito perché richiede privilegi di amministratore per l'esecuzione.</value>\n  </data>\n  <data name=\"ResumeCommandLongDescription\" xml:space=\"preserve\">\n    <value>Riprende l'esecuzione di un comando salvato in precedenza passando l'identificatore univoco del comando salvato. Consente di riprendere un comando eseguito che potrebbe essere stato terminato a causa di un riavvio.</value>\n  </data>\n  <data name=\"ResumeCommandShortDescription\" xml:space=\"preserve\">\n    <value>Riprende l'esecuzione di un comando salvato in precedenza.</value>\n  </data>\n  <data name=\"ResumeIdArgumentDescription\" xml:space=\"preserve\">\n    <value>Identificatore univoco dello stato salvato da riprendere</value>\n  </data>\n  <data name=\"ClientVersionMismatchError\" xml:space=\"preserve\">\n    <value>La ripresa dello stato da una versione client diversa non è supportata: {0}</value>\n    <comment>{Locked= \"{0}\"} Message displayed to inform the user that the client version of the resume state does not match the current client version. {0} is a placeholder for the client version that created the resume state.</comment>\n  </data>\n  <data name=\"ResumeIdNotFoundError\" xml:space=\"preserve\">\n    <value>Lo stato di ripresa non esiste: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a guid that does not correspond to a valid saved state. {0} is a placeholder replaced by the provided guid string.</comment>\n  </data>\n  <data name=\"ResumeStateDataNotFoundError\" xml:space=\"preserve\">\n    <value>Non sono stati trovati dati nello stato di ripresa.</value>\n  </data>\n  <data name=\"CommandDoesNotSupportResumeMessage\" xml:space=\"preserve\">\n    <value>Questo comando non supporta la ripresa.</value>\n  </data>\n  <data name=\"AllowRebootArgumentDescription\" xml:space=\"preserve\">\n    <value>Consente un riavvio, se applicabile</value>\n  </data>\n  <data name=\"InitiatingReboot\" xml:space=\"preserve\">\n    <value>Avvio del riavvio per completare l'operazione...</value>\n  </data>\n  <data name=\"FailedToInitiateReboot\" xml:space=\"preserve\">\n    <value>Non è stato possibile avviare un riavvio.</value>\n  </data>\n  <data name=\"ResumeLimitExceeded\" xml:space=\"preserve\">\n    <value>L'operazione di ripresa supera il limite consentito di {0} curriculum. Per riprendere manualmente, eseguire il comando '{1}'.</value>\n    <comment>{Locked=\"{0}\", \"{1}\"} {0} is a placeholder that is replaced by an integer number of the number of allowed resumes. {1} is a placeholder for the command to run to perform a manual resume.</comment>\n  </data>\n  <data name=\"IgnoreResumeLimitArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignora il limite per la ripresa di uno stato salvato</value>\n  </data>\n  <data name=\"UriSchemeNotSupported\" xml:space=\"preserve\">\n    <value>Schema Uri non supportato: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the provided uri is not supported. {0} is a placeholder replaced by the provided uri.</comment>\n  </data>\n  <data name=\"UriNotWellFormed\" xml:space=\"preserve\">\n    <value>Uri non ben formato: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the provided uri is not well formed. {0} is a placeholder replaced by the provided uri.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitEmptyContent\" xml:space=\"preserve\">\n    <value>Non è stato possibile analizzare {0} contenuto delle impostazioni dell'unità di configurazione o il contenuto delle impostazioni è vuoto.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder replaced by the input winget configure resource unit type.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitMissingRequiredArg\" xml:space=\"preserve\">\n    <value>argomento obbligatorio mancante nell'unità di configurazione {0}: {1}</value>\n    <comment>{Locked=\"{0},{1}\"} {0} is a placeholder for the input winget configure resource unit type. {1} is placeholder for the missing arg.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitMissingRecommendedArg\" xml:space=\"preserve\">\n    <value>{0}'unità di configurazione non contiene l'argomento consigliato: {1}</value>\n    <comment>{Locked=\"{0},{1}\"} {0} is a placeholder for the input winget configure resource unit type. {1} is placeholder for the missing arg.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitKnownSourceConfliction\" xml:space=\"preserve\">\n    <value>L'unità di configurazione WinGetSource è in conflitto con un'origine nota: {0}</value>\n    <comment>{Locked=\"WinGetSource,{0}\"} {0} is a placeholder for the input winget source in the configuration unit settings.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitThirdPartySourceAssertion\" xml:space=\"preserve\">\n    <value>L'unità di configurazione WinGetSource asserisce su un'origine di terze parti: {0}</value>\n    <comment>{Locked=\"WinGetSource,{0}\"} {0} is a placeholder for the input winget source in the configuration unit settings.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitBothPackageVersionAndUseLatest\" xml:space=\"preserve\">\n    <value>WinGetPackage dichiara sia UseLatest che Version. ID pacchetto: {0}</value>\n    <comment>{Locked=\"WinGetPackage,UseLatest,Version,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitThirdPartySourceAssertionForPackage\" xml:space=\"preserve\">\n    <value>L'unità di configurazione WinGetPackage asserisce un pacchetto da un'origine di terze parti. ID pacchetto: {0}; Origine: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitDependencySourceNotConfigured\" xml:space=\"preserve\">\n    <value>Il pacchetto dell'unità di configurazione WinGetPackage dipende da un'origine di terze parti non configurata in precedenza. ID pacchetto: {0}; Origine: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitDependencySourceNotDeclaredAsDependency\" xml:space=\"preserve\">\n    <value>Il pacchetto dell'unità di configurazione WinGetPackage dipende da un'origine di terze parti. È consigliabile dichiarare la dipendenza nella sezione dependsOn uni. ID pacchetto: {0}; Origine: {1}</value>\n    <comment>{Locked=\"WinGetPackage,dependsOn,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageSourceOpenFailed\" xml:space=\"preserve\">\n    <value>Impossibile convalidare il pacchetto di unità di configurazione WinGetPackage. Apertura dell'origine non riuscita. ID pacchetto: {0}; Origine: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageNotFound\" xml:space=\"preserve\">\n    <value>Impossibile convalidare il pacchetto di unità di configurazione WinGetPackage. Pacchetto non trovato. ID pacchetto: {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageMultipleFound\" xml:space=\"preserve\">\n    <value>Impossibile convalidare il pacchetto di unità di configurazione WinGetPackage. Sono stati trovati più pacchetti. ID pacchetto: {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageVersionNotFound\" xml:space=\"preserve\">\n    <value>Impossibile convalidare il pacchetto di unità di configurazione WinGetPackage. La versione del pacchetto non è stata trovata. ID pacchetto: {0}; Versione {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitPackageVersionSpecifiedWithOnlyOnePackageVersion\" xml:space=\"preserve\">\n    <value>Pacchetto di unità di configurazione WinGetPackage specificato con una versione specifica, ma è disponibile una sola versione del pacchetto. ID pacchetto:{0}; Versione: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackage\" xml:space=\"preserve\">\n    <value>Impossibile convalidare il pacchetto di unità di configurazione WinGetPackage. ID pacchetto: {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"AuthenticationModeArgumentDescription\" xml:space=\"preserve\">\n    <value>Specifica la preferenza per la finestra di autenticazione (silent, silentPreferred o interactive)</value>\n    <comment>{Locked=\"silent\",\"silentPreferred\",\"interactive\"} This argument allows the user to select authentication window popup behavior.</comment>\n  </data>\n  <data name=\"AuthenticationAccountArgumentDescription\" xml:space=\"preserve\">\n    <value>Specificare l'account da usare per l'autenticazione</value>\n  </data>\n  <data name=\"SourceAddFailedAuthenticationNotSupported\" xml:space=\"preserve\">\n    <value>Non è stato possibile aggiungere l'origine. Questa versione winget non supporta il metodo di autenticazione dell'origine. Provare a eseguire l'aggiornamento alla versione più recente winget.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"SourceRequiresAuthentication\" xml:space=\"preserve\">\n    <value>L'origine {0} richiede l'autenticazione. La richiesta di autenticazione può essere visualizzata quando necessario. Le informazioni autenticate verranno condivise con l'origine per l'autorizzazione di accesso.</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"RepairCommandLongDescription\" xml:space=\"preserve\">\n    <value>Ripristina il pacchetto selezionato, trovato eseguendo una ricerca nell'elenco dei pacchetti installati o direttamente da un manifesto. Per impostazione predefinita, la query deve corrispondere senza distinzione tra maiuscole e minuscole all'ID, al nome o al moniker del pacchetto. È possibile usare altri campi passando l'opzione appropriata.</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"RepairCommandShortDescription\" xml:space=\"preserve\">\n    <value>Ripristina il pacchetto selezionato</value>\n  </data>\n  <data name=\"NoRepairInfoFound\" xml:space=\"preserve\">\n    <value>Impossibile trovare il comando di ripristino per questo pacchetto. Contattare l'editore del pacchetto per ottenere supporto.</value>\n  </data>\n  <data name=\"RepairDifferentInstallTechnology\" xml:space=\"preserve\">\n    <value>La tecnologia del programma di installazione in uso non corrisponde alla versione attualmente installata.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_REPAIR_INFO_FOUND\" xml:space=\"preserve\">\n    <value>Comando di ripristino non trovato.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_REPAIR_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>La tecnologia del programma di installazione in uso non supporta il ripristino.</value>\n  </data>\n  <data name=\"RepairFlowRepairSuccess\" xml:space=\"preserve\">\n    <value>L'operazione di ripristino è stata completata.</value>\n  </data>\n  <data name=\"RepairAbandoned\" xml:space=\"preserve\">\n    <value>Riparazione abbandonata</value>\n  </data>\n  <data name=\"RepairFlowStartingPackageRepair\" xml:space=\"preserve\">\n    <value>Avvio del ripristino del pacchetto in corso...</value>\n  </data>\n  <data name=\"MSStoreRepairFailed\" xml:space=\"preserve\">\n    <value>Non è stato possibile riparare il pacchetto Microsoft Store. Codice di errore: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Microsoft Store application package fails to repair. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXEC_REPAIR_FAILED\" xml:space=\"preserve\">\n    <value>L'operazione di ripristino non è riuscita.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_REPAIR_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>L'operazione di ripristino non è applicabile.</value>\n  </data>\n  <data name=\"RepairFlowNoMatchingVersion\" xml:space=\"preserve\">\n    <value>Non sono disponibili versioni del pacchetto corrispondenti dalle origini configurate.</value>\n  </data>\n  <data name=\"RepairFlowReturnCodeSystemNotSupported\" xml:space=\"preserve\">\n    <value>La configurazione di sistema corrente non supporta il ripristino di questo pacchetto.</value>\n  </data>\n  <data name=\"RepairOperationNotSupported\" xml:space=\"preserve\">\n    <value>La tecnologia del programma di installazione in uso non supporta il ripristino.</value>\n  </data>\n  <data name=\"NoAdminRepairForUserScopePackage\" xml:space=\"preserve\">\n    <value>Impossibile ripristinare il pacchetto installato per l'ambito utente durante l'esecuzione con privilegi di amministratore.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED\" xml:space=\"preserve\">\n    <value>Le operazioni di ripristino che richiedono privilegi di amministratore non sono consentite nei pacchetti installati nell'ambito utente.</value>\n  </data>\n  <data name=\"RepairFailedWithCode\" xml:space=\"preserve\">\n    <value>Ripristino non riuscito con codice di uscita: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to repair an application package fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SQLITE_CONNECTION_TERMINATED\" xml:space=\"preserve\">\n    <value>La connessione SQLite è stata terminata per evitare il danneggiamento.</value>\n  </data>\n  <data name=\"UninstallAllVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Disinstalla tutte le versioni</value>\n  </data>\n  <data name=\"TargetVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>Versione su cui intervenire</value>\n  </data>\n  <data name=\"UninstallFailedDueToMultipleVersions\" xml:space=\"preserve\">\n    <value>Sono installate più versioni di questo pacchetto. Affinare la ricerca, passare l'argomento '--version' per selezionarne uno oppure passare il flag '--all-versions' per disinstallarli tutti.</value>\n    <comment>{Locked=\"--version,--all-versions\"}</comment>\n  </data>\n  <data name=\"PolicyEnableProxyCommandLineOptions\" xml:space=\"preserve\">\n    <value>Abilita le opzioni della riga di comando del proxy Gestione pacchetti Windows</value>\n    <comment>Describes a Group Policy that can enable the use of the --proxy option to set a proxy</comment>\n  </data>\n  <data name=\"ProxyArgumentDescription\" xml:space=\"preserve\">\n    <value>Imposta un proxy da usare per questa esecuzione</value>\n  </data>\n  <data name=\"NoProxyArgumentDescription\" xml:space=\"preserve\">\n    <value>Disabilita l'uso del proxy per questa esecuzione</value>\n  </data>\n  <data name=\"ResetAdminSettingFailed\" xml:space=\"preserve\">\n    <value>Impossibile reimpostare {0}. Questa impostazione è controllata dai criteri. Per ulteriori informazioni, contattare l'amministratore di sistema.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"ResetAdminSettingSucceeded\" xml:space=\"preserve\">\n    <value>Reimposta l'impostazione di amministrazione '{0}’.</value>\n    <comment>{Locked=\"{0}\"} Message displayed after the user resets an admin setting to its default value. Reset is used as verb in past tense. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"SetAdminSettingFailed\" xml:space=\"preserve\">\n    <value>Impossibile impostare {0}. Questa impostazione è controllata dai criteri. Per ulteriori informazioni, contattare l'amministratore di sistema.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"SetAdminSettingSucceeded\" xml:space=\"preserve\">\n    <value>Esegui l'impostazione di amministrazione '{0}' su '{1}'.</value>\n    <comment>{Locked=\"{0}\"} Message displayed after the user sets the value of an admin setting. Set is used as a verb in past tense. {0} is a placeholder replaced by the setting name. {1} is a placeholder replaced </comment>\n  </data>\n  <data name=\"SettingNameArgumentDescription\" xml:space=\"preserve\">\n    <value>Nome dell'impostazione da modificare</value>\n  </data>\n  <data name=\"SettingValueArgumentDescription\" xml:space=\"preserve\">\n    <value>Valore da impostare per l'impostazione.</value>\n  </data>\n  <data name=\"SettingsResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>Ripristina il valore predefinito di un'impostazione di amministrazione.</value>\n  </data>\n  <data name=\"SettingsResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>Ripristina il valore predefinito di un'impostazione di amministrazione.</value>\n  </data>\n  <data name=\"SettingsSetCommandLongDescription\" xml:space=\"preserve\">\n    <value>Imposta il valore di un'impostazione di amministrazione.</value>\n  </data>\n  <data name=\"SettingsSetCommandShortDescription\" xml:space=\"preserve\">\n    <value>Imposta il valore di un'impostazione di amministrazione.</value>\n  </data>\n  <data name=\"SourceExplicitArgumentDescription\" xml:space=\"preserve\">\n    <value>Esclude un'origine dall'individuazione se non specificata</value>\n  </data>\n  <data name=\"SourceEditExplicitArgumentDescription\" xml:space=\"preserve\">\n    <value>Esclude un'origine dall'individuazione (vero o falso)</value>\n  </data>\n  <data name=\"SourceListExplicit\" xml:space=\"preserve\">\n    <value>Contenuti espliciti</value>\n  </data>\n  <data name=\"SourceTrustLevelArgumentDescription\" xml:space=\"preserve\">\n    <value>Livello di attendibilità dell'origine (nessuno o attendibile)</value>\n  </data>\n  <data name=\"SourceListTrustLevel\" xml:space=\"preserve\">\n    <value>Livello di trust</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DISPLAYCATALOG_API_FAILED\" xml:space=\"preserve\">\n    <value>Non è possibile ottenere il catalogo pacchetti Microsoft Store.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_DISPLAYCATALOG_PACKAGE\" xml:space=\"preserve\">\n    <value>Non sono stati trovati pacchetti Microsoft Store applicabili dal catalogo pacchetti Microsoft Store.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SFSCLIENT_API_FAILED\" xml:space=\"preserve\">\n    <value>Non è possibile ottenere informazioni sul download del pacchetto Microsoft Store.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_SFSCLIENT_PACKAGE\" xml:space=\"preserve\">\n    <value>Non sono stati trovati pacchetti Microsoft Store applicabili per il download.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED\" xml:space=\"preserve\">\n    <value>Non è stato possibile recuperare la licenza del pacchetto Microsoft Store.</value>\n  </data>\n  <data name=\"MSStoreDownloadNoApplicablePackageFound\" xml:space=\"preserve\">\n    <value>Non sono stati trovati pacchetti Microsoft Store applicabili.</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageHashVerified\" xml:space=\"preserve\">\n    <value>La verifica dell'hash del pacchetto Microsoft Store è stata completata</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageHashMismatch\" xml:space=\"preserve\">\n    <value>Mancata corrispondenza dell'hash del pacchetto Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloaded\" xml:space=\"preserve\">\n    <value>Pacchetto Microsoft Store scaricato: {0}</value>\n    <comment>{Locked=\"{0}\"} Full path of the downloaded package.</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadFailed\" xml:space=\"preserve\">\n    <value>Download del pacchetto Microsoft Store non riuscito: {0}</value>\n    <comment>{Locked=\"{0}\"} Package name.</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadSuccess\" xml:space=\"preserve\">\n    <value>Download del pacchetto Microsoft Store completato</value>\n  </data>\n  <data name=\"MSStoreDownloadMainPackages\" xml:space=\"preserve\">\n    <value>Download dei pacchetti principali da Microsoft Store...</value>\n  </data>\n  <data name=\"MSStoreDownloadDependencyPackages\" xml:space=\"preserve\">\n    <value>Download dei pacchetti di dipendenze da Microsoft Store...</value>\n  </data>\n  <data name=\"MSStoreDownloadGetDownloadInfo\" xml:space=\"preserve\">\n    <value>Recupero delle informazioni di download del pacchetto Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadGetDownloadInfoFailed\" xml:space=\"preserve\">\n    <value>Non è possibile recuperare le informazioni sul download del pacchetto Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadGetLicense\" xml:space=\"preserve\">\n    <value>Recupero della licenza del pacchetto Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseSuccess\" xml:space=\"preserve\">\n    <value>Licenza del pacchetto Microsoft Store salvata: {0}</value>\n    <comment>{Locked=\"{0}\"} License file full path.</comment>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseFailed\" xml:space=\"preserve\">\n    <value>Non è possibile recuperare la licenza del pacchetto Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadRenameNotSupported\" xml:space=\"preserve\">\n    <value>Il download del pacchetto Microsoft Store non supporta l'argomento --rename. Il pacchetto Microsoft Store userà i nomi forniti dal catalogo Microsoft Store.</value>\n    <comment>{Locked=\"--rename\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadAuthenticationNotice\" xml:space=\"preserve\">\n    <value>Microsoft Store download del pacchetto richiede l'autenticazione con ID Microsoft Entra. La richiesta di autenticazione può essere visualizzata quando necessario. Le informazioni autenticate verranno condivise con servizi Microsoft per l'autorizzazione di accesso. Per Microsoft Store gestione delle licenze dei pacchetti, l'account ID Microsoft Entra deve essere membro dell'amministratore globale, dell'amministratore utente o dell'amministratore delle licenze.</value>\n    <comment>{Locked=\"Global Administrator,User Administrator,License Administrator\"}</comment>\n  </data>\n  <data name=\"SkipMicrosoftStorePackageLicenseArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignora il recupero della licenza offline del pacchetto Microsoft Store</value>\n  </data>\n  <data name=\"PlatformArgumentDescription\" xml:space=\"preserve\">\n    <value>Seleziona la piattaforma di destinazione</value>\n  </data>\n  <data name=\"ConfigurationExportAddingToFile\" xml:space=\"preserve\">\n    <value>Aggiunta del file di configurazione: {0}</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportSuccessful\" xml:space=\"preserve\">\n    <value>Esportazione completata</value>\n  </data>\n  <data name=\"ConfigurationGettingResourceSettings\" xml:space=\"preserve\">\n    <value>Recupero delle impostazioni di configurazione in corso...</value>\n  </data>\n  <data name=\"ConfigureExportArgumentRequiredError\" xml:space=\"preserve\">\n    <value>È necessario specificare almeno --packageId e/o --module con --resource. In alternativa, usare --all per esportare tutte le configurazioni dei pacchetti.</value>\n    <comment>{Locked=\"--packageId,--module, --resource, --all\"}</comment>\n  </data>\n  <data name=\"ConfigureExportArgumentConflictWithAllError\" xml:space=\"preserve\">\n    <value>Gli argomenti --packageId, --module e --resource non possono essere utilizzati insieme a --all.</value>\n    <comment>{Locked=\"--packageId,--module, --resource, --all\"}</comment>\n  </data>\n  <data name=\"ConfigureExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Esporta le risorse di configurazione in un file di configurazione. Se usato con --all, esporta tutte le configurazioni dei pacchetti. Se usato con --packageId, esporta una risorsa WinGetPackage dell'ID pacchetto specificato. Se usato con --module e --resource, ottiene le impostazioni della risorsa ed esporta la risorsa nel file di configurazione. Se il file di configurazione di output esiste già, aggiunge le risorse di configurazione esportate.</value>\n    <comment>{Locked=\"WinGetPackage,--packageId,--module, --resource\"}</comment>\n  </data>\n  <data name=\"ConfigureExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Esporta le risorse di configurazione in un file di configurazione.</value>\n  </data>\n  <data name=\"ConfigureExportModule\" xml:space=\"preserve\">\n    <value>Modulo della risorsa da esportare.</value>\n  </data>\n  <data name=\"ConfigureExportPackageId\" xml:space=\"preserve\">\n    <value>Identificatore del pacchetto da esportare.</value>\n  </data>\n  <data name=\"ConfigureExportResource\" xml:space=\"preserve\">\n    <value>Risorsa di configurazione da esportare.</value>\n  </data>\n  <data name=\"ConfigureExportAll\" xml:space=\"preserve\">\n    <value>Esporta tutte le configurazioni del pacchetto.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_GET_FAILED\" xml:space=\"preserve\">\n    <value>Non è possibile ottenere le proprietà dell'unità di configurazione.</value>\n  </data>\n  <data name=\"ConfigurationExportFailed\" xml:space=\"preserve\">\n    <value>Esportazione della configurazione non riuscita.</value>\n  </data>\n  <data name=\"ConfigureExportUnitDescription\" xml:space=\"preserve\">\n    <value>Configura {0}</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigureExportUnitInstallDescription\" xml:space=\"preserve\">\n    <value>Installa {0}</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationWarningSetViewTruncated\" xml:space=\"preserve\">\n    <value>Alcuni dati presenti nel file di configurazione sono stati troncati per questo output; controllare il contenuto completo del file.</value>\n  </data>\n  <data name=\"ConfigurationWarningValueTruncated\" xml:space=\"preserve\">\n    <value>&lt;questo valore è stato troncato; controlla il contenuto del file per il testo completo&gt;</value>\n    <comment>Keep some form of separator like the \"&lt;&gt;\" around the text so that it stands out from the preceding text.</comment>\n  </data>\n  <data name=\"ConfigureListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Mostra i dettagli di alto livello per le configurazioni applicate al sistema. Questi dati possono quindi essere usati con `configure` comandi per ottenere maggiori dettagli.</value>\n    <comment>{Locked=\"`configure`\"}</comment>\n  </data>\n  <data name=\"ConfigureListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Mostra la cronologia di configurazione</value>\n  </data>\n  <data name=\"ConfigurationHistoryEmpty\" xml:space=\"preserve\">\n    <value>Non sono presenti configurazioni nella cronologia.</value>\n  </data>\n  <data name=\"ConfigurationHistoryItemArgumentDescription\" xml:space=\"preserve\">\n    <value>Seleziona elementi dalla cronologia</value>\n  </data>\n  <data name=\"ConfigurationHistoryItemNotFound\" xml:space=\"preserve\">\n    <value>Impossibile trovare una singola configurazione corrispondente ai dati forniti. Specificare il nome completo o parte dell'identificatore che corrisponda senza ambiguità alla configurazione desiderata.</value>\n  </data>\n  <data name=\"ConfigurationHistoryRemoveArgumentDescription\" xml:space=\"preserve\">\n    <value>Rimuovi l'elemento dalla cronologia</value>\n  </data>\n  <data name=\"ConfigureListFirstApplied\" xml:space=\"preserve\">\n    <value>Prima applicazione</value>\n    <comment>Column header for date values indicating when a configuration was first applied to the system.</comment>\n  </data>\n  <data name=\"ConfigureListIdentifier\" xml:space=\"preserve\">\n    <value>Identificatore</value>\n  </data>\n  <data name=\"ConfigureListName\" xml:space=\"preserve\">\n    <value>Nome</value>\n  </data>\n  <data name=\"ConfigureListOrigin\" xml:space=\"preserve\">\n    <value>Origine</value>\n  </data>\n  <data name=\"ConfigureListPath\" xml:space=\"preserve\">\n    <value>Percorso</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_HISTORY_ITEM_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Non è possibile trovare la configurazione specificata.</value>\n  </data>\n  <data name=\"ConfigurationSetStateCompleted\" xml:space=\"preserve\">\n    <value>Operazione completata</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStateInProgress\" xml:space=\"preserve\">\n    <value>In corso</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStatePending\" xml:space=\"preserve\">\n    <value>In sospeso</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStateUnknown\" xml:space=\"preserve\">\n    <value>Sconosciuto</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationStatusWatchArgumentDescription\" xml:space=\"preserve\">\n    <value>Stato di configurazione monitoraggio.</value>\n    <comment>As in \"to monitor the status of a configuration being applied\".</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateCompleted\" xml:space=\"preserve\">\n    <value>Completato</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateInProgress\" xml:space=\"preserve\">\n    <value>In corso</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStatePending\" xml:space=\"preserve\">\n    <value>In sospeso</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateSkipped\" xml:space=\"preserve\">\n    <value>Ignorato</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateUnknown\" xml:space=\"preserve\">\n    <value>Sconosciuto</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigureListApplyBegun\" xml:space=\"preserve\">\n    <value>Applicazione avviata</value>\n    <comment>When the configuration application started.</comment>\n  </data>\n  <data name=\"ConfigureListApplyEnded\" xml:space=\"preserve\">\n    <value>Applicazione terminata</value>\n    <comment>When the configuration application ended.</comment>\n  </data>\n  <data name=\"ConfigureListResult\" xml:space=\"preserve\">\n    <value>Risultato</value>\n  </data>\n  <data name=\"ConfigureListResultDescription\" xml:space=\"preserve\">\n    <value>Dettagli</value>\n  </data>\n  <data name=\"ConfigureListState\" xml:space=\"preserve\">\n    <value>Stato</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigureListUnit\" xml:space=\"preserve\">\n    <value>Unità</value>\n  </data>\n  <data name=\"StoreInstall_PackageNotAvailableForCurrentSystem\" xml:space=\"preserve\">\n    <value>Il pacchetto non è compatibile con la versione o la piattaforma Windows corrente.</value>\n  </data>\n  <data name=\"ConfigurationSuppressPrologueArgumentDescription\" xml:space=\"preserve\">\n    <value>Non visualizzare i dettagli della configurazione iniziale quando possibile</value>\n  </data>\n  <data name=\"MSStoreDownloadMultiplePackagesNotice\" xml:space=\"preserve\">\n    <value>È possibile scaricare più pacchetti Microsoft Store destinati a piattaforme e architetture diverse. --platform, --architecture può essere usato per filtrare i pacchetti.</value>\n    <comment>{Locked=\"--platform--architecture\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseForbidden\" xml:space=\"preserve\">\n    <value>Non è stato possibile recuperare Microsoft Store licenza del pacchetto. L'account ID Microsoft Entra non è membro di Amministratore globale, Amministratore utenti o Amministratore licenze. Usare --skip-license per ignorare il recupero Microsoft Store licenza del pacchetto.</value>\n    <comment>{Locked=\"Global Administrator,User Administrator,License Administrator,--skip-license\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadNotSupported\" xml:space=\"preserve\">\n    <value>Il pacchetto Microsoft Store non supporta il download.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SFSCLIENT_PACKAGE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Il pacchetto Microsoft Store non supporta il download.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED_FORBIDDEN\" xml:space=\"preserve\">\n    <value>Non è stato possibile recuperare Microsoft Store licenza del pacchetto. L'account id Microsoft Entra non dispone dei privilegi necessari.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_PARAMETER_INTEGRITY_BOUNDARY\" xml:space=\"preserve\">\n    <value>Il parametro non può essere passato oltre il limite di integrità.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_ZERO_BYTE_FILE\" xml:space=\"preserve\">\n    <value>Programma di installazione a zero byte scaricato; verificare che la connessione di rete funzioni correttamente.</value>\n  </data>\n  <data name=\"InstallerZeroByteFile\" xml:space=\"preserve\">\n    <value>Programma di installazione a zero byte scaricato; verificare che la connessione di rete funzioni correttamente.</value>\n  </data>\n  <data name=\"FontCommandShortDescription\" xml:space=\"preserve\">\n    <value>Gestire i tipi di carattere</value>\n  </data>\n  <data name=\"FontCommandLongDescription\" xml:space=\"preserve\">\n    <value>Gestire i tipi di carattere con i sottocomandi. I tipi di carattere possono essere installati, aggiornati o disinstallati in modo simile ai pacchetti. </value>\n  </data>\n  <data name=\"FontFamily\" xml:space=\"preserve\">\n    <value>Famiglia</value>\n  </data>\n  <data name=\"FontFaces\" xml:space=\"preserve\">\n    <value>Facce</value>\n    <comment>\"Faces\" represents the typeface of the font family such as 'Bold' or 'Italic'</comment>\n  </data>\n  <data name=\"FontFamilyNameArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtra i risultati per cognome</value>\n  </data>\n  <data name=\"FontFace\" xml:space=\"preserve\">\n    <value>Viso</value>\n    <comment>\"Face\" represents the typeface of a font family such as 'Bold' or 'Italic'</comment>\n  </data>\n  <data name=\"FontFilePaths\" xml:space=\"preserve\">\n    <value>Percorsi</value>\n  </data>\n  <data name=\"NoInstalledFontFound\" xml:space=\"preserve\">\n    <value>Nessun tipo di carattere installato corrisponde ai criteri di input.</value>\n  </data>\n  <data name=\"FontListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Elencare i tipi di carattere installati</value>\n  </data>\n  <data name=\"FontListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Elenca tutti i tipi di carattere installati, tutti i file di tipi di carattere o i dettagli completi di un tipo di carattere specifico.</value>\n  </data>\n  <data name=\"FontVersion\" xml:space=\"preserve\">\n    <value>Versione</value>\n  </data>\n  <data name=\"ConfigurationModules\" xml:space=\"preserve\">\n    <value>Moduli di configurazione</value>\n    <comment>PowerShell Modules that are used for the Configuration feature</comment>\n  </data>\n  <data name=\"InstallerDownloadRequiresAuthentication\" xml:space=\"preserve\">\n    <value>Il programma di installazione del pacchetto richiede l'autenticazione. La richiesta di autenticazione può essere visualizzata quando necessario. Le informazioni autenticate verranno condivise con l'URL di download del programma di installazione.</value>\n  </data>\n  <data name=\"InstallerDownloadAuthenticationNotSupported\" xml:space=\"preserve\">\n    <value>Non è stato possibile scaricare il programma di installazione. Questa versione winget non supporta il metodo di autenticazione per il download del programma di installazione. Provare a eseguire l'aggiornamento alla versione più recente winget.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"InstallerDownloadAuthenticationFailed\" xml:space=\"preserve\">\n    <value>Download del programma di installazione non riuscito. Autenticazione non riuscita.</value>\n  </data>\n  <data name=\"ConfigurationProcessorPath\" xml:space=\"preserve\">\n    <value>Specifica il percorso del processore di configurazione</value>\n  </data>\n  <data name=\"DscCommandShortDescription\" xml:space=\"preserve\">\n    <value>Comandi delle risorse DSC v3</value>\n    <comment>DSC stands for \"Desired State Configuration\". It should already have a locked translation.</comment>\n  </data>\n  <data name=\"DscCommandLongDescription\" xml:space=\"preserve\">\n    <value>I comandi secondari implementano le risorse Desired State Configuration (DSC) v3 per la configurazione di winget e pacchetti.</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionGet\" xml:space=\"preserve\">\n    <value>Recupera stato della risorsa</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionSet\" xml:space=\"preserve\">\n    <value>Imposta stato della risorsa</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionWhatIf\" xml:space=\"preserve\">\n    <value>Descrivi le modifiche di stato necessarie</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionTest\" xml:space=\"preserve\">\n    <value>Testa stato della risorsa</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionDelete\" xml:space=\"preserve\">\n    <value>Elimina stato della risorsa</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionExport\" xml:space=\"preserve\">\n    <value>Recupera tutte le istanze di stato</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionValidate\" xml:space=\"preserve\">\n    <value>Convalida contenuti del gruppo</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionResolve\" xml:space=\"preserve\">\n    <value>Risolvi stato esterno</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionAdapter\" xml:space=\"preserve\">\n    <value>Esegui scheda</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionSchema\" xml:space=\"preserve\">\n    <value>Recupera schema della risorsa</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionManifest\" xml:space=\"preserve\">\n    <value>Recupera manifesto della risorsa</value>\n  </data>\n  <data name=\"DscPackageResourceShortDescription\" xml:space=\"preserve\">\n    <value>Gestisci stato del pacchetto</value>\n  </data>\n  <data name=\"DscPackageResourceLongDescription\" xml:space=\"preserve\">\n    <value>Gestisci pacchetti tramite WinGet.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionExist\" xml:space=\"preserve\">\n    <value>Indica se un'istanza deve esistere o meno.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionInDesiredState\" xml:space=\"preserve\">\n    <value>Indica se un'istanza si trova nello stato desiderato.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageId\" xml:space=\"preserve\">\n    <value>Identificatore pacchetto.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageSource\" xml:space=\"preserve\">\n    <value>Origine pacchetto.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageVersion\" xml:space=\"preserve\">\n    <value>Versione del pacchetto.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageMatchOption\" xml:space=\"preserve\">\n    <value>Metodo per la corrispondenza dell'identificatore con un pacchetto.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageUseLatest\" xml:space=\"preserve\">\n    <value>Indica che deve essere installata la versione più recente disponibile del pacchetto.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageInstallMode\" xml:space=\"preserve\">\n    <value>Modalità di installazione da utilizzare, se necessario.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageScope\" xml:space=\"preserve\">\n    <value>Ambito di destinazione del pacchetto.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionAcceptAgreements\" xml:space=\"preserve\">\n    <value>Indica se accettare contratti per origini e pacchetti.</value>\n  </data>\n  <data name=\"DscUserSettingsFileShortDescription\" xml:space=\"preserve\">\n    <value>Gestisci file delle impostazioni utente</value>\n  </data>\n  <data name=\"DscUserSettingsFileLongDescription\" xml:space=\"preserve\">\n    <value>Gestisci le impostazioni utente di WinGet.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionUserSettingsFileSettings\" xml:space=\"preserve\">\n    <value>Contenuto del file JSON delle impostazioni.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionUserSettingsFileAction\" xml:space=\"preserve\">\n    <value>Azione utilizzata per applicare le impostazioni.</value>\n  </data>\n  <data name=\"CorrelationArgumentDescription\" xml:space=\"preserve\">\n    <value>Il valore è registrato per la correlazione</value>\n  </data>\n  <data name=\"DscSourceResourceShortDescription\" xml:space=\"preserve\">\n    <value>Gestisci configurazione di origine</value>\n  </data>\n  <data name=\"DscSourceResourceLongDescription\" xml:space=\"preserve\">\n    <value>Gestisci le origini di WinGet.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceName\" xml:space=\"preserve\">\n    <value>Nome da utilizzare per l'origine.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceArgument\" xml:space=\"preserve\">\n    <value>Argomento per l'origine.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceType\" xml:space=\"preserve\">\n    <value>Tipo di origine.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceTrustLevel\" xml:space=\"preserve\">\n    <value>Livello di attendibilità dell'origine.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceExplicit\" xml:space=\"preserve\">\n    <value>Indica se l'origine è inclusa quando le chiamate non specificano un'origine.</value>\n  </data>\n  <data name=\"ConfigurationApplyingUnit\" xml:space=\"preserve\">\n    <value>Applicazione dell'unità di configurazione in corso...</value>\n  </data>\n  <data name=\"ConfigurationExportingUnit\" xml:space=\"preserve\">\n    <value>Esportazione dell'unità di configurazione in corso...</value>\n  </data>\n  <data name=\"ConfigurationGettingUnitProcessors\" xml:space=\"preserve\">\n    <value>Recupero dei processori dell'unità di configurazione in corso...</value>\n  </data>\n  <data name=\"ConfigurationExportInstallRequiredModule\" xml:space=\"preserve\">\n    <value>Assicurati che sia presente il modulo necessario per l'esportazione [{0}]</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportInstallRequiredModuleFailed\" xml:space=\"preserve\">\n    <value>Non è stato possibile testare o acquisire il modulo richiesto. Le impostazioni correlate non verranno esportate.</value>\n  </data>\n  <data name=\"ConfigurationExportUnitStart\" xml:space=\"preserve\">\n    <value>Esporta [{0}]</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportUnitFailed\" xml:space=\"preserve\">\n    <value>Esportazione della risorsa non riuscita.</value>\n  </data>\n  <data name=\"ConfigurationExportFailedToGetUnitProcessors\" xml:space=\"preserve\">\n    <value>Impossibile ottenere i processori di unità. Le impostazioni dei singoli pacchetti non verranno esportate.</value>\n  </data>\n  <data name=\"OutputDirectoryArgumentDescription\" xml:space=\"preserve\">\n    <value>Directory in cui devono essere scritti i risultati</value>\n  </data>\n  <data name=\"ConfigurationInstallDscPackage\" xml:space=\"preserve\">\n    <value>Pacchetto Desired State Configuration non trovato nel sistema. Installazione del pacchetto in corso...</value>\n  </data>\n  <data name=\"ConfigurationInstallDscPackageFailed\" xml:space=\"preserve\">\n    <value>Non è stato possibile installare Desired State Configuration pacchetto. Installare il pacchetto manualmente o specificare il percorso per dsc.exe tramite --processor-path argomento.</value>\n    <comment>{Locked=\"dsc.exe\",\"--processor-path\"}</comment>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionAdminSettingsSettings\" xml:space=\"preserve\">\n    <value>Oggetto contenente le impostazioni di amministratore e i relativi valori.</value>\n  </data>\n  <data name=\"DscAdminSettingsResourceShortDescription\" xml:space=\"preserve\">\n    <value>Gestisci impostazioni amministratore</value>\n  </data>\n  <data name=\"DscAdminSettingsResourceLongDescription\" xml:space=\"preserve\">\n    <value>Gestisci impostazioni amministratore di WinGet.</value>\n  </data>\n  <data name=\"ResetAllAdminSettingsArgumentDescription\" xml:space=\"preserve\">\n    <value>Reimposta tutte le impostazioni di amministrazione</value>\n  </data>\n  <data name=\"ResetAllAdminSettingsSucceeded\" xml:space=\"preserve\">\n    <value>Reimpostazione di tutte le impostazioni di amministrazione.</value>\n  </data>\n  <data name=\"McpCommandShortDescription\" xml:space=\"preserve\">\n    <value>Informazioni MCP</value>\n    <comment>MCP stands for Model Context Protocol and should probably remain as-is</comment>\n  </data>\n  <data name=\"McpCommandLongDescription\" xml:space=\"preserve\">\n    <value>Informazioni MCP (Model Context Protocol) per il Gestione pacchetti Windows.</value>\n  </data>\n  <data name=\"McpConfigurationPreamble\" xml:space=\"preserve\">\n    <value>Per configurare manualmente il server MCP Gestione pacchetti Windows con il client MCP, usare il frammento JSON seguente nell'oggetto `servers`:</value>\n    <comment>{Locked=\"`servers`\"}\nMCP stands for Model Context Protocol and should probably remain as-is.\nAn unlocalized JSON fragment will follow on another line.</comment>\n  </data>\n  <data name=\"PolicyEnableMcpServer\" xml:space=\"preserve\">\n    <value>Abilita Gestione pacchetti Windows server MCP</value>\n  </data>\n  <data name=\"OSVersionDescription\" xml:space=\"preserve\">\n    <value>Versione del sistema operativo di destinazione</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Impossibile installare uno o più tipi di carattere.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Il file dei tipi di carattere non è supportato e non può essere installato.</value>\n  </data>\n  <data name=\"FontFileNotSupported\" xml:space=\"preserve\">\n    <value>Uno o più tipi di carattere nel pacchetto di tipi di carattere non sono supportati e non possono essere installati.</value>\n  </data>\n  <data name=\"FontInstallFailed\" xml:space=\"preserve\">\n    <value>Installazione del tipo di carattere non riuscita; pulizia.</value>\n  </data>\n  <data name=\"FontAlreadyInstalled\" xml:space=\"preserve\">\n    <value>Tipo di carattere già installato.</value>\n  </data>\n  <data name=\"FontPackage\" xml:space=\"preserve\">\n    <value>ID pacchetto</value>\n  </data>\n  <data name=\"FontWinGetSupported\" xml:space=\"preserve\">\n    <value>WinGet supportato</value>\n  </data>\n  <data name=\"FontTitle\" xml:space=\"preserve\">\n    <value>Titolo</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Il file del tipo di carattere non è stato trovato.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Disinstallazione del carattere non riuscita. Il tipo di carattere potrebbe non essere in uno stato valido. Provare a disinstallare dopo un riavvio.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>Convalida del tipo di carattere non riuscita.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_ROLLBACK_FAILED\" xml:space=\"preserve\">\n    <value>Rollback del tipo di carattere non riuscito. Il tipo di carattere potrebbe non essere in uno stato valido. Provare a disinstallare dopo un riavvio.</value>\n  </data>\n  <data name=\"FontDetailsArgumentDescription\" xml:space=\"preserve\">\n    <value>Mostra informazioni dettagliate sul file del tipo di carattere.</value>\n  </data>\n  <data name=\"FontValidationFailed\" xml:space=\"preserve\">\n    <value>La convalida del pacchetto del tipo di carattere non è riuscita.</value>\n  </data>\n  <data name=\"FontRollbackFailed\" xml:space=\"preserve\">\n    <value>Il tentativo di rollback per l'installazione del tipo di carattere non riuscita non è riuscito. Potrebbe essere necessario riavviare il sistema per disinstallare correttamente il tipo di carattere.</value>\n  </data>\n  <data name=\"FontUninstallFailed\" xml:space=\"preserve\">\n    <value>Disinstallazione del pacchetto di caratteri non riuscita. Questo errore è spesso dovuto al fatto che i tipi di carattere sono in uso dal sistema o da un'applicazione. La disinstallazione potrebbe essere riuscita dopo il riavvio del computer.</value>\n  </data>\n  <data name=\"FontStatusOK\" xml:space=\"preserve\">\n    <value>OK</value>\n    <comment>\"OK\" means the font is in a good healthy state</comment>\n  </data>\n  <data name=\"FontStatusCorrupt\" xml:space=\"preserve\">\n    <value>Danneggiata</value>\n    <comment>\"Corrupt\" refers to an install that is in a corrupted or bad state, and needs repair.</comment>\n  </data>\n  <data name=\"FontStatus\" xml:space=\"preserve\">\n    <value>Stato</value>\n  </data>\n  <data name=\"FontStatusUnknown\" xml:space=\"preserve\">\n    <value>Sconosciuto</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>Il pacchetto di tipi di carattere è già installato.</value>\n  </data>\n  <data name=\"ListDetailsArgumentDescription\" xml:space=\"preserve\">\n    <value>Visualizza informazioni dettagliate sui pacchetti</value>\n    <comment>Providing this argument causes the CLI to output additional details about installed application packages.</comment>\n  </data>\n  <data name=\"ShowLabelChannel\" xml:space=\"preserve\">\n    <value>Canale:</value>\n    <comment>Precedes a string value that names the delivery channel for the software package (ex. stable, beta).</comment>\n  </data>\n  <data name=\"ShowListLocalIdentifier\" xml:space=\"preserve\">\n    <value>Identificatore locale:</value>\n    <comment>Precedes a value that is the unique identifier for the installed package on the local system.</comment>\n  </data>\n  <data name=\"ShowListPackageFamilyName\" xml:space=\"preserve\">\n    <value>Nome della famiglia di pacchetti:</value>\n    <comment>Precedes a value that is the APPX/MSIX package family name of the installed package.</comment>\n  </data>\n  <data name=\"ShowListProductCode\" xml:space=\"preserve\">\n    <value>Codice prodotto:</value>\n    <comment>Precedes a value that is the Add/Remove Programs identifier in the registry. This is also the Product Code value as defined in MSI installers.</comment>\n  </data>\n  <data name=\"ShowListUpgradeCode\" xml:space=\"preserve\">\n    <value>Codice aggiornamento:</value>\n    <comment>Precedes a value that is the MSI Upgrade Code for the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledScope\" xml:space=\"preserve\">\n    <value>Ambito installazione:</value>\n    <comment>Precedes a value that is the scope of the installation of the package (ex. user, machine).</comment>\n  </data>\n  <data name=\"ShowListInstalledArchitecture\" xml:space=\"preserve\">\n    <value>Architettura installata:</value>\n    <comment>Precedes a value that is the installed architecture of the package (ex. x86, x64, ARM64).</comment>\n  </data>\n  <data name=\"ShowListInstalledLocale\" xml:space=\"preserve\">\n    <value>Impostazioni locali installate:</value>\n    <comment>Precedes a value that is the locale of the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledLocation\" xml:space=\"preserve\">\n    <value>Posizione installata:</value>\n    <comment>Precedes a value that is the directory path to the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledSource\" xml:space=\"preserve\">\n    <value>Origine:</value>\n    <comment>Precedes a value that names the package source where the installed package originated from.</comment>\n  </data>\n  <data name=\"ShowListAvailableUpgrades\" xml:space=\"preserve\">\n    <value>Aggiornamenti disponibili:</value>\n    <comment>Precedes a list of package upgrades available for the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstallerCategory\" xml:space=\"preserve\">\n    <value>Categoria programma di installazione:</value>\n    <comment>Precedes a value that indicates the category of the installer for the installed package (ex. exe, msi, msix).</comment>\n  </data>\n  <data name=\"SourceEditOldValue\" xml:space=\"preserve\">\n    <value>Valore precedente</value>\n    <comment>Column title for listing edit changes.</comment>\n  </data>\n  <data name=\"SourceEditNewValue\" xml:space=\"preserve\">\n    <value>Nuovo valore</value>\n    <comment>Column title for listing the new value.</comment>\n  </data>\n</root>"
  },
  {
    "path": "Localization/Resources/ja-JP/Resources.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "Localization/Resources/ja-JP/winget.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"AdjoinedNotFlagError\" xml:space=\"preserve\">\n    <value>隣接エイリアスがフラグではありません: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an adjoined alias that is not a flag argument. {0} is a placeholder replaced by the user input argument (e.g. '-ab').</comment>\n  </data>\n  <data name=\"AdjoinedNotFoundError\" xml:space=\"preserve\">\n    <value>隣接フラグエイリアスが見つかりません: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an adjoined flag alias argument that was not found. {0} is a placeholder replaced by the user input argument (e.g. '-ab').</comment>\n  </data>\n  <data name=\"AvailableArguments\" xml:space=\"preserve\">\n    <value>次の引数を使用できます。</value>\n    <comment>Message displayed to inform the user about the available command line arguments.</comment>\n  </data>\n  <data name=\"AvailableCommandAliases\" xml:space=\"preserve\">\n    <value>次のコマンド エイリアスを使用できます:</value>\n    <comment>Message displayed to inform the user about the available command line alias arguments.</comment>\n  </data>\n  <data name=\"AvailableCommands\" xml:space=\"preserve\">\n    <value>使用できるコマンドは次のとおりです:</value>\n    <comment>Title displayed to inform the user about the available commands.</comment>\n  </data>\n  <data name=\"AvailableHeader\" xml:space=\"preserve\">\n    <value>利用可能</value>\n    <comment>As in \"a new version is available to upgrade to\".</comment>\n  </data>\n  <data name=\"AvailableOptions\" xml:space=\"preserve\">\n    <value>次のオプションを使用できます。</value>\n    <comment>Message displayed to inform the user about the available options.</comment>\n  </data>\n  <data name=\"AvailableSubcommands\" xml:space=\"preserve\">\n    <value>次のサブコマンドを使用できます。</value>\n    <comment>Message displayed to inform the user about the available nested commands that run in context of the selected command.</comment>\n  </data>\n  <data name=\"AvailableUpgrades\" xml:space=\"preserve\">\n    <value>{0} アップグレードを利用できます。</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about available package upgrades. {0} is a placeholder replaced by the number of package upgrades.</comment>\n  </data>\n  <data name=\"ChannelArgumentDescription\" xml:space=\"preserve\">\n    <value>指定されたチャンネルを使用します。既定値は一般向けです</value>\n  </data>\n  <data name=\"Command\" xml:space=\"preserve\">\n    <value>コマンド</value>\n    <comment>Label displayed for a command to give the software.</comment>\n  </data>\n  <data name=\"CommandArgumentDescription\" xml:space=\"preserve\">\n    <value>コマンドによる結果のフィルター処理</value>\n    <comment>Description message displayed to inform the user about filtering the search results by a package command.</comment>\n  </data>\n  <data name=\"CommandLineArgumentDescription\" xml:space=\"preserve\">\n    <value>完了するための完全なコマンド ライン</value>\n  </data>\n  <data name=\"CommandRequiresAdmin\" xml:space=\"preserve\">\n    <value>このコマンドを実行するには、管理者権限が必要です。</value>\n  </data>\n  <data name=\"CompleteCommandLongDescription\" xml:space=\"preserve\">\n    <value>このコマンドは、状況依存のコマンド ラインの完了を要求するために使用できます。コマンド ライン、カーソル位置、および完了する単語が渡されます。出力は、入力に基づいた一連の潜在的な値で、1 行に 1 つの可能な値が入ります。</value>\n  </data>\n  <data name=\"CompleteCommandShortDescription\" xml:space=\"preserve\">\n    <value>状況依存のコマンド ラインの完了を有効にする</value>\n  </data>\n  <data name=\"CountArgumentDescription\" xml:space=\"preserve\">\n    <value>指定した数を超える結果を表示しない (1 ~ 1000)</value>\n  </data>\n  <data name=\"Done\" xml:space=\"preserve\">\n    <value>完了</value>\n    <comment>Label displayed when an operation completes or is done executing.</comment>\n  </data>\n  <data name=\"ExactArgumentDescription\" xml:space=\"preserve\">\n    <value>完全一致を使用してパッケージを検索</value>\n    <comment>Description message displayed to inform the user about finding an application package using an exact matching criteria.</comment>\n  </data>\n  <data name=\"ExperimentalArgumentDescription\" xml:space=\"preserve\">\n    <value>デモを目的とした試験的引数</value>\n  </data>\n  <data name=\"ExperimentalCommandLongDescription\" xml:space=\"preserve\">\n    <value>このコマンドは、試験的な機能を実装する方法の例です。有効にするには、\"winget settings\"へと移動し、experimentalCmdまたはexperimentalArg機能を有効にします。</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"ExperimentalCommandShortDescription\" xml:space=\"preserve\">\n    <value>試験的な機能の例</value>\n  </data>\n  <data name=\"ExtraPositionalError\" xml:space=\"preserve\">\n    <value>何も指定されていないときに位置引数が見つかりました: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an extra positional argument when none was expected. {0} is a placeholder replaced by the user's extra argument input.</comment>\n  </data>\n  <data name=\"FeatureDisabledMessage\" xml:space=\"preserve\">\n    <value>この機能は進行中の作業であり、今後大幅に変更または完全に削除される可能性があります。これを有効にするには、設定 ('winget settings') を編集して試験的な機能を含めます: '{0}'</value>\n    <comment>{Locked=\"winget settings\",\"{0}\"}. Error message displayed when the user uses an experimental feature that is disabled. {0} is a placeholder replaced by the experimental feature name.</comment>\n  </data>\n  <data name=\"FeaturesCommandLongDescription\" xml:space=\"preserve\">\n    <value>試験的な機能の状態を表示します。試験的な機能は、\"winget settings\" を使用してオンにすることができます。</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"FeaturesCommandShortDescription\" xml:space=\"preserve\">\n    <value>試験的な機能の状態を表示</value>\n  </data>\n  <data name=\"FeaturesDisabled\" xml:space=\"preserve\">\n    <value>無効</value>\n  </data>\n  <data name=\"FeaturesEnabled\" xml:space=\"preserve\">\n    <value>有効</value>\n  </data>\n  <data name=\"FeaturesFeature\" xml:space=\"preserve\">\n    <value>機能</value>\n  </data>\n  <data name=\"FeaturesLink\" xml:space=\"preserve\">\n    <value>リンク</value>\n  </data>\n  <data name=\"FeaturesMessage\" xml:space=\"preserve\">\n    <value>次の試験的な機能が進行中です。\nこれらの設定は、設定ファイル'winget settings'を使用して構成できます。</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"FeaturesProperty\" xml:space=\"preserve\">\n    <value>プロパティ</value>\n  </data>\n  <data name=\"FeaturesStatus\" xml:space=\"preserve\">\n    <value>状態</value>\n  </data>\n  <data name=\"FileArgumentDescription\" xml:space=\"preserve\">\n    <value>ハッシュするファイル</value>\n  </data>\n  <data name=\"FlagContainAdjoinedError\" xml:space=\"preserve\">\n    <value>フラグ引数に隣接する値を含めることはできません: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a flag argument containing an unexpected adjoined value. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"HashCommandLongDescription\" xml:space=\"preserve\">\n    <value>マニフェストへのエントリに適したローカル ファイルのハッシュを計算します。また、MSIX パッケージの署名ファイルのハッシュを計算して、ストリーミング インストールを有効にすることもできます。</value>\n  </data>\n  <data name=\"HashCommandShortDescription\" xml:space=\"preserve\">\n    <value>インストーラー ファイルをハッシュするヘルパー</value>\n  </data>\n  <data name=\"HelpArgumentDescription\" xml:space=\"preserve\">\n    <value>選択したコマンドに関するヘルプを表示</value>\n  </data>\n  <data name=\"HelpForDetails\" xml:space=\"preserve\">\n    <value>特定のコマンドの詳細については、そのコマンドにヘルプ引数を渡します。</value>\n  </data>\n  <data name=\"HelpLinkPreamble\" xml:space=\"preserve\">\n    <value>その他のヘルプについては、次を参照してください: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a link where they can learn more about the subject context. {0} is a placeholder replaced by a website address.</comment>\n  </data>\n  <data name=\"IdArgumentDescription\" xml:space=\"preserve\">\n    <value>ID で結果をフィルター処理</value>\n  </data>\n  <data name=\"IgnoreWarningsArgumentDescription\" xml:space=\"preserve\">\n    <value>警告出力を非表示にする</value>\n  </data>\n  <data name=\"InstallationDisclaimer1\" xml:space=\"preserve\">\n    <value>このアプリケーションは所有者からライセンス供与されます。</value>\n  </data>\n  <data name=\"InstallationDisclaimer2\" xml:space=\"preserve\">\n    <value>Microsoft はサードパーティのパッケージに対して責任を負わず、ライセンスも付与しません。</value>\n  </data>\n  <data name=\"InstallationDisclaimerMSStore\" xml:space=\"preserve\">\n    <value>このパッケージは Microsoft Store から提供されています。winget は、現在のユーザーに代わって Microsoft Store からパッケージを取得する必要がある場合があります。</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"InstallCommandLongDescription\" xml:space=\"preserve\">\n    <value>構成されたソースを探して見つけるかマニフェストから直接見つけて、選んだパッケージをインストールします。既定では、そのクエリはパッケージの id、name、または moniker と大文字小文字の区別なく一致する必要があります。その他のフィールドは、適切なオプションを渡すと使えます。既定では、install コマンドは、パッケージのインストール済み状態を確認し、アップグレードがあればそれを実行しようとします。直接インストールするには、--force を指定してオーバーライドします。</value>\n    <comment>{Locked=\"--force\"}; id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"InstallCommandShortDescription\" xml:space=\"preserve\">\n    <value>指定されたパッケージをインストール</value>\n  </data>\n  <data name=\"InstallerHashMismatchAdminBlock\" xml:space=\"preserve\">\n    <value>インストーラーのハッシュが一致しません; これは、管理者として実行している場合は上書きできません</value>\n  </data>\n  <data name=\"InstallerHashMismatchOverridden\" xml:space=\"preserve\">\n    <value>インストーラーのハッシュが一致しません。--ignore-security-hash のため続行しています</value>\n    <comment>{Locked=\"--ignore-security-hash\"}</comment>\n  </data>\n  <data name=\"InstallerHashMismatchOverrideRequired\" xml:space=\"preserve\">\n    <value>インストーラーのハッシュが一致しません。このチェックをオーバーライドするには、--ignore-security-hash を使用してください</value>\n    <comment>{Locked=\"--ignore-security-hash\"}</comment>\n  </data>\n  <data name=\"InstallerHashVerified\" xml:space=\"preserve\">\n    <value>インストーラーハッシュが正常に検証されました</value>\n  </data>\n  <data name=\"InstallFlowInstallSuccess\" xml:space=\"preserve\">\n    <value>インストールが完了しました</value>\n  </data>\n  <data name=\"InstallFlowStartingPackageInstall\" xml:space=\"preserve\">\n    <value>パッケージのインストールを開始しています...</value>\n  </data>\n  <data name=\"HashOverrideArgumentDescription\" xml:space=\"preserve\">\n    <value>インストーラーのハッシュのチェックが失敗しても無視します</value>\n  </data>\n  <data name=\"IgnoreLocalArchiveMalwareScanArgumentDescription\" xml:space=\"preserve\">\n    <value>ローカル マニフェストからのアーカイブの種類のパッケージのインストールの一環として実行されたマルウェア スキャンを無視します</value>\n  </data>\n  <data name=\"InteractiveArgumentDescription\" xml:space=\"preserve\">\n    <value>対話式のインストールが要求されます。ユーザーの入力が必要になる場合があります</value>\n  </data>\n  <data name=\"InvalidAliasError\" xml:space=\"preserve\">\n    <value>引数のエイリアスが現在のコマンドに対して認識されませんでした: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a command line argument alias that was not recognized for a selected command. {0} is a placeholder replaced by the user's argument alias input (e.g. '-a').</comment>\n  </data>\n  <data name=\"InvalidArgumentSpecifierError\" xml:space=\"preserve\">\n    <value>無効な引数指定子: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an invalid argument specifier. {0} is a placeholder replaced by an argument specifier (e.g. '-').</comment>\n  </data>\n  <data name=\"InvalidNameError\" xml:space=\"preserve\">\n    <value>引数名が現在のコマンドに対して認識されませんでした: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an unrecognized command line argument name for the selected command. {0} is a placeholder replaced by the user's argument name input (e.g. '--example').</comment>\n  </data>\n  <data name=\"KeyDirectoriesHeader\" xml:space=\"preserve\">\n    <value>Winget ディレクトリ</value>\n    <comment>Header for a table detailing the directories Winget uses for key operations like logging and portable installs</comment>\n  </data>\n  <data name=\"LocaleArgumentDescription\" xml:space=\"preserve\">\n    <value>使用するロケール (BCP47 形式)</value>\n    <comment>{Locked=\"BCP47\"}</comment>\n  </data>\n  <data name=\"LicenseAgreement\" xml:space=\"preserve\">\n    <value>使用許諾契約</value>\n  </data>\n  <data name=\"Links\" xml:space=\"preserve\">\n    <value>リンク</value>\n    <comment>Links to different webpages</comment>\n  </data>\n  <data name=\"ListCommandLongDescription\" xml:space=\"preserve\">\n    <value>list コマンドは、システムにインストールされているパッケージと、アップグレードを適用可能かどうかを表示します。search コマンドとよく似ていて、出力をフィルター処理するためのその他のオプションを指定できます。</value>\n    <comment>{Locked=\"list\",\"search\"}</comment>\n  </data>\n  <data name=\"ListCommandShortDescription\" xml:space=\"preserve\">\n    <value>インストール済みパッケージを表示する</value>\n  </data>\n  <data name=\"LocationArgumentDescription\" xml:space=\"preserve\">\n    <value>インストール先 (サポートされている場合)</value>\n  </data>\n  <data name=\"LogArgumentDescription\" xml:space=\"preserve\">\n    <value>ログの場所 (サポートされている場合)</value>\n  </data>\n  <data name=\"MainCopyrightNotice\" xml:space=\"preserve\">\n    <value>Copyright (c) Microsoft Corporation. All rights reserved.</value>\n  </data>\n  <data name=\"MainHomepage\" xml:space=\"preserve\">\n    <value>ホーム ページ</value>\n    <comment>The primary webpage for the software</comment>\n  </data>\n  <data name=\"ManifestArgumentDescription\" xml:space=\"preserve\">\n    <value>パッケージのマニフェストのパス</value>\n  </data>\n  <data name=\"ManifestValidationFail\" xml:space=\"preserve\">\n    <value>マニフェストの検証に失敗しました。</value>\n  </data>\n  <data name=\"ManifestValidationSuccess\" xml:space=\"preserve\">\n    <value>マニフェストの検証は成功しました。</value>\n  </data>\n  <data name=\"ManifestValidationWarning\" xml:space=\"preserve\">\n    <value>マニフェストの検証は成功しましたが、警告があります。</value>\n  </data>\n  <data name=\"MissingArgumentError\" xml:space=\"preserve\">\n    <value>引数の値は必須ですが、見つかりませんでした: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user does not provide a required command line argument value. {0} is a placeholder replaced by the argument name.</comment>\n  </data>\n  <data name=\"MonikerArgumentDescription\" xml:space=\"preserve\">\n    <value>モニカーで結果をフィルター処理</value>\n  </data>\n  <data name=\"MsixArgumentDescription\" xml:space=\"preserve\">\n    <value>入力ファイルは msix として扱われます。署名された場合、署名ハッシュが提供されます</value>\n  </data>\n  <data name=\"MsixSignatureHashFailed\" xml:space=\"preserve\">\n    <value>MSIX 署名ハッシュを計算できませんでした。</value>\n  </data>\n  <data name=\"MSStoreAppBlocked\" xml:space=\"preserve\">\n    <value>特定のアプリがポリシーによってブロックされているため、Microsoft Store パッケージをインストールまたはアップグレードできませんでした</value>\n  </data>\n  <data name=\"MSStoreInstallOrUpdateFailed\" xml:space=\"preserve\">\n    <value>Microsoft Store パッケージをインストールまたはアップグレードできませんでした。エラー コード: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Microsoft Store application package fails to install or upgrade. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"MSStoreStoreClientBlocked\" xml:space=\"preserve\">\n    <value>Microsoft Store クライアントがポリシーによってブロックされているため、Microsoft Store パッケージをインストールまたはアップグレードできませんでした</value>\n  </data>\n  <data name=\"MSStoreInstallTryGetEntitlement\" xml:space=\"preserve\">\n    <value>パッケージ取得の確認/要求...</value>\n  </data>\n  <data name=\"MultipleInstalledPackagesFound\" xml:space=\"preserve\">\n    <value>複数のインストール済みパッケージが一致する入力条件を検出しました。入力内容を修正してください。</value>\n  </data>\n  <data name=\"MultiplePackagesFound\" xml:space=\"preserve\">\n    <value>複数のパッケージが入力条件に一致しました。入力内容を修正してください。</value>\n  </data>\n  <data name=\"NameArgumentDescription\" xml:space=\"preserve\">\n    <value>名前で結果をフィルター処理</value>\n  </data>\n  <data name=\"NoApplicableInstallers\" xml:space=\"preserve\">\n    <value>該当するインストーラーが見つかりません。詳細については、ログを参照してください。</value>\n  </data>\n  <data name=\"NoExperimentalFeaturesMessage\" xml:space=\"preserve\">\n    <value>現在、試験的な機能はありません。</value>\n  </data>\n  <data name=\"NoInstalledPackageFound\" xml:space=\"preserve\">\n    <value>入力条件に一致するインストール済みのパッケージが見つかりませんでした。</value>\n  </data>\n  <data name=\"NoPackageFound\" xml:space=\"preserve\">\n    <value>入力条件に一致するパッケージが見つかりませんでした。</value>\n  </data>\n  <data name=\"NoVTArgumentDescription\" xml:space=\"preserve\">\n    <value>VirtualTerminal 表示を無効にする</value>\n    <comment>{Locked=\"VirtualTerminal\"}</comment>\n  </data>\n  <data name=\"OpenLogsArgumentDescription\" xml:space=\"preserve\">\n    <value>既定のログの場所を開く</value>\n  </data>\n  <data name=\"Options\" xml:space=\"preserve\">\n    <value>オプション</value>\n    <comment>Options to change how a command works</comment>\n  </data>\n  <data name=\"OverrideArgumentDescription\" xml:space=\"preserve\">\n    <value>インストーラーに渡される引数を上書き</value>\n  </data>\n  <data name=\"Package\" xml:space=\"preserve\">\n    <value>パッケージ: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for a software package. {0} is a placeholder replaced by the software package name.</comment>\n  </data>\n  <data name=\"PendingWorkError\" xml:space=\"preserve\">\n    <value>申し訳ございません。これを行うことを忘れました…</value>\n  </data>\n  <data name=\"PositionArgumentDescription\" xml:space=\"preserve\">\n    <value>コマンド ライン内のカーソルの位置</value>\n  </data>\n  <data name=\"PrivacyStatement\" xml:space=\"preserve\">\n    <value>プライバシーに関する声明</value>\n  </data>\n  <data name=\"QueryArgumentDescription\" xml:space=\"preserve\">\n    <value>パッケージの検索に使用されるクエリ</value>\n  </data>\n  <data name=\"RainbowArgumentDescription\" xml:space=\"preserve\">\n    <value>進行状況は虹の色を表示します</value>\n  </data>\n  <data name=\"RequiredArgError\" xml:space=\"preserve\">\n    <value>必須の引数が指定されていません: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user does not provide a required command line argument. {0} is a placeholder replaced by an argument name.</comment>\n  </data>\n  <data name=\"RetroArgumentDescription\" xml:space=\"preserve\">\n    <value>既定の色としての進行状況の表示</value>\n  </data>\n  <data name=\"SearchCommandLongDescription\" xml:space=\"preserve\">\n    <value>構成されたソースからパッケージを検索します。</value>\n  </data>\n  <data name=\"SearchCommandShortDescription\" xml:space=\"preserve\">\n    <value>アプリの基本情報を見つけて表示</value>\n  </data>\n  <data name=\"SearchId\" xml:space=\"preserve\">\n    <value>ID</value>\n    <comment>Abbreviation of Identifier.</comment>\n  </data>\n  <data name=\"SearchMatch\" xml:space=\"preserve\">\n    <value>一致</value>\n  </data>\n  <data name=\"SearchName\" xml:space=\"preserve\">\n    <value>名前</value>\n  </data>\n  <data name=\"SearchSource\" xml:space=\"preserve\">\n    <value>ソース</value>\n  </data>\n  <data name=\"SearchTruncated\" xml:space=\"preserve\">\n    <value>結果制限により、エントリがさらに切り捨てられました</value>\n  </data>\n  <data name=\"SearchVersion\" xml:space=\"preserve\">\n    <value>バージョン</value>\n  </data>\n  <data name=\"SettingLoadFailure\" xml:space=\"preserve\">\n    <value>次のエラーが検出されたため、設定を検証しています:</value>\n  </data>\n  <data name=\"SettingsCommandLongDescription\" xml:space=\"preserve\">\n    <value>既定の json テキスト エディターで設定を開きます。エディターが構成されていない場合は、メモ帳で設定を開きます。使用可能な設定については、https://aka.ms/winget-settings を参照してください。このコマンドを使用して、--enable または --disable 引数を指定して管理者設定を設定することもできます。</value>\n    <comment>{Locked=\"--enable\"} {Locked=\"--disable\"}</comment>\n  </data>\n  <data name=\"SettingsCommandShortDescription\" xml:space=\"preserve\">\n    <value>設定を開くか、管理者設定を設定する</value>\n  </data>\n  <data name=\"SettingsWarnings\" xml:space=\"preserve\">\n    <value>設定の読み込み中に予期しないエラーが発生しました。'settings' コマンドを実行して、設定を確認してください。</value>\n    <comment>{Locked=\"'settings'\"}</comment>\n  </data>\n  <data name=\"ShowChannel\" xml:space=\"preserve\">\n    <value>チャネル</value>\n  </data>\n  <data name=\"ShowCommandLongDescription\" xml:space=\"preserve\">\n    <value>特定のパッケージの情報を表示します。既定では、クエリはパッケージの ID、名前、モニカーに大文字小文字の区別なく一致する必要があります。その他のフィールドは、適切なオプションを渡すことで使用することができます。</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"ShowCommandShortDescription\" xml:space=\"preserve\">\n    <value>パッケージに関する情報を表示します</value>\n  </data>\n  <data name=\"ShowVersion\" xml:space=\"preserve\">\n    <value>バージョン</value>\n  </data>\n  <data name=\"SilentArgumentDescription\" xml:space=\"preserve\">\n    <value>サイレント インストールを要求</value>\n  </data>\n  <data name=\"SingleCharAfterDashError\" xml:space=\"preserve\">\n    <value>単一の - の後に出現できるのは、1 文字の別名のみです: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides more than a single character command line alias argument after an alias argument specifier '-'. {0} is a placeholder replaced by the user's argument input.</comment>\n  </data>\n  <data name=\"SourceAddAlreadyExistsDifferentArg\" xml:space=\"preserve\">\n    <value>指定された名前のソースは既に存在し、別の場所を参照しています:</value>\n  </data>\n  <data name=\"SourceAddAlreadyExistsDifferentName\" xml:space=\"preserve\">\n    <value>別の名前のソースが、既に次の場所を参照しています:</value>\n  </data>\n  <data name=\"SourceAddAlreadyExistsMatch\" xml:space=\"preserve\">\n    <value>指定された名前のソースは既に存在し、同じ場所を参照しています:</value>\n  </data>\n  <data name=\"SourceAddBegin\" xml:space=\"preserve\">\n    <value>ソースを追加しています:</value>\n  </data>\n  <data name=\"SourceAddCommandLongDescription\" xml:space=\"preserve\">\n    <value>新しいソースを追加します。ソースは、パッケージを検出してインストールするためのデータを提供します。安全な場所として信頼できる場合にのみ、新しいソースを追加してください。</value>\n  </data>\n  <data name=\"SourceAddCommandShortDescription\" xml:space=\"preserve\">\n    <value>新しいソースを追加</value>\n  </data>\n  <data name=\"SourceArgArgumentDescription\" xml:space=\"preserve\">\n    <value>ソースに与えられた引数</value>\n  </data>\n  <data name=\"SourceArgumentDescription\" xml:space=\"preserve\">\n    <value>指定されたリソースを使用してパッケージを検索</value>\n  </data>\n  <data name=\"SourceCommandLongDescription\" xml:space=\"preserve\">\n    <value>サブコマンドでソースを管理します。ソースは、パッケージを検出してインストールするためのデータを提供します。安全な場所として信頼できる場合にのみ、新しいソースを追加してください。</value>\n  </data>\n  <data name=\"SourceCommandShortDescription\" xml:space=\"preserve\">\n    <value>パッケージのソースの管理</value>\n  </data>\n  <data name=\"SourceEditCommandLongDescription\" xml:space=\"preserve\">\n    <value>既存のソースのプロパティを編集します。ソースは、パッケージを検出してインストールするためのデータを提供します。</value>\n  </data>\n  <data name=\"SourceEditCommandShortDescription\" xml:space=\"preserve\">\n    <value>ソースのプロパティを編集します</value>\n  </data>\n  <data name=\"SourceEditOne\" xml:space=\"preserve\">\n    <value>ソースの編集中: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being edited. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceEditNoChanges\" xml:space=\"preserve\">\n    <value>'{0}' という名前のソースは既に適切な状態です。</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being edited. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceListArg\" xml:space=\"preserve\">\n    <value>引数</value>\n    <comment>Value given to source.</comment>\n  </data>\n  <data name=\"SourceListCommandLongDescription\" xml:space=\"preserve\">\n    <value>現在のすべてのソース、または特定のソースの完全な詳細を一覧表示します。</value>\n  </data>\n  <data name=\"SourceListCommandShortDescription\" xml:space=\"preserve\">\n    <value>現在のソースを一覧表示</value>\n  </data>\n  <data name=\"SourceListData\" xml:space=\"preserve\">\n    <value>データ</value>\n    <comment>Data stored by the source.</comment>\n  </data>\n  <data name=\"SourceListField\" xml:space=\"preserve\">\n    <value>フィールド</value>\n    <comment>The name of a piece of information about a source.</comment>\n  </data>\n  <data name=\"SourceListName\" xml:space=\"preserve\">\n    <value>名前</value>\n    <comment>The name of the source.</comment>\n  </data>\n  <data name=\"SourceListIdentifier\" xml:space=\"preserve\">\n    <value>ID</value>\n    <comment>The source's unique identifier.</comment>\n  </data>\n  <data name=\"SourceListNoneFound\" xml:space=\"preserve\">\n    <value>次の名前のソースが見つかりませんでした: {0}</value>\n    <comment>Error message displayed when the user provides a repository source name that was not found. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"SourceListNoSources\" xml:space=\"preserve\">\n    <value>構成されたソースがありません。</value>\n  </data>\n  <data name=\"SourceListType\" xml:space=\"preserve\">\n    <value>種類</value>\n    <comment>The kind of source.</comment>\n  </data>\n  <data name=\"SourceListUpdated\" xml:space=\"preserve\">\n    <value>更新されました</value>\n    <comment>The last time the source was updated.</comment>\n  </data>\n  <data name=\"SourceListUpdatedNever\" xml:space=\"preserve\">\n    <value>なし</value>\n    <comment>The source has never been updated.</comment>\n  </data>\n  <data name=\"SourceListValue\" xml:space=\"preserve\">\n    <value>値</value>\n    <comment>The value of information about a source.</comment>\n  </data>\n  <data name=\"SourceNameArgumentDescription\" xml:space=\"preserve\">\n    <value>ソース名</value>\n  </data>\n  <data name=\"SourceOpenFailedSuggestion\" xml:space=\"preserve\">\n    <value>ソースを開くときに失敗しました;問題が解決しない場合は、'source reset' コマンドを試してください。</value>\n    <comment>{Locked=\"source reset\"}</comment>\n  </data>\n  <data name=\"SourceOpenPredefinedFailedSuggestion\" xml:space=\"preserve\">\n    <value>定義済みのソースを開けませんでした; winget メンテナに報告してください。</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"SourceRemoveAll\" xml:space=\"preserve\">\n    <value>すべてのソースを削除しています...</value>\n  </data>\n  <data name=\"SourceRemoveCommandLongDescription\" xml:space=\"preserve\">\n    <value>特定のソースを削除します。</value>\n  </data>\n  <data name=\"SourceRemoveCommandShortDescription\" xml:space=\"preserve\">\n    <value>現在のソースを削除</value>\n  </data>\n  <data name=\"SourceRemoveOne\" xml:space=\"preserve\">\n    <value>ソースを削除しています: {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being removed. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceResetAll\" xml:space=\"preserve\">\n    <value>すべてのソースをリセットしています...</value>\n  </data>\n  <data name=\"SourceResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>このコマンドは既存のソースを削除し、ローカル データを潜在的に残します。引数がないと、すべてのソースが削除され、既定値が追加されます。名前付きソースが提供されている場合、そのソースのみが削除されます。</value>\n  </data>\n  <data name=\"SourceResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>ソースをリセット</value>\n  </data>\n  <data name=\"SourceResetForceArgumentDescription\" xml:space=\"preserve\">\n    <value>ソースのリセットの強制</value>\n  </data>\n  <data name=\"SourceResetListAndOverridePreamble\" xml:space=\"preserve\">\n    <value>--force オプションを指定すると、次のソースがリセットされます:</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"SourceResetOne\" xml:space=\"preserve\">\n    <value>ソースをリセットしています: {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a repository source that is currently being reset. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceTypeArgumentDescription\" xml:space=\"preserve\">\n    <value>ソースのタイプ</value>\n  </data>\n  <data name=\"SourceUpdateAll\" xml:space=\"preserve\">\n    <value>すべてのソースを更新しています...</value>\n  </data>\n  <data name=\"SourceUpdateCommandLongDescription\" xml:space=\"preserve\">\n    <value>すべてのソースを更新するか、特定のソースのみを更新します。</value>\n  </data>\n  <data name=\"SourceUpdateCommandShortDescription\" xml:space=\"preserve\">\n    <value>現在のソースを更新</value>\n  </data>\n  <data name=\"SourceUpdateOne\" xml:space=\"preserve\">\n    <value>ソースを更新しています: {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being updated. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"TagArgumentDescription\" xml:space=\"preserve\">\n    <value>タグで結果をフィルター処理</value>\n  </data>\n  <data name=\"ThankYou\" xml:space=\"preserve\">\n    <value>Winget をお使いいただきありがとうございます</value>\n  </data>\n  <data name=\"ThirdPartSoftwareNotices\" xml:space=\"preserve\">\n    <value>サード パーティに関する通知</value>\n  </data>\n  <data name=\"ToolDescription\" xml:space=\"preserve\">\n    <value>WinGet コマンド ライン ユーティリティを使用すると、コマンド ラインからアプリケーションやその他のパッケージをインストールできます。</value>\n  </data>\n  <data name=\"ToolInfoArgumentDescription\" xml:space=\"preserve\">\n    <value>ツールの一般情報を表示</value>\n  </data>\n  <data name=\"ToolVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>ツールのバージョンを表示</value>\n  </data>\n  <data name=\"TooManyArgError\" xml:space=\"preserve\">\n    <value>引数に指定された回数が許容回数を超えています: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a command line argument more times than it is allowed. {0} is a placeholder replaced by the user's argument name input.</comment>\n  </data>\n  <data name=\"TooManyBehaviorsError\" xml:space=\"preserve\">\n    <value>複数の実行動作引数が指定されました: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides more than one execution behavior argument when installing an application package. {0} is a placeholder replaced by the user specified execution behaviors (e.g. 'silent|interactive').</comment>\n  </data>\n  <data name=\"UnexpectedErrorExecutingCommand\" xml:space=\"preserve\">\n    <value>コマンドの実行中に予期しないエラーが発生しました:</value>\n  </data>\n  <data name=\"UninstallPreviousArgumentDescription\" xml:space=\"preserve\">\n    <value>アップグレード中に以前のバージョンのパッケージをアンインストールする</value>\n  </data>\n  <data name=\"UnrecognizedCommand\" xml:space=\"preserve\">\n    <value>認識されないコマンド: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an unrecognized command. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"UpdateAllArgumentDescription\" xml:space=\"preserve\">\n    <value>可能な場合はインストール済みのすべてのパッケージをアップグレードして最新状態にします</value>\n  </data>\n  <data name=\"UpdateNotApplicable\" xml:space=\"preserve\">\n    <value>適用可能なアップグレードは見つかりませんでした。</value>\n  </data>\n  <data name=\"UpdateNotApplicableReason\" xml:space=\"preserve\">\n    <value>構成されたソースでは新しいパッケージ バージョンを使用できますが、システムまたは要件には適用されません。</value>\n  </data>\n  <data name=\"UpdateNoPackagesFound\" xml:space=\"preserve\">\n    <value>利用可能なアップグレードが見つかりませんでした。</value>\n  </data>\n  <data name=\"UpdateNoPackagesFoundReason\" xml:space=\"preserve\">\n    <value>構成されたソースから入手できる新しいパッケージ バージョンはありません。</value>\n  </data>\n  <data name=\"UpgradeCommandLongDescription\" xml:space=\"preserve\">\n    <value>インストールされたパッケージ リスト、またはマニフェストから直接検索し、選択されたパッケージをアップグレードします。既定では、クエリはパッケージの ID、名前、モニカーに大文字小文字の区別なく一致する必要があります。その他のフィールドは、適切なオプションを渡すことで使用することができます。引数が指定されていない場合は、利用可能なアップグレードを含むパッケージが表示されます</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"UpgradeCommandShortDescription\" xml:space=\"preserve\">\n    <value>利用可能なアップグレードの表示と実行</value>\n  </data>\n  <data name=\"Usage\" xml:space=\"preserve\">\n    <value>使用法: {0} {1}</value>\n    <comment>{Locked=\"{0} {1}\"} Message displayed to provide the user with instructions on how to use a command. {0} is a placeholder replaced by the program name (e.g. 'winget'). {1} is a placeholder replaced by the pattern for using the selected command.</comment>\n  </data>\n  <data name=\"ValidateCommandLongDescription\" xml:space=\"preserve\">\n    <value>厳密なガイドラインのセットを使用してマニフェストを検証します。これは、リポジトリに送信する前にマニフェストを確認できるようにすることを目的としています。</value>\n  </data>\n  <data name=\"ValidateCommandShortDescription\" xml:space=\"preserve\">\n    <value>マニフェスト ファイルを検証</value>\n  </data>\n  <data name=\"ValidateManifestArgumentDescription\" xml:space=\"preserve\">\n    <value>検証対象のマニフェストのパス</value>\n  </data>\n  <data name=\"VerboseLogsArgumentDescription\" xml:space=\"preserve\">\n    <value>WinGet の詳細ログを有効にする</value>\n  </data>\n  <data name=\"VerifyFileSignedMsix\" xml:space=\"preserve\">\n    <value>入力ファイルが有効な署名された MSIX であることを確認してください。</value>\n  </data>\n  <data name=\"VersionArgumentDescription\" xml:space=\"preserve\">\n    <value>指定されたバージョンを使用します。既定値は最新バージョンです</value>\n  </data>\n  <data name=\"VersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>パッケージの利用可能なバージョンを表示</value>\n  </data>\n  <data name=\"WordArgumentDescription\" xml:space=\"preserve\">\n    <value>完了する前に提供された値が要求されます</value>\n  </data>\n  <data name=\"GetManifestResultVersionNotFound\" xml:space=\"preserve\">\n    <value>一致するバージョンが見つかりません: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to upgrade an application package to a version that was not found. {0} is a placeholder replaced by the user's provided upgrade package version.</comment>\n  </data>\n  <data name=\"OpenSourceFailedNoMatch\" xml:space=\"preserve\">\n    <value>指定された値に一致するソースがありません: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to install or upgrade an application package from a repository source that was not found. {0} is a placeholder replaced by the user's repository source name input.</comment>\n  </data>\n  <data name=\"OpenSourceFailedNoMatchHelp\" xml:space=\"preserve\">\n    <value>構成されたソースは次のとおりです:</value>\n  </data>\n  <data name=\"OpenSourceFailedNoSourceDefined\" xml:space=\"preserve\">\n    <value>ソースが定義されていません。[source add]で追加するか、[source reset]で規定値にリセットします</value>\n    <comment>{Locked=\"source add\",\"source reset\"}</comment>\n  </data>\n  <data name=\"ReportIdentityFound\" xml:space=\"preserve\">\n    <value>見つかりました</value>\n  </data>\n  <data name=\"VerifyFileFailedIsDirectory\" xml:space=\"preserve\">\n    <value>パスはディレクトリです: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system path that is a directory. {0} is a placeholder replaced by the provided directory path.</comment>\n  </data>\n  <data name=\"VerifyFileFailedNotExist\" xml:space=\"preserve\">\n    <value>ファイルが存在しません: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system file that does not exist. {0} is a placeholder replaced by the provided file path.</comment>\n  </data>\n  <data name=\"BothManifestAndSearchQueryProvided\" xml:space=\"preserve\">\n    <value>ローカル マニフェストと検索クエリ引数の両方が指定されています</value>\n  </data>\n  <data name=\"Logs\" xml:space=\"preserve\">\n    <value>ログ</value>\n    <comment>Label displayed for diagnostic files containing information about the application use.</comment>\n  </data>\n  <data name=\"InstallerBlockedByPolicy\" xml:space=\"preserve\">\n    <value>インストーラーはポリシーによってブロックされています</value>\n  </data>\n  <data name=\"InstallerFailedSecurityCheck\" xml:space=\"preserve\">\n    <value>インストーラーのセキュリティチェックに失敗しました</value>\n  </data>\n  <data name=\"InstallerFailedVirusScan\" xml:space=\"preserve\">\n    <value>ウイルス対策製品がインストーラーに感染を報告します</value>\n  </data>\n  <data name=\"SourceOpenWithFailedUpdate\" xml:space=\"preserve\">\n    <value>ソースを更新できませんでした: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to update the repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"UninstallCommandLongDescription\" xml:space=\"preserve\">\n    <value>インストールされているパッケージリスト、またはマニフェストから検索し、選択したパッケージをアンインストールします。既定では、クエリはパッケージのID、名前、モニカーと大文字と小文字の区別なく一致する必要があります。その他のフィールドは、適切なオプションを渡すことで使用することができます。</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"UninstallCommandShortDescription\" xml:space=\"preserve\">\n    <value>指定されたパッケージをアンインストール</value>\n  </data>\n  <data name=\"UninstallFlowStartingPackageUninstall\" xml:space=\"preserve\">\n    <value>パッケージのアンインストールを開始しています...</value>\n  </data>\n  <data name=\"UninstallFlowUninstallSuccess\" xml:space=\"preserve\">\n    <value>正常にアンインストールされました</value>\n  </data>\n  <data name=\"NoUninstallInfoFound\" xml:space=\"preserve\">\n    <value>winget は、このパッケージのアンインストールコマンドを見つけることができません。サポートについては、パッケージの発行元に問い合わせてください。</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"UninstallAbandoned\" xml:space=\"preserve\">\n    <value>アンインストールが中止されました</value>\n  </data>\n  <data name=\"UninstallFailedWithCode\" xml:space=\"preserve\">\n    <value>アンインストールは次の終了コードで失敗しました: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to uninstall an application package fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"ExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>インストールされているパッケージのリストをエクスポート</value>\n  </data>\n  <data name=\"ImportCommandLongDescription\" xml:space=\"preserve\">\n    <value>ファイルに一覧表示されているすべてのパッケージをインストールします。</value>\n  </data>\n  <data name=\"ImportCommandShortDescription\" xml:space=\"preserve\">\n    <value>ファイル中のすべてのパッケージをインストール</value>\n  </data>\n  <data name=\"OutputFileArgumentDescription\" xml:space=\"preserve\">\n    <value>結果が書き込まれるファイル</value>\n  </data>\n  <data name=\"ImportFileArgumentDescription\" xml:space=\"preserve\">\n    <value>インストールするパッケージを記述したファイル</value>\n  </data>\n  <data name=\"ExportSourceArgumentDescription\" xml:space=\"preserve\">\n    <value>指定したソースからパッケージをエクスポートする</value>\n  </data>\n  <data name=\"ExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>インストールされているパッケージの一覧をファイルに書き込みます。その後、パッケージを import コマンドを使用してインストールできます。</value>\n    <comment>{Locked=\"import\"}</comment>\n  </data>\n  <data name=\"ImportInstallFailed\" xml:space=\"preserve\">\n    <value>1つまたは複数のインポートされたパッケージをインストールできませんでした</value>\n  </data>\n  <data name=\"ImportSourceNotInstalled\" xml:space=\"preserve\">\n    <value>インポートに必要なソースがインストールされていません: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to import application package(s) from a repository source that is not installed. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"InstalledPackageNotAvailable\" xml:space=\"preserve\">\n    <value>インストールされているパッケージはどのソースからも利用できません: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when the user attempts to export an installed application package that is not available from any repository source. {0} is a placeholder replaced by the installed package name.</comment>\n  </data>\n  <data name=\"InstalledPackageVersionNotAvailable\" xml:space=\"preserve\">\n    <value>インストールされているパッケージのバージョンは、どのソースからも使用できません: {0} {1} {2}</value>\n    <comment>{Locked=\"{0} {1} {2}\"} Warning message displayed when the user attempts to export an installed application package with a version that is not available from any repository source. {0} is a placeholder replaced by the installed package identifier. {1} is a placeholder replaced by the installed package version. {2} is a placeholder replaced by the installed package channel.</comment>\n  </data>\n  <data name=\"NoPackagesInImportFile\" xml:space=\"preserve\">\n    <value>インポート ファイルにパッケージが見つかりません</value>\n  </data>\n  <data name=\"InvalidJsonFile\" xml:space=\"preserve\">\n    <value>JSON ファイルが無効です</value>\n  </data>\n  <data name=\"MultiQueryPackageAlreadyInstalled\" xml:space=\"preserve\">\n    <value>パッケージは既にインストールされています: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user that an application package is already installed. {0} is a placeholder replaced by the package identifier or search query.</comment>\n  </data>\n  <data name=\"ImportIgnoreUnavailableArgumentDescription\" xml:space=\"preserve\">\n    <value>使用できないパッケージを無視する</value>\n  </data>\n  <data name=\"ExportIncludeVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>エクスポート ファイルにパッケージ バージョンを含める</value>\n  </data>\n  <data name=\"ImportIgnoreVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>インポート ファイルからパッケージ バージョンを無視する</value>\n  </data>\n  <data name=\"VerifyPathFailedNotExist\" xml:space=\"preserve\">\n    <value>パスが存在しません: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system path argument value that does not exist. {0} is a placeholder replaced by the user's provided path.</comment>\n  </data>\n  <data name=\"ImportFileHasInvalidSchema\" xml:space=\"preserve\">\n    <value>JSON ファイルでは、認識されるスキーマが指定されていません。</value>\n  </data>\n  <data name=\"InstallScopeDescription\" xml:space=\"preserve\">\n    <value>インストールの範囲 (user または machine) の選択</value>\n    <comment>{Locked=\"user\",\"machine\"} This argument allows the user to select between installing for just the user or for the entire machine.</comment>\n  </data>\n  <data name=\"InvalidArgumentValueError\" xml:space=\"preserve\">\n    <value>'{0}' 引数に指定された値が無効です。有効な値: {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message displayed when the user provides an invalid command line argument value. {0} is a placeholder replaced by the argument name. {1} is a placeholder replaced by a list of valid options.</comment>\n  </data>\n  <data name=\"DisabledByGroupPolicy\" xml:space=\"preserve\">\n    <value>この操作はグループ ポリシーによって無効にされています: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user performs a command operation that is disabled by a group policy. {0} is a placeholder replaced by a group policy description.</comment>\n  </data>\n  <data name=\"PolicyAdditionalSources\" xml:space=\"preserve\">\n    <value>追加の Windows アプリ インストーラー ソースを有効にする</value>\n  </data>\n  <data name=\"PolicyAllowedSources\" xml:space=\"preserve\">\n    <value>Windows アプリ インストーラーの許可されたソースを有効にする</value>\n  </data>\n  <data name=\"PolicyEnableDefaultSource\" xml:space=\"preserve\">\n    <value>Windows アプリ インストーラーの既定のソースを有効にする</value>\n  </data>\n  <data name=\"PolicyEnableExperimentalFeatures\" xml:space=\"preserve\">\n    <value>Windows アプリ インストーラーの試験的な機能を有効にする</value>\n  </data>\n  <data name=\"PolicyEnableMSStoreSource\" xml:space=\"preserve\">\n    <value>Windows アプリインストーラー Microsoft Store ソースを有効にする</value>\n  </data>\n  <data name=\"PolicyEnableFontSource\" xml:space=\"preserve\">\n    <value>Windows App インストーラー フォント ソースを有効にする</value>\n  </data>\n  <data name=\"PolicyEnableWinGetSettings\" xml:space=\"preserve\">\n    <value>Windows パッケージ マネージャーを有効にする</value>\n  </data>\n  <data name=\"PolicyEnableWinGet\" xml:space=\"preserve\">\n    <value>Windows パッケージ マネージャーを有効にする</value>\n  </data>\n  <data name=\"PolicyEnableWindowsPackageManagerCommandLineInterfaces\" xml:space=\"preserve\">\n    <value>Windows パッケージ マネージャーのコマンド ライン インターフェイスを有効にする</value>\n  </data>\n  <data name=\"PolicySourceAutoUpdateInterval\" xml:space=\"preserve\">\n    <value>Windows パッケージ マネージャーのソース自動更新間隔を分単位で設定する</value>\n  </data>\n  <data name=\"PoliciesPolicy\" xml:space=\"preserve\">\n    <value>グループ ポリシー</value>\n    <comment>Header for a table listing active Group Policies</comment>\n  </data>\n  <data name=\"PolicyEnableLocalManifests\" xml:space=\"preserve\">\n    <value>Windows アプリ インストーラーのローカル マニフェスト ファイルを有効にする</value>\n  </data>\n  <data name=\"PolicyEnableBypassCertificatePinningForMicrosoftStore\" xml:space=\"preserve\">\n    <value>Windows アプリ インストーラーでの Microsoft Store ソースの固定証明書のバイパスを有効にする</value>\n  </data>\n  <data name=\"PolicyEnableLocalArchiveMalwareScanOverride\" xml:space=\"preserve\">\n    <value>Windows アプリ インストーラー ローカル アーカイブ マルウェア スキャンの上書きを有効にする</value>\n  </data>\n  <data name=\"SettingsWarningField\" xml:space=\"preserve\">\n    <value>フィールド: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when a user setting field has invalid syntax or semantics. {0} is a placeholder replaced by the setting field path.</comment>\n  </data>\n  <data name=\"SettingsWarningInvalidFieldFormat\" xml:space=\"preserve\">\n    <value>フィールド形式が無効です。</value>\n  </data>\n  <data name=\"SettingsWarningInvalidFieldValue\" xml:space=\"preserve\">\n    <value>無効なフィールド値です。</value>\n  </data>\n  <data name=\"SettingsWarningInvalidValueFromPolicy\" xml:space=\"preserve\">\n    <value>グループ ポリシーの設定が無効です。</value>\n  </data>\n  <data name=\"SettingsWarningLoadedBackupSettings\" xml:space=\"preserve\">\n    <value>バックアップ ファイルから設定を読み込みました。</value>\n  </data>\n  <data name=\"SettingsWarningParseError\" xml:space=\"preserve\">\n    <value>ファイルの解析エラー:</value>\n  </data>\n  <data name=\"SettingsWarningValue\" xml:space=\"preserve\">\n    <value>値: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when a user setting value has invalid syntax or semantics. {0} is a placeholder replaced by the setting data value.</comment>\n  </data>\n  <data name=\"FeaturesMessageDisabledByPolicy\" xml:space=\"preserve\">\n    <value>次の試験的な機能が進行中です。\nグループポリシーにより、構成が無効になっています。</value>\n  </data>\n  <data name=\"InstallerHashMismatchError\" xml:space=\"preserve\">\n    <value>インストーラーのハッシュが一致しません。</value>\n  </data>\n  <data name=\"PolicyEnableHashOverride\" xml:space=\"preserve\">\n    <value>Windows アプリ インストーラーのハッシュ上書きを有効にする</value>\n  </data>\n  <data name=\"SourceExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>グループポリシーの JSON として現在のソースをエクスポートします。</value>\n  </data>\n  <data name=\"SourceExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>現在のソースをエクスポートする</value>\n  </data>\n  <data name=\"SourceListAdditionalSource\" xml:space=\"preserve\">\n    <value>追加のソース</value>\n    <comment>An additional source required by policy.</comment>\n  </data>\n  <data name=\"SourceListAllowedSource\" xml:space=\"preserve\">\n    <value>許可されたソース</value>\n    <comment>A source that the user is allowed to add.</comment>\n  </data>\n  <data name=\"InvalidArgumentValueErrorWithoutValidValues\" xml:space=\"preserve\">\n    <value>'{0}' 引数に指定された値が無効です</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an invalid command line argument value. {0} is a placeholder replaced by the argument name.</comment>\n  </data>\n  <data name=\"Cancelled\" xml:space=\"preserve\">\n    <value>取り消し済み</value>\n  </data>\n  <data name=\"ExternalDependencies\" xml:space=\"preserve\">\n    <value>外部</value>\n  </data>\n  <data name=\"ImportCommandReportDependencies\" xml:space=\"preserve\">\n    <value>このインポートで見つかったパッケージには、次の依存関係があります:</value>\n    <comment>Import command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"PackageRequiresDependencies\" xml:space=\"preserve\">\n    <value>このパッケージには次の依存関係が必要です:</value>\n    <comment>Message shown before reporting dependencies</comment>\n  </data>\n  <data name=\"DependenciesFlowInstall\" xml:space=\"preserve\">\n    <value>依存関係をインストールしています</value>\n  </data>\n  <data name=\"DependenciesFlowSourceNotFound\" xml:space=\"preserve\">\n    <value>依存ソースが見つかりません</value>\n  </data>\n  <data name=\"DependenciesFlowSourceTooManyMatches\" xml:space=\"preserve\">\n    <value>パッケージ検索では、複数の結果が生成されます: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when application packages search yield more than one result. {0} is a placeholder replaced by the dependency package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowPackageVersionNotFound\" xml:space=\"preserve\">\n    <value>パッケージの最新バージョンが見つかりません: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when no suitable version found for the specific application package. {0} is a placeholder replaced by the package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoInstallerFound\" xml:space=\"preserve\">\n    <value>インストーラーが見つかりません: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when no installer found for a manifest. {0} is a placeholder replaced by the manifest identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoMinVersion\" xml:space=\"preserve\">\n    <value>パッケージに必要な最小バージョンは使用できません: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the minimum required version is not available for an application package. {0} is a placeholder replaced by the package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoMatches\" xml:space=\"preserve\">\n    <value>一致する項目はありません</value>\n    <comment>When package search yields no matches</comment>\n  </data>\n  <data name=\"DependenciesFlowContainsLoop\" xml:space=\"preserve\">\n    <value>ループを含む</value>\n    <comment>Dependency graph has loop</comment>\n  </data>\n  <data name=\"DependenciesFlowNoSuitableInstallerFound\" xml:space=\"preserve\">\n    <value>マニフェストに適したインストーラーが見つかりません: {0} バージョン {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message displayed when an attempt to get a preferred installer for a manifest fails. {0} is a placeholder replaced by the manifest identifier. {1} is a placeholder replaced by the manifest version.</comment>\n  </data>\n  <data name=\"DependenciesManagementError\" xml:space=\"preserve\">\n    <value>パッケージ依存関係の処理中にエラーが発生しました。インストールを続行しますか?</value>\n    <comment>Prompt message shown when dependencies processing yields errors.</comment>\n  </data>\n  <data name=\"DependenciesManagementExitMessage\" xml:space=\"preserve\">\n    <value>パッケージ依存関係の処理中にエラーが発生しました。終了しています...</value>\n  </data>\n  <data name=\"PackageDependencies\" xml:space=\"preserve\">\n    <value>パッケージ</value>\n  </data>\n  <data name=\"UninstallCommandReportDependencies\" xml:space=\"preserve\">\n    <value>このパッケージには、不要になる可能性のある依存関係があります:</value>\n    <comment>Uninstall command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"ValidateCommandReportDependencies\" xml:space=\"preserve\">\n    <value>マニフェストには、検証されていない次の依存関係があります。有効であることを確認してください:</value>\n    <comment>Validate command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"WindowsFeaturesDependencies\" xml:space=\"preserve\">\n    <value>Windows の機能</value>\n  </data>\n  <data name=\"WindowsLibrariesDependencies\" xml:space=\"preserve\">\n    <value>Windows ライブラリ</value>\n  </data>\n  <data name=\"DependencySourceArgumentDescription\" xml:space=\"preserve\">\n    <value>指定されたリソースを使用してパッケージの依存関係を検索</value>\n    <comment>For getting package type dependencies when installing from a local manifest</comment>\n  </data>\n  <data name=\"WindowsStoreTerms\" xml:space=\"preserve\">\n    <value>Windows ストアの使用条件</value>\n  </data>\n  <data name=\"AcceptPackageAgreementsArgumentDescription\" xml:space=\"preserve\">\n    <value>パッケージのすべての使用許諾契約に同意する</value>\n  </data>\n  <data name=\"ExportedPackageRequiresLicenseAgreement\" xml:space=\"preserve\">\n    <value>エクスポートされたパッケージをインストールするには、使用許諾契約書が必要です: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when an exported application package requires license agreement to install. {0} is a placeholder replaced by the package name.</comment>\n  </data>\n  <data name=\"PackageAgreementsPrompt\" xml:space=\"preserve\">\n    <value>発行元は、お客様がインストール前に上記の情報を表示し、契約に同意することを必要としています。\n使用条件に同意しますか?</value>\n  </data>\n  <data name=\"PackageAgreementsNotAgreedTo\" xml:space=\"preserve\">\n    <value>パッケージ契約に同意しませんでした。操作が取り消されました。</value>\n  </data>\n  <data name=\"ShowLabelAgreements\" xml:space=\"preserve\">\n    <value>契約:</value>\n  </data>\n  <data name=\"ShowLabelAuthor\" xml:space=\"preserve\">\n    <value>作成者:</value>\n  </data>\n  <data name=\"ShowLabelDescription\" xml:space=\"preserve\">\n    <value>説明:</value>\n  </data>\n  <data name=\"ShowLabelInstaller\" xml:space=\"preserve\">\n    <value>インストーラー:</value>\n  </data>\n  <data name=\"ShowLabelInstallerLocale\" xml:space=\"preserve\">\n    <value>インストーラーのロケール:</value>\n  </data>\n  <data name=\"ShowLabelInstallerProductId\" xml:space=\"preserve\">\n    <value>ストア製品 ID:</value>\n  </data>\n  <data name=\"ShowLabelInstallerSha256\" xml:space=\"preserve\">\n    <value>インストーラーの SHA256:</value>\n  </data>\n  <data name=\"ShowLabelInstallerType\" xml:space=\"preserve\">\n    <value>インストーラーの種類:</value>\n  </data>\n  <data name=\"ShowLabelInstallerUrl\" xml:space=\"preserve\">\n    <value>インストーラーの URL:</value>\n  </data>\n  <data name=\"ShowLabelLicense\" xml:space=\"preserve\">\n    <value>ライセンス:</value>\n  </data>\n  <data name=\"ShowLabelLicenseUrl\" xml:space=\"preserve\">\n    <value>ライセンス URL:</value>\n  </data>\n  <data name=\"ShowLabelMoniker\" xml:space=\"preserve\">\n    <value>モニカー:</value>\n  </data>\n  <data name=\"ShowLabelPackageUrl\" xml:space=\"preserve\">\n    <value>ホーム ページ:</value>\n  </data>\n  <data name=\"ShowLabelPublisher\" xml:space=\"preserve\">\n    <value>公開元:</value>\n  </data>\n  <data name=\"ShowLabelTags\" xml:space=\"preserve\">\n    <value>タグ:</value>\n  </data>\n  <data name=\"ShowLabelVersion\" xml:space=\"preserve\">\n    <value>バージョン:</value>\n  </data>\n  <data name=\"ShowLabelDependencies\" xml:space=\"preserve\">\n    <value>依存関係:</value>\n  </data>\n  <data name=\"ShowLabelWindowsFeaturesDependencies\" xml:space=\"preserve\">\n    <value>Windows の機能:</value>\n  </data>\n  <data name=\"ShowLabelWindowsLibrariesDependencies\" xml:space=\"preserve\">\n    <value>Windows ライブラリ:</value>\n  </data>\n  <data name=\"ShowLabelPackageDependencies\" xml:space=\"preserve\">\n    <value>パッケージの依存関係:</value>\n  </data>\n  <data name=\"ShowLabelExternalDependencies\" xml:space=\"preserve\">\n    <value>外部依存関係:</value>\n  </data>\n  <data name=\"PromptOptionNo\" xml:space=\"preserve\">\n    <value>いいえ</value>\n  </data>\n  <data name=\"PromptOptionYes\" xml:space=\"preserve\">\n    <value>はい</value>\n  </data>\n  <data name=\"SourceAddOpenSourceFailed\" xml:space=\"preserve\">\n    <value>追加されたソースを開けませんでした。</value>\n  </data>\n  <data name=\"AcceptSourceAgreementsArgumentDescription\" xml:space=\"preserve\">\n    <value>ソース操作中にすべてのソース契約に同意する</value>\n  </data>\n  <data name=\"SourceAgreementsTitle\" xml:space=\"preserve\">\n    <value>'{0}' ソースでは、使用する前に次の契約を表示する必要があります。</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user that a repository source requires viewing agreements before using. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceAgreementsPrompt\" xml:space=\"preserve\">\n    <value>すべてのソース契約条件に同意しますか?</value>\n  </data>\n  <data name=\"SourceAgreementsNotAgreedTo\" xml:space=\"preserve\">\n    <value>1 つ以上のソース契約が同意されませんでした。操作が取り消されました。ソース契約に同意するか、対応するソースを削除してください。</value>\n  </data>\n  <data name=\"SourceAgreementsMarketMessage\" xml:space=\"preserve\">\n    <value>ソースが正常に機能するには、現在のマシンの 2 文字の地理的リージョンをバックエンド サービスに送信する必要があります (例: \"US\")。</value>\n  </data>\n  <data name=\"InstallFlowRegistrationDeferred\" xml:space=\"preserve\">\n    <value>正常にインストールされました。アップグレードを完了するには、アプリケーションを再起動してください。</value>\n  </data>\n  <data name=\"HeaderArgumentDescription\" xml:space=\"preserve\">\n    <value>オプションの Windows-Package-Manager REST ソース HTTP ヘッダー</value>\n  </data>\n  <data name=\"HeaderArgumentNotApplicableForNonRestSourceWarning\" xml:space=\"preserve\">\n    <value>省略可能なヘッダーは、このソースには適用できないため無視されます。</value>\n  </data>\n  <data name=\"HeaderArgumentNotApplicableWithoutSource\" xml:space=\"preserve\">\n    <value>省略可能なヘッダーは、ソースを指定しないと適用されません: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user performs an operation (e.g install) and provides the HTTP 'header' argument without specifying the repository source. {0} is a placeholder replaced by the header argument name.</comment>\n  </data>\n  <data name=\"ShowLabelInstallerReleaseDate\" xml:space=\"preserve\">\n    <value>リリース日:</value>\n  </data>\n  <data name=\"ShowLabelInstallerOfflineDistributionSupported\" xml:space=\"preserve\">\n    <value>オフライン配信をサポート:</value>\n  </data>\n  <data name=\"ShowLabelPublisherUrl\" xml:space=\"preserve\">\n    <value>発行元 URL:</value>\n  </data>\n  <data name=\"ShowLabelPurchaseUrl\" xml:space=\"preserve\">\n    <value>購入 URL:</value>\n  </data>\n  <data name=\"ShowLabelPublisherSupportUrl\" xml:space=\"preserve\">\n    <value>発行元のサポート URL:</value>\n  </data>\n  <data name=\"ShowLabelPrivacyUrl\" xml:space=\"preserve\">\n    <value>プライバシー URL:</value>\n  </data>\n  <data name=\"ShowLabelCopyright\" xml:space=\"preserve\">\n    <value>著作権:</value>\n  </data>\n  <data name=\"ShowLabelCopyrightUrl\" xml:space=\"preserve\">\n    <value>著作権 URL:</value>\n  </data>\n  <data name=\"ShowLabelReleaseNotes\" xml:space=\"preserve\">\n    <value>リリース ノート:</value>\n  </data>\n  <data name=\"ShowLabelReleaseNotesUrl\" xml:space=\"preserve\">\n    <value>リリース ノート URL:</value>\n  </data>\n  <data name=\"SearchFailureWarning\" xml:space=\"preserve\">\n    <value>ソースの検索中にエラーが発生しました;結果は含まれません: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when searching a repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SearchFailureError\" xml:space=\"preserve\">\n    <value>ソースの検索中に失敗しました: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when searching a repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"FeatureDisabledByAdminSettingMessage\" xml:space=\"preserve\">\n    <value>この機能は管理者が有効にする必要があります。有効にするには、'winget settings --enable {0}' を管理者として実行します。</value>\n    <comment>{Locked=\"winget settings --enable\", \"{0}\"}. Error message displayed when the user uses a feature that needs to be enabled by administrators. {0} is a placeholder replaced by the admin setting.</comment>\n  </data>\n  <data name=\"AdminSettingEnableDescription\" xml:space=\"preserve\">\n    <value>特定の管理者設定を有効にします</value>\n  </data>\n  <data name=\"AdminSettingDisableDescription\" xml:space=\"preserve\">\n    <value>特定の管理者設定を無効にします</value>\n  </data>\n  <data name=\"AdminSettingEnabled\" xml:space=\"preserve\">\n    <value>管理者設定 '{0}' を有効にしました。</value>\n    <comment>{Locked=\"{0}\"} Message displayed when the user enables an admin setting. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"AdminSettingDisabled\" xml:space=\"preserve\">\n    <value>管理者設定 '{0}' を無効にしました。</value>\n    <comment>{Locked=\"{0}\"} Message displayed when the user disables an admin setting. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"AdminSettingHeader\" xml:space=\"preserve\">\n    <value>管理者設定</value>\n    <comment>Header for a table displaying admin settings.</comment>\n  </data>\n  <data name=\"InstallFlowReturnCodePackageInUse\" xml:space=\"preserve\">\n    <value>アプリケーションは現在実行中です。アプリケーションを終了してから、もう一度お試しください。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodePackageInUseByApplication\" xml:space=\"preserve\">\n    <value>インストーラーによって変更されたファイルは、現在別のアプリケーションで使用されています。アプリケーションを終了してから、もう一度お試しください。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInstallInProgress\" xml:space=\"preserve\">\n    <value>別のインストールが既に進行中です。後でもう一度お試しください。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeFileInUse\" xml:space=\"preserve\">\n    <value>1 つ以上のファイルが使用されています。アプリケーションを終了してから、もう一度お試しください。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeMissingDependency\" xml:space=\"preserve\">\n    <value>このパッケージには、システムに依存関係がありません。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeDiskFull\" xml:space=\"preserve\">\n    <value>PC にこれ以上空き領域がありません。空き領域を確保してから、もう一度やり直してください。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInsufficientMemory\" xml:space=\"preserve\">\n    <value>インストールできるメモリが不足しています。他のアプリケーションを閉じてから、もう一度やり直してください。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInvalidParameter\" xml:space=\"preserve\">\n    <value>インストール パラメーターの 1 つが無効です。パッケージのインストール ログに追加の詳細が含まれている可能性があります。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeNoNetwork\" xml:space=\"preserve\">\n    <value>このアプリケーションにはインターネット接続が必要です。ネットワークに接続してから、もう一度お試しください。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeContactSupport\" xml:space=\"preserve\">\n    <value>このアプリケーションのインストール中にエラーが発生しました。サポートにお問い合わせください。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootRequiredToFinish\" xml:space=\"preserve\">\n    <value>PC を再起動してインストールを完了します。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootRequiredForInstall\" xml:space=\"preserve\">\n    <value>PC が再起動してインストールが完了します。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootInitiated\" xml:space=\"preserve\">\n    <value>インストールに失敗しました。PC を再起動してから、もう一度お試しください。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeCancelledByUser\" xml:space=\"preserve\">\n    <value>ユーザーがインストールを取り消しました。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeAlreadyInstalled\" xml:space=\"preserve\">\n    <value>このアプリケーションの別のバージョンが既にインストールされています。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeDowngrade\" xml:space=\"preserve\">\n    <value>このアプリケーションの上位バージョンは既にインストールされています。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeBlockedByPolicy\" xml:space=\"preserve\">\n    <value>組織のポリシーが原因でインストールできません。管理者にお問い合わせください。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeSystemNotSupported\" xml:space=\"preserve\">\n    <value>現在のシステム構成では、このパッケージのインストールはサポートされていません。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeCustomError\" xml:space=\"preserve\">\n    <value>カスタム インストーラー エラーにより、インストールに失敗しました。パッケージ サポートにお問い合わせください。</value>\n  </data>\n  <data name=\"InstallAbandoned\" xml:space=\"preserve\">\n    <value>インストールが破棄されました</value>\n  </data>\n  <data name=\"InstallerFailedWithCode\" xml:space=\"preserve\">\n    <value>インストーラーが終了コードで失敗しました: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the application installer fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"InstallerLogAvailable\" xml:space=\"preserve\">\n    <value>インストーラー ログは次で入手できます: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about the system path of a diagnostic files containing information about the installer. {0} is a placeholder replaced by the diagnostic file system path.</comment>\n  </data>\n  <data name=\"SearchFailureErrorListMatches\" xml:space=\"preserve\">\n    <value>作業ソースの中以下のパッケージが見つかりました。\n続行するには、'--source' オプションを使用していずれかのパッケージを指定してください。</value>\n    <comment>{Locked=\"--source\"} \"working sources\" as in \"sources that are working correctly\"</comment>\n  </data>\n  <data name=\"SearchFailureErrorNoMatches\" xml:space=\"preserve\">\n    <value>作業ソースの中にパッケージが見つかりませんでした。</value>\n    <comment>\"working sources\" as in \"sources that are working correctly\"</comment>\n  </data>\n  <data name=\"FeaturesMessageDisabledByBuild\" xml:space=\"preserve\">\n    <value>これは、Windows パッケージ マネージャーの安定版リリースです。実験的な機能を試したい場合は、プレリリース ビルドをインストールしてください。手順は、GitHub (https://github.com/microsoft/winget-cli) で入手できます。</value>\n    <comment>{Locked=\"https://github.com/microsoft/winget-cli\"}</comment>\n  </data>\n  <data name=\"WindowsPackageManager\" xml:space=\"preserve\">\n    <value>v{0} の Windows パッケージ マネージャー</value>\n    <comment>{Locked=\"{0}\"} Label displaying the product name and version. {0} is a placeholder replaced by the product version.</comment>\n  </data>\n  <data name=\"ImportIgnorePackageVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>インポート ファイルのパッケージ バージョンを無視する</value>\n  </data>\n  <data name=\"CountOutOfBoundsError\" xml:space=\"preserve\">\n    <value>要求された結果の数は 1 から 1000 の間である必要があります。</value>\n  </data>\n  <data name=\"CustomSwitchesArgumentDescription\" xml:space=\"preserve\">\n    <value>既定値に加えてインストーラーに渡される引数</value>\n  </data>\n  <data name=\"UpgradeDifferentInstallTechnologyInNewerVersions\" xml:space=\"preserve\">\n    <value>新しいバージョンが見つかりましたが、インストールテクノロジが現在インストールされているバージョンと異なります。パッケージをアンインストールして、新しいバージョンをインストールしてください。</value>\n  </data>\n  <data name=\"UpgradeDifferentInstallTechnology\" xml:space=\"preserve\">\n    <value>指定された新しいバージョンのインストール テクノロジが、現在インストールされているバージョンと異なります。パッケージをアンインストールして、新しいバージョンをインストールしてください。</value>\n  </data>\n  <data name=\"WindowsPackageManagerPreview\" xml:space=\"preserve\">\n    <value>Windows パッケージ マネージャー (プレビュー) v{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying the preview product name and pre-release version. {0} is a placeholder replaced by the product version.</comment>\n  </data>\n  <data name=\"ArchitectureArgumentDescription\" xml:space=\"preserve\">\n    <value>アーキテクチャを選択する</value>\n  </data>\n  <data name=\"IncludeUnknownArgumentDescription\" xml:space=\"preserve\">\n    <value>現在のバージョンを特定できない場合でもパッケージをアップグレードする</value>\n  </data>\n  <data name=\"IncludeUnknownInListArgumentDescription\" xml:space=\"preserve\">\n    <value>現在のバージョンを特定できない場合でもパッケージを一覧表示します。--upgrade-available 引数でのみ使用できます</value>\n    <comment>{Locked=\"--upgrade-available\"}</comment>\n  </data>\n  <data name=\"UpgradeUnknownVersionExplanation\" xml:space=\"preserve\">\n    <value>このパッケージのバージョン番号を特定できません。とにかくアップグレードするには、前のコマンドに引数 --include-unknown を追加します。</value>\n    <comment>{Locked=\"--include-unknown\"}</comment>\n  </data>\n  <data name=\"UpgradeUnknownVersionCount\" xml:space=\"preserve\">\n    <value>{0} 個のパッケージのバージョン番号を判別できません。すべての結果を表示するには、--include-unknown を使用してください。</value>\n    <comment>{Locked=\"{0}\",\"--include-unknown\"} {0} is a placeholder that is replaced by an integer number of packages that do not have notated versions. </comment>\n  </data>\n  <data name=\"UpgradeRequireExplicitCount\" xml:space=\"preserve\">\n    <value>{0} パッケージがピン留めされているため、明示的にアップグレードする必要があります。</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by an integer number of packages that require explicit upgrades.</comment>\n  </data>\n  <data name=\"InvalidArgumentWithoutQueryError\" xml:space=\"preserve\">\n    <value>指定された引数はクエリでのみ使用できます。</value>\n  </data>\n  <data name=\"SystemArchitecture\" xml:space=\"preserve\">\n    <value>システム アーキテクチャ: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for the system architecture. {0} is a placeholder replaced by the value of the system architecture (e.g. X64).</comment>\n  </data>\n  <data name=\"PreserveArgumentDescription\" xml:space=\"preserve\">\n    <value>パッケージ (ポータブル) によって作成されたすべてのファイルとディレクトリを保持します</value>\n  </data>\n  <data name=\"PurgeArgumentDescription\" xml:space=\"preserve\">\n    <value>パッケージ ディレクトリ (ポータブル) 内のすべてのファイルとディレクトリを削除します</value>\n  </data>\n  <data name=\"PressEnterToContinue\" xml:space=\"preserve\">\n    <value>続行するには、Enter キーを押してください . . .</value>\n  </data>\n  <data name=\"RenameArgumentDescription\" xml:space=\"preserve\">\n    <value>実行可能ファイルの名前を変更する値 (ポータブル)</value>\n  </data>\n  <data name=\"WaitArgumentDescription\" xml:space=\"preserve\">\n    <value>終了する前に任意のキーを押すプロンプトをユーザーに表示します</value>\n  </data>\n  <data name=\"InstallerElevationExpected\" xml:space=\"preserve\">\n    <value>インストーラーは管理者として実行するように要求します。プロンプトが表示されます。</value>\n  </data>\n  <data name=\"InstallerProhibitsElevation\" xml:space=\"preserve\">\n    <value>管理者コンテキストからインストーラーを実行することはできません。</value>\n  </data>\n  <data name=\"ModifiedPathRequiresShellRestart\" xml:space=\"preserve\">\n    <value>パス環境変数が変更されました; 新しい値を使用するにはシェルを再起動してください。</value>\n  </data>\n  <data name=\"ProductCodeArgumentDescription\" xml:space=\"preserve\">\n    <value>製品コードを使用したフィルター</value>\n  </data>\n  <data name=\"PortableRegistryCollisionOverridden\" xml:space=\"preserve\">\n    <value>同じ名前で、別のソースからのポータブル パッケージが既に存在します; --force が原因で続行しています</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"ReparsePointsNotSupportedError\" xml:space=\"preserve\">\n    <value>ボリュームは再パース ポイントをサポートしていません</value>\n  </data>\n  <data name=\"ReservedFilenameError\" xml:space=\"preserve\">\n    <value>指定されたファイル名は有効なファイル名ではありません</value>\n  </data>\n  <data name=\"OverwritingExistingFileAtMessage\" xml:space=\"preserve\">\n    <value>既存のファイルを上書きしています: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed to inform the user that an existing file is being overwritten. {0} is a placeholder replaced by the file system path.</comment>\n  </data>\n  <data name=\"NoPackageSelectionArgumentProvided\" xml:space=\"preserve\">\n    <value>パッケージ選択引数が指定されていません; パッケージの検索の詳細については、ヘルプを参照してください。</value>\n  </data>\n  <data name=\"PortableAliasAdded\" xml:space=\"preserve\">\n    <value>コマンド ライン エイリアスが追加されました:</value>\n  </data>\n  <data name=\"PortableLinksMachine\" xml:space=\"preserve\">\n    <value>ポータブル リンク ディレクトリ (マシン)</value>\n  </data>\n  <data name=\"PortableLinksUser\" xml:space=\"preserve\">\n    <value>ポータブル リンク ディレクトリ (ユーザー)</value>\n  </data>\n  <data name=\"PortableRootUser\" xml:space=\"preserve\">\n    <value>ポータブル パッケージ ルート (ユーザー)</value>\n  </data>\n  <data name=\"PortableRoot\" xml:space=\"preserve\">\n    <value>ポータブル パッケージ ルート</value>\n  </data>\n  <data name=\"PortableRoot86\" xml:space=\"preserve\">\n    <value>ポータブル パッケージ ルート (x86)</value>\n  </data>\n  <data name=\"PortableInstallFailed\" xml:space=\"preserve\">\n    <value>ポータブル インストールに失敗しました; クリーンアップしています...</value>\n  </data>\n  <data name=\"PortableHashMismatchOverridden\" xml:space=\"preserve\">\n    <value>移植可能パッケージは変更されています。--force が指定されているため続行しています</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"PortableHashMismatchOverrideRequired\" xml:space=\"preserve\">\n    <value>移植可能パッケージは、変更されているため削除できません。このチェックをオーバーライドするには、--force を指定します</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"FilesRemainInInstallDirectory\" xml:space=\"preserve\">\n    <value>ファイルはインストール ディレクトリに残ります: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when files remain in install directory. {0} is a placeholder replaced by the directory path.</comment>\n  </data>\n  <data name=\"PurgeInstallDirectory\" xml:space=\"preserve\">\n    <value>インストール ディレクトリを破棄しています...</value>\n  </data>\n  <data name=\"UnableToPurgeInstallDirectory\" xml:space=\"preserve\">\n    <value>WinGet によって作成されていないため、インストール ディレクトリを破棄することができません</value>\n  </data>\n  <data name=\"RelatedLink\" xml:space=\"preserve\">\n    <value>関連リンク</value>\n  </data>\n  <data name=\"ShowLabelDocumentation\" xml:space=\"preserve\">\n    <value>Documentation:</value>\n  </data>\n  <data name=\"Notes\" xml:space=\"preserve\">\n    <value>メモ: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for installation notes. {0} is a placeholder replaced by installation notes.</comment>\n  </data>\n  <data name=\"ShowLabelInstallationNotes\" xml:space=\"preserve\">\n    <value>インストールに関する注意:</value>\n  </data>\n  <data name=\"UnsupportedArgument\" xml:space=\"preserve\">\n    <value>指定された引数はこのパッケージ用にはサポートされていません</value>\n  </data>\n  <data name=\"ExtractArchiveFailed\" xml:space=\"preserve\">\n    <value>アーカイブの内容を抽出できませんでした</value>\n  </data>\n  <data name=\"NestedInstallerNotFound\" xml:space=\"preserve\">\n    <value>入れ子になったインストーラー ファイルが存在しません。入れ子になったインストーラーの指定された相対パスが一致することを確認します: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when nested installer file does not exist. {0} is a placeholder replaced by the nested installer file path.</comment>\n  </data>\n  <data name=\"InvalidPathToNestedInstaller\" xml:space=\"preserve\">\n    <value>入れ子状態インストーラーへの相対ファイル パスが正しくありません。パスでインストール ディレクトリ以外の場所が示されています</value>\n  </data>\n  <data name=\"NestedInstallerNotSpecified\" xml:space=\"preserve\">\n    <value>このパッケージ用には入れ子状態インストーラーは指定されていません</value>\n  </data>\n  <data name=\"MultipleUnsupportedNestedInstallersSpecified\" xml:space=\"preserve\">\n    <value>移植可能なインストーラーまたはフォントで入れ子になったインストーラーでない限り、アーカイブ インストーラーに指定できる入れ子になったインストーラーは 1 つだけです</value>\n  </data>\n  <data name=\"IncompatibleArgumentsProvided\" xml:space=\"preserve\">\n    <value>互換性のないコマンド ライン引数が指定されました</value>\n  </data>\n  <data name=\"UpgradeArgumentDescription\" xml:space=\"preserve\">\n    <value>アップグレードが利用可能なパッケージのみを一覧表示します</value>\n  </data>\n  <data name=\"UpgradeAvailableForPinned\" xml:space=\"preserve\">\n    <value>次のパッケージにはアップグレードを適用可能ですが、アップグレードには明示的対象化が必要です:</value>\n    <comment>\"require explicit targeting for upgrade\" means that the package will not be upgraded with all others unless an extra flag is added, or the package is mentioned explicitly</comment>\n  </data>\n  <data name=\"Downloading\" xml:space=\"preserve\">\n    <value>ダウンロード中</value>\n    <comment>Label displayed while downloading an application installer.</comment>\n  </data>\n  <data name=\"NestedInstallerNotSupported\" xml:space=\"preserve\">\n    <value>入れ子状態インストーラーの種類には対応していません</value>\n  </data>\n  <data name=\"InstallerAbortsTerminal\" xml:space=\"preserve\">\n    <value>このインストーラーではターミナルまたはシェルが再起動されることがわかっています</value>\n  </data>\n  <data name=\"InstallerRequiresInstallLocation\" xml:space=\"preserve\">\n    <value>このパッケージにはインストール先の場所が必要です</value>\n  </data>\n  <data name=\"InstallersAbortTerminal\" xml:space=\"preserve\">\n    <value>次のインストーラーではターミナルまたはシェルが再起動されることがわかっています</value>\n  </data>\n  <data name=\"InstallersRequireInstallLocation\" xml:space=\"preserve\">\n    <value>次のインストーラーにはインストール先の場所が必要です:</value>\n  </data>\n  <data name=\"PromptForInstallRoot\" xml:space=\"preserve\">\n    <value>インストール ルートを指定してください:</value>\n  </data>\n  <data name=\"PromptToProceed\" xml:space=\"preserve\">\n    <value>続行しますか?</value>\n  </data>\n  <data name=\"ReportIdentityForAgreements\" xml:space=\"preserve\">\n    <value>契約の対象</value>\n    <comment>This will be followed by a package name, and then a list of license agreements</comment>\n  </data>\n  <data name=\"InstallLocationNotProvided\" xml:space=\"preserve\">\n    <value>パッケージにはインストール場所が必要ですが、指定されていませんでした</value>\n  </data>\n  <data name=\"DisableInteractivityArgumentDescription\" xml:space=\"preserve\">\n    <value>対話型プロンプトを無効にします</value>\n    <comment>Description for a command line argument, shown next to it in the help</comment>\n  </data>\n  <data name=\"ConvertInstallFlowToUpgrade\" xml:space=\"preserve\">\n    <value>既存のパッケージが既にインストールされています。インストールされているパッケージ...をアップグレードしようとしています</value>\n  </data>\n  <data name=\"ForceArgumentDescription\" xml:space=\"preserve\">\n    <value>コマンドを直接実行し、セキュリティ関連でない問題の場合に続行します</value>\n    <comment>Description for a command line argument, shown next to it in the help</comment>\n  </data>\n  <data name=\"PortablePackageAlreadyExists\" xml:space=\"preserve\">\n    <value>別のソースからの移植可能パッケージが既に存在します</value>\n  </data>\n  <data name=\"ExtractArchiveSucceeded\" xml:space=\"preserve\">\n    <value>アーカイブが正常に展開されました</value>\n  </data>\n  <data name=\"ExtractingArchive\" xml:space=\"preserve\">\n    <value>アーカイブを展開しています...</value>\n  </data>\n  <data name=\"ArchiveFailedMalwareScan\" xml:space=\"preserve\">\n    <value>アーカイブ スキャンでマルウェアが検出されました。このチェックをオーバーライドするには、--ignore-local-archive-malware-scan を使用します</value>\n    <comment>{Locked=\"--ignore-local-archive-malware-scan\"}</comment>\n  </data>\n  <data name=\"ArchiveFailedMalwareScanOverridden\" xml:space=\"preserve\">\n    <value>アーカイブ スキャンでマルウェアが検出されました。--ignore-local-archive-malware-scan により続行しています</value>\n    <comment>{Locked=\"--ignore-local-archive-malware-scan\"}</comment>\n  </data>\n  <data name=\"NoUpgradeArgumentDescription\" xml:space=\"preserve\">\n    <value>インストール済みバージョンが既に存在する場合はアップグレードをスキップします</value>\n  </data>\n  <data name=\"PackageAlreadyInstalled\" xml:space=\"preserve\">\n    <value>パッケージ バージョンは既にインストールされています。インストールが取り消されました。</value>\n  </data>\n  <data name=\"EnableAdminSettingFailed\" xml:space=\"preserve\">\n    <value>{0}を有効にできません。この設定はポリシーによって制御されます。詳細については、システム管理者に問い合わせてください。</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"DisableAdminSettingFailed\" xml:space=\"preserve\">\n    <value>{0}を無効にできません。この設定はポリシーによって制御されます。詳細については、システム管理者に問い合わせてください。</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"PinAddCommandLongDescription\" xml:space=\"preserve\">\n    <value>新しいピンを追加します。ピン留めをすると、Windows パッケージ マネージャーがパッケージを特定のバージョンの範囲にアップグレードするのを制限したり、パッケージを完全にアップグレードできなくなる可能性があります。ピン留めされたパッケージは、それ自体でアップグレードされ、Windows パッケージ マネージャー外からアップグレードされる可能性があります。既定では、ピン留めされたパッケージをアップグレードするには、'upgrade' コマンドで明示的に指定するか、'--include-pinned' フラグを 'winget upgrade --all' に追加します。</value>\n    <comment>{Locked{\"'upgrade'\"} Locked{\"--include-pinned\"} Locked{\"winget upgrade --all\"}</comment>\n  </data>\n  <data name=\"PinAddCommandShortDescription\" xml:space=\"preserve\">\n    <value>新しい PIN を追加する</value>\n  </data>\n  <data name=\"PinCommandLongDescription\" xml:space=\"preserve\">\n    <value>サブコマンドを使用してパッケージのピンを管理します。ピン留めすると、Windows パッケージ マネージャーがパッケージを特定のバージョンの範囲にアップグレードするのを制限したり、パッケージを完全にアップグレードできなくなる可能性があります。ピン留めされたパッケージは、それ自体でアップグレードされ、Windows パッケージ マネージャー外からアップグレードされる可能性があります。</value>\n  </data>\n  <data name=\"PinCommandShortDescription\" xml:space=\"preserve\">\n    <value>パッケージ ピンの管理</value>\n  </data>\n  <data name=\"PinListCommandLongDescription\" xml:space=\"preserve\">\n    <value>現在のすべてのピン、または特定のピンの完全な詳細を一覧表示します。</value>\n  </data>\n  <data name=\"PinListCommandShortDescription\" xml:space=\"preserve\">\n    <value>現在のピンを一覧表示する</value>\n  </data>\n  <data name=\"PinRemoveCommandLongDescription\" xml:space=\"preserve\">\n    <value>特定のパッケージ ピンを削除します。</value>\n  </data>\n  <data name=\"PinRemoveCommandShortDescription\" xml:space=\"preserve\">\n    <value>パッケージ ピンの削除</value>\n  </data>\n  <data name=\"PinResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>既存のすべてのピンをリセットします。</value>\n  </data>\n  <data name=\"PinResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>PIN をリセット</value>\n  </data>\n  <data name=\"GatedVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>パッケージをピン留めするバージョン。ワイルドカード '*' を最後のバージョン部分として使用できます</value>\n  </data>\n  <data name=\"PinAddBlockingArgumentDescription\" xml:space=\"preserve\">\n    <value>ピンが削除されるまで更新をブロックし、引数をオーバーライドできないようにします</value>\n  </data>\n  <data name=\"PinInstalledArgumentDescription\" xml:space=\"preserve\">\n    <value>インストールされている特定のバージョンをピン留めする</value>\n  </data>\n  <data name=\"PinInstalledSource\" xml:space=\"preserve\">\n    <value>インストール済み</value>\n    <comment>Value used in a table to indicate that a package comes from the list of packages installed in the machine</comment>\n  </data>\n  <data name=\"SettingsExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>設定を JSON としてエクスポート</value>\n  </data>\n  <data name=\"SettingsExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>設定のエクスポート</value>\n  </data>\n  <data name=\"UserSettings\" xml:space=\"preserve\">\n    <value>ユーザー設定</value>\n    <comment>Label displayed for the file containing the user settings.</comment>\n  </data>\n  <data name=\"SettingsWarningUsingDefault\" xml:space=\"preserve\">\n    <value>設定ファイルを読み込めませんでした。既定値を使用しています。</value>\n  </data>\n  <data name=\"InstalledScopeArgumentDescription\" xml:space=\"preserve\">\n    <value>インストールされているパッケージ スコープ フィルター (user または machine) の選択</value>\n    <comment>{Locked=\"user\",\"machine\"} This argument allows the user to select installed packages for just the user or for the entire machine.</comment>\n  </data>\n  <data name=\"PinAdded\" xml:space=\"preserve\">\n    <value>ピンが正常に追加されました</value>\n  </data>\n  <data name=\"PinAlreadyExists\" xml:space=\"preserve\">\n    <value>パッケージ {0}の PIN は既に存在します</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that will be replaced by a package name. The message is shown when attempting to add a pin for a package that is already pinned.</comment>\n  </data>\n  <data name=\"PinExistsOverwriting\" xml:space=\"preserve\">\n    <value>パッケージ {0}の PIN は既に存在します。--force引数が原因で上書きしています。</value>\n    <comment>{Locked=\"--force\"}{Locked=\"--force\",\"{0}\"} {0} is a placeholder that will be replaced by a package name.</comment>\n  </data>\n  <data name=\"PinExistsUseForceArg\" xml:space=\"preserve\">\n    <value>パッケージ {0}の PIN は既に存在します。--force引数を使用して上書きします。</value>\n    <comment>{Locked=\"--force\",\"{0}\"} {0} is a placeholder that will be replaced by a package name.</comment>\n  </data>\n  <data name=\"PinResettingAll\" xml:space=\"preserve\">\n    <value>現在のすべてのピンをリセットしています。</value>\n  </data>\n  <data name=\"PinResetUseForceArg\" xml:space=\"preserve\">\n    <value>--force 引数を使用して、すべてのピンをリセットします。次のピンが削除されます:</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"PinType\" xml:space=\"preserve\">\n    <value>ピンの種類</value>\n  </data>\n  <data name=\"PinDoesNotExist\" xml:space=\"preserve\">\n    <value>パッケージ {0} にピンがありません</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that will be replaced by a package name. The message is shown when attempting to delete a pin for a package that is not pinned.</comment>\n  </data>\n  <data name=\"PinNoPinsExist\" xml:space=\"preserve\">\n    <value>ピンが構成されていません。</value>\n    <comment>Shown when listing or modifying existing pins if there are none.</comment>\n  </data>\n  <data name=\"PinResetSuccessful\" xml:space=\"preserve\">\n    <value>ピンが正常にリセットされました</value>\n    <comment>Shown after resetting (deleting) all the pins</comment>\n  </data>\n  <data name=\"PinCannotOpenIndex\" xml:space=\"preserve\">\n    <value>ピン データベースを開けません。</value>\n    <comment>Error message for when we cannot open the database containing package pins.</comment>\n  </data>\n  <data name=\"ArgumentForSinglePackageProvidedWithMultipleQueries\" xml:space=\"preserve\">\n    <value>1 つのパッケージにのみ使用できる引数が指定されました</value>\n  </data>\n  <data name=\"MultipleExclusiveArgumentsProvided\" xml:space=\"preserve\">\n    <value>複数の相互排他的引数が指定されました: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message shown when mutually incompatible command line arguments are used. {0} is a placeholder replaced by the arguments that cannot be specified together</comment>\n  </data>\n  <data name=\"DependencyArgumentMissing\" xml:space=\"preserve\">\n    <value>引数 {0} は {1} でのみ使用できます</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message shown when having an argument needs another to be present, but that is missing. {0} and {1} are replaced by the arguments. For example \"Argument --include-unknown can only be used with --upgrade\"</comment>\n  </data>\n  <data name=\"StateDisabled\" xml:space=\"preserve\">\n    <value>無効</value>\n    <comment>As in enabled/disabled</comment>\n  </data>\n  <data name=\"StateEnabled\" xml:space=\"preserve\">\n    <value>有効</value>\n    <comment>As in enabled/disabled</comment>\n  </data>\n  <data name=\"StateHeader\" xml:space=\"preserve\">\n    <value>状態</value>\n    <comment>Header for a table listing the state (enabled/disabled) of Group Policies and Settings</comment>\n  </data>\n  <data name=\"MultiQueryArgumentDescription\" xml:space=\"preserve\">\n    <value>パッケージの検索に使用されるクエリ</value>\n  </data>\n  <data name=\"MultiQueryPackageNotFound\" xml:space=\"preserve\">\n    <value>パッケージが見つかりません: {0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches returns no results. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"MultiQuerySearchFoundMultiple\" xml:space=\"preserve\">\n    <value>複数のパッケージが見つかりました: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches returns more than one result. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"MultiQuerySearchFailed\" xml:space=\"preserve\">\n    <value>検索に失敗しました: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches fails. This message is for generic failures, we have more specific messages for when the search returns no results, or when it returns more than one result. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"UpgradeBlockedByPinCount\" xml:space=\"preserve\">\n    <value>{0} 個のパッケージには、アップグレードする前に削除する必要があるピンがあります</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by an integer number of packages with pins that prevent upgrade</comment>\n  </data>\n  <data name=\"UpgradeBlockedByManifest\" xml:space=\"preserve\">\n    <value>winget を使用してパッケージをアップグレードすることはできません。このパッケージをアップグレードするには、発行元から提供された方法を使用してください。</value>\n  </data>\n  <data name=\"IncludePinnedArgumentDescription\" xml:space=\"preserve\">\n    <value>ブロックでないピンを持っている場合でもパッケージをアップグレードする</value>\n  </data>\n  <data name=\"IncludePinnedInListArgumentDescription\" xml:space=\"preserve\">\n    <value>アップグレードを妨げるピンがある場合でもパッケージを一覧表示します。--upgrade-available 引数でのみ使用できます</value>\n    <comment>{Locked=\"--upgrade-available\"}</comment>\n  </data>\n  <data name=\"PinRemovedSuccessfully\" xml:space=\"preserve\">\n    <value>ピンが正常に削除されました</value>\n  </data>\n  <data name=\"UpgradeIsPinned\" xml:space=\"preserve\">\n    <value>新しいバージョンが見つかりましたが、パッケージにアップグレードを止めるピンが含まれています。</value>\n  </data>\n  <data name=\"PackageIsPinned\" xml:space=\"preserve\">\n    <value>パッケージはピン留めされているため、アップグレードできません。ピンを表示および編集するには、'winget pin' コマンドを使用します。一部のピンの種類は、--include-pinned 引数を使用してバイパスできます。</value>\n    <comment>{Locked=\"winget pin\",\"--include-pinned\"} Error shown when we block an upgrade due to the package being pinned</comment>\n  </data>\n  <data name=\"UpgradePinnedByUserCount\" xml:space=\"preserve\">\n    <value>{0} 個のパッケージには、アップグレードを止めるピンがあります。'winget pin' コマンドを使用してピンを表示および編集します。--include-pinned 引数を使用すると、より多くの結果が表示される場合があります。</value>\n    <comment>{Locked=\"winget pin\",\"--include-pinned\"} {0} is a placeholder replaced by an integer number of packages</comment>\n  </data>\n  <data name=\"ConfigureCommandLongDescription\" xml:space=\"preserve\">\n    <value>指定された構成で説明されているように、システムが適切な状態と一致することを確認します。適切な状態を達成するために、プロセッサをダウンロードまたは実行してください。構成とプロセッサを実行する前に、それらが信頼できることを確認する必要があります。</value>\n  </data>\n  <data name=\"ConfigureCommandShortDescription\" xml:space=\"preserve\">\n    <value>システムを適切な状態に構成します</value>\n  </data>\n  <data name=\"ConfigureShowCommandLongDescription\" xml:space=\"preserve\">\n    <value>指定された構成の詳細を表示します。既定では、システムは変更されませんが、一部のオプションによってファイルがダウンロードまたは読み込まれます。</value>\n  </data>\n  <data name=\"ConfigureShowCommandShortDescription\" xml:space=\"preserve\">\n    <value>構成の詳細を表示します</value>\n  </data>\n  <data name=\"ConfigureTestCommandLongDescription\" xml:space=\"preserve\">\n    <value>指定された構成で説明されているように、システムが適切な状態と一致することを確認します。適切な状態をテストするために、プロセッサをダウンロードまたは実行してください。構成とプロセッサを実行する前に、それらが信頼できることを確認する必要があります。</value>\n  </data>\n  <data name=\"ConfigureTestCommandShortDescription\" xml:space=\"preserve\">\n    <value>システムを適切な状態と照合します</value>\n  </data>\n  <data name=\"ConfigureValidateCommandLongDescription\" xml:space=\"preserve\">\n    <value>構成ファイルの正確性を検証します。</value>\n  </data>\n  <data name=\"ConfigureValidateCommandShortDescription\" xml:space=\"preserve\">\n    <value>構成ファイルを検証します</value>\n  </data>\n  <data name=\"ConfigurationFieldInvalidType\" xml:space=\"preserve\">\n    <value>構成ファイル'{0}'フィールドの種類が正しくありません。</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the field name from the file.</comment>\n  </data>\n  <data name=\"ConfigurationFileArgumentDescription\" xml:space=\"preserve\">\n    <value>構成ファイルへのパス</value>\n  </data>\n  <data name=\"ConfigurationFileInvalid\" xml:space=\"preserve\">\n    <value>構成ファイルが無効です。</value>\n  </data>\n  <data name=\"ConfigurationFileVersionUnknown\" xml:space=\"preserve\">\n    <value>構成ファイル バージョン {0} は不明です。</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the version of the configuration file.</comment>\n  </data>\n  <data name=\"ConfigurationAcceptWarningArgumentDescription\" xml:space=\"preserve\">\n    <value>構成の警告を受け入れ、対話型プロンプトを表示できないようにします</value>\n  </data>\n  <data name=\"ConfigurationApply\" xml:space=\"preserve\">\n    <value>適用</value>\n    <comment>Indicates that this item is used to write state</comment>\n  </data>\n  <data name=\"ConfigurationAssert\" xml:space=\"preserve\">\n    <value>アサート</value>\n    <comment>Indicates that this item is used to check/assert the state rather than write to it</comment>\n  </data>\n  <data name=\"ConfigurationDependencies\" xml:space=\"preserve\">\n    <value>依存関係:{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying a list of dependencies. {0} is replaced with a space separated list of identifiers referencing other items.</comment>\n  </data>\n  <data name=\"ConfigurationFailedToApply\" xml:space=\"preserve\">\n    <value>一部の構成が正常に適用されませんでした。</value>\n  </data>\n  <data name=\"ConfigurationFailedToGetDetails\" xml:space=\"preserve\">\n    <value>構成に関する詳細情報を取得できませんでした。</value>\n  </data>\n  <data name=\"ConfigurationInform\" xml:space=\"preserve\">\n    <value>情報</value>\n    <comment>Indicates that this item is used to retrieve values for future use rather than writing them</comment>\n  </data>\n  <data name=\"ConfigurationLocal\" xml:space=\"preserve\">\n    <value>ローカル</value>\n    <comment>Used to indicate that the item is present on the device.</comment>\n  </data>\n  <data name=\"ConfigurationModuleNameOnly\" xml:space=\"preserve\">\n    <value>モジュール: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying a module name. {0} is replaced with the name of the module from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationModuleWithDetails\" xml:space=\"preserve\">\n    <value>モジュール: {1} [{2}] による {0}</value>\n    <comment>{Locked=\"{0}\",\"{1}\",\"{2}\"} Label displaying module information. {0} is replaced by the module name. {1} is replaced by the module author. {2} is replaced by a string indicating the source of the module.</comment>\n  </data>\n  <data name=\"ConfigurationSettings\" xml:space=\"preserve\">\n    <value>設定:</value>\n    <comment>Label for the values that are used as inputs for this item when applying state</comment>\n  </data>\n  <data name=\"ConfigurationSuccessfullyApplied\" xml:space=\"preserve\">\n    <value>構成が正常に適用されました。</value>\n  </data>\n  <data name=\"ConfigurationUnitSuccessfullyApplied\" xml:space=\"preserve\">\n    <value>ユニットが正常に適用されました。</value>\n  </data>\n  <data name=\"ConfigurationWaitingOnAnother\" xml:space=\"preserve\">\n    <value>別の構成がシステムに適用されています。この構成は可能な限り早く続行...</value>\n  </data>\n  <data name=\"ConfigurationWarning\" xml:space=\"preserve\">\n    <value>実行を選択した構成設定について理解する責任はお客様にあります。お客様が作成またはインポートした構成ファイルについて、Microsoft は責任を負いません。この構成により、Windows の設定の変更、ソフトウェアのインストール、ソフトウェアの設定の変更 (セキュリティ設定を含む) が行われることや、サードパーティのパッケージとサービスに対するユーザー同意事項についてお客様の代理としての承諾が行われることがあります。この構成ファイルを実行することは、これらのリソースと設定を理解して同意したことの確認となります。インストールされるアプリケーションがある場合、それぞれの所有者からライセンスが付与されます。サードパーティのパッケージまたはサービスについて Microsoft は責任を負わず、ライセンスを付与することもありません。</value>\n    <comment>Legal approved. Do not change without approval.</comment>\n  </data>\n  <data name=\"ConfigurationWarningPromptApply\" xml:space=\"preserve\">\n    <value>構成を確認してから、システムへの適用を続行しますか?</value>\n    <comment>PM approved.</comment>\n  </data>\n  <data name=\"ConfigurationFileEmpty\" xml:space=\"preserve\">\n    <value>構成が空です。</value>\n  </data>\n  <data name=\"WindowsFeatureNotFound\" xml:space=\"preserve\">\n    <value>機能 [{0}] が見つかりませんでした。</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Windows feature was not found on the system.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeatureOverrideRequired\" xml:space=\"preserve\">\n    <value>Windows 機能の依存関係を有効にできませんでした。インストールを続行するには、'--force'を使用します。</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"RebootRequiredToEnableWindowsFeatureOverrideRequired\" xml:space=\"preserve\">\n    <value>Windows 機能を完全に有効にするには再起動が必要です。このチェックをオーバーライドするには、'--force' を使用してください。</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeatureOverridden\" xml:space=\"preserve\">\n    <value>Windows 機能の依存関係を有効にできませんでした;--forceが原因で続行しています</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.\n{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"EnablingWindowsFeature\" xml:space=\"preserve\">\n    <value>[{0}] を有効にしています...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to the user regarding which Windows Feature is being enabled.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeature\" xml:space=\"preserve\">\n    <value>[{0}] 機能を有効にできませんでした: {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"}  An error when enabling a Windows Feature. {0} is a placeholder for the name of the Windows Feature.\n{1} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"RebootRequiredToEnableWindowsFeatureOverridden\" xml:space=\"preserve\">\n    <value>Windows 機能を完全に有効にするには再起動が必要です。--force が原因で続行しています</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.</comment>\n  </data>\n  <data name=\"InstallWaitingOnAnother\" xml:space=\"preserve\">\n    <value>別のインストール/アンインストールが完了するのを待機しています...</value>\n  </data>\n  <data name=\"PinVersion\" xml:space=\"preserve\">\n    <value>ピン留めされたバージョン</value>\n    <comment>Table header for the version to which a package is pinned; meaning it should not update from that version.</comment>\n  </data>\n  <data name=\"ConfigurationDescriptionWasTruncated\" xml:space=\"preserve\">\n    <value>&lt;追加の詳細については、ログ ファイルを参照&gt;</value>\n    <comment>The brackets are intended to make the value stand out from other text which it will follow. Any locale appropriate mechanism that achieves this is acceptable.</comment>\n  </data>\n  <data name=\"ConfigurationGettingDetails\" xml:space=\"preserve\">\n    <value>構成の詳細を取得しています</value>\n  </data>\n  <data name=\"ConfigurationInitializing\" xml:space=\"preserve\">\n    <value>構成システムを初期化しています</value>\n  </data>\n  <data name=\"ConfigurationReadingConfigFile\" xml:space=\"preserve\">\n    <value>構成ファイルを読み取っています</value>\n  </data>\n  <data name=\"ConfigurationUnitAssertHadNegativeResult\" xml:space=\"preserve\">\n    <value>このシステムは、構成によってアサートされた適切な状態ではありません。</value>\n  </data>\n  <data name=\"ConfigurationUnitFailed\" xml:space=\"preserve\">\n    <value>この構成単位は不明な理由で失敗しました: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedConfigSet\" xml:space=\"preserve\">\n    <value>構成が原因で構成単位が失敗しました: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringGet\" xml:space=\"preserve\">\n    <value>現在のシステム状態の取得中に構成単位が失敗しました。</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringSet\" xml:space=\"preserve\">\n    <value>必要な状態の適用中に構成単位が失敗しました。</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringTest\" xml:space=\"preserve\">\n    <value>現在のシステム状態のテスト中に構成単位が失敗しました。</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedInternal\" xml:space=\"preserve\">\n    <value>内部エラーのため、構成単位が失敗しました: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedPrecondition\" xml:space=\"preserve\">\n    <value>必須条件が無効なため、構成単位が失敗しました: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedSystemState\" xml:space=\"preserve\">\n    <value>システムの状態が原因で構成単位が失敗しました: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedUnitProcessing\" xml:space=\"preserve\">\n    <value>構成単位の実行中にエラーが発生しました: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitHasDuplicateIdentifier\" xml:space=\"preserve\">\n    <value>構成に識別子 '{0}' が複数回含まれています。</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by the identifier string from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationUnitHasMissingDependency\" xml:space=\"preserve\">\n    <value>依存関係 '{0}' が構成内に見つかりませんでした。</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by the identifier string from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationUnitManuallySkipped\" xml:space=\"preserve\">\n    <value>この構成単位は手動でスキップされました。</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleConflict\" xml:space=\"preserve\">\n    <value>構成単位のモジュールは、同じバージョンの複数の場所で使用できます。</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleImportFailed\" xml:space=\"preserve\">\n    <value>構成単位のモジュールを読み込めませんでした。</value>\n  </data>\n  <data name=\"ConfigurationUnitMultipleMatches\" xml:space=\"preserve\">\n    <value>構成単位に一致する項目が複数見つかりました。モジュールを指定して、正しいモジュールを選択してください。</value>\n  </data>\n  <data name=\"ConfigurationUnitNotFound\" xml:space=\"preserve\">\n    <value>構成単位が見つかりませんでした。</value>\n  </data>\n  <data name=\"ConfigurationUnitNotFoundInModule\" xml:space=\"preserve\">\n    <value>構成単位がモジュール内に正しく含まれていませんでした。</value>\n  </data>\n  <data name=\"ConfigurationUnitNotRunDueToDependency\" xml:space=\"preserve\">\n    <value>依存関係が失敗したか、実行されなかったため、この構成単位は実行されませんでした。</value>\n  </data>\n  <data name=\"ConfigurationUnitNotRunDueToFailedAssert\" xml:space=\"preserve\">\n    <value>アサートが失敗したか false であったため、この構成単位は実行されませんでした。</value>\n  </data>\n  <data name=\"ConfigurationUnitReturnedInvalidResult\" xml:space=\"preserve\">\n    <value>構成単位が実行中に予期しない結果を返しました。</value>\n  </data>\n  <data name=\"ConfigurationUnitSkipped\" xml:space=\"preserve\">\n    <value>この構成単位は不明な理由で実行されませんでした: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationFieldInvalidValue\" xml:space=\"preserve\">\n    <value>フィールド '{0}'に無効な値が含まれています: {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} An error in reading a configuration file. {0} is a placeholder replaced by the field name from the file. {1} is a placeholder for the invalid value.</comment>\n  </data>\n  <data name=\"ConfigurationFieldMissing\" xml:space=\"preserve\">\n    <value>フィールド '{0}' が見つからないか、空です。</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the expected field name from the file.</comment>\n  </data>\n  <data name=\"SeeLineAndColumn\" xml:space=\"preserve\">\n    <value>ファイル内の行{0}、列{1}を参照してください。</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Indicates the file location of the error, {0} and {1} are placeholders for numbers of the line and column, respectively.</comment>\n  </data>\n  <data name=\"CancellingOperation\" xml:space=\"preserve\">\n    <value>操作を取り消しています</value>\n  </data>\n  <data name=\"InstallStubPackageDescription\" xml:space=\"preserve\">\n    <value>AppInstaller のスタブ パッケージをインストールする</value>\n  </data>\n  <data name=\"InstallFullPackageDescription\" xml:space=\"preserve\">\n    <value>AppInstaller のフル パッケージをインストールする</value>\n  </data>\n  <data name=\"ExtendedFeaturesEnableMessage\" xml:space=\"preserve\">\n    <value>拡張機能を有効にします。ストアへのアクセスが必要です。</value>\n  </data>\n  <data name=\"ExtendedFeaturesEnableArgumentError\" xml:space=\"preserve\">\n    <value>オプション '--enable' と '--disable' は他の引数で使用することはできません。</value>\n    <comment>{Locked=\"--enable\", \"--disable\"}</comment>\n  </data>\n  <data name=\"ExtendedFeaturesEnablingMessage\" xml:space=\"preserve\">\n    <value>拡張機能を有効にしています。ストアへのアクセスが必要です。</value>\n  </data>\n  <data name=\"ExtendedFeaturesNotEnabledMessage\" xml:space=\"preserve\">\n    <value>拡張機能が有効になっていません。'winget configure --enable' を実行して有効にします。</value>\n    <comment>{Locked=\"winget configure --enable\"}</comment>\n  </data>\n  <data name=\"ExtendedFeaturesEnabledMessage\" xml:space=\"preserve\">\n    <value>拡張機能が有効になっています。</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisableMessage\" xml:space=\"preserve\">\n    <value>拡張機能を無効にします。ストアへのアクセスが必要です。</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisablingMessage\" xml:space=\"preserve\">\n    <value>拡張機能を無効にしています。ストアへのアクセスが必要です。</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisabledMessage\" xml:space=\"preserve\">\n    <value>拡張機能は無効になっています。</value>\n  </data>\n  <data name=\"SkipDependenciesArgumentDescription\" xml:space=\"preserve\">\n    <value>パッケージの依存関係と Windows 機能の処理をスキップする</value>\n  </data>\n  <data name=\"DependenciesSkippedMessage\" xml:space=\"preserve\">\n    <value>依存関係がスキップされました。</value>\n  </data>\n  <data name=\"FailedToRefreshPathWarning\" xml:space=\"preserve\">\n    <value>プロセスの PATH 変数を更新できませんでした。PATH 変数への変更に依存する後続のインストールは失敗する可能性があります。</value>\n    <comment>{Locked=\"PATH\"}</comment>\n  </data>\n  <data name=\"ConfigurationFailedToTest\" xml:space=\"preserve\">\n    <value>状態のテスト中に一部の構成ユニットが失敗しました。</value>\n  </data>\n  <data name=\"ConfigurationInDesiredState\" xml:space=\"preserve\">\n    <value>システムは記述された構成状態です。</value>\n  </data>\n  <data name=\"ConfigurationNoTestRun\" xml:space=\"preserve\">\n    <value>構成の状態がテストされませんでした。</value>\n  </data>\n  <data name=\"ConfigurationNotInDesiredState\" xml:space=\"preserve\">\n    <value>システムは、記述された構成状態ではありません。</value>\n  </data>\n  <data name=\"ConfigurationUnexpectedTestResult\" xml:space=\"preserve\">\n    <value>予期しないテスト結果: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message. {0} will be replaced with the unexpected value (a number).</comment>\n  </data>\n  <data name=\"ConfigurationWarningPromptTest\" xml:space=\"preserve\">\n    <value>構成を確認してから、システムに対する検証を続行しますか?</value>\n  </data>\n  <data name=\"ConfigurationFileInvalidYAML\" xml:space=\"preserve\">\n    <value>構成ファイルが有効な YAML ファイルではありません。</value>\n    <comment>{Locked=\"YAML\"} YAML is a file format name.</comment>\n  </data>\n  <data name=\"ConfigurationUnitIsPartOfDependencyCycle\" xml:space=\"preserve\">\n    <value>この構成ユニットは依存関係サイクルの一部です。</value>\n  </data>\n  <data name=\"ConfigurationValidationFoundNoIssues\" xml:space=\"preserve\">\n    <value>検証で問題は見つかりませんでした。</value>\n  </data>\n  <data name=\"ConfigurationUnitNeedsPrereleaseWarning\" xml:space=\"preserve\">\n    <value>構成ユニットはプレリリースとしてのみ使用できますが、構成内でそのようにマークされていません。'allowPrerelease: true' を 'directives' に追加してください。</value>\n    <comment>{Locked=\"allowPrerelease: true\",\"directives\"} These are values in the configuration file that are not localized.</comment>\n  </data>\n  <data name=\"ConfigurationUnitNotInCatalogWarning\" xml:space=\"preserve\">\n    <value>構成単位がローカルで見つかりましたが、構成されたカタログに見つかりませんでした。構成を適用する前に、それがシステムに存在することを確認してください。</value>\n  </data>\n  <data name=\"ConfigurationUnitNotPublicWarning\" xml:space=\"preserve\">\n    <value>構成ユニットはパブリックに使用できません。この構成を使用するすべてのユーザーがアクセスできることを確認してください。</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleNotProvidedWarning\" xml:space=\"preserve\">\n    <value>モジュールが指定されませんでした。モジュールを指定すると、パフォーマンスが向上し、今後の名前の競合が回避されます。</value>\n  </data>\n  <data name=\"DownloadCommandLongDescription\" xml:space=\"preserve\">\n    <value>構成されたソースを探して見つけるかマニフェストから直接見つけて、選んだパッケージからインストーラをダウンロードします。既定では、そのクエリはパッケージの id、name、または moniker と大文字小文字の区別なく一致する必要があります。その他のフィールドは、適切なオプションを渡すと使えます。既定では、download コマンドによってユーザーのダウンロード フォルダーに該当するインストーラがダウンロードされます。</value>\n  </data>\n  <data name=\"DownloadCommandShortDescription\" xml:space=\"preserve\">\n    <value>指定されたパッケージからインストーラをダウンロードする</value>\n  </data>\n  <data name=\"DownloadDirectoryArgumentDescription\" xml:space=\"preserve\">\n    <value>インストーラのダウンロード先ディレクトリ</value>\n  </data>\n  <data name=\"DependenciesFlowDownload\" xml:space=\"preserve\">\n    <value>依存関係をダウンロードしています:</value>\n  </data>\n  <data name=\"InstallerDownloaded\" xml:space=\"preserve\">\n    <value>インストーラがダウンロードされました: {0}</value>\n    <comment>{Locked=\"{0}\"} Full path of the downloaded installer.</comment>\n  </data>\n  <data name=\"InstallerTypeArgumentDescription\" xml:space=\"preserve\">\n    <value>インストーラ タイプを選択する</value>\n  </data>\n  <data name=\"InstallerDownloads\" xml:space=\"preserve\">\n    <value>インストーラのダウンロード</value>\n  </data>\n  <data name=\"InstallerDownloadCommandProhibited\" xml:space=\"preserve\">\n    <value>インストーラは、後でオフラインでインストールするためにダウンロードすることはできません。 </value>\n  </data>\n  <data name=\"ConfigurationAllUsersElevated\" xml:space=\"preserve\">\n    <value>`--module-path allusers` を実行するには管理者特権が必要です。</value>\n    <comment>{Locked=\"--module-path allusers\"}</comment>\n  </data>\n  <data name=\"ConfigurationModulePath\" xml:space=\"preserve\">\n    <value>モジュールを格納するローカル コンピューター上の場所を指定します。既定の %LOCALAPPDATA%\\Microsoft\\WinGet\\Configuration\\Modules</value>\n    <comment>{Locked=\"%LOCALAPPDATA%\\Microsoft\\WinGet\\Configuration\\Modules\"}</comment>\n  </data>\n  <data name=\"ConfigurationModulePathArgError\" xml:space=\"preserve\">\n    <value>`--module-path` 値は、`currentuser`、`allusers`、`default`、または絶対パスである必要があります。</value>\n    <comment>{Locked=\"{--module-path}, {currentuser}, {allusers}, {default}}</comment>\n  </data>\n  <data name=\"PolicyEnableWinGetConfiguration\" xml:space=\"preserve\">\n    <value>Windows パッケージ マネージャーの構成を有効にする</value>\n  </data>\n  <data name=\"ErrorCommandLongDescription\" xml:space=\"preserve\">\n    <value>エラーに関する情報を取得します。指定された数値は、winget 固有のエラーの場合のシンボル名を含む、エラーに関する詳細を出力に含めます。文字列を指定すると、winget 固有のエラーがこの値で検索されます。</value>\n  </data>\n  <data name=\"ErrorCommandShortDescription\" xml:space=\"preserve\">\n    <value>エラーに関する情報を取得する</value>\n  </data>\n  <data name=\"ErrorInputArgumentDescription\" xml:space=\"preserve\">\n    <value>エラー情報内で検索する値</value>\n  </data>\n  <data name=\"ErrorNumberIsTooLarge\" xml:space=\"preserve\">\n    <value>指定された数値が大きすぎて HRESULT にできません。</value>\n  </data>\n  <data name=\"UnknownErrorCode\" xml:space=\"preserve\">\n    <value>不明なエラー コード</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INTERNAL_ERROR\" xml:space=\"preserve\">\n    <value>内部エラー</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS\" xml:space=\"preserve\">\n    <value>コマンド ラインの引数が無効です</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMMAND_FAILED\" xml:space=\"preserve\">\n    <value>コマンドの実行に失敗しました</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_FAILED\" xml:space=\"preserve\">\n    <value>マニフェストを開けませんでした</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CTRL_SIGNAL_RECEIVED\" xml:space=\"preserve\">\n    <value>取り消しシグナルを受信しました</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SHELLEXEC_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>ShellExecute の実行に失敗しました</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_MANIFESTVERSION\" xml:space=\"preserve\">\n    <value>マニフェストを処理できません。マニフェストのバージョンがサポートされているバージョンを超えています。クライアントを更新してください。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_FAILED\" xml:space=\"preserve\">\n    <value>インストーラーのダウンロードに失敗しました</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX\" xml:space=\"preserve\">\n    <value>インデックスに書き込めません;上位のスキーマ バージョンです</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INDEX_INTEGRITY_COMPROMISED\" xml:space=\"preserve\">\n    <value>インデックスが壊れています</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCES_INVALID\" xml:space=\"preserve\">\n    <value>構成されたソース情報が壊れています</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NAME_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>ソース名は既に構成されています</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_SOURCE_TYPE\" xml:space=\"preserve\">\n    <value>ソースの種類が無効です</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_BUNDLE\" xml:space=\"preserve\">\n    <value>MSIX ファイルがパッケージではなくバンドルです</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_DATA_MISSING\" xml:space=\"preserve\">\n    <value>ソースに必要なデータがありません</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER\" xml:space=\"preserve\">\n    <value>現在のシステムに適用できるインストーラーはありません</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_HASH_MISMATCH\" xml:space=\"preserve\">\n    <value>インストーラー ファイルのハッシュがマニフェストと一致しません</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NAME_DOES_NOT_EXIST\" xml:space=\"preserve\">\n    <value>ソース名が存在しません</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_ARG_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>ソースの場所は既に別の名前で構成されています</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICATIONS_FOUND\" xml:space=\"preserve\">\n    <value>パッケージが見つかりません</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_SOURCES_DEFINED\" xml:space=\"preserve\">\n    <value>ソースが構成されていません</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_APPLICATIONS_FOUND\" xml:space=\"preserve\">\n    <value>条件に一致するパッケージが複数見つかりました</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_MANIFEST_FOUND\" xml:space=\"preserve\">\n    <value>条件に一致するマニフェストが見つかりませんでした</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXTENSION_PUBLIC_FAILED\" xml:space=\"preserve\">\n    <value>ソース パッケージからパブリック フォルダーを取得できませんでした</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMMAND_REQUIRES_ADMIN\" xml:space=\"preserve\">\n    <value>コマンドを実行するには管理者権限が必要です</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NOT_SECURE\" xml:space=\"preserve\">\n    <value>ソースの場所がセキュリティで保護されていません</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>Microsoft Store クライアントがポリシーによってブロックされています</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_APP_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>Microsoft Store アプリがポリシーによってブロックされています</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXPERIMENTAL_FEATURE_DISABLED\" xml:space=\"preserve\">\n    <value>この機能は現在開発中です。winget 設定を使用して有効にできます。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Microsoft Store アプリをインストールできませんでした</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMPLETE_INPUT_BAD\" xml:space=\"preserve\">\n    <value>オート コンプリートを実行できませんでした</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED\" xml:space=\"preserve\">\n    <value>YAML パーサーの初期化に失敗しました</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_MAPPING_KEY\" xml:space=\"preserve\">\n    <value>無効な YAML キーが見つかりました</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY\" xml:space=\"preserve\">\n    <value>重複している YAML キーが見つかりました</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_OPERATION\" xml:space=\"preserve\">\n    <value>YAML 操作が無効です</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_DOC_BUILD_FAILED\" xml:space=\"preserve\">\n    <value>YAML ドキュメントをビルドできませんでした</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_EMITTER_STATE\" xml:space=\"preserve\">\n    <value>YAML エミッタの状態が無効です</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_DATA\" xml:space=\"preserve\">\n    <value>YAML データが無効です</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LIBYAML_ERROR\" xml:space=\"preserve\">\n    <value>LibYAML エラー</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_WARNING\" xml:space=\"preserve\">\n    <value>マニフェストの検証は成功しましたが、警告があります</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_FAILURE\" xml:space=\"preserve\">\n    <value>マニフェストの検証に失敗しました</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_MANIFEST\" xml:space=\"preserve\">\n    <value>マニフェストが無効です</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>適用可能な更新は見つかりませんでした</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPDATE_ALL_HAS_FAILURE\" xml:space=\"preserve\">\n    <value>WinGet アップグレード -- すべて完了しましたが、エラーが発生しました</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_SECURITY_CHECK_FAILED\" xml:space=\"preserve\">\n    <value>インストーラーのセキュリティ チェックに失敗しました</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_SIZE_MISMATCH\" xml:space=\"preserve\">\n    <value>ダウンロード サイズが予期されたコンテンツの長さと一致しません</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_UNINSTALL_INFO_FOUND\" xml:space=\"preserve\">\n    <value>アンインストール コマンドが見つかりません</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXEC_UNINSTALL_COMMAND_FAILED\" xml:space=\"preserve\">\n    <value>アンインストール コマンドの実行に失敗しました</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_BREAK_ITERATOR_ERROR\" xml:space=\"preserve\">\n    <value>ICU ブレーク反復子エラー</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_CASEMAP_ERROR\" xml:space=\"preserve\">\n    <value>ICU ケースマップ エラー</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_REGEX_ERROR\" xml:space=\"preserve\">\n    <value>ICU 正規表現エラー</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_IMPORT_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>1 つ以上のインポートされたパッケージをインストールできませんでした</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NOT_ALL_PACKAGES_FOUND\" xml:space=\"preserve\">\n    <value>1 つ以上の要求されたパッケージが見つかりませんでした</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE\" xml:space=\"preserve\">\n    <value>JSON ファイルが無効です</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NOT_REMOTE\" xml:space=\"preserve\">\n    <value>ソースの場所がリモートではありません</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE\" xml:space=\"preserve\">\n    <value>構成された REST ソースはサポートされていません</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA\" xml:space=\"preserve\">\n    <value>REST ソースによって無効なデータが返されました</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>操作はグループ ポリシーによってブロックされています</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_INTERNAL_ERROR\" xml:space=\"preserve\">\n    <value>Rest API 内部エラー</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_URL\" xml:space=\"preserve\">\n    <value>REST ソース URL が無効です</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_UNSUPPORTED_MIME_TYPE\" xml:space=\"preserve\">\n    <value>REST API によって返されたサポートされていない MIME の種類</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_VERSION\" xml:space=\"preserve\">\n    <value>REST ソース コントラクト バージョンが無効です</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE\" xml:space=\"preserve\">\n    <value>ソース データが壊れているか、改ざんされています</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_STREAM_READ_FAILURE\" xml:space=\"preserve\">\n    <value>ストリームからの読み込みエラー</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>パッケージ契約に同意しませんでした</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PROMPT_INPUT_ERROR\" xml:space=\"preserve\">\n    <value>プロンプトで入力の読み取り中にエラーが発生しました</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST\" xml:space=\"preserve\">\n    <value>検索要求は 1 つ以上のソースでサポートされていません</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_ENDPOINT_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Rest API エンドポイントが見つかりません。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_OPEN_FAILED\" xml:space=\"preserve\">\n    <value>ソースを開けませんでした。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>ソース契約に同意しませんでした</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CUSTOMHEADER_EXCEEDS_MAXLENGTH\" xml:space=\"preserve\">\n    <value>ヘッダーのサイズが許容される上限の 1024 文字を超えています。サイズを小さくして、もう一度お試しください。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MISSING_RESOURCE_FILE\" xml:space=\"preserve\">\n    <value>リソース ファイルがありません</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSI_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>MSI インストールの実行に失敗しました</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT\" xml:space=\"preserve\">\n    <value>msiexec の引数が無効です</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FAILED_TO_OPEN_ALL_SOURCES\" xml:space=\"preserve\">\n    <value>1 つ以上のソースを開けませんでした</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>依存関係の検証ができませんでした</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MISSING_PACKAGE\" xml:space=\"preserve\">\n    <value>1 つ以上のパッケージが見つかりません</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_TABLE_COLUMN\" xml:space=\"preserve\">\n    <value>テーブル列が無効です</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_NOT_NEWER\" xml:space=\"preserve\">\n    <value>アップグレード バージョンが、インストールされているバージョンより新しくありません</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_UNKNOWN\" xml:space=\"preserve\">\n    <value>アップグレード バージョンが不明で、オーバーライドが指定されていません</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_CONVERSION_ERROR\" xml:space=\"preserve\">\n    <value>ICU 変換エラー</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>ポータブル パッケージをインストールできませんでした</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_REPARSE_POINT_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>ボリュームは再パース ポイントをサポートしていません</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_PACKAGE_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>別のソースからのポータブル パッケージが既に存在します。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_SYMLINK_PATH_IS_DIRECTORY\" xml:space=\"preserve\">\n    <value>symlink を作成できません。パスはディレクトリを指しています。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_PROHIBITS_ELEVATION\" xml:space=\"preserve\">\n    <value>管理者コンテキストからインストーラーを実行することはできません。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>ポータブル パッケージをアンインストールできませんでした</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ARP_VERSION_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>インデックスに対して DisplayVersion 値を検証できませんでした。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_ARGUMENT\" xml:space=\"preserve\">\n    <value>1 つ以上の引数がサポートされていません。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_BIND_WITH_EMBEDDED_NULL\" xml:space=\"preserve\">\n    <value>SQLite では埋め込み Null 文字は使用できません</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_NOT_FOUND\" xml:space=\"preserve\">\n    <value>入れ子になったインストーラーがアーカイブに見つかりませんでした。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXTRACT_ARCHIVE_FAILED\" xml:space=\"preserve\">\n    <value>アーカイブを抽出できませんでした。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_INVALID_PATH\" xml:space=\"preserve\">\n    <value>指定された入れ子になったインストーラーへの相対ファイル パスが無効です。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PINNED_CERTIFICATE_MISMATCH\" xml:space=\"preserve\">\n    <value>サーバー証明書が、予期された値のいずれにも一致しませんでした。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_LOCATION_REQUIRED\" xml:space=\"preserve\">\n    <value>インストールの場所を指定する必要があります。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ARCHIVE_SCAN_FAILED\" xml:space=\"preserve\">\n    <value>アーカイブのマルウェア スキャンに失敗しました。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>インストールされているパッケージのバージョンが少なくとも 1 つ見つかりました。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PIN_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>パッケージの PIN が既に存在します。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PIN_DOES_NOT_EXIST\" xml:space=\"preserve\">\n    <value>パッケージの PIN がありません。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_OPEN_PINNING_INDEX\" xml:space=\"preserve\">\n    <value>PIN データベースを開けません。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>1 つ以上のアプリケーションをインストールできませんでした</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>1 つ以上のアプリケーションをアンインストールできませんでした</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NOT_ALL_QUERIES_FOUND_SINGLE\" xml:space=\"preserve\">\n    <value>1 つ以上のクエリで、返された結果が 1 つのみではありませんでした</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_PINNED\" xml:space=\"preserve\">\n    <value>パッケージがピン留めされているため、アップグレードできません。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB\" xml:space=\"preserve\">\n    <value>現在インストールされているパッケージはスタブ パッケージです</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_APPTERMINATION_RECEIVED\" xml:space=\"preserve\">\n    <value>アプリケーション シャットダウン シグナルを受信しました</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_DEPENDENCIES\" xml:space=\"preserve\">\n    <value>パッケージの依存関係をダウンロードできませんでした。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_COMMAND_PROHIBITED\" xml:space=\"preserve\">\n    <value>パッケージをダウンロードできませんでした。オフライン インストール用のダウンロードは禁止されています。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SERVICE_UNAVAILABLE\" xml:space=\"preserve\">\n    <value>必要なサービスがビジー状態であるか、利用できません。後でもう一度お試しください。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESUME_ID_NOT_FOUND\" xml:space=\"preserve\">\n    <value>指定された GUID は、有効な再開状態に対応していません。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CLIENT_VERSION_MISMATCH\" xml:space=\"preserve\">\n    <value>現在のクライアント バージョンは、保存された状態のクライアント バージョンと一致しませんでした。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_RESUME_STATE\" xml:space=\"preserve\">\n    <value>再開状態データが無効です。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_OPEN_CHECKPOINT_INDEX\" xml:space=\"preserve\">\n    <value>チェックポイント データベースを開けません。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESUME_LIMIT_EXCEEDED\" xml:space=\"preserve\">\n    <value>再開の上限を超えました。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_AUTHENTICATION_INFO\" xml:space=\"preserve\">\n    <value>認証情報が無効です。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>認証方法がサポートされていません。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED\" xml:space=\"preserve\">\n    <value>認証に失敗しました。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_INTERACTIVE_REQUIRED\" xml:space=\"preserve\">\n    <value>認証に失敗しました。対話型認証が必要です。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_CANCELLED_BY_USER\" xml:space=\"preserve\">\n    <value>認証に失敗しました。ユーザーにより取り消されました。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_INCORRECT_ACCOUNT\" xml:space=\"preserve\">\n    <value>認証に失敗しました。認証されたアカウントは目的のアカウントではありません。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE\" xml:space=\"preserve\">\n    <value>アプリケーションは現在実行中です。アプリケーションを終了してから、もう一度お試しください。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INSTALL_IN_PROGRESS\" xml:space=\"preserve\">\n    <value>別のインストールが既に進行中です。後でもう一度お試しください。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_FILE_IN_USE\" xml:space=\"preserve\">\n    <value>1 つ以上のファイルが使用されています。アプリケーションを終了してから、もう一度お試しください。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_MISSING_DEPENDENCY\" xml:space=\"preserve\">\n    <value>このパッケージには、システムに依存関係がありません。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DISK_FULL\" xml:space=\"preserve\">\n    <value>PC にこれ以上空き領域がありません。空き領域を確保してから、もう一度やり直してください。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INSUFFICIENT_MEMORY\" xml:space=\"preserve\">\n    <value>インストールできるメモリが不足しています。他のアプリケーションを閉じてから、もう一度やり直してください。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_NO_NETWORK\" xml:space=\"preserve\">\n    <value>このアプリケーションにはインターネット接続が必要です。ネットワークに接続してから、もう一度お試しください。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CONTACT_SUPPORT\" xml:space=\"preserve\">\n    <value>このアプリケーションのインストール中にエラーが発生しました。サポートにお問い合わせください。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_TO_FINISH\" xml:space=\"preserve\">\n    <value>PC を再起動してインストールを完了します。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_FOR_INSTALL\" xml:space=\"preserve\">\n    <value>インストールに失敗しました。PC を再起動してから、もう一度お試しください。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_INITIATED\" xml:space=\"preserve\">\n    <value>PC が再起動してインストールが完了します。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CANCELLED_BY_USER\" xml:space=\"preserve\">\n    <value>ユーザーがインストールを取り消しました。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>このアプリケーションの別のバージョンが既にインストールされています。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DOWNGRADE\" xml:space=\"preserve\">\n    <value>このアプリケーションの上位バージョンは既にインストールされています。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>組織のポリシーが原因でインストールできません。管理者にお問い合わせください。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DEPENDENCIES\" xml:space=\"preserve\">\n    <value>パッケージの依存関係をインストールできませんでした。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE_BY_APPLICATION\" xml:space=\"preserve\">\n    <value>アプリケーションは現在別のアプリケーションで使用されています。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INVALID_PARAMETER\" xml:space=\"preserve\">\n    <value>パラメーターが無効です。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>パッケージはシステムでサポートされていません。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_UPGRADE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>インストーラーは既存のパッケージのアップグレードをサポートしていません。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CUSTOM_ERROR\" xml:space=\"preserve\">\n    <value>カスタム インストーラー エラーにより、インストールに失敗しました。</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_ARP_ENTRY_NOT_FOUND\" xml:space=\"preserve\">\n    <value>パッケージのアプリと機能エントリが見つかりませんでした。</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>インストールの場所は適用できません。</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_FOUND\" xml:space=\"preserve\">\n    <value>インストールの場所が見つかりませんでした。</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_HASH_MISMATCH\" xml:space=\"preserve\">\n    <value>既存のファイルのハッシュが一致しませんでした。</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_NOT_FOUND\" xml:space=\"preserve\">\n    <value>ファイルが見つかりませんでした。</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK\" xml:space=\"preserve\">\n    <value>ファイルは見つかりましたが、ハッシュはチェックされませんでした。</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_ACCESS_ERROR\" xml:space=\"preserve\">\n    <value>ファイルにアクセスできませんでした。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE\" xml:space=\"preserve\">\n    <value>構成ファイルが無効です。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_YAML\" xml:space=\"preserve\">\n    <value>YAML 構文が無効です。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_FIELD_TYPE\" xml:space=\"preserve\">\n    <value>構成フィールドの型が無効です。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION\" xml:space=\"preserve\">\n    <value>構成のバージョンが不明です。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_SET_APPLY_FAILED\" xml:space=\"preserve\">\n    <value>構成の適用中にエラーが発生しました。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER\" xml:space=\"preserve\">\n    <value>重複する識別子が構成に含まれています。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MISSING_DEPENDENCY\" xml:space=\"preserve\">\n    <value>構成に依存関係がありません。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED\" xml:space=\"preserve\">\n    <value>構成に不十分な依存関係があります。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_ASSERTION_FAILED\" xml:space=\"preserve\">\n    <value>構成単位のアサーションが失敗しました。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MANUALLY_SKIPPED\" xml:space=\"preserve\">\n    <value>この構成は手動でスキップされました。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_WARNING_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>ユーザーが実行の続行を拒否しました。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_SET_DEPENDENCY_CYCLE\" xml:space=\"preserve\">\n    <value>依存関係グラフに、解決できない循環が含まれています。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_FIELD_VALUE\" xml:space=\"preserve\">\n    <value>構成に無効なフィールド値が含まれています。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MISSING_FIELD\" xml:space=\"preserve\">\n    <value>構成にフィールドがありません。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_TEST_FAILED\" xml:space=\"preserve\">\n    <value>状態のテスト中に一部の構成ユニットが失敗しました。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_TEST_NOT_RUN\" xml:space=\"preserve\">\n    <value>構成の状態がテストされませんでした。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_NOT_INSTALLED\" xml:space=\"preserve\">\n    <value>構成ユニットはインストールされませんでした。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_NOT_FOUND_REPOSITORY\" xml:space=\"preserve\">\n    <value>構成単位が見つかりませんでした。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_MULTIPLE_MATCHES\" xml:space=\"preserve\">\n    <value>構成単位に一致する項目が複数見つかりました。モジュールを指定して、正しいモジュールを選択してください。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_GET\" xml:space=\"preserve\">\n    <value>現在のシステム状態の取得中に構成単位が失敗しました。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_TEST\" xml:space=\"preserve\">\n    <value>現在のシステム状態のテスト中に構成単位が失敗しました。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_SET\" xml:space=\"preserve\">\n    <value>必要な状態の適用中に構成単位が失敗しました。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_MODULE_CONFLICT\" xml:space=\"preserve\">\n    <value>構成単位のモジュールは、同じバージョンの複数の場所で使用できます。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE\" xml:space=\"preserve\">\n    <value>構成単位のモジュールを読み込めませんでした。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_INVALID_RESULT\" xml:space=\"preserve\">\n    <value>構成単位が実行中に予期しない結果を返しました。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_SETTING_CONFIG_ROOT\" xml:space=\"preserve\">\n    <value>ユニットに構成ルートを必要とする設定が含まれています。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR\" xml:space=\"preserve\">\n    <value>構成プロセッサでは操作がサポートされていません。</value>\n  </data>\n  <data name=\"Unavailable\" xml:space=\"preserve\">\n    <value>利用不可</value>\n  </data>\n  <data name=\"EnableWindowsFeaturesSuccess\" xml:space=\"preserve\">\n    <value>Windows 機能の依存関係が正常に有効になりました</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE_ADMIN\" xml:space=\"preserve\">\n    <value>構成単位のモジュールを読み込めませんでした。実行するには管理者特権が必要です。</value>\n  </data>\n  <data name=\"ConfigurationUnitSettingConfigRoot\" xml:space=\"preserve\">\n    <value>ユニットに構成ルートを必要とする設定が含まれています。</value>\n  </data>\n  <data name=\"ConfigurationUnitImportModuleAdmin\" xml:space=\"preserve\">\n    <value>構成単位のモジュールを読み込めませんでした。実行するには管理者特権が必要です。</value>\n  </data>\n  <data name=\"ResumeCommandLongDescription\" xml:space=\"preserve\">\n    <value>保存されたコマンドの一意識別子を渡すことで、以前に保存されたコマンドの実行を再開します。これは、再起動のために終了した可能性のある、実行されたコマンドを再開するために使用されます。</value>\n  </data>\n  <data name=\"ResumeCommandShortDescription\" xml:space=\"preserve\">\n    <value>以前に保存したコマンドの実行を再開します。</value>\n  </data>\n  <data name=\"ResumeIdArgumentDescription\" xml:space=\"preserve\">\n    <value>再開する保存された状態の一意識別子</value>\n  </data>\n  <data name=\"ClientVersionMismatchError\" xml:space=\"preserve\">\n    <value>別のクライアント バージョンからの状態の再開はサポートされていません: {0}</value>\n    <comment>{Locked= \"{0}\"} Message displayed to inform the user that the client version of the resume state does not match the current client version. {0} is a placeholder for the client version that created the resume state.</comment>\n  </data>\n  <data name=\"ResumeIdNotFoundError\" xml:space=\"preserve\">\n    <value>再開状態が存在しません: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a guid that does not correspond to a valid saved state. {0} is a placeholder replaced by the provided guid string.</comment>\n  </data>\n  <data name=\"ResumeStateDataNotFoundError\" xml:space=\"preserve\">\n    <value>再開状態のデータが見つかりません。</value>\n  </data>\n  <data name=\"CommandDoesNotSupportResumeMessage\" xml:space=\"preserve\">\n    <value>このコマンドは再開をサポートしていません。</value>\n  </data>\n  <data name=\"AllowRebootArgumentDescription\" xml:space=\"preserve\">\n    <value>適用可能な場合は再起動を許可します</value>\n  </data>\n  <data name=\"InitiatingReboot\" xml:space=\"preserve\">\n    <value>再起動を開始して操作を完了しています...</value>\n  </data>\n  <data name=\"FailedToInitiateReboot\" xml:space=\"preserve\">\n    <value>再起動を開始できませんでした。</value>\n  </data>\n  <data name=\"ResumeLimitExceeded\" xml:space=\"preserve\">\n    <value>再開操作が、許可されている再開 {0} 制限を超えています。手動で再開するには、コマンド '{1}' を実行してください。</value>\n    <comment>{Locked=\"{0}\", \"{1}\"} {0} is a placeholder that is replaced by an integer number of the number of allowed resumes. {1} is a placeholder for the command to run to perform a manual resume.</comment>\n  </data>\n  <data name=\"IgnoreResumeLimitArgumentDescription\" xml:space=\"preserve\">\n    <value>保存された状態の再開の制限を無視する</value>\n  </data>\n  <data name=\"UriSchemeNotSupported\" xml:space=\"preserve\">\n    <value>URI スキームはサポートされていません: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the provided uri is not supported. {0} is a placeholder replaced by the provided uri.</comment>\n  </data>\n  <data name=\"UriNotWellFormed\" xml:space=\"preserve\">\n    <value>整形式の URL ではありません: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the provided uri is not well formed. {0} is a placeholder replaced by the provided uri.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitEmptyContent\" xml:space=\"preserve\">\n    <value>構成単位の設定コンテンツ {0} 解析できなかったか、設定コンテンツが空です。</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder replaced by the input winget configure resource unit type.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitMissingRequiredArg\" xml:space=\"preserve\">\n    <value>{0} 構成単位に必要な引数がありません: {1}</value>\n    <comment>{Locked=\"{0},{1}\"} {0} is a placeholder for the input winget configure resource unit type. {1} is placeholder for the missing arg.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitMissingRecommendedArg\" xml:space=\"preserve\">\n    <value>{0} 構成単位に推奨引数がありません: {1}</value>\n    <comment>{Locked=\"{0},{1}\"} {0} is a placeholder for the input winget configure resource unit type. {1} is placeholder for the missing arg.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitKnownSourceConfliction\" xml:space=\"preserve\">\n    <value>WinGetSource の構成ユニットが既知のソースと競合しています: {0}</value>\n    <comment>{Locked=\"WinGetSource,{0}\"} {0} is a placeholder for the input winget source in the configuration unit settings.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitThirdPartySourceAssertion\" xml:space=\"preserve\">\n    <value>WinGetSource の構成ユニットがサード パーティのソースに対してアサートしています: {0}</value>\n    <comment>{Locked=\"WinGetSource,{0}\"} {0} is a placeholder for the input winget source in the configuration unit settings.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitBothPackageVersionAndUseLatest\" xml:space=\"preserve\">\n    <value>WinGetPackage で UseLatest と Version の両方が宣言されています。パッケージ ID: {0}</value>\n    <comment>{Locked=\"WinGetPackage,UseLatest,Version,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitThirdPartySourceAssertionForPackage\" xml:space=\"preserve\">\n    <value>WinGetPackage 構成単位は、サード パーティのソースからのパッケージに対してアサートします。パッケージ ID: {0};ソース: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitDependencySourceNotConfigured\" xml:space=\"preserve\">\n    <value>WinGetPackage 構成単位パッケージは、以前に構成されていないサード パーティのソースに依存しています。パッケージ ID: {0};ソース: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitDependencySourceNotDeclaredAsDependency\" xml:space=\"preserve\">\n    <value>WinGetPackage 構成単位パッケージはサード パーティのソースに依存しています。uni dependsOn セクションで依存関係を宣言することをお勧めします。パッケージ ID: {0};ソース: {1}</value>\n    <comment>{Locked=\"WinGetPackage,dependsOn,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageSourceOpenFailed\" xml:space=\"preserve\">\n    <value>WinGetPackage 構成単位パッケージを検証できません。ソースを開けませんでした。パッケージ ID: {0};ソース: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageNotFound\" xml:space=\"preserve\">\n    <value>WinGetPackage 構成単位パッケージを検証できません。パッケージが見つかりません。パッケージ ID: {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageMultipleFound\" xml:space=\"preserve\">\n    <value>WinGetPackage 構成単位パッケージを検証できません。複数のパッケージが見つかりました。パッケージ ID: {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageVersionNotFound\" xml:space=\"preserve\">\n    <value>WinGetPackage 構成単位パッケージを検証できません。パッケージ バージョンが見つかりません。パッケージ ID: {0};バージョン {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitPackageVersionSpecifiedWithOnlyOnePackageVersion\" xml:space=\"preserve\">\n    <value>特定のバージョンで指定された WinGetPackage 構成ユニット パッケージ。使用可能なパッケージのバージョンは 1 つだけです。パッケージ ID: {0}; バージョン: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackage\" xml:space=\"preserve\">\n    <value>WinGetPackage 構成単位パッケージを検証できません。パッケージ ID: {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"AuthenticationModeArgumentDescription\" xml:space=\"preserve\">\n    <value>認証ウィンドウの設定を指定する (silent、silentPreferred、または interactive)</value>\n    <comment>{Locked=\"silent\",\"silentPreferred\",\"interactive\"} This argument allows the user to select authentication window popup behavior.</comment>\n  </data>\n  <data name=\"AuthenticationAccountArgumentDescription\" xml:space=\"preserve\">\n    <value>認証に使用するアカウントを指定します</value>\n  </data>\n  <data name=\"SourceAddFailedAuthenticationNotSupported\" xml:space=\"preserve\">\n    <value>ソースを追加できませんでした。この winget バージョンは、ソースの認証方法をサポートしていません。最新の winget バージョンにアップグレードしてみてください。</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"SourceRequiresAuthentication\" xml:space=\"preserve\">\n    <value>{0} ソースには認証が必要です。必要に応じて認証プロンプトが表示されることがあります。認証された情報は、アクセス承認のためにソースと共有されます。</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"RepairCommandLongDescription\" xml:space=\"preserve\">\n    <value>インストールされたパッケージリスト、またはマニフェストから検索し、選択されたパッケージを修復します。既定では、クエリはパッケージのID、名前、モニカーに大文字小文字の区別なく一致する必要があります。その他のフィールドは、適切なオプションを渡すことで使用することができます。</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"RepairCommandShortDescription\" xml:space=\"preserve\">\n    <value>選択したパッケージを修復します</value>\n  </data>\n  <data name=\"NoRepairInfoFound\" xml:space=\"preserve\">\n    <value>このパッケージの修復コマンドが見つかりません。サポートが必要な場合は、パッケージの発行元にお問い合わせください。</value>\n  </data>\n  <data name=\"RepairDifferentInstallTechnology\" xml:space=\"preserve\">\n    <value>使用中のインストーラー テクノロジが、現在インストールされているバージョンと一致しません。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_REPAIR_INFO_FOUND\" xml:space=\"preserve\">\n    <value>修復コマンドが見つかりません。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_REPAIR_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>使用中のインストーラー テクノロジは修復をサポートしていません。</value>\n  </data>\n  <data name=\"RepairFlowRepairSuccess\" xml:space=\"preserve\">\n    <value>修復操作が正常に完了しました。</value>\n  </data>\n  <data name=\"RepairAbandoned\" xml:space=\"preserve\">\n    <value>修復が中止されました</value>\n  </data>\n  <data name=\"RepairFlowStartingPackageRepair\" xml:space=\"preserve\">\n    <value>パッケージの修復を開始しています...</value>\n  </data>\n  <data name=\"MSStoreRepairFailed\" xml:space=\"preserve\">\n    <value>Microsoft Store パッケージを修復できませんでした。エラー コード: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Microsoft Store application package fails to repair. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXEC_REPAIR_FAILED\" xml:space=\"preserve\">\n    <value>修復操作に失敗しました。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_REPAIR_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>修復操作は適用できません。</value>\n  </data>\n  <data name=\"RepairFlowNoMatchingVersion\" xml:space=\"preserve\">\n    <value>構成されたソースから入手できるパッケージ バージョンの中に、一致するものはありません。</value>\n  </data>\n  <data name=\"RepairFlowReturnCodeSystemNotSupported\" xml:space=\"preserve\">\n    <value>現在のシステム構成では、このパッケージの修復はサポートされていません。</value>\n  </data>\n  <data name=\"RepairOperationNotSupported\" xml:space=\"preserve\">\n    <value>使用中のインストーラー テクノロジは修復をサポートしていません。</value>\n  </data>\n  <data name=\"NoAdminRepairForUserScopePackage\" xml:space=\"preserve\">\n    <value>管理者特権で実行している場合、ユーザー スコープ用にインストールされたパッケージは修復できません。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED\" xml:space=\"preserve\">\n    <value>管理者特権を含む修復操作は、ユーザースコープ内にインストールされたパッケージでは許可されていません。</value>\n  </data>\n  <data name=\"RepairFailedWithCode\" xml:space=\"preserve\">\n    <value>修復が終了コードで失敗しました: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to repair an application package fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SQLITE_CONNECTION_TERMINATED\" xml:space=\"preserve\">\n    <value>SQLite 接続は破損を防ぐために終了しました。</value>\n  </data>\n  <data name=\"UninstallAllVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>すべてのバージョンをアンインストール</value>\n  </data>\n  <data name=\"TargetVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>処理するバージョン</value>\n  </data>\n  <data name=\"UninstallFailedDueToMultipleVersions\" xml:space=\"preserve\">\n    <value>このパッケージの複数のバージョンがインストールされています。検索を絞り込むか、'--version' 引数を渡して 1 つ選択するか、'--all-versions' フラグを渡してすべてをアンインストールしてください。</value>\n    <comment>{Locked=\"--version,--all-versions\"}</comment>\n  </data>\n  <data name=\"PolicyEnableProxyCommandLineOptions\" xml:space=\"preserve\">\n    <value>プロキシ コマンド ライン オプションWindows パッケージ マネージャー有効にする</value>\n    <comment>Describes a Group Policy that can enable the use of the --proxy option to set a proxy</comment>\n  </data>\n  <data name=\"ProxyArgumentDescription\" xml:space=\"preserve\">\n    <value>この実行に使用するプロキシを設定します</value>\n  </data>\n  <data name=\"NoProxyArgumentDescription\" xml:space=\"preserve\">\n    <value>この実行に対するプロキシの使用を無効にする</value>\n  </data>\n  <data name=\"ResetAdminSettingFailed\" xml:space=\"preserve\">\n    <value>{0} をリセットできません。この設定はポリシーによって制御されます。詳細については、システム管理者に問い合わせてください。</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"ResetAdminSettingSucceeded\" xml:space=\"preserve\">\n    <value>管理者設定 '{0}' をリセットします。</value>\n    <comment>{Locked=\"{0}\"} Message displayed after the user resets an admin setting to its default value. Reset is used as verb in past tense. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"SetAdminSettingFailed\" xml:space=\"preserve\">\n    <value>{0} を設定できません。この設定はポリシーによって制御されます。詳細については、システム管理者に問い合わせてください。</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"SetAdminSettingSucceeded\" xml:space=\"preserve\">\n    <value>管理者設定の '{0}' を '{1}' に設定します。</value>\n    <comment>{Locked=\"{0}\"} Message displayed after the user sets the value of an admin setting. Set is used as a verb in past tense. {0} is a placeholder replaced by the setting name. {1} is a placeholder replaced </comment>\n  </data>\n  <data name=\"SettingNameArgumentDescription\" xml:space=\"preserve\">\n    <value>変更する設定の名前</value>\n  </data>\n  <data name=\"SettingValueArgumentDescription\" xml:space=\"preserve\">\n    <value>設定に設定する値。</value>\n  </data>\n  <data name=\"SettingsResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>管理者設定を既定値にリセットします。</value>\n  </data>\n  <data name=\"SettingsResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>管理者設定を既定値にリセットします。</value>\n  </data>\n  <data name=\"SettingsSetCommandLongDescription\" xml:space=\"preserve\">\n    <value>管理者設定の値を設定します。</value>\n  </data>\n  <data name=\"SettingsSetCommandShortDescription\" xml:space=\"preserve\">\n    <value>管理者設定の値を設定します。</value>\n  </data>\n  <data name=\"SourceExplicitArgumentDescription\" xml:space=\"preserve\">\n    <value>指定しない限り、ソースを検出から除外します</value>\n  </data>\n  <data name=\"SourceEditExplicitArgumentDescription\" xml:space=\"preserve\">\n    <value>ソースを検出から除外します (true または false)</value>\n  </data>\n  <data name=\"SourceListExplicit\" xml:space=\"preserve\">\n    <value>成人指定</value>\n  </data>\n  <data name=\"SourceTrustLevelArgumentDescription\" xml:space=\"preserve\">\n    <value>ソースの信頼レベル (なしまたは信頼済み)</value>\n  </data>\n  <data name=\"SourceListTrustLevel\" xml:space=\"preserve\">\n    <value>信頼レベル</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DISPLAYCATALOG_API_FAILED\" xml:space=\"preserve\">\n    <value>Microsoft Store パッケージ カタログを取得できませんでした。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_DISPLAYCATALOG_PACKAGE\" xml:space=\"preserve\">\n    <value>Microsoft Store パッケージ カタログから該当する Microsoft Store パッケージが見つかりません。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SFSCLIENT_API_FAILED\" xml:space=\"preserve\">\n    <value>Microsoft Store パッケージのダウンロード情報を取得できませんでした。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_SFSCLIENT_PACKAGE\" xml:space=\"preserve\">\n    <value>ダウンロードする適用可能なMicrosoft Store パッケージが見つかりませんでした。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED\" xml:space=\"preserve\">\n    <value>Microsoft Store パッケージ ライセンスを取得できませんでした。</value>\n  </data>\n  <data name=\"MSStoreDownloadNoApplicablePackageFound\" xml:space=\"preserve\">\n    <value>該当する Microsoft Store パッケージが見つかりません。</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageHashVerified\" xml:space=\"preserve\">\n    <value>Microsoft Store パッケージ ハッシュの検証に成功しました</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageHashMismatch\" xml:space=\"preserve\">\n    <value>Microsoft Store パッケージ ハッシュの不一致</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloaded\" xml:space=\"preserve\">\n    <value>Microsoft Store パッケージがダウンロードされました: {0}</value>\n    <comment>{Locked=\"{0}\"} Full path of the downloaded package.</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadFailed\" xml:space=\"preserve\">\n    <value>Microsoft Store パッケージのダウンロードに失敗しました: {0}</value>\n    <comment>{Locked=\"{0}\"} Package name.</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadSuccess\" xml:space=\"preserve\">\n    <value>Microsoft Store パッケージのダウンロードが完了しました</value>\n  </data>\n  <data name=\"MSStoreDownloadMainPackages\" xml:space=\"preserve\">\n    <value>Microsoft Store からメイン パッケージをダウンロードしています...</value>\n  </data>\n  <data name=\"MSStoreDownloadDependencyPackages\" xml:space=\"preserve\">\n    <value>Microsoft Store から依存パッケージをダウンロードしています...</value>\n  </data>\n  <data name=\"MSStoreDownloadGetDownloadInfo\" xml:space=\"preserve\">\n    <value>Microsoft Store パッケージのダウンロード情報を取得しています</value>\n  </data>\n  <data name=\"MSStoreDownloadGetDownloadInfoFailed\" xml:space=\"preserve\">\n    <value>Microsoft Store パッケージのダウンロード情報を取得できませんでした</value>\n  </data>\n  <data name=\"MSStoreDownloadGetLicense\" xml:space=\"preserve\">\n    <value>Microsoft Store パッケージ ライセンスを取得しています</value>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseSuccess\" xml:space=\"preserve\">\n    <value>Microsoft Store のパッケージ ライセンスを保存しました: {0}</value>\n    <comment>{Locked=\"{0}\"} License file full path.</comment>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseFailed\" xml:space=\"preserve\">\n    <value>Microsoft Store パッケージ ライセンスを取得できませんでした</value>\n  </data>\n  <data name=\"MSStoreDownloadRenameNotSupported\" xml:space=\"preserve\">\n    <value>Microsoft Store パッケージのダウンロードでは、--rename 引数はサポートされていません。Microsoft Store パッケージでは、Microsoft Store カタログによって提供される名前が使用されます。</value>\n    <comment>{Locked=\"--rename\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadAuthenticationNotice\" xml:space=\"preserve\">\n    <value>Microsoft Store パッケージのダウンロードにはMicrosoft Entra ID 認証が必要です。必要に応じて認証プロンプトが表示されることがあります。認証された情報は、アクセス承認のためにMicrosoft サービスと共有されます。パッケージ ライセンスMicrosoft Storeするには、Microsoft Entra ID アカウントがグローバル管理者、ユーザー管理者、またはライセンス管理者のメンバーである必要があります。</value>\n    <comment>{Locked=\"Global Administrator,User Administrator,License Administrator\"}</comment>\n  </data>\n  <data name=\"SkipMicrosoftStorePackageLicenseArgumentDescription\" xml:space=\"preserve\">\n    <value>Microsoft Store パッケージのオフライン ライセンスの取得をスキップします</value>\n  </data>\n  <data name=\"PlatformArgumentDescription\" xml:space=\"preserve\">\n    <value>ターゲット プラットフォームの選択</value>\n  </data>\n  <data name=\"ConfigurationExportAddingToFile\" xml:space=\"preserve\">\n    <value>構成ファイルの追加: {0}</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportSuccessful\" xml:space=\"preserve\">\n    <value>エクスポートに成功しました</value>\n  </data>\n  <data name=\"ConfigurationGettingResourceSettings\" xml:space=\"preserve\">\n    <value>構成設定を取得しています...</value>\n  </data>\n  <data name=\"ConfigureExportArgumentRequiredError\" xml:space=\"preserve\">\n    <value>--resource を含む --packageId または --module を少なくとも指定する必要があります。または、--all を使用して、すべてのパッケージ構成をエクスポートします。</value>\n    <comment>{Locked=\"--packageId,--module, --resource, --all\"}</comment>\n  </data>\n  <data name=\"ConfigureExportArgumentConflictWithAllError\" xml:space=\"preserve\">\n    <value>引数 --packageId、--module、--resource を --all と共に使用することはできません。</value>\n    <comment>{Locked=\"--packageId,--module, --resource, --all\"}</comment>\n  </data>\n  <data name=\"ConfigureExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>構成リソースを構成ファイルにエクスポートします。--all と共に使用すると、すべてのパッケージ構成がエクスポートされます。--packageId と共に使用すると、指定されたパッケージ ID の WinGetPackage リソースがエクスポートされます。--module および --resource と共に使用する場合、リソースの設定を取得し、構成ファイルにエクスポートします。出力構成ファイルが既に存在する場合は、エクスポートされた構成リソースを追加します。</value>\n    <comment>{Locked=\"WinGetPackage,--packageId,--module, --resource\"}</comment>\n  </data>\n  <data name=\"ConfigureExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>構成リソースを構成ファイルにエクスポートします。</value>\n  </data>\n  <data name=\"ConfigureExportModule\" xml:space=\"preserve\">\n    <value>エクスポートするリソースのモジュール。</value>\n  </data>\n  <data name=\"ConfigureExportPackageId\" xml:space=\"preserve\">\n    <value>エクスポートするパッケージ識別子。</value>\n  </data>\n  <data name=\"ConfigureExportResource\" xml:space=\"preserve\">\n    <value>エクスポートする構成リソース。</value>\n  </data>\n  <data name=\"ConfigureExportAll\" xml:space=\"preserve\">\n    <value>すべてのパッケージ構成をエクスポートします。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_GET_FAILED\" xml:space=\"preserve\">\n    <value>構成ユニットはプロパティの取得に失敗しました。</value>\n  </data>\n  <data name=\"ConfigurationExportFailed\" xml:space=\"preserve\">\n    <value>構成をエクスポートできませんでした。</value>\n  </data>\n  <data name=\"ConfigureExportUnitDescription\" xml:space=\"preserve\">\n    <value>{0} の構成</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigureExportUnitInstallDescription\" xml:space=\"preserve\">\n    <value>{0} のインストール</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationWarningSetViewTruncated\" xml:space=\"preserve\">\n    <value>構成ファイルに存在するデータの一部が、この出力に対して切り捨てられました。ファイルの内容を検査して、完全なコンテンツを確認してください。</value>\n  </data>\n  <data name=\"ConfigurationWarningValueTruncated\" xml:space=\"preserve\">\n    <value>&lt;この値は切り捨てられています。完全なテキストについてはファイルの内容を調べてください&gt;</value>\n    <comment>Keep some form of separator like the \"&lt;&gt;\" around the text so that it stands out from the preceding text.</comment>\n  </data>\n  <data name=\"ConfigureListCommandLongDescription\" xml:space=\"preserve\">\n    <value>システムに適用された構成の詳細レベルを表示します。このデータは、`configure` コマンドと共に使用して、詳細を取得できます。</value>\n    <comment>{Locked=\"`configure`\"}</comment>\n  </data>\n  <data name=\"ConfigureListCommandShortDescription\" xml:space=\"preserve\">\n    <value>構成履歴の表示</value>\n  </data>\n  <data name=\"ConfigurationHistoryEmpty\" xml:space=\"preserve\">\n    <value>履歴に構成はありません。</value>\n  </data>\n  <data name=\"ConfigurationHistoryItemArgumentDescription\" xml:space=\"preserve\">\n    <value>履歴からアイテムを選択する</value>\n  </data>\n  <data name=\"ConfigurationHistoryItemNotFound\" xml:space=\"preserve\">\n    <value>指定されたデータに一致する単一の構成が見つかりませんでした。必要な構成と厳密に一致する完全な名前または識別子の一部を指定してください。</value>\n  </data>\n  <data name=\"ConfigurationHistoryRemoveArgumentDescription\" xml:space=\"preserve\">\n    <value>履歴からアイテムを削除する</value>\n  </data>\n  <data name=\"ConfigureListFirstApplied\" xml:space=\"preserve\">\n    <value>最初に適用された日</value>\n    <comment>Column header for date values indicating when a configuration was first applied to the system.</comment>\n  </data>\n  <data name=\"ConfigureListIdentifier\" xml:space=\"preserve\">\n    <value>ID</value>\n  </data>\n  <data name=\"ConfigureListName\" xml:space=\"preserve\">\n    <value>名前</value>\n  </data>\n  <data name=\"ConfigureListOrigin\" xml:space=\"preserve\">\n    <value>元の場所</value>\n  </data>\n  <data name=\"ConfigureListPath\" xml:space=\"preserve\">\n    <value>パス</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_HISTORY_ITEM_NOT_FOUND\" xml:space=\"preserve\">\n    <value>指定された構成が見つかりませんでした。</value>\n  </data>\n  <data name=\"ConfigurationSetStateCompleted\" xml:space=\"preserve\">\n    <value>完了済み</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStateInProgress\" xml:space=\"preserve\">\n    <value>処理中</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStatePending\" xml:space=\"preserve\">\n    <value>保留中</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStateUnknown\" xml:space=\"preserve\">\n    <value>不明</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationStatusWatchArgumentDescription\" xml:space=\"preserve\">\n    <value>構成状態を監視します。</value>\n    <comment>As in \"to monitor the status of a configuration being applied\".</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateCompleted\" xml:space=\"preserve\">\n    <value>完了済み</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateInProgress\" xml:space=\"preserve\">\n    <value>処理中</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStatePending\" xml:space=\"preserve\">\n    <value>保留中</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateSkipped\" xml:space=\"preserve\">\n    <value>スキップ済み</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateUnknown\" xml:space=\"preserve\">\n    <value>不明</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigureListApplyBegun\" xml:space=\"preserve\">\n    <value>適用を開始しました</value>\n    <comment>When the configuration application started.</comment>\n  </data>\n  <data name=\"ConfigureListApplyEnded\" xml:space=\"preserve\">\n    <value>適用が終了しました</value>\n    <comment>When the configuration application ended.</comment>\n  </data>\n  <data name=\"ConfigureListResult\" xml:space=\"preserve\">\n    <value>結果</value>\n  </data>\n  <data name=\"ConfigureListResultDescription\" xml:space=\"preserve\">\n    <value>詳細</value>\n  </data>\n  <data name=\"ConfigureListState\" xml:space=\"preserve\">\n    <value>状態</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigureListUnit\" xml:space=\"preserve\">\n    <value>単位数</value>\n  </data>\n  <data name=\"StoreInstall_PackageNotAvailableForCurrentSystem\" xml:space=\"preserve\">\n    <value>パッケージは現在の Windows バージョンまたはプラットフォームと互換性がありません。</value>\n  </data>\n  <data name=\"ConfigurationSuppressPrologueArgumentDescription\" xml:space=\"preserve\">\n    <value>可能な場合は初期設定の詳細を表示しない</value>\n  </data>\n  <data name=\"MSStoreDownloadMultiplePackagesNotice\" xml:space=\"preserve\">\n    <value>異なるプラットフォームとアーキテクチャを対象に、複数のMicrosoft Store パッケージをダウンロードできます。--platform、 --architecture を使用してパッケージをフィルター処理できます。</value>\n    <comment>{Locked=\"--platform--architecture\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseForbidden\" xml:space=\"preserve\">\n    <value>Microsoft Store パッケージ ライセンスを取得できませんでした。Microsoft Entra ID アカウントは、グローバル管理者、ユーザー管理者、またはライセンス管理者のメンバーではありません。--skip-license を使用して、パッケージ ライセンスの取得Microsoft Storeスキップします。</value>\n    <comment>{Locked=\"Global Administrator,User Administrator,License Administrator,--skip-license\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadNotSupported\" xml:space=\"preserve\">\n    <value>Microsoft Store パッケージはダウンロードをサポートしていません。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SFSCLIENT_PACKAGE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Microsoft Store パッケージはダウンロードをサポートしていません。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED_FORBIDDEN\" xml:space=\"preserve\">\n    <value>Microsoft Store パッケージ ライセンスを取得できませんでした。Microsoft Entra ID アカウントに必要な特権がありません。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_PARAMETER_INTEGRITY_BOUNDARY\" xml:space=\"preserve\">\n    <value>整合性境界を越えてパラメーターを渡すことはできません。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_ZERO_BYTE_FILE\" xml:space=\"preserve\">\n    <value>ゼロ バイト インストーラーをダウンロードしました;ネットワーク接続が正しく動作していることを確認してください。</value>\n  </data>\n  <data name=\"InstallerZeroByteFile\" xml:space=\"preserve\">\n    <value>ゼロ バイト インストーラーをダウンロードしました;ネットワーク接続が正しく動作していることを確認してください。</value>\n  </data>\n  <data name=\"FontCommandShortDescription\" xml:space=\"preserve\">\n    <value>フォントの管理</value>\n  </data>\n  <data name=\"FontCommandLongDescription\" xml:space=\"preserve\">\n    <value>サブコマンドを使用してフォントを管理します。packages.  と同様に、フォントをインストール、アップグレード、またはアンインストールできます</value>\n  </data>\n  <data name=\"FontFamily\" xml:space=\"preserve\">\n    <value>ファミリ</value>\n  </data>\n  <data name=\"FontFaces\" xml:space=\"preserve\">\n    <value>フェイス</value>\n    <comment>\"Faces\" represents the typeface of the font family such as 'Bold' or 'Italic'</comment>\n  </data>\n  <data name=\"FontFamilyNameArgumentDescription\" xml:space=\"preserve\">\n    <value>ファミリ名で結果をフィルター処理する</value>\n  </data>\n  <data name=\"FontFace\" xml:space=\"preserve\">\n    <value>顔</value>\n    <comment>\"Face\" represents the typeface of a font family such as 'Bold' or 'Italic'</comment>\n  </data>\n  <data name=\"FontFilePaths\" xml:space=\"preserve\">\n    <value>パス</value>\n  </data>\n  <data name=\"NoInstalledFontFound\" xml:space=\"preserve\">\n    <value>入力条件に一致するインストール済みのフォントが見つかりませんでした。</value>\n  </data>\n  <data name=\"FontListCommandShortDescription\" xml:space=\"preserve\">\n    <value>インストール済みフォントを一覧表示します</value>\n  </data>\n  <data name=\"FontListCommandLongDescription\" xml:space=\"preserve\">\n    <value>インストールされているすべてのフォント、すべてのフォント ファイル、または特定のフォントの完全な詳細を一覧表示します。</value>\n  </data>\n  <data name=\"FontVersion\" xml:space=\"preserve\">\n    <value>バージョン</value>\n  </data>\n  <data name=\"ConfigurationModules\" xml:space=\"preserve\">\n    <value>構成モジュール</value>\n    <comment>PowerShell Modules that are used for the Configuration feature</comment>\n  </data>\n  <data name=\"InstallerDownloadRequiresAuthentication\" xml:space=\"preserve\">\n    <value>パッケージ インストーラーには認証が必要です。必要に応じて認証プロンプトが表示されることがあります。認証された情報はインストーラーのダウンロード URL と共有されます。</value>\n  </data>\n  <data name=\"InstallerDownloadAuthenticationNotSupported\" xml:space=\"preserve\">\n    <value>インストーラーをダウンロードできませんでした。この winget バージョンは、インストーラーのダウンロード認証方法をサポートしていません。最新の winget バージョンにアップグレードしてみてください。</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"InstallerDownloadAuthenticationFailed\" xml:space=\"preserve\">\n    <value>インストーラーをダウンロードできませんでした。認証に失敗しました。</value>\n  </data>\n  <data name=\"ConfigurationProcessorPath\" xml:space=\"preserve\">\n    <value>構成プロセッサへのパスを指定する</value>\n  </data>\n  <data name=\"DscCommandShortDescription\" xml:space=\"preserve\">\n    <value>DSC v3 リソース コマンド</value>\n    <comment>DSC stands for \"Desired State Configuration\". It should already have a locked translation.</comment>\n  </data>\n  <data name=\"DscCommandLongDescription\" xml:space=\"preserve\">\n    <value>ここでのサブコマンドは、winget とパッケージを構成するための Desired State Configuration (DSC) v3 リソースを実装しています。</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionGet\" xml:space=\"preserve\">\n    <value>リソースの状態を取得する</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionSet\" xml:space=\"preserve\">\n    <value>リソースの状態を設定する</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionWhatIf\" xml:space=\"preserve\">\n    <value>必要な状態の変更について説明する</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionTest\" xml:space=\"preserve\">\n    <value>リソースの状態をテストする</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionDelete\" xml:space=\"preserve\">\n    <value>リソースの状態を削除する</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionExport\" xml:space=\"preserve\">\n    <value>すべての状態インスタンスを取得する</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionValidate\" xml:space=\"preserve\">\n    <value>グループの内容を検証する</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionResolve\" xml:space=\"preserve\">\n    <value>外部状態を解決する</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionAdapter\" xml:space=\"preserve\">\n    <value>アダプターを実行する</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionSchema\" xml:space=\"preserve\">\n    <value>リソース スキーマを取得する</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionManifest\" xml:space=\"preserve\">\n    <value>リソース マニフェストを取得する</value>\n  </data>\n  <data name=\"DscPackageResourceShortDescription\" xml:space=\"preserve\">\n    <value>パッケージの状態を管理する</value>\n  </data>\n  <data name=\"DscPackageResourceLongDescription\" xml:space=\"preserve\">\n    <value>winget を使用してパッケージを管理します。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionExist\" xml:space=\"preserve\">\n    <value>インスタンスが存在するかどうかを示します。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionInDesiredState\" xml:space=\"preserve\">\n    <value>インスタンスが目的の状態かどうかを示します。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageId\" xml:space=\"preserve\">\n    <value>パッケージの識別子。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageSource\" xml:space=\"preserve\">\n    <value>パッケージのソース。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageVersion\" xml:space=\"preserve\">\n    <value>パッケージのバージョン。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageMatchOption\" xml:space=\"preserve\">\n    <value>識別子とパッケージを照合するためのメソッドです。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageUseLatest\" xml:space=\"preserve\">\n    <value>パッケージの使用可能な最新バージョンをインストールするように指示します。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageInstallMode\" xml:space=\"preserve\">\n    <value>必要に応じて使用するインストール モード。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageScope\" xml:space=\"preserve\">\n    <value>パッケージのターゲット スコープ。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionAcceptAgreements\" xml:space=\"preserve\">\n    <value>ソースとパッケージの契約に同意するかどうかを示します。</value>\n  </data>\n  <data name=\"DscUserSettingsFileShortDescription\" xml:space=\"preserve\">\n    <value>ユーザー設定ファイルを管理する</value>\n  </data>\n  <data name=\"DscUserSettingsFileLongDescription\" xml:space=\"preserve\">\n    <value>winget のユーザー設定を管理します。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionUserSettingsFileSettings\" xml:space=\"preserve\">\n    <value>設定 JSON ファイルの内容。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionUserSettingsFileAction\" xml:space=\"preserve\">\n    <value>設定の適用に使用されるアクション。</value>\n  </data>\n  <data name=\"CorrelationArgumentDescription\" xml:space=\"preserve\">\n    <value>相関関係のために値がログに記録されます</value>\n  </data>\n  <data name=\"DscSourceResourceShortDescription\" xml:space=\"preserve\">\n    <value>ソースの構成を管理する</value>\n  </data>\n  <data name=\"DscSourceResourceLongDescription\" xml:space=\"preserve\">\n    <value>winget のソースを管理します。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceName\" xml:space=\"preserve\">\n    <value>ソースに使用する名前。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceArgument\" xml:space=\"preserve\">\n    <value>ソースの引数。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceType\" xml:space=\"preserve\">\n    <value>ソースの種類。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceTrustLevel\" xml:space=\"preserve\">\n    <value>ソースの信頼レベル。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceExplicit\" xml:space=\"preserve\">\n    <value>呼び出しでソースが指定されていない場合にソースを含めるかどうか。</value>\n  </data>\n  <data name=\"ConfigurationApplyingUnit\" xml:space=\"preserve\">\n    <value>構成単位を適用しています...</value>\n  </data>\n  <data name=\"ConfigurationExportingUnit\" xml:space=\"preserve\">\n    <value>構成単位をエクスポートしています...</value>\n  </data>\n  <data name=\"ConfigurationGettingUnitProcessors\" xml:space=\"preserve\">\n    <value>構成単位プロセッサを取得しています...</value>\n  </data>\n  <data name=\"ConfigurationExportInstallRequiredModule\" xml:space=\"preserve\">\n    <value>エクスポートに必要なモジュールを確認する [{0}]</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportInstallRequiredModuleFailed\" xml:space=\"preserve\">\n    <value>必要なモジュールをテストまたは取得できませんでした。関連する設定はエクスポートされません。</value>\n  </data>\n  <data name=\"ConfigurationExportUnitStart\" xml:space=\"preserve\">\n    <value>エクスポート [{0}]</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportUnitFailed\" xml:space=\"preserve\">\n    <value>リソースをエクスポートできませんでした。</value>\n  </data>\n  <data name=\"ConfigurationExportFailedToGetUnitProcessors\" xml:space=\"preserve\">\n    <value>ユニット プロセッサを取得できませんでした。個々のパッケージ設定はエクスポートされません。</value>\n  </data>\n  <data name=\"OutputDirectoryArgumentDescription\" xml:space=\"preserve\">\n    <value>結果を書き込むディレクトリ</value>\n  </data>\n  <data name=\"ConfigurationInstallDscPackage\" xml:space=\"preserve\">\n    <value>Desired State Configuration パッケージがシステムに見つかりません。パッケージ... をインストールしています</value>\n  </data>\n  <data name=\"ConfigurationInstallDscPackageFailed\" xml:space=\"preserve\">\n    <value>Desired State Configuration パッケージをインストールできませんでした。パッケージを手動でインストールするか、引数を使用して dsc.exe するパス --processor-path 指定してください。</value>\n    <comment>{Locked=\"dsc.exe\",\"--processor-path\"}</comment>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionAdminSettingsSettings\" xml:space=\"preserve\">\n    <value>管理者の設定とその値を含むオブジェクトです。</value>\n  </data>\n  <data name=\"DscAdminSettingsResourceShortDescription\" xml:space=\"preserve\">\n    <value>管理者設定を管理する</value>\n  </data>\n  <data name=\"DscAdminSettingsResourceLongDescription\" xml:space=\"preserve\">\n    <value>winget の管理者設定を管理します。</value>\n  </data>\n  <data name=\"ResetAllAdminSettingsArgumentDescription\" xml:space=\"preserve\">\n    <value>すべての管理者設定をリセットする</value>\n  </data>\n  <data name=\"ResetAllAdminSettingsSucceeded\" xml:space=\"preserve\">\n    <value>すべての管理者設定がリセットされました。</value>\n  </data>\n  <data name=\"McpCommandShortDescription\" xml:space=\"preserve\">\n    <value>MCP 情報</value>\n    <comment>MCP stands for Model Context Protocol and should probably remain as-is</comment>\n  </data>\n  <data name=\"McpCommandLongDescription\" xml:space=\"preserve\">\n    <value>Windows パッケージ マネージャーの MCP (モデル コンテキスト プロトコル) 情報。</value>\n  </data>\n  <data name=\"McpConfigurationPreamble\" xml:space=\"preserve\">\n    <value>Windows パッケージ マネージャー MCP サーバーを MCP クライアントで手動で構成するには、`servers` オブジェクトで次の JSON フラグメントを使用します:</value>\n    <comment>{Locked=\"`servers`\"}\nMCP stands for Model Context Protocol and should probably remain as-is.\nAn unlocalized JSON fragment will follow on another line.</comment>\n  </data>\n  <data name=\"PolicyEnableMcpServer\" xml:space=\"preserve\">\n    <value>Windows パッケージ マネージャー MCP サーバーを有効にする</value>\n  </data>\n  <data name=\"OSVersionDescription\" xml:space=\"preserve\">\n    <value>ターゲット オペレーティング システムのバージョン</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>1 つ以上のフォントのインストールに失敗しました。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>フォント ファイルはサポートされていないため、インストールできません。</value>\n  </data>\n  <data name=\"FontFileNotSupported\" xml:space=\"preserve\">\n    <value>フォント パッケージ内の 1 つ以上のフォントがサポートされていないため、インストールできません。</value>\n  </data>\n  <data name=\"FontInstallFailed\" xml:space=\"preserve\">\n    <value>フォントのインストールに失敗しました。クリーンアップしています。</value>\n  </data>\n  <data name=\"FontAlreadyInstalled\" xml:space=\"preserve\">\n    <value>フォントは既にインストールされています。</value>\n  </data>\n  <data name=\"FontPackage\" xml:space=\"preserve\">\n    <value>パッケージ ID</value>\n  </data>\n  <data name=\"FontWinGetSupported\" xml:space=\"preserve\">\n    <value>WinGet がサポートされています</value>\n  </data>\n  <data name=\"FontTitle\" xml:space=\"preserve\">\n    <value>タイトル</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_FOUND\" xml:space=\"preserve\">\n    <value>フォント ファイルが見つかりません。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>フォントのアンインストールに失敗しました。フォントが正常な状態でない可能性があります。再起動後にアンインストールしてみてください。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>フォントの検証に失敗しました。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_ROLLBACK_FAILED\" xml:space=\"preserve\">\n    <value>フォントのロールバックに失敗しました。フォントが正常な状態でない可能性があります。再起動後にアンインストールしてみてください。</value>\n  </data>\n  <data name=\"FontDetailsArgumentDescription\" xml:space=\"preserve\">\n    <value>フォント ファイルの詳細情報を表示します。</value>\n  </data>\n  <data name=\"FontValidationFailed\" xml:space=\"preserve\">\n    <value>フォント パッケージの検証に失敗しました。</value>\n  </data>\n  <data name=\"FontRollbackFailed\" xml:space=\"preserve\">\n    <value>失敗したフォントのインストールのロールバックに失敗しました。フォントを正常にアンインストールするには、再起動が必要な場合があります。</value>\n  </data>\n  <data name=\"FontUninstallFailed\" xml:space=\"preserve\">\n    <value>フォント パッケージのアンインストールに失敗しました。多くの場合、フォントがシステムまたはアプリケーションによって使用されていることが原因です。コンピューターの再起動後にアンインストールが正常に完了する可能性があります。</value>\n  </data>\n  <data name=\"FontStatusOK\" xml:space=\"preserve\">\n    <value>OK</value>\n    <comment>\"OK\" means the font is in a good healthy state</comment>\n  </data>\n  <data name=\"FontStatusCorrupt\" xml:space=\"preserve\">\n    <value>破損</value>\n    <comment>\"Corrupt\" refers to an install that is in a corrupted or bad state, and needs repair.</comment>\n  </data>\n  <data name=\"FontStatus\" xml:space=\"preserve\">\n    <value>状態</value>\n  </data>\n  <data name=\"FontStatusUnknown\" xml:space=\"preserve\">\n    <value>不明</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>フォント パッケージは既にインストールされています。</value>\n  </data>\n  <data name=\"ListDetailsArgumentDescription\" xml:space=\"preserve\">\n    <value>パッケージに関する詳細情報を表示します</value>\n    <comment>Providing this argument causes the CLI to output additional details about installed application packages.</comment>\n  </data>\n  <data name=\"ShowLabelChannel\" xml:space=\"preserve\">\n    <value>チャネル:</value>\n    <comment>Precedes a string value that names the delivery channel for the software package (ex. stable, beta).</comment>\n  </data>\n  <data name=\"ShowListLocalIdentifier\" xml:space=\"preserve\">\n    <value>ローカル識別子:</value>\n    <comment>Precedes a value that is the unique identifier for the installed package on the local system.</comment>\n  </data>\n  <data name=\"ShowListPackageFamilyName\" xml:space=\"preserve\">\n    <value>パッケージ ファミリ名:</value>\n    <comment>Precedes a value that is the APPX/MSIX package family name of the installed package.</comment>\n  </data>\n  <data name=\"ShowListProductCode\" xml:space=\"preserve\">\n    <value>製品コード:</value>\n    <comment>Precedes a value that is the Add/Remove Programs identifier in the registry. This is also the Product Code value as defined in MSI installers.</comment>\n  </data>\n  <data name=\"ShowListUpgradeCode\" xml:space=\"preserve\">\n    <value>アップグレード コード:</value>\n    <comment>Precedes a value that is the MSI Upgrade Code for the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledScope\" xml:space=\"preserve\">\n    <value>インストール スコープ:</value>\n    <comment>Precedes a value that is the scope of the installation of the package (ex. user, machine).</comment>\n  </data>\n  <data name=\"ShowListInstalledArchitecture\" xml:space=\"preserve\">\n    <value>インストールされたアーキテクチャ:</value>\n    <comment>Precedes a value that is the installed architecture of the package (ex. x86, x64, ARM64).</comment>\n  </data>\n  <data name=\"ShowListInstalledLocale\" xml:space=\"preserve\">\n    <value>インストール ロケール:</value>\n    <comment>Precedes a value that is the locale of the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledLocation\" xml:space=\"preserve\">\n    <value>インストール場所:</value>\n    <comment>Precedes a value that is the directory path to the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledSource\" xml:space=\"preserve\">\n    <value>ソース提供元:</value>\n    <comment>Precedes a value that names the package source where the installed package originated from.</comment>\n  </data>\n  <data name=\"ShowListAvailableUpgrades\" xml:space=\"preserve\">\n    <value>利用可能なアップグレード:</value>\n    <comment>Precedes a list of package upgrades available for the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstallerCategory\" xml:space=\"preserve\">\n    <value>インストーラー カテゴリ:</value>\n    <comment>Precedes a value that indicates the category of the installer for the installed package (ex. exe, msi, msix).</comment>\n  </data>\n  <data name=\"SourceEditOldValue\" xml:space=\"preserve\">\n    <value>古い値</value>\n    <comment>Column title for listing edit changes.</comment>\n  </data>\n  <data name=\"SourceEditNewValue\" xml:space=\"preserve\">\n    <value>新しい値</value>\n    <comment>Column title for listing the new value.</comment>\n  </data>\n</root>"
  },
  {
    "path": "Localization/Resources/ko-KR/Resources.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "Localization/Resources/ko-KR/winget.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"AdjoinedNotFlagError\" xml:space=\"preserve\">\n    <value>근접한 별칭이 플래그가 아님: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an adjoined alias that is not a flag argument. {0} is a placeholder replaced by the user input argument (e.g. '-ab').</comment>\n  </data>\n  <data name=\"AdjoinedNotFoundError\" xml:space=\"preserve\">\n    <value>근접한 플래그 별칭 찾을 수 없음: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an adjoined flag alias argument that was not found. {0} is a placeholder replaced by the user input argument (e.g. '-ab').</comment>\n  </data>\n  <data name=\"AvailableArguments\" xml:space=\"preserve\">\n    <value>다음 인수를 사용할 수 있음</value>\n    <comment>Message displayed to inform the user about the available command line arguments.</comment>\n  </data>\n  <data name=\"AvailableCommandAliases\" xml:space=\"preserve\">\n    <value>다음 명령 별칭을 사용할 수 있습니다.</value>\n    <comment>Message displayed to inform the user about the available command line alias arguments.</comment>\n  </data>\n  <data name=\"AvailableCommands\" xml:space=\"preserve\">\n    <value>다음 명령을 사용할 수 있음</value>\n    <comment>Title displayed to inform the user about the available commands.</comment>\n  </data>\n  <data name=\"AvailableHeader\" xml:space=\"preserve\">\n    <value>사용 가능</value>\n    <comment>As in \"a new version is available to upgrade to\".</comment>\n  </data>\n  <data name=\"AvailableOptions\" xml:space=\"preserve\">\n    <value>다음 선택 사항을 사용할 수 있음</value>\n    <comment>Message displayed to inform the user about the available options.</comment>\n  </data>\n  <data name=\"AvailableSubcommands\" xml:space=\"preserve\">\n    <value>다음 부명령어는 사용 할 수 없음</value>\n    <comment>Message displayed to inform the user about the available nested commands that run in context of the selected command.</comment>\n  </data>\n  <data name=\"AvailableUpgrades\" xml:space=\"preserve\">\n    <value>{0} 업그레이드를 사용할 수 있습니다.</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about available package upgrades. {0} is a placeholder replaced by the number of package upgrades.</comment>\n  </data>\n  <data name=\"ChannelArgumentDescription\" xml:space=\"preserve\">\n    <value>지정된 채널을 사용합니다(기본값은 일반 대상).</value>\n  </data>\n  <data name=\"Command\" xml:space=\"preserve\">\n    <value>명령</value>\n    <comment>Label displayed for a command to give the software.</comment>\n  </data>\n  <data name=\"CommandArgumentDescription\" xml:space=\"preserve\">\n    <value>명령을 기준으로 결과 필터링</value>\n    <comment>Description message displayed to inform the user about filtering the search results by a package command.</comment>\n  </data>\n  <data name=\"CommandLineArgumentDescription\" xml:space=\"preserve\">\n    <value>완료에 대한 전체 명령줄</value>\n  </data>\n  <data name=\"CommandRequiresAdmin\" xml:space=\"preserve\">\n    <value>이 명령을 실행하려면 관리자 권한이 필요합니다.</value>\n  </data>\n  <data name=\"CompleteCommandLongDescription\" xml:space=\"preserve\">\n    <value>이 명령은 상황에 맞는 명령줄 완료를 요청하는 데 사용할 수 있습니다. 명령줄, 커서 위치 및 완료 할 단어가 전달됩니다. 출력은 입력을 기반으로 한 잠재적 값의 집합으로 한 줄당 하나의 값이 가능합니다.</value>\n  </data>\n  <data name=\"CompleteCommandShortDescription\" xml:space=\"preserve\">\n    <value>컨텍스트에 중요한 명령줄 완료를 사용합니다.</value>\n  </data>\n  <data name=\"CountArgumentDescription\" xml:space=\"preserve\">\n    <value>지정된 수의 결과만 표시(1~1000 사이)</value>\n  </data>\n  <data name=\"Done\" xml:space=\"preserve\">\n    <value>완료</value>\n    <comment>Label displayed when an operation completes or is done executing.</comment>\n  </data>\n  <data name=\"ExactArgumentDescription\" xml:space=\"preserve\">\n    <value>정확한 일치를 사용하여 패키지를 찾습니다.</value>\n    <comment>Description message displayed to inform the user about finding an application package using an exact matching criteria.</comment>\n  </data>\n  <data name=\"ExperimentalArgumentDescription\" xml:space=\"preserve\">\n    <value>데모용 실험 인수</value>\n  </data>\n  <data name=\"ExperimentalCommandLongDescription\" xml:space=\"preserve\">\n    <value>이 명령은 실험적 기능을 구현하는 방법에 대한 예입니다. 'winget settings'으로 이동하여 experimentalCmd 또는 experimentalArg 기능을 사용하려면</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"ExperimentalCommandShortDescription\" xml:space=\"preserve\">\n    <value>실험적 기능 예</value>\n  </data>\n  <data name=\"ExtraPositionalError\" xml:space=\"preserve\">\n    <value>필요한 인수가 없을 때 위치 인수를 찾았습니다. '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an extra positional argument when none was expected. {0} is a placeholder replaced by the user's extra argument input.</comment>\n  </data>\n  <data name=\"FeatureDisabledMessage\" xml:space=\"preserve\">\n    <value>이 기능은 진행 중인 작업이며, 향후 크게 변경되거나 모두 제거될 수 있습니다. 사용하도록 설정하려면 설정('winget settings')을 편집하여 실험적 기능을 포함하세요. '{0}'</value>\n    <comment>{Locked=\"winget settings\",\"{0}\"}. Error message displayed when the user uses an experimental feature that is disabled. {0} is a placeholder replaced by the experimental feature name.</comment>\n  </data>\n  <data name=\"FeaturesCommandLongDescription\" xml:space=\"preserve\">\n    <value>실험적 기능의 상태를 표시합니다. 'winget settings' 통해 실험적 기능을 켤 수 있습니다.</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"FeaturesCommandShortDescription\" xml:space=\"preserve\">\n    <value>실험적 기능의 상태 표시</value>\n  </data>\n  <data name=\"FeaturesDisabled\" xml:space=\"preserve\">\n    <value>사용 안 함</value>\n  </data>\n  <data name=\"FeaturesEnabled\" xml:space=\"preserve\">\n    <value>사용</value>\n  </data>\n  <data name=\"FeaturesFeature\" xml:space=\"preserve\">\n    <value>기능</value>\n  </data>\n  <data name=\"FeaturesLink\" xml:space=\"preserve\">\n    <value>링크</value>\n  </data>\n  <data name=\"FeaturesMessage\" xml:space=\"preserve\">\n    <value>다음 실험적 기능이 진행 중입니다.\n설정 파일 'winget settings'을 통해 설정을 구성할 수 있습니다.</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"FeaturesProperty\" xml:space=\"preserve\">\n    <value>속성</value>\n  </data>\n  <data name=\"FeaturesStatus\" xml:space=\"preserve\">\n    <value>상태</value>\n  </data>\n  <data name=\"FileArgumentDescription\" xml:space=\"preserve\">\n    <value>해시할 파일</value>\n  </data>\n  <data name=\"FlagContainAdjoinedError\" xml:space=\"preserve\">\n    <value>플래그 인수는 근접하는 값을 포함할 수 없음: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a flag argument containing an unexpected adjoined value. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"HashCommandLongDescription\" xml:space=\"preserve\">\n    <value>매니페스트에 삽입하기에 적합한 로컬 파일의 해시를 계산합니다. 또한 MSIX 패키지의 서명 파일의 해시를 계산하여 스트리밍 설치를 사용하도록 할 수도 있습니다.</value>\n  </data>\n  <data name=\"HashCommandShortDescription\" xml:space=\"preserve\">\n    <value>해시 설치 관리자 파일 도우미</value>\n  </data>\n  <data name=\"HelpArgumentDescription\" xml:space=\"preserve\">\n    <value>선택한 명령에 대한 도움말을 표시</value>\n  </data>\n  <data name=\"HelpForDetails\" xml:space=\"preserve\">\n    <value>특정 명령에 대한 자세한 내용을 보려면 도움말 인수에 해당 명령을 전달합니다.</value>\n  </data>\n  <data name=\"HelpLinkPreamble\" xml:space=\"preserve\">\n    <value>자세한 도움말은 다음의 위치에서 찾아볼 수 있음: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a link where they can learn more about the subject context. {0} is a placeholder replaced by a website address.</comment>\n  </data>\n  <data name=\"IdArgumentDescription\" xml:space=\"preserve\">\n    <value>ID를 기준으로 결과 필터링</value>\n  </data>\n  <data name=\"IgnoreWarningsArgumentDescription\" xml:space=\"preserve\">\n    <value>경고 출력을 표시하지 않습니다.</value>\n  </data>\n  <data name=\"InstallationDisclaimer1\" xml:space=\"preserve\">\n    <value>이 응용 프로그램의 라이선스는 그 소유자가 사용자에게 부여했습니다.</value>\n  </data>\n  <data name=\"InstallationDisclaimer2\" xml:space=\"preserve\">\n    <value>Microsoft는 타사 패키지에 대한 책임을 지지 않고 라이선스를 부여하지도 않습니다.</value>\n  </data>\n  <data name=\"InstallationDisclaimerMSStore\" xml:space=\"preserve\">\n    <value>이 패키지는 Microsoft Store를 통해 제공됩니다. winget은 현재 사용자를 대신하여 Microsoft Store에서 패키지를 가져와야 할 수 있습니다.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"InstallCommandLongDescription\" xml:space=\"preserve\">\n    <value>구성된 원본을 검색하여 찾거나 매니페스트에서 직접 선택한 패키지를 설치합니다. 기본적으로 쿼리는 대소문자를 구분하지 않고 패키지의 id, 이름 (name) 또는 모니커와 (moniker) 일치해야 합니다. 다른 필드는 적절한 옵션을 전달하여 사용할 수 있습니다. 기본적으로 install 명령은 패키지 설치 상태를 확인하고 해당되는 경우 업그레이드를 시도합니다. 직접 설치를 수행하려면 --force로 재정의하세요.</value>\n    <comment>{Locked=\"--force\"}; id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"InstallCommandShortDescription\" xml:space=\"preserve\">\n    <value>지정된 패키지를 설치합니다.</value>\n  </data>\n  <data name=\"InstallerHashMismatchAdminBlock\" xml:space=\"preserve\">\n    <value>설치 관리자 해시가 일치하지 않습니다. 관리자로 실행할 경우 이 설정을 무시할 수 없습니다.</value>\n  </data>\n  <data name=\"InstallerHashMismatchOverridden\" xml:space=\"preserve\">\n    <value>설치 프로그램 해시가 일치하지 않습니다. --ignore-security-hash로 인한 진행</value>\n    <comment>{Locked=\"--ignore-security-hash\"}</comment>\n  </data>\n  <data name=\"InstallerHashMismatchOverrideRequired\" xml:space=\"preserve\">\n    <value>설치 프로그램 해시가 일치하지 않습니다. 이 검사를 무시하려면 --ignore-security-hash를 사용하세요.</value>\n    <comment>{Locked=\"--ignore-security-hash\"}</comment>\n  </data>\n  <data name=\"InstallerHashVerified\" xml:space=\"preserve\">\n    <value>설치 관리자 해시를 확인했습니다.</value>\n  </data>\n  <data name=\"InstallFlowInstallSuccess\" xml:space=\"preserve\">\n    <value>설치 성공</value>\n  </data>\n  <data name=\"InstallFlowStartingPackageInstall\" xml:space=\"preserve\">\n    <value>패키지 설치를 시작하는 중...</value>\n  </data>\n  <data name=\"HashOverrideArgumentDescription\" xml:space=\"preserve\">\n    <value>설치 관리자 해시 확인 실패 무시</value>\n  </data>\n  <data name=\"IgnoreLocalArchiveMalwareScanArgumentDescription\" xml:space=\"preserve\">\n    <value>로컬 매니페스트에서 보관 유형 패키지를 설치하는 동안 수행된 맬웨어 검색 무시</value>\n  </data>\n  <data name=\"InteractiveArgumentDescription\" xml:space=\"preserve\">\n    <value>대화형 설치를 요청합니다(사용자 입력이 필요할 수 있음).</value>\n  </data>\n  <data name=\"InvalidAliasError\" xml:space=\"preserve\">\n    <value>현재 명령에 대해 인수 별칭을 인식할 수 없음: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a command line argument alias that was not recognized for a selected command. {0} is a placeholder replaced by the user's argument alias input (e.g. '-a').</comment>\n  </data>\n  <data name=\"InvalidArgumentSpecifierError\" xml:space=\"preserve\">\n    <value>유효하지 않은 인수 특정자: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an invalid argument specifier. {0} is a placeholder replaced by an argument specifier (e.g. '-').</comment>\n  </data>\n  <data name=\"InvalidNameError\" xml:space=\"preserve\">\n    <value>현재 명령에 대해 인수 이름을 인식할 수 없음: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an unrecognized command line argument name for the selected command. {0} is a placeholder replaced by the user's argument name input (e.g. '--example').</comment>\n  </data>\n  <data name=\"KeyDirectoriesHeader\" xml:space=\"preserve\">\n    <value>Winget 디렉터리</value>\n    <comment>Header for a table detailing the directories Winget uses for key operations like logging and portable installs</comment>\n  </data>\n  <data name=\"LocaleArgumentDescription\" xml:space=\"preserve\">\n    <value>사용할 로캘(BCP47 형식)</value>\n    <comment>{Locked=\"BCP47\"}</comment>\n  </data>\n  <data name=\"LicenseAgreement\" xml:space=\"preserve\">\n    <value>라이선스 계약</value>\n  </data>\n  <data name=\"Links\" xml:space=\"preserve\">\n    <value>링크</value>\n    <comment>Links to different webpages</comment>\n  </data>\n  <data name=\"ListCommandLongDescription\" xml:space=\"preserve\">\n    <value>list 명령은 시스템에 설치된 패키지를 표시하거나 업그레이드를 사용할 수 있는지 여부를 표시합니다. search 명령과 같이 출력을 필터링하는 데 추가 옵션을 제공할 수 도 있습니다.</value>\n    <comment>{Locked=\"list\",\"search\"}</comment>\n  </data>\n  <data name=\"ListCommandShortDescription\" xml:space=\"preserve\">\n    <value>설치된 패키지 표시</value>\n  </data>\n  <data name=\"LocationArgumentDescription\" xml:space=\"preserve\">\n    <value>설치할 위치(지원되는 경우)</value>\n  </data>\n  <data name=\"LogArgumentDescription\" xml:space=\"preserve\">\n    <value>로그 위치(지원되는 경우)</value>\n  </data>\n  <data name=\"MainCopyrightNotice\" xml:space=\"preserve\">\n    <value>Copyright (c) Microsoft Corporation. All rights reserved.</value>\n  </data>\n  <data name=\"MainHomepage\" xml:space=\"preserve\">\n    <value>홈페이지</value>\n    <comment>The primary webpage for the software</comment>\n  </data>\n  <data name=\"ManifestArgumentDescription\" xml:space=\"preserve\">\n    <value>패키지의 매니페스트 경로</value>\n  </data>\n  <data name=\"ManifestValidationFail\" xml:space=\"preserve\">\n    <value>매니페스트 유효성 검사에 실패했습니다.</value>\n  </data>\n  <data name=\"ManifestValidationSuccess\" xml:space=\"preserve\">\n    <value>매니페스트 유효성 검사에 성공했습니다.</value>\n  </data>\n  <data name=\"ManifestValidationWarning\" xml:space=\"preserve\">\n    <value>매니페스트 유효성 검사에 성공했으나 경고가 발생했습니다.</value>\n  </data>\n  <data name=\"MissingArgumentError\" xml:space=\"preserve\">\n    <value>인수 값이 필수이지만 아무것도 찾지 못했음: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user does not provide a required command line argument value. {0} is a placeholder replaced by the argument name.</comment>\n  </data>\n  <data name=\"MonikerArgumentDescription\" xml:space=\"preserve\">\n    <value>결과를 모니커로 필터링합니다.</value>\n  </data>\n  <data name=\"MsixArgumentDescription\" xml:space=\"preserve\">\n    <value>입력 파일이 msix로 처리됩니다. (서명된 경우 서명 해시가 제공됨)</value>\n  </data>\n  <data name=\"MsixSignatureHashFailed\" xml:space=\"preserve\">\n    <value>MSIX 서명 해시를 계산하지 못했습니다.</value>\n  </data>\n  <data name=\"MSStoreAppBlocked\" xml:space=\"preserve\">\n    <value>정책에 의해 특정 앱이 차단되어 Microsoft Store 패키지를 설치하거나 업그레이드하지 못했습니다.</value>\n  </data>\n  <data name=\"MSStoreInstallOrUpdateFailed\" xml:space=\"preserve\">\n    <value>Microsoft Store 패키지를 설치하거나 업그레이드하지 못했습니다. 오류 코드: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Microsoft Store application package fails to install or upgrade. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"MSStoreStoreClientBlocked\" xml:space=\"preserve\">\n    <value>Microsoft Store 클라이언트가 정책에 의해 차단되어 Microsoft Store 패키지를 설치 또는 업그레이드하지 못했습니다.</value>\n  </data>\n  <data name=\"MSStoreInstallTryGetEntitlement\" xml:space=\"preserve\">\n    <value>패키지 획득을 확인/요청하는 중..</value>\n  </data>\n  <data name=\"MultipleInstalledPackagesFound\" xml:space=\"preserve\">\n    <value>입력 기준과 일치하는 여러 개의 패키지를 찾았습니다. 입력을 구체화하십시오.</value>\n  </data>\n  <data name=\"MultiplePackagesFound\" xml:space=\"preserve\">\n    <value>입력 조건과 일치하는 패키지가 여러 개 있습니다. 입력을 구체화하십시오.</value>\n  </data>\n  <data name=\"NameArgumentDescription\" xml:space=\"preserve\">\n    <value>이름을 기준으로 결과 필터링</value>\n  </data>\n  <data name=\"NoApplicableInstallers\" xml:space=\"preserve\">\n    <value>적용 가능한 설치 관리자를 찾을 수 없습니다. 자세한 내용은 로그를 참조하십시오.</value>\n  </data>\n  <data name=\"NoExperimentalFeaturesMessage\" xml:space=\"preserve\">\n    <value>현재 사용 가능한 실험적 기능이 없습니다. </value>\n  </data>\n  <data name=\"NoInstalledPackageFound\" xml:space=\"preserve\">\n    <value>입력 조건과 일치하는 설치된 패키지를 찾을 수 없습니다.</value>\n  </data>\n  <data name=\"NoPackageFound\" xml:space=\"preserve\">\n    <value>입력 조건과 일치하는 패키지를 찾을 수 없습니다.</value>\n  </data>\n  <data name=\"NoVTArgumentDescription\" xml:space=\"preserve\">\n    <value>VirtualTerminal 표시를 사용 안 함</value>\n    <comment>{Locked=\"VirtualTerminal\"}</comment>\n  </data>\n  <data name=\"OpenLogsArgumentDescription\" xml:space=\"preserve\">\n    <value>기본 로그 위치 열기</value>\n  </data>\n  <data name=\"Options\" xml:space=\"preserve\">\n    <value>옵션</value>\n    <comment>Options to change how a command works</comment>\n  </data>\n  <data name=\"OverrideArgumentDescription\" xml:space=\"preserve\">\n    <value>설치 관리자에 전달할 인수 재정의</value>\n  </data>\n  <data name=\"Package\" xml:space=\"preserve\">\n    <value>패키지: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for a software package. {0} is a placeholder replaced by the software package name.</comment>\n  </data>\n  <data name=\"PendingWorkError\" xml:space=\"preserve\">\n    <value>죄송합니다 .작업 수행을 하지 못했습니다.</value>\n  </data>\n  <data name=\"PositionArgumentDescription\" xml:space=\"preserve\">\n    <value>명령줄 내의 커서 위치</value>\n  </data>\n  <data name=\"PrivacyStatement\" xml:space=\"preserve\">\n    <value>개인정보처리방침</value>\n  </data>\n  <data name=\"QueryArgumentDescription\" xml:space=\"preserve\">\n    <value>패키지를 검색하는 데 사용되는 쿼리</value>\n  </data>\n  <data name=\"RainbowArgumentDescription\" xml:space=\"preserve\">\n    <value>여러 가지 무지개의 색깔로 진행률 표시</value>\n  </data>\n  <data name=\"RequiredArgError\" xml:space=\"preserve\">\n    <value>필수 인수가 제공 되지 않음: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user does not provide a required command line argument. {0} is a placeholder replaced by an argument name.</comment>\n  </data>\n  <data name=\"RetroArgumentDescription\" xml:space=\"preserve\">\n    <value>기본 색깔로 진행률 표시</value>\n  </data>\n  <data name=\"SearchCommandLongDescription\" xml:space=\"preserve\">\n    <value>구성된 원본에서 패키지를 검색합니다.</value>\n  </data>\n  <data name=\"SearchCommandShortDescription\" xml:space=\"preserve\">\n    <value>패키지의 기본 정보를 찾아 표시</value>\n  </data>\n  <data name=\"SearchId\" xml:space=\"preserve\">\n    <value>장치 ID</value>\n    <comment>Abbreviation of Identifier.</comment>\n  </data>\n  <data name=\"SearchMatch\" xml:space=\"preserve\">\n    <value>일치</value>\n  </data>\n  <data name=\"SearchName\" xml:space=\"preserve\">\n    <value>이름</value>\n  </data>\n  <data name=\"SearchSource\" xml:space=\"preserve\">\n    <value>원본</value>\n  </data>\n  <data name=\"SearchTruncated\" xml:space=\"preserve\">\n    <value>결과 한도로 잘렸습니다.</value>\n  </data>\n  <data name=\"SearchVersion\" xml:space=\"preserve\">\n    <value>버전</value>\n  </data>\n  <data name=\"SettingLoadFailure\" xml:space=\"preserve\">\n    <value>설정의 유효성을 확인하는 동안 다음 오류가 발견되었습니다.</value>\n  </data>\n  <data name=\"SettingsCommandLongDescription\" xml:space=\"preserve\">\n    <value>기본 json 텍스트 편집기에서 설정을 엽니다. 편집기를 구성하지 않은 경우 메모장에서 설정을 엽니다. 사용 가능한 설정은 https://aka.ms/winget-settings를 참조하세요. 이 명령은 --enable 또는 --disable 함 인수를 제공하여 관리자 설정을 설정하는 데도 사용할 수 있습니다.</value>\n    <comment>{Locked=\"--enable\"} {Locked=\"--disable\"}</comment>\n  </data>\n  <data name=\"SettingsCommandShortDescription\" xml:space=\"preserve\">\n    <value>설정 열기 또는 관리자 설정 설정</value>\n  </data>\n  <data name=\"SettingsWarnings\" xml:space=\"preserve\">\n    <value>설정을 로드하는 동안 예기치 않은 오류가 발생했습니다. 'settings' 명령을 실행하여 설정을 확인하세요.</value>\n    <comment>{Locked=\"'settings'\"}</comment>\n  </data>\n  <data name=\"ShowChannel\" xml:space=\"preserve\">\n    <value>채널</value>\n  </data>\n  <data name=\"ShowCommandLongDescription\" xml:space=\"preserve\">\n    <value>특정 패키지에 대한 정보를 표시합니다. 기본적으로 쿼리는 패키지의 ID, 이름 또는 모양과 대/소문자를 구분하지 않는 다섯 번이 어려져야 합니다. 적절한 옵션을 전달하여 다른 필드를 사용할 수 있습니다.</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"ShowCommandShortDescription\" xml:space=\"preserve\">\n    <value>패키지에 대한 정보 표시</value>\n  </data>\n  <data name=\"ShowVersion\" xml:space=\"preserve\">\n    <value>버전</value>\n  </data>\n  <data name=\"SilentArgumentDescription\" xml:space=\"preserve\">\n    <value>무인 설치 요청</value>\n  </data>\n  <data name=\"SingleCharAfterDashError\" xml:space=\"preserve\">\n    <value>단일 문자 별칭만이 단일- 후에 나타남: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides more than a single character command line alias argument after an alias argument specifier '-'. {0} is a placeholder replaced by the user's argument input.</comment>\n  </data>\n  <data name=\"SourceAddAlreadyExistsDifferentArg\" xml:space=\"preserve\">\n    <value>지정한 이름의 원본이 이미 있으며 다른 위치를 참조합니다.</value>\n  </data>\n  <data name=\"SourceAddAlreadyExistsDifferentName\" xml:space=\"preserve\">\n    <value>원본이 다른 이름의 위치를 이미 참조합니다.</value>\n  </data>\n  <data name=\"SourceAddAlreadyExistsMatch\" xml:space=\"preserve\">\n    <value>지정한 이름의 소스가 이미 있으며 다음과 같이 동일한 위치를 참조합니다.</value>\n  </data>\n  <data name=\"SourceAddBegin\" xml:space=\"preserve\">\n    <value>원본을 추가하는 중:</value>\n  </data>\n  <data name=\"SourceAddCommandLongDescription\" xml:space=\"preserve\">\n    <value>새 원본을 추가합니다. 원본은 패키지를 검색하고 설치할 수 있는 데이터를 제공합니다. 새 원본을 보안 위치로 신뢰하는 경우에만 새 원본을 추가합니다.</value>\n  </data>\n  <data name=\"SourceAddCommandShortDescription\" xml:space=\"preserve\">\n    <value>새 원본 추가</value>\n  </data>\n  <data name=\"SourceArgArgumentDescription\" xml:space=\"preserve\">\n    <value>원본에 지정된 인수</value>\n  </data>\n  <data name=\"SourceArgumentDescription\" xml:space=\"preserve\">\n    <value>지정한 원본을 사용하여 패키지를 찾습니다.</value>\n  </data>\n  <data name=\"SourceCommandLongDescription\" xml:space=\"preserve\">\n    <value>하위 명령을 사용하여 원본을 관리합니다. 원본은 패키지를 검색하고 설치할 수 있는 데이터를 제공합니다. 새 원본을 보안 위치로 신뢰하는 경우에만 새 원본을 추가합니다.</value>\n  </data>\n  <data name=\"SourceCommandShortDescription\" xml:space=\"preserve\">\n    <value>패키지 원본 관리</value>\n  </data>\n  <data name=\"SourceEditCommandLongDescription\" xml:space=\"preserve\">\n    <value>기존 원본의 속성을 편집합니다. 원본은 패키지를 검색하고 설치하는 데 사용할 데이터를 제공합니다.</value>\n  </data>\n  <data name=\"SourceEditCommandShortDescription\" xml:space=\"preserve\">\n    <value>소스 속성 편집</value>\n  </data>\n  <data name=\"SourceEditOne\" xml:space=\"preserve\">\n    <value>소스 편집 중: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being edited. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceEditNoChanges\" xml:space=\"preserve\">\n    <value>이름이 '{0}' 원본이 이미 원하는 상태에 있습니다.</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being edited. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceListArg\" xml:space=\"preserve\">\n    <value>인수</value>\n    <comment>Value given to source.</comment>\n  </data>\n  <data name=\"SourceListCommandLongDescription\" xml:space=\"preserve\">\n    <value>현재의 모든 원본 또는 특정 원본의 전체 세부 정보를 목록에 추가합니다.</value>\n  </data>\n  <data name=\"SourceListCommandShortDescription\" xml:space=\"preserve\">\n    <value>현재의 원본을 목록에 추가</value>\n  </data>\n  <data name=\"SourceListData\" xml:space=\"preserve\">\n    <value>데이터</value>\n    <comment>Data stored by the source.</comment>\n  </data>\n  <data name=\"SourceListField\" xml:space=\"preserve\">\n    <value>필드</value>\n    <comment>The name of a piece of information about a source.</comment>\n  </data>\n  <data name=\"SourceListName\" xml:space=\"preserve\">\n    <value>이름</value>\n    <comment>The name of the source.</comment>\n  </data>\n  <data name=\"SourceListIdentifier\" xml:space=\"preserve\">\n    <value>식별자</value>\n    <comment>The source's unique identifier.</comment>\n  </data>\n  <data name=\"SourceListNoneFound\" xml:space=\"preserve\">\n    <value>다음 이름의 원본을 찾지 못함: {0}</value>\n    <comment>Error message displayed when the user provides a repository source name that was not found. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"SourceListNoSources\" xml:space=\"preserve\">\n    <value>구성된 원본이 없습니다.</value>\n  </data>\n  <data name=\"SourceListType\" xml:space=\"preserve\">\n    <value>유형</value>\n    <comment>The kind of source.</comment>\n  </data>\n  <data name=\"SourceListUpdated\" xml:space=\"preserve\">\n    <value>업데이트됨</value>\n    <comment>The last time the source was updated.</comment>\n  </data>\n  <data name=\"SourceListUpdatedNever\" xml:space=\"preserve\">\n    <value>사용 안 함</value>\n    <comment>The source has never been updated.</comment>\n  </data>\n  <data name=\"SourceListValue\" xml:space=\"preserve\">\n    <value>값</value>\n    <comment>The value of information about a source.</comment>\n  </data>\n  <data name=\"SourceNameArgumentDescription\" xml:space=\"preserve\">\n    <value>원본의 이름</value>\n  </data>\n  <data name=\"SourceOpenFailedSuggestion\" xml:space=\"preserve\">\n    <value>소스를 열 때 실패했습니다. 문제가 계속되면 'source reset' 명령을 사용해 보십시오.</value>\n    <comment>{Locked=\"source reset\"}</comment>\n  </data>\n  <data name=\"SourceOpenPredefinedFailedSuggestion\" xml:space=\"preserve\">\n    <value>미리 정의된 출처를 열지 못했습니다. 유지 관리 winget 신고하세요.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"SourceRemoveAll\" xml:space=\"preserve\">\n    <value>모든 원본을 제거하는 중...</value>\n  </data>\n  <data name=\"SourceRemoveCommandLongDescription\" xml:space=\"preserve\">\n    <value>특정 원본을 제거합니다.</value>\n  </data>\n  <data name=\"SourceRemoveCommandShortDescription\" xml:space=\"preserve\">\n    <value>현재의 원본 제거</value>\n  </data>\n  <data name=\"SourceRemoveOne\" xml:space=\"preserve\">\n    <value>출처를 제거하는 중: {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being removed. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceResetAll\" xml:space=\"preserve\">\n    <value>모든 원본... 다시 설정</value>\n  </data>\n  <data name=\"SourceResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>이 명령은 기존 원본을 삭제하고, 잠정적으로 로컬 데이터는 그대로 둡니다. 인수가 없으면 모든 원본이 삭제되고 기본값이 추가됩니다. 명명된 원본이 제공되는 경우, 해당 원본만 삭제됩니다.</value>\n  </data>\n  <data name=\"SourceResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>원본 재설정</value>\n  </data>\n  <data name=\"SourceResetForceArgumentDescription\" xml:space=\"preserve\">\n    <value>원본을 강제로 초기화</value>\n  </data>\n  <data name=\"SourceResetListAndOverridePreamble\" xml:space=\"preserve\">\n    <value>--force 옵션을 지정하면 다음 원본이 다시 설정됩니다.</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"SourceResetOne\" xml:space=\"preserve\">\n    <value>원본을 다시 설정하는 중: {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a repository source that is currently being reset. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceTypeArgumentDescription\" xml:space=\"preserve\">\n    <value>원본의 형식</value>\n  </data>\n  <data name=\"SourceUpdateAll\" xml:space=\"preserve\">\n    <value>모든 원본을 업데이트 중...</value>\n  </data>\n  <data name=\"SourceUpdateCommandLongDescription\" xml:space=\"preserve\">\n    <value>모든 원본 또는 특정 원본만을 업데이트합니다.</value>\n  </data>\n  <data name=\"SourceUpdateCommandShortDescription\" xml:space=\"preserve\">\n    <value>현재의 원본을 업데이트</value>\n  </data>\n  <data name=\"SourceUpdateOne\" xml:space=\"preserve\">\n    <value>원본 업데이트 중: {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being updated. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"TagArgumentDescription\" xml:space=\"preserve\">\n    <value>태그를 기준으로 결과 필터링</value>\n  </data>\n  <data name=\"ThankYou\" xml:space=\"preserve\">\n    <value>위젯을 이용해 주셔서 감사합니다</value>\n  </data>\n  <data name=\"ThirdPartSoftwareNotices\" xml:space=\"preserve\">\n    <value>타사 통지 사항</value>\n  </data>\n  <data name=\"ToolDescription\" xml:space=\"preserve\">\n    <value>원넷 명령줄 유틸리티를 사용하면 명령줄에서 응용 프로그램 및 기타 패키지를 설치할 수 있습니다.</value>\n  </data>\n  <data name=\"ToolInfoArgumentDescription\" xml:space=\"preserve\">\n    <value>도구의 일반 정보를 표시</value>\n  </data>\n  <data name=\"ToolVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>도구의 버전을 표시</value>\n  </data>\n  <data name=\"TooManyArgError\" xml:space=\"preserve\">\n    <value>인수가 허용 되는 횟수보다 더 많이 제공 됨: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a command line argument more times than it is allowed. {0} is a placeholder replaced by the user's argument name input.</comment>\n  </data>\n  <data name=\"TooManyBehaviorsError\" xml:space=\"preserve\">\n    <value>둘 이상의 실행 동작 인수가 제공되었습니다. '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides more than one execution behavior argument when installing an application package. {0} is a placeholder replaced by the user specified execution behaviors (e.g. 'silent|interactive').</comment>\n  </data>\n  <data name=\"UnexpectedErrorExecutingCommand\" xml:space=\"preserve\">\n    <value>명령을 실행하는 동안 예기치 않은 오류가 발생했습니다.</value>\n  </data>\n  <data name=\"UninstallPreviousArgumentDescription\" xml:space=\"preserve\">\n    <value>업그레이드하는 동안 이전 버전의 패키지 제거</value>\n  </data>\n  <data name=\"UnrecognizedCommand\" xml:space=\"preserve\">\n    <value>인식할 수 없는 명령임: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an unrecognized command. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"UpdateAllArgumentDescription\" xml:space=\"preserve\">\n    <value>설치된 모든 패키지를 사용 가능한 경우 최신 패키지로 업그레이드</value>\n  </data>\n  <data name=\"UpdateNotApplicable\" xml:space=\"preserve\">\n    <value>적용 가능한 업그레이드를 찾을 수 없습니다.</value>\n  </data>\n  <data name=\"UpdateNotApplicableReason\" xml:space=\"preserve\">\n    <value>구성된 원본에서 최신 패키지 버전을 사용할 수 있지만 시스템 또는 요구 사항에는 적용되지 않습니다.</value>\n  </data>\n  <data name=\"UpdateNoPackagesFound\" xml:space=\"preserve\">\n    <value>사용 가능한 업그레이드를 찾을 수 없습니다.</value>\n  </data>\n  <data name=\"UpdateNoPackagesFoundReason\" xml:space=\"preserve\">\n    <value>구성된 원본에서 사용할 수 있는 최신 패키지 버전이 없습니다.</value>\n  </data>\n  <data name=\"UpgradeCommandLongDescription\" xml:space=\"preserve\">\n    <value>설치된 패키지 목록을 검색하거나 매니페스트에서 직접 찾은 선택한 패키지를 업그레이드합니다. 기본적으로 쿼리는 패키지의 ID, 이름 또는 모니커와 대/소문자를 구분하지 않아야 합니다. 다른 필드는 적절한 옵션을 전달하여 사용할 수 있습니다. 인수가 지정되지 않은 경우 업그레이드를 사용할 수 있는 패키지가 표시됩니다.</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"UpgradeCommandShortDescription\" xml:space=\"preserve\">\n    <value>사용 가능한 업그레이드를 표시하고 수행합니다.</value>\n  </data>\n  <data name=\"Usage\" xml:space=\"preserve\">\n    <value>사용 현황: {0} {1}</value>\n    <comment>{Locked=\"{0} {1}\"} Message displayed to provide the user with instructions on how to use a command. {0} is a placeholder replaced by the program name (e.g. 'winget'). {1} is a placeholder replaced by the pattern for using the selected command.</comment>\n  </data>\n  <data name=\"ValidateCommandLongDescription\" xml:space=\"preserve\">\n    <value>엄격한 지침의 집합을 사용하여 매니페스트의 유효성을 검사합니다. 이 기능은 리포지토리를 제출하기 전에 매니페스트를 확인할 수 있도록 하기 위한 목적을 가지고 있습니다.</value>\n  </data>\n  <data name=\"ValidateCommandShortDescription\" xml:space=\"preserve\">\n    <value>매니페스트 파일의 유효성 검사</value>\n  </data>\n  <data name=\"ValidateManifestArgumentDescription\" xml:space=\"preserve\">\n    <value>유효성을 검사할 매니페스트로의 경로</value>\n  </data>\n  <data name=\"VerboseLogsArgumentDescription\" xml:space=\"preserve\">\n    <value>WinGet에 대해 자세한 로깅을 설정합니다.</value>\n  </data>\n  <data name=\"VerifyFileSignedMsix\" xml:space=\"preserve\">\n    <value>입력 파일이 올바른 MSIX인지 확인하십시오.</value>\n  </data>\n  <data name=\"VersionArgumentDescription\" xml:space=\"preserve\">\n    <value>지정된 버전을 사용합니다. 기본값은 최신 버전입니다.</value>\n  </data>\n  <data name=\"VersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>패키지의 사용 가능한 버전을 표시합니다.</value>\n  </data>\n  <data name=\"WordArgumentDescription\" xml:space=\"preserve\">\n    <value>완료되기 전에 제공한 값이 요청되었습니다.</value>\n  </data>\n  <data name=\"GetManifestResultVersionNotFound\" xml:space=\"preserve\">\n    <value>일치하는 버전을 찾을 수 없는 경우: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to upgrade an application package to a version that was not found. {0} is a placeholder replaced by the user's provided upgrade package version.</comment>\n  </data>\n  <data name=\"OpenSourceFailedNoMatch\" xml:space=\"preserve\">\n    <value>지정된 값과 일치하는 원본이 없는 경우: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to install or upgrade an application package from a repository source that was not found. {0} is a placeholder replaced by the user's repository source name input.</comment>\n  </data>\n  <data name=\"OpenSourceFailedNoMatchHelp\" xml:space=\"preserve\">\n    <value>구성된 원본은 다음과 같습니다.</value>\n  </data>\n  <data name=\"OpenSourceFailedNoSourceDefined\" xml:space=\"preserve\">\n    <value>정의된 원본이 없습니다. 'source add'를 사용해 추가하거나 'source reset'을 사용하여 기본값으로 다시 설정</value>\n    <comment>{Locked=\"source add\",\"source reset\"}</comment>\n  </data>\n  <data name=\"ReportIdentityFound\" xml:space=\"preserve\">\n    <value>찾음</value>\n  </data>\n  <data name=\"VerifyFileFailedIsDirectory\" xml:space=\"preserve\">\n    <value>경로가 디렉터리임: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system path that is a directory. {0} is a placeholder replaced by the provided directory path.</comment>\n  </data>\n  <data name=\"VerifyFileFailedNotExist\" xml:space=\"preserve\">\n    <value>파일이 없음: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system file that does not exist. {0} is a placeholder replaced by the provided file path.</comment>\n  </data>\n  <data name=\"BothManifestAndSearchQueryProvided\" xml:space=\"preserve\">\n    <value>로컬 매니페스트 및 검색 쿼리 인수가 모두 제공되었습니다.</value>\n  </data>\n  <data name=\"Logs\" xml:space=\"preserve\">\n    <value>로그</value>\n    <comment>Label displayed for diagnostic files containing information about the application use.</comment>\n  </data>\n  <data name=\"InstallerBlockedByPolicy\" xml:space=\"preserve\">\n    <value>설치 프로그램이 정책에 의해 차단됨</value>\n  </data>\n  <data name=\"InstallerFailedSecurityCheck\" xml:space=\"preserve\">\n    <value>설치 관리자가 보안 검사를 하지 못했습니다</value>\n  </data>\n  <data name=\"InstallerFailedVirusScan\" xml:space=\"preserve\">\n    <value>바이러스 백신 제품이 설치 관리자의 감염을 보고합니다.</value>\n  </data>\n  <data name=\"SourceOpenWithFailedUpdate\" xml:space=\"preserve\">\n    <value>원본을 업데이트하지 못했습니다. {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to update the repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"UninstallCommandLongDescription\" xml:space=\"preserve\">\n    <value>설치된 패키지 목록을 검색하거나 매니페스트에서 직접 찾은 선택한 패키지를 제거합니다. 기본적으로 쿼리는 패키지의 ID, 이름 또는 모양과 대/소문자를 구분하지 않는 것이 어떻게 되아야 합니다. 적절한 옵션을 전달하여 다른 필드를 사용할 수 있습니다.</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"UninstallCommandShortDescription\" xml:space=\"preserve\">\n    <value>지정된 패키지를 제거</value>\n  </data>\n  <data name=\"UninstallFlowStartingPackageUninstall\" xml:space=\"preserve\">\n    <value>패키지 제거를 시작하는 중...</value>\n  </data>\n  <data name=\"UninstallFlowUninstallSuccess\" xml:space=\"preserve\">\n    <value>성공적으로 제거됨</value>\n  </data>\n  <data name=\"NoUninstallInfoFound\" xml:space=\"preserve\">\n    <value>winget 이 패키지에 대한 제거 명령을 찾을 수 없습니다. 지원을 위해 패키지 게시자에게 문의하세요.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"UninstallAbandoned\" xml:space=\"preserve\">\n    <value>제거가 중단됨</value>\n  </data>\n  <data name=\"UninstallFailedWithCode\" xml:space=\"preserve\">\n    <value>설치 종료 코드로 인해 제거하지 못함: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to uninstall an application package fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"ExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>설치된 패키지 목록 내보내기</value>\n  </data>\n  <data name=\"ImportCommandLongDescription\" xml:space=\"preserve\">\n    <value>파일에 나열된 모든 패키지를 설치합니다.</value>\n  </data>\n  <data name=\"ImportCommandShortDescription\" xml:space=\"preserve\">\n    <value>파일에 있는 모든 패키지를 설치합니다.</value>\n  </data>\n  <data name=\"OutputFileArgumentDescription\" xml:space=\"preserve\">\n    <value>결과를 기록할 파일</value>\n  </data>\n  <data name=\"ImportFileArgumentDescription\" xml:space=\"preserve\">\n    <value>설치할 패키지를 설명하는 파일</value>\n  </data>\n  <data name=\"ExportSourceArgumentDescription\" xml:space=\"preserve\">\n    <value>지정한 원본에서 패키지 내보내기</value>\n  </data>\n  <data name=\"ExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>설치된 패키지 목록을 파일에 기록합니다. 그런 다음 패키지를 import 명령과 함께 설치할 수 있습니다.</value>\n    <comment>{Locked=\"import\"}</comment>\n  </data>\n  <data name=\"ImportInstallFailed\" xml:space=\"preserve\">\n    <value>가져온 패키지를 하나 이상 설치하지 못했습니다.</value>\n  </data>\n  <data name=\"ImportSourceNotInstalled\" xml:space=\"preserve\">\n    <value>가져오기에 필요한 원본이 설치되어 있지 않습니다. {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to import application package(s) from a repository source that is not installed. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"InstalledPackageNotAvailable\" xml:space=\"preserve\">\n    <value>어떤 원본에서도 설치된 패키지를 사용할 수 없음: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when the user attempts to export an installed application package that is not available from any repository source. {0} is a placeholder replaced by the installed package name.</comment>\n  </data>\n  <data name=\"InstalledPackageVersionNotAvailable\" xml:space=\"preserve\">\n    <value>어떤 원본에서도 설치된 패키지 버전을 사용할 수 없음: {0} {1} {2}</value>\n    <comment>{Locked=\"{0} {1} {2}\"} Warning message displayed when the user attempts to export an installed application package with a version that is not available from any repository source. {0} is a placeholder replaced by the installed package identifier. {1} is a placeholder replaced by the installed package version. {2} is a placeholder replaced by the installed package channel.</comment>\n  </data>\n  <data name=\"NoPackagesInImportFile\" xml:space=\"preserve\">\n    <value>가져오기 파일에 패키지가 없습니다.</value>\n  </data>\n  <data name=\"InvalidJsonFile\" xml:space=\"preserve\">\n    <value>JSON 파일이 잘못되었습니다.</value>\n  </data>\n  <data name=\"MultiQueryPackageAlreadyInstalled\" xml:space=\"preserve\">\n    <value>패키지가 이미 설치되어 있음: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user that an application package is already installed. {0} is a placeholder replaced by the package identifier or search query.</comment>\n  </data>\n  <data name=\"ImportIgnoreUnavailableArgumentDescription\" xml:space=\"preserve\">\n    <value>사용할 수 없는 패키지 무시</value>\n  </data>\n  <data name=\"ExportIncludeVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>내보내기 파일에 패키지 버전 포함</value>\n  </data>\n  <data name=\"ImportIgnoreVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>가져오기 파일에서 패키지 버전 무시</value>\n  </data>\n  <data name=\"VerifyPathFailedNotExist\" xml:space=\"preserve\">\n    <value>경로가 존재하지 않음: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system path argument value that does not exist. {0} is a placeholder replaced by the user's provided path.</comment>\n  </data>\n  <data name=\"ImportFileHasInvalidSchema\" xml:space=\"preserve\">\n    <value>JSON 파일에서 인식되는 스키마를 지정하지 않습니다.</value>\n  </data>\n  <data name=\"InstallScopeDescription\" xml:space=\"preserve\">\n    <value>설치 범위 선택(user 또는 machine)</value>\n    <comment>{Locked=\"user\",\"machine\"} This argument allows the user to select between installing for just the user or for the entire machine.</comment>\n  </data>\n  <data name=\"InvalidArgumentValueError\" xml:space=\"preserve\">\n    <value>'{0}' 인수에 제공된 값이 잘못되었습니다. 유효한 값: {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message displayed when the user provides an invalid command line argument value. {0} is a placeholder replaced by the argument name. {1} is a placeholder replaced by a list of valid options.</comment>\n  </data>\n  <data name=\"DisabledByGroupPolicy\" xml:space=\"preserve\">\n    <value>그룹 정책 이 작업을 사용하지 않도록 설정했습니다. {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user performs a command operation that is disabled by a group policy. {0} is a placeholder replaced by a group policy description.</comment>\n  </data>\n  <data name=\"PolicyAdditionalSources\" xml:space=\"preserve\">\n    <value>추가 Windows 앱 설치 관리자 원본 사용</value>\n  </data>\n  <data name=\"PolicyAllowedSources\" xml:space=\"preserve\">\n    <value>Windows 앱 설치 관리자 허용된 원본 사용</value>\n  </data>\n  <data name=\"PolicyEnableDefaultSource\" xml:space=\"preserve\">\n    <value>Windows 앱 설치 관리자 기본 원본 사용</value>\n  </data>\n  <data name=\"PolicyEnableExperimentalFeatures\" xml:space=\"preserve\">\n    <value>Windows 앱 설치 관리자 실험적 기능 사용</value>\n  </data>\n  <data name=\"PolicyEnableMSStoreSource\" xml:space=\"preserve\">\n    <value>Windows 앱 설치 관리자 Microsoft Store 소스 사용</value>\n  </data>\n  <data name=\"PolicyEnableFontSource\" xml:space=\"preserve\">\n    <value>Windows App 설치 관리자 글꼴 원본 활성화</value>\n  </data>\n  <data name=\"PolicyEnableWinGetSettings\" xml:space=\"preserve\">\n    <value>Windows 패키지 관리자 설정 사용</value>\n  </data>\n  <data name=\"PolicyEnableWinGet\" xml:space=\"preserve\">\n    <value>Windows 패키지 관리자 사용</value>\n  </data>\n  <data name=\"PolicyEnableWindowsPackageManagerCommandLineInterfaces\" xml:space=\"preserve\">\n    <value>Windows 패키지 관리자 명령줄 인터페이스 활성화</value>\n  </data>\n  <data name=\"PolicySourceAutoUpdateInterval\" xml:space=\"preserve\">\n    <value>Windows 패키지 관리자 원본 자동 업데이트 간격(분) 설정</value>\n  </data>\n  <data name=\"PoliciesPolicy\" xml:space=\"preserve\">\n    <value>그룹 정책</value>\n    <comment>Header for a table listing active Group Policies</comment>\n  </data>\n  <data name=\"PolicyEnableLocalManifests\" xml:space=\"preserve\">\n    <value>Windows 앱 설치 관리자 로컬 매니페스트 파일 사용</value>\n  </data>\n  <data name=\"PolicyEnableBypassCertificatePinningForMicrosoftStore\" xml:space=\"preserve\">\n    <value>Windows 앱 설치 관리자 Microsoft Store 원본 고정 인증서 바이패스 사용</value>\n  </data>\n  <data name=\"PolicyEnableLocalArchiveMalwareScanOverride\" xml:space=\"preserve\">\n    <value>Windows 앱 설치 관리자 로컬 보관 맬웨어 검사 재정의 사용</value>\n  </data>\n  <data name=\"SettingsWarningField\" xml:space=\"preserve\">\n    <value>필드: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when a user setting field has invalid syntax or semantics. {0} is a placeholder replaced by the setting field path.</comment>\n  </data>\n  <data name=\"SettingsWarningInvalidFieldFormat\" xml:space=\"preserve\">\n    <value>잘못된 필드 형식입니다.</value>\n  </data>\n  <data name=\"SettingsWarningInvalidFieldValue\" xml:space=\"preserve\">\n    <value>잘못된 필드 값</value>\n  </data>\n  <data name=\"SettingsWarningInvalidValueFromPolicy\" xml:space=\"preserve\">\n    <value>그룹 정책에서 잘못된 설정</value>\n  </data>\n  <data name=\"SettingsWarningLoadedBackupSettings\" xml:space=\"preserve\">\n    <value>백업 파일의 설정이 로드된 경우</value>\n  </data>\n  <data name=\"SettingsWarningParseError\" xml:space=\"preserve\">\n    <value>오류 구문 분석 파일:</value>\n  </data>\n  <data name=\"SettingsWarningValue\" xml:space=\"preserve\">\n    <value>값: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when a user setting value has invalid syntax or semantics. {0} is a placeholder replaced by the setting data value.</comment>\n  </data>\n  <data name=\"FeaturesMessageDisabledByPolicy\" xml:space=\"preserve\">\n    <value>다음 실험적 기능이 진행 중입니다.\n그룹 정책으로 인해 구성을 사용할 수 없습니다.</value>\n  </data>\n  <data name=\"InstallerHashMismatchError\" xml:space=\"preserve\">\n    <value>설치 관리자 해시가 일치하지 않습니다.</value>\n  </data>\n  <data name=\"PolicyEnableHashOverride\" xml:space=\"preserve\">\n    <value>Windows 앱 설치 관리자 해시 재정의 사용</value>\n  </data>\n  <data name=\"SourceExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>현재 원본을 그룹 정책에 대한 JSON으로 내보냅니다.</value>\n  </data>\n  <data name=\"SourceExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>현재 원본 내보내기</value>\n  </data>\n  <data name=\"SourceListAdditionalSource\" xml:space=\"preserve\">\n    <value>추가 원본</value>\n    <comment>An additional source required by policy.</comment>\n  </data>\n  <data name=\"SourceListAllowedSource\" xml:space=\"preserve\">\n    <value>허용된 원본</value>\n    <comment>A source that the user is allowed to add.</comment>\n  </data>\n  <data name=\"InvalidArgumentValueErrorWithoutValidValues\" xml:space=\"preserve\">\n    <value>'{0}' 인수에 제공된 값이 잘못되었습니다.</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an invalid command line argument value. {0} is a placeholder replaced by the argument name.</comment>\n  </data>\n  <data name=\"Cancelled\" xml:space=\"preserve\">\n    <value>취소됨</value>\n  </data>\n  <data name=\"ExternalDependencies\" xml:space=\"preserve\">\n    <value>외부</value>\n  </data>\n  <data name=\"ImportCommandReportDependencies\" xml:space=\"preserve\">\n    <value>이 가져오기에서 찾은 패키지에는 다음과 같은 종속성이 있습니다.</value>\n    <comment>Import command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"PackageRequiresDependencies\" xml:space=\"preserve\">\n    <value>이 패키지에는 다음 종속성이 필요합니다.</value>\n    <comment>Message shown before reporting dependencies</comment>\n  </data>\n  <data name=\"DependenciesFlowInstall\" xml:space=\"preserve\">\n    <value>종속성 설치 중:</value>\n  </data>\n  <data name=\"DependenciesFlowSourceNotFound\" xml:space=\"preserve\">\n    <value>종속성 원본을 찾을 수 없음</value>\n  </data>\n  <data name=\"DependenciesFlowSourceTooManyMatches\" xml:space=\"preserve\">\n    <value>패키지 검색 결과 두 개 이상 생성: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when application packages search yield more than one result. {0} is a placeholder replaced by the dependency package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowPackageVersionNotFound\" xml:space=\"preserve\">\n    <value>패키지에 대한 최신 버전을 찾을 수 없음: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when no suitable version found for the specific application package. {0} is a placeholder replaced by the package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoInstallerFound\" xml:space=\"preserve\">\n    <value>설치 프로그램을 찾을 수 없음: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when no installer found for a manifest. {0} is a placeholder replaced by the manifest identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoMinVersion\" xml:space=\"preserve\">\n    <value>패키지에 사용할 수 없는 최소 필수 버전: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the minimum required version is not available for an application package. {0} is a placeholder replaced by the package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoMatches\" xml:space=\"preserve\">\n    <value>일치하는 항목 없음</value>\n    <comment>When package search yields no matches</comment>\n  </data>\n  <data name=\"DependenciesFlowContainsLoop\" xml:space=\"preserve\">\n    <value>Loop 있음</value>\n    <comment>Dependency graph has loop</comment>\n  </data>\n  <data name=\"DependenciesFlowNoSuitableInstallerFound\" xml:space=\"preserve\">\n    <value>매니페스트에 적합한 설치 관리자를 찾을 수 없습니다. {0} 버전 {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message displayed when an attempt to get a preferred installer for a manifest fails. {0} is a placeholder replaced by the manifest identifier. {1} is a placeholder replaced by the manifest version.</comment>\n  </data>\n  <data name=\"DependenciesManagementError\" xml:space=\"preserve\">\n    <value>패키지 종속성을 처리하는 동안 오류가 발생했습니다. 설치를 계속하시겠나요?</value>\n    <comment>Prompt message shown when dependencies processing yields errors.</comment>\n  </data>\n  <data name=\"DependenciesManagementExitMessage\" xml:space=\"preserve\">\n    <value>패키지 종속성을 처리하는 동안 오류가 발생했습니다. 종료하는 중...</value>\n  </data>\n  <data name=\"PackageDependencies\" xml:space=\"preserve\">\n    <value>패키지</value>\n  </data>\n  <data name=\"UninstallCommandReportDependencies\" xml:space=\"preserve\">\n    <value>이 패키지에 더 이상 필요하지 않을 수 있는 종속성이 있습니다.</value>\n    <comment>Uninstall command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"ValidateCommandReportDependencies\" xml:space=\"preserve\">\n    <value>매니페스트에 유효성이 검사되지 않은 다음 종속성이 있습니다. 올바른지 확인하세요.</value>\n    <comment>Validate command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"WindowsFeaturesDependencies\" xml:space=\"preserve\">\n    <value>Windows 기능</value>\n  </data>\n  <data name=\"WindowsLibrariesDependencies\" xml:space=\"preserve\">\n    <value>Windows 라이브러리</value>\n  </data>\n  <data name=\"DependencySourceArgumentDescription\" xml:space=\"preserve\">\n    <value>지정된 원본을 사용하여 패키지 종속성 찾기</value>\n    <comment>For getting package type dependencies when installing from a local manifest</comment>\n  </data>\n  <data name=\"WindowsStoreTerms\" xml:space=\"preserve\">\n    <value>Windows 스토어 사용 약관</value>\n  </data>\n  <data name=\"AcceptPackageAgreementsArgumentDescription\" xml:space=\"preserve\">\n    <value>패키지에 대한 모든 사용권 계약 수락</value>\n  </data>\n  <data name=\"ExportedPackageRequiresLicenseAgreement\" xml:space=\"preserve\">\n    <value>내보낸 패키지를 설치하려면 사용권 계약이 필요합니다. {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when an exported application package requires license agreement to install. {0} is a placeholder replaced by the package name.</comment>\n  </data>\n  <data name=\"PackageAgreementsPrompt\" xml:space=\"preserve\">\n    <value>게시자는 설치하기 전에 위의 정보를 보고 계약에 동의해야 합니다.\n사용 약관에 동의하십니까?</value>\n  </data>\n  <data name=\"PackageAgreementsNotAgreedTo\" xml:space=\"preserve\">\n    <value>패키지 계약에 동의하지 않았습니다. 작업이 취소되었습니다.</value>\n  </data>\n  <data name=\"ShowLabelAgreements\" xml:space=\"preserve\">\n    <value>계약:</value>\n  </data>\n  <data name=\"ShowLabelAuthor\" xml:space=\"preserve\">\n    <value>만든 이:</value>\n  </data>\n  <data name=\"ShowLabelDescription\" xml:space=\"preserve\">\n    <value>설명:</value>\n  </data>\n  <data name=\"ShowLabelInstaller\" xml:space=\"preserve\">\n    <value>설치 관리자:</value>\n  </data>\n  <data name=\"ShowLabelInstallerLocale\" xml:space=\"preserve\">\n    <value>설치 관리자 로캘:</value>\n  </data>\n  <data name=\"ShowLabelInstallerProductId\" xml:space=\"preserve\">\n    <value>Store 제품 ID:</value>\n  </data>\n  <data name=\"ShowLabelInstallerSha256\" xml:space=\"preserve\">\n    <value>설치 관리자 SHA256:</value>\n  </data>\n  <data name=\"ShowLabelInstallerType\" xml:space=\"preserve\">\n    <value>설치 관리자 유형:</value>\n  </data>\n  <data name=\"ShowLabelInstallerUrl\" xml:space=\"preserve\">\n    <value>설치 관리자 URL:</value>\n  </data>\n  <data name=\"ShowLabelLicense\" xml:space=\"preserve\">\n    <value>라이선스:</value>\n  </data>\n  <data name=\"ShowLabelLicenseUrl\" xml:space=\"preserve\">\n    <value>라이선스 URL:</value>\n  </data>\n  <data name=\"ShowLabelMoniker\" xml:space=\"preserve\">\n    <value>모니커:</value>\n  </data>\n  <data name=\"ShowLabelPackageUrl\" xml:space=\"preserve\">\n    <value>홈페이지</value>\n  </data>\n  <data name=\"ShowLabelPublisher\" xml:space=\"preserve\">\n    <value>게시자:</value>\n  </data>\n  <data name=\"ShowLabelTags\" xml:space=\"preserve\">\n    <value>태그:</value>\n  </data>\n  <data name=\"ShowLabelVersion\" xml:space=\"preserve\">\n    <value>버전:</value>\n  </data>\n  <data name=\"ShowLabelDependencies\" xml:space=\"preserve\">\n    <value>종속성:</value>\n  </data>\n  <data name=\"ShowLabelWindowsFeaturesDependencies\" xml:space=\"preserve\">\n    <value>Windows 기능</value>\n  </data>\n  <data name=\"ShowLabelWindowsLibrariesDependencies\" xml:space=\"preserve\">\n    <value>Windows 라이브러리:</value>\n  </data>\n  <data name=\"ShowLabelPackageDependencies\" xml:space=\"preserve\">\n    <value>패키지 종속성:</value>\n  </data>\n  <data name=\"ShowLabelExternalDependencies\" xml:space=\"preserve\">\n    <value>외부 종속성:</value>\n  </data>\n  <data name=\"PromptOptionNo\" xml:space=\"preserve\">\n    <value>아니요</value>\n  </data>\n  <data name=\"PromptOptionYes\" xml:space=\"preserve\">\n    <value>예</value>\n  </data>\n  <data name=\"SourceAddOpenSourceFailed\" xml:space=\"preserve\">\n    <value>추가된 원본을 열지 못했습니다.</value>\n  </data>\n  <data name=\"AcceptSourceAgreementsArgumentDescription\" xml:space=\"preserve\">\n    <value>원본 작업 중 모든 원본 계약 수락</value>\n  </data>\n  <data name=\"SourceAgreementsTitle\" xml:space=\"preserve\">\n    <value>'{0}' 원본을 사용하려면 다음 계약을 확인해야 합니다.</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user that a repository source requires viewing agreements before using. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceAgreementsPrompt\" xml:space=\"preserve\">\n    <value>모든 원본 사용 약관에 동의하십니까?</value>\n  </data>\n  <data name=\"SourceAgreementsNotAgreedTo\" xml:space=\"preserve\">\n    <value>원본 계약 중 하나 이상이 동의하지 않았습니다. 작업이 취소되었습니다. 원본 계약에 동의하거나 해당 원본을 제거하세요.</value>\n  </data>\n  <data name=\"SourceAgreementsMarketMessage\" xml:space=\"preserve\">\n    <value>원본이 제대로 작동하려면 현재 컴퓨터의 두 글자 지리적 지역을 백 엔드 서비스로 보내야 합니다(예: \"미국\").</value>\n  </data>\n  <data name=\"InstallFlowRegistrationDeferred\" xml:space=\"preserve\">\n    <value>설치되었습니다. 업그레이드를 완료하려면 애플리케이션을 다시 시작하세요.</value>\n  </data>\n  <data name=\"HeaderArgumentDescription\" xml:space=\"preserve\">\n    <value>Windows-Package-Manager REST 원본 HTTP 헤더(선택 사항)</value>\n  </data>\n  <data name=\"HeaderArgumentNotApplicableForNonRestSourceWarning\" xml:space=\"preserve\">\n    <value>선택적 헤더는 이 원본에 적용할 수 없으므로 무시합니다.</value>\n  </data>\n  <data name=\"HeaderArgumentNotApplicableWithoutSource\" xml:space=\"preserve\">\n    <value>원본을 지정하지 않으면 선택적 헤더를 적용할 수 없습니다. '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user performs an operation (e.g install) and provides the HTTP 'header' argument without specifying the repository source. {0} is a placeholder replaced by the header argument name.</comment>\n  </data>\n  <data name=\"ShowLabelInstallerReleaseDate\" xml:space=\"preserve\">\n    <value>릴리스 날짜:</value>\n  </data>\n  <data name=\"ShowLabelInstallerOfflineDistributionSupported\" xml:space=\"preserve\">\n    <value>지원되는 오프라인 배포:</value>\n  </data>\n  <data name=\"ShowLabelPublisherUrl\" xml:space=\"preserve\">\n    <value>게시자 URL:</value>\n  </data>\n  <data name=\"ShowLabelPurchaseUrl\" xml:space=\"preserve\">\n    <value>구매 URL:</value>\n  </data>\n  <data name=\"ShowLabelPublisherSupportUrl\" xml:space=\"preserve\">\n    <value>게시자 지원 URL:</value>\n  </data>\n  <data name=\"ShowLabelPrivacyUrl\" xml:space=\"preserve\">\n    <value>개인 정보 URL:</value>\n  </data>\n  <data name=\"ShowLabelCopyright\" xml:space=\"preserve\">\n    <value>저작권:</value>\n  </data>\n  <data name=\"ShowLabelCopyrightUrl\" xml:space=\"preserve\">\n    <value>저작권 URL:</value>\n  </data>\n  <data name=\"ShowLabelReleaseNotes\" xml:space=\"preserve\">\n    <value>릴리스 정보:</value>\n  </data>\n  <data name=\"ShowLabelReleaseNotesUrl\" xml:space=\"preserve\">\n    <value>릴리스 정보 URL:</value>\n  </data>\n  <data name=\"SearchFailureWarning\" xml:space=\"preserve\">\n    <value>원본을 검색하는 동안 실패했습니다. 결과가 포함되지 않습니다. {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when searching a repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SearchFailureError\" xml:space=\"preserve\">\n    <value>원본을 검색하는 동안 실패함: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when searching a repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"FeatureDisabledByAdminSettingMessage\" xml:space=\"preserve\">\n    <value>관리자가 이 기능을 사용하도록 설정해야 합니다. 사용하도록 설정하려면 관리자로 'winget settings --enable {0}'를 실행하세요.</value>\n    <comment>{Locked=\"winget settings --enable\", \"{0}\"}. Error message displayed when the user uses a feature that needs to be enabled by administrators. {0} is a placeholder replaced by the admin setting.</comment>\n  </data>\n  <data name=\"AdminSettingEnableDescription\" xml:space=\"preserve\">\n    <value>특정 관리자 설정을 사용하도록 설정합니다.</value>\n  </data>\n  <data name=\"AdminSettingDisableDescription\" xml:space=\"preserve\">\n    <value>특정 관리자 설정을 사용하지 않도록 설정합니다.</value>\n  </data>\n  <data name=\"AdminSettingEnabled\" xml:space=\"preserve\">\n    <value>관리자 설정 '{0}'을(를) 사용하도록 설정했습니다.</value>\n    <comment>{Locked=\"{0}\"} Message displayed when the user enables an admin setting. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"AdminSettingDisabled\" xml:space=\"preserve\">\n    <value>관리자 설정 '{0}'을(를) 사용하지 않도록 설정했습니다.</value>\n    <comment>{Locked=\"{0}\"} Message displayed when the user disables an admin setting. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"AdminSettingHeader\" xml:space=\"preserve\">\n    <value>관리자 설정</value>\n    <comment>Header for a table displaying admin settings.</comment>\n  </data>\n  <data name=\"InstallFlowReturnCodePackageInUse\" xml:space=\"preserve\">\n    <value>응용 프로그램이 현재 실행 중입니다. 애플리케이션을 종료한 후 다시 시도하세요.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodePackageInUseByApplication\" xml:space=\"preserve\">\n    <value>설치 관리자가 수정한 파일을 현재 다른 응용 프로그램에서 사용하고 있습니다. 응용 프로그램을 종료한 후 다시 시도하십시오.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInstallInProgress\" xml:space=\"preserve\">\n    <value>다른 설치가 이미 진행 중입니다. 나중에 다시 시도하세요.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeFileInUse\" xml:space=\"preserve\">\n    <value>하나 이상의 파일을 사용하고 있습니다. 애플리케이션을 종료한 후 다시 시도하세요.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeMissingDependency\" xml:space=\"preserve\">\n    <value>이 패키지에 시스템에 종속성이 없습니다.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeDiskFull\" xml:space=\"preserve\">\n    <value>PC에 더 이상 공간이 없습니다. 공간을 확보한 후 다시 시도하세요.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInsufficientMemory\" xml:space=\"preserve\">\n    <value>설치할 수 있는 메모리가 부족합니다. 다른 애플리케이션을 닫은 후 다시 시도하세요.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInvalidParameter\" xml:space=\"preserve\">\n    <value>설치 매개 변수 중 하나가 잘못되었습니다. 패키지 설치 로그에 추가 정보가 있을 수 있습니다.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeNoNetwork\" xml:space=\"preserve\">\n    <value>이 응용 프로그램을 사용하려면 인터넷에 연결해야 합니다. 네트워크에 연결한 후 다시 시도하세요.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeContactSupport\" xml:space=\"preserve\">\n    <value>설치하는 동안 이 응용 프로그램에 오류가 발생했습니다. 고객 지원에 문의하세요.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootRequiredToFinish\" xml:space=\"preserve\">\n    <value>PC를 다시 시작하여 설치를 완료합니다.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootRequiredForInstall\" xml:space=\"preserve\">\n    <value>설치를 마치기 위해 PC가 다시 시작됩니다.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootInitiated\" xml:space=\"preserve\">\n    <value>설치하지 못했습니다. PC를 다시 시작한 후 다시 시도하세요.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeCancelledByUser\" xml:space=\"preserve\">\n    <value>설치를 취소했습니다.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeAlreadyInstalled\" xml:space=\"preserve\">\n    <value>이 응용 프로그램의 다른 버전이 이미 설치되어 있습니다.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeDowngrade\" xml:space=\"preserve\">\n    <value>이 응용 프로그램의 상위 버전이 이미 설치되어 있습니다.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeBlockedByPolicy\" xml:space=\"preserve\">\n    <value>조직 정책으로 인해 설치할 수 없습니다. 관리자에게 문의하세요.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeSystemNotSupported\" xml:space=\"preserve\">\n    <value>현재 시스템 구성에서는 이 패키지 설치를 지원하지 않습니다.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeCustomError\" xml:space=\"preserve\">\n    <value>사용자 지정 설치 관리자 오류로 인해 설치하지 못했습니다. 패키지 지원에 문의하세요.</value>\n  </data>\n  <data name=\"InstallAbandoned\" xml:space=\"preserve\">\n    <value>설치 중단됨</value>\n  </data>\n  <data name=\"InstallerFailedWithCode\" xml:space=\"preserve\">\n    <value>설치 관리자가 종료 코드로 인해 실패함: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the application installer fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"InstallerLogAvailable\" xml:space=\"preserve\">\n    <value>설치 관리자 로그는 다음 위치에서 사용할 수 있음: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about the system path of a diagnostic files containing information about the installer. {0} is a placeholder replaced by the diagnostic file system path.</comment>\n  </data>\n  <data name=\"SearchFailureErrorListMatches\" xml:space=\"preserve\">\n    <value>다음 패키지가 작업 원본에서 발견되었습니다.\n계속하려면 --source 옵션을 사용하여 둘 중 하나를 지정하십시오.</value>\n    <comment>{Locked=\"--source\"} \"working sources\" as in \"sources that are working correctly\"</comment>\n  </data>\n  <data name=\"SearchFailureErrorNoMatches\" xml:space=\"preserve\">\n    <value>작업 원본 중 패키지를 찾을 수 없습니다.</value>\n    <comment>\"working sources\" as in \"sources that are working correctly\"</comment>\n  </data>\n  <data name=\"FeaturesMessageDisabledByBuild\" xml:space=\"preserve\">\n    <value>이 릴리스는 Windows 패키지 관리자의 안정적인 릴리스입니다. 실험적인 기능을 사용해 보려면 시험판 빌드를 설치하세요. 지침은 GitHub(https://github.com/microsoft/winget-cli)에서 확인할 수 있습니다.</value>\n    <comment>{Locked=\"https://github.com/microsoft/winget-cli\"}</comment>\n  </data>\n  <data name=\"WindowsPackageManager\" xml:space=\"preserve\">\n    <value>Windows 패키지 관리자 v{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying the product name and version. {0} is a placeholder replaced by the product version.</comment>\n  </data>\n  <data name=\"ImportIgnorePackageVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>가져오기 파일의 패키지 버전 무시</value>\n  </data>\n  <data name=\"CountOutOfBoundsError\" xml:space=\"preserve\">\n    <value>요청한 결과 수는 1에서 1000 사이여야 합니다.</value>\n  </data>\n  <data name=\"CustomSwitchesArgumentDescription\" xml:space=\"preserve\">\n    <value>기본값 외에도 설치 관리자에 전달할 인수</value>\n  </data>\n  <data name=\"UpgradeDifferentInstallTechnologyInNewerVersions\" xml:space=\"preserve\">\n    <value>최신 버전을 찾았지만 설치 기술이 현재 설치된 버전과 다릅니다. 패키지를 제거하고 최신 버전을 설치하세요.</value>\n  </data>\n  <data name=\"UpgradeDifferentInstallTechnology\" xml:space=\"preserve\">\n    <value>지정된 최신 버전의 설치 기술이 현재 설치된 버전과 다릅니다. 패키지를 제거하고 최신 버전을 설치하세요.</value>\n  </data>\n  <data name=\"WindowsPackageManagerPreview\" xml:space=\"preserve\">\n    <value>Windows 패키지 관리자(미리 보기) v{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying the preview product name and pre-release version. {0} is a placeholder replaced by the product version.</comment>\n  </data>\n  <data name=\"ArchitectureArgumentDescription\" xml:space=\"preserve\">\n    <value>아키텍처를 선택하세요</value>\n  </data>\n  <data name=\"IncludeUnknownArgumentDescription\" xml:space=\"preserve\">\n    <value>현재 버전을 확인할 수 없는 경우에도 패키지 업그레이드</value>\n  </data>\n  <data name=\"IncludeUnknownInListArgumentDescription\" xml:space=\"preserve\">\n    <value>현재 버전을 확인할 수 없는 경우에도 패키지를 나열합니다. --upgrade-available 인수와 함께만 사용할 수 있습니다.</value>\n    <comment>{Locked=\"--upgrade-available\"}</comment>\n  </data>\n  <data name=\"UpgradeUnknownVersionExplanation\" xml:space=\"preserve\">\n    <value>이 패키지의 버전 번호를 확인할 수 없습니다. 그래도 업그레이드하려면 이전 명령에 인수 --include-unknown 추가하세요.</value>\n    <comment>{Locked=\"--include-unknown\"}</comment>\n  </data>\n  <data name=\"UpgradeUnknownVersionCount\" xml:space=\"preserve\">\n    <value>{0} 패키지에 확인할 수 없는 버전 번호가 있습니다. 모든 결과를 보려면 --include-unknown 사용하세요.</value>\n    <comment>{Locked=\"{0}\",\"--include-unknown\"} {0} is a placeholder that is replaced by an integer number of packages that do not have notated versions. </comment>\n  </data>\n  <data name=\"UpgradeRequireExplicitCount\" xml:space=\"preserve\">\n    <value>{0} 패키지가 고정되어 있으므로 명시적으로 업그레이드해야 합니다.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by an integer number of packages that require explicit upgrades.</comment>\n  </data>\n  <data name=\"InvalidArgumentWithoutQueryError\" xml:space=\"preserve\">\n    <value>제공된 인수는 쿼리에서만 사용할 수 있습니다.</value>\n  </data>\n  <data name=\"SystemArchitecture\" xml:space=\"preserve\">\n    <value>시스템 아키텍처: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for the system architecture. {0} is a placeholder replaced by the value of the system architecture (e.g. X64).</comment>\n  </data>\n  <data name=\"PreserveArgumentDescription\" xml:space=\"preserve\">\n    <value>패키지에서 만든 모든 파일 및 디렉터리를 유지합니다(이식 가능).</value>\n  </data>\n  <data name=\"PurgeArgumentDescription\" xml:space=\"preserve\">\n    <value>패키지 디렉터리의 모든 파일 및 디렉터리를 삭제합니다(이식 가능).</value>\n  </data>\n  <data name=\"PressEnterToContinue\" xml:space=\"preserve\">\n    <value>계속하려면 Enter 키를 누르세요 . . .</value>\n  </data>\n  <data name=\"RenameArgumentDescription\" xml:space=\"preserve\">\n    <value>실행 파일의 이름을 바꿀 값입니다(이식 가능).</value>\n  </data>\n  <data name=\"WaitArgumentDescription\" xml:space=\"preserve\">\n    <value>종료하기 전에 아무 키나 누르라는 메시지를 사용자에게 표시합니다.</value>\n  </data>\n  <data name=\"InstallerElevationExpected\" xml:space=\"preserve\">\n    <value>설치 관리자가 관리자 권한으로 실행을 요청합니다. 프롬프트가 표시됩니다.</value>\n  </data>\n  <data name=\"InstallerProhibitsElevation\" xml:space=\"preserve\">\n    <value>관리자 컨텍스트에서 설치 관리자를 실행할 수 없습니다.</value>\n  </data>\n  <data name=\"ModifiedPathRequiresShellRestart\" xml:space=\"preserve\">\n    <value>경로 환경 변수 수정됨; 셸을 다시 시작하여 새 값을 사용합니다.</value>\n  </data>\n  <data name=\"ProductCodeArgumentDescription\" xml:space=\"preserve\">\n    <value>제품 코드를 사용하여 필터링</value>\n  </data>\n  <data name=\"PortableRegistryCollisionOverridden\" xml:space=\"preserve\">\n    <value>이름이 같지만 다른 원본의 이식 가능한 패키지가 이미 있습니다. --force로 인해 계속 진행 중</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"ReparsePointsNotSupportedError\" xml:space=\"preserve\">\n    <value>볼륨에서 다시 지점 구문 분석을 지원하지 않습니다.</value>\n  </data>\n  <data name=\"ReservedFilenameError\" xml:space=\"preserve\">\n    <value>지정한 파일 이름이 올바른 파일 이름이 아닙니다.</value>\n  </data>\n  <data name=\"OverwritingExistingFileAtMessage\" xml:space=\"preserve\">\n    <value>기존 파일 덮어쓰기: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed to inform the user that an existing file is being overwritten. {0} is a placeholder replaced by the file system path.</comment>\n  </data>\n  <data name=\"NoPackageSelectionArgumentProvided\" xml:space=\"preserve\">\n    <value>패키지 선택 인수가 제공되지 않았습니다. 패키지 찾기에 대한 자세한 내용은 도움말을 참조하세요.</value>\n  </data>\n  <data name=\"PortableAliasAdded\" xml:space=\"preserve\">\n    <value>명령줄 별칭이 추가되었습니다.</value>\n  </data>\n  <data name=\"PortableLinksMachine\" xml:space=\"preserve\">\n    <value>이식 가능한 링크 디렉터리(컴퓨터)</value>\n  </data>\n  <data name=\"PortableLinksUser\" xml:space=\"preserve\">\n    <value>이식 가능한 링크 디렉터리(사용자)</value>\n  </data>\n  <data name=\"PortableRootUser\" xml:space=\"preserve\">\n    <value>이식 가능한 패키지 루트(사용자)</value>\n  </data>\n  <data name=\"PortableRoot\" xml:space=\"preserve\">\n    <value>이식 가능한 패키지 루트</value>\n  </data>\n  <data name=\"PortableRoot86\" xml:space=\"preserve\">\n    <value>이식 가능한 패키지 루트(x86)</value>\n  </data>\n  <data name=\"PortableInstallFailed\" xml:space=\"preserve\">\n    <value>이식 가능한 설치에 실패했습니다. 정리 중...</value>\n  </data>\n  <data name=\"PortableHashMismatchOverridden\" xml:space=\"preserve\">\n    <value>휴대용 패키지가 수정되었습니다. --force로 인해 계속 진행</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"PortableHashMismatchOverrideRequired\" xml:space=\"preserve\">\n    <value>휴대용 패키지가 수정되었으므로 제거할 수 없습니다. 이 검사를 재정의하려면 --force 사용하세요.</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"FilesRemainInInstallDirectory\" xml:space=\"preserve\">\n    <value>파일은 설치 디렉터리에 남아 있음: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when files remain in install directory. {0} is a placeholder replaced by the directory path.</comment>\n  </data>\n  <data name=\"PurgeInstallDirectory\" xml:space=\"preserve\">\n    <value>설치 디렉터리를 제거하는 중...</value>\n  </data>\n  <data name=\"UnableToPurgeInstallDirectory\" xml:space=\"preserve\">\n    <value>WinGet에서 만들지 않았으므로 설치 디렉터리를 제거할 수 없습니다.</value>\n  </data>\n  <data name=\"RelatedLink\" xml:space=\"preserve\">\n    <value>관련 링크</value>\n  </data>\n  <data name=\"ShowLabelDocumentation\" xml:space=\"preserve\">\n    <value>설명서:</value>\n  </data>\n  <data name=\"Notes\" xml:space=\"preserve\">\n    <value>메모: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for installation notes. {0} is a placeholder replaced by installation notes.</comment>\n  </data>\n  <data name=\"ShowLabelInstallationNotes\" xml:space=\"preserve\">\n    <value>설치 정보:</value>\n  </data>\n  <data name=\"UnsupportedArgument\" xml:space=\"preserve\">\n    <value>제공된 인수는 이 패키지에 대해 지원되지 않습니다.</value>\n  </data>\n  <data name=\"ExtractArchiveFailed\" xml:space=\"preserve\">\n    <value>보관 파일의 내용을 추출하지 못했습니다.</value>\n  </data>\n  <data name=\"NestedInstallerNotFound\" xml:space=\"preserve\">\n    <value>중첩된 설치 관리자 파일이 없습니다. 중첩 설치 관리자의 지정한 상대 경로가 일치하는지 확인하세요. {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when nested installer file does not exist. {0} is a placeholder replaced by the nested installer file path.</comment>\n  </data>\n  <data name=\"InvalidPathToNestedInstaller\" xml:space=\"preserve\">\n    <value>중첩된 설치 관리자에 대한 상대 파일 경로가 잘못되었습니다. 경로가 설치 디렉터리 외부의 위치를 가리킵니다.</value>\n  </data>\n  <data name=\"NestedInstallerNotSpecified\" xml:space=\"preserve\">\n    <value>이 패키지에 대해 중첩된 설치 관리자가 지정되지 않았습니다.</value>\n  </data>\n  <data name=\"MultipleUnsupportedNestedInstallersSpecified\" xml:space=\"preserve\">\n    <value>보관 설치 관리자의 경우, 이식 가능 또는 글꼴 중첩 설치 관리자가 아니면 중첩 설치 관리자를 하나만 지정할 수 있습니다.</value>\n  </data>\n  <data name=\"IncompatibleArgumentsProvided\" xml:space=\"preserve\">\n    <value>제공된 호환되지 않는 명령줄 인수</value>\n  </data>\n  <data name=\"UpgradeArgumentDescription\" xml:space=\"preserve\">\n    <value>업그레이드를 사용할 수 있는 패키지만 나열합니다.</value>\n  </data>\n  <data name=\"UpgradeAvailableForPinned\" xml:space=\"preserve\">\n    <value>다음 패키지에는 업그레이드를 사용할 수 있지만 업그레이드를 위해 명시적 대상 지정이 필요합니다.</value>\n    <comment>\"require explicit targeting for upgrade\" means that the package will not be upgraded with all others unless an extra flag is added, or the package is mentioned explicitly</comment>\n  </data>\n  <data name=\"Downloading\" xml:space=\"preserve\">\n    <value>다운로드 중</value>\n    <comment>Label displayed while downloading an application installer.</comment>\n  </data>\n  <data name=\"NestedInstallerNotSupported\" xml:space=\"preserve\">\n    <value>중첩된 설치 관리자 유형은 지원되지 않습니다.</value>\n  </data>\n  <data name=\"InstallerAbortsTerminal\" xml:space=\"preserve\">\n    <value>이 설치 관리자는 터미널 또는 셸을 다시 시작하는 것으로 알려져 있습니다.</value>\n  </data>\n  <data name=\"InstallerRequiresInstallLocation\" xml:space=\"preserve\">\n    <value>이 패키지에는 설치 위치가 필요합니다.</value>\n  </data>\n  <data name=\"InstallersAbortTerminal\" xml:space=\"preserve\">\n    <value>다음 설치 관리자는 터미널 또는 셸을 다시 시작하는 것으로 알려져 있습니다.</value>\n  </data>\n  <data name=\"InstallersRequireInstallLocation\" xml:space=\"preserve\">\n    <value>다음 설치 관리자에는 설치 위치가 필요합니다.</value>\n  </data>\n  <data name=\"PromptForInstallRoot\" xml:space=\"preserve\">\n    <value>설치 루트 지정:</value>\n  </data>\n  <data name=\"PromptToProceed\" xml:space=\"preserve\">\n    <value>계속하시겠습니까?</value>\n  </data>\n  <data name=\"ReportIdentityForAgreements\" xml:space=\"preserve\">\n    <value>다음에 대한 계약</value>\n    <comment>This will be followed by a package name, and then a list of license agreements</comment>\n  </data>\n  <data name=\"InstallLocationNotProvided\" xml:space=\"preserve\">\n    <value>설치 위치가 패키지에 필요하지만 제공되지 않았습니다.</value>\n  </data>\n  <data name=\"DisableInteractivityArgumentDescription\" xml:space=\"preserve\">\n    <value>대화형 프롬프트 사용 안 함</value>\n    <comment>Description for a command line argument, shown next to it in the help</comment>\n  </data>\n  <data name=\"ConvertInstallFlowToUpgrade\" xml:space=\"preserve\">\n    <value>이미 설치된 기존 패키지를 찾았습니다. 설치된 패키지를 업그레이드하는 중...</value>\n  </data>\n  <data name=\"ForceArgumentDescription\" xml:space=\"preserve\">\n    <value>명령을 직접 실행하고 보안과 관련되지 않은 문제를 계속 진행합니다.</value>\n    <comment>Description for a command line argument, shown next to it in the help</comment>\n  </data>\n  <data name=\"PortablePackageAlreadyExists\" xml:space=\"preserve\">\n    <value>다른 원본의 휴대용 패키지가 이미 있습니다.</value>\n  </data>\n  <data name=\"ExtractArchiveSucceeded\" xml:space=\"preserve\">\n    <value>보관 파일을 추출했습니다.</value>\n  </data>\n  <data name=\"ExtractingArchive\" xml:space=\"preserve\">\n    <value>보관 파일을 추출하는 중...</value>\n  </data>\n  <data name=\"ArchiveFailedMalwareScan\" xml:space=\"preserve\">\n    <value>보관 검색에서 맬웨어가 검색되었습니다. 이 검사를 재정의하려면 --ignore-local-archive-malware-scan 사용하세요.</value>\n    <comment>{Locked=\"--ignore-local-archive-malware-scan\"}</comment>\n  </data>\n  <data name=\"ArchiveFailedMalwareScanOverridden\" xml:space=\"preserve\">\n    <value>보관 검색에서 맬웨어가 검색되었습니다. --ignore-local-archive-malware-scan 때문에 계속</value>\n    <comment>{Locked=\"--ignore-local-archive-malware-scan\"}</comment>\n  </data>\n  <data name=\"NoUpgradeArgumentDescription\" xml:space=\"preserve\">\n    <value>설치된 버전이 이미 있는 경우 업그레이드를 건너뜁니다.</value>\n  </data>\n  <data name=\"PackageAlreadyInstalled\" xml:space=\"preserve\">\n    <value>패키지 버전이 이미 설치되어 있습니다. 설치가 취소되었습니다.</value>\n  </data>\n  <data name=\"EnableAdminSettingFailed\" xml:space=\"preserve\">\n    <value>{0} 사용하도록 설정할 수 없습니다. 이 설정은 정책에 의해 제어됩니다. 자세한 내용은 시스템 관리자에게 문의하십시오.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"DisableAdminSettingFailed\" xml:space=\"preserve\">\n    <value>{0} 사용하지 않도록 설정할 수 없습니다. 이 설정은 정책에 의해 제어됩니다. 자세한 내용은 시스템 관리자에게 문의하십시오.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"PinAddCommandLongDescription\" xml:space=\"preserve\">\n    <value>새 핀을 추가합니다. 핀을 사용하면 Windows 패키지 관리자 패키지를 특정 버전의 범위로 업그레이드하지 못하도록 제한하거나 패키지를 완전히 업그레이드하지 못할 수 있습니다. 고정된 패키지는 자체적으로 업그레이드되고 Windows 패키지 관리자 외부에서 업그레이드될 수 있습니다. 기본적으로 고정된 패키지는 'upgrade' 명령에서 명시적으로 언급하거나 'winget upgrade --all'에 '--include-pinned' 플래그를 추가하여 업그레이드할 수 있습니다.</value>\n    <comment>{Locked{\"'upgrade'\"} Locked{\"--include-pinned\"} Locked{\"winget upgrade --all\"}</comment>\n  </data>\n  <data name=\"PinAddCommandShortDescription\" xml:space=\"preserve\">\n    <value>새 핀 추가</value>\n  </data>\n  <data name=\"PinCommandLongDescription\" xml:space=\"preserve\">\n    <value>하위 명령을 사용하여 패키지 핀을 관리합니다. 핀은 Windows 패키지 관리자 패키지를 특정 버전의 범위로 업그레이드하지 못하도록 제한하거나 패키지를 완전히 업그레이드하지 못하게 할 수 있습니다. 고정된 패키지는 여전히 자체적으로 업그레이드되고 Windows 패키지 관리자 외부에서 업데이트될 수 있습니다.</value>\n  </data>\n  <data name=\"PinCommandShortDescription\" xml:space=\"preserve\">\n    <value>패키지 핀 관리</value>\n  </data>\n  <data name=\"PinListCommandLongDescription\" xml:space=\"preserve\">\n    <value>현재의 모든 핀 또는 특정 핀의 전체 세부 정보를 목록에 추가합니다.</value>\n  </data>\n  <data name=\"PinListCommandShortDescription\" xml:space=\"preserve\">\n    <value>현재 핀 나열</value>\n  </data>\n  <data name=\"PinRemoveCommandLongDescription\" xml:space=\"preserve\">\n    <value>특정 패키지 핀을 제거합니다.</value>\n  </data>\n  <data name=\"PinRemoveCommandShortDescription\" xml:space=\"preserve\">\n    <value>패키지 핀 제거</value>\n  </data>\n  <data name=\"PinResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>모든 기존 핀을 다시 설정합니다.</value>\n  </data>\n  <data name=\"PinResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>핀을 다시 설정하시겠습니까?</value>\n  </data>\n  <data name=\"GatedVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>패키지를 고정할 버전입니다. 와일드카드 '*'는 마지막 버전 부분으로 사용할 수 있습니다.</value>\n  </data>\n  <data name=\"PinAddBlockingArgumentDescription\" xml:space=\"preserve\">\n    <value>PIN이 제거될 때까지 업그레이드 차단, 인수 재정의 방지</value>\n  </data>\n  <data name=\"PinInstalledArgumentDescription\" xml:space=\"preserve\">\n    <value>설치된 특정 버전 고정</value>\n  </data>\n  <data name=\"PinInstalledSource\" xml:space=\"preserve\">\n    <value>설치됨</value>\n    <comment>Value used in a table to indicate that a package comes from the list of packages installed in the machine</comment>\n  </data>\n  <data name=\"SettingsExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>설정을 JSON으로 내보내기</value>\n  </data>\n  <data name=\"SettingsExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>내보내기 설정</value>\n  </data>\n  <data name=\"UserSettings\" xml:space=\"preserve\">\n    <value>사용자 설정</value>\n    <comment>Label displayed for the file containing the user settings.</comment>\n  </data>\n  <data name=\"SettingsWarningUsingDefault\" xml:space=\"preserve\">\n    <value>설정 파일을 로드할 수 없습니다. 기본값을 사용합니다.</value>\n  </data>\n  <data name=\"InstalledScopeArgumentDescription\" xml:space=\"preserve\">\n    <value>설치된 패키지 범위 필터 선택(user 또는 machine)</value>\n    <comment>{Locked=\"user\",\"machine\"} This argument allows the user to select installed packages for just the user or for the entire machine.</comment>\n  </data>\n  <data name=\"PinAdded\" xml:space=\"preserve\">\n    <value>고정이 추가됨</value>\n  </data>\n  <data name=\"PinAlreadyExists\" xml:space=\"preserve\">\n    <value>패키지 {0} 대한 PIN이 이미 있습니다.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that will be replaced by a package name. The message is shown when attempting to add a pin for a package that is already pinned.</comment>\n  </data>\n  <data name=\"PinExistsOverwriting\" xml:space=\"preserve\">\n    <value>패키지 {0} PIN이 이미 있습니다. --force 인수로 인해 덮어씁니다.</value>\n    <comment>{Locked=\"--force\"}{Locked=\"--force\",\"{0}\"} {0} is a placeholder that will be replaced by a package name.</comment>\n  </data>\n  <data name=\"PinExistsUseForceArg\" xml:space=\"preserve\">\n    <value>패키지 {0} 대한 PIN이 이미 있습니다. --force 인수를 사용하여 덮어쓰십시오.</value>\n    <comment>{Locked=\"--force\",\"{0}\"} {0} is a placeholder that will be replaced by a package name.</comment>\n  </data>\n  <data name=\"PinResettingAll\" xml:space=\"preserve\">\n    <value>현재의 모든 핀을 다시 설정하는 중입니다.</value>\n  </data>\n  <data name=\"PinResetUseForceArg\" xml:space=\"preserve\">\n    <value>--force 인수를 사용하여 모든 핀을 다시 설정합니다. 다음 핀이 제거됩니다.</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"PinType\" xml:space=\"preserve\">\n    <value>고정 유형</value>\n  </data>\n  <data name=\"PinDoesNotExist\" xml:space=\"preserve\">\n    <value>패키지 {0}에 대한 핀이 없습니다.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that will be replaced by a package name. The message is shown when attempting to delete a pin for a package that is not pinned.</comment>\n  </data>\n  <data name=\"PinNoPinsExist\" xml:space=\"preserve\">\n    <value>구성된 핀이 없습니다.</value>\n    <comment>Shown when listing or modifying existing pins if there are none.</comment>\n  </data>\n  <data name=\"PinResetSuccessful\" xml:space=\"preserve\">\n    <value>고정을 다시 설정했습니다.</value>\n    <comment>Shown after resetting (deleting) all the pins</comment>\n  </data>\n  <data name=\"PinCannotOpenIndex\" xml:space=\"preserve\">\n    <value>고정 데이터베이스를 열 수 없습니다.</value>\n    <comment>Error message for when we cannot open the database containing package pins.</comment>\n  </data>\n  <data name=\"ArgumentForSinglePackageProvidedWithMultipleQueries\" xml:space=\"preserve\">\n    <value>단일 패키지에만 사용할 수 있는 인수가 제공되었습니다.</value>\n  </data>\n  <data name=\"MultipleExclusiveArgumentsProvided\" xml:space=\"preserve\">\n    <value>여러 상호 배타적 인수가 제공됨: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message shown when mutually incompatible command line arguments are used. {0} is a placeholder replaced by the arguments that cannot be specified together</comment>\n  </data>\n  <data name=\"DependencyArgumentMissing\" xml:space=\"preserve\">\n    <value>인수 {0} {1} 사용할 수 있습니다.</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message shown when having an argument needs another to be present, but that is missing. {0} and {1} are replaced by the arguments. For example \"Argument --include-unknown can only be used with --upgrade\"</comment>\n  </data>\n  <data name=\"StateDisabled\" xml:space=\"preserve\">\n    <value>사용 안 함</value>\n    <comment>As in enabled/disabled</comment>\n  </data>\n  <data name=\"StateEnabled\" xml:space=\"preserve\">\n    <value>사용</value>\n    <comment>As in enabled/disabled</comment>\n  </data>\n  <data name=\"StateHeader\" xml:space=\"preserve\">\n    <value>상태</value>\n    <comment>Header for a table listing the state (enabled/disabled) of Group Policies and Settings</comment>\n  </data>\n  <data name=\"MultiQueryArgumentDescription\" xml:space=\"preserve\">\n    <value>패키지를 검색하는 데 사용되는 쿼리</value>\n  </data>\n  <data name=\"MultiQueryPackageNotFound\" xml:space=\"preserve\">\n    <value>패키지를 찾을 수 없음: '{0}' 패키지를 찾을 수 없습니다.</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches returns no results. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"MultiQuerySearchFoundMultiple\" xml:space=\"preserve\">\n    <value>다음에 대해 여러 패키지를 차음: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches returns more than one result. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"MultiQuerySearchFailed\" xml:space=\"preserve\">\n    <value>다음에 대한 검색이 실패함: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches fails. This message is for generic failures, we have more specific messages for when the search returns no results, or when it returns more than one result. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"UpgradeBlockedByPinCount\" xml:space=\"preserve\">\n    <value>{0} 패키지에 업그레이드 전에 제거해야 하는 PIN이 있습니다.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by an integer number of packages with pins that prevent upgrade</comment>\n  </data>\n  <data name=\"UpgradeBlockedByManifest\" xml:space=\"preserve\">\n    <value>winget을 사용하여 패키지를 업그레이드할 수 없습니다. 게시자가 제공한 메서드를 사용하여 이 패키지를 업그레이드하세요.</value>\n  </data>\n  <data name=\"IncludePinnedArgumentDescription\" xml:space=\"preserve\">\n    <value>차단되지 않는 PIN이 있는 경우에도 패키지 업그레이드</value>\n  </data>\n  <data name=\"IncludePinnedInListArgumentDescription\" xml:space=\"preserve\">\n    <value>업그레이드를 방해하는 핀이 있는 경우에도 패키지를 나열합니다. --upgrade-available 인수와 함께만 사용할 수 있습니다.</value>\n    <comment>{Locked=\"--upgrade-available\"}</comment>\n  </data>\n  <data name=\"PinRemovedSuccessfully\" xml:space=\"preserve\">\n    <value>고정을 제거했습니다.</value>\n  </data>\n  <data name=\"UpgradeIsPinned\" xml:space=\"preserve\">\n    <value>최신 버전을 찾았지만 패키지에 업그레이드를 방지하는 핀이 있습니다.</value>\n  </data>\n  <data name=\"PackageIsPinned\" xml:space=\"preserve\">\n    <value>패키지가 고정되어 있어 업그레이드할 수 없습니다. 'winget pin' 명령을 사용하여 핀을 보고 편집합니다. 일부 PIN 유형은 --include-pinned 인수를 사용하여 무시할 수 있습니다.</value>\n    <comment>{Locked=\"winget pin\",\"--include-pinned\"} Error shown when we block an upgrade due to the package being pinned</comment>\n  </data>\n  <data name=\"UpgradePinnedByUserCount\" xml:space=\"preserve\">\n    <value>{0} 패키지에 업그레이드를 방지하는 핀이 있습니다. 'winget pin' 명령을 사용하여 핀을 보고 편집합니다. --include-pinned 인수를 사용하면 더 많은 결과가 표시될 수 있습니다.</value>\n    <comment>{Locked=\"winget pin\",\"--include-pinned\"} {0} is a placeholder replaced by an integer number of packages</comment>\n  </data>\n  <data name=\"ConfigureCommandLongDescription\" xml:space=\"preserve\">\n    <value>시스템이 제공된 구성에 설명된 대로 원하는 상태와 일치하는지 확인합니다. 원하는 상태를 얻기 위해 프로세서를 다운로드/실행할 수 있습니다. 구성 및 프로세서를 적용하기 전에 신뢰할 수 있는지 확인해야 합니다.</value>\n  </data>\n  <data name=\"ConfigureCommandShortDescription\" xml:space=\"preserve\">\n    <value>시스템을 원하는 상태로 구성합니다.</value>\n  </data>\n  <data name=\"ConfigureShowCommandLongDescription\" xml:space=\"preserve\">\n    <value>제공된 구성의 세부 정보를 표시합니다. 기본적으로 시스템을 수정하지 않지만 일부 옵션을 사용하면 파일이 다운로드 및/또는 로드됩니다.</value>\n  </data>\n  <data name=\"ConfigureShowCommandShortDescription\" xml:space=\"preserve\">\n    <value>구성 세부 정보 표시</value>\n  </data>\n  <data name=\"ConfigureTestCommandLongDescription\" xml:space=\"preserve\">\n    <value>시스템이 제공된 구성에 설명된 대로 원하는 상태와 일치하는지 확인합니다. 원하는 상태를 테스트하기 위해 프로세서를 다운로드/실행할 수 있습니다. 구성 및 프로세서를 실행하기 전에 신뢰할 수 있는지 확인해야 합니다.</value>\n  </data>\n  <data name=\"ConfigureTestCommandShortDescription\" xml:space=\"preserve\">\n    <value>원하는 상태에 대해 시스템을 확인합니다.</value>\n  </data>\n  <data name=\"ConfigureValidateCommandLongDescription\" xml:space=\"preserve\">\n    <value>구성 파일의 정확성을 검사합니다.</value>\n  </data>\n  <data name=\"ConfigureValidateCommandShortDescription\" xml:space=\"preserve\">\n    <value>구성 파일의 유효성을 검사합니다.</value>\n  </data>\n  <data name=\"ConfigurationFieldInvalidType\" xml:space=\"preserve\">\n    <value>구성 파일의 필드 '{0}' 형식이 잘못되었습니다.</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the field name from the file.</comment>\n  </data>\n  <data name=\"ConfigurationFileArgumentDescription\" xml:space=\"preserve\">\n    <value>구성 파일의 경로</value>\n  </data>\n  <data name=\"ConfigurationFileInvalid\" xml:space=\"preserve\">\n    <value>구성 파일이 잘못되었습니다.</value>\n  </data>\n  <data name=\"ConfigurationFileVersionUnknown\" xml:space=\"preserve\">\n    <value>구성 파일 버전{0}을 알 수 없습니다.</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the version of the configuration file.</comment>\n  </data>\n  <data name=\"ConfigurationAcceptWarningArgumentDescription\" xml:space=\"preserve\">\n    <value>대화형 프롬프트가 발생하지 않도록 구성 경고를 수락합니다.</value>\n  </data>\n  <data name=\"ConfigurationApply\" xml:space=\"preserve\">\n    <value>적용</value>\n    <comment>Indicates that this item is used to write state</comment>\n  </data>\n  <data name=\"ConfigurationAssert\" xml:space=\"preserve\">\n    <value>어설션</value>\n    <comment>Indicates that this item is used to check/assert the state rather than write to it</comment>\n  </data>\n  <data name=\"ConfigurationDependencies\" xml:space=\"preserve\">\n    <value>종속성: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying a list of dependencies. {0} is replaced with a space separated list of identifiers referencing other items.</comment>\n  </data>\n  <data name=\"ConfigurationFailedToApply\" xml:space=\"preserve\">\n    <value>일부 구성이 적용되지 않았습니다.</value>\n  </data>\n  <data name=\"ConfigurationFailedToGetDetails\" xml:space=\"preserve\">\n    <value>구성에 대한 자세한 정보를 가져오지 못했습니다.</value>\n  </data>\n  <data name=\"ConfigurationInform\" xml:space=\"preserve\">\n    <value>알림</value>\n    <comment>Indicates that this item is used to retrieve values for future use rather than writing them</comment>\n  </data>\n  <data name=\"ConfigurationLocal\" xml:space=\"preserve\">\n    <value>로컬</value>\n    <comment>Used to indicate that the item is present on the device.</comment>\n  </data>\n  <data name=\"ConfigurationModuleNameOnly\" xml:space=\"preserve\">\n    <value>모듈: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying a module name. {0} is replaced with the name of the module from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationModuleWithDetails\" xml:space=\"preserve\">\n    <value>모듈: {0}, 작성자:{1}[{2}]</value>\n    <comment>{Locked=\"{0}\",\"{1}\",\"{2}\"} Label displaying module information. {0} is replaced by the module name. {1} is replaced by the module author. {2} is replaced by a string indicating the source of the module.</comment>\n  </data>\n  <data name=\"ConfigurationSettings\" xml:space=\"preserve\">\n    <value>설정:</value>\n    <comment>Label for the values that are used as inputs for this item when applying state</comment>\n  </data>\n  <data name=\"ConfigurationSuccessfullyApplied\" xml:space=\"preserve\">\n    <value>구성이 적용되었습니다.</value>\n  </data>\n  <data name=\"ConfigurationUnitSuccessfullyApplied\" xml:space=\"preserve\">\n    <value>단위를 적용했습니다.</value>\n  </data>\n  <data name=\"ConfigurationWaitingOnAnother\" xml:space=\"preserve\">\n    <value>시스템에 다른 구성이 적용되고 있습니다. 이 구성은 가능한 한 빨리...</value>\n  </data>\n  <data name=\"ConfigurationWarning\" xml:space=\"preserve\">\n    <value>실행하도록 선택한 구성 설정을 확실히 파악해야 합니다. Microsoft는 사용자가 작성하거나 가져온 구성 파일에 대해 책임을 지지 않습니다. 이 구성은 Windows의 설정을 변경하고, 소프트웨어를 설치하고, 소프트웨어 설정(보안 설정 포함)을 변경하고, 사용자 대신 타사 패키지 및 서비스에 대한 사용자 계약에 동의할 수 있습니다.  이 구성 파일을 실행하면 이러한 리소스 및 설정을 이해하고 동의하는 것입니다. 설치된 모든 응용 프로그램은 소유자에 의해 사용이 허가됩니다. Microsoft는 타사 패키지 또는 서비스에 대한 책임을 지지 않으며 라이선스를 부여하지도 않습니다.</value>\n    <comment>Legal approved. Do not change without approval.</comment>\n  </data>\n  <data name=\"ConfigurationWarningPromptApply\" xml:space=\"preserve\">\n    <value>구성을 검토했으며 계속 시스템에 적용하시겠습니까?</value>\n    <comment>PM approved.</comment>\n  </data>\n  <data name=\"ConfigurationFileEmpty\" xml:space=\"preserve\">\n    <value>구성이 비어 있습니다.</value>\n  </data>\n  <data name=\"WindowsFeatureNotFound\" xml:space=\"preserve\">\n    <value>[{0}] 기능을 찾을 수 없습니다.</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Windows feature was not found on the system.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeatureOverrideRequired\" xml:space=\"preserve\">\n    <value>Windows 기능 종속성을 사용하도록 설정하지 못했습니다. 설치를 계속하려면 '--force' 사용하세요.</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"RebootRequiredToEnableWindowsFeatureOverrideRequired\" xml:space=\"preserve\">\n    <value>Windows 기능을 완전히 사용하도록 설정하려면 다시 부팅해야 합니다. 이 검사 재정의하려면 '--force'를 사용하십시오.</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeatureOverridden\" xml:space=\"preserve\">\n    <value>Windows 기능 종속성을 사용하도록 설정하지 못했습니다. --force 때문에 계속</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.\n{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"EnablingWindowsFeature\" xml:space=\"preserve\">\n    <value>[{0} ]활성화하는 중...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to the user regarding which Windows Feature is being enabled.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeature\" xml:space=\"preserve\">\n    <value>[{0}] 기능을 사용하도록 설정하지 못했습니다.{1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"}  An error when enabling a Windows Feature. {0} is a placeholder for the name of the Windows Feature.\n{1} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"RebootRequiredToEnableWindowsFeatureOverridden\" xml:space=\"preserve\">\n    <value>Windows 기능을 완전히 사용하도록 설정하려면 다시 부팅해야 합니다. --force로 인해 계속</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.</comment>\n  </data>\n  <data name=\"InstallWaitingOnAnother\" xml:space=\"preserve\">\n    <value>다른 설치/제거가 완료되기를 기다리는 중...</value>\n  </data>\n  <data name=\"PinVersion\" xml:space=\"preserve\">\n    <value>고정된 버전</value>\n    <comment>Table header for the version to which a package is pinned; meaning it should not update from that version.</comment>\n  </data>\n  <data name=\"ConfigurationDescriptionWasTruncated\" xml:space=\"preserve\">\n    <value>&lt;자세한 내용은 로그 파일을 참고하세요&gt;</value>\n    <comment>The brackets are intended to make the value stand out from other text which it will follow. Any locale appropriate mechanism that achieves this is acceptable.</comment>\n  </data>\n  <data name=\"ConfigurationGettingDetails\" xml:space=\"preserve\">\n    <value>구성 세부 정보를 검색하는 중</value>\n  </data>\n  <data name=\"ConfigurationInitializing\" xml:space=\"preserve\">\n    <value>구성 시스템을 초기화하는 중</value>\n  </data>\n  <data name=\"ConfigurationReadingConfigFile\" xml:space=\"preserve\">\n    <value>구성 파일을 읽는 중</value>\n  </data>\n  <data name=\"ConfigurationUnitAssertHadNegativeResult\" xml:space=\"preserve\">\n    <value>시스템이 구성에서 어설션된 원하는 상태가 아닙니다.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailed\" xml:space=\"preserve\">\n    <value>알 수 없는 이유로 이 구성 단위가 실패했습니다. {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedConfigSet\" xml:space=\"preserve\">\n    <value>구성으로 인해 구성 단위가 실패했습니다. {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringGet\" xml:space=\"preserve\">\n    <value>현재 시스템 상태를 가져오는 동안 구성 단위가 실패했습니다.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringSet\" xml:space=\"preserve\">\n    <value>원하는 상태를 적용하는 동안 구성 단위가 실패했습니다.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringTest\" xml:space=\"preserve\">\n    <value>현재 시스템 상태를 테스트하는 동안 구성 단위가 실패했습니다.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedInternal\" xml:space=\"preserve\">\n    <value>내부 오류로 인해 구성 단위가 실패했습니다. {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedPrecondition\" xml:space=\"preserve\">\n    <value>사전 조건이 잘못되어 구성 단위가 실패했습니다. {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedSystemState\" xml:space=\"preserve\">\n    <value>시스템 상태로 인해 구성 단위가 실패했습니다. {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedUnitProcessing\" xml:space=\"preserve\">\n    <value>실행하는 동안 구성 단위가 실패했습니다. {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitHasDuplicateIdentifier\" xml:space=\"preserve\">\n    <value>구성에 식별자 '{0}'가 여러 번 포함되어 있습니다.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by the identifier string from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationUnitHasMissingDependency\" xml:space=\"preserve\">\n    <value>구성에서 종속성 '{0}'을(를) 찾을 수 없습니다.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by the identifier string from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationUnitManuallySkipped\" xml:space=\"preserve\">\n    <value>이 구성 단위는 수동으로 건너뛰었습니다.</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleConflict\" xml:space=\"preserve\">\n    <value>구성 단위의 모듈은 같은 버전으로 여러 위치에서 사용할 수 있습니다.</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleImportFailed\" xml:space=\"preserve\">\n    <value>구성 단위에 대한 모듈을 로드하지 못했습니다.</value>\n  </data>\n  <data name=\"ConfigurationUnitMultipleMatches\" xml:space=\"preserve\">\n    <value>구성 단위와 일치하는 항목이 여러 개 있습니다. 모듈을 지정하여 올바른 모듈을 선택하십시오.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotFound\" xml:space=\"preserve\">\n    <value>구성 단위를 찾을 수 없습니다.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotFoundInModule\" xml:space=\"preserve\">\n    <value>구성 단위가 모듈에 예상대로 없습니다.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotRunDueToDependency\" xml:space=\"preserve\">\n    <value>종속성이 실패했거나 실행되지 않았기 때문에 이 구성 단위가 실행되지 않았습니다.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotRunDueToFailedAssert\" xml:space=\"preserve\">\n    <value>어설션이 실패했거나 false이므로 이 구성 단위가 실행되지 않았습니다.</value>\n  </data>\n  <data name=\"ConfigurationUnitReturnedInvalidResult\" xml:space=\"preserve\">\n    <value>구성 단위가 실행 중에 예기치 않은 결과를 반환했습니다.</value>\n  </data>\n  <data name=\"ConfigurationUnitSkipped\" xml:space=\"preserve\">\n    <value>알 수 없는 이유로 이 구성 단위가 실행되지 않았습니다. {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationFieldInvalidValue\" xml:space=\"preserve\">\n    <value>필드 '{0}' 값이 잘못되었습니다. {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} An error in reading a configuration file. {0} is a placeholder replaced by the field name from the file. {1} is a placeholder for the invalid value.</comment>\n  </data>\n  <data name=\"ConfigurationFieldMissing\" xml:space=\"preserve\">\n    <value>'{0}' 필드가 없거나 비어 있습니다.</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the expected field name from the file.</comment>\n  </data>\n  <data name=\"SeeLineAndColumn\" xml:space=\"preserve\">\n    <value>파일의 줄 {0}, 열 {1} 참조하세요.</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Indicates the file location of the error, {0} and {1} are placeholders for numbers of the line and column, respectively.</comment>\n  </data>\n  <data name=\"CancellingOperation\" xml:space=\"preserve\">\n    <value>작업 취소 중</value>\n  </data>\n  <data name=\"InstallStubPackageDescription\" xml:space=\"preserve\">\n    <value>AppInstaller용 스텁 패키지 설치</value>\n  </data>\n  <data name=\"InstallFullPackageDescription\" xml:space=\"preserve\">\n    <value>AppInstaller의 전체 패키지 설치</value>\n  </data>\n  <data name=\"ExtendedFeaturesEnableMessage\" xml:space=\"preserve\">\n    <value>확장 기능을 활성화합니다. 저장소 액세스 권한이 필요합니다.</value>\n  </data>\n  <data name=\"ExtendedFeaturesEnableArgumentError\" xml:space=\"preserve\">\n    <value>옵션 '--enable' 및 '--disable' 다른 인수와 함께 사용할 수 없습니다.</value>\n    <comment>{Locked=\"--enable\", \"--disable\"}</comment>\n  </data>\n  <data name=\"ExtendedFeaturesEnablingMessage\" xml:space=\"preserve\">\n    <value>확장 기능을 활성화하는 중입니다. 저장소 액세스 권한이 필요합니다.</value>\n  </data>\n  <data name=\"ExtendedFeaturesNotEnabledMessage\" xml:space=\"preserve\">\n    <value>확장 기능을 사용할 수 없습니다. 'winget configure --enable'를 실행하여 사용하도록 설정하세요.</value>\n    <comment>{Locked=\"winget configure --enable\"}</comment>\n  </data>\n  <data name=\"ExtendedFeaturesEnabledMessage\" xml:space=\"preserve\">\n    <value>확장 기능이 활성화되어 있습니다.</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisableMessage\" xml:space=\"preserve\">\n    <value>확장 기능을 비활성화합니다. 저장소 액세스 권한이 필요합니다.</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisablingMessage\" xml:space=\"preserve\">\n    <value>확장 기능을 비활성화하는 중입니다. 저장소 액세스 권한이 필요합니다.</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisabledMessage\" xml:space=\"preserve\">\n    <value>확장 기능이 비활성화되어 있습니다.</value>\n  </data>\n  <data name=\"SkipDependenciesArgumentDescription\" xml:space=\"preserve\">\n    <value>패키지 종속성 및 Windows 기능 처리를 건너뜁니다.</value>\n  </data>\n  <data name=\"DependenciesSkippedMessage\" xml:space=\"preserve\">\n    <value>종속성을 건너뛰었습니다.</value>\n  </data>\n  <data name=\"FailedToRefreshPathWarning\" xml:space=\"preserve\">\n    <value>프로세스의 PATH 변수를 새로 고치지 못했습니다. PATH 변수 변경에 따라 후속 설치가 실패할 수 있습니다.</value>\n    <comment>{Locked=\"PATH\"}</comment>\n  </data>\n  <data name=\"ConfigurationFailedToTest\" xml:space=\"preserve\">\n    <value>상태를 테스트하는 동안 일부 구성 단위가 실패했습니다.</value>\n  </data>\n  <data name=\"ConfigurationInDesiredState\" xml:space=\"preserve\">\n    <value>시스템이 설명된 구성 상태에 있습니다.</value>\n  </data>\n  <data name=\"ConfigurationNoTestRun\" xml:space=\"preserve\">\n    <value>구성 상태가 테스트되지 않았습니다.</value>\n  </data>\n  <data name=\"ConfigurationNotInDesiredState\" xml:space=\"preserve\">\n    <value>시스템이 설명된 구성 상태가 아닙니다.</value>\n  </data>\n  <data name=\"ConfigurationUnexpectedTestResult\" xml:space=\"preserve\">\n    <value>예상치 못한 테스트 결과: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message. {0} will be replaced with the unexpected value (a number).</comment>\n  </data>\n  <data name=\"ConfigurationWarningPromptTest\" xml:space=\"preserve\">\n    <value>구성을 검토했으며 시스템에 대해 계속해서 확인하시겠습니까?</value>\n  </data>\n  <data name=\"ConfigurationFileInvalidYAML\" xml:space=\"preserve\">\n    <value>구성 파일이 올바른 YAML 파일이 아닙니다.</value>\n    <comment>{Locked=\"YAML\"} YAML is a file format name.</comment>\n  </data>\n  <data name=\"ConfigurationUnitIsPartOfDependencyCycle\" xml:space=\"preserve\">\n    <value>이 구성 단위는 종속성 주기의 일부입니다.</value>\n  </data>\n  <data name=\"ConfigurationValidationFoundNoIssues\" xml:space=\"preserve\">\n    <value>유효성 검사 결과 문제가 발견되지 않았습니다.</value>\n  </data>\n  <data name=\"ConfigurationUnitNeedsPrereleaseWarning\" xml:space=\"preserve\">\n    <value>구성 단위는 시험판으로만 제공되지만 구성에는 그런 방식으로 표시되지 않습니다. `directives`에 `allowPrerelease: true`를 추가합니다.</value>\n    <comment>{Locked=\"allowPrerelease: true\",\"directives\"} These are values in the configuration file that are not localized.</comment>\n  </data>\n  <data name=\"ConfigurationUnitNotInCatalogWarning\" xml:space=\"preserve\">\n    <value>구성 단위를 로컬에서 찾았지만 구성된 카탈로그에서 찾을 수 없습니다. 구성을 적용하기 전에 시스템에 있는지 확인하세요.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotPublicWarning\" xml:space=\"preserve\">\n    <value>구성 단위는 공개적으로 사용할 수 없습니다. 이 구성을 사용하는 사람은 누구나 해당 구성에 액세스할 수 있는지 확인하세요.</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleNotProvidedWarning\" xml:space=\"preserve\">\n    <value>모듈이 제공되지 않았습니다. 모듈을 지정하면 성능이 향상되고 이후 이름 충돌이 방지됩니다.</value>\n  </data>\n  <data name=\"DownloadCommandLongDescription\" xml:space=\"preserve\">\n    <value>구성된 소스를 검색하거나 매니페스트에서 직접 찾은 선택한 패키지에서 설치 관리자를 다운로드합니다. 기본적으로 쿼리는 대/소문자를 구분하지 않는 패키지의 ID, 이름 또는 모니커와 일치해야 합니다. 다른 필드는 해당 옵션을 전달하여 사용할 수 있습니다. 기본적으로 다운로드 명령은 적절한 설치 관리자를 사용자의 다운로드 폴더에 다운로드합니다.</value>\n  </data>\n  <data name=\"DownloadCommandShortDescription\" xml:space=\"preserve\">\n    <value>특정 패키지에서 설치 프로그램을 다운로드합니다.</value>\n  </data>\n  <data name=\"DownloadDirectoryArgumentDescription\" xml:space=\"preserve\">\n    <value>설치 프로그램이 다운로드되는 디렉터리</value>\n  </data>\n  <data name=\"DependenciesFlowDownload\" xml:space=\"preserve\">\n    <value>종속성 다운로드 중:</value>\n  </data>\n  <data name=\"InstallerDownloaded\" xml:space=\"preserve\">\n    <value>설치 프로그램 다운로드됨: {0}</value>\n    <comment>{Locked=\"{0}\"} Full path of the downloaded installer.</comment>\n  </data>\n  <data name=\"InstallerTypeArgumentDescription\" xml:space=\"preserve\">\n    <value>설치 프로그램 유형 선택</value>\n  </data>\n  <data name=\"InstallerDownloads\" xml:space=\"preserve\">\n    <value>설치 프로그램 다운로드</value>\n  </data>\n  <data name=\"InstallerDownloadCommandProhibited\" xml:space=\"preserve\">\n    <value>나중에 오프라인 설치를 위해 설치 관리자를 다운로드할 수 없습니다. </value>\n  </data>\n  <data name=\"ConfigurationAllUsersElevated\" xml:space=\"preserve\">\n    <value>'--module-path allusers'를 실행하려면 관리자 권한이 필요합니다.</value>\n    <comment>{Locked=\"--module-path allusers\"}</comment>\n  </data>\n  <data name=\"ConfigurationModulePath\" xml:space=\"preserve\">\n    <value>모듈을 저장할 로컬 컴퓨터의 위치를 지정합니다. 기본값 %LOCALAPPDATA%\\Microsoft\\WinGet\\Configuration\\Modules</value>\n    <comment>{Locked=\"%LOCALAPPDATA%\\Microsoft\\WinGet\\Configuration\\Modules\"}</comment>\n  </data>\n  <data name=\"ConfigurationModulePathArgError\" xml:space=\"preserve\">\n    <value>'--module-path' 값은 'currentuser', 'allusers', 'default' 또는 절대 경로여야 합니다.</value>\n    <comment>{Locked=\"{--module-path}, {currentuser}, {allusers}, {default}}</comment>\n  </data>\n  <data name=\"PolicyEnableWinGetConfiguration\" xml:space=\"preserve\">\n    <value>Windows 패키지 관리자 구성 사용</value>\n  </data>\n  <data name=\"ErrorCommandLongDescription\" xml:space=\"preserve\">\n    <value>오류에 대한 정보를 검색합니다. 숫자로 지정하면 출력에 winget 특정 오류인 경우 기호 이름을 포함하여 오류에 대한 세부 정보가 포함됩니다. 문자열이 지정되면 winget 관련 오류가 이 값을 검색합니다.</value>\n  </data>\n  <data name=\"ErrorCommandShortDescription\" xml:space=\"preserve\">\n    <value>오류에 대한 정보 가져오기</value>\n  </data>\n  <data name=\"ErrorInputArgumentDescription\" xml:space=\"preserve\">\n    <value>오류 정보 내에서 검색할 값입니다.</value>\n  </data>\n  <data name=\"ErrorNumberIsTooLarge\" xml:space=\"preserve\">\n    <value>주어진 숫자가 너무 커서 HRESULT가 될 수 없습니다.</value>\n  </data>\n  <data name=\"UnknownErrorCode\" xml:space=\"preserve\">\n    <value>알 수 없는 오류 코드</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INTERNAL_ERROR\" xml:space=\"preserve\">\n    <value>내부 오류</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS\" xml:space=\"preserve\">\n    <value>잘못된 명령줄 인수</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMMAND_FAILED\" xml:space=\"preserve\">\n    <value>명령을 실행하지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_FAILED\" xml:space=\"preserve\">\n    <value>매니페스트를 열지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CTRL_SIGNAL_RECEIVED\" xml:space=\"preserve\">\n    <value>취소 신호 수신됨</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SHELLEXEC_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>ShellExecute를 실행하지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_MANIFESTVERSION\" xml:space=\"preserve\">\n    <value>매니페스트를 처리할 수 없습니다. 매니페스트 버전이 지원되는 버전보다 높습니다. 클라이언트를 업데이트하세요.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_FAILED\" xml:space=\"preserve\">\n    <value>설치 관리자를 다운로드하지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX\" xml:space=\"preserve\">\n    <value>인덱스에 쓸 수 없습니다. 상위 스키마 버전입니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INDEX_INTEGRITY_COMPROMISED\" xml:space=\"preserve\">\n    <value>인덱스가 손상되었습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCES_INVALID\" xml:space=\"preserve\">\n    <value>구성된 원본 정보가 손상되었습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NAME_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>원본 이름이 이미 구성되어 있습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_SOURCE_TYPE\" xml:space=\"preserve\">\n    <value>원본 유형이 잘못되었습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_BUNDLE\" xml:space=\"preserve\">\n    <value>MSIX 파일은 패키지가 아닌 번들입니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_DATA_MISSING\" xml:space=\"preserve\">\n    <value>원본에 필요한 데이터가 없습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER\" xml:space=\"preserve\">\n    <value>현재 시스템에 적용할 수 있는 설치 관리자가 없습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_HASH_MISMATCH\" xml:space=\"preserve\">\n    <value>설치 관리자 파일의 해시가 매니페스트와 일치하지 않습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NAME_DOES_NOT_EXIST\" xml:space=\"preserve\">\n    <value>원본 이름이 없습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_ARG_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>원본 위치가 이미 다른 이름으로 구성되어 있습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICATIONS_FOUND\" xml:space=\"preserve\">\n    <value>패키지를 찾을 수 없음</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_SOURCES_DEFINED\" xml:space=\"preserve\">\n    <value>원본이 구성되지 않았습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_APPLICATIONS_FOUND\" xml:space=\"preserve\">\n    <value>조건과 일치하는 여러 패키지가 있습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_MANIFEST_FOUND\" xml:space=\"preserve\">\n    <value>조건과 일치하는 매니페스트를 찾을 수 없습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXTENSION_PUBLIC_FAILED\" xml:space=\"preserve\">\n    <value>원본 패키지에서 공용 폴더를 가져오지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMMAND_REQUIRES_ADMIN\" xml:space=\"preserve\">\n    <value>명령을 실행하려면 관리자 권한이 필요합니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NOT_SECURE\" xml:space=\"preserve\">\n    <value>원본 위치가 안전하지 않습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>Microsoft Store 클라이언트가 정책에 의해 차단됨</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_APP_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>Microsoft Store 앱이 정책에 의해 차단됨</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXPERIMENTAL_FEATURE_DISABLED\" xml:space=\"preserve\">\n    <value>이 기능은 현재 개발 중입니다. winget 설정을 사용하여 사용하도록 설정할 수 있습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Microsoft Store 앱을 설치하지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMPLETE_INPUT_BAD\" xml:space=\"preserve\">\n    <value>자동 완성을 수행하지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED\" xml:space=\"preserve\">\n    <value>YAML 파서 초기화 실패</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_MAPPING_KEY\" xml:space=\"preserve\">\n    <value>잘못된 YAML 키가 발견되었습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY\" xml:space=\"preserve\">\n    <value>중복된 YAML 키가 발견되었습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_OPERATION\" xml:space=\"preserve\">\n    <value>잘못된 YAML 작업</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_DOC_BUILD_FAILED\" xml:space=\"preserve\">\n    <value>YAML 문서를 빌드하지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_EMITTER_STATE\" xml:space=\"preserve\">\n    <value>잘못된 YAML 발신기 상태</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_DATA\" xml:space=\"preserve\">\n    <value>잘못된 YAML 데이터</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LIBYAML_ERROR\" xml:space=\"preserve\">\n    <value>LibYAML 오류</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_WARNING\" xml:space=\"preserve\">\n    <value>매니페스트 유효성 검사에 성공했으나 경고가 발생했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_FAILURE\" xml:space=\"preserve\">\n    <value>매니페스트 유효성 검사 실패</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_MANIFEST\" xml:space=\"preserve\">\n    <value>매니페스트가 잘못되었습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>적용 가능한 업데이트를 찾을 수 없음</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPDATE_ALL_HAS_FAILURE\" xml:space=\"preserve\">\n    <value>winget 업그레이드 -- 모두 실패로 완료됨</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_SECURITY_CHECK_FAILED\" xml:space=\"preserve\">\n    <value>설치 관리자에서 보안 검사 실패</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_SIZE_MISMATCH\" xml:space=\"preserve\">\n    <value>다운로드 크기가 예상 콘텐츠 길이와 일치하지 않습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_UNINSTALL_INFO_FOUND\" xml:space=\"preserve\">\n    <value>제거 명령을 찾을 수 없음</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXEC_UNINSTALL_COMMAND_FAILED\" xml:space=\"preserve\">\n    <value>제거 명령을 실행하지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_BREAK_ITERATOR_ERROR\" xml:space=\"preserve\">\n    <value>ICU 중단 반복기 오류</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_CASEMAP_ERROR\" xml:space=\"preserve\">\n    <value>ICU casemap 오류</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_REGEX_ERROR\" xml:space=\"preserve\">\n    <value>ICU regex 오류</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_IMPORT_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>가져온 패키지를 하나 이상 설치하지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NOT_ALL_PACKAGES_FOUND\" xml:space=\"preserve\">\n    <value>요청한 패키지를 하나 이상 찾을 수 없습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE\" xml:space=\"preserve\">\n    <value>Json 파일이 잘못되었습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NOT_REMOTE\" xml:space=\"preserve\">\n    <value>원본 위치가 원격이 아닙니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE\" xml:space=\"preserve\">\n    <value>구성된 rest 원본은 지원되지 않습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA\" xml:space=\"preserve\">\n    <value>REST 원본에서 반환된 데이터가 잘못되었습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>작업이 그룹 정책 의해 차단되었습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_INTERNAL_ERROR\" xml:space=\"preserve\">\n    <value>Rest API 내부 오류</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_URL\" xml:space=\"preserve\">\n    <value>잘못된 REST 원본 URL</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_UNSUPPORTED_MIME_TYPE\" xml:space=\"preserve\">\n    <value>REST API에서 반환된 지원되지 않는 MIME 형식</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_VERSION\" xml:space=\"preserve\">\n    <value>잘못된 REST 원본 계약 버전</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE\" xml:space=\"preserve\">\n    <value>원본 데이터가 손상되었거나 변조되었습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_STREAM_READ_FAILURE\" xml:space=\"preserve\">\n    <value>스트림에서 읽는 동안 오류가 발생했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>패키지 계약이 다음에 동의하지 않았습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PROMPT_INPUT_ERROR\" xml:space=\"preserve\">\n    <value>프롬프트에서 입력을 읽는 동안 오류가 발생했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST\" xml:space=\"preserve\">\n    <value>하나 이상의 원본에서 검색 요청을 지원하지 않습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_ENDPOINT_NOT_FOUND\" xml:space=\"preserve\">\n    <value>나머지 API 엔드포인트를 찾을 수 없습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_OPEN_FAILED\" xml:space=\"preserve\">\n    <value>원본을 열지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>원본 계약이 다음에 동의하지 않았습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CUSTOMHEADER_EXCEEDS_MAXLENGTH\" xml:space=\"preserve\">\n    <value>헤더 크기가 허용되는 제한인 1024자를 초과합니다. 크기를 줄이고 다시 시도하세요.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MISSING_RESOURCE_FILE\" xml:space=\"preserve\">\n    <value>누락된 리소스 파일</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSI_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>MSI 설치를 실행하지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT\" xml:space=\"preserve\">\n    <value>msiexec에 대한 인수가 잘못되었습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FAILED_TO_OPEN_ALL_SOURCES\" xml:space=\"preserve\">\n    <value>하나 이상의 원본을 열지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>종속성 유효성을 검사하지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MISSING_PACKAGE\" xml:space=\"preserve\">\n    <value>하나 이상의 패키지가 없습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_TABLE_COLUMN\" xml:space=\"preserve\">\n    <value>잘못된 테이블 열</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_NOT_NEWER\" xml:space=\"preserve\">\n    <value>업그레이드 버전이 설치된 버전보다 최신 버전이 아닙니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_UNKNOWN\" xml:space=\"preserve\">\n    <value>업그레이드 버전을 알 수 없으며 재정의가 지정되지 않았습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_CONVERSION_ERROR\" xml:space=\"preserve\">\n    <value>ICU 변환 오류</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>휴대용 패키지를 설치하지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_REPARSE_POINT_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>볼륨에서 다시 지점 구문 분석을 지원하지 않습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_PACKAGE_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>다른 원본의 휴대용 패키지가 이미 있습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_SYMLINK_PATH_IS_DIRECTORY\" xml:space=\"preserve\">\n    <value>symlink를 만들 수 없습니다. 경로가 디렉터리를 가리킵니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_PROHIBITS_ELEVATION\" xml:space=\"preserve\">\n    <value>관리자 컨텍스트에서 설치 관리자를 실행할 수 없습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>휴대용 패키지를 제거하지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ARP_VERSION_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>인덱스에 대해 DisplayVersion 값의 유효성을 검사하지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_ARGUMENT\" xml:space=\"preserve\">\n    <value>하나 이상의 인수가 지원되지 않습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_BIND_WITH_EMBEDDED_NULL\" xml:space=\"preserve\">\n    <value>포함된 null 문자는 SQLite에 대해 허용되지 않습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_NOT_FOUND\" xml:space=\"preserve\">\n    <value>보관함에서 중첩 설치 관리자를 찾지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXTRACT_ARCHIVE_FAILED\" xml:space=\"preserve\">\n    <value>보관 파일을 추출하지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_INVALID_PATH\" xml:space=\"preserve\">\n    <value>제공된 중첩 설치 관리자의 상대 파일 경로가 잘못되었습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PINNED_CERTIFICATE_MISMATCH\" xml:space=\"preserve\">\n    <value>서버 인증서가 필요한 값과 일치하지 않습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_LOCATION_REQUIRED\" xml:space=\"preserve\">\n    <value>설치 위치를 제공해야 합니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ARCHIVE_SCAN_FAILED\" xml:space=\"preserve\">\n    <value>보관 맬웨어 검색에 실패했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>설치된 패키지의 버전을 하나 이상 찾았습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PIN_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>패키지에 대한 핀이 이미 있습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PIN_DOES_NOT_EXIST\" xml:space=\"preserve\">\n    <value>패키지에 대한 핀이 없습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_OPEN_PINNING_INDEX\" xml:space=\"preserve\">\n    <value>고정 데이터베이스를 열 수 없습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>하나 이상의 응용 프로그램을 설치하지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>하나 이상의 애플리케이션을 제거하지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NOT_ALL_QUERIES_FOUND_SINGLE\" xml:space=\"preserve\">\n    <value>하나 이상의 쿼리가 정확히 하나의 일치 항목을 반환하지 않았습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_PINNED\" xml:space=\"preserve\">\n    <value>패키지에 업그레이드를 방지하는 PIN이 있습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB\" xml:space=\"preserve\">\n    <value>현재 설치된 패키지는 스텁 패키지입니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_APPTERMINATION_RECEIVED\" xml:space=\"preserve\">\n    <value>응용 프로그램 종료 신호 수신됨</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_DEPENDENCIES\" xml:space=\"preserve\">\n    <value>패키지 종속성을 다운로드하지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_COMMAND_PROHIBITED\" xml:space=\"preserve\">\n    <value>패키지를 다운로드하지 못했습니다. 오프라인 설치를 위해 다운로드할 수 없습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SERVICE_UNAVAILABLE\" xml:space=\"preserve\">\n    <value>필요한 서비스가 사용 중이거나 사용할 수 없습니다. 나중에 다시 시도하세요.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESUME_ID_NOT_FOUND\" xml:space=\"preserve\">\n    <value>제공된 GUID가 올바른 다시 시작 상태에 해당하지 않습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CLIENT_VERSION_MISMATCH\" xml:space=\"preserve\">\n    <value>현재 클라이언트 버전이 저장된 상태의 클라이언트 버전과 일치하지 않습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_RESUME_STATE\" xml:space=\"preserve\">\n    <value>다시 시작 상태 데이터가 잘못되었습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_OPEN_CHECKPOINT_INDEX\" xml:space=\"preserve\">\n    <value>검사점 데이터베이스를 열 수 없습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESUME_LIMIT_EXCEEDED\" xml:space=\"preserve\">\n    <value>최대 다시 시작 제한을 초과했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_AUTHENTICATION_INFO\" xml:space=\"preserve\">\n    <value>잘못된 인증 정보입니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>지원되지 않는 인증 방법입니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED\" xml:space=\"preserve\">\n    <value>인증에 실패했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_INTERACTIVE_REQUIRED\" xml:space=\"preserve\">\n    <value>인증에 실패했습니다. 대화형 인증이 필요합니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_CANCELLED_BY_USER\" xml:space=\"preserve\">\n    <value>인증에 실패했습니다. 사용자가 취소했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_INCORRECT_ACCOUNT\" xml:space=\"preserve\">\n    <value>인증에 실패했습니다. 인증된 계정이 원하는 계정이 아닙니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE\" xml:space=\"preserve\">\n    <value>응용 프로그램이 현재 실행 중입니다. 애플리케이션을 종료한 후 다시 시도하세요.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INSTALL_IN_PROGRESS\" xml:space=\"preserve\">\n    <value>다른 설치가 이미 진행 중입니다. 나중에 다시 시도하세요.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_FILE_IN_USE\" xml:space=\"preserve\">\n    <value>하나 이상의 파일을 사용하고 있습니다. 애플리케이션을 종료한 후 다시 시도하세요.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_MISSING_DEPENDENCY\" xml:space=\"preserve\">\n    <value>이 패키지에 시스템에 종속성이 없습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DISK_FULL\" xml:space=\"preserve\">\n    <value>PC에 더 이상 공간이 없습니다. 공간을 확보한 후 다시 시도하세요.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INSUFFICIENT_MEMORY\" xml:space=\"preserve\">\n    <value>설치할 수 있는 메모리가 부족합니다. 다른 애플리케이션을 닫은 후 다시 시도하세요.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_NO_NETWORK\" xml:space=\"preserve\">\n    <value>이 응용 프로그램을 사용하려면 인터넷에 연결해야 합니다. 네트워크에 연결한 후 다시 시도하세요.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CONTACT_SUPPORT\" xml:space=\"preserve\">\n    <value>설치하는 동안 이 응용 프로그램에 오류가 발생했습니다. 고객 지원에 문의하세요.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_TO_FINISH\" xml:space=\"preserve\">\n    <value>PC를 다시 시작하여 설치를 완료합니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_FOR_INSTALL\" xml:space=\"preserve\">\n    <value>설치하지 못했습니다. PC를 다시 시작한 후 다시 시도하세요.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_INITIATED\" xml:space=\"preserve\">\n    <value>설치를 마치기 위해 PC가 다시 시작됩니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CANCELLED_BY_USER\" xml:space=\"preserve\">\n    <value>설치를 취소했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>이 응용 프로그램의 다른 버전이 이미 설치되어 있습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DOWNGRADE\" xml:space=\"preserve\">\n    <value>이 응용 프로그램의 상위 버전이 이미 설치되어 있습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>조직 정책으로 인해 설치할 수 없습니다. 관리자에게 문의하세요.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DEPENDENCIES\" xml:space=\"preserve\">\n    <value>패키지 종속성을 설치하지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE_BY_APPLICATION\" xml:space=\"preserve\">\n    <value>현재 다른 응용 프로그램에서 응용 프로그램을 사용하고 있습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INVALID_PARAMETER\" xml:space=\"preserve\">\n    <value>잘못된 매개 변수입니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>시스템에서 패키지가 지원되지 않습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_UPGRADE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>설치 관리자가 기존 패키지 업그레이드를 지원하지 않습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CUSTOM_ERROR\" xml:space=\"preserve\">\n    <value>사용자 지정 설치 관리자 오류로 설치하지 못했습니다.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_ARP_ENTRY_NOT_FOUND\" xml:space=\"preserve\">\n    <value>패키지에 대한 앱 및 기능 항목을 찾을 수 없습니다.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>설치 위치를 적용할 수 없습니다.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_FOUND\" xml:space=\"preserve\">\n    <value>설치 위치를 찾을 수 없습니다.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_HASH_MISMATCH\" xml:space=\"preserve\">\n    <value>기존 파일의 해시가 일치하지 않습니다.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_NOT_FOUND\" xml:space=\"preserve\">\n    <value>파일을 찾을 수 없습니다.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK\" xml:space=\"preserve\">\n    <value>파일을 찾았지만 해시가 확인되지 않았습니다.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_ACCESS_ERROR\" xml:space=\"preserve\">\n    <value>파일에 액세스할 수 없습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE\" xml:space=\"preserve\">\n    <value>구성 파일이 잘못되었습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_YAML\" xml:space=\"preserve\">\n    <value>YAML 구문이 잘못되었습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_FIELD_TYPE\" xml:space=\"preserve\">\n    <value>구성 필드에 잘못된 형식이 있습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION\" xml:space=\"preserve\">\n    <value>구성에 알 수 없는 버전이 있습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_SET_APPLY_FAILED\" xml:space=\"preserve\">\n    <value>구성을 적용하는 동안 오류가 발생했습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER\" xml:space=\"preserve\">\n    <value>구성에 중복 식별자가 포함되어 있습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MISSING_DEPENDENCY\" xml:space=\"preserve\">\n    <value>구성에 종속성이 없습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED\" xml:space=\"preserve\">\n    <value>구성에 만족스럽지 않은 종속성이 있습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_ASSERTION_FAILED\" xml:space=\"preserve\">\n    <value>구성 단위에 대한 어설션이 실패했습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MANUALLY_SKIPPED\" xml:space=\"preserve\">\n    <value>구성을 수동으로 건너뛰었습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_WARNING_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>사용자가 실행을 계속하기를 거부했습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_SET_DEPENDENCY_CYCLE\" xml:space=\"preserve\">\n    <value>종속성 그래프 확인할 수 없는 주기가 포함되어 있습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_FIELD_VALUE\" xml:space=\"preserve\">\n    <value>구성에 잘못된 필드 값이 있습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MISSING_FIELD\" xml:space=\"preserve\">\n    <value>구성에 필드가 없습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_TEST_FAILED\" xml:space=\"preserve\">\n    <value>상태를 테스트하는 동안 일부 구성 단위가 실패했습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_TEST_NOT_RUN\" xml:space=\"preserve\">\n    <value>구성 상태가 테스트되지 않았습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_NOT_INSTALLED\" xml:space=\"preserve\">\n    <value>구성 단위가 설치되지 않았습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_NOT_FOUND_REPOSITORY\" xml:space=\"preserve\">\n    <value>구성 단위를 찾을 수 없습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_MULTIPLE_MATCHES\" xml:space=\"preserve\">\n    <value>구성 단위와 일치하는 항목이 여러 개 있습니다. 모듈을 지정하여 올바른 모듈을 선택하십시오.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_GET\" xml:space=\"preserve\">\n    <value>현재 시스템 상태를 가져오는 동안 구성 단위가 실패했습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_TEST\" xml:space=\"preserve\">\n    <value>현재 시스템 상태를 테스트하는 동안 구성 단위가 실패했습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_SET\" xml:space=\"preserve\">\n    <value>원하는 상태를 적용하는 동안 구성 단위가 실패했습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_MODULE_CONFLICT\" xml:space=\"preserve\">\n    <value>구성 단위의 모듈은 같은 버전으로 여러 위치에서 사용할 수 있습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE\" xml:space=\"preserve\">\n    <value>구성 단위에 대한 모듈을 로드하지 못했습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_INVALID_RESULT\" xml:space=\"preserve\">\n    <value>구성 단위가 실행 중에 예기치 않은 결과를 반환했습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_SETTING_CONFIG_ROOT\" xml:space=\"preserve\">\n    <value>구성 루트가 필요한 설정이 단위에 포함되어 있습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR\" xml:space=\"preserve\">\n    <value>구성 프로세서에서 지원하지 않는 작업입니다.</value>\n  </data>\n  <data name=\"Unavailable\" xml:space=\"preserve\">\n    <value>사용할 수 없음</value>\n  </data>\n  <data name=\"EnableWindowsFeaturesSuccess\" xml:space=\"preserve\">\n    <value>Windows 기능 종속성을 사용하도록 설정함</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE_ADMIN\" xml:space=\"preserve\">\n    <value>구성 단위를 실행하려면 관리자 권한이 필요하므로 구성 단위에 대한 모듈을 로드하지 못했습니다.</value>\n  </data>\n  <data name=\"ConfigurationUnitSettingConfigRoot\" xml:space=\"preserve\">\n    <value>구성 루트가 필요한 설정이 단위에 포함되어 있습니다.</value>\n  </data>\n  <data name=\"ConfigurationUnitImportModuleAdmin\" xml:space=\"preserve\">\n    <value>구성 단위를 실행하려면 관리자 권한이 필요하므로 구성 단위에 대한 모듈을 로드하지 못했습니다.</value>\n  </data>\n  <data name=\"ResumeCommandLongDescription\" xml:space=\"preserve\">\n    <value>저장된 명령의 고유 식별자를 전달하여 이전에 저장한 명령의 실행을 다시 시작합니다. 다시 부팅으로 인해 종료되었을 수 있는 실행된 명령을 다시 시작하는 데 사용됩니다.</value>\n  </data>\n  <data name=\"ResumeCommandShortDescription\" xml:space=\"preserve\">\n    <value>이전에 저장된 명령의 실행을 다시 시작합니다.</value>\n  </data>\n  <data name=\"ResumeIdArgumentDescription\" xml:space=\"preserve\">\n    <value>다시 시작할 저장된 상태의 고유 식별자입니다.</value>\n  </data>\n  <data name=\"ClientVersionMismatchError\" xml:space=\"preserve\">\n    <value>다른 클라이언트 버전에서 상태를 다시 시작하는 것은 지원되지 않습니다. {0}</value>\n    <comment>{Locked= \"{0}\"} Message displayed to inform the user that the client version of the resume state does not match the current client version. {0} is a placeholder for the client version that created the resume state.</comment>\n  </data>\n  <data name=\"ResumeIdNotFoundError\" xml:space=\"preserve\">\n    <value>다시 시작 상태가 없습니다. {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a guid that does not correspond to a valid saved state. {0} is a placeholder replaced by the provided guid string.</comment>\n  </data>\n  <data name=\"ResumeStateDataNotFoundError\" xml:space=\"preserve\">\n    <value>다시 시작 상태에서 데이터를 찾을 수 없습니다.</value>\n  </data>\n  <data name=\"CommandDoesNotSupportResumeMessage\" xml:space=\"preserve\">\n    <value>이 명령은 다시 시작이 지원되지 않습니다.</value>\n  </data>\n  <data name=\"AllowRebootArgumentDescription\" xml:space=\"preserve\">\n    <value>해당하는 경우 다시 부팅 허용</value>\n  </data>\n  <data name=\"InitiatingReboot\" xml:space=\"preserve\">\n    <value>작업을 완료하기 위해 다시 부팅을 시작하는 중...</value>\n  </data>\n  <data name=\"FailedToInitiateReboot\" xml:space=\"preserve\">\n    <value>다시 부팅을 시작하지 못했습니다.</value>\n  </data>\n  <data name=\"ResumeLimitExceeded\" xml:space=\"preserve\">\n    <value>다시 시작 작업이 허용되는 {0} 다시 시작 제한을 초과합니다. 수동으로 다시 시작하려면 '{1}' 명령을 실행하십시오.</value>\n    <comment>{Locked=\"{0}\", \"{1}\"} {0} is a placeholder that is replaced by an integer number of the number of allowed resumes. {1} is a placeholder for the command to run to perform a manual resume.</comment>\n  </data>\n  <data name=\"IgnoreResumeLimitArgumentDescription\" xml:space=\"preserve\">\n    <value>저장된 상태 다시 시작 시 제한 무시</value>\n  </data>\n  <data name=\"UriSchemeNotSupported\" xml:space=\"preserve\">\n    <value>{0} URI 체계는 지원되지 않습니다.</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the provided uri is not supported. {0} is a placeholder replaced by the provided uri.</comment>\n  </data>\n  <data name=\"UriNotWellFormed\" xml:space=\"preserve\">\n    <value>URI 형식이 잘못되었습니다. {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the provided uri is not well formed. {0} is a placeholder replaced by the provided uri.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitEmptyContent\" xml:space=\"preserve\">\n    <value>구성 단위 설정 콘텐츠 또는 설정 콘텐츠가 비어 {0} 구문 분석하지 못했습니다.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder replaced by the input winget configure resource unit type.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitMissingRequiredArg\" xml:space=\"preserve\">\n    <value>{0} 구성 단위에 필수 인수가 없습니다. {1}</value>\n    <comment>{Locked=\"{0},{1}\"} {0} is a placeholder for the input winget configure resource unit type. {1} is placeholder for the missing arg.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitMissingRecommendedArg\" xml:space=\"preserve\">\n    <value>{0} 구성 단위에 권장 인수가 없습니다. {1}</value>\n    <comment>{Locked=\"{0},{1}\"} {0} is a placeholder for the input winget configure resource unit type. {1} is placeholder for the missing arg.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitKnownSourceConfliction\" xml:space=\"preserve\">\n    <value>WinGetSource 구성 단위가 알려진 원본과 충돌합니다. {0}</value>\n    <comment>{Locked=\"WinGetSource,{0}\"} {0} is a placeholder for the input winget source in the configuration unit settings.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitThirdPartySourceAssertion\" xml:space=\"preserve\">\n    <value>WinGetSource 구성 단위는 타사 원본에서 어설션합니다. {0}</value>\n    <comment>{Locked=\"WinGetSource,{0}\"} {0} is a placeholder for the input winget source in the configuration unit settings.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitBothPackageVersionAndUseLatest\" xml:space=\"preserve\">\n    <value>WinGetPackage가 UseLatest와 Version을 모두 선언합니다. 패키지 ID: {0}</value>\n    <comment>{Locked=\"WinGetPackage,UseLatest,Version,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitThirdPartySourceAssertionForPackage\" xml:space=\"preserve\">\n    <value>WinGetPackage 구성 단위는 타사 소스의 패키지에 대해 어설션합니다. 패키지 ID: {0}; 원본: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitDependencySourceNotConfigured\" xml:space=\"preserve\">\n    <value>WinGetPackage 구성 단위 패키지는 이전에 구성되지 않은 타사 원본에 종속됩니다. 패키지 ID: {0}; 원본: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitDependencySourceNotDeclaredAsDependency\" xml:space=\"preserve\">\n    <value>WinGetPackage 구성 단위 패키지는 타사 원본에 종속됩니다. uni dependsOn 섹션에 종속성을 선언하는 것이 좋습니다. 패키지 ID: {0}; 원본: {1}</value>\n    <comment>{Locked=\"WinGetPackage,dependsOn,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageSourceOpenFailed\" xml:space=\"preserve\">\n    <value>WinGetPackage 구성 단위 패키지의 유효성을 검사할 수 없습니다. 원본을 열지 못했습니다. 패키지 ID: {0}; 원본: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageNotFound\" xml:space=\"preserve\">\n    <value>WinGetPackage 구성 단위 패키지의 유효성을 검사할 수 없습니다. 패키지를 찾을 수 없습니다. 패키지 ID: {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageMultipleFound\" xml:space=\"preserve\">\n    <value>WinGetPackage 구성 단위 패키지의 유효성을 검사할 수 없습니다. 패키지를 두 개 이상 찾았습니다. 패키지 ID: {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageVersionNotFound\" xml:space=\"preserve\">\n    <value>WinGetPackage 구성 단위 패키지의 유효성을 검사할 수 없습니다. 패키지 버전을 찾을 수 없습니다. 패키지 ID: {0}; 버전 {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitPackageVersionSpecifiedWithOnlyOnePackageVersion\" xml:space=\"preserve\">\n    <value>WinGetPackage 구성 단위 패키지는 특정 버전으로 지정되지만 하나의 패키지 버전만 사용할 수 있습니다. 패키지 ID: {0}, 버전: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackage\" xml:space=\"preserve\">\n    <value>WinGetPackage 구성 단위 패키지의 유효성을 검사할 수 없습니다. 패키지 ID: {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"AuthenticationModeArgumentDescription\" xml:space=\"preserve\">\n    <value>인증 창 기본 설정 지정(silent, silentPreferred 또는 interactive)</value>\n    <comment>{Locked=\"silent\",\"silentPreferred\",\"interactive\"} This argument allows the user to select authentication window popup behavior.</comment>\n  </data>\n  <data name=\"AuthenticationAccountArgumentDescription\" xml:space=\"preserve\">\n    <value>인증에 사용할 계정 지정</value>\n  </data>\n  <data name=\"SourceAddFailedAuthenticationNotSupported\" xml:space=\"preserve\">\n    <value>원본을 추가하지 못했습니다. 이 winget 버전에서는 원본의 인증 방법을 지원하지 않습니다. 최신 winget 버전으로 업그레이드해 보세요.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"SourceRequiresAuthentication\" xml:space=\"preserve\">\n    <value>{0} 원본을 인증해야 합니다. 필요한 경우 인증 프롬프트가 표시될 수 있습니다. 인증된 정보는 액세스 권한 부여를 위해 원본과 공유됩니다.</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"RepairCommandLongDescription\" xml:space=\"preserve\">\n    <value>설치된 패키지 목록을 검색하거나 매니페스트에서 직접 선택한 패키지를 복구합니다. 기본적으로 쿼리는 대/소문자를 구분하지 않는 패키지의 ID, 이름 또는 모니커와 일치해야 합니다. 다른 필드는 해당 옵션을 전달하여 사용할 수 있습니다.</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"RepairCommandShortDescription\" xml:space=\"preserve\">\n    <value>선택한 패키지를 복구합니다.</value>\n  </data>\n  <data name=\"NoRepairInfoFound\" xml:space=\"preserve\">\n    <value>이 패키지에 대한 복구 명령을 찾을 수 없습니다. 지원을 받으려면 패키지 게시자에 문의하세요.</value>\n  </data>\n  <data name=\"RepairDifferentInstallTechnology\" xml:space=\"preserve\">\n    <value>사용 중인 설치 관리자 기술이 현재 설치된 버전과 일치하지 않습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_REPAIR_INFO_FOUND\" xml:space=\"preserve\">\n    <value>복구 명령을 찾을 수 없습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_REPAIR_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>사용 중인 설치 관리자 기술이 복구를 지원하지 않습니다.</value>\n  </data>\n  <data name=\"RepairFlowRepairSuccess\" xml:space=\"preserve\">\n    <value>복구 작업이 완료되었습니다.</value>\n  </data>\n  <data name=\"RepairAbandoned\" xml:space=\"preserve\">\n    <value>복구 중단됨</value>\n  </data>\n  <data name=\"RepairFlowStartingPackageRepair\" xml:space=\"preserve\">\n    <value>패키지 복구를 시작하는 중...</value>\n  </data>\n  <data name=\"MSStoreRepairFailed\" xml:space=\"preserve\">\n    <value>Microsoft Store 패키지를 복구하지 못했습니다. 오류 코드: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Microsoft Store application package fails to repair. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXEC_REPAIR_FAILED\" xml:space=\"preserve\">\n    <value>복구 작업에 실패했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_REPAIR_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>복구 작업은 적용할 수 없습니다.</value>\n  </data>\n  <data name=\"RepairFlowNoMatchingVersion\" xml:space=\"preserve\">\n    <value>구성된 원본에서 사용할 수 있는 일치하는 패키지 버전이 없습니다.</value>\n  </data>\n  <data name=\"RepairFlowReturnCodeSystemNotSupported\" xml:space=\"preserve\">\n    <value>현재 시스템 구성은 이 패키지의 복구를 지원하지 않습니다.</value>\n  </data>\n  <data name=\"RepairOperationNotSupported\" xml:space=\"preserve\">\n    <value>사용 중인 설치 관리자 기술이 복구를 지원하지 않습니다.</value>\n  </data>\n  <data name=\"NoAdminRepairForUserScopePackage\" xml:space=\"preserve\">\n    <value>관리자 권한으로 실행하는 경우 사용자 scope 위해 설치된 패키지를 복구할 수 없습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED\" xml:space=\"preserve\">\n    <value>사용자 scope 내에 설치된 패키지에서는 관리자 권한과 관련된 복구 작업이 허용되지 않습니다.</value>\n  </data>\n  <data name=\"RepairFailedWithCode\" xml:space=\"preserve\">\n    <value>복구하지 못했습니다. 종료 코드: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to repair an application package fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SQLITE_CONNECTION_TERMINATED\" xml:space=\"preserve\">\n    <value>손상을 방지하기 위해 SQLite 연결을 종료했습니다.</value>\n  </data>\n  <data name=\"UninstallAllVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>모든 버전 제거</value>\n  </data>\n  <data name=\"TargetVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>작업할 버전</value>\n  </data>\n  <data name=\"UninstallFailedDueToMultipleVersions\" xml:space=\"preserve\">\n    <value>이 패키지의 여러 버전이 설치되어 있습니다. 검색을 구체화하거나,'--version' 인수를 전달하여 하나를 선택하거나, '--all-versions' 플래그를 전달하여 모두 제거하세요.</value>\n    <comment>{Locked=\"--version,--all-versions\"}</comment>\n  </data>\n  <data name=\"PolicyEnableProxyCommandLineOptions\" xml:space=\"preserve\">\n    <value>프록시 명령줄 옵션 Windows 패키지 관리자 사용</value>\n    <comment>Describes a Group Policy that can enable the use of the --proxy option to set a proxy</comment>\n  </data>\n  <data name=\"ProxyArgumentDescription\" xml:space=\"preserve\">\n    <value>이 실행에 사용할 프록시 설정</value>\n  </data>\n  <data name=\"NoProxyArgumentDescription\" xml:space=\"preserve\">\n    <value>이 실행에 프록시 사용 안 함</value>\n  </data>\n  <data name=\"ResetAdminSettingFailed\" xml:space=\"preserve\">\n    <value>{0} 다시 설정할 수 없습니다. 이 설정은 정책에 의해 제어됩니다. 자세한 내용은 시스템 관리자에게 문의하십시오.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"ResetAdminSettingSucceeded\" xml:space=\"preserve\">\n    <value>관리자 설정 ‘{0}’을(를) 초기화합니다.</value>\n    <comment>{Locked=\"{0}\"} Message displayed after the user resets an admin setting to its default value. Reset is used as verb in past tense. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"SetAdminSettingFailed\" xml:space=\"preserve\">\n    <value>{0} 설정할 수 없습니다. 이 설정은 정책에 의해 제어됩니다. 자세한 내용은 시스템 관리자에게 문의하십시오.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"SetAdminSettingSucceeded\" xml:space=\"preserve\">\n    <value>관리자 설정 '{0}'을(를) '{1}'(으)로 설정합니다.</value>\n    <comment>{Locked=\"{0}\"} Message displayed after the user sets the value of an admin setting. Set is used as a verb in past tense. {0} is a placeholder replaced by the setting name. {1} is a placeholder replaced </comment>\n  </data>\n  <data name=\"SettingNameArgumentDescription\" xml:space=\"preserve\">\n    <value>수정할 설정의 이름</value>\n  </data>\n  <data name=\"SettingValueArgumentDescription\" xml:space=\"preserve\">\n    <value>설정에 대해 설정할 값입니다.</value>\n  </data>\n  <data name=\"SettingsResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>관리자 설정을 기본값으로 다시 설정합니다.</value>\n  </data>\n  <data name=\"SettingsResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>관리자 설정을 기본값으로 다시 설정합니다.</value>\n  </data>\n  <data name=\"SettingsSetCommandLongDescription\" xml:space=\"preserve\">\n    <value>관리자 설정의 값을 설정합니다.</value>\n  </data>\n  <data name=\"SettingsSetCommandShortDescription\" xml:space=\"preserve\">\n    <value>관리자 설정의 값을 설정합니다.</value>\n  </data>\n  <data name=\"SourceExplicitArgumentDescription\" xml:space=\"preserve\">\n    <value>지정하지 않는 한 검색에서 원본 제외</value>\n  </data>\n  <data name=\"SourceEditExplicitArgumentDescription\" xml:space=\"preserve\">\n    <value>검색에서 원본 제외(true 또는 false)</value>\n  </data>\n  <data name=\"SourceListExplicit\" xml:space=\"preserve\">\n    <value>유해 콘텐츠</value>\n  </data>\n  <data name=\"SourceTrustLevelArgumentDescription\" xml:space=\"preserve\">\n    <value>원본의 신뢰 수준(없음 또는 신뢰할 수 없음)</value>\n  </data>\n  <data name=\"SourceListTrustLevel\" xml:space=\"preserve\">\n    <value>신뢰 수준</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DISPLAYCATALOG_API_FAILED\" xml:space=\"preserve\">\n    <value>Microsoft Store 패키지 카탈로그를 가져오지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_DISPLAYCATALOG_PACKAGE\" xml:space=\"preserve\">\n    <value>Microsoft Store 패키지 카탈로그에서 적용 가능한 Microsoft Store 패키지를 찾을 수 없습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SFSCLIENT_API_FAILED\" xml:space=\"preserve\">\n    <value>Microsoft Store 패키지 다운로드 정보를 가져오지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_SFSCLIENT_PACKAGE\" xml:space=\"preserve\">\n    <value>다운로드할 적용 가능한 Microsoft Store 패키지를 찾을 수 없습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED\" xml:space=\"preserve\">\n    <value>Microsoft Store 패키지 라이선스를 검색하지 못했습니다.</value>\n  </data>\n  <data name=\"MSStoreDownloadNoApplicablePackageFound\" xml:space=\"preserve\">\n    <value>해당하는 Microsoft Store 패키지를 찾을 수 없습니다.</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageHashVerified\" xml:space=\"preserve\">\n    <value>Microsoft Store 패키지 해시가 성공적으로 확인되었습니다.</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageHashMismatch\" xml:space=\"preserve\">\n    <value>Microsoft Store 패키지 해시 불일치</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloaded\" xml:space=\"preserve\">\n    <value>Microsoft Store 패키지 다운로드됨: {0}</value>\n    <comment>{Locked=\"{0}\"} Full path of the downloaded package.</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadFailed\" xml:space=\"preserve\">\n    <value>Microsoft Store 패키지 다운로드 실패: {0}</value>\n    <comment>{Locked=\"{0}\"} Package name.</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadSuccess\" xml:space=\"preserve\">\n    <value>Microsoft Store 패키지 다운로드 완료</value>\n  </data>\n  <data name=\"MSStoreDownloadMainPackages\" xml:space=\"preserve\">\n    <value>Microsoft Store 기본 패키지를 다운로드하는 중...</value>\n  </data>\n  <data name=\"MSStoreDownloadDependencyPackages\" xml:space=\"preserve\">\n    <value>Microsoft Store에서 종속성 패키지를 다운로드하는 중...</value>\n  </data>\n  <data name=\"MSStoreDownloadGetDownloadInfo\" xml:space=\"preserve\">\n    <value>Microsoft Store 패키지 다운로드 정보 검색</value>\n  </data>\n  <data name=\"MSStoreDownloadGetDownloadInfoFailed\" xml:space=\"preserve\">\n    <value>Microsoft Store 패키지 다운로드 정보를 검색하지 못했습니다.</value>\n  </data>\n  <data name=\"MSStoreDownloadGetLicense\" xml:space=\"preserve\">\n    <value>Microsoft Store 패키지 라이선스 검색</value>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseSuccess\" xml:space=\"preserve\">\n    <value>Microsoft Store 패키지 라이선스 저장됨: {0}</value>\n    <comment>{Locked=\"{0}\"} License file full path.</comment>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseFailed\" xml:space=\"preserve\">\n    <value>Microsoft Store 패키지 라이선스를 검색하지 못했습니다.</value>\n  </data>\n  <data name=\"MSStoreDownloadRenameNotSupported\" xml:space=\"preserve\">\n    <value>Microsoft Store 패키지 다운로드는 --rename 인수를 지원하지 않습니다. Microsoft Store 패키지는 Microsoft Store 카탈로그에서 제공하는 이름을 사용합니다.</value>\n    <comment>{Locked=\"--rename\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadAuthenticationNotice\" xml:space=\"preserve\">\n    <value>Microsoft Store 패키지를 다운로드하려면 Microsoft Entra ID 인증이 필요합니다. 필요한 경우 인증 프롬프트가 표시될 수 있습니다. 인증된 정보는 액세스 권한 부여를 위해 Microsoft 서비스 공유됩니다. Microsoft Store 패키지 라이선스의 경우 Microsoft Entra ID 계정은 전역 관리자, 사용자 관리자 또는 라이선스 관리자의 구성원이어야 합니다.</value>\n    <comment>{Locked=\"Global Administrator,User Administrator,License Administrator\"}</comment>\n  </data>\n  <data name=\"SkipMicrosoftStorePackageLicenseArgumentDescription\" xml:space=\"preserve\">\n    <value>Microsoft Store 패키지 오프라인 라이선스 검색 건너뛰기</value>\n  </data>\n  <data name=\"PlatformArgumentDescription\" xml:space=\"preserve\">\n    <value>대상 플랫폼 선택</value>\n  </data>\n  <data name=\"ConfigurationExportAddingToFile\" xml:space=\"preserve\">\n    <value>구성 파일 추가: {0}</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportSuccessful\" xml:space=\"preserve\">\n    <value>내보냈습니다.</value>\n  </data>\n  <data name=\"ConfigurationGettingResourceSettings\" xml:space=\"preserve\">\n    <value>구성 설정을 가져오는 중...</value>\n  </data>\n  <data name=\"ConfigureExportArgumentRequiredError\" xml:space=\"preserve\">\n    <value>--resource가 있는 --packageId 및/또는 --module 이상을 제공해야 합니다. 또는 --all을 사용하여 모든 패키지 구성을 내보냅니다.</value>\n    <comment>{Locked=\"--packageId,--module, --resource, --all\"}</comment>\n  </data>\n  <data name=\"ConfigureExportArgumentConflictWithAllError\" xml:space=\"preserve\">\n    <value>--packageId, --module 및 --resource 인수는 --all과 함께 사용할 수 없습니다.</value>\n    <comment>{Locked=\"--packageId,--module, --resource, --all\"}</comment>\n  </data>\n  <data name=\"ConfigureExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>구성 리소스를 구성 파일로 내보냅니다. --all과 함께 사용하면 모든 패키지 구성을 내보냅니다. --packageId와 함께 사용하면 지정된 패키지 ID의 WinGetPackage 리소스를 내보냅니다. --module 및 --resource와 함께 사용하면 리소스의 설정을 가져오고 구성 파일로 내보냅니다. 출력 구성 파일이 이미 있으면 내보낸 구성 리소스를 추가합니다.</value>\n    <comment>{Locked=\"WinGetPackage,--packageId,--module, --resource\"}</comment>\n  </data>\n  <data name=\"ConfigureExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>구성 리소스를 구성 파일로 내보냅니다.</value>\n  </data>\n  <data name=\"ConfigureExportModule\" xml:space=\"preserve\">\n    <value>내보낼 리소스의 모듈입니다.</value>\n  </data>\n  <data name=\"ConfigureExportPackageId\" xml:space=\"preserve\">\n    <value>내보낼 패키지 식별자입니다.</value>\n  </data>\n  <data name=\"ConfigureExportResource\" xml:space=\"preserve\">\n    <value>내보낼 구성 리소스입니다.</value>\n  </data>\n  <data name=\"ConfigureExportAll\" xml:space=\"preserve\">\n    <value>모든 패키지 구성을 내보냅니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_GET_FAILED\" xml:space=\"preserve\">\n    <value>구성 단위가 해당 속성을 가져오지 못했습니다.</value>\n  </data>\n  <data name=\"ConfigurationExportFailed\" xml:space=\"preserve\">\n    <value>구성을 내보내지 못했습니다.</value>\n  </data>\n  <data name=\"ConfigureExportUnitDescription\" xml:space=\"preserve\">\n    <value>{0} 구성</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigureExportUnitInstallDescription\" xml:space=\"preserve\">\n    <value>{0} 설치</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationWarningSetViewTruncated\" xml:space=\"preserve\">\n    <value>구성 파일에 있는 일부 데이터가 이 출력에 대해 잘렸습니다. 파일 콘텐츠를 검사하여 전체 콘텐츠를 검사합니다.</value>\n  </data>\n  <data name=\"ConfigurationWarningValueTruncated\" xml:space=\"preserve\">\n    <value>&lt;이 값이 잘렸습니다. 전체 텍스트를 보려면 파일 내용을 검사합니다&gt;</value>\n    <comment>Keep some form of separator like the \"&lt;&gt;\" around the text so that it stands out from the preceding text.</comment>\n  </data>\n  <data name=\"ConfigureListCommandLongDescription\" xml:space=\"preserve\">\n    <value>시스템에 적용된 구성에 대한 높은 수준의 세부 정보를 표시합니다. 그런 다음 이 데이터를 `configure` 명령과 함께 사용하여 자세한 정보를 확인할 수 있습니다.</value>\n    <comment>{Locked=\"`configure`\"}</comment>\n  </data>\n  <data name=\"ConfigureListCommandShortDescription\" xml:space=\"preserve\">\n    <value>구성 기록 표시</value>\n  </data>\n  <data name=\"ConfigurationHistoryEmpty\" xml:space=\"preserve\">\n    <value>기록에 구성이 없습니다.</value>\n  </data>\n  <data name=\"ConfigurationHistoryItemArgumentDescription\" xml:space=\"preserve\">\n    <value>기록에서 항목 선택</value>\n  </data>\n  <data name=\"ConfigurationHistoryItemNotFound\" xml:space=\"preserve\">\n    <value>제공된 데이터와 일치하는 단일 구성을 찾을 수 없습니다. 원하는 구성과 명확하게 일치하는 식별자의 전체 이름 또는 일부를 제공하십시오.</value>\n  </data>\n  <data name=\"ConfigurationHistoryRemoveArgumentDescription\" xml:space=\"preserve\">\n    <value>기록에서 항목 제거</value>\n  </data>\n  <data name=\"ConfigureListFirstApplied\" xml:space=\"preserve\">\n    <value>처음 적용됨</value>\n    <comment>Column header for date values indicating when a configuration was first applied to the system.</comment>\n  </data>\n  <data name=\"ConfigureListIdentifier\" xml:space=\"preserve\">\n    <value>식별자</value>\n  </data>\n  <data name=\"ConfigureListName\" xml:space=\"preserve\">\n    <value>이름</value>\n  </data>\n  <data name=\"ConfigureListOrigin\" xml:space=\"preserve\">\n    <value>원본</value>\n  </data>\n  <data name=\"ConfigureListPath\" xml:space=\"preserve\">\n    <value>경로</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_HISTORY_ITEM_NOT_FOUND\" xml:space=\"preserve\">\n    <value>지정한 구성을 찾을 수 없습니다.</value>\n  </data>\n  <data name=\"ConfigurationSetStateCompleted\" xml:space=\"preserve\">\n    <value>완료</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStateInProgress\" xml:space=\"preserve\">\n    <value>진행 중</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStatePending\" xml:space=\"preserve\">\n    <value>보류 중</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStateUnknown\" xml:space=\"preserve\">\n    <value>알 수 없음</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationStatusWatchArgumentDescription\" xml:space=\"preserve\">\n    <value>구성 상태를 모니터링합니다.</value>\n    <comment>As in \"to monitor the status of a configuration being applied\".</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateCompleted\" xml:space=\"preserve\">\n    <value>완료</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateInProgress\" xml:space=\"preserve\">\n    <value>진행 중</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStatePending\" xml:space=\"preserve\">\n    <value>보류 중</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateSkipped\" xml:space=\"preserve\">\n    <value>건너뜀</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateUnknown\" xml:space=\"preserve\">\n    <value>알 수 없음</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigureListApplyBegun\" xml:space=\"preserve\">\n    <value>적용 시작됨</value>\n    <comment>When the configuration application started.</comment>\n  </data>\n  <data name=\"ConfigureListApplyEnded\" xml:space=\"preserve\">\n    <value>적용 종료됨</value>\n    <comment>When the configuration application ended.</comment>\n  </data>\n  <data name=\"ConfigureListResult\" xml:space=\"preserve\">\n    <value>결과</value>\n  </data>\n  <data name=\"ConfigureListResultDescription\" xml:space=\"preserve\">\n    <value>세부 정보</value>\n  </data>\n  <data name=\"ConfigureListState\" xml:space=\"preserve\">\n    <value>상태</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigureListUnit\" xml:space=\"preserve\">\n    <value>단위</value>\n  </data>\n  <data name=\"StoreInstall_PackageNotAvailableForCurrentSystem\" xml:space=\"preserve\">\n    <value>패키지가 현재 Windows 버전 또는 플랫폼과 호환되지 않습니다.</value>\n  </data>\n  <data name=\"ConfigurationSuppressPrologueArgumentDescription\" xml:space=\"preserve\">\n    <value>가능한 경우 초기 구성 세부 정보를 표시하지 않음</value>\n  </data>\n  <data name=\"MSStoreDownloadMultiplePackagesNotice\" xml:space=\"preserve\">\n    <value>여러 플랫폼 및 아키텍처를 대상으로 하는 여러 Microsoft Store 패키지를 다운로드할 수 있습니다. --platform, --architecture를 사용하여 패키지를 필터링할 수 있습니다.</value>\n    <comment>{Locked=\"--platform--architecture\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseForbidden\" xml:space=\"preserve\">\n    <value>Microsoft Store 패키지 라이선스를 검색하지 못했습니다. Microsoft Entra ID 계정이 전역 관리자, 사용자 관리자 또는 라이선스 관리자의 구성원이 아닙니다. --skip-license를 사용하여 Microsoft Store 패키지 라이선스 검색을 건너뜁니다.</value>\n    <comment>{Locked=\"Global Administrator,User Administrator,License Administrator,--skip-license\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadNotSupported\" xml:space=\"preserve\">\n    <value>Microsoft Store 패키지는 다운로드를 지원하지 않습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SFSCLIENT_PACKAGE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Microsoft Store 패키지는 다운로드를 지원하지 않습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED_FORBIDDEN\" xml:space=\"preserve\">\n    <value>Microsoft Store 패키지 라이선스를 검색하지 못했습니다. Microsoft Entra ID 계정에 필요한 권한이 없습니다.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_PARAMETER_INTEGRITY_BOUNDARY\" xml:space=\"preserve\">\n    <value>무결성 경계를 넘어 매개 변수를 전달할 수 없습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_ZERO_BYTE_FILE\" xml:space=\"preserve\">\n    <value>0 바이트 설치 관리자 다운로드됨; 네트워크 연결이 제대로 작동하는지 확인하십시오.</value>\n  </data>\n  <data name=\"InstallerZeroByteFile\" xml:space=\"preserve\">\n    <value>0 바이트 설치 관리자 다운로드됨; 네트워크 연결이 제대로 작동하는지 확인하십시오.</value>\n  </data>\n  <data name=\"FontCommandShortDescription\" xml:space=\"preserve\">\n    <value>글꼴 관리</value>\n  </data>\n  <data name=\"FontCommandLongDescription\" xml:space=\"preserve\">\n    <value>하위 명령으로 글꼴을 관리합니다. 글꼴은 packages와 비슷하게 설치, 업그레이드 또는 제거할 수 있습니다. </value>\n  </data>\n  <data name=\"FontFamily\" xml:space=\"preserve\">\n    <value>가족</value>\n  </data>\n  <data name=\"FontFaces\" xml:space=\"preserve\">\n    <value>얼굴</value>\n    <comment>\"Faces\" represents the typeface of the font family such as 'Bold' or 'Italic'</comment>\n  </data>\n  <data name=\"FontFamilyNameArgumentDescription\" xml:space=\"preserve\">\n    <value>성으로 결과 필터링</value>\n  </data>\n  <data name=\"FontFace\" xml:space=\"preserve\">\n    <value>얼굴</value>\n    <comment>\"Face\" represents the typeface of a font family such as 'Bold' or 'Italic'</comment>\n  </data>\n  <data name=\"FontFilePaths\" xml:space=\"preserve\">\n    <value>경로</value>\n  </data>\n  <data name=\"NoInstalledFontFound\" xml:space=\"preserve\">\n    <value>입력 조건과 일치하는 설치된 글꼴을 찾을 수 없습니다.</value>\n  </data>\n  <data name=\"FontListCommandShortDescription\" xml:space=\"preserve\">\n    <value>설치된 글꼴 나열</value>\n  </data>\n  <data name=\"FontListCommandLongDescription\" xml:space=\"preserve\">\n    <value>설치된 모든 글꼴, 모든 글꼴 파일 또는 특정 글꼴의 전체 세부 정보를 나열합니다.</value>\n  </data>\n  <data name=\"FontVersion\" xml:space=\"preserve\">\n    <value>버전</value>\n  </data>\n  <data name=\"ConfigurationModules\" xml:space=\"preserve\">\n    <value>구성 모듈</value>\n    <comment>PowerShell Modules that are used for the Configuration feature</comment>\n  </data>\n  <data name=\"InstallerDownloadRequiresAuthentication\" xml:space=\"preserve\">\n    <value>패키지 설치 관리자에 인증이 필요합니다. 필요한 경우 인증 프롬프트가 표시될 수 있습니다. 인증된 정보는 설치 관리자 다운로드 URL과 공유됩니다.</value>\n  </data>\n  <data name=\"InstallerDownloadAuthenticationNotSupported\" xml:space=\"preserve\">\n    <value>설치 관리자를 다운로드하지 못했습니다. 이 winget 버전에서는 설치 관리자 다운로드 인증 방법을 지원하지 않습니다. 최신 winget 버전으로 업그레이드해 보세요.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"InstallerDownloadAuthenticationFailed\" xml:space=\"preserve\">\n    <value>설치 관리자를 다운로드하지 못했습니다. 인증에 실패했습니다.</value>\n  </data>\n  <data name=\"ConfigurationProcessorPath\" xml:space=\"preserve\">\n    <value>구성 프로세서의 경로를 지정합니다.</value>\n  </data>\n  <data name=\"DscCommandShortDescription\" xml:space=\"preserve\">\n    <value>DSC v3 리소스 명령</value>\n    <comment>DSC stands for \"Desired State Configuration\". It should already have a locked translation.</comment>\n  </data>\n  <data name=\"DscCommandLongDescription\" xml:space=\"preserve\">\n    <value>여기서 하위 명령은 WinGet 및 패키지를 구성하기 위한 DSC(Desired State Configuration) v3 리소스를 구현합니다.</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionGet\" xml:space=\"preserve\">\n    <value>리소스 상태 가져오기</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionSet\" xml:space=\"preserve\">\n    <value>리소스 상태 설정</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionWhatIf\" xml:space=\"preserve\">\n    <value>필요한 상태 변경 설명하기</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionTest\" xml:space=\"preserve\">\n    <value>리소스 상태 테스트</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionDelete\" xml:space=\"preserve\">\n    <value>리소스 상태 삭제</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionExport\" xml:space=\"preserve\">\n    <value>모든 상태 인스턴스 가져오기</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionValidate\" xml:space=\"preserve\">\n    <value>그룹 콘텐츠 유효성 검사</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionResolve\" xml:space=\"preserve\">\n    <value>외부 상태 해결</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionAdapter\" xml:space=\"preserve\">\n    <value>어댑터 실행</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionSchema\" xml:space=\"preserve\">\n    <value>리소스 스키마 가져오기</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionManifest\" xml:space=\"preserve\">\n    <value>리소스 매니페스트 가져오기</value>\n  </data>\n  <data name=\"DscPackageResourceShortDescription\" xml:space=\"preserve\">\n    <value>패키지 상태 관리</value>\n  </data>\n  <data name=\"DscPackageResourceLongDescription\" xml:space=\"preserve\">\n    <value>WinGet을 통해 패키지를 관리하세요.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionExist\" xml:space=\"preserve\">\n    <value>instance 있는지 여부를 나타냅니다.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionInDesiredState\" xml:space=\"preserve\">\n    <value>instance 원하는 상태에 있는지 여부를 나타냅니다.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageId\" xml:space=\"preserve\">\n    <value>패키지의 식별자입니다.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageSource\" xml:space=\"preserve\">\n    <value>패키지의 원본입니다.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageVersion\" xml:space=\"preserve\">\n    <value>패키지 버전입니다.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageMatchOption\" xml:space=\"preserve\">\n    <value>식별자를 패키지와 일치시키는 메서드입니다.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageUseLatest\" xml:space=\"preserve\">\n    <value>사용 가능한 최신 버전의 패키지를 설치해야 합니다.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageInstallMode\" xml:space=\"preserve\">\n    <value>필요한 경우 사용할 설치 모드입니다.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageScope\" xml:space=\"preserve\">\n    <value>패키지의 대상 범위입니다.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionAcceptAgreements\" xml:space=\"preserve\">\n    <value>소스 및 패키지에 대한 계약에 동의할지 여부를 나타냅니다.</value>\n  </data>\n  <data name=\"DscUserSettingsFileShortDescription\" xml:space=\"preserve\">\n    <value>사용자 설정 파일 관리</value>\n  </data>\n  <data name=\"DscUserSettingsFileLongDescription\" xml:space=\"preserve\">\n    <value>WinGet의 사용자 설정을 관리합니다.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionUserSettingsFileSettings\" xml:space=\"preserve\">\n    <value>설정 JSON 파일 콘텐츠입니다.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionUserSettingsFileAction\" xml:space=\"preserve\">\n    <value>설정을 적용하는 데 사용되는 작업입니다.</value>\n  </data>\n  <data name=\"CorrelationArgumentDescription\" xml:space=\"preserve\">\n    <value>상관 관계를 위해 값이 기록되었습니다.</value>\n  </data>\n  <data name=\"DscSourceResourceShortDescription\" xml:space=\"preserve\">\n    <value>데이터 원본 구성</value>\n  </data>\n  <data name=\"DscSourceResourceLongDescription\" xml:space=\"preserve\">\n    <value>WinGet의 소스를 관리합니다.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceName\" xml:space=\"preserve\">\n    <value>원본에 사용할 이름입니다.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceArgument\" xml:space=\"preserve\">\n    <value>원본의 인수입니다.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceType\" xml:space=\"preserve\">\n    <value>원본의 유형입니다.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceTrustLevel\" xml:space=\"preserve\">\n    <value>원본의 신뢰 수준입니다.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceExplicit\" xml:space=\"preserve\">\n    <value>호출 시 원본이 지정되지 않았을 때 원본이 포함되는지 여부입니다.</value>\n  </data>\n  <data name=\"ConfigurationApplyingUnit\" xml:space=\"preserve\">\n    <value>구성 단위 적용 중...</value>\n  </data>\n  <data name=\"ConfigurationExportingUnit\" xml:space=\"preserve\">\n    <value>단위를 내보내는 중...</value>\n  </data>\n  <data name=\"ConfigurationGettingUnitProcessors\" xml:space=\"preserve\">\n    <value>구성 단위 프로세서를 가져오는 중...</value>\n  </data>\n  <data name=\"ConfigurationExportInstallRequiredModule\" xml:space=\"preserve\">\n    <value>[{0}] 내보내기에 필요한 모듈을 확인하세요.</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportInstallRequiredModuleFailed\" xml:space=\"preserve\">\n    <value>필수 모듈을 테스트하거나 가져오지 못했습니다. 관련 설정을 내보내지 않습니다.</value>\n  </data>\n  <data name=\"ConfigurationExportUnitStart\" xml:space=\"preserve\">\n    <value>[{0}] 내보내기</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportUnitFailed\" xml:space=\"preserve\">\n    <value>리소스를 내보내지 못했습니다.</value>\n  </data>\n  <data name=\"ConfigurationExportFailedToGetUnitProcessors\" xml:space=\"preserve\">\n    <value>단위 프로세서를 가져오지 못했습니다. 개별 패키지 설정을 내보내지 않습니다.</value>\n  </data>\n  <data name=\"OutputDirectoryArgumentDescription\" xml:space=\"preserve\">\n    <value>결과를 쓸 디렉터리</value>\n  </data>\n  <data name=\"ConfigurationInstallDscPackage\" xml:space=\"preserve\">\n    <value>Desired State Configuration 패키지를 시스템에서 찾을 수 없습니다. 패키지... 설치 중</value>\n  </data>\n  <data name=\"ConfigurationInstallDscPackageFailed\" xml:space=\"preserve\">\n    <value>Desired State Configuration 패키지를 설치하지 못했습니다. 패키지를 수동으로 설치하거나 --processor-path 인수를 통해 dsc.exe 경로를 제공하십시오.</value>\n    <comment>{Locked=\"dsc.exe\",\"--processor-path\"}</comment>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionAdminSettingsSettings\" xml:space=\"preserve\">\n    <value>관리자 설정 및 해당 값을 포함하는 개체입니다.</value>\n  </data>\n  <data name=\"DscAdminSettingsResourceShortDescription\" xml:space=\"preserve\">\n    <value>관리자 설정 관리</value>\n  </data>\n  <data name=\"DscAdminSettingsResourceLongDescription\" xml:space=\"preserve\">\n    <value>WinGet의 관리자 설정을 관리합니다.</value>\n  </data>\n  <data name=\"ResetAllAdminSettingsArgumentDescription\" xml:space=\"preserve\">\n    <value>모든 관리자 설정을 초기화합니다.</value>\n  </data>\n  <data name=\"ResetAllAdminSettingsSucceeded\" xml:space=\"preserve\">\n    <value>모든 관리자 설정이 초기화되었습니다.</value>\n  </data>\n  <data name=\"McpCommandShortDescription\" xml:space=\"preserve\">\n    <value>MCP 정보</value>\n    <comment>MCP stands for Model Context Protocol and should probably remain as-is</comment>\n  </data>\n  <data name=\"McpCommandLongDescription\" xml:space=\"preserve\">\n    <value>Windows 패키지 관리자를 위한 MCP(모델 컨텍스트 프로토콜) 정보입니다.</value>\n  </data>\n  <data name=\"McpConfigurationPreamble\" xml:space=\"preserve\">\n    <value>MCP 클라이언트를 사용하여 Windows 패키지 관리자 MCP 서버를 수동으로 구성하려면 `servers` 개체에서 다음 JSON 조각을 사용하십시오.</value>\n    <comment>{Locked=\"`servers`\"}\nMCP stands for Model Context Protocol and should probably remain as-is.\nAn unlocalized JSON fragment will follow on another line.</comment>\n  </data>\n  <data name=\"PolicyEnableMcpServer\" xml:space=\"preserve\">\n    <value>WINDOWS 패키지 관리자 MCP 서버 활성화</value>\n  </data>\n  <data name=\"OSVersionDescription\" xml:space=\"preserve\">\n    <value>대상 OS 버전</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>하나 이상의 글꼴을 설치하지 못했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>글꼴 파일이 지원되지 않으므로 설치할 수 없습니다.</value>\n  </data>\n  <data name=\"FontFileNotSupported\" xml:space=\"preserve\">\n    <value>글꼴 패키지에 있는 하나 이상의 글꼴이 지원되지 않으므로 설치할 수 없습니다.</value>\n  </data>\n  <data name=\"FontInstallFailed\" xml:space=\"preserve\">\n    <value>글꼴 설치 실패, 정리하는 중입니다.</value>\n  </data>\n  <data name=\"FontAlreadyInstalled\" xml:space=\"preserve\">\n    <value>글꼴이 이미 설치되어 있습니다.</value>\n  </data>\n  <data name=\"FontPackage\" xml:space=\"preserve\">\n    <value>패키지 ID</value>\n  </data>\n  <data name=\"FontWinGetSupported\" xml:space=\"preserve\">\n    <value>WinGet 지원됨</value>\n  </data>\n  <data name=\"FontTitle\" xml:space=\"preserve\">\n    <value>제목</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_FOUND\" xml:space=\"preserve\">\n    <value>글꼴 파일을 찾을 수 없습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>글꼴을 제거하지 못했습니다. 글꼴 상태가 좋지 않을 수 있습니다. 다시 시작한 후 제거해 보세요.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>글꼴 유효성 검사에 실패했습니다.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_ROLLBACK_FAILED\" xml:space=\"preserve\">\n    <value>글꼴 롤백에 실패했습니다. 글꼴 상태가 좋지 않을 수 있습니다. 다시 시작한 후 제거해 보세요.</value>\n  </data>\n  <data name=\"FontDetailsArgumentDescription\" xml:space=\"preserve\">\n    <value>글꼴 파일의 자세한 정보를 표시합니다.</value>\n  </data>\n  <data name=\"FontValidationFailed\" xml:space=\"preserve\">\n    <value>글꼴 패키지의 유효성을 검사하지 못했습니다.</value>\n  </data>\n  <data name=\"FontRollbackFailed\" xml:space=\"preserve\">\n    <value>실패한 글꼴 설치에 대한 롤백 시도가 실패했습니다. 글꼴을 제거하려면 다시 시작해야 할 수 있습니다.</value>\n  </data>\n  <data name=\"FontUninstallFailed\" xml:space=\"preserve\">\n    <value>글꼴 패키지를 제거하지 못했습니다. 시스템 또는 응용 프로그램에서 글꼴을 사용 중이기 때문인 경우가 많습니다. 컴퓨터를 다시 시작한 후 제거가 성공할 수 있습니다.</value>\n  </data>\n  <data name=\"FontStatusOK\" xml:space=\"preserve\">\n    <value>확인</value>\n    <comment>\"OK\" means the font is in a good healthy state</comment>\n  </data>\n  <data name=\"FontStatusCorrupt\" xml:space=\"preserve\">\n    <value>손상됨</value>\n    <comment>\"Corrupt\" refers to an install that is in a corrupted or bad state, and needs repair.</comment>\n  </data>\n  <data name=\"FontStatus\" xml:space=\"preserve\">\n    <value>상태</value>\n  </data>\n  <data name=\"FontStatusUnknown\" xml:space=\"preserve\">\n    <value>알 수 없음</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>글꼴 패키지가 이미 설치되어 있습니다.</value>\n  </data>\n  <data name=\"ListDetailsArgumentDescription\" xml:space=\"preserve\">\n    <value>패키지에 대한 자세한 정보 표시</value>\n    <comment>Providing this argument causes the CLI to output additional details about installed application packages.</comment>\n  </data>\n  <data name=\"ShowLabelChannel\" xml:space=\"preserve\">\n    <value>채널:</value>\n    <comment>Precedes a string value that names the delivery channel for the software package (ex. stable, beta).</comment>\n  </data>\n  <data name=\"ShowListLocalIdentifier\" xml:space=\"preserve\">\n    <value>로컬 식별자</value>\n    <comment>Precedes a value that is the unique identifier for the installed package on the local system.</comment>\n  </data>\n  <data name=\"ShowListPackageFamilyName\" xml:space=\"preserve\">\n    <value>패키지 패밀리 이름:</value>\n    <comment>Precedes a value that is the APPX/MSIX package family name of the installed package.</comment>\n  </data>\n  <data name=\"ShowListProductCode\" xml:space=\"preserve\">\n    <value>제품 코드:</value>\n    <comment>Precedes a value that is the Add/Remove Programs identifier in the registry. This is also the Product Code value as defined in MSI installers.</comment>\n  </data>\n  <data name=\"ShowListUpgradeCode\" xml:space=\"preserve\">\n    <value>업그레이드 코드:</value>\n    <comment>Precedes a value that is the MSI Upgrade Code for the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledScope\" xml:space=\"preserve\">\n    <value>설치된 범위:</value>\n    <comment>Precedes a value that is the scope of the installation of the package (ex. user, machine).</comment>\n  </data>\n  <data name=\"ShowListInstalledArchitecture\" xml:space=\"preserve\">\n    <value>설치된 아키텍처:</value>\n    <comment>Precedes a value that is the installed architecture of the package (ex. x86, x64, ARM64).</comment>\n  </data>\n  <data name=\"ShowListInstalledLocale\" xml:space=\"preserve\">\n    <value>설치된 지역:</value>\n    <comment>Precedes a value that is the locale of the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledLocation\" xml:space=\"preserve\">\n    <value>설치된 위치:</value>\n    <comment>Precedes a value that is the directory path to the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledSource\" xml:space=\"preserve\">\n    <value>원본 소스:</value>\n    <comment>Precedes a value that names the package source where the installed package originated from.</comment>\n  </data>\n  <data name=\"ShowListAvailableUpgrades\" xml:space=\"preserve\">\n    <value>사용 가능한 업그레이드:</value>\n    <comment>Precedes a list of package upgrades available for the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstallerCategory\" xml:space=\"preserve\">\n    <value>설치 관리자 범주:</value>\n    <comment>Precedes a value that indicates the category of the installer for the installed package (ex. exe, msi, msix).</comment>\n  </data>\n  <data name=\"SourceEditOldValue\" xml:space=\"preserve\">\n    <value>이전 값</value>\n    <comment>Column title for listing edit changes.</comment>\n  </data>\n  <data name=\"SourceEditNewValue\" xml:space=\"preserve\">\n    <value>새 값</value>\n    <comment>Column title for listing the new value.</comment>\n  </data>\n</root>"
  },
  {
    "path": "Localization/Resources/pt-BR/Resources.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "Localization/Resources/pt-BR/winget.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"AdjoinedNotFlagError\" xml:space=\"preserve\">\n    <value>Alias adjacente não é um sinalizador: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an adjoined alias that is not a flag argument. {0} is a placeholder replaced by the user input argument (e.g. '-ab').</comment>\n  </data>\n  <data name=\"AdjoinedNotFoundError\" xml:space=\"preserve\">\n    <value>Alias de sinalizador adjacente não encontrado: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an adjoined flag alias argument that was not found. {0} is a placeholder replaced by the user input argument (e.g. '-ab').</comment>\n  </data>\n  <data name=\"AvailableArguments\" xml:space=\"preserve\">\n    <value>Os seguintes argumentos estão disponíveis:</value>\n    <comment>Message displayed to inform the user about the available command line arguments.</comment>\n  </data>\n  <data name=\"AvailableCommandAliases\" xml:space=\"preserve\">\n    <value>Os seguintes nomes alternativos de comando estão disponíveis:</value>\n    <comment>Message displayed to inform the user about the available command line alias arguments.</comment>\n  </data>\n  <data name=\"AvailableCommands\" xml:space=\"preserve\">\n    <value>Os seguintes comandos estão disponíveis:</value>\n    <comment>Title displayed to inform the user about the available commands.</comment>\n  </data>\n  <data name=\"AvailableHeader\" xml:space=\"preserve\">\n    <value>Disponível</value>\n    <comment>As in \"a new version is available to upgrade to\".</comment>\n  </data>\n  <data name=\"AvailableOptions\" xml:space=\"preserve\">\n    <value>As seguintes opções estão disponíveis:</value>\n    <comment>Message displayed to inform the user about the available options.</comment>\n  </data>\n  <data name=\"AvailableSubcommands\" xml:space=\"preserve\">\n    <value>Os seguintes subcomandos estão disponíveis:</value>\n    <comment>Message displayed to inform the user about the available nested commands that run in context of the selected command.</comment>\n  </data>\n  <data name=\"AvailableUpgrades\" xml:space=\"preserve\">\n    <value>{0} atualizações disponíveis.</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about available package upgrades. {0} is a placeholder replaced by the number of package upgrades.</comment>\n  </data>\n  <data name=\"ChannelArgumentDescription\" xml:space=\"preserve\">\n    <value>Usar o canal especificado; o padrão é público geral</value>\n  </data>\n  <data name=\"Command\" xml:space=\"preserve\">\n    <value>comando</value>\n    <comment>Label displayed for a command to give the software.</comment>\n  </data>\n  <data name=\"CommandArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtrar resultados por comando</value>\n    <comment>Description message displayed to inform the user about filtering the search results by a package command.</comment>\n  </data>\n  <data name=\"CommandLineArgumentDescription\" xml:space=\"preserve\">\n    <value>A linha de comando completa para conclusão</value>\n  </data>\n  <data name=\"CommandRequiresAdmin\" xml:space=\"preserve\">\n    <value>Este comando requer privilégios de administrador para ser executado.</value>\n  </data>\n  <data name=\"CompleteCommandLongDescription\" xml:space=\"preserve\">\n    <value>Esse comando pode ser usado para solicitar a conclusão da linha de comando sensível ao contexto. A linha de comando, a posição do cursor e a palavra a ser completada são entregues. A saída é um conjunto de valores possíveis com base nas entradas, com um valor possível por linha.</value>\n  </data>\n  <data name=\"CompleteCommandShortDescription\" xml:space=\"preserve\">\n    <value>Habilita a conclusão da linha de comando sensível ao contexto</value>\n  </data>\n  <data name=\"CountArgumentDescription\" xml:space=\"preserve\">\n    <value>Não mostrar mais do que o número especificado de resultados (entre 1 e 1000)</value>\n  </data>\n  <data name=\"Done\" xml:space=\"preserve\">\n    <value>Concluído</value>\n    <comment>Label displayed when an operation completes or is done executing.</comment>\n  </data>\n  <data name=\"ExactArgumentDescription\" xml:space=\"preserve\">\n    <value>Localizar pacote usando uma correspondência exata</value>\n    <comment>Description message displayed to inform the user about finding an application package using an exact matching criteria.</comment>\n  </data>\n  <data name=\"ExperimentalArgumentDescription\" xml:space=\"preserve\">\n    <value>Argumento experimental para fins de demonstração</value>\n  </data>\n  <data name=\"ExperimentalCommandLongDescription\" xml:space=\"preserve\">\n    <value>Este comando é um exemplo de como implementar um recurso experimental. Para ativar, vá para 'winget settings' e habilite os recursos experimentalCmd ou experimentalArg.</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"ExperimentalCommandShortDescription\" xml:space=\"preserve\">\n    <value>Exemplo de recurso experimental</value>\n  </data>\n  <data name=\"ExtraPositionalError\" xml:space=\"preserve\">\n    <value>Foi encontrado um argumento posicional quando nenhum era esperado: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an extra positional argument when none was expected. {0} is a placeholder replaced by the user's extra argument input.</comment>\n  </data>\n  <data name=\"FeatureDisabledMessage\" xml:space=\"preserve\">\n    <value>Este recurso é um trabalho em andamento e pode ser alterado radicalmente ou removido completamente no futuro. Para habilita-lo, edite suas configurações ('winget settings') para incluir o recurso experimental: '{0}'</value>\n    <comment>{Locked=\"winget settings\",\"{0}\"}. Error message displayed when the user uses an experimental feature that is disabled. {0} is a placeholder replaced by the experimental feature name.</comment>\n  </data>\n  <data name=\"FeaturesCommandLongDescription\" xml:space=\"preserve\">\n    <value>Mostra o status dos recursos experimentais. Os recursos experimentais podem ser ativados por 'winget settings'.</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"FeaturesCommandShortDescription\" xml:space=\"preserve\">\n    <value>Mostra o status dos recursos experimentais</value>\n  </data>\n  <data name=\"FeaturesDisabled\" xml:space=\"preserve\">\n    <value>Desabilitado</value>\n  </data>\n  <data name=\"FeaturesEnabled\" xml:space=\"preserve\">\n    <value>Habilitado</value>\n  </data>\n  <data name=\"FeaturesFeature\" xml:space=\"preserve\">\n    <value>Recurso</value>\n  </data>\n  <data name=\"FeaturesLink\" xml:space=\"preserve\">\n    <value>Link</value>\n  </data>\n  <data name=\"FeaturesMessage\" xml:space=\"preserve\">\n    <value>Os seguintes recursos experimentais estão em andamento.\nEles podem ser configurados por meio do arquivo de configurações ' winget settings '.</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"FeaturesProperty\" xml:space=\"preserve\">\n    <value>Propriedade</value>\n  </data>\n  <data name=\"FeaturesStatus\" xml:space=\"preserve\">\n    <value>Status</value>\n  </data>\n  <data name=\"FileArgumentDescription\" xml:space=\"preserve\">\n    <value>Arquivo em que será gerado o hash</value>\n  </data>\n  <data name=\"FlagContainAdjoinedError\" xml:space=\"preserve\">\n    <value>Argumento sinalizado não pode conter valores adjacentes: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a flag argument containing an unexpected adjoined value. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"HashCommandLongDescription\" xml:space=\"preserve\">\n    <value>Calcula o hash de um arquivo local, apropriado para entrada em um manifesto. Ele também pode calcular o hash do arquivo de assinatura de um pacote MSIX para habilitar instalações de streaming.</value>\n  </data>\n  <data name=\"HashCommandShortDescription\" xml:space=\"preserve\">\n    <value>Ajuda para arquivos do instalador de hash</value>\n  </data>\n  <data name=\"HelpArgumentDescription\" xml:space=\"preserve\">\n    <value>Mostra a ajuda sobre o comando selecionado</value>\n  </data>\n  <data name=\"HelpForDetails\" xml:space=\"preserve\">\n    <value>Para obter mais detalhes sobre um comando específico, passe o argumento help.</value>\n  </data>\n  <data name=\"HelpLinkPreamble\" xml:space=\"preserve\">\n    <value>Mais tópicos de ajuda podem ser encontrados em: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a link where they can learn more about the subject context. {0} is a placeholder replaced by a website address.</comment>\n  </data>\n  <data name=\"IdArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtrar resultados por id</value>\n  </data>\n  <data name=\"IgnoreWarningsArgumentDescription\" xml:space=\"preserve\">\n    <value>Suprime saídas de aviso</value>\n  </data>\n  <data name=\"InstallationDisclaimer1\" xml:space=\"preserve\">\n    <value>Este aplicativo é licenciado para você pelo proprietário.</value>\n  </data>\n  <data name=\"InstallationDisclaimer2\" xml:space=\"preserve\">\n    <value>A Microsoft não é responsável por, nem concede licenças a pacotes de terceiros.</value>\n  </data>\n  <data name=\"InstallationDisclaimerMSStore\" xml:space=\"preserve\">\n    <value>Este pacote é fornecido por meio da Microsoft Store. O winget talvez precise adquirir o pacote da Microsoft Store em nome do usuário atual.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"InstallCommandLongDescription\" xml:space=\"preserve\">\n    <value>Instala o pacote selecionado, seja encontrado pesquisando uma origem configurada ou diretamente de um manifesto. Por padrão, a consulta deve corresponder a maiúsculas e minúsculas a id, name ou moniker do pacote. Outros campos podem ser usados passando sua opção apropriada. Por padrão, o comando install verificará o status do pacote instalado e tentará realizar uma atualização, se aplicável. Substitua por --force para executar uma instalação direta.</value>\n    <comment>{Locked=\"--force\"}; id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"InstallCommandShortDescription\" xml:space=\"preserve\">\n    <value>Instalar um determinado pacote</value>\n  </data>\n  <data name=\"InstallerHashMismatchAdminBlock\" xml:space=\"preserve\">\n    <value>O hash do instalador não corresponde; Isto não pode ser substituído durante a execução como administrador</value>\n  </data>\n  <data name=\"InstallerHashMismatchOverridden\" xml:space=\"preserve\">\n    <value>O hash do instalador não corresponde; prosseguir devido à --ignore-security-hash</value>\n    <comment>{Locked=\"--ignore-security-hash\"}</comment>\n  </data>\n  <data name=\"InstallerHashMismatchOverrideRequired\" xml:space=\"preserve\">\n    <value>O hash do instalador não corresponde; para substituir este uso de verificação --ignore-security-hash</value>\n    <comment>{Locked=\"--ignore-security-hash\"}</comment>\n  </data>\n  <data name=\"InstallerHashVerified\" xml:space=\"preserve\">\n    <value>Hash do instalador verificado com êxito</value>\n  </data>\n  <data name=\"InstallFlowInstallSuccess\" xml:space=\"preserve\">\n    <value>Instalado com êxito</value>\n  </data>\n  <data name=\"InstallFlowStartingPackageInstall\" xml:space=\"preserve\">\n    <value>Iniciando a instalação do pacote...</value>\n  </data>\n  <data name=\"HashOverrideArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignorar a falha na verificação do código hash do instalador</value>\n  </data>\n  <data name=\"IgnoreLocalArchiveMalwareScanArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignorar a verificação de malware realizada como parte da instalação de um pacote de tipo de arquivo morto do manifesto local</value>\n  </data>\n  <data name=\"InteractiveArgumentDescription\" xml:space=\"preserve\">\n    <value>Solicitar instalação interativa; a entrada do usuário pode ser necessária</value>\n  </data>\n  <data name=\"InvalidAliasError\" xml:space=\"preserve\">\n    <value>O alias de argumento não foi reconhecido para o comando atual: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a command line argument alias that was not recognized for a selected command. {0} is a placeholder replaced by the user's argument alias input (e.g. '-a').</comment>\n  </data>\n  <data name=\"InvalidArgumentSpecifierError\" xml:space=\"preserve\">\n    <value>Especificador de argumento inválido: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an invalid argument specifier. {0} is a placeholder replaced by an argument specifier (e.g. '-').</comment>\n  </data>\n  <data name=\"InvalidNameError\" xml:space=\"preserve\">\n    <value>O nome do argumento não foi reconhecido para o comando atual: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an unrecognized command line argument name for the selected command. {0} is a placeholder replaced by the user's argument name input (e.g. '--example').</comment>\n  </data>\n  <data name=\"KeyDirectoriesHeader\" xml:space=\"preserve\">\n    <value>Diretórios Winget</value>\n    <comment>Header for a table detailing the directories Winget uses for key operations like logging and portable installs</comment>\n  </data>\n  <data name=\"LocaleArgumentDescription\" xml:space=\"preserve\">\n    <value>Local para usar (formato BCP47)</value>\n    <comment>{Locked=\"BCP47\"}</comment>\n  </data>\n  <data name=\"LicenseAgreement\" xml:space=\"preserve\">\n    <value>Contrato de Licença</value>\n  </data>\n  <data name=\"Links\" xml:space=\"preserve\">\n    <value>Links</value>\n    <comment>Links to different webpages</comment>\n  </data>\n  <data name=\"ListCommandLongDescription\" xml:space=\"preserve\">\n    <value>O comando list exibe os pacotes instalados no sistema, bem como se uma atualização está disponível. Opções adicionais podem ser fornecidas para filtrar a saída, assim como o comando de pesquisa (search).</value>\n    <comment>{Locked=\"list\",\"search\"}</comment>\n  </data>\n  <data name=\"ListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Exibir os pacotes instalados</value>\n  </data>\n  <data name=\"LocationArgumentDescription\" xml:space=\"preserve\">\n    <value>Local para instalar (se houver suporte)</value>\n  </data>\n  <data name=\"LogArgumentDescription\" xml:space=\"preserve\">\n    <value>Local do log (se houver suporte)</value>\n  </data>\n  <data name=\"MainCopyrightNotice\" xml:space=\"preserve\">\n    <value>Copyright (c) Microsoft Corporation. Todos os direitos reservados.</value>\n  </data>\n  <data name=\"MainHomepage\" xml:space=\"preserve\">\n    <value>Home page</value>\n    <comment>The primary webpage for the software</comment>\n  </data>\n  <data name=\"ManifestArgumentDescription\" xml:space=\"preserve\">\n    <value>O caminho para o manifesto do pacote</value>\n  </data>\n  <data name=\"ManifestValidationFail\" xml:space=\"preserve\">\n    <value>Falha na validação do manifesto.</value>\n  </data>\n  <data name=\"ManifestValidationSuccess\" xml:space=\"preserve\">\n    <value>Êxito na validação do manifesto.</value>\n  </data>\n  <data name=\"ManifestValidationWarning\" xml:space=\"preserve\">\n    <value>Êxito na validação do manifesto com avisos.</value>\n  </data>\n  <data name=\"MissingArgumentError\" xml:space=\"preserve\">\n    <value>Valor de argumento obrigatório, mas nenhum encontrado: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user does not provide a required command line argument value. {0} is a placeholder replaced by the argument name.</comment>\n  </data>\n  <data name=\"MonikerArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtrar resultados por moniker</value>\n  </data>\n  <data name=\"MsixArgumentDescription\" xml:space=\"preserve\">\n    <value>O arquivo de entrada será tratado como msix; hash de assinatura será fornecido se assinado</value>\n  </data>\n  <data name=\"MsixSignatureHashFailed\" xml:space=\"preserve\">\n    <value>Falha ao calcular o hash de assinatura MSIX.</value>\n  </data>\n  <data name=\"MSStoreAppBlocked\" xml:space=\"preserve\">\n    <value>Falha ao instalar ou atualizar o pacote da Microsoft Store porque o aplicativo específico está bloqueado pela política</value>\n  </data>\n  <data name=\"MSStoreInstallOrUpdateFailed\" xml:space=\"preserve\">\n    <value>Falha ao instalar ou atualizar o pacote da Microsoft Store. Código de erro: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Microsoft Store application package fails to install or upgrade. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"MSStoreStoreClientBlocked\" xml:space=\"preserve\">\n    <value>Falha ao instalar ou atualizar o pacote da Microsoft Store porque o cliente da Microsoft Store está bloqueado pela diretiva</value>\n  </data>\n  <data name=\"MSStoreInstallTryGetEntitlement\" xml:space=\"preserve\">\n    <value>Verificando/solicitando aquisição de pacote...</value>\n  </data>\n  <data name=\"MultipleInstalledPackagesFound\" xml:space=\"preserve\">\n    <value>Vários pacotes instalados encontraram critérios de entrada correspondentes. Refine a entrada.</value>\n  </data>\n  <data name=\"MultiplePackagesFound\" xml:space=\"preserve\">\n    <value>Vários pacotes encontraram critérios de entrada correspondentes. Refine a entrada.</value>\n  </data>\n  <data name=\"NameArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtrar resultados por nome</value>\n  </data>\n  <data name=\"NoApplicableInstallers\" xml:space=\"preserve\">\n    <value>Nenhum instalador aplicável encontrado; consulte os logs para obter mais detalhes.</value>\n  </data>\n  <data name=\"NoExperimentalFeaturesMessage\" xml:space=\"preserve\">\n    <value>Atualmente não há recursos experimentais disponíveis. </value>\n  </data>\n  <data name=\"NoInstalledPackageFound\" xml:space=\"preserve\">\n    <value>Nenhum pacote instalado foi encontrado que corresponda aos critérios de entrada.</value>\n  </data>\n  <data name=\"NoPackageFound\" xml:space=\"preserve\">\n    <value>Nenhum pacote encontrou os critérios de entrada correspondentes.</value>\n  </data>\n  <data name=\"NoVTArgumentDescription\" xml:space=\"preserve\">\n    <value>Desabilita a exibição VirtualTerminal</value>\n    <comment>{Locked=\"VirtualTerminal\"}</comment>\n  </data>\n  <data name=\"OpenLogsArgumentDescription\" xml:space=\"preserve\">\n    <value>Abrir o local padrão dos logs</value>\n  </data>\n  <data name=\"Options\" xml:space=\"preserve\">\n    <value>opções</value>\n    <comment>Options to change how a command works</comment>\n  </data>\n  <data name=\"OverrideArgumentDescription\" xml:space=\"preserve\">\n    <value>Substituir argumentos para passar para o instalador</value>\n  </data>\n  <data name=\"Package\" xml:space=\"preserve\">\n    <value>Pacote: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for a software package. {0} is a placeholder replaced by the software package name.</comment>\n  </data>\n  <data name=\"PendingWorkError\" xml:space=\"preserve\">\n    <value>Opa, esquecemos de fazer isso...</value>\n  </data>\n  <data name=\"PositionArgumentDescription\" xml:space=\"preserve\">\n    <value>A posição do cursor na linha de comando</value>\n  </data>\n  <data name=\"PrivacyStatement\" xml:space=\"preserve\">\n    <value>Política de Privacidade</value>\n  </data>\n  <data name=\"QueryArgumentDescription\" xml:space=\"preserve\">\n    <value>A consulta usada para pesquisar um pacote</value>\n  </data>\n  <data name=\"RainbowArgumentDescription\" xml:space=\"preserve\">\n    <value>Exibição de progresso arco-íris de cores</value>\n  </data>\n  <data name=\"RequiredArgError\" xml:space=\"preserve\">\n    <value>Argumento necessário não fornecido: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user does not provide a required command line argument. {0} is a placeholder replaced by an argument name.</comment>\n  </data>\n  <data name=\"RetroArgumentDescription\" xml:space=\"preserve\">\n    <value>Exibição de andamento como a cor padrão</value>\n  </data>\n  <data name=\"SearchCommandLongDescription\" xml:space=\"preserve\">\n    <value>Pesquisas de pacotes de fontes configuradas.</value>\n  </data>\n  <data name=\"SearchCommandShortDescription\" xml:space=\"preserve\">\n    <value>Localizar e mostrar informações básicas de pacotes</value>\n  </data>\n  <data name=\"SearchId\" xml:space=\"preserve\">\n    <value>ID</value>\n    <comment>Abbreviation of Identifier.</comment>\n  </data>\n  <data name=\"SearchMatch\" xml:space=\"preserve\">\n    <value>Correspondência</value>\n  </data>\n  <data name=\"SearchName\" xml:space=\"preserve\">\n    <value>Nome</value>\n  </data>\n  <data name=\"SearchSource\" xml:space=\"preserve\">\n    <value>Origem</value>\n  </data>\n  <data name=\"SearchTruncated\" xml:space=\"preserve\">\n    <value>entradas adicionais truncadas devido ao limite de resultado</value>\n  </data>\n  <data name=\"SearchVersion\" xml:space=\"preserve\">\n    <value>Versão</value>\n  </data>\n  <data name=\"SettingLoadFailure\" xml:space=\"preserve\">\n    <value>As seguintes falhas foram encontradas ao validar as configurações:</value>\n  </data>\n  <data name=\"SettingsCommandLongDescription\" xml:space=\"preserve\">\n    <value>Abre as configurações no editor de texto json padrão. Se nenhum editor estiver configurado, abre as configurações no bloco de notas. Para obter as configurações disponíveis, consulte https://aka.ms/winget-settings Este comando também pode ser usado para definir configurações de administrador fornecendo os argumentos --enable ou --disable</value>\n    <comment>{Locked=\"--enable\"} {Locked=\"--disable\"}</comment>\n  </data>\n  <data name=\"SettingsCommandShortDescription\" xml:space=\"preserve\">\n    <value>Abra as configurações ou defina as configurações do administrador</value>\n  </data>\n  <data name=\"SettingsWarnings\" xml:space=\"preserve\">\n    <value>Erro inesperado ao carregar as configurações. Verifique suas configurações executando o 'settings' comando.</value>\n    <comment>{Locked=\"'settings'\"}</comment>\n  </data>\n  <data name=\"ShowChannel\" xml:space=\"preserve\">\n    <value>Canal</value>\n  </data>\n  <data name=\"ShowCommandLongDescription\" xml:space=\"preserve\">\n    <value>Mostra informações sobre um pacote específico. Por padrão, a consulta deve corresponder de forma insensível à ID, ao nome ou ao moniker do pacote. Outros campos podem ser usados passando a opção apropriada.</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"ShowCommandShortDescription\" xml:space=\"preserve\">\n    <value>Mostra informações sobre um pacote</value>\n  </data>\n  <data name=\"ShowVersion\" xml:space=\"preserve\">\n    <value>Versão</value>\n  </data>\n  <data name=\"SilentArgumentDescription\" xml:space=\"preserve\">\n    <value>Solicitar uma instalação silenciosa</value>\n  </data>\n  <data name=\"SingleCharAfterDashError\" xml:space=\"preserve\">\n    <value>Somente o alias de caractere único pode ocorrer após um único -: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides more than a single character command line alias argument after an alias argument specifier '-'. {0} is a placeholder replaced by the user's argument input.</comment>\n  </data>\n  <data name=\"SourceAddAlreadyExistsDifferentArg\" xml:space=\"preserve\">\n    <value>Uma origem com o nome fornecido já existe e se refere a um local diferente:</value>\n  </data>\n  <data name=\"SourceAddAlreadyExistsDifferentName\" xml:space=\"preserve\">\n    <value>Uma origem com um nome diferente já se refere a este local:</value>\n  </data>\n  <data name=\"SourceAddAlreadyExistsMatch\" xml:space=\"preserve\">\n    <value>Uma origem com o nome fornecido já existe e se refere ao mesmo local:</value>\n  </data>\n  <data name=\"SourceAddBegin\" xml:space=\"preserve\">\n    <value>Adicionando fonte:</value>\n  </data>\n  <data name=\"SourceAddCommandLongDescription\" xml:space=\"preserve\">\n    <value>Adicione uma nova fonte. Uma fonte fornece dados para você descobrir e instalar pacotes. Adicione uma nova fonte apenas se você confiar nela como um local seguro.</value>\n  </data>\n  <data name=\"SourceAddCommandShortDescription\" xml:space=\"preserve\">\n    <value>Adicionar uma nova origem</value>\n  </data>\n  <data name=\"SourceArgArgumentDescription\" xml:space=\"preserve\">\n    <value>Argumento fornecido à fonte</value>\n  </data>\n  <data name=\"SourceArgumentDescription\" xml:space=\"preserve\">\n    <value>Encontrar pacote usando a fonte especificada</value>\n  </data>\n  <data name=\"SourceCommandLongDescription\" xml:space=\"preserve\">\n    <value>Gerencie fontes usando os subcomandos. Uma fonte fornece dados para você descobrir e instalar pacotes. Adicione uma nova fonte apenas se você confiar nela como um local seguro.</value>\n  </data>\n  <data name=\"SourceCommandShortDescription\" xml:space=\"preserve\">\n    <value>Gerenciar fontes de pacotes</value>\n  </data>\n  <data name=\"SourceEditCommandLongDescription\" xml:space=\"preserve\">\n    <value>Editar propriedades de uma fonte existente. Uma fonte fornece os dados para você descobrir e instalar pacotes.</value>\n  </data>\n  <data name=\"SourceEditCommandShortDescription\" xml:space=\"preserve\">\n    <value>Editar propriedades da fonte</value>\n  </data>\n  <data name=\"SourceEditOne\" xml:space=\"preserve\">\n    <value>Editando fonte: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being edited. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceEditNoChanges\" xml:space=\"preserve\">\n    <value>A fonte chamada '{0}' já está no estado desejado.</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being edited. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceListArg\" xml:space=\"preserve\">\n    <value>Argumento</value>\n    <comment>Value given to source.</comment>\n  </data>\n  <data name=\"SourceListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Liste todas as fontes atuais ou todos os detalhes de uma fonte específica.</value>\n  </data>\n  <data name=\"SourceListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Listar fontes atuais</value>\n  </data>\n  <data name=\"SourceListData\" xml:space=\"preserve\">\n    <value>Dados</value>\n    <comment>Data stored by the source.</comment>\n  </data>\n  <data name=\"SourceListField\" xml:space=\"preserve\">\n    <value>Campo</value>\n    <comment>The name of a piece of information about a source.</comment>\n  </data>\n  <data name=\"SourceListName\" xml:space=\"preserve\">\n    <value>Nome</value>\n    <comment>The name of the source.</comment>\n  </data>\n  <data name=\"SourceListIdentifier\" xml:space=\"preserve\">\n    <value>Identificador</value>\n    <comment>The source's unique identifier.</comment>\n  </data>\n  <data name=\"SourceListNoneFound\" xml:space=\"preserve\">\n    <value>Não foi encontrada uma fonte chamada: {0}</value>\n    <comment>Error message displayed when the user provides a repository source name that was not found. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"SourceListNoSources\" xml:space=\"preserve\">\n    <value>Não há fontes configuradas.</value>\n  </data>\n  <data name=\"SourceListType\" xml:space=\"preserve\">\n    <value>Digitar</value>\n    <comment>The kind of source.</comment>\n  </data>\n  <data name=\"SourceListUpdated\" xml:space=\"preserve\">\n    <value>Atualizada</value>\n    <comment>The last time the source was updated.</comment>\n  </data>\n  <data name=\"SourceListUpdatedNever\" xml:space=\"preserve\">\n    <value>nunca</value>\n    <comment>The source has never been updated.</comment>\n  </data>\n  <data name=\"SourceListValue\" xml:space=\"preserve\">\n    <value>Valor</value>\n    <comment>The value of information about a source.</comment>\n  </data>\n  <data name=\"SourceNameArgumentDescription\" xml:space=\"preserve\">\n    <value>Nome da fonte</value>\n  </data>\n  <data name=\"SourceOpenFailedSuggestion\" xml:space=\"preserve\">\n    <value>Falha ao abrir a origem(s); tentar o comando 'source reset' se o problema persistir.</value>\n    <comment>{Locked=\"source reset\"}</comment>\n  </data>\n  <data name=\"SourceOpenPredefinedFailedSuggestion\" xml:space=\"preserve\">\n    <value>Falha ao abrir a origem predefinida; Relate aos mantenedores winget.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"SourceRemoveAll\" xml:space=\"preserve\">\n    <value>Removendo todas as fontes...</value>\n  </data>\n  <data name=\"SourceRemoveCommandLongDescription\" xml:space=\"preserve\">\n    <value>Remover uma fonte específica.</value>\n  </data>\n  <data name=\"SourceRemoveCommandShortDescription\" xml:space=\"preserve\">\n    <value>Remover fontes atuais</value>\n  </data>\n  <data name=\"SourceRemoveOne\" xml:space=\"preserve\">\n    <value>Removendo fonte: {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being removed. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceResetAll\" xml:space=\"preserve\">\n    <value>Redefinindo todas as fontes...</value>\n  </data>\n  <data name=\"SourceResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>Esse comando descarta fontes existentes, deixando potencialmente todos os dados locais para trás. Sem nenhum argumento, ele removerá todas as fontes e adicionará os padrões. Se uma fonte nomeada for fornecida, só essa fonte será descartada.</value>\n  </data>\n  <data name=\"SourceResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>Redefinir fontes</value>\n  </data>\n  <data name=\"SourceResetForceArgumentDescription\" xml:space=\"preserve\">\n    <value>Força a redefinição das fontes</value>\n  </data>\n  <data name=\"SourceResetListAndOverridePreamble\" xml:space=\"preserve\">\n    <value>As seguintes fontes serão redefinidas se a opção--force for fornecida:</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"SourceResetOne\" xml:space=\"preserve\">\n    <value>Redefinindo fonte: {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a repository source that is currently being reset. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceTypeArgumentDescription\" xml:space=\"preserve\">\n    <value>Tipo da fonte</value>\n  </data>\n  <data name=\"SourceUpdateAll\" xml:space=\"preserve\">\n    <value>Atualizando todas as fontes...</value>\n  </data>\n  <data name=\"SourceUpdateCommandLongDescription\" xml:space=\"preserve\">\n    <value>Atualizar todas as fontes ou apenas uma fonte específica.</value>\n  </data>\n  <data name=\"SourceUpdateCommandShortDescription\" xml:space=\"preserve\">\n    <value>Atualizar fontes atuais</value>\n  </data>\n  <data name=\"SourceUpdateOne\" xml:space=\"preserve\">\n    <value>Atualizando fonte: {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being updated. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"TagArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtrar resultados por rótulo</value>\n  </data>\n  <data name=\"ThankYou\" xml:space=\"preserve\">\n    <value>Obrigado por usar o winget</value>\n  </data>\n  <data name=\"ThirdPartSoftwareNotices\" xml:space=\"preserve\">\n    <value>Avisos de Terceiros</value>\n  </data>\n  <data name=\"ToolDescription\" xml:space=\"preserve\">\n    <value>O programa utilitário de linha de comando winget permite instalar aplicativos e outros pacotes a partir da linha de comando.</value>\n  </data>\n  <data name=\"ToolInfoArgumentDescription\" xml:space=\"preserve\">\n    <value>Exibir informações gerais da ferramenta</value>\n  </data>\n  <data name=\"ToolVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>Exibir a versão da ferramenta</value>\n  </data>\n  <data name=\"TooManyArgError\" xml:space=\"preserve\">\n    <value>Argumento fornecido mais vezes do que o permitido: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a command line argument more times than it is allowed. {0} is a placeholder replaced by the user's argument name input.</comment>\n  </data>\n  <data name=\"TooManyBehaviorsError\" xml:space=\"preserve\">\n    <value>Mais de um argumento de comportamento de execução fornecido: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides more than one execution behavior argument when installing an application package. {0} is a placeholder replaced by the user specified execution behaviors (e.g. 'silent|interactive').</comment>\n  </data>\n  <data name=\"UnexpectedErrorExecutingCommand\" xml:space=\"preserve\">\n    <value>Ocorreu um erro inesperado ao executar o comando:</value>\n  </data>\n  <data name=\"UninstallPreviousArgumentDescription\" xml:space=\"preserve\">\n    <value>Desinstalar a versão anterior do pacote durante a atualização</value>\n  </data>\n  <data name=\"UnrecognizedCommand\" xml:space=\"preserve\">\n    <value>Comando não reconhecido: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an unrecognized command. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"UpdateAllArgumentDescription\" xml:space=\"preserve\">\n    <value>Atualizar todos os pacotes instalados para o mais recente, se disponível</value>\n  </data>\n  <data name=\"UpdateNotApplicable\" xml:space=\"preserve\">\n    <value>Nenhuma atualização aplicável foi encontrada.</value>\n  </data>\n  <data name=\"UpdateNotApplicableReason\" xml:space=\"preserve\">\n    <value>Uma versão de pacote mais recente está disponível em uma origem configurada, mas não se aplica ao seu sistema ou requisitos.</value>\n  </data>\n  <data name=\"UpdateNoPackagesFound\" xml:space=\"preserve\">\n    <value>Nenhuma atualização disponível foi encontrada.</value>\n  </data>\n  <data name=\"UpdateNoPackagesFoundReason\" xml:space=\"preserve\">\n    <value>Nenhuma versão de pacote mais recente está disponível nas origens configuradas.</value>\n  </data>\n  <data name=\"UpgradeCommandLongDescription\" xml:space=\"preserve\">\n    <value>Atualiza o pacote selecionado, encontrado pesquisando a lista de pacotes instalados ou diretamente de um manifesto. Por padrão, a consulta deve corresponder, sem diferenciação entre maiúsculas e minúsculas, à id, name ou ao moniker do pacote. Outros campos podem ser usados passando a opção apropriada. Quando nenhum argumento é fornecido, mostra os pacotes com atualizações disponíveis</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"UpgradeCommandShortDescription\" xml:space=\"preserve\">\n    <value>Mostra e executa atualizações disponíveis</value>\n  </data>\n  <data name=\"Usage\" xml:space=\"preserve\">\n    <value>uso: {0} {1}</value>\n    <comment>{Locked=\"{0} {1}\"} Message displayed to provide the user with instructions on how to use a command. {0} is a placeholder replaced by the program name (e.g. 'winget'). {1} is a placeholder replaced by the pattern for using the selected command.</comment>\n  </data>\n  <data name=\"ValidateCommandLongDescription\" xml:space=\"preserve\">\n    <value>Valida um manifesto usando um conjunto estrito de diretrizes. O objetivo é permitir que você verifique o manifesto antes de enviá-lo para um repositório.</value>\n  </data>\n  <data name=\"ValidateCommandShortDescription\" xml:space=\"preserve\">\n    <value>Valida um arquivo de manifesto</value>\n  </data>\n  <data name=\"ValidateManifestArgumentDescription\" xml:space=\"preserve\">\n    <value>O caminho para o manifesto a ser validado</value>\n  </data>\n  <data name=\"VerboseLogsArgumentDescription\" xml:space=\"preserve\">\n    <value>Habilita o registro em log detalhado para winget</value>\n  </data>\n  <data name=\"VerifyFileSignedMsix\" xml:space=\"preserve\">\n    <value>Verifique se o arquivo de entrada é um MSIX assinado válido.</value>\n  </data>\n  <data name=\"VersionArgumentDescription\" xml:space=\"preserve\">\n    <value>Usar a versão especificada. O padrão é a versão mais recente</value>\n  </data>\n  <data name=\"VersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Mostrar versões disponíveis do pacote</value>\n  </data>\n  <data name=\"WordArgumentDescription\" xml:space=\"preserve\">\n    <value>O valor fornecido antes da conclusão é solicitado</value>\n  </data>\n  <data name=\"GetManifestResultVersionNotFound\" xml:space=\"preserve\">\n    <value>Nenhuma versão correspondente foi encontrada: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to upgrade an application package to a version that was not found. {0} is a placeholder replaced by the user's provided upgrade package version.</comment>\n  </data>\n  <data name=\"OpenSourceFailedNoMatch\" xml:space=\"preserve\">\n    <value>Nenhuma fonte corresponde ao valor fornecido: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to install or upgrade an application package from a repository source that was not found. {0} is a placeholder replaced by the user's repository source name input.</comment>\n  </data>\n  <data name=\"OpenSourceFailedNoMatchHelp\" xml:space=\"preserve\">\n    <value>As fontes configuradas são:</value>\n  </data>\n  <data name=\"OpenSourceFailedNoSourceDefined\" xml:space=\"preserve\">\n    <value>Nenhuma fonte definida; adicionar um com 'source add' ou redefinir para os padrões com 'source reset'</value>\n    <comment>{Locked=\"source add\",\"source reset\"}</comment>\n  </data>\n  <data name=\"ReportIdentityFound\" xml:space=\"preserve\">\n    <value>Encontrado</value>\n  </data>\n  <data name=\"VerifyFileFailedIsDirectory\" xml:space=\"preserve\">\n    <value>O caminho é um diretório: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system path that is a directory. {0} is a placeholder replaced by the provided directory path.</comment>\n  </data>\n  <data name=\"VerifyFileFailedNotExist\" xml:space=\"preserve\">\n    <value>O arquivo {0} não existe.</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system file that does not exist. {0} is a placeholder replaced by the provided file path.</comment>\n  </data>\n  <data name=\"BothManifestAndSearchQueryProvided\" xml:space=\"preserve\">\n    <value>Tanto o manifesto local quanto os argumentos de consulta de pesquisa são fornecidos</value>\n  </data>\n  <data name=\"Logs\" xml:space=\"preserve\">\n    <value>Registros</value>\n    <comment>Label displayed for diagnostic files containing information about the application use.</comment>\n  </data>\n  <data name=\"InstallerBlockedByPolicy\" xml:space=\"preserve\">\n    <value>O instalador foi bloqueado pela política</value>\n  </data>\n  <data name=\"InstallerFailedSecurityCheck\" xml:space=\"preserve\">\n    <value>O instalador falhou na verificação de segurança</value>\n  </data>\n  <data name=\"InstallerFailedVirusScan\" xml:space=\"preserve\">\n    <value>Um produto antivírus relata uma infecção no instalador</value>\n  </data>\n  <data name=\"SourceOpenWithFailedUpdate\" xml:space=\"preserve\">\n    <value>Falha ao tentar atualizar a origem: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to update the repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"UninstallCommandLongDescription\" xml:space=\"preserve\">\n    <value>Desinstala o pacote selecionado, encontrado pesquisando a lista de pacotes instalados ou diretamente de um manifesto. Por padrão, a consulta deve corresponder de forma insensível à ID, ao nome ou ao moniker do pacote. Outros campos podem ser usados passando a opção apropriada.</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"UninstallCommandShortDescription\" xml:space=\"preserve\">\n    <value>Desinstala um determinado pacote</value>\n  </data>\n  <data name=\"UninstallFlowStartingPackageUninstall\" xml:space=\"preserve\">\n    <value>Iniciando a desinstalação do pacote...</value>\n  </data>\n  <data name=\"UninstallFlowUninstallSuccess\" xml:space=\"preserve\">\n    <value>Desinstalado com êxito</value>\n  </data>\n  <data name=\"NoUninstallInfoFound\" xml:space=\"preserve\">\n    <value>winget não é possível localizar o comando Uninstall deste pacote. Entre no fornecedor do pacote para obter suporte.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"UninstallAbandoned\" xml:space=\"preserve\">\n    <value>Desinstalação abandonada</value>\n  </data>\n  <data name=\"UninstallFailedWithCode\" xml:space=\"preserve\">\n    <value>Falha na desinstalação com o código de saída: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to uninstall an application package fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"ExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Exporta uma lista dos pacotes instalados</value>\n  </data>\n  <data name=\"ImportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Instala todos os pacotes listados em um arquivo.</value>\n  </data>\n  <data name=\"ImportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Instala todos os pacotes em um arquivo</value>\n  </data>\n  <data name=\"OutputFileArgumentDescription\" xml:space=\"preserve\">\n    <value>Arquivo em que o resultado deve ser gravado</value>\n  </data>\n  <data name=\"ImportFileArgumentDescription\" xml:space=\"preserve\">\n    <value>Arquivo descrevendo os pacotes que serão instalados</value>\n  </data>\n  <data name=\"ExportSourceArgumentDescription\" xml:space=\"preserve\">\n    <value>Exportar pacotes a partir da fonte especificada</value>\n  </data>\n  <data name=\"ExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Grava uma lista de pacotes instalados em um arquivo. Os pacotes podem ser instalados com o comando import.</value>\n    <comment>{Locked=\"import\"}</comment>\n  </data>\n  <data name=\"ImportInstallFailed\" xml:space=\"preserve\">\n    <value>Um ou mais pacotes importados não foram instalados</value>\n  </data>\n  <data name=\"ImportSourceNotInstalled\" xml:space=\"preserve\">\n    <value>A origem necessária para a importação não está instalada: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to import application package(s) from a repository source that is not installed. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"InstalledPackageNotAvailable\" xml:space=\"preserve\">\n    <value>Pacote instalado não disponível em nenhuma fonte: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when the user attempts to export an installed application package that is not available from any repository source. {0} is a placeholder replaced by the installed package name.</comment>\n  </data>\n  <data name=\"InstalledPackageVersionNotAvailable\" xml:space=\"preserve\">\n    <value>Versão instalada do pacote não disponível em nenhuma fonte: {0} {1} {2}</value>\n    <comment>{Locked=\"{0} {1} {2}\"} Warning message displayed when the user attempts to export an installed application package with a version that is not available from any repository source. {0} is a placeholder replaced by the installed package identifier. {1} is a placeholder replaced by the installed package version. {2} is a placeholder replaced by the installed package channel.</comment>\n  </data>\n  <data name=\"NoPackagesInImportFile\" xml:space=\"preserve\">\n    <value>Não foram encontrados pacotes no arquivo de importação</value>\n  </data>\n  <data name=\"InvalidJsonFile\" xml:space=\"preserve\">\n    <value>Arquivo JSON não é válido</value>\n  </data>\n  <data name=\"MultiQueryPackageAlreadyInstalled\" xml:space=\"preserve\">\n    <value>O pacote já está instalado: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user that an application package is already installed. {0} is a placeholder replaced by the package identifier or search query.</comment>\n  </data>\n  <data name=\"ImportIgnoreUnavailableArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignorar os pacotes indisponíveis</value>\n  </data>\n  <data name=\"ExportIncludeVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Incluir versões de pacote no arquivo de exportação</value>\n  </data>\n  <data name=\"ImportIgnoreVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignorar as versões de pacote do arquivo de importação</value>\n  </data>\n  <data name=\"VerifyPathFailedNotExist\" xml:space=\"preserve\">\n    <value>O caminho não existe: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system path argument value that does not exist. {0} is a placeholder replaced by the user's provided path.</comment>\n  </data>\n  <data name=\"ImportFileHasInvalidSchema\" xml:space=\"preserve\">\n    <value>O arquivo JSON não especifica um esquema reconhecido.</value>\n  </data>\n  <data name=\"InstallScopeDescription\" xml:space=\"preserve\">\n    <value>Selecione instalar escopo (user ou machine)</value>\n    <comment>{Locked=\"user\",\"machine\"} This argument allows the user to select between installing for just the user or for the entire machine.</comment>\n  </data>\n  <data name=\"InvalidArgumentValueError\" xml:space=\"preserve\">\n    <value>O valor fornecido para o argumento '{0}' é inválido; os valores válidos são: {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message displayed when the user provides an invalid command line argument value. {0} is a placeholder replaced by the argument name. {1} is a placeholder replaced by a list of valid options.</comment>\n  </data>\n  <data name=\"DisabledByGroupPolicy\" xml:space=\"preserve\">\n    <value>Esta operação foi desabilitada por Política de Grupo: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user performs a command operation that is disabled by a group policy. {0} is a placeholder replaced by a group policy description.</comment>\n  </data>\n  <data name=\"PolicyAdditionalSources\" xml:space=\"preserve\">\n    <value>Habilitar as Fontes Adicionais do Instalador de Aplicativos do Windows</value>\n  </data>\n  <data name=\"PolicyAllowedSources\" xml:space=\"preserve\">\n    <value>Habilitar as Fontes permitidas do Instalador de Aplicativos do Windows</value>\n  </data>\n  <data name=\"PolicyEnableDefaultSource\" xml:space=\"preserve\">\n    <value>Habilitar a Fonte Padrão do Instalador de Aplicativos do Windows</value>\n  </data>\n  <data name=\"PolicyEnableExperimentalFeatures\" xml:space=\"preserve\">\n    <value>Habilitar os Recursos Experimentais do Instalador de Aplicativos do Windows</value>\n  </data>\n  <data name=\"PolicyEnableMSStoreSource\" xml:space=\"preserve\">\n    <value>Habilitar a Fonte da Microsoft Store do Instalador de Aplicativos do Windows</value>\n  </data>\n  <data name=\"PolicyEnableFontSource\" xml:space=\"preserve\">\n    <value>Habilitar a origem da fonte do Instalador de Windows App</value>\n  </data>\n  <data name=\"PolicyEnableWinGetSettings\" xml:space=\"preserve\">\n    <value>Habilitar as Configurações do Gerenciador de Pacotes do Windows</value>\n  </data>\n  <data name=\"PolicyEnableWinGet\" xml:space=\"preserve\">\n    <value>Habilitar o Gerenciador de Pacotes do Windows</value>\n  </data>\n  <data name=\"PolicyEnableWindowsPackageManagerCommandLineInterfaces\" xml:space=\"preserve\">\n    <value>Habilitar interfaces de linha de comando do Gerenciador de Pacotes do Windows</value>\n  </data>\n  <data name=\"PolicySourceAutoUpdateInterval\" xml:space=\"preserve\">\n    <value>Definir o Intervalo de Atualização Automática da Fonte do Gerenciador de Pacotes do Windows em Minutos</value>\n  </data>\n  <data name=\"PoliciesPolicy\" xml:space=\"preserve\">\n    <value>Política de Grupo</value>\n    <comment>Header for a table listing active Group Policies</comment>\n  </data>\n  <data name=\"PolicyEnableLocalManifests\" xml:space=\"preserve\">\n    <value>Habilitar o Arquivos de Manifesto Local do Instalador de Aplicativos do Windows</value>\n  </data>\n  <data name=\"PolicyEnableBypassCertificatePinningForMicrosoftStore\" xml:space=\"preserve\">\n    <value>Habilitar Ignorar o Certificado Fixado de Origem da Microsoft Store do Instalador de Aplicativo do Windows</value>\n  </data>\n  <data name=\"PolicyEnableLocalArchiveMalwareScanOverride\" xml:space=\"preserve\">\n    <value>Habilitar a Substituição de Escaneamento de Malware de Arquivo Morto Local do Instalador de aplicativo do Windows</value>\n  </data>\n  <data name=\"SettingsWarningField\" xml:space=\"preserve\">\n    <value>Campo: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when a user setting field has invalid syntax or semantics. {0} is a placeholder replaced by the setting field path.</comment>\n  </data>\n  <data name=\"SettingsWarningInvalidFieldFormat\" xml:space=\"preserve\">\n    <value>O formato de campo é inválido.</value>\n  </data>\n  <data name=\"SettingsWarningInvalidFieldValue\" xml:space=\"preserve\">\n    <value>O valor de campo é inválido.</value>\n  </data>\n  <data name=\"SettingsWarningInvalidValueFromPolicy\" xml:space=\"preserve\">\n    <value>A configuração da Política de Grupo é inválida.</value>\n  </data>\n  <data name=\"SettingsWarningLoadedBackupSettings\" xml:space=\"preserve\">\n    <value>Configurações carregadas a partir do arquivo de backup.</value>\n  </data>\n  <data name=\"SettingsWarningParseError\" xml:space=\"preserve\">\n    <value>Arquivo de análise de erros:</value>\n  </data>\n  <data name=\"SettingsWarningValue\" xml:space=\"preserve\">\n    <value>Valor: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when a user setting value has invalid syntax or semantics. {0} is a placeholder replaced by the setting data value.</comment>\n  </data>\n  <data name=\"FeaturesMessageDisabledByPolicy\" xml:space=\"preserve\">\n    <value>Os seguintes recursos experimentais estão em andamento.\nA configuração está desabilitada devido à política de grupo.</value>\n  </data>\n  <data name=\"InstallerHashMismatchError\" xml:space=\"preserve\">\n    <value>O hash do instalador não corresponde.</value>\n  </data>\n  <data name=\"PolicyEnableHashOverride\" xml:space=\"preserve\">\n    <value>Habilitar a Substituição do Hash do Instalador de Aplicativos do Windows</value>\n  </data>\n  <data name=\"SourceExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Exportar as fontes atuais como JSON para a política de grupo.</value>\n  </data>\n  <data name=\"SourceExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Exportar fontes atuais</value>\n  </data>\n  <data name=\"SourceListAdditionalSource\" xml:space=\"preserve\">\n    <value>Fonte adicional</value>\n    <comment>An additional source required by policy.</comment>\n  </data>\n  <data name=\"SourceListAllowedSource\" xml:space=\"preserve\">\n    <value>Fonte permitida</value>\n    <comment>A source that the user is allowed to add.</comment>\n  </data>\n  <data name=\"InvalidArgumentValueErrorWithoutValidValues\" xml:space=\"preserve\">\n    <value>O valor fornecido para o argumento '{0}' é inválido</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an invalid command line argument value. {0} is a placeholder replaced by the argument name.</comment>\n  </data>\n  <data name=\"Cancelled\" xml:space=\"preserve\">\n    <value>Cancelado</value>\n  </data>\n  <data name=\"ExternalDependencies\" xml:space=\"preserve\">\n    <value>Externo</value>\n  </data>\n  <data name=\"ImportCommandReportDependencies\" xml:space=\"preserve\">\n    <value>Os pacotes encontrados nesta importação têm as seguintes dependências:</value>\n    <comment>Import command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"PackageRequiresDependencies\" xml:space=\"preserve\">\n    <value>Este pacote requer as seguintes dependências:</value>\n    <comment>Message shown before reporting dependencies</comment>\n  </data>\n  <data name=\"DependenciesFlowInstall\" xml:space=\"preserve\">\n    <value>Instalando dependências:</value>\n  </data>\n  <data name=\"DependenciesFlowSourceNotFound\" xml:space=\"preserve\">\n    <value>Origem da dependência não encontrada</value>\n  </data>\n  <data name=\"DependenciesFlowSourceTooManyMatches\" xml:space=\"preserve\">\n    <value>A pesquisa de pacote produz mais de um resultado: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when application packages search yield more than one result. {0} is a placeholder replaced by the dependency package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowPackageVersionNotFound\" xml:space=\"preserve\">\n    <value>Versão mais recente não encontrada para o pacote: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when no suitable version found for the specific application package. {0} is a placeholder replaced by the package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoInstallerFound\" xml:space=\"preserve\">\n    <value>Nenhum instalador encontrado: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when no installer found for a manifest. {0} is a placeholder replaced by the manifest identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoMinVersion\" xml:space=\"preserve\">\n    <value>Versão mínima exigida não disponível para o pacote: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the minimum required version is not available for an application package. {0} is a placeholder replaced by the package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoMatches\" xml:space=\"preserve\">\n    <value>Nenhuma correspondência</value>\n    <comment>When package search yields no matches</comment>\n  </data>\n  <data name=\"DependenciesFlowContainsLoop\" xml:space=\"preserve\">\n    <value>Tem loop</value>\n    <comment>Dependency graph has loop</comment>\n  </data>\n  <data name=\"DependenciesFlowNoSuitableInstallerFound\" xml:space=\"preserve\">\n    <value>Nenhum instalador adequado encontrado para o manifesto: {0} versão {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message displayed when an attempt to get a preferred installer for a manifest fails. {0} is a placeholder replaced by the manifest identifier. {1} is a placeholder replaced by the manifest version.</comment>\n  </data>\n  <data name=\"DependenciesManagementError\" xml:space=\"preserve\">\n    <value>Erro ao processar as dependências do pacote. Deseja continuar com a instalação?</value>\n    <comment>Prompt message shown when dependencies processing yields errors.</comment>\n  </data>\n  <data name=\"DependenciesManagementExitMessage\" xml:space=\"preserve\">\n    <value>Erro ao processar as dependências do pacote. Saindo...</value>\n  </data>\n  <data name=\"PackageDependencies\" xml:space=\"preserve\">\n    <value>Pacotes</value>\n  </data>\n  <data name=\"UninstallCommandReportDependencies\" xml:space=\"preserve\">\n    <value>Este pacote tinha dependências que podem não ser mais necessárias:</value>\n    <comment>Uninstall command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"ValidateCommandReportDependencies\" xml:space=\"preserve\">\n    <value>O manifesto tem as seguintes dependências que não foram validadas; verifique se eles são válidos:</value>\n    <comment>Validate command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"WindowsFeaturesDependencies\" xml:space=\"preserve\">\n    <value>Recursos do Windows</value>\n  </data>\n  <data name=\"WindowsLibrariesDependencies\" xml:space=\"preserve\">\n    <value>Bibliotecas do Windows</value>\n  </data>\n  <data name=\"DependencySourceArgumentDescription\" xml:space=\"preserve\">\n    <value>Encontre as dependências de pacotes usando a origem especificada</value>\n    <comment>For getting package type dependencies when installing from a local manifest</comment>\n  </data>\n  <data name=\"WindowsStoreTerms\" xml:space=\"preserve\">\n    <value>Termos da Windows Store</value>\n  </data>\n  <data name=\"AcceptPackageAgreementsArgumentDescription\" xml:space=\"preserve\">\n    <value>Aceitar todos os contratos de licença para pacotes</value>\n  </data>\n  <data name=\"ExportedPackageRequiresLicenseAgreement\" xml:space=\"preserve\">\n    <value>O pacote exportado requer o contrato de licença para instalar: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when an exported application package requires license agreement to install. {0} is a placeholder replaced by the package name.</comment>\n  </data>\n  <data name=\"PackageAgreementsPrompt\" xml:space=\"preserve\">\n    <value>O editor requer que você exiba as informações acima e aceite os contratos antes de instalar.\nVocê concorda com os termos?</value>\n  </data>\n  <data name=\"PackageAgreementsNotAgreedTo\" xml:space=\"preserve\">\n    <value>Os contratos de pacote não foram concordados. Operação cancelada.</value>\n  </data>\n  <data name=\"ShowLabelAgreements\" xml:space=\"preserve\">\n    <value>Acordos:</value>\n  </data>\n  <data name=\"ShowLabelAuthor\" xml:space=\"preserve\">\n    <value>Autor:</value>\n  </data>\n  <data name=\"ShowLabelDescription\" xml:space=\"preserve\">\n    <value>Descrição:</value>\n  </data>\n  <data name=\"ShowLabelInstaller\" xml:space=\"preserve\">\n    <value>Instaladora:</value>\n  </data>\n  <data name=\"ShowLabelInstallerLocale\" xml:space=\"preserve\">\n    <value>Local do instalador:</value>\n  </data>\n  <data name=\"ShowLabelInstallerProductId\" xml:space=\"preserve\">\n    <value>Id do Produto da Microsoft Store:</value>\n  </data>\n  <data name=\"ShowLabelInstallerSha256\" xml:space=\"preserve\">\n    <value>Instalador SHA256:</value>\n  </data>\n  <data name=\"ShowLabelInstallerType\" xml:space=\"preserve\">\n    <value>Tipo de instalador:</value>\n  </data>\n  <data name=\"ShowLabelInstallerUrl\" xml:space=\"preserve\">\n    <value>URL do instalador:</value>\n  </data>\n  <data name=\"ShowLabelLicense\" xml:space=\"preserve\">\n    <value>Licença:</value>\n  </data>\n  <data name=\"ShowLabelLicenseUrl\" xml:space=\"preserve\">\n    <value>URL da licença:</value>\n  </data>\n  <data name=\"ShowLabelMoniker\" xml:space=\"preserve\">\n    <value>Moniker:</value>\n  </data>\n  <data name=\"ShowLabelPackageUrl\" xml:space=\"preserve\">\n    <value>Página inicial:</value>\n  </data>\n  <data name=\"ShowLabelPublisher\" xml:space=\"preserve\">\n    <value>Fornecedor:</value>\n  </data>\n  <data name=\"ShowLabelTags\" xml:space=\"preserve\">\n    <value>Marcas:</value>\n  </data>\n  <data name=\"ShowLabelVersion\" xml:space=\"preserve\">\n    <value>Versão:</value>\n  </data>\n  <data name=\"ShowLabelDependencies\" xml:space=\"preserve\">\n    <value>Dependências:</value>\n  </data>\n  <data name=\"ShowLabelWindowsFeaturesDependencies\" xml:space=\"preserve\">\n    <value>Recursos do Windows:</value>\n  </data>\n  <data name=\"ShowLabelWindowsLibrariesDependencies\" xml:space=\"preserve\">\n    <value>Bibliotecas do Windows:</value>\n  </data>\n  <data name=\"ShowLabelPackageDependencies\" xml:space=\"preserve\">\n    <value>Dependências do pacote:</value>\n  </data>\n  <data name=\"ShowLabelExternalDependencies\" xml:space=\"preserve\">\n    <value>Dependências externas:</value>\n  </data>\n  <data name=\"PromptOptionNo\" xml:space=\"preserve\">\n    <value>Não</value>\n  </data>\n  <data name=\"PromptOptionYes\" xml:space=\"preserve\">\n    <value>Sim</value>\n  </data>\n  <data name=\"SourceAddOpenSourceFailed\" xml:space=\"preserve\">\n    <value>Falha ao abrir a fonte adicionada.</value>\n  </data>\n  <data name=\"AcceptSourceAgreementsArgumentDescription\" xml:space=\"preserve\">\n    <value>Aceitar todos os acordos de origem durante as operações de origem</value>\n  </data>\n  <data name=\"SourceAgreementsTitle\" xml:space=\"preserve\">\n    <value>A fonte '{0}' requer que você exiba os seguintes contratos antes de usar.</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user that a repository source requires viewing agreements before using. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceAgreementsPrompt\" xml:space=\"preserve\">\n    <value>Você concorda com todos os termos dos contratos de origem?</value>\n  </data>\n  <data name=\"SourceAgreementsNotAgreedTo\" xml:space=\"preserve\">\n    <value>Um ou mais contratos de origem não foram concordados. Operação cancelada. Aceite os contratos de origem ou remova as fontes correspondentes.</value>\n  </data>\n  <data name=\"SourceAgreementsMarketMessage\" xml:space=\"preserve\">\n    <value>A origem requer que a região geográfica de duas letras do computador atual seja enviada ao serviço de back-end para funcionar corretamente (por exemplo, \"EUA\").</value>\n  </data>\n  <data name=\"InstallFlowRegistrationDeferred\" xml:space=\"preserve\">\n    <value>Instalado com êxito. Reinicie o aplicativo para concluir a atualização.</value>\n  </data>\n  <data name=\"HeaderArgumentDescription\" xml:space=\"preserve\">\n    <value>Cabeçalho HTTP de origem REST opcional do Gerenciador de Pacotes do Windows</value>\n  </data>\n  <data name=\"HeaderArgumentNotApplicableForNonRestSourceWarning\" xml:space=\"preserve\">\n    <value>Ignorando o cabeçalho opcional, pois ele não é aplicável a esta fonte.</value>\n  </data>\n  <data name=\"HeaderArgumentNotApplicableWithoutSource\" xml:space=\"preserve\">\n    <value>O cabeçalho opcional não é aplicável sem especificar uma fonte: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user performs an operation (e.g install) and provides the HTTP 'header' argument without specifying the repository source. {0} is a placeholder replaced by the header argument name.</comment>\n  </data>\n  <data name=\"ShowLabelInstallerReleaseDate\" xml:space=\"preserve\">\n    <value>Data do Lançamento:</value>\n  </data>\n  <data name=\"ShowLabelInstallerOfflineDistributionSupported\" xml:space=\"preserve\">\n    <value>Distribuição Offline Com Suporte:</value>\n  </data>\n  <data name=\"ShowLabelPublisherUrl\" xml:space=\"preserve\">\n    <value>URL do Fornecedor:</value>\n  </data>\n  <data name=\"ShowLabelPurchaseUrl\" xml:space=\"preserve\">\n    <value>URL de compra:</value>\n  </data>\n  <data name=\"ShowLabelPublisherSupportUrl\" xml:space=\"preserve\">\n    <value>URL de Suporte do Fornecedor:</value>\n  </data>\n  <data name=\"ShowLabelPrivacyUrl\" xml:space=\"preserve\">\n    <value>URL de Privacidade:</value>\n  </data>\n  <data name=\"ShowLabelCopyright\" xml:space=\"preserve\">\n    <value>Copyright:</value>\n  </data>\n  <data name=\"ShowLabelCopyrightUrl\" xml:space=\"preserve\">\n    <value>Copyright URL:</value>\n  </data>\n  <data name=\"ShowLabelReleaseNotes\" xml:space=\"preserve\">\n    <value>Notas de Versão</value>\n  </data>\n  <data name=\"ShowLabelReleaseNotesUrl\" xml:space=\"preserve\">\n    <value>URL de Notas de Versão:</value>\n  </data>\n  <data name=\"SearchFailureWarning\" xml:space=\"preserve\">\n    <value>Falha ao pesquisar origem; os resultados não serão incluídos: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when searching a repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SearchFailureError\" xml:space=\"preserve\">\n    <value>Falha na pesquisa da origem: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when searching a repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"FeatureDisabledByAdminSettingMessage\" xml:space=\"preserve\">\n    <value>Este recurso precisa ser habilitado pelos administradores. Para habilita-lo, execute 'winget settings --enable {0}' como administrador.</value>\n    <comment>{Locked=\"winget settings --enable\", \"{0}\"}. Error message displayed when the user uses a feature that needs to be enabled by administrators. {0} is a placeholder replaced by the admin setting.</comment>\n  </data>\n  <data name=\"AdminSettingEnableDescription\" xml:space=\"preserve\">\n    <value>Habilitar a configuração específica do administrador</value>\n  </data>\n  <data name=\"AdminSettingDisableDescription\" xml:space=\"preserve\">\n    <value>Desabilitar a configuração específica do administrador</value>\n  </data>\n  <data name=\"AdminSettingEnabled\" xml:space=\"preserve\">\n    <value>Configuração de administrador \"{0}\" habilitada.</value>\n    <comment>{Locked=\"{0}\"} Message displayed when the user enables an admin setting. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"AdminSettingDisabled\" xml:space=\"preserve\">\n    <value>Configuração de administrador \"{0}\" desabilitada.</value>\n    <comment>{Locked=\"{0}\"} Message displayed when the user disables an admin setting. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"AdminSettingHeader\" xml:space=\"preserve\">\n    <value>Configuração do Administrador</value>\n    <comment>Header for a table displaying admin settings.</comment>\n  </data>\n  <data name=\"InstallFlowReturnCodePackageInUse\" xml:space=\"preserve\">\n    <value>O aplicativo está em execução no momento. Saia do aplicativo e tente novamente.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodePackageInUseByApplication\" xml:space=\"preserve\">\n    <value>Os arquivos modificados pelo instalador estão sendo usados por um aplicativo diferente. Saia dos aplicativos e tente novamente.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInstallInProgress\" xml:space=\"preserve\">\n    <value>Outra instalação já está em andamento. Tente novamente mais tarde.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeFileInUse\" xml:space=\"preserve\">\n    <value>Um ou mais arquivos estão sendo usados. Saia do aplicativo e tente novamente.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeMissingDependency\" xml:space=\"preserve\">\n    <value>Este pacote tem uma dependência ausente do sistema.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeDiskFull\" xml:space=\"preserve\">\n    <value>Não há mais espaço no computador. Libere espaço e tente novamente.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInsufficientMemory\" xml:space=\"preserve\">\n    <value>Não há memória suficiente disponível para instalar. Fechar outros aplicativos e depois tentar novamente.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInvalidParameter\" xml:space=\"preserve\">\n    <value>Um dos parâmetros de instalação é inválido. O log de instalação do pacote pode ter detalhes adicionais.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeNoNetwork\" xml:space=\"preserve\">\n    <value>Este aplicativo requer conectividade com a Internet. Conecte-se a uma rede e tente novamente.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeContactSupport\" xml:space=\"preserve\">\n    <value>Este aplicativo encontrou um erro durante a instalação. Entre em contato com o suporte.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootRequiredToFinish\" xml:space=\"preserve\">\n    <value>Reiniciar seu PC para terminar a instalação.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootRequiredForInstall\" xml:space=\"preserve\">\n    <value>Seu PC será reiniciado para terminar a instalação.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootInitiated\" xml:space=\"preserve\">\n    <value>Falha na instalação. Reinicie o computador e tente novamente.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeCancelledByUser\" xml:space=\"preserve\">\n    <value>Você cancelou a instalação.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeAlreadyInstalled\" xml:space=\"preserve\">\n    <value>Outra versão deste aplicativo já está instalada.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeDowngrade\" xml:space=\"preserve\">\n    <value>Uma versão superior deste aplicativo já está instalada.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeBlockedByPolicy\" xml:space=\"preserve\">\n    <value>As políticas da organização estão impedindo a instalação. Entre em contato com o administrador.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeSystemNotSupported\" xml:space=\"preserve\">\n    <value>A configuração atual do sistema não dá suporte à instalação deste pacote.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeCustomError\" xml:space=\"preserve\">\n    <value>Falha na instalação com um erro de instalador personalizado. Entre em contato com o suporte do pacote.</value>\n  </data>\n  <data name=\"InstallAbandoned\" xml:space=\"preserve\">\n    <value>Instalação abandonada</value>\n  </data>\n  <data name=\"InstallerFailedWithCode\" xml:space=\"preserve\">\n    <value>O instalador falhou com o código de saída: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the application installer fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"InstallerLogAvailable\" xml:space=\"preserve\">\n    <value>O registro do instalador está disponível em: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about the system path of a diagnostic files containing information about the installer. {0} is a placeholder replaced by the diagnostic file system path.</comment>\n  </data>\n  <data name=\"SearchFailureErrorListMatches\" xml:space=\"preserve\">\n    <value>Os seguintes pacotes foram encontrados entre as fontes de trabalho.\nEspecifique um deles usando a opção --source para continuar.</value>\n    <comment>{Locked=\"--source\"} \"working sources\" as in \"sources that are working correctly\"</comment>\n  </data>\n  <data name=\"SearchFailureErrorNoMatches\" xml:space=\"preserve\">\n    <value>Nenhum pacote foi encontrado entre as fontes de trabalho.</value>\n    <comment>\"working sources\" as in \"sources that are working correctly\"</comment>\n  </data>\n  <data name=\"FeaturesMessageDisabledByBuild\" xml:space=\"preserve\">\n    <value>Esta é uma versão estável do Gerenciador de Pacotes do Windows. Se quiser experimentar os recursos experimentais, instale uma versão de pré-lançamento. As instruções estão disponíveis no GitHub em https://github.com/microsoft/winget-cli.</value>\n    <comment>{Locked=\"https://github.com/microsoft/winget-cli\"}</comment>\n  </data>\n  <data name=\"WindowsPackageManager\" xml:space=\"preserve\">\n    <value>Gerenciador de Pacotes do Windows v{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying the product name and version. {0} is a placeholder replaced by the product version.</comment>\n  </data>\n  <data name=\"ImportIgnorePackageVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignorar versões do pacote no arquivo de importação</value>\n  </data>\n  <data name=\"CountOutOfBoundsError\" xml:space=\"preserve\">\n    <value>O número solicitado de resultados deve estar entre 1 e 1000.</value>\n  </data>\n  <data name=\"CustomSwitchesArgumentDescription\" xml:space=\"preserve\">\n    <value>Argumentos a serem passados para o instalador, além dos padrões</value>\n  </data>\n  <data name=\"UpgradeDifferentInstallTechnologyInNewerVersions\" xml:space=\"preserve\">\n    <value>Uma versão mais recente foi encontrada, mas a tecnologia de instalação é diferente da versão atual instalada. Desinstale o pacote e instale a versão mais recente.</value>\n  </data>\n  <data name=\"UpgradeDifferentInstallTechnology\" xml:space=\"preserve\">\n    <value>A tecnologia de instalação da versão mais recente especificada é diferente da versão atual instalada. Desinstale o pacote e instale a versão mais recente.</value>\n  </data>\n  <data name=\"WindowsPackageManagerPreview\" xml:space=\"preserve\">\n    <value>Gerenciador de Pacotes do Windows (Pré-visualização) v{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying the preview product name and pre-release version. {0} is a placeholder replaced by the product version.</comment>\n  </data>\n  <data name=\"ArchitectureArgumentDescription\" xml:space=\"preserve\">\n    <value>Selecionar a arquitetura</value>\n  </data>\n  <data name=\"IncludeUnknownArgumentDescription\" xml:space=\"preserve\">\n    <value>Atualizar pacotes mesmo que a versão atual não seja determinada</value>\n  </data>\n  <data name=\"IncludeUnknownInListArgumentDescription\" xml:space=\"preserve\">\n    <value>Liste pacotes mesmo que sua versão atual não possa ser determinada. Só pode ser usado com o argumento --upgrade-available</value>\n    <comment>{Locked=\"--upgrade-available\"}</comment>\n  </data>\n  <data name=\"UpgradeUnknownVersionExplanation\" xml:space=\"preserve\">\n    <value>Não é possível determinar o número de versão deste pacote. Para atualizá-lo mesmo assim, adicione o argumento --include-unknown ao comando anterior.</value>\n    <comment>{Locked=\"--include-unknown\"}</comment>\n  </data>\n  <data name=\"UpgradeUnknownVersionCount\" xml:space=\"preserve\">\n    <value>{0} pacotes têm números de versão que não podem ser determinados. Use --include-unknown para ver todos os resultados.</value>\n    <comment>{Locked=\"{0}\",\"--include-unknown\"} {0} is a placeholder that is replaced by an integer number of packages that do not have notated versions. </comment>\n  </data>\n  <data name=\"UpgradeRequireExplicitCount\" xml:space=\"preserve\">\n    <value>{0} os pacotes estão fixados e precisam ser atualizados explicitamente.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by an integer number of packages that require explicit upgrades.</comment>\n  </data>\n  <data name=\"InvalidArgumentWithoutQueryError\" xml:space=\"preserve\">\n    <value>Os argumentos fornecidos só podem ser usados com uma consulta.</value>\n  </data>\n  <data name=\"SystemArchitecture\" xml:space=\"preserve\">\n    <value>Arquitetura do Sistema: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for the system architecture. {0} is a placeholder replaced by the value of the system architecture (e.g. X64).</comment>\n  </data>\n  <data name=\"PreserveArgumentDescription\" xml:space=\"preserve\">\n    <value>Retém todos os arquivos e diretórios criados pelo pacote (portátil)</value>\n  </data>\n  <data name=\"PurgeArgumentDescription\" xml:space=\"preserve\">\n    <value>Exclui todos os arquivos e diretórios no diretório do pacote (portátil)</value>\n  </data>\n  <data name=\"PressEnterToContinue\" xml:space=\"preserve\">\n    <value>Pressione Enter para continuar . . .</value>\n  </data>\n  <data name=\"RenameArgumentDescription\" xml:space=\"preserve\">\n    <value>O valor para renomear o arquivo executável (portátil)</value>\n  </data>\n  <data name=\"WaitArgumentDescription\" xml:space=\"preserve\">\n    <value>Solicita que o usuário pressione qualquer tecla antes de sair</value>\n  </data>\n  <data name=\"InstallerElevationExpected\" xml:space=\"preserve\">\n    <value>O instalador solicitará que você execute como administrador. Espere uma solicitação.</value>\n  </data>\n  <data name=\"InstallerProhibitsElevation\" xml:space=\"preserve\">\n    <value>O instalador não pode ser executado de um contexto de administrador.</value>\n  </data>\n  <data name=\"ModifiedPathRequiresShellRestart\" xml:space=\"preserve\">\n    <value>Variável de ambiente do caminho modificada; reinicie seu shell para usar o novo valor.</value>\n  </data>\n  <data name=\"ProductCodeArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtros usando o código do produto</value>\n  </data>\n  <data name=\"PortableRegistryCollisionOverridden\" xml:space=\"preserve\">\n    <value>Já existe um pacote portátil com o mesmo nome, mas de uma fonte diferente; prosseguir devido a --force</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"ReparsePointsNotSupportedError\" xml:space=\"preserve\">\n    <value>O volume não suporta pontos de nova análise</value>\n  </data>\n  <data name=\"ReservedFilenameError\" xml:space=\"preserve\">\n    <value>O nome de arquivo especificado não é um nome de arquivo válido</value>\n  </data>\n  <data name=\"OverwritingExistingFileAtMessage\" xml:space=\"preserve\">\n    <value>Substituindo arquivo existente: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed to inform the user that an existing file is being overwritten. {0} is a placeholder replaced by the file system path.</comment>\n  </data>\n  <data name=\"NoPackageSelectionArgumentProvided\" xml:space=\"preserve\">\n    <value>Nenhum argumento de seleção de pacote foi fornecido; consulte a ajuda para obter detalhes sobre como encontrar um pacote.</value>\n  </data>\n  <data name=\"PortableAliasAdded\" xml:space=\"preserve\">\n    <value>O alias da linha de comando foi adicionado:</value>\n  </data>\n  <data name=\"PortableLinksMachine\" xml:space=\"preserve\">\n    <value>Diretório de Links Portáteis (Computador)</value>\n  </data>\n  <data name=\"PortableLinksUser\" xml:space=\"preserve\">\n    <value>Diretório de Links Portáteis (Usuário)</value>\n  </data>\n  <data name=\"PortableRootUser\" xml:space=\"preserve\">\n    <value>Raiz do Pacote Portátil (Usuário)</value>\n  </data>\n  <data name=\"PortableRoot\" xml:space=\"preserve\">\n    <value>Raiz do Pacote Portátil</value>\n  </data>\n  <data name=\"PortableRoot86\" xml:space=\"preserve\">\n    <value>Raiz do Pacote Portátil (x86)</value>\n  </data>\n  <data name=\"PortableInstallFailed\" xml:space=\"preserve\">\n    <value>Falha na instalação portátil; Limpando...</value>\n  </data>\n  <data name=\"PortableHashMismatchOverridden\" xml:space=\"preserve\">\n    <value>O pacote portátil foi modificado; continuando devido a --force</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"PortableHashMismatchOverrideRequired\" xml:space=\"preserve\">\n    <value>Não é possível remover o pacote Portátil, pois ele foi modificado; para substituir essa verificação, use --force</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"FilesRemainInInstallDirectory\" xml:space=\"preserve\">\n    <value>Os arquivos permanecem no diretório de instalação: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when files remain in install directory. {0} is a placeholder replaced by the directory path.</comment>\n  </data>\n  <data name=\"PurgeInstallDirectory\" xml:space=\"preserve\">\n    <value>Limpando o diretório de instalação...</value>\n  </data>\n  <data name=\"UnableToPurgeInstallDirectory\" xml:space=\"preserve\">\n    <value>Não é possível limpar o diretório de instalação porque ele não foi criado pelo winget</value>\n  </data>\n  <data name=\"RelatedLink\" xml:space=\"preserve\">\n    <value>Link Relacionado</value>\n  </data>\n  <data name=\"ShowLabelDocumentation\" xml:space=\"preserve\">\n    <value>Documentação:</value>\n  </data>\n  <data name=\"Notes\" xml:space=\"preserve\">\n    <value>Observações: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for installation notes. {0} is a placeholder replaced by installation notes.</comment>\n  </data>\n  <data name=\"ShowLabelInstallationNotes\" xml:space=\"preserve\">\n    <value>Notas da instalação:</value>\n  </data>\n  <data name=\"UnsupportedArgument\" xml:space=\"preserve\">\n    <value>Não há suporte para um argumento fornecido para este pacote</value>\n  </data>\n  <data name=\"ExtractArchiveFailed\" xml:space=\"preserve\">\n    <value>Falha ao extrair o conteúdo do arquivo morto</value>\n  </data>\n  <data name=\"NestedInstallerNotFound\" xml:space=\"preserve\">\n    <value>O arquivo do instalador aninhado não existe. Verifique se o caminho relativo especificado das correspondentes do instalador aninhado: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when nested installer file does not exist. {0} is a placeholder replaced by the nested installer file path.</comment>\n  </data>\n  <data name=\"InvalidPathToNestedInstaller\" xml:space=\"preserve\">\n    <value>Caminho de arquivo relativo inválido para o instalador aninhado; caminho aponta para um local fora do diretório de instalação</value>\n  </data>\n  <data name=\"NestedInstallerNotSpecified\" xml:space=\"preserve\">\n    <value>Nenhum instalador aninhado especificado para esse pacote</value>\n  </data>\n  <data name=\"MultipleUnsupportedNestedInstallersSpecified\" xml:space=\"preserve\">\n    <value>Somente um instalador aninhado pode ser especificado para um instalador de arquivo morto, a menos que ele seja um instalador portátil ou aninhado de fonte</value>\n  </data>\n  <data name=\"IncompatibleArgumentsProvided\" xml:space=\"preserve\">\n    <value>Argumentos de linha de comando incompatíveis fornecidos</value>\n  </data>\n  <data name=\"UpgradeArgumentDescription\" xml:space=\"preserve\">\n    <value>Lista somente os pacotes que têm uma atualização disponível</value>\n  </data>\n  <data name=\"UpgradeAvailableForPinned\" xml:space=\"preserve\">\n    <value>Os pacotes a seguir têm uma atualização disponível, mas exigem uma segmentação explícita para atualização:</value>\n    <comment>\"require explicit targeting for upgrade\" means that the package will not be upgraded with all others unless an extra flag is added, or the package is mentioned explicitly</comment>\n  </data>\n  <data name=\"Downloading\" xml:space=\"preserve\">\n    <value>Baixando</value>\n    <comment>Label displayed while downloading an application installer.</comment>\n  </data>\n  <data name=\"NestedInstallerNotSupported\" xml:space=\"preserve\">\n    <value>O tipo de instalador aninhado não é suportado</value>\n  </data>\n  <data name=\"InstallerAbortsTerminal\" xml:space=\"preserve\">\n    <value>Este instalador é conhecido por reiniciar o terminal ou shell</value>\n  </data>\n  <data name=\"InstallerRequiresInstallLocation\" xml:space=\"preserve\">\n    <value>Este pacote exige um local de instalação</value>\n  </data>\n  <data name=\"InstallersAbortTerminal\" xml:space=\"preserve\">\n    <value>Sabe-se que os seguintes instaladores reiniciam o terminal ou o shell:</value>\n  </data>\n  <data name=\"InstallersRequireInstallLocation\" xml:space=\"preserve\">\n    <value>Os seguintes instaladores exigem um local de instalação:</value>\n  </data>\n  <data name=\"PromptForInstallRoot\" xml:space=\"preserve\">\n    <value>Especifique a raiz da instalação:</value>\n  </data>\n  <data name=\"PromptToProceed\" xml:space=\"preserve\">\n    <value>Deseja continuar?</value>\n  </data>\n  <data name=\"ReportIdentityForAgreements\" xml:space=\"preserve\">\n    <value>Contratos para</value>\n    <comment>This will be followed by a package name, and then a list of license agreements</comment>\n  </data>\n  <data name=\"InstallLocationNotProvided\" xml:space=\"preserve\">\n    <value>O local de instalação é exigido pelo pacote, mas não foi fornecido</value>\n  </data>\n  <data name=\"DisableInteractivityArgumentDescription\" xml:space=\"preserve\">\n    <value>Desabilitar os prompts interativos</value>\n    <comment>Description for a command line argument, shown next to it in the help</comment>\n  </data>\n  <data name=\"ConvertInstallFlowToUpgrade\" xml:space=\"preserve\">\n    <value>Foi encontrado um pacote existente já instalado. Tentando atualizar o pacote instalado...</value>\n  </data>\n  <data name=\"ForceArgumentDescription\" xml:space=\"preserve\">\n    <value>Execute diretamente o comando e continue com problemas não relacionados à segurança</value>\n    <comment>Description for a command line argument, shown next to it in the help</comment>\n  </data>\n  <data name=\"PortablePackageAlreadyExists\" xml:space=\"preserve\">\n    <value>Já existe um pacote portátil de uma fonte diferente</value>\n  </data>\n  <data name=\"ExtractArchiveSucceeded\" xml:space=\"preserve\">\n    <value>Arquivo extraído com êxito</value>\n  </data>\n  <data name=\"ExtractingArchive\" xml:space=\"preserve\">\n    <value>Extraindo arquivo...</value>\n  </data>\n  <data name=\"ArchiveFailedMalwareScan\" xml:space=\"preserve\">\n    <value>Malware detectado na verificação de arquivo morto. Para substituir essa verificação, use --ignore-local-archive-malware-scan</value>\n    <comment>{Locked=\"--ignore-local-archive-malware-scan\"}</comment>\n  </data>\n  <data name=\"ArchiveFailedMalwareScanOverridden\" xml:space=\"preserve\">\n    <value>A verificação de arquivo morto detectou malware. Prosseguir devido a --ignore-local-archive-malware-scan</value>\n    <comment>{Locked=\"--ignore-local-archive-malware-scan\"}</comment>\n  </data>\n  <data name=\"NoUpgradeArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignora a atualização se uma versão instalada já existir</value>\n  </data>\n  <data name=\"PackageAlreadyInstalled\" xml:space=\"preserve\">\n    <value>Uma versão do pacote já está instalada. Instalação cancelada.</value>\n  </data>\n  <data name=\"EnableAdminSettingFailed\" xml:space=\"preserve\">\n    <value>Não é possível habilitar {0}. Esta configuração é controlada pela política. Para obter mais informações, contate o administrador do sistema.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"DisableAdminSettingFailed\" xml:space=\"preserve\">\n    <value>Não é possível desabilitar {0}. Esta configuração é controlada pela política. Para obter mais informações, contate o administrador do sistema.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"PinAddCommandLongDescription\" xml:space=\"preserve\">\n    <value>Adiciona um novo marcador. Um marcador pode limitar o Gerenciador de Pacotes do Windows de atualizar um pacote para intervalos específicos de versões ou pode impedir que ele atualize completamente o pacote. Um pacote fixado ainda pode ser atualizado por conta própria e ser atualizado de fora do Gerenciador de Pacotes do Windows. Por padrão, um pacote fixado pode ser atualizado mencionando-o explicitamente no comando \"upgrade\" ou adicionando o sinalizador \"--include-pinned\" a \"winget upgrade --all\".</value>\n    <comment>{Locked{\"'upgrade'\"} Locked{\"--include-pinned\"} Locked{\"winget upgrade --all\"}</comment>\n  </data>\n  <data name=\"PinAddCommandShortDescription\" xml:space=\"preserve\">\n    <value>Adicionar um novo pin</value>\n  </data>\n  <data name=\"PinCommandLongDescription\" xml:space=\"preserve\">\n    <value>Gerencie pinos de pacote com os sub-comandos. Um PIN pode limitar o Gerenciador de Pacotes do Windows de atualizar um pacote para intervalos específicos de versões ou pode impedir que ele atualize totalmente o pacote. Um pacote fixado ainda pode ser atualizado por conta própria e ser atualizado de fora da Gerenciador de Pacotes do Windows.</value>\n  </data>\n  <data name=\"PinCommandShortDescription\" xml:space=\"preserve\">\n    <value>Gerenciar pinos de pacote</value>\n  </data>\n  <data name=\"PinListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Listar todos os pins atuais ou detalhes completos de um PIN específico.</value>\n  </data>\n  <data name=\"PinListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Listar pinos atuais</value>\n  </data>\n  <data name=\"PinRemoveCommandLongDescription\" xml:space=\"preserve\">\n    <value>Remove um pin de pacote específico.</value>\n  </data>\n  <data name=\"PinRemoveCommandShortDescription\" xml:space=\"preserve\">\n    <value>Remover um pin de pacote</value>\n  </data>\n  <data name=\"PinResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>Redefine todos os pinos existentes.</value>\n  </data>\n  <data name=\"PinResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>Redefinir pinos</value>\n  </data>\n  <data name=\"GatedVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>Versão na qual fixar o pacote. O curinga '*' pode ser usado como a última parte da versão</value>\n  </data>\n  <data name=\"PinAddBlockingArgumentDescription\" xml:space=\"preserve\">\n    <value>Bloquear a atualização até que o pin seja removido, impedindo a substituição de argumentos</value>\n  </data>\n  <data name=\"PinInstalledArgumentDescription\" xml:space=\"preserve\">\n    <value>Fixar uma versão instalada específica</value>\n  </data>\n  <data name=\"PinInstalledSource\" xml:space=\"preserve\">\n    <value>Instalado</value>\n    <comment>Value used in a table to indicate that a package comes from the list of packages installed in the machine</comment>\n  </data>\n  <data name=\"SettingsExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Exportar configurações como JSON</value>\n  </data>\n  <data name=\"SettingsExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Exportar configurações</value>\n  </data>\n  <data name=\"UserSettings\" xml:space=\"preserve\">\n    <value>Configurações do Usuário</value>\n    <comment>Label displayed for the file containing the user settings.</comment>\n  </data>\n  <data name=\"SettingsWarningUsingDefault\" xml:space=\"preserve\">\n    <value>Não foi possível carregar o arquivo de configurações. Usando valores padrão.</value>\n  </data>\n  <data name=\"InstalledScopeArgumentDescription\" xml:space=\"preserve\">\n    <value>Selecione o filtro de escopo do pacote instalado (user ou machine)</value>\n    <comment>{Locked=\"user\",\"machine\"} This argument allows the user to select installed packages for just the user or for the entire machine.</comment>\n  </data>\n  <data name=\"PinAdded\" xml:space=\"preserve\">\n    <value>Marcador adicionado com êxito</value>\n  </data>\n  <data name=\"PinAlreadyExists\" xml:space=\"preserve\">\n    <value>Já existe um PIN para o pacote {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that will be replaced by a package name. The message is shown when attempting to add a pin for a package that is already pinned.</comment>\n  </data>\n  <data name=\"PinExistsOverwriting\" xml:space=\"preserve\">\n    <value>Já existe um PIN para o pacote {0}. Substituindo devido ao argumento --force.</value>\n    <comment>{Locked=\"--force\"}{Locked=\"--force\",\"{0}\"} {0} is a placeholder that will be replaced by a package name.</comment>\n  </data>\n  <data name=\"PinExistsUseForceArg\" xml:space=\"preserve\">\n    <value>Já existe um PIN para o pacote {0}. Use o --force para substituí-lo.</value>\n    <comment>{Locked=\"--force\",\"{0}\"} {0} is a placeholder that will be replaced by a package name.</comment>\n  </data>\n  <data name=\"PinResettingAll\" xml:space=\"preserve\">\n    <value>Redefinindo todos os marcadores atuais.</value>\n  </data>\n  <data name=\"PinResetUseForceArg\" xml:space=\"preserve\">\n    <value>Use o argumento --force para redefinir todos os marcadores. Os seguintes marcadores seriam removidos:</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"PinType\" xml:space=\"preserve\">\n    <value>Tipo de marcador</value>\n  </data>\n  <data name=\"PinDoesNotExist\" xml:space=\"preserve\">\n    <value>Não há marcador para o pacote {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that will be replaced by a package name. The message is shown when attempting to delete a pin for a package that is not pinned.</comment>\n  </data>\n  <data name=\"PinNoPinsExist\" xml:space=\"preserve\">\n    <value>Não há martcadores configurados.</value>\n    <comment>Shown when listing or modifying existing pins if there are none.</comment>\n  </data>\n  <data name=\"PinResetSuccessful\" xml:space=\"preserve\">\n    <value>Marcadores redefinidos com êxito</value>\n    <comment>Shown after resetting (deleting) all the pins</comment>\n  </data>\n  <data name=\"PinCannotOpenIndex\" xml:space=\"preserve\">\n    <value>Não é possível abrir o banco de dados do marcador.</value>\n    <comment>Error message for when we cannot open the database containing package pins.</comment>\n  </data>\n  <data name=\"ArgumentForSinglePackageProvidedWithMultipleQueries\" xml:space=\"preserve\">\n    <value>Foi fornecido um argumento que só pode ser usado para um único pacote</value>\n  </data>\n  <data name=\"MultipleExclusiveArgumentsProvided\" xml:space=\"preserve\">\n    <value>Vários argumentos mutuamente exclusivos fornecidos: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message shown when mutually incompatible command line arguments are used. {0} is a placeholder replaced by the arguments that cannot be specified together</comment>\n  </data>\n  <data name=\"DependencyArgumentMissing\" xml:space=\"preserve\">\n    <value>O {0} argumento só pode ser usado com {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message shown when having an argument needs another to be present, but that is missing. {0} and {1} are replaced by the arguments. For example \"Argument --include-unknown can only be used with --upgrade\"</comment>\n  </data>\n  <data name=\"StateDisabled\" xml:space=\"preserve\">\n    <value>Desabilitado</value>\n    <comment>As in enabled/disabled</comment>\n  </data>\n  <data name=\"StateEnabled\" xml:space=\"preserve\">\n    <value>Habilitado</value>\n    <comment>As in enabled/disabled</comment>\n  </data>\n  <data name=\"StateHeader\" xml:space=\"preserve\">\n    <value>Estado</value>\n    <comment>Header for a table listing the state (enabled/disabled) of Group Policies and Settings</comment>\n  </data>\n  <data name=\"MultiQueryArgumentDescription\" xml:space=\"preserve\">\n    <value>A consulta usada para pesquisar um pacote</value>\n  </data>\n  <data name=\"MultiQueryPackageNotFound\" xml:space=\"preserve\">\n    <value>Pacote não encontrado: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches returns no results. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"MultiQuerySearchFoundMultiple\" xml:space=\"preserve\">\n    <value>Vários pacotes encontrados para: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches returns more than one result. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"MultiQuerySearchFailed\" xml:space=\"preserve\">\n    <value>Falha na pesquisa por: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches fails. This message is for generic failures, we have more specific messages for when the search returns no results, or when it returns more than one result. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"UpgradeBlockedByPinCount\" xml:space=\"preserve\">\n    <value>{0} pacote(s) têm um pin que precisa ser removido antes da atualização</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by an integer number of packages with pins that prevent upgrade</comment>\n  </data>\n  <data name=\"UpgradeBlockedByManifest\" xml:space=\"preserve\">\n    <value>O pacote não pode ser atualizado usando winget. Use o método fornecido pelo editor para atualizar este pacote.</value>\n  </data>\n  <data name=\"IncludePinnedArgumentDescription\" xml:space=\"preserve\">\n    <value>Atualizar pacotes mesmo que eles tenham um marcador sem bloqueio</value>\n  </data>\n  <data name=\"IncludePinnedInListArgumentDescription\" xml:space=\"preserve\">\n    <value>Liste os pacotes mesmo que eles tenham um PIN que impeça a atualização. Só pode ser usado com o argumento --upgrade-available</value>\n    <comment>{Locked=\"--upgrade-available\"}</comment>\n  </data>\n  <data name=\"PinRemovedSuccessfully\" xml:space=\"preserve\">\n    <value>Marcador removido com êxito</value>\n  </data>\n  <data name=\"UpgradeIsPinned\" xml:space=\"preserve\">\n    <value>Uma versão mais recente foi encontrada, mas o pacote tem um PIN que impede de atualize-o.</value>\n  </data>\n  <data name=\"PackageIsPinned\" xml:space=\"preserve\">\n    <value>O pacote está fixado e não pode ser atualizado. Use o 'winget pin' para exibir e editar pinos. Alguns tipos de pinos podem ser ignorados com o --include-pinned especificado.</value>\n    <comment>{Locked=\"winget pin\",\"--include-pinned\"} Error shown when we block an upgrade due to the package being pinned</comment>\n  </data>\n  <data name=\"UpgradePinnedByUserCount\" xml:space=\"preserve\">\n    <value>{0} pacotes têm pinos que impedem a atualização. Use o 'winget pin' para exibir e editar pinos. O uso do --include-pinned pode mostrar mais resultados.</value>\n    <comment>{Locked=\"winget pin\",\"--include-pinned\"} {0} is a placeholder replaced by an integer number of packages</comment>\n  </data>\n  <data name=\"ConfigureCommandLongDescription\" xml:space=\"preserve\">\n    <value>Garante que o sistema corresponda ao estado desejado conforme descrito pela configuração fornecida. Pode baixar/executar processadores para atingir o estado desejado. A configuração e os processadores devem ser verificados para garantir que eles sejam confiáveis antes de apá-los.</value>\n  </data>\n  <data name=\"ConfigureCommandShortDescription\" xml:space=\"preserve\">\n    <value>Configura o sistema em um estado desejado</value>\n  </data>\n  <data name=\"ConfigureShowCommandLongDescription\" xml:space=\"preserve\">\n    <value>Mostra detalhes da configuração fornecida. Por padrão, não modificará o sistema, mas algumas opções fará com que os arquivos sejam baixados e/ou carregados.</value>\n  </data>\n  <data name=\"ConfigureShowCommandShortDescription\" xml:space=\"preserve\">\n    <value>Mostra detalhes de uma configuração</value>\n  </data>\n  <data name=\"ConfigureTestCommandLongDescription\" xml:space=\"preserve\">\n    <value>Verifica se o sistema corresponde ao estado desejado conforme descrito pela configuração fornecida. Pode baixar/executar processadores para testar o estado desejado. A configuração e os processadores devem ser verificados para garantir que eles sejam confiáveis antes de executá-los.</value>\n  </data>\n  <data name=\"ConfigureTestCommandShortDescription\" xml:space=\"preserve\">\n    <value>Verifica o sistema em relação a um estado desejado</value>\n  </data>\n  <data name=\"ConfigureValidateCommandLongDescription\" xml:space=\"preserve\">\n    <value>Valida um arquivo de configuração para correção.</value>\n  </data>\n  <data name=\"ConfigureValidateCommandShortDescription\" xml:space=\"preserve\">\n    <value>Valida um arquivo de configuração</value>\n  </data>\n  <data name=\"ConfigurationFieldInvalidType\" xml:space=\"preserve\">\n    <value>O campo \"{0}\" no arquivo de configuração é do tipo errado.</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the field name from the file.</comment>\n  </data>\n  <data name=\"ConfigurationFileArgumentDescription\" xml:space=\"preserve\">\n    <value>O caminho para o arquivo de configuração</value>\n  </data>\n  <data name=\"ConfigurationFileInvalid\" xml:space=\"preserve\">\n    <value>O arquivo de configuração é inválido.</value>\n  </data>\n  <data name=\"ConfigurationFileVersionUnknown\" xml:space=\"preserve\">\n    <value>A versão do arquivo {0} não é conhecida.</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the version of the configuration file.</comment>\n  </data>\n  <data name=\"ConfigurationAcceptWarningArgumentDescription\" xml:space=\"preserve\">\n    <value>Aceita o aviso de configuração, impedindo um prompt interativo</value>\n  </data>\n  <data name=\"ConfigurationApply\" xml:space=\"preserve\">\n    <value>Aplicar</value>\n    <comment>Indicates that this item is used to write state</comment>\n  </data>\n  <data name=\"ConfigurationAssert\" xml:space=\"preserve\">\n    <value>Declarar</value>\n    <comment>Indicates that this item is used to check/assert the state rather than write to it</comment>\n  </data>\n  <data name=\"ConfigurationDependencies\" xml:space=\"preserve\">\n    <value>Dependências:{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying a list of dependencies. {0} is replaced with a space separated list of identifiers referencing other items.</comment>\n  </data>\n  <data name=\"ConfigurationFailedToApply\" xml:space=\"preserve\">\n    <value>Parte da configuração não foi aplicada com êxito.</value>\n  </data>\n  <data name=\"ConfigurationFailedToGetDetails\" xml:space=\"preserve\">\n    <value>Falha ao obter informações detalhadas sobre a configuração.</value>\n  </data>\n  <data name=\"ConfigurationInform\" xml:space=\"preserve\">\n    <value>Informar</value>\n    <comment>Indicates that this item is used to retrieve values for future use rather than writing them</comment>\n  </data>\n  <data name=\"ConfigurationLocal\" xml:space=\"preserve\">\n    <value>Local</value>\n    <comment>Used to indicate that the item is present on the device.</comment>\n  </data>\n  <data name=\"ConfigurationModuleNameOnly\" xml:space=\"preserve\">\n    <value>Módulo: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying a module name. {0} is replaced with the name of the module from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationModuleWithDetails\" xml:space=\"preserve\">\n    <value>Módulo: {0} por {1} [{2}]</value>\n    <comment>{Locked=\"{0}\",\"{1}\",\"{2}\"} Label displaying module information. {0} is replaced by the module name. {1} is replaced by the module author. {2} is replaced by a string indicating the source of the module.</comment>\n  </data>\n  <data name=\"ConfigurationSettings\" xml:space=\"preserve\">\n    <value>Configurações:</value>\n    <comment>Label for the values that are used as inputs for this item when applying state</comment>\n  </data>\n  <data name=\"ConfigurationSuccessfullyApplied\" xml:space=\"preserve\">\n    <value>Configuração aplicada com êxito.</value>\n  </data>\n  <data name=\"ConfigurationUnitSuccessfullyApplied\" xml:space=\"preserve\">\n    <value>Unidade aplicada com êxito.</value>\n  </data>\n  <data name=\"ConfigurationWaitingOnAnother\" xml:space=\"preserve\">\n    <value>Outra configuração está sendo aplicada ao sistema. Esta configuração continuará assim que possível...</value>\n  </data>\n  <data name=\"ConfigurationWarning\" xml:space=\"preserve\">\n    <value>Você é responsável por entender as definições de configuração que você está escolhendo executar. A Microsoft não é responsável pelo arquivo de configuração que você criou ou importou. Essa configuração pode alterar as configurações no Windows, instalar software, alterar configurações de software (incluindo configurações de segurança) e aceitar contratos de usuário para pacotes e serviços de terceiros em seu nome.  Ao executar esse arquivo de configuração, você reconhece que entende e concorda com esses recursos e configurações. Todos os aplicativos instalados são licenciados para você por seus proprietários. A Microsoft não é responsável nem concede licenças a pacotes ou serviços de terceiros.</value>\n    <comment>Legal approved. Do not change without approval.</comment>\n  </data>\n  <data name=\"ConfigurationWarningPromptApply\" xml:space=\"preserve\">\n    <value>Você releou a configuração e gostaria de continuar aplicando-a ao sistema?</value>\n    <comment>PM approved.</comment>\n  </data>\n  <data name=\"ConfigurationFileEmpty\" xml:space=\"preserve\">\n    <value>A configuração está vazia.</value>\n  </data>\n  <data name=\"WindowsFeatureNotFound\" xml:space=\"preserve\">\n    <value>O recurso [{0}] não foi encontrado.</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Windows feature was not found on the system.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeatureOverrideRequired\" xml:space=\"preserve\">\n    <value>Falha ao habilitar as dependências do Recurso do Windows. Para continuar com a instalação, use '--force'.</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"RebootRequiredToEnableWindowsFeatureOverrideRequired\" xml:space=\"preserve\">\n    <value>Reinicialização necessária para habilitar totalmente o(s) Recurso(s) do Windows; para substituir este marcar use '--force'.</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeatureOverridden\" xml:space=\"preserve\">\n    <value>Falha ao habilitar as dependências do Recurso do Windows; continuar devido a --force</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.\n{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"EnablingWindowsFeature\" xml:space=\"preserve\">\n    <value>Habilitando o [{0}]...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to the user regarding which Windows Feature is being enabled.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeature\" xml:space=\"preserve\">\n    <value>Falha ao habilitar o recurso [{0}]: {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"}  An error when enabling a Windows Feature. {0} is a placeholder for the name of the Windows Feature.\n{1} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"RebootRequiredToEnableWindowsFeatureOverridden\" xml:space=\"preserve\">\n    <value>Reinicialização necessária para habilitar totalmente o(s) Recurso(s) do Windows; prosseguir devido a --force</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.</comment>\n  </data>\n  <data name=\"InstallWaitingOnAnother\" xml:space=\"preserve\">\n    <value>Aguardando a conclusão de outra instalação/desinstalação...</value>\n  </data>\n  <data name=\"PinVersion\" xml:space=\"preserve\">\n    <value>Versão fixada</value>\n    <comment>Table header for the version to which a package is pinned; meaning it should not update from that version.</comment>\n  </data>\n  <data name=\"ConfigurationDescriptionWasTruncated\" xml:space=\"preserve\">\n    <value>&lt;See the log file for additional details&gt;</value>\n    <comment>The brackets are intended to make the value stand out from other text which it will follow. Any locale appropriate mechanism that achieves this is acceptable.</comment>\n  </data>\n  <data name=\"ConfigurationGettingDetails\" xml:space=\"preserve\">\n    <value>Recuperando detalhes de configuração</value>\n  </data>\n  <data name=\"ConfigurationInitializing\" xml:space=\"preserve\">\n    <value>Inicializando o sistema de configuração</value>\n  </data>\n  <data name=\"ConfigurationReadingConfigFile\" xml:space=\"preserve\">\n    <value>Lendo arquivo de configuração</value>\n  </data>\n  <data name=\"ConfigurationUnitAssertHadNegativeResult\" xml:space=\"preserve\">\n    <value>O sistema não está no estado desejado declarado pela configuração.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailed\" xml:space=\"preserve\">\n    <value>Esta unidade de configuração falhou por um motivo desconhecido: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedConfigSet\" xml:space=\"preserve\">\n    <value>A unidade de configuração falhou devido à configuração: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringGet\" xml:space=\"preserve\">\n    <value>A unidade de configuração falhou ao tentar obter o estado atual do sistema.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringSet\" xml:space=\"preserve\">\n    <value>A unidade de configuração falhou ao tentar aplicar o estado desejado.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringTest\" xml:space=\"preserve\">\n    <value>A unidade de configuração falhou ao tentar testar o estado atual do sistema.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedInternal\" xml:space=\"preserve\">\n    <value>A unidade de configuração falhou devido a um erro interno: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedPrecondition\" xml:space=\"preserve\">\n    <value>A unidade de configuração falhou devido a uma pré-condição não ser válida: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedSystemState\" xml:space=\"preserve\">\n    <value>A unidade de configuração falhou devido ao estado do sistema: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedUnitProcessing\" xml:space=\"preserve\">\n    <value>A unidade de configuração falhou ao tentar executar: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitHasDuplicateIdentifier\" xml:space=\"preserve\">\n    <value>A configuração contém o identificador \"{0}\" várias vezes.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by the identifier string from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationUnitHasMissingDependency\" xml:space=\"preserve\">\n    <value>A dependência \"{0}\" não foi encontrada na configuração.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by the identifier string from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationUnitManuallySkipped\" xml:space=\"preserve\">\n    <value>Esta unidade de configuração foi ignorada manualmente.</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleConflict\" xml:space=\"preserve\">\n    <value>O módulo para a unidade de configuração está disponível em vários locais com a mesma versão.</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleImportFailed\" xml:space=\"preserve\">\n    <value>Falha ao carregar o módulo para a unidade de configuração.</value>\n  </data>\n  <data name=\"ConfigurationUnitMultipleMatches\" xml:space=\"preserve\">\n    <value>Foram encontradas várias correspondências para a unidade de configuração. Especifique o módulo para selecionar o correto.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotFound\" xml:space=\"preserve\">\n    <value>Não foi possível encontrar a unidade de configuração.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotFoundInModule\" xml:space=\"preserve\">\n    <value>A unidade de configuração não estava no módulo conforme o esperado.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotRunDueToDependency\" xml:space=\"preserve\">\n    <value>Esta unidade de configuração não foi executada porque uma dependência falhou ou não foi executada.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotRunDueToFailedAssert\" xml:space=\"preserve\">\n    <value>Esta unidade de configuração não foi executada porque uma asserção falhou ou era falsa.</value>\n  </data>\n  <data name=\"ConfigurationUnitReturnedInvalidResult\" xml:space=\"preserve\">\n    <value>A unidade de configuração retornou um resultado inesperado durante a execução.</value>\n  </data>\n  <data name=\"ConfigurationUnitSkipped\" xml:space=\"preserve\">\n    <value>Esta unidade de configuração não foi executada por um motivo desconhecido: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationFieldInvalidValue\" xml:space=\"preserve\">\n    <value>O campo \"{0}\" tem um valor inválido: {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} An error in reading a configuration file. {0} is a placeholder replaced by the field name from the file. {1} is a placeholder for the invalid value.</comment>\n  </data>\n  <data name=\"ConfigurationFieldMissing\" xml:space=\"preserve\">\n    <value>O campo \"{0}\" está ausente ou vazio.</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the expected field name from the file.</comment>\n  </data>\n  <data name=\"SeeLineAndColumn\" xml:space=\"preserve\">\n    <value>Consulte a linha {0}, coluna {1} no arquivo.</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Indicates the file location of the error, {0} and {1} are placeholders for numbers of the line and column, respectively.</comment>\n  </data>\n  <data name=\"CancellingOperation\" xml:space=\"preserve\">\n    <value>Cancelando operação...</value>\n  </data>\n  <data name=\"InstallStubPackageDescription\" xml:space=\"preserve\">\n    <value>Instalar o pacote stub para AppInstaller</value>\n  </data>\n  <data name=\"InstallFullPackageDescription\" xml:space=\"preserve\">\n    <value>Instalar o pacote completo do AppInstaller</value>\n  </data>\n  <data name=\"ExtendedFeaturesEnableMessage\" xml:space=\"preserve\">\n    <value>Habilitar recursos avançados. Requer acesso ao repositório.</value>\n  </data>\n  <data name=\"ExtendedFeaturesEnableArgumentError\" xml:space=\"preserve\">\n    <value>A '--enable' e '--disable' não podem ser usadas com outros argumentos.</value>\n    <comment>{Locked=\"--enable\", \"--disable\"}</comment>\n  </data>\n  <data name=\"ExtendedFeaturesEnablingMessage\" xml:space=\"preserve\">\n    <value>Habilitando recursos avançados. Requer acesso ao repositório.</value>\n  </data>\n  <data name=\"ExtendedFeaturesNotEnabledMessage\" xml:space=\"preserve\">\n    <value>Os recursos estendidos não estão habilitados. Execute 'winget configure --enable' para habilite-os.</value>\n    <comment>{Locked=\"winget configure --enable\"}</comment>\n  </data>\n  <data name=\"ExtendedFeaturesEnabledMessage\" xml:space=\"preserve\">\n    <value>Os recursos avançados estão habilitados.</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisableMessage\" xml:space=\"preserve\">\n    <value>Desabilitar recursos avançados. Requer acesso ao repositório.</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisablingMessage\" xml:space=\"preserve\">\n    <value>Desabilitando recursos avançados. Requer acesso ao repositório.</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisabledMessage\" xml:space=\"preserve\">\n    <value>Os recursos avançados estão desabilitados.</value>\n  </data>\n  <data name=\"SkipDependenciesArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignora o processamento de dependências de pacote e recursos do Windows</value>\n  </data>\n  <data name=\"DependenciesSkippedMessage\" xml:space=\"preserve\">\n    <value>Dependências ignoradas.</value>\n  </data>\n  <data name=\"FailedToRefreshPathWarning\" xml:space=\"preserve\">\n    <value>Falha ao atualizar PATH variável para o processo. As próximas instalação que dependem de alterações na PATH variável poderão falhar.</value>\n    <comment>{Locked=\"PATH\"}</comment>\n  </data>\n  <data name=\"ConfigurationFailedToTest\" xml:space=\"preserve\">\n    <value>Algumas das unidades de configuração falharam ao testar seu estado.</value>\n  </data>\n  <data name=\"ConfigurationInDesiredState\" xml:space=\"preserve\">\n    <value>O sistema está no estado de configuração descrito.</value>\n  </data>\n  <data name=\"ConfigurationNoTestRun\" xml:space=\"preserve\">\n    <value>O estado de configuração não foi testado.</value>\n  </data>\n  <data name=\"ConfigurationNotInDesiredState\" xml:space=\"preserve\">\n    <value>O sistema não está no estado de configuração descrito.</value>\n  </data>\n  <data name=\"ConfigurationUnexpectedTestResult\" xml:space=\"preserve\">\n    <value>Resultado de teste inesperado: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message. {0} will be replaced with the unexpected value (a number).</comment>\n  </data>\n  <data name=\"ConfigurationWarningPromptTest\" xml:space=\"preserve\">\n    <value>Você releou a configuração e gostaria de continuar a verificá-la no sistema?</value>\n  </data>\n  <data name=\"ConfigurationFileInvalidYAML\" xml:space=\"preserve\">\n    <value>O arquivo de configuração não é um arquivo YAML válido.</value>\n    <comment>{Locked=\"YAML\"} YAML is a file format name.</comment>\n  </data>\n  <data name=\"ConfigurationUnitIsPartOfDependencyCycle\" xml:space=\"preserve\">\n    <value>Esta unidade de configuração faz parte de um ciclo de dependência.</value>\n  </data>\n  <data name=\"ConfigurationValidationFoundNoIssues\" xml:space=\"preserve\">\n    <value>A validação não encontrou problemas.</value>\n  </data>\n  <data name=\"ConfigurationUnitNeedsPrereleaseWarning\" xml:space=\"preserve\">\n    <value>A unidade de configuração só está disponível como um pré-lançamento, mas não está marcada dessa forma na configuração. Adicione 'allowPrerelease: true' ao 'directives'.</value>\n    <comment>{Locked=\"allowPrerelease: true\",\"directives\"} These are values in the configuration file that are not localized.</comment>\n  </data>\n  <data name=\"ConfigurationUnitNotInCatalogWarning\" xml:space=\"preserve\">\n    <value>A unidade de configuração foi encontrada localmente, mas não pôde ser encontrada em nenhum catálogo configurado. Verifique se ele está presente em qualquer sistema antes de aplicar a configuração.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotPublicWarning\" xml:space=\"preserve\">\n    <value>A unidade de configuração não está disponível publicamente; verifique se qualquer pessoa que usará essa configuração tem acesso a ela.</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleNotProvidedWarning\" xml:space=\"preserve\">\n    <value>O módulo não foi fornecido. A especificação do módulo melhora o desempenho e impede futuras colisões de nomes.</value>\n  </data>\n  <data name=\"DownloadCommandLongDescription\" xml:space=\"preserve\">\n    <value>Baixa o instalador do pacote selecionado, encontrado pesquisando uma fonte configurada ou diretamente de um manifesto. Por padrão, a consulta deve corresponder sem diferenciar maiúsculas de minúsculas à ID, ao nome ou ao moniker do pacote. Outros campos podem ser usados passando a opção apropriada. Por padrão, o comando de download baixará o instalador apropriado para a pasta Downloads do usuário.</value>\n  </data>\n  <data name=\"DownloadCommandShortDescription\" xml:space=\"preserve\">\n    <value>Baixa o instalador de um determinado pacote</value>\n  </data>\n  <data name=\"DownloadDirectoryArgumentDescription\" xml:space=\"preserve\">\n    <value>Diretório para o qual os instaladores são baixados</value>\n  </data>\n  <data name=\"DependenciesFlowDownload\" xml:space=\"preserve\">\n    <value>Baixando dependências:</value>\n  </data>\n  <data name=\"InstallerDownloaded\" xml:space=\"preserve\">\n    <value>Instalador baixado: {0}</value>\n    <comment>{Locked=\"{0}\"} Full path of the downloaded installer.</comment>\n  </data>\n  <data name=\"InstallerTypeArgumentDescription\" xml:space=\"preserve\">\n    <value>Selecione o tipo de instalador</value>\n  </data>\n  <data name=\"InstallerDownloads\" xml:space=\"preserve\">\n    <value>Downloads do Instalador</value>\n  </data>\n  <data name=\"InstallerDownloadCommandProhibited\" xml:space=\"preserve\">\n    <value>O instalador está proibido de ser baixado para instalação offline posterior. </value>\n  </data>\n  <data name=\"ConfigurationAllUsersElevated\" xml:space=\"preserve\">\n    <value>'--module-path allusers' requer privilégios de administrador para ser executado.</value>\n    <comment>{Locked=\"--module-path allusers\"}</comment>\n  </data>\n  <data name=\"ConfigurationModulePath\" xml:space=\"preserve\">\n    <value>Especifica o local no computador local para armazenar módulos. Padrão %LOCALAPPDATA%\\Microsoft\\WinGet\\Configuration\\Modules</value>\n    <comment>{Locked=\"%LOCALAPPDATA%\\Microsoft\\WinGet\\Configuration\\Modules\"}</comment>\n  </data>\n  <data name=\"ConfigurationModulePathArgError\" xml:space=\"preserve\">\n    <value>O valor '--module-path' deve ser 'currentuser', 'allusers', 'default' ou um caminho absoluto.</value>\n    <comment>{Locked=\"{--module-path}, {currentuser}, {allusers}, {default}}</comment>\n  </data>\n  <data name=\"PolicyEnableWinGetConfiguration\" xml:space=\"preserve\">\n    <value>Habilitar as Configurações do Gerenciador de Pacotes do Windows</value>\n  </data>\n  <data name=\"ErrorCommandLongDescription\" xml:space=\"preserve\">\n    <value>Recuperar informações sobre erros. Dado um número, a saída conterá detalhes sobre o erro, incluindo o nome do símbolo se for um erro específico do winget. Dado uma cadeia de caracteres, os erros específicos do winget são pesquisados para esse valor.</value>\n  </data>\n  <data name=\"ErrorCommandShortDescription\" xml:space=\"preserve\">\n    <value>Obter informações sobre erros</value>\n  </data>\n  <data name=\"ErrorInputArgumentDescription\" xml:space=\"preserve\">\n    <value>Um valor a ser pesquisado dentro das informações de erro</value>\n  </data>\n  <data name=\"ErrorNumberIsTooLarge\" xml:space=\"preserve\">\n    <value>O número fornecido é muito grande para ser um HRESULT.</value>\n  </data>\n  <data name=\"UnknownErrorCode\" xml:space=\"preserve\">\n    <value>Código de erro desconhecido</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INTERNAL_ERROR\" xml:space=\"preserve\">\n    <value>ERRO INTERNO</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS\" xml:space=\"preserve\">\n    <value>Argumentos da linha de comando inválidos</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMMAND_FAILED\" xml:space=\"preserve\">\n    <value>Falha na execução do comando</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_FAILED\" xml:space=\"preserve\">\n    <value>Falha na abertura do manifesto</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CTRL_SIGNAL_RECEIVED\" xml:space=\"preserve\">\n    <value>Sinal de cancelamento recebido</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SHELLEXEC_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Falha na execução do ShellExecute</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_MANIFESTVERSION\" xml:space=\"preserve\">\n    <value>Não é possível processar o manifesto. A versão do manifesto é maior do que a suportada. Atualize o cliente.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_FAILED\" xml:space=\"preserve\">\n    <value>Falha no download do instalador</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX\" xml:space=\"preserve\">\n    <value>Não é possível gravar no índice; é uma versão de esquema superior</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INDEX_INTEGRITY_COMPROMISED\" xml:space=\"preserve\">\n    <value>O índice está corrompido</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCES_INVALID\" xml:space=\"preserve\">\n    <value>As informações da origem configurada estão corrompidas</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NAME_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>O nome da origem já está configurado</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_SOURCE_TYPE\" xml:space=\"preserve\">\n    <value>O tipo de fonte é inválido</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_BUNDLE\" xml:space=\"preserve\">\n    <value>O arquivo MSIX é um pacote, não um pacote</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_DATA_MISSING\" xml:space=\"preserve\">\n    <value>Os dados exigidos pela origem estão ausentes</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER\" xml:space=\"preserve\">\n    <value>Nenhum dos instaladores é aplicável ao sistema atual</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_HASH_MISMATCH\" xml:space=\"preserve\">\n    <value>O hash do arquivo do instalador não corresponde ao manifesto</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NAME_DOES_NOT_EXIST\" xml:space=\"preserve\">\n    <value>O nome da origem não existe</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_ARG_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>O local de origem já está configurado com outro nome</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICATIONS_FOUND\" xml:space=\"preserve\">\n    <value>Nenhum pacote encontrado</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_SOURCES_DEFINED\" xml:space=\"preserve\">\n    <value>Nenhuma fonte está configurada</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_APPLICATIONS_FOUND\" xml:space=\"preserve\">\n    <value>Vários pacotes encontrados que correspondem aos critérios</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_MANIFEST_FOUND\" xml:space=\"preserve\">\n    <value>Nenhum manifesto encontrado que corresponda aos critérios</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXTENSION_PUBLIC_FAILED\" xml:space=\"preserve\">\n    <value>Falha ao obter a pasta Pública do pacote de origem</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMMAND_REQUIRES_ADMIN\" xml:space=\"preserve\">\n    <value>O comando requer privilégios de administrador para ser executado</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NOT_SECURE\" xml:space=\"preserve\">\n    <value>O local de origem não é seguro</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>O cliente da Microsoft Store está bloqueado pela política</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_APP_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>O aplicativo da Microsoft Store está bloqueado pela política</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXPERIMENTAL_FEATURE_DISABLED\" xml:space=\"preserve\">\n    <value>O recurso está atualmente em desenvolvimento. Pode ser habilitado usando configurações de winget.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Falha ao instalar o aplicativo da Microsoft Store</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMPLETE_INPUT_BAD\" xml:space=\"preserve\">\n    <value>Falha ao executar a conclusão automática</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED\" xml:space=\"preserve\">\n    <value>Falha ao inicializar o analisador YAML</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_MAPPING_KEY\" xml:space=\"preserve\">\n    <value>Encontrou uma chave YAML inválida</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY\" xml:space=\"preserve\">\n    <value>Encontrou uma chave YAML duplicada</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_OPERATION\" xml:space=\"preserve\">\n    <value>Operação YAML inválida</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_DOC_BUILD_FAILED\" xml:space=\"preserve\">\n    <value>Falha ao criar o documento YAML</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_EMITTER_STATE\" xml:space=\"preserve\">\n    <value>O estado do emissor YAML é inválido</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_DATA\" xml:space=\"preserve\">\n    <value>Dados YAML inválidos</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LIBYAML_ERROR\" xml:space=\"preserve\">\n    <value>Erro da LibYAML</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_WARNING\" xml:space=\"preserve\">\n    <value>A validação do manifesto foi bem-sucedida com um aviso</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_FAILURE\" xml:space=\"preserve\">\n    <value>Falha na validação do manifesto</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_MANIFEST\" xml:space=\"preserve\">\n    <value>O manifesto é inválido</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>Nenhuma atualização aplicável foi encontrada</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPDATE_ALL_HAS_FAILURE\" xml:space=\"preserve\">\n    <value>A atualização do winget --all foi concluída com falhas</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_SECURITY_CHECK_FAILED\" xml:space=\"preserve\">\n    <value>Falha na verificação de segurança do instalador</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_SIZE_MISMATCH\" xml:space=\"preserve\">\n    <value>O tamanho do download não corresponde ao tamanho do conteúdo esperado</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_UNINSTALL_INFO_FOUND\" xml:space=\"preserve\">\n    <value>Comando de desinstalação não encontrado</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXEC_UNINSTALL_COMMAND_FAILED\" xml:space=\"preserve\">\n    <value>Falha na execução do comando de desinstalação</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_BREAK_ITERATOR_ERROR\" xml:space=\"preserve\">\n    <value>Erro no iterador de interrupção de ICU</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_CASEMAP_ERROR\" xml:space=\"preserve\">\n    <value>Erro no mapa de casos da ICU</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_REGEX_ERROR\" xml:space=\"preserve\">\n    <value>Erro de regex ICU</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_IMPORT_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Falha ao instalar um ou mais pacotes importados</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NOT_ALL_PACKAGES_FOUND\" xml:space=\"preserve\">\n    <value>Não foi possível localizar um ou mais pacotes solicitados</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE\" xml:space=\"preserve\">\n    <value>O arquivo Json é inválido</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NOT_REMOTE\" xml:space=\"preserve\">\n    <value>O local de origem não é remoto</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE\" xml:space=\"preserve\">\n    <value>Não há suporte para a origem REST configurada</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA\" xml:space=\"preserve\">\n    <value>Dados inválidos retornados pela origem REST</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>A operação está bloqueada pela Política de Grupo</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_INTERNAL_ERROR\" xml:space=\"preserve\">\n    <value>Erro interno da API Rest</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_URL\" xml:space=\"preserve\">\n    <value>URL de origem REST inválida</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_UNSUPPORTED_MIME_TYPE\" xml:space=\"preserve\">\n    <value>Tipo MIME sem suporte retornado pela API rest</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_VERSION\" xml:space=\"preserve\">\n    <value>Versão inválida do contrato da origem REST</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE\" xml:space=\"preserve\">\n    <value>Os dados de origem estão corrompidos ou adulterados</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_STREAM_READ_FAILURE\" xml:space=\"preserve\">\n    <value>Erro na leitura do fluxo</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>Os contratos de pacotes não foram aceitos</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PROMPT_INPUT_ERROR\" xml:space=\"preserve\">\n    <value>Erro na leitura da entrada no prompt</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST\" xml:space=\"preserve\">\n    <value>Uma ou mais fontes não dão suporte à solicitação de pesquisa</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_ENDPOINT_NOT_FOUND\" xml:space=\"preserve\">\n    <value>O ponto de extremidade da API rest não foi encontrado.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_OPEN_FAILED\" xml:space=\"preserve\">\n    <value>Falha ao abrir a origem.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>Os contratos de origem não foram aceitos</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CUSTOMHEADER_EXCEEDS_MAXLENGTH\" xml:space=\"preserve\">\n    <value>O tamanho do cabeçalho excede o limite permitido de 1024 caracteres. Reduza o tamanho e tente novamente.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MISSING_RESOURCE_FILE\" xml:space=\"preserve\">\n    <value>Arquivo de recurso ausente</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSI_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Falha na execução da instalação MSI</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT\" xml:space=\"preserve\">\n    <value>Os argumentos para o msiexec são inválidos</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FAILED_TO_OPEN_ALL_SOURCES\" xml:space=\"preserve\">\n    <value>Falha ao abrir uma ou mais fontes</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>Falha na validação das dependências</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MISSING_PACKAGE\" xml:space=\"preserve\">\n    <value>Um ou mais pacotes estão ausentes</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_TABLE_COLUMN\" xml:space=\"preserve\">\n    <value>Coluna de tabela inválida</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_NOT_NEWER\" xml:space=\"preserve\">\n    <value>A versão de atualização não é mais recente do que a versão instalada</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_UNKNOWN\" xml:space=\"preserve\">\n    <value>A versão de atualização é desconhecida e a substituição não foi especificada</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_CONVERSION_ERROR\" xml:space=\"preserve\">\n    <value>Erro de conversão de ICU</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Falha ao instalar o pacote portátil</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_REPARSE_POINT_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Não há suporte para pontos de reparo no volume</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_PACKAGE_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>Já existe um pacote portátil de uma fonte diferente.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_SYMLINK_PATH_IS_DIRECTORY\" xml:space=\"preserve\">\n    <value>Não é possível criar o link simbólico. O caminho aponta para um diretório.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_PROHIBITS_ELEVATION\" xml:space=\"preserve\">\n    <value>O instalador não pode ser executado de um contexto de administrador.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Falha ao desinstalar o pacote portátil</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ARP_VERSION_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>Falha ao validar os valores de DisplayVersion em relação ao índice.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_ARGUMENT\" xml:space=\"preserve\">\n    <value>Não há suporte para um ou mais argumentos.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_BIND_WITH_EMBEDDED_NULL\" xml:space=\"preserve\">\n    <value>Os caracteres nulos inseridos não são permitidos no SQLite</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Falha ao localizar o instalador aninhado no arquivo morto.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXTRACT_ARCHIVE_FAILED\" xml:space=\"preserve\">\n    <value>Falha ao extrair o arquivo.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_INVALID_PATH\" xml:space=\"preserve\">\n    <value>Caminho de arquivo relativo inválido para o instalador aninhado fornecido.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PINNED_CERTIFICATE_MISMATCH\" xml:space=\"preserve\">\n    <value>O certificado do servidor não correspondeu a nenhum dos valores esperados.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_LOCATION_REQUIRED\" xml:space=\"preserve\">\n    <value>O local de instalação deve ser fornecido.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ARCHIVE_SCAN_FAILED\" xml:space=\"preserve\">\n    <value>Falha na verificação do arquivo de malware.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>Encontrada pelo menos uma versão do pacote instalado.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PIN_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>Já existe uma marcação para o pacote.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PIN_DOES_NOT_EXIST\" xml:space=\"preserve\">\n    <value>Não há pino para o pacote.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_OPEN_PINNING_INDEX\" xml:space=\"preserve\">\n    <value>Não é possível abrir o banco de dados de pinos.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Falha na instalação de um ou mais aplicativos</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Falha na desinstalação de um ou mais aplicativos</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NOT_ALL_QUERIES_FOUND_SINGLE\" xml:space=\"preserve\">\n    <value>Uma ou mais consultas não retornaram exatamente uma correspondência</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_PINNED\" xml:space=\"preserve\">\n    <value>O pacote tem um PIN que impede a atualização.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB\" xml:space=\"preserve\">\n    <value>O pacote atualmente instalado é o pacote stub</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_APPTERMINATION_RECEIVED\" xml:space=\"preserve\">\n    <value>Sinal de desligamento do aplicativo recebido</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_DEPENDENCIES\" xml:space=\"preserve\">\n    <value>Falha no download das dependências do pacote.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_COMMAND_PROHIBITED\" xml:space=\"preserve\">\n    <value>Falha ao baixar o pacote. O download para instalação offline é proibido.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SERVICE_UNAVAILABLE\" xml:space=\"preserve\">\n    <value>Um serviço necessário está ocupado ou indisponível. Tente novamente mais tarde.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESUME_ID_NOT_FOUND\" xml:space=\"preserve\">\n    <value>O guid fornecido não corresponde a um estado de retomada válido.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CLIENT_VERSION_MISMATCH\" xml:space=\"preserve\">\n    <value>A versão atual do cliente não correspondeu à versão do cliente do estado salvo.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_RESUME_STATE\" xml:space=\"preserve\">\n    <value>Os dados do estado de retomada são inválidos.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_OPEN_CHECKPOINT_INDEX\" xml:space=\"preserve\">\n    <value>Não é possível abrir o banco de dados de pontos de verificação.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESUME_LIMIT_EXCEEDED\" xml:space=\"preserve\">\n    <value>Excedeu o limite máximo de retomadas.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_AUTHENTICATION_INFO\" xml:space=\"preserve\">\n    <value>Informações de autenticação inválidas.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Não há suporte para o método de autenticação.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED\" xml:space=\"preserve\">\n    <value>Falha na autenticação.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_INTERACTIVE_REQUIRED\" xml:space=\"preserve\">\n    <value>Falha na autenticação. É necessária autenticação interativa.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_CANCELLED_BY_USER\" xml:space=\"preserve\">\n    <value>Falha na autenticação. Usuário cancelado.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_INCORRECT_ACCOUNT\" xml:space=\"preserve\">\n    <value>Falha na autenticação. A conta autenticada não é a conta desejada.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE\" xml:space=\"preserve\">\n    <value>O aplicativo está em execução no momento. Saia do aplicativo e tente novamente.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INSTALL_IN_PROGRESS\" xml:space=\"preserve\">\n    <value>Outra instalação já está em andamento. Tente novamente mais tarde.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_FILE_IN_USE\" xml:space=\"preserve\">\n    <value>Um ou mais arquivos estão sendo usados. Saia do aplicativo e tente novamente.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_MISSING_DEPENDENCY\" xml:space=\"preserve\">\n    <value>Este pacote tem uma dependência ausente do sistema.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DISK_FULL\" xml:space=\"preserve\">\n    <value>Não há mais espaço no computador. Libere espaço e tente novamente.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INSUFFICIENT_MEMORY\" xml:space=\"preserve\">\n    <value>Não há memória suficiente disponível para instalar. Fechar outros aplicativos e depois tentar novamente.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_NO_NETWORK\" xml:space=\"preserve\">\n    <value>Este aplicativo requer conectividade com a Internet. Conecte-se a uma rede e tente novamente.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CONTACT_SUPPORT\" xml:space=\"preserve\">\n    <value>Este aplicativo encontrou um erro durante a instalação. Entre em contato com o suporte.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_TO_FINISH\" xml:space=\"preserve\">\n    <value>Reiniciar seu PC para terminar a instalação.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_FOR_INSTALL\" xml:space=\"preserve\">\n    <value>Falha na instalação. Reinicie o computador e tente novamente.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_INITIATED\" xml:space=\"preserve\">\n    <value>Seu PC será reiniciado para terminar a instalação.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CANCELLED_BY_USER\" xml:space=\"preserve\">\n    <value>Você cancelou a instalação.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>Outra versão deste aplicativo já está instalada.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DOWNGRADE\" xml:space=\"preserve\">\n    <value>Uma versão superior deste aplicativo já está instalada.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>As políticas da organização estão impedindo a instalação. Entre em contato com o administrador.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DEPENDENCIES\" xml:space=\"preserve\">\n    <value>Falha ao instalar as dependências do pacote.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE_BY_APPLICATION\" xml:space=\"preserve\">\n    <value>O aplicativo está sendo usado por outro aplicativo no momento.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INVALID_PARAMETER\" xml:space=\"preserve\">\n    <value>Parâmetro inválido.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Não há suporte para o pacote no sistema.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_UPGRADE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>O instalador não oferece suporte à atualização de um pacote existente.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CUSTOM_ERROR\" xml:space=\"preserve\">\n    <value>A instalação falhou com um erro do instalador personalizado.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_ARP_ENTRY_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Não foi possível encontrar a Entrada de Aplicativos e Recursos do pacote.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>O local de instalação não é aplicável.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Não foi possível encontrar o local da instalação.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_HASH_MISMATCH\" xml:space=\"preserve\">\n    <value>O hash do arquivo existente não correspondeu.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Arquivo não encontrado.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK\" xml:space=\"preserve\">\n    <value>O arquivo foi encontrado, mas o hash não foi verificado.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_ACCESS_ERROR\" xml:space=\"preserve\">\n    <value>O arquivo não pôde ser acessado.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE\" xml:space=\"preserve\">\n    <value>O arquivo de configuração é inválido.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_YAML\" xml:space=\"preserve\">\n    <value>A sintaxe YAML é inválida.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_FIELD_TYPE\" xml:space=\"preserve\">\n    <value>Um campo de configuração tem um tipo inválido.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION\" xml:space=\"preserve\">\n    <value>A configuração tem uma versão desconhecida.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_SET_APPLY_FAILED\" xml:space=\"preserve\">\n    <value>Ocorreu um erro ao aplicar a configuração.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER\" xml:space=\"preserve\">\n    <value>A configuração contém um identificador duplicado.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MISSING_DEPENDENCY\" xml:space=\"preserve\">\n    <value>Uma dependência está ausente na configuração.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED\" xml:space=\"preserve\">\n    <value>A configuração tem uma dependência não atendida.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_ASSERTION_FAILED\" xml:space=\"preserve\">\n    <value>Falha na instrução de declaração da unidade de configuração.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MANUALLY_SKIPPED\" xml:space=\"preserve\">\n    <value>A configuração foi ignorada manualmente.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_WARNING_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>O usuário se recusou a continuar a execução.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_SET_DEPENDENCY_CYCLE\" xml:space=\"preserve\">\n    <value>O grafo de dependência contém um ciclo que não pode ser resolvido.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_FIELD_VALUE\" xml:space=\"preserve\">\n    <value>A configuração tem um valor de campo inválido.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MISSING_FIELD\" xml:space=\"preserve\">\n    <value>A configuração está ausente em um campo.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_TEST_FAILED\" xml:space=\"preserve\">\n    <value>Algumas das unidades de configuração falharam ao testar seu estado.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_TEST_NOT_RUN\" xml:space=\"preserve\">\n    <value>O estado de configuração não foi testado.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_NOT_INSTALLED\" xml:space=\"preserve\">\n    <value>A unidade de configuração não foi instalada.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_NOT_FOUND_REPOSITORY\" xml:space=\"preserve\">\n    <value>Não foi possível encontrar a unidade de configuração.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_MULTIPLE_MATCHES\" xml:space=\"preserve\">\n    <value>Foram encontradas várias correspondências para a unidade de configuração. Especifique o módulo para selecionar o correto.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_GET\" xml:space=\"preserve\">\n    <value>A unidade de configuração falhou ao tentar obter o estado atual do sistema.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_TEST\" xml:space=\"preserve\">\n    <value>A unidade de configuração falhou ao tentar testar o estado atual do sistema.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_SET\" xml:space=\"preserve\">\n    <value>A unidade de configuração falhou ao tentar aplicar o estado desejado.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_MODULE_CONFLICT\" xml:space=\"preserve\">\n    <value>O módulo para a unidade de configuração está disponível em vários locais com a mesma versão.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE\" xml:space=\"preserve\">\n    <value>Falha ao carregar o módulo para a unidade de configuração.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_INVALID_RESULT\" xml:space=\"preserve\">\n    <value>A unidade de configuração retornou um resultado inesperado durante a execução.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_SETTING_CONFIG_ROOT\" xml:space=\"preserve\">\n    <value>Uma unidade contém uma configuração que requer a raiz de configuração.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR\" xml:space=\"preserve\">\n    <value>Não há suporte para a operação no processador de configuração.</value>\n  </data>\n  <data name=\"Unavailable\" xml:space=\"preserve\">\n    <value>Não disponível</value>\n  </data>\n  <data name=\"EnableWindowsFeaturesSuccess\" xml:space=\"preserve\">\n    <value>Habilitação bem-sucedida das Dependências de Recursos do Windows</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE_ADMIN\" xml:space=\"preserve\">\n    <value>Falha ao carregar o módulo para a unidade de configuração porque ele requer privilégios de administrador para ser executado.</value>\n  </data>\n  <data name=\"ConfigurationUnitSettingConfigRoot\" xml:space=\"preserve\">\n    <value>Uma unidade contém uma configuração que requer a raiz de configuração.</value>\n  </data>\n  <data name=\"ConfigurationUnitImportModuleAdmin\" xml:space=\"preserve\">\n    <value>Falha ao carregar o módulo para a unidade de configuração porque ele requer privilégios de administrador para ser executado.</value>\n  </data>\n  <data name=\"ResumeCommandLongDescription\" xml:space=\"preserve\">\n    <value>Retoma a execução de um comando salvo anteriormente passando o identificador exclusivo do comando salvo. Isso é usado para retomar um comando executado que pode ter sido encerrado devido a uma reinicialização.</value>\n  </data>\n  <data name=\"ResumeCommandShortDescription\" xml:space=\"preserve\">\n    <value>Retoma a execução de um comando salvo anteriormente.</value>\n  </data>\n  <data name=\"ResumeIdArgumentDescription\" xml:space=\"preserve\">\n    <value>O identificador exclusivo do estado salvo a ser retomado</value>\n  </data>\n  <data name=\"ClientVersionMismatchError\" xml:space=\"preserve\">\n    <value>Não há suporte para retomar o estado de uma versão de cliente diferente: {0}</value>\n    <comment>{Locked= \"{0}\"} Message displayed to inform the user that the client version of the resume state does not match the current client version. {0} is a placeholder for the client version that created the resume state.</comment>\n  </data>\n  <data name=\"ResumeIdNotFoundError\" xml:space=\"preserve\">\n    <value>O estado de retomada não existe: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a guid that does not correspond to a valid saved state. {0} is a placeholder replaced by the provided guid string.</comment>\n  </data>\n  <data name=\"ResumeStateDataNotFoundError\" xml:space=\"preserve\">\n    <value>Nenhum dado encontrado no estado do retomada.</value>\n  </data>\n  <data name=\"CommandDoesNotSupportResumeMessage\" xml:space=\"preserve\">\n    <value>Esse comando não dá suporte à retomada.</value>\n  </data>\n  <data name=\"AllowRebootArgumentDescription\" xml:space=\"preserve\">\n    <value>Permite uma reinicialização, se aplicável</value>\n  </data>\n  <data name=\"InitiatingReboot\" xml:space=\"preserve\">\n    <value>Iniciando a reinicialização para concluir a operação...</value>\n  </data>\n  <data name=\"FailedToInitiateReboot\" xml:space=\"preserve\">\n    <value>Falha ao iniciar uma reinicialização.</value>\n  </data>\n  <data name=\"ResumeLimitExceeded\" xml:space=\"preserve\">\n    <value>A operação retomar excede o limite permitido de {0} retomada(s). Para retomar manualmente, execute o comando '{1}'.</value>\n    <comment>{Locked=\"{0}\", \"{1}\"} {0} is a placeholder that is replaced by an integer number of the number of allowed resumes. {1} is a placeholder for the command to run to perform a manual resume.</comment>\n  </data>\n  <data name=\"IgnoreResumeLimitArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignorar o limite para retomar um estado salvo</value>\n  </data>\n  <data name=\"UriSchemeNotSupported\" xml:space=\"preserve\">\n    <value>Não há suporte para o esquema de URI: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the provided uri is not supported. {0} is a placeholder replaced by the provided uri.</comment>\n  </data>\n  <data name=\"UriNotWellFormed\" xml:space=\"preserve\">\n    <value>O Uri não está bem formado: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the provided uri is not well formed. {0} is a placeholder replaced by the provided uri.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitEmptyContent\" xml:space=\"preserve\">\n    <value>Falha ao analisar {0} conteúdo das configurações da unidade de configuração ou se o conteúdo das configurações está vazio.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder replaced by the input winget configure resource unit type.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitMissingRequiredArg\" xml:space=\"preserve\">\n    <value>{0} unidade de configuração não tem o argumento necessário: {1}</value>\n    <comment>{Locked=\"{0},{1}\"} {0} is a placeholder for the input winget configure resource unit type. {1} is placeholder for the missing arg.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitMissingRecommendedArg\" xml:space=\"preserve\">\n    <value>{0} unidade de configuração não tem o argumento recomendado: {1}</value>\n    <comment>{Locked=\"{0},{1}\"} {0} is a placeholder for the input winget configure resource unit type. {1} is placeholder for the missing arg.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitKnownSourceConfliction\" xml:space=\"preserve\">\n    <value>A unidade de configuração WinGetSource está em conflito com uma fonte conhecida: {0}</value>\n    <comment>{Locked=\"WinGetSource,{0}\"} {0} is a placeholder for the input winget source in the configuration unit settings.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitThirdPartySourceAssertion\" xml:space=\"preserve\">\n    <value>A unidade de configuração WinGetSource asser em uma fonte de terceiros: {0}</value>\n    <comment>{Locked=\"WinGetSource,{0}\"} {0} is a placeholder for the input winget source in the configuration unit settings.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitBothPackageVersionAndUseLatest\" xml:space=\"preserve\">\n    <value>WinGetPackage declara UseLatest e Version. ID do Pacote: {0}</value>\n    <comment>{Locked=\"WinGetPackage,UseLatest,Version,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitThirdPartySourceAssertionForPackage\" xml:space=\"preserve\">\n    <value>A unidade de configuração WinGetPackage asser em um pacote de origem de terceiros. ID do Pacote: {0}; Origem: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitDependencySourceNotConfigured\" xml:space=\"preserve\">\n    <value>O pacote da unidade de configuração WinGetPackage depende de uma fonte de terceiros que não foi configurada anteriormente. ID do Pacote: {0}; Origem: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitDependencySourceNotDeclaredAsDependency\" xml:space=\"preserve\">\n    <value>O pacote da unidade de configuração WinGetPackage depende de uma fonte de terceiros. É recomendável declarar a dependência na seção uni dependsOn. ID do Pacote: {0}; Origem: {1}</value>\n    <comment>{Locked=\"WinGetPackage,dependsOn,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageSourceOpenFailed\" xml:space=\"preserve\">\n    <value>O pacote da unidade de configuração WinGetPackage não pode ser validado. Falha ao abrir o código-fonte. ID do Pacote: {0}; Origem: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageNotFound\" xml:space=\"preserve\">\n    <value>O pacote da unidade de configuração WinGetPackage não pode ser validado. Pacote não encontrado. ID do Pacote: {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageMultipleFound\" xml:space=\"preserve\">\n    <value>O pacote da unidade de configuração WinGetPackage não pode ser validado. Mais de um pacote encontrado. ID do Pacote: {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageVersionNotFound\" xml:space=\"preserve\">\n    <value>O pacote da unidade de configuração WinGetPackage não pode ser validado. Versão do pacote não encontrada. ID do Pacote: {0}; Versão {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitPackageVersionSpecifiedWithOnlyOnePackageVersion\" xml:space=\"preserve\">\n    <value>Pacote da unidade de configuração do WinGetPackage especificado com uma versão específica enquanto apenas uma versão do pacote estiver disponível. ID do pacote: {0}; Versão: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackage\" xml:space=\"preserve\">\n    <value>O pacote da unidade de configuração WinGetPackage não pode ser validado. ID do Pacote: {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"AuthenticationModeArgumentDescription\" xml:space=\"preserve\">\n    <value>Especificar a preferência da janela de autenticação (silent, silentPreferred ou interactive)</value>\n    <comment>{Locked=\"silent\",\"silentPreferred\",\"interactive\"} This argument allows the user to select authentication window popup behavior.</comment>\n  </data>\n  <data name=\"AuthenticationAccountArgumentDescription\" xml:space=\"preserve\">\n    <value>Especifique a conta a ser usada para autenticação</value>\n  </data>\n  <data name=\"SourceAddFailedAuthenticationNotSupported\" xml:space=\"preserve\">\n    <value>Falha ao adicionar origem. Esta winget não dá suporte ao método de autenticação da origem. Tente atualizar para a versão mais winget versão.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"SourceRequiresAuthentication\" xml:space=\"preserve\">\n    <value>A fonte {0} requer autenticação. O prompt de autenticação pode aparecer quando necessário. As informações autenticadas serão compartilhadas com a origem para autorização de acesso.</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"RepairCommandLongDescription\" xml:space=\"preserve\">\n    <value>Repara o pacote selecionado, encontrado pesquisando a lista de pacotes instalados ou diretamente de um manifesto. Por padrão, a consulta deve corresponder sem diferenciar maiúsculas de minúsculas à ID, ao nome ou ao moniker do pacote. Outros campos podem ser usados passando a opção apropriada.</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"RepairCommandShortDescription\" xml:space=\"preserve\">\n    <value>Repara o pacote selecionado</value>\n  </data>\n  <data name=\"NoRepairInfoFound\" xml:space=\"preserve\">\n    <value>O comando de reparo deste pacote não foi encontrado. Entre em contato com o fornecedor do pacote para obter suporte.</value>\n  </data>\n  <data name=\"RepairDifferentInstallTechnology\" xml:space=\"preserve\">\n    <value>A tecnologia do instalador em uso não corresponde à versão instalada no momento.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_REPAIR_INFO_FOUND\" xml:space=\"preserve\">\n    <value>Comando de reparo não encontrado.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_REPAIR_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>A tecnologia do instalador em uso não dá suporte ao reparo.</value>\n  </data>\n  <data name=\"RepairFlowRepairSuccess\" xml:space=\"preserve\">\n    <value>A operação de reparo foi concluída com êxito.</value>\n  </data>\n  <data name=\"RepairAbandoned\" xml:space=\"preserve\">\n    <value>Reparo abandonado</value>\n  </data>\n  <data name=\"RepairFlowStartingPackageRepair\" xml:space=\"preserve\">\n    <value>Início do reparo do pacote...</value>\n  </data>\n  <data name=\"MSStoreRepairFailed\" xml:space=\"preserve\">\n    <value>Falha ao reparar o pacote da Microsoft Store. Código de erro: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Microsoft Store application package fails to repair. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXEC_REPAIR_FAILED\" xml:space=\"preserve\">\n    <value>Falha na operação de reparo.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_REPAIR_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>A operação de reparo não é aplicável.</value>\n  </data>\n  <data name=\"RepairFlowNoMatchingVersion\" xml:space=\"preserve\">\n    <value>Nenhuma versão de pacote correspondente está disponível nas origens configuradas.</value>\n  </data>\n  <data name=\"RepairFlowReturnCodeSystemNotSupported\" xml:space=\"preserve\">\n    <value>A configuração atual do sistema não dá suporte ao reparo deste pacote.</value>\n  </data>\n  <data name=\"RepairOperationNotSupported\" xml:space=\"preserve\">\n    <value>A tecnologia do instalador em uso não dá suporte ao reparo.</value>\n  </data>\n  <data name=\"NoAdminRepairForUserScopePackage\" xml:space=\"preserve\">\n    <value>O pacote instalado para o escopo do usuário não pode ser reparado durante a execução com privilégios de administrador.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED\" xml:space=\"preserve\">\n    <value>Operações de reparo envolvendo privilégios de administrador não são permitidas em pacotes instalados no escopo do usuário.</value>\n  </data>\n  <data name=\"RepairFailedWithCode\" xml:space=\"preserve\">\n    <value>O reparo falhou com o código de saída: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to repair an application package fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SQLITE_CONNECTION_TERMINATED\" xml:space=\"preserve\">\n    <value>A conexão SQLite foi encerrada para evitar danos.</value>\n  </data>\n  <data name=\"UninstallAllVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Desinstale todas as versões</value>\n  </data>\n  <data name=\"TargetVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>A versão para agir</value>\n  </data>\n  <data name=\"UninstallFailedDueToMultipleVersions\" xml:space=\"preserve\">\n    <value>Várias versões deste pacote estão instaladas. Refine a pesquisa, passe o argumento '--version' para selecionar um ou passe o sinalizador '--all-versions' para desinstalar todos eles.</value>\n    <comment>{Locked=\"--version,--all-versions\"}</comment>\n  </data>\n  <data name=\"PolicyEnableProxyCommandLineOptions\" xml:space=\"preserve\">\n    <value>Habilitar Gerenciador de Pacotes do Windows de linha de comando do proxy atual</value>\n    <comment>Describes a Group Policy that can enable the use of the --proxy option to set a proxy</comment>\n  </data>\n  <data name=\"ProxyArgumentDescription\" xml:space=\"preserve\">\n    <value>Definir um proxy a ser usado para esta execução</value>\n  </data>\n  <data name=\"NoProxyArgumentDescription\" xml:space=\"preserve\">\n    <value>Desabilitar o uso de proxy para esta execução</value>\n  </data>\n  <data name=\"ResetAdminSettingFailed\" xml:space=\"preserve\">\n    <value>Não é possível redefinir {0}. Esta configuração é controlada pela política. Para obter mais informações, contate o administrador do sistema.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"ResetAdminSettingSucceeded\" xml:space=\"preserve\">\n    <value>Redefinir configuração de administrador '{0}'.</value>\n    <comment>{Locked=\"{0}\"} Message displayed after the user resets an admin setting to its default value. Reset is used as verb in past tense. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"SetAdminSettingFailed\" xml:space=\"preserve\">\n    <value>Não é possível definir {0}. Esta configuração é controlada pela política. Para obter mais informações, contate o administrador do sistema.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"SetAdminSettingSucceeded\" xml:space=\"preserve\">\n    <value>Defina a configuração de administrador '{0}' para '{1}'.</value>\n    <comment>{Locked=\"{0}\"} Message displayed after the user sets the value of an admin setting. Set is used as a verb in past tense. {0} is a placeholder replaced by the setting name. {1} is a placeholder replaced </comment>\n  </data>\n  <data name=\"SettingNameArgumentDescription\" xml:space=\"preserve\">\n    <value>Nome da configuração a ser modificada</value>\n  </data>\n  <data name=\"SettingValueArgumentDescription\" xml:space=\"preserve\">\n    <value>Valor a ser definido para a configuração.</value>\n  </data>\n  <data name=\"SettingsResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>Redefine uma configuração de administrador para seu valor padrão.</value>\n  </data>\n  <data name=\"SettingsResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>Redefine uma configuração de administrador para seu valor padrão.</value>\n  </data>\n  <data name=\"SettingsSetCommandLongDescription\" xml:space=\"preserve\">\n    <value>Define o valor de uma configuração de administrador.</value>\n  </data>\n  <data name=\"SettingsSetCommandShortDescription\" xml:space=\"preserve\">\n    <value>Define o valor de uma configuração de administrador.</value>\n  </data>\n  <data name=\"SourceExplicitArgumentDescription\" xml:space=\"preserve\">\n    <value>Exclui uma fonte da descoberta, a menos que especificado</value>\n  </data>\n  <data name=\"SourceEditExplicitArgumentDescription\" xml:space=\"preserve\">\n    <value>Exclui uma origem da descoberta (true ou false)</value>\n  </data>\n  <data name=\"SourceListExplicit\" xml:space=\"preserve\">\n    <value>Explícito</value>\n  </data>\n  <data name=\"SourceTrustLevelArgumentDescription\" xml:space=\"preserve\">\n    <value>Nível de confiança da origem (nenhum ou confiável)</value>\n  </data>\n  <data name=\"SourceListTrustLevel\" xml:space=\"preserve\">\n    <value>Nível de Confiança</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DISPLAYCATALOG_API_FAILED\" xml:space=\"preserve\">\n    <value>Falha ao obter o catálogo do pacotes da Microsoft Store.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_DISPLAYCATALOG_PACKAGE\" xml:space=\"preserve\">\n    <value>Nenhum pacote aplicável da Microsoft Store encontrado no catálogo dos pacotes da Microsoft Store.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SFSCLIENT_API_FAILED\" xml:space=\"preserve\">\n    <value>Recuperando informações de download do pacote Microsoft Store.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_SFSCLIENT_PACKAGE\" xml:space=\"preserve\">\n    <value>Nenhum pacote aplicável da Microsoft Store para download.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED\" xml:space=\"preserve\">\n    <value>Falha ao recuperar a licença do pacote da Microsoft Store.</value>\n  </data>\n  <data name=\"MSStoreDownloadNoApplicablePackageFound\" xml:space=\"preserve\">\n    <value>Nenhum pacote aplicável da Microsoft Store encontrado.</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageHashVerified\" xml:space=\"preserve\">\n    <value>Hash do pacote da Microsoft Store verificado com êxito</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageHashMismatch\" xml:space=\"preserve\">\n    <value>Incompatibilidade de hash do pacote da Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloaded\" xml:space=\"preserve\">\n    <value>Pacote da Microsoft Store baixado: {0}</value>\n    <comment>{Locked=\"{0}\"} Full path of the downloaded package.</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadFailed\" xml:space=\"preserve\">\n    <value>Falha no download do pacote da Microsoft Store: {0}</value>\n    <comment>{Locked=\"{0}\"} Package name.</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadSuccess\" xml:space=\"preserve\">\n    <value>Download do pacote da Microsoft Store concluído</value>\n  </data>\n  <data name=\"MSStoreDownloadMainPackages\" xml:space=\"preserve\">\n    <value>Baixando pacotes principais da Microsoft Store...</value>\n  </data>\n  <data name=\"MSStoreDownloadDependencyPackages\" xml:space=\"preserve\">\n    <value>Baixando pacotes de dependências da Microsoft Store...</value>\n  </data>\n  <data name=\"MSStoreDownloadGetDownloadInfo\" xml:space=\"preserve\">\n    <value>Recuperando informações de download de pacotes da Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadGetDownloadInfoFailed\" xml:space=\"preserve\">\n    <value>Falha ao recuperar informações de download do pacote da Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadGetLicense\" xml:space=\"preserve\">\n    <value>Recuperando licença do pacote da Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseSuccess\" xml:space=\"preserve\">\n    <value>Licença do pacote da Microsoft Store salva: {0}</value>\n    <comment>{Locked=\"{0}\"} License file full path.</comment>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseFailed\" xml:space=\"preserve\">\n    <value>Falha ao recuperar a licença do pacote da Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadRenameNotSupported\" xml:space=\"preserve\">\n    <value>O download do pacote da Microsoft Store não dá suporte ao argumento --rename. O pacote da Microsoft Store usará nomes fornecidos pelo catálogo da Microsoft Store.</value>\n    <comment>{Locked=\"--rename\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadAuthenticationNotice\" xml:space=\"preserve\">\n    <value>Microsoft Store download do pacote requer Microsoft Entra de ID. O prompt de autenticação pode aparecer quando necessário. As informações autenticadas serão compartilhadas com serviços Microsoft autorização de acesso. Para Microsoft Store pacote de licenciamento, a Microsoft Entra ID do cliente precisa ser membro do Administrador Global, do Administrador de Usuários ou do Administrador de Licenças.</value>\n    <comment>{Locked=\"Global Administrator,User Administrator,License Administrator\"}</comment>\n  </data>\n  <data name=\"SkipMicrosoftStorePackageLicenseArgumentDescription\" xml:space=\"preserve\">\n    <value>Ignora a recuperação da licença offline do pacote da Microsoft Store</value>\n  </data>\n  <data name=\"PlatformArgumentDescription\" xml:space=\"preserve\">\n    <value>Selecione a plataforma de destino</value>\n  </data>\n  <data name=\"ConfigurationExportAddingToFile\" xml:space=\"preserve\">\n    <value>Adicionando arquivo de configuração: {0}</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportSuccessful\" xml:space=\"preserve\">\n    <value>Exportado com êxito</value>\n  </data>\n  <data name=\"ConfigurationGettingResourceSettings\" xml:space=\"preserve\">\n    <value>Obtendo definições de configuração...</value>\n  </data>\n  <data name=\"ConfigureExportArgumentRequiredError\" xml:space=\"preserve\">\n    <value>Pelo menos --packageId e/ou --module com --resource devem ser fornecidos. Ou use --all para exportar todas as configurações de pacote.</value>\n    <comment>{Locked=\"--packageId,--module, --resource, --all\"}</comment>\n  </data>\n  <data name=\"ConfigureExportArgumentConflictWithAllError\" xml:space=\"preserve\">\n    <value>Os argumentos --packageId, --module e --resource não podem ser usados com --all.</value>\n    <comment>{Locked=\"--packageId,--module, --resource, --all\"}</comment>\n  </data>\n  <data name=\"ConfigureExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Exporta recursos de configuração para um arquivo de configuração. Quando usado com --all, exporta todas as configurações de pacote. Quando usado com --packageId, exporta um recurso WinGetPackage da ID do pacote fornecida. Quando usado com --module e --resource, obtém as configurações do recurso e exporta-o para o arquivo de configuração. Se o arquivo de configuração de saída já existir, anexa os recursos de configuração exportados.</value>\n    <comment>{Locked=\"WinGetPackage,--packageId,--module, --resource\"}</comment>\n  </data>\n  <data name=\"ConfigureExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Exporta recursos de configuração para um arquivo de configuração.</value>\n  </data>\n  <data name=\"ConfigureExportModule\" xml:space=\"preserve\">\n    <value>O módulo do recurso a ser exportado.</value>\n  </data>\n  <data name=\"ConfigureExportPackageId\" xml:space=\"preserve\">\n    <value>O identificador do pacote a ser exportado.</value>\n  </data>\n  <data name=\"ConfigureExportResource\" xml:space=\"preserve\">\n    <value>O recurso de configuração a ser exportado.</value>\n  </data>\n  <data name=\"ConfigureExportAll\" xml:space=\"preserve\">\n    <value>Exporta todas as configurações de pacotes.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_GET_FAILED\" xml:space=\"preserve\">\n    <value>Falha na unidade de configuração ao obter suas propriedades.</value>\n  </data>\n  <data name=\"ConfigurationExportFailed\" xml:space=\"preserve\">\n    <value>Falha na exportação da configuração.</value>\n  </data>\n  <data name=\"ConfigureExportUnitDescription\" xml:space=\"preserve\">\n    <value>Configurar {0}</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigureExportUnitInstallDescription\" xml:space=\"preserve\">\n    <value>Instalar {0}</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationWarningSetViewTruncated\" xml:space=\"preserve\">\n    <value>Alguns dos dados presentes no arquivo de configuração foram truncados para esta saída; inspecione o conteúdo do arquivo para obter o conteúdo completo.</value>\n  </data>\n  <data name=\"ConfigurationWarningValueTruncated\" xml:space=\"preserve\">\n    <value>&lt;este valor foi truncado; inspecione o conteúdo do arquivo para obter o texto completo&gt;</value>\n    <comment>Keep some form of separator like the \"&lt;&gt;\" around the text so that it stands out from the preceding text.</comment>\n  </data>\n  <data name=\"ConfigureListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Mostra os detalhes de alto nível das configurações que foram aplicadas ao sistema. Em seguida, os dados podem ser usados com `configure` para obter mais detalhes.</value>\n    <comment>{Locked=\"`configure`\"}</comment>\n  </data>\n  <data name=\"ConfigureListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Mostra o histórico de configurações</value>\n  </data>\n  <data name=\"ConfigurationHistoryEmpty\" xml:space=\"preserve\">\n    <value>Não há configurações no histórico.</value>\n  </data>\n  <data name=\"ConfigurationHistoryItemArgumentDescription\" xml:space=\"preserve\">\n    <value>Selecionar itens do histórico</value>\n  </data>\n  <data name=\"ConfigurationHistoryItemNotFound\" xml:space=\"preserve\">\n    <value>Não foi encontrada nenhuma configuração única que corresponda aos dados fornecidos. Forneça o nome completo ou parte do identificador que corresponda ineiguamente à configuração desejada.</value>\n  </data>\n  <data name=\"ConfigurationHistoryRemoveArgumentDescription\" xml:space=\"preserve\">\n    <value>Remover o item do histórico</value>\n  </data>\n  <data name=\"ConfigureListFirstApplied\" xml:space=\"preserve\">\n    <value>Primeira Aplicação</value>\n    <comment>Column header for date values indicating when a configuration was first applied to the system.</comment>\n  </data>\n  <data name=\"ConfigureListIdentifier\" xml:space=\"preserve\">\n    <value>Identificador</value>\n  </data>\n  <data name=\"ConfigureListName\" xml:space=\"preserve\">\n    <value>Nome</value>\n  </data>\n  <data name=\"ConfigureListOrigin\" xml:space=\"preserve\">\n    <value>Origem</value>\n  </data>\n  <data name=\"ConfigureListPath\" xml:space=\"preserve\">\n    <value>Caminho</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_HISTORY_ITEM_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Não foi possível encontrar a configuração especificada.</value>\n  </data>\n  <data name=\"ConfigurationSetStateCompleted\" xml:space=\"preserve\">\n    <value>Concluídas</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStateInProgress\" xml:space=\"preserve\">\n    <value>Em andamento</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStatePending\" xml:space=\"preserve\">\n    <value>Pendente</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStateUnknown\" xml:space=\"preserve\">\n    <value>Desconhecido</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationStatusWatchArgumentDescription\" xml:space=\"preserve\">\n    <value>Monitorar o status da configuração.</value>\n    <comment>As in \"to monitor the status of a configuration being applied\".</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateCompleted\" xml:space=\"preserve\">\n    <value>Concluídas</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateInProgress\" xml:space=\"preserve\">\n    <value>Em andamento</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStatePending\" xml:space=\"preserve\">\n    <value>Pendente</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateSkipped\" xml:space=\"preserve\">\n    <value>Ignorado</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateUnknown\" xml:space=\"preserve\">\n    <value>Desconhecido</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigureListApplyBegun\" xml:space=\"preserve\">\n    <value>Aplicação Iniciada</value>\n    <comment>When the configuration application started.</comment>\n  </data>\n  <data name=\"ConfigureListApplyEnded\" xml:space=\"preserve\">\n    <value>Aplicação Encerrada</value>\n    <comment>When the configuration application ended.</comment>\n  </data>\n  <data name=\"ConfigureListResult\" xml:space=\"preserve\">\n    <value>Resultado</value>\n  </data>\n  <data name=\"ConfigureListResultDescription\" xml:space=\"preserve\">\n    <value>Detalhes</value>\n  </data>\n  <data name=\"ConfigureListState\" xml:space=\"preserve\">\n    <value>Estado</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigureListUnit\" xml:space=\"preserve\">\n    <value>Unidade</value>\n  </data>\n  <data name=\"StoreInstall_PackageNotAvailableForCurrentSystem\" xml:space=\"preserve\">\n    <value>O pacote não é compatível com a versão ou plataforma atual do Windows.</value>\n  </data>\n  <data name=\"ConfigurationSuppressPrologueArgumentDescription\" xml:space=\"preserve\">\n    <value>Suprimir a exibição dos detalhes da configuração inicial quando possível</value>\n  </data>\n  <data name=\"MSStoreDownloadMultiplePackagesNotice\" xml:space=\"preserve\">\n    <value>Vários Microsoft Store podem ser baixados direcionando diferentes plataformas e arquiteturas. --platform, --architecture pode ser usado para filtrar os pacotes.</value>\n    <comment>{Locked=\"--platform--architecture\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseForbidden\" xml:space=\"preserve\">\n    <value>Falha ao recuperar a Microsoft Store do pacote. A Microsoft Entra ID do cliente não é membro do Administrador Global, do Administrador de Usuários ou do Administrador de Licenças. Use --skip-license para ignorar a recuperação Microsoft Store de pacote.</value>\n    <comment>{Locked=\"Global Administrator,User Administrator,License Administrator,--skip-license\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadNotSupported\" xml:space=\"preserve\">\n    <value>O Microsoft Store não dá suporte ao download.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SFSCLIENT_PACKAGE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>O Microsoft Store não dá suporte ao download.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED_FORBIDDEN\" xml:space=\"preserve\">\n    <value>Falha ao recuperar a Microsoft Store do pacote. A Microsoft Entra de ID não tem o privilégio necessário.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_PARAMETER_INTEGRITY_BOUNDARY\" xml:space=\"preserve\">\n    <value>O parâmetro não pode ser passado através do limite de integridade.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_ZERO_BYTE_FILE\" xml:space=\"preserve\">\n    <value>Instalador de zero bytes baixado; verifique se a conexão de rede está funcionando corretamente.</value>\n  </data>\n  <data name=\"InstallerZeroByteFile\" xml:space=\"preserve\">\n    <value>Instalador de zero bytes baixado; verifique se a conexão de rede está funcionando corretamente.</value>\n  </data>\n  <data name=\"FontCommandShortDescription\" xml:space=\"preserve\">\n    <value>Gerenciar fontes</value>\n  </data>\n  <data name=\"FontCommandLongDescription\" xml:space=\"preserve\">\n    <value>Gerencie fontes com sub-comandos. As fontes podem ser instaladas, atualizadas ou desinstaladas semelhantes a packages. </value>\n  </data>\n  <data name=\"FontFamily\" xml:space=\"preserve\">\n    <value>Família</value>\n  </data>\n  <data name=\"FontFaces\" xml:space=\"preserve\">\n    <value>Fonte</value>\n    <comment>\"Faces\" represents the typeface of the font family such as 'Bold' or 'Italic'</comment>\n  </data>\n  <data name=\"FontFamilyNameArgumentDescription\" xml:space=\"preserve\">\n    <value>Filtrar resultados por nome da família</value>\n  </data>\n  <data name=\"FontFace\" xml:space=\"preserve\">\n    <value>Rosto</value>\n    <comment>\"Face\" represents the typeface of a font family such as 'Bold' or 'Italic'</comment>\n  </data>\n  <data name=\"FontFilePaths\" xml:space=\"preserve\">\n    <value>Caminhos</value>\n  </data>\n  <data name=\"NoInstalledFontFound\" xml:space=\"preserve\">\n    <value>Nenhuma fonte instalada foi encontrada que corresponda aos critérios de entrada.</value>\n  </data>\n  <data name=\"FontListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Listar fontes instaladas</value>\n  </data>\n  <data name=\"FontListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Listar todas as fontes instaladas, todos os arquivos de fonte ou detalhes completos de uma fonte específica.</value>\n  </data>\n  <data name=\"FontVersion\" xml:space=\"preserve\">\n    <value>Versão</value>\n  </data>\n  <data name=\"ConfigurationModules\" xml:space=\"preserve\">\n    <value>Módulos de Configuração</value>\n    <comment>PowerShell Modules that are used for the Configuration feature</comment>\n  </data>\n  <data name=\"InstallerDownloadRequiresAuthentication\" xml:space=\"preserve\">\n    <value>O instalador do pacote requer autenticação. O prompt de autenticação pode aparecer quando necessário. As informações autenticadas serão compartilhadas com a URL de download do instalador.</value>\n  </data>\n  <data name=\"InstallerDownloadAuthenticationNotSupported\" xml:space=\"preserve\">\n    <value>Falha ao baixar o instalador. Esta winget não dá suporte ao método de autenticação de download do instalador. Tente atualizar para a versão mais winget versão.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"InstallerDownloadAuthenticationFailed\" xml:space=\"preserve\">\n    <value>Falha ao baixar o instalador. Falha na autenticação.</value>\n  </data>\n  <data name=\"ConfigurationProcessorPath\" xml:space=\"preserve\">\n    <value>Especificar o caminho para o processador de configuração</value>\n  </data>\n  <data name=\"DscCommandShortDescription\" xml:space=\"preserve\">\n    <value>Comandos de recurso DSC v3</value>\n    <comment>DSC stands for \"Desired State Configuration\". It should already have a locked translation.</comment>\n  </data>\n  <data name=\"DscCommandLongDescription\" xml:space=\"preserve\">\n    <value>Os sub-comandos aqui implementam recursos Desired State Configuration (DSC) v3 para configurar o winget e os pacotes.</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionGet\" xml:space=\"preserve\">\n    <value>Obter o estado do recurso</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionSet\" xml:space=\"preserve\">\n    <value>Definir o estado do recurso</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionWhatIf\" xml:space=\"preserve\">\n    <value>Descrever as alterações de estado necessárias</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionTest\" xml:space=\"preserve\">\n    <value>Testar o estado do recurso</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionDelete\" xml:space=\"preserve\">\n    <value>Excluir o estado do recurso</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionExport\" xml:space=\"preserve\">\n    <value>Obter todas as instâncias de estado</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionValidate\" xml:space=\"preserve\">\n    <value>Validar o conteúdo do grupo</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionResolve\" xml:space=\"preserve\">\n    <value>Resolver o estado externo</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionAdapter\" xml:space=\"preserve\">\n    <value>Executar o adaptador</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionSchema\" xml:space=\"preserve\">\n    <value>Obter o esquema do recurso</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionManifest\" xml:space=\"preserve\">\n    <value>Obter o manifesto do recurso</value>\n  </data>\n  <data name=\"DscPackageResourceShortDescription\" xml:space=\"preserve\">\n    <value>Gerenciar o estado do pacote</value>\n  </data>\n  <data name=\"DscPackageResourceLongDescription\" xml:space=\"preserve\">\n    <value>Gerencie pacotes por meio do WinGet.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionExist\" xml:space=\"preserve\">\n    <value>Indica se uma instância deve ou não existir.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionInDesiredState\" xml:space=\"preserve\">\n    <value>Indica se uma instância está no estado desejado.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageId\" xml:space=\"preserve\">\n    <value>O identificador do pacote.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageSource\" xml:space=\"preserve\">\n    <value>A origem do pacote.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageVersion\" xml:space=\"preserve\">\n    <value>A versão do pacote.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageMatchOption\" xml:space=\"preserve\">\n    <value>O método para correspondência do identificador com um pacote.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageUseLatest\" xml:space=\"preserve\">\n    <value>Indique que a versão mais recente disponível do pacote deve ser instalada.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageInstallMode\" xml:space=\"preserve\">\n    <value>O modo de instalação a ser usado, se necessário.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageScope\" xml:space=\"preserve\">\n    <value>O escopo de destino do pacote.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionAcceptAgreements\" xml:space=\"preserve\">\n    <value>Indica se os contratos de fontes e pacotes devem ser aceitos.</value>\n  </data>\n  <data name=\"DscUserSettingsFileShortDescription\" xml:space=\"preserve\">\n    <value>Gerenciar o arquivo de configurações do usuário</value>\n  </data>\n  <data name=\"DscUserSettingsFileLongDescription\" xml:space=\"preserve\">\n    <value>Gerencie as configurações de usuário do WinGet.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionUserSettingsFileSettings\" xml:space=\"preserve\">\n    <value>O conteúdo do arquivo JSON de configurações.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionUserSettingsFileAction\" xml:space=\"preserve\">\n    <value>A ação utilizada para aplicar as configurações.</value>\n  </data>\n  <data name=\"CorrelationArgumentDescription\" xml:space=\"preserve\">\n    <value>O valor está registrado para correlação</value>\n  </data>\n  <data name=\"DscSourceResourceShortDescription\" xml:space=\"preserve\">\n    <value>Gerenciar a configuração da origem</value>\n  </data>\n  <data name=\"DscSourceResourceLongDescription\" xml:space=\"preserve\">\n    <value>Gerencie as fontes do WinGet.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceName\" xml:space=\"preserve\">\n    <value>O nome a ser usado para a origem.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceArgument\" xml:space=\"preserve\">\n    <value>O argumento para a origem.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceType\" xml:space=\"preserve\">\n    <value>O tipo da origem.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceTrustLevel\" xml:space=\"preserve\">\n    <value>O nível de confiança da origem.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceExplicit\" xml:space=\"preserve\">\n    <value>Se a origem é incluída quando as chamadas não especificam uma origem.</value>\n  </data>\n  <data name=\"ConfigurationApplyingUnit\" xml:space=\"preserve\">\n    <value>Aplicando a unidade de configuração...</value>\n  </data>\n  <data name=\"ConfigurationExportingUnit\" xml:space=\"preserve\">\n    <value>Exportando a unidade de configuração...</value>\n  </data>\n  <data name=\"ConfigurationGettingUnitProcessors\" xml:space=\"preserve\">\n    <value>Obtendo processadores de unidade de configuração...</value>\n  </data>\n  <data name=\"ConfigurationExportInstallRequiredModule\" xml:space=\"preserve\">\n    <value>Garantir o módulo necessário para exportação [{0}]</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportInstallRequiredModuleFailed\" xml:space=\"preserve\">\n    <value>Falha ao testar ou adquirir o módulo necessário. As configurações relacionadas não serão exportadas.</value>\n  </data>\n  <data name=\"ConfigurationExportUnitStart\" xml:space=\"preserve\">\n    <value>Exportar [{0}]</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportUnitFailed\" xml:space=\"preserve\">\n    <value>Falha ao exportar o recurso.</value>\n  </data>\n  <data name=\"ConfigurationExportFailedToGetUnitProcessors\" xml:space=\"preserve\">\n    <value>Falha ao obter processadores de unidade. As configurações de pacote individuais não serão exportadas.</value>\n  </data>\n  <data name=\"OutputDirectoryArgumentDescription\" xml:space=\"preserve\">\n    <value>Diretório em que os resultados devem ser gravados</value>\n  </data>\n  <data name=\"ConfigurationInstallDscPackage\" xml:space=\"preserve\">\n    <value>Desired State Configuration pacote não encontrado no sistema. Instalando o pacote...</value>\n  </data>\n  <data name=\"ConfigurationInstallDscPackageFailed\" xml:space=\"preserve\">\n    <value>Falha ao instalar Desired State Configuration pacote. Instale o pacote manualmente ou forneça o caminho para dsc.exe por meio --processor-path argumento.</value>\n    <comment>{Locked=\"dsc.exe\",\"--processor-path\"}</comment>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionAdminSettingsSettings\" xml:space=\"preserve\">\n    <value>Um objeto que contém as configurações de administrador e seus valores.</value>\n  </data>\n  <data name=\"DscAdminSettingsResourceShortDescription\" xml:space=\"preserve\">\n    <value>Gerenciar as configurações de administrador</value>\n  </data>\n  <data name=\"DscAdminSettingsResourceLongDescription\" xml:space=\"preserve\">\n    <value>Gerencie as configurações de administrador do WinGet.</value>\n  </data>\n  <data name=\"ResetAllAdminSettingsArgumentDescription\" xml:space=\"preserve\">\n    <value>Redefinindo todas as configurações de administrador</value>\n  </data>\n  <data name=\"ResetAllAdminSettingsSucceeded\" xml:space=\"preserve\">\n    <value>Todas as configurações de administrador foram redefinidas.</value>\n  </data>\n  <data name=\"McpCommandShortDescription\" xml:space=\"preserve\">\n    <value>Informações MCP</value>\n    <comment>MCP stands for Model Context Protocol and should probably remain as-is</comment>\n  </data>\n  <data name=\"McpCommandLongDescription\" xml:space=\"preserve\">\n    <value>Informações do MCP (Protocolo de Contexto de Modelo) do Gerenciador de Pacotes do Windows.</value>\n  </data>\n  <data name=\"McpConfigurationPreamble\" xml:space=\"preserve\">\n    <value>Para configurar manualmente o Gerenciador de Pacotes do Windows MCP com o cliente MCP, use o seguinte fragmento JSON no objeto `servers` servidor:</value>\n    <comment>{Locked=\"`servers`\"}\nMCP stands for Model Context Protocol and should probably remain as-is.\nAn unlocalized JSON fragment will follow on another line.</comment>\n  </data>\n  <data name=\"PolicyEnableMcpServer\" xml:space=\"preserve\">\n    <value>Habilitar o servidor MCP do Gerenciador de pacotes do Windows</value>\n  </data>\n  <data name=\"OSVersionDescription\" xml:space=\"preserve\">\n    <value>Versão do Sistema Operacional de destino</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Falha ao instalar uma ou mais fontes.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Não há suporte para o arquivo de fonte e ele não pode ser instalado.</value>\n  </data>\n  <data name=\"FontFileNotSupported\" xml:space=\"preserve\">\n    <value>Não há suporte para uma ou mais fontes no pacote de fontes e ela não pode ser instalada.</value>\n  </data>\n  <data name=\"FontInstallFailed\" xml:space=\"preserve\">\n    <value>Falha na instalação da fonte; limpando.</value>\n  </data>\n  <data name=\"FontAlreadyInstalled\" xml:space=\"preserve\">\n    <value>Fonte já instalada.</value>\n  </data>\n  <data name=\"FontPackage\" xml:space=\"preserve\">\n    <value>ID do pacote</value>\n  </data>\n  <data name=\"FontWinGetSupported\" xml:space=\"preserve\">\n    <value>WinGet com suporte</value>\n  </data>\n  <data name=\"FontTitle\" xml:space=\"preserve\">\n    <value>Título</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Arquivo da fonte não encontrado.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Falha na desinstalação da fonte. A fonte pode não estar em um bom estado. Tente desinstalar após uma reinicialização.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>Falha na validação da fonte.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_ROLLBACK_FAILED\" xml:space=\"preserve\">\n    <value>Falha na reversão da fonte. A fonte pode não estar em um bom estado. Tente desinstalar após uma reinicialização.</value>\n  </data>\n  <data name=\"FontDetailsArgumentDescription\" xml:space=\"preserve\">\n    <value>Mostrar informações detalhadas do arquivo da fonte.</value>\n  </data>\n  <data name=\"FontValidationFailed\" xml:space=\"preserve\">\n    <value>Falha na validação do pacote de fontes.</value>\n  </data>\n  <data name=\"FontRollbackFailed\" xml:space=\"preserve\">\n    <value>A tentativa de reversão da instalação de fonte com falha não foi bem-sucedida. Uma reinicialização pode ser necessária para desinstalar a fonte com êxito.</value>\n  </data>\n  <data name=\"FontUninstallFailed\" xml:space=\"preserve\">\n    <value>Falha na desinstalação do pacote de fontes. Isso geralmente ocorre devido às fontes que estão sendo usadas pelo sistema ou por um aplicativo. A desinstalação pode ser bem-sucedida após a reinicialização do computador.</value>\n  </data>\n  <data name=\"FontStatusOK\" xml:space=\"preserve\">\n    <value>OK</value>\n    <comment>\"OK\" means the font is in a good healthy state</comment>\n  </data>\n  <data name=\"FontStatusCorrupt\" xml:space=\"preserve\">\n    <value>Corrompido</value>\n    <comment>\"Corrupt\" refers to an install that is in a corrupted or bad state, and needs repair.</comment>\n  </data>\n  <data name=\"FontStatus\" xml:space=\"preserve\">\n    <value>Status</value>\n  </data>\n  <data name=\"FontStatusUnknown\" xml:space=\"preserve\">\n    <value>Desconhecido</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>O pacote de fontes já está instalado.</value>\n  </data>\n  <data name=\"ListDetailsArgumentDescription\" xml:space=\"preserve\">\n    <value>Mostrar informações detalhadas sobre os pacotes instalados</value>\n    <comment>Providing this argument causes the CLI to output additional details about installed application packages.</comment>\n  </data>\n  <data name=\"ShowLabelChannel\" xml:space=\"preserve\">\n    <value>Canal:</value>\n    <comment>Precedes a string value that names the delivery channel for the software package (ex. stable, beta).</comment>\n  </data>\n  <data name=\"ShowListLocalIdentifier\" xml:space=\"preserve\">\n    <value>Identificador Local:</value>\n    <comment>Precedes a value that is the unique identifier for the installed package on the local system.</comment>\n  </data>\n  <data name=\"ShowListPackageFamilyName\" xml:space=\"preserve\">\n    <value>Nome da Família de Pacotes:</value>\n    <comment>Precedes a value that is the APPX/MSIX package family name of the installed package.</comment>\n  </data>\n  <data name=\"ShowListProductCode\" xml:space=\"preserve\">\n    <value>Código do Produto:</value>\n    <comment>Precedes a value that is the Add/Remove Programs identifier in the registry. This is also the Product Code value as defined in MSI installers.</comment>\n  </data>\n  <data name=\"ShowListUpgradeCode\" xml:space=\"preserve\">\n    <value>Código de Atualização:</value>\n    <comment>Precedes a value that is the MSI Upgrade Code for the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledScope\" xml:space=\"preserve\">\n    <value>Escopo da Instalação:</value>\n    <comment>Precedes a value that is the scope of the installation of the package (ex. user, machine).</comment>\n  </data>\n  <data name=\"ShowListInstalledArchitecture\" xml:space=\"preserve\">\n    <value>Arquitetura Instalada:</value>\n    <comment>Precedes a value that is the installed architecture of the package (ex. x86, x64, ARM64).</comment>\n  </data>\n  <data name=\"ShowListInstalledLocale\" xml:space=\"preserve\">\n    <value>Localidade da Instalação:</value>\n    <comment>Precedes a value that is the locale of the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledLocation\" xml:space=\"preserve\">\n    <value>Local de Instalação:</value>\n    <comment>Precedes a value that is the directory path to the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledSource\" xml:space=\"preserve\">\n    <value>Fonte de Origem:</value>\n    <comment>Precedes a value that names the package source where the installed package originated from.</comment>\n  </data>\n  <data name=\"ShowListAvailableUpgrades\" xml:space=\"preserve\">\n    <value>Atualizações Disponíveis:</value>\n    <comment>Precedes a list of package upgrades available for the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstallerCategory\" xml:space=\"preserve\">\n    <value>Categoria do Instalador:</value>\n    <comment>Precedes a value that indicates the category of the installer for the installed package (ex. exe, msi, msix).</comment>\n  </data>\n  <data name=\"SourceEditOldValue\" xml:space=\"preserve\">\n    <value>Valor Antigo</value>\n    <comment>Column title for listing edit changes.</comment>\n  </data>\n  <data name=\"SourceEditNewValue\" xml:space=\"preserve\">\n    <value>Novo Valor</value>\n    <comment>Column title for listing the new value.</comment>\n  </data>\n</root>"
  },
  {
    "path": "Localization/Resources/ru-RU/Resources.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "Localization/Resources/ru-RU/winget.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"AdjoinedNotFlagError\" xml:space=\"preserve\">\n    <value>Присоединенный псевдоним не является флагом: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an adjoined alias that is not a flag argument. {0} is a placeholder replaced by the user input argument (e.g. '-ab').</comment>\n  </data>\n  <data name=\"AdjoinedNotFoundError\" xml:space=\"preserve\">\n    <value>Псевдоним присоединенного флага не найден: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an adjoined flag alias argument that was not found. {0} is a placeholder replaced by the user input argument (e.g. '-ab').</comment>\n  </data>\n  <data name=\"AvailableArguments\" xml:space=\"preserve\">\n    <value>Доступны следующие аргументы:</value>\n    <comment>Message displayed to inform the user about the available command line arguments.</comment>\n  </data>\n  <data name=\"AvailableCommandAliases\" xml:space=\"preserve\">\n    <value>Доступны следующие псевдонимы команд.</value>\n    <comment>Message displayed to inform the user about the available command line alias arguments.</comment>\n  </data>\n  <data name=\"AvailableCommands\" xml:space=\"preserve\">\n    <value>Применимы следующие команды:</value>\n    <comment>Title displayed to inform the user about the available commands.</comment>\n  </data>\n  <data name=\"AvailableHeader\" xml:space=\"preserve\">\n    <value>Доступно</value>\n    <comment>As in \"a new version is available to upgrade to\".</comment>\n  </data>\n  <data name=\"AvailableOptions\" xml:space=\"preserve\">\n    <value>Доступны следующие опции:</value>\n    <comment>Message displayed to inform the user about the available options.</comment>\n  </data>\n  <data name=\"AvailableSubcommands\" xml:space=\"preserve\">\n    <value>Доступны следующие подкоманды:</value>\n    <comment>Message displayed to inform the user about the available nested commands that run in context of the selected command.</comment>\n  </data>\n  <data name=\"AvailableUpgrades\" xml:space=\"preserve\">\n    <value>Доступны обновления: {0}.</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about available package upgrades. {0} is a placeholder replaced by the number of package upgrades.</comment>\n  </data>\n  <data name=\"ChannelArgumentDescription\" xml:space=\"preserve\">\n    <value>Использовать указанный канал; по умолчанию предназначено для широкой аудитории</value>\n  </data>\n  <data name=\"Command\" xml:space=\"preserve\">\n    <value>команда</value>\n    <comment>Label displayed for a command to give the software.</comment>\n  </data>\n  <data name=\"CommandArgumentDescription\" xml:space=\"preserve\">\n    <value>Фильтровать результаты по команде</value>\n    <comment>Description message displayed to inform the user about filtering the search results by a package command.</comment>\n  </data>\n  <data name=\"CommandLineArgumentDescription\" xml:space=\"preserve\">\n    <value>Полная командная строка для завершения</value>\n  </data>\n  <data name=\"CommandRequiresAdmin\" xml:space=\"preserve\">\n    <value>Для выполнения этой команды требуются права администратора.</value>\n  </data>\n  <data name=\"CompleteCommandLongDescription\" xml:space=\"preserve\">\n    <value>Эту команду можно использовать для запроса завершения контекстной командной строки. Передается командная строка, положение курсора и слово для завершения. Выходные данные представляют собой набор потенциальных значений, основанных на входных данных, по одному возможному значению на строку.</value>\n  </data>\n  <data name=\"CompleteCommandShortDescription\" xml:space=\"preserve\">\n    <value>Разрешает завершение контекстной командной строки</value>\n  </data>\n  <data name=\"CountArgumentDescription\" xml:space=\"preserve\">\n    <value>Показать не более указанного числа результатов (от 1 до 1000)</value>\n  </data>\n  <data name=\"Done\" xml:space=\"preserve\">\n    <value>Готово</value>\n    <comment>Label displayed when an operation completes or is done executing.</comment>\n  </data>\n  <data name=\"ExactArgumentDescription\" xml:space=\"preserve\">\n    <value>Поиск пакета по точному совпадению</value>\n    <comment>Description message displayed to inform the user about finding an application package using an exact matching criteria.</comment>\n  </data>\n  <data name=\"ExperimentalArgumentDescription\" xml:space=\"preserve\">\n    <value>Экспериментальный аргумент для демонстрации</value>\n  </data>\n  <data name=\"ExperimentalCommandLongDescription\" xml:space=\"preserve\">\n    <value>Эта команда является примером реализации экспериментального компонента. Чтобы включить его, перейдите к файлу \"winget settings\" и включите компоненты experimentalCmd или experimentalArg.</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"ExperimentalCommandShortDescription\" xml:space=\"preserve\">\n    <value>Пример экспериментального компонента</value>\n  </data>\n  <data name=\"ExtraPositionalError\" xml:space=\"preserve\">\n    <value>Найден позиционный аргумент, когда не ожидалось: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an extra positional argument when none was expected. {0} is a placeholder replaced by the user's extra argument input.</comment>\n  </data>\n  <data name=\"FeatureDisabledMessage\" xml:space=\"preserve\">\n    <value>Этот компонент находится в процессе разработки. В будущем он может быть существенно изменен или полностью удален. Чтобы включить его, измените параметры (\"winget settings\"), чтобы включить экспериментальный компонент: \"{0}\"</value>\n    <comment>{Locked=\"winget settings\",\"{0}\"}. Error message displayed when the user uses an experimental feature that is disabled. {0} is a placeholder replaced by the experimental feature name.</comment>\n  </data>\n  <data name=\"FeaturesCommandLongDescription\" xml:space=\"preserve\">\n    <value>Показывает состояние экспериментальных компонентов. Экспериментальные компоненты можно включить с помощью команды \"winget settings\".</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"FeaturesCommandShortDescription\" xml:space=\"preserve\">\n    <value>Показывает состояние экспериментальных компонентов</value>\n  </data>\n  <data name=\"FeaturesDisabled\" xml:space=\"preserve\">\n    <value>Отключено</value>\n  </data>\n  <data name=\"FeaturesEnabled\" xml:space=\"preserve\">\n    <value>Включено</value>\n  </data>\n  <data name=\"FeaturesFeature\" xml:space=\"preserve\">\n    <value>Компонент</value>\n  </data>\n  <data name=\"FeaturesLink\" xml:space=\"preserve\">\n    <value>Ссылка</value>\n  </data>\n  <data name=\"FeaturesMessage\" xml:space=\"preserve\">\n    <value>Следующие экспериментальные компоненты находятся в процессе разработки.\nИх можно настроить с помощью файла параметров \"winget settings\".</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"FeaturesProperty\" xml:space=\"preserve\">\n    <value>Свойство</value>\n  </data>\n  <data name=\"FeaturesStatus\" xml:space=\"preserve\">\n    <value>Состояние</value>\n  </data>\n  <data name=\"FileArgumentDescription\" xml:space=\"preserve\">\n    <value>Файл для хэширования</value>\n  </data>\n  <data name=\"FlagContainAdjoinedError\" xml:space=\"preserve\">\n    <value>Аргумент флага не может содержать присоединенное значение: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a flag argument containing an unexpected adjoined value. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"HashCommandLongDescription\" xml:space=\"preserve\">\n    <value>Вычисляет хэш локального файла, подходящий для записи в манифест. Он также может вычислить хэш файла подписи для MSIX-пакета, чтобы разрешить потоковые установки.</value>\n  </data>\n  <data name=\"HashCommandShortDescription\" xml:space=\"preserve\">\n    <value>Вспомогательное приложение для хэширования файлов установщика</value>\n  </data>\n  <data name=\"HelpArgumentDescription\" xml:space=\"preserve\">\n    <value>Отображает справку по выбранной команде</value>\n  </data>\n  <data name=\"HelpForDetails\" xml:space=\"preserve\">\n    <value>Для более подробной информации о конкретной команде передайте ей аргумент справки.</value>\n  </data>\n  <data name=\"HelpLinkPreamble\" xml:space=\"preserve\">\n    <value>Дополнительную справку см. по адресу: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a link where they can learn more about the subject context. {0} is a placeholder replaced by a website address.</comment>\n  </data>\n  <data name=\"IdArgumentDescription\" xml:space=\"preserve\">\n    <value>Фильтровать результаты по идентификатору</value>\n  </data>\n  <data name=\"IgnoreWarningsArgumentDescription\" xml:space=\"preserve\">\n    <value>Подавляет вывод предупреждений</value>\n  </data>\n  <data name=\"InstallationDisclaimer1\" xml:space=\"preserve\">\n    <value>Лицензия на это приложение предоставлена вам владельцем.</value>\n  </data>\n  <data name=\"InstallationDisclaimer2\" xml:space=\"preserve\">\n    <value>Корпорация Майкрософт не несет ответственность за сторонние пакеты и не предоставляет для них никакие лицензии.</value>\n  </data>\n  <data name=\"InstallationDisclaimerMSStore\" xml:space=\"preserve\">\n    <value>Этот пакет предоставляется через Microsoft Store. Программе winget может потребоваться получить пакет в Microsoft Store от имени текущего пользователя.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"InstallCommandLongDescription\" xml:space=\"preserve\">\n    <value>Устанавливает выбранный пакет, найденный путем поиска в настроенном источнике или непосредственно из манифеста. По умолчанию запрос должен сравнить id, name или moniker пакета (без учета регистра). Можно использовать и другие поля, указав соответствующий параметр. По умолчанию команда установки проверяет состояние установки пакета и, если применимо, пытается выполнить обновление. Переопределите с помощью параметра --force для прямой установки.</value>\n    <comment>{Locked=\"--force\"}; id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"InstallCommandShortDescription\" xml:space=\"preserve\">\n    <value>Установка указанного пакета</value>\n  </data>\n  <data name=\"InstallerHashMismatchAdminBlock\" xml:space=\"preserve\">\n    <value>Хэш установщика не совпадает. Невозможно переопределить этот параметр при запуске от имени администратора.</value>\n  </data>\n  <data name=\"InstallerHashMismatchOverridden\" xml:space=\"preserve\">\n    <value>Хеш установщика не совпадает. Продолжение работы, так как указан параметр --ignore-security-hash</value>\n    <comment>{Locked=\"--ignore-security-hash\"}</comment>\n  </data>\n  <data name=\"InstallerHashMismatchOverrideRequired\" xml:space=\"preserve\">\n    <value>Хэш установщика не совпадает. Чтобы переопределить это ограничение, используйте параметр --ignore-security-hash</value>\n    <comment>{Locked=\"--ignore-security-hash\"}</comment>\n  </data>\n  <data name=\"InstallerHashVerified\" xml:space=\"preserve\">\n    <value>Хэш установщика успешно проверен</value>\n  </data>\n  <data name=\"InstallFlowInstallSuccess\" xml:space=\"preserve\">\n    <value>Успешно установлено</value>\n  </data>\n  <data name=\"InstallFlowStartingPackageInstall\" xml:space=\"preserve\">\n    <value>Запуск установки пакета...</value>\n  </data>\n  <data name=\"HashOverrideArgumentDescription\" xml:space=\"preserve\">\n    <value>Игнорировать ошибку проверки хэша установщика</value>\n  </data>\n  <data name=\"IgnoreLocalArchiveMalwareScanArgumentDescription\" xml:space=\"preserve\">\n    <value>Игнорирование проверки вредоносных программ, выполняемое как часть установки пакета архивного типа из локального манифеста.</value>\n  </data>\n  <data name=\"InteractiveArgumentDescription\" xml:space=\"preserve\">\n    <value>Запросить интерактивную установку; может потребоваться ввод данных пользователем</value>\n  </data>\n  <data name=\"InvalidAliasError\" xml:space=\"preserve\">\n    <value>Псевдоним аргумента не был распознан для текущей команды: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a command line argument alias that was not recognized for a selected command. {0} is a placeholder replaced by the user's argument alias input (e.g. '-a').</comment>\n  </data>\n  <data name=\"InvalidArgumentSpecifierError\" xml:space=\"preserve\">\n    <value>Неверный указатель аргумента: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an invalid argument specifier. {0} is a placeholder replaced by an argument specifier (e.g. '-').</comment>\n  </data>\n  <data name=\"InvalidNameError\" xml:space=\"preserve\">\n    <value>Имя аргумента не распознано для текущей команды: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an unrecognized command line argument name for the selected command. {0} is a placeholder replaced by the user's argument name input (e.g. '--example').</comment>\n  </data>\n  <data name=\"KeyDirectoriesHeader\" xml:space=\"preserve\">\n    <value>Каталоги WinGet</value>\n    <comment>Header for a table detailing the directories Winget uses for key operations like logging and portable installs</comment>\n  </data>\n  <data name=\"LocaleArgumentDescription\" xml:space=\"preserve\">\n    <value>Используемый языковой стандарт (формат BCP47)</value>\n    <comment>{Locked=\"BCP47\"}</comment>\n  </data>\n  <data name=\"LicenseAgreement\" xml:space=\"preserve\">\n    <value>Лицензионное соглашение</value>\n  </data>\n  <data name=\"Links\" xml:space=\"preserve\">\n    <value>Ссылки</value>\n    <comment>Links to different webpages</comment>\n  </data>\n  <data name=\"ListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Команда list отображает пакеты, установленные в системе, а также доступность обновления. Для фильтрации выходных данных можно указать дополнительные параметры по аналогии с командой search.</value>\n    <comment>{Locked=\"list\",\"search\"}</comment>\n  </data>\n  <data name=\"ListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Отображать установленные пакеты</value>\n  </data>\n  <data name=\"LocationArgumentDescription\" xml:space=\"preserve\">\n    <value>Место для установки (если поддерживается)</value>\n  </data>\n  <data name=\"LogArgumentDescription\" xml:space=\"preserve\">\n    <value>Расположение журнала (если поддерживается)</value>\n  </data>\n  <data name=\"MainCopyrightNotice\" xml:space=\"preserve\">\n    <value>(с) Корпорация Майкрософт (Microsoft Corporation). Все права защищены.</value>\n  </data>\n  <data name=\"MainHomepage\" xml:space=\"preserve\">\n    <value>Домашняя страница</value>\n    <comment>The primary webpage for the software</comment>\n  </data>\n  <data name=\"ManifestArgumentDescription\" xml:space=\"preserve\">\n    <value>Путь к манифесту пакета</value>\n  </data>\n  <data name=\"ManifestValidationFail\" xml:space=\"preserve\">\n    <value>Ошибка проверки манифеста.</value>\n  </data>\n  <data name=\"ManifestValidationSuccess\" xml:space=\"preserve\">\n    <value>Проверка манифеста выполнена успешно.</value>\n  </data>\n  <data name=\"ManifestValidationWarning\" xml:space=\"preserve\">\n    <value>Проверка манифеста выполнена с предупреждениями.</value>\n  </data>\n  <data name=\"MissingArgumentError\" xml:space=\"preserve\">\n    <value>Требуется значение аргумента, но ничего не найдено: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user does not provide a required command line argument value. {0} is a placeholder replaced by the argument name.</comment>\n  </data>\n  <data name=\"MonikerArgumentDescription\" xml:space=\"preserve\">\n    <value>Фильтровать результаты по моникеру</value>\n  </data>\n  <data name=\"MsixArgumentDescription\" xml:space=\"preserve\">\n    <value>Входной файл будет обрабатываться как формат MSIX; при наличии подписи будет предоставлен хэш подписи</value>\n  </data>\n  <data name=\"MsixSignatureHashFailed\" xml:space=\"preserve\">\n    <value>Не удалось вычислить хэш подписи MSIX.</value>\n  </data>\n  <data name=\"MSStoreAppBlocked\" xml:space=\"preserve\">\n    <value>Не удалось установить или обновить пакет Microsoft Store, так как конкретное приложение заблокировано политикой</value>\n  </data>\n  <data name=\"MSStoreInstallOrUpdateFailed\" xml:space=\"preserve\">\n    <value>Не удалось установить или обновить пакет Microsoft Store. Код ошибки: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Microsoft Store application package fails to install or upgrade. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"MSStoreStoreClientBlocked\" xml:space=\"preserve\">\n    <value>Не удалось установить или обновить пакет Microsoft Store, так как клиент Microsoft Store заблокирован политикой</value>\n  </data>\n  <data name=\"MSStoreInstallTryGetEntitlement\" xml:space=\"preserve\">\n    <value>Проверка/запрос сведений о получении пакета...</value>\n  </data>\n  <data name=\"MultipleInstalledPackagesFound\" xml:space=\"preserve\">\n    <value>Обнаружено несколько установленных пакетов, соответствующих введенным условиям. Уточните условия.</value>\n  </data>\n  <data name=\"MultiplePackagesFound\" xml:space=\"preserve\">\n    <value>Обнаружено несколько пакетов, совпадающих с введенными условиями. Уточните условия.</value>\n  </data>\n  <data name=\"NameArgumentDescription\" xml:space=\"preserve\">\n    <value>Фильтровать результаты по имени</value>\n  </data>\n  <data name=\"NoApplicableInstallers\" xml:space=\"preserve\">\n    <value>Применимый установщик не найден. Дополнительные сведения см. в журналах.</value>\n  </data>\n  <data name=\"NoExperimentalFeaturesMessage\" xml:space=\"preserve\">\n    <value>В настоящее время нет доступных экспериментальных компонентов. </value>\n  </data>\n  <data name=\"NoInstalledPackageFound\" xml:space=\"preserve\">\n    <value>Не найдены установленные пакеты, соответствующие введенным условиям.</value>\n  </data>\n  <data name=\"NoPackageFound\" xml:space=\"preserve\">\n    <value>Не найдены пакеты, совпадающие с введенными условиями.</value>\n  </data>\n  <data name=\"NoVTArgumentDescription\" xml:space=\"preserve\">\n    <value>Отключает дисплей VirtualTerminal</value>\n    <comment>{Locked=\"VirtualTerminal\"}</comment>\n  </data>\n  <data name=\"OpenLogsArgumentDescription\" xml:space=\"preserve\">\n    <value>Открыть расположение журналов по умолчанию</value>\n  </data>\n  <data name=\"Options\" xml:space=\"preserve\">\n    <value>параметры</value>\n    <comment>Options to change how a command works</comment>\n  </data>\n  <data name=\"OverrideArgumentDescription\" xml:space=\"preserve\">\n    <value>Переопределить аргументы, передаваемые установщику</value>\n  </data>\n  <data name=\"Package\" xml:space=\"preserve\">\n    <value>Пакет: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for a software package. {0} is a placeholder replaced by the software package name.</comment>\n  </data>\n  <data name=\"PendingWorkError\" xml:space=\"preserve\">\n    <value>К сожалению, мы забыли сделать это...</value>\n  </data>\n  <data name=\"PositionArgumentDescription\" xml:space=\"preserve\">\n    <value>Положение курсора в командной строке</value>\n  </data>\n  <data name=\"PrivacyStatement\" xml:space=\"preserve\">\n    <value>Заявление о конфиденциальности</value>\n  </data>\n  <data name=\"QueryArgumentDescription\" xml:space=\"preserve\">\n    <value>Запрос, используемый для поиска пакета</value>\n  </data>\n  <data name=\"RainbowArgumentDescription\" xml:space=\"preserve\">\n    <value>Отображение хода выполнения в виде радуги цветов</value>\n  </data>\n  <data name=\"RequiredArgError\" xml:space=\"preserve\">\n    <value>Обязательный аргумент не указан: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user does not provide a required command line argument. {0} is a placeholder replaced by an argument name.</comment>\n  </data>\n  <data name=\"RetroArgumentDescription\" xml:space=\"preserve\">\n    <value>Отображение хода выполнения в виде стандартного цвета</value>\n  </data>\n  <data name=\"SearchCommandLongDescription\" xml:space=\"preserve\">\n    <value>Поиск пакетов в настроенных источниках.</value>\n  </data>\n  <data name=\"SearchCommandShortDescription\" xml:space=\"preserve\">\n    <value>Поиск и отображение базовых сведений о пакетах</value>\n  </data>\n  <data name=\"SearchId\" xml:space=\"preserve\">\n    <value>ИД</value>\n    <comment>Abbreviation of Identifier.</comment>\n  </data>\n  <data name=\"SearchMatch\" xml:space=\"preserve\">\n    <value>Совпадение</value>\n  </data>\n  <data name=\"SearchName\" xml:space=\"preserve\">\n    <value>Имя</value>\n  </data>\n  <data name=\"SearchSource\" xml:space=\"preserve\">\n    <value>Источник</value>\n  </data>\n  <data name=\"SearchTruncated\" xml:space=\"preserve\">\n    <value>дополнительные записи усечены из-за ограничения количества результатов</value>\n  </data>\n  <data name=\"SearchVersion\" xml:space=\"preserve\">\n    <value>Версия</value>\n  </data>\n  <data name=\"SettingLoadFailure\" xml:space=\"preserve\">\n    <value>Обнаружены следующие ошибки при проверке параметров:</value>\n  </data>\n  <data name=\"SettingsCommandLongDescription\" xml:space=\"preserve\">\n    <value>Открытие параметров в текстовом редакторе JSON по умолчанию. Если редактор не настроен, параметры будут открыты в Блокноте. Доступные параметры см. по адресу https://aka.ms/winget-settings С помощью этой команды также можно настраивать параметры администратора, указав аргумент --enable или --disable.</value>\n    <comment>{Locked=\"--enable\"} {Locked=\"--disable\"}</comment>\n  </data>\n  <data name=\"SettingsCommandShortDescription\" xml:space=\"preserve\">\n    <value>Открыть параметры или настроить параметры администратора</value>\n  </data>\n  <data name=\"SettingsWarnings\" xml:space=\"preserve\">\n    <value>Непредвиденная ошибка при загрузке параметров. Проверьте параметры, выполнив команду 'settings'.</value>\n    <comment>{Locked=\"'settings'\"}</comment>\n  </data>\n  <data name=\"ShowChannel\" xml:space=\"preserve\">\n    <value>Канал</value>\n  </data>\n  <data name=\"ShowCommandLongDescription\" xml:space=\"preserve\">\n    <value>Отображает сведения о конкретном пакете. По умолчанию запрос должен сравнить идентификатор, имя или моникер пакета (без учета регистра). Можно использовать и другие поля, указав соответствующий параметр.</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"ShowCommandShortDescription\" xml:space=\"preserve\">\n    <value>Показывает сведения о пакете</value>\n  </data>\n  <data name=\"ShowVersion\" xml:space=\"preserve\">\n    <value>Версия</value>\n  </data>\n  <data name=\"SilentArgumentDescription\" xml:space=\"preserve\">\n    <value>Запросить автоматическую установку</value>\n  </data>\n  <data name=\"SingleCharAfterDashError\" xml:space=\"preserve\">\n    <value>Только один псевдоним символа может появляться после одного символа -: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides more than a single character command line alias argument after an alias argument specifier '-'. {0} is a placeholder replaced by the user's argument input.</comment>\n  </data>\n  <data name=\"SourceAddAlreadyExistsDifferentArg\" xml:space=\"preserve\">\n    <value>Источник с указанным именем уже существует и ссылается на другое расположение:</value>\n  </data>\n  <data name=\"SourceAddAlreadyExistsDifferentName\" xml:space=\"preserve\">\n    <value>На это расположение уже ссылается источник с другим именем:</value>\n  </data>\n  <data name=\"SourceAddAlreadyExistsMatch\" xml:space=\"preserve\">\n    <value>Источник с указанным именем уже существует и ссылается на это же расположение:</value>\n  </data>\n  <data name=\"SourceAddBegin\" xml:space=\"preserve\">\n    <value>Добавление источника:</value>\n  </data>\n  <data name=\"SourceAddCommandLongDescription\" xml:space=\"preserve\">\n    <value>Добавление нового источника. Источник предоставляет данные для обнаружения и установки пакетов. Добавляйте новый источник только в том случае, если вы доверяете ему как надежному расположению.</value>\n  </data>\n  <data name=\"SourceAddCommandShortDescription\" xml:space=\"preserve\">\n    <value>Добавление нового источника</value>\n  </data>\n  <data name=\"SourceArgArgumentDescription\" xml:space=\"preserve\">\n    <value>Аргумент, предоставленный источнику</value>\n  </data>\n  <data name=\"SourceArgumentDescription\" xml:space=\"preserve\">\n    <value>Поиск пакета с помощью указанного источника</value>\n  </data>\n  <data name=\"SourceCommandLongDescription\" xml:space=\"preserve\">\n    <value>Управление источниками с помощью подкоманд. Источник предоставляет данные для обнаружения и установки пакетов. Добавляйте новый источник только в том случае, если вы доверяете ему как надежному расположению.</value>\n  </data>\n  <data name=\"SourceCommandShortDescription\" xml:space=\"preserve\">\n    <value>Управление источниками пакетов</value>\n  </data>\n  <data name=\"SourceEditCommandLongDescription\" xml:space=\"preserve\">\n    <value>Изменение свойств существующего источника. Источник предоставляет данные для обнаружения и установки пакетов.</value>\n  </data>\n  <data name=\"SourceEditCommandShortDescription\" xml:space=\"preserve\">\n    <value>Изменить свойства источника</value>\n  </data>\n  <data name=\"SourceEditOne\" xml:space=\"preserve\">\n    <value>Редактирование источника: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being edited. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceEditNoChanges\" xml:space=\"preserve\">\n    <value>Источник с '{0}' уже находится в нужном состоянии.</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being edited. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceListArg\" xml:space=\"preserve\">\n    <value>Аргумент</value>\n    <comment>Value given to source.</comment>\n  </data>\n  <data name=\"SourceListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Перечисление всех текущих источников или полных сведений об определенном источнике.</value>\n  </data>\n  <data name=\"SourceListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Перечисление текущих источников</value>\n  </data>\n  <data name=\"SourceListData\" xml:space=\"preserve\">\n    <value>Данные</value>\n    <comment>Data stored by the source.</comment>\n  </data>\n  <data name=\"SourceListField\" xml:space=\"preserve\">\n    <value>Поле</value>\n    <comment>The name of a piece of information about a source.</comment>\n  </data>\n  <data name=\"SourceListName\" xml:space=\"preserve\">\n    <value>Имя</value>\n    <comment>The name of the source.</comment>\n  </data>\n  <data name=\"SourceListIdentifier\" xml:space=\"preserve\">\n    <value>Идентификатор</value>\n    <comment>The source's unique identifier.</comment>\n  </data>\n  <data name=\"SourceListNoneFound\" xml:space=\"preserve\">\n    <value>Не найден источник с именем: {0}</value>\n    <comment>Error message displayed when the user provides a repository source name that was not found. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"SourceListNoSources\" xml:space=\"preserve\">\n    <value>Нет настроенных источников.</value>\n  </data>\n  <data name=\"SourceListType\" xml:space=\"preserve\">\n    <value>Тип</value>\n    <comment>The kind of source.</comment>\n  </data>\n  <data name=\"SourceListUpdated\" xml:space=\"preserve\">\n    <value>Обновлено</value>\n    <comment>The last time the source was updated.</comment>\n  </data>\n  <data name=\"SourceListUpdatedNever\" xml:space=\"preserve\">\n    <value>никогда</value>\n    <comment>The source has never been updated.</comment>\n  </data>\n  <data name=\"SourceListValue\" xml:space=\"preserve\">\n    <value>Значение</value>\n    <comment>The value of information about a source.</comment>\n  </data>\n  <data name=\"SourceNameArgumentDescription\" xml:space=\"preserve\">\n    <value>Имя источника</value>\n  </data>\n  <data name=\"SourceOpenFailedSuggestion\" xml:space=\"preserve\">\n    <value>Сбой при открытии источников; выполните команду ''source reset'', если проблема повторится.</value>\n    <comment>{Locked=\"source reset\"}</comment>\n  </data>\n  <data name=\"SourceOpenPredefinedFailedSuggestion\" xml:space=\"preserve\">\n    <value>Не удалось открыть предопределенный источник. Сообщите об этом специалистам по обслуживанию winget.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"SourceRemoveAll\" xml:space=\"preserve\">\n    <value>Удаление всех источников...</value>\n  </data>\n  <data name=\"SourceRemoveCommandLongDescription\" xml:space=\"preserve\">\n    <value>Удаление определенного источника.</value>\n  </data>\n  <data name=\"SourceRemoveCommandShortDescription\" xml:space=\"preserve\">\n    <value>Удаление текущих источников</value>\n  </data>\n  <data name=\"SourceRemoveOne\" xml:space=\"preserve\">\n    <value>Удаление источника: {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being removed. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceResetAll\" xml:space=\"preserve\">\n    <value>Сброс всех источников...</value>\n  </data>\n  <data name=\"SourceResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>Эта команда удаляет существующие источники, в результате чего могут остаться локальные данные. При отсутствии аргументов она удаляет все источники и добавляет значения по умолчанию. Если указан именованный источник, удаляется только он.</value>\n  </data>\n  <data name=\"SourceResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>Сброс источников</value>\n  </data>\n  <data name=\"SourceResetForceArgumentDescription\" xml:space=\"preserve\">\n    <value>Принудительный сброс источников</value>\n  </data>\n  <data name=\"SourceResetListAndOverridePreamble\" xml:space=\"preserve\">\n    <value>Если задан параметр --force, будут сброшены следующие источники:</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"SourceResetOne\" xml:space=\"preserve\">\n    <value>Сброс источника: {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a repository source that is currently being reset. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceTypeArgumentDescription\" xml:space=\"preserve\">\n    <value>Тип источника</value>\n  </data>\n  <data name=\"SourceUpdateAll\" xml:space=\"preserve\">\n    <value>Обновление всех источников...</value>\n  </data>\n  <data name=\"SourceUpdateCommandLongDescription\" xml:space=\"preserve\">\n    <value>Обновление всех источников или только определенного источника.</value>\n  </data>\n  <data name=\"SourceUpdateCommandShortDescription\" xml:space=\"preserve\">\n    <value>Обновление текущих источников</value>\n  </data>\n  <data name=\"SourceUpdateOne\" xml:space=\"preserve\">\n    <value>Обновление источника: {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being updated. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"TagArgumentDescription\" xml:space=\"preserve\">\n    <value>Фильтровать результаты по тегу</value>\n  </data>\n  <data name=\"ThankYou\" xml:space=\"preserve\">\n    <value>Благодарим за использование виджета</value>\n  </data>\n  <data name=\"ThirdPartSoftwareNotices\" xml:space=\"preserve\">\n    <value>Уведомления третьих сторон</value>\n  </data>\n  <data name=\"ToolDescription\" xml:space=\"preserve\">\n    <value>Программа командной строки winget дает возможность устанавливать приложения и другие пакеты из командной строки.</value>\n  </data>\n  <data name=\"ToolInfoArgumentDescription\" xml:space=\"preserve\">\n    <value>Отображать общие сведения об инструменте</value>\n  </data>\n  <data name=\"ToolVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>Отобразить версию инструмента</value>\n  </data>\n  <data name=\"TooManyArgError\" xml:space=\"preserve\">\n    <value>Аргумент предоставлен больше раз, чем разрешено: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a command line argument more times than it is allowed. {0} is a placeholder replaced by the user's argument name input.</comment>\n  </data>\n  <data name=\"TooManyBehaviorsError\" xml:space=\"preserve\">\n    <value>Указано несколько аргументов поведения выполнения: '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides more than one execution behavior argument when installing an application package. {0} is a placeholder replaced by the user specified execution behaviors (e.g. 'silent|interactive').</comment>\n  </data>\n  <data name=\"UnexpectedErrorExecutingCommand\" xml:space=\"preserve\">\n    <value>При выполнении команды произошла непредвиденная ошибка:</value>\n  </data>\n  <data name=\"UninstallPreviousArgumentDescription\" xml:space=\"preserve\">\n    <value>Удалить предыдущую версию пакета во время обновления</value>\n  </data>\n  <data name=\"UnrecognizedCommand\" xml:space=\"preserve\">\n    <value>Нераспознанная команда: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an unrecognized command. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"UpdateAllArgumentDescription\" xml:space=\"preserve\">\n    <value>Обновить все установленные пакеты до последней версии, если она доступна</value>\n  </data>\n  <data name=\"UpdateNotApplicable\" xml:space=\"preserve\">\n    <value>Применимые обновления не найдены.</value>\n  </data>\n  <data name=\"UpdateNotApplicableReason\" xml:space=\"preserve\">\n    <value>В настроенном источнике доступна более новая версия пакета, но она не применяется к системе или требованиям.</value>\n  </data>\n  <data name=\"UpdateNoPackagesFound\" xml:space=\"preserve\">\n    <value>Доступные обновления не найдены.</value>\n  </data>\n  <data name=\"UpdateNoPackagesFoundReason\" xml:space=\"preserve\">\n    <value>Более новые версии пакетов недоступны в настроенных источниках.</value>\n  </data>\n  <data name=\"UpgradeCommandLongDescription\" xml:space=\"preserve\">\n    <value>Обновляет выбранный пакет, обнаруженный путем поиска в списке установленных пакетов или непосредственно из манифеста приложения. По умолчанию запрос должен соответствовать идентификатору, имени или пути ссылки пакета (без учета регистра). Можно использовать и другие поля, указав соответствующий параметр. Если аргументы не указаны, показывает пакеты с доступными обновлениями</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"UpgradeCommandShortDescription\" xml:space=\"preserve\">\n    <value>Отображает и выполняет доступные обновления</value>\n  </data>\n  <data name=\"Usage\" xml:space=\"preserve\">\n    <value>использование: {0} {1}</value>\n    <comment>{Locked=\"{0} {1}\"} Message displayed to provide the user with instructions on how to use a command. {0} is a placeholder replaced by the program name (e.g. 'winget'). {1} is a placeholder replaced by the pattern for using the selected command.</comment>\n  </data>\n  <data name=\"ValidateCommandLongDescription\" xml:space=\"preserve\">\n    <value>Проверяет манифест с помощью строгого набора рекомендаций. Это позволяет вам проверить манифест перед отправкой в репозиторий.</value>\n  </data>\n  <data name=\"ValidateCommandShortDescription\" xml:space=\"preserve\">\n    <value>Утверждает файл манифеста</value>\n  </data>\n  <data name=\"ValidateManifestArgumentDescription\" xml:space=\"preserve\">\n    <value>Путь к манифесту, подлежащему утверждению</value>\n  </data>\n  <data name=\"VerboseLogsArgumentDescription\" xml:space=\"preserve\">\n    <value>Включает ведение подробного журнала для WinGet</value>\n  </data>\n  <data name=\"VerifyFileSignedMsix\" xml:space=\"preserve\">\n    <value>Убедитесь, что входной файл является допустимым подписанным MSIX-файлом.</value>\n  </data>\n  <data name=\"VersionArgumentDescription\" xml:space=\"preserve\">\n    <value>Использовать указанную версию; по умолчанию используется последняя версия</value>\n  </data>\n  <data name=\"VersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Показать доступные версии пакета</value>\n  </data>\n  <data name=\"WordArgumentDescription\" xml:space=\"preserve\">\n    <value>Значение, указанное до запроса завершения</value>\n  </data>\n  <data name=\"GetManifestResultVersionNotFound\" xml:space=\"preserve\">\n    <value>Не найдены совпадающие версии: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to upgrade an application package to a version that was not found. {0} is a placeholder replaced by the user's provided upgrade package version.</comment>\n  </data>\n  <data name=\"OpenSourceFailedNoMatch\" xml:space=\"preserve\">\n    <value>Нет источников, совпадающих с указанным значением: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to install or upgrade an application package from a repository source that was not found. {0} is a placeholder replaced by the user's repository source name input.</comment>\n  </data>\n  <data name=\"OpenSourceFailedNoMatchHelp\" xml:space=\"preserve\">\n    <value>Настроенные источники:</value>\n  </data>\n  <data name=\"OpenSourceFailedNoSourceDefined\" xml:space=\"preserve\">\n    <value>Источники не указаны. Добавьте источник с помощью команды \"source add\" или восстановите значения по умолчанию с помощью \"source reset\"</value>\n    <comment>{Locked=\"source add\",\"source reset\"}</comment>\n  </data>\n  <data name=\"ReportIdentityFound\" xml:space=\"preserve\">\n    <value>Найдено</value>\n  </data>\n  <data name=\"VerifyFileFailedIsDirectory\" xml:space=\"preserve\">\n    <value>Указан путь к каталогу: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system path that is a directory. {0} is a placeholder replaced by the provided directory path.</comment>\n  </data>\n  <data name=\"VerifyFileFailedNotExist\" xml:space=\"preserve\">\n    <value>Файл не существует: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system file that does not exist. {0} is a placeholder replaced by the provided file path.</comment>\n  </data>\n  <data name=\"BothManifestAndSearchQueryProvided\" xml:space=\"preserve\">\n    <value>Предоставляются аргументы и локального манифеста, и поискового запроса</value>\n  </data>\n  <data name=\"Logs\" xml:space=\"preserve\">\n    <value>Журналы</value>\n    <comment>Label displayed for diagnostic files containing information about the application use.</comment>\n  </data>\n  <data name=\"InstallerBlockedByPolicy\" xml:space=\"preserve\">\n    <value>Установщик заблокирован политикой</value>\n  </data>\n  <data name=\"InstallerFailedSecurityCheck\" xml:space=\"preserve\">\n    <value>Установщик не прошел проверку безопасности</value>\n  </data>\n  <data name=\"InstallerFailedVirusScan\" xml:space=\"preserve\">\n    <value>Антивирусная программа сообщает о заражении в установщике</value>\n  </data>\n  <data name=\"SourceOpenWithFailedUpdate\" xml:space=\"preserve\">\n    <value>Не удалось обновить источник: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to update the repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"UninstallCommandLongDescription\" xml:space=\"preserve\">\n    <value>Удаление выбранного пакета, обнаруженного путем поиска в списке установленных пакетов либо непосредственно из манифеста. По умолчанию запрос должен соответствовать идентификатору, имени или моникеру пакета (без учета регистра). Можно использовать и другие поля, указав соответствующий параметр.</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"UninstallCommandShortDescription\" xml:space=\"preserve\">\n    <value>Удаление указанного пакета</value>\n  </data>\n  <data name=\"UninstallFlowStartingPackageUninstall\" xml:space=\"preserve\">\n    <value>Запуск удаления пакета...</value>\n  </data>\n  <data name=\"UninstallFlowUninstallSuccess\" xml:space=\"preserve\">\n    <value>Удалено</value>\n  </data>\n  <data name=\"NoUninstallInfoFound\" xml:space=\"preserve\">\n    <value>winget не может найти команду удаления для пакета. Обратитесь за помощью к издателю пакетов.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"UninstallAbandoned\" xml:space=\"preserve\">\n    <value>Удаление прекращено</value>\n  </data>\n  <data name=\"UninstallFailedWithCode\" xml:space=\"preserve\">\n    <value>Не удалось удалить. Код выхода: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to uninstall an application package fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"ExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Экспортирует список установленных пакетов</value>\n  </data>\n  <data name=\"ImportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Установка всех пакетов, перечисленных в файле.</value>\n  </data>\n  <data name=\"ImportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Устанавливает все пакеты в файле</value>\n  </data>\n  <data name=\"OutputFileArgumentDescription\" xml:space=\"preserve\">\n    <value>Файл, в который будет записан результат</value>\n  </data>\n  <data name=\"ImportFileArgumentDescription\" xml:space=\"preserve\">\n    <value>Файл с описанием устанавливаемых пакетов</value>\n  </data>\n  <data name=\"ExportSourceArgumentDescription\" xml:space=\"preserve\">\n    <value>Экспорт пакетов из указанного источника</value>\n  </data>\n  <data name=\"ExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Записывает список установленных пакетов в файл. После этого пакеты можно установить командой import.</value>\n    <comment>{Locked=\"import\"}</comment>\n  </data>\n  <data name=\"ImportInstallFailed\" xml:space=\"preserve\">\n    <value>Не удалось установить один или несколько импортированных пакетов</value>\n  </data>\n  <data name=\"ImportSourceNotInstalled\" xml:space=\"preserve\">\n    <value>Источник, необходимый для импорта, не установлен: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to import application package(s) from a repository source that is not installed. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"InstalledPackageNotAvailable\" xml:space=\"preserve\">\n    <value>Установленный пакет недоступен из любого источника: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when the user attempts to export an installed application package that is not available from any repository source. {0} is a placeholder replaced by the installed package name.</comment>\n  </data>\n  <data name=\"InstalledPackageVersionNotAvailable\" xml:space=\"preserve\">\n    <value>Установленная версия пакета недоступна из любого источника: {0} {1} {2}</value>\n    <comment>{Locked=\"{0} {1} {2}\"} Warning message displayed when the user attempts to export an installed application package with a version that is not available from any repository source. {0} is a placeholder replaced by the installed package identifier. {1} is a placeholder replaced by the installed package version. {2} is a placeholder replaced by the installed package channel.</comment>\n  </data>\n  <data name=\"NoPackagesInImportFile\" xml:space=\"preserve\">\n    <value>Пакеты в файле импорта не найдены</value>\n  </data>\n  <data name=\"InvalidJsonFile\" xml:space=\"preserve\">\n    <value>Файл JSON не является допустимым</value>\n  </data>\n  <data name=\"MultiQueryPackageAlreadyInstalled\" xml:space=\"preserve\">\n    <value>Пакет уже установлен: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user that an application package is already installed. {0} is a placeholder replaced by the package identifier or search query.</comment>\n  </data>\n  <data name=\"ImportIgnoreUnavailableArgumentDescription\" xml:space=\"preserve\">\n    <value>Игнорировать недоступные пакеты</value>\n  </data>\n  <data name=\"ExportIncludeVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Включить версии пакетов в файл экспорта</value>\n  </data>\n  <data name=\"ImportIgnoreVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Игнорировать версии пакета из файла импорта</value>\n  </data>\n  <data name=\"VerifyPathFailedNotExist\" xml:space=\"preserve\">\n    <value>Путь не существует: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system path argument value that does not exist. {0} is a placeholder replaced by the user's provided path.</comment>\n  </data>\n  <data name=\"ImportFileHasInvalidSchema\" xml:space=\"preserve\">\n    <value>В JSON-файле не указана распознанная схема.</value>\n  </data>\n  <data name=\"InstallScopeDescription\" xml:space=\"preserve\">\n    <value>Выберите область установки (user или machine)</value>\n    <comment>{Locked=\"user\",\"machine\"} This argument allows the user to select between installing for just the user or for the entire machine.</comment>\n  </data>\n  <data name=\"InvalidArgumentValueError\" xml:space=\"preserve\">\n    <value>Для аргумента \"{0}\" указано недопустимое значение; допустимые значения: {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message displayed when the user provides an invalid command line argument value. {0} is a placeholder replaced by the argument name. {1} is a placeholder replaced by a list of valid options.</comment>\n  </data>\n  <data name=\"DisabledByGroupPolicy\" xml:space=\"preserve\">\n    <value>Эта операция отключена групповая политика: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user performs a command operation that is disabled by a group policy. {0} is a placeholder replaced by a group policy description.</comment>\n  </data>\n  <data name=\"PolicyAdditionalSources\" xml:space=\"preserve\">\n    <value>Включить дополнительные источники Установщика приложений для Windows</value>\n  </data>\n  <data name=\"PolicyAllowedSources\" xml:space=\"preserve\">\n    <value>Включить разрешенные источники Установщика приложений для Windows</value>\n  </data>\n  <data name=\"PolicyEnableDefaultSource\" xml:space=\"preserve\">\n    <value>Включить источник по умолчанию Установщика приложений для Windows</value>\n  </data>\n  <data name=\"PolicyEnableExperimentalFeatures\" xml:space=\"preserve\">\n    <value>Включить экспериментальные функции Установщика приложений для Windows</value>\n  </data>\n  <data name=\"PolicyEnableMSStoreSource\" xml:space=\"preserve\">\n    <value>Включить источник Microsoft Store Установщика приложений для Windows</value>\n  </data>\n  <data name=\"PolicyEnableFontSource\" xml:space=\"preserve\">\n    <value>Включить источник шрифтов Установщика Windows App</value>\n  </data>\n  <data name=\"PolicyEnableWinGetSettings\" xml:space=\"preserve\">\n    <value>Включить параметры Диспетчера пакетов Windows</value>\n  </data>\n  <data name=\"PolicyEnableWinGet\" xml:space=\"preserve\">\n    <value>Включить Диспетчер пакетов Windows</value>\n  </data>\n  <data name=\"PolicyEnableWindowsPackageManagerCommandLineInterfaces\" xml:space=\"preserve\">\n    <value>Включить интерфейсы командной строки Диспетчера пакетов Windows</value>\n  </data>\n  <data name=\"PolicySourceAutoUpdateInterval\" xml:space=\"preserve\">\n    <value>Задать интервал автоматического обновления источника Диспетчера пакетов Windows в минутах</value>\n  </data>\n  <data name=\"PoliciesPolicy\" xml:space=\"preserve\">\n    <value>Групповая политика</value>\n    <comment>Header for a table listing active Group Policies</comment>\n  </data>\n  <data name=\"PolicyEnableLocalManifests\" xml:space=\"preserve\">\n    <value>Включить локальные файлы манифестов Установщика приложений для Windows</value>\n  </data>\n  <data name=\"PolicyEnableBypassCertificatePinningForMicrosoftStore\" xml:space=\"preserve\">\n    <value>Включить обход закрепленного сертификата источника Microsoft Store Установщика приложений для Windows</value>\n  </data>\n  <data name=\"PolicyEnableLocalArchiveMalwareScanOverride\" xml:space=\"preserve\">\n    <value>Включение переопределения сканирования вредоносных программ в локальном архиве установщика приложений Windows</value>\n  </data>\n  <data name=\"SettingsWarningField\" xml:space=\"preserve\">\n    <value>Поле: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when a user setting field has invalid syntax or semantics. {0} is a placeholder replaced by the setting field path.</comment>\n  </data>\n  <data name=\"SettingsWarningInvalidFieldFormat\" xml:space=\"preserve\">\n    <value>Недопустимый формат поля.</value>\n  </data>\n  <data name=\"SettingsWarningInvalidFieldValue\" xml:space=\"preserve\">\n    <value>Недопустимое значение поля.</value>\n  </data>\n  <data name=\"SettingsWarningInvalidValueFromPolicy\" xml:space=\"preserve\">\n    <value>Недопустимый параметр из групповой политики.</value>\n  </data>\n  <data name=\"SettingsWarningLoadedBackupSettings\" xml:space=\"preserve\">\n    <value>Загруженные параметры из файла резервной копии.</value>\n  </data>\n  <data name=\"SettingsWarningParseError\" xml:space=\"preserve\">\n    <value>Ошибка при анализе файла:</value>\n  </data>\n  <data name=\"SettingsWarningValue\" xml:space=\"preserve\">\n    <value>Значение: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when a user setting value has invalid syntax or semantics. {0} is a placeholder replaced by the setting data value.</comment>\n  </data>\n  <data name=\"FeaturesMessageDisabledByPolicy\" xml:space=\"preserve\">\n    <value>Выполняются следующие экспериментальные функции.\nКонфигурация отключена из-за групповой политики.</value>\n  </data>\n  <data name=\"InstallerHashMismatchError\" xml:space=\"preserve\">\n    <value>Хэш-код установщика не совпадает.</value>\n  </data>\n  <data name=\"PolicyEnableHashOverride\" xml:space=\"preserve\">\n    <value>Включить переопределение хэша Установщика приложений для Windows</value>\n  </data>\n  <data name=\"SourceExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Экспорт текущих источников в формате JSON для групповой политики.</value>\n  </data>\n  <data name=\"SourceExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Экспорт текущих источников</value>\n  </data>\n  <data name=\"SourceListAdditionalSource\" xml:space=\"preserve\">\n    <value>Дополнительный источник</value>\n    <comment>An additional source required by policy.</comment>\n  </data>\n  <data name=\"SourceListAllowedSource\" xml:space=\"preserve\">\n    <value>Разрешенный источник</value>\n    <comment>A source that the user is allowed to add.</comment>\n  </data>\n  <data name=\"InvalidArgumentValueErrorWithoutValidValues\" xml:space=\"preserve\">\n    <value>Для аргумента \"{0}\" указано недопустимое значение</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an invalid command line argument value. {0} is a placeholder replaced by the argument name.</comment>\n  </data>\n  <data name=\"Cancelled\" xml:space=\"preserve\">\n    <value>Отменено</value>\n  </data>\n  <data name=\"ExternalDependencies\" xml:space=\"preserve\">\n    <value>Внешние</value>\n  </data>\n  <data name=\"ImportCommandReportDependencies\" xml:space=\"preserve\">\n    <value>У пакетов, обнаруженных в этом импорте, следующие зависимости:</value>\n    <comment>Import command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"PackageRequiresDependencies\" xml:space=\"preserve\">\n    <value>Для этого пакета требуются следующие зависимости:</value>\n    <comment>Message shown before reporting dependencies</comment>\n  </data>\n  <data name=\"DependenciesFlowInstall\" xml:space=\"preserve\">\n    <value>Установка зависимостей:</value>\n  </data>\n  <data name=\"DependenciesFlowSourceNotFound\" xml:space=\"preserve\">\n    <value>Источник зависимостей не найден</value>\n  </data>\n  <data name=\"DependenciesFlowSourceTooManyMatches\" xml:space=\"preserve\">\n    <value>Поиск пакетов дает несколько результатов: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when application packages search yield more than one result. {0} is a placeholder replaced by the dependency package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowPackageVersionNotFound\" xml:space=\"preserve\">\n    <value>Не найдена последняя версия для пакета: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when no suitable version found for the specific application package. {0} is a placeholder replaced by the package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoInstallerFound\" xml:space=\"preserve\">\n    <value>Установщики не найдены: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when no installer found for a manifest. {0} is a placeholder replaced by the manifest identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoMinVersion\" xml:space=\"preserve\">\n    <value>Для пакета недоступна минимальная необходимая версия: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the minimum required version is not available for an application package. {0} is a placeholder replaced by the package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoMatches\" xml:space=\"preserve\">\n    <value>Нет совпадений</value>\n    <comment>When package search yields no matches</comment>\n  </data>\n  <data name=\"DependenciesFlowContainsLoop\" xml:space=\"preserve\">\n    <value>Содержит цикл</value>\n    <comment>Dependency graph has loop</comment>\n  </data>\n  <data name=\"DependenciesFlowNoSuitableInstallerFound\" xml:space=\"preserve\">\n    <value>Не найден подходящий установщик для манифеста: {0} версии {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message displayed when an attempt to get a preferred installer for a manifest fails. {0} is a placeholder replaced by the manifest identifier. {1} is a placeholder replaced by the manifest version.</comment>\n  </data>\n  <data name=\"DependenciesManagementError\" xml:space=\"preserve\">\n    <value>Ошибка обработки зависимостей пакета. Продолжить установку?</value>\n    <comment>Prompt message shown when dependencies processing yields errors.</comment>\n  </data>\n  <data name=\"DependenciesManagementExitMessage\" xml:space=\"preserve\">\n    <value>Ошибка обработки зависимостей пакета. Выход...</value>\n  </data>\n  <data name=\"PackageDependencies\" xml:space=\"preserve\">\n    <value>Пакеты</value>\n  </data>\n  <data name=\"UninstallCommandReportDependencies\" xml:space=\"preserve\">\n    <value>У этого пакета есть зависимости, которые могут больше не требоваться:</value>\n    <comment>Uninstall command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"ValidateCommandReportDependencies\" xml:space=\"preserve\">\n    <value>Манифест содержит следующие непроверенные зависимости; убедитесь, что они действительны:</value>\n    <comment>Validate command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"WindowsFeaturesDependencies\" xml:space=\"preserve\">\n    <value>Компоненты Windows</value>\n  </data>\n  <data name=\"WindowsLibrariesDependencies\" xml:space=\"preserve\">\n    <value>Библиотеки Windows</value>\n  </data>\n  <data name=\"DependencySourceArgumentDescription\" xml:space=\"preserve\">\n    <value>Поиск зависимостей пакета с помощью указанного источника</value>\n    <comment>For getting package type dependencies when installing from a local manifest</comment>\n  </data>\n  <data name=\"WindowsStoreTerms\" xml:space=\"preserve\">\n    <value>Условия Windows Store</value>\n  </data>\n  <data name=\"AcceptPackageAgreementsArgumentDescription\" xml:space=\"preserve\">\n    <value>Принять все лицензионные соглашения для пакетов</value>\n  </data>\n  <data name=\"ExportedPackageRequiresLicenseAgreement\" xml:space=\"preserve\">\n    <value>Для установки экспортированного пакета требуется лицензионное соглашение: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when an exported application package requires license agreement to install. {0} is a placeholder replaced by the package name.</comment>\n  </data>\n  <data name=\"PackageAgreementsPrompt\" xml:space=\"preserve\">\n    <value>Издатель требует, чтобы вы просмотрели указанную выше информацию и приняли соглашения перед установкой.\nВы согласны с условиями?</value>\n  </data>\n  <data name=\"PackageAgreementsNotAgreedTo\" xml:space=\"preserve\">\n    <value>Соглашения для пакетов не приняты. Операция отменена.</value>\n  </data>\n  <data name=\"ShowLabelAgreements\" xml:space=\"preserve\">\n    <value>Соглашения:</value>\n  </data>\n  <data name=\"ShowLabelAuthor\" xml:space=\"preserve\">\n    <value>Автор:</value>\n  </data>\n  <data name=\"ShowLabelDescription\" xml:space=\"preserve\">\n    <value>Описание:</value>\n  </data>\n  <data name=\"ShowLabelInstaller\" xml:space=\"preserve\">\n    <value>Установщик:</value>\n  </data>\n  <data name=\"ShowLabelInstallerLocale\" xml:space=\"preserve\">\n    <value>Языковой стандарт установщика:</value>\n  </data>\n  <data name=\"ShowLabelInstallerProductId\" xml:space=\"preserve\">\n    <value>Идентификатор продукта в Store:</value>\n  </data>\n  <data name=\"ShowLabelInstallerSha256\" xml:space=\"preserve\">\n    <value>SHA256 установщика:</value>\n  </data>\n  <data name=\"ShowLabelInstallerType\" xml:space=\"preserve\">\n    <value>Тип установщика:</value>\n  </data>\n  <data name=\"ShowLabelInstallerUrl\" xml:space=\"preserve\">\n    <value>URL-адрес установщика:</value>\n  </data>\n  <data name=\"ShowLabelLicense\" xml:space=\"preserve\">\n    <value>Лицензия:</value>\n  </data>\n  <data name=\"ShowLabelLicenseUrl\" xml:space=\"preserve\">\n    <value>URL-адрес лицензии:</value>\n  </data>\n  <data name=\"ShowLabelMoniker\" xml:space=\"preserve\">\n    <value>Моникер:</value>\n  </data>\n  <data name=\"ShowLabelPackageUrl\" xml:space=\"preserve\">\n    <value>Домашняя страница:</value>\n  </data>\n  <data name=\"ShowLabelPublisher\" xml:space=\"preserve\">\n    <value>Издатель:</value>\n  </data>\n  <data name=\"ShowLabelTags\" xml:space=\"preserve\">\n    <value>Теги:</value>\n  </data>\n  <data name=\"ShowLabelVersion\" xml:space=\"preserve\">\n    <value>Версия:</value>\n  </data>\n  <data name=\"ShowLabelDependencies\" xml:space=\"preserve\">\n    <value>Зависимости:</value>\n  </data>\n  <data name=\"ShowLabelWindowsFeaturesDependencies\" xml:space=\"preserve\">\n    <value>Компоненты Windows:</value>\n  </data>\n  <data name=\"ShowLabelWindowsLibrariesDependencies\" xml:space=\"preserve\">\n    <value>Библиотеки Windows:</value>\n  </data>\n  <data name=\"ShowLabelPackageDependencies\" xml:space=\"preserve\">\n    <value>Зависимости пакетов:</value>\n  </data>\n  <data name=\"ShowLabelExternalDependencies\" xml:space=\"preserve\">\n    <value>Внешние зависимости:</value>\n  </data>\n  <data name=\"PromptOptionNo\" xml:space=\"preserve\">\n    <value>Нет</value>\n  </data>\n  <data name=\"PromptOptionYes\" xml:space=\"preserve\">\n    <value>Да</value>\n  </data>\n  <data name=\"SourceAddOpenSourceFailed\" xml:space=\"preserve\">\n    <value>Не удалось открыть добавленный источник.</value>\n  </data>\n  <data name=\"AcceptSourceAgreementsArgumentDescription\" xml:space=\"preserve\">\n    <value>Принимать все соглашения источников во время операций с источниками</value>\n  </data>\n  <data name=\"SourceAgreementsTitle\" xml:space=\"preserve\">\n    <value>Перед использованием источника \"{0}\" необходимо просмотреть следующие соглашения.</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user that a repository source requires viewing agreements before using. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceAgreementsPrompt\" xml:space=\"preserve\">\n    <value>Вы согласны со всеми условиями исходных соглашений?</value>\n  </data>\n  <data name=\"SourceAgreementsNotAgreedTo\" xml:space=\"preserve\">\n    <value>Соглашения для одного или нескольких источников не приняты. Операция отменена. Примите соглашения источников или удалите эти источники.</value>\n  </data>\n  <data name=\"SourceAgreementsMarketMessage\" xml:space=\"preserve\">\n    <value>Для правильной работы источника требуется отправить во внутреннюю службу двухбуквенный код текущего региона компьютера (например, \"RU\").</value>\n  </data>\n  <data name=\"InstallFlowRegistrationDeferred\" xml:space=\"preserve\">\n    <value>Успешно установлено. Перезапустите приложение, чтобы завершить обновление.</value>\n  </data>\n  <data name=\"HeaderArgumentDescription\" xml:space=\"preserve\">\n    <value>Необязательный HTTP-заголовок источника REST Windows-Package-Manager</value>\n  </data>\n  <data name=\"HeaderArgumentNotApplicableForNonRestSourceWarning\" xml:space=\"preserve\">\n    <value>Необязательный заголовок игнорируется, поскольку он неприменим для этого источника.</value>\n  </data>\n  <data name=\"HeaderArgumentNotApplicableWithoutSource\" xml:space=\"preserve\">\n    <value>Необязательный заголовок неприменим, если не указан источник: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user performs an operation (e.g install) and provides the HTTP 'header' argument without specifying the repository source. {0} is a placeholder replaced by the header argument name.</comment>\n  </data>\n  <data name=\"ShowLabelInstallerReleaseDate\" xml:space=\"preserve\">\n    <value>Дата выпуска:</value>\n  </data>\n  <data name=\"ShowLabelInstallerOfflineDistributionSupported\" xml:space=\"preserve\">\n    <value>Поддерживается автономное распространение:</value>\n  </data>\n  <data name=\"ShowLabelPublisherUrl\" xml:space=\"preserve\">\n    <value>URL-адрес издателя:</value>\n  </data>\n  <data name=\"ShowLabelPurchaseUrl\" xml:space=\"preserve\">\n    <value>URL-адрес покупки:</value>\n  </data>\n  <data name=\"ShowLabelPublisherSupportUrl\" xml:space=\"preserve\">\n    <value>URL-адрес службы поддержки издателя:</value>\n  </data>\n  <data name=\"ShowLabelPrivacyUrl\" xml:space=\"preserve\">\n    <value>URL-адрес заявления о конфиденциальности:</value>\n  </data>\n  <data name=\"ShowLabelCopyright\" xml:space=\"preserve\">\n    <value>Авторское право:</value>\n  </data>\n  <data name=\"ShowLabelCopyrightUrl\" xml:space=\"preserve\">\n    <value>URL-адрес заявления об авторских правах:</value>\n  </data>\n  <data name=\"ShowLabelReleaseNotes\" xml:space=\"preserve\">\n    <value>Заметки о выпуске:</value>\n  </data>\n  <data name=\"ShowLabelReleaseNotesUrl\" xml:space=\"preserve\">\n    <value>URL-адрес заметок о выпуске:</value>\n  </data>\n  <data name=\"SearchFailureWarning\" xml:space=\"preserve\">\n    <value>Сбой при поиске в источнике; результаты не будут включены: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when searching a repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SearchFailureError\" xml:space=\"preserve\">\n    <value>Сбой при поиске в источнике: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when searching a repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"FeatureDisabledByAdminSettingMessage\" xml:space=\"preserve\">\n    <value>Эту функцию должен включить администратор. Чтобы включить ее, выполните команду \"winget settings --enable {0}\" от имени администратора.</value>\n    <comment>{Locked=\"winget settings --enable\", \"{0}\"}. Error message displayed when the user uses a feature that needs to be enabled by administrators. {0} is a placeholder replaced by the admin setting.</comment>\n  </data>\n  <data name=\"AdminSettingEnableDescription\" xml:space=\"preserve\">\n    <value>Включает определенный параметр администратора</value>\n  </data>\n  <data name=\"AdminSettingDisableDescription\" xml:space=\"preserve\">\n    <value>Отключает определенный параметр администратора</value>\n  </data>\n  <data name=\"AdminSettingEnabled\" xml:space=\"preserve\">\n    <value>Включен параметр администратора \"{0}\".</value>\n    <comment>{Locked=\"{0}\"} Message displayed when the user enables an admin setting. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"AdminSettingDisabled\" xml:space=\"preserve\">\n    <value>Отключен параметр администратора \"{0}\".</value>\n    <comment>{Locked=\"{0}\"} Message displayed when the user disables an admin setting. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"AdminSettingHeader\" xml:space=\"preserve\">\n    <value>Параметр администратора</value>\n    <comment>Header for a table displaying admin settings.</comment>\n  </data>\n  <data name=\"InstallFlowReturnCodePackageInUse\" xml:space=\"preserve\">\n    <value>Приложение сейчас запущено. Выйдите из приложения и повторите попытку.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodePackageInUseByApplication\" xml:space=\"preserve\">\n    <value>Файлы, измененные установщиком, в настоящее время используются другим приложением. Выйдите из приложений и повторите попытку.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInstallInProgress\" xml:space=\"preserve\">\n    <value>Уже выполняется другая установка. Повторите попытку позже.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeFileInUse\" xml:space=\"preserve\">\n    <value>Используется один или несколько файлов. Выйдите из приложения и повторите попытку.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeMissingDependency\" xml:space=\"preserve\">\n    <value>У этого пакета отсутствует зависимость в вашей системе.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeDiskFull\" xml:space=\"preserve\">\n    <value>На вашем компьютере больше нет места. Освободите место и повторите попытку.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInsufficientMemory\" xml:space=\"preserve\">\n    <value>Недостаточно памяти для установки. Закройте другие приложения и повторите попытку.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInvalidParameter\" xml:space=\"preserve\">\n    <value>Один из параметров установки недопустим. Дополнительные сведения могут содержаться в журнале установки пакета.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeNoNetwork\" xml:space=\"preserve\">\n    <value>Для этого приложения требуется подключение к Интернету. Подключитесь к сети и повторите попытку.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeContactSupport\" xml:space=\"preserve\">\n    <value>Приложение обнаружило ошибку во время установки. Обратитесь в службу поддержки.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootRequiredToFinish\" xml:space=\"preserve\">\n    <value>Перезапустите компьютер, чтобы завершить установку.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootRequiredForInstall\" xml:space=\"preserve\">\n    <value>Ваш компьютер будет перезагружен, чтобы завершить установку.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootInitiated\" xml:space=\"preserve\">\n    <value>Сбой установки. Перезагрузите компьютер и повторите попытку.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeCancelledByUser\" xml:space=\"preserve\">\n    <value>Вы отменили установку.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeAlreadyInstalled\" xml:space=\"preserve\">\n    <value>Уже установлена другая версия этого приложения.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeDowngrade\" xml:space=\"preserve\">\n    <value>Уже установлена более поздняя версия этого приложения.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeBlockedByPolicy\" xml:space=\"preserve\">\n    <value>Установка запрещена политиками организации. Обратитесь к администратору.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeSystemNotSupported\" xml:space=\"preserve\">\n    <value>Текущая конфигурация системы не поддерживает установку этого пакета.</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeCustomError\" xml:space=\"preserve\">\n    <value>Сбой установки из-за ошибки настраиваемого установщика. Обратитесь в службу поддержки пакета.</value>\n  </data>\n  <data name=\"InstallAbandoned\" xml:space=\"preserve\">\n    <value>Установка прервана</value>\n  </data>\n  <data name=\"InstallerFailedWithCode\" xml:space=\"preserve\">\n    <value>Сбой установки с кодом выхода: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the application installer fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"InstallerLogAvailable\" xml:space=\"preserve\">\n    <value>Журнал установщика доступен по адресу: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about the system path of a diagnostic files containing information about the installer. {0} is a placeholder replaced by the diagnostic file system path.</comment>\n  </data>\n  <data name=\"SearchFailureErrorListMatches\" xml:space=\"preserve\">\n    <value>Среди рабочих источников найдены следующие пакеты.\nЧтобы продолжить, укажите один из них, используя параметр \"--source\".</value>\n    <comment>{Locked=\"--source\"} \"working sources\" as in \"sources that are working correctly\"</comment>\n  </data>\n  <data name=\"SearchFailureErrorNoMatches\" xml:space=\"preserve\">\n    <value>Пакеты не найдены среди рабочих источников.</value>\n    <comment>\"working sources\" as in \"sources that are working correctly\"</comment>\n  </data>\n  <data name=\"FeaturesMessageDisabledByBuild\" xml:space=\"preserve\">\n    <value>Это стабильный выпуск Диспетчера пакетов Windows. Чтобы попробовать экспериментальные функции, установите предварительную сборку. Инструкции доступны в GitHub по ссылке https://github.com/microsoft/winget-cli.</value>\n    <comment>{Locked=\"https://github.com/microsoft/winget-cli\"}</comment>\n  </data>\n  <data name=\"WindowsPackageManager\" xml:space=\"preserve\">\n    <value>Диспетчер пакетов Windows версии {0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying the product name and version. {0} is a placeholder replaced by the product version.</comment>\n  </data>\n  <data name=\"ImportIgnorePackageVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Игнорировать версии пакета в файле импорта</value>\n  </data>\n  <data name=\"CountOutOfBoundsError\" xml:space=\"preserve\">\n    <value>Запрошенное число результатов должно находиться в диапазоне от 1 до 1000.</value>\n  </data>\n  <data name=\"CustomSwitchesArgumentDescription\" xml:space=\"preserve\">\n    <value>Аргументы, передаваемые установщику в дополнение к параметрам по умолчанию</value>\n  </data>\n  <data name=\"UpgradeDifferentInstallTechnologyInNewerVersions\" xml:space=\"preserve\">\n    <value>Обнаружена более новая версия, но технология установки отличается от текущей установленной версии. Удалите пакет и установите более новую версию.</value>\n  </data>\n  <data name=\"UpgradeDifferentInstallTechnology\" xml:space=\"preserve\">\n    <value>Указанная технология установки более новой версии отличается от текущей установленной версии. Удалите пакет и установите более новую версию.</value>\n  </data>\n  <data name=\"WindowsPackageManagerPreview\" xml:space=\"preserve\">\n    <value>Диспетчер пакетов Windows (предварительная версия) версии {0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying the preview product name and pre-release version. {0} is a placeholder replaced by the product version.</comment>\n  </data>\n  <data name=\"ArchitectureArgumentDescription\" xml:space=\"preserve\">\n    <value>Выберите архитектуру</value>\n  </data>\n  <data name=\"IncludeUnknownArgumentDescription\" xml:space=\"preserve\">\n    <value>Обновить пакеты, даже если не удается определить их текущую версию</value>\n  </data>\n  <data name=\"IncludeUnknownInListArgumentDescription\" xml:space=\"preserve\">\n    <value>Список пакетов, даже если их текущая версия не может быть определена. Можно использовать только с аргументом --upgrade-available.</value>\n    <comment>{Locked=\"--upgrade-available\"}</comment>\n  </data>\n  <data name=\"UpgradeUnknownVersionExplanation\" xml:space=\"preserve\">\n    <value>Невозможно определить номер версии этого пакета. Чтобы все равно обновить его, добавьте аргумент --include-unknown к предыдущей команде.</value>\n    <comment>{Locked=\"--include-unknown\"}</comment>\n  </data>\n  <data name=\"UpgradeUnknownVersionCount\" xml:space=\"preserve\">\n    <value>Несколько ({0}) пакетов содержат номера версий, которые невозможно определить. Используйте параметр --include-unknown для просмотра всех результатов.</value>\n    <comment>{Locked=\"{0}\",\"--include-unknown\"} {0} is a placeholder that is replaced by an integer number of packages that do not have notated versions. </comment>\n  </data>\n  <data name=\"UpgradeRequireExplicitCount\" xml:space=\"preserve\">\n    <value>Несколько ({0}) пакетов закреплены и должны быть явно обновлены.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by an integer number of packages that require explicit upgrades.</comment>\n  </data>\n  <data name=\"InvalidArgumentWithoutQueryError\" xml:space=\"preserve\">\n    <value>Указанные аргументы можно использовать только с запросом.</value>\n  </data>\n  <data name=\"SystemArchitecture\" xml:space=\"preserve\">\n    <value>Архитектура системы: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for the system architecture. {0} is a placeholder replaced by the value of the system architecture (e.g. X64).</comment>\n  </data>\n  <data name=\"PreserveArgumentDescription\" xml:space=\"preserve\">\n    <value>Сохраняет все файлы и каталоги, созданные пакетом (переносной)</value>\n  </data>\n  <data name=\"PurgeArgumentDescription\" xml:space=\"preserve\">\n    <value>Удаляет все файлы и каталоги в каталоге пакета (переносной)</value>\n  </data>\n  <data name=\"PressEnterToContinue\" xml:space=\"preserve\">\n    <value>Для продолжения нажмите клавишу ВВОД . . .</value>\n  </data>\n  <data name=\"RenameArgumentDescription\" xml:space=\"preserve\">\n    <value>Значение для переименования исполняемого файла (переносной)</value>\n  </data>\n  <data name=\"WaitArgumentDescription\" xml:space=\"preserve\">\n    <value>Запрашивает нажатие любой клавиши пользователем перед выходом</value>\n  </data>\n  <data name=\"InstallerElevationExpected\" xml:space=\"preserve\">\n    <value>Установщик запросит запуск от имени администратора. Ожидайте запроса.</value>\n  </data>\n  <data name=\"InstallerProhibitsElevation\" xml:space=\"preserve\">\n    <value>Не удается запустить установщик из контекста администратора.</value>\n  </data>\n  <data name=\"ModifiedPathRequiresShellRestart\" xml:space=\"preserve\">\n    <value>Переменная среды пути изменена; перезапустите оболочку, чтобы использовать новое значение.</value>\n  </data>\n  <data name=\"ProductCodeArgumentDescription\" xml:space=\"preserve\">\n    <value>Фильтры с использованием кода продукта</value>\n  </data>\n  <data name=\"PortableRegistryCollisionOverridden\" xml:space=\"preserve\">\n    <value>Переносной пакет с таким именем, но из другого источника уже существует; выполняется из-за параметра --force</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"ReparsePointsNotSupportedError\" xml:space=\"preserve\">\n    <value>Том не поддерживает точки повторного анализа</value>\n  </data>\n  <data name=\"ReservedFilenameError\" xml:space=\"preserve\">\n    <value>Указанное имя файла не является допустимым именем файла</value>\n  </data>\n  <data name=\"OverwritingExistingFileAtMessage\" xml:space=\"preserve\">\n    <value>Перезапись существующего файла:{0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed to inform the user that an existing file is being overwritten. {0} is a placeholder replaced by the file system path.</comment>\n  </data>\n  <data name=\"NoPackageSelectionArgumentProvided\" xml:space=\"preserve\">\n    <value>Не указан аргумент выбора пакета; дополнительные сведения о поиске пакета см. в справке.</value>\n  </data>\n  <data name=\"PortableAliasAdded\" xml:space=\"preserve\">\n    <value>Добавлен псевдоним командной строки:</value>\n  </data>\n  <data name=\"PortableLinksMachine\" xml:space=\"preserve\">\n    <value>Каталог переносимых ссылок (компьютер)</value>\n  </data>\n  <data name=\"PortableLinksUser\" xml:space=\"preserve\">\n    <value>Каталог переносимых ссылок (пользователь)</value>\n  </data>\n  <data name=\"PortableRootUser\" xml:space=\"preserve\">\n    <value>Корень переносимого пакета (пользователь)</value>\n  </data>\n  <data name=\"PortableRoot\" xml:space=\"preserve\">\n    <value>Корень переносимого пакета</value>\n  </data>\n  <data name=\"PortableRoot86\" xml:space=\"preserve\">\n    <value>Корень переносимого пакета (x86)</value>\n  </data>\n  <data name=\"PortableInstallFailed\" xml:space=\"preserve\">\n    <value>Сбой переносной установки; Очистка...</value>\n  </data>\n  <data name=\"PortableHashMismatchOverridden\" xml:space=\"preserve\">\n    <value>Переносимый пакет был изменен. Продолжение работы, так как указан параметр --force</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"PortableHashMismatchOverrideRequired\" xml:space=\"preserve\">\n    <value>Не удалось удалить переносимый пакет, так как он был изменен. Чтобы переопределить эту проверку, используйте параметр --force</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"FilesRemainInInstallDirectory\" xml:space=\"preserve\">\n    <value>Файлы, остающиеся в каталоге установки:: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when files remain in install directory. {0} is a placeholder replaced by the directory path.</comment>\n  </data>\n  <data name=\"PurgeInstallDirectory\" xml:space=\"preserve\">\n    <value>Очистка каталога установки...</value>\n  </data>\n  <data name=\"UnableToPurgeInstallDirectory\" xml:space=\"preserve\">\n    <value>Не удается очистить каталог установки, так как он не был создан с помощью WinGet</value>\n  </data>\n  <data name=\"RelatedLink\" xml:space=\"preserve\">\n    <value>Связанная ссылка</value>\n  </data>\n  <data name=\"ShowLabelDocumentation\" xml:space=\"preserve\">\n    <value>Документация:</value>\n  </data>\n  <data name=\"Notes\" xml:space=\"preserve\">\n    <value>Заметки: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for installation notes. {0} is a placeholder replaced by installation notes.</comment>\n  </data>\n  <data name=\"ShowLabelInstallationNotes\" xml:space=\"preserve\">\n    <value>Примечания по установке:</value>\n  </data>\n  <data name=\"UnsupportedArgument\" xml:space=\"preserve\">\n    <value>Указанный аргумент не поддерживается для этого пакета</value>\n  </data>\n  <data name=\"ExtractArchiveFailed\" xml:space=\"preserve\">\n    <value>Не удалось извлечь содержимое архива</value>\n  </data>\n  <data name=\"NestedInstallerNotFound\" xml:space=\"preserve\">\n    <value>Вложенный файл установщика не существует. Убедитесь, что указанный относительный путь вложенного установщика совпадает: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when nested installer file does not exist. {0} is a placeholder replaced by the nested installer file path.</comment>\n  </data>\n  <data name=\"InvalidPathToNestedInstaller\" xml:space=\"preserve\">\n    <value>Недопустимый относительный путь к файлу для вложенного установщика. Путь указывает на расположение за пределами каталога установки</value>\n  </data>\n  <data name=\"NestedInstallerNotSpecified\" xml:space=\"preserve\">\n    <value>Для этого пакета не указаны вложенные установщики</value>\n  </data>\n  <data name=\"MultipleUnsupportedNestedInstallersSpecified\" xml:space=\"preserve\">\n    <value>Для установщика архива можно указать только один вложенный установщик, если только он не является переносимым или вложенным установщиком шрифтов</value>\n  </data>\n  <data name=\"IncompatibleArgumentsProvided\" xml:space=\"preserve\">\n    <value>Указаны несовместимые аргументы командной строки</value>\n  </data>\n  <data name=\"UpgradeArgumentDescription\" xml:space=\"preserve\">\n    <value>Перечисляет только пакеты с доступным обновлением</value>\n  </data>\n  <data name=\"UpgradeAvailableForPinned\" xml:space=\"preserve\">\n    <value>Для следующих пакетов доступно обновление, но для обновления требуется явный выбор целевого объекта.</value>\n    <comment>\"require explicit targeting for upgrade\" means that the package will not be upgraded with all others unless an extra flag is added, or the package is mentioned explicitly</comment>\n  </data>\n  <data name=\"Downloading\" xml:space=\"preserve\">\n    <value>Скачивание</value>\n    <comment>Label displayed while downloading an application installer.</comment>\n  </data>\n  <data name=\"NestedInstallerNotSupported\" xml:space=\"preserve\">\n    <value>Вложенный тип установщика не поддерживается</value>\n  </data>\n  <data name=\"InstallerAbortsTerminal\" xml:space=\"preserve\">\n    <value>Известно, что установщик перезапускает терминал или оболочку</value>\n  </data>\n  <data name=\"InstallerRequiresInstallLocation\" xml:space=\"preserve\">\n    <value>Для этого пакета требуется расположение установки</value>\n  </data>\n  <data name=\"InstallersAbortTerminal\" xml:space=\"preserve\">\n    <value>Известно, что следующие установщики перезапускают терминал или оболочку.</value>\n  </data>\n  <data name=\"InstallersRequireInstallLocation\" xml:space=\"preserve\">\n    <value>Для следующих установщиков требуется расположение установки.</value>\n  </data>\n  <data name=\"PromptForInstallRoot\" xml:space=\"preserve\">\n    <value>Укажите корень установки:</value>\n  </data>\n  <data name=\"PromptToProceed\" xml:space=\"preserve\">\n    <value>Вы хотите продолжить?</value>\n  </data>\n  <data name=\"ReportIdentityForAgreements\" xml:space=\"preserve\">\n    <value>Соглашения для</value>\n    <comment>This will be followed by a package name, and then a list of license agreements</comment>\n  </data>\n  <data name=\"InstallLocationNotProvided\" xml:space=\"preserve\">\n    <value>Для пакета требуется расположение установки, но оно не было предоставлено</value>\n  </data>\n  <data name=\"DisableInteractivityArgumentDescription\" xml:space=\"preserve\">\n    <value>Отключить интерактивные запросы</value>\n    <comment>Description for a command line argument, shown next to it in the help</comment>\n  </data>\n  <data name=\"ConvertInstallFlowToUpgrade\" xml:space=\"preserve\">\n    <value>Найден существующий установленный пакет. Попытка обновления установленного пакета...</value>\n  </data>\n  <data name=\"ForceArgumentDescription\" xml:space=\"preserve\">\n    <value>Выполнить команду напрямую и продолжить с проблемами, не связанными с безопасностью</value>\n    <comment>Description for a command line argument, shown next to it in the help</comment>\n  </data>\n  <data name=\"PortablePackageAlreadyExists\" xml:space=\"preserve\">\n    <value>Переносимый пакет из другого источника уже существует</value>\n  </data>\n  <data name=\"ExtractArchiveSucceeded\" xml:space=\"preserve\">\n    <value>Архив извлечен</value>\n  </data>\n  <data name=\"ExtractingArchive\" xml:space=\"preserve\">\n    <value>Извлечение архива...</value>\n  </data>\n  <data name=\"ArchiveFailedMalwareScan\" xml:space=\"preserve\">\n    <value>При проверке архива обнаружено вредоносное ПО. Чтобы переопределить эту проверку, используйте --ignore-local-archive-malware-scan</value>\n    <comment>{Locked=\"--ignore-local-archive-malware-scan\"}</comment>\n  </data>\n  <data name=\"ArchiveFailedMalwareScanOverridden\" xml:space=\"preserve\">\n    <value>При проверке архива обнаружено вредоносное ПО. Продолжено из-за --ignore-local-archive-malware-scan</value>\n    <comment>{Locked=\"--ignore-local-archive-malware-scan\"}</comment>\n  </data>\n  <data name=\"NoUpgradeArgumentDescription\" xml:space=\"preserve\">\n    <value>Пропускает обновление, если установленная версия уже существует</value>\n  </data>\n  <data name=\"PackageAlreadyInstalled\" xml:space=\"preserve\">\n    <value>Версия пакета уже установлена. Установка отменена.</value>\n  </data>\n  <data name=\"EnableAdminSettingFailed\" xml:space=\"preserve\">\n    <value>Не удается включить {0}. Этот параметр управляется политикой. Для получения дополнительных сведений обратитесь к системному администратору.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"DisableAdminSettingFailed\" xml:space=\"preserve\">\n    <value>Не удается отключить {0}. Этот параметр управляется политикой. Для получения дополнительных сведений обратитесь к системному администратору.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"PinAddCommandLongDescription\" xml:space=\"preserve\">\n    <value>Добавление нового закрепления. Закрепление может помешать Диспетчеру пакетов Windows обновить пакет до определенных диапазонов версий или предотвратить обновление пакета. Закрепленный пакет может по-прежнему обновляться сам и обновляться вне Диспетчера пакетов Windows. По умолчанию закрепленный пакет можно обновить, явно указав его в команде \"upgrade\" или добавив флаг \"--include-pinned\" в \"winget upgrade --all\".</value>\n    <comment>{Locked{\"'upgrade'\"} Locked{\"--include-pinned\"} Locked{\"winget upgrade --all\"}</comment>\n  </data>\n  <data name=\"PinAddCommandShortDescription\" xml:space=\"preserve\">\n    <value>Добавление нового закрепления</value>\n  </data>\n  <data name=\"PinCommandLongDescription\" xml:space=\"preserve\">\n    <value>Управление закреплениями пакетов с помощью подкоманд. Закрепление может помешать Диспетчеру пакетов Windows обновить пакет до определенных диапазонов версий или предотвратить обновление пакета. Закрепленный пакет может по-прежнему обновляться сам и обновляться вне Диспетчера пакетов Windows.</value>\n  </data>\n  <data name=\"PinCommandShortDescription\" xml:space=\"preserve\">\n    <value>Управление закреплениями пакетов</value>\n  </data>\n  <data name=\"PinListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Список всех текущих контактов или полных сведений о конкретном закреплении.</value>\n  </data>\n  <data name=\"PinListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Список текущих закреплений</value>\n  </data>\n  <data name=\"PinRemoveCommandLongDescription\" xml:space=\"preserve\">\n    <value>Удаление закрепления определенного пакета.</value>\n  </data>\n  <data name=\"PinRemoveCommandShortDescription\" xml:space=\"preserve\">\n    <value>Удаление закрепления пакета</value>\n  </data>\n  <data name=\"PinResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>Сброс всех существующих закреплений.</value>\n  </data>\n  <data name=\"PinResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>Сбросить закрепления</value>\n  </data>\n  <data name=\"GatedVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>Версия для закрепления пакета. Подстановочный знак \"*\" можно использовать как часть последней версии</value>\n  </data>\n  <data name=\"PinAddBlockingArgumentDescription\" xml:space=\"preserve\">\n    <value>Блокировать обновление до тех пор, пока закрепление не будет удалено. Это предотвращает переопределение аргументов</value>\n  </data>\n  <data name=\"PinInstalledArgumentDescription\" xml:space=\"preserve\">\n    <value>Закрепить определенную установленную версию</value>\n  </data>\n  <data name=\"PinInstalledSource\" xml:space=\"preserve\">\n    <value>Установлено</value>\n    <comment>Value used in a table to indicate that a package comes from the list of packages installed in the machine</comment>\n  </data>\n  <data name=\"SettingsExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Экспорт параметров в формате JSON</value>\n  </data>\n  <data name=\"SettingsExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Параметры экспорта</value>\n  </data>\n  <data name=\"UserSettings\" xml:space=\"preserve\">\n    <value>Параметры пользователя</value>\n    <comment>Label displayed for the file containing the user settings.</comment>\n  </data>\n  <data name=\"SettingsWarningUsingDefault\" xml:space=\"preserve\">\n    <value>Не удалось загрузить файл параметров. Используются значения по умолчанию.</value>\n  </data>\n  <data name=\"InstalledScopeArgumentDescription\" xml:space=\"preserve\">\n    <value>Выберите фильтр установленных пакетов (для user или machine)</value>\n    <comment>{Locked=\"user\",\"machine\"} This argument allows the user to select installed packages for just the user or for the entire machine.</comment>\n  </data>\n  <data name=\"PinAdded\" xml:space=\"preserve\">\n    <value>Закрепление добавлено</value>\n  </data>\n  <data name=\"PinAlreadyExists\" xml:space=\"preserve\">\n    <value>Пакет {0} уже закреплен</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that will be replaced by a package name. The message is shown when attempting to add a pin for a package that is already pinned.</comment>\n  </data>\n  <data name=\"PinExistsOverwriting\" xml:space=\"preserve\">\n    <value>Пакет {0} уже закреплен. Перезапись из-за аргумента --force.</value>\n    <comment>{Locked=\"--force\"}{Locked=\"--force\",\"{0}\"} {0} is a placeholder that will be replaced by a package name.</comment>\n  </data>\n  <data name=\"PinExistsUseForceArg\" xml:space=\"preserve\">\n    <value>Пин-код для пакета {0}. Используйте аргумент --force, чтобы перезаписать его.</value>\n    <comment>{Locked=\"--force\",\"{0}\"} {0} is a placeholder that will be replaced by a package name.</comment>\n  </data>\n  <data name=\"PinResettingAll\" xml:space=\"preserve\">\n    <value>Сброс всех текущих закреплений.</value>\n  </data>\n  <data name=\"PinResetUseForceArg\" xml:space=\"preserve\">\n    <value>Используйте аргумент --force для сброса всех закреплений. Будут удалены следующие закрепления:</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"PinType\" xml:space=\"preserve\">\n    <value>Тип закрепления</value>\n  </data>\n  <data name=\"PinDoesNotExist\" xml:space=\"preserve\">\n    <value>Нет закрепления для пакета {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that will be replaced by a package name. The message is shown when attempting to delete a pin for a package that is not pinned.</comment>\n  </data>\n  <data name=\"PinNoPinsExist\" xml:space=\"preserve\">\n    <value>Закрепления не настроены.</value>\n    <comment>Shown when listing or modifying existing pins if there are none.</comment>\n  </data>\n  <data name=\"PinResetSuccessful\" xml:space=\"preserve\">\n    <value>Закрепления сброшены</value>\n    <comment>Shown after resetting (deleting) all the pins</comment>\n  </data>\n  <data name=\"PinCannotOpenIndex\" xml:space=\"preserve\">\n    <value>Не удалось открыть базу данных закреплений.</value>\n    <comment>Error message for when we cannot open the database containing package pins.</comment>\n  </data>\n  <data name=\"ArgumentForSinglePackageProvidedWithMultipleQueries\" xml:space=\"preserve\">\n    <value>Указан аргумент, который можно использовать только для одного пакета</value>\n  </data>\n  <data name=\"MultipleExclusiveArgumentsProvided\" xml:space=\"preserve\">\n    <value>Указано несколько взаимоисключающих аргументов: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message shown when mutually incompatible command line arguments are used. {0} is a placeholder replaced by the arguments that cannot be specified together</comment>\n  </data>\n  <data name=\"DependencyArgumentMissing\" xml:space=\"preserve\">\n    <value>Аргумент {0} может использоваться только с {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message shown when having an argument needs another to be present, but that is missing. {0} and {1} are replaced by the arguments. For example \"Argument --include-unknown can only be used with --upgrade\"</comment>\n  </data>\n  <data name=\"StateDisabled\" xml:space=\"preserve\">\n    <value>Отключено</value>\n    <comment>As in enabled/disabled</comment>\n  </data>\n  <data name=\"StateEnabled\" xml:space=\"preserve\">\n    <value>Включено</value>\n    <comment>As in enabled/disabled</comment>\n  </data>\n  <data name=\"StateHeader\" xml:space=\"preserve\">\n    <value>Состояние</value>\n    <comment>Header for a table listing the state (enabled/disabled) of Group Policies and Settings</comment>\n  </data>\n  <data name=\"MultiQueryArgumentDescription\" xml:space=\"preserve\">\n    <value>Запрос, используемый для поиска пакета</value>\n  </data>\n  <data name=\"MultiQueryPackageNotFound\" xml:space=\"preserve\">\n    <value>Пакет не найден: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches returns no results. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"MultiQuerySearchFoundMultiple\" xml:space=\"preserve\">\n    <value>Найдено несколько пакетов для: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches returns more than one result. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"MultiQuerySearchFailed\" xml:space=\"preserve\">\n    <value>Сбой поиска для: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches fails. This message is for generic failures, we have more specific messages for when the search returns no results, or when it returns more than one result. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"UpgradeBlockedByPinCount\" xml:space=\"preserve\">\n    <value>Несколько ({0}) пакетов используют закрепление, которое необходимо удалить перед обновлением</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by an integer number of packages with pins that prevent upgrade</comment>\n  </data>\n  <data name=\"UpgradeBlockedByManifest\" xml:space=\"preserve\">\n    <value>Невозможно обновить пакет с помощью winget. Для обновления этого пакета используйте метод, предоставленный издателем.</value>\n  </data>\n  <data name=\"IncludePinnedArgumentDescription\" xml:space=\"preserve\">\n    <value>Обновление пакетов, даже если они используют неблокирующее закрепление</value>\n  </data>\n  <data name=\"IncludePinnedInListArgumentDescription\" xml:space=\"preserve\">\n    <value>Список пакетов, даже если у них есть ПИН-код, который блокирует обновление. Можно использовать только с аргументом --upgrade-available.</value>\n    <comment>{Locked=\"--upgrade-available\"}</comment>\n  </data>\n  <data name=\"PinRemovedSuccessfully\" xml:space=\"preserve\">\n    <value>Закрепление удалено</value>\n  </data>\n  <data name=\"UpgradeIsPinned\" xml:space=\"preserve\">\n    <value>Обнаружена более новая версия, но пакет содержит закрепление, которое не позволяет обновить его.</value>\n  </data>\n  <data name=\"PackageIsPinned\" xml:space=\"preserve\">\n    <value>Пакет закреплен и не может быть обновлен. Используйте команду \"winget pin\" для просмотра и изменения закреплений. Некоторые типы закреплений можно обойти с помощью аргумента --include-pinned.</value>\n    <comment>{Locked=\"winget pin\",\"--include-pinned\"} Error shown when we block an upgrade due to the package being pinned</comment>\n  </data>\n  <data name=\"UpgradePinnedByUserCount\" xml:space=\"preserve\">\n    <value>Несколько ({0}) пакетов используют закрепления, которые препятствуют обновлению. Воспользуйтесь командой \"winget pin\" для просмотра и изменения закреплений. Использование аргумента --include-pinned может привести к отображению дополнительных результатов.</value>\n    <comment>{Locked=\"winget pin\",\"--include-pinned\"} {0} is a placeholder replaced by an integer number of packages</comment>\n  </data>\n  <data name=\"ConfigureCommandLongDescription\" xml:space=\"preserve\">\n    <value>Гарантирует, что система соответствует нужному состоянию, как описано в указанной конфигурации. Может скачивать/выполнять обработчики для достижения нужного состояния. Необходимо проверить надежность конфигурации и обработчиков перед их применением.</value>\n  </data>\n  <data name=\"ConfigureCommandShortDescription\" xml:space=\"preserve\">\n    <value>Настройка системы в нужное состояние</value>\n  </data>\n  <data name=\"ConfigureShowCommandLongDescription\" xml:space=\"preserve\">\n    <value>Отображает сведения об указанной конфигурации. По умолчанию система не изменяется, но некоторые параметры будут вызывать скачивание и/или загрузку файлов.</value>\n  </data>\n  <data name=\"ConfigureShowCommandShortDescription\" xml:space=\"preserve\">\n    <value>Отображение сведений о конфигурации</value>\n  </data>\n  <data name=\"ConfigureTestCommandLongDescription\" xml:space=\"preserve\">\n    <value>Проверяет, соответствует ли система нужному состоянию, как описано в указанной конфигурации. Может скачивать/выполнять обработчики для тестирования нужного состояния. Необходимо проверить надежность конфигурации и обработчиков перед их выполнением.</value>\n  </data>\n  <data name=\"ConfigureTestCommandShortDescription\" xml:space=\"preserve\">\n    <value>Проверяет систему на соответствие нужному состоянию</value>\n  </data>\n  <data name=\"ConfigureValidateCommandLongDescription\" xml:space=\"preserve\">\n    <value>Проверяет правильность файла конфигурации.</value>\n  </data>\n  <data name=\"ConfigureValidateCommandShortDescription\" xml:space=\"preserve\">\n    <value>Проверяет файл конфигурации</value>\n  </data>\n  <data name=\"ConfigurationFieldInvalidType\" xml:space=\"preserve\">\n    <value>Недопустимый '{0}' в файле конфигурации.</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the field name from the file.</comment>\n  </data>\n  <data name=\"ConfigurationFileArgumentDescription\" xml:space=\"preserve\">\n    <value>Путь к файлу конфигурации</value>\n  </data>\n  <data name=\"ConfigurationFileInvalid\" xml:space=\"preserve\">\n    <value>Файл конфигурации недопустим.</value>\n  </data>\n  <data name=\"ConfigurationFileVersionUnknown\" xml:space=\"preserve\">\n    <value>Версия файла конфигурации {0} неизвестна.</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the version of the configuration file.</comment>\n  </data>\n  <data name=\"ConfigurationAcceptWarningArgumentDescription\" xml:space=\"preserve\">\n    <value>Принимает предупреждение конфигурации, препятствующее интерактивному запросу</value>\n  </data>\n  <data name=\"ConfigurationApply\" xml:space=\"preserve\">\n    <value>Применить</value>\n    <comment>Indicates that this item is used to write state</comment>\n  </data>\n  <data name=\"ConfigurationAssert\" xml:space=\"preserve\">\n    <value>Декларация</value>\n    <comment>Indicates that this item is used to check/assert the state rather than write to it</comment>\n  </data>\n  <data name=\"ConfigurationDependencies\" xml:space=\"preserve\">\n    <value>Зависимости:{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying a list of dependencies. {0} is replaced with a space separated list of identifiers referencing other items.</comment>\n  </data>\n  <data name=\"ConfigurationFailedToApply\" xml:space=\"preserve\">\n    <value>Не удалось применить часть конфигурации.</value>\n  </data>\n  <data name=\"ConfigurationFailedToGetDetails\" xml:space=\"preserve\">\n    <value>Не удалось получить подробные сведения о конфигурации.</value>\n  </data>\n  <data name=\"ConfigurationInform\" xml:space=\"preserve\">\n    <value>Информирование</value>\n    <comment>Indicates that this item is used to retrieve values for future use rather than writing them</comment>\n  </data>\n  <data name=\"ConfigurationLocal\" xml:space=\"preserve\">\n    <value>Локальный</value>\n    <comment>Used to indicate that the item is present on the device.</comment>\n  </data>\n  <data name=\"ConfigurationModuleNameOnly\" xml:space=\"preserve\">\n    <value>Модуль: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying a module name. {0} is replaced with the name of the module from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationModuleWithDetails\" xml:space=\"preserve\">\n    <value>Модуль: {0} от {1} [{2}]</value>\n    <comment>{Locked=\"{0}\",\"{1}\",\"{2}\"} Label displaying module information. {0} is replaced by the module name. {1} is replaced by the module author. {2} is replaced by a string indicating the source of the module.</comment>\n  </data>\n  <data name=\"ConfigurationSettings\" xml:space=\"preserve\">\n    <value>Параметры:</value>\n    <comment>Label for the values that are used as inputs for this item when applying state</comment>\n  </data>\n  <data name=\"ConfigurationSuccessfullyApplied\" xml:space=\"preserve\">\n    <value>Конфигурация применена.</value>\n  </data>\n  <data name=\"ConfigurationUnitSuccessfullyApplied\" xml:space=\"preserve\">\n    <value>Элемент успешно применен.</value>\n  </data>\n  <data name=\"ConfigurationWaitingOnAnother\" xml:space=\"preserve\">\n    <value>К системе применяется другая конфигурация. Эта конфигурация будет продолжена, как только это будет возможно...</value>\n  </data>\n  <data name=\"ConfigurationWarning\" xml:space=\"preserve\">\n    <value>Вы самостоятельно отвечаете за понимание параметров конфигурации, которую собираетесь выполнить. Корпорация Майкрософт не несет ответственности за файл конфигурации, который вы создали или импортировали. Эта конфигурация может изменить параметры Windows, установить программное обеспечение, изменить параметры установленного программного обеспечения (включая параметры безопасности), а также принять от вашего имени пользовательские соглашения для сторонних пакетов программ и служб. Запуская этот файл конфигурации, вы подтверждаете, что понимаете состав этих ресурсов и параметров и соглашаетесь их применить. Любые установленные приложения лицензируются их владельцами. Майкрософт не несет ответственности за сторонние пакеты программ или службы и не предоставляет для них никаких лицензий.</value>\n    <comment>Legal approved. Do not change without approval.</comment>\n  </data>\n  <data name=\"ConfigurationWarningPromptApply\" xml:space=\"preserve\">\n    <value>Вы проверили конфигурацию и хотите продолжить ее применение к системе?</value>\n    <comment>PM approved.</comment>\n  </data>\n  <data name=\"ConfigurationFileEmpty\" xml:space=\"preserve\">\n    <value>Конфигурация пуста.</value>\n  </data>\n  <data name=\"WindowsFeatureNotFound\" xml:space=\"preserve\">\n    <value>Компонент [{0}] не найден.</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Windows feature was not found on the system.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeatureOverrideRequired\" xml:space=\"preserve\">\n    <value>Не удалось включить зависимости компонентов Windows. Чтобы продолжить установку, используйте \"--force\".</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"RebootRequiredToEnableWindowsFeatureOverrideRequired\" xml:space=\"preserve\">\n    <value>Для полного включения компонентов Windows требуется перезагрузка. Чтобы переопределить эту проверку, используйте \"--force\".</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeatureOverridden\" xml:space=\"preserve\">\n    <value>Не удалось включить зависимости компонентов Windows; продолжение из-за --force</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.\n{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"EnablingWindowsFeature\" xml:space=\"preserve\">\n    <value>Включение компонента [{0}]…</value>\n    <comment>{Locked=\"{0}\"} Message displayed to the user regarding which Windows Feature is being enabled.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeature\" xml:space=\"preserve\">\n    <value>Не удалось включить компонент [{0}]: {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"}  An error when enabling a Windows Feature. {0} is a placeholder for the name of the Windows Feature.\n{1} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"RebootRequiredToEnableWindowsFeatureOverridden\" xml:space=\"preserve\">\n    <value>Для полного включения компонентов Windows требуется перезагрузка; продолжение из-за --force</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.</comment>\n  </data>\n  <data name=\"InstallWaitingOnAnother\" xml:space=\"preserve\">\n    <value>Ожидание завершения другой установки или удаления...</value>\n  </data>\n  <data name=\"PinVersion\" xml:space=\"preserve\">\n    <value>Закрепленная версия</value>\n    <comment>Table header for the version to which a package is pinned; meaning it should not update from that version.</comment>\n  </data>\n  <data name=\"ConfigurationDescriptionWasTruncated\" xml:space=\"preserve\">\n    <value>&lt;Дополнительные сведения см. в файле журнала&gt;</value>\n    <comment>The brackets are intended to make the value stand out from other text which it will follow. Any locale appropriate mechanism that achieves this is acceptable.</comment>\n  </data>\n  <data name=\"ConfigurationGettingDetails\" xml:space=\"preserve\">\n    <value>Получение сведений о конфигурации</value>\n  </data>\n  <data name=\"ConfigurationInitializing\" xml:space=\"preserve\">\n    <value>Инициализация системы конфигурации</value>\n  </data>\n  <data name=\"ConfigurationReadingConfigFile\" xml:space=\"preserve\">\n    <value>Чтение файла конфигурации</value>\n  </data>\n  <data name=\"ConfigurationUnitAssertHadNegativeResult\" xml:space=\"preserve\">\n    <value>Система не находится в нужном состоянии, утвержденном конфигурацией.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailed\" xml:space=\"preserve\">\n    <value>Сбой этой единицы конфигурации по неизвестной причине: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedConfigSet\" xml:space=\"preserve\">\n    <value>Сбой единицы конфигурации из-за конфигурации: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringGet\" xml:space=\"preserve\">\n    <value>Сбой блока конфигурации при попытке получить текущее состояние системы.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringSet\" xml:space=\"preserve\">\n    <value>Сбой блока конфигурации при попытке применить нужное состояние.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringTest\" xml:space=\"preserve\">\n    <value>Сбой блока конфигурации при попытке проверить текущее состояние системы.</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedInternal\" xml:space=\"preserve\">\n    <value>Сбой единицы конфигурации из-за внутренней ошибки: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedPrecondition\" xml:space=\"preserve\">\n    <value>Сбой единицы конфигурации из-за недопустимого предварительного условия: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedSystemState\" xml:space=\"preserve\">\n    <value>Сбой единицы конфигурации из-за состояния системы: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedUnitProcessing\" xml:space=\"preserve\">\n    <value>Сбой модуля конфигурации при попытке запуска: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitHasDuplicateIdentifier\" xml:space=\"preserve\">\n    <value>Конфигурация содержит идентификатор \"{0}\" несколько раз.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by the identifier string from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationUnitHasMissingDependency\" xml:space=\"preserve\">\n    <value>Зависимость \"{0}\" не найдена в конфигурации.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by the identifier string from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationUnitManuallySkipped\" xml:space=\"preserve\">\n    <value>Этот блок конфигурации был пропущен вручную.</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleConflict\" xml:space=\"preserve\">\n    <value>Модуль для блока конфигурации доступен в нескольких расположениях с одинаковой версией.</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleImportFailed\" xml:space=\"preserve\">\n    <value>Не удалось загрузить модуль для единицы конфигурации.</value>\n  </data>\n  <data name=\"ConfigurationUnitMultipleMatches\" xml:space=\"preserve\">\n    <value>Обнаружено несколько соответствий для блока конфигурации. Укажите модуль, чтобы выбрать правильный вариант.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotFound\" xml:space=\"preserve\">\n    <value>Не удалось найти блок конфигурации.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotFoundInModule\" xml:space=\"preserve\">\n    <value>Блок конфигурации отсутствовал в ожидаемом модуле.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotRunDueToDependency\" xml:space=\"preserve\">\n    <value>Этот блок конфигурации не был запущен из-за сбоя зависимости или невыполненного запуска зависимости.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotRunDueToFailedAssert\" xml:space=\"preserve\">\n    <value>Этот блок конфигурации не был запущен из-за сбоя утверждения или неверного утверждения.</value>\n  </data>\n  <data name=\"ConfigurationUnitReturnedInvalidResult\" xml:space=\"preserve\">\n    <value>Модуль конфигурации вернул непредвиденный результат во время выполнения.</value>\n  </data>\n  <data name=\"ConfigurationUnitSkipped\" xml:space=\"preserve\">\n    <value>Эта единица конфигурации не была запущена по неизвестной причине: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationFieldInvalidValue\" xml:space=\"preserve\">\n    <value>Поле '{0}' имеет недопустимое значение: {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} An error in reading a configuration file. {0} is a placeholder replaced by the field name from the file. {1} is a placeholder for the invalid value.</comment>\n  </data>\n  <data name=\"ConfigurationFieldMissing\" xml:space=\"preserve\">\n    <value>Поле \"{0}\" отсутствует или пусто.</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the expected field name from the file.</comment>\n  </data>\n  <data name=\"SeeLineAndColumn\" xml:space=\"preserve\">\n    <value>См. {0} строку, столбец {1} в файле.</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Indicates the file location of the error, {0} and {1} are placeholders for numbers of the line and column, respectively.</comment>\n  </data>\n  <data name=\"CancellingOperation\" xml:space=\"preserve\">\n    <value>Выполняется отмена операции</value>\n  </data>\n  <data name=\"InstallStubPackageDescription\" xml:space=\"preserve\">\n    <value>Установить пакет заглушки для AppInstaller</value>\n  </data>\n  <data name=\"InstallFullPackageDescription\" xml:space=\"preserve\">\n    <value>Установить полный пакет для AppInstaller</value>\n  </data>\n  <data name=\"ExtendedFeaturesEnableMessage\" xml:space=\"preserve\">\n    <value>Включите расширенные функции. Требуется доступ к хранилищу.</value>\n  </data>\n  <data name=\"ExtendedFeaturesEnableArgumentError\" xml:space=\"preserve\">\n    <value>Параметры \"--enable\" и \"--disable\" нельзя использовать с другими аргументами.</value>\n    <comment>{Locked=\"--enable\", \"--disable\"}</comment>\n  </data>\n  <data name=\"ExtendedFeaturesEnablingMessage\" xml:space=\"preserve\">\n    <value>Включение расширенных функций. Требуется доступ к хранилищу.</value>\n  </data>\n  <data name=\"ExtendedFeaturesNotEnabledMessage\" xml:space=\"preserve\">\n    <value>Расширенные функции не включены. Выполните \"winget configure --enable\", чтобы включить их.</value>\n    <comment>{Locked=\"winget configure --enable\"}</comment>\n  </data>\n  <data name=\"ExtendedFeaturesEnabledMessage\" xml:space=\"preserve\">\n    <value>Расширенные функции включены.</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisableMessage\" xml:space=\"preserve\">\n    <value>Отключить расширенные функции. Требуется доступ к хранилищу.</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisablingMessage\" xml:space=\"preserve\">\n    <value>Отключение расширенных функций. Требуется доступ к хранилищу.</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisabledMessage\" xml:space=\"preserve\">\n    <value>Расширенные функции отключены.</value>\n  </data>\n  <data name=\"SkipDependenciesArgumentDescription\" xml:space=\"preserve\">\n    <value>Пропускает обработку зависимостей пакетов и компонентов Windows</value>\n  </data>\n  <data name=\"DependenciesSkippedMessage\" xml:space=\"preserve\">\n    <value>Зависимости пропущены.</value>\n  </data>\n  <data name=\"FailedToRefreshPathWarning\" xml:space=\"preserve\">\n    <value>Не удалось обновить переменную PATH для процесса. Последующие установки, зависящие от изменений переменной PATH, могут быть завершиться сбоем.</value>\n    <comment>{Locked=\"PATH\"}</comment>\n  </data>\n  <data name=\"ConfigurationFailedToTest\" xml:space=\"preserve\">\n    <value>Сбой некоторых модулей конфигурации при проверке их состояния.</value>\n  </data>\n  <data name=\"ConfigurationInDesiredState\" xml:space=\"preserve\">\n    <value>Система находится в описанном состоянии конфигурации.</value>\n  </data>\n  <data name=\"ConfigurationNoTestRun\" xml:space=\"preserve\">\n    <value>Состояние конфигурации не протестировано.</value>\n  </data>\n  <data name=\"ConfigurationNotInDesiredState\" xml:space=\"preserve\">\n    <value>Система не находится в описанном состоянии конфигурации.</value>\n  </data>\n  <data name=\"ConfigurationUnexpectedTestResult\" xml:space=\"preserve\">\n    <value>Непредвиденный результат теста: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message. {0} will be replaced with the unexpected value (a number).</comment>\n  </data>\n  <data name=\"ConfigurationWarningPromptTest\" xml:space=\"preserve\">\n    <value>Вы просмотрели конфигурацию и хотите продолжить ее проверку в системе?</value>\n  </data>\n  <data name=\"ConfigurationFileInvalidYAML\" xml:space=\"preserve\">\n    <value>Файл конфигурации не является допустимым YAML файла.</value>\n    <comment>{Locked=\"YAML\"} YAML is a file format name.</comment>\n  </data>\n  <data name=\"ConfigurationUnitIsPartOfDependencyCycle\" xml:space=\"preserve\">\n    <value>Этот модуль конфигурации является частью цикла зависимостей.</value>\n  </data>\n  <data name=\"ConfigurationValidationFoundNoIssues\" xml:space=\"preserve\">\n    <value>Проверка не обнаружила проблем.</value>\n  </data>\n  <data name=\"ConfigurationUnitNeedsPrereleaseWarning\" xml:space=\"preserve\">\n    <value>Модуль конфигурации доступен только в качестве предварительной версии, но не помечен так в конфигурации. Добавьте \"allowPrerelease: true\" в \"directives\".</value>\n    <comment>{Locked=\"allowPrerelease: true\",\"directives\"} These are values in the configuration file that are not localized.</comment>\n  </data>\n  <data name=\"ConfigurationUnitNotInCatalogWarning\" xml:space=\"preserve\">\n    <value>Модуль конфигурации найден локально, но не найден ни в одном из настроенных каталогов. Перед применением конфигурации убедитесь, что он присутствует в какой-либо системе.</value>\n  </data>\n  <data name=\"ConfigurationUnitNotPublicWarning\" xml:space=\"preserve\">\n    <value>Модуль конфигурации не является общедоступным. Убедитесь, что у любого пользователя, который будет применять эту конфигурацию, есть к ней доступ.</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleNotProvidedWarning\" xml:space=\"preserve\">\n    <value>Модуль не указан. Указание модуля повышает производительность и предотвращает конфликты имен в будущем.</value>\n  </data>\n  <data name=\"DownloadCommandLongDescription\" xml:space=\"preserve\">\n    <value>Скачивание установщика из выбранного пакета, найденного путем поиска настроенного источника или непосредственно из манифеста. По умолчанию запрос должен без учета регистра совпадать с идентификатором, именем или моникером пакета. Другие поля можно использовать путем передачи соответствующего параметра. По умолчанию команда скачивания загрузит соответствующий установщик в папку загрузок пользователя.</value>\n  </data>\n  <data name=\"DownloadCommandShortDescription\" xml:space=\"preserve\">\n    <value>Скачивание установщика из указанного пакета</value>\n  </data>\n  <data name=\"DownloadDirectoryArgumentDescription\" xml:space=\"preserve\">\n    <value>Каталог, в который скачиваются установщики</value>\n  </data>\n  <data name=\"DependenciesFlowDownload\" xml:space=\"preserve\">\n    <value>Загрузка зависимостей:</value>\n  </data>\n  <data name=\"InstallerDownloaded\" xml:space=\"preserve\">\n    <value>Установщик скачан: {0}</value>\n    <comment>{Locked=\"{0}\"} Full path of the downloaded installer.</comment>\n  </data>\n  <data name=\"InstallerTypeArgumentDescription\" xml:space=\"preserve\">\n    <value>Выберите тип установщика</value>\n  </data>\n  <data name=\"InstallerDownloads\" xml:space=\"preserve\">\n    <value>Скачивания установщика</value>\n  </data>\n  <data name=\"InstallerDownloadCommandProhibited\" xml:space=\"preserve\">\n    <value>Загрузка установщика для более поздней автономной установки запрещена. </value>\n  </data>\n  <data name=\"ConfigurationAllUsersElevated\" xml:space=\"preserve\">\n    <value>Для выполнения команды --module-path allusers требуются права администратора.</value>\n    <comment>{Locked=\"--module-path allusers\"}</comment>\n  </data>\n  <data name=\"ConfigurationModulePath\" xml:space=\"preserve\">\n    <value>Указывает расположение на локальном компьютере для хранения модулей. По умолчанию: %LOCALAPPDATA%\\Microsoft\\WinGet\\Configuration\\Modules.</value>\n    <comment>{Locked=\"%LOCALAPPDATA%\\Microsoft\\WinGet\\Configuration\\Modules\"}</comment>\n  </data>\n  <data name=\"ConfigurationModulePathArgError\" xml:space=\"preserve\">\n    <value>Для --module-path должно быть задано значение currentuser, allusers, default или абсолютный путь.</value>\n    <comment>{Locked=\"{--module-path}, {currentuser}, {allusers}, {default}}</comment>\n  </data>\n  <data name=\"PolicyEnableWinGetConfiguration\" xml:space=\"preserve\">\n    <value>Включить конфигурацию Диспетчера пакетов Windows</value>\n  </data>\n  <data name=\"ErrorCommandLongDescription\" xml:space=\"preserve\">\n    <value>Получение сведений об ошибках. Если указано число, выходные данные будут содержать сведения об ошибке, включая имя символа, если это ошибка winget. При указании строки для этого значения будут искаться ошибки, относящиеся к winget.</value>\n  </data>\n  <data name=\"ErrorCommandShortDescription\" xml:space=\"preserve\">\n    <value>Получить информацию об ошибках</value>\n  </data>\n  <data name=\"ErrorInputArgumentDescription\" xml:space=\"preserve\">\n    <value>Значение для поиска в сведениях об ошибке</value>\n  </data>\n  <data name=\"ErrorNumberIsTooLarge\" xml:space=\"preserve\">\n    <value>Указанное число слишком велико для HRESULT.</value>\n  </data>\n  <data name=\"UnknownErrorCode\" xml:space=\"preserve\">\n    <value>Неизвестный код ошибки</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INTERNAL_ERROR\" xml:space=\"preserve\">\n    <value>Внутренняя ошибка</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS\" xml:space=\"preserve\">\n    <value>Недопустимые аргументы командной строки</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMMAND_FAILED\" xml:space=\"preserve\">\n    <value>Не удалось выполнить команду</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_FAILED\" xml:space=\"preserve\">\n    <value>Не удалось открыть манифест</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CTRL_SIGNAL_RECEIVED\" xml:space=\"preserve\">\n    <value>Получен сигнал отмены</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SHELLEXEC_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Сбой при выполнении ShellExecute</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_MANIFESTVERSION\" xml:space=\"preserve\">\n    <value>Не удается обработать манифест. Версия манифеста выше поддерживаемой. Обновите клиент.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_FAILED\" xml:space=\"preserve\">\n    <value>Не удалось скачать установщик</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX\" xml:space=\"preserve\">\n    <value>Не удается выполнить запись в индекс; более поздняя версия схемы</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INDEX_INTEGRITY_COMPROMISED\" xml:space=\"preserve\">\n    <value>Индекс поврежден</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCES_INVALID\" xml:space=\"preserve\">\n    <value>Сведения о настроенном источнике повреждены</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NAME_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>Имя источника уже настроено</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_SOURCE_TYPE\" xml:space=\"preserve\">\n    <value>Недопустимый тип источника</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_BUNDLE\" xml:space=\"preserve\">\n    <value>Файл MSIX является набором, а не пакетом</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_DATA_MISSING\" xml:space=\"preserve\">\n    <value>Отсутствуют данные, требуемые источником</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER\" xml:space=\"preserve\">\n    <value>Ни один из установщиков не подходит для текущей системы</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_HASH_MISMATCH\" xml:space=\"preserve\">\n    <value>Хэш файла установщика не соответствует манифесту</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NAME_DOES_NOT_EXIST\" xml:space=\"preserve\">\n    <value>Имя источника не существует</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_ARG_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>Исходное расположение уже настроено под другим именем</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICATIONS_FOUND\" xml:space=\"preserve\">\n    <value>Пакеты не найдены</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_SOURCES_DEFINED\" xml:space=\"preserve\">\n    <value>Источники не настроены</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_APPLICATIONS_FOUND\" xml:space=\"preserve\">\n    <value>Найдено несколько пакетов, соответствующих условиям</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_MANIFEST_FOUND\" xml:space=\"preserve\">\n    <value>Соответствующих условиям манифестов не найдено</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXTENSION_PUBLIC_FAILED\" xml:space=\"preserve\">\n    <value>Не удалось получить общедоступную папку из исходного пакета</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMMAND_REQUIRES_ADMIN\" xml:space=\"preserve\">\n    <value>Для выполнения команды требуются права администратора</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NOT_SECURE\" xml:space=\"preserve\">\n    <value>Исходное расположение не защищено</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>Клиент Microsoft Store заблокирован политикой</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_APP_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>Приложение Microsoft Store заблокировано политикой</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXPERIMENTAL_FEATURE_DISABLED\" xml:space=\"preserve\">\n    <value>Эта функция сейчас находится в разработке. Его можно включить с помощью параметров winget.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Не удалось установить приложение Microsoft Store</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMPLETE_INPUT_BAD\" xml:space=\"preserve\">\n    <value>Не удалось выполнить автозаполнение</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED\" xml:space=\"preserve\">\n    <value>Не удается инициализировать средство синтаксического анализа YAML</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_MAPPING_KEY\" xml:space=\"preserve\">\n    <value>Обнаружен недопустимый ключ YAML</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY\" xml:space=\"preserve\">\n    <value>Обнаружен повторяющийся ключ YAML</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_OPERATION\" xml:space=\"preserve\">\n    <value>Недопустимая операция YAML</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_DOC_BUILD_FAILED\" xml:space=\"preserve\">\n    <value>Не удалось создать документ YAML</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_EMITTER_STATE\" xml:space=\"preserve\">\n    <value>Недопустимое состояние передатчика YAML</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_DATA\" xml:space=\"preserve\">\n    <value>Недопустимые данные YAML</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LIBYAML_ERROR\" xml:space=\"preserve\">\n    <value>Ошибка LibYAML</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_WARNING\" xml:space=\"preserve\">\n    <value>Проверка манифеста завершена с предупреждениями</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_FAILURE\" xml:space=\"preserve\">\n    <value>Ошибка проверки манифеста</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_MANIFEST\" xml:space=\"preserve\">\n    <value>Недопустимый манифест</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>Применимые обновления не найдены</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPDATE_ALL_HAS_FAILURE\" xml:space=\"preserve\">\n    <value>Команда winget upgrade --all завершилась с ошибками</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_SECURITY_CHECK_FAILED\" xml:space=\"preserve\">\n    <value>Установщик не прошел проверку безопасности</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_SIZE_MISMATCH\" xml:space=\"preserve\">\n    <value>Размер скачиваемого файла не соответствует ожидаемому размеру содержимого</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_UNINSTALL_INFO_FOUND\" xml:space=\"preserve\">\n    <value>Команда удаления не найдена</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXEC_UNINSTALL_COMMAND_FAILED\" xml:space=\"preserve\">\n    <value>Не удалось выполнить команду удаления</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_BREAK_ITERATOR_ERROR\" xml:space=\"preserve\">\n    <value>Ошибка итератора прерывания ICU</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_CASEMAP_ERROR\" xml:space=\"preserve\">\n    <value>Ошибка сопоставления регистра ICU</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_REGEX_ERROR\" xml:space=\"preserve\">\n    <value>Ошибка регулярного выражения ICU</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_IMPORT_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Не удалось установить один или несколько импортированных пакетов</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NOT_ALL_PACKAGES_FOUND\" xml:space=\"preserve\">\n    <value>Не удалось найти один или несколько запрошенного пакета</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE\" xml:space=\"preserve\">\n    <value>Недопустимый JSON-файл</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NOT_REMOTE\" xml:space=\"preserve\">\n    <value>Расположение источника не является удаленным</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE\" xml:space=\"preserve\">\n    <value>Настроенный источник REST не поддерживается</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA\" xml:space=\"preserve\">\n    <value>Источник REST вернул недопустимые данные</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>Операция заблокирована групповой политикой</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_INTERNAL_ERROR\" xml:space=\"preserve\">\n    <value>Внутренняя ошибка REST API</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_URL\" xml:space=\"preserve\">\n    <value>Недопустимый URL-адрес источника REST</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_UNSUPPORTED_MIME_TYPE\" xml:space=\"preserve\">\n    <value>REST API вернул неподдерживаемый тип MIME</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_VERSION\" xml:space=\"preserve\">\n    <value>Недопустимая версия контракта источника REST</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE\" xml:space=\"preserve\">\n    <value>Исходные данные повреждены или незаконно изменены</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_STREAM_READ_FAILURE\" xml:space=\"preserve\">\n    <value>Ошибка чтения из потока</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>Соглашения для пакетов не приняты</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PROMPT_INPUT_ERROR\" xml:space=\"preserve\">\n    <value>Ошибка при чтении входных данных в запросе</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST\" xml:space=\"preserve\">\n    <value>Запрос поиска не поддерживается одним или несколькими источниками</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_ENDPOINT_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Конечная точка REST API не найдена.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_OPEN_FAILED\" xml:space=\"preserve\">\n    <value>Не удалось открыть источник.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>Соглашения для источников не приняты</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CUSTOMHEADER_EXCEEDS_MAXLENGTH\" xml:space=\"preserve\">\n    <value>Размер заголовка превышает допустимый предел в 1024 символа. Уменьшите размер и повторите попытку.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MISSING_RESOURCE_FILE\" xml:space=\"preserve\">\n    <value>Отсутствует файл ресурсов</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSI_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Не удалось выполнить установку MSI</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT\" xml:space=\"preserve\">\n    <value>Недопустимые аргументы для msiexec</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FAILED_TO_OPEN_ALL_SOURCES\" xml:space=\"preserve\">\n    <value>Не удалось открыть один или несколько источников</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>Не удалось проверить зависимости</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MISSING_PACKAGE\" xml:space=\"preserve\">\n    <value>Отсутствует один или несколько пакетов</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_TABLE_COLUMN\" xml:space=\"preserve\">\n    <value>Недопустимый столбец таблицы</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_NOT_NEWER\" xml:space=\"preserve\">\n    <value>Версия обновления не новее установленной версии</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_UNKNOWN\" xml:space=\"preserve\">\n    <value>Версия обновления неизвестна, и переопределение не указано</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_CONVERSION_ERROR\" xml:space=\"preserve\">\n    <value>Ошибка преобразования ICU</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Не удалось установить переносимый пакет</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_REPARSE_POINT_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Том не поддерживает точки повторного анализа</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_PACKAGE_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>Переносимый пакет из другого источника уже существует.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_SYMLINK_PATH_IS_DIRECTORY\" xml:space=\"preserve\">\n    <value>Не удалось создать symlink. Путь указывает на каталог.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_PROHIBITS_ELEVATION\" xml:space=\"preserve\">\n    <value>Не удается запустить установщик из контекста администратора.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Не удалось удалить переносимый пакет</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ARP_VERSION_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>Не удалось проверить значения DisplayVersion на соответствие индексу.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_ARGUMENT\" xml:space=\"preserve\">\n    <value>Один или несколько аргументов не поддерживаются.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_BIND_WITH_EMBEDDED_NULL\" xml:space=\"preserve\">\n    <value>Внедренные нуль-символы запрещены для SQLite</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Не удалось найти вложенный установщик в архиве.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXTRACT_ARCHIVE_FAILED\" xml:space=\"preserve\">\n    <value>Не удалось извлечь из архива.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_INVALID_PATH\" xml:space=\"preserve\">\n    <value>Указан недопустимый относительный путь к вложенным установщикам.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PINNED_CERTIFICATE_MISMATCH\" xml:space=\"preserve\">\n    <value>Сертификат сервера не соответствует ни одному из ожидаемых значений.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_LOCATION_REQUIRED\" xml:space=\"preserve\">\n    <value>Необходимо указать папку для установки.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ARCHIVE_SCAN_FAILED\" xml:space=\"preserve\">\n    <value>Не удалось проверить архив на наличие вредоносных программ.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>Найдена по крайней мере одна версия установленного пакета.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PIN_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>Закрепление для пакета уже существует.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PIN_DOES_NOT_EXIST\" xml:space=\"preserve\">\n    <value>Нет закрепления для пакета.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_OPEN_PINNING_INDEX\" xml:space=\"preserve\">\n    <value>Не удалось открыть базу данных закреплений.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Не удалось установить одно или несколько приложений</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Не удалось удалить одно или несколько приложений</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NOT_ALL_QUERIES_FOUND_SINGLE\" xml:space=\"preserve\">\n    <value>Один или несколько запросов вернули больше одного совпадения</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_PINNED\" xml:space=\"preserve\">\n    <value>Пакет защищен ПИН-кодом, что не позволяет выполнить обновление.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB\" xml:space=\"preserve\">\n    <value>Установленный пакет является заглушкой</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_APPTERMINATION_RECEIVED\" xml:space=\"preserve\">\n    <value>Получен сигнал завершения работы приложения</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_DEPENDENCIES\" xml:space=\"preserve\">\n    <value>Не удалось скачать зависимости пакета.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_COMMAND_PROHIBITED\" xml:space=\"preserve\">\n    <value>Не удалось скачать пакет. Скачивание для автономной установки запрещено.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SERVICE_UNAVAILABLE\" xml:space=\"preserve\">\n    <value>Требуемая служба занята или недоступна. Повторите попытку позже.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESUME_ID_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Указанный GUID не соответствует допустимому состоянию возобновления.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CLIENT_VERSION_MISMATCH\" xml:space=\"preserve\">\n    <value>Текущая версия клиента не соответствует версии клиента сохраненного состояния.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_RESUME_STATE\" xml:space=\"preserve\">\n    <value>Недопустимые данные о состоянии возобновления.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_OPEN_CHECKPOINT_INDEX\" xml:space=\"preserve\">\n    <value>Не удалось открыть базу данных контрольных точек.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESUME_LIMIT_EXCEEDED\" xml:space=\"preserve\">\n    <value>Превышено максимальное ограничение возобновления.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_AUTHENTICATION_INFO\" xml:space=\"preserve\">\n    <value>Неверные сведения для проверки подлинности.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Метод проверки подлинности не поддерживается.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED\" xml:space=\"preserve\">\n    <value>Произошел сбой проверки подлинности.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_INTERACTIVE_REQUIRED\" xml:space=\"preserve\">\n    <value>Сбой проверки подлинности. Требуется интерактивная проверка подлинности.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_CANCELLED_BY_USER\" xml:space=\"preserve\">\n    <value>Сбой проверки подлинности. Отменено пользователем.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_INCORRECT_ACCOUNT\" xml:space=\"preserve\">\n    <value>Сбой проверки подлинности. Прошедшая проверку подлинности учетная запись не подходит.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE\" xml:space=\"preserve\">\n    <value>Приложение сейчас запущено. Выйдите из приложения и повторите попытку.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INSTALL_IN_PROGRESS\" xml:space=\"preserve\">\n    <value>Уже выполняется другая установка. Повторите попытку позже.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_FILE_IN_USE\" xml:space=\"preserve\">\n    <value>Используется один или несколько файлов. Выйдите из приложения и повторите попытку.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_MISSING_DEPENDENCY\" xml:space=\"preserve\">\n    <value>У этого пакета отсутствует зависимость в вашей системе.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DISK_FULL\" xml:space=\"preserve\">\n    <value>На вашем компьютере больше нет места. Освободите место и повторите попытку.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INSUFFICIENT_MEMORY\" xml:space=\"preserve\">\n    <value>Недостаточно памяти для установки. Закройте другие приложения и повторите попытку.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_NO_NETWORK\" xml:space=\"preserve\">\n    <value>Для этого приложения требуется подключение к Интернету. Подключитесь к сети и повторите попытку.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CONTACT_SUPPORT\" xml:space=\"preserve\">\n    <value>Приложение обнаружило ошибку во время установки. Обратитесь в службу поддержки.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_TO_FINISH\" xml:space=\"preserve\">\n    <value>Перезапустите компьютер, чтобы завершить установку.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_FOR_INSTALL\" xml:space=\"preserve\">\n    <value>Сбой установки. Перезагрузите компьютер и повторите попытку.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_INITIATED\" xml:space=\"preserve\">\n    <value>Ваш компьютер будет перезагружен, чтобы завершить установку.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CANCELLED_BY_USER\" xml:space=\"preserve\">\n    <value>Вы отменили установку.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>Уже установлена другая версия этого приложения.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DOWNGRADE\" xml:space=\"preserve\">\n    <value>Уже установлена более поздняя версия этого приложения.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>Установка запрещена политиками организации. Обратитесь к администратору.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DEPENDENCIES\" xml:space=\"preserve\">\n    <value>Не удалось установить зависимости пакета.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE_BY_APPLICATION\" xml:space=\"preserve\">\n    <value>Приложение сейчас используется другим приложением.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INVALID_PARAMETER\" xml:space=\"preserve\">\n    <value>Недопустимый параметр.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Пакет не поддерживается системой.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_UPGRADE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Установщик не поддерживает обновление существующего пакета.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CUSTOM_ERROR\" xml:space=\"preserve\">\n    <value>Установка завершилась сбоем из-за ошибки пользовательского установщика.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_ARP_ENTRY_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Не удалось найти запись \"Приложения и компоненты\" для пакета.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>Расположение установки неприменимо.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Не удалось найти расположение установки.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_HASH_MISMATCH\" xml:space=\"preserve\">\n    <value>Хэш существующего файла не совпадает.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Файл не найден.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK\" xml:space=\"preserve\">\n    <value>Файл найден, но хэш не был проверен.</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_ACCESS_ERROR\" xml:space=\"preserve\">\n    <value>Не удалось получить доступ к файлу.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE\" xml:space=\"preserve\">\n    <value>Файл конфигурации недопустим.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_YAML\" xml:space=\"preserve\">\n    <value>Синтаксис YAML недопустим.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_FIELD_TYPE\" xml:space=\"preserve\">\n    <value>Поле конфигурации относится к недопустимому типу.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION\" xml:space=\"preserve\">\n    <value>Версия конфигурации неизвестна.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_SET_APPLY_FAILED\" xml:space=\"preserve\">\n    <value>Произошла ошибка при применении конфигурации.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER\" xml:space=\"preserve\">\n    <value>Конфигурация содержит повторяющийся идентификатор.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MISSING_DEPENDENCY\" xml:space=\"preserve\">\n    <value>В конфигурации отсутствует зависимость.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED\" xml:space=\"preserve\">\n    <value>В конфигурации есть неудовлетворенная зависимость.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_ASSERTION_FAILED\" xml:space=\"preserve\">\n    <value>Сбой утверждения для блока конфигурации.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MANUALLY_SKIPPED\" xml:space=\"preserve\">\n    <value>Конфигурация пропущена вручную.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_WARNING_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>Пользователь отклонил продолжение выполнения.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_SET_DEPENDENCY_CYCLE\" xml:space=\"preserve\">\n    <value>Этот граф зависимостей содержит цикл, который невозможно разрешить.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_FIELD_VALUE\" xml:space=\"preserve\">\n    <value>В конфигурации есть недопустимое значение поля.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MISSING_FIELD\" xml:space=\"preserve\">\n    <value>В конфигурации отсутствует поле.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_TEST_FAILED\" xml:space=\"preserve\">\n    <value>Сбой некоторых модулей конфигурации при проверке их состояния.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_TEST_NOT_RUN\" xml:space=\"preserve\">\n    <value>Состояние конфигурации не протестировано.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_NOT_INSTALLED\" xml:space=\"preserve\">\n    <value>Блок конфигурации не установлен.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_NOT_FOUND_REPOSITORY\" xml:space=\"preserve\">\n    <value>Не удалось найти блок конфигурации.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_MULTIPLE_MATCHES\" xml:space=\"preserve\">\n    <value>Обнаружено несколько соответствий для единицы конфигурации; укажите модуль, чтобы выбрать правильный модуль.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_GET\" xml:space=\"preserve\">\n    <value>Сбой единицы конфигурации при попытке получить текущее состояние системы.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_TEST\" xml:space=\"preserve\">\n    <value>Сбой единицы конфигурации при попытке проверить текущее состояние системы.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_SET\" xml:space=\"preserve\">\n    <value>Сбой блока конфигурации при попытке применить нужное состояние.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_MODULE_CONFLICT\" xml:space=\"preserve\">\n    <value>Модуль для блока конфигурации доступен в нескольких расположениях с одинаковой версией.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE\" xml:space=\"preserve\">\n    <value>Не удалось загрузить модуль для единицы конфигурации.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_INVALID_RESULT\" xml:space=\"preserve\">\n    <value>Модуль конфигурации вернул непредвиденный результат во время выполнения.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_SETTING_CONFIG_ROOT\" xml:space=\"preserve\">\n    <value>Блок содержит параметр, требующий корня конфигурации.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR\" xml:space=\"preserve\">\n    <value>Операция не поддерживается обработчиком конфигурации.</value>\n  </data>\n  <data name=\"Unavailable\" xml:space=\"preserve\">\n    <value>Недоступно</value>\n  </data>\n  <data name=\"EnableWindowsFeaturesSuccess\" xml:space=\"preserve\">\n    <value>Зависимости компонентов Windows включены</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE_ADMIN\" xml:space=\"preserve\">\n    <value>Не удалось загрузить модуль для единицы конфигурации, так как для его запуска требуются права администратора.</value>\n  </data>\n  <data name=\"ConfigurationUnitSettingConfigRoot\" xml:space=\"preserve\">\n    <value>Блок содержит параметр, требующий корня конфигурации.</value>\n  </data>\n  <data name=\"ConfigurationUnitImportModuleAdmin\" xml:space=\"preserve\">\n    <value>Не удалось загрузить модуль для единицы конфигурации, так как для его запуска требуются права администратора.</value>\n  </data>\n  <data name=\"ResumeCommandLongDescription\" xml:space=\"preserve\">\n    <value>Возобновление выполнения ранее сохраненной команды путем передачи уникального идентификатора сохраненной команды. Используется для возобновления выполнения команды, которая может быть прервана из-за перезагрузки.</value>\n  </data>\n  <data name=\"ResumeCommandShortDescription\" xml:space=\"preserve\">\n    <value>Возобновление выполнения ранее сохраненной команды.</value>\n  </data>\n  <data name=\"ResumeIdArgumentDescription\" xml:space=\"preserve\">\n    <value>Уникальный идентификатор сохраненного состояния для возобновления</value>\n  </data>\n  <data name=\"ClientVersionMismatchError\" xml:space=\"preserve\">\n    <value>Возобновление состояния из другой версии клиента не поддерживается: {0}</value>\n    <comment>{Locked= \"{0}\"} Message displayed to inform the user that the client version of the resume state does not match the current client version. {0} is a placeholder for the client version that created the resume state.</comment>\n  </data>\n  <data name=\"ResumeIdNotFoundError\" xml:space=\"preserve\">\n    <value>Состояние возобновления не существует: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a guid that does not correspond to a valid saved state. {0} is a placeholder replaced by the provided guid string.</comment>\n  </data>\n  <data name=\"ResumeStateDataNotFoundError\" xml:space=\"preserve\">\n    <value>Не найдены данные в состоянии возобновления.</value>\n  </data>\n  <data name=\"CommandDoesNotSupportResumeMessage\" xml:space=\"preserve\">\n    <value>Эта команда не поддерживает возобновление.</value>\n  </data>\n  <data name=\"AllowRebootArgumentDescription\" xml:space=\"preserve\">\n    <value>Разрешает перезагрузку, если применимо</value>\n  </data>\n  <data name=\"InitiatingReboot\" xml:space=\"preserve\">\n    <value>Запуск перезагрузки для завершения операции...</value>\n  </data>\n  <data name=\"FailedToInitiateReboot\" xml:space=\"preserve\">\n    <value>Не удалось инициировать перезагрузку.</value>\n  </data>\n  <data name=\"ResumeLimitExceeded\" xml:space=\"preserve\">\n    <value>Операция возобновления превышает допустимый предел {0} возобновления. Чтобы возобновить работу вручную, выполните команду \"{1}\".</value>\n    <comment>{Locked=\"{0}\", \"{1}\"} {0} is a placeholder that is replaced by an integer number of the number of allowed resumes. {1} is a placeholder for the command to run to perform a manual resume.</comment>\n  </data>\n  <data name=\"IgnoreResumeLimitArgumentDescription\" xml:space=\"preserve\">\n    <value>Игнорировать ограничение на возобновление сохраненного состояния</value>\n  </data>\n  <data name=\"UriSchemeNotSupported\" xml:space=\"preserve\">\n    <value>Схема URI не поддерживается: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the provided uri is not supported. {0} is a placeholder replaced by the provided uri.</comment>\n  </data>\n  <data name=\"UriNotWellFormed\" xml:space=\"preserve\">\n    <value>Неправильный формат URI: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the provided uri is not well formed. {0} is a placeholder replaced by the provided uri.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitEmptyContent\" xml:space=\"preserve\">\n    <value>Не удалось проанализировать {0} содержимое параметров единицы конфигурации или содержимое параметров пусто.</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder replaced by the input winget configure resource unit type.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitMissingRequiredArg\" xml:space=\"preserve\">\n    <value>В блоке конфигурации {0} отсутствует требуемый аргумент: {1}</value>\n    <comment>{Locked=\"{0},{1}\"} {0} is a placeholder for the input winget configure resource unit type. {1} is placeholder for the missing arg.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitMissingRecommendedArg\" xml:space=\"preserve\">\n    <value>В блоке конфигурации {0} отсутствует рекомендуемый аргумент: {1}</value>\n    <comment>{Locked=\"{0},{1}\"} {0} is a placeholder for the input winget configure resource unit type. {1} is placeholder for the missing arg.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitKnownSourceConfliction\" xml:space=\"preserve\">\n    <value>Блок конфигурации WinGetSource конфликтует с известным источником: {0}</value>\n    <comment>{Locked=\"WinGetSource,{0}\"} {0} is a placeholder for the input winget source in the configuration unit settings.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitThirdPartySourceAssertion\" xml:space=\"preserve\">\n    <value>Блок конфигурации WinGetSource утверждает сторонний источник: {0}</value>\n    <comment>{Locked=\"WinGetSource,{0}\"} {0} is a placeholder for the input winget source in the configuration unit settings.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitBothPackageVersionAndUseLatest\" xml:space=\"preserve\">\n    <value>WinGetPackage объявляет UseLatest и Version. Идентификатор пакета: {0}</value>\n    <comment>{Locked=\"WinGetPackage,UseLatest,Version,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitThirdPartySourceAssertionForPackage\" xml:space=\"preserve\">\n    <value>Единица конфигурации WinGetPackage утверждает пакет из стороннего источника. Идентификатор пакета: {0}; Источник: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitDependencySourceNotConfigured\" xml:space=\"preserve\">\n    <value>Пакет единиц конфигурации WinGetPackage зависит от стороннего источника, не настроенного ранее. Идентификатор пакета: {0}; Источник: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitDependencySourceNotDeclaredAsDependency\" xml:space=\"preserve\">\n    <value>Пакет единиц конфигурации WinGetPackage зависит от стороннего источника. Рекомендуется объявить зависимость в разделе uni dependsOn. Идентификатор пакета: {0}; Источник: {1}</value>\n    <comment>{Locked=\"WinGetPackage,dependsOn,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageSourceOpenFailed\" xml:space=\"preserve\">\n    <value>Не удается проверить пакет единиц конфигурации WinGetPackage. Не удалось открыть источник. Идентификатор пакета: {0}; Источник: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageNotFound\" xml:space=\"preserve\">\n    <value>Не удается проверить пакет единиц конфигурации WinGetPackage. Пакет не найден. Идентификатор пакета: {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageMultipleFound\" xml:space=\"preserve\">\n    <value>Не удается проверить пакет единиц конфигурации WinGetPackage. Найдено несколько пакетов. Идентификатор пакета: {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageVersionNotFound\" xml:space=\"preserve\">\n    <value>Не удается проверить пакет единиц конфигурации WinGetPackage. Версия пакета не найдена. Идентификатор пакета: {0}; Версия {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitPackageVersionSpecifiedWithOnlyOnePackageVersion\" xml:space=\"preserve\">\n    <value>Пакет блока конфигурации WinGetPackage указан с определенной версией, но доступна только одна версия пакета. Идентификатор пакета:{0}; версия: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackage\" xml:space=\"preserve\">\n    <value>Не удается проверить пакет единиц конфигурации WinGetPackage. Идентификатор пакета: {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"AuthenticationModeArgumentDescription\" xml:space=\"preserve\">\n    <value>Укажите предпочтительный режим окна проверки подлинности (silent, silentPreferred или interactive)</value>\n    <comment>{Locked=\"silent\",\"silentPreferred\",\"interactive\"} This argument allows the user to select authentication window popup behavior.</comment>\n  </data>\n  <data name=\"AuthenticationAccountArgumentDescription\" xml:space=\"preserve\">\n    <value>Укажите учетную запись, которая будет использоваться для проверки подлинности</value>\n  </data>\n  <data name=\"SourceAddFailedAuthenticationNotSupported\" xml:space=\"preserve\">\n    <value>Не удалось добавить источник. Эта winget не поддерживает метод проверки подлинности источника. Попробуйте обновиться до последней winget версии.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"SourceRequiresAuthentication\" xml:space=\"preserve\">\n    <value>Источник {0} требует проверки подлинности. При необходимости может появиться запрос проверки подлинности. Сведения, прошедшие проверку подлинности, будут предоставлены источнику для авторизации доступа.</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"RepairCommandLongDescription\" xml:space=\"preserve\">\n    <value>Восстановление выбранного пакета путем поиска в списке установленных пакетов или непосредственно из манифеста. По умолчанию запрос должен без учета регистра совпадать с идентификатором, именем или моникером пакета. Другие поля можно использовать путем передачи соответствующего параметра.</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"RepairCommandShortDescription\" xml:space=\"preserve\">\n    <value>Восстановление выбранного пакета</value>\n  </data>\n  <data name=\"NoRepairInfoFound\" xml:space=\"preserve\">\n    <value>Не удается найти команду восстановления для этого пакета. Обратитесь за поддержкой к издателю пакета.</value>\n  </data>\n  <data name=\"RepairDifferentInstallTechnology\" xml:space=\"preserve\">\n    <value>Используемая технология установщика не соответствует установленной версии.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_REPAIR_INFO_FOUND\" xml:space=\"preserve\">\n    <value>Команда восстановления не найдена.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_REPAIR_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Используемая технология установщика не поддерживает восстановление.</value>\n  </data>\n  <data name=\"RepairFlowRepairSuccess\" xml:space=\"preserve\">\n    <value>Операция восстановления успешно завершена.</value>\n  </data>\n  <data name=\"RepairAbandoned\" xml:space=\"preserve\">\n    <value>Восстановление прервано</value>\n  </data>\n  <data name=\"RepairFlowStartingPackageRepair\" xml:space=\"preserve\">\n    <value>Запуск восстановления пакета...</value>\n  </data>\n  <data name=\"MSStoreRepairFailed\" xml:space=\"preserve\">\n    <value>Не удалось восстановить пакет Microsoft Store. Код ошибки: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Microsoft Store application package fails to repair. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXEC_REPAIR_FAILED\" xml:space=\"preserve\">\n    <value>Не удалось выполнить операцию восстановления.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_REPAIR_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>Операция восстановления неприменима.</value>\n  </data>\n  <data name=\"RepairFlowNoMatchingVersion\" xml:space=\"preserve\">\n    <value>В настроенных источниках недоступны соответствующие версии пакетов.</value>\n  </data>\n  <data name=\"RepairFlowReturnCodeSystemNotSupported\" xml:space=\"preserve\">\n    <value>Текущая конфигурация системы не поддерживает восстановление этого пакета.</value>\n  </data>\n  <data name=\"RepairOperationNotSupported\" xml:space=\"preserve\">\n    <value>Используемая технология установщика не поддерживает восстановление.</value>\n  </data>\n  <data name=\"NoAdminRepairForUserScopePackage\" xml:space=\"preserve\">\n    <value>Пакет, установленный для область не может быть восстановлен при выполнении с правами администратора.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED\" xml:space=\"preserve\">\n    <value>Операции восстановления с правами администратора не разрешены для пакетов, установленных в пользовательском область.</value>\n  </data>\n  <data name=\"RepairFailedWithCode\" xml:space=\"preserve\">\n    <value>Сбой восстановления с кодом выхода: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to repair an application package fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SQLITE_CONNECTION_TERMINATED\" xml:space=\"preserve\">\n    <value>Подключение SQLite было разорвано для предотвращения повреждения.</value>\n  </data>\n  <data name=\"UninstallAllVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>Удалить все версии</value>\n  </data>\n  <data name=\"TargetVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>Версия для действий</value>\n  </data>\n  <data name=\"UninstallFailedDueToMultipleVersions\" xml:space=\"preserve\">\n    <value>Установлено несколько версий этого пакета. Уточните условия поиска, передайте аргумент \"--version\", чтобы выбрать его, или передайте флаг \"--all-versions\", чтобы удалить все из них.</value>\n    <comment>{Locked=\"--version,--all-versions\"}</comment>\n  </data>\n  <data name=\"PolicyEnableProxyCommandLineOptions\" xml:space=\"preserve\">\n    <value>Включить Диспетчер пакетов Windows командной строки прокси-сервера</value>\n    <comment>Describes a Group Policy that can enable the use of the --proxy option to set a proxy</comment>\n  </data>\n  <data name=\"ProxyArgumentDescription\" xml:space=\"preserve\">\n    <value>Задать прокси-сервер для этого выполнения</value>\n  </data>\n  <data name=\"NoProxyArgumentDescription\" xml:space=\"preserve\">\n    <value>Отключить использование прокси-сервера для этого выполнения</value>\n  </data>\n  <data name=\"ResetAdminSettingFailed\" xml:space=\"preserve\">\n    <value>Не удается сбросить {0}. Этот параметр управляется политикой. Для получения дополнительных сведений обратитесь к системному администратору.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"ResetAdminSettingSucceeded\" xml:space=\"preserve\">\n    <value>Сброс параметра администратора \"{0}\".</value>\n    <comment>{Locked=\"{0}\"} Message displayed after the user resets an admin setting to its default value. Reset is used as verb in past tense. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"SetAdminSettingFailed\" xml:space=\"preserve\">\n    <value>Невозможно задать {0}. Этот параметр управляется политикой. Для получения дополнительных сведений обратитесь к системному администратору.</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"SetAdminSettingSucceeded\" xml:space=\"preserve\">\n    <value>Задайте для параметра администратора \"{0}\" значение \"{1}\".</value>\n    <comment>{Locked=\"{0}\"} Message displayed after the user sets the value of an admin setting. Set is used as a verb in past tense. {0} is a placeholder replaced by the setting name. {1} is a placeholder replaced </comment>\n  </data>\n  <data name=\"SettingNameArgumentDescription\" xml:space=\"preserve\">\n    <value>Имя изменяемого параметра</value>\n  </data>\n  <data name=\"SettingValueArgumentDescription\" xml:space=\"preserve\">\n    <value>Значение, настраиваемое для параметра.</value>\n  </data>\n  <data name=\"SettingsResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>Сбрасывает значение по умолчанию для параметра администратора.</value>\n  </data>\n  <data name=\"SettingsResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>Сбрасывает значение по умолчанию для параметра администратора.</value>\n  </data>\n  <data name=\"SettingsSetCommandLongDescription\" xml:space=\"preserve\">\n    <value>Задает значение параметра администратора.</value>\n  </data>\n  <data name=\"SettingsSetCommandShortDescription\" xml:space=\"preserve\">\n    <value>Задает значение параметра администратора.</value>\n  </data>\n  <data name=\"SourceExplicitArgumentDescription\" xml:space=\"preserve\">\n    <value>Исключает источник из обнаружения, если не указано</value>\n  </data>\n  <data name=\"SourceEditExplicitArgumentDescription\" xml:space=\"preserve\">\n    <value>Исключить источник из обнаружения (true или false)</value>\n  </data>\n  <data name=\"SourceListExplicit\" xml:space=\"preserve\">\n    <value>Возрастные ограничения</value>\n  </data>\n  <data name=\"SourceTrustLevelArgumentDescription\" xml:space=\"preserve\">\n    <value>Уровень доверия источника (нет или недоверенный)</value>\n  </data>\n  <data name=\"SourceListTrustLevel\" xml:space=\"preserve\">\n    <value>Уровень доверия</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DISPLAYCATALOG_API_FAILED\" xml:space=\"preserve\">\n    <value>Не удалось получить каталог пакетов Microsoft Store.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_DISPLAYCATALOG_PACKAGE\" xml:space=\"preserve\">\n    <value>Применимый пакет Microsoft Store не найден в каталоге пакетов Microsoft Store.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SFSCLIENT_API_FAILED\" xml:space=\"preserve\">\n    <value>Не удалось получить сведения о скачивании пакета Microsoft Store.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_SFSCLIENT_PACKAGE\" xml:space=\"preserve\">\n    <value>Не найден применимый Microsoft Store для скачивания.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED\" xml:space=\"preserve\">\n    <value>Не удалось получить лицензию пакета Microsoft Store.</value>\n  </data>\n  <data name=\"MSStoreDownloadNoApplicablePackageFound\" xml:space=\"preserve\">\n    <value>Применимый пакет Microsoft Store не найден.</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageHashVerified\" xml:space=\"preserve\">\n    <value>Хэш пакета Microsoft Store успешно проверен</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageHashMismatch\" xml:space=\"preserve\">\n    <value>Несоответствие хэша пакета Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloaded\" xml:space=\"preserve\">\n    <value>Пакет Microsoft Store скачан: {0}</value>\n    <comment>{Locked=\"{0}\"} Full path of the downloaded package.</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadFailed\" xml:space=\"preserve\">\n    <value>Не удалось скачать пакет Microsoft Store: {0}</value>\n    <comment>{Locked=\"{0}\"} Package name.</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadSuccess\" xml:space=\"preserve\">\n    <value>Скачивание пакета Microsoft Store завершено</value>\n  </data>\n  <data name=\"MSStoreDownloadMainPackages\" xml:space=\"preserve\">\n    <value>Скачивание основных пакетов из Microsoft Store...</value>\n  </data>\n  <data name=\"MSStoreDownloadDependencyPackages\" xml:space=\"preserve\">\n    <value>Скачивание пакетов зависимостей из Microsoft Store...</value>\n  </data>\n  <data name=\"MSStoreDownloadGetDownloadInfo\" xml:space=\"preserve\">\n    <value>Получение сведений о скачивании пакета Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadGetDownloadInfoFailed\" xml:space=\"preserve\">\n    <value>Не удалось получить сведения о скачивании пакета Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadGetLicense\" xml:space=\"preserve\">\n    <value>Получение лицензии пакета Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseSuccess\" xml:space=\"preserve\">\n    <value>Лицензия пакета Microsoft Store сохранена: {0}</value>\n    <comment>{Locked=\"{0}\"} License file full path.</comment>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseFailed\" xml:space=\"preserve\">\n    <value>Не удалось получить лицензию пакета Microsoft Store</value>\n  </data>\n  <data name=\"MSStoreDownloadRenameNotSupported\" xml:space=\"preserve\">\n    <value>Скачивание пакета Microsoft Store не поддерживает аргумент --rename. Пакет Microsoft Store будет использовать имена, предоставленные каталогом Microsoft Store.</value>\n    <comment>{Locked=\"--rename\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadAuthenticationNotice\" xml:space=\"preserve\">\n    <value>Microsoft Store загрузки пакета требуется Microsoft Entra проверки подлинности. При необходимости может появиться запрос проверки подлинности. Сведения, прошедшие проверку подлинности, будут предоставлены службы Майкрософт для авторизации доступа. Для Microsoft Store лицензирования пакетов учетная запись Microsoft Entra идентификатора должна быть членом глобального администратора, администратора пользователей или администратора лицензий.</value>\n    <comment>{Locked=\"Global Administrator,User Administrator,License Administrator\"}</comment>\n  </data>\n  <data name=\"SkipMicrosoftStorePackageLicenseArgumentDescription\" xml:space=\"preserve\">\n    <value>Пропускает получение автономной лицензии пакета Microsoft Store</value>\n  </data>\n  <data name=\"PlatformArgumentDescription\" xml:space=\"preserve\">\n    <value>Выбор целевой платформы</value>\n  </data>\n  <data name=\"ConfigurationExportAddingToFile\" xml:space=\"preserve\">\n    <value>Добавление файла конфигурации: {0}</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportSuccessful\" xml:space=\"preserve\">\n    <value>Экспорт успешно выполнен</value>\n  </data>\n  <data name=\"ConfigurationGettingResourceSettings\" xml:space=\"preserve\">\n    <value>Получение параметров конфигурации...</value>\n  </data>\n  <data name=\"ConfigureExportArgumentRequiredError\" xml:space=\"preserve\">\n    <value>Необходимо указать хотя бы --packageId и (или) --module с параметром --resource. Либо используйте --all для экспорта всех конфигураций пакетов.</value>\n    <comment>{Locked=\"--packageId,--module, --resource, --all\"}</comment>\n  </data>\n  <data name=\"ConfigureExportArgumentConflictWithAllError\" xml:space=\"preserve\">\n    <value>Аргументы --packageId, --module и --resource нельзя использовать с параметром --all.</value>\n    <comment>{Locked=\"--packageId,--module, --resource, --all\"}</comment>\n  </data>\n  <data name=\"ConfigureExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>Экспорт ресурсов конфигурации в файл конфигурации. При использовании с --all выполняется экспорт всех конфигураций пакетов. При использовании с --packageId выполняется экспорт ресурса WinGetPackage указанного идентификатора пакета. При использовании с --module и --resource обеспечивается получение параметров ресурса и его экспорт в файл конфигурации. Если выходной файл конфигурации уже существует, добавляет экспортированные ресурсы конфигурации.</value>\n    <comment>{Locked=\"WinGetPackage,--packageId,--module, --resource\"}</comment>\n  </data>\n  <data name=\"ConfigureExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>Экспорт ресурсов конфигурации в файл конфигурации.</value>\n  </data>\n  <data name=\"ConfigureExportModule\" xml:space=\"preserve\">\n    <value>Модуль ресурса для экспорта.</value>\n  </data>\n  <data name=\"ConfigureExportPackageId\" xml:space=\"preserve\">\n    <value>Идентификатор пакета для экспорта.</value>\n  </data>\n  <data name=\"ConfigureExportResource\" xml:space=\"preserve\">\n    <value>Ресурс конфигурации для экспорта.</value>\n  </data>\n  <data name=\"ConfigureExportAll\" xml:space=\"preserve\">\n    <value>Экспортирует все конфигурации пакетов.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_GET_FAILED\" xml:space=\"preserve\">\n    <value>Единице конфигурации не удалось получить свойства.</value>\n  </data>\n  <data name=\"ConfigurationExportFailed\" xml:space=\"preserve\">\n    <value>Не удалось экспортировать конфигурацию.</value>\n  </data>\n  <data name=\"ConfigureExportUnitDescription\" xml:space=\"preserve\">\n    <value>{0}: настройка</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigureExportUnitInstallDescription\" xml:space=\"preserve\">\n    <value>Установить {0}</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationWarningSetViewTruncated\" xml:space=\"preserve\">\n    <value>Некоторые данные в файле конфигурации были усечены для этого вывода; проверьте содержимое файла на наличие полного содержимого.</value>\n  </data>\n  <data name=\"ConfigurationWarningValueTruncated\" xml:space=\"preserve\">\n    <value>&lt;это значение было усечено; проверьте содержимое файла на наличие полного текста&gt;</value>\n    <comment>Keep some form of separator like the \"&lt;&gt;\" around the text so that it stands out from the preceding text.</comment>\n  </data>\n  <data name=\"ConfigureListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Отображение сведений о конфигурациях высокого уровня, которые были применены к системе. Эти данные можно использовать с командами `configure` для получения дополнительных сведений.</value>\n    <comment>{Locked=\"`configure`\"}</comment>\n  </data>\n  <data name=\"ConfigureListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Отображает журнал конфигурации</value>\n  </data>\n  <data name=\"ConfigurationHistoryEmpty\" xml:space=\"preserve\">\n    <value>В журнале нет конфигураций.</value>\n  </data>\n  <data name=\"ConfigurationHistoryItemArgumentDescription\" xml:space=\"preserve\">\n    <value>Выбор элементов из журнала</value>\n  </data>\n  <data name=\"ConfigurationHistoryItemNotFound\" xml:space=\"preserve\">\n    <value>Не удалось найти одну конфигурацию, соответствующую предоставленным данным. Укажите полное имя или часть идентификатора, однозначно соответствующую требуемой конфигурации.</value>\n  </data>\n  <data name=\"ConfigurationHistoryRemoveArgumentDescription\" xml:space=\"preserve\">\n    <value>Удалить элемент из журнала</value>\n  </data>\n  <data name=\"ConfigureListFirstApplied\" xml:space=\"preserve\">\n    <value>Первое применение</value>\n    <comment>Column header for date values indicating when a configuration was first applied to the system.</comment>\n  </data>\n  <data name=\"ConfigureListIdentifier\" xml:space=\"preserve\">\n    <value>Идентификатор</value>\n  </data>\n  <data name=\"ConfigureListName\" xml:space=\"preserve\">\n    <value>Имя</value>\n  </data>\n  <data name=\"ConfigureListOrigin\" xml:space=\"preserve\">\n    <value>Источник</value>\n  </data>\n  <data name=\"ConfigureListPath\" xml:space=\"preserve\">\n    <value>Путь</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_HISTORY_ITEM_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Не удалось найти указанную конфигурацию.</value>\n  </data>\n  <data name=\"ConfigurationSetStateCompleted\" xml:space=\"preserve\">\n    <value>Завершено</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStateInProgress\" xml:space=\"preserve\">\n    <value>Выполняется</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStatePending\" xml:space=\"preserve\">\n    <value>Ожидание</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStateUnknown\" xml:space=\"preserve\">\n    <value>Неизвестно</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationStatusWatchArgumentDescription\" xml:space=\"preserve\">\n    <value>Отслеживайте состояние конфигурации.</value>\n    <comment>As in \"to monitor the status of a configuration being applied\".</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateCompleted\" xml:space=\"preserve\">\n    <value>Завершено</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateInProgress\" xml:space=\"preserve\">\n    <value>Выполняется</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStatePending\" xml:space=\"preserve\">\n    <value>Ожидание</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateSkipped\" xml:space=\"preserve\">\n    <value>Пропущено</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateUnknown\" xml:space=\"preserve\">\n    <value>Неизвестно</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigureListApplyBegun\" xml:space=\"preserve\">\n    <value>Применение начато</value>\n    <comment>When the configuration application started.</comment>\n  </data>\n  <data name=\"ConfigureListApplyEnded\" xml:space=\"preserve\">\n    <value>Применение завершено</value>\n    <comment>When the configuration application ended.</comment>\n  </data>\n  <data name=\"ConfigureListResult\" xml:space=\"preserve\">\n    <value>Результат</value>\n  </data>\n  <data name=\"ConfigureListResultDescription\" xml:space=\"preserve\">\n    <value>Подробности</value>\n  </data>\n  <data name=\"ConfigureListState\" xml:space=\"preserve\">\n    <value>Область/край</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigureListUnit\" xml:space=\"preserve\">\n    <value>Единица</value>\n  </data>\n  <data name=\"StoreInstall_PackageNotAvailableForCurrentSystem\" xml:space=\"preserve\">\n    <value>Пакет несовместим с текущей версией Windows или платформой.</value>\n  </data>\n  <data name=\"ConfigurationSuppressPrologueArgumentDescription\" xml:space=\"preserve\">\n    <value>По возможности не отображать сведения о начальной конфигурации</value>\n  </data>\n  <data name=\"MSStoreDownloadMultiplePackagesNotice\" xml:space=\"preserve\">\n    <value>Можно Microsoft Store несколько пакетов, нацеленных на разные платформы и архитектуры. --platform, --architecture можно использовать для фильтрации пакетов.</value>\n    <comment>{Locked=\"--platform--architecture\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseForbidden\" xml:space=\"preserve\">\n    <value>Не удалось получить Microsoft Store пакета. Учетная Microsoft Entra идентификатора не является членом группы \"Глобальный администратор\", \"Администратор пользователей\" или \"Администратор лицензий\". Используйте --skip-license, чтобы пропустить получение Microsoft Store пакета.</value>\n    <comment>{Locked=\"Global Administrator,User Administrator,License Administrator,--skip-license\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadNotSupported\" xml:space=\"preserve\">\n    <value>Пакет Microsoft Store не поддерживает скачивание.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SFSCLIENT_PACKAGE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Пакет Microsoft Store не поддерживает скачивание.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED_FORBIDDEN\" xml:space=\"preserve\">\n    <value>Не удалось получить Microsoft Store пакета. Учетная Microsoft Entra идентификатора учетной записи не имеет необходимых привилегий.</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_PARAMETER_INTEGRITY_BOUNDARY\" xml:space=\"preserve\">\n    <value>Параметр нельзя передать через границу целостности.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_ZERO_BYTE_FILE\" xml:space=\"preserve\">\n    <value>Скачан установщик нулевого байта. Убедитесь, что ваше сетевое подключение работает правильно.</value>\n  </data>\n  <data name=\"InstallerZeroByteFile\" xml:space=\"preserve\">\n    <value>Скачан установщик нулевого байта. Убедитесь, что ваше сетевое подключение работает правильно.</value>\n  </data>\n  <data name=\"FontCommandShortDescription\" xml:space=\"preserve\">\n    <value>Управление шрифтами</value>\n  </data>\n  <data name=\"FontCommandLongDescription\" xml:space=\"preserve\">\n    <value>Управляйте шрифтами с помощью подкоманд. Шрифты можно устанавливать, обновлять и удалять, как пакеты. </value>\n  </data>\n  <data name=\"FontFamily\" xml:space=\"preserve\">\n    <value>Семейство</value>\n  </data>\n  <data name=\"FontFaces\" xml:space=\"preserve\">\n    <value>Лица</value>\n    <comment>\"Faces\" represents the typeface of the font family such as 'Bold' or 'Italic'</comment>\n  </data>\n  <data name=\"FontFamilyNameArgumentDescription\" xml:space=\"preserve\">\n    <value>Фильтровать результаты по фамилии</value>\n  </data>\n  <data name=\"FontFace\" xml:space=\"preserve\">\n    <value>Лицо</value>\n    <comment>\"Face\" represents the typeface of a font family such as 'Bold' or 'Italic'</comment>\n  </data>\n  <data name=\"FontFilePaths\" xml:space=\"preserve\">\n    <value>Пути</value>\n  </data>\n  <data name=\"NoInstalledFontFound\" xml:space=\"preserve\">\n    <value>Ни один установленный шрифт не соответствует заданному критерию.</value>\n  </data>\n  <data name=\"FontListCommandShortDescription\" xml:space=\"preserve\">\n    <value>Получить список установленных шрифтов</value>\n  </data>\n  <data name=\"FontListCommandLongDescription\" xml:space=\"preserve\">\n    <value>Список всех установленных шрифтов, всех файлов шрифтов или полных сведений о конкретном шрифте.</value>\n  </data>\n  <data name=\"FontVersion\" xml:space=\"preserve\">\n    <value>Версия</value>\n  </data>\n  <data name=\"ConfigurationModules\" xml:space=\"preserve\">\n    <value>Модули конфигурации</value>\n    <comment>PowerShell Modules that are used for the Configuration feature</comment>\n  </data>\n  <data name=\"InstallerDownloadRequiresAuthentication\" xml:space=\"preserve\">\n    <value>Установщику пакета требуется проверка подлинности. При необходимости может появиться запрос проверки подлинности. Сведения, прошедшие проверку подлинности, будут предоставлены с URL-адресом скачивания установщика.</value>\n  </data>\n  <data name=\"InstallerDownloadAuthenticationNotSupported\" xml:space=\"preserve\">\n    <value>Не удалось скачать установщик. Эта winget не поддерживает метод проверки подлинности скачивания установщиком. Попробуйте обновиться до последней winget версии.</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"InstallerDownloadAuthenticationFailed\" xml:space=\"preserve\">\n    <value>Не удалось скачать установщик. Проверка подлинности не пройдена.</value>\n  </data>\n  <data name=\"ConfigurationProcessorPath\" xml:space=\"preserve\">\n    <value>Укажите путь к процессору конфигурации</value>\n  </data>\n  <data name=\"DscCommandShortDescription\" xml:space=\"preserve\">\n    <value>Команды ресурсов DSC v3</value>\n    <comment>DSC stands for \"Desired State Configuration\". It should already have a locked translation.</comment>\n  </data>\n  <data name=\"DscCommandLongDescription\" xml:space=\"preserve\">\n    <value>Вложенные команды реализуют Desired State Configuration (DSC) версии 3 для настройки winget и пакетов.</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionGet\" xml:space=\"preserve\">\n    <value>Получить состояние ресурса</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionSet\" xml:space=\"preserve\">\n    <value>Задать состояние ресурса</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionWhatIf\" xml:space=\"preserve\">\n    <value>Опишите необходимые изменения состояния</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionTest\" xml:space=\"preserve\">\n    <value>Проверьте состояние ресурса</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionDelete\" xml:space=\"preserve\">\n    <value>Удалить состояние ресурса</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionExport\" xml:space=\"preserve\">\n    <value>Получить все экземпляры состояния</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionValidate\" xml:space=\"preserve\">\n    <value>Утвердить контент группы</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionResolve\" xml:space=\"preserve\">\n    <value>Разрешить внешнее состояние</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionAdapter\" xml:space=\"preserve\">\n    <value>Запустить адаптер</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionSchema\" xml:space=\"preserve\">\n    <value>Получить схему ресурсов</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionManifest\" xml:space=\"preserve\">\n    <value>Получить манифест ресурса</value>\n  </data>\n  <data name=\"DscPackageResourceShortDescription\" xml:space=\"preserve\">\n    <value>Управление состоянием пакета</value>\n  </data>\n  <data name=\"DscPackageResourceLongDescription\" xml:space=\"preserve\">\n    <value>Управление пакетами через winget.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionExist\" xml:space=\"preserve\">\n    <value>Указывает, существует экземпляр или должен существовать.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionInDesiredState\" xml:space=\"preserve\">\n    <value>Указывает, находится ли экземпляр в желаемом состоянии.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageId\" xml:space=\"preserve\">\n    <value>Идентификатор пакета.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageSource\" xml:space=\"preserve\">\n    <value>Источник пакета.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageVersion\" xml:space=\"preserve\">\n    <value>Версия пакета.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageMatchOption\" xml:space=\"preserve\">\n    <value>Метод сопоставления идентификатора с пакетом.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageUseLatest\" xml:space=\"preserve\">\n    <value>Укажите, что следует установить последнюю доступную версию пакета.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageInstallMode\" xml:space=\"preserve\">\n    <value>Режим установки, который следует использовать при необходимости.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageScope\" xml:space=\"preserve\">\n    <value>Целевая область пакета.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionAcceptAgreements\" xml:space=\"preserve\">\n    <value>Указывает, следует ли принимать соглашения для источников и пакетов.</value>\n  </data>\n  <data name=\"DscUserSettingsFileShortDescription\" xml:space=\"preserve\">\n    <value>Управление файлом настроек пользователя</value>\n  </data>\n  <data name=\"DscUserSettingsFileLongDescription\" xml:space=\"preserve\">\n    <value>Управление настройками пользователя winget.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionUserSettingsFileSettings\" xml:space=\"preserve\">\n    <value>Содержимое файла настроек JSON.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionUserSettingsFileAction\" xml:space=\"preserve\">\n    <value>Действие, используемое для применения настроек.</value>\n  </data>\n  <data name=\"CorrelationArgumentDescription\" xml:space=\"preserve\">\n    <value>Значение регистрируется для корреляции</value>\n  </data>\n  <data name=\"DscSourceResourceShortDescription\" xml:space=\"preserve\">\n    <value>Управление конфигурацией источника</value>\n  </data>\n  <data name=\"DscSourceResourceLongDescription\" xml:space=\"preserve\">\n    <value>Управляйте источниками winget.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceName\" xml:space=\"preserve\">\n    <value>Имя, используемое для источника.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceArgument\" xml:space=\"preserve\">\n    <value>Аргумент в пользу источника.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceType\" xml:space=\"preserve\">\n    <value>Тип источника.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceTrustLevel\" xml:space=\"preserve\">\n    <value>Уровень доверия источника.</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceExplicit\" xml:space=\"preserve\">\n    <value>Включается ли источник, если в вызовах источник не указан.</value>\n  </data>\n  <data name=\"ConfigurationApplyingUnit\" xml:space=\"preserve\">\n    <value>Применение единицы конфигурации...</value>\n  </data>\n  <data name=\"ConfigurationExportingUnit\" xml:space=\"preserve\">\n    <value>Экспорт единицы конфигурации...</value>\n  </data>\n  <data name=\"ConfigurationGettingUnitProcessors\" xml:space=\"preserve\">\n    <value>Получение процессоров единиц конфигурации...</value>\n  </data>\n  <data name=\"ConfigurationExportInstallRequiredModule\" xml:space=\"preserve\">\n    <value>Обеспечьте необходимый модуль для экспорта [{0}]</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportInstallRequiredModuleFailed\" xml:space=\"preserve\">\n    <value>Не удалось проверить или получить требуемый модуль. Связанные параметры не будут экспортированы.</value>\n  </data>\n  <data name=\"ConfigurationExportUnitStart\" xml:space=\"preserve\">\n    <value>Экспортировать [{0}]</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportUnitFailed\" xml:space=\"preserve\">\n    <value>Не удалось экспортировать ресурс.</value>\n  </data>\n  <data name=\"ConfigurationExportFailedToGetUnitProcessors\" xml:space=\"preserve\">\n    <value>Не удалось получить модульные процессоры. Отдельные параметры пакета не будут экспортированы.</value>\n  </data>\n  <data name=\"OutputDirectoryArgumentDescription\" xml:space=\"preserve\">\n    <value>Директория, в которую будут записаны результаты</value>\n  </data>\n  <data name=\"ConfigurationInstallDscPackage\" xml:space=\"preserve\">\n    <value>Desired State Configuration пакет не найден в системе. Установка пакета...</value>\n  </data>\n  <data name=\"ConfigurationInstallDscPackageFailed\" xml:space=\"preserve\">\n    <value>Не удалось установить Desired State Configuration пакета. Установите пакет вручную или укажите путь для dsc.exe с помощью --processor-path аргумента.</value>\n    <comment>{Locked=\"dsc.exe\",\"--processor-path\"}</comment>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionAdminSettingsSettings\" xml:space=\"preserve\">\n    <value>Объект, содержащий настройки администратора и их значения.</value>\n  </data>\n  <data name=\"DscAdminSettingsResourceShortDescription\" xml:space=\"preserve\">\n    <value>Управление настройками администратора</value>\n  </data>\n  <data name=\"DscAdminSettingsResourceLongDescription\" xml:space=\"preserve\">\n    <value>Управление параметрами администратора winget.</value>\n  </data>\n  <data name=\"ResetAllAdminSettingsArgumentDescription\" xml:space=\"preserve\">\n    <value>Сбрасывает все настройки администратора</value>\n  </data>\n  <data name=\"ResetAllAdminSettingsSucceeded\" xml:space=\"preserve\">\n    <value>Все настройки администратора сброшены.</value>\n  </data>\n  <data name=\"McpCommandShortDescription\" xml:space=\"preserve\">\n    <value>Сведения об MCP</value>\n    <comment>MCP stands for Model Context Protocol and should probably remain as-is</comment>\n  </data>\n  <data name=\"McpCommandLongDescription\" xml:space=\"preserve\">\n    <value>Сведения MCP (протокол контекста модели) для Диспетчер пакетов Windows.</value>\n  </data>\n  <data name=\"McpConfigurationPreamble\" xml:space=\"preserve\">\n    <value>Чтобы вручную настроить Диспетчер пакетов Windows MCP-сервера с клиентом MCP, используйте следующий фрагмент JSON в `servers` объекта:</value>\n    <comment>{Locked=\"`servers`\"}\nMCP stands for Model Context Protocol and should probably remain as-is.\nAn unlocalized JSON fragment will follow on another line.</comment>\n  </data>\n  <data name=\"PolicyEnableMcpServer\" xml:space=\"preserve\">\n    <value>Включить сервер MCP Диспетчера пакетов Windows</value>\n  </data>\n  <data name=\"OSVersionDescription\" xml:space=\"preserve\">\n    <value>Целевая версия ОС</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Не удалось установить один или несколько шрифтов.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Файл шрифта не поддерживается и не может быть установлен.</value>\n  </data>\n  <data name=\"FontFileNotSupported\" xml:space=\"preserve\">\n    <value>Один или несколько шрифтов в пакете шрифтов не поддерживаются и не могут быть установлены.</value>\n  </data>\n  <data name=\"FontInstallFailed\" xml:space=\"preserve\">\n    <value>Сбой установки шрифта; выполняется очистка.</value>\n  </data>\n  <data name=\"FontAlreadyInstalled\" xml:space=\"preserve\">\n    <value>Шрифт уже установлен.</value>\n  </data>\n  <data name=\"FontPackage\" xml:space=\"preserve\">\n    <value>Идентификатор пакета</value>\n  </data>\n  <data name=\"FontWinGetSupported\" xml:space=\"preserve\">\n    <value>Поддержка WinGet</value>\n  </data>\n  <data name=\"FontTitle\" xml:space=\"preserve\">\n    <value>Название</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_FOUND\" xml:space=\"preserve\">\n    <value>Файл шрифта не найден.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>Не удалось удалить шрифт. Возможно, шрифт находится в неудовлетворительном состоянии. Попробуйте удалить после перезапуска.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>Сбой проверки шрифта.</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_ROLLBACK_FAILED\" xml:space=\"preserve\">\n    <value>Сбой отката шрифта. Возможно, шрифт поврежден. Попробуйте удалить после перезагрузки.</value>\n  </data>\n  <data name=\"FontDetailsArgumentDescription\" xml:space=\"preserve\">\n    <value>Показать подробную информацию о файле шрифта.</value>\n  </data>\n  <data name=\"FontValidationFailed\" xml:space=\"preserve\">\n    <value>Сбой проверки пакета шрифтов.</value>\n  </data>\n  <data name=\"FontRollbackFailed\" xml:space=\"preserve\">\n    <value>Не удалось выполнить откат для неудачной установки шрифта. Для успешного удаления шрифта может потребоваться перезагрузка.</value>\n  </data>\n  <data name=\"FontUninstallFailed\" xml:space=\"preserve\">\n    <value>Не удалось удалить пакет шрифтов. Часто это связано с тем, что шрифты используются системой или приложением. Удаление может быть успешным после перезагрузки компьютера.</value>\n  </data>\n  <data name=\"FontStatusOK\" xml:space=\"preserve\">\n    <value>ОК</value>\n    <comment>\"OK\" means the font is in a good healthy state</comment>\n  </data>\n  <data name=\"FontStatusCorrupt\" xml:space=\"preserve\">\n    <value>Повреждено</value>\n    <comment>\"Corrupt\" refers to an install that is in a corrupted or bad state, and needs repair.</comment>\n  </data>\n  <data name=\"FontStatus\" xml:space=\"preserve\">\n    <value>Состояние</value>\n  </data>\n  <data name=\"FontStatusUnknown\" xml:space=\"preserve\">\n    <value>Неизвестно</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>Пакет шрифтов уже установлен.</value>\n  </data>\n  <data name=\"ListDetailsArgumentDescription\" xml:space=\"preserve\">\n    <value>Показать подробную информацию о пакетах</value>\n    <comment>Providing this argument causes the CLI to output additional details about installed application packages.</comment>\n  </data>\n  <data name=\"ShowLabelChannel\" xml:space=\"preserve\">\n    <value>Канал:</value>\n    <comment>Precedes a string value that names the delivery channel for the software package (ex. stable, beta).</comment>\n  </data>\n  <data name=\"ShowListLocalIdentifier\" xml:space=\"preserve\">\n    <value>Локальный идентификатор:</value>\n    <comment>Precedes a value that is the unique identifier for the installed package on the local system.</comment>\n  </data>\n  <data name=\"ShowListPackageFamilyName\" xml:space=\"preserve\">\n    <value>Имя семейства пакетов</value>\n    <comment>Precedes a value that is the APPX/MSIX package family name of the installed package.</comment>\n  </data>\n  <data name=\"ShowListProductCode\" xml:space=\"preserve\">\n    <value>Код продукта:</value>\n    <comment>Precedes a value that is the Add/Remove Programs identifier in the registry. This is also the Product Code value as defined in MSI installers.</comment>\n  </data>\n  <data name=\"ShowListUpgradeCode\" xml:space=\"preserve\">\n    <value>Код обновления:</value>\n    <comment>Precedes a value that is the MSI Upgrade Code for the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledScope\" xml:space=\"preserve\">\n    <value>Установленная область:</value>\n    <comment>Precedes a value that is the scope of the installation of the package (ex. user, machine).</comment>\n  </data>\n  <data name=\"ShowListInstalledArchitecture\" xml:space=\"preserve\">\n    <value>Установленная архитектура:</value>\n    <comment>Precedes a value that is the installed architecture of the package (ex. x86, x64, ARM64).</comment>\n  </data>\n  <data name=\"ShowListInstalledLocale\" xml:space=\"preserve\">\n    <value>Установленный языковой стандарт:</value>\n    <comment>Precedes a value that is the locale of the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledLocation\" xml:space=\"preserve\">\n    <value>Установленное расположение:</value>\n    <comment>Precedes a value that is the directory path to the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledSource\" xml:space=\"preserve\">\n    <value>Источник пакета:</value>\n    <comment>Precedes a value that names the package source where the installed package originated from.</comment>\n  </data>\n  <data name=\"ShowListAvailableUpgrades\" xml:space=\"preserve\">\n    <value>Доступные обновления:</value>\n    <comment>Precedes a list of package upgrades available for the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstallerCategory\" xml:space=\"preserve\">\n    <value>Категория установщика:</value>\n    <comment>Precedes a value that indicates the category of the installer for the installed package (ex. exe, msi, msix).</comment>\n  </data>\n  <data name=\"SourceEditOldValue\" xml:space=\"preserve\">\n    <value>Старое значение</value>\n    <comment>Column title for listing edit changes.</comment>\n  </data>\n  <data name=\"SourceEditNewValue\" xml:space=\"preserve\">\n    <value>Новое значение</value>\n    <comment>Column title for listing the new value.</comment>\n  </data>\n</root>"
  },
  {
    "path": "Localization/Resources/zh-CN/Resources.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "Localization/Resources/zh-CN/winget.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"AdjoinedNotFlagError\" xml:space=\"preserve\">\n    <value>邻近别名不是标记: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an adjoined alias that is not a flag argument. {0} is a placeholder replaced by the user input argument (e.g. '-ab').</comment>\n  </data>\n  <data name=\"AdjoinedNotFoundError\" xml:space=\"preserve\">\n    <value>未找到邻近标记别名: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an adjoined flag alias argument that was not found. {0} is a placeholder replaced by the user input argument (e.g. '-ab').</comment>\n  </data>\n  <data name=\"AvailableArguments\" xml:space=\"preserve\">\n    <value>以下参数可用：</value>\n    <comment>Message displayed to inform the user about the available command line arguments.</comment>\n  </data>\n  <data name=\"AvailableCommandAliases\" xml:space=\"preserve\">\n    <value>以下命令别名可用：</value>\n    <comment>Message displayed to inform the user about the available command line alias arguments.</comment>\n  </data>\n  <data name=\"AvailableCommands\" xml:space=\"preserve\">\n    <value>下列命令有效:</value>\n    <comment>Title displayed to inform the user about the available commands.</comment>\n  </data>\n  <data name=\"AvailableHeader\" xml:space=\"preserve\">\n    <value>可用</value>\n    <comment>As in \"a new version is available to upgrade to\".</comment>\n  </data>\n  <data name=\"AvailableOptions\" xml:space=\"preserve\">\n    <value>下列选项可用：</value>\n    <comment>Message displayed to inform the user about the available options.</comment>\n  </data>\n  <data name=\"AvailableSubcommands\" xml:space=\"preserve\">\n    <value>以下子命令可用：</value>\n    <comment>Message displayed to inform the user about the available nested commands that run in context of the selected command.</comment>\n  </data>\n  <data name=\"AvailableUpgrades\" xml:space=\"preserve\">\n    <value>{0} 升级可用。</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about available package upgrades. {0} is a placeholder replaced by the number of package upgrades.</comment>\n  </data>\n  <data name=\"ChannelArgumentDescription\" xml:space=\"preserve\">\n    <value>使用指定的频道；默认为普通受众</value>\n  </data>\n  <data name=\"Command\" xml:space=\"preserve\">\n    <value>命令</value>\n    <comment>Label displayed for a command to give the software.</comment>\n  </data>\n  <data name=\"CommandArgumentDescription\" xml:space=\"preserve\">\n    <value>按命令筛选结果</value>\n    <comment>Description message displayed to inform the user about filtering the search results by a package command.</comment>\n  </data>\n  <data name=\"CommandLineArgumentDescription\" xml:space=\"preserve\">\n    <value>要补全的完整命令行</value>\n  </data>\n  <data name=\"CommandRequiresAdmin\" xml:space=\"preserve\">\n    <value>需要具有管理员权限才能执行此命令。</value>\n  </data>\n  <data name=\"CompleteCommandLongDescription\" xml:space=\"preserve\">\n    <value>此命令可用于请求上下文敏感命令行补全。已传入要补全的命令行、光标位置和单词。输出是基于输入的一组可能值，其中每行一个可能的值。</value>\n  </data>\n  <data name=\"CompleteCommandShortDescription\" xml:space=\"preserve\">\n    <value>启用上下文相关的命令行补全</value>\n  </data>\n  <data name=\"CountArgumentDescription\" xml:space=\"preserve\">\n    <value>显示介于 1 和 1000 ()之间的指定数量的结果</value>\n  </data>\n  <data name=\"Done\" xml:space=\"preserve\">\n    <value>完成</value>\n    <comment>Label displayed when an operation completes or is done executing.</comment>\n  </data>\n  <data name=\"ExactArgumentDescription\" xml:space=\"preserve\">\n    <value>使用精确匹配查找程序包</value>\n    <comment>Description message displayed to inform the user about finding an application package using an exact matching criteria.</comment>\n  </data>\n  <data name=\"ExperimentalArgumentDescription\" xml:space=\"preserve\">\n    <value>用于演示目的的实验性参数</value>\n  </data>\n  <data name=\"ExperimentalCommandLongDescription\" xml:space=\"preserve\">\n    <value>此命令是有关如何实施实验性功能的示例。若要启用，请转到“winget settings”并启用 experimentalCmd 或 experimentalArg 功能。</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"ExperimentalCommandShortDescription\" xml:space=\"preserve\">\n    <value>实验性功能示例</value>\n  </data>\n  <data name=\"ExtraPositionalError\" xml:space=\"preserve\">\n    <value>在未预期的情况下找到位置参数: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an extra positional argument when none was expected. {0} is a placeholder replaced by the user's extra argument input.</comment>\n  </data>\n  <data name=\"FeatureDisabledMessage\" xml:space=\"preserve\">\n    <value>此功能是一项正在进行的工作，将来可能会发生显著更改或完全删除。若要启用它，请编辑设置 ('winget settings')以包括实验性功能： '{0}'</value>\n    <comment>{Locked=\"winget settings\",\"{0}\"}. Error message displayed when the user uses an experimental feature that is disabled. {0} is a placeholder replaced by the experimental feature name.</comment>\n  </data>\n  <data name=\"FeaturesCommandLongDescription\" xml:space=\"preserve\">\n    <value>显示实验性功能的状态。可以通过'winget settings'启用实验性功能。</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"FeaturesCommandShortDescription\" xml:space=\"preserve\">\n    <value>显示实验性功能的状态</value>\n  </data>\n  <data name=\"FeaturesDisabled\" xml:space=\"preserve\">\n    <value>已禁用</value>\n  </data>\n  <data name=\"FeaturesEnabled\" xml:space=\"preserve\">\n    <value>已启用</value>\n  </data>\n  <data name=\"FeaturesFeature\" xml:space=\"preserve\">\n    <value>功能</value>\n  </data>\n  <data name=\"FeaturesLink\" xml:space=\"preserve\">\n    <value>链接</value>\n  </data>\n  <data name=\"FeaturesMessage\" xml:space=\"preserve\">\n    <value>以下实验性功能正在进行中。\n它们可以通过设置文件“winget settings”进行配置。</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"FeaturesProperty\" xml:space=\"preserve\">\n    <value>属性</value>\n  </data>\n  <data name=\"FeaturesStatus\" xml:space=\"preserve\">\n    <value>状态</value>\n  </data>\n  <data name=\"FileArgumentDescription\" xml:space=\"preserve\">\n    <value>进行哈希处理的文件</value>\n  </data>\n  <data name=\"FlagContainAdjoinedError\" xml:space=\"preserve\">\n    <value>标记参数不得含有邻近值: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a flag argument containing an unexpected adjoined value. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"HashCommandLongDescription\" xml:space=\"preserve\">\n    <value>计算本地文件的哈希值，适用于清单中的条目。此外，它还可以计算 MSIX 程序包的签名文件的哈希，以启用流式安装。</value>\n  </data>\n  <data name=\"HashCommandShortDescription\" xml:space=\"preserve\">\n    <value>哈希安装程序的帮助程序</value>\n  </data>\n  <data name=\"HelpArgumentDescription\" xml:space=\"preserve\">\n    <value>显示选定命令的帮助信息</value>\n  </data>\n  <data name=\"HelpForDetails\" xml:space=\"preserve\">\n    <value>如需特定命令的更多详细信息，请向其传递帮助参数。</value>\n  </data>\n  <data name=\"HelpLinkPreamble\" xml:space=\"preserve\">\n    <value>可在此找到更多帮助: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a link where they can learn more about the subject context. {0} is a placeholder replaced by a website address.</comment>\n  </data>\n  <data name=\"IdArgumentDescription\" xml:space=\"preserve\">\n    <value>按 id 筛选结果</value>\n  </data>\n  <data name=\"IgnoreWarningsArgumentDescription\" xml:space=\"preserve\">\n    <value>禁止显示警告输出</value>\n  </data>\n  <data name=\"InstallationDisclaimer1\" xml:space=\"preserve\">\n    <value>此应用程序由其所有者授权给你。</value>\n  </data>\n  <data name=\"InstallationDisclaimer2\" xml:space=\"preserve\">\n    <value>Microsoft 对第三方程序包概不负责，也不向第三方程序包授予任何许可证。</value>\n  </data>\n  <data name=\"InstallationDisclaimerMSStore\" xml:space=\"preserve\">\n    <value>此程序包是通过 Microsoft Store 提供的。winget 可能需要代表当前用户从 Microsoft Store 获取该程序包。</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"InstallCommandLongDescription\" xml:space=\"preserve\">\n    <value>安装选定的程序包（通过搜索配置的源或直接从清单中找到）。默认情况下，查询必须以不区分大小写的方式匹配程序包的 id、name 或 moniker。可以通过传递相应的选项来使用其他字段。默认情况下，安装命令将检查包安装状态，并尝试执行升级（如果适用）。使用 --force 重写以执行直接安装。</value>\n    <comment>{Locked=\"--force\"}; id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"InstallCommandShortDescription\" xml:space=\"preserve\">\n    <value>安装给定的程序包</value>\n  </data>\n  <data name=\"InstallerHashMismatchAdminBlock\" xml:space=\"preserve\">\n    <value>安装程序哈希不匹配；以管理员身份运行时不能覆盖此内容</value>\n  </data>\n  <data name=\"InstallerHashMismatchOverridden\" xml:space=\"preserve\">\n    <value>安装程序哈希不匹配；由于 --ignore-security-hash 而继续进行</value>\n    <comment>{Locked=\"--ignore-security-hash\"}</comment>\n  </data>\n  <data name=\"InstallerHashMismatchOverrideRequired\" xml:space=\"preserve\">\n    <value>安装程序哈希不匹配；若要重写此检查，请使用 --ignore-security-hash</value>\n    <comment>{Locked=\"--ignore-security-hash\"}</comment>\n  </data>\n  <data name=\"InstallerHashVerified\" xml:space=\"preserve\">\n    <value>已成功验证安装程序哈希</value>\n  </data>\n  <data name=\"InstallFlowInstallSuccess\" xml:space=\"preserve\">\n    <value>已成功安装</value>\n  </data>\n  <data name=\"InstallFlowStartingPackageInstall\" xml:space=\"preserve\">\n    <value>正在启动程序包安装...</value>\n  </data>\n  <data name=\"HashOverrideArgumentDescription\" xml:space=\"preserve\">\n    <value>忽略安装程序哈希检查失败</value>\n  </data>\n  <data name=\"IgnoreLocalArchiveMalwareScanArgumentDescription\" xml:space=\"preserve\">\n    <value>忽略在从本地清单安装存档类型包时执行的恶意软件扫描</value>\n  </data>\n  <data name=\"InteractiveArgumentDescription\" xml:space=\"preserve\">\n    <value>请求交互式安装；可能需要用户输入</value>\n  </data>\n  <data name=\"InvalidAliasError\" xml:space=\"preserve\">\n    <value>无法识别当前命令的参数别名: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a command line argument alias that was not recognized for a selected command. {0} is a placeholder replaced by the user's argument alias input (e.g. '-a').</comment>\n  </data>\n  <data name=\"InvalidArgumentSpecifierError\" xml:space=\"preserve\">\n    <value>无效参数说明符: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an invalid argument specifier. {0} is a placeholder replaced by an argument specifier (e.g. '-').</comment>\n  </data>\n  <data name=\"InvalidNameError\" xml:space=\"preserve\">\n    <value>当前命令无法识别参数名称: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an unrecognized command line argument name for the selected command. {0} is a placeholder replaced by the user's argument name input (e.g. '--example').</comment>\n  </data>\n  <data name=\"KeyDirectoriesHeader\" xml:space=\"preserve\">\n    <value>Winget 目录</value>\n    <comment>Header for a table detailing the directories Winget uses for key operations like logging and portable installs</comment>\n  </data>\n  <data name=\"LocaleArgumentDescription\" xml:space=\"preserve\">\n    <value>要使用的区域设置(BCP47 格式)</value>\n    <comment>{Locked=\"BCP47\"}</comment>\n  </data>\n  <data name=\"LicenseAgreement\" xml:space=\"preserve\">\n    <value>许可协议</value>\n  </data>\n  <data name=\"Links\" xml:space=\"preserve\">\n    <value>链接</value>\n    <comment>Links to different webpages</comment>\n  </data>\n  <data name=\"ListCommandLongDescription\" xml:space=\"preserve\">\n    <value>list 命令显示系统上安装的程序包，以及是否有可用的更新。可以提供其他选项来筛选输出，这与 search 命令非常相似。</value>\n    <comment>{Locked=\"list\",\"search\"}</comment>\n  </data>\n  <data name=\"ListCommandShortDescription\" xml:space=\"preserve\">\n    <value>显示已安装的程序包</value>\n  </data>\n  <data name=\"LocationArgumentDescription\" xml:space=\"preserve\">\n    <value>要安装到的位置（如支持）</value>\n  </data>\n  <data name=\"LogArgumentDescription\" xml:space=\"preserve\">\n    <value>日志位置（如果支持）</value>\n  </data>\n  <data name=\"MainCopyrightNotice\" xml:space=\"preserve\">\n    <value>版权所有 (C) Microsoft Corporation。保留所有权利。</value>\n  </data>\n  <data name=\"MainHomepage\" xml:space=\"preserve\">\n    <value>主页</value>\n    <comment>The primary webpage for the software</comment>\n  </data>\n  <data name=\"ManifestArgumentDescription\" xml:space=\"preserve\">\n    <value>程序包清单的路径</value>\n  </data>\n  <data name=\"ManifestValidationFail\" xml:space=\"preserve\">\n    <value>清单验证失败。</value>\n  </data>\n  <data name=\"ManifestValidationSuccess\" xml:space=\"preserve\">\n    <value>清单验证成功。</value>\n  </data>\n  <data name=\"ManifestValidationWarning\" xml:space=\"preserve\">\n    <value>清单验证成功，但出现警告。</value>\n  </data>\n  <data name=\"MissingArgumentError\" xml:space=\"preserve\">\n    <value>所需参数值，但未找到: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user does not provide a required command line argument value. {0} is a placeholder replaced by the argument name.</comment>\n  </data>\n  <data name=\"MonikerArgumentDescription\" xml:space=\"preserve\">\n    <value>按名字对象筛选结果</value>\n  </data>\n  <data name=\"MsixArgumentDescription\" xml:space=\"preserve\">\n    <value>输入文件将被视为 msix；如果签名，将提供签名哈希</value>\n  </data>\n  <data name=\"MsixSignatureHashFailed\" xml:space=\"preserve\">\n    <value>无法计算 MSIX 签名哈希。</value>\n  </data>\n  <data name=\"MSStoreAppBlocked\" xml:space=\"preserve\">\n    <value>无法安装或更新 Microsoft Store 程序包，因为策略阻止了特定应用</value>\n  </data>\n  <data name=\"MSStoreInstallOrUpdateFailed\" xml:space=\"preserve\">\n    <value>无法安装或更新 Microsoft Store 程序包。错误代码: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Microsoft Store application package fails to install or upgrade. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"MSStoreStoreClientBlocked\" xml:space=\"preserve\">\n    <value>无法安装或更新 Microsoft Store 程序包，因为策略阻止了 Microsoft Store 客户端</value>\n  </data>\n  <data name=\"MSStoreInstallTryGetEntitlement\" xml:space=\"preserve\">\n    <value>验证/请求程序包获取成功...</value>\n  </data>\n  <data name=\"MultipleInstalledPackagesFound\" xml:space=\"preserve\">\n    <value>找到多个与输入标准匹配的已安装程序包。请修改输入。</value>\n  </data>\n  <data name=\"MultiplePackagesFound\" xml:space=\"preserve\">\n    <value>找到多个与输入条件匹配的程序包。请修改输入。</value>\n  </data>\n  <data name=\"NameArgumentDescription\" xml:space=\"preserve\">\n    <value>按名称筛选结果</value>\n  </data>\n  <data name=\"NoApplicableInstallers\" xml:space=\"preserve\">\n    <value>找不到适用的安装程序;有关详细信息，请参阅日志。</value>\n  </data>\n  <data name=\"NoExperimentalFeaturesMessage\" xml:space=\"preserve\">\n    <value>当前没有实验性功能可用。</value>\n  </data>\n  <data name=\"NoInstalledPackageFound\" xml:space=\"preserve\">\n    <value>找不到与输入条件匹配的已安装程序包。</value>\n  </data>\n  <data name=\"NoPackageFound\" xml:space=\"preserve\">\n    <value>找不到与输入条件匹配的程序包。</value>\n  </data>\n  <data name=\"NoVTArgumentDescription\" xml:space=\"preserve\">\n    <value>禁用 VirtualTerminal 显示</value>\n    <comment>{Locked=\"VirtualTerminal\"}</comment>\n  </data>\n  <data name=\"OpenLogsArgumentDescription\" xml:space=\"preserve\">\n    <value>打开默认日志位置</value>\n  </data>\n  <data name=\"Options\" xml:space=\"preserve\">\n    <value>选项</value>\n    <comment>Options to change how a command works</comment>\n  </data>\n  <data name=\"OverrideArgumentDescription\" xml:space=\"preserve\">\n    <value>覆盖待传递的参数至安装程序</value>\n  </data>\n  <data name=\"Package\" xml:space=\"preserve\">\n    <value>软件包: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for a software package. {0} is a placeholder replaced by the software package name.</comment>\n  </data>\n  <data name=\"PendingWorkError\" xml:space=\"preserve\">\n    <value>抱歉，我们忘记了...</value>\n  </data>\n  <data name=\"PositionArgumentDescription\" xml:space=\"preserve\">\n    <value>光标在命令行中的位置</value>\n  </data>\n  <data name=\"PrivacyStatement\" xml:space=\"preserve\">\n    <value>隐私声明</value>\n  </data>\n  <data name=\"QueryArgumentDescription\" xml:space=\"preserve\">\n    <value>用于搜索程序包的查询</value>\n  </data>\n  <data name=\"RainbowArgumentDescription\" xml:space=\"preserve\">\n    <value>彩虹色进度显示</value>\n  </data>\n  <data name=\"RequiredArgError\" xml:space=\"preserve\">\n    <value>未提供所需参数: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user does not provide a required command line argument. {0} is a placeholder replaced by an argument name.</comment>\n  </data>\n  <data name=\"RetroArgumentDescription\" xml:space=\"preserve\">\n    <value>默认颜色进度显示</value>\n  </data>\n  <data name=\"SearchCommandLongDescription\" xml:space=\"preserve\">\n    <value>从配置的源搜索程序包。</value>\n  </data>\n  <data name=\"SearchCommandShortDescription\" xml:space=\"preserve\">\n    <value>查找并显示程序包的基本信息</value>\n  </data>\n  <data name=\"SearchId\" xml:space=\"preserve\">\n    <value>ID</value>\n    <comment>Abbreviation of Identifier.</comment>\n  </data>\n  <data name=\"SearchMatch\" xml:space=\"preserve\">\n    <value>匹配</value>\n  </data>\n  <data name=\"SearchName\" xml:space=\"preserve\">\n    <value>名称</value>\n  </data>\n  <data name=\"SearchSource\" xml:space=\"preserve\">\n    <value>源</value>\n  </data>\n  <data name=\"SearchTruncated\" xml:space=\"preserve\">\n    <value>由于结果限制而截断了其他条目</value>\n  </data>\n  <data name=\"SearchVersion\" xml:space=\"preserve\">\n    <value>版本</value>\n  </data>\n  <data name=\"SettingLoadFailure\" xml:space=\"preserve\">\n    <value>发现以下故障以验证设置：</value>\n  </data>\n  <data name=\"SettingsCommandLongDescription\" xml:space=\"preserve\">\n    <value>在默认 json 文本编辑器中打开设置。如果未配置任何编辑器，请在记事本中打开设置。有关可用设置，请参阅 https://aka.ms/winget-settings。此命令还可用于通过提供 --enable 或 --disable 参数来设置管理员设置</value>\n    <comment>{Locked=\"--enable\"} {Locked=\"--disable\"}</comment>\n  </data>\n  <data name=\"SettingsCommandShortDescription\" xml:space=\"preserve\">\n    <value>打开设置或设置管理员设置</value>\n  </data>\n  <data name=\"SettingsWarnings\" xml:space=\"preserve\">\n    <value>加载设置时出现意外错误。请运行'settings'命令来验证你的设置。</value>\n    <comment>{Locked=\"'settings'\"}</comment>\n  </data>\n  <data name=\"ShowChannel\" xml:space=\"preserve\">\n    <value>频道</value>\n  </data>\n  <data name=\"ShowCommandLongDescription\" xml:space=\"preserve\">\n    <value>显示有关特定程序包的信息。默认情况下，查询必须以不区分大小写的方式匹配程序包的 ID、名称或名字对象。可通过传递相应的选项来使用其他字段。</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"ShowCommandShortDescription\" xml:space=\"preserve\">\n    <value>显示包的相关信息</value>\n  </data>\n  <data name=\"ShowVersion\" xml:space=\"preserve\">\n    <value>版本</value>\n  </data>\n  <data name=\"SilentArgumentDescription\" xml:space=\"preserve\">\n    <value>请求无提示安装</value>\n  </data>\n  <data name=\"SingleCharAfterDashError\" xml:space=\"preserve\">\n    <value>只能在单个 - 后出现单个字符别名: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides more than a single character command line alias argument after an alias argument specifier '-'. {0} is a placeholder replaced by the user's argument input.</comment>\n  </data>\n  <data name=\"SourceAddAlreadyExistsDifferentArg\" xml:space=\"preserve\">\n    <value>具有给定名称的源已存在，并且引用了其他位置:</value>\n  </data>\n  <data name=\"SourceAddAlreadyExistsDifferentName\" xml:space=\"preserve\">\n    <value>具有不同名称的源已引用此位置:</value>\n  </data>\n  <data name=\"SourceAddAlreadyExistsMatch\" xml:space=\"preserve\">\n    <value>具有给定名称的源已存在，并且引用了相同位置:</value>\n  </data>\n  <data name=\"SourceAddBegin\" xml:space=\"preserve\">\n    <value>正在添加源:</value>\n  </data>\n  <data name=\"SourceAddCommandLongDescription\" xml:space=\"preserve\">\n    <value>添加新的来源。源提供了用于发现和安装程序包的数据。仅当将新来源视为安全位置时，才可添加。</value>\n  </data>\n  <data name=\"SourceAddCommandShortDescription\" xml:space=\"preserve\">\n    <value>添加新来源</value>\n  </data>\n  <data name=\"SourceArgArgumentDescription\" xml:space=\"preserve\">\n    <value>指定给源的参数</value>\n  </data>\n  <data name=\"SourceArgumentDescription\" xml:space=\"preserve\">\n    <value>使用指定的源查找程序包</value>\n  </data>\n  <data name=\"SourceCommandLongDescription\" xml:space=\"preserve\">\n    <value>使用子命令管理源。源提供了用于发现和安装程序包的数据。仅当将新来源视为安全位置时，才可添加。</value>\n  </data>\n  <data name=\"SourceCommandShortDescription\" xml:space=\"preserve\">\n    <value>管理程序包的来源</value>\n  </data>\n  <data name=\"SourceEditCommandLongDescription\" xml:space=\"preserve\">\n    <value>编辑现有源的属性。源提供用于发现和安装包的数据。</value>\n  </data>\n  <data name=\"SourceEditCommandShortDescription\" xml:space=\"preserve\">\n    <value>编辑源的属性</value>\n  </data>\n  <data name=\"SourceEditOne\" xml:space=\"preserve\">\n    <value>正在编辑源: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being edited. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceEditNoChanges\" xml:space=\"preserve\">\n    <value>名为 '{0}' 的源已处于所需状态。</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being edited. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceListArg\" xml:space=\"preserve\">\n    <value>参数</value>\n    <comment>Value given to source.</comment>\n  </data>\n  <data name=\"SourceListCommandLongDescription\" xml:space=\"preserve\">\n    <value>列出所有当前来源，或列出特定来源的完整详细信息。</value>\n  </data>\n  <data name=\"SourceListCommandShortDescription\" xml:space=\"preserve\">\n    <value>列出当前源</value>\n  </data>\n  <data name=\"SourceListData\" xml:space=\"preserve\">\n    <value>数据</value>\n    <comment>Data stored by the source.</comment>\n  </data>\n  <data name=\"SourceListField\" xml:space=\"preserve\">\n    <value>字段</value>\n    <comment>The name of a piece of information about a source.</comment>\n  </data>\n  <data name=\"SourceListName\" xml:space=\"preserve\">\n    <value>名称</value>\n    <comment>The name of the source.</comment>\n  </data>\n  <data name=\"SourceListIdentifier\" xml:space=\"preserve\">\n    <value>标识符</value>\n    <comment>The source's unique identifier.</comment>\n  </data>\n  <data name=\"SourceListNoneFound\" xml:space=\"preserve\">\n    <value>找不到具有以下名称的源: {0}</value>\n    <comment>Error message displayed when the user provides a repository source name that was not found. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"SourceListNoSources\" xml:space=\"preserve\">\n    <value>未配置源。</value>\n  </data>\n  <data name=\"SourceListType\" xml:space=\"preserve\">\n    <value>类型</value>\n    <comment>The kind of source.</comment>\n  </data>\n  <data name=\"SourceListUpdated\" xml:space=\"preserve\">\n    <value>已更新</value>\n    <comment>The last time the source was updated.</comment>\n  </data>\n  <data name=\"SourceListUpdatedNever\" xml:space=\"preserve\">\n    <value>从不</value>\n    <comment>The source has never been updated.</comment>\n  </data>\n  <data name=\"SourceListValue\" xml:space=\"preserve\">\n    <value>值</value>\n    <comment>The value of information about a source.</comment>\n  </data>\n  <data name=\"SourceNameArgumentDescription\" xml:space=\"preserve\">\n    <value>源名称</value>\n  </data>\n  <data name=\"SourceOpenFailedSuggestion\" xml:space=\"preserve\">\n    <value>打开源时失败;如果问题仍然存在，请尝试\"source reset\"命令。</value>\n    <comment>{Locked=\"source reset\"}</comment>\n  </data>\n  <data name=\"SourceOpenPredefinedFailedSuggestion\" xml:space=\"preserve\">\n    <value>打开预定义源失败; 请向 winget 维护人员报告。</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"SourceRemoveAll\" xml:space=\"preserve\">\n    <value>正在删除所有源...</value>\n  </data>\n  <data name=\"SourceRemoveCommandLongDescription\" xml:space=\"preserve\">\n    <value>删除指定的源。</value>\n  </data>\n  <data name=\"SourceRemoveCommandShortDescription\" xml:space=\"preserve\">\n    <value>删除当前源</value>\n  </data>\n  <data name=\"SourceRemoveOne\" xml:space=\"preserve\">\n    <value>正在删除源: {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being removed. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceResetAll\" xml:space=\"preserve\">\n    <value>正在重置所有源...</value>\n  </data>\n  <data name=\"SourceResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>此命令将丢弃现有源，从而有可能留下任何本地数据。没有任何参数，它将删除所有源并添加默认值。如果提供了已命名源，则只会删除该源。</value>\n  </data>\n  <data name=\"SourceResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>重置源</value>\n  </data>\n  <data name=\"SourceResetForceArgumentDescription\" xml:space=\"preserve\">\n    <value>强制重置源</value>\n  </data>\n  <data name=\"SourceResetListAndOverridePreamble\" xml:space=\"preserve\">\n    <value>如果指定了--force 选项，则将重置以下源：</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"SourceResetOne\" xml:space=\"preserve\">\n    <value>正在重置源: {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a repository source that is currently being reset. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceTypeArgumentDescription\" xml:space=\"preserve\">\n    <value>源类型</value>\n  </data>\n  <data name=\"SourceUpdateAll\" xml:space=\"preserve\">\n    <value>正在更新所有源...</value>\n  </data>\n  <data name=\"SourceUpdateCommandLongDescription\" xml:space=\"preserve\">\n    <value>更新所有源，或仅指定源。</value>\n  </data>\n  <data name=\"SourceUpdateCommandShortDescription\" xml:space=\"preserve\">\n    <value>更新当前源</value>\n  </data>\n  <data name=\"SourceUpdateOne\" xml:space=\"preserve\">\n    <value>正在更新源: {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being updated. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"TagArgumentDescription\" xml:space=\"preserve\">\n    <value>按标签筛选</value>\n  </data>\n  <data name=\"ThankYou\" xml:space=\"preserve\">\n    <value>感谢你使用 winget</value>\n  </data>\n  <data name=\"ThirdPartSoftwareNotices\" xml:space=\"preserve\">\n    <value>第三方声明</value>\n  </data>\n  <data name=\"ToolDescription\" xml:space=\"preserve\">\n    <value>WinGet 命令行实用工具可从命令行安装应用程序和其他程序包。</value>\n  </data>\n  <data name=\"ToolInfoArgumentDescription\" xml:space=\"preserve\">\n    <value>显示工具的常规信息</value>\n  </data>\n  <data name=\"ToolVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>显示工具的版本</value>\n  </data>\n  <data name=\"TooManyArgError\" xml:space=\"preserve\">\n    <value>提供的参数超过允许的参数: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a command line argument more times than it is allowed. {0} is a placeholder replaced by the user's argument name input.</comment>\n  </data>\n  <data name=\"TooManyBehaviorsError\" xml:space=\"preserve\">\n    <value>提供了多个执行行为参数: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides more than one execution behavior argument when installing an application package. {0} is a placeholder replaced by the user specified execution behaviors (e.g. 'silent|interactive').</comment>\n  </data>\n  <data name=\"UnexpectedErrorExecutingCommand\" xml:space=\"preserve\">\n    <value>执行此命令时发生意外错误：</value>\n  </data>\n  <data name=\"UninstallPreviousArgumentDescription\" xml:space=\"preserve\">\n    <value>升级期间卸载以前版本的程序包</value>\n  </data>\n  <data name=\"UnrecognizedCommand\" xml:space=\"preserve\">\n    <value>无法识别的命令: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an unrecognized command. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"UpdateAllArgumentDescription\" xml:space=\"preserve\">\n    <value>如果可用，将所有已安装的程序包更新为最新版本</value>\n  </data>\n  <data name=\"UpdateNotApplicable\" xml:space=\"preserve\">\n    <value>找不到适用的升级。</value>\n  </data>\n  <data name=\"UpdateNotApplicableReason\" xml:space=\"preserve\">\n    <value>较新的包版本在配置的源中可用，但不适用于你的系统或要求。</value>\n  </data>\n  <data name=\"UpdateNoPackagesFound\" xml:space=\"preserve\">\n    <value>找不到可用的升级。</value>\n  </data>\n  <data name=\"UpdateNoPackagesFoundReason\" xml:space=\"preserve\">\n    <value>配置的源中没有可用的较新的包版本。</value>\n  </data>\n  <data name=\"UpgradeCommandLongDescription\" xml:space=\"preserve\">\n    <value>升级通过搜索已安装的包列表或直接从清单中找到的所选包。默认情况下，查询必须以不区分大小写方式匹配包的 ID、名称或名字对象。可通过传递相应的选项来使用其他字段。如果未提供参数，则显示具有可用升级的包</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"UpgradeCommandShortDescription\" xml:space=\"preserve\">\n    <value>显示并执行可用升级</value>\n  </data>\n  <data name=\"Usage\" xml:space=\"preserve\">\n    <value>使用情况: {0} {1}</value>\n    <comment>{Locked=\"{0} {1}\"} Message displayed to provide the user with instructions on how to use a command. {0} is a placeholder replaced by the program name (e.g. 'winget'). {1} is a placeholder replaced by the pattern for using the selected command.</comment>\n  </data>\n  <data name=\"ValidateCommandLongDescription\" xml:space=\"preserve\">\n    <value>使用一组严格的准则验证清单。这是为了能够在提交到存储库之前检查清单。</value>\n  </data>\n  <data name=\"ValidateCommandShortDescription\" xml:space=\"preserve\">\n    <value>验证清单文件</value>\n  </data>\n  <data name=\"ValidateManifestArgumentDescription\" xml:space=\"preserve\">\n    <value>待验证的程序清单路径</value>\n  </data>\n  <data name=\"VerboseLogsArgumentDescription\" xml:space=\"preserve\">\n    <value>启用 WinGet 的详细日志记录</value>\n  </data>\n  <data name=\"VerifyFileSignedMsix\" xml:space=\"preserve\">\n    <value>请验证输入文件是否为有效的、已签名的 MSIX。</value>\n  </data>\n  <data name=\"VersionArgumentDescription\" xml:space=\"preserve\">\n    <value>使用指定的版本；默认为最新版本</value>\n  </data>\n  <data name=\"VersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>显示程序包的可用版本</value>\n  </data>\n  <data name=\"WordArgumentDescription\" xml:space=\"preserve\">\n    <value>请求补全前提供的值</value>\n  </data>\n  <data name=\"GetManifestResultVersionNotFound\" xml:space=\"preserve\">\n    <value>找不到匹配的版本: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to upgrade an application package to a version that was not found. {0} is a placeholder replaced by the user's provided upgrade package version.</comment>\n  </data>\n  <data name=\"OpenSourceFailedNoMatch\" xml:space=\"preserve\">\n    <value>没有与给定值匹配的源: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to install or upgrade an application package from a repository source that was not found. {0} is a placeholder replaced by the user's repository source name input.</comment>\n  </data>\n  <data name=\"OpenSourceFailedNoMatchHelp\" xml:space=\"preserve\">\n    <value>配置的源为:</value>\n  </data>\n  <data name=\"OpenSourceFailedNoSourceDefined\" xml:space=\"preserve\">\n    <value>未定义源; 使用“source add”添加一个或使用“source reset”重置为默认值</value>\n    <comment>{Locked=\"source add\",\"source reset\"}</comment>\n  </data>\n  <data name=\"ReportIdentityFound\" xml:space=\"preserve\">\n    <value>已找到</value>\n  </data>\n  <data name=\"VerifyFileFailedIsDirectory\" xml:space=\"preserve\">\n    <value>路径是一个目录: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system path that is a directory. {0} is a placeholder replaced by the provided directory path.</comment>\n  </data>\n  <data name=\"VerifyFileFailedNotExist\" xml:space=\"preserve\">\n    <value>文件不存在: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system file that does not exist. {0} is a placeholder replaced by the provided file path.</comment>\n  </data>\n  <data name=\"BothManifestAndSearchQueryProvided\" xml:space=\"preserve\">\n    <value>同时提供本地清单和搜索查询参数</value>\n  </data>\n  <data name=\"Logs\" xml:space=\"preserve\">\n    <value>日志</value>\n    <comment>Label displayed for diagnostic files containing information about the application use.</comment>\n  </data>\n  <data name=\"InstallerBlockedByPolicy\" xml:space=\"preserve\">\n    <value>安装程序已被策略阻止</value>\n  </data>\n  <data name=\"InstallerFailedSecurityCheck\" xml:space=\"preserve\">\n    <value>安装程序未通过安全性检查</value>\n  </data>\n  <data name=\"InstallerFailedVirusScan\" xml:space=\"preserve\">\n    <value>防病毒产品报告安装程序受感染</value>\n  </data>\n  <data name=\"SourceOpenWithFailedUpdate\" xml:space=\"preserve\">\n    <value>尝试更新源失败： {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to update the repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"UninstallCommandLongDescription\" xml:space=\"preserve\">\n    <value>通过搜索已安装的程序包列表或直接从清单中卸载选择的程序包。默认情况下，查询必须 insensitively 匹配程序包的 id、名称或名字对象。可通过传递适当的选项来使用其他字段。</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"UninstallCommandShortDescription\" xml:space=\"preserve\">\n    <value>卸载给定的程序包</value>\n  </data>\n  <data name=\"UninstallFlowStartingPackageUninstall\" xml:space=\"preserve\">\n    <value>正在启动程序包卸载...</value>\n  </data>\n  <data name=\"UninstallFlowUninstallSuccess\" xml:space=\"preserve\">\n    <value>已成功卸载</value>\n  </data>\n  <data name=\"NoUninstallInfoFound\" xml:space=\"preserve\">\n    <value>winget 找不到此程序包的卸载命令。请与程序包发布者联系以获取支持。</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"UninstallAbandoned\" xml:space=\"preserve\">\n    <value>卸载已放弃</value>\n  </data>\n  <data name=\"UninstallFailedWithCode\" xml:space=\"preserve\">\n    <value>卸载失败，退出代码为: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to uninstall an application package fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"ExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>导出已安装程序包的列表</value>\n  </data>\n  <data name=\"ImportCommandLongDescription\" xml:space=\"preserve\">\n    <value>安装文件中列出的所有程序包。</value>\n  </data>\n  <data name=\"ImportCommandShortDescription\" xml:space=\"preserve\">\n    <value>安装文件中的所有程序包</value>\n  </data>\n  <data name=\"OutputFileArgumentDescription\" xml:space=\"preserve\">\n    <value>将在其中写入结果的文件</value>\n  </data>\n  <data name=\"ImportFileArgumentDescription\" xml:space=\"preserve\">\n    <value>描述要安装的程序包的文件</value>\n  </data>\n  <data name=\"ExportSourceArgumentDescription\" xml:space=\"preserve\">\n    <value>从指定源导出程序包</value>\n  </data>\n  <data name=\"ExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>将已安装程序包的列表写入文件。然后可以通过 import 命令安装这些包。</value>\n    <comment>{Locked=\"import\"}</comment>\n  </data>\n  <data name=\"ImportInstallFailed\" xml:space=\"preserve\">\n    <value>无法安装一个或多个导入的程序包</value>\n  </data>\n  <data name=\"ImportSourceNotInstalled\" xml:space=\"preserve\">\n    <value>未安装导入所需的源： {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to import application package(s) from a repository source that is not installed. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"InstalledPackageNotAvailable\" xml:space=\"preserve\">\n    <value>无法从任何源获得已安装的程序包: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when the user attempts to export an installed application package that is not available from any repository source. {0} is a placeholder replaced by the installed package name.</comment>\n  </data>\n  <data name=\"InstalledPackageVersionNotAvailable\" xml:space=\"preserve\">\n    <value>无法从任何源获得已安装的程序包版本: {0} {1} {2}</value>\n    <comment>{Locked=\"{0} {1} {2}\"} Warning message displayed when the user attempts to export an installed application package with a version that is not available from any repository source. {0} is a placeholder replaced by the installed package identifier. {1} is a placeholder replaced by the installed package version. {2} is a placeholder replaced by the installed package channel.</comment>\n  </data>\n  <data name=\"NoPackagesInImportFile\" xml:space=\"preserve\">\n    <value>在导入文件中找不到程序包</value>\n  </data>\n  <data name=\"InvalidJsonFile\" xml:space=\"preserve\">\n    <value>JSON 文件无效</value>\n  </data>\n  <data name=\"MultiQueryPackageAlreadyInstalled\" xml:space=\"preserve\">\n    <value>已安装程序包: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user that an application package is already installed. {0} is a placeholder replaced by the package identifier or search query.</comment>\n  </data>\n  <data name=\"ImportIgnoreUnavailableArgumentDescription\" xml:space=\"preserve\">\n    <value>忽略不可用的程序包</value>\n  </data>\n  <data name=\"ExportIncludeVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>在导出文件中包括包版本</value>\n  </data>\n  <data name=\"ImportIgnoreVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>忽略导入文件中的程序包版本</value>\n  </data>\n  <data name=\"VerifyPathFailedNotExist\" xml:space=\"preserve\">\n    <value>路径不存在: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system path argument value that does not exist. {0} is a placeholder replaced by the user's provided path.</comment>\n  </data>\n  <data name=\"ImportFileHasInvalidSchema\" xml:space=\"preserve\">\n    <value>JSON 文件未指定可识别的架构。</value>\n  </data>\n  <data name=\"InstallScopeDescription\" xml:space=\"preserve\">\n    <value>选择安装范围 (user 或 machine)</value>\n    <comment>{Locked=\"user\",\"machine\"} This argument allows the user to select between installing for just the user or for the entire machine.</comment>\n  </data>\n  <data name=\"InvalidArgumentValueError\" xml:space=\"preserve\">\n    <value>为 '{0}' 参数提供的值无效;有效值为： {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message displayed when the user provides an invalid command line argument value. {0} is a placeholder replaced by the argument name. {1} is a placeholder replaced by a list of valid options.</comment>\n  </data>\n  <data name=\"DisabledByGroupPolicy\" xml:space=\"preserve\">\n    <value>组策略禁用此操作： {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user performs a command operation that is disabled by a group policy. {0} is a placeholder replaced by a group policy description.</comment>\n  </data>\n  <data name=\"PolicyAdditionalSources\" xml:space=\"preserve\">\n    <value>启用其他 Windows 应用安装程序源</value>\n  </data>\n  <data name=\"PolicyAllowedSources\" xml:space=\"preserve\">\n    <value>启用 Windows 应用安装程序允许的源</value>\n  </data>\n  <data name=\"PolicyEnableDefaultSource\" xml:space=\"preserve\">\n    <value>启用 Windows 应用安装程序默认源</value>\n  </data>\n  <data name=\"PolicyEnableExperimentalFeatures\" xml:space=\"preserve\">\n    <value>启用 Windows 应用安装程序实验性功能</value>\n  </data>\n  <data name=\"PolicyEnableMSStoreSource\" xml:space=\"preserve\">\n    <value>启用 Windows 应用安装程序 Microsoft Store 源</value>\n  </data>\n  <data name=\"PolicyEnableFontSource\" xml:space=\"preserve\">\n    <value>启用 Windows App 安装程序字体源</value>\n  </data>\n  <data name=\"PolicyEnableWinGetSettings\" xml:space=\"preserve\">\n    <value>启用 Windows 程序包管理器设置</value>\n  </data>\n  <data name=\"PolicyEnableWinGet\" xml:space=\"preserve\">\n    <value>启用 Windows 程序包管理器</value>\n  </data>\n  <data name=\"PolicyEnableWindowsPackageManagerCommandLineInterfaces\" xml:space=\"preserve\">\n    <value>启用 Windows 程序包管理器命令行接口</value>\n  </data>\n  <data name=\"PolicySourceAutoUpdateInterval\" xml:space=\"preserve\">\n    <value>设置 Windows 程序包管理器源自动更新间隔(分钟)</value>\n  </data>\n  <data name=\"PoliciesPolicy\" xml:space=\"preserve\">\n    <value>组策略</value>\n    <comment>Header for a table listing active Group Policies</comment>\n  </data>\n  <data name=\"PolicyEnableLocalManifests\" xml:space=\"preserve\">\n    <value>启用 Windows 应用安装程序本地清单文件</value>\n  </data>\n  <data name=\"PolicyEnableBypassCertificatePinningForMicrosoftStore\" xml:space=\"preserve\">\n    <value>启用 Windows 应用安装程序 Microsoft Store 源固定证书绕过</value>\n  </data>\n  <data name=\"PolicyEnableLocalArchiveMalwareScanOverride\" xml:space=\"preserve\">\n    <value>启用 Windows 应用安装程序 本地存档恶意软件扫描替代</value>\n  </data>\n  <data name=\"SettingsWarningField\" xml:space=\"preserve\">\n    <value>球场: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when a user setting field has invalid syntax or semantics. {0} is a placeholder replaced by the setting field path.</comment>\n  </data>\n  <data name=\"SettingsWarningInvalidFieldFormat\" xml:space=\"preserve\">\n    <value>字段格式无效。</value>\n  </data>\n  <data name=\"SettingsWarningInvalidFieldValue\" xml:space=\"preserve\">\n    <value>字段值无效。</value>\n  </data>\n  <data name=\"SettingsWarningInvalidValueFromPolicy\" xml:space=\"preserve\">\n    <value>组策略中的设置无效。</value>\n  </data>\n  <data name=\"SettingsWarningLoadedBackupSettings\" xml:space=\"preserve\">\n    <value>已从备份文件加载设置。</value>\n  </data>\n  <data name=\"SettingsWarningParseError\" xml:space=\"preserve\">\n    <value>分析文件时出错:</value>\n  </data>\n  <data name=\"SettingsWarningValue\" xml:space=\"preserve\">\n    <value>值: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when a user setting value has invalid syntax or semantics. {0} is a placeholder replaced by the setting data value.</comment>\n  </data>\n  <data name=\"FeaturesMessageDisabledByPolicy\" xml:space=\"preserve\">\n    <value>以下实验功能正在进行中。\n由于组策略，配置已被禁用。</value>\n  </data>\n  <data name=\"InstallerHashMismatchError\" xml:space=\"preserve\">\n    <value>安装程序哈希不匹配。</value>\n  </data>\n  <data name=\"PolicyEnableHashOverride\" xml:space=\"preserve\">\n    <value>启用 Windows 应用安装程序哈希替代</value>\n  </data>\n  <data name=\"SourceExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>将当前源作为组策略的 JSON 导出。</value>\n  </data>\n  <data name=\"SourceExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>导出当前源</value>\n  </data>\n  <data name=\"SourceListAdditionalSource\" xml:space=\"preserve\">\n    <value>其他源</value>\n    <comment>An additional source required by policy.</comment>\n  </data>\n  <data name=\"SourceListAllowedSource\" xml:space=\"preserve\">\n    <value>允许的源</value>\n    <comment>A source that the user is allowed to add.</comment>\n  </data>\n  <data name=\"InvalidArgumentValueErrorWithoutValidValues\" xml:space=\"preserve\">\n    <value>为 '{0}' 参数提供的值无效</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an invalid command line argument value. {0} is a placeholder replaced by the argument name.</comment>\n  </data>\n  <data name=\"Cancelled\" xml:space=\"preserve\">\n    <value>已取消</value>\n  </data>\n  <data name=\"ExternalDependencies\" xml:space=\"preserve\">\n    <value>外部</value>\n  </data>\n  <data name=\"ImportCommandReportDependencies\" xml:space=\"preserve\">\n    <value>在此导入中找到的包具有以下依赖项：</value>\n    <comment>Import command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"PackageRequiresDependencies\" xml:space=\"preserve\">\n    <value>此包需要以下依赖项：</value>\n    <comment>Message shown before reporting dependencies</comment>\n  </data>\n  <data name=\"DependenciesFlowInstall\" xml:space=\"preserve\">\n    <value>正在安装依赖项:</value>\n  </data>\n  <data name=\"DependenciesFlowSourceNotFound\" xml:space=\"preserve\">\n    <value>找不到依赖项源</value>\n  </data>\n  <data name=\"DependenciesFlowSourceTooManyMatches\" xml:space=\"preserve\">\n    <value>包搜索生成多个结果: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when application packages search yield more than one result. {0} is a placeholder replaced by the dependency package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowPackageVersionNotFound\" xml:space=\"preserve\">\n    <value>找不到包的最新版本: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when no suitable version found for the specific application package. {0} is a placeholder replaced by the package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoInstallerFound\" xml:space=\"preserve\">\n    <value>找不到安装程序: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when no installer found for a manifest. {0} is a placeholder replaced by the manifest identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoMinVersion\" xml:space=\"preserve\">\n    <value>包所需的最低版本不可用: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the minimum required version is not available for an application package. {0} is a placeholder replaced by the package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoMatches\" xml:space=\"preserve\">\n    <value>没有匹配项</value>\n    <comment>When package search yields no matches</comment>\n  </data>\n  <data name=\"DependenciesFlowContainsLoop\" xml:space=\"preserve\">\n    <value>具有循环</value>\n    <comment>Dependency graph has loop</comment>\n  </data>\n  <data name=\"DependenciesFlowNoSuitableInstallerFound\" xml:space=\"preserve\">\n    <value>找不到适用于清单的安装程序： {0} 版本 {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message displayed when an attempt to get a preferred installer for a manifest fails. {0} is a placeholder replaced by the manifest identifier. {1} is a placeholder replaced by the manifest version.</comment>\n  </data>\n  <data name=\"DependenciesManagementError\" xml:space=\"preserve\">\n    <value>处理包依赖项时出错。是否希望继续安装?</value>\n    <comment>Prompt message shown when dependencies processing yields errors.</comment>\n  </data>\n  <data name=\"DependenciesManagementExitMessage\" xml:space=\"preserve\">\n    <value>处理包依赖项时出错。正在退出...</value>\n  </data>\n  <data name=\"PackageDependencies\" xml:space=\"preserve\">\n    <value>程序包</value>\n  </data>\n  <data name=\"UninstallCommandReportDependencies\" xml:space=\"preserve\">\n    <value>此包具有可能不再需要的依赖项：</value>\n    <comment>Uninstall command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"ValidateCommandReportDependencies\" xml:space=\"preserve\">\n    <value>清单具有以下未验证的依赖项;确保它们有效：</value>\n    <comment>Validate command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"WindowsFeaturesDependencies\" xml:space=\"preserve\">\n    <value>Windows 功能</value>\n  </data>\n  <data name=\"WindowsLibrariesDependencies\" xml:space=\"preserve\">\n    <value>Windows 库</value>\n  </data>\n  <data name=\"DependencySourceArgumentDescription\" xml:space=\"preserve\">\n    <value>使用指定源查找包依赖项</value>\n    <comment>For getting package type dependencies when installing from a local manifest</comment>\n  </data>\n  <data name=\"WindowsStoreTerms\" xml:space=\"preserve\">\n    <value>Windows 应用商店条款</value>\n  </data>\n  <data name=\"AcceptPackageAgreementsArgumentDescription\" xml:space=\"preserve\">\n    <value>接受包的所有许可协议</value>\n  </data>\n  <data name=\"ExportedPackageRequiresLicenseAgreement\" xml:space=\"preserve\">\n    <value>导出的包需要安装许可协议： {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when an exported application package requires license agreement to install. {0} is a placeholder replaced by the package name.</comment>\n  </data>\n  <data name=\"PackageAgreementsPrompt\" xml:space=\"preserve\">\n    <value>发行商要求你在安装前查看上述信息并接受协议。\n是否同意上述条款?</value>\n  </data>\n  <data name=\"PackageAgreementsNotAgreedTo\" xml:space=\"preserve\">\n    <value>未同意包协议。操作已取消。</value>\n  </data>\n  <data name=\"ShowLabelAgreements\" xml:space=\"preserve\">\n    <value>协议：</value>\n  </data>\n  <data name=\"ShowLabelAuthor\" xml:space=\"preserve\">\n    <value>作者:</value>\n  </data>\n  <data name=\"ShowLabelDescription\" xml:space=\"preserve\">\n    <value>描述:</value>\n  </data>\n  <data name=\"ShowLabelInstaller\" xml:space=\"preserve\">\n    <value>安装：</value>\n  </data>\n  <data name=\"ShowLabelInstallerLocale\" xml:space=\"preserve\">\n    <value>安装程序区域设置：</value>\n  </data>\n  <data name=\"ShowLabelInstallerProductId\" xml:space=\"preserve\">\n    <value>应用商店产品 ID：</value>\n  </data>\n  <data name=\"ShowLabelInstallerSha256\" xml:space=\"preserve\">\n    <value>安装程序 SHA256：</value>\n  </data>\n  <data name=\"ShowLabelInstallerType\" xml:space=\"preserve\">\n    <value>安装程序类型：</value>\n  </data>\n  <data name=\"ShowLabelInstallerUrl\" xml:space=\"preserve\">\n    <value>安装程序 URL：</value>\n  </data>\n  <data name=\"ShowLabelLicense\" xml:space=\"preserve\">\n    <value>许可证:</value>\n  </data>\n  <data name=\"ShowLabelLicenseUrl\" xml:space=\"preserve\">\n    <value>许可证 URL:</value>\n  </data>\n  <data name=\"ShowLabelMoniker\" xml:space=\"preserve\">\n    <value>绰号：</value>\n  </data>\n  <data name=\"ShowLabelPackageUrl\" xml:space=\"preserve\">\n    <value>主页:</value>\n  </data>\n  <data name=\"ShowLabelPublisher\" xml:space=\"preserve\">\n    <value>发布者:</value>\n  </data>\n  <data name=\"ShowLabelTags\" xml:space=\"preserve\">\n    <value>标记：</value>\n  </data>\n  <data name=\"ShowLabelVersion\" xml:space=\"preserve\">\n    <value>版本:</value>\n  </data>\n  <data name=\"ShowLabelDependencies\" xml:space=\"preserve\">\n    <value>依赖项:</value>\n  </data>\n  <data name=\"ShowLabelWindowsFeaturesDependencies\" xml:space=\"preserve\">\n    <value>Windows 功能:</value>\n  </data>\n  <data name=\"ShowLabelWindowsLibrariesDependencies\" xml:space=\"preserve\">\n    <value>Windows 库:</value>\n  </data>\n  <data name=\"ShowLabelPackageDependencies\" xml:space=\"preserve\">\n    <value>包依赖项:</value>\n  </data>\n  <data name=\"ShowLabelExternalDependencies\" xml:space=\"preserve\">\n    <value>外部依赖项:</value>\n  </data>\n  <data name=\"PromptOptionNo\" xml:space=\"preserve\">\n    <value>否</value>\n  </data>\n  <data name=\"PromptOptionYes\" xml:space=\"preserve\">\n    <value>是</value>\n  </data>\n  <data name=\"SourceAddOpenSourceFailed\" xml:space=\"preserve\">\n    <value>无法打开添加的源。</value>\n  </data>\n  <data name=\"AcceptSourceAgreementsArgumentDescription\" xml:space=\"preserve\">\n    <value>在源操作期间接受所有源协议</value>\n  </data>\n  <data name=\"SourceAgreementsTitle\" xml:space=\"preserve\">\n    <value>“{0}”源要求在使用前查看以下协议。</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user that a repository source requires viewing agreements before using. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceAgreementsPrompt\" xml:space=\"preserve\">\n    <value>是否同意所有源协议条款?</value>\n  </data>\n  <data name=\"SourceAgreementsNotAgreedTo\" xml:space=\"preserve\">\n    <value>未同意一个或多个源协议。操作已取消。请接受源协议或删除相应的源。</value>\n  </data>\n  <data name=\"SourceAgreementsMarketMessage\" xml:space=\"preserve\">\n    <value>源要求将当前计算机的 2 个字母的地理区域发送到后端服务才能正常工作，(例如\"US\")。</value>\n  </data>\n  <data name=\"InstallFlowRegistrationDeferred\" xml:space=\"preserve\">\n    <value>已成功安装。重启应用程序以完成升级。</value>\n  </data>\n  <data name=\"HeaderArgumentDescription\" xml:space=\"preserve\">\n    <value>可选的 Windows-Package-Manager REST 源 HTTP 标头</value>\n  </data>\n  <data name=\"HeaderArgumentNotApplicableForNonRestSourceWarning\" xml:space=\"preserve\">\n    <value>忽略可选标头，因为它不适用于此源。</value>\n  </data>\n  <data name=\"HeaderArgumentNotApplicableWithoutSource\" xml:space=\"preserve\">\n    <value>在未指定源的情况下，可选标头不适用: \"{0}\"</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user performs an operation (e.g install) and provides the HTTP 'header' argument without specifying the repository source. {0} is a placeholder replaced by the header argument name.</comment>\n  </data>\n  <data name=\"ShowLabelInstallerReleaseDate\" xml:space=\"preserve\">\n    <value>发布日期:</value>\n  </data>\n  <data name=\"ShowLabelInstallerOfflineDistributionSupported\" xml:space=\"preserve\">\n    <value>支持脱机分发:</value>\n  </data>\n  <data name=\"ShowLabelPublisherUrl\" xml:space=\"preserve\">\n    <value>发布服务器 URL:</value>\n  </data>\n  <data name=\"ShowLabelPurchaseUrl\" xml:space=\"preserve\">\n    <value>购买 URL：</value>\n  </data>\n  <data name=\"ShowLabelPublisherSupportUrl\" xml:space=\"preserve\">\n    <value>发布服务器支持 URL:</value>\n  </data>\n  <data name=\"ShowLabelPrivacyUrl\" xml:space=\"preserve\">\n    <value>隐私 URL:</value>\n  </data>\n  <data name=\"ShowLabelCopyright\" xml:space=\"preserve\">\n    <value>版权所有:</value>\n  </data>\n  <data name=\"ShowLabelCopyrightUrl\" xml:space=\"preserve\">\n    <value>版权 URL:</value>\n  </data>\n  <data name=\"ShowLabelReleaseNotes\" xml:space=\"preserve\">\n    <value>发行说明:</value>\n  </data>\n  <data name=\"ShowLabelReleaseNotesUrl\" xml:space=\"preserve\">\n    <value>发行说明 URL:</value>\n  </data>\n  <data name=\"SearchFailureWarning\" xml:space=\"preserve\">\n    <value>搜索源时失败;结果将不包括在内： {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when searching a repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SearchFailureError\" xml:space=\"preserve\">\n    <value>搜索源时失败: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when searching a repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"FeatureDisabledByAdminSettingMessage\" xml:space=\"preserve\">\n    <value>此功能需要由管理员启用。若要启用它，请以管理员身份运行 “winget settings --enable {0}”。</value>\n    <comment>{Locked=\"winget settings --enable\", \"{0}\"}. Error message displayed when the user uses a feature that needs to be enabled by administrators. {0} is a placeholder replaced by the admin setting.</comment>\n  </data>\n  <data name=\"AdminSettingEnableDescription\" xml:space=\"preserve\">\n    <value>启用特定的管理员设置</value>\n  </data>\n  <data name=\"AdminSettingDisableDescription\" xml:space=\"preserve\">\n    <value>禁用特定管理员设置</value>\n  </data>\n  <data name=\"AdminSettingEnabled\" xml:space=\"preserve\">\n    <value>已启用管理员设置 '{0}'。</value>\n    <comment>{Locked=\"{0}\"} Message displayed when the user enables an admin setting. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"AdminSettingDisabled\" xml:space=\"preserve\">\n    <value>已禁用管理员设置 '{0}'。</value>\n    <comment>{Locked=\"{0}\"} Message displayed when the user disables an admin setting. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"AdminSettingHeader\" xml:space=\"preserve\">\n    <value>管理员设置</value>\n    <comment>Header for a table displaying admin settings.</comment>\n  </data>\n  <data name=\"InstallFlowReturnCodePackageInUse\" xml:space=\"preserve\">\n    <value>应用程序当前正在运行。退出应用程序，然后重试。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodePackageInUseByApplication\" xml:space=\"preserve\">\n    <value>安装程序修改的文件当前正由其他应用程序使用。退出应用程序，然后重试。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInstallInProgress\" xml:space=\"preserve\">\n    <value>另一个安装已在进行中。请稍后再试。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeFileInUse\" xml:space=\"preserve\">\n    <value>正在使用一个或多个文件。退出应用程序，然后重试。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeMissingDependency\" xml:space=\"preserve\">\n    <value>系统中缺少此包的依赖项。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeDiskFull\" xml:space=\"preserve\">\n    <value>你的电脑上没有更多空间。腾出空间，然后重试。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInsufficientMemory\" xml:space=\"preserve\">\n    <value>内存不足，无法安装。关闭其他应用程序，然后重试。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInvalidParameter\" xml:space=\"preserve\">\n    <value>其中一个安装参数无效。包安装日志可能包含其他详细信息。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeNoNetwork\" xml:space=\"preserve\">\n    <value>此应用程序需要 Internet 连接。请连接到网络，然后重试。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeContactSupport\" xml:space=\"preserve\">\n    <value>此应用程序在安装过程中遇到错误。请联系支持人员。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootRequiredToFinish\" xml:space=\"preserve\">\n    <value>重启电脑以完成安装。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootRequiredForInstall\" xml:space=\"preserve\">\n    <value>你的电脑将重启以完成安装。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootInitiated\" xml:space=\"preserve\">\n    <value>安装失败。请重新启动电脑，然后重试。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeCancelledByUser\" xml:space=\"preserve\">\n    <value>你已取消安装。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeAlreadyInstalled\" xml:space=\"preserve\">\n    <value>已安装此应用程序的另一个版本。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeDowngrade\" xml:space=\"preserve\">\n    <value>已安装此应用程序的更高版本。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeBlockedByPolicy\" xml:space=\"preserve\">\n    <value>组织策略正在阻止安装。请与管理员联系。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeSystemNotSupported\" xml:space=\"preserve\">\n    <value>当前系统配置不支持安装此包。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeCustomError\" xml:space=\"preserve\">\n    <value>安装失败，出现自定义安装程序错误。联系包支持。</value>\n  </data>\n  <data name=\"InstallAbandoned\" xml:space=\"preserve\">\n    <value>已放弃安装</value>\n  </data>\n  <data name=\"InstallerFailedWithCode\" xml:space=\"preserve\">\n    <value>安装程序失败，退出代码为: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the application installer fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"InstallerLogAvailable\" xml:space=\"preserve\">\n    <value>安装程序日志在以下位置可用: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about the system path of a diagnostic files containing information about the installer. {0} is a placeholder replaced by the diagnostic file system path.</comment>\n  </data>\n  <data name=\"SearchFailureErrorListMatches\" xml:space=\"preserve\">\n    <value>在工作源中找到以下包。\n若要继续操作，请使用--source选项指定其中一个。</value>\n    <comment>{Locked=\"--source\"} \"working sources\" as in \"sources that are working correctly\"</comment>\n  </data>\n  <data name=\"SearchFailureErrorNoMatches\" xml:space=\"preserve\">\n    <value>在工作源中找不到任何包。</value>\n    <comment>\"working sources\" as in \"sources that are working correctly\"</comment>\n  </data>\n  <data name=\"FeaturesMessageDisabledByBuild\" xml:space=\"preserve\">\n    <value>这是 Windows 程序包管理器的稳定版本。如果要尝试实验性功能，请安装预发布版本。请前往 https://github.com/microsoft/winget-cli 查看 GitHub 说明。</value>\n    <comment>{Locked=\"https://github.com/microsoft/winget-cli\"}</comment>\n  </data>\n  <data name=\"WindowsPackageManager\" xml:space=\"preserve\">\n    <value>Windows 程序包管理器 v{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying the product name and version. {0} is a placeholder replaced by the product version.</comment>\n  </data>\n  <data name=\"ImportIgnorePackageVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>忽略导入文件中的程序包版本</value>\n  </data>\n  <data name=\"CountOutOfBoundsError\" xml:space=\"preserve\">\n    <value>请求的结果数必须介于 1 和 1000 之间。</value>\n  </data>\n  <data name=\"CustomSwitchesArgumentDescription\" xml:space=\"preserve\">\n    <value>除默认值外，参数传递到安装程序</value>\n  </data>\n  <data name=\"UpgradeDifferentInstallTechnologyInNewerVersions\" xml:space=\"preserve\">\n    <value>找到了较新的版本，但安装技术与当前安装的版本不同。请卸载包并安装较新的版本。</value>\n  </data>\n  <data name=\"UpgradeDifferentInstallTechnology\" xml:space=\"preserve\">\n    <value>指定的较新版本的安装技术与当前安装的版本不同。请卸载包并安装较新的版本。</value>\n  </data>\n  <data name=\"WindowsPackageManagerPreview\" xml:space=\"preserve\">\n    <value>Windows 程序包管理器(预览) v{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying the preview product name and pre-release version. {0} is a placeholder replaced by the product version.</comment>\n  </data>\n  <data name=\"ArchitectureArgumentDescription\" xml:space=\"preserve\">\n    <value>选择体系结构</value>\n  </data>\n  <data name=\"IncludeUnknownArgumentDescription\" xml:space=\"preserve\">\n    <value>即使无法确定其当前版本，也可升级包</value>\n  </data>\n  <data name=\"IncludeUnknownInListArgumentDescription\" xml:space=\"preserve\">\n    <value>列出程序包，即使无法确定其当前版本。只能与 --upgrade-available 参数一起使用</value>\n    <comment>{Locked=\"--upgrade-available\"}</comment>\n  </data>\n  <data name=\"UpgradeUnknownVersionExplanation\" xml:space=\"preserve\">\n    <value>无法确定此包的版本号。若要继续升级，请将参数--include-unknown添加到上一命令。</value>\n    <comment>{Locked=\"--include-unknown\"}</comment>\n  </data>\n  <data name=\"UpgradeUnknownVersionCount\" xml:space=\"preserve\">\n    <value>{0} 程序包的版本号无法确定。使用 --include-unknown 查看所有结果。</value>\n    <comment>{Locked=\"{0}\",\"--include-unknown\"} {0} is a placeholder that is replaced by an integer number of packages that do not have notated versions. </comment>\n  </data>\n  <data name=\"UpgradeRequireExplicitCount\" xml:space=\"preserve\">\n    <value>{0} 程序包已固定，需要显式升级。</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by an integer number of packages that require explicit upgrades.</comment>\n  </data>\n  <data name=\"InvalidArgumentWithoutQueryError\" xml:space=\"preserve\">\n    <value>提供的参数只能与查询一起使用。</value>\n  </data>\n  <data name=\"SystemArchitecture\" xml:space=\"preserve\">\n    <value>系统体系结构: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for the system architecture. {0} is a placeholder replaced by the value of the system architecture (e.g. X64).</comment>\n  </data>\n  <data name=\"PreserveArgumentDescription\" xml:space=\"preserve\">\n    <value>保留由包创建的所有文件和目录(可移植)</value>\n  </data>\n  <data name=\"PurgeArgumentDescription\" xml:space=\"preserve\">\n    <value>删除包目录中的所有文件和目录(可移植)</value>\n  </data>\n  <data name=\"PressEnterToContinue\" xml:space=\"preserve\">\n    <value>按 Enter 键继续...</value>\n  </data>\n  <data name=\"RenameArgumentDescription\" xml:space=\"preserve\">\n    <value>要重命名可执行文件的值(可移植)</value>\n  </data>\n  <data name=\"WaitArgumentDescription\" xml:space=\"preserve\">\n    <value>提示用户在退出前按任意键</value>\n  </data>\n  <data name=\"InstallerElevationExpected\" xml:space=\"preserve\">\n    <value>安装程序将请求以管理员身份运行。期待提示。</value>\n  </data>\n  <data name=\"InstallerProhibitsElevation\" xml:space=\"preserve\">\n    <value>无法从管理员上下文运行安装程序。</value>\n  </data>\n  <data name=\"ModifiedPathRequiresShellRestart\" xml:space=\"preserve\">\n    <value>已修改路径环境变量；重启 shell 以使用新值。</value>\n  </data>\n  <data name=\"ProductCodeArgumentDescription\" xml:space=\"preserve\">\n    <value>使用产品代码进行筛选</value>\n  </data>\n  <data name=\"PortableRegistryCollisionOverridden\" xml:space=\"preserve\">\n    <value>具有相同名称但来自不同源的可移植包已存在；由于 --force 而继续</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"ReparsePointsNotSupportedError\" xml:space=\"preserve\">\n    <value>卷不支持重新分析点</value>\n  </data>\n  <data name=\"ReservedFilenameError\" xml:space=\"preserve\">\n    <value>指定的文件名不是有效的文件名</value>\n  </data>\n  <data name=\"OverwritingExistingFileAtMessage\" xml:space=\"preserve\">\n    <value>正在覆盖现有文件: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed to inform the user that an existing file is being overwritten. {0} is a placeholder replaced by the file system path.</comment>\n  </data>\n  <data name=\"NoPackageSelectionArgumentProvided\" xml:space=\"preserve\">\n    <value>未提供包选择参数；有关查找包的详细信息，请参阅帮助。</value>\n  </data>\n  <data name=\"PortableAliasAdded\" xml:space=\"preserve\">\n    <value>添加了命令行别名：</value>\n  </data>\n  <data name=\"PortableLinksMachine\" xml:space=\"preserve\">\n    <value>可移植链接目录(计算机)</value>\n  </data>\n  <data name=\"PortableLinksUser\" xml:space=\"preserve\">\n    <value>可移植链接目录(用户)</value>\n  </data>\n  <data name=\"PortableRootUser\" xml:space=\"preserve\">\n    <value>可移植包根目录(用户)</value>\n  </data>\n  <data name=\"PortableRoot\" xml:space=\"preserve\">\n    <value>可移植包根目录</value>\n  </data>\n  <data name=\"PortableRoot86\" xml:space=\"preserve\">\n    <value>可移植包根目录 (x86)</value>\n  </data>\n  <data name=\"PortableInstallFailed\" xml:space=\"preserve\">\n    <value>可移植安装失败;正在清理...</value>\n  </data>\n  <data name=\"PortableHashMismatchOverridden\" xml:space=\"preserve\">\n    <value>已修改可移植程序包；由于 --force 而继续进行</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"PortableHashMismatchOverrideRequired\" xml:space=\"preserve\">\n    <value>无法删除可移植程序包，因为它已被修改；要替代此检查，请使用 --force</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"FilesRemainInInstallDirectory\" xml:space=\"preserve\">\n    <value>文件保留在安装目录中: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when files remain in install directory. {0} is a placeholder replaced by the directory path.</comment>\n  </data>\n  <data name=\"PurgeInstallDirectory\" xml:space=\"preserve\">\n    <value>正在清除安装目录...</value>\n  </data>\n  <data name=\"UnableToPurgeInstallDirectory\" xml:space=\"preserve\">\n    <value>无法清除安装目录，因为它不是由 WinGet 创建的</value>\n  </data>\n  <data name=\"RelatedLink\" xml:space=\"preserve\">\n    <value>相关链接</value>\n  </data>\n  <data name=\"ShowLabelDocumentation\" xml:space=\"preserve\">\n    <value>文档:</value>\n  </data>\n  <data name=\"Notes\" xml:space=\"preserve\">\n    <value>注意: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for installation notes. {0} is a placeholder replaced by installation notes.</comment>\n  </data>\n  <data name=\"ShowLabelInstallationNotes\" xml:space=\"preserve\">\n    <value>安装说明：</value>\n  </data>\n  <data name=\"UnsupportedArgument\" xml:space=\"preserve\">\n    <value>此程序包不支持提供的参数</value>\n  </data>\n  <data name=\"ExtractArchiveFailed\" xml:space=\"preserve\">\n    <value>未能提取存档内容</value>\n  </data>\n  <data name=\"NestedInstallerNotFound\" xml:space=\"preserve\">\n    <value>嵌套安装程序文件不存在。确保嵌套安装程序的指定相对路径匹配： {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when nested installer file does not exist. {0} is a placeholder replaced by the nested installer file path.</comment>\n  </data>\n  <data name=\"InvalidPathToNestedInstaller\" xml:space=\"preserve\">\n    <value>嵌套安装程序的相对文件路径无效;路径指向安装目录之外的位置</value>\n  </data>\n  <data name=\"NestedInstallerNotSpecified\" xml:space=\"preserve\">\n    <value>没有为此程序包指定嵌套安装程序</value>\n  </data>\n  <data name=\"MultipleUnsupportedNestedInstallersSpecified\" xml:space=\"preserve\">\n    <value>只能为存档安装程序指定一个嵌套安装程序，除非它是可移植的或字体嵌套安装程序</value>\n  </data>\n  <data name=\"IncompatibleArgumentsProvided\" xml:space=\"preserve\">\n    <value>提供的命令行参数不兼容</value>\n  </data>\n  <data name=\"UpgradeArgumentDescription\" xml:space=\"preserve\">\n    <value>仅列出具有可用升级的包</value>\n  </data>\n  <data name=\"UpgradeAvailableForPinned\" xml:space=\"preserve\">\n    <value>以下程序包有可用的升级，但需要显式目标才能进行升级：</value>\n    <comment>\"require explicit targeting for upgrade\" means that the package will not be upgraded with all others unless an extra flag is added, or the package is mentioned explicitly</comment>\n  </data>\n  <data name=\"Downloading\" xml:space=\"preserve\">\n    <value>正在下载</value>\n    <comment>Label displayed while downloading an application installer.</comment>\n  </data>\n  <data name=\"NestedInstallerNotSupported\" xml:space=\"preserve\">\n    <value>不支持嵌套安装程序类型</value>\n  </data>\n  <data name=\"InstallerAbortsTerminal\" xml:space=\"preserve\">\n    <value>已知此安装程序重启终端或 shell</value>\n  </data>\n  <data name=\"InstallerRequiresInstallLocation\" xml:space=\"preserve\">\n    <value>此程序包需要安装位置</value>\n  </data>\n  <data name=\"InstallersAbortTerminal\" xml:space=\"preserve\">\n    <value>已知以下安装程序重启终端或 shell：</value>\n  </data>\n  <data name=\"InstallersRequireInstallLocation\" xml:space=\"preserve\">\n    <value>以下安装程序需要安装位置：</value>\n  </data>\n  <data name=\"PromptForInstallRoot\" xml:space=\"preserve\">\n    <value>指定安装根目录：</value>\n  </data>\n  <data name=\"PromptToProceed\" xml:space=\"preserve\">\n    <value>是否继续?</value>\n  </data>\n  <data name=\"ReportIdentityForAgreements\" xml:space=\"preserve\">\n    <value>的协议</value>\n    <comment>This will be followed by a package name, and then a list of license agreements</comment>\n  </data>\n  <data name=\"InstallLocationNotProvided\" xml:space=\"preserve\">\n    <value>此程序包需要安装位置，但未提供</value>\n  </data>\n  <data name=\"DisableInteractivityArgumentDescription\" xml:space=\"preserve\">\n    <value>禁用交互式提示</value>\n    <comment>Description for a command line argument, shown next to it in the help</comment>\n  </data>\n  <data name=\"ConvertInstallFlowToUpgrade\" xml:space=\"preserve\">\n    <value>找到已安装的现有包。正在尝试升级已安装的包...</value>\n  </data>\n  <data name=\"ForceArgumentDescription\" xml:space=\"preserve\">\n    <value>直接运行命令并继续处理与安全无关的问题</value>\n    <comment>Description for a command line argument, shown next to it in the help</comment>\n  </data>\n  <data name=\"PortablePackageAlreadyExists\" xml:space=\"preserve\">\n    <value>已存在来自其他源的可移植包</value>\n  </data>\n  <data name=\"ExtractArchiveSucceeded\" xml:space=\"preserve\">\n    <value>已成功提取存档</value>\n  </data>\n  <data name=\"ExtractingArchive\" xml:space=\"preserve\">\n    <value>正在提取存档...</value>\n  </data>\n  <data name=\"ArchiveFailedMalwareScan\" xml:space=\"preserve\">\n    <value>存档扫描检测到恶意软件。若要替代此检查，请使用 --ignore-local-archive-malware-scan</value>\n    <comment>{Locked=\"--ignore-local-archive-malware-scan\"}</comment>\n  </data>\n  <data name=\"ArchiveFailedMalwareScanOverridden\" xml:space=\"preserve\">\n    <value>存档扫描检测到恶意软件。由于 --ignore-local-archive-malware-scan 而继续</value>\n    <comment>{Locked=\"--ignore-local-archive-malware-scan\"}</comment>\n  </data>\n  <data name=\"NoUpgradeArgumentDescription\" xml:space=\"preserve\">\n    <value>如果已安装的版本已存在，则跳过升级</value>\n  </data>\n  <data name=\"PackageAlreadyInstalled\" xml:space=\"preserve\">\n    <value>已安装包版本。已取消安装。</value>\n  </data>\n  <data name=\"EnableAdminSettingFailed\" xml:space=\"preserve\">\n    <value>无法启用{0}。此设置由策略控制。有关详细信息，请与系统管理员联系。</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"DisableAdminSettingFailed\" xml:space=\"preserve\">\n    <value>无法禁用{0}。此设置由策略控制。有关详细信息，请与系统管理员联系。</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"PinAddCommandLongDescription\" xml:space=\"preserve\">\n    <value>添加新的包钉。包钉可以限制 Windows 程序包管理器将包升级到特定范围的版本，也可以阻止它对包进行任何升级。被固定的包仍然可以自行升级，并在 Windows 程序包管理器之外进行升级。默认情况下，可通过在 \"upgrade\" 命令中显式提及被固定的包或将 \"--include-pinned\" 标志添加到 \"winget upgrade --all\" 来升级被固定的包。</value>\n    <comment>{Locked{\"'upgrade'\"} Locked{\"--include-pinned\"} Locked{\"winget upgrade --all\"}</comment>\n  </data>\n  <data name=\"PinAddCommandShortDescription\" xml:space=\"preserve\">\n    <value>添加新的包钉</value>\n  </data>\n  <data name=\"PinCommandLongDescription\" xml:space=\"preserve\">\n    <value>使用子命令管理包钉。包钉可以限制 Windows 程序包管理器将包升级到特定范围的版本，也可以阻止它对包进行任何升级。被固定的包仍然可以自行升级，并在 Windows 程序包管理器之外进行升级。</value>\n  </data>\n  <data name=\"PinCommandShortDescription\" xml:space=\"preserve\">\n    <value>管理包钉</value>\n  </data>\n  <data name=\"PinListCommandLongDescription\" xml:space=\"preserve\">\n    <value>列出当前所有固定或特定 PIN 的完整详细信息。</value>\n  </data>\n  <data name=\"PinListCommandShortDescription\" xml:space=\"preserve\">\n    <value>列出当前包钉</value>\n  </data>\n  <data name=\"PinRemoveCommandLongDescription\" xml:space=\"preserve\">\n    <value>删除特定包钉。</value>\n  </data>\n  <data name=\"PinRemoveCommandShortDescription\" xml:space=\"preserve\">\n    <value>删除包钉</value>\n  </data>\n  <data name=\"PinResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>重置所有现有包钉。</value>\n  </data>\n  <data name=\"PinResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>重置包钉</value>\n  </data>\n  <data name=\"GatedVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>要将包钉到的版本。通配符 \"*\" 可用作最后一个版本部件</value>\n  </data>\n  <data name=\"PinAddBlockingArgumentDescription\" xml:space=\"preserve\">\n    <value>阻止升级，直到移除包钉，阻止替代参数</value>\n  </data>\n  <data name=\"PinInstalledArgumentDescription\" xml:space=\"preserve\">\n    <value>固定特定的已安装版本</value>\n  </data>\n  <data name=\"PinInstalledSource\" xml:space=\"preserve\">\n    <value>已安装</value>\n    <comment>Value used in a table to indicate that a package comes from the list of packages installed in the machine</comment>\n  </data>\n  <data name=\"SettingsExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>将设置导出为 JSON</value>\n  </data>\n  <data name=\"SettingsExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>导出设置</value>\n  </data>\n  <data name=\"UserSettings\" xml:space=\"preserve\">\n    <value>用户设置</value>\n    <comment>Label displayed for the file containing the user settings.</comment>\n  </data>\n  <data name=\"SettingsWarningUsingDefault\" xml:space=\"preserve\">\n    <value>无法加载设置文件。正在使用默认值。</value>\n  </data>\n  <data name=\"InstalledScopeArgumentDescription\" xml:space=\"preserve\">\n    <value>选择已安装的程序包范围筛选器 (user 或 machine)</value>\n    <comment>{Locked=\"user\",\"machine\"} This argument allows the user to select installed packages for just the user or for the entire machine.</comment>\n  </data>\n  <data name=\"PinAdded\" xml:space=\"preserve\">\n    <value>已成功添加包钉</value>\n  </data>\n  <data name=\"PinAlreadyExists\" xml:space=\"preserve\">\n    <value>包{0}已存在 PIN</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that will be replaced by a package name. The message is shown when attempting to add a pin for a package that is already pinned.</comment>\n  </data>\n  <data name=\"PinExistsOverwriting\" xml:space=\"preserve\">\n    <value>程序包 {0} 已存在包钉。由于 --force 参数而覆盖。</value>\n    <comment>{Locked=\"--force\"}{Locked=\"--force\",\"{0}\"} {0} is a placeholder that will be replaced by a package name.</comment>\n  </data>\n  <data name=\"PinExistsUseForceArg\" xml:space=\"preserve\">\n    <value>包{0}已存在 pin。使用--force参数覆盖它。</value>\n    <comment>{Locked=\"--force\",\"{0}\"} {0} is a placeholder that will be replaced by a package name.</comment>\n  </data>\n  <data name=\"PinResettingAll\" xml:space=\"preserve\">\n    <value>正在重置所有当前包钉。</value>\n  </data>\n  <data name=\"PinResetUseForceArg\" xml:space=\"preserve\">\n    <value>使用--force参数重置所有固定。将删除以下 PIN：</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"PinType\" xml:space=\"preserve\">\n    <value>包钉类型</value>\n  </data>\n  <data name=\"PinDoesNotExist\" xml:space=\"preserve\">\n    <value>程序包 {0} 无包钉</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that will be replaced by a package name. The message is shown when attempting to delete a pin for a package that is not pinned.</comment>\n  </data>\n  <data name=\"PinNoPinsExist\" xml:space=\"preserve\">\n    <value>没有已配置包钉。</value>\n    <comment>Shown when listing or modifying existing pins if there are none.</comment>\n  </data>\n  <data name=\"PinResetSuccessful\" xml:space=\"preserve\">\n    <value>已成功重置包钉</value>\n    <comment>Shown after resetting (deleting) all the pins</comment>\n  </data>\n  <data name=\"PinCannotOpenIndex\" xml:space=\"preserve\">\n    <value>无法打开包钉数据库。</value>\n    <comment>Error message for when we cannot open the database containing package pins.</comment>\n  </data>\n  <data name=\"ArgumentForSinglePackageProvidedWithMultipleQueries\" xml:space=\"preserve\">\n    <value>提供的参数只能用于单个程序包</value>\n  </data>\n  <data name=\"MultipleExclusiveArgumentsProvided\" xml:space=\"preserve\">\n    <value>已提供多个互相排斥的参数: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message shown when mutually incompatible command line arguments are used. {0} is a placeholder replaced by the arguments that cannot be specified together</comment>\n  </data>\n  <data name=\"DependencyArgumentMissing\" xml:space=\"preserve\">\n    <value>参数 {0} 只能与 {1} 一起使用</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message shown when having an argument needs another to be present, but that is missing. {0} and {1} are replaced by the arguments. For example \"Argument --include-unknown can only be used with --upgrade\"</comment>\n  </data>\n  <data name=\"StateDisabled\" xml:space=\"preserve\">\n    <value>已禁用</value>\n    <comment>As in enabled/disabled</comment>\n  </data>\n  <data name=\"StateEnabled\" xml:space=\"preserve\">\n    <value>已启用</value>\n    <comment>As in enabled/disabled</comment>\n  </data>\n  <data name=\"StateHeader\" xml:space=\"preserve\">\n    <value>状态</value>\n    <comment>Header for a table listing the state (enabled/disabled) of Group Policies and Settings</comment>\n  </data>\n  <data name=\"MultiQueryArgumentDescription\" xml:space=\"preserve\">\n    <value>用于搜索程序包的查询</value>\n  </data>\n  <data name=\"MultiQueryPackageNotFound\" xml:space=\"preserve\">\n    <value>未找到程序包: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches returns no results. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"MultiQuerySearchFoundMultiple\" xml:space=\"preserve\">\n    <value>已找到多个程序包: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches returns more than one result. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"MultiQuerySearchFailed\" xml:space=\"preserve\">\n    <value>搜索失败: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches fails. This message is for generic failures, we have more specific messages for when the search returns no results, or when it returns more than one result. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"UpgradeBlockedByPinCount\" xml:space=\"preserve\">\n    <value>{0} 程序包拥有需要在升级前移除的包钉</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by an integer number of packages with pins that prevent upgrade</comment>\n  </data>\n  <data name=\"UpgradeBlockedByManifest\" xml:space=\"preserve\">\n    <value>无法使用 winget 升级包。请使用发布者提供的方法升级此包。</value>\n  </data>\n  <data name=\"IncludePinnedArgumentDescription\" xml:space=\"preserve\">\n    <value>即使程序包拥有非阻止性包钉，也要升级程序包</value>\n  </data>\n  <data name=\"IncludePinnedInListArgumentDescription\" xml:space=\"preserve\">\n    <value>列出程序包，即使它们具有阻止升级的引脚。只能与 --upgrade-available 参数一起使用</value>\n    <comment>{Locked=\"--upgrade-available\"}</comment>\n  </data>\n  <data name=\"PinRemovedSuccessfully\" xml:space=\"preserve\">\n    <value>已成功移除包钉</value>\n  </data>\n  <data name=\"UpgradeIsPinned\" xml:space=\"preserve\">\n    <value>已找到较新版本，但程序包拥有阻止对它进行升级的包钉。</value>\n  </data>\n  <data name=\"PackageIsPinned\" xml:space=\"preserve\">\n    <value>程序包已固定，无法进行升级。使用 'winget pin' 命令查看和编辑包钉。可以使用 --include-pinned 参数绕过一些包钉类型。</value>\n    <comment>{Locked=\"winget pin\",\"--include-pinned\"} Error shown when we block an upgrade due to the package being pinned</comment>\n  </data>\n  <data name=\"UpgradePinnedByUserCount\" xml:space=\"preserve\">\n    <value>{0} 程序包拥有阻止升级的包钉。使用 'winget pin' 命令查看和编辑包钉。使用 --include-pinned 参数可能显示更多结果。</value>\n    <comment>{Locked=\"winget pin\",\"--include-pinned\"} {0} is a placeholder replaced by an integer number of packages</comment>\n  </data>\n  <data name=\"ConfigureCommandLongDescription\" xml:space=\"preserve\">\n    <value>确保系统是否与提供配置所述的所需状态匹配。可以下载/执行处理器以达到所需状态。在应用配置和处理器之前，应检查它们以确保可信。</value>\n  </data>\n  <data name=\"ConfigureCommandShortDescription\" xml:space=\"preserve\">\n    <value>将系统配置为所需状态</value>\n  </data>\n  <data name=\"ConfigureShowCommandLongDescription\" xml:space=\"preserve\">\n    <value>显示提供的配置的详细信息。默认情况下，不会修改系统，但某些选项将导致下载和/或加载文件。</value>\n  </data>\n  <data name=\"ConfigureShowCommandShortDescription\" xml:space=\"preserve\">\n    <value>显示配置的详细信息</value>\n  </data>\n  <data name=\"ConfigureTestCommandLongDescription\" xml:space=\"preserve\">\n    <value>检查系统是否与提供配置所述的所需状态匹配。可以下载/执行处理器以测试所需状态。在执行配置和处理器之前，应检查它们以确保可信。</value>\n  </data>\n  <data name=\"ConfigureTestCommandShortDescription\" xml:space=\"preserve\">\n    <value>根据所需状态检查系统</value>\n  </data>\n  <data name=\"ConfigureValidateCommandLongDescription\" xml:space=\"preserve\">\n    <value>验证配置文件是否正确。</value>\n  </data>\n  <data name=\"ConfigureValidateCommandShortDescription\" xml:space=\"preserve\">\n    <value>验证配置文件</value>\n  </data>\n  <data name=\"ConfigurationFieldInvalidType\" xml:space=\"preserve\">\n    <value>配置文件中'{0}'的字段类型错误。</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the field name from the file.</comment>\n  </data>\n  <data name=\"ConfigurationFileArgumentDescription\" xml:space=\"preserve\">\n    <value>配置文件的路径</value>\n  </data>\n  <data name=\"ConfigurationFileInvalid\" xml:space=\"preserve\">\n    <value>配置文件无效。</value>\n  </data>\n  <data name=\"ConfigurationFileVersionUnknown\" xml:space=\"preserve\">\n    <value>配置文件版本 {0} 未知。</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the version of the configuration file.</comment>\n  </data>\n  <data name=\"ConfigurationAcceptWarningArgumentDescription\" xml:space=\"preserve\">\n    <value>接受配置警告，阻止交互式提示</value>\n  </data>\n  <data name=\"ConfigurationApply\" xml:space=\"preserve\">\n    <value>应用</value>\n    <comment>Indicates that this item is used to write state</comment>\n  </data>\n  <data name=\"ConfigurationAssert\" xml:space=\"preserve\">\n    <value>声明</value>\n    <comment>Indicates that this item is used to check/assert the state rather than write to it</comment>\n  </data>\n  <data name=\"ConfigurationDependencies\" xml:space=\"preserve\">\n    <value>依赖项：{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying a list of dependencies. {0} is replaced with a space separated list of identifiers referencing other items.</comment>\n  </data>\n  <data name=\"ConfigurationFailedToApply\" xml:space=\"preserve\">\n    <value>某些配置未成功应用。</value>\n  </data>\n  <data name=\"ConfigurationFailedToGetDetails\" xml:space=\"preserve\">\n    <value>无法获取有关配置的详细信息。</value>\n  </data>\n  <data name=\"ConfigurationInform\" xml:space=\"preserve\">\n    <value>通知</value>\n    <comment>Indicates that this item is used to retrieve values for future use rather than writing them</comment>\n  </data>\n  <data name=\"ConfigurationLocal\" xml:space=\"preserve\">\n    <value>本地</value>\n    <comment>Used to indicate that the item is present on the device.</comment>\n  </data>\n  <data name=\"ConfigurationModuleNameOnly\" xml:space=\"preserve\">\n    <value>模块：{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying a module name. {0} is replaced with the name of the module from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationModuleWithDetails\" xml:space=\"preserve\">\n    <value>模块：{0} 由 {1} [{2}]</value>\n    <comment>{Locked=\"{0}\",\"{1}\",\"{2}\"} Label displaying module information. {0} is replaced by the module name. {1} is replaced by the module author. {2} is replaced by a string indicating the source of the module.</comment>\n  </data>\n  <data name=\"ConfigurationSettings\" xml:space=\"preserve\">\n    <value>设置：</value>\n    <comment>Label for the values that are used as inputs for this item when applying state</comment>\n  </data>\n  <data name=\"ConfigurationSuccessfullyApplied\" xml:space=\"preserve\">\n    <value>已成功应用配置。</value>\n  </data>\n  <data name=\"ConfigurationUnitSuccessfullyApplied\" xml:space=\"preserve\">\n    <value>已成功应用单元。</value>\n  </data>\n  <data name=\"ConfigurationWaitingOnAnother\" xml:space=\"preserve\">\n    <value>正在将另一个配置应用到系统。此配置将尽快继续...</value>\n  </data>\n  <data name=\"ConfigurationWarning\" xml:space=\"preserve\">\n    <value>你有了解要执行配置设置的责任。Microsoft 不对你编写或导入的配置文件负责。此配置可能会更改 Windows 中的设置、安装软件、更改软件设置（包括安全设置），并代表你接受第三方程序包和服务的用户协议。运行此配置文件即表示你确认理解并同意这些资源和设置。安装的任何应用程序均由其所有者授权给你。Microsoft 不对第三方软件包或服务负责，也不向其授予任何许可证。</value>\n    <comment>Legal approved. Do not change without approval.</comment>\n  </data>\n  <data name=\"ConfigurationWarningPromptApply\" xml:space=\"preserve\">\n    <value>是否已审阅配置，是否要继续将其应用到系统？</value>\n    <comment>PM approved.</comment>\n  </data>\n  <data name=\"ConfigurationFileEmpty\" xml:space=\"preserve\">\n    <value>配置为空。</value>\n  </data>\n  <data name=\"WindowsFeatureNotFound\" xml:space=\"preserve\">\n    <value>未找到功能 [{0}]。</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Windows feature was not found on the system.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeatureOverrideRequired\" xml:space=\"preserve\">\n    <value>无法启用 Windows 功能依赖项。若要继续安装，请使用'--force'。</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"RebootRequiredToEnableWindowsFeatureOverrideRequired\" xml:space=\"preserve\">\n    <value>需要重新启动才能完全启用 Windows 功能；重写此检查使用 “--force”。</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeatureOverridden\" xml:space=\"preserve\">\n    <value>无法启用 Windows 功能依赖项；由于 --force 而继续</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.\n{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"EnablingWindowsFeature\" xml:space=\"preserve\">\n    <value>正在启用 [{0}]...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to the user regarding which Windows Feature is being enabled.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeature\" xml:space=\"preserve\">\n    <value>未能启用 [{0}] 功能: {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"}  An error when enabling a Windows Feature. {0} is a placeholder for the name of the Windows Feature.\n{1} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"RebootRequiredToEnableWindowsFeatureOverridden\" xml:space=\"preserve\">\n    <value>需要重新启动才能完全启用 Windows 功能；由于 --force 而继续</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.</comment>\n  </data>\n  <data name=\"InstallWaitingOnAnother\" xml:space=\"preserve\">\n    <value>正在等待另一个安装/卸载完成...</value>\n  </data>\n  <data name=\"PinVersion\" xml:space=\"preserve\">\n    <value>固定版本</value>\n    <comment>Table header for the version to which a package is pinned; meaning it should not update from that version.</comment>\n  </data>\n  <data name=\"ConfigurationDescriptionWasTruncated\" xml:space=\"preserve\">\n    <value>&lt;查看日志文件以了解更多详细信息&gt;</value>\n    <comment>The brackets are intended to make the value stand out from other text which it will follow. Any locale appropriate mechanism that achieves this is acceptable.</comment>\n  </data>\n  <data name=\"ConfigurationGettingDetails\" xml:space=\"preserve\">\n    <value>检索配置详细信息</value>\n  </data>\n  <data name=\"ConfigurationInitializing\" xml:space=\"preserve\">\n    <value>正在初始化配置系统</value>\n  </data>\n  <data name=\"ConfigurationReadingConfigFile\" xml:space=\"preserve\">\n    <value>读取配置文件</value>\n  </data>\n  <data name=\"ConfigurationUnitAssertHadNegativeResult\" xml:space=\"preserve\">\n    <value>系统未处于配置声明的所需状态。</value>\n  </data>\n  <data name=\"ConfigurationUnitFailed\" xml:space=\"preserve\">\n    <value>由于未知原因，此配置单元失败： {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedConfigSet\" xml:space=\"preserve\">\n    <value>配置单元因配置而失败： {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringGet\" xml:space=\"preserve\">\n    <value>尝试获取当前系统状态时配置单元失败。</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringSet\" xml:space=\"preserve\">\n    <value>尝试应用所需状态时配置单元失败。</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringTest\" xml:space=\"preserve\">\n    <value>尝试测试当前系统状态时配置单元失败。</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedInternal\" xml:space=\"preserve\">\n    <value>由于内部错误，配置单元失败： {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedPrecondition\" xml:space=\"preserve\">\n    <value>配置单元失败，因为前提条件无效： {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedSystemState\" xml:space=\"preserve\">\n    <value>配置单元因系统状态而失败： {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedUnitProcessing\" xml:space=\"preserve\">\n    <value>尝试运行配置单元时失败： {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitHasDuplicateIdentifier\" xml:space=\"preserve\">\n    <value>配置多次包含标识符 “{0}”。</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by the identifier string from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationUnitHasMissingDependency\" xml:space=\"preserve\">\n    <value>在配置中找不到依赖项 “{0}”。</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by the identifier string from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationUnitManuallySkipped\" xml:space=\"preserve\">\n    <value>已手动跳过此配置单元。</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleConflict\" xml:space=\"preserve\">\n    <value>配置单元的模块在具有相同版本的多个位置可用。</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleImportFailed\" xml:space=\"preserve\">\n    <value>加载配置单元的模块失败。</value>\n  </data>\n  <data name=\"ConfigurationUnitMultipleMatches\" xml:space=\"preserve\">\n    <value>已找到配置单元的多个匹配项；指定模块以选择正确的模块。</value>\n  </data>\n  <data name=\"ConfigurationUnitNotFound\" xml:space=\"preserve\">\n    <value>未找到配置单元。</value>\n  </data>\n  <data name=\"ConfigurationUnitNotFoundInModule\" xml:space=\"preserve\">\n    <value>配置单元未按预期位于模块中。</value>\n  </data>\n  <data name=\"ConfigurationUnitNotRunDueToDependency\" xml:space=\"preserve\">\n    <value>此配置单元未运行，因为依赖项失败或未运行。</value>\n  </data>\n  <data name=\"ConfigurationUnitNotRunDueToFailedAssert\" xml:space=\"preserve\">\n    <value>此配置单元未运行，因为声明失败或为 False。</value>\n  </data>\n  <data name=\"ConfigurationUnitReturnedInvalidResult\" xml:space=\"preserve\">\n    <value>配置单元在执行过程中返回了意外结果。</value>\n  </data>\n  <data name=\"ConfigurationUnitSkipped\" xml:space=\"preserve\">\n    <value>由于未知原因，未运行此配置单元： {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationFieldInvalidValue\" xml:space=\"preserve\">\n    <value>字段“{0}”的值无效: {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} An error in reading a configuration file. {0} is a placeholder replaced by the field name from the file. {1} is a placeholder for the invalid value.</comment>\n  </data>\n  <data name=\"ConfigurationFieldMissing\" xml:space=\"preserve\">\n    <value>字段“{0}”缺失或为空。</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the expected field name from the file.</comment>\n  </data>\n  <data name=\"SeeLineAndColumn\" xml:space=\"preserve\">\n    <value>请参阅文件中的行{0}、列{1}。</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Indicates the file location of the error, {0} and {1} are placeholders for numbers of the line and column, respectively.</comment>\n  </data>\n  <data name=\"CancellingOperation\" xml:space=\"preserve\">\n    <value>正在取消操作</value>\n  </data>\n  <data name=\"InstallStubPackageDescription\" xml:space=\"preserve\">\n    <value>安装 AppInstaller 的存根包</value>\n  </data>\n  <data name=\"InstallFullPackageDescription\" xml:space=\"preserve\">\n    <value>安装 AppInstaller 的完整包</value>\n  </data>\n  <data name=\"ExtendedFeaturesEnableMessage\" xml:space=\"preserve\">\n    <value>请启用扩展功能。需要应用商店访问权限。</value>\n  </data>\n  <data name=\"ExtendedFeaturesEnableArgumentError\" xml:space=\"preserve\">\n    <value>选项“--enable”和“--disable”不能与其他参数一起使用。</value>\n    <comment>{Locked=\"--enable\", \"--disable\"}</comment>\n  </data>\n  <data name=\"ExtendedFeaturesEnablingMessage\" xml:space=\"preserve\">\n    <value>正在启用扩展功能。需要应用商店访问权限。</value>\n  </data>\n  <data name=\"ExtendedFeaturesNotEnabledMessage\" xml:space=\"preserve\">\n    <value>未启用扩展功能。运行 `winget configure --enable` 来启用它们。</value>\n    <comment>{Locked=\"winget configure --enable\"}</comment>\n  </data>\n  <data name=\"ExtendedFeaturesEnabledMessage\" xml:space=\"preserve\">\n    <value>扩展功能已启用。</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisableMessage\" xml:space=\"preserve\">\n    <value>禁用扩展功能。需要存储权限。</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisablingMessage\" xml:space=\"preserve\">\n    <value>正在禁用扩展功能。需要应用商店访问权限。</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisabledMessage\" xml:space=\"preserve\">\n    <value>扩展功能已禁用。</value>\n  </data>\n  <data name=\"SkipDependenciesArgumentDescription\" xml:space=\"preserve\">\n    <value>跳过处理包依赖项和 Windows 功能</value>\n  </data>\n  <data name=\"DependenciesSkippedMessage\" xml:space=\"preserve\">\n    <value>已跳过依赖项。</value>\n  </data>\n  <data name=\"FailedToRefreshPathWarning\" xml:space=\"preserve\">\n    <value>无法刷新进程的 PATH 变量。依赖于对 PATH 变量的更改的后续安装可能会失败。</value>\n    <comment>{Locked=\"PATH\"}</comment>\n  </data>\n  <data name=\"ConfigurationFailedToTest\" xml:space=\"preserve\">\n    <value>某些配置单元在测试其状态时失败。</value>\n  </data>\n  <data name=\"ConfigurationInDesiredState\" xml:space=\"preserve\">\n    <value>系统处于描述的配置状态。</value>\n  </data>\n  <data name=\"ConfigurationNoTestRun\" xml:space=\"preserve\">\n    <value>未测试配置状态。</value>\n  </data>\n  <data name=\"ConfigurationNotInDesiredState\" xml:space=\"preserve\">\n    <value>系统未处于描述的配置状态。</value>\n  </data>\n  <data name=\"ConfigurationUnexpectedTestResult\" xml:space=\"preserve\">\n    <value>意外的测试结果: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message. {0} will be replaced with the unexpected value (a number).</comment>\n  </data>\n  <data name=\"ConfigurationWarningPromptTest\" xml:space=\"preserve\">\n    <value>是否已审阅配置，是否要针对系统继续验证?</value>\n  </data>\n  <data name=\"ConfigurationFileInvalidYAML\" xml:space=\"preserve\">\n    <value>配置文件不是有效的 YAML 文件。</value>\n    <comment>{Locked=\"YAML\"} YAML is a file format name.</comment>\n  </data>\n  <data name=\"ConfigurationUnitIsPartOfDependencyCycle\" xml:space=\"preserve\">\n    <value>此配置单元是依赖项周期的一部分。</value>\n  </data>\n  <data name=\"ConfigurationValidationFoundNoIssues\" xml:space=\"preserve\">\n    <value>验证未发现任何问题。</value>\n  </data>\n  <data name=\"ConfigurationUnitNeedsPrereleaseWarning\" xml:space=\"preserve\">\n    <value>配置单元仅作为预发行版提供，但未在配置中以这种方式标记。将“allowPrerelease: true”添加到“directives”。</value>\n    <comment>{Locked=\"allowPrerelease: true\",\"directives\"} These are values in the configuration file that are not localized.</comment>\n  </data>\n  <data name=\"ConfigurationUnitNotInCatalogWarning\" xml:space=\"preserve\">\n    <value>已在本地找到配置单元，但在任何配置的目录中都找不到该配置单元。在应用配置之前，请确保它存在于任何系统上。</value>\n  </data>\n  <data name=\"ConfigurationUnitNotPublicWarning\" xml:space=\"preserve\">\n    <value>配置单元不可公开；确保将使用此配置的任何人都有权访问它。</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleNotProvidedWarning\" xml:space=\"preserve\">\n    <value>未提供模块。指定模块可提高性能并防止将来发生名称冲突。</value>\n  </data>\n  <data name=\"DownloadCommandLongDescription\" xml:space=\"preserve\">\n    <value>从所选包下载安装程序，通过搜索已配置的源找到或直接从清单中找到。默认情况下，查询必须以不区分大小写方式匹配包的 ID、名称或名字对象。可通过传递相应的选项来使用其他字段。默认情况下，下载命令会将相应的安装程序下载到用户的“下载”文件夹。</value>\n  </data>\n  <data name=\"DownloadCommandShortDescription\" xml:space=\"preserve\">\n    <value>从给定的程序包下载安装程序</value>\n  </data>\n  <data name=\"DownloadDirectoryArgumentDescription\" xml:space=\"preserve\">\n    <value>安装程序下载到的目录</value>\n  </data>\n  <data name=\"DependenciesFlowDownload\" xml:space=\"preserve\">\n    <value>正在下载依赖项:</value>\n  </data>\n  <data name=\"InstallerDownloaded\" xml:space=\"preserve\">\n    <value>已下载安装程序: {0}</value>\n    <comment>{Locked=\"{0}\"} Full path of the downloaded installer.</comment>\n  </data>\n  <data name=\"InstallerTypeArgumentDescription\" xml:space=\"preserve\">\n    <value>选择安装程序类型</value>\n  </data>\n  <data name=\"InstallerDownloads\" xml:space=\"preserve\">\n    <value>安装程序下载</value>\n  </data>\n  <data name=\"InstallerDownloadCommandProhibited\" xml:space=\"preserve\">\n    <value>禁止下载安装程序以供以后脱机安装。 </value>\n  </data>\n  <data name=\"ConfigurationAllUsersElevated\" xml:space=\"preserve\">\n    <value>“--module-path allusers”需要管理员权限才能执行。</value>\n    <comment>{Locked=\"--module-path allusers\"}</comment>\n  </data>\n  <data name=\"ConfigurationModulePath\" xml:space=\"preserve\">\n    <value>指定本地计算机上用于存储模块的位置。默认为 %LOCALAPPDATA%\\Microsoft\\WinGet\\Configuration\\Modules</value>\n    <comment>{Locked=\"%LOCALAPPDATA%\\Microsoft\\WinGet\\Configuration\\Modules\"}</comment>\n  </data>\n  <data name=\"ConfigurationModulePathArgError\" xml:space=\"preserve\">\n    <value>`--module-path` 值必须为 `currentuser`、`allusers`、`default` 或绝对路径。</value>\n    <comment>{Locked=\"{--module-path}, {currentuser}, {allusers}, {default}}</comment>\n  </data>\n  <data name=\"PolicyEnableWinGetConfiguration\" xml:space=\"preserve\">\n    <value>启用 Windows 程序包管理器配置</value>\n  </data>\n  <data name=\"ErrorCommandLongDescription\" xml:space=\"preserve\">\n    <value>检索有关错误的信息。给定一个数字，输出将包含有关错误的详细信息，如果是 winget 特定的错误，则包括符号名称。给定一个字符串，将搜索 winget 特定的错误以查找此值。</value>\n  </data>\n  <data name=\"ErrorCommandShortDescription\" xml:space=\"preserve\">\n    <value>获取错误相关信息</value>\n  </data>\n  <data name=\"ErrorInputArgumentDescription\" xml:space=\"preserve\">\n    <value>要在错误信息中搜索的值</value>\n  </data>\n  <data name=\"ErrorNumberIsTooLarge\" xml:space=\"preserve\">\n    <value>给定的数字太大，无法为 HRESULT。</value>\n  </data>\n  <data name=\"UnknownErrorCode\" xml:space=\"preserve\">\n    <value>未知错误代码</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INTERNAL_ERROR\" xml:space=\"preserve\">\n    <value>内部错误</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS\" xml:space=\"preserve\">\n    <value>命令行参数无效</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMMAND_FAILED\" xml:space=\"preserve\">\n    <value>执行命令失败</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_FAILED\" xml:space=\"preserve\">\n    <value>打开清单失败</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CTRL_SIGNAL_RECEIVED\" xml:space=\"preserve\">\n    <value>已收到取消信号</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SHELLEXEC_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>运行 ShellExecute 失败</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_MANIFESTVERSION\" xml:space=\"preserve\">\n    <value>无法处理清单。清单版本高于支持的版本。请更新客户端。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_FAILED\" xml:space=\"preserve\">\n    <value>下载安装程序失败</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX\" xml:space=\"preserve\">\n    <value>无法写入索引;它是更高版本的架构</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INDEX_INTEGRITY_COMPROMISED\" xml:space=\"preserve\">\n    <value>索引已损坏</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCES_INVALID\" xml:space=\"preserve\">\n    <value>配置的源信息已损坏</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NAME_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>已配置源名称</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_SOURCE_TYPE\" xml:space=\"preserve\">\n    <value>源类型无效</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_BUNDLE\" xml:space=\"preserve\">\n    <value>MSIX 文件是捆绑包，不是程序包</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_DATA_MISSING\" xml:space=\"preserve\">\n    <value>缺少源所需的数据</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER\" xml:space=\"preserve\">\n    <value>所有安装程序都不适用于当前系统</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_HASH_MISMATCH\" xml:space=\"preserve\">\n    <value>安装程序文件的哈希与清单不匹配</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NAME_DOES_NOT_EXIST\" xml:space=\"preserve\">\n    <value>源名称不存在</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_ARG_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>已使用其他名称配置源位置</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICATIONS_FOUND\" xml:space=\"preserve\">\n    <value>找不到程序包</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_SOURCES_DEFINED\" xml:space=\"preserve\">\n    <value>未配置任何源</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_APPLICATIONS_FOUND\" xml:space=\"preserve\">\n    <value>找到多个与条件匹配的程序包</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_MANIFEST_FOUND\" xml:space=\"preserve\">\n    <value>找不到与条件匹配的清单</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXTENSION_PUBLIC_FAILED\" xml:space=\"preserve\">\n    <value>未能从源包获取公用文件夹</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMMAND_REQUIRES_ADMIN\" xml:space=\"preserve\">\n    <value>需要管理员权限才能运行命令</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NOT_SECURE\" xml:space=\"preserve\">\n    <value>源位置不安全</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>Microsoft Store 客户端遭到策略阻止</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_APP_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>Microsoft Store 应用遭到策略阻止</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXPERIMENTAL_FEATURE_DISABLED\" xml:space=\"preserve\">\n    <value>该功能当前正在开发中。可以使用 winget 设置启用它。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>未能安装 Microsoft Store 应用</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMPLETE_INPUT_BAD\" xml:space=\"preserve\">\n    <value>未能执行自动完成</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED\" xml:space=\"preserve\">\n    <value>未能初始化 XML 分析程序</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_MAPPING_KEY\" xml:space=\"preserve\">\n    <value>遇到无效的 YAML 密钥</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY\" xml:space=\"preserve\">\n    <value>遇到重复的 YAML 密钥</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_OPERATION\" xml:space=\"preserve\">\n    <value>YAML 操作无效</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_DOC_BUILD_FAILED\" xml:space=\"preserve\">\n    <value>未能生成 YAML 文档</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_EMITTER_STATE\" xml:space=\"preserve\">\n    <value>YAML 发出程序状态无效</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_DATA\" xml:space=\"preserve\">\n    <value>YAML 数据无效</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LIBYAML_ERROR\" xml:space=\"preserve\">\n    <value>LibYAML 错误</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_WARNING\" xml:space=\"preserve\">\n    <value>清单验证成功，但出现警告</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_FAILURE\" xml:space=\"preserve\">\n    <value>清单验证失败</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_MANIFEST\" xml:space=\"preserve\">\n    <value>清单无效</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>找不到适用的更新</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPDATE_ALL_HAS_FAILURE\" xml:space=\"preserve\">\n    <value>winget upgrade --all 完成，但出现故障</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_SECURITY_CHECK_FAILED\" xml:space=\"preserve\">\n    <value>安装程序未通过安全性检查</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_SIZE_MISMATCH\" xml:space=\"preserve\">\n    <value>下载大小与预期内容长度不匹配</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_UNINSTALL_INFO_FOUND\" xml:space=\"preserve\">\n    <value>找不到卸载命令</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXEC_UNINSTALL_COMMAND_FAILED\" xml:space=\"preserve\">\n    <value>运行卸载命令失败</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_BREAK_ITERATOR_ERROR\" xml:space=\"preserve\">\n    <value>ICU 中断迭代器错误</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_CASEMAP_ERROR\" xml:space=\"preserve\">\n    <value>ICU casemap 错误</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_REGEX_ERROR\" xml:space=\"preserve\">\n    <value>ICU 正则表达式错误</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_IMPORT_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>无法安装一个或多个导入的包</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NOT_ALL_PACKAGES_FOUND\" xml:space=\"preserve\">\n    <value>找不到一个或多个请求的包</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE\" xml:space=\"preserve\">\n    <value>Json 文件无效</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NOT_REMOTE\" xml:space=\"preserve\">\n    <value>源位置不是远程位置</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE\" xml:space=\"preserve\">\n    <value>配置的 REST 源不受支持。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA\" xml:space=\"preserve\">\n    <value>REST 源返回的数据无效</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>操作被组策略阻止</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_INTERNAL_ERROR\" xml:space=\"preserve\">\n    <value>Rest API 内部错误</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_URL\" xml:space=\"preserve\">\n    <value>REST 源 URL 无效</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_UNSUPPORTED_MIME_TYPE\" xml:space=\"preserve\">\n    <value>REST API 返回的 MIME 类型不受支持</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_VERSION\" xml:space=\"preserve\">\n    <value>REST 源合同版本无效</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE\" xml:space=\"preserve\">\n    <value>源数据已损坏或被篡改</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_STREAM_READ_FAILURE\" xml:space=\"preserve\">\n    <value>从流中读取时出错</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>未同意程序包协议</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PROMPT_INPUT_ERROR\" xml:space=\"preserve\">\n    <value>在提示中读取输入时出错</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST\" xml:space=\"preserve\">\n    <value>一个或多个源不支持搜索请求</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_ENDPOINT_NOT_FOUND\" xml:space=\"preserve\">\n    <value>找不到 Rest API 终结点。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_OPEN_FAILED\" xml:space=\"preserve\">\n    <value>未能打开源。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>未同意源协议</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CUSTOMHEADER_EXCEEDS_MAXLENGTH\" xml:space=\"preserve\">\n    <value>标头大小超过了允许的 1024 个字符的限制。请减小大小，然后重试。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MISSING_RESOURCE_FILE\" xml:space=\"preserve\">\n    <value>缺少资源文件</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSI_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>运行 MSI 安装失败</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT\" xml:space=\"preserve\">\n    <value>msiexec 的参数无效</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FAILED_TO_OPEN_ALL_SOURCES\" xml:space=\"preserve\">\n    <value>未能打开一个或多个源</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>未能验证依赖项</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MISSING_PACKAGE\" xml:space=\"preserve\">\n    <value>缺少一个或多个程序包</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_TABLE_COLUMN\" xml:space=\"preserve\">\n    <value>表列无效</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_NOT_NEWER\" xml:space=\"preserve\">\n    <value>升级版本不高于已安装的版本</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_UNKNOWN\" xml:space=\"preserve\">\n    <value>升级版本未知，未指定替代</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_CONVERSION_ERROR\" xml:space=\"preserve\">\n    <value>ICU 转换错误</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>未能安装可移植包</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_REPARSE_POINT_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>卷不支持重新分析点</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_PACKAGE_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>已存在来自其他源的可移植包。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_SYMLINK_PATH_IS_DIRECTORY\" xml:space=\"preserve\">\n    <value>无法创建符号链接。路径指向目录。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_PROHIBITS_ELEVATION\" xml:space=\"preserve\">\n    <value>无法从管理员上下文运行安装程序。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>未能卸载可移植包</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ARP_VERSION_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>未能根据索引验证 DisplayVersion 值。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_ARGUMENT\" xml:space=\"preserve\">\n    <value>一个或多个参数不受支持。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_BIND_WITH_EMBEDDED_NULL\" xml:space=\"preserve\">\n    <value>SQLite 不允许嵌入的 null 字符</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_NOT_FOUND\" xml:space=\"preserve\">\n    <value>在存档中找不到嵌套安装程序。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXTRACT_ARCHIVE_FAILED\" xml:space=\"preserve\">\n    <value>未能解压缩存档。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_INVALID_PATH\" xml:space=\"preserve\">\n    <value>提供的嵌套安装程序的相对文件路径无效。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PINNED_CERTIFICATE_MISMATCH\" xml:space=\"preserve\">\n    <value>服务器证书与任何预期值都不匹配。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_LOCATION_REQUIRED\" xml:space=\"preserve\">\n    <value>必须提供安装位置。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ARCHIVE_SCAN_FAILED\" xml:space=\"preserve\">\n    <value>存档恶意软件扫描失败。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>找到至少一个已安装的包版本。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PIN_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>包的 PIN 已存在。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PIN_DOES_NOT_EXIST\" xml:space=\"preserve\">\n    <value>包没有 PIN。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_OPEN_PINNING_INDEX\" xml:space=\"preserve\">\n    <value>无法打开 PIN 数据库。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>一个或多个应用程序安装失败</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>一个或多个应用程序未能安装</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NOT_ALL_QUERIES_FOUND_SINGLE\" xml:space=\"preserve\">\n    <value>一个或多个查询并不是恰好返回一个匹配项</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_PINNED\" xml:space=\"preserve\">\n    <value>包具有阻止升级的 PIN。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB\" xml:space=\"preserve\">\n    <value>当前安装的程序包是存根程序包</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_APPTERMINATION_RECEIVED\" xml:space=\"preserve\">\n    <value>已收到应用程序关闭信号</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_DEPENDENCIES\" xml:space=\"preserve\">\n    <value>未能下载程序包依赖项。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_COMMAND_PROHIBITED\" xml:space=\"preserve\">\n    <value>未能下载包。禁止下载以进行脱机安装。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SERVICE_UNAVAILABLE\" xml:space=\"preserve\">\n    <value>所需的服务正忙或不可用。请稍后重试。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESUME_ID_NOT_FOUND\" xml:space=\"preserve\">\n    <value>提供的 GUID 与有效的恢复状态不对应。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CLIENT_VERSION_MISMATCH\" xml:space=\"preserve\">\n    <value>当前客户端版本与已保存状态的客户端版本不匹配。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_RESUME_STATE\" xml:space=\"preserve\">\n    <value>恢复状态数据无效。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_OPEN_CHECKPOINT_INDEX\" xml:space=\"preserve\">\n    <value>无法打开检查点数据库。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESUME_LIMIT_EXCEEDED\" xml:space=\"preserve\">\n    <value>超过了最大恢复限制。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_AUTHENTICATION_INFO\" xml:space=\"preserve\">\n    <value>身份验证信息无效。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>不支持的身份验证方法。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED\" xml:space=\"preserve\">\n    <value>身份验证失败。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_INTERACTIVE_REQUIRED\" xml:space=\"preserve\">\n    <value>身份验证失败。需要交互式身份验证。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_CANCELLED_BY_USER\" xml:space=\"preserve\">\n    <value>身份验证失败。用户已取消。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_INCORRECT_ACCOUNT\" xml:space=\"preserve\">\n    <value>身份验证失败。经过身份验证的帐户不是所需的帐户。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE\" xml:space=\"preserve\">\n    <value>应用程序当前正在运行。退出应用程序，然后重试。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INSTALL_IN_PROGRESS\" xml:space=\"preserve\">\n    <value>另一个安装已在进行中。请稍后再试。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_FILE_IN_USE\" xml:space=\"preserve\">\n    <value>正在使用一个或多个文件。退出应用程序，然后重试。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_MISSING_DEPENDENCY\" xml:space=\"preserve\">\n    <value>系统中缺少此包的依赖项。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DISK_FULL\" xml:space=\"preserve\">\n    <value>你的电脑上没有更多空间。腾出空间，然后重试。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INSUFFICIENT_MEMORY\" xml:space=\"preserve\">\n    <value>内存不足，无法安装。关闭其他应用程序，然后重试。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_NO_NETWORK\" xml:space=\"preserve\">\n    <value>此应用程序需要 Internet 连接。请连接到网络，然后重试。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CONTACT_SUPPORT\" xml:space=\"preserve\">\n    <value>此应用程序在安装过程中遇到错误。请联系支持人员。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_TO_FINISH\" xml:space=\"preserve\">\n    <value>重启电脑以完成安装。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_FOR_INSTALL\" xml:space=\"preserve\">\n    <value>安装失败。请重新启动电脑，然后重试。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_INITIATED\" xml:space=\"preserve\">\n    <value>你的电脑将重启以完成安装。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CANCELLED_BY_USER\" xml:space=\"preserve\">\n    <value>你已取消安装。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>已安装此应用程序的另一个版本。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DOWNGRADE\" xml:space=\"preserve\">\n    <value>已安装此应用程序的更高版本。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>组织策略正在阻止安装。请与管理员联系。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DEPENDENCIES\" xml:space=\"preserve\">\n    <value>未能安装程序包依赖项。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE_BY_APPLICATION\" xml:space=\"preserve\">\n    <value>应用程序当前正由另一个应用程序使用。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INVALID_PARAMETER\" xml:space=\"preserve\">\n    <value>参数无效。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>系统不支持程序包。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_UPGRADE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>安装程序不支持升级现有包。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CUSTOM_ERROR\" xml:space=\"preserve\">\n    <value>安装失败，出现自定义安装程序错误。</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_ARP_ENTRY_NOT_FOUND\" xml:space=\"preserve\">\n    <value>找不到包的“应用和功能”条目。</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>安装位置不适用。</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_FOUND\" xml:space=\"preserve\">\n    <value>找不到安装位置。</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_HASH_MISMATCH\" xml:space=\"preserve\">\n    <value>现有文件的哈希不匹配。</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_NOT_FOUND\" xml:space=\"preserve\">\n    <value>找不到文件。</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK\" xml:space=\"preserve\">\n    <value>找到文件，但未检查哈希。</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_ACCESS_ERROR\" xml:space=\"preserve\">\n    <value>无法访问该文件。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE\" xml:space=\"preserve\">\n    <value>配置文件无效。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_YAML\" xml:space=\"preserve\">\n    <value>YAML 语法无效。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_FIELD_TYPE\" xml:space=\"preserve\">\n    <value>配置字段的类型无效。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION\" xml:space=\"preserve\">\n    <value>配置具有未知版本。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_SET_APPLY_FAILED\" xml:space=\"preserve\">\n    <value>应用配置时出错。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER\" xml:space=\"preserve\">\n    <value>配置包含重复的标识符。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MISSING_DEPENDENCY\" xml:space=\"preserve\">\n    <value>配置缺少依赖项。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED\" xml:space=\"preserve\">\n    <value>配置具有未满足的依赖项。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_ASSERTION_FAILED\" xml:space=\"preserve\">\n    <value>配置单元的断言失败。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MANUALLY_SKIPPED\" xml:space=\"preserve\">\n    <value>已手动跳过配置。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_WARNING_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>用户拒绝继续执行。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_SET_DEPENDENCY_CYCLE\" xml:space=\"preserve\">\n    <value>依赖项关系图包含无法解析的循环。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_FIELD_VALUE\" xml:space=\"preserve\">\n    <value>配置具有无效的字段值。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MISSING_FIELD\" xml:space=\"preserve\">\n    <value>配置缺少字段。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_TEST_FAILED\" xml:space=\"preserve\">\n    <value>某些配置单元在测试其状态时失败。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_TEST_NOT_RUN\" xml:space=\"preserve\">\n    <value>未测试配置状态。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_NOT_INSTALLED\" xml:space=\"preserve\">\n    <value>未安装配置单元。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_NOT_FOUND_REPOSITORY\" xml:space=\"preserve\">\n    <value>未找到配置单元。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_MULTIPLE_MATCHES\" xml:space=\"preserve\">\n    <value>已找到配置单元的多个匹配项；指定模块以选择正确的模块。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_GET\" xml:space=\"preserve\">\n    <value>尝试获取当前系统状态时配置单元失败。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_TEST\" xml:space=\"preserve\">\n    <value>尝试测试当前系统状态时配置单元失败。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_SET\" xml:space=\"preserve\">\n    <value>尝试应用所需状态时配置单元失败。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_MODULE_CONFLICT\" xml:space=\"preserve\">\n    <value>配置单元的模块在具有相同版本的多个位置可用。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE\" xml:space=\"preserve\">\n    <value>加载配置单元的模块失败。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_INVALID_RESULT\" xml:space=\"preserve\">\n    <value>配置单元在执行过程中返回了意外结果。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_SETTING_CONFIG_ROOT\" xml:space=\"preserve\">\n    <value>单元包含需要配置根的设置。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR\" xml:space=\"preserve\">\n    <value>配置处理器不支持此操作。</value>\n  </data>\n  <data name=\"Unavailable\" xml:space=\"preserve\">\n    <value>不可用</value>\n  </data>\n  <data name=\"EnableWindowsFeaturesSuccess\" xml:space=\"preserve\">\n    <value>已成功启用 Windows 功能依赖项</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE_ADMIN\" xml:space=\"preserve\">\n    <value>加载配置单元的模块失败，因为它需要管理员权限才能运行。</value>\n  </data>\n  <data name=\"ConfigurationUnitSettingConfigRoot\" xml:space=\"preserve\">\n    <value>单元包含需要配置根的设置。</value>\n  </data>\n  <data name=\"ConfigurationUnitImportModuleAdmin\" xml:space=\"preserve\">\n    <value>加载配置单元的模块失败，因为它需要管理员权限才能运行。</value>\n  </data>\n  <data name=\"ResumeCommandLongDescription\" xml:space=\"preserve\">\n    <value>通过传递已保存命令的唯一标识符来恢复执行以前保存的命令。这用于恢复可能因重新启动而终止的已执行命令。</value>\n  </data>\n  <data name=\"ResumeCommandShortDescription\" xml:space=\"preserve\">\n    <value>继续执行以前保存的命令。</value>\n  </data>\n  <data name=\"ResumeIdArgumentDescription\" xml:space=\"preserve\">\n    <value>要恢复的已保存状态的唯一标识符</value>\n  </data>\n  <data name=\"ClientVersionMismatchError\" xml:space=\"preserve\">\n    <value>不支持从其他客户端版本恢复状态： {0}</value>\n    <comment>{Locked= \"{0}\"} Message displayed to inform the user that the client version of the resume state does not match the current client version. {0} is a placeholder for the client version that created the resume state.</comment>\n  </data>\n  <data name=\"ResumeIdNotFoundError\" xml:space=\"preserve\">\n    <value>恢复状态不存在: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a guid that does not correspond to a valid saved state. {0} is a placeholder replaced by the provided guid string.</comment>\n  </data>\n  <data name=\"ResumeStateDataNotFoundError\" xml:space=\"preserve\">\n    <value>在恢复状态下找不到数据。</value>\n  </data>\n  <data name=\"CommandDoesNotSupportResumeMessage\" xml:space=\"preserve\">\n    <value>此命令不支持恢复。</value>\n  </data>\n  <data name=\"AllowRebootArgumentDescription\" xml:space=\"preserve\">\n    <value>如果适用，允许重启</value>\n  </data>\n  <data name=\"InitiatingReboot\" xml:space=\"preserve\">\n    <value>正在发起重启以完成操作...</value>\n  </data>\n  <data name=\"FailedToInitiateReboot\" xml:space=\"preserve\">\n    <value>未能发起重启。</value>\n  </data>\n  <data name=\"ResumeLimitExceeded\" xml:space=\"preserve\">\n    <value>恢复操作超出了允许的 {0} 恢复() 限制。若要手动恢复，请运行命令 “{1}”。</value>\n    <comment>{Locked=\"{0}\", \"{1}\"} {0} is a placeholder that is replaced by an integer number of the number of allowed resumes. {1} is a placeholder for the command to run to perform a manual resume.</comment>\n  </data>\n  <data name=\"IgnoreResumeLimitArgumentDescription\" xml:space=\"preserve\">\n    <value>忽略恢复已保存状态的限制</value>\n  </data>\n  <data name=\"UriSchemeNotSupported\" xml:space=\"preserve\">\n    <value>不支持 URI 方案: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the provided uri is not supported. {0} is a placeholder replaced by the provided uri.</comment>\n  </data>\n  <data name=\"UriNotWellFormed\" xml:space=\"preserve\">\n    <value>URI 格式不标准: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the provided uri is not well formed. {0} is a placeholder replaced by the provided uri.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitEmptyContent\" xml:space=\"preserve\">\n    <value>无法分析 {0} 配置单元设置内容或设置内容为空。</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder replaced by the input winget configure resource unit type.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitMissingRequiredArg\" xml:space=\"preserve\">\n    <value>{0} 配置单元缺少必需的参数： {1}</value>\n    <comment>{Locked=\"{0},{1}\"} {0} is a placeholder for the input winget configure resource unit type. {1} is placeholder for the missing arg.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitMissingRecommendedArg\" xml:space=\"preserve\">\n    <value>{0} 配置单元缺少建议的参数： {1}</value>\n    <comment>{Locked=\"{0},{1}\"} {0} is a placeholder for the input winget configure resource unit type. {1} is placeholder for the missing arg.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitKnownSourceConfliction\" xml:space=\"preserve\">\n    <value>WinGetSource 配置单元与已知源冲突: {0}</value>\n    <comment>{Locked=\"WinGetSource,{0}\"} {0} is a placeholder for the input winget source in the configuration unit settings.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitThirdPartySourceAssertion\" xml:space=\"preserve\">\n    <value>第三方源上的 WinGetSource 配置单元声明： {0}</value>\n    <comment>{Locked=\"WinGetSource,{0}\"} {0} is a placeholder for the input winget source in the configuration unit settings.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitBothPackageVersionAndUseLatest\" xml:space=\"preserve\">\n    <value>WinGetPackage 声明 UseLatest 和 Version。包 ID： {0}</value>\n    <comment>{Locked=\"WinGetPackage,UseLatest,Version,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitThirdPartySourceAssertionForPackage\" xml:space=\"preserve\">\n    <value>WinGetPackage 配置单元声明来自第三方源的包。包 ID： {0};源： {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitDependencySourceNotConfigured\" xml:space=\"preserve\">\n    <value>WinGetPackage 配置单元包依赖于以前未配置的第三方源。包 ID： {0};源： {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitDependencySourceNotDeclaredAsDependency\" xml:space=\"preserve\">\n    <value>WinGetPackage 配置单元包依赖于第三方源。建议在 uni dependsOn 节中声明依赖项。包 ID： {0};源： {1}</value>\n    <comment>{Locked=\"WinGetPackage,dependsOn,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageSourceOpenFailed\" xml:space=\"preserve\">\n    <value>无法验证 WinGetPackage 配置单元包。源打开失败。包 ID： {0};源： {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageNotFound\" xml:space=\"preserve\">\n    <value>无法验证 WinGetPackage 配置单元包。找不到包。包 ID： {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageMultipleFound\" xml:space=\"preserve\">\n    <value>无法验证 WinGetPackage 配置单元包。找到多个包。包 ID： {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageVersionNotFound\" xml:space=\"preserve\">\n    <value>无法验证 WinGetPackage 配置单元包。找不到包版本。包 ID： {0};版本 {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitPackageVersionSpecifiedWithOnlyOnePackageVersion\" xml:space=\"preserve\">\n    <value>使用特定版本指定的 WinGetPackage 配置单元包，而只有一个包版本可用。包 ID: {0}；版本: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackage\" xml:space=\"preserve\">\n    <value>无法验证 WinGetPackage 配置单元包。包 ID： {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"AuthenticationModeArgumentDescription\" xml:space=\"preserve\">\n    <value>指定身份验证窗口首选项(silent、silentPreferred 或 interactive)</value>\n    <comment>{Locked=\"silent\",\"silentPreferred\",\"interactive\"} This argument allows the user to select authentication window popup behavior.</comment>\n  </data>\n  <data name=\"AuthenticationAccountArgumentDescription\" xml:space=\"preserve\">\n    <value>指定用于身份验证的帐户</value>\n  </data>\n  <data name=\"SourceAddFailedAuthenticationNotSupported\" xml:space=\"preserve\">\n    <value>无法添加源。此 winget 版本不支持源的身份验证方法。请尝试升级到最新 winget 版本。</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"SourceRequiresAuthentication\" xml:space=\"preserve\">\n    <value>{0} 源需要身份验证。必要时可能会显示身份验证提示。将与源共享经过身份验证的信息以进行访问授权。</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"RepairCommandLongDescription\" xml:space=\"preserve\">\n    <value>修复通过搜索已安装的包列表或直接从清单中找到的所选包。默认情况下，查询必须以不区分大小写方式匹配包的 ID、名称或名字对象。可通过传递相应的选项来使用其他字段。</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"RepairCommandShortDescription\" xml:space=\"preserve\">\n    <value>修复所选包</value>\n  </data>\n  <data name=\"NoRepairInfoFound\" xml:space=\"preserve\">\n    <value>找不到此包的修复命令。请联系包发布者以获取支持。</value>\n  </data>\n  <data name=\"RepairDifferentInstallTechnology\" xml:space=\"preserve\">\n    <value>正在使用的安装程序技术与当前安装的版本不匹配。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_REPAIR_INFO_FOUND\" xml:space=\"preserve\">\n    <value>找不到修复命令。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_REPAIR_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>正在使用的安装程序技术不支持修复。</value>\n  </data>\n  <data name=\"RepairFlowRepairSuccess\" xml:space=\"preserve\">\n    <value>修复操作成功完成。</value>\n  </data>\n  <data name=\"RepairAbandoned\" xml:space=\"preserve\">\n    <value>已放弃修复</value>\n  </data>\n  <data name=\"RepairFlowStartingPackageRepair\" xml:space=\"preserve\">\n    <value>正在启动包修复...</value>\n  </data>\n  <data name=\"MSStoreRepairFailed\" xml:space=\"preserve\">\n    <value>未能修复 Microsoft Store 包。错误代码: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Microsoft Store application package fails to repair. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXEC_REPAIR_FAILED\" xml:space=\"preserve\">\n    <value>修复操作失败。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_REPAIR_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>修复操作不适用。</value>\n  </data>\n  <data name=\"RepairFlowNoMatchingVersion\" xml:space=\"preserve\">\n    <value>配置的源中没有可用的匹配包版本。</value>\n  </data>\n  <data name=\"RepairFlowReturnCodeSystemNotSupported\" xml:space=\"preserve\">\n    <value>当前系统配置不支持修复此包。</value>\n  </data>\n  <data name=\"RepairOperationNotSupported\" xml:space=\"preserve\">\n    <value>正在使用的安装程序技术不支持修复。</value>\n  </data>\n  <data name=\"NoAdminRepairForUserScopePackage\" xml:space=\"preserve\">\n    <value>使用管理员权限运行时，无法修复为用户范围安装的包。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED\" xml:space=\"preserve\">\n    <value>不允许对用户范围内安装的包执行涉及管理员特权的修复操作。</value>\n  </data>\n  <data name=\"RepairFailedWithCode\" xml:space=\"preserve\">\n    <value>修复失败，退出代码为: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to repair an application package fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SQLITE_CONNECTION_TERMINATED\" xml:space=\"preserve\">\n    <value>为了防止损坏，SQLite 连接已终止。</value>\n  </data>\n  <data name=\"UninstallAllVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>卸载所有版本</value>\n  </data>\n  <data name=\"TargetVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>要执行的版本</value>\n  </data>\n  <data name=\"UninstallFailedDueToMultipleVersions\" xml:space=\"preserve\">\n    <value>已安装此包的多个版本。请优化搜索，传递 “--version” 参数以选择一个，或传递 “--all-versions” 标志以卸载所有这些参数。</value>\n    <comment>{Locked=\"--version,--all-versions\"}</comment>\n  </data>\n  <data name=\"PolicyEnableProxyCommandLineOptions\" xml:space=\"preserve\">\n    <value>启用Windows 程序包管理器代理命令行选项</value>\n    <comment>Describes a Group Policy that can enable the use of the --proxy option to set a proxy</comment>\n  </data>\n  <data name=\"ProxyArgumentDescription\" xml:space=\"preserve\">\n    <value>设置要用于此执行的代理</value>\n  </data>\n  <data name=\"NoProxyArgumentDescription\" xml:space=\"preserve\">\n    <value>禁止对此执行使用代理</value>\n  </data>\n  <data name=\"ResetAdminSettingFailed\" xml:space=\"preserve\">\n    <value>无法重置 {0}。此设置由策略控制。有关详细信息，请与系统管理员联系。</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"ResetAdminSettingSucceeded\" xml:space=\"preserve\">\n    <value>重置管理员设置“{0}”。</value>\n    <comment>{Locked=\"{0}\"} Message displayed after the user resets an admin setting to its default value. Reset is used as verb in past tense. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"SetAdminSettingFailed\" xml:space=\"preserve\">\n    <value>无法设置 {0}。此设置由策略控制。有关详细信息，请与系统管理员联系。</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"SetAdminSettingSucceeded\" xml:space=\"preserve\">\n    <value>将管理员设置 '{0}' 设置为 '{1}'。</value>\n    <comment>{Locked=\"{0}\"} Message displayed after the user sets the value of an admin setting. Set is used as a verb in past tense. {0} is a placeholder replaced by the setting name. {1} is a placeholder replaced </comment>\n  </data>\n  <data name=\"SettingNameArgumentDescription\" xml:space=\"preserve\">\n    <value>要修改的设置的名称</value>\n  </data>\n  <data name=\"SettingValueArgumentDescription\" xml:space=\"preserve\">\n    <value>要为设置设置的值。</value>\n  </data>\n  <data name=\"SettingsResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>将管理员设置重置为其默认值。</value>\n  </data>\n  <data name=\"SettingsResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>将管理员设置重置为其默认值。</value>\n  </data>\n  <data name=\"SettingsSetCommandLongDescription\" xml:space=\"preserve\">\n    <value>设置管理员设置的值。</value>\n  </data>\n  <data name=\"SettingsSetCommandShortDescription\" xml:space=\"preserve\">\n    <value>设置管理员设置的值。</value>\n  </data>\n  <data name=\"SourceExplicitArgumentDescription\" xml:space=\"preserve\">\n    <value>除非指定，否则从发现中排除源</value>\n  </data>\n  <data name=\"SourceEditExplicitArgumentDescription\" xml:space=\"preserve\">\n    <value>从发现中排除源(true 或 false)</value>\n  </data>\n  <data name=\"SourceListExplicit\" xml:space=\"preserve\">\n    <value>显式</value>\n  </data>\n  <data name=\"SourceTrustLevelArgumentDescription\" xml:space=\"preserve\">\n    <value>源的信任级别 (无或受信任的)</value>\n  </data>\n  <data name=\"SourceListTrustLevel\" xml:space=\"preserve\">\n    <value>信任级别</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DISPLAYCATALOG_API_FAILED\" xml:space=\"preserve\">\n    <value>未能获取 Microsoft Store 程序包目录。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_DISPLAYCATALOG_PACKAGE\" xml:space=\"preserve\">\n    <value>未从 Microsoft Store 程序包目录中找到适用的 Microsoft Store 程序包。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SFSCLIENT_API_FAILED\" xml:space=\"preserve\">\n    <value>无法获取 Microsoft Store 程序包下载信息。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_SFSCLIENT_PACKAGE\" xml:space=\"preserve\">\n    <value>找不到适用于下载的Microsoft Store包。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED\" xml:space=\"preserve\">\n    <value>无法检索 Microsoft Store 程序包许可证。</value>\n  </data>\n  <data name=\"MSStoreDownloadNoApplicablePackageFound\" xml:space=\"preserve\">\n    <value>找不到适用的 Microsoft Store 程序包。</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageHashVerified\" xml:space=\"preserve\">\n    <value>已成功验证 Microsoft Store 程序包哈希</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageHashMismatch\" xml:space=\"preserve\">\n    <value>Microsoft Store 程序包哈希不匹配</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloaded\" xml:space=\"preserve\">\n    <value>已下载 Microsoft Store 程序包: {0}</value>\n    <comment>{Locked=\"{0}\"} Full path of the downloaded package.</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadFailed\" xml:space=\"preserve\">\n    <value>Microsoft Store 程序包下载失败: {0}</value>\n    <comment>{Locked=\"{0}\"} Package name.</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadSuccess\" xml:space=\"preserve\">\n    <value>已完成 Microsoft Store 程序包下载</value>\n  </data>\n  <data name=\"MSStoreDownloadMainPackages\" xml:space=\"preserve\">\n    <value>正在从 Microsoft Store 下载主程序包...</value>\n  </data>\n  <data name=\"MSStoreDownloadDependencyPackages\" xml:space=\"preserve\">\n    <value>正在从 Microsoft Store 下载依赖项程序包...</value>\n  </data>\n  <data name=\"MSStoreDownloadGetDownloadInfo\" xml:space=\"preserve\">\n    <value>正在检索 Microsoft Store 程序包下载信息</value>\n  </data>\n  <data name=\"MSStoreDownloadGetDownloadInfoFailed\" xml:space=\"preserve\">\n    <value>未能检索 Microsoft Store 程序包下载信息</value>\n  </data>\n  <data name=\"MSStoreDownloadGetLicense\" xml:space=\"preserve\">\n    <value>正在检索 Microsoft Store 程序包许可证</value>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseSuccess\" xml:space=\"preserve\">\n    <value>已保存 Microsoft Store 程序包许可证: {0}</value>\n    <comment>{Locked=\"{0}\"} License file full path.</comment>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseFailed\" xml:space=\"preserve\">\n    <value>未能检索 Microsoft Store 程序包许可证</value>\n  </data>\n  <data name=\"MSStoreDownloadRenameNotSupported\" xml:space=\"preserve\">\n    <value>Microsoft Store 程序包下载不支持 --rename 参数。Microsoft Store 程序包将使用 Microsoft Store 目录提供的名称。</value>\n    <comment>{Locked=\"--rename\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadAuthenticationNotice\" xml:space=\"preserve\">\n    <value>Microsoft Store包下载需要Microsoft Entra ID 身份验证。必要时可能会显示身份验证提示。将与Microsoft 服务共享经过身份验证的信息以进行访问授权。对于Microsoft Store包授权，Microsoft Entra ID 帐户必须是全局管理员、用户管理员或许可证管理员的成员。</value>\n    <comment>{Locked=\"Global Administrator,User Administrator,License Administrator\"}</comment>\n  </data>\n  <data name=\"SkipMicrosoftStorePackageLicenseArgumentDescription\" xml:space=\"preserve\">\n    <value>跳过检索 Microsoft Store 程序包脱机许可证</value>\n  </data>\n  <data name=\"PlatformArgumentDescription\" xml:space=\"preserve\">\n    <value>选择目标平台</value>\n  </data>\n  <data name=\"ConfigurationExportAddingToFile\" xml:space=\"preserve\">\n    <value>正在添加配置文件: {0}</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportSuccessful\" xml:space=\"preserve\">\n    <value>已成功导出</value>\n  </data>\n  <data name=\"ConfigurationGettingResourceSettings\" xml:space=\"preserve\">\n    <value>正在获取配置设置...</value>\n  </data>\n  <data name=\"ConfigureExportArgumentRequiredError\" xml:space=\"preserve\">\n    <value>必须至少提供 --packageId 和/或 --module with --resource。或使用 --all 导出所有包配置。</value>\n    <comment>{Locked=\"--packageId,--module, --resource, --all\"}</comment>\n  </data>\n  <data name=\"ConfigureExportArgumentConflictWithAllError\" xml:space=\"preserve\">\n    <value>参数 --packageId、--module 和 --resource 不能与 --all 一起使用。</value>\n    <comment>{Locked=\"--packageId,--module, --resource, --all\"}</comment>\n  </data>\n  <data name=\"ConfigureExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>将配置资源导出到配置文件。与 --all 一起使用时，导出所有包配置。与 --packageId 一起使用时，导出给定包 ID 的 WinGetPackage 资源。与 --module 和 --resource 一起使用时，获取资源的设置并将其导出到配置文件。如果输出配置文件已存在，则追加导出的配置资源。</value>\n    <comment>{Locked=\"WinGetPackage,--packageId,--module, --resource\"}</comment>\n  </data>\n  <data name=\"ConfigureExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>将配置资源导出到配置文件。</value>\n  </data>\n  <data name=\"ConfigureExportModule\" xml:space=\"preserve\">\n    <value>要导出的资源的模块。</value>\n  </data>\n  <data name=\"ConfigureExportPackageId\" xml:space=\"preserve\">\n    <value>要导出的程序包标识符。</value>\n  </data>\n  <data name=\"ConfigureExportResource\" xml:space=\"preserve\">\n    <value>要导出的配置资源。</value>\n  </data>\n  <data name=\"ConfigureExportAll\" xml:space=\"preserve\">\n    <value>导出所有包配置。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_GET_FAILED\" xml:space=\"preserve\">\n    <value>配置单元无法获取其属性。</value>\n  </data>\n  <data name=\"ConfigurationExportFailed\" xml:space=\"preserve\">\n    <value>导出配置失败。</value>\n  </data>\n  <data name=\"ConfigureExportUnitDescription\" xml:space=\"preserve\">\n    <value>配置{0}</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigureExportUnitInstallDescription\" xml:space=\"preserve\">\n    <value>安装 {0}</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationWarningSetViewTruncated\" xml:space=\"preserve\">\n    <value>对于此输出，配置文件中存在的某些数据被截断;检查文件内容的完整内容。</value>\n  </data>\n  <data name=\"ConfigurationWarningValueTruncated\" xml:space=\"preserve\">\n    <value>&lt;此值已被截断;检查文件内容以获取完整文本&gt;</value>\n    <comment>Keep some form of separator like the \"&lt;&gt;\" around the text so that it stands out from the preceding text.</comment>\n  </data>\n  <data name=\"ConfigureListCommandLongDescription\" xml:space=\"preserve\">\n    <value>显示已应用于系统的配置的高级别详细信息。然后，此数据可与 `configure` 命令一起使用以获取更多详细信息。</value>\n    <comment>{Locked=\"`configure`\"}</comment>\n  </data>\n  <data name=\"ConfigureListCommandShortDescription\" xml:space=\"preserve\">\n    <value>显示配置历史记录</value>\n  </data>\n  <data name=\"ConfigurationHistoryEmpty\" xml:space=\"preserve\">\n    <value>历史记录中没有配置。</value>\n  </data>\n  <data name=\"ConfigurationHistoryItemArgumentDescription\" xml:space=\"preserve\">\n    <value>从历史记录中选择项目</value>\n  </data>\n  <data name=\"ConfigurationHistoryItemNotFound\" xml:space=\"preserve\">\n    <value>找不到与提供的数据匹配的单个配置。提供与所需配置明确匹配的全名或标识符的一部分。</value>\n  </data>\n  <data name=\"ConfigurationHistoryRemoveArgumentDescription\" xml:space=\"preserve\">\n    <value>从历史记录中移除项</value>\n  </data>\n  <data name=\"ConfigureListFirstApplied\" xml:space=\"preserve\">\n    <value>首次应用</value>\n    <comment>Column header for date values indicating when a configuration was first applied to the system.</comment>\n  </data>\n  <data name=\"ConfigureListIdentifier\" xml:space=\"preserve\">\n    <value>标识符</value>\n  </data>\n  <data name=\"ConfigureListName\" xml:space=\"preserve\">\n    <value>名称</value>\n  </data>\n  <data name=\"ConfigureListOrigin\" xml:space=\"preserve\">\n    <value>来源</value>\n  </data>\n  <data name=\"ConfigureListPath\" xml:space=\"preserve\">\n    <value>路径</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_HISTORY_ITEM_NOT_FOUND\" xml:space=\"preserve\">\n    <value>找不到指定的配置。</value>\n  </data>\n  <data name=\"ConfigurationSetStateCompleted\" xml:space=\"preserve\">\n    <value>已完成</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStateInProgress\" xml:space=\"preserve\">\n    <value>正在进行</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStatePending\" xml:space=\"preserve\">\n    <value>待处理</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStateUnknown\" xml:space=\"preserve\">\n    <value>未知</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationStatusWatchArgumentDescription\" xml:space=\"preserve\">\n    <value>监视配置状态。</value>\n    <comment>As in \"to monitor the status of a configuration being applied\".</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateCompleted\" xml:space=\"preserve\">\n    <value>已完成</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateInProgress\" xml:space=\"preserve\">\n    <value>正在进行</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStatePending\" xml:space=\"preserve\">\n    <value>待处理</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateSkipped\" xml:space=\"preserve\">\n    <value>已跳过</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateUnknown\" xml:space=\"preserve\">\n    <value>未知</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigureListApplyBegun\" xml:space=\"preserve\">\n    <value>应用已启动</value>\n    <comment>When the configuration application started.</comment>\n  </data>\n  <data name=\"ConfigureListApplyEnded\" xml:space=\"preserve\">\n    <value>应用已结束</value>\n    <comment>When the configuration application ended.</comment>\n  </data>\n  <data name=\"ConfigureListResult\" xml:space=\"preserve\">\n    <value>结果</value>\n  </data>\n  <data name=\"ConfigureListResultDescription\" xml:space=\"preserve\">\n    <value>详细信息</value>\n  </data>\n  <data name=\"ConfigureListState\" xml:space=\"preserve\">\n    <value>状态</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigureListUnit\" xml:space=\"preserve\">\n    <value>单位</value>\n  </data>\n  <data name=\"StoreInstall_PackageNotAvailableForCurrentSystem\" xml:space=\"preserve\">\n    <value>该包与当前 Windows 版本或平台不兼容。</value>\n  </data>\n  <data name=\"ConfigurationSuppressPrologueArgumentDescription\" xml:space=\"preserve\">\n    <value>尽可能禁止显示初始配置详细信息</value>\n  </data>\n  <data name=\"MSStoreDownloadMultiplePackagesNotice\" xml:space=\"preserve\">\n    <value>可以针对不同的平台和体系结构下载多个Microsoft Store包。--platform，--architecture 可用于筛选包。</value>\n    <comment>{Locked=\"--platform--architecture\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseForbidden\" xml:space=\"preserve\">\n    <value>无法检索Microsoft Store包许可证。Microsoft Entra ID 帐户不是全局管理员、用户管理员或许可证管理员的成员。使用 --skip-license 跳过检索Microsoft Store包许可证。</value>\n    <comment>{Locked=\"Global Administrator,User Administrator,License Administrator,--skip-license\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadNotSupported\" xml:space=\"preserve\">\n    <value>Microsoft Store包不支持下载。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SFSCLIENT_PACKAGE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Microsoft Store包不支持下载。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED_FORBIDDEN\" xml:space=\"preserve\">\n    <value>无法检索Microsoft Store包许可证。Microsoft Entra ID 帐户没有所需的权限。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_PARAMETER_INTEGRITY_BOUNDARY\" xml:space=\"preserve\">\n    <value>无法跨完整性边界传递参数。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_ZERO_BYTE_FILE\" xml:space=\"preserve\">\n    <value>已下载零字节安装程序;请确保网络连接正常工作。</value>\n  </data>\n  <data name=\"InstallerZeroByteFile\" xml:space=\"preserve\">\n    <value>已下载零字节安装程序;请确保网络连接正常工作。</value>\n  </data>\n  <data name=\"FontCommandShortDescription\" xml:space=\"preserve\">\n    <value>管理字体</value>\n  </data>\n  <data name=\"FontCommandLongDescription\" xml:space=\"preserve\">\n    <value>使用子命令管理字体。可以安装、升级或卸载与 package 类似的字体。 </value>\n  </data>\n  <data name=\"FontFamily\" xml:space=\"preserve\">\n    <value>家庭</value>\n  </data>\n  <data name=\"FontFaces\" xml:space=\"preserve\">\n    <value>脸</value>\n    <comment>\"Faces\" represents the typeface of the font family such as 'Bold' or 'Italic'</comment>\n  </data>\n  <data name=\"FontFamilyNameArgumentDescription\" xml:space=\"preserve\">\n    <value>按家庭名称筛选结果</value>\n  </data>\n  <data name=\"FontFace\" xml:space=\"preserve\">\n    <value>脸</value>\n    <comment>\"Face\" represents the typeface of a font family such as 'Bold' or 'Italic'</comment>\n  </data>\n  <data name=\"FontFilePaths\" xml:space=\"preserve\">\n    <value>路径</value>\n  </data>\n  <data name=\"NoInstalledFontFound\" xml:space=\"preserve\">\n    <value>找不到匹配输入条件的已安装字体。</value>\n  </data>\n  <data name=\"FontListCommandShortDescription\" xml:space=\"preserve\">\n    <value>列出已安装的字体</value>\n  </data>\n  <data name=\"FontListCommandLongDescription\" xml:space=\"preserve\">\n    <value>列出所有已安装的字体、所有字体文件或特定字体的完整详细信息。</value>\n  </data>\n  <data name=\"FontVersion\" xml:space=\"preserve\">\n    <value>版本</value>\n  </data>\n  <data name=\"ConfigurationModules\" xml:space=\"preserve\">\n    <value>配置模块</value>\n    <comment>PowerShell Modules that are used for the Configuration feature</comment>\n  </data>\n  <data name=\"InstallerDownloadRequiresAuthentication\" xml:space=\"preserve\">\n    <value>包安装程序需要身份验证。必要时可能会显示身份验证提示。将与安装程序下载 URL 共享经过身份验证的信息。</value>\n  </data>\n  <data name=\"InstallerDownloadAuthenticationNotSupported\" xml:space=\"preserve\">\n    <value>无法下载安装程序。此 winget 版本不支持安装程序下载身份验证方法。请尝试升级到最新 winget 版本。</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"InstallerDownloadAuthenticationFailed\" xml:space=\"preserve\">\n    <value>未能下载安装程序。身份验证失败。</value>\n  </data>\n  <data name=\"ConfigurationProcessorPath\" xml:space=\"preserve\">\n    <value>指定配置处理器的路径</value>\n  </data>\n  <data name=\"DscCommandShortDescription\" xml:space=\"preserve\">\n    <value>DSC v3 资源命令</value>\n    <comment>DSC stands for \"Desired State Configuration\". It should already have a locked translation.</comment>\n  </data>\n  <data name=\"DscCommandLongDescription\" xml:space=\"preserve\">\n    <value>此处的子命令实现Desired State Configuration (DSC) v3 资源来配置 winget 和包。</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionGet\" xml:space=\"preserve\">\n    <value>获取资源状态</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionSet\" xml:space=\"preserve\">\n    <value>设置资源状态</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionWhatIf\" xml:space=\"preserve\">\n    <value>描述所需的状态更改</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionTest\" xml:space=\"preserve\">\n    <value>测试资源状态</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionDelete\" xml:space=\"preserve\">\n    <value>删除资源状态</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionExport\" xml:space=\"preserve\">\n    <value>获取所有状态实例</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionValidate\" xml:space=\"preserve\">\n    <value>验证组内容</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionResolve\" xml:space=\"preserve\">\n    <value>解析外部状态</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionAdapter\" xml:space=\"preserve\">\n    <value>运行适配器</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionSchema\" xml:space=\"preserve\">\n    <value>获取资源架构</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionManifest\" xml:space=\"preserve\">\n    <value>获取资源清单</value>\n  </data>\n  <data name=\"DscPackageResourceShortDescription\" xml:space=\"preserve\">\n    <value>管理包状态</value>\n  </data>\n  <data name=\"DscPackageResourceLongDescription\" xml:space=\"preserve\">\n    <value>通过 winget 管理包。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionExist\" xml:space=\"preserve\">\n    <value>指示实例是否应存在。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionInDesiredState\" xml:space=\"preserve\">\n    <value>指示实例是否处于所需状态。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageId\" xml:space=\"preserve\">\n    <value>包的标识符。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageSource\" xml:space=\"preserve\">\n    <value>包的源。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageVersion\" xml:space=\"preserve\">\n    <value>包的版本。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageMatchOption\" xml:space=\"preserve\">\n    <value>用于将标识符与包匹配的方法。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageUseLatest\" xml:space=\"preserve\">\n    <value>指示应安装该包的最新可用版本。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageInstallMode\" xml:space=\"preserve\">\n    <value>要使用的安装模式(如需要)。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageScope\" xml:space=\"preserve\">\n    <value>包的目标范围。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionAcceptAgreements\" xml:space=\"preserve\">\n    <value>指示是否接受源和包的协议。</value>\n  </data>\n  <data name=\"DscUserSettingsFileShortDescription\" xml:space=\"preserve\">\n    <value>管理用户设置文件</value>\n  </data>\n  <data name=\"DscUserSettingsFileLongDescription\" xml:space=\"preserve\">\n    <value>管理 winget 的用户设置。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionUserSettingsFileSettings\" xml:space=\"preserve\">\n    <value>设置 json 文件内容。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionUserSettingsFileAction\" xml:space=\"preserve\">\n    <value>用于应用设置的操作。</value>\n  </data>\n  <data name=\"CorrelationArgumentDescription\" xml:space=\"preserve\">\n    <value>已为相关性记录值</value>\n  </data>\n  <data name=\"DscSourceResourceShortDescription\" xml:space=\"preserve\">\n    <value>管理源配置</value>\n  </data>\n  <data name=\"DscSourceResourceLongDescription\" xml:space=\"preserve\">\n    <value>管理 winget 的源。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceName\" xml:space=\"preserve\">\n    <value>用于源的名称。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceArgument\" xml:space=\"preserve\">\n    <value>源的参数。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceType\" xml:space=\"preserve\">\n    <value>源的类型。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceTrustLevel\" xml:space=\"preserve\">\n    <value>源的信任级别。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceExplicit\" xml:space=\"preserve\">\n    <value>调用未指定源时是否包含源。</value>\n  </data>\n  <data name=\"ConfigurationApplyingUnit\" xml:space=\"preserve\">\n    <value>正在应用配置单元...</value>\n  </data>\n  <data name=\"ConfigurationExportingUnit\" xml:space=\"preserve\">\n    <value>正在导出配置单元...</value>\n  </data>\n  <data name=\"ConfigurationGettingUnitProcessors\" xml:space=\"preserve\">\n    <value>正在获取配置单元处理器...</value>\n  </data>\n  <data name=\"ConfigurationExportInstallRequiredModule\" xml:space=\"preserve\">\n    <value>确保导出所需的模块 [{0}]</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportInstallRequiredModuleFailed\" xml:space=\"preserve\">\n    <value>未能测试或获取所需的模块。将不导出相关设置。</value>\n  </data>\n  <data name=\"ConfigurationExportUnitStart\" xml:space=\"preserve\">\n    <value>导出 [{0}]</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportUnitFailed\" xml:space=\"preserve\">\n    <value>无法导出资源。</value>\n  </data>\n  <data name=\"ConfigurationExportFailedToGetUnitProcessors\" xml:space=\"preserve\">\n    <value>未能获取单元处理器。将不导出单个包设置。</value>\n  </data>\n  <data name=\"OutputDirectoryArgumentDescription\" xml:space=\"preserve\">\n    <value>要在其中写入结果的目录</value>\n  </data>\n  <data name=\"ConfigurationInstallDscPackage\" xml:space=\"preserve\">\n    <value>在系统上找不到Desired State Configuration包。正在安装包...</value>\n  </data>\n  <data name=\"ConfigurationInstallDscPackageFailed\" xml:space=\"preserve\">\n    <value>未能安装Desired State Configuration包。手动安装包或提供通过 --processor-path 参数 dsc.exe 的路径。</value>\n    <comment>{Locked=\"dsc.exe\",\"--processor-path\"}</comment>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionAdminSettingsSettings\" xml:space=\"preserve\">\n    <value>包含管理员设置及其值的对象。</value>\n  </data>\n  <data name=\"DscAdminSettingsResourceShortDescription\" xml:space=\"preserve\">\n    <value>管理管理员设置</value>\n  </data>\n  <data name=\"DscAdminSettingsResourceLongDescription\" xml:space=\"preserve\">\n    <value>管理 winget 的管理员设置。</value>\n  </data>\n  <data name=\"ResetAllAdminSettingsArgumentDescription\" xml:space=\"preserve\">\n    <value>重置所有管理员设置</value>\n  </data>\n  <data name=\"ResetAllAdminSettingsSucceeded\" xml:space=\"preserve\">\n    <value>已重置所有管理员设置。</value>\n  </data>\n  <data name=\"McpCommandShortDescription\" xml:space=\"preserve\">\n    <value>MCP 信息</value>\n    <comment>MCP stands for Model Context Protocol and should probably remain as-is</comment>\n  </data>\n  <data name=\"McpCommandLongDescription\" xml:space=\"preserve\">\n    <value>MCP (模型上下文协议) Windows 程序包管理器的信息。</value>\n  </data>\n  <data name=\"McpConfigurationPreamble\" xml:space=\"preserve\">\n    <value>若要使用 MCP 客户端手动配置Windows 程序包管理器 MCP 服务器，请使用 `servers` 对象中的以下 JSON 片段：</value>\n    <comment>{Locked=\"`servers`\"}\nMCP stands for Model Context Protocol and should probably remain as-is.\nAn unlocalized JSON fragment will follow on another line.</comment>\n  </data>\n  <data name=\"PolicyEnableMcpServer\" xml:space=\"preserve\">\n    <value>启用 Windows 程序包管理器 MCP 服务器</value>\n  </data>\n  <data name=\"OSVersionDescription\" xml:space=\"preserve\">\n    <value>目标 OS 版本</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>安装一个或多个字体失败。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>字体文件不受支持，无法安装。</value>\n  </data>\n  <data name=\"FontFileNotSupported\" xml:space=\"preserve\">\n    <value>字体包中的一个或多个字体不受支持，无法安装。</value>\n  </data>\n  <data name=\"FontInstallFailed\" xml:space=\"preserve\">\n    <value>字体安装失败; 正在清理。</value>\n  </data>\n  <data name=\"FontAlreadyInstalled\" xml:space=\"preserve\">\n    <value>已安装字体。</value>\n  </data>\n  <data name=\"FontPackage\" xml:space=\"preserve\">\n    <value>包 ID</value>\n  </data>\n  <data name=\"FontWinGetSupported\" xml:space=\"preserve\">\n    <value>支持 WinGet</value>\n  </data>\n  <data name=\"FontTitle\" xml:space=\"preserve\">\n    <value>标题</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_FOUND\" xml:space=\"preserve\">\n    <value>找不到字体文件。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>字体卸载失败。字体可能未处于正常状态。请尝试在重启后卸载。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>字体验证失败。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_ROLLBACK_FAILED\" xml:space=\"preserve\">\n    <value>字体回滚失败。字体可能未处于正常状态。请尝试在重启后卸载。</value>\n  </data>\n  <data name=\"FontDetailsArgumentDescription\" xml:space=\"preserve\">\n    <value>显示字体文件详细信息。</value>\n  </data>\n  <data name=\"FontValidationFailed\" xml:space=\"preserve\">\n    <value>字体包验证失败。</value>\n  </data>\n  <data name=\"FontRollbackFailed\" xml:space=\"preserve\">\n    <value>失败的字体安装回退尝试未成功。可能需要重新启动才能成功卸载字体。</value>\n  </data>\n  <data name=\"FontUninstallFailed\" xml:space=\"preserve\">\n    <value>字体包卸载失败。这通常是因为系统或应用程序正在使用字体。重新启动计算机后，卸载可能会成功。</value>\n  </data>\n  <data name=\"FontStatusOK\" xml:space=\"preserve\">\n    <value>确定</value>\n    <comment>\"OK\" means the font is in a good healthy state</comment>\n  </data>\n  <data name=\"FontStatusCorrupt\" xml:space=\"preserve\">\n    <value>损坏</value>\n    <comment>\"Corrupt\" refers to an install that is in a corrupted or bad state, and needs repair.</comment>\n  </data>\n  <data name=\"FontStatus\" xml:space=\"preserve\">\n    <value>状态</value>\n  </data>\n  <data name=\"FontStatusUnknown\" xml:space=\"preserve\">\n    <value>未知</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>已安装字体包。</value>\n  </data>\n  <data name=\"ListDetailsArgumentDescription\" xml:space=\"preserve\">\n    <value>显示有关包的详细信息</value>\n    <comment>Providing this argument causes the CLI to output additional details about installed application packages.</comment>\n  </data>\n  <data name=\"ShowLabelChannel\" xml:space=\"preserve\">\n    <value>通道:</value>\n    <comment>Precedes a string value that names the delivery channel for the software package (ex. stable, beta).</comment>\n  </data>\n  <data name=\"ShowListLocalIdentifier\" xml:space=\"preserve\">\n    <value>本地标识符:</value>\n    <comment>Precedes a value that is the unique identifier for the installed package on the local system.</comment>\n  </data>\n  <data name=\"ShowListPackageFamilyName\" xml:space=\"preserve\">\n    <value>包系列名称:</value>\n    <comment>Precedes a value that is the APPX/MSIX package family name of the installed package.</comment>\n  </data>\n  <data name=\"ShowListProductCode\" xml:space=\"preserve\">\n    <value>产品代码:</value>\n    <comment>Precedes a value that is the Add/Remove Programs identifier in the registry. This is also the Product Code value as defined in MSI installers.</comment>\n  </data>\n  <data name=\"ShowListUpgradeCode\" xml:space=\"preserve\">\n    <value>升级代码:</value>\n    <comment>Precedes a value that is the MSI Upgrade Code for the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledScope\" xml:space=\"preserve\">\n    <value>已安装的范围:</value>\n    <comment>Precedes a value that is the scope of the installation of the package (ex. user, machine).</comment>\n  </data>\n  <data name=\"ShowListInstalledArchitecture\" xml:space=\"preserve\">\n    <value>已安装的体系结构:</value>\n    <comment>Precedes a value that is the installed architecture of the package (ex. x86, x64, ARM64).</comment>\n  </data>\n  <data name=\"ShowListInstalledLocale\" xml:space=\"preserve\">\n    <value>已安装的区域设置:</value>\n    <comment>Precedes a value that is the locale of the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledLocation\" xml:space=\"preserve\">\n    <value>安装位置:</value>\n    <comment>Precedes a value that is the directory path to the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledSource\" xml:space=\"preserve\">\n    <value>源位置:</value>\n    <comment>Precedes a value that names the package source where the installed package originated from.</comment>\n  </data>\n  <data name=\"ShowListAvailableUpgrades\" xml:space=\"preserve\">\n    <value>可用升级:</value>\n    <comment>Precedes a list of package upgrades available for the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstallerCategory\" xml:space=\"preserve\">\n    <value>安装程序类别:</value>\n    <comment>Precedes a value that indicates the category of the installer for the installed package (ex. exe, msi, msix).</comment>\n  </data>\n  <data name=\"SourceEditOldValue\" xml:space=\"preserve\">\n    <value>旧值</value>\n    <comment>Column title for listing edit changes.</comment>\n  </data>\n  <data name=\"SourceEditNewValue\" xml:space=\"preserve\">\n    <value>新值</value>\n    <comment>Column title for listing the new value.</comment>\n  </data>\n</root>"
  },
  {
    "path": "Localization/Resources/zh-TW/Resources.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "Localization/Resources/zh-TW/winget.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"AdjoinedNotFlagError\" xml:space=\"preserve\">\n    <value>鄰近別名不是旗標: [{0}]</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an adjoined alias that is not a flag argument. {0} is a placeholder replaced by the user input argument (e.g. '-ab').</comment>\n  </data>\n  <data name=\"AdjoinedNotFoundError\" xml:space=\"preserve\">\n    <value>找不到鄰近旗標別名: [{0}]</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an adjoined flag alias argument that was not found. {0} is a placeholder replaced by the user input argument (e.g. '-ab').</comment>\n  </data>\n  <data name=\"AvailableArguments\" xml:space=\"preserve\">\n    <value>以下是可用的引數:</value>\n    <comment>Message displayed to inform the user about the available command line arguments.</comment>\n  </data>\n  <data name=\"AvailableCommandAliases\" xml:space=\"preserve\">\n    <value>以下命令別名可用:</value>\n    <comment>Message displayed to inform the user about the available command line alias arguments.</comment>\n  </data>\n  <data name=\"AvailableCommands\" xml:space=\"preserve\">\n    <value>以下是所有可用的命令:</value>\n    <comment>Title displayed to inform the user about the available commands.</comment>\n  </data>\n  <data name=\"AvailableHeader\" xml:space=\"preserve\">\n    <value>可用</value>\n    <comment>As in \"a new version is available to upgrade to\".</comment>\n  </data>\n  <data name=\"AvailableOptions\" xml:space=\"preserve\">\n    <value>以下是可用的選項:</value>\n    <comment>Message displayed to inform the user about the available options.</comment>\n  </data>\n  <data name=\"AvailableSubcommands\" xml:space=\"preserve\">\n    <value>以下是可用的子命令:</value>\n    <comment>Message displayed to inform the user about the available nested commands that run in context of the selected command.</comment>\n  </data>\n  <data name=\"AvailableUpgrades\" xml:space=\"preserve\">\n    <value>{0} 個升級可供使用。</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about available package upgrades. {0} is a placeholder replaced by the number of package upgrades.</comment>\n  </data>\n  <data name=\"ChannelArgumentDescription\" xml:space=\"preserve\">\n    <value>使用指定的頻道; 預設為一般觀眾</value>\n  </data>\n  <data name=\"Command\" xml:space=\"preserve\">\n    <value>命令</value>\n    <comment>Label displayed for a command to give the software.</comment>\n  </data>\n  <data name=\"CommandArgumentDescription\" xml:space=\"preserve\">\n    <value>依命令篩選結果</value>\n    <comment>Description message displayed to inform the user about filtering the search results by a package command.</comment>\n  </data>\n  <data name=\"CommandLineArgumentDescription\" xml:space=\"preserve\">\n    <value>用於完成的完整命令列</value>\n  </data>\n  <data name=\"CommandRequiresAdmin\" xml:space=\"preserve\">\n    <value>此命令需要系統管理員許可權才能執行。</value>\n  </data>\n  <data name=\"CompleteCommandLongDescription\" xml:space=\"preserve\">\n    <value>此命令可以用來要求即時線上的命令列完成。將會傳入要完成的命令列、游標位置及文字。輸出為基於輸入的一組可能值，其中每行一個可能值。</value>\n  </data>\n  <data name=\"CompleteCommandShortDescription\" xml:space=\"preserve\">\n    <value>啟用即時線上的命令列完成</value>\n  </data>\n  <data name=\"CountArgumentDescription\" xml:space=\"preserve\">\n    <value>顯示介於 1 到 1000 個(之間的指定結果數目)</value>\n  </data>\n  <data name=\"Done\" xml:space=\"preserve\">\n    <value>完成</value>\n    <comment>Label displayed when an operation completes or is done executing.</comment>\n  </data>\n  <data name=\"ExactArgumentDescription\" xml:space=\"preserve\">\n    <value>以完全相符，來尋找套件</value>\n    <comment>Description message displayed to inform the user about finding an application package using an exact matching criteria.</comment>\n  </data>\n  <data name=\"ExperimentalArgumentDescription\" xml:space=\"preserve\">\n    <value>示範用的實驗引數</value>\n  </data>\n  <data name=\"ExperimentalCommandLongDescription\" xml:space=\"preserve\">\n    <value>此命令是如何執行實驗功能的範例。若要開啟，請移至 ‘winget settings’ 並啟用 experimentalCmd 或 experimentalArg 功能。</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"ExperimentalCommandShortDescription\" xml:space=\"preserve\">\n    <value>實驗功能範例</value>\n  </data>\n  <data name=\"ExtraPositionalError\" xml:space=\"preserve\">\n    <value>在未預期的情況下找到位置引數: [{0}]</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an extra positional argument when none was expected. {0} is a placeholder replaced by the user's extra argument input.</comment>\n  </data>\n  <data name=\"FeatureDisabledMessage\" xml:space=\"preserve\">\n    <value>此功能正在進行中，未來可能會大幅變更或全部移除。若要啟用，請編輯您的設定 ('winget settings')以包含實驗性功能： '{0}'</value>\n    <comment>{Locked=\"winget settings\",\"{0}\"}. Error message displayed when the user uses an experimental feature that is disabled. {0} is a placeholder replaced by the experimental feature name.</comment>\n  </data>\n  <data name=\"FeaturesCommandLongDescription\" xml:space=\"preserve\">\n    <value>顯次實驗功能的狀態。實驗功能可以從「winget settings」開啟。</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"FeaturesCommandShortDescription\" xml:space=\"preserve\">\n    <value>顯示實驗功能的狀態</value>\n  </data>\n  <data name=\"FeaturesDisabled\" xml:space=\"preserve\">\n    <value>已停用</value>\n  </data>\n  <data name=\"FeaturesEnabled\" xml:space=\"preserve\">\n    <value>已啟用</value>\n  </data>\n  <data name=\"FeaturesFeature\" xml:space=\"preserve\">\n    <value>功能</value>\n  </data>\n  <data name=\"FeaturesLink\" xml:space=\"preserve\">\n    <value>連結</value>\n  </data>\n  <data name=\"FeaturesMessage\" xml:space=\"preserve\">\n    <value>下列實驗性功能正在運行中。\n它們可以透過設定檔案的 [winget settings] 來設定。</value>\n    <comment>{Locked=\"winget settings\"}</comment>\n  </data>\n  <data name=\"FeaturesProperty\" xml:space=\"preserve\">\n    <value>屬性</value>\n  </data>\n  <data name=\"FeaturesStatus\" xml:space=\"preserve\">\n    <value>狀態</value>\n  </data>\n  <data name=\"FileArgumentDescription\" xml:space=\"preserve\">\n    <value>雜湊的檔案</value>\n  </data>\n  <data name=\"FlagContainAdjoinedError\" xml:space=\"preserve\">\n    <value>旗標引數不能包含鄰近值: [{0}]</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a flag argument containing an unexpected adjoined value. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"HashCommandLongDescription\" xml:space=\"preserve\">\n    <value>計算適合在資訊清單輸入的本機檔案雜湊。它也可以計算 MSIX 封裝的簽章檔案雜湊，以啟用串流安裝。</value>\n  </data>\n  <data name=\"HashCommandShortDescription\" xml:space=\"preserve\">\n    <value>雜湊安裝程式檔案的協助程式</value>\n  </data>\n  <data name=\"HelpArgumentDescription\" xml:space=\"preserve\">\n    <value>顯示所選命令的相關說明</value>\n  </data>\n  <data name=\"HelpForDetails\" xml:space=\"preserve\">\n    <value>如需特定命令的更多詳細資料，請向其傳遞說明引數。</value>\n  </data>\n  <data name=\"HelpLinkPreamble\" xml:space=\"preserve\">\n    <value>若要取得更多協助，請參閱: [{0}]</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a link where they can learn more about the subject context. {0} is a placeholder replaced by a website address.</comment>\n  </data>\n  <data name=\"IdArgumentDescription\" xml:space=\"preserve\">\n    <value>依識別碼篩選結果</value>\n  </data>\n  <data name=\"IgnoreWarningsArgumentDescription\" xml:space=\"preserve\">\n    <value>抑制警告輸出</value>\n  </data>\n  <data name=\"InstallationDisclaimer1\" xml:space=\"preserve\">\n    <value>此應用程式已由其擁有者授權給您。</value>\n  </data>\n  <data name=\"InstallationDisclaimer2\" xml:space=\"preserve\">\n    <value>Microsoft 不負任何責任，也不會授與協力廠商封裝的任何授權。</value>\n  </data>\n  <data name=\"InstallationDisclaimerMSStore\" xml:space=\"preserve\">\n    <value>此套件是透過 Microsoft Store 所提供。winget 可能需要代表目前的使用者從 Microsoft Store 取得套件。</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"InstallCommandLongDescription\" xml:space=\"preserve\">\n    <value>安裝透過搜尋已設定來源或直接來自資訊清單的已選取套件。根據預設，査詢必須與套件的識別碼 (id)、名稱 (name) 或連結路徑 (moniker) 不區分大小寫。透過傳遞適當的選項，可以使用其他欄位。根據預設，install 命令將檢查套件的安裝狀態，並在適用的情况下嘗試執行升級。使用 --force 覆寫可執行直接安裝。</value>\n    <comment>{Locked=\"--force\"}; id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"InstallCommandShortDescription\" xml:space=\"preserve\">\n    <value>安裝指定的套件</value>\n  </data>\n  <data name=\"InstallerHashMismatchAdminBlock\" xml:space=\"preserve\">\n    <value>安裝程式雜湊不相符;以系統管理員執行時，無法覆寫此情況</value>\n  </data>\n  <data name=\"InstallerHashMismatchOverridden\" xml:space=\"preserve\">\n    <value>安裝程式雜湊不相符; 正在繼續，因為 --ignore-security-hash</value>\n    <comment>{Locked=\"--ignore-security-hash\"}</comment>\n  </data>\n  <data name=\"InstallerHashMismatchOverrideRequired\" xml:space=\"preserve\">\n    <value>安裝程式雜湊不相符;若要覆寫此檢查，請使用 --ignore-security-hash</value>\n    <comment>{Locked=\"--ignore-security-hash\"}</comment>\n  </data>\n  <data name=\"InstallerHashVerified\" xml:space=\"preserve\">\n    <value>已成功驗證安裝程式雜湊</value>\n  </data>\n  <data name=\"InstallFlowInstallSuccess\" xml:space=\"preserve\">\n    <value>已成功安裝</value>\n  </data>\n  <data name=\"InstallFlowStartingPackageInstall\" xml:space=\"preserve\">\n    <value>正在啟動套件安裝...</value>\n  </data>\n  <data name=\"HashOverrideArgumentDescription\" xml:space=\"preserve\">\n    <value>略過安裝程式雜湊檢查失敗</value>\n  </data>\n  <data name=\"IgnoreLocalArchiveMalwareScanArgumentDescription\" xml:space=\"preserve\">\n    <value>從本機資訊清單安裝封存類型封裝時，略過執行的惡意程式碼掃描</value>\n  </data>\n  <data name=\"InteractiveArgumentDescription\" xml:space=\"preserve\">\n    <value>要求互動式安裝; 可能需要使用者輸入</value>\n  </data>\n  <data name=\"InvalidAliasError\" xml:space=\"preserve\">\n    <value>無法辨識目前命令的引數別名: [{0}]</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a command line argument alias that was not recognized for a selected command. {0} is a placeholder replaced by the user's argument alias input (e.g. '-a').</comment>\n  </data>\n  <data name=\"InvalidArgumentSpecifierError\" xml:space=\"preserve\">\n    <value>無效的引數指定元: [{0}]</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an invalid argument specifier. {0} is a placeholder replaced by an argument specifier (e.g. '-').</comment>\n  </data>\n  <data name=\"InvalidNameError\" xml:space=\"preserve\">\n    <value>無法辨識目前命令的引數名稱: [{0}]</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an unrecognized command line argument name for the selected command. {0} is a placeholder replaced by the user's argument name input (e.g. '--example').</comment>\n  </data>\n  <data name=\"KeyDirectoriesHeader\" xml:space=\"preserve\">\n    <value>Winget 目錄</value>\n    <comment>Header for a table detailing the directories Winget uses for key operations like logging and portable installs</comment>\n  </data>\n  <data name=\"LocaleArgumentDescription\" xml:space=\"preserve\">\n    <value>要使用的地區設定 (BCP47 格式)</value>\n    <comment>{Locked=\"BCP47\"}</comment>\n  </data>\n  <data name=\"LicenseAgreement\" xml:space=\"preserve\">\n    <value>授權合約</value>\n  </data>\n  <data name=\"Links\" xml:space=\"preserve\">\n    <value>連結</value>\n    <comment>Links to different webpages</comment>\n  </data>\n  <data name=\"ListCommandLongDescription\" xml:space=\"preserve\">\n    <value>list 命令會顯示已安裝在系統上的套件，以及是否有可用的更新。可以提供其他選項來篩選輸出 (這與 search 命令很相似)。</value>\n    <comment>{Locked=\"list\",\"search\"}</comment>\n  </data>\n  <data name=\"ListCommandShortDescription\" xml:space=\"preserve\">\n    <value>顯示已安裝的套件</value>\n  </data>\n  <data name=\"LocationArgumentDescription\" xml:space=\"preserve\">\n    <value>要安裝的位置 (如果有支援的話)</value>\n  </data>\n  <data name=\"LogArgumentDescription\" xml:space=\"preserve\">\n    <value>記錄位置 (如果有支援的話)</value>\n  </data>\n  <data name=\"MainCopyrightNotice\" xml:space=\"preserve\">\n    <value>Copyright (c) Microsoft Corporation. 著作權所有，並保留一切權利。</value>\n  </data>\n  <data name=\"MainHomepage\" xml:space=\"preserve\">\n    <value>首頁</value>\n    <comment>The primary webpage for the software</comment>\n  </data>\n  <data name=\"ManifestArgumentDescription\" xml:space=\"preserve\">\n    <value>套件資訊清單的路徑</value>\n  </data>\n  <data name=\"ManifestValidationFail\" xml:space=\"preserve\">\n    <value>資訊清單驗證失敗。</value>\n  </data>\n  <data name=\"ManifestValidationSuccess\" xml:space=\"preserve\">\n    <value>資訊清單驗證成功。</value>\n  </data>\n  <data name=\"ManifestValidationWarning\" xml:space=\"preserve\">\n    <value>資訊清單驗證成功，但出現警告。</value>\n  </data>\n  <data name=\"MissingArgumentError\" xml:space=\"preserve\">\n    <value>需要引數值，但找不到: [{0}]</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user does not provide a required command line argument value. {0} is a placeholder replaced by the argument name.</comment>\n  </data>\n  <data name=\"MonikerArgumentDescription\" xml:space=\"preserve\">\n    <value>依套件連結路徑來篩選結果</value>\n  </data>\n  <data name=\"MsixArgumentDescription\" xml:space=\"preserve\">\n    <value>系統會將輸入檔案視為 msix; 如果簽署的話，將會提供簽章雜湊</value>\n  </data>\n  <data name=\"MsixSignatureHashFailed\" xml:space=\"preserve\">\n    <value>無法計算 MSIX 簽章訊息摘要。</value>\n  </data>\n  <data name=\"MSStoreAppBlocked\" xml:space=\"preserve\">\n    <value>無法安裝或升級 Microsoft Store 套件，因為特定應用程式受原則封鎖</value>\n  </data>\n  <data name=\"MSStoreInstallOrUpdateFailed\" xml:space=\"preserve\">\n    <value>無法安裝或升級 Microsoft Store 套件。錯誤碼: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Microsoft Store application package fails to install or upgrade. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"MSStoreStoreClientBlocked\" xml:space=\"preserve\">\n    <value>無法安裝或升級 Microsoft Store 套件，因為 Microsoft Store 用戶端受原則封鎖</value>\n  </data>\n  <data name=\"MSStoreInstallTryGetEntitlement\" xml:space=\"preserve\">\n    <value>正在驗證/正在要求套件取得...</value>\n  </data>\n  <data name=\"MultipleInstalledPackagesFound\" xml:space=\"preserve\">\n    <value>找到多個符合輸入條件的已安裝套件。請精煉輸入。</value>\n  </data>\n  <data name=\"MultiplePackagesFound\" xml:space=\"preserve\">\n    <value>找到多個符合輸入條件的套件。請精煉輸入。</value>\n  </data>\n  <data name=\"NameArgumentDescription\" xml:space=\"preserve\">\n    <value>依名稱篩選結果</value>\n  </data>\n  <data name=\"NoApplicableInstallers\" xml:space=\"preserve\">\n    <value>找不到適用的安裝程式;請參閱紀錄檔以取得詳細資料。</value>\n  </data>\n  <data name=\"NoExperimentalFeaturesMessage\" xml:space=\"preserve\">\n    <value>目前沒有可用的實驗功能。</value>\n  </data>\n  <data name=\"NoInstalledPackageFound\" xml:space=\"preserve\">\n    <value>未找到符合輸入條件的已安裝套件。</value>\n  </data>\n  <data name=\"NoPackageFound\" xml:space=\"preserve\">\n    <value>未找到符合輸入條件的套件。</value>\n  </data>\n  <data name=\"NoVTArgumentDescription\" xml:space=\"preserve\">\n    <value>停用 VirtualTerminal 顯示</value>\n    <comment>{Locked=\"VirtualTerminal\"}</comment>\n  </data>\n  <data name=\"OpenLogsArgumentDescription\" xml:space=\"preserve\">\n    <value>開啟預設記錄位置</value>\n  </data>\n  <data name=\"Options\" xml:space=\"preserve\">\n    <value>選項</value>\n    <comment>Options to change how a command works</comment>\n  </data>\n  <data name=\"OverrideArgumentDescription\" xml:space=\"preserve\">\n    <value>覆寫要傳送到安裝程式的引數</value>\n  </data>\n  <data name=\"Package\" xml:space=\"preserve\">\n    <value>包裹: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for a software package. {0} is a placeholder replaced by the software package name.</comment>\n  </data>\n  <data name=\"PendingWorkError\" xml:space=\"preserve\">\n    <value>糟糕，我們忘了執行這項工作...</value>\n  </data>\n  <data name=\"PositionArgumentDescription\" xml:space=\"preserve\">\n    <value>游標在命令列內的位置</value>\n  </data>\n  <data name=\"PrivacyStatement\" xml:space=\"preserve\">\n    <value>隱私權聲明</value>\n  </data>\n  <data name=\"QueryArgumentDescription\" xml:space=\"preserve\">\n    <value>用來搜尋套件的查詢</value>\n  </data>\n  <data name=\"RainbowArgumentDescription\" xml:space=\"preserve\">\n    <value>顯示各種色彩的進度</value>\n  </data>\n  <data name=\"RequiredArgError\" xml:space=\"preserve\">\n    <value>未提供必要的引數: [{0}]</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user does not provide a required command line argument. {0} is a placeholder replaced by an argument name.</comment>\n  </data>\n  <data name=\"RetroArgumentDescription\" xml:space=\"preserve\">\n    <value>顯示為預設色彩的進度</value>\n  </data>\n  <data name=\"SearchCommandLongDescription\" xml:space=\"preserve\">\n    <value>從設定的來源中搜尋套件。</value>\n  </data>\n  <data name=\"SearchCommandShortDescription\" xml:space=\"preserve\">\n    <value>尋找並顯示套件的基本資訊</value>\n  </data>\n  <data name=\"SearchId\" xml:space=\"preserve\">\n    <value>識別碼</value>\n    <comment>Abbreviation of Identifier.</comment>\n  </data>\n  <data name=\"SearchMatch\" xml:space=\"preserve\">\n    <value>相符</value>\n  </data>\n  <data name=\"SearchName\" xml:space=\"preserve\">\n    <value>名稱</value>\n  </data>\n  <data name=\"SearchSource\" xml:space=\"preserve\">\n    <value>來源</value>\n  </data>\n  <data name=\"SearchTruncated\" xml:space=\"preserve\">\n    <value>由於結果限制，已截斷其他項目</value>\n  </data>\n  <data name=\"SearchVersion\" xml:space=\"preserve\">\n    <value>版本</value>\n  </data>\n  <data name=\"SettingLoadFailure\" xml:space=\"preserve\">\n    <value>驗證設定時發現下列失誤：</value>\n  </data>\n  <data name=\"SettingsCommandLongDescription\" xml:space=\"preserve\">\n    <value>在預設 json 文字編輯器中開啟設定。如果未設定任何編輯器，則會在記事本中開啟設定。如需可用的設定，請參閱 https://aka.ms/winget-settings 此命令透過提供 --enable 或 --disable 引數，可用於設定系統管理員設定。</value>\n    <comment>{Locked=\"--enable\"} {Locked=\"--disable\"}</comment>\n  </data>\n  <data name=\"SettingsCommandShortDescription\" xml:space=\"preserve\">\n    <value>開啟設定或設定系統管理員設定</value>\n  </data>\n  <data name=\"SettingsWarnings\" xml:space=\"preserve\">\n    <value>載入設定時發生未預期的錯誤。請執行 'settings' 命令以驗證您的設定。</value>\n    <comment>{Locked=\"'settings'\"}</comment>\n  </data>\n  <data name=\"ShowChannel\" xml:space=\"preserve\">\n    <value>頻道</value>\n  </data>\n  <data name=\"ShowCommandLongDescription\" xml:space=\"preserve\">\n    <value>顯示特定封裝的資訊。根據預設，查詢必須 insensitively 符合封裝的識別碼、名稱或名字物件。您可以透過傳遞適當的選項來使用其他欄位。</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"ShowCommandShortDescription\" xml:space=\"preserve\">\n    <value>顯示套件相關資訊</value>\n  </data>\n  <data name=\"ShowVersion\" xml:space=\"preserve\">\n    <value>版本</value>\n  </data>\n  <data name=\"SilentArgumentDescription\" xml:space=\"preserve\">\n    <value>要求無訊息安裝</value>\n  </data>\n  <data name=\"SingleCharAfterDashError\" xml:space=\"preserve\">\n    <value>單一 - 後只能出現單一字元別名: [{0}]</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides more than a single character command line alias argument after an alias argument specifier '-'. {0} is a placeholder replaced by the user's argument input.</comment>\n  </data>\n  <data name=\"SourceAddAlreadyExistsDifferentArg\" xml:space=\"preserve\">\n    <value>具有給定名稱的來源已存在，且參照到不同的位置：</value>\n  </data>\n  <data name=\"SourceAddAlreadyExistsDifferentName\" xml:space=\"preserve\">\n    <value>具有不同名稱的來源已參照到此位置：</value>\n  </data>\n  <data name=\"SourceAddAlreadyExistsMatch\" xml:space=\"preserve\">\n    <value>具有給定名稱的來源已存在，且參照到同樣的位置：</value>\n  </data>\n  <data name=\"SourceAddBegin\" xml:space=\"preserve\">\n    <value>新增的來源：</value>\n  </data>\n  <data name=\"SourceAddCommandLongDescription\" xml:space=\"preserve\">\n    <value>新增來源。來源會為您提供資料，以便您探索和安裝套件。只有在您信任其為安全位置時，才會新增來源。</value>\n  </data>\n  <data name=\"SourceAddCommandShortDescription\" xml:space=\"preserve\">\n    <value>新增來源</value>\n  </data>\n  <data name=\"SourceArgArgumentDescription\" xml:space=\"preserve\">\n    <value>指派給來源的引數</value>\n  </data>\n  <data name=\"SourceArgumentDescription\" xml:space=\"preserve\">\n    <value>使用指定的來源尋找套件</value>\n  </data>\n  <data name=\"SourceCommandLongDescription\" xml:space=\"preserve\">\n    <value>使用子命令管理來源。來源會為您提供資料，以便您探索和安裝套件。只有在您信任其為安全位置時，才會新增來源。</value>\n  </data>\n  <data name=\"SourceCommandShortDescription\" xml:space=\"preserve\">\n    <value>管理套件來源</value>\n  </data>\n  <data name=\"SourceEditCommandLongDescription\" xml:space=\"preserve\">\n    <value>編輯現有來源的屬性。來源提供資料讓你發現並安裝套件。</value>\n  </data>\n  <data name=\"SourceEditCommandShortDescription\" xml:space=\"preserve\">\n    <value>編輯來源屬性</value>\n  </data>\n  <data name=\"SourceEditOne\" xml:space=\"preserve\">\n    <value>正在編輯來源: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being edited. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceEditNoChanges\" xml:space=\"preserve\">\n    <value>名為 '{0}' 的來源已經處於所需的狀態。</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being edited. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceListArg\" xml:space=\"preserve\">\n    <value>引數</value>\n    <comment>Value given to source.</comment>\n  </data>\n  <data name=\"SourceListCommandLongDescription\" xml:space=\"preserve\">\n    <value>列出所有目前的來源，或特定來源的完整詳細資料。</value>\n  </data>\n  <data name=\"SourceListCommandShortDescription\" xml:space=\"preserve\">\n    <value>列出目前的來源</value>\n  </data>\n  <data name=\"SourceListData\" xml:space=\"preserve\">\n    <value>資料</value>\n    <comment>Data stored by the source.</comment>\n  </data>\n  <data name=\"SourceListField\" xml:space=\"preserve\">\n    <value>欄位</value>\n    <comment>The name of a piece of information about a source.</comment>\n  </data>\n  <data name=\"SourceListName\" xml:space=\"preserve\">\n    <value>名稱</value>\n    <comment>The name of the source.</comment>\n  </data>\n  <data name=\"SourceListIdentifier\" xml:space=\"preserve\">\n    <value>識別碼</value>\n    <comment>The source's unique identifier.</comment>\n  </data>\n  <data name=\"SourceListNoneFound\" xml:space=\"preserve\">\n    <value>找不到具有此名稱的來源: {0}</value>\n    <comment>Error message displayed when the user provides a repository source name that was not found. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"SourceListNoSources\" xml:space=\"preserve\">\n    <value>沒有未設定來源。</value>\n  </data>\n  <data name=\"SourceListType\" xml:space=\"preserve\">\n    <value>類型</value>\n    <comment>The kind of source.</comment>\n  </data>\n  <data name=\"SourceListUpdated\" xml:space=\"preserve\">\n    <value>已更新</value>\n    <comment>The last time the source was updated.</comment>\n  </data>\n  <data name=\"SourceListUpdatedNever\" xml:space=\"preserve\">\n    <value>永不</value>\n    <comment>The source has never been updated.</comment>\n  </data>\n  <data name=\"SourceListValue\" xml:space=\"preserve\">\n    <value>值</value>\n    <comment>The value of information about a source.</comment>\n  </data>\n  <data name=\"SourceNameArgumentDescription\" xml:space=\"preserve\">\n    <value>來源的名稱</value>\n  </data>\n  <data name=\"SourceOpenFailedSuggestion\" xml:space=\"preserve\">\n    <value>無法開啟來源；如果此問題持續發生，請嘗試使用‘source reset’命令。</value>\n    <comment>{Locked=\"source reset\"}</comment>\n  </data>\n  <data name=\"SourceOpenPredefinedFailedSuggestion\" xml:space=\"preserve\">\n    <value>無法開啟預先定義的來源; 請向 winget 維護者回報。</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"SourceRemoveAll\" xml:space=\"preserve\">\n    <value>正在移除所有來源...</value>\n  </data>\n  <data name=\"SourceRemoveCommandLongDescription\" xml:space=\"preserve\">\n    <value>移除特定來源。</value>\n  </data>\n  <data name=\"SourceRemoveCommandShortDescription\" xml:space=\"preserve\">\n    <value>移除目前的來源</value>\n  </data>\n  <data name=\"SourceRemoveOne\" xml:space=\"preserve\">\n    <value>正在移除來源: {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being removed. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceResetAll\" xml:space=\"preserve\">\n    <value>正在重設所有來源...</value>\n  </data>\n  <data name=\"SourceResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>此命令會刪除現有的來源，可能會留下任何本地資料。在沒有任何引數的情況下，系統會刪除所有的來源，並新增預設值。如果提供指定的命名來源，則只會刪除該來源。</value>\n  </data>\n  <data name=\"SourceResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>重設來源</value>\n  </data>\n  <data name=\"SourceResetForceArgumentDescription\" xml:space=\"preserve\">\n    <value>強制重設來源</value>\n  </data>\n  <data name=\"SourceResetListAndOverridePreamble\" xml:space=\"preserve\">\n    <value>若已給定 --force 選項，將重設下列來源：</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"SourceResetOne\" xml:space=\"preserve\">\n    <value>重設的來源: {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a repository source that is currently being reset. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceTypeArgumentDescription\" xml:space=\"preserve\">\n    <value>來源的類型</value>\n  </data>\n  <data name=\"SourceUpdateAll\" xml:space=\"preserve\">\n    <value>正在更新所有來源...</value>\n  </data>\n  <data name=\"SourceUpdateCommandLongDescription\" xml:space=\"preserve\">\n    <value>更新所有來源，或只更新特定來源。</value>\n  </data>\n  <data name=\"SourceUpdateCommandShortDescription\" xml:space=\"preserve\">\n    <value>更新目前的來源</value>\n  </data>\n  <data name=\"SourceUpdateOne\" xml:space=\"preserve\">\n    <value>更新的來源: {0}...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being updated. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"TagArgumentDescription\" xml:space=\"preserve\">\n    <value>依標籤篩選結果</value>\n  </data>\n  <data name=\"ThankYou\" xml:space=\"preserve\">\n    <value>感謝您使用 Winget</value>\n  </data>\n  <data name=\"ThirdPartSoftwareNotices\" xml:space=\"preserve\">\n    <value>第三方聲明</value>\n  </data>\n  <data name=\"ToolDescription\" xml:space=\"preserve\">\n    <value>Winget 命令列實用程式可讓您從命令列安裝應用程式和其他套件。</value>\n  </data>\n  <data name=\"ToolInfoArgumentDescription\" xml:space=\"preserve\">\n    <value>顯示該工具的一般資訊</value>\n  </data>\n  <data name=\"ToolVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>顯示該工具的版本</value>\n  </data>\n  <data name=\"TooManyArgError\" xml:space=\"preserve\">\n    <value>引數提供的次數超過允許的次數: [{0}]</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a command line argument more times than it is allowed. {0} is a placeholder replaced by the user's argument name input.</comment>\n  </data>\n  <data name=\"TooManyBehaviorsError\" xml:space=\"preserve\">\n    <value>提供了多個執行行為引數： '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides more than one execution behavior argument when installing an application package. {0} is a placeholder replaced by the user specified execution behaviors (e.g. 'silent|interactive').</comment>\n  </data>\n  <data name=\"UnexpectedErrorExecutingCommand\" xml:space=\"preserve\">\n    <value>執行命令時，發生意外的錯誤：</value>\n  </data>\n  <data name=\"UninstallPreviousArgumentDescription\" xml:space=\"preserve\">\n    <value>在升級期間卸載舊版的套件</value>\n  </data>\n  <data name=\"UnrecognizedCommand\" xml:space=\"preserve\">\n    <value>無法辨識的命令: [{0}]</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an unrecognized command. {0} is a placeholder replaced by the user input.</comment>\n  </data>\n  <data name=\"UpdateAllArgumentDescription\" xml:space=\"preserve\">\n    <value>將所有已安裝的套件升級至最新版本 (如果有可用更新的話)</value>\n  </data>\n  <data name=\"UpdateNotApplicable\" xml:space=\"preserve\">\n    <value>找不到適用的升級。</value>\n  </data>\n  <data name=\"UpdateNotApplicableReason\" xml:space=\"preserve\">\n    <value>已設定的來源中有較新的套件版本，但不適用於您的系統或需求。</value>\n  </data>\n  <data name=\"UpdateNoPackagesFound\" xml:space=\"preserve\">\n    <value>找不到可用的升級。</value>\n  </data>\n  <data name=\"UpdateNoPackagesFoundReason\" xml:space=\"preserve\">\n    <value>沒有較新的套件版本可從設定的來源使用。</value>\n  </data>\n  <data name=\"UpgradeCommandLongDescription\" xml:space=\"preserve\">\n    <value>可透過搜尋已安裝的套件或直接從資訊清單中，升級已選取的套件。根據預設，查詢必須不區分大小寫地符合該套件的識別碼、名稱或連結路徑。您可以透過傳遞適當的選項，來使用其他欄位。未提供引數時，顯示具有可用升級的套件</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"UpgradeCommandShortDescription\" xml:space=\"preserve\">\n    <value>顯示並執行可用的升級</value>\n  </data>\n  <data name=\"Usage\" xml:space=\"preserve\">\n    <value>使用狀況: {0} {1}</value>\n    <comment>{Locked=\"{0} {1}\"} Message displayed to provide the user with instructions on how to use a command. {0} is a placeholder replaced by the program name (e.g. 'winget'). {1} is a placeholder replaced by the pattern for using the selected command.</comment>\n  </data>\n  <data name=\"ValidateCommandLongDescription\" xml:space=\"preserve\">\n    <value>使用一套嚴格的指導方針驗證資訊清單。這是為了讓您能夠在提交報告之前檢查您的資訊清單。</value>\n  </data>\n  <data name=\"ValidateCommandShortDescription\" xml:space=\"preserve\">\n    <value>驗證資訊清單檔案</value>\n  </data>\n  <data name=\"ValidateManifestArgumentDescription\" xml:space=\"preserve\">\n    <value>要驗證的資訊清單路徑</value>\n  </data>\n  <data name=\"VerboseLogsArgumentDescription\" xml:space=\"preserve\">\n    <value>為 winget 啟用詳細登入</value>\n  </data>\n  <data name=\"VerifyFileSignedMsix\" xml:space=\"preserve\">\n    <value>請確認輸入檔是有效且已簽署的 MSIX。</value>\n  </data>\n  <data name=\"VersionArgumentDescription\" xml:space=\"preserve\">\n    <value>使用指定的版本; 預設為最新版本</value>\n  </data>\n  <data name=\"VersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>顯示該套件的可用版本</value>\n  </data>\n  <data name=\"WordArgumentDescription\" xml:space=\"preserve\">\n    <value>完成前提供的值已要求</value>\n  </data>\n  <data name=\"GetManifestResultVersionNotFound\" xml:space=\"preserve\">\n    <value>找不到相符的版本: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to upgrade an application package to a version that was not found. {0} is a placeholder replaced by the user's provided upgrade package version.</comment>\n  </data>\n  <data name=\"OpenSourceFailedNoMatch\" xml:space=\"preserve\">\n    <value>沒有符合給定值的來源: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to install or upgrade an application package from a repository source that was not found. {0} is a placeholder replaced by the user's repository source name input.</comment>\n  </data>\n  <data name=\"OpenSourceFailedNoMatchHelp\" xml:space=\"preserve\">\n    <value>設定的來源為：</value>\n  </data>\n  <data name=\"OpenSourceFailedNoSourceDefined\" xml:space=\"preserve\">\n    <value>未定義來源；使用 [source add]，以進行新增，或使用 [source reset] 將之重設成預設值</value>\n    <comment>{Locked=\"source add\",\"source reset\"}</comment>\n  </data>\n  <data name=\"ReportIdentityFound\" xml:space=\"preserve\">\n    <value>找到</value>\n  </data>\n  <data name=\"VerifyFileFailedIsDirectory\" xml:space=\"preserve\">\n    <value>路徑為目錄; {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system path that is a directory. {0} is a placeholder replaced by the provided directory path.</comment>\n  </data>\n  <data name=\"VerifyFileFailedNotExist\" xml:space=\"preserve\">\n    <value>檔案不存在: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system file that does not exist. {0} is a placeholder replaced by the provided file path.</comment>\n  </data>\n  <data name=\"BothManifestAndSearchQueryProvided\" xml:space=\"preserve\">\n    <value>提供本地顯示和搜尋查詢引數</value>\n  </data>\n  <data name=\"Logs\" xml:space=\"preserve\">\n    <value>記錄檔</value>\n    <comment>Label displayed for diagnostic files containing information about the application use.</comment>\n  </data>\n  <data name=\"InstallerBlockedByPolicy\" xml:space=\"preserve\">\n    <value>安裝程式受到政策封鎖</value>\n  </data>\n  <data name=\"InstallerFailedSecurityCheck\" xml:space=\"preserve\">\n    <value>安裝程式的安全性檢查失敗</value>\n  </data>\n  <data name=\"InstallerFailedVirusScan\" xml:space=\"preserve\">\n    <value>防毒程式產品報告安裝程式中有感染</value>\n  </data>\n  <data name=\"SourceOpenWithFailedUpdate\" xml:space=\"preserve\">\n    <value>嘗試更新來源失敗： {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to update the repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"UninstallCommandLongDescription\" xml:space=\"preserve\">\n    <value>可透過搜尋已安裝的套件或直接從資訊清單中，解除安裝已選取的套件。根據預設，查詢必須不區分大小寫地符合該套件的識別碼、名稱或連結路徑。您可以透過傳遞適當的選項，來使用其他欄位。</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"UninstallCommandShortDescription\" xml:space=\"preserve\">\n    <value>解除安裝指定的套件</value>\n  </data>\n  <data name=\"UninstallFlowStartingPackageUninstall\" xml:space=\"preserve\">\n    <value>正在啟動套件解除安裝...</value>\n  </data>\n  <data name=\"UninstallFlowUninstallSuccess\" xml:space=\"preserve\">\n    <value>已成功解除安裝</value>\n  </data>\n  <data name=\"NoUninstallInfoFound\" xml:space=\"preserve\">\n    <value>winget 找不到此套件的解除安裝命令。請向套件發行者尋求支援。</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"UninstallAbandoned\" xml:space=\"preserve\">\n    <value>已放棄解除安裝</value>\n  </data>\n  <data name=\"UninstallFailedWithCode\" xml:space=\"preserve\">\n    <value>解除安裝失敗，結束代碼: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to uninstall an application package fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"ExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>匯出已安裝套件的清單</value>\n  </data>\n  <data name=\"ImportCommandLongDescription\" xml:space=\"preserve\">\n    <value>安裝檔案中列出的所有套件。</value>\n  </data>\n  <data name=\"ImportCommandShortDescription\" xml:space=\"preserve\">\n    <value>安裝檔案中的所有套件。</value>\n  </data>\n  <data name=\"OutputFileArgumentDescription\" xml:space=\"preserve\">\n    <value>欲寫入結果的檔案</value>\n  </data>\n  <data name=\"ImportFileArgumentDescription\" xml:space=\"preserve\">\n    <value>描述要安裝之套件的檔案</value>\n  </data>\n  <data name=\"ExportSourceArgumentDescription\" xml:space=\"preserve\">\n    <value>從指定來源匯出套件</value>\n  </data>\n  <data name=\"ExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>將已安裝套件的清單寫入檔案。然後可以使用 import 命令來安裝封裝。</value>\n    <comment>{Locked=\"import\"}</comment>\n  </data>\n  <data name=\"ImportInstallFailed\" xml:space=\"preserve\">\n    <value>無法安裝一或多個匯入的套件</value>\n  </data>\n  <data name=\"ImportSourceNotInstalled\" xml:space=\"preserve\">\n    <value>未安裝匯入所需的來源： {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to import application package(s) from a repository source that is not installed. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"InstalledPackageNotAvailable\" xml:space=\"preserve\">\n    <value>已安裝套件無法從任何來源取得: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when the user attempts to export an installed application package that is not available from any repository source. {0} is a placeholder replaced by the installed package name.</comment>\n  </data>\n  <data name=\"InstalledPackageVersionNotAvailable\" xml:space=\"preserve\">\n    <value>已安裝的套件版本無法從任一來源取得: {0} {1} {2}</value>\n    <comment>{Locked=\"{0} {1} {2}\"} Warning message displayed when the user attempts to export an installed application package with a version that is not available from any repository source. {0} is a placeholder replaced by the installed package identifier. {1} is a placeholder replaced by the installed package version. {2} is a placeholder replaced by the installed package channel.</comment>\n  </data>\n  <data name=\"NoPackagesInImportFile\" xml:space=\"preserve\">\n    <value>在匯入檔案中找不到套件</value>\n  </data>\n  <data name=\"InvalidJsonFile\" xml:space=\"preserve\">\n    <value>JSON 檔案無效。</value>\n  </data>\n  <data name=\"MultiQueryPackageAlreadyInstalled\" xml:space=\"preserve\">\n    <value>已安裝的套件: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user that an application package is already installed. {0} is a placeholder replaced by the package identifier or search query.</comment>\n  </data>\n  <data name=\"ImportIgnoreUnavailableArgumentDescription\" xml:space=\"preserve\">\n    <value>略過無法使用的套件</value>\n  </data>\n  <data name=\"ExportIncludeVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>在匯出檔案中包含套件版本</value>\n  </data>\n  <data name=\"ImportIgnoreVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>略過匯入檔案的套件版本</value>\n  </data>\n  <data name=\"VerifyPathFailedNotExist\" xml:space=\"preserve\">\n    <value>路徑不存在: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system path argument value that does not exist. {0} is a placeholder replaced by the user's provided path.</comment>\n  </data>\n  <data name=\"ImportFileHasInvalidSchema\" xml:space=\"preserve\">\n    <value>JSON 檔案未指定可識別的結構描述。</value>\n  </data>\n  <data name=\"InstallScopeDescription\" xml:space=\"preserve\">\n    <value>選取安裝範圍 (user 或 machine)</value>\n    <comment>{Locked=\"user\",\"machine\"} This argument allows the user to select between installing for just the user or for the entire machine.</comment>\n  </data>\n  <data name=\"InvalidArgumentValueError\" xml:space=\"preserve\">\n    <value>`{0}` 引數提供的值無效;有效值為: {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message displayed when the user provides an invalid command line argument value. {0} is a placeholder replaced by the argument name. {1} is a placeholder replaced by a list of valid options.</comment>\n  </data>\n  <data name=\"DisabledByGroupPolicy\" xml:space=\"preserve\">\n    <value>群組原則已停用此作業： {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user performs a command operation that is disabled by a group policy. {0} is a placeholder replaced by a group policy description.</comment>\n  </data>\n  <data name=\"PolicyAdditionalSources\" xml:space=\"preserve\">\n    <value>啟用其他 Windows 應用程式安裝程式來源</value>\n  </data>\n  <data name=\"PolicyAllowedSources\" xml:space=\"preserve\">\n    <value>啟用 Windows 應用程式安裝程式允許的來源</value>\n  </data>\n  <data name=\"PolicyEnableDefaultSource\" xml:space=\"preserve\">\n    <value>啟用 Windows 應用程式安裝程式預設來源</value>\n  </data>\n  <data name=\"PolicyEnableExperimentalFeatures\" xml:space=\"preserve\">\n    <value>啟用 Windows 應用程式安裝程式實驗性功能</value>\n  </data>\n  <data name=\"PolicyEnableMSStoreSource\" xml:space=\"preserve\">\n    <value>啟用 Windows 應用程式安裝程式 Microsoft Store 來源</value>\n  </data>\n  <data name=\"PolicyEnableFontSource\" xml:space=\"preserve\">\n    <value>啟用 Windows App 安裝程式字型來源</value>\n  </data>\n  <data name=\"PolicyEnableWinGetSettings\" xml:space=\"preserve\">\n    <value>啟用 Windows 封裝管理員設定</value>\n  </data>\n  <data name=\"PolicyEnableWinGet\" xml:space=\"preserve\">\n    <value>啟用 Windows 封裝管理員</value>\n  </data>\n  <data name=\"PolicyEnableWindowsPackageManagerCommandLineInterfaces\" xml:space=\"preserve\">\n    <value>啟用 Windows 封裝管理員命令列介面</value>\n  </data>\n  <data name=\"PolicySourceAutoUpdateInterval\" xml:space=\"preserve\">\n    <value>設定 Windows 封裝管理員來源自動更新間隔 (分鐘)</value>\n  </data>\n  <data name=\"PoliciesPolicy\" xml:space=\"preserve\">\n    <value>群組原則</value>\n    <comment>Header for a table listing active Group Policies</comment>\n  </data>\n  <data name=\"PolicyEnableLocalManifests\" xml:space=\"preserve\">\n    <value>啟用 Windows 應用程式安裝程式本機資訊清單檔案</value>\n  </data>\n  <data name=\"PolicyEnableBypassCertificatePinningForMicrosoftStore\" xml:space=\"preserve\">\n    <value>啟用 Windows 應用程式安裝程式 Microsoft Store 來源已釘選憑證旁路</value>\n  </data>\n  <data name=\"PolicyEnableLocalArchiveMalwareScanOverride\" xml:space=\"preserve\">\n    <value>啟用 Windows 應用程式安裝程式本機封存惡意程式碼掃描覆寫</value>\n  </data>\n  <data name=\"SettingsWarningField\" xml:space=\"preserve\">\n    <value>欄位: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when a user setting field has invalid syntax or semantics. {0} is a placeholder replaced by the setting field path.</comment>\n  </data>\n  <data name=\"SettingsWarningInvalidFieldFormat\" xml:space=\"preserve\">\n    <value>無效的欄位格式。</value>\n  </data>\n  <data name=\"SettingsWarningInvalidFieldValue\" xml:space=\"preserve\">\n    <value>無效的欄位值。</value>\n  </data>\n  <data name=\"SettingsWarningInvalidValueFromPolicy\" xml:space=\"preserve\">\n    <value>群組原則的設定無效。</value>\n  </data>\n  <data name=\"SettingsWarningLoadedBackupSettings\" xml:space=\"preserve\">\n    <value>已載入備份檔案中的設定。</value>\n  </data>\n  <data name=\"SettingsWarningParseError\" xml:space=\"preserve\">\n    <value>剖析檔案時發生錯誤:</value>\n  </data>\n  <data name=\"SettingsWarningValue\" xml:space=\"preserve\">\n    <value>值: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when a user setting value has invalid syntax or semantics. {0} is a placeholder replaced by the setting data value.</comment>\n  </data>\n  <data name=\"FeaturesMessageDisabledByPolicy\" xml:space=\"preserve\">\n    <value>下列實驗性功能正在進行中。\n由於群組原則的原因，已停用設定。</value>\n  </data>\n  <data name=\"InstallerHashMismatchError\" xml:space=\"preserve\">\n    <value>安裝程式雜湊不相符。</value>\n  </data>\n  <data name=\"PolicyEnableHashOverride\" xml:space=\"preserve\">\n    <value>啟用 Windows 應用程式安裝程式雜湊覆寫</value>\n  </data>\n  <data name=\"SourceExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>匯出目前來源並做為群組原則的 JSON。</value>\n  </data>\n  <data name=\"SourceExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>匯出目前的來源</value>\n  </data>\n  <data name=\"SourceListAdditionalSource\" xml:space=\"preserve\">\n    <value>其他來源</value>\n    <comment>An additional source required by policy.</comment>\n  </data>\n  <data name=\"SourceListAllowedSource\" xml:space=\"preserve\">\n    <value>允許的來源</value>\n    <comment>A source that the user is allowed to add.</comment>\n  </data>\n  <data name=\"InvalidArgumentValueErrorWithoutValidValues\" xml:space=\"preserve\">\n    <value>為 '{0}' 引數提供的值無效</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an invalid command line argument value. {0} is a placeholder replaced by the argument name.</comment>\n  </data>\n  <data name=\"Cancelled\" xml:space=\"preserve\">\n    <value>已取消</value>\n  </data>\n  <data name=\"ExternalDependencies\" xml:space=\"preserve\">\n    <value>外部</value>\n  </data>\n  <data name=\"ImportCommandReportDependencies\" xml:space=\"preserve\">\n    <value>在此匯入中找到的套件具有下列相依性：</value>\n    <comment>Import command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"PackageRequiresDependencies\" xml:space=\"preserve\">\n    <value>此套件需要下列相依性：</value>\n    <comment>Message shown before reporting dependencies</comment>\n  </data>\n  <data name=\"DependenciesFlowInstall\" xml:space=\"preserve\">\n    <value>正在安裝相依性:</value>\n  </data>\n  <data name=\"DependenciesFlowSourceNotFound\" xml:space=\"preserve\">\n    <value>找不到相依性來源</value>\n  </data>\n  <data name=\"DependenciesFlowSourceTooManyMatches\" xml:space=\"preserve\">\n    <value>套件搜尋產生一個以上的結果: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when application packages search yield more than one result. {0} is a placeholder replaced by the dependency package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowPackageVersionNotFound\" xml:space=\"preserve\">\n    <value>找不到套件的最新版本: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when no suitable version found for the specific application package. {0} is a placeholder replaced by the package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoInstallerFound\" xml:space=\"preserve\">\n    <value>找不到任何安裝程式: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when no installer found for a manifest. {0} is a placeholder replaced by the manifest identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoMinVersion\" xml:space=\"preserve\">\n    <value>套用沒有可使用的最低必要版本: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the minimum required version is not available for an application package. {0} is a placeholder replaced by the package identifier.</comment>\n  </data>\n  <data name=\"DependenciesFlowNoMatches\" xml:space=\"preserve\">\n    <value>沒有相符項目</value>\n    <comment>When package search yields no matches</comment>\n  </data>\n  <data name=\"DependenciesFlowContainsLoop\" xml:space=\"preserve\">\n    <value>有迴圈</value>\n    <comment>Dependency graph has loop</comment>\n  </data>\n  <data name=\"DependenciesFlowNoSuitableInstallerFound\" xml:space=\"preserve\">\n    <value>找不到適合指令清單的安裝程式： {0} 版本 {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message displayed when an attempt to get a preferred installer for a manifest fails. {0} is a placeholder replaced by the manifest identifier. {1} is a placeholder replaced by the manifest version.</comment>\n  </data>\n  <data name=\"DependenciesManagementError\" xml:space=\"preserve\">\n    <value>處理套件相依性時發生錯誤。您要繼續安裝嗎?</value>\n    <comment>Prompt message shown when dependencies processing yields errors.</comment>\n  </data>\n  <data name=\"DependenciesManagementExitMessage\" xml:space=\"preserve\">\n    <value>處理套件相依性時發生錯誤。正在結束...</value>\n  </data>\n  <data name=\"PackageDependencies\" xml:space=\"preserve\">\n    <value>套件</value>\n  </data>\n  <data name=\"UninstallCommandReportDependencies\" xml:space=\"preserve\">\n    <value>此套件具有可能不再需要的相依性：</value>\n    <comment>Uninstall command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"ValidateCommandReportDependencies\" xml:space=\"preserve\">\n    <value>資訊清單具有下列未驗證的相依性;請確認它們有效：</value>\n    <comment>Validate command sentence showed before reporting dependencies</comment>\n  </data>\n  <data name=\"WindowsFeaturesDependencies\" xml:space=\"preserve\">\n    <value>Windows 功能</value>\n  </data>\n  <data name=\"WindowsLibrariesDependencies\" xml:space=\"preserve\">\n    <value>Windows 媒體櫃</value>\n  </data>\n  <data name=\"DependencySourceArgumentDescription\" xml:space=\"preserve\">\n    <value>使用指定的來源尋找套件相依性</value>\n    <comment>For getting package type dependencies when installing from a local manifest</comment>\n  </data>\n  <data name=\"WindowsStoreTerms\" xml:space=\"preserve\">\n    <value>Windows 市集條款</value>\n  </data>\n  <data name=\"AcceptPackageAgreementsArgumentDescription\" xml:space=\"preserve\">\n    <value>接受套件的所有授權合約</value>\n  </data>\n  <data name=\"ExportedPackageRequiresLicenseAgreement\" xml:space=\"preserve\">\n    <value>匯出的套件需要授權合約才能安裝： {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when an exported application package requires license agreement to install. {0} is a placeholder replaced by the package name.</comment>\n  </data>\n  <data name=\"PackageAgreementsPrompt\" xml:space=\"preserve\">\n    <value>發行者要求您檢視上述資訊並接受合約，然後再安裝。\n是否同意這些條款？</value>\n  </data>\n  <data name=\"PackageAgreementsNotAgreedTo\" xml:space=\"preserve\">\n    <value>未同意套件合約。作業已取消。</value>\n  </data>\n  <data name=\"ShowLabelAgreements\" xml:space=\"preserve\">\n    <value>合約：</value>\n  </data>\n  <data name=\"ShowLabelAuthor\" xml:space=\"preserve\">\n    <value>作者:</value>\n  </data>\n  <data name=\"ShowLabelDescription\" xml:space=\"preserve\">\n    <value>描述：</value>\n  </data>\n  <data name=\"ShowLabelInstaller\" xml:space=\"preserve\">\n    <value>安裝程式:</value>\n  </data>\n  <data name=\"ShowLabelInstallerLocale\" xml:space=\"preserve\">\n    <value>安裝程式地區設定:</value>\n  </data>\n  <data name=\"ShowLabelInstallerProductId\" xml:space=\"preserve\">\n    <value>Store 產品識別碼：</value>\n  </data>\n  <data name=\"ShowLabelInstallerSha256\" xml:space=\"preserve\">\n    <value>安裝程式 SHA256:</value>\n  </data>\n  <data name=\"ShowLabelInstallerType\" xml:space=\"preserve\">\n    <value>安裝程式類型:</value>\n  </data>\n  <data name=\"ShowLabelInstallerUrl\" xml:space=\"preserve\">\n    <value>安裝程式 URL:</value>\n  </data>\n  <data name=\"ShowLabelLicense\" xml:space=\"preserve\">\n    <value>授權:</value>\n  </data>\n  <data name=\"ShowLabelLicenseUrl\" xml:space=\"preserve\">\n    <value>授權 URL:</value>\n  </data>\n  <data name=\"ShowLabelMoniker\" xml:space=\"preserve\">\n    <value>綽號:</value>\n  </data>\n  <data name=\"ShowLabelPackageUrl\" xml:space=\"preserve\">\n    <value>首頁：</value>\n  </data>\n  <data name=\"ShowLabelPublisher\" xml:space=\"preserve\">\n    <value>發行者:</value>\n  </data>\n  <data name=\"ShowLabelTags\" xml:space=\"preserve\">\n    <value>標記:</value>\n  </data>\n  <data name=\"ShowLabelVersion\" xml:space=\"preserve\">\n    <value>版本:</value>\n  </data>\n  <data name=\"ShowLabelDependencies\" xml:space=\"preserve\">\n    <value>相依性:</value>\n  </data>\n  <data name=\"ShowLabelWindowsFeaturesDependencies\" xml:space=\"preserve\">\n    <value>Windows 功能:</value>\n  </data>\n  <data name=\"ShowLabelWindowsLibrariesDependencies\" xml:space=\"preserve\">\n    <value>Windows 文件庫:</value>\n  </data>\n  <data name=\"ShowLabelPackageDependencies\" xml:space=\"preserve\">\n    <value>套件相依性:</value>\n  </data>\n  <data name=\"ShowLabelExternalDependencies\" xml:space=\"preserve\">\n    <value>外部相依性:</value>\n  </data>\n  <data name=\"PromptOptionNo\" xml:space=\"preserve\">\n    <value>否</value>\n  </data>\n  <data name=\"PromptOptionYes\" xml:space=\"preserve\">\n    <value>是</value>\n  </data>\n  <data name=\"SourceAddOpenSourceFailed\" xml:space=\"preserve\">\n    <value>無法開啟新增的來源。</value>\n  </data>\n  <data name=\"AcceptSourceAgreementsArgumentDescription\" xml:space=\"preserve\">\n    <value>在來源作業期間接受所有來源合約</value>\n  </data>\n  <data name=\"SourceAgreementsTitle\" xml:space=\"preserve\">\n    <value>`{0}` 來源要求您必須先檢視下列合約，再使用。</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user that a repository source requires viewing agreements before using. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SourceAgreementsPrompt\" xml:space=\"preserve\">\n    <value>是否同意所有來源合約條款？</value>\n  </data>\n  <data name=\"SourceAgreementsNotAgreedTo\" xml:space=\"preserve\">\n    <value>一或多個來源合約未同意。作業已取消。請接受來源合約或移除對應的來源。</value>\n  </data>\n  <data name=\"SourceAgreementsMarketMessage\" xml:space=\"preserve\">\n    <value>來源需要將目前電腦的 2 個字母地理區域傳輸到後端服務，才能正確(例如\"US\")。</value>\n  </data>\n  <data name=\"InstallFlowRegistrationDeferred\" xml:space=\"preserve\">\n    <value>已成功安裝。重新開機應用程式以完成升級。</value>\n  </data>\n  <data name=\"HeaderArgumentDescription\" xml:space=\"preserve\">\n    <value>選用的 Windows-Package-Manager REST 來源 HTTP 標頭</value>\n  </data>\n  <data name=\"HeaderArgumentNotApplicableForNonRestSourceWarning\" xml:space=\"preserve\">\n    <value>略過選用標頭，因為它不適用於此來源。</value>\n  </data>\n  <data name=\"HeaderArgumentNotApplicableWithoutSource\" xml:space=\"preserve\">\n    <value>選擇性標頭不適用，但未指定來源： '{0}'</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user performs an operation (e.g install) and provides the HTTP 'header' argument without specifying the repository source. {0} is a placeholder replaced by the header argument name.</comment>\n  </data>\n  <data name=\"ShowLabelInstallerReleaseDate\" xml:space=\"preserve\">\n    <value>發行日期:</value>\n  </data>\n  <data name=\"ShowLabelInstallerOfflineDistributionSupported\" xml:space=\"preserve\">\n    <value>支援離線散發:</value>\n  </data>\n  <data name=\"ShowLabelPublisherUrl\" xml:space=\"preserve\">\n    <value>發行者 URL：</value>\n  </data>\n  <data name=\"ShowLabelPurchaseUrl\" xml:space=\"preserve\">\n    <value>購買 Url:</value>\n  </data>\n  <data name=\"ShowLabelPublisherSupportUrl\" xml:space=\"preserve\">\n    <value>發行者支援 URL：</value>\n  </data>\n  <data name=\"ShowLabelPrivacyUrl\" xml:space=\"preserve\">\n    <value>隱私權 Url：</value>\n  </data>\n  <data name=\"ShowLabelCopyright\" xml:space=\"preserve\">\n    <value>著作權:</value>\n  </data>\n  <data name=\"ShowLabelCopyrightUrl\" xml:space=\"preserve\">\n    <value>著作權 Url：</value>\n  </data>\n  <data name=\"ShowLabelReleaseNotes\" xml:space=\"preserve\">\n    <value>版本資訊：</value>\n  </data>\n  <data name=\"ShowLabelReleaseNotesUrl\" xml:space=\"preserve\">\n    <value>版本資訊 Url：</value>\n  </data>\n  <data name=\"SearchFailureWarning\" xml:space=\"preserve\">\n    <value>搜尋來源時失敗; 將不會包含結果: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when searching a repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"SearchFailureError\" xml:space=\"preserve\">\n    <value>搜尋來源時失敗: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when searching a repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\n  </data>\n  <data name=\"FeatureDisabledByAdminSettingMessage\" xml:space=\"preserve\">\n    <value>系統管理員必須啟用此功能。若要啟用此功能，請以系統管理員的身分執行‘winget settings --enable {0}’。</value>\n    <comment>{Locked=\"winget settings --enable\", \"{0}\"}. Error message displayed when the user uses a feature that needs to be enabled by administrators. {0} is a placeholder replaced by the admin setting.</comment>\n  </data>\n  <data name=\"AdminSettingEnableDescription\" xml:space=\"preserve\">\n    <value>啟用特定系統管理員設定</value>\n  </data>\n  <data name=\"AdminSettingDisableDescription\" xml:space=\"preserve\">\n    <value>停用特定系統管理員設定</value>\n  </data>\n  <data name=\"AdminSettingEnabled\" xml:space=\"preserve\">\n    <value>啟用管理員設定'{0}'。</value>\n    <comment>{Locked=\"{0}\"} Message displayed when the user enables an admin setting. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"AdminSettingDisabled\" xml:space=\"preserve\">\n    <value>關閉管理員設定 '{0}'。</value>\n    <comment>{Locked=\"{0}\"} Message displayed when the user disables an admin setting. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"AdminSettingHeader\" xml:space=\"preserve\">\n    <value>管理員設定</value>\n    <comment>Header for a table displaying admin settings.</comment>\n  </data>\n  <data name=\"InstallFlowReturnCodePackageInUse\" xml:space=\"preserve\">\n    <value>應用程式目前正在執行。結束應用程式，然後再試一次。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodePackageInUseByApplication\" xml:space=\"preserve\">\n    <value>安裝程式修改的檔案目前正被其他應用程式使用。結束應用程式，然後再試一次。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInstallInProgress\" xml:space=\"preserve\">\n    <value>另一個安裝已在進行中。請稍後再試。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeFileInUse\" xml:space=\"preserve\">\n    <value>一或多個檔案正在使用中。結束應用程式，然後再試一次。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeMissingDependency\" xml:space=\"preserve\">\n    <value>您的系統遺漏此套件的相依性。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeDiskFull\" xml:space=\"preserve\">\n    <value>您的電腦上已經沒有空間。請釋出空間，然後再試一次。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInsufficientMemory\" xml:space=\"preserve\">\n    <value>記憶體不足，無法安裝。請關閉其他應用程式，然後再試一次。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeInvalidParameter\" xml:space=\"preserve\">\n    <value>其中一個安裝參數無效。套裝安裝記錄可能包含其他詳細資訊。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeNoNetwork\" xml:space=\"preserve\">\n    <value>此應用程式需要網際網路連線。請連線到網路，然後再試一次。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeContactSupport\" xml:space=\"preserve\">\n    <value>此應用程式在安裝期間發生錯誤。連絡客戶支援。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootRequiredToFinish\" xml:space=\"preserve\">\n    <value>重新啟動您的電腦以完成安裝。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootRequiredForInstall\" xml:space=\"preserve\">\n    <value>將重新開機您的電腦以完成安裝。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeRebootInitiated\" xml:space=\"preserve\">\n    <value>安裝失敗。請重新開機您的電腦，然後再試一次。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeCancelledByUser\" xml:space=\"preserve\">\n    <value>您取消了安裝。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeAlreadyInstalled\" xml:space=\"preserve\">\n    <value>已安裝此應用程式的另一個版本。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeDowngrade\" xml:space=\"preserve\">\n    <value>已安裝此應用程式的較新版本。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeBlockedByPolicy\" xml:space=\"preserve\">\n    <value>組織原則導致無法安裝。請連絡您的系統管理員。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeSystemNotSupported\" xml:space=\"preserve\">\n    <value>目前系統設定不支援安裝此套件。</value>\n  </data>\n  <data name=\"InstallFlowReturnCodeCustomError\" xml:space=\"preserve\">\n    <value>安裝失敗，發生自定義安裝程序錯誤。連絡套件支援。</value>\n  </data>\n  <data name=\"InstallAbandoned\" xml:space=\"preserve\">\n    <value>已放棄安裝</value>\n  </data>\n  <data name=\"InstallerFailedWithCode\" xml:space=\"preserve\">\n    <value>安裝程式失敗，結束代碼為: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the application installer fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"InstallerLogAvailable\" xml:space=\"preserve\">\n    <value>安裝程式記錄檔可在下列位置使用: {0}</value>\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about the system path of a diagnostic files containing information about the installer. {0} is a placeholder replaced by the diagnostic file system path.</comment>\n  </data>\n  <data name=\"SearchFailureErrorListMatches\" xml:space=\"preserve\">\n    <value>在工作來源中找到下列套件。\n請使用 '--source' 選項指定其中一個以繼續。</value>\n    <comment>{Locked=\"--source\"} \"working sources\" as in \"sources that are working correctly\"</comment>\n  </data>\n  <data name=\"SearchFailureErrorNoMatches\" xml:space=\"preserve\">\n    <value>在工作來源中找不到任何套件。</value>\n    <comment>\"working sources\" as in \"sources that are working correctly\"</comment>\n  </data>\n  <data name=\"FeaturesMessageDisabledByBuild\" xml:space=\"preserve\">\n    <value>這是 Windows 封裝管理員的穩定版本。如果您想要嘗試實驗性功能，請安裝發行前版本組建。可於 https://github.com/microsoft/winget-cli 的 GitHub 上找到指示。</value>\n    <comment>{Locked=\"https://github.com/microsoft/winget-cli\"}</comment>\n  </data>\n  <data name=\"WindowsPackageManager\" xml:space=\"preserve\">\n    <value>Windows 封裝管理員 v{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying the product name and version. {0} is a placeholder replaced by the product version.</comment>\n  </data>\n  <data name=\"ImportIgnorePackageVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>忽略匯入檔案中的套件版本</value>\n  </data>\n  <data name=\"CountOutOfBoundsError\" xml:space=\"preserve\">\n    <value>要求的結果數目必須介於 1 到 1000 之間。</value>\n  </data>\n  <data name=\"CustomSwitchesArgumentDescription\" xml:space=\"preserve\">\n    <value>除預設外在安裝器上通過引數</value>\n  </data>\n  <data name=\"UpgradeDifferentInstallTechnologyInNewerVersions\" xml:space=\"preserve\">\n    <value>找到較新的版本，但安裝技術與目前安裝的版本不同。請卸載套件並安裝較新的版本。</value>\n  </data>\n  <data name=\"UpgradeDifferentInstallTechnology\" xml:space=\"preserve\">\n    <value>指定之較新版本的安裝技術與目前安裝的版本不同。請卸載套件並安裝較新的版本。</value>\n  </data>\n  <data name=\"WindowsPackageManagerPreview\" xml:space=\"preserve\">\n    <value>Windows 封裝管理員 (預覽) v{0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying the preview product name and pre-release version. {0} is a placeholder replaced by the product version.</comment>\n  </data>\n  <data name=\"ArchitectureArgumentDescription\" xml:space=\"preserve\">\n    <value>選取架構</value>\n  </data>\n  <data name=\"IncludeUnknownArgumentDescription\" xml:space=\"preserve\">\n    <value>升級套件，即使無法判斷其目前版本</value>\n  </data>\n  <data name=\"IncludeUnknownInListArgumentDescription\" xml:space=\"preserve\">\n    <value>即使無法判斷封裝的目前版本，也要列出封裝。可以只與 --upgrade-available 引數搭配使用</value>\n    <comment>{Locked=\"--upgrade-available\"}</comment>\n  </data>\n  <data name=\"UpgradeUnknownVersionExplanation\" xml:space=\"preserve\">\n    <value>無法判斷此套件的版本號碼。若要繼續升級，請將引數 「--include-unknown」新增至先前的命令。</value>\n    <comment>{Locked=\"--include-unknown\"}</comment>\n  </data>\n  <data name=\"UpgradeUnknownVersionCount\" xml:space=\"preserve\">\n    <value>{0} 套件具有無法確認的版本號碼。使用--include-unknown (包含未知項目) 來看到所有結果。</value>\n    <comment>{Locked=\"{0}\",\"--include-unknown\"} {0} is a placeholder that is replaced by an integer number of packages that do not have notated versions. </comment>\n  </data>\n  <data name=\"UpgradeRequireExplicitCount\" xml:space=\"preserve\">\n    <value>{0} 套件已固定且需要特別更新。</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by an integer number of packages that require explicit upgrades.</comment>\n  </data>\n  <data name=\"InvalidArgumentWithoutQueryError\" xml:space=\"preserve\">\n    <value>提供的引數只能與查詢一起使用。</value>\n  </data>\n  <data name=\"SystemArchitecture\" xml:space=\"preserve\">\n    <value>系統架構: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for the system architecture. {0} is a placeholder replaced by the value of the system architecture (e.g. X64).</comment>\n  </data>\n  <data name=\"PreserveArgumentDescription\" xml:space=\"preserve\">\n    <value>保留套件 (可攜式) 建立的所有檔案和目錄</value>\n  </data>\n  <data name=\"PurgeArgumentDescription\" xml:space=\"preserve\">\n    <value>刪除封裝目錄中的所有檔案和目錄(可攜式)</value>\n  </data>\n  <data name=\"PressEnterToContinue\" xml:space=\"preserve\">\n    <value>按 Enter 以繼續. . .</value>\n  </data>\n  <data name=\"RenameArgumentDescription\" xml:space=\"preserve\">\n    <value>對可執行檔 (可攜式) 重新命名的值</value>\n  </data>\n  <data name=\"WaitArgumentDescription\" xml:space=\"preserve\">\n    <value>在結束之前，提示使用者按下按鍵</value>\n  </data>\n  <data name=\"InstallerElevationExpected\" xml:space=\"preserve\">\n    <value>安裝程式會要求以系統管理員身分執行。預期提供提示。</value>\n  </data>\n  <data name=\"InstallerProhibitsElevation\" xml:space=\"preserve\">\n    <value>無法從系統管理員內容執行安裝程式。</value>\n  </data>\n  <data name=\"ModifiedPathRequiresShellRestart\" xml:space=\"preserve\">\n    <value>已修改路徑環境變數；重新啟動命令介面以使用新值。</value>\n  </data>\n  <data name=\"ProductCodeArgumentDescription\" xml:space=\"preserve\">\n    <value>使用產品代碼篩選</value>\n  </data>\n  <data name=\"PortableRegistryCollisionOverridden\" xml:space=\"preserve\">\n    <value>具有相同名稱但來源不同的可攜式套件存在；正在繼續，因為 --force</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"ReparsePointsNotSupportedError\" xml:space=\"preserve\">\n    <value>磁碟區不支援重新分析點</value>\n  </data>\n  <data name=\"ReservedFilenameError\" xml:space=\"preserve\">\n    <value>指定的檔案名稱不是有效的檔案名稱</value>\n  </data>\n  <data name=\"OverwritingExistingFileAtMessage\" xml:space=\"preserve\">\n    <value>正在覆寫現有的檔案: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed to inform the user that an existing file is being overwritten. {0} is a placeholder replaced by the file system path.</comment>\n  </data>\n  <data name=\"NoPackageSelectionArgumentProvided\" xml:space=\"preserve\">\n    <value>未提供套件選取引數；請參閱說明以取得有關尋找套件的詳細資訊。</value>\n  </data>\n  <data name=\"PortableAliasAdded\" xml:space=\"preserve\">\n    <value>新增的命令列別名:</value>\n  </data>\n  <data name=\"PortableLinksMachine\" xml:space=\"preserve\">\n    <value>可攜式連結目錄 (電腦)</value>\n  </data>\n  <data name=\"PortableLinksUser\" xml:space=\"preserve\">\n    <value>可攜式連結目錄 (使用者)</value>\n  </data>\n  <data name=\"PortableRootUser\" xml:space=\"preserve\">\n    <value>可攜式封裝根目錄 (使用者)</value>\n  </data>\n  <data name=\"PortableRoot\" xml:space=\"preserve\">\n    <value>可攜式封裝根目錄</value>\n  </data>\n  <data name=\"PortableRoot86\" xml:space=\"preserve\">\n    <value>可攜式封裝根目錄 (x86)</value>\n  </data>\n  <data name=\"PortableInstallFailed\" xml:space=\"preserve\">\n    <value>可攜式安裝失敗；正在清除...</value>\n  </data>\n  <data name=\"PortableHashMismatchOverridden\" xml:space=\"preserve\">\n    <value>已修改 Portable 套件: 正在繼續，因為 --force</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"PortableHashMismatchOverrideRequired\" xml:space=\"preserve\">\n    <value>無法移除 Portable 套件，因為它已遭到修改；覆寫此檢查可使用 --force</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"FilesRemainInInstallDirectory\" xml:space=\"preserve\">\n    <value>檔案仍保留在安裝目錄中: {0}</value>\n    <comment>{Locked=\"{0}\"} Warning message displayed when files remain in install directory. {0} is a placeholder replaced by the directory path.</comment>\n  </data>\n  <data name=\"PurgeInstallDirectory\" xml:space=\"preserve\">\n    <value>正在清除安裝目錄...</value>\n  </data>\n  <data name=\"UnableToPurgeInstallDirectory\" xml:space=\"preserve\">\n    <value>無法清除安裝目錄，因為它不是由 WinGet 所建立</value>\n  </data>\n  <data name=\"RelatedLink\" xml:space=\"preserve\">\n    <value>相關連結</value>\n  </data>\n  <data name=\"ShowLabelDocumentation\" xml:space=\"preserve\">\n    <value>文件:</value>\n  </data>\n  <data name=\"Notes\" xml:space=\"preserve\">\n    <value>筆記: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displayed for installation notes. {0} is a placeholder replaced by installation notes.</comment>\n  </data>\n  <data name=\"ShowLabelInstallationNotes\" xml:space=\"preserve\">\n    <value>安裝附註:</value>\n  </data>\n  <data name=\"UnsupportedArgument\" xml:space=\"preserve\">\n    <value>此套件不支援提供的引數</value>\n  </data>\n  <data name=\"ExtractArchiveFailed\" xml:space=\"preserve\">\n    <value>無法擷取要封存的內容</value>\n  </data>\n  <data name=\"NestedInstallerNotFound\" xml:space=\"preserve\">\n    <value>巢狀安裝程式檔案不存在。請確保巢狀安裝程式的指定相對路徑相符: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when nested installer file does not exist. {0} is a placeholder replaced by the nested installer file path.</comment>\n  </data>\n  <data name=\"InvalidPathToNestedInstaller\" xml:space=\"preserve\">\n    <value>巢狀安裝程式的相對檔案路徑無效；路徑指向安裝目錄之外的位置</value>\n  </data>\n  <data name=\"NestedInstallerNotSpecified\" xml:space=\"preserve\">\n    <value>沒有為此套件指定巢狀安裝程式</value>\n  </data>\n  <data name=\"MultipleUnsupportedNestedInstallersSpecified\" xml:space=\"preserve\">\n    <value>封存安裝程式只能指定一個巢狀安裝程式，除非它是可攜式或字型巢狀安裝程式</value>\n  </data>\n  <data name=\"IncompatibleArgumentsProvided\" xml:space=\"preserve\">\n    <value>提供的命令列引數不相容</value>\n  </data>\n  <data name=\"UpgradeArgumentDescription\" xml:space=\"preserve\">\n    <value>只列出有可供使用的升級的套件</value>\n  </data>\n  <data name=\"UpgradeAvailableForPinned\" xml:space=\"preserve\">\n    <value>以下套件有可用的升級，但需要升級的明確顯示目標:</value>\n    <comment>\"require explicit targeting for upgrade\" means that the package will not be upgraded with all others unless an extra flag is added, or the package is mentioned explicitly</comment>\n  </data>\n  <data name=\"Downloading\" xml:space=\"preserve\">\n    <value>正在下載</value>\n    <comment>Label displayed while downloading an application installer.</comment>\n  </data>\n  <data name=\"NestedInstallerNotSupported\" xml:space=\"preserve\">\n    <value>不支援巢狀安裝程式類型</value>\n  </data>\n  <data name=\"InstallerAbortsTerminal\" xml:space=\"preserve\">\n    <value>已知此安裝程式可以重新啟動終端機或殼層</value>\n  </data>\n  <data name=\"InstallerRequiresInstallLocation\" xml:space=\"preserve\">\n    <value>此套件需要安裝位置</value>\n  </data>\n  <data name=\"InstallersAbortTerminal\" xml:space=\"preserve\">\n    <value>已知以下安裝程式可以重新啟動終端機或殼層:</value>\n  </data>\n  <data name=\"InstallersRequireInstallLocation\" xml:space=\"preserve\">\n    <value>以下安裝程式需要安裝位置:</value>\n  </data>\n  <data name=\"PromptForInstallRoot\" xml:space=\"preserve\">\n    <value>指定安裝根目錄:</value>\n  </data>\n  <data name=\"PromptToProceed\" xml:space=\"preserve\">\n    <value>要繼續處理?</value>\n  </data>\n  <data name=\"ReportIdentityForAgreements\" xml:space=\"preserve\">\n    <value>的合約</value>\n    <comment>This will be followed by a package name, and then a list of license agreements</comment>\n  </data>\n  <data name=\"InstallLocationNotProvided\" xml:space=\"preserve\">\n    <value>套件需要安裝位置，但未提供</value>\n  </data>\n  <data name=\"DisableInteractivityArgumentDescription\" xml:space=\"preserve\">\n    <value>停用互動式提示</value>\n    <comment>Description for a command line argument, shown next to it in the help</comment>\n  </data>\n  <data name=\"ConvertInstallFlowToUpgrade\" xml:space=\"preserve\">\n    <value>發現已安裝的現有套件。正在嘗試升級已安裝的套件...</value>\n  </data>\n  <data name=\"ForceArgumentDescription\" xml:space=\"preserve\">\n    <value>直接執行命令並繼續處理非安全性相關問題</value>\n    <comment>Description for a command line argument, shown next to it in the help</comment>\n  </data>\n  <data name=\"PortablePackageAlreadyExists\" xml:space=\"preserve\">\n    <value>來自不同來源的 Portable 套件已存在</value>\n  </data>\n  <data name=\"ExtractArchiveSucceeded\" xml:space=\"preserve\">\n    <value>已成功擷取封存</value>\n  </data>\n  <data name=\"ExtractingArchive\" xml:space=\"preserve\">\n    <value>正在擷取封存...</value>\n  </data>\n  <data name=\"ArchiveFailedMalwareScan\" xml:space=\"preserve\">\n    <value>封存掃描偵測到惡意程式碼。若要覆寫此檢查，請使用 --ignore-local-archive-malware-scan</value>\n    <comment>{Locked=\"--ignore-local-archive-malware-scan\"}</comment>\n  </data>\n  <data name=\"ArchiveFailedMalwareScanOverridden\" xml:space=\"preserve\">\n    <value>封存掃描偵測到惡意程式碼。由於--ignore-local-archive-malware-scan，正在繼續</value>\n    <comment>{Locked=\"--ignore-local-archive-malware-scan\"}</comment>\n  </data>\n  <data name=\"NoUpgradeArgumentDescription\" xml:space=\"preserve\">\n    <value>如果已安裝版本已存在，則跳過升級</value>\n  </data>\n  <data name=\"PackageAlreadyInstalled\" xml:space=\"preserve\">\n    <value>已安裝套件版本。安裝已取消。</value>\n  </data>\n  <data name=\"EnableAdminSettingFailed\" xml:space=\"preserve\">\n    <value>無法啟用{0}。這個設定是由原則控制。如需詳細資訊，請連絡您的系統管理員。</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"DisableAdminSettingFailed\" xml:space=\"preserve\">\n    <value>無法停用{0}。這個設定是由原則控制。如需詳細資訊，請連絡您的系統管理員。</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"PinAddCommandLongDescription\" xml:space=\"preserve\">\n    <value>新增釘選。釘選可以限制 Windows 套件管理員將套件更新至指定的版本範圍，或是避免一次更新所有套件。固定的套件仍可以自行更新，且能在 Windows 套件管理員外進行更新。根據預設，固定的套件可以藉由在「更新」指令中特別指定來更新，或是利用「--include-pinned」(包含固定項目) 旗標至「winget upgrade --all」(winget 更新—全部。)</value>\n    <comment>{Locked{\"'upgrade'\"} Locked{\"--include-pinned\"} Locked{\"winget upgrade --all\"}</comment>\n  </data>\n  <data name=\"PinAddCommandShortDescription\" xml:space=\"preserve\">\n    <value>新增新釘選</value>\n  </data>\n  <data name=\"PinCommandLongDescription\" xml:space=\"preserve\">\n    <value>釘選可以限制 Windows 套件管理員將套件更新至指定的版本範圍，或是避免一次更新所有套件。固定套件仍可以自行更新，且能在 Windows 套件管理員外進行更新。</value>\n  </data>\n  <data name=\"PinCommandShortDescription\" xml:space=\"preserve\">\n    <value>管理套件釘選</value>\n  </data>\n  <data name=\"PinListCommandLongDescription\" xml:space=\"preserve\">\n    <value>列出所有目前的釘選，或特定釘選的完整詳細資料。</value>\n  </data>\n  <data name=\"PinListCommandShortDescription\" xml:space=\"preserve\">\n    <value>列出目前的釘選項目</value>\n  </data>\n  <data name=\"PinRemoveCommandLongDescription\" xml:space=\"preserve\">\n    <value>移除特定套件 PIN。</value>\n  </data>\n  <data name=\"PinRemoveCommandShortDescription\" xml:space=\"preserve\">\n    <value>移除套件釘選</value>\n  </data>\n  <data name=\"PinResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>重設所有現有的釘選。</value>\n  </data>\n  <data name=\"PinResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>重設釘選?</value>\n  </data>\n  <data name=\"GatedVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>要釘選封裝的版本。萬用字元 '*' 可以做為最後一個版本元件</value>\n  </data>\n  <data name=\"PinAddBlockingArgumentDescription\" xml:space=\"preserve\">\n    <value>直到移除釘選前，都對更新進行封鎖，以防止覆寫引數</value>\n  </data>\n  <data name=\"PinInstalledArgumentDescription\" xml:space=\"preserve\">\n    <value>釘選特定安裝的版本</value>\n  </data>\n  <data name=\"PinInstalledSource\" xml:space=\"preserve\">\n    <value>已安裝</value>\n    <comment>Value used in a table to indicate that a package comes from the list of packages installed in the machine</comment>\n  </data>\n  <data name=\"SettingsExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>將設定匯出為 JSON</value>\n  </data>\n  <data name=\"SettingsExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>匯出設定</value>\n  </data>\n  <data name=\"UserSettings\" xml:space=\"preserve\">\n    <value>使用者設定</value>\n    <comment>Label displayed for the file containing the user settings.</comment>\n  </data>\n  <data name=\"SettingsWarningUsingDefault\" xml:space=\"preserve\">\n    <value>無法載入設定檔案。使用預設值。</value>\n  </data>\n  <data name=\"InstalledScopeArgumentDescription\" xml:space=\"preserve\">\n    <value>選取已安裝的套件範圍篩選條件 (user 或 machine)</value>\n    <comment>{Locked=\"user\",\"machine\"} This argument allows the user to select installed packages for just the user or for the entire machine.</comment>\n  </data>\n  <data name=\"PinAdded\" xml:space=\"preserve\">\n    <value>成功新增釘選</value>\n  </data>\n  <data name=\"PinAlreadyExists\" xml:space=\"preserve\">\n    <value>已經有封裝{0}的 PIN</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that will be replaced by a package name. The message is shown when attempting to add a pin for a package that is already pinned.</comment>\n  </data>\n  <data name=\"PinExistsOverwriting\" xml:space=\"preserve\">\n    <value>套件{0}已經有 PIN。正在覆寫，因為--force引數。</value>\n    <comment>{Locked=\"--force\"}{Locked=\"--force\",\"{0}\"} {0} is a placeholder that will be replaced by a package name.</comment>\n  </data>\n  <data name=\"PinExistsUseForceArg\" xml:space=\"preserve\">\n    <value>套件{0}已經有 PIN。使用--force引數覆寫。</value>\n    <comment>{Locked=\"--force\",\"{0}\"} {0} is a placeholder that will be replaced by a package name.</comment>\n  </data>\n  <data name=\"PinResettingAll\" xml:space=\"preserve\">\n    <value>重設目前所有釘選。</value>\n  </data>\n  <data name=\"PinResetUseForceArg\" xml:space=\"preserve\">\n    <value>使用--force引數重設所有釘選。將移除下列 PIN：</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"PinType\" xml:space=\"preserve\">\n    <value>釘選類型</value>\n  </data>\n  <data name=\"PinDoesNotExist\" xml:space=\"preserve\">\n    <value>{0} 套件沒有釘選</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that will be replaced by a package name. The message is shown when attempting to delete a pin for a package that is not pinned.</comment>\n  </data>\n  <data name=\"PinNoPinsExist\" xml:space=\"preserve\">\n    <value>沒有經過設定的釘選。</value>\n    <comment>Shown when listing or modifying existing pins if there are none.</comment>\n  </data>\n  <data name=\"PinResetSuccessful\" xml:space=\"preserve\">\n    <value>成功重置釘選</value>\n    <comment>Shown after resetting (deleting) all the pins</comment>\n  </data>\n  <data name=\"PinCannotOpenIndex\" xml:space=\"preserve\">\n    <value>無法開啟釘選資料庫</value>\n    <comment>Error message for when we cannot open the database containing package pins.</comment>\n  </data>\n  <data name=\"ArgumentForSinglePackageProvidedWithMultipleQueries\" xml:space=\"preserve\">\n    <value>提供僅能用於單一套件的引數</value>\n  </data>\n  <data name=\"MultipleExclusiveArgumentsProvided\" xml:space=\"preserve\">\n    <value>已提供多個互斥的引數: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message shown when mutually incompatible command line arguments are used. {0} is a placeholder replaced by the arguments that cannot be specified together</comment>\n  </data>\n  <data name=\"DependencyArgumentMissing\" xml:space=\"preserve\">\n    <value>引數 {0} 只能搭配 {1} 使用</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message shown when having an argument needs another to be present, but that is missing. {0} and {1} are replaced by the arguments. For example \"Argument --include-unknown can only be used with --upgrade\"</comment>\n  </data>\n  <data name=\"StateDisabled\" xml:space=\"preserve\">\n    <value>停用</value>\n    <comment>As in enabled/disabled</comment>\n  </data>\n  <data name=\"StateEnabled\" xml:space=\"preserve\">\n    <value>已啟用</value>\n    <comment>As in enabled/disabled</comment>\n  </data>\n  <data name=\"StateHeader\" xml:space=\"preserve\">\n    <value>州</value>\n    <comment>Header for a table listing the state (enabled/disabled) of Group Policies and Settings</comment>\n  </data>\n  <data name=\"MultiQueryArgumentDescription\" xml:space=\"preserve\">\n    <value>用來搜尋套件的查詢</value>\n  </data>\n  <data name=\"MultiQueryPackageNotFound\" xml:space=\"preserve\">\n    <value>找不到套件: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches returns no results. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"MultiQuerySearchFoundMultiple\" xml:space=\"preserve\">\n    <value>找到多個套件: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches returns more than one result. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"MultiQuerySearchFailed\" xml:space=\"preserve\">\n    <value>搜尋失敗: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches fails. This message is for generic failures, we have more specific messages for when the search returns no results, or when it returns more than one result. {0} is a placeholder replaced by the package name or query.</comment>\n  </data>\n  <data name=\"UpgradeBlockedByPinCount\" xml:space=\"preserve\">\n    <value>{0} 個包裹具有更新前需要先移除的釘選</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by an integer number of packages with pins that prevent upgrade</comment>\n  </data>\n  <data name=\"UpgradeBlockedByManifest\" xml:space=\"preserve\">\n    <value>無法使用 winget 升級封裝。請使用發行者提供的方法來升級此套件。</value>\n  </data>\n  <data name=\"IncludePinnedArgumentDescription\" xml:space=\"preserve\">\n    <value>即使有非封鎖釘選仍要更新套件</value>\n  </data>\n  <data name=\"IncludePinnedInListArgumentDescription\" xml:space=\"preserve\">\n    <value>即使封裝有防止升級的 PIN 碼，也要列出封裝。可以只與 --upgrade-available 引數搭配使用</value>\n    <comment>{Locked=\"--upgrade-available\"}</comment>\n  </data>\n  <data name=\"PinRemovedSuccessfully\" xml:space=\"preserve\">\n    <value>成功移除釘選</value>\n  </data>\n  <data name=\"UpgradeIsPinned\" xml:space=\"preserve\">\n    <value>找到更新的版本，但套件具有防止更新的釘選。</value>\n  </data>\n  <data name=\"PackageIsPinned\" xml:space=\"preserve\">\n    <value>已固定套件且無法更新。使用「winget pin」指令來檢視並編輯釘選。有些釘選類型可以透過--include-pinned (包含固定項目) 引數執行繞過。</value>\n    <comment>{Locked=\"winget pin\",\"--include-pinned\"} Error shown when we block an upgrade due to the package being pinned</comment>\n  </data>\n  <data name=\"UpgradePinnedByUserCount\" xml:space=\"preserve\">\n    <value>{0} 個套件有阻止更新的釘選。請使用「winget pin」指令來檢視並編輯釘選。使用 --include-pinned (包含固定項目) 引數可能會顯示更多結果。</value>\n    <comment>{Locked=\"winget pin\",\"--include-pinned\"} {0} is a placeholder replaced by an integer number of packages</comment>\n  </data>\n  <data name=\"ConfigureCommandLongDescription\" xml:space=\"preserve\">\n    <value>確保系統是否符合所提供設定所述的預期狀態。可下載/執行處理器，以獲得所需的狀態。應該先檢查設定和處理器，以確保它們在套用前值得信任。</value>\n  </data>\n  <data name=\"ConfigureCommandShortDescription\" xml:space=\"preserve\">\n    <value>將系統設定為所需的狀態</value>\n  </data>\n  <data name=\"ConfigureShowCommandLongDescription\" xml:space=\"preserve\">\n    <value>顯示所提供設定的詳細資料。根據預設，不會修改系統，但某些選項會造成檔案下載和/或載入。</value>\n  </data>\n  <data name=\"ConfigureShowCommandShortDescription\" xml:space=\"preserve\">\n    <value>顯示設定的詳細資料</value>\n  </data>\n  <data name=\"ConfigureTestCommandLongDescription\" xml:space=\"preserve\">\n    <value>檢查系統是否符合所提供設定所述的預期狀態。可下載/執行處理器，以測試所需的狀態。應該先檢查設定和處理器，以確保它們在執行前值得信任。</value>\n  </data>\n  <data name=\"ConfigureTestCommandShortDescription\" xml:space=\"preserve\">\n    <value>檢查系統是否處於預期狀態</value>\n  </data>\n  <data name=\"ConfigureValidateCommandLongDescription\" xml:space=\"preserve\">\n    <value>驗證設定檔案的正確性。</value>\n  </data>\n  <data name=\"ConfigureValidateCommandShortDescription\" xml:space=\"preserve\">\n    <value>驗證設定檔案</value>\n  </data>\n  <data name=\"ConfigurationFieldInvalidType\" xml:space=\"preserve\">\n    <value>設定檔中的欄位'{0}'類型錯誤。</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the field name from the file.</comment>\n  </data>\n  <data name=\"ConfigurationFileArgumentDescription\" xml:space=\"preserve\">\n    <value>設定檔案的路徑</value>\n  </data>\n  <data name=\"ConfigurationFileInvalid\" xml:space=\"preserve\">\n    <value>設定檔案無效。</value>\n  </data>\n  <data name=\"ConfigurationFileVersionUnknown\" xml:space=\"preserve\">\n    <value>設定檔案版本 {0} 不明。</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the version of the configuration file.</comment>\n  </data>\n  <data name=\"ConfigurationAcceptWarningArgumentDescription\" xml:space=\"preserve\">\n    <value>接受設定警告，防止互動式提示</value>\n  </data>\n  <data name=\"ConfigurationApply\" xml:space=\"preserve\">\n    <value>套用</value>\n    <comment>Indicates that this item is used to write state</comment>\n  </data>\n  <data name=\"ConfigurationAssert\" xml:space=\"preserve\">\n    <value>判斷提示</value>\n    <comment>Indicates that this item is used to check/assert the state rather than write to it</comment>\n  </data>\n  <data name=\"ConfigurationDependencies\" xml:space=\"preserve\">\n    <value>相依性: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying a list of dependencies. {0} is replaced with a space separated list of identifiers referencing other items.</comment>\n  </data>\n  <data name=\"ConfigurationFailedToApply\" xml:space=\"preserve\">\n    <value>某些設定未成功套用。</value>\n  </data>\n  <data name=\"ConfigurationFailedToGetDetails\" xml:space=\"preserve\">\n    <value>無法取得設定的詳細資訊。</value>\n  </data>\n  <data name=\"ConfigurationInform\" xml:space=\"preserve\">\n    <value>通知</value>\n    <comment>Indicates that this item is used to retrieve values for future use rather than writing them</comment>\n  </data>\n  <data name=\"ConfigurationLocal\" xml:space=\"preserve\">\n    <value>本機</value>\n    <comment>Used to indicate that the item is present on the device.</comment>\n  </data>\n  <data name=\"ConfigurationModuleNameOnly\" xml:space=\"preserve\">\n    <value>模組: {0}</value>\n    <comment>{Locked=\"{0}\"} Label displaying a module name. {0} is replaced with the name of the module from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationModuleWithDetails\" xml:space=\"preserve\">\n    <value>模組: {0} {1} [{2}]</value>\n    <comment>{Locked=\"{0}\",\"{1}\",\"{2}\"} Label displaying module information. {0} is replaced by the module name. {1} is replaced by the module author. {2} is replaced by a string indicating the source of the module.</comment>\n  </data>\n  <data name=\"ConfigurationSettings\" xml:space=\"preserve\">\n    <value>設定:</value>\n    <comment>Label for the values that are used as inputs for this item when applying state</comment>\n  </data>\n  <data name=\"ConfigurationSuccessfullyApplied\" xml:space=\"preserve\">\n    <value>已成功套用設定。</value>\n  </data>\n  <data name=\"ConfigurationUnitSuccessfullyApplied\" xml:space=\"preserve\">\n    <value>已成功套用單位。</value>\n  </data>\n  <data name=\"ConfigurationWaitingOnAnother\" xml:space=\"preserve\">\n    <value>正在將另一個設定套用到系統。此設定會儘快繼續...</value>\n  </data>\n  <data name=\"ConfigurationWarning\" xml:space=\"preserve\">\n    <value>您必須瞭解您選擇要執行的組態設定。Microsoft 不負責您已撰寫或匯入的設定檔。此設定可能會變更 Windows 中的設定、安裝軟體、變更軟體設定 (包括安全性設定)，以及代表您接受與協力廠商套件和服務的使用者合約。 執行此設定檔案，即表示您瞭解並同意這些資源與設定。所有安裝的應用程式均由其擁有者授權給您。Microsoft 不負責，也不會授與任何授權給協力廠商套件或服務。</value>\n    <comment>Legal approved. Do not change without approval.</comment>\n  </data>\n  <data name=\"ConfigurationWarningPromptApply\" xml:space=\"preserve\">\n    <value>您是否已檢閱過設定，是否要繼續將它套用至系統?</value>\n    <comment>PM approved.</comment>\n  </data>\n  <data name=\"ConfigurationFileEmpty\" xml:space=\"preserve\">\n    <value>設定是空的。</value>\n  </data>\n  <data name=\"WindowsFeatureNotFound\" xml:space=\"preserve\">\n    <value>找不到功能 [{0}]。</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Windows feature was not found on the system.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeatureOverrideRequired\" xml:space=\"preserve\">\n    <value>無法啟用 Windows 功能相依性。若要繼續安裝，請使用'--force'。</value>\n    <comment>{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"RebootRequiredToEnableWindowsFeatureOverrideRequired\" xml:space=\"preserve\">\n    <value>必須重新開機，才能完全啟用 Windows 功能;若要覆寫此檢查，請使用 [--force]。</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeatureOverridden\" xml:space=\"preserve\">\n    <value>無法啟用 Windows 功能相依性;因為 [--force] 而繼續</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.\n{Locked=\"--force\"}</comment>\n  </data>\n  <data name=\"EnablingWindowsFeature\" xml:space=\"preserve\">\n    <value>正在啟用 [{0}]...</value>\n    <comment>{Locked=\"{0}\"} Message displayed to the user regarding which Windows Feature is being enabled.</comment>\n  </data>\n  <data name=\"FailedToEnableWindowsFeature\" xml:space=\"preserve\">\n    <value>無法啟用 [{0}] 功能: {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"}  An error when enabling a Windows Feature. {0} is a placeholder for the name of the Windows Feature.\n{1} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"RebootRequiredToEnableWindowsFeatureOverridden\" xml:space=\"preserve\">\n    <value>必須重新開機，才能完全啟用 Windows 功能;因為 [--force] 而繼續</value>\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.</comment>\n  </data>\n  <data name=\"InstallWaitingOnAnother\" xml:space=\"preserve\">\n    <value>正在等候另一個安裝/卸載完成...</value>\n  </data>\n  <data name=\"PinVersion\" xml:space=\"preserve\">\n    <value>已釘選的版本</value>\n    <comment>Table header for the version to which a package is pinned; meaning it should not update from that version.</comment>\n  </data>\n  <data name=\"ConfigurationDescriptionWasTruncated\" xml:space=\"preserve\">\n    <value>&lt;如需其他詳細資料，請參閱記錄檔&gt;</value>\n    <comment>The brackets are intended to make the value stand out from other text which it will follow. Any locale appropriate mechanism that achieves this is acceptable.</comment>\n  </data>\n  <data name=\"ConfigurationGettingDetails\" xml:space=\"preserve\">\n    <value>正在擷取設定詳細資料</value>\n  </data>\n  <data name=\"ConfigurationInitializing\" xml:space=\"preserve\">\n    <value>正在初始化設定系統</value>\n  </data>\n  <data name=\"ConfigurationReadingConfigFile\" xml:space=\"preserve\">\n    <value>讀取設定檔案</value>\n  </data>\n  <data name=\"ConfigurationUnitAssertHadNegativeResult\" xml:space=\"preserve\">\n    <value>系統不是設定所宣告的預期狀態。</value>\n  </data>\n  <data name=\"ConfigurationUnitFailed\" xml:space=\"preserve\">\n    <value>此設定單位失敗，原因不明： {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedConfigSet\" xml:space=\"preserve\">\n    <value>設定單位失敗，因為設定： {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringGet\" xml:space=\"preserve\">\n    <value>嘗試取得目前的系統狀態時，設定單位失敗。</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringSet\" xml:space=\"preserve\">\n    <value>嘗試套用所需的狀態時，組態單位失敗。</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedDuringTest\" xml:space=\"preserve\">\n    <value>嘗試測試目前的系統狀態時，組態單位失敗。</value>\n  </data>\n  <data name=\"ConfigurationUnitFailedInternal\" xml:space=\"preserve\">\n    <value>設定單位失敗，因為發生內部錯誤： {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedPrecondition\" xml:space=\"preserve\">\n    <value>設定單位失敗，因為先決條件無效： {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedSystemState\" xml:space=\"preserve\">\n    <value>設定單位失敗，因為系統狀態： {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitFailedUnitProcessing\" xml:space=\"preserve\">\n    <value>嘗試執行時設定單位失敗： {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationUnitHasDuplicateIdentifier\" xml:space=\"preserve\">\n    <value>組態包含識別碼 '{0}' 多次。</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by the identifier string from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationUnitHasMissingDependency\" xml:space=\"preserve\">\n    <value>在組態中找不到相依性 '{0}'。</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by the identifier string from the user input file.</comment>\n  </data>\n  <data name=\"ConfigurationUnitManuallySkipped\" xml:space=\"preserve\">\n    <value>已手動略過此設定單位。</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleConflict\" xml:space=\"preserve\">\n    <value>設定單位的模組可在多個具有相同版本的位置使用。</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleImportFailed\" xml:space=\"preserve\">\n    <value>載入設定單位的模組失敗。</value>\n  </data>\n  <data name=\"ConfigurationUnitMultipleMatches\" xml:space=\"preserve\">\n    <value>找到多個符合設定單位的項目；指定模組以選取正確的項目。</value>\n  </data>\n  <data name=\"ConfigurationUnitNotFound\" xml:space=\"preserve\">\n    <value>找不到設定單位。</value>\n  </data>\n  <data name=\"ConfigurationUnitNotFoundInModule\" xml:space=\"preserve\">\n    <value>設定單位未如預期地存在於模組中。</value>\n  </data>\n  <data name=\"ConfigurationUnitNotRunDueToDependency\" xml:space=\"preserve\">\n    <value>未執行此設定單位，因為相依性失敗或未執行。</value>\n  </data>\n  <data name=\"ConfigurationUnitNotRunDueToFailedAssert\" xml:space=\"preserve\">\n    <value>未執行此設定單位，因為判斷提示失敗或為 False。</value>\n  </data>\n  <data name=\"ConfigurationUnitReturnedInvalidResult\" xml:space=\"preserve\">\n    <value>組態單位在執行期間傳回非預期的結果。</value>\n  </data>\n  <data name=\"ConfigurationUnitSkipped\" xml:space=\"preserve\">\n    <value>無法執行此設定單位，原因不明: {0}</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\n  </data>\n  <data name=\"ConfigurationFieldInvalidValue\" xml:space=\"preserve\">\n    <value>欄位'{0}'具有不正確值： {1}</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} An error in reading a configuration file. {0} is a placeholder replaced by the field name from the file. {1} is a placeholder for the invalid value.</comment>\n  </data>\n  <data name=\"ConfigurationFieldMissing\" xml:space=\"preserve\">\n    <value>欄位 [{0}] 遺失或為空白。</value>\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the expected field name from the file.</comment>\n  </data>\n  <data name=\"SeeLineAndColumn\" xml:space=\"preserve\">\n    <value>請參閱檔案中的行 {0}、欄{1}。</value>\n    <comment>{Locked=\"{0}\",\"{1}\"} Indicates the file location of the error, {0} and {1} are placeholders for numbers of the line and column, respectively.</comment>\n  </data>\n  <data name=\"CancellingOperation\" xml:space=\"preserve\">\n    <value>正在取消操作</value>\n  </data>\n  <data name=\"InstallStubPackageDescription\" xml:space=\"preserve\">\n    <value>安裝適用於 AppInstaller 的虛設常式封裝</value>\n  </data>\n  <data name=\"InstallFullPackageDescription\" xml:space=\"preserve\">\n    <value>安裝適用於 AppInstaller 的完整封裝</value>\n  </data>\n  <data name=\"ExtendedFeaturesEnableMessage\" xml:space=\"preserve\">\n    <value>啟用擴充功能。需要商店存取權。</value>\n  </data>\n  <data name=\"ExtendedFeaturesEnableArgumentError\" xml:space=\"preserve\">\n    <value>選項 '--enable' 和 '--disable' 不能與其他引數一起使用。</value>\n    <comment>{Locked=\"--enable\", \"--disable\"}</comment>\n  </data>\n  <data name=\"ExtendedFeaturesEnablingMessage\" xml:space=\"preserve\">\n    <value>正在啟用擴充功能。需要商店存取權。</value>\n  </data>\n  <data name=\"ExtendedFeaturesNotEnabledMessage\" xml:space=\"preserve\">\n    <value>未啟用擴充功能。執行「winget configure --enable」以啟用它們。</value>\n    <comment>{Locked=\"winget configure --enable\"}</comment>\n  </data>\n  <data name=\"ExtendedFeaturesEnabledMessage\" xml:space=\"preserve\">\n    <value>擴充功能已啟用。</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisableMessage\" xml:space=\"preserve\">\n    <value>停用擴充功能。需要商店存取權。</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisablingMessage\" xml:space=\"preserve\">\n    <value>正在停用擴充功能。需要商店存取權。</value>\n  </data>\n  <data name=\"ExtendedFeaturesDisabledMessage\" xml:space=\"preserve\">\n    <value>擴充功能已停用。</value>\n  </data>\n  <data name=\"SkipDependenciesArgumentDescription\" xml:space=\"preserve\">\n    <value>略過處理封裝相依性和 Windows 功能</value>\n  </data>\n  <data name=\"DependenciesSkippedMessage\" xml:space=\"preserve\">\n    <value>已略過相依性。</value>\n  </data>\n  <data name=\"FailedToRefreshPathWarning\" xml:space=\"preserve\">\n    <value>無法重新整理流程的 PATH 變數。取決於變更 PATH 變數的後續安裝可能會失敗。</value>\n    <comment>{Locked=\"PATH\"}</comment>\n  </data>\n  <data name=\"ConfigurationFailedToTest\" xml:space=\"preserve\">\n    <value>部分設定單位在測試其狀態時失敗。</value>\n  </data>\n  <data name=\"ConfigurationInDesiredState\" xml:space=\"preserve\">\n    <value>系統處於描述的組態狀態。</value>\n  </data>\n  <data name=\"ConfigurationNoTestRun\" xml:space=\"preserve\">\n    <value>組態狀態未進行測試。</value>\n  </data>\n  <data name=\"ConfigurationNotInDesiredState\" xml:space=\"preserve\">\n    <value>系統未處於描述的組態狀態。</value>\n  </data>\n  <data name=\"ConfigurationUnexpectedTestResult\" xml:space=\"preserve\">\n    <value>未預期的測試結果: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message. {0} will be replaced with the unexpected value (a number).</comment>\n  </data>\n  <data name=\"ConfigurationWarningPromptTest\" xml:space=\"preserve\">\n    <value>您是否已檢閱過組態，是否要繼續針對系統繼續驗證?</value>\n  </data>\n  <data name=\"ConfigurationFileInvalidYAML\" xml:space=\"preserve\">\n    <value>組態檔不是有效的 YAML 檔案。</value>\n    <comment>{Locked=\"YAML\"} YAML is a file format name.</comment>\n  </data>\n  <data name=\"ConfigurationUnitIsPartOfDependencyCycle\" xml:space=\"preserve\">\n    <value>此組態單位是相依性循環圖的一部分。</value>\n  </data>\n  <data name=\"ConfigurationValidationFoundNoIssues\" xml:space=\"preserve\">\n    <value>驗證找不到問題。</value>\n  </data>\n  <data name=\"ConfigurationUnitNeedsPrereleaseWarning\" xml:space=\"preserve\">\n    <value>設定單位只能做為發行前版本使用，但不會在組態中標示。將 'allowPrerelease: true' 新增至 'directives'。</value>\n    <comment>{Locked=\"allowPrerelease: true\",\"directives\"} These are values in the configuration file that are not localized.</comment>\n  </data>\n  <data name=\"ConfigurationUnitNotInCatalogWarning\" xml:space=\"preserve\">\n    <value>已在本機找到組態單元，但在任何已設定的目錄中找不到。在套用設定之前，請確保在任何系統上已存有此組態。</value>\n  </data>\n  <data name=\"ConfigurationUnitNotPublicWarning\" xml:space=\"preserve\">\n    <value>組態單位無法公開使用; 請確認任何會使用此設定的人員都可存取此設定。</value>\n  </data>\n  <data name=\"ConfigurationUnitModuleNotProvidedWarning\" xml:space=\"preserve\">\n    <value>未提供模組。指定模組可改善效能並防止未來名稱衝突。</value>\n  </data>\n  <data name=\"DownloadCommandLongDescription\" xml:space=\"preserve\">\n    <value>從選取的套件下載安裝程式，可能是透過搜尋已設定的來源或直接從資訊清單找到。根據預設，查詢必須不區分大小寫地符合封裝的識別碼、名稱或 Moniker。傳遞其他欄位的適當選項即可使用。根據預設，下載命令會將適當的安裝程式下載到使用者的 [下載] 資料夾。</value>\n  </data>\n  <data name=\"DownloadCommandShortDescription\" xml:space=\"preserve\">\n    <value>從指定的封裝下載安裝程式</value>\n  </data>\n  <data name=\"DownloadDirectoryArgumentDescription\" xml:space=\"preserve\">\n    <value>下載安裝程式的目錄</value>\n  </data>\n  <data name=\"DependenciesFlowDownload\" xml:space=\"preserve\">\n    <value>正在下載相依性:</value>\n  </data>\n  <data name=\"InstallerDownloaded\" xml:space=\"preserve\">\n    <value>已下載安裝程式: {0}</value>\n    <comment>{Locked=\"{0}\"} Full path of the downloaded installer.</comment>\n  </data>\n  <data name=\"InstallerTypeArgumentDescription\" xml:space=\"preserve\">\n    <value>選取安裝程式類型</value>\n  </data>\n  <data name=\"InstallerDownloads\" xml:space=\"preserve\">\n    <value>安裝程式下載</value>\n  </data>\n  <data name=\"InstallerDownloadCommandProhibited\" xml:space=\"preserve\">\n    <value>禁止下載安裝程式以供稍後離線安裝。 </value>\n  </data>\n  <data name=\"ConfigurationAllUsersElevated\" xml:space=\"preserve\">\n    <value>'--module-path allusers' 需要系統管理員權限才能執行。</value>\n    <comment>{Locked=\"--module-path allusers\"}</comment>\n  </data>\n  <data name=\"ConfigurationModulePath\" xml:space=\"preserve\">\n    <value>在本機電腦上指定位置以儲存模組。預設 %LOCALAPPDATA%\\Microsoft\\WinGet\\Configuration\\Modules</value>\n    <comment>{Locked=\"%LOCALAPPDATA%\\Microsoft\\WinGet\\Configuration\\Modules\"}</comment>\n  </data>\n  <data name=\"ConfigurationModulePathArgError\" xml:space=\"preserve\">\n    <value>'--module-path' 值必須是 'currentuser'、'allusers'、'default' 或絕對路徑。</value>\n    <comment>{Locked=\"{--module-path}, {currentuser}, {allusers}, {default}}</comment>\n  </data>\n  <data name=\"PolicyEnableWinGetConfiguration\" xml:space=\"preserve\">\n    <value>啟用 Windows 封裝管理員設定</value>\n  </data>\n  <data name=\"ErrorCommandLongDescription\" xml:space=\"preserve\">\n    <value>擷取錯誤的相關信息。指定數位后，輸出將包含錯誤的詳細數據，包括符號名稱，如果是 Winget 特定的錯誤。指定字串時，會搜尋 winget 特定錯誤以尋找此值。</value>\n  </data>\n  <data name=\"ErrorCommandShortDescription\" xml:space=\"preserve\">\n    <value>取得關於錯誤的資訊</value>\n  </data>\n  <data name=\"ErrorInputArgumentDescription\" xml:space=\"preserve\">\n    <value>要在錯誤資訊中搜尋的值</value>\n  </data>\n  <data name=\"ErrorNumberIsTooLarge\" xml:space=\"preserve\">\n    <value>指定的數位太大，無法成為 HRESULT。</value>\n  </data>\n  <data name=\"UnknownErrorCode\" xml:space=\"preserve\">\n    <value>未知錯誤代碼</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INTERNAL_ERROR\" xml:space=\"preserve\">\n    <value>內部錯誤</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS\" xml:space=\"preserve\">\n    <value>命令列引數無效</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMMAND_FAILED\" xml:space=\"preserve\">\n    <value>執行命令失敗</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_FAILED\" xml:space=\"preserve\">\n    <value>開啟資訊清單失敗</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CTRL_SIGNAL_RECEIVED\" xml:space=\"preserve\">\n    <value>已收到取消訊號</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SHELLEXEC_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>ShellExecute 執行失敗</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_MANIFESTVERSION\" xml:space=\"preserve\">\n    <value>無法處理指令清單。指令清單版本高於支援。請更新用戶端。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_FAILED\" xml:space=\"preserve\">\n    <value>下載安裝程序失敗</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX\" xml:space=\"preserve\">\n    <value>無法寫入索引;這是較高的架構版本</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INDEX_INTEGRITY_COMPROMISED\" xml:space=\"preserve\">\n    <value>索引已損毀</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCES_INVALID\" xml:space=\"preserve\">\n    <value>設定的來源資訊已損毀</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NAME_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>已設定來源名稱</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_SOURCE_TYPE\" xml:space=\"preserve\">\n    <value>來源類型無效</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_BUNDLE\" xml:space=\"preserve\">\n    <value>MSIX 檔案是套件組合，而不是套件</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_DATA_MISSING\" xml:space=\"preserve\">\n    <value>遺失來源所需的資料</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER\" xml:space=\"preserve\">\n    <value>沒有任何安裝程式適用於目前的系統</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_HASH_MISMATCH\" xml:space=\"preserve\">\n    <value>安裝程式檔案的哈希不符合指令清單</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NAME_DOES_NOT_EXIST\" xml:space=\"preserve\">\n    <value>來源名稱不存在</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_ARG_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>來源位置已在另一個名稱下設定</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICATIONS_FOUND\" xml:space=\"preserve\">\n    <value>找不到封裝</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_SOURCES_DEFINED\" xml:space=\"preserve\">\n    <value>未設定任何來源</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_APPLICATIONS_FOUND\" xml:space=\"preserve\">\n    <value>找到多個符合準則的封裝</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_MANIFEST_FOUND\" xml:space=\"preserve\">\n    <value>找不到符合準則的資訊清單。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXTENSION_PUBLIC_FAILED\" xml:space=\"preserve\">\n    <value>無法從來源套件取得公用資料夾</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMMAND_REQUIRES_ADMIN\" xml:space=\"preserve\">\n    <value>命令需要系統管理員權限才能執行</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NOT_SECURE\" xml:space=\"preserve\">\n    <value>來源位置不安全</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>原則已封鎖 Microsoft Store 用戶端</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_APP_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>原則已封鎖 Microsoft Store 應用程式</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXPERIMENTAL_FEATURE_DISABLED\" xml:space=\"preserve\">\n    <value>功能目前正在開發中。您可以使用 winget 設定來啟用它。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>安裝 Microsoft Store 應用程式失敗</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_COMPLETE_INPUT_BAD\" xml:space=\"preserve\">\n    <value>無法執行自動完成</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED\" xml:space=\"preserve\">\n    <value>無法初始化 YAML 剖析器</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_MAPPING_KEY\" xml:space=\"preserve\">\n    <value>遇到無效的 YAML 金鑰</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY\" xml:space=\"preserve\">\n    <value>遇到重複的 YAML 金鑰</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_OPERATION\" xml:space=\"preserve\">\n    <value>YAML 作業無效</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_DOC_BUILD_FAILED\" xml:space=\"preserve\">\n    <value>無法建置 YAML 文件</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_EMITTER_STATE\" xml:space=\"preserve\">\n    <value>YAML 發射器狀態無效</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_DATA\" xml:space=\"preserve\">\n    <value>無效的 YAML 資料</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LIBYAML_ERROR\" xml:space=\"preserve\">\n    <value>LibYAML 錯誤</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_WARNING\" xml:space=\"preserve\">\n    <value>資訊清單驗證成功，但出現警告</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_FAILURE\" xml:space=\"preserve\">\n    <value>資訊清單驗證失敗</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_MANIFEST\" xml:space=\"preserve\">\n    <value>資訊清單無效</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>找不到適用的更新</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPDATE_ALL_HAS_FAILURE\" xml:space=\"preserve\">\n    <value>winget 升級 -- 全部完成，但有失敗部分</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_SECURITY_CHECK_FAILED\" xml:space=\"preserve\">\n    <value>安裝程式的安全性檢查失敗</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_SIZE_MISMATCH\" xml:space=\"preserve\">\n    <value>下載大小不符合預期的內容長度</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_UNINSTALL_INFO_FOUND\" xml:space=\"preserve\">\n    <value>找不到解除安裝命令</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXEC_UNINSTALL_COMMAND_FAILED\" xml:space=\"preserve\">\n    <value>執行解除安裝命令失敗</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_BREAK_ITERATOR_ERROR\" xml:space=\"preserve\">\n    <value>ICU 中斷列舉程式錯誤</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_CASEMAP_ERROR\" xml:space=\"preserve\">\n    <value>ICU 案例對應錯誤</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_REGEX_ERROR\" xml:space=\"preserve\">\n    <value>ICU Regex 錯誤</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_IMPORT_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>無法安裝一或多個匯入的套件</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NOT_ALL_PACKAGES_FOUND\" xml:space=\"preserve\">\n    <value>找不到一或多個要求的套件</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE\" xml:space=\"preserve\">\n    <value>無效的 Json 檔案</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NOT_REMOTE\" xml:space=\"preserve\">\n    <value>來源位置非遠端</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE\" xml:space=\"preserve\">\n    <value>不支援設定的剩餘來源</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA\" xml:space=\"preserve\">\n    <value>剩餘來源傳回的資料無效</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>[群組原則] 封鎖作業</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_INTERNAL_ERROR\" xml:space=\"preserve\">\n    <value>Rest API 內部錯誤</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_URL\" xml:space=\"preserve\">\n    <value>剩餘來源 URL 無效</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_UNSUPPORTED_MIME_TYPE\" xml:space=\"preserve\">\n    <value>剩餘 API 傳回不支援的 MIME 類型</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_VERSION\" xml:space=\"preserve\">\n    <value>休息來源合約版本無效</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE\" xml:space=\"preserve\">\n    <value>來源資料已損毀或遭竄改</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_STREAM_READ_FAILURE\" xml:space=\"preserve\">\n    <value>從資料流讀取時發生錯誤</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>未同意的封裝合約。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PROMPT_INPUT_ERROR\" xml:space=\"preserve\">\n    <value>讀取輸入提示時發生錯誤</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST\" xml:space=\"preserve\">\n    <value>一或多個來源不支持搜尋要求</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_ENDPOINT_NOT_FOUND\" xml:space=\"preserve\">\n    <value>找不到其餘的 API 端點。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_OPEN_FAILED\" xml:space=\"preserve\">\n    <value>無法開啟來源。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>未同意的來源合約</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CUSTOMHEADER_EXCEEDS_MAXLENGTH\" xml:space=\"preserve\">\n    <value>標頭大小超過允許的1024個字元限制。請縮減大小，然後再試一次。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MISSING_RESOURCE_FILE\" xml:space=\"preserve\">\n    <value>遺失資源檔案</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MSI_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>執行 MSI 安裝失敗</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT\" xml:space=\"preserve\">\n    <value>msiexec 的引數無效</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FAILED_TO_OPEN_ALL_SOURCES\" xml:space=\"preserve\">\n    <value>無法開啟一或多個來源</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>無法驗證相依性</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MISSING_PACKAGE\" xml:space=\"preserve\">\n    <value>一或多個封裝遺失</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_TABLE_COLUMN\" xml:space=\"preserve\">\n    <value>無效資料行欄</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_NOT_NEWER\" xml:space=\"preserve\">\n    <value>升級版本不比安裝的版本新</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_UNKNOWN\" xml:space=\"preserve\">\n    <value>升級版本不明，且未指定覆寫</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_CONVERSION_ERROR\" xml:space=\"preserve\">\n    <value>ICU 轉換錯誤</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>無法安裝可攜式封裝</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_REPARSE_POINT_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>磁碟區不支援重新分析點</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_PACKAGE_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>來自不同來源的可攜式封裝已經存在。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_SYMLINK_PATH_IS_DIRECTORY\" xml:space=\"preserve\">\n    <value>無法建立符號連結。路徑指向目錄。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_PROHIBITS_ELEVATION\" xml:space=\"preserve\">\n    <value>無法從系統管理員內容執行安裝程式。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>無法解除安裝可攜式封裝</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ARP_VERSION_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>無法根據索引驗證 DisplayVersion 值。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_ARGUMENT\" xml:space=\"preserve\">\n    <value>不支援一個或多個引數。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_BIND_WITH_EMBEDDED_NULL\" xml:space=\"preserve\">\n    <value>SQLite 不允許內嵌 Null 字元</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_NOT_FOUND\" xml:space=\"preserve\">\n    <value>在封存中找不到巢狀安裝程式。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXTRACT_ARCHIVE_FAILED\" xml:space=\"preserve\">\n    <value>無法解壓縮封存。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_INVALID_PATH\" xml:space=\"preserve\">\n    <value>提供的巢狀安裝程式相對檔案路徑無效。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PINNED_CERTIFICATE_MISMATCH\" xml:space=\"preserve\">\n    <value>伺服器證書不符合任何預期值。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_LOCATION_REQUIRED\" xml:space=\"preserve\">\n    <value>必須提供安裝位置。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ARCHIVE_SCAN_FAILED\" xml:space=\"preserve\">\n    <value>封存惡意代碼掃描失敗。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>找到至少一個已安裝的套件版本。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PIN_ALREADY_EXISTS\" xml:space=\"preserve\">\n    <value>封裝已經有釘選。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PIN_DOES_NOT_EXIST\" xml:space=\"preserve\">\n    <value>沒有適用於封裝的釘選。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_OPEN_PINNING_INDEX\" xml:space=\"preserve\">\n    <value>無法開啟釘選資料庫。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>一個或多個應用程式無法安裝</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>無法解除安裝一個或多個應用程式</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NOT_ALL_QUERIES_FOUND_SINGLE\" xml:space=\"preserve\">\n    <value>一或多個查詢未傳回完全相符的專案</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_PINNED\" xml:space=\"preserve\">\n    <value>封裝有防止升級的 PIN。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB\" xml:space=\"preserve\">\n    <value>目前安裝的套件是存根套件</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_APPTERMINATION_RECEIVED\" xml:space=\"preserve\">\n    <value>已收到應用程式關機訊號</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_DEPENDENCIES\" xml:space=\"preserve\">\n    <value>無法下載封裝相依性。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_COMMAND_PROHIBITED\" xml:space=\"preserve\">\n    <value>無法下載套件。禁止下載以進行離線安裝。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SERVICE_UNAVAILABLE\" xml:space=\"preserve\">\n    <value>必要服務忙碌中或無法使用。請稍後再試。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESUME_ID_NOT_FOUND\" xml:space=\"preserve\">\n    <value>提供的 GUID 未對應到有效的繼續狀態。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CLIENT_VERSION_MISMATCH\" xml:space=\"preserve\">\n    <value>目前的用戶端版本不符合儲存狀態的用戶端版本。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_RESUME_STATE\" xml:space=\"preserve\">\n    <value>恢復狀態資料無效。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_OPEN_CHECKPOINT_INDEX\" xml:space=\"preserve\">\n    <value>無法開啟檢查點資料庫。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_RESUME_LIMIT_EXCEEDED\" xml:space=\"preserve\">\n    <value>已超過最大恢復限制。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_AUTHENTICATION_INFO\" xml:space=\"preserve\">\n    <value>無效驗證資訊。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>不支援驗證方法。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED\" xml:space=\"preserve\">\n    <value>驗證失敗。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_INTERACTIVE_REQUIRED\" xml:space=\"preserve\">\n    <value>驗證失敗。需要互動式驗證。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_CANCELLED_BY_USER\" xml:space=\"preserve\">\n    <value>驗證失敗。使用者已取消。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_INCORRECT_ACCOUNT\" xml:space=\"preserve\">\n    <value>驗證失敗。已驗證的帳戶不是所需的帳戶。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE\" xml:space=\"preserve\">\n    <value>應用程式目前正在執行。結束應用程式，然後再試一次。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INSTALL_IN_PROGRESS\" xml:space=\"preserve\">\n    <value>另一個安裝已在進行中。請稍後再試。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_FILE_IN_USE\" xml:space=\"preserve\">\n    <value>一或多個檔案正在使用中。結束應用程式，然後再試一次。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_MISSING_DEPENDENCY\" xml:space=\"preserve\">\n    <value>您的系統遺漏此套件的相依性。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DISK_FULL\" xml:space=\"preserve\">\n    <value>您的電腦上已經沒有空間。請釋出空間，然後再試一次。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INSUFFICIENT_MEMORY\" xml:space=\"preserve\">\n    <value>記憶體不足，無法安裝。請關閉其他應用程式，然後再試一次。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_NO_NETWORK\" xml:space=\"preserve\">\n    <value>此應用程式需要因特網連線。請連線到網路，然後再試一次。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CONTACT_SUPPORT\" xml:space=\"preserve\">\n    <value>此應用程式在安裝期間發生錯誤。連絡客戶支援。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_TO_FINISH\" xml:space=\"preserve\">\n    <value>重新啟動您的電腦以完成安裝。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_FOR_INSTALL\" xml:space=\"preserve\">\n    <value>安裝失敗。請重新啟動您的計算機，然後再試一次。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_INITIATED\" xml:space=\"preserve\">\n    <value>將重新開機您的電腦以完成安裝。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CANCELLED_BY_USER\" xml:space=\"preserve\">\n    <value>您取消了安裝。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>已安裝此應用程式的另一個版本。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DOWNGRADE\" xml:space=\"preserve\">\n    <value>已安裝此應用程式的較新版本。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\n    <value>組織原則導致無法安裝。請連絡您的系統管理員。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DEPENDENCIES\" xml:space=\"preserve\">\n    <value>無法安裝封裝相依性。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE_BY_APPLICATION\" xml:space=\"preserve\">\n    <value>應用程式目前正由另一個應用程式使用中。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INVALID_PARAMETER\" xml:space=\"preserve\">\n    <value>參數無效。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>系統不支援封裝。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_UPGRADE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>安裝程式不支持升級現有的封裝。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CUSTOM_ERROR\" xml:space=\"preserve\">\n    <value>安裝失敗，出現自訂安裝程式錯誤。</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_ARP_ENTRY_NOT_FOUND\" xml:space=\"preserve\">\n    <value>找不到套件的應用程式和功能專案。</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>安裝位置不適用。</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_FOUND\" xml:space=\"preserve\">\n    <value>找不到安裝位置。</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_HASH_MISMATCH\" xml:space=\"preserve\">\n    <value>現有檔案的哈希不符。</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_NOT_FOUND\" xml:space=\"preserve\">\n    <value>找不到檔案。</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK\" xml:space=\"preserve\">\n    <value>找到檔案，但未檢查哈希。</value>\n  </data>\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_ACCESS_ERROR\" xml:space=\"preserve\">\n    <value>無法存取檔案。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE\" xml:space=\"preserve\">\n    <value>設定檔案無效。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_YAML\" xml:space=\"preserve\">\n    <value>YAML 語法無效。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_FIELD_TYPE\" xml:space=\"preserve\">\n    <value>設定欄位的類型無效。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION\" xml:space=\"preserve\">\n    <value>設定的版本不明。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_SET_APPLY_FAILED\" xml:space=\"preserve\">\n    <value>在套用設定時發生錯誤。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER\" xml:space=\"preserve\">\n    <value>設定包含重複的識別碼。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MISSING_DEPENDENCY\" xml:space=\"preserve\">\n    <value>設定缺少相依性。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED\" xml:space=\"preserve\">\n    <value>設定具有未滿足的相依性。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_ASSERTION_FAILED\" xml:space=\"preserve\">\n    <value>設定單位的聲明失敗。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MANUALLY_SKIPPED\" xml:space=\"preserve\">\n    <value>已手動略過設定。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_WARNING_NOT_ACCEPTED\" xml:space=\"preserve\">\n    <value>使用者拒絕繼續執行。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_SET_DEPENDENCY_CYCLE\" xml:space=\"preserve\">\n    <value>相依性圖形包含無法解析的迴圈。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_FIELD_VALUE\" xml:space=\"preserve\">\n    <value>設定具有無效的欄位值。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_MISSING_FIELD\" xml:space=\"preserve\">\n    <value>設定缺少一個欄位。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_TEST_FAILED\" xml:space=\"preserve\">\n    <value>部分設定單位在測試其狀態時失敗。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_TEST_NOT_RUN\" xml:space=\"preserve\">\n    <value>組態狀態未進行測試。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_NOT_INSTALLED\" xml:space=\"preserve\">\n    <value>未安裝設定單位。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_NOT_FOUND_REPOSITORY\" xml:space=\"preserve\">\n    <value>找不到設定單位。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_MULTIPLE_MATCHES\" xml:space=\"preserve\">\n    <value>找到多個符合設定單位的項目；指定模組以選取正確的項目。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_GET\" xml:space=\"preserve\">\n    <value>嘗試取得目前的系統狀態時，設定單位失敗。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_TEST\" xml:space=\"preserve\">\n    <value>嘗試測試目前的系統狀態時，組態單位失敗。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_SET\" xml:space=\"preserve\">\n    <value>嘗試套用所需的狀態時，組態單位失敗。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_MODULE_CONFLICT\" xml:space=\"preserve\">\n    <value>設定單位的模組可在多個具有相同版本的位置使用。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE\" xml:space=\"preserve\">\n    <value>載入設定單位的模組失敗。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_INVALID_RESULT\" xml:space=\"preserve\">\n    <value>組態單位在執行期間傳回非預期的結果。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_SETTING_CONFIG_ROOT\" xml:space=\"preserve\">\n    <value>單位包含需要設定根目錄的設定。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR\" xml:space=\"preserve\">\n    <value>設定處理器不支援此作業。</value>\n  </data>\n  <data name=\"Unavailable\" xml:space=\"preserve\">\n    <value>無法使用</value>\n  </data>\n  <data name=\"EnableWindowsFeaturesSuccess\" xml:space=\"preserve\">\n    <value>已成功啟用 Windows 功能相依性</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE_ADMIN\" xml:space=\"preserve\">\n    <value>載入組態單位的模組失敗，因為它需要系統管理員許可權才能執行。</value>\n  </data>\n  <data name=\"ConfigurationUnitSettingConfigRoot\" xml:space=\"preserve\">\n    <value>單位包含需要設定根目錄的設定。</value>\n  </data>\n  <data name=\"ConfigurationUnitImportModuleAdmin\" xml:space=\"preserve\">\n    <value>載入組態單位的模組失敗，因為它需要系統管理員許可權才能執行。</value>\n  </data>\n  <data name=\"ResumeCommandLongDescription\" xml:space=\"preserve\">\n    <value>傳入儲存命令的唯一標識符，以繼續執行先前儲存的命令。這可用來繼續可能因重新啟動而終止的已執行命令。</value>\n  </data>\n  <data name=\"ResumeCommandShortDescription\" xml:space=\"preserve\">\n    <value>繼續執行先前儲存的命令。</value>\n  </data>\n  <data name=\"ResumeIdArgumentDescription\" xml:space=\"preserve\">\n    <value>要繼續之儲存狀態的唯一標識符</value>\n  </data>\n  <data name=\"ClientVersionMismatchError\" xml:space=\"preserve\">\n    <value>不支援從不同的用戶端版本繼續狀態： {0}</value>\n    <comment>{Locked= \"{0}\"} Message displayed to inform the user that the client version of the resume state does not match the current client version. {0} is a placeholder for the client version that created the resume state.</comment>\n  </data>\n  <data name=\"ResumeIdNotFoundError\" xml:space=\"preserve\">\n    <value>恢復狀態不存在: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a guid that does not correspond to a valid saved state. {0} is a placeholder replaced by the provided guid string.</comment>\n  </data>\n  <data name=\"ResumeStateDataNotFoundError\" xml:space=\"preserve\">\n    <value>在恢復狀態中找不到任何資料。</value>\n  </data>\n  <data name=\"CommandDoesNotSupportResumeMessage\" xml:space=\"preserve\">\n    <value>此命令不支持恢復。</value>\n  </data>\n  <data name=\"AllowRebootArgumentDescription\" xml:space=\"preserve\">\n    <value>如果適用，則允許重新開機</value>\n  </data>\n  <data name=\"InitiatingReboot\" xml:space=\"preserve\">\n    <value>正在起始重新開機，以完成作業...</value>\n  </data>\n  <data name=\"FailedToInitiateReboot\" xml:space=\"preserve\">\n    <value>無法起始重新開機。</value>\n  </data>\n  <data name=\"ResumeLimitExceeded\" xml:space=\"preserve\">\n    <value>繼續作業超過允許的 {0} 繼續() 限制。若要手動繼續，請執行命令 '{1}'。</value>\n    <comment>{Locked=\"{0}\", \"{1}\"} {0} is a placeholder that is replaced by an integer number of the number of allowed resumes. {1} is a placeholder for the command to run to perform a manual resume.</comment>\n  </data>\n  <data name=\"IgnoreResumeLimitArgumentDescription\" xml:space=\"preserve\">\n    <value>略過繼續儲存狀態的限制</value>\n  </data>\n  <data name=\"UriSchemeNotSupported\" xml:space=\"preserve\">\n    <value>不支援 Uri 配置: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the provided uri is not supported. {0} is a placeholder replaced by the provided uri.</comment>\n  </data>\n  <data name=\"UriNotWellFormed\" xml:space=\"preserve\">\n    <value>Uri 的格式不正確: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when the provided uri is not well formed. {0} is a placeholder replaced by the provided uri.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitEmptyContent\" xml:space=\"preserve\">\n    <value>無法剖析 {0} 組態單位設定內容或設定內容是空的。</value>\n    <comment>{Locked=\"{0}\"} {0} is a placeholder replaced by the input winget configure resource unit type.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitMissingRequiredArg\" xml:space=\"preserve\">\n    <value>{0} 組態單位遺漏必要的自變數： {1}</value>\n    <comment>{Locked=\"{0},{1}\"} {0} is a placeholder for the input winget configure resource unit type. {1} is placeholder for the missing arg.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitMissingRecommendedArg\" xml:space=\"preserve\">\n    <value>{0} 組態單位遺漏建議的自變數： {1}</value>\n    <comment>{Locked=\"{0},{1}\"} {0} is a placeholder for the input winget configure resource unit type. {1} is placeholder for the missing arg.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitKnownSourceConfliction\" xml:space=\"preserve\">\n    <value>WinGetSource 組態單位與已知來源衝突： {0}</value>\n    <comment>{Locked=\"WinGetSource,{0}\"} {0} is a placeholder for the input winget source in the configuration unit settings.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitThirdPartySourceAssertion\" xml:space=\"preserve\">\n    <value>第三方來源的 WinGetSource 組態單位判斷提示： {0}</value>\n    <comment>{Locked=\"WinGetSource,{0}\"} {0} is a placeholder for the input winget source in the configuration unit settings.</comment>\n  </data>\n  <data name=\"WinGetResourceUnitBothPackageVersionAndUseLatest\" xml:space=\"preserve\">\n    <value>WinGetPackage 宣告 UseLatest 和 Version。套件識別碼： {0}</value>\n    <comment>{Locked=\"WinGetPackage,UseLatest,Version,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitThirdPartySourceAssertionForPackage\" xml:space=\"preserve\">\n    <value>WinGetPackage 組態單位在來自第三方來源的封裝上宣告。套件標識碼： {0};來源： {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitDependencySourceNotConfigured\" xml:space=\"preserve\">\n    <value>WinGetPackage 設定單元套件相依於先前未設定的第三方來源。套件標識碼： {0};來源： {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitDependencySourceNotDeclaredAsDependency\" xml:space=\"preserve\">\n    <value>WinGetPackage 設定單元套件相依於第三方來源。建議您在 uni dependsOn 區段中宣告相依性。套件標識碼： {0};來源： {1}</value>\n    <comment>{Locked=\"WinGetPackage,dependsOn,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageSourceOpenFailed\" xml:space=\"preserve\">\n    <value>無法驗證 WinGetPackage 設定單元套件。來源開啟失敗。套件標識碼： {0};來源： {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageNotFound\" xml:space=\"preserve\">\n    <value>無法驗證 WinGetPackage 設定單元套件。找不到套件。套件識別碼： {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageMultipleFound\" xml:space=\"preserve\">\n    <value>無法驗證 WinGetPackage 設定單元套件。找到多個套件。套件識別碼： {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackageVersionNotFound\" xml:space=\"preserve\">\n    <value>無法驗證 WinGetPackage 設定單元套件。找不到套件版本。套件標識碼： {0};版本 {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitPackageVersionSpecifiedWithOnlyOnePackageVersion\" xml:space=\"preserve\">\n    <value>以特定版本指定的 WinGetPackage 設定單元封裝，其中只有一個封裝版本可用。封裝識別碼: {0}；版本: {1}</value>\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\n  </data>\n  <data name=\"WinGetResourceUnitFailedToValidatePackage\" xml:space=\"preserve\">\n    <value>無法驗證 WinGetPackage 設定單元套件。套件識別碼： {0}</value>\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\n  </data>\n  <data name=\"AuthenticationModeArgumentDescription\" xml:space=\"preserve\">\n    <value>指定驗證視窗喜好設定 (silent、silentPreferred 或 interactive)</value>\n    <comment>{Locked=\"silent\",\"silentPreferred\",\"interactive\"} This argument allows the user to select authentication window popup behavior.</comment>\n  </data>\n  <data name=\"AuthenticationAccountArgumentDescription\" xml:space=\"preserve\">\n    <value>指定要用於驗證的帳戶</value>\n  </data>\n  <data name=\"SourceAddFailedAuthenticationNotSupported\" xml:space=\"preserve\">\n    <value>無法新增來源。此 winget 版本不支援來源的驗證方法。嘗試升級至最新 winget 版本。</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"SourceRequiresAuthentication\" xml:space=\"preserve\">\n    <value>{0} 來源需要驗證。必要時可能會顯示驗證提示。已驗證的資訊將與來源共用以取得存取授權。</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"RepairCommandLongDescription\" xml:space=\"preserve\">\n    <value>修復選取的套件，您可以搜尋已安裝的套件清單，或直接從指令清單找到該套件。根據預設，查詢必須不區分大小寫地符合封裝的標識碼、名稱或Moniker。傳遞其他欄位的適當選項即可使用。</value>\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\n  </data>\n  <data name=\"RepairCommandShortDescription\" xml:space=\"preserve\">\n    <value>修復選取的封裝</value>\n  </data>\n  <data name=\"NoRepairInfoFound\" xml:space=\"preserve\">\n    <value>找不到此封裝的修復命令。請連絡套件發行者以取得支援。</value>\n  </data>\n  <data name=\"RepairDifferentInstallTechnology\" xml:space=\"preserve\">\n    <value>使用中的安裝程序技術與目前安裝的版本不符。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_REPAIR_INFO_FOUND\" xml:space=\"preserve\">\n    <value>找不到修復命令。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_REPAIR_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>使用中的安裝程序技術不支持修復。</value>\n  </data>\n  <data name=\"RepairFlowRepairSuccess\" xml:space=\"preserve\">\n    <value>修復作業已成功完成。</value>\n  </data>\n  <data name=\"RepairAbandoned\" xml:space=\"preserve\">\n    <value>已放棄修復</value>\n  </data>\n  <data name=\"RepairFlowStartingPackageRepair\" xml:space=\"preserve\">\n    <value>正在啟動封裝修復...</value>\n  </data>\n  <data name=\"MSStoreRepairFailed\" xml:space=\"preserve\">\n    <value>無法修復 Microsoft Store 封裝。錯誤碼: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when a Microsoft Store application package fails to repair. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_EXEC_REPAIR_FAILED\" xml:space=\"preserve\">\n    <value>修復作業失敗。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_REPAIR_NOT_APPLICABLE\" xml:space=\"preserve\">\n    <value>修復作業不適用。</value>\n  </data>\n  <data name=\"RepairFlowNoMatchingVersion\" xml:space=\"preserve\">\n    <value>沒有相符的封裝版本可從設定的來源使用。</value>\n  </data>\n  <data name=\"RepairFlowReturnCodeSystemNotSupported\" xml:space=\"preserve\">\n    <value>目前的系統設定不支援修復此封裝。</value>\n  </data>\n  <data name=\"RepairOperationNotSupported\" xml:space=\"preserve\">\n    <value>使用中的安裝程序技術不支持修復。</value>\n  </data>\n  <data name=\"NoAdminRepairForUserScopePackage\" xml:space=\"preserve\">\n    <value>以系統管理員許可權執行時，無法修復為用戶範圍安裝的套件。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED\" xml:space=\"preserve\">\n    <value>不允許在使用者範圍內安裝的套件上修復涉及系統管理員許可權的作業。</value>\n  </data>\n  <data name=\"RepairFailedWithCode\" xml:space=\"preserve\">\n    <value>修復失敗，結束代碼為: {0}</value>\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to repair an application package fails. {0} is a placeholder replaced by an error code.</comment>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SQLITE_CONNECTION_TERMINATED\" xml:space=\"preserve\">\n    <value>已終止 SQLite 連線以避免損毀。</value>\n  </data>\n  <data name=\"UninstallAllVersionsArgumentDescription\" xml:space=\"preserve\">\n    <value>解除安裝所有版本</value>\n  </data>\n  <data name=\"TargetVersionArgumentDescription\" xml:space=\"preserve\">\n    <value>要執行的版本</value>\n  </data>\n  <data name=\"UninstallFailedDueToMultipleVersions\" xml:space=\"preserve\">\n    <value>已安裝此套件的多個版本。請精簡搜尋、傳遞 '--version' 自變數以選取，或傳遞 '--all-versions' 旗標以卸載所有專案。</value>\n    <comment>{Locked=\"--version,--all-versions\"}</comment>\n  </data>\n  <data name=\"PolicyEnableProxyCommandLineOptions\" xml:space=\"preserve\">\n    <value>啟用Windows 封裝管理員 Proxy 命令行選項</value>\n    <comment>Describes a Group Policy that can enable the use of the --proxy option to set a proxy</comment>\n  </data>\n  <data name=\"ProxyArgumentDescription\" xml:space=\"preserve\">\n    <value>設定要用於此執行的 Proxy</value>\n  </data>\n  <data name=\"NoProxyArgumentDescription\" xml:space=\"preserve\">\n    <value>停用此執行的 Proxy 使用</value>\n  </data>\n  <data name=\"ResetAdminSettingFailed\" xml:space=\"preserve\">\n    <value>無法重設 {0}。這個設定是由原則控制。如需詳細資訊，請連絡您的系統管理員。</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"ResetAdminSettingSucceeded\" xml:space=\"preserve\">\n    <value>重設系統管理員設定 '{0}'。</value>\n    <comment>{Locked=\"{0}\"} Message displayed after the user resets an admin setting to its default value. Reset is used as verb in past tense. {0} is a placeholder replaced by the setting name.</comment>\n  </data>\n  <data name=\"SetAdminSettingFailed\" xml:space=\"preserve\">\n    <value>無法設定 {0}。這個設定是由原則控制。如需詳細資訊，請連絡您的系統管理員。</value>\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\n  </data>\n  <data name=\"SetAdminSettingSucceeded\" xml:space=\"preserve\">\n    <value>將系統管理員設定 '{0}' 設為 '{1}'。</value>\n    <comment>{Locked=\"{0}\"} Message displayed after the user sets the value of an admin setting. Set is used as a verb in past tense. {0} is a placeholder replaced by the setting name. {1} is a placeholder replaced </comment>\n  </data>\n  <data name=\"SettingNameArgumentDescription\" xml:space=\"preserve\">\n    <value>要修改之設定的名稱</value>\n  </data>\n  <data name=\"SettingValueArgumentDescription\" xml:space=\"preserve\">\n    <value>要為設定設定的值。</value>\n  </data>\n  <data name=\"SettingsResetCommandLongDescription\" xml:space=\"preserve\">\n    <value>將系統管理員設定重設為其預設值。</value>\n  </data>\n  <data name=\"SettingsResetCommandShortDescription\" xml:space=\"preserve\">\n    <value>將系統管理員設定重設為其預設值。</value>\n  </data>\n  <data name=\"SettingsSetCommandLongDescription\" xml:space=\"preserve\">\n    <value>設定系統管理設定的值。</value>\n  </data>\n  <data name=\"SettingsSetCommandShortDescription\" xml:space=\"preserve\">\n    <value>設定系統管理設定的值。</value>\n  </data>\n  <data name=\"SourceExplicitArgumentDescription\" xml:space=\"preserve\">\n    <value>除非指定，否則將來源排除在探索之外</value>\n  </data>\n  <data name=\"SourceEditExplicitArgumentDescription\" xml:space=\"preserve\">\n    <value>從探索中排除來源 (true 或 false)</value>\n  </data>\n  <data name=\"SourceListExplicit\" xml:space=\"preserve\">\n    <value>偏激</value>\n  </data>\n  <data name=\"SourceTrustLevelArgumentDescription\" xml:space=\"preserve\">\n    <value>來源的信任層級 (無或信任)</value>\n  </data>\n  <data name=\"SourceListTrustLevel\" xml:space=\"preserve\">\n    <value>信任層級</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_DISPLAYCATALOG_API_FAILED\" xml:space=\"preserve\">\n    <value>無法取得 Microsoft Store 封裝類別目錄。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_DISPLAYCATALOG_PACKAGE\" xml:space=\"preserve\">\n    <value>在套件目錄 Microsoft Store 找不到適用的 Microsoft Store 封裝。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SFSCLIENT_API_FAILED\" xml:space=\"preserve\">\n    <value>無法取得 Microsoft Store 套件下載資訊。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_SFSCLIENT_PACKAGE\" xml:space=\"preserve\">\n    <value>找不到適用於下載Microsoft Store套件。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED\" xml:space=\"preserve\">\n    <value>無法擷取 Microsoft Store 套件授權。</value>\n  </data>\n  <data name=\"MSStoreDownloadNoApplicablePackageFound\" xml:space=\"preserve\">\n    <value>找不到適用的 Microsoft Store 套件。</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageHashVerified\" xml:space=\"preserve\">\n    <value>已成功驗證 Microsoft Store 套件雜湊</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageHashMismatch\" xml:space=\"preserve\">\n    <value>Microsoft Store 套件雜湊不符</value>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloaded\" xml:space=\"preserve\">\n    <value>已下載 Microsoft Store套件: {0}</value>\n    <comment>{Locked=\"{0}\"} Full path of the downloaded package.</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadFailed\" xml:space=\"preserve\">\n    <value>Microsoft Store 套件下載失敗: {0}</value>\n    <comment>{Locked=\"{0}\"} Package name.</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadSuccess\" xml:space=\"preserve\">\n    <value>Microsoft Store 套件下載完成</value>\n  </data>\n  <data name=\"MSStoreDownloadMainPackages\" xml:space=\"preserve\">\n    <value>正在從 Microsoft Store 下載主要套件...</value>\n  </data>\n  <data name=\"MSStoreDownloadDependencyPackages\" xml:space=\"preserve\">\n    <value>正在從 Microsoft Store 下載相依性套件...</value>\n  </data>\n  <data name=\"MSStoreDownloadGetDownloadInfo\" xml:space=\"preserve\">\n    <value>正在擷取 Microsoft Store 套件下載資訊</value>\n  </data>\n  <data name=\"MSStoreDownloadGetDownloadInfoFailed\" xml:space=\"preserve\">\n    <value>無法擷取 Microsoft Store 套件下載資訊</value>\n  </data>\n  <data name=\"MSStoreDownloadGetLicense\" xml:space=\"preserve\">\n    <value>正在擷取 Microsoft Store 套件授權</value>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseSuccess\" xml:space=\"preserve\">\n    <value>已儲存 Microsoft Store套件授權: {0}</value>\n    <comment>{Locked=\"{0}\"} License file full path.</comment>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseFailed\" xml:space=\"preserve\">\n    <value>無法擷取 Microsoft Store 套件授權</value>\n  </data>\n  <data name=\"MSStoreDownloadRenameNotSupported\" xml:space=\"preserve\">\n    <value>Microsoft Store 套件下載不支援 --rename 引數。Microsoft Store 封裝將使用 Microsoft Store 目錄提供的名稱。</value>\n    <comment>{Locked=\"--rename\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadAuthenticationNotice\" xml:space=\"preserve\">\n    <value>Microsoft Store套件下載需要 Microsoft Entra 標識符驗證。必要時可能會顯示驗證提示。將與Microsoft 服務共享已驗證的信息，以進行存取授權。對於Microsoft Store套件授權，Microsoft Entra 標識符帳戶必須是全域管理員、用戶系統管理員或授權系統管理員的成員。</value>\n    <comment>{Locked=\"Global Administrator,User Administrator,License Administrator\"}</comment>\n  </data>\n  <data name=\"SkipMicrosoftStorePackageLicenseArgumentDescription\" xml:space=\"preserve\">\n    <value>略過擷取 Microsoft Store 套件離線授權</value>\n  </data>\n  <data name=\"PlatformArgumentDescription\" xml:space=\"preserve\">\n    <value>選取目標平台</value>\n  </data>\n  <data name=\"ConfigurationExportAddingToFile\" xml:space=\"preserve\">\n    <value>正在新增設定檔: {0}</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportSuccessful\" xml:space=\"preserve\">\n    <value>已成功匯出</value>\n  </data>\n  <data name=\"ConfigurationGettingResourceSettings\" xml:space=\"preserve\">\n    <value>正在取得組態設定...</value>\n  </data>\n  <data name=\"ConfigureExportArgumentRequiredError\" xml:space=\"preserve\">\n    <value>至少必須提供 --packageId 和/或 --module with --resource。或使用 --all 匯出所有封裝組態。</value>\n    <comment>{Locked=\"--packageId,--module, --resource, --all\"}</comment>\n  </data>\n  <data name=\"ConfigureExportArgumentConflictWithAllError\" xml:space=\"preserve\">\n    <value>自變數 --packageId、--module 和 --resource 不能與 --all 一起使用。</value>\n    <comment>{Locked=\"--packageId,--module, --resource, --all\"}</comment>\n  </data>\n  <data name=\"ConfigureExportCommandLongDescription\" xml:space=\"preserve\">\n    <value>將設定資源匯出至組態檔。搭配 --all 使用時，導出所有封裝組態。搭配 --packageId 使用時，導出指定套件標識符的 WinGetPackage 資源。與 --module 和 --resource 搭配使用時，取得資源的設定，並將它匯出至組態檔。如果輸出組態檔已存在，會附加導出的設定資源。</value>\n    <comment>{Locked=\"WinGetPackage,--packageId,--module, --resource\"}</comment>\n  </data>\n  <data name=\"ConfigureExportCommandShortDescription\" xml:space=\"preserve\">\n    <value>將設定資源匯出至設定檔。</value>\n  </data>\n  <data name=\"ConfigureExportModule\" xml:space=\"preserve\">\n    <value>要匯出之資源的模組。</value>\n  </data>\n  <data name=\"ConfigureExportPackageId\" xml:space=\"preserve\">\n    <value>要匯出的套件識別碼。</value>\n  </data>\n  <data name=\"ConfigureExportResource\" xml:space=\"preserve\">\n    <value>要匯出的設定資源。</value>\n  </data>\n  <data name=\"ConfigureExportAll\" xml:space=\"preserve\">\n    <value>匯出所有套件設定。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_GET_FAILED\" xml:space=\"preserve\">\n    <value>設定單位無法取得其屬性。</value>\n  </data>\n  <data name=\"ConfigurationExportFailed\" xml:space=\"preserve\">\n    <value>無法匯出設定。</value>\n  </data>\n  <data name=\"ConfigureExportUnitDescription\" xml:space=\"preserve\">\n    <value>設定 {0}</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigureExportUnitInstallDescription\" xml:space=\"preserve\">\n    <value>安裝 {0}</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationWarningSetViewTruncated\" xml:space=\"preserve\">\n    <value>組態檔中存在的部分數據已針對此輸出截斷;檢查檔案內容以取得完整內容。</value>\n  </data>\n  <data name=\"ConfigurationWarningValueTruncated\" xml:space=\"preserve\">\n    <value>&lt;此值已被截斷; 檢查檔案內容以取得完整的文字&gt;</value>\n    <comment>Keep some form of separator like the \"&lt;&gt;\" around the text so that it stands out from the preceding text.</comment>\n  </data>\n  <data name=\"ConfigureListCommandLongDescription\" xml:space=\"preserve\">\n    <value>顯示已套用至系統之設定的高層級詳細數據。此數據可與 `configure` 命令搭配使用，以取得更多詳細數據。</value>\n    <comment>{Locked=\"`configure`\"}</comment>\n  </data>\n  <data name=\"ConfigureListCommandShortDescription\" xml:space=\"preserve\">\n    <value>顯示設定歷程記錄</value>\n  </data>\n  <data name=\"ConfigurationHistoryEmpty\" xml:space=\"preserve\">\n    <value>歷程記錄中沒有設定。</value>\n  </data>\n  <data name=\"ConfigurationHistoryItemArgumentDescription\" xml:space=\"preserve\">\n    <value>從歷程記錄選取項目</value>\n  </data>\n  <data name=\"ConfigurationHistoryItemNotFound\" xml:space=\"preserve\">\n    <value>找不到符合所提供數據的單一設定。提供明確符合所需設定的完整名稱或標識碼的一部分。</value>\n  </data>\n  <data name=\"ConfigurationHistoryRemoveArgumentDescription\" xml:space=\"preserve\">\n    <value>從歷程記錄中移除項目</value>\n  </data>\n  <data name=\"ConfigureListFirstApplied\" xml:space=\"preserve\">\n    <value>首次套用</value>\n    <comment>Column header for date values indicating when a configuration was first applied to the system.</comment>\n  </data>\n  <data name=\"ConfigureListIdentifier\" xml:space=\"preserve\">\n    <value>識別碼</value>\n  </data>\n  <data name=\"ConfigureListName\" xml:space=\"preserve\">\n    <value>名稱</value>\n  </data>\n  <data name=\"ConfigureListOrigin\" xml:space=\"preserve\">\n    <value>來源</value>\n  </data>\n  <data name=\"ConfigureListPath\" xml:space=\"preserve\">\n    <value>路徑</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_HISTORY_ITEM_NOT_FOUND\" xml:space=\"preserve\">\n    <value>找不到指定的設定。</value>\n  </data>\n  <data name=\"ConfigurationSetStateCompleted\" xml:space=\"preserve\">\n    <value>已完成</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStateInProgress\" xml:space=\"preserve\">\n    <value>進行中</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStatePending\" xml:space=\"preserve\">\n    <value>擱置中</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationSetStateUnknown\" xml:space=\"preserve\">\n    <value>未知</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationStatusWatchArgumentDescription\" xml:space=\"preserve\">\n    <value>監視設定狀態。</value>\n    <comment>As in \"to monitor the status of a configuration being applied\".</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateCompleted\" xml:space=\"preserve\">\n    <value>已完成</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateInProgress\" xml:space=\"preserve\">\n    <value>進行中</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStatePending\" xml:space=\"preserve\">\n    <value>擱置中</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateSkipped\" xml:space=\"preserve\">\n    <value>已略過</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigurationUnitStateUnknown\" xml:space=\"preserve\">\n    <value>未知</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigureListApplyBegun\" xml:space=\"preserve\">\n    <value>已啟動套用</value>\n    <comment>When the configuration application started.</comment>\n  </data>\n  <data name=\"ConfigureListApplyEnded\" xml:space=\"preserve\">\n    <value>已結束套用</value>\n    <comment>When the configuration application ended.</comment>\n  </data>\n  <data name=\"ConfigureListResult\" xml:space=\"preserve\">\n    <value>結果</value>\n  </data>\n  <data name=\"ConfigureListResultDescription\" xml:space=\"preserve\">\n    <value>詳細資料</value>\n  </data>\n  <data name=\"ConfigureListState\" xml:space=\"preserve\">\n    <value>狀態</value>\n    <comment>The state of processing an item.</comment>\n  </data>\n  <data name=\"ConfigureListUnit\" xml:space=\"preserve\">\n    <value>單位</value>\n  </data>\n  <data name=\"StoreInstall_PackageNotAvailableForCurrentSystem\" xml:space=\"preserve\">\n    <value>套件與目前的 Windows 版本或平台不相容。</value>\n  </data>\n  <data name=\"ConfigurationSuppressPrologueArgumentDescription\" xml:space=\"preserve\">\n    <value>盡可能隱藏顯示初始設定詳細資料</value>\n  </data>\n  <data name=\"MSStoreDownloadMultiplePackagesNotice\" xml:space=\"preserve\">\n    <value>可能會下載多個以不同平臺和架構為目標的Microsoft Store套件。--platform， --architecture 可以用來篩選封裝。</value>\n    <comment>{Locked=\"--platform--architecture\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadGetLicenseForbidden\" xml:space=\"preserve\">\n    <value>無法擷取Microsoft Store套件授權。Microsoft Entra標識子帳戶不是全域管理員、用戶系統管理員或授權管理員的成員。使用 --skip-license 略過擷取Microsoft Store套件授權。</value>\n    <comment>{Locked=\"Global Administrator,User Administrator,License Administrator,--skip-license\"}</comment>\n  </data>\n  <data name=\"MSStoreDownloadPackageDownloadNotSupported\" xml:space=\"preserve\">\n    <value>Microsoft Store套件不支持下載。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_SFSCLIENT_PACKAGE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>Microsoft Store套件不支持下載。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED_FORBIDDEN\" xml:space=\"preserve\">\n    <value>無法擷取Microsoft Store套件授權。Microsoft Entra識別子帳戶沒有所需的許可權。</value>\n  </data>\n  <data name=\"WINGET_CONFIG_ERROR_PARAMETER_INTEGRITY_BOUNDARY\" xml:space=\"preserve\">\n    <value>參數無法通過完整性邊界。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_ZERO_BYTE_FILE\" xml:space=\"preserve\">\n    <value>已下載零位元組安裝程式;請確認您的網路連線正常運作。</value>\n  </data>\n  <data name=\"InstallerZeroByteFile\" xml:space=\"preserve\">\n    <value>已下載零位元組安裝程式;請確認您的網路連線正常運作。</value>\n  </data>\n  <data name=\"FontCommandShortDescription\" xml:space=\"preserve\">\n    <value>管理字型</value>\n  </data>\n  <data name=\"FontCommandLongDescription\" xml:space=\"preserve\">\n    <value>使用子命令管理字型。可以安裝、升級或卸載類似封裝的字型。 </value>\n  </data>\n  <data name=\"FontFamily\" xml:space=\"preserve\">\n    <value>家庭</value>\n  </data>\n  <data name=\"FontFaces\" xml:space=\"preserve\">\n    <value>表情</value>\n    <comment>\"Faces\" represents the typeface of the font family such as 'Bold' or 'Italic'</comment>\n  </data>\n  <data name=\"FontFamilyNameArgumentDescription\" xml:space=\"preserve\">\n    <value>依家庭名稱篩選結果</value>\n  </data>\n  <data name=\"FontFace\" xml:space=\"preserve\">\n    <value>臉</value>\n    <comment>\"Face\" represents the typeface of a font family such as 'Bold' or 'Italic'</comment>\n  </data>\n  <data name=\"FontFilePaths\" xml:space=\"preserve\">\n    <value>路徑</value>\n  </data>\n  <data name=\"NoInstalledFontFound\" xml:space=\"preserve\">\n    <value>未找到符合輸入條件的已安裝字型。</value>\n  </data>\n  <data name=\"FontListCommandShortDescription\" xml:space=\"preserve\">\n    <value>列出安裝的字型</value>\n  </data>\n  <data name=\"FontListCommandLongDescription\" xml:space=\"preserve\">\n    <value>列出所有已安裝的字體、所有字體檔案或特定字體的完整詳細資訊。</value>\n  </data>\n  <data name=\"FontVersion\" xml:space=\"preserve\">\n    <value>版本</value>\n  </data>\n  <data name=\"ConfigurationModules\" xml:space=\"preserve\">\n    <value>設定模組</value>\n    <comment>PowerShell Modules that are used for the Configuration feature</comment>\n  </data>\n  <data name=\"InstallerDownloadRequiresAuthentication\" xml:space=\"preserve\">\n    <value>套件安裝程式需要驗證。必要時可能會顯示驗證提示。已驗證的資訊將會與安裝程序下載 URL 共用。</value>\n  </data>\n  <data name=\"InstallerDownloadAuthenticationNotSupported\" xml:space=\"preserve\">\n    <value>無法下載安裝程式。此 winget 版本不支援安裝程式下載驗證方法。嘗試升級至最新 winget 版本。</value>\n    <comment>{Locked=\"winget\"}</comment>\n  </data>\n  <data name=\"InstallerDownloadAuthenticationFailed\" xml:space=\"preserve\">\n    <value>無法下載安裝程式。驗證失敗。</value>\n  </data>\n  <data name=\"ConfigurationProcessorPath\" xml:space=\"preserve\">\n    <value>指定設定處理器的路徑</value>\n  </data>\n  <data name=\"DscCommandShortDescription\" xml:space=\"preserve\">\n    <value>DSC v3 資源命令</value>\n    <comment>DSC stands for \"Desired State Configuration\". It should already have a locked translation.</comment>\n  </data>\n  <data name=\"DscCommandLongDescription\" xml:space=\"preserve\">\n    <value>這裡的子命令實作 Desired State Configuration (DSC) v3 資源，以設定 winget 和封裝。</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionGet\" xml:space=\"preserve\">\n    <value>取得資源狀態</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionSet\" xml:space=\"preserve\">\n    <value>設定資源狀態</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionWhatIf\" xml:space=\"preserve\">\n    <value>描述必要的狀態變更</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionTest\" xml:space=\"preserve\">\n    <value>測試資源狀態</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionDelete\" xml:space=\"preserve\">\n    <value>刪除資源狀態</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionExport\" xml:space=\"preserve\">\n    <value>取得所有狀態執行個體</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionValidate\" xml:space=\"preserve\">\n    <value>驗證群組內容</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionResolve\" xml:space=\"preserve\">\n    <value>解決外部狀態</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionAdapter\" xml:space=\"preserve\">\n    <value>執行配接器</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionSchema\" xml:space=\"preserve\">\n    <value>取得資源結構描述</value>\n  </data>\n  <data name=\"DscResourceFunctionDescriptionManifest\" xml:space=\"preserve\">\n    <value>取得資源資訊清單</value>\n  </data>\n  <data name=\"DscPackageResourceShortDescription\" xml:space=\"preserve\">\n    <value>管理套件狀態</value>\n  </data>\n  <data name=\"DscPackageResourceLongDescription\" xml:space=\"preserve\">\n    <value>透過 winget 管理套件。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionExist\" xml:space=\"preserve\">\n    <value>指出實例是否應存在。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionInDesiredState\" xml:space=\"preserve\">\n    <value>指出實例是否處於預期狀態。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageId\" xml:space=\"preserve\">\n    <value>套件的識別碼。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageSource\" xml:space=\"preserve\">\n    <value>套件的來源。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageVersion\" xml:space=\"preserve\">\n    <value>套件版本。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageMatchOption\" xml:space=\"preserve\">\n    <value>用來比對標識碼與封裝的方法。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageUseLatest\" xml:space=\"preserve\">\n    <value>指示應安裝最新可用的套件版本。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageInstallMode\" xml:space=\"preserve\">\n    <value>必要時要使用的安裝模式。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionPackageScope\" xml:space=\"preserve\">\n    <value>套件的目標範圍。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionAcceptAgreements\" xml:space=\"preserve\">\n    <value>指出是否接受來源和套件的合約。</value>\n  </data>\n  <data name=\"DscUserSettingsFileShortDescription\" xml:space=\"preserve\">\n    <value>管理使用者設定檔案</value>\n  </data>\n  <data name=\"DscUserSettingsFileLongDescription\" xml:space=\"preserve\">\n    <value>管理 winget 的使用者設定。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionUserSettingsFileSettings\" xml:space=\"preserve\">\n    <value>設定 JSON 檔案內容。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionUserSettingsFileAction\" xml:space=\"preserve\">\n    <value>用來套用設定的動作。</value>\n  </data>\n  <data name=\"CorrelationArgumentDescription\" xml:space=\"preserve\">\n    <value>已記錄相互關聯的值</value>\n  </data>\n  <data name=\"DscSourceResourceShortDescription\" xml:space=\"preserve\">\n    <value>管理來源設定</value>\n  </data>\n  <data name=\"DscSourceResourceLongDescription\" xml:space=\"preserve\">\n    <value>管理 winget 的來源。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceName\" xml:space=\"preserve\">\n    <value>要用於來源的名稱。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceArgument\" xml:space=\"preserve\">\n    <value>來源的引數。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceType\" xml:space=\"preserve\">\n    <value>來源的類型。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceTrustLevel\" xml:space=\"preserve\">\n    <value>來源的信任層級。</value>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionSourceExplicit\" xml:space=\"preserve\">\n    <value>呼叫未指定來源時是否包含來源。</value>\n  </data>\n  <data name=\"ConfigurationApplyingUnit\" xml:space=\"preserve\">\n    <value>正在套用設定單位...</value>\n  </data>\n  <data name=\"ConfigurationExportingUnit\" xml:space=\"preserve\">\n    <value>正在匯出設定單位...</value>\n  </data>\n  <data name=\"ConfigurationGettingUnitProcessors\" xml:space=\"preserve\">\n    <value>正在取得設定單位處理器...</value>\n  </data>\n  <data name=\"ConfigurationExportInstallRequiredModule\" xml:space=\"preserve\">\n    <value>請確認匯出所需的模組[{0}]</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportInstallRequiredModuleFailed\" xml:space=\"preserve\">\n    <value>無法測試或取得必要的模組。將不會匯出相關設定。</value>\n  </data>\n  <data name=\"ConfigurationExportUnitStart\" xml:space=\"preserve\">\n    <value>匯出[{0}]</value>\n    <comment>{Locked=\"{0}\"}</comment>\n  </data>\n  <data name=\"ConfigurationExportUnitFailed\" xml:space=\"preserve\">\n    <value>無法匯出資源。</value>\n  </data>\n  <data name=\"ConfigurationExportFailedToGetUnitProcessors\" xml:space=\"preserve\">\n    <value>無法取得單元處理器。將不會匯出個別套件設定。</value>\n  </data>\n  <data name=\"OutputDirectoryArgumentDescription\" xml:space=\"preserve\">\n    <value>要寫入結果的目錄</value>\n  </data>\n  <data name=\"ConfigurationInstallDscPackage\" xml:space=\"preserve\">\n    <value>在系統上找不到 Desired State Configuration 封裝。正在安裝套件...</value>\n  </data>\n  <data name=\"ConfigurationInstallDscPackageFailed\" xml:space=\"preserve\">\n    <value>無法安裝 Desired State Configuration 封裝。手動安裝套件，或透過 --processor-path 自變數提供 dsc.exe 路徑。</value>\n    <comment>{Locked=\"dsc.exe\",\"--processor-path\"}</comment>\n  </data>\n  <data name=\"DscResourcePropertyDescriptionAdminSettingsSettings\" xml:space=\"preserve\">\n    <value>包含系統管理員設定及其值的物件。</value>\n  </data>\n  <data name=\"DscAdminSettingsResourceShortDescription\" xml:space=\"preserve\">\n    <value>管理系統管理員設定</value>\n  </data>\n  <data name=\"DscAdminSettingsResourceLongDescription\" xml:space=\"preserve\">\n    <value>管理 winget 的系統管理員設定。</value>\n  </data>\n  <data name=\"ResetAllAdminSettingsArgumentDescription\" xml:space=\"preserve\">\n    <value>重設所有系統管理員設定</value>\n  </data>\n  <data name=\"ResetAllAdminSettingsSucceeded\" xml:space=\"preserve\">\n    <value>已重設所有系統管理員設定。</value>\n  </data>\n  <data name=\"McpCommandShortDescription\" xml:space=\"preserve\">\n    <value>MCP 資訊</value>\n    <comment>MCP stands for Model Context Protocol and should probably remain as-is</comment>\n  </data>\n  <data name=\"McpCommandLongDescription\" xml:space=\"preserve\">\n    <value>MCP (模型內容通訊協定) Windows 封裝管理員的資訊。</value>\n  </data>\n  <data name=\"McpConfigurationPreamble\" xml:space=\"preserve\">\n    <value>若要使用 MCP 用戶端手動設定 Windows 封裝管理員 MCP 伺服器，請在 `servers` 物件中使用下列 JSON 片段：</value>\n    <comment>{Locked=\"`servers`\"}\nMCP stands for Model Context Protocol and should probably remain as-is.\nAn unlocalized JSON fragment will follow on another line.</comment>\n  </data>\n  <data name=\"PolicyEnableMcpServer\" xml:space=\"preserve\">\n    <value>啟用 Windows 封裝管理員 MCP 伺服器</value>\n  </data>\n  <data name=\"OSVersionDescription\" xml:space=\"preserve\">\n    <value>目標作業系統版本</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_INSTALL_FAILED\" xml:space=\"preserve\">\n    <value>無法安裝一或多種字型。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_SUPPORTED\" xml:space=\"preserve\">\n    <value>不支援字型檔案，無法安裝。</value>\n  </data>\n  <data name=\"FontFileNotSupported\" xml:space=\"preserve\">\n    <value>字型套件中的一或多個字型不受支援，無法安裝。</value>\n  </data>\n  <data name=\"FontInstallFailed\" xml:space=\"preserve\">\n    <value>字型安裝失敗；正在清除。</value>\n  </data>\n  <data name=\"FontAlreadyInstalled\" xml:space=\"preserve\">\n    <value>已安裝字型。</value>\n  </data>\n  <data name=\"FontPackage\" xml:space=\"preserve\">\n    <value>套件識別碼</value>\n  </data>\n  <data name=\"FontWinGetSupported\" xml:space=\"preserve\">\n    <value>支援 WinGet</value>\n  </data>\n  <data name=\"FontTitle\" xml:space=\"preserve\">\n    <value>標題</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_FOUND\" xml:space=\"preserve\">\n    <value>找不到字型檔案。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_UNINSTALL_FAILED\" xml:space=\"preserve\">\n    <value>字體解除安裝失敗。字型可能狀態不佳。重新啟動後嘗試解除安裝。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_VALIDATION_FAILED\" xml:space=\"preserve\">\n    <value>字型驗證失敗。</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_ROLLBACK_FAILED\" xml:space=\"preserve\">\n    <value>字型復原失敗。字型可能狀態不佳。重新啟動後嘗試解除安裝。</value>\n  </data>\n  <data name=\"FontDetailsArgumentDescription\" xml:space=\"preserve\">\n    <value>顯示字型檔案詳細資訊。</value>\n  </data>\n  <data name=\"FontValidationFailed\" xml:space=\"preserve\">\n    <value>字型套件驗證失敗。</value>\n  </data>\n  <data name=\"FontRollbackFailed\" xml:space=\"preserve\">\n    <value>嘗試復原失敗的字型安裝失敗。可能需要重新啟動才能成功卸載字體。</value>\n  </data>\n  <data name=\"FontUninstallFailed\" xml:space=\"preserve\">\n    <value>字型套件解除安裝失敗。這通常是由於系統或應用程式正在使用字型。重新啟動電腦後卸載可能會成功。</value>\n  </data>\n  <data name=\"FontStatusOK\" xml:space=\"preserve\">\n    <value>確定</value>\n    <comment>\"OK\" means the font is in a good healthy state</comment>\n  </data>\n  <data name=\"FontStatusCorrupt\" xml:space=\"preserve\">\n    <value>損毀</value>\n    <comment>\"Corrupt\" refers to an install that is in a corrupted or bad state, and needs repair.</comment>\n  </data>\n  <data name=\"FontStatus\" xml:space=\"preserve\">\n    <value>狀態</value>\n  </data>\n  <data name=\"FontStatusUnknown\" xml:space=\"preserve\">\n    <value>未知</value>\n  </data>\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_ALREADY_INSTALLED\" xml:space=\"preserve\">\n    <value>已安裝字型套件。</value>\n  </data>\n  <data name=\"ListDetailsArgumentDescription\" xml:space=\"preserve\">\n    <value>顯示套件的詳細資訊</value>\n    <comment>Providing this argument causes the CLI to output additional details about installed application packages.</comment>\n  </data>\n  <data name=\"ShowLabelChannel\" xml:space=\"preserve\">\n    <value>管道:</value>\n    <comment>Precedes a string value that names the delivery channel for the software package (ex. stable, beta).</comment>\n  </data>\n  <data name=\"ShowListLocalIdentifier\" xml:space=\"preserve\">\n    <value>本機識別碼:</value>\n    <comment>Precedes a value that is the unique identifier for the installed package on the local system.</comment>\n  </data>\n  <data name=\"ShowListPackageFamilyName\" xml:space=\"preserve\">\n    <value>套件系列名稱:</value>\n    <comment>Precedes a value that is the APPX/MSIX package family name of the installed package.</comment>\n  </data>\n  <data name=\"ShowListProductCode\" xml:space=\"preserve\">\n    <value>產品碼:</value>\n    <comment>Precedes a value that is the Add/Remove Programs identifier in the registry. This is also the Product Code value as defined in MSI installers.</comment>\n  </data>\n  <data name=\"ShowListUpgradeCode\" xml:space=\"preserve\">\n    <value>升級代碼:</value>\n    <comment>Precedes a value that is the MSI Upgrade Code for the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledScope\" xml:space=\"preserve\">\n    <value>已安裝範圍:</value>\n    <comment>Precedes a value that is the scope of the installation of the package (ex. user, machine).</comment>\n  </data>\n  <data name=\"ShowListInstalledArchitecture\" xml:space=\"preserve\">\n    <value>安裝結構:</value>\n    <comment>Precedes a value that is the installed architecture of the package (ex. x86, x64, ARM64).</comment>\n  </data>\n  <data name=\"ShowListInstalledLocale\" xml:space=\"preserve\">\n    <value>安裝地區設定:</value>\n    <comment>Precedes a value that is the locale of the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledLocation\" xml:space=\"preserve\">\n    <value>安裝位置:</value>\n    <comment>Precedes a value that is the directory path to the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstalledSource\" xml:space=\"preserve\">\n    <value>原始來源:</value>\n    <comment>Precedes a value that names the package source where the installed package originated from.</comment>\n  </data>\n  <data name=\"ShowListAvailableUpgrades\" xml:space=\"preserve\">\n    <value>可用的升級:</value>\n    <comment>Precedes a list of package upgrades available for the installed package.</comment>\n  </data>\n  <data name=\"ShowListInstallerCategory\" xml:space=\"preserve\">\n    <value>安裝程式類別:</value>\n    <comment>Precedes a value that indicates the category of the installer for the installed package (ex. exe, msi, msix).</comment>\n  </data>\n  <data name=\"SourceEditOldValue\" xml:space=\"preserve\">\n    <value>舊值</value>\n    <comment>Column title for listing edit changes.</comment>\n  </data>\n  <data name=\"SourceEditNewValue\" xml:space=\"preserve\">\n    <value>新值</value>\n    <comment>Column title for listing the new value.</comment>\n  </data>\n</root>"
  },
  {
    "path": "Localization/Settings/LocConfig.xml",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Modules>\r\n  <Module\r\n    name=\"Microsoft.Windows.WinGet\"\r\n    tdbuildteamid=\"8343\">\r\n    <File\r\n      location=\"Microsoft.Windows.WinGet\"\r\n      path=\"%TFS_SOURCESDIRECTORY%\\src\\AppInstallerCLIPackage\\Shared\\Strings\\en-us\\winget.resw\" />\r\n  </Module>\r\n</Modules>\r\n"
  },
  {
    "path": "NOTICE",
    "content": "NOTICES AND INFORMATION\r\nDo Not Translate or Localize\r\n\r\nThis software incorporates material from third parties.\r\nMicrosoft makes certain open source code available at https://3rdpartysource.microsoft.com,\r\nor you may send a check or money order for US $5.00, including the product name,\r\nthe open source component name, platform, and version number, to:\r\n\r\nSource Code Compliance Team\r\nMicrosoft Corporation\r\nOne Microsoft Way\r\nRedmond, WA 98052\r\nUSA\r\n\r\nNotwithstanding any other terms, you may reverse engineer this software to the extent\r\nrequired to debug changes to any libraries licensed under the GNU Lesser General Public License.\r\n\r\n---------------------------------------------------------\r\n\r\nCastle.Core 5.1.0 - Apache-2.0\r\n\r\n\r\n(c) 2004-2022 Castle Project - http://www.castleproject.org\r\nCopyright 2004-2021 Castle Project - http://www.castleproject.org\r\nCopyright (c) 2004-2022 Castle Project - http://www.castleproject.org\r\n\r\nCopyright 2004-2021 Castle Project - http://www.castleproject.org/\r\n\r\nLicensed under the Apache License, Version 2.0 (the \"License\");\r\nyou may not use this file except in compliance with the License.\r\nYou may obtain a copy of the License at\r\n\r\n     http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nUnless required by applicable law or agreed to in writing, software\r\ndistributed under the License is distributed on an \"AS IS\" BASIS,\r\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\nSee the License for the specific language governing permissions and\r\nlimitations under the License.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nNuGet.Frameworks 5.11.0 - Apache-2.0\r\n\r\n\r\n(c) Microsoft Corporation.\r\n\r\nApache License\r\n\r\nVersion 2.0, January 2004\r\n\r\nhttp://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r\n\r\n   1. Definitions.\r\n\r\n      \r\n\r\n      \"License\" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.\r\n\r\n      \r\n\r\n      \"Licensor\" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.\r\n\r\n      \r\n\r\n      \"Legal Entity\" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, \"control\" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.\r\n\r\n      \r\n\r\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity exercising permissions granted by this License.\r\n\r\n      \r\n\r\n      \"Source\" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.\r\n\r\n      \r\n\r\n      \"Object\" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.\r\n\r\n      \r\n\r\n      \"Work\" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).\r\n\r\n      \r\n\r\n      \"Derivative Works\" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.\r\n\r\n      \r\n\r\n      \"Contribution\" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, \"submitted\" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as \"Not a Contribution.\"\r\n\r\n      \r\n\r\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.\r\n\r\n   2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.\r\n\r\n   3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.\r\n\r\n   4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:\r\n\r\n      (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and\r\n\r\n      (b) You must cause any modified files to carry prominent notices stating that You changed the files; and\r\n\r\n      (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and\r\n\r\n      (d) If the Work includes a \"NOTICE\" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.\r\n\r\n      You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.\r\n\r\n   5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.\r\n\r\n   6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.\r\n\r\n   7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.\r\n\r\n   8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.\r\n\r\n   9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS\r\n\r\nAPPENDIX: How to apply the Apache License to your work.\r\n\r\nTo apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets \"[]\" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same \"printed page\" as the copyright notice for easier identification within third-party archives.\r\n\r\nCopyright [yyyy] [name of copyright owner]\r\n\r\nLicensed under the Apache License, Version 2.0 (the \"License\");\r\n\r\nyou may not use this file except in compliance with the License.\r\n\r\nYou may obtain a copy of the License at\r\n\r\nhttp://www.apache.org/licenses/LICENSE-2.0\r\n\r\nUnless required by applicable law or agreed to in writing, software\r\n\r\ndistributed under the License is distributed on an \"AS IS\" BASIS,\r\n\r\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n\r\nSee the License for the specific language governing permissions and\r\n\r\nlimitations under the License.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nopenssl/openssl 01d5e2318405362b4de5e670c90d9b40a351d053 - Apache-2.0\r\n\r\n\r\n(c) 2005 WISeKey SA1\r\nCopyright 2005 Nokia\r\nCopyright 2021 UnionTech\r\nCopyright 2021- IBM Inc.\r\nCopyright IBM Corp. 2018\r\nCopyright IBM Corp. 2019\r\nCopyright Nokia 2007-2018\r\nCopyright Nokia 2007-2019\r\nCopyright Nokia 2007-2020\r\nCopyright Siemens AG 2020\r\nCopyright 2011 Google Inc.\r\nCopyright 2017 Ribose Inc.\r\n(c) 2013 ATT Wi-Fi Services\r\nCopyright 2017 BaishanCloud\r\nCopyright 2013 M. J. Dominus\r\nCopyright 2019 Red Hat, Inc.\r\nCopyright IBM Corp. 2018-2019\r\nCopyright Patrick Powell 1995\r\nCopyright (c) 2011, RTFM, Inc.\r\nCopyright Siemens AG 2015-2019\r\nCopyright Siemens AG 2015-2020\r\nCopyright Siemens AG 2015-2022\r\nCopyright Siemens AG 2018-2020\r\nCopyright Siemens AG 2019-2022\r\nCopyright 2016 VMS Software, Inc.\r\nCopyright (c) 2004, EdelKey Project\r\nCopyright (c) 2015 CloudFlare, Inc.\r\nCopyright (c) 2015, CloudFlare, Inc.\r\nCopyright (c) 2005 WISeKey SA1 InterU\r\nCopyright (c) 2012, Intel Corporation\r\nCopyright (c) 2014, Intel Corporation\r\nCopyright (c) 2020, Intel Corporation\r\nCopyright (c) 2021, Intel Corporation\r\nCopyright (c) 2002 The OpenTSA Project\r\nCopyright 1998-$YEAR The OpenSSL Authors\r\nCopyright 2004-2014, Akamai Technologies\r\nCopyright 2023The OpenSSL Project Authors\r\nCopyright (c) 2020-2021, Intel Corporation\r\nCopyright 2014 Cryptography Research, Inc.\r\nCopyright 2015 Cryptography Research, Inc.\r\nCopyright 2016 Cryptography Research, Inc.\r\nCopyright 2016 The OpenSSL Project Authors\r\nCopyright 2017 The OpenSSL Project Authors\r\nCopyright 2018 The OpenSSL Project Authors\r\nCopyright 2019 The OpenSSL Project Authors\r\nCopyright 2020 The OpenSSL Project Authors\r\nCopyright 2021 The OpenSSL Project Authors\r\nCopyright 2022 The OpenSSL Project Authors\r\nCopyright 2023 The OpenSSL Project Authors\r\nCopyright (c) 1998-2023 The OpenSSL Project\r\nCopyright (c) 2006, Network Resonance, Inc.\r\nCopyright (c) 2012-2014 Daniel J. Bernstein\r\ncopyrighted by the Free Software Foundation\r\nCopyright (c) 2012-2016 Jean-Philippe Aumasson\r\nCopyright 1995-2016 The OpenSSL Project Authors\r\nCopyright 1995-2017 The OpenSSL Project Authors\r\nCopyright 1995-2018 The OpenSSL Project Authors\r\nCopyright 1995-2019 The OpenSSL Project Authors\r\nCopyright 1995-2020 The OpenSSL Project Authors\r\nCopyright 1995-2021 The OpenSSL Project Authors\r\nCopyright 1995-2022 The OpenSSL Project Authors\r\nCopyright 1995-2023 The OpenSSL Project Authors\r\nCopyright 1998-2016 The OpenSSL Project Authors\r\nCopyright 1998-2017 The OpenSSL Project Authors\r\nCopyright 1998-2020 The OpenSSL Project Authors\r\nCopyright 1998-2021 The OpenSSL Project Authors\r\nCopyright 1998-2022 The OpenSSL Project Authors\r\nCopyright 1998-2023 The OpenSSL Project Authors\r\nCopyright 1999-2016 The OpenSSL Project Authors\r\nCopyright 1999-2018 The OpenSSL Project Authors\r\nCopyright 1999-2020 The OpenSSL Project Authors\r\nCopyright 1999-2021 The OpenSSL Project Authors\r\nCopyright 1999-2022 The OpenSSL Project Authors\r\nCopyright 1999-2023 The OpenSSL Project Authors\r\nCopyright 2000-2016 The OpenSSL Project Authors\r\nCopyright 2000-2017 The OpenSSL Project Authors\r\nCopyright 2000-2018 The OpenSSL Project Authors\r\nCopyright 2000-2019 The OpenSSL Project Authors\r\nCopyright 2000-2020 The OpenSSL Project Authors\r\nCopyright 2000-2021 The OpenSSL Project Authors\r\nCopyright 2000-2022 The OpenSSL Project Authors\r\nCopyright 2000-2023 The OpenSSL Project Authors\r\nCopyright 2001-2016 The OpenSSL Project Authors\r\nCopyright 2001-2017 The OpenSSL Project Authors\r\nCopyright 2001-2018 The OpenSSL Project Authors\r\nCopyright 2001-2020 The OpenSSL Project Authors\r\nCopyright 2001-2021 The OpenSSL Project Authors\r\nCopyright 2001-2022 The OpenSSL Project Authors\r\nCopyright 2001-2023 The OpenSSL Project Authors\r\nCopyright 2002-2016 The OpenSSL Project Authors\r\nCopyright 2002-2018 The OpenSSL Project Authors\r\nCopyright 2002-2020 The OpenSSL Project Authors\r\nCopyright 2002-2021 The OpenSSL Project Authors\r\nCopyright 2002-2022 The OpenSSL Project Authors\r\nCopyright 2002-2023 The OpenSSL Project Authors\r\nCopyright 2003-2021 The OpenSSL Project Authors\r\nCopyright 2003-2022 The OpenSSL Project Authors\r\nCopyright 2003-2023 The OpenSSL Project Authors\r\nCopyright 2004-2016 The OpenSSL Project Authors\r\nCopyright 2004-2017 The OpenSSL Project Authors\r\nCopyright 2004-2018 The OpenSSL Project Authors\r\nCopyright 2004-2020 The OpenSSL Project Authors\r\nCopyright 2004-2021 The OpenSSL Project Authors\r\nCopyright 2004-2022 The OpenSSL Project Authors\r\nCopyright 2004-2023 The OpenSSL Project Authors\r\nCopyright 2005-2016 The OpenSSL Project Authors\r\nCopyright 2005-2018 The OpenSSL Project Authors\r\nCopyright 2005-2020 The OpenSSL Project Authors\r\nCopyright 2005-2021 The OpenSSL Project Authors\r\nCopyright 2005-2022 The OpenSSL Project Authors\r\nCopyright 2005-2023 The OpenSSL Project Authors\r\nCopyright 2006-2016 The OpenSSL Project Authors\r\nCopyright 2006-2017 The OpenSSL Project Authors\r\nCopyright 2006-2018 The OpenSSL Project Authors\r\nCopyright 2006-2020 The OpenSSL Project Authors\r\nCopyright 2006-2021 The OpenSSL Project Authors\r\nCopyright 2006-2022 The OpenSSL Project Authors\r\nCopyright 2006-2023 The OpenSSL Project Authors\r\nCopyright 2007-2016 The OpenSSL Project Authors\r\nCopyright 2007-2018 The OpenSSL Project Authors\r\nCopyright 2007-2019 The OpenSSL Project Authors\r\nCopyright 2007-2020 The OpenSSL Project Authors\r\nCopyright 2007-2021 The OpenSSL Project Authors\r\nCopyright 2007-2022 The OpenSSL Project Authors\r\nCopyright 2007-2023 The OpenSSL Project Authors\r\nCopyright 2008-2016 The OpenSSL Project Authors\r\nCopyright 2008-2018 The OpenSSL Project Authors\r\nCopyright 2008-2020 The OpenSSL Project Authors\r\nCopyright 2008-2021 The OpenSSL Project Authors\r\nCopyright 2008-2022 The OpenSSL Project Authors\r\nCopyright 2008-2023 The OpenSSL Project Authors\r\nCopyright 2009-2020 The OpenSSL Project Authors\r\nCopyright 2009-2021 The OpenSSL Project Authors\r\nCopyright 2009-2022 The OpenSSL Project Authors\r\nCopyright 2009-2023 The OpenSSL Project Authors\r\nCopyright 2010-2016 The OpenSSL Project Authors\r\nCopyright 2010-2020 The OpenSSL Project Authors\r\nCopyright 2010-2021 The OpenSSL Project Authors\r\nCopyright 2010-2022 The OpenSSL Project Authors\r\nCopyright 2010-2023 The OpenSSL Project Authors\r\nCopyright 2011-2016 The OpenSSL Project Authors\r\nCopyright 2011-2020 The OpenSSL Project Authors\r\nCopyright 2011-2021 The OpenSSL Project Authors\r\nCopyright 2011-2022 The OpenSSL Project Authors\r\nCopyright 2011-2023 The OpenSSL Project Authors\r\nCopyright 2012, Samuel Neves <sneves@dei.uc.pt>\r\nCopyright 2012-2016 The OpenSSL Project Authors\r\nCopyright 2012-2020 The OpenSSL Project Authors\r\nCopyright 2012-2021 The OpenSSL Project Authors\r\nCopyright 2012-2022 The OpenSSL Project Authors\r\nCopyright 2012-2023 The OpenSSL Project Authors\r\nCopyright 2013-2017 The OpenSSL Project Authors\r\nCopyright 2013-2018 The OpenSSL Project Authors\r\nCopyright 2013-2020 The OpenSSL Project Authors\r\nCopyright 2013-2021 The OpenSSL Project Authors\r\nCopyright 2013-2022 The OpenSSL Project Authors\r\nCopyright 2013-2023 The OpenSSL Project Authors\r\nCopyright 2014-2016 Cryptography Research, Inc.\r\nCopyright 2014-2016 The OpenSSL Project Authors\r\nCopyright 2014-2017 The OpenSSL Project Authors\r\nCopyright 2014-2018 The OpenSSL Project Authors\r\nCopyright 2014-2020 The OpenSSL Project Authors\r\nCopyright 2014-2021 The OpenSSL Project Authors\r\nCopyright 2014-2022 The OpenSSL Project Authors\r\nCopyright 2014-2023 The OpenSSL Project Authors\r\nCopyright 2015-2016 Cryptography Research, Inc.\r\nCopyright 2015-2016 The OpenSSL Project Authors\r\nCopyright 2015-2017 The OpenSSL Project Authors\r\nCopyright 2015-2018 The OpenSSL Project Authors\r\nCopyright 2015-2020 The OpenSSL Project Authors\r\nCopyright 2015-2021 The OpenSSL Project Authors\r\nCopyright 2015-2022 The OpenSSL Project Authors\r\nCopyright 2015-2023 The OpenSSL Project Authors\r\nCopyright 2016-2016 The OpenSSL Project Authors\r\nCopyright 2016-2017 The OpenSSL Project Authors\r\nCopyright 2016-2018 The OpenSSL Project Authors\r\nCopyright 2016-2019 The OpenSSL Project Authors\r\nCopyright 2016-2020 The OpenSSL Project Authors\r\nCopyright 2016-2021 The OpenSSL Project Authors\r\nCopyright 2016-2022 The OpenSSL Project Authors\r\nCopyright 2016-2023 The OpenSSL Project Authors\r\nCopyright 2017-2018 The OpenSSL Project Authors\r\nCopyright 2017-2019 The OpenSSL Project Authors\r\nCopyright 2017-2020 The OpenSSL Project Authors\r\nCopyright 2017-2021 The OpenSSL Project Authors\r\nCopyright 2017-2022 The OpenSSL Project Authors\r\nCopyright 2017-2023 The OpenSSL Project Authors\r\nCopyright 2018-2019 The OpenSSL Project Authors\r\nCopyright 2018-2020 The OpenSSL Project Authors\r\nCopyright 2018-2021 The OpenSSL Project Authors\r\nCopyright 2018-2022 The OpenSSL Project Authors\r\nCopyright 2018-2023 The OpenSSL Project Authors\r\nCopyright 2019-2020 The OpenSSL Project Authors\r\nCopyright 2019-2021 The OpenSSL Project Authors\r\nCopyright 2019-2022 The OpenSSL Project Authors\r\nCopyright 2019-2023 The OpenSSL Project Authors\r\nCopyright 2020-2021 The OpenSSL Project Authors\r\nCopyright 2020-2022 The OpenSSL Project Authors\r\nCopyright 2020-2023 The OpenSSL Project Authors\r\nCopyright 2021-2022 The OpenSSL Project Authors\r\nCopyright 2021-2023 The OpenSSL Project Authors\r\nCopyright 2022-2023 The OpenSSL Project Authors\r\nCopyright 20xx-20yy The OpenSSL Project Authors\r\nCopyright (c) 2002, Oracle and/or its affiliates\r\nCopyright (c) 2017, Oracle and/or its affiliates\r\nCopyright (c) 2018, Oracle and/or its affiliates\r\nCopyright (c) 2019, Oracle and/or its affiliates\r\nCopyright 1995-$YEAR The OpenSSL Project Authors\r\nCopyright 1998-$YEAR The OpenSSL Project Authors\r\nCopyright 1999-$YEAR The OpenSSL Project Authors\r\nCopyright 2000-$YEAR The OpenSSL Project Authors\r\nCopyright 2020-$YEAR The OpenSSL Project Authors\r\nCopyright (c) 1989 Free Software Foundation, Inc.\r\nCopyright 2017 Ribose Inc. (https://www.ribose.com)\r\nCopyright (c) 1995-1998 Eric A. Young, Tim J. Hudson\r\nCopyright (c) 2008 Andy Polyakov <appro@openssl.org>\r\nCopyright 2021 UnionTech (https://www.uniontech.com)\r\nCopyright (c) 2018-2019, Oracle and/or its affiliates\r\nCopyright (c) 2018-2020, Oracle and/or its affiliates\r\nCopyright (c) 2019-2020, Oracle and/or its affiliates\r\nCopyright (c) 2013 by Mark Jason Dominus <mjd@cpan.org>\r\nCopyright (c) 2017 National Security Research Institute\r\ncopyright (c) 2013 by Mark Jason Dominus <mjd@cpan.org>\r\nCopyright (c) 2004, Richard Levitte <richard@levitte.org>\r\nCopyright (c) 2013-2014 Timo Teras <timo.teras@gmail.com>\r\nCopyright (c) 2007 KISA(Korea Information Security Agency)\r\nCopyright (c) 2004, 2018, Richard Levitte <richard@levitte.org>\r\nCopyright (c) 2016 Viktor Dukhovni <openssl-users@dukhovni.org>\r\nCopyright 2006 NTT (Nippon Telegraph and Telephone Corporation)\r\nCopyright (c) 2005 WISeKey SA1 Internat(onal1)0 WISeKey CertifyID Advanced G1 CA0\r\nCopyright (c) 2005 WISeKey SA1 International1 0 WISeKey CertifyID Advanced G1 CA0\r\nCopyright (c) 2004 Kungliga Tekniska Hogskolan (Royal Institute of Technology, Stockholm, Sweden)\r\n\r\n\r\n                                 Apache License\r\n                           Version 2.0, January 2004\r\n                        https://www.apache.org/licenses/\r\n\r\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r\n\r\n   1. Definitions.\r\n\r\n      \"License\" shall mean the terms and conditions for use, reproduction,\r\n      and distribution as defined by Sections 1 through 9 of this document.\r\n\r\n      \"Licensor\" shall mean the copyright owner or entity authorized by\r\n      the copyright owner that is granting the License.\r\n\r\n      \"Legal Entity\" shall mean the union of the acting entity and all\r\n      other entities that control, are controlled by, or are under common\r\n      control with that entity. For the purposes of this definition,\r\n      \"control\" means (i) the power, direct or indirect, to cause the\r\n      direction or management of such entity, whether by contract or\r\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\r\n      outstanding shares, or (iii) beneficial ownership of such entity.\r\n\r\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\r\n      exercising permissions granted by this License.\r\n\r\n      \"Source\" form shall mean the preferred form for making modifications,\r\n      including but not limited to software source code, documentation\r\n      source, and configuration files.\r\n\r\n      \"Object\" form shall mean any form resulting from mechanical\r\n      transformation or translation of a Source form, including but\r\n      not limited to compiled object code, generated documentation,\r\n      and conversions to other media types.\r\n\r\n      \"Work\" shall mean the work of authorship, whether in Source or\r\n      Object form, made available under the License, as indicated by a\r\n      copyright notice that is included in or attached to the work\r\n      (an example is provided in the Appendix below).\r\n\r\n      \"Derivative Works\" shall mean any work, whether in Source or Object\r\n      form, that is based on (or derived from) the Work and for which the\r\n      editorial revisions, annotations, elaborations, or other modifications\r\n      represent, as a whole, an original work of authorship. For the purposes\r\n      of this License, Derivative Works shall not include works that remain\r\n      separable from, or merely link (or bind by name) to the interfaces of,\r\n      the Work and Derivative Works thereof.\r\n\r\n      \"Contribution\" shall mean any work of authorship, including\r\n      the original version of the Work and any modifications or additions\r\n      to that Work or Derivative Works thereof, that is intentionally\r\n      submitted to Licensor for inclusion in the Work by the copyright owner\r\n      or by an individual or Legal Entity authorized to submit on behalf of\r\n      the copyright owner. For the purposes of this definition, \"submitted\"\r\n      means any form of electronic, verbal, or written communication sent\r\n      to the Licensor or its representatives, including but not limited to\r\n      communication on electronic mailing lists, source code control systems,\r\n      and issue tracking systems that are managed by, or on behalf of, the\r\n      Licensor for the purpose of discussing and improving the Work, but\r\n      excluding communication that is conspicuously marked or otherwise\r\n      designated in writing by the copyright owner as \"Not a Contribution.\"\r\n\r\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\r\n      on behalf of whom a Contribution has been received by Licensor and\r\n      subsequently incorporated within the Work.\r\n\r\n   2. Grant of Copyright License. Subject to the terms and conditions of\r\n      this License, each Contributor hereby grants to You a perpetual,\r\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r\n      copyright license to reproduce, prepare Derivative Works of,\r\n      publicly display, publicly perform, sublicense, and distribute the\r\n      Work and such Derivative Works in Source or Object form.\r\n\r\n   3. Grant of Patent License. Subject to the terms and conditions of\r\n      this License, each Contributor hereby grants to You a perpetual,\r\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r\n      (except as stated in this section) patent license to make, have made,\r\n      use, offer to sell, sell, import, and otherwise transfer the Work,\r\n      where such license applies only to those patent claims licensable\r\n      by such Contributor that are necessarily infringed by their\r\n      Contribution(s) alone or by combination of their Contribution(s)\r\n      with the Work to which such Contribution(s) was submitted. If You\r\n      institute patent litigation against any entity (including a\r\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\r\n      or a Contribution incorporated within the Work constitutes direct\r\n      or contributory patent infringement, then any patent licenses\r\n      granted to You under this License for that Work shall terminate\r\n      as of the date such litigation is filed.\r\n\r\n   4. Redistribution. You may reproduce and distribute copies of the\r\n      Work or Derivative Works thereof in any medium, with or without\r\n      modifications, and in Source or Object form, provided that You\r\n      meet the following conditions:\r\n\r\n      (a) You must give any other recipients of the Work or\r\n          Derivative Works a copy of this License; and\r\n\r\n      (b) You must cause any modified files to carry prominent notices\r\n          stating that You changed the files; and\r\n\r\n      (c) You must retain, in the Source form of any Derivative Works\r\n          that You distribute, all copyright, patent, trademark, and\r\n          attribution notices from the Source form of the Work,\r\n          excluding those notices that do not pertain to any part of\r\n          the Derivative Works; and\r\n\r\n      (d) If the Work includes a \"NOTICE\" text file as part of its\r\n          distribution, then any Derivative Works that You distribute must\r\n          include a readable copy of the attribution notices contained\r\n          within such NOTICE file, excluding those notices that do not\r\n          pertain to any part of the Derivative Works, in at least one\r\n          of the following places: within a NOTICE text file distributed\r\n          as part of the Derivative Works; within the Source form or\r\n          documentation, if provided along with the Derivative Works; or,\r\n          within a display generated by the Derivative Works, if and\r\n          wherever such third-party notices normally appear. The contents\r\n          of the NOTICE file are for informational purposes only and\r\n          do not modify the License. You may add Your own attribution\r\n          notices within Derivative Works that You distribute, alongside\r\n          or as an addendum to the NOTICE text from the Work, provided\r\n          that such additional attribution notices cannot be construed\r\n          as modifying the License.\r\n\r\n      You may add Your own copyright statement to Your modifications and\r\n      may provide additional or different license terms and conditions\r\n      for use, reproduction, or distribution of Your modifications, or\r\n      for any such Derivative Works as a whole, provided Your use,\r\n      reproduction, and distribution of the Work otherwise complies with\r\n      the conditions stated in this License.\r\n\r\n   5. Submission of Contributions. Unless You explicitly state otherwise,\r\n      any Contribution intentionally submitted for inclusion in the Work\r\n      by You to the Licensor shall be under the terms and conditions of\r\n      this License, without any additional terms or conditions.\r\n      Notwithstanding the above, nothing herein shall supersede or modify\r\n      the terms of any separate license agreement you may have executed\r\n      with Licensor regarding such Contributions.\r\n\r\n   6. Trademarks. This License does not grant permission to use the trade\r\n      names, trademarks, service marks, or product names of the Licensor,\r\n      except as required for reasonable and customary use in describing the\r\n      origin of the Work and reproducing the content of the NOTICE file.\r\n\r\n   7. Disclaimer of Warranty. Unless required by applicable law or\r\n      agreed to in writing, Licensor provides the Work (and each\r\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\r\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r\n      implied, including, without limitation, any warranties or conditions\r\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r\n      PARTICULAR PURPOSE. You are solely responsible for determining the\r\n      appropriateness of using or redistributing the Work and assume any\r\n      risks associated with Your exercise of permissions under this License.\r\n\r\n   8. Limitation of Liability. In no event and under no legal theory,\r\n      whether in tort (including negligence), contract, or otherwise,\r\n      unless required by applicable law (such as deliberate and grossly\r\n      negligent acts) or agreed to in writing, shall any Contributor be\r\n      liable to You for damages, including any direct, indirect, special,\r\n      incidental, or consequential damages of any character arising as a\r\n      result of this License or out of the use or inability to use the\r\n      Work (including but not limited to damages for loss of goodwill,\r\n      work stoppage, computer failure or malfunction, or any and all\r\n      other commercial damages or losses), even if such Contributor\r\n      has been advised of the possibility of such damages.\r\n\r\n   9. Accepting Warranty or Additional Liability. While redistributing\r\n      the Work or Derivative Works thereof, You may choose to offer,\r\n      and charge a fee for, acceptance of support, warranty, indemnity,\r\n      or other liability obligations and/or rights consistent with this\r\n      License. However, in accepting such obligations, You may act only\r\n      on Your own behalf and on Your sole responsibility, not on behalf\r\n      of any other Contributor, and only if You agree to indemnify,\r\n      defend, and hold each Contributor harmless for any liability\r\n      incurred by, or claims asserted against, such Contributor by reason\r\n      of your accepting any such warranty or additional liability.\r\n\r\n   END OF TERMS AND CONDITIONS\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nStyleCop.Analyzers 1.1.118 - Apache-2.0 AND MIT\r\n\r\n\r\ncopyright company\r\nPlaceholderCompany Copyright (c)\r\nCopyright (c) 2015 Dennis Fischer\r\nCopyright (c) 2017 Marcos Lopez C.\r\nCopyright 2014 Giovanni Bassi and Elemar Jr\r\nCopyright (c) Tunnel Vision Laboratories, LLC.\r\nCopyright Tunnel Vision Laboratories, LLC 2015\r\ncopyright tag should contain a non-empty company\r\nCopyright 2015 Tunnel Vision Laboratories, LLC StyleCop DotNetAnalyzers Roslyn Diagnostic\r\n\r\n﻿Copyright (c) Tunnel Vision Laboratories, LLC. All rights reserved.\r\n\r\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use\r\nthese files except in compliance with the License. You may obtain a copy of the\r\nLicense at\r\n\r\nhttp://www.apache.org/licenses/LICENSE-2.0\r\n\r\nUnless required by applicable law or agreed to in writing, software distributed\r\nunder the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\r\nCONDITIONS OF ANY KIND, either express or implied. See the License for the\r\nspecific language governing permissions and limitations under the License.\r\n\r\n---\r\n\r\nThis project uses other open source projects, which are used under the terms\r\nof the following license(s).\r\n\r\n.NET Compiler Platform (\"Roslyn\")\r\n\r\n  Copyright Microsoft.\r\n\r\n  Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\r\n  these files except in compliance with the License. You may obtain a copy of the\r\n  License at\r\n\r\n  http://www.apache.org/licenses/LICENSE-2.0\r\n\r\n  Unless required by applicable law or agreed to in writing, software distributed\r\n  under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\r\n  CONDITIONS OF ANY KIND, either express or implied. See the License for the\r\n  specific language governing permissions and limitations under the License.\r\n\r\nCode Cracker\r\n\r\n  Copyright 2014 Giovanni Bassi and Elemar Jr.\r\n\r\n  Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\r\n  these files except in compliance with the License. You may obtain a copy of the\r\n  License at\r\n\r\n  http://www.apache.org/licenses/LICENSE-2.0\r\n\r\n  Unless required by applicable law or agreed to in writing, software distributed\r\n  under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\r\n  CONDITIONS OF ANY KIND, either express or implied. See the License for the\r\n  specific language governing permissions and limitations under the License.\r\n\r\nLightJson\r\n\r\n  Copyright (c) 2017 Marcos López C.\r\n  \r\n  Permission is hereby granted, free of charge, to any person obtaining a copy\r\n  of this software and associated documentation files (the \"Software\"), to deal\r\n  in the Software without restriction, including without limitation the rights\r\n  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n  copies of the Software, and to permit persons to whom the Software is\r\n  furnished to do so, subject to the following conditions:\r\n  \r\n  The above copyright notice and this permission notice shall be included in\r\n  all copies or substantial portions of the Software.\r\n  \r\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n  THE SOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMarkdig.Signed 0.33.0 - BSD-2-Clause\r\n\r\n\r\n\r\nCopyright (c) <year> <owner> . All rights reserved.\r\n\r\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\r\n\r\n   1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\r\n\r\n   2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\r\n\r\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Web.WebView2 1.0.3485.44 - BSD-3-Clause\r\n\r\n\r\n(c) MEE.\r\n(c) (c) S\r\n(c) Gyw A\r\n(c) Ono Q\r\n(c) 3Y Thaeh\r\n(c) Dyma (c)\r\n(c) Microsoft 2025\r\n(c) Microsoft Corporation\r\nCopyright Sam Harwell 2011\r\nCopyright Microsoft Corporation\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2011 The ANTLR Project\r\n\r\nCopyright (C) Microsoft Corporation. All rights reserved.\r\n\r\nRedistribution and use in source and binary forms, with or without\r\nmodification, are permitted provided that the following conditions are\r\nmet:\r\n\r\n   * Redistributions of source code must retain the above copyright\r\nnotice, this list of conditions and the following disclaimer.\r\n   * Redistributions in binary form must reproduce the above\r\ncopyright notice, this list of conditions and the following disclaimer\r\nin the documentation and/or other materials provided with the\r\ndistribution.\r\n   * The name of Microsoft Corporation, or the names of its contributors \r\nmay not be used to endorse or promote products derived from this\r\nsoftware without specific prior written permission.\r\n\r\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMoq 4.18.2 - BSD-3-Clause\r\n\r\n\r\nCopyright (c) 2007, Clarius Consulting, Manas Technology Solutions, InSTEDD, and Contributors\r\n\r\nCopyright (c) <year> <owner> . All rights reserved.\r\n\r\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\r\n\r\n   1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\r\n\r\n   2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\r\n\r\n   3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\r\n\r\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\ncurl/curl 83bedbd730d62b83744cc26fa0433d3f6e2e4cd6 - BSD-3-Clause AND BSD-4-Clause-UC AND ISC AND curl\r\n\r\n\r\nCopyright (C) David Shaw\r\nCopyright (C) Howard Chu\r\nCopyright (C) Max Dymond\r\n(c) ! ISCNTRL (c) ISSPACE\r\nCopyright (C) Jeroen Ooms\r\nCopyright (C) Mark Gaiser\r\nCopyright (c) Evgeny Grin\r\nDaniel Stenberg, , et al.\r\nCopyright (C) Dan Fandrich\r\nCopyright (C) Dorian Craps\r\nCopyright (C) Jan Venekamp\r\nCopyright (c) Dan Fandrich\r\nCopyright (C) Dmitry Karpov\r\nCopyright (C) Jay Satiro, .\r\nCopyright (C) John Malmberg\r\nCopyright (C) Red Hat, Inc.\r\nCopyright (c) John Malmberg\r\nCopyright (c) Red Hat, Inc.\r\ncopyright When contributing\r\nCopyright (C) Björn Stenberg\r\nCopyright (C) Michael Forney\r\nCopyright (C) Steve Holme, .\r\nCopyright (C) Viktor Szakats\r\nCopyright (c) Viktor Szakats\r\nCopyright (C) Daniel Stenberg\r\nCopyright (c) Daniel Fandrich\r\nCopyright (c) Daniel Stenberg\r\nCopyright (C) Nicolas Sterchele\r\nCopyright (C) \" CURL_COPYRIGHT \"\\0\"\r\nCopyright (C) Jacob Hoffman-Andrews\r\nCopyright (C) 2006-2022 wolfSSL Inc.\r\nCopyright (C) James Fuller, , et al.\r\nCopyright (C) Linus Nielsen Feltzing\r\nCopyright (c) 2001 Alexander Peslyak\r\nCopyright (c) 2006-2022 wolfSSL Inc.\r\nCopyright (C) Daniel Fandrich, et al.\r\nCopyright (C) Vijay Panghal, , et al.\r\nCopyright (C) \" LIBCURL_COPYRIGHT \"\\0\"\r\nCopyright (C) Daniel Fandrich, , et al.\r\nCopyright (C) Daniel Stenberg, , et al.\r\nCopyright (C) Simon Josefsson, , et al.\r\nCopyright (C) Evgeny Grin (Karlson2k), .\r\n2022 Free Software Foundation Europe e.V.\r\nCopyright (c) Internet Software Consortium.\r\nCopyright Daniel Stenberg, <daniel@haxx.se>\r\nCopyright (c) Howard Chu, <hyc@openldap.org>\r\nCopyright (c) Mandy Wu, <mandy.wu@intel.com>\r\nCopyright (C) Bill Nagel , Exacq Technologies\r\nCopyright (c) Bjorn Stenberg, <bjorn@haxx.se>\r\nCopyright (c) Jan Venekamp, <jan@venekamp.net>\r\nCopyright (c) Mark Gaiser, <markg85@gmail.com>\r\nCopyright (c) Daniel Stenberg, <daniel@haxx.se>\r\nCopyright (c) Howard Chu, <hyc@highlandsun.com>\r\nCopyright (c) Jay Satiro, <raysatiro@yahoo.com>\r\nCopyright (c) David Shaw <dshaw@jabberwocky.com>\r\nCopyright (c) Jeroen Ooms <jeroenooms@gmail.com>\r\nCopyright (c) Hoi-Ho Chan, <hoiho.chan@gmail.com>\r\nCopyright (c) Nick Zitzmann, <nickzman@gmail.com>\r\nCopyright (C) EdelWeb for EdelKey and OpenEvidence\r\nCopyright (c) EdelWeb for EdelKey and OpenEvidence\r\nCopyright (c) James Fuller, <jim@webcomposite.com>\r\nCopyright (c) Dmitry Karpov <dkarpov1970@gmail.com>\r\nCopyright (c) Michael Forney, <mforney@mforney.org>\r\nCopyright (c) 1996-2022 Internet Software Consortium\r\nCopyright (c) 1998, 1999 Kungliga Tekniska Hogskolan\r\nCopyright (c) Linus Nielsen Feltzing <linus@haxx.se>\r\nCopyright (c) Marc Hoersken, <info@marc-hoersken.de>\r\nCopyright (c) Max Dymond, <max.dymond@microsoft.com>\r\nCopyright (c) Simon Josefsson, <simon@josefsson.org>\r\nCopyright (c) Steve Holme, <steve_holme@hotmail.com>\r\nCopyright (C) 1996-2022 Internet Software Consortium.\r\nCopyright (c) Linus Nielsen Feltzing, <linus@haxx.se>\r\nCopyright (c) Mark Salisbury, <mark.salisbury@hp.com>\r\nCopyright (c) Vijay Panghal, <vpanghal@maginatics.com>\r\nCopyright (c) 2001-2004 Damien Miller <djm@openbsd.org>\r\nCopyright (c) Daniel Fandrich, <dan@coneharvesters.com>\r\nCopyright (c) Florin Petriuc, <petriuc.florin@gmail.com>\r\nCopyright (c) Nicolas Sterchele, <nicolas@sterchelen.net>\r\nCopyright (c) 1983, Regents of the University of California\r\nCopyright (c) Dorian Craps, <dorian.craps@student.vinci.be>\r\nCopyright (c) Markus Moeller, <markus_moeller@compuserve.com>\r\nCopyright (c) Jacob Hoffman-Andrews, <github@hoffman-andrews.com>\r\nCopyright (c) Bill Nagel <wnagel@tycoint.com> , Exacq Technologies\r\nCopyright various years The Regents of the University of California\r\nCopyright (C) Daniel Stenberg et al. OS/400 version by P. Monnerat\")'\r\nCopyright 2022 Free Software Foundation Europe e.V. <https://fsfe.org>\r\nCopyright (c) Daniel Stenberg, <daniel@haxx.se> , and many contributors\r\nCopyright (c) 1996 - 2024, Daniel Stenberg, <daniel@haxx.se> , and many contributors\r\nCopyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Hogskolan (Royal Institute of Technology, Stockholm, Sweden)\r\n\r\nCOPYRIGHT AND PERMISSION NOTICE\r\n\r\nCopyright (c) 1996 - 2024, Daniel Stenberg, <daniel@haxx.se>, and many\r\ncontributors, see the THANKS file.\r\n\r\nAll rights reserved.\r\n\r\nPermission to use, copy, modify, and distribute this software for any purpose\r\nwith or without fee is hereby granted, provided that the above copyright\r\nnotice and this permission notice appear in all copies.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN\r\nNO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\r\nDAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\r\nOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE\r\nOR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\nExcept as contained in this notice, the name of a copyright holder shall not\r\nbe used in advertising or otherwise to promote the sale, use or other dealings\r\nin this Software without prior written authorization of the copyright holder.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nc-ares/c-ares fddf01938d3789e06cc1c3774e4cd0c7d2a89976 - HPND\r\n\r\n\r\nCopyright 2008 Google Inc.\r\nCopyright 2005, Google Inc.\r\nCopyright 2006, Google Inc.\r\nCopyright 2007, Google Inc.\r\nCopyright 2008, Google Inc.\r\nCopyright 2013, Google Inc.\r\nCopyright 2015, Google Inc.\r\nCopyright (c) 2012 Xan Lopez\r\nCopyright (c) 2021 Permission\r\nCopyright (c) 2012 Dan Winship\r\nCopyright 2005 Dominick Meglio\r\nCopyright (c) 2012 Paolo Borelli\r\nCopyright (c) 2021 by Brad House\r\nCopyright 1998 by Daniel Stenberg\r\nCopyright 2004 by Daniel Stenberg\r\nCopyright 2005 by Dominick Meglio\r\nCopyright (c) 2012 Christian Persch\r\nCopyright (c) 2017 by John Schember\r\nCopyright (c) 2014, 2015 Google Inc.\r\nCopyright (c) 2004 by Daniel Stenberg\r\nCopyright (c) 2005 by Dominick Meglio\r\nCopyright (c) 2008 by Daniel Stenberg\r\nCopyright (c) 2013 by Daniel Stenberg\r\nCopyright (c) 2016 by Daniel Stenberg\r\nCopyright (c) 2019 by Andrew Selivanov\r\nCopyright (c) 2012, 2016 Philip Withnall\r\nCopyright (c) 2015,2018 Bastien ROUCARIES\r\nCopyright (c) 2004-2009 by Daniel Stenberg\r\nCopyright (c) 2004-2010 by Daniel Stenberg\r\nCopyright (c) 2004-2011 by Daniel Stenberg\r\nCopyright (c) 2004-2017 by Daniel Stenberg\r\nCopyright (c) 2005 - 2010, Daniel Stenberg\r\nCopyright (c) 2005-2013 by Daniel Stenberg\r\nCopyright (c) 2007 - 2018, Daniel Stenberg\r\nCopyright (c) 2007-2013 by Daniel Stenberg\r\nCopyright (c) 2008-2010 by Daniel Stenberg\r\nCopyright (c) 2008-2013 by Daniel Stenberg\r\nCopyright (c) 2009-2013 by Daniel Stenberg\r\nCopyright (c) 2009-2021 by Daniel Stenberg\r\nCopyright (c) 2010-2012 by Daniel Stenberg\r\nCopyright (c) 2010-2013 by Daniel Stenberg\r\nCopyright (c) 2005, 2013 by Dominick Meglio\r\nCopyright (c) 2004 - 2011 by Daniel Stenberg\r\nCopyright (c) 2004 - 2012 by Daniel Stenberg\r\nCopyright (c) 2004 - 2013 by Daniel Stenberg\r\nCopyright (c) 2008 - 2009 by Daniel Stenberg\r\nCopyright (c) 2008 - 2012 by Daniel Stenberg\r\nCopyright (c) 2008 - 2013 by Daniel Stenberg\r\nCopyright (c) 2009 - 2021 by Daniel Stenberg\r\nCopyright (c) 2017 - 2018 by Christian Ammer\r\nCopyright (c) 2010 Jeremy Lal <kapouer@melix.org>\r\nCopyright (c) 2012 Marko Kreen <markokr@gmail.com>\r\nCopyright (c) 2012 Zack Weinberg <zackw@panix.com>\r\nCopyright (c) 2018 The Android Open Source Project\r\nCopyright 2020 by <danny.sonnenschein@platynum.ch>\r\nCopyright (c) 2011 Daniel Stenberg <daniel@haxx.se>\r\nCopyright (c) 2013 Daniel Stenberg <daniel@haxx.se>\r\nCopyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>\r\nCopyright (c) 1995, 1996, 1997, and 1998 WIDE Project\r\nCopyright (c) 2014 Mike Frysinger <vapier@gentoo.org>\r\nCopyright (c) 2008 Tom Howard <tomhoward@users.sf.net>\r\nCopyright (c) 2009 Tom Howard <tomhoward@users.sf.net>\r\nCopyright 2010 by Ben Greear <greearb@candelatech.com>\r\nCopyright 2020 Danny Sonnenschein <my.card.god@web.de>\r\nCopyright (c) 1996,1999 by Internet Software Consortium\r\nCopyright (c) 1996-1999 by Internet Software Consortium\r\nCopyright (c) 2004 by Internet Systems Consortium, Inc.\r\nCopyright (c) 2009 by Jakub Hrozek <jhrozek@redhat.com>\r\nCopyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>\r\nCopyright (c) 2009 Allan Caffee <allan.caffee@gmail.com>\r\nCopyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>\r\nCopyright (c) 2017 by John Schember <john@nachtimwald.com>\r\nCopyright (c) 2018 by John Schember <john@nachtimwald.com>\r\nCopyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>\r\nCopyright 1998 by the Massachusetts Institute of Technology\r\nCopyright 2000 by the Massachusetts Institute of Technology\r\nCopyright 1998, 2000 by the Massachusetts Institute of Technology\r\nCopyright 1998, 2011 by the Massachusetts Institute of Technology\r\nCopyright (c) 1987-2001 The Regents of the University of California\r\nCopyright (c) 2008 John Darrington <j.darrington@elvis.murdoch.edu.au>\r\nCopyright (c) 2015 Enrico M. Crisostomo <enrico.m.crisostomo@gmail.com>\r\nCopyright 1998, 2011, 2013 by the Massachusetts Institute of Technology\r\n\r\n# c-ares license\r\n\r\nCopyright (c) 2007 - 2018, Daniel Stenberg with many contributors, see AUTHORS\r\nfile.\r\n\r\nCopyright 1998 by the Massachusetts Institute of Technology.\r\n\r\nPermission to use, copy, modify, and distribute this software and its\r\ndocumentation for any purpose and without fee is hereby granted, provided that\r\nthe above copyright notice appear in all copies and that both that copyright\r\nnotice and this permission notice appear in supporting documentation, and that\r\nthe name of M.I.T. not be used in advertising or publicity pertaining to\r\ndistribution of the software without specific, written prior permission.\r\nM.I.T. makes no representations about the suitability of this software for any\r\npurpose.  It is provided \"as is\" without express or implied warranty.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nmicrosoft/xlang cfe510d0d2b07484fea2c6d77163de017738c100 - LicenseRef-scancode-generic-cla AND MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\nCopyright 2017 Two Blue Cubes Ltd.\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2019 Two Blue Cubes Ltd.\r\n\r\n    MIT License\r\n\r\n    Copyright (c) Microsoft Corporation. All rights reserved.\r\n\r\n    Permission is hereby granted, free of charge, to any person obtaining a copy\r\n    of this software and associated documentation files (the \"Software\"), to deal\r\n    in the Software without restriction, including without limitation the rights\r\n    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n    copies of the Software, and to permit persons to whom the Software is\r\n    furnished to do so, subject to the following conditions:\r\n\r\n    The above copyright notice and this permission notice shall be included in all\r\n    copies or substantial portions of the Software.\r\n\r\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n    SOFTWARE\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Windows.WDK.Win32Metadata 0.12.8-experimental - LicenseRef-scancode-ms-windows-sdk-win10-net-6\r\n\r\n\r\n(c) Microsoft 2024\r\n(c) Microsoft Corporation\r\n\r\nLicenseRef-scancode-ms-windows-sdk-win10-net-6\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\ncoverlet.collector 3.1.2 - MIT\r\n\r\n\r\nCopyright 2008 - 2018 Jb Evain\r\nCopyright Microsoft Corporation\r\nCopyright James Newton-King 2008\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nHumanizer.Core 2.14.1 - MIT\r\n\r\n\r\nCopyright .NET Foundation and Contributors\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nJson.More.Net 2.0.1.2 - MIT\r\n\r\n\r\nCopyright (c) 2024 Greg Dennis\r\n\r\nMIT License\r\n\r\nCopyright (c) 2024 Greg Dennis\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nJsonPointer.Net 5.0.0 - MIT\r\n\r\n\r\nCopyright (c) 2024 Greg Dennis\r\n\r\nMIT License\r\n\r\nCopyright (c) 2024 Greg Dennis\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nJsonSchema.Net 7.0.4 - MIT\r\n\r\n\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.ApplicationInsights 2.21.0 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Bcl.AsyncInterfaces 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.CodeAnalysis.Analyzers 3.3.4 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2013 Scott Kirkland\r\nCopyright (c) 2012-2014 Mehdi Khalili\r\nCopyright (c) 2013-2014 Omar Khudeira (http://omar.io)\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.CodeAnalysis.Common 4.9.2 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.CodeAnalysis.CSharp 4.9.2 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) Microsoft Corporation. Alle Rechte\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.AI.Abstractions 9.7.1 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.Configuration 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.Configuration.Abstractions 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.Configuration.Binder 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.Configuration.CommandLine 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.Configuration.EnvironmentVariables 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.Configuration.FileExtensions 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.Configuration.Json 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.Configuration.UserSecrets 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.DependencyInjection 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.DependencyInjection.Abstractions 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.Diagnostics 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.Diagnostics.Abstractions 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.FileProviders.Abstractions 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.FileProviders.Physical 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.FileSystemGlobbing 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.Hosting 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.Hosting.Abstractions 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.Logging 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.Logging.Abstractions 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.Logging.Configuration 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.Logging.Console 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.Logging.Debug 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.Logging.EventLog 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.Logging.EventSource 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.ObjectPool 8.0.10 - MIT\r\n\r\n\r\nCopyright Jorn Zaefferer\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright (c) 2015, Google Inc.\r\nCopyright (c) 2019 David Fowler\r\nCopyright (c) HTML5 Boilerplate\r\nCopyright 2019 The gRPC Authors\r\nCopyright (c) 2016 Richard Morris\r\nCopyright (c) 1998 John D. Polstra\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 2013 - 2018 AngleSharp\r\nCopyright (c) 2000-2013 Julian Seward\r\nCopyright (c) 2011-2021 Twitter, Inc.\r\nCopyright (c) 2014-2018 Michael Daines\r\nCopyright (c) 1996-1998 John D. Polstra\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2011-2021 The Bootstrap Authors\r\nCopyright (c) 2019-2023 The Bootstrap Authors\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2019-2020 West Wind Technologies\r\nCopyright (c) 2007 John Birrell (jb@freebsd.org)\r\nCopyright (c) 2011 Alex MacCaw (info@eribium.org)\r\nCopyright (c) Nicolas Gallagher and Jonathan Neal\r\nCopyright (c) 2010-2019 Google LLC. http://angular.io/license\r\nCopyright (c) 2011 Nicolas Gallagher (nicolas@nicolasgallagher.com)\r\nCopyright (c) 1989, 1993 The Regents of the University of California\r\nCopyright (c) 1990, 1993 The Regents of the University of California\r\nCopyright OpenJS Foundation and other contributors, https://openjsf.org\r\nCopyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.Options 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.Options.ConfigurationExtensions 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Extensions.Primitives 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Management.Infrastructure 3.0.0 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Management.Infrastructure.CimCmdlets 7.4.6 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\n(c) Microsoft Corporation. CPowerShell's Microsoft.Management.Infrastructure.CimCmdlets project\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Management.Infrastructure.Runtime.Unix 3.0.0 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Msix.Utils 2.1.1 - MIT\r\n\r\n\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.NET.ILLink.Tasks 8.0.20 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright 2008 - 2018 Jb Evain\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.NETCore.Platforms 5.0.0 - MIT\r\n\r\n\r\n(c) Microsoft Corporation.\r\nCopyright (c) Andrew Arnott\r\nCopyright 2018 Daniel Lemire\r\nCopyright 2012 the V8 project\r\nCopyright (c) .NET Foundation.\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 1998 Microsoft. To\r\n(c) 1997-2005 Sean Eron Anderson.\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 2012-2014, Yann Collet\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2018 Alexander Chermyanin\r\nPortions (c) International Organization\r\nCopyright (c) 2015 The Chromium Authors.\r\nCopyright (c) The Internet Society 1997.\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) The Internet Society (2003).\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California.\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass.\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass. To\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.PowerShell.Commands.Diagnostics 7.4.6 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\n(c) Microsoft Corporation. PowerShell's Microsoft.PowerShell.Commands.Diagnostics project\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.PowerShell.Commands.Management 7.4.6 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\n(c) Microsoft Corporation. PowerShell's Microsoft.PowerShell.Commands.Management project\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.PowerShell.Commands.Utility 7.4.6 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\n(c) Microsoft Corporation. :PowerShell's Microsoft.PowerShell.Commands.Utility project\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.PowerShell.ConsoleHost 7.4.6 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\n(c) Microsoft Corporation. PowerShell Host\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.PowerShell.CoreCLR.Eventing 7.4.6 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\n(c) Microsoft Corporation. :PowerShell's Microsoft.PowerShell.CoreCLR.Eventing project\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.PowerShell.MarkdownRender 7.2.1 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\n(c) Microsoft Corporation. PowerShell's Markdown Rendering project PowerShell Markdown Renderer\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.PowerShell.Native 7.4.0 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\nCopyright (c) by P.J. Plauger\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.PowerShell.SDK 7.4.6 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\nCopyright (c) Microsoft Corporation\r\n(c) Microsoft Corporation. PowerShell SDK\r\n(c) Microsoft Corporation. PowerShell Host\r\n(c) Microsoft Corporation. 1PowerShell's System.Management.Automation project\r\n(c) Microsoft Corporation. :PowerShell's Microsoft.PowerShell.Commands.Utility project\r\n(c) Microsoft Corporation. PowerShell's Microsoft.PowerShell.Commands.Management project\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.PowerShell.Security 7.4.6 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\n(c) Microsoft Corporation. 2PowerShell's Microsoft.PowerShell.Security project\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Security.Extensions 1.2.0 - MIT\r\n\r\n\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Win32.Registry 4.7.0 - MIT\r\n\r\n\r\n(c) Microsoft Corporation.\r\nCopyright (c) .NET Foundation.\r\nCopyright (c) 2011, Google Inc.\r\n(c) 1997-2005 Sean Eron Anderson.\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2017 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nPortions (c) International Organization\r\nCopyright (c) 2015 The Chromium Authors.\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Win32.Registry 5.0.0 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 2012-2014, Yann Collet\r\nCopyright (c) 1991-2020 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass. To\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Win32.Registry.AccessControl 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Win32.SystemEvents 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Win32.SystemEvents 9.0.0-preview.6.24327.7 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Windows.Compatibility 8.0.10 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Windows.CppWinRT 2.0.210503.1 - MIT\r\n\r\n\r\n(c) Microsoft Corporation.\r\nCopyright (c) Microsoft Corporation.\r\n\r\n    MIT License\r\n\r\n    Copyright (c) Microsoft Corporation.\r\n\r\n    Permission is hereby granted, free of charge, to any person obtaining a copy\r\n    of this software and associated documentation files (the \"Software\"), to deal\r\n    in the Software without restriction, including without limitation the rights\r\n    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n    copies of the Software, and to permit persons to whom the Software is\r\n    furnished to do so, subject to the following conditions:\r\n\r\n    The above copyright notice and this permission notice shall be included in all\r\n    copies or substantial portions of the Software.\r\n\r\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n    SOFTWARE\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Windows.CppWinRT 2.0.240405.15 - MIT\r\n\r\n\r\n(c) Microsoft 2024\r\n(c) Microsoft Corporation\r\nCopyright (c) Microsoft Corporation\r\n\r\n    MIT License\r\n\r\n    Copyright (c) Microsoft Corporation.\r\n\r\n    Permission is hereby granted, free of charge, to any person obtaining a copy\r\n    of this software and associated documentation files (the \"Software\"), to deal\r\n    in the Software without restriction, including without limitation the rights\r\n    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n    copies of the Software, and to permit persons to whom the Software is\r\n    furnished to do so, subject to the following conditions:\r\n\r\n    The above copyright notice and this permission notice shall be included in all\r\n    copies or substantial portions of the Software.\r\n\r\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n    SOFTWARE\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Windows.CppWinRT 2.0.250303.1 - MIT\r\n\r\n\r\n(c) Microsoft 2025\r\n(c) Microsoft Corporation\r\nCopyright (c) Microsoft Corporation\r\n\r\n    MIT License\r\n\r\n    Copyright (c) Microsoft Corporation.\r\n\r\n    Permission is hereby granted, free of charge, to any person obtaining a copy\r\n    of this software and associated documentation files (the \"Software\"), to deal\r\n    in the Software without restriction, including without limitation the rights\r\n    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n    copies of the Software, and to permit persons to whom the Software is\r\n    furnished to do so, subject to the following conditions:\r\n\r\n    The above copyright notice and this permission notice shall be included in all\r\n    copies or substantial portions of the Software.\r\n\r\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n    SOFTWARE\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Windows.CsWin32 0.3.183 - MIT\r\n\r\n\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Windows.ImplementationLibrary 1.0.250325.1 - MIT\r\n\r\n\r\n(c) Microsoft 2025\r\nCopyright (c) Microsoft\r\n(c) Microsoft Corporation\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2009-2014 by the contributors\r\n\r\n    MIT License\r\n\r\n    Copyright (c) Microsoft Corporation. All rights reserved.\r\n\r\n    Permission is hereby granted, free of charge, to any person obtaining a copy\r\n    of this software and associated documentation files (the \"Software\"), to deal\r\n    in the Software without restriction, including without limitation the rights\r\n    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n    copies of the Software, and to permit persons to whom the Software is\r\n    furnished to do so, subject to the following conditions:\r\n\r\n    The above copyright notice and this permission notice shall be included in all\r\n    copies or substantial portions of the Software.\r\n\r\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n    SOFTWARE\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.WindowsPackageManager.ComInterop 1.8.1911 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.WSMan.Management 7.4.6 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\n(c) Microsoft Corporation. PowerShell's Microsoft.WSMan.Management project\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.WSMan.Runtime 7.4.6 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\n(c) Microsoft Corporation. ,PowerShell's Microsoft.WSMan.Runtime project\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nmicrosoft/correlationvector-cpp cf38d2b44baaf352509ad9980786bc49554c32e4 - MIT\r\n\r\n\r\nCopyright (c) Microsoft Corporation.\r\n\r\n    MIT License\r\n\r\n    Copyright (c) Microsoft Corporation. All rights reserved.\r\n\r\n    Permission is hereby granted, free of charge, to any person obtaining a copy\r\n    of this software and associated documentation files (the \"Software\"), to deal\r\n    in the Software without restriction, including without limitation the rights\r\n    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n    copies of the Software, and to permit persons to whom the Software is\r\n    furnished to do so, subject to the following conditions:\r\n\r\n    The above copyright notice and this permission notice shall be included in all\r\n    copies or substantial portions of the Software.\r\n\r\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n    SOFTWARE\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nmicrosoft/cpprestsdk 411a109150b270f23c8c97fa4ec9a0a4a98cdecf - MIT\r\n\r\n\r\nCopyright (c) Microsoft\r\nCopyright (c) 2014, Peter Thorson\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2011, Micael Hildenborg\r\nCopyright (c) 2004-2008 Rene Nyffenegger\r\nCopyright (c) 1999, 2002 Aladdin Enterprises\r\nPortions Copyright (c) Microsoft Corporation\r\nCopyright (c) 2006 Noel Llopis and Charles Nicholson\r\nCopyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>\r\n\r\nC++ REST SDK \r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) Microsoft Corporation\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of\r\nthis software and associated documentation files (the \"Software\"), to deal in\r\nthe Software without restriction, including without limitation the rights to\r\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r\nthe Software, and to permit persons to whom the Software is furnished to do so,\r\nsubject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nmicrosoft/sfs-client ff315ecfa2ef2953d8a808e51e8a61a4e0759180 - MIT\r\n\r\n\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2013-2022 Niels Lohmann\r\nCopyright (c) 2007 - 2023 Daniel Stenberg\r\nCopyright (c) 1998 Massachusetts Institute of Technology\r\nCopyright (c) 1996 - 2024, Daniel Stenberg, <daniel@haxx.se> , and many contributors\r\n\r\n    MIT License\r\n\r\n    Copyright (c) Microsoft Corporation.\r\n\r\n    Permission is hereby granted, free of charge, to any person obtaining a copy\r\n    of this software and associated documentation files (the \"Software\"), to deal\r\n    in the Software without restriction, including without limitation the rights\r\n    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n    copies of the Software, and to permit persons to whom the Software is\r\n    furnished to do so, subject to the following conditions:\r\n\r\n    The above copyright notice and this permission notice shall be included in all\r\n    copies or substantial portions of the Software.\r\n\r\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n    SOFTWARE\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nModelContextProtocol 0.3.0-preview.3 - MIT\r\n\r\n\r\n(c) Anthropic and Contributors\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nModelContextProtocol.Core 0.3.0-preview.3 - MIT\r\n\r\n\r\n(c) Anthropic and Contributors\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nNETStandard.Library 2.0.0 - MIT\r\n\r\n\r\ncopyright Unmanaged32Bit Required32Bit\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nNETStandard.Library 2.0.3 - MIT\r\n\r\n\r\ncopyright Unmanaged32Bit Required32Bit\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nNewtonsoft.Json 13.0.3 - MIT\r\n\r\n\r\nCopyright James Newton-King 2008\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) James Newton-King 2008\r\nCopyright James Newton-King 2008 Json.NET\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2007 James Newton-King\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of\r\nthis software and associated documentation files (the \"Software\"), to deal in\r\nthe Software without restriction, including without limitation the rights to\r\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r\nthe Software, and to permit persons to whom the Software is furnished to do so,\r\nsubject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nNewtonsoft.Json.Bson 1.0.1 - MIT\r\n\r\n\r\nCopyright James Newton-King 2017\r\nCopyright (c) James Newton-King 2017\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nnlohmann/json 9cca280a4d0ccf0c08f47a99aa71d1b0e52f8d03 - MIT\r\n\r\n\r\n(c) 2016\r\n2012 Erik Edlund\r\n2017 Georg Sauthoff\r\n2018 Vitaliy Manushkin\r\n2013-2022 Niels Lohmann\r\n2013-2023 Niels Lohmann\r\n2015-2017 Niels Lohmann\r\n2016-2021 Evan Nemerson\r\n2018 The Abseil Authors\r\n2003-2022, LLVM Project.\r\n2016-2021 Viktor Kirilov\r\n(c) 2013-2022 Niels Lohmann\r\nCopyright 2003-2022, LLVM Project\r\nCopyright 2015-2017 Niels Lohmann\r\nCopyright 2018 The Abseil Authors\r\nCopyright (c) 2009 Florian Loitsch\r\nCopyright 2016-2021 Viktor Kirilov\r\nCopyright (c) 2013-2022 Niels Lohmann\r\nCopyright (c) 2015-2017 Niels Lohmann\r\ncopyright (c) 2013-2022 Niels Lohmann\r\ncopyright (c) 2013-2023 Niels Lohmann\r\nCopyright (c) 2016-2023 Viktor Kirilov\r\nCopyright 2017 Georg Sauthoff <mail@gms.tf>\r\ncopyright Niels Lohmann <https://nlohmann.me>\r\nCopyright 2012 Erik Edlund <erik.edlund@32767.se>\r\nCopyright Copyright (c) 2013 - 2023 Niels Lohmann\r\nCopyright 2018 Vitaliy Manushkin <agri@akamo.info>\r\nCopyright 2016-2021 Evan Nemerson <evan@nemerson.com>\r\nCopyright (c) 2012, Erik Edlund <erik.edlund@32767.se>\r\nCopyright 2013-2022 Niels Lohmann <https://nlohmann.me>\r\nCopyright 2013-2023 Niels Lohmann <https://nlohmann.me>\r\nCopyright 2020 Hannes Domani <https://github.com/ssbssa>\r\nCopyright 2008-2009 Bjorn Hoehrmann <bjoern@hoehrmann.de>\r\nCopyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>\r\nCopyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>\r\nCopyright (c) 2013-2022 Niels Lohmann (https://nlohmann.me)\r\nCopyright (c) 2020 Hannes Domani (https://github.com/ssbssa)\r\nCopyright 2009 Florian Loitsch <https://florian.loitsch.com/>\r\nCopyright (c) 2009 Florian Loitsch (https://florian.loitsch.com/)\r\nCopyright (c) 2007 Free Software Foundation, Inc. <http://fsf.org/>\r\nCopyright (c) 2008-2009 Bjorn Hoehrmann (http://bjoern.hoehrmann.de/) <bjoern@hoehrmann.de>\r\nCopyright (c) 2008-2009 Bjorn Hoehrmann (https://bjoern.hoehrmann.de/) <bjoern@hoehrmann.de>\r\nCopyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de> @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa\r\n\r\nMIT License \r\n\r\nCopyright (c) 2013-2022 Niels Lohmann\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nNUnit 3.12.0 - MIT\r\n\r\n\r\n(c) Microsoft 2024\r\ncopyright in NUnit Console\r\n(c) 2019 Charlie Poole, Rob Prouse\r\nCopyright (c) 2002-2014 Charlie Poole\r\nCopyright (c) 2000-2002 Philip A. Craig\r\nCopyright (c) 2019 Charlie Poole, Rob Prouse\r\nCopyright (c) 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov\r\n\r\nCopyright (c) 2019 Charlie Poole, Rob Prouse\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nNUnit3TestAdapter 3.15.1 - MIT\r\n\r\n\r\n(c) Microsoft 2025\r\nCopyright 2008 - 2015 Jb Evain\r\nCopyright 2008 - 2018 Jb Evain\r\n(c) 2019 Charlie Poole, Rob Prouse\r\nCopyright (c) 2019 Charlie Poole, Rob Prouse\r\nCopyright 2011-2019 Charlie Poole, 2014-2019 Terje Sandstrom\r\nCopyright (c) 2011-2019 Charlie Poole, 2014-2019 Terje Sandstrom\r\n\r\nCopyright (c) 2011-2019 Charlie Poole, 2014-2019 Terje Sandstrom\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nOctokit 4.0.3 - MIT\r\n\r\n\r\nCopyright GitHub 2017\r\nCopyright GitHub 2017 GitHub API Octokit\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nPowerShellStandard.Library 5.1.1 - MIT\r\n\r\n\r\n(c) Microsoft Corporation.\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nronomon/pure fd54913e65338e678440ae66b3b5022ab23b761b - MIT\r\n\r\n\r\nCopyright (c) 2003 Mark Adler\r\nCopyright (c) 2020 Ronomon CC\r\nCopyright 1995-2017 Mark Adler\r\nCopyright (c) 2003 Cosmin Truta\r\nCopyright (c) 1990-2000 Info-ZIP.\r\nCopyright (c) 1998 by Bob Dellaca\r\nCopyright (c) 1995-2003 Mark Adler\r\nCopyright (c) 1995-2008 Mark Adler\r\nCopyright (c) 1995-2016 Mark Adler\r\nCopyright (c) 1995-2017 Mark Adler\r\nCopyright (c) 2002-2013 Mark Adler\r\nCopyright (c) 2003 by Cosmin Truta\r\nCopyright (c) 2003-2010 Mark Adler\r\nCopyright (c) 2004-2017 Mark Adler\r\nCopyright (c) 1996 L. Peter Deutsch\r\nCopyright (c) 1997,99 Borland Corp.\r\nCopyright (c) 2003, 2012 Mark Adler\r\nCopyright (c) 2004, 2005 Mark Adler\r\nCopyright (c) 2004, 2010 Mark Adler\r\nCopyright (c) 2005, 2012 Mark Adler\r\nCopyright (c) 2011, 2016 Mark Adler\r\nCopyright (c) 2007-2008 Even Rouault\r\nCopyright (c) 1998-2005 Gilles Vollant\r\nCopyright (c) 2004, 2005 by Mark Adler\r\nCopyright (c) 1995-1998 Jean-loup Gailly\r\nCopyright (c) 1995-2003 Jean-loup Gailly\r\nCopyright (c) 1995-2003, 2010 Mark Adler\r\nCopyright (c) 1995-2005, 2010 Mark Adler\r\nCopyright (c) 1995-2011, 2016 Mark Adler\r\nCopyright (c) 1995-2016 Jean-loup Gailly\r\nCopyright (c) 1995-2017 Jean-loup Gailly\r\nCopyright (c) 1997,99 Borland Corporation\r\nCopyright (c) 1998 by Andreas R. Kleinert\r\nCopyright (c) 2002-2003 Dmitriy Anisimkov\r\nCopyright (c) 2002-2004 Dmitriy Anisimkov\r\nCopyright (c) 2003, 2012, 2013 Mark Adler\r\nCopyright (c) 2004, 2005, 2012 Mark Adler\r\nCopyright (c) 2004, 2008, 2012 Mark Adler\r\nCopyright (c) 2007, 2008, 2012 Mark Adler\r\nCopyright (c) 1998 by Jacques Nomssi Nzali\r\n(c) 1995-2017 Jean-loup Gailly & Mark Adler\r\nCopyright (c) 1995-2003 by Jean-loup Gailly\r\nCopyright (c) 1998-2010 - by Gilles Vollant\r\n(c) 1995-2017 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2004, 2008, 2012, 2016 Mark Adler\r\nCopyright 1995-2017 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 1995-2006, 2011, 2016 Jean-loup Gailly\r\nCopyright (c) 1995-2016 Jean-loup Gailly, Mark Adler\r\nCopyright (c) 1995-2017 Jean-Loup Gailly, Mark Adler\r\nCopyright (c) 1995-2017 Jean-loup Gailly, Mark Adler\r\nCopyright (c) 1998,1999,2000 by Jacques Nomssi Nzali\r\nCopyright (c) 2003, 2005, 2008, 2010, 2012 Mark Adler\r\nCopyright (c) 2003 Chris Anderson <christop@charm.net>\r\nCopyright (c) 1995-2003 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\r\ncopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 1996 L. Peter Deutsch and Jean-Loup Gailly\r\nCopyright (c) 1998 Brian Raiter <breadbox@muppetlabs.com>\r\nCopyright (c) 1995-2006, 2010, 2011, 2012, 2016 Mark Adler\r\nCopyright (c) 1995-2006, 2010, 2011, 2016 Jean-loup Gailly\r\nCopyright (c) 2009-2010 Mathias Svensson http://result42.com\r\nCopyright (c) 1998, 2007 Brian Raiter <breadbox@muppetlabs.com>\r\nCopyright (c) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler\r\nCopyright (c) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler\r\nCopyright Jean-loup Gailly Osma Ahvenlampi <Osma.Ahvenlampi@hut.fi>\r\nCopyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll\r\nCopyright (c) 1997 Christian Michelsen Research AS Advanced Computing\r\nCopyright (c) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler\r\nCopyright (c) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson\r\nCopyright (c) 1995-1996 Jean-loup Gailly, Brian Raiter and Gilles Vollant\r\nCopyright (c) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant\r\nCopyright (c) 1998-2010 Gilles Vollant (minizip) http://www.winimage.com/zLibDll/minizip.html\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2020 Ronomon CC\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nruntime.linux-arm.runtime.native.System.IO.Ports 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nruntime.linux-arm64.runtime.native.System.IO.Ports 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nruntime.linux-x64.runtime.native.System.IO.Ports 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nruntime.native.System.Data.SqlClient.sni 4.7.0 - MIT\r\n\r\n\r\n(c) Microsoft Corporation.\r\nCopyright (c) .NET Foundation.\r\nCopyright (c) 2011, Google Inc.\r\n(c) 1997-2005 Sean Eron Anderson.\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2017 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nPortions (c) International Organization\r\nCopyright (c) 2015 The Chromium Authors.\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nruntime.native.System.IO.Ports 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nruntime.osx-arm64.runtime.native.System.IO.Ports 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nruntime.osx-x64.runtime.native.System.IO.Ports 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSemver 2.3.0 - MIT\r\n\r\n\r\nCopyright 2013 Max Hauser, Jeff Walker\r\nCopyright (c) 2013 Max Hauser, Jeff Walker\r\nCopyright 2013 Max Hauser, Jeff Walker VA SemVer\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Buffers 4.5.1 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\nCopyright (c) 2011, Google Inc.\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1991-2017 Unicode, Inc.\r\nCopyright (c) 2015 The Chromium Authors\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.CodeDom 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Collections.Immutable 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.ComponentModel.Composition 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.ComponentModel.Composition.Registration 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Configuration.ConfigurationManager 8.0.1 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Data.Odbc 8.0.1 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Data.OleDb 8.0.1 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Data.SqlClient 4.8.6 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2017 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Diagnostics.DiagnosticSource 5.0.0 - MIT\r\n\r\n\r\n(c) Microsoft Corporation.\r\nCopyright (c) Andrew Arnott\r\nCopyright 2018 Daniel Lemire\r\nCopyright 2012 the V8 project\r\nCopyright (c) .NET Foundation.\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 1998 Microsoft. To\r\n(c) 1997-2005 Sean Eron Anderson.\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 2012-2014, Yann Collet\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2018 Alexander Chermyanin\r\nPortions (c) International Organization\r\nCopyright (c) 2015 The Chromium Authors.\r\nCopyright (c) The Internet Society 1997.\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) The Internet Society (2003).\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California.\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass.\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass. To\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Diagnostics.DiagnosticSource 8.0.1 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Diagnostics.DiagnosticSource 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Diagnostics.EventLog 6.0.0 - MIT\r\n\r\n\r\n(c) Microsoft Corporation.\r\nCopyright (c) Andrew Arnott\r\nCopyright 2018 Daniel Lemire\r\nCopyright 2012 the V8 project\r\nCopyright (c) .NET Foundation.\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 1998 Microsoft. To\r\n(c) 1997-2005 Sean Eron Anderson.\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 2012-2014, Yann Collet\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2018 Alexander Chermyanin\r\nPortions (c) International Organization\r\nCopyright (c) 2015 The Chromium Authors.\r\nCopyright (c) The Internet Society 1997.\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) The Internet Society (2003).\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California.\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass.\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass. To\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Diagnostics.EventLog 8.0.1 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Diagnostics.EventLog 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Diagnostics.PerformanceCounter 8.0.1 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.DirectoryServices 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.DirectoryServices.AccountManagement 8.0.1 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.DirectoryServices.Protocols 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Drawing.Common 8.0.19 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\nCopyright (c) Sven Groot (Ookii.org) 2009\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Drawing.Common 9.0.0-preview.6.24327.6 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\nCopyright (c) Sven Groot (Ookii.org) 2009\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Formats.Asn1 8.0.1 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.IO.Packaging 8.0.1 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.IO.Pipelines 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.IO.Ports 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Management 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Management.Automation 7.4.6 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\n(c) Microsoft Corporation. 1PowerShell's System.Management.Automation project\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Memory 4.5.4 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\nCopyright (c) 2011, Google Inc.\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1991-2017 Unicode, Inc.\r\nCopyright (c) 2015 The Chromium Authors\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Net.Http.WinHttpHandler 8.0.2 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Net.ServerSentEvents 10.0.0-preview.4.25258.110 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2024 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Numerics.Vectors 4.4.0 - MIT\r\n\r\n\r\n(c) Microsoft Corporation.\r\n(c) 1997-2005 Sean Eron Anderson.\r\nCopyright (c) 1991-2017 Unicode, Inc.\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Numerics.Vectors 4.5.0 - MIT\r\n\r\n\r\n(c) 2023 GitHub, Inc.\r\n(c) Microsoft Corporation\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1991-2017 Unicode, Inc.\r\nCopyright (c) 2015 The Chromium Authors\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Private.ServiceModel 4.10.3 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Reflection.Context 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Reflection.DispatchProxy 4.7.1 - MIT\r\n\r\n\r\n(c) Microsoft Corporation.\r\nCopyright (c) .NET Foundation.\r\nCopyright (c) 2011, Google Inc.\r\n(c) 1997-2005 Sean Eron Anderson.\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2017 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nPortions (c) International Organization\r\nCopyright (c) 2015 The Chromium Authors.\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Reflection.Metadata 1.6.0 - MIT\r\n\r\n\r\n(c) 2023 GitHub, Inc.\r\n(c) Microsoft Corporation\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1991-2017 Unicode, Inc.\r\nCopyright (c) 2015 The Chromium Authors\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Reflection.Metadata 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\nGets the Copyright Table\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Runtime.Caching 8.0.1 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Runtime.CompilerServices.Unsafe 4.5.3 - MIT\r\n\r\n\r\n(c) Microsoft Corporation.\r\nCopyright (c) 2011, Google Inc.\r\n(c) 1997-2005 Sean Eron Anderson.\r\nCopyright (c) 1991-2017 Unicode, Inc.\r\nPortions (c) International Organization\r\nCopyright (c) 2015 The Chromium Authors.\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Runtime.CompilerServices.Unsafe 6.0.0 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 2012-2014, Yann Collet\r\nCopyright (c) 1991-2020 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass. To\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Runtime.WindowsRuntime 4.6.0 - MIT\r\n\r\n\r\n(c) Microsoft Corporation.\r\nCopyright (c) .NET Foundation.\r\nCopyright (c) 2011, Google Inc.\r\n(c) 1997-2005 Sean Eron Anderson.\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2017 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nPortions (c) International Organization\r\nCopyright (c) 2015 The Chromium Authors.\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Runtime.WindowsRuntime.UI.Xaml 4.6.0 - MIT\r\n\r\n\r\n(c) Microsoft Corporation.\r\nCopyright (c) .NET Foundation.\r\nCopyright (c) 2011, Google Inc.\r\n(c) 1997-2005 Sean Eron Anderson.\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2017 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nPortions (c) International Organization\r\nCopyright (c) 2015 The Chromium Authors.\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Security.AccessControl 5.0.0 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 2012-2014, Yann Collet\r\nCopyright (c) 1991-2020 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass. To\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Security.AccessControl 6.0.1 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 2012-2014, Yann Collet\r\nCopyright (c) 1991-2020 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass. To\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Security.Cryptography.Pkcs 8.0.1 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Security.Cryptography.ProtectedData 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Security.Cryptography.Xml 8.0.2 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Security.Permissions 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Security.Principal.Windows 5.0.0 - MIT\r\n\r\n\r\n(c) Microsoft Corporation.\r\nCopyright (c) Andrew Arnott\r\nCopyright 2018 Daniel Lemire\r\nCopyright 2012 the V8 project\r\nCopyright (c) .NET Foundation.\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 1998 Microsoft. To\r\n(c) 1997-2005 Sean Eron Anderson.\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 2012-2014, Yann Collet\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2018 Alexander Chermyanin\r\nPortions (c) International Organization\r\nCopyright (c) 2015 The Chromium Authors.\r\nCopyright (c) The Internet Society 1997.\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) The Internet Society (2003).\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California.\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass.\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass. To\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.ServiceModel.Duplex 4.10.3 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.ServiceModel.Http 4.10.3 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.ServiceModel.NetTcp 4.10.3 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.ServiceModel.Primitives 4.10.3 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.ServiceModel.Security 4.10.3 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.ServiceModel.Syndication 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.ServiceProcess.ServiceController 8.0.1 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Speech 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Text.Encoding.CodePages 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Text.Encodings.Web 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Text.Encodings.Web 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Text.Json 9.0.6 - MIT\r\n\r\n\r\nCopyright (c) 2021\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright (c) 1998 Microsoft\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nPortions (c) International Organization for Standardization 1986\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Threading.AccessControl 9.0.0-preview.6.24327.7 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) 2022 FormatJS\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2015 Andrew Gallant\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright (c) 2018 Nemanja Mijailovic\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2015-2018, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Web.Services.Description 4.10.3 - MIT\r\n\r\n\r\n(c) Microsoft Corporation\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nSystem.Windows.Extensions 8.0.0 - MIT\r\n\r\n\r\nCopyright (c) Six Labors\r\n(c) Microsoft Corporation\r\nCopyright (c) Andrew Arnott\r\nCopyright 2019 LLVM Project\r\nCopyright 2018 Daniel Lemire\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2011, Google Inc.\r\nCopyright (c) 2020 Dan Shechter\r\n(c) 1997-2005 Sean Eron Anderson\r\nCopyright (c) 1998 Microsoft. To\r\nCopyright (c) 2022, Wojciech Mula\r\nCopyright (c) 2017 Yoshifumi Kawai\r\nCopyright (c) 2022, Geoff Langdale\r\nCopyright (c) 2005-2020 Rich Felker\r\nCopyright (c) 2012-2021 Yann Collet\r\nCopyright (c) Microsoft Corporation\r\nCopyright (c) 2007 James Newton-King\r\nCopyright (c) 1991-2022 Unicode, Inc.\r\nCopyright (c) 2013-2017, Alfred Klomp\r\nCopyright 2012 the V8 project authors\r\nCopyright (c) 1999 Lucent Technologies\r\nCopyright (c) 2008-2016, Wojciech Mula\r\nCopyright (c) 2011-2020 Microsoft Corp\r\nCopyright (c) 2015-2017, Wojciech Mula\r\nCopyright (c) 2021 csFastFloat authors\r\nCopyright (c) 2005-2007, Nick Galbreath\r\nCopyright (c) 2015 The Chromium Authors\r\nCopyright (c) 2018 Alexander Chermyanin\r\nCopyright (c) The Internet Society 1997\r\nPortions (c) International Organization\r\nCopyright (c) 2004-2006 Intel Corporation\r\nCopyright (c) 2011-2015 Intel Corporation\r\nCopyright (c) 2013-2017, Milosz Krajewski\r\nCopyright (c) 2016-2017, Matthieu Darbois\r\nCopyright (c) The Internet Society (2003)\r\nCopyright (c) .NET Foundation Contributors\r\nCopyright (c) 2020 Mara Bos <m-ou.se@m-ou.se>\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) 2012 - present, Victor Zverovich\r\nCopyright (c) 2006 Jb Evain (jbevain@gmail.com)\r\nCopyright (c) 2008-2020 Advanced Micro Devices, Inc.\r\nCopyright (c) 2019 Microsoft Corporation, Daan Leijen\r\nCopyright (c) 2011 Novell, Inc (http://www.novell.com)\r\nCopyright (c) 1995-2022 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)\r\nCopyright (c) 2009, 2010, 2013-2016 by the Brotli Authors\r\nCopyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com\r\nCopyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.\r\nCopyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers\r\nCopyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip\r\nCopyright (c) 1980, 1986, 1993 The Regents of the University of California\r\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California\r\nCopyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\nAll rights reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nxunit.runner.visualstudio 2.4.5 - MIT\r\n\r\n\r\nCopyright (c) .NET Foundation\r\nCopyright (c) 2015 .NET Foundation\r\nCopyright (c) Outercurve Foundation\r\nCopyright (c) .NET Foundation and Contributors\r\nCopyright (c) .NET Foundation xUnit.net Runner Utility\r\nCopyright (c) .NET Foundation ,xUnit.net Runner Utility\r\nCopyright (c) .NET Foundation 1xUnit.net Runner Utility\r\nCopyright (c) .NET Foundation xUnit.net Runner Reporters\r\nCopyright (c) .NET Foundation .xUnit.net Runner Reporters\r\nCopyright (c) Outercurve Foundation WrapNonExceptionThrows RSDS\r\nCopyright (c) .NET Foundation and Contributors. Visual Studio 2019\r\n\r\nUnless otherwise noted, the source code here is covered by the following license:\r\n\r\n    Copyright (c) .NET Foundation and Contributors\r\n    All Rights Reserved\r\n\r\n    Licensed under the Apache License, Version 2.0 (the \"License\");\r\n    you may not use this file except in compliance with the License.\r\n    You may obtain a copy of the License at\r\n\r\n        http://www.apache.org/licenses/LICENSE-2.0\r\n\r\n    Unless required by applicable law or agreed to in writing, software\r\n    distributed under the License is distributed on an \"AS IS\" BASIS,\r\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n    See the License for the specific language governing permissions and\r\n    limitations under the License.\r\n\r\n-----------------------\r\n\r\nThe code in src/xunit.runner.visualstudio/Utility/AssemblyResolution/Microsoft.DotNet.PlatformAbstractions was imported from:\r\n    https://github.com/dotnet/core-setup/tree/v2.0.1/src/managed/Microsoft.DotNet.PlatformAbstractions\r\n\r\nThe code in src/xunit.runner.visualstudio/Utility/AssemblyResolution/Microsoft.DotNet.PlatformAbstractions was imported from:\r\n    https://github.com/dotnet/core-setup/tree/v2.0.1/src/managed/Microsoft.Extensions.DependencyModel\r\n\r\nBoth sets of code are covered by the following license:\r\n\r\n    The MIT License (MIT)\r\n\r\n    Copyright (c) 2015 .NET Foundation\r\n\r\n    Permission is hereby granted, free of charge, to any person obtaining a copy\r\n    of this software and associated documentation files (the \"Software\"), to deal\r\n    in the Software without restriction, including without limitation the rights\r\n    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n    copies of the Software, and to permit persons to whom the Software is\r\n    furnished to do so, subject to the following conditions:\r\n\r\n    The above copyright notice and this permission notice shall be included in all\r\n    copies or substantial portions of the Software.\r\n\r\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n    SOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nyaml/libyaml 840b65c40675e2d06bf40405ad3f12dec7f35923 - MIT\r\n\r\n\r\nCopyright (c) 2017-2020 Ingy dot Net\r\nCopyright (c) 2006-2016 Kirill Simonov\r\nCopyright (c) 2017-2020 Ingy dot Net <ingy@ingy.net>\r\nCopyright (c) 2006-2016 Kirill Simonov <xi@resolvent.net>\r\n\r\nCopyright (c) 2017-2020 Ingy döt Net\r\nCopyright (c) 2006-2016 Kirill Simonov\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of\r\nthis software and associated documentation files (the \"Software\"), to deal in\r\nthe Software without restriction, including without limitation the rights to\r\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\r\nof the Software, and to permit persons to whom the Software is furnished to do\r\nso, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all\r\ncopies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nYamlDotNet 16.3.0 - MIT\r\n\r\n\r\nCopyright (c) Antoine Aubry and contributors\r\n(c) Antoine Aubry and contributors 2008 - 2019\r\nCopyright (c) Antoine Aubry and contributors 2008 - 2019\r\n\r\nMIT License\r\n\r\nCopyright (c) <year> <copyright holders>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.Management.Infrastructure.Runtime.Win 3.0.0\r\n\r\n\r\n(c) Microsoft 2024\r\n(c) Microsoft Corporation\r\nCopyright (c) Microsoft Corporation\r\n\r\nMICROSOFT SOFTWARE LICENSE TERMS\r\nMicrosoft.Management.Infrastructure.dll \r\nMicrosoft.Management.Infrastructure.Native.dll\r\nMicrosoft.Management.Infrastructure.Unmanaged.dll \r\nMi.dll \r\nMiutils.dll\r\n________________________________________\r\nIF YOU LIVE IN (OR ARE A BUSINESS WITH A PRINCIPAL PLACE OF BUSINESS IN) THE UNITED STATES, PLEASE READ THE “BINDING ARBITRATION AND CLASS ACTION WAIVER” SECTION BELOW. IT AFFECTS HOW DISPUTES ARE RESOLVED.\r\n________________________________________\r\n\r\nThese license terms are an agreement between you and Microsoft Corporation (or one of its affiliates). They apply to the software named above and any Microsoft services or software updates (except to the extent such services or updates are accompanied by new or additional terms, in which case those different terms apply prospectively and do not alter your or Microsoft’s rights relating to pre-updated software or services). IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW. BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS.\r\n1.\tINSTALLATION AND USE RIGHTS.\r\na)\tGeneral. You may install and use any number of copies of the software solely for use with Microsoft PowerShell.\r\nb)\tThird Party Software. The software may include third party applications that Microsoft, not the third party, licenses to you under this agreement. Any included notices for third party applications are for your information only.\r\n2.\tDATA COLLECTION. The software may collect information about you and your use of the software and send that to Microsoft. Microsoft may use this information to provide services and improve Microsoft’s products and services. Your opt-out rights, if any, are described in the product documentation. Some features in the software may enable collection of data from users of your applications that access or use the software. If you use these features to enable data collection in your applications, you must comply with applicable law, including getting any required user consent, and maintain a prominent privacy policy that accurately informs users about how you use, collect, and share their data. You can learn more about Microsoft’s data collection and use in the product documentation and the Microsoft Privacy Statement at aka.ms/privacy. You agree to comply with all applicable provisions of the Microsoft Privacy Statement.   \r\na.\tProcessing of Personal Data. To the extent Microsoft is a processor or subprocessor of personal data in connection with the software, Microsoft makes the commitments in the European Union General Data Protection Regulation Terms of the Online Services Terms to all customers effective May 25, 2018, at http://go.microsoft.com/?linkid=9840733.\r\n3.\tSCOPE OF LICENSE. The software is licensed, not sold. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you will not (and have no right to):\r\na)\twork around any technical limitations in the software that only allow you to use it in certain ways;\r\nb)\treverse engineer, decompile or disassemble the software;\r\nc)\tremove, minimize, block, or modify any notices of Microsoft or its suppliers in the software;\r\nd)\tuse the software in any way that is against the law or to create or propagate malware; or\r\ne)\tshare, publish, distribute, or lend the software, provide the software as a stand-alone hosted solution for others to use, or transfer the software or this agreement to any third party.\r\n4.\tEXPORT RESTRICTIONS. You must comply with all domestic and international export laws and regulations that apply to the software, which include restrictions on destinations, end users, and end use. For further information on export restrictions, visit http://aka.ms/exporting.\r\n5.\tSUPPORT SERVICES. Microsoft is not obligated under this agreement to provide any support services for the software. Any support provided is “as is”, “with all faults”, and without warranty of any kind.\r\n6.\tUPDATES. The software may periodically check for updates, and download and install them for you. You may obtain updates only from Microsoft or authorized sources. Microsoft may need to update your system to provide you with updates. You agree to receive these automatic updates without any additional notice. Updates may not include or support all existing software features, services, or peripheral devices.\r\n7.\tBINDING ARBITRATION AND CLASS ACTION WAIVER. This Section applies if you live in (or, if a business, your principal place of business is in) the United States.  If you and Microsoft have a dispute, you and Microsoft agree to try for 60 days to resolve it informally. If you and Microsoft can’t, you and Microsoft agree to binding individual arbitration before the American Arbitration Association under the Federal Arbitration Act (“FAA”), and not to sue in court in front of a judge or jury. Instead, a neutral arbitrator will decide. Class action lawsuits, class-wide arbitrations, private attorney-general actions, and any other proceeding where someone acts in a representative capacity are not allowed; nor is combining individual proceedings without the consent of all parties. The complete Arbitration Agreement contains more terms and is at http://aka.ms/arb-agreement-1. You and Microsoft agree to these terms.\r\n8.\tTERMINATION. Without prejudice to any other rights, Microsoft may terminate this agreement if you fail to comply with any of its terms or conditions. In such event, you must destroy all copies of the software and all of its component parts.\r\n9.\tENTIRE AGREEMENT. This agreement, and any other terms Microsoft may provide for supplements, updates, or third-party applications, is the entire agreement for the software.\r\n10.\tAPPLICABLE LAW AND PLACE TO RESOLVE DISPUTES. If you acquired the software in the United States or Canada, the laws of the state or province where you live (or, if a business, where your principal place of business is located) govern the interpretation of this agreement, claims for its breach, and all other claims (including consumer protection, unfair competition, and tort claims), regardless of conflict of laws principles, except that the FAA governs everything related to arbitration. If you acquired the software in any other country, its laws apply, except that the FAA governs everything related to arbitration. If U.S. federal jurisdiction exists, you and Microsoft consent to exclusive jurisdiction and venue in the federal court in King County, Washington for all disputes heard in court (excluding arbitration). If not, you and Microsoft consent to exclusive jurisdiction and venue in the Superior Court of King County, Washington for all disputes heard in court (excluding arbitration).\r\n11.\tCONSUMER RIGHTS; REGIONAL VARIATIONS. This agreement describes certain legal rights. You may have other rights, including consumer rights, under the laws of your state, province, or country. Separate and apart from your relationship with Microsoft, you may also have rights with respect to the party from which you acquired the software. This agreement does not change those other rights if the laws of your state, province, or country do not permit it to do so. For example, if you acquired the software in one of the below regions, or mandatory country law applies, then the following provisions apply to you:\r\na)\tAustralia. You have statutory guarantees under the Australian Consumer Law and nothing in this agreement is intended to affect those rights.\r\nb)\tCanada. If you acquired this software in Canada, you may stop receiving updates by turning off the automatic update feature, disconnecting your device from the Internet (if and when you re-connect to the Internet, however, the software will resume checking for and installing updates), or uninstalling the software. The product documentation, if any, may also specify how to turn off updates for your specific device or software.\r\nc)\tGermany and Austria.\r\ni.\tWarranty. The properly licensed software will perform substantially as described in any Microsoft materials that accompany the software. However, Microsoft gives no contractual guarantee in relation to the licensed software.\r\nii.\tLimitation of Liability. In case of intentional conduct, gross negligence, claims based on the Product Liability Act, as well as, in case of death or personal or physical injury, Microsoft is liable according to the statutory law.\r\nSubject to the foregoing clause ii., Microsoft will only be liable for slight negligence if Microsoft is in breach of such material contractual obligations, the fulfillment of which facilitate the due performance of this agreement, the breach of which would endanger the purpose of this agreement and the compliance with which a party may constantly trust in (so-called \"cardinal obligations\"). In other cases of slight negligence, Microsoft will not be liable for slight negligence.\r\n12.\tDISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED “AS IS.” YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES, OR CONDITIONS. TO THE EXTENT PERMITTED UNDER APPLICABLE LAWS, MICROSOFT EXCLUDES ALL IMPLIED WARRANTIES, INCLUDING MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.\r\n13.\tLIMITATION ON AND EXCLUSION OF DAMAGES. IF YOU HAVE ANY BASIS FOR RECOVERING DAMAGES DESPITE THE PRECEDING DISCLAIMER OF WARRANTY, YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.\r\nThis limitation applies to (a) anything related to the software, services, content (including code) on third party Internet sites, or third party applications; and (b) claims for breach of contract, warranty, guarantee, or condition; strict liability, negligence, or other tort; or any other claim; in each case to the extent permitted by applicable law.\r\nIt also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your state, province, or country may not allow the exclusion or limitation of incidental, consequential, or other damages.\r\n\r\nPlease note: As this software is distributed in Canada, some of the clauses in this agreement are provided below in French.\r\nRemarque: Ce logiciel étant distribué au Canada, certaines des clauses dans ce contrat sont fournies ci-dessous en français.\r\nEXONÉRATION DE GARANTIE. Le logiciel visé par une licence est offert « tel quel ». Toute utilisation de ce logiciel est à votre seule risque et péril. Microsoft n’accorde aucune autre garantie expresse. Vous pouvez bénéficier de droits additionnels en vertu du droit local sur la protection des consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualité marchande, d’adéquation à un usage particulier et d’absence de contrefaçon sont exclues.\r\nLIMITATION DES DOMMAGES-INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ POUR LES DOMMAGES. Vous pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de dommages directs uniquement à hauteur de 5,00 $ US. Vous ne pouvez prétendre à aucune indemnisation pour les autres dommages, y compris les dommages spéciaux, indirects ou accessoires et pertes de bénéfices.\r\nCette limitation concerne:\r\n•\ttout ce qui est relié au logiciel, aux services ou au contenu (y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers; et\r\n•\tles réclamations au titre de violation de contrat ou de garantie, ou au titre de responsabilité stricte, de négligence ou d’une autre faute dans la limite autorisée par la loi en vigueur.\r\nElle s’applique également, même si Microsoft connaissait ou devrait connaître l’éventualité d’un tel dommage. Si votre pays n’autorise pas l’exclusion ou la limitation de responsabilité pour les dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l’exclusion ci-dessus ne s’appliquera pas à votre égard.\r\nEFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous pourriez avoir d’autres droits prévus par les lois de votre pays. Le présent contrat ne modifie pas les droits que vous confèrent les lois de votre pays si celles-ci ne le permettent pas.\r\n\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nMicrosoft.NETCore.Platforms 1.1.1\r\n\r\n\r\n(c) Microsoft Corporation\r\nCopyright (c) .NET Foundation and Contributors\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nmadler/zlib 51b7f2abdade71cd9bb0e7a373ef2610ec6f9daf - Zlib\r\n\r\n\r\nCopyright (c) 2003 Mark Adler\r\nCopyright (c) 2018 Mark Adler\r\n(c) Copyright Henrik Ravn 2004\r\nCopyright (c) Henrik Ravn 2004\r\nCopyright 1995-2024 Mark Adler\r\nCopyright (c) 2003 Cosmin Truta\r\nCopyright (c) 1990-2000 Info-ZIP.\r\nCopyright (c) 1998 by Bob Dellaca\r\nCopyright (c) 2004 by Henrik Ravn\r\nCopyright (c) 1995-2003 Mark Adler\r\nCopyright (c) 1995-2008 Mark Adler\r\nCopyright (c) 1995-2017 Mark Adler\r\nCopyright (c) 1995-2019 Mark Adler\r\nCopyright (c) 1995-2022 Mark Adler\r\nCopyright (c) 1995-2024 Mark Adler\r\nCopyright (c) 2002-2013 Mark Adler\r\nCopyright (c) 2003 by Cosmin Truta\r\nCopyright (c) 2003-2010 Mark Adler\r\nCopyright (c) 2004-2017 Mark Adler\r\nCopyright (c) 2004-2019 Mark Adler\r\nCopyright (c) 2004-2023 Mark Adler\r\nCopyright (c) 2004-2024 Mark Adler\r\nCopyright (c) 1996 L. Peter Deutsch\r\nCopyright (c) 1997,99 Borland Corp.\r\nCopyright (c) 2003, 2012 Mark Adler\r\nCopyright (c) 2004, 2010 Mark Adler\r\nCopyright (c) 2011, 2016 Mark Adler\r\nCopyright (c) 2007-2008 Even Rouault\r\nCopyright (c) 1998-2005 Gilles Vollant\r\nCopyright (c) 1995-1998 Jean-loup Gailly\r\nCopyright (c) 1995-2003 Jean-loup Gailly\r\nCopyright (c) 1995-2003, 2010 Mark Adler\r\nCopyright (c) 1995-2005, 2010 Mark Adler\r\nCopyright (c) 1995-2011, 2016 Mark Adler\r\nCopyright (c) 1995-2017 Jean-loup Gailly\r\nCopyright (c) 1995-2024 Jean-loup Gailly\r\nCopyright (c) 1997,99 Borland Corporation\r\nCopyright (c) 1998 by Andreas R. Kleinert\r\nCopyright (c) 2002-2003 Dmitriy Anisimkov\r\nCopyright (c) 2002-2004 Dmitriy Anisimkov\r\nCopyright (c) 2003, 2012, 2013 Mark Adler\r\nCopyright (c) 2004, 2005, 2012 Mark Adler\r\nCopyright (c) 2004, 2008, 2012 Mark Adler\r\nCopyright (c) 1998 by Jacques Nomssi Nzali\r\n(c) 1995-2022 Jean-loup Gailly & Mark Adler\r\n(c) 1995-2024 Jean-loup Gailly & Mark Adler\r\nCopyright (c) 1995-2003 by Jean-loup Gailly\r\nCopyright (c) 1998-2010 - by Gilles Vollant\r\n(c) 1995-2017 Jean-loup Gailly and Mark Adler\r\n(c) 1995-2022 Jean-loup Gailly and Mark Adler\r\n(c) 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 2005, 2012, 2018, 2023 Mark Adler\r\nCopyright (c) 2007, 2008, 2012, 2018 Mark Adler\r\nCopyright 1995-2024 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 1995-2006, 2011, 2016 Jean-loup Gailly\r\nCopyright (c) 1995-2017 Jean-Loup Gailly, Mark Adler\r\nCopyright (c) 1995-2024 Jean-loup Gailly, Mark Adler\r\nCopyright (c) 1998,1999,2000 by Jacques Nomssi Nzali\r\nCopyright (c) 2003, 2005, 2008, 2010, 2012 Mark Adler\r\nCopyright (c) 2004, 2008, 2012, 2016, 2019 Mark Adler\r\nCopyright (c) 1995-2003 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 1995-2024 Jean-loup Gailly and Mark Adler\r\ncopyright (c) 1995-2017 Jean-loup Gailly and Mark Adler\r\nCopyright (c) 1996 L. Peter Deutsch and Jean-Loup Gailly\r\nCopyright (c) 1995-2006, 2010, 2011, 2016 Jean-loup Gailly\r\nCopyright (c) 2009-2010 Mathias Svensson http://result42.com\r\nCopyright (c) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler\r\nCopyright Jean-loup Gailly Osma Ahvenlampi <Osma.Ahvenlampi@hut.fi>\r\nCopyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll\r\nCopyright (c) 1997 Christian Michelsen Research AS Advanced Computing\r\nCopyright (c) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler\r\nCopyright (c) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson\r\nCopyright (c) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant\r\nCopyright (c) 1998-2010 Gilles Vollant (minizip) http://www.winimage.com/zLibDll/minizip.html\r\n\r\nCopyright notice:\r\n\r\n (C) 1995-2022 Jean-loup Gailly and Mark Adler\r\n\r\n  This software is provided 'as-is', without any express or implied\r\n  warranty.  In no event will the authors be held liable for any damages\r\n  arising from the use of this software.\r\n\r\n  Permission is granted to anyone to use this software for any purpose,\r\n  including commercial applications, and to alter it and redistribute it\r\n  freely, subject to the following restrictions:\r\n\r\n  1. The origin of this software must not be misrepresented; you must not\r\n     claim that you wrote the original software. If you use this software\r\n     in a product, an acknowledgment in the product documentation would be\r\n     appreciated but is not required.\r\n  2. Altered source versions must be plainly marked as such, and must not be\r\n     misrepresented as being the original software.\r\n  3. This notice may not be removed or altered from any source distribution.\r\n\r\n  Jean-loup Gailly        Mark Adler\r\n  jloup@gzip.org          madler@alumni.caltech.edu\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\ntristanpenman/valijson 0b4771e273a065d437814baf426bcfcafec0f434 - BSD-2-Clause\r\n\r\n\r\nCopyright (c) 2021 Tristan Penman\r\nCopyright (c) 2016, Tristan Penman\r\nCopyright (c) The Internet Society (2005)\r\nCopyright (c) The Internet Society (2006)\r\nCopyright (c) 2011 - 2012 Andrzej Krzemienski\r\nCopyright (c) 2016, Akamai Technologies, Inc.\r\nCopyright (c) 2016 Akamai Technologies Polymorphic\r\nCopyright (c) 2010 IETF Trust and the persons identified as the document authors\r\nCopyright (c) 2012 IETF Trust and the persons identified as the document authors\r\nCopyright (c) 2013 IETF Trust and the persons identified as the document authors\r\n\r\nCopyright (c) 2016, Tristan Penman\r\nCopyright (c) 2016, Akamai Technologies, Inc.\r\nAll rights reserved.\r\n\r\nRedistribution and use in source and binary forms, with or without\r\nmodification, are permitted provided that the following conditions are met:\r\n\r\n1. Redistributions of source code must retain the above copyright notice, this\r\n   list of conditions and the following disclaimer.\r\n2. Redistributions in binary form must reproduce the above copyright notice,\r\n   this list of conditions and the following disclaimer in the documentation\r\n   and/or other materials provided with the distribution.\r\n\r\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\r\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR\r\nANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n---------------------------------------------------------\r\n\r\nopen-source-parsers/jsoncpp 9be589598595963f94ba264d7b416d0533421106 - MIT OR OTHER\r\n\r\n\r\nCopyright (c) 2016 InfoTeCS JSC.\r\nCopyright 2007-2010 The JsonCpp Authors\r\nCopyright 2007-2019 The JsonCpp Authors\r\nCopyright 2007 Baptiste Lepilleur and The JsonCpp Authors\r\nCopyright 2009 Baptiste Lepilleur and The JsonCpp Authors\r\nCopyright 2010 Baptiste Lepilleur and The JsonCpp Authors\r\nCopyright 2011 Baptiste Lepilleur and The JsonCpp Authors\r\nCopyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors\r\nCopyright 2007-2011 Baptiste Lepilleur and The JsonCpp Authors\r\nCopyright (c) 2007-2010 Baptiste Lepilleur and The JsonCpp Authors\r\nCopyright (c) 2007-2010 by Baptiste Lepilleur and The JsonCpp Authors\r\n\r\nThe JsonCpp library's source code, including accompanying documentation, \r\ntests and demonstration applications, are licensed under the following\r\nconditions...\r\n\r\nBaptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all \r\njurisdictions which recognize such a disclaimer. In such jurisdictions, \r\nthis software is released into the Public Domain.\r\n\r\nIn jurisdictions which do not recognize Public Domain property (e.g. Germany as of\r\n2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and\r\nThe JsonCpp Authors, and is released under the terms of the MIT License (see below).\r\n\r\nIn jurisdictions which recognize Public Domain property, the user of this \r\nsoftware may choose to accept it either as 1) Public Domain, 2) under the \r\nconditions of the MIT License (see below), or 3) under the terms of dual \r\nPublic Domain/MIT License conditions described here, as they choose.\r\n\r\nThe MIT License is about as close to Public Domain as a license can get, and is\r\ndescribed in clear, concise terms at:\r\n\r\n   http://en.wikipedia.org/wiki/MIT_License\r\n   \r\nThe full text of the MIT License follows:\r\n\r\n========================================================================\r\nCopyright (c) 2007-2010 Baptiste Lepilleur and The JsonCpp Authors\r\n\r\nPermission is hereby granted, free of charge, to any person\r\nobtaining a copy of this software and associated documentation\r\nfiles (the \"Software\"), to deal in the Software without\r\nrestriction, including without limitation the rights to use, copy,\r\nmodify, merge, publish, distribute, sublicense, and/or sell copies\r\nof the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be\r\nincluded in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\r\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r\nBE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r\nACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\nSOFTWARE.\r\n========================================================================\r\n(END LICENSE TEXT)\r\n\r\nThe MIT license is compatible with both the GPL and commercial\r\nsoftware, affording one all of the rights of Public Domain with the\r\nminor nuisance of being required to keep the above copyright notice\r\nand license text in the source code. Note also that by accepting the\r\nPublic Domain \"license\" you can re-license your copy using whatever\r\nlicense you like.\r\n\r\n\r\n---------------------------------------------------------\r\n\r\n"
  },
  {
    "path": "PRIVACY.md",
    "content": "# Data Collection\n\nThe software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the repository. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft's privacy statement. Our privacy statement is located at https://go.microsoft.com/fwlink/?LinkID=824704. You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices.\n"
  },
  {
    "path": "README.md",
    "content": "# ![WinGet Icon](.github/images/WindowsPackageManager_Assets/ICO/PNG/_40.png) Windows Package Manager\r\n\r\n## WinGet Client\r\n\r\n![winget install wingetcreate](.github/images/WingetInstall.gif)\r\n\r\nIf you are new to the Windows Package Manager, you might want to [Explore the Windows Package Manager tool](https://docs.microsoft.com/learn/modules/explore-windows-package-manager-tool/?WT.mc_id=AZ-MVP-5004737). The client has access to packages from two default sources. The first is \"msstore\" the Microsoft Store (free Apps rated \"e\" for everyone). The second is \"winget\" the [WinGet community repository](https://github.com/microsoft/winget-pkgs).\r\n\r\n> [!NOTE]\r\n> Group policy may be configured and modify configured sources. Run `winget --info` to see any configured policies.\r\n\r\n## Installing The Client\r\n\r\n> [!NOTE]\r\n> The client requires Windows 10 1809 (build 17763) or later at this time. Windows Server 2019 is not supported as the Microsoft Store is not available nor are updated dependencies. It may be possible to install on Windows Server 2022, this should be considered experimental (not supported) and requires dependencies to be manually installed as well.\r\n\r\n### Microsoft Store [Recommended]\r\n\r\nThe client is distributed within the [App Installer](https://apps.microsoft.com/detail/9nblggh4nns1) package.\r\n\r\n### Development Releases\r\n\r\nThere are a few methods to get development releases:\r\n\r\n* Install a [Windows 10 or Windows 11 Insider](https://insider.windows.com/) build.\r\n* Manually update using a development build from our [Releases](https://github.com/microsoft/winget-cli/releases) page.\r\n* Use the `Repair-WinGetPackageManager` cmdlet from the [Microsoft.WinGet.Client](https://www.powershellgallery.com/packages/Microsoft.WinGet.Client/) PowerShell module and use the `-IncludePrerelease` parameter.\r\n\r\n> [!NOTE]\r\n> If you decide to install the latest release from GitHub, and you have successfully joined the insider program, you will receive updates when the next development release has been published in the Microsoft Store.\r\n\r\nOnce you have received the updated App Installer from the Microsoft Store you should be able to execute `winget features` to see experimental features. Some users have reported [issues](https://github.com/microsoft/winget-cli/issues/210) with the client not being on their PATH.\r\n\r\n### Manually Update\r\n\r\nThe same Microsoft Store package will be made available via our [Releases](https://github.com/microsoft/winget-cli/releases). Note that installing this package will give you the WinGet client, but it will not enable automatic updates from the Microsoft Store if you have not joined the Windows Package Manager Insider program.\r\n\r\n> [!NOTE]\r\n> You may need to install the [VC++ v14 Desktop Framework Package](https://docs.microsoft.com/troubleshoot/cpp/c-runtime-packages-desktop-bridge#how-to-install-and-update-desktop-framework-packages).\r\n> This should only be necessary on older builds of Windows 10 and only if you get an error about missing framework packages.\r\n\r\n### Troubleshooting\r\n\r\nPlease read our [troubleshooting guide](/doc/troubleshooting/README.md).\r\n\r\n## Administrator Considerations\r\n\r\nInstaller behavior can be different depending on whether you are running **WinGet** with administrator privileges.\r\n\r\n* When running **WinGet** without administrator privileges, some applications may [require elevation](https://docs.microsoft.com/windows/security/identity-protection/user-account-control/how-user-account-control-works) to install. When the installer runs, Windows will prompt you to [elevate](https://docs.microsoft.com/windows/security/identity-protection/user-account-control/how-user-account-control-works#the-uac-user-experience). If you choose not to elevate, the application will fail to install.\r\n\r\n* When running **WinGet** in an Administrator Command Prompt, you will not see [elevation prompts](https://docs.microsoft.com/windows/security/identity-protection/user-account-control/how-user-account-control-works#the-uac-user-experience) if the application requires it. Always use caution when running your command prompt as an administrator, and only install applications you trust.\r\n\r\n### Build your own\r\n\r\nYou can also [build the client yourself](#building-the-client). While the client should be perfectly functional, we are not ready to provide full support for clients running outside of the official distribution mechanisms yet. Feel free to file an [Issue](https://github.com/microsoft/winget-cli/issues/new/choose), but know that it may get lower prioritization.\r\n\r\n## Build Status\r\n\r\n[![Build Status](https://dev.azure.com/shine-oss/winget-cli/_apis/build/status/winget-cli%20Build_Test?branchName=master&label=Main%20Branch%20(Including%20PRs))](https://dev.azure.com/shine-oss/winget-cli/_build/latest?definitionId=10&branchName=master)\r\n\r\n## Windows Package Manager Release Roadmap\r\n\r\nThe plan for delivering the next Windows Package Manager release is described and included in our [discussions](https://github.com/microsoft/winget-cli/discussions/2063), and will be updated as the project proceeds.\r\n\r\n## Overview of the  Windows Package Manager\r\n\r\nThe **Windows Package Manager** is a tool designed to help you quickly and easily discover and install those packages that make your PC environment special.  By using the **Windows Package Manager**, from one command, you can install your favorite packages:\r\n\r\n`winget install <package>`\r\n\r\n## Overview\r\n\r\n### Client Repository\r\n\r\nThis winget-cli repository includes the source code designed to build the client.  You are encouraged to participate in the development of this client. We have plenty of backlog features in our [Issues](https://github.com/microsoft/winget-cli/issues?q=is%3Aopen+is%3Aissue+milestone%3ABacklog-Client). You can upvote the ones you want, add more, or even [get started on one.](https://github.com/orgs/microsoft/projects/137)\r\n\r\n### Sources\r\n\r\nThe client is built around the concept of sources; a set of packages effectively. Sources provide the ability to discover and retrieve the metadata about the packages so that the client can act on it.\r\n\r\n* The default \"winget\" source includes packages in the [Windows Package Manager Community Repository](https://github.com/microsoft/winget-pkgs).\r\n* The default \"msstore\" source includes packages in the Microsoft Store.\r\n* It is also possible to host your own private [REST-based](https://github.com/microsoft/winget-cli-restsource) source.\r\n\r\n## Building the client\r\n\r\nPlease follow our [developer guidance](/doc/Developing.md) to build, run & test the client.\r\n\r\n## Credit\r\n\r\nWe would like to thank [Keivan Beigi (@kayone)](https://github.com/kayone) for his work on AppGet which helped us with the initial project direction for Windows Package Manager.\r\n\r\n## Contributing\r\n\r\nThis project welcomes contributions and suggestions.  Most contributions require you to agree to a\r\nContributor License Agreement (CLA) declaring that you have the right to, and do, actually grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. More\r\ninformation is available in our [CONTRIBUTING.md](/CONTRIBUTING.md) file.\r\n\r\nWhen you submit a pull request, a CLA bot will automatically determine whether you need to provide\r\na CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions\r\nprovided by the bot. You will only need to do this once across all repos using our CLA.\r\n\r\nThis project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).\r\nFor more information, please refer to the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or\r\ncontact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.\r\n\r\n## Data/Telemetry\r\n\r\nThe winget.exe client is instrumented to collect usage and diagnostic (error) data and sends it to Microsoft to help improve the product.\r\n\r\nIf you build the client yourself the instrumentation will not be enabled and no data will be sent to Microsoft.\r\n\r\nThe winget.exe client respects machine-wide privacy settings and users can opt out on their device, as documented in the [Microsoft Windows privacy statement](https://support.microsoft.com/help/4468236/diagnostics-feedback-and-privacy-in-windows-10-microsoft-privacy). In addition, you may also explicitly block telemetry using [settings](https://docs.microsoft.com/windows/package-manager/winget/settings)\r\n\r\nIn short, to opt out, do one of the following:\r\n\r\n**Windows 11**: Go to `Start`, then select `Settings` > `Privacy & Security` > `Diagnostics & feedback` > `Diagnostic data` and unselect `Send optional diagnostic data`.\r\n\r\n**Windows 10**: Go to `Start`, then select `Settings` > `Privacy` > `Diagnostics & feedback`, and select `Required diagnostic data`.\r\n\r\nSee the [privacy statement](PRIVACY.md) for more details.\r\n\r\n"
  },
  {
    "path": "SECURITY.md",
    "content": "<!-- BEGIN MICROSOFT SECURITY.MD V0.0.9 BLOCK -->\n## Security\n\nMicrosoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet) and [Xamarin](https://github.com/xamarin).\n\nIf you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/security.md/definition), please report it to us as described below.\n\n## Reporting Security Issues\n\n**Please do not report security vulnerabilities through public GitHub issues.**\n\nInstead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/security.md/msrc/create-report).\n\nIf you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com).  If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/security.md/msrc/pgp).\n\nYou should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc).\n\nPlease include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:\n\n  * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)\n  * Full paths of source file(s) related to the manifestation of the issue\n  * The location of the affected source code (tag/branch/commit or direct URL)\n  * Any special configuration required to reproduce the issue\n  * Step-by-step instructions to reproduce the issue\n  * Proof-of-concept or exploit code (if possible)\n  * Impact of the issue, including how an attacker might exploit the issue\n\nThis information will help us triage your report more quickly.\n\nIf you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/security.md/msrc/bounty) page for more details about our active programs.\n\n## Preferred Languages\n\nWe prefer all communications to be in English.\n\n## Policy\n\nMicrosoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/security.md/cvd).\n\n<!-- END MICROSOFT SECURITY.MD BLOCK -->\n"
  },
  {
    "path": "SUPPORT.md",
    "content": "# Support\n\n## How to file issues and get help\n\nThis project uses [GitHub issues][gh-issue] to [track bugs][gh-bug] and [feature requests][gh-feature]. Please search the existing issues before filing new issues to avoid duplicates. For new topics, file your bug or feature request as a new issue.\n\nFor help and questions about using this project, please look at the [docs site for Windows Package Manager][docs] and our [Contributor's Guide][contributor] if you want to work on WinGet.\n\n## Microsoft Support Policy\n\nSupport for Windows Package Manager is limited to the resources listed above.\n\n[gh-issue]: https://github.com/microsoft/winget-cli/issues/new/choose\n[gh-bug]: https://github.com/microsoft/winget-cli/issues/new?assignees=&labels=Issue-Bug&projects=&template=Bug_Report.yml\n[gh-feature]: https://github.com/microsoft/winget-cli/issues/new?assignees=&labels=Issue-Feature&projects=&template=Feature_Request.yml\n[docs]: https://docs.microsoft.com/windows/package-manager\n[contributor]: https://github.com/microsoft/winget-cli/blob/master/CONTRIBUTING.md\n"
  },
  {
    "path": "azure-pipelines.loc.yml",
    "content": "#\r\n# Localization\r\n# This pipeline uploads English strings files to the localization service, downloads any translated\r\n# files which are available, and checks them into git. This pipeline relies on Microsoft-internal\r\n# resources to run.\r\n#\r\n\r\n# Expects a variable called LocServiceKey to contain the OAuth client secret for Touchdown.\r\n\r\ntrigger: none\r\npr: none\r\n\r\nname: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr)\r\n\r\njobs:\r\n- job: Localize\r\n  pool:\r\n    vmImage: windows-latest\r\n  variables:\r\n    skipComponentGovernanceDetection: true\r\n    tdbuildTeamId: 8343\r\n  steps:\r\n    # Upload client resources\r\n  - task: MicrosoftTDBuild.tdbuild-task.tdbuild-task.TouchdownBuildTask@5\r\n    displayName: Send resources to Touchdown Build\r\n    inputs:\r\n      teamId: $(tdbuildTeamId)\r\n      authType: FederatedIdentity\r\n      FederatedIdentityServiceConnection: AppInstallerTDBuild\r\n      isPreview: false\r\n      relativePathRoot: src\\AppInstallerCLIPackage\\Shared\\Strings\\en-us\r\n      resourceFilePath: '*.resw'\r\n      outputDirectoryRoot: localization/Resources/\r\n\r\n    # Upload Group Policy ADML\r\n    # Do it as a separate step as we need the result in a different location\r\n  - task: MicrosoftTDBuild.tdbuild-task.tdbuild-task.TouchdownBuildTask@5\r\n    displayName: Send ADML to Touchdown Build\r\n    inputs:\r\n      teamId: $(tdbuildTeamId)\r\n      authType: FederatedIdentity\r\n      FederatedIdentityServiceConnection: AppInstallerTDBuild\r\n      isPreview: false\r\n      relativePathRoot: doc\\admx\\en-US\r\n      resourceFilePath: '*.adml'\r\n      outputDirectoryRoot: Localization\\Policies\\\r\n\r\n  - script: |\r\n      cd $(Build.SourcesDirectory)\r\n      git add -A\r\n      git diff --cached --exit-code\r\n      echo ##vso[task.setvariable variable=hasChanges]%errorlevel%\r\n      git diff --cached > $(Build.ArtifactStagingDirectory)\\LocalizedStrings.patch\r\n    displayName: Check for changes and create patch file\r\n\r\n  - task: PublishPipelineArtifact@0\r\n    displayName: Publish patch file as artifact\r\n    condition: eq(variables['hasChanges'], '1')\r\n    inputs:\r\n      artifactName: Patch\r\n      targetPath: $(Build.ArtifactStagingDirectory)\r\n"
  },
  {
    "path": "azure-pipelines.yml",
    "content": "# Commit triggers\r\ntrigger:\r\n- master\r\n\r\n# PR triggers\r\npr:\r\n  branches:\r\n    include:\r\n    - master\r\n  paths:\r\n    include:\r\n    - azure-pipelines.yml\r\n    - templates/*\r\n    - src/*\r\n    - schemas/JSON/manifests/*\r\n\r\npool:\r\n  vmImage: 'windows-2025'\r\n\r\nvariables:\r\n  solution: 'src\\AppInstallerCLI.sln'\r\n  EnableDetectorVcpkg: true\r\n\r\n# Do not set the build version for a PR build.\r\n\r\njobs:\r\n- job: 'GetReleaseTag'\r\n  condition: not(eq(variables['Build.Reason'], 'PullRequest'))\r\n  variables:\r\n    runCodesignValidationInjection: ${{ false }}\r\n    skipComponentGovernanceDetection: ${{ true }}\r\n  steps:\r\n  - task: PowerShell@2\r\n    name: 'GetTag'\r\n    displayName: Get Release Tag\r\n    inputs:\r\n      filePath: 'src\\binver\\Update-BinVer.ps1'\r\n      arguments: '-OutVar'\r\n      workingDirectory: 'src'\r\n\r\n# Build job creates artifacts for use in test jobs\r\n\r\n- job: 'Build'\r\n  timeoutInMinutes: 120\r\n  dependsOn: 'GetReleaseTag'\r\n  condition: always()\r\n\r\n  strategy:\r\n    matrix:\r\n      x86_release:\r\n        buildConfiguration: 'Release'\r\n        buildPlatform: 'x86'\r\n        artifactIdentifier: 'x86release'\r\n      x64_release:\r\n        buildConfiguration: 'Release'\r\n        buildPlatform: 'x64'\r\n        artifactIdentifier: 'x64release'\r\n\r\n  variables:\r\n    BuildVer: $[counter(dependencies.GetReleaseTag.outputs['GetTag.tag'], 1)]\r\n    buildOutDir: $(Build.SourcesDirectory)\\src\\$(buildPlatform)\\$(buildConfiguration)\r\n    buildOutDirAnyCpu: $(Build.SourcesDirectory)\\src\\AnyCPU\\$(buildConfiguration)\r\n    artifactsDir: $(Build.ArtifactStagingDirectory)\\$(buildPlatform)\r\n    appxPackageDir: $(Build.ArtifactStagingDirectory)\\$(buildPlatform)\\AppxPackages\r\n\r\n  steps:\r\n  - task: NuGetToolInstaller@1\r\n    displayName: Install Nuget\r\n\r\n  # Restores all projects, including native (vcxproj) projects\r\n  - task: NuGetCommand@2\r\n    displayName: Restore Solution\r\n    inputs:\r\n      restoreSolution: '$(solution)'\r\n\r\n  # Restore these UAP packages as https://github.com/NuGet/Home/issues/7796 leads to all UAP packages being skipped for restore.\r\n  # Even though they don't need any actual restore action, they need the project.assets.json file to be created and a direct restore does that.\r\n  - task: NuGetCommand@2\r\n    displayName: Restore AppInstallerCLIPackage\r\n    inputs:\r\n      restoreSolution: 'src\\AppInstallerCLIPackage\\AppInstallerCLIPackage.wapproj'\r\n\r\n  - task: NuGetCommand@2\r\n    displayName: Restore AppInstallerTestMsixInstaller\r\n    inputs:\r\n      restoreSolution: 'src\\AppInstallerTestMsixInstaller\\AppInstallerTestMsixInstaller.wapproj'\r\n\r\n  # Restores only .NET core projects, but is still necessary, as without this the IndexCreationTool and LocalhostWebServer projects fail to build\r\n  - task: DotNetCoreCLI@2\r\n    displayName: DotNet Restore\r\n    inputs:\r\n      command: 'restore'\r\n      projects: '**/*.csproj'\r\n\r\n  - task: CmdLine@2\r\n    displayName: Enable Vcpkg Install\r\n    inputs:\r\n      script: |\r\n        $(VCPKG_INSTALLATION_ROOT)\\vcpkg.exe integrate install\r\n      workingDirectory: '$(VCPKG_INSTALLATION_ROOT)'\r\n\r\n  - task: PowerShell@2\r\n    displayName: Update Binary Version\r\n    condition: not(eq(variables['Build.Reason'], 'PullRequest'))\r\n    inputs:\r\n      filePath: 'src\\binver\\Update-BinVer.ps1'\r\n      arguments: '-TargetFile binver\\binver\\version.h -BuildVersion $(BuildVer)'\r\n      workingDirectory: 'src'\r\n\r\n  # Build all solutions in the root directory.\r\n  - task: VSBuild@1\r\n    displayName: Build Solution\r\n    inputs:\r\n      platform: '$(buildPlatform)'\r\n      solution: '$(solution)'\r\n      configuration: '$(buildConfiguration)'\r\n      msbuildArgs: '/bl:$(artifactsDir)\\msbuild.binlog\r\n                    /p:AppxBundlePlatforms=\"$(buildPlatform)\"\r\n                    /p:AppxPackageDir=\"$(appxPackageDir)\"\r\n                    /p:AppxBundle=Always\r\n                    /p:UapAppxPackageBuildMode=SideloadOnly\r\n                    /p:WingetCleanIntermediateFiles=true'\r\n      maximumCpuCount: true\r\n\r\n  - task: MSBuild@1\r\n    displayName: Build MSIX Test Installer File\r\n    inputs:\r\n      platform: '$(buildPlatform)'\r\n      solution: 'src\\AppInstallerTestMsixInstaller\\AppInstallerTestMsixInstaller.wapproj'\r\n      configuration: '$(buildConfiguration)'\r\n      msbuildArguments: '/p:AppxPackageOutput=\"$(Build.ArtifactStagingDirectory)\\AppInstallerTestMsixInstaller.msix\"\r\n                         /p:AppxBundle=Never\r\n                         /p:UapAppxPackageBuildMode=SideLoadOnly\r\n                         /p:AppxPackageSigningEnabled=false'\r\n      maximumCpuCount: true\r\n\r\n  - task: CopyFiles@2\r\n    displayName: Copy vcpkg logs\r\n    inputs:\r\n      SourceFolder: $(VCPKG_INSTALLATION_ROOT)\\buildtrees\r\n      Contents: '**\\*.log'\r\n      TargetFolder: '$(artifactsDir)\\vcpkgLogs'\r\n    condition: succeededOrFailed()\r\n\r\n  - task: CopyFiles@2\r\n    displayName: 'Copy specific build artifacts'\r\n    inputs:\r\n      Contents: |\r\n          $(buildOutDir)\\WinGetUtil\\WinGetUtil.dll\r\n          $(buildOutDir)\\WinGetUtil\\WinGetUtil.pdb\r\n      TargetFolder: '$(artifactsDir)'\r\n\r\n  - task: PowerShell@2\r\n    displayName: Create Package Layout\r\n    inputs:\r\n      filePath: 'src\\AppInstallerCLIPackage\\Execute-AppxRecipe.ps1'\r\n      arguments: '-AppxRecipePath AppInstallerCLIPackage\\bin\\$(buildPlatform)\\$(buildConfiguration)\\AppInstallerCLIPackage.build.appxrecipe -LayoutPath $(artifactsDir)\\DevPackage -Force -Verbose'\r\n      workingDirectory: 'src'\r\n\r\n  - task: CopyFiles@2\r\n    displayName: 'Copy native binaries for Microsoft.WinGet.Client (net8)'\r\n    inputs:\r\n      SourceFolder: $(buildOutDir)\r\n      Contents: |\r\n          Microsoft.Management.Deployment.InProc\\Microsoft.Management.Deployment.dll\r\n          Microsoft.Management.Deployment\\Microsoft.Management.Deployment.winmd\r\n          WindowsPackageManager\\WindowsPackageManager.dll\r\n          UndockedRegFreeWinRT\\winrtact.dll\r\n      TargetFolder: $(buildOutDirAnyCpu)\\PowerShell\\Microsoft.WinGet.Client\\net8.0-windows10.0.26100.0\\SharedDependencies\\$(BuildPlatform)\r\n      flattenFolders: true\r\n\r\n  - task: CopyFiles@2\r\n    displayName: 'Copy native binaries for Microsoft.WinGet.Client (net48)'\r\n    inputs:\r\n      SourceFolder: $(buildOutDir)\r\n      Contents: |\r\n          Microsoft.Management.Deployment.InProc\\Microsoft.Management.Deployment.dll\r\n          Microsoft.Management.Deployment\\Microsoft.Management.Deployment.winmd\r\n          WindowsPackageManager\\WindowsPackageManager.dll\r\n          UndockedRegFreeWinRT\\winrtact.dll\r\n      TargetFolder: $(buildOutDirAnyCpu)\\PowerShell\\Microsoft.WinGet.Client\\net48\\SharedDependencies\\$(BuildPlatform)\r\n      flattenFolders: true\r\n\r\n  - task: CopyFiles@2\r\n    displayName: 'Copy native binaries for Microsoft.WinGet.Configuration'\r\n    inputs:\r\n      SourceFolder: $(buildOutDir)\r\n      Contents: |\r\n          Microsoft.Management.Configuration\\Microsoft.Management.Configuration.dll\r\n      TargetFolder: $(buildOutDirAnyCpu)\\PowerShell\\Microsoft.WinGet.Configuration\\SharedDependencies\\$(BuildPlatform)\r\n      flattenFolders: true\r\n\r\n  - task: CopyFiles@2\r\n    displayName: 'Copy managed binaries for Microsoft.WinGet.Configuration in arch specific'\r\n    inputs:\r\n      SourceFolder: $(buildOutDirAnyCpu)\r\n      Contents: |\r\n          Microsoft.Management.Configuration.Projection\\net8.0-windows10.0.26100.0\\Microsoft.Management.Configuration.Projection.dll\r\n      TargetFolder: $(buildOutDirAnyCpu)\\PowerShell\\Microsoft.WinGet.Configuration\\SharedDependencies\\$(BuildPlatform)\r\n      flattenFolders: true\r\n\r\n  - task: CopyFiles@2\r\n    displayName: 'Copy Microsoft.WinGet.UnitTests AnyCPU Files'\r\n    inputs:\r\n      SourceFolder: '$(buildOutDirAnyCpu)\\Microsoft.WinGet.UnitTests\\net8.0-windows10.0.26100.0'\r\n      TargetFolder: '$(artifactsDir)\\Microsoft.WinGet.UnitTests\\'\r\n      CleanTargetFolder: true\r\n      OverWrite: true\r\n\r\n  - task: CopyFiles@2\r\n    displayName: 'Copy PowerShell AnyCPU Module Files'\r\n    inputs:\r\n      SourceFolder: '$(buildOutDirAnyCpu)\\PowerShell'\r\n      TargetFolder: '$(artifactsDir)\\PowerShell'\r\n\r\n  - task: CopyFiles@2\r\n    displayName: 'Copy binaries'\r\n    inputs:\r\n      SourceFolder: '$(buildOutDir)'\r\n      TargetFolder: '$(artifactsDir)'\r\n      Contents: |\r\n        AppInstallerCLIE2ETests\\**\r\n        AppInstallerCLITests\\**\r\n        ComInprocTestbed\\**\r\n        Microsoft.Management.Configuration\\**\r\n        Microsoft.Management.Configuration.UnitTests\\**\r\n        Microsoft.Management.Configuration.OutOfProc\\**\r\n\r\n  - task: CopyFiles@2\r\n    displayName: 'Copy Files: WinGetUtilInterop.UnitTests'\r\n    inputs:\r\n      SourceFolder: '$(Build.SourcesDirectory)\\src\\WinGetUtilInterop.UnitTests\\bin\\$(buildPlatform)\\$(BuildConfiguration)\\net8.0'\r\n      TargetFolder:  '$(artifactsDir)\\WinGetUtilInterop.UnitTests\\'\r\n      CleanTargetFolder: true\r\n      OverWrite: true\r\n\r\n  - task: CopyFiles@2\r\n    displayName: 'Copy WinGetUtil to WinGetUtilInterop.UnitTests folder'\r\n    inputs:\r\n      Contents: |\r\n          $(buildOutDir)\\WinGetUtil\\WinGetUtil.dll\r\n      TargetFolder: '$(artifactsDir)\\WinGetUtilInterop.UnitTests\\'\r\n      flattenFolders: true\r\n\r\n  - task: CopyFiles@2\r\n    displayName: 'Copy LocalhostWebServer to E2ETests'\r\n    inputs:\r\n      SourceFolder: '$(buildOutDir)\\LocalhostWebServer'\r\n      TargetFolder: '$(artifactsDir)\\E2ETests\\LocalhostWebServer'\r\n\r\n    # Invoke E2E setup to generate the TestLocalIndex; could optimize out some of its steps if needed\r\n  - template: templates/e2e-setup.yml\r\n    parameters:\r\n      sourceDir: $(Build.SourcesDirectory)\r\n      localhostWebServerArgs: '-BuildRoot $(artifactsDir)\\E2ETests\\LocalhostWebServer -StaticFileRoot $(Agent.TempDirectory)\\TestLocalIndex -LocalSourceJson $(Build.SourcesDirectory)\\src\\AppInstallerCLIE2ETests\\TestData\\localsource.json -TestDataPath $(Build.SourcesDirectory)\\src\\AppInstallerCLIE2ETests\\TestData -ExitBeforeRun'\r\n      signingCertOutDir: $(artifactsDir)\\E2ETests\r\n\r\n  - task: CopyFiles@2\r\n    displayName: 'Copy TestLocalIndex'\r\n    inputs:\r\n      SourceFolder: '$(Agent.TempDirectory)\\TestLocalIndex'\r\n      TargetFolder: '$(artifactsDir)\\E2ETests\\TestLocalIndex'\r\n\r\n  - task: CopyFiles@2\r\n    displayName: 'Copy TestData'\r\n    inputs:\r\n      SourceFolder: '$(Build.SourcesDirectory)\\src\\AppInstallerCLIE2ETests\\TestData\\'\r\n      TargetFolder: '$(artifactsDir)\\E2ETests\\TestData'\r\n\r\n  - task: CopyFiles@2\r\n    displayName: 'Copy Dev Package Dependencies'\r\n    inputs:\r\n      SourceFolder: '$(appxPackageDir)\\AppInstallerCLIPackage_0.0.2.0_Test\\Dependencies\\$(buildPlatform)\\'\r\n      TargetFolder: '$(artifactsDir)\\E2ETests\\DevPackageDependencies'\r\n\r\n  - task: CopyFiles@2\r\n    displayName: 'Copy test scripts to artifacts'\r\n    inputs:\r\n      Contents: |\r\n          $(Build.SourcesDirectory)\\src\\PowerShell\\scripts\\Execute-WinGetTests.ps1\r\n          $(Build.SourcesDirectory)\\src\\PowerShell\\tests\\**\r\n          $(Build.SourcesDirectory)\\src\\LocalhostWebServer\\Run-LocalhostWebServer.ps1\r\n      TargetFolder: '$(artifactsDir)\\E2ETests\\Scripts'\r\n      flattenFolders: true\r\n\r\n  - task: PublishPipelineArtifact@1\r\n    displayName: Publish Pipeline Artifacts\r\n    inputs:\r\n      targetPath: '$(artifactsDir)'\r\n      artifact: 'Build.$(artifactIdentifier)'\r\n    condition: succeededOrFailed()\r\n\r\n  - task: ComponentGovernanceComponentDetection@0\r\n    displayName: Component Governance\r\n    inputs:\r\n      scanType: 'Register'\r\n      verbosity: 'Verbose'\r\n      alertWarningLevel: 'High'\r\n\r\n# Test job runs tests using build artifacts\r\n\r\n- job: 'Test'\r\n  timeoutInMinutes: 120\r\n  dependsOn: 'Build'\r\n  condition: succeeded('Build')\r\n\r\n  strategy:\r\n    matrix:\r\n      x86_release:\r\n        buildConfiguration: 'Release'\r\n        buildPlatform: 'x86'\r\n        artifactIdentifier: 'x86release'\r\n      x64_release:\r\n        buildConfiguration: 'Release'\r\n        buildPlatform: 'x64'\r\n        artifactIdentifier: 'x64release'\r\n\r\n  variables:\r\n    buildOutDir: $(Pipeline.Workspace)\\Build.$(artifactIdentifier)\r\n    artifactsDir: $(Build.ArtifactStagingDirectory)\r\n    packageLayoutDir: $(Pipeline.Workspace)\\Build.$(artifactIdentifier)\\DevPackage\r\n\r\n  steps:\r\n  - task: DownloadPipelineArtifact@2\r\n    displayName: 'Download Build Artifacts'\r\n    inputs:\r\n      artifact: 'Build.$(artifactIdentifier)'\r\n      path: '$(buildOutDir)'\r\n\r\n  - task: PowerShell@2\r\n    displayName: Install Tests Dependencies\r\n    inputs:\r\n      targetType: 'inline'\r\n      script: |\r\n        Get-ChildItem $(buildOutDir)\\E2ETests\\DevPackageDependencies -Filter *.appx | %{ Add-AppxPackage $_.FullName }\r\n\r\n  - task: VisualStudioTestPlatformInstaller@1\r\n    displayName: Prepare VSTest for E2E Tests\r\n    inputs:\r\n      packageFeedSelector: 'nugetOrg'\r\n\r\n  - task: CmdLine@2\r\n    displayName: Start HAM trace\r\n    condition: and(succeededOrFailed(), eq(variables['System.debug'], true))\r\n    inputs:\r\n      script: 'wpr -start $(Build.SourcesDirectory)\\tools\\HAMTrace\\WER.HostActivityManager.wprp -filemode'\r\n\r\n  - powershell: |\r\n      Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force\r\n      Install-Module Microsoft.WinGet.Client -Repository PSGallery -Force\r\n      try { Repair-WingetPackageManager -Latest -Verbose } catch { $_.Exception }\r\n      Install-WinGetPackage -Id Microsoft.Sysinternals.PsTools -Source winget\r\n    displayName: Install Sysinternals PsTools Using Winget\r\n    condition: succeededOrFailed()\r\n\r\n  - task: CmdLine@2\r\n    displayName: Complete HAM trace\r\n    condition: and(succeededOrFailed(), eq(variables['System.debug'], true))\r\n    inputs:\r\n      script: 'wpr -stop \"$(artifactsDir)\\HamTrace.etl\"'\r\n\r\n  - pwsh: |\r\n      $env:Path = [System.Environment]::GetEnvironmentVariable(\"Path\",\"Machine\") + \";\" + [System.Environment]::GetEnvironmentVariable(\"Path\",\"User\")\r\n      PsExec -accepteula -s -i $(buildOutDir)\\AppInstallerCLITests\\AppInstallerCLITests.exe -logto $(artifactsDir)\\AICLI-Unpackaged-System.log -mdmpto $(artifactsDir)\\AICLI-Unpackaged-System.mdmp -s -r junit -o $(artifactsDir)\\TEST-AppInstallerCLI-Unpackaged-System.xml\r\n    displayName: Run Unit Tests Unpackaged Under System Context\r\n    workingDirectory: '$(buildOutDir)\\AppInstallerCLITests'\r\n    condition: succeededOrFailed()\r\n\r\n  - powershell: |\r\n      Uninstall-WinGetPackage -Id Microsoft.Sysinternals.PsTools -Source winget\r\n    displayName: Clean up Sysinternals PsTools\r\n    condition: succeededOrFailed()\r\n\r\n  - task: PowerShell@2\r\n    displayName: Run Unit Tests Packaged\r\n    inputs:\r\n      filePath: 'src\\AppInstallerCLITests\\Run-TestsInPackage.ps1'\r\n      arguments: '-Args \"~[pips]\" -BuildRoot $(buildOutDir) -PackageRoot $(packageLayoutDir) -LogTarget $(artifactsDir)\\AICLI-Packaged.log -MdmpTarget $(artifactsDir)\\AICLI-Packaged.mdmp -TestResultsTarget $(artifactsDir)\\TEST-AppInstallerCLI-Packaged.xml -ScriptWait'\r\n      workingDirectory: 'src'\r\n    condition: succeededOrFailed()\r\n\r\n  - task: PublishTestResults@2\r\n    displayName: Publish Unit Test Results\r\n    inputs:\r\n      testResultsFormat: 'JUnit'\r\n      testResultsFiles: '$(artifactsDir)\\TEST-*.xml'\r\n      failTaskOnFailedTests: true\r\n    condition: succeededOrFailed()\r\n\r\n  - task: PowerShell@2\r\n    displayName: 'Set program files directory'\r\n    inputs:\r\n      targetType: 'inline'\r\n      script: |\r\n        if (\"$(buildPlatform)\" -eq \"x86\") {\r\n          Write-Host \"##vso[task.setvariable variable=platformProgramFiles;]${env:ProgramFiles(x86)}\"\r\n        } else {\r\n          Write-Host \"##vso[task.setvariable variable=platformProgramFiles;]${env:ProgramFiles}\"\r\n        }\r\n    condition: succeededOrFailed()\r\n\r\n  # Resolves resource strings utilized by InProc E2E tests.\r\n  - task: CopyFiles@2\r\n    displayName: 'Copy resources.pri to dotnet directory'\r\n    inputs:\r\n      SourceFolder: '$(buildOutDir)\\DevPackage'\r\n      TargetFolder:  '$(platformProgramFiles)\\dotnet'\r\n      Contents: resources.pri\r\n    condition: succeededOrFailed()\r\n\r\n  # Winmd accessed by test runner process (dotnet.exe)\r\n  - task: CopyFiles@2\r\n    displayName: 'Copy winmd to dotnet directory'\r\n    inputs:\r\n      SourceFolder: '$(buildOutDir)\\DevPackage'\r\n      TargetFolder: '$(platformProgramFiles)\\dotnet'\r\n      Contents: Microsoft.Management.Deployment.winmd\r\n    condition: succeededOrFailed()\r\n\r\n  - template: templates/e2e-setup.yml\r\n    parameters:\r\n      sourceDir: $(Build.SourcesDirectory)\r\n      localhostWebServerArgs: '-BuildRoot $(buildOutDir)\\E2ETests\\LocalhostWebServer -StaticFileRoot $(buildOutDir)\\E2ETests\\TestLocalIndex -SourceCert $(buildOutDir)\\E2ETests\\TestSigningCert.cer'\r\n\r\n  - template: templates/e2e-test.template.yml\r\n    parameters:\r\n      title: \"E2E Tests Packaged\"\r\n      isPackaged: true\r\n      filter: \"TestCategory!=InProcess&TestCategory!=OutOfProcess\"\r\n\r\n  - template: templates/e2e-test.template.yml\r\n    parameters:\r\n      title: \"Microsoft.Management.Deployment E2E Tests (In-process)\"\r\n      isPackaged: false\r\n      filter: \"TestCategory=InProcess\"\r\n\r\n  - template: templates/e2e-test.template.yml\r\n    parameters:\r\n      title: \"Microsoft.Management.Deployment E2E Tests (Out-of-process)\"\r\n      isPackaged: true\r\n      filter: \"TestCategory=OutOfProcess\"\r\n\r\n  - task: CopyFiles@2\r\n    displayName: 'Copy E2E Tests Package Log to artifacts folder'\r\n    inputs:\r\n      SourceFolder: '$(temp)\\E2ETestLogs'\r\n      TargetFolder: '$(artifactsDir)\\PackagedLog'\r\n    condition: succeededOrFailed()\r\n\r\n  - task: VSTest@2\r\n    displayName: 'Run tests: Microsoft.WinGet.UnitTests'\r\n    inputs:\r\n      testSelector: 'testAssemblies'\r\n      testAssemblyVer2: 'Microsoft.WinGet.UnitTests.dll'\r\n      searchFolder: '$(buildOutDir)\\Microsoft.WinGet.UnitTests'\r\n      codeCoverageEnabled: true\r\n      platform: '$(buildPlatform)'\r\n      configuration: '$(BuildConfiguration)'\r\n      diagnosticsEnabled: true\r\n    condition: succeededOrFailed()\r\n\r\n  - task: VSTest@2\r\n    displayName: 'Run tests: WinGetUtilInterop.UnitTests'\r\n    inputs:\r\n      testSelector: 'testAssemblies'\r\n      testAssemblyVer2: 'WinGetUtilInterop.UnitTests.dll'\r\n      searchFolder: '$(buildOutDir)\\WinGetUtilInterop.UnitTests'\r\n      codeCoverageEnabled: true\r\n      platform: '$(buildPlatform)'\r\n      configuration: '$(BuildConfiguration)'\r\n      diagnosticsEnabled: true\r\n    condition: succeededOrFailed()\r\n\r\n  - task: VSTest@2\r\n    displayName: 'Run tests: Microsoft.Management.Configuration.UnitTests (InProc)'\r\n    inputs:\r\n      testRunTitle: Microsoft.Management.Configuration.UnitTests (InProc)\r\n      testSelector: 'testAssemblies'\r\n      testAssemblyVer2: '**\\Microsoft.Management.Configuration.UnitTests.dll'\r\n      searchFolder: '$(buildOutDir)\\Microsoft.Management.Configuration.UnitTests'\r\n      testFiltercriteria: 'Category=InProc'\r\n      codeCoverageEnabled: false\r\n      platform: '$(buildPlatform)'\r\n      configuration: '$(BuildConfiguration)'\r\n      diagnosticsEnabled: true\r\n    condition: succeededOrFailed()\r\n\r\n  - task: PowerShell@2\r\n    displayName: Prepare for Microsoft.Management.Configuration.UnitTests (OutOfProc)\r\n    inputs:\r\n      filePath: 'src\\Microsoft.Management.Configuration.OutOfProc\\Prepare-ConfigurationOOPTests.ps1'\r\n      arguments: '-BuildOutputPath $(buildOutDir) -PackageLayoutPath $(packageLayoutDir)'\r\n    condition: succeededOrFailed()\r\n\r\n  - task: VSTest@2\r\n    displayName: 'Run tests: Microsoft.Management.Configuration.UnitTests (OutOfProc)'\r\n    inputs:\r\n      testRunTitle: Microsoft.Management.Configuration.UnitTests (OutOfProc)\r\n      testSelector: 'testAssemblies'\r\n      testAssemblyVer2: '**\\Microsoft.Management.Configuration.UnitTests.dll'\r\n      searchFolder: '$(buildOutDir)\\Microsoft.Management.Configuration.UnitTests'\r\n      testFiltercriteria: 'Category=OutOfProc'\r\n      codeCoverageEnabled: true\r\n      platform: '$(buildPlatform)'\r\n      configuration: '$(BuildConfiguration)'\r\n    condition: succeededOrFailed()\r\n\r\n  - task: PowerShell@2\r\n    displayName: Collect logs for Microsoft.Management.Configuration.UnitTests (OutOfProc)\r\n    inputs:\r\n      filePath: 'src\\Microsoft.Management.Configuration.OutOfProc\\Collect-ConfigurationOOPTests.ps1'\r\n      arguments: '-TargetLocation $(artifactsDir)\\ConfigOOPTestsLog'\r\n    condition: succeededOrFailed()\r\n\r\n  - powershell: Get-Process LocalhostWebServer | Stop-Process\r\n    displayName: Stop LocalhostWebServer\r\n    condition: succeededOrFailed()\r\n    \r\n  - task: PowerShell@2\r\n    displayName: 'Copy GA WinGet Log to artifacts folder'\r\n    inputs:\r\n      targetType: 'inline'\r\n      script: |\r\n        $source = \"$env:LocalAppData\\Packages\\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\\LocalState\\DiagOutputDir\"\r\n        $destination = \"$(artifactsDir)\\GA_WinGet_Logs\"\r\n        if (Test-Path $source) {\r\n          Copy-Item -Path $source -Destination $destination -Recurse -Force\r\n        } else {\r\n          Write-Host \"WinGet logs not found at $source\"\r\n        }\r\n    condition: succeededOrFailed()\r\n\r\n  - task: PowerShell@2\r\n    displayName: 'Copy Application Event Logs to Artifacts'\r\n    inputs:\r\n      targetType: 'inline'\r\n      script: |\r\n        $source = \"$env:SystemRoot\\System32\\winevt\\Logs\\Application.evtx\"\r\n        $destination = \"$(artifactsDir)\\Application.evtx\"\r\n        if (Test-Path $source) {\r\n          Copy-Item -Path $source -Destination $destination -Force\r\n        } else {\r\n          Write-Host \"Application event log not found at $source\"\r\n        }\r\n    condition: succeededOrFailed()\r\n\r\n  - task: PublishPipelineArtifact@1\r\n    displayName: Publish Pipeline Artifacts\r\n    inputs:\r\n      targetPath: '$(artifactsDir)'\r\n      artifact: 'Test.$(artifactIdentifier).$(System.JobAttempt)'\r\n    condition: succeededOrFailed()\r\n\r\n# Build and test PowerShell module\r\n\r\n- job: 'BuildPowerShellModule'\r\n  timeoutInMinutes: 120\r\n  dependsOn: 'Build'\r\n  condition: succeeded('Build')\r\n  variables:\r\n    buildOutDir: $(Pipeline.Workspace)\\Build.x64Release\r\n\r\n  steps:\r\n  - task: DownloadPipelineArtifact@2\r\n    displayName: 'Download Build Artifacts'\r\n\r\n  - task: CopyFiles@2\r\n    displayName: 'Copy x64 PowerShell Binaries to Output'\r\n    inputs:\r\n      SourceFolder: '$(buildOutDir)\\PowerShell'\r\n      Contents: '**\\*'\r\n      TargetFolder: '$(Build.ArtifactStagingDirectory)'\r\n\r\n  - task: CopyFiles@2\r\n    displayName: 'Copy x86 PowerShell Binaries to Output'\r\n    inputs:\r\n      SourceFolder: '$(Pipeline.Workspace)\\Build.x86release\\PowerShell'\r\n      Contents: '**\\*'\r\n      TargetFolder: '$(Build.ArtifactStagingDirectory)'\r\n\r\n  - task: PowerShell@2\r\n    displayName: Generate Microsoft.WinGet.Client Help Documentation\r\n    inputs:\r\n      pwsh: true\r\n      targetType: inline\r\n      script: |\r\n        Install-Module -Name platyPS -Force\r\n        Import-Module platyPS\r\n        New-ExternalHelp -Path '$(Build.SourcesDirectory)\\src\\PowerShell\\Help\\Microsoft.WinGet.Client' -OutputPath '$(Build.ArtifactStagingDirectory)\\Microsoft.WinGet.Client'\r\n\r\n  - task: CopyFiles@2\r\n    displayName: 'Copy Microsoft.WinGet.DSC module to staging directory'\r\n    inputs:\r\n      SourceFolder: '$(Build.SourcesDirectory)\\src\\PowerShell\\Microsoft.WinGet.DSC'\r\n      Contents: '**\\*'\r\n      TargetFolder: '$(Build.ArtifactStagingDirectory)\\Microsoft.WinGet.DSC'\r\n\r\n  - task: PowerShell@2\r\n    displayName: Install Tests Dependencies\r\n    inputs:\r\n      targetType: 'inline'\r\n      script: |\r\n        Get-ChildItem AppxPackages\\AppInstallerCLIPackage_0.0.2.0_Test\\Dependencies\\x64 -Filter *.appx | %{ Add-AppxPackage $_.FullName }\r\n      workingDirectory: $(buildOutDir)\r\n\r\n  - template: templates/e2e-setup.yml\r\n    parameters:\r\n      sourceDir: $(Build.SourcesDirectory)\r\n      localhostWebServerArgs: '-BuildRoot $(buildOutDir)\\E2ETests\\LocalhostWebServer -StaticFileRoot $(buildOutDir)\\E2ETests\\TestLocalIndex -SourceCert $(buildOutDir)\\E2ETests\\TestSigningCert.cer'\r\n\r\n  - pwsh: .\\RunTests.ps1 -testModulesPath $(Build.ArtifactStagingDirectory) -outputPath $(Pipeline.Workspace)\\PesterTest -packageLayoutPath $(buildOutDir)\\DevPackage\r\n    workingDirectory: $(Build.SourcesDirectory)\\src\\PowerShell\\tests\\\r\n    displayName: Run PowerShell 7 Tests\r\n\r\n  - powershell: .\\RunTests.ps1 -testModulesPath $(Build.ArtifactStagingDirectory) -outputPath $(Pipeline.Workspace)\\WPPesterTest\r\n    workingDirectory: $(Build.SourcesDirectory)\\src\\PowerShell\\tests\\\r\n    displayName: Run Windows PowerShell Tests\r\n    condition: succeededOrFailed()\r\n\r\n  - powershell: Get-Process LocalhostWebServer | Stop-Process\r\n    displayName: Stop LocalhostWebServer\r\n    condition: succeededOrFailed()\r\n\r\n  - task: PublishTestResults@2\r\n    displayName: Publish Pester Test Results PowerShell 7\r\n    inputs:\r\n      testResultsFormat: 'NUnit'\r\n      testResultsFiles: '$(Pipeline.Workspace)\\PesterTest\\Test*.xml'\r\n      failTaskOnFailedTests: true\r\n    condition: succeededOrFailed()\r\n\r\n  - task: PublishTestResults@2\r\n    displayName: Publish Pester Test Results Windows PowerShell\r\n    inputs:\r\n      testResultsFormat: 'NUnit'\r\n      testResultsFiles: '$(Pipeline.Workspace)\\WPPesterTest\\Test*.xml'\r\n      failTaskOnFailedTests: true\r\n    condition: succeededOrFailed()\r\n\r\n  - task: PowerShell@2\r\n    displayName: Copy WinGet Logs\r\n    inputs:\r\n      pwsh: true\r\n      targetType: inline\r\n      script: |\r\n        $sourceDir = Join-Path $env:LocalAppData Packages\\WinGetDevCLI_8wekyb3d8bbwe\\LocalState\\DiagOutputDir\r\n        $destinationDir = Join-Path $(Build.ArtifactStagingDirectory) WinGetLogs\r\n        Copy-Item -Path $sourceDir -Destination $destinationDir -Recurse -Force\r\n    condition: succeededOrFailed()\r\n\r\n  - task: PublishPipelineArtifact@1\r\n    displayName: Publish PowerShell Module Artifacts\r\n    inputs:\r\n      targetPath: '$(Build.ArtifactStagingDirectory)'\r\n    condition: succeededOrFailed()\r\n\r\n- job: 'Fuzzing'\r\n  timeoutInMinutes: 60\r\n  condition: not(eq(variables['Build.Reason'], 'PullRequest'))\r\n\r\n  strategy:\r\n    matrix:\r\n      x64:\r\n        buildConfiguration: 'Fuzzing'\r\n        buildPlatform: 'x64'\r\n\r\n  variables:\r\n    buildOutDir: $(Build.SourcesDirectory)\\src\\$(buildPlatform)\\$(buildConfiguration)\r\n    artifactsDir: $(Build.ArtifactStagingDirectory)\\$(buildPlatform)\r\n\r\n  steps:\r\n  - task: NuGetToolInstaller@1\r\n    displayName: Install Nuget\r\n\r\n  - task: NuGetCommand@2\r\n    displayName: Restore Solution\r\n    inputs:\r\n      restoreSolution: '$(solution)'\r\n\r\n  - task: CmdLine@2\r\n    displayName: Enable Vcpkg Install\r\n    inputs:\r\n      script: |\r\n        $(VCPKG_INSTALLATION_ROOT)\\vcpkg.exe integrate install\r\n      workingDirectory: '$(VCPKG_INSTALLATION_ROOT)'\r\n\r\n  - task: VSBuild@1\r\n    displayName: Build Fuzzing Artifacts\r\n    inputs:\r\n      platform: '$(buildPlatform)'\r\n      solution: '$(solution)'\r\n      configuration: '$(buildConfiguration)'\r\n      msbuildArgs: '/bl:$(artifactsDir)\\msbuild.binlog'\r\n      maximumCpuCount: true\r\n\r\n  - task: CopyFiles@2\r\n    displayName: Copy vcpkg logs\r\n    inputs:\r\n      SourceFolder: $(VCPKG_INSTALLATION_ROOT)\\buildtrees\r\n      Contents: '**\\*.log'\r\n      TargetFolder: '$(artifactsDir)\\vcpkgLogs'\r\n    condition: succeededOrFailed()\r\n\r\n  - task: CopyFiles@2\r\n    displayName: Copy Fuzzing Artifacts for Publishing\r\n    inputs:\r\n      SourceFolder: '$(buildOutDir)\\WinGetYamlFuzzing'\r\n      Contents: '**'\r\n      TargetFolder: '$(artifactsDir)'\r\n\r\n  - task: PublishPipelineArtifact@1\r\n    displayName: Publish Fuzzing Artifacts\r\n    inputs:\r\n      targetPath: '$(artifactsDir)'\r\n    condition: succeededOrFailed()\r\n\r\n  - task: onefuzz-task@0\r\n    inputs:\r\n      onefuzzOSes: 'Windows'\r\n    env:\r\n      onefuzzDropDirectory: '$(buildOutDir)\\WinGetYamlFuzzing'\r\n      SYSTEM_ACCESSTOKEN: $(System.AccessToken)\r\n"
  },
  {
    "path": "cgmanifest.json",
    "content": "{\r\n  \"$schema\": \"https://json.schemastore.org/component-detection-manifest.json\",\r\n  \"Registrations\": [\r\n    {\r\n      \"component\": {\r\n        \"type\": \"git\",\r\n        \"git\": {\r\n          \"repositoryUrl\": \"https://github.com/microsoft/cpprestsdk.git\",\r\n          \"commitHash\": \"411a109150b270f23c8c97fa4ec9a0a4a98cdecf\"\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"component\": {\r\n        \"type\": \"git\",\r\n        \"git\": {\r\n          \"repositoryUrl\": \"https://github.com/ronomon/pure.git\",\r\n          \"commitHash\": \"fd54913e65338e678440ae66b3b5022ab23b761b\"\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"component\": {\r\n        \"type\": \"git\",\r\n        \"git\": {\r\n          \"repositoryUrl\": \"https://github.com/microsoft/xlang\",\r\n          \"commitHash\": \"cfe510d0d2b07484fea2c6d77163de017738c100\"\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"component\": {\r\n        \"type\": \"git\",\r\n        \"git\": {\r\n          \"repositoryUrl\": \"https://github.com/microsoft/sfs-client.git\",\r\n          \"commitHash\": \"ff315ecfa2ef2953d8a808e51e8a61a4e0759180\"\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"component\": {\r\n        \"type\": \"git\",\r\n        \"git\": {\r\n          \"repositoryUrl\": \"https://github.com/yaml/libyaml.git\",\r\n          \"commitHash\": \"840b65c40675e2d06bf40405ad3f12dec7f35923\"\r\n        }\r\n      }\r\n    }\r\n  ],\r\n  \"Version\": 1\r\n}\r\n"
  },
  {
    "path": "doc/Completion.md",
    "content": "﻿# WinGet Command Line Tab Completion\n\nWinGet offers a `complete` command that can be leveraged by your shell to provide context sensitive tab completion. It allows for completion of command names, argument names, and argument values, dependent on the current command line state.\n\n> Note, this feature was released in [v0.1.42241 Preview](https://github.com/microsoft/winget-cli/releases/tag/v0.1.42241-preview). Please update if you are on an older build.\n\n## Examples\n\n> These examples assume that the tab completion in your shell works similar to PowerShell; repeated presses of tab (`⇥`) will result in cycling through the possible values.\n\nInput | Result | Reason\n--- | --- | ---\n`winget ⇥` | `winget install` | `install` is the first command below the root\n`winget sh⇥` | `winget show` | `show` is the first command that starts with `sh`\n`winget source l⇥` | `winget source list` | `list` is the first sub-command of source that starts with `l`\n`winget -⇥` | `winget --version` | `--version` is the first argument defined for the root\n`winget install power⇥` | `winget install \"Power Toys\"` | `\"Power Toys\"` is the first package whose Id, Name, or Moniker starts with `power`\n`winget install \"Power Toys\" --version ⇥` | `winget install \"Power Toys\" --version 0.19.2` | `0.19.2` is the highest version of Power Toys at the time of writing\n\n## PowerShell\n\nYou can add the argument completer to your `$PROFILE`, which will enable it in all subsequent PowerShell sessions.\nFor more information, see [How to create your profile](https://docs.microsoft.com/powershell/module/microsoft.powershell.core/about/about_profiles#how-to-create-a-profile) and [Profiles and execution policy](https://docs.microsoft.com/powershell/module/microsoft.powershell.core/about/about_profiles#profiles-and-execution-policy).\n\nHere is the PowerShell command to add to your `$PROFILE`:\n\n```PowerShell\nRegister-ArgumentCompleter -Native -CommandName winget -ScriptBlock {\n    param($wordToComplete, $commandAst, $cursorPosition)\n        [Console]::InputEncoding = [Console]::OutputEncoding = $OutputEncoding = [System.Text.Utf8Encoding]::new()\n        $Local:word = $wordToComplete.Replace('\"', '\"\"')\n        $Local:ast = $commandAst.ToString().Replace('\"', '\"\"')\n        winget complete --word=\"$Local:word\" --commandline \"$Local:ast\" --position $cursorPosition | ForEach-Object {\n            [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)\n        }\n}\n```\n\n## Command Reference\n\nThe complete command takes 3 required arguments:\n\nArgument | Description\n--- | ---\n`--word` | The current word that is being completed; the token that the cursor is located within. Can be empty to indicate no current value at the cursor, but if provided, it must appear as a substring in the command line.\n`--commandline` | The entire current command line, including `winget`. See the examples above; everything but the tab character (`⇥`) should be provided to this argument.\n`--position` | The current position of the cursor in the command line. Can be greater than the length of the command line string to indicate at the end.\n\nWhen a word value is provided, the completion operates in replacement mode.  It will suggest completions that would fit correctly at this location that also start with the given word value.\n\nWhen a word value is not provided (an empty value is provided for word, ex. `--word=`), the completion operates in insertion mode.  It will suggest completions that would fit as a new value in the cursor's location.\n\nBased on the arguments, the completions suggested can be one of:\n1. A sub command :: The cursor is located just after a command and there are sub commands available.\n2. An argument specifier :: The cursor is not positioned after an argument specifier that expects a value, and there are arguments available.\n3. An argument value :: The cursor is positioned after an argument specifier that expects a value, or a positional argument is expected.\n\nAfter evaluating all of these cases, the potential completions are output, one on each line. If the completion string contains a space, it is wrapped in quotations.\n"
  },
  {
    "path": "doc/Developing.md",
    "content": "# Developer guidance\n\n## Prerequisites\n\n* Windows 10 1809 (17763) or later\n* [Developer Mode enabled](https://docs.microsoft.com/windows/uwp/get-started/enable-your-device-for-development)\n* [Visual Studio 2022](https://visualstudio.microsoft.com/downloads/)\n  * Or use WinGet to install it ;) (although you may need to adjust the workloads via Tools->Get Tools and Features...)\n* The following workloads:\n  * .NET Desktop Development\n  * Desktop Development with C++\n  * Universal Windows Platform Development\n  * Check [.vsconfig file](../.vsconfig) for full components list\n\n* [Windows SDK for Windows 11 (10.0.26100)](https://developer.microsoft.com/en-us/windows/downloads/sdk-archive/)\n\n> [!NOTE]\n> You can also get it through `winget install Microsoft.WindowsSDK.10.0.26100` or via Visual Studio > Get Tools and Features > Individual Components > Windows 10 SDK (10.0.26100.0)\n\n* The following extensions:\n\n  * [Microsoft Visual Studio Installer Projects](https://marketplace.visualstudio.com/items?itemName=VisualStudioClient.MicrosoftVisualStudio2022InstallerProjects)\n\n## Building the client\n\n1. Clone the repository\n2. Configure your system using the [configuration file](../.config/configuration.winget) in the repository. Run one of the following configurations from the project root so relative paths resolve correctly:\n   - For VS Community: `winget configure .config/configuration.winget`\n   - For VS Professional: `winget configure .config/configuration.vsProfessional.winget`\n   - For VS Enterprise: `winget configure .config/configuration.vsEnterprise.winget`\n3. Run `vcpkg integrate install` from the Developer Command Prompt / Developer PowerShell for VS 2022. This is a one-time setup step until the configuration file in step 2 is updated to work with vcpkg setup.\n\nOpen `winget-cli\\src\\AppInstallerCLI.sln` in Visual Studio and build. We currently only build using the solution; command-line methods of building a VS solution should work as well.\n\n## Running and Debugging\n\nAfter the build finishes, deploy the solution from Build > Deploy Solution. You can then run the client from the command line using `wingetdev`.\n\nTo enable step-through debugging, right click on `AppInstallerCLIPackage` in the Solution Explorer, select Properties, and navigate to the Debug tab. In the Debugger type selection, change \"Application process\" and \"Background task process\" to \"Native Only\". This will allow you to add breakpoints and step through the code. The main entry point for the client is in `src/AppInstallerCLI/main.cpp`\n\nThe best way to debug the client is to select `Do not launch, but debug my code when it starts` in the `Debug` tab and start the debugging session with <kbd>F5</kbd>. You can then use the `wingetdev` command in a terminal session, or any PowerShell code for COM API interaction, which will get picked up by the debugger.\n\n## Running Unit Tests\n\nThe unit tests are located inside the `AppInstallerCLITests` project. When the solution is built, all tests are compiled under `src/<ARCHITECTURE>/<Debug|Release>/AppInstallerCLITests`. An executable `AppInstallerCLITests.exe` is generated in this directory to run the tests. Run `AppInstallerCLITests.exe` from the command line to execute the tests. To see all available options, run `AppInstallerCLITests.exe --help`.\n\n> [!TIP]\n> If you just want to run a particular test, you can specify the test name as an argument to the executable. For example, `AppInstallerCLITests.exe EnsureSortedErrorList`.\n"
  },
  {
    "path": "doc/ReleaseNotes.md",
    "content": "## New in v1.29\n\n# New Feature: Source Priority\n\n> [!NOTE]\n> Experimental under `sourcePriority`; defaulted to disabled.\n\nWith this feature, one can assign a numerical priority to sources when added or later through the `source edit`\ncommand. Sources with higher priority are sorted first in the list of sources, which results in them getting put first\nin the results if other things are equal.\n\n> [!TIP]\n> Search result ordering in winget is currently based on these values in this order:\n> 1. Match quality (how well a valid field matches the search request)\n> 2. Match field (which field was matched against the search request)\n> 3. Source order (was always relevant, but with priority you can more easily affect this)\n\nBeyond the ability to slightly affect the result ordering, commands that primarily target available packages\n(largely `install`) will now prefer to use a single result from a source with higher priority rather than prompting for\ndisambiguation from the user. Said another way, if multiple sources return results but only one of those sources has\nthe highest priority value (and it returned only one result) then that package will be used rather than giving a\n\"multiple packages were found\" error. This has been applied to both winget CLI and PowerShell module commands.\n\n### REST result match criteria update\n\nAlong with the source priority change, the results from REST sources (like `msstore`) now attempt to correctly set the\nmatch criteria that factor into the result ordering. This will prevent them from being sorted to the top automatically.\n\n## Minor Features\n\n### --no-progress flag\n\nAdded a new `--no-progress` command-line flag that disables all progress reporting (progress bars and spinners). This flag is universally available on all commands and takes precedence over the `visual.progressBar` setting. Useful for automation scenarios or when running WinGet in environments where progress output is undesirable.\n\n### Authenticated GitHub API requests in PowerShell module\n\nThe PowerShell module now automatically uses `GH_TOKEN` or `GITHUB_TOKEN` environment variables to authenticate GitHub API requests. This significantly increases the GitHub API rate limit, preventing failures in CI/CD pipelines. Use `-Verbose` to see which token is being used.\n\n## Bug Fixes\n\n<!-- Nothing yet! -->\n"
  },
  {
    "path": "doc/Settings.md",
    "content": "# WinGet CLI Settings\n\nYou can configure WinGet by editing the `settings.json` file. Running `winget settings` will open the file in the default json editor; if no editor is configured, Windows will prompt for you to select an editor, and Notepad is a sensible option if you have no other preference.\n\n## File Location\n\nSettings file is located in %LOCALAPPDATA%\\Packages\\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\\LocalState\\settings.json\n\nIf you are using the non-packaged WinGet version by building it from source code, the file will be located under %LOCALAPPDATA%\\Microsoft\\WinGet\\Settings\\settings.json\n\nIf you are creating a settings file from scratch, make sure that the line `\"$schema\": \"https://aka.ms/winget-settings.schema.json\",` is in it.\n\n## Source\n\nThe `source` settings involve configuration to the WinGet source.\n\n```json\n    \"source\": {\n        \"autoUpdateIntervalInMinutes\": 3\n    },\n```\n\n### autoUpdateIntervalInMinutes\n\nA positive integer represents the update interval in minutes. The check for updates only happens when a source is used. A zero will disable the check for updates to a source. Any other values are invalid.\n\n- Disable: 0\n- Default: 15\n\nTo manually update the source use `winget source update`\n\n## Visual\n\nThe `visual` settings involve visual elements that are displayed by WinGet\n\n### progressBar\n\nStyle of the progress spinner and bar that WinGet displays when not specified by arguments. In addition, all options except `disabled` send [Virtual Terminal progress](https://conemu.github.io/en/AnsiEscapeCodes.html#ConEmu_specific_OSC) updates that any supporting terminal may display visually.\n\n> [!NOTE]\n> You can also disable progress output for a single command using the `--no-progress` flag, which takes precedence over this setting.\n\n|Value|Description|Release|\n|---|---|---|\n|`accent` (default)|Use the [Windows Accent color](https://support.microsoft.com/en-us/windows/change-colors-in-windows-d26ef4d6-819a-581c-1581-493cfcc005fe)|1.0|\n|`retro`|Use the current foreground terminal color|1.0|\n|`rainbow`|Progress through a rainbow of colors|1.0|\n|`sixel`|Use sixel images; requires a terminal that supports displaying sixels, such as [Windows Terminal](https://github.com/microsoft/terminal/releases) 1.22.2362 or later|1.9|\n|`disabled`|No progress will be displayed|1.9|\n\n```json\n    \"visual\": {\n        \"progressBar\": \"accent\"\n    },\n```\n\n### anonymizeDisplayedPaths\n\nReplaces some known folder paths with their respective environment variable. Defaults to true.\n\n```json\n    \"visual\": {\n        \"anonymizeDisplayedPaths\": true\n    },\n```\n\n### enableSixels\n\nEnables output of sixel images in certain contexts. Defaults to false.\n\n```json\n    \"visual\": {\n        \"enableSixels\": true\n    },\n```\n\n## Install Behavior\n\nThe `installBehavior` settings affect the default behavior of installing and upgrading (where applicable) packages.\n\n### Disable Install Notes\n\nThe `disableInstallNotes` behavior affects whether installation notes are shown after a successful install. Defaults to `false` if value is not set or is invalid.\n\n```json\n    \"installBehavior\": {\n        \"disableInstallNotes\": true\n    },\n```\n\n### Portable Package User Root\n\nThe `portablePackageUserRoot` setting affects the default root directory where packages are installed to under `User` scope. This setting only applies to packages with the `portable` installer type. Defaults to `%LOCALAPPDATA%/Microsoft/WinGet/Packages/` if value is not set or is invalid.\n\n> Note: This setting value must be an absolute path.\n\n```json\n    \"installBehavior\": {\n        \"portablePackageUserRoot\": \"C:/Users/FooBar/Packages\"\n    },\n```\n\n### Portable Package Machine Root\n\nThe `portablePackageMachineRoot` setting affects the default root directory where packages are installed to under `Machine` scope. This setting only applies to packages with the `portable` installer type. Defaults to `%PROGRAMFILES%/WinGet/Packages/` if value is not set or is invalid.\n\n> Note: This setting value must be an absolute path.\n\n```json\n    \"installBehavior\": {\n        \"portablePackageMachineRoot\": \"C:/Program Files/Packages/Portable\"\n    },\n```\n\n### Skip Dependencies\n\nThe 'skipDependencies' behavior affects whether dependencies are installed for a given package. Defaults to 'false' if value is not set or is invalid.\n\n```json\n    \"installBehavior\": {\n        \"skipDependencies\": true\n    },\n```\n\n### Archive Extraction Method\n\nThe `archiveExtractionMethod` behavior affects how installer archives are extracted. Currently there are two supported values: `Tar` or `ShellApi`.\n`Tar` indicates that the archive should be extracted using the tar executable ('tar.exe') while `shellApi` indicates using the Windows Shell API. Defaults to `shellApi` if value is not set or is invalid.\n\n```json\n    \"installBehavior\": {\n        \"archiveExtractionMethod\": \"tar\" | \"shellApi\"\n    },\n```\n\n### Preferences and Requirements\n\nSome of the settings are duplicated under `preferences` and `requirements`. `preferences` affect how the various available options are sorted when choosing the one to act on.  For instance, the default scope of package installs is for the current user, but if that is not an option then a machine level installer will be chosen. `requirements` filter the options, potentially resulting in an empty list and a failure to install. In the previous example, a user scope requirement would result in no applicable installers and an error.\n\nAny arguments passed on the command line will effectively override the matching `requirement` setting for the duration of that command.\n\n> [!NOTE]\n>\n> - These settings are only applied for the `winget install` command.\n> - Other commands like `winget configure` are not affected by these settings.\n\n### Scope\n\nThe `scope` behavior affects the choice between installing a package for the current user or for the entire machine. The matching parameter is `--scope`, and uses the same values (`user` or `machine`).\n\n```json\n    \"installBehavior\": {\n        \"preferences\": {\n            \"scope\": \"user\"\n        }\n    },\n```\n\n### Locale\n\nThe `locale` behavior affects the choice of installer based on installer locale. The matching parameter is `--locale`, and uses bcp47 language tag.\n\n```json\n    \"installBehavior\": {\n        \"preferences\": {\n            \"locale\": [ \"en-US\", \"fr-FR\" ]\n        }\n    },\n```\n\n### Architectures\n\nThe `architectures` behavior affects what architectures will be selected when installing a package. The matching parameter is `--architecture`. Note that only architectures compatible with your system can be selected.\n\n```json\n    \"installBehavior\": {\n        \"preferences\": {\n            \"architectures\": [\"x64\", \"arm64\"]\n        }\n    },\n```\n\n### Installer Types\n\nThe `installerTypes` behavior affects what installer types will be selected when installing a package. It can also determine which type to install by default if a manifest has multiple types: The list is in priority order, with the first listed type being preferred over the others, and so on.  This is convenient for users who for instance prefer portable packages or MSIX/AppX installations. The matching parameter is `--installer-type`, which will override the settings.\n\nAllowed values as of version 1.12.470 include: `appx`, `burn`, `exe`, `font`, `inno`, `msi`, `msix`, `msstore`, `nullsoft`, `portable`, `wix`, `zip`\n\nBy default, and with all other properties being equal, WinGet defaults to the installer type that is listed first in the manifest's installer YAML if the package has not been installed yet.  If it is already installed, the same installer type will be required to ensure a proper upgrade.\n\n```json\n    \"installBehavior\": {\n        \"preferences\": {\n            \"installerTypes\": [\"msi\", \"msix\"]\n        }\n    },\n```\n\n### Default install root\n\nThe `defaultInstallRoot` affects the install location when a package requires one. This can be overridden by the `--location` parameter. This setting is only used when a package manifest includes `InstallLocationRequired`, and the actual location is obtained by appending the package ID to the root.\n\n```json\n    \"installBehavior\": {\n        \"defaultInstallRoot\": \"C:/installRoot\"\n    },\n```\n\n### Maximum resumes\n\nThe `maxResumes` setting determines the maximum number of times that a command may be resumed automatically. The default value is 3.\n\n```json\n    \"installBehavior\": {\n        \"maxResumes\": 3\n    },\n```\n\n> Note: [The resume behavior is an experimental feature.](#resume)\n\n## Uninstall Behavior\n\nThe `uninstallBehavior` settings affect the default behavior of uninstalling (where applicable) packages.\n\n### Purge Portable Package\n\nThe `purgePortablePackage` behavior affects the default behavior for uninstalling a portable package. If set to `true`, uninstall will remove all files and directories relevant to the `portable` package. This setting only applies to packages with the `portable` installer type. Defaults to `false` if value is not set or is invalid.\n\n```json\n    \"uninstallBehavior\": {\n        \"purgePortablePackage\": true\n    },\n```\n\n## Configure Behavior\n\nThe `configureBehavior` settings affect the default behavior of applying a configuration.\n\n### Default Module Root\n\nThe `defaultModuleRoot` behavior affects the default root directory where modules are installed to. Defaults to `%LOCALAPPDATA%/Microsoft/WinGet/Configuration/Modules` if value is not set or is invalid.\n\n> Note: This setting value must be an absolute path.\n\n```json\n    \"configureBehavior\": {\n        \"defaultModuleRoot\": \"C:/Program Files/Modules/\"\n    },\n```\n\n## Telemetry\n\nThe `telemetry` settings control whether winget writes ETW events that may be sent to Microsoft on a default installation of Windows.\n\nSee [details on telemetry](../README.md#datatelemetry), and our [primary privacy statement](../PRIVACY.md).\n\n### disable\n\n```json\n    \"telemetry\": {\n        \"disable\": true\n    },\n```\n\nIf set to true, the `telemetry.disable` setting will prevent any event from being written by the program.\n\n## Logging\n\nThe `logging` settings control the level of detail in log files.\n\n### level\n\n `--verbose-logs` will override this setting and always creates a verbose log.\nDefaults to `info` if value is not set or is invalid.\n\n```json\n    \"logging\": {\n        \"level\": \"verbose\" | \"info\" | \"warning\" | \"error\" | \"critical\"\n    },\n```\n\n### channels\n\nThe valid values in this array are defined in the function `GetChannelFromName` in the [logging code](../src/AppInstallerSharedLib/AppInstallerLogging.cpp).  These align with the ***channel identifier*** found in the log files.  For example, ***`CORE`*** in:\n\n```plaintext\n2023-12-06 19:17:07.988 [CORE] WinGet, version [1.7.0-preview], activity [{24A91EA8-46BE-47A1-B65C-CEBCE90B8675}]\n```\n\nIn addition, there are special values that cover multiple channels.  `default` is the default set of channels, while `all` is all of the channels.  Invalid values are ignored.\n\n```json\n    \"logging\": {\n        \"channels\": [\"default\"]\n    },\n```\n\n### file\n\nThe `file` settings control the log files generated by winget during operation.  These settings apply to the automatic cleanup that happens whenever a Windows Package Manager process is run.\nThey only apply to the default log location, which contains winget logs, AppInstaller logs (the MSIX install UI), and is the default location where installer logs are placed.\nThe automatic cleanup happens at the beginning of the process, so the log file(s) generated by the current process will not be considered in the limits.\n\n|Setting|Description|Default|Note|\n|---|---|---|---|\n|`ageLimitInDays`|The maximum age, in days, of files in the log directory; older files are deleted.|7 (days)|Set to 0 to disable this limit.|\n|`totalSizeLimitInMB`|The maximum size, in megabytes, of all files in the log directory; the oldest files are deleted first.|128 (MB)|Set to 0 to disable this limit.|\n|`countLimit`|The maximum number of files in the log directory; the oldest files are deleted first.|0|Set to 0 (the default) to disable this limit.|\n\nThese settings apply to the log files that winget writes, only as they are being written.  They do not apply to files written by installers or the AppInstaller UI.\n\n|Setting|Description|Default|Note|\n|---|---|---|---|\n|`individualSizeLimitInMB`|The maximum size, in megabytes, of an individual log file. If a file would exceed this limit, the logs will wrap. Note that this limit is approximate and the actual files may exceed it by a few bytes.|16 (MB)|Set to 0 to disable this limit.|\n\n```json\n    \"logging\": {\n        \"file\": {\n            \"ageLimitInDays\": 7,\n            \"totalSizeLimitInMB\": 128,\n            \"countLimit\": 0,\n            \"individualSizeLimitInMB\": 16,\n        }\n    },\n```\n\n## Network\n\nThe `network` settings influence how winget uses the network to retrieve packages and metadata.\n\n### Downloader\n\nThe `downloader` setting controls which code is used when downloading packages. The default is `default`, which may be any of the options based on our determination.\n`wininet` uses the [WinINet](https://docs.microsoft.com/windows/win32/wininet/about-wininet) APIs, while `do` uses the\n[Delivery Optimization](https://support.microsoft.com/windows/delivery-optimization-in-windows-10-0656e53c-15f2-90de-a87a-a2172c94cf6d) service.\n\nThe `doProgressTimeoutInSeconds` setting updates the number of seconds to wait without progress before fallback. The default number of seconds is 60, minimum is 1 and the maximum is 600.\n\n```json\n   \"network\": {\n       \"downloader\": \"do\",\n       \"doProgressTimeoutInSeconds\": 60\n   }\n```\n\n## Interactivity\n\nThe `interactivity` settings control whether winget may show interactive prompts during execution. Note that this refers only to prompts shown by winget itself and not to those shown by package installers.\n\n### disable\n\n```json\n    \"interactivity\": {\n        \"disable\": true\n    },\n```\n\nIf set to true, the `interactivity.disable` setting will prevent any interactive prompt from being shown.\n\n## Experimental Features\n\nTo allow work to be done and distributed to early adopters for feedback, settings can be used to enable \"experimental\" features.\n\nThe `experimentalFeatures` settings involve the configuration of these \"experimental\" features. Individual features can be enabled under this node. The example below shows sample experimental features.\n\n```json\n   \"experimentalFeatures\": {\n       \"experimentalCmd\": true,\n       \"experimentalArg\": false\n   },\n```\n\n### directMSI\n\nThis feature enables the Windows Package Manager to directly install MSI packages with the MSI APIs rather than through msiexec.\nNote that when silent installation is used this is already in affect, as MSI packages that require elevation will fail in that scenario without it.\nYou can enable the feature as shown below.\n\n```json\n   \"experimentalFeatures\": {\n       \"directMSI\": true\n   },\n```\n\n### resume\n\nThis feature enables support for some commands to resume.\nYou can enable the feature as shown below.\n\n```json\n   \"experimentalFeatures\": {\n       \"resume\": true\n   },\n```\n\n### fonts\n\nThis feature enables support for fonts via `winget settings`. The `winget font list` command will list installed font families and the number of installed font faces.\n\n```json\n  \"experimentalFeatures\": {\n        \"fonts\": true\n  },\n```\n\n### sourcePriority\n\nThis feature enables sources to have a priority value assigned. Sources with a higher priority will appear earlier in search results and will be selected for installing new packages when multiple sources have a matching package.\n\nNote that search result ordering is dependent on several factors, and source priority is the lowest field in that currently (match quality and field are more important).\n\n```json\n  \"experimentalFeatures\": {\n        \"sourcePriority\": true\n  },\n```\n"
  },
  {
    "path": "doc/admx/DesktopAppInstaller.admx",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<!-- Copyright (c) Microsoft Corporation.\r\n     Licensed under the MIT License. -->\r\n<policyDefinitions xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" revision=\"1.0\" schemaVersion=\"1.0\" xmlns=\"http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions\">\r\n  <policyNamespaces>\r\n    <target prefix=\"appinstaller\" namespace=\"Microsoft.Policies.AppInstaller\" />\r\n    <using prefix=\"windows\" namespace=\"Microsoft.Policies.Windows\" />\r\n  </policyNamespaces>\r\n  <resources minRequiredRevision=\"1.0\" />\r\n  <categories>\r\n    <category name=\"AppInstaller\" displayName=\"$(string.AppInstaller)\">\r\n      <parentCategory ref=\"windows:WindowsComponents\" />\r\n    </category>\r\n  </categories>\r\n  <policies>\r\n    <policy name=\"EnableAppInstaller\" class=\"Machine\" displayName=\"$(string.EnableAppInstaller)\" explainText=\"$(string.EnableAppInstallerExplanation)\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\" valueName=\"EnableAppInstaller\">\r\n      <parentCategory ref=\"AppInstaller\" />\r\n      <supportedOn ref=\"windows:SUPPORTED_Windows_10_0_RS5\" />\r\n      <enabledValue>\r\n        <decimal value=\"1\" />\r\n      </enabledValue>\r\n      <disabledValue>\r\n        <decimal value=\"0\" />\r\n      </disabledValue>\r\n    </policy>\r\n    <policy name=\"EnableSettings\" class=\"Machine\" displayName=\"$(string.EnableSettings)\" explainText=\"$(string.EnableSettingsExplanation)\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\" valueName=\"EnableSettings\">\r\n      <parentCategory ref=\"AppInstaller\" />\r\n      <supportedOn ref=\"windows:SUPPORTED_Windows_10_0_RS5\" />\r\n      <enabledValue>\r\n        <decimal value=\"1\" />\r\n      </enabledValue>\r\n      <disabledValue>\r\n        <decimal value=\"0\" />\r\n      </disabledValue>\r\n    </policy>\r\n    <policy name=\"EnableExperimentalFeatures\" class=\"Machine\" displayName=\"$(string.EnableExperimentalFeatures)\" explainText=\"$(string.EnableExperimentalFeaturesExplanation)\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\" valueName=\"EnableExperimentalFeatures\">\r\n      <parentCategory ref=\"AppInstaller\" />\r\n      <supportedOn ref=\"windows:SUPPORTED_Windows_10_0_RS5\" />\r\n      <enabledValue>\r\n        <decimal value=\"1\" />\r\n      </enabledValue>\r\n      <disabledValue>\r\n        <decimal value=\"0\" />\r\n      </disabledValue>\r\n    </policy>\r\n    <policy name=\"EnableLocalManifestFiles\" class=\"Machine\" displayName=\"$(string.EnableLocalManifestFiles)\" explainText=\"$(string.EnableLocalManifestFilesExplanation)\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\" valueName=\"EnableLocalManifestFiles\">\r\n      <parentCategory ref=\"AppInstaller\" />\r\n      <supportedOn ref=\"windows:SUPPORTED_Windows_10_0_RS5\" />\r\n      <enabledValue>\r\n        <decimal value=\"1\" />\r\n      </enabledValue>\r\n      <disabledValue>\r\n        <decimal value=\"0\" />\r\n      </disabledValue>\r\n    </policy>\r\n    <policy name=\"EnableBypassCertificatePinningForMicrosoftStore\" class=\"Machine\" displayName=\"$(string.EnableBypassCertificatePinningForMicrosoftStore)\" explainText=\"$(string.EnableBypassCertificatePinningForMicrosoftStoreExplanation)\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\" valueName=\"EnableBypassCertificatePinningForMicrosoftStore\">\r\n      <parentCategory ref=\"AppInstaller\" />\r\n      <supportedOn ref=\"windows:SUPPORTED_Windows_10_0_RS5\" />\r\n      <enabledValue>\r\n        <decimal value=\"1\" />\r\n      </enabledValue>\r\n      <disabledValue>\r\n        <decimal value=\"0\" />\r\n      </disabledValue>\r\n    </policy>\r\n    <policy name=\"EnableHashOverride\" class=\"Machine\" displayName=\"$(string.EnableHashOverride)\" explainText=\"$(string.EnableHashOverrideExplanation)\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\" valueName=\"EnableHashOverride\">\r\n      <parentCategory ref=\"AppInstaller\" />\r\n      <supportedOn ref=\"windows:SUPPORTED_Windows_10_0_RS5\" />\r\n      <enabledValue>\r\n        <decimal value=\"1\" />\r\n      </enabledValue>\r\n      <disabledValue>\r\n        <decimal value=\"0\" />\r\n      </disabledValue>\r\n    </policy>\r\n    <policy name=\"EnableLocalArchiveMalwareScanOverride\" class=\"Machine\" displayName=\"$(string.EnableLocalArchiveMalwareScanOverride)\" explainText=\"$(string.EnableLocalArchiveMalwareScanOverrideExplanation)\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\" valueName=\"EnableLocalArchiveMalwareScanOverride\">\r\n      <parentCategory ref=\"AppInstaller\" />\r\n      <supportedOn ref=\"windows:SUPPORTED_Windows_10_0_RS5\" />\r\n      <enabledValue>\r\n        <decimal value=\"1\" />\r\n      </enabledValue>\r\n      <disabledValue>\r\n        <decimal value=\"0\" />\r\n      </disabledValue>\r\n    </policy>\r\n    <policy name=\"EnableDefaultSource\" class=\"Machine\" displayName=\"$(string.EnableDefaultSource)\" explainText=\"$(string.EnableDefaultSourceExplanation)\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\" valueName=\"EnableDefaultSource\">\r\n      <parentCategory ref=\"AppInstaller\" />\r\n      <supportedOn ref=\"windows:SUPPORTED_Windows_10_0_RS5\" />\r\n      <enabledValue>\r\n        <decimal value=\"1\" />\r\n      </enabledValue>\r\n      <disabledValue>\r\n        <decimal value=\"0\" />\r\n      </disabledValue>\r\n    </policy>\r\n    <policy name=\"EnableMicrosoftStoreSource\" class=\"Machine\" displayName=\"$(string.EnableMicrosoftStoreSource)\" explainText=\"$(string.EnableMicrosoftStoreSourceExplanation)\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\" valueName=\"EnableMicrosoftStoreSource\">\r\n      <parentCategory ref=\"AppInstaller\" />\r\n      <supportedOn ref=\"windows:SUPPORTED_Windows_10_0_RS5\" />\r\n      <enabledValue>\r\n        <decimal value=\"1\" />\r\n      </enabledValue>\r\n      <disabledValue>\r\n        <decimal value=\"0\" />\r\n      </disabledValue>\r\n    </policy>\r\n    <policy name=\"EnableFontSource\" class=\"Machine\" displayName=\"$(string.EnableFontSource)\" explainText=\"$(string.EnableFontSourceExplanation)\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\" valueName=\"EnableFontSource\">\r\n      <parentCategory ref=\"AppInstaller\" />\r\n      <supportedOn ref=\"windows:SUPPORTED_Windows_10_0_RS5\" />\r\n      <enabledValue>\r\n        <decimal value=\"1\" />\r\n      </enabledValue>\r\n      <disabledValue>\r\n        <decimal value=\"0\" />\r\n      </disabledValue>\r\n    </policy>\r\n    <policy name=\"SourceAutoUpdateInterval\" class=\"Machine\" displayName=\"$(string.SourceAutoUpdateInterval)\" explainText=\"$(string.SourceAutoUpdateIntervalExplanation)\" presentation=\"$(presentation.SourceAutoUpdateInterval)\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\">\r\n      <parentCategory ref=\"AppInstaller\" />\r\n      <supportedOn ref=\"windows:SUPPORTED_Windows_10_0_RS5\" />\r\n      <elements>\r\n        <decimal id=\"SourceAutoUpdateInterval\" valueName=\"SourceAutoUpdateInterval\" maxValue=\"43200\" />\r\n      </elements>\r\n    </policy>\r\n    <policy name=\"EnableAdditionalSources\" class=\"Machine\" displayName=\"$(string.EnableAdditionalSources)\" explainText=\"$(string.EnableAdditionalSourcesExplanation)\" presentation=\"$(presentation.AdditionalSources)\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\" valueName=\"EnableAdditionalSources\">\r\n      <parentCategory ref=\"AppInstaller\" />\r\n      <supportedOn ref=\"windows:SUPPORTED_Windows_10_0_RS5\" />\r\n      <enabledValue>\r\n        <decimal value=\"1\" />\r\n      </enabledValue>\r\n      <disabledValue>\r\n        <decimal value=\"0\" />\r\n      </disabledValue>\r\n      <elements>\r\n        <list id=\"AdditionalSources\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\\AdditionalSources\" valuePrefix=\"\" />\r\n      </elements>\r\n    </policy>\r\n    <policy name=\"EnableAllowedSources\" class=\"Machine\" displayName=\"$(string.EnableAllowedSources)\" explainText=\"$(string.EnableAllowedSourcesExplanation)\" presentation=\"$(presentation.AllowedSources)\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\" valueName=\"EnableAllowedSources\">\r\n      <parentCategory ref=\"AppInstaller\" />\r\n      <supportedOn ref=\"windows:SUPPORTED_Windows_10_0_RS5\" />\r\n      <enabledValue>\r\n        <decimal value=\"1\" />\r\n      </enabledValue>\r\n      <disabledValue>\r\n        <decimal value=\"0\" />\r\n      </disabledValue>\r\n      <elements>\r\n        <list id=\"AllowedSources\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\\AllowedSources\" valuePrefix=\"\" />\r\n      </elements>\r\n    </policy>\r\n    <policy name=\"EnableMSAppInstallerProtocol\" class=\"Machine\" displayName=\"$(string.EnableMSAppInstallerProtocol)\" explainText=\"$(string.EnableMSAppInstallerProtocolExplanation)\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\" valueName=\"EnableMSAppInstallerProtocol\">\r\n      <parentCategory ref=\"AppInstaller\" />\r\n      <supportedOn ref=\"windows:SUPPORTED_Windows_10_0_RS5\" />\r\n      <enabledValue>\r\n        <decimal value=\"1\" />\r\n      </enabledValue>\r\n      <disabledValue>\r\n        <decimal value=\"0\" />\r\n      </disabledValue>\r\n    </policy>\r\n    <policy name=\"EnableWindowsPackageManagerCommandLineInterfaces\" class=\"Machine\" displayName=\"$(string.EnableWindowsPackageManagerCommandLineInterfaces)\" explainText=\"$(string.EnableWindowsPackageManagerCommandLineInterfacesExplanation)\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\" valueName=\"EnableWindowsPackageManagerCommandLineInterfaces\">\r\n      <parentCategory ref=\"AppInstaller\" />\r\n      <supportedOn ref=\"windows:SUPPORTED_Windows_10_0_RS5\" />\r\n      <enabledValue>\r\n        <decimal value=\"1\" />\r\n      </enabledValue>\r\n      <disabledValue>\r\n        <decimal value=\"0\" />\r\n      </disabledValue>\r\n    </policy>\r\n    <policy name=\"EnableWindowsPackageManagerConfiguration\" class=\"Machine\" displayName=\"$(string.EnableWindowsPackageManagerConfiguration)\" explainText=\"$(string.EnableWindowsPackageManagerConfigurationExplanation)\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\" valueName=\"EnableWindowsPackageManagerConfiguration\">\r\n      <parentCategory ref=\"AppInstaller\" />\r\n      <supportedOn ref=\"windows:SUPPORTED_Windows_10_0_RS5\" />\r\n      <enabledValue>\r\n        <decimal value=\"1\" />\r\n      </enabledValue>\r\n      <disabledValue>\r\n        <decimal value=\"0\" />\r\n      </disabledValue>\r\n    </policy>\r\n    <policy name=\"EnableWindowsPackageManagerProxyCommandLineOptions\" class=\"Machine\" displayName=\"$(string.EnableWindowsPackageManagerProxyCommandLineOptions)\" explainText=\"$(string.EnableWindowsPackageManagerProxyCommandLineOptionsExplanation)\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\" valueName=\"EnableWindowsPackageManagerProxyCommandLineOptions\">\r\n      <parentCategory ref=\"AppInstaller\" />\r\n      <supportedOn ref=\"windows:SUPPORTED_Windows_10_0_RS5\" />\r\n      <enabledValue>\r\n        <decimal value=\"1\" />\r\n      </enabledValue>\r\n      <disabledValue>\r\n        <decimal value=\"0\" />\r\n      </disabledValue>\r\n    </policy>\r\n    <policy name=\"EnableWindowsPackageManagerMcpServer\" class=\"Machine\" displayName=\"$(string.EnableWindowsPackageManagerMcpServer)\" explainText=\"$(string.EnableWindowsPackageManagerMcpServerExplanation)\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\" valueName=\"EnableWindowsPackageManagerMcpServer\">\r\n      <parentCategory ref=\"AppInstaller\" />\r\n      <supportedOn ref=\"windows:SUPPORTED_Windows_10_0_RS5\" />\r\n      <enabledValue>\r\n        <decimal value=\"1\" />\r\n      </enabledValue>\r\n      <disabledValue>\r\n        <decimal value=\"0\" />\r\n      </disabledValue>\r\n    </policy>\r\n    <policy name=\"WindowsPackageManagerDefaultProxy\" class=\"Machine\" displayName=\"$(string.WindowsPackageManagerDefaultProxy)\" explainText=\"$(string.WindowsPackageManagerDefaultProxyExplanation)\" presentation=\"$(presentation.WindowsPackageManagerDefaultProxy)\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\">\r\n      <parentCategory ref=\"AppInstaller\" />\r\n      <supportedOn ref=\"windows:SUPPORTED_Windows_10_0_RS5\" />\r\n      <elements>\r\n        <text id=\"WindowsPackageManagerDefaultProxy\" valueName=\"DefaultProxy\"  />\r\n      </elements>\r\n    </policy>\r\n    <policy name=\"EnableMsixAllowedZones\" class=\"Machine\" displayName=\"$(string.EnableMsixAllowedZones)\" explainText=\"$(string.EnableMsixAllowedZonesExplanation)\" presentation=\"$(presentation.MsixAllowedZones)\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\" valueName=\"EnableMsixAllowedZones\">\r\n      <parentCategory ref=\"AppInstaller\" />\r\n      <supportedOn ref=\"windows:SUPPORTED_Windows_10_0_RS5\" />\r\n      <enabledValue>\r\n        <decimal value=\"1\" />\r\n      </enabledValue>\r\n      <disabledValue>\r\n        <decimal value=\"0\" />\r\n      </disabledValue>\r\n      <elements>\r\n        <enum id=\"LocalMachine\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\\MsixAllowedZones\" valueName=\"LocalMachine\" required=\"false\">\r\n          <item displayName=\"$(string.ZoneBlocked)\">\r\n            <value>\r\n              <decimal value=\"0\" />\r\n            </value>\r\n          </item>\r\n          <item displayName=\"$(string.ZoneAllowed)\">\r\n            <value>\r\n              <decimal value=\"1\" />\r\n            </value>\r\n          </item>\r\n        </enum>\r\n        <enum id=\"Intranet\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\\MsixAllowedZones\" valueName=\"Intranet\">\r\n          <item displayName=\"$(string.ZoneBlocked)\">\r\n            <value>\r\n              <decimal value=\"0\" />\r\n            </value>\r\n          </item>\r\n          <item displayName=\"$(string.ZoneAllowed)\">\r\n            <value>\r\n              <decimal value=\"1\" />\r\n            </value>\r\n          </item>\r\n        </enum>\r\n        <enum id=\"TrustedSites\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\\MsixAllowedZones\" valueName=\"TrustedSites\">\r\n          <item displayName=\"$(string.ZoneBlocked)\">\r\n            <value>\r\n              <decimal value=\"0\" />\r\n            </value>\r\n          </item>\r\n          <item displayName=\"$(string.ZoneAllowed)\">\r\n            <value>\r\n              <decimal value=\"1\" />\r\n            </value>\r\n          </item>\r\n        </enum>\r\n        <enum id=\"Internet\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\\MsixAllowedZones\" valueName=\"Internet\">\r\n          <item displayName=\"$(string.ZoneBlocked)\">\r\n            <value>\r\n              <decimal value=\"0\" />\r\n            </value>\r\n          </item>\r\n          <item displayName=\"$(string.ZoneAllowed)\">\r\n            <value>\r\n              <decimal value=\"1\" />\r\n            </value>\r\n          </item>\r\n        </enum>\r\n        <enum id=\"UntrustedSites\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\\MsixAllowedZones\" valueName=\"UntrustedSites\">\r\n          <item displayName=\"$(string.ZoneBlocked)\">\r\n            <value>\r\n              <decimal value=\"0\" />\r\n            </value>\r\n          </item>\r\n          <item displayName=\"$(string.ZoneAllowed)\">\r\n            <value>\r\n              <decimal value=\"1\" />\r\n            </value>\r\n          </item>\r\n        </enum>\r\n      </elements>\r\n    </policy>\r\n    <policy name=\"EnableMsixSmartScreenCheck\" class=\"Machine\" displayName=\"$(string.EnableMsixSmartScreenCheck)\" explainText=\"$(string.EnableMsixSmartScreenCheckExplanation)\" key=\"Software\\Policies\\Microsoft\\Windows\\AppInstaller\" valueName=\"EnableMsixSmartScreenCheck\">\r\n      <parentCategory ref=\"AppInstaller\" />\r\n      <supportedOn ref=\"windows:SUPPORTED_Windows_10_0_RS5\" />\r\n      <enabledValue>\r\n        <decimal value=\"1\" />\r\n      </enabledValue>\r\n      <disabledValue>\r\n        <decimal value=\"0\" />\r\n      </disabledValue>\r\n    </policy>\r\n  </policies>\r\n</policyDefinitions>\r\n"
  },
  {
    "path": "doc/admx/en-US/DesktopAppInstaller.adml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<!-- Copyright (c) Microsoft Corporation.\r\n     Licensed under the MIT License. -->\r\n<policyDefinitionResources xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" revision=\"1.0\" schemaVersion=\"1.0\" xmlns=\"http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions\">\r\n  <displayName>App Installer</displayName>\r\n  <description>App Installer</description>\r\n  <resources>\r\n    <stringTable>\r\n      <string id=\"AppInstaller\">Desktop App Installer</string>\r\n      <string id=\"EnableAppInstaller\">Enable Windows Package Manager</string>\r\n      <string id=\"EnableAppInstallerExplanation\">This policy controls whether the Windows Package Manager can be used by users.\r\n\r\nIf you enable or do not configure this setting, users will be able to use the Windows Package Manager.\r\n\r\nIf you disable this setting, users will not be able to use the Windows Package Manager.</string>\r\n      <string id=\"EnableSettings\">Enable Windows Package Manager Settings</string>\r\n      <string id=\"EnableSettingsExplanation\">This policy controls whether users can change their settings.\r\n\r\nIf you enable or do not configure this setting, users will be able to change settings for the Windows Package Manager.\r\n\r\nIf you disable this setting, users will not be able to change settings for the Windows Package Manager.</string>\r\n      <string id=\"EnableExperimentalFeatures\">Enable Windows Package Manager Experimental Features</string>\r\n      <string id=\"EnableExperimentalFeaturesExplanation\">This policy controls whether users can enable experimental features in the Windows Package Manager.\r\n\r\nIf you enable or do not configure this setting, users will be able to enable experimental features for the Windows Package Manager.\r\n\r\nIf you disable this setting, users will not be able to enable experimental features for the Windows Package Manager.</string>\r\n      <string id=\"EnableLocalManifestFiles\">Enable Windows Package Manager Local Manifest Files</string>\r\n      <string id=\"EnableLocalManifestFilesExplanation\">This policy controls whether users can install packages with local manifest files.\r\n\r\nIf you enable or do not configure this setting, users will be able to install packages with local manifests using the Windows Package Manager.\r\n\r\nIf you disable this setting, users will not be able to install packages with local manifests using the Windows Package Manager.</string>\r\n      <string id=\"EnableBypassCertificatePinningForMicrosoftStore\">Enable Windows Package Manager Microsoft Store Source Certificate Validation Bypass</string>\r\n      <string id=\"EnableBypassCertificatePinningForMicrosoftStoreExplanation\">This policy controls whether the Windows Package Manager will validate the Microsoft Store certificate hash matches to a known Microsoft Store certificate when initiating a connection to the Microsoft Store Source. \r\nIf you enable this policy, the Windows Package Manager will bypass the Microsoft Store certificate validation. \r\n\r\nIf you disable this policy, the Windows Package Manager will validate the Microsoft Store certificate used is valid and belongs to the Microsoft Store before communicating with the Microsoft Store source.\r\n\r\nIf you do not configure this policy, the Windows Package Manager administrator settings will be adhered to.</string>\r\n      <string id=\"EnableHashOverride\">Enable Windows Package Manager Hash Override</string>\r\n      <string id=\"EnableHashOverrideExplanation\">This policy controls whether or not the Windows Package Manager can be configured to enable the ability override the SHA256 security validation in settings.\r\n\r\nIf you enable or do not configure this policy, users will be able to enable the ability override the SHA256 security validation in the Windows Package Manager settings.\r\n\r\nIf you disable this policy, users will not be able to enable the ability override the SHA256 security validation in the Windows Package Manager settings.</string>\r\n      <string id=\"EnableLocalArchiveMalwareScanOverride\">Enable Windows Package Manager Local Archive Malware Scan Override</string>\r\n      <string id=\"EnableLocalArchiveMalwareScanOverrideExplanation\">This policy controls the ability to override malware vulnerability scans when installing an archive file using a local manifest using the command line arguments.\r\nIf you enable this policy, users can override the malware scan when performing a local manifest install of an archive file.\r\n\r\nIf you disable this policy, users will be unable to override the malware scan of an archive file when installing using a local manifest.\r\n\r\nIf you do not configure this policy, the Windows Package Manager administrator settings will be adhered to.</string>\r\n      <string id=\"EnableDefaultSource\">Enable Windows Package Manager Default Source</string>\r\n      <string id=\"EnableDefaultSourceExplanation\">This policy controls the default source included with the Windows Package Manager.\r\n\r\nIf you do not configure this setting, the default source for the Windows Package Manager will be available and can be removed.\r\n\r\nIf you enable this setting, the default source for the Windows Package Manager will be available and cannot be removed.\r\n\r\nIf you disable this setting the default source for the Windows Package Manager will not be available.</string>\r\n      <string id=\"EnableMicrosoftStoreSource\">Enable Windows Package Manager Microsoft Store Source</string>\r\n      <string id=\"EnableMicrosoftStoreSourceExplanation\">This policy controls the Microsoft Store source included with the Windows Package Manager.\r\n\r\nIf you do not configure this setting, the Microsoft Store source for the Windows Package manager will be available and can be removed.\r\n\r\nIf you enable this setting, the Microsoft Store source for the Windows Package Manager will be available and cannot be removed.\r\n\r\nIf you disable this setting the Microsoft Store source for the Windows Package Manager will not be available.</string>\r\n      <string id=\"EnableFontSource\">Enable Windows Package Manager Font Source</string>\r\n      <string id=\"EnableFontSourceExplanation\">\r\n        This policy controls the Font source included with the Windows Package Manager.\r\n\r\n        If you do not configure this setting, the Font source for the Windows Package manager will be available and can be removed.\r\n\r\n        If you enable this setting, the Font source for the Windows Package Manager will be available and cannot be removed.\r\n\r\n        If you disable this setting the Font source for the Windows Package Manager will not be available.\r\n      </string>\r\n      <string id=\"SourceAutoUpdateInterval\">Set Windows Package Manager Source Auto Update Interval In Minutes</string>\r\n      <string id=\"SourceAutoUpdateIntervalExplanation\">This policy controls the auto-update interval for package-based sources. The default source for Windows Package Manager is configured such that an index of the packages is cached on the local machine. The index is downloaded when a user invokes a command, and the interval has passed.\r\n\r\nIf you disable or do not configure this setting, the default interval or the value specified in the Windows Package Manager settings will be used.\r\n\r\nIf you enable this setting, the number of minutes specified will be used by the Windows Package Manager.</string>\r\n      <string id=\"EnableAdditionalSources\">Enable Windows Package Manager Additional Sources</string>\r\n      <string id=\"EnableAdditionalSourcesExplanation\">This policy controls additional sources provided by the enterprise IT administrator.\r\n\r\nIf you do not configure this policy, no additional sources will be configured for the Windows Package Manager.\r\n\r\nIf you enable this policy, the additional sources will be added to the Windows Package Manager and cannot be removed. The representation for each additional source can be obtained from installed sources using 'winget source export'.\r\n\r\nIf you disable this policy, no additional sources can be configured for the Windows Package Manager.</string>\r\n      <string id=\"EnableAllowedSources\">Enable Windows Package Manager Allowed Sources</string>\r\n      <string id=\"EnableAllowedSourcesExplanation\">This policy controls additional sources allowed by the enterprise IT administrator.\r\n\r\nIf you do not configure this policy, users will be able to add or remove additional sources other than those configured by policy.\r\n\r\nIf you enable this policy, only the sources specified can be added or removed from the Windows Package Manager. The representation for each allowed source can be obtained from installed sources using 'winget source export'.\r\n\r\nIf you disable this policy, no additional sources can be configured for the Windows Package Manager.</string>\r\n      <string id=\"EnableMSAppInstallerProtocol\">Enable App Installer ms-appinstaller protocol</string>\r\n      <string id=\"EnableMSAppInstallerProtocolExplanation\">This policy controls whether users can install packages from a website that is using the ms-appinstaller protocol.\r\n\r\nIf you enable this setting, users will be able to install packages from websites that use this protocol.\r\n\r\nIf you disable or do not configure this setting, users will not be able to install packages from websites that use this protocol.</string>\r\n      <string id=\"EnableWindowsPackageManagerCommandLineInterfaces\">Enable Windows Package Manager command line interfaces</string>\r\n      <string id=\"EnableWindowsPackageManagerCommandLineInterfacesExplanation\">This policy determines if a user can perform an action using the Windows Package Manager through a command line interface (WinGet CLI, or WinGet PowerShell).\r\n\r\n        If you disable this policy, users will not be able execute the Windows Package Manager CLI, and PowerShell cmdlets.\r\n\r\n        If you enable, or do not configure this policy, users will be able to execute the Windows Package Manager CLI commands, and PowerShell cmdlets. (Provided “Enable App Installer” policy is not disabled).\r\n\r\n        This policy does not override the “Enable App Installer” policy.</string>\r\n      <string id=\"EnableWindowsPackageManagerConfiguration\">Enable Windows Package Manager Configuration</string>\r\n      <string id=\"EnableWindowsPackageManagerConfigurationExplanation\">This policy controls whether the Windows Package Manager configuration feature can be used by users.\r\n\r\nIf you enable or do not configure this setting, users will be able to use the Windows Package Manager configuration feature.\r\n\r\nIf you disable this setting, users will not be able to use the Windows Package Manager configuration feature.</string>\r\n      <string id=\"EnableWindowsPackageManagerProxyCommandLineOptions\">Enable Windows Package Manager Proxy command line options</string>\r\n      <string id=\"EnableWindowsPackageManagerProxyCommandLineOptionsExplanation\">\r\n        This policy controls whether the Windows Package Manager usage of proxy can be configured by users through the command line.\r\n\r\n        If you enable this setting, users will be able to configure the Windows Package Manager's use of proxy through the command line.\r\n\r\n        If you disable or do not configure this setting, users will not be able to to configure the Windows Package Manager's use of proxy through the command line.</string>\r\n      <string id=\"EnableWindowsPackageManagerMcpServer\">Enable MCP Server for Windows Package Manager</string>\r\n      <string id=\"EnableWindowsPackageManagerMcpServerExplanation\">\r\n        This policy controls whether the Windows Package Manager Model Context Protocol (MCP) server can be used.\r\n\r\n        If you enable or do not configure this setting, users will be able to use the Windows Package Manager's MCP server.\r\n\r\n        If you disable this setting, users will not be able to to use the Windows Package Manager's MCP server.</string>\r\n      <string id=\"WindowsPackageManagerDefaultProxy\">Set Windows Package Manager Default Proxy</string>\r\n      <string id=\"WindowsPackageManagerDefaultProxyExplanation\">This policy controls the default proxy used by the Windows Package Manager.\r\n\r\nIf you disable or do not configure this setting, no proxy will be used by default.\r\n\r\nIf you enable this setting, the specified proxy will be used by default.</string>\r\n      <string id=\"EnableMsixAllowedZones\">Enable App Installer Allowed Zones for MSIX Packages</string>\r\n      <string id=\"EnableMsixAllowedZonesExplanation\">This policy controls whether App Installer allows installing packages originating from specific URL Zones. A package's origin is determined by its URI and whether a Mart-of-the-Web (MotW) is present. If multiple URIs are involved, all of them are considered; for example, when using a .appinstaller file that involves redirection.\r\n\r\nIf you enable this policy, users will be able to install MSIX packages according to the configuration for each zone.\r\n\r\nIf you disable or do not configure this policy, users will be able to install MSIX packages from any zone except for Untrusted.</string>\r\n      <string id=\"ZoneAllowed\">Allow</string>\r\n      <string id=\"ZoneBlocked\">Block</string>\r\n      <string id=\"EnableMsixSmartScreenCheck\">Enable Microsoft SmartScreen checks for MSIX Packages</string>\r\n      <string id=\"EnableMsixSmartScreenCheckExplanation\">This policy controls whether App Installer performs Microsoft SmartScreen checks when installing MSIX packages.\r\n\r\nIf you enable or do not configure this policy, the package URI will be evaluated with Microsoft SmartScreen before installation. This check is only done for packages that come from the internet.\r\n\r\nIf you disable, Microsoft SmartScreen will not be consulted before installing a package.</string>\r\n    </stringTable>\r\n    <presentationTable>\r\n      <presentation id=\"SourceAutoUpdateInterval\">\r\n        <decimalTextBox refId=\"SourceAutoUpdateInterval\" defaultValue=\"5\">Source Auto Update Interval In Minutes</decimalTextBox>\r\n      </presentation>\r\n      <presentation id=\"AdditionalSources\">\r\n        <listBox refId=\"AdditionalSources\" required=\"false\">Additional Sources: </listBox>\r\n      </presentation>\r\n      <presentation id=\"AllowedSources\">\r\n        <listBox refId=\"AllowedSources\" required=\"false\">Allowed Sources: </listBox>\r\n      </presentation>\r\n      <presentation id=\"WindowsPackageManagerDefaultProxy\">\r\n        <textBox refId=\"WindowsPackageManagerDefaultProxy\">\r\n          <label>Default Proxy</label>\r\n        </textBox>\r\n      </presentation>\r\n      <presentation id=\"MsixAllowedZones\">\r\n        <dropdownList refId=\"LocalMachine\" noSort=\"true\" defaultItem=\"1\">Local Machine</dropdownList>\r\n        <dropdownList refId=\"Intranet\" noSort=\"true\" defaultItem=\"1\">Intranet</dropdownList>\r\n        <dropdownList refId=\"TrustedSites\" noSort=\"true\" defaultItem=\"1\">Trusted Sites</dropdownList>\r\n        <dropdownList refId=\"Internet\" noSort=\"true\" defaultItem=\"1\">Internet</dropdownList>\r\n        <dropdownList refId=\"UntrustedSites\" noSort=\"true\" defaultItem=\"0\">Untrusted Sites</dropdownList>\r\n      </presentation>\r\n    </presentationTable>\r\n  </resources>\r\n</policyDefinitionResources>\r\n\r\n"
  },
  {
    "path": "doc/specs/#1012 - Show dependencies.md",
    "content": "---\r\nauthor: Florencia Zanollo fzanollo/t-fzanollo@microsoft.com\r\ncreated on: 2021-05-28\r\nlast updated: 2021-05-28\r\nissue id: 1012\r\n---\r\n\r\n# Show dependencies\r\n\r\nFor [#1012](https://github.com/microsoft/winget-cli/issues/1012)\r\n\r\n## Abstract\r\nSeveral packages require other packages as dependencies. The Windows Package Manager should be able to support declared dependencies and, as a first step to manage them, inform the user about any required ones.\r\n\r\n## Solution Design\r\nThe Windows Package Manager should be able to report package dependency information for each of the four different types of dependencies declared in the [v1.0 manifest schemas](https://github.com/microsoft/winget-cli/blob/master/schemas/JSON/manifests/v1.0.0/).\r\n\r\n* Windows Features\r\n* Windows Libraries\r\n* Package Dependencies (same source)\r\n* External Dependencies\r\n\r\nOnly dependencies declared in the manifest/installer will be shown, not the entire dependency graph.\r\n\r\n### install\r\nThe install command will enumerate the dependencies of the package version being installed as follows:\r\n```\r\n> winget install Notepad++\r\nFound Notepad++ [Notepad++.Notepad++]\r\nThis application is licensed to you by its owner.\r\nMicrosoft is not responsible for, nor does it grant any licenses to, third-party packages.\r\nThis package requires the following dependencies:\r\n  - Windows Feature:\r\n      Hyper-V\r\n  - Package:\r\n      Microsoft.WindowsTerminal\r\nDownloading https://github.com/notepad-plus-plus/notepad-plus-plus/releases/download/v7.9.5/npp.7.9.5.Installer.x64.exe\r\nSuccessfully verified installer hash\r\nStarting package install...\r\n```\r\n\r\n### show\r\nThe show command will enumerate the dependencies of the package as follows:\r\n```\r\n> winget show Notepad++\r\nFound Notepad++ [Notepad++.Notepad++]\r\nVersion: 7.9.5\r\nPublisher: Notepad++ Team\r\nAuthor: Don Ho\r\nMoniker: notepad++\r\nDescription: Notepad++ is a free (as in “free speech” and also as in “free beer”) source code editor and Notepad replacement that supports several languages. Running in the MS Windows environment, its use is governed by GNU General Public License.\r\nHomepage: https://notepad-plus-plus.org/\r\nLicense: GPL-2.0-only\r\nLicense Url: https://raw.githubusercontent.com/notepad-plus-plus/notepad-plus-plus/v7.9.5/LICENSE\r\nInstaller:\r\n  Type: Nullsoft\r\n  Locale: en-US\r\n  Download Url: https://github.com/notepad-plus-plus/notepad-plus-plus/releases/download/v7.9.5/npp.7.9.5.Installer.x64.exe\r\n  SHA256: 4881548cd86491b453520e83c19292c93b9c6ce485a1f9eb9301e3913a9baced\r\n  Dependencies:\r\n    - Windows Feature:\r\n        Hyper-V\r\n    - Package:\r\n        Microsoft.WindowsTerminal\r\n```\r\n\r\n### upgrade\r\nThe upgrade command will enumerate the dependencies of the package as follows:\r\n```\r\n> winget upgrade Notepad++\r\nFound Notepad++ [Notepad++.Notepad++]\r\nThis application is licensed to you by its owner.\r\nMicrosoft is not responsible for, nor does it grant any licenses to, third-party packages.\r\nThis package requires the following dependencies:\r\n  - Windows Feature:\r\n      Hyper-V\r\n  - Package:\r\n      Microsoft.WindowsTerminal\r\nSuccessfully verified installer hash\r\nStarting package install...\r\n```\r\nAs of now, it will not try to validate nor install any of the dependencies for any package version.\r\n\r\n### uninstall\r\nUninstall needs more work as we don't have the actual installer to get the dependencies from. This will not be added in this step.\r\n\r\n### validate\r\nWill gather and report dependencies for all of the installers found. Will not check if they are valid nor if there are duplicates.\r\n```\r\nManifest has the following dependencies that were not validated; ensure that they are valid:\r\n  - Windows Feature:\r\n      Hyper-V\r\n  - Package:\r\n      Microsoft.WindowsTerminal\r\nManifest validation succeeded.\r\n```\r\n\r\n### import\r\nWill gather all the dependencies from the packages included in the import and show them together before starting.\r\n```\r\nThe packages found in this import have the following dependencies:\r\n  - Windows Feature:\r\n      Hyper-V\r\n      Containers\r\n  - Windows Libraries:\r\n      Microsoft.WinJS\r\n  - Package:\r\n      Microsoft.WindowsTerminal\r\n  - External:\r\n      JDK-11.0.10\r\nFound  [Notepad++.Notepad++]\r\nThis application is licensed to you by its owner.\r\nMicrosoft is not responsible for, nor does it grant any licenses to, third-party packages.\r\nDownloading https://github.com/notepad-plus-plus/notepad-plus-plus/releases/download/v8/npp.8.0.Installer.x64.exe\r\nSuccessfully verified installer hash\r\nStarting package install...\r\nSuccessfully installed\r\nFound  [plex.Plex]\r\nThis application is licensed to you by its owner.\r\nMicrosoft is not responsible for, nor does it grant any licenses to, third-party packages.\r\nSuccessfully verified installer hash\r\nStarting package install...\r\nSuccessfully installed\r\n```\r\n\r\n## Capabilities\r\nIt's only an informational feature, will not check if the dependency is a valid one, nor if the source is available.\r\nIf a dependency is declared more than once (for example when gathering all dependencies in an import) it will only show the highest minimum version needed.\r\n\r\nKeep in mind dependencies can be declared on the root manifest and on each of the installers. If they happen to be declared in both, installer's dependencies will override those of the manifest. With the manifest's dependencies working as a default whenever installer's dependencies are not declared.\r\n\r\n## Future considerations\r\nIt may be able to enable/disable this feature using extra options for the command.\r\n"
  },
  {
    "path": "doc/specs/#1155 - Enhancements to list command.md",
    "content": "---\nauthor: Demitrius Nelon @denelon\ncreated on: 2021-06-11\nlast updated: 2021-06-11\nissue id: 1155\n---\n\n# Enhancements to List Command\n\nFor [#1155](https://github.com/microsoft/winget-cli/issues/1155).\n\n## Abstract\n\nThe `winget list` command was designed to display all packages installed on a users Windows 10 machine in Add / Remove Programs (ARP). The command would also show which Apps with possible upgrades were available from sources configured in the Windows Package Manager. This specification proposes enhancements to the output provided by the list command.\n\nThe first enhancement is adding the values for \"Available\" and \"Source\" for every package in configured sources rather that just packages with upgrades available.\n\nThe second enhancement is reducing the set of packages to the source specified when the source is passed as an argument to the list command.\n\nThe third enhancement is adding an argument to provide the list of Apps with no matching package in configured sources.\n\n## Inspiration\n\nSeveral suggestions have been made on how to improve user experience. Recently, many users have been attempting to identify Apps on their system with no corresponding package in the Microsoft Community Repository.\n\n## Solution Design\n\nModify the output behavior for `winget list` to display available version from any source. When a package is available via more than once source, the first configured source should be displayed.\n\n>Note: Users will be able to see if packages are available from individual sources by specifying the source as an argument to the list command.\n\nModify the output behavior for `winget list -s <source>` to display only packages available from the specified source.\n\nAdd a new argument `-u, --unavailable`  to the list command to display Apps installed in ARP not matching any configured source.\n\n## UI/UX Design\n\nThe UI would remain consistent with the current tabular output.\n\n## Capabilities\n\n### Accessibility\n\nThis should not change impact accessibility for users of screen readers, assistive input devices, etc.\n\n### Security\n\nThis should not change or impact security?\n\n### Reliability\n\nThis should not impact reliability.\n\n### Compatibility\n\nThis will change existing behaviors. The `winget list` output currently displays available versions and sources in addition to all other installed Apps. The `winget upgrade` command should be used instead to view available upgrades.\n\n### Performance, Power, and Efficiency\n\n## Potential Issues\n\nThis may impact performance, but it should be minor. Another Issue [#964](https://github.com/microsoft/winget-cli/issues/964) \"Improvements to the list command\" was created to address performance issues related to the `winget list` command.\n\n## Future considerations\n\nThis feature may simplify the process of identifying packages missing from source repositories.\n\n## Resources\n\nIssue [#977](https://github.com/microsoft/winget-cli/issues/977) \"`winget list` should be able to show hidden apps\" is also related to the `winget list` command.\n"
  },
  {
    "path": "doc/specs/#1287 - Management of package type dependencies.md",
    "content": "---\r\nauthor: Florencia Zanollo fzanollo/t-fzanollo@microsoft.com\r\ncreated on: 2021-07-15\r\nlast updated: 2021-07-15\r\nissue id: 1287\r\n---\r\n\r\n# Management of package type dependencies\r\n\r\nFor [#1287](https://github.com/microsoft/winget-cli/issues/1287)\r\n\r\n## Abstract\r\nAs a new step in the pursue of dependency management, the Windows Package Manager will take care of one of the four types of dependencies (Package) for most of the commands. The underlying logic of the code will prove useful when implementing the rest of the types and commands; since it will manage dependencies' graph building and validation, as well as the correct order of installation.\r\n\r\n## Solution Design\r\nThe Windows Package Manager will build the dependencies' graph and corroborate there's not a cyclic dependency, among other validations (depending on the command).\r\n\r\n### Install:\r\nInstall command will build the dependency graph at runtime, from installer information. It will report on the other three types of dependencies and manage package type installation/validation (for new/installed dependencies respectively).\r\nAs a best effort, in case a cyclic dependency exists, Windows Package Manager will inform the user but try to install in some order; this is because most of the dependencies are at run time so there shouldn't present an issue on install.\r\n\r\nWhile building the graph, install command will verify:\r\n* Availability: the package declared as dependency will need to be an existing one.\r\n* Installed version: it will check for existing versions of the dependency and update if the minimum required version is bigger than the installed.\r\n* Version: minimum required version will need to be less or equal to the latest available one.\r\n\r\nInformation will be shown about failures, existence or installation progress for each of the dependencies required.\r\n\r\nWhen installing from a local manifest, a dependency source will be required (using --dependency-source parameter), but only if the target has at least one package type dependency declared.\r\n\r\n```\r\n> winget install Notepad++\r\nFound Notepad++ [Notepad++.Notepad++]\r\nThis application is licensed to you by its owner.\r\nMicrosoft is not responsible for, nor does it grant any licenses to, third-party packages.\r\nThis package requires the following dependencies:\r\n  - Windows Feature:\r\n      Hyper-V\r\n  - Package:\r\n      Microsoft.WindowsTerminal\r\nBuilding package type dependencies' graph:\r\n    No errors or cyclic dependencies found.\r\nInstalling package type dependencies:\r\n    Found WindowsTerminal [Microsoft.WindowsTerminal]\r\n    This application is licensed to you by its owner.\r\n    Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.\r\n    Downloading (...)\r\n    Successfully verified installer hash\r\n    Starting package install...\r\nDownloading https://github.com/notepad-plus-plus/notepad-plus-plus/releases/download/v7.9.5/npp.7.9.5.Installer.x64.exe\r\nSuccessfully verified installer hash\r\nStarting package install...\r\n```\r\n\r\n### Import:\r\nImport command will report all first level dependencies beforehand and after will work as install command for each of the packages found, iteratively. Ex. if packages *foo* and *foo1* are part of the import, dependencies for *foo* will be fetch and installed before continuing with *foo1*.\r\n\r\n```\r\nThe packages found in this import have the following dependencies:\r\n  - Windows Feature:\r\n      Hyper-V\r\n      Containers\r\n  - Windows Libraries:\r\n      Microsoft.WinJS\r\n  - Package:\r\n      Microsoft.WindowsTerminal\r\n  - External:\r\n      JDK-11.0.10\r\nFound  [Notepad++.Notepad++]\r\nThis application is licensed to you by its owner.\r\nMicrosoft is not responsible for, nor does it grant any licenses to, third-party packages.\r\nBuilding package type dependencies' graph:\r\n    No errors or cyclic dependencies found.\r\nInstalling package type dependencies:\r\n    Found WindowsTerminal [Microsoft.WindowsTerminal]\r\n    This application is licensed to you by its owner.\r\n    Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.\r\n    Downloading (...)\r\n    Successfully verified installer hash\r\n    Starting package install...\r\nFound  [plex.Plex]\r\nThis application is licensed to you by its owner.\r\nMicrosoft is not responsible for, nor does it grant any licenses to, third-party packages.\r\n(...)\r\n```\r\n\r\n### Update:\r\n* Update one: will also work as install command, we need to check again for dependencies as the new installer can have new ones or bigger minimum required versions.\r\n* Update many: will work iteratively (as import).\r\n\r\n```\r\n> winget upgrade Notepad++\r\nFound Notepad++ [Notepad++.Notepad++]\r\nThis application is licensed to you by its owner.\r\nMicrosoft is not responsible for, nor does it grant any licenses to, third-party packages.\r\nThis package requires the following dependencies:\r\n  - Windows Feature:\r\n      Hyper-V\r\n  - Package:\r\n      Microsoft.WindowsTerminal\r\nBuilding package type dependencies' graph:\r\n    No errors or cyclic dependencies found.\r\nInstalling package type dependencies:\r\n    Found WindowsTerminal [Microsoft.WindowsTerminal]\r\n    This application is licensed to you by its owner.\r\n    Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.\r\n    Downloading (...)\r\n    Successfully verified installer hash\r\n    Starting package install...\r\nSuccessfully verified installer hash\r\nStarting package install...\r\n```\r\n\r\n## Capabilities\r\nWill manage package type dependencies installation for install, import and update commands.\r\nWill not manage or try to install any of the other types of dependencies (Windows Features, Windows Libraries, External).\r\n"
  },
  {
    "path": "doc/specs/#140 - ZIP Support.md",
    "content": "---\r\nauthor: Ryan Fu @ryfu-msft\r\ncreated on: 2022-05-24\r\nlast updated: 2022-12-13\r\nissue id: 140\r\n---\r\n\r\n# Support ZIP/Archive InstallerTypes\r\n\r\nFor [#140](https://github.com/microsoft/winget-cli/issues/140)\r\n\r\n## Abstract\r\nThis spec outlines the design for supporting the installation of packages using archive files. The initial implementation will aim to support only ZIP files. This spec will be updated if support for other archive types such as .tar.gz or .cab files are added.\r\n\r\n## Design Flow/Implementation\r\n\r\nBecause ZIP archive files are essentially a compressed directory containing the relevant installer files, the install flow will need to add the following steps:\r\n\r\n1. Perform checks on the downloaded ZIP archive for potential malware or threats.\r\n2. Extract the contents of the ZIP archive to a temporary location.\r\n3. Execute the appropriate install flow using the extracted installer based on the installer type derived from the manifest.\r\n\r\n>NOTE: The initial implementation will first support installing ZIPs that contain only basic installers (msix, msi, or exe), then portable apps.\r\n\r\n## Manifest Changes:\r\nAddition of `NestedInstallerType`:\r\n- Enumeration of supported nested installerTypes contained inside an archive file.\r\n\r\nAddition of `NestedInstallerFile`\r\n- Object containing metadata about a nested installer file contained inside an archive.\r\n- Properties:\r\n    - `RelativeFilePath`: The relative path to a nested installer file contained inside an archive.\r\n    - `PortableCommandAlias`: The command alias to be used for calling the package. Only applies to a nested portable package.\r\n\r\nThese changes would be added to the `Installer` object with `NestedInstallerFiles` representing an array of `NestedInstallerFile`.\r\n\r\n### Manifest Validation:\r\n- Exactly one `NestedInstallerFile` entry must be specified for a non-portable nested installer type.\r\n- Multiple `NestedInstallerFile` entries can be specified for portable nested installer type to support a suite of portable exes that would all be installed under the same package.\r\n- If a ZIP `InstallerType` is specified, a `NestedInstallerType` is required to be specified.\r\n\r\n## Supported Install Scenarios:\r\nThe initial implementation of this feature will only support the following installation scenarios:\r\n- Single base installer (exe, msi, msix) contained inside an archive file.\r\n- Single or multiple portable exes bundled as a suite inside an archive file.\r\n\r\n## ZIP Extraction\r\nThe extraction of ZIPs will be done using Windows Shell APIs. ZIP files can be represented as a [ShellFolder](https://docs.microsoft.com/windows/win32/api/shobjidl_core/nn-shobjidl_core-ishellfolder) object that can be used to manage the contents of the ZIP file. File contents are represented as [ShellItems](https://docs.microsoft.com/windows/win32/api/shobjidl_core/nn-shobjidl_core-ishellitem), which can be handled using the methods exposed by the [IFileOperation interface](https://docs.microsoft.com/windows/win32/api/shobjidl_core/nn-shobjidl_core-ifileoperation).\r\n\r\nIn our initial implementation, we will only support extracting the top level archive to a temporary location. This means that the `NestedInstallerFile` must not be contained in any nested archives. The appropriate install flow will proceed based on the specified `NestedInstallerType`.\r\n\r\n> If the community presents enough use cases that require decompressing additional layers, then we will consider extending this functionality and adding a separate manifest entry to override the default behavior of only unzipping the top level archive.\r\n\r\n> Since we are utilizing Windows Shell APIs, we need to ensure that we are not invoking a UI during the extraction. This can be done by [setting the operation flag to not display any UI](https://docs.microsoft.com/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifileoperation-setoperationflags).\r\n\r\n> During implementation, we will also need to ensure that this process can work under SYSTEM context.\r\n\r\n## ZIP Threat Detection\r\nZIP and other archive file types are known threat vectors for malware in the form of ZIP compression bombs. Two of the most common types of compression bombs are multi-layered (recursive) and single-layered (non-recursive). ZIP bombs rely on a repetition of identical files that have extremely large compression ratios. Some examples include the following:\r\n\r\n1. **Multi-layered (recursive)**:\r\nA ZIP file containing multiple layers of nested ZIP files that achieve high compression ratios when decompressed recursively. This technique is often used to bypass compression ratio checks performed by ZIP parsers for a single layer.\r\n\r\n2. **Single-Layered (non-recursive)**\r\nA ZIP bomb that expands fully after a single round of decompression. The extremely high compression ratio of the ZIP bomb is achieved by overlapping files within the ZIP container.\r\n\r\nIn order to protect our users from these possible threats, we will need to scan the ZIP file for malware using [Pure, a static analysis file format checker](https://github.com/ronomon/pure).\r\n\r\n> Pure is licensed under the [MIT license](https://github.com/ronomon/pure/blob/master/LICENSE).\r\n\r\nIf the Pure library functions that are called on a given ZIP file detect malware, the process will terminate and a warning will be displayed to the user. The user can include `--ignore-local-archive-malware-scan` to bypass this check and continue installation at their own risk.\r\n\r\n\r\nTo minimize unnecessary costs on performance during installation, these checks will only be applied when any of the following conditions are met:\r\n-  Hash mismatch was overridden\r\n-  Untrusted source (i.e. installing from a local manifest, private source or third-party REST sources)\r\n\r\n## Supporting Nested Portable(s) in an Archive\r\nCurrently, information regarding a single installed portable is stored in the ARP entry. In order to support installing a single or multiple portables contained inside an archive file, we will need to create a separate record that will be stored with the extracted files. This record will contain a table capturing the list of files that were created and placed down as well as various metadata to enable us to verify whether they have been modified. This table should replace most of the uninstall-related information that is stored in ARP for a given portable package.\r\n\r\nThe table will contain the following information for each item that we create or place down during installation.\r\n\r\n| Metadata    | Description |\r\n| ----------- | ----------- |\r\n| Path      | Path to the item |\r\n| Flag   | Flag to indicate what type of file was placed down (directory, symlink, exe) |\r\n| Hash   | Hash for files with contents (exe) |\r\n| SymlinkTarget | Target exe for the created symlink (only applies to symlink files) |\r\n\r\n"
  },
  {
    "path": "doc/specs/#148 - Repair Support.md",
    "content": "---\r\nauthor: Madhusudhan Gumbalapura Sudarshan @Madhusudhan-MSFT\r\ncreated on: 2023-12-01\r\nlast updated: 2024-08-27\r\nissue id: 148\r\n---\r\n\r\n# Repair Feature for Windows Package Manager\r\n\r\n\"For [#148](https://github.com/microsoft/winget-cli/issues/148)\"\r\n\r\n## Abstract\r\n\r\nThis specification outlines the design and implementation of a repair feature for the Windows Package Manager.The repair feature aims to provide a convenient and reliable way for users to fix any issues that may arise with their installed applications, such as corrupted files, missing dependencies, or broken registry entries.The initial implementation will support repair for main installer types, such as Msi, Wix, Msix and MSStore installer types, which have native repair capabilities from their respective frameworks. Additionally, other installer types such as Burn/Exe/Nullsoft/Inno that can specify a custom repair switch in their YAML manifest files can also use the repair feature.The document also outlines the future plans for extending the repair feature to other installer types Portables that do not have a standard repair mechanism.\r\n\r\n## Inspiration\r\n\r\nThe motivation for creating a repair feature in the Windows Package Manager is to provide users with a convenient and consistent way to fix their malfunctioning applications, regardless of the installer type. Currently, users have to rely on different methods to repair their applications, such as using the Windows Settings app, the Control Panel, the command line, or the application's own repair tool. These methods are not always available, accessible, or intuitive, and they may vary depending on the application and the installer type. The repair feature aims to provide a unified experience for users to repair their applications, regardless of the installer type.\r\n\r\n## Solution Design\r\n\r\n### Repair Command Syntax\r\n`winget repair [[-q] <query>...] [<options>]`\r\nwill initiate the repair of the specified package. The command will display an error message if the application is not installed. The command will attempt to repair the application if it is installed. The command will display a success message if the repair succeeds. The command will display an error message if the repair fails.\r\n\r\n#### Arguments\r\n| Argument | Description |\r\n|-------------|-------------|  \r\n| **-q,--query**  |  The query used to search for an app. |\r\n\r\n\r\n#### Optional Arguments\r\n\r\n| Option | Description |\r\n|--------|-------------|\r\n| **-m, --manifest** | Must be followed by the path to the manifest (YAML) file.You can use the manifest to run the repair experience from a [local manifest file](#local-repair).|\r\n| **--id** | Limits the repair to the specified ID of the application.|\r\n| **--name** | Limits the repair to the specified name of the application.|\r\n| **--moniker** | Limits the repair to the specified moniker of the application.|\r\n| **-v --version** | Limits the repair to the specified version of the application.If not specified, the repair will be applied to the latest version of the application.|\r\n| **--architectures** | Select the architecture |\r\n| **-s --source** | Limits the search to specified source(s).Must be followed by the source name.|\r\n| **-o, --log** | Directs the logging to a log file. You must provide a path to a file that you have the write rights to. |\r\n| **-i --interactive** | Runs the repair in interactive mode.|\r\n| **-h --silent** | Runs the repair in silent mode.|\r\n| **-?, --help** | Get additional help on this command. |\r\n| **--accept-source-agreements** | Accept all source agreements during source operations |\r\n| **--logs, --open-logs** | Open the default logs location. |\r\n| **--locale** | Sets the locale.|\r\n\r\n\r\n### Repair Feature for different Installer Types with Native Repair Capabilities\r\n  - Msi, Wix : The repair command will use the built-in repair features of the MSI installer type. It will run the msiexec command with the default [repair options](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/msiexec#repair-options) to repair the application using a ShellExecute call.\r\n  - Msix : The repair command will use the built-in repair features of the MSIX installer type. It will make an MSIX API call to register the application package, which will attempt to repair the package.\r\n    > We can't do the same thing as setting app repair for MSIX app right now because we can't use the private APIs that it uses to do repair operations with winget.\r\n  - MSStore : The repair command will make an MSStore API  [StartProductInstallAsync](https://learn.microsoft.com/en-us/uwp/api/windows.applicationmodel.store.preview.installcontrol.appinstallmanager.startproductinstallasync?view=winrt-22621) call to repair the application with 'Repair' property of AppInstallOption set to true.\r\n\r\n### Repair Feature for Installer Types that require Custom Repair Switch\r\n  - Burn, Exe, Nullsoft & Inno : The custom switch for repair in the YAML manifest file will be used to perform the repair. The repair command will run the installer with the custom switch to repair the application. To have enough flexibility, different options are possible depending on the installer source used for repair. \r\n   - Installed Source: \r\n     - If the YAML manifest file specifies the `Repair` switch and `Modify` as the `RepairBehavior`, the repair command will use the modify command in the ARP `ModifyPath` registry key, along with the repair switch, through a ShellExecute call, as long as `NoModify` and `NoRepair` ARP registry flags are not set to 1.\r\n     - If the YAML manifest file specifies the `Repair` switch and `Uninstaller` as the RepairBehavior, the repair command will use the uninstall command in the ARP `UninstallString` registry key, along with the repair switch, through a ShellExecute call, as long as `NoRepair` APR registry flag is not set to 1.\r\n   - Remote Source: If the YAML manifest file specifies the `Repair` switch and `Installer` value for the RepairBehavior, the repair command will obtain the matching installer from the remote source and use the repair switch on the downloaded installer through a ShellExecute call..\r\n\r\n> If neither switch is specified, the repair command will display an error message.\r\n\r\n> Note: The initial implementation will not support repair for Portables installer type. Based on feedback from the community, we may add the repair feature for these installer type in a future release.\r\n\r\n## Manifest Changes\r\nAddition of `Repair` property to InstallerSwitch\r\n- The `Repair` property is used to set the custom repair option that works with `RepairBehavior` field that controls the different repair behavior.\r\n\r\nAddition of `RepairBehavior` enumerable property to Installer Object\r\n- With the `RepairBehavior` switch, we can adjust the repair behavior by choosing the installer source (Installed/local or remote) and making sure that the proper ARP registry entries are applied to identify the local installer type when carrying out a repair operation using a local installer source. \r\n- The permitted initial values for the `RepairBehavior` switch include:\r\n   - Performing a repair using a Installed/Local Installer Source:\r\n    - `Modify`: if this option is specified, the repair switch will be applied to the `ModifyPath` ARP command entry, as long as `NoModify` and `NoRepair` ARP registry flags are not set to 1.\r\n    - `Uninstaller` : if this option is specified, the repair switch will be applied to the `UninstallString` ARP command entry, as long as `NoRepair` APR registry flag is note set to 1.\r\n   - Performing a repair using a Remote Installer Source:\r\n    - `Installer` : If this option is specified, the repair switch will be applied to the appropriate installer obtained from the remote installer source.\r\n\r\n## Manifest Validation\r\n-  Specifying `Repair` switch without `RepairBehavior` switch will result in an error.\r\n - Specifying `RepairBehavior` switch without `Repair` switch will result in an error.\r\n - `Repair` switch can't be empty when specified.\r\n - `RepairBehavior` switch can't be empty when specified.\r\n\r\n## Handling Elevation Requirement\r\n- The design presumes that the elevation requirements for modification/repair are consistent with those for installation, much like uninstallation.\r\n- The expectations are:\r\n  - If a non-elevated session tries to modify a package installed for machine scope, the installer should prompt for elevation, as observed in sample runs.\r\n  - If a package installed for user scope attempts a repair operation in an admin context, it is restricted due to possible security risks.\r\n\r\n## Supported Repair Scenarios\r\n- Repair for installed applications of Msi, Wix, Msix and MSStore installer types.\r\n- Repair for the application using the custom repair switch specified in the YAML manifest file for Burn/Exe/Nullsoft/Inno/Wix/Msi installer types.\r\n  -  The appropriate repair behavior is determined by the combination of the `Repair` switch and the `RepairBehavior` value in the YAML manifest.\r\n\r\n## Potential Issues\r\n- For Msi based installer types\r\n  - To repair an Msi-based installer using msiexec platform support, the original installer must be present at the location registered as 'InstallSource' in the ARP registry. If the original installer is moved or renamed, the repair operation will fail, which is consistent with the modify repair through the settings app. This issue is more likely with installers installed via the winget install command, as it removes the installer right after installation to reduce disk footprint by design, making the 'InstallSource' path invalid. However, this issue does not apply if the installer can store the installer in a package cache path for future use and registers that path in 'InstallSource' in the ARP registry at the time of installation.\r\n- For Burn/Exe/Nullsoft/Inno installer types \r\n  - the repair command will not work if the installer does not have a custom repair switch specified in the YAML manifest file.\r\n  - the repair command will not work if the installed Burn/Exe/Nullsoft/inno installer type doesn't correlate to the remote installer type that has a custom repair switch specified in the YAML manifest file.\r\n\r\n## Future considerations\r\n\r\n- Repair for Portables installer types. The possible options are:\r\n   - Download matching installer , uninstall & Install OR\r\n   - Download matching installer & re Install to overwrite existing files.\r\n- Repair for Burn/Exe/Nullsoft/Inno installer types without custom repair switch. The possible options are:\r\n   - Download matching installer , uninstall & Install OR \r\n   - Download matching installer & re Install to overwrite existing files.\r\n\r\n## Resources\r\n- https://learn.microsoft.com/en-us/windows/msix/desktop/managing-your-msix-reset-and-repair\r\n- https://learn.microsoft.com/en-us/windows/win32/msi/reinstalling-a-feature-or-application\r\n- https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/msiexec#repair-options\r\n- https://learn.microsoft.com/en-us/uwp/api/windows.applicationmodel.store.preview.installcontrol.appinstallmanager.startproductinstallasync?view=winrt-22621\r\n- https://learn.microsoft.com/en-us/windows/win32/api/msi/nf-msi-msireinstallproductw\r\n"
  },
  {
    "path": "doc/specs/#163 - Dependencies.md",
    "content": "---\nauthor: Demitrius Nelon denelon/denelon@microsoft.com\ncreated on: 2021-05-06\nlast updated: 2021-05-06\nissue id: 163\n---\n\n# Dependencies\n\n\"For [#163](https://github.com/microsoft/winget-cli/issues/163)\"\n\n## Abstract\n\nSeveral packages require other packages as dependencies. The Windows Package Manager should be able to support declared dependencies. In the best case scenario the Windows Package Manager should be able to install any necessary dependencies a package needs. In the worst case scenario the Windows Package manger should be able to inform a user about any required dependencies not able to be installed automatically.\n\n## Inspiration\n\nMany other package mangers have this capability. It's frustrating to be required to figure out what other dependencies are needed for a package, and have to deal with their dependencies as well.\n\n## Solution Design\n\nThe Windows Package Manager manifest v1.0 schema has provided keys for four different types of dependencies.\n\n@Conan-Kudo [suggested](https://github.com/microsoft/winget-cli/issues/163#issuecomment-631091560) evaluating [openSUSE/libsolv](https://github.com/openSUSE/libsolv).\n\nFour different types of dependencies have been declared in the [v1.0 manifest schemas](https://github.com/microsoft/winget-cli/blob/master/schemas/JSON/manifests/v1.0.0/).\n\n* Windows Features\n* Windows Libraries\n* Package Dependencies (same source)\n* External Dependencies\n\nEach of these dependencies must be declared in the manifest. In the case of MSIX packages, the dependencies are not required to be declared in the manifest.\n\nThe implementation for dependency support should initially be enabled as an experimental feature.\n\nEach of the dependency types should be handled the same way for the minimum viable approach. A warning should be presented to the user with the list of dependencies specified in the manifest.\n```\nwarning: This package requires the following dependencies:\n<dependency type>: <dependency>\nDo you have these dependencies installed [y/n]?\n```\nIf the user chooses \"yes\", the installation will proceed.\n\nNote: This is essentially the complete implementation for External Dependencies. It is not required at this stage to deal with nested dependencies.\n\nIn addition, the consumes and provides concept is not in scope with this implementation.\n\n### Windows Features\nThese include items like .NET Frameworks, Internet Information Services, and Windows Subsystem for Linux. In some cases, turning these features on may require a reboot.\n\n### Windows Libraries\nThese include items like Microsoft.WinJS or Visual C++ Redistributable libraries.\n\n### Package Dependencies\nThese include other packages. The restriction on these dependencies is that they come from the same source for the package to be installed. These include programming languages, runtime environments, or drivers.\n\n### External Dependencies\nThese include dependencies from outside of the source the original package is distributed. In some cases suitable items may exist in the same source, but for licensing or personal preference, no explicit package should be required. One example is Java. Many vendors offer JREs and JDKs so it may be more reasonable to have a user informed, and allow the user to confirm the presence of a dependency.\n\nAs a first step the Windows Package Manager should show dependency information to the user, see issue [1012](https://github.com/microsoft/winget-cli/issues/1012) with [spec](./#1012%20-%20Show%20dependencies.md).\n\n## UI/UX Design\n\n@dustojnikhummer [suggested](https://github.com/microsoft/winget-cli/issues/163#issuecomment-633901489) a syntax like:\n\n`winget install package -y` to install all dependencies and then the package and `winget install package` to prompt the user for each required dependency before installing it.\n\n## Capabilities\n\nSeveral different package installers exist and treat dependencies differently.\n\nMSIX installers have an internal mechanism to identify dependencies.\n\nMSI and .exe installers may include dependencies.\n\n### Accessibility\n\nThe Windows Package Manager has been built in such a way that screen readers will still provide audible output as the command is executed keeping the user informed of progress, warnings, and errors. This should have no direct impact on accessibility.\n\n### Security\n\nThere should be no security impact directly, although we must remember that different sources may not guarantee the safety of packages. The Windows Package Manager community repository performs static and dynamic analysis, and in some cases additional manual validation before accepting a package.\n\n### Reliability\n\nThe Windows Package Manager community repository does not directly host packages that may be called as dependencies. These packages may be removed or become unavailable if the site they are hosted on encounters a failure (or no network access is available).\n\n### Compatibility\n\nNo current implementation for dependencies exists, so no compatibility issues are expected to occur as a result of dependency support.\n\n### Performance, Power, and Efficiency\n\nThe time needed to download and install a package and it's dependencies is directly related to network speed and the size of any packages.\n\n## Potential Issues\n\nNot all dependencies are identified using [semantic versioning](https://semver.org/). This may cause complications for packages depending on a range of versions. It is possible a breaking change is introduced in a newer version of a dependency the Windows Package Manager cannot heuristically reason about.\n\nSome systems have limited storage, and may not have suitable space to install a package and all of it's dependencies.\n\n## Future considerations\n\nThe import command may be able to take advantage of determining all dependencies for all packages, and avoid repeatedly installing the same dependencies multiple times.\n\n## Resources\n\n[RPM Dependencies](https://jfearn.fedorapeople.org/en-US/RPM/4/html/RPM_Guide/ch-advanced-packaging.html)\n\n[Node.js package.json configuration](https://docs.microsoft.com/visualstudio/javascript/configure-packages-with-package-json?view=vs-2019#:~:text=package.json%20configuration%201%20In%20a%20major%20version%20update%2C,fixes%20are%20included.%20Bug%20fixes%20are%20always%20backwards-compatible.)\n\n[R Package metadata](https://r-pkgs.org/description.html)\n\n[Debian package relationships](https://www.debian.org/doc/debian-policy/ch-relationships.html)\n\n[Brew Untangling Dependencies](https://blog.jpalardy.com/posts/untangling-your-homebrew-dependencies/)\n\n[Scoop Dependencies](https://scoop.netlify.app/concepts/#dependencies)\n\n[Chocolatey Create Packages](https://docs.chocolatey.org/en-us/create/create-packages)\n"
  },
  {
    "path": "doc/specs/#164 - PWA Support.md",
    "content": "---\r\nauthor: Amrutha Srinivasan @amrutha95\r\ncreated on: 2020-08-19\r\nlast updated: 2020-08-19\r\nissue id: 164\r\n---\r\n\r\n# Spec Title\r\n\r\nFor [#164](https://github.com/microsoft/winget-cli/issues/164)\r\n\r\n## Abstract\r\n\r\nThis feature adds PWA (Progressive Web Application) support to winget. The goal is to allow users to install and maintain PWAs just like they would any other type of application on winget. As a first step, this would be available as an \"experimental\" feature to make it available to the community and receive feedback.\r\n\r\n## Inspiration\r\n\r\nPWA adoption is extremely important in the Windows app ecosystem. It is also crucial that they are treated as first class citizens in the app ecosystem, just like any native application. Providing PWA support for winget is key to achieving this goal.\r\n\r\n## Solution Design\r\n\r\n### System requirements\r\n\r\nWindows 10 v2004 or newer\r\nEdge latest Canary build\r\n\r\n### PWA YAML manifest\r\n\r\nThe \"InstallerType\" field in the YAML manifest file specifies the type of the application. A new InstallerType \"PWA\" will be added to show that a given application is a PWA.\r\n\r\nEach PWA would have its own manifest YAML file. A sample manifest file would look like this:\r\n\r\n```\r\nId: FinancialTimesLimited.FinTimes\r\nVersion: 1.0.0.0\r\nName: AppInstaller FinTimes\r\nPublisher: Financial Times Limited\r\nAppMoniker: fintimes\r\nLicense: Test\r\nInstallerType: PWA\r\nMinOSVersion: 10.0.19041.0\r\nInstallers:\r\n- Arch: x64\r\n  Url: https://app.ft.com\r\n  InstallerType: PWA\r\nManifestVersion: 0.1.0\r\n```\r\n\r\n### Package generation\r\n\r\nA POST call is made to a web service (https://pwabuilder-win-chromium-platform.centralus.cloudapp.azure.com) with a JSON body containing the URL to the PWA. The web service packages the PWA and its assets into an unsigned MSIX. An example of the JSON body would be :\r\n\r\n```\r\n{\r\n    \"url\": \"https://app.ft.com\"\r\n}\r\n```\r\n\r\nThere are many more optional parameters that can be passed to this service. For more information, refer to the test website linked in the Resources section.\r\n\r\n### Package installation\r\n\r\nThe unsigned MSIX package and any other dependency packages are added for the current user and the application is silently installed on the user's system. The installation is done by calling the Windows API AddPackageByUriAsync() using the specific deployment options that allow unsigned packages.\r\n\r\n### Flow of the install process\r\n\r\n1. User types the install command, eg. `winget install fintimes` (For the experimental version, the manifest will be passed as an argument)\r\n2. The URL from the manifest YAML file of the Financial Times PWA will be sent as a POST request to an internal web service that will generate an unsigned MSIX package. This MSIX package is downloaded onto the user's system.\r\n3. The generated package will then be silently installed as a Hosted App (Refer to resources for more on the Hostel App Model).\r\n4. The MSIX file is removed from the user's system.\r\n\r\n## UI/UX Design\r\n\r\nInstalling a PWA will be similar to installing other application types currently supported by winget, using the install command. The only difference in experience might be if the user passes a -i flag to get a more interactive experience. When this flag is passed, the user will be prompted to allow the PWA to be launched on install. This feature is provided because in order to register a PWA with Edge, it has to be launched once.\r\n\r\nAn example of the interactive install would look like this:\r\n\r\n```\r\n>winget install -i fintimes\r\nFound Financial Times [PWAtest.FinTimes]\r\nThis application is licensed to you by its owner.\r\nMicrosoft is not responsible for, nor does it grant any licenses to, third-party packages.\r\nStarting package install...\r\n<Progress bar>\r\nSuccessfully installed! Launching app now. This is a necessary step to complete installation.\r\n(App launches on Edge)\r\n```\r\n\r\n## Capabilities\r\n\r\n### Accessibility\r\n\r\nThis should have no direct impact on accessibility.\r\n\r\n### Security\r\n\r\nNo direct impact on security.\r\n\r\n### Reliability\r\n\r\nThis is not expected to impact reliability.\r\n\r\n### Compatibility\r\n\r\nThis is an additional functionality built on top of the existing implementation to allow the install of PWAs. Therefore we don't anticipate any breaking changes to the existing implementation.\r\n\r\n### Performance, Power, and Efficiency\r\n\r\n## Potential Issues\r\n\r\nIf the user navigates to the site before launching the installed PWA at least once (i.e. before registration with Edge), Edge might prompt them to install the PWA again.\r\n\r\n## Future considerations\r\n\r\n1. We are looking into where the catalog of PWAs should exist, and the pros and cons of maintaining a separate catalog vs including PWAs on the existing catalog.\r\n2. We're testing this new integration technology with Edge first in 2020 and hope to have this debugged and contributed to the Chromium project early 2021.\r\n3. Sometimes there may be multiple versions of a PWA available. In such scenarios, we may allow a \"force\" option in the case where a user wants all of them to be installed.\r\n4. There will be a service developed in the future that updates all the PWA manifests whenever there is a breaking change in Edge or in the web service that generates MSIX packages.\r\n\r\n## Resources\r\n\r\nHosted App Model : https://blogs.windows.com/windowsdeveloper/2020/03/19/hosted-app-model/\r\nTest Website for generating MSIX for PWA : https://pwabuilder-win-chromium-platform.centralus.cloudapp.azure.com/\r\n"
  },
  {
    "path": "doc/specs/#182 - Support for installation of portable standalone apps.md",
    "content": "---\nauthor: Demitrius Nelon @denelon\ncreated on: 2022-03-09\nlast updated: 2022-04-07\nissue id: 182\n---\n\n# Portable/Standalone applications\n\n\"For [#182](https://github.com/microsoft/winget-cli/issues/182)\"\n\n## Abstract\n\nSeveral packages do not have an installer. They are simply a binary executable. This specification describes how these types of programs will be treated as \"packages\" by the Windows Package Manager.\n\n## Inspiration\n\nJust because an installer doesn't exist for a particular package doesn't mean you shouldn't be able to install it with the Windows Package Manager.\n\n## Solution Design\n\nThe installer type “portable” will be added to the enumerated list of installer types to support these types of packages.\n\nWhen one of these packages is encountered, there are several aspects to “installing” these packages and supporting the “upgrade” behavior. Notable concerns include the location of the package, creating or updating an entry in Windows Apps & Features.\n\n### Command Line Arguments\n\nUsers should be able to specify the location for where the program is “installed” on their machine with the “--location” argument.\n\nSome packages like GitLab Runner have a file name including extra metadata (gitlab-runner-windows-386.exe). The installation instructions suggest renaming the file after it has been downloaded. In that vein, a \"--rename\" argument should be added so the user can choose a value they prefer. To have the upgrade scenario honor the custom name, this information should be recorded in the installed packages data store.\n\nPortable / standalone executables should have their “command” value specified so the Windows Package Manager can determine the default value to use when creating a new entry in the \"App Paths\" registry during installation. If no command value is provided, then the entry will use the filename of the exe.\n\nSome portable applications generate or consume other files. An additional argument \"--purge\" will be added for the uninstall scenario to remove all files and subsequently the directory if the user wishes. The corollary argument \"--preserve\" will be used to preserve files if the default setting has been modified.\n\n### Settings\n\nUsers should have settings to be able to specify a new default location other than the system default for the Windows Package Manager.\n\nThe default path for installing these packages is \"%LOCALAPPDATA%/Microsoft/WinGet/Packages/\" for user based installs. The default path for installing these packages is \"Program Files/WinGet/Packages/\" for machine wide x64 installs and \"Program Files (x86)/WinGet/Packages/\" for machine wide x86 installs.\n\nThe corresponding settings are \"PortablePackageUserRoot\" and \"PortablePackageMachineRoot\".\n\n>Note: The \"packageIdentifier\" will be used to generate subdirectories for these binaries to be installed to.\n\nUsing GitLab.gitlab runner as an example would result in the .exe being placed in \"%LOCALAPPDATA%/Microsoft/WinGet/Packages/GitLab.gitlab-runner/\"\nIf a user has configured a path to be used for portable applications, that path should be honored. The user should also be able to specify if they want all portable packages placed in the same directory, or in a directory per package.\n\nA related setting for the uninstall scenario will be able to specify the default behavior for either \"--clean\" or \"--purge\".\n\n### Install\n\nWhen the portable application is being installed by the Windows Package Manager, an entry will be created in Windows Apps & Features so the user will be able to see that the application is installed.\n\nOnce the portable application is copied to the appropriate install location based on the preferences of the user, a symlink will be created that points to the portable application. The locations where these symlinks will be stored are \"%LOCALAPPDATA%/Microsoft/WinGet/Links/\" for user based installs, \"Program Files/WinGet/Links/\" for machine wide x64 installs and \"Program Files (x86)/WinGet/Links/\" for machine wide x86 installs. We will then append these paths to the PATH environment variable if they do not exist already.\n\nThe filename of the symlink file determines the command alias that will be used when being executed in the command prompt. By default, the symlink filename we be the same as the filename of the portable exe. If a command value is specified in the manifest, then the symlink filename will be renamed to match the command value. If the rename argument is provided, then both the symlink filename and the portable exe filename will be renamed to match the rename argument value.\n\n>Note: In our initial design, we had opted to only writing to the \"AppPath\" registry subkey to install/register the portable application. However, we determined that this is not sufficient to support command-line execution, which does not look in the \"AppPath\" registry when locating executables.\n\nThe data from “AppsAndFeaturesEntry” in the manifest will be used to specify the name of the package in Windows Apps & Features.  Constraints for manifests with portable packages are covered below in the section on validating manifests. If the “AppsAndFeaturesEntry” doesn’t have a “DisplayName” value, then we will use the “PackageName”.\nThe Product Code will be populated with the \"PackageIdentifier\" if it is not specified in the “AppsAndFeaturesEntry”.\n\nNo shortcuts or icons will be created for the package.\n\n>Note: Some portable programs may require dependencies. Dependencies are not covered in this specification and are not yet supported as of the writing of this specification.\n\n#### Scope Behavior\n\nBy default, portable apps will be installed with the \"User\" scope unless specified otherwise by the user through the \"--scope\" argument or in their settings. This also means that the \"scope\" field in the manifest will be ignored when installing portable apps. Since portable apps are unique in that they are simply standalone executables that are copied to a specific install location based on scope, it does not seem reasonable to have the manifest enforce an install behavior that is not required. Manifest validation would also need to be updated to show an error to the user that the \"scope\" field does not apply if a portable installer type is specified.\n\n#### Installation from multiple sources:\n\nIf the user chooses to install the same package but from a secondary source, the Windows Package Manager will append the source name to subdirectory. For example, if GitLabRunner is installed a second time but from the msstore, then the full path would be \"%LOCALAPPDATA%/Microsoft/WinGet/Packages/GitLab.GitLabRunner_msstore/\".\n\nThe same behavior will be applied when creating a symlink in order to avoid overwriting an existing symlink of the same package but from a different source. Using the same example, the generated symlink for GitLabRunner from the msstore will have a full path of \"%LOCALAPPDATA%/Microsoft/WinGet/Links/GitLab.GitLabRunner_msstore.exe/\"\n\n### Upgrade\n\nThe package is upgraded in the same path as the installed version. The first step the Windows Package Manager will perform is to download the executable to a temporary location, and attempt to copy the exe to the specified install location. If an exe with the same name already exists, the Windows Package Manager will attempt to overwrite the file. If that process fails because the file is currently in use, the user will be informed the package is running so they can shut it down. Optionally, the user may specify \"--force\" to forcefully shut the application down for upgrade. Once the exe has successfully been copied to the specified install location, the entry in \"Apps & Features\" will be updated accordingly and the symlink will be overwritten to point to the latest portable exe.\n\nIf the \"UninstallPrevious\" field is specified in the manifest, then the Windows Package Manager will perform an uninstall of the previous version of the package prior to installing the newer version.\n\nA new Windows Apps & Features entry is created to correctly report the upgraded version for future potential upgrades.\n\nThere will be no support for installing multiple “side by side” versions of portable packages.\n\n### Uninstall\n\nThe executable and the symlink should be removed along with the entry in Apps & Features. The user should also be able to uninstall the package from Apps & Features.\n\n>Note: The default behavior for uninstalling a portable application with Windows Apps & Features will be to execute uninstall without \"--purge\" so any files created by the portable application will be remain if they are located in the portable applications directory. An additional argument for \"--wait\" will be added that will prompt the user to press any key to exit. This is intended to support this scenario so that the user is aware of any remaining files if they choose to uninstall through Windows Apps & Features.\n\nIf the directory is empty after removing the portable application, the directory should also be deleted. If the directory is not empty, the user should be informed that other files exist in the directory so it will not be removed.\n\n### Manifest Validation\n\nPortable package manifests will only support zero or one \"command\" value to be specified. In the absence of the \"--rename\" argument, the value specified in \"command\" will define the default value for naming the symlink file that is created to point to the portable application.\n\nIf a value for \"scope\" is specified for a portable installer, the user should be shown an error that the \"scope\" field is not supported for portable installers.\n\nOnly zero or one entry for \"Apps & Features\" can be specified for a portable installer.\n\n## UI/UX Design\n\n### Installing a portable package\n\n```text\nwinget install Microsoft.NuGet\nFound NuGet [Microsoft.NuGet] Version 6.0\nThis application is licensed to you by its owner.\nMicrosoft is not responsible for, nor does it grant any licenses to, third-party packages.\nDownloading https://dist.nuget.org/win-x86-commandline/v6.0.0/nuget.exe\n  ██████████████████████████████   0.1 MB /  0.1 MB\nSuccessfully verified installer hash\nStarting package install...\nSuccessfully installed\n```\n\n### Upgrading a portable package\n\n```text\nwinget upgrade Microsoft.NuGet\nFound NuGet [Microsoft.NuGet] Version 7.0\nThis application is licensed to you by its owner.\nMicrosoft is not responsible for, nor does it grant any licenses to, third-party packages.\nDownloading https://dist.nuget.org/win-x86-commandline/v7.0.0/nuget.exe\n  ██████████████████████████████   0.1 MB /  0.1 MB\nSuccessfully verified installer hash\nStarting package install...\nSuccessfully installed\n```\n\nIf the portable application is running when the user performs an upgrade, the user will be informed.\n\n```text\nwinget upgrade Microsoft.NuGet\nFound NuGet [Microsoft.NuGet] Version 7.0\nThis application is licensed to you by its owner.\nMicrosoft is not responsible for, nor does it grant any licenses to, third-party packages.\nDownloading https://dist.nuget.org/win-x86-commandline/v7.0.0/nuget.exe\n  ██████████████████████████████   0.1 MB /  0.1 MB\nSuccessfully verified installer hash\nStarting package install...\nFailed to install NuGet [Microsoft.Nuget].\nPackage in use. Either exit the program or use \"--force\" to upgrade.\n```\n\n### Uninstalling a portable package\n\n```text\nwinget uninstall NuGet\nFound NuGet [Microsoft.NuGet]\nStarting package uninstall...\nSuccessfully uninstalled\n```\n\nIf the portable application created files in the portable application's directory, the user will be informed.\n\n```text\nwinget uninstall NuGet\nFound NuGet [Microsoft.NuGet]\nStarting package uninstall...\nThe \"--purge\" argument was not specified.\nFiles still exist in \"%LOCALAPPDATA%/WinGet_Packages/User/Microsoft.NuGet/\".\nSuccessfully uninstalled\n```\n\n## Capabilities\n\nThis will allow users to manage portable applications via the Windows Package Manager.\n\n### Accessibility\n\nAny description or output text that is added by consequence of this feature will need to be localized. Moreover, this feature allows a mechanism to add accessibility settings in the future.\n\n### Security\n\nThis feature will not add any new security risks. All risks associated with this feature have been resolved with the core install, import, upgrade, and uninstall features.\n\n>Note: We recommend users leverage the Windows Sandbox when testing manifests on their local machines as the programs may not have been validated from a security perspective prior to being submitted to the Windows Package Manager Community App Repository.\n\n### Reliability\n\nThis should not introduce any new reliability concerns.\n\n### Compatibility\n\nPrevious versions of the Windows Package Manager will not cease to function, but they will not be able to apply arguments or settings related to this feature. They will not be able to install portable applications.\n\nAn update to the Windows Package Manager is required to use this feature with the related arguments and settings.\n\n### Performance, Power, and Efficiency\n\nThis should not introduce any new performance, power, or efficiency concerns in the Windows Package Manager.\n\n## Potential Issues\n\nUsers may not be aware that there is no support for multiple versions of the same package on their system, so performing an upgrade may not provide they experience they were expecting.\n\nUsers may not be aware that the uninstall behavior by default may leave files on their systems if they were created by a portable application.\n\nIf a user performs uninstall via Windows Apps & Features the default behavior will be to run `winget uninstall package --purge`. If a user removes the \"App Installer\" they would not be able to perform uninstall.\n\nDisplaying a path may be improved with detecting the shell the Windows Package Manager is being executed in. An [Issue](https://github.com/microsoft/winget-cli/issues/1977) was already raised covering the differences in how CMD and PowerShell render or support file system paths.\n\n## Future considerations\n\nSome portable applications have icons. The options for creating shortcuts with icons could be considered in the future.\n\nSupport for channels has not yet been implemented. Some portable applications may have \"beta\" and \"stable\" releases. Users may want to have support for both in the future.\n\n## Resources\n\n[Portable / Standalone Executables · Discussion #1887 · microsoft/winget-cli (github.com)](https://github.com/microsoft/winget-cli/discussions/1887)\n\n[Application Registration - Win32 Apps](https://docs.microsoft.com/windows/win32/shell/app-registration)\n\n"
  },
  {
    "path": "doc/specs/#190 - Proxy Support.md",
    "content": "---\nauthor: Flor Chacon @florelis\ncreated on: 2024-02-07\nlast updated: 2024-02-07\nissue id: 190\n---\n\n# Proxy support\n\nFor [#190](https://github.com/microsoft/winget-cli/issues/190)\n\n## Abstract\n\nThis spec describes a feature to specify a proxy for winget to use when connecting to the internet.\n\n## Solution Design\n\nA new command line argument will be added to specify a proxy to use during a particular invocation of winget.\nThis functionality will first need to be enabled through an admin setting, similar to local manifests or hash override.\n\nAn option to set a default proxy to use on every flow will be added, but it will require administrator permissions to be set.\n\nNew Group Policy will also be added for IT admins to control the use of proxies.\nThe policies will be similar to those we already have for sources, so that a specific proxy can be required or only a predefined set of proxies can be allowed.\n\nProxies will not be used for the configuration features for now.\nProxy settings in winget will not affect the behavior of installers themselves, so an installation may still generate traffic outside of the proxy.\n\nThe proxy will be used to download the installers and access the sources.\n\nSince the APIs used for Delivery Optimization and MSIX deployment do not provide a way to specify a custom proxy, if a proxy is specified, we will change the use of those APIs to accomodate the proxy.\nFor Delivery Optimization, a proxy will force use of WinINet instead.\nFor MSIX deployment, the packages will be fully downloaded before deploying; this will require more network traffic than a streaming install of only the required bits.\n\n## UI/UX Design\n\nWe will add a command line argument taking the URI to the proxy.\nA separate argument will be available to disable the use of proxy if there is a default set.\nBoth of these arguments will be disabled by default and require admin privileges to enable.\n\n```\n> winget settings --enable ProxyCommandLineArgument\n> winget install Contoso.App --proxy https://127.0.0.1:2345\n> winget install Contoso.App --no-proxy\n```\n\nTo configure the default proxy, new `set` and `reset` subcommands will be added to the `settings` command.\nThis will require admin privileges and does not require `ProxyCommandLineArgument` to be enabled.\n\n```\n> winget settings set DefaultProxy https://127.0.0.1:2345\n> winget settings reset DefaultProxy\n```\n\nThe current default proxy will be added to the output `winget --info`.\n\n## Capabilities\n\n### Accessibility\n\nThis should have no direct impact on accessibility.\n\n### Security\n\nThere is a possibility of an attacker using a malicious proxy to tamper with the data received from the source, or with the contents of the installer file.\nThis is not much different from the risks of using a public network.\nThe following mitigating factors will be in place:\n* (New) The ability to set a default proxy will be restricted to administrators, to prevent attackers from adding a proxy without the user realizing.\n* (New) A Group Policy will be available to block the use of proxies, require the use of a specific proxy, or limit them to an approved list.\n* Pre-indexed sources need to be signed, and the publisher is required to match during source update.\n  When initially adding the source, administrator privileges are already required to limit misuse.\n* Pre-indexed sources include manifest hashes in the local database, to ensure that the manifest downloaded later is as expected.\n* For the Microsoft Store source, we use certificate pinning to ensure we are talking to the right server.\n* When communicating with REST sources, the certificate used by the source for HTTPS needs to match the domain.\n* Manifests include a hash of the installer that is validated before executing it.\n  The ability to ignore installer hash mismatches is disabled by default, and enabling it requires administrator privileges.\n\n### Compatibility\n\nNo breaking changes to existing behavior.\n\n### Performance, Power, and Efficiency\n\nThere should not be any notable performance changes.\n\n## Potential Issues\n\nA faulty or misconfigured proxy could impact most of winget's functionality, but it can be worked around by disabling the use of the proxy.\n\n## Future considerations\n\nThings we may want to consider in the future:\n* Extend support for proxies to the Configuration feature\n* Add proxy support to the COM API\n* Add support for proxies that require authentication\n* Add the ability for admins to set multiple allowed proxies that a user can use\n* Add the ability to specify a different default proxy for each source\n* Use proxies with Delivery Optimization. This requires changes to the Delivery Optimization APIs.\n"
  },
  {
    "path": "doc/specs/#292 - winget should install an app if there is an exact match.md",
    "content": "---\nauthor: Demitrius Nelon @denelon\ncreated on: <2020-05-28>\nlast updated: <2020-05-28>\nissue id: 292\n---\n\n# Package matching bug fix\n\nFor [#292](https://github.com/microsoft/winget-cli/issues/292)\n\n## Abstract\n\nThe winget.exe client attempts to be generous with the `search` command, but is a bit too generous with `install`. The *id*\nshould be the unique key to identifying a package (other than the package version). It should also be case-insensitive from the perspective of command execution, but it should be case-sensitive in terms of the displayed value.\n\nIf a manifest was created with the *id* \"Git.Git\" then that is what would be displayed in the client output.\nAny combination of case in the `install` command should match.\n\nIf multiple versions of the package have been created, and they differ in the casing for the *id* then the most recent version\nof the manifest should be used for displaying the characters in the search output.\n\nThe latest version of a package is also the version that should be displayed during `search`, and subsequently installed.\n\n## Inspiration\n\n`winget install git.git` should work.\n\n## Solution Design\n\nInstalling a package by using the *Id* as the package name should not require disambiguation.\nThe package *Id* should perform a case-insensitive match. If the given *Id* is exact, it should not\nbe confused with a longer *Id*\n`winget install git.git` should install that package\nThe `git.gitLFS` should not cause ambiguity\n\nIf the value passed as a package *Id* is a substring, or there is still ambiguity, the help text should provide an example.\n\n## UI/UX Design\n\nExecuting `winget install git.git` will install the Git package.\nExecuting `winget install git.g` will provide additional guidance:\nMultiple apps found matching input criteria. Please refine the input.\nTry providing the Id: winget install git.git\n\nFor the example above, the help could default to the Id for the top listed package from the search result.\n\n## Capabilities\n\nThis should help reduce the friction for users trying to install a package when there is ambiguity.\n\n### Accessibility\n\nThis may have an impact on users with screen readers. The goal is to provide additional context for this scenario.\n\n### Security\n\nThis should not introduce any _new_ security concerns.\n\n### Reliability\n\nThis is not expected to impact reliability.\n\n### Compatibility\n\nThis changes existing behavior with `install`, but is expected to be an improvement. There are no known unintended consequences.\n\n### Performance, Power, and Efficiency\n\n## Potential Issues\n\nUsers may not realize another package exists with a longer name, and may install a program other than what they intended.\nIf \"git.git\" and \"git.gity\" both existed and the user were to press enter before typing the final \"y\", the git.git package would\nbe installed rather than what they intended.\n\n## Future considerations\n\nThere are changes to how results should displayed to reduce the likelihood of a user mistakenly assuming the \"Name\" is a key value\nfor a package. The client commands should be case-insensitive, but the display should still be case-sensitive to support ease of\nreading. Long names can be easier to understand when presented in camel case, pascal case, or with a branded letter casing.\nThe client also needs a mechanism to display all of the available versions of a package.\n\n## Resources\n\nN/A\n"
  },
  {
    "path": "doc/specs/#3026 - Bypass Microsoft Store blocked for COM API.md",
    "content": "---\nauthor: Roy MacLachlan RDMaclachlan/roy.maclachlan@microsoft.com\ncreated on: 2023-02-09\nlast updated: 2023-02-09\nissue id: 3025\n---\n\n# Bypass Microsoft Store blocked for COM API\n\n\"For [#3025](https://github.com/microsoft/winget-cli/issues/3025)\"\n\n## Abstract\n\nThis spec describes allowing WinGet install COM APIs to install applications from the Microsoft Store when the Store application has been disabled through group policy object or SLAPI policies.\n\n## Inspiration\n\nThis is inspired by\n* Enterprise customer feedback requiring the ability to disable the Microsoft Store on Enterprise devices but capable of delivering Microsoft Store apps through deployment technologies (Example: Microsoft Intune).\n* Education customers feedback requiring the ability to control what a student can install on education devices, while continuing to leverage deployment technologies (Example: Microsoft Intune).\n\n\n## Solution Design\n\nThe Windows Package Manager will allow the WinGet COM APIs to perform Microsoft Store application installations that will bypass the check on Microsoft Store is blocked by policy (IsStoreBlockedByPolicyAsync). Both the WinGet command line interface (CLI) and WinGet PowerShell commands will continue to block application installations from the Store when the Microsoft Store is blocked by policy.\n\nThe checks on Microsoft Store blocked by policy will allow calls through COM, with the exception of PowerShell and CLI.\n\n## UI/UX Design\n\nNone.\n\n## Capabilities\n\n### Accessibility\n\nNone.\n\n### Security\n\nNone.\n\n### Reliability\n\nNone.\n\n### Compatibility\n\nThis proposed change will allow IT Administrators to allow the installation of Microsoft Store applications using the WinGet while preventing users from using the Microsoft Store application to search and install applications.\n\nThis setting is an override that will be disabled by default.\n\n### Performance, Power, and Efficiency\n\n## Potential Issues\n\nNone.\n\n## Future considerations\n\nNone.\n\n## Resources\n\nN/A\n"
  },
  {
    "path": "doc/specs/#364 - Feature Toggle.md",
    "content": "---\nauthor: John McPherson @JohnMcPMS\ncreated on: 2020-06-04\nlast updated: 2020-06-04\nissue id: 364\n---\n\n# Feature Toggle\n\nFor [#364](https://github.com/microsoft/winget-cli/issues/364)\n\n## Abstract\n\nAs features are implemented within winget, they may cause disruption to users oblivious to the fact that they are in progress. In order to allow work to be done in master, and distributed to early adopters for their feedback, this spec suggests that settings should be used to control \"experimental\" features. We use this term [as others have](https://github.com/PowerShell/PowerShell-RFC/blob/master/Final/RFC0029-Support-Experimental-Features.md) to mean work in progress that is not yet ready for release to the general audience.\n\n## Inspiration\n\nWe realize that we need to be able to:\n1. deliver work in progress to users so that we can receive feedback\n2. work in master without creating multiple, divergent branches\n3. not disrupt users who do not wish to investigate unfinished features\n\nThank you to @megamorf for the link to the PowerShell Experimental Features RFC.\n\n## Solution Design\n\nA new settings block will be added to the settings file for experimental features to be toggled. By default, all experimental features will be disabled.\n\nA hidden command will be added to the root:\n```\n>winget features\nThe following experimental features are in progress.\nThey can be configured through the settings file (winget settings).\n\nFeature  Status   Link\n--------------------------------------------------------------------\nExample1 Enabled  https://github.com/microsoft/winget-cli/issues/364\nExample2 Disabled https://github.com/microsoft/winget-cli/issues/396\n```\nWhen run, this command will give the status of each feature (enabled/disabled), as well as a link to the Issue or Spec.\n\nInternally, a single flag enum will be used to reference experimental features. All command line parsing objects will have a field added for the feature(s) to which they belong. Any internal behavioral changes will be made based on a check using this enum. In this way, transitioning a feature either to release or remove can be done by finding by a single identifier.\n\nA feature is released by removing the feature enum value in code, and all related references. The value in settings will become ignored, and we can keep a list in a comment to prevent future reuse of settings names.\n\n## Settings File\n\nTo enable experimental features a user will need to modify the settings file. The settings file can be opened via the settings command.\n\n```\n  \"experimentalFeatures\": {\n      \"example1\": true,\n      \"example2\": false,\n      \"example3\": true\n  }\n```\n\n## UI/UX Design\n\nExperimental features can impact the winget user interface in 2 ways; new commands and options. Both will be added to the parse tree, but hidden from help view if disabled. When enabled, they will be labeled as experimental to reiterate this to the user. If a user attempts to use an experimental command or option that is not enabled, a special error will be presented to indicate that this feature is experimental and must be enabled via settings.\n\nIf the feature needs settings after release, they should be added as part of the feature work, and can be tagged with the enum value as well.\n\n## Capabilities\n\n\n\n### Accessibility\n\nThis should have no direct impact on accessibility.\n\n### Security\n\nThere should be no security impact directly, although we must remember that any medium IL process will be able to enable any feature by writing to the settings file. But any experimental feature should be created with the intention of becoming released, and so should have its own security consideration.\n\n### Reliability\n\nOne of the goals is to increase reliability for unaware users, so that they do not accidentally stumble into an incomplete feature.\n\n### Compatibility\n\nNo breaking changes to existing behavior.\n\n### Performance, Power, and Efficiency\n\n## Potential Issues\n\nNo known issues.\n\n## Future considerations\n\nThis feature enables all larger features in the future to have a phased rollout.\n\n## Resources\n\n[PowerShell Experimental Features RFC](https://github.com/PowerShell/PowerShell-RFC/blob/master/Final/RFC0029-Support-Experimental-Features.md)\n"
  },
  {
    "path": "doc/specs/#396 - Settings command.md",
    "content": "---\nauthor: Ruben Guerrero @msftrubengu\ncreated on: 2020-06-03\nlast updated: 2021-07-14\nissue id: 396\n---\n\n# Settings command\n\nFor [#396](https://github.com/microsoft/winget-cli/issues/396)\n\n## Abstract\n\nThe winget.exe client must support having a feature that allows users to specify settings. This will be in the form of an editable file. The file must be in a location where a user can easily access it and modify it.\n\n## Inspiration\n\nAdd ability for user to set their own preferences.\n\n## Solution Design\n\n### Format\n\nThe WinGet settings file needs to be in a readable format for users. We considered using other options, like the registry, but having a file makes it more accessible to users.\n\n#### Option 1: YAML\n\nWinGet already knows how to handle YAML files via yaml-cpp. To follow the manifest style, the properties will be PascalCased.\n\n#### Option 2: JSON\n\nJSON is a popular format that most applications tend to use. It is also possible to parse JSON with yaml-cpp as YAML is a superset of JSON, but a proper JSON parser might be needed depending on how well yaml-cpp handles it. Options are third party JSON parsers or Microsoft cpp winrt implementation `winrt::Windows::Data::Json::JsonObject`. Properties will be camelCased.\n\nThere is also the concern about comments because JSON doesn't support them. There are different approaches we could take.\n- Go with JSON standard and support properties named `__comments` which will be ignored when parsing the file.\n- Use jsoncpp and allow C type comments.\n- Use yaml-cpp and allow YAML comments.\n\nBased on this information we are going to use JSON and jsoncpp as a parser. For the comments issue, we are having a discussion here [#416](https://github.com/microsoft/winget-cli/issues/416)\n\n### Location\n\nWinGet can either run in package context or not. That means the location of the settings file will be determined depending on the context.\n\nPackage Context: %LOCALAPPDATA%\\Packages\\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\\LocalState\\settings.json. For more about UWP file system see [this](https://docs.microsoft.com/windows/uwp/get-started/fileio-learning-track#access-the-file-system)\n\nNon-package context: %LOCALAPPDATA%\\Microsoft\\Winget\\settings.json\n\n### Command\n\nA WinGet command will be added to support settings.\n\nOptions:\n- settings (preferred)\n- config\n- configure\n\nA command is a better option than having an argument, for example `winget --settings`, because it let us add more commands into it in the future such as set and unset.\n\nThe expectation is that when the user enters `winget settings` the settings file will be opened in the user's default text editor via ShellExecute. If the user doesn't have any file type association with `.json`, the default will be to open it with notepad.exe\n\nThere will also be a telemetry point added into the command as the other commands have.\n\n### Backup Settings File\n\nA user might make a mistake that could make the settings file unparsable. To protect against this there must be a backup settings file with the latest known good settings file. The flow is the following:\n\n1. `winget settings`\n2. If settings file can be parsed copy to settings.json.backup\n3. Open settings file\n4. Wait for next command\n5. If settings file can be parsed use it; otherwise, use settings.json.backup and warn user.\n\nThis mechanism allows the settings file to be resilient against mistakes.\n\n### Creating file\n\nA settings file will only be created if the user runs `winget settings` and one of the following occurs:\n\n1. First time use: Files settings.json or settings.json.backup don't exist. Winget will create both settings.json and settings.json.backup files using the default settings text. Winget will open settings.json in an editor.\n\n2. settings.json deleted: If the settings file doesn't exist but settings.json.backup exists, the settings file will be created using settings.json.backup. Winget will open settings.json in an editor. If the user intended to remove their settings the recommendation should be an empty JSON file, not deleting the file.\n\n3. settings.json and settings.json.backup deleted: Scenario is identical to 1.\n\n### Loading settings\n\nSince the settings file doesn't exist at this time, we can't force the creation of it at WinGet install time. Moreover, the file will only be created at `winget settings` time, so any other command executed before it must work as it does right now. This means that winget must work without the existence of the file, which are the default settings.\n\nThese leave us with three different sources of settings in order of importance:\n1. settings.json\n2. settings.json.backup\n3. Default settings\n\nSetting will be loaded as following:\n\n```\nif settings exists and valid\n    load settings\nelse if backup exists and valid\n    load settings backup\nelse\n    use default settings\n```\n\nWhere valid means that syntax and semantic checks pass. For now, semantics checks will be part of the validation. If one setting is semantically incorrect and we fallback to backup proves to be annoying to users, checks can be relaxed so that only syntax failures are fatal and semantic errors are warnings. We could also in the future add a `winget settings validate` to improve the experience.\n\nWe cannot force the user to upgrade, so it is possible for someone to add a setting for a future version that is not supported. There is not an easy way to detect it which means that loading the settings will warn of an unknown property. The user will need to verify the documentation and the version of winget that is running via `winget --info`.\n\n#### Errors and Warnings\n\nLoading settings will never fail, but warnings might happen. In addition to warnings regarding syntax and semantic validation, a warning will be printed if settings.json.backup is being used. If both settings and backup files failed to load and they exist another warning will be printed. There is no warning if the files don't exist. All these warnings must be localized as other text used in the project.\n\n- Settings Warning: Settings file failed loading. Using backup file.\n- Settings Backup Warning: Settings backup failed loading. Using default settings.\n\n### Documentation\n\nAll settings must be documented in the winget-cli repository in doc\\Settings.md. The settings file will need to have a link to this file or some other Microsoft documentation site for reference.\n\n### Version property\n\nA version property can be added to the settings, such as the manifest has, to have a more structured validation. I am currently opposed to the idea because, for future settings, we will need to always bump up the version and force the users to modify two pieces: the settings they want to use and the version property. I can also see settings becoming more dynamic and bumping the version per addition/removal seems like an overkill.\n\n### Settings\n\nTwo settings will be implemented for the sake of the discussion and to not provide a setting feature without actual settings.\n\n### Progress Bar Visual Style\n\nThis setting will specify the color of the progress bar that WinGet displays. It will only support the current visual style that WinGet already supports and no new ones will be added for now.\n\nPossible values:\n1. accent (default)\n2. retro\n3. rainbow\n\n```\n  \"Visual\": {\n      \"ProgressBar\": \"accent\"\n    }\n```\n\n#### Override\n\nThe user must be able to keep using the preferred visual style via arguments as it is now. This has more priority than the style defined in the settings file, because is saying it want that style for the current run.\n\n#### Special request\n\nThe author of this document firmly believes that `--plain` must be replaced with `--retro`.\n\n### Source auto update\n\nCurrently, WinGet updates the source after 5 minutes. This setting will enable users to set the timeout in minutes.\n\nValue must be integers with a minimum of 0. An arbitrary limit can be set but is not strictly necessary. A value of 0 indicates no update.\n\n```\n  \"Source\": {\n      \"AutoUpdateIntervalInMinutes\": 5\n    }\n```\n\nHaving the unit defined in the property makes it self documented and avoids the pain of opening the settings file to see the unit.\n\nWhen the value is set to 0 it is the user responsibility to update the source if needed via `winget source update`\n\n## UI/UX Design\n\nExecuting `winget settings` will open settings file in the default text editor the user has for the file extension.\n\n## Capabilities\n\nIt will allow winget to set and define any new settings in the future.\n\n### Accessibility\n\nAny description or output text that is added by consequence of this feature will need to be localized. Moreover, this feature allows a mechanism to add accessibility settings in the future.\n\n### Security\n\nThis should not introduce any _new_ security concerns.\n\n### Reliability\n\nThis is not expected to impact reliability.\n\nSettings will not be transferred if the user changes the context in which WinGet runs. That is, if the user has the Microsoft provided WinGet package and uninstalls it and runs a non-packaged WinGet, the settings are gone. This is by design.\n\n### Compatibility\n\nPrevious versions winget will not be able to read a setting file. An update to winget is required.\n\n### Performance, Power, and Efficiency\n\nThis introduce a read file for every command being run. However this shouldn't affect the performance of WinGet.\n\n## Potential Issues\n\nIf the file isn't intuitive users will experience difficulties setting what they need.\n\n## Future considerations\n\nThis feature allows the ability to expand the customization of winget for any user. It is also designed to be expanded with future settings commands that don't fit the scope of this feature. For example, one could use `winget settings set SOME_SETTING on` to modify the settings without the need of editing a file.\n\n## References\n\n@JohnMcPMS for telling me what to type.\n"
  },
  {
    "path": "doc/specs/#476 - Package Pinning.md",
    "content": "---\nauthor: Yao Sun @yao-msft\ncreated on: 2022-10-12\nlast updated: 2022-10-12\nissue id: 476\n---\n\n# Package Pinning\n\nFor [#476](https://github.com/microsoft/winget-cli/issues/476)\n\n## Abstract\n\nThis spec describes the functionality and high level implementation design of Package Pinning feature.\n\n## Inspiration\n\nThis is inspired by functionalities in other package managers, as well as community feedback.\n- Packages may introduce breaking changes that users may not want integrate into their workflow quite yet.\n- Packages may update themselves so that it will be duplicate effort for winget to try to update them.\n- User may want to maintain some of the packages through other channels outside of winget, or prefer one source over others within winget.\n- User may want some of the packages to stay in some major versions but allow minor version changes during upgrade.\n\n## Solution Design\n\n#### Package Pinning types\nTo achieve goals listed above, winget will support 3 types of Package Pinning:\n- **Blocking:** The package is blocked from `winget upgrade --all` or `winget upgrade <specific package>`, user has to unblock the package to let winget perform upgrade.\n- **Pinning:** The package is excluded from `winget upgrade --all` but allowed in `winget upgrade <specific package>`, a new argument `--include-pinned` will be introduced to let `winget upgrade --all` to include pinned packages.\n- **Gating:** The package is pinned to specific version(s). For example, if a package is pinned to version `1.2.*`, any version between `1.2.0` to `1.2.<anything>` is considered valid.\n\nTo allow user override, `--force` can be used with `winget upgrade <specific package>` to override some of the pinning created above.\n\n#### Package Pinning Configuration Storage\n\nA separate sqlite db (other than the existing tracking catalog) will be created to store the package pinning configurations from user.\n```text\nPackageIdentifier       SourceIdentifier       Version        PinningType\n----------------------------------------------------------------------------\nMicrosoft.TestApp       winget                 1.2.*          Gating\n```\n\n**Notes:** For this iteration, winget will only support pinning packages that are locally installed and correlatable with at least one of the remote sources. Winget will record a pinned package by the PackageIdentifier and SourceIdentifier. There can only be one pinning configuration for a specific package. In the future, winget may consider pinning packages from installed packages (upon improving the installed package's PackageIdentifier logic).\n\n## UI/UX Design\n\n#### winget pin commands\n\nA new `winget pin` command with 3 sub-commands will be introduced.\n- Add package pinning configuration:\n\n  `winget pin add <package> [--version <optional gated version>] [--source <source>] [--force] [--blocking]`\n\n- Remove package pinning configuration:\n\n  `winget pin remove <package> [--source <source>] [--force]`\n\n- List package pinning configuration:\n\n  `winget pin list <package> [--source <source>]` for a specific package or `winget pin list` to list all\n\n#### Blocking\nTo block a package from upgrade, use `winget pin add <package> --blocking`\n```text\ncmd> winget pin Microsoft.TestApp --blocking\n```\nNow the pinning configuration is recorded as\n```text\nPackageIdentifier       SourceIdentifier       Version        PinningType\n----------------------------------------------------------------------------\nMicrosoft.TestApp       winget                                Blocking\nMicrosoft.TestAppStore  msstore                               Blocking\n```\n**Note:** by default packages correlated from all sources are blocked, user can pass in `--source` to block for a specific source\n\nCorresponding upgrade behavior\n```text\ncmd> winget upgrade -all\nMicrosoft TestApp is blocked from upgrade and skipped\n\ncmd> winget upgrade Microsoft.TestApp\nMicrosoft TestApp is blocked from upgrade\n\ncmd> winget upgrade Microsoft.TestApp --force\nSuccess\n```\n\n#### Pinning\nTo pin a package from `winget upgrade --all`, use `winget pin add <package>`\n```text\ncmd> winget pin Microsoft.TestApp\n```\nNow the pinning configuration is recorded as\n```text\nPackageIdentifier       SourceIdentifier       Version        PinningType\n----------------------------------------------------------------------------\nMicrosoft.TestApp       winget                                Pinning\nMicrosoft.TestAppStore  msstore                               Pinning\n```\n**Note:** by default packages correlated from all sources are pinned, user can pass in `--source` to pin for a specific source\n\nCorresponding upgrade behavior\n```text\ncmd> winget upgrade -all\nMicrosoft TestApp is pinned from upgrade and skipped\n\ncmd> winget upgrade Microsoft.TestApp\nSuccess\n```\n\n#### Gating\nTo gate a package to some specific version, use `winget pin add <package> --version <gated version>`\n```text\ncmd> winget pin Microsoft.TestApp --version 1.2.*\n```\nNow the pinning configuration is recorded as\n```text\nPackageIdentifier       SourceIdentifier       Version        PinningType\n----------------------------------------------------------------------------\nMicrosoft.TestApp       winget                 1.2.*          Gating\nMicrosoft.TestAppStore  msstore                1.2.*          Gating\n```\n**Note:** by default packages correlated from all sources are gated, user can pass in `--source` to gate for a specific source\n\nCorresponding upgrade behavior\n```text\ncmd> winget upgrade -all\nSuccess  // If the available versions for upgrade are: 1.2.3 and 1.3.0, the selected version for upgrade is 1.2.3\n\ncmd> winget upgrade Microsoft.TestApp\nSuccess  // If the available versions for upgrade are: 1.2.3 and 1.3.0, the selected version for upgrade is 1.2.3\n\ncmd> winget upgrade Microsoft.TestApp --version 1.3.0\nMicrosoft TestApp is gated to version 1.2.* Override with --force\n\ncmd> winget upgrade Microsoft.TestApp --version 1.3.0 --force\nSuccess\n```\n\n**Note:** Regarding gated version syntax, it will be mostly same as what current winget version supports, except with special `.*` in the end as wild card matching any remaining version parts if there are any.\n\nExample:\nWhen `.*` in the end is detected:\nGate version `1.0.*` matches Version `1.0.1`\nGate version `1.0.*` matches Version `1.0`\nGate version `1.0.*` matches Version `1`\nGate version `1.0.*` matches Version `1.0.alpha`\nGate version `1.0.*` matches Version `1.0.1.2.3`\nGate version `1.0.*` matches Version `1.0.*`\nGate version `1.0.*` does not match Version `1.1.1`\n\nIn rare cases where `*` is actually part of a version, only the last `.*` is considered wild card:\nGate version `1.*.*` matches Version `1.*.1`\nGate version `1.*.*` matches Version `1.*.*`\nGate version `1.*.*` does not match Version `1.1.1`\n\nIf no `.*` in the end is detected, the gate version gates to the specific version:\nGate version `1.0.1` matches Version `1.0.1`\nGate version `1.0.1` does not match Version `1.1.1`\n\n## Capabilities\n\n### Accessibility\n\nAccessibility should not be impacted by this change. There will be a few more tables printed to the terminal in certain cases, but they should use the current table implementation used by `winget upgrade` and `winget list`.\n\n### Security\n\nSecurity of the Windows Package Manager should not be impacted by this change. However, security of user's software may be, as if they pin a insecure version of a package, it will not be upgraded by Winget unless explicitly requested by user.\n\n### Reliability\n\nThe change will improve reliability, as users will be able to have fine-grained control of the Windows Package Manager's upgrade functionality to ensure their workflow is not disrupted.\n\n### Compatibility\n\nThere should not be any breaking changes to the code. Although there could be a mild breaking change to the behavior of `upgrade --all` (not all packages are upgraded anymore since pinned ones are skipped), this is purely opt-in from the user's perspective at this time (if they do not pin software, there should not be a change).\n\n### Performance, Power, and Efficiency\n\nThere should not be any notable performance changes.\n\n## Potential Issues\n\n- Installation/Upgrades from Com Apis may be impacted by user's package pinning configuration. It could be mitigated by returning a specific error code and the caller  retrying with Force option.\n- Package dependencies resolution may be impacted by user's package pinning configuration.\n- Package imports may be impacted by user's package pinning configuration.\n\n## Future considerations\n\n- Implementation in this spec only supports pinning from remote sources, so all installed versions from same package share the same pinning configuration. Winget could better support side by side installations by introducing package pinning from installed source.\n- Package pinning from user and from manifest are stored separately, we may integrate the `winget pin` commands to control package pinning from manifests.\n- A couple UI integrations can be made to `winget upgrade` and `winget list` to show pinned status during listing.\n- Dependencies flow can be improved to first check pinned status of each dependent package before trying to install all dependencies.\n- Support setting pinned state right after installation/upgrades like `winget install foo --pin`.\n- Improvements to import export commands to work seamlessly with existing package pinning configurations.\n\n## Resources\n\n- [Brew - How do I stop certain formulae from being upgraded?](https://docs.brew.sh/FAQ#how-do-i-stop-certain-formulae-from-being-updated)\n- [NPM - package.json dependencies](https://docs.npmjs.com/cli/v7/configuring-npm/package-json#dependencies)\n- [APT - Introduction to Holding Packages](https://help.ubuntu.com/community/PinningHowto#Introduction_to_Holding_Packages)\n- [Chocolatey - pin a package](https://docs.chocolatey.org/en-us/choco/commands/pin)\n\nSpecial thanks to [@jedieaston](https://github.com/jedieaston) for coming up with the initial draft of Package Pinning spec at [#1894](https://github.com/microsoft/winget-cli/pull/1894/). A lot has been discussed and this spec is much inspired from the draft.\n"
  },
  {
    "path": "doc/specs/#5949 - Authenticated GitHub API Requests for PowerShell Module.md",
    "content": "---\nauthor: Melvin Wang @wmmc88\ncreated on: 2026-02-09\nlast updated: 2026-02-26\nissue id: 5949\n---\n\n# Authenticated GitHub API Requests for PowerShell Module\n\nFor [#5949](https://github.com/microsoft/winget-cli/issues/5949).\n\n## Abstract\n\nThis spec describes adding support for authenticated GitHub API requests in the WinGet PowerShell module. The module's `GitHubClient` helper will automatically detect `GH_TOKEN` or `GITHUB_TOKEN` environment variables and use them to authenticate Octokit API calls, significantly increasing the GitHub API rate limit.\n\n## Inspiration\n\nUsers running `Repair-WinGetPackageManager` in GitHub Actions pipelines hit unauthenticated rate limits (60 requests/hour). Authenticated requests allow 5,000 requests/hour. The GitHub CLI (`gh`) already uses `GH_TOKEN` and `GITHUB_TOKEN` for the same purpose, and GitHub Actions automatically provides `GITHUB_TOKEN`.\n\nSee: https://github.com/microsoft/windows-drivers-rs/actions/runs/20531244312/job/58982795057#step:3:43\n\n## Solution Design\n\nThe `GitHubClient` class in `Microsoft.WinGet.Client.Engine` is updated to:\n\n1. Read all known token environment variables (`GH_TOKEN`, `GITHUB_TOKEN`) on construction.\n2. Log the presence or absence of each token via `StreamType.Verbose`.\n3. Select the token to use based on precedence (`GH_TOKEN` > `GITHUB_TOKEN`), matching GitHub CLI behavior.\n4. Log which token source is being used, or that no token was found.\n5. Set `Octokit.GitHubClient.Credentials` if a token is available.\n\nToken resolution is extracted into a static `ResolveGitHubToken` method for testability.\n\n### Token Precedence\n\n`GH_TOKEN` takes precedence over `GITHUB_TOKEN`, matching the [GitHub CLI convention](https://cli.github.com/manual/gh_help_environment). This is because `GH_TOKEN` is explicitly set by users, while `GITHUB_TOKEN` is automatically provided by GitHub Actions and may have more restricted permissions.\n\n### Logging\n\nAll logging uses `StreamType.Verbose` via the existing `PowerShellCmdlet.Write` pattern, visible when users pass `-Verbose` to cmdlets. Example output:\n\n```\nVERBOSE: GH_TOKEN environment variable: not found\nVERBOSE: GITHUB_TOKEN environment variable: found\nVERBOSE: Using authenticated GitHub API requests via GITHUB_TOKEN environment variable.\n```\n\n### Files Changed\n\n- `src/PowerShell/Microsoft.WinGet.Client.Engine/Helpers/GitHubClient.cs` — Token resolution logic and logging.\n- `src/PowerShell/Microsoft.WinGet.Client.Engine/Properties/AssemblyInfo.cs` — `InternalsVisibleTo` for unit tests.\n- `src/PowerShell/Microsoft.WinGet.Client.Engine/Commands/WinGetPackageManagerCommand.cs` — Pass `PowerShellCmdlet` to `GitHubClient` constructor.\n- `src/PowerShell/Microsoft.WinGet.Client.Engine/Helpers/AppxModuleHelper.cs` — Pass `PowerShellCmdlet` to `GitHubClient` constructor.\n- `src/PowerShell/Microsoft.WinGet.UnitTests/GitHubClientTests.cs` — Unit tests for token resolution.\n\n## UI/UX Design\n\nNo new command-line arguments or user-facing changes. The feature is automatic: if `GH_TOKEN` or `GITHUB_TOKEN` is set in the environment, authenticated requests are used. Users can see which token is being used by running any repair/assert cmdlet with `-Verbose`.\n\n### Accessibility\n\nNo impact on accessibility.\n\n### Security\n\n- Tokens are never logged or written to output; only the environment variable name is logged.\n- Token values are read from environment variables which are a standard secure mechanism for passing secrets in CI/CD environments.\n- Whitespace-only token values are treated as unset to prevent accidental empty-credential authentication.\n\n### Reliability\n\nImproves reliability by reducing GitHub API rate limit failures in CI/CD pipelines. Unauthenticated requests are still used as a fallback when no tokens are set.\n\n### Compatibility\n\nFully backward compatible. When no token environment variables are set, behavior is identical to the previous implementation.\n\n### Performance, Power, and Efficiency\n\nNo measurable impact. A single environment variable read per `GitHubClient` construction.\n\n## Potential Issues\n\n- If a user has an expired or revoked token in `GH_TOKEN`/`GITHUB_TOKEN`, API calls will fail with a 401 rather than falling back to unauthenticated. This matches GitHub CLI behavior and is the expected outcome.\n\n## Future considerations\n\n- Support for additional token sources (e.g., `gh auth token` integration, Windows Credential Manager).\n- Applying authenticated requests to other parts of the WinGet client beyond the PowerShell module.\n\n## Resources\n\n- [GitHub API rate limits](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api)\n- [GitHub CLI environment variables](https://cli.github.com/manual/gh_help_environment)\n- [Octokit.NET authenticated access](https://octokitnet.readthedocs.io/en/latest/getting-started/#authenticated-access)\n- [Issue #5949](https://github.com/microsoft/winget-cli/issues/5949)\n"
  },
  {
    "path": "doc/specs/#658 - WinGet Download.md",
    "content": "---\nauthor: Roy MacLachlan @RDMaclachlan, Ryan Fu @ryfu-msft\ncreated on: 2023-02-09\nlast updated: 2024-02-15\nissue id: 658\n---\n\n# `Download` command\n\n\"For [#658](https://github.com/microsoft/winget-cli/issues/658)\"\n\n## Abstract\n\nThis spec describes the functionality and high-level implementation design for downloading package installers using the Windows Package Manager.\n\n## Inspiration\n\nThis is inspired by customer feedback, and a need for broader application deployments:\n* Customers want to share the installer with an offline device.\n\n## Solution Design\n\nThe `download` command will provide users with the ability to download any installer from a single package. The following command options are available:\n\n```\n  -d,--download-directory      Directory where the installers are downloaded to\n  -m,--manifest                The path to the manifest of the package\n  --id                         Filter results by id\n  --name                       Filter results by name\n  --moniker                    Filter results by moniker\n  -v,--version                 Use the specified version; default is the latest version\n  -s,--source                  Find package using the specified source\n  --scope                      Select install scope (user or machine)\n  -a,--architecture            Select the architecture\n  --installer-type             Select the installer type\n  -e,--exact                   Find package using exact match\n  --locale                     Locale to use (BCP47 format)\n  --ignore-security-hash       Ignore the installer hash check failure\n  --skip-dependencies          Skips processing package dependencies and Windows features\n  --header                     Optional Windows-Package-Manager REST source HTTP header\n  --authentication-mode        Specify authentication window preference (silent, silentPreferred or interactive)\n  --authentication-account     Specify the account to be used for authentication\n  --accept-package-agreements  Accept all license agreements for packages\n  --accept-source-agreements   Accept all source agreements during source operations\n  -?,--help                    Shows help about the selected command\n  --wait                       Prompts the user to press any key before exiting\n  --logs,--open-logs           Open the default logs location\n  --verbose,--verbose-logs     Enables verbose logging for winget\n  --disable-interactivity      Disable interactive prompts\n  ```\n\n### Selecting the installer\nA new command argument for `--installer-type` has been added to support selecting a specific installer type to download. A package installer should also be able to be selected by `--scope`, `--architecture`, and `--locale`.\n\n### Downloading the installer\nDownloading the package's installer will still require that the package's installer hash be verified before becoming available to the user to interact with. By default, installers will be downloaded to a unique folder name located in the `%USERPROFILE%/Downloads` directory. The default download directory can be modified in the user's settings. The unique folder name is comprised of the package identifier and package version. The installer will be comprised of the package identifier, package version, scope, architecture, and locale. This naming pattern ensures that the installer is unique and identifiable based on the installer filters applied:\n\n> Example installer download path name: `%USER_PROFILE%\\Downloads\\Microsoft.PowerToys_0.78.0\\PowerToys (Preview)_0.78.0_User_X64_burn_en-US.exe`\n\nWhen downloading the package's installer, if a file with the same name exists the new download will overwrite the existing file.\n\n### Downloading the manifest\nAlong with downloading the installer, a merged manifest will be generated and outputted in the same installer download directory. The naming of the file will be exactly the same as the installer except for the extension which will be `.yaml`. The manifest is useful for providing information about the installer such as scope, product code, installer switches, etc.\n\n## UI/UX Design\n\n### WinGet Command Line\nDownloading an installer will output information relative to each step performed. Informing the user of any license agreements that must be accepted prior to download. Acceptance of license agreements will trigger the download to begin, displaying a progress bar that shows the download status. Upon download, the user will then be informed of the file hash validation status before being notified of the download status.\n\nThe following is representative of the user experience.\n\n```PowerShell\nPS C:\\> WinGet download --id Microsoft.VisualStudioCode\nFound Microsoft Visual Studio Code [Microsoft.VisualStudioCode] Version 1.73.1\nThis application is licensed to you by its owner.\nMicrosoft is not responsible for, nor does it grant any licenses to, third-party packages.\nStarting package download...\n   \\\nSuccessfully verified installer hash\nInstaller downloaded:%USERPROFILE%\\Downloads\\Microsoft.VisualStudioCode_1.86.1\\Microsoft Visual Studio Code_1.86.1_User_X64_inno_en-US.exe\n```\n\nWhen the user runs `download` command with the `--help` argument, the following information will be provided:\n\n```\nPS C:\\> WinGet Download --help\nWindows Package Manager v1.1.1\nCopyright (c) Microsoft Corporation. All rights reserved.\n\nDownloads the installer from the selected package, either found by searching a configured source or directly from a manifest. By default, the query must case-insensitively match the id, name, or moniker of the package. Other fields can be used by passing their appropriate option. By default, download command will download the appropriate installer to the user's Downloads folder.\n\nusage: winget download [[-q] <query>] [<options>]\n```\n\n### WinGet Setting - Default Download Output\n\nThe following items will be included in the WinGet Settings Schema\n\n```json\n\"DownloadBehavior\": {\n        \"defaultDownloadDirectory\":\"%USERPROFILE%/Downloads/\"\n}\n```\n\nThe \"defaultDownloadDirectory\" setting will be used as the default folder where the package installer and manifest is downloaded to.\n\n### WinGet PowerShell Cmdlet\nWinGet PowerShell cmdlet will download the identified package's installer and manifest based on the user specified parameters. While downloading the package's installer, PowerShell will show a progress bar displaying the progress. Once the download is complete, the status of the download will be shown to the user, along with the id, name, and source of the package.\n\n```\nC:\\> Export-WinGetPackage -?\n\nNAME\n    Export-WinGetPackage\n\nSYNTAX\n    Export-WinGetPackage [[-Query] <string[]>] [-DownloadDirectory <string>] [-AllowHashMismatch] [-Architecture\n    {Default | X86 | Arm | X64 | Arm64}] [-InstallerType {Default | Inno | Wix | Msi | Nullsoft | Zip | Msix | Exe |\n    Burn | MSStore | Portable}] [-Locale <string>] [-Scope {Any | User | System | UserOrUnknown | SystemOrUnknown}]\n    [-SkipDependencies] [-Version <string>] [-Id <string>] [-Name <string>] [-Moniker <string>] [-Source <string>]\n    [-MatchOption {Equals | EqualsCaseInsensitive | StartsWithCaseInsensitive | ContainsCaseInsensitive}] [-WhatIf]\n    [-Confirm] [<CommonParameters>]\n\n    Export-WinGetPackage [[-PSCatalogPackage] <PSCatalogPackage>] [-DownloadDirectory <string>] [-AllowHashMismatch]\n    [-Architecture {Default | X86 | Arm | X64 | Arm64}] [-InstallerType {Default | Inno | Wix | Msi | Nullsoft | Zip |\n    Msix | Exe | Burn | MSStore | Portable}] [-Locale <string>] [-Scope {Any | User | System | UserOrUnknown |\n    SystemOrUnknown}] [-SkipDependencies] [-Version <string>] [-WhatIf] [-Confirm] [<CommonParameters>]\n\n\nALIASES\n    None\n\n\nREMARKS\n    None\n```\n\n## Capabilities\n\n### Accessibility\n\nAccessibility should not be impacted by this change. There will be a new column in WinGet search that will appear if an application is downloadable.\n\n### Security\n\nSecurity of the Windows Package Manager should not be impacted by this change.\n\n### Reliability\n\nThere will be no change to the reliability of the Windows Package Manager.\n\n### Compatibility\n\nThere will be no breaking changes to the code. A subsection of the WinGet Install functionality will be leveraged for this new functionality.\n\n### Performance, Power, and Efficiency\n\n## Potential Issues\n\n## Future considerations\n\n* AAD Authentication\n\n## Resources\n"
  },
  {
    "path": "doc/specs/#888 - Com Api.md",
    "content": "# 1. Background\r\n\r\nThe Windows Package Manager currently exposes a command line interface to search for packages,\r\ninstall them, view progress, and more. This API is designed to provide another way for callers to\r\nmake use of that functionality. The API will be preferred by callers that want to receive progress\r\nand completion events, and UWP packages that do not have permission to launch command line processes.\r\nThe goal for this api is to provide the full set of install functionality possible using the Windows\r\nPackage Manager command line. The command line is documented at\r\nhttps://docs.microsoft.com/windows/package-manager/winget/\r\n\r\n# 2. Description\r\n\r\nWindows Package Manager is a package manager for windows applications. It comes with a predefined\r\nrepository of applications and users can add new repositories using the winget command line. This\r\nAPI allows packaged apps with the packageManagement capability and other higher privilege processes\r\nto start, manage, and monitor installation of packages that are listed in Windows Package Manager\r\nrepositories.\r\n\r\n# 3. Examples\r\n\r\nSample member values for the following examples:\r\nm_installAppId = L\"Microsoft.VisualStudioCode\";\r\n\r\n## 3.1. Create objects\r\n\r\nCreation of objects has to be done through CoCreateInstance rather than normal winrt initialization\r\nsince it's hosted by an out of proc com server. These helper methods will be used in the rest of the\r\nexamples.\r\n\r\n```c++ (C++ish pseudocode)\r\n    AppInstaller CreateAppInstaller() {\r\n        return winrt::create_instance<AppInstaller>(CLSID_AppInstaller, CLSCTX_ALL);\r\n    }\r\n    InstallOptions CreateInstallOptions() {\r\n        return winrt::create_instance<InstallOptions>(CLSID_InstallOptions, CLSCTX_ALL);\r\n    }\r\n    FindPackagesOptions CreateFindPackagesOptions() {\r\n        return winrt::create_instance<FindPackagesOptions>(CLSID_FindPackagesOptions, CLSCTX_ALL);\r\n    }\r\n    CreateCompositeAppCatalogOptions CreateCreateCompositeAppCatalogOptions() {\r\n        return winrt::create_instance<CreateCompositeAppCatalogOptions>(CLSID_CreateCompositeAppCatalogOptions, CLSCTX_ALL);\r\n    }\r\n    PackageMatchFilter CreatePackageMatchFilter() {\r\n        return winrt::create_instance<PackageMatchFilter>(CLSID_PackageMatchFilter, CLSCTX_ALL);\r\n    }\r\n```\r\n\r\n## 3.2. Search\r\n\r\nThe api can be used to search for packages in a catalog known to Windows Package Manager. This can\r\nbe used to get availability information or start an install.\r\n\r\n```c++ (C++ish pseudocode)\r\n\r\n    // Sample of using synchronous methods on background thread.\r\n    CatalogPackage MainPage::FindPackageOnBackgroundThread()\r\n    {\r\n        PackageManager packageManager = CreatePackageManager();\r\n        PackageCatalogReference catalogRef{\r\n            packageManager.GetPredefinedPackageCatalog(PredefinedPackageCatalog::OpenWindowsCatalog) };\r\n        ConnectResult connectResult = catalogRef.Connect();\r\n        if (connectResult.Status() != ConnectResultStatus::Ok)\r\n        {\r\n            return nullptr;\r\n        }\r\n        PackageCatalog catalog = connectResult.PackageCatalog();\r\n\r\n        FindPackagesOptions findPackagesOptions = CreateFindPackagesOptions();\r\n        PackageMatchFilter filter = CreatePackageMatchFilter();\r\n        filter.Field(PackageMatchField::Id);\r\n        filter.Option(PackageFieldMatchOption::Equals);\r\n        filter.Value(m_installAppId);\r\n        findPackagesOptions.Filters().Append(filter);\r\n        // We've already switched to a background thread, so do everything synchronously.\r\n        FindPackagesResult findPackagesResult{ catalog.FindPackages(findPackagesOptions) };\r\n\r\n        winrt::IVectorView<MatchResult> matches = findPackagesResult.Matches();\r\n        if (matches.Size() == 0)\r\n        {\r\n            return nullptr;\r\n        }\r\n        return matches.GetAt(0).CatalogPackage();\r\n    }\r\n\r\n    // Sample of using async methods.\r\n    IAsyncOperation<CatalogPackage> MainPage::FindPackageInCatalogAsync(PackageCatalog catalog,\r\n            std::wstring packageId)\r\n    {\r\n        FindPackagesOptions findPackagesOptions = CreateFindPackagesOptions();\r\n        PackageMatchFilter filter = CreatePackageMatchFilter();\r\n        filter.Field(PackageMatchField::Id);\r\n        filter.Option(PackageFieldMatchOption::Equals);\r\n        filter.Value(packageId);\r\n        findPackagesOptions.Filters().Append(filter);\r\n        FindPackagesResult findPackagesResult{ co_await catalog.FindPackagesAsync(findPackagesOptions) };\r\n\r\n        winrt::IVectorView<MatchResult> matches = findPackagesResult.Matches();\r\n        if (matches.Size() == 0)\r\n        {\r\n            co_return nullptr;\r\n        }\r\n        co_return matches.GetAt(0).CatalogPackage();\r\n    }\r\n\r\n    IAsyncOperation<CatalogPackage> MainPage::FindPackageAsync()\r\n    {\r\n        PackageManager packageManager = CreatePackageManager();\r\n        PackageCatalogReference catalogRef{\r\n            packageManager.GetPredefinedPackageCatalog(PredefinedPackageCatalog::OpenWindowsCatalog) };\r\n        ConnectResult connectResult = catalogRef.Connect();\r\n        if (connectResult.Status() != ConnectResultStatus::Ok)\r\n        {\r\n            co_return nullptr;\r\n        }\r\n        PackageCatalog catalog = connectResult.PackageCatalog();\r\n        co_return FindPackageInCatalogAsync(catalog, m_installAppId).get();\r\n    }\r\n```\r\n\r\n## 3.3. Install\r\n\r\n```c++ (C++ish pseudocode)\r\n\r\n    IAsyncOperationWithProgress<InstallResult, InstallProgress> MainPage::InstallPackage(CatalogPackage package)\r\n    {\r\n        PackageManager packageManager = CreatePackageManager();\r\n        InstallOptions installOptions = CreateInstallOptions();\r\n        installOptions.PackageInstallScope(PackageInstallScope::Any);\r\n\r\n        return packageManager.InstallPackageAsync(package, installOptions);\r\n    }\r\n\r\n     IAsyncAction UpdateUIProgress(\r\n        InstallProgress progress,\r\n        winrt::Windows::UI::Xaml::Controls::ProgressBar progressBar,\r\n        winrt::Windows::UI::Xaml::Controls::TextBlock statusText)\r\n    {\r\n        co_await winrt::resume_foreground(progressBar.Dispatcher());\r\n        progressBar.Value(progress.DownloadProgress*100);\r\n\r\n        std::wstring downloadText{ L\"Downloading. \" };\r\n        switch (progress.State)\r\n        {\r\n        case PackageInstallProgressState::Queued:\r\n            statusText.Text(L\"Queued\");\r\n            break;\r\n        case PackageInstallProgressState::Downloading:\r\n            downloadText += std::to_wstring(progress.BytesDownloaded) + L\" bytes of \" + std::to_wstring(progress.BytesRequired);\r\n            statusText.Text(downloadText);\r\n            break;\r\n        case PackageInstallProgressState::Installing:\r\n            statusText.Text(L\"Installing\");\r\n            progressBar.IsIndeterminate(true);\r\n            break;\r\n        case PackageInstallProgressState::PostInstall:\r\n            statusText.Text(L\"Finishing install\");\r\n            break;\r\n        case PackageInstallProgressState::Finished:\r\n            statusText.Text(L\"Finished install.\");\r\n            progressBar.IsIndeterminate(false);\r\n            break;\r\n        default:\r\n            statusText.Text(L\"\");\r\n        }\r\n        co_return;\r\n    }\r\n\r\n    // This method is called from a background thread.\r\n    IAsyncAction UpdateUIForInstall(\r\n        IAsyncOperationWithProgress<InstallResult, InstallProgress> installPackageOperation,\r\n        winrt::Windows::UI::Xaml::Controls::Button installButton,\r\n        winrt::Windows::UI::Xaml::Controls::Button cancelButton,\r\n        winrt::Windows::UI::Xaml::Controls::ProgressBar progressBar,\r\n        winrt::Windows::UI::Xaml::Controls::TextBlock statusText)\r\n    {\r\n        if (installPackageOperation)\r\n        {\r\n\r\n            installPackageOperation.Progress([=](\r\n                IAsyncOperationWithProgress<InstallResult, InstallProgress> const& /* sender */,\r\n                InstallProgress const& progress)\r\n                {\r\n                    UpdateUIProgress(progressBar, statusText, 50, stateStr).get();\r\n                });\r\n\r\n\r\n            winrt::hresult installOperationHr = S_OK;\r\n            std::wstring errorMessage{ L\"Unknown Error\" };\r\n            InstallResult installResult{ nullptr };\r\n            try\r\n            {\r\n                installResult = co_await installPackageOperation;\r\n            }\r\n            catch (hresult_canceled const&)\r\n            {\r\n                errorMessage = L\"Cancelled\";\r\n                OutputDebugString(L\"Operation was cancelled\");\r\n            }\r\n            catch (...)\r\n            {\r\n                // Operation failed\r\n                // Example: HRESULT_FROM_WIN32(ERROR_DISK_FULL).\r\n                installOperationHr = winrt::to_hresult();\r\n                // Example: \"There is not enough space on the disk.\"\r\n                errorMessage = winrt::to_message();\r\n                OutputDebugString(L\"Operation failed\");\r\n            }\r\n\r\n            // Switch back to ui thread context.\r\n            co_await winrt::resume_foreground(progressBar.Dispatcher());\r\n\r\n            cancelButton.IsEnabled(false);\r\n            installButton.IsEnabled(true);\r\n            progressBar.IsIndeterminate(false);\r\n\r\n            if (installPackageOperation.Status() == AsyncStatus::Canceled)\r\n            {\r\n                installButton.Content(box_value(L\"Retry\"));\r\n                statusText.Text(L\"Install cancelled.\");\r\n            }\r\n            if (installPackageOperation.Status() == AsyncStatus::Error || installResult == nullptr)\r\n            {\r\n                installButton.Content(box_value(L\"Retry\"));\r\n                statusText.Text(errorMessage);\r\n            }\r\n            else if (installResult.RebootRequired())\r\n            {\r\n                installButton.Content(box_value(L\"Install\"));\r\n                statusText.Text(L\"Reboot to finish installation.\");\r\n            }\r\n            else if (installResult.Status() == InstallResultStatus::Ok)\r\n            {\r\n                installButton.Content(box_value(L\"Install\"));\r\n                statusText.Text(L\"Finished.\");\r\n            }\r\n            else\r\n            {\r\n                installButton.Content(box_value(L\"Install\"));\r\n                statusText.Text(L\"Install failed.\");\r\n            }\r\n        }\r\n    }\r\n\r\n    IAsyncAction MainPage::StartInstall(\r\n        winrt::Windows::UI::Xaml::Controls::Button installButton,\r\n        winrt::Windows::UI::Xaml::Controls::Button cancelButton,\r\n        winrt::Windows::UI::Xaml::Controls::ProgressBar progressBar,\r\n        winrt::Windows::UI::Xaml::Controls::TextBlock statusText)\r\n    {\r\n        installButton.IsEnabled(false);\r\n        cancelButton.IsEnabled(true);\r\n\r\n        co_await winrt::resume_background();\r\n\r\n        PackageManager packageManager = CreatePackageManager();\r\n        PackageCatalogReference catalogRef{\r\n            packageManager.GetPredefinedPackageCatalog(PredefinedPackageCatalog::OpenWindowsCatalog) };\r\n        ConnectResult connectResult = catalogRef.Connect();\r\n        if (connectResult.Status() != ConnectResultStatus::Ok)\r\n        {\r\n            co_await winrt::resume_foreground(progressBar.Dispatcher());\r\n            statusText.Text(L\"Connecting to catalog failed.\");\r\n            co_return;\r\n        }\r\n        PackageCatalog catalog = connectResult.PackageCatalog();\r\n\r\n        FindPackagesResult findPackagesResult{ FindPackageOnBackgroundThread(catalog, m_installAppId) };\r\n\r\n        winrt::IVectorView<MatchResult> matches = findPackagesResult.Matches();\r\n        if (matches.Size() > 0)\r\n        {\r\n            m_installPackageOperation = InstallPackage(matches.GetAt(0).CatalogPackage());\r\n            UpdateUIForInstall(m_installPackageOperation, installButton, cancelButton, progressBar, statusText);\r\n        }\r\n        else\r\n        {\r\n            co_await winrt::resume_foreground(progressBar.Dispatcher());\r\n            statusText.Text(L\"Could not find package.\");\r\n            co_return;\r\n        }\r\n    }\r\n```\r\n\r\n## 3.4.1 Cancel\r\n\r\nThe async operation can be stored, or the install code can wait on an event that can be triggered.\r\n\r\n```c++ (C++ish pseudocode)\r\n    void MainPage::CancelButtonClickHandler(IInspectable const&, RoutedEventArgs const&)\r\n    {\r\n        if (m_installPackageOperation)\r\n        {\r\n            m_installPackageOperation.Cancel();\r\n        }\r\n    }\r\n```\r\n\r\n## 3.5. Open a catalog by name\r\n\r\nOpen a catalog known to the caller. There is no way to use the api to add a catalog, that must be done\r\non the command line.\r\n\r\n```c++ (C++ish pseudocode)\r\n    IAsyncOperation<PackageCatalog> MainPage::FindSourceAsync(std::wstring packageSource)\r\n    {\r\n        PackageManager packageManager = CreatePackageManager();\r\n        PackageCatalogReference catalogRef{ packageManager.GetPackageCatalogByName(packageSource) };\r\n        if (catalogRef)\r\n        {\r\n            ConnectResult connectResult{ co_await catalogRef.ConnectAsync() };\r\n            // PackageCatalog will be null if connectResult.ErrorCode() is a failure\r\n            PackageCatalog catalog = connectResult.PackageCatalog();\r\n            co_return catalog;\r\n        }\r\n    }\r\n```\r\n\r\n# 4 Remarks\r\n\r\nNotes have been added inline throughout the api details.\r\n\r\n\r\nFor this api there are multiple similar apis that are\r\nrelevant with regard to naming and consistency. There is the Windows Package Manager command line which uses\r\n\"source\" to describe the various repositories that can host packages and \"search\" to describe looking up an app.\r\nhttps://docs.microsoft.com/windows/package-manager/winget/\r\nThere is the Windows::ApplicationModel::PackageCatalog which exists as a Windows API for installing packages\r\nand monitoring their installation progress.\r\nhttps://docs.microsoft.com/uwp/api/windows.applicationmodel.packagecatalog?view=winrt-19041\r\nAnd there is Windows.Management.Deployment.PackageManager which allows packages with the packageManagement\r\ncapability to install msix apps and uses \"Find\" to describe looking up an app\r\nhttps://docs.microsoft.com/uwp/api/windows.management.deployment.packagemanager?view=winrt-19041\r\n\r\nThis API has aligned with those Windows APIs in using \\*Catalog and Find.\r\n\r\n# 5 API Details\r\n\r\n```c# (but really MIDL3)\r\nnamespace Microsoft.Management.Deployment\r\n{\r\n    [contractversion(1)]\r\n    apicontract WindowsPackageManagerContract{};\r\n\r\n    /// State of the install.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum PackageInstallProgressState\r\n    {\r\n        /// The install is queued but not yet active. Cancellation of the IAsyncOperationWithProgress in this\r\n        /// state will prevent the package from downloading or installing.\r\n        Queued,\r\n        /// The installer is downloading. Cancellation of the IAsyncOperationWithProgress in this state will\r\n        /// end the download and prevent the package from installing.\r\n        Downloading,\r\n        /// The install is in progress. Cancellation of the IAsyncOperationWithProgress in this state will not\r\n        /// stop the installation or the post install cleanup.\r\n        Installing,\r\n        /// The installer has completed and cleanup actions are in progress. Cancellation of the\r\n        /// IAsyncOperationWithProgress in this state will not stop cleanup or roll back the install.\r\n        PostInstall,\r\n        /// The operation has completed.\r\n        Finished,\r\n    };\r\n\r\n    /// Progress object for the install\r\n    /// DESIGN NOTE: percentage for the install as a whole is purposefully not included as there is no way to\r\n    /// estimate progress when the installer is running.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    struct InstallProgress\r\n    {\r\n        /// State of the install\r\n        PackageInstallProgressState State;\r\n        /// DESIGN NOTE: BytesDownloaded may only be available for downloads done by Windows Package Manager itself.\r\n        /// Number of bytes downloaded if known\r\n        UInt64 BytesDownloaded;\r\n        /// DESIGN NOTE: BytesRequired may only be available for downloads done by Windows Package Manager itself.\r\n        /// Number of bytes required if known\r\n        UInt64 BytesRequired;\r\n        /// Download percentage completed\r\n        Double DownloadProgress;\r\n        /// Install percentage if known.\r\n        Double InstallationProgress;\r\n    };\r\n\r\n    /// Status of the Install call\r\n    /// Implementation Note: Errors mapped from AppInstallerErrors.h\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum InstallResultStatus\r\n    {\r\n        Ok,\r\n        BlockedByPolicy,\r\n        CatalogError,\r\n        InternalError,\r\n        InvalidOptions,\r\n        DownloadError,\r\n        InstallError,\r\n        ManifestError,\r\n        NoApplicableInstallers,\r\n    };\r\n\r\n    /// Result of the install\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass InstallResult\r\n    {\r\n        /// Used by a caller to correlate the install with a caller's data.\r\n        String CorrelationData{ get; };\r\n        /// Whether a restart is required to complete the install.\r\n        Boolean RebootRequired{ get; };\r\n\r\n        /// Batched error code, example APPINSTALLER_CLI_ERROR_SHELLEXEC_INSTALL_FAILED\r\n        InstallResultStatus Status{ get; };\r\n        /// Specific error if known, from downloader or installer itself, example ERROR_INSTALL_PACKAGE_REJECTED\r\n        HRESULT ExtendedErrorCode{ get; };\r\n    }\r\n\r\n    /// IMPLEMENTATION NOTE: SourceOrigin from AppInstallerRepositorySource.h\r\n    /// Defines the origin of the package catalog details.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum PackageCatalogOrigin\r\n    {\r\n        /// Predefined means it came as part of the Windows Package Manager package and cannot be removed.\r\n        Predefined,\r\n        /// User means it was added by the user and could be removed.\r\n        User,\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: SourceTrustLevel from AppInstallerRepositorySource.h\r\n    /// Defines the trust level of the package catalog.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum PackageCatalogTrustLevel\r\n    {\r\n        None,\r\n        Trusted,\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: SourceDetails from AppInstallerRepositorySource.h\r\n    /// Interface for retrieving information about an package catalog without acting on it.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass PackageCatalogInfo\r\n    {\r\n        /// The package catalog's unique identifier.\r\n        /// SAMPLE VALUES: For OpenWindowsCatalog \"Microsoft.Winget.Source_8wekyb3d8bbwe\"\r\n        /// For contoso sample on msdn \"contoso\"\r\n        String Id { get; };\r\n        /// The name of the package catalog.\r\n        /// SAMPLE VALUES: For OpenWindowsCatalog \"winget\".\r\n        /// For contoso sample on msdn \"contoso\"\r\n        String Name { get; };\r\n        /// The type of the package catalog.\r\n        /// ALLOWED VALUES: \"Microsoft.Rest\", \"Microsoft.PreIndexed.Package\"\r\n        /// SAMPLE VALUES: For OpenWindowsCatalog \"Microsoft.PreIndexed.Package\".\r\n        /// For contoso sample on msdn \"Microsoft.PreIndexed.Package\"\r\n        String Type { get; };\r\n        /// The argument used when adding the package catalog.\r\n        /// SAMPLE VALUES: For OpenWindowsCatalog \"https://winget.azureedge.net/cache\"\r\n        /// For contoso sample on msdn \"https://pkgmgr-int.azureedge.net/cache\"\r\n        String Argument { get; };\r\n        /// The last time that this package catalog was updated.\r\n        Windows.Foundation.DateTime LastUpdateTime { get; };\r\n        /// The origin of the package catalog.\r\n        PackageCatalogOrigin Origin { get; };\r\n        /// The trust level of the package catalog\r\n        PackageCatalogTrustLevel TrustLevel { get; };\r\n    }\r\n\r\n    /// A metadata item of a package version.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum PackageVersionMetadataField\r\n    {\r\n        /// The InstallerType of an installed package\r\n        InstallerType,\r\n        /// The Scope of an installed package\r\n        InstalledScope,\r\n        /// The system path where the package is installed\r\n        InstalledLocation,\r\n        /// The standard uninstall command; which may be interactive\r\n        StandardUninstallCommand,\r\n        /// An uninstall command that should be non-interactive\r\n        SilentUninstallCommand,\r\n        /// The publisher of the package\r\n        PublisherDisplayName,\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: IPackageVersion from AppInstallerRepositorySearch.h\r\n    /// A single package version.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass PackageVersionInfo\r\n    {\r\n        /// IMPLEMENTATION NOTE: PackageVersionMetadata fields from AppInstallerRepositorySearch.h\r\n        /// Gets any metadata associated with this package version.\r\n        /// Primarily stores data on installed packages.\r\n        /// Metadata fields may have no value (e.g. packages that aren't installed will not have an InstalledLocation).\r\n        String GetMetadata(PackageVersionMetadataField metadataField);\r\n        /// IMPLEMENTATION NOTE: PackageVersionProperty fields from AppInstallerRepositorySearch.h\r\n        String Id { get; };\r\n        String DisplayName { get; };\r\n        String Version { get; };\r\n        String Channel { get; };\r\n        /// DESIGN NOTE: RelativePath from AppInstallerRepositorySearch.h is excluded as not needed.\r\n        /// String RelativePath;\r\n\r\n        /// IMPLEMENTATION NOTE: PackageVersionMultiProperty fields from AppInstallerRepositorySearch.h\r\n        /// PackageFamilyName and ProductCode can have multiple values.\r\n        Windows.Foundation.Collections.IVectorView<String> PackageFamilyNames { get; };\r\n        Windows.Foundation.Collections.IVectorView<String> ProductCodes { get; };\r\n\r\n        /// Gets the package catalog  where this package version is from.\r\n        PackageCatalog PackageCatalog { get; };\r\n\r\n        /// DESIGN NOTE:\r\n        /// GetManifest from IPackageVersion in AppInstallerRepositorySearch is not implemented in V1. That class has\r\n        /// a lot of fields and no one requesting it.\r\n        /// Gets the manifest of this package version.\r\n        /// virtual Manifest::Manifest GetManifest() = 0;\r\n    }\r\n\r\n    /// IMPLEMENTATION NOTE: PackageVersionKey from AppInstallerRepositorySearch.h\r\n    /// A key to identify a package version within a package.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass PackageVersionId\r\n    {\r\n        /// The package catalog id that this version came from.\r\n        String PackageCatalogId { get; };\r\n        /// The version.\r\n        String Version { get; };\r\n        /// The channel.\r\n        String Channel { get; };\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: IPackage from AppInstallerRepositorySearch.h\r\n    /// A package, potentially containing information about it's local state and the available versions.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass CatalogPackage\r\n    {\r\n        /// IMPLEMENTATION NOTE: PackageProperty fields from AppInstallerRepositorySearch.h\r\n        /// Gets a property of this package.\r\n        String Id { get; };\r\n        String Name { get; };\r\n\r\n        /// Gets the installed package information if the package is installed.\r\n        PackageVersionInfo InstalledVersion{ get; };\r\n\r\n        /// Gets all available versions of this package. Ordering is not guaranteed.\r\n        Windows.Foundation.Collections.IVectorView<PackageVersionId> AvailableVersions { get; };\r\n\r\n        /// Gets the version of this package that will be installed if version is not set in InstallOptions.\r\n        PackageVersionInfo DefaultInstallVersion { get; };\r\n\r\n        /// Gets a specific version of this package.\r\n        PackageVersionInfo GetPackageVersionInfo(PackageVersionId versionKey);\r\n\r\n        /// Gets a value indicating whether an available version is newer than the installed version.\r\n        Boolean IsUpdateAvailable { get; };\r\n\r\n        /// DESIGN NOTE:\r\n        /// IsSame from IPackage in AppInstallerRepositorySearch is not implemented in V1.\r\n        /// Determines if the given IPackage refers to the same package as this one.\r\n        /// virtual bool IsSame(const IPackage*) const = 0;\r\n    }\r\n\r\n    /// IMPLEMENTATION NOTE: CompositeSearchBehavior from AppInstallerRepositorySource.h\r\n    /// Search behavior for composite catalogs.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum CompositeSearchBehavior\r\n    {\r\n        /// Search local catalogs only\r\n        LocalCatalogs,\r\n        /// Search remote catalogs only, don't check local catalogs for InstalledVersion\r\n        RemotePackagesFromRemoteCatalogs,\r\n        /// Search remote catalogs, and check local catalogs for InstalledVersion\r\n        RemotePackagesFromAllCatalogs,\r\n        /// Search both local and remote catalogs.\r\n        AllCatalogs,\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: PackageFieldMatchOption from AppInstallerRepositorySearch.h\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum PackageFieldMatchOption\r\n    {\r\n        Equals,\r\n        EqualsCaseInsensitive,\r\n        StartsWithCaseInsensitive,\r\n        ContainsCaseInsensitive,\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: PackageFieldMatchOption from AppInstallerRepositorySearch.h\r\n    /// The field to match on.\r\n    /// The values must be declared in order of preference in search results.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum PackageMatchField\r\n    {\r\n        CatalogDefault,\r\n        Id,\r\n        Name,\r\n        Moniker,\r\n        Command,\r\n        Tag,\r\n        /// DESIGN NOTE: The following PackageFieldMatchOption from AppInstallerRepositorySearch.h are not implemented in V1.\r\n        /// PackageFamilyName,\r\n        /// ProductCode,\r\n        /// NormalizedNameAndPublisher,\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: PackageMatchFilter from AppInstallerRepositorySearch.h\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass PackageMatchFilter\r\n    {\r\n        PackageMatchFilter();\r\n        /// The type of string comparison for matching\r\n        PackageFieldMatchOption Option;\r\n        /// The field to search\r\n        PackageMatchField Field;\r\n        /// The value to match\r\n        String Value;\r\n        /// DESIGN NOTE: \"Additional\" from RequestMatch AppInstallerRepositorySearch.h is not implemented here.\r\n    }\r\n\r\n    /// IMPLEMENTATION NOTE: MatchResult from AppInstallerRepositorySearch.h\r\n    /// A single result from the search.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass MatchResult\r\n    {\r\n        /// The package found by the search request.\r\n        CatalogPackage CatalogPackage { get; };\r\n\r\n        /// The highest order field on which the package matched the search.\r\n        PackageMatchFilter MatchCriteria { get; };\r\n    }\r\n\r\n    /// Status of the FindPackages call\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum FindPackagesResultStatus\r\n    {\r\n        Ok,\r\n        BlockedByPolicy,\r\n        CatalogError,\r\n        InternalError,\r\n        InvalidOptions\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: SearchResult from AppInstallerRepositorySearch.h\r\n    /// Search result data returned from FindPackages\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass FindPackagesResult\r\n    {\r\n        /// Error codes\r\n        FindPackagesResultStatus Status{ get; };\r\n\r\n        /// The full set of results from the search.\r\n        Windows.Foundation.Collections.IVectorView<MatchResult> Matches { get; };\r\n\r\n        /// If true, the results were truncated by the given ResultLimit\r\n        /// USAGE NOTE: Windows Package Manager does not support result pagination, there is no way to continue\r\n        /// getting more results.\r\n        Boolean WasLimitExceeded{ get; };\r\n    }\r\n\r\n    /// Options for FindPackages\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass FindPackagesOptions\r\n    {\r\n        FindPackagesOptions();\r\n\r\n        /// DESIGN NOTE:\r\n        /// This class maps to SearchRequest from  AppInstallerRepositorySearch.h\r\n        /// That class is a container for data used to filter the available manifests in an package catalog.\r\n        /// Its properties can be thought of as:\r\n        /// (Query || Selectors...) && Filters...\r\n        /// If Query and Selectors are both empty, the starting data set will be the entire database.\r\n        /// Everything && Filters...\r\n        /// Query is PackageMatchField::CatalogDefault and in the Selector list.\r\n        /// USAGE NOTE: Only one selector with PackageMatchField::CatalogDefault is allowed.\r\n\r\n        /// Selectors = you have to match at least one selector (if there are no selectors, then nothing is selected)\r\n        Windows.Foundation.Collections.IVector<PackageMatchFilter> Selectors { get; };\r\n        /// Filters = you have to match all filters(if there are no filters, then there is no filtering of selected items)\r\n        Windows.Foundation.Collections.IVector<PackageMatchFilter> Filters{ get; };\r\n\r\n        /// Restricts the length of the returned results to the specified count.\r\n        UInt32 ResultLimit;\r\n    }\r\n\r\n    /// IMPLEMENTATION NOTE: ISource from AppInstallerRepositorySource.h\r\n    /// A catalog for searching for packages\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass PackageCatalog\r\n    {\r\n        /// Gets a value indicating whether this package catalog is a composite of other package catalogs,\r\n        /// and thus the packages may come from disparate package catalogs as well.\r\n        Boolean IsComposite { get; };\r\n        /// The details of the package catalog if it is not a composite.\r\n        PackageCatalogInfo Info { get; };\r\n\r\n        /// Searches for Packages in the catalog.\r\n        Windows.Foundation.IAsyncOperation<FindPackagesResult> FindPackagesAsync(FindPackagesOptions options);\r\n        FindPackagesResult FindPackages(FindPackagesOptions options);\r\n    }\r\n\r\n    /// Status of the Connect call\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum ConnectResultStatus\r\n    {\r\n        Ok,\r\n        CatalogError,\r\n    };\r\n\r\n    /// Result of the Connect call\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass ConnectResult\r\n    {\r\n        /// Error codes\r\n        ConnectResultStatus Status{ get; };\r\n\r\n        PackageCatalog PackageCatalog { get; };\r\n    }\r\n\r\n    /// A reference to a catalog that callers can try to Connect.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass PackageCatalogReference\r\n    {\r\n        /// Gets a value indicating whether this package catalog is a composite of other package catalogs,\r\n        /// and thus the packages may come from disparate package catalogs as well.\r\n        Boolean IsComposite { get; };\r\n        /// The details of the package catalog if it is not a composite.\r\n        PackageCatalogInfo Info { get; };\r\n\r\n        /// Opens a catalog. Required before searching. For remote catalogs (i.e. not Installed and Installing) this\r\n        /// may require downloading information from a server.\r\n        Windows.Foundation.IAsyncOperation<ConnectResult> ConnectAsync();\r\n        ConnectResult Connect();\r\n    }\r\n\r\n    /// Catalogs with PackageCatalogOrigin Predefined\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum PredefinedPackageCatalog\r\n    {\r\n        OpenWindowsCatalog,\r\n    };\r\n\r\n    /// Local Catalogs with PackageCatalogOrigin Predefined\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum LocalPackageCatalog\r\n    {\r\n        InstalledPackages,\r\n    };\r\n\r\n    /// Options for creating a composite catalog.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass CreateCompositePackageCatalogOptions\r\n    {\r\n        CreateCompositePackageCatalogOptions();\r\n\r\n        /// Create a composite catalog to allow searching a user defined or pre defined source\r\n        /// and a local source (Installed packages) together\r\n        IVector<PackageCatalogReference> Catalogs { get; };\r\n        /// Sets the default search behavior if the catalog is a composite catalog.\r\n        CompositeSearchBehavior CompositeSearchBehavior;\r\n    }\r\n\r\n    /// Required install scope for the package. If the package does not have an installer that\r\n    /// supports the specified scope the Install call will fail with InstallResultStatus.NoApplicableInstallers\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum PackageInstallScope\r\n    {\r\n        /// An installer with any install scope is valid.\r\n        Any,\r\n        /// Only User install scope installers are valid\r\n        User,\r\n        /// Only System installers will be valid\r\n        System,\r\n    };\r\n\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum PackageInstallMode\r\n    {\r\n        /// The default experience for the installer. Installer may show some UI.\r\n        Default,\r\n        /// Runs the installer in silent mode. This suppresses the installer's UI to the extent\r\n        /// possible (installer may still show some required UI).\r\n        Silent,\r\n        /// Runs the installer in interactive mode.\r\n        Interactive,\r\n    };\r\n\r\n    /// Options when installing a package.\r\n    /// Intended to allow full compatibility with the \"winget install\" command line interface.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass InstallOptions\r\n    {\r\n        InstallOptions();\r\n\r\n        /// Optionally specifies the version from the package to install. If unspecified the version matching\r\n        /// CatalogPackage.GetLatestVersion() is used.\r\n        PackageVersionId PackageVersionId;\r\n\r\n        /// Specifies alternate location to install package (if supported).\r\n        String PreferredInstallLocation;\r\n        /// User or Machine.\r\n        PackageInstallScope PackageInstallScope;\r\n        /// Silent, Interactive, or Default\r\n        PackageInstallMode PackageInstallMode;\r\n        /// Directs the logging to a log file. If provided, the installer must have write access to the file\r\n        String LogOutputPath;\r\n        /// Continues the install even if the hash in the catalog does not match the linked installer.\r\n        Boolean AllowHashMismatch;\r\n        /// Allows Store installs when Store Client is disabled.\r\n        Boolean BypassIsStoreClientBlockedPolicyCheck;\r\n        /// A string that will be passed to the installer.\r\n        /// IMPLEMENTATION NOTE: maps to \"--override\" in the winget cmd line\r\n        String ReplacementInstallerArguments;\r\n\r\n        /// Used by a caller to correlate the install with a caller's data.\r\n        /// The string must be JSON encoded.\r\n        String CorrelationData;\r\n        /// A string that will be passed to the source server if using a REST source\r\n        String AdditionalPackageCatalogArguments;\r\n    }\r\n\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass PackageManager\r\n    {\r\n        PackageManager();\r\n\r\n        /// Get the available catalogs. Each source will have a separate catalog.\r\n        /// This does not open the catalog. These catalogs can be used individually or merged with CreateCompositePackageCatalogAsync.\r\n        /// IMPLEMENTATION NOTE: This is a list of sources returned by Windows Package Manager source list\r\n        Windows.Foundation.Collections.IVectorView<PackageCatalogReference> GetPackageCatalogs();\r\n        /// Get a built in catalog\r\n        PackageCatalogReference GetPredefinedPackageCatalog(PredefinedPackageCatalog predefinedPackageCatalog);\r\n        /// Get a built in catalog\r\n        PackageCatalogReference GetLocalPackageCatalog(LocalPackageCatalog localPackageCatalog);\r\n        /// Get a catalog by a known name\r\n        PackageCatalogReference GetPackageCatalogByName(String catalogName);\r\n        /// Get a composite catalog to allow searching a user defined or pre defined source and a local source\r\n        /// (Installing, Installed) together at the same time.\r\n        PackageCatalogReference CreateCompositePackageCatalog(CreateCompositePackageCatalogOptions options);\r\n\r\n        /// Install the specified package\r\n        Windows.Foundation.IAsyncOperationWithProgress<InstallResult, InstallProgress> InstallPackageAsync(CatalogPackage package, InstallOptions options);\r\n    }\r\n\r\n    /// Force midl3 to generate vector marshalling info.\r\n    declare\r\n    {\r\n        interface Windows.Foundation.Collections.IVector<PackageCatalog>;\r\n        interface Windows.Foundation.Collections.IVectorView<PackageCatalog>;\r\n        interface Windows.Foundation.Collections.IVector<PackageCatalogInfo>;\r\n        interface Windows.Foundation.Collections.IVectorView<PackageCatalogInfo>;\r\n        interface Windows.Foundation.Collections.IVector<PackageCatalogReference>;\r\n        interface Windows.Foundation.Collections.IVectorView<PackageCatalogReference>;\r\n        interface Windows.Foundation.Collections.IVector<CatalogPackage>;\r\n        interface Windows.Foundation.Collections.IVectorView<CatalogPackage>;\r\n        interface Windows.Foundation.Collections.IVector<FindPackagesOptions>;\r\n        interface Windows.Foundation.Collections.IVectorView<FindPackagesOptions>;\r\n        interface Windows.Foundation.Collections.IVector<FindPackagesResult>;\r\n        interface Windows.Foundation.Collections.IVectorView<FindPackagesResult>;\r\n        interface Windows.Foundation.Collections.IVector<CreateCompositePackageCatalogOptions>;\r\n        interface Windows.Foundation.Collections.IVectorView<CreateCompositePackageCatalogOptions>;\r\n        interface Windows.Foundation.Collections.IVector<InstallOptions>;\r\n        interface Windows.Foundation.Collections.IVectorView<InstallOptions>;\r\n        interface Windows.Foundation.Collections.IVector<InstallResult>;\r\n        interface Windows.Foundation.Collections.IVectorView<InstallResult>;\r\n        interface Windows.Foundation.Collections.IVector<MatchResult>;\r\n        interface Windows.Foundation.Collections.IVectorView<MatchResult>;\r\n        interface Windows.Foundation.Collections.IVector<PackageManager>;\r\n        interface Windows.Foundation.Collections.IVectorView<PackageManager>;\r\n        interface Windows.Foundation.Collections.IVector<PackageMatchFilter>;\r\n        interface Windows.Foundation.Collections.IVectorView<PackageMatchFilter>;\r\n        interface Windows.Foundation.Collections.IVector<PackageVersionId>;\r\n        interface Windows.Foundation.Collections.IVectorView<PackageVersionId>;\r\n        interface Windows.Foundation.Collections.IVector<PackageVersionInfo>;\r\n        interface Windows.Foundation.Collections.IVectorView<PackageVersionInfo>;\r\n    }\r\n}\r\n```\r\n\r\n# Appendix\r\n"
  },
  {
    "path": "doc/specs/#893 - Support for arbitrary HTTP header for Rest sources.md",
    "content": "---\nauthor: Ashwini Patil @ashpatil\ncreated on: 2021-08-11\nlast updated: 2021-09-01\nissue id: 893\n---\n\n# Support for arbitrary HTTP header for Rest sources\n\nFor [#893](https://github.com/microsoft/winget-cli/issues/893).\n\n## Abstract\n\nThere is a need for some REST sources to support custom behaviors when interacting with Windows Package Manager Client. The client should be able to pass data to a REST source via an HTTP header provided by the user. This could be used for any appropriate scenario. One example might be passing data to a source to indicate a specific behavior for the source to act on. For example, if you want the source to return an invalid response to test client behavior.\nThe optional HTTP header can be passed in as a command-line argument with winget commands and a specific Rest source option.\n\nIf the source specified is not a Rest source, the header will be ignored and a warning message will be displayed.\n\n## Inspiration\n\nAn ability for the REST source to define custom behavior based on data provided in the HTTP header.\n\n## Solution Design\n\nAn optional command-line argument named `--header` will be exposed for the commands that interact with Rest source. The header argument should be accompanied with a source argument that specifies which source should the custom header should be sent to. If the source specified is something other than a Rest source in the command, the header will be ignored and a warning message will be displayed. If no source is specified, an error message will be displayed with more information. The header can have a maximum length of 1024 characters. If the length of the header input exceeds this, an error message will be displayed with information.\n\nThe client will send the header as a value of HTTP header named `Windows-Package-Manager`. The source may use it any way the source sees fit.\n\n## UI/UX Design\n\nAn optional command-line argument named `--header` will be exposed on the winget commands `source add, search, install, uninstall, list, upgrade and show`. Support for `import/export` commands with header will be added when we get more information on how custom header will be used in those commands.\n\n### Accessibility\n\nThis should not change impact accessibility for users of screen readers, assistive input devices, etc.\n\n### Security\n\n### Reliability\n\nThis should not impact reliability.\n\n### Compatibility\n\n### Performance, Power, and Efficiency\n\n## Potential Issues\n\n## Future considerations\n\n## Resources\n\nIssue [#893](https://github.com/microsoft/winget-cli/issues/893) Add support for an arbitrary HTTP header value in REST API.\n"
  },
  {
    "path": "doc/specs/#929 #2334 - Improvements and behavior changes to winget install and winget upgrade flow.md",
    "content": "---\nauthor: Yao Sun @yao-msft\ncreated on: 2022-09-19\nlast updated: 2022-09-19\nissue id: 929, 2334\n---\n\n# Improvements and behavior changes to winget install and winget upgrade flow\n\nFor [#929](https://github.com/microsoft/winget-cli/issues/929), [#2334](https://github.com/microsoft/winget-cli/issues/2334)\n\n## Abstract\n\nThis is a mini spec for describing upcoming behavior changes and improvements to `winget install` and `winget upgrade` workflows.\n\n## Solution Design\n\n### Winget Install flow will look for installed packages and act accordingly\n\n**Existing Behavior**: `winget install` is a light-weight command that just installs the found package with latest version without any installed package detection and applicable version selection.\n\n**New Behavior**: By default, `winget install` will check for installed package after a package is found in a source. If an installed package is found, `winget install` will inform user in bold text and try to do a `winget upgrade` workflow instead. User will get `No applicable upgrade` if upgradable version not available. If an installed package is not found, `winget install` will try to search through all available package versions and find the latest that's applicable, in hope that installation success will be higher with less `No applicable installer`.\n\n**Note**: To better accommodate various user needs, the existing behavior will be preserved and can be invoked with `--force` argument.\n\n### Winget Upgrade flow will try to select installer that better matches installed package\n\n**Existing Behavior**: `winget upgrade` does not try to select installer by installed package's architecture, locale.\n\n**New Behavior**:\n\n- `architecture` and `locale` arguments will be added to `winget upgrade` command\n- winget will try to record selected installer's architecture and locale for installation through winget\n- winget will record architecture or locale from command line arguments as user intent. i.e. `winget install foo --architecture x86 --locale en-US`\n- During upgrade flow installer selection, installer architecture or locale from previous installation will be treated as preference. Installer architecture or locale from user intent will be treated as requirement (i.e. the upgrade will fail if architecture or locale requirement cannot be met).\n\n**Note**: This improvement only works for installations through winget. Due to current limitations of winget tracking implementation, side by side installations may not work perfectly, as winget will only honor metadata from last installation for the same package. User would need to provide `--architecture` or `--locale` to override the last installation metadata when side by side scenarios fail to work as expected.\n\n### `--force` argument separation from Override Hash Mismatch\n\n**Existing Behavior**: Currently, the `--force` argument is overloaded with overriding installer hash mismatch, overriding conflicting portable package, and potentially overriding the new `winget install` behavior.\n\n**New Behavior**: Since hash mismatch overriding is security related, it warrants a dedicated argument. `--ignore-security-hash`(name suggested in [#715](https://github.com/microsoft/winget-cli/issues/715)) will be introduced to represent installer hash mismatch overriding. `--force` argument will be kept for generic workflow behavior overriding.\n"
  },
  {
    "path": "doc/specs/#980 - Apps and Features entries version mapping.md",
    "content": "---\nauthor: Yao Sun @yao-msft\ncreated on: 2022-05-09\nlast updated: 2022-05-15\nissue id: 980\n---\n\n# Mapping of Apps and Features version and Winget package version\n\nFor [#980](https://github.com/microsoft/winget-cli/issues/980)\n\n## Abstract\n\nSome Winget packages may have the concept of marketing version and internal version. So they may have different version values in Winget manifest and in Apps and Features registry entry. Usually, the marketing version will be in the Winget manifest and internal version will be written in the Apps and Features registry.\n\nIn this doc, Winget manifest version will be referred to as Winget version and Apps and Features version in registry will be referred to as ARP version.\n\n## Inspiration\n\nWinget should try to map or correlate the ARP version of an installed package to its Winget version. This will help Winget List/Upgrade better determine if there's an upgrade available.\n\n## Solution Design\n\n### Version parsing and comparison logic in Winget\n\nVersions are parsed by:\n1. Splitting the string based on the split character (`.`)\n2. Parsing a leading, positive integer from each split part\n3. Saving any remaining, non-digits as a supplemental value\n4. If a version part's value is 0 and it does not have supplemental value(non-digits), the version part is dropped(i.e. `1.0.0` will be parsed internally as version with only one part with value 1)\n\nVersions are compared by:\n for each part in each version\n  if both sides have no more parts, return equal\n  else if one side has no more parts, it is less\n  else if integers not equal, return comparison of integers\n  else if only one side has a non-empty string part, it is less\n  else if string parts not equal, return comparison of strings\n\nFor example:\nVersion `1` is less than version `2`\nVersion `1.0.0` is less than version `2.0.0`\nVersion `0.0.1-alpha` is less than version `0.0.2-alpha`\nVersion `0.0.1-beta` is less than version `0.0.2-alpha`\nVersion `0.0.1-alpha` is less than version `0.0.1-beta`\nVersion `0.0.1-alpha` is less than version `0.0.1`\nVersion `13.9.8` is less than version `14.0`\nVersion `1.0` is equal to version `1.0.0`\n\nBoth Winget version and ARP version will use the above parsing and comparison logic.\n\n### How Winget collects and stores ARP version\n\nThe `DisplayVersion` field under `AppsAndFeaturesEntries` will be treated as ARP versions of the package.\n```YAML\nInstallers:\n  AppsAndFeaturesEntries:\n    DisplayVersion:     # Used as ARP version for version comparison if the key is present\n```\n\nSome packages may assign different build numbers to their internal versions for different installers. Winget will treat the ARP versions as a version range.\nFor example, for below manifest, the ARP version range will be [10.0.0.1, 10.0.0.4], any ARP version between 10.0.0.1 and 10.0.0.4(both inclusive) will be treated as a match(i.e. mapped to Winget version 1.0.0).\n```YAML\nPackageVersion: 1.0.0\nInstallers:\n- Architecture: x86\n  AppsAndFeaturesEntries:\n    DisplayVersion: 10.0.0.1\n- Architecture: x64\n  AppsAndFeaturesEntries:\n    DisplayVersion: 10.0.0.2\n- Architecture: arm\n  AppsAndFeaturesEntries:\n    DisplayVersion: 10.0.0.3\n- Architecture: arm64\n  AppsAndFeaturesEntries:\n    DisplayVersion: 10.0.0.4\n```\n\nFor manifest with only 1 ARP version, the only ARP version will be both the minimum and maximum version of the ARP version range.\n\nThe Winget index will record the ARP version range(if present in the manifest) in its internal VersionTable. During indexing, Winget will make sure ARP version range does not collide with each other within a same package.\n\n### How Winget maps ARP version to Winget version\n\nWinget will create a map of Winget version and ARP version range after all available packages info and installed package info are ready. The map will be sorted by Winget version. Conceptually below:\n```text\nWinget version:       1.0.0                   2.0.0                  3.0.0\nARP version range:    [10.0.0.1, 10.0.0.4]    [11.0.0.1, 11.0.0.4]   [12.0.0.1, 12.0.0.4]\n```\n\n#### No version mapping performed\nFor packages without ARP version ranges provided, or if all ARP version ranges provided are same as the Winget version, no ARP version and Winget version mapping will be performed. For example:\n```text\nWinget version:       1.0.0                   2.0.0                  3.0.0\nARP version range:    [1.0.0, 1.0.0]          [Not provided]         [3.0.0, 3.0.0]\n```\n\n#### Only mapped if installed ARP version fall within one of the ARP version range\nFor packages with ARP version unordered, or ordered in the opposite order of Winget version, mapping will be performed only when installed ARP version fall within one of the ARP version range. Otherwise the installed version will be set to Unknown. For example:\n```text\nWinget version:       1.0.0                   2.0.0                  3.0.0\nARP version range:    [10.0, 10.5]            [7.0, 7.5]             [13.0, 13.7]\n```\n\nARP version `10.4` will be mapped as Winget version `1.0.0`.\nARP version `13.4` will be mapped as Winget version `3.0.0`.\nARP version `9.4` will be mapped as Winget version `Unknown`.\n\n#### Full version mapping performed\nFor packages with ARP version ordered in the same order of Winget version, full mapping will be performed. For example:\n```text\nWinget version:       1.0.0                   2.0.0                  3.0.0             4.0.0\nARP version range:    [10.0, 10.5]            [Not provided]         [12.0, 12.5]      [13.0, 13.5]\n```\n\nWinget will perform following mapping:\n1. Check if ARP version fall within one of the ARP version range\n2. Try to find the closest ARP version range it's less than, this is higher priority than greater than mapping because this mapping will mostly be used for package upgrade applicability check.\n3. Try to find the closes ARP version range it's greater than\n\nA special \"less than\"(\"< \") and \"greater than\"(\"> \") version concept will be used. This is to indicate the version is less than or greater than the closest version Winget is known of. UI/UX change to the output is described in later UI/UX section.\n\nFor above version mapping:\nARP version `10.0` will be mapped as Winget version `1.0.0`.\nARP version `11.7` will be mapped as less than Winget version 3.0.0(`< 3.0.0`).\nARP version `12.7` will be mapped as less than Winget version 4.0.0(`< 4.0.0`).\nARP version `14.0` will be mapped as greater than Winget version 4.0.0(`> 4.0.0`).\nARP version `2.0.0` will be mapped as less than Winget version 1.0.0(`< 1.0.0`)(Once ARP version mapping logic is applied, Winget will only look at ARP version range, though `2.0.0` exactly matches one Winget version).\n\nFor version comparison with special \"less than\" or \"greater than\", the \"less than\" or \"greater than\" only applies when compared to the specific version, for comparing to other versions, \"less than\" or \"greater than\" could be considered as ignored.\n\nFor example:\nVersion `< 3.0` is less than version `3.0`\nVersion `< 3.0` is greater than version `2.9`(because `3.0` is greater than `2.9`)\nVersion `< 3.0` is less than version `4.0`\nVersion `< 3.0` is less than version `> 3.0`\nVersion `> 3.0` is greater than version `3.0`\nVersion `> 3.0` is less than version `3.1`  (because `3.0` is less than `3.1`)\nVersion `> 3.0` is greater than version `2.9`\n\n**Note:** It is recommended for package authors to update ARP version info for all package versions of a package for better version mapping if this feature is to be used for a package.\n\n**Note:** Given the limited support for multiple component packages by Winget as of the writing, if a package has multiple components to be installed, it is recommended for package authors to only list the `DisplayName`s of the primary component for better version mapping results.\n\n## UI/UX Design\n\nFor packages matched to a particular Winget version, there'll be no UI/UX change.\n\nFor packages not matched to a particular Winget version, \"> \" will be used to indicate the version is greater than a closest version known to Winget.\n\n```text\nName           Id                   Version   Available Source\n------------------------------------------------------------\nGit            Git.Git              > 2.36.0            winget\nGitHub Desktop GitHub.GitHubDesktop 2.9.15    3.0.0     winget\n```\n\n\"< \" will be used to indicate the version is less than a closest version known to Winget.\n\n```text\nName           Id                   Version   Available Source\n------------------------------------------------------------\nGit            Git.Git              < 2.36.0  2.36.0    winget\nGitHub Desktop GitHub.GitHubDesktop 2.9.15    3.0.0     winget\n```\n\n## Capabilities\n\nThis should improve Winget upgrade applicability check and lead to a better result for Winget list/upgrade.\n\n### Accessibility\n\nThis is not expected to impact accessibility.\n\n### Security\n\nThis should not introduce any _new_ security concerns.\n\n### Reliability\n\nThis is not expected to impact reliability.\n\n### Compatibility\n\nThis changes existing behavior with Winget installed packages version detection, but is expected to be an improvement.\n\n### Performance, Power, and Efficiency\n\nAll the new ARP versions info will be indexed so this should have little impact to performance.\n\n## Potential Issues\n\n## Future considerations\n\n## Resources\n"
  },
  {
    "path": "doc/specs/Configuration-COM-API.md",
    "content": "<!-- TEMPLATE\r\n    The purpose of this spec is to describe new APIs, in a way\r\n    that will transfer to docs.microsoft.com (DMC).\r\n\r\n    There are two audiences for the spec. The first are people that want to evaluate and\r\n    give feedback on the API, as part of the submission process.\r\n    When it's complete it will be incorporated into the public documentation at\r\n    http://docs.microsoft.com (DMC).\r\n    Hopefully we'll be able to copy it mostly verbatim. So the second audience is\r\n    everyone that reads there to learn how and why to use this API.\r\n    Some of this text also shows up in Visual Studio Intellisense.\r\n\r\n    For example, much of the examples and descriptions in the `RadialGradientBrush` API spec\r\n    (https://github.com/microsoft/microsoft-ui-xaml-specs/blob/master/active/RadialGradientBrush/RadialGradientBrush.md)\r\n    were carried over to the public API page on DMC\r\n    (https://docs.microsoft.com/windows/winui/api/microsoft.ui.xaml.media.radialgradientbrush?view=winui-2.5)\r\n\r\n    Once the API is on DMC, that becomes the official copy, and this spec becomes an archive.\r\n    For example if the description is updated, that only needs to happen on DMC and needn't\r\n    be duplicated here.\r\n\r\n    Examples:\r\n    * New class (RadialGradientBrush):\r\n      https://github.com/microsoft/microsoft-ui-xaml-specs/blob/master/active/RadialGradientBrush/RadialGradientBrush.md\r\n    * New member on an existing class (UIElement.ProtectedCursor):\r\n      https://github.com/microsoft/microsoft-ui-xaml-specs/blob/master/active/UIElement/ElementCursor.md\r\n\r\n    Style guide:\r\n    * Use second person; speak to the developer who will be learning/using this API.\r\n    (For example \"you use this to...\" rather than \"the developer uses this to...\")\r\n    * Use hard returns to keep the page width within ~100 columns.\r\n    (Otherwise it's more difficult to leave comments in a GitHub PR.)\r\n    * Talk about an API's behavior, not its implementation.\r\n    (Speak to the developer using this API, not to the team implementing it.)\r\n    * A picture is worth a thousand words.\r\n    * An example is worth a million words.\r\n    * Keep examples realistic but simple; don't add unrelated complications.\r\n    (An example that passes a stream needn't show the process of launching the File-Open dialog.)\r\n\r\n-->\r\n\r\nMicrosoft.Management.Configuration API\r\n===\r\n\r\n# Background\r\nThis API is being added to enable the Developer+ configuration scenarios. It enables interacting with\r\nconfiguration sets in three contexts:\r\n\r\n1. Loading an existing configuration set from a stream\r\n2. Loading previously applied configuration sets from the local history\r\n3. Authoring a new/editing an existing configuration\r\n\r\nThese configuration sets are composed of configuration units, which describe the individual configurable\r\nitems and the values to configure.\r\n\r\nConfiguration actions consist of:\r\n\r\n1. Test :: Determining whether the system state matches the described state\r\n2. Get :: Extracting the current system state with respect to the configuration scope\r\n3. Set :: Applying the described state to the system\r\n\r\nThis API is also intended to support multiple processes watching for state changes, both for the\r\nconfiguration set lifetimes and the individual configuration unit states.\r\n\r\n# Conceptual pages (How To)\r\n\r\n_(Add conceptual documentation that will go to docs.microsoft.com \"how to\" page if needed)_\r\n\r\n# API Pages\r\n\r\n<!-- TEMPLATE\r\n\r\n  Each of the L2 sections in this \"API Pages\" section corresponds to a page on DMC.\r\n\r\n  It's not necessary to have a section for every class member though:\r\n  * If its purpose and usage is obvious from it's name/type, it's not necessary to\r\n    create a section for it.\r\n  * If its purpose and usage is fully explained by brief description, either\r\n      put it in a table in the \"Other [class] members\" section\r\n      put it with /// comments in the IDL section\r\n\r\n  Create an L2 section here for each API that needs more description or examples.\r\n  For a new class with members, the members should go in their own L2 section.\r\n\r\n  Example layout\r\n    ## MyClass\r\n    ## MyClass.Member1\r\n    ## MyClass.Member2\r\n    ## Other MyClass members\r\n    ## MyOtherClass\r\n    ## ...\r\n\r\n  Notes:\r\n  * The first line of each of these sections should become that first line on the DMC page,\r\n    which then becomes the description you see in Intellisense.\r\n  * Each page can have description, examples, and remarks.\r\n    Remarks are where the documentation calls out special considerations that the developer\r\n    should be aware of.\r\n  * It can be helpful at the top of an API page (or after the Intellisense text) to add the\r\n    API signature in C#\r\n  * Add a \"_Spec note: ..._\" to add a note that's useful in this spec but shouldn't go to DMC.\r\n  * Show _examples_, not _samples_; an example is a snippet, a sample is a full working app.\r\n\r\n-->\r\n\r\n## ConfigurationSetState enumeration\r\n\r\nThe state of a configuration set in the configuration history.\r\n\r\n| Name | Description |\r\n|-|-|\r\n| Unknown | Primarily used for a configuration set that has not been applied. |\r\n| Pending | The configuration set has been recorded into the history, but has not yet begun applying. |\r\n| InProgress | The configuration set has begun being applied to the system. |\r\n| Completed | The configuration set has completed being applied. |\r\n\r\n## ConfigurationUnitState enumeration\r\n\r\nThe state of a configuration unit in the configuration history.\r\n\r\n| Name | Description |\r\n|-|-|\r\n| Unknown | Primarily used for a configuration unit that has not been applied. |\r\n| Pending | The configuration unit has been recorded into the history, but has not yet begun applying. |\r\n| InProgress | The configuration unit has begun being applied to the system. |\r\n| Completed | The configuration unit has completed being applied; the result information will contain additional details. |\r\n| Skipped | The configuration unit was skipped; the result information will contain additional details on the reason. |\r\n\r\n## ConfigurationUnitDetailLevel enumeration\r\n\r\nDefines the level of detail probing that is allowed about a configuration unit.\r\n\r\n| Name | Description |\r\n|-|-|\r\n| Local | Only reads details from local data. |\r\n| Catalog | Will query the catalog information for details, but will not download any modules. |\r\n| Download | Will download modules, but not load them. |\r\n| Load | Will download and load modules for details. |\r\n\r\n## ConfigurationUnitResultInformation class\r\n\r\nInformation on a result for a single unit of configuration.\r\n\r\nThe class is used both in reporting results through the `ConfigurationSet.ConfigurationSetChange` event as they occur\r\nand in viewing past results via the `ConfigurationUnit.ResultInformation` property on a historical record.\r\n\r\n## IConfigurationUnitSettingDetails interface\r\n\r\nProvides information for a specific configuration unit setting.\r\n\r\nThe properties on this interface are useful for creating a rich authoring experience.\r\n\r\n## IConfigurationUnitSettingDetails.Semantics schema\r\n\r\n> _TODO: Define the meaning/schema for this value_\r\n\r\n## IConfigurationUnitProcessorDetails interface\r\n\r\nProvides information for a specific configuration unit within the runtime.\r\n\r\nThe properties on this interface are useful for informing the user about the provenance of the code that is\r\nresponsible for processing the configuration unit.\r\n\r\n## ConfigurationUnit class\r\n\r\nA single unit of configuration.\r\n\r\nRepresents the smallest actionable configuration element.\r\n\r\n## ConfigurationUnit constructor\r\n\r\nCreates an empty configuration unit for authoring purposes.\r\n\r\n```C#\r\nConfigurationUnit();\r\n```\r\n\r\n## ConfigurationUnit properties\r\n\r\n| Name | Description |\r\n|-|-|\r\n| UnitName | The name of the unit being configured; not a name for this instance. |\r\n| InstanceIdentifier | An identifier used to uniquely identify the instance of a configuration unit on the system. |\r\n| Identifier | The identifier name of this instance within the set. This value is referenced by other unit's `Dependencies`. |\r\n| Dependencies | The identifiers of the configuration units that this unit depends on. |\r\n| Directives | Contains the values that are for use by the configuration system, related to this unit. |\r\n| Settings | Contains the values that are for use by the configuration unit itself. |\r\n| Details | Contains information on the origin of the configuration unit. You must call `ConfigurationProcessor.Get*DetailsAsync` to populate this value. |\r\n| State | The current state of the configuration unit. |\r\n| ResultInformation | Contains information on the result of the latest attempt to apply the configuration unit. |\r\n| ShouldApply | Allows for control over whether this unit should be applied when the set containing it is applied. |\r\n\r\n## ConfigurationUnit.Directives known values\r\n\r\n> _TODO: List of well known directives_\r\n\r\n## ConfigurationSetChangeEventType enumeration\r\n\r\nThe change event type that has occurred for a configuration set change.\r\n\r\n| Name | Description |\r\n|-|-|\r\n| Unknown | For future use if the caller is not aware of newer change types. |\r\n| SetStateChanged | The state of the configuration set has changed. |\r\n| UnitStateChanged | The state of a configuration unit has changed. |\r\n\r\n## ConfigurationSetChangeData class\r\n\r\nThe change data sent about changes to a specific set.\r\n\r\nThis class is sent to subscribers of the `ConfigurationSet.ConfigurationSetChange` event, containing information\r\nabout the specific change that occurred.\r\n\r\n## ConfigurationSet class\r\n\r\nA configuration set contains a collection of configuration units and details about the set.\r\n\r\nRepresents a self contained group of configuration units that are operated on together.\r\n\r\n## ConfigurationSet constructors\r\n\r\nCreates an empty configuration set for authoring purposes.\r\n\r\n```C#\r\nConfigurationSet();\r\n```\r\n\r\nLoads a configuration set from the given stream.\r\n\r\n```C#\r\nConfigurationSet(Windows.Storage.Streams.IInputStream stream);\r\n```\r\n\r\n## ConfigurationSet.ConfigurationSetChange event\r\n\r\nState changes for this set and it's units are sent to subscribers of this event.\r\n\r\n```C#\r\nevent Windows.Foundation.TypedEventHandler<ConfigurationSet, ConfigurationSetChangeData> ConfigurationSetChange;\r\n```\r\n\r\n## ConfigurationSet.Serialize method\r\n\r\nSerializes the configuration set to the given output stream.\r\n\r\n```C#\r\nvoid Serialize(Windows.Storage.Streams.IOutputStream stream);\r\n```\r\n\r\n## ConfigurationSet.Remove method\r\n\r\nRemoves the configuration set from the recorded history, if present.\r\n\r\n```C#\r\nvoid Remove();\r\n```\r\n\r\nYou can use this method to remove a configuration set that is no longer relevant. For example, it may have been for\r\na repository that is no longer being used by the user and future conflicts with it's configuration are not important.\r\n\r\n## ConfigurationSet properties\r\n\r\n| Name | Description |\r\n|-|-|\r\n| Name | The name of the set; if from a file this could be the file name. |\r\n| Origin | The origin of the set; if it came from a repository it could be the remote URL (ex. https://github.com/microsoft/winget-cli.git). |\r\n| InstanceIdentifier | An identifier used to uniquely identify the instance of a configuration set on the system. |\r\n| State | The state that the set is in. |\r\n| InitialIntent | The time that this set was recorded with intent to apply. |\r\n| ApplyBegun | The time that this set was last started to be applied. |\r\n| ApplyEnded | The time that this set was last finished being applied (does not indicate success). |\r\n| ConfigurationUnits | The configuration units that are part of this set. |\r\n\r\n## IConfigurationUnitProcessor interface\r\n\r\nProvides access to a specific configuration unit within the runtime.\r\n\r\nThis interface is the primary mechanism used to actually read and write configuration to the system,\r\nbut it is not expected that you would use this directly as a consumer of Microsoft.Management.Configuration.\r\n\r\n## IConfigurationSetProcessor interface\r\n\r\nContains the lifetime of the processing action for a configuration set.\r\n\r\nThis interface is used to contain the lifetime of a processing action,\r\nbut it is not expected that you would use this directly as a consumer of Microsoft.Management.Configuration.\r\n\r\n## IConfigurationProcessorFactory interface\r\n\r\nAllows different runtimes to provide specialized handling of configuration processing.\r\n\r\nIt is not expected that you would use this interface directly, but rather the `ConfigurationProcessor` class.\r\n\r\n_Spec note: A separate binary (written by us) will contain the implementation(s) of this interface._\r\n\r\n## DiagnosticLevel enumeration\r\n\r\nIndicates the importance of diagnostic information.\r\n\r\n| Name | Description |\r\n|-|-|\r\n| Verbose | Most useful for debugging scenarios; likely too much for general use. |\r\n| Informational | Details that can be useful for understanding what is happening. |\r\n| Warning | Indicates some abnormal condition, but that is not expected to impact functionality. |\r\n| Error | An error has occurred, but this does not necessarily mean that it will halt the operation. |\r\n| Critical | A serious, fatal condition has been encountered. |\r\n\r\n## DiagnosticInformation class\r\n\r\nContains diagnostic information from the configuration system that can be passed along to the user or log files.\r\nThis is not intended as primary information, and is thus not localized.\r\n\r\n## ConfigurationConflictType enumeration\r\n\r\nThe type of conflict between configuration sets that was detected.\r\n\r\n| Name | Description |\r\n|-|-|\r\n| Unknown | For future use if the caller is not aware of newer conflict types. |\r\n| MatchingOrigin | Indicates that the first configuration set has a matching name and origin to the second, which has already been applied. |\r\n| IdenticalSetApplied | Indicates that the first configuration set is identical to the second, which has already been applied. |\r\n| SettingsConflict | Indicates a conflict between the settings of two configuration units. |\r\n\r\n## ConfigurationConflictSetting class\r\n\r\nDescribes a conflict between a setting of two configuration units.\r\n\r\n## ConfigurationConflict class\r\n\r\nDescribes a conflict between two configuration sets.\r\n\r\n## ApplyConfigurationSetFlags enumeration\r\n\r\nFlags to control how a configuration set should be applied to the system.\r\n\r\n| Name | Description |\r\n|-|-|\r\n| None | The configuration set should be applied in the default manner. |\r\n| DoNotOverwriteMatchingOriginSet | Forces a new configuration set instance to be recorded when the set being applied matches a previous set's origin. The default behavior is to assume that the incoming set is an update to the existing set and overwrite it. |\r\n\r\n## ConfigurationChangeEventType enumeration\r\n\r\nThe configuration set change event type that has occurred.\r\n\r\n| Name | Description |\r\n|-|-|\r\n| Unknown | For future use if the caller is not aware of newer change types. |\r\n| SetAdded | A new configuration set was recorded in the history with the intent to be applied. |\r\n| SetStateChanged | A configuration set has changed state. |\r\n| SetRemoved | A configuration set has been removed from the history. |\r\n\r\n## ConfigurationChangeEventType class\r\n\r\nThe change data sent about changes to sets.\r\n\r\n## ConfigurationProcessor class\r\n\r\nThe configuration processor is responsible for the interactions with the system.\r\n\r\nYou must use this class to do anything beyond reading configuration sets. It is the entrypoint for all actions that\r\nwill interact with the actual system configuration.\r\n\r\n## ConfigurationProcessor constructor\r\n\r\nCreates a configuration processor using the given configuration factory.\r\n\r\n```C#\r\nConfigurationProcessor(IConfigurationProcessorFactory factory);\r\n```\r\n\r\n> _TODO: Add details on the mechanics of creating the `IConfigurationProcessorFactory` objects that we provide._\r\n\r\n## ConfigurationProcessor.CheckForConflicts(Async) method\r\n\r\nChecks for conflicts amongst the configuration sets provided, optionally including the configuration sets already applied to the system.\r\n\r\n```C#\r\nWindows.Foundation.Collections.IVectorView<ConfigurationConflict> CheckForConflicts(Windows.Foundation.Collections.IVectorView<ConfigurationSet> configurationSets, Boolean includeConfigurationHistory);\r\n\r\nWindows.Foundation.IAsyncOperation< Windows.Foundation.Collections.IVectorView<ConfigurationConflict> > CheckForConflictsAsync(Windows.Foundation.Collections.IVectorView<ConfigurationSet> configurationSets, Boolean includeConfigurationHistory);\r\n```\r\n\r\nThis method should be used on any configuration set that is opened in order to determine if it would cause a conflict\r\nwith previously applied configurations. It should be called *after* setting the `Name` and `Origin` in order to determine\r\nif it is a potential update.\r\n\r\n## ConfigurationProcessor.GetSetDetails(Async) method\r\n\r\nGets the details for all configuration units in a set.\r\n\r\n```C#\r\nvoid GetSetDetails(ConfigurationSet configurationSet, ConfigurationUnitDetailLevel detailLevel);\r\n\r\nWindows.Foundation.IAsyncAction GetSetDetailsAsync(ConfigurationSet configurationSet, ConfigurationUnitDetailLevel detailLevel);\r\n```\r\n\r\nThis is a convenience/optimization method that will do the same thing as calling `GetUnitDetails(Async)` on each\r\nconfiguration unit in the set. See `GetUnitDetails(Async)` for more information on what it will do.\r\n\r\n## ConfigurationProcessor.GetUnitDetails(Async) method\r\n\r\nGets the details for all configuration units in a set.\r\n\r\n```C#\r\nvoid GetUnitDetails(ConfigurationUnit unit, ConfigurationUnitDetailLevel detailLevel);\r\n\r\nWindows.Foundation.IAsyncAction GetUnitDetailsAsync(ConfigurationUnit unit, ConfigurationUnitDetailLevel detailLevel);\r\n```\r\n\r\nThis method will get the details about a specific configuration unit and make them available via `ConfigurationUnit.Details`.\r\nThe `detailLevel` parameter allows control over how deeply to probe for details. It is an analog for the amount of\r\ntrust to place in the configuration unit processor.\r\n\r\n## ConfigurationProcessor.ApplySet(Async) method\r\n\r\nApplies the configuration set state to the system.\r\n\r\n```C#\r\nApplyConfigurationSetResult ApplySet(ConfigurationSet configurationSet, ApplyConfigurationSetFlags flags);\r\n\r\nWindows.Foundation.IAsyncOperationWithProgress<ApplyConfigurationSetResult, ConfigurationSetChangeData> ApplySetAsync(ConfigurationSet configurationSet, ApplyConfigurationSetFlags flags);\r\n```\r\n\r\nUsing the async method and it's progress is more efficient than subscribing to the `ConfigurationSetChange` event before calling this method.\r\n\r\n## ConfigurationProcessor.TestSet(Async) method\r\n\r\nTests if the system state matches the state described by the configuration set.\r\n\r\n```C#\r\nTestConfigurationSetResult TestSet(ConfigurationSet configurationSet);\r\n\r\nWindows.Foundation.IAsyncOperationWithProgress<TestConfigurationSetResult, TestConfigurationUnitResult> TestSetAsync(ConfigurationSet configurationSet);\r\n```\r\n\r\n## ConfigurationProcessor.GetSettings(Async) method\r\n\r\nGets the current configuration unit settings from the system state.\r\n\r\n```C#\r\nGetConfigurationUnitSettingsResult GetSettings(ConfigurationUnit unit);\r\n\r\nWindows.Foundation.IAsyncOperation<GetConfigurationUnitSettingsResult> GetSettingsAsync(ConfigurationUnit unit);\r\n```\r\n\r\n## ConfigurationProcessor.Diagnostics event\r\n\r\nEnables listening to internal diagnostics events for logging purposes.\r\n\r\n## ConfigurationProcessor.ConfigurationChange event\r\n\r\nSignals changes to the set of configuration sets in the history, as well as changes to the state of configuration sets in the history.\r\n\r\n## ConfigurationProcessor.GetConfigurationHistory method\r\n\r\nGets the configuration sets from the recorded history.\r\n\r\n```C#\r\nWindows.Foundation.Collections.IVectorView<ConfigurationSet> GetConfigurationHistory();\r\n```\r\n\r\nGets the configuration sets that have already been applied or those recorded with the intent to be applied. This may include in progress sets or those that are waiting to be applied.\r\n\r\n# API Details\r\n\r\n[Link to the MIDL3 file.](../../src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl)\r\n\r\n# Appendix\r\n\r\n<!-- TEMPLATE\r\n  Anything else that you want to write down about implementation notes and for posterity,\r\n  but that isn't necessary to understand the purpose and usage of the API.\r\n\r\n  This or the Background section are a good place to describe alternative designs\r\n  and why they were rejected.\r\n-->\r\n\r\n# Sample\r\n\r\nThis sample illustrates some of the expected usage patterns.\r\n\r\n```C#\r\nusing Microsoft.Management.Configuration;\r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.IO;\r\nusing System.Reflection;\r\nusing Windows.Foundation;\r\nusing Windows.Foundation.Collections;\r\nusing Windows.Storage;\r\nusing Windows.Storage.Streams;\r\n\r\nnamespace ConfigurationSample\r\n{\r\n    internal static class Helpers\r\n    {\r\n        internal static IConfigurationProcessorFactory CreateIConfigurationProcessorFactory()\r\n        {\r\n            throw new NotImplementedException();\r\n        }\r\n\r\n        internal static ConfigurationSet OpenConfigurationSet(string filePath, ConfigurationProcessor processor)\r\n        {\r\n            var fileOperation = FileRandomAccessStream.OpenAsync(filePath, FileAccessMode.Read);\r\n            fileOperation.AsTask().Wait();\r\n            var file = fileOperation.GetResults();\r\n            OpenConfigurationSetResult result = processor.OpenConfigurationSet(file);\r\n\r\n            if (result.Set != null)\r\n            {\r\n                return result.Set;\r\n            }\r\n\r\n            Console.WriteLine($\"Failed opening configuration set: 0x{result.ResultCode:X} at {result.Field}\");\r\n            return null;\r\n        }\r\n\r\n        internal static void SetWatcher(ConfigurationSet set, ConfigurationSetChangeData data)\r\n        {\r\n            Console.WriteLine($\"  - Set: {set.Name} [{set.InstanceIdentifier}]\");\r\n            Console.WriteLine($\"    Change: {data.Change}\");\r\n            Console.WriteLine($\"    Set State: {data.SetState}\");\r\n            switch (data.Change)\r\n            {\r\n                case ConfigurationSetChangeEventType.UnitStateChanged:\r\n                    Console.WriteLine($\"    Unit: {data.Unit.UnitName} [{data.Unit.InstanceIdentifier}]\");\r\n                    Console.WriteLine($\"    Unit State: {data.UnitState}\");\r\n                    if (data.UnitState == ConfigurationUnitState.Completed && data.ResultInformation.ResultCode != null)\r\n                    {\r\n                        Console.WriteLine($\"    Failure: {data.ResultInformation.Description} [{data.ResultInformation.ResultCode.HResult}]\");\r\n                    }\r\n                    break;\r\n            }\r\n        }\r\n    }\r\n\r\n    internal class ApplyProgressWatcher\r\n    {\r\n        private bool isFirstProgress = true;\r\n\r\n        internal void Watcher(IAsyncOperationWithProgress<ApplyConfigurationSetResult, ConfigurationSetChangeData> operation, ConfigurationSetChangeData data)\r\n        {\r\n            if (isFirstProgress)\r\n            {\r\n                isFirstProgress = false;\r\n\r\n                // If our first progress callback contains partial results, output them as if they had been called through progress\r\n                ApplyConfigurationSetResult partialResult = operation.GetResults();\r\n\r\n                foreach (ApplyConfigurationUnitResult unitResult in partialResult.UnitResults)\r\n                {\r\n                    HandleUnitProgress(unitResult.Unit, unitResult.State, unitResult.ResultInformation);\r\n                }\r\n            }\r\n\r\n            switch (data.Change)\r\n            {\r\n                case ConfigurationSetChangeEventType.SetStateChanged:\r\n                    Console.WriteLine($\"  - Set State: {data.SetState}\");\r\n                    break;\r\n                case ConfigurationSetChangeEventType.UnitStateChanged:\r\n                    HandleUnitProgress(data.Unit, data.UnitState, data.ResultInformation);\r\n                    break;\r\n            }\r\n        }\r\n\r\n        private void HandleUnitProgress(ConfigurationUnit unit, ConfigurationUnitState state, ConfigurationUnitResultInformation resultInformation)\r\n        {\r\n            switch (state)\r\n            {\r\n                case ConfigurationUnitState.Pending:\r\n                    break;\r\n                case ConfigurationUnitState.InProgress:\r\n                case ConfigurationUnitState.Completed:\r\n                case ConfigurationUnitState.Skipped:\r\n                    Console.WriteLine($\"  - Unit: {unit.UnitName} [{unit.InstanceIdentifier}]\");\r\n                    Console.WriteLine($\"    Unit State: {state}\");\r\n                    if (resultInformation.ResultCode != null)\r\n                    {\r\n                        Console.WriteLine($\"    HRESULT: [0x{resultInformation.ResultCode.HResult:X8}]\");\r\n                        Console.WriteLine($\"    Reason: {resultInformation.Description}\");\r\n                    }\r\n                    break;\r\n                case ConfigurationUnitState.Unknown:\r\n                    break;\r\n            }\r\n        }\r\n    }\r\n\r\n    internal class Program\r\n    {\r\n        static void LoadAndOutput(string[] args)\r\n        {\r\n            ConfigurationProcessor processor = new ConfigurationProcessor(Helpers.CreateIConfigurationProcessorFactory());\r\n\r\n            // Open the given configuration file\r\n            ConfigurationSet configSet = Helpers.OpenConfigurationSet(args[1], processor);\r\n            if (configSet == null)\r\n            {\r\n                return;\r\n            }\r\n\r\n            // Output some of the information from the set\r\n            Console.WriteLine($\"Configuration Set: {args[1]}\");\r\n\r\n            foreach (ConfigurationUnit unit in configSet.ConfigurationUnits)\r\n            {\r\n                Console.WriteLine($\"  - Configuration Unit: {unit.UnitName}\");\r\n                if (!string.IsNullOrEmpty(unit.Identifier))\r\n                {\r\n                    Console.WriteLine($\"    Identifier: {unit.Identifier}\");\r\n                }\r\n                Console.WriteLine($\"    Intent: {unit.Intent}\");\r\n                IReadOnlyList<string> dependencies = unit.Dependencies;\r\n                if (dependencies.Count > 0)\r\n                {\r\n                    Console.WriteLine(\"    Dependencies:\");\r\n                    foreach (string dependency in dependencies)\r\n                    {\r\n                        Console.WriteLine($\"      {dependency}\");\r\n                    }\r\n                }\r\n                ValueSet directives = unit.Directives;\r\n                if (directives.Count > 0)\r\n                {\r\n                    Console.WriteLine(\"    Directives:\");\r\n                    foreach (var directive in unit.Directives)\r\n                    {\r\n                        Console.WriteLine($\"      {directive.Key}: {directive.Value}\");\r\n                    }\r\n                }\r\n                ValueSet settings = unit.Settings;\r\n                if (settings.Count > 0)\r\n                {\r\n                    Console.WriteLine(\"    Settings:\");\r\n                    foreach (var setting in unit.Settings)\r\n                    {\r\n                        Console.WriteLine($\"      {setting.Key}: {setting.Value}\");\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        static void LoadAndCheckConflicts(string[] args)\r\n        {\r\n            // Create the factory and processor\r\n            ConfigurationProcessor processor = new ConfigurationProcessor(Helpers.CreateIConfigurationProcessorFactory());\r\n\r\n            // Open the given configuration file\r\n            ConfigurationSet configSet = Helpers.OpenConfigurationSet(args[1], processor);\r\n            if (configSet == null)\r\n            {\r\n                return;\r\n            }\r\n\r\n            // Set a name and origin for this set so that we can see it in the conflict info\r\n            configSet.Name = Path.GetFileName(args[1]);\r\n            configSet.Origin = args[1];\r\n\r\n            // Check for conflicts with existing configurations\r\n            List<ConfigurationSet> configSets = new List<ConfigurationSet>() { configSet };\r\n            IList<ConfigurationConflict> conflicts = processor.CheckForConflicts(configSets, true);\r\n\r\n            Console.WriteLine($\"Conflicts with Configuration Set: {args[1]}\");\r\n\r\n            foreach (ConfigurationConflict conflict in conflicts)\r\n            {\r\n                Console.WriteLine($\"  - Conflict: {conflict.Conflict}\");\r\n                Console.WriteLine($\"    First Set: {conflict.FirstSet.Name} [{conflict.FirstSet.Origin}]\");\r\n                Console.WriteLine($\"    Second Set: {conflict.SecondSet.Name} [{conflict.SecondSet.Origin}]\");\r\n                if (conflict.Conflict == ConfigurationConflictType.SettingsConflict)\r\n                {\r\n                    Console.WriteLine($\"    First Unit: {conflict.FirstUnit.UnitName} [{conflict.FirstUnit.InstanceIdentifier}]\");\r\n                    Console.WriteLine($\"    Second Unit: {conflict.SecondUnit.UnitName} [{conflict.SecondUnit.InstanceIdentifier}]\");\r\n                    foreach (ConfigurationConflictSetting setting in conflict.Settings)\r\n                    {\r\n                        Console.WriteLine($\"    - Setting: {setting.Name}\");\r\n                        Console.WriteLine($\"      First Value: {setting.FirstValue}\");\r\n                        Console.WriteLine($\"      Second Value: {setting.SecondValue}\");\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        static void LoadAndApply(string[] args)\r\n        {\r\n            // Create the factory and processor\r\n            ConfigurationProcessor processor = new ConfigurationProcessor(Helpers.CreateIConfigurationProcessorFactory());\r\n\r\n            // Open the given configuration file\r\n            ConfigurationSet configSet = Helpers.OpenConfigurationSet(args[1], processor);\r\n            if (configSet == null)\r\n            {\r\n                return;\r\n            }\r\n\r\n            Console.WriteLine($\"Applying Configuration Set: {args[1]}\");\r\n\r\n            ApplyProgressWatcher watcher = new ApplyProgressWatcher();\r\n\r\n            var operation = processor.ApplySetAsync(configSet, ApplyConfigurationSetFlags.None);\r\n            operation.Progress = watcher.Watcher;\r\n            operation.AsTask().Wait();\r\n            ApplyConfigurationSetResult result = operation.GetResults();\r\n\r\n            Console.WriteLine($\"  - Done: {result.ResultCode.HResult}\");\r\n        }\r\n\r\n        static void GetHistoryAndWatchEverything(string[] args)\r\n        {\r\n            Console.WriteLine(\"Watching all configuration [press Enter to stop]:\");\r\n\r\n            // Create the factory and processor\r\n            ConfigurationProcessor processor = new ConfigurationProcessor(Helpers.CreateIConfigurationProcessorFactory());\r\n\r\n            List<ConfigurationSet> list = new List<ConfigurationSet>();\r\n\r\n            // Attach to the top level change event\r\n            processor.ConfigurationChange += (ConfigurationSet incomingSet, ConfigurationChangeData data) =>\r\n            {\r\n                int existingSetIndex = -1;\r\n\r\n                lock (list)\r\n                {\r\n                    for (int i = 0; i < list.Count; ++i)\r\n                    {\r\n                        if (list[i].InstanceIdentifier == data.InstanceIdentifier)\r\n                        {\r\n                            existingSetIndex = i;\r\n                            break;\r\n                        }\r\n                    }\r\n\r\n                    if (data.Change == ConfigurationChangeEventType.SetAdded || data.Change == ConfigurationChangeEventType.SetStateChanged)\r\n                    {\r\n                        if (existingSetIndex == -1)\r\n                        {\r\n                            incomingSet.ConfigurationSetChange += Helpers.SetWatcher;\r\n                            list.Add(incomingSet);\r\n                        }\r\n                    }\r\n                    else // Removed\r\n                    {\r\n                        if (existingSetIndex != -1)\r\n                        {\r\n                            list[existingSetIndex].ConfigurationSetChange -= Helpers.SetWatcher;\r\n                            list.RemoveAt(existingSetIndex);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                Console.WriteLine($\"  - Set: {data.InstanceIdentifier}\");\r\n                Console.WriteLine($\"    Change: {data.Change}\");\r\n            };\r\n\r\n            foreach (ConfigurationSet set in processor.GetConfigurationHistory())\r\n            {\r\n                int existingSetIndex = -1;\r\n\r\n                lock (list)\r\n                {\r\n                    for (int i = 0; i < list.Count; ++i)\r\n                    {\r\n                        if (list[i].InstanceIdentifier == set.InstanceIdentifier)\r\n                        {\r\n                            existingSetIndex = i;\r\n                            break;\r\n                        }\r\n                    }\r\n\r\n                    if (existingSetIndex == -1)\r\n                    {\r\n                        set.ConfigurationSetChange += Helpers.SetWatcher;\r\n                        list.Add(set);\r\n                    }\r\n                }\r\n\r\n                if (existingSetIndex == -1)\r\n                {\r\n                    Console.WriteLine($\"  - Set: {set.Name} [{set.InstanceIdentifier}]\");\r\n                    Console.WriteLine($\"    State: {set.State}\");\r\n                }\r\n            }\r\n\r\n            // Wait for user to press enter\r\n            Console.ReadLine();\r\n        }\r\n\r\n        static void Main(string[] args)\r\n        {\r\n            var method = typeof(Program).GetMethod(args[0], BindingFlags.NonPublic | BindingFlags.Static);\r\n\r\n            if (method != null)\r\n            {\r\n                method.Invoke(null, new object[]{ args });\r\n            }\r\n            else\r\n            {\r\n                Console.WriteLine($\"{args[0]} is not a sample\");\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\n```\r\n"
  },
  {
    "path": "doc/specs/spec-template.md",
    "content": "---\nauthor: <first-name> <last-name> <github-id>/<email>\ncreated on: <yyyy-mm-dd>\nlast updated: <yyyy-mm-dd>\nissue id: <github issue id>\n---\n\n# Spec Title\n\n[comment]: # Link to issue: \"For [#1](https://github.com/microsoft/winget-cli/issues/1)\"\n\n## Abstract\n\n[comment]: # Outline what this spec describes\n\n## Inspiration\n\n[comment]: # What were the drivers/inspiration behind the creation of this spec.\n\n## Solution Design\n\n[comment]: # Outline the design of the solution. Feel free to include ASCII-art diagrams, etc.\n\n## UI/UX Design\n\n[comment]: # What will this fix/feature look like? How will it affect the end user?\n\n## Capabilities\n\n[comment]: # Discuss how the proposed fixes/features impact the following key considerations:\n\n### Accessibility\n\n[comment]: # How will the proposed change impact accessibility for users of screen readers, assistive input devices, etc.\n\n### Security\n\n[comment]: # How will the proposed change impact security?\n\n### Reliability\n\n[comment]: # Will the proposed change improve reliability? If not, why make the change?\n\n### Compatibility\n\n[comment]: # Will the proposed change break existing code/behaviors? If so, how, and is the breaking change \"worth it\"?\n\n### Performance, Power, and Efficiency\n\n## Potential Issues\n\n[comment]: # What are some of the things that might cause problems with the fixes/features proposed? Consider how the user might be negatively impacted.\n\n## Future considerations\n\n[comment]: # What are some of the things that the fixes/features might unlock in the future? Does the implementation of this spec enable scenarios?\n\n## Resources\n\n[comment]: # Be sure to add links to references, resources, footnotes, etc.\n"
  },
  {
    "path": "doc/troubleshooting/README.md",
    "content": "# Troubleshooting\n\n## How do I get the Windows Package Manager?\n\n### Prerequisites\n\nThe first thing to check is which version of Windows 10 you have.\n\n[Check your version of Windows](https://support.microsoft.com/windows/see-which-version-of-windows-10-you-have-12d35019-4da9-0cb1-ba47-f8b031b712ad).\n\nThe Windows Package Manager requires at least Version 1809 (October 2018 Update).\n\nThe next requirement is ensuring you have the [App Installer](https://apps.microsoft.com/detail/9nblggh4nns1) from the Microsoft Store. The Windows Package Manager is delivered as an MSIX package. The App Installer is required to install MSIX packages on Windows 10.\n\n>Note: The Windows Package Manager is shipped with later versions of the App Installer.\n\n### Stable Releases\n\nThe first stable release of the Windows Package Manager was v1.0.11451. This release was **not** published as an automatic update to all Windows 10 users on a supported version of Windows 10. This was an intentional decision made to provide enterprise customers (IT Professionals) sufficient time to configure and deploy Group Policy for the Windows Package Manager.\n\nCustomers may install the [latest stable release](https://github.com/microsoft/winget-cli/releases/latest/) directly from the GitHub repository. These packages are signed, and customers will receive automatic updates if IT Policy does not block the Microsoft Store.\n\n### Developer Releases (Pre-Release)\n\n>Note: There is a known problem restoring the client to the latest stable App Installer release. We will be distributing the latest stable builds and providing instructions once they are made available.\n\nDuring the initial Windows Package Manager Preview period, releases were distributed to all Windows Insider channels. Customers who [sign up](http://aka.ms/winget-InsiderProgram) to become members of the Windows Package Manager Insider program also receive pre-release builds. The final process for inclusion into the program requires manual steps, so the App Installer update may not be available for a few days **after** receiving their e-mail notification.\n\nCustomers may install any [release](https://github.com/microsoft/winget-cli/releases/) including pre-release builds directly from the GitHub repository. These packages are signed, and customers will receive automatic updates if IT Policy does not block the Microsoft Store.\n\n>Note: Insiders will receive updates to the latest build (stable or pre-release) if IT Policy does not block the Microsoft Store. Other customers will receive updates to the latest stable build once a newer stable version is published if IT Policy does not block the Microsoft Store.\n\nOnly the Windows Insider DEV channel will continue receiving pre-release builds of the Windows Package Manager after v1.0.11451. Other Windows Insider channels will only receive stable release candidates or updated versions of the Windows Package Manager with critical bug fixes.\n\n### Machine-wide Provisioning\n\nThe Windows Package Manager can be provisioned machine-wide or for each new user. The following PowerShell cmdlet can be used to provision the package machine-wide. The latest Windows Package Manager release and license can be downloaded directly from the GitHub repository. It is dependent on the [Microsoft.VCLibs](https://docs.microsoft.com/troubleshoot/cpp/c-runtime-packages-desktop-bridge) desktop framework package, which needs to be downloaded and specified in the dependency path option in the cmdlet.\n\n  >`Add-AppxProvisionedPackage -online -PackagePath <desktop AppInstaller msixbundle package path> -LicensePath <license path> -DependencyPackagePath <Microsoft.VCLibs package path>`\n\nAfter the package is provisioned, the users need to log into their Windows account to get the package registered and use it.\n\n## Common Issues\n\n### Executing `winget` exits with no message\n\nIf no output is displayed, it is likely that the version of WinGet on your system is using a retired Content Delivery Network (CDN).\nYou can check which version of WinGet is on your machine using `winget --info`. If the version is lower than `1.6.3482`, take the following troubleshooting steps.\n\n1. Install the latest version of WinGet using one of the below methods\n  * a. Through the Microsoft Store by installing the latest version of [App Installer](https://apps.microsoft.com/detail/9NBLGGH4NNS1)\n  * b. Through installing the MSIX package found in the [GitHub releases](https://github.com/microsoft/winget-cli/releases)\n  * c. Through installing the MSIX package from https://aka.ms/getwinget\n2. Force a source update using `winget source update`\n\nIf the above guidelines do not resolve the problem, please open an issue with details of the Windows version and App Installer version you are using.\n\n### Executing `winget` doesn't display help\n\nThe following errors are displayed when executed in CMD.\n `The system cannot execute the specified program.`\n or\n\n```\n'winget' is not recognized as an internal or external command,\noperable program or batch file.\n```\n\nThe following errors are displayed when executed in PowerShell.\n\n```\nwinget : The term 'winget' is not recognized as the name of a cmdlet, function, script file, or operable program.\nCheck the spelling of the name, or if a path was included, verify that the path is correct and try again.\nAt line:1 char:1\n+ winget\n+ ~~~~~~\n    + CategoryInfo          : ObjectNotFound: (winget:String) [], CommandNotFoundException\n    + FullyQualifiedErrorId : CommandNotFoundException\n```\nor\n\n```\nProgram 'winget.exe' failed to run: The file cannot be accessed by the systemAt line:1 char:1\n+ winget\n+ ~~~~~~.\nAt line:1 char:1\n+ winget\n+ ~~~~~~\n    + CategoryInfo          : ResourceUnavailable: (:) [], ApplicationFailedException\n    + FullyQualifiedErrorId : NativeCommandFailed\n```\n\nThe following error is displayed when executed in Windows Terminal's Powershell profile.\n\n```\nwinget : The term 'winget' is not recognized as the name of a cmdlet, function, script file, or operable program.\nCheck the spelling of the name, or if a path was included, verify that the path is correct and try again.\nAt line:1 char:1\n+ winget\n+ ~~~~~~\n    + CategoryInfo          : ObjectNotFound: (winget:String) [], CommandNotFoundException\n    + FullyQualifiedErrorId : CommandNotFoundException\n```\n\nThese errors most commonly occur for one of following reasons. Please try out the following troubleshooting steps.\n1. The App Installer does not contain the Windows Package Manager. You should check to ensure the version of App Installer is greater than 1.11.11451. You can check by executing the following command in PowerShell:\n\n    >`Get-AppxPackage microsoft.desktopappinstaller`\n\n2. The App Execution Alias for the Windows Package Manager is disabled. You should enable the App Execution Alias for the Windows Package Manager. Go to `App execution aliases` option in `Apps & features Settings` to enable it.\n3. The App Installer did not automatically add the PATH environment variable. You should add the path environment variable. The value to add is \"%userprofile%\\AppData\\Local\\Microsoft\\WindowsApps\". You can verify this by running `%LOCALAPPDATA%\\Microsoft\\WindowsApps\\winget` from a command-prompt or  `& \"$env:LOCALAPPDATA\\Microsoft\\WindowsApps\\winget\"` from a powershell. If the command runs then, but not before, then you very likely have a missing PATH environment component.\n4. Apps deployed on the machine are registered per user by default. If App Installer was installed on a different user account than the one you are trying to run it on, you will have to reinstall it again on this account and try again:\n   1. Get the `PackageFullName` of your installed `App Installer` package (PowerShell): `Get-AppxPackage Microsoft.DesktopAppInstaller | Select Name, PackageFullName`.\n   2. `Add-AppxPackage -register \"C:\\Program Files\\WindowsApps\\{PackageFullName}\\appxmanifest.xml\" -DisableDevelopmentMode` (where `{PackageFullName}` is the info from the previous point).\n   3. Toggle the App Execution Alias for winget, again (see above).\n\nIf the above guidelines do not resolve the problem, please open an issue with details of the Windows version and App Installer version you are using.\n\n## Common Errors\n\n#### Error 0x80072efd\n\nThis error is related to networking and maps to \"ERROR_INTERNET_CANNOT_CONNECT\". It could be related to TLS (Transport Layer Security).\n\nThis issue may be resolved by enabling TLS 1.2.\n\nIt may also be resolved by flushing your DNS cache. Instructions are available at [Microsoft Learn](https://learn.microsoft.com/windows-server/administration/windows-commands/ipconfig).\n\n\n#### Error 0x801901a0\n\nThis error is related to Delivery Optimization (DO). You may configure the Windows Package Manager settings to use the standard `WININET` library. Add the following network setting:\n\n>`\"network\": {\"downloader\": \"wininet\"}`\n\n#### Error 0x80d03002\n\nThis error is related to Delivery Optimization (DO). You may configure the Windows Package Manager settings to use the standard `WININET` library. Add the following network setting:\n\n>`\"network\": {\"downloader\": \"wininet\"}`\n\n#### Error 0x80070490\n\nThe following error is displayed when trying to install some appxbundles.\n\n```\nInstall failed: error 0x80070490: Opening the package from location appxbundle_Name.appxbundle failed.\n0x80070490 : Element not found.\n```\n\nA possible troubleshooting step is to install the [KB5005565](https://support.microsoft.com/topic/september-14-2021-kb5005565-os-builds-19041-1237-19042-1237-and-19043-1237-292cf8ed-f97b-4cd8-9883-32b71e3e6b44) update, reboot your machine and try installing the appxbundle again.\n\n#### Updating Microsoft.DesktopAppInstaller from version 1.0.42251.0 doesn't render package name on Windows 11 Pro image in Azure\n\nLaunching the Microsoft.DesktopAppInstaller update on Windows 11 Pro image in Azure to update from version 1.0.42251.0 might not render the correct package name title. The workaround to this issue is to install the latest Microsoft.DesktopAppInstaller with Windows Package Manager.\n\n#### Failed in attempting to update the source: winget\n\nThe WinGet Community repository (a.k.a. \"winget\" source) requires network connectivity to https://cdn.winget.microsoft.com/cache. Depending on the version of WinGet, either the source.msix or source2.msix is downloaded and installed. This pre-indexed package contains the local copy of metadata queried by WinGet. \n\nIf running `winget source update` doesn't resolve the problem and you are on WinGet 1.10 or newer, you may be able to correct the problem by uninstalling the current source \"Windows Package Manager Source (winget) V2\" and running another winget command, or manually install the source from: https://cdn.winget.microsoft.com/cache/source2.msix (You may need to download this using \"In Private\" if you encounter a 404).\n"
  },
  {
    "path": "doc/windows/package-manager/index.md",
    "content": "---\ntitle: Windows Package Manager\ndescription: Windows Package Manager is a comprehensive package manager solution that consists of a command line tool and set of services for installing applications on Windows 10.\nms.date: 05/03/2020\nms.topic: overview\nms.localizationpriority: medium\n---\n\n# Windows Package Manager\n\nWindows Package Manager is a comprehensive [package manager solution](#understanding-package-managers) that consists of a command line tool and set of services for installing applications on Windows 10 and Windows 11.\n\n## Windows Package Manager for developers\n\nDevelopers use the **winget** command line tool to discover, install, upgrade, remove and configure a curated set of applications. After it is installed, developers can access **winget** via the Windows Terminal, PowerShell, or the Command Prompt.\n\nFor more information, see [Use the winget tool to install and manage applications](winget/index.md).\n\n## Windows Package Manager for ISVs\n\nIndependent Software Vendors (ISVs) can use Windows Package Manager as a distribution channel for software packages containing their tools and applications. To submit software packages (containing .msix, .msi, or .exe installers) to Windows Package Manager, we provide the open source **Microsoft Community Package Manifest Repository** on GitHub where ISVs can upload [package manifests](package/manifest.md) to have their software packages considered for inclusion with Windows Package Manager. Manifests are automatically validated and may also be reviewed manually.\n\nFor more information, see [Submit packages to Windows Package Manager](package/repository.md).\n\n## Understanding package managers\n\nA package manager is a system or set of tools used to automate installing, upgrading, configuring and using software. Most package managers are designed for discovering and installing developer tools.\n\nIdeally, developers use a package manager to specify the prerequisites for the tools they need to develop solutions for a given project. The package manager then follows the declarative instructions to install and configure the tools. The package manager reduces the time spent getting an environment ready, and it helps ensure the same versions of packages are installed on their machine.\n\nThird party package managers can leverage the [Microsoft Community Package Manifest Repository](package/repository.md) to increase the size of their software catalog.\n\n## Related topics\n\n* [Use the winget tool to install and manage software packages](winget/index.md)\n* [Submit packages to Windows Package Manager](package/index.md)\n"
  },
  {
    "path": "doc/windows/package-manager/package/binary-validation-errors.md",
    "content": "# Binary-Validation-Error\n\nThe Windows Package Manager goes to great lengths to create an excellent user experience when installing applications. In order to do this, we must ensure that all applications install on PCs without errors regardless of environment.\n\nTo that end, a key test we use for the Windows Package Manager is to ensure that all installers will install without warnings on a variety of popular antivirus configurations. While Windows provides Defender as a built-in antivirus program, many enterprise customers and users employ a wide range of antivirus software.\n\nTherefore, each submission to the Windows Package Manager will be run through several antivirus programs.  These programs all have different virus detection algorithms for identifying [Potentially unwanted application (PUA)](https://docs.microsoft.com/windows/security/threat-protection/intelligence/criteria) and malware.\n\n## Application failures\n\nIf an application fails validation, Microsoft will first attempt to verify that the flagged software is not a false positive with the antivirus vendors.  In many cases, after notification and validation, the antivirus vendor will update their algorithm and the application will pass.\n\nIn some cases, however, the code anomaly detected is not able to be determined to be a false positive by the antivirus vendors. In this case the application cannot be added to the Windows Package Manager repository, and the Pull Request will be rejected with a **Binary-Validation-Error** label.\n\n## Responding to Binary-Validation-Error\n\nA previously mentioned, the Windows Package Manager repository is not allowed applications that fail with a **Binary-Validation-Error**.  The next step is for the ISV to update their software to remove the code detected as PUA.\n\n### What if I cannot remove that code?\n\nOccasionally, genuine tools used for debugging and low-level activities, will appear as PUA to the antivirus vendors.  This is because the code necessary to do the debugging will have a similar signature to unwanted software.  Even though this is a legitimate use of that coding practice, unfortunately we are unable to allow those applications into the Windows Package Manager repository.\n"
  },
  {
    "path": "doc/windows/package-manager/package/index.md",
    "content": "---\ntitle: Submit packages to Windows Package Manager\ndescription: You can use Windows Package Manager as a distribution channel for software packages containing your applications.\nms.date: 04/29/2020\nms.topic: overview\nms.localizationpriority: medium\n---\n\n# Submit packages to Windows Package Manager\n\n## Independent Software Vendor (ISV) or Publisher\n\nIf you are an ISV or Publisher, you can use Windows Package Manager as a distribution channel for software packages containing your applications. Windows Package Manager currently supports installers in the following formats: MSIX, MSI, and EXE.\n\nTo submit software packages to Windows Package Manager, follow these steps:\n\n1. [Create a package manifest that provides information about your application](manifest.md). Manifests are YAML files that follow the Windows Package Manager schema.\n2. [Submit your manifest to the Windows Package Manager repository](repository.md). This is an open source repository on GitHub that contains a collection of manifests that the **winget** tool can access.\n\n## Community Member\n\nIf you are a GitHub community member, you may also submit packages to Windows Package Manager following the steps above.\n\nOptionally, you may also request help to have a package added to the [community repository](https://github.com/microsoft/winget-pkgs). To do so, create a new [Package Request/Submission](https://github.com/microsoft/winget-pkgs/issues/new/choose) Issue.\n\n## Related topics\n\n* [Use the winget tool](../winget/index.md)\n* [Create your package manifest](manifest.md)\n* [Submit your manifest to the repository](repository.md)\n"
  },
  {
    "path": "doc/windows/package-manager/package/manifest.md",
    "content": "---\ntitle: Create your package manifest\ndescription: If you want to submit a software package to the Windows Package Manager repository, start by creating a package manifest.\nms.date: 04/29/2020\nms.topic: article\nms.localizationpriority: medium\n---\n\n# Create your package manifest\n\nIf you want to submit a software package to the [Windows Package Manager Community Repository](repository.md), start by creating a package manifest. The manifest is a YAML file that describes the application to be installed.\n\nYou may either use the [Windows Package Manager Manifest Creator](https://github.com/microsoft/winget-create), the [YAMLCreate](#using-the-yamlcreateps1) PowerShell script, or you can craft a manifest manually following the instructions below.\n\n### Using WinGetCreate Utility\n\nYou can install `wingetcreate` utility using the command below.\n\n```powershell\nwinget install wingetcreate\n```\n\nAfter installation, you can run `wingetcreate new` to create a new package and fill in the prompts. The last option **WinGetCreate** will offer is for you to submit the manifest to the packages repository. If you choose yes, you will automatically submit your Pull Request (PR) to the [Windows Package Manager Community Repository](https://github.com/microsoft/winget-pkgs).\n\n### Using the YAMLCreate.ps1\nTo help author manifest files, we have provided a YAMLCreate.ps1 powershell script located in the Tools folder on the [Windows Package Manager Community Repository](https://github.com/microsoft/winget-pkgs). You can use the script by cloning the [Windows Package Manager Community Repository](https://github.com/microsoft/winget-pkgs) on your PC and run the script directly from the **Tools** folder. The script will prompt you for the URL to the installer, then will prompt you to fill in metadata. Like **WinGetCreate**, this script will also offer you to submit your manifest automatically.\n\n## YAML basics\n\nThe YAML format was chosen for package manifests because of its relative ease of human readability and consistency with other Microsoft development tools. If you are not familiar with YAML syntax, you can learn the basics at [Learn YAML in Y Minutes](https://learnxinyminutes.com/docs/yaml/).\n\n> Manifests for Windows Package Manager currently do not support all YAML features. Unsupported YAML features include anchors, complex keys, and sets.\n\n## Conventions\n\nThese conventions are used in this article:\n\n* To the left of `:` is a literal keyword used in manifest definitions.\n* To the right of `:` is a data type. The data type can be a primitive type like **string** or a reference to a rich structure defined elsewhere in this article.\n* The notation `[` *datatype* `]` indicates an array of the mentioned data type. For example, `[ string ]` is an array of strings.\n* The notation `{` *datatype* `:` *datatype* `}` indicates a mapping of one data type to another. For example, `{ string: string }` is a mapping of strings to strings.\n\n## Manifest contents\n\nA package manifest must include a set of required items, and can also include further optional items that can help improve the customer experience of installing your software. This section provides brief summaries of the required manifest schema and complete manifest schemas, and examples of each.\n\nEach field in the manifest file must be Pascal-cased and cannot be duplicated.\n\nFor a complete list and descriptions of items in a manifest, see the [manifest specification](https://github.com/microsoft/winget-pkgs/tree/master/doc/manifest/schema) in the [https://github.com/microsoft/winget-pkgs](https://github.com/microsoft/winget-pkgs) repository.\n\n### Minimal required schema\n\n#### [Minimal required schema](#tab/minschema/)\n\nAs specified in the [singleton JSON schema](https://github.com/microsoft/winget-cli/blob/master/schemas/JSON/manifests/v1.4.0/manifest.singleton.1.4.0.json),\nonly a number of fields are required.  The minimal supported YAML file would look like the example below. The singleton format is only valid for packages containing\na single installer and a single locale. If more than one installer or locale is provided, the multiple YAML file format and schema must be used.\n\nThe partitioning scheme was added to help with GitHub's UX. Folders with thousands of children do not render well in the browser.\n\n\n```YAML\nPackageIdentifier:  # Publisher.package format.\nPackageVersion:     # Version numbering format.\nPackageLocale:      # BCP 47 format (e.g. en-US)\nPublisher:          # The name of the publisher.\nPackageName:        # The name of the application.\nLicense:            # The license of the application.\nShortDescription:   # The description of the application.\nInstallers:\n - Architecture:    # Enumeration of supported architectures.\n   InstallerType:   # Enumeration of supported installer types (exe, msi, msix, inno, wix, nullsoft, appx).\n   InstallerUrl:    # Path to download installation file.\n   InstallerSha256: # SHA256 calculated from installer.\nManifestType:       # The manifest file type\nManifestVersion: 1.4.0\n```\n\n#### [Example](#tab/minexample/)\n\nPath: manifests / m / Microsoft / WindowsTerminal / 1.6.10571.0 / Microsoft.WindowsTerminal.yaml\n\n```YAML\nPackageIdentifier: Microsoft.WindowsTerminal\nPackageVersion: 1.6.10571.0\nPackageLocale: en-US\nPublisher: Microsoft\nPackageName: Windows Terminal\nLicense: MIT\nShortDescription: The new Windows Terminal, a tabbed command line experience for Windows.\nInstallers:\n - Architecture: x64\n   InstallerType: msix\n   InstallerUrl: https://github.com/microsoft/terminal/releases/download/v1.6.10571.0/Microsoft.WindowsTerminal_1.6.10571.0_8wekyb3d8bbwe.msixbundle\n   InstallerSha256: 092aa89b1881e058d31b1a8d88f31bb298b5810afbba25c5cb341cfa4904d843\n   SignatureSha256: e53f48473621390c8243ada6345826af7c713cf1f4bbbf0d030599d1e4c175ee\nManifestType: singleton\nManifestVersion: 1.4.0\n```\n\n#### Multiple File Example\nIn order to provide the best user experience, manifests should contain as much meta-data as possible. In order to separate concerns for validating installers\nand providing localized meta-data manifests will be split into multiple files. The minimum number of YAML files for this kind of manifest is three. Additional\nlocales should also be provided.\n* A [version](https://github.com/microsoft/winget-cli/blob/master/schemas/JSON/manifests/v1.4.0/manifest.version.1.4.0.json) file\n* The [default locale](https://github.com/microsoft/winget-cli/blob/master/schemas/JSON/manifests/v1.4.0/manifest.defaultLocale.1.4.0.json) file\n* An [installer](https://github.com/microsoft/winget-cli/blob/master/schemas/JSON/manifests/v1.4.0/manifest.installer.1.4.0.json) file\n* Additional [locale](https://github.com/microsoft/winget-cli/blob/master/schemas/JSON/manifests/v1.4.0/manifest.locale.1.4.0.json) files\n\nThe example below shows many optional meta-data fields and multiple locales. Note the default locale has more requirements than additional locales. In the show\ncommand, any required fields that aren't provided for additional locales will display fields from the default locale.\n\nPath: manifests / m / Microsoft / WindowsTerminal / 1.6.10571.0 / Microsoft.WindowsTerminal.yaml\n\n```YAML\nPackageIdentifier: Microsoft.WindowsTerminal\nPackageVersion: 1.6.10571.0\nDefaultLocale: en-US\nManifestType: version\nManifestVersion: 1.4.0\n```\n\nPath: manifests / m / Microsoft / WindowsTerminal / 1.6.10571.0 / Microsoft.WindowsTerminal.locale.en-US.yaml\n\n```YAML\nPackageIdentifier: Microsoft.WindowsTerminal\nPackageVersion: 1.6.10571.0\nPackageLocale: en-US\nPublisher: Microsoft\nPublisherURL: https://www.microsoft.com/\nPrivacyURL: https://privacy.microsoft.com/\nPackageName: Windows Terminal\nPackageURL: https://docs.microsoft.com/windows/terminal/\nLicense: MIT\nLicenseURL: https://github.com/microsoft/terminal/blob/master/LICENSE\nShortDescription: The new Windows Terminal, a tabbed command line experience for Windows.\nTags:\n- console\n- command-line\n- shell\n- command-prompt\n- powershell\n- wsl\n- developer-tools\n- utilities\n- cli\n- cmd\n- ps\n- terminal\nManifestType: defaultLocale\nManifestVersion: 1.4.0\n```\n\nPath: manifests / m / Microsoft / WindowsTerminal / 1.6.10571.0 / Microsoft.WindowsTerminal.locale.fr-FR.yaml\n\n```YAML\nPackageIdentifier: Microsoft.WindowsTerminal\nPackageVersion: 1.6.10571.0\nPackageLocale: fr-FR\nPublisher: Microsoft\nShortDescription: Le nouveau terminal Windows, une expérience de ligne de commande à onglets pour Windows.\nManifestType: locale\nManifestVersion: 1.4.0\n```\n\nPath: manifests / m / Microsoft / WindowsTerminal / 1.6.10571.0 / Microsoft.WindowsTerminal.installer.yaml\n\n```YAML\nPackageIdentifier: Microsoft.WindowsTerminal\nPackageVersion: 1.6.10571.0\nPlatform:\n - Windows.Desktop\nMinimumOSVersion: 10.0.18362.0\nInstallerType: msix\nInstallModes:\n - silent\nPackageFamilyName: Microsoft.WindowsTerminal_8wekyb3d8bbwe\nInstallers:\n - Architecture: x64\n   InstallerUrl: https://github.com/microsoft/terminal/releases/download/v1.6.10571.0/Microsoft.WindowsTerminal_1.6.10571.0_8wekyb3d8bbwe.msixbundle\n   InstallerSha256: 092aa89b1881e058d31b1a8d88f31bb298b5810afbba25c5cb341cfa4904d843\n   SignatureSha256: e53f48473621390c8243ada6345826af7c713cf1f4bbbf0d030599d1e4c175ee\n - Architecture: arm64\n   InstallerUrl: https://github.com/microsoft/terminal/releases/download/v1.6.10571.0/Microsoft.WindowsTerminal_1.6.10571.0_8wekyb3d8bbwe.msixbundle\n   InstallerSha256: 092aa89b1881e058d31b1a8d88f31bb298b5810afbba25c5cb341cfa4904d843\n   SignatureSha256: e53f48473621390c8243ada6345826af7c713cf1f4bbbf0d030599d1e4c175ee\n - Architecture: x86\n   InstallerUrl: https://github.com/microsoft/terminal/releases/download/v1.6.10571.0/Microsoft.WindowsTerminal_1.6.10571.0_8wekyb3d8bbwe.msixbundle\n   InstallerSha256: 092aa89b1881e058d31b1a8d88f31bb298b5810afbba25c5cb341cfa4904d843\n   SignatureSha256: e53f48473621390c8243ada6345826af7c713cf1f4bbbf0d030599d1e4c175ee\nManifestType: installer\nManifestVersion: 1.4.0\n```\n\n* * *\n\n> If your installer is an .exe and it was built using Nullsoft or Inno, you may specify those values instead. When Nullsoft or Inno are specified, the client will automatically set the silent and silent with progress install behaviors for the installer.\n\n## Installer switches\n\nYou can often figure out what silent `Switches` are available for an installer by passing in a `-?` to the installer from the command line. Here are some common silent `Switches` that can be used for different installer types.\n\n| Installer | Command  | Documentation |\n| :--- | :-- | :--- |\n| MSI | `/q` | [MSI Command-Line Options](https://docs.microsoft.com/windows/win32/msi/command-line-options) |\n| InstallShield | `/s`  | [InstallShield Command-Line Parameters](https://docs.flexera.com/installshield19helplib/helplibrary/IHelpSetup_EXECmdLine.htm) |\n| Inno Setup | `/SILENT or /VERYSILENT` | [Inno Setup documentation](https://jrsoftware.org/ishelp/) |\n| Nullsoft | `/S` | [Nullsoft Silent Installers/Uninstallers](https://nsis.sourceforge.io/Docs/Chapter4.html#silent) |\n\n## Tips and best practices\n\n* The package identifier must be unique. You cannot have multiple submissions with the same package identifier. Only one pull request per package version is allowed.\n\n* Avoid creating multiple publisher folders. For example, do not create \"Contoso Ltd.\" if there is already a \"Contoso\" folder.\n\n* All tools must support a silent install. If you have an executable that does not support a silent install, then we cannot provide that tool at this time.\n\n* Provide as many fields as possible.  The more meta-data you provide the better the user experience will be. In some cases, the fields may not yet be supported\nby the Windows Package Manager client (winget.exe). For example, the `Moniker` field is optional. However, if you include this field, customers will see results associated with the `Moniker` value when performing the [search](../winget/search.md) command (for example, **vscode** for **Visual Studio Code**). If there is only one app with the specified `Moniker` value, customers can install your application by specifying the moniker rather than the fully qualified package identifier.\n\n* The length of strings in this specification should be limited to 100 characters before a line break.\n\n* The \"PackageName\" and \"Publisher\" should match the entry made in Add / Remove Programs to help the correlation with manifests to support **export**, and **upgrade**.\n\n* Package installers in MSI format use [Product Codes](https://docs.microsoft.com/windows/win32/msi/product-codes) to uniquely identify applications. The product code for a given version of a package should be included in the manifest to help ensure the best **upgrade** experience.\n\n* Limit the length of strings in your manifest to 100 characters before a line break.\n* When more than one installer type exists for the specified version of the package, an instance of `InstallerType` can be placed under each of the `Installers`.\n"
  },
  {
    "path": "doc/windows/package-manager/package/repository.md",
    "content": "---\ntitle: Submit your manifest to the repository\ndescription: After you create a package manifest that describes your application, you're ready to submit your manifest to the Windows Package Manager repository.\nms.date: 04/29/2020\nms.topic: article\nms.localizationpriority: medium\n---\n\n# Submit your manifest to the repository\n\nAfter you create a [package manifest](manifest.md) that describes your application, you're ready to submit your manifest to the Windows Package Manager repository. This a public-facing repository that contains a collection of manifests that the **winget** tool can access. To submit your manifest, you'll upload it to the open source [https://github.com/microsoft/winget-pkgs](https://github.com/microsoft/winget-pkgs) repository on GitHub.\n\nAfter you submit a **pull request** to add a new manifest to the GitHub repository, an automated process will validate your manifest file and check to make sure the package complies with the [Windows Package Manager polices](windows-package-manager-policies.md) and is not known to be malicious. If this validation is successful, your package will be added to the public-facing Windows Package Manager repository so it can be discovered by the **winget** client tool. Note the distinction between the manifests in the open source GitHub repository and the public-facing Windows Package Manager repository.\n\n> **Important**: Microsoft reserves the right to refuse a submission for any reason.\n\n## Third-party repositories\n\nThere are currently no known third party repositories. Microsoft is working with multiple partners to develop protocols or an API to enable third party repositories.\n\n## Manifest validation\n\nWhen you submit a manifest to the [https://github.com/microsoft/winget-pkgs](https://github.com/microsoft/winget-pkgs) repository on GitHub, your manifest will be automatically validated and evaluated for the safety of the Windows ecosystem. Manifests will be reviewed manually by [Community Moderators](https://github.com/microsoft/winget-pkgs/issues/15674).\n\nFor information on the validation process, see [Windows Package Manager validation](winget-validation.md)\n\n## How to submit your manifest\n\nTo submit a manifest to the repository, follow these steps.\n\n### Step 1: Validate your manifest\n\nThe **winget** tool provides the [validate](../winget/validate.md) command to confirm that you have created your manifest correctly. To validate your manifest, use this command.\n\n```CMD\nwinget validate <path-to-the-manifests>\n```\n\nIf your validation fails, use the errors to locate the line number and make a correction. After your manifest is validated, you can submit it to the repository.\n\n### Step 2: Clone the repository\n\nNext, create a fork of the repository and clone it.\n\n1. Go to [https://github.com/microsoft/winget-pkgs](https://github.com/microsoft/winget-pkgs) in your browser and click **Fork**.\n    ![picture of fork](images/fork.png)\n\n2. From a command line environment such as the Windows Command Prompt or PowerShell, use the following command to clone your fork.\n    ```CMD\n    git clone <your-fork-name>\n    ```\n\n 3. If you are making multiple submissions, make a branch instead of a fork. We currently allow only one manifest file per PR.\n    ```CMD\n    git checkout -b <branch-name>\n    ```\n\n### Step 3: Add your manifest to the local repository\n\nYou must add your manifest files to the repository in the following folder structure:\n\n**manifests** / **letter** / **publisher** / **application** / **version**\n\n* The **manifests** folder is the root folder for all manifests in the repository.\n* The **letter** folder is the first letter of the publisher name in the lower case. For example, **m** of the publisher **Microsoft**.\n* The **publisher** folder is the name of the company that publishes the software. For example, **Microsoft**.\n* The **application** folder is the name of the application or tool. For example, **VSCode**.\n* The **version** folder is the version of the application or tool. For example, **1.0.0**.\n\nThe `PackageIdentifier` and the `PackageVersion` values in the manifest must match the publisher, application names and version in the manifest folder path. For more information, see [Create your package manifest](manifest.md#tips-and-best-practices).\n\n### Step 4: Submit your manifest to the remote repository\n\nYou're now ready to push your new manifest to the remote repository.\n\n1. Use the `commit` command to add files and commit the change and provide information on the submission.\n    ```CMD\n    git commit -m \"Submitting ContosoApp version 1.0.0\" --all\n    ```\n\n3. Use the `push` command to push the changes to the remote repository.\n    ```CMD\n    git push\n    ```\n\n### Step 5: Create a pull request\n\nAfter you push your changes, return to [https://github.com/microsoft/winget-pkgs](https://github.com/microsoft/winget-pkgs) and create a **pull request** to merge your fork or branch to the main branch.\n\n![picture of pull request tab](images/pull-request.png)\n\n## Submission process\n\nWhen you create a **pull request**, this will start an automated process that validates the manifests and verifies your **pull request**. During this process we will run tests against the installer and installed binaries to validate the submission.\n\nWe add labels to your **pull request** so you can track its progress.  For more information on labels and the process see [Windows Package Manager validation](winget-validation.md).\n\nOnce complete, your submission will be manually reviewed by a moderator, and after it is approved, your application will be added to the Windows Package Manager catalog.\n\nIf there is ever an error during the process, you will be notified and our labels and bot will assist you in fixing your submission.  For the list of common errors, see [Windows Package Manager validation](winget-validation.md).\n"
  },
  {
    "path": "doc/windows/package-manager/package/windows-package-manager-policies-change-history.md",
    "content": "# Change history for Microsoft Store Policies\n\n| Date | Document Version | Change Description |\n|------|------------------|--------------------|\n| 5/25/2021 | 1.0 | Initial publishing of Windows Package Manager Policies|\n"
  },
  {
    "path": "doc/windows/package-manager/package/windows-package-manager-policies.md",
    "content": "# Windows Package Manager Repository Policies\n\n**Document version: 1.0**\n\n**Document date: May 22, 2021**\n\n**Effective date: May 22, 2021**\n\nThank you for your interest in providing a Product to the Windows Package Manager repository.\n\n\"Product\" means content in whatever form including, but not limited to, apps, games, titles, and any additional content sold or offered from within a Product.\n\"Submission\" means [**Pull Request**](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request)\n of manifest files and includes but is not limited to the \"Product\" and metadata about the \"Product\".\n\nA few principles to get you started:\n\n- Offer unique and distinct value within your Submission. Provide a compelling reason to download the Product from [Windows Package Manager repository](https://www.github.com/microsoft/winget-pkgs).\n- Don’t mislead our customers about what your Submission can do, who is offering it, etc.\n- Don’t attempt to cheat customers, the system or the ecosystem. There is no place in the repository for any kind of fraud, be it ratings and review manipulation, credit card fraud or other fraudulent activity.\n\nAdhering to these policies should help you make choices that enhance your Submission’s appeal and audience.\n\nYour Submissions are crucial to the experience of hundreds of millions of customers. We can’t wait to see what you create and are thrilled to help deliver your Submissions to the world.\n\nIf you have feedback on the policies or the Windows Package Manager, please let us know by commenting in our [GitHub issues forum](https://www.github.com/microsoft/winget-cli/issues)\n\n## Table of Contents\n\n**Product Policies:**\n\n- [1.1 Distinct Function & Value; Accurate Representation](#11-distinct-function--value-accurate-representation)\n- [1.2 Security](#12-security)\n- [1.3 Product is Testable](#13-product-is-testable)\n- [1.4 Usability](#14-usability)\n- [1.5 Personal Information](#15-personal-information)\n- [1.6 Capabilities](#16-capabilities)\n- [1.7 Localization](#17-localization)\n- [1.8 Financial Transactions](#18-financial-transactions)\n- [1.9 Notifications](#19-notifications)\n- [1.10 Advertising Conduct and Content](#110-advertising-conduct-and-content)\n\n**Content Policies:**\n- [2.1 General Content Requirements](#21-general-content-requirements)\n- [2.2 Content Including Names, Logos, Original and Third Party](#22-content-including-names-logos-original-and-third-party)\n- [2.3 Risk of Harm](#23-risk-of-harm)\n- [2.4 Defamatory, Libelous, Slanderous and Threatening](#24-defamatory-libelous-slanderous-and-threatening)\n- [2.5 Offensive Content](#25-offensive-content)\n- [2.6 Alcohol, Tobacco, Weapons and Drugs](#26-alcohol-tobacco-weapons-and-drugs)\n- [2.7 Adult Content](#27-adult-content)\n- [2.8 Illegal Activity](#28-illegal-activity)\n- [2.9 Excessive Profanity and Inappropriate Content](#29-excessive-profanity-and-inappropriate-content)\n- [2.10 Country/Region Specific Requirements](#210-countryregion-specific-requirements)\n- [2.11 Age Ratings](#211-age-ratings)\n- [2.12 User Generated Content](#212-user-generated-content)\n\n## Product Policies\n\n### 1.1 Distinct Function & Value; Accurate Representation\n\nThe Product and its associated metadata, including but not limited to the app title, description, screenshots, trailers, content rating and Product category, must accurately and clearly reflect the source, functionality, and features of the Product.\n\n### 1.1.1\n\nAll aspects of the Product should accurately describe the functions, features and any important limitations of the Product.\n\n### 1.1.2\n\n[Tags](https://github.com/microsoft/winget-cli/blob/master/schemas/JSON/manifests/v1.4.0/manifest.defaultLocale.1.4.0.json) may not exceed 16 unique tags and should be relevant to the Product.\n\n### 1.1.3\n\nThe Product must have distinct and informative metadata and must provide a valuable and quality user experience.\n\n### 1.1.4\nThe [InstallerUrl](https://github.com/microsoft/winget-cli/blob/master/schemas/JSON/manifests/v1.4.0/manifest.defaultLocale.1.4.0.json) must be the ISVs release location for the Product.  Products from download websites will not be allowed.\n\n### 1.2 Security\n\nThe Product must not jeopardize or compromise user security, or the security or functionality of the device, system or related systems.\n\n### 1.2.1\n\nThe Product must not attempt to change or extend its described functionality through any form of dynamic inclusion of code that is in violation of Windows Package Manager Policies. The Product should not, for example, download a remote script and subsequently execute that script in a manner that is not consistent with the described functionality.\n\n### 1.2.2\n\nThe Product must not contain or enable malware as defined by the Microsoft criteria for [Unwanted and Malicious Software](https://docs.microsoft.com/windows/security/threat-protection/intelligence/criteria).\n\n### 1.2.3\n\nThe Product may contain fully integrated middleware (such as third-party cross-platform engines and third-party analytics services).\n\nThe Product may depend on non-integrated software (such as another Product, module, or service) to deliver its primary functionality, subject to the following requirements:\n\n### 1.3 Product is Testable\n\nThe Product must be testable. If it is not possible to test your submitted Product for any reason your Product may fail this requirement.\n\n### 1.4 Usability\n\nThe Product should meet usability standards, including, but not limited to, those listed in the subsections below.\n\n### 1.4.1\n\nThe Product should support the devices and platforms on which they are downloaded, including compatibility with the software, hardware and screen resolution requirements specified by the Product. If the Product is downloaded on a device with which it is not compatible, it should detect that at launch and display a message to the customer detailing the requirements.\n\n### 1.4.2\n\nThe Product should continue to run and remain responsive to user input. Products should shut down gracefully and not close unexpectedly. The Product should handle exceptions raised by any of the managed or native system APIs and remain responsive to user input after the exception is handled.\n\n### 1.4.3\n\nThe Product should start up promptly and must stay responsive to user input.\n\n### 1.5 Personal Information\n\nThe following requirements apply to Products that access Personal Information. Personal Information includes all information or data that identifies or could be used to identify a person, or that is associated with such information or data.\n\n### 1.5.1\n\nIf the Product accesses, collects or transmits Personal Information, or if otherwise required by law, it should maintain a privacy policy. The submission, should include the [PrivacyUrl](https://github.com/microsoft/winget-cli/blob/master/schemas/JSON/manifests/v1.4.0/manifest.defaultLocale.1.4.0.json) which links to the privacy policy of the Product.\n\n### 1.5.2\n\nIf the Product publishes the Personal Information of customers of the Product to an outside service or third party, the Product should only do so after obtaining opt-in consent from those customers. Opt-in consent means the customer gives their express permission in the Product user interface for the requested activity, after the Product has:\n\n- described to the customer how the information will be accessed, used or shared, indicating the types of parties to whom it is disclosed, and\n- provided the customer a mechanism in the Product user interface through which they can later rescind this permission and opt-out.\n\n### 1.5.3\n\nIf the Product publishes a person’s Personal Information to an outside service or third party through the Product or its metadata, but the person whose information is being shared is not a customer of the Product, the Product must obtain express written consent to publish that Personal Information, and must permit the person whose information is shared to withdraw that consent at any time. If the Product provides a customer with access to another person’s Personal Information, this requirement would also apply.\n\n### 1.5.4\n\nIf the Product collects, stores or transmits Personal Information, it must do so securely, by using modern cryptography methods.\n\n### 1.5.5\n\nThe Product must not collect, store or transmit highly sensitive personal information, such as health or financial data, unless the information is related to the Product’s functionality. The Product must also obtain express user consent before collecting, storing or transmitting such information. The Product’s privacy policy must clearly tell the user when and why it is collecting Personal Information and how it will be used.\n\n### 1.5.6\n\nIf the Product supports Microsoft identity authentication it must do so only by using Microsoft-approved methods.\n\n### 1.5.7\n\nProducts that receive device location must provide settings that allow the user to enable and disable the Product's access to and use of location from the Location Service API.\n\n### 1.6 Capabilities\n\nIf the Product declares the use of capabilities, then the capabilities the Product declares must legitimately relate to the functions of the Product.  The Product must not circumvent operating system checks for capability usage.\n\n### 1.7 Localization\n\nIf the Product you should provide localized all languages that it supports. The experience provided by a product must be reasonably similar in all languages that it supports.\n\n### 1.8 Financial Transactions\n\nIf your product includes in-product purchase, subscriptions, virtual currency, billing functionality or captures financial information, the following requirements apply:\n\n### 1.8.1\n\nIn-product offerings sold in your product cannot be converted to any legally valid currency (for example, USD, Euro, etc.) or any physical goods or services.\n\n### 1.8.2\n\nThe Product must use a secure purchase API for purchases of physical goods or services, and a secure purchase API for payments made in connection with real world gambling or charitable contributions. If the Product is used to facilitate or collect charitable contributions or to conduct a promotional sweepstakes or contest, it must do so in compliance with applicable law. The Product must also state clearly that Microsoft is not the fundraiser or sponsor of the promotion.\n\nThe Product must use a secure purchase API to receive voluntary donations from users.\n\nThe following requirements apply to your use of a secure purchase API:\n\n- At the time of the transaction or when the Product collects any payment or financial information from the customer, the Product must identify the commerce transaction provider, authenticate the user, and obtain user confirmation for the transaction.\n- The product can offer the user the ability to save this authentication, but the user must have the ability to either require an authentication on every transaction or to turn off in-product transactions.\n- If the product collects credit card information or uses a third-party payment processor that collects credit card information, the payment processing must meet the current PCI Data Security Standard (PCI DSS).\n\n### 1.8.3\n\nThe product and its associated metadata must provide information about the types of in-product purchases offered and the range of prices. The Product not mislead customers and must be clear about the nature of the in-product promotions and offerings including the scope and terms of any trial experiences. If the Product restricts access to user-created content during or after a trial, it must notify users in advance. In addition, the Product must make it clear to users that they are initiating a purchase option in the Product.\n\nIf your game offers “loot boxes” or other mechanisms that provide randomized virtual items, then you must disclose the odds of receiving each item to customers prior to purchase. These disclosures may appear: in-product, such as in an in-app store, on the Microsoft Store Product Description Page (PDP), and/or on a developer or publisher website, with a link from the Store Product Description Page (PDP) and/or in-app.\n\n### 10.8.4\n\nAll pricing, including sales or discounting, for your digital products or services shall comply with all applicable laws, regulations and regulatory guidelines, including without limitation, the Federal Trade Commission [Guides Against Deceptive Pricing](https://www.ecfr.gov/cgi-bin/text-idx?SID=676bd39fe43a808fcb417973b3d0247e&mc=true&tpl=/ecfrbrowse/Title16/16cfr233_main_02.tpl).\n\n### 1.9 Notifications\n\nIf the Product supports notifications, then the Product must respect system settings for notifications and remain functional when they are disabled. This includes the presentation of ads and notifications to the customer, which must also be consistent with the customer’s preferences, whether the notifications are provided by the Microsoft Push Notification Service (MPNS), Windows Push Notification Service (WNS) or any other service. If the customer disables notifications, either on an Product-specific or system-wide basis, the Product must remain functional.\n\n### 1.10 Advertising Conduct and Content\n\nFor all advertising related activities, the following requirements apply:\n\n### 1.10.1\n\n- The primary purpose of the Product should not be to get users to click ads.\n- The Product may not do anything that interferes with or diminishes the visibility, value, or quality of any ads it displays.\n- The Product must respect advertising ID settings that the user has selected.\n- All advertising must be truthful, non-misleading and comply with all applicable laws, regulations, and regulatory guidelines.\n\n## Content Policies\n\nThe following policies apply to content and metadata (including publisher name, Product name, Product icon, Product description, Product screenshots, Product trailers and trailer thumbnails, and any other Product metadata) offered for distribution in the Windows Package Manager repository. Content means the Product name, publisher name, Product icon, Product description, the images, sounds, videos and text contained in the Product, the tiles, notifications, error messages or ads exposed through the Product, and anything that’s delivered from a server or that the Product connects to. Because Product and the Windows Package Manager repository are used around the world, these requirements will be interpreted and applied in the context of regional and cultural norms.\n\n### 2.1 General Content Requirements\n\nMetadata and other content you submit to accompany your submission may contain only content that would merit a rating of PEGI 12, ESRB EVERYONE 10+, or lower.\n\n### 2.2 Content Including Names, Logos, Original and Third Party\n\nAll content in the Product and associated metadata must be either originally created by the application provider, appropriately licensed from the third-party rights holder, used as permitted by the rights holder, or used as otherwise permitted by law.\n\n### 2.3 Risk of Harm\n\n### 2.3.1\n\nThe Product must not contain any content that facilitates or glamorizes the following real world activities: (a) extreme or gratuitous violence; (b) human rights violations; (c) the creation of illegal weapons; or (d) the use of weapons against a person, animal, or real or personal property.\n\n### 2.3.2\n\nThe Product must not: (a) pose a safety risk to, nor result in discomfort, injury or any other harm to end users or to any other person or animal; or (b) pose a risk of or result in damage to real or personal property. You are solely responsible for all Product safety testing, certificate acquisition, and  implementation of any appropriate feature safeguards. You will not disable any platform safety or comfort features, and you must include all legally required and industry-standard warnings, notices, and disclaimers in the Product.\n\n### 2.4 Defamatory, Libelous, Slanderous and Threatening\n\nThe Product must not contain any content that is defamatory, libelous, slanderous, or threatening.\n\n### 2.5 Offensive Content\n\nThe Product and associated metadata must not contain potentially sensitive or offensive content. Content may be considered sensitive or offensive in certain countries/regions because of local laws or cultural norms. In addition, the Product and associated metadata must not contain content that advocates discrimination, hatred, or violence based on considerations of race, ethnicity, national origin, language, gender, age, disability, religion, sexual orientation, status as a veteran, or membership in any other social group.\n\n### 2.6 Alcohol, Tobacco, Weapons and Drugs\n\nThe Product must not contain any content that facilitates or glamorizes excessive or irresponsible use of alcohol or tobacco Products, drugs, or weapons.\n\n### 2.7 Adult Content\n\nThe Product must not contain or display content that a reasonable person would consider pornographic or sexually explicit.\n\n### 2.8 Illegal Activity\n\nThe Product must not contain content or functionality that encourages, facilitates or glamorizes illegal activity in the real world.\n\n### 2.9 Excessive Profanity and Inappropriate Content\n\n- The Product must not contain excessive or gratuitous profanity.\n- The Product must not contain or display content that a reasonable person would consider to be obscene.\n\n### 2.10 Country/Region Specific Requirements\n\nContent that is offensive in any country/region to which the Product is targeted is not allowed. Content may be considered offensive in certain countries/regions because of local laws or cultural norms. Examples of potentially offensive content in certain countries/regions include the following:\n\nChina\n\n- Prohibited sexual content\n- Disputed territory or region references\n- Providing or enabling access to content or services that are illegal under applicable local law\n\n### 2.11 Age Ratings\n\nThe Product should have a age rating that would merit a rating of PEGI 12, ESRB EVERYONE 10+, or lower.\n\n### 2.11.1\n\nIf the Product provides content (such as user-generated, retail or other web-based content) that might be appropriate for a higher age rating than its assigned rating, you must enable users to opt in to receiving such content by using a content filter or by signing in with a preexisting account.\n\n### 2.12 User Generated Content\n\nUser Generated Content (UGC) is content that users contribute to an app or Product and which can be viewed or accessed by other users in an online state. If the Product contains UGC, the Product should:\n\n- Publish and make available to users a Product terms of service and/or content guidelines for User Generated Content either in Product or on the Product website.\n- Provide a means for users to report inappropriate content within the Product to the developer for review and removal/disablement if in violation of content guidelines and/or implement a method for proactive detection of inappropriate or harmful UGC.\n- Remove or disable UGC when requested by Microsoft.\n\n### See also\n\n- [Change history for Windows Package Manager Policy History](windows-package-manager-policies-change-history.md)\n- [Windows Package Manager Code of Conduct](https://github.com/microsoft/winget-pkgs/blob/master/CODE_OF_CONDUCT.md)\n- [Windows Package Manager Contributing requirements](https://github.com/microsoft/winget-pkgs/blob/master/README.md)\n"
  },
  {
    "path": "doc/windows/package-manager/package/winget-validation-troubleshooter.md",
    "content": "# Change history for Microsoft Store Policies\n\n| Date | Document Version | Change Description |\n|------|------------------|--------------------|\n| 5/25/2021 | 1.0 | Initial publishing of Windows Package Manager Policies|\n"
  },
  {
    "path": "doc/windows/package-manager/package/winget-validation.md",
    "content": "## Validation process\r\n\r\nWhen you create a pull request, this will start an automation process that validates the manifest and processes your pull request. GitHub labels are used to share progress and allow you to communicate with us.\r\n\r\n## Submission expectations\r\n\r\nAll application submissions to the Windows Package Manager repository should be well-behaved and adhere to the [Windows Package Manager policies](./windows-package-manager-policies.md).\r\nHere are some expectations for submissions:\r\n\r\n- The manifest complies with the [schema requirements](https://learn.microsoft.com/en-us/windows/package-manager/package/manifest?tabs=minschema%2Cversion-example#minimal-required-schema).\r\n- All URLs in the manifest lead to safe websites.\r\n\r\n- The installer and application are virus free. The package may be identified as malware by mistake. If you believe it is a false positive you can [submit the installer to the defender team for\r\n analysis](https://www.microsoft.com/wdsi/filesubmission).\r\n\r\n- The application installs and uninstalls correctly for both administrators and non-administrators.\r\n\r\n- The installer supports non-interactive modes.\r\n\r\n- All manifest entries are accurate and not misleading.\r\n\r\n- The installer comes directly from the publisher\\'s website.\r\n\r\nPlease see [Windows Package Manager policies](windows-package-manager-policies.md) for a complete list of the policies.\r\n\r\n## Pull request labels\r\n\r\nDuring validation, we apply a series of labels to our pull request to\r\ncommunicate progress. Some labels will direct the ISV to take action,\r\nwhile others will be directed to the Package Manager developers.\r\n\r\n### Status Labels\r\n\r\nThe following table describes the possible **status labels** you will\r\nencounter:\r\n\r\n| **Label** | **Details** |\r\n|--------------|-------------|\r\n| <img width=180/> | <img width=500/> |\r\n| **Azure-Pipeline-Passed** | The manifest has completed the test pass. It is waiting for approval. If no issues are encountered during the test pass it will automatically be approved. If a test fails, it may be flagged for manual review.|\r\n| **Blocking-Issue** | This label indicates that the **Pull Request** cannot be approved because there is a blocking issue. You can often tell what the blocking issue is by the included error label as well. |\r\n| **Needs-Attention** | This label indicates that the **Pull Request** needs to be investigated by the Windows Package Manager development team. This is either due to a test failure that needs manual review, or a comment added to the **Pull Request** by the community. |\r\n| **Needs-Author-Feedback** | Indicates there is a failure with the submission. We will reassign **Pull Request** back to you. If you do not address the issue within 10 days, the bot will close the **pull request**. **Needs-Author-Feedback** labels are typically added when there was a failure with the Pull Request that should be updated, or if the person reviewing the Pull Request has a question. |\r\n| **Validation-Completed** | Indicates that the test pass has been completed successfully and your **Pull Request** will be merged.|\r\n\r\n### Error Labels\r\n\r\nThe following table describes the possible **error labels** that will be\r\nencountered. Not all of the error cases will be assigned to the ISV\r\nimmediately. Some may trigger manual validation.\r\n\r\n\r\n| **Label** | **Details** |\r\n|--------------|-------------|\r\n|<img width=200/>|<img width=500/>|\r\n| **Binary-Validation-Error** | The application included in this **Pull Request** failed to pass the **Installers Scan** test. This test is designed to ensure that the application installs on all environments without warnings.  For further details on this error, see [binary validation errors](binary-validation-errors.md). |\r\n| **Error-Analysis-Timeout** | This label indicates that the **Binary-Validation-Test** test timed out. The **Pull Request** will get assigned to a Windows Package Manager developer to look at it. |\r\n| **Error-Hash-Mismatch** | The submitted manifest could not be processed because the **InstallerSha256** hash provided for the **InstallerURL** did not match. Update the **InstallerSha256** in the **Pull Request** and try again. |\r\n| **Error-Installer-Availability** | The validation service was unable to download the installer. This may be related to Azure IP ranges being blocked, or the installer URL may be incorrect. Check that the **InstallerURL** is correct and try again. If you feel this has failed in error, please add a comment and the **Pull Request** will get assigned to a Windows Package Manager developer to look investigate. |\r\n| **Manifest-Path-Error** | The manifest files must be put into a specific folder structure. This label indicates a problem with the path of your submission. For example, the folder structure does not have the [required format](https://docs.microsoft.com/windows/package-manager/package/manifest?tabs=minschema%2Ccompschema). Update your manifest and path resubmit your **Pull Request**. |\r\n| **Manifest-Validation-Error** | The submitted manifest contains a syntax error. Address the syntax issue with the manifest and re-submit. For details on the manifest format and schema see: [required format](https://docs.microsoft.com/windows/package-manager/package/manifest?tabs=minschema%2Ccompschema). |\r\n| **PullRequest-Error** | The pull request is invalid because not all files submitted are under manifest folder or there is more than one package or version in the **Pull Request**. Update your **Pull Request** to address the issue and try again. |\r\n| **URL-Validation-Error** | The **URLs Validation Test** could not locate the URL and responded with a [HTTP error status code](https://docs.microsoft.com/troubleshoot/iis/http-status-code) (403 or 404), or the URL reputation test failed. You can identify which URL is in question by looking at the [Pull Request check details](winget-validation-troubleshooter.md). To address this issue, update the URLs in question to resolve the [HTTP error status code](https://docs.microsoft.com/troubleshoot/iis/http-status-code). If the issue is not due to [HTTP error status code](https://docs.microsoft.com/troubleshoot/iis/http-status-code) then you can [submit the URL for review](https://www.microsoft.com/wdsi/filesubmission/) to avoid the reputation failure. |\r\n| **Validation-Defender-Error** | During dynamic testing, Defender reported a problem. To reproduce this problem, install your application, then run a Defender full scan. If you can reproduce the problem, either fix the binary, or submit to this URL for false positive assistance. As stated in the following article, [Address false positives/negatives in Microsoft Defender for Endpoint Microsoft Docs](https://docs.microsoft.com/microsoft-365/security/defender-endpoint/defender-endpoint-false-positives-negatives?view=o365-worldwide), you can submit your binary for analysis to the [defender analysis web page](https://docs.microsoft.com/microsoft-365/security/defender-endpoint/defender-endpoint-false-positives-negatives?view=o365-worldwide#part-4-submit-a-file-for-analysis). If you are unable to reproduce, add a comment to get the Windows Package Manager developers to look at it. |\r\n| **Validation-Domain** | The test has determined the domain if the **InstallerURL** does not match the domain expected. The Windows Package Manager policies requires that the [InstallerUrl](https://docs.microsoft.com/windows/package-manager/package/manifest?tabs=minschema%2Ccompschema) comes directly from the ISVs release location. If you believe this is a false detection, add a comment to the **Pull Request** to get the Windows Package Manager developers to look at it. |\r\n| **Validation-Error** | Validation of the Windows Package Manager failed during manual approval. Look at the accompanying comment for next steps. |\r\n| **Validation-Executable-Error** | During installation testing, the test was unable to locate the primary application. Make sure the application installs correctly on all platforms. If your application does not install an application, but should still be included in the repository, add a comment to the **Pull Request** to get the Windows Package Manager developers to look at it.|\r\n| **Validation-Hash-Verification-Failed** | During installation testing, the application fails to install because the **InstallerSha256** no longer matches the **InstallerURL** hash. This can occur if the application is behind a vanity URL and the installer was updated without updating the **InstallerSha256**. To address this issue, update the **InstallerSha256** associated with the **InstallerURL** and submit again. |\r\n| **Validation-HTTP-Error** | The URL used for the installer does not use the HTTPs protocol. Please update the **InstallerURL** to use HTTPS and resubmit the **Pull Request.** |\r\n| **Validation-Indirect-URL** | The URL is not coming directly from the ISVs server. Testing has determined a redirector has been used. This is not allowed because the Windows Package Manager policies require that the [InstallerUrl](https://docs.microsoft.com/windows/package-manager/package/manifest?tabs=minschema%2Ccompschema) comes directly from the ISVs release location. Remove the redirection and resubmit.\r\n| **Validation-Installation-Error** | During manual validation of this package, there was a general error. Look at the accompanying comment for next steps.|\r\n| **Validation-Merge-Conflict** | This package could not be validated due to a merge conflict. Please address the merge conflict and resubmit your **Pull Request.**\r\n| **Validation-MSIX-Dependency** | The MSIX package has a dependency on package that could not be resolved. Update the package to include the missing components or add the dependency to the manifest file and resubmit the **Pull Request.**|\r\n| **Validation-Unapproved-URL** | The test has determined the domain if the **InstallerURL** does not match the domain expected. The Windows Package Manager policies requires that the [InstallerUrl](https://docs.microsoft.com/windows/package-manager/package/manifest?tabs=minschema%2Ccompschema) comes directly from the ISVs release location. |\r\n| **Validation-Unattended-Failed** |  During installation, the test timed out.This most likely is due to the application not installing silently. It could also be due to some other error being encountered and stopping the test. Verify that you can install your manifest without user input. If you need assistance, add a comment to the **Pull Request** and the Windows Package Manager developers will look at it. |\r\n| **Validation-Uninstall-Error**  | During uninstall testing, the application did not clean up completely following uninstall. Look at the accompanying comment for more details.|\r\n| **Validation-VCRuntime-Dependency** | The package has a dependency on the C++ runtime that could not be resolved. Update the package to include the missing components or add the dependency to the manifest file and resubmit the **Pull Request**. |\r\n\r\n### Content Policy Labels\r\n\r\nThe following table lists **content policy labels**. If one of\r\nthe following labels is added, then something in the manifest metadata\r\ntriggered additional manual content review to ensure that the metadata\r\nis following the [Windows Package Manager policies](windows-package-manager-policies.md).\r\n\r\n| **Label** | **Details** |\r\n|--------------|-------------|\r\n|<img width=180/>|<img width=500/>|\r\n| **Policy-Test-2.1** |Manual review triggered see [Windows Package Manager Policies](windows-package-manager-policies.md#21-general-content-requirements) |\r\n| **Policy-Test-2.2** | Manual review triggered see [Windows Package Manager Policies](windows-package-manager-policies.md#22-content-including-names-logos-original-and-third-party) |\r\n| **Policy-Test-2.3** | Manual review triggered see [Windows Package Manager Policies](windows-package-manager-policies.md#23-risk-of-harm) |\r\n| **Policy-Test-2.4** | Manual review triggered see [Windows Package Manager Policies](windows-package-manager-policies.md#24-defamatory-libelous-slanderous-and-threatening) |\r\n| **Policy-Test-2.5** | Manual review triggered see [Windows Package Manager Policies](windows-package-manager-policies.md#25-offensive-content) |\r\n| **Policy-Test-2.6** | Manual review triggered see [Windows Package Manager Policies](windows-package-manager-policies.md#26-alcohol-tobacco-weapons-and-drugs) |\r\n| **Policy-Test-2.7** | Manual review triggered see [Windows Package Manager Policies](windows-package-manager-policies.md#27-adult-content) |\r\n| **Policy-Test-2.8** | Manual review triggered see [Windows Package Manager Policies](windows-package-manager-policies.md#28-illegal-activity) |\r\n| **Policy-Test-2.9** | Manual review triggered see [Windows Package Manager Policies](windows-package-manager-policies.md#29-excessive-profanity-and-inappropriate-content) |\r\n| **Policy-Test-2.10** | Manual review triggered see [Windows Package Manager Policies](windows-package-manager-policies.md#210-countryregion-specific-requirements) |\r\n| **Policy-Test-2.11** | Manual review triggered see [Windows Package Manager Policies](windows-package-manager-policies.md#211-age-ratings) |\r\n| **Policy-Test-2.12** | Manual review triggered see [Windows Package Manager Policies](windows-package-manager-policies.md#212-user-generated-content) |\r\n\r\n### Internal Labels\r\n\r\nThe following table lists the **internal errors**. When internal errors are encountered the **Pull Request** will be assigned to the Windows Package\r\nManager developers to investigate:\r\n\r\n| **Label** | **Details** |\r\n|--------------|-------------|\r\n|<img width=180/>|<img width=500/>|\r\n|**Internal-Error-Domain**|During the domain validation of the URL, the test encountered an issue. A Windows Package Manager developer will take a look at it.|\r\n|**Internal-Error-Dynamic-Scan**|During the validation of the installed binaries, the test encountered an issue. A Windows Package Manager developer will take a look at it.|\r\n|**Internal-Error-Keyword-Policy**| During the validation of the manifest, the test encountered an issue. A Windows Package Manager developer will take a look at it.|\r\n|**Internal-Error-Manifest**| During the validation of the manifest, the test encountered an issue. A Windows Package Manager developer will take a look at it.|\r\n|**Internal-Error-NoArchitectures**| Testing encountered and issue where the test could not determine the architecture if the application. A Windows Package Manager developer will take a look at it.|\r\n|**Internal-Error-NoSupportedArchitectures**| Testing encountered and issue where the current architecture is not supported. A Windows Package Manager developer will take a look at it.|\r\n|**Internal-Error-PR**| An error occurred during the processing of the PR. A Windows Package Manager developer will take a look at it.|\r\n|**Internal-Error-Static-Scan**| During static analysis of the installers, the test encountered an issue. A Windows Package Manager developer will take a look at it.|\r\n|**Internal-Error-URL**| During reputation validation of the installers, the test encountered an issue. A Windows Package Manager developer will take a look at it.|\r\n|**Internal-Error**| This indicates a generic failure or unknown error was encountered during the test pass. A Windows Package Manager developer will take a look at it.|\r\n"
  },
  {
    "path": "doc/windows/package-manager/winget/export.md",
    "content": "---\r\ntitle: export Command\r\ndescription: exports the list of installed applications.\r\nms.date: 05/02/2021\r\nms.topic: overview\r\nms.localizationpriority: medium\r\n---\r\n\r\n# export command (winget)\r\n\r\nThe **export** command of the [winget](index.md) tool exports a JSON file of apps to a specified file.  The **export** command users JSON as the format.  See [the JSON schema used by **winget**](https://aka.ms/winget-packages.schema.1.0.json).\r\n\r\nThe **export** combined with the [**import**](import.md) command allows you to batch install applications on your PC.\r\n\r\nThe **export** command is often used to create a file that you can share with other developers, or for use when restoring your build environment.\r\n\r\n## Usage\r\n\r\n`winget export [-o] <output> [<options>]`\r\n\r\n![export](images/export.png)\r\n\r\n## Arguments\r\n\r\nThe following arguments are available.\r\n| Argument    | Description |\r\n|-------------|-------------|\r\n| **-o,--output** | Path to the JSON file to be created\r\n\r\n## Options\r\n\r\nThe options allow you to customize the export experience to meet your needs.\r\n\r\n| Option | Description |\r\n|--------|-------------|\r\n| **-s, --source**  |  [optional] Specifies a source to export files from.  Use this option when you only want files from a specific source.  |\r\n| **--include-versions** | [optional] Includes the version of the app currently installed.  Use this option if you want a specific version.  By default, unless specified, [**import**](import.md) will use latest. |\r\n| **--accept-source-agreements**  | Accept all source agreements during source operations |\r\n| **-?, --help** | Shows help about the selected command |\r\n| **--wait** | Prompts the user to press any key before exiting |\r\n| **--logs, --open-logs** | Open the default logs location |\r\n| **--verbose, --verbose-logs** | Enables verbose logging for winget |\r\n| **--disable-interactivity** | Disable interactive prompts |\r\n\r\n## JSON Schema\r\nThe driving force behind the **export** command is the JSON file.  As mentioned, you can see the [schema for the JSON file](https://aka.ms/winget-packages.schema.1.0.json).\r\n\r\nThe JSON file includes the following hierarchy:\r\n| Entry | Description |\r\n|-------------|-------------|\r\n| **Sources**  |  The sources application manifests come from.  |\r\n| **Packages**  |  The collection of packages to install.  |\r\n| **PackageIdentifier**  |  The Windows Package Manager package identifier used to specify the package.  |\r\n| **Version**  |  [Optional] The specific version of the package to install.  |\r\n\r\n## exporting files\r\n\r\nWhen the Windows Package Manager exports the JSON file, it attempts to export all the applications installed on the PC. If the **winget export** command is not able to match an application to an application from an available **source**, the export command will show a warning.\r\n\r\nNote: matching an application depends on metadata in the manifest from a configured source, and metadata in Add / Remove Programs in Windows based on the package installer.\r\n\r\nIn the example below, you will see warnings for **WhatsApp Desktop** and **7-Zip**.\r\n\r\n![export](images/export-command.png)\r\n\r\nOnce the export is complete, you can edit the resulting JSON file in your favorite editor. You can remove apps you do not wish to import in the future.\r\n\r\n## Related topics\r\n\r\n* [Use the winget tool to install and manage applications](index.md)\r\n\r\n"
  },
  {
    "path": "doc/windows/package-manager/winget/features.md",
    "content": "---\ntitle: features Command\ndescription: Displays the list of experimental features available and the state.\nms.date: 05/5/2021\nms.topic: overview\nms.localizationpriority: medium\n---\n\n# features command (winget)\n\nThe **features** command of the [winget](index.md) tool displays a list of the experimental features available with your version of the Windows Package Manager.\n\nEach feature can be turned on individually by enabling the features through [**settings**](settings.md).\n\nYou can find the latest up to date information on the [experimental features](../../../Settings.md#experimental-features) web page.\n\n## Usage\n\n![features command](images/features.png)\n\nNotice above that the status of each feature is listed.  If the feature is **disabled** you will not be able to use it.  If the feature is **enabled** you will notice that the command will be available to you through winget.\n\nTo enabled any disabled features, go to **settings** and enable the feature.\n\nNote: features may be managed by group policy. You can use the **winget --info** command to view any policies in effect on your system.\n"
  },
  {
    "path": "doc/windows/package-manager/winget/hash.md",
    "content": "---\ntitle: winget hash command\ndescription: Generates the SHA256 hash for an installer.\nms.date: 04/28/2020\nms.topic: article\nms.localizationpriority: medium\n---\n\n# hash command (winget)\n\nThe **hash** command of the [winget](index.md) tool generates the SHA256 hash for an installer. This command is used if you need to create a [manifest file](../package/manifest.md) for submitting software to the **Microsoft Community Package Manifest Repository** on GitHub. In addition, the **hash** command also supports generating a SHA256 certificate hash for MSIX files.\n\n## Usage\n\n`winget hash [--file] <file> [<options>]`\n\n![hash](images/hash.png)\n\nThe **hash** sub-command can only run on a local file. To use the **hash** sub-command, download your installer to a known location. Then pass in the file path as an argument to the **hash** sub-command.\n\n## Arguments\n\nThe following arguments are available:\n\n| Argument  | Description |\n|--------------|-------------|\n| **-f, --file** |  The path to the file to be hashed. |\n\n## Options\n\nThe following options are available:\n\n| Option | Description |\n|--------|-------------|\n| **-m, --msix**  | Specifies that the hash command will also create the SHA-256 SignatureSha256 for use with MSIX installers. |\n| **-?, --help** |  Gets additional help on this command. |\n| **--wait** | Prompts the user to press any key before exiting |\n| **--logs, --open-logs** | Open the default logs location |\n| **--verbose, --verbose-logs** | Enables verbose logging for winget |\n| **--disable-interactivity** | Disable interactive prompts |\n\n\n## Related topics\n\n* [Use the winget tool to install and manage applications](index.md)\n* [Submit packages to Windows Package Manager](../package/index.md)\n"
  },
  {
    "path": "doc/windows/package-manager/winget/help.md",
    "content": "---\ntitle: winget help Command\ndescription: Displays help for all the supported commands.\nms.date: 04/28/2020\nms.topic: article\nms.localizationpriority: medium\n---\n\n# help command (winget)\n\nThe **help** command of the [winget](index.md) tool displays help for all the supported commands and sub commands. In addition, you can pass the **--help** argument to any other command to get details about all additional command options.\n\n## Usage\n\n* Display help for all commands: `winget --help` or `winget -?`\n* View options for a command: `winget <command> --help` or `winget <command> -?`\n\n## Related topics\n\n* [Use the winget tool to install and manage applications](index.md)\n"
  },
  {
    "path": "doc/windows/package-manager/winget/import.md",
    "content": "---\r\ntitle: import Command\r\ndescription: imports the list of installed applications.\r\nms.date: 05/02/2021\r\nms.topic: overview\r\nms.localizationpriority: medium\r\n---\r\n\r\n# import command (winget)\r\n\r\nThe **import** command of the [winget](index.md) tool imports a JSON file of apps to install.  The **import** command combined with the [**export**](export.md) command allows you to batch install applications on your PC.\r\n\r\nThe **import** command is often used to share your developer environment or build up your PC image with your favorite apps.\r\n\r\n## Usage\r\n\r\n`winget import [-i] <import-file> [<options>]`\r\n\r\n![import](images/import.png)\r\n\r\n## Arguments\r\n\r\nThe following arguments are available.\r\n| Argument    | Description |\r\n|-------------|-------------|\r\n| **-i, --import-file** | JSON file describing the packages to install\r\n\r\n## Options\r\n\r\nThe options allow you to customize the import experience to meet your needs.\r\n\r\n| Option | Description |\r\n|-------------|-------------|\r\n| **--ignore-unavailable** | Suppresses errors if the app requested is unavailable |\r\n| **--ignore-versions** | Ignores versions specified in the JSON file and installs the latest available version |\r\n| **--no-upgrade** | Skips upgrade if an installed version already exists |\r\n| **--accept-package-agreements** | Accept all license agreements for packages |\r\n| **--accept-source-agreements** | Accept all source agreements during source operations |\r\n| **-?, --help** | Shows help about the selected command |\r\n| **--wait** | Prompts the user to press any key before exiting |\r\n| **--logs, --open-logs** | Open the default logs location |\r\n| **--verbose, --verbose-logs** | Enables verbose logging for winget |\r\n| **--disable-interactivity** | Disable interactive prompts |\r\n\r\n## JSON Schema\r\nThe driving force behind the **import** command is the JSON file.  You can see the [schema for the JSON file](https://aka.ms/winget-packages.schema.1.0.json).\r\n\r\nThe JSON file includes the following hierarchy:\r\n| Entry      | Description |\r\n|-------------|-------------|\r\n| **Sources**  |  The sources application manifests come from.  |\r\n| **Packages**  |  The collection of packages to install.  |\r\n| **PackageIdentifier**  |  The Windows Package Manager package identifier used to specify the package.  |\r\n| **Version**  |  [optional] The specific version of the package to install.  |\r\n\r\n## Importing files\r\n\r\nWhen the Windows Package Manager imports the JSON file, it attempts to install the specified applications in a serial fashion. If the application is not available or the application is already installed, it will notify the user of that case.\r\n\r\n![import](images/import-command.png)\r\n\r\nYou will notice in the example above, **Microsoft.VisualStudioCode** and **JanDeDobbeleer.OhMyPosh** were already installed. Therefore the import command skipped the installation.\r\n"
  },
  {
    "path": "doc/windows/package-manager/winget/index.md",
    "content": "---\ntitle: Use the winget tool to install and manage applications\ndescription: The winget command line tool enables developers to discover, install, upgrade, remove and configure applications on Windows 10 computers.\nms.date: 10/22/2020\nms.topic: overview\nms.localizationpriority: medium\n---\n\n# Use the winget tool to install and manage applications\n\nThe **winget** command line tool enables users to discover, install, upgrade, remove and configure applications on Windows 10 and Windows 11 computers. This tool is the client interface to the Windows Package Manager service.\n\n## Install winget\n\nThere are several ways to install the **winget** tool:\n\n* The **winget** tool is included in the flight or preview version of [Windows App Installer](https://apps.microsoft.com/detail/9nblggh4nns1?ocid=9nblggh4nns1_ORSEARCH_Bing&rtc=1&activetab=pivot:overviewtab). You must install the preview version of **App Installer** to use **winget**. To gain early access, submit your request to the [Windows Package Manager Insiders Program](https://aka.ms/AppInstaller_InsiderProgram). Participating in the flight ring will guarantee you see the latest preview updates.\n\n* Participate in the [Windows Insider Dev Channel](https://insider.windows.com/understand-flighting).\n\n* Install the Windows Desktop App Installer package located on the [Releases page for the winget repository](https://github.com/microsoft/winget-cli/releases).\n\n> The **winget** tool is supported on Windows 10, version 1809 (build 17763) and above.\n\n## Administrator considerations\n\nInstaller behavior can be different depending on whether you are running **winget** with administrator privileges.\n\n* When running **winget** without administrator privileges, some applications may [require elevation](https://docs.microsoft.com/windows/security/identity-protection/user-account-control/how-user-account-control-works) to install. When the installer runs, Windows will prompt you to [elevate](https://docs.microsoft.com/windows/security/identity-protection/user-account-control/how-user-account-control-works). If you choose not to elevate, the application will fail to install.\n\n* When running **winget** in an Administrator Command Prompt, you will not see [elevation prompts](https://docs.microsoft.com/windows/security/identity-protection/user-account-control/how-user-account-control-works) if the application requires it. Always use caution when running your command prompt as an administrator, and only install applications you trust.\n\n## Use winget\n\nAfter **App Installer** is installed, you can run **winget** by typing 'winget' from a Command Prompt.\n\nOne of the most common usage scenarios is to search for and install a favorite tool.\n\n1. To [search](search.md) for a tool, type `winget search <appname>`.\n2. After you have confirmed that the tool you want is available, you can [install](install.md) the tool by typing `winget install <appname>`. The **winget** tool will launch the installer and install the application on your PC.\n    ![winget commandline](images/install.png)\n3. In addition to install and search, **winget** provides a number of other commands that enable you to [show details](show.md) on applications, [change sources](source.md), and [validate packages](validate.md). To get a complete list of commands, type: `winget --help`.\n    ![winget help](images/help.png)\n\n### Commands\n\nThe current preview of the **winget** tool supports the following commands.\n| Command | Description |\n|---------|-------------|\n| [install](install.md) | Installs the specified application. |\n| [show](show.md) | Displays details for the specified application. |\n| [source](source.md) | Adds, removes, and updates the Windows Package Manager repositories accessed by the **winget** tool. |\n| [search](search.md) | Searches for an application. |\n| [list](list.md) | Display installed packages. |\n| [upgrade](upgrade.md) |  Upgrades the given package. |\n| [uninstall](uninstall.md) | Uninstalls the given package. |\n| [hash](hash.md) | Generates the SHA256 hash for the installer. |\n| [validate](validate.md) | Validates a manifest file for submission to the Windows Package Manager repository. |\n| [settings](settings.md) | Open settings. |\n| [features](features.md) | Shows the status of experimental features. |\n| [export](export.md) | Exports a list of the installed packages. |\n| [import](import.md) | Installs all the packages in a file. |\n| pin | Manage package pins. |\n| configure | Configures the system into a desired state. |\n| download | Downloads the installer from a given package. |\n\n### Options\n\nThe current version of the **winget** tool supports the following options.\n\n| Option | Description |\n|--------------|-------------|\n| **-v, --version** | Returns the current version of winget. |\n| **--info** |  Provides you with all detailed information on winget, including the links to the license, privacy statement, and configured group policies. |\n| **-?, --help** |  Shows additional help for winget. |\n| **--wait** | Waits for user input upon command completion. |\n| **--logs,--open-logs** | Open the default logs location |\n| **--verbose,--verbose-logs** | Enables verbose logging for winget |\n| **--disable-interactivity** | Disable interactive prompts |\n\n## Supported installer formats\n\nThe current version of the **winget** tool supports the following types of installers:\n\n* EXE (with **Silent** and **SilentWithProgress** flags)\n* INNO\n* NULLSOFT\n* MSI\n* APPX\n* MSIX\n* BURN\n* PORTABLE\n* ZIP\n\n## Scripting winget\n\nYou can author batch scripts and PowerShell scripts to install multiple applications.\n\n```CMD\n@echo off\nEcho Install Powertoys and Terminal\nREM Powertoys\nwinget install Microsoft.Powertoys\nif %ERRORLEVEL% EQU 0 Echo Powertoys installed successfully.\nREM Terminal\nwinget install Microsoft.WindowsTerminal\nif %ERRORLEVEL% EQU 0 Echo Terminal installed successfully. %ERRORLEVEL%\n```\n\n> When scripted, **winget** will launch the applications in the specified order. When an installer returns success or failure, **winget** will launch the next installer. If an installer launches another process, it is possible that it will return to **winget** prematurely. This will cause **winget** to install the next installer before the previous installer has completed.\n\n## Missing tools\n\nIf the [community repository](../package/repository.md) does not include your tool or application, please submit a package to our [repository](https://github.com/microsoft/winget-pkgs). By adding your favorite tool, it will be available to you and everyone else.\n\n## Customize winget settings\n\nYou can configure the **winget** command line experience by modifying the **settings.json** file. For more information, see [https://aka.ms/winget-settings](https://aka.ms/winget-settings). Note that the settings are still in an experimental state and not yet finalized for the preview version of the tool.\n\n## Open source details\n\nThe **winget** tool is open source software available on GitHub in the repo [https://github.com/microsoft/winget-cli/](https://github.com/microsoft/winget-cli/). The source for building the client is located in the [src folder](https://github.com/microsoft/winget-cli/tree/master/src).\n\nThe source for **winget** is contained in a Visual Studio solution. To build the solution correctly, install the latest [Visual Studio with the C++ workload](https://visualstudio.microsoft.com/downloads/).\n\nWe encourage you to contribute to the **winget** source on GitHub. You must first agree to and sign the Microsoft CLA.\n"
  },
  {
    "path": "doc/windows/package-manager/winget/install.md",
    "content": "---\ntitle: install Command\ndescription: Installs the specified application.\nms.date: 04/28/2020\nms.topic: overview\nms.localizationpriority: medium\n---\n\n# install command (winget)\n\nThe **install** command of the [winget](index.md) tool installs the specified application. Use the [**search**](search.md) command to identify the application you want to install.\n\nThe **install** command requires that you specify the exact string to install. If there is any ambiguity, you will be prompted to further filter the **install** command to  an exact application.\n\n## Usage\n\n`winget install [[-q] <query>] [<options>]`\n\nThe following command aliases are available: \\\n`add`\n\n![search command](images/install.png)\n\n## Arguments\n\nThe following arguments are available.\n\n| Argument | Description |\n|-------------|-------------|\n| **-q, --query** | The query used to search for an app. |\n\n## Options\n\nThe options allow you to customize the install experience to meet your needs.\n\n| Option | Description |\n|-------------|-------------|\n| **-m, --manifest** | Must be followed by the path to the manifest (YAML) file. You can use the manifest to run the install experience from a [local YAML file](#local-install). |\n| **--id** | Limits the install to the ID of the application. |\n| **--name** | Limits the search to the name of the application. |\n| **--moniker** | Limits the search to the moniker listed for the application. |\n| **-v, --version** | Enables you to specify an exact version to install. If not specified, latest will install the highest versioned application. |\n| **-s, --source** | Restricts the search to the source name provided. Must be followed by the source name. |\n| **--scope** | Select install scope (user or machine) |\n| **-e, --exact** | Uses the exact string in the query, including checking for case-sensitivity. It will not use the default behavior of a substring. |\n| **-i, --interactive** | Runs the installer in interactive mode. The default experience shows installer progress. |\n| **-h, --silent** | Runs the installer in silent mode. This suppresses all UI. The default experience shows installer progress. |\n| **-o, --log** | Directs the logging to a log file. You must provide a path to a file that you have the write rights to. |\n| **--override** | A string that will be passed directly to the installer. |\n| **-l, --location** | Location to install to (if supported). |\n| **--force** | Override the installer hash check. |\n| **-a, --architecture** | Select the architecture |\n| **--installer-type** | Select the installer type |\n| **--locale** | Locale to use (BCP47 format) |\n| **--custom** | Arguments to be passed on to the installer in addition to the defaults |\n| **--ignore-security-hash** | Ignore the installer hash check failure |\n| **--skip-dependencies** | Skip processing package dependencies and Windows features |\n| **--ignore-local-archive-malware-scan** | Ignore the malware scan performed as part of installing an archive-type package from a local manifest |\n| **--dependency-source** | Find package dependencies using the specified source |\n| **--accept-package-agreements** | Accept all license agreements for packages |\n| **--no-upgrade** | Skip upgrade if an installed version already exists |\n| **--header** | Optional Windows-Package-Manager REST source HTTP header |\n| **--accept-source-agreements** | Accept all source agreements during source operations |\n| **-r, --rename** | The value to rename the executable file (portable) |\n| **--uninstall-previous** | Uninstall the previous version of the package during the upgrade |\n| **--ignore-interactivity** | Disable interactive prompts |\n| **-?, --help** | Get additional help on this command. |\n| **--wait** | Prompts the user to press any key before exiting |\n| **--logs, --open-logs** | Open the default logs location |\n| **--verbose, --verbose-logs** | Enables verbose logging for winget |\n| **--disable-interactivity** | Disable interactive prompts |\n\n### Example queries\n\nThe following example installs a specific version of an application.\n\n```CMD\nwinget install powertoys --version 0.15.2\n```\n\nThe following example installs an application from its **Package Identifier**.\n\n```CMD\nwinget install --id Microsoft.PowerToys\n```\n\nThe following example installs an application by version and ID.\n\n```CMD\nwinget install --id Microsoft.PowerToys --version 0.15.2\n```\n\n## Multiple selections\n\nIf the query provided to **winget** does not result in a single application, then **winget** will display the results of the search. This will provide you with the additional data necessary to refine the search for a correct install.\n\nThe best way to limit the selection to one file is to use the **id** of the application combined with the **exact** query option.  For example:\n\n```CMD\nwinget install --id Git.Git -e\n```\n\nIf multiple sources are configured, it is possible to have duplicate entries. Specifying a source is required to further disambiguate.\n\n```CMD\nwinget install --id Git.Git -e --source winget\n```\n\n## Local install\n\nThe **manifest** option enables you to install an application by passing in a YAML file directly to the client. If the manifest is a multi file manifest, the directory containing the files must be used. The **manifest** option has the following usage.\n\nUsage: `winget install --manifest <path>`\n\n| Option  | Description |\n|---------|-------------|\n| **-m, --manifest** | The path to the manifest of the application to install. |\n\n### Log files\n\nThe log files for winget unless redirected, will be located in the following folder:  **\\%temp%\\\\AICLI\\\\*.log**\n\n## Related topics\n\n* [Use the winget tool to install and manage applications](index.md)\n"
  },
  {
    "path": "doc/windows/package-manager/winget/list.md",
    "content": "---\ntitle: features Command\ndescription: Displays the list of listed apps and if an update is available.\nms.date: 05/5/2021\nms.topic: overview\nms.localizationpriority: medium\n---\n\n# list command (winget)\n\nThe **list** command of the [winget](index.md) tool displays a list of the applications currently installed on your computer.  The list command will show apps that were installed through the Windows Package Manager as well as apps that were installed by other means.\n\nIn addition, the **list** command will also display if an update is available for an app, and you can use the [**upgrade**](upgrade.md) command to update the app.\n\nThe **list** command also supports filters which can be used to limit your list query.\n\n## Usage\n\n`winget list [[-q] <query>] [<options>]`\n\nThe following command aliases are available: \\\n`ls`\n\n![list help command](images/list.png)\n\n## Arguments\n\nThe following arguments are available.\n\n| Argument | Description |\n|-------------|-------------|\n| **-q,--query** | The query used to search for an app. |\n\n## Options\n\nThe options allow you to customize the list experience to meet your needs.\n| Option | Description |\n|--------|-------------|\n| **--id** | Limits the list to the ID of the application. |\n| **--name** | Limits the list to the name of the application. |\n| **--moniker** | Limits the list to the moniker listed for the application. |\n| **-s, --source** | Restricts the list to the source name provided. Must be followed by the source name. |\n| **--tag** | Filters results by tags. |\n| **--command** | Filters results by command specified by the application. |\n| **-n, --count** | Limits the number of apps displayed in one query. |\n| **-e, --exact** | Uses the exact string in the list query, including checking for case-sensitivity. It will not use the default behavior of a substring. |\n| **--scope** | Select installed package scope filter (user or machine). |\n| **--header** | Optional Windows-Package-Manager REST source HTTP header. |\n| **--accept-source-agreements** | Accept all source agreements during source operations. |\n| **--upgrade-available** | Lists only packages which have an upgrade available. |\n| **-u,--unknown,--include-unknown** | List packages even if their current version cannot be determined. Can only be used with the --upgrade-available argument. |\n| **--pinned,--include-pinned** | List packages even if they have a pin that prevents upgrade. Can only be used with the --upgrade-available argument. |\n| **-?,--help** | Get additional help on this command. |\n| **--wait** | Prompts the user to press any key before exiting. |\n| **--logs,--open-logs** | Open the default logs location. |\n| **--verbose,--verbose-logs** | Enables verbose logging for winget. |\n| **--disable-interactivity** | Disable interactive prompts. |\n\n### Example queries\n\nThe following example lists a specific version of an application.\n\n![list name command](images/list-name.png)\n\nThe following example lists all application by ID from a specific source.\n\n![list id with source command](images/list-id-source.png)\n\nThe following example limits the output of list to 9 apps.\n\n![list count command](images/list-count.png)\n\n## List with Update\n\nAs stated above, the **list** command allows you to see what apps you have installed that have updates available.\n\nIn the image below, you will notice the current version of **Google Chrome** has an update available.\n\n![list update command](images/list-update.png)\n\nThe **list** command will show not only the update version available, but the source that the update is available from.\n\n## Related topics\n\n* [Use the winget tool to install and manage applications](index.md)\n"
  },
  {
    "path": "doc/windows/package-manager/winget/returnCodes.md",
    "content": "---\ntitle: Exit Codes\ndescription: WinGet return codes and their meanings\nms.date: 05/02/2023\nms.topic: article\nms.localizationpriority: medium\n---\n\n# Return Codes\n\n## General Errors\n\n| Hex | Decimal | Symbol | Description |\n|-------------|-------------|-------------|-------------|\n| 0x8A150001 | -1978335231 | APPINSTALLER_CLI_ERROR_INTERNAL_ERROR | Internal Error |\n| 0x8A150002 | -1978335230 | APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS | Invalid command line arguments |\n| 0x8A150003 | -1978335229 | APPINSTALLER_CLI_ERROR_COMMAND_FAILED | Executing command failed |\n| 0x8A150004 | -1978335228 | APPINSTALLER_CLI_ERROR_MANIFEST_FAILED | Opening manifest failed |\n| 0x8A150005 | -1978335227 | APPINSTALLER_CLI_ERROR_CTRL_SIGNAL_RECEIVED | Cancellation signal received |\n| 0x8A150006 | -1978335226 | APPINSTALLER_CLI_ERROR_SHELLEXEC_INSTALL_FAILED | Running ShellExecute failed |\n| 0x8A150007 | -1978335225 | APPINSTALLER_CLI_ERROR_UNSUPPORTED_MANIFESTVERSION | Cannot process manifest. The manifest version is higher than supported. Please update the client. |\n| 0x8A150008 | -1978335224 | APPINSTALLER_CLI_ERROR_DOWNLOAD_FAILED | Downloading installer failed |\n| 0x8A150009 | -1978335223 | APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX | Cannot write to index; it is a higher schema version |\n| 0x8A15000A | -1978335222 | APPINSTALLER_CLI_ERROR_INDEX_INTEGRITY_COMPROMISED | The index is corrupt |\n| 0x8A15000B | -1978335221 | APPINSTALLER_CLI_ERROR_SOURCES_INVALID | The configured source information is corrupt |\n| 0x8A15000C | -1978335220 | APPINSTALLER_CLI_ERROR_SOURCE_NAME_ALREADY_EXISTS | The source name is already configured |\n| 0x8A15000D | -1978335219 | APPINSTALLER_CLI_ERROR_INVALID_SOURCE_TYPE | The source type is invalid |\n| 0x8A15000E | -1978335218 | APPINSTALLER_CLI_ERROR_PACKAGE_IS_BUNDLE | The MSIX file is a bundle, not a package |\n| 0x8A15000F | -1978335217 | APPINSTALLER_CLI_ERROR_SOURCE_DATA_MISSING | Data required by the source is missing |\n| 0x8A150010 | -1978335216 | APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER | None of the installers are applicable for the current system |\n| 0x8A150011 | -1978335215 | APPINSTALLER_CLI_ERROR_INSTALLER_HASH_MISMATCH | The installer file's hash does not match the manifest |\n| 0x8A150012 | -1978335214 | APPINSTALLER_CLI_ERROR_SOURCE_NAME_DOES_NOT_EXIST | The source name does not exist |\n| 0x8A150013 | -1978335213 | APPINSTALLER_CLI_ERROR_SOURCE_ARG_ALREADY_EXISTS | The source location is already configured under another name |\n| 0x8A150014 | -1978335212 | APPINSTALLER_CLI_ERROR_NO_APPLICATIONS_FOUND | No packages found |\n| 0x8A150015 | -1978335211 | APPINSTALLER_CLI_ERROR_NO_SOURCES_DEFINED | No sources are configured |\n| 0x8A150016 | -1978335210 | APPINSTALLER_CLI_ERROR_MULTIPLE_APPLICATIONS_FOUND | Multiple packages found matching the criteria |\n| 0x8A150017 | -1978335209 | APPINSTALLER_CLI_ERROR_NO_MANIFEST_FOUND | No manifest found matching the criteria |\n| 0x8A150018 | -1978335208 | APPINSTALLER_CLI_ERROR_EXTENSION_PUBLIC_FAILED | Failed to get Public folder from source package |\n| 0x8A150019 | -1978335207 | APPINSTALLER_CLI_ERROR_COMMAND_REQUIRES_ADMIN | Command requires administrator privileges to run |\n| 0x8A15001A | -1978335206 | APPINSTALLER_CLI_ERROR_SOURCE_NOT_SECURE | The source location is not secure |\n| 0x8A15001B | -1978335205 | APPINSTALLER_CLI_ERROR_MSSTORE_BLOCKED_BY_POLICY | The Microsoft Store client is blocked by policy |\n| 0x8A15001C | -1978335204 | APPINSTALLER_CLI_ERROR_MSSTORE_APP_BLOCKED_BY_POLICY | The Microsoft Store app is blocked by policy |\n| 0x8A15001D | -1978335203 | APPINSTALLER_CLI_ERROR_EXPERIMENTAL_FEATURE_DISABLED | The feature is currently under development. It can be enabled using winget settings. |\n| 0x8A15001E | -1978335202 | APPINSTALLER_CLI_ERROR_MSSTORE_INSTALL_FAILED | Failed to install the Microsoft Store app |\n| 0x8A15001F | -1978335201 | APPINSTALLER_CLI_ERROR_COMPLETE_INPUT_BAD | Failed to perform auto complete |\n| 0x8A150020 | -1978335200 | APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED | Failed to initialize YAML parser |\n| 0x8A150021 | -1978335199 | APPINSTALLER_CLI_ERROR_YAML_INVALID_MAPPING_KEY | Encountered an invalid YAML key |\n| 0x8A150022 | -1978335198 | APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY | Encountered a duplicate YAML key |\n| 0x8A150023 | -1978335197 | APPINSTALLER_CLI_ERROR_YAML_INVALID_OPERATION | Invalid YAML operation |\n| 0x8A150024 | -1978335196 | APPINSTALLER_CLI_ERROR_YAML_DOC_BUILD_FAILED | Failed to build YAML doc |\n| 0x8A150025 | -1978335195 | APPINSTALLER_CLI_ERROR_YAML_INVALID_EMITTER_STATE | Invalid YAML emitter state |\n| 0x8A150026 | -1978335194 | APPINSTALLER_CLI_ERROR_YAML_INVALID_DATA | Invalid YAML data |\n| 0x8A150027 | -1978335193 | APPINSTALLER_CLI_ERROR_LIBYAML_ERROR | LibYAML error |\n| 0x8A150028 | -1978335192 | APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_WARNING | Manifest validation succeeded with warning |\n| 0x8A150029 | -1978335191 | APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_FAILURE | Manifest validation failed |\n| 0x8A15002A | -1978335190 | APPINSTALLER_CLI_ERROR_INVALID_MANIFEST | Manifest is invalid |\n| 0x8A15002B | -1978335189 | APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE | No applicable update found |\n| 0x8A15002C | -1978335188 | APPINSTALLER_CLI_ERROR_UPDATE_ALL_HAS_FAILURE | winget upgrade --all completed with failures |\n| 0x8A15002D | -1978335187 | APPINSTALLER_CLI_ERROR_INSTALLER_SECURITY_CHECK_FAILED | Installer failed security check |\n| 0x8A15002E | -1978335186 | APPINSTALLER_CLI_ERROR_DOWNLOAD_SIZE_MISMATCH | Download size does not match expected content length |\n| 0x8A15002F | -1978335185 | APPINSTALLER_CLI_ERROR_NO_UNINSTALL_INFO_FOUND | Uninstall command not found |\n| 0x8A150030 | -1978335184 | APPINSTALLER_CLI_ERROR_EXEC_UNINSTALL_COMMAND_FAILED | Running uninstall command failed |\n| 0x8A150031 | -1978335183 | APPINSTALLER_CLI_ERROR_ICU_BREAK_ITERATOR_ERROR | ICU break iterator error |\n| 0x8A150032 | -1978335182 | APPINSTALLER_CLI_ERROR_ICU_CASEMAP_ERROR | ICU casemap error |\n| 0x8A150033 | -1978335181 | APPINSTALLER_CLI_ERROR_ICU_REGEX_ERROR | ICU regex error |\n| 0x8A150034 | -1978335180 | APPINSTALLER_CLI_ERROR_IMPORT_INSTALL_FAILED | Failed to install one or more imported packages |\n| 0x8A150035 | -1978335179 | APPINSTALLER_CLI_ERROR_NOT_ALL_PACKAGES_FOUND | Could not find one or more requested packages |\n| 0x8A150036 | -1978335178 | APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE | Json file is invalid |\n| 0x8A150037 | -1978335177 | APPINSTALLER_CLI_ERROR_SOURCE_NOT_REMOTE | The source location is not remote |\n| 0x8A150038 | -1978335176 | APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE | The configured rest source is not supported |\n| 0x8A150039 | -1978335175 | APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA | Invalid data returned by rest source |\n| 0x8A15003A | -1978335174 | APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY | Operation is blocked by Group Policy |\n| 0x8A15003B | -1978335173 | APPINSTALLER_CLI_ERROR_RESTAPI_INTERNAL_ERROR | Rest API internal error |\n| 0x8A15003C | -1978335172 | APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_URL | Invalid rest source url |\n| 0x8A15003D | -1978335171 | APPINSTALLER_CLI_ERROR_RESTAPI_UNSUPPORTED_MIME_TYPE | Unsupported MIME type returned by rest API |\n| 0x8A15003E | -1978335170 | APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_VERSION | Invalid rest source contract version |\n| 0x8A15003F | -1978335169 | APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE | The source data is corrupted or tampered |\n| 0x8A150040 | -1978335168 | APPINSTALLER_CLI_ERROR_STREAM_READ_FAILURE | Error reading from the stream |\n| 0x8A150041 | -1978335167 | APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED | Package agreements were not agreed to |\n| 0x8A150042 | -1978335166 | APPINSTALLER_CLI_ERROR_PROMPT_INPUT_ERROR | Error reading input in prompt |\n| 0x8A150043 | -1978335165 | APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST | The search request is not supported by one or more sources |\n| 0x8A150044 | -1978335164 | APPINSTALLER_CLI_ERROR_RESTAPI_ENDPOINT_NOT_FOUND | The rest API endpoint is not found. |\n| 0x8A150045 | -1978335163 | APPINSTALLER_CLI_ERROR_SOURCE_OPEN_FAILED | Failed to open the source. |\n| 0x8A150046 | -1978335162 | APPINSTALLER_CLI_ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED | Source agreements were not agreed to |\n| 0x8A150047 | -1978335161 | APPINSTALLER_CLI_ERROR_CUSTOMHEADER_EXCEEDS_MAXLENGTH | Header size exceeds the allowable limit of 1024 characters. Please reduce the size and try again. |\n| 0x8A150048 | -1978335160 | APPINSTALLER_CLI_ERROR_MISSING_RESOURCE_FILE | Missing resource file |\n| 0x8A150049 | -1978335159 | APPINSTALLER_CLI_ERROR_MSI_INSTALL_FAILED | Running MSI install failed |\n| 0x8A15004A | -1978335158 | APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT | Arguments for msiexec are invalid |\n| 0x8A15004B | -1978335157 | APPINSTALLER_CLI_ERROR_FAILED_TO_OPEN_ALL_SOURCES | Failed to open one or more sources |\n| 0x8A15004C | -1978335156 | APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED | Failed to validate dependencies |\n| 0x8A15004D | -1978335155 | APPINSTALLER_CLI_ERROR_MISSING_PACKAGE | One or more package is missing |\n| 0x8A15004E | -1978335154 | APPINSTALLER_CLI_ERROR_INVALID_TABLE_COLUMN | Invalid table column |\n| 0x8A15004F | -1978335153 | APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_NOT_NEWER | The upgrade version is not newer than the installed version |\n| 0x8A150050 | -1978335152 | APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_UNKNOWN | Upgrade version is unknown and override is not specified |\n| 0x8A150051 | -1978335151 | APPINSTALLER_CLI_ERROR_ICU_CONVERSION_ERROR | ICU conversion error |\n| 0x8A150052 | -1978335150 | APPINSTALLER_CLI_ERROR_PORTABLE_INSTALL_FAILED | Failed to install portable package |\n| 0x8A150053 | -1978335149 | APPINSTALLER_CLI_ERROR_PORTABLE_REPARSE_POINT_NOT_SUPPORTED | Volume does not support reparse points. |\n| 0x8A150054 | -1978335148 | APPINSTALLER_CLI_ERROR_PORTABLE_PACKAGE_ALREADY_EXISTS | Portable package from a different source already exists. |\n| 0x8A150055 | -1978335147 | APPINSTALLER_CLI_ERROR_PORTABLE_SYMLINK_PATH_IS_DIRECTORY | Unable to create symlink, path points to a directory. |\n| 0x8A150056 | -1978335146 | APPINSTALLER_CLI_ERROR_INSTALLER_PROHIBITS_ELEVATION | The installer cannot be run from an administrator context. |\n| 0x8A150057 | -1978335145 | APPINSTALLER_CLI_ERROR_PORTABLE_UNINSTALL_FAILED | Failed to uninstall portable package |\n| 0x8A150058 | -1978335144 | APPINSTALLER_CLI_ERROR_ARP_VERSION_VALIDATION_FAILED | Failed to validate DisplayVersion values against index. |\n| 0x8A150059 | -1978335143 | APPINSTALLER_CLI_ERROR_UNSUPPORTED_ARGUMENT | One or more arguments are not supported. |\n| 0x8A15005A | -1978335142 | APPINSTALLER_CLI_ERROR_BIND_WITH_EMBEDDED_NULL | Embedded null characters are disallowed for SQLite |\n| 0x8A15005B | -1978335141 | APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_NOT_FOUND | Failed to find the nested installer in the archive. |\n| 0x8A15005C | -1978335140 | APPINSTALLER_CLI_ERROR_EXTRACT_ARCHIVE_FAILED | Failed to extract archive. |\n| 0x8A15005D | -1978335139 | APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_INVALID_PATH | Invalid relative file path to nested installer provided. |\n| 0x8A15005E | -1978335138 | APPINSTALLER_CLI_ERROR_PINNED_CERTIFICATE_MISMATCH | The server certificate did not match any of the expected values. |\n| 0x8A15005F | -1978335137 | APPINSTALLER_CLI_ERROR_INSTALL_LOCATION_REQUIRED | Install location must be provided. |\n| 0x8A150060 | -1978335136 | APPINSTALLER_CLI_ERROR_ARCHIVE_SCAN_FAILED | Archive malware scan failed. |\n| 0x8A150061 | -1978335135 | APPINSTALLER_CLI_ERROR_PACKAGE_ALREADY_INSTALLED | Found at least one version of the package installed. |\n| 0x8A150062 | -1978335134 | APPINSTALLER_CLI_ERROR_PIN_ALREADY_EXISTS | A pin already exists for the package. |\n| 0x8A150063 | -1978335133 | APPINSTALLER_CLI_ERROR_PIN_DOES_NOT_EXIST | There is no pin for the package. |\n| 0x8A150064 | -1978335132 | APPINSTALLER_CLI_ERROR_CANNOT_OPEN_PINNING_INDEX | Unable to open the pin database. |\n| 0x8A150065 | -1978335131 | APPINSTALLER_CLI_ERROR_MULTIPLE_INSTALL_FAILED | One or more applications failed to install |\n| 0x8A150066 | -1978335130 | APPINSTALLER_CLI_ERROR_MULTIPLE_UNINSTALL_FAILED | One or more applications failed to uninstall |\n| 0x8A150067 | -1978335129 | APPINSTALLER_CLI_ERROR_NOT_ALL_QUERIES_FOUND_SINGLE | One or more queries did not return exactly one match |\n| 0x8A150068 | -1978335128 | APPINSTALLER_CLI_ERROR_PACKAGE_IS_PINNED | The package has a pin that prevents upgrade. |\n| 0x8A150069 | -1978335127 | APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB | The package currently installed is the stub package |\n| 0x8A15006A | -1978335126 | APPINSTALLER_CLI_ERROR_APPTERMINATION_RECEIVED | Application shutdown signal received |\n| 0x8A15006B | -1978335125 | APPINSTALLER_CLI_ERROR_DOWNLOAD_DEPENDENCIES | Failed to download package dependencies. |\n| 0x8A15006C | -1978335124 | APPINSTALLER_CLI_ERROR_DOWNLOAD_COMMAND_PROHIBITED | Failed to download package. Download for offline installation is prohibited. |\n| 0x8A15006D | -1978335123 | APPINSTALLER_CLI_ERROR_SERVICE_UNAVAILABLE | A required service is busy or unavailable. Try again later. |\n| 0x8A15006E | -1978335122 | APPINSTALLER_CLI_ERROR_RESUME_ID_NOT_FOUND | The guid provided does not correspond to a valid resume state. |\n| 0x8A15006F | -1978335121 | APPINSTALLER_CLI_ERROR_CLIENT_VERSION_MISMATCH | The current client version did not match the client version of the saved state. |\n| 0x8A150070 | -1978335120 | APPINSTALLER_CLI_ERROR_INVALID_RESUME_STATE | The resume state data is invalid. |\n| 0x8A150071 | -1978335119 | APPINSTALLER_CLI_ERROR_CANNOT_OPEN_CHECKPOINT_INDEX | Unable to open the checkpoint database. |\n| 0x8A150072 | -1978335118 | APPINSTALLER_CLI_ERROR_RESUME_LIMIT_EXCEEDED | Exceeded max resume limit. |\n| 0x8A150073 | -1978335117 | APPINSTALLER_CLI_ERROR_INVALID_AUTHENTICATION_INFO | Invalid authentication info. |\n| 0x8A150074 | -1978335116 | APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED | Authentication method not supported. |\n| 0x8A150075 | -1978335115 | APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED | Authentication failed. |\n| 0x8A150076 | -1978335114 | APPINSTALLER_CLI_ERROR_AUTHENTICATION_INTERACTIVE_REQUIRED | Authentication failed. Interactive authentication required. |\n| 0x8A150077 | -1978335113 | APPINSTALLER_CLI_ERROR_AUTHENTICATION_CANCELLED_BY_USER | Authentication failed. User cancelled. |\n| 0x8A150078 | -1978335112 | APPINSTALLER_CLI_ERROR_AUTHENTICATION_INCORRECT_ACCOUNT | Authentication failed. Authenticated account is not the desired account. |\n| 0x8A150079 | -1978335111 | APPINSTALLER_CLI_ERROR_NO_REPAIR_INFO_FOUND | Repair command not found. |\n| 0x8A15007A | -1978335110 | APPINSTALLER_CLI_ERROR_REPAIR_NOT_APPLICABLE | Repair operation is not applicable. |\n| 0x8A15007B | -1978335109 | APPINSTALLER_CLI_ERROR_EXEC_REPAIR_FAILED | Repair operation failed. |\n| 0x8A15007C | -1978335108 | APPINSTALLER_CLI_ERROR_REPAIR_NOT_SUPPORTED | The installer technology in use doesn't support repair. |\n| 0x8A15007D | -1978335107 | APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED | Repair operations involving administrator privileges are not permitted on packages installed within the user scope. |\n| 0x8A15007E | -1978335106 | APPINSTALLER_CLI_ERROR_SQLITE_CONNECTION_TERMINATED | The SQLite connection was terminated to prevent corruption. |\n| 0x8A15007F | -1978335105 | APPINSTALLER_CLI_ERROR_DISPLAYCATALOG_API_FAILED | Failed to get Microsoft Store package catalog. |\n| 0x8A150080 | -1978335104 | APPINSTALLER_CLI_ERROR_NO_APPLICABLE_DISPLAYCATALOG_PACKAGE | No applicable Microsoft Store package found from Microsoft Store package catalog. |\n| 0x8A150081 | -1978335103 | APPINSTALLER_CLI_ERROR_SFSCLIENT_API_FAILED | Failed to get Microsoft Store package download information. |\n| 0x8A150082 | -1978335102 | APPINSTALLER_CLI_ERROR_NO_APPLICABLE_SFSCLIENT_PACKAGE | No applicable Microsoft Store package download information found. |\n| 0x8A150083 | -1978335101 | APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED | Failed to retrieve Microsoft Store package license. |\n| 0x8A150084 | -1978335100 | APPINSTALLER_CLI_ERROR_SFSCLIENT_PACKAGE_NOT_SUPPORTED | The Microsoft Store package does not support download command. |\n| 0x8A150085 | -1978335099 | APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED_FORBIDDEN | Failed to retrieve Microsoft Store package license. The Microsoft Entra Id account does not have required privilege. |\n| 0x8A150086 | -1978335098 | APPINSTALLER_CLI_ERROR_INSTALLER_ZERO_BYTE_FILE | Downloaded zero byte installer; ensure that your network connection is working properly. |\n| 0x8A150087 | -1979335097 | APPINSTALLER_CLI_ERROR_FONT_INSTALL_FAILED | Failed installing one or more fonts. |\n| 0x8A150088 | -1979335096 | APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_SUPPORTED | Font file is not supported and cannot be installed. |\n| 0x8A150089 | -1979335095 | APPINSTALLER_CLI_ERROR_FONT_ALREADY_INSTALLED | Font package is already installed. |\n| 0x8A15008A | -1979335094 | APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_FOUND | Font file not found. |\n| 0x8A15008B | -1979335093 | APPINSTALLER_CLI_ERROR_FONT_UNINSTALL_FAILED | Font uninstall failed. The font may not be in a good state. Try uninstalling after a restart. |\n| 0x8A15008C | -1979335092 | APPINSTALLER_CLI_ERROR_FONT_VALIDATION_FAILED | Font validation failed. |\n| 0x8A15008D | -1979335091 | APPINSTALLER_CLI_ERROR_FONT_ROLLBACK_FAILED | Font rollback failed. The font may not be in a good state. Try uninstalling after a restart. |\n\n## Install errors.\n\n| Hex | Decimal | Symbol | Description |\n|-------------|-------------|-------------|-------------|\n| 0x8A150101 | -1978334975 | APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE | Application is currently running. Exit the application then try again. |\n| 0x8A150102 | -1978334974 | APPINSTALLER_CLI_ERROR_INSTALL_INSTALL_IN_PROGRESS | Another installation is already in progress. Try again later. |\n| 0x8A150103 | -1978334973 | APPINSTALLER_CLI_ERROR_INSTALL_FILE_IN_USE | One or more file is being used. Exit the application then try again. |\n| 0x8A150104 | -1978334972 | APPINSTALLER_CLI_ERROR_INSTALL_MISSING_DEPENDENCY | This package has a dependency missing from your system. |\n| 0x8A150105 | -1978334971 | APPINSTALLER_CLI_ERROR_INSTALL_DISK_FULL | There's no more space on your PC. Make space, then try again. |\n| 0x8A150106 | -1978334970 | APPINSTALLER_CLI_ERROR_INSTALL_INSUFFICIENT_MEMORY | There's not enough memory available to install. Close other applications then try again. |\n| 0x8A150107 | -1978334969 | APPINSTALLER_CLI_ERROR_INSTALL_NO_NETWORK | This application requires internet connectivity. Connect to a network then try again. |\n| 0x8A150108 | -1978334968 | APPINSTALLER_CLI_ERROR_INSTALL_CONTACT_SUPPORT | This application encountered an error during installation. Contact support. |\n| 0x8A150109 | -1978334967 | APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_TO_FINISH | Restart your PC to finish installation. |\n| 0x8A15010A | -1978334966 | APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_TO_INSTALL | Installation failed. Restart your PC then try again. |\n| 0x8A15010B | -1978334965 | APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_INITIATED | Your PC will restart to finish installation. |\n| 0x8A15010C | -1978334964 | APPINSTALLER_CLI_ERROR_INSTALL_CANCELLED_BY_USER | You cancelled the installation. |\n| 0x8A15010D | -1978334963 | APPINSTALLER_CLI_ERROR_INSTALL_ALREADY_INSTALLED | Another version of this application is already installed. |\n| 0x8A15010E | -1978334962 | APPINSTALLER_CLI_ERROR_INSTALL_DOWNGRADE | A higher version of this application is already installed. |\n| 0x8A15010F | -1978334961 | APPINSTALLER_CLI_ERROR_INSTALL_BLOCKED_BY_POLICY | Organization policies are preventing installation. Contact your admin. |\n| 0x8A150110 | -1978334960 | APPINSTALLER_CLI_ERROR_INSTALL_DEPENDENCIES | Failed to install package dependencies. |\n| 0x8A150111 | -1978334959 | APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE_BY_APPLICATION | Application is currently in use by another application. |\n| 0x8A150112 | -1978334958 | APPINSTALLER_CLI_ERROR_INSTALL_INVALID_PARAMETER | Invalid parameter. |\n| 0x8A150113 | -1978334957 | APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED | Package not supported by the system. |\n| 0x8A150114 | -1978334956 | APPINSTALLER_CLI_ERROR_INSTALL_UPGRADE_NOT_SUPPORTED | The installer does not support upgrading an existing package. |\n| 0x8A150115 | -1978334955 | APPINSTALLER_CLI_ERROR_INSTALL_CUSTOM_ERROR | Installation failed with installer custom error. |\n\n## Check for package installed status\n\n| Hex | Decimal | Symbol | Description |\n|-------------|-------------|-------------|-------------|\n| 0x8A150201 | -1978334719 | WINGET_INSTALLED_STATUS_ARP_ENTRY_NOT_FOUND | The Apps and Features Entry for the package could not be found. |\n| 0x8A150202 | -1978334718 | WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_APPLICABLE | The install location is not applicable. |\n| 0x8A150203 | -1978334717 | WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_FOUND | The install location could not be found. |\n| 0x8A150204 | -1978334716 | WINGET_INSTALLED_STATUS_FILE_HASH_MISMATCH | The hash of the existing file did not match. |\n| 0x8A150205 | -1978334715 | WINGET_INSTALLED_STATUS_FILE_NOT_FOUND | File not found. |\n| 0x8A150206 | -1978334714 | WINGET_INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK | The file was found but the hash was not checked. |\n| 0x8A150207 | -1978334713 | WINGET_INSTALLED_STATUS_FILE_ACCESS_ERROR | The file could not be accessed. |\n\n## Configuration Errors\n\n| Hex | Decimal | Symbol | Description |\n|-------------|-------------|-------------|-------------|\n| 0x8A15C001 | -1978286079 | WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE | The configuration file is invalid. |\n| 0x8A15C002 | -1978286078 | WINGET_CONFIG_ERROR_INVALID_YAML | The YAML syntax is invalid. |\n| 0x8A15C003 | -1978286077 | WINGET_CONFIG_ERROR_INVALID_FIELD_TYPE | A configuration field has an invalid type. |\n| 0x8A15C004 | -1978286076 | WINGET_CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION | The configuration has an unknown version. |\n| 0x8A15C005 | -1978286075 | WINGET_CONFIG_ERROR_SET_APPLY_FAILED | An error occurred while applying the configuration. |\n| 0x8A15C006 | -1978286074 | WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER | The configuration contains a duplicate identifier. |\n| 0x8A15C007 | -1978286073 | WINGET_CONFIG_ERROR_MISSING_DEPENDENCY | The configuration is missing a dependency. |\n| 0x8A15C008 | -1978286072 | WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED | The configuration has an unsatisfied dependency. |\n| 0x8A15C009 | -1978286071 | WINGET_CONFIG_ERROR_ASSERTION_FAILED | An assertion for the configuration unit failed. |\n| 0x8A15C00A | -1978286070 | WINGET_CONFIG_ERROR_MANUALLY_SKIPPED | The configuration was manually skipped. |\n| 0x8A15C00B | -1978286069 | WINGET_CONFIG_ERROR_WARNING_NOT_ACCEPTED | A warning was thrown and the user declined to continue execution. |\n| 0x8A15C00C | -1978286068 | WINGET_CONFIG_ERROR_SET_DEPENDENCY_CYCLE | The dependency graph contains a cycle which cannot be resolved. |\n| 0x8A15C00D | -1978286067 | WINGET_CONFIG_ERROR_INVALID_FIELD_VALUE | The configuration has an invalid field value. |\n| 0x8A15C00E | -1978286066 | WINGET_CONFIG_ERROR_MISSING_FIELD | The configuration is missing a field. |\n| 0x8A15C00F | -1978286065 | WINGET_CONFIG_ERROR_TEST_FAILED | Some of the configuration units failed while testing their state. |\n| 0x8A15C010 | -1978286064 | WINGET_CONFIG_ERROR_TEST_NOT_RUN | Configuration state was not tested. |\n| 0x8A15C011 | -1978286063 | WINGET_CONFIG_ERROR_GET_FAILED | The configuration unit failed getting its properties. |\n| 0x8A15C012 | -1978286062 | WINGET_CONFIG_ERROR_HISTORY_ITEM_NOT_FOUND | The specified configuration could not be found. |\n| 0x8A15C013 | -1978286061 | WINGET_CONFIG_ERROR_PARAMETER_INTEGRITY_BOUNDARY | Parameter cannot be passed across integrity boundary. |\n\n## Configuration Processor Errors\n\n| Hex | Decimal | Symbol | Description |\n|-------------|-------------|-------------|-------------|\n| 0x8A15C101 | -1978285823 | WINGET_CONFIG_ERROR_UNIT_NOT_INSTALLED | The configuration unit was not installed. |\n| 0x8A15C102 | -1978285822 | WINGET_CONFIG_ERROR_UNIT_NOT_FOUND_REPOSITORY | The configuration unit could not be found. |\n| 0x8A15C103 | -1978285821 | WINGET_CONFIG_ERROR_UNIT_MULTIPLE_MATCHES | Multiple matches were found for the configuration unit specify the module to select the correct one. |\n| 0x8A15C104 | -1978285820 | WINGET_CONFIG_ERROR_UNIT_INVOKE_GET | The configuration unit failed while attempting to get the current system state. |\n| 0x8A15C105 | -1978285819 | WINGET_CONFIG_ERROR_UNIT_INVOKE_TEST | The configuration unit failed while attempting to test the current system state. |\n| 0x8A15C106 | -1978285818 | WINGET_CONFIG_ERROR_UNIT_INVOKE_SET | The configuration unit failed while attempting to apply the desired state. |\n| 0x8A15C107 | -1978285817 | WINGET_CONFIG_ERROR_UNIT_MODULE_CONFLICT | The module for the configuration unit is available in multiple locations with the same version. |\n| 0x8A15C108 | -1978285816 | WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE | Loading the module for the configuration unit failed. |\n| 0x8A15C109 | -1978285815 | WINGET_CONFIG_ERROR_UNIT_INVOKE_INVALID_RESULT | The configuration unit returned an unexpected result during execution. |\n| 0x8A15C110 | -1978285814 | WINGET_CONFIG_ERROR_UNIT_SETTING_CONFIG_ROOT | A unit contains a setting that requires the config root. |\n| 0x8A15C111 | -1978285813 | WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE_ADMIN | Loading the module for the configuration unit failed because it requires administrator privileges to run. |\n| 0x8A15C112 | -1978285812 | WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR | Operation is not supported by the configuration processor. |\n"
  },
  {
    "path": "doc/windows/package-manager/winget/search.md",
    "content": "---\ntitle: search Command\ndescription: Queries the sources for available applications that can be installed\nms.date: 04/28/2020\nms.topic: overview\nms.localizationpriority: medium\n---\n\n# search command (winget)\n\nThe **search** command of the [winget](index.md) tool queries the sources for available applications that can be installed.\n\nThe **search** command can show all applications available, or it can be filtered down to a specific application. The **search** command is used typically to identify the string to use to install a specific application.\n\n## Usage\n\n`winget search [[-q] <query>] [<options>]`\n\nThe following command aliases are available: \\\n`find`\n\n![Screenshot of the Windows Power Shell window displaying the results of the winget search.](images/search.png)\n\n## Arguments\n\nThe following arguments are available.\n\n| Argument  | Description |\n --------------|-------------|\n| **-q, --query** |  The query used to search for an app. |\n\n## Show all\n\nIf the search command includes no filters or options, it will display all available applications in the default source. You can also search for all applications in another source if you pass in just the **source** option.\n\n## Search strings\n\nSearch strings can be filtered with the following options.\n\n| Option  | Description |\n --------------|-------------|\n| **--id** | Limits the search to the ID of the application. The ID includes the publisher and the application name. |\n| **--name** | Limits the search to the name of the application. |\n| **--moniker** | Limits the search to the moniker specified. |\n| **--tag** | Limits the search to the tags listed for the application. |\n| **--cmd, --command** | Limits the search to the commands listed for the application. |\n| **-s, --source** | Find package using the specified source. |\n| **-n, --count** | Show no more than specified number of results (between 1 and 1000). |\n| **-e, --exact** | Find package using exact match. |\n| **--header** | Optional Windows-Package-Manager REST source HTTP header. |\n| **--accept-source-agreements** | Accept all source agreements during source operations. |\n| **--versions** | Show available versions of the package. |\n| **-?, --help** | Gets additional help on this command. |\n| **--wait** | Prompts the user to press any key before exiting. |\n| **--logs, --open-logs** | Open the default logs location. |\n| **--verbose, --verbose-logs** | Enables verbose logging for winget. |\n| **--disable-interactivity** | Disable interactive prompts. |\n\nThe string will be treated as a substring. The search by default is also case-insensitive. For example, `winget search micro` could return the following:\n\n* Microsoft\n* Microscope\n* MyMicro\n\n## Search options\n\nThe search commands supports a number of options or filters to help limit the results.\n\n| Option  | Description |\n --------------|-------------|\n| **-e, --exact** | Uses the exact string in the query, including checking for case-sensitivity. It will not use the default behavior of a substring. |\n| **-n, --count** | Restricts the output of the display to the specified count. |\n| **-s, --source** | Restricts the search to the specified [source](source.md) name. |\n\n## Related topics\n\n* [Use the winget tool to install and manage applications](index.md)\n"
  },
  {
    "path": "doc/windows/package-manager/winget/settings.md",
    "content": "---\ntitle: winget settings command\ndescription: Provides customizations for the Windows Package Manager.\nms.date: 05/05/2021\nms.topic: article\nms.localizationpriority: medium\n---\n\n# settings command (winget)\n\nThe **settings** command of the [winget](index.md) tool allows you to customize your Windows Package Manager client experience.  You can change defaults and try out experimental features that are enabled in your client.\nThe **settings** command will launch your default JSON editor. Windows by default will launch Notepad as an option. We recommend using a tool like [Visual Studio code](https://code.visualstudio.com/).\n\n> You can easily install Visual Studio Code, by typing `winget install Microsoft.VisualStudioCode`\n\n## Usage\n\nLaunch your default JSON editing tool: `winget settings`\n\n![Screenshot of the Windows Package Manager Settings.](images/settings.png)\n\nWhen you launch the settings for the first time, there will be no settings specified. At the top of the JSON we provide a link to [https://aka.ms/winget-settings](https://aka.ms/winget-settings) where you can discover the latest experimental features and settings.\n\nWe have also defined a schema for the settings file.  This allows you to use TAB to discover settings and syntax if your JSON editor supports JSON schemas.\n\n## Updating Settings\n\nThe following settings are available for the 1.0 release of the Windows Package Manager.\n\n### Source\n\nThe `source` settings involve configuration to the WinGet source.\n\n```json\n    \"source\": {\n        \"autoUpdateIntervalInMinutes\": 3\n    },\n```\n\n#### autoUpdateIntervalInMinutes\n\nA positive integer represents the update interval in minutes. The check for updates only happens when a source is used. A zero will disable the check for updates to a source. Any other values are invalid.\n\n- Disable: 0\n- Default: 5\n\nTo manually update the source use `winget source update`\n\n### Visual\n\nThe `visual` settings involve visual elements that are displayed by WinGet\n\n```json\n    \"visual\": {\n        \"progressBar\": \"accent\"\n    },\n```\n\n#### progressBar\n\nColor of the progress bar that WinGet displays when not specified by arguments.\n\n- accent (default)\n- retro\n- rainbow\n\n### Install Behavior\n\nThe `installBehavior` settings affect the default behavior of installing and upgrading (where applicable) packages.\n\n#### Preferences and Requirements\n\nSome of the settings are duplicated under `preferences` and `requirements`. `preferences` affect how the various available options are sorted when choosing the one to act on.  For instance, the default scope of package installs is for the current user, but if that is not an option then a machine level installer will be chosen. `requirements` filter the options, potentially resulting in an empty list and a failure to install. In the previous example, a user scope requirement would result in no applicable installers and an error.\n\nAny arguments passed on the command line will effectively override the matching `requirement` setting for the duration of that command.\n\n#### Scope\n\nThe `scope` behavior affects the choice between installing a package for the current user or for the entire machine. The matching parameter is `--scope`, and uses the same values (`user` or `machine`).\n\n```json\n    \"installBehavior\": {\n        \"preferences\": {\n            \"scope\": \"user\"\n        }\n    },\n```\n\n#### Locale\n\nThe `locale` behavior affects the choice of installer based on installer locale. The matching parameter is `--locale`, and uses bcp47 language tag.\n\n```json\n    \"installBehavior\": {\n        \"preferences\": {\n            \"locale\": [ \"en-US\", \"fr-FR\" ]\n        }\n    },\n```\n\n### Telemetry\n\nThe `telemetry` settings control whether winget writes ETW events that may be sent to Microsoft on a default installation of Windows.\n\nSee [details on telemetry](https://github.com/microsoft/winget-cli/blob/master/README.md#datatelemetry), and our [primary privacy statement](https://github.com/microsoft/winget-cli/blob/master/PRIVACY.md).\n\n#### disable\n\n```json\n    \"telemetry\": {\n        \"disable\": true\n    },\n```\n\nIf set to true, the `telemetry.disable` setting will prevent any event from being written by the program.\n\n### Network\n\nThe `network` settings influence how winget uses the network to retrieve packages and metadata.\n\n#### Downloader\n\nThe `downloader` setting controls which code is used when downloading packages. The default is `default`, which may be any of the options based on our determination.\n`wininet` uses the [WinINet](https://docs.microsoft.com/windows/win32/wininet/about-wininet) APIs, while `do` uses the\n[Delivery Optimization](https://support.microsoft.com/windows/delivery-optimization-in-windows-10-0656e53c-15f2-90de-a87a-a2172c94cf6d) service.\n\n```json\n   \"network\": {\n       \"downloader\": \"do\"\n   }\n```\n\n## Enabling Experimental features\n\nTo discover which experimental features are available, go to [https://aka.ms/winget-settings](https://aka.ms/winget-settings) where you can see the experimental features available to you.\n\n"
  },
  {
    "path": "doc/windows/package-manager/winget/show.md",
    "content": "---\ntitle: show Command\ndescription: Displays details for the specified application, including details on the source of the application as well as the metadata associated with the application.\nms.date: 04/28/2020\nms.topic: overview\nms.localizationpriority: medium\n---\n\n# show command (winget)\n\nThe **show** command of the [winget](index.md) tool displays details for the specified application, including details on the source of the application as well as the metadata associated with the application.\n\nThe **show** command only shows metadata that was submitted with the application. If the submitted application excludes some metadata, then the data will not be displayed.\n\n## Usage\n\n`winget show [[-q] <query>] [<options>]`\n\nThe following command aliases are available: \\\n`view`\n\n![show command](images/show.png)\n\n## Arguments\n\nThe following arguments are available.\n\n| Argument  | Description |\n|--------------|-------------|\n| **-q, --query** |  The query used to search for an application. |\n\n## Options\n\nThe following options are available.\n\n| Option  | Description |\n|--------------|-------------|\n| **-m,--manifest** | The path to the manifest of the application to install. |\n| **--id**         |  Filter results by ID. |\n| **--name**   |      Filter results by name. |\n| **--moniker**   |  Filter results by application moniker. |\n| **-v,--version** |  Use the specified version. The default is the latest version. |\n| **-s,--source** |   Find the application using the specified [source](source.md). |\n| **-e,--exact**     | Find the application using exact match. |\n| **--versions**    | Show available versions of the application. |\n| **--scope** | Select install scope (user or machine). |\n| **-a, --architecture** | Select the architecture. |\n| **--installer-type** | Select the installer type. |\n| **--locale** | Locale to use (BCP47 format). |\n| **--header** | Optional Windows-Package-Manager REST source HTTP header. |\n| **--accept-source-agreements** | Accept all source agreements during source operations. |\n| **-?, --help** | Gets additional help on this command. |\n| **--wait** | Prompts the user to press any key before exiting. |\n| **--logs, --open-logs** | Open the default logs location. |\n| **--verbose, --verbose-logs** | Enables verbose logging for winget. |\n| **--disable-interactivity** | Disable interactive prompts. |\n\n## Multiple selections\n\nIf the query provided to **winget** does not result in a single application, then **winget** will display the results of the search. This will provide you with the additional data necessary to refine the search.\n\n## Results of show\n\nIf a single application is detected, the following data will be displayed.\n\n### Metadata\n\n| Value  | Description |\n|--------------|-------------|\n| **Version** | Version of the application. |\n| **Publisher** | Publisher of the application. |\n| **Moniker** | AppMoniker of the application. |\n| **Description** | Description of the application. |\n| **Homepage**  | Homepage of the application. |\n| **License**  | License of the application. |\n| **LicenseUrl** | The URL to the license file of the application. |\n\n### Installer details\n\n| Value  | Description |\n|--------------|-------------|\n| **Type**  | The type of installer. |\n| **Download Url** | The Url of the installer. |\n| **SHA256** | The Sha-256 of the installer.  |\n\n## Related topics\n\n* [Use the winget tool to install and manage applications](index.md)\n"
  },
  {
    "path": "doc/windows/package-manager/winget/source.md",
    "content": "---\ntitle: source Command\ndescription: Manages the repositories accessed by Windows Package Manager.\nms.date: 04/28/2020\nms.topic: overview\nms.localizationpriority: medium\n---\n\n# source command (winget)\n\n> The **source** command is currently for internal use only. Additional sources are not supported at this time.\n\nThe **source** command of the [winget](index.md) tool manages the repositories accessed by Windows Package Manager. With the **source** command you can **add**, **remove**, **list**, and **update** the repositories.\n\nA source provides the data for you to discover and install applications. Only add a new source if you trust it as a secure location.\n\n## Usage\n\n`winget source [<command>] [<options>]`\n\n![Source image](images/source.png)\n\n## Arguments\n\nThe following arguments are available.\n\n| Argument  | Description |\n|--------------|-------------|\n| **-?, --help** |  Gets additional help on this command. |\n\n## Sub-commands\n\nSource supports the following sub-commands for manipulating the sources.\n\n| Sub-command  | Description |\n|--------------|-------------|\n|  **add** |  Adds a new source. |\n|  **list** | Enumerates the list of enabled sources. |\n|  **update** | Updates a source. |\n|  **remove** | Removes a source. |\n|  **reset** | Resets **winget** back to the initial configuration.  |\n|  **export** | Export current sources |\n\nFor more details on a specific command, pass it the help argument. [-?]\n\n## Options\n\nThe **source** command supports the following options.\n\n| Option  | Description |\n|--------------|-------------|\n|  **-n, --name** | The name to identify the source by. |\n|  **-a, --arg** | The URL or UNC of the source. |\n|  **-t, --type** | The type of source. |\n| **-?, --help** |  Gets additional help on this command. |\n| **--wait** | Prompts the user to press any key before exiting. |\n| **--logs, --open-logs** | Open the default logs location. |\n| **--verbose, --verbose-logs** | Enables verbose logging for winget. |\n| **--disable-interactivity** | Disable interactive prompts. |\n\n## add\n\nThe **add** sub-command adds a new source. This sub-command requires the **--name** option and the **name** argument.\n\nUsage: `winget source add [-n, --name] <name> [-a] <url> [[-t] <type>]`\n\nExample:  `winget source add --name Contoso https://www.contoso.com/cache`\n\nThe **add** sub-command also supports the optional **type** parameter. The **type** parameter communicates to the client what type of repository it is connecting to. The following types are supported.\n\n| Type  | Description |\n|--------------|-------------|\n| **Microsoft.PreIndexed.Package** | The type of source \\<default>. |\n| **Microsoft.Rest** | A Microsoft REST API source. |\n\n## list\n\nthe **list** sub-command enumerates the currently enabled sources. This sub-command also provides details on a specific source.\n\nUsage: `winget source list [-n, --name] <name>`\n\n### list all\n\nThe **list** sub-command by itself will reveal the complete list of supported sources. For example:\n\n![Source list image](images/source-list.png)\n\n### list source details\n\nIn order to get complete details on the source, pass in the name used to identify the source. For example:\n\n![Source list winget image](images/source-list-winget.png)\n\n**Name** displays the name to identify the source by.\n**Type** displays the type of repo.\n**Arg** displays the URL or path used by the source.\n**Data** displays the optional package name used if appropriate.\n**Updated** displays the last date and time the source was updated.\n\n## update\n\nThe **update** sub-command forces an update to an individual source or for all.\n\nusage: `winget source update [-n, --name] <name>`\n\n### update all\n\nThe **update** sub-command by itself will request and update to each repo. For example: `C:\\winget update`\n\n### update source\n\nThe **update** sub-command combined with the **--name** option can direct and update to an individual source. For example: `C:\\winget source update --name winget`\n\n## remove\n\nThe **remove** sub-command removes a source. This sub-command requires the **--name** option and **name argument** in order to identify the source.\n\nUsage: `winget source remove [-n, --name] <name>`\n\nFor example: `winget source remove --name Contoso`\n\n## reset\n\nThe **reset** sub-command resets the client back to its original configuration. The **reset** sub-command removes all sources and sets the source to the default. This sub-command should only be used in rare cases.\n\nUsage: `winget source reset`\n\n## Default repository\n\nWindows Package Manager specifies a default repository. You can identify the repository by using the **list** command. For example: `winget source list`\n\n## Related topics\n\n* [Use the winget tool to install and manage applications](index.md)\n"
  },
  {
    "path": "doc/windows/package-manager/winget/uninstall.md",
    "content": "---\ntitle: uninstall Command\ndescription: uninstalls the specified application.\nms.date: 05/05/2021\nms.topic: overview\nms.localizationpriority: medium\n---\n\n# uninstall command (winget)\n\nThe **uninstall** command of the [winget](index.md) tool uninstalls the specified application.\n\nThe **uninstall** command requires that you specify the exact string to uninstall. If there is any ambiguity, you will be prompted to further filter the **uninstall** command to an exact application.\n\n## Usage\n\n`winget uninstall [[-q] <query>...] [<options>]`\n\nThe following command aliases are available: \\\n`remove` \\\n`rm`\n\n![uninstall command](images/uninstall.png)\n\n## Arguments\n\nThe following arguments are available.\n\n| Argument | Description |\n|-------------|-------------|\n| **-q,--query**  |  The query used to search for an app. |\n\n## Options\n\nThe options allow you to customize the uninstall experience to meet your needs.\n\n| Option | Description |\n|--------|-------------|\n| **-m, --manifest** | Must be followed by the path to the manifest (YAML) file. You can use the manifest to run the uninstall experience from a [local YAML file](#local-uninstall). |\n| **--id** | Limits the uninstall to the ID of the application. |\n| **--name** | Limits the search to the name of the application. |\n| **--moniker** | Limits the search to the moniker listed for the application. |\n| **-v, --version** | Enables you to specify an exact version to uninstall. If not specified, the latest will uninstall the highest versioned application. |\n| **-s, --source** | Restricts the search to the source name provided. Must be followed by the source name. |\n| **-e, --exact** | Uses the exact string in the query, including checking for case-sensitivity. It will not use the default behavior of a substring. |\n| **-i, --interactive** | Runs the uninstaller in interactive mode. The default experience shows uninstaller progress. |\n| **-h, --silent** | Runs the uninstaller in silent mode. This suppresses all UI. The default experience shows uninstaller progress. |\n| **-o, --log** | Directs the logging to a log file. You must provide a path to a file that you have the write rights to. |\n| **--product-code** | Filters using the product code. |\n| **--scope** | Select installed package scope filter (user or machine). |\n| **--force** | Directly run the command and continue with non-security-related issues. |\n| **--purge** | Deletes all files and directories in the package directory (portable). |\n| **--preserve** | Retains all files and directories created by the package (portable). |\n| **--header** | Optional Windows-Package-Manager REST source HTTP header. |\n| **--accept-source-agreements** | Accept all source agreements during source operations. |\n| **-?, --help** | Get additional help on this command. |\n| **--wait** | Prompts the user to press any key before exiting. |\n| **--logs, --open-logs** | Open the default logs location. |\n| **--verbose, --verbose-logs** | Enables verbose logging for winget. |\n| **--disable-interactivity** | Disable interactive prompts. |\n\nOnce you have successfully identified the application intended to uninstall, winget will execute the uninstall command.  In the example below, the **name** 'orca' and the **id** was passed in.\n\n![uninstall command](images/uninstall-execute.png)\n\n\n### Example queries\n\nThe following example uninstalls a specific version of an application.\n\n```CMD\nwinget uninstall --name powertoys --version 0.15.2\n```\n\nThe following example uninstalls an application using its ID.\n\n```CMD\nwinget uninstall --id \"{24559D0F-481C-F3BE-8DD0-D908923A38F8}\"\n```\n\n## Multiple selections\n\nIf the query provided to **winget** does not result in a single application to uninstall, then **winget** will display multiple results. You can then use additional filters to refine the search for a correct application.\n\n![uninstall command](images/uninstall-multiple.png)\n\n## Uninstalling apps not installed with Windows Package Manager\nAs mentioned in [**list**](list.md), the **winget list** command will display more than just apps installed with the **winget**.  Therefore you can use these commands to quickly and easily remove apps from your PC.\n\nIn this example, **list** was used to find the application, and then the **id** was passed in as part of uninstall.\n\n![uninstall with list command](images/uninstall-with-list.png)\n\n## Related topics\n\n* [Use the winget tool to install and manage applications](index.md)\n"
  },
  {
    "path": "doc/windows/package-manager/winget/upgrade.md",
    "content": "---\ntitle: upgrade Command\ndescription: upgrades the specified application.\nms.date: 05/05/2021\nms.topic: overview\nms.localizationpriority: medium\n---\n\n# upgrade command (winget)\n\nThe **upgrade** command of the [winget](index.md) tool upgrades the specified application. Optionally, you may not specify an application, this will list all available upgrades instead.\n\nThe **upgrade** command requires that you specify the exact string to upgrade. If there is any ambiguity, you will be prompted to further filter the **upgrade** command to  an exact application.\n\n## Usage\n\n`winget upgrade [[-q] <query>...] [<options>]`\n\nThe following command aliases are available: \\\n`update`\n\n![upgrade command](images/upgrade.png)\n\n## Options\n\nThe options allow you to customize the upgrade experience to meet your needs.\n\n| Option                            | Description                                                                                                                  |\n|-----------------------------------|------------------------------------------------------------------------------------------------------------------------------|\n| **-m, --manifest**                | Must be followed by the path to the manifest (YAML) file. You can use the manifest to run the upgrade experience from a [local YAML file](#local-upgrade). |\n| **--id**                          | Limits the upgrade to the ID of the application.                                                                             |\n| **--name**                        | Limits the search to the name of the application.                                                                           |\n| **--moniker**                     | Limits the search to the moniker listed for the application.                                                                |\n| **-v, --version**                 | Enables you to specify an exact version to upgrade. If not specified, the latest will upgrade the highest versioned application. |\n| **-s, --source**                  | Restricts the search to the source name provided. Must be followed by the source name.                                      |\n| **-e, --exact**                   | Uses the exact string in the query, including checking for case-sensitivity. It will not use the default behavior of a substring. |\n| **-i, --interactive**             | Runs the installer in interactive mode. The default experience shows installer progress.                                      |\n| **-h, --silent**                  | Runs the installer in silent mode. This suppresses all UI. The default experience shows installer progress.                 |\n| **-o, --log**                     | Directs the logging to a log file. You must provide a path to a file that you have the write rights to.                      |\n| **--override**                    | A string that will be passed directly to the installer.                                                                     |\n| **-l, --location**                | Location to upgrade to (if supported).                                                                                     |\n| **--force**                       | When a hash mismatch is discovered will ignore the error and attempt to install the package.                                |\n| **--all**                         | Updates all available packages to the latest application.                                                                  |\n| **--include-unknown**            | Attempt to upgrade a package even if the package's current version is unknown.                                              |\n| **--purge**                       | Deletes all files and directories in the package directory (portable).                                                      |\n| **--custom**                      | Arguments to be passed on to the installer in addition to the defaults.                                                     |\n| **--scope**                       | Select installed package scope filter (user or machine).                                                                    |\n| **-a, --architecture**            | Select the architecture to install.                                                                                         |\n| **--locale**                      | Locale to use (BCP47 format).                                                                                               |\n| **--ignore-security-hash**        | Ignore the installer hash check failure.                                                                                    |\n| **--ignore-local-archive-malware-scan** | Ignore the malware scan performed as part of installing an archive-type package from a local manifest.                  |\n| **--accept-package-agreements**   | Accept all license agreements for packages.                                                                                 |\n| **--accept-source-agreements**    | Accept all source agreements during source operations.                                                                      |\n| **--header**                      | Optional Windows-Package-Manager REST source HTTP header.                                                                   |\n| **-r, --recurse, --all**         | Upgrade all installed packages to the latest version if available.                                                           |\n| **--pinned,--include-pinned**    | Upgrade packages even if they have a non-blocking pin.                                                                      |\n| **--uninstall-previous**         | Uninstall the previous version of the package during the upgrade.                                                            |\n| **--wait**                        | Prompts the user to press any key before exiting.                                                                           |\n| **--logs,--open-logs**           | Open the default logs location.                                                                                             |\n| **--verbose,--verbose-logs**     | Enable verbose logging for winget.                                                                                          |\n| **--disable-interactivity**      | Disable interactive prompts.                                                                                                |\n| **--installer-type**             |        Select the installer type\n| **--skip-dependencies**          |        Skips processing package dependencies and Windows features                                                           |\n\n### Example queries\n\nThe following example upgrades a specific version of an application.\n\n```CMD\nwinget upgrade powertoys --version 0.15.2\n```\n\nThe following example upgrades an application from its ID.\n\n```CMD\nwinget upgrade --id Microsoft.PowerToys\n```\n\nThe following example shows upgrading all apps\n\n```CMD\nwinget upgrade --all\n```\n\n## Using **list** and **upgrade**\n\nIt is common to use the [**list**](list.md) command to identify apps in need of an update, and then to use **upgrade** to install the latest.\n\nIn the example below you will see [**list**](list.md) identifies that an update is available for **JetBrains.Toolbox**, and then the user uses **upgrade** to update the application.\n\n![upgrade command usage](images/upgrade.gif)\n\n## **upgrade** --all\n\n**upgrade --all** will identify all the applications with upgrades available. When you run **winget upgrade --all** the Windows Package Manager will look for all applications that have updates available and attempt to install the upgrade.\n\n## Related topics\n\n* [Use the winget tool to install and manage applications](index.md)\n"
  },
  {
    "path": "doc/windows/package-manager/winget/validate.md",
    "content": "---\ntitle: winget validate Command\ndescription: Validates a manifest file for submitting software to the Microsoft Community Package Manifest Repository on GitHub.\nms.date: 04/28/2020\nms.topic: article\nms.localizationpriority: medium\n---\n\n# validate command (winget)\n\nThe **validate** command of the [winget](index.md) tool validates a [manifest](../package/manifest.md) for submitting software to the **Microsoft Community Package Manifest Repository** on GitHub. The manifest must be a YAML file that follows the [specification](https://github.com/microsoft/winget-pkgs/blob/master/doc/manifest/README.md).\n\n## Usage\n\n`winget validate [--manifest] <manifest> [<options>]`\n\n## Arguments\n\nThe following arguments are available.\n\n| Argument  | Description |\n|--------------|-------------|\n| **--manifest** |  The path to the manifest to be validated. |\n\n## Options\n\nThe options allow you to customize the export experience to meet your needs.\n\n| Option | Description |\n|--------|-------------|\n| **-?, --help** | Get additional help on this command. |\n| **--wait** | Prompts the user to press any key before exiting. |\n| **--logs, --open-logs** | Open the default logs location. |\n| **--verbose, --verbose-logs** | Enables verbose logging for winget. |\n| **--disable-interactivity** | Disable interactive prompts. |\n\n## Related topics\n\n* [Use the winget tool to install and manage applications](index.md)\n* [Submit packages to Windows Package Manager](../package/index.md)\n"
  },
  {
    "path": "doc/windows-package-manager-release-roadmap.md",
    "content": "# Windows Package Manager Release Roadmap\n\n## Overview\n\nThis document outlines our aspirational roadmap to deliver next release of Windows Package Manager. We anticipate substantial feedback from the community, and as such, this plan is subject to change.\n\n## Milestones\n\nThe Windows Package Manager project is engineered and delivered as described below.\n\n### Activities\n\n#### Dev Work\n\n* Fixes / Features for Windows Package Manager\n* Fixes / Features for future Windows Releases\n\n#### Quality & Stability\n\n* Bug Fixes\n* Performance & Stability\n* Globalization, Localization, Internationalization, Accessibility\n* Tests\n\n#### Release\n\n* Available from to Windows Insiders through the [Microsoft Store](https://apps.microsoft.com/detail/9nblggh4nns1) & [GitHub Releases](https://github.com/microsoft/winget-cli/releases)\n* Release Notes & Announcement Blog published\n* Engineering System Maintenance\n* Community Engagement\n* [Docs](https://docs.microsoft.com/windows/package-manager/)\n* Future Milestone Planning\n\n### Releases\n\nReleases will be available here on GitHub first. We will release to the App Installer for Insiders as frequently as the releases have met our quality bars.\n\n## GitHub Milestones\n\nWe use [GitHub Projects](https://github.com/orgs/microsoft/projects/137) to broadly organize what we intend to work on.  Issues will be added to milestones when we're reasonably confident they will land in the next milestone. Dates in [GitHub milestones](https://github.com/microsoft/winget-cli/milestones) are only used for sequencing and do not represent a commitment.\n\n| Milestone                                                                                                     | Description                                     | Status             |\n| ------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | ------------------ |\n| [v1.12-Client](https://github.com/microsoft/winget-cli/milestone/47)                                          | Work Targeted for v1.12                         | :white_check_mark: |\n| [v1.28-Client](https://github.com/microsoft/winget-cli/milestone/48)                                          | Work Targeted for v1.28                         | :construction:     |\n| [v1.29-Client](https://github.com/microsoft/winget-cli/milestone/49)                                          | Work Targeted for v1.29                         | :construction:     |\n| [v2.0-Client](https://github.com/microsoft/winget-cli/milestone/41)                                           | Work Targeted for breaking-change Release       | :rocket:           |\n| [Backlog-Client](https://github.com/microsoft/winget-cli/issues?q=is%3Aissue%20state%3Aopen%20no%3Amilestone) | Work not yet assigned to a milestone or release | N/A                |\n\nOlder milestones can be found in the [list of closed milestones](https://github.com/microsoft/winget-cli/milestones?state=closed).\n\n## Issue Triage & Prioritization\n\nIncoming issues/asks/etc. are triaged several times a week, labelled appropriately, and assigned to a milestone in priority order:\n\n* P0 (serious crashes, data loss, etc.) issues are scheduled to be dealt with ASAP.\n* P1/2 issues/features/asks assigned to the current or future milestone.\n* Issues/features/asks not on our list of the features of next release is assigned to the [Windows Package Manager Backlog](https://github.com/microsoft/winget-cli/milestone/2) for subsequent triage, prioritization & scheduling.\n\n#### Feature Priorities will be influenced by community feedback on issues.\n\n"
  },
  {
    "path": "samples/MinimalCallers/C#/Configuration-InProc/C#_Configuration_InProc.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <TargetFramework>net8.0-windows10.0.22000.0</TargetFramework>\n    <RootNamespace>Configuration_InProc</RootNamespace>\n    <ImplicitUsings>enable</ImplicitUsings>\n    <Nullable>enable</Nullable>\n    <Platforms>x64;x86;ARM64</Platforms>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.Windows.Compatibility\" Version=\"6.0.9\" />\n    <PackageReference Include=\"Microsoft.WindowsPackageManager.Configuration\" Version=\"1.9.25180\" GeneratePathProperty=\"True\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <Content Include=\"$(PkgMicrosoft_WindowsPackageManager_Configuration)\\runtimes\\win10-$(Platform)\\native\\Microsoft.Management.Configuration.dll\" Link=\"Microsoft.Management.Configuration.dll\" CopyToOutputDirectory=\"PreserveNewest\" />\n    <Content Include=\"$(PkgMicrosoft_WindowsPackageManager_Configuration)\\runtimes\\win10-$(Platform)\\native\\Microsoft.Management.Configuration.winmd\" Link=\"Microsoft.Management.Configuration.winmd\" CopyToOutputDirectory=\"PreserveNewest\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "samples/MinimalCallers/C#/Configuration-InProc/Program.cs",
    "content": "// Shows the contents of a configuration yml file\nusing Windows.Storage;\nusing Microsoft.Management.Configuration;\nusing Microsoft.Management.Configuration.Processor;\n\nif (args.Length != 1)\n{\n    Console.WriteLine(\"Usage: Configuration-InProc <path>\");\n    return;\n}\n\nvar configStatics = new ConfigurationStaticFunctions();\nif (!configStatics.IsConfigurationAvailable)\n{\n    throw new Exception(\"Configuration is not available\");\n}\n\n// Differs from the OutOfProc version in that we create the factory object directly\nvar factory = new PowerShellConfigurationSetProcessorFactory();\n\nvar processor = configStatics.CreateConfigurationProcessor(factory);\n\nvar file = await StorageFile.GetFileFromPathAsync(args[0]);\nvar fileStream = await file.OpenStreamForReadAsync();\n\nvar openResult = processor.OpenConfigurationSet(fileStream.AsInputStream());\nvar configSet = openResult.Set;\n\nConsole.WriteLine(\"Configuration set:\");\nconfigSet.Serialize(Console.OpenStandardOutput().AsOutputStream());\n"
  },
  {
    "path": "samples/MinimalCallers/C#/Configuration-OutOfProc/C#_Configuration_OutOfProc.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <TargetFramework>net8.0-windows10.0.22000.0</TargetFramework>\n    <RootNamespace>Configuration_OutOfProc</RootNamespace>\n    <ImplicitUsings>enable</ImplicitUsings>\n    <Nullable>enable</Nullable>\n    <Platforms>x64;x86;ARM64</Platforms>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.WindowsPackageManager.Configuration.OutOfProc\" Version=\"1.10.340\" GeneratePathProperty=\"True\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <Content Include=\"$(PkgMicrosoft_WindowsPackageManager_Configuration_OutOfProc)\\runtimes\\win-$(Platform)\\native\\Microsoft.Management.Configuration.dll\" Link=\"Microsoft.Management.Configuration.dll\" CopyToOutputDirectory=\"PreserveNewest\" />\n    <Content Include=\"$(PkgMicrosoft_WindowsPackageManager_Configuration_OutOfProc)\\runtimes\\win-$(Platform)\\native\\Microsoft.Management.Configuration.winmd\" Link=\"Microsoft.Management.Configuration.winmd\" CopyToOutputDirectory=\"PreserveNewest\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "samples/MinimalCallers/C#/Configuration-OutOfProc/Program.cs",
    "content": "// Shows the contents of a configuration yml file\nusing Windows.Storage;\nusing Microsoft.Management.Configuration;\n\nif (args.Length != 1)\n{\n    Console.WriteLine(\"Usage: Configuration-InProc <path>\");\n    return;\n}\n\nvar configStatics = new ConfigurationStaticFunctions();\nif (!configStatics.IsConfigurationAvailable)\n{\n    throw new Exception(\"Configuration is not available\");\n}\n\nvar factory = await configStatics.CreateConfigurationSetProcessorFactoryAsync(\"pwsh\");\n\nvar processor = configStatics.CreateConfigurationProcessor(factory);\n\nvar file = await StorageFile.GetFileFromPathAsync(args[0]);\nvar fileStream = await file.OpenStreamForReadAsync();\n\nvar openResult = processor.OpenConfigurationSet(fileStream.AsInputStream());\nvar configSet = openResult.Set;\n\nConsole.WriteLine(\"Configuration set:\");\nconfigSet.Serialize(Console.OpenStandardOutput().AsOutputStream());\n"
  },
  {
    "path": "samples/MinimalCallers/C#/WinGet-InProc/C#_WinGet_InProc.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <TargetFramework>net8.0-windows10.0.22000.0</TargetFramework>\n    <RootNamespace>WinGet_InProc</RootNamespace>\n    <ImplicitUsings>enable</ImplicitUsings>\n    <Nullable>enable</Nullable>\n    <Platforms>x64;x86;ARM64</Platforms>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.Windows.CsWinRT\" Version=\"2.2.0\" />\n    <PackageReference Include=\"Microsoft.WindowsPackageManager.InProcCom\" Version=\"1.10.340\">\n      <!-- NU1701: The package targets .NET Framework, but this uses .NET -->\n      <NoWarn>NU1701</NoWarn>\n      <GeneratePathProperty>true</GeneratePathProperty>\n      <IncludeAssets>none</IncludeAssets>\n    </PackageReference>\n  </ItemGroup>\n\n  <!-- Tell CsWinRT to create the projection for the API -->\n  <PropertyGroup>\n    <CsWinRTWindowsMetadata>10.0.19041.0</CsWinRTWindowsMetadata>\n    <CsWinRTIncludes>Microsoft.Management.Deployment</CsWinRTIncludes>\n  </PropertyGroup>\n  <ItemGroup>\n    <CsWinRTInputs Include=\"$(PkgMicrosoft_WindowsPackageManager_InProcCom)\\lib\\Microsoft.Management.Deployment.winmd\" />\n  </ItemGroup>\n\n  <!-- Reference and include necessary binaries -->\n  <ItemGroup>\n    <Content Include=\"$(PkgMicrosoft_WindowsPackageManager_InProcCom)\\runtimes\\win-$(Platform)\\native\\Microsoft.Management.Deployment.InProc.dll\" Link=\"Microsoft.Management.Deployment.dll\" CopyToOutputDirectory=\"PreserveNewest\" />\n    <Content Include=\"$(PkgMicrosoft_WindowsPackageManager_InProcCom)\\runtimes\\win-$(Platform)\\native\\Microsoft.Management.Deployment.InProc.dll.manifest\" Link=\"Microsoft.Management.Deployment.dll.manifest\" CopyToOutputDirectory=\"PreserveNewest\" />\n    <Content Include=\"$(PkgMicrosoft_WindowsPackageManager_InProcCom)\\runtimes\\win-$(Platform)\\native\\Microsoft.Management.Deployment.winmd\" Link=\"Microsoft.Management.Deployment.winmd\" CopyToOutputDirectory=\"PreserveNewest\" />\n    <Content Include=\"$(PkgMicrosoft_WindowsPackageManager_InProcCom)\\runtimes\\win-$(Platform)\\native\\WindowsPackageManager.dll\" Link=\"WindowsPackageManager.dll\" CopyToOutputDirectory=\"PreserveNewest\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "samples/MinimalCallers/C#/WinGet-InProc/Program.cs",
    "content": "// Lists all installed packages\nusing Microsoft.Management.Deployment;\n\nvar packageManager = new PackageManager();\n\nvar installedCatalogConnectResult = packageManager.GetLocalPackageCatalog(LocalPackageCatalog.InstalledPackages).Connect();\nif (installedCatalogConnectResult.Status != ConnectResultStatus.Ok)\n{\n    throw new Exception(\"Error connecting to catalog\");\n}\n\nvar installedCatalog = installedCatalogConnectResult.PackageCatalog;\n\nvar findOptions = new FindPackagesOptions();\nvar searchResult = installedCatalog.FindPackages(findOptions);\nif (searchResult.Status != FindPackagesResultStatus.Ok)\n{\n    throw new Exception(\"Error finding packages\");\n}\n\n// Can't use foreach due to C#/WinRT limitations\nfor (int i = 0; i < searchResult.Matches.Count; ++i)\n{\n    Console.WriteLine(\"Package found: \" + searchResult.Matches[i].CatalogPackage.Id);\n}\n"
  },
  {
    "path": "samples/MinimalCallers/C#/WinGet-OutOfProc/C#_WinGet_OutOfProc.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <TargetFramework>net8.0-windows10.0.22000.0</TargetFramework>\n    <RootNamespace>WinGet_OutOfProc</RootNamespace>\n    <ImplicitUsings>enable</ImplicitUsings>\n    <Nullable>enable</Nullable>\n    <Platforms>x64;ARM64;x86</Platforms>\n\n    <!-- Use one of static, dynamic, none -->\n    <MicrosoftManagementDeployment-FactoryLinkage>static</MicrosoftManagementDeployment-FactoryLinkage>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.Windows.CsWinRT\" Version=\"2.2.0\" />\n    <PackageReference Include=\"Microsoft.WindowsPackageManager.ComInterop\" Version=\"1.10.340\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "samples/MinimalCallers/C#/WinGet-OutOfProc/Program.cs",
    "content": "// Lists all installed packages\nusing Microsoft.Management.Deployment;\n\nvar packageManager = new PackageManager();\n\nvar installedCatalogConnectResult = packageManager.GetLocalPackageCatalog(LocalPackageCatalog.InstalledPackages).Connect();\nif (installedCatalogConnectResult.Status != ConnectResultStatus.Ok)\n{\n    throw new Exception(\"Error connecting to catalog\");\n}\n\nvar installedCatalog = installedCatalogConnectResult.PackageCatalog;\n\nvar findOptions = new FindPackagesOptions();\nvar searchResult = installedCatalog.FindPackages(findOptions);\nif (searchResult.Status != FindPackagesResultStatus.Ok)\n{\n    throw new Exception(\"Error finding packages\");\n}\n\n// Can't use foreach due to C#/WinRT limitations\nfor (int i = 0; i < searchResult.Matches.Count; ++i)\n{\n    Console.WriteLine(\"Package found: \" + searchResult.Matches[i].CatalogPackage.Id);\n}\n"
  },
  {
    "path": "samples/MinimalCallers/C++/WinGet-InProc/WinGet-InProc.cpp",
    "content": "#include <Windows.h>\n\n#include <winrt/Microsoft.Management.Deployment.h>\n#include <winrt/Windows.Foundation.Collections.h>\n\n#include <iostream>\n\nusing namespace winrt::Microsoft::Management::Deployment;\n\nconst CLSID CLSID_PackageManager = { 0xC53A4F16, 0x787E, 0x42A4, 0xB3, 0x04, 0x29, 0xEF, 0xFB, 0x4B, 0xF5, 0x97 };  //C53A4F16-787E-42A4-B304-29EFFB4BF597\nconst CLSID CLSID_FindPackagesOptions = { 0x572DED96, 0x9C60, 0x4526, { 0x8F, 0x92, 0xEE, 0x7D, 0x91, 0xD3, 0x8C, 0x1A } }; //572DED96-9C60-4526-8F92-EE7D91D38C1A\n\n// Simple RAII for COM initialization\nstruct ComInitialization\n{\n    ComInitialization()\n    {\n        winrt::check_hresult(CoInitialize(nullptr));\n    }\n\n    ~ComInitialization()\n    {\n        CoUninitialize();\n    }\n};\n\n// Lists all installed packages\nint main()\n{\n    ComInitialization comInitialization;\n\n    auto packageManager = winrt::create_instance<PackageManager>(CLSID_PackageManager, CLSCTX_ALL);\n\n    auto installedCatalogConnectResult = packageManager.GetLocalPackageCatalog(LocalPackageCatalog::InstalledPackages).Connect();\n    if (installedCatalogConnectResult.Status() != ConnectResultStatus::Ok)\n    {\n        std::wcerr << L\"Error connecting to catalog\" << std::endl;\n        return E_FAIL;\n    }\n    auto installedCatalog = installedCatalogConnectResult.PackageCatalog();\n\n    auto findOptions = winrt::create_instance<FindPackagesOptions>(CLSID_FindPackagesOptions, CLSCTX_ALL);\n    auto searchResult = installedCatalog.FindPackages(findOptions);\n    if (searchResult.Status() != FindPackagesResultStatus::Ok)\n    {\n        std::wcerr << L\"Error finding packages\" << std::endl;\n        return E_FAIL;\n    }\n\n    for (auto package : searchResult.Matches())\n    {\n        std::wcout << L\"Found package: \" << package.CatalogPackage().Id().c_str() << std::endl;\n    }\n}\n"
  },
  {
    "path": "samples/MinimalCallers/C++/WinGet-InProc/WinGet-InProc.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240405.15\\build\\native\\Microsoft.Windows.CppWinRT.props\" Condition=\"Exists('..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240405.15\\build\\native\\Microsoft.Windows.CppWinRT.props')\" />\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|ARM64\">\n      <Configuration>Debug</Configuration>\n      <Platform>ARM64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|ARM64\">\n      <Configuration>Release</Configuration>\n      <Platform>ARM64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <VCProjectVersion>17.0</VCProjectVersion>\n    <Keyword>Win32Proj</Keyword>\n    <ProjectGuid>{925454b7-a3fa-40c9-806a-4b64d5764157}</ProjectGuid>\n    <RootNamespace>WinGetInProc</RootNamespace>\n    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>\n    <ProjectName>C++_WinGet_InProc</ProjectName>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)'=='Debug'\" Label=\"Configuration\">\n    <UseDebugLibraries>true</UseDebugLibraries>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)'=='Release'\" Label=\"Configuration\">\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"Shared\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <ItemDefinitionGroup>\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <SDLCheck>true</SDLCheck>\n      <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ConformanceMode>true</ConformanceMode>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Platform)'=='Win32'\">\n    <ClCompile>\n      <PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Debug'\">\n    <ClCompile>\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Release'\">\n    <ClCompile>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"WinGet-InProc.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <!-- Reference the .winmd so that it can be processed by CppWinRT -->\n  <ItemGroup>\n    <Reference Include=\"Microsoft.Management.Deployment\">\n      <HintPath>..\\..\\packages\\Microsoft.WindowsPackageManager.InProcCom.1.10.340\\lib\\Microsoft.Management.Deployment.winmd</HintPath>\n      <IsWinMDFile>true</IsWinMDFile>\n    </Reference>\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n    <Import Project=\"..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240405.15\\build\\native\\Microsoft.Windows.CppWinRT.targets\" Condition=\"Exists('..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240405.15\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" />\n  </ImportGroup>\n  <Target Name=\"EnsureNuGetPackageBuildImports\" BeforeTargets=\"PrepareForBuild\">\n    <PropertyGroup>\n      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>\n    </PropertyGroup>\n    <Error Condition=\"!Exists('..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240405.15\\build\\native\\Microsoft.Windows.CppWinRT.props')\" Text=\"$([System.String]::Format('$(ErrorText)', '..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240405.15\\build\\native\\Microsoft.Windows.CppWinRT.props'))\" />\n    <Error Condition=\"!Exists('..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240405.15\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240405.15\\build\\native\\Microsoft.Windows.CppWinRT.targets'))\" />\n  </Target>\n</Project>"
  },
  {
    "path": "samples/MinimalCallers/C++/WinGet-InProc/WinGet-InProc.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"WinGet-InProc.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "samples/MinimalCallers/C++/WinGet-InProc/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Microsoft.Windows.CppWinRT\" version=\"2.0.240405.15\" targetFramework=\"native\" />\n  <package id=\"Microsoft.WindowsPackageManager.InProcCom\" version=\"1.10.340\" targetFramework=\"native\" />\n</packages>"
  },
  {
    "path": "samples/MinimalCallers/C++/WinGet-OutOfProc/WinGet-OutOfProc.cpp",
    "content": "#include <Windows.h>\n\n#include <winrt/Microsoft.Management.Deployment.h>\n#include <winrt/Windows.Foundation.Collections.h>\n\n#include <iostream>\n\nusing namespace winrt::Microsoft::Management::Deployment;\n\nconst CLSID CLSID_PackageManager = { 0xC53A4F16, 0x787E, 0x42A4, 0xB3, 0x04, 0x29, 0xEF, 0xFB, 0x4B, 0xF5, 0x97 };  //C53A4F16-787E-42A4-B304-29EFFB4BF597\nconst CLSID CLSID_FindPackagesOptions = { 0x572DED96, 0x9C60, 0x4526, { 0x8F, 0x92, 0xEE, 0x7D, 0x91, 0xD3, 0x8C, 0x1A } }; //572DED96-9C60-4526-8F92-EE7D91D38C1A\n\n// Simple RAII for COM initialization\nstruct ComInitialization\n{\n    ComInitialization()\n    {\n        winrt::check_hresult(CoInitialize(nullptr));\n    }\n\n    ~ComInitialization()\n    {\n        CoUninitialize();\n    }\n};\n\n// Lists all installed packages\nint main()\n{\n    ComInitialization comInitialization;\n\n    auto packageManager = winrt::create_instance<PackageManager>(CLSID_PackageManager, CLSCTX_ALL);\n\n    auto installedCatalogConnectResult = packageManager.GetLocalPackageCatalog(LocalPackageCatalog::InstalledPackages).Connect();\n    if (installedCatalogConnectResult.Status() != ConnectResultStatus::Ok)\n    {\n        std::wcerr << L\"Error connecting to catalog\" << std::endl;\n        return E_FAIL;\n    }\n    auto installedCatalog = installedCatalogConnectResult.PackageCatalog();\n\n    auto findOptions = winrt::create_instance<FindPackagesOptions>(CLSID_FindPackagesOptions, CLSCTX_ALL);\n    auto searchResult = installedCatalog.FindPackages(findOptions);\n    if (searchResult.Status() != FindPackagesResultStatus::Ok)\n    {\n        std::wcerr << L\"Error finding packages\" << std::endl;\n        return E_FAIL;\n    }\n\n    for (auto package : searchResult.Matches())\n    {\n        std::wcout << L\"Found package: \" << package.CatalogPackage().Id().c_str() << std::endl;\n    }\n}\n"
  },
  {
    "path": "samples/MinimalCallers/C++/WinGet-OutOfProc/WinGet-OutOfProc.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240405.15\\build\\native\\Microsoft.Windows.CppWinRT.props\" Condition=\"Exists('..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240405.15\\build\\native\\Microsoft.Windows.CppWinRT.props')\" />\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|ARM64\">\n      <Configuration>Debug</Configuration>\n      <Platform>ARM64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|ARM64\">\n      <Configuration>Release</Configuration>\n      <Platform>ARM64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <VCProjectVersion>17.0</VCProjectVersion>\n    <Keyword>Win32Proj</Keyword>\n    <ProjectGuid>{01cb5485-d1f3-421f-8e8a-7bc04b9ca037}</ProjectGuid>\n    <RootNamespace>WinGetOutOfProc</RootNamespace>\n    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>\n    <ProjectName>C++_WinGet_OutOfProc</ProjectName>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)'=='Debug'\" Label=\"Configuration\">\n    <UseDebugLibraries>true</UseDebugLibraries>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)'=='Release'\" Label=\"Configuration\">\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"Shared\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <ItemDefinitionGroup>\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <SDLCheck>true</SDLCheck>\n      <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ConformanceMode>true</ConformanceMode>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Platform)'=='Win32'\">\n    <ClCompile>\n      <PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Debug'\">\n    <ClCompile>\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Release'\">\n    <ClCompile>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"WinGet-OutOfProc.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <PropertyGroup>\n    <!-- Use one of static, dynamic, none -->\n    <MicrosoftManagementDeployment-FactoryLinkage>static</MicrosoftManagementDeployment-FactoryLinkage>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n    <Import Project=\"..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240405.15\\build\\native\\Microsoft.Windows.CppWinRT.targets\" Condition=\"Exists('..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240405.15\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" />\n    <Import Project=\"..\\..\\packages\\Microsoft.WindowsPackageManager.ComInterop.1.10.340\\build\\native\\Microsoft.WindowsPackageManager.ComInterop.targets\" Condition=\"Exists('..\\..\\packages\\Microsoft.WindowsPackageManager.ComInterop.1.10.340\\build\\native\\Microsoft.WindowsPackageManager.ComInterop.targets')\" />\n  </ImportGroup>\n  <Target Name=\"EnsureNuGetPackageBuildImports\" BeforeTargets=\"PrepareForBuild\">\n    <PropertyGroup>\n      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>\n    </PropertyGroup>\n    <Error Condition=\"!Exists('..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240405.15\\build\\native\\Microsoft.Windows.CppWinRT.props')\" Text=\"$([System.String]::Format('$(ErrorText)', '..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240405.15\\build\\native\\Microsoft.Windows.CppWinRT.props'))\" />\n    <Error Condition=\"!Exists('..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240405.15\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240405.15\\build\\native\\Microsoft.Windows.CppWinRT.targets'))\" />\n    <Error Condition=\"!Exists('..\\..\\packages\\Microsoft.WindowsPackageManager.ComInterop.1.10.340\\build\\native\\Microsoft.WindowsPackageManager.ComInterop.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '..\\..\\packages\\Microsoft.WindowsPackageManager.ComInterop.1.10.340\\build\\native\\Microsoft.WindowsPackageManager.ComInterop.targets'))\" />\n  </Target>\n</Project>"
  },
  {
    "path": "samples/MinimalCallers/C++/WinGet-OutOfProc/WinGet-OutOfProc.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"WinGet-OutOfProc.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "samples/MinimalCallers/C++/WinGet-OutOfProc/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Microsoft.Windows.CppWinRT\" version=\"2.0.240405.15\" targetFramework=\"native\" />\n  <package id=\"Microsoft.WindowsPackageManager.ComInterop\" version=\"1.10.340\" targetFramework=\"native\" />\n</packages>"
  },
  {
    "path": "samples/MinimalCallers/MinimalCallers.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.12.35527.113\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Solution Items\", \"Solution Items\", \"{ABB7C5E7-2192-4D33-9130-BBB951BF9284}\"\n\tProjectSection(SolutionItems) = preProject\n\t\tREADME.md = README.md\n\tEndProjectSection\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"C#\", \"C#\", \"{FD31D4E6-4934-4273-B5A3-C89CF7197E93}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"C#_WinGet_OutOfProc\", \"C#\\WinGet-OutOfProc\\C#_WinGet_OutOfProc.csproj\", \"{A7CC8A07-02FC-4035-848F-1EBECCCE9C07}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"C#_WinGet_InProc\", \"C#\\WinGet-InProc\\C#_WinGet_InProc.csproj\", \"{DD80F640-5071-4200-9BDE-620FBDFF1725}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"C#_Configuration_InProc\", \"C#\\Configuration-InProc\\C#_Configuration_InProc.csproj\", \"{B44C18DE-FE76-4D30-B740-25A5AD99257F}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"C#_Configuration_OutOfProc\", \"C#\\Configuration-OutOfProc\\C#_Configuration_OutOfProc.csproj\", \"{93B5C28B-04AC-4B35-9253-81C1405D9A72}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"C++\", \"C++\", \"{41D22958-B935-4B37-A3BA-9E60441CE3E9}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"C++_WinGet_InProc\", \"C++\\WinGet-InProc\\WinGet-InProc.vcxproj\", \"{925454B7-A3FA-40C9-806A-4B64D5764157}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"C++_WinGet_OutOfProc\", \"C++\\WinGet-OutOfProc\\WinGet-OutOfProc.vcxproj\", \"{01CB5485-D1F3-421F-8E8A-7BC04B9CA037}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|ARM64 = Debug|ARM64\n\t\tDebug|x64 = Debug|x64\n\t\tDebug|x86 = Debug|x86\n\t\tRelease|ARM64 = Release|ARM64\n\t\tRelease|x64 = Release|x64\n\t\tRelease|x86 = Release|x86\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{A7CC8A07-02FC-4035-848F-1EBECCCE9C07}.Debug|ARM64.ActiveCfg = Debug|ARM64\n\t\t{A7CC8A07-02FC-4035-848F-1EBECCCE9C07}.Debug|ARM64.Build.0 = Debug|ARM64\n\t\t{A7CC8A07-02FC-4035-848F-1EBECCCE9C07}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{A7CC8A07-02FC-4035-848F-1EBECCCE9C07}.Debug|x64.Build.0 = Debug|x64\n\t\t{A7CC8A07-02FC-4035-848F-1EBECCCE9C07}.Debug|x86.ActiveCfg = Debug|x86\n\t\t{A7CC8A07-02FC-4035-848F-1EBECCCE9C07}.Debug|x86.Build.0 = Debug|x86\n\t\t{A7CC8A07-02FC-4035-848F-1EBECCCE9C07}.Release|ARM64.ActiveCfg = Release|ARM64\n\t\t{A7CC8A07-02FC-4035-848F-1EBECCCE9C07}.Release|ARM64.Build.0 = Release|ARM64\n\t\t{A7CC8A07-02FC-4035-848F-1EBECCCE9C07}.Release|x64.ActiveCfg = Release|x64\n\t\t{A7CC8A07-02FC-4035-848F-1EBECCCE9C07}.Release|x64.Build.0 = Release|x64\n\t\t{A7CC8A07-02FC-4035-848F-1EBECCCE9C07}.Release|x86.ActiveCfg = Release|x86\n\t\t{A7CC8A07-02FC-4035-848F-1EBECCCE9C07}.Release|x86.Build.0 = Release|x86\n\t\t{DD80F640-5071-4200-9BDE-620FBDFF1725}.Debug|ARM64.ActiveCfg = Debug|ARM64\n\t\t{DD80F640-5071-4200-9BDE-620FBDFF1725}.Debug|ARM64.Build.0 = Debug|ARM64\n\t\t{DD80F640-5071-4200-9BDE-620FBDFF1725}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{DD80F640-5071-4200-9BDE-620FBDFF1725}.Debug|x64.Build.0 = Debug|x64\n\t\t{DD80F640-5071-4200-9BDE-620FBDFF1725}.Debug|x86.ActiveCfg = Debug|x86\n\t\t{DD80F640-5071-4200-9BDE-620FBDFF1725}.Debug|x86.Build.0 = Debug|x86\n\t\t{DD80F640-5071-4200-9BDE-620FBDFF1725}.Release|ARM64.ActiveCfg = Release|ARM64\n\t\t{DD80F640-5071-4200-9BDE-620FBDFF1725}.Release|ARM64.Build.0 = Release|ARM64\n\t\t{DD80F640-5071-4200-9BDE-620FBDFF1725}.Release|x64.ActiveCfg = Release|x64\n\t\t{DD80F640-5071-4200-9BDE-620FBDFF1725}.Release|x64.Build.0 = Release|x64\n\t\t{DD80F640-5071-4200-9BDE-620FBDFF1725}.Release|x86.ActiveCfg = Release|x86\n\t\t{DD80F640-5071-4200-9BDE-620FBDFF1725}.Release|x86.Build.0 = Release|x86\n\t\t{B44C18DE-FE76-4D30-B740-25A5AD99257F}.Debug|ARM64.ActiveCfg = Debug|ARM64\n\t\t{B44C18DE-FE76-4D30-B740-25A5AD99257F}.Debug|ARM64.Build.0 = Debug|ARM64\n\t\t{B44C18DE-FE76-4D30-B740-25A5AD99257F}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{B44C18DE-FE76-4D30-B740-25A5AD99257F}.Debug|x64.Build.0 = Debug|x64\n\t\t{B44C18DE-FE76-4D30-B740-25A5AD99257F}.Debug|x86.ActiveCfg = Debug|x86\n\t\t{B44C18DE-FE76-4D30-B740-25A5AD99257F}.Debug|x86.Build.0 = Debug|x86\n\t\t{B44C18DE-FE76-4D30-B740-25A5AD99257F}.Release|ARM64.ActiveCfg = Release|ARM64\n\t\t{B44C18DE-FE76-4D30-B740-25A5AD99257F}.Release|ARM64.Build.0 = Release|ARM64\n\t\t{B44C18DE-FE76-4D30-B740-25A5AD99257F}.Release|x64.ActiveCfg = Release|x64\n\t\t{B44C18DE-FE76-4D30-B740-25A5AD99257F}.Release|x64.Build.0 = Release|x64\n\t\t{B44C18DE-FE76-4D30-B740-25A5AD99257F}.Release|x86.ActiveCfg = Release|x86\n\t\t{B44C18DE-FE76-4D30-B740-25A5AD99257F}.Release|x86.Build.0 = Release|x86\n\t\t{93B5C28B-04AC-4B35-9253-81C1405D9A72}.Debug|ARM64.ActiveCfg = Debug|ARM64\n\t\t{93B5C28B-04AC-4B35-9253-81C1405D9A72}.Debug|ARM64.Build.0 = Debug|ARM64\n\t\t{93B5C28B-04AC-4B35-9253-81C1405D9A72}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{93B5C28B-04AC-4B35-9253-81C1405D9A72}.Debug|x64.Build.0 = Debug|x64\n\t\t{93B5C28B-04AC-4B35-9253-81C1405D9A72}.Debug|x86.ActiveCfg = Debug|x86\n\t\t{93B5C28B-04AC-4B35-9253-81C1405D9A72}.Debug|x86.Build.0 = Debug|x86\n\t\t{93B5C28B-04AC-4B35-9253-81C1405D9A72}.Release|ARM64.ActiveCfg = Release|ARM64\n\t\t{93B5C28B-04AC-4B35-9253-81C1405D9A72}.Release|ARM64.Build.0 = Release|ARM64\n\t\t{93B5C28B-04AC-4B35-9253-81C1405D9A72}.Release|x64.ActiveCfg = Release|x64\n\t\t{93B5C28B-04AC-4B35-9253-81C1405D9A72}.Release|x64.Build.0 = Release|x64\n\t\t{93B5C28B-04AC-4B35-9253-81C1405D9A72}.Release|x86.ActiveCfg = Release|x86\n\t\t{93B5C28B-04AC-4B35-9253-81C1405D9A72}.Release|x86.Build.0 = Release|x86\n\t\t{925454B7-A3FA-40C9-806A-4B64D5764157}.Debug|ARM64.ActiveCfg = Debug|ARM64\n\t\t{925454B7-A3FA-40C9-806A-4B64D5764157}.Debug|ARM64.Build.0 = Debug|ARM64\n\t\t{925454B7-A3FA-40C9-806A-4B64D5764157}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{925454B7-A3FA-40C9-806A-4B64D5764157}.Debug|x64.Build.0 = Debug|x64\n\t\t{925454B7-A3FA-40C9-806A-4B64D5764157}.Debug|x86.ActiveCfg = Debug|Win32\n\t\t{925454B7-A3FA-40C9-806A-4B64D5764157}.Debug|x86.Build.0 = Debug|Win32\n\t\t{925454B7-A3FA-40C9-806A-4B64D5764157}.Release|ARM64.ActiveCfg = Release|ARM64\n\t\t{925454B7-A3FA-40C9-806A-4B64D5764157}.Release|ARM64.Build.0 = Release|ARM64\n\t\t{925454B7-A3FA-40C9-806A-4B64D5764157}.Release|x64.ActiveCfg = Release|x64\n\t\t{925454B7-A3FA-40C9-806A-4B64D5764157}.Release|x64.Build.0 = Release|x64\n\t\t{925454B7-A3FA-40C9-806A-4B64D5764157}.Release|x86.ActiveCfg = Release|Win32\n\t\t{925454B7-A3FA-40C9-806A-4B64D5764157}.Release|x86.Build.0 = Release|Win32\n\t\t{01CB5485-D1F3-421F-8E8A-7BC04B9CA037}.Debug|ARM64.ActiveCfg = Debug|ARM64\n\t\t{01CB5485-D1F3-421F-8E8A-7BC04B9CA037}.Debug|ARM64.Build.0 = Debug|ARM64\n\t\t{01CB5485-D1F3-421F-8E8A-7BC04B9CA037}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{01CB5485-D1F3-421F-8E8A-7BC04B9CA037}.Debug|x64.Build.0 = Debug|x64\n\t\t{01CB5485-D1F3-421F-8E8A-7BC04B9CA037}.Debug|x86.ActiveCfg = Debug|Win32\n\t\t{01CB5485-D1F3-421F-8E8A-7BC04B9CA037}.Debug|x86.Build.0 = Debug|Win32\n\t\t{01CB5485-D1F3-421F-8E8A-7BC04B9CA037}.Release|ARM64.ActiveCfg = Release|ARM64\n\t\t{01CB5485-D1F3-421F-8E8A-7BC04B9CA037}.Release|ARM64.Build.0 = Release|ARM64\n\t\t{01CB5485-D1F3-421F-8E8A-7BC04B9CA037}.Release|x64.ActiveCfg = Release|x64\n\t\t{01CB5485-D1F3-421F-8E8A-7BC04B9CA037}.Release|x64.Build.0 = Release|x64\n\t\t{01CB5485-D1F3-421F-8E8A-7BC04B9CA037}.Release|x86.ActiveCfg = Release|Win32\n\t\t{01CB5485-D1F3-421F-8E8A-7BC04B9CA037}.Release|x86.Build.0 = Release|Win32\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(NestedProjects) = preSolution\n\t\t{A7CC8A07-02FC-4035-848F-1EBECCCE9C07} = {FD31D4E6-4934-4273-B5A3-C89CF7197E93}\n\t\t{DD80F640-5071-4200-9BDE-620FBDFF1725} = {FD31D4E6-4934-4273-B5A3-C89CF7197E93}\n\t\t{B44C18DE-FE76-4D30-B740-25A5AD99257F} = {FD31D4E6-4934-4273-B5A3-C89CF7197E93}\n\t\t{93B5C28B-04AC-4B35-9253-81C1405D9A72} = {FD31D4E6-4934-4273-B5A3-C89CF7197E93}\n\t\t{925454B7-A3FA-40C9-806A-4B64D5764157} = {41D22958-B935-4B37-A3BA-9E60441CE3E9}\n\t\t{01CB5485-D1F3-421F-8E8A-7BC04B9CA037} = {41D22958-B935-4B37-A3BA-9E60441CE3E9}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "samples/MinimalCallers/README.md",
    "content": "# Sample projects for COM APIs\n\nThese are minimal samples for using the winget COM APIs in C++ and C#. The samples are mostly centered around the required project settings. For a more fleshed out example, see [`/Samples/WinGetUWPCaller`](https://github.com/microsoft/winget-cli/tree/master/samples/WinGetUWPCaller)."
  },
  {
    "path": "samples/WinGetUWPCaller/WinGetUWPCaller/ActivePackageView.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"ActivePackageView.h\"\n#include \"ActivePackageView.g.cpp\"\n#include <winrt/Windows.UI.Core.h>\n\nnamespace winrt::WinGetUWPCaller::implementation\n{\n    Microsoft::Management::Deployment::CatalogPackage ActivePackageView::Package()\n    {\n        return m_package;\n    }\n\n    void ActivePackageView::Package(Microsoft::Management::Deployment::CatalogPackage const& value)\n    {\n        m_package = value;\n    }\n\n    ActivePackageView::AsyncOperation_t ActivePackageView::AsyncOperation()\n    {\n        return m_asyncOperation;\n    }\n\n    Windows::Foundation::IAsyncAction UpdateUIProgress(\n        Microsoft::Management::Deployment::InstallProgress progress,\n        WinGetUWPCaller::ActivePackageView view)\n    {\n        co_await resume_foreground(view.Dispatcher());\n        view.Progress(progress.DownloadProgress * 100);\n    }\n\n    void ActivePackageView::AsyncOperation(ActivePackageView::AsyncOperation_t const& value)\n    {\n        m_asyncOperation = value;\n        m_asyncOperation.Progress([=](\n            ActivePackageView::AsyncOperation_t const& /* sender */,\n            Microsoft::Management::Deployment::InstallProgress const& progress)\n            {\n                UpdateUIProgress(progress, *this);\n            });\n    }\n\n    double ActivePackageView::Progress()\n    {\n        return m_progress;\n    }\n\n    void ActivePackageView::Progress(double value)\n    {\n        if (m_progress != value)\n        {\n            m_progress = value;\n            m_propertyChanged(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L\"Progress\" });\n        }\n    }\n\n    hstring ActivePackageView::StatusText()\n    {\n        return m_text;\n    }\n\n    void ActivePackageView::StatusText(hstring const& value)\n    {\n        m_text = value;\n    }\n\n    Windows::UI::Core::CoreDispatcher ActivePackageView::Dispatcher()\n    {\n        return m_dispatcher;\n    }\n\n    void ActivePackageView::Dispatcher(Windows::UI::Core::CoreDispatcher const& value)\n    {\n        m_dispatcher = value;\n    }\n\n    event_token ActivePackageView::PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& handler)\n    {\n        return m_propertyChanged.add(handler);\n    }\n\n    void ActivePackageView::PropertyChanged(event_token const& token)\n    {\n        m_propertyChanged.remove(token);\n    }\n}\n"
  },
  {
    "path": "samples/WinGetUWPCaller/WinGetUWPCaller/ActivePackageView.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"ActivePackageView.g.h\"\n\nnamespace winrt::WinGetUWPCaller::implementation\n{\n    struct ActivePackageView : ActivePackageViewT<ActivePackageView>\n    {\n        using AsyncOperation_t = Windows::Foundation::IAsyncOperationWithProgress<Microsoft::Management::Deployment::InstallResult, Microsoft::Management::Deployment::InstallProgress>;\n\n        ActivePackageView() = default;\n\n        Microsoft::Management::Deployment::CatalogPackage Package();\n        void Package(Microsoft::Management::Deployment::CatalogPackage const& value);\n        AsyncOperation_t AsyncOperation();\n        void AsyncOperation(AsyncOperation_t const& value);\n        double Progress();\n        void Progress(double value);\n        hstring StatusText();\n        void StatusText(hstring const& value);\n        Windows::UI::Core::CoreDispatcher Dispatcher();\n        void Dispatcher(Windows::UI::Core::CoreDispatcher const& value);\n        event_token PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& value);\n        void PropertyChanged(event_token const& token);\n\n    private:\n        Microsoft::Management::Deployment::CatalogPackage m_package{ nullptr };\n        AsyncOperation_t m_asyncOperation{ nullptr };\n        double m_progress = 0;\n        hstring m_text;\n        Windows::UI::Core::CoreDispatcher m_dispatcher{ nullptr };\n        event<Windows::UI::Xaml::Data::PropertyChangedEventHandler> m_propertyChanged;\n    };\n}\n\nnamespace winrt::WinGetUWPCaller::factory_implementation\n{\n    struct ActivePackageView : ActivePackageViewT<ActivePackageView, implementation::ActivePackageView>\n    {\n    };\n}\n"
  },
  {
    "path": "samples/WinGetUWPCaller/WinGetUWPCaller/App.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n\r\n#include \"App.h\"\r\n#include \"MainPage.h\"\r\n\r\nusing namespace winrt;\r\nusing namespace Windows::ApplicationModel;\r\nusing namespace Windows::ApplicationModel::Activation;\r\nusing namespace Windows::Foundation;\r\nusing namespace Windows::UI::Xaml;\r\nusing namespace Windows::UI::Xaml::Controls;\r\nusing namespace Windows::UI::Xaml::Navigation;\r\nusing namespace WinGetUWPCaller;\r\nusing namespace WinGetUWPCaller::implementation;\r\n\r\n/// <summary>\r\n/// Initializes the singleton application object.  This is the first line of authored code\r\n/// executed, and as such is the logical equivalent of main() or WinMain().\r\n/// </summary>\r\nApp::App()\r\n{\r\n    InitializeComponent();\r\n    Suspending({ this, &App::OnSuspending });\r\n\r\n#if defined _DEBUG && !defined DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION\r\n    UnhandledException([this](IInspectable const&, UnhandledExceptionEventArgs const& e)\r\n    {\r\n        if (IsDebuggerPresent())\r\n        {\r\n            auto errorMessage = e.Message();\r\n            __debugbreak();\r\n        }\r\n    });\r\n#endif\r\n}\r\n\r\n/// <summary>\r\n/// Invoked when the application is launched normally by the end user.  Other entry points\r\n/// will be used such as when the application is launched to open a specific file.\r\n/// </summary>\r\n/// <param name=\"e\">Details about the launch request and process.</param>\r\nvoid App::OnLaunched(LaunchActivatedEventArgs const& e)\r\n{\r\n    Frame rootFrame{ nullptr };\r\n    auto content = Window::Current().Content();\r\n    if (content)\r\n    {\r\n        rootFrame = content.try_as<Frame>();\r\n    }\r\n\r\n    // Do not repeat app initialization when the Window already has content,\r\n    // just ensure that the window is active\r\n    if (rootFrame == nullptr)\r\n    {\r\n        // Create a Frame to act as the navigation context and associate it with\r\n        // a SuspensionManager key\r\n        rootFrame = Frame();\r\n\r\n        rootFrame.NavigationFailed({ this, &App::OnNavigationFailed });\r\n\r\n        if (e.PreviousExecutionState() == ApplicationExecutionState::Terminated)\r\n        {\r\n            // Restore the saved session state only when appropriate, scheduling the\r\n            // final launch steps after the restore is complete\r\n        }\r\n\r\n        if (e.PrelaunchActivated() == false)\r\n        {\r\n            if (rootFrame.Content() == nullptr)\r\n            {\r\n                // When the navigation stack isn't restored navigate to the first page,\r\n                // configuring the new page by passing required information as a navigation\r\n                // parameter\r\n                rootFrame.Navigate(xaml_typename<WinGetUWPCaller::MainPage>(), box_value(e.Arguments()));\r\n            }\r\n            // Place the frame in the current Window\r\n            Window::Current().Content(rootFrame);\r\n            // Ensure the current window is active\r\n            Window::Current().Activate();\r\n        }\r\n    }\r\n    else\r\n    {\r\n        if (e.PrelaunchActivated() == false)\r\n        {\r\n            if (rootFrame.Content() == nullptr)\r\n            {\r\n                // When the navigation stack isn't restored navigate to the first page,\r\n                // configuring the new page by passing required information as a navigation\r\n                // parameter\r\n                rootFrame.Navigate(xaml_typename<WinGetUWPCaller::MainPage>(), box_value(e.Arguments()));\r\n            }\r\n            // Ensure the current window is active\r\n            Window::Current().Activate();\r\n        }\r\n    }\r\n}\r\n\r\n/// <summary>\r\n/// Invoked when application execution is being suspended.  Application state is saved\r\n/// without knowing whether the application will be terminated or resumed with the contents\r\n/// of memory still intact.\r\n/// </summary>\r\n/// <param name=\"sender\">The source of the suspend request.</param>\r\n/// <param name=\"e\">Details about the suspend request.</param>\r\nvoid App::OnSuspending([[maybe_unused]] IInspectable const& sender, [[maybe_unused]] SuspendingEventArgs const& e)\r\n{\r\n    // Save application state and stop any background activity\r\n}\r\n\r\n/// <summary>\r\n/// Invoked when Navigation to a certain page fails\r\n/// </summary>\r\n/// <param name=\"sender\">The Frame which failed navigation</param>\r\n/// <param name=\"e\">Details about the navigation failure</param>\r\nvoid App::OnNavigationFailed(IInspectable const&, NavigationFailedEventArgs const& e)\r\n{\r\n    throw hresult_error(E_FAIL, hstring(L\"Failed to load Page \") + e.SourcePageType().Name);\r\n}\r\n"
  },
  {
    "path": "samples/WinGetUWPCaller/WinGetUWPCaller/App.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"App.xaml.g.h\"\n\nnamespace winrt::WinGetUWPCaller::implementation\n{\n    struct App : AppT<App>\n    {\n        App();\n\n        void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs const&);\n        void OnSuspending(IInspectable const&, Windows::ApplicationModel::SuspendingEventArgs const&);\n        void OnNavigationFailed(IInspectable const&, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs const&);\n    };\n}\n"
  },
  {
    "path": "samples/WinGetUWPCaller/WinGetUWPCaller/App.idl",
    "content": "namespace WinGetUWPCaller\n{\n}\n"
  },
  {
    "path": "samples/WinGetUWPCaller/WinGetUWPCaller/App.xaml",
    "content": "<!-- Copyright (c) Microsoft Corporation.\r\n     Licensed under the MIT License. -->\r\n<Application\r\n    x:Class=\"WinGetUWPCaller.App\"\r\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\r\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\r\n    xmlns:local=\"using:WinGetUWPCaller\">\r\n\r\n</Application>\r\n"
  },
  {
    "path": "samples/WinGetUWPCaller/WinGetUWPCaller/MainPage.cpp",
    "content": "#include \"pch.h\"\r\n#include \"MainPage.h\"\r\n#include \"MainPage.g.cpp\"\r\n\r\n#include <winrt/Microsoft.Management.Deployment.h>\r\n\r\nusing namespace std::chrono_literals;\r\nusing namespace std::string_view_literals;\r\nusing namespace winrt::Microsoft::Management::Deployment;\r\n\r\nnamespace winrt\r\n{\r\n    using namespace Windows::UI::Xaml;\r\n    using namespace Windows::Foundation;\r\n    using namespace Windows::Foundation::Collections;\r\n}\r\n\r\nnamespace winrt::WinGetUWPCaller::implementation\r\n{\r\n    namespace\r\n    {\r\n        std::wstring ConvertExceptionToStatusString(std::wstring_view context, std::exception_ptr exceptionPtr)\r\n        {\r\n            std::wostringstream result;\r\n\r\n            try\r\n            {\r\n                std::rethrow_exception(exceptionPtr);\r\n            }\r\n            catch (const winrt::hresult_error& error)\r\n            {\r\n                result << context << L\" :: \" << L\"0x\" << std::hex << std::setw(8) << std::setfill(L'0') << error.code() << L\": \" << static_cast<std::wstring_view>(error.message());\r\n            }\r\n            catch (const std::exception& exception)\r\n            {\r\n                result << context << L\" :: \" << exception.what();\r\n            }\r\n            catch (...)\r\n            {\r\n                result << context << L\" :: Unknown exception\";\r\n            }\r\n\r\n            return std::move(result).str();\r\n        }\r\n\r\n        template <typename Operation>\r\n        std::wstring RunAndReturnStatus(std::wstring_view context, Operation&& operation)\r\n        {\r\n            try\r\n            {\r\n                operation();\r\n            }\r\n            catch (...)\r\n            {\r\n                return ConvertExceptionToStatusString(context, std::current_exception());\r\n            }\r\n\r\n            return {};\r\n        }\r\n\r\n        // Helper object to control button states and status text.\r\n        struct BackgroundActionData\r\n        {\r\n            // This object should be constructed on the foreground thread.\r\n            // disabledButtons will be disabled during the operation.\r\n            // enabledButtons will be enabled during the operation.\r\n            // statusText will be updated with the result.\r\n            BackgroundActionData(\r\n                std::initializer_list<Windows::UI::Xaml::Controls::Button> disabledButtons,\r\n                Windows::UI::Xaml::Controls::TextBlock statusText) :\r\n                m_disabledButtons(disabledButtons),\r\n                m_statusText(statusText)\r\n            {\r\n                if (m_disabledButtons.empty())\r\n                {\r\n                    throw std::exception(\"Must specify at least one disabled button.\");\r\n                }\r\n\r\n                for (const auto& button : m_disabledButtons)\r\n                {\r\n                    button.IsEnabled(false);\r\n                }\r\n\r\n                m_statusText.Text(L\"\");\r\n            }\r\n\r\n            BackgroundActionData(\r\n                std::initializer_list<Windows::UI::Xaml::Controls::Button> disabledButtons,\r\n                std::initializer_list<Windows::UI::Xaml::Controls::Button> enabledButtons,\r\n                Windows::UI::Xaml::Controls::TextBlock statusText) :\r\n                BackgroundActionData(disabledButtons, statusText)\r\n            {\r\n                m_enabledButtons = enabledButtons;\r\n                for (const auto& button : m_enabledButtons)\r\n                {\r\n                    button.IsEnabled(true);\r\n                }\r\n            }\r\n\r\n            // This should be run on the foreground thread.\r\n            void Finalize() const\r\n            {\r\n                for (const auto& button : m_disabledButtons)\r\n                {\r\n                    button.IsEnabled(true);\r\n                }\r\n\r\n                for (const auto& button : m_enabledButtons)\r\n                {\r\n                    button.IsEnabled(false);\r\n                }\r\n\r\n                m_statusText.Text(m_status);\r\n            }\r\n\r\n            template <typename Operation>\r\n            void RunAndCatchStatus(std::wstring_view context, Operation&& operation)\r\n            {\r\n                if (m_status.empty())\r\n                {\r\n                    m_status = RunAndReturnStatus(context, operation);\r\n                }\r\n            }\r\n\r\n            void Status(std::wstring&& value)\r\n            {\r\n                m_status = std::move(value);\r\n            }\r\n\r\n            bool Successful() const\r\n            {\r\n                return m_status.empty();\r\n            }\r\n\r\n            Windows::UI::Core::CoreDispatcher Dispatcher() const\r\n            {\r\n                return m_disabledButtons[0].Dispatcher();\r\n            }\r\n\r\n        private:\r\n            std::vector<Windows::UI::Xaml::Controls::Button> m_disabledButtons;\r\n            std::vector<Windows::UI::Xaml::Controls::Button> m_enabledButtons;\r\n            Windows::UI::Xaml::Controls::TextBlock m_statusText;\r\n            std::wstring m_status;\r\n        };\r\n\r\n        std::wstring MakeCompactByteString(uint64_t bytes)\r\n        {\r\n            static constexpr std::array<std::wstring_view, 4> s_sizeStrings = { L\"B\"sv, L\"KB\"sv, L\"MB\"sv, L\"GB\"sv };\r\n            static constexpr size_t s_sizeIncrement = 1000;\r\n\r\n            size_t sizeIndex = 0;\r\n            while (sizeIndex < s_sizeStrings.size() && bytes > s_sizeIncrement)\r\n            {\r\n                sizeIndex += 1;\r\n                bytes /= s_sizeIncrement;\r\n            }\r\n\r\n            return std::to_wstring(bytes).append(L\" \").append(s_sizeStrings[sizeIndex]);\r\n        }\r\n    }\r\n\r\n    MainPage::MainPage()\r\n    {\r\n        InitializeComponent();\r\n        m_packageCatalogs = winrt::single_threaded_observable_vector<PackageCatalogReference>();\r\n        m_installedPackages = winrt::single_threaded_observable_vector<CatalogPackage>();\r\n        m_activePackageViews = winrt::single_threaded_observable_vector<WinGetUWPCaller::ActivePackageView>();\r\n    }\r\n\r\n    Windows::Foundation::Collections::IObservableVector<Microsoft::Management::Deployment::PackageCatalogReference> MainPage::PackageCatalogs()\r\n    {\r\n        return m_packageCatalogs;\r\n    }\r\n\r\n    Windows::Foundation::Collections::IObservableVector<Microsoft::Management::Deployment::CatalogPackage> MainPage::InstalledPackages()\r\n    {\r\n        return m_installedPackages;\r\n    }\r\n\r\n    Windows::Foundation::Collections::IObservableVector<WinGetUWPCaller::ActivePackageView> MainPage::ActivePackages()\r\n    {\r\n        return m_activePackageViews;\r\n    }\r\n\r\n    void MainPage::LoadCatalogsButtonClickHandler(IInspectable const&, RoutedEventArgs const&)\r\n    {\r\n        LoadCatalogsAsync();\r\n    }\r\n\r\n    void MainPage::CatalogSelectionChangedHandler(Windows::Foundation::IInspectable const&, Windows::UI::Xaml::RoutedEventArgs const&)\r\n    {\r\n        m_catalog = nullptr;\r\n    }\r\n\r\n    void MainPage::SearchButtonClickHandler(IInspectable const&, RoutedEventArgs const&)\r\n    {\r\n        FindPackageAsync();\r\n    }\r\n\r\n    void MainPage::InstallButtonClickHandler(IInspectable const&, RoutedEventArgs const&)\r\n    {\r\n        if (m_packageOperation == nullptr || m_packageOperation.Status() != AsyncStatus::Started)\r\n        {\r\n            InstallOrUpgradeAsync(false);\r\n        }\r\n    }\r\n\r\n    void MainPage::UpgradeButtonClickHandler(IInspectable const&, RoutedEventArgs const&)\r\n    {\r\n        if (m_packageOperation == nullptr || m_packageOperation.Status() != AsyncStatus::Started)\r\n        {\r\n            InstallOrUpgradeAsync(true);\r\n        }\r\n    }\r\n\r\n    void MainPage::DownloadButtonClickHandler(IInspectable const&, RoutedEventArgs const&)\r\n    {\r\n        if (m_packageOperation == nullptr || m_packageOperation.Status() != AsyncStatus::Started)\r\n        {\r\n            DownloadAsync();\r\n        }\r\n    }\r\n\r\n    void MainPage::CancelButtonClickHandler(IInspectable const&, RoutedEventArgs const&)\r\n    {\r\n        if (m_packageOperation && m_packageOperation.Status() == AsyncStatus::Started)\r\n        {\r\n            m_packageOperation.Cancel();\r\n        }\r\n    }\r\n\r\n    void MainPage::RefreshInstalledButtonClickHandler(IInspectable const&, RoutedEventArgs const&)\r\n    {\r\n        GetInstalledPackagesAsync();\r\n    }\r\n\r\n    void MainPage::UninstallButtonClickHandler(IInspectable const&, RoutedEventArgs const&)\r\n    {\r\n        UninstallAsync();\r\n    }\r\n\r\n    void MainPage::RefreshActiveButtonClickHandler(IInspectable const&, RoutedEventArgs const&)\r\n    {\r\n        GetActivePackagesAsync();\r\n    }\r\n\r\n    std::wstring MainPage::EnsurePackageManager(bool forceRecreate)\r\n    {\r\n        std::lock_guard<std::mutex> lock{ m_packageManagerMutex };\r\n\r\n        std::wstring result;\r\n\r\n        if (!m_packageManager || forceRecreate)\r\n        {\r\n            result = RunAndReturnStatus(L\"Create PackageManager\", [&]() {\r\n                m_packageManager = PackageManager{};\r\n            });\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    IAsyncAction MainPage::LoadCatalogsAsync()\r\n    {\r\n        BackgroundActionData actionData{ { loadCatalogsButton() }, catalogStatusText() };\r\n\r\n        co_await winrt::resume_background();\r\n\r\n        actionData.Status(EnsurePackageManager(true));\r\n\r\n        decltype(m_packageManager.GetPackageCatalogs()) catalogs{ nullptr };\r\n        actionData.RunAndCatchStatus(L\"Load Catalogs\", [&]() {\r\n            catalogs = m_packageManager.GetPackageCatalogs();\r\n            });\r\n\r\n        co_await winrt::resume_foreground(actionData.Dispatcher());\r\n\r\n        m_packageCatalogs.Clear();\r\n\r\n        if (catalogs)\r\n        {\r\n            for (auto const catalog : catalogs)\r\n            {\r\n                m_packageCatalogs.Append(catalog);\r\n            }\r\n        }\r\n\r\n        actionData.Finalize();\r\n    }\r\n\r\n    IAsyncAction MainPage::FindPackageAsync()\r\n    {\r\n        hstring queryInput = queryTextBox().Text();\r\n        auto selectedItems = catalogsListBox().SelectedItems();\r\n        int32_t searchType = searchField().SelectedIndex();\r\n        PackageCatalog catalog = m_catalog;\r\n\r\n        BackgroundActionData actionData{ { searchButton() }, operationStatusText() };\r\n\r\n        co_await winrt::resume_background();\r\n\r\n        actionData.Status(EnsurePackageManager());\r\n\r\n        if (!catalog)\r\n        {\r\n            actionData.RunAndCatchStatus(L\"Connect catalog(s)\", [&]() {\r\n                PackageCatalogReference catalogReference{ nullptr };\r\n\r\n                if (selectedItems.Size() == 0)\r\n                {\r\n                    // If no items are selected, we use all implicit catalogs.\r\n                    CreateCompositePackageCatalogOptions createCompositePackageCatalogOptions;\r\n                    createCompositePackageCatalogOptions.CompositeSearchBehavior(CompositeSearchBehavior::RemotePackagesFromRemoteCatalogs);\r\n\r\n                    for (const auto& item : m_packageManager.GetPackageCatalogs())\r\n                    {\r\n                        if (!item.Info().Explicit())\r\n                        {\r\n                            createCompositePackageCatalogOptions.Catalogs().Append(item);\r\n                        }\r\n                    }\r\n\r\n                    catalogReference = m_packageManager.CreateCompositePackageCatalog(createCompositePackageCatalogOptions);\r\n                }\r\n                else if (selectedItems.Size() == 1)\r\n                {\r\n                    // If one items is selected, we can directly use this catalog.\r\n                    catalogReference = selectedItems.GetAt(0).as<PackageCatalogReference>();\r\n                }\r\n                else\r\n                {\r\n                    // If multiple items are selected, we create a composite catalog using those catalogs.\r\n                    CreateCompositePackageCatalogOptions createCompositePackageCatalogOptions;\r\n                    createCompositePackageCatalogOptions.CompositeSearchBehavior(CompositeSearchBehavior::RemotePackagesFromRemoteCatalogs);\r\n\r\n                    for (const auto& item : selectedItems)\r\n                    {\r\n                        createCompositePackageCatalogOptions.Catalogs().Append(item.as<PackageCatalogReference>());\r\n                    }\r\n\r\n                    catalogReference = m_packageManager.CreateCompositePackageCatalog(createCompositePackageCatalogOptions);\r\n                }\r\n\r\n                ConnectResult connectResult{ catalogReference.Connect() };\r\n\r\n                switch (connectResult.Status())\r\n                {\r\n                case ConnectResultStatus::Ok: break;\r\n                case ConnectResultStatus::CatalogError: throw std::exception{ \"Catalog connection error.\" };\r\n                case ConnectResultStatus::SourceAgreementsNotAccepted: throw std::exception{ \"Required catalog agreements not accepted.\" };\r\n                }\r\n\r\n                catalog = connectResult.PackageCatalog();\r\n            });\r\n        }\r\n\r\n        CatalogPackage package{ nullptr };\r\n\r\n        actionData.RunAndCatchStatus(L\"Find package\", [&]() {\r\n            FindPackagesOptions findPackagesOptions;\r\n            PackageMatchFilter filter;\r\n\r\n            switch (searchType)\r\n            {\r\n            case 0: // Generic query\r\n                filter.Field(PackageMatchField::CatalogDefault);\r\n                filter.Option(PackageFieldMatchOption::ContainsCaseInsensitive);\r\n                break;\r\n            case 1: // Identifier (case-insensitive)\r\n                filter.Field(PackageMatchField::Id);\r\n                filter.Option(PackageFieldMatchOption::EqualsCaseInsensitive);\r\n                break;\r\n            case 2: // Name (substring)\r\n                filter.Field(PackageMatchField::Name);\r\n                filter.Option(PackageFieldMatchOption::ContainsCaseInsensitive);\r\n                break;\r\n            }\r\n\r\n            filter.Value(queryInput);\r\n            findPackagesOptions.Selectors().Append(filter);\r\n            FindPackagesResult findPackagesResult = catalog.FindPackages(findPackagesOptions);\r\n\r\n            winrt::IVectorView<MatchResult> matches = findPackagesResult.Matches();\r\n            if (matches.Size() == 0)\r\n            {\r\n                throw std::exception{ \"No package found matching input\" };\r\n            }\r\n            else if (matches.Size() > 1)\r\n            {\r\n                throw std::exception{ \"Multiple packages found matching input; refine query.\" };\r\n            }\r\n            else\r\n            {\r\n                package = matches.GetAt(0).CatalogPackage();\r\n            }\r\n        });\r\n\r\n        if (package)\r\n        {\r\n            // Display the package name using the user's default localization information.\r\n            std::wostringstream stream;\r\n            stream << L\"Found package: \" <<\r\n                static_cast<std::wstring_view>(package.DefaultInstallVersion().GetCatalogPackageMetadata().PackageName()) << L\" [\" <<\r\n                static_cast<std::wstring_view>(package.Id()) << L\"]\";\r\n            actionData.Status(std::move(stream).str());\r\n        }\r\n\r\n        co_await winrt::resume_foreground(actionData.Dispatcher());\r\n\r\n        m_catalog = catalog;\r\n        m_package = package;\r\n\r\n        bool operationButtonsEnabled = static_cast<bool>(m_package);\r\n        installButton().IsEnabled(operationButtonsEnabled);\r\n        upgradeButton().IsEnabled(operationButtonsEnabled);\r\n        downloadButton().IsEnabled(operationButtonsEnabled);\r\n\r\n        actionData.Finalize();\r\n    }\r\n\r\n    IAsyncAction MainPage::InstallOrUpgradeAsync(bool upgrade)\r\n    {\r\n        PackageManager packageManager = m_packageManager;\r\n        CatalogPackage package = m_package;\r\n        auto progressBar = operationProgressBar();\r\n        auto statusText = operationStatusText();\r\n\r\n        BackgroundActionData actionData{ { installButton(), upgradeButton(), downloadButton() }, { cancelButton() }, statusText };\r\n\r\n        co_await winrt::resume_background();\r\n\r\n        Windows::Foundation::IAsyncOperationWithProgress<Deployment::InstallResult, Deployment::InstallProgress> packageOperation;\r\n\r\n        actionData.RunAndCatchStatus(L\"Begin install\", [&]() {\r\n            InstallOptions installOptions;\r\n\r\n            // Passing PackageInstallScope::User causes the install to fail if there's no installer that supports that.\r\n            installOptions.PackageInstallScope(PackageInstallScope::Any);\r\n            installOptions.PackageInstallMode(PackageInstallMode::Silent);\r\n\r\n            if (upgrade)\r\n            {\r\n                packageOperation = packageManager.UpgradePackageAsync(package, installOptions);\r\n            }\r\n            else\r\n            {\r\n                packageOperation = packageManager.InstallPackageAsync(package, installOptions);\r\n            }\r\n        });\r\n\r\n        actionData.Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal,\r\n            [packageOperation, this]() { m_packageOperation = packageOperation; });\r\n\r\n        actionData.RunAndCatchStatus(L\"Set progress handler\", [&]() {\r\n            packageOperation.Progress([&](\r\n                IAsyncOperationWithProgress<InstallResult, InstallProgress> const& /* sender */,\r\n                InstallProgress const& progress)\r\n                {\r\n                    actionData.Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal,\r\n                        [progressBar, statusText, progress]() {\r\n                            progressBar.Value(progress.DownloadProgress * 100);\r\n\r\n                            switch (progress.State)\r\n                            {\r\n                            case PackageInstallProgressState::Queued:\r\n                                statusText.Text(L\"Queued\");\r\n                                break;\r\n                            case PackageInstallProgressState::Downloading:\r\n                            {\r\n                                std::wstring downloadText{ L\"Downloaded \" };\r\n                                downloadText += MakeCompactByteString(progress.BytesDownloaded) + L\" of \" + MakeCompactByteString(progress.BytesRequired);\r\n                                statusText.Text(downloadText);\r\n                            }\r\n                            break;\r\n                            case PackageInstallProgressState::Installing:\r\n                                statusText.Text(L\"Installer running\");\r\n                                progressBar.IsIndeterminate(true);\r\n                                break;\r\n                            case PackageInstallProgressState::PostInstall:\r\n                                statusText.Text(L\"Post install bookkeeping\");\r\n                                break;\r\n                            case PackageInstallProgressState::Finished:\r\n                                statusText.Text(L\"Done\");\r\n                                progressBar.IsIndeterminate(false);\r\n                                break;\r\n                            default:\r\n                                statusText.Text(L\"\");\r\n                            }\r\n                        });\r\n                });\r\n            });\r\n\r\n        InstallResult installResult{ nullptr };\r\n\r\n        actionData.RunAndCatchStatus(L\"Install\", [&]() {\r\n            installResult = packageOperation.get();\r\n        });\r\n\r\n        if (packageOperation && packageOperation.Status() == AsyncStatus::Canceled)\r\n        {\r\n            actionData.Status(L\"Cancelled\");\r\n        }\r\n        else if (installResult)\r\n        {\r\n            // Error handling for the installResult is done by first examining the Status.\r\n            // Any status value other than Ok will have additional error detail in the\r\n            // ExtendedErrorCode property. This HRESULT value will typically (but not always)\r\n            // have the Windows Package Manager facility value (0xA15). The symbolic names and\r\n            // meanings of these error codes can be found at:\r\n            // https://github.com/microsoft/winget-cli/blob/master/doc/windows/package-manager/winget/returnCodes.md\r\n            // or by using the winget CLI:\r\n            // > winget error 0x8A150049\r\n            // > winget error -- -2146762487\r\n            switch (installResult.Status())\r\n            {\r\n            case InstallResultStatus::Ok:\r\n                actionData.Status(installResult.RebootRequired() ? L\"Reboot required\" : L\"Done\");\r\n                break;\r\n            case InstallResultStatus::BlockedByPolicy:\r\n                // See installResult.ExtendedErrorCode for more detail.\r\n                // This is typically caused by system configuration applied by policy.\r\n                actionData.Status(L\"Blocked by policy\");\r\n                break;\r\n            case InstallResultStatus::CatalogError:\r\n                // See installResult.ExtendedErrorCode for more detail.\r\n                // This is typically an issue with an external service.\r\n                actionData.Status(L\"Catalog error\");\r\n                break;\r\n            case InstallResultStatus::InternalError:\r\n                // See installResult.ExtendedErrorCode for more detail.\r\n                // This is typically an issue with the Windows Package Manager code.\r\n                actionData.Status(L\"Internal error\");\r\n                break;\r\n            case InstallResultStatus::InvalidOptions:\r\n                // See installResult.ExtendedErrorCode for more detail.\r\n                // This is caused by invalid input combinations.\r\n                actionData.Status(L\"Invalid options\");\r\n                break;\r\n            case InstallResultStatus::DownloadError:\r\n                // See installResult.ExtendedErrorCode for more detail.\r\n                // This is typically a transient network error.\r\n                actionData.Status(L\"Download error\");\r\n                break;\r\n            case InstallResultStatus::InstallError:\r\n                // See installResult.ExtendedErrorCode and installResult.InstallerErrorCode for more detail.\r\n                // This is caused by an error in the installer or an issue with the system state.\r\n                // InstallerErrorCode is the value returned by the installer technology in use for the install\r\n                // attempt and may or may not be an HRESULT.\r\n                actionData.Status(L\"Installation error\");\r\n                break;\r\n            case InstallResultStatus::ManifestError:\r\n                // See installResult.ExtendedErrorCode for more detail.\r\n                // This is an issue with the catalog providing the package.\r\n                actionData.Status(L\"Manifest error\");\r\n                break;\r\n            case InstallResultStatus::NoApplicableInstallers:\r\n                // No applicable installers were available due the combination of the current system,\r\n                // user settings, and parameters provided to the install request.\r\n                actionData.Status(L\"No applicable installers\");\r\n                break;\r\n            case InstallResultStatus::NoApplicableUpgrade:\r\n                // No upgrade was available due the combination of available versions, the current system,\r\n                // user settings, and parameters provided to the upgrade request.\r\n                actionData.Status(L\"No applicable upgrade\");\r\n                break;\r\n            case InstallResultStatus::PackageAgreementsNotAccepted:\r\n                // The user has not accepted the agreements required by the package.\r\n                actionData.Status(L\"Package agreements not accepted\");\r\n                break;\r\n            }\r\n        }\r\n\r\n        // Switch back to ui thread context.\r\n        co_await winrt::resume_foreground(actionData.Dispatcher());\r\n\r\n        progressBar.IsIndeterminate(false);\r\n\r\n        actionData.Finalize();\r\n    }\r\n\r\n    IAsyncAction MainPage::DownloadAsync()\r\n    {\r\n        hstring downloadDirectory = downloadDirectoryTextBox().Text();\r\n        PackageManager packageManager = m_packageManager;\r\n        CatalogPackage package = m_package;\r\n        auto progressBar = operationProgressBar();\r\n        auto statusText = operationStatusText();\r\n\r\n        BackgroundActionData actionData{ { installButton(), upgradeButton(), downloadButton() }, { cancelButton() }, statusText};\r\n\r\n        co_await winrt::resume_background();\r\n\r\n        Windows::Foundation::IAsyncOperationWithProgress<Deployment::DownloadResult, Deployment::PackageDownloadProgress> packageOperation;\r\n\r\n        actionData.RunAndCatchStatus(L\"Begin download\", [&]() {\r\n            DownloadOptions downloadOptions;\r\n\r\n            if (!downloadDirectory.empty())\r\n            {\r\n                downloadOptions.DownloadDirectory(downloadDirectory);\r\n            }\r\n\r\n            packageOperation = packageManager.DownloadPackageAsync(package, downloadOptions);\r\n        });\r\n\r\n        actionData.Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal,\r\n            [packageOperation, this]() { m_packageOperation = packageOperation; });\r\n\r\n        actionData.RunAndCatchStatus(L\"Set progress handler\", [&]() {\r\n            packageOperation.Progress([&](\r\n                IAsyncOperationWithProgress<DownloadResult, PackageDownloadProgress> const& /* sender */,\r\n                PackageDownloadProgress const& progress)\r\n                {\r\n                    actionData.Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal,\r\n                        [progressBar, statusText, progress]() {\r\n                            progressBar.Value(progress.DownloadProgress * 100);\r\n\r\n                            switch (progress.State)\r\n                            {\r\n                            case PackageDownloadProgressState::Queued:\r\n                                statusText.Text(L\"Queued\");\r\n                                break;\r\n                            case PackageDownloadProgressState::Downloading:\r\n                            {\r\n                                std::wstring downloadText{ L\"Downloaded \" };\r\n                                downloadText += MakeCompactByteString(progress.BytesDownloaded) + L\" of \" + MakeCompactByteString(progress.BytesRequired);\r\n                                statusText.Text(downloadText);\r\n                            }\r\n                            break;\r\n                            case PackageDownloadProgressState::Finished:\r\n                                statusText.Text(L\"Done\");\r\n                                progressBar.IsIndeterminate(false);\r\n                                break;\r\n                            default:\r\n                                statusText.Text(L\"\");\r\n                            }\r\n                        });\r\n                });\r\n            });\r\n\r\n        DownloadResult downloadResult{ nullptr };\r\n\r\n        actionData.RunAndCatchStatus(L\"Download\", [&]() {\r\n            downloadResult = packageOperation.get();\r\n        });\r\n\r\n        if (packageOperation && packageOperation.Status() == AsyncStatus::Canceled)\r\n        {\r\n            actionData.Status(L\"Cancelled\");\r\n        }\r\n        else if (downloadResult)\r\n        {\r\n            // Error handling for the downloadResult is done by first examining the Status.\r\n            // Any status value other than Ok will have additional error detail in the\r\n            // ExtendedErrorCode property. This HRESULT value will typically (but not always)\r\n            // have the Windows Package Manager facility value (0xA15). The symbolic names and\r\n            // meanings of these error codes can be found at:\r\n            // https://github.com/microsoft/winget-cli/blob/master/doc/windows/package-manager/winget/returnCodes.md\r\n            // or by using the winget CLI:\r\n            // > winget error 0x8A150049\r\n            // > winget error -- -2146762487\r\n            switch (downloadResult.Status())\r\n            {\r\n            case DownloadResultStatus::Ok:\r\n                actionData.Status(L\"Done\");\r\n                break;\r\n            case DownloadResultStatus::BlockedByPolicy:\r\n                // See installResult.ExtendedErrorCode for more detail.\r\n                // This is typically caused by system configuration applied by policy.\r\n                actionData.Status(L\"Blocked by policy\");\r\n                break;\r\n            case DownloadResultStatus::CatalogError:\r\n                // See installResult.ExtendedErrorCode for more detail.\r\n                // This is typically an issue with an external service.\r\n                actionData.Status(L\"Catalog error\");\r\n                break;\r\n            case DownloadResultStatus::InternalError:\r\n                // See installResult.ExtendedErrorCode for more detail.\r\n                // This is typically an issue with the Windows Package Manager code.\r\n                actionData.Status(L\"Internal error\");\r\n                break;\r\n            case DownloadResultStatus::InvalidOptions:\r\n                // See installResult.ExtendedErrorCode for more detail.\r\n                // This is caused by invalid input combinations.\r\n                actionData.Status(L\"Invalid options\");\r\n                break;\r\n            case DownloadResultStatus::DownloadError:\r\n                // See installResult.ExtendedErrorCode for more detail.\r\n                // This is typically a transient network error.\r\n                actionData.Status(L\"Download error\");\r\n                break;\r\n            case DownloadResultStatus::ManifestError:\r\n                // See installResult.ExtendedErrorCode for more detail.\r\n                // This is an issue with the catalog providing the package.\r\n                actionData.Status(L\"Manifest error\");\r\n                break;\r\n            case DownloadResultStatus::NoApplicableInstallers:\r\n                // No applicable installers were available due the combination of the current system,\r\n                // user settings, and parameters provided to the install request.\r\n                actionData.Status(L\"No applicable installers\");\r\n                break;\r\n            case DownloadResultStatus::PackageAgreementsNotAccepted:\r\n                // The user has not accepted the agreements required by the package.\r\n                actionData.Status(L\"Package agreements not accepted\");\r\n                break;\r\n            }\r\n        }\r\n\r\n        // Switch back to ui thread context.\r\n        co_await winrt::resume_foreground(actionData.Dispatcher());\r\n\r\n        progressBar.IsIndeterminate(false);\r\n\r\n        actionData.Finalize();\r\n    }\r\n\r\n    IAsyncAction MainPage::GetInstalledPackagesAsync()\r\n    {\r\n        BackgroundActionData actionData{ { refreshInstalledButton() }, installedStatusText() };\r\n\r\n        co_await winrt::resume_background();\r\n\r\n        actionData.Status(EnsurePackageManager());\r\n\r\n        PackageCatalog catalog{ nullptr };\r\n\r\n        actionData.RunAndCatchStatus(L\"Connect installed catalog\", [&]() {\r\n            PackageCatalogReference catalogReference = m_packageManager.GetLocalPackageCatalog(LocalPackageCatalog::InstalledPackages);\r\n            ConnectResult connectResult{ catalogReference.Connect() };\r\n\r\n            switch (connectResult.Status())\r\n            {\r\n            case ConnectResultStatus::Ok: break;\r\n            case ConnectResultStatus::CatalogError: throw std::exception{ \"Catalog connection error.\" };\r\n            }\r\n\r\n            catalog = connectResult.PackageCatalog();\r\n        });\r\n\r\n        winrt::IVectorView<MatchResult> matches;\r\n\r\n        actionData.RunAndCatchStatus(L\"Find package\", [&]() {\r\n            FindPackagesOptions findPackagesOptions;\r\n            FindPackagesResult findPackagesResult = catalog.FindPackages(findPackagesOptions);\r\n\r\n            matches = findPackagesResult.Matches();\r\n        });\r\n\r\n        co_await winrt::resume_foreground(actionData.Dispatcher());\r\n\r\n        m_installedPackages.Clear();\r\n\r\n        if (matches)\r\n        {\r\n            for (auto const& match : matches)\r\n            {\r\n                m_installedPackages.Append(match.CatalogPackage());\r\n            }\r\n        }\r\n\r\n        actionData.Finalize();\r\n    }\r\n\r\n    IAsyncAction MainPage::UninstallAsync()\r\n    {\r\n        PackageManager packageManager = m_packageManager;\r\n\r\n        auto progressBar = uninstallProgressBar();\r\n        auto statusText = uninstallStatusText();\r\n\r\n        IInspectable selectedValue = installedListBox().SelectedValue();\r\n        CatalogPackage package{ nullptr };\r\n        if (selectedValue)\r\n        {\r\n            package = selectedValue.as<CatalogPackage>();\r\n        }\r\n        else\r\n        {\r\n            statusText.Text(L\"Select a package to uninstall\");\r\n            co_return;\r\n        }\r\n\r\n        BackgroundActionData actionData{ { uninstallButton() }, statusText };\r\n\r\n        co_await winrt::resume_background();\r\n\r\n        Windows::Foundation::IAsyncOperationWithProgress<Deployment::UninstallResult, Deployment::UninstallProgress> packageOperation;\r\n\r\n        actionData.RunAndCatchStatus(L\"Begin uninstall\", [&]() {\r\n            UninstallOptions uninstallOptions;\r\n\r\n            uninstallOptions.PackageUninstallScope(PackageUninstallScope::Any);\r\n            uninstallOptions.PackageUninstallMode(PackageUninstallMode::Silent);\r\n\r\n            packageOperation = packageManager.UninstallPackageAsync(package, uninstallOptions);\r\n        });\r\n\r\n        actionData.RunAndCatchStatus(L\"Set progress handler\", [&]() {\r\n            packageOperation.Progress([&](\r\n                IAsyncOperationWithProgress<UninstallResult, UninstallProgress> const& /* sender */,\r\n                UninstallProgress const& progress)\r\n                {\r\n                    actionData.Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal,\r\n                        [progressBar, statusText, progress]() {\r\n                            progressBar.Value(progress.UninstallationProgress * 100);\r\n\r\n                            switch (progress.State)\r\n                            {\r\n                            case PackageUninstallProgressState::Queued:\r\n                                statusText.Text(L\"Queued\");\r\n                                break;\r\n                            case PackageUninstallProgressState::Uninstalling:\r\n                                statusText.Text(L\"Uninstaller running\");\r\n                                progressBar.IsIndeterminate(true);\r\n                                break;\r\n                            case PackageUninstallProgressState::PostUninstall:\r\n                                statusText.Text(L\"Post uninstall bookkeeping\");\r\n                                break;\r\n                            case PackageUninstallProgressState::Finished:\r\n                                statusText.Text(L\"Done\");\r\n                                progressBar.IsIndeterminate(false);\r\n                                break;\r\n                            default:\r\n                                statusText.Text(L\"\");\r\n                            }\r\n                        });\r\n                });\r\n            });\r\n\r\n        UninstallResult uninstallResult{ nullptr };\r\n\r\n        actionData.RunAndCatchStatus(L\"Uninstall\", [&]() {\r\n            uninstallResult = packageOperation.get();\r\n        });\r\n\r\n        if (packageOperation && packageOperation.Status() == AsyncStatus::Canceled)\r\n        {\r\n            actionData.Status(L\"Cancelled\");\r\n        }\r\n        else if (uninstallResult)\r\n        {\r\n            // Error handling for the installResult is done by first examining the Status.\r\n            // Any status value other than Ok will have additional error detail in the\r\n            // ExtendedErrorCode property. This HRESULT value will typically (but not always)\r\n            // have the Windows Package Manager facility value (0xA15). The symbolic names and\r\n            // meanings of these error codes can be found at:\r\n            // https://github.com/microsoft/winget-cli/blob/master/doc/windows/package-manager/winget/returnCodes.md\r\n            // or by using the winget CLI:\r\n            // > winget error 0x8A150049\r\n            // > winget error -- -2146762487\r\n            switch (uninstallResult.Status())\r\n            {\r\n            case UninstallResultStatus::Ok:\r\n                actionData.Status(uninstallResult.RebootRequired() ? L\"Reboot required\" : L\"Done\");\r\n                break;\r\n            case UninstallResultStatus::BlockedByPolicy:\r\n                // See installResult.ExtendedErrorCode for more detail.\r\n                // This is typically caused by system configuration applied by policy.\r\n                actionData.Status(L\"Blocked by policy\");\r\n                break;\r\n            case UninstallResultStatus::CatalogError:\r\n                // See installResult.ExtendedErrorCode for more detail.\r\n                // This is typically an issue with an external service.\r\n                actionData.Status(L\"Catalog error\");\r\n                break;\r\n            case UninstallResultStatus::InternalError:\r\n                // See installResult.ExtendedErrorCode for more detail.\r\n                // This is typically an issue with the Windows Package Manager code.\r\n                actionData.Status(L\"Internal error\");\r\n                break;\r\n            case UninstallResultStatus::InvalidOptions:\r\n                // See installResult.ExtendedErrorCode for more detail.\r\n                // This is caused by invalid input combinations.\r\n                actionData.Status(L\"Invalid options\");\r\n                break;\r\n            case UninstallResultStatus::UninstallError:\r\n                // See installResult.ExtendedErrorCode and installResult.UninstallerErrorCode for more detail.\r\n                // This is caused by an error in the uninstaller or an issue with the system state.\r\n                // UninstallerErrorCode is the value returned by the uninstaller technology in use for the uninstall\r\n                // attempt and may or may not be an HRESULT.\r\n                actionData.Status(L\"Uninstallation error\");\r\n                break;\r\n            case UninstallResultStatus::ManifestError:\r\n                // See installResult.ExtendedErrorCode for more detail.\r\n                // This is an issue with the catalog providing the package.\r\n                actionData.Status(L\"Manifest error\");\r\n                break;\r\n            }\r\n        }\r\n\r\n        // Switch back to ui thread context.\r\n        co_await winrt::resume_foreground(actionData.Dispatcher());\r\n\r\n        progressBar.IsIndeterminate(false);\r\n\r\n        actionData.Finalize();\r\n    }\r\n\r\n    IAsyncAction MainPage::GetActivePackagesAsync()\r\n    {\r\n        BackgroundActionData actionData{ { activeRefreshButton() }, activeStatusText() };\r\n\r\n        co_await winrt::resume_background();\r\n\r\n        actionData.Status(EnsurePackageManager());\r\n\r\n        PackageCatalog catalog{ nullptr };\r\n\r\n        actionData.RunAndCatchStatus(L\"Connect installed catalog\", [&]() {\r\n            PackageCatalogReference catalogReference = m_packageManager.GetLocalPackageCatalog(LocalPackageCatalog::InstallingPackages);\r\n            ConnectResult connectResult{ catalogReference.Connect() };\r\n\r\n            switch (connectResult.Status())\r\n            {\r\n            case ConnectResultStatus::Ok: break;\r\n            case ConnectResultStatus::CatalogError: throw std::exception{ \"Catalog connection error.\" };\r\n            }\r\n\r\n            catalog = connectResult.PackageCatalog();\r\n        });\r\n\r\n        winrt::IVectorView<MatchResult> matches;\r\n\r\n        actionData.RunAndCatchStatus(L\"Find package\", [&]() {\r\n            FindPackagesOptions findPackagesOptions;\r\n            FindPackagesResult findPackagesResult = catalog.FindPackages(findPackagesOptions);\r\n\r\n            matches = findPackagesResult.Matches();\r\n        });\r\n\r\n        co_await winrt::resume_foreground(actionData.Dispatcher());\r\n\r\n        m_activePackageViews.Clear();\r\n\r\n        if (matches)\r\n        {\r\n            for (auto const& match : matches)\r\n            {\r\n                WinGetUWPCaller::ActivePackageView activeView;\r\n                activeView.Package(match.CatalogPackage());\r\n                auto installOperation = m_packageManager.GetInstallProgress(activeView.Package(), nullptr);\r\n                if (installOperation)\r\n                {\r\n                    activeView.Dispatcher(actionData.Dispatcher());\r\n                    activeView.AsyncOperation(installOperation);\r\n                    m_activePackageViews.Append(activeView);\r\n                }\r\n            }\r\n        }\r\n\r\n        actionData.Finalize();\r\n    }\r\n}\r\n"
  },
  {
    "path": "samples/WinGetUWPCaller/WinGetUWPCaller/MainPage.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"MainPage.g.h\"\r\n#include \"ActivePackageView.h\"\r\n#include <winrt\\Microsoft.Management.Deployment.h>\r\n#include <mutex>\r\n\r\nnamespace Deployment = winrt::Microsoft::Management::Deployment;\r\n\r\nnamespace winrt::WinGetUWPCaller::implementation\r\n{\r\n    struct MainPage : MainPageT<MainPage>\r\n    {\r\n        MainPage();\r\n\r\n        Windows::Foundation::Collections::IObservableVector<Deployment::PackageCatalogReference> PackageCatalogs();\r\n        Windows::Foundation::Collections::IObservableVector<Deployment::CatalogPackage> InstalledPackages();\r\n        Windows::Foundation::Collections::IObservableVector<WinGetUWPCaller::ActivePackageView> ActivePackages();\r\n\r\n        // Select Catalog(s) section\r\n        void LoadCatalogsButtonClickHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);\r\n        void CatalogSelectionChangedHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);\r\n\r\n        // Package Operations section\r\n        void SearchButtonClickHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);\r\n        void InstallButtonClickHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);\r\n        void UpgradeButtonClickHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);\r\n        void DownloadButtonClickHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);\r\n        void CancelButtonClickHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);\r\n\r\n        // Installed Packages section\r\n        void RefreshInstalledButtonClickHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);\r\n        void UninstallButtonClickHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);\r\n\r\n        // Active Operations section\r\n        void RefreshActiveButtonClickHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);\r\n\r\n    private:\r\n        // Ensures that the package manager object exists; potentially recreating it if requested.\r\n        // Should be called from a background thread.\r\n        // Is thread-safe.\r\n        // Returns an error string if it fails.\r\n        std::wstring EnsurePackageManager(bool forceRecreate = false);\r\n\r\n        // Select Catalog(s) section\r\n        Windows::Foundation::IAsyncAction LoadCatalogsAsync();\r\n\r\n        // Package Operations section\r\n        Windows::Foundation::IAsyncAction FindPackageAsync();\r\n        Windows::Foundation::IAsyncAction InstallOrUpgradeAsync(bool upgrade);\r\n        Windows::Foundation::IAsyncAction DownloadAsync();\r\n\r\n        // Installed Packages section\r\n        Windows::Foundation::IAsyncAction GetInstalledPackagesAsync();\r\n        Windows::Foundation::IAsyncAction UninstallAsync();\r\n\r\n        // Active Operations section\r\n        Windows::Foundation::IAsyncAction GetActivePackagesAsync();\r\n\r\n        // Member fields\r\n        Windows::Foundation::Collections::IObservableVector<Deployment::PackageCatalogReference> m_packageCatalogs;\r\n        Windows::Foundation::Collections::IObservableVector<Deployment::CatalogPackage> m_installedPackages;\r\n        Windows::Foundation::Collections::IObservableVector<WinGetUWPCaller::ActivePackageView> m_activePackageViews;\r\n\r\n        std::mutex m_packageManagerMutex;\r\n        Deployment::PackageManager m_packageManager{ nullptr };\r\n        Deployment::PackageCatalog m_catalog{ nullptr };\r\n        Deployment::CatalogPackage m_package{ nullptr };\r\n        Windows::Foundation::IAsyncInfo m_packageOperation;\r\n    };\r\n}\r\n\r\nnamespace winrt::WinGetUWPCaller::factory_implementation\r\n{\r\n    struct MainPage : MainPageT<MainPage, implementation::MainPage>\r\n    {\r\n    };\r\n}\r\n"
  },
  {
    "path": "samples/WinGetUWPCaller/WinGetUWPCaller/MainPage.idl",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nnamespace WinGetUWPCaller\n{\n    [default_interface]\n    runtimeclass ActivePackageView : Windows.UI.Xaml.Data.INotifyPropertyChanged\n    {\n        ActivePackageView();\r\n\n        Microsoft.Management.Deployment.CatalogPackage Package;\n        Windows.Foundation.IAsyncOperationWithProgress<Microsoft.Management.Deployment.InstallResult, Microsoft.Management.Deployment.InstallProgress> AsyncOperation;\n        Double Progress;\n        String StatusText;\n        Windows.UI.Core.CoreDispatcher Dispatcher;\n    }\n\n    [default_interface]\n    runtimeclass MainPage : Windows.UI.Xaml.Controls.Page\n    {\n        MainPage();\r\n\n        Windows.Foundation.Collections.IObservableVector<Microsoft.Management.Deployment.PackageCatalogReference> PackageCatalogs{ get; };\n        Windows.Foundation.Collections.IObservableVector<Microsoft.Management.Deployment.CatalogPackage> InstalledPackages{ get; };\n        Windows.Foundation.Collections.IObservableVector<ActivePackageView> ActivePackages{ get; };\n    }\n\n    declare\n    {\n        interface Windows.Foundation.Collections.IVector<ActivePackageView>;\n        interface Windows.Foundation.Collections.IVectorView<ActivePackageView>;\n    }\n}\n"
  },
  {
    "path": "samples/WinGetUWPCaller/WinGetUWPCaller/MainPage.xaml",
    "content": "<!-- Copyright (c) Microsoft Corporation.\r\n     Licensed under the MIT License. -->\r\n<Page\r\n    x:Class=\"WinGetUWPCaller.MainPage\"\r\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\r\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\r\n    xmlns:local=\"using:WinGetUWPCaller\"\r\n    xmlns:deployment=\"using:Microsoft.Management.Deployment\"\r\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\r\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\r\n    mc:Ignorable=\"d\">\r\n\r\n    <Page.Resources>\r\n        <ResourceDictionary>\r\n            <Style TargetType=\"StackPanel\">\r\n                <Setter Property=\"Margin\" Value=\"5\" />\r\n                <Setter Property=\"HorizontalAlignment\" Value=\"Center\" />\r\n            </Style>\r\n            <Style TargetType=\"Button\">\r\n                <Setter Property=\"Margin\" Value=\"5\" />\r\n                <Setter Property=\"HorizontalAlignment\" Value=\"Center\" />\r\n            </Style>\r\n        </ResourceDictionary>\r\n    </Page.Resources>\r\n\r\n    <Grid MinWidth=\"800\" MinHeight=\"600\">\r\n        <Grid.RowDefinitions>\r\n            <RowDefinition Height=\"Auto\"/>\r\n            <RowDefinition Height=\"Auto\"/>\r\n            <RowDefinition Height=\"Auto\"/>\r\n        </Grid.RowDefinitions>\r\n        <Grid.ColumnDefinitions>\r\n            <ColumnDefinition Width=\"*\"/>\r\n            <ColumnDefinition Width=\"*\"/>\r\n        </Grid.ColumnDefinitions>\r\n\r\n        <StackPanel Grid.Row=\"1\">\r\n            <TextBlock Style=\"{StaticResource SubheaderTextBlockStyle}\">Select Catalog(s)</TextBlock>\r\n\r\n            <Button x:Name=\"loadCatalogsButton\" Click=\"LoadCatalogsButtonClickHandler\">Load Catalogs</Button>\r\n            <TextBlock x:Name=\"catalogStatusText\" Text=\"\" HorizontalAlignment=\"Center\" Margin=\"0,0,0,20\"/>\r\n            <TextBlock>Select catalog(s) to use</TextBlock>\r\n            <ListBox x:Name=\"catalogsListBox\" ItemsSource=\"{x:Bind PackageCatalogs}\" SelectionChanged=\"CatalogSelectionChangedHandler\" SelectionMode=\"Multiple\" Height=\"200\">\r\n                <ItemsControl.ItemTemplate>\r\n                    <DataTemplate x:DataType=\"deployment:PackageCatalogReference\">\r\n                        <TextBlock Text=\"{x:Bind Info.Name, Mode=OneTime}\"/>\r\n                    </DataTemplate>\r\n                </ItemsControl.ItemTemplate>\r\n            </ListBox>\r\n        </StackPanel>\r\n\r\n        <StackPanel Grid.Row=\"1\" Grid.Column=\"1\">\r\n            <TextBlock Style=\"{StaticResource SubheaderTextBlockStyle}\">Package Operations</TextBlock>\r\n            <TextBlock>Search for a package from the selected catalog(s) and take action on it.</TextBlock>\r\n\r\n            <StackPanel Orientation=\"Horizontal\">\r\n                <TextBox x:Name=\"queryTextBox\" Header=\"Find a package:\" PlaceholderText=\"Query (e.g. Microsoft.Teams)\"></TextBox>\r\n                <ComboBox x:Name=\"searchField\" Header=\"Search options\" Margin=\"5,0,5,0\" SelectedIndex=\"0\">\r\n                    <ComboBoxItem Content=\"Generic query\"></ComboBoxItem>\r\n                    <ComboBoxItem Content=\"Identifier (case-insensitive)\"></ComboBoxItem>\r\n                    <ComboBoxItem Content=\"Name (substring)\"></ComboBoxItem>\r\n                </ComboBox>\r\n                <Button x:Name=\"searchButton\" Click=\"SearchButtonClickHandler\" VerticalAlignment=\"Bottom\" Margin=\"5,0,5,0\">🔍</Button>\r\n            </StackPanel>\r\n\r\n            <StackPanel Orientation=\"Horizontal\">\r\n                <Button x:Name=\"installButton\" Click=\"InstallButtonClickHandler\" IsEnabled=\"False\">Install</Button>\r\n                <Button x:Name=\"upgradeButton\" Click=\"UpgradeButtonClickHandler\" IsEnabled=\"False\">Upgrade</Button>\r\n                <Button x:Name=\"downloadButton\" Click=\"DownloadButtonClickHandler\" IsEnabled=\"False\">Download</Button>\r\n                <Button x:Name=\"cancelButton\" Click=\"CancelButtonClickHandler\" IsEnabled=\"False\">Cancel</Button>\r\n            </StackPanel>\r\n\r\n            <ProgressBar x:Name=\"operationProgressBar\" Value=\"0\" Maximum=\"100\" Width=\"350\"/>\r\n            <TextBlock x:Name=\"operationStatusText\" Text=\"\" HorizontalAlignment=\"Center\" Margin=\"0,0,0,20\"/>\r\n\r\n            <TextBox x:Name=\"downloadDirectoryTextBox\" Header=\"Download Location:\" PlaceholderText=\"Existing directory path to download to\"></TextBox>\r\n        </StackPanel>\r\n\r\n        <StackPanel Grid.Row=\"2\" Margin=\"3\">\r\n            <TextBlock Style=\"{StaticResource SubheaderTextBlockStyle}\">Installed Packages</TextBlock>\r\n            <TextBlock>View installed package information</TextBlock>\r\n            <Button x:Name=\"refreshInstalledButton\" Click=\"RefreshInstalledButtonClickHandler\" IsEnabled=\"True\">Refresh</Button>\r\n            <TextBlock x:Name=\"installedStatusText\" Text=\"\"/>\r\n            <ListBox x:Name=\"installedListBox\" ItemsSource=\"{x:Bind InstalledPackages}\" Height=\"300\" SelectionMode=\"Single\" ScrollViewer.VerticalScrollBarVisibility=\"Visible\">\r\n                <ItemsControl.ItemTemplate>\r\n                    <DataTemplate x:DataType=\"deployment:CatalogPackage\">\r\n                        <TextBlock Text=\"{x:Bind Name, Mode=OneTime}\"/>\r\n                    </DataTemplate>\r\n                </ItemsControl.ItemTemplate>\r\n            </ListBox>\r\n\r\n            <Button x:Name=\"uninstallButton\" Click=\"UninstallButtonClickHandler\" IsEnabled=\"True\" Margin=\"5,20,5,5\">Uninstall</Button>\r\n            <ProgressBar x:Name=\"uninstallProgressBar\" Value=\"0\" Maximum=\"100\" Width=\"350\"/>\r\n            <TextBlock x:Name=\"uninstallStatusText\" Text=\"\" HorizontalAlignment=\"Center\" Margin=\"0,0,0,20\"/>\r\n        </StackPanel>\r\n\r\n        <StackPanel Grid.Row=\"2\" Grid.Column=\"1\" Margin=\"3\">\r\n            <TextBlock Style=\"{StaticResource SubheaderTextBlockStyle}\">Active Operations</TextBlock>\r\n            <TextBlock>View active package install/upgrade operations</TextBlock>\r\n            <StackPanel Orientation=\"Horizontal\" >\r\n                <Button x:Name=\"activeRefreshButton\" Click=\"RefreshActiveButtonClickHandler\" IsEnabled=\"True\">Refresh</Button>\r\n            </StackPanel>\r\n            <TextBlock x:Name=\"activeStatusText\" Text=\"\"/>\r\n            <ListBox x:Name=\"activeListBox\" ItemsSource=\"{x:Bind ActivePackages}\" Height=\"300\" ScrollViewer.VerticalScrollBarVisibility=\"Visible\">\r\n                <ItemsControl.ItemTemplate>\r\n                    <DataTemplate x:DataType=\"local:ActivePackageView\">\r\n                        <StackPanel HorizontalAlignment=\"Center\">\r\n                            <TextBlock Text=\"{x:Bind Package.Id, Mode=OneWay}\"/>\r\n                            <ProgressBar Value=\"{x:Bind Progress, Mode=OneWay}\" Maximum=\"100\" Width=\"200px\"></ProgressBar>\r\n                            <TextBlock Text=\"{x:Bind StatusText, Mode=OneWay}\" HorizontalAlignment=\"Center\"></TextBlock>\r\n                        </StackPanel>\r\n                    </DataTemplate>\r\n                </ItemsControl.ItemTemplate>\r\n            </ListBox>\r\n        </StackPanel>\r\n    </Grid>\r\n</Page>\r\n"
  },
  {
    "path": "samples/WinGetUWPCaller/WinGetUWPCaller/Package.appxmanifest",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Package xmlns=\"http://schemas.microsoft.com/appx/manifest/foundation/windows10\"\n         xmlns:mp=\"http://schemas.microsoft.com/appx/2014/phone/manifest\"\n         xmlns:uap=\"http://schemas.microsoft.com/appx/manifest/uap/windows10\"\n         xmlns:rescap=\"http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities\"\n         IgnorableNamespaces=\"uap mp rescap\">\n  <Identity Name=\"SampleWinGetCaller\" Publisher=\"CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US\" Version=\"1.0.0.0\" />\n  <mp:PhoneIdentity PhoneProductId=\"8b5526fe-0870-42b7-bde0-da8c4c7ea1aa\" PhonePublisherId=\"00000000-0000-0000-0000-000000000000\" />\n  <Properties>\n    <DisplayName>Sample WinGet Caller</DisplayName>\n    <PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>\n    <Logo>Assets\\StoreLogo.png</Logo>\n  </Properties>\n  <Dependencies>\n    <TargetDeviceFamily Name=\"Windows.Universal\" MinVersion=\"10.0.0.0\" MaxVersionTested=\"10.0.0.0\" />\n  </Dependencies>\n  <Resources>\n    <Resource Language=\"x-generate\" />\n  </Resources>\n  <Applications>\n    <Application Id=\"App\" Executable=\"$targetnametoken$.exe\" EntryPoint=\"Sample WinGet Caller\">\n      <uap:VisualElements DisplayName=\"SampleWinGetCaller\" Square150x150Logo=\"Assets\\Square150x150Logo.png\" Square44x44Logo=\"Assets\\Square44x44Logo.png\" BackgroundColor=\"transparent\" Description=\"Sample WinGet UWP caller\">\n        <uap:DefaultTile Wide310x150Logo=\"Assets\\Wide310x150Logo.png\"></uap:DefaultTile>\n      </uap:VisualElements>\n    </Application>\n  </Applications>\n  <Capabilities>\n    <Capability Name=\"internetClient\" />\n    <rescap:Capability Name=\"packageManagement\" />\n  </Capabilities>\n</Package>"
  },
  {
    "path": "samples/WinGetUWPCaller/WinGetUWPCaller/WinGetUWPCaller.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"15.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <Import Project=\"..\\packages\\Microsoft.Windows.CppWinRT.2.0.210503.1\\build\\native\\Microsoft.Windows.CppWinRT.props\" Condition=\"Exists('..\\packages\\Microsoft.Windows.CppWinRT.2.0.210503.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" />\r\n  <PropertyGroup Label=\"Globals\">\r\n    <CppWinRTOptimized>true</CppWinRTOptimized>\r\n    <CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>\r\n    <CppWinRTGenerateWindowsMetadata>true</CppWinRTGenerateWindowsMetadata>\r\n    <MinimalCoreWin>true</MinimalCoreWin>\r\n    <ProjectGuid>{37f1fd2a-4d63-45a0-82aa-66ef126cb322}</ProjectGuid>\r\n    <ProjectName>WinGetUWPCaller</ProjectName>\r\n    <RootNamespace>WinGetUWPCaller</RootNamespace>\r\n    <DefaultLanguage>en-US</DefaultLanguage>\r\n    <MinimumVisualStudioVersion>15.0</MinimumVisualStudioVersion>\r\n    <AppContainerApplication>true</AppContainerApplication>\r\n    <ApplicationType>Windows Store</ApplicationType>\r\n    <ApplicationTypeRevision>10.0</ApplicationTypeRevision>\r\n    <WindowsTargetPlatformVersion Condition=\" '$(WindowsTargetPlatformVersion)' == '' \">10.0.22000.0</WindowsTargetPlatformVersion>\r\n    <WindowsTargetPlatformMinVersion>10.0.17763.0</WindowsTargetPlatformMinVersion>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|ARM64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|Win32\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|ARM64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|Win32\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <PropertyGroup Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Debug'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n    <LinkIncremental>true</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Release'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <LinkIncremental>false</LinkIncremental>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\r\n  <ImportGroup Label=\"ExtensionSettings\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <PropertyGroup Label=\"UserMacros\">\r\n    <GenerateAppInstallerFile>False</GenerateAppInstallerFile>\r\n    <AppxPackageSigningTimestampDigestAlgorithm>SHA256</AppxPackageSigningTimestampDigestAlgorithm>\r\n    <AppxAutoIncrementPackageRevision>True</AppxAutoIncrementPackageRevision>\r\n    <GenerateTestArtifacts>True</GenerateTestArtifacts>\r\n    <AppxBundlePlatforms>x64</AppxBundlePlatforms>\r\n    <HoursBetweenUpdateChecks>0</HoursBetweenUpdateChecks>\r\n    <AppxBundle>Always</AppxBundle>\r\n  </PropertyGroup>\r\n  <ItemDefinitionGroup>\r\n    <ClCompile>\r\n      <PrecompiledHeader>Use</PrecompiledHeader>\r\n      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>\r\n      <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <AdditionalOptions>%(AdditionalOptions) /bigobj</AdditionalOptions>\r\n      <!--Temporarily disable cppwinrt heap enforcement to work around xaml compiler generated std::shared_ptr use -->\r\n      <AdditionalOptions Condition=\"'$(CppWinRTHeapEnforcement)'==''\">/DWINRT_NO_MAKE_DETECTION %(AdditionalOptions)</AdditionalOptions>\r\n      <DisableSpecificWarnings>\r\n      </DisableSpecificWarnings>\r\n      <PreprocessorDefinitions>WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n    </ClCompile>\r\n    <Link>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Debug'\">\r\n    <ClCompile>\r\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n    </ClCompile>\r\n    <PostBuildEvent>\r\n      <Command Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n      </Command>\r\n    </PostBuildEvent>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Release'\">\r\n    <ClCompile>\r\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n    </ClCompile>\r\n    <Link>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n    </Link>\r\n    <PostBuildEvent>\r\n      <Command Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n      </Command>\r\n    </PostBuildEvent>\r\n  </ItemDefinitionGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"ActivePackageView.h\" />\r\n    <ClInclude Include=\"pch.h\" />\r\n    <ClInclude Include=\"App.h\">\r\n      <DependentUpon>App.xaml</DependentUpon>\r\n    </ClInclude>\r\n    <ClInclude Include=\"MainPage.h\">\r\n      <DependentUpon>MainPage.xaml</DependentUpon>\r\n    </ClInclude>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ApplicationDefinition Include=\"App.xaml\">\r\n      <SubType>Designer</SubType>\r\n    </ApplicationDefinition>\r\n    <Page Include=\"MainPage.xaml\">\r\n      <SubType>Designer</SubType>\r\n    </Page>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <AppxManifest Include=\"Package.appxmanifest\">\r\n      <SubType>Designer</SubType>\r\n    </AppxManifest>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Image Include=\"Assets\\LockScreenLogo.scale-200.png\" />\r\n    <Image Include=\"Assets\\SplashScreen.scale-200.png\" />\r\n    <Image Include=\"Assets\\Square150x150Logo.scale-200.png\" />\r\n    <Image Include=\"Assets\\Square44x44Logo.scale-200.png\" />\r\n    <Image Include=\"Assets\\Square44x44Logo.targetsize-24_altform-unplated.png\" />\r\n    <Image Include=\"Assets\\StoreLogo.png\" />\r\n    <Image Include=\"Assets\\Wide310x150Logo.scale-200.png\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"ActivePackageView.cpp\" />\r\n    <ClCompile Include=\"pch.cpp\">\r\n      <PrecompiledHeader>Create</PrecompiledHeader>\r\n    </ClCompile>\r\n    <ClCompile Include=\"App.cpp\">\r\n      <DependentUpon>App.xaml</DependentUpon>\r\n    </ClCompile>\r\n    <ClCompile Include=\"MainPage.cpp\">\r\n      <DependentUpon>MainPage.xaml</DependentUpon>\r\n    </ClCompile>\r\n    <ClCompile Include=\"$(GeneratedFilesDir)module.g.cpp\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Midl Include=\"App.idl\">\r\n      <DependentUpon>App.xaml</DependentUpon>\r\n    </Midl>\r\n    <Midl Include=\"MainPage.idl\">\r\n      <DependentUpon>MainPage.xaml</DependentUpon>\r\n    </Midl>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"packages.config\" />\r\n  </ItemGroup>\r\n  <Target Name=\"_AddCustomPackagePayload\" AfterTargets=\"_ComputeAppxPackagePayload\">\r\n    <PropertyGroup>\r\n      <NugetRuntimeID Condition=\"'$(Platform)'=='Win32'\">win10-x86</NugetRuntimeID>\r\n      <NugetRuntimeID Condition=\"'$(Platform)'=='x64'\">win10-x64</NugetRuntimeID>\r\n      <NugetRuntimeID Condition=\"'$(Platform)'=='ARM64'\">win10-arm64</NugetRuntimeID>\r\n    </PropertyGroup>\r\n    <ItemGroup>\r\n      <AppxPackagePayload Include=\"$(SolutionDir)packages\\Microsoft.WindowsPackageManager.ComInterop.1.8.1911\\runtimes\\$(NugetRuntimeID)\\native\\Microsoft.Management.Deployment.Dynamic.dll\">\r\n        <TargetPath>Microsoft.Management.Deployment.dll</TargetPath>\r\n      </AppxPackagePayload>\r\n    </ItemGroup>\r\n  </Target>\r\n  <ItemGroup>\r\n    <Reference Include=\"Microsoft.Management.Deployment\">\r\n      <HintPath>..\\packages\\Microsoft.WindowsPackageManager.ComInterop.1.8.1911\\lib\\Microsoft.Management.Deployment.winmd</HintPath>\r\n      <IsWinMDFile>true</IsWinMDFile>\r\n      <Implementation>Microsoft.Management.Deployment.dll</Implementation>\r\n    </Reference>\r\n  </ItemGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\r\n  <ImportGroup Label=\"ExtensionTargets\">\r\n    <Import Project=\"..\\packages\\Microsoft.Windows.CppWinRT.2.0.210503.1\\build\\native\\Microsoft.Windows.CppWinRT.targets\" Condition=\"Exists('..\\packages\\Microsoft.Windows.CppWinRT.2.0.210503.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" />\r\n  </ImportGroup>\r\n  <Target Name=\"EnsureNuGetPackageBuildImports\" BeforeTargets=\"PrepareForBuild\">\r\n    <PropertyGroup>\r\n      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>\r\n    </PropertyGroup>\r\n    <Error Condition=\"!Exists('..\\packages\\Microsoft.Windows.CppWinRT.2.0.210503.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" Text=\"$([System.String]::Format('$(ErrorText)', '..\\packages\\Microsoft.Windows.CppWinRT.2.0.210503.1\\build\\native\\Microsoft.Windows.CppWinRT.props'))\" />\r\n    <Error Condition=\"!Exists('..\\packages\\Microsoft.Windows.CppWinRT.2.0.210503.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '..\\packages\\Microsoft.Windows.CppWinRT.2.0.210503.1\\build\\native\\Microsoft.Windows.CppWinRT.targets'))\" />\r\n  </Target>\r\n</Project>"
  },
  {
    "path": "samples/WinGetUWPCaller/WinGetUWPCaller/WinGetUWPCaller.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup>\r\n    <ApplicationDefinition Include=\"App.xaml\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Page Include=\"MainPage.xaml\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Midl Include=\"App.idl\" />\r\n    <Midl Include=\"MainPage.idl\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"pch.cpp\" />\r\n    <ClCompile Include=\"App.cpp\" />\r\n    <ClCompile Include=\"MainPage.cpp\" />\r\n    <ClCompile Include=\"$(GeneratedFilesDir)module.g.cpp\" />\r\n    <ClCompile Include=\"InstallingPackageView.cpp\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"pch.h\" />\r\n    <ClInclude Include=\"InstallingPackageView.h\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Image Include=\"Assets\\Wide310x150Logo.scale-200.png\">\r\n      <Filter>Assets</Filter>\r\n    </Image>\r\n    <Image Include=\"Assets\\SplashScreen.scale-200.png\">\r\n      <Filter>Assets</Filter>\r\n    </Image>\r\n    <Image Include=\"Assets\\Square44x44Logo.scale-200.png\">\r\n      <Filter>Assets</Filter>\r\n    </Image>\r\n    <Image Include=\"Assets\\Square44x44Logo.targetsize-24_altform-unplated.png\">\r\n      <Filter>Assets</Filter>\r\n    </Image>\r\n    <Image Include=\"Assets\\Square150x150Logo.scale-200.png\">\r\n      <Filter>Assets</Filter>\r\n    </Image>\r\n    <Image Include=\"Assets\\StoreLogo.png\">\r\n      <Filter>Assets</Filter>\r\n    </Image>\r\n    <Image Include=\"Assets\\LockScreenLogo.scale-200.png\">\r\n      <Filter>Assets</Filter>\r\n    </Image>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <AppxManifest Include=\"Package.appxmanifest\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"packages.config\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Filter Include=\"Assets\">\r\n      <UniqueIdentifier>{adeebf4e-70b7-41ae-936b-ded00e6e6777}</UniqueIdentifier>\r\n    </Filter>\r\n  </ItemGroup>\r\n</Project>"
  },
  {
    "path": "samples/WinGetUWPCaller/WinGetUWPCaller/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<packages>\r\n  <package id=\"Microsoft.Windows.CppWinRT\" version=\"2.0.210503.1\" targetFramework=\"native\" />\r\n  <package id=\"Microsoft.WindowsPackageManager.ComInterop\" version=\"1.8.1911\" targetFramework=\"native\" />\r\n</packages>"
  },
  {
    "path": "samples/WinGetUWPCaller/WinGetUWPCaller/pch.cpp",
    "content": "﻿// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n"
  },
  {
    "path": "samples/WinGetUWPCaller/WinGetUWPCaller/pch.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include <windows.h>\n#include <unknwn.h>\n#include <hstring.h>\n#include <winrt/Windows.Foundation.h>\n#include <winrt/Windows.Foundation.Collections.h>\n#include <winrt/Windows.ApplicationModel.Activation.h>\r\n#include <winrt/Windows.UI.Core.h>\n#include <winrt/Windows.UI.Xaml.h>\n#include <winrt/Windows.UI.Xaml.Controls.h>\n#include <winrt/Windows.UI.Xaml.Controls.Primitives.h>\n#include <winrt/Windows.UI.Xaml.Data.h>\n#include <winrt/Windows.UI.Xaml.Interop.h>\n#include <winrt/Windows.UI.Xaml.Markup.h>\n#include <winrt/Windows.UI.Xaml.Navigation.h>\n\r\n#include <initializer_list>\r\n#include <iomanip>\r\n#include <mutex>\n#include <sstream>\r\n#include <string>\n#include <string_view>\n#include <vector>\n"
  },
  {
    "path": "samples/WinGetUWPCaller/WinGetUWPCaller.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 16\nVisualStudioVersion = 16.0.30704.19\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"WinGetUWPCaller\", \"WinGetUWPCaller\\WinGetUWPCaller.vcxproj\", \"{37F1FD2A-4D63-45A0-82AA-66EF126CB322}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|ARM64 = Debug|ARM64\n\t\tDebug|x64 = Debug|x64\n\t\tDebug|x86 = Debug|x86\n\t\tRelease|ARM64 = Release|ARM64\n\t\tRelease|x64 = Release|x64\n\t\tRelease|x86 = Release|x86\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Debug|ARM64.ActiveCfg = Debug|ARM64\n\t\t{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Debug|ARM64.Build.0 = Debug|ARM64\n\t\t{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Debug|ARM64.Deploy.0 = Debug|ARM64\n\t\t{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Debug|x64.Build.0 = Debug|x64\n\t\t{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Debug|x64.Deploy.0 = Debug|x64\n\t\t{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Debug|x86.ActiveCfg = Debug|Win32\n\t\t{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Debug|x86.Build.0 = Debug|Win32\n\t\t{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Debug|x86.Deploy.0 = Debug|Win32\n\t\t{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Release|ARM64.ActiveCfg = Release|ARM64\n\t\t{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Release|ARM64.Build.0 = Release|ARM64\n\t\t{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Release|ARM64.Deploy.0 = Release|ARM64\n\t\t{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Release|x64.ActiveCfg = Release|x64\n\t\t{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Release|x64.Build.0 = Release|x64\n\t\t{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Release|x64.Deploy.0 = Release|x64\n\t\t{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Release|x86.ActiveCfg = Release|Win32\n\t\t{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Release|x86.Build.0 = Release|Win32\n\t\t{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Release|x86.Deploy.0 = Release|Win32\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {D7D1DE2E-A7C1-4FB3-A191-C848562A3EBD}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "schemas/JSON/configuration/configuration.schema.0.1.json",
    "content": "{\r\n    \"$id\": \"https://aka.ms/schemas/dsc/configuration.schema.0.1.json\",\r\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\r\n    \"description\": \"A representation of a configuration used by an orchestrator for WinDSC.\",\r\n    \"type\": \"object\",\r\n    \"properties\": {\r\n        \"properties\": {\r\n            \"type\": \"object\",\r\n            \"properties\": {\r\n                \"assertions\": {\r\n                    \"type\": \"array\",\r\n                    \"items\": { \"$ref\": \"#/$defs/resource\" }\r\n                },\r\n                \"resources\": {\r\n                    \"type\": \"array\",\r\n                    \"items\": { \"$ref\": \"#/$defs/resource\" }\r\n                },\r\n                \"parameters\": {\r\n                    \"type\": \"array\",\r\n                    \"items\": { \"$ref\": \"#/$defs/resource\" },\r\n                    \"description\": \"Resources that retrieve information via a 'get' operation.\"\r\n                },\r\n                \"configurationVersion\": {\r\n                    \"type\": \"string\",\r\n                    \"pattern\": \"^(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)(?:-((?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\\\.(?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\\\+([0-9a-zA-Z-]+(?:\\\\.[0-9a-zA-Z-]+)*))?$\",\r\n                    \"maxLength\": 128,\r\n                    \"default\": \"0.1.0\",\r\n                    \"description\": \"The configuration syntax version.\"\r\n                }\r\n            },\r\n            \"required\": [\"configurationVersion\"]\r\n        }\r\n    },\r\n\r\n    \"$defs\": {\r\n        \"resource\": {\r\n            \"type\": \"object\",\r\n            \"properties\": {\r\n                \"resource\": {\r\n                    \"type\": \"string\",\r\n                    \"maxLength\": 128,\r\n                    \"description\": \"The name of the resource.\"\r\n                },\r\n                \"id\": {\r\n                    \"type\": \"string\",\r\n                    \"maxLength\": 128,\r\n                    \"description\": \"The identifier of this item.\"\r\n                },\r\n                \"dependsOn\": {\r\n                    \"type\": [ \"array\", \"null\" ],\r\n                    \"items\": {\r\n                        \"type\": \"string\"\r\n                    },\r\n                    \"uniqueItems\": true,\r\n                    \"description\": \"The list of resource ids identifying dependencies.\"\r\n                },\r\n                \"directives\": {\r\n                    \"type\": \"object\", \r\n                    \"properties\": {\r\n                        \"module\": {\r\n                            \"type\": \"string\",\r\n                            \"maxLength\": 128,\r\n                            \"description\": \"The name of the module.\"\r\n                        },\r\n                        \"description\": {\r\n                            \"type\": \"string\",\r\n                            \"maxLength\": 512,\r\n                            \"description\": \"The description of the desired state.\"\r\n                        }\r\n                    },\r\n                    \"additionalProperties\": true\r\n                },\r\n                \"settings\": { \"type\": \"object\" }\r\n            },\r\n            \"required\": [\"resource\"]\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "schemas/JSON/configuration/configuration.schema.0.2.json",
    "content": "{\n    \"$id\": \"https://aka.ms/schemas/dsc/configuration.schema.0.2.json\",\n    \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n    \"description\": \"Description of what these resources do to apply the desired state in the configuration.\",\n    \"type\": \"object\",\n    \"properties\": {\n        \"properties\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"assertions\": {\n                    \"type\": \"array\",\n                    \"items\": { \"$ref\": \"#/$defs/resource\" },\n                    \"description\": \"The preconditions required to run the configuration.\"\n                },\n                \"resources\": {\n                    \"type\": \"array\",\n                    \"items\": { \"$ref\": \"#/$defs/resource\" },\n                    \"description\": \"A list of resources (software, tools, packages, settings, etc.) to be included in the configuration.\"\n                },\n                \"parameters\": {\n                    \"type\": \"array\",\n                    \"items\": { \"$ref\": \"#/$defs/resource\" },\n                    \"description\": \"Resources that retrieve information via a 'get' operation.\"\n                },\n                \"configurationVersion\": {\n                    \"type\": \"string\",\n                    \"pattern\": \"^(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)\\\\.(0|[1-9]\\\\d*)(?:-((?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\\\.(?:0|[1-9]\\\\d*|\\\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\\\+([0-9a-zA-Z-]+(?:\\\\.[0-9a-zA-Z-]+)*))?$\",\n                    \"maxLength\": 128,\n                    \"default\": \"0.2.0\",\n                    \"description\": \"The configuration syntax version.\"\n                }\n            },\n            \"required\": [\"configurationVersion\"],\n            \"description\": \"The properties of the configuration.\"\n        }\n    },\n\n    \"$defs\": {\n        \"resource\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"resource\": {\n                    \"type\": \"string\",\n                    \"maxLength\": 128,\n                    \"description\": \"The name of the resource. Optionally specify module and resource as module/resource.\"\n                },\n                \"id\": {\n                    \"type\": \"string\",\n                    \"maxLength\": 128,\n                    \"description\": \"A unique identifier for this resource.\"\n                },\n                \"dependsOn\": {\n                    \"type\": [ \"array\", \"null\" ],\n                    \"items\": {\n                        \"type\": \"string\"\n                    },\n                    \"uniqueItems\": true,\n                    \"description\": \"The list of resource ids identifying dependencies.\"\n                },\n                \"directives\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                        \"module\": {\n                            \"type\": \"string\",\n                            \"maxLength\": 128,\n                            \"description\": \"The name of the module.\"\n                        },\n                        \"description\": {\n                            \"type\": \"string\",\n                            \"maxLength\": 512,\n                            \"description\": \"The description of the desired state.\"\n                        },\n                        \"allowPrerelease\": {\n                            \"type\": \"boolean\",\n                            \"description\": \"Enable using prerelease modules.\"\n                        },\n                        \"securityContext\": {\n                            \"type\": \"string\",\n                            \"enum\": [ \"current\", \"restricted\", \"elevated\" ],\n                            \"description\": \"Provides an indication of the security context in which the configuration unit should be run.\"\n                        }\n                    },\n                    \"additionalProperties\": true,\n                    \"description\": \"Information about the module and/or resource.\"\n                },\n                \"settings\": {\n                    \"type\": \"object\",\n                    \"description\": \"Parameters as key-value pairs to be passed to the resource.\"\n                }\n            },\n            \"required\": [\"resource\"]\n        }\n    }\n}"
  },
  {
    "path": "schemas/JSON/manifests/latest/manifest.defaultLocale.latest.json",
    "content": "{\n  \"$id\": \"https://aka.ms/winget-manifest.defaultlocale.1.28.0.schema.json\",\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"description\": \"A representation of a multiple-file manifest representing a default app metadata in the OWC. v1.28.0\",\n  \"definitions\": {\n    \"Url\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n      \"maxLength\": 2048,\n      \"description\": \"Optional Url type\"\n    },\n    \"Tag\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 40,\n      \"description\": \"Package moniker or tag\"\n    },\n    \"Agreement\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"AgreementLabel\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 100,\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\n        },\n        \"Agreement\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 10000,\n          \"description\": \"The agreement text content.\"\n        },\n        \"AgreementUrl\": {\n          \"$ref\": \"#/definitions/Url\",\n          \"description\": \"The agreement URL.\"\n        }\n      }\n    },\n    \"Documentation\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"DocumentLabel\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 100,\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\n        },\n        \"DocumentUrl\": {\n          \"$ref\": \"#/definitions/Url\",\n          \"description\": \"The documentation URL.\"\n        }\n      }\n    },\n    \"Icon\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"IconUrl\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n          \"maxLength\": 2048,\n          \"description\": \"The url of the hosted icon file\"\n        },\n        \"IconFileType\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"png\",\n            \"jpeg\",\n            \"ico\"\n          ],\n          \"description\": \"The icon file type\"\n        },\n        \"IconResolution\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"enum\": [\n            \"custom\",\n            \"16x16\",\n            \"20x20\",\n            \"24x24\",\n            \"30x30\",\n            \"32x32\",\n            \"36x36\",\n            \"40x40\",\n            \"48x48\",\n            \"60x60\",\n            \"64x64\",\n            \"72x72\",\n            \"80x80\",\n            \"96x96\",\n            \"256x256\"\n          ],\n          \"description\": \"Optional icon resolution\"\n        },\n        \"IconTheme\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"enum\": [\n            \"default\",\n            \"light\",\n            \"dark\",\n            \"highContrast\"\n          ],\n          \"description\": \"Optional icon theme\"\n        },\n        \"IconSha256\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"Optional Sha256 of the icon file\"\n        }\n      },\n      \"required\": [\n        \"IconUrl\",\n        \"IconFileType\"\n      ]\n    }\n  },\n  \"type\": \"object\",\n  \"properties\": {\n    \"PackageIdentifier\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\n      \"maxLength\": 128,\n      \"description\": \"The package unique identifier\"\n    },\n    \"PackageVersion\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n      \"maxLength\": 128,\n      \"description\": \"The package version\"\n    },\n    \"PackageLocale\": {\n      \"type\": \"string\",\n      \"default\": \"en-US\",\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\n      \"maxLength\": 20,\n      \"description\": \"The package meta-data locale\"\n    },\n    \"Publisher\": {\n      \"type\": \"string\",\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The publisher name\"\n    },\n    \"PublisherUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher home page\"\n    },\n    \"PublisherSupportUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher support page\"\n    },\n    \"PrivacyUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher privacy page or the package privacy page\"\n    },\n    \"Author\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The package author\"\n    },\n    \"PackageName\": {\n      \"type\": \"string\",\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The package name\"\n    },\n    \"PackageUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package home page\"\n    },\n    \"License\": {\n      \"type\": \"string\",\n      \"minLength\": 3,\n      \"maxLength\": 512,\n      \"description\": \"The package license\"\n    },\n    \"LicenseUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The license page\"\n    },\n    \"Copyright\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 512,\n      \"description\": \"The package copyright\"\n    },\n    \"CopyrightUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package copyright page\"\n    },\n    \"ShortDescription\": {\n      \"type\": \"string\",\n      \"minLength\": 3,\n      \"maxLength\": 256,\n      \"description\": \"The short package description\"\n    },\n    \"Description\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 10000,\n      \"description\": \"The full package description\"\n    },\n    \"Moniker\": {\n      \"$ref\": \"#/definitions/Tag\",\n      \"description\": \"The most common package term\"\n    },\n    \"Tags\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Tag\"\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of additional package search terms\"\n    },\n    \"Agreements\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Agreement\"\n      },\n      \"maxItems\": 128\n    },\n    \"ReleaseNotes\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 10000,\n      \"description\": \"The package release notes\"\n    },\n    \"ReleaseNotesUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package release notes url\"\n    },\n    \"PurchaseUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\n    },\n    \"InstallationNotes\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 10000,\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"\n    },\n    \"Documentations\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Documentation\"\n      },\n      \"maxItems\": 256\n    },\n    \"Icons\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Icon\"\n      },\n      \"maxItems\": 1024\n    },\n    \"ManifestType\": {\n      \"type\": \"string\",\n      \"default\": \"defaultLocale\",\n      \"const\": \"defaultLocale\",\n      \"description\": \"The manifest type\"\n    },\n    \"ManifestVersion\": {\n      \"type\": \"string\",\n      \"default\": \"1.28.0\",\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\n      \"description\": \"The manifest syntax version\"\n    }\n  },\n  \"required\": [\n    \"PackageIdentifier\",\n    \"PackageVersion\",\n    \"PackageLocale\",\n    \"Publisher\",\n    \"PackageName\",\n    \"License\",\n    \"ShortDescription\",\n    \"ManifestType\",\n    \"ManifestVersion\"\n  ]\n}\n"
  },
  {
    "path": "schemas/JSON/manifests/latest/manifest.installer.latest.json",
    "content": "{\n  \"$id\": \"https://aka.ms/winget-manifest.installer.1.28.0.schema.json\",\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"description\": \"A representation of a single-file manifest representing an app installers in the OWC. v1.28.0\",\n  \"definitions\": {\n    \"PackageIdentifier\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\n      \"maxLength\": 128,\n      \"description\": \"The package unique identifier\"\n    },\n    \"PackageVersion\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n      \"maxLength\": 128,\n      \"description\": \"The package version\"\n    },\n    \"Locale\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\n      \"maxLength\": 20,\n      \"description\": \"The installer meta-data locale\"\n    },\n    \"Channel\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 16,\n      \"description\": \"The distribution channel\"\n    },\n    \"Platform\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"title\": \"Platform\",\n        \"type\": \"string\",\n        \"enum\": [\n          \"Windows.Desktop\",\n          \"Windows.Universal\"\n        ]\n      },\n      \"maxItems\": 2,\n      \"uniqueItems\": true,\n      \"description\": \"The installer supported operating system\"\n    },\n    \"MinimumOSVersion\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$\",\n      \"description\": \"The installer minimum operating system version\"\n    },\n    \"Url\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n      \"maxLength\": 2048,\n      \"description\": \"Url type\"\n    },\n    \"InstallerType\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"msix\",\n        \"msi\",\n        \"appx\",\n        \"exe\",\n        \"zip\",\n        \"inno\",\n        \"nullsoft\",\n        \"wix\",\n        \"burn\",\n        \"pwa\",\n        \"portable\",\n        \"font\"\n      ],\n      \"description\": \"Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level\"\n    },\n    \"NestedInstallerType\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"msix\",\n        \"msi\",\n        \"appx\",\n        \"exe\",\n        \"inno\",\n        \"nullsoft\",\n        \"wix\",\n        \"burn\",\n        \"portable\",\n        \"font\"\n      ],\n      \"description\": \"Enumeration of supported nested installer types contained inside an archive file\"\n    },\n    \"NestedInstallerFiles\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"object\",\n        \"title\": \"NestedInstallerFile\",\n        \"properties\": {\n          \"RelativeFilePath\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 512,\n            \"description\": \"The relative path to the nested installer file\"\n          },\n          \"PortableCommandAlias\": {\n            \"type\": [ \"string\", \"null\" ],\n            \"minLength\": 1,\n            \"maxLength\": 40,\n            \"description\": \"The command alias to be used for calling the package. Only applies to the nested portable package\"\n          }\n        },\n        \"required\": [ \"RelativeFilePath\" ],\n        \"description\": \"A nested installer file contained inside an archive\"\n      },\n      \"maxItems\": 1024,\n      \"description\": \"List of nested installer files contained inside an archive\"\n    },\n    \"Architecture\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"x86\",\n        \"x64\",\n        \"arm\",\n        \"arm64\",\n        \"neutral\"\n      ],\n      \"description\": \"The installer target architecture\"\n    },\n    \"Scope\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"user\",\n        \"machine\"\n      ],\n      \"description\": \"Scope indicates if the installer is per user or per machine\"\n    },\n    \"InstallModes\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"title\": \"InstallModes\",\n        \"type\": \"string\",\n        \"enum\": [\n          \"interactive\",\n          \"silent\",\n          \"silentWithProgress\"\n        ]\n      },\n      \"maxItems\": 3,\n      \"uniqueItems\": true,\n      \"description\": \"List of supported installer modes\"\n    },\n    \"InstallerSwitches\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"Silent\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Silent is the value that should be passed to the installer when user chooses a silent or quiet install\"\n        },\n        \"SilentWithProgress\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install\"\n        },\n        \"Interactive\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Interactive is the value that should be passed to the installer when user chooses an interactive install\"\n        },\n        \"InstallLocation\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"InstallLocation is the value passed to the installer for custom install location. <INSTALLPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\n        },\n        \"Log\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Log is the value passed to the installer for custom log file path. <LOGPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\n        },\n        \"Upgrade\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Upgrade is the value that should be passed to the installer when user chooses an upgrade\"\n        },\n        \"Custom\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 2048,\n          \"description\": \"Custom switches will be passed directly to the installer by winget\"\n        },\n        \"Repair\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"The 'Repair' value must be passed to the installer, ModifyPath ARP command, or uninstaller ARP command when the user opts for a repair.\"\n        }\n      }\n    },\n    \"InstallerReturnCode\": {\n      \"type\": \"integer\",\n      \"format\": \"long\",\n      \"not\": {\n        \"enum\": [ 0 ]\n      },\n      \"minimum\": -2147483648,\n      \"maximum\": 4294967295,\n      \"description\": \"An exit code that can be returned by the installer after execution\"\n    },\n    \"InstallerSuccessCodes\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/InstallerReturnCode\"\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of additional non-zero installer success exit codes other than known default values by winget\"\n    },\n    \"ExpectedReturnCodes\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"object\",\n        \"title\": \"ExpectedReturnCode\",\n        \"properties\": {\n          \"InstallerReturnCode\": {\n            \"$ref\": \"#/definitions/InstallerReturnCode\"\n          },\n          \"ReturnResponse\": {\n            \"type\": \"string\",\n            \"enum\": [\n              \"packageInUse\",\n              \"packageInUseByApplication\",\n              \"installInProgress\",\n              \"fileInUse\",\n              \"missingDependency\",\n              \"diskFull\",\n              \"insufficientMemory\",\n              \"invalidParameter\",\n              \"noNetwork\",\n              \"contactSupport\",\n              \"rebootRequiredToFinish\",\n              \"rebootRequiredForInstall\",\n              \"rebootInitiated\",\n              \"cancelledByUser\",\n              \"alreadyInstalled\",\n              \"downgrade\",\n              \"blockedByPolicy\",\n              \"systemNotSupported\",\n              \"custom\"\n            ]\n          },\n          \"ReturnResponseUrl\": {\n            \"$ref\": \"#/definitions/Url\",\n            \"description\": \"The return response url to provide additional guidance for expected return codes\"\n          }\n        },\n        \"required\": [ \"InstallerReturnCode\", \"ReturnResponse\" ]\n      },\n      \"maxItems\": 128,\n      \"description\": \"Installer exit codes for common errors\"\n    },\n    \"UpgradeBehavior\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"install\",\n        \"uninstallPrevious\",\n        \"deny\"\n      ],\n      \"description\": \"The upgrade method\"\n    },\n    \"Commands\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"maxLength\": 40\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of commands or aliases to run the package\"\n    },\n    \"Protocols\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"maxLength\": 2048\n      },\n      \"maxItems\": 64,\n      \"uniqueItems\": true,\n      \"description\": \"List of protocols the package provides a handler for\"\n    },\n    \"FileExtensions\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n        \"maxLength\": 64\n      },\n      \"maxItems\": 512,\n      \"uniqueItems\": true,\n      \"description\": \"List of file extensions the package could support\"\n    },\n    \"Dependencies\": {\n      \"type\": [ \"object\", \"null\" ],\n      \"properties\": {\n        \"WindowsFeatures\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 128\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of Windows feature dependencies\"\n        },\n        \"WindowsLibraries\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 128\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of Windows library dependencies\"\n        },\n        \"PackageDependencies\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"PackageIdentifier\": {\n                \"$ref\": \"#/definitions/PackageIdentifier\"\n              },\n              \"MinimumVersion\": {\n                \"$ref\": \"#/definitions/PackageVersion\"\n              }\n            },\n            \"required\": [ \"PackageIdentifier\" ]\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of package dependencies from current source\"\n        },\n        \"ExternalDependencies\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 128\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of external package dependencies\"\n        }\n      }\n    },\n    \"PackageFamilyName\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^[A-Za-z0-9][-\\\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$\",\n      \"maxLength\": 255,\n      \"description\": \"PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources\"\n    },\n    \"ProductCode\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 255,\n      \"description\": \"ProductCode could be used for correlation of packages across sources\"\n    },\n    \"Capabilities\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"maxLength\": 40\n      },\n      \"maxItems\": 1000,\n      \"uniqueItems\": true,\n      \"description\": \"List of appx or msix installer capabilities\"\n    },\n    \"RestrictedCapabilities\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"maxLength\": 40\n      },\n      \"maxItems\": 1000,\n      \"uniqueItems\": true,\n      \"description\": \"List of appx or msix installer restricted capabilities\"\n    },\n    \"Market\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[A-Z]{2}$\",\n      \"description\": \"The installer target market\"\n    },\n    \"MarketArray\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"maxItems\": 256,\n      \"items\": {\n        \"$ref\": \"#/definitions/Market\"\n      },\n      \"description\": \"Array of markets\"\n    },\n    \"Markets\": {\n      \"description\": \"The installer markets\",\n      \"type\": [ \"object\", \"null\" ],\n      \"oneOf\": [\n        {\n          \"properties\": {\n            \"AllowedMarkets\": {\n              \"$ref\": \"#/definitions/MarketArray\"\n            }\n          },\n          \"required\": [ \"AllowedMarkets\" ]\n        },\n        {\n          \"properties\": {\n            \"ExcludedMarkets\": {\n              \"$ref\": \"#/definitions/MarketArray\"\n            }\n          },\n          \"required\": [ \"ExcludedMarkets\" ]\n        }\n      ]\n    },\n    \"InstallerAbortsTerminal\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer will abort terminal. Default is false\"\n    },\n    \"ReleaseDate\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"format\": \"date\",\n      \"description\": \"The installer release date\"\n    },\n    \"InstallLocationRequired\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer requires an install location provided\"\n    },\n    \"RequireExplicitUpgrade\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer should be pinned by default from upgrade\"\n    },\n    \"DisplayInstallWarnings\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications.\"\n    },\n    \"UnsupportedOSArchitectures\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"items\": {\n        \"type\": \"string\",\n        \"title\": \"UnsupportedOSArchitecture\",\n        \"enum\": [\n          \"x86\",\n          \"x64\",\n          \"arm\",\n          \"arm64\"\n        ]\n      },\n      \"description\": \"List of OS architectures the installer does not support\"\n    },\n    \"UnsupportedArguments\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"items\": {\n        \"type\": \"string\",\n        \"title\": \"UnsupportedArgument\",\n        \"enum\": [\n          \"log\",\n          \"location\"\n        ]\n      },\n      \"description\": \"List of winget arguments the installer does not support\"\n    },\n    \"AppsAndFeaturesEntry\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"DisplayName\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 256,\n          \"description\": \"The DisplayName registry value\"\n        },\n        \"Publisher\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 256,\n          \"description\": \"The Publisher registry value\"\n        },\n        \"DisplayVersion\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 128,\n          \"description\": \"The DisplayVersion registry value\"\n        },\n        \"ProductCode\": {\n          \"$ref\": \"#/definitions/ProductCode\"\n        },\n        \"UpgradeCode\": {\n          \"$ref\": \"#/definitions/ProductCode\"\n        },\n        \"InstallerType\": {\n          \"$ref\": \"#/definitions/InstallerType\"\n        }\n      },\n      \"description\": \"Various key values under installer's ARP entry\"\n    },\n    \"AppsAndFeaturesEntries\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"maxItems\": 128,\n      \"items\": {\n        \"$ref\": \"#/definitions/AppsAndFeaturesEntry\"\n      },\n      \"description\": \"List of ARP entries.\"\n    },\n    \"ElevationRequirement\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"elevationRequired\",\n        \"elevationProhibited\",\n        \"elevatesSelf\"\n      ],\n      \"description\": \"The installer's elevation requirement\"\n    },\n    \"InstallationMetadata\": {\n      \"type\": \"object\",\n      \"title\": \"InstallationMetadata\",\n      \"properties\": {\n        \"DefaultInstallLocation\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 2048,\n          \"description\": \"Represents the default installed package location. Used for deeper installation detection.\"\n        },\n        \"Files\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"uniqueItems\": true,\n          \"maxItems\": 2048,\n          \"items\": {\n            \"type\": \"object\",\n            \"title\": \"InstalledFile\",\n            \"properties\": {\n              \"RelativeFilePath\": {\n                \"type\": \"string\",\n                \"minLength\": 1,\n                \"maxLength\": 2048,\n                \"description\": \"The relative path to the installed file.\"\n              },\n              \"FileSha256\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n                \"description\": \"Optional Sha256 of the installed file.\"\n              },\n              \"FileType\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"enum\": [\n                  \"launch\",\n                  \"uninstall\",\n                  \"other\"\n                ],\n                \"description\": \"The optional installed file type. If not specified, the file is treated as other.\"\n              },\n              \"InvocationParameter\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"minLength\": 1,\n                \"maxLength\": 2048,\n                \"description\": \"Optional parameter for invocable files.\"\n              },\n              \"DisplayName\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"minLength\": 1,\n                \"maxLength\": 256,\n                \"description\": \"Optional display name for invocable files.\"\n              }\n            },\n            \"required\": [ \"RelativeFilePath\" ],\n            \"description\": \"Represents an installed file.\"\n          },\n          \"description\": \"List of installed files.\"\n        }\n      },\n      \"description\": \"Details about the installation. Used for deeper installation detection.\"\n    },\n    \"DownloadCommandProhibited\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer is prohibited from being downloaded for offline installation.\"\n    },\n    \"RepairBehavior\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"modify\",\n        \"uninstaller\",\n        \"installer\"\n      ],\n      \"description\": \"The repair method\"\n    },\n    \"ArchiveBinariesDependOnPath\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the install location should be added directly to the PATH environment variable. Only applies to an archive containing portable packages.\"\n    },\n    \"Authentication\": {\n      \"type\": [ \"object\", \"null\" ],\n      \"properties\": {\n        \"AuthenticationType\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"none\",\n            \"microsoftEntraId\",\n            \"microsoftEntraIdForAzureBlobStorage\"\n          ],\n          \"description\": \"The authentication type\"\n        },\n        \"MicrosoftEntraIdAuthenticationInfo\": {\n          \"type\": [ \"object\", \"null\" ],\n          \"properties\": {\n            \"Resource\": {\n              \"type\": [ \"string\", \"null\" ],\n              \"minLength\": 1,\n              \"maxLength\": 512,\n              \"description\": \"The resource value for Microsoft Entra Id authentication.\"\n            },\n            \"Scope\": {\n              \"type\": [ \"string\", \"null\" ],\n              \"minLength\": 1,\n              \"maxLength\": 512,\n              \"description\": \"The scope value for Microsoft Entra Id authentication.\"\n            }\n          },\n          \"description\": \"The Microsoft Entra Id authentication info\"\n        }\n      },\n      \"required\": [\n        \"AuthenticationType\"\n      ],\n      \"description\": \"The authentication requirement for downloading the installer.\"\n    },\n    \"DesiredStateConfiguration\": {\n      \"type\": [ \"object\", \"null\" ],\n      \"description\": \"References to desired state configuration (DSC) resources that are related to the package.\",\n      \"properties\": {\n        \"PowerShell\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"description\": \"Contains data about DSC resources that are contained in PowerShell modules.\",\n          \"uniqueItems\": true,\n          \"maxItems\": 16,\n          \"items\": {\n            \"type\": \"object\",\n            \"title\": \"PowerShell DSC Module Item\",\n            \"properties\": {\n              \"RepositoryUrl\": {\n                \"$ref\": \"#/definitions/Url\"\n              },\n              \"ModuleName\": {\n                \"type\": \"string\",\n                \"description\": \"The name of the module containing resources.\",\n                \"$comment\": \"From nuget package id, although PowerShell convention is slightly more strict: https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu1017\",\n                \"pattern\": \"^\\\\w+([.-]\\\\w+)*$\",\n                \"maxLength\": 100\n              },\n              \"Resources\": {\n                \"type\": \"array\",\n                \"description\": \"The resources contained within the module.\",\n                \"maxItems\": 64,\n                \"items\": {\n                  \"type\": \"object\",\n                  \"title\": \"PowerShell DSC Resource Item\",\n                  \"properties\": {\n                    \"Name\": {\n                      \"type\": \"string\",\n                      \"description\": \"The name of the resource.\",\n                      \"$comment\": \"Needs to be an identifier in the various languages (MOF, PS class name), could not find any direct description.\",\n                      \"pattern\": \"^[A-Za-z][-_A-Za-z0-9]*$\",\n                      \"maxLength\": 100\n                    }\n                  }\n                }\n              }\n            },\n            \"required\": [ \"RepositoryUrl\", \"ModuleName\", \"Resources\" ]\n          }\n        },\n        \"DSCv3\": {\n          \"type\": [ \"object\", \"null\" ],\n          \"description\": \"Contains data about DSC resources that are contained in the package using the DSC v3 specification.\",\n          \"properties\": {\n            \"Resources\": {\n              \"type\": \"array\",\n              \"description\": \"The resources contained within the package.\",\n              \"maxItems\": 128,\n              \"items\": {\n                \"type\": \"object\",\n                \"title\": \"DSCv3 Resource Item\",\n                \"properties\": {\n                  \"Type\": {\n                    \"type\": \"string\",\n                    \"description\": \"The name of the resource.\",\n                    \"$comment\": \"Pulled from DSCv3 definition; matches `Publisher.Product.Component/ResourceName` where the Product and Component are optional.\",\n                    \"pattern\": \"^\\\\w+(\\\\.\\\\w+){0,2}\\\\/\\\\w+$\",\n                    \"maxLength\": 256\n                  }\n                }\n              }\n            }\n          },\n          \"required\": [ \"Resources\" ]\n        }\n      }\n    },\n    \"Installer\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"InstallerLocale\": {\n          \"$ref\": \"#/definitions/Locale\"\n        },\n        \"Platform\": {\n          \"$ref\": \"#/definitions/Platform\"\n        },\n        \"MinimumOSVersion\": {\n          \"$ref\": \"#/definitions/MinimumOSVersion\"\n        },\n        \"Architecture\": {\n          \"$ref\": \"#/definitions/Architecture\"\n        },\n        \"InstallerType\": {\n          \"$ref\": \"#/definitions/InstallerType\"\n        },\n        \"NestedInstallerType\": {\n          \"$ref\": \"#/definitions/NestedInstallerType\"\n        },\n        \"NestedInstallerFiles\": {\n          \"$ref\": \"#/definitions/NestedInstallerFiles\"\n        },\n        \"Scope\": {\n          \"$ref\": \"#/definitions/Scope\"\n        },\n        \"InstallerUrl\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n          \"maxLength\": 2048,\n          \"description\": \"The installer Url\"\n        },\n        \"InstallerSha256\": {\n          \"type\": \"string\",\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"Sha256 is required. Sha256 of the installer\"\n        },\n        \"SignatureSha256\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable\"\n        },\n        \"InstallModes\": {\n          \"$ref\": \"#/definitions/InstallModes\"\n        },\n        \"InstallerSwitches\": {\n          \"$ref\": \"#/definitions/InstallerSwitches\"\n        },\n        \"InstallerSuccessCodes\": {\n          \"$ref\": \"#/definitions/InstallerSuccessCodes\"\n        },\n        \"ExpectedReturnCodes\": {\n          \"$ref\": \"#/definitions/ExpectedReturnCodes\"\n        },\n        \"UpgradeBehavior\": {\n          \"$ref\": \"#/definitions/UpgradeBehavior\"\n        },\n        \"Commands\": {\n          \"$ref\": \"#/definitions/Commands\"\n        },\n        \"Protocols\": {\n          \"$ref\": \"#/definitions/Protocols\"\n        },\n        \"FileExtensions\": {\n          \"$ref\": \"#/definitions/FileExtensions\"\n        },\n        \"Dependencies\": {\n          \"$ref\": \"#/definitions/Dependencies\"\n        },\n        \"PackageFamilyName\": {\n          \"$ref\": \"#/definitions/PackageFamilyName\"\n        },\n        \"ProductCode\": {\n          \"$ref\": \"#/definitions/ProductCode\"\n        },\n        \"Capabilities\": {\n          \"$ref\": \"#/definitions/Capabilities\"\n        },\n        \"RestrictedCapabilities\": {\n          \"$ref\": \"#/definitions/RestrictedCapabilities\"\n        },\n        \"Markets\": {\n          \"$ref\": \"#/definitions/Markets\"\n        },\n        \"InstallerAbortsTerminal\": {\n          \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\n        },\n        \"ReleaseDate\": {\n          \"$ref\": \"#/definitions/ReleaseDate\"\n        },\n        \"InstallLocationRequired\": {\n          \"$ref\": \"#/definitions/InstallLocationRequired\"\n        },\n        \"RequireExplicitUpgrade\": {\n          \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\n        },\n        \"DisplayInstallWarnings\": {\n          \"$ref\": \"#/definitions/DisplayInstallWarnings\"\n        },\n        \"UnsupportedOSArchitectures\": {\n          \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\n        },\n        \"UnsupportedArguments\": {\n          \"$ref\": \"#/definitions/UnsupportedArguments\"\n        },\n        \"AppsAndFeaturesEntries\": {\n          \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\n        },\n        \"ElevationRequirement\": {\n          \"$ref\": \"#/definitions/ElevationRequirement\"\n        },\n        \"InstallationMetadata\": {\n          \"$ref\": \"#/definitions/InstallationMetadata\"\n        },\n        \"DownloadCommandProhibited\": {\n          \"$ref\": \"#/definitions/DownloadCommandProhibited\"\n        },\n        \"RepairBehavior\": {\n          \"$ref\": \"#/definitions/RepairBehavior\"\n        },\n        \"ArchiveBinariesDependOnPath\": {\n          \"$ref\": \"#/definitions/ArchiveBinariesDependOnPath\"\n        },\n        \"Authentication\": {\n          \"$ref\": \"#/definitions/Authentication\"\n        },\n        \"DesiredStateConfiguration\": {\n          \"$ref\": \"#/definitions/DesiredStateConfiguration\"\n        }\n      },\n      \"required\": [\n        \"Architecture\",\n        \"InstallerUrl\",\n        \"InstallerSha256\"\n      ]\n    }\n  },\n  \"type\": \"object\",\n  \"properties\": {\n    \"PackageIdentifier\": {\n      \"$ref\": \"#/definitions/PackageIdentifier\"\n    },\n    \"PackageVersion\": {\n      \"$ref\": \"#/definitions/PackageVersion\"\n    },\n    \"Channel\": {\n      \"$ref\": \"#/definitions/Channel\"\n    },\n    \"InstallerLocale\": {\n      \"$ref\": \"#/definitions/Locale\"\n    },\n    \"Platform\": {\n      \"$ref\": \"#/definitions/Platform\"\n    },\n    \"MinimumOSVersion\": {\n      \"$ref\": \"#/definitions/MinimumOSVersion\"\n    },\n    \"InstallerType\": {\n      \"$ref\": \"#/definitions/InstallerType\"\n    },\n    \"NestedInstallerType\": {\n      \"$ref\": \"#/definitions/NestedInstallerType\"\n    },\n    \"NestedInstallerFiles\": {\n      \"$ref\": \"#/definitions/NestedInstallerFiles\"\n    },\n    \"Scope\": {\n      \"$ref\": \"#/definitions/Scope\"\n    },\n    \"InstallModes\": {\n      \"$ref\": \"#/definitions/InstallModes\"\n    },\n    \"InstallerSwitches\": {\n      \"$ref\": \"#/definitions/InstallerSwitches\"\n    },\n    \"InstallerSuccessCodes\": {\n      \"$ref\": \"#/definitions/InstallerSuccessCodes\"\n    },\n    \"ExpectedReturnCodes\": {\n      \"$ref\": \"#/definitions/ExpectedReturnCodes\"\n    },\n    \"UpgradeBehavior\": {\n      \"$ref\": \"#/definitions/UpgradeBehavior\"\n    },\n    \"Commands\": {\n      \"$ref\": \"#/definitions/Commands\"\n    },\n    \"Protocols\": {\n      \"$ref\": \"#/definitions/Protocols\"\n    },\n    \"FileExtensions\": {\n      \"$ref\": \"#/definitions/FileExtensions\"\n    },\n    \"Dependencies\": {\n      \"$ref\": \"#/definitions/Dependencies\"\n    },\n    \"PackageFamilyName\": {\n      \"$ref\": \"#/definitions/PackageFamilyName\"\n    },\n    \"ProductCode\": {\n      \"$ref\": \"#/definitions/ProductCode\"\n    },\n    \"Capabilities\": {\n      \"$ref\": \"#/definitions/Capabilities\"\n    },\n    \"RestrictedCapabilities\": {\n      \"$ref\": \"#/definitions/RestrictedCapabilities\"\n    },\n    \"Markets\": {\n      \"$ref\": \"#/definitions/Markets\"\n    },\n    \"InstallerAbortsTerminal\": {\n      \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\n    },\n    \"ReleaseDate\": {\n      \"$ref\": \"#/definitions/ReleaseDate\"\n    },\n    \"InstallLocationRequired\": {\n      \"$ref\": \"#/definitions/InstallLocationRequired\"\n    },\n    \"RequireExplicitUpgrade\": {\n      \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\n    },\n    \"DisplayInstallWarnings\": {\n      \"$ref\": \"#/definitions/DisplayInstallWarnings\"\n    },\n    \"UnsupportedOSArchitectures\": {\n      \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\n    },\n    \"UnsupportedArguments\": {\n      \"$ref\": \"#/definitions/UnsupportedArguments\"\n    },\n    \"AppsAndFeaturesEntries\": {\n      \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\n    },\n    \"ElevationRequirement\": {\n      \"$ref\": \"#/definitions/ElevationRequirement\"\n    },\n    \"InstallationMetadata\": {\n      \"$ref\": \"#/definitions/InstallationMetadata\"\n    },\n    \"DownloadCommandProhibited\": {\n      \"$ref\": \"#/definitions/DownloadCommandProhibited\"\n    },\n    \"RepairBehavior\": {\n      \"$ref\": \"#/definitions/RepairBehavior\"\n    },\n    \"ArchiveBinariesDependOnPath\": {\n      \"$ref\": \"#/definitions/ArchiveBinariesDependOnPath\"\n    },\n    \"Authentication\": {\n      \"$ref\": \"#/definitions/Authentication\"\n    },\n    \"DesiredStateConfiguration\": {\n      \"$ref\": \"#/definitions/DesiredStateConfiguration\"\n    },\n    \"Installers\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/Installer\"\n      },\n      \"minItems\": 1,\n      \"maxItems\": 1024\n    },\n    \"ManifestType\": {\n      \"type\": \"string\",\n      \"default\": \"installer\",\n      \"const\": \"installer\",\n      \"description\": \"The manifest type\"\n    },\n    \"ManifestVersion\": {\n      \"type\": \"string\",\n      \"default\": \"1.28.0\",\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\n      \"description\": \"The manifest syntax version\"\n    }\n  },\n  \"required\": [\n    \"PackageIdentifier\",\n    \"PackageVersion\",\n    \"Installers\",\n    \"ManifestType\",\n    \"ManifestVersion\"\n  ]\n}\n"
  },
  {
    "path": "schemas/JSON/manifests/latest/manifest.locale.latest.json",
    "content": "{\n  \"$id\": \"https://aka.ms/winget-manifest.locale.1.28.0.schema.json\",\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"description\": \"A representation of a multiple-file manifest representing app metadata in other locale in the OWC. v1.28.0\",\n  \"definitions\": {\n    \"Url\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n      \"maxLength\": 2048,\n      \"description\": \"Optional Url type\"\n    },\n    \"Tag\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 40,\n      \"description\": \"Package tag\"\n    },\n    \"Agreement\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"AgreementLabel\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 100,\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\n        },\n        \"Agreement\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 10000,\n          \"description\": \"The agreement text content.\"\n        },\n        \"AgreementUrl\": {\n          \"$ref\": \"#/definitions/Url\",\n          \"description\": \"The agreement URL.\"\n        }\n      }\n    },\n    \"Documentation\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"DocumentLabel\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 100,\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\n        },\n        \"DocumentUrl\": {\n          \"$ref\": \"#/definitions/Url\",\n          \"description\": \"The documentation URL.\"\n        }\n      }\n    },\n    \"Icon\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"IconUrl\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n          \"maxLength\": 2048,\n          \"description\": \"The url of the hosted icon file\"\n        },\n        \"IconFileType\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"png\",\n            \"jpeg\",\n            \"ico\"\n          ],\n          \"description\": \"The icon file type\"\n        },\n        \"IconResolution\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"enum\": [\n            \"custom\",\n            \"16x16\",\n            \"20x20\",\n            \"24x24\",\n            \"30x30\",\n            \"32x32\",\n            \"36x36\",\n            \"40x40\",\n            \"48x48\",\n            \"60x60\",\n            \"64x64\",\n            \"72x72\",\n            \"80x80\",\n            \"96x96\",\n            \"256x256\"\n          ],\n          \"description\": \"Optional icon resolution\"\n        },\n        \"IconTheme\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"enum\": [\n            \"default\",\n            \"light\",\n            \"dark\",\n            \"highContrast\"\n          ],\n          \"description\": \"Optional icon theme\"\n        },\n        \"IconSha256\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"Optional Sha256 of the icon file\"\n        }\n      },\n      \"required\": [\n        \"IconUrl\",\n        \"IconFileType\"\n      ]\n    }\n  },\n  \"type\": \"object\",\n  \"properties\": {\n    \"PackageIdentifier\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\n      \"maxLength\": 128,\n      \"description\": \"The package unique identifier\"\n    },\n    \"PackageVersion\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n      \"maxLength\": 128,\n      \"description\": \"The package version\"\n    },\n    \"PackageLocale\": {\n      \"type\": \"string\",\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\n      \"maxLength\": 20,\n      \"description\": \"The package meta-data locale\"\n    },\n    \"Publisher\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The publisher name\"\n    },\n    \"PublisherUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher home page\"\n    },\n    \"PublisherSupportUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher support page\"\n    },\n    \"PrivacyUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher privacy page or the package privacy page\"\n    },\n    \"Author\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The package author\"\n    },\n    \"PackageName\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The package name\"\n    },\n    \"PackageUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package home page\"\n    },\n    \"License\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 512,\n      \"description\": \"The package license\"\n    },\n    \"LicenseUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The license page\"\n    },\n    \"Copyright\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 512,\n      \"description\": \"The package copyright\"\n    },\n    \"CopyrightUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package copyright page\"\n    },\n    \"ShortDescription\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 256,\n      \"description\": \"The short package description\"\n    },\n    \"Description\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 10000,\n      \"description\": \"The full package description\"\n    },\n    \"Tags\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Tag\"\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of additional package search terms\"\n    },\n    \"Agreements\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Agreement\"\n      },\n      \"maxItems\": 128\n    },\n    \"ReleaseNotes\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 10000,\n      \"description\": \"The package release notes\"\n    },\n    \"ReleaseNotesUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package release notes url\"\n    },\n    \"PurchaseUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\n    },\n    \"InstallationNotes\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 10000,\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"\n    },\n    \"Documentations\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Documentation\"\n      },\n      \"maxItems\": 256\n    },\n    \"Icons\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Icon\"\n      },\n      \"maxItems\": 1024\n    },\n    \"ManifestType\": {\n      \"type\": \"string\",\n      \"default\": \"locale\",\n      \"const\": \"locale\",\n      \"description\": \"The manifest type\"\n    },\n    \"ManifestVersion\": {\n      \"type\": \"string\",\n      \"default\": \"1.28.0\",\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\n      \"description\": \"The manifest syntax version\"\n    }\n  },\n  \"required\": [\n    \"PackageIdentifier\",\n    \"PackageVersion\",\n    \"PackageLocale\",\n    \"ManifestType\",\n    \"ManifestVersion\"\n  ]\n}\n"
  },
  {
    "path": "schemas/JSON/manifests/latest/manifest.singleton.latest.json",
    "content": "{\n  \"$id\": \"https://aka.ms/winget-manifest.singleton.1.28.0.schema.json\",\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"description\": \"A representation of a single-file manifest representing an app in the OWC. v1.28.0\",\n  \"definitions\": {\n    \"PackageIdentifier\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\n      \"maxLength\": 128,\n      \"description\": \"The package unique identifier\"\n    },\n    \"PackageVersion\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n      \"maxLength\": 128,\n      \"description\": \"The package version\"\n    },\n    \"Locale\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\n      \"maxLength\": 20,\n      \"description\": \"The package meta-data locale\"\n    },\n    \"Url\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n      \"maxLength\": 2048,\n      \"description\": \"Optional Url type\"\n    },\n    \"Tag\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 40,\n      \"description\": \"Package moniker or tag\"\n    },\n    \"Agreement\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"AgreementLabel\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 100,\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\n        },\n        \"Agreement\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 10000,\n          \"description\": \"The agreement text content.\"\n        },\n        \"AgreementUrl\": {\n          \"$ref\": \"#/definitions/Url\",\n          \"description\": \"The agreement URL.\"\n        }\n      }\n    },\n    \"Documentation\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"DocumentLabel\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 100,\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\n        },\n        \"DocumentUrl\": {\n          \"$ref\": \"#/definitions/Url\",\n          \"description\": \"The documentation URL.\"\n        }\n      }\n    },\n    \"Icon\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"IconUrl\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n          \"maxLength\": 2048,\n          \"description\": \"The url of the hosted icon file\"\n        },\n        \"IconFileType\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"png\",\n            \"jpeg\",\n            \"ico\"\n          ],\n          \"description\": \"The icon file type\"\n        },\n        \"IconResolution\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"enum\": [\n            \"custom\",\n            \"16x16\",\n            \"20x20\",\n            \"24x24\",\n            \"30x30\",\n            \"32x32\",\n            \"36x36\",\n            \"40x40\",\n            \"48x48\",\n            \"60x60\",\n            \"64x64\",\n            \"72x72\",\n            \"80x80\",\n            \"96x96\",\n            \"256x256\"\n          ],\n          \"description\": \"Optional icon resolution\"\n        },\n        \"IconTheme\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"enum\": [\n            \"default\",\n            \"light\",\n            \"dark\",\n            \"highContrast\"\n          ],\n          \"description\": \"Optional icon theme\"\n        },\n        \"IconSha256\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"Optional Sha256 of the icon file\"\n        }\n      },\n      \"required\": [\n        \"IconUrl\",\n        \"IconFileType\"\n      ]\n    },\n    \"Channel\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 16,\n      \"description\": \"The distribution channel\"\n    },\n    \"Platform\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"title\": \"Platform\",\n        \"type\": \"string\",\n        \"enum\": [\n          \"Windows.Desktop\",\n          \"Windows.Universal\"\n        ]\n      },\n      \"maxItems\": 2,\n      \"uniqueItems\": true,\n      \"description\": \"The installer supported operating system\"\n    },\n    \"MinimumOSVersion\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$\",\n      \"description\": \"The installer minimum operating system version\"\n    },\n    \"InstallerType\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"msix\",\n        \"msi\",\n        \"appx\",\n        \"exe\",\n        \"zip\",\n        \"inno\",\n        \"nullsoft\",\n        \"wix\",\n        \"burn\",\n        \"pwa\",\n        \"portable\",\n        \"font\"\n      ],\n      \"description\": \"Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level\"\n    },\n    \"NestedInstallerType\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"msix\",\n        \"msi\",\n        \"appx\",\n        \"exe\",\n        \"inno\",\n        \"nullsoft\",\n        \"wix\",\n        \"burn\",\n        \"portable\",\n        \"font\"\n      ],\n      \"description\": \"Enumeration of supported nested installer types contained inside an archive file\"\n    },\n    \"NestedInstallerFiles\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"object\",\n        \"title\": \"NestedInstallerFile\",\n        \"properties\": {\n          \"RelativeFilePath\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 512,\n            \"description\": \"The relative path to the nested installer file\"\n          },\n          \"PortableCommandAlias\": {\n            \"type\": [ \"string\", \"null\" ],\n            \"minLength\": 1,\n            \"maxLength\": 40,\n            \"description\": \"The command alias to be used for calling the package. Only applies to the nested portable package\"\n          }\n        },\n        \"required\": [ \"RelativeFilePath\" ],\n        \"description\": \"A nested installer file contained inside an archive\"\n      },\n      \"maxItems\": 1024,\n      \"description\": \"List of nested installer files contained inside an archive\"\n    },\n    \"Architecture\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"x86\",\n        \"x64\",\n        \"arm\",\n        \"arm64\",\n        \"neutral\"\n      ],\n      \"description\": \"The installer target architecture\"\n    },\n    \"Scope\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"user\",\n        \"machine\"\n      ],\n      \"description\": \"Scope indicates if the installer is per user or per machine\"\n    },\n    \"InstallModes\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"title\": \"InstallModes\",\n        \"type\": \"string\",\n        \"enum\": [\n          \"interactive\",\n          \"silent\",\n          \"silentWithProgress\"\n        ]\n      },\n      \"maxItems\": 3,\n      \"uniqueItems\": true,\n      \"description\": \"List of supported installer modes\"\n    },\n    \"InstallerSwitches\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"Silent\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Silent is the value that should be passed to the installer when user chooses a silent or quiet install\"\n        },\n        \"SilentWithProgress\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install\"\n        },\n        \"Interactive\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Interactive is the value that should be passed to the installer when user chooses an interactive install\"\n        },\n        \"InstallLocation\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"InstallLocation is the value passed to the installer for custom install location. <INSTALLPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\n        },\n        \"Log\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Log is the value passed to the installer for custom log file path. <LOGPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\n        },\n        \"Upgrade\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Upgrade is the value that should be passed to the installer when user chooses an upgrade\"\n        },\n        \"Custom\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 2048,\n          \"description\": \"Custom switches will be passed directly to the installer by winget\"\n        },\n        \"Repair\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"The 'Repair' value must be passed to the installer, ModifyPath ARP command, or uninstaller ARP command when the user opts for a repair\"\n        }\n      }\n    },\n    \"InstallerReturnCode\": {\n      \"type\": \"integer\",\n      \"format\": \"long\",\n      \"not\": {\n        \"enum\": [ 0 ]\n      },\n      \"minimum\": -2147483648,\n      \"maximum\": 4294967295,\n      \"description\": \"An exit code that can be returned by the installer after execution\"\n    },\n    \"InstallerSuccessCodes\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/InstallerReturnCode\"\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of additional non-zero installer success exit codes other than known default values by winget\"\n    },\n    \"ExpectedReturnCodes\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"object\",\n        \"title\": \"ExpectedReturnCode\",\n        \"properties\": {\n          \"InstallerReturnCode\": {\n            \"$ref\": \"#/definitions/InstallerReturnCode\"\n          },\n          \"ReturnResponse\": {\n            \"type\": \"string\",\n            \"enum\": [\n              \"packageInUse\",\n              \"packageInUseByApplication\",\n              \"installInProgress\",\n              \"fileInUse\",\n              \"missingDependency\",\n              \"diskFull\",\n              \"insufficientMemory\",\n              \"invalidParameter\",\n              \"noNetwork\",\n              \"contactSupport\",\n              \"rebootRequiredToFinish\",\n              \"rebootRequiredForInstall\",\n              \"rebootInitiated\",\n              \"cancelledByUser\",\n              \"alreadyInstalled\",\n              \"downgrade\",\n              \"blockedByPolicy\",\n              \"systemNotSupported\",\n              \"custom\"\n            ]\n          },\n          \"ReturnResponseUrl\": {\n            \"$ref\": \"#/definitions/Url\",\n            \"description\": \"The return response url to provide additional guidance for expected return codes\"\n          }\n        },\n        \"required\": [ \"InstallerReturnCode\", \"ReturnResponse\" ]\n      },\n      \"maxItems\": 128,\n      \"description\": \"Installer exit codes for common errors\"\n    },\n    \"UpgradeBehavior\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"install\",\n        \"uninstallPrevious\",\n        \"deny\"\n      ],\n      \"description\": \"The upgrade method\"\n    },\n    \"Commands\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"maxLength\": 40\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of commands or aliases to run the package\"\n    },\n    \"Protocols\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"maxLength\": 2048\n      },\n      \"maxItems\": 64,\n      \"uniqueItems\": true,\n      \"description\": \"List of protocols the package provides a handler for\"\n    },\n    \"FileExtensions\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n        \"maxLength\": 64\n      },\n      \"maxItems\": 512,\n      \"uniqueItems\": true,\n      \"description\": \"List of file extensions the package could support\"\n    },\n    \"Dependencies\": {\n      \"type\": [ \"object\", \"null\" ],\n      \"properties\": {\n        \"WindowsFeatures\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 128\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of Windows feature dependencies\"\n        },\n        \"WindowsLibraries\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 128\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of Windows library dependencies\"\n        },\n        \"PackageDependencies\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"PackageIdentifier\": {\n                \"$ref\": \"#/definitions/PackageIdentifier\"\n              },\n              \"MinimumVersion\": {\n                \"$ref\": \"#/definitions/PackageVersion\"\n              }\n            },\n            \"required\": [ \"PackageIdentifier\" ]\n          },\n          \"maxItems\": 16,\n          \"description\": \"List of package dependencies from current source\"\n        },\n        \"ExternalDependencies\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 128\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of external package dependencies\"\n        }\n      }\n    },\n    \"PackageFamilyName\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^[A-Za-z0-9][-\\\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$\",\n      \"maxLength\": 255,\n      \"description\": \"PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources\"\n    },\n    \"ProductCode\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 255,\n      \"description\": \"ProductCode could be used for correlation of packages across sources\"\n    },\n    \"Capabilities\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"maxLength\": 40\n      },\n      \"maxItems\": 1000,\n      \"uniqueItems\": true,\n      \"description\": \"List of appx or msix installer capabilities\"\n    },\n    \"RestrictedCapabilities\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"maxLength\": 40\n      },\n      \"maxItems\": 1000,\n      \"uniqueItems\": true,\n      \"description\": \"List of appx or msix installer restricted capabilities\"\n    },\n    \"Market\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[A-Z]{2}$\",\n      \"description\": \"The installer target market\"\n    },\n    \"MarketArray\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"maxItems\": 256,\n      \"items\": {\n        \"$ref\": \"#/definitions/Market\"\n      },\n      \"description\": \"Array of markets\"\n    },\n    \"Markets\": {\n      \"description\": \"The installer markets\",\n      \"type\": [ \"object\", \"null\" ],\n      \"oneOf\": [\n        {\n          \"properties\": {\n            \"AllowedMarkets\": {\n              \"$ref\": \"#/definitions/MarketArray\"\n            }\n          },\n          \"required\": [ \"AllowedMarkets\" ]\n        },\n        {\n          \"properties\": {\n            \"ExcludedMarkets\": {\n              \"$ref\": \"#/definitions/MarketArray\"\n            }\n          },\n          \"required\": [ \"ExcludedMarkets\" ]\n        }\n      ]\n    },\n    \"InstallerAbortsTerminal\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer will abort terminal. Default is false\"\n    },\n    \"ReleaseDate\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"format\": \"date\",\n      \"description\": \"The installer release date\"\n    },\n    \"InstallLocationRequired\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer requires an install location provided\"\n    },\n    \"RequireExplicitUpgrade\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer should be pinned by default from upgrade\"\n    },\n    \"DisplayInstallWarnings\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications.\"\n    },\n    \"UnsupportedOSArchitectures\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"items\": {\n        \"type\": \"string\",\n        \"title\": \"UnsupportedOSArchitecture\",\n        \"enum\": [\n          \"x86\",\n          \"x64\",\n          \"arm\",\n          \"arm64\"\n        ]\n      },\n      \"description\": \"List of OS architectures the installer does not support\"\n    },\n    \"UnsupportedArguments\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"items\": {\n        \"type\": \"string\",\n        \"title\": \"UnsupportedArgument\",\n        \"enum\": [\n          \"log\",\n          \"location\"\n        ]\n      },\n      \"description\": \"List of winget arguments the installer does not support\"\n    },\n    \"AppsAndFeaturesEntry\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"DisplayName\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 256,\n          \"description\": \"The DisplayName registry value\"\n        },\n        \"Publisher\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 256,\n          \"description\": \"The Publisher registry value\"\n        },\n        \"DisplayVersion\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 128,\n          \"description\": \"The DisplayVersion registry value\"\n        },\n        \"ProductCode\": {\n          \"$ref\": \"#/definitions/ProductCode\"\n        },\n        \"UpgradeCode\": {\n          \"$ref\": \"#/definitions/ProductCode\"\n        },\n        \"InstallerType\": {\n          \"$ref\": \"#/definitions/InstallerType\"\n        }\n      },\n      \"description\": \"Various key values under installer's ARP entry\"\n    },\n    \"AppsAndFeaturesEntries\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"maxItems\": 128,\n      \"items\": {\n        \"$ref\": \"#/definitions/AppsAndFeaturesEntry\"\n      },\n      \"description\": \"List of ARP entries.\"\n    },\n    \"ElevationRequirement\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"elevationRequired\",\n        \"elevationProhibited\",\n        \"elevatesSelf\"\n      ],\n      \"description\": \"The installer's elevation requirement\"\n    },\n    \"InstallationMetadata\": {\n      \"type\": \"object\",\n      \"title\": \"InstallationMetadata\",\n      \"properties\": {\n        \"DefaultInstallLocation\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 2048,\n          \"description\": \"Represents the default installed package location. Used for deeper installation detection.\"\n        },\n        \"Files\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"uniqueItems\": true,\n          \"maxItems\": 2048,\n          \"items\": {\n            \"type\": \"object\",\n            \"title\": \"InstalledFile\",\n            \"properties\": {\n              \"RelativeFilePath\": {\n                \"type\": \"string\",\n                \"minLength\": 1,\n                \"maxLength\": 2048,\n                \"description\": \"The relative path to the installed file.\"\n              },\n              \"FileSha256\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n                \"description\": \"Optional Sha256 of the installed file.\"\n              },\n              \"FileType\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"enum\": [\n                  \"launch\",\n                  \"uninstall\",\n                  \"other\"\n                ],\n                \"description\": \"The optional installed file type. If not specified, the file is treated as other.\"\n              },\n              \"InvocationParameter\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"minLength\": 1,\n                \"maxLength\": 2048,\n                \"description\": \"Optional parameter for invocable files.\"\n              },\n              \"DisplayName\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"minLength\": 1,\n                \"maxLength\": 256,\n                \"description\": \"Optional display name for invocable files.\"\n              }\n            },\n            \"required\": [ \"RelativeFilePath\" ],\n            \"description\": \"Represents an installed file.\"\n          },\n          \"description\": \"List of installed files.\"\n        }\n      },\n      \"description\": \"Details about the installation. Used for deeper installation detection.\"\n    },\n    \"DownloadCommandProhibited\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer is prohibited from being downloaded for offline installation.\"\n    },\n    \"RepairBehavior\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"modify\",\n        \"uninstaller\",\n        \"installer\"\n      ],\n      \"description\": \"The repair method\"\n    },\n    \"ArchiveBinariesDependOnPath\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the install location should be added directly to the PATH environment variable. Only applies to an archive containing portable packages.\"\n    },\n    \"Authentication\": {\n      \"type\": [ \"object\", \"null\" ],\n      \"properties\": {\n        \"AuthenticationType\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"none\",\n            \"microsoftEntraId\",\n            \"microsoftEntraIdForAzureBlobStorage\"\n          ],\n          \"description\": \"The authentication type\"\n        },\n        \"MicrosoftEntraIdAuthenticationInfo\": {\n          \"type\": [ \"object\", \"null\" ],\n          \"properties\": {\n            \"Resource\": {\n              \"type\": [ \"string\", \"null\" ],\n              \"minLength\": 1,\n              \"maxLength\": 512,\n              \"description\": \"The resource value for Microsoft Entra Id authentication.\"\n            },\n            \"Scope\": {\n              \"type\": [ \"string\", \"null\" ],\n              \"minLength\": 1,\n              \"maxLength\": 512,\n              \"description\": \"The scope value for Microsoft Entra Id authentication.\"\n            }\n          },\n          \"description\": \"The Microsoft Entra Id authentication info\"\n        }\n      },\n      \"required\": [\n        \"AuthenticationType\"\n      ],\n      \"description\": \"The authentication requirement for downloading the installer.\"\n    },\n    \"DesiredStateConfiguration\": {\n      \"type\": [ \"object\", \"null\" ],\n      \"description\": \"References to desired state configuration (DSC) resources that are related to the package.\",\n      \"properties\": {\n        \"PowerShell\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"description\": \"Contains data about DSC resources that are contained in PowerShell modules.\",\n          \"uniqueItems\": true,\n          \"maxItems\": 16,\n          \"items\": {\n            \"type\": \"object\",\n            \"title\": \"PowerShell DSC Module Item\",\n            \"properties\": {\n              \"RepositoryUrl\": {\n                \"$ref\": \"#/definitions/Url\"\n              },\n              \"ModuleName\": {\n                \"type\": \"string\",\n                \"description\": \"The name of the module containing resources.\",\n                \"$comment\": \"From nuget package id, although PowerShell convention is slightly more strict: https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu1017\",\n                \"pattern\": \"^\\\\w+([.-]\\\\w+)*$\",\n                \"maxLength\": 100\n              },\n              \"Resources\": {\n                \"type\": \"array\",\n                \"description\": \"The resources contained within the module.\",\n                \"maxItems\": 64,\n                \"items\": {\n                  \"type\": \"object\",\n                  \"title\": \"PowerShell DSC Resource Item\",\n                  \"properties\": {\n                    \"Name\": {\n                      \"type\": \"string\",\n                      \"description\": \"The name of the resource.\",\n                      \"$comment\": \"Needs to be an identifier in the various languages (MOF, PS class name), could not find any direct description.\",\n                      \"pattern\": \"^[A-Za-z][-_A-Za-z0-9]*$\",\n                      \"maxLength\": 100\n                    }\n                  }\n                }\n              }\n            },\n            \"required\": [ \"RepositoryUrl\", \"ModuleName\", \"Resources\" ]\n          }\n        },\n        \"DSCv3\": {\n          \"type\": [ \"object\", \"null\" ],\n          \"description\": \"Contains data about DSC resources that are contained in the package using the DSC v3 specification.\",\n          \"properties\": {\n            \"Resources\": {\n              \"type\": \"array\",\n              \"description\": \"The resources contained within the package.\",\n              \"maxItems\": 128,\n              \"items\": {\n                \"type\": \"object\",\n                \"title\": \"DSCv3 Resource Item\",\n                \"properties\": {\n                  \"Type\": {\n                    \"type\": \"string\",\n                    \"description\": \"The name of the resource.\",\n                    \"$comment\": \"Pulled from DSCv3 definition; matches `Publisher.Product.Component/ResourceName` where the Product and Component are optional.\",\n                    \"pattern\": \"^\\\\w+(\\\\.\\\\w+){0,2}\\\\/\\\\w+$\",\n                    \"maxLength\": 256\n                  }\n                }\n              }\n            }\n          },\n          \"required\": [ \"Resources\" ]\n        }\n      }\n    },\n    \"Installer\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"InstallerLocale\": {\n          \"$ref\": \"#/definitions/Locale\"\n        },\n        \"Platform\": {\n          \"$ref\": \"#/definitions/Platform\"\n        },\n        \"MinimumOSVersion\": {\n          \"$ref\": \"#/definitions/MinimumOSVersion\"\n        },\n        \"Architecture\": {\n          \"$ref\": \"#/definitions/Architecture\"\n        },\n        \"InstallerType\": {\n          \"$ref\": \"#/definitions/InstallerType\"\n        },\n        \"NestedInstallerType\": {\n          \"$ref\": \"#/definitions/NestedInstallerType\"\n        },\n        \"NestedInstallerFiles\": {\n          \"$ref\": \"#/definitions/NestedInstallerFiles\"\n        },\n        \"Scope\": {\n          \"$ref\": \"#/definitions/Scope\"\n        },\n        \"InstallerUrl\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n          \"maxLength\": 2048,\n          \"description\": \"The installer Url\"\n        },\n        \"InstallerSha256\": {\n          \"type\": \"string\",\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"Sha256 is required. Sha256 of the installer\"\n        },\n        \"SignatureSha256\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable\"\n        },\n        \"InstallModes\": {\n          \"$ref\": \"#/definitions/InstallModes\"\n        },\n        \"InstallerSwitches\": {\n          \"$ref\": \"#/definitions/InstallerSwitches\"\n        },\n        \"InstallerSuccessCodes\": {\n          \"$ref\": \"#/definitions/InstallerSuccessCodes\"\n        },\n        \"ExpectedReturnCodes\": {\n          \"$ref\": \"#/definitions/ExpectedReturnCodes\"\n        },\n        \"UpgradeBehavior\": {\n          \"$ref\": \"#/definitions/UpgradeBehavior\"\n        },\n        \"Commands\": {\n          \"$ref\": \"#/definitions/Commands\"\n        },\n        \"Protocols\": {\n          \"$ref\": \"#/definitions/Protocols\"\n        },\n        \"FileExtensions\": {\n          \"$ref\": \"#/definitions/FileExtensions\"\n        },\n        \"Dependencies\": {\n          \"$ref\": \"#/definitions/Dependencies\"\n        },\n        \"PackageFamilyName\": {\n          \"$ref\": \"#/definitions/PackageFamilyName\"\n        },\n        \"ProductCode\": {\n          \"$ref\": \"#/definitions/ProductCode\"\n        },\n        \"Capabilities\": {\n          \"$ref\": \"#/definitions/Capabilities\"\n        },\n        \"RestrictedCapabilities\": {\n          \"$ref\": \"#/definitions/RestrictedCapabilities\"\n        },\n        \"Markets\": {\n          \"$ref\": \"#/definitions/Markets\"\n        },\n        \"InstallerAbortsTerminal\": {\n          \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\n        },\n        \"ReleaseDate\": {\n          \"$ref\": \"#/definitions/ReleaseDate\"\n        },\n        \"InstallLocationRequired\": {\n          \"$ref\": \"#/definitions/InstallLocationRequired\"\n        },\n        \"RequireExplicitUpgrade\": {\n          \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\n        },\n        \"DisplayInstallWarnings\": {\n          \"$ref\": \"#/definitions/DisplayInstallWarnings\"\n        },\n        \"UnsupportedOSArchitectures\": {\n          \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\n        },\n        \"UnsupportedArguments\": {\n          \"$ref\": \"#/definitions/UnsupportedArguments\"\n        },\n        \"AppsAndFeaturesEntries\": {\n          \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\n        },\n        \"ElevationRequirement\": {\n          \"$ref\": \"#/definitions/ElevationRequirement\"\n        },\n        \"InstallationMetadata\": {\n          \"$ref\": \"#/definitions/InstallationMetadata\"\n        },\n        \"DownloadCommandProhibited\": {\n          \"$ref\": \"#/definitions/DownloadCommandProhibited\"\n        },\n        \"RepairBehavior\": {\n          \"$ref\": \"#/definitions/RepairBehavior\"\n        },\n        \"ArchiveBinariesDependOnPath\": {\n          \"$ref\": \"#/definitions/ArchiveBinariesDependOnPath\"\n        },\n        \"Authentication\": {\n          \"$ref\": \"#/definitions/Authentication\"\n        },\n        \"DesiredStateConfiguration\": {\n          \"$ref\": \"#/definitions/DesiredStateConfiguration\"\n        }\n      },\n      \"required\": [\n        \"Architecture\",\n        \"InstallerUrl\",\n        \"InstallerSha256\"\n      ]\n    }\n  },\n  \"type\": \"object\",\n  \"properties\": {\n    \"PackageIdentifier\": {\n      \"$ref\": \"#/definitions/PackageIdentifier\"\n    },\n    \"PackageVersion\": {\n      \"$ref\": \"#/definitions/PackageVersion\"\n    },\n    \"PackageLocale\": {\n      \"$ref\": \"#/definitions/Locale\"\n    },\n    \"Publisher\": {\n      \"type\": \"string\",\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The publisher name\"\n    },\n    \"PublisherUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher home page\"\n    },\n    \"PublisherSupportUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher support page\"\n    },\n    \"PrivacyUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher privacy page or the package privacy page\"\n    },\n    \"Author\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The package author\"\n    },\n    \"PackageName\": {\n      \"type\": \"string\",\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The package name\"\n    },\n    \"PackageUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package home page\"\n    },\n    \"License\": {\n      \"type\": \"string\",\n      \"minLength\": 3,\n      \"maxLength\": 512,\n      \"description\": \"The package license\"\n    },\n    \"LicenseUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The license page\"\n    },\n    \"Copyright\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 512,\n      \"description\": \"The package copyright\"\n    },\n    \"CopyrightUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package copyright page\"\n    },\n    \"ShortDescription\": {\n      \"type\": \"string\",\n      \"minLength\": 3,\n      \"maxLength\": 256,\n      \"description\": \"The short package description\"\n    },\n    \"Description\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 10000,\n      \"description\": \"The full package description\"\n    },\n    \"Moniker\": {\n      \"$ref\": \"#/definitions/Tag\",\n      \"description\": \"The most common package term\"\n    },\n    \"Tags\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Tag\"\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of additional package search terms\"\n    },\n    \"Agreements\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Agreement\"\n      },\n      \"maxItems\": 128\n    },\n    \"ReleaseNotes\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 10000,\n      \"description\": \"The package release notes\"\n    },\n    \"ReleaseNotesUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package release notes url\"\n    },\n    \"PurchaseUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\n    },\n    \"InstallationNotes\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 10000,\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"\n    },\n    \"Documentations\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Documentation\"\n      },\n      \"maxItems\": 256\n    },\n    \"Icons\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Icon\"\n      },\n      \"maxItems\": 1024\n    },\n    \"Channel\": {\n      \"$ref\": \"#/definitions/Channel\"\n    },\n    \"InstallerLocale\": {\n      \"$ref\": \"#/definitions/Locale\"\n    },\n    \"Platform\": {\n      \"$ref\": \"#/definitions/Platform\"\n    },\n    \"MinimumOSVersion\": {\n      \"$ref\": \"#/definitions/MinimumOSVersion\"\n    },\n    \"InstallerType\": {\n      \"$ref\": \"#/definitions/InstallerType\"\n    },\n    \"NestedInstallerType\": {\n      \"$ref\": \"#/definitions/NestedInstallerType\"\n    },\n    \"NestedInstallerFiles\": {\n      \"$ref\": \"#/definitions/NestedInstallerFiles\"\n    },\n    \"Scope\": {\n      \"$ref\": \"#/definitions/Scope\"\n    },\n    \"InstallModes\": {\n      \"$ref\": \"#/definitions/InstallModes\"\n    },\n    \"InstallerSwitches\": {\n      \"$ref\": \"#/definitions/InstallerSwitches\"\n    },\n    \"InstallerSuccessCodes\": {\n      \"$ref\": \"#/definitions/InstallerSuccessCodes\"\n    },\n    \"ExpectedReturnCodes\": {\n      \"$ref\": \"#/definitions/ExpectedReturnCodes\"\n    },\n    \"UpgradeBehavior\": {\n      \"$ref\": \"#/definitions/UpgradeBehavior\"\n    },\n    \"Commands\": {\n      \"$ref\": \"#/definitions/Commands\"\n    },\n    \"Protocols\": {\n      \"$ref\": \"#/definitions/Protocols\"\n    },\n    \"FileExtensions\": {\n      \"$ref\": \"#/definitions/FileExtensions\"\n    },\n    \"Dependencies\": {\n      \"$ref\": \"#/definitions/Dependencies\"\n    },\n    \"PackageFamilyName\": {\n      \"$ref\": \"#/definitions/PackageFamilyName\"\n    },\n    \"ProductCode\": {\n      \"$ref\": \"#/definitions/ProductCode\"\n    },\n    \"Capabilities\": {\n      \"$ref\": \"#/definitions/Capabilities\"\n    },\n    \"RestrictedCapabilities\": {\n      \"$ref\": \"#/definitions/RestrictedCapabilities\"\n    },\n    \"Markets\": {\n      \"$ref\": \"#/definitions/Markets\"\n    },\n    \"InstallerAbortsTerminal\": {\n      \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\n    },\n    \"ReleaseDate\": {\n      \"$ref\": \"#/definitions/ReleaseDate\"\n    },\n    \"InstallLocationRequired\": {\n      \"$ref\": \"#/definitions/InstallLocationRequired\"\n    },\n    \"RequireExplicitUpgrade\": {\n      \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\n    },\n    \"DisplayInstallWarnings\": {\n      \"$ref\": \"#/definitions/DisplayInstallWarnings\"\n    },\n    \"UnsupportedOSArchitectures\": {\n      \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\n    },\n    \"UnsupportedArguments\": {\n      \"$ref\": \"#/definitions/UnsupportedArguments\"\n    },\n    \"AppsAndFeaturesEntries\": {\n      \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\n    },\n    \"ElevationRequirement\": {\n      \"$ref\": \"#/definitions/ElevationRequirement\"\n    },\n    \"InstallationMetadata\": {\n      \"$ref\": \"#/definitions/InstallationMetadata\"\n    },\n    \"DownloadCommandProhibited\": {\n      \"$ref\": \"#/definitions/DownloadCommandProhibited\"\n    },\n    \"RepairBehavior\": {\n      \"$ref\": \"#/definitions/RepairBehavior\"\n    },\n    \"ArchiveBinariesDependOnPath\": {\n      \"$ref\": \"#/definitions/ArchiveBinariesDependOnPath\"\n    },\n    \"Authentication\": {\n      \"$ref\": \"#/definitions/Authentication\"\n    },\n    \"DesiredStateConfiguration\": {\n      \"$ref\": \"#/definitions/DesiredStateConfiguration\"\n    },\n    \"Installers\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/Installer\"\n      },\n      \"minItems\": 1,\n      \"maxItems\": 1\n    },\n    \"ManifestType\": {\n      \"type\": \"string\",\n      \"default\": \"singleton\",\n      \"const\": \"singleton\",\n      \"description\": \"The manifest type\"\n    },\n    \"ManifestVersion\": {\n      \"type\": \"string\",\n      \"default\": \"1.28.0\",\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\n      \"description\": \"The manifest syntax version\"\n    }\n  },\n  \"required\": [\n    \"PackageIdentifier\",\n    \"PackageVersion\",\n    \"PackageLocale\",\n    \"Publisher\",\n    \"PackageName\",\n    \"License\",\n    \"ShortDescription\",\n    \"Installers\",\n    \"ManifestType\",\n    \"ManifestVersion\"\n  ]\n}\n"
  },
  {
    "path": "schemas/JSON/manifests/latest/manifest.version.latest.json",
    "content": "{\n  \"$id\": \"https://aka.ms/winget-manifest.version.1.28.0.schema.json\",\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"description\": \"A representation of a multi-file manifest representing an app version in the OWC. v1.28.0\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"PackageIdentifier\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\n      \"maxLength\": 128,\n      \"description\": \"The package unique identifier\"\n    },\n    \"PackageVersion\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n      \"maxLength\": 128,\n      \"description\": \"The package version\"\n    },\n    \"DefaultLocale\": {\n      \"type\": \"string\",\n      \"default\": \"en-US\",\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\n      \"maxLength\": 20,\n      \"description\": \"The default package meta-data locale\"\n    },\n    \"ManifestType\": {\n      \"type\": \"string\",\n      \"default\": \"version\",\n      \"const\": \"version\",\n      \"description\": \"The manifest type\"\n    },\n    \"ManifestVersion\": {\n      \"type\": \"string\",\n      \"default\": \"1.28.0\",\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\n      \"description\": \"The manifest syntax version\"\n    }\n  },\n  \"required\": [\n    \"PackageIdentifier\",\n    \"PackageVersion\",\n    \"DefaultLocale\",\n    \"ManifestType\",\n    \"ManifestVersion\"\n  ]\n}\n"
  },
  {
    "path": "schemas/JSON/manifests/preview/manifest.0.1.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.0.1.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A single-file manifest representing a package in winget community repo. v0.1.0 Preview\",\r\n  \"definitions\": {\r\n    \"InstallerType\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^(([Ee][Xx][Ee])|([Mm][Ss][Ii])|([Mm][Ss][Ii][Xx])|([Ii][Nn][Nn][Oo])|([Ww][Ii][Xx])|([Nn][Uu][Ll][Ll][Ss][Oo][Ff][Tt])|([Aa][Pp][Pp][Xx])|([Zz][Ii][Pp])|([Bb][Uu][Rr][Nn]))$\",\r\n      \"description\": \"InstallerType is required under Installer node if it's not defined in root\"\r\n    },\r\n    \"UpdateBehavior\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^(([Ii][Nn][Ss][Tt][Aa][Ll][Ll])|([Uu][Nn][Ii][Nn][Ss][Tt][Aa][Ll][Ll][Pp][Rr][Ee][Vv][Ii][Oo][Uu][Ss]))$\",\r\n      \"description\": \"UpdateBehavior is used to specify desired action during package upgrade\"\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^[A-Za-z0-9][-\\\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$\",\r\n      \"maxLength\": 255,\r\n      \"description\": \"PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 255,\r\n      \"description\": \"ProductCode could be used for correlation of packages across sources\"\r\n    },\r\n    \"Description\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"Description of the package\"\r\n    },\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048\r\n    },\r\n    \"Homepage\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"Homepage is a Url where the user can find more information about the package\"\r\n    },\r\n    \"LicenseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"LicenseUrl provides a link to the license for the user to read\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"properties\": {\r\n        \"Custom\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 2048,\r\n          \"description\": \"Custom switches will be passed directly to the installer by winget\"\r\n        },\r\n        \"Silent\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Silent is the value that should be passed to the installer when user chooses a silent or quiet install\"\r\n        },\r\n        \"SilentWithProgress\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install\"\r\n        },\r\n        \"Interactive\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Interactive is the value that should be passed to the installer when user chooses an interactive install\"\r\n        },\r\n        \"Language\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Some installers include all localized resources. By specifying a Language switch, winget will pass the value of Language to the installer. This is not yet supported in Preview releases\"\r\n        },\r\n        \"Log\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Log is the value passed to the installer for custom log file path. <LOGPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"InstallLocation\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"InstallLocation is the value passed to the installer for custom install location. <INSTALLPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Update\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Update is the value that should be passed to the installer when user chooses an upgrade\"\r\n        }\r\n      }\r\n    },\r\n    \"Installer\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"Arch\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^(([Aa][Rr][Mm])|([Xx]86)|([Xx]64)|([Aa][Rr][Mm]64)|([Nn][Ee][Uu][Tt][Rr][Aa][Ll]))$\",\r\n          \"description\": \"Arch is required. The installer architecture\"\r\n        },\r\n        \"Url\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n          \"maxLength\": 2048,\r\n          \"description\": \"Url is required. The path to the installer.\"\r\n        },\r\n        \"Sha256\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"Sha256 is required. Sha256 of the installer\"\r\n        },\r\n        \"SignatureSha256\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable\"\r\n        },\r\n        \"Language\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 2,\r\n          \"maxLength\": 20,\r\n          \"description\": \"Language is the specific language of the installer. Language must follow IETF language tag guidelines\"\r\n        },\r\n        \"Scope\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"pattern\": \"^(([Uu][Ss][Ee][Rr])|([Mm][Aa][Cc][Hh][Ii][Nn][Ee]))$\",\r\n          \"description\": \"Scope indicates if the installer is per user or per machine. Scope is not yet supported in Preview releases\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        },\r\n        \"UpdateBehavior\": {\r\n          \"$ref\": \"#/definitions/UpdateBehavior\"\r\n        },\r\n        \"PackageFamilyName\": {\r\n          \"$ref\": \"#/definitions/PackageFamilyName\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"Switches\": {\r\n          \"$ref\": \"#/definitions/InstallerSwitches\"\r\n        }\r\n      },\r\n      \"required\": [\r\n        \"Arch\",\r\n        \"Url\",\r\n        \"Sha256\"\r\n      ]\r\n    },\r\n    \"ManifestLocalization\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"Language\": {\r\n          \"type\": \"string\",\r\n          \"minLength\": 2,\r\n          \"maxLength\": 20,\r\n          \"description\": \"Language is the specific language of the localization. Language must follow IETF language tag guidelines\"\r\n        },\r\n        \"Description\": {\r\n          \"$ref\": \"#/definitions/Description\"\r\n        },\r\n        \"Homepage\": {\r\n          \"$ref\": \"#/definitions/Homepage\"\r\n        },\r\n        \"LicenseUrl\": {\r\n          \"$ref\": \"#/definitions/LicenseUrl\"\r\n        }\r\n      },\r\n      \"required\": [\r\n        \"Language\"\r\n      ]\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"0.1.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    },\r\n    \"Id\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+\\\\.[^\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 255,\r\n      \"description\": \"Id is a required field. It MUST include the publisher name and package name separated by a period. For example: Publisher.Package\"\r\n    },\r\n    \"Name\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 1,\r\n      \"maxLength\": 128,\r\n      \"description\": \"Name is a required field. The name of the package\"\r\n    },\r\n    \"Version\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"minLength\": 1,\r\n      \"description\": \"Version is a required field. The version of the package\"\r\n    },\r\n    \"Publisher\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 1,\r\n      \"maxLength\": 128,\r\n      \"description\": \"Publisher is a required field. The legal publisher name\"\r\n    },\r\n    \"AppMoniker\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 100,\r\n      \"description\": \"AppMoniker is the common name someone may use to search for the package\"\r\n    },\r\n    \"Channel\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 40,\r\n      \"description\": \"Channel a string representing the flight ring. For example: stable, beta, canary\"\r\n    },\r\n    \"Author\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 100,\r\n      \"description\": \"The person or company responsible for authoring the package\"\r\n    },\r\n    \"License\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 1,\r\n      \"maxLength\": 1000,\r\n      \"description\": \"License is a required field. License provides the type of license the package is provided under\"\r\n    },\r\n    \"MinOSVersion\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$\",\r\n      \"description\": \"MinOSVersion uses the Windows version to limit installations on unsupported platforms\"\r\n    },\r\n    \"Tags\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 1000,\r\n      \"description\": \"Tags is a comma separated list. They represent strings that user may use to search for the package\"\r\n    },\r\n    \"Commands\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 1000,\r\n      \"description\": \"Commands is a comma separated list. They are the common executable or alias that user might type trying to run the package\"\r\n    },\r\n    \"Protocols\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 1000,\r\n      \"description\": \"Protocols is a comma separated list. Protocols provides the list of protocols the package provides a handler for\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 1000,\r\n      \"description\": \"FileExtensions is a comma separated list. FileExtensions provides the list of extensions the package can support\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"$ref\": \"#/definitions/InstallerType\"\r\n    },\r\n    \"UpdateBehavior\": {\r\n      \"$ref\": \"#/definitions/UpdateBehavior\"\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"$ref\": \"#/definitions/PackageFamilyName\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"$ref\": \"#/definitions/ProductCode\"\r\n    },\r\n    \"Description\": {\r\n      \"$ref\": \"#/definitions/Description\"\r\n    },\r\n    \"Homepage\": {\r\n      \"$ref\": \"#/definitions/Homepage\"\r\n    },\r\n    \"LicenseUrl\": {\r\n      \"$ref\": \"#/definitions/LicenseUrl\"\r\n    },\r\n    \"Switches\": {\r\n      \"$ref\": \"#/definitions/InstallerSwitches\"\r\n    },\r\n    \"Installers\": {\r\n      \"type\": \"array\",\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Installer\"\r\n      },\r\n      \"minItems\": 1,\r\n      \"uniqueItems\": true\r\n    },\r\n    \"Localization\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/ManifestLocalization\"\r\n      }\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"Id\",\r\n    \"Name\",\r\n    \"Version\",\r\n    \"Publisher\",\r\n    \"License\",\r\n    \"Installers\"\r\n  ]\r\n}"
  },
  {
    "path": "schemas/JSON/manifests/v1.0.0/manifest.defaultLocale.1.0.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.defaultlocale.1.0.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a multiple-file manifest representing a default app metadata in the OWC. v1.0.0\",\r\n  \"definitions\": {\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Optional Url type\"\r\n    },\r\n    \"Tag\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 40,\r\n      \"description\": \"Package moniker or tag\"\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,3}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"PackageLocale\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"en-US\",\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The package meta-data locale\"\r\n    },\r\n    \"Publisher\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The publisher name\"\r\n    },\r\n    \"PublisherUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher home page\"\r\n    },\r\n    \"PublisherSupportUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher support page\"\r\n    },\r\n    \"PrivacyUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher privacy page or the package privacy page\"\r\n    },\r\n    \"Author\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package author\"\r\n    },\r\n    \"PackageName\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package name\"\r\n    },\r\n    \"PackageUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package home page\"\r\n    },\r\n    \"License\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package license\"\r\n    },\r\n    \"LicenseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The license page\"\r\n    },\r\n    \"Copyright\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package copyright\"\r\n    },\r\n    \"CopyrightUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package copyright page\"\r\n    },\r\n    \"ShortDescription\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The short package description\"\r\n    },\r\n    \"Description\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The full package description\"\r\n    },\r\n    \"Moniker\": {\r\n      \"$ref\": \"#/definitions/Tag\",\r\n      \"description\": \"The most common package term\"\r\n    },\r\n    \"Tags\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Tag\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional package search terms\"\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"defaultLocale\",\r\n      \"const\": \"defaultLocale\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.0.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"PackageLocale\",\r\n    \"Publisher\",\r\n    \"PackageName\",\r\n    \"License\",\r\n    \"ShortDescription\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}"
  },
  {
    "path": "schemas/JSON/manifests/v1.0.0/manifest.installer.1.0.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.installer.1.0.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a single-file manifest representing an app installers in the OWC. v1.0.0\",\r\n  \"definitions\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,3}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"Locale\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The installer meta-data locale\"\r\n    },\r\n    \"Channel\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 16,\r\n      \"description\": \"The distribution channel\"\r\n    },\r\n    \"Platform\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"Platform\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"Windows.Desktop\",\r\n          \"Windows.Universal\"\r\n        ]\r\n      },\r\n      \"maxItems\": 2,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"The installer supported operating system\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$\",\r\n      \"description\": \"The installer minimum operating system version\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"msix\",\r\n        \"msi\",\r\n        \"appx\",\r\n        \"exe\",\r\n        \"inno\",\r\n        \"nullsoft\",\r\n        \"wix\",\r\n        \"burn\",\r\n        \"pwa\"\r\n      ],\r\n      \"description\": \"Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level\"\r\n    },\r\n    \"Scope\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"user\",\r\n        \"machine\"\r\n      ],\r\n      \"description\": \"Scope indicates if the installer is per user or per machine\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"InstallModes\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"interactive\",\r\n          \"silent\",\r\n          \"silentWithProgress\"\r\n        ]\r\n      },\r\n      \"maxItems\": 3,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of supported installer modes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"Silent\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Silent is the value that should be passed to the installer when user chooses a silent or quiet install\"\r\n        },\r\n        \"SilentWithProgress\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install\"\r\n        },\r\n        \"Interactive\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Interactive is the value that should be passed to the installer when user chooses an interactive install\"\r\n        },\r\n        \"InstallLocation\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"InstallLocation is the value passed to the installer for custom install location. <INSTALLPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Log\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Log is the value passed to the installer for custom log file path. <LOGPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Upgrade\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Upgrade is the value that should be passed to the installer when user chooses an upgrade\"\r\n        },\r\n        \"Custom\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 2048,\r\n          \"description\": \"Custom switches will be passed directly to the installer by winget\"\r\n        }\r\n      }\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"integer\",\r\n        \"format\": \"long\",\r\n        \"not\": {\r\n          \"enum\": [ 0 ]\r\n        },\r\n        \"minimum\": -2147483648,\r\n        \"maximum\": 4294967295\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional non-zero installer success exit codes other than known default values by winget\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"install\",\r\n        \"uninstallPrevious\"\r\n      ],\r\n      \"description\": \"The upgrade method\"\r\n    },\r\n    \"Commands\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of commands or aliases to run the package\"\r\n    },\r\n    \"Protocols\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"pattern\": \"^[a-z][-a-z0-9\\\\.\\\\+]*$\",\r\n        \"maxLength\": 2048\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of protocols the package provides a handler for\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n        \"maxLength\": 64\r\n      },\r\n      \"maxItems\": 256,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of file extensions the package could support\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"properties\": {\r\n        \"WindowsFeatures\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows feature dependencies\"\r\n        },\r\n        \"WindowsLibraries\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows library dependencies\"\r\n        },\r\n        \"PackageDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"object\",\r\n            \"properties\": {\r\n              \"PackageIdentifier\": {\r\n                \"$ref\": \"#/definitions/PackageIdentifier\"\r\n              },\r\n              \"MinimumVersion\": {\r\n                \"$ref\": \"#/definitions/PackageVersion\"\r\n              }\r\n            },\r\n            \"required\": [ \"PackageIdentifier\" ]\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of package dependencies from current source\"\r\n        },\r\n        \"ExternalDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of external package dependencies\"\r\n        }\r\n      }\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^[A-Za-z0-9][-\\\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$\",\r\n      \"maxLength\": 255,\r\n      \"description\": \"PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 255,\r\n      \"description\": \"ProductCode could be used for correlation of packages across sources\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer restricted capabilities\"\r\n    },\r\n    \"Installer\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"InstallerLocale\": {\r\n          \"$ref\": \"#/definitions/Locale\"\r\n        },\r\n        \"Platform\": {\r\n          \"$ref\": \"#/definitions/Platform\"\r\n        },\r\n        \"MinimumOSVersion\": {\r\n          \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n        },\r\n        \"Architecture\": {\r\n          \"type\": \"string\",\r\n          \"enum\": [\r\n            \"x86\",\r\n            \"x64\",\r\n            \"arm\",\r\n            \"arm64\",\r\n            \"neutral\"\r\n          ],\r\n          \"description\": \"The installer target architecture\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        },\r\n        \"Scope\": {\r\n          \"$ref\": \"#/definitions/Scope\"\r\n        },\r\n        \"InstallerUrl\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n          \"maxLength\": 2048,\r\n          \"description\": \"The installer Url\"\r\n        },\r\n        \"InstallerSha256\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"Sha256 is required. Sha256 of the installer\"\r\n        },\r\n        \"SignatureSha256\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable\"\r\n        },\r\n        \"InstallModes\": {\r\n          \"$ref\": \"#/definitions/InstallModes\"\r\n        },\r\n        \"InstallerSwitches\": {\r\n          \"$ref\": \"#/definitions/InstallerSwitches\"\r\n        },\r\n        \"InstallerSuccessCodes\": {\r\n          \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n        },\r\n        \"UpgradeBehavior\": {\r\n          \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n        },\r\n        \"Commands\": {\r\n          \"$ref\": \"#/definitions/Commands\"\r\n        },\r\n        \"Protocols\": {\r\n          \"$ref\": \"#/definitions/Protocols\"\r\n        },\r\n        \"FileExtensions\": {\r\n          \"$ref\": \"#/definitions/FileExtensions\"\r\n        },\r\n        \"Dependencies\": {\r\n          \"$ref\": \"#/definitions/Dependencies\"\r\n        },\r\n        \"PackageFamilyName\": {\r\n          \"$ref\": \"#/definitions/PackageFamilyName\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"Capabilities\": {\r\n          \"$ref\": \"#/definitions/Capabilities\"\r\n        },\r\n        \"RestrictedCapabilities\": {\r\n          \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n        }\r\n      },\r\n      \"required\": [\r\n        \"Architecture\",\r\n        \"InstallerUrl\",\r\n        \"InstallerSha256\"\r\n      ]\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"$ref\": \"#/definitions/PackageIdentifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"$ref\": \"#/definitions/PackageVersion\"\r\n    },\r\n    \"Channel\": {\r\n      \"$ref\": \"#/definitions/Channel\"\r\n    },\r\n    \"InstallerLocale\": {\r\n      \"$ref\": \"#/definitions/Locale\"\r\n    },\r\n    \"Platform\": {\r\n      \"$ref\": \"#/definitions/Platform\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"$ref\": \"#/definitions/InstallerType\"\r\n    },\r\n    \"Scope\": {\r\n      \"$ref\": \"#/definitions/Scope\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"$ref\": \"#/definitions/InstallModes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"$ref\": \"#/definitions/InstallerSwitches\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n    },\r\n    \"Commands\": {\r\n      \"$ref\": \"#/definitions/Commands\"\r\n    },\r\n    \"Protocols\": {\r\n      \"$ref\": \"#/definitions/Protocols\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"$ref\": \"#/definitions/FileExtensions\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"$ref\": \"#/definitions/Dependencies\"\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"$ref\": \"#/definitions/PackageFamilyName\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"$ref\": \"#/definitions/ProductCode\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"$ref\": \"#/definitions/Capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n    },\r\n    \"Installers\": {\r\n      \"type\": \"array\",\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Installer\"\r\n      },\r\n      \"minItems\": 1,\r\n      \"maxItems\": 128\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"installer\",\r\n      \"const\": \"installer\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.0.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"Installers\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}"
  },
  {
    "path": "schemas/JSON/manifests/v1.0.0/manifest.locale.1.0.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.locale.1.0.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a multiple-file manifest representing app metadata in other locale in the OWC. v1.0.0\",\r\n  \"definitions\": {\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Optional Url type\"\r\n    },\r\n    \"Tag\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 40,\r\n      \"description\": \"Package tag\"\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,3}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"PackageLocale\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The package meta-data locale\"\r\n    },\r\n    \"Publisher\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The publisher name\"\r\n    },\r\n    \"PublisherUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher home page\"\r\n    },\r\n    \"PublisherSupportUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher support page\"\r\n    },\r\n    \"PrivacyUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher privacy page or the package privacy page\"\r\n    },\r\n    \"Author\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package author\"\r\n    },\r\n    \"PackageName\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package name\"\r\n    },\r\n    \"PackageUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package home page\"\r\n    },\r\n    \"License\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package license\"\r\n    },\r\n    \"LicenseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The license page\"\r\n    },\r\n    \"Copyright\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package copyright\"\r\n    },\r\n    \"CopyrightUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package copyright page\"\r\n    },\r\n    \"ShortDescription\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The short package description\"\r\n    },\r\n    \"Description\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The full package description\"\r\n    },\r\n    \"Tags\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Tag\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional package search terms\"\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"locale\",\r\n      \"const\": \"locale\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.0.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"PackageLocale\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}"
  },
  {
    "path": "schemas/JSON/manifests/v1.0.0/manifest.singleton.1.0.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.singleton.1.0.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a single-file manifest representing an app in the OWC. v1.0.0\",\r\n  \"definitions\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,3}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"Locale\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The package meta-data locale\"\r\n    },\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Optional Url type\"\r\n    },\r\n    \"Tag\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 40,\r\n      \"description\": \"Package moniker or tag\"\r\n    },\r\n    \"Channel\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 16,\r\n      \"description\": \"The distribution channel\"\r\n    },\r\n    \"Platform\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"Platform\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"Windows.Desktop\",\r\n          \"Windows.Universal\"\r\n        ]\r\n      },\r\n      \"maxItems\": 2,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"The installer supported operating system\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$\",\r\n      \"description\": \"The installer minimum operating system version\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"msix\",\r\n        \"msi\",\r\n        \"appx\",\r\n        \"exe\",\r\n        \"inno\",\r\n        \"nullsoft\",\r\n        \"wix\",\r\n        \"burn\",\r\n        \"pwa\"\r\n      ],\r\n      \"description\": \"Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level\"\r\n    },\r\n    \"Scope\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"user\",\r\n        \"machine\"\r\n      ],\r\n      \"description\": \"Scope indicates if the installer is per user or per machine\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"InstallModes\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"interactive\",\r\n          \"silent\",\r\n          \"silentWithProgress\"\r\n        ]\r\n      },\r\n      \"maxItems\": 3,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of supported installer modes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"Silent\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Silent is the value that should be passed to the installer when user chooses a silent or quiet install\"\r\n        },\r\n        \"SilentWithProgress\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install\"\r\n        },\r\n        \"Interactive\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Interactive is the value that should be passed to the installer when user chooses an interactive install\"\r\n        },\r\n        \"InstallLocation\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"InstallLocation is the value passed to the installer for custom install location. <INSTALLPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Log\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Log is the value passed to the installer for custom log file path. <LOGPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Upgrade\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Upgrade is the value that should be passed to the installer when user chooses an upgrade\"\r\n        },\r\n        \"Custom\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 2048,\r\n          \"description\": \"Custom switches will be passed directly to the installer by winget\"\r\n        }\r\n      }\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"integer\",\r\n        \"format\": \"long\",        \r\n        \"not\": {\r\n          \"enum\": [ 0 ]\r\n        },\r\n        \"minimum\": -2147483648,\r\n        \"maximum\": 4294967295\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional non-zero installer success exit codes other than known default values by winget\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"install\",\r\n        \"uninstallPrevious\"\r\n      ],\r\n      \"description\": \"The upgrade method\"\r\n    },\r\n    \"Commands\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of commands or aliases to run the package\"\r\n    },\r\n    \"Protocols\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"pattern\": \"^[a-z][-a-z0-9\\\\.\\\\+]*$\",\r\n        \"maxLength\": 2048\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of protocols the package provides a handler for\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n        \"maxLength\": 64\r\n      },\r\n      \"maxItems\": 256,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of file extensions the package could support\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"properties\": {\r\n        \"WindowsFeatures\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows feature dependencies\"\r\n        },\r\n        \"WindowsLibraries\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows library dependencies\"\r\n        },\r\n        \"PackageDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"object\",\r\n            \"properties\": {\r\n              \"PackageIdentifier\": {\r\n                \"$ref\": \"#/definitions/PackageIdentifier\"\r\n              },\r\n              \"MinimumVersion\": {\r\n                \"$ref\": \"#/definitions/PackageVersion\"\r\n              }\r\n            },\r\n            \"required\": [ \"PackageIdentifier\" ]\r\n          },\r\n          \"maxItems\": 16,\r\n          \"description\": \"List of package dependencies from current source\"\r\n        },\r\n        \"ExternalDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of external package dependencies\"\r\n        }\r\n      }\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^[A-Za-z0-9][-\\\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$\",\r\n      \"maxLength\": 255,\r\n      \"description\": \"PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 255,\r\n      \"description\": \"ProductCode could be used for correlation of packages across sources\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer restricted capabilities\"\r\n    },\r\n    \"Installer\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"InstallerLocale\": {\r\n          \"$ref\": \"#/definitions/Locale\"\r\n        },\r\n        \"Platform\": {\r\n          \"$ref\": \"#/definitions/Platform\"\r\n        },\r\n        \"MinimumOSVersion\": {\r\n          \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n        },\r\n        \"Architecture\": {\r\n          \"type\": \"string\",\r\n          \"enum\": [\r\n            \"x86\",\r\n            \"x64\",\r\n            \"arm\",\r\n            \"arm64\",\r\n            \"neutral\"\r\n          ],\r\n          \"description\": \"The installer target architecture\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        },\r\n        \"Scope\": {\r\n          \"$ref\": \"#/definitions/Scope\"\r\n        },\r\n        \"InstallerUrl\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n          \"maxLength\": 2048,\r\n          \"description\": \"The installer Url\"\r\n        },\r\n        \"InstallerSha256\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"Sha256 is required. Sha256 of the installer\"\r\n        },\r\n        \"SignatureSha256\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable\"\r\n        },\r\n        \"InstallModes\": {\r\n          \"$ref\": \"#/definitions/InstallModes\"\r\n        },\r\n        \"InstallerSwitches\": {\r\n          \"$ref\": \"#/definitions/InstallerSwitches\"\r\n        },\r\n        \"InstallerSuccessCodes\": {\r\n          \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n        },\r\n        \"UpgradeBehavior\": {\r\n          \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n        },\r\n        \"Commands\": {\r\n          \"$ref\": \"#/definitions/Commands\"\r\n        },\r\n        \"Protocols\": {\r\n          \"$ref\": \"#/definitions/Protocols\"\r\n        },\r\n        \"FileExtensions\": {\r\n          \"$ref\": \"#/definitions/FileExtensions\"\r\n        },\r\n        \"Dependencies\": {\r\n          \"$ref\": \"#/definitions/Dependencies\"\r\n        },\r\n        \"PackageFamilyName\": {\r\n          \"$ref\": \"#/definitions/PackageFamilyName\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"Capabilities\": {\r\n          \"$ref\": \"#/definitions/Capabilities\"\r\n        },\r\n        \"RestrictedCapabilities\": {\r\n          \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n        }\r\n      },\r\n      \"required\": [\r\n        \"Architecture\",\r\n        \"InstallerUrl\",\r\n        \"InstallerSha256\"\r\n      ]\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"$ref\": \"#/definitions/PackageIdentifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"$ref\": \"#/definitions/PackageVersion\"\r\n    },\r\n    \"PackageLocale\": {\r\n      \"$ref\": \"#/definitions/Locale\"\r\n    },\r\n    \"Publisher\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The publisher name\"\r\n    },\r\n    \"PublisherUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher home page\"\r\n    },\r\n    \"PublisherSupportUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher support page\"\r\n    },\r\n    \"PrivacyUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher privacy page or the package privacy page\"\r\n    },\r\n    \"Author\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package author\"\r\n    },\r\n    \"PackageName\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package name\"\r\n    },\r\n    \"PackageUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package home page\"\r\n    },\r\n    \"License\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package license\"\r\n    },\r\n    \"LicenseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The license page\"\r\n    },\r\n    \"Copyright\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package copyright\"\r\n    },\r\n    \"CopyrightUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package copyright page\"\r\n    },\r\n    \"ShortDescription\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The short package description\"\r\n    },\r\n    \"Description\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The full package description\"\r\n    },\r\n    \"Moniker\": {\r\n      \"$ref\": \"#/definitions/Tag\",\r\n      \"description\": \"The most common package term\"\r\n    },\r\n    \"Tags\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Tag\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional package search terms\"\r\n    },\r\n    \"Channel\": {\r\n      \"$ref\": \"#/definitions/Channel\"\r\n    },\r\n    \"InstallerLocale\": {\r\n      \"$ref\": \"#/definitions/Locale\"\r\n    },\r\n    \"Platform\": {\r\n      \"$ref\": \"#/definitions/Platform\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"$ref\": \"#/definitions/InstallerType\"\r\n    },\r\n    \"Scope\": {\r\n      \"$ref\": \"#/definitions/Scope\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"$ref\": \"#/definitions/InstallModes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"$ref\": \"#/definitions/InstallerSwitches\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n    },\r\n    \"Commands\": {\r\n      \"$ref\": \"#/definitions/Commands\"\r\n    },\r\n    \"Protocols\": {\r\n      \"$ref\": \"#/definitions/Protocols\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"$ref\": \"#/definitions/FileExtensions\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"$ref\": \"#/definitions/Dependencies\"\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"$ref\": \"#/definitions/PackageFamilyName\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"$ref\": \"#/definitions/ProductCode\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"$ref\": \"#/definitions/Capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n    },\r\n    \"Installers\": {\r\n      \"type\": \"array\",\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Installer\"\r\n      },\r\n      \"minItems\": 1,\r\n      \"maxItems\": 1\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"singleton\",\r\n      \"const\": \"singleton\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.0.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"PackageLocale\",\r\n    \"Publisher\",\r\n    \"PackageName\",\r\n    \"License\",\r\n    \"ShortDescription\",\r\n    \"Installers\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}"
  },
  {
    "path": "schemas/JSON/manifests/v1.0.0/manifest.version.1.0.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.version.1.0.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a multi-file manifest representing an app version in the OWC. v1.0.0\",\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,3}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"DefaultLocale\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"en-US\",\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The default package meta-data locale\"\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"version\",\r\n      \"const\": \"version\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.0.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"DefaultLocale\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}\r\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.1.0/manifest.defaultLocale.1.1.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.defaultlocale.1.1.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a multiple-file manifest representing a default app metadata in the OWC. v1.1.0\",\r\n  \"definitions\": {\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Optional Url type\"\r\n    },\r\n    \"Tag\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 40,\r\n      \"description\": \"Package moniker or tag\"\r\n    },\r\n    \"Agreement\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"AgreementLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\r\n        },\r\n        \"Agreement\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 10000,\r\n          \"description\": \"The agreement text content.\"\r\n        },\r\n        \"AgreementUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The agreement URL.\"\r\n        }\r\n      }\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,3}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"PackageLocale\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"en-US\",\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The package meta-data locale\"\r\n    },\r\n    \"Publisher\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The publisher name\"\r\n    },\r\n    \"PublisherUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher home page\"\r\n    },\r\n    \"PublisherSupportUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher support page\"\r\n    },\r\n    \"PrivacyUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher privacy page or the package privacy page\"\r\n    },\r\n    \"Author\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package author\"\r\n    },\r\n    \"PackageName\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package name\"\r\n    },\r\n    \"PackageUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package home page\"\r\n    },\r\n    \"License\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package license\"\r\n    },\r\n    \"LicenseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The license page\"\r\n    },\r\n    \"Copyright\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package copyright\"\r\n    },\r\n    \"CopyrightUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package copyright page\"\r\n    },\r\n    \"ShortDescription\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The short package description\"\r\n    },\r\n    \"Description\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The full package description\"\r\n    },\r\n    \"Moniker\": {\r\n      \"$ref\": \"#/definitions/Tag\",\r\n      \"description\": \"The most common package term\"\r\n    },\r\n    \"Tags\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Tag\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional package search terms\"\r\n    },\r\n    \"Agreements\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Agreement\"\r\n      },\r\n      \"maxItems\": 128\r\n    },\r\n    \"ReleaseNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The package release notes\"\r\n    },\r\n    \"ReleaseNotesUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package release notes url\"\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"defaultLocale\",\r\n      \"const\": \"defaultLocale\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.1.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"PackageLocale\",\r\n    \"Publisher\",\r\n    \"PackageName\",\r\n    \"License\",\r\n    \"ShortDescription\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}"
  },
  {
    "path": "schemas/JSON/manifests/v1.1.0/manifest.installer.1.1.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.installer.1.1.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a single-file manifest representing an app installers in the OWC. v1.1.0\",\r\n  \"definitions\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,3}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"Locale\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The installer meta-data locale\"\r\n    },\r\n    \"Channel\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 16,\r\n      \"description\": \"The distribution channel\"\r\n    },\r\n    \"Platform\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"Platform\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"Windows.Desktop\",\r\n          \"Windows.Universal\"\r\n        ]\r\n      },\r\n      \"maxItems\": 2,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"The installer supported operating system\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$\",\r\n      \"description\": \"The installer minimum operating system version\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"msix\",\r\n        \"msi\",\r\n        \"appx\",\r\n        \"exe\",\r\n        \"inno\",\r\n        \"nullsoft\",\r\n        \"wix\",\r\n        \"burn\",\r\n        \"pwa\"\r\n      ],\r\n      \"description\": \"Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level\"\r\n    },\r\n    \"Scope\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"user\",\r\n        \"machine\"\r\n      ],\r\n      \"description\": \"Scope indicates if the installer is per user or per machine\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"InstallModes\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"interactive\",\r\n          \"silent\",\r\n          \"silentWithProgress\"\r\n        ]\r\n      },\r\n      \"maxItems\": 3,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of supported installer modes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"Silent\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Silent is the value that should be passed to the installer when user chooses a silent or quiet install\"\r\n        },\r\n        \"SilentWithProgress\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install\"\r\n        },\r\n        \"Interactive\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Interactive is the value that should be passed to the installer when user chooses an interactive install\"\r\n        },\r\n        \"InstallLocation\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"InstallLocation is the value passed to the installer for custom install location. <INSTALLPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Log\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Log is the value passed to the installer for custom log file path. <LOGPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Upgrade\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Upgrade is the value that should be passed to the installer when user chooses an upgrade\"\r\n        },\r\n        \"Custom\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 2048,\r\n          \"description\": \"Custom switches will be passed directly to the installer by winget\"\r\n        }\r\n      }\r\n    },\r\n    \"InstallerReturnCode\": {\r\n      \"type\": \"integer\",\r\n      \"format\": \"long\",\r\n      \"not\": {\r\n        \"enum\": [ 0 ]\r\n      },\r\n      \"minimum\": -2147483648,\r\n      \"maximum\": 4294967295,\r\n      \"description\": \"An exit code that can be returned by the installer after execution\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/InstallerReturnCode\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional non-zero installer success exit codes other than known default values by winget\"\r\n    },\r\n    \"ExpectedReturnCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"object\",\r\n        \"title\": \"ExpectedReturnCode\",\r\n        \"properties\": {\r\n          \"InstallerReturnCode\": {\r\n            \"$ref\": \"#/definitions/InstallerReturnCode\"\r\n          },\r\n          \"ReturnResponse\": {\r\n            \"type\": \"string\",\r\n            \"enum\": [\r\n              \"packageInUse\",\r\n              \"installInProgress\",\r\n              \"fileInUse\",\r\n              \"missingDependency\",\r\n              \"diskFull\",\r\n              \"insufficientMemory\",\r\n              \"noNetwork\",\r\n              \"contactSupport\",\r\n              \"rebootRequiredToFinish\",\r\n              \"rebootRequiredForInstall\",\r\n              \"rebootInitiated\",\r\n              \"cancelledByUser\",\r\n              \"alreadyInstalled\",\r\n              \"downgrade\",\r\n              \"blockedByPolicy\"\r\n            ]\r\n          }\r\n        },\r\n        \"required\": [ \"InstallerReturnCode\", \"ReturnResponse\" ]\r\n      },\r\n      \"maxItems\": 128,\r\n      \"description\": \"Installer exit codes for common errors\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"install\",\r\n        \"uninstallPrevious\"\r\n      ],\r\n      \"description\": \"The upgrade method\"\r\n    },\r\n    \"Commands\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of commands or aliases to run the package\"\r\n    },\r\n    \"Protocols\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"pattern\": \"^[a-z][-a-z0-9\\\\.\\\\+]*$\",\r\n        \"maxLength\": 2048\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of protocols the package provides a handler for\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n        \"maxLength\": 64\r\n      },\r\n      \"maxItems\": 256,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of file extensions the package could support\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"properties\": {\r\n        \"WindowsFeatures\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows feature dependencies\"\r\n        },\r\n        \"WindowsLibraries\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows library dependencies\"\r\n        },\r\n        \"PackageDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"object\",\r\n            \"properties\": {\r\n              \"PackageIdentifier\": {\r\n                \"$ref\": \"#/definitions/PackageIdentifier\"\r\n              },\r\n              \"MinimumVersion\": {\r\n                \"$ref\": \"#/definitions/PackageVersion\"\r\n              }\r\n            },\r\n            \"required\": [ \"PackageIdentifier\" ]\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of package dependencies from current source\"\r\n        },\r\n        \"ExternalDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of external package dependencies\"\r\n        }\r\n      }\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^[A-Za-z0-9][-\\\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$\",\r\n      \"maxLength\": 255,\r\n      \"description\": \"PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 255,\r\n      \"description\": \"ProductCode could be used for correlation of packages across sources\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer restricted capabilities\"\r\n    },\r\n    \"Market\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[A-Z]{2}$\",\r\n      \"description\": \"The installer target market\"\r\n    },\r\n    \"MarketArray\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"maxItems\": 256,\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Market\"\r\n      },\r\n      \"description\": \"Array of markets\"\r\n    },\r\n    \"Markets\": {\r\n      \"description\": \"The installer markets\",\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"oneOf\": [\r\n        {\r\n          \"properties\": {\r\n            \"AllowedMarkets\": {\r\n              \"$ref\": \"#/definitions/MarketArray\"\r\n            }\r\n          },\r\n          \"required\": [ \"AllowedMarkets\" ]\r\n        },\r\n        {\r\n          \"properties\": {\r\n            \"ExcludedMarkets\": {\r\n              \"$ref\": \"#/definitions/MarketArray\"\r\n            }\r\n          },\r\n          \"required\": [ \"ExcludedMarkets\" ]\r\n        }\r\n      ]\r\n    },\r\n    \"InstallerAbortsTerminal\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer will abort terminal. Default is false\"\r\n    },\r\n    \"ReleaseDate\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"format\": \"date\",\r\n      \"description\": \"The installer release date\"\r\n    },\r\n    \"InstallLocationRequired\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer requires an install location provided\"\r\n    },\r\n    \"RequireExplicitUpgrade\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer should be pinned by default from upgrade\"\r\n    },\r\n    \"UnsupportedOSArchitectures\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"title\": \"UnsupportedOSArchitecture\",\r\n        \"enum\": [\r\n          \"x86\",\r\n          \"x64\",\r\n          \"arm\",\r\n          \"arm64\"\r\n        ]\r\n      },\r\n      \"description\": \"List of OS architectures the installer does not support\"\r\n    },\r\n    \"AppsAndFeaturesEntry\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DisplayName\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 256,\r\n          \"description\": \"The DisplayName registry value\"\r\n        },\r\n        \"Publisher\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 256,\r\n          \"description\": \"The Publisher registry value\"\r\n        },\r\n        \"DisplayVersion\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 128,\r\n          \"description\": \"The DisplayVersion registry value\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"UpgradeCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        }\r\n      },\r\n      \"description\": \"Various key values under installer's ARP entry\"\r\n    },\r\n    \"AppsAndFeaturesEntries\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"maxItems\": 128,\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/AppsAndFeaturesEntry\"\r\n      },\r\n      \"description\": \"List of ARP entries.\"\r\n    },\r\n    \"ElevationRequirement\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"elevationRequired\",\r\n        \"elevationProhibited\",\r\n        \"elevatesSelf\"\r\n      ],\r\n      \"description\": \"The installer's elevation requirement\"\r\n    },\r\n    \"Installer\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"InstallerLocale\": {\r\n          \"$ref\": \"#/definitions/Locale\"\r\n        },\r\n        \"Platform\": {\r\n          \"$ref\": \"#/definitions/Platform\"\r\n        },\r\n        \"MinimumOSVersion\": {\r\n          \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n        },\r\n        \"Architecture\": {\r\n          \"type\": \"string\",\r\n          \"enum\": [\r\n            \"x86\",\r\n            \"x64\",\r\n            \"arm\",\r\n            \"arm64\",\r\n            \"neutral\"\r\n          ],\r\n          \"description\": \"The installer target architecture\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        },\r\n        \"Scope\": {\r\n          \"$ref\": \"#/definitions/Scope\"\r\n        },\r\n        \"InstallerUrl\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n          \"maxLength\": 2048,\r\n          \"description\": \"The installer Url\"\r\n        },\r\n        \"InstallerSha256\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"Sha256 is required. Sha256 of the installer\"\r\n        },\r\n        \"SignatureSha256\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable\"\r\n        },\r\n        \"InstallModes\": {\r\n          \"$ref\": \"#/definitions/InstallModes\"\r\n        },\r\n        \"InstallerSwitches\": {\r\n          \"$ref\": \"#/definitions/InstallerSwitches\"\r\n        },\r\n        \"InstallerSuccessCodes\": {\r\n          \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n        },\r\n        \"ExpectedReturnCodes\": {\r\n          \"$ref\": \"#/definitions/ExpectedReturnCodes\"\r\n        },\r\n        \"UpgradeBehavior\": {\r\n          \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n        },\r\n        \"Commands\": {\r\n          \"$ref\": \"#/definitions/Commands\"\r\n        },\r\n        \"Protocols\": {\r\n          \"$ref\": \"#/definitions/Protocols\"\r\n        },\r\n        \"FileExtensions\": {\r\n          \"$ref\": \"#/definitions/FileExtensions\"\r\n        },\r\n        \"Dependencies\": {\r\n          \"$ref\": \"#/definitions/Dependencies\"\r\n        },\r\n        \"PackageFamilyName\": {\r\n          \"$ref\": \"#/definitions/PackageFamilyName\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"Capabilities\": {\r\n          \"$ref\": \"#/definitions/Capabilities\"\r\n        },\r\n        \"RestrictedCapabilities\": {\r\n          \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n        },\r\n        \"Markets\": {\r\n          \"$ref\": \"#/definitions/Markets\"\r\n        },\r\n        \"InstallerAbortsTerminal\": {\r\n          \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\r\n        },\r\n        \"ReleaseDate\": {\r\n          \"$ref\": \"#/definitions/ReleaseDate\"\r\n        },\r\n        \"InstallLocationRequired\": {\r\n          \"$ref\": \"#/definitions/InstallLocationRequired\"\r\n        },\r\n        \"RequireExplicitUpgrade\": {\r\n          \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\r\n        },\r\n        \"UnsupportedOSArchitectures\": {\r\n          \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\r\n        },\r\n        \"AppsAndFeaturesEntries\": {\r\n          \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\r\n        },\r\n        \"ElevationRequirement\": {\r\n          \"$ref\": \"#/definitions/ElevationRequirement\"\r\n        }\r\n      },\r\n      \"required\": [\r\n        \"Architecture\",\r\n        \"InstallerUrl\",\r\n        \"InstallerSha256\"\r\n      ]\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"$ref\": \"#/definitions/PackageIdentifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"$ref\": \"#/definitions/PackageVersion\"\r\n    },\r\n    \"Channel\": {\r\n      \"$ref\": \"#/definitions/Channel\"\r\n    },\r\n    \"InstallerLocale\": {\r\n      \"$ref\": \"#/definitions/Locale\"\r\n    },\r\n    \"Platform\": {\r\n      \"$ref\": \"#/definitions/Platform\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"$ref\": \"#/definitions/InstallerType\"\r\n    },\r\n    \"Scope\": {\r\n      \"$ref\": \"#/definitions/Scope\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"$ref\": \"#/definitions/InstallModes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"$ref\": \"#/definitions/InstallerSwitches\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n    },\r\n    \"ExpectedReturnCodes\": {\r\n      \"$ref\": \"#/definitions/ExpectedReturnCodes\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n    },\r\n    \"Commands\": {\r\n      \"$ref\": \"#/definitions/Commands\"\r\n    },\r\n    \"Protocols\": {\r\n      \"$ref\": \"#/definitions/Protocols\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"$ref\": \"#/definitions/FileExtensions\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"$ref\": \"#/definitions/Dependencies\"\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"$ref\": \"#/definitions/PackageFamilyName\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"$ref\": \"#/definitions/ProductCode\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"$ref\": \"#/definitions/Capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n    },\r\n    \"Markets\": {\r\n      \"$ref\": \"#/definitions/Markets\"\r\n    },\r\n    \"InstallerAbortsTerminal\": {\r\n      \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\r\n    },\r\n    \"ReleaseDate\": {\r\n      \"$ref\": \"#/definitions/ReleaseDate\"\r\n    },\r\n    \"InstallLocationRequired\": {\r\n      \"$ref\": \"#/definitions/InstallLocationRequired\"\r\n    },\r\n    \"RequireExplicitUpgrade\": {\r\n      \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\r\n    },\r\n    \"UnsupportedOSArchitectures\": {\r\n      \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\r\n    },\r\n    \"AppsAndFeaturesEntries\": {\r\n      \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\r\n    },\r\n    \"ElevationRequirement\": {\r\n      \"$ref\": \"#/definitions/ElevationRequirement\"\r\n    },\r\n    \"Installers\": {\r\n      \"type\": \"array\",\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Installer\"\r\n      },\r\n      \"minItems\": 1,\r\n      \"maxItems\": 1024\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"installer\",\r\n      \"const\": \"installer\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.1.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"Installers\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}\r\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.1.0/manifest.locale.1.1.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.locale.1.1.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a multiple-file manifest representing app metadata in other locale in the OWC. v1.1.0\",\r\n  \"definitions\": {\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Optional Url type\"\r\n    },\r\n    \"Tag\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 40,\r\n      \"description\": \"Package tag\"\r\n    },\r\n    \"Agreement\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"AgreementLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\r\n        },\r\n        \"Agreement\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 10000,\r\n          \"description\": \"The agreement text content.\"\r\n        },\r\n        \"AgreementUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The agreement URL.\"\r\n        }\r\n      }\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,3}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"PackageLocale\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The package meta-data locale\"\r\n    },\r\n    \"Publisher\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The publisher name\"\r\n    },\r\n    \"PublisherUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher home page\"\r\n    },\r\n    \"PublisherSupportUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher support page\"\r\n    },\r\n    \"PrivacyUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher privacy page or the package privacy page\"\r\n    },\r\n    \"Author\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package author\"\r\n    },\r\n    \"PackageName\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package name\"\r\n    },\r\n    \"PackageUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package home page\"\r\n    },\r\n    \"License\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package license\"\r\n    },\r\n    \"LicenseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The license page\"\r\n    },\r\n    \"Copyright\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package copyright\"\r\n    },\r\n    \"CopyrightUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package copyright page\"\r\n    },\r\n    \"ShortDescription\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The short package description\"\r\n    },\r\n    \"Description\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The full package description\"\r\n    },\r\n    \"Tags\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Tag\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional package search terms\"\r\n    },\r\n    \"Agreements\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Agreement\"\r\n      },\r\n      \"maxItems\": 128\r\n    },\r\n    \"ReleaseNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The package release notes\"\r\n    },\r\n    \"ReleaseNotesUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package release notes url\"\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"locale\",\r\n      \"const\": \"locale\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.1.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"PackageLocale\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}"
  },
  {
    "path": "schemas/JSON/manifests/v1.1.0/manifest.singleton.1.1.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.singleton.1.1.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a single-file manifest representing an app in the OWC. v1.1.0\",\r\n  \"definitions\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,3}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"Locale\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The package meta-data locale\"\r\n    },\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Optional Url type\"\r\n    },\r\n    \"Tag\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 40,\r\n      \"description\": \"Package moniker or tag\"\r\n    },\r\n    \"Agreement\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"AgreementLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\r\n        },\r\n        \"Agreement\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 10000,\r\n          \"description\": \"The agreement text content.\"\r\n        },\r\n        \"AgreementUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The agreement URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Channel\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 16,\r\n      \"description\": \"The distribution channel\"\r\n    },\r\n    \"Platform\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"Platform\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"Windows.Desktop\",\r\n          \"Windows.Universal\"\r\n        ]\r\n      },\r\n      \"maxItems\": 2,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"The installer supported operating system\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$\",\r\n      \"description\": \"The installer minimum operating system version\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"msix\",\r\n        \"msi\",\r\n        \"appx\",\r\n        \"exe\",\r\n        \"inno\",\r\n        \"nullsoft\",\r\n        \"wix\",\r\n        \"burn\",\r\n        \"pwa\"\r\n      ],\r\n      \"description\": \"Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level\"\r\n    },\r\n    \"Scope\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"user\",\r\n        \"machine\"\r\n      ],\r\n      \"description\": \"Scope indicates if the installer is per user or per machine\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"InstallModes\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"interactive\",\r\n          \"silent\",\r\n          \"silentWithProgress\"\r\n        ]\r\n      },\r\n      \"maxItems\": 3,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of supported installer modes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"Silent\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Silent is the value that should be passed to the installer when user chooses a silent or quiet install\"\r\n        },\r\n        \"SilentWithProgress\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install\"\r\n        },\r\n        \"Interactive\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Interactive is the value that should be passed to the installer when user chooses an interactive install\"\r\n        },\r\n        \"InstallLocation\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"InstallLocation is the value passed to the installer for custom install location. <INSTALLPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Log\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Log is the value passed to the installer for custom log file path. <LOGPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Upgrade\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Upgrade is the value that should be passed to the installer when user chooses an upgrade\"\r\n        },\r\n        \"Custom\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 2048,\r\n          \"description\": \"Custom switches will be passed directly to the installer by winget\"\r\n        }\r\n      }\r\n    },\r\n    \"InstallerReturnCode\": {\r\n      \"type\": \"integer\",\r\n      \"format\": \"long\",\r\n      \"not\": {\r\n        \"enum\": [ 0 ]\r\n      },\r\n      \"minimum\": -2147483648,\r\n      \"maximum\": 4294967295,\r\n      \"description\": \"An exit code that can be returned by the installer after execution\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/InstallerReturnCode\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional non-zero installer success exit codes other than known default values by winget\"\r\n    },\r\n    \"ExpectedReturnCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"object\",\r\n        \"title\": \"ExpectedReturnCode\",\r\n        \"properties\": {\r\n          \"InstallerReturnCode\": {\r\n            \"$ref\": \"#/definitions/InstallerReturnCode\"\r\n          },\r\n          \"ReturnResponse\": {\r\n            \"type\": \"string\",\r\n            \"enum\": [\r\n              \"packageInUse\",\r\n              \"installInProgress\",\r\n              \"fileInUse\",\r\n              \"missingDependency\",\r\n              \"diskFull\",\r\n              \"insufficientMemory\",\r\n              \"noNetwork\",\r\n              \"contactSupport\",\r\n              \"rebootRequiredToFinish\",\r\n              \"rebootRequiredForInstall\",\r\n              \"rebootInitiated\",\r\n              \"cancelledByUser\",\r\n              \"alreadyInstalled\",\r\n              \"downgrade\",\r\n              \"blockedByPolicy\"\r\n            ]\r\n          }\r\n        },\r\n        \"required\": [ \"InstallerReturnCode\", \"ReturnResponse\" ]\r\n      },\r\n      \"maxItems\": 128,\r\n      \"description\": \"Installer exit codes for common errors\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"install\",\r\n        \"uninstallPrevious\"\r\n      ],\r\n      \"description\": \"The upgrade method\"\r\n    },\r\n    \"Commands\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of commands or aliases to run the package\"\r\n    },\r\n    \"Protocols\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"pattern\": \"^[a-z][-a-z0-9\\\\.\\\\+]*$\",\r\n        \"maxLength\": 2048\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of protocols the package provides a handler for\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n        \"maxLength\": 64\r\n      },\r\n      \"maxItems\": 256,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of file extensions the package could support\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"properties\": {\r\n        \"WindowsFeatures\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows feature dependencies\"\r\n        },\r\n        \"WindowsLibraries\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows library dependencies\"\r\n        },\r\n        \"PackageDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"object\",\r\n            \"properties\": {\r\n              \"PackageIdentifier\": {\r\n                \"$ref\": \"#/definitions/PackageIdentifier\"\r\n              },\r\n              \"MinimumVersion\": {\r\n                \"$ref\": \"#/definitions/PackageVersion\"\r\n              }\r\n            },\r\n            \"required\": [ \"PackageIdentifier\" ]\r\n          },\r\n          \"maxItems\": 16,\r\n          \"description\": \"List of package dependencies from current source\"\r\n        },\r\n        \"ExternalDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of external package dependencies\"\r\n        }\r\n      }\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^[A-Za-z0-9][-\\\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$\",\r\n      \"maxLength\": 255,\r\n      \"description\": \"PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 255,\r\n      \"description\": \"ProductCode could be used for correlation of packages across sources\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer restricted capabilities\"\r\n    },\r\n    \"Market\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[A-Z]{2}$\",\r\n      \"description\": \"The installer target market\"\r\n    },\r\n    \"MarketArray\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"maxItems\": 256,\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Market\"\r\n      },\r\n      \"description\": \"Array of markets\"\r\n    },\r\n    \"Markets\": {\r\n      \"description\": \"The installer markets\",\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"oneOf\": [\r\n        {\r\n          \"properties\": {\r\n            \"AllowedMarkets\": {\r\n              \"$ref\": \"#/definitions/MarketArray\"\r\n            }\r\n          },\r\n          \"required\": [ \"AllowedMarkets\" ]\r\n        },\r\n        {\r\n          \"properties\": {\r\n            \"ExcludedMarkets\": {\r\n              \"$ref\": \"#/definitions/MarketArray\"\r\n            }\r\n          },\r\n          \"required\": [ \"ExcludedMarkets\" ]\r\n        }\r\n      ]\r\n    },\r\n    \"InstallerAbortsTerminal\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer will abort terminal. Default is false\"\r\n    },\r\n    \"ReleaseDate\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"format\": \"date\",\r\n      \"description\": \"The installer release date\"\r\n    },\r\n    \"InstallLocationRequired\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer requires an install location provided\"\r\n    },\r\n    \"RequireExplicitUpgrade\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer should be pinned by default from upgrade\"\r\n    },\r\n    \"UnsupportedOSArchitectures\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"title\": \"UnsupportedOSArchitecture\",\r\n        \"enum\": [\r\n          \"x86\",\r\n          \"x64\",\r\n          \"arm\",\r\n          \"arm64\"\r\n        ]\r\n      },\r\n      \"description\": \"List of OS architectures the installer does not support\"\r\n    },\r\n    \"AppsAndFeaturesEntry\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DisplayName\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 256,\r\n          \"description\": \"The DisplayName registry value\"\r\n        },\r\n        \"Publisher\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 256,\r\n          \"description\": \"The Publisher registry value\"\r\n        },\r\n        \"DisplayVersion\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 128,\r\n          \"description\": \"The DisplayVersion registry value\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"UpgradeCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        }\r\n      },\r\n      \"description\": \"Various key values under installer's ARP entry\"\r\n    },\r\n    \"AppsAndFeaturesEntries\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"maxItems\": 128,\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/AppsAndFeaturesEntry\"\r\n      },\r\n      \"description\": \"List of ARP entries.\"\r\n    },\r\n    \"ElevationRequirement\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"elevationRequired\",\r\n        \"elevationProhibited\",\r\n        \"elevatesSelf\"\r\n      ],\r\n      \"description\": \"The installer's elevation requirement\"\r\n    },\r\n    \"Installer\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"InstallerLocale\": {\r\n          \"$ref\": \"#/definitions/Locale\"\r\n        },\r\n        \"Platform\": {\r\n          \"$ref\": \"#/definitions/Platform\"\r\n        },\r\n        \"MinimumOSVersion\": {\r\n          \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n        },\r\n        \"Architecture\": {\r\n          \"type\": \"string\",\r\n          \"enum\": [\r\n            \"x86\",\r\n            \"x64\",\r\n            \"arm\",\r\n            \"arm64\",\r\n            \"neutral\"\r\n          ],\r\n          \"description\": \"The installer target architecture\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        },\r\n        \"Scope\": {\r\n          \"$ref\": \"#/definitions/Scope\"\r\n        },\r\n        \"InstallerUrl\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n          \"maxLength\": 2048,\r\n          \"description\": \"The installer Url\"\r\n        },\r\n        \"InstallerSha256\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"Sha256 is required. Sha256 of the installer\"\r\n        },\r\n        \"SignatureSha256\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable\"\r\n        },\r\n        \"InstallModes\": {\r\n          \"$ref\": \"#/definitions/InstallModes\"\r\n        },\r\n        \"InstallerSwitches\": {\r\n          \"$ref\": \"#/definitions/InstallerSwitches\"\r\n        },\r\n        \"InstallerSuccessCodes\": {\r\n          \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n        },\r\n        \"ExpectedReturnCodes\": {\r\n          \"$ref\": \"#/definitions/ExpectedReturnCodes\"\r\n        },\r\n        \"UpgradeBehavior\": {\r\n          \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n        },\r\n        \"Commands\": {\r\n          \"$ref\": \"#/definitions/Commands\"\r\n        },\r\n        \"Protocols\": {\r\n          \"$ref\": \"#/definitions/Protocols\"\r\n        },\r\n        \"FileExtensions\": {\r\n          \"$ref\": \"#/definitions/FileExtensions\"\r\n        },\r\n        \"Dependencies\": {\r\n          \"$ref\": \"#/definitions/Dependencies\"\r\n        },\r\n        \"PackageFamilyName\": {\r\n          \"$ref\": \"#/definitions/PackageFamilyName\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"Capabilities\": {\r\n          \"$ref\": \"#/definitions/Capabilities\"\r\n        },\r\n        \"RestrictedCapabilities\": {\r\n          \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n        },\r\n        \"Markets\": {\r\n          \"$ref\": \"#/definitions/Markets\"\r\n        },\r\n        \"InstallerAbortsTerminal\": {\r\n          \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\r\n        },\r\n        \"ReleaseDate\": {\r\n          \"$ref\": \"#/definitions/ReleaseDate\"\r\n        },\r\n        \"InstallLocationRequired\": {\r\n          \"$ref\": \"#/definitions/InstallLocationRequired\"\r\n        },\r\n        \"RequireExplicitUpgrade\": {\r\n          \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\r\n        },\r\n        \"UnsupportedOSArchitectures\": {\r\n          \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\r\n        },\r\n        \"AppsAndFeaturesEntries\": {\r\n          \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\r\n        },\r\n        \"ElevationRequirement\": {\r\n          \"$ref\": \"#/definitions/ElevationRequirement\"\r\n        }\r\n      },\r\n      \"required\": [\r\n        \"Architecture\",\r\n        \"InstallerUrl\",\r\n        \"InstallerSha256\"\r\n      ]\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"$ref\": \"#/definitions/PackageIdentifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"$ref\": \"#/definitions/PackageVersion\"\r\n    },\r\n    \"PackageLocale\": {\r\n      \"$ref\": \"#/definitions/Locale\"\r\n    },\r\n    \"Publisher\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The publisher name\"\r\n    },\r\n    \"PublisherUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher home page\"\r\n    },\r\n    \"PublisherSupportUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher support page\"\r\n    },\r\n    \"PrivacyUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher privacy page or the package privacy page\"\r\n    },\r\n    \"Author\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package author\"\r\n    },\r\n    \"PackageName\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package name\"\r\n    },\r\n    \"PackageUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package home page\"\r\n    },\r\n    \"License\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package license\"\r\n    },\r\n    \"LicenseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The license page\"\r\n    },\r\n    \"Copyright\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package copyright\"\r\n    },\r\n    \"CopyrightUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package copyright page\"\r\n    },\r\n    \"ShortDescription\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The short package description\"\r\n    },\r\n    \"Description\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The full package description\"\r\n    },\r\n    \"Moniker\": {\r\n      \"$ref\": \"#/definitions/Tag\",\r\n      \"description\": \"The most common package term\"\r\n    },\r\n    \"Tags\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Tag\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional package search terms\"\r\n    },\r\n    \"Agreements\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Agreement\"\r\n      },\r\n      \"maxItems\": 128\r\n    },\r\n    \"ReleaseNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The package release notes\"\r\n    },\r\n    \"ReleaseNotesUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package release notes url\"\r\n    },\r\n    \"Channel\": {\r\n      \"$ref\": \"#/definitions/Channel\"\r\n    },\r\n    \"InstallerLocale\": {\r\n      \"$ref\": \"#/definitions/Locale\"\r\n    },\r\n    \"Platform\": {\r\n      \"$ref\": \"#/definitions/Platform\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"$ref\": \"#/definitions/InstallerType\"\r\n    },\r\n    \"Scope\": {\r\n      \"$ref\": \"#/definitions/Scope\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"$ref\": \"#/definitions/InstallModes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"$ref\": \"#/definitions/InstallerSwitches\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n    },\r\n    \"ExpectedReturnCodes\": {\r\n      \"$ref\": \"#/definitions/ExpectedReturnCodes\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n    },\r\n    \"Commands\": {\r\n      \"$ref\": \"#/definitions/Commands\"\r\n    },\r\n    \"Protocols\": {\r\n      \"$ref\": \"#/definitions/Protocols\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"$ref\": \"#/definitions/FileExtensions\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"$ref\": \"#/definitions/Dependencies\"\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"$ref\": \"#/definitions/PackageFamilyName\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"$ref\": \"#/definitions/ProductCode\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"$ref\": \"#/definitions/Capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n    },\r\n    \"Markets\": {\r\n      \"$ref\": \"#/definitions/Markets\"\r\n    },\r\n    \"InstallerAbortsTerminal\": {\r\n      \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\r\n    },\r\n    \"ReleaseDate\": {\r\n      \"$ref\": \"#/definitions/ReleaseDate\"\r\n    },\r\n    \"InstallLocationRequired\": {\r\n      \"$ref\": \"#/definitions/InstallLocationRequired\"\r\n    },\r\n    \"RequireExplicitUpgrade\": {\r\n      \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\r\n    },\r\n    \"UnsupportedOSArchitectures\": {\r\n      \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\r\n    },\r\n    \"AppsAndFeaturesEntries\": {\r\n      \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\r\n    },\r\n    \"ElevationRequirement\": {\r\n      \"$ref\": \"#/definitions/ElevationRequirement\"\r\n    },\r\n    \"Installers\": {\r\n      \"type\": \"array\",\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Installer\"\r\n      },\r\n      \"minItems\": 1,\r\n      \"maxItems\": 1\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"singleton\",\r\n      \"const\": \"singleton\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.1.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"PackageLocale\",\r\n    \"Publisher\",\r\n    \"PackageName\",\r\n    \"License\",\r\n    \"ShortDescription\",\r\n    \"Installers\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}\r\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.1.0/manifest.version.1.1.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.version.1.1.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a multi-file manifest representing an app version in the OWC. v1.1.0\",\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,3}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"DefaultLocale\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"en-US\",\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The default package meta-data locale\"\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"version\",\r\n      \"const\": \"version\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.1.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"DefaultLocale\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}"
  },
  {
    "path": "schemas/JSON/manifests/v1.10.0/manifest.defaultLocale.1.10.0.json",
    "content": "{\n  \"$id\": \"https://aka.ms/winget-manifest.defaultlocale.1.10.0.schema.json\",\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"description\": \"A representation of a multiple-file manifest representing a default app metadata in the OWC. v1.10.0\",\n  \"definitions\": {\n    \"Url\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n      \"maxLength\": 2048,\n      \"description\": \"Optional Url type\"\n    },\n    \"Tag\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 40,\n      \"description\": \"Package moniker or tag\"\n    },\n    \"Agreement\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"AgreementLabel\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 100,\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\n        },\n        \"Agreement\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 10000,\n          \"description\": \"The agreement text content.\"\n        },\n        \"AgreementUrl\": {\n          \"$ref\": \"#/definitions/Url\",\n          \"description\": \"The agreement URL.\"\n        }\n      }\n    },\n    \"Documentation\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"DocumentLabel\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 100,\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\n        },\n        \"DocumentUrl\": {\n          \"$ref\": \"#/definitions/Url\",\n          \"description\": \"The documentation URL.\"\n        }\n      }\n    },\n    \"Icon\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"IconUrl\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n          \"maxLength\": 2048,\n          \"description\": \"The url of the hosted icon file\"\n        },\n        \"IconFileType\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"png\",\n            \"jpeg\",\n            \"ico\"\n          ],\n          \"description\": \"The icon file type\"\n        },\n        \"IconResolution\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"enum\": [\n            \"custom\",\n            \"16x16\",\n            \"20x20\",\n            \"24x24\",\n            \"30x30\",\n            \"32x32\",\n            \"36x36\",\n            \"40x40\",\n            \"48x48\",\n            \"60x60\",\n            \"64x64\",\n            \"72x72\",\n            \"80x80\",\n            \"96x96\",\n            \"256x256\"\n          ],\n          \"description\": \"Optional icon resolution\"\n        },\n        \"IconTheme\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"enum\": [\n            \"default\",\n            \"light\",\n            \"dark\",\n            \"highContrast\"\n          ],\n          \"description\": \"Optional icon theme\"\n        },\n        \"IconSha256\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"Optional Sha256 of the icon file\"\n        }\n      },\n      \"required\": [\n        \"IconUrl\",\n        \"IconFileType\"\n      ]\n    }\n  },\n  \"type\": \"object\",\n  \"properties\": {\n    \"PackageIdentifier\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\n      \"maxLength\": 128,\n      \"description\": \"The package unique identifier\"\n    },\n    \"PackageVersion\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n      \"maxLength\": 128,\n      \"description\": \"The package version\"\n    },\n    \"PackageLocale\": {\n      \"type\": \"string\",\n      \"default\": \"en-US\",\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\n      \"maxLength\": 20,\n      \"description\": \"The package meta-data locale\"\n    },\n    \"Publisher\": {\n      \"type\": \"string\",\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The publisher name\"\n    },\n    \"PublisherUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher home page\"\n    },\n    \"PublisherSupportUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher support page\"\n    },\n    \"PrivacyUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher privacy page or the package privacy page\"\n    },\n    \"Author\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The package author\"\n    },\n    \"PackageName\": {\n      \"type\": \"string\",\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The package name\"\n    },\n    \"PackageUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package home page\"\n    },\n    \"License\": {\n      \"type\": \"string\",\n      \"minLength\": 3,\n      \"maxLength\": 512,\n      \"description\": \"The package license\"\n    },\n    \"LicenseUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The license page\"\n    },\n    \"Copyright\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 512,\n      \"description\": \"The package copyright\"\n    },\n    \"CopyrightUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package copyright page\"\n    },\n    \"ShortDescription\": {\n      \"type\": \"string\",\n      \"minLength\": 3,\n      \"maxLength\": 256,\n      \"description\": \"The short package description\"\n    },\n    \"Description\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 10000,\n      \"description\": \"The full package description\"\n    },\n    \"Moniker\": {\n      \"$ref\": \"#/definitions/Tag\",\n      \"description\": \"The most common package term\"\n    },\n    \"Tags\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Tag\"\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of additional package search terms\"\n    },\n    \"Agreements\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Agreement\"\n      },\n      \"maxItems\": 128\n    },\n    \"ReleaseNotes\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 10000,\n      \"description\": \"The package release notes\"\n    },\n    \"ReleaseNotesUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package release notes url\"\n    },\n    \"PurchaseUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\n    },\n    \"InstallationNotes\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 10000,\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"\n    },\n    \"Documentations\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Documentation\"\n      },\n      \"maxItems\": 256\n    },\n    \"Icons\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Icon\"\n      },\n      \"maxItems\": 1024\n    },\n    \"ManifestType\": {\n      \"type\": \"string\",\n      \"default\": \"defaultLocale\",\n      \"const\": \"defaultLocale\",\n      \"description\": \"The manifest type\"\n    },\n    \"ManifestVersion\": {\n      \"type\": \"string\",\n      \"default\": \"1.10.0\",\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\n      \"description\": \"The manifest syntax version\"\n    }\n  },\n  \"required\": [\n    \"PackageIdentifier\",\n    \"PackageVersion\",\n    \"PackageLocale\",\n    \"Publisher\",\n    \"PackageName\",\n    \"License\",\n    \"ShortDescription\",\n    \"ManifestType\",\n    \"ManifestVersion\"\n  ]\n}\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.10.0/manifest.installer.1.10.0.json",
    "content": "{\n  \"$id\": \"https://aka.ms/winget-manifest.installer.1.10.0.schema.json\",\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"description\": \"A representation of a single-file manifest representing an app installers in the OWC. v1.10.0\",\n  \"definitions\": {\n    \"PackageIdentifier\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\n      \"maxLength\": 128,\n      \"description\": \"The package unique identifier\"\n    },\n    \"PackageVersion\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n      \"maxLength\": 128,\n      \"description\": \"The package version\"\n    },\n    \"Locale\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\n      \"maxLength\": 20,\n      \"description\": \"The installer meta-data locale\"\n    },\n    \"Channel\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 16,\n      \"description\": \"The distribution channel\"\n    },\n    \"Platform\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"title\": \"Platform\",\n        \"type\": \"string\",\n        \"enum\": [\n          \"Windows.Desktop\",\n          \"Windows.Universal\"\n        ]\n      },\n      \"maxItems\": 2,\n      \"uniqueItems\": true,\n      \"description\": \"The installer supported operating system\"\n    },\n    \"MinimumOSVersion\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$\",\n      \"description\": \"The installer minimum operating system version\"\n    },\n    \"Url\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n      \"maxLength\": 2048,\n      \"description\": \"Url type\"\n    },\n    \"InstallerType\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"msix\",\n        \"msi\",\n        \"appx\",\n        \"exe\",\n        \"zip\",\n        \"inno\",\n        \"nullsoft\",\n        \"wix\",\n        \"burn\",\n        \"pwa\",\n        \"portable\"\n      ],\n      \"description\": \"Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level\"\n    },\n    \"NestedInstallerType\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"msix\",\n        \"msi\",\n        \"appx\",\n        \"exe\",\n        \"inno\",\n        \"nullsoft\",\n        \"wix\",\n        \"burn\",\n        \"portable\"\n      ],\n      \"description\": \"Enumeration of supported nested installer types contained inside an archive file\"\n    },\n    \"NestedInstallerFiles\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"object\",\n        \"title\": \"NestedInstallerFile\",\n        \"properties\": {\n          \"RelativeFilePath\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 512,\n            \"description\": \"The relative path to the nested installer file\"\n          },\n          \"PortableCommandAlias\": {\n            \"type\": [ \"string\", \"null\" ],\n            \"minLength\": 1,\n            \"maxLength\": 40,\n            \"description\": \"The command alias to be used for calling the package. Only applies to the nested portable package\"\n          }\n        },\n        \"required\": [ \"RelativeFilePath\" ],\n        \"description\": \"A nested installer file contained inside an archive\"\n      },\n      \"maxItems\": 1024,\n      \"description\": \"List of nested installer files contained inside an archive\"\n    },\n    \"Architecture\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"x86\",\n        \"x64\",\n        \"arm\",\n        \"arm64\",\n        \"neutral\"\n      ],\n      \"description\": \"The installer target architecture\"\n    },\n    \"Scope\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"user\",\n        \"machine\"\n      ],\n      \"description\": \"Scope indicates if the installer is per user or per machine\"\n    },\n    \"InstallModes\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"title\": \"InstallModes\",\n        \"type\": \"string\",\n        \"enum\": [\n          \"interactive\",\n          \"silent\",\n          \"silentWithProgress\"\n        ]\n      },\n      \"maxItems\": 3,\n      \"uniqueItems\": true,\n      \"description\": \"List of supported installer modes\"\n    },\n    \"InstallerSwitches\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"Silent\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Silent is the value that should be passed to the installer when user chooses a silent or quiet install\"\n        },\n        \"SilentWithProgress\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install\"\n        },\n        \"Interactive\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Interactive is the value that should be passed to the installer when user chooses an interactive install\"\n        },\n        \"InstallLocation\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"InstallLocation is the value passed to the installer for custom install location. <INSTALLPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\n        },\n        \"Log\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Log is the value passed to the installer for custom log file path. <LOGPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\n        },\n        \"Upgrade\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Upgrade is the value that should be passed to the installer when user chooses an upgrade\"\n        },\n        \"Custom\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 2048,\n          \"description\": \"Custom switches will be passed directly to the installer by winget\"\n        },\n        \"Repair\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"The 'Repair' value must be passed to the installer, ModifyPath ARP command, or uninstaller ARP command when the user opts for a repair.\"\n        }\n      }\n    },\n    \"InstallerReturnCode\": {\n      \"type\": \"integer\",\n      \"format\": \"long\",\n      \"not\": {\n        \"enum\": [ 0 ]\n      },\n      \"minimum\": -2147483648,\n      \"maximum\": 4294967295,\n      \"description\": \"An exit code that can be returned by the installer after execution\"\n    },\n    \"InstallerSuccessCodes\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/InstallerReturnCode\"\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of additional non-zero installer success exit codes other than known default values by winget\"\n    },\n    \"ExpectedReturnCodes\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"object\",\n        \"title\": \"ExpectedReturnCode\",\n        \"properties\": {\n          \"InstallerReturnCode\": {\n            \"$ref\": \"#/definitions/InstallerReturnCode\"\n          },\n          \"ReturnResponse\": {\n            \"type\": \"string\",\n            \"enum\": [\n              \"packageInUse\",\n              \"packageInUseByApplication\",\n              \"installInProgress\",\n              \"fileInUse\",\n              \"missingDependency\",\n              \"diskFull\",\n              \"insufficientMemory\",\n              \"invalidParameter\",\n              \"noNetwork\",\n              \"contactSupport\",\n              \"rebootRequiredToFinish\",\n              \"rebootRequiredForInstall\",\n              \"rebootInitiated\",\n              \"cancelledByUser\",\n              \"alreadyInstalled\",\n              \"downgrade\",\n              \"blockedByPolicy\",\n              \"systemNotSupported\",\n              \"custom\"\n            ]\n          },\n          \"ReturnResponseUrl\": {\n            \"$ref\": \"#/definitions/Url\",\n            \"description\": \"The return response url to provide additional guidance for expected return codes\"\n          }\n        },\n        \"required\": [ \"InstallerReturnCode\", \"ReturnResponse\" ]\n      },\n      \"maxItems\": 128,\n      \"description\": \"Installer exit codes for common errors\"\n    },\n    \"UpgradeBehavior\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"install\",\n        \"uninstallPrevious\",\n        \"deny\"\n      ],\n      \"description\": \"The upgrade method\"\n    },\n    \"Commands\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"maxLength\": 40\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of commands or aliases to run the package\"\n    },\n    \"Protocols\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"maxLength\": 2048\n      },\n      \"maxItems\": 64,\n      \"uniqueItems\": true,\n      \"description\": \"List of protocols the package provides a handler for\"\n    },\n    \"FileExtensions\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n        \"maxLength\": 64\n      },\n      \"maxItems\": 512,\n      \"uniqueItems\": true,\n      \"description\": \"List of file extensions the package could support\"\n    },\n    \"Dependencies\": {\n      \"type\": [ \"object\", \"null\" ],\n      \"properties\": {\n        \"WindowsFeatures\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 128\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of Windows feature dependencies\"\n        },\n        \"WindowsLibraries\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 128\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of Windows library dependencies\"\n        },\n        \"PackageDependencies\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"PackageIdentifier\": {\n                \"$ref\": \"#/definitions/PackageIdentifier\"\n              },\n              \"MinimumVersion\": {\n                \"$ref\": \"#/definitions/PackageVersion\"\n              }\n            },\n            \"required\": [ \"PackageIdentifier\" ]\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of package dependencies from current source\"\n        },\n        \"ExternalDependencies\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 128\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of external package dependencies\"\n        }\n      }\n    },\n    \"PackageFamilyName\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^[A-Za-z0-9][-\\\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$\",\n      \"maxLength\": 255,\n      \"description\": \"PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources\"\n    },\n    \"ProductCode\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 255,\n      \"description\": \"ProductCode could be used for correlation of packages across sources\"\n    },\n    \"Capabilities\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"maxLength\": 40\n      },\n      \"maxItems\": 1000,\n      \"uniqueItems\": true,\n      \"description\": \"List of appx or msix installer capabilities\"\n    },\n    \"RestrictedCapabilities\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"maxLength\": 40\n      },\n      \"maxItems\": 1000,\n      \"uniqueItems\": true,\n      \"description\": \"List of appx or msix installer restricted capabilities\"\n    },\n    \"Market\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[A-Z]{2}$\",\n      \"description\": \"The installer target market\"\n    },\n    \"MarketArray\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"maxItems\": 256,\n      \"items\": {\n        \"$ref\": \"#/definitions/Market\"\n      },\n      \"description\": \"Array of markets\"\n    },\n    \"Markets\": {\n      \"description\": \"The installer markets\",\n      \"type\": [ \"object\", \"null\" ],\n      \"oneOf\": [\n        {\n          \"properties\": {\n            \"AllowedMarkets\": {\n              \"$ref\": \"#/definitions/MarketArray\"\n            }\n          },\n          \"required\": [ \"AllowedMarkets\" ]\n        },\n        {\n          \"properties\": {\n            \"ExcludedMarkets\": {\n              \"$ref\": \"#/definitions/MarketArray\"\n            }\n          },\n          \"required\": [ \"ExcludedMarkets\" ]\n        }\n      ]\n    },\n    \"InstallerAbortsTerminal\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer will abort terminal. Default is false\"\n    },\n    \"ReleaseDate\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"format\": \"date\",\n      \"description\": \"The installer release date\"\n    },\n    \"InstallLocationRequired\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer requires an install location provided\"\n    },\n    \"RequireExplicitUpgrade\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer should be pinned by default from upgrade\"\n    },\n    \"DisplayInstallWarnings\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications.\"\n    },\n    \"UnsupportedOSArchitectures\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"items\": {\n        \"type\": \"string\",\n        \"title\": \"UnsupportedOSArchitecture\",\n        \"enum\": [\n          \"x86\",\n          \"x64\",\n          \"arm\",\n          \"arm64\"\n        ]\n      },\n      \"description\": \"List of OS architectures the installer does not support\"\n    },\n    \"UnsupportedArguments\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"items\": {\n        \"type\": \"string\",\n        \"title\": \"UnsupportedArgument\",\n        \"enum\": [\n          \"log\",\n          \"location\"\n        ]\n      },\n      \"description\": \"List of winget arguments the installer does not support\"\n    },\n    \"AppsAndFeaturesEntry\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"DisplayName\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 256,\n          \"description\": \"The DisplayName registry value\"\n        },\n        \"Publisher\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 256,\n          \"description\": \"The Publisher registry value\"\n        },\n        \"DisplayVersion\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 128,\n          \"description\": \"The DisplayVersion registry value\"\n        },\n        \"ProductCode\": {\n          \"$ref\": \"#/definitions/ProductCode\"\n        },\n        \"UpgradeCode\": {\n          \"$ref\": \"#/definitions/ProductCode\"\n        },\n        \"InstallerType\": {\n          \"$ref\": \"#/definitions/InstallerType\"\n        }\n      },\n      \"description\": \"Various key values under installer's ARP entry\"\n    },\n    \"AppsAndFeaturesEntries\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"maxItems\": 128,\n      \"items\": {\n        \"$ref\": \"#/definitions/AppsAndFeaturesEntry\"\n      },\n      \"description\": \"List of ARP entries.\"\n    },\n    \"ElevationRequirement\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"elevationRequired\",\n        \"elevationProhibited\",\n        \"elevatesSelf\"\n      ],\n      \"description\": \"The installer's elevation requirement\"\n    },\n    \"InstallationMetadata\": {\n      \"type\": \"object\",\n      \"title\": \"InstallationMetadata\",\n      \"properties\": {\n        \"DefaultInstallLocation\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 2048,\n          \"description\": \"Represents the default installed package location. Used for deeper installation detection.\"\n        },\n        \"Files\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"uniqueItems\": true,\n          \"maxItems\": 2048,\n          \"items\": {\n            \"type\": \"object\",\n            \"title\": \"InstalledFile\",\n            \"properties\": {\n              \"RelativeFilePath\": {\n                \"type\": \"string\",\n                \"minLength\": 1,\n                \"maxLength\": 2048,\n                \"description\": \"The relative path to the installed file.\"\n              },\n              \"FileSha256\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n                \"description\": \"Optional Sha256 of the installed file.\"\n              },\n              \"FileType\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"enum\": [\n                  \"launch\",\n                  \"uninstall\",\n                  \"other\"\n                ],\n                \"description\": \"The optional installed file type. If not specified, the file is treated as other.\"\n              },\n              \"InvocationParameter\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"minLength\": 1,\n                \"maxLength\": 2048,\n                \"description\": \"Optional parameter for invocable files.\"\n              },\n              \"DisplayName\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"minLength\": 1,\n                \"maxLength\": 256,\n                \"description\": \"Optional display name for invocable files.\"\n              }\n            },\n            \"required\": [ \"RelativeFilePath\" ],\n            \"description\": \"Represents an installed file.\"\n          },\n          \"description\": \"List of installed files.\"\n        }\n      },\n      \"description\": \"Details about the installation. Used for deeper installation detection.\"\n    },\n    \"DownloadCommandProhibited\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer is prohibited from being downloaded for offline installation.\"\n    },\n    \"RepairBehavior\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"modify\",\n        \"uninstaller\",\n        \"installer\"\n      ],\n      \"description\": \"The repair method\"\n    },\n    \"ArchiveBinariesDependOnPath\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the install location should be added directly to the PATH environment variable. Only applies to an archive containing portable packages.\"\n    },\n    \"Authentication\": {\n      \"type\": [ \"object\", \"null\" ],\n      \"properties\": {\n        \"AuthenticationType\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"none\",\n            \"microsoftEntraId\",\n            \"microsoftEntraIdForAzureBlobStorage\"\n          ],\n          \"description\": \"The authentication type\"\n        },\n        \"MicrosoftEntraIdAuthenticationInfo\": {\n          \"type\": [ \"object\", \"null\" ],\n          \"properties\": {\n            \"Resource\": {\n              \"type\": [ \"string\", \"null\" ],\n              \"minLength\": 1,\n              \"maxLength\": 512,\n              \"description\": \"The resource value for Microsoft Entra Id authentication.\"\n            },\n            \"Scope\": {\n              \"type\": [ \"string\", \"null\" ],\n              \"minLength\": 1,\n              \"maxLength\": 512,\n              \"description\": \"The scope value for Microsoft Entra Id authentication.\"\n            }\n          },\n          \"description\": \"The Microsoft Entra Id authentication info\"\n        }\n      },\n      \"required\": [\n        \"AuthenticationType\"\n      ],\n      \"description\": \"The authentication requirement for downloading the installer.\"\n    },\n    \"Installer\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"InstallerLocale\": {\n          \"$ref\": \"#/definitions/Locale\"\n        },\n        \"Platform\": {\n          \"$ref\": \"#/definitions/Platform\"\n        },\n        \"MinimumOSVersion\": {\n          \"$ref\": \"#/definitions/MinimumOSVersion\"\n        },\n        \"Architecture\": {\n          \"$ref\": \"#/definitions/Architecture\"\n        },\n        \"InstallerType\": {\n          \"$ref\": \"#/definitions/InstallerType\"\n        },\n        \"NestedInstallerType\": {\n          \"$ref\": \"#/definitions/NestedInstallerType\"\n        },\n        \"NestedInstallerFiles\": {\n          \"$ref\": \"#/definitions/NestedInstallerFiles\"\n        },\n        \"Scope\": {\n          \"$ref\": \"#/definitions/Scope\"\n        },\n        \"InstallerUrl\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n          \"maxLength\": 2048,\n          \"description\": \"The installer Url\"\n        },\n        \"InstallerSha256\": {\n          \"type\": \"string\",\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"Sha256 is required. Sha256 of the installer\"\n        },\n        \"SignatureSha256\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable\"\n        },\n        \"InstallModes\": {\n          \"$ref\": \"#/definitions/InstallModes\"\n        },\n        \"InstallerSwitches\": {\n          \"$ref\": \"#/definitions/InstallerSwitches\"\n        },\n        \"InstallerSuccessCodes\": {\n          \"$ref\": \"#/definitions/InstallerSuccessCodes\"\n        },\n        \"ExpectedReturnCodes\": {\n          \"$ref\": \"#/definitions/ExpectedReturnCodes\"\n        },\n        \"UpgradeBehavior\": {\n          \"$ref\": \"#/definitions/UpgradeBehavior\"\n        },\n        \"Commands\": {\n          \"$ref\": \"#/definitions/Commands\"\n        },\n        \"Protocols\": {\n          \"$ref\": \"#/definitions/Protocols\"\n        },\n        \"FileExtensions\": {\n          \"$ref\": \"#/definitions/FileExtensions\"\n        },\n        \"Dependencies\": {\n          \"$ref\": \"#/definitions/Dependencies\"\n        },\n        \"PackageFamilyName\": {\n          \"$ref\": \"#/definitions/PackageFamilyName\"\n        },\n        \"ProductCode\": {\n          \"$ref\": \"#/definitions/ProductCode\"\n        },\n        \"Capabilities\": {\n          \"$ref\": \"#/definitions/Capabilities\"\n        },\n        \"RestrictedCapabilities\": {\n          \"$ref\": \"#/definitions/RestrictedCapabilities\"\n        },\n        \"Markets\": {\n          \"$ref\": \"#/definitions/Markets\"\n        },\n        \"InstallerAbortsTerminal\": {\n          \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\n        },\n        \"ReleaseDate\": {\n          \"$ref\": \"#/definitions/ReleaseDate\"\n        },\n        \"InstallLocationRequired\": {\n          \"$ref\": \"#/definitions/InstallLocationRequired\"\n        },\n        \"RequireExplicitUpgrade\": {\n          \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\n        },\n        \"DisplayInstallWarnings\": {\n          \"$ref\": \"#/definitions/DisplayInstallWarnings\"\n        },\n        \"UnsupportedOSArchitectures\": {\n          \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\n        },\n        \"UnsupportedArguments\": {\n          \"$ref\": \"#/definitions/UnsupportedArguments\"\n        },\n        \"AppsAndFeaturesEntries\": {\n          \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\n        },\n        \"ElevationRequirement\": {\n          \"$ref\": \"#/definitions/ElevationRequirement\"\n        },\n        \"InstallationMetadata\": {\n          \"$ref\": \"#/definitions/InstallationMetadata\"\n        },\n        \"DownloadCommandProhibited\": {\n          \"$ref\": \"#/definitions/DownloadCommandProhibited\"\n        },\n        \"RepairBehavior\": {\n          \"$ref\": \"#/definitions/RepairBehavior\"\n        },\n        \"ArchiveBinariesDependOnPath\": {\n          \"$ref\": \"#/definitions/ArchiveBinariesDependOnPath\"\n        },\n        \"Authentication\": {\n          \"$ref\": \"#/definitions/Authentication\"\n        }\n      },\n      \"required\": [\n        \"Architecture\",\n        \"InstallerUrl\",\n        \"InstallerSha256\"\n      ]\n    }\n  },\n  \"type\": \"object\",\n  \"properties\": {\n    \"PackageIdentifier\": {\n      \"$ref\": \"#/definitions/PackageIdentifier\"\n    },\n    \"PackageVersion\": {\n      \"$ref\": \"#/definitions/PackageVersion\"\n    },\n    \"Channel\": {\n      \"$ref\": \"#/definitions/Channel\"\n    },\n    \"InstallerLocale\": {\n      \"$ref\": \"#/definitions/Locale\"\n    },\n    \"Platform\": {\n      \"$ref\": \"#/definitions/Platform\"\n    },\n    \"MinimumOSVersion\": {\n      \"$ref\": \"#/definitions/MinimumOSVersion\"\n    },\n    \"InstallerType\": {\n      \"$ref\": \"#/definitions/InstallerType\"\n    },\n    \"NestedInstallerType\": {\n      \"$ref\": \"#/definitions/NestedInstallerType\"\n    },\n    \"NestedInstallerFiles\": {\n      \"$ref\": \"#/definitions/NestedInstallerFiles\"\n    },\n    \"Scope\": {\n      \"$ref\": \"#/definitions/Scope\"\n    },\n    \"InstallModes\": {\n      \"$ref\": \"#/definitions/InstallModes\"\n    },\n    \"InstallerSwitches\": {\n      \"$ref\": \"#/definitions/InstallerSwitches\"\n    },\n    \"InstallerSuccessCodes\": {\n      \"$ref\": \"#/definitions/InstallerSuccessCodes\"\n    },\n    \"ExpectedReturnCodes\": {\n      \"$ref\": \"#/definitions/ExpectedReturnCodes\"\n    },\n    \"UpgradeBehavior\": {\n      \"$ref\": \"#/definitions/UpgradeBehavior\"\n    },\n    \"Commands\": {\n      \"$ref\": \"#/definitions/Commands\"\n    },\n    \"Protocols\": {\n      \"$ref\": \"#/definitions/Protocols\"\n    },\n    \"FileExtensions\": {\n      \"$ref\": \"#/definitions/FileExtensions\"\n    },\n    \"Dependencies\": {\n      \"$ref\": \"#/definitions/Dependencies\"\n    },\n    \"PackageFamilyName\": {\n      \"$ref\": \"#/definitions/PackageFamilyName\"\n    },\n    \"ProductCode\": {\n      \"$ref\": \"#/definitions/ProductCode\"\n    },\n    \"Capabilities\": {\n      \"$ref\": \"#/definitions/Capabilities\"\n    },\n    \"RestrictedCapabilities\": {\n      \"$ref\": \"#/definitions/RestrictedCapabilities\"\n    },\n    \"Markets\": {\n      \"$ref\": \"#/definitions/Markets\"\n    },\n    \"InstallerAbortsTerminal\": {\n      \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\n    },\n    \"ReleaseDate\": {\n      \"$ref\": \"#/definitions/ReleaseDate\"\n    },\n    \"InstallLocationRequired\": {\n      \"$ref\": \"#/definitions/InstallLocationRequired\"\n    },\n    \"RequireExplicitUpgrade\": {\n      \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\n    },\n    \"DisplayInstallWarnings\": {\n      \"$ref\": \"#/definitions/DisplayInstallWarnings\"\n    },\n    \"UnsupportedOSArchitectures\": {\n      \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\n    },\n    \"UnsupportedArguments\": {\n      \"$ref\": \"#/definitions/UnsupportedArguments\"\n    },\n    \"AppsAndFeaturesEntries\": {\n      \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\n    },\n    \"ElevationRequirement\": {\n      \"$ref\": \"#/definitions/ElevationRequirement\"\n    },\n    \"InstallationMetadata\": {\n      \"$ref\": \"#/definitions/InstallationMetadata\"\n    },\n    \"DownloadCommandProhibited\": {\n      \"$ref\": \"#/definitions/DownloadCommandProhibited\"\n    },\n    \"RepairBehavior\": {\n      \"$ref\": \"#/definitions/RepairBehavior\"\n    },\n    \"ArchiveBinariesDependOnPath\": {\n      \"$ref\": \"#/definitions/ArchiveBinariesDependOnPath\"\n    },\n    \"Authentication\": {\n      \"$ref\": \"#/definitions/Authentication\"\n    },\n    \"Installers\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/Installer\"\n      },\n      \"minItems\": 1,\n      \"maxItems\": 1024\n    },\n    \"ManifestType\": {\n      \"type\": \"string\",\n      \"default\": \"installer\",\n      \"const\": \"installer\",\n      \"description\": \"The manifest type\"\n    },\n    \"ManifestVersion\": {\n      \"type\": \"string\",\n      \"default\": \"1.10.0\",\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\n      \"description\": \"The manifest syntax version\"\n    }\n  },\n  \"required\": [\n    \"PackageIdentifier\",\n    \"PackageVersion\",\n    \"Installers\",\n    \"ManifestType\",\n    \"ManifestVersion\"\n  ]\n}\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.10.0/manifest.locale.1.10.0.json",
    "content": "{\n  \"$id\": \"https://aka.ms/winget-manifest.locale.1.10.0.schema.json\",\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"description\": \"A representation of a multiple-file manifest representing app metadata in other locale in the OWC. v1.10.0\",\n  \"definitions\": {\n    \"Url\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n      \"maxLength\": 2048,\n      \"description\": \"Optional Url type\"\n    },\n    \"Tag\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 40,\n      \"description\": \"Package tag\"\n    },\n    \"Agreement\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"AgreementLabel\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 100,\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\n        },\n        \"Agreement\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 10000,\n          \"description\": \"The agreement text content.\"\n        },\n        \"AgreementUrl\": {\n          \"$ref\": \"#/definitions/Url\",\n          \"description\": \"The agreement URL.\"\n        }\n      }\n    },\n    \"Documentation\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"DocumentLabel\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 100,\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\n        },\n        \"DocumentUrl\": {\n          \"$ref\": \"#/definitions/Url\",\n          \"description\": \"The documentation URL.\"\n        }\n      }\n    },\n    \"Icon\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"IconUrl\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n          \"maxLength\": 2048,\n          \"description\": \"The url of the hosted icon file\"\n        },\n        \"IconFileType\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"png\",\n            \"jpeg\",\n            \"ico\"\n          ],\n          \"description\": \"The icon file type\"\n        },\n        \"IconResolution\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"enum\": [\n            \"custom\",\n            \"16x16\",\n            \"20x20\",\n            \"24x24\",\n            \"30x30\",\n            \"32x32\",\n            \"36x36\",\n            \"40x40\",\n            \"48x48\",\n            \"60x60\",\n            \"64x64\",\n            \"72x72\",\n            \"80x80\",\n            \"96x96\",\n            \"256x256\"\n          ],\n          \"description\": \"Optional icon resolution\"\n        },\n        \"IconTheme\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"enum\": [\n            \"default\",\n            \"light\",\n            \"dark\",\n            \"highContrast\"\n          ],\n          \"description\": \"Optional icon theme\"\n        },\n        \"IconSha256\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"Optional Sha256 of the icon file\"\n        }\n      },\n      \"required\": [\n        \"IconUrl\",\n        \"IconFileType\"\n      ]\n    }\n  },\n  \"type\": \"object\",\n  \"properties\": {\n    \"PackageIdentifier\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\n      \"maxLength\": 128,\n      \"description\": \"The package unique identifier\"\n    },\n    \"PackageVersion\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n      \"maxLength\": 128,\n      \"description\": \"The package version\"\n    },\n    \"PackageLocale\": {\n      \"type\": \"string\",\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\n      \"maxLength\": 20,\n      \"description\": \"The package meta-data locale\"\n    },\n    \"Publisher\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The publisher name\"\n    },\n    \"PublisherUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher home page\"\n    },\n    \"PublisherSupportUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher support page\"\n    },\n    \"PrivacyUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher privacy page or the package privacy page\"\n    },\n    \"Author\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The package author\"\n    },\n    \"PackageName\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The package name\"\n    },\n    \"PackageUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package home page\"\n    },\n    \"License\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 512,\n      \"description\": \"The package license\"\n    },\n    \"LicenseUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The license page\"\n    },\n    \"Copyright\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 512,\n      \"description\": \"The package copyright\"\n    },\n    \"CopyrightUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package copyright page\"\n    },\n    \"ShortDescription\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 256,\n      \"description\": \"The short package description\"\n    },\n    \"Description\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 10000,\n      \"description\": \"The full package description\"\n    },\n    \"Tags\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Tag\"\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of additional package search terms\"\n    },\n    \"Agreements\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Agreement\"\n      },\n      \"maxItems\": 128\n    },\n    \"ReleaseNotes\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 10000,\n      \"description\": \"The package release notes\"\n    },\n    \"ReleaseNotesUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package release notes url\"\n    },\n    \"PurchaseUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\n    },\n    \"InstallationNotes\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 10000,\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"\n    },\n    \"Documentations\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Documentation\"\n      },\n      \"maxItems\": 256\n    },\n    \"Icons\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Icon\"\n      },\n      \"maxItems\": 1024\n    },\n    \"ManifestType\": {\n      \"type\": \"string\",\n      \"default\": \"locale\",\n      \"const\": \"locale\",\n      \"description\": \"The manifest type\"\n    },\n    \"ManifestVersion\": {\n      \"type\": \"string\",\n      \"default\": \"1.10.0\",\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\n      \"description\": \"The manifest syntax version\"\n    }\n  },\n  \"required\": [\n    \"PackageIdentifier\",\n    \"PackageVersion\",\n    \"PackageLocale\",\n    \"ManifestType\",\n    \"ManifestVersion\"\n  ]\n}\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.10.0/manifest.singleton.1.10.0.json",
    "content": "{\n  \"$id\": \"https://aka.ms/winget-manifest.singleton.1.10.0.schema.json\",\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"description\": \"A representation of a single-file manifest representing an app in the OWC. v1.10.0\",\n  \"definitions\": {\n    \"PackageIdentifier\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\n      \"maxLength\": 128,\n      \"description\": \"The package unique identifier\"\n    },\n    \"PackageVersion\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n      \"maxLength\": 128,\n      \"description\": \"The package version\"\n    },\n    \"Locale\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\n      \"maxLength\": 20,\n      \"description\": \"The package meta-data locale\"\n    },\n    \"Url\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n      \"maxLength\": 2048,\n      \"description\": \"Optional Url type\"\n    },\n    \"Tag\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 40,\n      \"description\": \"Package moniker or tag\"\n    },\n    \"Agreement\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"AgreementLabel\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 100,\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\n        },\n        \"Agreement\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 10000,\n          \"description\": \"The agreement text content.\"\n        },\n        \"AgreementUrl\": {\n          \"$ref\": \"#/definitions/Url\",\n          \"description\": \"The agreement URL.\"\n        }\n      }\n    },\n    \"Documentation\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"DocumentLabel\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 100,\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\n        },\n        \"DocumentUrl\": {\n          \"$ref\": \"#/definitions/Url\",\n          \"description\": \"The documentation URL.\"\n        }\n      }\n    },\n    \"Icon\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"IconUrl\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n          \"maxLength\": 2048,\n          \"description\": \"The url of the hosted icon file\"\n        },\n        \"IconFileType\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"png\",\n            \"jpeg\",\n            \"ico\"\n          ],\n          \"description\": \"The icon file type\"\n        },\n        \"IconResolution\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"enum\": [\n            \"custom\",\n            \"16x16\",\n            \"20x20\",\n            \"24x24\",\n            \"30x30\",\n            \"32x32\",\n            \"36x36\",\n            \"40x40\",\n            \"48x48\",\n            \"60x60\",\n            \"64x64\",\n            \"72x72\",\n            \"80x80\",\n            \"96x96\",\n            \"256x256\"\n          ],\n          \"description\": \"Optional icon resolution\"\n        },\n        \"IconTheme\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"enum\": [\n            \"default\",\n            \"light\",\n            \"dark\",\n            \"highContrast\"\n          ],\n          \"description\": \"Optional icon theme\"\n        },\n        \"IconSha256\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"Optional Sha256 of the icon file\"\n        }\n      },\n      \"required\": [\n        \"IconUrl\",\n        \"IconFileType\"\n      ]\n    },\n    \"Channel\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 16,\n      \"description\": \"The distribution channel\"\n    },\n    \"Platform\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"title\": \"Platform\",\n        \"type\": \"string\",\n        \"enum\": [\n          \"Windows.Desktop\",\n          \"Windows.Universal\"\n        ]\n      },\n      \"maxItems\": 2,\n      \"uniqueItems\": true,\n      \"description\": \"The installer supported operating system\"\n    },\n    \"MinimumOSVersion\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$\",\n      \"description\": \"The installer minimum operating system version\"\n    },\n    \"InstallerType\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"msix\",\n        \"msi\",\n        \"appx\",\n        \"exe\",\n        \"zip\",\n        \"inno\",\n        \"nullsoft\",\n        \"wix\",\n        \"burn\",\n        \"pwa\",\n        \"portable\"\n      ],\n      \"description\": \"Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level\"\n    },\n    \"NestedInstallerType\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"msix\",\n        \"msi\",\n        \"appx\",\n        \"exe\",\n        \"inno\",\n        \"nullsoft\",\n        \"wix\",\n        \"burn\",\n        \"portable\"\n      ],\n      \"description\": \"Enumeration of supported nested installer types contained inside an archive file\"\n    },\n    \"NestedInstallerFiles\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"object\",\n        \"title\": \"NestedInstallerFile\",\n        \"properties\": {\n          \"RelativeFilePath\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 512,\n            \"description\": \"The relative path to the nested installer file\"\n          },\n          \"PortableCommandAlias\": {\n            \"type\": [ \"string\", \"null\" ],\n            \"minLength\": 1,\n            \"maxLength\": 40,\n            \"description\": \"The command alias to be used for calling the package. Only applies to the nested portable package\"\n          }\n        },\n        \"required\": [ \"RelativeFilePath\" ],\n        \"description\": \"A nested installer file contained inside an archive\"\n      },\n      \"maxItems\": 1024,\n      \"description\": \"List of nested installer files contained inside an archive\"\n    },\n    \"Architecture\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"x86\",\n        \"x64\",\n        \"arm\",\n        \"arm64\",\n        \"neutral\"\n      ],\n      \"description\": \"The installer target architecture\"\n    },\n    \"Scope\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"user\",\n        \"machine\"\n      ],\n      \"description\": \"Scope indicates if the installer is per user or per machine\"\n    },\n    \"InstallModes\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"title\": \"InstallModes\",\n        \"type\": \"string\",\n        \"enum\": [\n          \"interactive\",\n          \"silent\",\n          \"silentWithProgress\"\n        ]\n      },\n      \"maxItems\": 3,\n      \"uniqueItems\": true,\n      \"description\": \"List of supported installer modes\"\n    },\n    \"InstallerSwitches\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"Silent\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Silent is the value that should be passed to the installer when user chooses a silent or quiet install\"\n        },\n        \"SilentWithProgress\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install\"\n        },\n        \"Interactive\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Interactive is the value that should be passed to the installer when user chooses an interactive install\"\n        },\n        \"InstallLocation\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"InstallLocation is the value passed to the installer for custom install location. <INSTALLPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\n        },\n        \"Log\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Log is the value passed to the installer for custom log file path. <LOGPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\n        },\n        \"Upgrade\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Upgrade is the value that should be passed to the installer when user chooses an upgrade\"\n        },\n        \"Custom\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 2048,\n          \"description\": \"Custom switches will be passed directly to the installer by winget\"\n        },\n        \"Repair\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"The 'Repair' value must be passed to the installer, ModifyPath ARP command, or uninstaller ARP command when the user opts for a repair\"\n        }\n      }\n    },\n    \"InstallerReturnCode\": {\n      \"type\": \"integer\",\n      \"format\": \"long\",\n      \"not\": {\n        \"enum\": [ 0 ]\n      },\n      \"minimum\": -2147483648,\n      \"maximum\": 4294967295,\n      \"description\": \"An exit code that can be returned by the installer after execution\"\n    },\n    \"InstallerSuccessCodes\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/InstallerReturnCode\"\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of additional non-zero installer success exit codes other than known default values by winget\"\n    },\n    \"ExpectedReturnCodes\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"object\",\n        \"title\": \"ExpectedReturnCode\",\n        \"properties\": {\n          \"InstallerReturnCode\": {\n            \"$ref\": \"#/definitions/InstallerReturnCode\"\n          },\n          \"ReturnResponse\": {\n            \"type\": \"string\",\n            \"enum\": [\n              \"packageInUse\",\n              \"packageInUseByApplication\",\n              \"installInProgress\",\n              \"fileInUse\",\n              \"missingDependency\",\n              \"diskFull\",\n              \"insufficientMemory\",\n              \"invalidParameter\",\n              \"noNetwork\",\n              \"contactSupport\",\n              \"rebootRequiredToFinish\",\n              \"rebootRequiredForInstall\",\n              \"rebootInitiated\",\n              \"cancelledByUser\",\n              \"alreadyInstalled\",\n              \"downgrade\",\n              \"blockedByPolicy\",\n              \"systemNotSupported\",\n              \"custom\"\n            ]\n          },\n          \"ReturnResponseUrl\": {\n            \"$ref\": \"#/definitions/Url\",\n            \"description\": \"The return response url to provide additional guidance for expected return codes\"\n          }\n        },\n        \"required\": [ \"InstallerReturnCode\", \"ReturnResponse\" ]\n      },\n      \"maxItems\": 128,\n      \"description\": \"Installer exit codes for common errors\"\n    },\n    \"UpgradeBehavior\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"install\",\n        \"uninstallPrevious\",\n        \"deny\"\n      ],\n      \"description\": \"The upgrade method\"\n    },\n    \"Commands\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"maxLength\": 40\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of commands or aliases to run the package\"\n    },\n    \"Protocols\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"maxLength\": 2048\n      },\n      \"maxItems\": 64,\n      \"uniqueItems\": true,\n      \"description\": \"List of protocols the package provides a handler for\"\n    },\n    \"FileExtensions\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n        \"maxLength\": 64\n      },\n      \"maxItems\": 512,\n      \"uniqueItems\": true,\n      \"description\": \"List of file extensions the package could support\"\n    },\n    \"Dependencies\": {\n      \"type\": [ \"object\", \"null\" ],\n      \"properties\": {\n        \"WindowsFeatures\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 128\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of Windows feature dependencies\"\n        },\n        \"WindowsLibraries\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 128\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of Windows library dependencies\"\n        },\n        \"PackageDependencies\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"PackageIdentifier\": {\n                \"$ref\": \"#/definitions/PackageIdentifier\"\n              },\n              \"MinimumVersion\": {\n                \"$ref\": \"#/definitions/PackageVersion\"\n              }\n            },\n            \"required\": [ \"PackageIdentifier\" ]\n          },\n          \"maxItems\": 16,\n          \"description\": \"List of package dependencies from current source\"\n        },\n        \"ExternalDependencies\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 128\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of external package dependencies\"\n        }\n      }\n    },\n    \"PackageFamilyName\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^[A-Za-z0-9][-\\\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$\",\n      \"maxLength\": 255,\n      \"description\": \"PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources\"\n    },\n    \"ProductCode\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 255,\n      \"description\": \"ProductCode could be used for correlation of packages across sources\"\n    },\n    \"Capabilities\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"maxLength\": 40\n      },\n      \"maxItems\": 1000,\n      \"uniqueItems\": true,\n      \"description\": \"List of appx or msix installer capabilities\"\n    },\n    \"RestrictedCapabilities\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"maxLength\": 40\n      },\n      \"maxItems\": 1000,\n      \"uniqueItems\": true,\n      \"description\": \"List of appx or msix installer restricted capabilities\"\n    },\n    \"Market\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[A-Z]{2}$\",\n      \"description\": \"The installer target market\"\n    },\n    \"MarketArray\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"maxItems\": 256,\n      \"items\": {\n        \"$ref\": \"#/definitions/Market\"\n      },\n      \"description\": \"Array of markets\"\n    },\n    \"Markets\": {\n      \"description\": \"The installer markets\",\n      \"type\": [ \"object\", \"null\" ],\n      \"oneOf\": [\n        {\n          \"properties\": {\n            \"AllowedMarkets\": {\n              \"$ref\": \"#/definitions/MarketArray\"\n            }\n          },\n          \"required\": [ \"AllowedMarkets\" ]\n        },\n        {\n          \"properties\": {\n            \"ExcludedMarkets\": {\n              \"$ref\": \"#/definitions/MarketArray\"\n            }\n          },\n          \"required\": [ \"ExcludedMarkets\" ]\n        }\n      ]\n    },\n    \"InstallerAbortsTerminal\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer will abort terminal. Default is false\"\n    },\n    \"ReleaseDate\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"format\": \"date\",\n      \"description\": \"The installer release date\"\n    },\n    \"InstallLocationRequired\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer requires an install location provided\"\n    },\n    \"RequireExplicitUpgrade\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer should be pinned by default from upgrade\"\n    },\n    \"DisplayInstallWarnings\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications.\"\n    },\n    \"UnsupportedOSArchitectures\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"items\": {\n        \"type\": \"string\",\n        \"title\": \"UnsupportedOSArchitecture\",\n        \"enum\": [\n          \"x86\",\n          \"x64\",\n          \"arm\",\n          \"arm64\"\n        ]\n      },\n      \"description\": \"List of OS architectures the installer does not support\"\n    },\n    \"UnsupportedArguments\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"items\": {\n        \"type\": \"string\",\n        \"title\": \"UnsupportedArgument\",\n        \"enum\": [\n          \"log\",\n          \"location\"\n        ]\n      },\n      \"description\": \"List of winget arguments the installer does not support\"\n    },\n    \"AppsAndFeaturesEntry\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"DisplayName\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 256,\n          \"description\": \"The DisplayName registry value\"\n        },\n        \"Publisher\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 256,\n          \"description\": \"The Publisher registry value\"\n        },\n        \"DisplayVersion\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 128,\n          \"description\": \"The DisplayVersion registry value\"\n        },\n        \"ProductCode\": {\n          \"$ref\": \"#/definitions/ProductCode\"\n        },\n        \"UpgradeCode\": {\n          \"$ref\": \"#/definitions/ProductCode\"\n        },\n        \"InstallerType\": {\n          \"$ref\": \"#/definitions/InstallerType\"\n        }\n      },\n      \"description\": \"Various key values under installer's ARP entry\"\n    },\n    \"AppsAndFeaturesEntries\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"maxItems\": 128,\n      \"items\": {\n        \"$ref\": \"#/definitions/AppsAndFeaturesEntry\"\n      },\n      \"description\": \"List of ARP entries.\"\n    },\n    \"ElevationRequirement\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"elevationRequired\",\n        \"elevationProhibited\",\n        \"elevatesSelf\"\n      ],\n      \"description\": \"The installer's elevation requirement\"\n    },\n    \"InstallationMetadata\": {\n      \"type\": \"object\",\n      \"title\": \"InstallationMetadata\",\n      \"properties\": {\n        \"DefaultInstallLocation\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 2048,\n          \"description\": \"Represents the default installed package location. Used for deeper installation detection.\"\n        },\n        \"Files\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"uniqueItems\": true,\n          \"maxItems\": 2048,\n          \"items\": {\n            \"type\": \"object\",\n            \"title\": \"InstalledFile\",\n            \"properties\": {\n              \"RelativeFilePath\": {\n                \"type\": \"string\",\n                \"minLength\": 1,\n                \"maxLength\": 2048,\n                \"description\": \"The relative path to the installed file.\"\n              },\n              \"FileSha256\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n                \"description\": \"Optional Sha256 of the installed file.\"\n              },\n              \"FileType\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"enum\": [\n                  \"launch\",\n                  \"uninstall\",\n                  \"other\"\n                ],\n                \"description\": \"The optional installed file type. If not specified, the file is treated as other.\"\n              },\n              \"InvocationParameter\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"minLength\": 1,\n                \"maxLength\": 2048,\n                \"description\": \"Optional parameter for invocable files.\"\n              },\n              \"DisplayName\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"minLength\": 1,\n                \"maxLength\": 256,\n                \"description\": \"Optional display name for invocable files.\"\n              }\n            },\n            \"required\": [ \"RelativeFilePath\" ],\n            \"description\": \"Represents an installed file.\"\n          },\n          \"description\": \"List of installed files.\"\n        }\n      },\n      \"description\": \"Details about the installation. Used for deeper installation detection.\"\n    },\n    \"DownloadCommandProhibited\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer is prohibited from being downloaded for offline installation.\"\n    },\n    \"RepairBehavior\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"modify\",\n        \"uninstaller\",\n        \"installer\"\n      ],\n      \"description\": \"The repair method\"\n    },\n    \"ArchiveBinariesDependOnPath\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the install location should be added directly to the PATH environment variable. Only applies to an archive containing portable packages.\"\n    },\n    \"Authentication\": {\n      \"type\": [ \"object\", \"null\" ],\n      \"properties\": {\n        \"AuthenticationType\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"none\",\n            \"microsoftEntraId\",\n            \"microsoftEntraIdForAzureBlobStorage\"\n          ],\n          \"description\": \"The authentication type\"\n        },\n        \"MicrosoftEntraIdAuthenticationInfo\": {\n          \"type\": [ \"object\", \"null\" ],\n          \"properties\": {\n            \"Resource\": {\n              \"type\": [ \"string\", \"null\" ],\n              \"minLength\": 1,\n              \"maxLength\": 512,\n              \"description\": \"The resource value for Microsoft Entra Id authentication.\"\n            },\n            \"Scope\": {\n              \"type\": [ \"string\", \"null\" ],\n              \"minLength\": 1,\n              \"maxLength\": 512,\n              \"description\": \"The scope value for Microsoft Entra Id authentication.\"\n            }\n          },\n          \"description\": \"The Microsoft Entra Id authentication info\"\n        }\n      },\n      \"required\": [\n        \"AuthenticationType\"\n      ],\n      \"description\": \"The authentication requirement for downloading the installer.\"\n    },\n    \"Installer\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"InstallerLocale\": {\n          \"$ref\": \"#/definitions/Locale\"\n        },\n        \"Platform\": {\n          \"$ref\": \"#/definitions/Platform\"\n        },\n        \"MinimumOSVersion\": {\n          \"$ref\": \"#/definitions/MinimumOSVersion\"\n        },\n        \"Architecture\": {\n          \"$ref\": \"#/definitions/Architecture\"\n        },\n        \"InstallerType\": {\n          \"$ref\": \"#/definitions/InstallerType\"\n        },\n        \"NestedInstallerType\": {\n          \"$ref\": \"#/definitions/NestedInstallerType\"\n        },\n        \"NestedInstallerFiles\": {\n          \"$ref\": \"#/definitions/NestedInstallerFiles\"\n        },\n        \"Scope\": {\n          \"$ref\": \"#/definitions/Scope\"\n        },\n        \"InstallerUrl\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n          \"maxLength\": 2048,\n          \"description\": \"The installer Url\"\n        },\n        \"InstallerSha256\": {\n          \"type\": \"string\",\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"Sha256 is required. Sha256 of the installer\"\n        },\n        \"SignatureSha256\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable\"\n        },\n        \"InstallModes\": {\n          \"$ref\": \"#/definitions/InstallModes\"\n        },\n        \"InstallerSwitches\": {\n          \"$ref\": \"#/definitions/InstallerSwitches\"\n        },\n        \"InstallerSuccessCodes\": {\n          \"$ref\": \"#/definitions/InstallerSuccessCodes\"\n        },\n        \"ExpectedReturnCodes\": {\n          \"$ref\": \"#/definitions/ExpectedReturnCodes\"\n        },\n        \"UpgradeBehavior\": {\n          \"$ref\": \"#/definitions/UpgradeBehavior\"\n        },\n        \"Commands\": {\n          \"$ref\": \"#/definitions/Commands\"\n        },\n        \"Protocols\": {\n          \"$ref\": \"#/definitions/Protocols\"\n        },\n        \"FileExtensions\": {\n          \"$ref\": \"#/definitions/FileExtensions\"\n        },\n        \"Dependencies\": {\n          \"$ref\": \"#/definitions/Dependencies\"\n        },\n        \"PackageFamilyName\": {\n          \"$ref\": \"#/definitions/PackageFamilyName\"\n        },\n        \"ProductCode\": {\n          \"$ref\": \"#/definitions/ProductCode\"\n        },\n        \"Capabilities\": {\n          \"$ref\": \"#/definitions/Capabilities\"\n        },\n        \"RestrictedCapabilities\": {\n          \"$ref\": \"#/definitions/RestrictedCapabilities\"\n        },\n        \"Markets\": {\n          \"$ref\": \"#/definitions/Markets\"\n        },\n        \"InstallerAbortsTerminal\": {\n          \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\n        },\n        \"ReleaseDate\": {\n          \"$ref\": \"#/definitions/ReleaseDate\"\n        },\n        \"InstallLocationRequired\": {\n          \"$ref\": \"#/definitions/InstallLocationRequired\"\n        },\n        \"RequireExplicitUpgrade\": {\n          \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\n        },\n        \"DisplayInstallWarnings\": {\n          \"$ref\": \"#/definitions/DisplayInstallWarnings\"\n        },\n        \"UnsupportedOSArchitectures\": {\n          \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\n        },\n        \"UnsupportedArguments\": {\n          \"$ref\": \"#/definitions/UnsupportedArguments\"\n        },\n        \"AppsAndFeaturesEntries\": {\n          \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\n        },\n        \"ElevationRequirement\": {\n          \"$ref\": \"#/definitions/ElevationRequirement\"\n        },\n        \"InstallationMetadata\": {\n          \"$ref\": \"#/definitions/InstallationMetadata\"\n        },\n        \"DownloadCommandProhibited\": {\n          \"$ref\": \"#/definitions/DownloadCommandProhibited\"\n        },\n        \"RepairBehavior\": {\n          \"$ref\": \"#/definitions/RepairBehavior\"\n        },\n        \"ArchiveBinariesDependOnPath\": {\n          \"$ref\": \"#/definitions/ArchiveBinariesDependOnPath\"\n        },\n        \"Authentication\": {\n          \"$ref\": \"#/definitions/Authentication\"\n        }\n      },\n      \"required\": [\n        \"Architecture\",\n        \"InstallerUrl\",\n        \"InstallerSha256\"\n      ]\n    }\n  },\n  \"type\": \"object\",\n  \"properties\": {\n    \"PackageIdentifier\": {\n      \"$ref\": \"#/definitions/PackageIdentifier\"\n    },\n    \"PackageVersion\": {\n      \"$ref\": \"#/definitions/PackageVersion\"\n    },\n    \"PackageLocale\": {\n      \"$ref\": \"#/definitions/Locale\"\n    },\n    \"Publisher\": {\n      \"type\": \"string\",\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The publisher name\"\n    },\n    \"PublisherUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher home page\"\n    },\n    \"PublisherSupportUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher support page\"\n    },\n    \"PrivacyUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher privacy page or the package privacy page\"\n    },\n    \"Author\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The package author\"\n    },\n    \"PackageName\": {\n      \"type\": \"string\",\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The package name\"\n    },\n    \"PackageUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package home page\"\n    },\n    \"License\": {\n      \"type\": \"string\",\n      \"minLength\": 3,\n      \"maxLength\": 512,\n      \"description\": \"The package license\"\n    },\n    \"LicenseUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The license page\"\n    },\n    \"Copyright\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 512,\n      \"description\": \"The package copyright\"\n    },\n    \"CopyrightUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package copyright page\"\n    },\n    \"ShortDescription\": {\n      \"type\": \"string\",\n      \"minLength\": 3,\n      \"maxLength\": 256,\n      \"description\": \"The short package description\"\n    },\n    \"Description\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 10000,\n      \"description\": \"The full package description\"\n    },\n    \"Moniker\": {\n      \"$ref\": \"#/definitions/Tag\",\n      \"description\": \"The most common package term\"\n    },\n    \"Tags\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Tag\"\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of additional package search terms\"\n    },\n    \"Agreements\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Agreement\"\n      },\n      \"maxItems\": 128\n    },\n    \"ReleaseNotes\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 10000,\n      \"description\": \"The package release notes\"\n    },\n    \"ReleaseNotesUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package release notes url\"\n    },\n    \"PurchaseUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\n    },\n    \"InstallationNotes\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 10000,\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"\n    },\n    \"Documentations\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Documentation\"\n      },\n      \"maxItems\": 256\n    },\n    \"Icons\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Icon\"\n      },\n      \"maxItems\": 1024\n    },\n    \"Channel\": {\n      \"$ref\": \"#/definitions/Channel\"\n    },\n    \"InstallerLocale\": {\n      \"$ref\": \"#/definitions/Locale\"\n    },\n    \"Platform\": {\n      \"$ref\": \"#/definitions/Platform\"\n    },\n    \"MinimumOSVersion\": {\n      \"$ref\": \"#/definitions/MinimumOSVersion\"\n    },\n    \"InstallerType\": {\n      \"$ref\": \"#/definitions/InstallerType\"\n    },\n    \"NestedInstallerType\": {\n      \"$ref\": \"#/definitions/NestedInstallerType\"\n    },\n    \"NestedInstallerFiles\": {\n      \"$ref\": \"#/definitions/NestedInstallerFiles\"\n    },\n    \"Scope\": {\n      \"$ref\": \"#/definitions/Scope\"\n    },\n    \"InstallModes\": {\n      \"$ref\": \"#/definitions/InstallModes\"\n    },\n    \"InstallerSwitches\": {\n      \"$ref\": \"#/definitions/InstallerSwitches\"\n    },\n    \"InstallerSuccessCodes\": {\n      \"$ref\": \"#/definitions/InstallerSuccessCodes\"\n    },\n    \"ExpectedReturnCodes\": {\n      \"$ref\": \"#/definitions/ExpectedReturnCodes\"\n    },\n    \"UpgradeBehavior\": {\n      \"$ref\": \"#/definitions/UpgradeBehavior\"\n    },\n    \"Commands\": {\n      \"$ref\": \"#/definitions/Commands\"\n    },\n    \"Protocols\": {\n      \"$ref\": \"#/definitions/Protocols\"\n    },\n    \"FileExtensions\": {\n      \"$ref\": \"#/definitions/FileExtensions\"\n    },\n    \"Dependencies\": {\n      \"$ref\": \"#/definitions/Dependencies\"\n    },\n    \"PackageFamilyName\": {\n      \"$ref\": \"#/definitions/PackageFamilyName\"\n    },\n    \"ProductCode\": {\n      \"$ref\": \"#/definitions/ProductCode\"\n    },\n    \"Capabilities\": {\n      \"$ref\": \"#/definitions/Capabilities\"\n    },\n    \"RestrictedCapabilities\": {\n      \"$ref\": \"#/definitions/RestrictedCapabilities\"\n    },\n    \"Markets\": {\n      \"$ref\": \"#/definitions/Markets\"\n    },\n    \"InstallerAbortsTerminal\": {\n      \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\n    },\n    \"ReleaseDate\": {\n      \"$ref\": \"#/definitions/ReleaseDate\"\n    },\n    \"InstallLocationRequired\": {\n      \"$ref\": \"#/definitions/InstallLocationRequired\"\n    },\n    \"RequireExplicitUpgrade\": {\n      \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\n    },\n    \"DisplayInstallWarnings\": {\n      \"$ref\": \"#/definitions/DisplayInstallWarnings\"\n    },\n    \"UnsupportedOSArchitectures\": {\n      \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\n    },\n    \"UnsupportedArguments\": {\n      \"$ref\": \"#/definitions/UnsupportedArguments\"\n    },\n    \"AppsAndFeaturesEntries\": {\n      \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\n    },\n    \"ElevationRequirement\": {\n      \"$ref\": \"#/definitions/ElevationRequirement\"\n    },\n    \"InstallationMetadata\": {\n      \"$ref\": \"#/definitions/InstallationMetadata\"\n    },\n    \"DownloadCommandProhibited\": {\n      \"$ref\": \"#/definitions/DownloadCommandProhibited\"\n    },\n    \"RepairBehavior\": {\n      \"$ref\": \"#/definitions/RepairBehavior\"\n    },\n    \"ArchiveBinariesDependOnPath\": {\n      \"$ref\": \"#/definitions/ArchiveBinariesDependOnPath\"\n    },\n    \"Authentication\": {\n      \"$ref\": \"#/definitions/Authentication\"\n    },\n    \"Installers\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/Installer\"\n      },\n      \"minItems\": 1,\n      \"maxItems\": 1\n    },\n    \"ManifestType\": {\n      \"type\": \"string\",\n      \"default\": \"singleton\",\n      \"const\": \"singleton\",\n      \"description\": \"The manifest type\"\n    },\n    \"ManifestVersion\": {\n      \"type\": \"string\",\n      \"default\": \"1.10.0\",\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\n      \"description\": \"The manifest syntax version\"\n    }\n  },\n  \"required\": [\n    \"PackageIdentifier\",\n    \"PackageVersion\",\n    \"PackageLocale\",\n    \"Publisher\",\n    \"PackageName\",\n    \"License\",\n    \"ShortDescription\",\n    \"Installers\",\n    \"ManifestType\",\n    \"ManifestVersion\"\n  ]\n}\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.10.0/manifest.version.1.10.0.json",
    "content": "{\n  \"$id\": \"https://aka.ms/winget-manifest.version.1.10.0.schema.json\",\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"description\": \"A representation of a multi-file manifest representing an app version in the OWC. v1.10.0\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"PackageIdentifier\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\n      \"maxLength\": 128,\n      \"description\": \"The package unique identifier\"\n    },\n    \"PackageVersion\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n      \"maxLength\": 128,\n      \"description\": \"The package version\"\n    },\n    \"DefaultLocale\": {\n      \"type\": \"string\",\n      \"default\": \"en-US\",\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\n      \"maxLength\": 20,\n      \"description\": \"The default package meta-data locale\"\n    },\n    \"ManifestType\": {\n      \"type\": \"string\",\n      \"default\": \"version\",\n      \"const\": \"version\",\n      \"description\": \"The manifest type\"\n    },\n    \"ManifestVersion\": {\n      \"type\": \"string\",\n      \"default\": \"1.10.0\",\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\n      \"description\": \"The manifest syntax version\"\n    }\n  },\n  \"required\": [\n    \"PackageIdentifier\",\n    \"PackageVersion\",\n    \"DefaultLocale\",\n    \"ManifestType\",\n    \"ManifestVersion\"\n  ]\n}"
  },
  {
    "path": "schemas/JSON/manifests/v1.12.0/manifest.defaultLocale.1.12.0.json",
    "content": "{\n  \"$id\": \"https://aka.ms/winget-manifest.defaultlocale.1.12.0.schema.json\",\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"description\": \"A representation of a multiple-file manifest representing a default app metadata in the OWC. v1.12.0\",\n  \"definitions\": {\n    \"Url\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n      \"maxLength\": 2048,\n      \"description\": \"Optional Url type\"\n    },\n    \"Tag\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 40,\n      \"description\": \"Package moniker or tag\"\n    },\n    \"Agreement\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"AgreementLabel\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 100,\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\n        },\n        \"Agreement\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 10000,\n          \"description\": \"The agreement text content.\"\n        },\n        \"AgreementUrl\": {\n          \"$ref\": \"#/definitions/Url\",\n          \"description\": \"The agreement URL.\"\n        }\n      }\n    },\n    \"Documentation\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"DocumentLabel\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 100,\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\n        },\n        \"DocumentUrl\": {\n          \"$ref\": \"#/definitions/Url\",\n          \"description\": \"The documentation URL.\"\n        }\n      }\n    },\n    \"Icon\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"IconUrl\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n          \"maxLength\": 2048,\n          \"description\": \"The url of the hosted icon file\"\n        },\n        \"IconFileType\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"png\",\n            \"jpeg\",\n            \"ico\"\n          ],\n          \"description\": \"The icon file type\"\n        },\n        \"IconResolution\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"enum\": [\n            \"custom\",\n            \"16x16\",\n            \"20x20\",\n            \"24x24\",\n            \"30x30\",\n            \"32x32\",\n            \"36x36\",\n            \"40x40\",\n            \"48x48\",\n            \"60x60\",\n            \"64x64\",\n            \"72x72\",\n            \"80x80\",\n            \"96x96\",\n            \"256x256\"\n          ],\n          \"description\": \"Optional icon resolution\"\n        },\n        \"IconTheme\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"enum\": [\n            \"default\",\n            \"light\",\n            \"dark\",\n            \"highContrast\"\n          ],\n          \"description\": \"Optional icon theme\"\n        },\n        \"IconSha256\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"Optional Sha256 of the icon file\"\n        }\n      },\n      \"required\": [\n        \"IconUrl\",\n        \"IconFileType\"\n      ]\n    }\n  },\n  \"type\": \"object\",\n  \"properties\": {\n    \"PackageIdentifier\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\n      \"maxLength\": 128,\n      \"description\": \"The package unique identifier\"\n    },\n    \"PackageVersion\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n      \"maxLength\": 128,\n      \"description\": \"The package version\"\n    },\n    \"PackageLocale\": {\n      \"type\": \"string\",\n      \"default\": \"en-US\",\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\n      \"maxLength\": 20,\n      \"description\": \"The package meta-data locale\"\n    },\n    \"Publisher\": {\n      \"type\": \"string\",\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The publisher name\"\n    },\n    \"PublisherUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher home page\"\n    },\n    \"PublisherSupportUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher support page\"\n    },\n    \"PrivacyUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher privacy page or the package privacy page\"\n    },\n    \"Author\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The package author\"\n    },\n    \"PackageName\": {\n      \"type\": \"string\",\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The package name\"\n    },\n    \"PackageUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package home page\"\n    },\n    \"License\": {\n      \"type\": \"string\",\n      \"minLength\": 3,\n      \"maxLength\": 512,\n      \"description\": \"The package license\"\n    },\n    \"LicenseUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The license page\"\n    },\n    \"Copyright\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 512,\n      \"description\": \"The package copyright\"\n    },\n    \"CopyrightUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package copyright page\"\n    },\n    \"ShortDescription\": {\n      \"type\": \"string\",\n      \"minLength\": 3,\n      \"maxLength\": 256,\n      \"description\": \"The short package description\"\n    },\n    \"Description\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 10000,\n      \"description\": \"The full package description\"\n    },\n    \"Moniker\": {\n      \"$ref\": \"#/definitions/Tag\",\n      \"description\": \"The most common package term\"\n    },\n    \"Tags\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Tag\"\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of additional package search terms\"\n    },\n    \"Agreements\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Agreement\"\n      },\n      \"maxItems\": 128\n    },\n    \"ReleaseNotes\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 10000,\n      \"description\": \"The package release notes\"\n    },\n    \"ReleaseNotesUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package release notes url\"\n    },\n    \"PurchaseUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\n    },\n    \"InstallationNotes\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 10000,\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"\n    },\n    \"Documentations\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Documentation\"\n      },\n      \"maxItems\": 256\n    },\n    \"Icons\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Icon\"\n      },\n      \"maxItems\": 1024\n    },\n    \"ManifestType\": {\n      \"type\": \"string\",\n      \"default\": \"defaultLocale\",\n      \"const\": \"defaultLocale\",\n      \"description\": \"The manifest type\"\n    },\n    \"ManifestVersion\": {\n      \"type\": \"string\",\n      \"default\": \"1.12.0\",\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\n      \"description\": \"The manifest syntax version\"\n    }\n  },\n  \"required\": [\n    \"PackageIdentifier\",\n    \"PackageVersion\",\n    \"PackageLocale\",\n    \"Publisher\",\n    \"PackageName\",\n    \"License\",\n    \"ShortDescription\",\n    \"ManifestType\",\n    \"ManifestVersion\"\n  ]\n}\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.12.0/manifest.installer.1.12.0.json",
    "content": "{\n  \"$id\": \"https://aka.ms/winget-manifest.installer.1.12.0.schema.json\",\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"description\": \"A representation of a single-file manifest representing an app installers in the OWC. v1.12.0\",\n  \"definitions\": {\n    \"PackageIdentifier\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\n      \"maxLength\": 128,\n      \"description\": \"The package unique identifier\"\n    },\n    \"PackageVersion\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n      \"maxLength\": 128,\n      \"description\": \"The package version\"\n    },\n    \"Locale\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\n      \"maxLength\": 20,\n      \"description\": \"The installer meta-data locale\"\n    },\n    \"Channel\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 16,\n      \"description\": \"The distribution channel\"\n    },\n    \"Platform\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"title\": \"Platform\",\n        \"type\": \"string\",\n        \"enum\": [\n          \"Windows.Desktop\",\n          \"Windows.Universal\"\n        ]\n      },\n      \"maxItems\": 2,\n      \"uniqueItems\": true,\n      \"description\": \"The installer supported operating system\"\n    },\n    \"MinimumOSVersion\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$\",\n      \"description\": \"The installer minimum operating system version\"\n    },\n    \"Url\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n      \"maxLength\": 2048,\n      \"description\": \"Url type\"\n    },\n    \"InstallerType\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"msix\",\n        \"msi\",\n        \"appx\",\n        \"exe\",\n        \"zip\",\n        \"inno\",\n        \"nullsoft\",\n        \"wix\",\n        \"burn\",\n        \"pwa\",\n        \"portable\",\n        \"font\"\n      ],\n      \"description\": \"Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level\"\n    },\n    \"NestedInstallerType\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"msix\",\n        \"msi\",\n        \"appx\",\n        \"exe\",\n        \"inno\",\n        \"nullsoft\",\n        \"wix\",\n        \"burn\",\n        \"portable\",\n        \"font\"\n      ],\n      \"description\": \"Enumeration of supported nested installer types contained inside an archive file\"\n    },\n    \"NestedInstallerFiles\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"object\",\n        \"title\": \"NestedInstallerFile\",\n        \"properties\": {\n          \"RelativeFilePath\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 512,\n            \"description\": \"The relative path to the nested installer file\"\n          },\n          \"PortableCommandAlias\": {\n            \"type\": [ \"string\", \"null\" ],\n            \"minLength\": 1,\n            \"maxLength\": 40,\n            \"description\": \"The command alias to be used for calling the package. Only applies to the nested portable package\"\n          }\n        },\n        \"required\": [ \"RelativeFilePath\" ],\n        \"description\": \"A nested installer file contained inside an archive\"\n      },\n      \"maxItems\": 1024,\n      \"description\": \"List of nested installer files contained inside an archive\"\n    },\n    \"Architecture\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"x86\",\n        \"x64\",\n        \"arm\",\n        \"arm64\",\n        \"neutral\"\n      ],\n      \"description\": \"The installer target architecture\"\n    },\n    \"Scope\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"user\",\n        \"machine\"\n      ],\n      \"description\": \"Scope indicates if the installer is per user or per machine\"\n    },\n    \"InstallModes\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"title\": \"InstallModes\",\n        \"type\": \"string\",\n        \"enum\": [\n          \"interactive\",\n          \"silent\",\n          \"silentWithProgress\"\n        ]\n      },\n      \"maxItems\": 3,\n      \"uniqueItems\": true,\n      \"description\": \"List of supported installer modes\"\n    },\n    \"InstallerSwitches\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"Silent\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Silent is the value that should be passed to the installer when user chooses a silent or quiet install\"\n        },\n        \"SilentWithProgress\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install\"\n        },\n        \"Interactive\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Interactive is the value that should be passed to the installer when user chooses an interactive install\"\n        },\n        \"InstallLocation\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"InstallLocation is the value passed to the installer for custom install location. <INSTALLPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\n        },\n        \"Log\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Log is the value passed to the installer for custom log file path. <LOGPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\n        },\n        \"Upgrade\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Upgrade is the value that should be passed to the installer when user chooses an upgrade\"\n        },\n        \"Custom\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 2048,\n          \"description\": \"Custom switches will be passed directly to the installer by winget\"\n        },\n        \"Repair\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"The 'Repair' value must be passed to the installer, ModifyPath ARP command, or uninstaller ARP command when the user opts for a repair.\"\n        }\n      }\n    },\n    \"InstallerReturnCode\": {\n      \"type\": \"integer\",\n      \"format\": \"long\",\n      \"not\": {\n        \"enum\": [ 0 ]\n      },\n      \"minimum\": -2147483648,\n      \"maximum\": 4294967295,\n      \"description\": \"An exit code that can be returned by the installer after execution\"\n    },\n    \"InstallerSuccessCodes\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/InstallerReturnCode\"\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of additional non-zero installer success exit codes other than known default values by winget\"\n    },\n    \"ExpectedReturnCodes\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"object\",\n        \"title\": \"ExpectedReturnCode\",\n        \"properties\": {\n          \"InstallerReturnCode\": {\n            \"$ref\": \"#/definitions/InstallerReturnCode\"\n          },\n          \"ReturnResponse\": {\n            \"type\": \"string\",\n            \"enum\": [\n              \"packageInUse\",\n              \"packageInUseByApplication\",\n              \"installInProgress\",\n              \"fileInUse\",\n              \"missingDependency\",\n              \"diskFull\",\n              \"insufficientMemory\",\n              \"invalidParameter\",\n              \"noNetwork\",\n              \"contactSupport\",\n              \"rebootRequiredToFinish\",\n              \"rebootRequiredForInstall\",\n              \"rebootInitiated\",\n              \"cancelledByUser\",\n              \"alreadyInstalled\",\n              \"downgrade\",\n              \"blockedByPolicy\",\n              \"systemNotSupported\",\n              \"custom\"\n            ]\n          },\n          \"ReturnResponseUrl\": {\n            \"$ref\": \"#/definitions/Url\",\n            \"description\": \"The return response url to provide additional guidance for expected return codes\"\n          }\n        },\n        \"required\": [ \"InstallerReturnCode\", \"ReturnResponse\" ]\n      },\n      \"maxItems\": 128,\n      \"description\": \"Installer exit codes for common errors\"\n    },\n    \"UpgradeBehavior\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"install\",\n        \"uninstallPrevious\",\n        \"deny\"\n      ],\n      \"description\": \"The upgrade method\"\n    },\n    \"Commands\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"maxLength\": 40\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of commands or aliases to run the package\"\n    },\n    \"Protocols\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"maxLength\": 2048\n      },\n      \"maxItems\": 64,\n      \"uniqueItems\": true,\n      \"description\": \"List of protocols the package provides a handler for\"\n    },\n    \"FileExtensions\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n        \"maxLength\": 64\n      },\n      \"maxItems\": 512,\n      \"uniqueItems\": true,\n      \"description\": \"List of file extensions the package could support\"\n    },\n    \"Dependencies\": {\n      \"type\": [ \"object\", \"null\" ],\n      \"properties\": {\n        \"WindowsFeatures\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 128\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of Windows feature dependencies\"\n        },\n        \"WindowsLibraries\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 128\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of Windows library dependencies\"\n        },\n        \"PackageDependencies\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"PackageIdentifier\": {\n                \"$ref\": \"#/definitions/PackageIdentifier\"\n              },\n              \"MinimumVersion\": {\n                \"$ref\": \"#/definitions/PackageVersion\"\n              }\n            },\n            \"required\": [ \"PackageIdentifier\" ]\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of package dependencies from current source\"\n        },\n        \"ExternalDependencies\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 128\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of external package dependencies\"\n        }\n      }\n    },\n    \"PackageFamilyName\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^[A-Za-z0-9][-\\\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$\",\n      \"maxLength\": 255,\n      \"description\": \"PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources\"\n    },\n    \"ProductCode\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 255,\n      \"description\": \"ProductCode could be used for correlation of packages across sources\"\n    },\n    \"Capabilities\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"maxLength\": 40\n      },\n      \"maxItems\": 1000,\n      \"uniqueItems\": true,\n      \"description\": \"List of appx or msix installer capabilities\"\n    },\n    \"RestrictedCapabilities\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"maxLength\": 40\n      },\n      \"maxItems\": 1000,\n      \"uniqueItems\": true,\n      \"description\": \"List of appx or msix installer restricted capabilities\"\n    },\n    \"Market\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[A-Z]{2}$\",\n      \"description\": \"The installer target market\"\n    },\n    \"MarketArray\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"maxItems\": 256,\n      \"items\": {\n        \"$ref\": \"#/definitions/Market\"\n      },\n      \"description\": \"Array of markets\"\n    },\n    \"Markets\": {\n      \"description\": \"The installer markets\",\n      \"type\": [ \"object\", \"null\" ],\n      \"oneOf\": [\n        {\n          \"properties\": {\n            \"AllowedMarkets\": {\n              \"$ref\": \"#/definitions/MarketArray\"\n            }\n          },\n          \"required\": [ \"AllowedMarkets\" ]\n        },\n        {\n          \"properties\": {\n            \"ExcludedMarkets\": {\n              \"$ref\": \"#/definitions/MarketArray\"\n            }\n          },\n          \"required\": [ \"ExcludedMarkets\" ]\n        }\n      ]\n    },\n    \"InstallerAbortsTerminal\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer will abort terminal. Default is false\"\n    },\n    \"ReleaseDate\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"format\": \"date\",\n      \"description\": \"The installer release date\"\n    },\n    \"InstallLocationRequired\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer requires an install location provided\"\n    },\n    \"RequireExplicitUpgrade\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer should be pinned by default from upgrade\"\n    },\n    \"DisplayInstallWarnings\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications.\"\n    },\n    \"UnsupportedOSArchitectures\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"items\": {\n        \"type\": \"string\",\n        \"title\": \"UnsupportedOSArchitecture\",\n        \"enum\": [\n          \"x86\",\n          \"x64\",\n          \"arm\",\n          \"arm64\"\n        ]\n      },\n      \"description\": \"List of OS architectures the installer does not support\"\n    },\n    \"UnsupportedArguments\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"items\": {\n        \"type\": \"string\",\n        \"title\": \"UnsupportedArgument\",\n        \"enum\": [\n          \"log\",\n          \"location\"\n        ]\n      },\n      \"description\": \"List of winget arguments the installer does not support\"\n    },\n    \"AppsAndFeaturesEntry\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"DisplayName\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 256,\n          \"description\": \"The DisplayName registry value\"\n        },\n        \"Publisher\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 256,\n          \"description\": \"The Publisher registry value\"\n        },\n        \"DisplayVersion\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 128,\n          \"description\": \"The DisplayVersion registry value\"\n        },\n        \"ProductCode\": {\n          \"$ref\": \"#/definitions/ProductCode\"\n        },\n        \"UpgradeCode\": {\n          \"$ref\": \"#/definitions/ProductCode\"\n        },\n        \"InstallerType\": {\n          \"$ref\": \"#/definitions/InstallerType\"\n        }\n      },\n      \"description\": \"Various key values under installer's ARP entry\"\n    },\n    \"AppsAndFeaturesEntries\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"maxItems\": 128,\n      \"items\": {\n        \"$ref\": \"#/definitions/AppsAndFeaturesEntry\"\n      },\n      \"description\": \"List of ARP entries.\"\n    },\n    \"ElevationRequirement\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"elevationRequired\",\n        \"elevationProhibited\",\n        \"elevatesSelf\"\n      ],\n      \"description\": \"The installer's elevation requirement\"\n    },\n    \"InstallationMetadata\": {\n      \"type\": \"object\",\n      \"title\": \"InstallationMetadata\",\n      \"properties\": {\n        \"DefaultInstallLocation\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 2048,\n          \"description\": \"Represents the default installed package location. Used for deeper installation detection.\"\n        },\n        \"Files\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"uniqueItems\": true,\n          \"maxItems\": 2048,\n          \"items\": {\n            \"type\": \"object\",\n            \"title\": \"InstalledFile\",\n            \"properties\": {\n              \"RelativeFilePath\": {\n                \"type\": \"string\",\n                \"minLength\": 1,\n                \"maxLength\": 2048,\n                \"description\": \"The relative path to the installed file.\"\n              },\n              \"FileSha256\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n                \"description\": \"Optional Sha256 of the installed file.\"\n              },\n              \"FileType\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"enum\": [\n                  \"launch\",\n                  \"uninstall\",\n                  \"other\"\n                ],\n                \"description\": \"The optional installed file type. If not specified, the file is treated as other.\"\n              },\n              \"InvocationParameter\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"minLength\": 1,\n                \"maxLength\": 2048,\n                \"description\": \"Optional parameter for invocable files.\"\n              },\n              \"DisplayName\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"minLength\": 1,\n                \"maxLength\": 256,\n                \"description\": \"Optional display name for invocable files.\"\n              }\n            },\n            \"required\": [ \"RelativeFilePath\" ],\n            \"description\": \"Represents an installed file.\"\n          },\n          \"description\": \"List of installed files.\"\n        }\n      },\n      \"description\": \"Details about the installation. Used for deeper installation detection.\"\n    },\n    \"DownloadCommandProhibited\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer is prohibited from being downloaded for offline installation.\"\n    },\n    \"RepairBehavior\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"modify\",\n        \"uninstaller\",\n        \"installer\"\n      ],\n      \"description\": \"The repair method\"\n    },\n    \"ArchiveBinariesDependOnPath\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the install location should be added directly to the PATH environment variable. Only applies to an archive containing portable packages.\"\n    },\n    \"Authentication\": {\n      \"type\": [ \"object\", \"null\" ],\n      \"properties\": {\n        \"AuthenticationType\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"none\",\n            \"microsoftEntraId\",\n            \"microsoftEntraIdForAzureBlobStorage\"\n          ],\n          \"description\": \"The authentication type\"\n        },\n        \"MicrosoftEntraIdAuthenticationInfo\": {\n          \"type\": [ \"object\", \"null\" ],\n          \"properties\": {\n            \"Resource\": {\n              \"type\": [ \"string\", \"null\" ],\n              \"minLength\": 1,\n              \"maxLength\": 512,\n              \"description\": \"The resource value for Microsoft Entra Id authentication.\"\n            },\n            \"Scope\": {\n              \"type\": [ \"string\", \"null\" ],\n              \"minLength\": 1,\n              \"maxLength\": 512,\n              \"description\": \"The scope value for Microsoft Entra Id authentication.\"\n            }\n          },\n          \"description\": \"The Microsoft Entra Id authentication info\"\n        }\n      },\n      \"required\": [\n        \"AuthenticationType\"\n      ],\n      \"description\": \"The authentication requirement for downloading the installer.\"\n    },\n    \"Installer\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"InstallerLocale\": {\n          \"$ref\": \"#/definitions/Locale\"\n        },\n        \"Platform\": {\n          \"$ref\": \"#/definitions/Platform\"\n        },\n        \"MinimumOSVersion\": {\n          \"$ref\": \"#/definitions/MinimumOSVersion\"\n        },\n        \"Architecture\": {\n          \"$ref\": \"#/definitions/Architecture\"\n        },\n        \"InstallerType\": {\n          \"$ref\": \"#/definitions/InstallerType\"\n        },\n        \"NestedInstallerType\": {\n          \"$ref\": \"#/definitions/NestedInstallerType\"\n        },\n        \"NestedInstallerFiles\": {\n          \"$ref\": \"#/definitions/NestedInstallerFiles\"\n        },\n        \"Scope\": {\n          \"$ref\": \"#/definitions/Scope\"\n        },\n        \"InstallerUrl\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n          \"maxLength\": 2048,\n          \"description\": \"The installer Url\"\n        },\n        \"InstallerSha256\": {\n          \"type\": \"string\",\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"Sha256 is required. Sha256 of the installer\"\n        },\n        \"SignatureSha256\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable\"\n        },\n        \"InstallModes\": {\n          \"$ref\": \"#/definitions/InstallModes\"\n        },\n        \"InstallerSwitches\": {\n          \"$ref\": \"#/definitions/InstallerSwitches\"\n        },\n        \"InstallerSuccessCodes\": {\n          \"$ref\": \"#/definitions/InstallerSuccessCodes\"\n        },\n        \"ExpectedReturnCodes\": {\n          \"$ref\": \"#/definitions/ExpectedReturnCodes\"\n        },\n        \"UpgradeBehavior\": {\n          \"$ref\": \"#/definitions/UpgradeBehavior\"\n        },\n        \"Commands\": {\n          \"$ref\": \"#/definitions/Commands\"\n        },\n        \"Protocols\": {\n          \"$ref\": \"#/definitions/Protocols\"\n        },\n        \"FileExtensions\": {\n          \"$ref\": \"#/definitions/FileExtensions\"\n        },\n        \"Dependencies\": {\n          \"$ref\": \"#/definitions/Dependencies\"\n        },\n        \"PackageFamilyName\": {\n          \"$ref\": \"#/definitions/PackageFamilyName\"\n        },\n        \"ProductCode\": {\n          \"$ref\": \"#/definitions/ProductCode\"\n        },\n        \"Capabilities\": {\n          \"$ref\": \"#/definitions/Capabilities\"\n        },\n        \"RestrictedCapabilities\": {\n          \"$ref\": \"#/definitions/RestrictedCapabilities\"\n        },\n        \"Markets\": {\n          \"$ref\": \"#/definitions/Markets\"\n        },\n        \"InstallerAbortsTerminal\": {\n          \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\n        },\n        \"ReleaseDate\": {\n          \"$ref\": \"#/definitions/ReleaseDate\"\n        },\n        \"InstallLocationRequired\": {\n          \"$ref\": \"#/definitions/InstallLocationRequired\"\n        },\n        \"RequireExplicitUpgrade\": {\n          \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\n        },\n        \"DisplayInstallWarnings\": {\n          \"$ref\": \"#/definitions/DisplayInstallWarnings\"\n        },\n        \"UnsupportedOSArchitectures\": {\n          \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\n        },\n        \"UnsupportedArguments\": {\n          \"$ref\": \"#/definitions/UnsupportedArguments\"\n        },\n        \"AppsAndFeaturesEntries\": {\n          \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\n        },\n        \"ElevationRequirement\": {\n          \"$ref\": \"#/definitions/ElevationRequirement\"\n        },\n        \"InstallationMetadata\": {\n          \"$ref\": \"#/definitions/InstallationMetadata\"\n        },\n        \"DownloadCommandProhibited\": {\n          \"$ref\": \"#/definitions/DownloadCommandProhibited\"\n        },\n        \"RepairBehavior\": {\n          \"$ref\": \"#/definitions/RepairBehavior\"\n        },\n        \"ArchiveBinariesDependOnPath\": {\n          \"$ref\": \"#/definitions/ArchiveBinariesDependOnPath\"\n        },\n        \"Authentication\": {\n          \"$ref\": \"#/definitions/Authentication\"\n        }\n      },\n      \"required\": [\n        \"Architecture\",\n        \"InstallerUrl\",\n        \"InstallerSha256\"\n      ]\n    }\n  },\n  \"type\": \"object\",\n  \"properties\": {\n    \"PackageIdentifier\": {\n      \"$ref\": \"#/definitions/PackageIdentifier\"\n    },\n    \"PackageVersion\": {\n      \"$ref\": \"#/definitions/PackageVersion\"\n    },\n    \"Channel\": {\n      \"$ref\": \"#/definitions/Channel\"\n    },\n    \"InstallerLocale\": {\n      \"$ref\": \"#/definitions/Locale\"\n    },\n    \"Platform\": {\n      \"$ref\": \"#/definitions/Platform\"\n    },\n    \"MinimumOSVersion\": {\n      \"$ref\": \"#/definitions/MinimumOSVersion\"\n    },\n    \"InstallerType\": {\n      \"$ref\": \"#/definitions/InstallerType\"\n    },\n    \"NestedInstallerType\": {\n      \"$ref\": \"#/definitions/NestedInstallerType\"\n    },\n    \"NestedInstallerFiles\": {\n      \"$ref\": \"#/definitions/NestedInstallerFiles\"\n    },\n    \"Scope\": {\n      \"$ref\": \"#/definitions/Scope\"\n    },\n    \"InstallModes\": {\n      \"$ref\": \"#/definitions/InstallModes\"\n    },\n    \"InstallerSwitches\": {\n      \"$ref\": \"#/definitions/InstallerSwitches\"\n    },\n    \"InstallerSuccessCodes\": {\n      \"$ref\": \"#/definitions/InstallerSuccessCodes\"\n    },\n    \"ExpectedReturnCodes\": {\n      \"$ref\": \"#/definitions/ExpectedReturnCodes\"\n    },\n    \"UpgradeBehavior\": {\n      \"$ref\": \"#/definitions/UpgradeBehavior\"\n    },\n    \"Commands\": {\n      \"$ref\": \"#/definitions/Commands\"\n    },\n    \"Protocols\": {\n      \"$ref\": \"#/definitions/Protocols\"\n    },\n    \"FileExtensions\": {\n      \"$ref\": \"#/definitions/FileExtensions\"\n    },\n    \"Dependencies\": {\n      \"$ref\": \"#/definitions/Dependencies\"\n    },\n    \"PackageFamilyName\": {\n      \"$ref\": \"#/definitions/PackageFamilyName\"\n    },\n    \"ProductCode\": {\n      \"$ref\": \"#/definitions/ProductCode\"\n    },\n    \"Capabilities\": {\n      \"$ref\": \"#/definitions/Capabilities\"\n    },\n    \"RestrictedCapabilities\": {\n      \"$ref\": \"#/definitions/RestrictedCapabilities\"\n    },\n    \"Markets\": {\n      \"$ref\": \"#/definitions/Markets\"\n    },\n    \"InstallerAbortsTerminal\": {\n      \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\n    },\n    \"ReleaseDate\": {\n      \"$ref\": \"#/definitions/ReleaseDate\"\n    },\n    \"InstallLocationRequired\": {\n      \"$ref\": \"#/definitions/InstallLocationRequired\"\n    },\n    \"RequireExplicitUpgrade\": {\n      \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\n    },\n    \"DisplayInstallWarnings\": {\n      \"$ref\": \"#/definitions/DisplayInstallWarnings\"\n    },\n    \"UnsupportedOSArchitectures\": {\n      \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\n    },\n    \"UnsupportedArguments\": {\n      \"$ref\": \"#/definitions/UnsupportedArguments\"\n    },\n    \"AppsAndFeaturesEntries\": {\n      \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\n    },\n    \"ElevationRequirement\": {\n      \"$ref\": \"#/definitions/ElevationRequirement\"\n    },\n    \"InstallationMetadata\": {\n      \"$ref\": \"#/definitions/InstallationMetadata\"\n    },\n    \"DownloadCommandProhibited\": {\n      \"$ref\": \"#/definitions/DownloadCommandProhibited\"\n    },\n    \"RepairBehavior\": {\n      \"$ref\": \"#/definitions/RepairBehavior\"\n    },\n    \"ArchiveBinariesDependOnPath\": {\n      \"$ref\": \"#/definitions/ArchiveBinariesDependOnPath\"\n    },\n    \"Authentication\": {\n      \"$ref\": \"#/definitions/Authentication\"\n    },\n    \"Installers\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/Installer\"\n      },\n      \"minItems\": 1,\n      \"maxItems\": 1024\n    },\n    \"ManifestType\": {\n      \"type\": \"string\",\n      \"default\": \"installer\",\n      \"const\": \"installer\",\n      \"description\": \"The manifest type\"\n    },\n    \"ManifestVersion\": {\n      \"type\": \"string\",\n      \"default\": \"1.12.0\",\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\n      \"description\": \"The manifest syntax version\"\n    }\n  },\n  \"required\": [\n    \"PackageIdentifier\",\n    \"PackageVersion\",\n    \"Installers\",\n    \"ManifestType\",\n    \"ManifestVersion\"\n  ]\n}\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.12.0/manifest.locale.1.12.0.json",
    "content": "{\n  \"$id\": \"https://aka.ms/winget-manifest.locale.1.12.0.schema.json\",\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"description\": \"A representation of a multiple-file manifest representing app metadata in other locale in the OWC. v1.12.0\",\n  \"definitions\": {\n    \"Url\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n      \"maxLength\": 2048,\n      \"description\": \"Optional Url type\"\n    },\n    \"Tag\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 40,\n      \"description\": \"Package tag\"\n    },\n    \"Agreement\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"AgreementLabel\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 100,\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\n        },\n        \"Agreement\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 10000,\n          \"description\": \"The agreement text content.\"\n        },\n        \"AgreementUrl\": {\n          \"$ref\": \"#/definitions/Url\",\n          \"description\": \"The agreement URL.\"\n        }\n      }\n    },\n    \"Documentation\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"DocumentLabel\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 100,\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\n        },\n        \"DocumentUrl\": {\n          \"$ref\": \"#/definitions/Url\",\n          \"description\": \"The documentation URL.\"\n        }\n      }\n    },\n    \"Icon\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"IconUrl\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n          \"maxLength\": 2048,\n          \"description\": \"The url of the hosted icon file\"\n        },\n        \"IconFileType\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"png\",\n            \"jpeg\",\n            \"ico\"\n          ],\n          \"description\": \"The icon file type\"\n        },\n        \"IconResolution\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"enum\": [\n            \"custom\",\n            \"16x16\",\n            \"20x20\",\n            \"24x24\",\n            \"30x30\",\n            \"32x32\",\n            \"36x36\",\n            \"40x40\",\n            \"48x48\",\n            \"60x60\",\n            \"64x64\",\n            \"72x72\",\n            \"80x80\",\n            \"96x96\",\n            \"256x256\"\n          ],\n          \"description\": \"Optional icon resolution\"\n        },\n        \"IconTheme\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"enum\": [\n            \"default\",\n            \"light\",\n            \"dark\",\n            \"highContrast\"\n          ],\n          \"description\": \"Optional icon theme\"\n        },\n        \"IconSha256\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"Optional Sha256 of the icon file\"\n        }\n      },\n      \"required\": [\n        \"IconUrl\",\n        \"IconFileType\"\n      ]\n    }\n  },\n  \"type\": \"object\",\n  \"properties\": {\n    \"PackageIdentifier\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\n      \"maxLength\": 128,\n      \"description\": \"The package unique identifier\"\n    },\n    \"PackageVersion\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n      \"maxLength\": 128,\n      \"description\": \"The package version\"\n    },\n    \"PackageLocale\": {\n      \"type\": \"string\",\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\n      \"maxLength\": 20,\n      \"description\": \"The package meta-data locale\"\n    },\n    \"Publisher\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The publisher name\"\n    },\n    \"PublisherUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher home page\"\n    },\n    \"PublisherSupportUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher support page\"\n    },\n    \"PrivacyUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher privacy page or the package privacy page\"\n    },\n    \"Author\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The package author\"\n    },\n    \"PackageName\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The package name\"\n    },\n    \"PackageUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package home page\"\n    },\n    \"License\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 512,\n      \"description\": \"The package license\"\n    },\n    \"LicenseUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The license page\"\n    },\n    \"Copyright\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 512,\n      \"description\": \"The package copyright\"\n    },\n    \"CopyrightUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package copyright page\"\n    },\n    \"ShortDescription\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 256,\n      \"description\": \"The short package description\"\n    },\n    \"Description\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 10000,\n      \"description\": \"The full package description\"\n    },\n    \"Tags\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Tag\"\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of additional package search terms\"\n    },\n    \"Agreements\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Agreement\"\n      },\n      \"maxItems\": 128\n    },\n    \"ReleaseNotes\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 10000,\n      \"description\": \"The package release notes\"\n    },\n    \"ReleaseNotesUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package release notes url\"\n    },\n    \"PurchaseUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\n    },\n    \"InstallationNotes\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 10000,\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"\n    },\n    \"Documentations\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Documentation\"\n      },\n      \"maxItems\": 256\n    },\n    \"Icons\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Icon\"\n      },\n      \"maxItems\": 1024\n    },\n    \"ManifestType\": {\n      \"type\": \"string\",\n      \"default\": \"locale\",\n      \"const\": \"locale\",\n      \"description\": \"The manifest type\"\n    },\n    \"ManifestVersion\": {\n      \"type\": \"string\",\n      \"default\": \"1.12.0\",\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\n      \"description\": \"The manifest syntax version\"\n    }\n  },\n  \"required\": [\n    \"PackageIdentifier\",\n    \"PackageVersion\",\n    \"PackageLocale\",\n    \"ManifestType\",\n    \"ManifestVersion\"\n  ]\n}\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.12.0/manifest.singleton.1.12.0.json",
    "content": "{\n  \"$id\": \"https://aka.ms/winget-manifest.singleton.1.12.0.schema.json\",\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"description\": \"A representation of a single-file manifest representing an app in the OWC. v1.12.0\",\n  \"definitions\": {\n    \"PackageIdentifier\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\n      \"maxLength\": 128,\n      \"description\": \"The package unique identifier\"\n    },\n    \"PackageVersion\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n      \"maxLength\": 128,\n      \"description\": \"The package version\"\n    },\n    \"Locale\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\n      \"maxLength\": 20,\n      \"description\": \"The package meta-data locale\"\n    },\n    \"Url\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n      \"maxLength\": 2048,\n      \"description\": \"Optional Url type\"\n    },\n    \"Tag\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 40,\n      \"description\": \"Package moniker or tag\"\n    },\n    \"Agreement\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"AgreementLabel\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 100,\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\n        },\n        \"Agreement\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 10000,\n          \"description\": \"The agreement text content.\"\n        },\n        \"AgreementUrl\": {\n          \"$ref\": \"#/definitions/Url\",\n          \"description\": \"The agreement URL.\"\n        }\n      }\n    },\n    \"Documentation\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"DocumentLabel\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 100,\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\n        },\n        \"DocumentUrl\": {\n          \"$ref\": \"#/definitions/Url\",\n          \"description\": \"The documentation URL.\"\n        }\n      }\n    },\n    \"Icon\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"IconUrl\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n          \"maxLength\": 2048,\n          \"description\": \"The url of the hosted icon file\"\n        },\n        \"IconFileType\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"png\",\n            \"jpeg\",\n            \"ico\"\n          ],\n          \"description\": \"The icon file type\"\n        },\n        \"IconResolution\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"enum\": [\n            \"custom\",\n            \"16x16\",\n            \"20x20\",\n            \"24x24\",\n            \"30x30\",\n            \"32x32\",\n            \"36x36\",\n            \"40x40\",\n            \"48x48\",\n            \"60x60\",\n            \"64x64\",\n            \"72x72\",\n            \"80x80\",\n            \"96x96\",\n            \"256x256\"\n          ],\n          \"description\": \"Optional icon resolution\"\n        },\n        \"IconTheme\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"enum\": [\n            \"default\",\n            \"light\",\n            \"dark\",\n            \"highContrast\"\n          ],\n          \"description\": \"Optional icon theme\"\n        },\n        \"IconSha256\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"Optional Sha256 of the icon file\"\n        }\n      },\n      \"required\": [\n        \"IconUrl\",\n        \"IconFileType\"\n      ]\n    },\n    \"Channel\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 16,\n      \"description\": \"The distribution channel\"\n    },\n    \"Platform\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"title\": \"Platform\",\n        \"type\": \"string\",\n        \"enum\": [\n          \"Windows.Desktop\",\n          \"Windows.Universal\"\n        ]\n      },\n      \"maxItems\": 2,\n      \"uniqueItems\": true,\n      \"description\": \"The installer supported operating system\"\n    },\n    \"MinimumOSVersion\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$\",\n      \"description\": \"The installer minimum operating system version\"\n    },\n    \"InstallerType\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"msix\",\n        \"msi\",\n        \"appx\",\n        \"exe\",\n        \"zip\",\n        \"inno\",\n        \"nullsoft\",\n        \"wix\",\n        \"burn\",\n        \"pwa\",\n        \"portable\",\n        \"font\"\n      ],\n      \"description\": \"Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level\"\n    },\n    \"NestedInstallerType\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"msix\",\n        \"msi\",\n        \"appx\",\n        \"exe\",\n        \"inno\",\n        \"nullsoft\",\n        \"wix\",\n        \"burn\",\n        \"portable\",\n        \"font\"\n      ],\n      \"description\": \"Enumeration of supported nested installer types contained inside an archive file\"\n    },\n    \"NestedInstallerFiles\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"object\",\n        \"title\": \"NestedInstallerFile\",\n        \"properties\": {\n          \"RelativeFilePath\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 512,\n            \"description\": \"The relative path to the nested installer file\"\n          },\n          \"PortableCommandAlias\": {\n            \"type\": [ \"string\", \"null\" ],\n            \"minLength\": 1,\n            \"maxLength\": 40,\n            \"description\": \"The command alias to be used for calling the package. Only applies to the nested portable package\"\n          }\n        },\n        \"required\": [ \"RelativeFilePath\" ],\n        \"description\": \"A nested installer file contained inside an archive\"\n      },\n      \"maxItems\": 1024,\n      \"description\": \"List of nested installer files contained inside an archive\"\n    },\n    \"Architecture\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"x86\",\n        \"x64\",\n        \"arm\",\n        \"arm64\",\n        \"neutral\"\n      ],\n      \"description\": \"The installer target architecture\"\n    },\n    \"Scope\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"user\",\n        \"machine\"\n      ],\n      \"description\": \"Scope indicates if the installer is per user or per machine\"\n    },\n    \"InstallModes\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"title\": \"InstallModes\",\n        \"type\": \"string\",\n        \"enum\": [\n          \"interactive\",\n          \"silent\",\n          \"silentWithProgress\"\n        ]\n      },\n      \"maxItems\": 3,\n      \"uniqueItems\": true,\n      \"description\": \"List of supported installer modes\"\n    },\n    \"InstallerSwitches\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"Silent\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Silent is the value that should be passed to the installer when user chooses a silent or quiet install\"\n        },\n        \"SilentWithProgress\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install\"\n        },\n        \"Interactive\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Interactive is the value that should be passed to the installer when user chooses an interactive install\"\n        },\n        \"InstallLocation\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"InstallLocation is the value passed to the installer for custom install location. <INSTALLPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\n        },\n        \"Log\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Log is the value passed to the installer for custom log file path. <LOGPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\n        },\n        \"Upgrade\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Upgrade is the value that should be passed to the installer when user chooses an upgrade\"\n        },\n        \"Custom\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 2048,\n          \"description\": \"Custom switches will be passed directly to the installer by winget\"\n        },\n        \"Repair\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"The 'Repair' value must be passed to the installer, ModifyPath ARP command, or uninstaller ARP command when the user opts for a repair\"\n        }\n      }\n    },\n    \"InstallerReturnCode\": {\n      \"type\": \"integer\",\n      \"format\": \"long\",\n      \"not\": {\n        \"enum\": [ 0 ]\n      },\n      \"minimum\": -2147483648,\n      \"maximum\": 4294967295,\n      \"description\": \"An exit code that can be returned by the installer after execution\"\n    },\n    \"InstallerSuccessCodes\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/InstallerReturnCode\"\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of additional non-zero installer success exit codes other than known default values by winget\"\n    },\n    \"ExpectedReturnCodes\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"object\",\n        \"title\": \"ExpectedReturnCode\",\n        \"properties\": {\n          \"InstallerReturnCode\": {\n            \"$ref\": \"#/definitions/InstallerReturnCode\"\n          },\n          \"ReturnResponse\": {\n            \"type\": \"string\",\n            \"enum\": [\n              \"packageInUse\",\n              \"packageInUseByApplication\",\n              \"installInProgress\",\n              \"fileInUse\",\n              \"missingDependency\",\n              \"diskFull\",\n              \"insufficientMemory\",\n              \"invalidParameter\",\n              \"noNetwork\",\n              \"contactSupport\",\n              \"rebootRequiredToFinish\",\n              \"rebootRequiredForInstall\",\n              \"rebootInitiated\",\n              \"cancelledByUser\",\n              \"alreadyInstalled\",\n              \"downgrade\",\n              \"blockedByPolicy\",\n              \"systemNotSupported\",\n              \"custom\"\n            ]\n          },\n          \"ReturnResponseUrl\": {\n            \"$ref\": \"#/definitions/Url\",\n            \"description\": \"The return response url to provide additional guidance for expected return codes\"\n          }\n        },\n        \"required\": [ \"InstallerReturnCode\", \"ReturnResponse\" ]\n      },\n      \"maxItems\": 128,\n      \"description\": \"Installer exit codes for common errors\"\n    },\n    \"UpgradeBehavior\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"install\",\n        \"uninstallPrevious\",\n        \"deny\"\n      ],\n      \"description\": \"The upgrade method\"\n    },\n    \"Commands\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"maxLength\": 40\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of commands or aliases to run the package\"\n    },\n    \"Protocols\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"maxLength\": 2048\n      },\n      \"maxItems\": 64,\n      \"uniqueItems\": true,\n      \"description\": \"List of protocols the package provides a handler for\"\n    },\n    \"FileExtensions\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n        \"maxLength\": 64\n      },\n      \"maxItems\": 512,\n      \"uniqueItems\": true,\n      \"description\": \"List of file extensions the package could support\"\n    },\n    \"Dependencies\": {\n      \"type\": [ \"object\", \"null\" ],\n      \"properties\": {\n        \"WindowsFeatures\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 128\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of Windows feature dependencies\"\n        },\n        \"WindowsLibraries\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 128\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of Windows library dependencies\"\n        },\n        \"PackageDependencies\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"PackageIdentifier\": {\n                \"$ref\": \"#/definitions/PackageIdentifier\"\n              },\n              \"MinimumVersion\": {\n                \"$ref\": \"#/definitions/PackageVersion\"\n              }\n            },\n            \"required\": [ \"PackageIdentifier\" ]\n          },\n          \"maxItems\": 16,\n          \"description\": \"List of package dependencies from current source\"\n        },\n        \"ExternalDependencies\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 128\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of external package dependencies\"\n        }\n      }\n    },\n    \"PackageFamilyName\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^[A-Za-z0-9][-\\\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$\",\n      \"maxLength\": 255,\n      \"description\": \"PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources\"\n    },\n    \"ProductCode\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 255,\n      \"description\": \"ProductCode could be used for correlation of packages across sources\"\n    },\n    \"Capabilities\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"maxLength\": 40\n      },\n      \"maxItems\": 1000,\n      \"uniqueItems\": true,\n      \"description\": \"List of appx or msix installer capabilities\"\n    },\n    \"RestrictedCapabilities\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"maxLength\": 40\n      },\n      \"maxItems\": 1000,\n      \"uniqueItems\": true,\n      \"description\": \"List of appx or msix installer restricted capabilities\"\n    },\n    \"Market\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[A-Z]{2}$\",\n      \"description\": \"The installer target market\"\n    },\n    \"MarketArray\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"maxItems\": 256,\n      \"items\": {\n        \"$ref\": \"#/definitions/Market\"\n      },\n      \"description\": \"Array of markets\"\n    },\n    \"Markets\": {\n      \"description\": \"The installer markets\",\n      \"type\": [ \"object\", \"null\" ],\n      \"oneOf\": [\n        {\n          \"properties\": {\n            \"AllowedMarkets\": {\n              \"$ref\": \"#/definitions/MarketArray\"\n            }\n          },\n          \"required\": [ \"AllowedMarkets\" ]\n        },\n        {\n          \"properties\": {\n            \"ExcludedMarkets\": {\n              \"$ref\": \"#/definitions/MarketArray\"\n            }\n          },\n          \"required\": [ \"ExcludedMarkets\" ]\n        }\n      ]\n    },\n    \"InstallerAbortsTerminal\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer will abort terminal. Default is false\"\n    },\n    \"ReleaseDate\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"format\": \"date\",\n      \"description\": \"The installer release date\"\n    },\n    \"InstallLocationRequired\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer requires an install location provided\"\n    },\n    \"RequireExplicitUpgrade\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer should be pinned by default from upgrade\"\n    },\n    \"DisplayInstallWarnings\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications.\"\n    },\n    \"UnsupportedOSArchitectures\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"items\": {\n        \"type\": \"string\",\n        \"title\": \"UnsupportedOSArchitecture\",\n        \"enum\": [\n          \"x86\",\n          \"x64\",\n          \"arm\",\n          \"arm64\"\n        ]\n      },\n      \"description\": \"List of OS architectures the installer does not support\"\n    },\n    \"UnsupportedArguments\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"items\": {\n        \"type\": \"string\",\n        \"title\": \"UnsupportedArgument\",\n        \"enum\": [\n          \"log\",\n          \"location\"\n        ]\n      },\n      \"description\": \"List of winget arguments the installer does not support\"\n    },\n    \"AppsAndFeaturesEntry\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"DisplayName\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 256,\n          \"description\": \"The DisplayName registry value\"\n        },\n        \"Publisher\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 256,\n          \"description\": \"The Publisher registry value\"\n        },\n        \"DisplayVersion\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 128,\n          \"description\": \"The DisplayVersion registry value\"\n        },\n        \"ProductCode\": {\n          \"$ref\": \"#/definitions/ProductCode\"\n        },\n        \"UpgradeCode\": {\n          \"$ref\": \"#/definitions/ProductCode\"\n        },\n        \"InstallerType\": {\n          \"$ref\": \"#/definitions/InstallerType\"\n        }\n      },\n      \"description\": \"Various key values under installer's ARP entry\"\n    },\n    \"AppsAndFeaturesEntries\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"maxItems\": 128,\n      \"items\": {\n        \"$ref\": \"#/definitions/AppsAndFeaturesEntry\"\n      },\n      \"description\": \"List of ARP entries.\"\n    },\n    \"ElevationRequirement\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"elevationRequired\",\n        \"elevationProhibited\",\n        \"elevatesSelf\"\n      ],\n      \"description\": \"The installer's elevation requirement\"\n    },\n    \"InstallationMetadata\": {\n      \"type\": \"object\",\n      \"title\": \"InstallationMetadata\",\n      \"properties\": {\n        \"DefaultInstallLocation\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 2048,\n          \"description\": \"Represents the default installed package location. Used for deeper installation detection.\"\n        },\n        \"Files\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"uniqueItems\": true,\n          \"maxItems\": 2048,\n          \"items\": {\n            \"type\": \"object\",\n            \"title\": \"InstalledFile\",\n            \"properties\": {\n              \"RelativeFilePath\": {\n                \"type\": \"string\",\n                \"minLength\": 1,\n                \"maxLength\": 2048,\n                \"description\": \"The relative path to the installed file.\"\n              },\n              \"FileSha256\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n                \"description\": \"Optional Sha256 of the installed file.\"\n              },\n              \"FileType\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"enum\": [\n                  \"launch\",\n                  \"uninstall\",\n                  \"other\"\n                ],\n                \"description\": \"The optional installed file type. If not specified, the file is treated as other.\"\n              },\n              \"InvocationParameter\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"minLength\": 1,\n                \"maxLength\": 2048,\n                \"description\": \"Optional parameter for invocable files.\"\n              },\n              \"DisplayName\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"minLength\": 1,\n                \"maxLength\": 256,\n                \"description\": \"Optional display name for invocable files.\"\n              }\n            },\n            \"required\": [ \"RelativeFilePath\" ],\n            \"description\": \"Represents an installed file.\"\n          },\n          \"description\": \"List of installed files.\"\n        }\n      },\n      \"description\": \"Details about the installation. Used for deeper installation detection.\"\n    },\n    \"DownloadCommandProhibited\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer is prohibited from being downloaded for offline installation.\"\n    },\n    \"RepairBehavior\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"modify\",\n        \"uninstaller\",\n        \"installer\"\n      ],\n      \"description\": \"The repair method\"\n    },\n    \"ArchiveBinariesDependOnPath\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the install location should be added directly to the PATH environment variable. Only applies to an archive containing portable packages.\"\n    },\n    \"Authentication\": {\n      \"type\": [ \"object\", \"null\" ],\n      \"properties\": {\n        \"AuthenticationType\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"none\",\n            \"microsoftEntraId\",\n            \"microsoftEntraIdForAzureBlobStorage\"\n          ],\n          \"description\": \"The authentication type\"\n        },\n        \"MicrosoftEntraIdAuthenticationInfo\": {\n          \"type\": [ \"object\", \"null\" ],\n          \"properties\": {\n            \"Resource\": {\n              \"type\": [ \"string\", \"null\" ],\n              \"minLength\": 1,\n              \"maxLength\": 512,\n              \"description\": \"The resource value for Microsoft Entra Id authentication.\"\n            },\n            \"Scope\": {\n              \"type\": [ \"string\", \"null\" ],\n              \"minLength\": 1,\n              \"maxLength\": 512,\n              \"description\": \"The scope value for Microsoft Entra Id authentication.\"\n            }\n          },\n          \"description\": \"The Microsoft Entra Id authentication info\"\n        }\n      },\n      \"required\": [\n        \"AuthenticationType\"\n      ],\n      \"description\": \"The authentication requirement for downloading the installer.\"\n    },\n    \"Installer\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"InstallerLocale\": {\n          \"$ref\": \"#/definitions/Locale\"\n        },\n        \"Platform\": {\n          \"$ref\": \"#/definitions/Platform\"\n        },\n        \"MinimumOSVersion\": {\n          \"$ref\": \"#/definitions/MinimumOSVersion\"\n        },\n        \"Architecture\": {\n          \"$ref\": \"#/definitions/Architecture\"\n        },\n        \"InstallerType\": {\n          \"$ref\": \"#/definitions/InstallerType\"\n        },\n        \"NestedInstallerType\": {\n          \"$ref\": \"#/definitions/NestedInstallerType\"\n        },\n        \"NestedInstallerFiles\": {\n          \"$ref\": \"#/definitions/NestedInstallerFiles\"\n        },\n        \"Scope\": {\n          \"$ref\": \"#/definitions/Scope\"\n        },\n        \"InstallerUrl\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n          \"maxLength\": 2048,\n          \"description\": \"The installer Url\"\n        },\n        \"InstallerSha256\": {\n          \"type\": \"string\",\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"Sha256 is required. Sha256 of the installer\"\n        },\n        \"SignatureSha256\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable\"\n        },\n        \"InstallModes\": {\n          \"$ref\": \"#/definitions/InstallModes\"\n        },\n        \"InstallerSwitches\": {\n          \"$ref\": \"#/definitions/InstallerSwitches\"\n        },\n        \"InstallerSuccessCodes\": {\n          \"$ref\": \"#/definitions/InstallerSuccessCodes\"\n        },\n        \"ExpectedReturnCodes\": {\n          \"$ref\": \"#/definitions/ExpectedReturnCodes\"\n        },\n        \"UpgradeBehavior\": {\n          \"$ref\": \"#/definitions/UpgradeBehavior\"\n        },\n        \"Commands\": {\n          \"$ref\": \"#/definitions/Commands\"\n        },\n        \"Protocols\": {\n          \"$ref\": \"#/definitions/Protocols\"\n        },\n        \"FileExtensions\": {\n          \"$ref\": \"#/definitions/FileExtensions\"\n        },\n        \"Dependencies\": {\n          \"$ref\": \"#/definitions/Dependencies\"\n        },\n        \"PackageFamilyName\": {\n          \"$ref\": \"#/definitions/PackageFamilyName\"\n        },\n        \"ProductCode\": {\n          \"$ref\": \"#/definitions/ProductCode\"\n        },\n        \"Capabilities\": {\n          \"$ref\": \"#/definitions/Capabilities\"\n        },\n        \"RestrictedCapabilities\": {\n          \"$ref\": \"#/definitions/RestrictedCapabilities\"\n        },\n        \"Markets\": {\n          \"$ref\": \"#/definitions/Markets\"\n        },\n        \"InstallerAbortsTerminal\": {\n          \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\n        },\n        \"ReleaseDate\": {\n          \"$ref\": \"#/definitions/ReleaseDate\"\n        },\n        \"InstallLocationRequired\": {\n          \"$ref\": \"#/definitions/InstallLocationRequired\"\n        },\n        \"RequireExplicitUpgrade\": {\n          \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\n        },\n        \"DisplayInstallWarnings\": {\n          \"$ref\": \"#/definitions/DisplayInstallWarnings\"\n        },\n        \"UnsupportedOSArchitectures\": {\n          \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\n        },\n        \"UnsupportedArguments\": {\n          \"$ref\": \"#/definitions/UnsupportedArguments\"\n        },\n        \"AppsAndFeaturesEntries\": {\n          \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\n        },\n        \"ElevationRequirement\": {\n          \"$ref\": \"#/definitions/ElevationRequirement\"\n        },\n        \"InstallationMetadata\": {\n          \"$ref\": \"#/definitions/InstallationMetadata\"\n        },\n        \"DownloadCommandProhibited\": {\n          \"$ref\": \"#/definitions/DownloadCommandProhibited\"\n        },\n        \"RepairBehavior\": {\n          \"$ref\": \"#/definitions/RepairBehavior\"\n        },\n        \"ArchiveBinariesDependOnPath\": {\n          \"$ref\": \"#/definitions/ArchiveBinariesDependOnPath\"\n        },\n        \"Authentication\": {\n          \"$ref\": \"#/definitions/Authentication\"\n        }\n      },\n      \"required\": [\n        \"Architecture\",\n        \"InstallerUrl\",\n        \"InstallerSha256\"\n      ]\n    }\n  },\n  \"type\": \"object\",\n  \"properties\": {\n    \"PackageIdentifier\": {\n      \"$ref\": \"#/definitions/PackageIdentifier\"\n    },\n    \"PackageVersion\": {\n      \"$ref\": \"#/definitions/PackageVersion\"\n    },\n    \"PackageLocale\": {\n      \"$ref\": \"#/definitions/Locale\"\n    },\n    \"Publisher\": {\n      \"type\": \"string\",\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The publisher name\"\n    },\n    \"PublisherUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher home page\"\n    },\n    \"PublisherSupportUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher support page\"\n    },\n    \"PrivacyUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher privacy page or the package privacy page\"\n    },\n    \"Author\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The package author\"\n    },\n    \"PackageName\": {\n      \"type\": \"string\",\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The package name\"\n    },\n    \"PackageUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package home page\"\n    },\n    \"License\": {\n      \"type\": \"string\",\n      \"minLength\": 3,\n      \"maxLength\": 512,\n      \"description\": \"The package license\"\n    },\n    \"LicenseUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The license page\"\n    },\n    \"Copyright\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 512,\n      \"description\": \"The package copyright\"\n    },\n    \"CopyrightUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package copyright page\"\n    },\n    \"ShortDescription\": {\n      \"type\": \"string\",\n      \"minLength\": 3,\n      \"maxLength\": 256,\n      \"description\": \"The short package description\"\n    },\n    \"Description\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 10000,\n      \"description\": \"The full package description\"\n    },\n    \"Moniker\": {\n      \"$ref\": \"#/definitions/Tag\",\n      \"description\": \"The most common package term\"\n    },\n    \"Tags\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Tag\"\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of additional package search terms\"\n    },\n    \"Agreements\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Agreement\"\n      },\n      \"maxItems\": 128\n    },\n    \"ReleaseNotes\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 10000,\n      \"description\": \"The package release notes\"\n    },\n    \"ReleaseNotesUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package release notes url\"\n    },\n    \"PurchaseUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\n    },\n    \"InstallationNotes\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 10000,\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"\n    },\n    \"Documentations\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Documentation\"\n      },\n      \"maxItems\": 256\n    },\n    \"Icons\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Icon\"\n      },\n      \"maxItems\": 1024\n    },\n    \"Channel\": {\n      \"$ref\": \"#/definitions/Channel\"\n    },\n    \"InstallerLocale\": {\n      \"$ref\": \"#/definitions/Locale\"\n    },\n    \"Platform\": {\n      \"$ref\": \"#/definitions/Platform\"\n    },\n    \"MinimumOSVersion\": {\n      \"$ref\": \"#/definitions/MinimumOSVersion\"\n    },\n    \"InstallerType\": {\n      \"$ref\": \"#/definitions/InstallerType\"\n    },\n    \"NestedInstallerType\": {\n      \"$ref\": \"#/definitions/NestedInstallerType\"\n    },\n    \"NestedInstallerFiles\": {\n      \"$ref\": \"#/definitions/NestedInstallerFiles\"\n    },\n    \"Scope\": {\n      \"$ref\": \"#/definitions/Scope\"\n    },\n    \"InstallModes\": {\n      \"$ref\": \"#/definitions/InstallModes\"\n    },\n    \"InstallerSwitches\": {\n      \"$ref\": \"#/definitions/InstallerSwitches\"\n    },\n    \"InstallerSuccessCodes\": {\n      \"$ref\": \"#/definitions/InstallerSuccessCodes\"\n    },\n    \"ExpectedReturnCodes\": {\n      \"$ref\": \"#/definitions/ExpectedReturnCodes\"\n    },\n    \"UpgradeBehavior\": {\n      \"$ref\": \"#/definitions/UpgradeBehavior\"\n    },\n    \"Commands\": {\n      \"$ref\": \"#/definitions/Commands\"\n    },\n    \"Protocols\": {\n      \"$ref\": \"#/definitions/Protocols\"\n    },\n    \"FileExtensions\": {\n      \"$ref\": \"#/definitions/FileExtensions\"\n    },\n    \"Dependencies\": {\n      \"$ref\": \"#/definitions/Dependencies\"\n    },\n    \"PackageFamilyName\": {\n      \"$ref\": \"#/definitions/PackageFamilyName\"\n    },\n    \"ProductCode\": {\n      \"$ref\": \"#/definitions/ProductCode\"\n    },\n    \"Capabilities\": {\n      \"$ref\": \"#/definitions/Capabilities\"\n    },\n    \"RestrictedCapabilities\": {\n      \"$ref\": \"#/definitions/RestrictedCapabilities\"\n    },\n    \"Markets\": {\n      \"$ref\": \"#/definitions/Markets\"\n    },\n    \"InstallerAbortsTerminal\": {\n      \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\n    },\n    \"ReleaseDate\": {\n      \"$ref\": \"#/definitions/ReleaseDate\"\n    },\n    \"InstallLocationRequired\": {\n      \"$ref\": \"#/definitions/InstallLocationRequired\"\n    },\n    \"RequireExplicitUpgrade\": {\n      \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\n    },\n    \"DisplayInstallWarnings\": {\n      \"$ref\": \"#/definitions/DisplayInstallWarnings\"\n    },\n    \"UnsupportedOSArchitectures\": {\n      \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\n    },\n    \"UnsupportedArguments\": {\n      \"$ref\": \"#/definitions/UnsupportedArguments\"\n    },\n    \"AppsAndFeaturesEntries\": {\n      \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\n    },\n    \"ElevationRequirement\": {\n      \"$ref\": \"#/definitions/ElevationRequirement\"\n    },\n    \"InstallationMetadata\": {\n      \"$ref\": \"#/definitions/InstallationMetadata\"\n    },\n    \"DownloadCommandProhibited\": {\n      \"$ref\": \"#/definitions/DownloadCommandProhibited\"\n    },\n    \"RepairBehavior\": {\n      \"$ref\": \"#/definitions/RepairBehavior\"\n    },\n    \"ArchiveBinariesDependOnPath\": {\n      \"$ref\": \"#/definitions/ArchiveBinariesDependOnPath\"\n    },\n    \"Authentication\": {\n      \"$ref\": \"#/definitions/Authentication\"\n    },\n    \"Installers\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/Installer\"\n      },\n      \"minItems\": 1,\n      \"maxItems\": 1\n    },\n    \"ManifestType\": {\n      \"type\": \"string\",\n      \"default\": \"singleton\",\n      \"const\": \"singleton\",\n      \"description\": \"The manifest type\"\n    },\n    \"ManifestVersion\": {\n      \"type\": \"string\",\n      \"default\": \"1.12.0\",\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\n      \"description\": \"The manifest syntax version\"\n    }\n  },\n  \"required\": [\n    \"PackageIdentifier\",\n    \"PackageVersion\",\n    \"PackageLocale\",\n    \"Publisher\",\n    \"PackageName\",\n    \"License\",\n    \"ShortDescription\",\n    \"Installers\",\n    \"ManifestType\",\n    \"ManifestVersion\"\n  ]\n}\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.12.0/manifest.version.1.12.0.json",
    "content": "{\n  \"$id\": \"https://aka.ms/winget-manifest.version.1.12.0.schema.json\",\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"description\": \"A representation of a multi-file manifest representing an app version in the OWC. v1.12.0\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"PackageIdentifier\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\n      \"maxLength\": 128,\n      \"description\": \"The package unique identifier\"\n    },\n    \"PackageVersion\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n      \"maxLength\": 128,\n      \"description\": \"The package version\"\n    },\n    \"DefaultLocale\": {\n      \"type\": \"string\",\n      \"default\": \"en-US\",\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\n      \"maxLength\": 20,\n      \"description\": \"The default package meta-data locale\"\n    },\n    \"ManifestType\": {\n      \"type\": \"string\",\n      \"default\": \"version\",\n      \"const\": \"version\",\n      \"description\": \"The manifest type\"\n    },\n    \"ManifestVersion\": {\n      \"type\": \"string\",\n      \"default\": \"1.12.0\",\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\n      \"description\": \"The manifest syntax version\"\n    }\n  },\n  \"required\": [\n    \"PackageIdentifier\",\n    \"PackageVersion\",\n    \"DefaultLocale\",\n    \"ManifestType\",\n    \"ManifestVersion\"\n  ]\n}\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.2.0/manifest.defaultLocale.1.2.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.defaultlocale.1.2.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a multiple-file manifest representing a default app metadata in the OWC. v1.2.0\",\r\n  \"definitions\": {\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Optional Url type\"\r\n    },\r\n    \"Tag\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 40,\r\n      \"description\": \"Package moniker or tag\"\r\n    },\r\n    \"Agreement\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"AgreementLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\r\n        },\r\n        \"Agreement\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 10000,\r\n          \"description\": \"The agreement text content.\"\r\n        },\r\n        \"AgreementUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The agreement URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Documentation\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DocumentLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\r\n        },\r\n        \"DocumentUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The documentation URL.\"          \r\n        }\r\n      }\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,3}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"PackageLocale\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"en-US\",\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The package meta-data locale\"\r\n    },\r\n    \"Publisher\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The publisher name\"\r\n    },\r\n    \"PublisherUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher home page\"\r\n    },\r\n    \"PublisherSupportUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher support page\"\r\n    },\r\n    \"PrivacyUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher privacy page or the package privacy page\"\r\n    },\r\n    \"Author\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package author\"\r\n    },\r\n    \"PackageName\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package name\"\r\n    },\r\n    \"PackageUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package home page\"\r\n    },\r\n    \"License\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package license\"\r\n    },\r\n    \"LicenseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The license page\"\r\n    },\r\n    \"Copyright\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package copyright\"\r\n    },\r\n    \"CopyrightUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package copyright page\"\r\n    },\r\n    \"ShortDescription\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The short package description\"\r\n    },\r\n    \"Description\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The full package description\"\r\n    },\r\n    \"Moniker\": {\r\n      \"$ref\": \"#/definitions/Tag\",\r\n      \"description\": \"The most common package term\"\r\n    },\r\n    \"Tags\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Tag\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional package search terms\"\r\n    },\r\n    \"Agreements\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Agreement\"\r\n      },\r\n      \"maxItems\": 128\r\n    },\r\n    \"ReleaseNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The package release notes\"\r\n    },\r\n    \"ReleaseNotesUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package release notes url\"\r\n    },\r\n    \"PurchaseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\r\n    },\r\n    \"InstallationNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"      \r\n    },\r\n    \"Documentations\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Documentation\"\r\n      },\r\n      \"maxItems\": 256\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"defaultLocale\",\r\n      \"const\": \"defaultLocale\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.2.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"PackageLocale\",\r\n    \"Publisher\",\r\n    \"PackageName\",\r\n    \"License\",\r\n    \"ShortDescription\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}"
  },
  {
    "path": "schemas/JSON/manifests/v1.2.0/manifest.installer.1.2.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.installer.1.2.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a single-file manifest representing an app installers in the OWC. v1.2.0\",\r\n  \"definitions\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,3}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"Locale\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The installer meta-data locale\"\r\n    },\r\n    \"Channel\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 16,\r\n      \"description\": \"The distribution channel\"\r\n    },\r\n    \"Platform\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"Platform\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"Windows.Desktop\",\r\n          \"Windows.Universal\"\r\n        ]\r\n      },\r\n      \"maxItems\": 2,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"The installer supported operating system\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$\",\r\n      \"description\": \"The installer minimum operating system version\"\r\n    },\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Url type\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"msix\",\r\n        \"msi\",\r\n        \"appx\",\r\n        \"exe\",\r\n        \"inno\",\r\n        \"nullsoft\",\r\n        \"wix\",\r\n        \"burn\",\r\n        \"pwa\",\r\n        \"portable\"\r\n      ],\r\n      \"description\": \"Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level\"\r\n    },\r\n    \"Architecture\": {\r\n      \"type\": \"string\",\r\n      \"enum\": [\r\n        \"x86\",\r\n        \"x64\",\r\n        \"arm\",\r\n        \"arm64\",\r\n        \"neutral\"\r\n      ],\r\n      \"description\": \"The installer target architecture\"\r\n    },   \r\n    \"Scope\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"user\",\r\n        \"machine\"\r\n      ],\r\n      \"description\": \"Scope indicates if the installer is per user or per machine\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"InstallModes\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"interactive\",\r\n          \"silent\",\r\n          \"silentWithProgress\"\r\n        ]\r\n      },\r\n      \"maxItems\": 3,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of supported installer modes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"Silent\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Silent is the value that should be passed to the installer when user chooses a silent or quiet install\"\r\n        },\r\n        \"SilentWithProgress\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install\"\r\n        },\r\n        \"Interactive\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Interactive is the value that should be passed to the installer when user chooses an interactive install\"\r\n        },\r\n        \"InstallLocation\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"InstallLocation is the value passed to the installer for custom install location. <INSTALLPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Log\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Log is the value passed to the installer for custom log file path. <LOGPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Upgrade\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Upgrade is the value that should be passed to the installer when user chooses an upgrade\"\r\n        },\r\n        \"Custom\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 2048,\r\n          \"description\": \"Custom switches will be passed directly to the installer by winget\"\r\n        }\r\n      }\r\n    },\r\n    \"InstallerReturnCode\": {\r\n      \"type\": \"integer\",\r\n      \"format\": \"long\",\r\n      \"not\": {\r\n        \"enum\": [ 0 ]\r\n      },\r\n      \"minimum\": -2147483648,\r\n      \"maximum\": 4294967295,\r\n      \"description\": \"An exit code that can be returned by the installer after execution\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/InstallerReturnCode\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional non-zero installer success exit codes other than known default values by winget\"\r\n    },\r\n    \"ExpectedReturnCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"object\",\r\n        \"title\": \"ExpectedReturnCode\",\r\n        \"properties\": {\r\n          \"InstallerReturnCode\": {\r\n            \"$ref\": \"#/definitions/InstallerReturnCode\"\r\n          },\r\n          \"ReturnResponse\": {\r\n            \"type\": \"string\",\r\n            \"enum\": [\r\n              \"packageInUse\",\r\n              \"installInProgress\",\r\n              \"fileInUse\",\r\n              \"missingDependency\",\r\n              \"diskFull\",\r\n              \"insufficientMemory\",\r\n              \"noNetwork\",\r\n              \"contactSupport\",\r\n              \"rebootRequiredToFinish\",\r\n              \"rebootRequiredForInstall\",\r\n              \"rebootInitiated\",\r\n              \"cancelledByUser\",\r\n              \"alreadyInstalled\",\r\n              \"downgrade\",\r\n              \"blockedByPolicy\",\r\n              \"custom\"\r\n            ]\r\n          },\r\n          \"ReturnResponseUrl\": {\r\n            \"$ref\": \"#/definitions/Url\",\r\n            \"description\": \"The return response url to provide additional guidance for expected return codes\"\r\n          }\r\n        },\r\n        \"required\": [ \"InstallerReturnCode\", \"ReturnResponse\" ]\r\n      },\r\n      \"maxItems\": 128,\r\n      \"description\": \"Installer exit codes for common errors\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"install\",\r\n        \"uninstallPrevious\"\r\n      ],\r\n      \"description\": \"The upgrade method\"\r\n    },\r\n    \"Commands\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of commands or aliases to run the package\"\r\n    },\r\n    \"Protocols\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"maxLength\": 2048\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of protocols the package provides a handler for\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n        \"maxLength\": 64\r\n      },\r\n      \"maxItems\": 512,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of file extensions the package could support\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"properties\": {\r\n        \"WindowsFeatures\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows feature dependencies\"\r\n        },\r\n        \"WindowsLibraries\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows library dependencies\"\r\n        },\r\n        \"PackageDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"object\",\r\n            \"properties\": {\r\n              \"PackageIdentifier\": {\r\n                \"$ref\": \"#/definitions/PackageIdentifier\"\r\n              },\r\n              \"MinimumVersion\": {\r\n                \"$ref\": \"#/definitions/PackageVersion\"\r\n              }\r\n            },\r\n            \"required\": [ \"PackageIdentifier\" ]\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of package dependencies from current source\"\r\n        },\r\n        \"ExternalDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of external package dependencies\"\r\n        }\r\n      }\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^[A-Za-z0-9][-\\\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$\",\r\n      \"maxLength\": 255,\r\n      \"description\": \"PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 255,\r\n      \"description\": \"ProductCode could be used for correlation of packages across sources\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer restricted capabilities\"\r\n    },\r\n    \"Market\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[A-Z]{2}$\",\r\n      \"description\": \"The installer target market\"\r\n    },\r\n    \"MarketArray\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"maxItems\": 256,\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Market\"\r\n      },\r\n      \"description\": \"Array of markets\"\r\n    },\r\n    \"Markets\": {\r\n      \"description\": \"The installer markets\",\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"oneOf\": [\r\n        {\r\n          \"properties\": {\r\n            \"AllowedMarkets\": {\r\n              \"$ref\": \"#/definitions/MarketArray\"\r\n            }\r\n          },\r\n          \"required\": [ \"AllowedMarkets\" ]\r\n        },\r\n        {\r\n          \"properties\": {\r\n            \"ExcludedMarkets\": {\r\n              \"$ref\": \"#/definitions/MarketArray\"\r\n            }\r\n          },\r\n          \"required\": [ \"ExcludedMarkets\" ]\r\n        }\r\n      ]\r\n    },\r\n    \"InstallerAbortsTerminal\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer will abort terminal. Default is false\"\r\n    },\r\n    \"ReleaseDate\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"format\": \"date\",\r\n      \"description\": \"The installer release date\"\r\n    },\r\n    \"InstallLocationRequired\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer requires an install location provided\"\r\n    },\r\n    \"RequireExplicitUpgrade\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer should be pinned by default from upgrade\"\r\n    },\r\n    \"DisplayInstallWarnings\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications.\"\r\n    },\r\n    \"UnsupportedOSArchitectures\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"title\": \"UnsupportedOSArchitecture\",\r\n        \"enum\": [\r\n          \"x86\",\r\n          \"x64\",\r\n          \"arm\",\r\n          \"arm64\"\r\n        ]\r\n      },\r\n      \"description\": \"List of OS architectures the installer does not support\"\r\n    },\r\n    \"UnsupportedArguments\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"title\": \"UnsupportedArgument\",\r\n        \"enum\": [\r\n          \"log\",\r\n          \"location\"\r\n        ]\r\n      },\r\n      \"description\": \"List of winget arguments the installer does not support\"\r\n    },\r\n    \"AppsAndFeaturesEntry\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DisplayName\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 256,\r\n          \"description\": \"The DisplayName registry value\"\r\n        },\r\n        \"Publisher\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 256,\r\n          \"description\": \"The Publisher registry value\"\r\n        },\r\n        \"DisplayVersion\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 128,\r\n          \"description\": \"The DisplayVersion registry value\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"UpgradeCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        }\r\n      },\r\n      \"description\": \"Various key values under installer's ARP entry\"\r\n    },\r\n    \"AppsAndFeaturesEntries\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"maxItems\": 128,\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/AppsAndFeaturesEntry\"\r\n      },\r\n      \"description\": \"List of ARP entries.\"\r\n    },\r\n    \"ElevationRequirement\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"elevationRequired\",\r\n        \"elevationProhibited\",\r\n        \"elevatesSelf\"\r\n      ],\r\n      \"description\": \"The installer's elevation requirement\"\r\n    },\r\n    \"Installer\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"InstallerLocale\": {\r\n          \"$ref\": \"#/definitions/Locale\"\r\n        },\r\n        \"Platform\": {\r\n          \"$ref\": \"#/definitions/Platform\"\r\n        },\r\n        \"MinimumOSVersion\": {\r\n          \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n        },\r\n        \"Architecture\": {\r\n          \"$ref\": \"#/definitions/Architecture\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        },\r\n        \"Scope\": {\r\n          \"$ref\": \"#/definitions/Scope\"\r\n        },\r\n        \"InstallerUrl\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n          \"maxLength\": 2048,\r\n          \"description\": \"The installer Url\"\r\n        },\r\n        \"InstallerSha256\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"Sha256 is required. Sha256 of the installer\"\r\n        },\r\n        \"SignatureSha256\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable\"\r\n        },\r\n        \"InstallModes\": {\r\n          \"$ref\": \"#/definitions/InstallModes\"\r\n        },\r\n        \"InstallerSwitches\": {\r\n          \"$ref\": \"#/definitions/InstallerSwitches\"\r\n        },\r\n        \"InstallerSuccessCodes\": {\r\n          \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n        },\r\n        \"ExpectedReturnCodes\": {\r\n          \"$ref\": \"#/definitions/ExpectedReturnCodes\"\r\n        },\r\n        \"UpgradeBehavior\": {\r\n          \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n        },\r\n        \"Commands\": {\r\n          \"$ref\": \"#/definitions/Commands\"\r\n        },\r\n        \"Protocols\": {\r\n          \"$ref\": \"#/definitions/Protocols\"\r\n        },\r\n        \"FileExtensions\": {\r\n          \"$ref\": \"#/definitions/FileExtensions\"\r\n        },\r\n        \"Dependencies\": {\r\n          \"$ref\": \"#/definitions/Dependencies\"\r\n        },\r\n        \"PackageFamilyName\": {\r\n          \"$ref\": \"#/definitions/PackageFamilyName\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"Capabilities\": {\r\n          \"$ref\": \"#/definitions/Capabilities\"\r\n        },\r\n        \"RestrictedCapabilities\": {\r\n          \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n        },\r\n        \"Markets\": {\r\n          \"$ref\": \"#/definitions/Markets\"\r\n        },\r\n        \"InstallerAbortsTerminal\": {\r\n          \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\r\n        },\r\n        \"ReleaseDate\": {\r\n          \"$ref\": \"#/definitions/ReleaseDate\"\r\n        },\r\n        \"InstallLocationRequired\": {\r\n          \"$ref\": \"#/definitions/InstallLocationRequired\"\r\n        },\r\n        \"RequireExplicitUpgrade\": {\r\n          \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\r\n        },\r\n        \"DisplayInstallWarnings\": {\r\n          \"$ref\": \"#/definitions/DisplayInstallWarnings\"\r\n        },\r\n        \"UnsupportedOSArchitectures\": {\r\n          \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\r\n        },\r\n        \"UnsupportedArguments\": {\r\n          \"$ref\": \"#/definitions/UnsupportedArguments\"\r\n        },\r\n        \"AppsAndFeaturesEntries\": {\r\n          \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\r\n        },\r\n        \"ElevationRequirement\": {\r\n          \"$ref\": \"#/definitions/ElevationRequirement\"\r\n        }\r\n      },\r\n      \"required\": [\r\n        \"Architecture\",\r\n        \"InstallerUrl\",\r\n        \"InstallerSha256\"\r\n      ]\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"$ref\": \"#/definitions/PackageIdentifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"$ref\": \"#/definitions/PackageVersion\"\r\n    },\r\n    \"Channel\": {\r\n      \"$ref\": \"#/definitions/Channel\"\r\n    },\r\n    \"InstallerLocale\": {\r\n      \"$ref\": \"#/definitions/Locale\"\r\n    },\r\n    \"Platform\": {\r\n      \"$ref\": \"#/definitions/Platform\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"$ref\": \"#/definitions/InstallerType\"\r\n    },\r\n    \"Scope\": {\r\n      \"$ref\": \"#/definitions/Scope\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"$ref\": \"#/definitions/InstallModes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"$ref\": \"#/definitions/InstallerSwitches\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n    },\r\n    \"ExpectedReturnCodes\": {\r\n      \"$ref\": \"#/definitions/ExpectedReturnCodes\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n    },\r\n    \"Commands\": {\r\n      \"$ref\": \"#/definitions/Commands\"\r\n    },\r\n    \"Protocols\": {\r\n      \"$ref\": \"#/definitions/Protocols\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"$ref\": \"#/definitions/FileExtensions\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"$ref\": \"#/definitions/Dependencies\"\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"$ref\": \"#/definitions/PackageFamilyName\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"$ref\": \"#/definitions/ProductCode\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"$ref\": \"#/definitions/Capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n    },\r\n    \"Markets\": {\r\n      \"$ref\": \"#/definitions/Markets\"\r\n    },\r\n    \"InstallerAbortsTerminal\": {\r\n      \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\r\n    },\r\n    \"ReleaseDate\": {\r\n      \"$ref\": \"#/definitions/ReleaseDate\"\r\n    },\r\n    \"InstallLocationRequired\": {\r\n      \"$ref\": \"#/definitions/InstallLocationRequired\"\r\n    },\r\n    \"RequireExplicitUpgrade\": {\r\n      \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\r\n    },\r\n    \"UnsupportedOSArchitectures\": {\r\n      \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\r\n    },\r\n    \"UnsupportedArguments\": {\r\n      \"$ref\": \"#/definitions/UnsupportedArguments\"\r\n    },\r\n    \"AppsAndFeaturesEntries\": {\r\n      \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\r\n    },\r\n    \"ElevationRequirement\": {\r\n      \"$ref\": \"#/definitions/ElevationRequirement\"\r\n    },\r\n    \"DisplayInstallWarnings\": {\r\n      \"$ref\": \"#/definitions/DisplayInstallWarnings\"\r\n    },\r\n    \"Installers\": {\r\n      \"type\": \"array\",\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Installer\"\r\n      },\r\n      \"minItems\": 1,\r\n      \"maxItems\": 1024\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"installer\",\r\n      \"const\": \"installer\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.2.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"Installers\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}\r\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.2.0/manifest.locale.1.2.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.locale.1.2.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a multiple-file manifest representing app metadata in other locale in the OWC. v1.2.0\",\r\n  \"definitions\": {\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Optional Url type\"\r\n    },\r\n    \"Tag\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 40,\r\n      \"description\": \"Package tag\"\r\n    },\r\n    \"Agreement\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"AgreementLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\r\n        },\r\n        \"Agreement\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 10000,\r\n          \"description\": \"The agreement text content.\"\r\n        },\r\n        \"AgreementUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The agreement URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Documentation\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DocumentLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\r\n        },\r\n        \"DocumentUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The documentation URL.\"          \r\n        }\r\n      }\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,3}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"PackageLocale\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The package meta-data locale\"\r\n    },\r\n    \"Publisher\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The publisher name\"\r\n    },\r\n    \"PublisherUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher home page\"\r\n    },\r\n    \"PublisherSupportUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher support page\"\r\n    },\r\n    \"PrivacyUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher privacy page or the package privacy page\"\r\n    },\r\n    \"Author\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package author\"\r\n    },\r\n    \"PackageName\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package name\"\r\n    },\r\n    \"PackageUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package home page\"\r\n    },\r\n    \"License\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package license\"\r\n    },\r\n    \"LicenseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The license page\"\r\n    },\r\n    \"Copyright\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package copyright\"\r\n    },\r\n    \"CopyrightUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package copyright page\"\r\n    },\r\n    \"ShortDescription\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The short package description\"\r\n    },\r\n    \"Description\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The full package description\"\r\n    },\r\n    \"Tags\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Tag\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional package search terms\"\r\n    },\r\n    \"Agreements\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Agreement\"\r\n      },\r\n      \"maxItems\": 128\r\n    },\r\n    \"ReleaseNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The package release notes\"\r\n    },\r\n    \"ReleaseNotesUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package release notes url\"\r\n    },\r\n    \"PurchaseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\r\n    },\r\n    \"InstallationNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"      \r\n    },\r\n    \"Documentations\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Documentation\"\r\n      },\r\n      \"maxItems\": 256\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"locale\",\r\n      \"const\": \"locale\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.2.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"PackageLocale\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}"
  },
  {
    "path": "schemas/JSON/manifests/v1.2.0/manifest.singleton.1.2.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.singleton.1.2.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a single-file manifest representing an app in the OWC. v1.2.0\",\r\n  \"definitions\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,3}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"Locale\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The package meta-data locale\"\r\n    },\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Optional Url type\"\r\n    },\r\n    \"Tag\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 40,\r\n      \"description\": \"Package moniker or tag\"\r\n    },\r\n    \"Agreement\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"AgreementLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\r\n        },\r\n        \"Agreement\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 10000,\r\n          \"description\": \"The agreement text content.\"\r\n        },\r\n        \"AgreementUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The agreement URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Documentation\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DocumentLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\r\n        },\r\n        \"DocumentUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The documentation URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Channel\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 16,\r\n      \"description\": \"The distribution channel\"\r\n    },\r\n    \"Platform\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"Platform\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"Windows.Desktop\",\r\n          \"Windows.Universal\"\r\n        ]\r\n      },\r\n      \"maxItems\": 2,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"The installer supported operating system\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$\",\r\n      \"description\": \"The installer minimum operating system version\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"msix\",\r\n        \"msi\",\r\n        \"appx\",\r\n        \"exe\",\r\n        \"inno\",\r\n        \"nullsoft\",\r\n        \"wix\",\r\n        \"burn\",\r\n        \"pwa\",\r\n        \"portable\"\r\n      ],\r\n      \"description\": \"Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level\"\r\n    },\r\n    \"Architecture\": {\r\n      \"type\": \"string\",\r\n      \"enum\": [\r\n        \"x86\",\r\n        \"x64\",\r\n        \"arm\",\r\n        \"arm64\",\r\n        \"neutral\"\r\n      ],\r\n      \"description\": \"The installer target architecture\"\r\n    },\r\n    \"Scope\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"user\",\r\n        \"machine\"\r\n      ],\r\n      \"description\": \"Scope indicates if the installer is per user or per machine\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"InstallModes\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"interactive\",\r\n          \"silent\",\r\n          \"silentWithProgress\"\r\n        ]\r\n      },\r\n      \"maxItems\": 3,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of supported installer modes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"Silent\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Silent is the value that should be passed to the installer when user chooses a silent or quiet install\"\r\n        },\r\n        \"SilentWithProgress\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install\"\r\n        },\r\n        \"Interactive\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Interactive is the value that should be passed to the installer when user chooses an interactive install\"\r\n        },\r\n        \"InstallLocation\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"InstallLocation is the value passed to the installer for custom install location. <INSTALLPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Log\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Log is the value passed to the installer for custom log file path. <LOGPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Upgrade\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Upgrade is the value that should be passed to the installer when user chooses an upgrade\"\r\n        },\r\n        \"Custom\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 2048,\r\n          \"description\": \"Custom switches will be passed directly to the installer by winget\"\r\n        }\r\n      }\r\n    },\r\n    \"InstallerReturnCode\": {\r\n      \"type\": \"integer\",\r\n      \"format\": \"long\",\r\n      \"not\": {\r\n        \"enum\": [ 0 ]\r\n      },\r\n      \"minimum\": -2147483648,\r\n      \"maximum\": 4294967295,\r\n      \"description\": \"An exit code that can be returned by the installer after execution\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/InstallerReturnCode\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional non-zero installer success exit codes other than known default values by winget\"\r\n    },\r\n    \"ExpectedReturnCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"object\",\r\n        \"title\": \"ExpectedReturnCode\",\r\n        \"properties\": {\r\n          \"InstallerReturnCode\": {\r\n            \"$ref\": \"#/definitions/InstallerReturnCode\"\r\n          },\r\n          \"ReturnResponse\": {\r\n            \"type\": \"string\",\r\n            \"enum\": [\r\n              \"packageInUse\",\r\n              \"installInProgress\",\r\n              \"fileInUse\",\r\n              \"missingDependency\",\r\n              \"diskFull\",\r\n              \"insufficientMemory\",\r\n              \"noNetwork\",\r\n              \"contactSupport\",\r\n              \"rebootRequiredToFinish\",\r\n              \"rebootRequiredForInstall\",\r\n              \"rebootInitiated\",\r\n              \"cancelledByUser\",\r\n              \"alreadyInstalled\",\r\n              \"downgrade\",\r\n              \"blockedByPolicy\",\r\n              \"custom\"\r\n            ]\r\n          },\r\n          \"ReturnResponseUrl\": {\r\n            \"$ref\": \"#/definitions/Url\",\r\n            \"description\": \"The return response url to provide additional guidance for expected return codes\"\r\n          }\r\n        },\r\n        \"required\": [ \"InstallerReturnCode\", \"ReturnResponse\" ]\r\n      },\r\n      \"maxItems\": 128,\r\n      \"description\": \"Installer exit codes for common errors\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"install\",\r\n        \"uninstallPrevious\"\r\n      ],\r\n      \"description\": \"The upgrade method\"\r\n    },\r\n    \"Commands\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of commands or aliases to run the package\"\r\n    },\r\n    \"Protocols\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"maxLength\": 2048\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of protocols the package provides a handler for\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n        \"maxLength\": 64\r\n      },\r\n      \"maxItems\": 512,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of file extensions the package could support\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"properties\": {\r\n        \"WindowsFeatures\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows feature dependencies\"\r\n        },\r\n        \"WindowsLibraries\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows library dependencies\"\r\n        },\r\n        \"PackageDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"object\",\r\n            \"properties\": {\r\n              \"PackageIdentifier\": {\r\n                \"$ref\": \"#/definitions/PackageIdentifier\"\r\n              },\r\n              \"MinimumVersion\": {\r\n                \"$ref\": \"#/definitions/PackageVersion\"\r\n              }\r\n            },\r\n            \"required\": [ \"PackageIdentifier\" ]\r\n          },\r\n          \"maxItems\": 16,\r\n          \"description\": \"List of package dependencies from current source\"\r\n        },\r\n        \"ExternalDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of external package dependencies\"\r\n        }\r\n      }\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^[A-Za-z0-9][-\\\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$\",\r\n      \"maxLength\": 255,\r\n      \"description\": \"PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 255,\r\n      \"description\": \"ProductCode could be used for correlation of packages across sources\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer restricted capabilities\"\r\n    },\r\n    \"Market\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[A-Z]{2}$\",\r\n      \"description\": \"The installer target market\"\r\n    },\r\n    \"MarketArray\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"maxItems\": 256,\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Market\"\r\n      },\r\n      \"description\": \"Array of markets\"\r\n    },\r\n    \"Markets\": {\r\n      \"description\": \"The installer markets\",\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"oneOf\": [\r\n        {\r\n          \"properties\": {\r\n            \"AllowedMarkets\": {\r\n              \"$ref\": \"#/definitions/MarketArray\"\r\n            }\r\n          },\r\n          \"required\": [ \"AllowedMarkets\" ]\r\n        },\r\n        {\r\n          \"properties\": {\r\n            \"ExcludedMarkets\": {\r\n              \"$ref\": \"#/definitions/MarketArray\"\r\n            }\r\n          },\r\n          \"required\": [ \"ExcludedMarkets\" ]\r\n        }\r\n      ]\r\n    },\r\n    \"InstallerAbortsTerminal\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer will abort terminal. Default is false\"\r\n    },\r\n    \"ReleaseDate\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"format\": \"date\",\r\n      \"description\": \"The installer release date\"\r\n    },\r\n    \"InstallLocationRequired\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer requires an install location provided\"\r\n    },\r\n    \"RequireExplicitUpgrade\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer should be pinned by default from upgrade\"\r\n    },\r\n    \"DisplayInstallWarnings\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications.\"\r\n    },\r\n    \"UnsupportedOSArchitectures\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"title\": \"UnsupportedOSArchitecture\",\r\n        \"enum\": [\r\n          \"x86\",\r\n          \"x64\",\r\n          \"arm\",\r\n          \"arm64\"\r\n        ]\r\n      },\r\n      \"description\": \"List of OS architectures the installer does not support\"\r\n    },\r\n    \"UnsupportedArguments\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"title\": \"UnsupportedArgument\",\r\n        \"enum\": [\r\n          \"log\",\r\n          \"location\"\r\n        ]\r\n      },\r\n      \"description\": \"List of winget arguments the installer does not support\"\r\n    },\r\n    \"AppsAndFeaturesEntry\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DisplayName\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 256,\r\n          \"description\": \"The DisplayName registry value\"\r\n        },\r\n        \"Publisher\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 256,\r\n          \"description\": \"The Publisher registry value\"\r\n        },\r\n        \"DisplayVersion\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 128,\r\n          \"description\": \"The DisplayVersion registry value\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"UpgradeCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        }\r\n      },\r\n      \"description\": \"Various key values under installer's ARP entry\"\r\n    },\r\n    \"AppsAndFeaturesEntries\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"maxItems\": 128,\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/AppsAndFeaturesEntry\"\r\n      },\r\n      \"description\": \"List of ARP entries.\"\r\n    },\r\n    \"ElevationRequirement\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"elevationRequired\",\r\n        \"elevationProhibited\",\r\n        \"elevatesSelf\"\r\n      ],\r\n      \"description\": \"The installer's elevation requirement\"\r\n    },\r\n    \"Installer\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"InstallerLocale\": {\r\n          \"$ref\": \"#/definitions/Locale\"\r\n        },\r\n        \"Platform\": {\r\n          \"$ref\": \"#/definitions/Platform\"\r\n        },\r\n        \"MinimumOSVersion\": {\r\n          \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n        },\r\n        \"Architecture\": {\r\n          \"$ref\": \"#/definitions/Architecture\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        },\r\n        \"Scope\": {\r\n          \"$ref\": \"#/definitions/Scope\"\r\n        },\r\n        \"InstallerUrl\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n          \"maxLength\": 2048,\r\n          \"description\": \"The installer Url\"\r\n        },\r\n        \"InstallerSha256\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"Sha256 is required. Sha256 of the installer\"\r\n        },\r\n        \"SignatureSha256\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable\"\r\n        },\r\n        \"InstallModes\": {\r\n          \"$ref\": \"#/definitions/InstallModes\"\r\n        },\r\n        \"InstallerSwitches\": {\r\n          \"$ref\": \"#/definitions/InstallerSwitches\"\r\n        },\r\n        \"InstallerSuccessCodes\": {\r\n          \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n        },\r\n        \"ExpectedReturnCodes\": {\r\n          \"$ref\": \"#/definitions/ExpectedReturnCodes\"\r\n        },\r\n        \"UpgradeBehavior\": {\r\n          \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n        },\r\n        \"Commands\": {\r\n          \"$ref\": \"#/definitions/Commands\"\r\n        },\r\n        \"Protocols\": {\r\n          \"$ref\": \"#/definitions/Protocols\"\r\n        },\r\n        \"FileExtensions\": {\r\n          \"$ref\": \"#/definitions/FileExtensions\"\r\n        },\r\n        \"Dependencies\": {\r\n          \"$ref\": \"#/definitions/Dependencies\"\r\n        },\r\n        \"PackageFamilyName\": {\r\n          \"$ref\": \"#/definitions/PackageFamilyName\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"Capabilities\": {\r\n          \"$ref\": \"#/definitions/Capabilities\"\r\n        },\r\n        \"RestrictedCapabilities\": {\r\n          \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n        },\r\n        \"Markets\": {\r\n          \"$ref\": \"#/definitions/Markets\"\r\n        },\r\n        \"InstallerAbortsTerminal\": {\r\n          \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\r\n        },\r\n        \"ReleaseDate\": {\r\n          \"$ref\": \"#/definitions/ReleaseDate\"\r\n        },\r\n        \"InstallLocationRequired\": {\r\n          \"$ref\": \"#/definitions/InstallLocationRequired\"\r\n        },\r\n        \"RequireExplicitUpgrade\": {\r\n          \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\r\n        },\r\n        \"DisplayInstallWarnings\": {\r\n          \"$ref\": \"#/definitions/DisplayInstallWarnings\"\r\n        },\r\n        \"UnsupportedOSArchitectures\": {\r\n          \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\r\n        },\r\n        \"UnsupportedArguments\": {\r\n          \"$ref\": \"#/definitions/UnsupportedArguments\"\r\n        },\r\n        \"AppsAndFeaturesEntries\": {\r\n          \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\r\n        },\r\n        \"ElevationRequirement\": {\r\n          \"$ref\": \"#/definitions/ElevationRequirement\"\r\n        }\r\n      },\r\n      \"required\": [\r\n        \"Architecture\",\r\n        \"InstallerUrl\",\r\n        \"InstallerSha256\"\r\n      ]\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"$ref\": \"#/definitions/PackageIdentifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"$ref\": \"#/definitions/PackageVersion\"\r\n    },\r\n    \"PackageLocale\": {\r\n      \"$ref\": \"#/definitions/Locale\"\r\n    },\r\n    \"Publisher\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The publisher name\"\r\n    },\r\n    \"PublisherUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher home page\"\r\n    },\r\n    \"PublisherSupportUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher support page\"\r\n    },\r\n    \"PrivacyUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher privacy page or the package privacy page\"\r\n    },\r\n    \"Author\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package author\"\r\n    },\r\n    \"PackageName\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package name\"\r\n    },\r\n    \"PackageUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package home page\"\r\n    },\r\n    \"License\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package license\"\r\n    },\r\n    \"LicenseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The license page\"\r\n    },\r\n    \"Copyright\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package copyright\"\r\n    },\r\n    \"CopyrightUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package copyright page\"\r\n    },\r\n    \"ShortDescription\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The short package description\"\r\n    },\r\n    \"Description\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The full package description\"\r\n    },\r\n    \"Moniker\": {\r\n      \"$ref\": \"#/definitions/Tag\",\r\n      \"description\": \"The most common package term\"\r\n    },\r\n    \"Tags\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Tag\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional package search terms\"\r\n    },\r\n    \"Agreements\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Agreement\"\r\n      },\r\n      \"maxItems\": 128\r\n    },\r\n    \"ReleaseNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The package release notes\"\r\n    },\r\n    \"ReleaseNotesUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package release notes url\"\r\n    },\r\n    \"PurchaseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\r\n    },\r\n    \"InstallationNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"\r\n    },\r\n    \"Documentations\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Documentation\"\r\n      },\r\n      \"maxItems\": 256\r\n    },\r\n    \"Channel\": {\r\n      \"$ref\": \"#/definitions/Channel\"\r\n    },\r\n    \"InstallerLocale\": {\r\n      \"$ref\": \"#/definitions/Locale\"\r\n    },\r\n    \"Platform\": {\r\n      \"$ref\": \"#/definitions/Platform\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"$ref\": \"#/definitions/InstallerType\"\r\n    },\r\n    \"Scope\": {\r\n      \"$ref\": \"#/definitions/Scope\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"$ref\": \"#/definitions/InstallModes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"$ref\": \"#/definitions/InstallerSwitches\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n    },\r\n    \"ExpectedReturnCodes\": {\r\n      \"$ref\": \"#/definitions/ExpectedReturnCodes\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n    },\r\n    \"Commands\": {\r\n      \"$ref\": \"#/definitions/Commands\"\r\n    },\r\n    \"Protocols\": {\r\n      \"$ref\": \"#/definitions/Protocols\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"$ref\": \"#/definitions/FileExtensions\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"$ref\": \"#/definitions/Dependencies\"\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"$ref\": \"#/definitions/PackageFamilyName\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"$ref\": \"#/definitions/ProductCode\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"$ref\": \"#/definitions/Capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n    },\r\n    \"Markets\": {\r\n      \"$ref\": \"#/definitions/Markets\"\r\n    },\r\n    \"InstallerAbortsTerminal\": {\r\n      \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\r\n    },\r\n    \"ReleaseDate\": {\r\n      \"$ref\": \"#/definitions/ReleaseDate\"\r\n    },\r\n    \"InstallLocationRequired\": {\r\n      \"$ref\": \"#/definitions/InstallLocationRequired\"\r\n    },\r\n    \"RequireExplicitUpgrade\": {\r\n      \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\r\n    },\r\n    \"DisplayInstallWarnings\": {\r\n      \"$ref\": \"#/definitions/DisplayInstallWarnings\"\r\n    },\r\n    \"UnsupportedOSArchitectures\": {\r\n      \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\r\n    },\r\n    \"UnsupportedArguments\": {\r\n      \"$ref\": \"#/definitions/UnsupportedArguments\"\r\n    },\r\n    \"AppsAndFeaturesEntries\": {\r\n      \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\r\n    },\r\n    \"ElevationRequirement\": {\r\n      \"$ref\": \"#/definitions/ElevationRequirement\"\r\n    },\r\n    \"Installers\": {\r\n      \"type\": \"array\",\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Installer\"\r\n      },\r\n      \"minItems\": 1,\r\n      \"maxItems\": 1\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"singleton\",\r\n      \"const\": \"singleton\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.2.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"PackageLocale\",\r\n    \"Publisher\",\r\n    \"PackageName\",\r\n    \"License\",\r\n    \"ShortDescription\",\r\n    \"Installers\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}\r\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.2.0/manifest.version.1.2.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.version.1.2.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a multi-file manifest representing an app version in the OWC. v1.2.0\",\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,3}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"DefaultLocale\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"en-US\",\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The default package meta-data locale\"\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"version\",\r\n      \"const\": \"version\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.2.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"DefaultLocale\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}"
  },
  {
    "path": "schemas/JSON/manifests/v1.4.0/manifest.defaultLocale.1.4.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.defaultlocale.1.4.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a multiple-file manifest representing a default app metadata in the OWC. v1.4.0\",\r\n  \"definitions\": {\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Optional Url type\"\r\n    },\r\n    \"Tag\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 40,\r\n      \"description\": \"Package moniker or tag\"\r\n    },\r\n    \"Agreement\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"AgreementLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\r\n        },\r\n        \"Agreement\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 10000,\r\n          \"description\": \"The agreement text content.\"\r\n        },\r\n        \"AgreementUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The agreement URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Documentation\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DocumentLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\r\n        },\r\n        \"DocumentUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The documentation URL.\"\r\n        }\r\n      }\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"PackageLocale\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"en-US\",\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The package meta-data locale\"\r\n    },\r\n    \"Publisher\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The publisher name\"\r\n    },\r\n    \"PublisherUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher home page\"\r\n    },\r\n    \"PublisherSupportUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher support page\"\r\n    },\r\n    \"PrivacyUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher privacy page or the package privacy page\"\r\n    },\r\n    \"Author\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package author\"\r\n    },\r\n    \"PackageName\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package name\"\r\n    },\r\n    \"PackageUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package home page\"\r\n    },\r\n    \"License\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package license\"\r\n    },\r\n    \"LicenseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The license page\"\r\n    },\r\n    \"Copyright\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package copyright\"\r\n    },\r\n    \"CopyrightUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package copyright page\"\r\n    },\r\n    \"ShortDescription\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The short package description\"\r\n    },\r\n    \"Description\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The full package description\"\r\n    },\r\n    \"Moniker\": {\r\n      \"$ref\": \"#/definitions/Tag\",\r\n      \"description\": \"The most common package term\"\r\n    },\r\n    \"Tags\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Tag\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional package search terms\"\r\n    },\r\n    \"Agreements\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Agreement\"\r\n      },\r\n      \"maxItems\": 128\r\n    },\r\n    \"ReleaseNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The package release notes\"\r\n    },\r\n    \"ReleaseNotesUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package release notes url\"\r\n    },\r\n    \"PurchaseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\r\n    },\r\n    \"InstallationNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"\r\n    },\r\n    \"Documentations\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Documentation\"\r\n      },\r\n      \"maxItems\": 256\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"defaultLocale\",\r\n      \"const\": \"defaultLocale\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.4.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"PackageLocale\",\r\n    \"Publisher\",\r\n    \"PackageName\",\r\n    \"License\",\r\n    \"ShortDescription\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}"
  },
  {
    "path": "schemas/JSON/manifests/v1.4.0/manifest.installer.1.4.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.installer.1.4.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a single-file manifest representing an app installers in the OWC. v1.4.0\",\r\n  \"definitions\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"Locale\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The installer meta-data locale\"\r\n    },\r\n    \"Channel\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 16,\r\n      \"description\": \"The distribution channel\"\r\n    },\r\n    \"Platform\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"Platform\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"Windows.Desktop\",\r\n          \"Windows.Universal\"\r\n        ]\r\n      },\r\n      \"maxItems\": 2,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"The installer supported operating system\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$\",\r\n      \"description\": \"The installer minimum operating system version\"\r\n    },\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Url type\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"msix\",\r\n        \"msi\",\r\n        \"appx\",\r\n        \"exe\",\r\n        \"zip\",\r\n        \"inno\",\r\n        \"nullsoft\",\r\n        \"wix\",\r\n        \"burn\",\r\n        \"pwa\",\r\n        \"portable\"\r\n      ],\r\n      \"description\": \"Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level\"\r\n    },\r\n    \"NestedInstallerType\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"msix\",\r\n        \"msi\",\r\n        \"appx\",\r\n        \"exe\",\r\n        \"inno\",\r\n        \"nullsoft\",\r\n        \"wix\",\r\n        \"burn\",\r\n        \"portable\"\r\n      ],\r\n      \"description\": \"Enumeration of supported nested installer types contained inside an archive file\"\r\n    },\r\n    \"NestedInstallerFiles\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"object\",\r\n        \"title\": \"NestedInstallerFile\",\r\n        \"properties\": {\r\n          \"RelativeFilePath\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 512,\r\n            \"description\": \"The relative path to the nested installer file\"\r\n          },\r\n          \"PortableCommandAlias\": {\r\n            \"type\": [ \"string\", \"null\" ],\r\n            \"minLength\": 1,\r\n            \"maxLength\": 40,\r\n            \"description\": \"The command alias to be used for calling the package. Only applies to the nested portable package\"\r\n          }\r\n        },\r\n        \"required\": [ \"RelativeFilePath\" ],\r\n        \"description\": \"A nested installer file contained inside an archive\"\r\n      },\r\n      \"maxItems\": 1024,\r\n      \"description\": \"List of nested installer files contained inside an archive\"\r\n    },\r\n    \"Architecture\": {\r\n      \"type\": \"string\",\r\n      \"enum\": [\r\n        \"x86\",\r\n        \"x64\",\r\n        \"arm\",\r\n        \"arm64\",\r\n        \"neutral\"\r\n      ],\r\n      \"description\": \"The installer target architecture\"\r\n    },\r\n    \"Scope\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"user\",\r\n        \"machine\"\r\n      ],\r\n      \"description\": \"Scope indicates if the installer is per user or per machine\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"InstallModes\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"interactive\",\r\n          \"silent\",\r\n          \"silentWithProgress\"\r\n        ]\r\n      },\r\n      \"maxItems\": 3,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of supported installer modes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"Silent\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Silent is the value that should be passed to the installer when user chooses a silent or quiet install\"\r\n        },\r\n        \"SilentWithProgress\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install\"\r\n        },\r\n        \"Interactive\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Interactive is the value that should be passed to the installer when user chooses an interactive install\"\r\n        },\r\n        \"InstallLocation\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"InstallLocation is the value passed to the installer for custom install location. <INSTALLPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Log\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Log is the value passed to the installer for custom log file path. <LOGPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Upgrade\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Upgrade is the value that should be passed to the installer when user chooses an upgrade\"\r\n        },\r\n        \"Custom\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 2048,\r\n          \"description\": \"Custom switches will be passed directly to the installer by winget\"\r\n        }\r\n      }\r\n    },\r\n    \"InstallerReturnCode\": {\r\n      \"type\": \"integer\",\r\n      \"format\": \"long\",\r\n      \"not\": {\r\n        \"enum\": [ 0 ]\r\n      },\r\n      \"minimum\": -2147483648,\r\n      \"maximum\": 4294967295,\r\n      \"description\": \"An exit code that can be returned by the installer after execution\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/InstallerReturnCode\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional non-zero installer success exit codes other than known default values by winget\"\r\n    },\r\n    \"ExpectedReturnCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"object\",\r\n        \"title\": \"ExpectedReturnCode\",\r\n        \"properties\": {\r\n          \"InstallerReturnCode\": {\r\n            \"$ref\": \"#/definitions/InstallerReturnCode\"\r\n          },\r\n          \"ReturnResponse\": {\r\n            \"type\": \"string\",\r\n            \"enum\": [\r\n              \"packageInUse\",\r\n              \"packageInUseByApplication\",\r\n              \"installInProgress\",\r\n              \"fileInUse\",\r\n              \"missingDependency\",\r\n              \"diskFull\",\r\n              \"insufficientMemory\",\r\n              \"invalidParameter\",\r\n              \"noNetwork\",\r\n              \"contactSupport\",\r\n              \"rebootRequiredToFinish\",\r\n              \"rebootRequiredForInstall\",\r\n              \"rebootInitiated\",\r\n              \"cancelledByUser\",\r\n              \"alreadyInstalled\",\r\n              \"downgrade\",\r\n              \"blockedByPolicy\",\r\n              \"systemNotSupported\",\r\n              \"custom\"\r\n            ]\r\n          },\r\n          \"ReturnResponseUrl\": {\r\n            \"$ref\": \"#/definitions/Url\",\r\n            \"description\": \"The return response url to provide additional guidance for expected return codes\"\r\n          }\r\n        },\r\n        \"required\": [ \"InstallerReturnCode\", \"ReturnResponse\" ]\r\n      },\r\n      \"maxItems\": 128,\r\n      \"description\": \"Installer exit codes for common errors\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"install\",\r\n        \"uninstallPrevious\"\r\n      ],\r\n      \"description\": \"The upgrade method\"\r\n    },\r\n    \"Commands\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of commands or aliases to run the package\"\r\n    },\r\n    \"Protocols\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"maxLength\": 2048\r\n      },\r\n      \"maxItems\": 64,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of protocols the package provides a handler for\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n        \"maxLength\": 64\r\n      },\r\n      \"maxItems\": 512,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of file extensions the package could support\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"properties\": {\r\n        \"WindowsFeatures\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows feature dependencies\"\r\n        },\r\n        \"WindowsLibraries\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows library dependencies\"\r\n        },\r\n        \"PackageDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"object\",\r\n            \"properties\": {\r\n              \"PackageIdentifier\": {\r\n                \"$ref\": \"#/definitions/PackageIdentifier\"\r\n              },\r\n              \"MinimumVersion\": {\r\n                \"$ref\": \"#/definitions/PackageVersion\"\r\n              }\r\n            },\r\n            \"required\": [ \"PackageIdentifier\" ]\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of package dependencies from current source\"\r\n        },\r\n        \"ExternalDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of external package dependencies\"\r\n        }\r\n      }\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^[A-Za-z0-9][-\\\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$\",\r\n      \"maxLength\": 255,\r\n      \"description\": \"PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 255,\r\n      \"description\": \"ProductCode could be used for correlation of packages across sources\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer restricted capabilities\"\r\n    },\r\n    \"Market\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[A-Z]{2}$\",\r\n      \"description\": \"The installer target market\"\r\n    },\r\n    \"MarketArray\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"maxItems\": 256,\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Market\"\r\n      },\r\n      \"description\": \"Array of markets\"\r\n    },\r\n    \"Markets\": {\r\n      \"description\": \"The installer markets\",\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"oneOf\": [\r\n        {\r\n          \"properties\": {\r\n            \"AllowedMarkets\": {\r\n              \"$ref\": \"#/definitions/MarketArray\"\r\n            }\r\n          },\r\n          \"required\": [ \"AllowedMarkets\" ]\r\n        },\r\n        {\r\n          \"properties\": {\r\n            \"ExcludedMarkets\": {\r\n              \"$ref\": \"#/definitions/MarketArray\"\r\n            }\r\n          },\r\n          \"required\": [ \"ExcludedMarkets\" ]\r\n        }\r\n      ]\r\n    },\r\n    \"InstallerAbortsTerminal\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer will abort terminal. Default is false\"\r\n    },\r\n    \"ReleaseDate\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"format\": \"date\",\r\n      \"description\": \"The installer release date\"\r\n    },\r\n    \"InstallLocationRequired\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer requires an install location provided\"\r\n    },\r\n    \"RequireExplicitUpgrade\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer should be pinned by default from upgrade\"\r\n    },\r\n    \"DisplayInstallWarnings\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications.\"\r\n    },\r\n    \"UnsupportedOSArchitectures\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"title\": \"UnsupportedOSArchitecture\",\r\n        \"enum\": [\r\n          \"x86\",\r\n          \"x64\",\r\n          \"arm\",\r\n          \"arm64\"\r\n        ]\r\n      },\r\n      \"description\": \"List of OS architectures the installer does not support\"\r\n    },\r\n    \"UnsupportedArguments\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"title\": \"UnsupportedArgument\",\r\n        \"enum\": [\r\n          \"log\",\r\n          \"location\"\r\n        ]\r\n      },\r\n      \"description\": \"List of winget arguments the installer does not support\"\r\n    },\r\n    \"AppsAndFeaturesEntry\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DisplayName\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 256,\r\n          \"description\": \"The DisplayName registry value\"\r\n        },\r\n        \"Publisher\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 256,\r\n          \"description\": \"The Publisher registry value\"\r\n        },\r\n        \"DisplayVersion\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 128,\r\n          \"description\": \"The DisplayVersion registry value\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"UpgradeCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        }\r\n      },\r\n      \"description\": \"Various key values under installer's ARP entry\"\r\n    },\r\n    \"AppsAndFeaturesEntries\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"maxItems\": 128,\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/AppsAndFeaturesEntry\"\r\n      },\r\n      \"description\": \"List of ARP entries.\"\r\n    },\r\n    \"ElevationRequirement\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"elevationRequired\",\r\n        \"elevationProhibited\",\r\n        \"elevatesSelf\"\r\n      ],\r\n      \"description\": \"The installer's elevation requirement\"\r\n    },\r\n    \"InstallationMetadata\": {\r\n      \"type\": \"object\",\r\n      \"title\": \"InstallationMetadata\",\r\n      \"properties\": {\r\n        \"DefaultInstallLocation\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 2048,\r\n          \"description\": \"Represents the default installed package location. Used for deeper installation detection.\"\r\n        },\r\n        \"Files\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"uniqueItems\": true,\r\n          \"maxItems\": 2048,\r\n          \"items\": {\r\n            \"type\": \"object\",\r\n            \"title\": \"InstalledFile\",\r\n            \"properties\": {\r\n              \"RelativeFilePath\": {\r\n                \"type\": \"string\",\r\n                \"minLength\": 1,\r\n                \"maxLength\": 2048,\r\n                \"description\": \"The relative path to the installed file.\"\r\n              },\r\n              \"FileSha256\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n                \"description\": \"Optional Sha256 of the installed file.\"\r\n              },\r\n              \"FileType\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"enum\": [\r\n                  \"launch\",\r\n                  \"uninstall\",\r\n                  \"other\"\r\n                ],\r\n                \"description\": \"The optional installed file type. If not specified, the file is treated as other.\"\r\n              },\r\n              \"InvocationParameter\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"minLength\": 1,\r\n                \"maxLength\": 2048,\r\n                \"description\": \"Optional parameter for invocable files.\"\r\n              },\r\n              \"DisplayName\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"minLength\": 1,\r\n                \"maxLength\": 256,\r\n                \"description\": \"Optional display name for invocable files.\"\r\n              }\r\n            },\r\n            \"required\": [ \"RelativeFilePath\" ],\r\n            \"description\": \"Represents an installed file.\"\r\n          },\r\n          \"description\": \"List of installed files.\"\r\n        }\r\n      },\r\n      \"description\": \"Details about the installation. Used for deeper installation detection.\"\r\n    },\r\n    \"Installer\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"InstallerLocale\": {\r\n          \"$ref\": \"#/definitions/Locale\"\r\n        },\r\n        \"Platform\": {\r\n          \"$ref\": \"#/definitions/Platform\"\r\n        },\r\n        \"MinimumOSVersion\": {\r\n          \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n        },\r\n        \"Architecture\": {\r\n          \"$ref\": \"#/definitions/Architecture\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        },\r\n        \"NestedInstallerType\": {\r\n          \"$ref\": \"#/definitions/NestedInstallerType\"\r\n        },\r\n        \"NestedInstallerFiles\": {\r\n          \"$ref\": \"#/definitions/NestedInstallerFiles\"\r\n        },\r\n        \"Scope\": {\r\n          \"$ref\": \"#/definitions/Scope\"\r\n        },\r\n        \"InstallerUrl\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n          \"maxLength\": 2048,\r\n          \"description\": \"The installer Url\"\r\n        },\r\n        \"InstallerSha256\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"Sha256 is required. Sha256 of the installer\"\r\n        },\r\n        \"SignatureSha256\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable\"\r\n        },\r\n        \"InstallModes\": {\r\n          \"$ref\": \"#/definitions/InstallModes\"\r\n        },\r\n        \"InstallerSwitches\": {\r\n          \"$ref\": \"#/definitions/InstallerSwitches\"\r\n        },\r\n        \"InstallerSuccessCodes\": {\r\n          \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n        },\r\n        \"ExpectedReturnCodes\": {\r\n          \"$ref\": \"#/definitions/ExpectedReturnCodes\"\r\n        },\r\n        \"UpgradeBehavior\": {\r\n          \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n        },\r\n        \"Commands\": {\r\n          \"$ref\": \"#/definitions/Commands\"\r\n        },\r\n        \"Protocols\": {\r\n          \"$ref\": \"#/definitions/Protocols\"\r\n        },\r\n        \"FileExtensions\": {\r\n          \"$ref\": \"#/definitions/FileExtensions\"\r\n        },\r\n        \"Dependencies\": {\r\n          \"$ref\": \"#/definitions/Dependencies\"\r\n        },\r\n        \"PackageFamilyName\": {\r\n          \"$ref\": \"#/definitions/PackageFamilyName\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"Capabilities\": {\r\n          \"$ref\": \"#/definitions/Capabilities\"\r\n        },\r\n        \"RestrictedCapabilities\": {\r\n          \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n        },\r\n        \"Markets\": {\r\n          \"$ref\": \"#/definitions/Markets\"\r\n        },\r\n        \"InstallerAbortsTerminal\": {\r\n          \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\r\n        },\r\n        \"ReleaseDate\": {\r\n          \"$ref\": \"#/definitions/ReleaseDate\"\r\n        },\r\n        \"InstallLocationRequired\": {\r\n          \"$ref\": \"#/definitions/InstallLocationRequired\"\r\n        },\r\n        \"RequireExplicitUpgrade\": {\r\n          \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\r\n        },\r\n        \"DisplayInstallWarnings\": {\r\n          \"$ref\": \"#/definitions/DisplayInstallWarnings\"\r\n        },\r\n        \"UnsupportedOSArchitectures\": {\r\n          \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\r\n        },\r\n        \"UnsupportedArguments\": {\r\n          \"$ref\": \"#/definitions/UnsupportedArguments\"\r\n        },\r\n        \"AppsAndFeaturesEntries\": {\r\n          \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\r\n        },\r\n        \"ElevationRequirement\": {\r\n          \"$ref\": \"#/definitions/ElevationRequirement\"\r\n        },\r\n        \"InstallationMetadata\": {\r\n          \"$ref\": \"#/definitions/InstallationMetadata\"\r\n        }\r\n      },\r\n      \"required\": [\r\n        \"Architecture\",\r\n        \"InstallerUrl\",\r\n        \"InstallerSha256\"\r\n      ]\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"$ref\": \"#/definitions/PackageIdentifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"$ref\": \"#/definitions/PackageVersion\"\r\n    },\r\n    \"Channel\": {\r\n      \"$ref\": \"#/definitions/Channel\"\r\n    },\r\n    \"InstallerLocale\": {\r\n      \"$ref\": \"#/definitions/Locale\"\r\n    },\r\n    \"Platform\": {\r\n      \"$ref\": \"#/definitions/Platform\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"$ref\": \"#/definitions/InstallerType\"\r\n    },\r\n    \"NestedInstallerType\": {\r\n      \"$ref\": \"#/definitions/NestedInstallerType\"\r\n    },\r\n    \"NestedInstallerFiles\": {\r\n      \"$ref\": \"#/definitions/NestedInstallerFiles\"\r\n    },\r\n    \"Scope\": {\r\n      \"$ref\": \"#/definitions/Scope\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"$ref\": \"#/definitions/InstallModes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"$ref\": \"#/definitions/InstallerSwitches\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n    },\r\n    \"ExpectedReturnCodes\": {\r\n      \"$ref\": \"#/definitions/ExpectedReturnCodes\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n    },\r\n    \"Commands\": {\r\n      \"$ref\": \"#/definitions/Commands\"\r\n    },\r\n    \"Protocols\": {\r\n      \"$ref\": \"#/definitions/Protocols\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"$ref\": \"#/definitions/FileExtensions\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"$ref\": \"#/definitions/Dependencies\"\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"$ref\": \"#/definitions/PackageFamilyName\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"$ref\": \"#/definitions/ProductCode\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"$ref\": \"#/definitions/Capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n    },\r\n    \"Markets\": {\r\n      \"$ref\": \"#/definitions/Markets\"\r\n    },\r\n    \"InstallerAbortsTerminal\": {\r\n      \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\r\n    },\r\n    \"ReleaseDate\": {\r\n      \"$ref\": \"#/definitions/ReleaseDate\"\r\n    },\r\n    \"InstallLocationRequired\": {\r\n      \"$ref\": \"#/definitions/InstallLocationRequired\"\r\n    },\r\n    \"RequireExplicitUpgrade\": {\r\n      \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\r\n    },\r\n    \"DisplayInstallWarnings\": {\r\n      \"$ref\": \"#/definitions/DisplayInstallWarnings\"\r\n    },\r\n    \"UnsupportedOSArchitectures\": {\r\n      \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\r\n    },\r\n    \"UnsupportedArguments\": {\r\n      \"$ref\": \"#/definitions/UnsupportedArguments\"\r\n    },\r\n    \"AppsAndFeaturesEntries\": {\r\n      \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\r\n    },\r\n    \"ElevationRequirement\": {\r\n      \"$ref\": \"#/definitions/ElevationRequirement\"\r\n    },\r\n    \"InstallationMetadata\": {\r\n      \"$ref\": \"#/definitions/InstallationMetadata\"\r\n    },\r\n    \"Installers\": {\r\n      \"type\": \"array\",\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Installer\"\r\n      },\r\n      \"minItems\": 1,\r\n      \"maxItems\": 1024\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"installer\",\r\n      \"const\": \"installer\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.4.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"Installers\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}\r\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.4.0/manifest.locale.1.4.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.locale.1.4.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a multiple-file manifest representing app metadata in other locale in the OWC. v1.4.0\",\r\n  \"definitions\": {\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Optional Url type\"\r\n    },\r\n    \"Tag\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 40,\r\n      \"description\": \"Package tag\"\r\n    },\r\n    \"Agreement\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"AgreementLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\r\n        },\r\n        \"Agreement\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 10000,\r\n          \"description\": \"The agreement text content.\"\r\n        },\r\n        \"AgreementUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The agreement URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Documentation\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DocumentLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\r\n        },\r\n        \"DocumentUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The documentation URL.\"\r\n        }\r\n      }\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"PackageLocale\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The package meta-data locale\"\r\n    },\r\n    \"Publisher\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The publisher name\"\r\n    },\r\n    \"PublisherUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher home page\"\r\n    },\r\n    \"PublisherSupportUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher support page\"\r\n    },\r\n    \"PrivacyUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher privacy page or the package privacy page\"\r\n    },\r\n    \"Author\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package author\"\r\n    },\r\n    \"PackageName\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package name\"\r\n    },\r\n    \"PackageUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package home page\"\r\n    },\r\n    \"License\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package license\"\r\n    },\r\n    \"LicenseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The license page\"\r\n    },\r\n    \"Copyright\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package copyright\"\r\n    },\r\n    \"CopyrightUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package copyright page\"\r\n    },\r\n    \"ShortDescription\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The short package description\"\r\n    },\r\n    \"Description\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The full package description\"\r\n    },\r\n    \"Tags\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Tag\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional package search terms\"\r\n    },\r\n    \"Agreements\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Agreement\"\r\n      },\r\n      \"maxItems\": 128\r\n    },\r\n    \"ReleaseNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The package release notes\"\r\n    },\r\n    \"ReleaseNotesUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package release notes url\"\r\n    },\r\n    \"PurchaseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\r\n    },\r\n    \"InstallationNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"\r\n    },\r\n    \"Documentations\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Documentation\"\r\n      },\r\n      \"maxItems\": 256\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"locale\",\r\n      \"const\": \"locale\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.4.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"PackageLocale\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}"
  },
  {
    "path": "schemas/JSON/manifests/v1.4.0/manifest.singleton.1.4.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a single-file manifest representing an app in the OWC. v1.4.0\",\r\n  \"definitions\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"Locale\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The package meta-data locale\"\r\n    },\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Optional Url type\"\r\n    },\r\n    \"Tag\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 40,\r\n      \"description\": \"Package moniker or tag\"\r\n    },\r\n    \"Agreement\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"AgreementLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\r\n        },\r\n        \"Agreement\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 10000,\r\n          \"description\": \"The agreement text content.\"\r\n        },\r\n        \"AgreementUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The agreement URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Documentation\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DocumentLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\r\n        },\r\n        \"DocumentUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The documentation URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Channel\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 16,\r\n      \"description\": \"The distribution channel\"\r\n    },\r\n    \"Platform\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"Platform\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"Windows.Desktop\",\r\n          \"Windows.Universal\"\r\n        ]\r\n      },\r\n      \"maxItems\": 2,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"The installer supported operating system\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$\",\r\n      \"description\": \"The installer minimum operating system version\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"msix\",\r\n        \"msi\",\r\n        \"appx\",\r\n        \"exe\",\r\n        \"zip\",\r\n        \"inno\",\r\n        \"nullsoft\",\r\n        \"wix\",\r\n        \"burn\",\r\n        \"pwa\",\r\n        \"portable\"\r\n      ],\r\n      \"description\": \"Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level\"\r\n    },\r\n    \"NestedInstallerType\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"msix\",\r\n        \"msi\",\r\n        \"appx\",\r\n        \"exe\",\r\n        \"inno\",\r\n        \"nullsoft\",\r\n        \"wix\",\r\n        \"burn\",\r\n        \"portable\"\r\n      ],\r\n      \"description\": \"Enumeration of supported nested installer types contained inside an archive file\"\r\n    },\r\n    \"NestedInstallerFiles\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"object\",\r\n        \"title\": \"NestedInstallerFile\",\r\n        \"properties\": {\r\n          \"RelativeFilePath\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 512,\r\n            \"description\": \"The relative path to the nested installer file\"\r\n          },\r\n          \"PortableCommandAlias\": {\r\n            \"type\": [ \"string\", \"null\" ],\r\n            \"minLength\": 1,\r\n            \"maxLength\": 40,\r\n            \"description\": \"The command alias to be used for calling the package. Only applies to the nested portable package\"\r\n          }\r\n        },\r\n        \"required\": [ \"RelativeFilePath\" ],\r\n        \"description\": \"A nested installer file contained inside an archive\"\r\n      },\r\n      \"maxItems\": 1024,\r\n      \"description\": \"List of nested installer files contained inside an archive\"\r\n    },\r\n    \"Architecture\": {\r\n      \"type\": \"string\",\r\n      \"enum\": [\r\n        \"x86\",\r\n        \"x64\",\r\n        \"arm\",\r\n        \"arm64\",\r\n        \"neutral\"\r\n      ],\r\n      \"description\": \"The installer target architecture\"\r\n    },\r\n    \"Scope\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"user\",\r\n        \"machine\"\r\n      ],\r\n      \"description\": \"Scope indicates if the installer is per user or per machine\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"InstallModes\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"interactive\",\r\n          \"silent\",\r\n          \"silentWithProgress\"\r\n        ]\r\n      },\r\n      \"maxItems\": 3,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of supported installer modes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"Silent\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Silent is the value that should be passed to the installer when user chooses a silent or quiet install\"\r\n        },\r\n        \"SilentWithProgress\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install\"\r\n        },\r\n        \"Interactive\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Interactive is the value that should be passed to the installer when user chooses an interactive install\"\r\n        },\r\n        \"InstallLocation\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"InstallLocation is the value passed to the installer for custom install location. <INSTALLPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Log\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Log is the value passed to the installer for custom log file path. <LOGPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Upgrade\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Upgrade is the value that should be passed to the installer when user chooses an upgrade\"\r\n        },\r\n        \"Custom\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 2048,\r\n          \"description\": \"Custom switches will be passed directly to the installer by winget\"\r\n        }\r\n      }\r\n    },\r\n    \"InstallerReturnCode\": {\r\n      \"type\": \"integer\",\r\n      \"format\": \"long\",\r\n      \"not\": {\r\n        \"enum\": [ 0 ]\r\n      },\r\n      \"minimum\": -2147483648,\r\n      \"maximum\": 4294967295,\r\n      \"description\": \"An exit code that can be returned by the installer after execution\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/InstallerReturnCode\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional non-zero installer success exit codes other than known default values by winget\"\r\n    },\r\n    \"ExpectedReturnCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"object\",\r\n        \"title\": \"ExpectedReturnCode\",\r\n        \"properties\": {\r\n          \"InstallerReturnCode\": {\r\n            \"$ref\": \"#/definitions/InstallerReturnCode\"\r\n          },\r\n          \"ReturnResponse\": {\r\n            \"type\": \"string\",\r\n            \"enum\": [\r\n              \"packageInUse\",\r\n              \"packageInUseByApplication\",\r\n              \"installInProgress\",\r\n              \"fileInUse\",\r\n              \"missingDependency\",\r\n              \"diskFull\",\r\n              \"insufficientMemory\",\r\n              \"invalidParameter\",\r\n              \"noNetwork\",\r\n              \"contactSupport\",\r\n              \"rebootRequiredToFinish\",\r\n              \"rebootRequiredForInstall\",\r\n              \"rebootInitiated\",\r\n              \"cancelledByUser\",\r\n              \"alreadyInstalled\",\r\n              \"downgrade\",\r\n              \"blockedByPolicy\",\r\n              \"systemNotSupported\",\r\n              \"custom\"\r\n            ]\r\n          },\r\n          \"ReturnResponseUrl\": {\r\n            \"$ref\": \"#/definitions/Url\",\r\n            \"description\": \"The return response url to provide additional guidance for expected return codes\"\r\n          }\r\n        },\r\n        \"required\": [ \"InstallerReturnCode\", \"ReturnResponse\" ]\r\n      },\r\n      \"maxItems\": 128,\r\n      \"description\": \"Installer exit codes for common errors\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"install\",\r\n        \"uninstallPrevious\"\r\n      ],\r\n      \"description\": \"The upgrade method\"\r\n    },\r\n    \"Commands\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of commands or aliases to run the package\"\r\n    },\r\n    \"Protocols\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"maxLength\": 2048\r\n      },\r\n      \"maxItems\": 64,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of protocols the package provides a handler for\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n        \"maxLength\": 64\r\n      },\r\n      \"maxItems\": 512,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of file extensions the package could support\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"properties\": {\r\n        \"WindowsFeatures\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows feature dependencies\"\r\n        },\r\n        \"WindowsLibraries\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows library dependencies\"\r\n        },\r\n        \"PackageDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"object\",\r\n            \"properties\": {\r\n              \"PackageIdentifier\": {\r\n                \"$ref\": \"#/definitions/PackageIdentifier\"\r\n              },\r\n              \"MinimumVersion\": {\r\n                \"$ref\": \"#/definitions/PackageVersion\"\r\n              }\r\n            },\r\n            \"required\": [ \"PackageIdentifier\" ]\r\n          },\r\n          \"maxItems\": 16,\r\n          \"description\": \"List of package dependencies from current source\"\r\n        },\r\n        \"ExternalDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of external package dependencies\"\r\n        }\r\n      }\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^[A-Za-z0-9][-\\\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$\",\r\n      \"maxLength\": 255,\r\n      \"description\": \"PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 255,\r\n      \"description\": \"ProductCode could be used for correlation of packages across sources\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer restricted capabilities\"\r\n    },\r\n    \"Market\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[A-Z]{2}$\",\r\n      \"description\": \"The installer target market\"\r\n    },\r\n    \"MarketArray\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"maxItems\": 256,\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Market\"\r\n      },\r\n      \"description\": \"Array of markets\"\r\n    },\r\n    \"Markets\": {\r\n      \"description\": \"The installer markets\",\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"oneOf\": [\r\n        {\r\n          \"properties\": {\r\n            \"AllowedMarkets\": {\r\n              \"$ref\": \"#/definitions/MarketArray\"\r\n            }\r\n          },\r\n          \"required\": [ \"AllowedMarkets\" ]\r\n        },\r\n        {\r\n          \"properties\": {\r\n            \"ExcludedMarkets\": {\r\n              \"$ref\": \"#/definitions/MarketArray\"\r\n            }\r\n          },\r\n          \"required\": [ \"ExcludedMarkets\" ]\r\n        }\r\n      ]\r\n    },\r\n    \"InstallerAbortsTerminal\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer will abort terminal. Default is false\"\r\n    },\r\n    \"ReleaseDate\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"format\": \"date\",\r\n      \"description\": \"The installer release date\"\r\n    },\r\n    \"InstallLocationRequired\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer requires an install location provided\"\r\n    },\r\n    \"RequireExplicitUpgrade\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer should be pinned by default from upgrade\"\r\n    },\r\n    \"DisplayInstallWarnings\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications.\"\r\n    },\r\n    \"UnsupportedOSArchitectures\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"title\": \"UnsupportedOSArchitecture\",\r\n        \"enum\": [\r\n          \"x86\",\r\n          \"x64\",\r\n          \"arm\",\r\n          \"arm64\"\r\n        ]\r\n      },\r\n      \"description\": \"List of OS architectures the installer does not support\"\r\n    },\r\n    \"UnsupportedArguments\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"title\": \"UnsupportedArgument\",\r\n        \"enum\": [\r\n          \"log\",\r\n          \"location\"\r\n        ]\r\n      },\r\n      \"description\": \"List of winget arguments the installer does not support\"\r\n    },\r\n    \"AppsAndFeaturesEntry\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DisplayName\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 256,\r\n          \"description\": \"The DisplayName registry value\"\r\n        },\r\n        \"Publisher\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 256,\r\n          \"description\": \"The Publisher registry value\"\r\n        },\r\n        \"DisplayVersion\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 128,\r\n          \"description\": \"The DisplayVersion registry value\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"UpgradeCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        }\r\n      },\r\n      \"description\": \"Various key values under installer's ARP entry\"\r\n    },\r\n    \"AppsAndFeaturesEntries\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"maxItems\": 128,\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/AppsAndFeaturesEntry\"\r\n      },\r\n      \"description\": \"List of ARP entries.\"\r\n    },\r\n    \"ElevationRequirement\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"elevationRequired\",\r\n        \"elevationProhibited\",\r\n        \"elevatesSelf\"\r\n      ],\r\n      \"description\": \"The installer's elevation requirement\"\r\n    },\r\n    \"InstallationMetadata\": {\r\n      \"type\": \"object\",\r\n      \"title\": \"InstallationMetadata\",\r\n      \"properties\": {\r\n        \"DefaultInstallLocation\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 2048,\r\n          \"description\": \"Represents the default installed package location. Used for deeper installation detection.\"\r\n        },\r\n        \"Files\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"uniqueItems\": true,\r\n          \"maxItems\": 2048,\r\n          \"items\": {\r\n            \"type\": \"object\",\r\n            \"title\": \"InstalledFile\",\r\n            \"properties\": {\r\n              \"RelativeFilePath\": {\r\n                \"type\": \"string\",\r\n                \"minLength\": 1,\r\n                \"maxLength\": 2048,\r\n                \"description\": \"The relative path to the installed file.\"\r\n              },\r\n              \"FileSha256\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n                \"description\": \"Optional Sha256 of the installed file.\"\r\n              },\r\n              \"FileType\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"enum\": [\r\n                  \"launch\",\r\n                  \"uninstall\",\r\n                  \"other\"\r\n                ],\r\n                \"description\": \"The optional installed file type. If not specified, the file is treated as other.\"\r\n              },\r\n              \"InvocationParameter\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"minLength\": 1,\r\n                \"maxLength\": 2048,\r\n                \"description\": \"Optional parameter for invocable files.\"\r\n              },\r\n              \"DisplayName\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"minLength\": 1,\r\n                \"maxLength\": 256,\r\n                \"description\": \"Optional display name for invocable files.\"\r\n              }\r\n            },\r\n            \"required\": [ \"RelativeFilePath\" ],\r\n            \"description\": \"Represents an installed file.\"\r\n          },\r\n          \"description\": \"List of installed files.\"\r\n        }\r\n      },\r\n      \"description\": \"Details about the installation. Used for deeper installation detection.\"\r\n    },\r\n    \"Installer\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"InstallerLocale\": {\r\n          \"$ref\": \"#/definitions/Locale\"\r\n        },\r\n        \"Platform\": {\r\n          \"$ref\": \"#/definitions/Platform\"\r\n        },\r\n        \"MinimumOSVersion\": {\r\n          \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n        },\r\n        \"Architecture\": {\r\n          \"$ref\": \"#/definitions/Architecture\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        },\r\n        \"NestedInstallerType\": {\r\n          \"$ref\": \"#/definitions/NestedInstallerType\"\r\n        },\r\n        \"NestedInstallerFiles\": {\r\n          \"$ref\": \"#/definitions/NestedInstallerFiles\"\r\n        },\r\n        \"Scope\": {\r\n          \"$ref\": \"#/definitions/Scope\"\r\n        },\r\n        \"InstallerUrl\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n          \"maxLength\": 2048,\r\n          \"description\": \"The installer Url\"\r\n        },\r\n        \"InstallerSha256\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"Sha256 is required. Sha256 of the installer\"\r\n        },\r\n        \"SignatureSha256\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable\"\r\n        },\r\n        \"InstallModes\": {\r\n          \"$ref\": \"#/definitions/InstallModes\"\r\n        },\r\n        \"InstallerSwitches\": {\r\n          \"$ref\": \"#/definitions/InstallerSwitches\"\r\n        },\r\n        \"InstallerSuccessCodes\": {\r\n          \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n        },\r\n        \"ExpectedReturnCodes\": {\r\n          \"$ref\": \"#/definitions/ExpectedReturnCodes\"\r\n        },\r\n        \"UpgradeBehavior\": {\r\n          \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n        },\r\n        \"Commands\": {\r\n          \"$ref\": \"#/definitions/Commands\"\r\n        },\r\n        \"Protocols\": {\r\n          \"$ref\": \"#/definitions/Protocols\"\r\n        },\r\n        \"FileExtensions\": {\r\n          \"$ref\": \"#/definitions/FileExtensions\"\r\n        },\r\n        \"Dependencies\": {\r\n          \"$ref\": \"#/definitions/Dependencies\"\r\n        },\r\n        \"PackageFamilyName\": {\r\n          \"$ref\": \"#/definitions/PackageFamilyName\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"Capabilities\": {\r\n          \"$ref\": \"#/definitions/Capabilities\"\r\n        },\r\n        \"RestrictedCapabilities\": {\r\n          \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n        },\r\n        \"Markets\": {\r\n          \"$ref\": \"#/definitions/Markets\"\r\n        },\r\n        \"InstallerAbortsTerminal\": {\r\n          \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\r\n        },\r\n        \"ReleaseDate\": {\r\n          \"$ref\": \"#/definitions/ReleaseDate\"\r\n        },\r\n        \"InstallLocationRequired\": {\r\n          \"$ref\": \"#/definitions/InstallLocationRequired\"\r\n        },\r\n        \"RequireExplicitUpgrade\": {\r\n          \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\r\n        },\r\n        \"DisplayInstallWarnings\": {\r\n          \"$ref\": \"#/definitions/DisplayInstallWarnings\"\r\n        },\r\n        \"UnsupportedOSArchitectures\": {\r\n          \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\r\n        },\r\n        \"UnsupportedArguments\": {\r\n          \"$ref\": \"#/definitions/UnsupportedArguments\"\r\n        },\r\n        \"AppsAndFeaturesEntries\": {\r\n          \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\r\n        },\r\n        \"ElevationRequirement\": {\r\n          \"$ref\": \"#/definitions/ElevationRequirement\"\r\n        },\r\n        \"InstallationMetadata\": {\r\n          \"$ref\": \"#/definitions/InstallationMetadata\"\r\n        }\r\n      },\r\n      \"required\": [\r\n        \"Architecture\",\r\n        \"InstallerUrl\",\r\n        \"InstallerSha256\"\r\n      ]\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"$ref\": \"#/definitions/PackageIdentifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"$ref\": \"#/definitions/PackageVersion\"\r\n    },\r\n    \"PackageLocale\": {\r\n      \"$ref\": \"#/definitions/Locale\"\r\n    },\r\n    \"Publisher\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The publisher name\"\r\n    },\r\n    \"PublisherUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher home page\"\r\n    },\r\n    \"PublisherSupportUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher support page\"\r\n    },\r\n    \"PrivacyUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher privacy page or the package privacy page\"\r\n    },\r\n    \"Author\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package author\"\r\n    },\r\n    \"PackageName\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package name\"\r\n    },\r\n    \"PackageUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package home page\"\r\n    },\r\n    \"License\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package license\"\r\n    },\r\n    \"LicenseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The license page\"\r\n    },\r\n    \"Copyright\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package copyright\"\r\n    },\r\n    \"CopyrightUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package copyright page\"\r\n    },\r\n    \"ShortDescription\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The short package description\"\r\n    },\r\n    \"Description\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The full package description\"\r\n    },\r\n    \"Moniker\": {\r\n      \"$ref\": \"#/definitions/Tag\",\r\n      \"description\": \"The most common package term\"\r\n    },\r\n    \"Tags\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Tag\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional package search terms\"\r\n    },\r\n    \"Agreements\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Agreement\"\r\n      },\r\n      \"maxItems\": 128\r\n    },\r\n    \"ReleaseNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The package release notes\"\r\n    },\r\n    \"ReleaseNotesUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package release notes url\"\r\n    },\r\n    \"PurchaseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\r\n    },\r\n    \"InstallationNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"\r\n    },\r\n    \"Documentations\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Documentation\"\r\n      },\r\n      \"maxItems\": 256\r\n    },\r\n    \"Channel\": {\r\n      \"$ref\": \"#/definitions/Channel\"\r\n    },\r\n    \"InstallerLocale\": {\r\n      \"$ref\": \"#/definitions/Locale\"\r\n    },\r\n    \"Platform\": {\r\n      \"$ref\": \"#/definitions/Platform\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"$ref\": \"#/definitions/InstallerType\"\r\n    },\r\n    \"NestedInstallerType\": {\r\n      \"$ref\": \"#/definitions/NestedInstallerType\"\r\n    },\r\n    \"NestedInstallerFiles\": {\r\n      \"$ref\": \"#/definitions/NestedInstallerFiles\"\r\n    },\r\n    \"Scope\": {\r\n      \"$ref\": \"#/definitions/Scope\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"$ref\": \"#/definitions/InstallModes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"$ref\": \"#/definitions/InstallerSwitches\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n    },\r\n    \"ExpectedReturnCodes\": {\r\n      \"$ref\": \"#/definitions/ExpectedReturnCodes\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n    },\r\n    \"Commands\": {\r\n      \"$ref\": \"#/definitions/Commands\"\r\n    },\r\n    \"Protocols\": {\r\n      \"$ref\": \"#/definitions/Protocols\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"$ref\": \"#/definitions/FileExtensions\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"$ref\": \"#/definitions/Dependencies\"\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"$ref\": \"#/definitions/PackageFamilyName\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"$ref\": \"#/definitions/ProductCode\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"$ref\": \"#/definitions/Capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n    },\r\n    \"Markets\": {\r\n      \"$ref\": \"#/definitions/Markets\"\r\n    },\r\n    \"InstallerAbortsTerminal\": {\r\n      \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\r\n    },\r\n    \"ReleaseDate\": {\r\n      \"$ref\": \"#/definitions/ReleaseDate\"\r\n    },\r\n    \"InstallLocationRequired\": {\r\n      \"$ref\": \"#/definitions/InstallLocationRequired\"\r\n    },\r\n    \"RequireExplicitUpgrade\": {\r\n      \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\r\n    },\r\n    \"DisplayInstallWarnings\": {\r\n      \"$ref\": \"#/definitions/DisplayInstallWarnings\"\r\n    },\r\n    \"UnsupportedOSArchitectures\": {\r\n      \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\r\n    },\r\n    \"UnsupportedArguments\": {\r\n      \"$ref\": \"#/definitions/UnsupportedArguments\"\r\n    },\r\n    \"AppsAndFeaturesEntries\": {\r\n      \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\r\n    },\r\n    \"ElevationRequirement\": {\r\n      \"$ref\": \"#/definitions/ElevationRequirement\"\r\n    },\r\n    \"InstallationMetadata\": {\r\n      \"$ref\": \"#/definitions/InstallationMetadata\"\r\n    },\r\n    \"Installers\": {\r\n      \"type\": \"array\",\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Installer\"\r\n      },\r\n      \"minItems\": 1,\r\n      \"maxItems\": 1\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"singleton\",\r\n      \"const\": \"singleton\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.4.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"PackageLocale\",\r\n    \"Publisher\",\r\n    \"PackageName\",\r\n    \"License\",\r\n    \"ShortDescription\",\r\n    \"Installers\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}\r\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.4.0/manifest.version.1.4.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.version.1.4.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a multi-file manifest representing an app version in the OWC. v1.4.0\",\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"DefaultLocale\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"en-US\",\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The default package meta-data locale\"\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"version\",\r\n      \"const\": \"version\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.4.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"DefaultLocale\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}"
  },
  {
    "path": "schemas/JSON/manifests/v1.5.0/manifest.defaultLocale.1.5.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.defaultlocale.1.5.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a multiple-file manifest representing a default app metadata in the OWC. v1.5.0\",\r\n  \"definitions\": {\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Optional Url type\"\r\n    },\r\n    \"Tag\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 40,\r\n      \"description\": \"Package moniker or tag\"\r\n    },\r\n    \"Agreement\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"AgreementLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\r\n        },\r\n        \"Agreement\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 10000,\r\n          \"description\": \"The agreement text content.\"\r\n        },\r\n        \"AgreementUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The agreement URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Documentation\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DocumentLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\r\n        },\r\n        \"DocumentUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The documentation URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Icon\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"IconUrl\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n          \"maxLength\": 2048,\r\n          \"description\": \"The url of the hosted icon file\"\r\n        },\r\n        \"IconFileType\": {\r\n          \"type\": \"string\",\r\n          \"enum\": [\r\n            \"png\",\r\n            \"jpeg\",\r\n            \"ico\"\r\n          ],\r\n          \"description\": \"The icon file type\"\r\n        },\r\n        \"IconResolution\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"enum\": [\r\n            \"custom\",\r\n            \"16x16\",\r\n            \"20x20\",\r\n            \"24x24\",\r\n            \"30x30\",\r\n            \"32x32\",\r\n            \"36x36\",\r\n            \"40x40\",\r\n            \"48x48\",\r\n            \"60x60\",\r\n            \"64x64\",\r\n            \"72x72\",\r\n            \"80x80\",\r\n            \"96x96\",\r\n            \"256x256\"\r\n          ],\r\n          \"description\": \"Optional icon resolution\"\r\n        },\r\n        \"IconTheme\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"enum\": [\r\n            \"default\",\r\n            \"light\",\r\n            \"dark\",\r\n            \"highContrast\"\r\n          ],\r\n          \"description\": \"Optional icon theme\"\r\n        },\r\n        \"IconSha256\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"Optional Sha256 of the icon file\"\r\n        }\r\n      },\r\n      \"required\": [\r\n        \"IconUrl\",\r\n        \"IconFileType\"\r\n      ]\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"PackageLocale\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"en-US\",\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The package meta-data locale\"\r\n    },\r\n    \"Publisher\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The publisher name\"\r\n    },\r\n    \"PublisherUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher home page\"\r\n    },\r\n    \"PublisherSupportUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher support page\"\r\n    },\r\n    \"PrivacyUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher privacy page or the package privacy page\"\r\n    },\r\n    \"Author\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package author\"\r\n    },\r\n    \"PackageName\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package name\"\r\n    },\r\n    \"PackageUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package home page\"\r\n    },\r\n    \"License\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package license\"\r\n    },\r\n    \"LicenseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The license page\"\r\n    },\r\n    \"Copyright\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package copyright\"\r\n    },\r\n    \"CopyrightUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package copyright page\"\r\n    },\r\n    \"ShortDescription\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The short package description\"\r\n    },\r\n    \"Description\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The full package description\"\r\n    },\r\n    \"Moniker\": {\r\n      \"$ref\": \"#/definitions/Tag\",\r\n      \"description\": \"The most common package term\"\r\n    },\r\n    \"Tags\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Tag\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional package search terms\"\r\n    },\r\n    \"Agreements\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Agreement\"\r\n      },\r\n      \"maxItems\": 128\r\n    },\r\n    \"ReleaseNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The package release notes\"\r\n    },\r\n    \"ReleaseNotesUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package release notes url\"\r\n    },\r\n    \"PurchaseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\r\n    },\r\n    \"InstallationNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"\r\n    },\r\n    \"Documentations\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Documentation\"\r\n      },\r\n      \"maxItems\": 256\r\n    },\r\n    \"Icons\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Icon\"\r\n      },\r\n      \"maxItems\": 1024\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"defaultLocale\",\r\n      \"const\": \"defaultLocale\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.5.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"PackageLocale\",\r\n    \"Publisher\",\r\n    \"PackageName\",\r\n    \"License\",\r\n    \"ShortDescription\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}\r\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.5.0/manifest.installer.1.5.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.installer.1.5.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a single-file manifest representing an app installers in the OWC. v1.5.0\",\r\n  \"definitions\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"Locale\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The installer meta-data locale\"\r\n    },\r\n    \"Channel\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 16,\r\n      \"description\": \"The distribution channel\"\r\n    },\r\n    \"Platform\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"Platform\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"Windows.Desktop\",\r\n          \"Windows.Universal\"\r\n        ]\r\n      },\r\n      \"maxItems\": 2,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"The installer supported operating system\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$\",\r\n      \"description\": \"The installer minimum operating system version\"\r\n    },\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Url type\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"msix\",\r\n        \"msi\",\r\n        \"appx\",\r\n        \"exe\",\r\n        \"zip\",\r\n        \"inno\",\r\n        \"nullsoft\",\r\n        \"wix\",\r\n        \"burn\",\r\n        \"pwa\",\r\n        \"portable\"\r\n      ],\r\n      \"description\": \"Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level\"\r\n    },\r\n    \"NestedInstallerType\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"msix\",\r\n        \"msi\",\r\n        \"appx\",\r\n        \"exe\",\r\n        \"inno\",\r\n        \"nullsoft\",\r\n        \"wix\",\r\n        \"burn\",\r\n        \"portable\"\r\n      ],\r\n      \"description\": \"Enumeration of supported nested installer types contained inside an archive file\"\r\n    },\r\n    \"NestedInstallerFiles\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"object\",\r\n        \"title\": \"NestedInstallerFile\",\r\n        \"properties\": {\r\n          \"RelativeFilePath\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 512,\r\n            \"description\": \"The relative path to the nested installer file\"\r\n          },\r\n          \"PortableCommandAlias\": {\r\n            \"type\": [ \"string\", \"null\" ],\r\n            \"minLength\": 1,\r\n            \"maxLength\": 40,\r\n            \"description\": \"The command alias to be used for calling the package. Only applies to the nested portable package\"\r\n          }\r\n        },\r\n        \"required\": [ \"RelativeFilePath\" ],\r\n        \"description\": \"A nested installer file contained inside an archive\"\r\n      },\r\n      \"maxItems\": 1024,\r\n      \"description\": \"List of nested installer files contained inside an archive\"\r\n    },\r\n    \"Architecture\": {\r\n      \"type\": \"string\",\r\n      \"enum\": [\r\n        \"x86\",\r\n        \"x64\",\r\n        \"arm\",\r\n        \"arm64\",\r\n        \"neutral\"\r\n      ],\r\n      \"description\": \"The installer target architecture\"\r\n    },\r\n    \"Scope\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"user\",\r\n        \"machine\"\r\n      ],\r\n      \"description\": \"Scope indicates if the installer is per user or per machine\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"InstallModes\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"interactive\",\r\n          \"silent\",\r\n          \"silentWithProgress\"\r\n        ]\r\n      },\r\n      \"maxItems\": 3,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of supported installer modes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"Silent\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Silent is the value that should be passed to the installer when user chooses a silent or quiet install\"\r\n        },\r\n        \"SilentWithProgress\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install\"\r\n        },\r\n        \"Interactive\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Interactive is the value that should be passed to the installer when user chooses an interactive install\"\r\n        },\r\n        \"InstallLocation\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"InstallLocation is the value passed to the installer for custom install location. <INSTALLPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Log\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Log is the value passed to the installer for custom log file path. <LOGPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Upgrade\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Upgrade is the value that should be passed to the installer when user chooses an upgrade\"\r\n        },\r\n        \"Custom\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 2048,\r\n          \"description\": \"Custom switches will be passed directly to the installer by winget\"\r\n        }\r\n      }\r\n    },\r\n    \"InstallerReturnCode\": {\r\n      \"type\": \"integer\",\r\n      \"format\": \"long\",\r\n      \"not\": {\r\n        \"enum\": [ 0 ]\r\n      },\r\n      \"minimum\": -2147483648,\r\n      \"maximum\": 4294967295,\r\n      \"description\": \"An exit code that can be returned by the installer after execution\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/InstallerReturnCode\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional non-zero installer success exit codes other than known default values by winget\"\r\n    },\r\n    \"ExpectedReturnCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"object\",\r\n        \"title\": \"ExpectedReturnCode\",\r\n        \"properties\": {\r\n          \"InstallerReturnCode\": {\r\n            \"$ref\": \"#/definitions/InstallerReturnCode\"\r\n          },\r\n          \"ReturnResponse\": {\r\n            \"type\": \"string\",\r\n            \"enum\": [\r\n              \"packageInUse\",\r\n              \"packageInUseByApplication\",\r\n              \"installInProgress\",\r\n              \"fileInUse\",\r\n              \"missingDependency\",\r\n              \"diskFull\",\r\n              \"insufficientMemory\",\r\n              \"invalidParameter\",\r\n              \"noNetwork\",\r\n              \"contactSupport\",\r\n              \"rebootRequiredToFinish\",\r\n              \"rebootRequiredForInstall\",\r\n              \"rebootInitiated\",\r\n              \"cancelledByUser\",\r\n              \"alreadyInstalled\",\r\n              \"downgrade\",\r\n              \"blockedByPolicy\",\r\n              \"systemNotSupported\",\r\n              \"custom\"\r\n            ]\r\n          },\r\n          \"ReturnResponseUrl\": {\r\n            \"$ref\": \"#/definitions/Url\",\r\n            \"description\": \"The return response url to provide additional guidance for expected return codes\"\r\n          }\r\n        },\r\n        \"required\": [ \"InstallerReturnCode\", \"ReturnResponse\" ]\r\n      },\r\n      \"maxItems\": 128,\r\n      \"description\": \"Installer exit codes for common errors\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"install\",\r\n        \"uninstallPrevious\"\r\n      ],\r\n      \"description\": \"The upgrade method\"\r\n    },\r\n    \"Commands\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of commands or aliases to run the package\"\r\n    },\r\n    \"Protocols\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"maxLength\": 2048\r\n      },\r\n      \"maxItems\": 64,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of protocols the package provides a handler for\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n        \"maxLength\": 64\r\n      },\r\n      \"maxItems\": 512,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of file extensions the package could support\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"properties\": {\r\n        \"WindowsFeatures\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows feature dependencies\"\r\n        },\r\n        \"WindowsLibraries\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows library dependencies\"\r\n        },\r\n        \"PackageDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"object\",\r\n            \"properties\": {\r\n              \"PackageIdentifier\": {\r\n                \"$ref\": \"#/definitions/PackageIdentifier\"\r\n              },\r\n              \"MinimumVersion\": {\r\n                \"$ref\": \"#/definitions/PackageVersion\"\r\n              }\r\n            },\r\n            \"required\": [ \"PackageIdentifier\" ]\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of package dependencies from current source\"\r\n        },\r\n        \"ExternalDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of external package dependencies\"\r\n        }\r\n      }\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^[A-Za-z0-9][-\\\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$\",\r\n      \"maxLength\": 255,\r\n      \"description\": \"PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 255,\r\n      \"description\": \"ProductCode could be used for correlation of packages across sources\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer restricted capabilities\"\r\n    },\r\n    \"Market\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[A-Z]{2}$\",\r\n      \"description\": \"The installer target market\"\r\n    },\r\n    \"MarketArray\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"maxItems\": 256,\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Market\"\r\n      },\r\n      \"description\": \"Array of markets\"\r\n    },\r\n    \"Markets\": {\r\n      \"description\": \"The installer markets\",\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"oneOf\": [\r\n        {\r\n          \"properties\": {\r\n            \"AllowedMarkets\": {\r\n              \"$ref\": \"#/definitions/MarketArray\"\r\n            }\r\n          },\r\n          \"required\": [ \"AllowedMarkets\" ]\r\n        },\r\n        {\r\n          \"properties\": {\r\n            \"ExcludedMarkets\": {\r\n              \"$ref\": \"#/definitions/MarketArray\"\r\n            }\r\n          },\r\n          \"required\": [ \"ExcludedMarkets\" ]\r\n        }\r\n      ]\r\n    },\r\n    \"InstallerAbortsTerminal\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer will abort terminal. Default is false\"\r\n    },\r\n    \"ReleaseDate\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"format\": \"date\",\r\n      \"description\": \"The installer release date\"\r\n    },\r\n    \"InstallLocationRequired\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer requires an install location provided\"\r\n    },\r\n    \"RequireExplicitUpgrade\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer should be pinned by default from upgrade\"\r\n    },\r\n    \"DisplayInstallWarnings\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications.\"\r\n    },\r\n    \"UnsupportedOSArchitectures\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"title\": \"UnsupportedOSArchitecture\",\r\n        \"enum\": [\r\n          \"x86\",\r\n          \"x64\",\r\n          \"arm\",\r\n          \"arm64\"\r\n        ]\r\n      },\r\n      \"description\": \"List of OS architectures the installer does not support\"\r\n    },\r\n    \"UnsupportedArguments\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"title\": \"UnsupportedArgument\",\r\n        \"enum\": [\r\n          \"log\",\r\n          \"location\"\r\n        ]\r\n      },\r\n      \"description\": \"List of winget arguments the installer does not support\"\r\n    },\r\n    \"AppsAndFeaturesEntry\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DisplayName\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 256,\r\n          \"description\": \"The DisplayName registry value\"\r\n        },\r\n        \"Publisher\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 256,\r\n          \"description\": \"The Publisher registry value\"\r\n        },\r\n        \"DisplayVersion\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 128,\r\n          \"description\": \"The DisplayVersion registry value\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"UpgradeCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        }\r\n      },\r\n      \"description\": \"Various key values under installer's ARP entry\"\r\n    },\r\n    \"AppsAndFeaturesEntries\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"maxItems\": 128,\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/AppsAndFeaturesEntry\"\r\n      },\r\n      \"description\": \"List of ARP entries.\"\r\n    },\r\n    \"ElevationRequirement\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"elevationRequired\",\r\n        \"elevationProhibited\",\r\n        \"elevatesSelf\"\r\n      ],\r\n      \"description\": \"The installer's elevation requirement\"\r\n    },\r\n    \"InstallationMetadata\": {\r\n      \"type\": \"object\",\r\n      \"title\": \"InstallationMetadata\",\r\n      \"properties\": {\r\n        \"DefaultInstallLocation\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 2048,\r\n          \"description\": \"Represents the default installed package location. Used for deeper installation detection.\"\r\n        },\r\n        \"Files\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"uniqueItems\": true,\r\n          \"maxItems\": 2048,\r\n          \"items\": {\r\n            \"type\": \"object\",\r\n            \"title\": \"InstalledFile\",\r\n            \"properties\": {\r\n              \"RelativeFilePath\": {\r\n                \"type\": \"string\",\r\n                \"minLength\": 1,\r\n                \"maxLength\": 2048,\r\n                \"description\": \"The relative path to the installed file.\"\r\n              },\r\n              \"FileSha256\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n                \"description\": \"Optional Sha256 of the installed file.\"\r\n              },\r\n              \"FileType\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"enum\": [\r\n                  \"launch\",\r\n                  \"uninstall\",\r\n                  \"other\"\r\n                ],\r\n                \"description\": \"The optional installed file type. If not specified, the file is treated as other.\"\r\n              },\r\n              \"InvocationParameter\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"minLength\": 1,\r\n                \"maxLength\": 2048,\r\n                \"description\": \"Optional parameter for invocable files.\"\r\n              },\r\n              \"DisplayName\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"minLength\": 1,\r\n                \"maxLength\": 256,\r\n                \"description\": \"Optional display name for invocable files.\"\r\n              }\r\n            },\r\n            \"required\": [ \"RelativeFilePath\" ],\r\n            \"description\": \"Represents an installed file.\"\r\n          },\r\n          \"description\": \"List of installed files.\"\r\n        }\r\n      },\r\n      \"description\": \"Details about the installation. Used for deeper installation detection.\"\r\n    },\r\n    \"Installer\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"InstallerLocale\": {\r\n          \"$ref\": \"#/definitions/Locale\"\r\n        },\r\n        \"Platform\": {\r\n          \"$ref\": \"#/definitions/Platform\"\r\n        },\r\n        \"MinimumOSVersion\": {\r\n          \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n        },\r\n        \"Architecture\": {\r\n          \"$ref\": \"#/definitions/Architecture\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        },\r\n        \"NestedInstallerType\": {\r\n          \"$ref\": \"#/definitions/NestedInstallerType\"\r\n        },\r\n        \"NestedInstallerFiles\": {\r\n          \"$ref\": \"#/definitions/NestedInstallerFiles\"\r\n        },\r\n        \"Scope\": {\r\n          \"$ref\": \"#/definitions/Scope\"\r\n        },\r\n        \"InstallerUrl\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n          \"maxLength\": 2048,\r\n          \"description\": \"The installer Url\"\r\n        },\r\n        \"InstallerSha256\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"Sha256 is required. Sha256 of the installer\"\r\n        },\r\n        \"SignatureSha256\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable\"\r\n        },\r\n        \"InstallModes\": {\r\n          \"$ref\": \"#/definitions/InstallModes\"\r\n        },\r\n        \"InstallerSwitches\": {\r\n          \"$ref\": \"#/definitions/InstallerSwitches\"\r\n        },\r\n        \"InstallerSuccessCodes\": {\r\n          \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n        },\r\n        \"ExpectedReturnCodes\": {\r\n          \"$ref\": \"#/definitions/ExpectedReturnCodes\"\r\n        },\r\n        \"UpgradeBehavior\": {\r\n          \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n        },\r\n        \"Commands\": {\r\n          \"$ref\": \"#/definitions/Commands\"\r\n        },\r\n        \"Protocols\": {\r\n          \"$ref\": \"#/definitions/Protocols\"\r\n        },\r\n        \"FileExtensions\": {\r\n          \"$ref\": \"#/definitions/FileExtensions\"\r\n        },\r\n        \"Dependencies\": {\r\n          \"$ref\": \"#/definitions/Dependencies\"\r\n        },\r\n        \"PackageFamilyName\": {\r\n          \"$ref\": \"#/definitions/PackageFamilyName\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"Capabilities\": {\r\n          \"$ref\": \"#/definitions/Capabilities\"\r\n        },\r\n        \"RestrictedCapabilities\": {\r\n          \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n        },\r\n        \"Markets\": {\r\n          \"$ref\": \"#/definitions/Markets\"\r\n        },\r\n        \"InstallerAbortsTerminal\": {\r\n          \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\r\n        },\r\n        \"ReleaseDate\": {\r\n          \"$ref\": \"#/definitions/ReleaseDate\"\r\n        },\r\n        \"InstallLocationRequired\": {\r\n          \"$ref\": \"#/definitions/InstallLocationRequired\"\r\n        },\r\n        \"RequireExplicitUpgrade\": {\r\n          \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\r\n        },\r\n        \"DisplayInstallWarnings\": {\r\n          \"$ref\": \"#/definitions/DisplayInstallWarnings\"\r\n        },\r\n        \"UnsupportedOSArchitectures\": {\r\n          \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\r\n        },\r\n        \"UnsupportedArguments\": {\r\n          \"$ref\": \"#/definitions/UnsupportedArguments\"\r\n        },\r\n        \"AppsAndFeaturesEntries\": {\r\n          \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\r\n        },\r\n        \"ElevationRequirement\": {\r\n          \"$ref\": \"#/definitions/ElevationRequirement\"\r\n        },\r\n        \"InstallationMetadata\": {\r\n          \"$ref\": \"#/definitions/InstallationMetadata\"\r\n        }\r\n      },\r\n      \"required\": [\r\n        \"Architecture\",\r\n        \"InstallerUrl\",\r\n        \"InstallerSha256\"\r\n      ]\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"$ref\": \"#/definitions/PackageIdentifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"$ref\": \"#/definitions/PackageVersion\"\r\n    },\r\n    \"Channel\": {\r\n      \"$ref\": \"#/definitions/Channel\"\r\n    },\r\n    \"InstallerLocale\": {\r\n      \"$ref\": \"#/definitions/Locale\"\r\n    },\r\n    \"Platform\": {\r\n      \"$ref\": \"#/definitions/Platform\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"$ref\": \"#/definitions/InstallerType\"\r\n    },\r\n    \"NestedInstallerType\": {\r\n      \"$ref\": \"#/definitions/NestedInstallerType\"\r\n    },\r\n    \"NestedInstallerFiles\": {\r\n      \"$ref\": \"#/definitions/NestedInstallerFiles\"\r\n    },\r\n    \"Scope\": {\r\n      \"$ref\": \"#/definitions/Scope\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"$ref\": \"#/definitions/InstallModes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"$ref\": \"#/definitions/InstallerSwitches\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n    },\r\n    \"ExpectedReturnCodes\": {\r\n      \"$ref\": \"#/definitions/ExpectedReturnCodes\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n    },\r\n    \"Commands\": {\r\n      \"$ref\": \"#/definitions/Commands\"\r\n    },\r\n    \"Protocols\": {\r\n      \"$ref\": \"#/definitions/Protocols\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"$ref\": \"#/definitions/FileExtensions\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"$ref\": \"#/definitions/Dependencies\"\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"$ref\": \"#/definitions/PackageFamilyName\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"$ref\": \"#/definitions/ProductCode\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"$ref\": \"#/definitions/Capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n    },\r\n    \"Markets\": {\r\n      \"$ref\": \"#/definitions/Markets\"\r\n    },\r\n    \"InstallerAbortsTerminal\": {\r\n      \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\r\n    },\r\n    \"ReleaseDate\": {\r\n      \"$ref\": \"#/definitions/ReleaseDate\"\r\n    },\r\n    \"InstallLocationRequired\": {\r\n      \"$ref\": \"#/definitions/InstallLocationRequired\"\r\n    },\r\n    \"RequireExplicitUpgrade\": {\r\n      \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\r\n    },\r\n    \"DisplayInstallWarnings\": {\r\n      \"$ref\": \"#/definitions/DisplayInstallWarnings\"\r\n    },\r\n    \"UnsupportedOSArchitectures\": {\r\n      \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\r\n    },\r\n    \"UnsupportedArguments\": {\r\n      \"$ref\": \"#/definitions/UnsupportedArguments\"\r\n    },\r\n    \"AppsAndFeaturesEntries\": {\r\n      \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\r\n    },\r\n    \"ElevationRequirement\": {\r\n      \"$ref\": \"#/definitions/ElevationRequirement\"\r\n    },\r\n    \"InstallationMetadata\": {\r\n      \"$ref\": \"#/definitions/InstallationMetadata\"\r\n    },\r\n    \"Installers\": {\r\n      \"type\": \"array\",\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Installer\"\r\n      },\r\n      \"minItems\": 1,\r\n      \"maxItems\": 1024\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"installer\",\r\n      \"const\": \"installer\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.5.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"Installers\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}\r\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.5.0/manifest.locale.1.5.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.locale.1.5.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a multiple-file manifest representing app metadata in other locale in the OWC. v1.5.0\",\r\n  \"definitions\": {\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Optional Url type\"\r\n    },\r\n    \"Tag\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 40,\r\n      \"description\": \"Package tag\"\r\n    },\r\n    \"Agreement\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"AgreementLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\r\n        },\r\n        \"Agreement\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 10000,\r\n          \"description\": \"The agreement text content.\"\r\n        },\r\n        \"AgreementUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The agreement URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Documentation\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DocumentLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\r\n        },\r\n        \"DocumentUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The documentation URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Icon\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"IconUrl\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n          \"maxLength\": 2048,\r\n          \"description\": \"The url of the hosted icon file\"\r\n        },\r\n        \"IconFileType\": {\r\n          \"type\": \"string\",\r\n          \"enum\": [\r\n            \"png\",\r\n            \"jpeg\",\r\n            \"ico\"\r\n          ],\r\n          \"description\": \"The icon file type\"\r\n        },\r\n        \"IconResolution\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"enum\": [\r\n            \"custom\",\r\n            \"16x16\",\r\n            \"20x20\",\r\n            \"24x24\",\r\n            \"30x30\",\r\n            \"32x32\",\r\n            \"36x36\",\r\n            \"40x40\",\r\n            \"48x48\",\r\n            \"60x60\",\r\n            \"64x64\",\r\n            \"72x72\",\r\n            \"80x80\",\r\n            \"96x96\",\r\n            \"256x256\"\r\n          ],\r\n          \"description\": \"Optional icon resolution\"\r\n        },\r\n        \"IconTheme\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"enum\": [\r\n            \"default\",\r\n            \"light\",\r\n            \"dark\",\r\n            \"highContrast\"\r\n          ],\r\n          \"description\": \"Optional icon theme\"\r\n        },\r\n        \"IconSha256\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"Optional Sha256 of the icon file\"\r\n        }\r\n      },\r\n      \"required\": [\r\n        \"IconUrl\",\r\n        \"IconFileType\"\r\n      ]\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"PackageLocale\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The package meta-data locale\"\r\n    },\r\n    \"Publisher\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The publisher name\"\r\n    },\r\n    \"PublisherUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher home page\"\r\n    },\r\n    \"PublisherSupportUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher support page\"\r\n    },\r\n    \"PrivacyUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher privacy page or the package privacy page\"\r\n    },\r\n    \"Author\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package author\"\r\n    },\r\n    \"PackageName\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package name\"\r\n    },\r\n    \"PackageUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package home page\"\r\n    },\r\n    \"License\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package license\"\r\n    },\r\n    \"LicenseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The license page\"\r\n    },\r\n    \"Copyright\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package copyright\"\r\n    },\r\n    \"CopyrightUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package copyright page\"\r\n    },\r\n    \"ShortDescription\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The short package description\"\r\n    },\r\n    \"Description\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The full package description\"\r\n    },\r\n    \"Tags\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Tag\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional package search terms\"\r\n    },\r\n    \"Agreements\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Agreement\"\r\n      },\r\n      \"maxItems\": 128\r\n    },\r\n    \"ReleaseNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The package release notes\"\r\n    },\r\n    \"ReleaseNotesUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package release notes url\"\r\n    },\r\n    \"PurchaseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\r\n    },\r\n    \"InstallationNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"\r\n    },\r\n    \"Documentations\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Documentation\"\r\n      },\r\n      \"maxItems\": 256\r\n    },\r\n    \"Icons\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Icon\"\r\n      },\r\n      \"maxItems\": 1024\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"locale\",\r\n      \"const\": \"locale\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.5.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"PackageLocale\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}\r\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.5.0/manifest.singleton.1.5.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.singleton.1.5.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a single-file manifest representing an app in the OWC. v1.5.0\",\r\n  \"definitions\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"Locale\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The package meta-data locale\"\r\n    },\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Optional Url type\"\r\n    },\r\n    \"Tag\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 40,\r\n      \"description\": \"Package moniker or tag\"\r\n    },\r\n    \"Agreement\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"AgreementLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\r\n        },\r\n        \"Agreement\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 10000,\r\n          \"description\": \"The agreement text content.\"\r\n        },\r\n        \"AgreementUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The agreement URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Documentation\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DocumentLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\r\n        },\r\n        \"DocumentUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The documentation URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Icon\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"IconUrl\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n          \"maxLength\": 2048,\r\n          \"description\": \"The url of the hosted icon file\"\r\n        },\r\n        \"IconFileType\": {\r\n          \"type\": \"string\",\r\n          \"enum\": [\r\n            \"png\",\r\n            \"jpeg\",\r\n            \"ico\"\r\n          ],\r\n          \"description\": \"The icon file type\"\r\n        },\r\n        \"IconResolution\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"enum\": [\r\n            \"custom\",\r\n            \"16x16\",\r\n            \"20x20\",\r\n            \"24x24\",\r\n            \"30x30\",\r\n            \"32x32\",\r\n            \"36x36\",\r\n            \"40x40\",\r\n            \"48x48\",\r\n            \"60x60\",\r\n            \"64x64\",\r\n            \"72x72\",\r\n            \"80x80\",\r\n            \"96x96\",\r\n            \"256x256\"\r\n          ],\r\n          \"description\": \"Optional icon resolution\"\r\n        },\r\n        \"IconTheme\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"enum\": [\r\n            \"default\",\r\n            \"light\",\r\n            \"dark\",\r\n            \"highContrast\"\r\n          ],\r\n          \"description\": \"Optional icon theme\"\r\n        },\r\n        \"IconSha256\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"Optional Sha256 of the icon file\"\r\n        }\r\n      },\r\n      \"required\": [\r\n        \"IconUrl\",\r\n        \"IconFileType\"\r\n      ]\r\n    },\r\n    \"Channel\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 16,\r\n      \"description\": \"The distribution channel\"\r\n    },\r\n    \"Platform\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"Platform\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"Windows.Desktop\",\r\n          \"Windows.Universal\"\r\n        ]\r\n      },\r\n      \"maxItems\": 2,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"The installer supported operating system\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$\",\r\n      \"description\": \"The installer minimum operating system version\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"msix\",\r\n        \"msi\",\r\n        \"appx\",\r\n        \"exe\",\r\n        \"zip\",\r\n        \"inno\",\r\n        \"nullsoft\",\r\n        \"wix\",\r\n        \"burn\",\r\n        \"pwa\",\r\n        \"portable\"\r\n      ],\r\n      \"description\": \"Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level\"\r\n    },\r\n    \"NestedInstallerType\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"msix\",\r\n        \"msi\",\r\n        \"appx\",\r\n        \"exe\",\r\n        \"inno\",\r\n        \"nullsoft\",\r\n        \"wix\",\r\n        \"burn\",\r\n        \"portable\"\r\n      ],\r\n      \"description\": \"Enumeration of supported nested installer types contained inside an archive file\"\r\n    },\r\n    \"NestedInstallerFiles\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"object\",\r\n        \"title\": \"NestedInstallerFile\",\r\n        \"properties\": {\r\n          \"RelativeFilePath\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 512,\r\n            \"description\": \"The relative path to the nested installer file\"\r\n          },\r\n          \"PortableCommandAlias\": {\r\n            \"type\": [ \"string\", \"null\" ],\r\n            \"minLength\": 1,\r\n            \"maxLength\": 40,\r\n            \"description\": \"The command alias to be used for calling the package. Only applies to the nested portable package\"\r\n          }\r\n        },\r\n        \"required\": [ \"RelativeFilePath\" ],\r\n        \"description\": \"A nested installer file contained inside an archive\"\r\n      },\r\n      \"maxItems\": 1024,\r\n      \"description\": \"List of nested installer files contained inside an archive\"\r\n    },\r\n    \"Architecture\": {\r\n      \"type\": \"string\",\r\n      \"enum\": [\r\n        \"x86\",\r\n        \"x64\",\r\n        \"arm\",\r\n        \"arm64\",\r\n        \"neutral\"\r\n      ],\r\n      \"description\": \"The installer target architecture\"\r\n    },\r\n    \"Scope\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"user\",\r\n        \"machine\"\r\n      ],\r\n      \"description\": \"Scope indicates if the installer is per user or per machine\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"InstallModes\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"interactive\",\r\n          \"silent\",\r\n          \"silentWithProgress\"\r\n        ]\r\n      },\r\n      \"maxItems\": 3,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of supported installer modes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"Silent\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Silent is the value that should be passed to the installer when user chooses a silent or quiet install\"\r\n        },\r\n        \"SilentWithProgress\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install\"\r\n        },\r\n        \"Interactive\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Interactive is the value that should be passed to the installer when user chooses an interactive install\"\r\n        },\r\n        \"InstallLocation\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"InstallLocation is the value passed to the installer for custom install location. <INSTALLPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Log\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Log is the value passed to the installer for custom log file path. <LOGPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Upgrade\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Upgrade is the value that should be passed to the installer when user chooses an upgrade\"\r\n        },\r\n        \"Custom\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 2048,\r\n          \"description\": \"Custom switches will be passed directly to the installer by winget\"\r\n        }\r\n      }\r\n    },\r\n    \"InstallerReturnCode\": {\r\n      \"type\": \"integer\",\r\n      \"format\": \"long\",\r\n      \"not\": {\r\n        \"enum\": [ 0 ]\r\n      },\r\n      \"minimum\": -2147483648,\r\n      \"maximum\": 4294967295,\r\n      \"description\": \"An exit code that can be returned by the installer after execution\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/InstallerReturnCode\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional non-zero installer success exit codes other than known default values by winget\"\r\n    },\r\n    \"ExpectedReturnCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"object\",\r\n        \"title\": \"ExpectedReturnCode\",\r\n        \"properties\": {\r\n          \"InstallerReturnCode\": {\r\n            \"$ref\": \"#/definitions/InstallerReturnCode\"\r\n          },\r\n          \"ReturnResponse\": {\r\n            \"type\": \"string\",\r\n            \"enum\": [\r\n              \"packageInUse\",\r\n              \"packageInUseByApplication\",\r\n              \"installInProgress\",\r\n              \"fileInUse\",\r\n              \"missingDependency\",\r\n              \"diskFull\",\r\n              \"insufficientMemory\",\r\n              \"invalidParameter\",\r\n              \"noNetwork\",\r\n              \"contactSupport\",\r\n              \"rebootRequiredToFinish\",\r\n              \"rebootRequiredForInstall\",\r\n              \"rebootInitiated\",\r\n              \"cancelledByUser\",\r\n              \"alreadyInstalled\",\r\n              \"downgrade\",\r\n              \"blockedByPolicy\",\r\n              \"systemNotSupported\",\r\n              \"custom\"\r\n            ]\r\n          },\r\n          \"ReturnResponseUrl\": {\r\n            \"$ref\": \"#/definitions/Url\",\r\n            \"description\": \"The return response url to provide additional guidance for expected return codes\"\r\n          }\r\n        },\r\n        \"required\": [ \"InstallerReturnCode\", \"ReturnResponse\" ]\r\n      },\r\n      \"maxItems\": 128,\r\n      \"description\": \"Installer exit codes for common errors\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"install\",\r\n        \"uninstallPrevious\"\r\n      ],\r\n      \"description\": \"The upgrade method\"\r\n    },\r\n    \"Commands\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of commands or aliases to run the package\"\r\n    },\r\n    \"Protocols\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"maxLength\": 2048\r\n      },\r\n      \"maxItems\": 64,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of protocols the package provides a handler for\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n        \"maxLength\": 64\r\n      },\r\n      \"maxItems\": 512,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of file extensions the package could support\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"properties\": {\r\n        \"WindowsFeatures\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows feature dependencies\"\r\n        },\r\n        \"WindowsLibraries\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows library dependencies\"\r\n        },\r\n        \"PackageDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"object\",\r\n            \"properties\": {\r\n              \"PackageIdentifier\": {\r\n                \"$ref\": \"#/definitions/PackageIdentifier\"\r\n              },\r\n              \"MinimumVersion\": {\r\n                \"$ref\": \"#/definitions/PackageVersion\"\r\n              }\r\n            },\r\n            \"required\": [ \"PackageIdentifier\" ]\r\n          },\r\n          \"maxItems\": 16,\r\n          \"description\": \"List of package dependencies from current source\"\r\n        },\r\n        \"ExternalDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of external package dependencies\"\r\n        }\r\n      }\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^[A-Za-z0-9][-\\\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$\",\r\n      \"maxLength\": 255,\r\n      \"description\": \"PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 255,\r\n      \"description\": \"ProductCode could be used for correlation of packages across sources\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer restricted capabilities\"\r\n    },\r\n    \"Market\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[A-Z]{2}$\",\r\n      \"description\": \"The installer target market\"\r\n    },\r\n    \"MarketArray\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"maxItems\": 256,\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Market\"\r\n      },\r\n      \"description\": \"Array of markets\"\r\n    },\r\n    \"Markets\": {\r\n      \"description\": \"The installer markets\",\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"oneOf\": [\r\n        {\r\n          \"properties\": {\r\n            \"AllowedMarkets\": {\r\n              \"$ref\": \"#/definitions/MarketArray\"\r\n            }\r\n          },\r\n          \"required\": [ \"AllowedMarkets\" ]\r\n        },\r\n        {\r\n          \"properties\": {\r\n            \"ExcludedMarkets\": {\r\n              \"$ref\": \"#/definitions/MarketArray\"\r\n            }\r\n          },\r\n          \"required\": [ \"ExcludedMarkets\" ]\r\n        }\r\n      ]\r\n    },\r\n    \"InstallerAbortsTerminal\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer will abort terminal. Default is false\"\r\n    },\r\n    \"ReleaseDate\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"format\": \"date\",\r\n      \"description\": \"The installer release date\"\r\n    },\r\n    \"InstallLocationRequired\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer requires an install location provided\"\r\n    },\r\n    \"RequireExplicitUpgrade\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer should be pinned by default from upgrade\"\r\n    },\r\n    \"DisplayInstallWarnings\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications.\"\r\n    },\r\n    \"UnsupportedOSArchitectures\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"title\": \"UnsupportedOSArchitecture\",\r\n        \"enum\": [\r\n          \"x86\",\r\n          \"x64\",\r\n          \"arm\",\r\n          \"arm64\"\r\n        ]\r\n      },\r\n      \"description\": \"List of OS architectures the installer does not support\"\r\n    },\r\n    \"UnsupportedArguments\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"title\": \"UnsupportedArgument\",\r\n        \"enum\": [\r\n          \"log\",\r\n          \"location\"\r\n        ]\r\n      },\r\n      \"description\": \"List of winget arguments the installer does not support\"\r\n    },\r\n    \"AppsAndFeaturesEntry\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DisplayName\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 256,\r\n          \"description\": \"The DisplayName registry value\"\r\n        },\r\n        \"Publisher\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 256,\r\n          \"description\": \"The Publisher registry value\"\r\n        },\r\n        \"DisplayVersion\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 128,\r\n          \"description\": \"The DisplayVersion registry value\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"UpgradeCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        }\r\n      },\r\n      \"description\": \"Various key values under installer's ARP entry\"\r\n    },\r\n    \"AppsAndFeaturesEntries\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"maxItems\": 128,\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/AppsAndFeaturesEntry\"\r\n      },\r\n      \"description\": \"List of ARP entries.\"\r\n    },\r\n    \"ElevationRequirement\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"elevationRequired\",\r\n        \"elevationProhibited\",\r\n        \"elevatesSelf\"\r\n      ],\r\n      \"description\": \"The installer's elevation requirement\"\r\n    },\r\n    \"InstallationMetadata\": {\r\n      \"type\": \"object\",\r\n      \"title\": \"InstallationMetadata\",\r\n      \"properties\": {\r\n        \"DefaultInstallLocation\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 2048,\r\n          \"description\": \"Represents the default installed package location. Used for deeper installation detection.\"\r\n        },\r\n        \"Files\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"uniqueItems\": true,\r\n          \"maxItems\": 2048,\r\n          \"items\": {\r\n            \"type\": \"object\",\r\n            \"title\": \"InstalledFile\",\r\n            \"properties\": {\r\n              \"RelativeFilePath\": {\r\n                \"type\": \"string\",\r\n                \"minLength\": 1,\r\n                \"maxLength\": 2048,\r\n                \"description\": \"The relative path to the installed file.\"\r\n              },\r\n              \"FileSha256\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n                \"description\": \"Optional Sha256 of the installed file.\"\r\n              },\r\n              \"FileType\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"enum\": [\r\n                  \"launch\",\r\n                  \"uninstall\",\r\n                  \"other\"\r\n                ],\r\n                \"description\": \"The optional installed file type. If not specified, the file is treated as other.\"\r\n              },\r\n              \"InvocationParameter\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"minLength\": 1,\r\n                \"maxLength\": 2048,\r\n                \"description\": \"Optional parameter for invocable files.\"\r\n              },\r\n              \"DisplayName\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"minLength\": 1,\r\n                \"maxLength\": 256,\r\n                \"description\": \"Optional display name for invocable files.\"\r\n              }\r\n            },\r\n            \"required\": [ \"RelativeFilePath\" ],\r\n            \"description\": \"Represents an installed file.\"\r\n          },\r\n          \"description\": \"List of installed files.\"\r\n        }\r\n      },\r\n      \"description\": \"Details about the installation. Used for deeper installation detection.\"\r\n    },\r\n    \"Installer\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"InstallerLocale\": {\r\n          \"$ref\": \"#/definitions/Locale\"\r\n        },\r\n        \"Platform\": {\r\n          \"$ref\": \"#/definitions/Platform\"\r\n        },\r\n        \"MinimumOSVersion\": {\r\n          \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n        },\r\n        \"Architecture\": {\r\n          \"$ref\": \"#/definitions/Architecture\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        },\r\n        \"NestedInstallerType\": {\r\n          \"$ref\": \"#/definitions/NestedInstallerType\"\r\n        },\r\n        \"NestedInstallerFiles\": {\r\n          \"$ref\": \"#/definitions/NestedInstallerFiles\"\r\n        },\r\n        \"Scope\": {\r\n          \"$ref\": \"#/definitions/Scope\"\r\n        },\r\n        \"InstallerUrl\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n          \"maxLength\": 2048,\r\n          \"description\": \"The installer Url\"\r\n        },\r\n        \"InstallerSha256\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"Sha256 is required. Sha256 of the installer\"\r\n        },\r\n        \"SignatureSha256\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable\"\r\n        },\r\n        \"InstallModes\": {\r\n          \"$ref\": \"#/definitions/InstallModes\"\r\n        },\r\n        \"InstallerSwitches\": {\r\n          \"$ref\": \"#/definitions/InstallerSwitches\"\r\n        },\r\n        \"InstallerSuccessCodes\": {\r\n          \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n        },\r\n        \"ExpectedReturnCodes\": {\r\n          \"$ref\": \"#/definitions/ExpectedReturnCodes\"\r\n        },\r\n        \"UpgradeBehavior\": {\r\n          \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n        },\r\n        \"Commands\": {\r\n          \"$ref\": \"#/definitions/Commands\"\r\n        },\r\n        \"Protocols\": {\r\n          \"$ref\": \"#/definitions/Protocols\"\r\n        },\r\n        \"FileExtensions\": {\r\n          \"$ref\": \"#/definitions/FileExtensions\"\r\n        },\r\n        \"Dependencies\": {\r\n          \"$ref\": \"#/definitions/Dependencies\"\r\n        },\r\n        \"PackageFamilyName\": {\r\n          \"$ref\": \"#/definitions/PackageFamilyName\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"Capabilities\": {\r\n          \"$ref\": \"#/definitions/Capabilities\"\r\n        },\r\n        \"RestrictedCapabilities\": {\r\n          \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n        },\r\n        \"Markets\": {\r\n          \"$ref\": \"#/definitions/Markets\"\r\n        },\r\n        \"InstallerAbortsTerminal\": {\r\n          \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\r\n        },\r\n        \"ReleaseDate\": {\r\n          \"$ref\": \"#/definitions/ReleaseDate\"\r\n        },\r\n        \"InstallLocationRequired\": {\r\n          \"$ref\": \"#/definitions/InstallLocationRequired\"\r\n        },\r\n        \"RequireExplicitUpgrade\": {\r\n          \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\r\n        },\r\n        \"DisplayInstallWarnings\": {\r\n          \"$ref\": \"#/definitions/DisplayInstallWarnings\"\r\n        },\r\n        \"UnsupportedOSArchitectures\": {\r\n          \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\r\n        },\r\n        \"UnsupportedArguments\": {\r\n          \"$ref\": \"#/definitions/UnsupportedArguments\"\r\n        },\r\n        \"AppsAndFeaturesEntries\": {\r\n          \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\r\n        },\r\n        \"ElevationRequirement\": {\r\n          \"$ref\": \"#/definitions/ElevationRequirement\"\r\n        },\r\n        \"InstallationMetadata\": {\r\n          \"$ref\": \"#/definitions/InstallationMetadata\"\r\n        }\r\n      },\r\n      \"required\": [\r\n        \"Architecture\",\r\n        \"InstallerUrl\",\r\n        \"InstallerSha256\"\r\n      ]\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"$ref\": \"#/definitions/PackageIdentifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"$ref\": \"#/definitions/PackageVersion\"\r\n    },\r\n    \"PackageLocale\": {\r\n      \"$ref\": \"#/definitions/Locale\"\r\n    },\r\n    \"Publisher\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The publisher name\"\r\n    },\r\n    \"PublisherUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher home page\"\r\n    },\r\n    \"PublisherSupportUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher support page\"\r\n    },\r\n    \"PrivacyUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher privacy page or the package privacy page\"\r\n    },\r\n    \"Author\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package author\"\r\n    },\r\n    \"PackageName\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package name\"\r\n    },\r\n    \"PackageUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package home page\"\r\n    },\r\n    \"License\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package license\"\r\n    },\r\n    \"LicenseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The license page\"\r\n    },\r\n    \"Copyright\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package copyright\"\r\n    },\r\n    \"CopyrightUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package copyright page\"\r\n    },\r\n    \"ShortDescription\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The short package description\"\r\n    },\r\n    \"Description\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The full package description\"\r\n    },\r\n    \"Moniker\": {\r\n      \"$ref\": \"#/definitions/Tag\",\r\n      \"description\": \"The most common package term\"\r\n    },\r\n    \"Tags\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Tag\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional package search terms\"\r\n    },\r\n    \"Agreements\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Agreement\"\r\n      },\r\n      \"maxItems\": 128\r\n    },\r\n    \"ReleaseNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The package release notes\"\r\n    },\r\n    \"ReleaseNotesUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package release notes url\"\r\n    },\r\n    \"PurchaseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\r\n    },\r\n    \"InstallationNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"\r\n    },\r\n    \"Documentations\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Documentation\"\r\n      },\r\n      \"maxItems\": 256\r\n    },\r\n    \"Icons\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Icon\"\r\n      },\r\n      \"maxItems\": 1024\r\n    },\r\n    \"Channel\": {\r\n      \"$ref\": \"#/definitions/Channel\"\r\n    },\r\n    \"InstallerLocale\": {\r\n      \"$ref\": \"#/definitions/Locale\"\r\n    },\r\n    \"Platform\": {\r\n      \"$ref\": \"#/definitions/Platform\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"$ref\": \"#/definitions/InstallerType\"\r\n    },\r\n    \"NestedInstallerType\": {\r\n      \"$ref\": \"#/definitions/NestedInstallerType\"\r\n    },\r\n    \"NestedInstallerFiles\": {\r\n      \"$ref\": \"#/definitions/NestedInstallerFiles\"\r\n    },\r\n    \"Scope\": {\r\n      \"$ref\": \"#/definitions/Scope\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"$ref\": \"#/definitions/InstallModes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"$ref\": \"#/definitions/InstallerSwitches\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n    },\r\n    \"ExpectedReturnCodes\": {\r\n      \"$ref\": \"#/definitions/ExpectedReturnCodes\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n    },\r\n    \"Commands\": {\r\n      \"$ref\": \"#/definitions/Commands\"\r\n    },\r\n    \"Protocols\": {\r\n      \"$ref\": \"#/definitions/Protocols\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"$ref\": \"#/definitions/FileExtensions\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"$ref\": \"#/definitions/Dependencies\"\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"$ref\": \"#/definitions/PackageFamilyName\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"$ref\": \"#/definitions/ProductCode\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"$ref\": \"#/definitions/Capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n    },\r\n    \"Markets\": {\r\n      \"$ref\": \"#/definitions/Markets\"\r\n    },\r\n    \"InstallerAbortsTerminal\": {\r\n      \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\r\n    },\r\n    \"ReleaseDate\": {\r\n      \"$ref\": \"#/definitions/ReleaseDate\"\r\n    },\r\n    \"InstallLocationRequired\": {\r\n      \"$ref\": \"#/definitions/InstallLocationRequired\"\r\n    },\r\n    \"RequireExplicitUpgrade\": {\r\n      \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\r\n    },\r\n    \"DisplayInstallWarnings\": {\r\n      \"$ref\": \"#/definitions/DisplayInstallWarnings\"\r\n    },\r\n    \"UnsupportedOSArchitectures\": {\r\n      \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\r\n    },\r\n    \"UnsupportedArguments\": {\r\n      \"$ref\": \"#/definitions/UnsupportedArguments\"\r\n    },\r\n    \"AppsAndFeaturesEntries\": {\r\n      \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\r\n    },\r\n    \"ElevationRequirement\": {\r\n      \"$ref\": \"#/definitions/ElevationRequirement\"\r\n    },\r\n    \"InstallationMetadata\": {\r\n      \"$ref\": \"#/definitions/InstallationMetadata\"\r\n    },\r\n    \"Installers\": {\r\n      \"type\": \"array\",\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Installer\"\r\n      },\r\n      \"minItems\": 1,\r\n      \"maxItems\": 1\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"singleton\",\r\n      \"const\": \"singleton\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.5.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"PackageLocale\",\r\n    \"Publisher\",\r\n    \"PackageName\",\r\n    \"License\",\r\n    \"ShortDescription\",\r\n    \"Installers\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}\r\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.5.0/manifest.version.1.5.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.version.1.5.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a multi-file manifest representing an app version in the OWC. v1.5.0\",\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"DefaultLocale\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"en-US\",\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The default package meta-data locale\"\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"version\",\r\n      \"const\": \"version\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.5.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"DefaultLocale\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}"
  },
  {
    "path": "schemas/JSON/manifests/v1.6.0/manifest.defaultLocale.1.6.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.defaultlocale.1.6.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a multiple-file manifest representing a default app metadata in the OWC. v1.6.0\",\r\n  \"definitions\": {\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Optional Url type\"\r\n    },\r\n    \"Tag\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 40,\r\n      \"description\": \"Package moniker or tag\"\r\n    },\r\n    \"Agreement\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"AgreementLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\r\n        },\r\n        \"Agreement\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 10000,\r\n          \"description\": \"The agreement text content.\"\r\n        },\r\n        \"AgreementUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The agreement URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Documentation\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DocumentLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\r\n        },\r\n        \"DocumentUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The documentation URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Icon\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"IconUrl\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n          \"maxLength\": 2048,\r\n          \"description\": \"The url of the hosted icon file\"\r\n        },\r\n        \"IconFileType\": {\r\n          \"type\": \"string\",\r\n          \"enum\": [\r\n            \"png\",\r\n            \"jpeg\",\r\n            \"ico\"\r\n          ],\r\n          \"description\": \"The icon file type\"\r\n        },\r\n        \"IconResolution\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"enum\": [\r\n            \"custom\",\r\n            \"16x16\",\r\n            \"20x20\",\r\n            \"24x24\",\r\n            \"30x30\",\r\n            \"32x32\",\r\n            \"36x36\",\r\n            \"40x40\",\r\n            \"48x48\",\r\n            \"60x60\",\r\n            \"64x64\",\r\n            \"72x72\",\r\n            \"80x80\",\r\n            \"96x96\",\r\n            \"256x256\"\r\n          ],\r\n          \"description\": \"Optional icon resolution\"\r\n        },\r\n        \"IconTheme\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"enum\": [\r\n            \"default\",\r\n            \"light\",\r\n            \"dark\",\r\n            \"highContrast\"\r\n          ],\r\n          \"description\": \"Optional icon theme\"\r\n        },\r\n        \"IconSha256\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"Optional Sha256 of the icon file\"\r\n        }\r\n      },\r\n      \"required\": [\r\n        \"IconUrl\",\r\n        \"IconFileType\"\r\n      ]\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"PackageLocale\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"en-US\",\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The package meta-data locale\"\r\n    },\r\n    \"Publisher\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The publisher name\"\r\n    },\r\n    \"PublisherUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher home page\"\r\n    },\r\n    \"PublisherSupportUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher support page\"\r\n    },\r\n    \"PrivacyUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher privacy page or the package privacy page\"\r\n    },\r\n    \"Author\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package author\"\r\n    },\r\n    \"PackageName\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package name\"\r\n    },\r\n    \"PackageUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package home page\"\r\n    },\r\n    \"License\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package license\"\r\n    },\r\n    \"LicenseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The license page\"\r\n    },\r\n    \"Copyright\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package copyright\"\r\n    },\r\n    \"CopyrightUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package copyright page\"\r\n    },\r\n    \"ShortDescription\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The short package description\"\r\n    },\r\n    \"Description\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The full package description\"\r\n    },\r\n    \"Moniker\": {\r\n      \"$ref\": \"#/definitions/Tag\",\r\n      \"description\": \"The most common package term\"\r\n    },\r\n    \"Tags\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Tag\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional package search terms\"\r\n    },\r\n    \"Agreements\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Agreement\"\r\n      },\r\n      \"maxItems\": 128\r\n    },\r\n    \"ReleaseNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The package release notes\"\r\n    },\r\n    \"ReleaseNotesUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package release notes url\"\r\n    },\r\n    \"PurchaseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\r\n    },\r\n    \"InstallationNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"\r\n    },\r\n    \"Documentations\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Documentation\"\r\n      },\r\n      \"maxItems\": 256\r\n    },\r\n    \"Icons\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Icon\"\r\n      },\r\n      \"maxItems\": 1024\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"defaultLocale\",\r\n      \"const\": \"defaultLocale\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.6.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"PackageLocale\",\r\n    \"Publisher\",\r\n    \"PackageName\",\r\n    \"License\",\r\n    \"ShortDescription\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}\r\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.6.0/manifest.installer.1.6.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.installer.1.6.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a single-file manifest representing an app installers in the OWC. v1.6.0\",\r\n  \"definitions\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"Locale\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The installer meta-data locale\"\r\n    },\r\n    \"Channel\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 16,\r\n      \"description\": \"The distribution channel\"\r\n    },\r\n    \"Platform\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"Platform\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"Windows.Desktop\",\r\n          \"Windows.Universal\"\r\n        ]\r\n      },\r\n      \"maxItems\": 2,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"The installer supported operating system\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$\",\r\n      \"description\": \"The installer minimum operating system version\"\r\n    },\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Url type\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"msix\",\r\n        \"msi\",\r\n        \"appx\",\r\n        \"exe\",\r\n        \"zip\",\r\n        \"inno\",\r\n        \"nullsoft\",\r\n        \"wix\",\r\n        \"burn\",\r\n        \"pwa\",\r\n        \"portable\"\r\n      ],\r\n      \"description\": \"Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level\"\r\n    },\r\n    \"NestedInstallerType\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"msix\",\r\n        \"msi\",\r\n        \"appx\",\r\n        \"exe\",\r\n        \"inno\",\r\n        \"nullsoft\",\r\n        \"wix\",\r\n        \"burn\",\r\n        \"portable\"\r\n      ],\r\n      \"description\": \"Enumeration of supported nested installer types contained inside an archive file\"\r\n    },\r\n    \"NestedInstallerFiles\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"object\",\r\n        \"title\": \"NestedInstallerFile\",\r\n        \"properties\": {\r\n          \"RelativeFilePath\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 512,\r\n            \"description\": \"The relative path to the nested installer file\"\r\n          },\r\n          \"PortableCommandAlias\": {\r\n            \"type\": [ \"string\", \"null\" ],\r\n            \"minLength\": 1,\r\n            \"maxLength\": 40,\r\n            \"description\": \"The command alias to be used for calling the package. Only applies to the nested portable package\"\r\n          }\r\n        },\r\n        \"required\": [ \"RelativeFilePath\" ],\r\n        \"description\": \"A nested installer file contained inside an archive\"\r\n      },\r\n      \"maxItems\": 1024,\r\n      \"description\": \"List of nested installer files contained inside an archive\"\r\n    },\r\n    \"Architecture\": {\r\n      \"type\": \"string\",\r\n      \"enum\": [\r\n        \"x86\",\r\n        \"x64\",\r\n        \"arm\",\r\n        \"arm64\",\r\n        \"neutral\"\r\n      ],\r\n      \"description\": \"The installer target architecture\"\r\n    },\r\n    \"Scope\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"user\",\r\n        \"machine\"\r\n      ],\r\n      \"description\": \"Scope indicates if the installer is per user or per machine\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"InstallModes\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"interactive\",\r\n          \"silent\",\r\n          \"silentWithProgress\"\r\n        ]\r\n      },\r\n      \"maxItems\": 3,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of supported installer modes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"Silent\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Silent is the value that should be passed to the installer when user chooses a silent or quiet install\"\r\n        },\r\n        \"SilentWithProgress\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install\"\r\n        },\r\n        \"Interactive\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Interactive is the value that should be passed to the installer when user chooses an interactive install\"\r\n        },\r\n        \"InstallLocation\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"InstallLocation is the value passed to the installer for custom install location. <INSTALLPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Log\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Log is the value passed to the installer for custom log file path. <LOGPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Upgrade\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Upgrade is the value that should be passed to the installer when user chooses an upgrade\"\r\n        },\r\n        \"Custom\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 2048,\r\n          \"description\": \"Custom switches will be passed directly to the installer by winget\"\r\n        }\r\n      }\r\n    },\r\n    \"InstallerReturnCode\": {\r\n      \"type\": \"integer\",\r\n      \"format\": \"long\",\r\n      \"not\": {\r\n        \"enum\": [ 0 ]\r\n      },\r\n      \"minimum\": -2147483648,\r\n      \"maximum\": 4294967295,\r\n      \"description\": \"An exit code that can be returned by the installer after execution\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/InstallerReturnCode\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional non-zero installer success exit codes other than known default values by winget\"\r\n    },\r\n    \"ExpectedReturnCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"object\",\r\n        \"title\": \"ExpectedReturnCode\",\r\n        \"properties\": {\r\n          \"InstallerReturnCode\": {\r\n            \"$ref\": \"#/definitions/InstallerReturnCode\"\r\n          },\r\n          \"ReturnResponse\": {\r\n            \"type\": \"string\",\r\n            \"enum\": [\r\n              \"packageInUse\",\r\n              \"packageInUseByApplication\",\r\n              \"installInProgress\",\r\n              \"fileInUse\",\r\n              \"missingDependency\",\r\n              \"diskFull\",\r\n              \"insufficientMemory\",\r\n              \"invalidParameter\",\r\n              \"noNetwork\",\r\n              \"contactSupport\",\r\n              \"rebootRequiredToFinish\",\r\n              \"rebootRequiredForInstall\",\r\n              \"rebootInitiated\",\r\n              \"cancelledByUser\",\r\n              \"alreadyInstalled\",\r\n              \"downgrade\",\r\n              \"blockedByPolicy\",\r\n              \"systemNotSupported\",\r\n              \"custom\"\r\n            ]\r\n          },\r\n          \"ReturnResponseUrl\": {\r\n            \"$ref\": \"#/definitions/Url\",\r\n            \"description\": \"The return response url to provide additional guidance for expected return codes\"\r\n          }\r\n        },\r\n        \"required\": [ \"InstallerReturnCode\", \"ReturnResponse\" ]\r\n      },\r\n      \"maxItems\": 128,\r\n      \"description\": \"Installer exit codes for common errors\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"install\",\r\n        \"uninstallPrevious\",\r\n        \"deny\"\r\n      ],\r\n      \"description\": \"The upgrade method\"\r\n    },\r\n    \"Commands\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of commands or aliases to run the package\"\r\n    },\r\n    \"Protocols\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"maxLength\": 2048\r\n      },\r\n      \"maxItems\": 64,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of protocols the package provides a handler for\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n        \"maxLength\": 64\r\n      },\r\n      \"maxItems\": 512,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of file extensions the package could support\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"properties\": {\r\n        \"WindowsFeatures\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows feature dependencies\"\r\n        },\r\n        \"WindowsLibraries\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows library dependencies\"\r\n        },\r\n        \"PackageDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"object\",\r\n            \"properties\": {\r\n              \"PackageIdentifier\": {\r\n                \"$ref\": \"#/definitions/PackageIdentifier\"\r\n              },\r\n              \"MinimumVersion\": {\r\n                \"$ref\": \"#/definitions/PackageVersion\"\r\n              }\r\n            },\r\n            \"required\": [ \"PackageIdentifier\" ]\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of package dependencies from current source\"\r\n        },\r\n        \"ExternalDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of external package dependencies\"\r\n        }\r\n      }\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^[A-Za-z0-9][-\\\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$\",\r\n      \"maxLength\": 255,\r\n      \"description\": \"PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 255,\r\n      \"description\": \"ProductCode could be used for correlation of packages across sources\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer restricted capabilities\"\r\n    },\r\n    \"Market\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[A-Z]{2}$\",\r\n      \"description\": \"The installer target market\"\r\n    },\r\n    \"MarketArray\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"maxItems\": 256,\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Market\"\r\n      },\r\n      \"description\": \"Array of markets\"\r\n    },\r\n    \"Markets\": {\r\n      \"description\": \"The installer markets\",\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"oneOf\": [\r\n        {\r\n          \"properties\": {\r\n            \"AllowedMarkets\": {\r\n              \"$ref\": \"#/definitions/MarketArray\"\r\n            }\r\n          },\r\n          \"required\": [ \"AllowedMarkets\" ]\r\n        },\r\n        {\r\n          \"properties\": {\r\n            \"ExcludedMarkets\": {\r\n              \"$ref\": \"#/definitions/MarketArray\"\r\n            }\r\n          },\r\n          \"required\": [ \"ExcludedMarkets\" ]\r\n        }\r\n      ]\r\n    },\r\n    \"InstallerAbortsTerminal\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer will abort terminal. Default is false\"\r\n    },\r\n    \"ReleaseDate\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"format\": \"date\",\r\n      \"description\": \"The installer release date\"\r\n    },\r\n    \"InstallLocationRequired\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer requires an install location provided\"\r\n    },\r\n    \"RequireExplicitUpgrade\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer should be pinned by default from upgrade\"\r\n    },\r\n    \"DisplayInstallWarnings\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications.\"\r\n    },\r\n    \"UnsupportedOSArchitectures\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"title\": \"UnsupportedOSArchitecture\",\r\n        \"enum\": [\r\n          \"x86\",\r\n          \"x64\",\r\n          \"arm\",\r\n          \"arm64\"\r\n        ]\r\n      },\r\n      \"description\": \"List of OS architectures the installer does not support\"\r\n    },\r\n    \"UnsupportedArguments\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"title\": \"UnsupportedArgument\",\r\n        \"enum\": [\r\n          \"log\",\r\n          \"location\"\r\n        ]\r\n      },\r\n      \"description\": \"List of winget arguments the installer does not support\"\r\n    },\r\n    \"AppsAndFeaturesEntry\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DisplayName\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 256,\r\n          \"description\": \"The DisplayName registry value\"\r\n        },\r\n        \"Publisher\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 256,\r\n          \"description\": \"The Publisher registry value\"\r\n        },\r\n        \"DisplayVersion\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 128,\r\n          \"description\": \"The DisplayVersion registry value\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"UpgradeCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        }\r\n      },\r\n      \"description\": \"Various key values under installer's ARP entry\"\r\n    },\r\n    \"AppsAndFeaturesEntries\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"maxItems\": 128,\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/AppsAndFeaturesEntry\"\r\n      },\r\n      \"description\": \"List of ARP entries.\"\r\n    },\r\n    \"ElevationRequirement\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"elevationRequired\",\r\n        \"elevationProhibited\",\r\n        \"elevatesSelf\"\r\n      ],\r\n      \"description\": \"The installer's elevation requirement\"\r\n    },\r\n    \"InstallationMetadata\": {\r\n      \"type\": \"object\",\r\n      \"title\": \"InstallationMetadata\",\r\n      \"properties\": {\r\n        \"DefaultInstallLocation\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 2048,\r\n          \"description\": \"Represents the default installed package location. Used for deeper installation detection.\"\r\n        },\r\n        \"Files\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"uniqueItems\": true,\r\n          \"maxItems\": 2048,\r\n          \"items\": {\r\n            \"type\": \"object\",\r\n            \"title\": \"InstalledFile\",\r\n            \"properties\": {\r\n              \"RelativeFilePath\": {\r\n                \"type\": \"string\",\r\n                \"minLength\": 1,\r\n                \"maxLength\": 2048,\r\n                \"description\": \"The relative path to the installed file.\"\r\n              },\r\n              \"FileSha256\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n                \"description\": \"Optional Sha256 of the installed file.\"\r\n              },\r\n              \"FileType\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"enum\": [\r\n                  \"launch\",\r\n                  \"uninstall\",\r\n                  \"other\"\r\n                ],\r\n                \"description\": \"The optional installed file type. If not specified, the file is treated as other.\"\r\n              },\r\n              \"InvocationParameter\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"minLength\": 1,\r\n                \"maxLength\": 2048,\r\n                \"description\": \"Optional parameter for invocable files.\"\r\n              },\r\n              \"DisplayName\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"minLength\": 1,\r\n                \"maxLength\": 256,\r\n                \"description\": \"Optional display name for invocable files.\"\r\n              }\r\n            },\r\n            \"required\": [ \"RelativeFilePath\" ],\r\n            \"description\": \"Represents an installed file.\"\r\n          },\r\n          \"description\": \"List of installed files.\"\r\n        }\r\n      },\r\n      \"description\": \"Details about the installation. Used for deeper installation detection.\"\r\n    },\r\n    \"DownloadCommandProhibited\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer is prohibited from being downloaded for offline installation.\"\r\n    },\r\n    \"Installer\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"InstallerLocale\": {\r\n          \"$ref\": \"#/definitions/Locale\"\r\n        },\r\n        \"Platform\": {\r\n          \"$ref\": \"#/definitions/Platform\"\r\n        },\r\n        \"MinimumOSVersion\": {\r\n          \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n        },\r\n        \"Architecture\": {\r\n          \"$ref\": \"#/definitions/Architecture\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        },\r\n        \"NestedInstallerType\": {\r\n          \"$ref\": \"#/definitions/NestedInstallerType\"\r\n        },\r\n        \"NestedInstallerFiles\": {\r\n          \"$ref\": \"#/definitions/NestedInstallerFiles\"\r\n        },\r\n        \"Scope\": {\r\n          \"$ref\": \"#/definitions/Scope\"\r\n        },\r\n        \"InstallerUrl\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n          \"maxLength\": 2048,\r\n          \"description\": \"The installer Url\"\r\n        },\r\n        \"InstallerSha256\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"Sha256 is required. Sha256 of the installer\"\r\n        },\r\n        \"SignatureSha256\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable\"\r\n        },\r\n        \"InstallModes\": {\r\n          \"$ref\": \"#/definitions/InstallModes\"\r\n        },\r\n        \"InstallerSwitches\": {\r\n          \"$ref\": \"#/definitions/InstallerSwitches\"\r\n        },\r\n        \"InstallerSuccessCodes\": {\r\n          \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n        },\r\n        \"ExpectedReturnCodes\": {\r\n          \"$ref\": \"#/definitions/ExpectedReturnCodes\"\r\n        },\r\n        \"UpgradeBehavior\": {\r\n          \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n        },\r\n        \"Commands\": {\r\n          \"$ref\": \"#/definitions/Commands\"\r\n        },\r\n        \"Protocols\": {\r\n          \"$ref\": \"#/definitions/Protocols\"\r\n        },\r\n        \"FileExtensions\": {\r\n          \"$ref\": \"#/definitions/FileExtensions\"\r\n        },\r\n        \"Dependencies\": {\r\n          \"$ref\": \"#/definitions/Dependencies\"\r\n        },\r\n        \"PackageFamilyName\": {\r\n          \"$ref\": \"#/definitions/PackageFamilyName\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"Capabilities\": {\r\n          \"$ref\": \"#/definitions/Capabilities\"\r\n        },\r\n        \"RestrictedCapabilities\": {\r\n          \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n        },\r\n        \"Markets\": {\r\n          \"$ref\": \"#/definitions/Markets\"\r\n        },\r\n        \"InstallerAbortsTerminal\": {\r\n          \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\r\n        },\r\n        \"ReleaseDate\": {\r\n          \"$ref\": \"#/definitions/ReleaseDate\"\r\n        },\r\n        \"InstallLocationRequired\": {\r\n          \"$ref\": \"#/definitions/InstallLocationRequired\"\r\n        },\r\n        \"RequireExplicitUpgrade\": {\r\n          \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\r\n        },\r\n        \"DisplayInstallWarnings\": {\r\n          \"$ref\": \"#/definitions/DisplayInstallWarnings\"\r\n        },\r\n        \"UnsupportedOSArchitectures\": {\r\n          \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\r\n        },\r\n        \"UnsupportedArguments\": {\r\n          \"$ref\": \"#/definitions/UnsupportedArguments\"\r\n        },\r\n        \"AppsAndFeaturesEntries\": {\r\n          \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\r\n        },\r\n        \"ElevationRequirement\": {\r\n          \"$ref\": \"#/definitions/ElevationRequirement\"\r\n        },\r\n        \"InstallationMetadata\": {\r\n          \"$ref\": \"#/definitions/InstallationMetadata\"\r\n        },\r\n        \"DownloadCommandProhibited\": {\r\n          \"$ref\": \"#/definitions/DownloadCommandProhibited\"\r\n        }\r\n      },\r\n      \"required\": [\r\n        \"Architecture\",\r\n        \"InstallerUrl\",\r\n        \"InstallerSha256\"\r\n      ]\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"$ref\": \"#/definitions/PackageIdentifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"$ref\": \"#/definitions/PackageVersion\"\r\n    },\r\n    \"Channel\": {\r\n      \"$ref\": \"#/definitions/Channel\"\r\n    },\r\n    \"InstallerLocale\": {\r\n      \"$ref\": \"#/definitions/Locale\"\r\n    },\r\n    \"Platform\": {\r\n      \"$ref\": \"#/definitions/Platform\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"$ref\": \"#/definitions/InstallerType\"\r\n    },\r\n    \"NestedInstallerType\": {\r\n      \"$ref\": \"#/definitions/NestedInstallerType\"\r\n    },\r\n    \"NestedInstallerFiles\": {\r\n      \"$ref\": \"#/definitions/NestedInstallerFiles\"\r\n    },\r\n    \"Scope\": {\r\n      \"$ref\": \"#/definitions/Scope\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"$ref\": \"#/definitions/InstallModes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"$ref\": \"#/definitions/InstallerSwitches\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n    },\r\n    \"ExpectedReturnCodes\": {\r\n      \"$ref\": \"#/definitions/ExpectedReturnCodes\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n    },\r\n    \"Commands\": {\r\n      \"$ref\": \"#/definitions/Commands\"\r\n    },\r\n    \"Protocols\": {\r\n      \"$ref\": \"#/definitions/Protocols\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"$ref\": \"#/definitions/FileExtensions\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"$ref\": \"#/definitions/Dependencies\"\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"$ref\": \"#/definitions/PackageFamilyName\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"$ref\": \"#/definitions/ProductCode\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"$ref\": \"#/definitions/Capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n    },\r\n    \"Markets\": {\r\n      \"$ref\": \"#/definitions/Markets\"\r\n    },\r\n    \"InstallerAbortsTerminal\": {\r\n      \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\r\n    },\r\n    \"ReleaseDate\": {\r\n      \"$ref\": \"#/definitions/ReleaseDate\"\r\n    },\r\n    \"InstallLocationRequired\": {\r\n      \"$ref\": \"#/definitions/InstallLocationRequired\"\r\n    },\r\n    \"RequireExplicitUpgrade\": {\r\n      \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\r\n    },\r\n    \"DisplayInstallWarnings\": {\r\n      \"$ref\": \"#/definitions/DisplayInstallWarnings\"\r\n    },\r\n    \"UnsupportedOSArchitectures\": {\r\n      \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\r\n    },\r\n    \"UnsupportedArguments\": {\r\n      \"$ref\": \"#/definitions/UnsupportedArguments\"\r\n    },\r\n    \"AppsAndFeaturesEntries\": {\r\n      \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\r\n    },\r\n    \"ElevationRequirement\": {\r\n      \"$ref\": \"#/definitions/ElevationRequirement\"\r\n    },\r\n    \"InstallationMetadata\": {\r\n      \"$ref\": \"#/definitions/InstallationMetadata\"\r\n    },\r\n    \"DownloadCommandProhibited\": {\r\n      \"$ref\": \"#/definitions/DownloadCommandProhibited\"\r\n    },\r\n    \"Installers\": {\r\n      \"type\": \"array\",\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Installer\"\r\n      },\r\n      \"minItems\": 1,\r\n      \"maxItems\": 1024\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"installer\",\r\n      \"const\": \"installer\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.6.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"Installers\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}\r\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.6.0/manifest.locale.1.6.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.locale.1.6.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a multiple-file manifest representing app metadata in other locale in the OWC. v1.6.0\",\r\n  \"definitions\": {\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Optional Url type\"\r\n    },\r\n    \"Tag\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 40,\r\n      \"description\": \"Package tag\"\r\n    },\r\n    \"Agreement\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"AgreementLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\r\n        },\r\n        \"Agreement\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 10000,\r\n          \"description\": \"The agreement text content.\"\r\n        },\r\n        \"AgreementUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The agreement URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Documentation\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DocumentLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\r\n        },\r\n        \"DocumentUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The documentation URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Icon\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"IconUrl\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n          \"maxLength\": 2048,\r\n          \"description\": \"The url of the hosted icon file\"\r\n        },\r\n        \"IconFileType\": {\r\n          \"type\": \"string\",\r\n          \"enum\": [\r\n            \"png\",\r\n            \"jpeg\",\r\n            \"ico\"\r\n          ],\r\n          \"description\": \"The icon file type\"\r\n        },\r\n        \"IconResolution\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"enum\": [\r\n            \"custom\",\r\n            \"16x16\",\r\n            \"20x20\",\r\n            \"24x24\",\r\n            \"30x30\",\r\n            \"32x32\",\r\n            \"36x36\",\r\n            \"40x40\",\r\n            \"48x48\",\r\n            \"60x60\",\r\n            \"64x64\",\r\n            \"72x72\",\r\n            \"80x80\",\r\n            \"96x96\",\r\n            \"256x256\"\r\n          ],\r\n          \"description\": \"Optional icon resolution\"\r\n        },\r\n        \"IconTheme\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"enum\": [\r\n            \"default\",\r\n            \"light\",\r\n            \"dark\",\r\n            \"highContrast\"\r\n          ],\r\n          \"description\": \"Optional icon theme\"\r\n        },\r\n        \"IconSha256\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"Optional Sha256 of the icon file\"\r\n        }\r\n      },\r\n      \"required\": [\r\n        \"IconUrl\",\r\n        \"IconFileType\"\r\n      ]\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"PackageLocale\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The package meta-data locale\"\r\n    },\r\n    \"Publisher\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The publisher name\"\r\n    },\r\n    \"PublisherUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher home page\"\r\n    },\r\n    \"PublisherSupportUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher support page\"\r\n    },\r\n    \"PrivacyUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher privacy page or the package privacy page\"\r\n    },\r\n    \"Author\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package author\"\r\n    },\r\n    \"PackageName\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package name\"\r\n    },\r\n    \"PackageUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package home page\"\r\n    },\r\n    \"License\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package license\"\r\n    },\r\n    \"LicenseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The license page\"\r\n    },\r\n    \"Copyright\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package copyright\"\r\n    },\r\n    \"CopyrightUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package copyright page\"\r\n    },\r\n    \"ShortDescription\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The short package description\"\r\n    },\r\n    \"Description\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The full package description\"\r\n    },\r\n    \"Tags\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Tag\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional package search terms\"\r\n    },\r\n    \"Agreements\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Agreement\"\r\n      },\r\n      \"maxItems\": 128\r\n    },\r\n    \"ReleaseNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The package release notes\"\r\n    },\r\n    \"ReleaseNotesUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package release notes url\"\r\n    },\r\n    \"PurchaseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\r\n    },\r\n    \"InstallationNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"\r\n    },\r\n    \"Documentations\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Documentation\"\r\n      },\r\n      \"maxItems\": 256\r\n    },\r\n    \"Icons\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Icon\"\r\n      },\r\n      \"maxItems\": 1024\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"locale\",\r\n      \"const\": \"locale\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.6.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"PackageLocale\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}\r\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.6.0/manifest.singleton.1.6.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.singleton.1.6.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a single-file manifest representing an app in the OWC. v1.6.0\",\r\n  \"definitions\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"Locale\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The package meta-data locale\"\r\n    },\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Optional Url type\"\r\n    },\r\n    \"Tag\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 40,\r\n      \"description\": \"Package moniker or tag\"\r\n    },\r\n    \"Agreement\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"AgreementLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\r\n        },\r\n        \"Agreement\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 10000,\r\n          \"description\": \"The agreement text content.\"\r\n        },\r\n        \"AgreementUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The agreement URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Documentation\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DocumentLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\r\n        },\r\n        \"DocumentUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The documentation URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Icon\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"IconUrl\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n          \"maxLength\": 2048,\r\n          \"description\": \"The url of the hosted icon file\"\r\n        },\r\n        \"IconFileType\": {\r\n          \"type\": \"string\",\r\n          \"enum\": [\r\n            \"png\",\r\n            \"jpeg\",\r\n            \"ico\"\r\n          ],\r\n          \"description\": \"The icon file type\"\r\n        },\r\n        \"IconResolution\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"enum\": [\r\n            \"custom\",\r\n            \"16x16\",\r\n            \"20x20\",\r\n            \"24x24\",\r\n            \"30x30\",\r\n            \"32x32\",\r\n            \"36x36\",\r\n            \"40x40\",\r\n            \"48x48\",\r\n            \"60x60\",\r\n            \"64x64\",\r\n            \"72x72\",\r\n            \"80x80\",\r\n            \"96x96\",\r\n            \"256x256\"\r\n          ],\r\n          \"description\": \"Optional icon resolution\"\r\n        },\r\n        \"IconTheme\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"enum\": [\r\n            \"default\",\r\n            \"light\",\r\n            \"dark\",\r\n            \"highContrast\"\r\n          ],\r\n          \"description\": \"Optional icon theme\"\r\n        },\r\n        \"IconSha256\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"Optional Sha256 of the icon file\"\r\n        }\r\n      },\r\n      \"required\": [\r\n        \"IconUrl\",\r\n        \"IconFileType\"\r\n      ]\r\n    },\r\n    \"Channel\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 16,\r\n      \"description\": \"The distribution channel\"\r\n    },\r\n    \"Platform\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"Platform\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"Windows.Desktop\",\r\n          \"Windows.Universal\"\r\n        ]\r\n      },\r\n      \"maxItems\": 2,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"The installer supported operating system\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$\",\r\n      \"description\": \"The installer minimum operating system version\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"msix\",\r\n        \"msi\",\r\n        \"appx\",\r\n        \"exe\",\r\n        \"zip\",\r\n        \"inno\",\r\n        \"nullsoft\",\r\n        \"wix\",\r\n        \"burn\",\r\n        \"pwa\",\r\n        \"portable\"\r\n      ],\r\n      \"description\": \"Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level\"\r\n    },\r\n    \"NestedInstallerType\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"msix\",\r\n        \"msi\",\r\n        \"appx\",\r\n        \"exe\",\r\n        \"inno\",\r\n        \"nullsoft\",\r\n        \"wix\",\r\n        \"burn\",\r\n        \"portable\"\r\n      ],\r\n      \"description\": \"Enumeration of supported nested installer types contained inside an archive file\"\r\n    },\r\n    \"NestedInstallerFiles\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"object\",\r\n        \"title\": \"NestedInstallerFile\",\r\n        \"properties\": {\r\n          \"RelativeFilePath\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 512,\r\n            \"description\": \"The relative path to the nested installer file\"\r\n          },\r\n          \"PortableCommandAlias\": {\r\n            \"type\": [ \"string\", \"null\" ],\r\n            \"minLength\": 1,\r\n            \"maxLength\": 40,\r\n            \"description\": \"The command alias to be used for calling the package. Only applies to the nested portable package\"\r\n          }\r\n        },\r\n        \"required\": [ \"RelativeFilePath\" ],\r\n        \"description\": \"A nested installer file contained inside an archive\"\r\n      },\r\n      \"maxItems\": 1024,\r\n      \"description\": \"List of nested installer files contained inside an archive\"\r\n    },\r\n    \"Architecture\": {\r\n      \"type\": \"string\",\r\n      \"enum\": [\r\n        \"x86\",\r\n        \"x64\",\r\n        \"arm\",\r\n        \"arm64\",\r\n        \"neutral\"\r\n      ],\r\n      \"description\": \"The installer target architecture\"\r\n    },\r\n    \"Scope\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"user\",\r\n        \"machine\"\r\n      ],\r\n      \"description\": \"Scope indicates if the installer is per user or per machine\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"InstallModes\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"interactive\",\r\n          \"silent\",\r\n          \"silentWithProgress\"\r\n        ]\r\n      },\r\n      \"maxItems\": 3,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of supported installer modes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"Silent\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Silent is the value that should be passed to the installer when user chooses a silent or quiet install\"\r\n        },\r\n        \"SilentWithProgress\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install\"\r\n        },\r\n        \"Interactive\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Interactive is the value that should be passed to the installer when user chooses an interactive install\"\r\n        },\r\n        \"InstallLocation\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"InstallLocation is the value passed to the installer for custom install location. <INSTALLPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Log\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Log is the value passed to the installer for custom log file path. <LOGPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Upgrade\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Upgrade is the value that should be passed to the installer when user chooses an upgrade\"\r\n        },\r\n        \"Custom\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 2048,\r\n          \"description\": \"Custom switches will be passed directly to the installer by winget\"\r\n        }\r\n      }\r\n    },\r\n    \"InstallerReturnCode\": {\r\n      \"type\": \"integer\",\r\n      \"format\": \"long\",\r\n      \"not\": {\r\n        \"enum\": [ 0 ]\r\n      },\r\n      \"minimum\": -2147483648,\r\n      \"maximum\": 4294967295,\r\n      \"description\": \"An exit code that can be returned by the installer after execution\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/InstallerReturnCode\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional non-zero installer success exit codes other than known default values by winget\"\r\n    },\r\n    \"ExpectedReturnCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"object\",\r\n        \"title\": \"ExpectedReturnCode\",\r\n        \"properties\": {\r\n          \"InstallerReturnCode\": {\r\n            \"$ref\": \"#/definitions/InstallerReturnCode\"\r\n          },\r\n          \"ReturnResponse\": {\r\n            \"type\": \"string\",\r\n            \"enum\": [\r\n              \"packageInUse\",\r\n              \"packageInUseByApplication\",\r\n              \"installInProgress\",\r\n              \"fileInUse\",\r\n              \"missingDependency\",\r\n              \"diskFull\",\r\n              \"insufficientMemory\",\r\n              \"invalidParameter\",\r\n              \"noNetwork\",\r\n              \"contactSupport\",\r\n              \"rebootRequiredToFinish\",\r\n              \"rebootRequiredForInstall\",\r\n              \"rebootInitiated\",\r\n              \"cancelledByUser\",\r\n              \"alreadyInstalled\",\r\n              \"downgrade\",\r\n              \"blockedByPolicy\",\r\n              \"systemNotSupported\",\r\n              \"custom\"\r\n            ]\r\n          },\r\n          \"ReturnResponseUrl\": {\r\n            \"$ref\": \"#/definitions/Url\",\r\n            \"description\": \"The return response url to provide additional guidance for expected return codes\"\r\n          }\r\n        },\r\n        \"required\": [ \"InstallerReturnCode\", \"ReturnResponse\" ]\r\n      },\r\n      \"maxItems\": 128,\r\n      \"description\": \"Installer exit codes for common errors\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"install\",\r\n        \"uninstallPrevious\",\r\n        \"deny\"\r\n      ],\r\n      \"description\": \"The upgrade method\"\r\n    },\r\n    \"Commands\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of commands or aliases to run the package\"\r\n    },\r\n    \"Protocols\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"maxLength\": 2048\r\n      },\r\n      \"maxItems\": 64,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of protocols the package provides a handler for\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n        \"maxLength\": 64\r\n      },\r\n      \"maxItems\": 512,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of file extensions the package could support\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"properties\": {\r\n        \"WindowsFeatures\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows feature dependencies\"\r\n        },\r\n        \"WindowsLibraries\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows library dependencies\"\r\n        },\r\n        \"PackageDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"object\",\r\n            \"properties\": {\r\n              \"PackageIdentifier\": {\r\n                \"$ref\": \"#/definitions/PackageIdentifier\"\r\n              },\r\n              \"MinimumVersion\": {\r\n                \"$ref\": \"#/definitions/PackageVersion\"\r\n              }\r\n            },\r\n            \"required\": [ \"PackageIdentifier\" ]\r\n          },\r\n          \"maxItems\": 16,\r\n          \"description\": \"List of package dependencies from current source\"\r\n        },\r\n        \"ExternalDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of external package dependencies\"\r\n        }\r\n      }\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^[A-Za-z0-9][-\\\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$\",\r\n      \"maxLength\": 255,\r\n      \"description\": \"PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 255,\r\n      \"description\": \"ProductCode could be used for correlation of packages across sources\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer restricted capabilities\"\r\n    },\r\n    \"Market\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[A-Z]{2}$\",\r\n      \"description\": \"The installer target market\"\r\n    },\r\n    \"MarketArray\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"maxItems\": 256,\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Market\"\r\n      },\r\n      \"description\": \"Array of markets\"\r\n    },\r\n    \"Markets\": {\r\n      \"description\": \"The installer markets\",\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"oneOf\": [\r\n        {\r\n          \"properties\": {\r\n            \"AllowedMarkets\": {\r\n              \"$ref\": \"#/definitions/MarketArray\"\r\n            }\r\n          },\r\n          \"required\": [ \"AllowedMarkets\" ]\r\n        },\r\n        {\r\n          \"properties\": {\r\n            \"ExcludedMarkets\": {\r\n              \"$ref\": \"#/definitions/MarketArray\"\r\n            }\r\n          },\r\n          \"required\": [ \"ExcludedMarkets\" ]\r\n        }\r\n      ]\r\n    },\r\n    \"InstallerAbortsTerminal\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer will abort terminal. Default is false\"\r\n    },\r\n    \"ReleaseDate\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"format\": \"date\",\r\n      \"description\": \"The installer release date\"\r\n    },\r\n    \"InstallLocationRequired\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer requires an install location provided\"\r\n    },\r\n    \"RequireExplicitUpgrade\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer should be pinned by default from upgrade\"\r\n    },\r\n    \"DisplayInstallWarnings\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications.\"\r\n    },\r\n    \"UnsupportedOSArchitectures\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"title\": \"UnsupportedOSArchitecture\",\r\n        \"enum\": [\r\n          \"x86\",\r\n          \"x64\",\r\n          \"arm\",\r\n          \"arm64\"\r\n        ]\r\n      },\r\n      \"description\": \"List of OS architectures the installer does not support\"\r\n    },\r\n    \"UnsupportedArguments\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"title\": \"UnsupportedArgument\",\r\n        \"enum\": [\r\n          \"log\",\r\n          \"location\"\r\n        ]\r\n      },\r\n      \"description\": \"List of winget arguments the installer does not support\"\r\n    },\r\n    \"AppsAndFeaturesEntry\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DisplayName\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 256,\r\n          \"description\": \"The DisplayName registry value\"\r\n        },\r\n        \"Publisher\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 256,\r\n          \"description\": \"The Publisher registry value\"\r\n        },\r\n        \"DisplayVersion\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 128,\r\n          \"description\": \"The DisplayVersion registry value\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"UpgradeCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        }\r\n      },\r\n      \"description\": \"Various key values under installer's ARP entry\"\r\n    },\r\n    \"AppsAndFeaturesEntries\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"maxItems\": 128,\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/AppsAndFeaturesEntry\"\r\n      },\r\n      \"description\": \"List of ARP entries.\"\r\n    },\r\n    \"ElevationRequirement\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"elevationRequired\",\r\n        \"elevationProhibited\",\r\n        \"elevatesSelf\"\r\n      ],\r\n      \"description\": \"The installer's elevation requirement\"\r\n    },\r\n    \"InstallationMetadata\": {\r\n      \"type\": \"object\",\r\n      \"title\": \"InstallationMetadata\",\r\n      \"properties\": {\r\n        \"DefaultInstallLocation\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 2048,\r\n          \"description\": \"Represents the default installed package location. Used for deeper installation detection.\"\r\n        },\r\n        \"Files\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"uniqueItems\": true,\r\n          \"maxItems\": 2048,\r\n          \"items\": {\r\n            \"type\": \"object\",\r\n            \"title\": \"InstalledFile\",\r\n            \"properties\": {\r\n              \"RelativeFilePath\": {\r\n                \"type\": \"string\",\r\n                \"minLength\": 1,\r\n                \"maxLength\": 2048,\r\n                \"description\": \"The relative path to the installed file.\"\r\n              },\r\n              \"FileSha256\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n                \"description\": \"Optional Sha256 of the installed file.\"\r\n              },\r\n              \"FileType\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"enum\": [\r\n                  \"launch\",\r\n                  \"uninstall\",\r\n                  \"other\"\r\n                ],\r\n                \"description\": \"The optional installed file type. If not specified, the file is treated as other.\"\r\n              },\r\n              \"InvocationParameter\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"minLength\": 1,\r\n                \"maxLength\": 2048,\r\n                \"description\": \"Optional parameter for invocable files.\"\r\n              },\r\n              \"DisplayName\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"minLength\": 1,\r\n                \"maxLength\": 256,\r\n                \"description\": \"Optional display name for invocable files.\"\r\n              }\r\n            },\r\n            \"required\": [ \"RelativeFilePath\" ],\r\n            \"description\": \"Represents an installed file.\"\r\n          },\r\n          \"description\": \"List of installed files.\"\r\n        }\r\n      },\r\n      \"description\": \"Details about the installation. Used for deeper installation detection.\"\r\n    },\r\n    \"DownloadCommandProhibited\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer is prohibited from being downloaded for offline installation.\"\r\n    },\r\n    \"Installer\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"InstallerLocale\": {\r\n          \"$ref\": \"#/definitions/Locale\"\r\n        },\r\n        \"Platform\": {\r\n          \"$ref\": \"#/definitions/Platform\"\r\n        },\r\n        \"MinimumOSVersion\": {\r\n          \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n        },\r\n        \"Architecture\": {\r\n          \"$ref\": \"#/definitions/Architecture\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        },\r\n        \"NestedInstallerType\": {\r\n          \"$ref\": \"#/definitions/NestedInstallerType\"\r\n        },\r\n        \"NestedInstallerFiles\": {\r\n          \"$ref\": \"#/definitions/NestedInstallerFiles\"\r\n        },\r\n        \"Scope\": {\r\n          \"$ref\": \"#/definitions/Scope\"\r\n        },\r\n        \"InstallerUrl\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n          \"maxLength\": 2048,\r\n          \"description\": \"The installer Url\"\r\n        },\r\n        \"InstallerSha256\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"Sha256 is required. Sha256 of the installer\"\r\n        },\r\n        \"SignatureSha256\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable\"\r\n        },\r\n        \"InstallModes\": {\r\n          \"$ref\": \"#/definitions/InstallModes\"\r\n        },\r\n        \"InstallerSwitches\": {\r\n          \"$ref\": \"#/definitions/InstallerSwitches\"\r\n        },\r\n        \"InstallerSuccessCodes\": {\r\n          \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n        },\r\n        \"ExpectedReturnCodes\": {\r\n          \"$ref\": \"#/definitions/ExpectedReturnCodes\"\r\n        },\r\n        \"UpgradeBehavior\": {\r\n          \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n        },\r\n        \"Commands\": {\r\n          \"$ref\": \"#/definitions/Commands\"\r\n        },\r\n        \"Protocols\": {\r\n          \"$ref\": \"#/definitions/Protocols\"\r\n        },\r\n        \"FileExtensions\": {\r\n          \"$ref\": \"#/definitions/FileExtensions\"\r\n        },\r\n        \"Dependencies\": {\r\n          \"$ref\": \"#/definitions/Dependencies\"\r\n        },\r\n        \"PackageFamilyName\": {\r\n          \"$ref\": \"#/definitions/PackageFamilyName\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"Capabilities\": {\r\n          \"$ref\": \"#/definitions/Capabilities\"\r\n        },\r\n        \"RestrictedCapabilities\": {\r\n          \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n        },\r\n        \"Markets\": {\r\n          \"$ref\": \"#/definitions/Markets\"\r\n        },\r\n        \"InstallerAbortsTerminal\": {\r\n          \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\r\n        },\r\n        \"ReleaseDate\": {\r\n          \"$ref\": \"#/definitions/ReleaseDate\"\r\n        },\r\n        \"InstallLocationRequired\": {\r\n          \"$ref\": \"#/definitions/InstallLocationRequired\"\r\n        },\r\n        \"RequireExplicitUpgrade\": {\r\n          \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\r\n        },\r\n        \"DisplayInstallWarnings\": {\r\n          \"$ref\": \"#/definitions/DisplayInstallWarnings\"\r\n        },\r\n        \"UnsupportedOSArchitectures\": {\r\n          \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\r\n        },\r\n        \"UnsupportedArguments\": {\r\n          \"$ref\": \"#/definitions/UnsupportedArguments\"\r\n        },\r\n        \"AppsAndFeaturesEntries\": {\r\n          \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\r\n        },\r\n        \"ElevationRequirement\": {\r\n          \"$ref\": \"#/definitions/ElevationRequirement\"\r\n        },\r\n        \"InstallationMetadata\": {\r\n          \"$ref\": \"#/definitions/InstallationMetadata\"\r\n        },\r\n        \"DownloadCommandProhibited\": {\r\n          \"$ref\": \"#/definitions/DownloadCommandProhibited\"\r\n        }\r\n      },\r\n      \"required\": [\r\n        \"Architecture\",\r\n        \"InstallerUrl\",\r\n        \"InstallerSha256\"\r\n      ]\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"$ref\": \"#/definitions/PackageIdentifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"$ref\": \"#/definitions/PackageVersion\"\r\n    },\r\n    \"PackageLocale\": {\r\n      \"$ref\": \"#/definitions/Locale\"\r\n    },\r\n    \"Publisher\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The publisher name\"\r\n    },\r\n    \"PublisherUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher home page\"\r\n    },\r\n    \"PublisherSupportUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher support page\"\r\n    },\r\n    \"PrivacyUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher privacy page or the package privacy page\"\r\n    },\r\n    \"Author\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package author\"\r\n    },\r\n    \"PackageName\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package name\"\r\n    },\r\n    \"PackageUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package home page\"\r\n    },\r\n    \"License\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package license\"\r\n    },\r\n    \"LicenseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The license page\"\r\n    },\r\n    \"Copyright\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package copyright\"\r\n    },\r\n    \"CopyrightUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package copyright page\"\r\n    },\r\n    \"ShortDescription\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The short package description\"\r\n    },\r\n    \"Description\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The full package description\"\r\n    },\r\n    \"Moniker\": {\r\n      \"$ref\": \"#/definitions/Tag\",\r\n      \"description\": \"The most common package term\"\r\n    },\r\n    \"Tags\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Tag\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional package search terms\"\r\n    },\r\n    \"Agreements\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Agreement\"\r\n      },\r\n      \"maxItems\": 128\r\n    },\r\n    \"ReleaseNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The package release notes\"\r\n    },\r\n    \"ReleaseNotesUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package release notes url\"\r\n    },\r\n    \"PurchaseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\r\n    },\r\n    \"InstallationNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"\r\n    },\r\n    \"Documentations\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Documentation\"\r\n      },\r\n      \"maxItems\": 256\r\n    },\r\n    \"Icons\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Icon\"\r\n      },\r\n      \"maxItems\": 1024\r\n    },\r\n    \"Channel\": {\r\n      \"$ref\": \"#/definitions/Channel\"\r\n    },\r\n    \"InstallerLocale\": {\r\n      \"$ref\": \"#/definitions/Locale\"\r\n    },\r\n    \"Platform\": {\r\n      \"$ref\": \"#/definitions/Platform\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"$ref\": \"#/definitions/InstallerType\"\r\n    },\r\n    \"NestedInstallerType\": {\r\n      \"$ref\": \"#/definitions/NestedInstallerType\"\r\n    },\r\n    \"NestedInstallerFiles\": {\r\n      \"$ref\": \"#/definitions/NestedInstallerFiles\"\r\n    },\r\n    \"Scope\": {\r\n      \"$ref\": \"#/definitions/Scope\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"$ref\": \"#/definitions/InstallModes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"$ref\": \"#/definitions/InstallerSwitches\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n    },\r\n    \"ExpectedReturnCodes\": {\r\n      \"$ref\": \"#/definitions/ExpectedReturnCodes\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n    },\r\n    \"Commands\": {\r\n      \"$ref\": \"#/definitions/Commands\"\r\n    },\r\n    \"Protocols\": {\r\n      \"$ref\": \"#/definitions/Protocols\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"$ref\": \"#/definitions/FileExtensions\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"$ref\": \"#/definitions/Dependencies\"\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"$ref\": \"#/definitions/PackageFamilyName\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"$ref\": \"#/definitions/ProductCode\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"$ref\": \"#/definitions/Capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n    },\r\n    \"Markets\": {\r\n      \"$ref\": \"#/definitions/Markets\"\r\n    },\r\n    \"InstallerAbortsTerminal\": {\r\n      \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\r\n    },\r\n    \"ReleaseDate\": {\r\n      \"$ref\": \"#/definitions/ReleaseDate\"\r\n    },\r\n    \"InstallLocationRequired\": {\r\n      \"$ref\": \"#/definitions/InstallLocationRequired\"\r\n    },\r\n    \"RequireExplicitUpgrade\": {\r\n      \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\r\n    },\r\n    \"DisplayInstallWarnings\": {\r\n      \"$ref\": \"#/definitions/DisplayInstallWarnings\"\r\n    },\r\n    \"UnsupportedOSArchitectures\": {\r\n      \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\r\n    },\r\n    \"UnsupportedArguments\": {\r\n      \"$ref\": \"#/definitions/UnsupportedArguments\"\r\n    },\r\n    \"AppsAndFeaturesEntries\": {\r\n      \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\r\n    },\r\n    \"ElevationRequirement\": {\r\n      \"$ref\": \"#/definitions/ElevationRequirement\"\r\n    },\r\n    \"InstallationMetadata\": {\r\n      \"$ref\": \"#/definitions/InstallationMetadata\"\r\n    },\r\n    \"DownloadCommandProhibited\": {\r\n      \"$ref\": \"#/definitions/DownloadCommandProhibited\"\r\n    },\r\n    \"Installers\": {\r\n      \"type\": \"array\",\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Installer\"\r\n      },\r\n      \"minItems\": 1,\r\n      \"maxItems\": 1\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"singleton\",\r\n      \"const\": \"singleton\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.6.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"PackageLocale\",\r\n    \"Publisher\",\r\n    \"PackageName\",\r\n    \"License\",\r\n    \"ShortDescription\",\r\n    \"Installers\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}\r\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.6.0/manifest.version.1.6.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.version.1.6.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a multi-file manifest representing an app version in the OWC. v1.6.0\",\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"DefaultLocale\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"en-US\",\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The default package meta-data locale\"\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"version\",\r\n      \"const\": \"version\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.6.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"DefaultLocale\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}"
  },
  {
    "path": "schemas/JSON/manifests/v1.7.0/manifest.defaultLocale.1.7.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.defaultlocale.1.7.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a multiple-file manifest representing a default app metadata in the OWC. v1.7.0\",\r\n  \"definitions\": {\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Optional Url type\"\r\n    },\r\n    \"Tag\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 40,\r\n      \"description\": \"Package moniker or tag\"\r\n    },\r\n    \"Agreement\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"AgreementLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\r\n        },\r\n        \"Agreement\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 10000,\r\n          \"description\": \"The agreement text content.\"\r\n        },\r\n        \"AgreementUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The agreement URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Documentation\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DocumentLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\r\n        },\r\n        \"DocumentUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The documentation URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Icon\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"IconUrl\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n          \"maxLength\": 2048,\r\n          \"description\": \"The url of the hosted icon file\"\r\n        },\r\n        \"IconFileType\": {\r\n          \"type\": \"string\",\r\n          \"enum\": [\r\n            \"png\",\r\n            \"jpeg\",\r\n            \"ico\"\r\n          ],\r\n          \"description\": \"The icon file type\"\r\n        },\r\n        \"IconResolution\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"enum\": [\r\n            \"custom\",\r\n            \"16x16\",\r\n            \"20x20\",\r\n            \"24x24\",\r\n            \"30x30\",\r\n            \"32x32\",\r\n            \"36x36\",\r\n            \"40x40\",\r\n            \"48x48\",\r\n            \"60x60\",\r\n            \"64x64\",\r\n            \"72x72\",\r\n            \"80x80\",\r\n            \"96x96\",\r\n            \"256x256\"\r\n          ],\r\n          \"description\": \"Optional icon resolution\"\r\n        },\r\n        \"IconTheme\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"enum\": [\r\n            \"default\",\r\n            \"light\",\r\n            \"dark\",\r\n            \"highContrast\"\r\n          ],\r\n          \"description\": \"Optional icon theme\"\r\n        },\r\n        \"IconSha256\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"Optional Sha256 of the icon file\"\r\n        }\r\n      },\r\n      \"required\": [\r\n        \"IconUrl\",\r\n        \"IconFileType\"\r\n      ]\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"PackageLocale\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"en-US\",\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The package meta-data locale\"\r\n    },\r\n    \"Publisher\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The publisher name\"\r\n    },\r\n    \"PublisherUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher home page\"\r\n    },\r\n    \"PublisherSupportUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher support page\"\r\n    },\r\n    \"PrivacyUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher privacy page or the package privacy page\"\r\n    },\r\n    \"Author\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package author\"\r\n    },\r\n    \"PackageName\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package name\"\r\n    },\r\n    \"PackageUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package home page\"\r\n    },\r\n    \"License\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package license\"\r\n    },\r\n    \"LicenseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The license page\"\r\n    },\r\n    \"Copyright\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package copyright\"\r\n    },\r\n    \"CopyrightUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package copyright page\"\r\n    },\r\n    \"ShortDescription\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The short package description\"\r\n    },\r\n    \"Description\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The full package description\"\r\n    },\r\n    \"Moniker\": {\r\n      \"$ref\": \"#/definitions/Tag\",\r\n      \"description\": \"The most common package term\"\r\n    },\r\n    \"Tags\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Tag\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional package search terms\"\r\n    },\r\n    \"Agreements\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Agreement\"\r\n      },\r\n      \"maxItems\": 128\r\n    },\r\n    \"ReleaseNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The package release notes\"\r\n    },\r\n    \"ReleaseNotesUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package release notes url\"\r\n    },\r\n    \"PurchaseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\r\n    },\r\n    \"InstallationNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"\r\n    },\r\n    \"Documentations\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Documentation\"\r\n      },\r\n      \"maxItems\": 256\r\n    },\r\n    \"Icons\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Icon\"\r\n      },\r\n      \"maxItems\": 1024\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"defaultLocale\",\r\n      \"const\": \"defaultLocale\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.7.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"PackageLocale\",\r\n    \"Publisher\",\r\n    \"PackageName\",\r\n    \"License\",\r\n    \"ShortDescription\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}\r\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.7.0/manifest.installer.1.7.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.installer.1.7.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a single-file manifest representing an app installers in the OWC. v1.7.0\",\r\n  \"definitions\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"Locale\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The installer meta-data locale\"\r\n    },\r\n    \"Channel\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 16,\r\n      \"description\": \"The distribution channel\"\r\n    },\r\n    \"Platform\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"Platform\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"Windows.Desktop\",\r\n          \"Windows.Universal\"\r\n        ]\r\n      },\r\n      \"maxItems\": 2,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"The installer supported operating system\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$\",\r\n      \"description\": \"The installer minimum operating system version\"\r\n    },\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Url type\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"msix\",\r\n        \"msi\",\r\n        \"appx\",\r\n        \"exe\",\r\n        \"zip\",\r\n        \"inno\",\r\n        \"nullsoft\",\r\n        \"wix\",\r\n        \"burn\",\r\n        \"pwa\",\r\n        \"portable\"\r\n      ],\r\n      \"description\": \"Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level\"\r\n    },\r\n    \"NestedInstallerType\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"msix\",\r\n        \"msi\",\r\n        \"appx\",\r\n        \"exe\",\r\n        \"inno\",\r\n        \"nullsoft\",\r\n        \"wix\",\r\n        \"burn\",\r\n        \"portable\"\r\n      ],\r\n      \"description\": \"Enumeration of supported nested installer types contained inside an archive file\"\r\n    },\r\n    \"NestedInstallerFiles\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"object\",\r\n        \"title\": \"NestedInstallerFile\",\r\n        \"properties\": {\r\n          \"RelativeFilePath\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 512,\r\n            \"description\": \"The relative path to the nested installer file\"\r\n          },\r\n          \"PortableCommandAlias\": {\r\n            \"type\": [ \"string\", \"null\" ],\r\n            \"minLength\": 1,\r\n            \"maxLength\": 40,\r\n            \"description\": \"The command alias to be used for calling the package. Only applies to the nested portable package\"\r\n          }\r\n        },\r\n        \"required\": [ \"RelativeFilePath\" ],\r\n        \"description\": \"A nested installer file contained inside an archive\"\r\n      },\r\n      \"maxItems\": 1024,\r\n      \"description\": \"List of nested installer files contained inside an archive\"\r\n    },\r\n    \"Architecture\": {\r\n      \"type\": \"string\",\r\n      \"enum\": [\r\n        \"x86\",\r\n        \"x64\",\r\n        \"arm\",\r\n        \"arm64\",\r\n        \"neutral\"\r\n      ],\r\n      \"description\": \"The installer target architecture\"\r\n    },\r\n    \"Scope\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"user\",\r\n        \"machine\"\r\n      ],\r\n      \"description\": \"Scope indicates if the installer is per user or per machine\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"InstallModes\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"interactive\",\r\n          \"silent\",\r\n          \"silentWithProgress\"\r\n        ]\r\n      },\r\n      \"maxItems\": 3,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of supported installer modes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"Silent\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Silent is the value that should be passed to the installer when user chooses a silent or quiet install\"\r\n        },\r\n        \"SilentWithProgress\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install\"\r\n        },\r\n        \"Interactive\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Interactive is the value that should be passed to the installer when user chooses an interactive install\"\r\n        },\r\n        \"InstallLocation\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"InstallLocation is the value passed to the installer for custom install location. <INSTALLPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Log\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Log is the value passed to the installer for custom log file path. <LOGPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Upgrade\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Upgrade is the value that should be passed to the installer when user chooses an upgrade\"\r\n        },\r\n        \"Custom\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 2048,\r\n          \"description\": \"Custom switches will be passed directly to the installer by winget\"\r\n        },\r\n        \"Repair\" : {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"The 'Repair' value must be passed to the installer, ModifyPath ARP command, or uninstaller ARP command when the user opts for a repair.\"\r\n        }\r\n      }\r\n    },\r\n    \"InstallerReturnCode\": {\r\n      \"type\": \"integer\",\r\n      \"format\": \"long\",\r\n      \"not\": {\r\n        \"enum\": [ 0 ]\r\n      },\r\n      \"minimum\": -2147483648,\r\n      \"maximum\": 4294967295,\r\n      \"description\": \"An exit code that can be returned by the installer after execution\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/InstallerReturnCode\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional non-zero installer success exit codes other than known default values by winget\"\r\n    },\r\n    \"ExpectedReturnCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"object\",\r\n        \"title\": \"ExpectedReturnCode\",\r\n        \"properties\": {\r\n          \"InstallerReturnCode\": {\r\n            \"$ref\": \"#/definitions/InstallerReturnCode\"\r\n          },\r\n          \"ReturnResponse\": {\r\n            \"type\": \"string\",\r\n            \"enum\": [\r\n              \"packageInUse\",\r\n              \"packageInUseByApplication\",\r\n              \"installInProgress\",\r\n              \"fileInUse\",\r\n              \"missingDependency\",\r\n              \"diskFull\",\r\n              \"insufficientMemory\",\r\n              \"invalidParameter\",\r\n              \"noNetwork\",\r\n              \"contactSupport\",\r\n              \"rebootRequiredToFinish\",\r\n              \"rebootRequiredForInstall\",\r\n              \"rebootInitiated\",\r\n              \"cancelledByUser\",\r\n              \"alreadyInstalled\",\r\n              \"downgrade\",\r\n              \"blockedByPolicy\",\r\n              \"systemNotSupported\",\r\n              \"custom\"\r\n            ]\r\n          },\r\n          \"ReturnResponseUrl\": {\r\n            \"$ref\": \"#/definitions/Url\",\r\n            \"description\": \"The return response url to provide additional guidance for expected return codes\"\r\n          }\r\n        },\r\n        \"required\": [ \"InstallerReturnCode\", \"ReturnResponse\" ]\r\n      },\r\n      \"maxItems\": 128,\r\n      \"description\": \"Installer exit codes for common errors\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"install\",\r\n        \"uninstallPrevious\",\r\n        \"deny\"\r\n      ],\r\n      \"description\": \"The upgrade method\"\r\n    },\r\n    \"Commands\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of commands or aliases to run the package\"\r\n    },\r\n    \"Protocols\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"maxLength\": 2048\r\n      },\r\n      \"maxItems\": 64,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of protocols the package provides a handler for\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n        \"maxLength\": 64\r\n      },\r\n      \"maxItems\": 512,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of file extensions the package could support\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"properties\": {\r\n        \"WindowsFeatures\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows feature dependencies\"\r\n        },\r\n        \"WindowsLibraries\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows library dependencies\"\r\n        },\r\n        \"PackageDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"object\",\r\n            \"properties\": {\r\n              \"PackageIdentifier\": {\r\n                \"$ref\": \"#/definitions/PackageIdentifier\"\r\n              },\r\n              \"MinimumVersion\": {\r\n                \"$ref\": \"#/definitions/PackageVersion\"\r\n              }\r\n            },\r\n            \"required\": [ \"PackageIdentifier\" ]\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of package dependencies from current source\"\r\n        },\r\n        \"ExternalDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of external package dependencies\"\r\n        }\r\n      }\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^[A-Za-z0-9][-\\\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$\",\r\n      \"maxLength\": 255,\r\n      \"description\": \"PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 255,\r\n      \"description\": \"ProductCode could be used for correlation of packages across sources\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer restricted capabilities\"\r\n    },\r\n    \"Market\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[A-Z]{2}$\",\r\n      \"description\": \"The installer target market\"\r\n    },\r\n    \"MarketArray\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"maxItems\": 256,\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Market\"\r\n      },\r\n      \"description\": \"Array of markets\"\r\n    },\r\n    \"Markets\": {\r\n      \"description\": \"The installer markets\",\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"oneOf\": [\r\n        {\r\n          \"properties\": {\r\n            \"AllowedMarkets\": {\r\n              \"$ref\": \"#/definitions/MarketArray\"\r\n            }\r\n          },\r\n          \"required\": [ \"AllowedMarkets\" ]\r\n        },\r\n        {\r\n          \"properties\": {\r\n            \"ExcludedMarkets\": {\r\n              \"$ref\": \"#/definitions/MarketArray\"\r\n            }\r\n          },\r\n          \"required\": [ \"ExcludedMarkets\" ]\r\n        }\r\n      ]\r\n    },\r\n    \"InstallerAbortsTerminal\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer will abort terminal. Default is false\"\r\n    },\r\n    \"ReleaseDate\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"format\": \"date\",\r\n      \"description\": \"The installer release date\"\r\n    },\r\n    \"InstallLocationRequired\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer requires an install location provided\"\r\n    },\r\n    \"RequireExplicitUpgrade\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer should be pinned by default from upgrade\"\r\n    },\r\n    \"DisplayInstallWarnings\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications.\"\r\n    },\r\n    \"UnsupportedOSArchitectures\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"title\": \"UnsupportedOSArchitecture\",\r\n        \"enum\": [\r\n          \"x86\",\r\n          \"x64\",\r\n          \"arm\",\r\n          \"arm64\"\r\n        ]\r\n      },\r\n      \"description\": \"List of OS architectures the installer does not support\"\r\n    },\r\n    \"UnsupportedArguments\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"title\": \"UnsupportedArgument\",\r\n        \"enum\": [\r\n          \"log\",\r\n          \"location\"\r\n        ]\r\n      },\r\n      \"description\": \"List of winget arguments the installer does not support\"\r\n    },\r\n    \"AppsAndFeaturesEntry\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DisplayName\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 256,\r\n          \"description\": \"The DisplayName registry value\"\r\n        },\r\n        \"Publisher\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 256,\r\n          \"description\": \"The Publisher registry value\"\r\n        },\r\n        \"DisplayVersion\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 128,\r\n          \"description\": \"The DisplayVersion registry value\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"UpgradeCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        }\r\n      },\r\n      \"description\": \"Various key values under installer's ARP entry\"\r\n    },\r\n    \"AppsAndFeaturesEntries\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"maxItems\": 128,\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/AppsAndFeaturesEntry\"\r\n      },\r\n      \"description\": \"List of ARP entries.\"\r\n    },\r\n    \"ElevationRequirement\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"elevationRequired\",\r\n        \"elevationProhibited\",\r\n        \"elevatesSelf\"\r\n      ],\r\n      \"description\": \"The installer's elevation requirement\"\r\n    },\r\n    \"InstallationMetadata\": {\r\n      \"type\": \"object\",\r\n      \"title\": \"InstallationMetadata\",\r\n      \"properties\": {\r\n        \"DefaultInstallLocation\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 2048,\r\n          \"description\": \"Represents the default installed package location. Used for deeper installation detection.\"\r\n        },\r\n        \"Files\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"uniqueItems\": true,\r\n          \"maxItems\": 2048,\r\n          \"items\": {\r\n            \"type\": \"object\",\r\n            \"title\": \"InstalledFile\",\r\n            \"properties\": {\r\n              \"RelativeFilePath\": {\r\n                \"type\": \"string\",\r\n                \"minLength\": 1,\r\n                \"maxLength\": 2048,\r\n                \"description\": \"The relative path to the installed file.\"\r\n              },\r\n              \"FileSha256\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n                \"description\": \"Optional Sha256 of the installed file.\"\r\n              },\r\n              \"FileType\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"enum\": [\r\n                  \"launch\",\r\n                  \"uninstall\",\r\n                  \"other\"\r\n                ],\r\n                \"description\": \"The optional installed file type. If not specified, the file is treated as other.\"\r\n              },\r\n              \"InvocationParameter\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"minLength\": 1,\r\n                \"maxLength\": 2048,\r\n                \"description\": \"Optional parameter for invocable files.\"\r\n              },\r\n              \"DisplayName\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"minLength\": 1,\r\n                \"maxLength\": 256,\r\n                \"description\": \"Optional display name for invocable files.\"\r\n              }\r\n            },\r\n            \"required\": [ \"RelativeFilePath\" ],\r\n            \"description\": \"Represents an installed file.\"\r\n          },\r\n          \"description\": \"List of installed files.\"\r\n        }\r\n      },\r\n      \"description\": \"Details about the installation. Used for deeper installation detection.\"\r\n    },\r\n    \"DownloadCommandProhibited\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer is prohibited from being downloaded for offline installation.\"\r\n    },\r\n    \"RepairBehavior\": { \r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"modify\",\r\n        \"uninstaller\",\r\n        \"installer\"\r\n      ],\r\n      \"description\": \"The repair method\"\r\n    },\r\n    \"Installer\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"InstallerLocale\": {\r\n          \"$ref\": \"#/definitions/Locale\"\r\n        },\r\n        \"Platform\": {\r\n          \"$ref\": \"#/definitions/Platform\"\r\n        },\r\n        \"MinimumOSVersion\": {\r\n          \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n        },\r\n        \"Architecture\": {\r\n          \"$ref\": \"#/definitions/Architecture\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        },\r\n        \"NestedInstallerType\": {\r\n          \"$ref\": \"#/definitions/NestedInstallerType\"\r\n        },\r\n        \"NestedInstallerFiles\": {\r\n          \"$ref\": \"#/definitions/NestedInstallerFiles\"\r\n        },\r\n        \"Scope\": {\r\n          \"$ref\": \"#/definitions/Scope\"\r\n        },\r\n        \"InstallerUrl\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n          \"maxLength\": 2048,\r\n          \"description\": \"The installer Url\"\r\n        },\r\n        \"InstallerSha256\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"Sha256 is required. Sha256 of the installer\"\r\n        },\r\n        \"SignatureSha256\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable\"\r\n        },\r\n        \"InstallModes\": {\r\n          \"$ref\": \"#/definitions/InstallModes\"\r\n        },\r\n        \"InstallerSwitches\": {\r\n          \"$ref\": \"#/definitions/InstallerSwitches\"\r\n        },\r\n        \"InstallerSuccessCodes\": {\r\n          \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n        },\r\n        \"ExpectedReturnCodes\": {\r\n          \"$ref\": \"#/definitions/ExpectedReturnCodes\"\r\n        },\r\n        \"UpgradeBehavior\": {\r\n          \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n        },\r\n        \"Commands\": {\r\n          \"$ref\": \"#/definitions/Commands\"\r\n        },\r\n        \"Protocols\": {\r\n          \"$ref\": \"#/definitions/Protocols\"\r\n        },\r\n        \"FileExtensions\": {\r\n          \"$ref\": \"#/definitions/FileExtensions\"\r\n        },\r\n        \"Dependencies\": {\r\n          \"$ref\": \"#/definitions/Dependencies\"\r\n        },\r\n        \"PackageFamilyName\": {\r\n          \"$ref\": \"#/definitions/PackageFamilyName\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"Capabilities\": {\r\n          \"$ref\": \"#/definitions/Capabilities\"\r\n        },\r\n        \"RestrictedCapabilities\": {\r\n          \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n        },\r\n        \"Markets\": {\r\n          \"$ref\": \"#/definitions/Markets\"\r\n        },\r\n        \"InstallerAbortsTerminal\": {\r\n          \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\r\n        },\r\n        \"ReleaseDate\": {\r\n          \"$ref\": \"#/definitions/ReleaseDate\"\r\n        },\r\n        \"InstallLocationRequired\": {\r\n          \"$ref\": \"#/definitions/InstallLocationRequired\"\r\n        },\r\n        \"RequireExplicitUpgrade\": {\r\n          \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\r\n        },\r\n        \"DisplayInstallWarnings\": {\r\n          \"$ref\": \"#/definitions/DisplayInstallWarnings\"\r\n        },\r\n        \"UnsupportedOSArchitectures\": {\r\n          \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\r\n        },\r\n        \"UnsupportedArguments\": {\r\n          \"$ref\": \"#/definitions/UnsupportedArguments\"\r\n        },\r\n        \"AppsAndFeaturesEntries\": {\r\n          \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\r\n        },\r\n        \"ElevationRequirement\": {\r\n          \"$ref\": \"#/definitions/ElevationRequirement\"\r\n        },\r\n        \"InstallationMetadata\": {\r\n          \"$ref\": \"#/definitions/InstallationMetadata\"\r\n        },\r\n        \"DownloadCommandProhibited\": {\r\n          \"$ref\": \"#/definitions/DownloadCommandProhibited\"\r\n        },\r\n        \"RepairBehavior\": {\r\n          \"$ref\": \"#/definitions/RepairBehavior\"\r\n        }\r\n      },\r\n      \"required\": [\r\n        \"Architecture\",\r\n        \"InstallerUrl\",\r\n        \"InstallerSha256\"\r\n      ]\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"$ref\": \"#/definitions/PackageIdentifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"$ref\": \"#/definitions/PackageVersion\"\r\n    },\r\n    \"Channel\": {\r\n      \"$ref\": \"#/definitions/Channel\"\r\n    },\r\n    \"InstallerLocale\": {\r\n      \"$ref\": \"#/definitions/Locale\"\r\n    },\r\n    \"Platform\": {\r\n      \"$ref\": \"#/definitions/Platform\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"$ref\": \"#/definitions/InstallerType\"\r\n    },\r\n    \"NestedInstallerType\": {\r\n      \"$ref\": \"#/definitions/NestedInstallerType\"\r\n    },\r\n    \"NestedInstallerFiles\": {\r\n      \"$ref\": \"#/definitions/NestedInstallerFiles\"\r\n    },\r\n    \"Scope\": {\r\n      \"$ref\": \"#/definitions/Scope\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"$ref\": \"#/definitions/InstallModes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"$ref\": \"#/definitions/InstallerSwitches\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n    },\r\n    \"ExpectedReturnCodes\": {\r\n      \"$ref\": \"#/definitions/ExpectedReturnCodes\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n    },\r\n    \"Commands\": {\r\n      \"$ref\": \"#/definitions/Commands\"\r\n    },\r\n    \"Protocols\": {\r\n      \"$ref\": \"#/definitions/Protocols\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"$ref\": \"#/definitions/FileExtensions\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"$ref\": \"#/definitions/Dependencies\"\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"$ref\": \"#/definitions/PackageFamilyName\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"$ref\": \"#/definitions/ProductCode\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"$ref\": \"#/definitions/Capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n    },\r\n    \"Markets\": {\r\n      \"$ref\": \"#/definitions/Markets\"\r\n    },\r\n    \"InstallerAbortsTerminal\": {\r\n      \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\r\n    },\r\n    \"ReleaseDate\": {\r\n      \"$ref\": \"#/definitions/ReleaseDate\"\r\n    },\r\n    \"InstallLocationRequired\": {\r\n      \"$ref\": \"#/definitions/InstallLocationRequired\"\r\n    },\r\n    \"RequireExplicitUpgrade\": {\r\n      \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\r\n    },\r\n    \"DisplayInstallWarnings\": {\r\n      \"$ref\": \"#/definitions/DisplayInstallWarnings\"\r\n    },\r\n    \"UnsupportedOSArchitectures\": {\r\n      \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\r\n    },\r\n    \"UnsupportedArguments\": {\r\n      \"$ref\": \"#/definitions/UnsupportedArguments\"\r\n    },\r\n    \"AppsAndFeaturesEntries\": {\r\n      \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\r\n    },\r\n    \"ElevationRequirement\": {\r\n      \"$ref\": \"#/definitions/ElevationRequirement\"\r\n    },\r\n    \"InstallationMetadata\": {\r\n      \"$ref\": \"#/definitions/InstallationMetadata\"\r\n    },\r\n    \"DownloadCommandProhibited\": {\r\n      \"$ref\": \"#/definitions/DownloadCommandProhibited\"\r\n    },\r\n    \"RepairBehavior\": {\r\n      \"$ref\": \"#/definitions/RepairBehavior\"\r\n    },\r\n    \"Installers\": {\r\n      \"type\": \"array\",\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Installer\"\r\n      },\r\n      \"minItems\": 1,\r\n      \"maxItems\": 1024\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"installer\",\r\n      \"const\": \"installer\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.7.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"Installers\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}\r\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.7.0/manifest.locale.1.7.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.locale.1.7.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a multiple-file manifest representing app metadata in other locale in the OWC. v1.7.0\",\r\n  \"definitions\": {\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Optional Url type\"\r\n    },\r\n    \"Tag\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 40,\r\n      \"description\": \"Package tag\"\r\n    },\r\n    \"Agreement\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"AgreementLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\r\n        },\r\n        \"Agreement\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 10000,\r\n          \"description\": \"The agreement text content.\"\r\n        },\r\n        \"AgreementUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The agreement URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Documentation\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DocumentLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\r\n        },\r\n        \"DocumentUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The documentation URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Icon\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"IconUrl\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n          \"maxLength\": 2048,\r\n          \"description\": \"The url of the hosted icon file\"\r\n        },\r\n        \"IconFileType\": {\r\n          \"type\": \"string\",\r\n          \"enum\": [\r\n            \"png\",\r\n            \"jpeg\",\r\n            \"ico\"\r\n          ],\r\n          \"description\": \"The icon file type\"\r\n        },\r\n        \"IconResolution\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"enum\": [\r\n            \"custom\",\r\n            \"16x16\",\r\n            \"20x20\",\r\n            \"24x24\",\r\n            \"30x30\",\r\n            \"32x32\",\r\n            \"36x36\",\r\n            \"40x40\",\r\n            \"48x48\",\r\n            \"60x60\",\r\n            \"64x64\",\r\n            \"72x72\",\r\n            \"80x80\",\r\n            \"96x96\",\r\n            \"256x256\"\r\n          ],\r\n          \"description\": \"Optional icon resolution\"\r\n        },\r\n        \"IconTheme\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"enum\": [\r\n            \"default\",\r\n            \"light\",\r\n            \"dark\",\r\n            \"highContrast\"\r\n          ],\r\n          \"description\": \"Optional icon theme\"\r\n        },\r\n        \"IconSha256\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"Optional Sha256 of the icon file\"\r\n        }\r\n      },\r\n      \"required\": [\r\n        \"IconUrl\",\r\n        \"IconFileType\"\r\n      ]\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"PackageLocale\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The package meta-data locale\"\r\n    },\r\n    \"Publisher\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The publisher name\"\r\n    },\r\n    \"PublisherUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher home page\"\r\n    },\r\n    \"PublisherSupportUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher support page\"\r\n    },\r\n    \"PrivacyUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher privacy page or the package privacy page\"\r\n    },\r\n    \"Author\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package author\"\r\n    },\r\n    \"PackageName\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package name\"\r\n    },\r\n    \"PackageUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package home page\"\r\n    },\r\n    \"License\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package license\"\r\n    },\r\n    \"LicenseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The license page\"\r\n    },\r\n    \"Copyright\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package copyright\"\r\n    },\r\n    \"CopyrightUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package copyright page\"\r\n    },\r\n    \"ShortDescription\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The short package description\"\r\n    },\r\n    \"Description\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The full package description\"\r\n    },\r\n    \"Tags\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Tag\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional package search terms\"\r\n    },\r\n    \"Agreements\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Agreement\"\r\n      },\r\n      \"maxItems\": 128\r\n    },\r\n    \"ReleaseNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The package release notes\"\r\n    },\r\n    \"ReleaseNotesUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package release notes url\"\r\n    },\r\n    \"PurchaseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\r\n    },\r\n    \"InstallationNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"\r\n    },\r\n    \"Documentations\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Documentation\"\r\n      },\r\n      \"maxItems\": 256\r\n    },\r\n    \"Icons\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Icon\"\r\n      },\r\n      \"maxItems\": 1024\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"locale\",\r\n      \"const\": \"locale\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.7.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"PackageLocale\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}\r\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.7.0/manifest.singleton.1.7.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.singleton.1.7.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a single-file manifest representing an app in the OWC. v1.7.0\",\r\n  \"definitions\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"Locale\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The package meta-data locale\"\r\n    },\r\n    \"Url\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n      \"maxLength\": 2048,\r\n      \"description\": \"Optional Url type\"\r\n    },\r\n    \"Tag\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 40,\r\n      \"description\": \"Package moniker or tag\"\r\n    },\r\n    \"Agreement\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"AgreementLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\r\n        },\r\n        \"Agreement\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 10000,\r\n          \"description\": \"The agreement text content.\"\r\n        },\r\n        \"AgreementUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The agreement URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Documentation\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DocumentLabel\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 100,\r\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\r\n        },\r\n        \"DocumentUrl\": {\r\n          \"$ref\": \"#/definitions/Url\",\r\n          \"description\": \"The documentation URL.\"\r\n        }\r\n      }\r\n    },\r\n    \"Icon\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"IconUrl\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n          \"maxLength\": 2048,\r\n          \"description\": \"The url of the hosted icon file\"\r\n        },\r\n        \"IconFileType\": {\r\n          \"type\": \"string\",\r\n          \"enum\": [\r\n            \"png\",\r\n            \"jpeg\",\r\n            \"ico\"\r\n          ],\r\n          \"description\": \"The icon file type\"\r\n        },\r\n        \"IconResolution\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"enum\": [\r\n            \"custom\",\r\n            \"16x16\",\r\n            \"20x20\",\r\n            \"24x24\",\r\n            \"30x30\",\r\n            \"32x32\",\r\n            \"36x36\",\r\n            \"40x40\",\r\n            \"48x48\",\r\n            \"60x60\",\r\n            \"64x64\",\r\n            \"72x72\",\r\n            \"80x80\",\r\n            \"96x96\",\r\n            \"256x256\"\r\n          ],\r\n          \"description\": \"Optional icon resolution\"\r\n        },\r\n        \"IconTheme\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"enum\": [\r\n            \"default\",\r\n            \"light\",\r\n            \"dark\",\r\n            \"highContrast\"\r\n          ],\r\n          \"description\": \"Optional icon theme\"\r\n        },\r\n        \"IconSha256\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"Optional Sha256 of the icon file\"\r\n        }\r\n      },\r\n      \"required\": [\r\n        \"IconUrl\",\r\n        \"IconFileType\"\r\n      ]\r\n    },\r\n    \"Channel\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 16,\r\n      \"description\": \"The distribution channel\"\r\n    },\r\n    \"Platform\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"Platform\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"Windows.Desktop\",\r\n          \"Windows.Universal\"\r\n        ]\r\n      },\r\n      \"maxItems\": 2,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"The installer supported operating system\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$\",\r\n      \"description\": \"The installer minimum operating system version\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"msix\",\r\n        \"msi\",\r\n        \"appx\",\r\n        \"exe\",\r\n        \"zip\",\r\n        \"inno\",\r\n        \"nullsoft\",\r\n        \"wix\",\r\n        \"burn\",\r\n        \"pwa\",\r\n        \"portable\"\r\n      ],\r\n      \"description\": \"Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level\"\r\n    },\r\n    \"NestedInstallerType\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"msix\",\r\n        \"msi\",\r\n        \"appx\",\r\n        \"exe\",\r\n        \"inno\",\r\n        \"nullsoft\",\r\n        \"wix\",\r\n        \"burn\",\r\n        \"portable\"\r\n      ],\r\n      \"description\": \"Enumeration of supported nested installer types contained inside an archive file\"\r\n    },\r\n    \"NestedInstallerFiles\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"object\",\r\n        \"title\": \"NestedInstallerFile\",\r\n        \"properties\": {\r\n          \"RelativeFilePath\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 512,\r\n            \"description\": \"The relative path to the nested installer file\"\r\n          },\r\n          \"PortableCommandAlias\": {\r\n            \"type\": [ \"string\", \"null\" ],\r\n            \"minLength\": 1,\r\n            \"maxLength\": 40,\r\n            \"description\": \"The command alias to be used for calling the package. Only applies to the nested portable package\"\r\n          }\r\n        },\r\n        \"required\": [ \"RelativeFilePath\" ],\r\n        \"description\": \"A nested installer file contained inside an archive\"\r\n      },\r\n      \"maxItems\": 1024,\r\n      \"description\": \"List of nested installer files contained inside an archive\"\r\n    },\r\n    \"Architecture\": {\r\n      \"type\": \"string\",\r\n      \"enum\": [\r\n        \"x86\",\r\n        \"x64\",\r\n        \"arm\",\r\n        \"arm64\",\r\n        \"neutral\"\r\n      ],\r\n      \"description\": \"The installer target architecture\"\r\n    },\r\n    \"Scope\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"user\",\r\n        \"machine\"\r\n      ],\r\n      \"description\": \"Scope indicates if the installer is per user or per machine\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"title\": \"InstallModes\",\r\n        \"type\": \"string\",\r\n        \"enum\": [\r\n          \"interactive\",\r\n          \"silent\",\r\n          \"silentWithProgress\"\r\n        ]\r\n      },\r\n      \"maxItems\": 3,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of supported installer modes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"Silent\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Silent is the value that should be passed to the installer when user chooses a silent or quiet install\"\r\n        },\r\n        \"SilentWithProgress\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install\"\r\n        },\r\n        \"Interactive\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Interactive is the value that should be passed to the installer when user chooses an interactive install\"\r\n        },\r\n        \"InstallLocation\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"InstallLocation is the value passed to the installer for custom install location. <INSTALLPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Log\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Log is the value passed to the installer for custom log file path. <LOGPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\r\n        },\r\n        \"Upgrade\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"Upgrade is the value that should be passed to the installer when user chooses an upgrade\"\r\n        },\r\n        \"Custom\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 2048,\r\n          \"description\": \"Custom switches will be passed directly to the installer by winget\"\r\n        },\r\n        \"Repair\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 512,\r\n          \"description\": \"The 'Repair' value must be passed to the installer, ModifyPath ARP command, or uninstaller ARP command when the user opts for a repair\"\r\n        }\r\n      }\r\n    },\r\n    \"InstallerReturnCode\": {\r\n      \"type\": \"integer\",\r\n      \"format\": \"long\",\r\n      \"not\": {\r\n        \"enum\": [ 0 ]\r\n      },\r\n      \"minimum\": -2147483648,\r\n      \"maximum\": 4294967295,\r\n      \"description\": \"An exit code that can be returned by the installer after execution\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/InstallerReturnCode\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional non-zero installer success exit codes other than known default values by winget\"\r\n    },\r\n    \"ExpectedReturnCodes\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"object\",\r\n        \"title\": \"ExpectedReturnCode\",\r\n        \"properties\": {\r\n          \"InstallerReturnCode\": {\r\n            \"$ref\": \"#/definitions/InstallerReturnCode\"\r\n          },\r\n          \"ReturnResponse\": {\r\n            \"type\": \"string\",\r\n            \"enum\": [\r\n              \"packageInUse\",\r\n              \"packageInUseByApplication\",\r\n              \"installInProgress\",\r\n              \"fileInUse\",\r\n              \"missingDependency\",\r\n              \"diskFull\",\r\n              \"insufficientMemory\",\r\n              \"invalidParameter\",\r\n              \"noNetwork\",\r\n              \"contactSupport\",\r\n              \"rebootRequiredToFinish\",\r\n              \"rebootRequiredForInstall\",\r\n              \"rebootInitiated\",\r\n              \"cancelledByUser\",\r\n              \"alreadyInstalled\",\r\n              \"downgrade\",\r\n              \"blockedByPolicy\",\r\n              \"systemNotSupported\",\r\n              \"custom\"\r\n            ]\r\n          },\r\n          \"ReturnResponseUrl\": {\r\n            \"$ref\": \"#/definitions/Url\",\r\n            \"description\": \"The return response url to provide additional guidance for expected return codes\"\r\n          }\r\n        },\r\n        \"required\": [ \"InstallerReturnCode\", \"ReturnResponse\" ]\r\n      },\r\n      \"maxItems\": 128,\r\n      \"description\": \"Installer exit codes for common errors\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"install\",\r\n        \"uninstallPrevious\",\r\n        \"deny\"\r\n      ],\r\n      \"description\": \"The upgrade method\"\r\n    },\r\n    \"Commands\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of commands or aliases to run the package\"\r\n    },\r\n    \"Protocols\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"maxLength\": 2048\r\n      },\r\n      \"maxItems\": 64,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of protocols the package provides a handler for\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n        \"maxLength\": 64\r\n      },\r\n      \"maxItems\": 512,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of file extensions the package could support\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"properties\": {\r\n        \"WindowsFeatures\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows feature dependencies\"\r\n        },\r\n        \"WindowsLibraries\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of Windows library dependencies\"\r\n        },\r\n        \"PackageDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"object\",\r\n            \"properties\": {\r\n              \"PackageIdentifier\": {\r\n                \"$ref\": \"#/definitions/PackageIdentifier\"\r\n              },\r\n              \"MinimumVersion\": {\r\n                \"$ref\": \"#/definitions/PackageVersion\"\r\n              }\r\n            },\r\n            \"required\": [ \"PackageIdentifier\" ]\r\n          },\r\n          \"maxItems\": 16,\r\n          \"description\": \"List of package dependencies from current source\"\r\n        },\r\n        \"ExternalDependencies\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"items\": {\r\n            \"type\": \"string\",\r\n            \"minLength\": 1,\r\n            \"maxLength\": 128\r\n          },\r\n          \"maxItems\": 16,\r\n          \"uniqueItems\": true,\r\n          \"description\": \"List of external package dependencies\"\r\n        }\r\n      }\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"pattern\": \"^[A-Za-z0-9][-\\\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$\",\r\n      \"maxLength\": 255,\r\n      \"description\": \"PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 255,\r\n      \"description\": \"ProductCode could be used for correlation of packages across sources\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"minLength\": 1,\r\n        \"maxLength\": 40\r\n      },\r\n      \"maxItems\": 1000,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of appx or msix installer restricted capabilities\"\r\n    },\r\n    \"Market\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[A-Z]{2}$\",\r\n      \"description\": \"The installer target market\"\r\n    },\r\n    \"MarketArray\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"maxItems\": 256,\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Market\"\r\n      },\r\n      \"description\": \"Array of markets\"\r\n    },\r\n    \"Markets\": {\r\n      \"description\": \"The installer markets\",\r\n      \"type\": [ \"object\", \"null\" ],\r\n      \"oneOf\": [\r\n        {\r\n          \"properties\": {\r\n            \"AllowedMarkets\": {\r\n              \"$ref\": \"#/definitions/MarketArray\"\r\n            }\r\n          },\r\n          \"required\": [ \"AllowedMarkets\" ]\r\n        },\r\n        {\r\n          \"properties\": {\r\n            \"ExcludedMarkets\": {\r\n              \"$ref\": \"#/definitions/MarketArray\"\r\n            }\r\n          },\r\n          \"required\": [ \"ExcludedMarkets\" ]\r\n        }\r\n      ]\r\n    },\r\n    \"InstallerAbortsTerminal\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer will abort terminal. Default is false\"\r\n    },\r\n    \"ReleaseDate\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"format\": \"date\",\r\n      \"description\": \"The installer release date\"\r\n    },\r\n    \"InstallLocationRequired\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer requires an install location provided\"\r\n    },\r\n    \"RequireExplicitUpgrade\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer should be pinned by default from upgrade\"\r\n    },\r\n    \"DisplayInstallWarnings\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications.\"\r\n    },\r\n    \"UnsupportedOSArchitectures\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"title\": \"UnsupportedOSArchitecture\",\r\n        \"enum\": [\r\n          \"x86\",\r\n          \"x64\",\r\n          \"arm\",\r\n          \"arm64\"\r\n        ]\r\n      },\r\n      \"description\": \"List of OS architectures the installer does not support\"\r\n    },\r\n    \"UnsupportedArguments\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"items\": {\r\n        \"type\": \"string\",\r\n        \"title\": \"UnsupportedArgument\",\r\n        \"enum\": [\r\n          \"log\",\r\n          \"location\"\r\n        ]\r\n      },\r\n      \"description\": \"List of winget arguments the installer does not support\"\r\n    },\r\n    \"AppsAndFeaturesEntry\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"DisplayName\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 256,\r\n          \"description\": \"The DisplayName registry value\"\r\n        },\r\n        \"Publisher\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 256,\r\n          \"description\": \"The Publisher registry value\"\r\n        },\r\n        \"DisplayVersion\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 128,\r\n          \"description\": \"The DisplayVersion registry value\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"UpgradeCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        }\r\n      },\r\n      \"description\": \"Various key values under installer's ARP entry\"\r\n    },\r\n    \"AppsAndFeaturesEntries\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"uniqueItems\": true,\r\n      \"maxItems\": 128,\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/AppsAndFeaturesEntry\"\r\n      },\r\n      \"description\": \"List of ARP entries.\"\r\n    },\r\n    \"ElevationRequirement\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"elevationRequired\",\r\n        \"elevationProhibited\",\r\n        \"elevatesSelf\"\r\n      ],\r\n      \"description\": \"The installer's elevation requirement\"\r\n    },\r\n    \"InstallationMetadata\": {\r\n      \"type\": \"object\",\r\n      \"title\": \"InstallationMetadata\",\r\n      \"properties\": {\r\n        \"DefaultInstallLocation\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"minLength\": 1,\r\n          \"maxLength\": 2048,\r\n          \"description\": \"Represents the default installed package location. Used for deeper installation detection.\"\r\n        },\r\n        \"Files\": {\r\n          \"type\": [ \"array\", \"null\" ],\r\n          \"uniqueItems\": true,\r\n          \"maxItems\": 2048,\r\n          \"items\": {\r\n            \"type\": \"object\",\r\n            \"title\": \"InstalledFile\",\r\n            \"properties\": {\r\n              \"RelativeFilePath\": {\r\n                \"type\": \"string\",\r\n                \"minLength\": 1,\r\n                \"maxLength\": 2048,\r\n                \"description\": \"The relative path to the installed file.\"\r\n              },\r\n              \"FileSha256\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n                \"description\": \"Optional Sha256 of the installed file.\"\r\n              },\r\n              \"FileType\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"enum\": [\r\n                  \"launch\",\r\n                  \"uninstall\",\r\n                  \"other\"\r\n                ],\r\n                \"description\": \"The optional installed file type. If not specified, the file is treated as other.\"\r\n              },\r\n              \"InvocationParameter\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"minLength\": 1,\r\n                \"maxLength\": 2048,\r\n                \"description\": \"Optional parameter for invocable files.\"\r\n              },\r\n              \"DisplayName\": {\r\n                \"type\": [ \"string\", \"null\" ],\r\n                \"minLength\": 1,\r\n                \"maxLength\": 256,\r\n                \"description\": \"Optional display name for invocable files.\"\r\n              }\r\n            },\r\n            \"required\": [ \"RelativeFilePath\" ],\r\n            \"description\": \"Represents an installed file.\"\r\n          },\r\n          \"description\": \"List of installed files.\"\r\n        }\r\n      },\r\n      \"description\": \"Details about the installation. Used for deeper installation detection.\"\r\n    },\r\n    \"DownloadCommandProhibited\": {\r\n      \"type\": [ \"boolean\", \"null\" ],\r\n      \"description\": \"Indicates whether the installer is prohibited from being downloaded for offline installation.\"\r\n    },\r\n    \"RepairBehavior\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"enum\": [\r\n        \"modify\",\r\n        \"uninstaller\",\r\n        \"installer\"\r\n      ],\r\n      \"description\": \"The repair method\"\r\n    },\r\n    \"Installer\": {\r\n      \"type\": \"object\",\r\n      \"properties\": {\r\n        \"InstallerLocale\": {\r\n          \"$ref\": \"#/definitions/Locale\"\r\n        },\r\n        \"Platform\": {\r\n          \"$ref\": \"#/definitions/Platform\"\r\n        },\r\n        \"MinimumOSVersion\": {\r\n          \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n        },\r\n        \"Architecture\": {\r\n          \"$ref\": \"#/definitions/Architecture\"\r\n        },\r\n        \"InstallerType\": {\r\n          \"$ref\": \"#/definitions/InstallerType\"\r\n        },\r\n        \"NestedInstallerType\": {\r\n          \"$ref\": \"#/definitions/NestedInstallerType\"\r\n        },\r\n        \"NestedInstallerFiles\": {\r\n          \"$ref\": \"#/definitions/NestedInstallerFiles\"\r\n        },\r\n        \"Scope\": {\r\n          \"$ref\": \"#/definitions/Scope\"\r\n        },\r\n        \"InstallerUrl\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\r\n          \"maxLength\": 2048,\r\n          \"description\": \"The installer Url\"\r\n        },\r\n        \"InstallerSha256\": {\r\n          \"type\": \"string\",\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"Sha256 is required. Sha256 of the installer\"\r\n        },\r\n        \"SignatureSha256\": {\r\n          \"type\": [ \"string\", \"null\" ],\r\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\r\n          \"description\": \"SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable\"\r\n        },\r\n        \"InstallModes\": {\r\n          \"$ref\": \"#/definitions/InstallModes\"\r\n        },\r\n        \"InstallerSwitches\": {\r\n          \"$ref\": \"#/definitions/InstallerSwitches\"\r\n        },\r\n        \"InstallerSuccessCodes\": {\r\n          \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n        },\r\n        \"ExpectedReturnCodes\": {\r\n          \"$ref\": \"#/definitions/ExpectedReturnCodes\"\r\n        },\r\n        \"UpgradeBehavior\": {\r\n          \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n        },\r\n        \"Commands\": {\r\n          \"$ref\": \"#/definitions/Commands\"\r\n        },\r\n        \"Protocols\": {\r\n          \"$ref\": \"#/definitions/Protocols\"\r\n        },\r\n        \"FileExtensions\": {\r\n          \"$ref\": \"#/definitions/FileExtensions\"\r\n        },\r\n        \"Dependencies\": {\r\n          \"$ref\": \"#/definitions/Dependencies\"\r\n        },\r\n        \"PackageFamilyName\": {\r\n          \"$ref\": \"#/definitions/PackageFamilyName\"\r\n        },\r\n        \"ProductCode\": {\r\n          \"$ref\": \"#/definitions/ProductCode\"\r\n        },\r\n        \"Capabilities\": {\r\n          \"$ref\": \"#/definitions/Capabilities\"\r\n        },\r\n        \"RestrictedCapabilities\": {\r\n          \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n        },\r\n        \"Markets\": {\r\n          \"$ref\": \"#/definitions/Markets\"\r\n        },\r\n        \"InstallerAbortsTerminal\": {\r\n          \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\r\n        },\r\n        \"ReleaseDate\": {\r\n          \"$ref\": \"#/definitions/ReleaseDate\"\r\n        },\r\n        \"InstallLocationRequired\": {\r\n          \"$ref\": \"#/definitions/InstallLocationRequired\"\r\n        },\r\n        \"RequireExplicitUpgrade\": {\r\n          \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\r\n        },\r\n        \"DisplayInstallWarnings\": {\r\n          \"$ref\": \"#/definitions/DisplayInstallWarnings\"\r\n        },\r\n        \"UnsupportedOSArchitectures\": {\r\n          \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\r\n        },\r\n        \"UnsupportedArguments\": {\r\n          \"$ref\": \"#/definitions/UnsupportedArguments\"\r\n        },\r\n        \"AppsAndFeaturesEntries\": {\r\n          \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\r\n        },\r\n        \"ElevationRequirement\": {\r\n          \"$ref\": \"#/definitions/ElevationRequirement\"\r\n        },\r\n        \"InstallationMetadata\": {\r\n          \"$ref\": \"#/definitions/InstallationMetadata\"\r\n        },\r\n        \"DownloadCommandProhibited\": {\r\n          \"$ref\": \"#/definitions/DownloadCommandProhibited\"\r\n        },\r\n        \"RepairBehavior\": {\r\n          \"$ref\": \"#/definitions/RepairBehavior\"\r\n        }\r\n      },\r\n      \"required\": [\r\n        \"Architecture\",\r\n        \"InstallerUrl\",\r\n        \"InstallerSha256\"\r\n      ]\r\n    }\r\n  },\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"$ref\": \"#/definitions/PackageIdentifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"$ref\": \"#/definitions/PackageVersion\"\r\n    },\r\n    \"PackageLocale\": {\r\n      \"$ref\": \"#/definitions/Locale\"\r\n    },\r\n    \"Publisher\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The publisher name\"\r\n    },\r\n    \"PublisherUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher home page\"\r\n    },\r\n    \"PublisherSupportUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher support page\"\r\n    },\r\n    \"PrivacyUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The publisher privacy page or the package privacy page\"\r\n    },\r\n    \"Author\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package author\"\r\n    },\r\n    \"PackageName\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 2,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The package name\"\r\n    },\r\n    \"PackageUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package home page\"\r\n    },\r\n    \"License\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package license\"\r\n    },\r\n    \"LicenseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The license page\"\r\n    },\r\n    \"Copyright\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 512,\r\n      \"description\": \"The package copyright\"\r\n    },\r\n    \"CopyrightUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package copyright page\"\r\n    },\r\n    \"ShortDescription\": {\r\n      \"type\": \"string\",\r\n      \"minLength\": 3,\r\n      \"maxLength\": 256,\r\n      \"description\": \"The short package description\"\r\n    },\r\n    \"Description\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 3,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The full package description\"\r\n    },\r\n    \"Moniker\": {\r\n      \"$ref\": \"#/definitions/Tag\",\r\n      \"description\": \"The most common package term\"\r\n    },\r\n    \"Tags\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Tag\"\r\n      },\r\n      \"maxItems\": 16,\r\n      \"uniqueItems\": true,\r\n      \"description\": \"List of additional package search terms\"\r\n    },\r\n    \"Agreements\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Agreement\"\r\n      },\r\n      \"maxItems\": 128\r\n    },\r\n    \"ReleaseNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The package release notes\"\r\n    },\r\n    \"ReleaseNotesUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The package release notes url\"\r\n    },\r\n    \"PurchaseUrl\": {\r\n      \"$ref\": \"#/definitions/Url\",\r\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\r\n    },\r\n    \"InstallationNotes\": {\r\n      \"type\": [ \"string\", \"null\" ],\r\n      \"minLength\": 1,\r\n      \"maxLength\": 10000,\r\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"\r\n    },\r\n    \"Documentations\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Documentation\"\r\n      },\r\n      \"maxItems\": 256\r\n    },\r\n    \"Icons\": {\r\n      \"type\": [ \"array\", \"null\" ],\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Icon\"\r\n      },\r\n      \"maxItems\": 1024\r\n    },\r\n    \"Channel\": {\r\n      \"$ref\": \"#/definitions/Channel\"\r\n    },\r\n    \"InstallerLocale\": {\r\n      \"$ref\": \"#/definitions/Locale\"\r\n    },\r\n    \"Platform\": {\r\n      \"$ref\": \"#/definitions/Platform\"\r\n    },\r\n    \"MinimumOSVersion\": {\r\n      \"$ref\": \"#/definitions/MinimumOSVersion\"\r\n    },\r\n    \"InstallerType\": {\r\n      \"$ref\": \"#/definitions/InstallerType\"\r\n    },\r\n    \"NestedInstallerType\": {\r\n      \"$ref\": \"#/definitions/NestedInstallerType\"\r\n    },\r\n    \"NestedInstallerFiles\": {\r\n      \"$ref\": \"#/definitions/NestedInstallerFiles\"\r\n    },\r\n    \"Scope\": {\r\n      \"$ref\": \"#/definitions/Scope\"\r\n    },\r\n    \"InstallModes\": {\r\n      \"$ref\": \"#/definitions/InstallModes\"\r\n    },\r\n    \"InstallerSwitches\": {\r\n      \"$ref\": \"#/definitions/InstallerSwitches\"\r\n    },\r\n    \"InstallerSuccessCodes\": {\r\n      \"$ref\": \"#/definitions/InstallerSuccessCodes\"\r\n    },\r\n    \"ExpectedReturnCodes\": {\r\n      \"$ref\": \"#/definitions/ExpectedReturnCodes\"\r\n    },\r\n    \"UpgradeBehavior\": {\r\n      \"$ref\": \"#/definitions/UpgradeBehavior\"\r\n    },\r\n    \"Commands\": {\r\n      \"$ref\": \"#/definitions/Commands\"\r\n    },\r\n    \"Protocols\": {\r\n      \"$ref\": \"#/definitions/Protocols\"\r\n    },\r\n    \"FileExtensions\": {\r\n      \"$ref\": \"#/definitions/FileExtensions\"\r\n    },\r\n    \"Dependencies\": {\r\n      \"$ref\": \"#/definitions/Dependencies\"\r\n    },\r\n    \"PackageFamilyName\": {\r\n      \"$ref\": \"#/definitions/PackageFamilyName\"\r\n    },\r\n    \"ProductCode\": {\r\n      \"$ref\": \"#/definitions/ProductCode\"\r\n    },\r\n    \"Capabilities\": {\r\n      \"$ref\": \"#/definitions/Capabilities\"\r\n    },\r\n    \"RestrictedCapabilities\": {\r\n      \"$ref\": \"#/definitions/RestrictedCapabilities\"\r\n    },\r\n    \"Markets\": {\r\n      \"$ref\": \"#/definitions/Markets\"\r\n    },\r\n    \"InstallerAbortsTerminal\": {\r\n      \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\r\n    },\r\n    \"ReleaseDate\": {\r\n      \"$ref\": \"#/definitions/ReleaseDate\"\r\n    },\r\n    \"InstallLocationRequired\": {\r\n      \"$ref\": \"#/definitions/InstallLocationRequired\"\r\n    },\r\n    \"RequireExplicitUpgrade\": {\r\n      \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\r\n    },\r\n    \"DisplayInstallWarnings\": {\r\n      \"$ref\": \"#/definitions/DisplayInstallWarnings\"\r\n    },\r\n    \"UnsupportedOSArchitectures\": {\r\n      \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\r\n    },\r\n    \"UnsupportedArguments\": {\r\n      \"$ref\": \"#/definitions/UnsupportedArguments\"\r\n    },\r\n    \"AppsAndFeaturesEntries\": {\r\n      \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\r\n    },\r\n    \"ElevationRequirement\": {\r\n      \"$ref\": \"#/definitions/ElevationRequirement\"\r\n    },\r\n    \"InstallationMetadata\": {\r\n      \"$ref\": \"#/definitions/InstallationMetadata\"\r\n    },\r\n    \"DownloadCommandProhibited\": {\r\n      \"$ref\": \"#/definitions/DownloadCommandProhibited\"\r\n    },\r\n    \"RepairBehavior\": {\r\n      \"$ref\": \"#/definitions/RepairBehavior\"\r\n    },\r\n    \"Installers\": {\r\n      \"type\": \"array\",\r\n      \"items\": {\r\n        \"$ref\": \"#/definitions/Installer\"\r\n      },\r\n      \"minItems\": 1,\r\n      \"maxItems\": 1\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"singleton\",\r\n      \"const\": \"singleton\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.7.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"PackageLocale\",\r\n    \"Publisher\",\r\n    \"PackageName\",\r\n    \"License\",\r\n    \"ShortDescription\",\r\n    \"Installers\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}\r\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.7.0/manifest.version.1.7.0.json",
    "content": "{\r\n  \"$id\": \"https://aka.ms/winget-manifest.version.1.7.0.schema.json\",\r\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n  \"description\": \"A representation of a multi-file manifest representing an app version in the OWC. v1.7.0\",\r\n  \"type\": \"object\",\r\n  \"properties\": {\r\n    \"PackageIdentifier\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package unique identifier\"\r\n    },\r\n    \"PackageVersion\": {\r\n      \"type\": \"string\",\r\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\r\n      \"maxLength\": 128,\r\n      \"description\": \"The package version\"\r\n    },\r\n    \"DefaultLocale\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"en-US\",\r\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\r\n      \"maxLength\": 20,\r\n      \"description\": \"The default package meta-data locale\"\r\n    },\r\n    \"ManifestType\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"version\",\r\n      \"const\": \"version\",\r\n      \"description\": \"The manifest type\"\r\n    },\r\n    \"ManifestVersion\": {\r\n      \"type\": \"string\",\r\n      \"default\": \"1.7.0\",\r\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\r\n      \"description\": \"The manifest syntax version\"\r\n    }\r\n  },\r\n  \"required\": [\r\n    \"PackageIdentifier\",\r\n    \"PackageVersion\",\r\n    \"DefaultLocale\",\r\n    \"ManifestType\",\r\n    \"ManifestVersion\"\r\n  ]\r\n}"
  },
  {
    "path": "schemas/JSON/manifests/v1.9.0/manifest.defaultLocale.1.9.0.json",
    "content": "{\n  \"$id\": \"https://aka.ms/winget-manifest.defaultlocale.1.9.0.schema.json\",\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"description\": \"A representation of a multiple-file manifest representing a default app metadata in the OWC. v1.9.0\",\n  \"definitions\": {\n    \"Url\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n      \"maxLength\": 2048,\n      \"description\": \"Optional Url type\"\n    },\n    \"Tag\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 40,\n      \"description\": \"Package moniker or tag\"\n    },\n    \"Agreement\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"AgreementLabel\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 100,\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\n        },\n        \"Agreement\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 10000,\n          \"description\": \"The agreement text content.\"\n        },\n        \"AgreementUrl\": {\n          \"$ref\": \"#/definitions/Url\",\n          \"description\": \"The agreement URL.\"\n        }\n      }\n    },\n    \"Documentation\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"DocumentLabel\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 100,\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\n        },\n        \"DocumentUrl\": {\n          \"$ref\": \"#/definitions/Url\",\n          \"description\": \"The documentation URL.\"\n        }\n      }\n    },\n    \"Icon\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"IconUrl\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n          \"maxLength\": 2048,\n          \"description\": \"The url of the hosted icon file\"\n        },\n        \"IconFileType\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"png\",\n            \"jpeg\",\n            \"ico\"\n          ],\n          \"description\": \"The icon file type\"\n        },\n        \"IconResolution\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"enum\": [\n            \"custom\",\n            \"16x16\",\n            \"20x20\",\n            \"24x24\",\n            \"30x30\",\n            \"32x32\",\n            \"36x36\",\n            \"40x40\",\n            \"48x48\",\n            \"60x60\",\n            \"64x64\",\n            \"72x72\",\n            \"80x80\",\n            \"96x96\",\n            \"256x256\"\n          ],\n          \"description\": \"Optional icon resolution\"\n        },\n        \"IconTheme\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"enum\": [\n            \"default\",\n            \"light\",\n            \"dark\",\n            \"highContrast\"\n          ],\n          \"description\": \"Optional icon theme\"\n        },\n        \"IconSha256\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"Optional Sha256 of the icon file\"\n        }\n      },\n      \"required\": [\n        \"IconUrl\",\n        \"IconFileType\"\n      ]\n    }\n  },\n  \"type\": \"object\",\n  \"properties\": {\n    \"PackageIdentifier\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\n      \"maxLength\": 128,\n      \"description\": \"The package unique identifier\"\n    },\n    \"PackageVersion\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n      \"maxLength\": 128,\n      \"description\": \"The package version\"\n    },\n    \"PackageLocale\": {\n      \"type\": \"string\",\n      \"default\": \"en-US\",\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\n      \"maxLength\": 20,\n      \"description\": \"The package meta-data locale\"\n    },\n    \"Publisher\": {\n      \"type\": \"string\",\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The publisher name\"\n    },\n    \"PublisherUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher home page\"\n    },\n    \"PublisherSupportUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher support page\"\n    },\n    \"PrivacyUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher privacy page or the package privacy page\"\n    },\n    \"Author\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The package author\"\n    },\n    \"PackageName\": {\n      \"type\": \"string\",\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The package name\"\n    },\n    \"PackageUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package home page\"\n    },\n    \"License\": {\n      \"type\": \"string\",\n      \"minLength\": 3,\n      \"maxLength\": 512,\n      \"description\": \"The package license\"\n    },\n    \"LicenseUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The license page\"\n    },\n    \"Copyright\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 512,\n      \"description\": \"The package copyright\"\n    },\n    \"CopyrightUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package copyright page\"\n    },\n    \"ShortDescription\": {\n      \"type\": \"string\",\n      \"minLength\": 3,\n      \"maxLength\": 256,\n      \"description\": \"The short package description\"\n    },\n    \"Description\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 10000,\n      \"description\": \"The full package description\"\n    },\n    \"Moniker\": {\n      \"$ref\": \"#/definitions/Tag\",\n      \"description\": \"The most common package term\"\n    },\n    \"Tags\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Tag\"\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of additional package search terms\"\n    },\n    \"Agreements\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Agreement\"\n      },\n      \"maxItems\": 128\n    },\n    \"ReleaseNotes\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 10000,\n      \"description\": \"The package release notes\"\n    },\n    \"ReleaseNotesUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package release notes url\"\n    },\n    \"PurchaseUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\n    },\n    \"InstallationNotes\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 10000,\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"\n    },\n    \"Documentations\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Documentation\"\n      },\n      \"maxItems\": 256\n    },\n    \"Icons\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Icon\"\n      },\n      \"maxItems\": 1024\n    },\n    \"ManifestType\": {\n      \"type\": \"string\",\n      \"default\": \"defaultLocale\",\n      \"const\": \"defaultLocale\",\n      \"description\": \"The manifest type\"\n    },\n    \"ManifestVersion\": {\n      \"type\": \"string\",\n      \"default\": \"1.9.0\",\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\n      \"description\": \"The manifest syntax version\"\n    }\n  },\n  \"required\": [\n    \"PackageIdentifier\",\n    \"PackageVersion\",\n    \"PackageLocale\",\n    \"Publisher\",\n    \"PackageName\",\n    \"License\",\n    \"ShortDescription\",\n    \"ManifestType\",\n    \"ManifestVersion\"\n  ]\n}\r\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.9.0/manifest.installer.1.9.0.json",
    "content": "{\n  \"$id\": \"https://aka.ms/winget-manifest.installer.1.9.0.schema.json\",\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"description\": \"A representation of a single-file manifest representing an app installers in the OWC. v1.9.0\",\n  \"definitions\": {\n    \"PackageIdentifier\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\n      \"maxLength\": 128,\n      \"description\": \"The package unique identifier\"\n    },\n    \"PackageVersion\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n      \"maxLength\": 128,\n      \"description\": \"The package version\"\n    },\n    \"Locale\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\n      \"maxLength\": 20,\n      \"description\": \"The installer meta-data locale\"\n    },\n    \"Channel\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 16,\n      \"description\": \"The distribution channel\"\n    },\n    \"Platform\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"title\": \"Platform\",\n        \"type\": \"string\",\n        \"enum\": [\n          \"Windows.Desktop\",\n          \"Windows.Universal\"\n        ]\n      },\n      \"maxItems\": 2,\n      \"uniqueItems\": true,\n      \"description\": \"The installer supported operating system\"\n    },\n    \"MinimumOSVersion\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$\",\n      \"description\": \"The installer minimum operating system version\"\n    },\n    \"Url\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n      \"maxLength\": 2048,\n      \"description\": \"Url type\"\n    },\n    \"InstallerType\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"msix\",\n        \"msi\",\n        \"appx\",\n        \"exe\",\n        \"zip\",\n        \"inno\",\n        \"nullsoft\",\n        \"wix\",\n        \"burn\",\n        \"pwa\",\n        \"portable\"\n      ],\n      \"description\": \"Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level\"\n    },\n    \"NestedInstallerType\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"msix\",\n        \"msi\",\n        \"appx\",\n        \"exe\",\n        \"inno\",\n        \"nullsoft\",\n        \"wix\",\n        \"burn\",\n        \"portable\"\n      ],\n      \"description\": \"Enumeration of supported nested installer types contained inside an archive file\"\n    },\n    \"NestedInstallerFiles\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"object\",\n        \"title\": \"NestedInstallerFile\",\n        \"properties\": {\n          \"RelativeFilePath\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 512,\n            \"description\": \"The relative path to the nested installer file\"\n          },\n          \"PortableCommandAlias\": {\n            \"type\": [ \"string\", \"null\" ],\n            \"minLength\": 1,\n            \"maxLength\": 40,\n            \"description\": \"The command alias to be used for calling the package. Only applies to the nested portable package\"\n          }\n        },\n        \"required\": [ \"RelativeFilePath\" ],\n        \"description\": \"A nested installer file contained inside an archive\"\n      },\n      \"maxItems\": 1024,\n      \"description\": \"List of nested installer files contained inside an archive\"\n    },\n    \"Architecture\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"x86\",\n        \"x64\",\n        \"arm\",\n        \"arm64\",\n        \"neutral\"\n      ],\n      \"description\": \"The installer target architecture\"\n    },\n    \"Scope\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"user\",\n        \"machine\"\n      ],\n      \"description\": \"Scope indicates if the installer is per user or per machine\"\n    },\n    \"InstallModes\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"title\": \"InstallModes\",\n        \"type\": \"string\",\n        \"enum\": [\n          \"interactive\",\n          \"silent\",\n          \"silentWithProgress\"\n        ]\n      },\n      \"maxItems\": 3,\n      \"uniqueItems\": true,\n      \"description\": \"List of supported installer modes\"\n    },\n    \"InstallerSwitches\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"Silent\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Silent is the value that should be passed to the installer when user chooses a silent or quiet install\"\n        },\n        \"SilentWithProgress\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install\"\n        },\n        \"Interactive\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Interactive is the value that should be passed to the installer when user chooses an interactive install\"\n        },\n        \"InstallLocation\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"InstallLocation is the value passed to the installer for custom install location. <INSTALLPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\n        },\n        \"Log\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Log is the value passed to the installer for custom log file path. <LOGPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\n        },\n        \"Upgrade\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Upgrade is the value that should be passed to the installer when user chooses an upgrade\"\n        },\n        \"Custom\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 2048,\n          \"description\": \"Custom switches will be passed directly to the installer by winget\"\n        },\n        \"Repair\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"The 'Repair' value must be passed to the installer, ModifyPath ARP command, or uninstaller ARP command when the user opts for a repair.\"\n        }\n      }\n    },\n    \"InstallerReturnCode\": {\n      \"type\": \"integer\",\n      \"format\": \"long\",\n      \"not\": {\n        \"enum\": [ 0 ]\n      },\n      \"minimum\": -2147483648,\n      \"maximum\": 4294967295,\n      \"description\": \"An exit code that can be returned by the installer after execution\"\n    },\n    \"InstallerSuccessCodes\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/InstallerReturnCode\"\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of additional non-zero installer success exit codes other than known default values by winget\"\n    },\n    \"ExpectedReturnCodes\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"object\",\n        \"title\": \"ExpectedReturnCode\",\n        \"properties\": {\n          \"InstallerReturnCode\": {\n            \"$ref\": \"#/definitions/InstallerReturnCode\"\n          },\n          \"ReturnResponse\": {\n            \"type\": \"string\",\n            \"enum\": [\n              \"packageInUse\",\n              \"packageInUseByApplication\",\n              \"installInProgress\",\n              \"fileInUse\",\n              \"missingDependency\",\n              \"diskFull\",\n              \"insufficientMemory\",\n              \"invalidParameter\",\n              \"noNetwork\",\n              \"contactSupport\",\n              \"rebootRequiredToFinish\",\n              \"rebootRequiredForInstall\",\n              \"rebootInitiated\",\n              \"cancelledByUser\",\n              \"alreadyInstalled\",\n              \"downgrade\",\n              \"blockedByPolicy\",\n              \"systemNotSupported\",\n              \"custom\"\n            ]\n          },\n          \"ReturnResponseUrl\": {\n            \"$ref\": \"#/definitions/Url\",\n            \"description\": \"The return response url to provide additional guidance for expected return codes\"\n          }\n        },\n        \"required\": [ \"InstallerReturnCode\", \"ReturnResponse\" ]\n      },\n      \"maxItems\": 128,\n      \"description\": \"Installer exit codes for common errors\"\n    },\n    \"UpgradeBehavior\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"install\",\n        \"uninstallPrevious\",\n        \"deny\"\n      ],\n      \"description\": \"The upgrade method\"\n    },\n    \"Commands\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"maxLength\": 40\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of commands or aliases to run the package\"\n    },\n    \"Protocols\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"maxLength\": 2048\n      },\n      \"maxItems\": 64,\n      \"uniqueItems\": true,\n      \"description\": \"List of protocols the package provides a handler for\"\n    },\n    \"FileExtensions\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n        \"maxLength\": 64\n      },\n      \"maxItems\": 512,\n      \"uniqueItems\": true,\n      \"description\": \"List of file extensions the package could support\"\n    },\n    \"Dependencies\": {\n      \"type\": [ \"object\", \"null\" ],\n      \"properties\": {\n        \"WindowsFeatures\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 128\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of Windows feature dependencies\"\n        },\n        \"WindowsLibraries\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 128\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of Windows library dependencies\"\n        },\n        \"PackageDependencies\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"PackageIdentifier\": {\n                \"$ref\": \"#/definitions/PackageIdentifier\"\n              },\n              \"MinimumVersion\": {\n                \"$ref\": \"#/definitions/PackageVersion\"\n              }\n            },\n            \"required\": [ \"PackageIdentifier\" ]\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of package dependencies from current source\"\n        },\n        \"ExternalDependencies\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 128\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of external package dependencies\"\n        }\n      }\n    },\n    \"PackageFamilyName\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^[A-Za-z0-9][-\\\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$\",\n      \"maxLength\": 255,\n      \"description\": \"PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources\"\n    },\n    \"ProductCode\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 255,\n      \"description\": \"ProductCode could be used for correlation of packages across sources\"\n    },\n    \"Capabilities\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"maxLength\": 40\n      },\n      \"maxItems\": 1000,\n      \"uniqueItems\": true,\n      \"description\": \"List of appx or msix installer capabilities\"\n    },\n    \"RestrictedCapabilities\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"maxLength\": 40\n      },\n      \"maxItems\": 1000,\n      \"uniqueItems\": true,\n      \"description\": \"List of appx or msix installer restricted capabilities\"\n    },\n    \"Market\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[A-Z]{2}$\",\n      \"description\": \"The installer target market\"\n    },\n    \"MarketArray\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"maxItems\": 256,\n      \"items\": {\n        \"$ref\": \"#/definitions/Market\"\n      },\n      \"description\": \"Array of markets\"\n    },\n    \"Markets\": {\n      \"description\": \"The installer markets\",\n      \"type\": [ \"object\", \"null\" ],\n      \"oneOf\": [\n        {\n          \"properties\": {\n            \"AllowedMarkets\": {\n              \"$ref\": \"#/definitions/MarketArray\"\n            }\n          },\n          \"required\": [ \"AllowedMarkets\" ]\n        },\n        {\n          \"properties\": {\n            \"ExcludedMarkets\": {\n              \"$ref\": \"#/definitions/MarketArray\"\n            }\n          },\n          \"required\": [ \"ExcludedMarkets\" ]\n        }\n      ]\n    },\n    \"InstallerAbortsTerminal\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer will abort terminal. Default is false\"\n    },\n    \"ReleaseDate\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"format\": \"date\",\n      \"description\": \"The installer release date\"\n    },\n    \"InstallLocationRequired\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer requires an install location provided\"\n    },\n    \"RequireExplicitUpgrade\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer should be pinned by default from upgrade\"\n    },\n    \"DisplayInstallWarnings\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications.\"\n    },\n    \"UnsupportedOSArchitectures\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"items\": {\n        \"type\": \"string\",\n        \"title\": \"UnsupportedOSArchitecture\",\n        \"enum\": [\n          \"x86\",\n          \"x64\",\n          \"arm\",\n          \"arm64\"\n        ]\n      },\n      \"description\": \"List of OS architectures the installer does not support\"\n    },\n    \"UnsupportedArguments\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"items\": {\n        \"type\": \"string\",\n        \"title\": \"UnsupportedArgument\",\n        \"enum\": [\n          \"log\",\n          \"location\"\n        ]\n      },\n      \"description\": \"List of winget arguments the installer does not support\"\n    },\n    \"AppsAndFeaturesEntry\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"DisplayName\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 256,\n          \"description\": \"The DisplayName registry value\"\n        },\n        \"Publisher\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 256,\n          \"description\": \"The Publisher registry value\"\n        },\n        \"DisplayVersion\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 128,\n          \"description\": \"The DisplayVersion registry value\"\n        },\n        \"ProductCode\": {\n          \"$ref\": \"#/definitions/ProductCode\"\n        },\n        \"UpgradeCode\": {\n          \"$ref\": \"#/definitions/ProductCode\"\n        },\n        \"InstallerType\": {\n          \"$ref\": \"#/definitions/InstallerType\"\n        }\n      },\n      \"description\": \"Various key values under installer's ARP entry\"\n    },\n    \"AppsAndFeaturesEntries\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"maxItems\": 128,\n      \"items\": {\n        \"$ref\": \"#/definitions/AppsAndFeaturesEntry\"\n      },\n      \"description\": \"List of ARP entries.\"\n    },\n    \"ElevationRequirement\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"elevationRequired\",\n        \"elevationProhibited\",\n        \"elevatesSelf\"\n      ],\n      \"description\": \"The installer's elevation requirement\"\n    },\n    \"InstallationMetadata\": {\n      \"type\": \"object\",\n      \"title\": \"InstallationMetadata\",\n      \"properties\": {\n        \"DefaultInstallLocation\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 2048,\n          \"description\": \"Represents the default installed package location. Used for deeper installation detection.\"\n        },\n        \"Files\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"uniqueItems\": true,\n          \"maxItems\": 2048,\n          \"items\": {\n            \"type\": \"object\",\n            \"title\": \"InstalledFile\",\n            \"properties\": {\n              \"RelativeFilePath\": {\n                \"type\": \"string\",\n                \"minLength\": 1,\n                \"maxLength\": 2048,\n                \"description\": \"The relative path to the installed file.\"\n              },\n              \"FileSha256\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n                \"description\": \"Optional Sha256 of the installed file.\"\n              },\n              \"FileType\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"enum\": [\n                  \"launch\",\n                  \"uninstall\",\n                  \"other\"\n                ],\n                \"description\": \"The optional installed file type. If not specified, the file is treated as other.\"\n              },\n              \"InvocationParameter\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"minLength\": 1,\n                \"maxLength\": 2048,\n                \"description\": \"Optional parameter for invocable files.\"\n              },\n              \"DisplayName\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"minLength\": 1,\n                \"maxLength\": 256,\n                \"description\": \"Optional display name for invocable files.\"\n              }\n            },\n            \"required\": [ \"RelativeFilePath\" ],\n            \"description\": \"Represents an installed file.\"\n          },\n          \"description\": \"List of installed files.\"\n        }\n      },\n      \"description\": \"Details about the installation. Used for deeper installation detection.\"\n    },\n    \"DownloadCommandProhibited\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer is prohibited from being downloaded for offline installation.\"\n    },\n    \"RepairBehavior\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"modify\",\n        \"uninstaller\",\n        \"installer\"\n      ],\n      \"description\": \"The repair method\"\n    },\n    \"ArchiveBinariesDependOnPath\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the install location should be added directly to the PATH environment variable. Only applies to an archive containing portable packages.\"\n    },\n    \"Installer\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"InstallerLocale\": {\n          \"$ref\": \"#/definitions/Locale\"\n        },\n        \"Platform\": {\n          \"$ref\": \"#/definitions/Platform\"\n        },\n        \"MinimumOSVersion\": {\n          \"$ref\": \"#/definitions/MinimumOSVersion\"\n        },\n        \"Architecture\": {\n          \"$ref\": \"#/definitions/Architecture\"\n        },\n        \"InstallerType\": {\n          \"$ref\": \"#/definitions/InstallerType\"\n        },\n        \"NestedInstallerType\": {\n          \"$ref\": \"#/definitions/NestedInstallerType\"\n        },\n        \"NestedInstallerFiles\": {\n          \"$ref\": \"#/definitions/NestedInstallerFiles\"\n        },\n        \"Scope\": {\n          \"$ref\": \"#/definitions/Scope\"\n        },\n        \"InstallerUrl\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n          \"maxLength\": 2048,\n          \"description\": \"The installer Url\"\n        },\n        \"InstallerSha256\": {\n          \"type\": \"string\",\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"Sha256 is required. Sha256 of the installer\"\n        },\n        \"SignatureSha256\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable\"\n        },\n        \"InstallModes\": {\n          \"$ref\": \"#/definitions/InstallModes\"\n        },\n        \"InstallerSwitches\": {\n          \"$ref\": \"#/definitions/InstallerSwitches\"\n        },\n        \"InstallerSuccessCodes\": {\n          \"$ref\": \"#/definitions/InstallerSuccessCodes\"\n        },\n        \"ExpectedReturnCodes\": {\n          \"$ref\": \"#/definitions/ExpectedReturnCodes\"\n        },\n        \"UpgradeBehavior\": {\n          \"$ref\": \"#/definitions/UpgradeBehavior\"\n        },\n        \"Commands\": {\n          \"$ref\": \"#/definitions/Commands\"\n        },\n        \"Protocols\": {\n          \"$ref\": \"#/definitions/Protocols\"\n        },\n        \"FileExtensions\": {\n          \"$ref\": \"#/definitions/FileExtensions\"\n        },\n        \"Dependencies\": {\n          \"$ref\": \"#/definitions/Dependencies\"\n        },\n        \"PackageFamilyName\": {\n          \"$ref\": \"#/definitions/PackageFamilyName\"\n        },\n        \"ProductCode\": {\n          \"$ref\": \"#/definitions/ProductCode\"\n        },\n        \"Capabilities\": {\n          \"$ref\": \"#/definitions/Capabilities\"\n        },\n        \"RestrictedCapabilities\": {\n          \"$ref\": \"#/definitions/RestrictedCapabilities\"\n        },\n        \"Markets\": {\n          \"$ref\": \"#/definitions/Markets\"\n        },\n        \"InstallerAbortsTerminal\": {\n          \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\n        },\n        \"ReleaseDate\": {\n          \"$ref\": \"#/definitions/ReleaseDate\"\n        },\n        \"InstallLocationRequired\": {\n          \"$ref\": \"#/definitions/InstallLocationRequired\"\n        },\n        \"RequireExplicitUpgrade\": {\n          \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\n        },\n        \"DisplayInstallWarnings\": {\n          \"$ref\": \"#/definitions/DisplayInstallWarnings\"\n        },\n        \"UnsupportedOSArchitectures\": {\n          \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\n        },\n        \"UnsupportedArguments\": {\n          \"$ref\": \"#/definitions/UnsupportedArguments\"\n        },\n        \"AppsAndFeaturesEntries\": {\n          \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\n        },\n        \"ElevationRequirement\": {\n          \"$ref\": \"#/definitions/ElevationRequirement\"\n        },\n        \"InstallationMetadata\": {\n          \"$ref\": \"#/definitions/InstallationMetadata\"\n        },\n        \"DownloadCommandProhibited\": {\n          \"$ref\": \"#/definitions/DownloadCommandProhibited\"\n        },\n        \"RepairBehavior\": {\n          \"$ref\": \"#/definitions/RepairBehavior\"\n        },\n        \"ArchiveBinariesDependOnPath\": {\n          \"$ref\": \"#/definitions/ArchiveBinariesDependOnPath\"\n        }\n      },\n      \"required\": [\n        \"Architecture\",\n        \"InstallerUrl\",\n        \"InstallerSha256\"\n      ]\n    }\n  },\n  \"type\": \"object\",\n  \"properties\": {\n    \"PackageIdentifier\": {\n      \"$ref\": \"#/definitions/PackageIdentifier\"\n    },\n    \"PackageVersion\": {\n      \"$ref\": \"#/definitions/PackageVersion\"\n    },\n    \"Channel\": {\n      \"$ref\": \"#/definitions/Channel\"\n    },\n    \"InstallerLocale\": {\n      \"$ref\": \"#/definitions/Locale\"\n    },\n    \"Platform\": {\n      \"$ref\": \"#/definitions/Platform\"\n    },\n    \"MinimumOSVersion\": {\n      \"$ref\": \"#/definitions/MinimumOSVersion\"\n    },\n    \"InstallerType\": {\n      \"$ref\": \"#/definitions/InstallerType\"\n    },\n    \"NestedInstallerType\": {\n      \"$ref\": \"#/definitions/NestedInstallerType\"\n    },\n    \"NestedInstallerFiles\": {\n      \"$ref\": \"#/definitions/NestedInstallerFiles\"\n    },\n    \"Scope\": {\n      \"$ref\": \"#/definitions/Scope\"\n    },\n    \"InstallModes\": {\n      \"$ref\": \"#/definitions/InstallModes\"\n    },\n    \"InstallerSwitches\": {\n      \"$ref\": \"#/definitions/InstallerSwitches\"\n    },\n    \"InstallerSuccessCodes\": {\n      \"$ref\": \"#/definitions/InstallerSuccessCodes\"\n    },\n    \"ExpectedReturnCodes\": {\n      \"$ref\": \"#/definitions/ExpectedReturnCodes\"\n    },\n    \"UpgradeBehavior\": {\n      \"$ref\": \"#/definitions/UpgradeBehavior\"\n    },\n    \"Commands\": {\n      \"$ref\": \"#/definitions/Commands\"\n    },\n    \"Protocols\": {\n      \"$ref\": \"#/definitions/Protocols\"\n    },\n    \"FileExtensions\": {\n      \"$ref\": \"#/definitions/FileExtensions\"\n    },\n    \"Dependencies\": {\n      \"$ref\": \"#/definitions/Dependencies\"\n    },\n    \"PackageFamilyName\": {\n      \"$ref\": \"#/definitions/PackageFamilyName\"\n    },\n    \"ProductCode\": {\n      \"$ref\": \"#/definitions/ProductCode\"\n    },\n    \"Capabilities\": {\n      \"$ref\": \"#/definitions/Capabilities\"\n    },\n    \"RestrictedCapabilities\": {\n      \"$ref\": \"#/definitions/RestrictedCapabilities\"\n    },\n    \"Markets\": {\n      \"$ref\": \"#/definitions/Markets\"\n    },\n    \"InstallerAbortsTerminal\": {\n      \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\n    },\n    \"ReleaseDate\": {\n      \"$ref\": \"#/definitions/ReleaseDate\"\n    },\n    \"InstallLocationRequired\": {\n      \"$ref\": \"#/definitions/InstallLocationRequired\"\n    },\n    \"RequireExplicitUpgrade\": {\n      \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\n    },\n    \"DisplayInstallWarnings\": {\n      \"$ref\": \"#/definitions/DisplayInstallWarnings\"\n    },\n    \"UnsupportedOSArchitectures\": {\n      \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\n    },\n    \"UnsupportedArguments\": {\n      \"$ref\": \"#/definitions/UnsupportedArguments\"\n    },\n    \"AppsAndFeaturesEntries\": {\n      \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\n    },\n    \"ElevationRequirement\": {\n      \"$ref\": \"#/definitions/ElevationRequirement\"\n    },\n    \"InstallationMetadata\": {\n      \"$ref\": \"#/definitions/InstallationMetadata\"\n    },\n    \"DownloadCommandProhibited\": {\n      \"$ref\": \"#/definitions/DownloadCommandProhibited\"\n    },\n    \"RepairBehavior\": {\n      \"$ref\": \"#/definitions/RepairBehavior\"\n    },\n    \"ArchiveBinariesDependOnPath\": {\n      \"$ref\": \"#/definitions/ArchiveBinariesDependOnPath\"\n    },\n    \"Installers\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/Installer\"\n      },\n      \"minItems\": 1,\n      \"maxItems\": 1024\n    },\n    \"ManifestType\": {\n      \"type\": \"string\",\n      \"default\": \"installer\",\n      \"const\": \"installer\",\n      \"description\": \"The manifest type\"\n    },\n    \"ManifestVersion\": {\n      \"type\": \"string\",\n      \"default\": \"1.9.0\",\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\n      \"description\": \"The manifest syntax version\"\n    }\n  },\n  \"required\": [\n    \"PackageIdentifier\",\n    \"PackageVersion\",\n    \"Installers\",\n    \"ManifestType\",\n    \"ManifestVersion\"\n  ]\n}\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.9.0/manifest.locale.1.9.0.json",
    "content": "{\n  \"$id\": \"https://aka.ms/winget-manifest.locale.1.9.0.schema.json\",\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"description\": \"A representation of a multiple-file manifest representing app metadata in other locale in the OWC. v1.9.0\",\n  \"definitions\": {\n    \"Url\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n      \"maxLength\": 2048,\n      \"description\": \"Optional Url type\"\n    },\n    \"Tag\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 40,\n      \"description\": \"Package tag\"\n    },\n    \"Agreement\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"AgreementLabel\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 100,\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\n        },\n        \"Agreement\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 10000,\n          \"description\": \"The agreement text content.\"\n        },\n        \"AgreementUrl\": {\n          \"$ref\": \"#/definitions/Url\",\n          \"description\": \"The agreement URL.\"\n        }\n      }\n    },\n    \"Documentation\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"DocumentLabel\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 100,\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\n        },\n        \"DocumentUrl\": {\n          \"$ref\": \"#/definitions/Url\",\n          \"description\": \"The documentation URL.\"\n        }\n      }\n    },\n    \"Icon\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"IconUrl\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n          \"maxLength\": 2048,\n          \"description\": \"The url of the hosted icon file\"\n        },\n        \"IconFileType\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"png\",\n            \"jpeg\",\n            \"ico\"\n          ],\n          \"description\": \"The icon file type\"\n        },\n        \"IconResolution\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"enum\": [\n            \"custom\",\n            \"16x16\",\n            \"20x20\",\n            \"24x24\",\n            \"30x30\",\n            \"32x32\",\n            \"36x36\",\n            \"40x40\",\n            \"48x48\",\n            \"60x60\",\n            \"64x64\",\n            \"72x72\",\n            \"80x80\",\n            \"96x96\",\n            \"256x256\"\n          ],\n          \"description\": \"Optional icon resolution\"\n        },\n        \"IconTheme\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"enum\": [\n            \"default\",\n            \"light\",\n            \"dark\",\n            \"highContrast\"\n          ],\n          \"description\": \"Optional icon theme\"\n        },\n        \"IconSha256\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"Optional Sha256 of the icon file\"\n        }\n      },\n      \"required\": [\n        \"IconUrl\",\n        \"IconFileType\"\n      ]\n    }\n  },\n  \"type\": \"object\",\n  \"properties\": {\n    \"PackageIdentifier\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\n      \"maxLength\": 128,\n      \"description\": \"The package unique identifier\"\n    },\n    \"PackageVersion\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n      \"maxLength\": 128,\n      \"description\": \"The package version\"\n    },\n    \"PackageLocale\": {\n      \"type\": \"string\",\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\n      \"maxLength\": 20,\n      \"description\": \"The package meta-data locale\"\n    },\n    \"Publisher\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The publisher name\"\n    },\n    \"PublisherUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher home page\"\n    },\n    \"PublisherSupportUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher support page\"\n    },\n    \"PrivacyUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher privacy page or the package privacy page\"\n    },\n    \"Author\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The package author\"\n    },\n    \"PackageName\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The package name\"\n    },\n    \"PackageUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package home page\"\n    },\n    \"License\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 512,\n      \"description\": \"The package license\"\n    },\n    \"LicenseUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The license page\"\n    },\n    \"Copyright\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 512,\n      \"description\": \"The package copyright\"\n    },\n    \"CopyrightUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package copyright page\"\n    },\n    \"ShortDescription\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 256,\n      \"description\": \"The short package description\"\n    },\n    \"Description\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 10000,\n      \"description\": \"The full package description\"\n    },\n    \"Tags\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Tag\"\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of additional package search terms\"\n    },\n    \"Agreements\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Agreement\"\n      },\n      \"maxItems\": 128\n    },\n    \"ReleaseNotes\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 10000,\n      \"description\": \"The package release notes\"\n    },\n    \"ReleaseNotesUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package release notes url\"\n    },\n    \"PurchaseUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\n    },\n    \"InstallationNotes\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 10000,\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"\n    },\n    \"Documentations\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Documentation\"\n      },\n      \"maxItems\": 256\n    },\n    \"Icons\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Icon\"\n      },\n      \"maxItems\": 1024\n    },\n    \"ManifestType\": {\n      \"type\": \"string\",\n      \"default\": \"locale\",\n      \"const\": \"locale\",\n      \"description\": \"The manifest type\"\n    },\n    \"ManifestVersion\": {\n      \"type\": \"string\",\n      \"default\": \"1.9.0\",\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\n      \"description\": \"The manifest syntax version\"\n    }\n  },\n  \"required\": [\n    \"PackageIdentifier\",\n    \"PackageVersion\",\n    \"PackageLocale\",\n    \"ManifestType\",\n    \"ManifestVersion\"\n  ]\n}\r\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.9.0/manifest.singleton.1.9.0.json",
    "content": "{\n  \"$id\": \"https://aka.ms/winget-manifest.singleton.1.9.0.schema.json\",\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"description\": \"A representation of a single-file manifest representing an app in the OWC. v1.9.0\",\n  \"definitions\": {\n    \"PackageIdentifier\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\n      \"maxLength\": 128,\n      \"description\": \"The package unique identifier\"\n    },\n    \"PackageVersion\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n      \"maxLength\": 128,\n      \"description\": \"The package version\"\n    },\n    \"Locale\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\n      \"maxLength\": 20,\n      \"description\": \"The package meta-data locale\"\n    },\n    \"Url\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n      \"maxLength\": 2048,\n      \"description\": \"Optional Url type\"\n    },\n    \"Tag\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 40,\n      \"description\": \"Package moniker or tag\"\n    },\n    \"Agreement\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"AgreementLabel\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 100,\n          \"description\": \"The label of the Agreement. i.e. EULA, AgeRating, etc. This field should be localized. Either Agreement or AgreementUrl is required. When we show the agreements, we would Bold the AgreementLabel\"\n        },\n        \"Agreement\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 10000,\n          \"description\": \"The agreement text content.\"\n        },\n        \"AgreementUrl\": {\n          \"$ref\": \"#/definitions/Url\",\n          \"description\": \"The agreement URL.\"\n        }\n      }\n    },\n    \"Documentation\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"DocumentLabel\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 100,\n          \"description\": \"The label of the documentation for providing software guides such as manuals and troubleshooting URLs.\"\n        },\n        \"DocumentUrl\": {\n          \"$ref\": \"#/definitions/Url\",\n          \"description\": \"The documentation URL.\"\n        }\n      }\n    },\n    \"Icon\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"IconUrl\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n          \"maxLength\": 2048,\n          \"description\": \"The url of the hosted icon file\"\n        },\n        \"IconFileType\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"png\",\n            \"jpeg\",\n            \"ico\"\n          ],\n          \"description\": \"The icon file type\"\n        },\n        \"IconResolution\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"enum\": [\n            \"custom\",\n            \"16x16\",\n            \"20x20\",\n            \"24x24\",\n            \"30x30\",\n            \"32x32\",\n            \"36x36\",\n            \"40x40\",\n            \"48x48\",\n            \"60x60\",\n            \"64x64\",\n            \"72x72\",\n            \"80x80\",\n            \"96x96\",\n            \"256x256\"\n          ],\n          \"description\": \"Optional icon resolution\"\n        },\n        \"IconTheme\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"enum\": [\n            \"default\",\n            \"light\",\n            \"dark\",\n            \"highContrast\"\n          ],\n          \"description\": \"Optional icon theme\"\n        },\n        \"IconSha256\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"Optional Sha256 of the icon file\"\n        }\n      },\n      \"required\": [\n        \"IconUrl\",\n        \"IconFileType\"\n      ]\n    },\n    \"Channel\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 16,\n      \"description\": \"The distribution channel\"\n    },\n    \"Platform\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"title\": \"Platform\",\n        \"type\": \"string\",\n        \"enum\": [\n          \"Windows.Desktop\",\n          \"Windows.Universal\"\n        ]\n      },\n      \"maxItems\": 2,\n      \"uniqueItems\": true,\n      \"description\": \"The installer supported operating system\"\n    },\n    \"MinimumOSVersion\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){0,3}$\",\n      \"description\": \"The installer minimum operating system version\"\n    },\n    \"InstallerType\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"msix\",\n        \"msi\",\n        \"appx\",\n        \"exe\",\n        \"zip\",\n        \"inno\",\n        \"nullsoft\",\n        \"wix\",\n        \"burn\",\n        \"pwa\",\n        \"portable\"\n      ],\n      \"description\": \"Enumeration of supported installer types. InstallerType is required in either root level or individual Installer level\"\n    },\n    \"NestedInstallerType\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"msix\",\n        \"msi\",\n        \"appx\",\n        \"exe\",\n        \"inno\",\n        \"nullsoft\",\n        \"wix\",\n        \"burn\",\n        \"portable\"\n      ],\n      \"description\": \"Enumeration of supported nested installer types contained inside an archive file\"\n    },\n    \"NestedInstallerFiles\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"object\",\n        \"title\": \"NestedInstallerFile\",\n        \"properties\": {\n          \"RelativeFilePath\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 512,\n            \"description\": \"The relative path to the nested installer file\"\n          },\n          \"PortableCommandAlias\": {\n            \"type\": [ \"string\", \"null\" ],\n            \"minLength\": 1,\n            \"maxLength\": 40,\n            \"description\": \"The command alias to be used for calling the package. Only applies to the nested portable package\"\n          }\n        },\n        \"required\": [ \"RelativeFilePath\" ],\n        \"description\": \"A nested installer file contained inside an archive\"\n      },\n      \"maxItems\": 1024,\n      \"description\": \"List of nested installer files contained inside an archive\"\n    },\n    \"Architecture\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"x86\",\n        \"x64\",\n        \"arm\",\n        \"arm64\",\n        \"neutral\"\n      ],\n      \"description\": \"The installer target architecture\"\n    },\n    \"Scope\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"user\",\n        \"machine\"\n      ],\n      \"description\": \"Scope indicates if the installer is per user or per machine\"\n    },\n    \"InstallModes\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"title\": \"InstallModes\",\n        \"type\": \"string\",\n        \"enum\": [\n          \"interactive\",\n          \"silent\",\n          \"silentWithProgress\"\n        ]\n      },\n      \"maxItems\": 3,\n      \"uniqueItems\": true,\n      \"description\": \"List of supported installer modes\"\n    },\n    \"InstallerSwitches\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"Silent\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Silent is the value that should be passed to the installer when user chooses a silent or quiet install\"\n        },\n        \"SilentWithProgress\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"SilentWithProgress is the value that should be passed to the installer when user chooses a non-interactive install\"\n        },\n        \"Interactive\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Interactive is the value that should be passed to the installer when user chooses an interactive install\"\n        },\n        \"InstallLocation\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"InstallLocation is the value passed to the installer for custom install location. <INSTALLPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\n        },\n        \"Log\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Log is the value passed to the installer for custom log file path. <LOGPATH> token can be included in the switch value so that winget will replace the token with user provided path\"\n        },\n        \"Upgrade\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"Upgrade is the value that should be passed to the installer when user chooses an upgrade\"\n        },\n        \"Custom\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 2048,\n          \"description\": \"Custom switches will be passed directly to the installer by winget\"\n        },\n        \"Repair\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 512,\n          \"description\": \"The 'Repair' value must be passed to the installer, ModifyPath ARP command, or uninstaller ARP command when the user opts for a repair\"\n        }\n      }\n    },\n    \"InstallerReturnCode\": {\n      \"type\": \"integer\",\n      \"format\": \"long\",\n      \"not\": {\n        \"enum\": [ 0 ]\n      },\n      \"minimum\": -2147483648,\n      \"maximum\": 4294967295,\n      \"description\": \"An exit code that can be returned by the installer after execution\"\n    },\n    \"InstallerSuccessCodes\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/InstallerReturnCode\"\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of additional non-zero installer success exit codes other than known default values by winget\"\n    },\n    \"ExpectedReturnCodes\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"object\",\n        \"title\": \"ExpectedReturnCode\",\n        \"properties\": {\n          \"InstallerReturnCode\": {\n            \"$ref\": \"#/definitions/InstallerReturnCode\"\n          },\n          \"ReturnResponse\": {\n            \"type\": \"string\",\n            \"enum\": [\n              \"packageInUse\",\n              \"packageInUseByApplication\",\n              \"installInProgress\",\n              \"fileInUse\",\n              \"missingDependency\",\n              \"diskFull\",\n              \"insufficientMemory\",\n              \"invalidParameter\",\n              \"noNetwork\",\n              \"contactSupport\",\n              \"rebootRequiredToFinish\",\n              \"rebootRequiredForInstall\",\n              \"rebootInitiated\",\n              \"cancelledByUser\",\n              \"alreadyInstalled\",\n              \"downgrade\",\n              \"blockedByPolicy\",\n              \"systemNotSupported\",\n              \"custom\"\n            ]\n          },\n          \"ReturnResponseUrl\": {\n            \"$ref\": \"#/definitions/Url\",\n            \"description\": \"The return response url to provide additional guidance for expected return codes\"\n          }\n        },\n        \"required\": [ \"InstallerReturnCode\", \"ReturnResponse\" ]\n      },\n      \"maxItems\": 128,\n      \"description\": \"Installer exit codes for common errors\"\n    },\n    \"UpgradeBehavior\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"install\",\n        \"uninstallPrevious\",\n        \"deny\"\n      ],\n      \"description\": \"The upgrade method\"\n    },\n    \"Commands\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"maxLength\": 40\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of commands or aliases to run the package\"\n    },\n    \"Protocols\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"maxLength\": 2048\n      },\n      \"maxItems\": 64,\n      \"uniqueItems\": true,\n      \"description\": \"List of protocols the package provides a handler for\"\n    },\n    \"FileExtensions\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n        \"maxLength\": 64\n      },\n      \"maxItems\": 512,\n      \"uniqueItems\": true,\n      \"description\": \"List of file extensions the package could support\"\n    },\n    \"Dependencies\": {\n      \"type\": [ \"object\", \"null\" ],\n      \"properties\": {\n        \"WindowsFeatures\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 128\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of Windows feature dependencies\"\n        },\n        \"WindowsLibraries\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 128\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of Windows library dependencies\"\n        },\n        \"PackageDependencies\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"PackageIdentifier\": {\n                \"$ref\": \"#/definitions/PackageIdentifier\"\n              },\n              \"MinimumVersion\": {\n                \"$ref\": \"#/definitions/PackageVersion\"\n              }\n            },\n            \"required\": [ \"PackageIdentifier\" ]\n          },\n          \"maxItems\": 16,\n          \"description\": \"List of package dependencies from current source\"\n        },\n        \"ExternalDependencies\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"items\": {\n            \"type\": \"string\",\n            \"minLength\": 1,\n            \"maxLength\": 128\n          },\n          \"maxItems\": 16,\n          \"uniqueItems\": true,\n          \"description\": \"List of external package dependencies\"\n        }\n      }\n    },\n    \"PackageFamilyName\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"pattern\": \"^[A-Za-z0-9][-\\\\.A-Za-z0-9]+_[A-Za-z0-9]{13}$\",\n      \"maxLength\": 255,\n      \"description\": \"PackageFamilyName for appx or msix installer. Could be used for correlation of packages across sources\"\n    },\n    \"ProductCode\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 255,\n      \"description\": \"ProductCode could be used for correlation of packages across sources\"\n    },\n    \"Capabilities\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"maxLength\": 40\n      },\n      \"maxItems\": 1000,\n      \"uniqueItems\": true,\n      \"description\": \"List of appx or msix installer capabilities\"\n    },\n    \"RestrictedCapabilities\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"maxLength\": 40\n      },\n      \"maxItems\": 1000,\n      \"uniqueItems\": true,\n      \"description\": \"List of appx or msix installer restricted capabilities\"\n    },\n    \"Market\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[A-Z]{2}$\",\n      \"description\": \"The installer target market\"\n    },\n    \"MarketArray\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"maxItems\": 256,\n      \"items\": {\n        \"$ref\": \"#/definitions/Market\"\n      },\n      \"description\": \"Array of markets\"\n    },\n    \"Markets\": {\n      \"description\": \"The installer markets\",\n      \"type\": [ \"object\", \"null\" ],\n      \"oneOf\": [\n        {\n          \"properties\": {\n            \"AllowedMarkets\": {\n              \"$ref\": \"#/definitions/MarketArray\"\n            }\n          },\n          \"required\": [ \"AllowedMarkets\" ]\n        },\n        {\n          \"properties\": {\n            \"ExcludedMarkets\": {\n              \"$ref\": \"#/definitions/MarketArray\"\n            }\n          },\n          \"required\": [ \"ExcludedMarkets\" ]\n        }\n      ]\n    },\n    \"InstallerAbortsTerminal\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer will abort terminal. Default is false\"\n    },\n    \"ReleaseDate\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"format\": \"date\",\n      \"description\": \"The installer release date\"\n    },\n    \"InstallLocationRequired\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer requires an install location provided\"\n    },\n    \"RequireExplicitUpgrade\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer should be pinned by default from upgrade\"\n    },\n    \"DisplayInstallWarnings\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether winget should display a warning message if the install or upgrade is known to interfere with running applications.\"\n    },\n    \"UnsupportedOSArchitectures\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"items\": {\n        \"type\": \"string\",\n        \"title\": \"UnsupportedOSArchitecture\",\n        \"enum\": [\n          \"x86\",\n          \"x64\",\n          \"arm\",\n          \"arm64\"\n        ]\n      },\n      \"description\": \"List of OS architectures the installer does not support\"\n    },\n    \"UnsupportedArguments\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"items\": {\n        \"type\": \"string\",\n        \"title\": \"UnsupportedArgument\",\n        \"enum\": [\n          \"log\",\n          \"location\"\n        ]\n      },\n      \"description\": \"List of winget arguments the installer does not support\"\n    },\n    \"AppsAndFeaturesEntry\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"DisplayName\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 256,\n          \"description\": \"The DisplayName registry value\"\n        },\n        \"Publisher\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 256,\n          \"description\": \"The Publisher registry value\"\n        },\n        \"DisplayVersion\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 128,\n          \"description\": \"The DisplayVersion registry value\"\n        },\n        \"ProductCode\": {\n          \"$ref\": \"#/definitions/ProductCode\"\n        },\n        \"UpgradeCode\": {\n          \"$ref\": \"#/definitions/ProductCode\"\n        },\n        \"InstallerType\": {\n          \"$ref\": \"#/definitions/InstallerType\"\n        }\n      },\n      \"description\": \"Various key values under installer's ARP entry\"\n    },\n    \"AppsAndFeaturesEntries\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"uniqueItems\": true,\n      \"maxItems\": 128,\n      \"items\": {\n        \"$ref\": \"#/definitions/AppsAndFeaturesEntry\"\n      },\n      \"description\": \"List of ARP entries.\"\n    },\n    \"ElevationRequirement\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"elevationRequired\",\n        \"elevationProhibited\",\n        \"elevatesSelf\"\n      ],\n      \"description\": \"The installer's elevation requirement\"\n    },\n    \"InstallationMetadata\": {\n      \"type\": \"object\",\n      \"title\": \"InstallationMetadata\",\n      \"properties\": {\n        \"DefaultInstallLocation\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"minLength\": 1,\n          \"maxLength\": 2048,\n          \"description\": \"Represents the default installed package location. Used for deeper installation detection.\"\n        },\n        \"Files\": {\n          \"type\": [ \"array\", \"null\" ],\n          \"uniqueItems\": true,\n          \"maxItems\": 2048,\n          \"items\": {\n            \"type\": \"object\",\n            \"title\": \"InstalledFile\",\n            \"properties\": {\n              \"RelativeFilePath\": {\n                \"type\": \"string\",\n                \"minLength\": 1,\n                \"maxLength\": 2048,\n                \"description\": \"The relative path to the installed file.\"\n              },\n              \"FileSha256\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n                \"description\": \"Optional Sha256 of the installed file.\"\n              },\n              \"FileType\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"enum\": [\n                  \"launch\",\n                  \"uninstall\",\n                  \"other\"\n                ],\n                \"description\": \"The optional installed file type. If not specified, the file is treated as other.\"\n              },\n              \"InvocationParameter\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"minLength\": 1,\n                \"maxLength\": 2048,\n                \"description\": \"Optional parameter for invocable files.\"\n              },\n              \"DisplayName\": {\n                \"type\": [ \"string\", \"null\" ],\n                \"minLength\": 1,\n                \"maxLength\": 256,\n                \"description\": \"Optional display name for invocable files.\"\n              }\n            },\n            \"required\": [ \"RelativeFilePath\" ],\n            \"description\": \"Represents an installed file.\"\n          },\n          \"description\": \"List of installed files.\"\n        }\n      },\n      \"description\": \"Details about the installation. Used for deeper installation detection.\"\n    },\n    \"DownloadCommandProhibited\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the installer is prohibited from being downloaded for offline installation.\"\n    },\n    \"RepairBehavior\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"enum\": [\n        \"modify\",\n        \"uninstaller\",\n        \"installer\"\n      ],\n      \"description\": \"The repair method\"\n    },\n    \"ArchiveBinariesDependOnPath\": {\n      \"type\": [ \"boolean\", \"null\" ],\n      \"description\": \"Indicates whether the install location should be added directly to the PATH environment variable. Only applies to an archive containing portable packages.\"\n    },\n    \"Installer\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"InstallerLocale\": {\n          \"$ref\": \"#/definitions/Locale\"\n        },\n        \"Platform\": {\n          \"$ref\": \"#/definitions/Platform\"\n        },\n        \"MinimumOSVersion\": {\n          \"$ref\": \"#/definitions/MinimumOSVersion\"\n        },\n        \"Architecture\": {\n          \"$ref\": \"#/definitions/Architecture\"\n        },\n        \"InstallerType\": {\n          \"$ref\": \"#/definitions/InstallerType\"\n        },\n        \"NestedInstallerType\": {\n          \"$ref\": \"#/definitions/NestedInstallerType\"\n        },\n        \"NestedInstallerFiles\": {\n          \"$ref\": \"#/definitions/NestedInstallerFiles\"\n        },\n        \"Scope\": {\n          \"$ref\": \"#/definitions/Scope\"\n        },\n        \"InstallerUrl\": {\n          \"type\": \"string\",\n          \"pattern\": \"^([Hh][Tt][Tt][Pp][Ss]?)://.+$\",\n          \"maxLength\": 2048,\n          \"description\": \"The installer Url\"\n        },\n        \"InstallerSha256\": {\n          \"type\": \"string\",\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"Sha256 is required. Sha256 of the installer\"\n        },\n        \"SignatureSha256\": {\n          \"type\": [ \"string\", \"null\" ],\n          \"pattern\": \"^[A-Fa-f0-9]{64}$\",\n          \"description\": \"SignatureSha256 is recommended for appx or msix. It is the sha256 of signature file inside appx or msix. Could be used during streaming install if applicable\"\n        },\n        \"InstallModes\": {\n          \"$ref\": \"#/definitions/InstallModes\"\n        },\n        \"InstallerSwitches\": {\n          \"$ref\": \"#/definitions/InstallerSwitches\"\n        },\n        \"InstallerSuccessCodes\": {\n          \"$ref\": \"#/definitions/InstallerSuccessCodes\"\n        },\n        \"ExpectedReturnCodes\": {\n          \"$ref\": \"#/definitions/ExpectedReturnCodes\"\n        },\n        \"UpgradeBehavior\": {\n          \"$ref\": \"#/definitions/UpgradeBehavior\"\n        },\n        \"Commands\": {\n          \"$ref\": \"#/definitions/Commands\"\n        },\n        \"Protocols\": {\n          \"$ref\": \"#/definitions/Protocols\"\n        },\n        \"FileExtensions\": {\n          \"$ref\": \"#/definitions/FileExtensions\"\n        },\n        \"Dependencies\": {\n          \"$ref\": \"#/definitions/Dependencies\"\n        },\n        \"PackageFamilyName\": {\n          \"$ref\": \"#/definitions/PackageFamilyName\"\n        },\n        \"ProductCode\": {\n          \"$ref\": \"#/definitions/ProductCode\"\n        },\n        \"Capabilities\": {\n          \"$ref\": \"#/definitions/Capabilities\"\n        },\n        \"RestrictedCapabilities\": {\n          \"$ref\": \"#/definitions/RestrictedCapabilities\"\n        },\n        \"Markets\": {\n          \"$ref\": \"#/definitions/Markets\"\n        },\n        \"InstallerAbortsTerminal\": {\n          \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\n        },\n        \"ReleaseDate\": {\n          \"$ref\": \"#/definitions/ReleaseDate\"\n        },\n        \"InstallLocationRequired\": {\n          \"$ref\": \"#/definitions/InstallLocationRequired\"\n        },\n        \"RequireExplicitUpgrade\": {\n          \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\n        },\n        \"DisplayInstallWarnings\": {\n          \"$ref\": \"#/definitions/DisplayInstallWarnings\"\n        },\n        \"UnsupportedOSArchitectures\": {\n          \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\n        },\n        \"UnsupportedArguments\": {\n          \"$ref\": \"#/definitions/UnsupportedArguments\"\n        },\n        \"AppsAndFeaturesEntries\": {\n          \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\n        },\n        \"ElevationRequirement\": {\n          \"$ref\": \"#/definitions/ElevationRequirement\"\n        },\n        \"InstallationMetadata\": {\n          \"$ref\": \"#/definitions/InstallationMetadata\"\n        },\n        \"DownloadCommandProhibited\": {\n          \"$ref\": \"#/definitions/DownloadCommandProhibited\"\n        },\n        \"RepairBehavior\": {\n          \"$ref\": \"#/definitions/RepairBehavior\"\n        },\n        \"ArchiveBinariesDependOnPath\": {\n          \"$ref\": \"#/definitions/ArchiveBinariesDependOnPath\"\n        }\n      },\n      \"required\": [\n        \"Architecture\",\n        \"InstallerUrl\",\n        \"InstallerSha256\"\n      ]\n    }\n  },\n  \"type\": \"object\",\n  \"properties\": {\n    \"PackageIdentifier\": {\n      \"$ref\": \"#/definitions/PackageIdentifier\"\n    },\n    \"PackageVersion\": {\n      \"$ref\": \"#/definitions/PackageVersion\"\n    },\n    \"PackageLocale\": {\n      \"$ref\": \"#/definitions/Locale\"\n    },\n    \"Publisher\": {\n      \"type\": \"string\",\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The publisher name\"\n    },\n    \"PublisherUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher home page\"\n    },\n    \"PublisherSupportUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher support page\"\n    },\n    \"PrivacyUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The publisher privacy page or the package privacy page\"\n    },\n    \"Author\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The package author\"\n    },\n    \"PackageName\": {\n      \"type\": \"string\",\n      \"minLength\": 2,\n      \"maxLength\": 256,\n      \"description\": \"The package name\"\n    },\n    \"PackageUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package home page\"\n    },\n    \"License\": {\n      \"type\": \"string\",\n      \"minLength\": 3,\n      \"maxLength\": 512,\n      \"description\": \"The package license\"\n    },\n    \"LicenseUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The license page\"\n    },\n    \"Copyright\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 512,\n      \"description\": \"The package copyright\"\n    },\n    \"CopyrightUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package copyright page\"\n    },\n    \"ShortDescription\": {\n      \"type\": \"string\",\n      \"minLength\": 3,\n      \"maxLength\": 256,\n      \"description\": \"The short package description\"\n    },\n    \"Description\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 3,\n      \"maxLength\": 10000,\n      \"description\": \"The full package description\"\n    },\n    \"Moniker\": {\n      \"$ref\": \"#/definitions/Tag\",\n      \"description\": \"The most common package term\"\n    },\n    \"Tags\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Tag\"\n      },\n      \"maxItems\": 16,\n      \"uniqueItems\": true,\n      \"description\": \"List of additional package search terms\"\n    },\n    \"Agreements\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Agreement\"\n      },\n      \"maxItems\": 128\n    },\n    \"ReleaseNotes\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 10000,\n      \"description\": \"The package release notes\"\n    },\n    \"ReleaseNotesUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The package release notes url\"\n    },\n    \"PurchaseUrl\": {\n      \"$ref\": \"#/definitions/Url\",\n      \"description\": \"The purchase url for acquiring entitlement for the package.\"\n    },\n    \"InstallationNotes\": {\n      \"type\": [ \"string\", \"null\" ],\n      \"minLength\": 1,\n      \"maxLength\": 10000,\n      \"description\": \"The notes displayed to the user upon completion of a package installation.\"\n    },\n    \"Documentations\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Documentation\"\n      },\n      \"maxItems\": 256\n    },\n    \"Icons\": {\n      \"type\": [ \"array\", \"null\" ],\n      \"items\": {\n        \"$ref\": \"#/definitions/Icon\"\n      },\n      \"maxItems\": 1024\n    },\n    \"Channel\": {\n      \"$ref\": \"#/definitions/Channel\"\n    },\n    \"InstallerLocale\": {\n      \"$ref\": \"#/definitions/Locale\"\n    },\n    \"Platform\": {\n      \"$ref\": \"#/definitions/Platform\"\n    },\n    \"MinimumOSVersion\": {\n      \"$ref\": \"#/definitions/MinimumOSVersion\"\n    },\n    \"InstallerType\": {\n      \"$ref\": \"#/definitions/InstallerType\"\n    },\n    \"NestedInstallerType\": {\n      \"$ref\": \"#/definitions/NestedInstallerType\"\n    },\n    \"NestedInstallerFiles\": {\n      \"$ref\": \"#/definitions/NestedInstallerFiles\"\n    },\n    \"Scope\": {\n      \"$ref\": \"#/definitions/Scope\"\n    },\n    \"InstallModes\": {\n      \"$ref\": \"#/definitions/InstallModes\"\n    },\n    \"InstallerSwitches\": {\n      \"$ref\": \"#/definitions/InstallerSwitches\"\n    },\n    \"InstallerSuccessCodes\": {\n      \"$ref\": \"#/definitions/InstallerSuccessCodes\"\n    },\n    \"ExpectedReturnCodes\": {\n      \"$ref\": \"#/definitions/ExpectedReturnCodes\"\n    },\n    \"UpgradeBehavior\": {\n      \"$ref\": \"#/definitions/UpgradeBehavior\"\n    },\n    \"Commands\": {\n      \"$ref\": \"#/definitions/Commands\"\n    },\n    \"Protocols\": {\n      \"$ref\": \"#/definitions/Protocols\"\n    },\n    \"FileExtensions\": {\n      \"$ref\": \"#/definitions/FileExtensions\"\n    },\n    \"Dependencies\": {\n      \"$ref\": \"#/definitions/Dependencies\"\n    },\n    \"PackageFamilyName\": {\n      \"$ref\": \"#/definitions/PackageFamilyName\"\n    },\n    \"ProductCode\": {\n      \"$ref\": \"#/definitions/ProductCode\"\n    },\n    \"Capabilities\": {\n      \"$ref\": \"#/definitions/Capabilities\"\n    },\n    \"RestrictedCapabilities\": {\n      \"$ref\": \"#/definitions/RestrictedCapabilities\"\n    },\n    \"Markets\": {\n      \"$ref\": \"#/definitions/Markets\"\n    },\n    \"InstallerAbortsTerminal\": {\n      \"$ref\": \"#/definitions/InstallerAbortsTerminal\"\n    },\n    \"ReleaseDate\": {\n      \"$ref\": \"#/definitions/ReleaseDate\"\n    },\n    \"InstallLocationRequired\": {\n      \"$ref\": \"#/definitions/InstallLocationRequired\"\n    },\n    \"RequireExplicitUpgrade\": {\n      \"$ref\": \"#/definitions/RequireExplicitUpgrade\"\n    },\n    \"DisplayInstallWarnings\": {\n      \"$ref\": \"#/definitions/DisplayInstallWarnings\"\n    },\n    \"UnsupportedOSArchitectures\": {\n      \"$ref\": \"#/definitions/UnsupportedOSArchitectures\"\n    },\n    \"UnsupportedArguments\": {\n      \"$ref\": \"#/definitions/UnsupportedArguments\"\n    },\n    \"AppsAndFeaturesEntries\": {\n      \"$ref\": \"#/definitions/AppsAndFeaturesEntries\"\n    },\n    \"ElevationRequirement\": {\n      \"$ref\": \"#/definitions/ElevationRequirement\"\n    },\n    \"InstallationMetadata\": {\n      \"$ref\": \"#/definitions/InstallationMetadata\"\n    },\n    \"DownloadCommandProhibited\": {\n      \"$ref\": \"#/definitions/DownloadCommandProhibited\"\n    },\n    \"RepairBehavior\": {\n      \"$ref\": \"#/definitions/RepairBehavior\"\n    },\n    \"ArchiveBinariesDependOnPath\": {\n      \"$ref\": \"#/definitions/ArchiveBinariesDependOnPath\"\n    },\n    \"Installers\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/Installer\"\n      },\n      \"minItems\": 1,\n      \"maxItems\": 1\n    },\n    \"ManifestType\": {\n      \"type\": \"string\",\n      \"default\": \"singleton\",\n      \"const\": \"singleton\",\n      \"description\": \"The manifest type\"\n    },\n    \"ManifestVersion\": {\n      \"type\": \"string\",\n      \"default\": \"1.9.0\",\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\n      \"description\": \"The manifest syntax version\"\n    }\n  },\n  \"required\": [\n    \"PackageIdentifier\",\n    \"PackageVersion\",\n    \"PackageLocale\",\n    \"Publisher\",\n    \"PackageName\",\n    \"License\",\n    \"ShortDescription\",\n    \"Installers\",\n    \"ManifestType\",\n    \"ManifestVersion\"\n  ]\n}\n"
  },
  {
    "path": "schemas/JSON/manifests/v1.9.0/manifest.version.1.9.0.json",
    "content": "{\n  \"$id\": \"https://aka.ms/winget-manifest.version.1.9.0.schema.json\",\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"description\": \"A representation of a multi-file manifest representing an app version in the OWC. v1.9.0\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"PackageIdentifier\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}(\\\\.[^\\\\.\\\\s\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]{1,32}){1,7}$\",\n      \"maxLength\": 128,\n      \"description\": \"The package unique identifier\"\n    },\n    \"PackageVersion\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^\\\\\\\\/:\\\\*\\\\?\\\"<>\\\\|\\\\x01-\\\\x1f]+$\",\n      \"maxLength\": 128,\n      \"description\": \"The package version\"\n    },\n    \"DefaultLocale\": {\n      \"type\": \"string\",\n      \"default\": \"en-US\",\n      \"pattern\": \"^([a-zA-Z]{2,3}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\n      \"maxLength\": 20,\n      \"description\": \"The default package meta-data locale\"\n    },\n    \"ManifestType\": {\n      \"type\": \"string\",\n      \"default\": \"version\",\n      \"const\": \"version\",\n      \"description\": \"The manifest type\"\n    },\n    \"ManifestVersion\": {\n      \"type\": \"string\",\n      \"default\": \"1.9.0\",\n      \"pattern\": \"^(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\\\\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){2}$\",\n      \"description\": \"The manifest syntax version\"\n    }\n  },\n  \"required\": [\n    \"PackageIdentifier\",\n    \"PackageVersion\",\n    \"DefaultLocale\",\n    \"ManifestType\",\n    \"ManifestVersion\"\n  ]\n}"
  },
  {
    "path": "schemas/JSON/settings/settings.export.schema.0.1.json",
    "content": "{\n  \"$id\": \"https://aka.ms/winget-settings-export.schema.json\",\n  \"$schema\": \"https://json-schema.org/draft/2019-09/schema#\",\n  \"title\": \"Microsoft's Windows Package Manager Settings Export Schema\",\n  \"definitions\": {\n    \"AdminSettings\": {\n      \"description\": \"Administrator settings\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"BypassCertificatePinningForMicrosoftStore\": {\n          \"description\": \"Bypass Certificate Pinning For Microsoft Store\",\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"LocalManifestFiles\": {\n          \"description\": \"Enable installing local manifests.\",\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"InstallerHashOverride\": {\n          \"description\": \"Enable overriding installer hash validation.\",\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"LocalArchiveMalwareScanOverride\": {\n          \"description\": \"Enable overriding malware scan for local archives.\",\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"ProxyCommandLineOptions\": {\n          \"description\": \"Enable using command line options for proxy.\",\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"DefaultProxy\": {\n          \"description\": \"Default proxy.\",\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"UserSettingsFile\": {\n      \"description\": \"Path for the winget's user settings file.\",\n      \"type\": \"string\",\n      \"maxLength\": 32767\n    }\n  },\n  \"allOf\": [\n    {\n      \"properties\": {\n        \"adminSettings\": { \"$ref\": \"#/definitions/AdminSettings\" }\n      },\n      \"additionalItems\": true\n    },\n    {\n      \"properties\": {\n        \"userSettingsFile\": { \"$ref\": \"#/definitions/UserSettingsFile\" }\n      },\n      \"additionalItems\": true\n    }\n  ],\n  \"additionalProperties\": true\n}\n"
  },
  {
    "path": "schemas/JSON/settings/settings.schema.0.2.json",
    "content": "{\n  \"$id\": \"https://aka.ms/winget-settings.schema.json\",\n  \"$schema\": \"https://json-schema.org/draft/2019-09/schema#\",\n  \"title\": \"Microsoft's Windows Package Manager Settings Profile Schema\",\n  \"definitions\": {\n    \"Source\": {\n      \"description\": \"Source repository settings\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"autoUpdateIntervalInMinutes\": {\n          \"description\": \"Number of minutes before source update\",\n          \"type\": \"integer\",\n          \"default\": 5,\n          \"minimum\": 0,\n          \"maximum\": 43200\n        }\n      }\n    },\n    \"Visual\": {\n      \"description\": \"Visual settings\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"progressBar\": {\n          \"description\": \"Progress bar display style\",\n          \"type\": \"string\",\n          \"enum\": [\n            \"accent\",\n            \"rainbow\",\n            \"retro\",\n            \"sixel\",\n            \"disabled\"\n          ]\n        },\n        \"anonymizeDisplayedPaths\": {\n          \"description\": \"Replaces some known folder paths with their respective environment variable\",\n          \"type\": \"boolean\",\n          \"default\": true\n        },\n        \"enableSixels\": {\n          \"description\": \"Enables output of sixel images in certain contexts\",\n          \"type\": \"boolean\",\n          \"default\": false\n        }\n      }\n    },\n    \"Logging\": {\n      \"description\": \"Logging settings\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"level\": {\n          \"description\": \"Preferred logging level\",\n          \"type\": \"string\",\n          \"enum\": [\n            \"verbose\",\n            \"info\",\n            \"warning\",\n            \"error\",\n            \"critical\"\n          ]\n        },\n        \"channels\": {\n          \"description\": \"The logging channels to enable\",\n          \"type\": \"array\",\n          \"items\": {\n            \"uniqueItems\": true,\n            \"type\": \"string\",\n            \"enum\": [\n              \"fail\",\n              \"cli\",\n              \"sql\",\n              \"repo\",\n              \"yaml\",\n              \"core\",\n              \"test\",\n              \"config\",\n              \"default\",\n              \"all\"\n            ],\n            \"maxLength\": 20\n          },\n          \"minItems\": 0,\n          \"maxItems\": 20\n        },\n        \"file\": {\n          \"description\": \"The file settings control the log files generated by winget during operation.\",\n          \"type\": \"object\",\n          \"properties\": {\n            \"ageLimitInDays\": {\n              \"description\": \"The maximum age, in days, of a log file before it is deleted. Set to 0 to disable automatic deletion based on age.\",\n              \"type\": \"integer\",\n              \"default\": 7,\n              \"minimum\": 0\n            },\n            \"totalSizeLimitInMB\": {\n              \"description\": \"The maximum total size, in megabytes, of all log files. If the total size exceeds this limit, the oldest files will be deleted first. Set to 0 to disable this limit.\",\n              \"type\": \"integer\",\n              \"default\": 128,\n              \"minimum\": 0\n            },\n            \"countLimit\": {\n              \"description\": \"The maximum number of log files to retain. If the number of log files exceeds this limit, the oldest files will be deleted first. Set to 0 (the default) to disable this limit.\",\n              \"type\": \"integer\",\n              \"default\": 0,\n              \"minimum\": 0\n            },\n            \"individualSizeLimitInMB\": {\n              \"description\": \"The maximum size, in megabytes, of an individual log file. If a file would exceed this limit, new log lines will overwrite the file from the beginning. Set to 0 to disable this limit.\",\n              \"type\": \"integer\",\n              \"default\": 16,\n              \"minimum\": 0\n            }\n          }\n        }\n      }\n    },\n    \"InstallPrefReq\": {\n      \"description\": \"Shared schema for preferences and requirements\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"scope\": {\n          \"description\": \"The scope of a package install\",\n          \"type\": \"string\",\n          \"enum\": [\n            \"user\",\n            \"machine\"\n          ],\n          \"default\": \"user\"\n        },\n        \"locale\": {\n          \"description\": \"The locales of a package install\",\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\",\n            \"pattern\": \"^([a-zA-Z]{2}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*$\",\n            \"maxLength\": 20\n          },\n          \"minItems\": 1,\n          \"maxItems\": 10\n        },\n        \"architectures\": {\n          \"description\": \"The architecture(s) to use for a package install\",\n          \"type\": \"array\",\n          \"items\": {\n            \"uniqueItems\": true,\n            \"type\": \"string\",\n            \"enum\": [\n              \"neutral\",\n              \"x64\",\n              \"x86\",\n              \"arm64\",\n              \"arm\"\n            ],\n            \"minItems\": 1,\n            \"maxItems\": 4\n          }\n        },\n        \"installerTypes\": {\n          \"description\": \"The installerType(s) to use for a package install\",\n          \"type\": \"array\",\n          \"items\": {\n            \"uniqueItems\": true,\n            \"type\": \"string\",\n            \"enum\": [\n              \"inno\",\n              \"wix\",\n              \"msi\",\n              \"nullsoft\",\n              \"zip\",\n              \"msix\",\n              \"exe\",\n              \"burn\",\n              \"msstore\",\n              \"portable\"\n            ],\n            \"minItems\": 1,\n            \"maxItems\": 9\n          }\n        }\n      }\n    },\n    \"InstallBehavior\": {\n      \"description\": \"Install settings\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"preferences\": { \"$ref\": \"#/definitions/InstallPrefReq\" },\n        \"requirements\": { \"$ref\": \"#/definitions/InstallPrefReq\" },\n        \"skipDependencies\": {\n          \"description\": \"Controls whether package dependencies and Windows Features are skipped during installation\",\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"disableInstallNotes\": {\n          \"description\": \"Controls whether installation notes are shown after a successful install\",\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"portablePackageUserRoot\": {\n          \"description\": \"The default root directory where packages are installed to under User scope. Applies to the portable installer type.\",\n          \"type\": \"string\",\n          \"default\": \"%LOCALAPPDATA%/Microsoft/WinGet/Packages/\"\n        },\n        \"portablePackageMachineRoot\": {\n          \"description\": \"The default root directory where packages are installed to under Machine scope. Applies to the portable installer type.\",\n          \"type\": \"string\",\n          \"default\": \"%PROGRAMFILES%/WinGet/Packages/\"\n        },\n        \"defaultInstallRoot\": {\n          \"description\": \"Default install location to use for packages that require it when not specified\",\n          \"type\": \"string\",\n          \"maxLength\": 32767\n        },\n        \"maxResumes\": {\n          \"description\": \"The maximum number of resumes allowed for a single resume id. This is to prevent continuous reboots if an install that requires a reboot is not properly detected.\",\n          \"type\": \"integer\",\n          \"default\": 3,\n          \"minimum\": 1\n        },\n        \"archiveExtractionMethod\": {\n          \"description\": \"Controls the behavior how the installer extracts archives. The current two supported values are 'shellApi' and 'tar'. 'shellApi' uses the Windows Shell API to extract archives. 'tar' uses the tar command to extract archives.\",\n          \"type\": \"string\",\n          \"enum\": [\n            \"shellApi\",\n            \"tar\"\n          ],\n          \"default\": \"shellApi\"\n        }\n      }\n    },\n    \"UninstallBehavior\": {\n      \"description\": \"Uninstall settings\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"purgePortablePackage\": {\n          \"description\": \"Controls whether the default behavior for uninstall removes all files and directories relevant to this package. Only applies to the portable installerType.\",\n          \"type\": \"boolean\",\n          \"default\": false\n        }\n      }\n    },\n    \"ConfigureBehavior\": {\n      \"description\": \"Configure settings\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"defaultModuleRoot\": {\n          \"description\": \"The default root directory where PowerShell modules are installed to when applying a configuration.\",\n          \"type\": \"string\",\n          \"maxLength\": 32767,\n          \"default\": \"%LOCALAPPDATA%/Microsoft/WinGet/Configuration/Modules/\"\n        }\n      }\n    },\n    \"DownloadBehavior\": {\n      \"description\": \"Download settings\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"defaultDownloadDirectory\": {\n          \"description\": \"The default directory where installers are downloaded to.\",\n          \"type\": \"string\",\n          \"default\": \"%USERPROFILE%/Downloads/\"\n        }\n      }\n    },\n    \"Telemetry\": {\n      \"description\": \"Telemetry settings\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"disable\": {\n          \"description\": \"Controls whether telemetry events are written\",\n          \"type\": \"boolean\",\n          \"default\": false\n        }\n      }\n    },\n    \"Network\": {\n      \"description\": \"Network settings\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"downloader\": {\n          \"description\": \"Control which download code is used for packages\",\n          \"type\": \"string\",\n          \"enum\": [\n            \"default\",\n            \"wininet\",\n            \"do\"\n          ],\n          \"default\": \"default\"\n        },\n        \"doProgressTimeoutInSeconds\": {\n          \"description\": \"Number of seconds to wait without progress before fallback\",\n          \"type\": \"integer\",\n          \"default\": 60,\n          \"minimum\": 1,\n          \"maximum\": 600\n        }\n      }\n    },\n    \"Interactivity\": {\n      \"description\": \"Interactivity settings\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"disable\": {\n          \"description\": \"Controls whether interactive prompts are shown by the Windows Package Manager client\",\n          \"type\": \"boolean\",\n          \"default\": false\n        }\n      }\n    },\n    \"Experimental\": {\n      \"description\": \"Experimental Features\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"experimentalCMD\": {\n          \"description\": \"Reference implementation for an experimental command\",\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"experimentalARG\": {\n          \"description\": \"Reference implementation for an experimental argument\",\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"directMSI\": {\n          \"description\": \"Enable use of MSI APIs rather than msiexec for MSI installs\",\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"fonts\": {\n          \"description\": \"Enable support for managing fonts\",\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"sourcePriority\": {\n          \"description\": \"Enable source priority feature\",\n          \"type\": \"boolean\",\n          \"default\": false\n        }\n      }\n    }\n  },\n  \"allOf\": [\n    {\n      \"properties\": {\n        \"source\": { \"$ref\": \"#/definitions/Source\" }\n      },\n      \"additionalItems\": true\n    },\n    {\n      \"properties\": {\n        \"visual\": { \"$ref\": \"#/definitions/Visual\" }\n      },\n      \"additionalItems\": true\n    },\n    {\n      \"properties\": {\n        \"logging\": { \"$ref\": \"#/definitions/Logging\" }\n      },\n      \"additionalItems\": true\n    },\n    {\n      \"properties\": {\n        \"installPrefReq\": { \"$ref\": \"#/definitions/InstallPrefReq\" }\n      },\n      \"additionalItems\": true\n    },\n    {\n      \"properties\": {\n        \"installBehavior\": { \"$ref\": \"#/definitions/InstallBehavior\" }\n      },\n      \"additionalItems\": true\n    },\n    {\n      \"properties\": {\n        \"uninstallBehavior\": { \"$ref\": \"#/definitions/UninstallBehavior\" }\n      },\n      \"additionalItems\": true\n    },\n    {\n      \"properties\": {\n        \"configureBehavior\": { \"$ref\": \"#/definitions/ConfigureBehavior\" }\n      },\n      \"additionalItems\": true\n    },\n    {\n      \"properties\": {\n        \"downloadBehavior\": { \"$ref\": \"#/definitions/DownloadBehavior\" }\n      },\n      \"additionalItems\": true\n    },\n    {\n      \"properties\": {\n        \"telemetry\": { \"$ref\": \"#/definitions/Telemetry\" }\n      },\n      \"additionalItems\": true\n    },\n    {\n      \"properties\": {\n        \"network\": { \"$ref\": \"#/definitions/Network\" }\n      },\n      \"additionalItems\": true\n    },\n    {\n      \"properties\": {\n        \"interactivity\": { \"$ref\": \"#/definitions/Interactivity\" }\n      },\n      \"additionalItems\": true\n    },\n    {\n      \"properties\": {\n        \"experimentalFeatures\": { \"$ref\": \"#/definitions/Experimental\" }\n      },\n      \"additionalItems\": true\n    }\n  ],\n  \"additionalProperties\": true\n}\n"
  },
  {
    "path": "src/AppInstallerCLI/AppInstallerCLI.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" />\r\n  <PropertyGroup Label=\"Globals\">\r\n    <CppWinRTOptimized>true</CppWinRTOptimized>\r\n    <CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>\r\n    <MinimalCoreWin>true</MinimalCoreWin>\r\n    <VCProjectVersion>15.0</VCProjectVersion>\r\n    <ProjectGuid>{5b6f90df-fd19-4bae-83d9-24dad128e777}</ProjectGuid>\r\n    <Keyword>Win32Proj</Keyword>\r\n    <RootNamespace>AppInstallerCLI</RootNamespace>\r\n    <WindowsTargetPlatformVersion>10.0.26100.0</WindowsTargetPlatformVersion>\r\n    <WindowsTargetPlatformMinVersion>10.0.17763.0</WindowsTargetPlatformMinVersion>\r\n    <WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|ARM64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|Win32\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|ARM64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|Win32\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <PropertyGroup Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Debug'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n    <LinkIncremental>true</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Release'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <LinkIncremental>false</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\r\n  <ImportGroup Label=\"ExtensionSettings\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"Shared\">\r\n    <Import Project=\"..\\binver\\binver.vcxitems\" Label=\"Shared\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"PropertySheet.props\" />\r\n  </ImportGroup>\r\n  <PropertyGroup Label=\"UserMacros\" />\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>true</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n    <TargetName>winget</TargetName>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>true</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n    <TargetName>winget</TargetName>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>true</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n    <TargetName>winget</TargetName>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n    <TargetName>winget</TargetName>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n    <TargetName>winget</TargetName>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n    <TargetName>winget</TargetName>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(ProjectDir)\\..\\vcpkg.props\" />\r\n  <ItemDefinitionGroup>\r\n    <ClCompile>\r\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>\r\n      <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>\r\n      <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <AdditionalOptions>%(AdditionalOptions) /permissive- /bigobj</AdditionalOptions>\r\n    </ClCompile>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Debug'\">\r\n    <ClCompile>\r\n      <Optimization>Disabled</Optimization>\r\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">$(ProjectDir);$(ProjectDir)..\\WindowsPackageManager\\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">$(ProjectDir);$(ProjectDir)..\\WindowsPackageManager\\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</TreatWarningAsError>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">false</ControlFlowGuard>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</ControlFlowGuard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">stdcpp17</LanguageStandard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">stdcpp17</LanguageStandard>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</EnablePREfast>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <AdditionalDependencies Condition=\"'$(Configuration)'=='Debug'\">%(AdditionalDependencies)</AdditionalDependencies>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</CETCompat>\r\n    </Link>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Platform)'=='Win32'\">\r\n    <ClCompile>\r\n      <PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">$(ProjectDir);$(ProjectDir)..\\WindowsPackageManager\\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</TreatWarningAsError>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</ControlFlowGuard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">stdcpp17</LanguageStandard>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</EnablePREfast>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Link>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</CETCompat>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Release'\">\r\n    <ClCompile>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">$(ProjectDir);$(ProjectDir)..\\WindowsPackageManager\\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">$(ProjectDir);$(ProjectDir)..\\WindowsPackageManager\\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">$(ProjectDir);$(ProjectDir)..\\WindowsPackageManager\\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">true</TreatWarningAsError>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">Guard</ControlFlowGuard>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Guard</ControlFlowGuard>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Guard</ControlFlowGuard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">stdcpp17</LanguageStandard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">stdcpp17</LanguageStandard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">stdcpp17</LanguageStandard>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</EnablePREfast>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <AdditionalDependencies Condition=\"'$(Configuration)'=='Release'\">%(AdditionalDependencies)</AdditionalDependencies>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">/debug:full /debugtype:cv,fixup /incremental:no %(AdditionalOptions)</AdditionalOptions>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">/debug:full /debugtype:cv,fixup /incremental:no %(AdditionalOptions)</AdditionalOptions>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">/debug:full /debugtype:cv,fixup /incremental:no %(AdditionalOptions)</AdditionalOptions>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</CETCompat>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">true</CETCompat>\r\n    </Link>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n  </ItemDefinitionGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"main.cpp\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"packages.config\" />\r\n    <None Include=\"PropertySheet.props\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\WindowsPackageManager\\WindowsPackageManager.vcxproj\">\r\n      <Project>{2046b5af-666d-4ce8-8d3e-c32c57908a56}</Project>\r\n    </ProjectReference>\r\n  </ItemGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\r\n  <ImportGroup Label=\"ExtensionTargets\">\r\n    <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" />\r\n  </ImportGroup>\r\n  <Target Name=\"EnsureNuGetPackageBuildImports\" BeforeTargets=\"PrepareForBuild\">\r\n    <PropertyGroup>\r\n      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>\r\n    </PropertyGroup>\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props'))\" />\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets'))\" />\r\n  </Target>\r\n</Project>\r\n"
  },
  {
    "path": "src/AppInstallerCLI/AppInstallerCLI.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup>\r\n    <Filter Include=\"Source Files\">\r\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Header Files\">\r\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r\n      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Resource Files\">\r\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\r\n    </Filter>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"main.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"PropertySheet.props\" />\r\n    <None Include=\"packages.config\" />\r\n  </ItemGroup>\r\n</Project>"
  },
  {
    "path": "src/AppInstallerCLI/PropertySheet.props",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ImportGroup Label=\"PropertySheets\" />\n  <PropertyGroup Label=\"UserMacros\" />\n    <!--\n    To customize common C++/WinRT project properties: \n    * right-click the project node\n    * expand the Common Properties item\n    * select the C++/WinRT property page\n\n    For more advanced scenarios, and complete documentation, please see:\n    https://github.com/Microsoft/xlang/tree/master/src/package/cppwinrt/nuget \n    -->\n  <PropertyGroup />\n  <ItemDefinitionGroup />\n</Project>"
  },
  {
    "path": "src/AppInstallerCLI/main.cpp",
    "content": "﻿// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#define WIN32_LEAN_AND_MEAN\n#include <Windows.h>\n#include <WindowsPackageManager.h>\n\nint wmain(int argc, wchar_t const** argv)\n{\n    return WindowsPackageManagerCLIMain(argc, argv);\n}\n"
  },
  {
    "path": "src/AppInstallerCLI/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<packages>\r\n  <package id=\"Microsoft.Windows.CppWinRT\" version=\"2.0.250303.1\" targetFramework=\"native\" />\r\n</packages>"
  },
  {
    "path": "src/AppInstallerCLI.sln",
    "content": "﻿\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio Version 17\r\nVisualStudioVersion = 17.14.36915.13 d17.14\r\nMinimumVisualStudioVersion = 10.0.40219.1\r\nProject(\"{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}\") = \"AppInstallerCLIPackage\", \"AppInstallerCLIPackage\\AppInstallerCLIPackage.wapproj\", \"{6AA3791A-0713-4548-A357-87A323E7AC3A}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\t\t{0BA531C8-CF0C-405B-8221-0FE51BA529D1} = {0BA531C8-CF0C-405B-8221-0FE51BA529D1}\r\n\t\t{1CC41A9A-AE66-459D-9210-1E572DD7BE69} = {1CC41A9A-AE66-459D-9210-1E572DD7BE69}\r\n\t\t{2B00D362-AC92-41F3-A8D2-5B1599BDCA01} = {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}\r\n\t\t{33745E4A-39E2-676F-7E23-50FB43848D25} = {33745E4A-39E2-676F-7E23-50FB43848D25}\r\n\t\t{5B6F90DF-FD19-4BAE-83D9-24DAD128E777} = {5B6F90DF-FD19-4BAE-83D9-24DAD128E777}\r\n\t\t{6597EB04-D105-49A7-A5A3-D27FE1DF895E} = {6597EB04-D105-49A7-A5A3-D27FE1DF895E}\r\n\t\t{CA460806-5E41-4E97-9A3D-1D74B433B663} = {CA460806-5E41-4E97-9A3D-1D74B433B663}\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"AppInstallerCLI\", \"AppInstallerCLI\\AppInstallerCLI.vcxproj\", \"{5B6F90DF-FD19-4BAE-83D9-24DAD128E777}\"\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"AppInstallerCLICore\", \"AppInstallerCLICore\\AppInstallerCLICore.vcxproj\", \"{1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\t\t{71FA29AA-9035-468B-A11D-0F0B0F5D5AF4} = {71FA29AA-9035-468B-A11D-0F0B0F5D5AF4}\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"AppInstallerCLITests\", \"AppInstallerCLITests\\AppInstallerCLITests.vcxproj\", \"{89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\t\t{6AA3791A-0713-4548-A357-87A323E7AC3A} = {6AA3791A-0713-4548-A357-87A323E7AC3A}\r\n\t\t{6CB84692-5994-407D-B9BD-9216AF77FE83} = {6CB84692-5994-407D-B9BD-9216AF77FE83}\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"External - Do Not Modify\", \"External - Do Not Modify\", \"{60618CAC-2995-4DF9-9914-45C6FC02C995}\"\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"AppInstallerRepositoryCore\", \"AppInstallerRepositoryCore\\AppInstallerRepositoryCore.vcxproj\", \"{5EB88068-5FB9-4E69-89B2-72DBC5E068F9}\"\r\nEndProject\r\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Project\", \"Project\", \"{8D53D749-D51C-46F8-A162-9371AAA6C2E7}\"\r\n\tProjectSection(SolutionItems) = preProject\r\n\t\t..\\azure-pipelines.loc.yml = ..\\azure-pipelines.loc.yml\r\n\t\t..\\azure-pipelines.nuget.yml = ..\\azure-pipelines.nuget.yml\r\n\t\t..\\azure-pipelines.yml = ..\\azure-pipelines.yml\r\n\t\t..\\cgmanifest.json = ..\\cgmanifest.json\r\n\t\tGet-VcxprojNugetPackageVersions.ps1 = Get-VcxprojNugetPackageVersions.ps1\r\n\t\t..\\README.md = ..\\README.md\r\n\t\t..\\doc\\ReleaseNotes.md = ..\\doc\\ReleaseNotes.md\r\n\t\t..\\doc\\Settings.md = ..\\doc\\Settings.md\r\n\t\tUpdate-VcxprojNugetPackageVersions.ps1 = Update-VcxprojNugetPackageVersions.ps1\r\n\t\t..\\WinGetInProcCom.nuspec = ..\\WinGetInProcCom.nuspec\r\n\t\t..\\WinGetUtil.nuspec = ..\\WinGetUtil.nuspec\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"AppInstallerCommonCore\", \"AppInstallerCommonCore\\AppInstallerCommonCore.vcxproj\", \"{5890D6ED-7C3B-40F3-B436-B54F640D9E65}\"\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"WinGetUtil\", \"WinGetUtil\\WinGetUtil.vcxproj\", \"{FB313532-38B0-4676-9303-AB200AA13576}\"\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"AppInstallerTestExeInstaller\", \"AppInstallerTestExeInstaller\\AppInstallerTestExeInstaller.vcxproj\", \"{6CB84692-5994-407D-B9BD-9216AF77FE83}\"\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"binver\", \"binver\\binver.vcxitems\", \"{6E36DDD7-1602-474E-B1D7-D0A7E1D5AD86}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"AppInstallerCLIE2ETests\", \"AppInstallerCLIE2ETests\\AppInstallerCLIE2ETests.csproj\", \"{3C0269FA-E582-4CA7-9E33-3881A005CA0C}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA} = {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}\r\n\t\t{6CB84692-5994-407D-B9BD-9216AF77FE83} = {6CB84692-5994-407D-B9BD-9216AF77FE83}\r\n\t\t{C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8} = {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}\") = \"AppInstallerTestMsixInstaller\", \"AppInstallerTestMsixInstaller\\AppInstallerTestMsixInstaller.wapproj\", \"{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}\"\r\nEndProject\r\nProject(\"{54435603-DBB4-11D2-8724-00A0C9A8B90C}\") = \"AppInstallerTestMsiInstaller\", \"AppInstallerTestMsiInstaller\\AppInstallerTestMsiInstaller.vdproj\", \"{C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}\"\r\nEndProject\r\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Tool\", \"Tool\", \"{EA8CD934-0702-4911-A2C5-A40600E616DE}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IndexCreationTool\", \"IndexCreationTool\\IndexCreationTool.csproj\", \"{3B8466CF-4FDD-4329-9C80-91321C4AAC99}\"\r\nEndProject\r\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Fuzzing\", \"Fuzzing\", \"{6D7776A8-42FE-46DD-B0F8-712F35EA0C79}\"\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"WinGetYamlFuzzing\", \"WinGetYamlFuzzing\\WinGetYamlFuzzing.vcxproj\", \"{1622DA16-914F-4F57-A259-D5169003CC8C}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"LocalhostWebServer\", \"LocalhostWebServer\\LocalhostWebServer.csproj\", \"{3BAF989F-7F65-465B-ACE8-BAFE42D1017E}\"\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"ManifestSchema\", \"ManifestSchema\\ManifestSchema.vcxitems\", \"{7D05F64D-CE5A-42AA-A2C1-E91458F061CF}\"\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"WinGetSchemas\", \"WinGetSchemas\\WinGetSchemas.vcxitems\", \"{952B513F-8A00-4D74-9271-925AFB3C6252}\"\r\nEndProject\r\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"spelling\", \"spelling\", \"{2ACDE176-F13F-42FA-8159-C34FA3D37837}\"\r\n\tProjectSection(SolutionItems) = preProject\r\n\t\t..\\.github\\actions\\spelling\\allow.txt = ..\\.github\\actions\\spelling\\allow.txt\r\n\t\t..\\.github\\actions\\spelling\\excludes.txt = ..\\.github\\actions\\spelling\\excludes.txt\r\n\t\t..\\.github\\actions\\spelling\\expect.txt = ..\\.github\\actions\\spelling\\expect.txt\r\n\t\t..\\.github\\actions\\spelling\\patterns.txt = ..\\.github\\actions\\spelling\\patterns.txt\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"policy\", \"policy\", \"{1A47951F-5C7A-4D6D-BB5F-D77484437940}\"\r\n\tProjectSection(SolutionItems) = preProject\r\n\t\t..\\doc\\admx\\en-US\\DesktopAppInstaller.adml = ..\\doc\\admx\\en-US\\DesktopAppInstaller.adml\r\n\t\t..\\doc\\admx\\DesktopAppInstaller.admx = ..\\doc\\admx\\DesktopAppInstaller.admx\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Solution Items\", \"Solution Items\", \"{1A5D7A7D-5CB2-47D5-B40D-4E61CAEDC798}\"\r\n\tProjectSection(SolutionItems) = preProject\r\n\t\tCodeAnalysis.ruleset = CodeAnalysis.ruleset\r\n\t\tDirectory.Build.props = Directory.Build.props\r\n\t\tDirectory.Packages.props = Directory.Packages.props\r\n\t\tDirectory.Solution.props = Directory.Solution.props\r\n\t\tnuget.config = nuget.config\r\n\t\tstylecop.json = stylecop.json\r\n\t\tvcpkg.json = vcpkg.json\r\n\t\tvcpkg.props = vcpkg.props\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"Microsoft.Management.Deployment\", \"Microsoft.Management.Deployment\\Microsoft.Management.Deployment.vcxproj\", \"{1CC41A9A-AE66-459D-9210-1E572DD7BE69}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\t\t{1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D} = {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}\r\n\t\t{5890D6ED-7C3B-40F3-B436-B54F640D9E65} = {5890D6ED-7C3B-40F3-B436-B54F640D9E65}\r\n\t\t{5EB88068-5FB9-4E69-89B2-72DBC5E068F9} = {5EB88068-5FB9-4E69-89B2-72DBC5E068F9}\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"WinGetServer\", \"WinGetServer\\WinGetServer.vcxproj\", \"{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\t\t{1CC41A9A-AE66-459D-9210-1E572DD7BE69} = {1CC41A9A-AE66-459D-9210-1E572DD7BE69}\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"WinGetUtilInterop\", \"WinGetUtilInterop\\WinGetUtilInterop.csproj\", \"{846FB88B-BF1B-4F33-9883-E589CEC99739}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"WinGetUtilInterop.UnitTests\", \"WinGetUtilInterop.UnitTests\\WinGetUtilInterop.UnitTests.csproj\", \"{68808357-902B-406C-8C19-E8E26A69DE8A}\"\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"WindowsPackageManager\", \"WindowsPackageManager\\WindowsPackageManager.vcxproj\", \"{2046B5AF-666D-4CE8-8D3E-C32C57908A56}\"\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"COMServer\", \"COMServer\\COMServer.vcxitems\", \"{409CD681-22A4-469D-88AE-CB5E4836E07A}\"\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"Microsoft.Management.Deployment.InProc\", \"Microsoft.Management.Deployment.InProc\\Microsoft.Management.Deployment.InProc.vcxproj\", \"{9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}\"\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"CertificateResources\", \"CertificateResources\\CertificateResources.vcxitems\", \"{B0BBBD92-943B-408F-B2B2-DBBAB4A22D23}\"\r\nEndProject\r\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"PowerShell\", \"PowerShell\", \"{7C218A3E-9BC8-48FF-B91B-BCACD828C0C9}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Microsoft.WinGet.Client.Cmdlets\", \"PowerShell\\Microsoft.WinGet.Client.Cmdlets\\Microsoft.WinGet.Client.Cmdlets.csproj\", \"{463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Microsoft.Management.Deployment.Projection\", \"Microsoft.Management.Deployment.Projection\\Microsoft.Management.Deployment.Projection.csproj\", \"{0B104762-5CD8-47EE-A904-71C1C3F84DCD}\"\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"UndockedRegFreeWinRT\", \"Xlang\\UndockedRegFreeWinRT\\src\\UndockedRegFreeWinRT\\UndockedRegFreeWinRT\\UndockedRegFreeWinRT.vcxproj\", \"{31ED69A8-5310-45A9-953F-56C351D2C3E1}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\t\t{2B00D362-AC92-41F3-A8D2-5B1599BDCA01} = {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"templates\", \"templates\", \"{8E43F982-40D5-4DF1-9044-C08047B5F43B}\"\r\n\tProjectSection(SolutionItems) = preProject\r\n\t\t..\\templates\\e2e-setup.yml = ..\\templates\\e2e-setup.yml\r\n\t\t..\\templates\\e2e-test.template.yml = ..\\templates\\e2e-test.template.yml\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"AppInstallerSharedLib\", \"AppInstallerSharedLib\\AppInstallerSharedLib.vcxproj\", \"{F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}\"\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"Microsoft.Management.Configuration\", \"Microsoft.Management.Configuration\\Microsoft.Management.Configuration.vcxproj\", \"{CA460806-5E41-4E97-9A3D-1D74B433B663}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Microsoft.Management.Configuration.Projection\", \"Microsoft.Management.Configuration.Projection\\Microsoft.Management.Configuration.Projection.csproj\", \"{E8454BF1-2068-4513-A525-ABF55CC8742C}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Microsoft.Management.Configuration.UnitTests\", \"Microsoft.Management.Configuration.UnitTests\\Microsoft.Management.Configuration.UnitTests.csproj\", \"{EE43C990-7789-4A60-B077-BF0ED3D093A1}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Microsoft.Management.Configuration.Processor\", \"Microsoft.Management.Configuration.Processor\\Microsoft.Management.Configuration.Processor.csproj\", \"{71FA29AA-9035-468B-A11D-0F0B0F5D5AF4}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ConfigurationRemotingServer\", \"ConfigurationRemotingServer\\ConfigurationRemotingServer.csproj\", \"{6597EB04-D105-49A7-A5A3-D27FE1DF895E}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Microsoft.WinGet.Client.Engine\", \"PowerShell\\Microsoft.WinGet.Client.Engine\\Microsoft.WinGet.Client.Engine.csproj\", \"{1F56BECB-D65D-4BBA-8788-6671B251392A}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Microsoft.WinGet.Configuration.Cmdlets\", \"PowerShell\\Microsoft.WinGet.Configuration.Cmdlets\\Microsoft.WinGet.Configuration.Cmdlets.csproj\", \"{167F634B-A3AD-494E-8E67-B888103E35FF}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Microsoft.WinGet.Configuration.Engine\", \"PowerShell\\Microsoft.WinGet.Configuration.Engine\\Microsoft.WinGet.Configuration.Engine.csproj\", \"{C54F80ED-B736-49B0-9BD3-662F57024D01}\"\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"Microsoft.Management.Configuration.OutOfProc\", \"Microsoft.Management.Configuration.OutOfProc\\Microsoft.Management.Configuration.OutOfProc.vcxproj\", \"{2268D5AD-7F2A-485A-8C4B-C574497514C9}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\t\t{2B00D362-AC92-41F3-A8D2-5B1599BDCA01} = {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"WinGetSourceCreator\", \"WinGetSourceCreator\\WinGetSourceCreator.csproj\", \"{52EC37D6-088C-40D3-AD0B-BDE8F8DAF9EB}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Microsoft.WinGet.SharedLib\", \"PowerShell\\Microsoft.WinGet.SharedLib\\Microsoft.WinGet.SharedLib.csproj\", \"{272B2B0E-40D4-4F0F-B187-519A6EF89B10}\"\r\nEndProject\r\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Tests\", \"Tests\", \"{5A52D9FC-0059-4A4A-8196-427A7AA0D1C5}\"\r\n\tProjectSection(SolutionItems) = preProject\r\n\t\tPowerShell\\tests\\Microsoft.WinGet.Client.Tests.ps1 = PowerShell\\tests\\Microsoft.WinGet.Client.Tests.ps1\r\n\t\tPowerShell\\tests\\Microsoft.WinGet.Configuration.Tests.ps1 = PowerShell\\tests\\Microsoft.WinGet.Configuration.Tests.ps1\r\n\t\tPowerShell\\tests\\Microsoft.WinGet.DSC.Tests.ps1 = PowerShell\\tests\\Microsoft.WinGet.DSC.Tests.ps1\r\n\t\tPowerShell\\tests\\RunTests.ps1 = PowerShell\\tests\\RunTests.ps1\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"SfsClient\", \"SfsClient\\SfsClient.vcxproj\", \"{1B9077B3-8923-4ECD-8FC9-B3190FCBE4D4}\"\r\nEndProject\r\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"VcpkgCustomTriplets\", \"VcpkgCustomTriplets\", \"{76B26B2C-602A-4AD0-9736-4162D3FCA92A}\"\r\n\tProjectSection(SolutionItems) = preProject\r\n\t\tVcpkgCustomTriplets\\arm64-release-static.cmake = VcpkgCustomTriplets\\arm64-release-static.cmake\r\n\t\tVcpkgCustomTriplets\\arm64-release.cmake = VcpkgCustomTriplets\\arm64-release.cmake\r\n\t\tVcpkgCustomTriplets\\arm64.cmake = VcpkgCustomTriplets\\arm64.cmake\r\n\t\tVcpkgCustomTriplets\\common.cmake = VcpkgCustomTriplets\\common.cmake\r\n\t\tVcpkgCustomTriplets\\fuzzing.cmake = VcpkgCustomTriplets\\fuzzing.cmake\r\n\t\tVcpkgCustomTriplets\\x64-fuzzing.cmake = VcpkgCustomTriplets\\x64-fuzzing.cmake\r\n\t\tVcpkgCustomTriplets\\x64-release-static.cmake = VcpkgCustomTriplets\\x64-release-static.cmake\r\n\t\tVcpkgCustomTriplets\\x64-release.cmake = VcpkgCustomTriplets\\x64-release.cmake\r\n\t\tVcpkgCustomTriplets\\x64.cmake = VcpkgCustomTriplets\\x64.cmake\r\n\t\tVcpkgCustomTriplets\\x86-fuzzing.cmake = VcpkgCustomTriplets\\x86-fuzzing.cmake\r\n\t\tVcpkgCustomTriplets\\x86-release-static.cmake = VcpkgCustomTriplets\\x86-release-static.cmake\r\n\t\tVcpkgCustomTriplets\\x86-release.cmake = VcpkgCustomTriplets\\x86-release.cmake\r\n\t\tVcpkgCustomTriplets\\x86.cmake = VcpkgCustomTriplets\\x86.cmake\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"Microsoft.Management.Deployment.OutOfProc\", \"Microsoft.Management.Deployment.OutOfProc\\Microsoft.Management.Deployment.OutOfProc.vcxproj\", \"{0BA531C8-CF0C-405B-8221-0FE51BA529D1}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\t\t{2B00D362-AC92-41F3-A8D2-5B1599BDCA01} = {2B00D362-AC92-41F3-A8D2-5B1599BDCA01}\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Microsoft.Management.Deployment.CsWinRTProjection\", \"Microsoft.Management.Deployment.CsWinRTProjection\\Microsoft.Management.Deployment.CsWinRTProjection.csproj\", \"{9406322E-6272-487E-902A-9953889719EA}\"\r\nEndProject\r\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"targets\", \"targets\", \"{A0B4F808-B190-41C4-97CB-C8EA1932F84F}\"\r\n\tProjectSection(SolutionItems) = preProject\r\n\t\ttargets\\EmbeddedCsWinRT.targets = targets\\EmbeddedCsWinRT.targets\r\n\t\ttargets\\ReferenceEmbeddedCsWinRTProject.targets = targets\\ReferenceEmbeddedCsWinRTProject.targets\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"PureLib\", \"PureLib\\PureLib.vcxitems\", \"{A33223D2-550B-4D99-A53D-488B1F68683E}\"\r\nEndProject\r\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"WinGetTestCommon\", \"WinGetTestCommon\\WinGetTestCommon.csproj\", \"{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}\"\r\nEndProject\r\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Tests\", \"Tests\", \"{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}\"\r\nEndProject\r\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"WinGetMCPServer\", \"WinGetMCPServer\\WinGetMCPServer.csproj\", \"{33745E4A-39E2-676F-7E23-50FB43848D25}\"\r\nEndProject\r\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Scripts\", \"Scripts\", \"{F49C4C89-447E-4D15-B38B-5A8DCFB134AF}\"\r\n\tProjectSection(SolutionItems) = preProject\r\n\t\tPowerShell\\scripts\\Execute-WinGetTests.ps1 = PowerShell\\scripts\\Execute-WinGetTests.ps1\r\n\t\tPowerShell\\scripts\\Initialize-LocalWinGetModules.ps1 = PowerShell\\scripts\\Initialize-LocalWinGetModules.ps1\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"ComInprocTestbed\", \"ComInprocTestbed\\ComInprocTestbed.vcxproj\", \"{E5BCFF58-7D0C-4770-ABB9-AECE1027CD94}\"\r\nEndProject\r\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"DSC\", \"DSC\", \"{40D7CA7F-EB86-4345-9641-AD27180C559D}\"\r\n\tProjectSection(SolutionItems) = preProject\r\n\t\tPowerShell\\Microsoft.WinGet.DSC\\Microsoft.WinGet.DSC.psd1 = PowerShell\\Microsoft.WinGet.DSC\\Microsoft.WinGet.DSC.psd1\r\n\t\tPowerShell\\Microsoft.WinGet.DSC\\Microsoft.WinGet.DSC.psm1 = PowerShell\\Microsoft.WinGet.DSC\\Microsoft.WinGet.DSC.psm1\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Microsoft.WinGet.UnitTests\", \"PowerShell\\Microsoft.WinGet.UnitTests\\Microsoft.WinGet.UnitTests.csproj\", \"{5421394F-5619-4E4B-8923-F3FB30D5EFAD}\"\r\nEndProject\r\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"copilot\", \"copilot\", \"{B978E358-D2BE-4FA7-A21A-6661F3744DD7}\"\r\n\tProjectSection(SolutionItems) = preProject\r\n\t\t..\\.github\\copilot-instructions.md = ..\\.github\\copilot-instructions.md\r\n\tEndProjectSection\r\nEndProject\r\nGlobal\r\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\r\n\t\tDebug|ARM64 = Debug|ARM64\r\n\t\tDebug|x64 = Debug|x64\r\n\t\tDebug|x86 = Debug|x86\r\n\t\tFuzzing|ARM64 = Fuzzing|ARM64\r\n\t\tFuzzing|x64 = Fuzzing|x64\r\n\t\tFuzzing|x86 = Fuzzing|x86\r\n\t\tRelease|ARM64 = Release|ARM64\r\n\t\tRelease|x64 = Release|x64\r\n\t\tRelease|x86 = Release|x86\r\n\t\tReleaseStatic|ARM64 = ReleaseStatic|ARM64\r\n\t\tReleaseStatic|x64 = ReleaseStatic|x64\r\n\t\tReleaseStatic|x86 = ReleaseStatic|x86\r\n\tEndGlobalSection\r\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n\t\t{6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|ARM64.ActiveCfg = Debug|ARM64\r\n\t\t{6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|ARM64.Build.0 = Debug|ARM64\r\n\t\t{6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|ARM64.Deploy.0 = Debug|ARM64\r\n\t\t{6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|x64.Deploy.0 = Debug|x64\r\n\t\t{6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|x86.ActiveCfg = Debug|x86\r\n\t\t{6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|x86.Build.0 = Debug|x86\r\n\t\t{6AA3791A-0713-4548-A357-87A323E7AC3A}.Debug|x86.Deploy.0 = Debug|x86\r\n\t\t{6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{6AA3791A-0713-4548-A357-87A323E7AC3A}.Fuzzing|x86.ActiveCfg = Release|x86\r\n\t\t{6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|ARM64.Build.0 = Release|ARM64\r\n\t\t{6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|ARM64.Deploy.0 = Release|ARM64\r\n\t\t{6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|x64.Build.0 = Release|x64\r\n\t\t{6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|x64.Deploy.0 = Release|x64\r\n\t\t{6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|x86.ActiveCfg = Release|x86\r\n\t\t{6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|x86.Build.0 = Release|x86\r\n\t\t{6AA3791A-0713-4548-A357-87A323E7AC3A}.Release|x86.Deploy.0 = Release|x86\r\n\t\t{6AA3791A-0713-4548-A357-87A323E7AC3A}.ReleaseStatic|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{6AA3791A-0713-4548-A357-87A323E7AC3A}.ReleaseStatic|x64.ActiveCfg = Release|x64\r\n\t\t{6AA3791A-0713-4548-A357-87A323E7AC3A}.ReleaseStatic|x86.ActiveCfg = Release|x86\r\n\t\t{5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|ARM64.ActiveCfg = Debug|ARM64\r\n\t\t{5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|ARM64.Build.0 = Debug|ARM64\r\n\t\t{5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|x86.ActiveCfg = Debug|Win32\r\n\t\t{5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Debug|x86.Build.0 = Debug|Win32\r\n\t\t{5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Fuzzing|x86.ActiveCfg = Release|Win32\r\n\t\t{5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|ARM64.Build.0 = Release|ARM64\r\n\t\t{5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|x64.Build.0 = Release|x64\r\n\t\t{5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|x86.ActiveCfg = Release|Win32\r\n\t\t{5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.Release|x86.Build.0 = Release|Win32\r\n\t\t{5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.ReleaseStatic|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.ReleaseStatic|x64.ActiveCfg = Release|x64\r\n\t\t{5B6F90DF-FD19-4BAE-83D9-24DAD128E777}.ReleaseStatic|x86.ActiveCfg = Release|Win32\r\n\t\t{1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|ARM64.ActiveCfg = Debug|ARM64\r\n\t\t{1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|ARM64.Build.0 = Debug|ARM64\r\n\t\t{1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|x86.ActiveCfg = Debug|Win32\r\n\t\t{1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Debug|x86.Build.0 = Debug|Win32\r\n\t\t{1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Fuzzing|x86.ActiveCfg = Release|Win32\r\n\t\t{1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|ARM64.Build.0 = Release|ARM64\r\n\t\t{1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|x64.Build.0 = Release|x64\r\n\t\t{1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|x86.ActiveCfg = Release|Win32\r\n\t\t{1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.Release|x86.Build.0 = Release|Win32\r\n\t\t{1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.ReleaseStatic|ARM64.ActiveCfg = ReleaseStatic|ARM64\r\n\t\t{1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.ReleaseStatic|ARM64.Build.0 = ReleaseStatic|ARM64\r\n\t\t{1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64\r\n\t\t{1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64\r\n\t\t{1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32\r\n\t\t{1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32\r\n\t\t{89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|ARM64.ActiveCfg = Debug|ARM64\r\n\t\t{89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|ARM64.Build.0 = Debug|ARM64\r\n\t\t{89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|x86.ActiveCfg = Debug|Win32\r\n\t\t{89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Debug|x86.Build.0 = Debug|Win32\r\n\t\t{89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|ARM64.ActiveCfg = Release|x64\r\n\t\t{89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Fuzzing|x86.ActiveCfg = Release|Win32\r\n\t\t{89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|ARM64.Build.0 = Release|ARM64\r\n\t\t{89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|x64.Build.0 = Release|x64\r\n\t\t{89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|x86.ActiveCfg = Release|Win32\r\n\t\t{89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.Release|x86.Build.0 = Release|Win32\r\n\t\t{89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.ReleaseStatic|ARM64.ActiveCfg = Release|x64\r\n\t\t{89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.ReleaseStatic|x64.ActiveCfg = Release|x64\r\n\t\t{89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230}.ReleaseStatic|x86.ActiveCfg = Release|Win32\r\n\t\t{5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|ARM64.ActiveCfg = Debug|ARM64\r\n\t\t{5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|ARM64.Build.0 = Debug|ARM64\r\n\t\t{5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|x86.ActiveCfg = Debug|Win32\r\n\t\t{5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Debug|x86.Build.0 = Debug|Win32\r\n\t\t{5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Fuzzing|x86.ActiveCfg = Release|Win32\r\n\t\t{5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|ARM64.Build.0 = Release|ARM64\r\n\t\t{5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|x64.Build.0 = Release|x64\r\n\t\t{5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|x86.ActiveCfg = Release|Win32\r\n\t\t{5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.Release|x86.Build.0 = Release|Win32\r\n\t\t{5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.ReleaseStatic|ARM64.ActiveCfg = ReleaseStatic|ARM64\r\n\t\t{5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.ReleaseStatic|ARM64.Build.0 = ReleaseStatic|ARM64\r\n\t\t{5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64\r\n\t\t{5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64\r\n\t\t{5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32\r\n\t\t{5EB88068-5FB9-4E69-89B2-72DBC5E068F9}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32\r\n\t\t{5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|ARM64.ActiveCfg = Debug|ARM64\r\n\t\t{5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|ARM64.Build.0 = Debug|ARM64\r\n\t\t{5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|x86.ActiveCfg = Debug|Win32\r\n\t\t{5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Debug|x86.Build.0 = Debug|Win32\r\n\t\t{5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|x64.ActiveCfg = Fuzzing|x64\r\n\t\t{5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|x64.Build.0 = Fuzzing|x64\r\n\t\t{5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32\r\n\t\t{5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Fuzzing|x86.Build.0 = Fuzzing|Win32\r\n\t\t{5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|ARM64.Build.0 = Release|ARM64\r\n\t\t{5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|x64.Build.0 = Release|x64\r\n\t\t{5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|x86.ActiveCfg = Release|Win32\r\n\t\t{5890D6ED-7C3B-40F3-B436-B54F640D9E65}.Release|x86.Build.0 = Release|Win32\r\n\t\t{5890D6ED-7C3B-40F3-B436-B54F640D9E65}.ReleaseStatic|ARM64.ActiveCfg = ReleaseStatic|ARM64\r\n\t\t{5890D6ED-7C3B-40F3-B436-B54F640D9E65}.ReleaseStatic|ARM64.Build.0 = ReleaseStatic|ARM64\r\n\t\t{5890D6ED-7C3B-40F3-B436-B54F640D9E65}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64\r\n\t\t{5890D6ED-7C3B-40F3-B436-B54F640D9E65}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64\r\n\t\t{5890D6ED-7C3B-40F3-B436-B54F640D9E65}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32\r\n\t\t{5890D6ED-7C3B-40F3-B436-B54F640D9E65}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32\r\n\t\t{FB313532-38B0-4676-9303-AB200AA13576}.Debug|ARM64.ActiveCfg = Debug|ARM64\r\n\t\t{FB313532-38B0-4676-9303-AB200AA13576}.Debug|ARM64.Build.0 = Debug|ARM64\r\n\t\t{FB313532-38B0-4676-9303-AB200AA13576}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{FB313532-38B0-4676-9303-AB200AA13576}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{FB313532-38B0-4676-9303-AB200AA13576}.Debug|x86.ActiveCfg = Debug|Win32\r\n\t\t{FB313532-38B0-4676-9303-AB200AA13576}.Debug|x86.Build.0 = Debug|Win32\r\n\t\t{FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{FB313532-38B0-4676-9303-AB200AA13576}.Fuzzing|x86.ActiveCfg = Release|Win32\r\n\t\t{FB313532-38B0-4676-9303-AB200AA13576}.Release|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{FB313532-38B0-4676-9303-AB200AA13576}.Release|ARM64.Build.0 = Release|ARM64\r\n\t\t{FB313532-38B0-4676-9303-AB200AA13576}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{FB313532-38B0-4676-9303-AB200AA13576}.Release|x64.Build.0 = Release|x64\r\n\t\t{FB313532-38B0-4676-9303-AB200AA13576}.Release|x86.ActiveCfg = Release|Win32\r\n\t\t{FB313532-38B0-4676-9303-AB200AA13576}.Release|x86.Build.0 = Release|Win32\r\n\t\t{FB313532-38B0-4676-9303-AB200AA13576}.ReleaseStatic|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{FB313532-38B0-4676-9303-AB200AA13576}.ReleaseStatic|x64.ActiveCfg = Release|x64\r\n\t\t{FB313532-38B0-4676-9303-AB200AA13576}.ReleaseStatic|x86.ActiveCfg = Release|Win32\r\n\t\t{6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|ARM64.ActiveCfg = Debug|ARM64\r\n\t\t{6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|ARM64.Build.0 = Debug|ARM64\r\n\t\t{6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|x86.ActiveCfg = Debug|Win32\r\n\t\t{6CB84692-5994-407D-B9BD-9216AF77FE83}.Debug|x86.Build.0 = Debug|Win32\r\n\t\t{6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{6CB84692-5994-407D-B9BD-9216AF77FE83}.Fuzzing|x86.ActiveCfg = Release|Win32\r\n\t\t{6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|ARM64.Build.0 = Release|ARM64\r\n\t\t{6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|x64.Build.0 = Release|x64\r\n\t\t{6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|x86.ActiveCfg = Release|Win32\r\n\t\t{6CB84692-5994-407D-B9BD-9216AF77FE83}.Release|x86.Build.0 = Release|Win32\r\n\t\t{6CB84692-5994-407D-B9BD-9216AF77FE83}.ReleaseStatic|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{6CB84692-5994-407D-B9BD-9216AF77FE83}.ReleaseStatic|x64.ActiveCfg = Release|x64\r\n\t\t{6CB84692-5994-407D-B9BD-9216AF77FE83}.ReleaseStatic|x86.ActiveCfg = Release|Win32\r\n\t\t{3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|ARM64.ActiveCfg = Debug|x64\r\n\t\t{3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|x86.ActiveCfg = Debug|x86\r\n\t\t{3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Debug|x86.Build.0 = Debug|x86\r\n\t\t{3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|ARM64.ActiveCfg = Release|x64\r\n\t\t{3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Fuzzing|x86.ActiveCfg = Release|x86\r\n\t\t{3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|ARM64.ActiveCfg = Release|x64\r\n\t\t{3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|x64.Build.0 = Release|x64\r\n\t\t{3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|x86.ActiveCfg = Release|x86\r\n\t\t{3C0269FA-E582-4CA7-9E33-3881A005CA0C}.Release|x86.Build.0 = Release|x86\r\n\t\t{3C0269FA-E582-4CA7-9E33-3881A005CA0C}.ReleaseStatic|ARM64.ActiveCfg = Release|x86\r\n\t\t{3C0269FA-E582-4CA7-9E33-3881A005CA0C}.ReleaseStatic|x64.ActiveCfg = Release|x64\r\n\t\t{3C0269FA-E582-4CA7-9E33-3881A005CA0C}.ReleaseStatic|x86.ActiveCfg = Release|x86\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|ARM64.ActiveCfg = Debug|ARM64\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|ARM64.Build.0 = Debug|ARM64\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|ARM64.Deploy.0 = Debug|ARM64\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|x64.Deploy.0 = Debug|x64\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|x86.ActiveCfg = Debug|x86\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|x86.Build.0 = Debug|x86\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Debug|x86.Deploy.0 = Debug|x86\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Fuzzing|x86.ActiveCfg = Release|x86\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|ARM64.Build.0 = Release|ARM64\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|ARM64.Deploy.0 = Release|ARM64\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|x64.Build.0 = Release|x64\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|x64.Deploy.0 = Release|x64\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|x86.ActiveCfg = Release|x86\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|x86.Build.0 = Release|x86\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.Release|x86.Deploy.0 = Release|x86\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.ReleaseStatic|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.ReleaseStatic|x64.ActiveCfg = Release|x64\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}.ReleaseStatic|x86.ActiveCfg = Release|x86\r\n\t\t{C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|ARM64.ActiveCfg = Debug\r\n\t\t{C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|x64.ActiveCfg = Debug\r\n\t\t{C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Debug|x86.ActiveCfg = Debug\r\n\t\t{C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Fuzzing|ARM64.ActiveCfg = Release\r\n\t\t{C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Fuzzing|x64.ActiveCfg = Release\r\n\t\t{C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Fuzzing|x86.ActiveCfg = Release\r\n\t\t{C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|ARM64.ActiveCfg = Release\r\n\t\t{C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|x64.ActiveCfg = Release\r\n\t\t{C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.Release|x86.ActiveCfg = Release\r\n\t\t{C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.ReleaseStatic|ARM64.ActiveCfg = Release\r\n\t\t{C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.ReleaseStatic|x64.ActiveCfg = Release\r\n\t\t{C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8}.ReleaseStatic|x86.ActiveCfg = Release\r\n\t\t{3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|ARM64.ActiveCfg = Debug|x64\r\n\t\t{3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|x86.ActiveCfg = Debug|x86\r\n\t\t{3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Debug|x86.Build.0 = Debug|x86\r\n\t\t{3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|ARM64.ActiveCfg = Release|x64\r\n\t\t{3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Fuzzing|x86.ActiveCfg = Release|x86\r\n\t\t{3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|ARM64.ActiveCfg = Release|x64\r\n\t\t{3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|x64.Build.0 = Release|x64\r\n\t\t{3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|x86.ActiveCfg = Release|x86\r\n\t\t{3B8466CF-4FDD-4329-9C80-91321C4AAC99}.Release|x86.Build.0 = Release|x86\r\n\t\t{3B8466CF-4FDD-4329-9C80-91321C4AAC99}.ReleaseStatic|ARM64.ActiveCfg = Release|x64\r\n\t\t{3B8466CF-4FDD-4329-9C80-91321C4AAC99}.ReleaseStatic|x64.ActiveCfg = Release|x64\r\n\t\t{3B8466CF-4FDD-4329-9C80-91321C4AAC99}.ReleaseStatic|x86.ActiveCfg = Release|x86\r\n\t\t{1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|ARM64.ActiveCfg = Fuzzing|x64\r\n\t\t{1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|x64.ActiveCfg = Fuzzing|x64\r\n\t\t{1622DA16-914F-4F57-A259-D5169003CC8C}.Debug|x86.ActiveCfg = Fuzzing|Win32\r\n\t\t{1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|ARM64.ActiveCfg = Fuzzing|x64\r\n\t\t{1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|x64.ActiveCfg = Fuzzing|x64\r\n\t\t{1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|x64.Build.0 = Fuzzing|x64\r\n\t\t{1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32\r\n\t\t{1622DA16-914F-4F57-A259-D5169003CC8C}.Fuzzing|x86.Build.0 = Fuzzing|Win32\r\n\t\t{1622DA16-914F-4F57-A259-D5169003CC8C}.Release|ARM64.ActiveCfg = Fuzzing|x64\r\n\t\t{1622DA16-914F-4F57-A259-D5169003CC8C}.Release|x64.ActiveCfg = Fuzzing|x64\r\n\t\t{1622DA16-914F-4F57-A259-D5169003CC8C}.Release|x86.ActiveCfg = Fuzzing|Win32\r\n\t\t{1622DA16-914F-4F57-A259-D5169003CC8C}.ReleaseStatic|ARM64.ActiveCfg = Fuzzing|x64\r\n\t\t{1622DA16-914F-4F57-A259-D5169003CC8C}.ReleaseStatic|x64.ActiveCfg = Fuzzing|x64\r\n\t\t{1622DA16-914F-4F57-A259-D5169003CC8C}.ReleaseStatic|x86.ActiveCfg = Fuzzing|Win32\r\n\t\t{3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|ARM64.ActiveCfg = Debug|x64\r\n\t\t{3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|x86.ActiveCfg = Debug|x86\r\n\t\t{3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Debug|x86.Build.0 = Debug|x86\r\n\t\t{3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|ARM64.ActiveCfg = Release|x64\r\n\t\t{3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Fuzzing|x86.ActiveCfg = Release|x86\r\n\t\t{3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|ARM64.ActiveCfg = Release|x64\r\n\t\t{3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|x64.Build.0 = Release|x64\r\n\t\t{3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|x86.ActiveCfg = Release|x86\r\n\t\t{3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.Release|x86.Build.0 = Release|x86\r\n\t\t{3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.ReleaseStatic|ARM64.ActiveCfg = Release|x64\r\n\t\t{3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.ReleaseStatic|x64.ActiveCfg = Release|x64\r\n\t\t{3BAF989F-7F65-465B-ACE8-BAFE42D1017E}.ReleaseStatic|x86.ActiveCfg = Release|x86\r\n\t\t{1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|ARM64.ActiveCfg = Debug|ARM64\r\n\t\t{1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|ARM64.Build.0 = Debug|ARM64\r\n\t\t{1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|x86.ActiveCfg = Debug|Win32\r\n\t\t{1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Debug|x86.Build.0 = Debug|Win32\r\n\t\t{1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Fuzzing|x86.ActiveCfg = Release|Win32\r\n\t\t{1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|ARM64.Build.0 = Release|ARM64\r\n\t\t{1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|x64.Build.0 = Release|x64\r\n\t\t{1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|x86.ActiveCfg = Release|Win32\r\n\t\t{1CC41A9A-AE66-459D-9210-1E572DD7BE69}.Release|x86.Build.0 = Release|Win32\r\n\t\t{1CC41A9A-AE66-459D-9210-1E572DD7BE69}.ReleaseStatic|ARM64.ActiveCfg = ReleaseStatic|ARM64\r\n\t\t{1CC41A9A-AE66-459D-9210-1E572DD7BE69}.ReleaseStatic|ARM64.Build.0 = ReleaseStatic|ARM64\r\n\t\t{1CC41A9A-AE66-459D-9210-1E572DD7BE69}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64\r\n\t\t{1CC41A9A-AE66-459D-9210-1E572DD7BE69}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64\r\n\t\t{1CC41A9A-AE66-459D-9210-1E572DD7BE69}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32\r\n\t\t{1CC41A9A-AE66-459D-9210-1E572DD7BE69}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32\r\n\t\t{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM64.ActiveCfg = Debug|ARM64\r\n\t\t{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|ARM64.Build.0 = Debug|ARM64\r\n\t\t{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x86.ActiveCfg = Debug|Win32\r\n\t\t{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Debug|x86.Build.0 = Debug|Win32\r\n\t\t{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Fuzzing|x86.ActiveCfg = Release|Win32\r\n\t\t{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|ARM64.Build.0 = Release|ARM64\r\n\t\t{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x64.Build.0 = Release|x64\r\n\t\t{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x86.ActiveCfg = Release|Win32\r\n\t\t{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.Release|x86.Build.0 = Release|Win32\r\n\t\t{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.ReleaseStatic|ARM64.ActiveCfg = ReleaseStatic|ARM64\r\n\t\t{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.ReleaseStatic|ARM64.Build.0 = ReleaseStatic|ARM64\r\n\t\t{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64\r\n\t\t{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64\r\n\t\t{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32\r\n\t\t{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32\r\n\t\t{846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|ARM64.ActiveCfg = Debug|Any CPU\r\n\t\t{846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|ARM64.Build.0 = Debug|Any CPU\r\n\t\t{846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|x64.ActiveCfg = Debug|Any CPU\r\n\t\t{846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|x64.Build.0 = Debug|Any CPU\r\n\t\t{846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|x86.ActiveCfg = Debug|Any CPU\r\n\t\t{846FB88B-BF1B-4F33-9883-E589CEC99739}.Debug|x86.Build.0 = Debug|Any CPU\r\n\t\t{846FB88B-BF1B-4F33-9883-E589CEC99739}.Fuzzing|ARM64.ActiveCfg = Release|Any CPU\r\n\t\t{846FB88B-BF1B-4F33-9883-E589CEC99739}.Fuzzing|x64.ActiveCfg = Release|Any CPU\r\n\t\t{846FB88B-BF1B-4F33-9883-E589CEC99739}.Fuzzing|x86.ActiveCfg = Release|Any CPU\r\n\t\t{846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|ARM64.ActiveCfg = Release|Any CPU\r\n\t\t{846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|ARM64.Build.0 = Release|Any CPU\r\n\t\t{846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|x64.ActiveCfg = Release|Any CPU\r\n\t\t{846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|x64.Build.0 = Release|Any CPU\r\n\t\t{846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|x86.ActiveCfg = Release|Any CPU\r\n\t\t{846FB88B-BF1B-4F33-9883-E589CEC99739}.Release|x86.Build.0 = Release|Any CPU\r\n\t\t{846FB88B-BF1B-4F33-9883-E589CEC99739}.ReleaseStatic|ARM64.ActiveCfg = Release|Any CPU\r\n\t\t{846FB88B-BF1B-4F33-9883-E589CEC99739}.ReleaseStatic|x64.ActiveCfg = Release|Any CPU\r\n\t\t{846FB88B-BF1B-4F33-9883-E589CEC99739}.ReleaseStatic|x86.ActiveCfg = Release|Any CPU\r\n\t\t{68808357-902B-406C-8C19-E8E26A69DE8A}.Debug|ARM64.ActiveCfg = Debug|x64\r\n\t\t{68808357-902B-406C-8C19-E8E26A69DE8A}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{68808357-902B-406C-8C19-E8E26A69DE8A}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{68808357-902B-406C-8C19-E8E26A69DE8A}.Debug|x86.ActiveCfg = Debug|x86\r\n\t\t{68808357-902B-406C-8C19-E8E26A69DE8A}.Debug|x86.Build.0 = Debug|x86\r\n\t\t{68808357-902B-406C-8C19-E8E26A69DE8A}.Fuzzing|ARM64.ActiveCfg = Release|x64\r\n\t\t{68808357-902B-406C-8C19-E8E26A69DE8A}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{68808357-902B-406C-8C19-E8E26A69DE8A}.Fuzzing|x86.ActiveCfg = Release|x86\r\n\t\t{68808357-902B-406C-8C19-E8E26A69DE8A}.Release|ARM64.ActiveCfg = Release|x64\r\n\t\t{68808357-902B-406C-8C19-E8E26A69DE8A}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{68808357-902B-406C-8C19-E8E26A69DE8A}.Release|x64.Build.0 = Release|x64\r\n\t\t{68808357-902B-406C-8C19-E8E26A69DE8A}.Release|x86.ActiveCfg = Release|x86\r\n\t\t{68808357-902B-406C-8C19-E8E26A69DE8A}.Release|x86.Build.0 = Release|x86\r\n\t\t{68808357-902B-406C-8C19-E8E26A69DE8A}.ReleaseStatic|ARM64.ActiveCfg = Release|x64\r\n\t\t{68808357-902B-406C-8C19-E8E26A69DE8A}.ReleaseStatic|x64.ActiveCfg = Release|x64\r\n\t\t{68808357-902B-406C-8C19-E8E26A69DE8A}.ReleaseStatic|x86.ActiveCfg = Release|x86\r\n\t\t{2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Debug|ARM64.ActiveCfg = Debug|ARM64\r\n\t\t{2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Debug|ARM64.Build.0 = Debug|ARM64\r\n\t\t{2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Debug|x86.ActiveCfg = Debug|Win32\r\n\t\t{2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Debug|x86.Build.0 = Debug|Win32\r\n\t\t{2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Fuzzing|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Fuzzing|x86.ActiveCfg = Release|Win32\r\n\t\t{2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Release|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Release|ARM64.Build.0 = Release|ARM64\r\n\t\t{2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Release|x64.Build.0 = Release|x64\r\n\t\t{2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Release|x86.ActiveCfg = Release|Win32\r\n\t\t{2046B5AF-666D-4CE8-8D3E-C32C57908A56}.Release|x86.Build.0 = Release|Win32\r\n\t\t{2046B5AF-666D-4CE8-8D3E-C32C57908A56}.ReleaseStatic|ARM64.ActiveCfg = ReleaseStatic|ARM64\r\n\t\t{2046B5AF-666D-4CE8-8D3E-C32C57908A56}.ReleaseStatic|ARM64.Build.0 = ReleaseStatic|ARM64\r\n\t\t{2046B5AF-666D-4CE8-8D3E-C32C57908A56}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64\r\n\t\t{2046B5AF-666D-4CE8-8D3E-C32C57908A56}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64\r\n\t\t{2046B5AF-666D-4CE8-8D3E-C32C57908A56}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32\r\n\t\t{2046B5AF-666D-4CE8-8D3E-C32C57908A56}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32\r\n\t\t{9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Debug|ARM64.ActiveCfg = Debug|ARM64\r\n\t\t{9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Debug|ARM64.Build.0 = Debug|ARM64\r\n\t\t{9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Debug|x86.ActiveCfg = Debug|Win32\r\n\t\t{9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Debug|x86.Build.0 = Debug|Win32\r\n\t\t{9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Fuzzing|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Fuzzing|x86.ActiveCfg = Release|Win32\r\n\t\t{9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Release|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Release|x64.Build.0 = Release|x64\r\n\t\t{9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Release|x86.ActiveCfg = Release|Win32\r\n\t\t{9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.Release|x86.Build.0 = Release|Win32\r\n\t\t{9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.ReleaseStatic|ARM64.ActiveCfg = ReleaseStatic|ARM64\r\n\t\t{9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.ReleaseStatic|ARM64.Build.0 = ReleaseStatic|ARM64\r\n\t\t{9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64\r\n\t\t{9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64\r\n\t\t{9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32\r\n\t\t{9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32\r\n\t\t{463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Debug|ARM64.ActiveCfg = Debug|Any CPU\r\n\t\t{463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Debug|ARM64.Build.0 = Debug|Any CPU\r\n\t\t{463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Debug|x64.ActiveCfg = Debug|Any CPU\r\n\t\t{463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Debug|x64.Build.0 = Debug|Any CPU\r\n\t\t{463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Debug|x86.ActiveCfg = Debug|Any CPU\r\n\t\t{463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Debug|x86.Build.0 = Debug|Any CPU\r\n\t\t{463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Fuzzing|ARM64.ActiveCfg = Release|Any CPU\r\n\t\t{463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Fuzzing|x64.ActiveCfg = Release|Any CPU\r\n\t\t{463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Fuzzing|x86.ActiveCfg = Release|Any CPU\r\n\t\t{463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Release|ARM64.ActiveCfg = Release|Any CPU\r\n\t\t{463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Release|ARM64.Build.0 = Release|Any CPU\r\n\t\t{463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Release|x64.ActiveCfg = Release|Any CPU\r\n\t\t{463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Release|x64.Build.0 = Release|Any CPU\r\n\t\t{463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Release|x86.ActiveCfg = Release|Any CPU\r\n\t\t{463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Release|x86.Build.0 = Release|Any CPU\r\n\t\t{463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.ReleaseStatic|ARM64.ActiveCfg = ReleaseStatic|Any CPU\r\n\t\t{463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|Any CPU\r\n\t\t{463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.ReleaseStatic|x64.Build.0 = ReleaseStatic|Any CPU\r\n\t\t{463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Any CPU\r\n\t\t{463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Any CPU\r\n\t\t{0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Debug|ARM64.ActiveCfg = Debug|arm64\r\n\t\t{0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Debug|x86.ActiveCfg = Debug|x86\r\n\t\t{0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Debug|x86.Build.0 = Debug|x86\r\n\t\t{0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Fuzzing|ARM64.ActiveCfg = Release|arm64\r\n\t\t{0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Fuzzing|x86.ActiveCfg = Release|x86\r\n\t\t{0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Release|ARM64.ActiveCfg = Release|arm64\r\n\t\t{0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Release|x64.Build.0 = Release|x64\r\n\t\t{0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Release|x86.ActiveCfg = Release|x86\r\n\t\t{0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Release|x86.Build.0 = Release|x86\r\n\t\t{0B104762-5CD8-47EE-A904-71C1C3F84DCD}.ReleaseStatic|ARM64.ActiveCfg = ReleaseStatic|arm64\r\n\t\t{0B104762-5CD8-47EE-A904-71C1C3F84DCD}.ReleaseStatic|ARM64.Build.0 = ReleaseStatic|arm64\r\n\t\t{0B104762-5CD8-47EE-A904-71C1C3F84DCD}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64\r\n\t\t{0B104762-5CD8-47EE-A904-71C1C3F84DCD}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64\r\n\t\t{0B104762-5CD8-47EE-A904-71C1C3F84DCD}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|x86\r\n\t\t{0B104762-5CD8-47EE-A904-71C1C3F84DCD}.ReleaseStatic|x86.Build.0 = ReleaseStatic|x86\r\n\t\t{31ED69A8-5310-45A9-953F-56C351D2C3E1}.Debug|ARM64.ActiveCfg = Debug|ARM64\r\n\t\t{31ED69A8-5310-45A9-953F-56C351D2C3E1}.Debug|ARM64.Build.0 = Debug|ARM64\r\n\t\t{31ED69A8-5310-45A9-953F-56C351D2C3E1}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{31ED69A8-5310-45A9-953F-56C351D2C3E1}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{31ED69A8-5310-45A9-953F-56C351D2C3E1}.Debug|x86.ActiveCfg = Debug|Win32\r\n\t\t{31ED69A8-5310-45A9-953F-56C351D2C3E1}.Debug|x86.Build.0 = Debug|Win32\r\n\t\t{31ED69A8-5310-45A9-953F-56C351D2C3E1}.Fuzzing|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{31ED69A8-5310-45A9-953F-56C351D2C3E1}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{31ED69A8-5310-45A9-953F-56C351D2C3E1}.Fuzzing|x86.ActiveCfg = Release|Win32\r\n\t\t{31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|ARM64.Build.0 = Release|ARM64\r\n\t\t{31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|x64.Build.0 = Release|x64\r\n\t\t{31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|x86.ActiveCfg = Release|Win32\r\n\t\t{31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|x86.Build.0 = Release|Win32\r\n\t\t{31ED69A8-5310-45A9-953F-56C351D2C3E1}.ReleaseStatic|ARM64.ActiveCfg = ReleaseStatic|ARM64\r\n\t\t{31ED69A8-5310-45A9-953F-56C351D2C3E1}.ReleaseStatic|ARM64.Build.0 = ReleaseStatic|ARM64\r\n\t\t{31ED69A8-5310-45A9-953F-56C351D2C3E1}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64\r\n\t\t{31ED69A8-5310-45A9-953F-56C351D2C3E1}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64\r\n\t\t{31ED69A8-5310-45A9-953F-56C351D2C3E1}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32\r\n\t\t{31ED69A8-5310-45A9-953F-56C351D2C3E1}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32\r\n\t\t{F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Debug|ARM64.ActiveCfg = Debug|ARM64\r\n\t\t{F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Debug|ARM64.Build.0 = Debug|ARM64\r\n\t\t{F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Debug|x86.ActiveCfg = Debug|Win32\r\n\t\t{F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Debug|x86.Build.0 = Debug|Win32\r\n\t\t{F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Fuzzing|ARM64.ActiveCfg = Fuzzing|x64\r\n\t\t{F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Fuzzing|x64.ActiveCfg = Fuzzing|x64\r\n\t\t{F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Fuzzing|x64.Build.0 = Fuzzing|x64\r\n\t\t{F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32\r\n\t\t{F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Fuzzing|x86.Build.0 = Fuzzing|Win32\r\n\t\t{F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Release|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Release|ARM64.Build.0 = Release|ARM64\r\n\t\t{F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Release|x64.Build.0 = Release|x64\r\n\t\t{F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Release|x86.ActiveCfg = Release|Win32\r\n\t\t{F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.Release|x86.Build.0 = Release|Win32\r\n\t\t{F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.ReleaseStatic|ARM64.ActiveCfg = ReleaseStatic|ARM64\r\n\t\t{F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.ReleaseStatic|ARM64.Build.0 = ReleaseStatic|ARM64\r\n\t\t{F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64\r\n\t\t{F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64\r\n\t\t{F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32\r\n\t\t{F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32\r\n\t\t{CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|ARM64.ActiveCfg = Debug|ARM64\r\n\t\t{CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|ARM64.Build.0 = Debug|ARM64\r\n\t\t{CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|x86.ActiveCfg = Debug|Win32\r\n\t\t{CA460806-5E41-4E97-9A3D-1D74B433B663}.Debug|x86.Build.0 = Debug|Win32\r\n\t\t{CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{CA460806-5E41-4E97-9A3D-1D74B433B663}.Fuzzing|x86.ActiveCfg = Release|Win32\r\n\t\t{CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|ARM64.Build.0 = Release|ARM64\r\n\t\t{CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|x64.Build.0 = Release|x64\r\n\t\t{CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|x86.ActiveCfg = Release|Win32\r\n\t\t{CA460806-5E41-4E97-9A3D-1D74B433B663}.Release|x86.Build.0 = Release|Win32\r\n\t\t{CA460806-5E41-4E97-9A3D-1D74B433B663}.ReleaseStatic|ARM64.ActiveCfg = ReleaseStatic|ARM64\r\n\t\t{CA460806-5E41-4E97-9A3D-1D74B433B663}.ReleaseStatic|ARM64.Build.0 = ReleaseStatic|ARM64\r\n\t\t{CA460806-5E41-4E97-9A3D-1D74B433B663}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64\r\n\t\t{CA460806-5E41-4E97-9A3D-1D74B433B663}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64\r\n\t\t{CA460806-5E41-4E97-9A3D-1D74B433B663}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32\r\n\t\t{CA460806-5E41-4E97-9A3D-1D74B433B663}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32\r\n\t\t{E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|ARM64.ActiveCfg = Debug|Any CPU\r\n\t\t{E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|ARM64.Build.0 = Debug|Any CPU\r\n\t\t{E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|x64.ActiveCfg = Debug|Any CPU\r\n\t\t{E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|x64.Build.0 = Debug|Any CPU\r\n\t\t{E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|x86.ActiveCfg = Debug|Any CPU\r\n\t\t{E8454BF1-2068-4513-A525-ABF55CC8742C}.Debug|x86.Build.0 = Debug|Any CPU\r\n\t\t{E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|ARM64.ActiveCfg = Release|Any CPU\r\n\t\t{E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|x64.ActiveCfg = Release|Any CPU\r\n\t\t{E8454BF1-2068-4513-A525-ABF55CC8742C}.Fuzzing|x86.ActiveCfg = Release|Any CPU\r\n\t\t{E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|ARM64.ActiveCfg = Release|Any CPU\r\n\t\t{E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|ARM64.Build.0 = Release|Any CPU\r\n\t\t{E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|x64.ActiveCfg = Release|Any CPU\r\n\t\t{E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|x64.Build.0 = Release|Any CPU\r\n\t\t{E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|x86.ActiveCfg = Release|Any CPU\r\n\t\t{E8454BF1-2068-4513-A525-ABF55CC8742C}.Release|x86.Build.0 = Release|Any CPU\r\n\t\t{E8454BF1-2068-4513-A525-ABF55CC8742C}.ReleaseStatic|ARM64.ActiveCfg = ReleaseStatic|Any CPU\r\n\t\t{E8454BF1-2068-4513-A525-ABF55CC8742C}.ReleaseStatic|ARM64.Build.0 = ReleaseStatic|Any CPU\r\n\t\t{E8454BF1-2068-4513-A525-ABF55CC8742C}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|Any CPU\r\n\t\t{E8454BF1-2068-4513-A525-ABF55CC8742C}.ReleaseStatic|x64.Build.0 = ReleaseStatic|Any CPU\r\n\t\t{E8454BF1-2068-4513-A525-ABF55CC8742C}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Any CPU\r\n\t\t{E8454BF1-2068-4513-A525-ABF55CC8742C}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Any CPU\r\n\t\t{EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|ARM64.ActiveCfg = Debug|arm64\r\n\t\t{EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|ARM64.Build.0 = Debug|arm64\r\n\t\t{EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|x86.ActiveCfg = Debug|x86\r\n\t\t{EE43C990-7789-4A60-B077-BF0ED3D093A1}.Debug|x86.Build.0 = Debug|x86\r\n\t\t{EE43C990-7789-4A60-B077-BF0ED3D093A1}.Fuzzing|ARM64.ActiveCfg = Release|arm64\r\n\t\t{EE43C990-7789-4A60-B077-BF0ED3D093A1}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{EE43C990-7789-4A60-B077-BF0ED3D093A1}.Fuzzing|x86.ActiveCfg = Release|x86\r\n\t\t{EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|ARM64.ActiveCfg = Release|arm64\r\n\t\t{EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|ARM64.Build.0 = Release|arm64\r\n\t\t{EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|x64.Build.0 = Release|x64\r\n\t\t{EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|x86.ActiveCfg = Release|x86\r\n\t\t{EE43C990-7789-4A60-B077-BF0ED3D093A1}.Release|x86.Build.0 = Release|x86\r\n\t\t{EE43C990-7789-4A60-B077-BF0ED3D093A1}.ReleaseStatic|ARM64.ActiveCfg = Release|arm64\r\n\t\t{EE43C990-7789-4A60-B077-BF0ED3D093A1}.ReleaseStatic|x64.ActiveCfg = Release|x64\r\n\t\t{EE43C990-7789-4A60-B077-BF0ED3D093A1}.ReleaseStatic|x86.ActiveCfg = Release|x86\r\n\t\t{71FA29AA-9035-468B-A11D-0F0B0F5D5AF4}.Debug|ARM64.ActiveCfg = Debug|Any CPU\r\n\t\t{71FA29AA-9035-468B-A11D-0F0B0F5D5AF4}.Debug|ARM64.Build.0 = Debug|Any CPU\r\n\t\t{71FA29AA-9035-468B-A11D-0F0B0F5D5AF4}.Debug|x64.ActiveCfg = Debug|Any CPU\r\n\t\t{71FA29AA-9035-468B-A11D-0F0B0F5D5AF4}.Debug|x64.Build.0 = Debug|Any CPU\r\n\t\t{71FA29AA-9035-468B-A11D-0F0B0F5D5AF4}.Debug|x86.ActiveCfg = Debug|Any CPU\r\n\t\t{71FA29AA-9035-468B-A11D-0F0B0F5D5AF4}.Debug|x86.Build.0 = Debug|Any CPU\r\n\t\t{71FA29AA-9035-468B-A11D-0F0B0F5D5AF4}.Fuzzing|ARM64.ActiveCfg = Release|Any CPU\r\n\t\t{71FA29AA-9035-468B-A11D-0F0B0F5D5AF4}.Fuzzing|x64.ActiveCfg = Release|Any CPU\r\n\t\t{71FA29AA-9035-468B-A11D-0F0B0F5D5AF4}.Fuzzing|x86.ActiveCfg = Release|Any CPU\r\n\t\t{71FA29AA-9035-468B-A11D-0F0B0F5D5AF4}.Release|ARM64.ActiveCfg = Release|Any CPU\r\n\t\t{71FA29AA-9035-468B-A11D-0F0B0F5D5AF4}.Release|ARM64.Build.0 = Release|Any CPU\r\n\t\t{71FA29AA-9035-468B-A11D-0F0B0F5D5AF4}.Release|x64.ActiveCfg = Release|Any CPU\r\n\t\t{71FA29AA-9035-468B-A11D-0F0B0F5D5AF4}.Release|x64.Build.0 = Release|Any CPU\r\n\t\t{71FA29AA-9035-468B-A11D-0F0B0F5D5AF4}.Release|x86.ActiveCfg = Release|Any CPU\r\n\t\t{71FA29AA-9035-468B-A11D-0F0B0F5D5AF4}.Release|x86.Build.0 = Release|Any CPU\r\n\t\t{71FA29AA-9035-468B-A11D-0F0B0F5D5AF4}.ReleaseStatic|ARM64.ActiveCfg = ReleaseStatic|Any CPU\r\n\t\t{71FA29AA-9035-468B-A11D-0F0B0F5D5AF4}.ReleaseStatic|ARM64.Build.0 = ReleaseStatic|Any CPU\r\n\t\t{71FA29AA-9035-468B-A11D-0F0B0F5D5AF4}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|Any CPU\r\n\t\t{71FA29AA-9035-468B-A11D-0F0B0F5D5AF4}.ReleaseStatic|x64.Build.0 = ReleaseStatic|Any CPU\r\n\t\t{71FA29AA-9035-468B-A11D-0F0B0F5D5AF4}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Any CPU\r\n\t\t{71FA29AA-9035-468B-A11D-0F0B0F5D5AF4}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Any CPU\r\n\t\t{6597EB04-D105-49A7-A5A3-D27FE1DF895E}.Debug|ARM64.ActiveCfg = Debug|arm64\r\n\t\t{6597EB04-D105-49A7-A5A3-D27FE1DF895E}.Debug|ARM64.Build.0 = Debug|arm64\r\n\t\t{6597EB04-D105-49A7-A5A3-D27FE1DF895E}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{6597EB04-D105-49A7-A5A3-D27FE1DF895E}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{6597EB04-D105-49A7-A5A3-D27FE1DF895E}.Debug|x86.ActiveCfg = Debug|x86\r\n\t\t{6597EB04-D105-49A7-A5A3-D27FE1DF895E}.Debug|x86.Build.0 = Debug|x86\r\n\t\t{6597EB04-D105-49A7-A5A3-D27FE1DF895E}.Fuzzing|ARM64.ActiveCfg = Release|arm64\r\n\t\t{6597EB04-D105-49A7-A5A3-D27FE1DF895E}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{6597EB04-D105-49A7-A5A3-D27FE1DF895E}.Fuzzing|x86.ActiveCfg = Release|x86\r\n\t\t{6597EB04-D105-49A7-A5A3-D27FE1DF895E}.Release|ARM64.ActiveCfg = Release|arm64\r\n\t\t{6597EB04-D105-49A7-A5A3-D27FE1DF895E}.Release|ARM64.Build.0 = Release|arm64\r\n\t\t{6597EB04-D105-49A7-A5A3-D27FE1DF895E}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{6597EB04-D105-49A7-A5A3-D27FE1DF895E}.Release|x64.Build.0 = Release|x64\r\n\t\t{6597EB04-D105-49A7-A5A3-D27FE1DF895E}.Release|x86.ActiveCfg = Release|x86\r\n\t\t{6597EB04-D105-49A7-A5A3-D27FE1DF895E}.Release|x86.Build.0 = Release|x86\r\n\t\t{6597EB04-D105-49A7-A5A3-D27FE1DF895E}.ReleaseStatic|ARM64.ActiveCfg = Release|arm64\r\n\t\t{6597EB04-D105-49A7-A5A3-D27FE1DF895E}.ReleaseStatic|x64.ActiveCfg = Release|x64\r\n\t\t{6597EB04-D105-49A7-A5A3-D27FE1DF895E}.ReleaseStatic|x86.ActiveCfg = Release|x86\r\n\t\t{1F56BECB-D65D-4BBA-8788-6671B251392A}.Debug|ARM64.ActiveCfg = Debug|Any CPU\r\n\t\t{1F56BECB-D65D-4BBA-8788-6671B251392A}.Debug|ARM64.Build.0 = Debug|Any CPU\r\n\t\t{1F56BECB-D65D-4BBA-8788-6671B251392A}.Debug|x64.ActiveCfg = Debug|Any CPU\r\n\t\t{1F56BECB-D65D-4BBA-8788-6671B251392A}.Debug|x64.Build.0 = Debug|Any CPU\r\n\t\t{1F56BECB-D65D-4BBA-8788-6671B251392A}.Debug|x86.ActiveCfg = Debug|Any CPU\r\n\t\t{1F56BECB-D65D-4BBA-8788-6671B251392A}.Debug|x86.Build.0 = Debug|Any CPU\r\n\t\t{1F56BECB-D65D-4BBA-8788-6671B251392A}.Fuzzing|ARM64.ActiveCfg = Release|Any CPU\r\n\t\t{1F56BECB-D65D-4BBA-8788-6671B251392A}.Fuzzing|x64.ActiveCfg = Release|Any CPU\r\n\t\t{1F56BECB-D65D-4BBA-8788-6671B251392A}.Fuzzing|x86.ActiveCfg = Release|Any CPU\r\n\t\t{1F56BECB-D65D-4BBA-8788-6671B251392A}.Release|ARM64.ActiveCfg = Release|Any CPU\r\n\t\t{1F56BECB-D65D-4BBA-8788-6671B251392A}.Release|ARM64.Build.0 = Release|Any CPU\r\n\t\t{1F56BECB-D65D-4BBA-8788-6671B251392A}.Release|x64.ActiveCfg = Release|Any CPU\r\n\t\t{1F56BECB-D65D-4BBA-8788-6671B251392A}.Release|x64.Build.0 = Release|Any CPU\r\n\t\t{1F56BECB-D65D-4BBA-8788-6671B251392A}.Release|x86.ActiveCfg = Release|Any CPU\r\n\t\t{1F56BECB-D65D-4BBA-8788-6671B251392A}.Release|x86.Build.0 = Release|Any CPU\r\n\t\t{1F56BECB-D65D-4BBA-8788-6671B251392A}.ReleaseStatic|ARM64.ActiveCfg = ReleaseStatic|Any CPU\r\n\t\t{1F56BECB-D65D-4BBA-8788-6671B251392A}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|Any CPU\r\n\t\t{1F56BECB-D65D-4BBA-8788-6671B251392A}.ReleaseStatic|x64.Build.0 = ReleaseStatic|Any CPU\r\n\t\t{1F56BECB-D65D-4BBA-8788-6671B251392A}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Any CPU\r\n\t\t{1F56BECB-D65D-4BBA-8788-6671B251392A}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Any CPU\r\n\t\t{167F634B-A3AD-494E-8E67-B888103E35FF}.Debug|ARM64.ActiveCfg = Debug|Any CPU\r\n\t\t{167F634B-A3AD-494E-8E67-B888103E35FF}.Debug|ARM64.Build.0 = Debug|Any CPU\r\n\t\t{167F634B-A3AD-494E-8E67-B888103E35FF}.Debug|x64.ActiveCfg = Debug|Any CPU\r\n\t\t{167F634B-A3AD-494E-8E67-B888103E35FF}.Debug|x64.Build.0 = Debug|Any CPU\r\n\t\t{167F634B-A3AD-494E-8E67-B888103E35FF}.Debug|x86.ActiveCfg = Debug|Any CPU\r\n\t\t{167F634B-A3AD-494E-8E67-B888103E35FF}.Debug|x86.Build.0 = Debug|Any CPU\r\n\t\t{167F634B-A3AD-494E-8E67-B888103E35FF}.Fuzzing|ARM64.ActiveCfg = Release|Any CPU\r\n\t\t{167F634B-A3AD-494E-8E67-B888103E35FF}.Fuzzing|x64.ActiveCfg = Release|Any CPU\r\n\t\t{167F634B-A3AD-494E-8E67-B888103E35FF}.Fuzzing|x86.ActiveCfg = Release|Any CPU\r\n\t\t{167F634B-A3AD-494E-8E67-B888103E35FF}.Release|ARM64.ActiveCfg = Release|Any CPU\r\n\t\t{167F634B-A3AD-494E-8E67-B888103E35FF}.Release|ARM64.Build.0 = Release|Any CPU\r\n\t\t{167F634B-A3AD-494E-8E67-B888103E35FF}.Release|x64.ActiveCfg = Release|Any CPU\r\n\t\t{167F634B-A3AD-494E-8E67-B888103E35FF}.Release|x64.Build.0 = Release|Any CPU\r\n\t\t{167F634B-A3AD-494E-8E67-B888103E35FF}.Release|x86.ActiveCfg = Release|Any CPU\r\n\t\t{167F634B-A3AD-494E-8E67-B888103E35FF}.Release|x86.Build.0 = Release|Any CPU\r\n\t\t{167F634B-A3AD-494E-8E67-B888103E35FF}.ReleaseStatic|ARM64.ActiveCfg = ReleaseStatic|Any CPU\r\n\t\t{167F634B-A3AD-494E-8E67-B888103E35FF}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|Any CPU\r\n\t\t{167F634B-A3AD-494E-8E67-B888103E35FF}.ReleaseStatic|x64.Build.0 = ReleaseStatic|Any CPU\r\n\t\t{167F634B-A3AD-494E-8E67-B888103E35FF}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Any CPU\r\n\t\t{167F634B-A3AD-494E-8E67-B888103E35FF}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Any CPU\r\n\t\t{C54F80ED-B736-49B0-9BD3-662F57024D01}.Debug|ARM64.ActiveCfg = Debug|Any CPU\r\n\t\t{C54F80ED-B736-49B0-9BD3-662F57024D01}.Debug|ARM64.Build.0 = Debug|Any CPU\r\n\t\t{C54F80ED-B736-49B0-9BD3-662F57024D01}.Debug|x64.ActiveCfg = Debug|Any CPU\r\n\t\t{C54F80ED-B736-49B0-9BD3-662F57024D01}.Debug|x64.Build.0 = Debug|Any CPU\r\n\t\t{C54F80ED-B736-49B0-9BD3-662F57024D01}.Debug|x86.ActiveCfg = Debug|Any CPU\r\n\t\t{C54F80ED-B736-49B0-9BD3-662F57024D01}.Debug|x86.Build.0 = Debug|Any CPU\r\n\t\t{C54F80ED-B736-49B0-9BD3-662F57024D01}.Fuzzing|ARM64.ActiveCfg = Release|Any CPU\r\n\t\t{C54F80ED-B736-49B0-9BD3-662F57024D01}.Fuzzing|x64.ActiveCfg = Release|Any CPU\r\n\t\t{C54F80ED-B736-49B0-9BD3-662F57024D01}.Fuzzing|x86.ActiveCfg = Release|Any CPU\r\n\t\t{C54F80ED-B736-49B0-9BD3-662F57024D01}.Release|ARM64.ActiveCfg = Release|Any CPU\r\n\t\t{C54F80ED-B736-49B0-9BD3-662F57024D01}.Release|ARM64.Build.0 = Release|Any CPU\r\n\t\t{C54F80ED-B736-49B0-9BD3-662F57024D01}.Release|x64.ActiveCfg = Release|Any CPU\r\n\t\t{C54F80ED-B736-49B0-9BD3-662F57024D01}.Release|x64.Build.0 = Release|Any CPU\r\n\t\t{C54F80ED-B736-49B0-9BD3-662F57024D01}.Release|x86.ActiveCfg = Release|Any CPU\r\n\t\t{C54F80ED-B736-49B0-9BD3-662F57024D01}.Release|x86.Build.0 = Release|Any CPU\r\n\t\t{C54F80ED-B736-49B0-9BD3-662F57024D01}.ReleaseStatic|ARM64.ActiveCfg = ReleaseStatic|Any CPU\r\n\t\t{C54F80ED-B736-49B0-9BD3-662F57024D01}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|Any CPU\r\n\t\t{C54F80ED-B736-49B0-9BD3-662F57024D01}.ReleaseStatic|x64.Build.0 = ReleaseStatic|Any CPU\r\n\t\t{C54F80ED-B736-49B0-9BD3-662F57024D01}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Any CPU\r\n\t\t{C54F80ED-B736-49B0-9BD3-662F57024D01}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Any CPU\r\n\t\t{2268D5AD-7F2A-485A-8C4B-C574497514C9}.Debug|ARM64.ActiveCfg = Debug|ARM64\r\n\t\t{2268D5AD-7F2A-485A-8C4B-C574497514C9}.Debug|ARM64.Build.0 = Debug|ARM64\r\n\t\t{2268D5AD-7F2A-485A-8C4B-C574497514C9}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{2268D5AD-7F2A-485A-8C4B-C574497514C9}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{2268D5AD-7F2A-485A-8C4B-C574497514C9}.Debug|x86.ActiveCfg = Debug|Win32\r\n\t\t{2268D5AD-7F2A-485A-8C4B-C574497514C9}.Debug|x86.Build.0 = Debug|Win32\r\n\t\t{2268D5AD-7F2A-485A-8C4B-C574497514C9}.Fuzzing|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{2268D5AD-7F2A-485A-8C4B-C574497514C9}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{2268D5AD-7F2A-485A-8C4B-C574497514C9}.Fuzzing|x86.ActiveCfg = Release|Win32\r\n\t\t{2268D5AD-7F2A-485A-8C4B-C574497514C9}.Release|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{2268D5AD-7F2A-485A-8C4B-C574497514C9}.Release|ARM64.Build.0 = Release|ARM64\r\n\t\t{2268D5AD-7F2A-485A-8C4B-C574497514C9}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{2268D5AD-7F2A-485A-8C4B-C574497514C9}.Release|x64.Build.0 = Release|x64\r\n\t\t{2268D5AD-7F2A-485A-8C4B-C574497514C9}.Release|x86.ActiveCfg = Release|Win32\r\n\t\t{2268D5AD-7F2A-485A-8C4B-C574497514C9}.Release|x86.Build.0 = Release|Win32\r\n\t\t{2268D5AD-7F2A-485A-8C4B-C574497514C9}.ReleaseStatic|ARM64.ActiveCfg = ReleaseStatic|ARM64\r\n\t\t{2268D5AD-7F2A-485A-8C4B-C574497514C9}.ReleaseStatic|ARM64.Build.0 = ReleaseStatic|ARM64\r\n\t\t{2268D5AD-7F2A-485A-8C4B-C574497514C9}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64\r\n\t\t{2268D5AD-7F2A-485A-8C4B-C574497514C9}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64\r\n\t\t{2268D5AD-7F2A-485A-8C4B-C574497514C9}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32\r\n\t\t{2268D5AD-7F2A-485A-8C4B-C574497514C9}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32\r\n\t\t{52EC37D6-088C-40D3-AD0B-BDE8F8DAF9EB}.Debug|ARM64.ActiveCfg = Debug|Any CPU\r\n\t\t{52EC37D6-088C-40D3-AD0B-BDE8F8DAF9EB}.Debug|ARM64.Build.0 = Debug|Any CPU\r\n\t\t{52EC37D6-088C-40D3-AD0B-BDE8F8DAF9EB}.Debug|x64.ActiveCfg = Debug|Any CPU\r\n\t\t{52EC37D6-088C-40D3-AD0B-BDE8F8DAF9EB}.Debug|x64.Build.0 = Debug|Any CPU\r\n\t\t{52EC37D6-088C-40D3-AD0B-BDE8F8DAF9EB}.Debug|x86.ActiveCfg = Debug|Any CPU\r\n\t\t{52EC37D6-088C-40D3-AD0B-BDE8F8DAF9EB}.Debug|x86.Build.0 = Debug|Any CPU\r\n\t\t{52EC37D6-088C-40D3-AD0B-BDE8F8DAF9EB}.Fuzzing|ARM64.ActiveCfg = Release|Any CPU\r\n\t\t{52EC37D6-088C-40D3-AD0B-BDE8F8DAF9EB}.Fuzzing|x64.ActiveCfg = Release|Any CPU\r\n\t\t{52EC37D6-088C-40D3-AD0B-BDE8F8DAF9EB}.Fuzzing|x86.ActiveCfg = Release|Any CPU\r\n\t\t{52EC37D6-088C-40D3-AD0B-BDE8F8DAF9EB}.Release|ARM64.ActiveCfg = Release|Any CPU\r\n\t\t{52EC37D6-088C-40D3-AD0B-BDE8F8DAF9EB}.Release|ARM64.Build.0 = Release|Any CPU\r\n\t\t{52EC37D6-088C-40D3-AD0B-BDE8F8DAF9EB}.Release|x64.ActiveCfg = Release|Any CPU\r\n\t\t{52EC37D6-088C-40D3-AD0B-BDE8F8DAF9EB}.Release|x64.Build.0 = Release|Any CPU\r\n\t\t{52EC37D6-088C-40D3-AD0B-BDE8F8DAF9EB}.Release|x86.ActiveCfg = Release|Any CPU\r\n\t\t{52EC37D6-088C-40D3-AD0B-BDE8F8DAF9EB}.Release|x86.Build.0 = Release|Any CPU\r\n\t\t{52EC37D6-088C-40D3-AD0B-BDE8F8DAF9EB}.ReleaseStatic|ARM64.ActiveCfg = Release|Any CPU\r\n\t\t{52EC37D6-088C-40D3-AD0B-BDE8F8DAF9EB}.ReleaseStatic|x64.ActiveCfg = Release|Any CPU\r\n\t\t{52EC37D6-088C-40D3-AD0B-BDE8F8DAF9EB}.ReleaseStatic|x86.ActiveCfg = Release|Any CPU\r\n\t\t{272B2B0E-40D4-4F0F-B187-519A6EF89B10}.Debug|ARM64.ActiveCfg = Debug|Any CPU\r\n\t\t{272B2B0E-40D4-4F0F-B187-519A6EF89B10}.Debug|ARM64.Build.0 = Debug|Any CPU\r\n\t\t{272B2B0E-40D4-4F0F-B187-519A6EF89B10}.Debug|x64.ActiveCfg = Debug|Any CPU\r\n\t\t{272B2B0E-40D4-4F0F-B187-519A6EF89B10}.Debug|x64.Build.0 = Debug|Any CPU\r\n\t\t{272B2B0E-40D4-4F0F-B187-519A6EF89B10}.Debug|x86.ActiveCfg = Debug|Any CPU\r\n\t\t{272B2B0E-40D4-4F0F-B187-519A6EF89B10}.Debug|x86.Build.0 = Debug|Any CPU\r\n\t\t{272B2B0E-40D4-4F0F-B187-519A6EF89B10}.Fuzzing|ARM64.ActiveCfg = Release|Any CPU\r\n\t\t{272B2B0E-40D4-4F0F-B187-519A6EF89B10}.Fuzzing|x64.ActiveCfg = Release|Any CPU\r\n\t\t{272B2B0E-40D4-4F0F-B187-519A6EF89B10}.Fuzzing|x86.ActiveCfg = Release|Any CPU\r\n\t\t{272B2B0E-40D4-4F0F-B187-519A6EF89B10}.Release|ARM64.ActiveCfg = Release|Any CPU\r\n\t\t{272B2B0E-40D4-4F0F-B187-519A6EF89B10}.Release|ARM64.Build.0 = Release|Any CPU\r\n\t\t{272B2B0E-40D4-4F0F-B187-519A6EF89B10}.Release|x64.ActiveCfg = Release|Any CPU\r\n\t\t{272B2B0E-40D4-4F0F-B187-519A6EF89B10}.Release|x64.Build.0 = Release|Any CPU\r\n\t\t{272B2B0E-40D4-4F0F-B187-519A6EF89B10}.Release|x86.ActiveCfg = Release|Any CPU\r\n\t\t{272B2B0E-40D4-4F0F-B187-519A6EF89B10}.Release|x86.Build.0 = Release|Any CPU\r\n\t\t{272B2B0E-40D4-4F0F-B187-519A6EF89B10}.ReleaseStatic|ARM64.ActiveCfg = ReleaseStatic|Any CPU\r\n\t\t{272B2B0E-40D4-4F0F-B187-519A6EF89B10}.ReleaseStatic|ARM64.Build.0 = ReleaseStatic|Any CPU\r\n\t\t{272B2B0E-40D4-4F0F-B187-519A6EF89B10}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|Any CPU\r\n\t\t{272B2B0E-40D4-4F0F-B187-519A6EF89B10}.ReleaseStatic|x64.Build.0 = ReleaseStatic|Any CPU\r\n\t\t{272B2B0E-40D4-4F0F-B187-519A6EF89B10}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Any CPU\r\n\t\t{272B2B0E-40D4-4F0F-B187-519A6EF89B10}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Any CPU\r\n\t\t{1B9077B3-8923-4ECD-8FC9-B3190FCBE4D4}.Debug|ARM64.ActiveCfg = Debug|ARM64\r\n\t\t{1B9077B3-8923-4ECD-8FC9-B3190FCBE4D4}.Debug|ARM64.Build.0 = Debug|ARM64\r\n\t\t{1B9077B3-8923-4ECD-8FC9-B3190FCBE4D4}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{1B9077B3-8923-4ECD-8FC9-B3190FCBE4D4}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{1B9077B3-8923-4ECD-8FC9-B3190FCBE4D4}.Debug|x86.ActiveCfg = Debug|Win32\r\n\t\t{1B9077B3-8923-4ECD-8FC9-B3190FCBE4D4}.Debug|x86.Build.0 = Debug|Win32\r\n\t\t{1B9077B3-8923-4ECD-8FC9-B3190FCBE4D4}.Fuzzing|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{1B9077B3-8923-4ECD-8FC9-B3190FCBE4D4}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{1B9077B3-8923-4ECD-8FC9-B3190FCBE4D4}.Fuzzing|x86.ActiveCfg = Release|Win32\r\n\t\t{1B9077B3-8923-4ECD-8FC9-B3190FCBE4D4}.Release|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{1B9077B3-8923-4ECD-8FC9-B3190FCBE4D4}.Release|ARM64.Build.0 = Release|ARM64\r\n\t\t{1B9077B3-8923-4ECD-8FC9-B3190FCBE4D4}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{1B9077B3-8923-4ECD-8FC9-B3190FCBE4D4}.Release|x64.Build.0 = Release|x64\r\n\t\t{1B9077B3-8923-4ECD-8FC9-B3190FCBE4D4}.Release|x86.ActiveCfg = Release|Win32\r\n\t\t{1B9077B3-8923-4ECD-8FC9-B3190FCBE4D4}.Release|x86.Build.0 = Release|Win32\r\n\t\t{1B9077B3-8923-4ECD-8FC9-B3190FCBE4D4}.ReleaseStatic|ARM64.ActiveCfg = ReleaseStatic|ARM64\r\n\t\t{1B9077B3-8923-4ECD-8FC9-B3190FCBE4D4}.ReleaseStatic|ARM64.Build.0 = ReleaseStatic|ARM64\r\n\t\t{1B9077B3-8923-4ECD-8FC9-B3190FCBE4D4}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64\r\n\t\t{1B9077B3-8923-4ECD-8FC9-B3190FCBE4D4}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64\r\n\t\t{1B9077B3-8923-4ECD-8FC9-B3190FCBE4D4}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32\r\n\t\t{1B9077B3-8923-4ECD-8FC9-B3190FCBE4D4}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32\r\n\t\t{0BA531C8-CF0C-405B-8221-0FE51BA529D1}.Debug|ARM64.ActiveCfg = Debug|ARM64\r\n\t\t{0BA531C8-CF0C-405B-8221-0FE51BA529D1}.Debug|ARM64.Build.0 = Debug|ARM64\r\n\t\t{0BA531C8-CF0C-405B-8221-0FE51BA529D1}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{0BA531C8-CF0C-405B-8221-0FE51BA529D1}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{0BA531C8-CF0C-405B-8221-0FE51BA529D1}.Debug|x86.ActiveCfg = Debug|Win32\r\n\t\t{0BA531C8-CF0C-405B-8221-0FE51BA529D1}.Debug|x86.Build.0 = Debug|Win32\r\n\t\t{0BA531C8-CF0C-405B-8221-0FE51BA529D1}.Fuzzing|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{0BA531C8-CF0C-405B-8221-0FE51BA529D1}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{0BA531C8-CF0C-405B-8221-0FE51BA529D1}.Fuzzing|x86.ActiveCfg = Release|Win32\r\n\t\t{0BA531C8-CF0C-405B-8221-0FE51BA529D1}.Release|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{0BA531C8-CF0C-405B-8221-0FE51BA529D1}.Release|ARM64.Build.0 = Release|ARM64\r\n\t\t{0BA531C8-CF0C-405B-8221-0FE51BA529D1}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{0BA531C8-CF0C-405B-8221-0FE51BA529D1}.Release|x64.Build.0 = Release|x64\r\n\t\t{0BA531C8-CF0C-405B-8221-0FE51BA529D1}.Release|x86.ActiveCfg = Release|Win32\r\n\t\t{0BA531C8-CF0C-405B-8221-0FE51BA529D1}.Release|x86.Build.0 = Release|Win32\r\n\t\t{0BA531C8-CF0C-405B-8221-0FE51BA529D1}.ReleaseStatic|ARM64.ActiveCfg = ReleaseStatic|ARM64\r\n\t\t{0BA531C8-CF0C-405B-8221-0FE51BA529D1}.ReleaseStatic|ARM64.Build.0 = ReleaseStatic|ARM64\r\n\t\t{0BA531C8-CF0C-405B-8221-0FE51BA529D1}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64\r\n\t\t{0BA531C8-CF0C-405B-8221-0FE51BA529D1}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64\r\n\t\t{0BA531C8-CF0C-405B-8221-0FE51BA529D1}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32\r\n\t\t{0BA531C8-CF0C-405B-8221-0FE51BA529D1}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32\r\n\t\t{9406322E-6272-487E-902A-9953889719EA}.Debug|ARM64.ActiveCfg = Debug|Any CPU\r\n\t\t{9406322E-6272-487E-902A-9953889719EA}.Debug|ARM64.Build.0 = Debug|Any CPU\r\n\t\t{9406322E-6272-487E-902A-9953889719EA}.Debug|x64.ActiveCfg = Debug|Any CPU\r\n\t\t{9406322E-6272-487E-902A-9953889719EA}.Debug|x64.Build.0 = Debug|Any CPU\r\n\t\t{9406322E-6272-487E-902A-9953889719EA}.Debug|x86.ActiveCfg = Debug|Any CPU\r\n\t\t{9406322E-6272-487E-902A-9953889719EA}.Debug|x86.Build.0 = Debug|Any CPU\r\n\t\t{9406322E-6272-487E-902A-9953889719EA}.Fuzzing|ARM64.ActiveCfg = Debug|Any CPU\r\n\t\t{9406322E-6272-487E-902A-9953889719EA}.Fuzzing|x64.ActiveCfg = Debug|Any CPU\r\n\t\t{9406322E-6272-487E-902A-9953889719EA}.Fuzzing|x86.ActiveCfg = Debug|Any CPU\r\n\t\t{9406322E-6272-487E-902A-9953889719EA}.Release|ARM64.ActiveCfg = Release|Any CPU\r\n\t\t{9406322E-6272-487E-902A-9953889719EA}.Release|ARM64.Build.0 = Release|Any CPU\r\n\t\t{9406322E-6272-487E-902A-9953889719EA}.Release|x64.ActiveCfg = Release|Any CPU\r\n\t\t{9406322E-6272-487E-902A-9953889719EA}.Release|x64.Build.0 = Release|Any CPU\r\n\t\t{9406322E-6272-487E-902A-9953889719EA}.Release|x86.ActiveCfg = Release|Any CPU\r\n\t\t{9406322E-6272-487E-902A-9953889719EA}.Release|x86.Build.0 = Release|Any CPU\r\n\t\t{9406322E-6272-487E-902A-9953889719EA}.ReleaseStatic|ARM64.ActiveCfg = ReleaseStatic|Any CPU\r\n\t\t{9406322E-6272-487E-902A-9953889719EA}.ReleaseStatic|ARM64.Build.0 = ReleaseStatic|Any CPU\r\n\t\t{9406322E-6272-487E-902A-9953889719EA}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|Any CPU\r\n\t\t{9406322E-6272-487E-902A-9953889719EA}.ReleaseStatic|x64.Build.0 = ReleaseStatic|Any CPU\r\n\t\t{9406322E-6272-487E-902A-9953889719EA}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Any CPU\r\n\t\t{9406322E-6272-487E-902A-9953889719EA}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Any CPU\r\n\t\t{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Debug|ARM64.ActiveCfg = Debug|arm64\r\n\t\t{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Debug|ARM64.Build.0 = Debug|arm64\r\n\t\t{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Debug|x86.ActiveCfg = Debug|x86\r\n\t\t{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Debug|x86.Build.0 = Debug|x86\r\n\t\t{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Fuzzing|ARM64.ActiveCfg = Release|arm64\r\n\t\t{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Fuzzing|x86.ActiveCfg = Release|x86\r\n\t\t{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Release|ARM64.ActiveCfg = Release|arm64\r\n\t\t{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Release|ARM64.Build.0 = Release|arm64\r\n\t\t{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Release|x64.Build.0 = Release|x64\r\n\t\t{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Release|x86.ActiveCfg = Release|x86\r\n\t\t{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Release|x86.Build.0 = Release|x86\r\n\t\t{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.ReleaseStatic|ARM64.ActiveCfg = Release|arm64\r\n\t\t{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.ReleaseStatic|x64.ActiveCfg = Release|x64\r\n\t\t{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.ReleaseStatic|x86.ActiveCfg = Release|x86\r\n\t\t{33745E4A-39E2-676F-7E23-50FB43848D25}.Debug|ARM64.ActiveCfg = Debug|arm64\r\n\t\t{33745E4A-39E2-676F-7E23-50FB43848D25}.Debug|ARM64.Build.0 = Debug|arm64\r\n\t\t{33745E4A-39E2-676F-7E23-50FB43848D25}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{33745E4A-39E2-676F-7E23-50FB43848D25}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{33745E4A-39E2-676F-7E23-50FB43848D25}.Debug|x86.ActiveCfg = Debug|x86\r\n\t\t{33745E4A-39E2-676F-7E23-50FB43848D25}.Debug|x86.Build.0 = Debug|x86\r\n\t\t{33745E4A-39E2-676F-7E23-50FB43848D25}.Fuzzing|ARM64.ActiveCfg = Release|arm64\r\n\t\t{33745E4A-39E2-676F-7E23-50FB43848D25}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{33745E4A-39E2-676F-7E23-50FB43848D25}.Fuzzing|x86.ActiveCfg = Release|x86\r\n\t\t{33745E4A-39E2-676F-7E23-50FB43848D25}.Release|ARM64.ActiveCfg = Release|arm64\r\n\t\t{33745E4A-39E2-676F-7E23-50FB43848D25}.Release|ARM64.Build.0 = Release|arm64\r\n\t\t{33745E4A-39E2-676F-7E23-50FB43848D25}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{33745E4A-39E2-676F-7E23-50FB43848D25}.Release|x64.Build.0 = Release|x64\r\n\t\t{33745E4A-39E2-676F-7E23-50FB43848D25}.Release|x86.ActiveCfg = Release|x86\r\n\t\t{33745E4A-39E2-676F-7E23-50FB43848D25}.Release|x86.Build.0 = Release|x86\r\n\t\t{33745E4A-39E2-676F-7E23-50FB43848D25}.ReleaseStatic|ARM64.ActiveCfg = Release|arm64\r\n\t\t{33745E4A-39E2-676F-7E23-50FB43848D25}.ReleaseStatic|ARM64.Build.0 = Release|arm64\r\n\t\t{33745E4A-39E2-676F-7E23-50FB43848D25}.ReleaseStatic|x64.ActiveCfg = Release|x64\r\n\t\t{33745E4A-39E2-676F-7E23-50FB43848D25}.ReleaseStatic|x64.Build.0 = Release|x64\r\n\t\t{33745E4A-39E2-676F-7E23-50FB43848D25}.ReleaseStatic|x86.ActiveCfg = Release|x86\r\n\t\t{33745E4A-39E2-676F-7E23-50FB43848D25}.ReleaseStatic|x86.Build.0 = Release|x86\r\n\t\t{E5BCFF58-7D0C-4770-ABB9-AECE1027CD94}.Debug|ARM64.ActiveCfg = Debug|ARM64\r\n\t\t{E5BCFF58-7D0C-4770-ABB9-AECE1027CD94}.Debug|ARM64.Build.0 = Debug|ARM64\r\n\t\t{E5BCFF58-7D0C-4770-ABB9-AECE1027CD94}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{E5BCFF58-7D0C-4770-ABB9-AECE1027CD94}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{E5BCFF58-7D0C-4770-ABB9-AECE1027CD94}.Debug|x86.ActiveCfg = Debug|Win32\r\n\t\t{E5BCFF58-7D0C-4770-ABB9-AECE1027CD94}.Debug|x86.Build.0 = Debug|Win32\r\n\t\t{E5BCFF58-7D0C-4770-ABB9-AECE1027CD94}.Fuzzing|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{E5BCFF58-7D0C-4770-ABB9-AECE1027CD94}.Fuzzing|x64.ActiveCfg = Release|x64\r\n\t\t{E5BCFF58-7D0C-4770-ABB9-AECE1027CD94}.Fuzzing|x86.ActiveCfg = Release|Win32\r\n\t\t{E5BCFF58-7D0C-4770-ABB9-AECE1027CD94}.Release|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{E5BCFF58-7D0C-4770-ABB9-AECE1027CD94}.Release|ARM64.Build.0 = Release|ARM64\r\n\t\t{E5BCFF58-7D0C-4770-ABB9-AECE1027CD94}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{E5BCFF58-7D0C-4770-ABB9-AECE1027CD94}.Release|x64.Build.0 = Release|x64\r\n\t\t{E5BCFF58-7D0C-4770-ABB9-AECE1027CD94}.Release|x86.ActiveCfg = Release|Win32\r\n\t\t{E5BCFF58-7D0C-4770-ABB9-AECE1027CD94}.Release|x86.Build.0 = Release|Win32\r\n\t\t{E5BCFF58-7D0C-4770-ABB9-AECE1027CD94}.ReleaseStatic|ARM64.ActiveCfg = Release|ARM64\r\n\t\t{E5BCFF58-7D0C-4770-ABB9-AECE1027CD94}.ReleaseStatic|x64.ActiveCfg = Release|x64\r\n\t\t{E5BCFF58-7D0C-4770-ABB9-AECE1027CD94}.ReleaseStatic|x86.ActiveCfg = Release|Win32\r\n\t\t{5421394F-5619-4E4B-8923-F3FB30D5EFAD}.Debug|ARM64.ActiveCfg = Debug|Any CPU\r\n\t\t{5421394F-5619-4E4B-8923-F3FB30D5EFAD}.Debug|ARM64.Build.0 = Debug|Any CPU\r\n\t\t{5421394F-5619-4E4B-8923-F3FB30D5EFAD}.Debug|x64.ActiveCfg = Debug|Any CPU\r\n\t\t{5421394F-5619-4E4B-8923-F3FB30D5EFAD}.Debug|x64.Build.0 = Debug|Any CPU\r\n\t\t{5421394F-5619-4E4B-8923-F3FB30D5EFAD}.Debug|x86.ActiveCfg = Debug|Any CPU\r\n\t\t{5421394F-5619-4E4B-8923-F3FB30D5EFAD}.Debug|x86.Build.0 = Debug|Any CPU\r\n\t\t{5421394F-5619-4E4B-8923-F3FB30D5EFAD}.Fuzzing|ARM64.ActiveCfg = Release|Any CPU\r\n\t\t{5421394F-5619-4E4B-8923-F3FB30D5EFAD}.Fuzzing|x64.ActiveCfg = Release|Any CPU\r\n\t\t{5421394F-5619-4E4B-8923-F3FB30D5EFAD}.Fuzzing|x86.ActiveCfg = Release|Any CPU\r\n\t\t{5421394F-5619-4E4B-8923-F3FB30D5EFAD}.Release|ARM64.ActiveCfg = Release|Any CPU\r\n\t\t{5421394F-5619-4E4B-8923-F3FB30D5EFAD}.Release|ARM64.Build.0 = Release|Any CPU\r\n\t\t{5421394F-5619-4E4B-8923-F3FB30D5EFAD}.Release|x64.ActiveCfg = Release|Any CPU\r\n\t\t{5421394F-5619-4E4B-8923-F3FB30D5EFAD}.Release|x64.Build.0 = Release|Any CPU\r\n\t\t{5421394F-5619-4E4B-8923-F3FB30D5EFAD}.Release|x86.ActiveCfg = Release|Any CPU\r\n\t\t{5421394F-5619-4E4B-8923-F3FB30D5EFAD}.Release|x86.Build.0 = Release|Any CPU\r\n\t\t{5421394F-5619-4E4B-8923-F3FB30D5EFAD}.ReleaseStatic|ARM64.ActiveCfg = Release|Any CPU\r\n\t\t{5421394F-5619-4E4B-8923-F3FB30D5EFAD}.ReleaseStatic|x64.ActiveCfg = Release|Any CPU\r\n\t\t{5421394F-5619-4E4B-8923-F3FB30D5EFAD}.ReleaseStatic|x86.ActiveCfg = Release|Any CPU\r\n\tEndGlobalSection\r\n\tGlobalSection(SolutionProperties) = preSolution\r\n\t\tHideSolutionNode = FALSE\r\n\tEndGlobalSection\r\n\tGlobalSection(NestedProjects) = preSolution\r\n\t\t{89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}\r\n\t\t{6CB84692-5994-407D-B9BD-9216AF77FE83} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}\r\n\t\t{6E36DDD7-1602-474E-B1D7-D0A7E1D5AD86} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7}\r\n\t\t{3C0269FA-E582-4CA7-9E33-3881A005CA0C} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}\r\n\t\t{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}\r\n\t\t{C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}\r\n\t\t{3B8466CF-4FDD-4329-9C80-91321C4AAC99} = {EA8CD934-0702-4911-A2C5-A40600E616DE}\r\n\t\t{1622DA16-914F-4F57-A259-D5169003CC8C} = {6D7776A8-42FE-46DD-B0F8-712F35EA0C79}\r\n\t\t{3BAF989F-7F65-465B-ACE8-BAFE42D1017E} = {EA8CD934-0702-4911-A2C5-A40600E616DE}\r\n\t\t{7D05F64D-CE5A-42AA-A2C1-E91458F061CF} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7}\r\n\t\t{952B513F-8A00-4D74-9271-925AFB3C6252} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7}\r\n\t\t{2ACDE176-F13F-42FA-8159-C34FA3D37837} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7}\r\n\t\t{1A47951F-5C7A-4D6D-BB5F-D77484437940} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7}\r\n\t\t{68808357-902B-406C-8C19-E8E26A69DE8A} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}\r\n\t\t{409CD681-22A4-469D-88AE-CB5E4836E07A} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7}\r\n\t\t{B0BBBD92-943B-408F-B2B2-DBBAB4A22D23} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7}\r\n\t\t{463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C} = {7C218A3E-9BC8-48FF-B91B-BCACD828C0C9}\r\n\t\t{31ED69A8-5310-45A9-953F-56C351D2C3E1} = {60618CAC-2995-4DF9-9914-45C6FC02C995}\r\n\t\t{8E43F982-40D5-4DF1-9044-C08047B5F43B} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7}\r\n\t\t{EE43C990-7789-4A60-B077-BF0ED3D093A1} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}\r\n\t\t{1F56BECB-D65D-4BBA-8788-6671B251392A} = {7C218A3E-9BC8-48FF-B91B-BCACD828C0C9}\r\n\t\t{167F634B-A3AD-494E-8E67-B888103E35FF} = {7C218A3E-9BC8-48FF-B91B-BCACD828C0C9}\r\n\t\t{C54F80ED-B736-49B0-9BD3-662F57024D01} = {7C218A3E-9BC8-48FF-B91B-BCACD828C0C9}\r\n\t\t{272B2B0E-40D4-4F0F-B187-519A6EF89B10} = {7C218A3E-9BC8-48FF-B91B-BCACD828C0C9}\r\n\t\t{5A52D9FC-0059-4A4A-8196-427A7AA0D1C5} = {7C218A3E-9BC8-48FF-B91B-BCACD828C0C9}\r\n\t\t{1B9077B3-8923-4ECD-8FC9-B3190FCBE4D4} = {60618CAC-2995-4DF9-9914-45C6FC02C995}\r\n\t\t{76B26B2C-602A-4AD0-9736-4162D3FCA92A} = {1A5D7A7D-5CB2-47D5-B40D-4E61CAEDC798}\r\n\t\t{A0B4F808-B190-41C4-97CB-C8EA1932F84F} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7}\r\n\t\t{A33223D2-550B-4D99-A53D-488B1F68683E} = {60618CAC-2995-4DF9-9914-45C6FC02C995}\r\n\t\t{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}\r\n\t\t{F49C4C89-447E-4D15-B38B-5A8DCFB134AF} = {7C218A3E-9BC8-48FF-B91B-BCACD828C0C9}\r\n\t\t{E5BCFF58-7D0C-4770-ABB9-AECE1027CD94} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}\r\n\t\t{40D7CA7F-EB86-4345-9641-AD27180C559D} = {7C218A3E-9BC8-48FF-B91B-BCACD828C0C9}\r\n\t\t{5421394F-5619-4E4B-8923-F3FB30D5EFAD} = {7C218A3E-9BC8-48FF-B91B-BCACD828C0C9}\r\n\t\t{B978E358-D2BE-4FA7-A21A-6661F3744DD7} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7}\r\n\tEndGlobalSection\r\n\tGlobalSection(ExtensibilityGlobals) = postSolution\r\n\t\tSolutionGuid = {B6FDB70C-A751-422C-ACD1-E35419495857}\r\n\tEndGlobalSection\r\n\tGlobalSection(SharedMSBuildProjectFiles) = preSolution\r\n\t\tManifestSchema\\ManifestSchema.vcxitems*{1622da16-914f-4f57-a259-d5169003cc8c}*SharedItemsImports = 4\r\n\t\tWinGetSchemas\\WinGetSchemas.vcxitems*{1c6e0108-2860-4b17-9f7e-fa5c6c1f3d3d}*SharedItemsImports = 4\r\n\t\tCOMServer\\COMServer.vcxitems*{1cc41a9a-ae66-459d-9210-1e572dd7be69}*SharedItemsImports = 4\r\n\t\tbinver\\binver.vcxitems*{2046b5af-666d-4ce8-8d3e-c32c57908a56}*SharedItemsImports = 4\r\n\t\tCertificateResources\\CertificateResources.vcxitems*{2046b5af-666d-4ce8-8d3e-c32c57908a56}*SharedItemsImports = 4\r\n\t\tCOMServer\\COMServer.vcxitems*{2046b5af-666d-4ce8-8d3e-c32c57908a56}*SharedItemsImports = 4\r\n\t\tManifestSchema\\ManifestSchema.vcxitems*{2046b5af-666d-4ce8-8d3e-c32c57908a56}*SharedItemsImports = 4\r\n\t\tWinGetSchemas\\WinGetSchemas.vcxitems*{2046b5af-666d-4ce8-8d3e-c32c57908a56}*SharedItemsImports = 4\r\n\t\tCOMServer\\COMServer.vcxitems*{409cd681-22a4-469d-88ae-cb5e4836e07a}*SharedItemsImports = 9\r\n\t\tCertificateResources\\CertificateResources.vcxitems*{5890d6ed-7c3b-40f3-b436-b54f640d9e65}*SharedItemsImports = 4\r\n\t\tCOMServer\\COMServer.vcxitems*{5890d6ed-7c3b-40f3-b436-b54f640d9e65}*SharedItemsImports = 4\r\n\t\tManifestSchema\\ManifestSchema.vcxitems*{5890d6ed-7c3b-40f3-b436-b54f640d9e65}*SharedItemsImports = 4\r\n\t\tPureLib\\PureLib.vcxitems*{5890d6ed-7c3b-40f3-b436-b54f640d9e65}*SharedItemsImports = 4\r\n\t\tbinver\\binver.vcxitems*{5b6f90df-fd19-4bae-83d9-24dad128e777}*SharedItemsImports = 4\r\n\t\tCertificateResources\\CertificateResources.vcxitems*{5eb88068-5fb9-4e69-89b2-72dbc5e068f9}*SharedItemsImports = 4\r\n\t\tbinver\\binver.vcxitems*{6e36ddd7-1602-474e-b1d7-d0a7e1d5ad86}*SharedItemsImports = 9\r\n\t\tManifestSchema\\ManifestSchema.vcxitems*{7d05f64d-ce5a-42aa-a2c1-e91458f061cf}*SharedItemsImports = 9\r\n\t\tCertificateResources\\CertificateResources.vcxitems*{89b1aab4-2bbc-4b65-9ed7-a01d5cf88230}*SharedItemsImports = 4\r\n\t\tManifestSchema\\ManifestSchema.vcxitems*{89b1aab4-2bbc-4b65-9ed7-a01d5cf88230}*SharedItemsImports = 4\r\n\t\tWinGetSchemas\\WinGetSchemas.vcxitems*{89b1aab4-2bbc-4b65-9ed7-a01d5cf88230}*SharedItemsImports = 4\r\n\t\tWinGetSchemas\\WinGetSchemas.vcxitems*{952b513f-8a00-4d74-9271-925afb3c6252}*SharedItemsImports = 9\r\n\t\tPureLib\\PureLib.vcxitems*{a33223d2-550b-4d99-a53d-488b1f68683e}*SharedItemsImports = 9\r\n\t\tCertificateResources\\CertificateResources.vcxitems*{b0bbbd92-943b-408f-b2b2-dbbab4a22d23}*SharedItemsImports = 9\r\n\t\tbinver\\binver.vcxitems*{fb313532-38b0-4676-9303-ab200aa13576}*SharedItemsImports = 4\r\n\t\tManifestSchema\\ManifestSchema.vcxitems*{fb313532-38b0-4676-9303-ab200aa13576}*SharedItemsImports = 4\r\n\tEndGlobalSection\r\nEndGlobal\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/AppInstallerCLICore.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" />\r\n  <PropertyGroup Label=\"Globals\">\r\n    <CppWinRTOptimized>true</CppWinRTOptimized>\r\n    <CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>\r\n    <MinimalCoreWin>true</MinimalCoreWin>\r\n    <VCProjectVersion>15.0</VCProjectVersion>\r\n    <ProjectGuid>{1c6e0108-2860-4b17-9f7e-fa5c6c1f3d3d}</ProjectGuid>\r\n    <Keyword>Win32Proj</Keyword>\r\n    <RootNamespace>AppInstallerCLICore</RootNamespace>\r\n    <WindowsTargetPlatformVersion>10.0.26100.0</WindowsTargetPlatformVersion>\r\n    <WindowsTargetPlatformMinVersion>10.0.17763.0</WindowsTargetPlatformMinVersion>\r\n    <WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|ARM64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|Win32\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|ARM64\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|Win32\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|x64\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|ARM64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|Win32\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <PropertyGroup Label=\"Configuration\">\r\n    <ConfigurationType>StaticLibrary</ConfigurationType>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Debug'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n    <LinkIncremental>true</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Release'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <LinkIncremental>false</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='ReleaseStatic'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <LinkIncremental>false</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\" Label=\"Configuration\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\" Label=\"Configuration\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\" Label=\"Configuration\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\r\n  <ImportGroup Label=\"ExtensionSettings\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"Shared\">\r\n    <Import Project=\"..\\WinGetSchemas\\WinGetSchemas.vcxitems\" Label=\"Shared\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"PropertySheet.props\" />\r\n  </ImportGroup>\r\n  <PropertyGroup Label=\"UserMacros\" />\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>true</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>true</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>true</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(ProjectDir)\\..\\vcpkg.props\" />\r\n  <ItemDefinitionGroup>\r\n    <ClCompile>\r\n      <PrecompiledHeader>Use</PrecompiledHeader>\r\n      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>\r\n      <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>\r\n      <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <DisableSpecificWarnings>5321;%(DisableSpecificWarnings)</DisableSpecificWarnings>\r\n      <AdditionalOptions>%(AdditionalOptions) /permissive- /bigobj /D _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING</AdditionalOptions>\r\n    </ClCompile>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Debug'\">\r\n    <ClCompile>\r\n      <Optimization>Disabled</Optimization>\r\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">$(ProjectDir);$(ProjectDir)..\\AppInstallerRepositoryCore\\Public;$(ProjectDir)..\\AppInstallerCommonCore\\Public;$(ProjectDir)..\\AppInstallerSharedLib\\Public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">$(ProjectDir);$(ProjectDir)..\\AppInstallerRepositoryCore\\Public;$(ProjectDir)..\\AppInstallerCommonCore\\Public;$(ProjectDir)..\\AppInstallerSharedLib\\Public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</TreatWarningAsError>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</EnablePREfast>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">Windows</SubSystem>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Platform)'=='Win32'\">\r\n    <ClCompile>\r\n      <PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions);CLICOREDLLBUILD</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">$(ProjectDir);$(ProjectDir)..\\AppInstallerRepositoryCore\\Public;$(ProjectDir)..\\AppInstallerCommonCore\\Public;$(ProjectDir)..\\AppInstallerSharedLib\\Public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</TreatWarningAsError>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</EnablePREfast>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Windows</SubSystem>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Release'\">\r\n    <ClCompile>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">$(ProjectDir);$(ProjectDir)..\\AppInstallerRepositoryCore\\Public;$(ProjectDir)..\\AppInstallerCommonCore\\Public;$(ProjectDir)..\\AppInstallerSharedLib\\Public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">$(ProjectDir);$(ProjectDir)..\\AppInstallerRepositoryCore\\Public;$(ProjectDir)..\\AppInstallerCommonCore\\Public;$(ProjectDir)..\\AppInstallerSharedLib\\Public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">$(ProjectDir);$(ProjectDir)..\\AppInstallerRepositoryCore\\Public;$(ProjectDir)..\\AppInstallerCommonCore\\Public;$(ProjectDir)..\\AppInstallerSharedLib\\Public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">true</TreatWarningAsError>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</EnablePREfast>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Windows</SubSystem>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='ReleaseStatic'\">\r\n    <ClCompile>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">$(ProjectDir);$(ProjectDir)..\\AppInstallerRepositoryCore\\Public;$(ProjectDir)..\\AppInstallerCommonCore\\Public;$(ProjectDir)..\\AppInstallerSharedLib\\Public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">$(ProjectDir);$(ProjectDir)..\\AppInstallerRepositoryCore\\Public;$(ProjectDir)..\\AppInstallerCommonCore\\Public;$(ProjectDir)..\\AppInstallerSharedLib\\Public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">$(ProjectDir);$(ProjectDir)..\\AppInstallerRepositoryCore\\Public;$(ProjectDir)..\\AppInstallerCommonCore\\Public;$(ProjectDir)..\\AppInstallerSharedLib\\Public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">true</TreatWarningAsError>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">false</EnablePREfast>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">MultiThreaded</RuntimeLibrary>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">MultiThreaded</RuntimeLibrary>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">MultiThreaded</RuntimeLibrary>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">Windows</SubSystem>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"Argument.h\" />\r\n    <ClInclude Include=\"ChannelStreams.h\" />\r\n    <ClInclude Include=\"CheckpointManager.h\" />\r\n    <ClInclude Include=\"Command.h\" />\r\n    <ClInclude Include=\"Commands\\COMCommand.h\" />\r\n    <ClInclude Include=\"Commands\\CompleteCommand.h\" />\r\n    <ClInclude Include=\"Commands\\ConfigureCommand.h\" />\r\n    <ClInclude Include=\"Commands\\ConfigureListCommand.h\" />\r\n    <ClInclude Include=\"Commands\\ConfigureShowCommand.h\" />\r\n    <ClInclude Include=\"Commands\\ConfigureTestCommand.h\" />\r\n    <ClInclude Include=\"Commands\\ConfigureValidateCommand.h\" />\r\n    <ClInclude Include=\"Commands\\DebugCommand.h\" />\r\n    <ClInclude Include=\"Commands\\DownloadCommand.h\" />\r\n    <ClInclude Include=\"Commands\\DscAdminSettingsResource.h\" />\r\n    <ClInclude Include=\"Commands\\DscCommand.h\" />\r\n    <ClInclude Include=\"Commands\\DscCommandBase.h\" />\r\n    <ClInclude Include=\"Commands\\DscComposableObject.h\" />\r\n    <ClInclude Include=\"Commands\\DscPackageResource.h\" />\r\n    <ClInclude Include=\"Commands\\DscSourceResource.h\" />\r\n    <ClInclude Include=\"Commands\\DscTestFileResource.h\" />\r\n    <ClInclude Include=\"Commands\\DscTestJsonResource.h\" />\r\n    <ClInclude Include=\"Commands\\DscUserSettingsFileResource.h\" />\r\n    <ClInclude Include=\"Commands\\ErrorCommand.h\" />\r\n    <ClInclude Include=\"Commands\\ExperimentalCommand.h\" />\r\n    <ClInclude Include=\"Commands\\ExportCommand.h\" />\r\n    <ClInclude Include=\"Commands\\FontCommand.h\" />\r\n    <ClInclude Include=\"Commands\\ImportCommand.h\" />\r\n    <ClInclude Include=\"Commands\\FeaturesCommand.h\" />\r\n    <ClInclude Include=\"Commands\\HashCommand.h\" />\r\n    <ClInclude Include=\"Commands\\ListCommand.h\" />\r\n    <ClInclude Include=\"Commands\\McpCommand.h\" />\r\n    <ClInclude Include=\"Commands\\PinCommand.h\" />\r\n    <ClInclude Include=\"Commands\\RepairCommand.h\" />\r\n    <ClInclude Include=\"Commands\\SearchCommand.h\" />\r\n    <ClInclude Include=\"Commands\\ShowCommand.h\" />\r\n    <ClInclude Include=\"Commands\\InstallCommand.h\" />\r\n    <ClInclude Include=\"Commands\\RootCommand.h\" />\r\n    <ClInclude Include=\"Commands\\ResumeCommand.h\" />\r\n    <ClInclude Include=\"Commands\\SourceCommand.h\" />\r\n    <ClInclude Include=\"Commands\\TestCommand.h\" />\r\n    <ClInclude Include=\"Commands\\UninstallCommand.h\" />\r\n    <ClInclude Include=\"Commands\\UpgradeCommand.h\" />\r\n    <ClInclude Include=\"Commands\\ValidateCommand.h\" />\r\n    <ClInclude Include=\"Commands\\SettingsCommand.h\" />\r\n    <ClInclude Include=\"CompletionData.h\" />\r\n    <ClInclude Include=\"ConfigurationCommon.h\" />\r\n    <ClInclude Include=\"ConfigurationContext.h\" />\r\n    <ClInclude Include=\"ConfigurationWingetDscModuleUnitValidation.h\" />\r\n    <ClInclude Include=\"ConfigureExportCommand.h\" />\r\n    <ClInclude Include=\"ContextOrchestrator.h\" />\r\n    <ClInclude Include=\"COMContext.h\" />\r\n    <ClInclude Include=\"Public\\ConfigurationSetProcessorFactoryRemoting.h\" />\r\n    <ClInclude Include=\"Public\\ShutdownMonitoring.h\" />\r\n    <ClInclude Include=\"Sixel.h\" />\r\n    <ClInclude Include=\"Workflows\\ConfigurationFlow.h\" />\r\n    <ClInclude Include=\"Workflows\\DependenciesFlow.h\" />\r\n    <ClInclude Include=\"ExecutionArgs.h\" />\r\n    <ClInclude Include=\"ExecutionContextData.h\" />\r\n    <ClInclude Include=\"ExecutionContext.h\" />\r\n    <ClInclude Include=\"ExecutionProgress.h\" />\r\n    <ClInclude Include=\"ExecutionReporter.h\" />\r\n    <ClInclude Include=\"Invocation.h\" />\r\n    <ClInclude Include=\"pch.h\" />\r\n    <ClInclude Include=\"PortableInstaller.h\" />\r\n    <ClInclude Include=\"Public\\AppInstallerCLICore.h\" />\r\n    <ClInclude Include=\"Resources.h\" />\r\n    <ClInclude Include=\"Search\\Search.h\" />\r\n    <ClInclude Include=\"TableOutput.h\" />\r\n    <ClInclude Include=\"VTSupport.h\" />\r\n    <ClInclude Include=\"PackageCollection.h\" />\r\n    <ClInclude Include=\"Workflows\\ArchiveFlow.h\" />\r\n    <ClInclude Include=\"Workflows\\CompletionFlow.h\" />\r\n    <ClInclude Include=\"Workflows\\DependencyNodeProcessor.h\" />\r\n    <ClInclude Include=\"Workflows\\DownloadFlow.h\" />\r\n    <ClInclude Include=\"Workflows\\FontFlow.h\" />\r\n    <ClInclude Include=\"Workflows\\ImportExportFlow.h\" />\r\n    <ClInclude Include=\"Workflows\\MsiInstallFlow.h\" />\r\n    <ClInclude Include=\"Workflows\\MSStoreInstallerHandler.h\" />\r\n    <ClInclude Include=\"Workflows\\MultiQueryFlow.h\" />\r\n    <ClInclude Include=\"Workflows\\PinFlow.h\" />\r\n    <ClInclude Include=\"Workflows\\PortableFlow.h\" />\r\n    <ClInclude Include=\"Workflows\\PromptFlow.h\" />\r\n    <ClInclude Include=\"Workflows\\RepairFlow.h\" />\r\n    <ClInclude Include=\"Workflows\\SettingsFlow.h\" />\r\n    <ClInclude Include=\"Workflows\\ShellExecuteInstallerHandler.h\" />\r\n    <ClInclude Include=\"Workflows\\InstallFlow.h\" />\r\n    <ClInclude Include=\"Workflows\\ResumeFlow.h\" />\r\n    <ClInclude Include=\"Workflows\\ShowFlow.h\" />\r\n    <ClInclude Include=\"Workflows\\SourceFlow.h\" />\r\n    <ClInclude Include=\"Workflows\\UninstallFlow.h\" />\r\n    <ClInclude Include=\"Workflows\\UpdateFlow.h\" />\r\n    <ClInclude Include=\"Workflows\\WorkflowBase.h\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"COMContext.cpp\" />\r\n    <ClCompile Include=\"CheckpointManager.cpp\" />\r\n    <ClCompile Include=\"Commands\\COMCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\ConfigureCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\ConfigureListCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\ConfigureShowCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\ConfigureTestCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\ConfigureValidateCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\DebugCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\DownloadCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\DscAdminSettingsResource.cpp\" />\r\n    <ClCompile Include=\"Commands\\DscCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\DscCommandBase.cpp\" />\r\n    <ClCompile Include=\"Commands\\DscComposableObject.cpp\" />\r\n    <ClCompile Include=\"Commands\\DscPackageResource.cpp\" />\r\n    <ClCompile Include=\"Commands\\DscSourceResource.cpp\" />\r\n    <ClCompile Include=\"Commands\\DscTestFileResource.cpp\" />\r\n    <ClCompile Include=\"Commands\\DscTestJsonResource.cpp\" />\r\n    <ClCompile Include=\"Commands\\DscUserSettingsFileResource.cpp\" />\r\n    <ClCompile Include=\"Commands\\ErrorCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\FontCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\ImportCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\McpCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\PinCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\RepairCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\TestCommand.cpp\" />\r\n    <ClCompile Include=\"ConfigurationCommon.cpp\" />\r\n    <ClCompile Include=\"ConfigurationContext.cpp\" />\r\n    <ClCompile Include=\"ConfigurationDynamicRuntimeFactory.cpp\" />\r\n    <ClCompile Include=\"ConfigurationSetProcessorFactoryRemoting.cpp\" />\r\n    <ClCompile Include=\"ConfigurationWingetDscModuleUnitValidation.cpp\" />\r\n    <ClCompile Include=\"ConfigureExportCommand.cpp\" />\r\n    <ClCompile Include=\"ContextOrchestrator.cpp\" />\r\n    <ClCompile Include=\"ShutdownMonitoring.cpp\" />\r\n    <ClCompile Include=\"Sixel.cpp\" />\r\n    <ClCompile Include=\"Workflows\\ConfigurationFlow.cpp\" />\r\n    <ClCompile Include=\"Workflows\\DependenciesFlow.cpp\" />\r\n    <ClCompile Include=\"PackageCollection.cpp\" />\r\n    <ClCompile Include=\"Argument.cpp\" />\r\n    <ClCompile Include=\"ChannelStreams.cpp\" />\r\n    <ClCompile Include=\"Command.cpp\" />\r\n    <ClCompile Include=\"Commands\\CompleteCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\ExperimentalCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\ExportCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\FeaturesCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\HashCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\ListCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\SearchCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\ShowCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\InstallCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\RootCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\ResumeCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\SourceCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\UninstallCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\UpgradeCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\ValidateCommand.cpp\" />\r\n    <ClCompile Include=\"Commands\\SettingsCommand.cpp\" />\r\n    <ClCompile Include=\"CompletionData.cpp\" />\r\n    <ClCompile Include=\"Core.cpp\" />\r\n    <ClCompile Include=\"ExecutionContext.cpp\" />\r\n    <ClCompile Include=\"ExecutionProgress.cpp\" />\r\n    <ClCompile Include=\"ExecutionReporter.cpp\" />\r\n    <ClCompile Include=\"pch.cpp\">\r\n      <PrecompiledHeader>Create</PrecompiledHeader>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PortableInstaller.cpp\" />\r\n    <ClCompile Include=\"Resources.cpp\" />\r\n    <ClCompile Include=\"VTSupport.cpp\" />\r\n    <ClCompile Include=\"Workflows\\ArchiveFlow.cpp\" />\r\n    <ClCompile Include=\"Workflows\\CompletionFlow.cpp\" />\r\n    <ClCompile Include=\"Workflows\\DependencyNodeProcessor.cpp\" />\r\n    <ClCompile Include=\"Workflows\\DownloadFlow.cpp\" />\r\n    <ClCompile Include=\"Workflows\\FontFlow.cpp\" />\r\n    <ClCompile Include=\"Workflows\\ImportExportFlow.cpp\" />\r\n    <ClCompile Include=\"Workflows\\MsiInstallFlow.cpp\" />\r\n    <ClCompile Include=\"Workflows\\MSStoreInstallerHandler.cpp\" />\r\n    <ClCompile Include=\"Workflows\\MultiQueryFlow.cpp\" />\r\n    <ClCompile Include=\"Workflows\\PinFlow.cpp\" />\r\n    <ClCompile Include=\"Workflows\\PortableFlow.cpp\" />\r\n    <ClCompile Include=\"Workflows\\PromptFlow.cpp\" />\r\n    <ClCompile Include=\"Workflows\\RepairFlow.cpp\" />\r\n    <ClCompile Include=\"Workflows\\SettingsFlow.cpp\" />\r\n    <ClCompile Include=\"Workflows\\ShellExecuteInstallerHandler.cpp\" />\r\n    <ClCompile Include=\"Workflows\\InstallFlow.cpp\" />\r\n    <ClCompile Include=\"Workflows\\ResumeFlow.cpp\" />\r\n    <ClCompile Include=\"Workflows\\ShowFlow.cpp\" />\r\n    <ClCompile Include=\"Workflows\\SourceFlow.cpp\" />\r\n    <ClCompile Include=\"Workflows\\UninstallFlow.cpp\" />\r\n    <ClCompile Include=\"Workflows\\UpdateFlow.cpp\" />\r\n    <ClCompile Include=\"Workflows\\WorkflowBase.cpp\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"packages.config\" />\r\n    <None Include=\"PropertySheet.props\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\AppInstallerCommonCore\\AppInstallerCommonCore.vcxproj\">\r\n      <Project>{5890d6ed-7c3b-40f3-b436-b54f640d9e65}</Project>\r\n    </ProjectReference>\r\n    <ProjectReference Include=\"..\\AppInstallerRepositoryCore\\AppInstallerRepositoryCore.vcxproj\">\r\n      <Project>{5eb88068-5fb9-4e69-89b2-72dbc5e068f9}</Project>\r\n    </ProjectReference>\r\n    <ProjectReference Include=\"..\\Microsoft.Management.Configuration\\Microsoft.Management.Configuration.vcxproj\">\r\n      <Project>{ca460806-5e41-4e97-9a3d-1d74b433b663}</Project>\r\n    </ProjectReference>\r\n  </ItemGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\r\n  <ImportGroup Label=\"ExtensionTargets\">\r\n    <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets')\" />\r\n    <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" />\r\n  </ImportGroup>\r\n  <Target Name=\"EnsureBuildImports\" BeforeTargets=\"PrepareForBuild\">\r\n    <PropertyGroup>\r\n      <ErrorTextNuget>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorTextNuget>\r\n    </PropertyGroup>\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets')\" Text=\"$([System.String]::Format('$(ErrorTextNuget)', '$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets'))\" />\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" Text=\"$([System.String]::Format('$(ErrorTextNuget)', '$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props'))\" />\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" Text=\"$([System.String]::Format('$(ErrorTextNuget)', '$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets'))\" />\r\n  </Target>\r\n</Project>\r\n\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/AppInstallerCLICore.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup>\r\n    <Filter Include=\"Source Files\">\r\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Header Files\">\r\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r\n      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Commands\">\r\n      <UniqueIdentifier>{4b0dcf8b-b4a1-47e5-9c28-e8a3440178e6}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Public\">\r\n      <UniqueIdentifier>{00cc3138-2893-4fc4-8595-d3cf9d26be1c}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Workflows\">\r\n      <UniqueIdentifier>{fdeb940e-93e2-4bb0-a59c-1e2d1c0588d1}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Commands\\Configuration\">\r\n      <UniqueIdentifier>{bd9d8dfe-7a37-4a53-b4e7-ddbd9694c0ab}</UniqueIdentifier>\r\n    </Filter>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"pch.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\RootCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\InstallCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Command.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Invocation.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Search\\Search.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\AppInstallerCLICore.h\">\r\n      <Filter>Public</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Workflows\\InstallFlow.h\">\r\n      <Filter>Workflows</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Workflows\\ShellExecuteInstallerHandler.h\">\r\n      <Filter>Workflows</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Workflows\\WorkflowBase.h\">\r\n      <Filter>Workflows</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\SourceCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\ShowCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\SearchCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Workflows\\ShowFlow.h\">\r\n      <Filter>Workflows</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ExecutionReporter.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ExecutionArgs.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\HashCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"VTSupport.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Argument.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Workflows\\SourceFlow.h\">\r\n      <Filter>Workflows</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\ValidateCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ExecutionProgress.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"TableOutput.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Resources.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\SettingsCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\ExperimentalCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\FeaturesCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\CompleteCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"CompletionData.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Workflows\\CompletionFlow.h\">\r\n      <Filter>Workflows</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ChannelStreams.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Workflows\\UpdateFlow.h\">\r\n      <Filter>Workflows</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Workflows\\MSStoreInstallerHandler.h\">\r\n      <Filter>Workflows</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\UpgradeCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\ListCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\UninstallCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Workflows\\UninstallFlow.h\">\r\n      <Filter>Workflows</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\ExportCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"PackageCollection.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Workflows\\ImportExportFlow.h\">\r\n      <Filter>Workflows</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\ImportCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ExecutionContextData.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ExecutionContext.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ContextOrchestrator.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Workflows\\DependenciesFlow.h\">\r\n      <Filter>Workflows</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\COMCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Workflows\\MsiInstallFlow.h\">\r\n      <Filter>Workflows</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Workflows\\SettingsFlow.h\">\r\n      <Filter>Workflows</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Workflows\\DownloadFlow.h\">\r\n      <Filter>Workflows</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Workflows\\DependencyNodeProcessor.h\">\r\n      <Filter>Workflows</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"COMContext.h\">\r\n      <Filter>Public</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Workflows\\PortableFlow.h\">\r\n      <Filter>Workflows</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Workflows\\ArchiveFlow.h\">\r\n      <Filter>Workflows</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Workflows\\PromptFlow.h\">\r\n      <Filter>Workflows</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"PortableInstaller.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\PinCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Workflows\\PinFlow.h\">\r\n      <Filter>Workflows</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Workflows\\MultiQueryFlow.h\">\r\n      <Filter>Workflows</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationContext.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Workflows\\ConfigurationFlow.h\">\r\n      <Filter>Workflows</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\ConfigurationSetProcessorFactoryRemoting.h\">\r\n      <Filter>Public</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\DebugCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\TestCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\DownloadCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationCommon.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\ErrorCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\ResumeCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Workflows\\ResumeFlow.h\">\r\n      <Filter>Workflows</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"CheckpointManager.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\RepairCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Workflows\\RepairFlow.h\">\r\n      <Filter>Workflows</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationWingetDscModuleUnitValidation.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Sixel.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\FontCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Workflows\\FontFlow.h\">\r\n      <Filter>Workflows</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\ConfigureCommand.h\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigureExportCommand.h\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\ConfigureListCommand.h\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\ConfigureShowCommand.h\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\ConfigureTestCommand.h\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\ConfigureValidateCommand.h\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\DscCommand.h\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\DscCommandBase.h\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\DscTestFileResource.h\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\DscComposableObject.h\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\DscTestJsonResource.h\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\DscPackageResource.h\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\DscSourceResource.h\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\DscUserSettingsFileResource.h\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\DscAdminSettingsResource.h\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\ShutdownMonitoring.h\">\r\n      <Filter>Public</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Commands\\McpCommand.h\">\r\n      <Filter>Commands</Filter>\r\n    </ClInclude>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"pch.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\RootCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\InstallCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Command.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Core.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Workflows\\ShellExecuteInstallerHandler.cpp\">\r\n      <Filter>Workflows</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Workflows\\WorkflowBase.cpp\">\r\n      <Filter>Workflows</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\ShowCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\SearchCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\SourceCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Workflows\\ShowFlow.cpp\">\r\n      <Filter>Workflows</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Workflows\\InstallFlow.cpp\">\r\n      <Filter>Workflows</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ExecutionReporter.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\HashCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"VTSupport.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Argument.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Workflows\\SourceFlow.cpp\">\r\n      <Filter>Workflows</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ExecutionContext.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\ValidateCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ExecutionProgress.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Resources.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\SettingsCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\ExperimentalCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\FeaturesCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\CompleteCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"CompletionData.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Workflows\\CompletionFlow.cpp\">\r\n      <Filter>Workflows</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ChannelStreams.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Workflows\\UpdateFlow.cpp\">\r\n      <Filter>Workflows</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Workflows\\MSStoreInstallerHandler.cpp\">\r\n      <Filter>Workflows</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\UpgradeCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\ListCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\UninstallCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Workflows\\UninstallFlow.cpp\">\r\n      <Filter>Workflows</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\ExportCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PackageCollection.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Workflows\\ImportExportFlow.cpp\">\r\n      <Filter>Workflows</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\ImportCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"COMContext.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ContextOrchestrator.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\COMCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Workflows\\MsiInstallFlow.cpp\">\r\n      <Filter>Workflows</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Workflows\\SettingsFlow.cpp\">\r\n      <Filter>Workflows</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Workflows\\DependencyNodeProcessor.cpp\">\r\n      <Filter>Workflows</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Workflows\\DependenciesFlow.cpp\">\r\n      <Filter>Workflows</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Workflows\\DownloadFlow.cpp\">\r\n      <Filter>Workflows</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Workflows\\PortableFlow.cpp\">\r\n      <Filter>Workflows</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Workflows\\PromptFlow.cpp\">\r\n      <Filter>Workflows</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Workflows\\ArchiveFlow.cpp\">\r\n      <Filter>Workflows</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PortableInstaller.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Workflows\\PinFlow.cpp\">\r\n      <Filter>Workflows</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\PinCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Workflows\\MultiQueryFlow.cpp\">\r\n      <Filter>Workflows</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationContext.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Workflows\\ConfigurationFlow.cpp\">\r\n      <Filter>Workflows</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationSetProcessorFactoryRemoting.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\DebugCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\TestCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationCommon.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\DownloadCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\ResumeCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Workflows\\ResumeFlow.cpp\">\r\n      <Filter>Workflows</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"CheckpointManager.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\ErrorCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\RepairCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Workflows\\RepairFlow.cpp\">\r\n      <Filter>Workflows</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationWingetDscModuleUnitValidation.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationDynamicRuntimeFactory.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Sixel.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\FontCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Workflows\\FontFlow.cpp\">\r\n      <Filter>Workflows</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\ConfigureCommand.cpp\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigureExportCommand.cpp\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\ConfigureListCommand.cpp\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\ConfigureShowCommand.cpp\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\ConfigureTestCommand.cpp\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\ConfigureValidateCommand.cpp\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\DscCommand.cpp\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\DscCommandBase.cpp\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\DscTestFileResource.cpp\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\DscComposableObject.cpp\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\DscTestJsonResource.cpp\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\DscPackageResource.cpp\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\DscSourceResource.cpp\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\DscUserSettingsFileResource.cpp\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\DscAdminSettingsResource.cpp\">\r\n      <Filter>Commands\\Configuration</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ShutdownMonitoring.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Commands\\McpCommand.cpp\">\r\n      <Filter>Commands</Filter>\r\n    </ClCompile>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"PropertySheet.props\" />\r\n    <None Include=\"packages.config\" />\r\n  </ItemGroup>\r\n</Project>"
  },
  {
    "path": "src/AppInstallerCLICore/Argument.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Argument.h\"\r\n#include \"Command.h\"\r\n#include \"Resources.h\"\r\n#include <winget/UserSettings.h>\r\n#include <winget/LocIndependent.h>\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    using namespace AppInstaller::CLI::Execution;\r\n    using namespace Settings;\r\n    using namespace AppInstaller::Utility::literals;\r\n\r\n    namespace\r\n    {\r\n        bool ContainsArgumentFromList(const Execution::Args& args, const std::vector<Execution::Args::Type>& argTypes)\r\n        {\r\n            return std::any_of(argTypes.begin(), argTypes.end(), [&](Execution::Args::Type arg) { return args.Contains(arg); });\r\n        }\r\n    }\r\n\r\n    ArgumentCommon ArgumentCommon::ForType(Execution::Args::Type type)\r\n    {\r\n        // A test ensures that all types are listed here\r\n        switch (type)\r\n        {\r\n        // Args to specify where to get app\r\n        case Execution::Args::Type::Query:\r\n            return { type, \"query\"_liv, 'q', ArgTypeCategory::PackageQuery | ArgTypeCategory::SinglePackageQuery };\r\n        case Execution::Args::Type::MultiQuery:\r\n            return { type, \"query\"_liv, 'q', ArgTypeCategory::PackageQuery | ArgTypeCategory::MultiplePackages };\r\n        case Execution::Args::Type::Manifest:\r\n            return { type, \"manifest\"_liv, 'm', ArgTypeCategory::Manifest };\r\n\r\n        // Query filtering criteria and query behavior\r\n        case Execution::Args::Type::Id:\r\n            return { type, \"id\"_liv, ArgTypeCategory::PackageQuery | ArgTypeCategory::SinglePackageQuery };\r\n        case Execution::Args::Type::Name:\r\n            return { type, \"name\"_liv, ArgTypeCategory::PackageQuery | ArgTypeCategory::SinglePackageQuery };\r\n        case Execution::Args::Type::Moniker:\r\n            return { type, \"moniker\"_liv, ArgTypeCategory::PackageQuery | ArgTypeCategory::SinglePackageQuery };\r\n        case Execution::Args::Type::Tag:\r\n            return { type, \"tag\"_liv, ArgTypeCategory::PackageQuery };\r\n        case Execution::Args::Type::Command:\r\n            return { type, \"command\"_liv, \"cmd\"_liv, ArgTypeCategory::PackageQuery | ArgTypeCategory::SinglePackageQuery };\r\n        case Execution::Args::Type::Source:\r\n            return { type, \"source\"_liv, 's', ArgTypeCategory::QuerySource };\r\n        case Execution::Args::Type::Count:\r\n            return { type, \"count\"_liv, 'n', ArgTypeCategory::PackageQuery | ArgTypeCategory::SinglePackageQuery };\r\n        case Execution::Args::Type::Exact:\r\n            return { type, \"exact\"_liv, 'e', ArgTypeCategory::PackageQuery };\r\n\r\n        // Manifest selection behavior after an app is found\r\n        case Execution::Args::Type::Version:\r\n            return { type, \"version\"_liv, 'v', ArgTypeCategory::PackageQuery | ArgTypeCategory::SinglePackageQuery };\r\n        case Execution::Args::Type::Channel:\r\n            return { type, \"channel\"_liv, 'c', ArgTypeCategory::PackageQuery };\r\n\r\n        // Install behavior\r\n        case Execution::Args::Type::Interactive:\r\n            return { type, \"interactive\"_liv, 'i', ArgTypeCategory::InstallerBehavior | ArgTypeCategory::CopyFlagToSubContext };\r\n        case Execution::Args::Type::Silent:\r\n            return { type, \"silent\"_liv, 'h', ArgTypeCategory::InstallerBehavior | ArgTypeCategory::CopyFlagToSubContext };\r\n        case Execution::Args::Type::Locale:\r\n            return { type, \"locale\"_liv, ArgTypeCategory::InstallerSelection | ArgTypeCategory::CopyValueToSubContext };\r\n        case Execution::Args::Type::Log:\r\n            return { type, \"log\"_liv, 'o', ArgTypeCategory::InstallerSelection | ArgTypeCategory::SingleInstallerBehavior };\r\n        case Execution::Args::Type::CustomSwitches:\r\n            return { type, \"custom\"_liv, ArgTypeCategory::InstallerSelection | ArgTypeCategory::SingleInstallerBehavior };\r\n        case Execution::Args::Type::Override:\r\n            return { type, \"override\"_liv, ArgTypeCategory::InstallerSelection | ArgTypeCategory::SingleInstallerBehavior };\r\n        case Execution::Args::Type::InstallLocation:\r\n            return { type, \"location\"_liv, 'l', ArgTypeCategory::InstallerSelection | ArgTypeCategory::SingleInstallerBehavior };\r\n        case Execution::Args::Type::InstallScope:\r\n            return { type, \"scope\"_liv, ArgTypeCategory::InstallerSelection | ArgTypeCategory::CopyValueToSubContext };\r\n        case Execution::Args::Type::InstallArchitecture:\r\n            return { type, \"architecture\"_liv, 'a', ArgTypeCategory::InstallerSelection | ArgTypeCategory::CopyValueToSubContext };\r\n        case Execution::Args::Type::InstallerArchitecture: // Used for input architecture that does not need applicability check. E.g. Download, Show.\r\n            return { type, \"architecture\"_liv, 'a', ArgTypeCategory::InstallerSelection | ArgTypeCategory::CopyValueToSubContext };\r\n        case Execution::Args::Type::InstallerType:\r\n            return { type, \"installer-type\"_liv, ArgTypeCategory::InstallerSelection };\r\n        case Execution::Args::Type::HashOverride:\r\n            return { type, \"ignore-security-hash\"_liv, ArgTypeCategory::InstallerBehavior | ArgTypeCategory::CopyFlagToSubContext };\r\n        case Execution::Args::Type::IgnoreLocalArchiveMalwareScan:\r\n            return { type, \"ignore-local-archive-malware-scan\"_liv, ArgTypeCategory::InstallerBehavior | ArgTypeCategory::CopyFlagToSubContext };\r\n        case Execution::Args::Type::AcceptPackageAgreements:\r\n            return { type, \"accept-package-agreements\"_liv, ArgTypeCategory::InstallerBehavior };\r\n        case Execution::Args::Type::Rename:\r\n            return { type, \"rename\"_liv, 'r' };\r\n        case Execution::Args::Type::NoUpgrade:\r\n            return { type, \"no-upgrade\"_liv, ArgTypeCategory::CopyFlagToSubContext };\r\n        case Execution::Args::Type::SkipDependencies:\r\n            return { type, \"skip-dependencies\"_liv, ArgTypeCategory::InstallerBehavior | ArgTypeCategory::CopyFlagToSubContext, ArgTypeExclusiveSet::DependenciesConflict };\r\n        case Execution::Args::Type::DependenciesOnly:\r\n            return { type, \"dependencies-only\"_liv, ArgTypeCategory::InstallerBehavior, ArgTypeExclusiveSet::DependenciesConflict };\r\n        case Execution::Args::Type::AllowReboot:\r\n            return { type, \"allow-reboot\"_liv, ArgTypeCategory::InstallerBehavior | ArgTypeCategory::CopyFlagToSubContext };\r\n\r\n        // Uninstall behavior\r\n        case Execution::Args::Type::Purge:\r\n            return { type, \"purge\"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::PurgePreserve };\r\n        case Execution::Args::Type::Preserve:\r\n            return { type, \"preserve\"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::PurgePreserve };\r\n        case Execution::Args::Type::ProductCode:\r\n            return { type, \"product-code\"_liv, ArgTypeCategory::SinglePackageQuery };\r\n        case Execution::Args::Type::AllVersions:\r\n            return { type, \"all-versions\"_liv, \"all\"_liv, ArgTypeCategory::CopyFlagToSubContext, ArgTypeExclusiveSet::AllAndTargetVersion };\r\n        case Execution::Args::Type::TargetVersion:\r\n            return { type, \"version\"_liv, 'v', ArgTypeCategory::SinglePackageQuery, ArgTypeExclusiveSet::AllAndTargetVersion };\r\n\r\n        // Source Command\r\n        case Execution::Args::Type::SourceName:\r\n            return { type, \"name\"_liv, 'n' };\r\n        case Execution::Args::Type::SourceType:\r\n            return { type, \"type\"_liv, 't' };\r\n        case Execution::Args::Type::SourceArg:\r\n            return { type, \"arg\"_liv, 'a' };\r\n        case Execution::Args::Type::ForceSourceReset:\r\n            return { type, \"force\"_liv };\r\n        case Execution::Args::Type::SourceExplicit:\r\n            return { type, \"explicit\"_liv };\r\n        case Execution::Args::Type::SourceTrustLevel:\r\n            return { type, \"trust-level\"_liv };\r\n        case Execution::Args::Type::SourceEditExplicit:\r\n            return { type, \"explicit\"_liv, 'e' };\r\n        case Execution::Args::Type::SourcePriority:\r\n            return { type, \"priority\"_liv, 'p' };\r\n\r\n        // Hash Command\r\n        case Execution::Args::Type::HashFile:\r\n            return { type, \"file\"_liv, 'f' };\r\n        case Execution::Args::Type::Msix:\r\n            return { type, \"msix\"_liv, 'm' };\r\n\r\n        // Validate Command\r\n        case Execution::Args::Type::ValidateManifest:\r\n            return { type, \"manifest\"_liv };\r\n        case Execution::Args::Type::IgnoreWarnings:\r\n            return { type, \"ignore-warnings\"_liv, \"nowarn\"_liv};\r\n\r\n        // Complete Command\r\n        case Execution::Args::Type::Word:\r\n            return { type, \"word\"_liv };\r\n        case Execution::Args::Type::CommandLine:\r\n            return { type, \"commandline\"_liv };\r\n        case Execution::Args::Type::Position:\r\n            return { type, \"position\"_liv };\r\n\r\n        // Export Command\r\n        case Execution::Args::Type::IncludeVersions:\r\n            return { type, \"include-versions\"_liv };\r\n\r\n        // Import Command\r\n        case Execution::Args::Type::ImportFile:\r\n            return { type, \"import-file\"_liv, 'i' };\r\n        case Execution::Args::Type::IgnoreUnavailable:\r\n            return { type, \"ignore-unavailable\"_liv };\r\n        case Execution::Args::Type::IgnoreVersions:\r\n            return { type, \"ignore-versions\"_liv };\r\n\r\n        // Setting Command\r\n        case Execution::Args::Type::AdminSettingEnable:\r\n            return { type, \"enable\"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::EnableDisable };\r\n        case Execution::Args::Type::AdminSettingDisable:\r\n            return { type, \"disable\"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::EnableDisable };\r\n        case Execution::Args::Type::SettingName:\r\n            return { type, \"setting\"_liv };\r\n        case Execution::Args::Type::SettingValue:\r\n            return { type, \"value\"_liv };\r\n\r\n        // Upgrade command\r\n        case Execution::Args::Type::All:\r\n            return { type, \"all\"_liv, 'r', \"recurse\"_liv, ArgTypeCategory::MultiplePackages };\r\n        case Execution::Args::Type::IncludeUnknown:\r\n            return { type, \"include-unknown\"_liv, 'u', \"unknown\"_liv, ArgTypeCategory::CopyFlagToSubContext };\r\n        case Execution::Args::Type::IncludePinned:\r\n            return { type, \"include-pinned\"_liv, \"pinned\"_liv, ArgTypeCategory::CopyFlagToSubContext };\r\n        case Execution::Args::Type::UninstallPrevious:\r\n            return { type, \"uninstall-previous\"_liv, ArgTypeCategory::InstallerBehavior | ArgTypeCategory::CopyFlagToSubContext };\r\n\r\n        // Show command\r\n        case Execution::Args::Type::ListVersions:\r\n            return { type, \"versions\"_liv };\r\n\r\n        // List command\r\n        case Execution::Args::Type::Upgrade:\r\n            return { type, \"upgrade-available\"_liv};\r\n        case Execution::Args::Type::ListDetails:\r\n            return { type, \"details\"_liv };\r\n\r\n        // Pin command\r\n        case Execution::Args::Type::GatedVersion:\r\n            return { type, \"version\"_liv, 'v', ArgTypeCategory::None, ArgTypeExclusiveSet::PinType };\r\n        case Execution::Args::Type::BlockingPin:\r\n            return { type, \"blocking\"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::PinType };\r\n        case Execution::Args::Type::PinInstalled:\r\n            return { type, \"installed\"_liv, ArgTypeCategory::None };\r\n\r\n        // Error command\r\n        case Execution::Args::Type::ErrorInput:\r\n            return { type, \"input\"_liv, ArgTypeCategory::None };\r\n\r\n        // Resume command\r\n        case Execution::Args::Type::ResumeId:\r\n            return { type, \"resume-id\"_liv, 'g', ArgTypeCategory::None };\r\n        case Execution::Args::Type::IgnoreResumeLimit:\r\n            return { type, \"ignore-resume-limit\"_liv, ArgTypeCategory::None };\r\n\r\n        // Font command\r\n        case Execution::Args::Type::Family:\r\n            return { type, \"family\"_liv, ArgTypeCategory::None };\r\n        case Execution::Args::Type::Details:\r\n            return { type, \"details\"_liv, ArgTypeCategory::None };\r\n\r\n        // Configuration commands\r\n        case Execution::Args::Type::ConfigurationFile:\r\n            return { type, \"file\"_liv, 'f', ArgTypeCategory::ConfigurationSetChoice, ArgTypeExclusiveSet::ConfigurationSetChoice };\r\n        case Execution::Args::Type::ConfigurationAcceptWarning:\r\n            return { type, \"accept-configuration-agreements\"_liv };\r\n        case Execution::Args::Type::ConfigurationSuppressPrologue:\r\n            return { type, \"suppress-initial-details\"_liv };\r\n        case Execution::Args::Type::ExtendedFeaturesEnable:\r\n            return { type, \"enable\"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::StubType };\r\n        case Execution::Args::Type::ExtendedFeaturesDisable:\r\n            return { type, \"disable\"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::StubType };\r\n        case Execution::Args::Type::ConfigurationModulePath:\r\n            return { type, \"module-path\"_liv };\r\n        case Execution::Args::Type::ConfigurationProcessorPath:\r\n            return { type, \"processor-path\"_liv };\r\n        case Execution::Args::Type::ConfigurationExportPackageId:\r\n            return { type, \"package-id\"_liv };\r\n        case Execution::Args::Type::ConfigurationExportModule:\r\n            return { type, \"module\"_liv };\r\n        case Execution::Args::Type::ConfigurationExportResource:\r\n            return { type, \"resource\"_liv };\r\n        case Execution::Args::Type::ConfigurationExportAll:\r\n            return { type, \"all\"_liv, 'r', \"recurse\"_liv };\r\n        case Execution::Args::Type::ConfigurationHistoryItem:\r\n            return { type, \"history\"_liv, 'h', ArgTypeCategory::ConfigurationSetChoice, ArgTypeExclusiveSet::ConfigurationSetChoice };\r\n        case Execution::Args::Type::ConfigurationHistoryRemove:\r\n            return { type, \"remove\"_liv };\r\n        case Execution::Args::Type::ConfigurationStatusWatch:\r\n            return { type, \"live\"_liv };\r\n\r\n        // DSCv3 resources\r\n        case Execution::Args::Type::DscResourceFunctionGet:\r\n            return { type, \"get\"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::DscResourceFunction };\r\n        case Execution::Args::Type::DscResourceFunctionSet:\r\n            return { type, \"set\"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::DscResourceFunction };\r\n        case Execution::Args::Type::DscResourceFunctionWhatIf:\r\n            return { type, \"whatIf\"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::DscResourceFunction };\r\n        case Execution::Args::Type::DscResourceFunctionTest:\r\n            return { type, \"test\"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::DscResourceFunction };\r\n        case Execution::Args::Type::DscResourceFunctionDelete:\r\n            return { type, \"delete\"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::DscResourceFunction };\r\n        case Execution::Args::Type::DscResourceFunctionExport:\r\n            return { type, \"export\"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::DscResourceFunction };\r\n        case Execution::Args::Type::DscResourceFunctionValidate:\r\n            return { type, \"validate\"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::DscResourceFunction };\r\n        case Execution::Args::Type::DscResourceFunctionResolve:\r\n            return { type, \"resolve\"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::DscResourceFunction };\r\n        case Execution::Args::Type::DscResourceFunctionAdapter:\r\n            return { type, \"adapter\"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::DscResourceFunction };\r\n        case Execution::Args::Type::DscResourceFunctionSchema:\r\n            return { type, \"schema\"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::DscResourceFunction };\r\n        case Execution::Args::Type::DscResourceFunctionManifest:\r\n            return { type, \"manifest\"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::DscResourceFunction };\r\n\r\n        // Download command\r\n        case Execution::Args::Type::DownloadDirectory:\r\n            return { type, \"download-directory\"_liv, 'd', ArgTypeCategory::None };\r\n        case Execution::Args::Type::Platform:\r\n            return { type, \"platform\"_liv, ArgTypeCategory::None };\r\n        case Execution::Args::Type::SkipMicrosoftStorePackageLicense:\r\n            return { type, \"skip-microsoft-store-package-license\"_liv, \"skip-license\"_liv, ArgTypeCategory::None };\r\n        case Execution::Args::Type::OSVersion:\r\n            return { type, \"os-version\"_liv, ArgTypeCategory::None };\r\n\r\n        // Common arguments\r\n        case Execution::Args::Type::NoVT:\r\n            return { type, \"no-vt\"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::ProgressBarOption };\r\n        case Execution::Args::Type::RetroStyle:\r\n            return { type, \"retro\"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::ProgressBarOption };\r\n        case Execution::Args::Type::RainbowStyle:\r\n            return { type, \"rainbow\"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::ProgressBarOption };\r\n        case Execution::Args::Type::NoProgress:\r\n            return { type, \"no-progress\"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::ProgressBarOption };\r\n        case Execution::Args::Type::Help:\r\n            return { type, \"help\"_liv, APPINSTALLER_CLI_HELP_ARGUMENT_TEXT_CHAR };\r\n        case Execution::Args::Type::Info:\r\n            return { type, \"info\"_liv };\r\n        case Execution::Args::Type::VerboseLogs:\r\n            return { type, \"verbose-logs\"_liv, \"verbose\"_liv };\r\n        case Execution::Args::Type::DisableInteractivity:\r\n            return { type, \"disable-interactivity\"_liv };\r\n        case Execution::Args::Type::Wait:\r\n            return { type, \"wait\"_liv };\r\n        case Execution::Args::Type::OpenLogs:\r\n            return { type, \"open-logs\"_liv, \"logs\"_liv };\r\n        case Execution::Args::Type::Force:\r\n            return { type, \"force\"_liv, ArgTypeCategory::CopyFlagToSubContext };\r\n        case Execution::Args::Type::OutputFile:\r\n            return { type, \"output\"_liv, 'o' };\r\n        case Execution::Args::Type::Correlation:\r\n            return { type, \"correlation\"_liv };\r\n\r\n        case Execution::Args::Type::DependencySource:\r\n            return { type, \"dependency-source\"_liv, ArgTypeCategory::ExtendedSource };\r\n        case Execution::Args::Type::CustomHeader:\r\n            return { type, \"header\"_liv, ArgTypeCategory::ExtendedSource };\r\n        case Execution::Args::Type::AcceptSourceAgreements:\r\n            return { type, \"accept-source-agreements\"_liv, ArgTypeCategory::ExtendedSource };\r\n\r\n        case Execution::Args::Type::Proxy:\r\n            return { type, \"proxy\"_liv, ArgTypeCategory::CopyValueToSubContext, ArgTypeExclusiveSet::Proxy };\r\n        case Execution::Args::Type::NoProxy:\r\n            return { type, \"no-proxy\"_liv, ArgTypeCategory::CopyFlagToSubContext, ArgTypeExclusiveSet::Proxy };\r\n\r\n        case Execution::Args::Type::ToolVersion:\r\n            return { type, \"version\"_liv, 'v' };\r\n\r\n        // Authentication arguments\r\n        case Execution::Args::Type::AuthenticationMode:\r\n            return { type, \"authentication-mode\"_liv, ArgTypeCategory::CopyValueToSubContext };\r\n        case Execution::Args::Type::AuthenticationAccount:\r\n            return { type, \"authentication-account\"_liv, ArgTypeCategory::CopyValueToSubContext };\r\n\r\n        // Used for demonstration purposes\r\n        case Execution::Args::Type::ExperimentalArg:\r\n                return { type, \"arg\"_liv };\r\n\r\n        default:\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n    }\r\n\r\n    std::vector<ArgumentCommon> ArgumentCommon::GetFromExecArgs(const Execution::Args& execArgs)\r\n    {\r\n        auto argTypes = execArgs.GetTypes();\r\n        std::vector<ArgumentCommon> result;\r\n        std::transform(argTypes.begin(), argTypes.end(), std::back_inserter(result), ArgumentCommon::ForType);\r\n        return result;\r\n    }\r\n\r\n    Argument Argument::ForType(Execution::Args::Type type)\r\n    {\r\n        switch (type)\r\n        {\r\n        case Args::Type::Query:\r\n            return Argument{ type, Resource::String::QueryArgumentDescription, ArgumentType::Positional};\r\n        case Args::Type::MultiQuery:\r\n            return Argument{ type, Resource::String::MultiQueryArgumentDescription, ArgumentType::Positional }.SetCountLimit(128);\r\n        case Args::Type::Manifest:\r\n            return Argument{ type, Resource::String::ManifestArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help, Settings::TogglePolicy::Policy::LocalManifestFiles, Settings::BoolAdminSetting::LocalManifestFiles };\r\n        case Args::Type::Id:\r\n            return Argument{ type, Resource::String::IdArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help };\r\n        case Args::Type::Name:\r\n            return Argument{ type, Resource::String::NameArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help };\r\n        case Args::Type::Moniker:\r\n            return Argument{ type, Resource::String::MonikerArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help };\r\n        case Args::Type::Tag:\r\n            return Argument{ type, Resource::String::TagArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help };\r\n        case Args::Type::Command:\r\n            return Argument{ type, Resource::String::CommandArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help };\r\n        case Args::Type::Source:\r\n            return Argument{ type, Resource::String::SourceArgumentDescription, ArgumentType::Standard };\r\n        case Args::Type::DependencySource:\r\n            return Argument{ type, Resource::String::DependencySourceArgumentDescription, ArgumentType::Standard };\r\n        case Args::Type::Count:\r\n            return Argument{ type, Resource::String::CountArgumentDescription, ArgumentType::Standard };\r\n        case Args::Type::Exact:\r\n            return Argument{ type, Resource::String::ExactArgumentDescription, ArgumentType::Flag };\r\n        case Args::Type::Version:\r\n            return Argument{ type, Resource::String::VersionArgumentDescription, ArgumentType::Standard };\r\n        case Args::Type::Channel:\r\n            return Argument{ type, Resource::String::ChannelArgumentDescription, ArgumentType::Standard, Argument::Visibility::Hidden };\r\n        case Args::Type::Interactive:\r\n            return Argument{ type, Resource::String::InteractiveArgumentDescription, ArgumentType::Flag };\r\n        case Args::Type::Silent:\r\n            return Argument{ type, Resource::String::SilentArgumentDescription, ArgumentType::Flag };\r\n        case Args::Type::Locale:\r\n            return Argument{ type, Resource::String::LocaleArgumentDescription, ArgumentType::Standard };\r\n        case Args::Type::InstallArchitecture:\r\n            return Argument{ type, Resource::String::ArchitectureArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help };\r\n        case Args::Type::InstallerArchitecture:\r\n            return Argument{ type, Resource::String::ArchitectureArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help };\r\n        case Args::Type::Log:\r\n            return Argument{ type, Resource::String::LogArgumentDescription, ArgumentType::Standard };\r\n        case Args::Type::CustomSwitches:\r\n            return Argument{ type, Resource::String::CustomSwitchesArgumentDescription, ArgumentType::Standard };\r\n        case Args::Type::Override:\r\n            return Argument{ type, Resource::String::OverrideArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help };\r\n        case Args::Type::InstallLocation:\r\n            return Argument{ type, Resource::String::LocationArgumentDescription, ArgumentType::Standard };\r\n        case Args::Type::HashOverride:\r\n            return Argument{ type, Resource::String::HashOverrideArgumentDescription, ArgumentType::Flag, Settings::TogglePolicy::Policy::HashOverride, Settings::BoolAdminSetting::InstallerHashOverride };\r\n        case Args::Type::AcceptPackageAgreements:\r\n            return Argument{ type, Resource::String::AcceptPackageAgreementsArgumentDescription, ArgumentType::Flag };\r\n        case Args::Type::NoUpgrade:\r\n            return Argument{ type, Resource::String::NoUpgradeArgumentDescription, ArgumentType::Flag };\r\n        case Args::Type::HashFile:\r\n            return Argument{ type, Resource::String::FileArgumentDescription, ArgumentType::Positional, true };\r\n        case Args::Type::Msix:\r\n            return Argument{ type, Resource::String::MsixArgumentDescription, ArgumentType::Flag };\r\n        case Args::Type::ListVersions:\r\n            return Argument{ type, Resource::String::VersionsArgumentDescription, ArgumentType::Flag };\r\n        case Args::Type::Help:\r\n            return Argument{ type, Resource::String::HelpArgumentDescription, ArgumentType::Flag };\r\n        case Args::Type::SkipDependencies:\r\n            return Argument{ type, Resource::String::SkipDependenciesArgumentDescription, ArgumentType::Flag, false };\r\n        case Args::Type::DependenciesOnly:\r\n            return Argument{ type, Resource::String::DependenciesOnlyArgumentDescription, ArgumentType::Flag, false };\r\n        case Args::Type::IgnoreLocalArchiveMalwareScan:\r\n            return Argument{ type, Resource::String::IgnoreLocalArchiveMalwareScanArgumentDescription, ArgumentType::Flag, Settings::TogglePolicy::Policy::LocalArchiveMalwareScanOverride, Settings::BoolAdminSetting::LocalArchiveMalwareScanOverride };\r\n        case Args::Type::SourceName:\r\n            return Argument{ type, Resource::String::SourceNameArgumentDescription, ArgumentType::Positional, false };\r\n        case Args::Type::SourceArg:\r\n            return Argument{ type, Resource::String::SourceArgArgumentDescription, ArgumentType::Positional, true };\r\n        case Args::Type::SourceType:\r\n            return Argument{ type, Resource::String::SourceTypeArgumentDescription, ArgumentType::Positional };\r\n        case Args::Type::SourceExplicit:\r\n            return Argument{ type, Resource::String::SourceExplicitArgumentDescription, ArgumentType::Flag };\r\n        case Args::Type::SourceEditExplicit:\r\n            return Argument{ type, Resource::String::SourceEditExplicitArgumentDescription, ArgumentType::Standard };\r\n        case Args::Type::SourcePriority:\r\n            return Argument{ type, Resource::String::SourcePriorityArgumentDescription, ArgumentType::Standard, ExperimentalFeature::Feature::SourcePriority };\r\n        case Args::Type::SourceTrustLevel:\r\n            return Argument{ type, Resource::String::SourceTrustLevelArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help };\r\n        case Args::Type::ValidateManifest:\r\n            return Argument{ type, Resource::String::ValidateManifestArgumentDescription, ArgumentType::Positional, true };\r\n        case Args::Type::IgnoreWarnings:\r\n            return Argument{ type, Resource::String::IgnoreWarningsArgumentDescription, ArgumentType::Flag, Argument::Visibility::Help };\r\n        case Args::Type::NoVT:\r\n            return Argument{ type, Resource::String::NoVTArgumentDescription, ArgumentType::Flag, Argument::Visibility::Hidden };\r\n        case Args::Type::RainbowStyle:\r\n            return Argument{ type, Resource::String::RainbowArgumentDescription, ArgumentType::Flag, Argument::Visibility::Hidden };\r\n        case Args::Type::RetroStyle:\r\n            return Argument{ type, Resource::String::RetroArgumentDescription, ArgumentType::Flag, Argument::Visibility::Hidden };\r\n        case Args::Type::NoProgress:\r\n            return Argument{ type, Resource::String::NoProgressArgumentDescription, ArgumentType::Flag, Argument::Visibility::Hidden };\r\n        case Args::Type::VerboseLogs:\r\n            return Argument{ type, Resource::String::VerboseLogsArgumentDescription, ArgumentType::Flag };\r\n        case Args::Type::CustomHeader:\r\n            return Argument{ type, Resource::String::HeaderArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help };\r\n        case Args::Type::AcceptSourceAgreements:\r\n            return Argument{ type, Resource::String::AcceptSourceAgreementsArgumentDescription, ArgumentType::Flag };\r\n        case Args::Type::AuthenticationMode:\r\n            return Argument{ type, Resource::String::AuthenticationModeArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help };\r\n        case Args::Type::AuthenticationAccount:\r\n            return Argument{ type, Resource::String::AuthenticationAccountArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help };\r\n        case Args::Type::ExperimentalArg:\r\n            return Argument{ type, Resource::String::ExperimentalArgumentDescription, ArgumentType::Flag, ExperimentalFeature::Feature::ExperimentalArg };\r\n        case Args::Type::Rename:\r\n            return Argument{ type, Resource::String::RenameArgumentDescription, ArgumentType::Standard, false };\r\n        case Args::Type::Purge:\r\n            return Argument{ type, Resource::String::PurgeArgumentDescription, ArgumentType::Flag, false };\r\n        case Args::Type::Preserve:\r\n            return Argument{ type, Resource::String::PreserveArgumentDescription, ArgumentType::Flag, false };\r\n        case Args::Type::Wait:\r\n            return Argument{ type, Resource::String::WaitArgumentDescription, ArgumentType::Flag, false };\r\n        case Args::Type::ProductCode:\r\n            return Argument{ type, Resource::String::ProductCodeArgumentDescription, ArgumentType::Standard, false };\r\n        case Args::Type::OpenLogs:\r\n            return Argument{ type, Resource::String::OpenLogsArgumentDescription, ArgumentType::Flag, Argument::Visibility::Help };\r\n        case Args::Type::UninstallPrevious:\r\n            return Argument{ type, Resource::String::UninstallPreviousArgumentDescription, ArgumentType::Flag, Argument::Visibility::Help };\r\n        case Args::Type::Force:\r\n            return Argument{ type, Resource::String::ForceArgumentDescription, ArgumentType::Flag, false };\r\n        case Args::Type::DownloadDirectory:\r\n            return Argument{ type, Resource::String::DownloadDirectoryArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help, false };\r\n        case Args::Type::SkipMicrosoftStorePackageLicense:\r\n            return Argument{ type, Resource::String::SkipMicrosoftStorePackageLicenseArgumentDescription, ArgumentType::Flag, Argument::Visibility::Help, false };\r\n        case Args::Type::Platform:\r\n            return Argument{ type, Resource::String::PlatformArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help, false };\r\n        case Args::Type::InstallerType:\r\n            return Argument{ type, Resource::String::InstallerTypeArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help, false };\r\n        case Args::Type::ResumeId:\r\n            return Argument{ type, Resource::String::ResumeIdArgumentDescription, ArgumentType::Standard, true };\r\n        case Args::Type::AllowReboot:\r\n            return Argument{ type, Resource::String::AllowRebootArgumentDescription, ArgumentType::Flag };\r\n        case Args::Type::IgnoreResumeLimit:\r\n            return Argument{ type, Resource::String::IgnoreResumeLimitArgumentDescription, ArgumentType::Flag, ExperimentalFeature::Feature::Resume };\r\n        case Args::Type::AllVersions:\r\n            return Argument{ type, Resource::String::UninstallAllVersionsArgumentDescription, ArgumentType::Flag, Argument::Visibility::Help };\r\n        case Args::Type::TargetVersion:\r\n            return Argument{ type, Resource::String::TargetVersionArgumentDescription, ArgumentType::Standard };\r\n        case Args::Type::Proxy:\r\n            return Argument{ type, Resource::String::ProxyArgumentDescription, ArgumentType::Standard, TogglePolicy::Policy::ProxyCommandLineOptions, BoolAdminSetting::ProxyCommandLineOptions };\r\n        case Args::Type::NoProxy:\r\n            return Argument{ type, Resource::String::NoProxyArgumentDescription, ArgumentType::Flag, TogglePolicy::Policy::ProxyCommandLineOptions, BoolAdminSetting::ProxyCommandLineOptions };\r\n        case Args::Type::Family:\r\n            return Argument{ type, Resource::String::FontFamilyNameArgumentDescription, ArgumentType::Positional, false };\r\n        case Args::Type::Details:\r\n            return Argument{ type, Resource::String::FontDetailsArgumentDescription, ArgumentType::Flag, false };\r\n        case Args::Type::Correlation:\r\n            return Argument{ type, Resource::String::CorrelationArgumentDescription, ArgumentType::Standard, Argument::Visibility::Hidden };\r\n        case Args::Type::ListDetails:\r\n            return Argument{ type, Resource::String::ListDetailsArgumentDescription, ArgumentType::Flag, Argument::Visibility::Help };\r\n        default:\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n    }\r\n\r\n    void Argument::GetCommon(std::vector<Argument>& args)\r\n    {\r\n        args.push_back(ForType(Args::Type::Help));\r\n        args.push_back(ForType(Args::Type::Wait));\r\n        args.push_back(ForType(Args::Type::OpenLogs));\r\n        args.push_back(ForType(Args::Type::NoVT));\r\n        args.push_back(ForType(Args::Type::RainbowStyle));\r\n        args.push_back(ForType(Args::Type::RetroStyle));\r\n        args.push_back(ForType(Args::Type::NoProgress));\r\n        args.push_back(ForType(Args::Type::VerboseLogs));\r\n        args.push_back(ForType(Args::Type::IgnoreWarnings));\r\n        args.emplace_back(Args::Type::DisableInteractivity, Resource::String::DisableInteractivityArgumentDescription, ArgumentType::Flag, false);\r\n        args.push_back(ForType(Args::Type::Proxy));\r\n        args.push_back(ForType(Args::Type::NoProxy));\r\n        args.push_back(ForType(Args::Type::Correlation));\r\n    }\r\n\r\n    std::string Argument::GetUsageString() const\r\n    {\r\n        std::ostringstream strstr;\r\n        if (Alias() != ArgumentCommon::NoAlias)\r\n        {\r\n            strstr << APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_CHAR << Alias() << ',';\r\n        }\r\n        if (AlternateName() != Argument::NoAlternateName)\r\n        {\r\n            strstr << APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_CHAR << APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_CHAR << AlternateName() << ',';\r\n        }\r\n        strstr << APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_CHAR << APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_CHAR << Name();\r\n        return strstr.str();\r\n    }\r\n\r\n    void Argument::ValidateExclusiveArguments(const Execution::Args& args)\r\n    {\r\n        auto argProperties = ArgumentCommon::GetFromExecArgs(args);\r\n\r\n        using ExclusiveSet_t = std::underlying_type_t<ArgTypeExclusiveSet>;\r\n        for (ExclusiveSet_t i = 1 + static_cast<ExclusiveSet_t>(ArgTypeExclusiveSet::None); i < static_cast<ExclusiveSet_t>(ArgTypeExclusiveSet::Max); i <<= 1)\r\n        {\r\n            std::vector<ArgumentCommon> argsFromSet;\r\n            std::copy_if(\r\n                argProperties.begin(),\r\n                argProperties.end(),\r\n                std::back_inserter(argsFromSet),\r\n                [=](const ArgumentCommon& arg) { return static_cast<ExclusiveSet_t>(arg.ExclusiveSet) & i; });\r\n\r\n            if (argsFromSet.size() > 1)\r\n            {\r\n                // Create a string showing the exclusive args.\r\n                std::string argsString;\r\n                for (const auto& arg : argsFromSet)\r\n                {\r\n                    if (!argsString.empty())\r\n                    {\r\n                        argsString += '|';\r\n\r\n                    }\r\n\r\n                    argsString += arg.Name;\r\n                }\r\n\r\n                throw CommandException(Resource::String::MultipleExclusiveArgumentsProvided(Utility::LocIndString{ argsString }));\r\n            }\r\n        }\r\n    }\r\n\r\n    void Argument::ValidateArgumentDependency(const Execution::Args& args, Execution::Args::Type type, Execution::Args::Type dependencyArgType)\r\n    {\r\n        if (args.Contains(type) && !args.Contains(dependencyArgType))\r\n        {\r\n            throw CommandException(Resource::String::DependencyArgumentMissing(\r\n                Utility::LocIndString{ ArgumentCommon::ForType(type).Name },\r\n                Utility::LocIndString{ ArgumentCommon::ForType(dependencyArgType).Name }));\r\n        }\r\n    }\r\n\r\n    ArgTypeCategory Argument::GetCategoriesPresent(const Execution::Args& args)\r\n    {\r\n        auto argProperties = ArgumentCommon::GetFromExecArgs(args);\r\n\r\n        ArgTypeCategory result = ArgTypeCategory::None;\r\n        for (const auto& arg : argProperties)\r\n        {\r\n            result |= arg.TypeCategory;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    ArgTypeCategory Argument::GetCategoriesAndValidateCommonArguments(const Execution::Args& args, bool requirePackageSelectionArg)\r\n    {\r\n        const auto categories = GetCategoriesPresent(args);\r\n\r\n        // Commands like install require some argument to select a package\r\n        if (requirePackageSelectionArg)\r\n        {\r\n            if (WI_AreAllFlagsClear(categories, ArgTypeCategory::Manifest | ArgTypeCategory::PackageQuery | ArgTypeCategory::SinglePackageQuery))\r\n            {\r\n                throw CommandException(Resource::String::NoPackageSelectionArgumentProvided);\r\n            }\r\n        }\r\n\r\n        // If a manifest is specified, we cannot also have arguments for searching\r\n        if (WI_IsFlagSet(categories, ArgTypeCategory::Manifest) &&\r\n            WI_IsAnyFlagSet(categories, ArgTypeCategory::PackageQuery | ArgTypeCategory::QuerySource))\r\n        {\r\n            throw CommandException(Resource::String::BothManifestAndSearchQueryProvided);\r\n        }\r\n\r\n        // If we have multiple packages, we cannot have arguments that only make sense for a single package\r\n        if (WI_IsFlagSet(categories, ArgTypeCategory::MultiplePackages) &&\r\n            WI_IsAnyFlagSet(categories, ArgTypeCategory::SinglePackageQuery | ArgTypeCategory::SingleInstallerBehavior))\r\n        {\r\n            throw CommandException(Resource::String::ArgumentForSinglePackageProvidedWithMultipleQueries);\r\n        }\r\n\r\n        return categories;\r\n    }\r\n\r\n    Argument::Visibility Argument::GetVisibility() const\r\n    {\r\n        if (!ExperimentalFeature::IsEnabled(m_feature))\r\n        {\r\n            return Argument::Visibility::Hidden;\r\n        }\r\n\r\n        if (!GroupPolicies().IsEnabled(m_groupPolicy))\r\n        {\r\n            return Argument::Visibility::Hidden;\r\n        }\r\n\r\n        return m_visibility;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Argument.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ExecutionContext.h\"\r\n#include \"Resources.h\"\r\n#include <winget/UserSettings.h>\r\n#include <winget/ExperimentalFeature.h>\r\n#include <winget/GroupPolicy.h>\r\n#include <winget/AdminSettings.h>\r\n#include <winget/LocIndependent.h>\r\n\r\n#include <string>\r\n#include <string_view>\r\n\r\n\r\n#define APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_CHAR       '-'\r\n#define APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_STRING     \"-\"\r\n#define APPINSTALLER_CLI_ARGUMENT_SPLIT_CHAR            '='\r\n#define APPINSTALLER_CLI_HELP_ARGUMENT_TEXT_CHAR        '?'\r\n#define APPINSTALLER_CLI_HELP_ARGUMENT_TEXT_STRING      \"?\"\r\n#define APPINSTALLER_CLI_HELP_ARGUMENT                  APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_STRING APPINSTALLER_CLI_HELP_ARGUMENT_TEXT_STRING\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    using namespace AppInstaller::Utility::literals;\r\n\r\n    // The type of argument.\r\n    enum class ArgumentType\r\n    {\r\n        // Argument requires specifying the name before the value.\r\n        Standard,\r\n        // Argument value can be specified alone; position indicates argument name.\r\n        Positional,\r\n        // Only argument name can be specified and indicates a bool value.\r\n        Flag,\r\n    };\r\n\r\n    // Categories an arg type can belong to.\r\n    // Used to reason about the arguments present without having to repeat the same\r\n    // lists every time.\r\n    enum class ArgTypeCategory\r\n    {\r\n        None = 0,\r\n        // The --manifest argument.\r\n        Manifest = 0x1,\r\n        // Arguments for querying or selecting a package.\r\n        // E.g.: --query\r\n        PackageQuery = 0x2,\r\n        // Arguments for querying or selecting a package, which do not work for multiple packages.\r\n        // E.g.: --version\r\n        SinglePackageQuery = 0x4,\r\n        // Arguments for installer or uninstaller selection.\r\n        // E.g.: --scope\r\n        InstallerSelection = 0x8,\r\n        // Arguments for installer or uninstaller behavior.\r\n        // E.g.: --interactive\r\n        InstallerBehavior = 0x10,\r\n        // Arguments for installer or uninstaller behavior, which do not work for multiple packages.\r\n        // E.g.: --override\r\n        SingleInstallerBehavior = 0x20,\r\n        // Arguments for selecting or interacting with the source used for initial querying\r\n        // E.g.: --header\r\n        QuerySource = 0x40,\r\n        // Arguments that only make sense when talking about multiple packages\r\n        MultiplePackages = 0x80,\r\n        // Flag arguments that should be copied over when creating a sub-context\r\n        CopyFlagToSubContext = 0x100,\r\n        // Arguments with associated values that should be copied over when creating a sub-context\r\n        CopyValueToSubContext = 0x200,\r\n        // Arguments for selecting or interacting with dependencies or setting specific source behaviors\r\n        // E.g.: --dependency-source\r\n        // E.g.: --accept-source-agreements\r\n        ExtendedSource = 0x400,\r\n        // Arguments for selecting a configuration set (file or history).\r\n        ConfigurationSetChoice = 0x800,\r\n    };\r\n\r\n    DEFINE_ENUM_FLAG_OPERATORS(ArgTypeCategory);\r\n\r\n    // Exclusive sets an argument can belong to.\r\n    // Only one argument from each exclusive set is allowed at a time.\r\n    enum class ArgTypeExclusiveSet : uint32_t\r\n    {\r\n        None = 0x0,\r\n        ProgressBarOption = 0x1,\r\n        EnableDisable = 0x2,\r\n        PurgePreserve = 0x4,\r\n        PinType = 0x8,\r\n        StubType = 0x10,\r\n        Proxy = 0x20,\r\n        AllAndTargetVersion = 0x40,\r\n        ConfigurationSetChoice = 0x80,\r\n        DscResourceFunction = 0x100,\r\n        DependenciesConflict = 0x200,\r\n\r\n        // This must always be at the end\r\n        Max\r\n    };\r\n\r\n    DEFINE_ENUM_FLAG_OPERATORS(ArgTypeExclusiveSet);\r\n\r\n    // An argument to a command; containing only data that is common to all its uses.\r\n    // Argument extends this by adding command-specific values, like help strings.\r\n    struct ArgumentCommon\r\n    {\r\n        // Defines an argument with no alias.\r\n        constexpr static char NoAlias = '\\0';\r\n\r\n        ArgumentCommon(Execution::Args::Type execArgType, Utility::LocIndView name, char alias, Utility::LocIndView alternateName, ArgTypeCategory typeCategory = ArgTypeCategory::None, ArgTypeExclusiveSet exclusiveSet = ArgTypeExclusiveSet::None)\r\n            : Type(execArgType), Name(name), Alias(alias), AlternateName(alternateName), TypeCategory(typeCategory), ExclusiveSet(exclusiveSet) {}\r\n\r\n        ArgumentCommon(Execution::Args::Type execArgType, Utility::LocIndView name, char alias, ArgTypeCategory typeCategory = ArgTypeCategory::None, ArgTypeExclusiveSet exclusiveSet = ArgTypeExclusiveSet::None)\r\n            : Type(execArgType), Name(name), Alias(alias), TypeCategory(typeCategory), ExclusiveSet(exclusiveSet) {}\r\n\r\n        ArgumentCommon(Execution::Args::Type execArgType, Utility::LocIndView name, Utility::LocIndView alternateName, ArgTypeCategory typeCategory = ArgTypeCategory::None, ArgTypeExclusiveSet exclusiveSet = ArgTypeExclusiveSet::None)\r\n            : Type(execArgType), Name(name), Alias(NoAlias), AlternateName(alternateName), TypeCategory(typeCategory), ExclusiveSet(exclusiveSet) {}\r\n\r\n        ArgumentCommon(Execution::Args::Type execArgType, Utility::LocIndView name, ArgTypeCategory typeCategory = ArgTypeCategory::None, ArgTypeExclusiveSet exclusiveSet = ArgTypeExclusiveSet::None)\r\n            : Type(execArgType), Name(name), Alias(NoAlias), TypeCategory(typeCategory), ExclusiveSet(exclusiveSet) {}\r\n\r\n        // Gets the argument for the given type.\r\n        static ArgumentCommon ForType(Execution::Args::Type execArgType);\r\n\r\n        static std::vector<ArgumentCommon> GetFromExecArgs(const Execution::Args& execArgs);\r\n\r\n        Execution::Args::Type Type;\r\n        Utility::LocIndView Name;\r\n        char Alias;\r\n        Utility::LocIndView AlternateName;\r\n        ArgTypeCategory TypeCategory;\r\n        ArgTypeExclusiveSet ExclusiveSet;\r\n    };\r\n\r\n    // An argument to a command.\r\n    struct Argument\r\n    {\r\n        // Controls the visibility of the field.\r\n        enum class Visibility\r\n        {\r\n            // Shown in the example.\r\n            Example,\r\n            // Shown only in the table below the example.\r\n            Help,\r\n            // Not shown in help.\r\n            Hidden,\r\n        };\r\n\r\n        // Defines an argument with no alternate name\r\n        constexpr static std::string_view NoAlternateName = \"\";\r\n\r\n        Argument(Execution::Args::Type execArgType, Resource::StringId desc) :\r\n            m_argCommon(ArgumentCommon::ForType(execArgType)), m_desc(std::move(desc)) {}\r\n\r\n        Argument(Execution::Args::Type execArgType, Resource::StringId desc, bool required) :\r\n            m_argCommon(ArgumentCommon::ForType(execArgType)), m_desc(std::move(desc)), m_required(required) {}\r\n\r\n        Argument(Execution::Args::Type execArgType, Resource::StringId desc, ArgumentType type) :\r\n            m_argCommon(ArgumentCommon::ForType(execArgType)), m_desc(std::move(desc)), m_type(type) {}\r\n\r\n        Argument(Execution::Args::Type execArgType, Resource::StringId desc, ArgumentType type, Argument::Visibility visibility) :\r\n            m_argCommon(ArgumentCommon::ForType(execArgType)), m_desc(std::move(desc)), m_type(type), m_visibility(visibility) {}\r\n\r\n        Argument(Execution::Args::Type execArgType, Resource::StringId desc, ArgumentType type, bool required) :\r\n            m_argCommon(ArgumentCommon::ForType(execArgType)), m_desc(std::move(desc)), m_type(type), m_required(required) {}\r\n\r\n        Argument(Execution::Args::Type execArgType, Resource::StringId desc, ArgumentType type, Argument::Visibility visibility, bool required) :\r\n            m_argCommon(ArgumentCommon::ForType(execArgType)), m_desc(std::move(desc)), m_type(type), m_visibility(visibility), m_required(required) {}\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        // Constructors for arguments with custom names and aliases to use in tests\r\n        Argument(std::string_view name, char alias, Execution::Args::Type execArgType, Resource::StringId desc, ArgumentType type) :\r\n            m_argCommon(execArgType, Utility::LocIndView{ name }, alias), m_desc(std::move(desc)), m_type(type) {}\r\n\r\n        Argument(std::string_view name, char alias, std::string_view alternateName, Execution::Args::Type execArgType, Resource::StringId desc, ArgumentType type) :\r\n            m_argCommon(execArgType, Utility::LocIndView{ name }, alias, Utility::LocIndView{ alternateName }), m_desc(std::move(desc)), m_type(type) {}\r\n#endif\r\n\r\n        ~Argument() = default;\r\n\r\n        Argument(const Argument&) = default;\r\n        Argument& operator=(const Argument&) = default;\r\n\r\n        Argument(Argument&&) = default;\r\n        Argument& operator=(Argument&&) = default;\r\n\r\n        // Gets the argument for the given type.\r\n        static Argument ForType(Execution::Args::Type type);\r\n\r\n        // Gets the common arguments for all commands.\r\n        static void GetCommon(std::vector<Argument>& args);\r\n\r\n        // Static argument validation helpers; throw CommandException when validation fails.\r\n\r\n        // Requires that at most one argument from the list is present.\r\n        static void ValidateExclusiveArguments(const Execution::Args& args);\r\n\r\n        // Requires that if an argument depends on another one, it is not present without the dependency.\r\n        static void ValidateArgumentDependency(const Execution::Args& args, Execution::Args::Type type, Execution::Args::Type dependencyArgType);\r\n\r\n        static ArgTypeCategory GetCategoriesPresent(const Execution::Args& arg);\r\n\r\n        // Requires that arguments meet common requirements\r\n        static ArgTypeCategory GetCategoriesAndValidateCommonArguments(const Execution::Args& args, bool requirePackageSelectionArg = true);\r\n        static void ValidateCommonArguments(const Execution::Args& args, bool requirePackageSelectionArg = true) { std::ignore = GetCategoriesAndValidateCommonArguments(args, requirePackageSelectionArg); }\r\n\r\n        // Gets the argument usage string in the format of \"-alias,--name\".\r\n        std::string GetUsageString() const;\r\n\r\n        // Arguments are not localized at this time.\r\n        Utility::LocIndView Name() const { return m_argCommon.Name; }\r\n        char Alias() const { return m_argCommon.Alias; }\r\n        std::string_view AlternateName() const { return m_argCommon.AlternateName; }\r\n        Execution::Args::Type ExecArgType() const { return m_argCommon.Type; }\r\n        const Resource::StringId& Description() const { return m_desc; }\r\n        bool Required() const { return m_required; }\r\n        ArgumentType Type() const { return m_type; }\r\n        size_t Limit() const { return m_countLimit; }\r\n        Argument::Visibility GetVisibility() const;\r\n        Settings::ExperimentalFeature::Feature Feature() const { return m_feature; }\r\n        Settings::TogglePolicy::Policy GroupPolicy() const { return m_groupPolicy; }\r\n        Settings::BoolAdminSetting AdminSetting() const { return m_adminSetting; }\r\n\r\n        Argument& SetRequired(bool required) { m_required = required; return *this; }\r\n        Argument& SetCountLimit(size_t countLimit) { m_countLimit = countLimit; return *this; }\r\n\r\n    private:\r\n        // Constructors that set a Feature or Policy are private to force callers to go through the ForType() function.\r\n        // This helps keep it all in one place to reduce chances of missing it somewhere.\r\n        Argument(Execution::Args::Type execArgType, Resource::StringId desc, Settings::ExperimentalFeature::Feature feature) :\r\n            m_argCommon(ArgumentCommon::ForType(execArgType)), m_desc(std::move(desc)), m_feature(feature) {}\r\n\r\n        Argument(Execution::Args::Type execArgType, Resource::StringId desc, bool required, Settings::ExperimentalFeature::Feature feature) :\r\n            m_argCommon(ArgumentCommon::ForType(execArgType)), m_desc(std::move(desc)), m_required(required), m_feature(feature) {}\r\n\r\n        Argument(Execution::Args::Type execArgType, Resource::StringId desc, ArgumentType type, Settings::ExperimentalFeature::Feature feature) :\r\n            m_argCommon(ArgumentCommon::ForType(execArgType)), m_desc(std::move(desc)), m_type(type), m_feature(feature) {}\r\n\r\n        Argument(Execution::Args::Type execArgType, Resource::StringId desc, ArgumentType type, Argument::Visibility visibility, Settings::ExperimentalFeature::Feature feature) :\r\n            m_argCommon(ArgumentCommon::ForType(execArgType)), m_desc(std::move(desc)), m_type(type), m_visibility(visibility), m_feature(feature) {}\r\n\r\n        Argument(Execution::Args::Type execArgType, Resource::StringId desc, ArgumentType type, bool required, Settings::ExperimentalFeature::Feature feature) :\r\n            m_argCommon(ArgumentCommon::ForType(execArgType)), m_desc(std::move(desc)), m_type(type), m_required(required), m_feature(feature) {}\r\n\r\n        Argument(Execution::Args::Type execArgType, Resource::StringId desc, ArgumentType type, Argument::Visibility visibility, bool required, Settings::ExperimentalFeature::Feature feature) :\r\n            m_argCommon(ArgumentCommon::ForType(execArgType)), m_desc(std::move(desc)), m_type(type), m_visibility(visibility), m_required(required), m_feature(feature) {}\r\n\r\n        Argument(Execution::Args::Type execArgType, Resource::StringId desc, ArgumentType type, Settings::TogglePolicy::Policy groupPolicy, Settings::BoolAdminSetting adminSetting) :\r\n            m_argCommon(ArgumentCommon::ForType(execArgType)), m_desc(std::move(desc)), m_type(type), m_groupPolicy(groupPolicy), m_adminSetting(adminSetting) {}\r\n\r\n        Argument(Execution::Args::Type execArgType, Resource::StringId desc, ArgumentType type, Argument::Visibility visibility, Settings::TogglePolicy::Policy groupPolicy, Settings::BoolAdminSetting adminSetting) :\r\n            m_argCommon(ArgumentCommon::ForType(execArgType)), m_desc(std::move(desc)), m_type(type), m_visibility(visibility), m_groupPolicy(groupPolicy), m_adminSetting(adminSetting) {}\r\n\r\n        Argument(Execution::Args::Type execArgType, Resource::StringId desc, ArgumentType type, Settings::ExperimentalFeature::Feature feature, Settings::TogglePolicy::Policy groupPolicy, Settings::BoolAdminSetting adminSetting) :\r\n            m_argCommon(ArgumentCommon::ForType(execArgType)), m_desc(std::move(desc)), m_type(type), m_feature(feature), m_groupPolicy(groupPolicy), m_adminSetting(adminSetting) {}\r\n\r\n        ArgumentCommon m_argCommon;\r\n        Resource::StringId m_desc;\r\n        bool m_required = false;\r\n        ArgumentType m_type = ArgumentType::Standard;\r\n        Argument::Visibility m_visibility = Argument::Visibility::Example;\r\n        size_t m_countLimit = 1;\r\n        Settings::ExperimentalFeature::Feature m_feature = Settings::ExperimentalFeature::Feature::None;\r\n        Settings::TogglePolicy::Policy m_groupPolicy = Settings::TogglePolicy::Policy::None;\r\n        Settings::BoolAdminSetting m_adminSetting = Settings::BoolAdminSetting::Unknown;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/COMContext.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"COMContext.h\"\r\n#include <AppInstallerFileLogger.h>\r\n#include <winget/TraceLogger.h>\r\n#include <winget/OutputDebugStringLogger.h>\r\n\r\nnamespace AppInstaller::CLI::Execution\r\n{\r\n    static constexpr std::string_view s_comLogFileNamePrefix = \"WinGetCOM\"sv;\r\n\r\n    NullStream::NullStream()\r\n    {\r\n        m_nullOut.reset(new std::ostream(&m_nullStreamBuf));\r\n        m_nullIn.reset(new std::istream(&m_nullStreamBuf));\r\n    }\r\n\r\n    void COMContext::AddProgressCallbackFunction(ProgressCallBackFunction&& f)\r\n    {\r\n        std::lock_guard<std::mutex> lock{ m_callbackLock };\r\n        m_comProgressCallbacks.push_back(std::move(f));\r\n    }\r\n\r\n    void COMContext::FireCallbacks(ReportType reportType, uint64_t current, uint64_t maximum, ProgressType progressType, ::AppInstaller::CLI::Workflow::ExecutionStage executionPhase)\r\n    {\r\n        // Lock around iterating through the list. Callbacks should not do long running tasks.\r\n        std::lock_guard<std::mutex> lock{ m_callbackLock };\r\n        for (auto& callback : m_comProgressCallbacks)\r\n        {\r\n            callback(reportType, current, maximum, progressType, executionPhase);\r\n        }\r\n    };\r\n\r\n    void COMContext::BeginProgress()\r\n    {\r\n        FireCallbacks(ReportType::BeginProgress, 0, 0, ProgressType::None, m_executionStage);\r\n    };\r\n\r\n    void COMContext::OnProgress(uint64_t current, uint64_t maximum, ProgressType progressType)\r\n    {\r\n        FireCallbacks(ReportType::Progressing, current, maximum, progressType, m_executionStage);\r\n    }\r\n\r\n    void COMContext::SetProgressMessage(std::string_view)\r\n    {\r\n        // TODO: Consider sending message to COM progress\r\n    }\r\n\r\n    void COMContext::EndProgress(bool)\r\n    {\r\n        FireCallbacks(ReportType::EndProgress, 0, 0, ProgressType::None, m_executionStage);\r\n    };\r\n\r\n    void COMContext::SetExecutionStage(CLI::Workflow::ExecutionStage executionStage)\r\n    {\r\n        m_executionStage = executionStage;\r\n        FireCallbacks(ReportType::ExecutionPhaseUpdate, 0, 0, ProgressType::None, m_executionStage);\r\n        GetThreadGlobals().GetTelemetryLogger().SetExecutionStage(static_cast<uint32_t>(m_executionStage));\r\n    }\r\n\r\n    void COMContext::SetContextLoggers(const std::wstring_view telemetryCorrelationJson, const std::string& caller)\r\n    {\r\n        m_correlationData = telemetryCorrelationJson;\r\n\r\n        std::unique_ptr<AppInstaller::ThreadLocalStorage::PreviousThreadGlobals> setThreadGlobalsToPreviousState = this->SetForCurrentThread();\r\n\r\n        SetLoggers();\r\n        GetThreadGlobals().GetTelemetryLogger().SetTelemetryCorrelationJson(telemetryCorrelationJson);\r\n        GetThreadGlobals().GetTelemetryLogger().SetCaller(caller);\r\n        GetThreadGlobals().GetTelemetryLogger().LogStartup(true);\r\n    }\r\n\r\n    std::wstring_view COMContext::GetCorrelationJson()\r\n    {\r\n        return m_correlationData;\r\n    }\r\n\r\n    void COMContext::SetLoggers(std::optional<AppInstaller::Logging::Channel> channel, std::optional<AppInstaller::Logging::Level> level)\r\n    {\r\n        // Set up debug string logging during initialization\r\n        Logging::OutputDebugStringLogger::Add();\r\n        Logging::Log().SetEnabledChannels(Logging::Channel::All);\r\n        Logging::Log().SetLevel(Logging::Level::Verbose);\r\n\r\n        Logging::Log().SetEnabledChannels(channel.has_value() ? channel.value() : Settings::User().Get<Settings::Setting::LoggingChannelPreference>());\r\n        Logging::Log().SetLevel(level.has_value() ? level.value() : Settings::User().Get<Settings::Setting::LoggingLevelPreference>());\r\n\r\n        // TODO: Log to file for COM API calls only when debugging in visual studio\r\n        Logging::FileLogger::Add(s_comLogFileNamePrefix);\r\n\r\n        Logging::OutputDebugStringLogger::Remove();\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        if (!Settings::User().Get<Settings::Setting::KeepAllLogFiles>())\r\n#endif\r\n        {\r\n            // Initiate the background cleanup of the log file location.\r\n            Logging::FileLogger::BeginCleanup();\r\n        }\r\n\r\n        Logging::TraceLogger::Add();\r\n\r\n        Logging::EnableWilFailureTelemetry();\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/COMContext.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"AppInstallerProgress.h\"\r\n#include \"ExecutionContext.h\"\r\n#include \"Workflows/WorkflowBase.h\"\r\n\r\nnamespace AppInstaller::CLI::Execution\r\n{\r\n    enum class ReportType : uint32_t\r\n    {\r\n        ExecutionPhaseUpdate,\r\n        BeginProgress,\r\n        Progressing,\r\n        EndProgress,\r\n    };\r\n\r\n    class NullStreamBuf : public std::streambuf {};\r\n\r\n    struct NullStream\r\n    {\r\n        NullStream();\r\n\r\n        ~NullStream() = default;\r\n\r\n    protected:\r\n        NullStreamBuf m_nullStreamBuf;\r\n        std::unique_ptr<std::ostream> m_nullOut;\r\n        std::unique_ptr<std::istream> m_nullIn;\r\n    };\r\n\r\n    typedef std::function<void(ReportType reportType, uint64_t current, uint64_t maximum, ProgressType progressType, CLI::Workflow::ExecutionStage executionPhase)> ProgressCallBackFunction;\r\n\r\n    // NullStream constructs the Stream parameters for Context constructor\r\n    // Hence, NullStream should always precede Context in base class order of COMContext's inheritance\r\n    struct COMContext : IProgressSink, NullStream, CLI::Execution::Context\r\n    {\r\n        // When no Console streams need involvement, construct NullStreams instead to pass to Context\r\n        COMContext() : NullStream(), CLI::Execution::Context(*m_nullOut, *m_nullIn)\r\n        {\r\n            Reporter.SetChannel(Reporter::Channel::Disabled);\r\n            Reporter.SetProgressSink(this);\r\n            SetFlags(CLI::Execution::ContextFlag::DisableInteractivity);\r\n        }\r\n\r\n        COMContext(std::ostream& out, std::istream& in) : CLI::Execution::Context(out, in)\r\n        {\r\n            Reporter.SetProgressSink(this);\r\n            SetFlags(CLI::Execution::ContextFlag::DisableInteractivity);\r\n        }\r\n\r\n        ~COMContext() = default;\r\n\r\n        // IProgressSink\r\n        void BeginProgress() override;\r\n        void OnProgress(uint64_t current, uint64_t maximum, ProgressType type) override;\r\n        void SetProgressMessage(std::string_view message) override;\r\n        void EndProgress(bool) override;\r\n\r\n        //Execution::Context\r\n        void SetExecutionStage(CLI::Workflow::ExecutionStage executionPhase);\r\n\r\n        CLI::Workflow::ExecutionStage GetExecutionStage() const { return m_executionStage; }\r\n\r\n        void AddProgressCallbackFunction(ProgressCallBackFunction&& f);\r\n\r\n        // Set Diagnostic and Telemetry loggers, Wil failure callback\r\n        // This should be called only once per COM Server instance\r\n        static void SetLoggers(std::optional<AppInstaller::Logging::Channel> channel = std::nullopt, std::optional<AppInstaller::Logging::Level> level = std::nullopt);\r\n\r\n        // Set COM call context for diagnostic and telemetry loggers\r\n        // This should be called for every COMContext object instance\r\n        void SetContextLoggers(const std::wstring_view telemetryCorrelationJson, const std::string& caller);\r\n\r\n        std::wstring_view GetCorrelationJson();\r\n\r\n    private:\r\n        void FireCallbacks(ReportType reportType, uint64_t current, uint64_t maximum, ProgressType progressType, ::AppInstaller::CLI::Workflow::ExecutionStage executionPhase);\r\n\r\n        CLI::Workflow::ExecutionStage m_executionStage = CLI::Workflow::ExecutionStage::Initial;\r\n        std::vector<ProgressCallBackFunction> m_comProgressCallbacks;\r\n        std::wstring m_correlationData = L\"\";\r\n        std::mutex m_callbackLock;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/ChannelStreams.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ChannelStreams.h\"\r\n\r\n\r\nnamespace AppInstaller::CLI::Execution\r\n{\r\n    using namespace VirtualTerminal;\r\n\r\n    size_t GetConsoleWidth()\r\n    {\r\n        CONSOLE_SCREEN_BUFFER_INFO consoleInfo{};\r\n        if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo))\r\n        {\r\n            return static_cast<size_t>(consoleInfo.dwSize.X);\r\n        }\r\n        else\r\n        {\r\n            return 120;\r\n        }\r\n    }\r\n\r\n    BaseStream::BaseStream(std::ostream& out, bool enabled, bool VTEnabled) :\r\n        m_out(out), m_enabled(enabled), m_VTEnabled(VTEnabled) {}\r\n\r\n    BaseStream& BaseStream::operator<<(std::ostream& (__cdecl* f)(std::ostream&))\r\n    {\r\n        if (m_enabled)\r\n        {\r\n            f(m_out);\r\n        }\r\n        return *this;\r\n    }\r\n\r\n    BaseStream& BaseStream::operator<<(const Sequence& sequence)\r\n    {\r\n        if (m_enabled && m_VTEnabled)\r\n        {\r\n            m_VTUpdated = true;\r\n            m_out << sequence;\r\n        }\r\n        return *this;\r\n    }\r\n\r\n    BaseStream& BaseStream::operator<<(const ConstructedSequence& sequence)\r\n    {\r\n        if (m_enabled && m_VTEnabled)\r\n        {\r\n            m_VTUpdated = true;\r\n            m_out << sequence;\r\n        }\r\n        return *this;\r\n    }\r\n\r\n    void BaseStream::SetVTEnabled(bool enabled)\r\n    {\r\n        m_VTEnabled = enabled;\r\n    }\r\n\r\n    void BaseStream::RestoreDefault()\r\n    {\r\n        if (m_VTUpdated)\r\n        {\r\n            Write(TextFormat::Default, true);\r\n        }\r\n    }\r\n\r\n    void BaseStream::Disable()\r\n    {\r\n        m_enabled = false;\r\n    }\r\n\r\n    std::ostream& BaseStream::Get()\r\n    {\r\n        return m_out;\r\n    }\r\n\r\n    OutputStream::OutputStream(BaseStream& out, bool enabled, bool VTEnabled) :\r\n        m_out(out),\r\n        m_enabled(enabled),\r\n        m_VTEnabled(VTEnabled)\r\n    {}\r\n\r\n    void OutputStream::AddFormat(const Sequence& sequence)\r\n    {\r\n        m_format.Append(sequence);\r\n    }\r\n\r\n    void OutputStream::ClearFormat()\r\n    {\r\n        m_format.Clear();\r\n    }\r\n\r\n    void OutputStream::ApplyFormat()\r\n    {\r\n        // Only apply format if m_applyFormatAtOne == 1 coming into this function.\r\n        if (m_applyFormatAtOne)\r\n        {\r\n            if (!--m_applyFormatAtOne)\r\n            {\r\n                m_out << m_format;\r\n            }\r\n        }\r\n    }\r\n\r\n    OutputStream& OutputStream::operator<<(std::ostream& (__cdecl* f)(std::ostream&))\r\n    {\r\n        if (m_enabled)\r\n        {\r\n            m_out << f;\r\n        }\r\n        \r\n        return *this;\r\n    }\r\n\r\n    OutputStream& OutputStream::operator<<(const Sequence& sequence)\r\n    {\r\n        if (m_enabled && m_VTEnabled)\r\n        {\r\n            // Apply format as normal to ensure that any previous format doesn't bleed through.\r\n            ApplyFormat();\r\n\r\n            m_out << sequence;\r\n\r\n            // An incoming sequence will be valid for 1 \"standard\" output after this one.\r\n            // We set this to 2 to make that happen, because when it is 1, we will output\r\n            // the format for the current OutputStream.\r\n            m_applyFormatAtOne = 2;\r\n        }\r\n        \r\n        return *this;\r\n    }\r\n\r\n    OutputStream& OutputStream::operator<<(const ConstructedSequence& sequence)\r\n    {\r\n        if (m_enabled && m_VTEnabled)\r\n        {\r\n            // Apply format as normal to ensure that any previous format doesn't bleed through.\r\n            ApplyFormat();\r\n\r\n            m_out << sequence;\r\n            // An incoming sequence will be valid for 1 \"standard\" output after this one.\r\n            // We set this to 2 to make that happen, because when it is 1, we will output\r\n            // the format for the current OutputStream.\r\n            m_applyFormatAtOne = 2;\r\n        }\r\n        \r\n        return *this;\r\n    }\r\n\r\n    OutputStream& OutputStream::operator<<(const std::filesystem::path& path)\r\n    {\r\n        if (m_enabled)\r\n        {\r\n            if (m_VTEnabled)\r\n            {\r\n                ApplyFormat();\r\n            }\r\n            m_out << path.u8string();\r\n        }\r\n        return *this;\r\n        \r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/ChannelStreams.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Resources.h\"\r\n#include \"VTSupport.h\"\r\n#include <winget/LocIndependent.h>\r\n\r\n#include <ostream>\r\n#include <string>\r\n\r\n\r\nnamespace AppInstaller::CLI::Execution\r\n{\r\n    // Gets the current console width.\r\n    size_t GetConsoleWidth();\r\n\r\n    // The base stream for all channels.\r\n    struct BaseStream\r\n    {\r\n        BaseStream(std::ostream& out, bool enabled, bool VTEnabled);\r\n\r\n        template <typename T>\r\n        BaseStream& operator<<(const T& t)\r\n        {\r\n            Write<T>(t, false);\r\n            return *this;\r\n        }\r\n\r\n        BaseStream& operator<<(std::ostream& (__cdecl* f)(std::ostream&));\r\n        BaseStream& operator<<(const VirtualTerminal::Sequence& sequence);\r\n        BaseStream& operator<<(const VirtualTerminal::ConstructedSequence& sequence);\r\n\r\n        void SetVTEnabled(bool enabled);\r\n\r\n        void RestoreDefault();\r\n\r\n        void Disable();\r\n\r\n        std::ostream& Get();\r\n\r\n    private:\r\n        template <typename T>\r\n        void Write(const T& t, bool bypass)\r\n        {\r\n            if (bypass || m_enabled)\r\n            {\r\n                m_out << t;\r\n            }\r\n        };\r\n\r\n        std::ostream& m_out;\r\n        std::atomic_bool m_enabled;\r\n        std::atomic_bool m_VTUpdated;\r\n        bool m_VTEnabled;\r\n    };\r\n\r\n    // Holds output formatting information.\r\n    struct OutputStream\r\n    {\r\n        OutputStream(BaseStream& out, bool enabled, bool VTEnabled = true);\r\n\r\n        // Adds a format to the current value.\r\n        void AddFormat(const VirtualTerminal::Sequence& sequence);\r\n\r\n        // Clears the current format value.\r\n        void ClearFormat();\r\n\r\n        template <typename T>\r\n        OutputStream& operator<<(const T& t)\r\n        {\r\n            // You've found your way here because you tried to output a type that may not localized.\r\n            // In order to ensure that all output is localized, only the types with specializations of\r\n            // details::IsApprovedForOutput above can be output.\r\n            // * If your string is a simple message, it should be put in\r\n            //      /src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw\r\n            //      and referenced in /src/AppInstallerCLICore/Resources.h. Then either output the\r\n            //      Resource::StringId, or load it manually and output the Resource::LocString.\r\n            // * If your string is *definitely* localization independent, you can tag it as such with\r\n            //      the Utility::LocInd(View/String) types.\r\n            // * If your string came from outside of the source code, it is best to store it in a\r\n            //      Utility::NormalizedString so that it has a normalized representation. This also\r\n            //      informs the output that there is no localized version to use.\r\n            // TODO: This assertion is currently only applied to placeholders in localized strings.\r\n            //       Convert the rest of the code base and uncomment to enforce localization.\r\n            //static_assert(details::IsApprovedForOutput<std::decay_t<T>>::value, \"This type may not be localized, see comment for more information\");\r\n            if (m_enabled)\r\n            {\r\n                if (m_VTEnabled)\r\n                {\r\n                    ApplyFormat();\r\n                }\r\n                m_out << t;\r\n            }\r\n            return *this;\r\n        }\r\n\r\n        OutputStream& operator<<(std::ostream& (__cdecl* f)(std::ostream&));\r\n        OutputStream& operator<<(const VirtualTerminal::Sequence& sequence);\r\n        OutputStream& operator<<(const VirtualTerminal::ConstructedSequence& sequence);\r\n        OutputStream& operator<<(const std::filesystem::path& path);\r\n\r\n        inline bool IsEnabled() {\r\n            return m_enabled;\r\n        }\r\n\r\n    private:\r\n        // Applies the format for the stream.\r\n        void ApplyFormat();\r\n\r\n        BaseStream& m_out;\r\n        bool m_enabled;\r\n        bool m_VTEnabled;\r\n        size_t m_applyFormatAtOne = 1;\r\n        VirtualTerminal::ConstructedSequence m_format;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/CheckpointManager.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"CheckpointManager.h\"\n#include \"Command.h\"\n#include \"ExecutionContextData.h\"\n#include <AppInstallerRuntime.h>\n\nusing namespace AppInstaller::CLI;\nusing namespace AppInstaller::Repository::Microsoft;\nusing namespace AppInstaller::SQLite;\n\nnamespace AppInstaller::Checkpoints\n{\n\n    // This checkpoint name is reserved for the starting checkpoint which captures the automatic metadata.\n    constexpr std::string_view s_AutomaticCheckpoint = \"automatic\"sv;\n    constexpr std::string_view s_CheckpointsFileName = \"checkpoints.db\"sv;\n\n    std::filesystem::path CheckpointManager::GetCheckpointDatabasePath(const std::string_view& resumeId, bool createCheckpointDirectory)\n    {\n        const auto checkpointsDirectory = Runtime::GetPathTo(Runtime::PathName::CheckpointsLocation) / resumeId;\n\n        if (createCheckpointDirectory)\n        {\n            if (!std::filesystem::exists(checkpointsDirectory))\n            {\n                AICLI_LOG(Repo, Info, << \"Creating checkpoint database directory: \" << checkpointsDirectory);\n                std::filesystem::create_directories(checkpointsDirectory);\n            }\n            else\n            {\n                THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_CANNOT_MAKE), !std::filesystem::is_directory(checkpointsDirectory));\n            }\n        }\n\n        auto recordPath = checkpointsDirectory / s_CheckpointsFileName;\n        return recordPath;\n    }\n\n    CheckpointManager::CheckpointManager()\n    {\n        GUID resumeId;\n        std::ignore = CoCreateGuid(&resumeId);\n        m_resumeId = Utility::ConvertGuidToString(resumeId);\n        const auto& checkpointDatabasePath = GetCheckpointDatabasePath(m_resumeId, true);\n        m_checkpointDatabase = CheckpointDatabase::CreateNew(checkpointDatabasePath.u8string());\n    }\n\n    CheckpointManager::CheckpointManager(const std::string& resumeId)\n    {\n        m_resumeId = resumeId;\n        const auto& checkpointDatabasePath = GetCheckpointDatabasePath(m_resumeId);\n        m_checkpointDatabase = CheckpointDatabase::Open(checkpointDatabasePath.u8string());\n    }\n\n    void CheckpointManager::CreateAutomaticCheckpoint(CLI::Execution::Context& context)\n    {\n        CheckpointDatabase::IdType startCheckpointId = m_checkpointDatabase->AddCheckpoint(s_AutomaticCheckpoint);\n        Checkpoint<AutomaticCheckpointData> automaticCheckpoint{ m_checkpointDatabase, startCheckpointId };\n\n        automaticCheckpoint.Set(AutomaticCheckpointData::ClientVersion, {}, AppInstaller::Runtime::GetClientVersion());\n\n        const auto& executingCommand = context.GetExecutingCommand();\n        if (executingCommand != nullptr)\n        {\n            automaticCheckpoint.Set(AutomaticCheckpointData::Command, {}, std::string{ executingCommand->FullName() });\n        }\n\n        const auto& argTypes = context.Args.GetTypes();\n        for (auto type : argTypes)\n        {\n            const auto& argument = std::to_string(static_cast<int>(type));\n            auto argumentType = Argument::ForType(type).Type();\n\n            if (argumentType == ArgumentType::Flag)\n            {\n                automaticCheckpoint.Set(AutomaticCheckpointData::Arguments, argument, {});\n            }\n            else\n            {\n                const auto& values = *context.Args.GetArgs(type);\n                automaticCheckpoint.SetMany(AutomaticCheckpointData::Arguments, argument, values);\n            }\n        }\n\n        automaticCheckpoint.Set(AutomaticCheckpointData::ResumeCount, {}, std::to_string(0));\n    }\n\n    void LoadCommandArgsFromAutomaticCheckpoint(CLI::Execution::Context& context, Checkpoint<AutomaticCheckpointData>& automaticCheckpoint)\n    {\n        for (const auto& fieldName : automaticCheckpoint.GetFieldNames(AutomaticCheckpointData::Arguments))\n        {\n            // Command arguments are represented as integer strings in the checkpoint record.\n            Execution::Args::Type type = static_cast<Execution::Args::Type>(std::stoi(fieldName));\n            auto argumentType = Argument::ForType(type).Type();\n            if (argumentType == ArgumentType::Flag)\n            {\n                context.Args.AddArg(type);\n            }\n            else\n            {\n                const auto& values = automaticCheckpoint.GetMany(AutomaticCheckpointData::Arguments, fieldName);\n                for (const auto& value : values)\n                {\n                    context.Args.AddArg(type, value);\n                }\n            }\n        }\n    }\n\n    std::optional<Checkpoint<AutomaticCheckpointData>> CheckpointManager::GetAutomaticCheckpoint()\n    {\n        const auto& checkpointIds = m_checkpointDatabase->GetCheckpointIds();\n        if (checkpointIds.empty())\n        {\n            return {};\n        }\n\n        CheckpointDatabase::IdType automaticCheckpointId = checkpointIds.back();\n        return Checkpoint<AutomaticCheckpointData>{ m_checkpointDatabase, automaticCheckpointId };\n    }\n\n    Checkpoint<CLI::Execution::Data> CheckpointManager::CreateCheckpoint(std::string_view checkpointName)\n    {\n        CheckpointDatabase::IdType checkpointId = m_checkpointDatabase->AddCheckpoint(checkpointName);\n        Checkpoint<CLI::Execution::Data> checkpoint{ m_checkpointDatabase, checkpointId };\n        return checkpoint;\n    }\n\n    std::vector<Checkpoint<CLI::Execution::Data>> CheckpointManager::GetCheckpoints()\n    {\n        auto checkpointIds = m_checkpointDatabase->GetCheckpointIds();\n        if (checkpointIds.empty())\n        {\n            return {};\n        }\n\n        // Remove the last checkpoint (automatic)\n        checkpointIds.pop_back();\n\n        std::vector<Checkpoint<CLI::Execution::Data>> checkpoints;\n        for (const auto& checkpointId : checkpointIds)\n        {\n            checkpoints.emplace_back(Checkpoint<CLI::Execution::Data>{ m_checkpointDatabase, checkpointId });\n        }\n\n        return checkpoints;\n    }\n\n    void CheckpointManager::CleanUpDatabase()\n    {\n        if (m_checkpointDatabase)\n        {\n            m_checkpointDatabase.reset();\n        }\n\n        if (!m_resumeId.empty())\n        {\n            const auto& checkpointDatabasePath = GetCheckpointDatabasePath(m_resumeId);\n            if (std::filesystem::exists(checkpointDatabasePath))\n            {\n                const auto& checkpointDatabaseParentDirectory = checkpointDatabasePath.parent_path();\n                AICLI_LOG(CLI, Info, << \"Deleting Checkpoint database directory: \" << checkpointDatabaseParentDirectory);\n                std::filesystem::remove_all(checkpointDatabaseParentDirectory);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/CheckpointManager.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"ExecutionContextData.h\"\n#include \"ExecutionContext.h\"\n#include <winget/Checkpoint.h>\n#include <guiddef.h>\n\nnamespace AppInstaller::Checkpoints\n{\n    // Reads the command arguments from the automatic checkpoint and populates the context.\n    void LoadCommandArgsFromAutomaticCheckpoint(CLI::Execution::Context& context, Checkpoint<AutomaticCheckpointData>& automaticCheckpoint);\n\n    // Owns the lifetime of a checkpoint data base and creates the checkpoints.\n    struct CheckpointManager\n    {\n        // Constructor that generates a new resume id and creates the checkpoint database.\n        CheckpointManager();\n\n        // Constructor that loads the resume id and opens an existing checkpoint database.\n        CheckpointManager(const std::string& resumeId);\n\n        ~CheckpointManager() = default;\n\n        // Gets the file path of the checkpoint database.\n        static std::filesystem::path GetCheckpointDatabasePath(const std::string_view& resumeId, bool createCheckpointDirectory = false);\n\n        // Gets the resume id.\n        std::string GetResumeId() { return m_resumeId; };\n\n        // Gets the automatic checkpoint.\n        std::optional<Checkpoint<AutomaticCheckpointData>> GetAutomaticCheckpoint();\n\n        // Creates an automatic checkpoint using the provided context.\n        void CreateAutomaticCheckpoint(CLI::Execution::Context& context);\n\n        // Gets all context data checkpoints.\n        std::vector<Checkpoint<CLI::Execution::Data>> GetCheckpoints();\n\n        // Creates a new context data checkpoint.\n        Checkpoint<CLI::Execution::Data> CreateCheckpoint(std::string_view checkpointName);\n\n        // Cleans up the checkpoint database.\n        void CleanUpDatabase();\n\n    private:\n        std::string m_resumeId;\n        std::shared_ptr<AppInstaller::Repository::Microsoft::CheckpointDatabase> m_checkpointDatabase;\n    };\n}"
  },
  {
    "path": "src/AppInstallerCLICore/Command.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Command.h\"\r\n#include \"Resources.h\"\r\n#include \"Sixel.h\"\r\n#include <winget/UserSettings.h>\r\n#include <AppInstallerRuntime.h>\r\n#include <winget/Locale.h>\r\n#include <winget/Reboot.h>\r\n#include <winget/Authentication.h>\r\n\r\nusing namespace std::string_view_literals;\r\nusing namespace AppInstaller::Utility::literals;\r\nusing namespace AppInstaller::Settings;\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    namespace\r\n    {\r\n        constexpr Utility::LocIndView s_Command_ArgName_SilentAndInteractive = \"silent|interactive\"_liv;\r\n\r\n        void LaunchLogsIfRequested(Execution::Context& context)\r\n        {\r\n            try\r\n            {\r\n                if (context.Args.Contains(Execution::Args::Type::OpenLogs))\r\n                {\r\n                    // TODO: Consider possibly adding functionality that if the context contains 'Execution::Args::Type::Log' to open the path provided for the log\r\n                    // The above was omitted initially as a security precaution to ensure that user input to '--log' wouldn't be passed directly to ShellExecute\r\n                    ShellExecute(NULL, NULL, Runtime::GetPathTo(Runtime::PathName::DefaultLogLocation).wstring().c_str(), NULL, NULL, SW_SHOWNORMAL);\r\n                }\r\n            }\r\n            CATCH_LOG();\r\n        }\r\n    }\r\n\r\n    Command::Command(\r\n        std::string_view name,\r\n        std::vector<std::string_view> aliases,\r\n        std::string_view parent,\r\n        Command::Visibility visibility,\r\n        Settings::ExperimentalFeature::Feature feature,\r\n        Settings::TogglePolicy::Policy groupPolicy,\r\n        CommandOutputFlags outputFlags) :\r\n        m_name(name), m_aliases(std::move(aliases)), m_visibility(visibility), m_feature(feature), m_groupPolicy(groupPolicy), m_outputFlags(outputFlags)\r\n    {\r\n        if (!parent.empty())\r\n        {\r\n            m_fullName.reserve(parent.length() + 1 + name.length());\r\n            m_fullName = parent;\r\n            m_fullName += ParentSplitChar;\r\n            m_fullName += name;\r\n        }\r\n        else\r\n        {\r\n            m_fullName = name;\r\n        }\r\n    }\r\n\r\n    void Command::OutputIntroHeader(Execution::Reporter& reporter) const\r\n    {\r\n        auto infoOut = reporter.Info();\r\n        VirtualTerminal::ConstructedSequence indent;\r\n\r\n        if (reporter.SixelsEnabled())\r\n        {\r\n            try\r\n            {\r\n                std::filesystem::path imagePath = Runtime::GetPathTo(Runtime::PathName::ImageAssets);\r\n\r\n                if (!imagePath.empty())\r\n                {\r\n                    // This image matches the target pixel size. If changing the target size, choose the most appropriate image.\r\n                    imagePath /= \"AppList.targetsize-40.png\";\r\n\r\n                    VirtualTerminal::Sixel::Image wingetIcon{ imagePath };\r\n\r\n                    // Using a height of 2 to match the two lines of header.\r\n                    UINT imageHeightCells = 2;\r\n                    UINT imageWidthCells = 2 * imageHeightCells;\r\n\r\n                    wingetIcon.RenderSizeInCells(imageWidthCells, imageHeightCells);\r\n                    wingetIcon.RenderTo(infoOut);\r\n\r\n                    indent = VirtualTerminal::Cursor::Position::Forward(static_cast<int16_t>(imageWidthCells));\r\n                    infoOut << VirtualTerminal::Cursor::Position::Up(static_cast<int16_t>(imageHeightCells) - 1);\r\n                }\r\n            }\r\n            CATCH_LOG();\r\n        }\r\n\r\n        auto productName = Runtime::IsReleaseBuild() ? Resource::String::WindowsPackageManager : Resource::String::WindowsPackageManagerPreview;\r\n        infoOut << indent << productName(Runtime::GetClientVersion()) << std::endl\r\n            << indent << Resource::String::MainCopyrightNotice << std::endl;\r\n    }\r\n\r\n    void Command::OutputHelp(Execution::Reporter& reporter, const CommandException* exception) const\r\n    {\r\n        // Header\r\n        OutputIntroHeader(reporter);\r\n        reporter.EmptyLine();\r\n\r\n        // Error if given\r\n        if (exception)\r\n        {\r\n            reporter.Error() << exception->Message() << std::endl << std::endl;\r\n        }\r\n\r\n        // Description\r\n        auto infoOut = reporter.Info();\r\n        infoOut <<\r\n            LongDescription() << std::endl <<\r\n            std::endl;\r\n\r\n        // Example usage for this command\r\n        // First create the command chain for output\r\n        std::string commandChain = FullName();\r\n        size_t firstSplit = commandChain.find_first_of(ParentSplitChar);\r\n        if (firstSplit == std::string::npos)\r\n        {\r\n            commandChain.clear();\r\n        }\r\n        else\r\n        {\r\n            commandChain = commandChain.substr(firstSplit + 1);\r\n            for (char& c : commandChain)\r\n            {\r\n                if (c == ParentSplitChar)\r\n                {\r\n                    c = ' ';\r\n                }\r\n            }\r\n        }\r\n\r\n        // Output the command preamble and command chain\r\n        infoOut << Resource::String::Usage(\"winget\"_liv, Utility::LocIndView{ commandChain });\r\n\r\n        auto commandAliases = Aliases();\r\n        auto commands = GetVisibleCommands();\r\n        auto arguments = GetVisibleArguments();\r\n\r\n        bool hasArguments = false;\r\n        bool hasOptions = false;\r\n\r\n        // Output the command token, made optional if arguments are present.\r\n        if (!commands.empty())\r\n        {\r\n            infoOut << ' ';\r\n\r\n            if (!arguments.empty())\r\n            {\r\n                infoOut << '[';\r\n            }\r\n\r\n            infoOut << '<' << Resource::String::Command << '>';\r\n\r\n            if (!arguments.empty())\r\n            {\r\n                infoOut << ']';\r\n            }\r\n        }\r\n\r\n        // Arguments are required by a test to have all positionals first.\r\n        for (const auto& arg : arguments)\r\n        {\r\n            if (arg.Type() == ArgumentType::Positional)\r\n            {\r\n                hasArguments = true;\r\n\r\n                infoOut << ' ';\r\n\r\n                if (!arg.Required())\r\n                {\r\n                    infoOut << '[';\r\n                }\r\n\r\n                infoOut << '[';\r\n\r\n                if (arg.Alias() == ArgumentCommon::NoAlias)\r\n                {\r\n                    infoOut << APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_CHAR << APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_CHAR << arg.Name();\r\n                }\r\n                else\r\n                {\r\n                    infoOut << APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_CHAR << arg.Alias();\r\n                }\r\n\r\n                infoOut << \"] <\"_liv << arg.Name() << '>';\r\n\r\n                if (arg.Limit() > 1)\r\n                {\r\n                    infoOut << \"...\"_liv;\r\n                }\r\n\r\n                if (!arg.Required())\r\n                {\r\n                    infoOut << ']';\r\n                }\r\n            }\r\n            else\r\n            {\r\n                hasOptions = true;\r\n                infoOut << \" [<\"_liv << Resource::String::Options << \">]\"_liv;\r\n                break;\r\n            }\r\n        }\r\n\r\n        infoOut <<\r\n            std::endl <<\r\n            std::endl;\r\n\r\n        if (!commandAliases.empty())\r\n        {\r\n            infoOut << Resource::String::AvailableCommandAliases << std::endl;\r\n            \r\n            for (const auto& commandAlias : commandAliases)\r\n            {\r\n                infoOut << \"  \"_liv << Execution::HelpCommandEmphasis << commandAlias << std::endl;\r\n            }\r\n            infoOut << std::endl;\r\n        }\r\n\r\n        if (!commands.empty())\r\n        {\r\n            if (Name() == FullName())\r\n            {\r\n                infoOut << Resource::String::AvailableCommands << std::endl;\r\n            }\r\n            else\r\n            {\r\n                infoOut << Resource::String::AvailableSubcommands << std::endl;\r\n            }\r\n\r\n            size_t maxCommandNameLength = 0;\r\n            for (const auto& command : commands)\r\n            {\r\n                maxCommandNameLength = std::max(maxCommandNameLength, command->Name().length());\r\n            }\r\n\r\n            for (const auto& command : commands)\r\n            {\r\n                size_t fillChars = (maxCommandNameLength - command->Name().length()) + 2;\r\n                infoOut << \"  \"_liv << Execution::HelpCommandEmphasis << command->Name() << Utility::LocIndString{ std::string(fillChars, ' ') } << command->ShortDescription() << std::endl;\r\n            }\r\n\r\n            infoOut <<\r\n                std::endl <<\r\n                Resource::String::HelpForDetails\r\n                << \" [\"_liv << APPINSTALLER_CLI_HELP_ARGUMENT << ']' << std::endl;\r\n        }\r\n\r\n        if (!arguments.empty())\r\n        {\r\n            if (!commands.empty())\r\n            {\r\n                infoOut << std::endl;\r\n            }\r\n\r\n            std::vector<std::string> argNames;\r\n            size_t maxArgNameLength = 0;\r\n            for (const auto& arg : arguments)\r\n            {\r\n                argNames.emplace_back(arg.GetUsageString());\r\n                maxArgNameLength = std::max(maxArgNameLength, argNames.back().length());\r\n            }\r\n\r\n            if (hasArguments)\r\n            {\r\n                infoOut << Resource::String::AvailableArguments << std::endl;\r\n\r\n                size_t i = 0;\r\n                for (const auto& arg : arguments)\r\n                {\r\n                    const std::string& argName = argNames[i++];\r\n                    if (arg.Type() == ArgumentType::Positional)\r\n                    {\r\n                        size_t fillChars = (maxArgNameLength - argName.length()) + 2;\r\n                        infoOut << \"  \"_liv << Execution::HelpArgumentEmphasis << argName << Utility::LocIndString{ std::string(fillChars, ' ') } << arg.Description() << std::endl;\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (hasOptions)\r\n            {\r\n                if (hasArguments)\r\n                {\r\n                    infoOut << std::endl;\r\n                }\r\n\r\n                infoOut << Resource::String::AvailableOptions << std::endl;\r\n\r\n                size_t i = 0;\r\n                for (const auto& arg : arguments)\r\n                {\r\n                    const std::string& argName = argNames[i++];\r\n                    if (arg.Type() != ArgumentType::Positional)\r\n                    {\r\n                        size_t fillChars = (maxArgNameLength - argName.length()) + 2;\r\n                        infoOut << \"  \"_liv << Execution::HelpArgumentEmphasis << argName << Utility::LocIndString{ std::string(fillChars, ' ') } << arg.Description() << std::endl;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // Finally, the link to the documentation pages\r\n        auto helpLink = HelpLink();\r\n        if (!helpLink.empty())\r\n        {\r\n            infoOut << std::endl << Resource::String::HelpLinkPreamble(helpLink) << std::endl;\r\n        }\r\n    }\r\n\r\n    std::unique_ptr<Command> Command::FindSubCommand(Invocation& inv) const\r\n    {\r\n        auto itr = inv.begin();\r\n        if (itr == inv.end() || (*itr)[0] == APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_CHAR)\r\n        {\r\n            // No more command arguments to check, so no command to find\r\n            return {};\r\n        }\r\n\r\n        auto commands = GetCommands();\r\n        if (commands.empty())\r\n        {\r\n            // No more subcommands\r\n            return {};\r\n        }\r\n\r\n        for (auto& command : commands)\r\n        {\r\n            if (\r\n                Utility::CaseInsensitiveEquals(*itr, command->Name()) ||\r\n                Utility::CaseInsensitiveContains(command->Aliases(), *itr)\r\n            )\r\n            {\r\n                if (!ExperimentalFeature::IsEnabled(command->Feature()))\r\n                {\r\n                    auto feature = ExperimentalFeature::GetFeature(command->Feature());\r\n                    AICLI_LOG(CLI, Error, << \"Trying to use command: \" << *itr << \" without enabling feature \" << feature.JsonName());\r\n                    throw CommandException(Resource::String::FeatureDisabledMessage(feature.JsonName()));\r\n                }\r\n\r\n                if (!Settings::GroupPolicies().IsEnabled(command->GroupPolicy()))\r\n                {\r\n                    auto policy = TogglePolicy::GetPolicy(command->GroupPolicy());\r\n                    AICLI_LOG(CLI, Error, << \"Trying to use command: \" << *itr << \" disabled by group policy \" << policy.RegValueName());\r\n                    throw GroupPolicyException(command->GroupPolicy());\r\n                }\r\n\r\n                AICLI_LOG(CLI, Info, << \"Found subcommand: \" << *itr);\r\n                inv.consume(itr);\r\n                return std::move(command);\r\n            }\r\n        }\r\n\r\n        // The command has opted-in to be executed when it has subcommands and the next token is a positional parameter value\r\n        if (m_selectCurrentCommandIfUnrecognizedSubcommandFound)\r\n        {\r\n            return {};\r\n        }\r\n\r\n        // TODO: If we get to a large number of commands, do a fuzzy search much like git\r\n        throw CommandException(Resource::String::UnrecognizedCommand(Utility::LocIndView{ *itr }));\r\n    }\r\n\r\n    // The argument parsing state machine.\r\n    // It is broken out to enable completion to process arguments, ignore errors,\r\n    // and determine the likely state of the word to be completed.\r\n    struct ParseArgumentsStateMachine\r\n    {\r\n        ParseArgumentsStateMachine(Invocation& inv, Execution::Args& execArgs, std::vector<CLI::Argument> arguments);\r\n\r\n        ParseArgumentsStateMachine(const ParseArgumentsStateMachine&) = delete;\r\n        ParseArgumentsStateMachine& operator=(const ParseArgumentsStateMachine&) = delete;\r\n\r\n        ParseArgumentsStateMachine(ParseArgumentsStateMachine&&) = default;\r\n        ParseArgumentsStateMachine& operator=(ParseArgumentsStateMachine&&) = default;\r\n\r\n        // Processes the next argument from the invocation.\r\n        // Returns true if there was an argument to process;\r\n        // returns false if there were none.\r\n        bool Step();\r\n\r\n        // Throws if there was an error during the prior step.\r\n        void ThrowIfError() const;\r\n\r\n        // The current state of the state machine.\r\n        // An empty state indicates that the next argument can be anything.\r\n        struct State\r\n        {\r\n            State() = default;\r\n            State(Execution::Args::Type type, std::string_view arg) : m_type(type), m_arg(arg) {}\r\n            State(CommandException ce) : m_exception(std::move(ce)) {}\r\n\r\n            // If set, indicates that the next argument is a value for this type.\r\n            const std::optional<Execution::Args::Type>& Type() const { return m_type; }\r\n\r\n            // The actual argument string associated with Type.\r\n            const Utility::LocIndString& Arg() const { return m_arg; }\r\n\r\n            // If set, indicates that the last argument produced an error.\r\n            const std::optional<CommandException>& Exception() const { return m_exception; }\r\n\r\n        private:\r\n            std::optional<Execution::Args::Type> m_type;\r\n            Utility::LocIndString m_arg;\r\n            std::optional<CommandException> m_exception;\r\n        };\r\n\r\n        const State& GetState() const { return m_state; }\r\n\r\n        bool OnlyPositionalRemain() const { return m_onlyPositionalArgumentsRemain; }\r\n\r\n        // Gets the next positional argument, or nullptr if there is not one.\r\n        const CLI::Argument* NextPositional();\r\n\r\n        const std::vector<CLI::Argument>& Arguments() const { return m_arguments; }\r\n\r\n    private:\r\n        State StepInternal();\r\n\r\n        void ProcessAdjoinedValue(Execution::Args::Type type, std::string_view value);\r\n\r\n        Invocation& m_invocation;\r\n        Execution::Args& m_executionArgs;\r\n        std::vector<CLI::Argument> m_arguments;\r\n\r\n        Invocation::iterator m_invocationItr;\r\n        std::vector<CLI::Argument>::iterator m_positionalSearchItr;\r\n        bool m_onlyPositionalArgumentsRemain = false;\r\n\r\n        State m_state;\r\n    };\r\n\r\n    ParseArgumentsStateMachine::ParseArgumentsStateMachine(Invocation& inv, Execution::Args& execArgs, std::vector<CLI::Argument> arguments) :\r\n        m_invocation(inv),\r\n        m_executionArgs(execArgs),\r\n        m_arguments(std::move(arguments)),\r\n        m_invocationItr(m_invocation.begin()),\r\n        m_positionalSearchItr(m_arguments.begin())\r\n    {\r\n    }\r\n\r\n    bool ParseArgumentsStateMachine::Step()\r\n    {\r\n        if (m_invocationItr == m_invocation.end())\r\n        {\r\n            return false;\r\n        }\r\n\r\n        m_state = StepInternal();\r\n        return true;\r\n    }\r\n\r\n    void ParseArgumentsStateMachine::ThrowIfError() const\r\n    {\r\n        if (m_state.Exception())\r\n        {\r\n            throw m_state.Exception().value();\r\n        }\r\n        // If the next argument was to be a value, but none was provided, convert it to an exception.\r\n        else if (m_state.Type() && m_invocationItr == m_invocation.end())\r\n        {\r\n            throw CommandException(Resource::String::MissingArgumentError(m_state.Arg()));\r\n        }\r\n    }\r\n\r\n    const CLI::Argument* ParseArgumentsStateMachine::NextPositional()\r\n    {\r\n        // Find the next appropriate positional arg if the current itr isn't one or has hit its limit.\r\n        while (m_positionalSearchItr != m_arguments.end() &&\r\n            (m_positionalSearchItr->Type() != ArgumentType::Positional || m_executionArgs.GetCount(m_positionalSearchItr->ExecArgType()) == m_positionalSearchItr->Limit()))\r\n        {\r\n            ++m_positionalSearchItr;\r\n        }\r\n\r\n        if (m_positionalSearchItr == m_arguments.end())\r\n        {\r\n            return nullptr;\r\n        }\r\n\r\n        return &*m_positionalSearchItr;\r\n    }\r\n\r\n    // Parse arguments as such:\r\n    //  1. If argument starts with a single -, only the single character alias is considered.\r\n    //      a. If the named argument alias (a) needs a VALUE, it can be provided in these ways:\r\n    //          -a=VALUE\r\n    //          -a VALUE\r\n    //      b. If the argument is a flag, additional characters after are treated as if they start\r\n    //          with a -, repeatedly until the end of the argument is reached.  Fails if non-flags hit.\r\n    //  2. If the argument starts with a double --, only the full name is considered.\r\n    //      a. If the named argument (arg) needs a VALUE, it can be provided in these ways:\r\n    //          --arg=VALUE\r\n    //          --arg VALUE\r\n    //  3. If the argument does not start with any -, it is considered the next positional argument.\r\n    //  4. If the argument is only a double --, all further arguments are only considered as positional.\r\n    ParseArgumentsStateMachine::State ParseArgumentsStateMachine::StepInternal()\r\n    {\r\n        auto currArg = Utility::LocIndView{ *m_invocationItr };\r\n        ++m_invocationItr;\r\n\r\n        // If the previous step indicated a value was needed, set it and forget it.\r\n        if (m_state.Type())\r\n        {\r\n            m_executionArgs.AddArg(m_state.Type().value(), currArg);\r\n            return {};\r\n        }\r\n\r\n        // This is a positional argument\r\n        if (m_onlyPositionalArgumentsRemain || currArg.empty() || currArg[0] != APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_CHAR)\r\n        {\r\n            const CLI::Argument* nextPositional = NextPositional();\r\n            if (!nextPositional)\r\n            {\r\n                return CommandException(Resource::String::ExtraPositionalError(currArg));\r\n            }\r\n\r\n            m_executionArgs.AddArg(nextPositional->ExecArgType(), currArg);\r\n        }\r\n        // The currentArg must not be empty, and starts with a -\r\n        else if (currArg.length() == 1)\r\n        {\r\n            return CommandException(Resource::String::InvalidArgumentSpecifierError(currArg));\r\n        }\r\n        // Now it must be at least 2 chars\r\n        else if (currArg[1] != APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_CHAR)\r\n        {\r\n            // Parse the single character alias argument\r\n            char currChar = currArg[1];\r\n\r\n            auto itr = std::find_if(m_arguments.begin(), m_arguments.end(), [&](const Argument& arg) { return (currChar == arg.Alias()); });\r\n            if (itr == m_arguments.end())\r\n            {\r\n                return CommandException(Resource::String::InvalidAliasError(currArg));\r\n            }\r\n\r\n            if (itr->Type() == ArgumentType::Flag)\r\n            {\r\n                m_executionArgs.AddArg(itr->ExecArgType());\r\n\r\n                for (size_t i = 2; i < currArg.length(); ++i)\r\n                {\r\n                    currChar = currArg[i];\r\n\r\n                    auto itr2 = std::find_if(m_arguments.begin(), m_arguments.end(), [&](const Argument& arg) { return (currChar == arg.Alias()); });\r\n                    if (itr2 == m_arguments.end())\r\n                    {\r\n                        return CommandException(Resource::String::AdjoinedNotFoundError(currArg));\r\n                    }\r\n                    else if (itr2->Type() != ArgumentType::Flag)\r\n                    {\r\n                        return CommandException(Resource::String::AdjoinedNotFlagError(currArg));\r\n                    }\r\n                    else\r\n                    {\r\n                        m_executionArgs.AddArg(itr2->ExecArgType());\r\n                    }\r\n                }\r\n            }\r\n            else if (currArg.length() > 2)\r\n            {\r\n                if (currArg[2] == APPINSTALLER_CLI_ARGUMENT_SPLIT_CHAR)\r\n                {\r\n                    ProcessAdjoinedValue(itr->ExecArgType(), currArg.substr(3));\r\n                }\r\n                else\r\n                {\r\n                    return CommandException(Resource::String::SingleCharAfterDashError(currArg));\r\n                }\r\n            }\r\n            else\r\n            {\r\n                return { itr->ExecArgType(), currArg };\r\n            }\r\n        }\r\n        // The currentArg is at least 2 chars, both of which are --\r\n        else if (currArg.length() == 2)\r\n        {\r\n            m_onlyPositionalArgumentsRemain = true;\r\n        }\r\n        // The currentArg is more than 2 chars, both of which are --\r\n        else\r\n        {\r\n            // This is an arg name, find it and process its value if needed.\r\n            // Skip the double arg identifier chars.\r\n            size_t argStart = currArg.find_first_not_of(APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_CHAR);\r\n            std::string_view argName = currArg.substr(argStart);\r\n            bool argFound = false;\r\n\r\n            bool hasValue = false;\r\n            std::string_view argValue;\r\n            size_t splitChar = argName.find_first_of(APPINSTALLER_CLI_ARGUMENT_SPLIT_CHAR);\r\n            if (splitChar != std::string::npos)\r\n            {\r\n                hasValue = true;\r\n                argValue = argName.substr(splitChar + 1);\r\n                argName = argName.substr(0, splitChar);\r\n            }\r\n\r\n            for (const auto& arg : m_arguments)\r\n            {\r\n                if (\r\n                    Utility::CaseInsensitiveEquals(argName, arg.Name()) ||\r\n                    Utility::CaseInsensitiveEquals(argName, arg.AlternateName())\r\n                   )\r\n                {\r\n                    if (arg.Type() == ArgumentType::Flag)\r\n                    {\r\n                        if (hasValue)\r\n                        {\r\n                            return CommandException(Resource::String::FlagContainAdjoinedError(currArg));\r\n                        }\r\n\r\n                        m_executionArgs.AddArg(arg.ExecArgType());\r\n                    }\r\n                    else if (hasValue)\r\n                    {\r\n                        ProcessAdjoinedValue(arg.ExecArgType(), argValue);\r\n                    }\r\n                    else\r\n                    {\r\n                        return { arg.ExecArgType(), currArg };\r\n                    }\r\n                    argFound = true;\r\n                    break;\r\n                }\r\n            }\r\n\r\n            if (!argFound)\r\n            {\r\n                return CommandException(Resource::String::InvalidNameError(currArg));\r\n            }\r\n        }\r\n\r\n        // If we get here, the next argument can be anything again.\r\n        return {};\r\n    }\r\n\r\n    void ParseArgumentsStateMachine::ProcessAdjoinedValue(Execution::Args::Type type, std::string_view value)\r\n    {\r\n        // If the adjoined value is wrapped in quotes, strip them off.\r\n        if (value.length() >= 2 && value[0] == '\"' && value[value.length() - 1] == '\"')\r\n        {\r\n            value = value.substr(1, value.length() - 2);\r\n        }\r\n\r\n        m_executionArgs.AddArg(type, std::string{ value });\r\n    }\r\n\r\n    void Command::ParseArguments(Invocation& inv, Execution::Args& execArgs) const\r\n    {\r\n        auto definedArgs = GetArguments();\r\n        Argument::GetCommon(definedArgs);\r\n\r\n        ParseArgumentsStateMachine stateMachine{ inv, execArgs, std::move(definedArgs) };\r\n\r\n        while (stateMachine.Step())\r\n        {\r\n            stateMachine.ThrowIfError();\r\n        }\r\n\r\n        // Special handling for multi-query arguments:\r\n        execArgs.MakeMultiQueryContainUniqueValues();\r\n        execArgs.MoveMultiQueryToSingleQueryIfNeeded();\r\n    }\r\n\r\n    void Command::ValidateArguments(Execution::Args& execArgs) const\r\n    {\r\n        // If help is asked for, don't bother validating anything else\r\n        if (execArgs.Contains(Execution::Args::Type::Help))\r\n        {\r\n            return;\r\n        }\r\n\r\n        // Common arguments need to be validated with command arguments, as there may be common arguments blocked by Experimental Feature or Group Policy\r\n        auto allArgs = GetArguments();\r\n        Argument::GetCommon(allArgs);\r\n\r\n        for (const auto& arg : allArgs)\r\n        {\r\n            if (!Settings::GroupPolicies().IsEnabled(arg.GroupPolicy()) && execArgs.Contains(arg.ExecArgType()))\r\n            {\r\n                auto policy = TogglePolicy::GetPolicy(arg.GroupPolicy());\r\n                AICLI_LOG(CLI, Error, << \"Trying to use argument: \" << arg.Name() << \" disabled by group policy \" << policy.RegValueName());\r\n                throw GroupPolicyException(arg.GroupPolicy());\r\n            }\r\n\r\n            if (arg.AdminSetting() != BoolAdminSetting::Unknown && !Settings::IsAdminSettingEnabled(arg.AdminSetting()) && execArgs.Contains(arg.ExecArgType()))\r\n            {\r\n                auto setting = Settings::AdminSettingToString(arg.AdminSetting());\r\n                AICLI_LOG(CLI, Error, << \"Trying to use argument: \" << arg.Name() << \" disabled by admin setting \" << setting);\r\n                throw CommandException(Resource::String::FeatureDisabledByAdminSettingMessage(setting));\r\n            }\r\n\r\n            if (!ExperimentalFeature::IsEnabled(arg.Feature()) && execArgs.Contains(arg.ExecArgType()))\r\n            {\r\n                auto feature = ExperimentalFeature::GetFeature(arg.Feature());\r\n                AICLI_LOG(CLI, Error, << \"Trying to use argument: \" << arg.Name() << \" without enabling feature \" << feature.JsonName());\r\n                throw CommandException(Resource::String::FeatureDisabledMessage(feature.JsonName()));\r\n            }\r\n\r\n            if (arg.Required() && !execArgs.Contains(arg.ExecArgType()))\r\n            {\r\n                throw CommandException(Resource::String::RequiredArgError(arg.Name()));\r\n            }\r\n\r\n            if (arg.Limit() < execArgs.GetCount(arg.ExecArgType()))\r\n            {\r\n                throw CommandException(Resource::String::TooManyArgError(arg.Name()));\r\n            }\r\n        }\r\n\r\n        if (execArgs.Contains(Execution::Args::Type::Silent) && execArgs.Contains(Execution::Args::Type::Interactive))\r\n        {\r\n            throw CommandException(Resource::String::TooManyBehaviorsError(s_Command_ArgName_SilentAndInteractive));\r\n        }\r\n\r\n        if (execArgs.Contains(Execution::Args::Type::CustomHeader) && !execArgs.Contains(Execution::Args::Type::Source) &&\r\n           !execArgs.Contains(Execution::Args::Type::SourceName))\r\n        {\r\n            throw CommandException(Resource::String::HeaderArgumentNotApplicableWithoutSource(Argument::ForType(Execution::Args::Type::CustomHeader).Name()));\r\n        }\r\n\r\n        if (execArgs.Contains(Execution::Args::Type::Count))\r\n        {\r\n            try\r\n            {\r\n                int countRequested = std::stoi(std::string(execArgs.GetArg(Execution::Args::Type::Count)));\r\n                if (countRequested < 1 || countRequested > 1000)\r\n                {\r\n                    throw CommandException(Resource::String::CountOutOfBoundsError);\r\n                }\r\n            }\r\n            catch (...)\r\n            {\r\n                throw CommandException(Resource::String::CountOutOfBoundsError);\r\n            }\r\n        }\r\n\r\n        if (execArgs.Contains(Execution::Args::Type::InstallArchitecture))\r\n        {\r\n            Utility::Architecture selectedArch = Utility::ConvertToArchitectureEnum(std::string(execArgs.GetArg(Execution::Args::Type::InstallArchitecture)));\r\n            if ((selectedArch == Utility::Architecture::Unknown) || (Utility::IsApplicableArchitecture(selectedArch) == Utility::InapplicableArchitecture))\r\n            {\r\n                std::vector<Utility::LocIndString> applicableArchitectures;\r\n                for (Utility::Architecture i : Utility::GetApplicableArchitectures())\r\n                {\r\n                    applicableArchitectures.emplace_back(Utility::ToString(i));\r\n                }\r\n\r\n                auto validOptions = Utility::Join(\", \"_liv, applicableArchitectures);\r\n                throw CommandException(Resource::String::InvalidArgumentValueError(Argument::ForType(Execution::Args::Type::InstallArchitecture).Name(), validOptions));\r\n            }\r\n        }\r\n\r\n        if (execArgs.Contains(Execution::Args::Type::InstallerArchitecture))\r\n        {\r\n            Utility::Architecture selectedArch = Utility::ConvertToArchitectureEnum(std::string(execArgs.GetArg(Execution::Args::Type::InstallerArchitecture)));\r\n            if (selectedArch == Utility::Architecture::Unknown)\r\n            {\r\n                std::vector<Utility::LocIndString> applicableArchitectures;\r\n                for (Utility::Architecture i : Utility::GetAllArchitectures())\r\n                {\r\n                    applicableArchitectures.emplace_back(Utility::ToString(i));\r\n                }\r\n\r\n                auto validOptions = Utility::Join(\", \"_liv, applicableArchitectures);\r\n                throw CommandException(Resource::String::InvalidArgumentValueError(Argument::ForType(Execution::Args::Type::InstallerArchitecture).Name(), validOptions));\r\n            }\r\n        }\r\n\r\n        if (execArgs.Contains(Execution::Args::Type::Locale))\r\n        {\r\n            if (!Locale::IsWellFormedBcp47Tag(execArgs.GetArg(Execution::Args::Type::Locale)))\r\n            {\r\n                throw CommandException(Resource::String::InvalidArgumentValueErrorWithoutValidValues(Argument::ForType(Execution::Args::Type::Locale).Name()));\r\n            }\r\n        }\r\n\r\n        if (execArgs.Contains(Execution::Args::Type::InstallScope))\r\n        {\r\n            if (Manifest::ConvertToScopeEnum(execArgs.GetArg(Execution::Args::Type::InstallScope)) == Manifest::ScopeEnum::Unknown)\r\n            {\r\n                auto validOptions = Utility::Join(\", \"_liv, std::vector<Utility::LocIndString>{ \"user\"_lis, \"machine\"_lis });\r\n                throw CommandException(Resource::String::InvalidArgumentValueError(ArgumentCommon::ForType(Execution::Args::Type::InstallScope).Name, validOptions));\r\n            }\r\n        }\r\n\r\n        if (execArgs.Contains(Execution::Args::Type::InstallerType))\r\n        {\r\n            Manifest::InstallerTypeEnum selectedInstallerType = Manifest::ConvertToInstallerTypeEnum(std::string(execArgs.GetArg(Execution::Args::Type::InstallerType)));\r\n            if (selectedInstallerType == Manifest::InstallerTypeEnum::Unknown)\r\n            {\r\n                throw CommandException(Resource::String::InvalidArgumentValueErrorWithoutValidValues(Argument::ForType(Execution::Args::Type::InstallerType).Name()));\r\n            }\r\n        }\r\n\r\n        if (execArgs.Contains(Execution::Args::Type::AuthenticationMode))\r\n        {\r\n            if (Authentication::ConvertToAuthenticationMode(execArgs.GetArg(Execution::Args::Type::AuthenticationMode)) == Authentication::AuthenticationMode::Unknown)\r\n            {\r\n                auto validOptions = Utility::Join(\", \"_liv, std::vector<Utility::LocIndString>{ \"interactive\"_lis, \"silentPreferred\"_lis, \"silent\"_lis });\r\n                throw CommandException(Resource::String::InvalidArgumentValueError(ArgumentCommon::ForType(Execution::Args::Type::AuthenticationMode).Name, validOptions));\r\n            }\r\n        }\r\n\r\n        Argument::ValidateExclusiveArguments(execArgs);\r\n\r\n        ValidateArgumentsInternal(execArgs);\r\n    }\r\n\r\n    // Completion can produce one of several things if the completion context is appropriate:\r\n    //  1. Sub commands, if the context is immediately after this command.\r\n    //  2. Argument names, if a value is not expected.\r\n    //  3. Argument values, if one is expected.\r\n    void Command::Complete(Execution::Context& context) const\r\n    {\r\n        CompletionData& data = context.Get<Execution::Data::CompletionData>();\r\n        const std::string& word = data.Word();\r\n\r\n        // The word we are to complete is directly after the command, thus it's sub-commands are potentials.\r\n        if (data.BeforeWord().begin() == data.BeforeWord().end())\r\n        {\r\n            for (const auto& command : GetCommands())\r\n            {\r\n                if (word.empty() || Utility::CaseInsensitiveStartsWith(command->Name(), word))\r\n                {\r\n                    context.Reporter.Completion() << command->Name() << std::endl;\r\n                }\r\n                // Allow for command aliases to be auto-completed\r\n                if (!(command->Aliases()).empty() && !word.empty())\r\n                {\r\n                    for (const auto& commandAlias : command->Aliases())\r\n                    {\r\n                        if (Utility::CaseInsensitiveStartsWith(commandAlias, word))\r\n                        {\r\n                            context.Reporter.Completion() << commandAlias << std::endl;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // Consume what remains, if any, of the preceding values to determine what type the word is.\r\n        auto definedArgs = GetArguments();\r\n        Argument::GetCommon(definedArgs);\r\n\r\n        ParseArgumentsStateMachine stateMachine{ data.BeforeWord(), context.Args, std::move(definedArgs) };\r\n\r\n        // We don't care if there are errors along the way, just do the best that can be done and try to\r\n        // complete whatever would be next if the bad strings were simply ignored. To do that we just spin\r\n        // through the state until we reach our word.\r\n        while (stateMachine.Step());\r\n\r\n        const auto& state = stateMachine.GetState();\r\n\r\n        // This means that anything is possible, so argument names are on the table.\r\n        if (!state.Type() && !stateMachine.OnlyPositionalRemain())\r\n        {\r\n            // Use argument names if:\r\n            //  1. word is empty\r\n            //  2. word is just \"-\"\r\n            //  3. word starts with \"--\"\r\n            if (word.empty() ||\r\n                word == APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_STRING ||\r\n                Utility::CaseInsensitiveStartsWith(word, APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_STRING APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_STRING))\r\n            {\r\n                for (const auto& arg : stateMachine.Arguments())\r\n                {\r\n                    if (word.length() <= 2 || Utility::CaseInsensitiveStartsWith(arg.Name(), word.substr(2)))\r\n                    {\r\n                        context.Reporter.Completion() << APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_CHAR << APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_CHAR << arg.Name() << std::endl;\r\n                    }\r\n                }\r\n            }\r\n            // Use argument aliases if the word is already one; allow cycling through them.\r\n            else if (Utility::CaseInsensitiveStartsWith(word, APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_STRING) && word.length() == 2)\r\n            {\r\n                for (const auto& arg : stateMachine.Arguments())\r\n                {\r\n                    if (arg.Alias() != ArgumentCommon::NoAlias)\r\n                    {\r\n                        context.Reporter.Completion() << APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_CHAR << arg.Alias() << std::endl;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        std::optional<Execution::Args::Type> typeToComplete = state.Type();\r\n\r\n        // We are not waiting on an argument value, so the next could be a positional if the incoming word is not an argument name.\r\n        // If there is one, offer to complete it.\r\n        if (!typeToComplete && (word.empty() || word[0] != APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_CHAR))\r\n        {\r\n            const auto* nextPositional = stateMachine.NextPositional();\r\n            if (nextPositional)\r\n            {\r\n                typeToComplete = nextPositional->ExecArgType();\r\n            }\r\n        }\r\n\r\n        // To enable more complete scenarios, also attempt to parse any arguments after the word to complete.\r\n        // This will allow these later values to affect the result of the completion (for instance, if a specific source is listed).\r\n        {\r\n            ParseArgumentsStateMachine afterWordStateMachine{ data.AfterWord(), context.Args, stateMachine.Arguments() };\r\n            while (afterWordStateMachine.Step());\r\n        }\r\n\r\n        // Let the derived command take over supplying context sensitive argument value.\r\n        if (typeToComplete)\r\n        {\r\n            Complete(context, typeToComplete.value());\r\n        }\r\n    }\r\n\r\n    void Command::Complete(Execution::Context&, Execution::Args::Type) const\r\n    {\r\n        // Derived commands must supply context sensitive argument values.\r\n    }\r\n\r\n    void Command::Execute(Execution::Context& context) const\r\n    {\r\n        // Block any execution if winget is disabled by policy.\r\n        // Override the function to bypass this.\r\n        if (!Settings::GroupPolicies().IsEnabled(Settings::TogglePolicy::Policy::WinGet))\r\n        {\r\n            AICLI_LOG(CLI, Error, << \"WinGet is disabled by group policy\");\r\n            throw Settings::GroupPolicyException::GroupPolicyException(Settings::TogglePolicy::Policy::WinGet);\r\n        }\r\n\r\n        AICLI_LOG(CLI, Info, << \"Executing command: \" << Name());\r\n        if (context.Args.Contains(Execution::Args::Type::Help))\r\n        {\r\n            OutputHelp(context.Reporter);\r\n        }\r\n        else\r\n        {\r\n            ExecuteInternal(context);\r\n        }\r\n\r\n        // NOTE: Reboot logic will still run even if the context is terminated (not including unhandled exceptions).\r\n        if (context.Args.Contains(Execution::Args::Type::AllowReboot) &&\r\n            WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::RebootRequired))\r\n        {\r\n            context.Reporter.Warn() << Resource::String::InitiatingReboot << std::endl;\r\n\r\n            if (context.Args.Contains(Execution::Args::Type::Wait))\r\n            {\r\n                context.Reporter.PromptForEnter();\r\n            }\r\n\r\n            if (WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::RegisterResume))\r\n            {\r\n                // RegisterResume context flag assumes we already wrote to the RunOnce registry.\r\n                // Since we are about to initiate a restart, this is no longer needed as a safety net.\r\n                Reboot::UnregisterRestartForWER();\r\n\r\n                context.ClearFlags(Execution::ContextFlag::RegisterResume);\r\n            }\r\n\r\n            context.ClearFlags(Execution::ContextFlag::RebootRequired);\r\n\r\n            if (!Reboot::InitiateReboot())\r\n            {\r\n                context.Reporter.Error() << Resource::String::FailedToInitiateReboot << std::endl;\r\n            }\r\n        }\r\n        else\r\n        {\r\n            LaunchLogsIfRequested(context);\r\n\r\n            if (context.Args.Contains(Execution::Args::Type::Wait))\r\n            {\r\n                context.Reporter.PromptForEnter();\r\n            }\r\n        }\r\n    }\r\n\r\n    void Command::Resume(Execution::Context& context) const\r\n    {\r\n        context.Reporter.Error() << Resource::String::CommandDoesNotSupportResumeMessage << std::endl;\r\n        AICLI_TERMINATE_CONTEXT(E_NOTIMPL);\r\n    }\r\n    \r\n    void Command::SelectCurrentCommandIfUnrecognizedSubcommandFound(bool value)\r\n    {\r\n        m_selectCurrentCommandIfUnrecognizedSubcommandFound = value;\r\n    }\r\n\r\n    void Command::ValidateArgumentsInternal(Execution::Args&) const\r\n    {\r\n        // Do nothing by default.\r\n        // Commands may not need any extra validation.\r\n    }\r\n\r\n    void Command::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        context.Reporter.Error() << Resource::String::PendingWorkError << std::endl;\r\n        THROW_HR(E_NOTIMPL);\r\n    }\r\n\r\n    Command::Visibility Command::GetVisibility() const\r\n    {\r\n        if (!ExperimentalFeature::IsEnabled(m_feature))\r\n        {\r\n            return Command::Visibility::Hidden;\r\n        }\r\n\r\n        if (!Settings::GroupPolicies().IsEnabled(m_groupPolicy))\r\n        {\r\n            return Command::Visibility::Hidden;\r\n        }\r\n\r\n        return m_visibility;\r\n    }\r\n\r\n    std::vector<std::unique_ptr<Command>> Command::GetVisibleCommands() const\r\n    {\r\n        auto commands = GetCommands();\r\n\r\n        commands.erase(\r\n            std::remove_if(\r\n                commands.begin(), commands.end(),\r\n                [](const std::unique_ptr<Command>& command) { return command->GetVisibility() == Command::Visibility::Hidden; }),\r\n            commands.end());\r\n\r\n        return commands;\r\n    }\r\n\r\n    std::vector<Argument> Command::GetVisibleArguments() const\r\n    {\r\n        auto arguments = GetArguments();\r\n        Argument::GetCommon(arguments);\r\n\r\n        arguments.erase(\r\n            std::remove_if(\r\n                arguments.begin(), arguments.end(),\r\n                [](const Argument& arg) { return arg.GetVisibility() == Argument::Visibility::Hidden; }),\r\n            arguments.end());\r\n\r\n        return arguments;\r\n    }\r\n\r\n    void ExecuteWithoutLoggingSuccess(Execution::Context& context, Command* command)\r\n    {\r\n        try\r\n        {\r\n            if (!Settings::User().GetWarnings().empty() &&\r\n                !WI_IsFlagSet(command->GetOutputFlags(), CommandOutputFlags::IgnoreSettingsWarnings))\r\n            {\r\n                context.Reporter.Warn() << Resource::String::SettingsWarnings << std::endl;\r\n            }\r\n\r\n            command->Execute(context);\r\n        }\r\n        catch (...)\r\n        {\r\n            context.SetTerminationHR(Workflow::HandleException(context, std::current_exception()));\r\n\r\n            LaunchLogsIfRequested(context);\r\n        }\r\n    }\r\n\r\n    int Execute(Execution::Context& context, std::unique_ptr<Command>& command)\r\n    {\r\n        ExecuteWithoutLoggingSuccess(context, command.get());\r\n\r\n        if (SUCCEEDED(context.GetTerminationHR()))\r\n        {\r\n            Logging::Telemetry().LogCommandSuccess(command->FullName());\r\n        }\r\n\r\n        return context.GetTerminationHR();\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Command.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Argument.h\"\r\n#include \"ExecutionContext.h\"\r\n#include \"Invocation.h\"\r\n#include \"Resources.h\"\r\n#include <winget/UserSettings.h>\r\n#include <winget/ExperimentalFeature.h>\r\n#include <winget/GroupPolicy.h>\r\n\r\n#include <initializer_list>\r\n#include <memory>\r\n#include <optional>\r\n#include <ostream>\r\n#include <string>\r\n#include <string_view>\r\n#include <type_traits>\r\n#include <vector>\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    struct CommandException\r\n    {\r\n        CommandException(Resource::LocString message) : m_message(std::move(message)) {}\r\n        const Utility::LocIndString Message() const { return m_message; }\r\n\r\n    private:\r\n        Resource::LocString m_message;\r\n    };\r\n\r\n    // Flags to control the behavior of the command output.\r\n    enum class CommandOutputFlags : int\r\n    {\r\n        None = 0x0,\r\n        IgnoreSettingsWarnings = 0x1,\r\n    };\r\n\r\n    DEFINE_ENUM_FLAG_OPERATORS(CommandOutputFlags);\r\n\r\n    struct Command\r\n    {\r\n        // Controls the visibility of the field.\r\n        enum class Visibility\r\n        {\r\n            // Shown in help.\r\n            Show,\r\n            // Not shown in help.\r\n            Hidden,\r\n        };\r\n\r\n        Command(std::string_view name, std::string_view parent) :\r\n            Command(name, {}, parent) {}\r\n        Command(std::string_view name, std::vector<std::string_view> aliases, std::string_view parent) :\r\n            Command(name, aliases, parent, Settings::ExperimentalFeature::Feature::None) {}\r\n        Command(std::string_view name, std::string_view parent, CommandOutputFlags outputFlags) :\r\n            Command(name, {}, parent, Command::Visibility::Show, Settings::ExperimentalFeature::Feature::None, Settings::TogglePolicy::Policy::None, outputFlags) {}\r\n        Command(std::string_view name, std::vector<std::string_view> aliases, std::string_view parent, Command::Visibility visibility) :\r\n            Command(name, aliases, parent, visibility, Settings::ExperimentalFeature::Feature::None) {}\r\n        Command(std::string_view name, std::string_view parent, Settings::ExperimentalFeature::Feature feature) :\r\n            Command(name, {}, parent, Command::Visibility::Show, feature) {}\r\n        Command(std::string_view name, std::string_view parent, Settings::ExperimentalFeature::Feature feature, CommandOutputFlags outputFlags) :\r\n            Command(name, {}, parent, Command::Visibility::Show, feature, Settings::TogglePolicy::Policy::None, outputFlags) {}\r\n        Command(std::string_view name, std::vector<std::string_view> aliases, std::string_view parent, Settings::ExperimentalFeature::Feature feature) :\r\n            Command(name, aliases, parent, Command::Visibility::Show, feature) {}\r\n        Command(std::string_view name, std::vector<std::string_view> aliases, std::string_view parent, Settings::TogglePolicy::Policy groupPolicy) :\r\n            Command(name, aliases, parent, Command::Visibility::Show, Settings::ExperimentalFeature::Feature::None, groupPolicy, CommandOutputFlags::None) {}\r\n        Command(std::string_view name, std::vector<std::string_view> aliases, std::string_view parent, Command::Visibility visibility, Settings::ExperimentalFeature::Feature feature) :\r\n            Command(name, aliases, parent, visibility, feature, Settings::TogglePolicy::Policy::None, CommandOutputFlags::None) {}\r\n        Command(std::string_view name, std::vector<std::string_view> aliases, std::string_view parent, Command::Visibility visibility, Settings::TogglePolicy::Policy groupPolicy) :\r\n            Command(name, aliases, parent, visibility, Settings::ExperimentalFeature::Feature::None, groupPolicy, CommandOutputFlags::None) {}\r\n\r\n        Command(std::string_view name,\r\n            std::vector<std::string_view> aliases,\r\n            std::string_view parent,\r\n            Command::Visibility visibility,\r\n            Settings::ExperimentalFeature::Feature feature,\r\n            Settings::TogglePolicy::Policy groupPolicy,\r\n            CommandOutputFlags outputFlags);\r\n\r\n        virtual ~Command() = default;\r\n\r\n        Command(const Command&) = default;\r\n        Command& operator=(const Command&) = default;\r\n\r\n        Command(Command&&) = default;\r\n        Command& operator=(Command&&) = default;\r\n\r\n        // The character used to split between commands and their parents in FullName.\r\n        constexpr static char ParentSplitChar = ':';\r\n\r\n        std::string_view Name() const { return m_name; }\r\n        const std::vector<std::string_view>& Aliases() const& { return m_aliases; }\r\n        const std::string& FullName() const { return m_fullName; }\r\n        Command::Visibility GetVisibility() const;\r\n        Settings::ExperimentalFeature::Feature Feature() const { return m_feature; }\r\n        Settings::TogglePolicy::Policy GroupPolicy() const { return m_groupPolicy; }\r\n        CommandOutputFlags GetOutputFlags() const { return m_outputFlags; }\r\n\r\n        virtual std::vector<std::unique_ptr<Command>> GetCommands() const { return {}; }\r\n        virtual std::vector<Argument> GetArguments() const { return {}; }\r\n        std::vector<std::unique_ptr<Command>> GetVisibleCommands() const;\r\n        std::vector<Argument> GetVisibleArguments() const;\r\n\r\n        virtual Resource::LocString ShortDescription() const = 0;\r\n        virtual Resource::LocString LongDescription() const = 0;\r\n\r\n        virtual void OutputIntroHeader(Execution::Reporter& reporter) const;\r\n        virtual void OutputHelp(Execution::Reporter& reporter, const CommandException* exception = nullptr) const;\r\n        virtual Utility::LocIndView HelpLink() const { return {}; }\r\n\r\n        virtual std::unique_ptr<Command> FindSubCommand(Invocation& inv) const;\r\n        virtual void ParseArguments(Invocation& inv, Execution::Args& execArgs) const;\r\n        virtual void ValidateArguments(Execution::Args& execArgs) const;\r\n\r\n        virtual void Complete(Execution::Context& context) const;\r\n        virtual void Complete(Execution::Context& context, Execution::Args::Type valueType) const;\r\n\r\n        virtual void Execute(Execution::Context& context) const;\r\n\r\n        virtual void Resume(Execution::Context& context) const;\r\n\r\n    protected:\r\n        void SelectCurrentCommandIfUnrecognizedSubcommandFound(bool value);\r\n\r\n        virtual void ValidateArgumentsInternal(Execution::Args& execArgs) const;\r\n        virtual void ExecuteInternal(Execution::Context& context) const;\r\n\r\n    private:\r\n        std::string_view m_name;\r\n        std::string m_fullName;\r\n        std::vector<std::string_view> m_aliases;\r\n        Command::Visibility m_visibility;\r\n        Settings::ExperimentalFeature::Feature m_feature;\r\n        Settings::TogglePolicy::Policy m_groupPolicy;\r\n        CommandOutputFlags m_outputFlags;\r\n        bool m_selectCurrentCommandIfUnrecognizedSubcommandFound = false;\r\n        std::string m_commandArguments;\r\n    };\r\n\r\n    template <typename Container>\r\n    Container InitializeFromMoveOnly(std::initializer_list<typename Container::value_type> il)\r\n    {\r\n        using Value = typename Container::value_type;\r\n        Container result;\r\n\r\n        for (const auto& v : il)\r\n        {\r\n            result.emplace_back(std::move(*const_cast<Value*>(&v)));\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    void ExecuteWithoutLoggingSuccess(Execution::Context& context, Command* command);\r\n\r\n    int Execute(Execution::Context& context, std::unique_ptr<Command>& command);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/COMCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"COMCommand.h\"\n#include \"Workflows/DownloadFlow.h\"\n#include \"Workflows/InstallFlow.h\"\n#include \"Workflows/PromptFlow.h\"\n#include \"Workflows/UninstallFlow.h\"\n#include \"Workflows/WorkflowBase.h\"\n#include \"Workflows/DependenciesFlow.h\"\r\n#include \"Workflows/RepairFlow.h\"\n\nnamespace AppInstaller::CLI\n{\n    using namespace AppInstaller::CLI::Execution;\n    using namespace AppInstaller::CLI::Workflow;\n    using namespace AppInstaller::Manifest;\n    using namespace AppInstaller::Utility::literals;\n\n    // IMPORTANT: To use this command, the caller should have already retrieved the package manifest (GetManifest()) and added it to the Context Data\n    void COMDownloadCommand::ExecuteInternal(Context& context) const\n    {\n        context <<\r\n            Workflow::InitializeInstallerDownloadAuthenticatorsMap <<\n            Workflow::ReportExecutionStage(ExecutionStage::Discovery) <<\n            Workflow::SelectInstaller <<\n            Workflow::EnsureApplicableInstaller <<\n            Workflow::ReportIdentityAndInstallationDisclaimer <<\n            Workflow::ShowPromptsForSinglePackage(/* ensureAcceptance */ true) <<\n            Workflow::SetDownloadDirectory <<\n            Workflow::DownloadPackageDependencies <<\n            Workflow::DownloadInstaller;\n    }\n\n    // IMPORTANT: To use this command, the caller should have already executed the COMDownloadCommand\n    void COMInstallCommand::ExecuteInternal(Context& context) const\n    {\n        context <<\n            Workflow::InstallDependencies <<\n            Workflow::ReverifyInstallerHash << \n            Workflow::InstallPackageInstaller;\n    }\n\n    // IMPORTANT: To use this command, the caller should have already retrieved the InstalledPackageVersion and added it to the Context Data\n    void COMUninstallCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        context <<\r\n            Workflow::UninstallSinglePackage;\r\n    }\r\n\r\n    // IMPORTANT: To use this command, the caller should have already retrieved the InstalledPackageVersion and added it to the Context Data\r\n    void COMRepairCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        context <<\r\n            Workflow::InitializeInstallerDownloadAuthenticatorsMap <<\r\n            Workflow::SelectApplicableInstallerIfNecessary <<\r\n            Workflow::RepairSinglePackage;\r\n    }\r\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/COMCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"Command.h\"\n\nnamespace AppInstaller::CLI\n{\n    // IMPORTANT: To use this command, the caller should have already retrieved the package manifest (GetManifest()) and added it to the Context Data\n    struct COMDownloadCommand final : public Command\n    {\n        constexpr static std::string_view CommandName = \"download\"sv;\n        COMDownloadCommand(std::string_view parent) : Command(CommandName, parent) {}\r\n\r\n        CLI::Resource::LocString ShortDescription() const override { return {}; }\r\n        CLI::Resource::LocString LongDescription() const override { return {}; }\n\n    protected:\n        void ExecuteInternal(Execution::Context& context) const override;\n    };\n\n    // IMPORTANT: To use this command, the caller should have already retrieved the package manifest (GetManifest()) and added it to the Context Data\n    struct COMInstallCommand final : public Command\n    {\n        constexpr static std::string_view CommandName = \"install\"sv;\n        COMInstallCommand(std::string_view parent) : Command(CommandName, parent) {}\r\n\r\n        CLI::Resource::LocString ShortDescription() const override { return {}; }\r\n        CLI::Resource::LocString LongDescription() const override { return {}; }\n\n    protected:\n        void ExecuteInternal(Execution::Context& context) const override;\n    };\n\n    // IMPORTANT: To use this command, the caller should have already retrieved the InstalledPackageVersion and added it to the Context Data\n    struct COMUninstallCommand final : public Command\n    {\n        constexpr static std::string_view CommandName = \"uninstall\"sv;\n        COMUninstallCommand(std::string_view parent) : Command(CommandName, parent) {}\r\n\r\n        CLI::Resource::LocString ShortDescription() const override { return {}; }\r\n        CLI::Resource::LocString LongDescription() const override { return {}; }\n\n    protected:\n        void ExecuteInternal(Execution::Context& context) const override;\n    };\r\n\r\n    // IMPORTANT: To use this command, the caller should have already retrieved the InstalledPackageVersion and added it to the Context Data\r\n    struct COMRepairCommand final : public Command\r\n    {\r\n        constexpr static std::string_view CommandName = \"repair\"sv;\r\n        COMRepairCommand(std::string_view parent) : Command(CommandName, parent) {}\r\n\r\n        CLI::Resource::LocString ShortDescription() const override { return {}; }\r\n        CLI::Resource::LocString LongDescription() const override { return {}; }\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/CompleteCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"CompleteCommand.h\"\r\n#include \"RootCommand.h\"\r\n#include \"Resources.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    using namespace std::string_view_literals;\r\n    using namespace Execution;\r\n\r\n    std::vector<Argument> CompleteCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument{ Args::Type::Word, Resource::String::WordArgumentDescription, ArgumentType::Standard, Argument::Visibility::Example, true },\r\n            Argument{ Args::Type::CommandLine, Resource::String::CommandLineArgumentDescription, ArgumentType::Standard, Argument::Visibility::Example, true },\r\n            Argument{ Args::Type::Position, Resource::String::PositionArgumentDescription, ArgumentType::Standard, Argument::Visibility::Example, true },\r\n        };\r\n    }\r\n\r\n    Resource::LocString CompleteCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::CompleteCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString CompleteCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::CompleteCommandLongDescription };\r\n    }\r\n\r\n    Utility::LocIndView CompleteCommand::HelpLink() const\r\n    {\r\n        return \"https://aka.ms/winget-command-complete\"_liv;\r\n    }\r\n\r\n    void CompleteCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        try\r\n        {\r\n            CompletionData data{\r\n                context.Args.GetArg(Args::Type::Word),\r\n                context.Args.GetArg(Args::Type::CommandLine),\r\n                context.Args.GetArg(Args::Type::Position) };\r\n\r\n            std::unique_ptr<Command> command = std::make_unique<RootCommand>();\r\n\r\n            std::unique_ptr<Command> subCommand = command->FindSubCommand(data.BeforeWord());\r\n            while (subCommand)\r\n            {\r\n                command = std::move(subCommand);\r\n                subCommand = command->FindSubCommand(data.BeforeWord());\r\n            }\r\n\r\n            // Create a new Context to execute the Complete from\r\n            auto subContextPtr = context.CreateSubContext();\r\n            Context& subContext = *subContextPtr;\r\n            auto previousThreadGlobals = subContext.SetForCurrentThread();\r\n\r\n            subContext.Reporter.SetChannel(Execution::Reporter::Channel::Completion);\r\n            subContext.Add<Data::CompletionData>(std::move(data));\r\n\r\n            // Disable all telemetry while doing a completion\r\n            Logging::DisableTelemetryScope disable;\r\n\r\n            AICLI_LOG(CLI, Info, << \"Complete handing off to command \" << command->FullName());\r\n            command->Complete(subContext);\r\n        }\r\n        catch (const CommandException& ce)\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"Error encountered during completion, ignoring: \" << ce.Message());\r\n        }\r\n        catch (const Settings::GroupPolicyException& e)\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"Error encountered during completion, ignoring: Blocked by Group Policy \" << Settings::TogglePolicy::GetPolicy(e.Policy()).RegValueName());\r\n        }\r\n        catch (...)\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"Error encountered during completion, ignoring...\");\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/CompleteCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Command.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    // Command to enable tab completion scenarios, including allowing them to\r\n    // be context sensitive in their data output.\r\n    struct CompleteCommand final : public Command\r\n    {\r\n        CompleteCommand(std::string_view parent) : Command(\"complete\", {}, parent, Visibility::Hidden) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ConfigureCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigureCommand.h\"\r\n#include \"ConfigureListCommand.h\"\r\n#include \"ConfigureShowCommand.h\"\r\n#include \"ConfigureTestCommand.h\"\r\n#include \"ConfigureValidateCommand.h\"\r\n#include \"ConfigureExportCommand.h\"\r\n#include \"Workflows/ConfigurationFlow.h\"\r\n#include \"Workflows/MSStoreInstallerHandler.h\"\r\n#include \"ConfigurationCommon.h\"\r\n\r\nusing namespace AppInstaller::CLI::Workflow;\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    ConfigureCommand::ConfigureCommand(std::string_view parent) :\r\n        Command(\"configure\", { \"configuration\", \"dsc\"}, parent, Settings::TogglePolicy::Policy::Configuration)\r\n    {\r\n        SelectCurrentCommandIfUnrecognizedSubcommandFound(true);\r\n    }\r\n\r\n    std::vector<std::unique_ptr<Command>> ConfigureCommand::GetCommands() const\r\n    {\r\n        return InitializeFromMoveOnly<std::vector<std::unique_ptr<Command>>>({\r\n            std::make_unique<ConfigureShowCommand>(FullName()),\r\n            std::make_unique<ConfigureListCommand>(FullName()),\r\n            std::make_unique<ConfigureTestCommand>(FullName()),\r\n            std::make_unique<ConfigureValidateCommand>(FullName()),\r\n            std::make_unique<ConfigureExportCommand>(FullName()),\r\n        });\r\n    }\r\n\r\n    std::vector<Argument> ConfigureCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument{ Execution::Args::Type::ConfigurationFile, Resource::String::ConfigurationFileArgumentDescription, ArgumentType::Positional },\r\n            Argument{ Execution::Args::Type::ConfigurationModulePath, Resource::String::ConfigurationModulePath, ArgumentType::Positional },\r\n            Argument{ Execution::Args::Type::ConfigurationProcessorPath, Resource::String::ConfigurationProcessorPath, ArgumentType::Standard, Argument::Visibility::Help },\r\n            Argument{ Execution::Args::Type::ConfigurationHistoryItem, Resource::String::ConfigurationHistoryItemArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help },\r\n            Argument{ Execution::Args::Type::ConfigurationAcceptWarning, Resource::String::ConfigurationAcceptWarningArgumentDescription, ArgumentType::Flag },\r\n            Argument{ Execution::Args::Type::ConfigurationSuppressPrologue, Resource::String::ConfigurationSuppressPrologueArgumentDescription, ArgumentType::Flag, Argument::Visibility::Help },\r\n            Argument{ Execution::Args::Type::ExtendedFeaturesEnable, Resource::String::ExtendedFeaturesEnableMessage, ArgumentType::Flag, Argument::Visibility::Help },\r\n            Argument{ Execution::Args::Type::ExtendedFeaturesDisable, Resource::String::ExtendedFeaturesDisableMessage, ArgumentType::Flag, Argument::Visibility::Help },\r\n        };\r\n    }\r\n\r\n    Resource::LocString ConfigureCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::ConfigureCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString ConfigureCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::ConfigureCommandLongDescription };\r\n    }\r\n\r\n    Utility::LocIndView ConfigureCommand::HelpLink() const\r\n    {\r\n        return \"https://aka.ms/winget-command-configure\"_liv;\r\n    }\r\n\r\n    void ConfigureCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        if (context.Args.Contains(Execution::Args::Type::ExtendedFeaturesEnable))\r\n        {\r\n            context <<\r\n                EnableExtendedFeatures;\r\n        }\r\n        else if (context.Args.Contains(Execution::Args::Type::ExtendedFeaturesDisable))\r\n        {\r\n            context <<\r\n                DisableExtendedFeatures;\r\n        }\r\n        else\r\n        {\r\n            context <<\r\n                VerifyIsFullPackage <<\r\n                VerifyFileOrUri(Execution::Args::Type::ConfigurationFile) <<\r\n                CreateConfigurationProcessorWithoutFactory <<\r\n                OpenConfigurationSet <<\r\n                CreateConfigurationProcessor <<\r\n                ShowConfigurationSet <<\r\n                ShowConfigurationSetConflicts <<\r\n                ConfirmConfigurationProcessing(true) <<\r\n                ApplyConfigurationSet;\r\n        }\r\n    }\r\n\r\n    void ConfigureCommand::ValidateArgumentsInternal(Execution::Args& execArgs) const\r\n    {\r\n        if (execArgs.Contains(Execution::Args::Type::ExtendedFeaturesEnable) ||\r\n            execArgs.Contains(Execution::Args::Type::ExtendedFeaturesDisable))\r\n        {\r\n            if (execArgs.GetArgsCount() > 1)\r\n            {\r\n                throw CommandException(Resource::String::ExtendedFeaturesEnableArgumentError);\r\n            }\r\n        }\r\n        else\r\n        {\r\n            Configuration::ValidateCommonArguments(execArgs, true);\r\n        }\r\n    }\r\n\r\n    void ConfigureCommand::Complete(Execution::Context& context, Execution::Args::Type argType) const\r\n    {\r\n        if (argType == Execution::Args::Type::ConfigurationHistoryItem)\r\n        {\r\n            context << CompleteConfigurationHistoryItem;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ConfigureCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Command.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    struct ConfigureCommand final : public Command\r\n    {\r\n        ConfigureCommand(std::string_view parent);\r\n\r\n        std::vector<std::unique_ptr<Command>> GetCommands() const override;\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n        void ValidateArgumentsInternal(Execution::Args& execArgs) const override;\r\n        void Complete(Execution::Context& context, Execution::Args::Type argType) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ConfigureListCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigureListCommand.h\"\r\n#include \"Workflows/ConfigurationFlow.h\"\r\n#include \"Workflows/MSStoreInstallerHandler.h\"\r\n#include \"ConfigurationCommon.h\"\r\n\r\nusing namespace AppInstaller::CLI::Workflow;\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    std::vector<Argument> ConfigureListCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument{ Execution::Args::Type::ConfigurationHistoryItem, Resource::String::ConfigurationHistoryItemArgumentDescription, ArgumentType::Standard },\r\n            Argument{ Execution::Args::Type::OutputFile, Resource::String::OutputFileArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help },\r\n            Argument{ Execution::Args::Type::ConfigurationHistoryRemove, Resource::String::ConfigurationHistoryRemoveArgumentDescription, ArgumentType::Flag, Argument::Visibility::Help },\r\n            Argument{ Execution::Args::Type::ConfigurationStatusWatch, Resource::String::ConfigurationStatusWatchArgumentDescription, ArgumentType::Flag, Argument::Visibility::Hidden },\r\n        };\r\n    }\r\n\r\n    Resource::LocString ConfigureListCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::ConfigureListCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString ConfigureListCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::ConfigureListCommandLongDescription };\r\n    }\r\n\r\n    Utility::LocIndView ConfigureListCommand::HelpLink() const\r\n    {\r\n        return \"https://aka.ms/winget-command-configure#list\"_liv;\r\n    }\r\n\r\n    void ConfigureListCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        context <<\r\n            VerifyIsFullPackage <<\r\n            CreateConfigurationProcessorWithoutFactory <<\r\n            GetConfigurationSetHistory;\r\n\r\n        if (context.Args.Contains(Execution::Args::Type::ConfigurationHistoryItem))\r\n        {\r\n            context << SelectSetFromHistory;\r\n\r\n            if (context.Args.Contains(Execution::Args::Type::OutputFile))\r\n            {\r\n                context << SerializeConfigurationSetHistory;\r\n            }\r\n\r\n            if (context.Args.Contains(Execution::Args::Type::ConfigurationHistoryRemove))\r\n            {\r\n                context << RemoveConfigurationSetHistory;\r\n            }\r\n            else\r\n            {\r\n                context << ShowSingleConfigurationSetHistory;\r\n            }\r\n        }\r\n        else if (context.Args.Contains(Execution::Args::Type::ConfigurationStatusWatch))\r\n        {\r\n            context << MonitorConfigurationStatus;\r\n        }\r\n        else\r\n        {\r\n            context << ShowConfigurationSetHistory;\r\n        }\r\n    }\r\n\r\n    void ConfigureListCommand::ValidateArgumentsInternal(Execution::Args& execArgs) const\r\n    {\r\n        if ((execArgs.Contains(Execution::Args::Type::ConfigurationHistoryRemove) ||\r\n             execArgs.Contains(Execution::Args::Type::OutputFile)) &&\r\n            !execArgs.Contains(Execution::Args::Type::ConfigurationHistoryItem))\r\n        {\r\n            throw CommandException(Resource::String::RequiredArgError(ArgumentCommon::ForType(Execution::Args::Type::ConfigurationHistoryItem).Name));\r\n        }\r\n    }\r\n\r\n    void ConfigureListCommand::Complete(Execution::Context& context, Execution::Args::Type argType) const\r\n    {\r\n        if (argType == Execution::Args::Type::ConfigurationHistoryItem)\r\n        {\r\n            context << CompleteConfigurationHistoryItem;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ConfigureListCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Command.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    struct ConfigureListCommand final : public Command\r\n    {\r\n        ConfigureListCommand(std::string_view parent) : Command(\"list\", { \"ls\" }, parent) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n        void ValidateArgumentsInternal(Execution::Args& execArgs) const override;\r\n        void Complete(Execution::Context& context, Execution::Args::Type argType) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ConfigureShowCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigureShowCommand.h\"\r\n#include \"Workflows/ConfigurationFlow.h\"\r\n#include \"Workflows/MSStoreInstallerHandler.h\"\r\n#include \"ConfigurationCommon.h\"\r\n\r\nusing namespace AppInstaller::CLI::Workflow;\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    std::vector<Argument> ConfigureShowCommand::GetArguments() const\r\n    {\r\n        return {\r\n            // Required for now, make exclusive when history implemented\r\n            Argument{ Execution::Args::Type::ConfigurationFile, Resource::String::ConfigurationFileArgumentDescription, ArgumentType::Positional },\r\n            Argument{ Execution::Args::Type::ConfigurationModulePath, Resource::String::ConfigurationModulePath, ArgumentType::Positional },\r\n            Argument{ Execution::Args::Type::ConfigurationProcessorPath, Resource::String::ConfigurationProcessorPath, ArgumentType::Standard, Argument::Visibility::Help },\r\n            Argument{ Execution::Args::Type::ConfigurationHistoryItem, Resource::String::ConfigurationHistoryItemArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help },\r\n        };\r\n    }\r\n\r\n    Resource::LocString ConfigureShowCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::ConfigureShowCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString ConfigureShowCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::ConfigureShowCommandLongDescription };\r\n    }\r\n\r\n    Utility::LocIndView ConfigureShowCommand::HelpLink() const\r\n    {\r\n        return \"https://aka.ms/winget-command-configure#show\"_liv;\r\n    }\r\n\r\n    void ConfigureShowCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        context <<\r\n            VerifyIsFullPackage <<\r\n            VerifyFileOrUri(Execution::Args::Type::ConfigurationFile) <<\r\n            CreateConfigurationProcessorWithoutFactory <<\r\n            OpenConfigurationSet <<\r\n            CreateConfigurationProcessor <<\r\n            ShowConfigurationSet;\r\n    }\r\n\r\n    void ConfigureShowCommand::ValidateArgumentsInternal(Execution::Args& execArgs) const\r\n    {\r\n        Configuration::ValidateCommonArguments(execArgs, true);\r\n    }\r\n\r\n    void ConfigureShowCommand::Complete(Execution::Context& context, Execution::Args::Type argType) const\r\n    {\r\n        if (argType == Execution::Args::Type::ConfigurationHistoryItem)\r\n        {\r\n            context << CompleteConfigurationHistoryItem;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ConfigureShowCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Command.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    struct ConfigureShowCommand final : public Command\r\n    {\r\n        ConfigureShowCommand(std::string_view parent) : Command(\"show\", { \"view\" }, parent) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n        void ValidateArgumentsInternal(Execution::Args& execArgs) const override;\r\n        void Complete(Execution::Context& context, Execution::Args::Type argType) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ConfigureTestCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigureTestCommand.h\"\r\n#include \"Workflows/ConfigurationFlow.h\"\r\n#include \"Workflows/MSStoreInstallerHandler.h\"\r\n#include \"ConfigurationCommon.h\"\r\n\r\nusing namespace AppInstaller::CLI::Workflow;\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    std::vector<Argument> ConfigureTestCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument{ Execution::Args::Type::ConfigurationFile, Resource::String::ConfigurationFileArgumentDescription, ArgumentType::Positional },\r\n            Argument{ Execution::Args::Type::ConfigurationModulePath, Resource::String::ConfigurationModulePath, ArgumentType::Positional },\r\n            Argument{ Execution::Args::Type::ConfigurationProcessorPath, Resource::String::ConfigurationProcessorPath, ArgumentType::Standard, Argument::Visibility::Help },\r\n            Argument{ Execution::Args::Type::ConfigurationHistoryItem, Resource::String::ConfigurationHistoryItemArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help },\r\n            Argument{ Execution::Args::Type::ConfigurationSuppressPrologue, Resource::String::ConfigurationSuppressPrologueArgumentDescription, ArgumentType::Flag, Argument::Visibility::Help },\r\n            Argument{ Execution::Args::Type::ConfigurationAcceptWarning, Resource::String::ConfigurationAcceptWarningArgumentDescription, ArgumentType::Flag },\r\n        };\r\n    }\r\n\r\n    Resource::LocString ConfigureTestCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::ConfigureTestCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString ConfigureTestCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::ConfigureTestCommandLongDescription };\r\n    }\r\n\r\n    Utility::LocIndView ConfigureTestCommand::HelpLink() const\r\n    {\r\n        return \"https://aka.ms/winget-command-configure#test\"_liv;\r\n    }\r\n\r\n    void ConfigureTestCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        context <<\r\n            VerifyIsFullPackage <<\r\n            VerifyFileOrUri(Execution::Args::Type::ConfigurationFile) <<\r\n            CreateConfigurationProcessorWithoutFactory <<\r\n            OpenConfigurationSet <<\r\n            CreateConfigurationProcessor <<\r\n            ShowConfigurationSet <<\r\n            ShowConfigurationSetConflicts <<\r\n            ConfirmConfigurationProcessing(false) <<\r\n            TestConfigurationSet;\r\n    }\r\n\r\n    void ConfigureTestCommand::ValidateArgumentsInternal(Execution::Args& execArgs) const\r\n    {\r\n        Configuration::ValidateCommonArguments(execArgs, true);\r\n    }\r\n\r\n    void ConfigureTestCommand::Complete(Execution::Context& context, Execution::Args::Type argType) const\r\n    {\r\n        if (argType == Execution::Args::Type::ConfigurationHistoryItem)\r\n        {\r\n            context << CompleteConfigurationHistoryItem;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ConfigureTestCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Command.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    struct ConfigureTestCommand final : public Command\r\n    {\r\n        ConfigureTestCommand(std::string_view parent) : Command(\"test\", parent) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n        void ValidateArgumentsInternal(Execution::Args& execArgs) const override;\r\n        void Complete(Execution::Context& context, Execution::Args::Type argType) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ConfigureValidateCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigureValidateCommand.h\"\r\n#include \"Workflows/ConfigurationFlow.h\"\r\n#include \"Workflows/MSStoreInstallerHandler.h\"\r\n#include \"ConfigurationCommon.h\"\r\n\r\nusing namespace AppInstaller::CLI::Workflow;\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    std::vector<Argument> ConfigureValidateCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument{ Execution::Args::Type::ConfigurationFile, Resource::String::ConfigurationFileArgumentDescription, ArgumentType::Positional, true },\r\n            Argument{ Execution::Args::Type::ConfigurationModulePath, Resource::String::ConfigurationModulePath, ArgumentType::Positional },\r\n            Argument{ Execution::Args::Type::ConfigurationProcessorPath, Resource::String::ConfigurationProcessorPath, ArgumentType::Standard, Argument::Visibility::Help },\r\n        };\r\n    }\r\n\r\n    Resource::LocString ConfigureValidateCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::ConfigureValidateCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString ConfigureValidateCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::ConfigureValidateCommandLongDescription };\r\n    }\r\n\r\n    Utility::LocIndView ConfigureValidateCommand::HelpLink() const\r\n    {\r\n        return \"https://aka.ms/winget-command-configure#validate\"_liv;\r\n    }\r\n\r\n    void ConfigureValidateCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        context <<\r\n            VerifyIsFullPackage <<\r\n            VerifyFileOrUri(Execution::Args::Type::ConfigurationFile) <<\r\n            CreateConfigurationProcessorWithoutFactory <<\r\n            OpenConfigurationSet <<\r\n            CreateConfigurationProcessor <<\r\n            ValidateConfigurationSetSemantics <<\r\n            ValidateConfigurationSetUnitProcessors <<\r\n            ValidateConfigurationSetUnitContents <<\r\n            ValidateAllGoodMessage;\r\n    }\r\n\r\n    void ConfigureValidateCommand::ValidateArgumentsInternal(Execution::Args& execArgs) const\r\n    {\r\n        Configuration::ValidateCommonArguments(execArgs);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ConfigureValidateCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Command.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    struct ConfigureValidateCommand final : public Command\r\n    {\r\n        ConfigureValidateCommand(std::string_view parent) : Command(\"validate\", parent) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n        void ValidateArgumentsInternal(Execution::Args& execArgs) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/DebugCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n\r\n#if _DEBUG\r\n#include \"DebugCommand.h\"\r\n#include <winrt/Microsoft.Management.Configuration.h>\r\n#include <winrt/Microsoft.Management.Configuration.SetProcessorFactory.h>\r\n#include \"AppInstallerDownloader.h\"\r\n#include \"Sixel.h\"\r\n\r\nusing namespace AppInstaller::CLI::Execution;\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    namespace\r\n    {\r\n        std::string MakeInterfaceNameAttribute(std::wstring_view name)\r\n        {\r\n            std::string result = Utility::ConvertToUTF8(name);\r\n            Utility::FindAndReplace(result, \"<\", \"&lt;\");\r\n            Utility::FindAndReplace(result, \">\", \"&gt;\");\r\n            return result;\r\n        }\r\n\r\n        std::string MakeIIDAttribute(const winrt::guid& guid)\r\n        {\r\n            std::string result;\r\n            wchar_t buffer[256];\r\n\r\n            if (StringFromGUID2(guid, buffer, ARRAYSIZE(buffer)))\r\n            {\r\n                result = AppInstaller::Utility::ConvertToUTF8(buffer);\r\n                result = result.substr(1, result.length() - 2);\r\n            }\r\n            else\r\n            {\r\n                result = \"error\";\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        template <typename Interface>\r\n        void OutputProxyStubInterfaceRegistration(Execution::Context& context)\r\n        {\r\n            context.Reporter.Info() << \"<Interface Name=\\\"\" << MakeInterfaceNameAttribute(winrt::name_of<Interface>()) << \"\\\" InterfaceId=\\\"\" << MakeIIDAttribute(winrt::guid_of<Interface>()) << \"\\\" />\" << std::endl;\r\n        }\r\n\r\n        template <typename Interface>\r\n        void OutputIIDMapping(Execution::Context& context)\r\n        {\r\n            context.Reporter.Info() << Utility::ConvertToUTF8(winrt::name_of<Interface>()) << \" == \" << winrt::guid_of<Interface>() << std::endl;\r\n        }\r\n    }\r\n\r\n    std::vector<std::unique_ptr<Command>> DebugCommand::GetCommands() const\r\n    {\r\n        return InitializeFromMoveOnly<std::vector<std::unique_ptr<Command>>>({\r\n            std::make_unique<DumpProxyStubRegistrationsCommand>(FullName()),\r\n            std::make_unique<DumpInterestingIIDsCommand>(FullName()),\r\n            std::make_unique<DumpErrorResourceCommand>(FullName()),\r\n            std::make_unique<ShowSixelCommand>(FullName()),\r\n            std::make_unique<ProgressCommand>(FullName()),\r\n        });\r\n    }\r\n\r\n    Resource::LocString DebugCommand::ShortDescription() const\r\n    {\r\n        return Utility::LocIndString(\"Debug only dev commands\"sv);\r\n    }\r\n\r\n    Resource::LocString DebugCommand::LongDescription() const\r\n    {\r\n        return Utility::LocIndString(\"Commands that are useful in debugging and development.\"sv);\r\n    }\r\n\r\n    void DebugCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        OutputHelp(context.Reporter);\r\n    }\r\n\r\n    Resource::LocString DumpProxyStubRegistrationsCommand::ShortDescription() const\r\n    {\r\n        return Utility::LocIndString(\"Dump proxy-stub registrations\"sv);\r\n    }\r\n\r\n    Resource::LocString DumpProxyStubRegistrationsCommand::LongDescription() const\r\n    {\r\n        return Utility::LocIndString(\"Dump proxy-stub registrations for WinRT interfaces to be place in the manifest.\"sv);\r\n    }\r\n\r\n    void DumpProxyStubRegistrationsCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        OutputProxyStubInterfaceRegistration<winrt::Windows::Foundation::Collections::IIterable<winrt::Microsoft::Management::Configuration::ConfigurationUnit>>(context);\r\n        OutputProxyStubInterfaceRegistration<winrt::Windows::Foundation::Collections::IIterable<winrt::Microsoft::Management::Configuration::ConfigurationSet>>(context);\r\n        OutputProxyStubInterfaceRegistration<winrt::Windows::Foundation::Collections::IIterable<winrt::Microsoft::Management::Configuration::ConfigurationConflict>>(context);\r\n        OutputProxyStubInterfaceRegistration<winrt::Windows::Foundation::Collections::IIterable<winrt::Microsoft::Management::Configuration::ConfigurationParameter>>(context);\r\n        OutputProxyStubInterfaceRegistration<winrt::Windows::Foundation::Collections::IIterable<winrt::Microsoft::Management::Configuration::IConfigurationUnitSettingDetails>>(context);\r\n        OutputProxyStubInterfaceRegistration<winrt::Windows::Foundation::Collections::IIterable<winrt::Microsoft::Management::Configuration::ConfigurationConflictSetting>>(context);\r\n        OutputProxyStubInterfaceRegistration<winrt::Windows::Foundation::Collections::IIterable<winrt::Microsoft::Management::Configuration::GetConfigurationUnitDetailsResult>>(context);\r\n        OutputProxyStubInterfaceRegistration<winrt::Windows::Foundation::Collections::IIterable<winrt::Microsoft::Management::Configuration::ApplyConfigurationUnitResult>>(context);\r\n        OutputProxyStubInterfaceRegistration<winrt::Windows::Foundation::Collections::IIterable<winrt::Microsoft::Management::Configuration::TestConfigurationUnitResult>>(context);\r\n        OutputProxyStubInterfaceRegistration<winrt::Windows::Foundation::Collections::IIterable<winrt::Microsoft::Management::Configuration::IApplyGroupMemberSettingsResult>>(context);\r\n        OutputProxyStubInterfaceRegistration<winrt::Windows::Foundation::Collections::IIterable<winrt::Microsoft::Management::Configuration::ITestSettingsResult>>(context);\r\n        OutputProxyStubInterfaceRegistration<winrt::Windows::Foundation::Collections::IIterable<winrt::Microsoft::Management::Configuration::ConfigurationEnvironment>>(context);\r\n        OutputProxyStubInterfaceRegistration<winrt::Windows::Foundation::Collections::IIterable<winrt::Microsoft::Management::Configuration::IConfigurationUnitProcessorDetails>>(context);\r\n        OutputProxyStubInterfaceRegistration<winrt::Microsoft::Management::Configuration::IConfigurationUnitProcessorDetails2>(context);\r\n        OutputProxyStubInterfaceRegistration<winrt::Microsoft::Management::Configuration::IConfigurationUnitProcessorDetails3>(context);\r\n        OutputProxyStubInterfaceRegistration<winrt::Microsoft::Management::Configuration::IGetAllSettingsConfigurationUnitProcessor>(context);\r\n        OutputProxyStubInterfaceRegistration<winrt::Microsoft::Management::Configuration::IGetAllUnitsConfigurationUnitProcessor>(context);\r\n        OutputProxyStubInterfaceRegistration<winrt::Microsoft::Management::Configuration::IFindUnitProcessorsSetProcessor>(context);\r\n        OutputProxyStubInterfaceRegistration<winrt::Microsoft::Management::Configuration::IConfigurationStatics2>(context);\r\n        OutputProxyStubInterfaceRegistration<winrt::Microsoft::Management::Configuration::IConfigurationStatics3>(context);\r\n        OutputProxyStubInterfaceRegistration<winrt::Microsoft::Management::Configuration::SetProcessorFactory::IPwshConfigurationSetProcessorFactoryProperties>(context);\r\n\r\n        // TODO: Fix the layering inversion created by the COM deployment API (probably in order to operate winget.exe against the COM server).\r\n        //       Then this code can just have a CppWinRT reference to the deployment API and spit out the interface registrations just like for configuration.\r\n        HMODULE module = nullptr;\r\n        if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, reinterpret_cast<LPCWSTR>(&MakeInterfaceNameAttribute), &module))\r\n        {\r\n            return;\r\n        }\r\n\r\n        // TODO: Have a PRIVATE export from WindowsPackageManager that returns a set of names and IIDs to include from the Deployment API surface\r\n    }\r\n\r\n    Resource::LocString DumpInterestingIIDsCommand::ShortDescription() const\r\n    {\r\n        return Utility::LocIndString(\"Dump some IIDs\"sv);\r\n    }\r\n\r\n    Resource::LocString DumpInterestingIIDsCommand::LongDescription() const\r\n    {\r\n        return Utility::LocIndString(\"Dump some IIDs that might be useful.\"sv);\r\n    }\r\n\r\n    void DumpInterestingIIDsCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        OutputIIDMapping<winrt::Microsoft::Management::Configuration::IConfigurationStatics>(context);\r\n        OutputIIDMapping<winrt::Microsoft::Management::Configuration::IConfigurationStatics2>(context);\r\n        OutputIIDMapping<winrt::Microsoft::Management::Configuration::IConfigurationStatics3>(context);\r\n    }\r\n\r\n    Resource::LocString DumpErrorResourceCommand::ShortDescription() const\r\n    {\r\n        return Utility::LocIndString(\"Dump error resources\"sv);\r\n    }\r\n\r\n    Resource::LocString DumpErrorResourceCommand::LongDescription() const\r\n    {\r\n        return Utility::LocIndString(\"Dump the error information as resources.\"sv);\r\n    }\r\n\r\n    void DumpErrorResourceCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        auto info = context.Reporter.Info();\r\n\r\n        //  <data name=\"InstallFlowReturnCodeInstallInProgress\" xml:space=\"preserve\">\r\n        //    <value>Another installation is already in progress. Try again later.</value>\r\n        //  </data>\r\n        for (const auto& error : Errors::GetWinGetErrors())\r\n        {\r\n            info <<\r\n                \"  <data name=\\\"\" << error->Symbol() << \"\\\" xml:space=\\\"preserve\\\">\\n\"\r\n                \"    <value>\" << error->GetDescription() << \"</value>\\n\"\r\n                \"  </data>\" << std::endl;\r\n        }\r\n    }\r\n\r\n#define WINGET_DEBUG_SIXEL_FILE Args::Type::Manifest\r\n#define WINGET_DEBUG_SIXEL_ASPECT_RATIO Args::Type::AcceptPackageAgreements\r\n#define WINGET_DEBUG_SIXEL_TRANSPARENT Args::Type::AcceptSourceAgreements\r\n#define WINGET_DEBUG_SIXEL_COLOR_COUNT Args::Type::ConfigurationAcceptWarning\r\n#define WINGET_DEBUG_SIXEL_WIDTH Args::Type::AdminSettingEnable\r\n#define WINGET_DEBUG_SIXEL_HEIGHT Args::Type::AllowReboot\r\n#define WINGET_DEBUG_SIXEL_STRETCH Args::Type::AllVersions\r\n#define WINGET_DEBUG_SIXEL_REPEAT Args::Type::Name\r\n#define WINGET_DEBUG_SIXEL_OUT_FILE Args::Type::BlockingPin\r\n\r\n    std::vector<Argument> ShowSixelCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument{ \"file\", 'f', WINGET_DEBUG_SIXEL_FILE, Resource::String::SourceListUpdatedNever, ArgumentType::Positional },\r\n            Argument{ \"aspect-ratio\", 'a', WINGET_DEBUG_SIXEL_ASPECT_RATIO, Resource::String::SourceListUpdatedNever, ArgumentType::Standard },\r\n            Argument{ \"transparent\", 't', WINGET_DEBUG_SIXEL_TRANSPARENT, Resource::String::SourceListUpdatedNever, ArgumentType::Flag },\r\n            Argument{ \"color-count\", 'c', WINGET_DEBUG_SIXEL_COLOR_COUNT, Resource::String::SourceListUpdatedNever, ArgumentType::Standard },\r\n            Argument{ \"width\", 'w', WINGET_DEBUG_SIXEL_WIDTH, Resource::String::SourceListUpdatedNever, ArgumentType::Standard },\r\n            Argument{ \"height\", 'h', WINGET_DEBUG_SIXEL_HEIGHT, Resource::String::SourceListUpdatedNever, ArgumentType::Standard },\r\n            Argument{ \"stretch\", 's', WINGET_DEBUG_SIXEL_STRETCH, Resource::String::SourceListUpdatedNever, ArgumentType::Flag },\r\n            Argument{ \"repeat\", 'r', WINGET_DEBUG_SIXEL_REPEAT, Resource::String::SourceListUpdatedNever, ArgumentType::Flag },\r\n            Argument{ \"out-file\", 'o', WINGET_DEBUG_SIXEL_OUT_FILE, Resource::String::SourceListUpdatedNever, ArgumentType::Standard },\r\n        };\r\n    }\r\n\r\n    Resource::LocString ShowSixelCommand::ShortDescription() const\r\n    {\r\n        return Utility::LocIndString(\"Output an image with sixels\"sv);\r\n    }\r\n\r\n    Resource::LocString ShowSixelCommand::LongDescription() const\r\n    {\r\n        return Utility::LocIndString(\"Outputs an image from a file using sixel format.\"sv);\r\n    }\r\n\r\n    void ShowSixelCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        using namespace VirtualTerminal;\r\n        std::unique_ptr<Sixel::Image> sixelImagePtr;\r\n\r\n        std::string imageUrl{ context.Args.GetArg(WINGET_DEBUG_SIXEL_FILE) };\r\n\r\n        if (Utility::IsUrlRemote(imageUrl))\r\n        {\r\n            auto imageStream = std::make_unique<std::stringstream>();\r\n            ProgressCallback emptyCallback;\r\n            Utility::DownloadToStream(imageUrl, *imageStream, Utility::DownloadType::Manifest, emptyCallback);\r\n\r\n            sixelImagePtr = std::make_unique<Sixel::Image>(*imageStream, Manifest::IconFileTypeEnum::Unknown);\r\n        }\r\n        else\r\n        {\r\n            sixelImagePtr = std::make_unique<Sixel::Image>(Utility::ConvertToUTF16(imageUrl));\r\n        }\r\n\r\n        Sixel::Image& sixelImage = *sixelImagePtr.get();\r\n\r\n        if (context.Args.Contains(WINGET_DEBUG_SIXEL_ASPECT_RATIO))\r\n        {\r\n            switch (context.Args.GetArg(WINGET_DEBUG_SIXEL_ASPECT_RATIO)[0])\r\n            {\r\n            case '1':\r\n                sixelImage.AspectRatio(Sixel::AspectRatio::OneToOne);\r\n                break;\r\n            case '2':\r\n                sixelImage.AspectRatio(Sixel::AspectRatio::TwoToOne);\r\n                break;\r\n            case '3':\r\n                sixelImage.AspectRatio(Sixel::AspectRatio::ThreeToOne);\r\n                break;\r\n            case '5':\r\n                sixelImage.AspectRatio(Sixel::AspectRatio::FiveToOne);\r\n                break;\r\n            }\r\n        }\r\n\r\n        sixelImage.Transparency(context.Args.Contains(WINGET_DEBUG_SIXEL_TRANSPARENT));\r\n\r\n        if (context.Args.Contains(WINGET_DEBUG_SIXEL_COLOR_COUNT))\r\n        {\r\n            sixelImage.ColorCount(std::stoul(std::string{ context.Args.GetArg(WINGET_DEBUG_SIXEL_COLOR_COUNT) }));\r\n        }\r\n\r\n        if (context.Args.Contains(WINGET_DEBUG_SIXEL_WIDTH) && context.Args.Contains(WINGET_DEBUG_SIXEL_HEIGHT))\r\n        {\r\n            sixelImage.RenderSizeInCells(\r\n                std::stoul(std::string{ context.Args.GetArg(WINGET_DEBUG_SIXEL_WIDTH) }),\r\n                std::stoul(std::string{ context.Args.GetArg(WINGET_DEBUG_SIXEL_HEIGHT) }));\r\n        }\r\n\r\n        sixelImage.StretchSourceToFill(context.Args.Contains(WINGET_DEBUG_SIXEL_STRETCH));\r\n\r\n        sixelImage.UseRepeatSequence(context.Args.Contains(WINGET_DEBUG_SIXEL_REPEAT));\r\n\r\n        if (context.Args.Contains(WINGET_DEBUG_SIXEL_OUT_FILE))\r\n        {\r\n            std::ofstream stream{ Utility::ConvertToUTF16(context.Args.GetArg(WINGET_DEBUG_SIXEL_OUT_FILE)) };\r\n            stream << sixelImage.Render().Get();\r\n        }\r\n        else\r\n        {\r\n            OutputStream stream = context.Reporter.GetOutputStream(Reporter::Level::Info);\r\n            stream.ClearFormat();\r\n            sixelImage.RenderTo(stream);\r\n\r\n            // Force a new line to show entire image\r\n            stream << std::endl;\r\n        }\r\n    }\r\n\r\n#define WINGET_DEBUG_PROGRESS_SIXEL Args::Type::Manifest\r\n#define WINGET_DEBUG_PROGRESS_DISABLED Args::Type::GatedVersion\r\n#define WINGET_DEBUG_PROGRESS_HIDE Args::Type::AcceptPackageAgreements\r\n#define WINGET_DEBUG_PROGRESS_TIME Args::Type::AcceptSourceAgreements\r\n#define WINGET_DEBUG_PROGRESS_MESSAGE Args::Type::ConfigurationAcceptWarning\r\n#define WINGET_DEBUG_PROGRESS_PERCENT Args::Type::AllowReboot\r\n#define WINGET_DEBUG_PROGRESS_POST Args::Type::AllVersions\r\n\r\n    std::vector<Argument> ProgressCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument{ \"sixel\", 's', WINGET_DEBUG_PROGRESS_SIXEL, Resource::String::SourceListUpdatedNever, ArgumentType::Flag },\r\n            Argument{ \"disabled\", 'd', WINGET_DEBUG_PROGRESS_DISABLED, Resource::String::SourceListUpdatedNever, ArgumentType::Flag },\r\n            Argument{ \"hide\", 'h', WINGET_DEBUG_PROGRESS_HIDE, Resource::String::SourceListUpdatedNever, ArgumentType::Flag },\r\n            Argument{ \"time\", 't', WINGET_DEBUG_PROGRESS_TIME, Resource::String::SourceListUpdatedNever, ArgumentType::Standard },\r\n            Argument{ \"message\", 'm', WINGET_DEBUG_PROGRESS_MESSAGE, Resource::String::SourceListUpdatedNever, ArgumentType::Standard },\r\n            Argument{ \"percent\", 'p', WINGET_DEBUG_PROGRESS_PERCENT, Resource::String::SourceListUpdatedNever, ArgumentType::Flag },\r\n            Argument{ \"post\", 0, WINGET_DEBUG_PROGRESS_POST, Resource::String::SourceListUpdatedNever, ArgumentType::Standard },\r\n        };\r\n    }\r\n\r\n    Resource::LocString ProgressCommand::ShortDescription() const\r\n    {\r\n        return Utility::LocIndString(\"Show progress\"sv);\r\n    }\r\n\r\n    Resource::LocString ProgressCommand::LongDescription() const\r\n    {\r\n        return Utility::LocIndString(\"Show progress with various controls to emulate different behaviors.\"sv);\r\n    }\r\n\r\n    void ProgressCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        if (context.Args.Contains(WINGET_DEBUG_PROGRESS_SIXEL))\r\n        {\r\n            context.Reporter.SetStyle(Settings::VisualStyle::Sixel);\r\n        }\r\n\r\n        if (context.Args.Contains(WINGET_DEBUG_PROGRESS_DISABLED))\r\n        {\r\n            context.Reporter.SetStyle(Settings::VisualStyle::Disabled);\r\n        }\r\n\r\n        auto progress = context.Reporter.BeginAsyncProgress(context.Args.Contains(WINGET_DEBUG_PROGRESS_HIDE));\r\n\r\n        if (context.Args.Contains(WINGET_DEBUG_PROGRESS_MESSAGE))\r\n        {\r\n            progress->Callback().SetProgressMessage(context.Args.GetArg(WINGET_DEBUG_PROGRESS_MESSAGE));\r\n        }\r\n\r\n        bool sendProgress = context.Args.Contains(WINGET_DEBUG_PROGRESS_PERCENT);\r\n\r\n        UINT timeInSeconds = 3600;\r\n        if (context.Args.Contains(WINGET_DEBUG_PROGRESS_TIME))\r\n        {\r\n            timeInSeconds = std::stoul(std::string{ context.Args.GetArg(WINGET_DEBUG_PROGRESS_TIME) });\r\n        }\r\n\r\n        UINT ticks = timeInSeconds * 10;\r\n        for (UINT i = 0; i < ticks; ++i)\r\n        {\r\n            if (sendProgress)\r\n            {\r\n                progress->Callback().OnProgress(i, ticks, ProgressType::Bytes);\r\n            }\r\n\r\n            if (progress->Callback().IsCancelledBy(CancelReason::Any))\r\n            {\r\n                sendProgress = false;\r\n                break;\r\n            }\r\n\r\n            std::this_thread::sleep_for(100ms);\r\n        }\r\n\r\n        if (sendProgress)\r\n        {\r\n            progress->Callback().OnProgress(ticks, ticks, ProgressType::Bytes);\r\n        }\r\n\r\n        progress.reset();\r\n\r\n        if (context.Args.Contains(WINGET_DEBUG_PROGRESS_POST))\r\n        {\r\n            context.Reporter.Info() << context.Args.GetArg(WINGET_DEBUG_PROGRESS_POST) << std::endl;\r\n        }\r\n    }\r\n}\r\n\r\n#endif\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/DebugCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Command.h\"\r\n\r\n#if _DEBUG\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    // Command that is only available with debug builds to aid development.\r\n    // Don't create localized strings for use here.\r\n    struct DebugCommand final : public Command\r\n    {\r\n        DebugCommand(std::string_view parent) : Command(\"debug\", {}, parent, Visibility::Hidden) {}\r\n\r\n        std::vector<std::unique_ptr<Command>> GetCommands() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n\r\n    // Outputs the proxy stub registrations for the manifest.\r\n    struct DumpProxyStubRegistrationsCommand final : public Command\r\n    {\r\n        DumpProxyStubRegistrationsCommand(std::string_view parent) : Command(\"dump-proxystub-reg\", {}, parent) {}\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n\r\n    // Outputs some IIDs.\r\n    struct DumpInterestingIIDsCommand final : public Command\r\n    {\r\n        DumpInterestingIIDsCommand(std::string_view parent) : Command(\"dump-iids\", {}, parent) {}\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n\r\n    // Outputs the errors as resources.\r\n    struct DumpErrorResourceCommand final : public Command\r\n    {\r\n        DumpErrorResourceCommand(std::string_view parent) : Command(\"dump-error-resource\", {}, parent) {}\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n\r\n    // Outputs a sixel image.\r\n    struct ShowSixelCommand final : public Command\r\n    {\r\n        ShowSixelCommand(std::string_view parent) : Command(\"sixel\", {}, parent) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n\r\n    // Invokes progress display.\r\n    struct ProgressCommand final : public Command\r\n    {\r\n        ProgressCommand(std::string_view parent) : Command(\"progress\", {}, parent) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n}\r\n\r\n#endif\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/DownloadCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"DownloadCommand.h\"\r\n#include \"Workflows/CompletionFlow.h\"\r\n#include \"Workflows/DownloadFlow.h\"\r\n#include \"Workflows/InstallFlow.h\"\r\n#include \"Workflows/PromptFlow.h\"\r\n#include \"Resources.h\"\r\n#include <AppInstallerRuntime.h>\r\n#include <winget/ManifestCommon.h>\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    using namespace AppInstaller::CLI::Execution;\r\n    using namespace AppInstaller::CLI::Workflow;\r\n    using namespace AppInstaller::Utility::literals;\r\n\r\n    std::vector<Argument> DownloadCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument::ForType(Args::Type::Query),\r\n            Argument::ForType(Args::Type::DownloadDirectory),\r\n            Argument::ForType(Args::Type::Manifest),\r\n            Argument::ForType(Args::Type::Id),\r\n            Argument::ForType(Args::Type::Name),\r\n            Argument::ForType(Args::Type::Moniker),\r\n            Argument::ForType(Args::Type::Version),\r\n            Argument::ForType(Args::Type::Channel),\r\n            Argument::ForType(Args::Type::Source),\r\n            Argument{ Args::Type::InstallScope, Resource::String::InstallScopeDescription, ArgumentType::Standard, Argument::Visibility::Help },\r\n            Argument::ForType(Args::Type::InstallerArchitecture),\r\n            Argument::ForType(Args::Type::InstallerType),\r\n            Argument::ForType(Args::Type::Exact),\r\n            Argument::ForType(Args::Type::Locale),\r\n            Argument::ForType(Args::Type::HashOverride),\r\n            Argument::ForType(Args::Type::SkipDependencies),\r\n            Argument::ForType(Args::Type::CustomHeader),\r\n            Argument::ForType(Args::Type::AuthenticationMode),\r\n            Argument::ForType(Args::Type::AuthenticationAccount),\r\n            Argument::ForType(Args::Type::AcceptPackageAgreements),\r\n            Argument::ForType(Args::Type::AcceptSourceAgreements),\r\n            Argument::ForType(Args::Type::SkipMicrosoftStorePackageLicense),\r\n            Argument::ForType(Args::Type::Platform),\r\n            Argument{ Args::Type::OSVersion, Resource::String::OSVersionDescription, ArgumentType::Standard, Argument::Visibility::Help },\r\n        };\r\n    }\r\n\r\n    Resource::LocString DownloadCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::DownloadCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString DownloadCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::DownloadCommandLongDescription };\r\n    }\r\n\r\n    void DownloadCommand::Complete(Context& context, Args::Type valueType) const\r\n    {\r\n        switch (valueType)\r\n        {\r\n        case Args::Type::Query:\r\n        case Args::Type::Manifest:\r\n        case Args::Type::Id:\r\n        case Args::Type::Name:\r\n        case Args::Type::Moniker:\r\n        case Args::Type::Version:\r\n        case Args::Type::Channel:\r\n        case Args::Type::Source:\r\n            context <<\r\n                Workflow::CompleteWithSingleSemanticsForValue(valueType);\r\n            break;\r\n        case Args::Type::InstallerArchitecture:\r\n        case Args::Type::Locale:\r\n            // May well move to CompleteWithSingleSemanticsForValue,\r\n            // but for now output nothing.\r\n            context <<\r\n                Workflow::CompleteWithEmptySet;\r\n            break;\r\n        case Args::Type::Log:\r\n        case Args::Type::DownloadDirectory:\r\n            // Intentionally output nothing to allow pass through to filesystem.\r\n            break;\r\n        }\r\n    }\r\n\r\n    Utility::LocIndView DownloadCommand::HelpLink() const\r\n    {\r\n        return \"https://aka.ms/winget-command-download\"_liv;\r\n    }\r\n\r\n    void DownloadCommand::ValidateArgumentsInternal(Args& execArgs) const\r\n    {\r\n        Argument::ValidateCommonArguments(execArgs);\r\n\r\n        if (execArgs.Contains(Execution::Args::Type::Platform))\r\n        {\r\n            Manifest::PlatformEnum selectedPlatform = Manifest::ConvertToPlatformEnumForMSStoreDownload(execArgs.GetArg(Execution::Args::Type::Platform));\r\n            if (selectedPlatform == Manifest::PlatformEnum::Unknown)\r\n            {\r\n                auto validOptions = Utility::Join(\", \"_liv, std::vector<Utility::LocIndString>{\r\n                    \"Windows.Universal\"_lis, \"Windows.Desktop\"_lis, \"Windows.IoT\"_lis, \"Windows.Team\"_lis, \"Windows.Holographic\"_lis\r\n                });\r\n                throw CommandException(Resource::String::InvalidArgumentValueError(Argument::ForType(Execution::Args::Type::Platform).Name(), validOptions));\r\n            }\r\n        }\r\n    }\r\n\r\n    void DownloadCommand::ExecuteInternal(Context& context) const\r\n    {\r\n        context.SetFlags(AppInstaller::CLI::Execution::ContextFlag::InstallerDownloadOnly);\r\n\r\n        context << Workflow::InitializeInstallerDownloadAuthenticatorsMap;\r\n\r\n        if (context.Args.Contains(Execution::Args::Type::Manifest))\r\n        {\r\n            context <<\r\n                Workflow::ReportExecutionStage(ExecutionStage::Discovery) <<\r\n                Workflow::GetManifestFromArg;\r\n        }\r\n        else\r\n        {\r\n            context <<\r\n                Workflow::ReportExecutionStage(ExecutionStage::Discovery) <<\r\n                Workflow::OpenSource() <<\r\n                Workflow::SearchSourceForSingle <<\r\n                Workflow::HandleSearchResultFailures <<\r\n                Workflow::EnsureOneMatchFromSearchResult(OperationType::Download) <<\r\n                Workflow::GetManifestFromPackage(false);\r\n        }\r\n\r\n        context <<\r\n            Workflow::SetDownloadDirectory <<\r\n            Workflow::SelectInstaller <<\r\n            Workflow::EnsureApplicableInstaller <<\r\n            Workflow::ReportIdentityAndInstallationDisclaimer <<\r\n            Workflow::ShowPromptsForSinglePackage(/* ensureAcceptance */ true) <<\r\n            Workflow::DownloadPackageDependencies <<\r\n            Workflow::DownloadInstaller;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/DownloadCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"Command.h\"\n\nnamespace AppInstaller::CLI\n{\n    struct DownloadCommand final : public Command\n    {\n        DownloadCommand(std::string_view parent) : Command(\"download\", {} /* aliases */, parent) {}\n\n        std::vector<Argument> GetArguments() const override;\n\n        Resource::LocString ShortDescription() const override;\n        Resource::LocString LongDescription() const override;\r\n\r\n        void Complete(Execution::Context& context, Execution::Args::Type valueType) const override;\n\n        Utility::LocIndView HelpLink() const override;\n\n    protected:\n        void ValidateArgumentsInternal(Execution::Args& execArgs) const override;\n        void ExecuteInternal(Execution::Context& context) const override;\n    };\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/DscAdminSettingsResource.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"DscAdminSettingsResource.h\"\r\n#include \"DscComposableObject.h\"\r\n#include \"Resources.h\"\r\n#include <winget/AdminSettings.h>\r\n\r\nusing namespace AppInstaller::Utility::literals;\r\nusing namespace AppInstaller::Repository;\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    namespace AdminSettingsDetails\r\n    {\r\n        // The base for admin settings.\r\n        struct IAdminSetting\r\n        {\r\n            virtual ~IAdminSetting() = default;\r\n\r\n            // Gets the name of the setting.\r\n            virtual Utility::LocIndView SettingName() const = 0;\r\n\r\n            // Tests the value.\r\n            // Returns true if in the desired state; false if not.\r\n            virtual bool Test() const = 0;\r\n\r\n            // Sets the value.\r\n            // Returns true if the value could be set; false if not.\r\n            virtual bool Set() const = 0;\r\n        };\r\n\r\n        // A boolean based admin setting\r\n        struct AdminSetting_Bool : public IAdminSetting\r\n        {\r\n            AdminSetting_Bool(Settings::BoolAdminSetting setting, bool value) : m_setting(setting), m_value(value) {}\r\n\r\n            Utility::LocIndView SettingName() const override\r\n            {\r\n                return Settings::AdminSettingToString(m_setting);\r\n            }\r\n\r\n            bool Test() const override\r\n            {\r\n                return Settings::IsAdminSettingEnabled(m_setting) == m_value;\r\n            }\r\n\r\n            bool Set() const override\r\n            {\r\n                return m_value ? Settings::EnableAdminSetting(m_setting) : Settings::DisableAdminSetting(m_setting);\r\n            }\r\n\r\n        private:\r\n            Settings::BoolAdminSetting m_setting;\r\n            bool m_value;\r\n        };\r\n\r\n        // A string based admin setting\r\n        struct AdminSetting_String : public IAdminSetting\r\n        {\r\n            AdminSetting_String(Settings::StringAdminSetting setting, std::optional<std::string> value) : m_setting(setting), m_value(std::move(value)) {}\r\n\r\n            Utility::LocIndView SettingName() const override\r\n            {\r\n                return Settings::AdminSettingToString(m_setting);\r\n            }\r\n\r\n            bool Test() const override\r\n            {\r\n                return Settings::GetAdminSetting(m_setting) == m_value;\r\n            }\r\n\r\n            bool Set() const override\r\n            {\r\n                return m_value ? Settings::SetAdminSetting(m_setting, m_value.value()) : Settings::ResetAdminSetting(m_setting);\r\n            }\r\n\r\n        private:\r\n            Settings::StringAdminSetting m_setting;\r\n            std::optional<std::string> m_value;\r\n        };\r\n    }\r\n\r\n    namespace\r\n    {\r\n        WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY(SettingsProperty, Json::Value, Settings, \"settings\", Resource::String::DscResourcePropertyDescriptionAdminSettingsSettings);\r\n\r\n        using AdminSettingsResourceObject = DscComposableObject<StandardInDesiredStateProperty, SettingsProperty>;\r\n\r\n        struct AdminSettingsFunctionData\r\n        {\r\n            AdminSettingsFunctionData() = default;\r\n\r\n            AdminSettingsFunctionData(const std::optional<Json::Value>& json) :\r\n                Input(json)\r\n            {\r\n            }\r\n\r\n            const AdminSettingsResourceObject Input;\r\n            AdminSettingsResourceObject Output;\r\n            std::vector<std::unique_ptr<AdminSettingsDetails::IAdminSetting>> InputSettings;\r\n\r\n            // Converts the input settings into the appropriate settings object.\r\n            void ParseSettings()\r\n            {\r\n                if (Input.Settings())\r\n                {\r\n                    const Json::Value& inputSettings = Input.Settings().value();\r\n                    for (const auto& property : inputSettings.getMemberNames())\r\n                    {\r\n                        auto boolSetting = Settings::StringToBoolAdminSetting(property);\r\n                        if (boolSetting != Settings::BoolAdminSetting::Unknown)\r\n                        {\r\n                            bool value = inputSettings[property].asBool();\r\n                            AICLI_LOG(Config, Info, << \"Bool admin setting: \" << property << \" => \" << (value ? \"true\" : \"false\"));\r\n                            InputSettings.emplace_back(std::make_unique<AdminSettingsDetails::AdminSetting_Bool>(boolSetting, value));\r\n                            continue;\r\n                        }\r\n\r\n                        auto stringSetting = Settings::StringToStringAdminSetting(property);\r\n                        if (stringSetting != Settings::StringAdminSetting::Unknown)\r\n                        {\r\n                            const auto& propertyNode = inputSettings[property];\r\n                            std::optional<std::string> value;\r\n\r\n                            if (propertyNode.isNull())\r\n                            {\r\n                                AICLI_LOG(Config, Info, << \"String admin setting: \" << property << \" => null\");\r\n                            }\r\n                            else\r\n                            {\r\n                                value = propertyNode.asString();\r\n                                AICLI_LOG(Config, Info, << \"String admin setting: \" << property << \" => `\" << value.value() << \"`\");\r\n                            }\r\n\r\n                            InputSettings.emplace_back(std::make_unique<AdminSettingsDetails::AdminSetting_String>(stringSetting, std::move(value)));\r\n                            continue;\r\n                        }\r\n\r\n                        AICLI_LOG(Config, Warning, << \"Unknown admin setting: \" << property);\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Fills the Output object with the current state\r\n            void Get()\r\n            {\r\n                Json::Value adminSettings{ Json::objectValue };\r\n\r\n                for (const auto& setting : Settings::GetAllBoolAdminSettings())\r\n                {\r\n                    auto str = std::string{ Settings::AdminSettingToString(setting) };\r\n                    adminSettings[str] = Settings::IsAdminSettingEnabled(setting);\r\n                }\r\n\r\n                for (const auto& setting : Settings::GetAllStringAdminSettings())\r\n                {\r\n                    auto name = std::string{ Settings::AdminSettingToString(setting) };\r\n                    auto value = Settings::GetAdminSetting(setting);\r\n                    if (value)\r\n                    {\r\n                        adminSettings[name] = value.value();\r\n                    }\r\n                }\r\n\r\n                Output.Settings(std::move(adminSettings));\r\n            }\r\n\r\n            // Determines if the current Output values match the Input values state.\r\n            bool Test()\r\n            {\r\n                for (const auto& setting : InputSettings)\r\n                {\r\n                    if (!setting->Test())\r\n                    {\r\n                        return false;\r\n                    }\r\n                }\r\n\r\n                return true;\r\n            }\r\n\r\n            // Sets all of the input settings.\r\n            void Set()\r\n            {\r\n                for (const auto& setting : InputSettings)\r\n                {\r\n                    if (!setting->Test())\r\n                    {\r\n                        if (!setting->Set())\r\n                        {\r\n                            auto message = Resource::String::DisabledByGroupPolicy(setting->SettingName());\r\n                            THROW_HR_MSG(APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY, \"%hs\", message.get().c_str());\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            Json::Value DiffJson(bool inDesiredState)\r\n            {\r\n                Json::Value result{ Json::ValueType::arrayValue };\r\n\r\n                if (!inDesiredState)\r\n                {\r\n                    result.append(std::string{ SettingsProperty::Name() });\r\n                }\r\n\r\n                return result;\r\n            }\r\n        };\r\n    }\r\n\r\n    DscAdminSettingsResource::DscAdminSettingsResource(std::string_view parent) :\r\n        DscCommandBase(parent, \"admin-settings\", DscResourceKind::Resource,\r\n            DscFunctions::Get | DscFunctions::Set | DscFunctions::Test | DscFunctions::Export | DscFunctions::Schema,\r\n            DscFunctionModifiers::ImplementsPretest | DscFunctionModifiers::ReturnsStateAndDiff)\r\n    {\r\n    }\r\n\r\n    Resource::LocString DscAdminSettingsResource::ShortDescription() const\r\n    {\r\n        return Resource::String::DscAdminSettingsResourceShortDescription;\r\n    }\r\n\r\n    Resource::LocString DscAdminSettingsResource::LongDescription() const\r\n    {\r\n        return Resource::String::DscAdminSettingsResourceLongDescription;\r\n    }\r\n\r\n    std::string DscAdminSettingsResource::ResourceType() const\r\n    {\r\n        return \"AdminSettings\";\r\n    }\r\n\r\n    void DscAdminSettingsResource::ResourceFunctionGet(Execution::Context& context) const\r\n    {\r\n        AdminSettingsFunctionData data;\r\n        data.Get();\r\n        WriteJsonOutputLine(context, data.Output.ToJson());\r\n    }\r\n\r\n    void DscAdminSettingsResource::ResourceFunctionSet(Execution::Context& context) const\r\n    {\r\n        if (auto json = GetJsonFromInput(context))\r\n        {\r\n            AdminSettingsFunctionData data{ json };\r\n\r\n            data.ParseSettings();\r\n\r\n            bool inDesiredState = data.Test();\r\n            if (!inDesiredState)\r\n            {\r\n                Workflow::EnsureRunningAsAdmin(context);\r\n\r\n                if (context.IsTerminated())\r\n                {\r\n                    return;\r\n                }\r\n\r\n                data.Set();\r\n            }\r\n\r\n            data.Get();\r\n            WriteJsonOutputLine(context, data.Output.ToJson());\r\n            WriteJsonOutputLine(context, data.DiffJson(inDesiredState));\r\n        }\r\n    }\r\n\r\n    void DscAdminSettingsResource::ResourceFunctionTest(Execution::Context& context) const\r\n    {\r\n        if (auto json = GetJsonFromInput(context))\r\n        {\r\n            AdminSettingsFunctionData data{ json };\r\n\r\n            data.ParseSettings();\r\n\r\n            data.Get();\r\n            data.Output.InDesiredState(data.Test());\r\n\r\n            WriteJsonOutputLine(context, data.Output.ToJson());\r\n            WriteJsonOutputLine(context, data.DiffJson(data.Output.InDesiredState().value()));\r\n        }\r\n    }\r\n\r\n    void DscAdminSettingsResource::ResourceFunctionExport(Execution::Context& context) const\r\n    {\r\n        ResourceFunctionGet(context);\r\n    }\r\n\r\n    void DscAdminSettingsResource::ResourceFunctionSchema(Execution::Context& context) const\r\n    {\r\n        WriteJsonOutputLine(context, AdminSettingsResourceObject::Schema(ResourceType()));\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/DscAdminSettingsResource.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"DscCommandBase.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    // A resource for managing admin settings.\r\n    struct DscAdminSettingsResource : public DscCommandBase\r\n    {\r\n        DscAdminSettingsResource(std::string_view parent);\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n    protected:\r\n        std::string ResourceType() const override;\r\n\r\n        void ResourceFunctionGet(Execution::Context& context) const override;\r\n        void ResourceFunctionSet(Execution::Context& context) const override;\r\n        void ResourceFunctionTest(Execution::Context& context) const override;\r\n        void ResourceFunctionExport(Execution::Context& context) const override;\r\n        void ResourceFunctionSchema(Execution::Context& context) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/DscCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"DscCommand.h\"\r\n#include \"DscPackageResource.h\"\r\n#include \"DscUserSettingsFileResource.h\"\r\n#include \"DscSourceResource.h\"\r\n#include \"DscAdminSettingsResource.h\"\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n#include \"DscTestFileResource.h\"\r\n#include \"DscTestJsonResource.h\"\r\n#endif\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    namespace\r\n    {\r\n        Argument GetOutputFileArgument()\r\n        {\r\n            return { Execution::Args::Type::OutputFile, Resource::String::OutputDirectoryArgumentDescription, ArgumentType::Standard };\r\n        }\r\n    }\r\n\r\n    DscCommand::DscCommand(std::string_view parent) :\r\n        Command(StaticName(), parent)\r\n    {\r\n    }\r\n\r\n    std::vector<std::unique_ptr<Command>> DscCommand::GetCommands() const\r\n    {\r\n        // These should all derive from DscCommandBase\r\n        return InitializeFromMoveOnly<std::vector<std::unique_ptr<Command>>>({\r\n            std::make_unique<DscPackageResource>(FullName()),\r\n            std::make_unique<DscSourceResource>(FullName()),\r\n            std::make_unique<DscUserSettingsFileResource>(FullName()),\r\n            std::make_unique<DscAdminSettingsResource>(FullName()),\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n            std::make_unique<DscTestFileResource>(FullName()),\r\n            std::make_unique<DscTestJsonResource>(FullName()),\r\n#endif\r\n        });\r\n    }\r\n\r\n    std::vector<Argument> DscCommand::GetArguments() const\r\n    {\r\n        std::vector<Argument> result;\r\n\r\n        result.emplace_back(Execution::Args::Type::DscResourceFunctionManifest, Resource::String::DscResourceFunctionDescriptionManifest, ArgumentType::Flag);\r\n        result.emplace_back(GetOutputFileArgument());\r\n\r\n        return result;\r\n    }\r\n\r\n    Resource::LocString DscCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::DscCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString DscCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::DscCommandLongDescription };\r\n    }\r\n\r\n    Utility::LocIndView DscCommand::HelpLink() const\r\n    {\r\n        return \"https://aka.ms/winget-dsc-resources\"_liv;\r\n    }\r\n\r\n    void DscCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        if (context.Args.Contains(Execution::Args::Type::DscResourceFunctionManifest))\r\n        {\r\n            std::filesystem::path outputDirectory{ Utility::ConvertToUTF16(context.Args.GetArg(Execution::Args::Type::OutputFile)) };\r\n            std::filesystem::create_directories(outputDirectory);\r\n\r\n            std::string filePrefix = Utility::ToLower(DscCommandBase::ModuleName());\r\n\r\n            for (const auto& command : GetCommands())\r\n            {\r\n                DscCommandBase* commandBase = static_cast<DscCommandBase*>(command.get());\r\n\r\n                std::filesystem::path outputPath = outputDirectory;\r\n                outputPath /= std::string{ filePrefix }.append(\".\").append(commandBase->Name()).append(\".dsc.resource.json\");\r\n                commandBase->WriteManifest(context, outputPath);\r\n            }\r\n        }\r\n        else\r\n        {\r\n            OutputHelp(context.Reporter);\r\n        }\r\n    }\r\n\r\n    void DscCommand::ValidateArgumentsInternal(Execution::Args& args) const\r\n    {\r\n        if (args.Contains(Execution::Args::Type::DscResourceFunctionManifest) &&\r\n            !args.Contains(Execution::Args::Type::OutputFile))\r\n        {\r\n            throw CommandException(Resource::String::RequiredArgError(GetOutputFileArgument().Name()));\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/DscCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Command.h\"\r\n#include <winget/ExperimentalFeature.h>\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    struct DscCommand final : public Command\r\n    {\r\n        DscCommand(std::string_view parent);\r\n\r\n        static constexpr std::string_view StaticName() { return \"dscv3\"sv; };\r\n\r\n        std::vector<std::unique_ptr<Command>> GetCommands() const override;\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n        void ValidateArgumentsInternal(Execution::Args& args) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/DscCommandBase.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"DscCommandBase.h\"\r\n#include \"DscCommand.h\"\r\n#include <winget/Runtime.h>\r\n#include <winget/StdErrLogger.h>\r\n\r\n#define WINGET_DSC_FUNCTION_FOREACH(_macro_) \\\r\n    _macro_(Get); \\\r\n    _macro_(Set); \\\r\n    _macro_(WhatIf); \\\r\n    _macro_(Test); \\\r\n    _macro_(Delete); \\\r\n    _macro_(Export); \\\r\n    _macro_(Validate); \\\r\n    _macro_(Resolve); \\\r\n    _macro_(Adapter); \\\r\n    _macro_(Schema); \\\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    namespace\r\n    {\r\n        std::string GetFunctionManifestString(DscFunctions function)\r\n        {\r\n            THROW_HR_IF(E_INVALIDARG, !WI_IsSingleFlagSet(function));\r\n\r\n            switch (function)\r\n            {\r\n            case DscFunctions::Get: return \"get\";\r\n            case DscFunctions::Set: return \"set\";\r\n            case DscFunctions::WhatIf: return \"whatIf\";\r\n            case DscFunctions::Test: return \"test\";\r\n            case DscFunctions::Delete: return \"delete\";\r\n            case DscFunctions::Export: return \"export\";\r\n            case DscFunctions::Validate: return \"validate\";\r\n            case DscFunctions::Resolve: return \"resolve\";\r\n            case DscFunctions::Adapter: return \"adapter\";\r\n            case DscFunctions::Schema: return \"schema\";\r\n            }\r\n\r\n            THROW_HR(E_NOTIMPL);\r\n        }\r\n\r\n        std::string GetFunctionArgumentString(DscFunctions function)\r\n        {\r\n            return std::string{ \"--\" } + GetFunctionManifestString(function);\r\n        }\r\n\r\n        bool FunctionSpecifiesInput(DscFunctions function)\r\n        {\r\n            switch (function)\r\n            {\r\n            case DscFunctions::Get:\r\n            case DscFunctions::Set:\r\n            case DscFunctions::WhatIf:\r\n            case DscFunctions::Test:\r\n            case DscFunctions::Delete:\r\n            case DscFunctions::Export:\r\n            case DscFunctions::Validate:\r\n            case DscFunctions::Resolve:\r\n                return true;\r\n            }\r\n\r\n            return false;\r\n        }\r\n\r\n        bool FunctionIsSetLike(DscFunctions function)\r\n        {\r\n            switch (function)\r\n            {\r\n            case DscFunctions::Set:\r\n            case DscFunctions::WhatIf:\r\n                return true;\r\n            }\r\n\r\n            return false;\r\n        }\r\n\r\n        bool FunctionSpecifiesReturn(DscFunctions function)\r\n        {\r\n            switch (function)\r\n            {\r\n            case DscFunctions::Set:\r\n            case DscFunctions::WhatIf:\r\n            case DscFunctions::Test:\r\n                return true;\r\n            }\r\n\r\n            return false;\r\n        }\r\n\r\n        std::optional<std::string> GetReturnType(DscFunctionModifiers modifiers)\r\n        {\r\n            if (WI_IsFlagSet(modifiers, DscFunctionModifiers::ReturnsStateAndDiff))\r\n            {\r\n                return \"stateAndDiff\";\r\n            }\r\n\r\n            if (WI_IsFlagSet(modifiers, DscFunctionModifiers::ReturnsState))\r\n            {\r\n                return \"state\";\r\n            }\r\n\r\n            return std::nullopt;\r\n        }\r\n\r\n        Json::Value CreateJsonDefinitionFor(std::string_view name, DscFunctions function, DscFunctionModifiers modifiers)\r\n        {\r\n            THROW_HR_IF(E_INVALIDARG, !WI_IsSingleFlagSet(function));\r\n            THROW_HR_IF(E_NOTIMPL, function == DscFunctions::Adapter);\r\n\r\n            Json::Value result{ Json::ValueType::objectValue };\r\n\r\n#ifndef USE_PROD_CLSIDS\r\n            result[\"executable\"] = \"wingetdev\";\r\n#else\r\n            result[\"executable\"] = \"winget\";\r\n#endif\r\n\r\n            Json::Value args{ Json::ValueType::arrayValue };\r\n            args.append(std::string{ DscCommand::StaticName() });\r\n            args.append(std::string{ name });\r\n            args.append(GetFunctionArgumentString(function));\r\n            result[\"args\"] = std::move(args);\r\n\r\n            if (FunctionSpecifiesInput(function))\r\n            {\r\n                result[\"input\"] = \"stdin\";\r\n            }\r\n\r\n            if (FunctionIsSetLike(function))\r\n            {\r\n                if (WI_IsFlagSet(modifiers, DscFunctionModifiers::ImplementsPretest))\r\n                {\r\n                    result[\"implementsPretest\"] = true;\r\n                }\r\n\r\n                if (WI_IsFlagSet(modifiers, DscFunctionModifiers::HandlesExist))\r\n                {\r\n                    result[\"handlesExist\"] = true;\r\n                }\r\n            }\r\n\r\n            if (FunctionSpecifiesReturn(function))\r\n            {\r\n                std::optional<std::string> returnType = GetReturnType(modifiers);\r\n\r\n                if (returnType)\r\n                {\r\n                    result[\"return\"] = returnType.value();\r\n                }\r\n            }\r\n\r\n            if (function == DscFunctions::Schema)\r\n            {\r\n                Json::Value newResult{ Json::ValueType::objectValue };\r\n                newResult[\"command\"] = std::move(result);\r\n                result = std::move(newResult);\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n\r\n    DscCommandBase::DscCommandBase(std::string_view parent, std::string_view resourceName, DscResourceKind kind, DscFunctions functions, DscFunctionModifiers modifiers) :\r\n        Command(resourceName, parent, CommandOutputFlags::IgnoreSettingsWarnings), m_kind(kind), m_functions(functions), m_modifiers(modifiers)\r\n    {\r\n        // Limits on current implementation\r\n        THROW_HR_IF(E_NOTIMPL, kind != DscResourceKind::Resource);\r\n        THROW_HR_IF(E_NOTIMPL, WI_IsFlagSet(functions, DscFunctions::Adapter));\r\n    }\r\n\r\n    std::vector<Argument> DscCommandBase::GetArguments() const\r\n    {\r\n        std::vector<Argument> result;\r\n\r\n#define WINGET_DSC_FUNCTION_ARGUMENT(_function_) \\\r\n        if (WI_IsFlagSet(m_functions, DscFunctions::_function_)) \\\r\n        { \\\r\n            result.emplace_back(Execution::Args::Type::DscResourceFunction ## _function_, Resource::String::DscResourceFunctionDescription ## _function_, ArgumentType::Flag); \\\r\n        }\r\n\r\n        WINGET_DSC_FUNCTION_FOREACH(WINGET_DSC_FUNCTION_ARGUMENT);\r\n\r\n#undef WINGET_DSC_FUNCTION_ARGUMENT\r\n\r\n        result.emplace_back(Execution::Args::Type::DscResourceFunctionManifest, Resource::String::DscResourceFunctionDescriptionManifest, ArgumentType::Flag);\r\n        result.emplace_back(Execution::Args::Type::OutputFile, Resource::String::OutputFileArgumentDescription, ArgumentType::Standard);\r\n\r\n        return result;\r\n    }\r\n\r\n    Utility::LocIndView DscCommandBase::HelpLink() const\r\n    {\r\n        return \"https://aka.ms/winget-dsc-resources\"_liv;\r\n    }\r\n\r\n    void DscCommandBase::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        context.Reporter.SetChannel(Execution::Reporter::Channel::Json);\r\n        Logging::StdErrLogger::Add();\r\n\r\n#define WINGET_DSC_FUNCTION_ARGUMENT(_function_) \\\r\n        if (context.Args.Contains(Execution::Args::Type::DscResourceFunction ## _function_)) \\\r\n        { \\\r\n            return ResourceFunction ## _function_(context); \\\r\n        }\r\n\r\n        WINGET_DSC_FUNCTION_FOREACH(WINGET_DSC_FUNCTION_ARGUMENT);\r\n        WINGET_DSC_FUNCTION_ARGUMENT(Manifest);\r\n\r\n#undef WINGET_DSC_FUNCTION_ARGUMENT\r\n    }\r\n\r\n#define WINGET_DSC_FUNCTION_METHOD(_function_) \\\r\n    void DscCommandBase::ResourceFunction ## _function_(Execution::Context&) const \\\r\n    { \\\r\n        THROW_HR(E_NOTIMPL); \\\r\n    } \\\r\n\r\n    WINGET_DSC_FUNCTION_FOREACH(WINGET_DSC_FUNCTION_METHOD);\r\n\r\n    void DscCommandBase::WriteManifest(Execution::Context& context, const std::filesystem::path& filePath) const\r\n    {\r\n        Json::Value json{ Json::ValueType::objectValue };\r\n\r\n        // TODO: Move to release schema when released (there should be an aka.ms link as well, but it wasn't active yet)\r\n        //json[\"$schema\"] = \"https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/v3/bundled/resource/manifest.json\";\r\n        json[\"$schema\"] = \"https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/resource/manifest.json\";\r\n        json[\"type\"] = std::string{ ModuleName() } + '/' + ResourceType();\r\n        json[\"description\"] = LongDescription().get();\r\n        json[\"version\"] = Runtime::GetClientVersion().get();\r\n\r\n        Json::Value tags{ Json::ValueType::arrayValue };\r\n        tags.append(\"WinGet\");\r\n        json[\"tags\"] = std::move(tags);\r\n\r\n#define WINGET_DSC_FUNCTION_MANIFEST(_function_) \\\r\n        if (WI_IsFlagSet(m_functions, DscFunctions::_function_)) \\\r\n        { \\\r\n            json[GetFunctionManifestString(DscFunctions::_function_)] = CreateJsonDefinitionFor(Name(), DscFunctions::_function_, m_modifiers); \\\r\n        }\r\n\r\n        WINGET_DSC_FUNCTION_FOREACH(WINGET_DSC_FUNCTION_MANIFEST);\r\n\r\n#undef WINGET_DSC_FUNCTION_MANIFEST\r\n\r\n        Json::StreamWriterBuilder writerBuilder;\r\n        writerBuilder.settings_[\"indentation\"] = \"  \";\r\n        std::string jsonString = Json::writeString(writerBuilder, json);\r\n\r\n        if (!filePath.empty())\r\n        {\r\n            std::ofstream stream{ filePath, std::ios::binary };\r\n            stream.write(jsonString.c_str(), jsonString.length());\r\n        }\r\n        else\r\n        {\r\n            context.Reporter.Json() << jsonString;\r\n        }\r\n    }\r\n\r\n    void DscCommandBase::ResourceFunctionManifest(Execution::Context& context) const\r\n    {\r\n        std::filesystem::path path;\r\n        if (context.Args.Contains(Execution::Args::Type::OutputFile))\r\n        {\r\n            path = std::filesystem::path{ Utility::ConvertToUTF16(context.Args.GetArg(Execution::Args::Type::OutputFile)) };\r\n        }\r\n        WriteManifest(context, path);\r\n    }\r\n\r\n#undef WINGET_DSC_FUNCTION_METHOD\r\n\r\n    std::optional<Json::Value> DscCommandBase::GetJsonFromInput(Execution::Context& context, bool terminateContextOnError) const\r\n    {\r\n        // Don't attempt to read from an interactive stream as this will just block\r\n        if (!context.Reporter.InputStreamIsInteractive())\r\n        {\r\n            AICLI_LOG(CLI, Verbose, << \"Reading Json from input stream...\");\r\n\r\n            Json::Value result;\r\n            Json::CharReaderBuilder builder;\r\n            Json::String errors;\r\n            if (Json::parseFromStream(builder, context.Reporter.RawInputStream(), &result, &errors))\r\n            {\r\n                AICLI_LOG(CLI, Info, << \"Json from input stream:\\n\" << Json::writeString(Json::StreamWriterBuilder{}, result));\r\n                return result;\r\n            }\r\n\r\n            AICLI_LOG(CLI, Error, << \"Failed to read input JSON: \" << errors);\r\n        }\r\n\r\n        if (terminateContextOnError)\r\n        {\r\n            AICLI_TERMINATE_CONTEXT_RETURN(APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE, std::nullopt);\r\n        }\r\n        else\r\n        {\r\n            return std::nullopt;\r\n        }\r\n    }\r\n\r\n    void DscCommandBase::WriteJsonOutputLine(Execution::Context& context, const Json::Value& value) const\r\n    {\r\n        Json::StreamWriterBuilder writerBuilder;\r\n        writerBuilder.settings_[\"indentation\"] = \"\";\r\n        writerBuilder.settings_[\"commentStyle\"] = \"None\";\r\n        writerBuilder.settings_[\"emitUTF8\"] = true;\r\n        context.Reporter.Json() << Json::writeString(writerBuilder, value) << std::endl;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/DscCommandBase.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Command.h\"\r\n#include <json/json.h>\r\n#include <optional>\r\n\r\n#ifndef USE_PROD_CLSIDS\r\n#define WINGET_DSCV3_MODULE_NAME \"Microsoft.WinGet.Dev\"\r\n#define WINGET_DSCV3_MODULE_NAME_WIDE L\"Microsoft.WinGet.Dev\"\r\n#else\r\n#define WINGET_DSCV3_MODULE_NAME \"Microsoft.WinGet\"\r\n#define WINGET_DSCV3_MODULE_NAME_WIDE L\"Microsoft.WinGet\"\r\n#endif\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    // The kind of resource that this command is implementing.\r\n    enum class DscResourceKind\r\n    {\r\n        // Standard resource\r\n        Resource,\r\n        // Group resource\r\n        Group,\r\n        // Adapter resource\r\n        Adapter,\r\n        // Import resource\r\n        Import,\r\n    };\r\n\r\n    // The functions that a DSC resource can provide.\r\n    enum class DscFunctions\r\n    {\r\n        None        = 0x000,\r\n        // Gets the current state; should always be implemented.\r\n        Get         = 0x001,\r\n        // Sets the state; should always be implemented.\r\n        Set         = 0x002,\r\n        // Produces the output of Set without modifying state.\r\n        WhatIf      = 0x004,\r\n        // Determines if the current state matches the given state.\r\n        Test        = 0x008,\r\n        // Deletes the given state.\r\n        Delete      = 0x010,\r\n        // Gets all instances of the resource.\r\n        Export      = 0x020,\r\n        // Required for a Group resource, ignored for all others.\r\n        Validate    = 0x040,\r\n        // Required for an Import resource.\r\n        Resolve     = 0x080,\r\n        // Required for an Adapter resource.\r\n        Adapter     = 0x100,\r\n        // Gets the schema for the resource's properties.\r\n        Schema      = 0x200,\r\n    };\r\n\r\n    DEFINE_ENUM_FLAG_OPERATORS(DscFunctions);\r\n\r\n    // Behavior changes for DSC functions.\r\n    enum class DscFunctionModifiers\r\n    {\r\n        None                = 0x00,\r\n        // The resource implements a check during Set (and WhatIf) to determine if already in the correct state.\r\n        // If not provided, DSC will ensure that the state is tested beforehand.\r\n        ImplementsPretest   = 0x01,\r\n        // The resource will act on the `_exist` property during Set (and WhatIf).\r\n        // If not provided, the resource should implement Delete.\r\n        HandlesExist        = 0x02,\r\n        // Functions that may return state information (set, what-if, test) return only the state.\r\n        ReturnsState        = 0x04,\r\n        // Functions that may return state information (set, what-if, test) return the state and property difference.\r\n        ReturnsStateAndDiff = 0x08,\r\n    };\r\n\r\n    DEFINE_ENUM_FLAG_OPERATORS(DscFunctionModifiers);\r\n\r\n    // Provides infrastructure for DSC commands to be implemented.\r\n    struct DscCommandBase : public Command\r\n    {\r\n        DscCommandBase(std::string_view parent, std::string_view resourceName, DscResourceKind kind, DscFunctions functions, DscFunctionModifiers modifiers);\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n        static constexpr std::string_view ModuleName()\r\n        {\r\n            return WINGET_DSCV3_MODULE_NAME;\r\n        }\r\n\r\n        // Writes the manifest for the command to the file path.\r\n        // If the path is empty, writes the manifest to the output stream.\r\n        void WriteManifest(Execution::Context& context, const std::filesystem::path& filePath) const;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n\r\n        // Gets the resource specific type name.\r\n        virtual std::string ResourceType() const = 0;\r\n\r\n        virtual void ResourceFunctionGet(Execution::Context& context) const;\r\n        virtual void ResourceFunctionSet(Execution::Context& context) const;\r\n        virtual void ResourceFunctionWhatIf(Execution::Context& context) const;\r\n        virtual void ResourceFunctionTest(Execution::Context& context) const;\r\n        virtual void ResourceFunctionDelete(Execution::Context& context) const;\r\n        virtual void ResourceFunctionExport(Execution::Context& context) const;\r\n        virtual void ResourceFunctionValidate(Execution::Context& context) const;\r\n        virtual void ResourceFunctionResolve(Execution::Context& context) const;\r\n        virtual void ResourceFunctionAdapter(Execution::Context& context) const;\r\n        virtual void ResourceFunctionSchema(Execution::Context& context) const;\r\n        virtual void ResourceFunctionManifest(Execution::Context& context) const;\r\n\r\n        // Parses a JSON object from stdin.\r\n        std::optional<Json::Value> GetJsonFromInput(Execution::Context& context, bool terminateContextOnError = true) const;\r\n\r\n        // Writes the value to the context output.\r\n        void WriteJsonOutputLine(Execution::Context& context, const Json::Value& value) const;\r\n\r\n    private:\r\n        DscResourceKind m_kind = DscResourceKind::Resource;\r\n        DscFunctions m_functions = DscFunctions::None;\r\n        DscFunctionModifiers m_modifiers = DscFunctionModifiers::None;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/DscComposableObject.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"DscComposableObject.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    namespace\r\n    {\r\n        std::string GetTypeString(Json::ValueType type)\r\n        {\r\n            switch (type)\r\n            {\r\n            case Json::nullValue:\r\n                return \"null\";\r\n            case Json::intValue:\r\n            case Json::uintValue:\r\n            case Json::realValue:\r\n                return \"number\";\r\n            case Json::stringValue:\r\n                return \"string\";\r\n            case Json::booleanValue:\r\n                return \"boolean\";\r\n            case Json::arrayValue:\r\n                return \"array\";\r\n            case Json::objectValue:\r\n                return \"object\";\r\n            default:\r\n                THROW_HR(E_UNEXPECTED);\r\n            }\r\n        }\r\n    }\r\n\r\n    namespace details\r\n    {\r\n        const Json::Value* GetProperty(const Json::Value& object, std::string_view name)\r\n        {\r\n            return object.find(name.data(), name.data() + name.length());\r\n        }\r\n\r\n        void AddProperty(Json::Value& object, std::string_view name, std::optional<Json::Value>&& value)\r\n        {\r\n            if (value)\r\n            {\r\n                object[std::string{ name }] = std::move(value).value();\r\n            }\r\n        }\r\n\r\n        Json::Value GetBaseSchema(const std::string& title)\r\n        {\r\n            Json::Value result{ Json::ValueType::objectValue };\r\n\r\n            result[\"$schema\"] = \"http://json-schema.org/draft-07/schema#\";\r\n            result[\"title\"] = title;\r\n            result[\"type\"] = \"object\";\r\n            result[\"additionalProperties\"] = false;\r\n\r\n            return result;\r\n        }\r\n\r\n        void AddPropertySchema(\r\n            Json::Value& object,\r\n            std::string_view name,\r\n            DscComposablePropertyFlag flags,\r\n            Json::ValueType type,\r\n            std::string_view description,\r\n            const std::vector<std::string>& enumValues,\r\n            const std::optional<std::string>& defaultValue)\r\n        {\r\n            Json::Value& propertiesObject = object[\"properties\"];\r\n\r\n            if (propertiesObject.isNull())\r\n            {\r\n                propertiesObject = Json::Value{ Json::ValueType::objectValue };\r\n            }\r\n\r\n            std::string nameString{ name };\r\n\r\n            Json::Value property{ Json::ValueType::objectValue };\r\n\r\n            if (type != Json::ValueType::objectValue)\r\n            {\r\n                property[\"type\"] = GetTypeString(type);\r\n            }\r\n\r\n            property[\"description\"] = std::string{ description };\r\n\r\n            if (!enumValues.empty())\r\n            {\r\n                Json::Value enumArray{ Json::ValueType::arrayValue };\r\n\r\n                for (const std::string& enumValue : enumValues)\r\n                {\r\n                    enumArray.append(enumValue);\r\n                }\r\n\r\n                property[\"enum\"] = std::move(enumArray);\r\n            }\r\n\r\n            if (defaultValue)\r\n            {\r\n                property[\"default\"] = defaultValue.value();\r\n            }\r\n\r\n            propertiesObject[nameString] = std::move(property);\r\n\r\n            if (WI_IsFlagSet(flags, DscComposablePropertyFlag::Required))\r\n            {\r\n                Json::Value& requiredArray = object[\"required\"];\r\n\r\n                if (requiredArray.isNull())\r\n                {\r\n                    requiredArray = Json::Value{ Json::ValueType::arrayValue };\r\n                }\r\n\r\n                requiredArray.append(nameString);\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/DscComposableObject.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerErrors.h>\r\n#include <AppInstallerLanguageUtilities.h>\r\n#include <AppInstallerLogging.h>\r\n#include <winget/LocIndependent.h>\r\n#include \"Resources.h\"\r\n#include <json/json.h>\r\n#include <optional>\r\n#include <string>\r\n#include <vector>\r\n\r\nusing namespace std::string_view_literals;\r\nusing namespace AppInstaller::Utility::literals;\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    // Flags that define how to treat properties.\r\n    enum DscComposablePropertyFlag\r\n    {\r\n        None = 0x0,\r\n        Required = 0x1,\r\n        CopyToOutput = 0x2,\r\n    };\r\n\r\n    DEFINE_ENUM_FLAG_OPERATORS(DscComposablePropertyFlag);\r\n\r\n    namespace details\r\n    {\r\n        // Gets a property or null if not present.\r\n        const Json::Value* GetProperty(const Json::Value& object, std::string_view name);\r\n\r\n        // Adds the given property and value to the object, if provided.\r\n        void AddProperty(Json::Value& object, std::string_view name, std::optional<Json::Value>&& value);\r\n\r\n        // Gets the default schema object.\r\n        Json::Value GetBaseSchema(const std::string& title);\r\n\r\n        // Adds a property to the schema object.\r\n        void AddPropertySchema(\r\n            Json::Value& object,\r\n            std::string_view name,\r\n            DscComposablePropertyFlag flags,\r\n            Json::ValueType type,\r\n            std::string_view description,\r\n            const std::vector<std::string>& enumValues,\r\n            const std::optional<std::string>& defaultValue);\r\n    }\r\n\r\n    template <typename PropertyType>\r\n    struct GetJsonTypeValue\r\n    {\r\n        static_assert(false, \"Implement for this type.\");\r\n    };\r\n\r\n    template <>\r\n    struct GetJsonTypeValue<bool>\r\n    {\r\n        static bool Get(const Json::Value& value)\r\n        {\r\n            return value.asBool();\r\n        }\r\n\r\n        static Json::ValueType SchemaType()\r\n        {\r\n            return Json::ValueType::booleanValue;\r\n        }\r\n    };\r\n\r\n    template <>\r\n    struct GetJsonTypeValue<std::string>\r\n    {\r\n        static std::string Get(const Json::Value& value)\r\n        {\r\n            return value.asString();\r\n        }\r\n\r\n        static Json::ValueType SchemaType()\r\n        {\r\n            return Json::ValueType::stringValue;\r\n        }\r\n    };\r\n\r\n    template <>\r\n    struct GetJsonTypeValue<int32_t>\r\n    {\r\n        static int32_t Get(const Json::Value& value)\r\n        {\r\n            return value.asInt();\r\n        }\r\n\r\n        static Json::ValueType SchemaType()\r\n        {\r\n            return Json::ValueType::intValue;\r\n        }\r\n    };\r\n\r\n    template <>\r\n    struct GetJsonTypeValue<Json::Value>\r\n    {\r\n        static Json::Value Get(const Json::Value& value)\r\n        {\r\n            return value;\r\n        }\r\n\r\n        static Json::ValueType SchemaType()\r\n        {\r\n            return Json::ValueType::objectValue;\r\n        }\r\n    };\r\n\r\n    // Template useful for composing objects for DSC resources.\r\n    // Properties should be of the shape:\r\n    //\r\n    // struct Property\r\n    // {\r\n    //      using PropertyType = { bool, std::string };\r\n    //      static std::string_view Name();\r\n    //      static void FromJson(Property*, const Json::Value*);\r\n    //      static std::optional<Json::Value> ToJson(const Property*);\r\n    //\r\n    //      const PropertyType& PROPERTY_NAME() const;\r\n    //      void PROPERTY_NAME(const PropertyType&);\r\n    // }\r\n    template <typename... Property>\r\n    struct DscComposableObject : public Property...\r\n    {\r\n        DscComposableObject() = default;\r\n\r\n        DscComposableObject(const std::optional<Json::Value>& input, bool ignoreFieldRequirements = false)\r\n        {\r\n            THROW_HR_IF(E_POINTER, !input && !ignoreFieldRequirements);\r\n            if (input)\r\n            {\r\n                FromJson(input.value(), ignoreFieldRequirements);\r\n            }\r\n        }\r\n\r\n        // Read values for each property\r\n        void FromJson(const Json::Value& input, bool ignoreFieldRequirements = false)\r\n        {\r\n            (FoldHelper{}, ..., Property::FromJson(this, details::GetProperty(input, Property::Name()), ignoreFieldRequirements));\r\n        }\r\n\r\n        // Populate JSON object with properties.\r\n        Json::Value ToJson()\r\n        {\r\n            Json::Value result{ Json::ValueType::objectValue };\r\n            (FoldHelper{}, ..., details::AddProperty(result, Property::Name(), Property::ToJson(this)));\r\n            return result;\r\n        }\r\n\r\n        // Copies the appropriate values to a new object for output.\r\n        DscComposableObject CopyForOutput() const\r\n        {\r\n            DscComposableObject result;\r\n            (FoldHelper{}, ..., Property::CopyForOutput(this, &result));\r\n            return result;\r\n        }\r\n\r\n        // Get the JSON Schema for this object\r\n        static Json::Value Schema(const std::string& title)\r\n        {\r\n            Json::Value result = details::GetBaseSchema(title);\r\n            (FoldHelper{}, ..., details::AddPropertySchema(result, Property::Name(), Property::Flags, GetJsonTypeValue<typename Property::PropertyType>::SchemaType(), Property::Description(), Property::EnumValues(), Property::Default()));\r\n            return result;\r\n        }\r\n    };\r\n\r\n    template <typename Derived, typename PropertyTypeT, DscComposablePropertyFlag PropertyFlags>\r\n    struct DscComposableProperty\r\n    {\r\n        using PropertyType = PropertyTypeT;\r\n        static constexpr DscComposablePropertyFlag Flags = PropertyFlags;\r\n\r\n        static void FromJson(Derived* self, const Json::Value* value, bool ignoreFieldRequirements)\r\n        {\r\n            if (value && !value->isNull())\r\n            {\r\n                self->m_value = GetJsonTypeValue<PropertyType>::Get(*value);\r\n            }\r\n            else\r\n            {\r\n                if (!ignoreFieldRequirements && WI_IsFlagSet(PropertyFlags, DscComposablePropertyFlag::Required))\r\n                {\r\n                    THROW_HR_MSG(WINGET_CONFIG_ERROR_MISSING_FIELD, \"Required property `%hs` not provided.\", Derived::Name().data());\r\n                }\r\n                else\r\n                {\r\n                    self->m_value = std::nullopt;\r\n                }\r\n            }\r\n        }\r\n\r\n        static std::optional<Json::Value> ToJson(const Derived* self)\r\n        {\r\n            if constexpr (WI_IsFlagSet(PropertyFlags, DscComposablePropertyFlag::Required))\r\n            {\r\n                THROW_HR_IF(WINGET_CONFIG_ERROR_MISSING_FIELD, !self->m_value);\r\n                return self->m_value.value();\r\n            }\r\n            else\r\n            {\r\n                return self->m_value ? std::optional<Json::Value>{ self->m_value.value() } : std::nullopt;\r\n            }\r\n        }\r\n\r\n        static void CopyForOutput(const Derived* self, Derived* other)\r\n        {\r\n            if constexpr (WI_IsFlagSet(PropertyFlags, DscComposablePropertyFlag::CopyToOutput))\r\n            {\r\n                other->m_value = self->m_value;\r\n            }\r\n        }\r\n\r\n    protected:\r\n        std::optional<PropertyType> m_value;\r\n    };\r\n\r\n#define WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY_IMPL_START(_property_type_, _value_type_, _property_name_, _json_name_, _flags_, _description_, _enum_vals_, _default_) \\\r\n    struct _property_type_ : public DscComposableProperty<_property_type_, _value_type_, _flags_> \\\r\n    { \\\r\n        static std::string_view Name() { return _json_name_; } \\\r\n        static Resource::LocString Description() { return _description_; } \\\r\n        static std::vector<std::string> EnumValues() { return std::vector<std::string> _enum_vals_; } \\\r\n        static std::optional<std::string> Default() { return _default_; } \\\r\n        std::optional<PropertyType>& _property_name_() { return m_value; } \\\r\n        const std::optional<PropertyType>& _property_name_() const { return m_value; } \\\r\n        void _property_name_(std::optional<PropertyType> value) { m_value = std::move(value); } \\\r\n\r\n#define WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY_IMPL(_property_type_, _value_type_, _property_name_, _json_name_, _flags_, _description_, _enum_vals_, _default_) \\\r\n    WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY_IMPL_START(_property_type_, _value_type_, _property_name_, _json_name_, _flags_, _description_, _enum_vals_, _default_) \\\r\n    };\r\n\r\n#define WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY(_property_type_, _value_type_, _property_name_, _json_name_, _description_) \\\r\n    WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY_IMPL(_property_type_, _value_type_, _property_name_, _json_name_, DscComposablePropertyFlag::None, _description_, {}, {})\r\n\r\n#define WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY_FLAGS(_property_type_, _value_type_, _property_name_, _json_name_, _flags_, _description_) \\\r\n    WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY_IMPL(_property_type_, _value_type_, _property_name_, _json_name_, _flags_, _description_, {}, {})\r\n\r\n#define WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY_DEFAULT(_property_type_, _value_type_, _property_name_, _json_name_, _description_, _default_) \\\r\n    WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY_IMPL(_property_type_, _value_type_, _property_name_, _json_name_, DscComposablePropertyFlag::None, _description_, {}, _default_)\r\n\r\n#define WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY_ENUM(_property_type_, _value_type_, _property_name_, _json_name_, _description_, _enum_vals_, _default_) \\\r\n    WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY_IMPL(_property_type_, _value_type_, _property_name_, _json_name_, DscComposablePropertyFlag::None, _description_, _enum_vals_, _default_)\r\n\r\n#define WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY_ENUM_FLAGS(_property_type_, _value_type_, _property_name_, _json_name_, _flags_, _description_, _enum_vals_, _default_) \\\r\n    WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY_IMPL(_property_type_, _value_type_, _property_name_, _json_name_, _flags_, _description_, _enum_vals_, _default_)\r\n\r\n    WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY_IMPL_START(StandardExistProperty, bool, Exist, \"_exist\", DscComposablePropertyFlag::None, Resource::String::DscResourcePropertyDescriptionExist, {}, {})\r\n        bool ShouldExist() const { return m_value.value_or(true); }\r\n    };\r\n\r\n    WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY(StandardInDesiredStateProperty, bool, InDesiredState, \"_inDesiredState\", Resource::String::DscResourcePropertyDescriptionInDesiredState);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/DscPackageResource.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"DscPackageResource.h\"\r\n#include \"DscComposableObject.h\"\r\n#include \"Resources.h\"\r\n#include \"Workflows/WorkflowBase.h\"\r\n#include \"Workflows/ConfigurationFlow.h\"\r\n#include \"Workflows/InstallFlow.h\"\r\n#include \"Workflows/UninstallFlow.h\"\r\n#include \"Workflows/UpdateFlow.h\"\r\n#include <winget/PackageVersionSelection.h>\r\n\r\nusing namespace AppInstaller::Utility::literals;\r\nusing namespace AppInstaller::Repository;\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    namespace\r\n    {\r\n        WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY_FLAGS(IdProperty, std::string, Identifier, \"id\", DscComposablePropertyFlag::Required | DscComposablePropertyFlag::CopyToOutput, Resource::String::DscResourcePropertyDescriptionPackageId);\r\n        WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY_FLAGS(SourceProperty, std::string, Source, \"source\", DscComposablePropertyFlag::CopyToOutput, Resource::String::DscResourcePropertyDescriptionPackageSource);\r\n        WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY(VersionProperty, std::string, Version, \"version\", Resource::String::DscResourcePropertyDescriptionPackageVersion);\r\n        WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY_ENUM(MatchOptionProperty, std::string, MatchOption, \"matchOption\", Resource::String::DscResourcePropertyDescriptionPackageMatchOption, ({ \"equals\", \"equalsCaseInsensitive\", \"startsWithCaseInsensitive\", \"containsCaseInsensitive\" }), \"equalsCaseInsensitive\");\r\n        WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY_DEFAULT(UseLatestProperty, bool, UseLatest, \"useLatest\", Resource::String::DscResourcePropertyDescriptionPackageUseLatest, \"false\");\r\n        WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY_ENUM(InstallModeProperty, std::string, InstallMode, \"installMode\", Resource::String::DscResourcePropertyDescriptionPackageInstallMode, ({ \"default\", \"silent\", \"interactive\" }), \"silent\");\r\n        WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY(AcceptAgreementsProperty, bool, AcceptAgreements, \"acceptAgreements\", Resource::String::DscResourcePropertyDescriptionAcceptAgreements);\r\n\r\n        // TODO: To support Scope on this resource:\r\n        //  1. Change the installed source to pull in all package info for both scopes by default\r\n        //  2. Change the installed source open in workflows to always open for everything, regardless of scope\r\n        //  3. Improve correlation handling if needed for cross-scope package installations\r\n        //  4. Update the test EXE installer to handle being installed for both scopes\r\n        using PackageResourceObject = DscComposableObject<StandardExistProperty, StandardInDesiredStateProperty, IdProperty, SourceProperty, VersionProperty, MatchOptionProperty, UseLatestProperty, InstallModeProperty, AcceptAgreementsProperty>;\r\n\r\n        std::optional<MatchType> ToMatchType(const std::optional<std::string>& value)\r\n        {\r\n            if (!value)\r\n            {\r\n                return std::nullopt;\r\n            }\r\n\r\n            std::string lowerValue = Utility::ToLower(value.value());\r\n\r\n            if (lowerValue == \"equals\")\r\n            {\r\n                return MatchType::Exact;\r\n            }\r\n            else if (lowerValue == \"equals\"\"case\"\"insensitive\")\r\n            {\r\n                return MatchType::CaseInsensitive;\r\n            }\r\n            else if (lowerValue == \"starts\"\"with\"\"case\"\"insensitive\")\r\n            {\r\n                return MatchType::StartsWith;\r\n            }\r\n            else if (lowerValue == \"contains\"\"case\"\"insensitive\")\r\n            {\r\n                return MatchType::Substring;\r\n            }\r\n\r\n            THROW_HR(E_INVALIDARG);\r\n        }\r\n\r\n        struct PackageFunctionData\r\n        {\r\n            PackageFunctionData(Execution::Context& context, const std::optional<Json::Value>& json, bool ignoreFieldRequirements = false) :\r\n                Input(json, ignoreFieldRequirements),\r\n                ParentContext(context)\r\n            {\r\n                Reset();\r\n            }\r\n\r\n            const PackageResourceObject Input;\r\n            PackageResourceObject Output;\r\n            Execution::Context& ParentContext;\r\n            std::unique_ptr<Execution::Context> SubContext;\r\n\r\n            // Reset the state that is modified by Get\r\n            void Reset()\r\n            {\r\n                Output = Input.CopyForOutput();\r\n\r\n                SubContext = ParentContext.CreateSubContext();\r\n                SubContext->SetFlags(Execution::ContextFlag::DisableInteractivity);\r\n\r\n                if (Input.AcceptAgreements().value_or(false))\r\n                {\r\n                    SubContext->Args.AddArg(Execution::Args::Type::AcceptSourceAgreements);\r\n                    SubContext->Args.AddArg(Execution::Args::Type::AcceptPackageAgreements);\r\n                }\r\n            }\r\n\r\n            void PrepareSubContextInputs()\r\n            {\r\n                if (Input.Source())\r\n                {\r\n                    SubContext->Args.AddArg(Execution::Args::Type::Source, Input.Source().value());\r\n                }\r\n            }\r\n\r\n            // Fills the Output object with the current state\r\n            bool Get()\r\n            {\r\n                PrepareSubContextInputs();\r\n\r\n                *SubContext <<\r\n                    Workflow::ReportExecutionStage(Workflow::ExecutionStage::Discovery) <<\r\n                    Workflow::OpenSource() <<\r\n                    Workflow::OpenCompositeSource(Workflow::DetermineInstalledSource(*SubContext), false, CompositeSearchBehavior::AllPackages);\r\n\r\n                if (SubContext->IsTerminated())\r\n                {\r\n                    ParentContext.Terminate(SubContext->GetTerminationHR());\r\n                    return false;\r\n                }\r\n\r\n                // Do a manual search of the now opened source\r\n                Source& source = SubContext->Get<Execution::Data::Source>();\r\n                MatchType matchType = ToMatchType(Input.MatchOption()).value_or(MatchType::CaseInsensitive);\r\n\r\n                SearchRequest request;\r\n                request.Filters.emplace_back(PackageMatchFilter(PackageMatchField::Id, matchType, Input.Identifier().value()));\r\n\r\n                SearchResult result = source.Search(request);\r\n                SubContext->Add<Execution::Data::SearchResult>(result);\r\n\r\n                if (result.Matches.empty())\r\n                {\r\n                    Output.Exist(false);\r\n                }\r\n                else if (result.Matches.size() > 1)\r\n                {\r\n                    AICLI_LOG(Config, Warning, << \"Found \" << result.Matches.size() << \" matches when searching for '\" << Input.Identifier().value() << \"'\");\r\n                    Output.Exist(false);\r\n                }\r\n                else\r\n                {\r\n                    auto& package = result.Matches.front().Package;\r\n                    SubContext->Add<Execution::Data::Package>(package);\r\n\r\n                    auto installedPackage = package->GetInstalled();\r\n\r\n                    // Fill Output and SubContext\r\n                    Output.Exist(static_cast<bool>(installedPackage));\r\n                    Output.Identifier(package->GetProperty(PackageProperty::Id));\r\n\r\n                    if (installedPackage)\r\n                    {\r\n                        auto versionKeys = installedPackage->GetVersionKeys();\r\n                        AICLI_LOG(CLI, Verbose, << \"Package::Get found \" << versionKeys.size() << \" installed versions\");\r\n\r\n                        std::shared_ptr<Repository::IPackageVersion> installedVersion;\r\n\r\n                        // Find the specific version provided if possible\r\n                        if (Input.Version())\r\n                        {\r\n                            Utility::Version inputVersion{ Input.Version().value() };\r\n\r\n                            for (const auto& key : versionKeys)\r\n                            {\r\n                                if (inputVersion == Utility::Version{ key.Version })\r\n                                {\r\n                                    installedVersion = installedPackage->GetVersion(key);\r\n                                    break;\r\n                                }\r\n                            }\r\n                        }\r\n\r\n                        if (!installedVersion)\r\n                        {\r\n                            installedVersion = installedPackage->GetLatestVersion();\r\n                        }\r\n\r\n                        if (installedVersion)\r\n                        {\r\n                            Output.Version(installedVersion->GetProperty(PackageVersionProperty::Version));\r\n                        }\r\n\r\n                        auto data = Repository::GetLatestApplicableVersion(package);\r\n                        Output.UseLatest(!data.UpdateAvailable);\r\n                    }\r\n                }\r\n\r\n                AICLI_LOG(CLI, Verbose, << \"Package::Get found:\\n\" << Json::writeString(Json::StreamWriterBuilder{}, Output.ToJson()));\r\n                return true;\r\n            }\r\n\r\n            void Uninstall()\r\n            {\r\n                AICLI_LOG(CLI, Verbose, << \"Package::Uninstall invoked\");\r\n\r\n                if (Input.Version())\r\n                {\r\n                    SubContext->Args.AddArg(Execution::Args::Type::TargetVersion, Input.Version().value());\r\n                }\r\n                else\r\n                {\r\n                    SubContext->Args.AddArg(Execution::Args::Type::AllVersions);\r\n                }\r\n\r\n                *SubContext <<\r\n                    Workflow::UninstallSinglePackage;\r\n\r\n                if (SubContext->IsTerminated())\r\n                {\r\n                    ParentContext.Terminate(SubContext->GetTerminationHR());\r\n                    return;\r\n                }\r\n\r\n                Output.Exist(false);\r\n                Output.Version(std::nullopt);\r\n                Output.UseLatest(std::nullopt);\r\n            }\r\n\r\n            void Install(bool allowDowngrade = false)\r\n            {\r\n                AICLI_LOG(CLI, Verbose, << \"Package::Install invoked\");\r\n\r\n                if (Input.Version())\r\n                {\r\n                    SubContext->Args.AddArg(Execution::Args::Type::Version, Input.Version().value());\r\n                }\r\n\r\n                *SubContext <<\r\n                    Workflow::SelectSinglePackageVersionForInstallOrUpgrade(Workflow::OperationType::Install, allowDowngrade) <<\r\n                    Workflow::InstallSinglePackage;\r\n\r\n                if (SubContext->IsTerminated())\r\n                {\r\n                    ParentContext.Terminate(SubContext->GetTerminationHR());\r\n                    return;\r\n                }\r\n\r\n                Output.Exist(true);\r\n\r\n                Output.Version(std::nullopt);\r\n                if (SubContext->Contains(Execution::Data::PackageVersion))\r\n                {\r\n                    const auto& packageVersion = SubContext->Get<Execution::Data::PackageVersion>();\r\n                    if (packageVersion)\r\n                    {\r\n                        Output.Version(packageVersion->GetProperty(Repository::PackageVersionProperty::Version));\r\n                    }\r\n                }\r\n\r\n                Output.UseLatest(std::nullopt);\r\n            }\r\n\r\n            void Reinstall()\r\n            {\r\n                AICLI_LOG(CLI, Verbose, << \"Package::Reinstall invoked\");\r\n\r\n                SubContext->Args.AddArg(Execution::Args::Type::UninstallPrevious);\r\n\r\n                Install(true);\r\n            }\r\n\r\n            // Determines if the current Output values match the Input values state.\r\n            bool Test()\r\n            {\r\n                // Need to populate Output before calling\r\n                THROW_HR_IF(E_UNEXPECTED, !Output.Exist().has_value());\r\n\r\n                if (Input.ShouldExist())\r\n                {\r\n                    if (Output.Exist().value())\r\n                    {\r\n                        AICLI_LOG(CLI, Verbose, << \"Package::Test needed to inspect these properties: Version(\" << TestVersion() << \"), Latest(\" << TestLatest() << \")\");\r\n                        return TestVersion() && TestLatest();\r\n                    }\r\n                    else\r\n                    {\r\n                        AICLI_LOG(CLI, Verbose, << \"Package::Test was false because the package was not installed\");\r\n                        return false;\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(CLI, Verbose, << \"Package::Test desired the package to not exist, and it \" << (Output.Exist().value() ? \"did\" : \"did not\"));\r\n                    return !Output.Exist().value();\r\n                }\r\n            }\r\n\r\n            Json::Value DiffJson()\r\n            {\r\n                // Need to populate Output before calling\r\n                THROW_HR_IF(E_UNEXPECTED, !Output.Exist().has_value());\r\n\r\n                Json::Value result{ Json::ValueType::arrayValue };\r\n\r\n                if (Input.ShouldExist() != Output.Exist().value())\r\n                {\r\n                    result.append(std::string{ StandardExistProperty::Name() });\r\n                }\r\n                else\r\n                {\r\n                    if (!TestVersion())\r\n                    {\r\n                        result.append(std::string{ VersionProperty::Name() });\r\n                    }\r\n\r\n                    if (!TestLatest())\r\n                    {\r\n                        result.append(std::string{ UseLatestProperty::Name() });\r\n                    }\r\n                }\r\n\r\n                return result;\r\n            }\r\n\r\n            bool TestVersion()\r\n            {\r\n                if (Input.Version())\r\n                {\r\n                    if (Output.Version())\r\n                    {\r\n                        return Utility::Version{ Input.Version().value() } == Utility::Version{ Output.Version().value() };\r\n                    }\r\n                    else\r\n                    {\r\n                        return false;\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    return true;\r\n                }\r\n            }\r\n\r\n            bool TestLatest()\r\n            {\r\n                if (Input.UseLatest() && Input.UseLatest().value())\r\n                {\r\n                    if (Output.UseLatest())\r\n                    {\r\n                        return Output.UseLatest().value();\r\n                    }\r\n                    else\r\n                    {\r\n                        return false;\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    return true;\r\n                }\r\n            }\r\n        };\r\n    }\r\n\r\n    DscPackageResource::DscPackageResource(std::string_view parent) :\r\n        DscCommandBase(parent, \"package\", DscResourceKind::Resource,\r\n            DscFunctions::Get | DscFunctions::Set | DscFunctions::Test | DscFunctions::Export | DscFunctions::Schema,\r\n            DscFunctionModifiers::ImplementsPretest | DscFunctionModifiers::HandlesExist | DscFunctionModifiers::ReturnsStateAndDiff)\r\n    {\r\n    }\r\n\r\n    Resource::LocString DscPackageResource::ShortDescription() const\r\n    {\r\n        return Resource::String::DscPackageResourceShortDescription;\r\n    }\r\n\r\n    Resource::LocString DscPackageResource::LongDescription() const\r\n    {\r\n        return Resource::String::DscPackageResourceLongDescription;\r\n    }\r\n\r\n    std::string DscPackageResource::ResourceType() const\r\n    {\r\n        return \"Package\";\r\n    }\r\n\r\n    void DscPackageResource::ResourceFunctionGet(Execution::Context& context) const\r\n    {\r\n        if (auto json = GetJsonFromInput(context))\r\n        {\r\n            PackageFunctionData data{ context, json };\r\n\r\n            if (!data.Get())\r\n            {\r\n                return;\r\n            }\r\n\r\n            WriteJsonOutputLine(context, data.Output.ToJson());\r\n        }\r\n    }\r\n\r\n    void DscPackageResource::ResourceFunctionSet(Execution::Context& context) const\r\n    {\r\n        if (auto json = GetJsonFromInput(context))\r\n        {\r\n            PackageFunctionData data{ context, json };\r\n\r\n            if (!data.Get())\r\n            {\r\n                return;\r\n            }\r\n\r\n            // Capture the diff before updating the output\r\n            auto diff = data.DiffJson();\r\n\r\n            if (!data.Test())\r\n            {\r\n                if (data.Input.ShouldExist())\r\n                {\r\n                    if (data.Output.Exist().value())\r\n                    {\r\n                        if (!data.TestLatest())\r\n                        {\r\n                            // Install will swap to update flow\r\n                            AICLI_LOG(CLI, Info, << \"Installing package to update to latest\");\r\n                            data.Install();\r\n                        }\r\n                        else // (!data.TestVersion())\r\n                        {\r\n                            Utility::Version inputVersion{ data.Input.Version().value() };\r\n                            Utility::Version outputVersion{ data.Output.Version().value() };\r\n\r\n                            if (outputVersion < inputVersion)\r\n                            {\r\n                                // Install will swap to update flow\r\n                                AICLI_LOG(CLI, Info, << \"Installing package to update to desired version\");\r\n                                data.Install();\r\n                            }\r\n                            else\r\n                            {\r\n                                AICLI_LOG(CLI, Info, << \"Reinstalling package to downgrade to desired version\");\r\n                                data.Reinstall();\r\n                            }\r\n                        }\r\n                    }\r\n                    else\r\n                    {\r\n                        AICLI_LOG(CLI, Info, << \"Installing package as it was not found\");\r\n                        data.Install();\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(CLI, Info, << \"Uninstalling package as desired\");\r\n                    data.Uninstall();\r\n                }\r\n\r\n                if (data.SubContext->IsTerminated())\r\n                {\r\n                    return;\r\n                }\r\n            }\r\n\r\n            WriteJsonOutputLine(context, data.Output.ToJson());\r\n            WriteJsonOutputLine(context, diff);\r\n        }\r\n    }\r\n\r\n    void DscPackageResource::ResourceFunctionTest(Execution::Context& context) const\r\n    {\r\n        if (auto json = GetJsonFromInput(context))\r\n        {\r\n            PackageFunctionData data{ context, json };\r\n\r\n            if (!data.Get())\r\n            {\r\n                return;\r\n            }\r\n\r\n            data.Output.InDesiredState(data.Test());\r\n\r\n            WriteJsonOutputLine(context, data.Output.ToJson());\r\n            WriteJsonOutputLine(context, data.DiffJson());\r\n        }\r\n    }\r\n\r\n    void DscPackageResource::ResourceFunctionExport(Execution::Context& context) const\r\n    {\r\n        auto json = GetJsonFromInput(context, false);\r\n        PackageFunctionData data{ context, json, true };\r\n\r\n        data.PrepareSubContextInputs();\r\n\r\n        if (!data.Input.UseLatest().value_or(true))\r\n        {\r\n            data.SubContext->Args.AddArg(Execution::Args::Type::IncludeVersions);\r\n        }\r\n\r\n        data.SubContext->Args.AddArg(Execution::Args::Type::ConfigurationExportAll);\r\n\r\n        *data.SubContext <<\r\n            Workflow::SearchSourceForPackageExport;\r\n\r\n        if (data.SubContext->IsTerminated())\r\n        {\r\n            context.Terminate(data.SubContext->GetTerminationHR());\r\n            return;\r\n        }\r\n\r\n        const auto& packageCollection = data.SubContext->Get<Execution::Data::PackageCollection>();\r\n\r\n        for (const auto& source : packageCollection.Sources)\r\n        {\r\n            for (const auto& package : source.Packages)\r\n            {\r\n                PackageResourceObject output;\r\n\r\n                output.Identifier(package.Id);\r\n                output.Source(source.Details.Name);\r\n\r\n                if (!package.VersionAndChannel.GetVersion().IsEmpty())\r\n                {\r\n                    output.Version(package.VersionAndChannel.GetVersion().ToString());\r\n                }\r\n\r\n                // TODO: Exporting scope requires one or more of the following:\r\n                //  1. Support for \"OrUnknown\" scope variants during Set (and workflows)\r\n                //  2. Tracking scope intent as we do for some other installer properties\r\n                //  3. Checking for the availability of the current scope in the package\r\n\r\n                WriteJsonOutputLine(context, output.ToJson());\r\n            }\r\n        }\r\n    }\r\n\r\n    void DscPackageResource::ResourceFunctionSchema(Execution::Context& context) const\r\n    {\r\n        WriteJsonOutputLine(context, PackageResourceObject::Schema(ResourceType()));\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/DscPackageResource.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"DscCommandBase.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    // A resource for managing package state.\r\n    struct DscPackageResource : public DscCommandBase\r\n    {\r\n        DscPackageResource(std::string_view parent);\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n    protected:\r\n        std::string ResourceType() const override;\r\n\r\n        void ResourceFunctionGet(Execution::Context& context) const override;\r\n        void ResourceFunctionSet(Execution::Context& context) const override;\r\n        void ResourceFunctionTest(Execution::Context& context) const override;\r\n        void ResourceFunctionExport(Execution::Context& context) const override;\r\n        void ResourceFunctionSchema(Execution::Context& context) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/DscSourceResource.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"DscSourceResource.h\"\r\n#include \"DscComposableObject.h\"\r\n#include \"Resources.h\"\r\n#include \"Workflows/SourceFlow.h\"\r\n#include <winget/RepositorySource.h>\r\n#include <winget/ExperimentalFeature.h>\r\n\r\nusing namespace AppInstaller::Utility::literals;\r\nusing namespace AppInstaller::Repository;\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    namespace\r\n    {\r\n        WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY_FLAGS(NameProperty, std::string, SourceName, \"name\", DscComposablePropertyFlag::Required | DscComposablePropertyFlag::CopyToOutput, Resource::String::DscResourcePropertyDescriptionSourceName);\r\n        WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY(ArgumentProperty, std::string, Argument, \"argument\", Resource::String::DscResourcePropertyDescriptionSourceArgument);\r\n        WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY(TypeProperty, std::string, Type, \"type\", Resource::String::DscResourcePropertyDescriptionSourceType);\r\n        WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY_ENUM(TrustLevelProperty, std::string, TrustLevel, \"trustLevel\", Resource::String::DscResourcePropertyDescriptionSourceTrustLevel, ({ \"undefined\", \"none\", \"trusted\" }), \"undefined\");\r\n        WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY(ExplicitProperty, bool, Explicit, \"explicit\", Resource::String::DscResourcePropertyDescriptionSourceExplicit);\r\n        WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY(AcceptAgreementsProperty, bool, AcceptAgreements, \"acceptAgreements\", Resource::String::DscResourcePropertyDescriptionAcceptAgreements);\r\n        WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY(PriorityProperty, int32_t, Priority, \"priority\", Resource::String::DscResourcePropertyDescriptionSourcePriority);\r\n\r\n        using SourceResourceObject = DscComposableObject<StandardExistProperty, StandardInDesiredStateProperty, NameProperty, ArgumentProperty, TypeProperty, TrustLevelProperty, ExplicitProperty, AcceptAgreementsProperty, PriorityProperty>;\r\n\r\n        std::string TrustLevelStringFromFlags(SourceTrustLevel trustLevel)\r\n        {\r\n            return WI_IsFlagSet(trustLevel, SourceTrustLevel::Trusted) ? \"trusted\" : \"none\";\r\n        }\r\n\r\n        // The values as the resource uses them.\r\n        enum class ResourceTrustLevel\r\n        {\r\n            Undefined,\r\n            Invalid,\r\n            None,\r\n            Trusted\r\n        };\r\n\r\n        ResourceTrustLevel EffectiveTrustLevel(const std::optional<std::string>& input)\r\n        {\r\n            if (!input)\r\n            {\r\n                return ResourceTrustLevel::Undefined;\r\n            }\r\n\r\n            std::string inputValue = Utility::ToLower(input.value());\r\n            if (inputValue == \"undefined\")\r\n            {\r\n                return ResourceTrustLevel::Undefined;\r\n            }\r\n            else if (inputValue == \"none\")\r\n            {\r\n                return ResourceTrustLevel::None;\r\n            }\r\n            else if (inputValue == \"trusted\")\r\n            {\r\n                return ResourceTrustLevel::Trusted;\r\n            }\r\n            else\r\n            {\r\n                return ResourceTrustLevel::Invalid;\r\n            }\r\n        }\r\n\r\n        struct SourceFunctionData\r\n        {\r\n            SourceFunctionData(Execution::Context& context, const std::optional<Json::Value>& json, bool ignoreFieldRequirements = false) :\r\n                Input(json, ignoreFieldRequirements),\r\n                ParentContext(context)\r\n            {\r\n                Reset();\r\n            }\r\n\r\n            const SourceResourceObject Input;\r\n            SourceResourceObject Output;\r\n            Execution::Context& ParentContext;\r\n            std::unique_ptr<Execution::Context> SubContext;\r\n\r\n            // Reset the state that is modified by Get\r\n            void Reset()\r\n            {\r\n                Output = Input.CopyForOutput();\r\n\r\n                SubContext = ParentContext.CreateSubContext();\r\n                SubContext->SetFlags(Execution::ContextFlag::DisableInteractivity);\r\n\r\n                if (Input.AcceptAgreements().value_or(false))\r\n                {\r\n                    SubContext->Args.AddArg(Execution::Args::Type::AcceptSourceAgreements);\r\n                }\r\n            }\r\n\r\n            // Fills the Output object with the current state\r\n            void Get()\r\n            {\r\n                auto currentSources = Repository::Source::GetCurrentSources();\r\n                const std::string& name = Input.SourceName().value();\r\n\r\n                Output.Exist(false);\r\n\r\n                for (auto const& source : currentSources)\r\n                {\r\n                    if (Utility::ICUCaseInsensitiveEquals(source.Name, name))\r\n                    {\r\n                        Output.Exist(true);\r\n                        Output.Argument(source.Arg);\r\n                        Output.Type(source.Type);\r\n                        Output.TrustLevel(TrustLevelStringFromFlags(source.TrustLevel));\r\n                        Output.Explicit(source.Explicit);\r\n\r\n                        if (Settings::ExperimentalFeature::IsEnabled(Settings::ExperimentalFeature::Feature::SourcePriority))\r\n                        {\r\n                            Output.Priority(source.Priority);\r\n                        }\r\n\r\n                        std::vector<Repository::SourceDetails> sources;\r\n                        sources.emplace_back(source);\r\n                        SubContext->Add<Execution::Data::SourceList>(std::move(sources));\r\n                        break;\r\n                    }\r\n                }\r\n\r\n                AICLI_LOG(CLI, Verbose, << \"Source::Get found:\\n\" << Json::writeString(Json::StreamWriterBuilder{}, Output.ToJson()));\r\n            }\r\n\r\n            void Add()\r\n            {\r\n                AICLI_LOG(CLI, Verbose, << \"Source::Add invoked\");\r\n\r\n                if (!SubContext->Args.Contains(Execution::Args::Type::SourceName))\r\n                {\r\n                    SubContext->Args.AddArg(Execution::Args::Type::SourceName, Input.SourceName().value());\r\n                }\r\n\r\n                THROW_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS, !Input.Argument().has_value());\r\n                SubContext->Args.AddArg(Execution::Args::Type::SourceArg, Input.Argument().value());\r\n\r\n                if (Input.Type())\r\n                {\r\n                    SubContext->Args.AddArg(Execution::Args::Type::SourceType, Input.Type().value());\r\n                }\r\n\r\n                ResourceTrustLevel effectiveTrustLevel = EffectiveTrustLevel(Input.TrustLevel());\r\n                THROW_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS, effectiveTrustLevel == ResourceTrustLevel::Invalid);\r\n                if (effectiveTrustLevel == ResourceTrustLevel::Trusted)\r\n                {\r\n                    SubContext->Args.AddArg(Execution::Args::Type::SourceTrustLevel, TrustLevelStringFromFlags(SourceTrustLevel::Trusted));\r\n                }\r\n\r\n                if (Input.Explicit().value_or(false))\r\n                {\r\n                    SubContext->Args.AddArg(Execution::Args::Type::SourceExplicit);\r\n                }\r\n\r\n                std::string priorityString;\r\n                if (Input.Priority())\r\n                {\r\n                    THROW_HR_IF(APPINSTALLER_CLI_ERROR_EXPERIMENTAL_FEATURE_DISABLED, !Settings::ExperimentalFeature::IsEnabled(Settings::ExperimentalFeature::Feature::SourcePriority));\r\n                    priorityString = std::to_string(Input.Priority().value());\r\n                    SubContext->Args.AddArg(Execution::Args::Type::SourcePriority, priorityString);\r\n                }\r\n\r\n                *SubContext <<\r\n                    Workflow::EnsureRunningAsAdmin <<\r\n                    Workflow::CreateSourceForSourceAdd <<\r\n                    Workflow::AddSource;\r\n            }\r\n\r\n            void Remove()\r\n            {\r\n                AICLI_LOG(CLI, Verbose, << \"Source::Remove invoked\");\r\n\r\n                if (!SubContext->Args.Contains(Execution::Args::Type::SourceName))\r\n                {\r\n                    SubContext->Args.AddArg(Execution::Args::Type::SourceName, Input.SourceName().value());\r\n                }\r\n\r\n                *SubContext <<\r\n                    Workflow::EnsureRunningAsAdmin <<\r\n                    Workflow::RemoveSources;\r\n            }\r\n\r\n            void Edit()\r\n            {\r\n                AICLI_LOG(CLI, Verbose, << \"Source::Edit invoked\");\r\n\r\n                if (!SubContext->Args.Contains(Execution::Args::Type::SourceName))\r\n                {\r\n                    SubContext->Args.AddArg(Execution::Args::Type::SourceName, Input.SourceName().value());\r\n                }\r\n\r\n                std::string explicitString;\r\n                if (Input.Explicit())\r\n                {\r\n                    explicitString = Utility::ConvertBoolToString(Input.Explicit().value());\r\n                    SubContext->Args.AddArg(Execution::Args::Type::SourceEditExplicit, explicitString);\r\n                }\r\n\r\n                std::string priorityString;\r\n                if (Input.Priority())\r\n                {\r\n                    THROW_HR_IF(APPINSTALLER_CLI_ERROR_EXPERIMENTAL_FEATURE_DISABLED, !Settings::ExperimentalFeature::IsEnabled(Settings::ExperimentalFeature::Feature::SourcePriority));\r\n                    priorityString = std::to_string(Input.Priority().value());\r\n                    SubContext->Args.AddArg(Execution::Args::Type::SourcePriority, priorityString);\r\n                }\r\n\r\n                *SubContext <<\r\n                    Workflow::EnsureRunningAsAdmin <<\r\n                    Workflow::EditSources;\r\n            }\r\n\r\n            void Replace()\r\n            {\r\n                AICLI_LOG(CLI, Verbose, << \"Source::Replace invoked\");\r\n\r\n                // Check to see if we can use an edit rather than a complete replacement\r\n                if (TestArgument() && TestType() && TestTrustLevel())\r\n                {\r\n                    // Implies that the failing portion of Test was in the editable Explicit or Priority properties\r\n                    Edit();\r\n                }\r\n                else\r\n                {\r\n                    Remove();\r\n                    Add();\r\n                }\r\n            }\r\n\r\n            // Determines if the current Output values match the Input values state.\r\n            bool Test()\r\n            {\r\n                // Need to populate Output before calling\r\n                THROW_HR_IF(E_UNEXPECTED, !Output.Exist().has_value());\r\n\r\n                if (Input.ShouldExist())\r\n                {\r\n                    if (Output.Exist().value())\r\n                    {\r\n                        AICLI_LOG(CLI, Verbose, << \"Source::Test needed to inspect these properties: Argument(\" << TestArgument() <<\r\n                            \"), Type(\" << TestType() << \"), TrustLevel(\" << TestTrustLevel() << \"), Explicit(\" << TestExplicit() << \"), Priority(\" << TestPriority() << \")\");\r\n                        return TestArgument() && TestType() && TestTrustLevel() && TestExplicit() && TestPriority();\r\n                    }\r\n                    else\r\n                    {\r\n                        AICLI_LOG(CLI, Verbose, << \"Source::Test was false because the source is not present\");\r\n                        return false;\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(CLI, Verbose, << \"Source::Test desired the source to not exist, and it \" << (Output.Exist().value() ? \"did\" : \"did not\"));\r\n                    return !Output.Exist().value();\r\n                }\r\n            }\r\n\r\n            Json::Value DiffJson()\r\n            {\r\n                // Need to populate Output before calling\r\n                THROW_HR_IF(E_UNEXPECTED, !Output.Exist().has_value());\r\n\r\n                Json::Value result{ Json::ValueType::arrayValue };\r\n\r\n                if (Input.ShouldExist() != Output.Exist().value())\r\n                {\r\n                    result.append(std::string{ StandardExistProperty::Name() });\r\n                }\r\n                else\r\n                {\r\n                    if (!TestArgument())\r\n                    {\r\n                        result.append(std::string{ ArgumentProperty::Name() });\r\n                    }\r\n\r\n                    if (!TestType())\r\n                    {\r\n                        result.append(std::string{ TypeProperty::Name() });\r\n                    }\r\n\r\n                    if (!TestTrustLevel())\r\n                    {\r\n                        result.append(std::string{ TrustLevelProperty::Name() });\r\n                    }\r\n\r\n                    if (!TestExplicit())\r\n                    {\r\n                        result.append(std::string{ ExplicitProperty::Name() });\r\n                    }\r\n\r\n                    if (!TestPriority())\r\n                    {\r\n                        result.append(std::string{ PriorityProperty::Name() });\r\n                    }\r\n                }\r\n\r\n                return result;\r\n            }\r\n\r\n            bool TestArgument()\r\n            {\r\n                if (Input.Argument())\r\n                {\r\n                    if (Output.Argument())\r\n                    {\r\n                        return Input.Argument().value() == Output.Argument().value();\r\n                    }\r\n                    else\r\n                    {\r\n                        return false;\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    return true;\r\n                }\r\n            }\r\n\r\n            bool TestType()\r\n            {\r\n                if (Input.Type())\r\n                {\r\n                    if (Output.Type())\r\n                    {\r\n                        return Utility::CaseInsensitiveEquals(Input.Type().value(), Output.Type().value());\r\n                    }\r\n                    else\r\n                    {\r\n                        return false;\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    return true;\r\n                }\r\n            }\r\n\r\n            bool TestTrustLevel()\r\n            {\r\n                auto inputTrustLevel = EffectiveTrustLevel(Input.TrustLevel());\r\n\r\n                if (inputTrustLevel != ResourceTrustLevel::Undefined)\r\n                {\r\n                    return inputTrustLevel == EffectiveTrustLevel(Output.TrustLevel());\r\n                }\r\n                else\r\n                {\r\n                    return true;\r\n                }\r\n            }\r\n\r\n            bool TestExplicit()\r\n            {\r\n                if (Input.Explicit())\r\n                {\r\n                    if (Output.Explicit())\r\n                    {\r\n                        return Input.Explicit().value() == Output.Explicit().value();\r\n                    }\r\n                    else\r\n                    {\r\n                        return false;\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    return true;\r\n                }\r\n            }\r\n\r\n            bool TestPriority()\r\n            {\r\n                if (Input.Priority())\r\n                {\r\n                    THROW_HR_IF(APPINSTALLER_CLI_ERROR_EXPERIMENTAL_FEATURE_DISABLED, !Settings::ExperimentalFeature::IsEnabled(Settings::ExperimentalFeature::Feature::SourcePriority));\r\n                    if (Output.Priority())\r\n                    {\r\n                        return Input.Priority().value() == Output.Priority().value();\r\n                    }\r\n                    else\r\n                    {\r\n                        return false;\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    return true;\r\n                }\r\n            }\r\n        };\r\n    }\r\n\r\n    DscSourceResource::DscSourceResource(std::string_view parent) :\r\n        DscCommandBase(parent, \"source\", DscResourceKind::Resource,\r\n            DscFunctions::Get | DscFunctions::Set | DscFunctions::Test | DscFunctions::Export | DscFunctions::Schema,\r\n            DscFunctionModifiers::ImplementsPretest | DscFunctionModifiers::HandlesExist | DscFunctionModifiers::ReturnsStateAndDiff)\r\n    {\r\n    }\r\n\r\n    Resource::LocString DscSourceResource::ShortDescription() const\r\n    {\r\n        return Resource::String::DscSourceResourceShortDescription;\r\n    }\r\n\r\n    Resource::LocString DscSourceResource::LongDescription() const\r\n    {\r\n        return Resource::String::DscSourceResourceLongDescription;\r\n    }\r\n\r\n    std::string DscSourceResource::ResourceType() const\r\n    {\r\n        return \"Source\";\r\n    }\r\n\r\n    void DscSourceResource::ResourceFunctionGet(Execution::Context& context) const\r\n    {\r\n        if (auto json = GetJsonFromInput(context))\r\n        {\r\n            SourceFunctionData data{ context, json };\r\n\r\n            data.Get();\r\n\r\n            WriteJsonOutputLine(context, data.Output.ToJson());\r\n        }\r\n    }\r\n\r\n    void DscSourceResource::ResourceFunctionSet(Execution::Context& context) const\r\n    {\r\n        if (auto json = GetJsonFromInput(context))\r\n        {\r\n            SourceFunctionData data{ context, json };\r\n\r\n            data.Get();\r\n\r\n            // Capture the diff before updating the output\r\n            auto diff = data.DiffJson();\r\n\r\n            if (!data.Test())\r\n            {\r\n                if (data.Input.ShouldExist())\r\n                {\r\n                    if (data.Output.Exist().value())\r\n                    {\r\n                        AICLI_LOG(CLI, Info, << \"Replacing source with new information\");\r\n                        data.Replace();\r\n                    }\r\n                    else\r\n                    {\r\n                        AICLI_LOG(CLI, Info, << \"Adding source as it was not found\");\r\n                        data.Add();\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(CLI, Info, << \"Removing source as desired\");\r\n                    data.Remove();\r\n                }\r\n\r\n                if (data.SubContext->IsTerminated())\r\n                {\r\n                    data.ParentContext.Terminate(data.SubContext->GetTerminationHR());\r\n                    return;\r\n                }\r\n\r\n                data.Reset();\r\n                data.Get();\r\n            }\r\n\r\n            WriteJsonOutputLine(context, data.Output.ToJson());\r\n            WriteJsonOutputLine(context, diff);\r\n        }\r\n    }\r\n\r\n    void DscSourceResource::ResourceFunctionTest(Execution::Context& context) const\r\n    {\r\n        if (auto json = GetJsonFromInput(context))\r\n        {\r\n            SourceFunctionData data{ context, json };\r\n\r\n            data.Get();\r\n            data.Output.InDesiredState(data.Test());\r\n\r\n            WriteJsonOutputLine(context, data.Output.ToJson());\r\n            WriteJsonOutputLine(context, data.DiffJson());\r\n        }\r\n    }\r\n\r\n    void DscSourceResource::ResourceFunctionExport(Execution::Context& context) const\r\n    {\r\n        auto currentSources = Repository::Source::GetCurrentSources();\r\n\r\n        for (auto const& source : currentSources)\r\n        {\r\n            SourceResourceObject output;\r\n            output.SourceName(source.Name);\r\n            output.Argument(source.Arg);\r\n            output.Type(source.Type);\r\n            output.TrustLevel(TrustLevelStringFromFlags(source.TrustLevel));\r\n            output.Explicit(source.Explicit);\r\n\r\n            if (Settings::ExperimentalFeature::IsEnabled(Settings::ExperimentalFeature::Feature::SourcePriority))\r\n            {\r\n                output.Priority(source.Priority);\r\n            }\r\n\r\n            WriteJsonOutputLine(context, output.ToJson());\r\n        }\r\n    }\r\n\r\n    void DscSourceResource::ResourceFunctionSchema(Execution::Context& context) const\r\n    {\r\n        WriteJsonOutputLine(context, SourceResourceObject::Schema(ResourceType()));\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/DscSourceResource.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"DscCommandBase.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    // A resource for managing source configuration.\r\n    struct DscSourceResource : public DscCommandBase\r\n    {\r\n        DscSourceResource(std::string_view parent);\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n    protected:\r\n        std::string ResourceType() const override;\r\n\r\n        void ResourceFunctionGet(Execution::Context& context) const override;\r\n        void ResourceFunctionSet(Execution::Context& context) const override;\r\n        void ResourceFunctionTest(Execution::Context& context) const override;\r\n        void ResourceFunctionExport(Execution::Context& context) const override;\r\n        void ResourceFunctionSchema(Execution::Context& context) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/DscTestFileResource.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"DscTestFileResource.h\"\r\n#include \"DscComposableObject.h\"\r\n\r\nusing namespace AppInstaller::Utility::literals;\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    namespace\r\n    {\r\n        WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY_FLAGS(PathProperty, std::string, Path, \"path\", DscComposablePropertyFlag::Required | DscComposablePropertyFlag::CopyToOutput, \"The absolute path to a file.\"_lis);\r\n        WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY(ContentProperty, std::string, Content, \"content\", \"The content of the file.\"_lis);\r\n\r\n        using TestFileObject = DscComposableObject<StandardExistProperty, StandardInDesiredStateProperty, PathProperty, ContentProperty>;\r\n\r\n        struct TestFileFunctionData\r\n        {\r\n            TestFileFunctionData(const std::optional<Json::Value>& json) : Input(json), Output(Input.CopyForOutput())\r\n            {\r\n                Path = Utility::ConvertToUTF16(Input.Path().value());\r\n                THROW_HR_IF(E_INVALIDARG, !Path.is_absolute());\r\n            }\r\n\r\n            TestFileObject Input;\r\n            TestFileObject Output;\r\n            std::filesystem::path Path;\r\n\r\n            // Fills the Output object with the current state\r\n            void Get()\r\n            {\r\n                if (std::filesystem::exists(Path) && std::filesystem::is_regular_file(Path))\r\n                {\r\n                    Output.Exist(true);\r\n\r\n                    std::ifstream stream{ Path, std::ios::binary };\r\n                    Output.Content(Utility::ReadEntireStream(stream));\r\n                }\r\n                else\r\n                {\r\n                    Output.Exist(false);\r\n                }\r\n            }\r\n\r\n            // Determines if the current Output values match the Input values state.\r\n            bool Test()\r\n            {\r\n                // Need to populate Output before calling\r\n                THROW_HR_IF(E_UNEXPECTED, !Output.Exist().has_value());\r\n\r\n                if (Input.ShouldExist())\r\n                {\r\n                    if (Output.Exist().value())\r\n                    {\r\n                        return ContentMatches();\r\n                    }\r\n                    else\r\n                    {\r\n                        return false;\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    return !Output.Exist().value();\r\n                }\r\n            }\r\n\r\n            Json::Value DiffJson()\r\n            {\r\n                // Need to populate Output before calling\r\n                THROW_HR_IF(E_UNEXPECTED, !Output.Exist().has_value());\r\n\r\n                Json::Value result{ Json::ValueType::arrayValue };\r\n\r\n                if (Input.ShouldExist() != Output.Exist().value())\r\n                {\r\n                    result.append(std::string{ StandardExistProperty::Name() });\r\n                }\r\n                else\r\n                {\r\n                    if (!ContentMatches())\r\n                    {\r\n                        result.append(std::string{ ContentProperty::Name() });\r\n                    }\r\n                }\r\n\r\n                return result;\r\n            }\r\n\r\n        private:\r\n            bool ContentMatches()\r\n            {\r\n                bool hasInput = Input.Content().has_value() && !Input.Content().value().empty();\r\n                bool hasOutput = Output.Content().has_value() && !Output.Content().value().empty();\r\n\r\n                return\r\n                    (hasInput && hasOutput && Input.Content().value() == Output.Content().value()) ||\r\n                    (!hasInput && !hasOutput);\r\n            }\r\n        };\r\n    }\r\n\r\n    DscTestFileResource::DscTestFileResource(std::string_view parent) :\r\n        DscCommandBase(parent, \"test-file\", DscResourceKind::Resource,\r\n            DscFunctions::Get | DscFunctions::Set | DscFunctions::Test | DscFunctions::Export | DscFunctions::Schema,\r\n            DscFunctionModifiers::ImplementsPretest | DscFunctionModifiers::HandlesExist | DscFunctionModifiers::ReturnsStateAndDiff)\r\n    {\r\n    }\r\n\r\n    Resource::LocString DscTestFileResource::ShortDescription() const\r\n    {\r\n        return \"[TEST] File content resource\"_lis;\r\n    }\r\n\r\n    Resource::LocString DscTestFileResource::LongDescription() const\r\n    {\r\n        return \"[TEST] This resource is only available for tests. It provides file content configuration.\"_lis;\r\n    }\r\n\r\n    std::string DscTestFileResource::ResourceType() const\r\n    {\r\n        return \"TestFile\";\r\n    }\r\n\r\n    void DscTestFileResource::ResourceFunctionGet(Execution::Context& context) const\r\n    {\r\n        if (auto json = GetJsonFromInput(context))\r\n        {\r\n            TestFileFunctionData data{ json };\r\n\r\n            data.Get();\r\n\r\n            WriteJsonOutputLine(context, data.Output.ToJson());\r\n        }\r\n    }\r\n\r\n    void DscTestFileResource::ResourceFunctionSet(Execution::Context& context) const\r\n    {\r\n        if (auto json = GetJsonFromInput(context))\r\n        {\r\n            TestFileFunctionData data{ json };\r\n\r\n            data.Get();\r\n\r\n            if (!data.Test())\r\n            {\r\n                bool exists = std::filesystem::exists(data.Path);\r\n                if (exists)\r\n                {\r\n                    // Don't delete a directory or other special files in this test resource\r\n                    THROW_WIN32_IF(ERROR_DIRECTORY_NOT_SUPPORTED, !std::filesystem::is_regular_file(data.Path));\r\n                }\r\n\r\n                if (data.Input.ShouldExist())\r\n                {\r\n                    std::filesystem::create_directories(data.Path.parent_path());\r\n\r\n                    std::ofstream stream{ data.Path, std::ios::binary | std::ios::trunc };\r\n                    if (data.Input.Content())\r\n                    {\r\n                        stream.write(data.Input.Content().value().c_str(), data.Input.Content().value().length());\r\n                    }\r\n                }\r\n                else if (exists)\r\n                {\r\n                    std::filesystem::remove(data.Path);\r\n                }\r\n            }\r\n\r\n            // Capture the diff before updating the output\r\n            auto diff = data.DiffJson();\r\n\r\n            data.Output.Exist(data.Input.ShouldExist());\r\n            if (data.Output.Exist().value())\r\n            {\r\n                data.Output.Content(data.Input.Content().value_or(\"\"));\r\n            }\r\n\r\n            WriteJsonOutputLine(context, data.Output.ToJson());\r\n            WriteJsonOutputLine(context, diff);\r\n        }\r\n    }\r\n\r\n    void DscTestFileResource::ResourceFunctionTest(Execution::Context& context) const\r\n    {\r\n        if (auto json = GetJsonFromInput(context))\r\n        {\r\n            TestFileFunctionData data{ json };\r\n\r\n            data.Get();\r\n            data.Output.InDesiredState(data.Test());\r\n\r\n            WriteJsonOutputLine(context, data.Output.ToJson());\r\n            WriteJsonOutputLine(context, data.DiffJson());\r\n        }\r\n    }\r\n\r\n    void DscTestFileResource::ResourceFunctionExport(Execution::Context& context) const\r\n    {\r\n        if (auto json = GetJsonFromInput(context))\r\n        {\r\n            TestFileFunctionData data{ json };\r\n\r\n            if (std::filesystem::exists(data.Path))\r\n            {\r\n                if (std::filesystem::is_regular_file(data.Path))\r\n                {\r\n                    data.Get();\r\n                    WriteJsonOutputLine(context, data.Output.ToJson());\r\n                }\r\n                else if (std::filesystem::is_directory(data.Path))\r\n                {\r\n                    for (const auto& file : std::filesystem::directory_iterator{ data.Path })\r\n                    {\r\n                        if (std::filesystem::is_regular_file(file))\r\n                        {\r\n                            TestFileObject output;\r\n                            output.Path(file.path().u8string());\r\n\r\n                            std::ifstream stream{ file.path(), std::ios::binary};\r\n                            output.Content(Utility::ReadEntireStream(stream));\r\n\r\n                            WriteJsonOutputLine(context, output.ToJson());\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    void DscTestFileResource::ResourceFunctionSchema(Execution::Context& context) const\r\n    {\r\n        WriteJsonOutputLine(context, TestFileObject::Schema(ResourceType()));\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/DscTestFileResource.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"DscCommandBase.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    // A test resource implementing file content configuration.\r\n    struct DscTestFileResource : public DscCommandBase\r\n    {\r\n        DscTestFileResource(std::string_view parent);\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n    protected:\r\n        std::string ResourceType() const override;\r\n\r\n        void ResourceFunctionGet(Execution::Context& context) const override;\r\n        void ResourceFunctionSet(Execution::Context& context) const override;\r\n        void ResourceFunctionTest(Execution::Context& context) const override;\r\n        void ResourceFunctionExport(Execution::Context& context) const override;\r\n        void ResourceFunctionSchema(Execution::Context& context) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/DscTestJsonResource.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"DscTestJsonResource.h\"\r\n#include \"DscComposableObject.h\"\r\n#include <AppInstallerRuntime.h>\r\n\r\nusing namespace AppInstaller::Utility::literals;\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    namespace\r\n    {\r\n        WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY_FLAGS(PropertyProperty, std::string, Property, \"property\", DscComposablePropertyFlag::Required | DscComposablePropertyFlag::CopyToOutput, \"The JSON property name.\"_lis);\r\n        WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY(ValueProperty, Json::Value, Value, \"value\", \"The value for the JSON property.\"_lis);\r\n\r\n        using TestJsonObject = DscComposableObject<StandardExistProperty, PropertyProperty, ValueProperty>;\r\n\r\n        struct TestJsonFunctionData\r\n        {\r\n            TestJsonFunctionData()\r\n            {\r\n                InitializeFileData();\r\n            }\r\n\r\n            TestJsonFunctionData(const std::optional<Json::Value>& json) : Input(json), Output(Input.CopyForOutput())\r\n            {\r\n                InitializeFileData();\r\n            }\r\n\r\n            TestJsonObject Input;\r\n            TestJsonObject Output;\r\n            std::filesystem::path FilePath;\r\n            Json::Value RootValue;\r\n\r\n            static std::filesystem::path GetFilePath()\r\n            {\r\n                std::filesystem::path result = Runtime::GetPathTo(Runtime::PathName::LocalState);\r\n                result /= \"test-json-file.json\";\r\n                return result;\r\n            }\r\n\r\n            // Fills the Output object with the current state\r\n            void Get()\r\n            {\r\n                const std::string& propertyName = Input.Property().value();\r\n                const Json::Value* propertyValue = RootValue.find(propertyName.data(), propertyName.data() + propertyName.length());\r\n\r\n                if (propertyValue)\r\n                {\r\n                    Output.Exist(true);\r\n\r\n                    Output.Value(*propertyValue);\r\n                }\r\n                else\r\n                {\r\n                    Output.Exist(false);\r\n                }\r\n            }\r\n\r\n        private:\r\n            void InitializeFileData()\r\n            {\r\n                FilePath = GetFilePath();\r\n                RootValue = GetJsonFromFile();\r\n            }\r\n\r\n            Json::Value GetJsonFromFile() const\r\n            {\r\n                Json::Value result;\r\n                Json::CharReaderBuilder builder;\r\n                Json::String errors;\r\n\r\n                std::ifstream stream{ FilePath, std::ios::binary };\r\n\r\n                if (stream)\r\n                {\r\n                    if (!Json::parseFromStream(builder, stream, &result, &errors))\r\n                    {\r\n                        AICLI_LOG(CLI, Warning, << \"Failed to read test JSON file: \" << errors);\r\n                        result = Json::Value{};\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(CLI, Warning, << \"Couldn't open test JSON file: \" << FilePath);\r\n                }\r\n\r\n                return result;\r\n            }\r\n        };\r\n    }\r\n\r\n    DscTestJsonResource::DscTestJsonResource(std::string_view parent) :\r\n        DscCommandBase(parent, \"test-json\", DscResourceKind::Resource,\r\n            DscFunctions::Get | DscFunctions::Set | DscFunctions::Export | DscFunctions::Schema,\r\n            DscFunctionModifiers::HandlesExist | DscFunctionModifiers::ReturnsState)\r\n    {\r\n    }\r\n\r\n    std::vector<Argument> DscTestJsonResource::GetArguments() const\r\n    {\r\n        auto result = DscCommandBase::GetArguments();\r\n        result.emplace_back(Execution::Args::Type::DscResourceFunctionDelete, Resource::String::DscResourceFunctionDescriptionDelete, ArgumentType::Flag);\r\n        return result;\r\n    }\r\n\r\n    Resource::LocString DscTestJsonResource::ShortDescription() const\r\n    {\r\n        return \"[TEST] JSON content resource\"_lis;\r\n    }\r\n\r\n    Resource::LocString DscTestJsonResource::LongDescription() const\r\n    {\r\n        return \"[TEST] This resource is only available for tests. It provides JSON content configuration of a well known file.\"_lis;\r\n    }\r\n\r\n    void DscTestJsonResource::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        if (context.Args.Contains(Execution::Args::Type::DscResourceFunctionDelete))\r\n        {\r\n            std::filesystem::remove_all(TestJsonFunctionData::GetFilePath());\r\n            return;\r\n        }\r\n\r\n        DscCommandBase::ExecuteInternal(context);\r\n    }\r\n\r\n    std::string DscTestJsonResource::ResourceType() const\r\n    {\r\n        return \"TestJSON\";\r\n    }\r\n\r\n    void DscTestJsonResource::ResourceFunctionGet(Execution::Context& context) const\r\n    {\r\n        if (auto json = GetJsonFromInput(context))\r\n        {\r\n            TestJsonFunctionData data{ json };\r\n\r\n            data.Get();\r\n\r\n            WriteJsonOutputLine(context, data.Output.ToJson());\r\n        }\r\n    }\r\n\r\n    void DscTestJsonResource::ResourceFunctionSet(Execution::Context& context) const\r\n    {\r\n        if (auto json = GetJsonFromInput(context))\r\n        {\r\n            TestJsonFunctionData data{ json };\r\n\r\n            data.Get();\r\n\r\n            if (data.RootValue.isNull())\r\n            {\r\n                data.RootValue = Json::Value{ Json::objectValue };\r\n            }\r\n\r\n            if (data.Input.ShouldExist())\r\n            {\r\n                data.RootValue[data.Input.Property().value()] = data.Input.Value().value_or(Json::Value{ Json::nullValue });\r\n                data.Output.Exist(true);\r\n                data.Output.Value(data.RootValue[data.Input.Property().value()]);\r\n            }\r\n            else if (data.Output.Exist().value())\r\n            {\r\n                data.RootValue.removeMember(data.Input.Property().value());\r\n                data.Output.Exist(false);\r\n            }\r\n\r\n            std::ofstream stream{ data.FilePath, std::ios::binary };\r\n\r\n            Json::StreamWriterBuilder writerBuilder;\r\n            writerBuilder.settings_[\"indentation\"] = \"  \";\r\n\r\n            stream << Json::writeString(writerBuilder, data.RootValue);\r\n\r\n            WriteJsonOutputLine(context, data.Output.ToJson());\r\n        }\r\n    }\r\n\r\n    void DscTestJsonResource::ResourceFunctionExport(Execution::Context& context) const\r\n    {\r\n        TestJsonFunctionData data;\r\n\r\n        if (data.RootValue.isObject())\r\n        {\r\n            for (const auto& member : data.RootValue.getMemberNames())\r\n            {\r\n                const Json::Value* memberValue = data.RootValue.find(member.data(), member.data() + member.length());\r\n\r\n                if (memberValue)\r\n                {\r\n                    TestJsonObject output;\r\n                    output.Property(member);\r\n                    output.Value(*memberValue);\r\n\r\n                    WriteJsonOutputLine(context, output.ToJson());\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    void DscTestJsonResource::ResourceFunctionSchema(Execution::Context& context) const\r\n    {\r\n        WriteJsonOutputLine(context, TestJsonObject::Schema(ResourceType()));\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/DscTestJsonResource.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"DscCommandBase.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    // A test resource implementing JSON content configuration of a well known file.\r\n    // This is exists to enable an input-less export, which is required in DSC v3.0.0\r\n    struct DscTestJsonResource : public DscCommandBase\r\n    {\r\n        DscTestJsonResource(std::string_view parent);\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n\r\n        std::string ResourceType() const override;\r\n\r\n        void ResourceFunctionGet(Execution::Context& context) const override;\r\n        void ResourceFunctionSet(Execution::Context& context) const override;\r\n        void ResourceFunctionExport(Execution::Context& context) const override;\r\n        void ResourceFunctionSchema(Execution::Context& context) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/DscUserSettingsFileResource.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"DscUserSettingsFileResource.h\"\r\n#include \"DscComposableObject.h\"\r\n#include \"Resources.h\"\r\n#include \"AppInstallerStrings.h\"\r\n\r\nusing namespace AppInstaller::Utility::literals;\r\nusing namespace AppInstaller::Settings;\r\n\r\n#define ACTION_FULL \"Full\"\r\n#define ACTION_PARTIAL \"Partial\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    namespace\r\n    {\r\n        WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY_FLAGS(SettingsProperty, Json::Value, Settings, \"settings\", DscComposablePropertyFlag::Required | DscComposablePropertyFlag::CopyToOutput, Resource::String::DscResourcePropertyDescriptionUserSettingsFileSettings);\r\n        WINGET_DSC_DEFINE_COMPOSABLE_PROPERTY_ENUM(ActionProperty, std::string, Action, \"action\", Resource::String::DscResourcePropertyDescriptionUserSettingsFileAction, ({ ACTION_PARTIAL, ACTION_FULL }), ACTION_PARTIAL);\r\n\r\n        using UserSettingsFileResourceObject = DscComposableObject<StandardInDesiredStateProperty, SettingsProperty, ActionProperty>;\r\n\r\n        struct UserSettingsFileFunctionData\r\n        {\r\n            UserSettingsFileFunctionData()\r\n                : UserSettingsFileFunctionData(std::nullopt, true)\r\n            {\r\n            }\r\n\r\n            UserSettingsFileFunctionData(const std::optional<Json::Value>& json, bool ignoreFieldRequirements = false) :\r\n                Input(json, ignoreFieldRequirements),\r\n                _userSettingsPath(UserSettings::SettingsFilePath())\r\n            {\r\n            }\r\n\r\n            const UserSettingsFileResourceObject Input;\r\n            UserSettingsFileResourceObject Output;\r\n\r\n            void Get()\r\n            {\r\n                Output.Settings(GetUserSettings());\r\n            }\r\n\r\n            bool Test()\r\n            {\r\n                return GetResolvedInput() == Output.Settings();\r\n            }\r\n\r\n            Json::Value DiffJson()\r\n            {\r\n                Json::Value result{ Json::ValueType::arrayValue };\r\n\r\n                if (!Test())\r\n                {\r\n                    result.append(std::string{ SettingsProperty::Name() });\r\n                }\r\n\r\n                return result;\r\n            }\r\n\r\n            const Json::Value& GetResolvedInput()\r\n            {\r\n                THROW_HR_IF(E_UNEXPECTED, !Input.Settings().has_value());\r\n                if (!_resolvedInputUserSettings)\r\n                {\r\n                    if(Input.Action().has_value() && Utility::CaseInsensitiveEquals(Input.Action().value(), ACTION_FULL))\r\n                    {\r\n                        Output.Action(ACTION_FULL);\r\n                        _resolvedInputUserSettings = Input.Settings();\r\n                    }\r\n                    else\r\n                    {\r\n                        Output.Action(ACTION_PARTIAL);\r\n                        _resolvedInputUserSettings = MergeUserSettingsFiles(*Input.Settings());\r\n                    }\r\n                }\r\n\r\n                return *_resolvedInputUserSettings;\r\n            }\r\n\r\n            bool WriteOutput()\r\n            {\r\n                THROW_HR_IF(E_UNEXPECTED, !Output.Settings().has_value());\r\n                std::ofstream file(_userSettingsPath, std::ios::binary);\r\n                if (file)\r\n                {\r\n                    Json::StreamWriterBuilder writer;\r\n                    writer[\"indentation\"] = \"  \";\r\n                    file << Json::writeString(writer, *Output.Settings());\r\n                    return true;\r\n                }\r\n\r\n                AICLI_LOG(Config, Error, << \"Failed to open or create user settings file: \" << _userSettingsPath);\r\n                return false;\r\n            }\r\n\r\n        private:\r\n            std::filesystem::path _userSettingsPath;\r\n            std::optional<Json::Value> _userSettings;\r\n            std::optional<Json::Value> _resolvedInputUserSettings;\r\n\r\n            Json::Value MergeUserSettingsFiles(const Json::Value& overlay)\r\n            {\r\n                Json::Value mergedUserSettingsFile = GetUserSettings();\r\n                MergeUserSettingsFiles(mergedUserSettingsFile, overlay);\r\n                return mergedUserSettingsFile;\r\n            }\r\n\r\n            // Merges the overlay settings into the target settings.\r\n            void MergeUserSettingsFiles(Json::Value& target, const Json::Value& overlay)\r\n            {\r\n                // If either is not an object, we can't merge.\r\n                if (!overlay.isObject() || !target.isObject())\r\n                {\r\n                    return;\r\n                }\r\n\r\n                // Iterate through the overlay settings and merge them into the target.\r\n                for (const auto& overlayKey : overlay.getMemberNames())\r\n                {\r\n                    const Json::Value& overlayValue = overlay[overlayKey];\r\n                    if (target.isMember(overlayKey))\r\n                    {\r\n                        Json::Value& targetValue = target[overlayKey];\r\n                        if (targetValue.isObject() && overlayValue.isObject())\r\n                        {\r\n                            // Recursively merge the objects.\r\n                            MergeUserSettingsFiles(targetValue, overlayValue);\r\n                        }\r\n                        else\r\n                        {\r\n                            // Replace the value in the target.\r\n                            // Note: Arrays are not merged, they are replaced.\r\n                            target[overlayKey] = overlayValue;\r\n                        }\r\n                    }\r\n                    else\r\n                    {\r\n                        // Add the overlay key to the target.\r\n                        target[overlayKey] = overlayValue;\r\n                    }\r\n                }\r\n            }\r\n\r\n            const Json::Value& GetUserSettings()\r\n            {\r\n                if (!_userSettings)\r\n                {\r\n                    _userSettings = Json::objectValue;\r\n                    std::ifstream file(_userSettingsPath, std::ios::binary);\r\n                    if (file)\r\n                    {\r\n                        Json::CharReaderBuilder builder;\r\n                        std::string errs;\r\n                        Json::Value jsonRoot;\r\n                        if (Json::parseFromStream(builder, file, &jsonRoot, &errs))\r\n                        {\r\n                            _userSettings = jsonRoot;\r\n                        }\r\n                        else\r\n                        {\r\n                            AICLI_LOG(Config, Warning, << \"Failed to parse user settings file: \" << _userSettingsPath << \", error: \" << errs);\r\n                        }\r\n                    }\r\n                    else\r\n                    {\r\n                        AICLI_LOG(Config, Warning, << \"Failed to open user settings file: \" << _userSettingsPath);\r\n                    }\r\n                }\r\n\r\n                return *_userSettings;\r\n            }\r\n        };\r\n    }\r\n\r\n    DscUserSettingsFileResource::DscUserSettingsFileResource(std::string_view parent) :\r\n        DscCommandBase(parent, \"user-settings-file\", DscResourceKind::Resource,\r\n            DscFunctions::Get | DscFunctions::Set | DscFunctions::Test | DscFunctions::Export | DscFunctions::Schema,\r\n            DscFunctionModifiers::ImplementsPretest | DscFunctionModifiers::HandlesExist | DscFunctionModifiers::ReturnsStateAndDiff)\r\n    {\r\n    }\r\n\r\n    Resource::LocString DscUserSettingsFileResource::ShortDescription() const\r\n    {\r\n        return Resource::String::DscUserSettingsFileShortDescription;\r\n    }\r\n\r\n    Resource::LocString DscUserSettingsFileResource::LongDescription() const\r\n    {\r\n        return Resource::String::DscUserSettingsFileLongDescription;\r\n    }\r\n\r\n    std::string DscUserSettingsFileResource::ResourceType() const\r\n    {\r\n        return \"UserSettingsFile\";\r\n    }\r\n\r\n    void DscUserSettingsFileResource::ResourceFunctionGet(Execution::Context& context) const\r\n    {\r\n        ResourceFunctionExport(context);\r\n    }\r\n\r\n    void DscUserSettingsFileResource::ResourceFunctionSet(Execution::Context& context) const\r\n    {\r\n        if (auto json = GetJsonFromInput(context))\r\n        {\r\n            UserSettingsFileFunctionData data{ json };\r\n\r\n            data.Get();\r\n\r\n            // Capture the diff before updating the output\r\n            auto diff = data.DiffJson();\r\n\r\n            if (!data.Test())\r\n            {\r\n                data.Output.Settings(data.GetResolvedInput());\r\n                if (!data.WriteOutput())\r\n                {\r\n                    AICLI_TERMINATE_CONTEXT(HRESULT_FROM_WIN32(ERROR_OPEN_FAILED));\r\n                    return;\r\n                }\r\n            }\r\n\r\n            WriteJsonOutputLine(context, data.Output.ToJson());\r\n            WriteJsonOutputLine(context, diff);\r\n        }\r\n    }\r\n\r\n    void DscUserSettingsFileResource::ResourceFunctionTest(Execution::Context& context) const\r\n    {\r\n        if (auto json = GetJsonFromInput(context))\r\n        {\r\n            UserSettingsFileFunctionData data{ json };\r\n\r\n            data.Get();\r\n            data.Output.InDesiredState(data.Test());\r\n\r\n            WriteJsonOutputLine(context, data.Output.ToJson());\r\n            WriteJsonOutputLine(context, data.DiffJson());\r\n        }\r\n    }\r\n\r\n    void DscUserSettingsFileResource::ResourceFunctionExport(Execution::Context& context) const\r\n    {\r\n        UserSettingsFileFunctionData data;\r\n\r\n        data.Get();\r\n\r\n        WriteJsonOutputLine(context, data.Output.ToJson());\r\n    }\r\n\r\n    void DscUserSettingsFileResource::ResourceFunctionSchema(Execution::Context& context) const\r\n    {\r\n        WriteJsonOutputLine(context, UserSettingsFileResourceObject::Schema(ResourceType()));\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/DscUserSettingsFileResource.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"DscCommandBase.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    // A resource for managing user settings file.\r\n    struct DscUserSettingsFileResource : public DscCommandBase\r\n    {\r\n        DscUserSettingsFileResource(std::string_view parent);\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n    protected:\r\n        std::string ResourceType() const override;\r\n\r\n        void ResourceFunctionGet(Execution::Context& context) const override;\r\n        void ResourceFunctionSet(Execution::Context& context) const override;\r\n        void ResourceFunctionTest(Execution::Context& context) const override;\r\n        void ResourceFunctionExport(Execution::Context& context) const override;\r\n        void ResourceFunctionSchema(Execution::Context& context) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ErrorCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ErrorCommand.h\"\r\n#include \"AppInstallerStrings.h\"\r\n#include \"AppInstallerErrors.h\"\r\n#include \"VTSupport.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    namespace\r\n    {\r\n        // 0x12345678 : SYMBOL_VALUE\r\n        // Descriptive text\r\n        void OutputHResultInformation(Execution::Context& context, const Errors::HResultInformation& error)\r\n        {\r\n            auto info = context.Reporter.Info();\r\n            info << VirtualTerminal::TextFormat::Foreground::Bright << \"0x\" << VirtualTerminal::TextFormat::Foreground::Bright << Logging::SetHRFormat << error.Value();\r\n            if (!error.Symbol().empty())\r\n            {\r\n                info << \" : \"_liv << VirtualTerminal::TextFormat::Foreground::BrightCyan << error.Symbol();\r\n            }\r\n            info << std::endl;\r\n            info << error.GetDescription() << std::endl;\r\n        }\r\n    }\r\n\r\n    std::vector<Argument> ErrorCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument{ Execution::Args::Type::ErrorInput, Resource::String::ErrorInputArgumentDescription, ArgumentType::Positional, true },\r\n        };\r\n    }\r\n\r\n    Resource::LocString ErrorCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::ErrorCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString ErrorCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::ErrorCommandLongDescription };\r\n    }\r\n\r\n    void ErrorCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        std::string input{ context.Args.GetArg(Execution::Args::Type::ErrorInput) };\r\n\r\n        const char* begin = input.c_str();\r\n        char* end = nullptr;\r\n        errno = 0;\r\n        HRESULT errorNumber = strtol(begin, &end, 0);\r\n\r\n        if (errno == ERANGE)\r\n        {\r\n            errno = 0;\r\n            unsigned long unsignedError = strtoul(begin, &end, 0);\r\n\r\n            if (errno == ERANGE)\r\n            {\r\n                context.Reporter.Error() << Resource::String::ErrorNumberIsTooLarge << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(E_INVALIDARG);\r\n            }\r\n\r\n            errorNumber = static_cast<HRESULT>(unsignedError);\r\n        }\r\n\r\n        // If the entire string was consumed as a number, treat it as an HRESULT\r\n        if (static_cast<size_t>(end - begin) == input.length())\r\n        {\r\n            auto error = Errors::HResultInformation::Find(errorNumber);\r\n            if (error)\r\n            {\r\n                OutputHResultInformation(context, *error);\r\n            }\r\n        }\r\n        // otherwise, treat it as a string and search our error list\r\n        else\r\n        {\r\n            auto errors = Errors::HResultInformation::Find(Utility::Trim(input));\r\n            for (const auto& error : errors)\r\n            {\r\n                OutputHResultInformation(context, *error);\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ErrorCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Command.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    // This command makes it easier to get information on winget errors.\r\n    struct ErrorCommand final : public Command\r\n    {\r\n        ErrorCommand(std::string_view parent) : Command(\"error\", { \"err\" }, parent, Visibility::Hidden) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ExperimentalCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"ExperimentalCommand.h\"\n#include <winget/UserSettings.h>\n\nnamespace AppInstaller::CLI\n{\n    using namespace Utility::literals;\n    using namespace AppInstaller::Settings;\n\n    using namespace std::string_view_literals;\n\n    std::vector<Argument> ExperimentalCommand::GetArguments() const\n    {\n        return\n        {\n            Argument::ForType(Execution::Args::Type::ExperimentalArg)\n        };\n    }\n\n    Resource::LocString ExperimentalCommand::ShortDescription() const\n    {\n        return { Resource::String::ExperimentalCommandShortDescription };\n    }\n\n    Resource::LocString ExperimentalCommand::LongDescription() const\n    {\n        return { Resource::String::ExperimentalCommandLongDescription };\n    }\n\n    Utility::LocIndView ExperimentalCommand::HelpLink() const\n    {\n        return \"https://aka.ms/winget-settings\"_liv;\n    }\n\n    void ExperimentalCommand::ExecuteInternal(Execution::Context& context) const\n    {\n        if (context.Args.Contains(Execution::Args::Type::ExperimentalArg))\n        {\n            static constexpr std::string_view s_ninjaCat = R\"(\n                                    -<vYT`                                           \n                                 ')hM3d$$c                                           \n                              `~uydNv>>$$$^                                          \n                        -T}uymkZdqUdN3mowkh_                                         \n                         T06m\\xrwingetxYxcky`                                        \n                          wDNf3omhXucVi!\"YyjL                                        \n                          `VmhkuvrHG}VVT)~:_:!           r!`-_                       \n                           `hqf-.-TH3r\"`     !-`r^,`-!:^)kUdE\"                       \n                            -jGhkyY*-        'T!YyTykzGNkxLxv-                       \n,]Vyx!`                                      `\"kKPGHKzhHy)*>'                        \n  `_|fZV*-                           `*\\*~~*LuVkXzXUm3GGx|x`      `<}cc*`            \n     _ryGNm]~-                        `_\"!^**vL}ycVkh5MG}|L:    !V0QMv=r|_``         \n       `\"rumdNbfyLr>!:\",_--_\"\"\",---_!*iwHNNNZxv}XqbNNNNNNNNZX3RQBQQR98QTrrr*.        \n          `\"*ThZNNNNNNNNNNNNNNNNNN9NNNNNNNNNN]VNNNbNNNNdNNNQ#BBBB80N8#@QZc}}^`       \n             `\">vuhMNNNNNNNNNNN6$gENNNNNNR9&NKyZNNNRgd53GbN0#BBB$N60bNRNNNZ3XT!      \n                 .:*]coPbNNNNNN$Q$NNNdNNN$QQ6NNNNN6QR5Xy3bNEdMMENNNbkT5NNNNN60T      \n                    `-:^)YuyX3Z0QNNdMMZdN8QBQRNNN68Q6Z55dbMqqqGqdNNNUy#Ho5NNG3y      \n                         `._=*vc0NZGKa5dEBBBBQQ8QQQ8NNNgGjjjjjx=:yNNNqgBN}`          \n                               ~NZ3kyhq9B03oycuuymdNNN$ZvvxcqU~`  :zN}Q#8:           \n                               }bHk}cmZNcxxxxxxxYVhg9N3!   .V3ZEm, .MZkZ@v           \n                             `rPMKyVhG*-````-L8@@@@@@#x}3yvr:`  r&^ 'cddoX.          \n                            xd#N53Um9r         m####BM   rdGY.  :PV:::,:-      __`   \n                           ^NN#BZ5EQv         -QBQ$N3'   `=^.!>;,.`  `-,\"::\",:r!,~   \n                         ~q68#@@@Dx`          rQ86Nd\"           .=;~-        `x--    \n                        `P9BBbx:`             ~9NNX-                _~;!' -^)*:,\"    \n                        rN6QZ`               `KNNZ_                    `\"x*' -^      \n                        yNgD5^`              XNNNy                       >)``        \n                       .NNg#NQa`             ^qN$N}.                     `:r^        \n                        ZNk#QNQQdx-           !N@#RgQy,-                             \n                       _Zy ,h03o= `           -!G@BNQ@#85T.                          \n                        `      `                :*vxL`)L! '                          \n)\"sv;\n            context.Reporter.Info() << s_ninjaCat << std::endl;\n        }\n        context.Reporter.Info() << Resource::String::ThankYou << std::endl;\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ExperimentalCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"Command.h\"\n#include <winget/UserSettings.h>\n\nnamespace AppInstaller::CLI\n{\n    struct ExperimentalCommand final : public Command\n    {\n        // This command is used as an example on how experimental features can be used.\n        // To enable this command set ExperimentalCmd = true in the settings file.\n        ExperimentalCommand(std::string_view parent) : Command(\"experimental\", {}, parent, Settings::ExperimentalFeature::Feature::ExperimentalCmd) {}\n\n        virtual std::vector<Argument> GetArguments() const override;\n\n        virtual Resource::LocString ShortDescription() const override;\n        virtual Resource::LocString LongDescription() const override;\n\n        Utility::LocIndView HelpLink() const override;\n\n    protected:\n        void ExecuteInternal(Execution::Context& context) const override;\n    };\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ExportCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"ExportCommand.h\"\n#include \"Workflows/CompletionFlow.h\"\n#include \"Workflows/ImportExportFlow.h\"\n#include \"Workflows/WorkflowBase.h\"\n#include \"Resources.h\"\n\nnamespace AppInstaller::CLI\n{\n    using namespace AppInstaller::CLI::Workflow;\n    using namespace std::string_view_literals;\n\n    std::vector<Argument> ExportCommand::GetArguments() const\n    {\n        return {\n            Argument{ Execution::Args::Type::OutputFile, Resource::String::OutputFileArgumentDescription, ArgumentType::Positional, true },\n            Argument{ Execution::Args::Type::Source, Resource::String::ExportSourceArgumentDescription, ArgumentType::Standard },\n            Argument{ Execution::Args::Type::IncludeVersions, Resource::String::ExportIncludeVersionsArgumentDescription, ArgumentType::Flag },\n            Argument::ForType(Execution::Args::Type::AcceptSourceAgreements),\n        };\n    }\n\n    Resource::LocString ExportCommand::ShortDescription() const\n    {\n        return { Resource::String::ExportCommandShortDescription };\n    }\n\n    Resource::LocString ExportCommand::LongDescription() const\n    {\n        return { Resource::String::ExportCommandLongDescription };\n    }\n\n    void ExportCommand::Complete(Execution::Context& context, Execution::Args::Type valueType) const\n    {\n        if (valueType == Execution::Args::Type::OutputFile)\n        {\n            // Intentionally output nothing to allow pass through to filesystem.\n            return;\n        }\n\n        if (valueType == Execution::Args::Type::Source)\n        {\n            context << Workflow::CompleteSourceName;\n            return;\n        }\n    }\n\n    Utility::LocIndView ExportCommand::HelpLink() const\n    {\n        return \"https://aka.ms/winget-command-export\"_liv;\n    }\n\n    void ExportCommand::ExecuteInternal(Execution::Context& context) const\n    {\n        context.SetFlags(Execution::ContextFlag::TreatSourceFailuresAsWarning);\n\n        context <<\n            Workflow::ReportExecutionStage(ExecutionStage::Discovery) <<\n            Workflow::OpenSource() <<\n            Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed) <<\n            Workflow::SearchSourceForMany <<\n            Workflow::HandleSearchResultFailures <<\n            Workflow::EnsureMatchesFromSearchResult(OperationType::Export) <<\n            Workflow::SelectVersionsToExport <<\n            Workflow::ReportExecutionStage(ExecutionStage::Execution) <<\n            Workflow::WriteImportFile;\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ExportCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"Command.h\"\n\nnamespace AppInstaller::CLI\n{\n    // Command to get the set of installed packages on the system.\n    struct ExportCommand final : public Command\n    {\n        ExportCommand(std::string_view parent) : Command(\"export\", parent) {}\n\n        std::vector<Argument> GetArguments() const override;\n\n        Resource::LocString ShortDescription() const override;\n        Resource::LocString LongDescription() const override;\n\n        void Complete(Execution::Context& context, Execution::Args::Type valueType) const override;\n\n        Utility::LocIndView HelpLink() const override;\n\n    protected:\n        void ExecuteInternal(Execution::Context& context) const override;\n    };\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/FeaturesCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"FeaturesCommand.h\"\n#include \"TableOutput.h\"\n#include <winget/UserSettings.h>\n\nnamespace AppInstaller::CLI\n{\n    using namespace Utility::literals;\n    using namespace AppInstaller::Settings;\n\n    Resource::LocString FeaturesCommand::ShortDescription() const\n    {\n        return { Resource::String::FeaturesCommandShortDescription };\n    }\n\n    Resource::LocString FeaturesCommand::LongDescription() const\n    {\n        return { Resource::String::FeaturesCommandLongDescription };\n    }\n\n    Utility::LocIndView FeaturesCommand::HelpLink() const\n    {\n        return \"https://aka.ms/winget-experimentalfeatures\"_liv;\n    }\n\n    void FeaturesCommand::ExecuteInternal(Execution::Context& context) const\n    {\n#ifdef WINGET_DISABLE_EXPERIMENTAL_FEATURES\n        context.Reporter.Info() << Resource::String::FeaturesMessageDisabledByBuild << std::endl;\n#else\n        if (GroupPolicies().IsEnabled(TogglePolicy::Policy::ExperimentalFeatures) &&\n            GroupPolicies().IsEnabled(TogglePolicy::Policy::Settings))\n        {\n            context.Reporter.Info() << Resource::String::FeaturesMessage << std::endl << std::endl;\n        }\n        else\n        {\n            context.Reporter.Info() << Resource::String::FeaturesMessageDisabledByPolicy << std::endl << std::endl;\n        }\n\n        auto features = ExperimentalFeature::GetAllFeatures();\n\n        if (!features.empty())\n        {\n            Execution::TableOutput<4> table(context.Reporter, {\n                Resource::String::FeaturesFeature,\n                Resource::String::FeaturesStatus,\n                Resource::String::FeaturesProperty,\n                Resource::String::FeaturesLink });\n            for (const auto& feature : features)\n            {\n                table.OutputLine({\n                    std::string{ feature.Name() },\n                    Resource::LocString{ ExperimentalFeature::IsEnabled(feature.GetFeature()) ? Resource::String::FeaturesEnabled : Resource::String::FeaturesDisabled},\n                    std::string { feature.JsonName() },\n                    std::string{ feature.Link() } });\n            }\n            table.Complete();\n        }\n        else\n        {\n            // Better work hard to get some out there!\n            context.Reporter.Info() << Resource::String::NoExperimentalFeaturesMessage << std::endl;\n        }\n#endif\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/FeaturesCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"Command.h\"\n#include <winget/UserSettings.h>\n\nnamespace AppInstaller::CLI\n{\n    struct FeaturesCommand final : public Command\n    {\n        // This command outputs all the experimental features that are available, if they are enabled/disabled\n        // and a link to the spec.\n        FeaturesCommand(std::string_view parent) : Command(\"features\", parent) {}\n\n        virtual Resource::LocString ShortDescription() const override;\n        virtual Resource::LocString LongDescription() const override;\n\n        Utility::LocIndView HelpLink() const override;\n\n    protected:\n        void ExecuteInternal(Execution::Context& context) const override;\n    };\n}\n#pragma once\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/FontCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"FontCommand.h\"\n#include \"Workflows/CompletionFlow.h\"\n#include \"Workflows/FontFlow.h\"\n#include \"Workflows/WorkflowBase.h\"\n#include \"Resources.h\"\n\nnamespace AppInstaller::CLI\n{\n    using namespace AppInstaller::CLI::Execution;\n    using namespace AppInstaller::CLI::Workflow;\n    using namespace AppInstaller::Utility::literals;\n    using namespace std::string_view_literals;\n\n    Utility::LocIndView s_FontCommand_HelpLink = \"https://aka.ms/winget-command-font\"_liv;\n\n    // Base Font Command\n\n    std::vector<std::unique_ptr<Command>> FontCommand::GetCommands() const\n    {\n        return InitializeFromMoveOnly<std::vector<std::unique_ptr<Command>>>({\n            std::make_unique<FontListCommand>(FullName()),\n        });\n    }\n\n    Resource::LocString FontCommand::ShortDescription() const\n    {\n        return { Resource::String::FontCommandShortDescription };\n    }\n\n    Resource::LocString FontCommand::LongDescription() const\n    {\n        return { Resource::String::FontCommandLongDescription };\n    }\n\n    Utility::LocIndView FontCommand::HelpLink() const\n    {\n        return s_FontCommand_HelpLink;\n    }\n\n    void FontCommand::ExecuteInternal(Execution::Context& context) const\n    {\n        OutputHelp(context.Reporter);\n    }\n\n    // FontListCommand\n\n    std::vector<Argument> FontListCommand::GetArguments() const\n    {\n        return {\n            Argument::ForType(Args::Type::Family),\n            Argument::ForType(Args::Type::Details),\n        };\n    }\n\n    Resource::LocString FontListCommand::ShortDescription() const\n    {\n        return { Resource::String::FontListCommandShortDescription };\n    }\n\n    Resource::LocString FontListCommand::LongDescription() const\n    {\n        return { Resource::String::FontListCommandLongDescription };\n    }\n\n    void FontListCommand::Complete(Execution::Context& context, Args::Type valueType) const\n    {\n        UNREFERENCED_PARAMETER(valueType);\n        context.Reporter.Error() << Resource::String::PendingWorkError << std::endl;\n        THROW_HR(E_NOTIMPL);\n    }\n\n    Utility::LocIndView FontListCommand::HelpLink() const\n    {\n        return s_FontCommand_HelpLink;\n    }\n\n    void FontListCommand::ExecuteInternal(Execution::Context& context) const\n    {\n        context << Workflow::ReportInstalledFonts;\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/FontCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"Command.h\"\n#include <winget/UserSettings.h>\n\nnamespace AppInstaller::CLI\n{\n    struct FontCommand final : public Command\n    {\n        FontCommand(std::string_view parent) : Command(\"font\", { \"fonts\" }, parent, Settings::ExperimentalFeature::Feature::Font) {}\n\n        std::vector<std::unique_ptr<Command>> GetCommands() const override;\n\n        Resource::LocString ShortDescription() const override;\n        Resource::LocString LongDescription() const override;\n\n        Utility::LocIndView HelpLink() const override;\n\n    protected:\n        void ExecuteInternal(Execution::Context& context) const override;\n    };\n\n    struct FontListCommand final : public Command\n    {\n        FontListCommand(std::string_view parent) : Command(\"list\", parent) {}\n\n        std::vector<Argument> GetArguments() const override;\n\n        Resource::LocString ShortDescription() const override;\n        Resource::LocString LongDescription() const override;\n\n        void Complete(Execution::Context& context, Execution::Args::Type valueType) const override;\n\n        Utility::LocIndView HelpLink() const override;\n\n    protected:\n        void ExecuteInternal(Execution::Context& context) const override;\n    };\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/HashCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"HashCommand.h\"\r\n#include \"Workflows/WorkflowBase.h\"\r\n#include \"Resources.h\"\r\n\r\n#include <AppInstallerMsixInfo.h>\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    using namespace std::string_view_literals;\r\n    using namespace Utility::literals;\r\n\r\n    std::vector<Argument> HashCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument::ForType(Execution::Args::Type::HashFile),\r\n            Argument::ForType(Execution::Args::Type::Msix),\r\n        };\r\n    }\r\n\r\n    Resource::LocString HashCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::HashCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString HashCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::HashCommandLongDescription };\r\n    }\r\n\r\n    Utility::LocIndView HashCommand::HelpLink() const\r\n    {\r\n        return \"https://aka.ms/winget-command-hash\"_liv;\r\n    }\r\n\r\n    void HashCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        context <<\r\n            Workflow::VerifyFile(Execution::Args::Type::HashFile) <<\r\n            [](Execution::Context& context)\r\n        {\r\n            auto inputFile = context.Args.GetArg(Execution::Args::Type::HashFile);\r\n            std::ifstream inStream{ Utility::ConvertToUTF16(inputFile), std::ifstream::binary };\r\n\r\n            context.Reporter.Info() << \"InstallerSha256: \"_liv << Utility::LocIndString{ Utility::SHA256::ConvertToString(Utility::SHA256::ComputeHash(inStream)) } << std::endl;\r\n\r\n            if (context.Args.Contains(Execution::Args::Type::Msix))\r\n            {\r\n                try\r\n                {\r\n                    Msix::MsixInfo msixInfo{ inputFile };\r\n                    auto signatureHash = msixInfo.GetSignatureHash();\r\n\r\n                    context.Reporter.Info() << \"SignatureSha256: \"_liv << Utility::LocIndString{ Utility::SHA256::ConvertToString(signatureHash) } << std::endl;\r\n                }\r\n                catch (const wil::ResultException& re)\r\n                {\r\n                    context.Reporter.Warn() << \r\n                        Resource::String::MsixSignatureHashFailed << std::endl <<\r\n                        Resource::String::VerifyFileSignedMsix << std::endl;\r\n                    AICLI_TERMINATE_CONTEXT(re.GetErrorCode());\r\n                }\r\n            }\r\n        };\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/HashCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Command.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    struct HashCommand final : public Command\r\n    {\r\n        HashCommand(std::string_view parent) : Command(\"hash\", parent) {}\r\n\r\n        virtual std::vector<Argument> GetArguments() const override;\r\n\r\n        virtual Resource::LocString ShortDescription() const override;\r\n        virtual Resource::LocString LongDescription() const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ImportCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"ImportCommand.h\"\r\n#include \"Workflows/DownloadFlow.h\"\n#include \"Workflows/CompletionFlow.h\"\n#include \"Workflows/ImportExportFlow.h\"\n#include \"Workflows/MultiQueryFlow.h\"\n#include \"Workflows/WorkflowBase.h\"\n#include \"Resources.h\"\n\nnamespace AppInstaller::CLI\n{\n    using namespace std::string_view_literals;\n\n    std::vector<Argument> ImportCommand::GetArguments() const\n    {\n        return {\n            Argument{ Execution::Args::Type::ImportFile, Resource::String::ImportFileArgumentDescription, ArgumentType::Positional, true },\n            Argument{ Execution::Args::Type::IgnoreUnavailable, Resource::String::ImportIgnoreUnavailableArgumentDescription, ArgumentType::Flag },\n            Argument{ Execution::Args::Type::IgnoreVersions, Resource::String::ImportIgnorePackageVersionsArgumentDescription, ArgumentType::Flag },\n            Argument::ForType(Execution::Args::Type::NoUpgrade),\n            Argument::ForType(Execution::Args::Type::AcceptPackageAgreements),\n            Argument::ForType(Execution::Args::Type::AcceptSourceAgreements),\n        };\n    }\n\n    Resource::LocString ImportCommand::ShortDescription() const\n    {\n        return { Resource::String::ImportCommandShortDescription };\n    }\n\n    Resource::LocString ImportCommand::LongDescription() const\n    {\n        return { Resource::String::ImportCommandLongDescription };\n    }\n\n    Utility::LocIndView ImportCommand::HelpLink() const\n    {\n        return \"https://aka.ms/winget-command-import\"_liv;\n    }\n\n    void ImportCommand::ExecuteInternal(Execution::Context& context) const\n    {\n        context <<\r\n            Workflow::InitializeInstallerDownloadAuthenticatorsMap <<\n            Workflow::ReportExecutionStage(Workflow::ExecutionStage::Discovery) <<\n            Workflow::VerifyFile(Execution::Args::Type::ImportFile) <<\n            Workflow::ReadImportFile <<\n            Workflow::OpenSourcesForImport <<\n            Workflow::OpenPredefinedSource(Repository::PredefinedSource::Installed) <<\n            Workflow::GetSearchRequestsForImport <<\n            Workflow::SearchSubContextsForSingle() <<\n            Workflow::ReportExecutionStage(Workflow::ExecutionStage::Execution) <<\n            Workflow::InstallImportedPackages;\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ImportCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"Command.h\"\n\nnamespace AppInstaller::CLI\n{\n    // Command to install a set of packages from a list.\n    struct ImportCommand final : public Command\n    {\n        ImportCommand(std::string_view parent) : Command(\"import\", parent) {}\n\n        std::vector<Argument> GetArguments() const override;\n\n        Resource::LocString ShortDescription() const override;\n        Resource::LocString LongDescription() const override;\n\n        Utility::LocIndView HelpLink() const override;\n\n    protected:\n        void ExecuteInternal(Execution::Context& context) const override;\n    };\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/InstallCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"AppInstallerRuntime.h\"\r\n#include \"CheckpointManager.h\"\r\n#include \"InstallCommand.h\"\r\n#include \"Workflows/CompletionFlow.h\"\r\n#include \"Workflows/DownloadFlow.h\"\r\n#include \"Workflows/InstallFlow.h\"\r\n#include \"Workflows/UpdateFlow.h\"\r\n#include \"Workflows/MultiQueryFlow.h\"\r\n#include \"Workflows/ResumeFlow.h\"\r\n#include \"Workflows/WorkflowBase.h\"\r\n#include \"Resources.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    using namespace AppInstaller::CLI::Execution;\r\n    using namespace AppInstaller::CLI::Workflow;\r\n    using namespace AppInstaller::Manifest;\r\n    using namespace AppInstaller::Utility::literals;\r\n\r\n    std::vector<Argument> InstallCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument::ForType(Args::Type::MultiQuery),\r\n            Argument::ForType(Args::Type::Manifest),\r\n            Argument::ForType(Args::Type::Id),\r\n            Argument::ForType(Args::Type::Name),\r\n            Argument::ForType(Args::Type::Moniker),\r\n            Argument::ForType(Args::Type::Version),\r\n            Argument::ForType(Args::Type::Channel),\r\n            Argument::ForType(Args::Type::Source),\r\n            Argument{ Args::Type::InstallScope, Resource::String::InstallScopeDescription, ArgumentType::Standard, Argument::Visibility::Help },\r\n            Argument::ForType(Args::Type::InstallArchitecture),\r\n            Argument::ForType(Args::Type::InstallerType),\r\n            Argument::ForType(Args::Type::Exact),\r\n            Argument::ForType(Args::Type::Interactive),\r\n            Argument::ForType(Args::Type::Silent),\r\n            Argument::ForType(Args::Type::Locale),\r\n            Argument::ForType(Args::Type::Log),\r\n            Argument::ForType(Args::Type::CustomSwitches),\r\n            Argument::ForType(Args::Type::Override),\r\n            Argument::ForType(Args::Type::InstallLocation),\r\n            Argument::ForType(Args::Type::HashOverride),\r\n            Argument::ForType(Args::Type::AllowReboot),\r\n            Argument::ForType(Args::Type::SkipDependencies),\r\n            Argument::ForType(Args::Type::DependenciesOnly),\r\n            Argument::ForType(Args::Type::IgnoreLocalArchiveMalwareScan),\r\n            Argument::ForType(Args::Type::DependencySource),\r\n            Argument::ForType(Args::Type::AcceptPackageAgreements),\r\n            Argument::ForType(Args::Type::NoUpgrade),\r\n            Argument::ForType(Args::Type::CustomHeader),\r\n            Argument::ForType(Args::Type::AuthenticationMode),\r\n            Argument::ForType(Args::Type::AuthenticationAccount),\r\n            Argument::ForType(Args::Type::AcceptSourceAgreements),\r\n            Argument::ForType(Args::Type::Rename),\r\n            Argument::ForType(Args::Type::UninstallPrevious),\r\n            Argument::ForType(Args::Type::Force),\r\n            Argument{ Args::Type::IncludeUnknown, Resource::String::IncludeUnknownArgumentDescription, ArgumentType::Flag, Argument::Visibility::Hidden},\r\n        };\r\n    }\r\n\r\n    Resource::LocString InstallCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::InstallCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString InstallCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::InstallCommandLongDescription };\r\n    }\r\n\r\n    void InstallCommand::Complete(Context& context, Args::Type valueType) const\r\n    {\r\n        switch (valueType)\r\n        {\r\n        case Args::Type::MultiQuery:\r\n        case Args::Type::Manifest:\r\n        case Args::Type::Id:\r\n        case Args::Type::Name:\r\n        case Args::Type::Moniker:\r\n        case Args::Type::Version:\r\n        case Args::Type::Channel:\r\n        case Args::Type::Source:\r\n            context <<\r\n                Workflow::CompleteWithSingleSemanticsForValue(valueType);\r\n            break;\r\n        case Args::Type::InstallArchitecture:\r\n        case Args::Type::Locale:\r\n            // May well move to CompleteWithSingleSemanticsForValue,\r\n            // but for now output nothing.\r\n            context <<\r\n                Workflow::CompleteWithEmptySet;\r\n            break;\r\n        case Args::Type::Log:\r\n        case Args::Type::InstallLocation:\r\n            // Intentionally output nothing to allow pass through to filesystem.\r\n            break;\r\n        }\r\n    }\r\n\r\n    Utility::LocIndView InstallCommand::HelpLink() const\r\n    {\r\n        return \"https://aka.ms/winget-command-install\"_liv;\r\n    }\r\n\r\n    void InstallCommand::ValidateArgumentsInternal(Args& execArgs) const\r\n    {\r\n        Argument::ValidateCommonArguments(execArgs);\r\n    }\r\n\r\n    void InstallCommand::Resume(Context& context) const\r\n    {\r\n        // TODO: Load context data from checkpoint for install command.\r\n        ExecuteInternal(context);\r\n    }\r\n\r\n    void InstallCommand::ExecuteInternal(Context& context) const\r\n    {\r\n        context.SetFlags(ContextFlag::ShowSearchResultsOnPartialFailure);\r\n\r\n        context << InitializeInstallerDownloadAuthenticatorsMap;\r\n\r\n        if (context.Args.Contains(Execution::Args::Type::Manifest))\r\n        {\r\n            context <<\r\n                ReportExecutionStage(ExecutionStage::Discovery) <<\r\n                GetManifestFromArg <<\r\n                SelectInstaller <<\r\n                EnsureApplicableInstaller <<\r\n                Checkpoint(\"PreInstallCheckpoint\", {}) << // TODO: Capture context data\r\n                InstallSinglePackage;\r\n        }\r\n        else\r\n        {\r\n            context <<\r\n                ReportExecutionStage(ExecutionStage::Discovery) <<\r\n                OpenSource();\r\n\r\n            if (!context.Args.Contains(Execution::Args::Type::Force))\r\n            {\r\n                context <<\r\n                    OpenCompositeSource(DetermineInstalledSource(context), false, Repository::CompositeSearchBehavior::AvailablePackages);\r\n            }\r\n\r\n            if (context.Args.Contains(Execution::Args::Type::MultiQuery))\r\n            {\r\n                ProcessMultiplePackages::Flags flags = ProcessMultiplePackages::Flags::None;\r\n                if (Settings::User().Get<Settings::Setting::InstallSkipDependencies>() || context.Args.Contains(Execution::Args::Type::SkipDependencies))\r\n                {\r\n                    flags = ProcessMultiplePackages::Flags::IgnoreDependencies;\r\n                }\r\n                else if (context.Args.Contains(Execution::Args::Type::DependenciesOnly))\r\n                {\r\n                    flags = ProcessMultiplePackages::Flags::DependenciesOnly;\r\n                }\r\n\r\n                context <<\r\n                    GetMultiSearchRequests <<\r\n                    SearchSubContextsForSingle() <<\r\n                    ReportExecutionStage(ExecutionStage::Execution) <<\r\n                    ProcessMultiplePackages(Resource::String::PackageRequiresDependencies, APPINSTALLER_CLI_ERROR_MULTIPLE_INSTALL_FAILED, flags);\r\n            }\r\n            else\r\n            {\r\n                context <<\r\n                    Checkpoint(\"PreInstallCheckpoint\", {}) << // TODO: Capture context data\r\n                    InstallOrUpgradeSinglePackage(OperationType::Install);\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/InstallCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Command.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    struct InstallCommand final : public Command\r\n    {\r\n        InstallCommand(std::string_view parent) : Command(\"install\", { \"add\" }, parent) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        void Complete(Execution::Context& context, Execution::Args::Type valueType) const override;\r\n\r\n        void Resume(Execution::Context& context) const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ValidateArgumentsInternal(Execution::Args& execArgs) const override;\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ListCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ListCommand.h\"\r\n#include \"Workflows/CompletionFlow.h\"\r\n#include \"Workflows/WorkflowBase.h\"\r\n#include \"Resources.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    using namespace AppInstaller::CLI::Workflow;\r\n    using namespace std::string_view_literals;\r\n\r\n    std::vector<Argument> ListCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument::ForType(Execution::Args::Type::Query),\r\n            Argument::ForType(Execution::Args::Type::Id),\r\n            Argument::ForType(Execution::Args::Type::Name),\r\n            Argument::ForType(Execution::Args::Type::Moniker),\r\n            Argument::ForType(Execution::Args::Type::Source),\r\n            Argument::ForType(Execution::Args::Type::Tag),\r\n            Argument::ForType(Execution::Args::Type::Command),\r\n            Argument::ForType(Execution::Args::Type::Count),\r\n            Argument::ForType(Execution::Args::Type::Exact),\r\n            Argument{ Execution::Args::Type::InstallScope, Resource::String::InstalledScopeArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help },\r\n            Argument::ForType(Execution::Args::Type::CustomHeader),\r\n            Argument::ForType(Execution::Args::Type::AuthenticationMode),\r\n            Argument::ForType(Execution::Args::Type::AuthenticationAccount),\r\n            Argument::ForType(Execution::Args::Type::AcceptSourceAgreements),\r\n            Argument{ Execution::Args::Type::Upgrade, Resource::String::UpgradeArgumentDescription, ArgumentType::Flag, Argument::Visibility::Help },\r\n            Argument{ Execution::Args::Type::IncludeUnknown, Resource::String::IncludeUnknownInListArgumentDescription, ArgumentType::Flag },\r\n            Argument{ Execution::Args::Type::IncludePinned, Resource::String::IncludePinnedInListArgumentDescription, ArgumentType::Flag},\r\n            Argument::ForType(Execution::Args::Type::ListDetails),\r\n        };\r\n    }\r\n\r\n    Resource::LocString ListCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::ListCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString ListCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::ListCommandLongDescription };\r\n    }\r\n\r\n    void ListCommand::Complete(Execution::Context& context, Execution::Args::Type valueType) const\r\n    {\r\n        context <<\r\n            Workflow::OpenSource() <<\r\n            Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed);\r\n\r\n        switch (valueType)\r\n        {\r\n        case Execution::Args::Type::Query:\r\n            context <<\r\n                Workflow::RequireCompletionWordNonEmpty <<\r\n                Workflow::SearchSourceForManyCompletion <<\r\n                Workflow::CompleteWithMatchedField;\r\n            break;\r\n        case Execution::Args::Type::Id:\r\n        case Execution::Args::Type::Name:\r\n        case Execution::Args::Type::Moniker:\r\n        case Execution::Args::Type::Source:\r\n        case Execution::Args::Type::Tag:\r\n        case Execution::Args::Type::Command:\r\n            context <<\r\n                Workflow::CompleteWithSingleSemanticsForValueUsingExistingSource(valueType);\r\n            break;\r\n        }\r\n    }\r\n\r\n    Utility::LocIndView ListCommand::HelpLink() const\r\n    {\r\n        return \"https://aka.ms/winget-command-list\"_liv;\r\n    }\r\n\r\n    void ListCommand::ValidateArgumentsInternal(Execution::Args& execArgs) const\r\n    {\r\n        Argument::ValidateArgumentDependency(execArgs, Execution::Args::Type::IncludeUnknown, Execution::Args::Type::Upgrade);\r\n        Argument::ValidateArgumentDependency(execArgs, Execution::Args::Type::IncludePinned, Execution::Args::Type::Upgrade);\r\n    }\r\n\r\n    void ListCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        context.SetFlags(Execution::ContextFlag::TreatSourceFailuresAsWarning);\r\n\r\n        context <<\r\n            Workflow::OpenSource() <<\r\n            Workflow::OpenCompositeSource(Workflow::DetermineInstalledSource(context)) <<\r\n            Workflow::SearchSourceForMany <<\r\n            Workflow::HandleSearchResultFailures <<\r\n            Workflow::EnsureMatchesFromSearchResult(OperationType::List) <<\r\n            Workflow::ReportListResult(context.Args.Contains(Execution::Args::Type::Upgrade));\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ListCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Command.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    // Command to get the set of installed packages on the system.\r\n    struct ListCommand final : public Command\r\n    {\r\n        ListCommand(std::string_view parent) : Command(\"list\", { \"ls\" }, parent) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        void Complete(Execution::Context& context, Execution::Args::Type valueType) const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ValidateArgumentsInternal(Execution::Args& execArgs) const override;\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/McpCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"McpCommand.h\"\r\n#include \"Workflows/MSStoreInstallerHandler.h\"\r\n#include <AppInstallerRuntime.h>\r\n\r\nusing namespace AppInstaller::CLI::Workflow;\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    McpCommand::McpCommand(std::string_view parent) :\r\n        Command(\"mcp\", {}, parent, Settings::TogglePolicy::Policy::McpServer)\r\n    {\r\n    }\r\n\r\n    std::vector<Argument> McpCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument{ Execution::Args::Type::ExtendedFeaturesEnable, Resource::String::ExtendedFeaturesEnableMessage, ArgumentType::Flag, Argument::Visibility::Help },\r\n            Argument{ Execution::Args::Type::ExtendedFeaturesDisable, Resource::String::ExtendedFeaturesDisableMessage, ArgumentType::Flag, Argument::Visibility::Help },\r\n        };\r\n    }\r\n\r\n    Resource::LocString McpCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::McpCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString McpCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::McpCommandLongDescription };\r\n    }\r\n\r\n    Utility::LocIndView McpCommand::HelpLink() const\r\n    {\r\n        return \"https://aka.ms/winget-command-mcp\"_liv;\r\n    }\r\n\r\n    void McpCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        if (context.Args.Contains(Execution::Args::Type::ExtendedFeaturesEnable))\r\n        {\r\n            context <<\r\n                EnableExtendedFeatures;\r\n        }\r\n        else if (context.Args.Contains(Execution::Args::Type::ExtendedFeaturesDisable))\r\n        {\r\n            context <<\r\n                DisableExtendedFeatures;\r\n        }\r\n        else\r\n        {\r\n            context <<\r\n                VerifyIsFullPackage <<\r\n                [](Execution::Context& context)\r\n                {\r\n                    std::filesystem::path exePath = Runtime::GetPathTo(Runtime::PathName::MCPExecutable);\r\n                    std::string jsonCompatiblePath = exePath.u8string();\r\n                    Utility::FindAndReplace(jsonCompatiblePath, \"\\\\\", \"\\\\\\\\\");\r\n\r\n                    context.Reporter.Info() << Resource::String::McpConfigurationPreamble <<\r\n                        R\"(\r\n    \"winget-mcp\": {\r\n        \"type\": \"stdio\",\r\n        \"command\": \")\" << jsonCompatiblePath << R\"(\"\r\n    })\" << std::endl;\r\n                };\r\n        }\r\n    }\r\n\r\n    void McpCommand::ValidateArgumentsInternal(Execution::Args& execArgs) const\r\n    {\r\n        if (execArgs.Contains(Execution::Args::Type::ExtendedFeaturesEnable) ||\r\n            execArgs.Contains(Execution::Args::Type::ExtendedFeaturesDisable))\r\n        {\r\n            if (execArgs.GetArgsCount() > 1)\r\n            {\r\n                throw CommandException(Resource::String::ExtendedFeaturesEnableArgumentError);\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/McpCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Command.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    struct McpCommand final : public Command\r\n    {\r\n        McpCommand(std::string_view parent);\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n        void ValidateArgumentsInternal(Execution::Args& execArgs) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/PinCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"PinCommand.h\"\r\n#include \"Workflows/CompletionFlow.h\"\r\n#include \"Workflows/PinFlow.h\"\r\n#include \"Workflows/WorkflowBase.h\"\r\n#include \"Resources.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    using namespace AppInstaller::CLI::Execution;\r\n    using namespace AppInstaller::CLI::Workflow;\r\n    using namespace AppInstaller::Utility::literals;\r\n    using namespace std::string_view_literals;\r\n\r\n    Utility::LocIndView s_PinCommand_HelpLink = \"https://aka.ms/winget-command-pin\"_liv;\r\n\r\n    std::vector<std::unique_ptr<Command>> PinCommand::GetCommands() const\r\n    {\r\n        return InitializeFromMoveOnly<std::vector<std::unique_ptr<Command>>>({\r\n            std::make_unique<PinAddCommand>(FullName()),\r\n            std::make_unique<PinRemoveCommand>(FullName()),\r\n            std::make_unique<PinListCommand>(FullName()),\r\n            std::make_unique<PinResetCommand>(FullName()),\r\n        });\r\n    }\r\n\r\n    Resource::LocString PinCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::PinCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString PinCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::PinCommandLongDescription };\r\n    }\r\n\r\n    Utility::LocIndView PinCommand::HelpLink() const\r\n    {\r\n        return s_PinCommand_HelpLink;\r\n    }\r\n\r\n    void PinCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        OutputHelp(context.Reporter);\r\n    }\r\n\r\n    std::vector<Argument> PinAddCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument::ForType(Args::Type::Query),\r\n            Argument::ForType(Args::Type::Id),\r\n            Argument::ForType(Args::Type::Name),\r\n            Argument::ForType(Args::Type::Moniker),\r\n            Argument::ForType(Args::Type::Tag),\r\n            Argument::ForType(Args::Type::Command),\r\n            Argument::ForType(Args::Type::Exact),\r\n            Argument{ Args::Type::GatedVersion, Resource::String::GatedVersionArgumentDescription, ArgumentType::Standard },\r\n            Argument::ForType(Args::Type::Source),\r\n            Argument::ForType(Args::Type::CustomHeader),\r\n            Argument::ForType(Args::Type::AuthenticationMode),\r\n            Argument::ForType(Args::Type::AuthenticationAccount),\r\n            Argument::ForType(Args::Type::AcceptSourceAgreements),\r\n            Argument::ForType(Args::Type::Force),\r\n            Argument{ Args::Type::BlockingPin, Resource::String::PinAddBlockingArgumentDescription, ArgumentType::Flag },\r\n            Argument{ Args::Type::PinInstalled, Resource::String::PinInstalledArgumentDescription, ArgumentType::Flag },\r\n        };\r\n    }\r\n\r\n    Resource::LocString PinAddCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::PinAddCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString PinAddCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::PinAddCommandLongDescription };\r\n    }\r\n\r\n    void PinAddCommand::Complete(Execution::Context& context, Args::Type valueType) const\r\n    {\r\n        context <<\r\n            Workflow::OpenSource() <<\r\n            Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed);\r\n\r\n        switch (valueType)\r\n        {\r\n        case Execution::Args::Type::Query:\r\n            context <<\r\n                Workflow::RequireCompletionWordNonEmpty <<\r\n                Workflow::SearchSourceForManyCompletion <<\r\n                Workflow::CompleteWithMatchedField;\r\n            break;\r\n        case Execution::Args::Type::Id:\r\n        case Execution::Args::Type::Name:\r\n        case Execution::Args::Type::Moniker:\r\n        case Execution::Args::Type::Source:\r\n        case Execution::Args::Type::Tag:\r\n        case Execution::Args::Type::Command:\r\n            context <<\r\n                Workflow::CompleteWithSingleSemanticsForValueUsingExistingSource(valueType);\r\n            break;\r\n        }\r\n    }\r\n\r\n    Utility::LocIndView PinAddCommand::HelpLink() const\r\n    {\r\n        return s_PinCommand_HelpLink;\r\n    }\r\n\r\n    void PinAddCommand::ValidateArgumentsInternal(Execution::Args& execArgs) const\r\n    {\r\n        Argument::ValidateCommonArguments(execArgs);\r\n    }\r\n\r\n    void PinAddCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        if (context.Args.Contains(Execution::Args::Type::Id))\r\n        {\r\n            // When we are given an ID, just pin that available package without checking for installed.\r\n            // This helps when there are matching issues, for example due to multiple side-by-side installs.\r\n            context <<\r\n                Workflow::OpenSource();\r\n        }\r\n        else\r\n        {\r\n            // If not working from just ID, try matching a single installed package\r\n            context <<\r\n                Workflow::OpenSource() <<\r\n                Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed);\r\n        }\r\n\r\n        context <<\r\n            Workflow::SearchSourceForSingle <<\r\n            Workflow::HandleSearchResultFailures <<\r\n            Workflow::EnsureOneMatchFromSearchResult(OperationType::Pin) <<\r\n            Workflow::GetInstalledPackageVersion <<\r\n            Workflow::ReportPackageIdentity <<\r\n            Workflow::OpenPinningIndex() <<\r\n            Workflow::AddPin;\r\n    }\r\n\r\n    std::vector<Argument> PinRemoveCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument::ForType(Args::Type::Query),\r\n            Argument::ForType(Args::Type::Id),\r\n            Argument::ForType(Args::Type::Name),\r\n            Argument::ForType(Args::Type::Moniker),\r\n            Argument::ForType(Args::Type::Source),\r\n            Argument::ForType(Args::Type::Tag),\r\n            Argument::ForType(Args::Type::Command),\r\n            Argument::ForType(Args::Type::Exact),\r\n            Argument::ForType(Args::Type::CustomHeader),\r\n            Argument::ForType(Args::Type::AuthenticationMode),\r\n            Argument::ForType(Args::Type::AuthenticationAccount),\r\n            Argument::ForType(Args::Type::AcceptSourceAgreements),\r\n            Argument{ Args::Type::PinInstalled, Resource::String::PinInstalledArgumentDescription, ArgumentType::Flag },\r\n        };\r\n    }\r\n\r\n    Resource::LocString PinRemoveCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::PinRemoveCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString PinRemoveCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::PinRemoveCommandLongDescription };\r\n    }\r\n\r\n    void PinRemoveCommand::Complete(Execution::Context& context, Args::Type valueType) const\r\n    {\r\n        context <<\r\n            Workflow::OpenSource() <<\r\n            Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed);\r\n\r\n        switch (valueType)\r\n        {\r\n        case Execution::Args::Type::Query:\r\n            context <<\r\n                Workflow::RequireCompletionWordNonEmpty <<\r\n                Workflow::SearchSourceForManyCompletion <<\r\n                Workflow::CompleteWithMatchedField;\r\n            break;\r\n        case Execution::Args::Type::Id:\r\n        case Execution::Args::Type::Name:\r\n        case Execution::Args::Type::Moniker:\r\n        case Execution::Args::Type::Source:\r\n        case Execution::Args::Type::Tag:\r\n        case Execution::Args::Type::Command:\r\n            context <<\r\n                Workflow::CompleteWithSingleSemanticsForValueUsingExistingSource(valueType);\r\n            break;\r\n        }\r\n    }\r\n\r\n    Utility::LocIndView PinRemoveCommand::HelpLink() const\r\n    {\r\n        return s_PinCommand_HelpLink;\r\n    }\r\n\r\n    void PinRemoveCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        if (context.Args.Contains(Execution::Args::Type::Id))\r\n        {\r\n            // When we are given an ID, just un-pin that available package without checking for installed.\r\n            // This helps when there are matching issues, for example due to multiple side-by-side installs.\r\n            context <<\r\n                Workflow::OpenSource();\r\n        }\r\n        else\r\n        {\r\n            // If not working from just ID, try matching a single installed package\r\n            context <<\r\n                Workflow::OpenSource() <<\r\n                Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed);\r\n        }\r\n\r\n        context <<\r\n            Workflow::SearchSourceForSingle <<\r\n            Workflow::HandleSearchResultFailures <<\r\n            Workflow::EnsureOneMatchFromSearchResult(OperationType::Pin) <<\r\n            Workflow::GetInstalledPackageVersion <<\r\n            Workflow::ReportPackageIdentity <<\r\n            Workflow::OpenPinningIndex() <<\r\n            Workflow::SearchPin <<\r\n            Workflow::RemovePin;\r\n    }\r\n\r\n    std::vector<Argument> PinListCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument::ForType(Args::Type::Query),\r\n            Argument::ForType(Args::Type::Id),\r\n            Argument::ForType(Args::Type::Name),\r\n            Argument::ForType(Args::Type::Moniker),\r\n            Argument::ForType(Args::Type::Source),\r\n            Argument::ForType(Args::Type::Tag),\r\n            Argument::ForType(Args::Type::Command),\r\n            Argument::ForType(Args::Type::Exact),\r\n            Argument::ForType(Args::Type::CustomHeader),\r\n            Argument::ForType(Args::Type::AuthenticationMode),\r\n            Argument::ForType(Args::Type::AuthenticationAccount),\r\n            Argument::ForType(Args::Type::AcceptSourceAgreements),\r\n        };\r\n    }\r\n\r\n    Resource::LocString PinListCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::PinListCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString PinListCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::PinListCommandLongDescription };\r\n    }\r\n\r\n    void PinListCommand::Complete(Execution::Context& context, Args::Type valueType) const\r\n    {\r\n        context <<\r\n            Workflow::OpenSource() <<\r\n            Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed);\r\n\r\n        switch (valueType)\r\n        {\r\n        case Execution::Args::Type::Query:\r\n            context <<\r\n                Workflow::RequireCompletionWordNonEmpty <<\r\n                Workflow::SearchSourceForManyCompletion <<\r\n                Workflow::CompleteWithMatchedField;\r\n            break;\r\n        case Execution::Args::Type::Id:\r\n        case Execution::Args::Type::Name:\r\n        case Execution::Args::Type::Moniker:\r\n        case Execution::Args::Type::Source:\r\n        case Execution::Args::Type::Tag:\r\n        case Execution::Args::Type::Command:\r\n            context <<\r\n                Workflow::CompleteWithSingleSemanticsForValueUsingExistingSource(valueType);\r\n            break;\r\n        }\r\n    }\r\n\r\n    Utility::LocIndView PinListCommand::HelpLink() const\r\n    {\r\n        return s_PinCommand_HelpLink;\r\n    }\r\n\r\n    void PinListCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        context <<\r\n            Workflow::OpenPinningIndex(/* readOnly */ true) <<\r\n            Workflow::GetAllPins <<\r\n            Workflow::OpenSource() <<\r\n            Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed, false, Repository::CompositeSearchBehavior::AllPackages) <<\r\n            Workflow::ReportPins;\r\n    }\r\n\r\n    std::vector<Argument> PinResetCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument::ForType(Args::Type::Force),\r\n            Argument::ForType(Args::Type::Source),\r\n        };\r\n    }\r\n\r\n    Resource::LocString PinResetCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::PinResetCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString PinResetCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::PinResetCommandLongDescription };\r\n    }\r\n\r\n    Utility::LocIndView PinResetCommand::HelpLink() const\r\n    {\r\n        return s_PinCommand_HelpLink;\r\n    }\r\n\r\n    void PinResetCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n\r\n        if (context.Args.Contains(Execution::Args::Type::Force))\r\n        {\r\n            context <<\r\n                Workflow::OpenPinningIndex() <<\r\n                Workflow::ResetAllPins;\r\n        }\r\n        else\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"--force argument is not present\");\r\n            context.Reporter.Info() << Resource::String::PinResetUseForceArg << std::endl;\r\n\r\n            context <<\r\n                Workflow::OpenPinningIndex(/* readOnly */ true) <<\r\n                Workflow::GetAllPins <<\r\n                Workflow::OpenSource() <<\r\n                Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed) <<\r\n                Workflow::ReportPins;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/PinCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Command.h\"\r\n#include <winget/UserSettings.h>\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    struct PinCommand final : public Command\r\n    {\r\n        PinCommand(std::string_view parent) : Command(\"pin\", {} /* aliases */, parent) {}\r\n\r\n        std::vector<std::unique_ptr<Command>> GetCommands() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n\r\n    struct PinAddCommand final : public Command\r\n    {\r\n        PinAddCommand(std::string_view parent) : Command(\"add\", parent) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        void Complete(Execution::Context& context, Execution::Args::Type valueType) const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ValidateArgumentsInternal(Execution::Args& execArgs) const override;\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n\r\n    struct PinRemoveCommand final : public Command\r\n    {\r\n        PinRemoveCommand(std::string_view parent) : Command(\"remove\", parent) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        void Complete(Execution::Context& context, Execution::Args::Type valueType) const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n\r\n    struct PinListCommand final : public Command\r\n    {\r\n        PinListCommand(std::string_view parent) : Command(\"list\", parent) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        void Complete(Execution::Context& context, Execution::Args::Type valueType) const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n\r\n    struct PinResetCommand final : public Command\r\n    {\r\n        PinResetCommand(std::string_view parent) : Command(\"reset\", parent) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/RepairCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"RepairCommand.h\"\r\n#include \"Workflows/RepairFlow.h\"\r\n#include \"Workflows/CompletionFlow.h\"\r\n#include \"Workflows/DownloadFlow.h\"\r\n#include \"Workflows/InstallFlow.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    using namespace AppInstaller::CLI::Execution;\r\n    using namespace AppInstaller::CLI::Workflow;\r\n\r\n    std::vector<Argument> RepairCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument::ForType(Args::Type::Query),                            // -q\r\n            Argument::ForType(Args::Type::Manifest),                         // -m\r\n            Argument::ForType(Args::Type::Id),                               // -id\r\n            Argument::ForType(Args::Type::Name),                             // -n\r\n            Argument::ForType(Args::Type::Channel),\r\n            Argument::ForType(Args::Type::Moniker),                          // -mn\r\n            Argument::ForType(Args::Type::TargetVersion),                    // -v\r\n            Argument::ForType(Args::Type::ProductCode),\r\n            Argument::ForType(Args::Type::InstallArchitecture),              // -arch\r\n            Argument{ Execution::Args::Type::InstallScope, Resource::String::InstalledScopeArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help },\r\n            Argument::ForType(Args::Type::Source),                           // -s\r\n            Argument::ForType(Args::Type::Interactive),                      // -i\r\n            Argument::ForType(Args::Type::Silent),                           // -h\r\n            Argument::ForType(Args::Type::Log),                              // -o\r\n            Argument::ForType(Args::Type::IgnoreLocalArchiveMalwareScan),    // -ignore-local-archive-malware-scan\r\n            Argument::ForType(Args::Type::AcceptSourceAgreements),           // -accept-source-agreements\r\n            Argument::ForType(Args::Type::AcceptPackageAgreements),\r\n            Argument::ForType(Args::Type::Locale),\r\n            Argument::ForType(Args::Type::CustomHeader),\r\n            Argument::ForType(Args::Type::AuthenticationMode),\r\n            Argument::ForType(Args::Type::AuthenticationAccount),\r\n            Argument::ForType(Args::Type::Force),\r\n            Argument::ForType(Args::Type::HashOverride),\r\n            Argument::ForType(Args::Type::Exact),\r\n        };\r\n    }\r\n\r\n    Resource::LocString RepairCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::RepairCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString RepairCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::RepairCommandLongDescription };\r\n    }\r\n\r\n    void RepairCommand::Complete(Execution::Context& context, Execution::Args::Type valueType) const\r\n    {\r\n        if (valueType == Execution::Args::Type::Manifest ||\r\n            valueType == Execution::Args::Type::Log)\r\n        {\r\n            // Intentionally output nothing to allow pass through to filesystem.\r\n            return;\r\n        }\r\n\r\n        context <<\r\n            Workflow::OpenSource() <<\r\n            Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed);\r\n\r\n        switch (valueType)\r\n        {\r\n        case Execution::Args::Type::Id:\r\n        case Execution::Args::Type::Name:\r\n        case Execution::Args::Type::Moniker:\r\n        case Execution::Args::Type::TargetVersion:\r\n        case Execution::Args::Type::Channel:\r\n        case Execution::Args::Type::Source:\r\n            context <<\r\n                Workflow::CompleteWithSingleSemanticsForValueUsingExistingSource(valueType);\r\n            break;\r\n        }\r\n    }\r\n\r\n    Utility::LocIndView RepairCommand::HelpLink() const\r\n    {\r\n        // TODO: point to the right place\r\n        return \"https://aka.ms/winget-command-repair\"_liv;\r\n    }\r\n\r\n    void RepairCommand::ValidateArgumentsInternal(Execution::Args& execArgs) const\r\n    {\r\n        Argument::ValidateCommonArguments(execArgs);\r\n    }\r\n\r\n    void RepairCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        context.SetFlags(Execution::ContextFlag::InstallerExecutionUseRepair);\r\n\r\n        context <<\r\n            Workflow::InitializeInstallerDownloadAuthenticatorsMap <<\r\n            Workflow::ReportExecutionStage(ExecutionStage::Discovery) <<\r\n            Workflow::OpenSource() <<\r\n            Workflow::OpenCompositeSource(DetermineInstalledSource(context));\r\n\r\n        if (context.Args.Contains(Args::Type::Manifest))\r\n        {\r\n            context <<\r\n                Workflow::GetManifestFromArg <<\r\n                Workflow::ReportManifestIdentity <<\r\n                Workflow::SearchSourceUsingManifest <<\r\n                Workflow::EnsureOneMatchFromSearchResult(OperationType::Repair);\r\n        }\r\n        else\r\n        {\r\n            context <<\r\n                Workflow::SearchSourceForSingle <<\r\n                Workflow::HandleSearchResultFailures <<\r\n                Workflow::EnsureOneMatchFromSearchResult(OperationType::Repair) <<\r\n                Workflow::ReportPackageIdentity;\r\n        }\r\n\r\n        context <<\r\n            Workflow::GetInstalledPackageVersion <<\r\n            Workflow::SelectApplicableInstallerIfNecessary <<\r\n            Workflow::RepairSinglePackage;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/RepairCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Command.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    struct RepairCommand final : public Command\r\n    {\r\n        RepairCommand(std::string_view parent) : Command(\"repair\", { \"fix\" }, parent) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        void Complete(Execution::Context& context, Execution::Args::Type valueType) const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ValidateArgumentsInternal(Execution::Args& execArgs) const override;\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ResumeCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"AppInstallerRuntime.h\"\n#include \"Resources.h\"\n#include \"ResumeCommand.h\"\n#include \"RootCommand.h\"\n#include \"CheckpointManager.h\"\n#include \"Workflows/ResumeFlow.h\"\n\nusing namespace AppInstaller::Checkpoints;\n\nnamespace AppInstaller::CLI\n{\n    namespace\n    {\n        std::unique_ptr<Command> FindCommandToResume(const std::string& commandFullName)\n        {\n            std::unique_ptr<Command> commandToResume = std::make_unique<RootCommand>();\n\n            for (const auto& commandPart : Utility::Split(commandFullName, ':'))\n            {\n                bool commandFound = false;\n                if (Utility::CaseInsensitiveEquals(commandPart, commandToResume->Name()))\n                {\n                    // Since we always expect to start at the 'root' command, skip and check the next command part. \n                    continue;\n                }\n\n                for (auto& command : commandToResume->GetCommands())\n                {\n                    if (Utility::CaseInsensitiveEquals(commandPart, command->Name()))\n                    {\n                        commandFound = true;\n                        commandToResume = std::move(command);\n                        break;\n                    }\n                }\n\n                if (!commandFound)\n                {\n                    THROW_HR_MSG(E_UNEXPECTED, \"Command to resume not found.\");\n                }\n            }\n\n            return std::move(commandToResume);\n        }\n    }\n\n    using namespace std::string_view_literals;\n    using namespace Execution;\n\n    std::vector<Argument> ResumeCommand::GetArguments() const\n    {\n        return {\n            Argument::ForType(Execution::Args::Type::ResumeId),\n            Argument::ForType(Execution::Args::Type::IgnoreResumeLimit),\n        };\n    }\n\n    Resource::LocString ResumeCommand::ShortDescription() const\n    {\n        return { Resource::String::ResumeCommandShortDescription };\n    }\n\n    Resource::LocString ResumeCommand::LongDescription() const\n    {\n        return { Resource::String::ResumeCommandLongDescription };\n    }\n\n    Utility::LocIndView ResumeCommand::HelpLink() const\n    {\n        return \"https://aka.ms/winget-command-resume\"_liv;\n    }\n\n    void ResumeCommand::ExecuteInternal(Execution::Context& context) const\n    {\n        const auto& resumeId = context.Args.GetArg(Execution::Args::Type::ResumeId);\n\n        if (!std::filesystem::exists(Checkpoints::CheckpointManager::GetCheckpointDatabasePath(resumeId)))\n        {\n            context.Reporter.Error() << Resource::String::ResumeIdNotFoundError(Utility::LocIndView{ resumeId }) << std::endl;\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_RESUME_ID_NOT_FOUND);\n        }\n\n        Execution::Context resumeContext = context.CreateEmptyContext();\n        std::optional<Checkpoint<AutomaticCheckpointData>> foundAutomaticCheckpoint = resumeContext.LoadCheckpoint(std::string{ resumeId });\n        if (!foundAutomaticCheckpoint.has_value())\n        {\n            context.Reporter.Error() << Resource::String::ResumeStateDataNotFoundError << std::endl;\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_INVALID_RESUME_STATE);\n        }\n\n        Checkpoint<AutomaticCheckpointData> automaticCheckpoint = foundAutomaticCheckpoint.value();\n\n        const auto& checkpointClientVersion = automaticCheckpoint.Get(AutomaticCheckpointData::ClientVersion, {});\n        if (checkpointClientVersion != AppInstaller::Runtime::GetClientVersion().get())\n        {\n            context.Reporter.Error() << Resource::String::ClientVersionMismatchError(Utility::LocIndView{ checkpointClientVersion }) << std::endl;\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_CLIENT_VERSION_MISMATCH);\n        }\n\n        const auto& resumeCountString = automaticCheckpoint.Get(AutomaticCheckpointData::ResumeCount, {});\n        int resumeCount = std::stoi(resumeCountString);\n        if (!context.Args.Contains(Execution::Args::Type::IgnoreResumeLimit) && resumeCount >= Settings::User().Get<Settings::Setting::MaxResumes>())\n        {\n            std::string manualResumeString = \"winget resume -g \" + std::string{ resumeId } + \" --ignore-resume-limit\";\n            context.Reporter.Error() << Resource::String::ResumeLimitExceeded(Utility::LocIndView{ resumeCountString }) << Utility::LocIndView{ manualResumeString } << std::endl;\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_RESUME_LIMIT_EXCEEDED);\n        }\n        else\n        {\n            automaticCheckpoint.Update(AutomaticCheckpointData::ResumeCount, {}, std::to_string(resumeCount + 1));\n        }\n\n        const auto& checkpointCommand = automaticCheckpoint.Get(AutomaticCheckpointData::Command, {});\n        AICLI_LOG(CLI, Info, << \"Resuming command: \" << checkpointCommand);\n        std::unique_ptr<Command> commandToResume = FindCommandToResume(checkpointCommand);\n\n        LoadCommandArgsFromAutomaticCheckpoint(resumeContext, automaticCheckpoint);\n\n        resumeContext.SetExecutingCommand(commandToResume.get());\n\n        // TODO: Ensure telemetry is properly handled for resume context.\n        resumeContext.SetFlags(Execution::ContextFlag::Resume);\n\n        auto previousThreadGlobals = resumeContext.SetForCurrentThread();\n        resumeContext.EnableSignalTerminationHandler();\n        commandToResume->Resume(resumeContext);\n        context.SetTerminationHR(resumeContext.GetTerminationHR());\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ResumeCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"Command.h\"\n\nnamespace AppInstaller::CLI\n{\n    struct ResumeCommand final : public Command\n    {\n        ResumeCommand(std::string_view parent) : Command(\"resume\", {}, parent, Visibility::Hidden, Settings::ExperimentalFeature::Feature::Resume) {}\n\n        std::vector<Argument> GetArguments() const override;\n\n        Resource::LocString ShortDescription() const override;\n        Resource::LocString LongDescription() const override;\n\n        Utility::LocIndView HelpLink() const override;\n\n    protected:\n        void ExecuteInternal(Execution::Context& context) const override;\n    };\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/RootCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"RootCommand.h\"\r\n#include <AppInstallerRuntime.h>\r\n\r\n#include \"InstallCommand.h\"\r\n#include \"ShowCommand.h\"\r\n#include \"SourceCommand.h\"\r\n#include \"SearchCommand.h\"\r\n#include \"ListCommand.h\"\r\n#include \"UpgradeCommand.h\"\r\n#include \"UninstallCommand.h\"\r\n#include \"HashCommand.h\"\r\n#include \"ValidateCommand.h\"\r\n#include \"SettingsCommand.h\"\r\n#include \"FeaturesCommand.h\"\r\n#include \"FontCommand.h\"\r\n#include \"ExperimentalCommand.h\"\r\n#include \"CompleteCommand.h\"\r\n#include \"ExportCommand.h\"\r\n#include \"ImportCommand.h\"\r\n#include \"PinCommand.h\"\r\n#include \"ConfigureCommand.h\"\r\n#include \"DebugCommand.h\"\r\n#include \"TestCommand.h\"\r\n#include \"DownloadCommand.h\"\r\n#include \"ErrorCommand.h\"\r\n#include \"ResumeCommand.h\"\r\n#include \"RepairCommand.h\"\r\n#include \"DscCommand.h\"\r\n#include \"McpCommand.h\"\r\n\r\n#include \"Resources.h\"\r\n#include \"TableOutput.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    using namespace AppInstaller::Utility::literals;\r\n    using namespace Settings;\r\n\r\n    namespace\r\n    {\r\n        void OutputGroupPolicySourceList(Execution::Context& context, const std::vector<Settings::SourceFromPolicy>& sources, Resource::StringId header)\r\n        {\r\n            Execution::TableOutput<3> sourcesTable{ context.Reporter, { header, Resource::String::SourceListType, Resource::String::SourceListArg } };\r\n            for (const auto& source : sources)\r\n            {\r\n                sourcesTable.OutputLine({ source.Name, source.Type, source.Arg });\r\n            }\r\n\r\n            sourcesTable.Complete();\r\n        }\r\n\r\n        void OutputGroupPolicies(Execution::Context& context)\r\n        {\r\n            const auto& groupPolicies = Settings::GroupPolicies();\r\n\r\n            // Get the state of policies that are a simple enabled/disabled toggle\r\n            std::map<Settings::TogglePolicy::Policy, Settings::PolicyState> activePolicies;\r\n            for (const auto& togglePolicy : Settings::TogglePolicy::GetAllPolicies())\r\n            {\r\n                auto state = groupPolicies.GetState(togglePolicy.GetPolicy());\r\n                if (state != Settings::PolicyState::NotConfigured)\r\n                {\r\n                    activePolicies[togglePolicy.GetPolicy()] = state;\r\n                }\r\n            }\r\n\r\n            // The source update interval is the only ValuePolicy that is not gated by a TogglePolicy.\r\n            // We need to output the table if there is a TogglePolicy configured or if this one is configured.\r\n            // We can rework this when more policies are added.\r\n            auto sourceAutoUpdateIntervalPolicy = groupPolicies.GetValue<Settings::ValuePolicy::SourceAutoUpdateIntervalInMinutes>();\r\n\r\n            if (!activePolicies.empty() || sourceAutoUpdateIntervalPolicy.has_value())\r\n            {\r\n                auto info = context.Reporter.Info();\r\n                info << std::endl;\r\n\r\n                Execution::TableOutput<2> policiesTable{ context.Reporter, { Resource::String::PoliciesPolicy, Resource::String::StateHeader } };\r\n\r\n                // Output the toggle policies.\r\n                for (const auto& activePolicy : activePolicies)\r\n                {\r\n                    auto policy = Settings::TogglePolicy::GetPolicy(activePolicy.first);\r\n                    policiesTable.OutputLine({\r\n                        Resource::LocString{ policy.PolicyName() }.get(),\r\n                        Resource::LocString{ activePolicy.second == Settings::PolicyState::Enabled ? Resource::String::StateEnabled : Resource::String::StateDisabled }.get() });\r\n                }\r\n\r\n                // Output the update interval in the same table if needed.\r\n                if (sourceAutoUpdateIntervalPolicy.has_value())\r\n                {\r\n                    policiesTable.OutputLine({\r\n                        Resource::LocString{ AppInstaller::StringResource::String::PolicySourceAutoUpdateInterval },\r\n                        std::to_string(sourceAutoUpdateIntervalPolicy.value()) });\r\n                }\r\n\r\n                policiesTable.Complete();\r\n\r\n                // Output the additional and allowed sources as separate tables.\r\n                if (groupPolicies.GetState(Settings::TogglePolicy::Policy::AdditionalSources) == Settings::PolicyState::Enabled)\r\n                {\r\n                    info << std::endl;\r\n                    auto sources = groupPolicies.GetValueRef<Settings::ValuePolicy::AdditionalSources>();\r\n                    if (sources.has_value() && !sources->get().empty())\r\n                    {\r\n                        OutputGroupPolicySourceList(context, sources->get(), Resource::String::SourceListAdditionalSource);\r\n                    }\r\n                }\r\n\r\n                if (groupPolicies.GetState(Settings::TogglePolicy::Policy::AllowedSources) == Settings::PolicyState::Enabled)\r\n                {\r\n                    info << std::endl;\r\n                    auto sources = groupPolicies.GetValueRef<Settings::ValuePolicy::AllowedSources>();\r\n                    if (sources.has_value() && !sources->get().empty())\r\n                    {\r\n                        OutputGroupPolicySourceList(context, sources->get(), Resource::String::SourceListAllowedSource);\r\n                    }\r\n                }\r\n                info << std::endl;\r\n            }\r\n        }\r\n\r\n        void OutputAdminSettings(Execution::Context& context)\r\n        {\r\n            Execution::TableOutput<2> adminSettingsTable{ context.Reporter, { Resource::String::AdminSettingHeader, Resource::String::StateHeader } };\r\n\r\n            // Output the admin settings.\r\n            for (const auto& setting : Settings::GetAllBoolAdminSettings())\r\n            {\r\n                adminSettingsTable.OutputLine({\r\n                    std::string{ AdminSettingToString(setting)},\r\n                    Resource::LocString{ IsAdminSettingEnabled(setting) ? Resource::String::StateEnabled : Resource::String::StateDisabled }\r\n                });\r\n            }\r\n            for (const auto& setting : Settings::GetAllStringAdminSettings())\r\n            {\r\n                auto settingValue = GetAdminSetting(setting);\r\n                adminSettingsTable.OutputLine({\r\n                    std::string{ AdminSettingToString(setting)},\r\n                    settingValue ? Utility::LocIndString{ settingValue.value() } : Resource::LocString{ Resource::String::StateDisabled }\r\n                    });\r\n            }\r\n            adminSettingsTable.Complete();\r\n        }\r\n\r\n        void OutputKeyDirectories(Execution::Context& context)\r\n        {\r\n            Execution::TableOutput<2> keyDirectories{ context.Reporter, { Resource::String::KeyDirectoriesHeader, {} } };\r\n            keyDirectories.OutputLine({ Resource::LocString{ Resource::String::Logs }, Runtime::GetPathTo(Runtime::PathName::DefaultLogLocation, true).u8string() });\r\n            keyDirectories.OutputLine({ Resource::LocString{ Resource::String::UserSettings }, UserSettings::SettingsFilePath(true).u8string() });\r\n            keyDirectories.OutputLine({ Resource::LocString{ Resource::String::PortableLinksUser }, Runtime::GetPathTo(Runtime::PathName::PortableLinksUserLocation, true).u8string() });\r\n            keyDirectories.OutputLine({ Resource::LocString{ Resource::String::PortableLinksMachine }, Runtime::GetPathTo(Runtime::PathName::PortableLinksMachineLocation, true).u8string() });\r\n            keyDirectories.OutputLine({ Resource::LocString{ Resource::String::PortableRootUser }, Runtime::GetPathTo(Runtime::PathName::PortablePackageUserRoot, true).u8string() });\r\n            keyDirectories.OutputLine({ Resource::LocString{ Resource::String::PortableRoot }, Runtime::GetPathTo(Runtime::PathName::PortablePackageMachineRoot, true).u8string() });\r\n            keyDirectories.OutputLine({ Resource::LocString{ Resource::String::PortableRoot86 }, Runtime::GetPathTo(Runtime::PathName::PortablePackageMachineRootX86, true).u8string() });\r\n            keyDirectories.OutputLine({ Resource::LocString{ Resource::String::InstallerDownloads }, Runtime::GetPathTo(Runtime::PathName::UserProfileDownloads, true).u8string() });\r\n            keyDirectories.OutputLine({ Resource::LocString{ Resource::String::ConfigurationModules }, Runtime::GetPathTo(Runtime::PathName::ConfigurationModules, true).u8string() });\r\n            keyDirectories.Complete();\r\n            context.Reporter.Info() << std::endl;\r\n        }\r\n\r\n        void OutputLinks(Execution::Context& context)\r\n        {\r\n            Execution::TableOutput<2> links{ context.Reporter, { Resource::String::Links, {} } };\r\n            links.OutputLine({ Resource::LocString{ Resource::String::PrivacyStatement }, \"https://aka.ms/winget-privacy\" });\r\n            links.OutputLine({ Resource::LocString{ Resource::String::LicenseAgreement }, \"https://aka.ms/winget-license\" });\r\n            links.OutputLine({ Resource::LocString{ Resource::String::ThirdPartSoftwareNotices }, \"https://aka.ms/winget-3rdPartyNotice\" });\r\n            links.OutputLine({ Resource::LocString{ Resource::String::MainHomepage }, \"https://aka.ms/winget\" });\r\n            links.OutputLine({ Resource::LocString{ Resource::String::WindowsStoreTerms }, \"https://www.microsoft.com/en-us/storedocs/terms-of-sale\" });\r\n            links.Complete();\r\n            context.Reporter.Info() << std::endl;\r\n        }\r\n    }\r\n\r\n    std::vector<std::unique_ptr<Command>> RootCommand::GetCommands() const\r\n    {\r\n        return InitializeFromMoveOnly<std::vector<std::unique_ptr<Command>>>({\r\n            std::make_unique<InstallCommand>(FullName()),\r\n            std::make_unique<ShowCommand>(FullName()),\r\n            std::make_unique<SourceCommand>(FullName()),\r\n            std::make_unique<SearchCommand>(FullName()),\r\n            std::make_unique<ListCommand>(FullName()),\r\n            std::make_unique<UpgradeCommand>(FullName()),\r\n            std::make_unique<UninstallCommand>(FullName()),\r\n            std::make_unique<HashCommand>(FullName()),\r\n            std::make_unique<ValidateCommand>(FullName()),\r\n            std::make_unique<SettingsCommand>(FullName()),\r\n            std::make_unique<FeaturesCommand>(FullName()),\r\n            std::make_unique<ExperimentalCommand>(FullName()),\r\n            std::make_unique<CompleteCommand>(FullName()),\r\n            std::make_unique<ExportCommand>(FullName()),\r\n            std::make_unique<ImportCommand>(FullName()),\r\n            std::make_unique<PinCommand>(FullName()),\r\n            std::make_unique<ConfigureCommand>(FullName()),\r\n            std::make_unique<DownloadCommand>(FullName()),\r\n            std::make_unique<ErrorCommand>(FullName()),\r\n            std::make_unique<ResumeCommand>(FullName()),\r\n            std::make_unique<RepairCommand>(FullName()),\r\n            std::make_unique<FontCommand>(FullName()),\r\n            std::make_unique<DscCommand>(FullName()),\r\n            std::make_unique<McpCommand>(FullName()),\r\n#if _DEBUG\r\n            std::make_unique<DebugCommand>(FullName()),\r\n#endif\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n            std::make_unique<TestCommand>(FullName()),\r\n#endif\r\n        });\r\n    }\r\n\r\n    std::vector<Argument> RootCommand::GetArguments() const\r\n    {\r\n        return\r\n        {\r\n            Argument{ Execution::Args::Type::ToolVersion, Resource::String::ToolVersionArgumentDescription, ArgumentType::Flag, Argument::Visibility::Help },\r\n            Argument{ Execution::Args::Type::Info, Resource::String::ToolInfoArgumentDescription, ArgumentType::Flag, Argument::Visibility::Help },\r\n        };\r\n    }\r\n\r\n    Resource::LocString RootCommand::ShortDescription() const\r\n    {\r\n        return {};\r\n    }\r\n\r\n    Resource::LocString RootCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::ToolDescription };\r\n    }\r\n\r\n    Utility::LocIndView RootCommand::HelpLink() const\r\n    {\r\n        return \"https://aka.ms/winget-command-help\"_liv;\r\n    }\r\n\r\n    void RootCommand::Execute(Execution::Context& context) const\r\n    {\r\n        AICLI_LOG(CLI, Info, << \"Executing command: \" << Name());\r\n        if (context.Args.Contains(Execution::Args::Type::Help))\r\n        {\r\n            OutputHelp(context.Reporter);\r\n        }\r\n        else\r\n        {\r\n            ExecuteInternal(context);\r\n        }\r\n\r\n        if (context.Args.Contains(Execution::Args::Type::OpenLogs))\r\n        {\r\n            ShellExecute(NULL, NULL, Runtime::GetPathTo(Runtime::PathName::DefaultLogLocation).wstring().c_str(), NULL, NULL, SW_SHOWNORMAL);\r\n        }\r\n\r\n        if (context.Args.Contains(Execution::Args::Type::Wait))\r\n        {\r\n            context.Reporter.PromptForEnter();\r\n        }\r\n    }\r\n\r\n    void RootCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        if (context.Args.Contains(Execution::Args::Type::Info))\r\n        {\r\n            OutputIntroHeader(context.Reporter);\r\n\r\n            auto info = context.Reporter.Info();\r\n\r\n            info << std::endl <<\r\n                \"Windows: \"_liv << Runtime::GetOSVersion() << std::endl;\r\n\r\n            info << Resource::String::SystemArchitecture(Utility::ToString(Utility::GetSystemArchitecture())) << std::endl;\r\n\r\n            if (Runtime::IsRunningInPackagedContext())\r\n            {\r\n                info << Resource::String::Package(Runtime::GetPackageVersion()) << std::endl;\r\n            };\r\n\r\n            info << std::endl;\r\n\r\n            OutputKeyDirectories(context);\r\n            OutputLinks(context);\r\n            OutputGroupPolicies(context);\r\n            OutputAdminSettings(context);\r\n        }\r\n        else if (context.Args.Contains(Execution::Args::Type::ToolVersion))\r\n        {\r\n            context.Reporter.Info() << 'v' << Runtime::GetClientVersion() << std::endl;\r\n        }\r\n        else\r\n        {\r\n            OutputHelp(context.Reporter);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/RootCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Command.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    struct RootCommand final : public Command\r\n    {\r\n        constexpr static std::string_view CommandName = \"root\"sv;\r\n\r\n        RootCommand() : Command(CommandName, {}) {}\r\n\r\n        std::vector<std::unique_ptr<Command>> GetCommands() const override;\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n        void Execute(Execution::Context& context) const override;\r\n\r\n    protected:\r\n        virtual void ExecuteInternal(Execution::Context& context) const;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/SearchCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"SearchCommand.h\"\r\n#include \"Workflows/CompletionFlow.h\"\r\n#include \"Workflows/WorkflowBase.h\"\r\n#include \"Resources.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    using namespace AppInstaller::CLI::Execution;\r\n    using namespace AppInstaller::CLI::Workflow;\r\n    using namespace std::string_view_literals;\r\n\r\n    std::vector<Argument> SearchCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument::ForType(Execution::Args::Type::Query),\r\n            Argument::ForType(Execution::Args::Type::Id),\r\n            Argument::ForType(Execution::Args::Type::Name),\r\n            Argument::ForType(Execution::Args::Type::Moniker),\r\n            Argument::ForType(Execution::Args::Type::Tag),\r\n            Argument::ForType(Execution::Args::Type::Command),\r\n            Argument::ForType(Execution::Args::Type::Source),\r\n            Argument::ForType(Execution::Args::Type::Count),\r\n            Argument::ForType(Execution::Args::Type::Exact),\r\n            Argument::ForType(Execution::Args::Type::CustomHeader),\r\n            Argument::ForType(Execution::Args::Type::AuthenticationMode),\r\n            Argument::ForType(Execution::Args::Type::AuthenticationAccount),\r\n            Argument::ForType(Execution::Args::Type::AcceptSourceAgreements),\r\n            Argument::ForType(Execution::Args::Type::ListVersions),\r\n        };\r\n    }\r\n\r\n    Resource::LocString SearchCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::SearchCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString SearchCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::SearchCommandLongDescription };\r\n    }\r\n\r\n    void SearchCommand::Complete(Execution::Context& context, Execution::Args::Type valueType) const\r\n    {\r\n        switch (valueType)\r\n        {\r\n        case Execution::Args::Type::Query:\r\n            context <<\r\n                Workflow::OpenSource() <<\r\n                Workflow::RequireCompletionWordNonEmpty <<\r\n                Workflow::SearchSourceForManyCompletion <<\r\n                Workflow::CompleteWithMatchedField;\r\n            break;\r\n        case Execution::Args::Type::Id:\r\n        case Execution::Args::Type::Name:\r\n        case Execution::Args::Type::Moniker:\r\n        case Execution::Args::Type::Tag:\r\n        case Execution::Args::Type::Command:\r\n        case Execution::Args::Type::Source:\r\n            context <<\r\n                Workflow::CompleteWithSingleSemanticsForValue(valueType);\r\n            break;\r\n        }\r\n    }\r\n\r\n    Utility::LocIndView SearchCommand::HelpLink() const\r\n    {\r\n        return \"https://aka.ms/winget-command-search\"_liv;\r\n    }\r\n\r\n    void SearchCommand::ValidateArgumentsInternal(Args& execArgs) const\r\n    {\r\n        Argument::ValidateCommonArguments(execArgs);\r\n    }\r\n\r\n    void SearchCommand::ExecuteInternal(Context& context) const\r\n    {\r\n        context.SetFlags(Execution::ContextFlag::TreatSourceFailuresAsWarning);\r\n\r\n        context <<\r\n            Workflow::OpenSource() <<\r\n            Workflow::SearchSourceForMany <<\r\n            Workflow::HandleSearchResultFailures;\r\n\r\n            if (context.Args.Contains(Execution::Args::Type::ListVersions))\r\n            {\r\n                context <<\r\n                Workflow::EnsureOneMatchFromSearchResult(OperationType::Search) <<\r\n                Workflow::ReportPackageIdentity <<\r\n                Workflow::ShowAppVersions;\r\n            }\r\n            else\r\n            {\r\n                context << \r\n                    Workflow::EnsureMatchesFromSearchResult(OperationType::Search) <<\r\n                    Workflow::ReportSearchResult;\r\n            }\r\n        \r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/SearchCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Command.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n\r\n    struct SearchCommand final : public Command\r\n    {\r\n        SearchCommand(std::string_view parent) : Command(\"search\", { \"find\" }, parent) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        void Complete(Execution::Context& context, Execution::Args::Type valueType) const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ValidateArgumentsInternal(Execution::Args& execArgs) const override;\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/SettingsCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"SettingsCommand.h\"\r\n#include \"Workflows/WorkflowBase.h\"\r\n#include \"Workflows/SettingsFlow.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    using namespace Utility::literals;\r\n    using namespace AppInstaller::Settings;\r\n    using namespace std::string_view_literals;\r\n\r\n    namespace\r\n    {\r\n        Utility::LocIndView s_SettingsCommand_HelpLink = \"https://aka.ms/winget-settings\"_liv;\r\n    }\r\n\r\n    std::vector<std::unique_ptr<Command>> SettingsCommand::GetCommands() const\r\n    {\r\n        return InitializeFromMoveOnly<std::vector<std::unique_ptr<Command>>>({\r\n            std::make_unique<SettingsExportCommand>(FullName()),\r\n            std::make_unique<SettingsSetCommand>(FullName()),\r\n            std::make_unique<SettingsResetCommand>(FullName()),\r\n            });\r\n    }\r\n\r\n    std::vector<Argument> SettingsCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument{ Execution::Args::Type::AdminSettingEnable, Resource::String::AdminSettingEnableDescription, ArgumentType::Standard, Argument::Visibility::Help },\r\n            Argument{ Execution::Args::Type::AdminSettingDisable, Resource::String::AdminSettingDisableDescription, ArgumentType::Standard, Argument::Visibility::Help },\r\n        };\r\n    }\r\n\r\n    Resource::LocString SettingsCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::SettingsCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString SettingsCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::SettingsCommandLongDescription };\r\n    }\r\n\r\n    Utility::LocIndView SettingsCommand::HelpLink() const\r\n    {\r\n        return s_SettingsCommand_HelpLink;\r\n    }\r\n\r\n    void SettingsCommand::ValidateArgumentsInternal(Execution::Args& execArgs) const\r\n    {\r\n        // Get admin setting string for all available options except Unknown\r\n        std::vector<Utility::LocIndString> adminSettingList;\r\n        for (auto setting : GetAllSequentialEnumValues(BoolAdminSetting::Unknown))\r\n        {\r\n            adminSettingList.emplace_back(AdminSettingToString(setting));\r\n        }\r\n\r\n        Utility::LocIndString validOptions = Join(\", \"_liv, adminSettingList);\r\n\r\n        if (execArgs.Contains(Execution::Args::Type::AdminSettingEnable) && BoolAdminSetting::Unknown == StringToBoolAdminSetting(execArgs.GetArg(Execution::Args::Type::AdminSettingEnable)))\r\n        {\r\n            throw CommandException(Resource::String::InvalidArgumentValueError(ArgumentCommon::ForType(Execution::Args::Type::AdminSettingEnable).Name, validOptions));\r\n        }\r\n\r\n        if (execArgs.Contains(Execution::Args::Type::AdminSettingDisable) && BoolAdminSetting::Unknown == StringToBoolAdminSetting(execArgs.GetArg(Execution::Args::Type::AdminSettingDisable)))\r\n        {\r\n            throw CommandException(Resource::String::InvalidArgumentValueError(ArgumentCommon::ForType(Execution::Args::Type::AdminSettingDisable).Name, validOptions));\r\n        }\r\n    }\r\n\r\n    void SettingsCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        if (context.Args.Contains(Execution::Args::Type::AdminSettingEnable))\r\n        {\r\n            context <<\r\n                Workflow::EnsureRunningAsAdmin <<\r\n                Workflow::EnableAdminSetting;\r\n\r\n        }\r\n        else if (context.Args.Contains(Execution::Args::Type::AdminSettingDisable))\r\n        {\r\n            context <<\r\n                Workflow::EnsureRunningAsAdmin <<\r\n                Workflow::DisableAdminSetting;\r\n        }\r\n        else\r\n        {\r\n            context << Workflow::OpenUserSetting;\r\n        }\r\n    }\r\n\r\n    Resource::LocString SettingsExportCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::SettingsExportCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString SettingsExportCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::SettingsExportCommandLongDescription };\r\n    }\r\n\r\n    Utility::LocIndView SettingsExportCommand::HelpLink() const\r\n    {\r\n        return s_SettingsCommand_HelpLink;\r\n    }\r\n\r\n    void SettingsExportCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        context <<\r\n            Workflow::ExportSettings;\r\n    }\r\n\r\n    std::vector<Argument> SettingsSetCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument { Execution::Args::Type::SettingName, Resource::String::SettingNameArgumentDescription, ArgumentType::Positional, true },\r\n            Argument { Execution::Args::Type::SettingValue, Resource::String::SettingValueArgumentDescription, ArgumentType::Positional, true },\r\n        };\r\n    }\r\n\r\n    Resource::LocString SettingsSetCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::SettingsSetCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString SettingsSetCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::SettingsSetCommandLongDescription };\r\n    }\r\n\r\n    Utility::LocIndView SettingsSetCommand::HelpLink() const\r\n    {\r\n        return s_SettingsCommand_HelpLink;\r\n    }\r\n\r\n    void SettingsSetCommand::ValidateArgumentsInternal(Execution::Args& execArgs) const\r\n    {\r\n        // Get admin setting string for all available options except Unknown\r\n        std::vector<Utility::LocIndString> adminSettingList;\r\n        for (auto setting : GetAllSequentialEnumValues(StringAdminSetting::Unknown))\r\n        {\r\n            adminSettingList.emplace_back(AdminSettingToString(setting));\r\n        }\r\n\r\n        Utility::LocIndString validOptions = Join(\", \"_liv, adminSettingList);\r\n\r\n        if (StringAdminSetting::Unknown == StringToStringAdminSetting(execArgs.GetArg(Execution::Args::Type::SettingName)))\r\n        {\r\n            throw CommandException(Resource::String::InvalidArgumentValueError(ArgumentCommon::ForType(Execution::Args::Type::SettingName).Name, validOptions));\r\n        }\r\n    }\r\n\r\n    void SettingsSetCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        context <<\r\n            Workflow::EnsureRunningAsAdmin <<\r\n            Workflow::SetAdminSetting;\r\n    }\r\n\r\n    std::vector<Argument> SettingsResetCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument { Execution::Args::Type::SettingName, Resource::String::SettingNameArgumentDescription, ArgumentType::Positional },\r\n            Argument { Execution::Args::Type::All, Resource::String::ResetAllAdminSettingsArgumentDescription, ArgumentType::Flag },\r\n        };\r\n    }\r\n\r\n    Resource::LocString SettingsResetCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::SettingsResetCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString SettingsResetCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::SettingsResetCommandLongDescription };\r\n    }\r\n\r\n    Utility::LocIndView SettingsResetCommand::HelpLink() const\r\n    {\r\n        return s_SettingsCommand_HelpLink;\r\n    }\r\n\r\n    void SettingsResetCommand::ValidateArgumentsInternal(Execution::Args& execArgs) const\r\n    {\r\n        if (execArgs.Contains(Execution::Args::Type::All))\r\n        {\r\n            if (execArgs.Contains(Execution::Args::Type::SettingName))\r\n            {\r\n                throw CommandException(Resource::String::MultipleExclusiveArgumentsProvided(\"all|setting\"_liv));\r\n            }\r\n\r\n            return;\r\n        }\r\n\r\n        if (!execArgs.Contains(Execution::Args::Type::SettingName))\r\n        {\r\n            throw CommandException(Resource::String::RequiredArgError(ArgumentCommon::ForType(Execution::Args::Type::SettingName).Name));\r\n        }\r\n\r\n        // Get admin setting string for all available options except Unknown.\r\n        // We accept both bool and string settings\r\n        std::vector<Utility::LocIndString> adminSettingList;\r\n        for (auto setting : GetAllSequentialEnumValues(BoolAdminSetting::Unknown))\r\n        {\r\n            adminSettingList.emplace_back(AdminSettingToString(setting));\r\n        }\r\n        for (auto setting : GetAllSequentialEnumValues(StringAdminSetting::Unknown))\r\n        {\r\n            adminSettingList.emplace_back(AdminSettingToString(setting));\r\n        }\r\n\r\n        Utility::LocIndString validOptions = Join(\", \"_liv, adminSettingList);\r\n\r\n        if (StringAdminSetting::Unknown == StringToStringAdminSetting(execArgs.GetArg(Execution::Args::Type::SettingName))\r\n            && BoolAdminSetting::Unknown == StringToBoolAdminSetting(execArgs.GetArg(Execution::Args::Type::SettingName)))\r\n        {\r\n            throw CommandException(Resource::String::InvalidArgumentValueError(ArgumentCommon::ForType(Execution::Args::Type::SettingName).Name, validOptions));\r\n        }\r\n    }\r\n\r\n    void SettingsResetCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        context <<\r\n            Workflow::EnsureRunningAsAdmin <<\r\n            (context.Args.Contains(Execution::Args::Type::All) ? Workflow::ResetAllAdminSettings : Workflow::ResetAdminSetting);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/SettingsCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"Command.h\"\n\nnamespace AppInstaller::CLI\n{\n    struct SettingsCommand final : public Command\n    {\n        SettingsCommand(std::string_view parent) : Command(\"settings\", { \"config\" }, parent, Settings::TogglePolicy::Policy::Settings) {}\n\n        std::vector<std::unique_ptr<Command>> GetCommands() const override;\n        std::vector<Argument> GetArguments() const override;\n\n        virtual Resource::LocString ShortDescription() const override;\n        virtual Resource::LocString LongDescription() const override;\n\n        Utility::LocIndView HelpLink() const override;\n\n    protected:\n        void ValidateArgumentsInternal(Execution::Args& execArgs) const override;\n        void ExecuteInternal(Execution::Context& context) const override;\n    };\n\n    struct SettingsExportCommand final : public Command\n    {\n        SettingsExportCommand(std::string_view parent) : Command(\"export\", parent, CommandOutputFlags::IgnoreSettingsWarnings) {}\n\n        Resource::LocString ShortDescription() const override;\n        Resource::LocString LongDescription() const override;\n\n        Utility::LocIndView HelpLink() const override;\n\n    protected:\n        void ExecuteInternal(Execution::Context& context) const override;\n    };\n\n    struct SettingsSetCommand final : public Command\n    {\n        SettingsSetCommand(std::string_view parent) : Command(\"set\", {}, parent, Settings::TogglePolicy::Policy::Settings) {}\n\n        std::vector<Argument> GetArguments() const override;\n\n        virtual Resource::LocString ShortDescription() const override;\n        virtual Resource::LocString LongDescription() const override;\n\n        Utility::LocIndView HelpLink() const override;\n\n    protected:\n        void ValidateArgumentsInternal(Execution::Args& execArgs) const override;\n        void ExecuteInternal(Execution::Context& context) const override;\n    };\n\n    struct SettingsResetCommand final : public Command\n    {\n        SettingsResetCommand(std::string_view parent) : Command(\"reset\", {}, parent, Settings::TogglePolicy::Policy::Settings) {}\n\n        std::vector<Argument> GetArguments() const override;\n\n        virtual Resource::LocString ShortDescription() const override;\n        virtual Resource::LocString LongDescription() const override;\n\n        Utility::LocIndView HelpLink() const override;\n\n    protected:\n        void ValidateArgumentsInternal(Execution::Args& execArgs) const override;\n        void ExecuteInternal(Execution::Context& context) const override;\n    };\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ShowCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ShowCommand.h\"\r\n#include \"Workflows/ShowFlow.h\"\r\n#include \"Workflows/CompletionFlow.h\"\r\n#include \"Workflows/WorkflowBase.h\"\r\n#include \"Resources.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    using namespace AppInstaller::CLI::Execution;\r\n    using namespace AppInstaller::CLI::Workflow;\r\n\r\n    std::vector<Argument> ShowCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument::ForType(Execution::Args::Type::Query),\r\n            // The manifest argument from Argument::ForType can be blocked by Group Policy but we don't want that here\r\n            Argument{ Execution::Args::Type::Manifest, Resource::String::ManifestArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help },\r\n            Argument::ForType(Execution::Args::Type::Id),\r\n            Argument::ForType(Execution::Args::Type::Name),\r\n            Argument::ForType(Execution::Args::Type::Moniker),\r\n            Argument::ForType(Execution::Args::Type::Version),\r\n            Argument::ForType(Execution::Args::Type::Channel),\r\n            Argument::ForType(Execution::Args::Type::Source),\r\n            Argument::ForType(Execution::Args::Type::Exact),\r\n            Argument{ Args::Type::InstallScope, Resource::String::InstallScopeDescription, ArgumentType::Standard, Argument::Visibility::Help },\r\n            Argument::ForType(Execution::Args::Type::InstallerArchitecture),\r\n            Argument::ForType(Execution::Args::Type::InstallerType),\r\n            Argument::ForType(Execution::Args::Type::Locale),\r\n            Argument::ForType(Execution::Args::Type::ListVersions),\r\n            Argument::ForType(Execution::Args::Type::CustomHeader),\r\n            Argument::ForType(Execution::Args::Type::AuthenticationMode),\r\n            Argument::ForType(Execution::Args::Type::AuthenticationAccount),\r\n            Argument::ForType(Execution::Args::Type::AcceptSourceAgreements),\r\n        };\r\n    }\r\n\r\n    Resource::LocString ShowCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::ShowCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString ShowCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::ShowCommandLongDescription };\r\n    }\r\n\r\n    void ShowCommand::Complete(Execution::Context& context, Execution::Args::Type valueType) const\r\n    {\r\n        switch (valueType)\r\n        {\r\n        case Args::Type::InstallerArchitecture:\r\n        case Args::Type::Locale:\r\n            // May well move to CompleteWithSingleSemanticsForValue,\r\n            // but for now output nothing.\r\n            context <<\r\n                Workflow::CompleteWithEmptySet;\r\n            break;\r\n        default:\r\n            context <<\r\n                Workflow::CompleteWithSingleSemanticsForValue(valueType);\r\n        }\r\n    }\r\n\r\n    Utility::LocIndView ShowCommand::HelpLink() const\r\n    {\r\n        return \"https://aka.ms/winget-command-show\"_liv;\r\n    }\r\n\r\n    void ShowCommand::ValidateArgumentsInternal(Args& execArgs) const\r\n    {\r\n        Argument::ValidateCommonArguments(execArgs);\r\n    }\r\n\r\n    void ShowCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        context.SetFlags(Execution::ContextFlag::TreatSourceFailuresAsWarning);\r\n\r\n        if (context.Args.Contains(Execution::Args::Type::ListVersions))\r\n        {\r\n            if (context.Args.Contains(Execution::Args::Type::Manifest))\r\n            {\r\n                context <<\r\n                    Workflow::GetManifestFromArg <<\r\n                    Workflow::ReportManifestIdentity <<\r\n                    Workflow::ShowManifestVersion;\r\n            }\r\n            else\r\n            {\r\n                context <<\r\n                    Workflow::OpenSource() <<\r\n                    Workflow::SearchSourceForSingle <<\r\n                    Workflow::HandleSearchResultFailures <<\r\n                    Workflow::EnsureOneMatchFromSearchResult(OperationType::Show) <<\r\n                    Workflow::ReportPackageIdentity <<\r\n                    Workflow::ShowAppVersions;\r\n            }\r\n        }\r\n        else\r\n        {\r\n            context <<\r\n                GetManifest( /* considerPins */ false) <<\r\n                Workflow::ReportManifestIdentity <<\r\n                Workflow::SelectInstaller <<\r\n                Workflow::ShowManifestInfo;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ShowCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Command.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    struct ShowCommand final : public Command\r\n    {\r\n        ShowCommand(std::string_view parent) : Command(\"show\", { \"view\" }, parent) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        void Complete(Execution::Context& context, Execution::Args::Type valueType) const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ValidateArgumentsInternal(Execution::Args& execArgs) const override;\r\n        void ExecuteInternal(AppInstaller::CLI::Execution::Context& context) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/SourceCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"SourceCommand.h\"\r\n#include \"Workflows/CompletionFlow.h\"\r\n#include \"Workflows/SourceFlow.h\"\r\n#include \"Workflows/WorkflowBase.h\"\r\n#include \"Resources.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    using namespace AppInstaller::CLI::Execution;\r\n    using namespace std::string_view_literals;\r\n\r\n    namespace\r\n    {\r\n        void ValidateSourcePriorityArgument(const Args& execArgs)\r\n        {\r\n            if (execArgs.Contains(Execution::Args::Type::SourcePriority))\r\n            {\r\n                std::string_view priorityArg = execArgs.GetArg(Execution::Args::Type::SourcePriority);\r\n                auto convertedArg = Utility::TryConvertStringToInt32(priorityArg);\r\n                if (!convertedArg.has_value())\r\n                {\r\n                    throw CommandException(Resource::String::InvalidArgumentValueErrorWithoutValidValues(Argument::ForType(Execution::Args::Type::SourcePriority).Name()));\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    Utility::LocIndView s_SourceCommand_HelpLink = \"https://aka.ms/winget-command-source\"_liv;\r\n\r\n    std::vector<std::unique_ptr<Command>> SourceCommand::GetCommands() const\r\n    {\r\n        return InitializeFromMoveOnly<std::vector<std::unique_ptr<Command>>>({\r\n            std::make_unique<SourceAddCommand>(FullName()),\r\n            std::make_unique<SourceListCommand>(FullName()),\r\n            std::make_unique<SourceUpdateCommand>(FullName()),\r\n            std::make_unique<SourceRemoveCommand>(FullName()),\r\n            std::make_unique<SourceEditCommand>(FullName()),\r\n            std::make_unique<SourceResetCommand>(FullName()),\r\n            std::make_unique<SourceExportCommand>(FullName()),\r\n            });\r\n    }\r\n\r\n    Resource::LocString SourceCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::SourceCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString SourceCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::SourceCommandLongDescription };\r\n    }\r\n\r\n    Utility::LocIndView SourceCommand::HelpLink() const\r\n    {\r\n        return s_SourceCommand_HelpLink;\r\n    }\r\n\r\n    void SourceCommand::ExecuteInternal(Context& context) const\r\n    {\r\n        OutputHelp(context.Reporter);\r\n    }\r\n\r\n    std::vector<Argument> SourceAddCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument::ForType(Args::Type::SourceName).SetRequired(true),\r\n            Argument::ForType(Args::Type::SourceArg),\r\n            Argument::ForType(Args::Type::SourceType),\r\n            Argument::ForType(Args::Type::SourceTrustLevel),\r\n            Argument::ForType(Args::Type::CustomHeader),\r\n            Argument::ForType(Args::Type::AcceptSourceAgreements),\r\n            Argument::ForType(Args::Type::SourceExplicit),\r\n            Argument::ForType(Args::Type::SourcePriority),\r\n        };\r\n    }\r\n\r\n    Resource::LocString SourceAddCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::SourceAddCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString SourceAddCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::SourceAddCommandLongDescription };\r\n    }\r\n\r\n    Utility::LocIndView SourceAddCommand::HelpLink() const\r\n    {\r\n        return s_SourceCommand_HelpLink;\r\n    }\r\n\r\n    void SourceAddCommand::ValidateArgumentsInternal(Args& execArgs) const\r\n    {\r\n        if (execArgs.Contains(Execution::Args::Type::SourceTrustLevel))\r\n        {\r\n            try\r\n            {\r\n                std::string trustLevelArg = std::string{ execArgs.GetArg(Execution::Args::Type::SourceTrustLevel) };\r\n\r\n                for (auto trustLevel : Utility::Split(trustLevelArg, '|', true))\r\n                {\r\n                    Repository::ConvertToSourceTrustLevelEnum(trustLevel);\r\n                }\r\n            }\r\n            catch (...)\r\n            {\r\n                auto validOptions = std::vector<Utility::LocIndString>{\r\n                    Utility::LocIndString{ Repository::SourceTrustLevelEnumToString(Repository::SourceTrustLevel::None) },\r\n                    Utility::LocIndString{ Repository::SourceTrustLevelEnumToString(Repository::SourceTrustLevel::Trusted) } };\r\n                throw CommandException(Resource::String::InvalidArgumentValueError(ArgumentCommon::ForType(Execution::Args::Type::SourceTrustLevel).Name, Utility::Join(\",\"_liv, validOptions)));\r\n            }\r\n        }\r\n\r\n        ValidateSourcePriorityArgument(execArgs);\r\n    }\r\n\r\n    void SourceAddCommand::ExecuteInternal(Context& context) const\r\n    {\r\n        // Note: Group Policy for allowed sources is enforced at the RepositoryCore level\r\n        //       as we need to validate the source data and handle sources that were already added.\r\n        context <<\r\n            Workflow::EnsureRunningAsAdmin <<\r\n            Workflow::GetSourceList <<\r\n            Workflow::CheckSourceListAgainstAdd <<\r\n            Workflow::CreateSourceForSourceAdd <<\r\n            Workflow::AddSource;\r\n    }\r\n\r\n    std::vector<Argument> SourceListCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument::ForType(Args::Type::SourceName),\r\n        };\r\n    }\r\n\r\n    Resource::LocString SourceListCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::SourceListCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString SourceListCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::SourceListCommandLongDescription };\r\n    }\r\n\r\n    void SourceListCommand::Complete(Context& context, Args::Type valueType) const\r\n    {\r\n        if (valueType == Args::Type::SourceName)\r\n        {\r\n            context <<\r\n                Workflow::CompleteSourceName;\r\n        }\r\n    }\r\n\r\n    Utility::LocIndView SourceListCommand::HelpLink() const\r\n    {\r\n        return s_SourceCommand_HelpLink;\r\n    }\r\n\r\n    void SourceListCommand::ExecuteInternal(Context& context) const\r\n    {\r\n        context <<\r\n            Workflow::GetSourceListWithFilter <<\r\n            Workflow::ListSources;\r\n    }\r\n\r\n    std::vector<Argument> SourceUpdateCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument::ForType(Args::Type::SourceName),\r\n        };\r\n    }\r\n\r\n    Resource::LocString SourceUpdateCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::SourceUpdateCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString SourceUpdateCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::SourceUpdateCommandLongDescription };\r\n    }\r\n\r\n    void SourceUpdateCommand::Complete(Context& context, Args::Type valueType) const\r\n    {\r\n        if (valueType == Args::Type::SourceName)\r\n        {\r\n            context <<\r\n                Workflow::CompleteSourceName;\r\n        }\r\n    }\r\n\r\n    Utility::LocIndView SourceUpdateCommand::HelpLink() const\r\n    {\r\n        return s_SourceCommand_HelpLink;\r\n    }\r\n\r\n    void SourceUpdateCommand::ExecuteInternal(Context& context) const\r\n    {\r\n        context <<\r\n            Workflow::GetSourceListWithFilter <<\r\n            Workflow::UpdateSources;\r\n    }\r\n\r\n    std::vector<Argument> SourceRemoveCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument::ForType(Args::Type::SourceName).SetRequired(true),\r\n        };\r\n    }\r\n\r\n    Resource::LocString SourceRemoveCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::SourceRemoveCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString SourceRemoveCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::SourceRemoveCommandLongDescription };\r\n    }\r\n\r\n    void SourceRemoveCommand::Complete(Context& context, Args::Type valueType) const\r\n    {\r\n        if (valueType == Args::Type::SourceName)\r\n        {\r\n            context <<\r\n                Workflow::CompleteSourceName;\r\n        }\r\n    }\r\n\r\n    Utility::LocIndView SourceRemoveCommand::HelpLink() const\r\n    {\r\n        return s_SourceCommand_HelpLink;\r\n    }\r\n\r\n    void SourceRemoveCommand::ExecuteInternal(Context& context) const\r\n    {\r\n        // Note: Group Policy for unremovable sources is enforced at the RepositoryCore.\r\n        context <<\r\n            Workflow::EnsureRunningAsAdmin <<\r\n            Workflow::GetSourceListWithFilter <<\r\n            Workflow::RemoveSources;\r\n    }\r\n\r\n    std::vector<Argument> SourceResetCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument::ForType(Args::Type::SourceName),\r\n            Argument{ Args::Type::ForceSourceReset, Resource::String::SourceResetForceArgumentDescription, ArgumentType::Flag },\r\n        };\r\n    }\r\n\r\n    Resource::LocString SourceResetCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::SourceResetCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString SourceResetCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::SourceResetCommandLongDescription };\r\n    }\r\n\r\n    void SourceResetCommand::Complete(Context& context, Args::Type valueType) const\r\n    {\r\n        if (valueType == Args::Type::SourceName)\r\n        {\r\n            context <<\r\n                Workflow::CompleteSourceName;\r\n        }\r\n    }\r\n\r\n    Utility::LocIndView SourceResetCommand::HelpLink() const\r\n    {\r\n        return s_SourceCommand_HelpLink;\r\n    }\r\n\r\n    void SourceResetCommand::ExecuteInternal(Context& context) const\r\n    {\r\n        if (context.Args.Contains(Args::Type::SourceName))\r\n        {\r\n            context <<\r\n                Workflow::EnsureRunningAsAdmin <<\r\n                Workflow::GetSourceListWithFilter <<\r\n                Workflow::ResetSourceList;\r\n        }\r\n        else\r\n        {\r\n            context <<\r\n                Workflow::EnsureRunningAsAdmin <<\r\n                Workflow::QueryUserForSourceReset <<\r\n                Workflow::ResetAllSources;\r\n        }\r\n    }\r\n\r\n    std::vector<Argument> SourceExportCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument::ForType(Args::Type::SourceName),\r\n        };\r\n    }\r\n\r\n    Resource::LocString SourceExportCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::SourceExportCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString SourceExportCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::SourceExportCommandLongDescription };\r\n    }\r\n\r\n    void SourceExportCommand::Complete(Context& context, Args::Type valueType) const\r\n    {\r\n        if (valueType == Args::Type::SourceName)\r\n        {\r\n            context <<\r\n                Workflow::CompleteSourceName;\r\n        }\r\n    }\r\n\r\n    Utility::LocIndView SourceExportCommand::HelpLink() const\r\n    {\r\n        return s_SourceCommand_HelpLink;\r\n    }\r\n\r\n    void SourceExportCommand::ExecuteInternal(Context& context) const\r\n    {\r\n        context <<\r\n            Workflow::GetSourceListWithFilter <<\r\n            Workflow::ExportSourceList;\r\n    }\r\n\r\n    // Source Edit Command\r\n\r\n    std::vector<Argument> SourceEditCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument::ForType(Args::Type::SourceName).SetRequired(true),\r\n            Argument::ForType(Args::Type::SourceEditExplicit),\r\n            Argument::ForType(Args::Type::SourcePriority),\r\n        };\r\n    }\r\n\r\n    Resource::LocString SourceEditCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::SourceEditCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString SourceEditCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::SourceEditCommandLongDescription };\r\n    }\r\n\r\n    Utility::LocIndView SourceEditCommand::HelpLink() const\r\n    {\r\n        return s_SourceCommand_HelpLink;\r\n    }\r\n\r\n    void SourceEditCommand::ValidateArgumentsInternal(Execution::Args& execArgs) const\r\n    {\r\n        if (execArgs.Contains(Execution::Args::Type::SourceEditExplicit))\r\n        {\r\n            std::string_view explicitArg = execArgs.GetArg(Execution::Args::Type::SourceEditExplicit);\r\n            auto convertedArg = Utility::TryConvertStringToBool(explicitArg);\r\n            if (!convertedArg.has_value())\r\n            {\r\n                auto validOptions = Utility::Join(\", \"_liv, std::vector<Utility::LocIndString>{\r\n                    \"true\"_lis,\r\n                    \"false\"_lis,\r\n                });\r\n                throw CommandException(Resource::String::InvalidArgumentValueError(Argument::ForType(Execution::Args::Type::SourceEditExplicit).Name(), validOptions));\r\n            }\r\n        }\r\n\r\n        ValidateSourcePriorityArgument(execArgs);\r\n    }\r\n\r\n    void SourceEditCommand::ExecuteInternal(Context& context) const\r\n    {\r\n        context <<\r\n            Workflow::EnsureRunningAsAdmin <<\r\n            Workflow::GetSourceListWithFilter <<\r\n            Workflow::EditSources;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/SourceCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Command.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    struct SourceCommand final : public Command\r\n    {\r\n        SourceCommand(std::string_view parent) : Command(\"source\", parent) {}\r\n\r\n        std::vector<std::unique_ptr<Command>> GetCommands() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n\r\n    struct SourceAddCommand final : public Command\r\n    {\r\n        SourceAddCommand(std::string_view parent) : Command(\"add\", {}, parent, Settings::TogglePolicy::Policy::AllowedSources) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ValidateArgumentsInternal(Execution::Args& execArgs) const override;\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n\r\n    struct SourceListCommand final : public Command\r\n    {\r\n        SourceListCommand(std::string_view parent) : Command(\"list\", { \"ls\" }, parent) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        void Complete(Execution::Context& context, Execution::Args::Type valueType) const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n\r\n    struct SourceUpdateCommand final : public Command\r\n    {\r\n        SourceUpdateCommand(std::string_view parent) : Command(\"update\", { \"refresh\" }, parent) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        void Complete(Execution::Context& context, Execution::Args::Type valueType) const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n\r\n    struct SourceRemoveCommand final : public Command\r\n    {\r\n        // We can remove user or default sources, so this is not gated by any single policy.\r\n        SourceRemoveCommand(std::string_view parent) : Command(\"remove\", { \"rm\" }, parent) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        void Complete(Execution::Context& context, Execution::Args::Type valueType) const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n\r\n    struct SourceResetCommand final : public Command\r\n    {\r\n        SourceResetCommand(std::string_view parent) : Command(\"reset\", parent) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        void Complete(Execution::Context& context, Execution::Args::Type valueType) const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n\r\n    struct SourceExportCommand final : public Command\r\n    {\r\n        SourceExportCommand(std::string_view parent) : Command(\"export\", parent, CommandOutputFlags::IgnoreSettingsWarnings) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        void Complete(Execution::Context& context, Execution::Args::Type valueType) const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n\r\n    struct SourceEditCommand final : public Command\r\n    {\r\n        SourceEditCommand(std::string_view parent) : Command(\"edit\", { \"config\", \"set\" }, parent) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ValidateArgumentsInternal(Execution::Args& execArgs) const override;\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/TestCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n\r\n#include \"TestCommand.h\"\r\n#include \"AppInstallerRuntime.h\"\r\n#include \"TableOutput.h\"\r\n#include \"Public/ConfigurationSetProcessorFactoryRemoting.h\"\r\n#include \"Public/ShutdownMonitoring.h\"\r\n#include \"Workflows/ConfigurationFlow.h\"\r\n#include \"Workflows/MSStoreInstallerHandler.h\"\r\n#include <winget/RepositorySource.h>\r\n#include <winrt/Microsoft.Management.Configuration.h>\r\n#include <winrt/Windows.ApplicationModel.Core.h>\r\n\r\nusing namespace AppInstaller::CLI::Workflow;\r\nusing namespace AppInstaller::Utility::literals;\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    namespace\r\n    {\r\n        void LogAndReport(Execution::Context& context, std::string_view message)\r\n        {\r\n            context.Reporter.Info() << message << std::endl;\r\n            AICLI_LOG(CLI, Info, << message);\r\n        }\r\n\r\n        HRESULT WaitForShutdown(Execution::Context& context)\r\n        {\r\n            LogAndReport(context, \"Waiting for app shutdown event\");\r\n            if (!ShutdownMonitoring::ServerShutdownSynchronization::WaitForShutdown(300000))\r\n            {\r\n                LogAndReport(context, \"Failed getting app shutdown event\");\r\n                return APPINSTALLER_CLI_ERROR_INTERNAL_ERROR;\r\n            }\r\n\r\n            LogAndReport(context, \"Succeeded waiting for app shutdown event\");\r\n            return S_OK;\r\n        }\r\n\r\n        HRESULT AppShutdownWindowMessage(Execution::Context& context)\r\n        {\r\n            auto windowHandle = ShutdownMonitoring::TerminationSignalHandler::Instance()->GetWindowHandle();\r\n\r\n            if (windowHandle == NULL)\r\n            {\r\n                LogAndReport(context, \"Window was not created\");\r\n                return APPINSTALLER_CLI_ERROR_INTERNAL_ERROR;\r\n            }\r\n\r\n            if (context.Args.Contains(Execution::Args::Type::Force))\r\n            {\r\n                LogAndReport(context, \"Sending WM_QUERYENDSESSION message\");\r\n                THROW_LAST_ERROR_IF(!SendMessageTimeout(\r\n                    windowHandle,\r\n                    WM_QUERYENDSESSION,\r\n                    NULL,\r\n                    ENDSESSION_CLOSEAPP,\r\n                    (SMTO_ABORTIFHUNG | SMTO_ERRORONEXIT),\r\n                    5000,\r\n                    NULL));\r\n            }\r\n\r\n            HRESULT hr = WaitForShutdown(context);\r\n\r\n            if (context.Args.Contains(Execution::Args::Type::Force))\r\n            {\r\n                LogAndReport(context, \"Sending WM_ENDSESSION message\");\r\n                THROW_LAST_ERROR_IF(!SendMessageTimeout(\r\n                    windowHandle,\r\n                    WM_ENDSESSION,\r\n                    NULL,\r\n                    ENDSESSION_CLOSEAPP,\r\n                    (SMTO_ABORTIFHUNG | SMTO_ERRORONEXIT),\r\n                    10000,\r\n                    NULL));\r\n            }\r\n\r\n            return hr;\r\n        }\r\n\r\n        void AppShutdownTestSystemBlockNewWork(CancelReason reason)\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"AppShutdownTestSystemBlockNewWork :: \" << reason);\r\n        }\r\n\r\n        void AppShutdownTestSystemBeginShutdown(CancelReason reason)\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"AppShutdownTestSystemBeginShutdown :: \" << reason);\r\n        }\r\n\r\n        void AppShutdownTestSystemWait()\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"AppShutdownTestSystemWait\");\r\n        }\r\n\r\n        void EnsureDSCv3Processor(Execution::Context& context)\r\n        {\r\n            auto& configurationSet = context.Get<Execution::Data::ConfigurationContext>().Set();\r\n            configurationSet.Environment().ProcessorIdentifier(L\"dscv3\");\r\n        }\r\n\r\n        void InvokeGetAllUnits(Execution::Context& context)\r\n        {\r\n            auto& configurationContext = context.Get<Execution::Data::ConfigurationContext>();\r\n\r\n            winrt::Microsoft::Management::Configuration::ConfigurationUnit unit;\r\n            unit.Type(Utility::ConvertToUTF16(context.Args.GetArg(Execution::Args::Type::ConfigurationExportResource)));\r\n\r\n            auto result = configurationContext.Processor().GetAllUnits(unit);\r\n\r\n            if (FAILED(result.ResultInformation().ResultCode()))\r\n            {\r\n                context.Reporter.Error() << \"Failed to export: \" << WINGET_OSTREAM_FORMAT_HRESULT(result.ResultInformation().ResultCode()) << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(result.ResultInformation().ResultCode());\r\n            }\r\n\r\n            for (const auto& resultUnit : result.Units())\r\n            {\r\n                configurationContext.Set().Units().Append(resultUnit);\r\n            }\r\n        }\r\n\r\n        // Command to directly invoke the export flow.\r\n        struct TestConfigurationExportCommand final : public Command\r\n        {\r\n            TestConfigurationExportCommand(std::string_view parent) : Command(\"config-export-units\", {}, parent) {}\r\n\r\n            std::vector<Argument> GetArguments() const override\r\n            {\r\n                return {\r\n                    Argument{ Execution::Args::Type::OutputFile, Resource::String::OutputFileArgumentDescription, true },\r\n                    Argument{ Execution::Args::Type::ConfigurationExportResource, Resource::String::ConfigureExportResource },\r\n                };\r\n            }\r\n\r\n            Resource::LocString ShortDescription() const override\r\n            {\r\n                return \"Run config export\"_lis;\r\n            }\r\n\r\n            Resource::LocString LongDescription() const override\r\n            {\r\n                return \"Runs the GetAllUnits configuration method to test export on a DSC v3 directly.\"_lis;\r\n            }\r\n\r\n        protected:\r\n            void ExecuteInternal(Execution::Context& context) const override\r\n            {\r\n                context <<\r\n                    VerifyIsFullPackage <<\r\n                    CreateConfigurationProcessorWithoutFactory <<\r\n                    CreateOrOpenConfigurationSet{ \"0.3\" } <<\r\n                    EnsureDSCv3Processor <<\r\n                    CreateConfigurationProcessor <<\r\n                    InvokeGetAllUnits <<\r\n                    WriteConfigFile;\r\n            }\r\n        };\r\n\r\n        void InvokeFindUnitProcessors(Execution::Context& context)\r\n        {\r\n            auto& configurationContext = context.Get<Execution::Data::ConfigurationContext>();\r\n\r\n            winrt::Microsoft::Management::Configuration::FindUnitProcessorsOptions findOptions;\r\n\r\n            if (context.Args.Contains(Execution::Args::Type::InstallLocation))\r\n            {\r\n                findOptions.SearchPaths(Utility::ConvertToUTF16(context.Args.GetArg(Execution::Args::Type::InstallLocation)));\r\n                findOptions.SearchPathsExclusive(true);\r\n                findOptions.UnitDetailFlags(winrt::Microsoft::Management::Configuration::ConfigurationUnitDetailFlags::Local);\r\n            }\r\n\r\n            auto result = configurationContext.Processor().FindUnitProcessors(findOptions);\r\n\r\n            if (result.Size() > 0)\r\n            {\r\n                Execution::TableOutput<2> table(context.Reporter,\r\n                    {\r\n                        \"Type\"_lis,\r\n                        \"Description\"_lis\r\n                    });\r\n\r\n                for (const auto& resultUnitProcessor : result)\r\n                {\r\n                    table.OutputLine({\r\n                        Utility::ConvertToUTF8(resultUnitProcessor.UnitType()),\r\n                        Utility::ConvertToUTF8(resultUnitProcessor.UnitDescription())\r\n                        });\r\n                }\r\n\r\n                table.Complete();\r\n            }\r\n            else\r\n            {\r\n                context.Reporter.Info() << \"No unit processors found.\"_lis << std::endl;\r\n            }\r\n        }\r\n\r\n        // Command to directly invoke find unit processors.\r\n        struct TestConfigurationFindUnitProcessorsCommand final : public Command\r\n        {\r\n            TestConfigurationFindUnitProcessorsCommand(std::string_view parent) : Command(\"config-find-unit-processors\", {}, parent) {}\r\n\r\n            std::vector<Argument> GetArguments() const override\r\n            {\r\n                return {\r\n                    Argument{ Execution::Args::Type::InstallLocation, Resource::String::LocationArgumentDescription },\r\n                };\r\n            }\r\n\r\n            Resource::LocString ShortDescription() const override\r\n            {\r\n                return \"Run find unit processors\"_lis;\r\n            }\r\n\r\n            Resource::LocString LongDescription() const override\r\n            {\r\n                return \"Runs find unit processors. Search paths could be provided.\"_lis;\r\n            }\r\n\r\n        protected:\r\n            void ExecuteInternal(Execution::Context& context) const override\r\n            {\r\n                context <<\r\n                    VerifyIsFullPackage <<\r\n                    CreateConfigurationProcessorWithoutFactory <<\r\n                    CreateOrOpenConfigurationSet{ \"0.3\" } <<\r\n                    EnsureDSCv3Processor <<\r\n                    CreateConfigurationProcessor <<\r\n                    InvokeFindUnitProcessors;\r\n            }\r\n        };\r\n\r\n        struct TestCanUnloadNowCommand final : public Command\r\n        {\r\n            TestCanUnloadNowCommand(std::string_view parent) : Command(\"can-unload-now\", {}, parent, Visibility::Hidden) {}\r\n\r\n            Resource::LocString ShortDescription() const override\r\n            {\r\n                return \"Test DllCanUnloadNow\"_lis;\r\n            }\r\n\r\n            Resource::LocString LongDescription() const override\r\n            {\r\n                return \"Verifies that the function that implements the inproc DllCanUnloadNow properly blocks unload due to static storage object.\"_lis;\r\n            }\r\n\r\n        protected:\r\n            void ExecuteInternal(Execution::Context& context) const override\r\n            {\r\n                Repository::Source source{ Repository::PredefinedSource::Installed };\r\n\r\n                ProgressCallback progress;\r\n                source.Open(progress);\r\n\r\n                HMODULE self = GetModuleHandle(L\"WindowsPackageManager.dll\");\r\n                if (!self)\r\n                {\r\n                    LogAndReport(context, \"Couldn't get WindowsPackageManager module\");\r\n                    return;\r\n                }\r\n\r\n                auto WindowsPackageManagerInProcModuleTerminate = reinterpret_cast<bool (__stdcall *)()>(GetProcAddress(self, \"WindowsPackageManagerInProcModuleTerminate\"));\r\n\r\n                // Report the object counts, attempt to terminate, report the object counts again\r\n                ReportObjectCounts(context);\r\n                LogAndReport(context, WindowsPackageManagerInProcModuleTerminate() ? \"DllCanUnloadNow\" : \"DllCannotUnloadNow\");\r\n                ReportObjectCounts(context);\r\n            }\r\n\r\n        private:\r\n            void ReportObjectCounts(Execution::Context& context) const\r\n            {\r\n                std::ostringstream stream;\r\n                stream << \"Internal objects: \" << GetInternalObjectCount() << '\\n';\r\n                stream << \"External objects: \" << GetExternalObjectCount();\r\n\r\n                LogAndReport(context, stream.str());\r\n            }\r\n\r\n            uint32_t GetInternalObjectCount() const\r\n            {\r\n                return winrt::get_module_lock().operator unsigned int();\r\n            }\r\n\r\n            unsigned long GetExternalObjectCount() const\r\n            {\r\n                auto module = Microsoft::WRL::GetModuleBase();\r\n                return module ? module->GetObjectCount() : 0;\r\n            }\r\n        };\r\n\r\n        struct TestTerminateTerminationSignalHandler final : public Command\r\n        {\r\n            TestTerminateTerminationSignalHandler(std::string_view parent) : Command(\"term-signal-handler\", {}, parent, Visibility::Hidden) {}\r\n\r\n            Resource::LocString ShortDescription() const override\r\n            {\r\n                return \"Test TerminationSignalHandler thread\"_lis;\r\n            }\r\n\r\n            Resource::LocString LongDescription() const override\r\n            {\r\n                return \"Forces the TerminationSignalHandler static object to be destroyed so that the thread behavior can be observed.\"_lis;\r\n            }\r\n\r\n        protected:\r\n            void ExecuteInternal(Execution::Context& context) const override\r\n            {\r\n                // Destroy the one created by standard execution\r\n                // We join on the window thread, so if this never exits we have failed the test.\r\n                winrt::Windows::ApplicationModel::Core::CoreApplication::Properties().TryRemove(L\"WindowsPackageManager.TerminationSignalHandler\");\r\n\r\n                // Create a new instance\r\n                auto instance = ShutdownMonitoring::TerminationSignalHandler::Instance();\r\n                \r\n                if (instance->GetWindowHandle() == nullptr)\r\n                {\r\n                    LogAndReport(context, \"Didn't get a window handle\");\r\n                }\r\n                else\r\n                {\r\n                    LogAndReport(context, \"Got a window handle\");\r\n                }\r\n            }\r\n        };\r\n    }\r\n\r\n    std::vector<std::unique_ptr<Command>> TestCommand::GetCommands() const\r\n    {\r\n        return InitializeFromMoveOnly<std::vector<std::unique_ptr<Command>>>(\r\n            {\r\n                std::make_unique<TestAppShutdownCommand>(FullName()),\r\n                std::make_unique<TestConfigurationExportCommand>(FullName()),\r\n                std::make_unique<TestConfigurationFindUnitProcessorsCommand>(FullName()),\r\n                std::make_unique<TestCanUnloadNowCommand>(FullName()),\r\n                std::make_unique<TestTerminateTerminationSignalHandler>(FullName()),\r\n            });\r\n    }\r\n\r\n    void TestCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        UNREFERENCED_PARAMETER(context);\r\n        Sleep(INFINITE);\r\n    }\r\n\r\n    Resource::LocString TestCommand::ShortDescription() const\r\n    {\r\n        return Utility::LocIndString(\"Waits infinitely\"sv);\r\n    }\r\n\r\n    Resource::LocString TestCommand::LongDescription() const\r\n    {\r\n        return Utility::LocIndString(\"Waits infinitely. Use this if you want winget to wait forever while something is going on\"sv);\r\n    }\r\n\r\n    std::vector<Argument> TestAppShutdownCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument::ForType(Execution::Args::Type::Force)\r\n        };\r\n    }\r\n\r\n    void TestAppShutdownCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        HRESULT hr = E_FAIL;\r\n\r\n        ShutdownMonitoring::ServerShutdownSynchronization::ComponentSystem appShutdownTestSystem{};\r\n        appShutdownTestSystem.BlockNewWork = AppShutdownTestSystemBlockNewWork;\r\n        appShutdownTestSystem.BeginShutdown = AppShutdownTestSystemBeginShutdown;\r\n        appShutdownTestSystem.Wait = AppShutdownTestSystemWait;\r\n\r\n        ShutdownMonitoring::ServerShutdownSynchronization::AddComponent(appShutdownTestSystem);\r\n\r\n        // Only package context and admin won't create the window message.\r\n        if (!Runtime::IsRunningInPackagedContext() || !Runtime::IsRunningAsAdmin())\r\n        {\r\n            hr = AppShutdownWindowMessage(context);\r\n        }\r\n        else\r\n        {\r\n            hr = WaitForShutdown(context);\r\n        }\r\n\r\n        AICLI_TERMINATE_CONTEXT(hr);\r\n    }\r\n\r\n    Resource::LocString TestAppShutdownCommand::ShortDescription() const\r\n    {\r\n        return Utility::LocIndString(\"Test command to verify appshutdown event.\"sv);\r\n    }\r\n\r\n    Resource::LocString TestAppShutdownCommand::LongDescription() const\r\n    {\r\n        return Utility::LocIndString(\"Test command for appshutdown. Verifies the window was created and waits for the app shutdown event\"sv);\r\n    }\r\n\r\n}\r\n\r\n#endif\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/TestCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Command.h\"\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    // Command: winget test\r\n    // Convenient command for debugging. Waits infinitely.\r\n    // Use this if you want to debug things that happen out side of workflows or modify locally to do whatever you need.\r\n    struct TestCommand final : public Command\r\n    {\r\n        TestCommand(std::string_view parent) : Command(\"test\", {}, parent, Visibility::Hidden) {}\r\n\r\n        std::vector<std::unique_ptr<Command>> GetCommands() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n\r\n    // Command: winget test appshutdown\r\n    // Verifies the window was created and waits for the app shutdown event.\r\n    // Used in E2E.\r\n    struct TestAppShutdownCommand final : public Command\r\n    {\r\n        TestAppShutdownCommand(std::string_view parent) : Command(\"appshutdown\", {}, parent, Visibility::Hidden) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n}\r\n\r\n#endif\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/UninstallCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"UninstallCommand.h\"\n#include \"Workflows/UninstallFlow.h\"\n#include \"Workflows/CompletionFlow.h\"\n#include \"Workflows/WorkflowBase.h\"\n#include \"Workflows/MultiQueryFlow.h\"\n#include \"Resources.h\"\n\nnamespace AppInstaller::CLI\n{\n    using AppInstaller::CLI::Execution::Args;\n    using namespace AppInstaller::CLI::Workflow;\n\n    std::vector<Argument> UninstallCommand::GetArguments() const\n    {\n        return\n        {\n            Argument::ForType(Args::Type::MultiQuery),\n            Argument::ForType(Args::Type::Manifest),\n            Argument::ForType(Args::Type::Id),\n            Argument::ForType(Args::Type::Name),\n            Argument::ForType(Args::Type::Moniker),\n            Argument::ForType(Args::Type::ProductCode),\n            Argument::ForType(Args::Type::TargetVersion),\n            Argument::ForType(Args::Type::AllVersions),\n            Argument::ForType(Args::Type::Channel),\n            Argument::ForType(Args::Type::Source),\n            Argument::ForType(Args::Type::Exact),\n            Argument{ Args::Type::InstallScope, Resource::String::InstalledScopeArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help },\n            Argument::ForType(Args::Type::Interactive),\n            Argument::ForType(Args::Type::Silent),\n            Argument::ForType(Args::Type::Force),\n            Argument::ForType(Args::Type::Purge),\n            Argument::ForType(Args::Type::Preserve),\n            Argument::ForType(Args::Type::Log),\n            Argument::ForType(Args::Type::CustomHeader),\n            Argument::ForType(Args::Type::AuthenticationMode),\n            Argument::ForType(Args::Type::AuthenticationAccount),\n            Argument::ForType(Args::Type::AcceptSourceAgreements),\n        };\n    }\n\n    Resource::LocString UninstallCommand::ShortDescription() const\n    {\n        return { Resource::String::UninstallCommandShortDescription };\n    }\n\n    Resource::LocString UninstallCommand::LongDescription() const\n    {\n        return { Resource::String::UninstallCommandLongDescription };\n    }\n\n    void UninstallCommand::Complete(Execution::Context& context, Execution::Args::Type valueType) const\n    {\n        if (valueType == Execution::Args::Type::Manifest ||\n            valueType == Execution::Args::Type::Log)\n        {\n            // Intentionally output nothing to allow pass through to filesystem.\n            return;\n        }\n\n        context <<\n            Workflow::OpenSource() <<\n            Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed);\n\n        switch (valueType)\n        {\n        case Execution::Args::Type::MultiQuery:\n            context <<\n                Workflow::RequireCompletionWordNonEmpty <<\n                Workflow::SearchSourceForManyCompletion <<\n                Workflow::CompleteWithMatchedField;\n            break;\n        case Execution::Args::Type::Id:\n        case Execution::Args::Type::Name:\n        case Execution::Args::Type::Moniker:\n        case Execution::Args::Type::TargetVersion:\n        case Execution::Args::Type::Channel:\n        case Execution::Args::Type::Source:\n        case Execution::Args::Type::ProductCode:\n            context <<\n                Workflow::CompleteWithSingleSemanticsForValueUsingExistingSource(valueType);\n            break;\n        }\n    }\n\n    Utility::LocIndView UninstallCommand::HelpLink() const\n    {\n        return \"https://aka.ms/winget-command-uninstall\"_liv;\n    }\n\n    void UninstallCommand::ValidateArgumentsInternal(Execution::Args& execArgs) const\n    {\n        Argument::ValidateCommonArguments(execArgs);\n    }\n\n    void UninstallCommand::ExecuteInternal(Execution::Context& context) const\n    {\n        context.SetFlags(Execution::ContextFlag::TreatSourceFailuresAsWarning);\n\n        // open the sources where to search for the package\n        context <<\n            Workflow::ReportExecutionStage(ExecutionStage::Discovery) <<\n            Workflow::OpenSource() <<\n            Workflow::OpenCompositeSource(Workflow::DetermineInstalledSource(context));\n\n        // find the uninstaller\n        if (context.Args.Contains(Execution::Args::Type::Manifest))\n        {\n            // --manifest case where new manifest is provided\n            context <<\n                Workflow::GetManifestFromArg <<\n                Workflow::SearchSourceUsingManifest <<\n                Workflow::EnsureOneMatchFromSearchResult(OperationType::Uninstall) <<\n                Workflow::UninstallSinglePackage;\n        }\n        else\n        {\n            // search for specific packages to uninstall\n            if (!context.Args.Contains(Execution::Args::Type::MultiQuery))\n            {\n                context <<\n                    Workflow::SearchSourceForSingle <<\n                    Workflow::HandleSearchResultFailures <<\n                    Workflow::EnsureOneMatchFromSearchResult(OperationType::Uninstall) <<\n                    Workflow::UninstallSinglePackage;\n            }\n            else\n            {\n                context <<\n                    Workflow::GetMultiSearchRequests <<\n                    Workflow::SearchSubContextsForSingle(OperationType::Uninstall) <<\n                    Workflow::UninstallMultiplePackages;\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/UninstallCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"Command.h\"\n\nnamespace AppInstaller::CLI\n{\n    struct UninstallCommand final : public Command\n    {\n        UninstallCommand(std::string_view parent) : Command(\"uninstall\", { \"remove\", \"rm\" }, parent) {}\n\n        std::vector<Argument> GetArguments() const override;\n\n        Resource::LocString ShortDescription() const override;\n        Resource::LocString LongDescription() const override;\n\n        void Complete(Execution::Context& context, Execution::Args::Type valueType) const override;\n\n        Utility::LocIndView HelpLink() const override;\n\n    protected:\n        void ValidateArgumentsInternal(Execution::Args& execArgs) const override;\n        void ExecuteInternal(Execution::Context& context) const override;\n    };\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/UpgradeCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"UpgradeCommand.h\"\r\n#include \"Workflows/CompletionFlow.h\"\r\n#include \"Workflows/DownloadFlow.h\"\r\n#include \"Workflows/InstallFlow.h\"\r\n#include \"Workflows/MultiQueryFlow.h\"\r\n#include \"Workflows/UpdateFlow.h\"\r\n#include \"Workflows/WorkflowBase.h\"\r\n#include \"Workflows/DependenciesFlow.h\"\r\n#include \"Resources.h\"\r\n#include <winget/LocIndependent.h>\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    using namespace AppInstaller::CLI::Execution;\r\n    using namespace AppInstaller::Manifest;\r\n    using namespace AppInstaller::CLI::Workflow;\r\n    using namespace AppInstaller::Utility::literals;\r\n\r\n    namespace\r\n    {\r\n        // Determines whether we should list available upgrades, instead\r\n        // of performing an upgrade\r\n        bool ShouldListUpgrade(const Execution::Args& args, ArgTypeCategory argCategories = ArgTypeCategory::None)\r\n        {\r\n            if (argCategories == ArgTypeCategory::None)\r\n            {\r\n                argCategories = Argument::GetCategoriesPresent(args);\r\n            }\r\n\r\n            // Valid arguments for list are only those related to the sources and which packages to include (e.g. --include-unknown).\r\n            // Instead of checking for them, we check that there aren't any other arguments present.\r\n            return !args.Contains(Args::Type::All) &&\r\n                WI_AreAllFlagsClear(argCategories, ArgTypeCategory::Manifest | ArgTypeCategory::PackageQuery | ArgTypeCategory::InstallerBehavior);\r\n        }\r\n    }\r\n\r\n    std::vector<Argument> UpgradeCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument::ForType(Args::Type::MultiQuery),      // -q\r\n            Argument::ForType(Args::Type::Manifest),        // -m\r\n            Argument::ForType(Args::Type::Id),\r\n            Argument::ForType(Args::Type::Name),\r\n            Argument::ForType(Args::Type::Moniker),\r\n            Argument::ForType(Args::Type::Version),         // -v\r\n            Argument::ForType(Args::Type::Channel),\r\n            Argument::ForType(Args::Type::Source),          // -s\r\n            Argument::ForType(Args::Type::Exact),           // -e\r\n            Argument::ForType(Args::Type::Interactive),     // -i\r\n            Argument::ForType(Args::Type::Silent),          // -h\r\n            Argument::ForType(Args::Type::Purge),\r\n            Argument::ForType(Args::Type::Log),             // -o\r\n            Argument::ForType(Args::Type::CustomSwitches),\r\n            Argument::ForType(Args::Type::Override),\r\n            Argument::ForType(Args::Type::InstallLocation), // -l\r\n            Argument{ Args::Type::InstallScope, Resource::String::InstalledScopeArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help },\r\n            Argument::ForType(Args::Type::InstallArchitecture), // -a\r\n            Argument::ForType(Args::Type::InstallerType),\r\n            Argument::ForType(Args::Type::Locale),\r\n            Argument::ForType(Args::Type::HashOverride),\r\n            Argument::ForType(Args::Type::AllowReboot),\r\n            Argument::ForType(Args::Type::SkipDependencies),\r\n            Argument::ForType(Args::Type::IgnoreLocalArchiveMalwareScan),\r\n            Argument::ForType(Args::Type::AcceptPackageAgreements),\r\n            Argument::ForType(Args::Type::AcceptSourceAgreements),\r\n            Argument::ForType(Args::Type::CustomHeader),\r\n            Argument::ForType(Args::Type::AuthenticationMode),\r\n            Argument::ForType(Args::Type::AuthenticationAccount),\r\n            Argument{ Args::Type::All, Resource::String::UpdateAllArgumentDescription, ArgumentType::Flag },\r\n            Argument{ Args::Type::IncludeUnknown, Resource::String::IncludeUnknownArgumentDescription, ArgumentType::Flag },\r\n            Argument{ Args::Type::IncludePinned, Resource::String::IncludePinnedArgumentDescription, ArgumentType::Flag},\r\n            Argument::ForType(Args::Type::UninstallPrevious),\r\n            Argument::ForType(Args::Type::Force),\r\n        };\r\n    }\r\n\r\n    Resource::LocString UpgradeCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::UpgradeCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString UpgradeCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::UpgradeCommandLongDescription };\r\n    }\r\n\r\n    void UpgradeCommand::Complete(Execution::Context& context, Execution::Args::Type valueType) const\r\n    {\r\n        if (valueType == Execution::Args::Type::Manifest ||\r\n            valueType == Execution::Args::Type::Log ||\r\n            valueType == Execution::Args::Type::Override ||\r\n            valueType == Execution::Args::Type::InstallLocation)\r\n        {\r\n            // Intentionally output nothing to allow pass through to filesystem.\r\n            return;\r\n        }\r\n\r\n        context <<\r\n            OpenSource() <<\r\n            OpenCompositeSource(Repository::PredefinedSource::Installed);\r\n\r\n        switch (valueType)\r\n        {\r\n        case Execution::Args::Type::MultiQuery:\r\n            context <<\r\n                RequireCompletionWordNonEmpty <<\r\n                SearchSourceForManyCompletion <<\r\n                CompleteWithMatchedField;\r\n            break;\r\n        case Execution::Args::Type::Id:\r\n        case Execution::Args::Type::Name:\r\n        case Execution::Args::Type::Moniker:\r\n        case Execution::Args::Type::Version:\r\n        case Execution::Args::Type::Channel:\r\n        case Execution::Args::Type::Source:\r\n            context <<\r\n                CompleteWithSingleSemanticsForValueUsingExistingSource(valueType);\r\n            break;\r\n        case Args::Type::InstallArchitecture:\r\n        case Args::Type::Locale:\r\n            // May well move to CompleteWithSingleSemanticsForValue,\r\n            // but for now output nothing.\r\n            context <<\r\n                Workflow::CompleteWithEmptySet;\r\n            break;\r\n        }\r\n    }\r\n\r\n    Utility::LocIndView UpgradeCommand::HelpLink() const\r\n    {\r\n        return \"https://aka.ms/winget-command-upgrade\"_liv;\r\n    }\r\n\r\n    void UpgradeCommand::ValidateArgumentsInternal(Execution::Args& execArgs) const\r\n    {\r\n        const auto argCategories = Argument::GetCategoriesAndValidateCommonArguments(execArgs, /* requirePackageSelectionArg */ false);\r\n\r\n        if (!ShouldListUpgrade(execArgs, argCategories) &&\r\n            WI_IsFlagClear(argCategories, ArgTypeCategory::PackageQuery) &&\r\n            WI_IsFlagSet(argCategories, ArgTypeCategory::SingleInstallerBehavior))\r\n        {\r\n            throw CommandException(Resource::String::InvalidArgumentWithoutQueryError);\r\n        }\r\n    }\r\n\r\n    void UpgradeCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        context.SetFlags(Execution::ContextFlag::InstallerExecutionUseUpdate);\r\n\r\n        // Only allow for source failures when doing a list of available upgrades.\r\n        // We have to set it now to allow for source open failures to also just warn.\r\n        if (ShouldListUpgrade(context.Args))\r\n        {\r\n            context.SetFlags(Execution::ContextFlag::TreatSourceFailuresAsWarning);\r\n        }\r\n\r\n        context <<\r\n            InitializeInstallerDownloadAuthenticatorsMap <<\r\n            ReportExecutionStage(ExecutionStage::Discovery) <<\r\n            OpenSource() <<\r\n            OpenCompositeSource(DetermineInstalledSource(context));\r\n\r\n        if (ShouldListUpgrade(context.Args))\r\n        {\r\n            // Upgrade with no args list packages with updates available\r\n            context <<\r\n                SearchSourceForMany <<\r\n                HandleSearchResultFailures <<\r\n                EnsureMatchesFromSearchResult(OperationType::Upgrade) <<\r\n                ReportListResult(true);\r\n        }\r\n        else if (context.Args.Contains(Execution::Args::Type::All))\r\n        {\r\n            // --all switch updates all packages found\r\n            context <<\r\n                SearchSourceForMany <<\r\n                HandleSearchResultFailures <<\r\n                EnsureMatchesFromSearchResult(OperationType::Upgrade) <<\r\n                ReportListResult(true) <<\r\n                UpdateAllApplicable;\r\n        }\r\n        else if (context.Args.Contains(Execution::Args::Type::Manifest))\r\n        {\r\n            // --manifest case where new manifest is provided\r\n            context <<\r\n                GetManifestFromArg <<\r\n                SearchSourceUsingManifest <<\r\n                EnsureOneMatchFromSearchResult(OperationType::Upgrade) <<\r\n                GetInstalledPackageVersion <<\r\n                EnsureUpdateVersionApplicable <<\r\n                SelectInstaller <<\r\n                EnsureApplicableInstaller <<\r\n                InstallSinglePackage;\r\n        }\r\n        else\r\n        {\r\n            // The remaining case: search for specific packages to update\r\n            if (!context.Args.Contains(Execution::Args::Type::MultiQuery))\r\n            {\r\n                context << InstallOrUpgradeSinglePackage(OperationType::Upgrade);\r\n            }\r\n            else\r\n            {\r\n                ProcessMultiplePackages::Flags flags = ProcessMultiplePackages::Flags::None;\r\n                if (Settings::User().Get<Settings::Setting::InstallSkipDependencies>() || context.Args.Contains(Execution::Args::Type::SkipDependencies))\r\n                {\r\n                    flags = ProcessMultiplePackages::Flags::IgnoreDependencies;\r\n                }\r\n\r\n                context <<\r\n                    GetMultiSearchRequests <<\r\n                    SearchSubContextsForSingle(OperationType::Upgrade) <<\r\n                    ReportExecutionStage(ExecutionStage::Execution) <<\r\n                    ProcessMultiplePackages(Resource::String::PackageRequiresDependencies, APPINSTALLER_CLI_ERROR_MULTIPLE_INSTALL_FAILED, flags);\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/UpgradeCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Command.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    struct UpgradeCommand final : public Command\r\n    {\r\n        UpgradeCommand(std::string_view parent) : Command(\"upgrade\", { \"update\" }, parent) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        void Complete(Execution::Context& context, Execution::Args::Type valueType) const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ValidateArgumentsInternal(Execution::Args& execArgs) const override;\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ValidateCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ValidateCommand.h\"\r\n#include \"Workflows/WorkflowBase.h\"\r\n#include \"Workflows/DependenciesFlow.h\"\r\n#include \"Resources.h\"\r\n#include <winget/ManifestYamlParser.h>\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    using namespace std::string_view_literals;\r\n    using namespace AppInstaller::Manifest;\r\n\r\n    std::vector<Argument> ValidateCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument::ForType(Execution::Args::Type::ValidateManifest),\r\n        };\r\n    }\r\n\r\n    Resource::LocString ValidateCommand::ShortDescription() const\r\n    {\r\n        return Resource::LocString{ Resource::String::ValidateCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString ValidateCommand::LongDescription() const\r\n    {\r\n        return Resource::LocString{ Resource::String::ValidateCommandLongDescription };\r\n    }\r\n\r\n    Utility::LocIndView ValidateCommand::HelpLink() const\r\n    {\r\n        return \"https://aka.ms/winget-command-validate\"_liv;\r\n    }\r\n\r\n    void ValidateCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        context <<\r\n            Workflow::VerifyPath(Execution::Args::Type::ValidateManifest) <<\r\n            [](Execution::Context& context)\r\n        {\r\n            auto inputFile = Utility::ConvertToUTF16(context.Args.GetArg(Execution::Args::Type::ValidateManifest));\r\n\r\n            try\r\n            {\r\n                ManifestValidateOption validateOption;\r\n                validateOption.FullValidation = true;\r\n                validateOption.SchemaHeaderValidationAsWarning = true;\r\n                validateOption.ThrowOnWarning = !(context.Args.Contains(Execution::Args::Type::IgnoreWarnings));\r\n                auto manifest = YamlParser::CreateFromPath(inputFile, validateOption);\r\n\r\n                context.Add<Execution::Data::Manifest>(manifest);\r\n                context <<\r\n                    Workflow::GetInstallersDependenciesFromManifest <<\r\n                    Workflow::ReportDependencies(Resource::String::ValidateCommandReportDependencies);\r\n\r\n                context.Reporter.Info() << Resource::String::ManifestValidationSuccess << std::endl;\r\n            }\r\n            catch (const ManifestException& e)\r\n            {\r\n                HRESULT hr = S_OK;\r\n                if (e.IsWarningOnly())\r\n                {\r\n                    context.Reporter.Warn() << Resource::String::ManifestValidationWarning << std::endl;\r\n                    hr = APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_WARNING;\r\n                }\r\n                else\r\n                {\r\n                    context.Reporter.Error() << Resource::String::ManifestValidationFail << std::endl;\r\n                    hr = APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_FAILURE;\r\n                }\r\n\r\n                context.Reporter.Info() << e.GetManifestErrorMessage() << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(hr);\r\n            }\r\n        };\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Commands/ValidateCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Command.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    struct ValidateCommand final : public Command\r\n    {\r\n        ValidateCommand(std::string_view parent) : Command(\"validate\", parent) {}\r\n\r\n        virtual std::vector<Argument> GetArguments() const override;\r\n\r\n        virtual Resource::LocString ShortDescription() const override;\r\n        virtual Resource::LocString LongDescription() const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/CompletionData.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"CompletionData.h\"\r\n#include \"Resources.h\"\r\n#include <AppInstallerLogging.h>\r\n#include <AppInstallerErrors.h>\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    using namespace std::string_view_literals;\r\n    using namespace Utility::literals;\r\n\r\n    // Completion takes in the following values:\r\n    //  Word :: The token from the command line that is being targeted for completion.\r\n    //          This value may have quotes surrounding it, and will need to be removed in such a case.\r\n    //  CommandLine :: The full command line that contains the word to be completed.\r\n    //                 This value has the fully quoted strings, as well as escaped quotations if needed.\r\n    //  Position :: The position of the cursor within the command line.\r\n    //\r\n    // Completions here will not attempt to take exact cursor position into account; meaning if the cursor\r\n    // is in the middle of the word, it is not different than at the beginning or end. This functionality\r\n    // could be added later.\r\n    CompletionData::CompletionData(std::string_view word, std::string_view commandLine, std::string_view position)\r\n    {\r\n        m_word = word;\r\n\r\n        AICLI_LOG(CLI, Info, << \"Completing word '\" << m_word << '\\'');\r\n\r\n        // Determine position as an integer\r\n        size_t cursor = wil::safe_cast<size_t>(std::stoull(std::string{ position }));\r\n\r\n        AICLI_LOG(CLI, Info, << \"Cursor position starts at '\" << cursor << '\\'');\r\n\r\n        // First, move the cursor from the UTF-8 grapheme position to the UTF-8 byte position.\r\n        // This simplifies the rest of the code.\r\n        cursor = Utility::UTF8Substring(commandLine, 0, cursor).length();\r\n\r\n        AICLI_LOG(CLI, Info, << \"Cursor position moved to '\" << cursor << '\\'');\r\n\r\n        std::vector<std::string> argsBeforeWord;\r\n        std::vector<std::string> argsAfterWord;\r\n\r\n        // If the word is empty, we must determine where the split is. We operate as PowerShell does; the cursor\r\n        // being at the front of a token results in an empty word and an insertion rather than a replacement.\r\n        // If the user put spaces at the front of the statement, this can lead to the position being out of sorts;\r\n        // PowerShell sends the cursor position, but does not include leading spaces in the AST output. If the\r\n        // user puts too many spaces at the front we will be unable to determine the true location.\r\n        if (m_word.empty())\r\n        {\r\n            // The cursor is past the end, so everything is before the word.\r\n            if (cursor >= commandLine.length())\r\n            {\r\n                // Move the position to the end in case it was extended past it.\r\n                ParseInto(commandLine, argsBeforeWord, true);\r\n            }\r\n            // The cursor is not past the end; ensure that the preceding character is whitespace or move the\r\n            // position back until it is. This is far from foolproof, but until we have evidence otherwise,\r\n            // very few users are likely to put any spaces at the front of their statements, let alone many.\r\n            else\r\n            {\r\n                for (; cursor > 0 && !std::isspace(static_cast<unsigned char>(commandLine[cursor - 1])); --cursor);\r\n\r\n                AICLI_LOG(CLI, Info, << \"Cursor position moved to '\" << cursor << '\\'');\r\n\r\n                // If we actually hit the front of the string, something bad probably happened.\r\n                THROW_HR_IF(APPINSTALLER_CLI_ERROR_COMPLETE_INPUT_BAD, cursor == 0);\r\n\r\n                ParseInto(commandLine.substr(0, cursor), argsBeforeWord, true);\r\n                ParseInto(commandLine.substr(cursor), argsAfterWord, false);\r\n            }\r\n        }\r\n        // If the word is not empty, the cursor is either in the middle of a token, or at the end of one.\r\n        // The value will be replaced, and we will remove it from the args here.\r\n        else\r\n        {\r\n            std::vector<std::string> allArgs;\r\n            ParseInto(commandLine, allArgs, true);\r\n\r\n            // Find the word amongst the arguments\r\n            std::vector<size_t> wordIndices;\r\n            for (size_t i = 0; i < allArgs.size(); ++i)\r\n            {\r\n                if (m_word == allArgs[i])\r\n                {\r\n                    wordIndices.push_back(i);\r\n                }\r\n            }\r\n\r\n            // If we didn't find a matching string, we probably made some bad assumptions.\r\n            THROW_HR_IF(APPINSTALLER_CLI_ERROR_COMPLETE_INPUT_BAD, wordIndices.empty());\r\n\r\n            // If we find an exact match only once, we can just split on that.\r\n            size_t wordIndexForSplit = wordIndices[0];\r\n\r\n            // If we found more than one match, we have to rely on the position to\r\n            // determine which argument is the word in question.\r\n            if (wordIndices.size() > 1)\r\n            {\r\n                // Escape the word and search for it in the command line.\r\n                std::string escapedWord = m_word;\r\n                Utility::FindAndReplace(escapedWord, \"\\\"\", \"\\\"\\\"\");\r\n\r\n                std::vector<size_t> escapedIndices;\r\n                for (size_t offset = 0; offset < commandLine.length();)\r\n                {\r\n                    size_t pos = commandLine.find(escapedWord, offset);\r\n\r\n                    if (pos == std::string::npos)\r\n                    {\r\n                        break;\r\n                    }\r\n\r\n                    escapedIndices.push_back(pos);\r\n                    offset = pos + escapedWord.length();\r\n                }\r\n\r\n                // If these are out of sync we don't have much hope.\r\n                THROW_HR_IF(APPINSTALLER_CLI_ERROR_COMPLETE_INPUT_BAD, wordIndices.size() != escapedIndices.size());\r\n\r\n                // Find the closest one to the position. This can be fooled as above if there is\r\n                // leading whitespace in the statement. But it is the best we can do.\r\n                size_t indexToUse = std::numeric_limits<size_t>::max();\r\n                size_t distanceToCursor = std::numeric_limits<size_t>::max();\r\n\r\n                for (size_t i = 0; i < escapedIndices.size(); ++i)\r\n                {\r\n                    size_t lowerBound = escapedIndices[i];\r\n                    size_t upperBound = lowerBound + escapedWord.length();\r\n                    size_t distance = 0;\r\n\r\n                    // The cursor is square in the middle of this location, this is the one.\r\n                    if (cursor > lowerBound && cursor <= upperBound)\r\n                    {\r\n                        indexToUse = i;\r\n                        break;\r\n                    }\r\n                    else if (cursor <= lowerBound)\r\n                    {\r\n                        distance = lowerBound - cursor;\r\n                    }\r\n                    else // cursor > upperBound\r\n                    {\r\n                        distance = cursor - upperBound;\r\n                    }\r\n\r\n                    if (distance < distanceToCursor)\r\n                    {\r\n                        indexToUse = i;\r\n                        distanceToCursor = distance;\r\n                    }\r\n                }\r\n\r\n                // It really would be unexpected to not find a closest one.\r\n                THROW_HR_IF(APPINSTALLER_CLI_ERROR_COMPLETE_INPUT_BAD, indexToUse == std::numeric_limits<size_t>::max());\r\n\r\n                wordIndexForSplit = wordIndices[indexToUse];\r\n            }\r\n\r\n            std::vector<std::string>* moveTarget = &argsBeforeWord;\r\n            for (size_t i = 0; i < allArgs.size(); ++i)\r\n            {\r\n                if (i == wordIndexForSplit)\r\n                {\r\n                    // Intentionally leave the matched arg behind.\r\n                    moveTarget = &argsAfterWord;\r\n                }\r\n                else\r\n                {\r\n                    moveTarget->emplace_back(std::move(allArgs[i]));\r\n                }\r\n            }\r\n        }\r\n\r\n        // Move the arguments into an Invocation for future use.\r\n        m_argsBeforeWord = std::make_unique<CLI::Invocation>(std::move(argsBeforeWord));\r\n        m_argsAfterWord = std::make_unique<CLI::Invocation>(std::move(argsAfterWord));\r\n\r\n        AICLI_LOG(CLI, Info, << \"Completion invoked for arguments:\" << [&]() {\r\n            std::stringstream strstr;\r\n            for (const auto& arg : *m_argsBeforeWord)\r\n            {\r\n                strstr << \" '\" << arg << '\\'';\r\n            }\r\n            if (m_word.empty())\r\n            {\r\n                strstr << \" << [insert] >> \";\r\n            }\r\n            else\r\n            {\r\n                strstr << \" << [replace] '\" << m_word << \"' >> \";\r\n            }\r\n            for (const auto& arg : *m_argsAfterWord)\r\n            {\r\n                strstr << \" '\" << arg << '\\'';\r\n            }\r\n            return strstr.str();\r\n            }());\r\n    }\r\n\r\n    void CompletionData::ParseInto(std::string_view line, std::vector<std::string>& args, bool skipFirst)\r\n    {\r\n        std::wstring commandLineW = Utility::ConvertToUTF16(line);\r\n        int argc = 0;\r\n        wil::unique_hlocal_ptr<LPWSTR> argv{ CommandLineToArgvW(commandLineW.c_str(), &argc) };\r\n        THROW_LAST_ERROR_IF_NULL(argv);\r\n\r\n        for (int i = (skipFirst ? 1 : 0); i < argc; ++i)\r\n        {\r\n            args.emplace_back(Utility::ConvertToUTF8(argv.get()[i]));\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/CompletionData.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ExecutionArgs.h\"\r\n#include \"Invocation.h\"\r\n\r\n#include <memory>\r\n#include <string>\r\n#include <string_view>\r\n#include <vector>\r\n\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    // Data created by CompleteCommand to be consumed by other commands in order\r\n    // to provide context sensitive results.\r\n    struct CompletionData\r\n    {\r\n        CompletionData(std::string_view word, std::string_view commandLine, std::string_view position);\r\n\r\n        const std::string& Word() const { return m_word; }\r\n        Invocation& BeforeWord() const { return *m_argsBeforeWord; }\r\n        Invocation& AfterWord() const { return *m_argsAfterWord; }\r\n\r\n    private:\r\n        static void ParseInto(std::string_view line, std::vector<std::string>& args, bool skipFirst);\r\n\r\n        std::string m_word;\r\n        std::unique_ptr<CLI::Invocation> m_argsBeforeWord;\r\n        std::unique_ptr<CLI::Invocation> m_argsAfterWord;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/ConfigurationCommon.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigurationCommon.h\"\r\n#include \"ExecutionArgs.h\"\r\n#include <AppInstallerRuntime.h>\r\n#include \"Command.h\"\r\n#include <winrt/Microsoft.Management.Configuration.SetProcessorFactory.h>\r\n#include <filesystem>\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    using namespace winrt::Microsoft::Management::Configuration;\r\n\r\n    namespace\r\n    {\r\n        constexpr std::string_view s_ModulePath_Default = \"default\";\r\n        constexpr std::string_view s_ModulePath_CurrentUser = \"currentuser\";\r\n        constexpr std::string_view s_ModulePath_AllUsers = \"allusers\";\r\n\r\n        struct ModulePathInfo\r\n        {\r\n            SetProcessorFactory::PwshConfigurationProcessorLocation location;\r\n            std::optional<std::string> customLocation;\r\n        };\r\n\r\n        ModulePathInfo GetModulePathInfo(Execution::Args& execArgs)\r\n        {\r\n            if (execArgs.Contains(Execution::Args::Type::ConfigurationModulePath))\r\n            {\r\n                auto modulePath = execArgs.GetArg(Execution::Args::Type::ConfigurationModulePath);\r\n\r\n                if (Utility::CaseInsensitiveEquals(modulePath, s_ModulePath_Default))\r\n                {\r\n                    return { SetProcessorFactory::PwshConfigurationProcessorLocation::Default, {} };\r\n                }\r\n                else if (Utility::CaseInsensitiveEquals(modulePath, s_ModulePath_CurrentUser))\r\n                {\r\n                    return { SetProcessorFactory::PwshConfigurationProcessorLocation::CurrentUser, {} };\r\n                }\r\n                else if (Utility::CaseInsensitiveEquals(modulePath, s_ModulePath_AllUsers))\r\n                {\r\n                    return { SetProcessorFactory::PwshConfigurationProcessorLocation::AllUsers, {} };\r\n                }\r\n                else\r\n                {\r\n                    return { SetProcessorFactory::PwshConfigurationProcessorLocation::Custom, std::string(execArgs.GetArg(Execution::Args::Type::ConfigurationModulePath)) };\r\n                }\r\n            }\r\n\r\n            std::filesystem::path defaultModuleRoot = Settings::User().Get<Settings::Setting::ConfigureDefaultModuleRoot>();\r\n\r\n            if (!defaultModuleRoot.empty())\r\n            {\r\n                return { SetProcessorFactory::PwshConfigurationProcessorLocation::Custom, defaultModuleRoot.u8string() };\r\n            }\r\n\r\n            return { SetProcessorFactory::PwshConfigurationProcessorLocation::WinGetModulePath, {} };\r\n        }\r\n    }\r\n\r\n    namespace Configuration\r\n    {\r\n        void ValidateCommonArguments(Execution::Args& execArgs, bool requireConfigurationSetChoice)\r\n        {\r\n            auto modulePath = GetModulePathInfo(execArgs);\r\n\r\n            if (modulePath.location == SetProcessorFactory::PwshConfigurationProcessorLocation::AllUsers && !Runtime::IsRunningAsAdmin())\r\n            {\r\n                throw CommandException(Resource::String::ConfigurationAllUsersElevated);\r\n            }\r\n\r\n            if (modulePath.location == SetProcessorFactory::PwshConfigurationProcessorLocation::Custom)\r\n            {\r\n                auto path = std::filesystem::path{ modulePath.customLocation.value() };\r\n                if (!path.is_absolute())\r\n                {\r\n                    throw CommandException(Resource::String::ConfigurationModulePathArgError);\r\n                }\r\n            }\r\n\r\n            if (requireConfigurationSetChoice &&\r\n                !WI_IsFlagSet(Argument::GetCategoriesPresent(execArgs), ArgTypeCategory::ConfigurationSetChoice))\r\n            {\r\n                throw CommandException(Resource::String::RequiredArgError(\"file\"_liv));\r\n            }\r\n        }\r\n\r\n        void SetModulePath(Execution::Context& context, IConfigurationSetProcessorFactory const& factory)\r\n        {\r\n            auto pwshFactory = factory.as<SetProcessorFactory::IPwshConfigurationSetProcessorFactoryProperties>();\r\n            auto modulePath = GetModulePathInfo(context.Args);\r\n\r\n            if (modulePath.location == SetProcessorFactory::PwshConfigurationProcessorLocation::Custom)\r\n            {\r\n                pwshFactory.CustomLocation(winrt::to_hstring(modulePath.customLocation.value()));\r\n            }\r\n\r\n            pwshFactory.Location(modulePath.location);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/ConfigurationCommon.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ExecutionContext.h\"\r\n#include <winrt/Microsoft.Management.Configuration.h>\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    namespace Configuration\r\n    {\r\n        // Validates common arguments between configuration commands.\r\n        void ValidateCommonArguments(Execution::Args& execArgs, bool requireConfigurationSetChoice = false);\r\n\r\n        // Sets the module path to install modules in the set processor.\r\n        void SetModulePath(Execution::Context& context, winrt::Microsoft::Management::Configuration::IConfigurationSetProcessorFactory const& factory);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/ConfigurationContext.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigurationContext.h\"\r\n#include <winrt/Microsoft.Management.Configuration.h>\r\n\r\nusing namespace winrt::Microsoft::Management::Configuration;\r\n\r\nnamespace AppInstaller::CLI::Execution\r\n{\r\n    namespace details\r\n    {\r\n        struct ConfigurationContextData\r\n        {\r\n            ConfigurationProcessor Processor = nullptr;\r\n            ConfigurationSet Set = nullptr;\r\n            std::vector<ConfigurationSet> History;\r\n        };\r\n    }\r\n\r\n    ConfigurationContext::ConfigurationContext() : m_data(std::make_unique<details::ConfigurationContextData>())\r\n    {\r\n    }\r\n\r\n    ConfigurationContext::~ConfigurationContext() = default;\r\n\r\n    ConfigurationContext::ConfigurationContext(ConfigurationContext&&) = default;\r\n    ConfigurationContext& ConfigurationContext::operator=(ConfigurationContext&&) = default;\r\n\r\n    ConfigurationProcessor& ConfigurationContext::Processor()\r\n    {\r\n        return m_data->Processor;\r\n    }\r\n\r\n    const ConfigurationProcessor& ConfigurationContext::Processor() const\r\n    {\r\n        return m_data->Processor;\r\n    }\r\n\r\n    void ConfigurationContext::Processor(const ConfigurationProcessor& value)\r\n    {\r\n        m_data->Processor = value;\r\n    }\r\n\r\n    void ConfigurationContext::Processor(ConfigurationProcessor&& value)\r\n    {\r\n        m_data->Processor = std::move(value);\r\n    }\r\n\r\n    ConfigurationSet& ConfigurationContext::Set()\r\n    {\r\n        return m_data->Set;\r\n    }\r\n\r\n    const ConfigurationSet& ConfigurationContext::Set() const\r\n    {\r\n        return m_data->Set;\r\n    }\r\n\r\n    void ConfigurationContext::Set(const ConfigurationSet& value)\r\n    {\r\n        m_data->Set = value;\r\n    }\r\n\r\n    void ConfigurationContext::Set(ConfigurationSet&& value)\r\n    {\r\n        m_data->Set = std::move(value);\r\n    }\r\n\r\n    std::vector<ConfigurationSet>& ConfigurationContext::History()\r\n    {\r\n        return m_data->History;\r\n    }\r\n\r\n    const std::vector<ConfigurationSet>& ConfigurationContext::History() const\r\n    {\r\n        return m_data->History;\r\n    }\r\n\r\n    void ConfigurationContext::History(const winrt::Windows::Foundation::Collections::IVector<ConfigurationSet>& value)\r\n    {\r\n        std::vector<ConfigurationSet> history{ value.Size() };\r\n        value.GetMany(0, history);\r\n        m_data->History = std::move(history);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/ConfigurationContext.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <memory>\r\n#include <vector>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration\r\n{\r\n    struct ConfigurationProcessor;\r\n    struct ConfigurationSet;\r\n}\r\n\r\nnamespace AppInstaller::CLI::Execution\r\n{\r\n    namespace details\r\n    {\r\n        struct ConfigurationContextData;\r\n    }\r\n\r\n    struct ConfigurationContext\r\n    {\r\n        using ConfigurationSet = winrt::Microsoft::Management::Configuration::ConfigurationSet;\r\n\r\n        ConfigurationContext();\r\n        ~ConfigurationContext();\r\n\r\n        ConfigurationContext(ConfigurationContext&) = delete;\r\n        ConfigurationContext& operator=(ConfigurationContext&) = delete;\r\n\r\n        ConfigurationContext(ConfigurationContext&&);\r\n        ConfigurationContext& operator=(ConfigurationContext&&);\r\n\r\n        winrt::Microsoft::Management::Configuration::ConfigurationProcessor& Processor();\r\n        const winrt::Microsoft::Management::Configuration::ConfigurationProcessor& Processor() const;\r\n        void Processor(const winrt::Microsoft::Management::Configuration::ConfigurationProcessor& value);\r\n        void Processor(winrt::Microsoft::Management::Configuration::ConfigurationProcessor&& value);\r\n\r\n        ConfigurationSet& Set();\r\n        const ConfigurationSet& Set() const;\r\n        void Set(const ConfigurationSet& value);\r\n        void Set(ConfigurationSet&& value);\r\n\r\n        std::vector<ConfigurationSet>& History();\r\n        const std::vector<ConfigurationSet>& History() const;\r\n        void History(const winrt::Windows::Foundation::Collections::IVector<ConfigurationSet>& value);\r\n\r\n    private:\r\n        std::unique_ptr<details::ConfigurationContextData> m_data;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/ConfigurationDynamicRuntimeFactory.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/ConfigurationSetProcessorFactoryRemoting.h\"\r\n#include <AppInstallerErrors.h>\r\n#include <AppInstallerLanguageUtilities.h>\r\n#include <AppInstallerLogging.h>\r\n#include <AppInstallerStrings.h>\r\n#include <winget/ILifetimeWatcher.h>\r\n#include <winget/Security.h>\r\n#include <winrt/Microsoft.Management.Configuration.SetProcessorFactory.h>\r\n\r\nusing namespace winrt::Windows::Foundation;\r\nusing namespace winrt::Microsoft::Management::Configuration;\r\nusing namespace winrt::Windows::Storage;\r\n\r\nnamespace AppInstaller::CLI::ConfigurationRemoting\r\n{\r\n    namespace anonymous\r\n    {\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        constexpr std::wstring_view EnableTestModeTestGuid = L\"1e62d683-2999-44e7-81f7-6f8f35e8d731\";\r\n        constexpr std::wstring_view ForceHighIntegrityLevelUnitsTestGuid = L\"f698d20f-3584-4f28-bc75-28037e08e651\";\r\n        constexpr std::wstring_view EnableRestrictedIntegrityLevelTestGuid = L\"5cae3226-185f-4289-815c-3c089d238dc6\";\r\n\r\n        // Checks the configuration set metadata for a specific test guid that controls the behavior flow.\r\n        bool GetConfigurationSetMetadataOverride(const ConfigurationSet& configurationSet, const std::wstring_view& testGuid)\r\n        {\r\n            auto metadataOverride = configurationSet.Metadata().TryLookup(testGuid);\r\n            if (metadataOverride)\r\n            {\r\n                auto metadataOverrideProperty = metadataOverride.try_as<IPropertyValue>();\r\n                if (metadataOverrideProperty && metadataOverrideProperty.Type() == PropertyType::Boolean)\r\n                {\r\n                    return metadataOverrideProperty.GetBoolean();\r\n                }\r\n            }\r\n\r\n            return false;\r\n        }\r\n#endif\r\n\r\n        // This is implemented completely in the packaged context for now, if we want to make it more configurable, we will probably want to move it to configuration and\r\n        // have this implementation leverage that one with an event handler for the packaged specifics.\r\n        // TODO: Add SetProcessorFactory::IPwshConfigurationSetProcessorFactoryProperties and pass values along to sets on creation\r\n        //       In turn, any properties must only be set via the command line (or eventual UI requests to the user).\r\n        struct DynamicFactory : winrt::implements<DynamicFactory, IConfigurationSetProcessorFactory, SetProcessorFactory::IPwshConfigurationSetProcessorFactoryProperties, Collections::IMap<winrt::hstring, winrt::hstring>, winrt::cloaked<WinRT::ILifetimeWatcher>>, WinRT::LifetimeWatcherBase\r\n        {\r\n            DynamicFactory(ProcessorEngine processorEngine);\r\n\r\n            IConfigurationSetProcessor CreateSetProcessor(const ConfigurationSet& configurationSet);\r\n\r\n            winrt::event_token Diagnostics(const EventHandler<IDiagnosticInformation>& handler);\r\n            void Diagnostics(const winrt::event_token& token) noexcept;\r\n\r\n            DiagnosticLevel MinimumLevel();\r\n            void MinimumLevel(DiagnosticLevel value);\r\n\r\n            HRESULT STDMETHODCALLTYPE SetLifetimeWatcher(IUnknown* watcher);\r\n\r\n            IConfigurationSetProcessorFactory& DefaultFactory();\r\n\r\n            void SendDiagnostics(const IDiagnosticInformation& information);\r\n\r\n            Collections::IVectorView<winrt::hstring> AdditionalModulePaths() const\r\n            {\r\n                THROW_HR(E_NOTIMPL);\r\n            }\r\n\r\n            void AdditionalModulePaths(const Collections::IVectorView<winrt::hstring>&)\r\n            {\r\n                THROW_HR(E_NOTIMPL);\r\n            }\r\n\r\n            SetProcessorFactory::PwshConfigurationProcessorPolicy Policy() const\r\n            {\r\n                THROW_HR(E_NOTIMPL);\r\n            }\r\n\r\n            void Policy(SetProcessorFactory::PwshConfigurationProcessorPolicy)\r\n            {\r\n                THROW_HR(E_NOTIMPL);\r\n            }\r\n\r\n            SetProcessorFactory::PwshConfigurationProcessorLocation Location() const\r\n            {\r\n                return m_location;\r\n            }\r\n\r\n            void Location(SetProcessorFactory::PwshConfigurationProcessorLocation value)\r\n            {\r\n                auto pwshFactory = m_defaultRemoteFactory.as<SetProcessorFactory::IPwshConfigurationSetProcessorFactoryProperties>();\r\n                pwshFactory.Location(value);\r\n                m_location = value;\r\n            }\r\n\r\n            winrt::hstring CustomLocation() const\r\n            {\r\n                return m_customLocation;\r\n            }\r\n\r\n            void CustomLocation(winrt::hstring value)\r\n            {\r\n                auto pwshFactory = m_defaultRemoteFactory.as<SetProcessorFactory::IPwshConfigurationSetProcessorFactoryProperties>();\r\n                pwshFactory.CustomLocation(value);\r\n                m_customLocation = value;\r\n            }\r\n\r\n            // Implement a subset of IMap to enable property bag semantics\r\n            uint32_t Size() { THROW_HR(E_NOTIMPL); }\r\n            void Clear() { THROW_HR(E_NOTIMPL); }\r\n            Collections::IMapView<winrt::hstring, winrt::hstring> GetView() { THROW_HR(E_NOTIMPL); }\r\n            bool HasKey(winrt::hstring) { THROW_HR(E_NOTIMPL); }\r\n            void Remove(winrt::hstring) { THROW_HR(E_NOTIMPL); }\r\n\r\n            bool Insert(winrt::hstring key, winrt::hstring value)\r\n            {\r\n                auto result = m_defaultRemoteFactory.as<Collections::IMap<winrt::hstring, winrt::hstring>>().Insert(key, value);\r\n                m_factoryMapValues[key] = value;\r\n                return result;\r\n            }\r\n\r\n            winrt::hstring Lookup(winrt::hstring key)\r\n            {\r\n                return m_defaultRemoteFactory.as<Collections::IMap<winrt::hstring, winrt::hstring>>().Lookup(key);\r\n            }\r\n\r\n            ProcessorEngine Engine() const\r\n            {\r\n                return m_processorEngine;\r\n            }\r\n\r\n            std::optional<winrt::hstring> GetFactoryMapValue(winrt::hstring key)\r\n            {\r\n                auto itr = m_factoryMapValues.find(key);\r\n                return itr != m_factoryMapValues.end() ? std::make_optional(itr->second) : std::nullopt;\r\n            }\r\n\r\n        private:\r\n            IConfigurationSetProcessorFactory m_defaultRemoteFactory;\r\n            winrt::event<EventHandler<IDiagnosticInformation>> m_diagnostics;\r\n            IConfigurationSetProcessorFactory::Diagnostics_revoker m_factoryDiagnosticsEventRevoker;\r\n            std::mutex m_diagnosticsMutex;\r\n            DiagnosticLevel m_minimumLevel = DiagnosticLevel::Informational;\r\n            SetProcessorFactory::PwshConfigurationProcessorLocation m_location = SetProcessorFactory::PwshConfigurationProcessorLocation::Default;\r\n            winrt::hstring m_customLocation;\r\n            ProcessorEngine m_processorEngine;\r\n            std::map<winrt::hstring, winrt::hstring> m_factoryMapValues;\r\n        };\r\n\r\n        struct DynamicProcessorInfo\r\n        {\r\n            IConfigurationSetProcessorFactory Factory;\r\n            IConfigurationSetProcessor Processor;\r\n            IConfigurationSetProcessorFactory::Diagnostics_revoker DiagnosticsEventRevoker;\r\n        };\r\n\r\n        struct DynamicSetProcessor : winrt::implements<DynamicSetProcessor, IConfigurationSetProcessor, IFindUnitProcessorsSetProcessor>\r\n        {\r\n            using ProcessorMap = std::map<Security::IntegrityLevel, DynamicProcessorInfo>;\r\n\r\n            DynamicSetProcessor(winrt::com_ptr<DynamicFactory> dynamicFactory, IConfigurationSetProcessor defaultRemoteSetProcessor, const ConfigurationSet& configurationSet) :\r\n                m_dynamicFactory(std::move(dynamicFactory)), m_configurationSet(configurationSet)\r\n            {\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n                if (m_configurationSet)\r\n                {\r\n                    m_enableTestMode = GetConfigurationSetMetadataOverride(m_configurationSet, EnableTestModeTestGuid);\r\n                    m_enableRestrictedIntegrityLevel = GetConfigurationSetMetadataOverride(m_configurationSet, EnableRestrictedIntegrityLevelTestGuid);\r\n                    m_forceHighIntegrityLevelUnits = GetConfigurationSetMetadataOverride(m_configurationSet, ForceHighIntegrityLevelUnitsTestGuid);\r\n                }\r\n\r\n                m_currentIntegrityLevel = m_enableTestMode ? Security::IntegrityLevel::Medium : Security::GetEffectiveIntegrityLevel();\r\n#else\r\n                m_currentIntegrityLevel = Security::GetEffectiveIntegrityLevel();\r\n#endif\r\n\r\n                m_setIntegrityLevel = m_currentIntegrityLevel;\r\n\r\n                if (m_configurationSet)\r\n                {\r\n                    m_setIntegrityLevel = SecurityContextToIntegrityLevel(m_configurationSet.Environment().Context());\r\n\r\n                    // Check for multiple integrity level requirements\r\n                    bool multipleIntegrityLevels = false;\r\n                    bool higherIntegrityLevelsThanCurrent = false;\r\n                    for (const auto& environment : m_configurationSet.GetUnitEnvironments())\r\n                    {\r\n                        auto integrityLevel = SecurityContextToIntegrityLevel(environment.Context());\r\n                        if (integrityLevel != m_currentIntegrityLevel)\r\n                        {\r\n                            multipleIntegrityLevels = true;\r\n\r\n                            if (ToIntegral(m_currentIntegrityLevel) < ToIntegral(integrityLevel))\r\n                            {\r\n                                higherIntegrityLevelsThanCurrent = true;\r\n                                break;\r\n                            }\r\n                        }\r\n                    }\r\n\r\n                    // Prevent supplied parameters from crossing integrity levels\r\n                    for (const auto& parameter : m_configurationSet.Parameters())\r\n                    {\r\n                        if (parameter.ProvidedValue() != nullptr)\r\n                        {\r\n                            THROW_HR_IF(WINGET_CONFIG_ERROR_PARAMETER_INTEGRITY_BOUNDARY, higherIntegrityLevelsThanCurrent || (multipleIntegrityLevels && parameter.IsSecure()));\r\n                        }\r\n                    }\r\n                }\r\n\r\n                m_setProcessors.emplace(m_currentIntegrityLevel, DynamicProcessorInfo{ m_dynamicFactory->DefaultFactory(), defaultRemoteSetProcessor});\r\n            }\r\n\r\n            IConfigurationUnitProcessorDetails GetUnitProcessorDetails(const ConfigurationUnit& unit, ConfigurationUnitDetailFlags detailFlags)\r\n            {\r\n                // Always get processor details from the current integrity level\r\n                return m_setProcessors[m_currentIntegrityLevel].Processor.GetUnitProcessorDetails(unit, detailFlags);\r\n            }\r\n\r\n            // Creates a configuration unit processor for the given unit.\r\n            IConfigurationUnitProcessor CreateUnitProcessor(const ConfigurationUnit& unit)\r\n            {\r\n                // Determine and create set processors for all required integrity levels.\r\n                // Doing this here avoids creating them if the only call is going to be for details (ex. `configure show`) \r\n                std::call_once(m_createUnitSetProcessorsOnce,\r\n                    [&]()\r\n                    {\r\n                        if (m_configurationSet)\r\n                        {\r\n                            for (const auto& environment : m_configurationSet.GetUnitEnvironments())\r\n                            {\r\n                                Security::IntegrityLevel requiredIntegrityLevel = SecurityContextToIntegrityLevel(environment.Context());\r\n\r\n                                if (m_setProcessors.find(requiredIntegrityLevel) == m_setProcessors.end())\r\n                                {\r\n                                    CreateSetProcessorForIntegrityLevel(requiredIntegrityLevel);\r\n                                }\r\n                            }\r\n                        }\r\n                    });\r\n\r\n                // Create set and unit processor for current unit.\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n                Security::IntegrityLevel requiredIntegrityLevel = m_forceHighIntegrityLevelUnits ? Security::IntegrityLevel::High : GetIntegrityLevelForUnit(unit);\r\n#else\r\n                Security::IntegrityLevel requiredIntegrityLevel = GetIntegrityLevelForUnit(unit);\r\n#endif\r\n\r\n                auto itr = m_setProcessors.find(requiredIntegrityLevel);\r\n                if (itr == m_setProcessors.end())\r\n                {\r\n                    THROW_WIN32_IF_MSG(ERROR_NOT_SUPPORTED, !m_configurationSet, \"Using configuration unit integrity level other than current level without a configuration set is not supported.\");\r\n                    itr = CreateSetProcessorForIntegrityLevel(requiredIntegrityLevel);\r\n                }\r\n\r\n                return itr->second.Processor.CreateUnitProcessor(unit);\r\n            }\r\n\r\n            Collections::IVector<IConfigurationUnitProcessorDetails> FindUnitProcessors(const FindUnitProcessorsOptions& findOptions)\r\n            {\r\n                IFindUnitProcessorsSetProcessor findUnitProcessorsSetProcessor;\r\n\r\n                if (m_setProcessors[m_currentIntegrityLevel].Processor.try_as<IFindUnitProcessorsSetProcessor>(findUnitProcessorsSetProcessor))\r\n                {\r\n                    return findUnitProcessorsSetProcessor.FindUnitProcessors(findOptions);\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(Config, Error, << \"Set Processor does not support FindUnitProcessors operation\");\r\n                    THROW_HR(WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR);\r\n                }\r\n            }\r\n\r\n        private:\r\n            // Converts the string representation of SecurityContext to the target integrity level for this instance\r\n            Security::IntegrityLevel SecurityContextToIntegrityLevel(SecurityContext securityContext)\r\n            {\r\n                switch (securityContext)\r\n                {\r\n                case SecurityContext::Current:\r\n                    return m_setIntegrityLevel;\r\n                case SecurityContext::Restricted:\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n                    if (m_enableRestrictedIntegrityLevel)\r\n                    {\r\n                        return Security::IntegrityLevel::Medium;\r\n                    }\r\n                    else\r\n#endif\r\n                    {\r\n                        // Not supporting elevated callers downgrading at the moment.\r\n                        THROW_WIN32(ERROR_NOT_SUPPORTED);\r\n\r\n                        // Technically this means the default level of the user token, so if UAC is disabled it would be the only integrity level (aka current).\r\n                        // return Security::IntegrityLevel::Medium;\r\n                    }\r\n                case SecurityContext::Elevated:\r\n                    return Security::IntegrityLevel::High;\r\n                default:\r\n                    THROW_WIN32(ERROR_NOT_SUPPORTED);\r\n                }\r\n            }\r\n\r\n            // Gets the integrity level that the given unit should be run at\r\n            Security::IntegrityLevel GetIntegrityLevelForUnit(const ConfigurationUnit& unit)\r\n            {\r\n                return SecurityContextToIntegrityLevel(unit.Environment().Context());\r\n            }\r\n\r\n            // Serializes the set properties to be sent to the remote server\r\n            std::string SerializeSetProperties()\r\n            {\r\n                Json::Value json{ Json::ValueType::objectValue };\r\n\r\n                json[\"path\"] = winrt::to_string(m_configurationSet.Path());\r\n\r\n                std::string locationString;\r\n                switch (m_dynamicFactory->Location())\r\n                {\r\n                case SetProcessorFactory::PwshConfigurationProcessorLocation::AllUsers:\r\n                    locationString = \"AllUsers\";\r\n                    break;\r\n                case SetProcessorFactory::PwshConfigurationProcessorLocation::CurrentUser:\r\n                    locationString = \"CurrentUser\";\r\n                    break;\r\n                case SetProcessorFactory::PwshConfigurationProcessorLocation::Custom:\r\n                    locationString = Utility::ConvertToUTF8(m_dynamicFactory->CustomLocation());\r\n                    break;\r\n                case SetProcessorFactory::PwshConfigurationProcessorLocation::Default:\r\n                    break;\r\n                }\r\n\r\n                if (!locationString.empty())\r\n                {\r\n                    json[\"modulePath\"] = locationString;\r\n                }\r\n\r\n                // Ensure that we always pass a path to the executable\r\n                if (m_dynamicFactory->Engine() == ProcessorEngine::DSCv3)\r\n                {\r\n                    winrt::hstring dscExecutablePathPropertyName = ToHString(PropertyName::DscExecutablePath);\r\n                    std::optional<winrt::hstring> dscExecutablePath = m_dynamicFactory->GetFactoryMapValue(dscExecutablePathPropertyName);\r\n\r\n                    if (!dscExecutablePath)\r\n                    {\r\n                        dscExecutablePath = m_dynamicFactory->Lookup(ToHString(PropertyName::FoundDscExecutablePath));\r\n                    }\r\n\r\n                    if (dscExecutablePath->empty())\r\n                    {\r\n                        // This is backstop to prevent a case where dsc.exe not found.\r\n                        AICLI_LOG(Config, Error, << \"Could not find dsc.exe, it must be provided by the user.\");\r\n                        THROW_WIN32(ERROR_FILE_NOT_FOUND);\r\n                    }\r\n\r\n                    json[\"processorPath\"] = Utility::ConvertToUTF8(dscExecutablePath.value());\r\n                }\r\n\r\n                Json::StreamWriterBuilder writerBuilder;\r\n                writerBuilder.settings_[\"indentation\"] = \"\\t\";\r\n                return Json::writeString(writerBuilder, json);\r\n            }\r\n\r\n            /// <summary>\r\n            /// Creates a separate configuration set containing high integrity units and returns the serialized string value.\r\n            /// </summary>\r\n            /// <returns>Serialized string value.</returns>\r\n            std::string SerializeHighIntegrityLevelSet()\r\n            {\r\n                ConfigurationSet highIntegritySet;\r\n                highIntegritySet.SchemaVersion(m_configurationSet.SchemaVersion());\r\n                highIntegritySet.Metadata(m_configurationSet.Metadata());\r\n                highIntegritySet.Parameters(m_configurationSet.Parameters());\r\n                highIntegritySet.Variables(m_configurationSet.Variables());\r\n\r\n                std::vector<ConfigurationUnit> highIntegrityUnits;\r\n                auto units = m_configurationSet.Units();\r\n\r\n                for (auto unit : units)\r\n                {\r\n                    if (unit.IsActive() && GetIntegrityLevelForUnit(unit) == Security::IntegrityLevel::High)\r\n                    {\r\n                        highIntegrityUnits.emplace_back(unit);\r\n                    }\r\n                }\r\n\r\n                highIntegritySet.Units(std::move(highIntegrityUnits));\r\n\r\n                // Serialize high integrity set and return output string.\r\n                Streams::InMemoryRandomAccessStream memoryStream;\r\n                highIntegritySet.Serialize(memoryStream);\r\n\r\n                Streams::DataReader reader(memoryStream.GetInputStreamAt(0));\r\n                THROW_HR_IF(E_UNEXPECTED, memoryStream.Size() > std::numeric_limits<uint32_t>::max());\r\n                uint32_t streamSize = (uint32_t)memoryStream.Size();\r\n                std::vector<uint8_t> bytes;\r\n                bytes.resize(streamSize);\r\n                reader.LoadAsync(streamSize);\r\n                reader.ReadBytes(bytes);\r\n                reader.DetachStream();\r\n                memoryStream.Close();\r\n\r\n                return { bytes.begin(), bytes.end() };\r\n            }\r\n\r\n            ProcessorMap::iterator CreateSetProcessorForIntegrityLevel(Security::IntegrityLevel integrityLevel)\r\n            {\r\n                IConfigurationSetProcessorFactory factory;\r\n                IConfigurationSetProcessorFactory::Diagnostics_revoker factoryDiagnosticsEventRevoker;\r\n\r\n                // If we got here, the only option is that the current integrity level is not High.\r\n                if (integrityLevel == Security::IntegrityLevel::High)\r\n                {\r\n                    bool useRunAs = true;\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n                    useRunAs = !m_enableTestMode;\r\n#endif\r\n\r\n                    factory = CreateOutOfProcessFactory(m_dynamicFactory->Engine(), useRunAs, SerializeSetProperties(), SerializeHighIntegrityLevelSet());\r\n                }\r\n                else\r\n                {\r\n                    THROW_WIN32(ERROR_NOT_SUPPORTED);\r\n                }\r\n\r\n                if (factory)\r\n                {\r\n                    factory.MinimumLevel(m_dynamicFactory->MinimumLevel());\r\n                    factoryDiagnosticsEventRevoker = factory.Diagnostics(winrt::auto_revoke,\r\n                        [weak_this{ get_weak() }](const IInspectable&, const IDiagnosticInformation& information)\r\n                        {\r\n                            if (auto strong_this{ weak_this.get() })\r\n                            {\r\n                                strong_this->m_dynamicFactory->SendDiagnostics(information);\r\n                            }\r\n                        });\r\n\r\n                    winrt::hstring propertyName = ConfigurationRemoting::ToHString(ConfigurationRemoting::PropertyName::DiagnosticTraceEnabled);\r\n                    if (auto propertyValue = m_dynamicFactory->GetFactoryMapValue(propertyName))\r\n                    {\r\n                        factory.as<Collections::IMap<winrt::hstring, winrt::hstring>>().Insert(propertyName, propertyValue.value());\r\n                    }\r\n                }\r\n\r\n                return m_setProcessors.emplace(integrityLevel, DynamicProcessorInfo{ factory, factory.CreateSetProcessor(m_configurationSet), std::move(factoryDiagnosticsEventRevoker) }).first;\r\n            }\r\n\r\n            winrt::com_ptr<DynamicFactory> m_dynamicFactory;\r\n            Security::IntegrityLevel m_currentIntegrityLevel;\r\n            Security::IntegrityLevel m_setIntegrityLevel;\r\n            ProcessorMap m_setProcessors;\r\n            ConfigurationSet m_configurationSet;\r\n            std::once_flag m_createUnitSetProcessorsOnce;\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n            bool m_enableTestMode = false;\r\n            bool m_enableRestrictedIntegrityLevel = false;\r\n            bool m_forceHighIntegrityLevelUnits = false;\r\n#endif\r\n        };\r\n\r\n        DynamicFactory::DynamicFactory(ProcessorEngine processorEngine)\r\n        {\r\n            m_processorEngine = processorEngine;\r\n            m_defaultRemoteFactory = CreateOutOfProcessFactory(processorEngine);\r\n\r\n            if (m_defaultRemoteFactory)\r\n            {\r\n                m_factoryDiagnosticsEventRevoker = m_defaultRemoteFactory.Diagnostics(winrt::auto_revoke,\r\n                    [weak_this{ get_weak() }](const IInspectable&, const IDiagnosticInformation& information)\r\n                    {\r\n                        if (auto strong_this{ weak_this.get() })\r\n                        {\r\n                            strong_this->SendDiagnostics(information);\r\n                        }\r\n                    });\r\n            }\r\n        }\r\n\r\n        IConfigurationSetProcessor DynamicFactory::CreateSetProcessor(const ConfigurationSet& configurationSet)\r\n        {\r\n            return winrt::make<DynamicSetProcessor>(get_strong(), m_defaultRemoteFactory.CreateSetProcessor(configurationSet), configurationSet);\r\n        }\r\n\r\n        winrt::event_token DynamicFactory::Diagnostics(const EventHandler<IDiagnosticInformation>& handler)\r\n        {\r\n            return m_diagnostics.add(handler);\r\n        }\r\n\r\n        void DynamicFactory::Diagnostics(const winrt::event_token& token) noexcept\r\n        {\r\n            m_diagnostics.remove(token);\r\n        }\r\n\r\n        DiagnosticLevel DynamicFactory::MinimumLevel()\r\n        {\r\n            return m_minimumLevel;\r\n        }\r\n\r\n        void DynamicFactory::MinimumLevel(DiagnosticLevel value)\r\n        {\r\n            m_minimumLevel = value;\r\n\r\n            if (m_defaultRemoteFactory)\r\n            {\r\n                m_defaultRemoteFactory.MinimumLevel(value);\r\n            }\r\n        }\r\n\r\n        HRESULT STDMETHODCALLTYPE DynamicFactory::SetLifetimeWatcher(IUnknown* watcher)\r\n        {\r\n            return WinRT::LifetimeWatcherBase::SetLifetimeWatcher(watcher);\r\n        }\r\n\r\n        IConfigurationSetProcessorFactory& DynamicFactory::DefaultFactory()\r\n        {\r\n            return m_defaultRemoteFactory;\r\n        }\r\n\r\n        void DynamicFactory::SendDiagnostics(const IDiagnosticInformation& information) try\r\n        {\r\n            if (information.Level() >= m_minimumLevel)\r\n            {\r\n                std::lock_guard<std::mutex> lock{ m_diagnosticsMutex };\r\n                m_diagnostics(*this, information);\r\n            }\r\n        }\r\n        // While diagnostics can be important, a failure to send them should not cause additional issues.\r\n        catch (...) {}\r\n    }\r\n\r\n    winrt::Microsoft::Management::Configuration::IConfigurationSetProcessorFactory CreateDynamicRuntimeFactory(ProcessorEngine processorEngine)\r\n    {\r\n        return winrt::make<anonymous::DynamicFactory>(processorEngine);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/ConfigurationSetProcessorFactoryRemoting.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/ConfigurationSetProcessorFactoryRemoting.h\"\r\n#include <AppInstallerErrors.h>\r\n#include <AppInstallerLanguageUtilities.h>\r\n#include <AppInstallerLogging.h>\r\n#include <AppInstallerRuntime.h>\r\n#include <AppInstallerStrings.h>\r\n#include <winget/ExperimentalFeature.h>\r\n#include <winget/ILifetimeWatcher.h>\r\n#include <winrt/Microsoft.Management.Configuration.SetProcessorFactory.h>\r\n\r\nusing namespace winrt::Windows::Foundation;\r\nusing namespace winrt::Microsoft::Management::Configuration;\r\nusing namespace std::string_view_literals;\r\n\r\nnamespace AppInstaller::CLI::ConfigurationRemoting\r\n{\r\n    namespace\r\n    {\r\n        // The executable file name for the remote server process.\r\n        constexpr std::wstring_view s_RemoteServerFileName = L\"DotNet\\\\ConfigurationRemotingServer.exe\"sv;\r\n\r\n        constexpr std::wstring_view s_ProcessorEngine_PowerShell = L\"pwsh\"sv;\r\n        constexpr std::wstring_view s_ProcessorEngine_DSCv3 = L\"dscv3\"sv;\r\n\r\n        // The string used to divide the arguments sent to the remote server\r\n        constexpr std::wstring_view s_ArgumentsDivider = L\"\\n~~~~~~\\n\"sv;\r\n\r\n        // A helper with a convenient function that we use to receive the remote factory object.\r\n        struct RemoteFactoryCallback : winrt::implements<RemoteFactoryCallback, IConfigurationStatics>\r\n        {\r\n            RemoteFactoryCallback()\r\n            {\r\n                m_initEvent.create();\r\n            }\r\n\r\n            ConfigurationUnit CreateConfigurationUnit()\r\n            {\r\n                THROW_HR(E_NOTIMPL);\r\n            }\r\n\r\n            ConfigurationSet CreateConfigurationSet()\r\n            {\r\n                THROW_HR(E_NOTIMPL);\r\n            }\r\n\r\n            IAsyncOperation<IConfigurationSetProcessorFactory> CreateConfigurationSetProcessorFactoryAsync(winrt::hstring handler)\r\n            {\r\n                // TODO: Ensure calling process has same package identity\r\n                std::wstringstream stringStream{ std::wstring{ static_cast<std::wstring_view>(handler) } };\r\n                stringStream >> m_result;\r\n                m_initEvent.SetEvent();\r\n                return nullptr;\r\n            }\r\n\r\n            ConfigurationProcessor CreateConfigurationProcessor(IConfigurationSetProcessorFactory factory)\r\n            {\r\n                // TODO: Ensure calling process has same package identity\r\n                m_factory = factory;\r\n                m_initEvent.SetEvent();\r\n                return nullptr;\r\n            }\r\n\r\n            bool IsConfigurationAvailable()\r\n            {\r\n                THROW_HR(E_NOTIMPL);\r\n            }\r\n\r\n            IAsyncActionWithProgress<uint32_t> EnsureConfigurationAvailableAsync()\r\n            {\r\n                THROW_HR(E_NOTIMPL);\r\n            }\r\n\r\n            IConfigurationSetProcessorFactory Wait(HANDLE process)\r\n            {\r\n                HANDLE waitHandles[2];\r\n                waitHandles[0] = m_initEvent.get();\r\n                waitHandles[1] = process;\r\n\r\n                for (;;)\r\n                {\r\n                    // Wait up to 10 seconds for the server to complete initialization.\r\n                    // This time is fairly arbitrary, although it does correspond with the maximum time for a COM fast rundown.\r\n                    DWORD waitResult = WaitForMultipleObjects(ARRAYSIZE(waitHandles), waitHandles, FALSE, 10000);\r\n                    THROW_LAST_ERROR_IF(waitResult == WAIT_FAILED);\r\n\r\n                    // The init event was signaled.\r\n                    if (waitResult == WAIT_OBJECT_0)\r\n                    {\r\n                        break;\r\n                    }\r\n\r\n                    // Don't break things if the process is being debugged\r\n                    if (waitResult == WAIT_TIMEOUT && IsDebuggerPresent())\r\n                    {\r\n                        continue;\r\n                    }\r\n\r\n                    // If the process exited, then try to use the exit code.\r\n                    DWORD processExitCode = 0;\r\n                    if (waitResult == (WAIT_OBJECT_0 + 1) && GetExitCodeProcess(process, &processExitCode) && FAILED(processExitCode))\r\n                    {\r\n                        THROW_HR(static_cast<HRESULT>(processExitCode));\r\n                    }\r\n                    else\r\n                    {\r\n                        // The server timed out or didn't have a failed exit code.\r\n                        THROW_HR(E_FAIL);\r\n                    }\r\n                }\r\n\r\n                THROW_IF_FAILED(m_result);\r\n\r\n                // Double-check the result\r\n                THROW_HR_IF(E_POINTER, !m_factory);\r\n                return m_factory;\r\n            }\r\n\r\n        private:\r\n            IConfigurationSetProcessorFactory m_factory;\r\n            HRESULT m_result = S_OK;\r\n            wil::unique_event m_initEvent;\r\n        };\r\n\r\n        // Represents a remote factory object that was created from a specific process.\r\n        struct RemoteFactory : winrt::implements<RemoteFactory, IConfigurationSetProcessorFactory, SetProcessorFactory::IPwshConfigurationSetProcessorFactoryProperties, Collections::IMap<winrt::hstring, winrt::hstring>, winrt::cloaked<WinRT::ILifetimeWatcher>>, WinRT::LifetimeWatcherBase\r\n        {\r\n            RemoteFactory(ProcessorEngine processorEngine, bool useRunAs, const std::string& properties, const std::string& restrictions)\r\n            {\r\n                AICLI_LOG(Config, Verbose, << \"Launching process for configuration processing...\");\r\n\r\n                // Create our callback and marshal it\r\n                auto callback = winrt::make_self<RemoteFactoryCallback>();\r\n\r\n                wil::com_ptr<IStream> stream;\r\n                THROW_IF_FAILED(CreateStreamOnHGlobal(nullptr, TRUE, &stream));\r\n\r\n                THROW_IF_FAILED(CoMarshalInterface(stream.get(), winrt::guid_of<IConfigurationStatics>(), reinterpret_cast<::IUnknown*>(winrt::get_abi(callback.as<IConfigurationStatics>())), MSHCTX_LOCAL, nullptr, MSHLFLAGS_NORMAL));\r\n\r\n                ULARGE_INTEGER streamSize{};\r\n                THROW_IF_FAILED(stream->Seek({}, STREAM_SEEK_CUR, &streamSize));\r\n\r\n                ULONG bufferSize = static_cast<ULONG>(streamSize.QuadPart);\r\n                std::vector<uint8_t> buffer;\r\n                buffer.resize(bufferSize);\r\n\r\n                THROW_IF_FAILED(stream->Seek({}, STREAM_SEEK_SET, nullptr));\r\n                ULONG bytesRead = 0;\r\n                THROW_IF_FAILED(stream->Read(&buffer[0], bufferSize, &bytesRead));\r\n                THROW_HR_IF(E_UNEXPECTED, bytesRead != bufferSize);\r\n\r\n                std::wstring marshalledCallback = Utility::ConvertToUTF16(Utility::ConvertToHexString(buffer));\r\n\r\n                // Create the event that the remote process will wait on to keep the object alive.\r\n                std::wstring completionEventName = Utility::CreateNewGuidNameWString();\r\n                m_completionEvent.create(wil::EventOptions::None, completionEventName.c_str());\r\n                auto completeEventIfFailureDuringConstruction = wil::scope_exit([&]() { m_completionEvent.SetEvent(); });\r\n\r\n                // This will be presented to the user so it must be formatted nicely.\r\n                // Arguments are:\r\n                // server.exe <marshalled callback object> <completion event name> <this process id>\r\n                // \r\n                // Optionally, we may also place additional data that limits what the server may do as:\r\n                // ~~~~~~\r\n                // { \"JSON properties\" }\r\n                // ~~~~~~\r\n                // YAML configuration set definition\r\n                std::wostringstream argumentsStream;\r\n                argumentsStream << s_RemoteServerFileName << L' ' << marshalledCallback << L' ' << completionEventName << L' ' << GetCurrentProcessId() << L' ' << ToString(processorEngine);\r\n\r\n                if (!properties.empty() && !restrictions.empty())\r\n                {\r\n                    argumentsStream << L' ' << s_ArgumentsDivider << Utility::ConvertToUTF16(properties) << s_ArgumentsDivider << Utility::ConvertToUTF16(restrictions);\r\n                }\r\n\r\n                std::wstring arguments = argumentsStream.str();\r\n\r\n                std::filesystem::path serverPath = Runtime::GetPathTo(Runtime::PathName::SelfPackageRoot);\r\n                serverPath /= s_RemoteServerFileName;\r\n                std::wstring serverPathString = serverPath.wstring();\r\n\r\n                // Per documentation, the maximum length is 32767 *counting* the null.\r\n                THROW_WIN32_IF(ERROR_BUFFER_OVERFLOW, serverPathString.length() > 32766);\r\n                THROW_WIN32_IF(ERROR_BUFFER_OVERFLOW, arguments.length() > 32766);\r\n                // Overflow safe since we verify that each of the individual strings is also small.\r\n                // +1 for the space between the path and args.\r\n                THROW_WIN32_IF(ERROR_BUFFER_OVERFLOW, serverPathString.length() + 1 + arguments.length() > 32766);\r\n\r\n                SHELLEXECUTEINFOW execInfo = { 0 };\r\n                execInfo.cbSize = sizeof(execInfo);\r\n                execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI | SEE_MASK_NO_CONSOLE;\r\n                execInfo.lpFile = serverPath.c_str();\r\n                execInfo.lpParameters = arguments.c_str();\r\n                execInfo.nShow = SW_HIDE;\r\n\r\n                if (useRunAs)\r\n                {\r\n                    execInfo.lpVerb = L\"runas\";\r\n                }\r\n\r\n                THROW_LAST_ERROR_IF(!ShellExecuteExW(&execInfo) || !execInfo.hProcess);\r\n\r\n                wil::unique_process_handle process{ execInfo.hProcess };\r\n                AICLI_LOG(Config, Verbose, << \"  Configuration remote PID is \" << GetProcessId(process.get()));\r\n\r\n                m_remoteFactory = callback->Wait(process.get());\r\n                AICLI_LOG(Config, Verbose, << \"... configuration processing connection established.\");\r\n\r\n                completeEventIfFailureDuringConstruction.release();\r\n            }\r\n\r\n            ~RemoteFactory()\r\n            {\r\n                m_completionEvent.SetEvent();\r\n            }\r\n\r\n            IConfigurationSetProcessor CreateSetProcessor(const ConfigurationSet& configurationSet)\r\n            {\r\n                return m_remoteFactory.CreateSetProcessor(configurationSet);\r\n            }\r\n\r\n            winrt::event_token Diagnostics(const EventHandler<IDiagnosticInformation>& handler)\r\n            {\r\n                return m_remoteFactory.Diagnostics(handler);\r\n            }\r\n\r\n            void Diagnostics(const winrt::event_token& token) noexcept\r\n            {\r\n                m_remoteFactory.Diagnostics(token);\r\n            }\r\n\r\n            DiagnosticLevel MinimumLevel()\r\n            {\r\n                return m_remoteFactory.MinimumLevel();\r\n            }\r\n\r\n            void MinimumLevel(DiagnosticLevel value)\r\n            {\r\n                m_remoteFactory.MinimumLevel(value);\r\n            }\r\n\r\n            Collections::IVectorView<winrt::hstring> AdditionalModulePaths() const\r\n            {\r\n                return m_additionalModulePaths.GetView();\r\n            }\r\n\r\n            void AdditionalModulePaths(const Collections::IVectorView<winrt::hstring>& value)\r\n            {\r\n                // Extract all values from incoming view\r\n                std::vector<winrt::hstring> newModulePaths{ value.Size() };\r\n                value.GetMany(0, newModulePaths);\r\n\r\n                // Create a copy for remote and set remote module paths\r\n                std::vector<winrt::hstring> newRemotePaths{ newModulePaths };\r\n                m_remoteAdditionalModulePaths = winrt::single_threaded_vector<winrt::hstring>(std::move(newRemotePaths));\r\n                m_remoteFactory.as<SetProcessorFactory::IPwshConfigurationSetProcessorFactoryProperties>().AdditionalModulePaths(m_remoteAdditionalModulePaths.GetView());\r\n\r\n                // Store the updated module paths that we were given\r\n                m_additionalModulePaths = winrt::single_threaded_vector<winrt::hstring>(std::move(newModulePaths));\r\n            }\r\n\r\n            SetProcessorFactory::PwshConfigurationProcessorPolicy Policy() const\r\n            {\r\n                return m_remoteFactory.as<SetProcessorFactory::IPwshConfigurationSetProcessorFactoryProperties>().Policy();\r\n            }\r\n\r\n            void Policy(SetProcessorFactory::PwshConfigurationProcessorPolicy value)\r\n            {\r\n                m_remoteFactory.as<SetProcessorFactory::IPwshConfigurationSetProcessorFactoryProperties>().Policy(value);\r\n            }\r\n\r\n            SetProcessorFactory::PwshConfigurationProcessorLocation Location() const\r\n            {\r\n                return m_remoteFactory.as<SetProcessorFactory::IPwshConfigurationSetProcessorFactoryProperties>().Location();\r\n            }\r\n\r\n            void Location(SetProcessorFactory::PwshConfigurationProcessorLocation value)\r\n            {\r\n                m_remoteFactory.as<SetProcessorFactory::IPwshConfigurationSetProcessorFactoryProperties>().Location(value);\r\n            }\r\n\r\n            winrt::hstring CustomLocation() const\r\n            {\r\n                return m_remoteFactory.as<SetProcessorFactory::IPwshConfigurationSetProcessorFactoryProperties>().CustomLocation();\r\n            }\r\n\r\n            void CustomLocation(winrt::hstring value)\r\n            {\r\n                m_remoteFactory.as<SetProcessorFactory::IPwshConfigurationSetProcessorFactoryProperties>().CustomLocation(value);\r\n            }\r\n\r\n            // Implement a subset of IMap to enable property bag semantics\r\n            uint32_t Size() { THROW_HR(E_NOTIMPL); }\r\n            void Clear() { THROW_HR(E_NOTIMPL); }\r\n            Collections::IMapView<winrt::hstring, winrt::hstring> GetView() { THROW_HR(E_NOTIMPL); }\r\n            bool HasKey(winrt::hstring) { THROW_HR(E_NOTIMPL); }\r\n            void Remove(winrt::hstring) { THROW_HR(E_NOTIMPL); }\r\n\r\n            bool Insert(winrt::hstring key, winrt::hstring value)\r\n            {\r\n                auto map = m_remoteFactory.try_as<Collections::IMap<winrt::hstring, winrt::hstring>>();\r\n                return map ? map.Insert(key, value) : false;\r\n            }\r\n\r\n            winrt::hstring Lookup(winrt::hstring key)\r\n            {\r\n                auto map = m_remoteFactory.try_as<Collections::IMap<winrt::hstring, winrt::hstring>>();\r\n                return map ? map.Lookup(key) : winrt::hstring{};\r\n            }\r\n\r\n            HRESULT STDMETHODCALLTYPE SetLifetimeWatcher(IUnknown* watcher)\r\n            {\r\n                return WinRT::LifetimeWatcherBase::SetLifetimeWatcher(watcher);\r\n            }\r\n\r\n        private:\r\n            IConfigurationSetProcessorFactory m_remoteFactory;\r\n            wil::unique_event m_completionEvent;\r\n            Collections::IVector<winrt::hstring> m_additionalModulePaths{ winrt::single_threaded_vector<winrt::hstring>() };\r\n            Collections::IVector<winrt::hstring> m_remoteAdditionalModulePaths{ winrt::single_threaded_vector<winrt::hstring>() };\r\n        };\r\n    }\r\n\r\n    IConfigurationSetProcessorFactory CreateOutOfProcessFactory(ProcessorEngine processorEngine, bool useRunAs, const std::string& properties, const std::string& restrictions)\r\n    {\r\n        return winrt::make<RemoteFactory>(processorEngine, useRunAs, properties, restrictions);\r\n    }\r\n\r\n    ProcessorEngine DetermineProcessorEngine(ConfigurationSet set)\r\n    {\r\n        Utility::Version schemaVersion{ Utility::ConvertToUTF8(set.SchemaVersion()) };\r\n\r\n        if (schemaVersion <= Utility::Version{ \"0.3\" })\r\n        {\r\n            ProcessorEngine result = ProcessorEngine::Unknown;\r\n\r\n            std::wstring processorIdentifier = Utility::ToLower(set.Environment().ProcessorIdentifier());\r\n            if (processorIdentifier.empty() || processorIdentifier == s_ProcessorEngine_PowerShell)\r\n            {\r\n                // Default to PowerShell\r\n                result = ProcessorEngine::PowerShell;\r\n            }\r\n            else if (processorIdentifier == s_ProcessorEngine_DSCv3)\r\n            {\r\n                result = ProcessorEngine::DSCv3;\r\n            }\r\n            else\r\n            {\r\n                AICLI_LOG(Config, Warning, << \"Unknown processor: \" << Utility::ConvertToUTF8(processorIdentifier));\r\n            }\r\n\r\n            return result;\r\n        }\r\n        else\r\n        {\r\n            // Intentionally fail out here until a decision is made.\r\n            THROW_HR(E_NOTIMPL);\r\n        }\r\n    }\r\n\r\n    std::wstring_view ToString(ProcessorEngine value)\r\n    {\r\n        switch (value)\r\n        {\r\n        case ProcessorEngine::PowerShell:\r\n            return s_ProcessorEngine_PowerShell;\r\n        case ProcessorEngine::DSCv3:\r\n            return s_ProcessorEngine_DSCv3;\r\n        default:\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n    }\r\n\r\n    winrt::hstring ToHString(PropertyName name)\r\n    {\r\n        switch (name)\r\n        {\r\n        case PropertyName::DscExecutablePath: return L\"DscExecutablePath\";\r\n        case PropertyName::FoundDscExecutablePath: return L\"FoundDscExecutablePath\";\r\n        case PropertyName::DiagnosticTraceEnabled: return L\"DiagnosticTraceEnabled\";\r\n        case PropertyName::FindDscStateMachine: return L\"FindDscStateMachine\";\r\n        }\r\n\r\n        THROW_HR(E_UNEXPECTED);\r\n    }\r\n}\r\n\r\nHRESULT WindowsPackageManagerConfigurationCompleteOutOfProcessFactoryInitialization(HRESULT result, void* factory, LPWSTR staticsCallback, LPWSTR completionEventName, DWORD parentProcessId) try\r\n{\r\n    {\r\n        wil::com_ptr<IGlobalOptions> globalOptions;\r\n        RETURN_IF_FAILED(CoCreateInstance(CLSID_GlobalOptions, nullptr, CLSCTX_INPROC, IID_PPV_ARGS(&globalOptions)));\r\n        RETURN_IF_FAILED(globalOptions->Set(COMGLB_RO_SETTINGS, COMGLB_FAST_RUNDOWN));\r\n        RETURN_IF_FAILED(globalOptions->Set(COMGLB_UNMARSHALING_POLICY, COMGLB_UNMARSHALING_POLICY_STRONG));\r\n        RETURN_IF_FAILED(globalOptions->Set(COMGLB_EXCEPTION_HANDLING, COMGLB_EXCEPTION_DONOT_HANDLE_ANY));\r\n    }\r\n\r\n    using namespace AppInstaller;\r\n    using namespace AppInstaller::CLI::ConfigurationRemoting;\r\n\r\n    RETURN_HR_IF(E_POINTER, !staticsCallback);\r\n\r\n    auto callbackBytes = Utility::ParseFromHexString(Utility::ConvertToUTF8(staticsCallback));\r\n    RETURN_HR_IF(E_INVALIDARG, callbackBytes.size() > (1 << 15));\r\n\r\n    wil::com_ptr<IStream> stream;\r\n    RETURN_IF_FAILED(CreateStreamOnHGlobal(nullptr, TRUE, &stream));\r\n    RETURN_IF_FAILED(stream->Write(&callbackBytes[0], static_cast<ULONG>(callbackBytes.size()), nullptr));\r\n    RETURN_IF_FAILED(stream->Seek({}, STREAM_SEEK_SET, nullptr));\r\n\r\n    wil::com_ptr<::IUnknown> output;\r\n    RETURN_IF_FAILED(CoUnmarshalInterface(stream.get(), winrt::guid_of<IConfigurationStatics>(), reinterpret_cast<void**>(&output)));\r\n\r\n    IConfigurationStatics callback{ output.detach(), winrt::take_ownership_from_abi };\r\n\r\n    if (FAILED(result))\r\n    {\r\n        std::ignore = callback.CreateConfigurationSetProcessorFactoryAsync(std::to_wstring(result));\r\n    }\r\n    else\r\n    {\r\n        IConfigurationSetProcessorFactory factoryObject;\r\n        winrt::copy_from_abi(factoryObject, factory);\r\n        std::ignore = callback.CreateConfigurationProcessor(factoryObject);\r\n    }\r\n\r\n    // Wait until the caller releases the object (signalling the event) or the parent process exits\r\n    wil::unique_event completionEvent;\r\n    completionEvent.open(completionEventName);\r\n    wil::unique_process_handle parentProcess{ OpenProcess(SYNCHRONIZE, FALSE, parentProcessId) };\r\n\r\n    HANDLE waitHandles[2];\r\n    waitHandles[0] = completionEvent.get();\r\n    waitHandles[1] = parentProcess.get();\r\n\r\n    std::ignore = WaitForMultipleObjects(ARRAYSIZE(waitHandles), waitHandles, FALSE, INFINITE);\r\n\r\n    return S_OK;\r\n}\r\nCATCH_RETURN();\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/ConfigurationWingetDscModuleUnitValidation.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigurationWingetDscModuleUnitValidation.h\"\r\n#include \"ExecutionContext.h\"\r\n#include <winrt/Microsoft.Management.Configuration.h>\r\n\r\nusing namespace winrt::Microsoft::Management::Configuration;\r\nusing namespace winrt::Windows::Foundation;\r\nusing namespace winrt::Windows::Foundation::Collections;\r\nusing namespace AppInstaller::Utility::literals;\r\n\r\nnamespace AppInstaller::CLI::Configuration\r\n{\r\n    namespace\r\n    {\r\n        constexpr static std::string_view UnitType_WinGetSource = \"WinGetSource\"sv;\r\n        constexpr static std::string_view UnitType_WinGetPackage = \"WinGetPackage\"sv;\r\n\r\n        constexpr static std::string_view WellKnownSourceName_WinGet = \"winget\"sv;\r\n        constexpr static std::string_view WellKnownSourceName_MSStore = \"msstore\"sv;\r\n        constexpr static std::string_view WellKnownSourceName_WinGetFont = \"winget-font\"sv;\r\n\r\n        constexpr static std::string_view ValueSetKey_TreatAsArray = \"treatAsArray\"sv;\r\n\r\n        constexpr static std::string_view WinGetSourceValueSetKey_Name = \"name\"sv;\r\n        constexpr static std::string_view WinGetSourceValueSetKey_Type = \"type\"sv;\r\n        constexpr static std::string_view WinGetSourceValueSetKey_Arg = \"argument\"sv;\r\n        constexpr static std::string_view WinGetSourceValueSetKey_Ensure = \"ensure\"sv;\r\n        constexpr static std::string_view WinGetSourceValueSetKey_Ensure_Present = \"present\"sv;\r\n\r\n        constexpr static std::string_view WinGetPackageValueSetKey_Id = \"id\"sv;\r\n        constexpr static std::string_view WinGetPackageValueSetKey_Version = \"version\"sv;\r\n        constexpr static std::string_view WinGetPackageValueSetKey_Source = \"source\"sv;\r\n        constexpr static std::string_view WinGetPackageValueSetKey_UseLatest = \"useLatest\"sv;\r\n\r\n        struct WinGetSource\r\n        {\r\n            std::string Name;\r\n            std::string Type;\r\n            std::string Arg;\r\n            bool Present = true;\r\n\r\n            bool Empty()\r\n            {\r\n                return Name.empty() && Arg.empty() && Type.empty();\r\n            }\r\n        };\r\n\r\n        std::string GetPropertyValueAsString(const winrt::Windows::Foundation::IInspectable& value)\r\n        {\r\n            IPropertyValue propertyValue = value.try_as<IPropertyValue>();\r\n            if (propertyValue && propertyValue.Type() == PropertyType::String)\r\n            {\r\n                return Utility::ConvertToUTF8(propertyValue.GetString());\r\n            }\r\n\r\n            return {};\r\n        }\r\n\r\n        bool GetPropertyValueAsBoolean(const winrt::Windows::Foundation::IInspectable& value, bool defaultIfFailed = false)\r\n        {\r\n            IPropertyValue propertyValue = value.try_as<IPropertyValue>();\r\n            if (propertyValue && propertyValue.Type() == PropertyType::Boolean)\r\n            {\r\n                return propertyValue.GetBoolean();\r\n            }\r\n\r\n            return defaultIfFailed;\r\n        }\r\n\r\n        WinGetSource ParseWinGetSourceFromSettings(const ValueSet& settings)\r\n        {\r\n            WinGetSource result;\r\n\r\n            // Iterate through the value set as Powershell variables are case-insensitive.\r\n            for (auto const& settingsPair : settings)\r\n            {\r\n                auto settingsKey = Utility::ConvertToUTF8(settingsPair.Key());\r\n\r\n                if (Utility::CaseInsensitiveEquals(WinGetSourceValueSetKey_Name, settingsKey))\r\n                {\r\n                    result.Name = GetPropertyValueAsString(settingsPair.Value());\r\n                }\r\n                else if (Utility::CaseInsensitiveEquals(WinGetSourceValueSetKey_Type, settingsKey))\r\n                {\r\n                    result.Type = GetPropertyValueAsString(settingsPair.Value());\r\n                }\r\n                else if (Utility::CaseInsensitiveEquals(WinGetSourceValueSetKey_Arg, settingsKey))\r\n                {\r\n                    result.Arg = GetPropertyValueAsString(settingsPair.Value());\r\n                }\r\n                else if (Utility::CaseInsensitiveEquals(WinGetSourceValueSetKey_Ensure, settingsKey))\r\n                {\r\n                    result.Present = Utility::CaseInsensitiveEquals(WinGetSourceValueSetKey_Ensure_Present, GetPropertyValueAsString(settingsPair.Value()));\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        bool IsWellKnownSourceName(std::string_view sourceName)\r\n        {\r\n            return Utility::CaseInsensitiveEquals(WellKnownSourceName_WinGet, sourceName) ||\r\n                Utility::CaseInsensitiveEquals(WellKnownSourceName_MSStore, sourceName) ||\r\n                Utility::CaseInsensitiveEquals(WellKnownSourceName_WinGetFont, sourceName);\r\n        }\r\n\r\n        bool ValidateWellKnownSource(const WinGetSource& source)\r\n        {\r\n            static std::vector<Repository::SourceDetails> wellKnownSourceDetails =\r\n            {\r\n                Repository::Source{ Repository::WellKnownSource::WinGet }.GetDetails(),\r\n                Repository::Source{ Repository::WellKnownSource::MicrosoftStore }.GetDetails(),\r\n                Repository::Source{ Repository::WellKnownSource::WinGetFont }.GetDetails(),\r\n            };\r\n\r\n            for (auto const& wellKnownSource : wellKnownSourceDetails)\r\n            {\r\n                if (Utility::CaseInsensitiveEquals(wellKnownSource.Name, source.Name) &&\r\n                    Utility::CaseInsensitiveEquals(wellKnownSource.Arg, source.Arg) &&\r\n                    Utility::CaseInsensitiveEquals(wellKnownSource.Type, source.Type))\r\n                {\r\n                    return true;\r\n                }\r\n            }\r\n\r\n            return false;\r\n        }\r\n\r\n        struct WinGetPackage\r\n        {\r\n            std::string Id;\r\n            std::string Version;\r\n            std::string Source;\r\n            bool UseLatest = false;\r\n\r\n            bool Empty()\r\n            {\r\n                return Id.empty() && Version.empty() && Source.empty();\r\n            }\r\n        };\r\n\r\n        WinGetPackage ParseWinGetPackageFromSettings(const ValueSet& settings)\r\n        {\r\n            // Iterate through the value set as Powershell variables are case-insensitive.\r\n            WinGetPackage result;\r\n            for (auto const& settingsPair : settings)\r\n            {\r\n                auto settingsKey = Utility::ConvertToUTF8(settingsPair.Key());\r\n                if (Utility::CaseInsensitiveEquals(WinGetPackageValueSetKey_Id, settingsKey))\r\n                {\r\n                    result.Id = GetPropertyValueAsString(settingsPair.Value());\r\n                }\r\n                else if (Utility::CaseInsensitiveEquals(WinGetPackageValueSetKey_Version, settingsKey))\r\n                {\r\n                    result.Version = GetPropertyValueAsString(settingsPair.Value());\r\n                }\r\n                else if (Utility::CaseInsensitiveEquals(WinGetPackageValueSetKey_Source, settingsKey))\r\n                {\r\n                    result.Source = GetPropertyValueAsString(settingsPair.Value());\r\n                }\r\n                else if (Utility::CaseInsensitiveEquals(WinGetPackageValueSetKey_UseLatest, settingsKey))\r\n                {\r\n                    result.UseLatest = GetPropertyValueAsBoolean(settingsPair.Value());\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n\r\n    bool WingetDscModuleUnitValidator::ValidateConfigurationSetUnit(Execution::Context& context, const ConfigurationUnit& unit)\r\n    {\r\n       bool foundIssues = false;\r\n       auto details = unit.Details();\r\n       auto unitType = Utility::ConvertToUTF8(details.UnitType());\r\n       auto unitIntent = unit.Intent();\r\n\r\n       if (Utility::CaseInsensitiveEquals(UnitType_WinGetSource, unitType))\r\n       {\r\n           auto source = ParseWinGetSourceFromSettings(unit.Settings());\r\n\r\n            // Validate basic semantics.\r\n            if (source.Name.empty())\r\n            {\r\n                AICLI_LOG(Config, Error, << \"WinGetSource unit missing required arg: Name\");\r\n                context.Reporter.Error() << Resource::String::WinGetResourceUnitMissingRequiredArg(Utility::LocIndView{ UnitType_WinGetSource }, \"Name\"_liv) << std::endl;\r\n                foundIssues = true;\r\n            }\r\n            if (source.Arg.empty() && source.Present)\r\n            {\r\n                AICLI_LOG(Config, Error, << \"WinGetSource unit missing required arg: Argument\");\r\n                context.Reporter.Error() << Resource::String::WinGetResourceUnitMissingRequiredArg(Utility::LocIndView{ UnitType_WinGetSource }, \"Argument\"_liv) << std::endl;\r\n                foundIssues = true;\r\n            }\r\n\r\n            // Validate well known source or process 3rd party source.\r\n            if (IsWellKnownSourceName(source.Name))\r\n            {\r\n                if (!ValidateWellKnownSource(source))\r\n                {\r\n                    AICLI_LOG(Config, Warning, << \"WinGetSource conflicts with a well known source. Source: \" << source.Name);\r\n                    context.Reporter.Warn() << Resource::String::WinGetResourceUnitKnownSourceConfliction(Utility::LocIndView{ source.Name }) << std::endl;\r\n                    foundIssues = true;\r\n                }\r\n            }\r\n            else\r\n            {\r\n                if (unitIntent == ConfigurationUnitIntent::Assert)\r\n                {\r\n                    AICLI_LOG(Config, Warning, << \"Asserting on 3rd party source: \" << source.Name);\r\n                    context.Reporter.Warn() << Resource::String::WinGetResourceUnitThirdPartySourceAssertion(Utility::LocIndView{ source.Name }) << std::endl;\r\n                    foundIssues = true;\r\n                }\r\n                else if (unitIntent == ConfigurationUnitIntent::Apply)\r\n                {\r\n                    // Add to dependency source map so it can be validated with later WinGetPackage source\r\n                    m_dependenciesSourceAndUnitIdMap.emplace(Utility::FoldCase(std::string_view{ source.Name }), Utility::FoldCase(Utility::NormalizedString{ unit.Identifier() }));\r\n                }\r\n            }\r\n       }\r\n       else if (Utility::CaseInsensitiveEquals(UnitType_WinGetPackage, unitType))\r\n       {\r\n           auto package = ParseWinGetPackageFromSettings(unit.Settings());\r\n           if (package.Empty())\r\n           {\r\n               AICLI_LOG(Config, Warning, << \"Failed to parse WinGetPackage or empty content.\");\r\n               context.Reporter.Warn() << Resource::String::WinGetResourceUnitEmptyContent(Utility::LocIndView{ UnitType_WinGetPackage }) << std::endl;\r\n               foundIssues = true;\r\n           }\r\n           // Validate basic semantics.\r\n           if (package.Id.empty())\r\n           {\r\n               AICLI_LOG(Config, Error, << \"WinGetPackage unit missing required arg: Id\");\r\n               context.Reporter.Error() << Resource::String::WinGetResourceUnitMissingRequiredArg(Utility::LocIndView{ UnitType_WinGetPackage }, \"Id\"_liv) << std::endl;\r\n               foundIssues = true;\r\n           }\r\n           if (package.Source.empty())\r\n           {\r\n               AICLI_LOG(Config, Warning, << \"WinGetPackage unit missing recommended arg: Source\");\r\n               context.Reporter.Warn() << Resource::String::WinGetResourceUnitMissingRecommendedArg(Utility::LocIndView{ UnitType_WinGetPackage }, \"Source\"_liv) << std::endl;\r\n               foundIssues = true;\r\n           }\r\n           if (package.UseLatest && !package.Version.empty())\r\n           {\r\n               AICLI_LOG(Config, Warning, << \"WinGetPackage unit both UseLatest and Version declared. Package: \" << package.Id);\r\n               context.Reporter.Warn() << Resource::String::WinGetResourceUnitBothPackageVersionAndUseLatest(Utility::LocIndView{ package.Id }) << std::endl;\r\n               foundIssues = true;\r\n           }\r\n           // Validate dependency source is configured.\r\n           if (!package.Source.empty() && !IsWellKnownSourceName(package.Source))\r\n           {\r\n               if (unitIntent == ConfigurationUnitIntent::Assert)\r\n               {\r\n                   AICLI_LOG(Config, Warning, << \"Asserting on a package that depends on a 3rd party source. Package: \" << package.Id << \" Source: \" << package.Source);\r\n                   context.Reporter.Warn() << Resource::String::WinGetResourceUnitThirdPartySourceAssertionForPackage(Utility::LocIndView{ package.Id }, Utility::LocIndView{ package.Source }) << std::endl;\r\n                   foundIssues = true;\r\n               }\r\n               else\r\n               {\r\n                   auto dependencySourceItr = m_dependenciesSourceAndUnitIdMap.find(Utility::FoldCase(std::string_view{ package.Source }));\r\n                   if (dependencySourceItr == m_dependenciesSourceAndUnitIdMap.end())\r\n                   {\r\n                       AICLI_LOG(Config, Warning, << \"WinGetPackage depends on a 3rd party source not previously configured. Package: \" << package.Id << \" Source: \" << package.Source);\r\n                       context.Reporter.Warn() << Resource::String::WinGetResourceUnitDependencySourceNotConfigured(Utility::LocIndView{ package.Id }, Utility::LocIndView{ package.Source }) << std::endl;\r\n                       foundIssues = true;\r\n                   }\r\n                   else\r\n                   {\r\n                       bool foundInUnitDependencies = false;\r\n                       for (auto const& entry : unit.Dependencies())\r\n                       {\r\n                           // The map contains normalized string, so just use direct comparison;\r\n                           if (dependencySourceItr->second == Utility::FoldCase(Utility::NormalizedString{ entry }))\r\n                           {\r\n                               foundInUnitDependencies = true;\r\n                               break;\r\n                           }\r\n                       }\r\n                       if (!foundInUnitDependencies)\r\n                       {\r\n                           AICLI_LOG(Config, Warning, << \"WinGetPackage depends on a 3rd party source. It is recommended to add the WinGetSources unit configuring the source to the unit's dependsOn list. Package: \" << package.Id << \" Source: \" << package.Source);\r\n                           context.Reporter.Warn() << Resource::String::WinGetResourceUnitDependencySourceNotDeclaredAsDependency(Utility::LocIndView{ package.Id }, Utility::LocIndView{ package.Source }) << std::endl;\r\n                           foundIssues = true;\r\n                       }\r\n                   }\r\n               }\r\n           }\r\n           // Validate package is found and version available.\r\n           try\r\n           {\r\n               Repository::Source source{ package.Source };\r\n               if (!source)\r\n               {\r\n                   AICLI_LOG(Config, Warning, << \"Failed to open WinGet source. Package: \" << package.Id << \" Source: \" << package.Source);\r\n                   context.Reporter.Warn() << Resource::String::WinGetResourceUnitFailedToValidatePackageSourceOpenFailed(Utility::LocIndView{ package.Id }, Utility::LocIndView{ package.Source }) << std::endl;\r\n                   foundIssues = true;\r\n               }\r\n               else\r\n               {\r\n                   source.SetCaller(\"winget-cli-configuration-unit-module-validation\");\r\n                   ProgressCallback empty;\r\n                   source.Open(empty);\r\n                   Repository::SearchRequest searchRequest;\r\n                   searchRequest.Filters.emplace_back(Repository::PackageMatchFilter{ Repository::PackageMatchField::Id, Repository::MatchType::CaseInsensitive, package.Id });\r\n                   auto searchResult = source.Search(searchRequest);\r\n                   if (searchResult.Matches.size() == 0)\r\n                   {\r\n                       AICLI_LOG(Config, Warning, << \"WinGetPackage not found: \" << package.Id);\r\n                       context.Reporter.Warn() << Resource::String::WinGetResourceUnitFailedToValidatePackageNotFound(Utility::LocIndView{ package.Id }) << std::endl;\r\n                       foundIssues = true;\r\n                   }\r\n                   else if (searchResult.Matches.size() > 1)\r\n                   {\r\n                       AICLI_LOG(Config, Warning, << \"More than one WinGetPackage found: \" << package.Id);\r\n                       context.Reporter.Warn() << Resource::String::WinGetResourceUnitFailedToValidatePackageMultipleFound(Utility::LocIndView{ package.Id }) << std::endl;\r\n                       foundIssues = true;\r\n                   }\r\n                   else\r\n                   {\r\n                       if (!package.Version.empty())\r\n                       {\r\n                           std::shared_ptr<Repository::IPackage> availablePackage = searchResult.Matches.at(0).Package->GetAvailable().at(0);\r\n                           auto versionKeys = availablePackage->GetVersionKeys();\r\n                           bool foundVersion = false;\r\n                           for (auto const& versionKey : versionKeys)\r\n                           {\r\n                               if (versionKey.Version == Utility::NormalizedString(package.Version))\r\n                               {\r\n                                   foundVersion = true;\r\n                                   break;\r\n                               }\r\n                           }\r\n                           if (!foundVersion)\r\n                           {\r\n                               AICLI_LOG(Config, Warning, << \"WinGetPackage version not found. Package: \" << package.Id << \" Version: \" << package.Version);\r\n                               context.Reporter.Warn() << Resource::String::WinGetResourceUnitFailedToValidatePackageVersionNotFound(Utility::LocIndView{ package.Id }, Utility::LocIndView{ package.Version }) << std::endl;\r\n                               foundIssues = true;\r\n                           }\r\n                           if (versionKeys.size() == 1)\r\n                           {\r\n                               AICLI_LOG(Config, Warning, << \"WinGetPackage version specified with only one version available: \" << package.Id);\r\n                               context.Reporter.Warn() << Resource::String::WinGetResourceUnitPackageVersionSpecifiedWithOnlyOnePackageVersion(Utility::LocIndView{ package.Id }, Utility::LocIndView{ package.Version }) << std::endl;\r\n                               foundIssues = true;\r\n                           }\r\n                       }\r\n                   }\r\n               }\r\n           }\r\n           catch (...)\r\n           {\r\n               AICLI_LOG(Config, Warning, << \"Failed to validate WinGetPackage: \" << package.Id);\r\n               context.Reporter.Warn() << Resource::String::WinGetResourceUnitFailedToValidatePackage(Utility::LocIndView{ package.Id }) << std::endl;\r\n               foundIssues = true;\r\n           }\r\n       }\r\n\r\n       return !foundIssues;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/ConfigurationWingetDscModuleUnitValidation.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <map>\r\n#include <string>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration\r\n{\r\n    struct ConfigurationUnit;\r\n}\r\n\r\nnamespace AppInstaller::CLI::Execution\r\n{\r\n    struct Context;\r\n}\r\n\r\nnamespace AppInstaller::CLI::Configuration\r\n{\r\n    using namespace std::string_view_literals;\r\n\r\n    struct WingetDscModuleUnitValidator\r\n    {\r\n        bool ValidateConfigurationSetUnit(AppInstaller::CLI::Execution::Context& context, const winrt::Microsoft::Management::Configuration::ConfigurationUnit& unit);\r\n\r\n        std::string_view ModuleName() { return \"Microsoft.WinGet.DSC\"sv; };\r\n\r\n    private:\r\n        std::map<std::string, std::string> m_dependenciesSourceAndUnitIdMap;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/ConfigureExportCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigureExportCommand.h\"\r\n#include \"Workflows/ConfigurationFlow.h\"\r\n#include \"Workflows/MSStoreInstallerHandler.h\"\r\n#include \"ConfigurationCommon.h\"\r\n\r\nusing namespace AppInstaller::CLI::Workflow;\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    std::vector<Argument> ConfigureExportCommand::GetArguments() const\r\n    {\r\n        return {\r\n            Argument{ Execution::Args::Type::OutputFile, Resource::String::OutputFileArgumentDescription, true },\r\n            Argument{ Execution::Args::Type::ConfigurationExportPackageId, Resource::String::ConfigureExportPackageId },\r\n            Argument{ Execution::Args::Type::ConfigurationExportModule, Resource::String::ConfigureExportModule },\r\n            Argument{ Execution::Args::Type::ConfigurationExportResource, Resource::String::ConfigureExportResource },\r\n            Argument{ Execution::Args::Type::ConfigurationModulePath, Resource::String::ConfigurationModulePath },\r\n            Argument{ Execution::Args::Type::ConfigurationProcessorPath, Resource::String::ConfigurationProcessorPath, ArgumentType::Standard, Argument::Visibility::Help },\r\n            Argument{ Execution::Args::Type::Source, Resource::String::ExportSourceArgumentDescription, ArgumentType::Standard },\r\n            Argument{ Execution::Args::Type::IncludeVersions, Resource::String::ExportIncludeVersionsArgumentDescription, ArgumentType::Flag },\r\n            Argument{ Execution::Args::Type::ConfigurationExportAll, Resource::String::ConfigureExportAll, ArgumentType::Flag },\r\n            Argument::ForType(Execution::Args::Type::AcceptSourceAgreements),\r\n        };\r\n    }\r\n\r\n    Resource::LocString ConfigureExportCommand::ShortDescription() const\r\n    {\r\n        return { Resource::String::ConfigureExportCommandShortDescription };\r\n    }\r\n\r\n    Resource::LocString ConfigureExportCommand::LongDescription() const\r\n    {\r\n        return { Resource::String::ConfigureExportCommandLongDescription };\r\n    }\r\n\r\n    Utility::LocIndView ConfigureExportCommand::HelpLink() const\r\n    {\r\n        return \"https://aka.ms/winget-command-configure#export\"_liv;\r\n    }\r\n\r\n    void ConfigureExportCommand::ExecuteInternal(Execution::Context& context) const\r\n    {\r\n        context <<\r\n            VerifyIsFullPackage <<\r\n            CreateConfigurationProcessorWithoutFactory <<\r\n            CreateOrOpenConfigurationSet{ \"0.3\", context.Args.Contains(Execution::Args::Type::ConfigurationExportAll) } <<\r\n            CreateConfigurationProcessor <<\r\n            PopulateConfigurationSetForExport <<\r\n            WriteConfigFile;\r\n    }\r\n\r\n    void ConfigureExportCommand::ValidateArgumentsInternal(Execution::Args& execArgs) const\r\n    {\r\n        Configuration::ValidateCommonArguments(execArgs);\r\n\r\n        if (!execArgs.Contains(Execution::Args::Type::ConfigurationExportModule, Execution::Args::Type::ConfigurationExportResource) &&\r\n            !execArgs.Contains(Execution::Args::Type::ConfigurationExportPackageId) &&\r\n            !execArgs.Contains(Execution::Args::Type::ConfigurationExportAll))\r\n        {\r\n            throw CommandException(Resource::String::ConfigureExportArgumentRequiredError);\r\n        }\r\n\r\n        if (execArgs.Contains(Execution::Args::Type::ConfigurationExportAll) &&\r\n            (execArgs.Contains(Execution::Args::Type::ConfigurationExportPackageId) ||\r\n             execArgs.Contains(Execution::Args::Type::ConfigurationExportModule) ||\r\n             execArgs.Contains(Execution::Args::Type::ConfigurationExportResource)))\r\n        {\r\n            throw CommandException(Resource::String::ConfigureExportArgumentConflictWithAllError);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/ConfigureExportCommand.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Command.h\"\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    struct ConfigureExportCommand final : public Command\r\n    {\r\n        ConfigureExportCommand(std::string_view parent) : Command(\"export\", parent) {}\r\n\r\n        std::vector<Argument> GetArguments() const override;\r\n\r\n        Resource::LocString ShortDescription() const override;\r\n        Resource::LocString LongDescription() const override;\r\n\r\n        Utility::LocIndView HelpLink() const override;\r\n\r\n    protected:\r\n        void ExecuteInternal(Execution::Context& context) const override;\r\n        void ValidateArgumentsInternal(Execution::Args& execArgs) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/ContextOrchestrator.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ExecutionContext.h\"\r\n#include \"ContextOrchestrator.h\"\r\n#include \"COMContext.h\"\r\n#include \"Commands/COMCommand.h\"\r\n#include \"Public/ShutdownMonitoring.h\"\r\n#include \"winget/UserSettings.h\"\r\n#include <Commands/RootCommand.h>\r\n\r\nnamespace AppInstaller::CLI::Execution\r\n{\r\n    namespace\r\n    {\r\n        // Operation command queue used by install, uninstall and repair commands.\r\n        constexpr static std::string_view OperationCommandQueueName = \"operation\"sv;\r\n\r\n        // Callback function used by worker threads in the queue.\r\n        // context must be a pointer to a queue item.\r\n        void CALLBACK OrchestratorQueueWorkCallback(PTP_CALLBACK_INSTANCE, PVOID context, PTP_WORK)\r\n        {\r\n            auto queueItem = reinterpret_cast<OrchestratorQueueItem*>(context);\r\n            auto queue = queueItem->GetCurrentQueue();\r\n            if (queue)\r\n            {\r\n                queue->RunItem(queueItem->GetId());\r\n            }\r\n        }\r\n\r\n        // Get command queue name based on command name.\r\n        std::string_view GetCommandQueueName(std::string_view commandName)\r\n        {\r\n            if (commandName == COMInstallCommand::CommandName || commandName == COMUninstallCommand::CommandName || commandName == COMRepairCommand::CommandName)\r\n            {\r\n                return OperationCommandQueueName;\r\n            }\r\n\r\n            return commandName;\r\n        }\r\n    }\r\n\r\n    ContextOrchestrator& ContextOrchestrator::Instance()\r\n    {\r\n        static ContextOrchestrator s_instance;\r\n        return s_instance;\r\n    }\r\n\r\n    ContextOrchestrator::ContextOrchestrator() : ContextOrchestrator(std::thread::hardware_concurrency()) {}\r\n\r\n    ContextOrchestrator::ContextOrchestrator(unsigned int hardwareConcurrency)\r\n    {\r\n        ProgressCallback progress;\r\n        m_installingWriteableSource = Repository::Source(Repository::PredefinedSource::Installing);\r\n        m_installingWriteableSource.Open(progress);\r\n\r\n        // Decide how many threads to use for each command.\r\n        // We always allow only one install at a time.\r\n        // For download, if we can find the number of supported concurrent threads,\r\n        // use that as the maximum (up to 3); otherwise use a single thread.\r\n        const UINT32 maxDownloadThreads = 3;\r\n        const UINT32 operationThreads = 1;\r\n        const UINT32 downloadThreads = std::min(hardwareConcurrency > 1 ? hardwareConcurrency - 1 : 1, maxDownloadThreads);\r\n\r\n        AddCommandQueue(COMDownloadCommand::CommandName, downloadThreads);\r\n        AddCommandQueue(OperationCommandQueueName, operationThreads);\r\n    }\r\n\r\n    void ContextOrchestrator::AddCommandQueue(std::string_view commandName, UINT32 allowedThreads)\r\n    {\r\n        std::lock_guard<std::mutex> lockQueue{ m_queueLock };\r\n        m_commandQueues.emplace(commandName, std::make_unique<OrchestratorQueue>(*this, commandName, allowedThreads));\r\n    }\r\n\r\n    _Requires_lock_held_(m_queueLock)\r\n    std::shared_ptr<OrchestratorQueueItem> ContextOrchestrator::FindById(const OrchestratorQueueItemId& comparisonQueueItemId)\r\n    {\r\n        for (const auto& queue : m_commandQueues)\r\n        {\r\n            auto item = queue.second->FindById(comparisonQueueItemId);\r\n            if (item)\r\n            {\r\n                return item;\r\n            }\r\n        }\r\n\r\n        return {};\r\n    }\r\n\r\n    void ContextOrchestrator::EnqueueAndRunItem(const std::shared_ptr<OrchestratorQueueItem>& item)\r\n    {\r\n        std::lock_guard<std::mutex> lockQueue{ m_queueLock };\r\n\r\n        if (item->IsOnFirstCommand())\r\n        {\r\n            // Directly error on attempting to enqueue first time\r\n            THROW_HR_IF(ToHRESULT(m_disabledReason), !m_enabled);\r\n\r\n            THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INSTALL_ALREADY_RUNNING), FindById(item->GetId()));\r\n\r\n            // Log the beginning of the item\r\n            item->GetContext().GetThreadGlobals().GetTelemetryLogger().LogCommand(item->GetItemCommandName());\r\n        }\r\n        else if (!m_enabled)\r\n        {\r\n            // On subsequent command enqueues, cancel and complete the item\r\n            item->GetContext().Cancel(m_disabledReason, true);\r\n            item->HandleItemCompletion(*this);\r\n        }\r\n\r\n        std::string commandQueueName{ GetCommandQueueName(item->GetNextCommand().Name()) };\r\n        m_commandQueues.at(commandQueueName)->EnqueueAndRunItem(item);\r\n    }\r\n\r\n    void ContextOrchestrator::RemoveItemInState(const OrchestratorQueueItem& item, OrchestratorQueueItemState state)\r\n    {\r\n        std::lock_guard<std::mutex> lockQueue{ m_queueLock };\r\n        for (const auto& queue : m_commandQueues)\r\n        {\r\n            if (queue.second->RemoveItemInState(item, state, true))\r\n            {\r\n                return;\r\n            }\r\n        }\r\n    }\r\n\r\n    void ContextOrchestrator::CancelQueueItem(const OrchestratorQueueItem& item)\r\n    {\r\n        // Always cancel the item, even if it isn't running yet, to get the terminationHR set correctly.\r\n        item.GetContext().Cancel(CancelReason::Abort, true);\r\n\r\n        RemoveItemInState(item, OrchestratorQueueItemState::Queued);\r\n    }\r\n\r\n    std::shared_ptr<OrchestratorQueueItem> ContextOrchestrator::GetQueueItem(const OrchestratorQueueItemId& queueItemId)\r\n    {\r\n        std::lock_guard<std::mutex> lock{ m_queueLock };\r\n\r\n        return FindById(queueItemId);\r\n    }\r\n\r\n    void ContextOrchestrator::AddItemManifestToInstallingSource(const OrchestratorQueueItem& queueItem)\r\n    {\r\n        if (queueItem.IsApplicableForInstallingSource())\r\n        {\r\n            const auto& manifest = queueItem.GetContext().Get<Execution::Data::Manifest>();\r\n            m_installingWriteableSource.AddPackageVersion(manifest, std::filesystem::path{ manifest.Id + '.' + manifest.Version });\r\n        }\r\n    }\r\n\r\n    void ContextOrchestrator::RemoveItemManifestFromInstallingSource(const OrchestratorQueueItem& queueItem)\r\n    {\r\n        if (queueItem.IsApplicableForInstallingSource())\r\n        {\r\n            const auto& manifest = queueItem.GetContext().Get<Execution::Data::Manifest>();\r\n            m_installingWriteableSource.RemovePackageVersion(manifest, std::filesystem::path{ manifest.Id + '.' + manifest.Version });\r\n        }\r\n    }\r\n\r\n    void ContextOrchestrator::RegisterForShutdownSynchronization()\r\n    {\r\n        static std::once_flag registerComponentOnceFlag;\r\n        std::call_once(registerComponentOnceFlag,\r\n            [&]()\r\n            {\r\n                using namespace ShutdownMonitoring;\r\n\r\n                ServerShutdownSynchronization::ComponentSystem component;\r\n                component.BlockNewWork = StaticDisable;\r\n                component.BeginShutdown = StaticCancelQueuedItems;\r\n                component.Wait = StaticWaitForRunningItems;\r\n\r\n                ServerShutdownSynchronization::AddComponent(component);\r\n            });\r\n    }\r\n\r\n    void ContextOrchestrator::StaticDisable(CancelReason reason)\r\n    {\r\n        Instance().Disable(reason);\r\n    }\r\n\r\n    void ContextOrchestrator::StaticCancelQueuedItems(CancelReason reason)\r\n    {\r\n        Instance().CancelQueuedItems(reason);\r\n    }\r\n\r\n    void ContextOrchestrator::StaticWaitForRunningItems()\r\n    {\r\n        Instance().WaitForRunningItems();\r\n    }\r\n\r\n    void ContextOrchestrator::Disable(CancelReason reason)\r\n    {\r\n        std::lock_guard<std::mutex> lock{ m_queueLock };\r\n        m_enabled = false;\r\n        m_disabledReason = reason;\r\n    }\r\n\r\n    void ContextOrchestrator::CancelQueuedItems(CancelReason reason)\r\n    {\r\n        std::lock_guard<std::mutex> lock{ m_queueLock };\r\n        for (const auto& queue : m_commandQueues)\r\n        {\r\n            queue.second->CancelAllItems(reason);\r\n        }\r\n    }\r\n\r\n    void ContextOrchestrator::WaitForRunningItems()\r\n    {\r\n        std::lock_guard<std::mutex> lock{ m_queueLock };\r\n        for (const auto& queue : m_commandQueues)\r\n        {\r\n            queue.second->WaitForEmptyQueue();\r\n        }\r\n    }\r\n\r\n    bool ContextOrchestrator::WaitForRunningItems(DWORD timeoutMilliseconds)\r\n    {\r\n        std::lock_guard<std::mutex> lock{ m_queueLock };\r\n        for (const auto& queue : m_commandQueues)\r\n        {\r\n            if (!queue.second->WaitForEmptyQueue(timeoutMilliseconds))\r\n            {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    std::string ContextOrchestrator::GetStatusString()\r\n    {\r\n        std::ostringstream stream;\r\n\r\n        std::lock_guard<std::mutex> lock{ m_queueLock };\r\n\r\n        if (!m_enabled)\r\n        {\r\n            stream << \"Disabled due to \" << ToIntegral(m_disabledReason) << std::endl;\r\n        }\r\n\r\n        for (const auto& queue : m_commandQueues)\r\n        {\r\n            stream << queue.second->GetStatusString();\r\n        }\r\n\r\n        return stream.str();\r\n    }\r\n\r\n    _Requires_lock_held_(m_itemLock)\r\n    std::deque<std::shared_ptr<OrchestratorQueueItem>>::iterator OrchestratorQueue::FindIteratorById(const OrchestratorQueueItemId& comparisonQueueItemId)\r\n    {\r\n        return std::find_if(m_queueItems.begin(), m_queueItems.end(), [&comparisonQueueItemId](const std::shared_ptr<OrchestratorQueueItem>& item) {return (item->GetId().IsSame(comparisonQueueItemId)); });\r\n    }\r\n\r\n    _Requires_lock_held_(m_itemLock)\r\n    std::shared_ptr<OrchestratorQueueItem> OrchestratorQueue::FindById(const OrchestratorQueueItemId& comparisonQueueItemId)\r\n    {\r\n        auto itr = FindIteratorById(comparisonQueueItemId);\r\n        if (itr != m_queueItems.end())\r\n        {\r\n            return *itr;\r\n        }\r\n\r\n        return {};\r\n    }\r\n\r\n    void OrchestratorQueue::EnqueueItem(const std::shared_ptr<OrchestratorQueueItem>& item)\r\n    {\r\n        {\r\n            std::lock_guard<std::mutex> lockQueue{ m_itemLock };\r\n            m_queueItems.push_back(item);\r\n            m_queueEmpty.ResetEvent();\r\n        }\r\n\r\n        // Add the package to the Installing source so that it can be queried using the Source interface.\r\n        // Only do this the first time the item is queued.\r\n        if (item->IsOnFirstCommand())\r\n        {\r\n            try\r\n            {\r\n                m_orchestrator.AddItemManifestToInstallingSource(*item);\r\n            }\r\n            catch (...)\r\n            {\r\n                std::lock_guard<std::mutex> lockQueue{ m_itemLock };\r\n                auto itr = FindIteratorById(item->GetId());\r\n                if (itr != m_queueItems.end())\r\n                {\r\n                    m_queueItems.erase(itr);\r\n\r\n                    if (m_queueItems.empty())\r\n                    {\r\n                        m_queueEmpty.SetEvent();\r\n                    }\r\n                }\r\n                throw;\r\n            }\r\n        }\r\n\r\n        {\r\n            std::lock_guard<std::mutex> lockQueue{ m_itemLock };\r\n            item->SetState(OrchestratorQueueItemState::Queued);\r\n        }\r\n    }\r\n\r\n    OrchestratorQueue::OrchestratorQueue(ContextOrchestrator& orchestrator, std::string_view commandName, UINT32 allowedThreads) :\r\n        m_orchestrator(orchestrator), m_commandName(commandName), m_allowedThreads(allowedThreads)\r\n    {\r\n        m_threadPool.reset(CreateThreadpool(nullptr));\r\n        THROW_LAST_ERROR_IF_NULL(m_threadPool);\r\n        m_threadPoolCleanupGroup.reset(CreateThreadpoolCleanupGroup());\r\n        THROW_LAST_ERROR_IF_NULL(m_threadPoolCleanupGroup);\r\n        InitializeThreadpoolEnvironment(&m_threadPoolCallbackEnviron);\r\n        SetThreadpoolCallbackPool(&m_threadPoolCallbackEnviron, m_threadPool.get());\r\n        SetThreadpoolCallbackCleanupGroup(&m_threadPoolCallbackEnviron, m_threadPoolCleanupGroup.get(), nullptr);\r\n\r\n        SetThreadpoolThreadMaximum(m_threadPool.get(), m_allowedThreads);\r\n        THROW_LAST_ERROR_IF(!SetThreadpoolThreadMinimum(m_threadPool.get(), 1));\r\n    }\r\n\r\n    OrchestratorQueue::~OrchestratorQueue()\r\n    {\r\n        CloseThreadpoolCleanupGroupMembers(m_threadPoolCleanupGroup.get(), false, nullptr);\r\n    }\r\n\r\n    void OrchestratorQueue::EnqueueAndRunItem(const std::shared_ptr<OrchestratorQueueItem>& item)\r\n    {\r\n        EnqueueItem(item);\r\n\r\n        item->SetCurrentQueue(this);\r\n        auto work = CreateThreadpoolWork(OrchestratorQueueWorkCallback, item.get(), &m_threadPoolCallbackEnviron);\r\n        SubmitThreadpoolWork(work);\r\n    }\r\n\r\n    void OrchestratorQueue::RunItem(const OrchestratorQueueItemId& itemId)\r\n    {\r\n        try\r\n        {\r\n            std::shared_ptr<OrchestratorQueueItem> item;\r\n            bool isCancelled = false;\r\n\r\n            // Try to find the item in the queue.\r\n            {\r\n                std::lock_guard<std::mutex> lockQueue{ m_itemLock };\r\n                item = FindById(itemId);\r\n\r\n                if (!item)\r\n                {\r\n                    // Item should be in the queue; this shouldn't happen.\r\n                    return;\r\n                }\r\n\r\n                // Only run if the item is queued and not cancelled.\r\n                if (item->GetState() == OrchestratorQueueItemState::Queued)\r\n                {\r\n                    // Mark it as running so that it cannot be cancelled by other threads.\r\n                    item->SetState(OrchestratorQueueItemState::Running);\r\n                }\r\n                else if (item->GetState() == OrchestratorQueueItemState::Cancelled)\r\n                {\r\n                    isCancelled = true;\r\n                }\r\n            }\r\n\r\n            if (isCancelled)\r\n            {\r\n                // Do this separate from above block as the Remove function needs to manage the lock.\r\n                RemoveItemInState(*item, OrchestratorQueueItemState::Cancelled, true);\r\n            }\r\n\r\n            // Get the item's command and execute it.\r\n            HRESULT exceptionHR = S_OK;\r\n            try\r\n            {\r\n                std::unique_ptr<Command> command = item->PopNextCommand();\r\n\r\n                std::unique_ptr<AppInstaller::ThreadLocalStorage::PreviousThreadGlobals> setThreadGlobalsToPreviousState = item->GetContext().SetForCurrentThread();\r\n\r\n                command->ValidateArguments(item->GetContext().Args);\r\n\r\n                item->GetContext().EnableSignalTerminationHandler();\r\n\r\n                ::AppInstaller::CLI::ExecuteWithoutLoggingSuccess(item->GetContext(), command.get());\r\n            }\r\n            WINGET_CATCH_STORE(exceptionHR, APPINSTALLER_CLI_ERROR_COMMAND_FAILED);\r\n\r\n            if (FAILED(exceptionHR))\r\n            {\r\n                // Set the termination hr directly from any exception that escaped so that the context always \r\n                // has the result of the operation no matter how it failed.\r\n                item->GetContext().SetTerminationHR(exceptionHR);\r\n            }\r\n\r\n            item->GetContext().EnableSignalTerminationHandler(false);\r\n\r\n            if (FAILED(item->GetContext().GetTerminationHR()) || item->IsComplete())\r\n            {\r\n                if (SUCCEEDED(item->GetContext().GetTerminationHR()))\r\n                {\r\n                    item->GetContext().GetThreadGlobals().GetTelemetryLogger().LogCommandSuccess(item->GetItemCommandName());\r\n                }\r\n\r\n                RemoveItemInState(*item, OrchestratorQueueItemState::Running, true);\r\n            }\r\n            else\r\n            {\r\n                // Remove item from this queue and add it to the queue for the next command.\r\n                RemoveItemInState(*item, OrchestratorQueueItemState::Running, false);\r\n                m_orchestrator.EnqueueAndRunItem(item);\r\n            }\r\n        }\r\n        catch (...)\r\n        {\r\n        }\r\n    }\r\n\r\n    void OrchestratorQueue::CancelAllItems(CancelReason reason)\r\n    {\r\n        std::lock_guard<std::mutex> lockQueue{ m_itemLock };\r\n\r\n        for (auto itr = m_queueItems.begin(); itr != m_queueItems.end(); itr++)\r\n        {\r\n            auto& item = *itr;\r\n\r\n            item->GetContext().Cancel(reason, true);\r\n\r\n            // This mimics ContextOrchestrator::CancelQueueItem, which speeds up the process of cancelling queued items\r\n            if (item->GetState() == OrchestratorQueueItemState::Queued)\r\n            {\r\n                item->SetState(OrchestratorQueueItemState::Cancelled);\r\n                item->HandleItemCompletion(m_orchestrator);\r\n            }\r\n        }\r\n    }\r\n\r\n    void OrchestratorQueue::WaitForEmptyQueue()\r\n    {\r\n        m_queueEmpty.wait();\r\n    }\r\n\r\n    bool OrchestratorQueue::WaitForEmptyQueue(DWORD timeoutMilliseconds)\r\n    {\r\n        return m_queueEmpty.wait(timeoutMilliseconds);\r\n    }\r\n\r\n    std::string OrchestratorQueue::GetStatusString()\r\n    {\r\n        std::ostringstream stream;\r\n        stream << m_commandName << '[' << m_allowedThreads << \"]\\n\";\r\n\r\n        std::map<OrchestratorQueueItemState, size_t> stateCounts;\r\n        stateCounts[OrchestratorQueueItemState::NotQueued] = 0;\r\n        stateCounts[OrchestratorQueueItemState::Queued] = 0;\r\n        stateCounts[OrchestratorQueueItemState::Running] = 0;\r\n        stateCounts[OrchestratorQueueItemState::Cancelled] = 0;\r\n\r\n        {\r\n            std::lock_guard<std::mutex> lock{ m_itemLock };\r\n\r\n            for (const auto& item : m_queueItems)\r\n            {\r\n                stateCounts[item->GetState()] += 1;\r\n            }\r\n        }\r\n\r\n        for (const auto& stateCount : stateCounts)\r\n        {\r\n            stream << \"  \" << ToString(stateCount.first) << \" : \" << stateCount.second << std::endl;\r\n        }\r\n\r\n        return stream.str();\r\n    }\r\n\r\n    bool OrchestratorQueue::RemoveItemInState(const OrchestratorQueueItem& item, OrchestratorQueueItemState state, bool isGlobalRemove)\r\n    {\r\n        // OrchestratorQueueItemState::Running items should only be removed by the thread that ran the item.\r\n        // Queued items can be removed by any thread.\r\n        // NotQueued items should not be removed since, if found in the queue, they are in the process of being queued by another thread.\r\n        bool foundItem = false;\r\n\r\n        {\r\n            std::lock_guard<std::mutex> lockQueue{ m_itemLock };\r\n\r\n            // Look for the item. It's ok if the item is not found since multiple listeners may try to remove the same item.\r\n            auto itr = FindIteratorById(item.GetId());\r\n            if (itr != m_queueItems.end() && (*itr)->GetState() == state)\r\n            {\r\n                foundItem = true;\r\n\r\n                // The item must only be removed from the queue by the thread that runs\r\n                // it, because the callback uses it. If any other thread tries to remove\r\n                // it, we simply mark it as cancelled.\r\n                if (state == OrchestratorQueueItemState::Running || state == OrchestratorQueueItemState::Cancelled)\r\n                {\r\n                    (*itr)->SetCurrentQueue(nullptr);\r\n                    m_queueItems.erase(itr);\r\n\r\n                    if (m_queueItems.empty())\r\n                    {\r\n                        m_queueEmpty.SetEvent();\r\n                    }\r\n                }\r\n                else if (state == OrchestratorQueueItemState::Queued)\r\n                {\r\n                    (*itr)->SetState(OrchestratorQueueItemState::Cancelled);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (foundItem && isGlobalRemove)\r\n        {\r\n            item.HandleItemCompletion(m_orchestrator);\r\n        }\r\n\r\n        return foundItem;\r\n    }\r\n\r\n    bool OrchestratorQueueItemId::IsSame(const OrchestratorQueueItemId& comparedId) const\r\n    {\r\n        return ((GetPackageId() == comparedId.GetPackageId()) && \r\n                (GetSourceId() == comparedId.GetSourceId()));\r\n    }\r\n\r\n    std::string_view OrchestratorQueueItem::GetItemCommandName() const\r\n    {\r\n        // The goal is that these should match the winget.exe commands for easy correlation.\r\n        switch (m_operationType)\r\n        {\r\n        case PackageOperationType::Search: return \"root:search\"sv;\r\n        case PackageOperationType::Install: return \"root:install\"sv;\r\n        case PackageOperationType::Upgrade: return \"root:upgrade\"sv;\r\n        case PackageOperationType::Uninstall: return \"root:uninstall\"sv;\r\n        case PackageOperationType::Download: return \"root:download\"sv;\r\n        case PackageOperationType::Repair: return \"root:repair\"sv;\r\n        default: return \"unknown\";\r\n        }\r\n    }\r\n\r\n    void OrchestratorQueueItem::HandleItemCompletion(ContextOrchestrator& orchestrator) const\r\n    {\r\n        orchestrator.RemoveItemManifestFromInstallingSource(*this);\r\n        GetCompletedEvent().SetEvent();\r\n    }\r\n\r\n    std::unique_ptr<OrchestratorQueueItem> OrchestratorQueueItemFactory::CreateItemForInstall(std::wstring packageId, std::wstring sourceId, std::unique_ptr<COMContext> context, bool isUpgrade)\r\n    {\r\n        std::unique_ptr<OrchestratorQueueItem> item = std::make_unique<OrchestratorQueueItem>(OrchestratorQueueItemId(std::move(packageId), std::move(sourceId)), std::move(context), isUpgrade ? PackageOperationType::Upgrade : PackageOperationType::Install);\r\n        item->AddCommand(std::make_unique<::AppInstaller::CLI::COMDownloadCommand>(RootCommand::CommandName));\r\n        item->AddCommand(std::make_unique<::AppInstaller::CLI::COMInstallCommand>(RootCommand::CommandName));\r\n        return item;\r\n    }\r\n\r\n    std::unique_ptr<OrchestratorQueueItem> OrchestratorQueueItemFactory::CreateItemForUninstall(std::wstring packageId, std::wstring sourceId, std::unique_ptr<COMContext> context)\r\n    {\r\n        std::unique_ptr<OrchestratorQueueItem> item = std::make_unique<OrchestratorQueueItem>(OrchestratorQueueItemId(std::move(packageId), std::move(sourceId)), std::move(context), PackageOperationType::Uninstall);\r\n        item->AddCommand(std::make_unique<::AppInstaller::CLI::COMUninstallCommand>(RootCommand::CommandName));\r\n        return item;\r\n    }\r\n\r\n    std::unique_ptr<OrchestratorQueueItem> OrchestratorQueueItemFactory::CreateItemForSearch(std::wstring packageId, std::wstring sourceId, std::unique_ptr<COMContext> context)\r\n    {\r\n        std::unique_ptr<OrchestratorQueueItem> item = std::make_unique<OrchestratorQueueItem>(OrchestratorQueueItemId(std::move(packageId), std::move(sourceId)), std::move(context), PackageOperationType::Search);\r\n        return item;\r\n    }\r\n\r\n    std::unique_ptr<OrchestratorQueueItem> OrchestratorQueueItemFactory::CreateItemForDownload(std::wstring packageId, std::wstring sourceId, std::unique_ptr<COMContext> context)\r\n    {\r\n        std::unique_ptr<OrchestratorQueueItem> item = std::make_unique<OrchestratorQueueItem>(OrchestratorQueueItemId(std::move(packageId), std::move(sourceId)), std::move(context), PackageOperationType::Download);\r\n        item->AddCommand(std::make_unique<::AppInstaller::CLI::COMDownloadCommand>(RootCommand::CommandName));\r\n        return item;\r\n    }\r\n\r\n    std::unique_ptr<OrchestratorQueueItem> OrchestratorQueueItemFactory::CreateItemForRepair(std::wstring packageId, std::wstring sourceId, std::unique_ptr<COMContext> context)\r\n    {\r\n        std::unique_ptr<OrchestratorQueueItem> item = std::make_unique<OrchestratorQueueItem>(OrchestratorQueueItemId(std::move(packageId), std::move(sourceId)), std::move(context), PackageOperationType::Repair);\r\n        item->AddCommand(std::make_unique<::AppInstaller::CLI::COMRepairCommand>(RootCommand::CommandName));\r\n        return item;\r\n    }\r\n\r\n    std::string_view ToString(OrchestratorQueueItemState state)\r\n    {\r\n        switch (state)\r\n        {\r\n        case OrchestratorQueueItemState::NotQueued: return \"NotQueued\";\r\n        case OrchestratorQueueItemState::Queued: return \"Queued\";\r\n        case OrchestratorQueueItemState::Running: return \"Running\";\r\n        case OrchestratorQueueItemState::Cancelled: return \"Cancelled\";\r\n        default: return \"Unknown\";\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/ContextOrchestrator.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerLogging.h>\r\n#include <winget/RepositorySource.h>\r\n#include \"ExecutionReporter.h\"\r\n#include \"ExecutionArgs.h\"\r\n#include \"ExecutionContextData.h\"\r\n#include \"CompletionData.h\"\r\n#include \"Command.h\"\r\n#include \"COMContext.h\"\r\n#include <wil/resource.h>\r\n#include <string>\r\n#include <string_view>\r\n\r\nnamespace AppInstaller::CLI::Execution\r\n{\r\n    enum class OrchestratorQueueItemState\r\n    {\r\n        // Created but not yet queued\r\n        NotQueued,\r\n        // Queued and waiting to be run\r\n        Queued,\r\n        // Running in the thread pool\r\n        Running,\r\n        // Cancelled before it was run; will be deleted when we try to run it\r\n        Cancelled\r\n    };\r\n\r\n    std::string_view ToString(OrchestratorQueueItemState state);\r\n\r\n    struct OrchestratorQueueItemId\r\n    {\r\n        OrchestratorQueueItemId(std::wstring packageId, std::wstring sourceId) : m_packageId(std::move(packageId)), m_sourceId(std::move(sourceId)) {}\r\n        std::wstring_view GetPackageId() const { return m_packageId; }\r\n        std::wstring_view GetSourceId() const { return m_sourceId; }\r\n\r\n        bool IsSame(const OrchestratorQueueItemId& comparisonQueueItemId) const;\r\n    private:\r\n        std::wstring m_packageId;\r\n        std::wstring m_sourceId;\r\n    };\r\n\r\n    struct OrchestratorQueue;\r\n\r\n    enum class PackageOperationType\r\n    {\r\n        Search,\r\n        Install,\r\n        Upgrade,\r\n        Uninstall,\r\n        Download,\r\n        Repair,\r\n    };\r\n\r\n    struct ContextOrchestrator;\r\n\r\n    struct OrchestratorQueueItem\r\n    {\r\n        OrchestratorQueueItem(OrchestratorQueueItemId id, std::unique_ptr<COMContext> context, PackageOperationType operationType) :\r\n            m_id(std::move(id)), m_context(std::move(context)), m_operationType(operationType) {}\r\n\r\n        OrchestratorQueueItemState GetState() const { return m_state; }\r\n        void SetState(OrchestratorQueueItemState state) { m_state = state; }\r\n\r\n        OrchestratorQueue* GetCurrentQueue() const { return m_currentQueue; }\r\n        void SetCurrentQueue(OrchestratorQueue* currentQueue) { m_currentQueue = currentQueue; }\r\n\r\n        COMContext& GetContext() const { return *m_context; }\r\n        const wil::unique_event& GetCompletedEvent() const { return m_completedEvent; }\r\n        const OrchestratorQueueItemId& GetId() const { return m_id; }\r\n\r\n        void AddCommand(std::unique_ptr<Command> command) { m_commands.push_back(std::move(command)); }\r\n        const Command& GetNextCommand() const { return *m_commands.front(); }\r\n        std::unique_ptr<Command> PopNextCommand()\r\n        {\r\n            m_isOnFirstCommand = false;\r\n            std::unique_ptr<Command> command = std::move(m_commands.front());\r\n            m_commands.pop_front();\r\n            return command;\r\n        }\r\n\r\n        bool IsOnFirstCommand() const { return m_isOnFirstCommand; }\r\n        bool IsComplete() const { return m_commands.empty(); }\r\n        bool IsApplicableForInstallingSource() const { return m_operationType == PackageOperationType::Install || m_operationType == PackageOperationType::Upgrade; }\r\n        PackageOperationType GetPackageOperationType() const { return m_operationType; }\r\n        std::string_view GetItemCommandName() const;\r\n\r\n        void HandleItemCompletion(ContextOrchestrator& orchestrator) const;\r\n\r\n    private:\r\n        OrchestratorQueueItemState m_state = OrchestratorQueueItemState::NotQueued;\r\n        std::unique_ptr<COMContext> m_context;\r\n        wil::unique_event m_completedEvent{ wil::EventOptions::ManualReset };\r\n        OrchestratorQueueItemId m_id;\r\n        std::deque<std::unique_ptr<Command>> m_commands;\r\n        bool m_isOnFirstCommand = true;\r\n        OrchestratorQueue* m_currentQueue = nullptr;\r\n        PackageOperationType m_operationType;\r\n    };\r\n\r\n    struct OrchestratorQueueItemFactory\r\n    {\r\n        // Create queue item for install/upgrade\r\n        static std::unique_ptr<OrchestratorQueueItem> CreateItemForInstall(std::wstring packageId, std::wstring sourceId, std::unique_ptr<COMContext> context, bool isUpgrade);\r\n        // Create queue item for uninstall\r\n        static std::unique_ptr<OrchestratorQueueItem> CreateItemForUninstall(std::wstring packageId, std::wstring sourceId, std::unique_ptr<COMContext> context);\r\n        // Create queue item for finding existing entry from the orchestrator queue\r\n        static std::unique_ptr<OrchestratorQueueItem> CreateItemForSearch(std::wstring packageId, std::wstring sourceId, std::unique_ptr<COMContext> context);\r\n        // Create queue item for download\r\n        static std::unique_ptr<OrchestratorQueueItem> CreateItemForDownload(std::wstring packageId, std::wstring sourceId, std::unique_ptr<COMContext> context);\r\n        // Create queue item for repair\r\n        static std::unique_ptr<OrchestratorQueueItem> CreateItemForRepair(std::wstring packageId, std::wstring sourceId, std::unique_ptr<COMContext> context);\r\n    };\r\n\r\n    struct ContextOrchestrator\r\n    {\r\n        ContextOrchestrator();\r\n        ContextOrchestrator(unsigned int hardwareConcurrency);\r\n        static ContextOrchestrator& Instance();\r\n\r\n        void EnqueueAndRunItem(const std::shared_ptr<OrchestratorQueueItem>& queueItem);\r\n        void CancelQueueItem(const OrchestratorQueueItem& item);\r\n\r\n        std::shared_ptr<OrchestratorQueueItem> GetQueueItem(const OrchestratorQueueItemId& queueItemId);\r\n\r\n        void AddItemManifestToInstallingSource(const OrchestratorQueueItem& queueItem);\r\n        void RemoveItemManifestFromInstallingSource(const OrchestratorQueueItem& queueItem);\r\n\r\n        // Functions for ServerShutdownSynchronization::ComponentSystem registration\r\n        static void RegisterForShutdownSynchronization();\r\n        static void StaticDisable(CancelReason reason);\r\n        static void StaticCancelQueuedItems(CancelReason reason);\r\n        static void StaticWaitForRunningItems();\r\n\r\n        void Disable(CancelReason reason);\r\n        void CancelQueuedItems(CancelReason reason);\r\n        void WaitForRunningItems();\r\n\r\n        // Waits for running items to complete; waits up to full time out in *each* queue.\r\n        // Returns true to indicate all queues are empty before the timeout.\r\n        bool WaitForRunningItems(DWORD timeoutMilliseconds);\r\n\r\n        // Gets a string that represents the current state of the orchestrator.\r\n        std::string GetStatusString();\r\n\r\n    private:\r\n        std::mutex m_queueLock;\r\n        bool m_enabled = true;\r\n        CancelReason m_disabledReason = CancelReason::None;\r\n        void AddCommandQueue(std::string_view commandName, UINT32 allowedThreads);\r\n        void RemoveItemInState(const OrchestratorQueueItem& item, OrchestratorQueueItemState state);\r\n\r\n        _Requires_lock_held_(m_queueLock)\r\n        std::shared_ptr<OrchestratorQueueItem> FindById(const OrchestratorQueueItemId& queueItemId);\r\n\r\n        Repository::Source m_installingWriteableSource;\r\n        std::map<std::string, std::unique_ptr<OrchestratorQueue>> m_commandQueues;\r\n    };\r\n\r\n    // One of the queues used by the orchestrator.\r\n    // All items in the queue execute the same command.\r\n    // The queue allows multiple items to run at the same time, up to a limit.\r\n    struct OrchestratorQueue\r\n    {\r\n        OrchestratorQueue(ContextOrchestrator& orchestrator, std::string_view commandName, UINT32 allowedThreads);\r\n        ~OrchestratorQueue();\r\n\r\n        // Name of the command this queue can execute\r\n        std::string_view CommandName() const { return m_commandName; }\r\n\r\n        // Enqueues an item to be run when there are threads available.\r\n        void EnqueueAndRunItem(const std::shared_ptr<OrchestratorQueueItem>& item);\r\n\r\n        // Removes an item by id, provided that it is in the given state.\r\n        // Returns true if an item was removed.\r\n        // The item can be removed globally from the orchestrator, or from just this queue.\r\n        bool RemoveItemInState(const OrchestratorQueueItem& item, OrchestratorQueueItemState state, bool isGlobalRemove);\r\n\r\n        // Finds an item by id, if it is in the queue.\r\n        _Requires_lock_held_(m_itemLock)\r\n        std::shared_ptr<OrchestratorQueueItem> FindById(const OrchestratorQueueItemId& queueItemId);\r\n\r\n        // Runs a single item from the queue.\r\n        void RunItem(const OrchestratorQueueItemId& itemId);\r\n\r\n        // Cancels and \"removes\" all items in the queue.\r\n        void CancelAllItems(CancelReason reason);\r\n\r\n        // Waits until the empty queue event is signaled.\r\n        void WaitForEmptyQueue();\r\n\r\n        // Waits until the empty queue event is signaled.\r\n        // Returns true to indicate the queue is empty before the timeout.\r\n        bool WaitForEmptyQueue(DWORD timeoutMilliseconds);\r\n\r\n        // Gets a string that represents the current state of the queue.\r\n        std::string GetStatusString();\r\n\r\n    private:\r\n        // Enqueues an item.\r\n        void EnqueueItem(const std::shared_ptr<OrchestratorQueueItem>& item);\r\n\r\n        _Requires_lock_held_(m_itemLock)\r\n        std::deque<std::shared_ptr<OrchestratorQueueItem>>::iterator FindIteratorById(const OrchestratorQueueItemId& comparisonQueueItemId);\r\n\r\n        ContextOrchestrator& m_orchestrator;\r\n        std::string_view m_commandName;\r\n\r\n        // Number of threads allowed to run items in this queue.\r\n        const UINT32 m_allowedThreads;\r\n\r\n        // Thread pool for this queue, and associated objects.\r\n        // All work items will be added to the callback environment, and the cleanup group\r\n        // will manage their closing.\r\n        // See https://docs.microsoft.com/windows/win32/procthread/using-the-thread-pool-functions\r\n        TP_CALLBACK_ENVIRON m_threadPoolCallbackEnviron;\r\n        wil::unique_any<PTP_POOL, decltype(CloseThreadpool), CloseThreadpool> m_threadPool;\r\n        wil::unique_any<PTP_CLEANUP_GROUP, decltype(CloseThreadpoolCleanupGroup), CloseThreadpoolCleanupGroup> m_threadPoolCleanupGroup;\r\n\r\n        std::mutex m_itemLock;\r\n        std::deque<std::shared_ptr<OrchestratorQueueItem>> m_queueItems;\r\n        wil::slim_event_manual_reset m_queueEmpty{ true };\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Core.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"Public/AppInstallerCLICore.h\"\n#include \"Commands/RootCommand.h\"\n#include \"ExecutionContext.h\"\n#include \"Workflows/WorkflowBase.h\"\n#include <winget/UserSettings.h>\n#include \"Commands/InstallCommand.h\"\n#include \"COMContext.h\"\n#include <AppInstallerFileLogger.h>\n#include <winget/OutputDebugStringLogger.h>\r\n#include \"Public/ShutdownMonitoring.h\"\n\n#ifndef AICLI_DISABLE_TEST_HOOKS\n#include <winget/Debugging.h>\n#endif\n\nusing namespace winrt;\nusing namespace winrt::Windows::Foundation;\nusing namespace AppInstaller::CLI;\nusing namespace AppInstaller::Utility::literals;\n\nnamespace AppInstaller::CLI\n{\n    namespace\n    {\n        // RAII class to restore the console output codepage.\n        struct ConsoleOutputCPRestore\n        {\n            ConsoleOutputCPRestore(UINT cpToChangeTo)\n            {\n                m_previousCP = GetConsoleOutputCP();\n                LOG_LAST_ERROR_IF(!SetConsoleOutputCP(cpToChangeTo));\n            }\n\n            ~ConsoleOutputCPRestore()\n            {\n                SetConsoleOutputCP(m_previousCP);\n            }\n\n            ConsoleOutputCPRestore(const ConsoleOutputCPRestore&) = delete;\n            ConsoleOutputCPRestore& operator=(const ConsoleOutputCPRestore&) = delete;\n\n            ConsoleOutputCPRestore(ConsoleOutputCPRestore&&) = delete;\n            ConsoleOutputCPRestore& operator=(ConsoleOutputCPRestore&&) = delete;\n\n        private:\n            UINT m_previousCP = 0;\n        };\r\n\r\n        void __CRTDECL abort_signal_handler(int)\r\n        {\n#ifndef AICLI_DISABLE_TEST_HOOKS\n            if (Settings::User().Get<Settings::Setting::EnableSelfInitiatedMinidump>())\n            {\n                Debugging::WriteMinidump();\n            }\n#endif\r\n\n            std::_Exit(APPINSTALLER_CLI_ERROR_INTERNAL_ERROR);\n        }\r\n\r\n        wil::slim_event_manual_reset& GetMainWaitEvent()\r\n        {\r\n            static wil::slim_event_manual_reset s_mainWait;\r\n            return s_mainWait;\r\n        }\r\n\r\n        void WaitOnMainWaitEvent()\r\n        {\r\n            GetMainWaitEvent().wait(5000);\r\n        }\r\n\r\n        void RegisterShutdownBlocker()\r\n        {\n            ShutdownMonitoring::ServerShutdownSynchronization::ComponentSystem main{};\r\n            main.Wait = WaitOnMainWaitEvent;\r\n            ShutdownMonitoring::ServerShutdownSynchronization::AddComponent(main);\n        }\n    }\n\n    int CoreMain(int argc, wchar_t const** argv) try\n    {\r\n        // This prevents the OS package management from terminating the CLI process before it has had a chance to gracefully exit.\r\n        RegisterShutdownBlocker();\r\n        auto signalMainExit = wil::scope_exit([]() { GetMainWaitEvent().SetEvent(); });\r\n\r\n        std::signal(SIGABRT, abort_signal_handler);\r\n\n        init_apartment();\n\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        // We have to do this here so the auto minidump config initialization gets caught\r\n        Logging::OutputDebugStringLogger::Add();\n        Logging::Log().SetEnabledChannels(Logging::Channel::All);\n        Logging::Log().SetLevel(Logging::Level::Verbose);\r\n\n        if (Settings::User().Get<Settings::Setting::EnableSelfInitiatedMinidump>())\n        {\n            Debugging::EnableSelfInitiatedMinidump();\n        }\r\n\r\n        Logging::OutputDebugStringLogger::Remove();\n#endif\n\n        Logging::UseGlobalTelemetryLoggerActivityIdOnly();\n\n        Execution::Context context;\n        auto previousThreadGlobals = context.SetForCurrentThread();\r\n\r\n        // Set up debug string logging during initialization\r\n        Logging::OutputDebugStringLogger::Add();\n        Logging::Log().SetEnabledChannels(Logging::Channel::All);\n        Logging::Log().SetLevel(Logging::Level::Verbose);\n\n        Logging::Log().SetEnabledChannels(Settings::User().Get<Settings::Setting::LoggingChannelPreference>());\n        Logging::Log().SetLevel(Settings::User().Get<Settings::Setting::LoggingLevelPreference>());\n        Logging::FileLogger::Add();\r\n        Logging::OutputDebugStringLogger::Remove();\n        Logging::EnableWilFailureTelemetry();\n\n        // Set output to UTF8\n        ConsoleOutputCPRestore utf8CP(CP_UTF8);\n\n        Logging::Telemetry().SetCaller(\"winget-cli\");\n        Logging::Telemetry().LogStartup();\n\n#ifndef AICLI_DISABLE_TEST_HOOKS\n        if (!Settings::User().Get<Settings::Setting::KeepAllLogFiles>())\n#endif\n        {\n            // Initiate the background cleanup of the log file location.\n            Logging::FileLogger::BeginCleanup();\n        }\n\n        context.EnableSignalTerminationHandler();\n\n        context << Workflow::ReportExecutionStage(Workflow::ExecutionStage::ParseArgs);\n\n        // Convert incoming wide char args to UTF8\n        std::vector<std::string> utf8Args;\n        for (int i = 1; i < argc; ++i)\n        {\n            utf8Args.emplace_back(Utility::ConvertToUTF8(argv[i]));\n        }\n\n        AICLI_LOG(CLI, Info, << \"WinGet invoked with arguments:\" << [&]() {\n                std::stringstream strstr;\n                for (const auto& arg : utf8Args)\n                {\n                    strstr << \" '\" << arg << '\\'';\n                }\n                return strstr.str();\n            }());\n\n        Invocation invocation{ std::move(utf8Args) };\n\n        // The root command is our fallback in the event of very bad or very little input\n        std::unique_ptr<Command> command = std::make_unique<RootCommand>();\n\n        try\n        {\r\n            // Block CLI execution if WinGetCommandLineInterfaces is disabled by Policy\r\n            if (!Settings::GroupPolicies().IsEnabled(Settings::TogglePolicy::Policy::WinGetCommandLineInterfaces))\r\n            {\r\n                AICLI_LOG(CLI, Error, << \"WinGet is disabled by group policy\");\r\n                throw Settings::GroupPolicyException(Settings::TogglePolicy::Policy::WinGetCommandLineInterfaces);\r\n            }\r\n\n            std::unique_ptr<Command> subCommand = command->FindSubCommand(invocation);\n            while (subCommand)\n            {\n                command = std::move(subCommand);\n                subCommand = command->FindSubCommand(invocation);\n            }\n            Logging::Telemetry().LogCommand(command->FullName());\n\n            command->ParseArguments(invocation, context.Args);\n            context.UpdateForArgs();\n            context.SetExecutingCommand(command.get());\n            command->ValidateArguments(context.Args);\n        }\n        // Exceptions specific to parsing the arguments of a command\n        catch (const CommandException& ce)\n        {\n            command->OutputHelp(context.Reporter, &ce);\n            AICLI_LOG(CLI, Error, << \"Error encountered parsing command line: \" << ce.Message());\n            return APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS;\n        }\n        catch (const Settings::GroupPolicyException& e)\n        {\n            // Report any action blocked by Group Policy.\n            auto policy = Settings::TogglePolicy::GetPolicy(e.Policy());\n            AICLI_LOG(CLI, Error, << \"Operation blocked by Group Policy: \" << policy.RegValueName());\n            context.Reporter.Error() << Resource::String::DisabledByGroupPolicy(policy.PolicyName()) << std::endl;\n            return APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY;\n        }\r\n        catch (...)\r\n        {\r\n            return Workflow::HandleException(context, std::current_exception());\r\n        }\n\n        return Execute(context, command);\n    }\n    // End of the line exceptions that are not ever expected.\n    // Telemetry cannot be reliable beyond this point, so don't let these happen.\n    catch (...)\n    {\n        return APPINSTALLER_CLI_ERROR_INTERNAL_ERROR;\n    }\n\n    void ServerInitialize()\n    {\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        // We have to do this here so the auto minidump config initialization gets caught\r\n        Logging::OutputDebugStringLogger::Add();\n        Logging::Log().SetEnabledChannels(Logging::Channel::All);\n        Logging::Log().SetLevel(Logging::Level::Verbose);\r\n\n        if (Settings::User().Get<Settings::Setting::EnableSelfInitiatedMinidump>())\n        {\n            Debugging::EnableSelfInitiatedMinidump();\n        }\r\n\r\n        Logging::OutputDebugStringLogger::Remove();\n#endif\n\n        AppInstaller::CLI::Execution::COMContext::SetLoggers();\n    }\r\n\r\n    void InProcInitialize()\n    {\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        // We have to do this here so the auto minidump config initialization gets caught\r\n        Logging::OutputDebugStringLogger::Add();\n        Logging::Log().SetEnabledChannels(Logging::Channel::All);\n        Logging::Log().SetLevel(Logging::Level::Verbose);\r\n\n        if (Settings::User().Get<Settings::Setting::EnableSelfInitiatedMinidump>())\n        {\n            Debugging::EnableSelfInitiatedMinidump();\n        }\r\n\r\n        Logging::OutputDebugStringLogger::Remove();\n#endif\n\r\n        // Explicitly set default channel and level before user settings from PackageManagerSettings\n        AppInstaller::CLI::Execution::COMContext::SetLoggers(AppInstaller::Logging::Channel::Defaults, AppInstaller::Logging::Level::Info);\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/ExecutionArgs.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <string>\r\n#include <string_view>\r\n#include <map>\r\n#include <vector>\r\n\r\nnamespace AppInstaller::CLI::Execution\r\n{\r\n    struct Args\r\n    {\r\n        enum class Type : uint32_t\r\n        {\r\n            // Args to specify where to get app\r\n            Query, // Query to be performed against index\r\n            MultiQuery, // Like query, but can take multiple values\r\n            Manifest, // Provide the app manifest directly\r\n\r\n            // Query filtering criteria and query behavior\r\n            Id,\r\n            Name,\r\n            Moniker,\r\n            Tag,\r\n            Command,\r\n            Source, // Index source to be queried against\r\n            Count, // Maximum query results\r\n            Exact, // Exact match required\r\n\r\n            // Manifest selection behavior after an app is found\r\n            Version,\r\n            Channel,\r\n\r\n            // Install behavior\r\n            Interactive,\r\n            Silent,\r\n            Locale,\r\n            Log,\r\n            CustomSwitches, // CustomSwitches args are args passed to the installer in addition to any defined in the manifest\r\n            Override, // Override args are (and the only args) directly passed to installer\r\n            InstallLocation,\r\n            InstallScope,\r\n            InstallArchitecture,\r\n            InstallerArchitecture,\r\n            InstallerType,\r\n            HashOverride, // Ignore hash mismatches\r\n            SkipDependencies, // Skip dependencies\r\n            DependenciesOnly, // Install only dependencies, not the target package\r\n            IgnoreLocalArchiveMalwareScan, // Ignore the local malware scan on archive files\r\n            AcceptPackageAgreements, // Accept all license agreements for packages\r\n            Rename, // Renames the file of the executable. Only applies to the portable installerType\r\n            NoUpgrade, // Install flow should not try to convert to upgrade flow upon finding existing installed version\r\n            AllowReboot, // Allows the reboot flow to proceed if applicable\r\n\r\n            // Uninstall behavior\r\n            Purge, // Removes all files and directories related to a package during an uninstall. Only applies to the portable installerType.\r\n            Preserve, // Retains any files and directories created by the portable exe.\r\n            ProductCode, // Uninstalls using the product code as the identifier.\r\n            AllVersions, // Uninstall all versions of the package\r\n            TargetVersion, // The specific version to target\r\n\r\n            //Source Command\r\n            SourceName,\r\n            SourceType,\r\n            SourceArg,\r\n            ForceSourceReset,\r\n            SourceExplicit,\r\n            SourceTrustLevel,\r\n            SourcePriority,\r\n            SourceEditExplicit,\r\n\r\n            //Hash Command\r\n            HashFile,\r\n            Msix, // Flag to indicate the input file is msix\r\n\r\n            //Validate Command\r\n            ValidateManifest,\r\n            IgnoreWarnings,\r\n\r\n            // Complete Command\r\n            Word,\r\n            CommandLine,\r\n            Position,\r\n\r\n            // Export Command\r\n            IncludeVersions,\r\n\r\n            // Import Command\r\n            ImportFile,\r\n            IgnoreUnavailable,\r\n            IgnoreVersions,\r\n\r\n            // Download Command\r\n            DownloadDirectory,\r\n            SkipMicrosoftStorePackageLicense,\r\n            Platform,\r\n            OSVersion,\r\n\r\n            // Setting Command\r\n            AdminSettingEnable,\r\n            AdminSettingDisable,\r\n            SettingName,\r\n            SettingValue,\r\n\r\n            // Upgrade command\r\n            All, // Used in Update command to update all installed packages to latest\r\n            IncludeUnknown, // Used in Upgrade command to allow upgrades of packages with unknown versions\r\n            IncludePinned, // Used in Upgrade command to allow upgrades to pinned packages (only for pinning type of pins)\r\n            UninstallPrevious, // Used in Upgrade command to override the default manifest behavior to UninstallPrevious\r\n\r\n            // Show command\r\n            ListVersions, // Used in Show command to list all available versions of an app\r\n\r\n            // List Command\r\n            Upgrade, // Used in List command to only show versions with upgrades\r\n            ListDetails,\r\n\r\n            // Pin command\r\n            GatedVersion, // Differs from Version in that this supports wildcards\r\n            BlockingPin,\r\n            PinInstalled,\r\n\r\n            // Error command\r\n            ErrorInput,\r\n\r\n            // Resume Command\r\n            ResumeId,\r\n            IgnoreResumeLimit,\r\n\r\n            // Font Command\r\n            Family,\r\n            Details,\r\n\r\n            // Stub package (extended features)\r\n            ExtendedFeaturesEnable,\r\n            ExtendedFeaturesDisable,\r\n\r\n            // Configuration\r\n            ConfigurationFile,\r\n            ConfigurationAcceptWarning,\r\n            ConfigurationSuppressPrologue,\r\n            ConfigurationProcessorPath,\r\n            ConfigurationModulePath,\r\n            ConfigurationExportPackageId,\r\n            ConfigurationExportModule,\r\n            ConfigurationExportResource,\r\n            ConfigurationExportAll,\r\n            ConfigurationHistoryItem,\r\n            ConfigurationHistoryRemove,\r\n            ConfigurationStatusWatch,\r\n\r\n            // DSCv3 resources\r\n            DscResourceFunctionGet,\r\n            DscResourceFunctionSet,\r\n            DscResourceFunctionWhatIf,\r\n            DscResourceFunctionTest,\r\n            DscResourceFunctionDelete,\r\n            DscResourceFunctionExport,\r\n            DscResourceFunctionValidate,\r\n            DscResourceFunctionResolve,\r\n            DscResourceFunctionAdapter,\r\n            DscResourceFunctionSchema,\r\n            DscResourceFunctionManifest,\r\n\r\n            // Common arguments\r\n            NoVT, // Disable VirtualTerminal outputs\r\n            RetroStyle, // Makes progress display as retro\r\n            RainbowStyle, // Makes progress display as a rainbow\r\n            NoProgress, // Disables progress bar and spinner\r\n            Help, // Show command usage\r\n            Info, // Show general info about WinGet\r\n            VerboseLogs, // Increases winget logging level to verbose\r\n            DisableInteractivity, // Disable interactive prompts\r\n            Wait, // Prompts the user to press any key before exiting\r\n            OpenLogs, // Opens the default logs directory after executing the command\r\n            Force, // Forces the execution of the workflow with non security related issues\r\n            OutputFile,\r\n            Correlation,\r\n\r\n            DependencySource, // Index source to be queried against for finding dependencies\r\n            CustomHeader, // Optional Rest source header\r\n            AcceptSourceAgreements, // Accept all source agreements\r\n\r\n            AuthenticationMode, // Authentication mode (silent, silentPreferred or interactive)\r\n            AuthenticationAccount, // Authentication account to be used\r\n\r\n            // Network Behavior\r\n            Proxy, // Set a proxy to use in this execution\r\n            NoProxy, // Do not use the default proxy\r\n\r\n            ToolVersion,\r\n\r\n            // Used for demonstration purposes\r\n            ExperimentalArg,\r\n\r\n            // This should always be at the end\r\n            Max\r\n        };\r\n\r\n        template<typename... T, std::enable_if_t<(... && std::is_same_v<T, Args::Type>), bool> = true>\r\n        bool Contains(T... arg) const\r\n        {\r\n            return (... && (m_parsedArgs.count(arg) != 0));\r\n        }\r\n\r\n        const std::vector<std::string>* GetArgs(Type arg) const\r\n        {\r\n            auto itr = m_parsedArgs.find(arg);\r\n            return (itr == m_parsedArgs.end() ? nullptr : &(itr->second));\r\n        }\r\n\r\n        std::string_view GetArg(Type arg) const\r\n        {\r\n            auto itr = m_parsedArgs.find(arg);\r\n\r\n            if (itr == m_parsedArgs.end())\r\n            {\r\n                return {};\r\n            }\r\n\r\n            return itr->second[0];\r\n        }\r\n\r\n        size_t GetCount(Type arg) const\r\n        {\r\n            auto args = GetArgs(arg);\r\n            return (args ? args->size() : 0);\r\n        }\r\n\r\n        bool AddArg(Type arg)\r\n        {\r\n            return m_parsedArgs[arg].empty();\r\n        }\r\n\r\n        void AddArg(Type arg, std::string value)\r\n        {\r\n            m_parsedArgs[arg].emplace_back(std::move(value));\r\n        }\r\n\r\n        void AddArg(Type arg, std::string_view value)\r\n        {\r\n            m_parsedArgs[arg].emplace_back(value);\r\n        }\r\n\r\n        bool Empty()\r\n        {\r\n            return m_parsedArgs.empty();\r\n        }\r\n\r\n        size_t GetArgsCount() const\r\n        {\r\n            return m_parsedArgs.size();\r\n        }\r\n\r\n        std::vector<Type> GetTypes() const\r\n        {\r\n            std::vector<Type> types;\r\n\r\n            for (auto const& i : m_parsedArgs)\r\n            {\r\n                types.emplace_back(i.first);\r\n            }\r\n\r\n            return types;\r\n        }\r\n\r\n        // If the user passes the same value multiple times inside a MultiQuery, operations will be repeated\r\n        // Since there currently is not a way to include search options within a MultiQuery, processing duplicates\r\n        // does not make sense within a single invocation\r\n        void MakeMultiQueryContainUniqueValues()\r\n        {\r\n            auto itr = m_parsedArgs.find(Type::MultiQuery);\r\n            \r\n            // If there is not a value in MultiQuery, or there is only one value, it is presumed to be unique\r\n            if (itr == m_parsedArgs.end() || itr->second.size() == 1)\r\n            {\r\n                return;\r\n            }\r\n\r\n            std::set<std::string> querySet;\r\n            std::vector<std::string>& queryStrings = itr->second;\r\n\r\n            queryStrings.erase(std::remove_if(queryStrings.begin(), queryStrings.end(), [&](const std::string value) { return !querySet.insert(value).second; }), queryStrings.end());\r\n        }\r\n\r\n        // If we get a single value for multi-query, we remove the argument and add it back as a single query.\r\n        // This way the rest of the code can assume that if there is a MultiQuery we will always have multiple values,\r\n        // and if there is a single one it will be in the Query type.\r\n        void MoveMultiQueryToSingleQueryIfNeeded()\r\n        {\r\n            auto itr = m_parsedArgs.find(Type::MultiQuery);\r\n            if (itr != m_parsedArgs.end() && itr->second.size() == 1)\r\n            {\r\n                // A test ensures that commands don't have both Query and MultiQuery arguments,\r\n                // so if we had a MultiQuery value, we can be sure there is no Query value\r\n                m_parsedArgs[Type::Query].emplace_back(std::move(itr->second[0]));\r\n                m_parsedArgs.erase(itr);\r\n            }\r\n        }\r\n\r\n    private:\r\n        std::map<Type, std::vector<std::string>> m_parsedArgs;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/ExecutionContext.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"AppInstallerRuntime.h\"\r\n#include \"Argument.h\"\r\n#include \"COMContext.h\"\r\n#include \"Command.h\"\r\n#include \"ExecutionContext.h\"\r\n#include \"Public/ShutdownMonitoring.h\"\r\n#include <winget/Checkpoint.h>\r\n#include <winget/Reboot.h>\r\n#include <winget/UserSettings.h>\r\n#include <winget/NetworkSettings.h>\r\n\r\nusing namespace AppInstaller::Checkpoints;\r\n\r\nnamespace AppInstaller::CLI::Execution\r\n{\r\n    using namespace Settings;\r\n\r\n    namespace\r\n    {\r\n        bool ShouldRemoveCheckpointDatabase(HRESULT hr)\r\n        {\r\n            switch (hr)\r\n            {\r\n            case APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_FOR_INSTALL:\r\n            case APPINSTALLER_CLI_ERROR_RESUME_LIMIT_EXCEEDED:\r\n            case APPINSTALLER_CLI_ERROR_CLIENT_VERSION_MISMATCH:\r\n                return false;\r\n            default:\r\n                return true;\r\n            }\r\n        }\r\n    }\r\n\r\n    Context::~Context()\r\n    {\r\n        if (Settings::ExperimentalFeature::IsEnabled(ExperimentalFeature::Feature::Resume))\r\n        {\r\n            if (m_checkpointManager && (!IsTerminated() || ShouldRemoveCheckpointDatabase(GetTerminationHR())))\r\n            {\r\n                m_checkpointManager->CleanUpDatabase();\r\n                AppInstaller::Reboot::UnregisterRestartForWER();\r\n            }\r\n        }\r\n\r\n        if (m_disableSignalTerminationHandlerOnExit)\r\n        {\r\n            EnableSignalTerminationHandler(false);\r\n        }\r\n    }\r\n\r\n    Context Context::CreateEmptyContext()\r\n    {\r\n        AppInstaller::ThreadLocalStorage::WingetThreadGlobals threadGlobals;\r\n        return Context(Reporter, threadGlobals);\r\n    }\r\n\r\n    std::unique_ptr<Context> Context::CreateSubContext()\r\n    {\r\n        auto clone = std::make_unique<Context>(Reporter, *m_threadGlobals);\r\n        clone->m_flags = m_flags;\r\n        clone->m_executingCommand = m_executingCommand;\r\n        // If the parent is hooked up to the CTRL signal, have the clone be as well\r\n        if (m_disableSignalTerminationHandlerOnExit)\r\n        {\r\n            clone->EnableSignalTerminationHandler();\r\n        }\r\n        CopyArgsToSubContext(clone.get());\r\n        CopyDataToSubContext(clone.get());\r\n        return clone;\r\n    }\r\n\r\n    void Context::CopyArgsToSubContext(Context* subContext)\r\n    {\r\n        auto argProperties = ArgumentCommon::GetFromExecArgs(Args);\r\n        for (const auto& arg : argProperties)\r\n        {\r\n            if (WI_IsFlagSet(arg.TypeCategory, ArgTypeCategory::CopyFlagToSubContext))\r\n            {\r\n                subContext->Args.AddArg(arg.Type);\r\n            }\r\n            else if (WI_IsFlagSet(arg.TypeCategory, ArgTypeCategory::CopyValueToSubContext))\r\n            {\r\n                subContext->Args.AddArg(arg.Type, Args.GetArg(arg.Type));\r\n            }\r\n        }\r\n    }\r\n\r\n    void Context::CopyDataToSubContext(Context* subContext)\r\n    {\r\n#define COPY_DATA_IF_EXISTS(dataType) \\\r\n        if (this->Contains(dataType)) \\\r\n        { \\\r\n            subContext->Add<dataType>(this->Get<dataType>()); \\\r\n        }\r\n\r\n        COPY_DATA_IF_EXISTS(Data::InstallerDownloadAuthenticators);\r\n    }\r\n\r\n    void Context::EnableSignalTerminationHandler(bool enabled)\r\n    {\r\n        ShutdownMonitoring::TerminationSignalHandler::EnableListener(enabled, this);\r\n        m_disableSignalTerminationHandlerOnExit = enabled;\r\n    }\r\n\r\n    void Context::UpdateForArgs()\r\n    {\r\n        // Change logging level to Info if Verbose not requested\r\n        if (Args.Contains(Args::Type::VerboseLogs))\r\n        {\r\n            Logging::Log().SetLevel(Logging::Level::Verbose);\r\n        }\r\n\r\n        // Disable warnings if requested\r\n        if (Args.Contains(Args::Type::IgnoreWarnings))\r\n        {\r\n            Reporter.SetLevelMask(Reporter::Level::Warning, false);\r\n        }\r\n\r\n        // Set proxy\r\n        if (Args.Contains(Args::Type::Proxy))\r\n        {\r\n            Network().SetProxyUri(std::string{ Args.GetArg(Args::Type::Proxy) });\r\n        }\r\n        else if (Args.Contains(Args::Type::NoProxy))\r\n        {\r\n            Network().SetProxyUri(std::nullopt);\r\n        }\r\n\r\n        // Set visual style\r\n        if (Args.Contains(Args::Type::NoProgress))\r\n        {\r\n            Reporter.SetStyle(VisualStyle::Disabled);\r\n        }\r\n        else if (Args.Contains(Args::Type::NoVT))\r\n        {\r\n            Reporter.SetStyle(VisualStyle::NoVT);\r\n        }\r\n        else if (Args.Contains(Args::Type::RetroStyle))\r\n        {\r\n            Reporter.SetStyle(VisualStyle::Retro);\r\n        }\r\n        else if (Args.Contains(Args::Type::RainbowStyle))\r\n        {\r\n            Reporter.SetStyle(VisualStyle::Rainbow);\r\n        }\r\n        else\r\n        {\r\n            Reporter.SetStyle(User().Get<Setting::ProgressBarVisualStyle>());\r\n        }\r\n    }\r\n\r\n    void Context::Terminate(HRESULT hr, std::string_view file, size_t line)\r\n    {\r\n        if (hr == APPINSTALLER_CLI_ERROR_CTRL_SIGNAL_RECEIVED)\r\n        {\r\n            ++m_CtrlSignalCount;\r\n            // Use a more recognizable error\r\n            hr = E_ABORT;\r\n\r\n            // If things aren't terminating fast enough for the user, they will probably press CTRL+C again.\r\n            // In that case, we should forcibly terminate.\r\n            // Unless we want to spin a separate thread for all work, we have to just exit here.\r\n            if (m_CtrlSignalCount >= 2)\r\n            {\r\n                Reporter.CloseOutputStream(true);\r\n                Logging::Telemetry().LogCommandTermination(hr, file, line);\r\n                std::exit(hr);\r\n            }\r\n        }\r\n        else if (hr == APPINSTALLER_CLI_ERROR_APPTERMINATION_RECEIVED)\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"Got app termination signal\");\r\n            hr = E_ABORT;\r\n        }\r\n\r\n        Logging::Telemetry().LogCommandTermination(hr, file, line);\r\n\r\n        if (!m_isTerminated)\r\n        {\r\n            SetTerminationHR(hr);\r\n        }\r\n    }\r\n\r\n    void Context::SetTerminationHR(HRESULT hr)\r\n    {\r\n        m_terminationHR = hr;\r\n        m_isTerminated = true;\r\n    }\r\n\r\n    void Context::Cancel(CancelReason reason, bool bypassUser)\r\n    {\r\n        HRESULT hr = ToHRESULT(reason);\r\n\r\n        Terminate(hr);\r\n        Reporter.CancelInProgressTask(bypassUser, reason);\r\n    }\r\n\r\n    void Context::SetExecutionStage(Workflow::ExecutionStage stage)\r\n    {\r\n        if (m_executionStage == stage)\r\n        {\r\n            return;\r\n        }\r\n        else if (m_executionStage > stage)\r\n        {\r\n            THROW_HR_MSG(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), \"Reporting ExecutionStage to an earlier Stage: current[%d], new[%d]\", ToIntegral(m_executionStage), ToIntegral(stage));\r\n        }\r\n\r\n        m_executionStage = stage;\r\n        GetThreadGlobals().GetTelemetryLogger().SetExecutionStage(static_cast<uint32_t>(m_executionStage));\r\n    }\r\n\r\n    AppInstaller::ThreadLocalStorage::WingetThreadGlobals& Context::GetThreadGlobals()\r\n    {\r\n        return *m_threadGlobals;\r\n    }\r\n\r\n    std::shared_ptr<ThreadLocalStorage::WingetThreadGlobals> Context::GetSharedThreadGlobals()\r\n    {\r\n        return m_threadGlobals;\r\n    }\r\n\r\n    std::unique_ptr<AppInstaller::ThreadLocalStorage::PreviousThreadGlobals> Context::SetForCurrentThread()\r\n    {\r\n        return m_threadGlobals->SetForCurrentThread();\r\n    }\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n    bool Context::ShouldExecuteWorkflowTask(const Workflow::WorkflowTask& task)\r\n    {\r\n        return (m_shouldExecuteWorkflowTask ? m_shouldExecuteWorkflowTask(task) : true);\r\n    }\r\n#endif\r\n\r\n    void ContextEnumBasedVariantMapActionCallback(const void* map, Data data, EnumBasedVariantMapAction action)\r\n    {\r\n        switch (action)\r\n        {\r\n        case EnumBasedVariantMapAction::Add:\r\n            AICLI_LOG(Workflow, Verbose, << \"Setting data item: \" << data);\r\n            break;\r\n        case EnumBasedVariantMapAction::Contains:\r\n            AICLI_LOG(Workflow, Verbose, << \"Checking data item: \" << data);\r\n            break;\r\n        case EnumBasedVariantMapAction::Get:\r\n            AICLI_LOG(Workflow, Verbose, << \"Getting data item: \" << data);\r\n            break;\r\n        }\r\n\r\n        UNREFERENCED_PARAMETER(map);\r\n    }\r\n\r\n    std::string Context::GetResumeId()\r\n    {\r\n        return m_checkpointManager->GetResumeId();\r\n    }\r\n\r\n    std::optional<Checkpoint<AutomaticCheckpointData>> Context::LoadCheckpoint(const std::string& resumeId)\r\n    {\r\n        m_checkpointManager = std::make_unique<AppInstaller::Checkpoints::CheckpointManager>(resumeId);\r\n        return m_checkpointManager->GetAutomaticCheckpoint();\r\n    }\r\n\r\n    std::vector<AppInstaller::Checkpoints::Checkpoint<Execution::Data>> Context::GetCheckpoints()\r\n    {\r\n        return m_checkpointManager->GetCheckpoints();\r\n    }\r\n\r\n    void Context::Checkpoint(std::string_view checkpointName, std::vector<Execution::Data> contextData)\r\n    {\r\n        UNREFERENCED_PARAMETER(checkpointName);\r\n        UNREFERENCED_PARAMETER(contextData);\r\n\r\n        if (!m_checkpointManager)\r\n        {\r\n            m_checkpointManager = std::make_unique<AppInstaller::Checkpoints::CheckpointManager>();\r\n            m_checkpointManager->CreateAutomaticCheckpoint(*this);\r\n\r\n            // Register for restart only when we first call checkpoint to support restarting from an unexpected shutdown.\r\n            AppInstaller::Reboot::RegisterRestartForWER(\"resume -g \" + GetResumeId());\r\n        }\r\n\r\n        // TODO: Capture context data for checkpoint.\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/ExecutionContext.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"winget/ThreadGlobals.h\"\r\n#include \"ExecutionReporter.h\"\r\n#include \"ExecutionArgs.h\"\r\n#include \"ExecutionContextData.h\"\r\n#include \"CompletionData.h\"\r\n#include \"CheckpointManager.h\"\r\n#include <AppInstallerProgress.h>\r\n#include <winget/Checkpoint.h>\r\n\r\n#include <string_view>\r\n\r\n#define WINGET_CATCH_RESULT_EXCEPTION_STORE(exceptionHR)   catch (const wil::ResultException& re) { exceptionHR = re.GetErrorCode(); }\r\n#define WINGET_CATCH_HRESULT_EXCEPTION_STORE(exceptionHR)   catch (const winrt::hresult_error& hre) { exceptionHR = hre.code(); }\r\n#define WINGET_CATCH_COMMAND_EXCEPTION_STORE(exceptionHR)   catch (const ::AppInstaller::CLI::CommandException&) { exceptionHR = APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS; }\r\n#define WINGET_CATCH_POLICY_EXCEPTION_STORE(exceptionHR)   catch (const ::AppInstaller::Settings::GroupPolicyException&) { exceptionHR = APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY; }\r\n#define WINGET_CATCH_STD_EXCEPTION_STORE(exceptionHR, genericHR)   catch (const std::exception&) { exceptionHR = genericHR; }\r\n#define WINGET_CATCH_ALL_EXCEPTION_STORE(exceptionHR, genericHR)   catch (...) { exceptionHR = genericHR; }\r\n#define WINGET_CATCH_STORE(exceptionHR, genericHR) \\\r\n        WINGET_CATCH_RESULT_EXCEPTION_STORE(exceptionHR) \\\r\n        WINGET_CATCH_HRESULT_EXCEPTION_STORE(exceptionHR) \\\r\n        WINGET_CATCH_COMMAND_EXCEPTION_STORE(exceptionHR) \\\r\n        WINGET_CATCH_POLICY_EXCEPTION_STORE(exceptionHR) \\\r\n        WINGET_CATCH_STD_EXCEPTION_STORE(exceptionHR, genericHR) \\\r\n        WINGET_CATCH_ALL_EXCEPTION_STORE(exceptionHR, genericHR)\r\n\r\n// Terminates the Context with some logging to indicate the location.\r\n// Also returns from the current function.\r\n#define AICLI_TERMINATE_CONTEXT_ARGS(_context_,_hr_,_ret_) \\\r\n    do { \\\r\n        _context_.Terminate(_hr_, __FILE__, __LINE__); \\\r\n        return _ret_; \\\r\n    } while(0,0)\r\n\r\n// Terminates the Context named 'context' with some logging to indicate the location.\r\n// Also returns from the current function.\r\n#define AICLI_TERMINATE_CONTEXT(_hr_)   AICLI_TERMINATE_CONTEXT_ARGS(context,_hr_,)\r\n\r\n// Terminates the Context named 'context' with some logging to indicate the location.\r\n// Also returns the specified value from the current function.\r\n#define AICLI_TERMINATE_CONTEXT_RETURN(_hr_,_ret_) AICLI_TERMINATE_CONTEXT_ARGS(context,_hr_,_ret_)\r\n\r\n// Returns if the context is terminated.\r\n#define AICLI_RETURN_IF_TERMINATED(_context_) if ((_context_).IsTerminated()) { return; }\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    struct Command;\r\n}\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    struct WorkflowTask;\r\n    enum class ExecutionStage : uint32_t;\r\n}\r\n\r\nnamespace AppInstaller::CLI::Execution\r\n{\r\n    // bit masks used as Context flags\r\n    enum class ContextFlag : int\r\n    {\r\n        None = 0x0,\r\n        InstallerExecutionUseUpdate = 0x1,\r\n        InstallerHashMatched = 0x2,\r\n        InstallerTrusted = 0x4,\r\n        // Allows a failure in a single source to generate a warning rather than an error.\r\n        // TODO: Remove when the source interface is refactored.\r\n        TreatSourceFailuresAsWarning = 0x8,\r\n        ShowSearchResultsOnPartialFailure = 0x10,\r\n        DisableInteractivity = 0x40,\r\n        BypassIsStoreClientBlockedPolicyCheck = 0x80,\r\n        InstallerDownloadOnly = 0x100,\r\n        Resume = 0x200,\r\n        RebootRequired = 0x400,\r\n        RegisterResume = 0x800,\r\n        InstallerExecutionUseRepair = 0x1000,\r\n    };\r\n\r\n    DEFINE_ENUM_FLAG_OPERATORS(ContextFlag);\r\n\r\n    // Callback to log data actions.\r\n    void ContextEnumBasedVariantMapActionCallback(const void* map, Data data, EnumBasedVariantMapAction action);\r\n\r\n    // The context within which all commands execute.\r\n    // Contains input/output via Execution::Reporter and\r\n    // arguments via Execution::Args.\r\n    struct Context : EnumBasedVariantMap<Data, details::DataMapping, ContextEnumBasedVariantMapActionCallback>, ICancellable\r\n    {\r\n        Context() = default;\r\n        Context(std::ostream& out, std::istream& in) : Reporter(out, in) {}\r\n\r\n        // Constructor for creating a sub-context.\r\n        Context(Execution::Reporter& reporter, ThreadLocalStorage::WingetThreadGlobals& threadGlobals) :\r\n            Reporter(reporter, Execution::Reporter::clone_t{}),\r\n            m_threadGlobals(std::make_shared<ThreadLocalStorage::WingetThreadGlobals>(threadGlobals, ThreadLocalStorage::WingetThreadGlobals::create_sub_thread_globals_t{})) {}\r\n\r\n        virtual ~Context();\r\n\r\n        // The path for console input/output for all functionality.\r\n        Reporter Reporter;\r\n\r\n        // The arguments given to execute with.\r\n        Args Args;\r\n\r\n        // Creates a empty context, inheriting \r\n        Context CreateEmptyContext();\r\n\r\n        // Creates a child of this context.\r\n        virtual std::unique_ptr<Context> CreateSubContext();\r\n\r\n        // Enables reception of CTRL signals and window messages.\r\n        void EnableSignalTerminationHandler(bool enabled = true);\r\n\r\n        // Applies changes based on the parsed args.\r\n        void UpdateForArgs();\r\n\r\n        // Returns a value indicating whether the context is terminated.\r\n        bool IsTerminated() const { return m_isTerminated; }\r\n\r\n        // Resets the context to a nonterminated state. \r\n        void ResetTermination() { m_terminationHR = S_OK; m_isTerminated = false; }\r\n\r\n        // Gets the HRESULT reason for the termination.\r\n        HRESULT GetTerminationHR() const { return m_terminationHR; }\r\n\r\n        // Set the context to the terminated state.\r\n        void Terminate(HRESULT hr, std::string_view file = {}, size_t line = {});\r\n\r\n        // Set the termination hr of the context.\r\n        void SetTerminationHR(HRESULT hr);\r\n\r\n        // Cancel the context; this terminates it as well as informing any in progress task to stop cooperatively.\r\n        // Multiple attempts with CancelReason::CancelSignal may cause the process to simply exit.\r\n        // The bypassUser indicates whether the user should be asked for cancellation (does not currently have any effect).\r\n        void Cancel(CancelReason reason, bool bypassUser = false) override;\r\n\r\n        // Gets context flags\r\n        ContextFlag GetFlags() const\r\n        {\r\n            return m_flags;\r\n        }\r\n\r\n        // Set context flags\r\n        void SetFlags(ContextFlag flags)\r\n        {\r\n            WI_SetAllFlags(m_flags, flags);\r\n        }\r\n\r\n        // Clear context flags\r\n        void ClearFlags(ContextFlag flags)\r\n        {\r\n            WI_ClearAllFlags(m_flags, flags);\r\n        }\r\n\r\n        virtual void SetExecutionStage(Workflow::ExecutionStage stage);\r\n\r\n        // Get Globals for Current Context\r\n        ThreadLocalStorage::WingetThreadGlobals& GetThreadGlobals();\r\n        std::shared_ptr<ThreadLocalStorage::WingetThreadGlobals> GetSharedThreadGlobals();\r\n\r\n        std::unique_ptr<AppInstaller::ThreadLocalStorage::PreviousThreadGlobals> SetForCurrentThread();\r\n\r\n        // Gets the executing command\r\n        AppInstaller::CLI::Command* GetExecutingCommand() { return m_executingCommand; }\r\n\r\n        // Sets the executing command\r\n        void SetExecutingCommand(AppInstaller::CLI::Command* command) { m_executingCommand = command; }\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        // Enable tests to override behavior\r\n        bool ShouldExecuteWorkflowTask(const Workflow::WorkflowTask& task);\r\n#endif\r\n\r\n        // Returns the resume id.\r\n        std::string GetResumeId();\r\n\r\n        // Called by the resume command. Loads the checkpoint manager with the resume id and returns the automatic checkpoint.\r\n        std::optional<AppInstaller::Checkpoints::Checkpoint<AppInstaller::Checkpoints::AutomaticCheckpointData>> LoadCheckpoint(const std::string& resumeId);\r\n\r\n        // Returns data checkpoints in the order of latest checkpoint to earliest.\r\n        std::vector<AppInstaller::Checkpoints::Checkpoint<Execution::Data>> GetCheckpoints();\r\n\r\n        // Creates a checkpoint for the provided context data.\r\n        void Checkpoint(std::string_view checkpointName, std::vector<Execution::Data> contextData);\r\n\r\n    protected:\r\n        // Copies the args that are also needed in a sub-context. E.g., silent\r\n        void CopyArgsToSubContext(Context* subContext);\r\n\r\n        // Copies the execution data that are also needed in a sub-context. E.g., shared installer download authenticator map\r\n        void CopyDataToSubContext(Context* subContext);\r\n\r\n        // Neither virtual functions nor member fields can be inside AICLI_DISABLE_TEST_HOOKS\r\n        // or we could have ODR violations that lead to nasty bugs. So we will simply never\r\n        // use this if AICLI_DISABLE_TEST_HOOKS is defined.\r\n        std::function<bool(const Workflow::WorkflowTask&)> m_shouldExecuteWorkflowTask;\r\n\r\n    private:\r\n        DestructionToken m_disableSignalTerminationHandlerOnExit = false;\r\n        bool m_isTerminated = false;\r\n        HRESULT m_terminationHR = S_OK;\r\n        size_t m_CtrlSignalCount = 0;\r\n        ContextFlag m_flags = ContextFlag::None;\r\n        Workflow::ExecutionStage m_executionStage = Workflow::ExecutionStage::Initial;\r\n        std::shared_ptr<ThreadLocalStorage::WingetThreadGlobals> m_threadGlobals = std::make_shared<ThreadLocalStorage::WingetThreadGlobals>();\r\n        AppInstaller::CLI::Command* m_executingCommand = nullptr;\r\n        std::unique_ptr<AppInstaller::Checkpoints::CheckpointManager> m_checkpointManager;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/ExecutionContextData.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerDownloader.h>\r\n#include <winget/RepositorySource.h>\r\n#include <winget/Manifest.h>\r\n#include <winget/ARPCorrelation.h>\r\n#include <winget/Authentication.h>\r\n#include <winget/Pin.h>\r\n#include <winget/PinningData.h>\r\n#include \"CompletionData.h\"\r\n#include \"PackageCollection.h\"\r\n#include \"PortableInstaller.h\"\r\n#include \"Workflows/WorkflowBase.h\"\r\n#include \"ConfigurationContext.h\"\r\n\r\n#include <filesystem>\r\n#include <map>\r\n#include <string>\r\n#include <utility>\r\n#include <variant>\r\n#include <vector>\r\n\r\nnamespace AppInstaller::CLI::Execution\r\n{\r\n    // Names a piece of data stored in the context by a workflow step.\r\n    // Must start at 0 to enable direct access to variant in Context.\r\n    // Max must be last and unused.\r\n    enum class Data : size_t\r\n    {\r\n        Source,\r\n        SearchRequest, // Only set for multiple installs\r\n        SearchResult,\r\n        SourceList,\r\n        Package,\r\n        Manifest,\r\n        PackageVersion,\r\n        Installer,\r\n        DownloadHashInfo,\r\n        InstallerPath,\r\n        LogPath,\r\n        InstallerArgs,\r\n        OperationReturnCode,\r\n        CompletionData,\r\n        InstalledPackageVersion,\r\n        UninstallString,\r\n        PackageFamilyNames,\r\n        ProductCodes,\r\n        // On export: A collection of packages to be exported to a file\r\n        // On import: A collection of packages read from a file\r\n        PackageCollection,\r\n        // When installing multiple packages at once (upgrade all, import, install with multiple args, dependencies):\r\n        // A collection of sub-contexts, each of which handles the installation of a single package.\r\n        PackageSubContexts,\r\n        // On import: Sources for the imported packages\r\n        Sources,\r\n        ARPCorrelationData,\r\n        CorrelatedAppsAndFeaturesEntries,\r\n        Dependencies,\r\n        DependencySource,\r\n        AllowedArchitectures,\r\n        AllowUnknownScope,\r\n        PortableInstaller,\r\n        PinningData,\r\n        Pins,\r\n        ConfigurationContext,\r\n        DownloadDirectory,\r\n        ModifyPath,\r\n        RepairString,\r\n        MsixDigests,\r\n        InstallerDownloadAuthenticators,\r\n        Max\r\n    };\r\n\r\n    struct Context;\r\n\r\n    namespace details\r\n    {\r\n        template <Data D>\r\n        struct DataMapping\r\n        {\r\n            // value_t type specifies the type of this data\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::Source>\r\n        {\r\n            using value_t = Repository::Source;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::SearchRequest>\r\n        {\r\n            using value_t = Repository::SearchRequest;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::SearchResult>\r\n        {\r\n            using value_t = Repository::SearchResult;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::SourceList>\r\n        {\r\n            using value_t = std::vector<Repository::SourceDetails>;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::Package>\r\n        {\r\n            using value_t = std::shared_ptr<Repository::ICompositePackage>;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::Manifest>\r\n        {\r\n            using value_t = Manifest::Manifest;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::PackageVersion>\r\n        {\r\n            using value_t = std::shared_ptr<Repository::IPackageVersion>;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::Installer>\r\n        {\r\n            using value_t = std::optional<Manifest::ManifestInstaller>;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::DownloadHashInfo>\r\n        {\r\n            using value_t = std::pair<std::vector<uint8_t>, Utility::DownloadResult>;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::InstallerPath>\r\n        {\r\n            using value_t = std::filesystem::path;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::LogPath>\r\n        {\r\n            using value_t = std::filesystem::path;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::InstallerArgs>\r\n        {\r\n            using value_t = std::string;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::OperationReturnCode>\r\n        {\r\n            using value_t = DWORD;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::CompletionData>\r\n        {\r\n            using value_t = CLI::CompletionData;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::InstalledPackageVersion>\r\n        {\r\n            using value_t = std::shared_ptr<Repository::IPackageVersion>;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::UninstallString>\r\n        {\r\n            using value_t = std::string;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::PackageFamilyNames>\r\n        {\r\n            using value_t = std::vector<Utility::LocIndString>;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::ProductCodes>\r\n        {\r\n            using value_t = std::vector<Utility::LocIndString>;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::PackageCollection>\r\n        {\r\n            using value_t = CLI::PackageCollection;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::PackageSubContexts>\r\n        {\r\n            using value_t = std::vector<std::unique_ptr<Context>>;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::Sources>\r\n        {\r\n            using value_t = std::vector<Repository::Source>;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::ARPCorrelationData>\r\n        {\r\n            using value_t = Repository::Correlation::ARPCorrelationData;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::CorrelatedAppsAndFeaturesEntries>\r\n        {\r\n            using value_t = std::vector<Manifest::AppsAndFeaturesEntry>;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::Dependencies>\r\n        {\r\n            using value_t = Manifest::DependencyList;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::DependencySource>\r\n        {\r\n            using value_t = Repository::Source;\r\n        };\r\n        \r\n        template <>\r\n        struct DataMapping<Data::AllowedArchitectures>\r\n        {\r\n            using value_t = std::vector<Utility::Architecture>;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::AllowUnknownScope>\r\n        {\r\n            using value_t = bool;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::PortableInstaller>\r\n        {\r\n            using value_t = CLI::Portable::PortableInstaller;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::PinningData>\r\n        {\r\n            using value_t = Pinning::PinningData;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::Pins>\r\n        {\r\n            using value_t = std::vector<Pinning::Pin>;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::ConfigurationContext>\r\n        {\r\n            using value_t = ConfigurationContext;\r\n        };\r\n\r\n        template <>\r\n        struct DataMapping<Data::DownloadDirectory>\r\n        {\r\n            using value_t = std::filesystem::path;\r\n        };\r\n\r\n        template<>\r\n        struct DataMapping<Data::ModifyPath>\r\n        {\r\n            using value_t = std::string;\r\n        };\r\n\r\n        template<>\r\n        struct DataMapping<Data::RepairString>\r\n        {\r\n            using value_t = std::string;\r\n        };\r\n\r\n        template<>\r\n        struct DataMapping<Data::MsixDigests>\r\n        {\r\n            // The pair is { URL, Digest }\r\n            using value_t = std::vector<std::pair<std::string, std::wstring>>;\r\n        };\r\n\r\n        template<>\r\n        struct DataMapping<Data::InstallerDownloadAuthenticators>\r\n        {\r\n            // The authenticator map shared with sub contexts\r\n            using value_t = std::shared_ptr<std::map<Authentication::AuthenticationInfo, Authentication::Authenticator>>;\r\n        };\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/ExecutionProgress.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ExecutionProgress.h\"\r\n#include \"VTSupport.h\"\r\n#include \"AppInstallerRuntime.h\"\r\n#include \"Sixel.h\"\r\n\r\nusing namespace AppInstaller::Settings;\r\nusing namespace AppInstaller::CLI::VirtualTerminal;\r\nusing namespace std::string_view_literals;\r\n\r\nnamespace AppInstaller::CLI::Execution\r\n{\r\n    namespace\r\n    {\r\n        static constexpr size_t s_ProgressBarCellWidth = 30;\r\n\r\n        struct BytesFormatData\r\n        {\r\n            uint64_t PowerOfTwo;\r\n            std::string_view Name;\r\n        };\r\n\r\n        BytesFormatData s_bytesFormatData[] =\r\n        {\r\n            // Multi-terabyte installers should be fairly rare for the foreseeable future...\r\n            { 40, \"TB\"sv },\r\n            { 30, \"GB\"sv },\r\n            { 20, \"MB\"sv },\r\n            { 10, \"KB\"sv },\r\n            { 0, \"B\"sv },\r\n        };\r\n\r\n        const BytesFormatData& GetFormatForSize(uint64_t bytes)\r\n        {\r\n            for (const auto& format : s_bytesFormatData)\r\n            {\r\n                if (bytes > (1ull << format.PowerOfTwo))\r\n                {\r\n                    return format;\r\n                }\r\n            }\r\n\r\n            // Just to make the compiler happy, return the last in the list if we get here.\r\n            return s_bytesFormatData[ARRAYSIZE(s_bytesFormatData) - 1];\r\n        }\r\n\r\n        void OutputBytes(BaseStream& out, uint64_t byteCount)\r\n        {\r\n            const BytesFormatData& bfd = GetFormatForSize(byteCount);\r\n\r\n            uint64_t integralAmount = byteCount >> bfd.PowerOfTwo;\r\n            uint64_t remainder = byteCount & ((1ull << bfd.PowerOfTwo) - 1);\r\n            size_t remainderDigits = 0;\r\n\r\n            if (integralAmount < 10)\r\n            {\r\n                remainder *= 100;\r\n                remainderDigits = 2;\r\n            }\r\n            else if (integralAmount < 100)\r\n            {\r\n                remainder *= 10;\r\n                remainderDigits = 1;\r\n            }\r\n            else if (integralAmount < 1000)\r\n            {\r\n                // Put an extra space to ensure a consistent 4 chars per numeric output\r\n                out << ' ';\r\n            }\r\n\r\n            out << integralAmount;\r\n\r\n            if (remainderDigits)\r\n            {\r\n                remainder = remainder >> bfd.PowerOfTwo;\r\n                out << '.' << std::setw(remainderDigits) << std::setfill('0') << remainder;\r\n            }\r\n\r\n            out << ' ' << bfd.Name;\r\n        }\r\n\r\n        void SetColor(BaseStream& out, const TextFormat::Color& color, bool foregroundOnly)\r\n        {\r\n            out << TextFormat::Foreground::Extended(color);\r\n\r\n            if (!foregroundOnly)\r\n            {\r\n                constexpr uint8_t divisor = 3;\r\n\r\n                auto reduced = color;\r\n                reduced.R /= divisor;\r\n                reduced.G /= divisor;\r\n                reduced.B /= divisor;\r\n\r\n                out << TextFormat::Background::Extended(reduced);\r\n            }\r\n        }\r\n\r\n        void SetRainbowColor(BaseStream& out, size_t i, size_t max, bool foregroundOnly)\r\n        {\r\n            TextFormat::Color rainbow[] =\r\n            {\r\n                { 0xff, 0x00, 0x00 },\r\n                { 0xff, 0x77, 0x00 },\r\n                { 0xff, 0xdd, 0x00 },\r\n                { 0x00, 0xff, 0x00 },\r\n                { 0x00, 0x00, 0xff },\r\n                { 0x8a, 0x2b, 0xe2 },\r\n                { 0xc7, 0x7d, 0xf3 },\r\n            };\r\n\r\n            double target = (static_cast<double>(i) / (max - 1)) * (ARRAYSIZE(rainbow) - 1);\r\n            size_t lower = static_cast<size_t>(std::floor(target));\r\n            const auto& lowerVal = rainbow[lower];\r\n            TextFormat::Color result;\r\n\r\n            if (lower == (ARRAYSIZE(rainbow) - 1))\r\n            {\r\n                result = lowerVal;\r\n            }\r\n            else\r\n            {\r\n                double upperContribution = target - lower;\r\n\r\n#define AICLI_AVERAGE(v) static_cast<uint8_t>(((lowerVal.v * (1.0 - upperContribution)) + (rainbow[lower + 1].v * upperContribution)))\r\n                result = { AICLI_AVERAGE(R), AICLI_AVERAGE(G), AICLI_AVERAGE(B) };\r\n            }\r\n\r\n            SetColor(out, result, foregroundOnly);\r\n        }\r\n    }\r\n\r\n    // Shared functionality for progress visualizers.\r\n    struct ProgressVisualizerBase\r\n    {\r\n        ProgressVisualizerBase(BaseStream& stream, bool enableVT) :\r\n            m_out(stream), m_enableVT(enableVT) {}\r\n\r\n        void SetMessage(std::string_view message)\r\n        {\r\n            std::atomic_store(&m_message, std::make_shared<Utility::NormalizedString>(message));\r\n        }\r\n\r\n        std::shared_ptr<Utility::NormalizedString> Message()\r\n        {\r\n            return std::atomic_load(&m_message);\r\n        }\r\n\r\n    protected:\r\n        BaseStream& m_out;\r\n\r\n        bool VT_Enabled() const { return m_enableVT; }\r\n\r\n        void ClearLine()\r\n        {\r\n            if (VT_Enabled())\r\n            {\r\n                m_out << TextModification::EraseLineEntirely << '\\r';\r\n            }\r\n            else\r\n            {\r\n                m_out << '\\r' << std::string(GetConsoleWidth(), ' ') << '\\r';\r\n            }\r\n        }\r\n\r\n    private:\r\n        bool m_enableVT = false;\r\n        std::shared_ptr<Utility::NormalizedString> m_message;\r\n    };\r\n\r\n    // Shared functionality for progress visualizers.\r\n    struct CharacterProgressVisualizerBase : public ProgressVisualizerBase\r\n    {\r\n        CharacterProgressVisualizerBase(BaseStream& stream, bool enableVT, VisualStyle style) :\r\n            ProgressVisualizerBase(stream, enableVT && style != AppInstaller::Settings::VisualStyle::NoVT), m_style(style) {}\r\n\r\n    protected:\r\n        Settings::VisualStyle m_style = AppInstaller::Settings::VisualStyle::Accent;\r\n\r\n        // Applies the selected visual style.\r\n        void ApplyStyle(size_t i, size_t max, bool foregroundOnly)\r\n        {\r\n            if (!VT_Enabled())\r\n            {\r\n                // Either no style set or VT disabled\r\n                return;\r\n            }\r\n            switch (m_style)\r\n            {\r\n            case VisualStyle::Retro:\r\n                m_out << TextFormat::Default;\r\n                break;\r\n            case VisualStyle::Accent:\r\n                SetColor(m_out, TextFormat::Color::GetAccentColor(), foregroundOnly);\r\n                break;\r\n            case VisualStyle::Rainbow:\r\n                SetRainbowColor(m_out, i, max, foregroundOnly);\r\n                break;\r\n            default:\r\n                LOG_HR(E_UNEXPECTED);\r\n            }\r\n        }\r\n    };\r\n\r\n    // Displays an indefinite spinner via a character.\r\n    struct CharacterIndefiniteSpinner : public CharacterProgressVisualizerBase, public IIndefiniteSpinner\r\n    {\r\n        CharacterIndefiniteSpinner(BaseStream& stream, bool enableVT, VisualStyle style) :\r\n            CharacterProgressVisualizerBase(stream, enableVT, style) {}\r\n\r\n        void ShowSpinner() override\r\n        {\r\n            if (!m_spinnerJob.valid() && !m_spinnerRunning && !m_canceled)\r\n            {\r\n                m_spinnerRunning = true;\r\n                m_spinnerJob = std::async(std::launch::async, &CharacterIndefiniteSpinner::ShowSpinnerInternal, this);\r\n            }\r\n        }\r\n\r\n        void StopSpinner() override\r\n        {\r\n            if (!m_canceled && m_spinnerJob.valid() && m_spinnerRunning)\r\n            {\r\n                m_canceled = true;\r\n                m_spinnerJob.get();\r\n            }\r\n        }\r\n\r\n        void SetMessage(std::string_view message) override\r\n        {\r\n            ProgressVisualizerBase::SetMessage(message);\r\n        }\r\n\r\n        std::shared_ptr<Utility::NormalizedString> Message() override\r\n        {\r\n            return ProgressVisualizerBase::Message();\r\n        }\r\n\r\n    private:\r\n        std::atomic<bool> m_canceled = false;\r\n        std::atomic<bool> m_spinnerRunning = false;\r\n        std::future<void> m_spinnerJob;\r\n\r\n        void ShowSpinnerInternal()\r\n        {\r\n            char spinnerChars[] = { '-', '\\\\', '|', '/' };\r\n\r\n            // First wait for a small amount of time to enable a fast task to skip\r\n            // showing anything, or a progress task to skip straight to progress.\r\n            Sleep(100);\r\n\r\n            if (!m_canceled)\r\n            {\r\n                if (VT_Enabled())\r\n                {\r\n                    // Additional VT-based progress reporting, for terminals that support it\r\n                    m_out << Progress::Construct(Progress::State::Indeterminate);\r\n                }\r\n\r\n                // Indent two spaces for the spinner, but three here so that we can overwrite it in the loop.\r\n                std::string_view indent = \"   \";\r\n                std::shared_ptr<Utility::NormalizedString> message = ProgressVisualizerBase::Message();\r\n                size_t messageLength = message ? Utility::UTF8ColumnWidth(*message) : 0;\r\n\r\n                for (size_t i = 0; !m_canceled; ++i)\r\n                {\r\n                    constexpr size_t repetitionCount = 20;\r\n                    ApplyStyle(i % repetitionCount, repetitionCount, true);\r\n                    m_out << '\\r' << indent << spinnerChars[i % ARRAYSIZE(spinnerChars)];\r\n                    m_out.RestoreDefault();\r\n\r\n                    std::shared_ptr<Utility::NormalizedString> newMessage = ProgressVisualizerBase::Message();\r\n                    std::string eraser;\r\n                    if (newMessage)\r\n                    {\r\n                        size_t newLength = Utility::UTF8ColumnWidth(*newMessage);\r\n\r\n                        if (newLength < messageLength)\r\n                        {\r\n                            eraser = std::string(messageLength - newLength, ' ');\r\n                        }\r\n\r\n                        message = newMessage;\r\n                        messageLength = newLength;\r\n                    }\r\n\r\n                    m_out << ' ' << (message ? *message : std::string{}) << eraser << std::flush;\r\n                    Sleep(250);\r\n                }\r\n\r\n                ClearLine();\r\n\r\n                if (VT_Enabled())\r\n                {\r\n                    m_out << Progress::Construct(Progress::State::None);\r\n                }\r\n            }\r\n\r\n            m_canceled = false;\r\n            m_spinnerRunning = false;\r\n        }\r\n    };\r\n\r\n    // Displays progress via character output.\r\n    class CharacterProgressBar : public CharacterProgressVisualizerBase, public IProgressBar\r\n    {\r\n    public:\r\n        CharacterProgressBar(BaseStream& stream, bool enableVT, VisualStyle style) :\r\n            CharacterProgressVisualizerBase(stream, enableVT, style) {}\r\n\r\n        void ShowProgress(uint64_t current, uint64_t maximum, ProgressType type) override\r\n        {\r\n            if (current < m_lastCurrent)\r\n            {\r\n                ClearLine();\r\n            }\r\n\r\n            // TODO: Progress bar does not currently use message\r\n            if (VT_Enabled())\r\n            {\r\n                ShowProgressWithVT(current, maximum, type);\r\n            }\r\n            else\r\n            {\r\n                ShowProgressNoVT(current, maximum, type);\r\n            }\r\n\r\n            m_lastCurrent = current;\r\n            m_isVisible = true;\r\n        }\r\n\r\n        void EndProgress(bool hideProgressWhenDone) override\r\n        {\r\n            if (m_isVisible)\r\n            {\r\n                if (hideProgressWhenDone)\r\n                {\r\n                    ClearLine();\r\n                }\r\n                else\r\n                {\r\n                    m_out << std::endl;\r\n                }\r\n\r\n                if (VT_Enabled())\r\n                {\r\n                    // We always clear the VT-based progress bar, even if hideProgressWhenDone is false\r\n                    // since it would be confusing for users if progress continues to be shown after winget exits\r\n                    // (it is typically not automatically cleared by terminals on process exit)\r\n                    m_out << Progress::Construct(Progress::State::None);\r\n                }\r\n\r\n                m_isVisible = false;\r\n            }\r\n        }\r\n\r\n    private:\r\n        std::atomic<bool> m_isVisible = false;\r\n        uint64_t m_lastCurrent = 0;\r\n\r\n        void ShowProgressNoVT(uint64_t current, uint64_t maximum, ProgressType type)\r\n        {\r\n            m_out << \"\\r  \";\r\n\r\n            if (maximum)\r\n            {\r\n                const char* const blockOn = u8\"\\x2588\";\r\n                const char* const blockOff = u8\"\\x2592\";\r\n                constexpr size_t blockWidth = 30;\r\n\r\n                double percentage = static_cast<double>(current) / maximum;\r\n                size_t blocksOn = static_cast<size_t>(std::floor(percentage * blockWidth));\r\n\r\n                for (size_t i = 0; i < blocksOn; ++i)\r\n                {\r\n                    m_out << blockOn;\r\n                }\r\n\r\n                for (size_t i = 0; i < blockWidth - blocksOn; ++i)\r\n                {\r\n                    m_out << blockOff;\r\n                }\r\n\r\n                m_out << \"  \";\r\n\r\n                switch (type)\r\n                {\r\n                case AppInstaller::ProgressType::Bytes:\r\n                    OutputBytes(m_out, current);\r\n                    m_out << \" / \";\r\n                    OutputBytes(m_out, maximum);\r\n                    break;\r\n                case AppInstaller::ProgressType::Percent:\r\n                default:\r\n                    m_out << static_cast<int>(percentage * 100) << '%';\r\n                    break;\r\n                }\r\n            }\r\n            else\r\n            {\r\n                switch (type)\r\n                {\r\n                case AppInstaller::ProgressType::Bytes:\r\n                    OutputBytes(m_out, current);\r\n                    break;\r\n                case AppInstaller::ProgressType::Percent:\r\n                    m_out << current << '%';\r\n                    break;\r\n                default:\r\n                    m_out << current << \" unknowns\";\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n\r\n        void ShowProgressWithVT(uint64_t current, uint64_t maximum, ProgressType type)\r\n        {\r\n            m_out << TextFormat::Default;\r\n\r\n            m_out << \"\\r  \";\r\n\r\n            if (maximum)\r\n            {\r\n                const char* const blocks[] =\r\n                {\r\n                    u8\" \",      // block off\r\n                    u8\"\\x258F\", // block 1/8\r\n                    u8\"\\x258E\", // block 2/8\r\n                    u8\"\\x258D\", // block 3/8\r\n                    u8\"\\x258C\", // block 4/8\r\n                    u8\"\\x258B\", // block 5/8\r\n                    u8\"\\x258A\", // block 6/8\r\n                    u8\"\\x2589\", // block 7/8\r\n                    u8\"\\x2588\"  // block on\r\n                };\r\n                const char* const blockOn = blocks[8];\r\n                const char* const blockOff = blocks[0];\r\n                constexpr size_t blockWidth = s_ProgressBarCellWidth;\r\n\r\n                double percentage = static_cast<double>(current) / maximum;\r\n                size_t blocksOn = static_cast<size_t>(std::floor(percentage * blockWidth));\r\n                size_t partialBlockIndex = static_cast<size_t>((percentage * blockWidth - blocksOn) * 8);\r\n                TextFormat::Color accent = TextFormat::Color::GetAccentColor();\r\n\r\n                for (size_t i = 0; i < blockWidth; ++i)\r\n                {\r\n                    ApplyStyle(i, blockWidth, false);\r\n\r\n                    if (i < blocksOn)\r\n                    {\r\n                        m_out << blockOn;\r\n                    }\r\n                    else if (i == blocksOn)\r\n                    {\r\n                        m_out << blocks[partialBlockIndex];\r\n                    }\r\n                    else\r\n                    {\r\n                        m_out << blockOff;\r\n                    }\r\n                }\r\n\r\n                m_out << TextFormat::Default;\r\n\r\n                m_out << \"  \";\r\n\r\n                switch (type)\r\n                {\r\n                case AppInstaller::ProgressType::Bytes:\r\n                    OutputBytes(m_out, current);\r\n                    m_out << \" / \";\r\n                    OutputBytes(m_out, maximum);\r\n                    break;\r\n                case AppInstaller::ProgressType::Percent:\r\n                default:\r\n                    m_out << static_cast<int>(percentage * 100) << '%';\r\n                    break;\r\n                }\r\n\r\n                // Additional VT-based progress reporting, for terminals that support it\r\n                m_out << Progress::Construct(Progress::State::Normal, static_cast<int>(percentage * 100));\r\n            }\r\n            else\r\n            {\r\n                switch (type)\r\n                {\r\n                case AppInstaller::ProgressType::Bytes:\r\n                    OutputBytes(m_out, current);\r\n                    break;\r\n                case AppInstaller::ProgressType::Percent:\r\n                    m_out << current << '%';\r\n                    break;\r\n                default:\r\n                    m_out << current << \" unknowns\";\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n    };\r\n\r\n    // Displays an indefinite spinner via a sixel.\r\n    struct SixelIndefiniteSpinner : public ProgressVisualizerBase, public IIndefiniteSpinner\r\n    {\r\n        SixelIndefiniteSpinner(BaseStream& stream, bool enableVT) :\r\n            ProgressVisualizerBase(stream, enableVT)\r\n        {\r\n            Sixel::RenderControls& renderControls = m_compositor.Controls();\r\n            renderControls.RenderSizeInCells(2, 1);\r\n\r\n            // Create palette from full image\r\n            std::filesystem::path imageAssetsRoot = Runtime::GetPathTo(Runtime::PathName::ImageAssets);\r\n            THROW_WIN32_IF(ERROR_FILE_NOT_FOUND, imageAssetsRoot.empty());\r\n\r\n            // This image matches the target pixel size. If changing the target size, choose the most appropriate image.\r\n            Sixel::ImageSource wingetIcon{ imageAssetsRoot / \"AppList.targetsize-20.png\" };\r\n            wingetIcon.Resize(renderControls);\r\n            Sixel::Palette palette = wingetIcon.CreatePalette(renderControls);\r\n\r\n            m_folder = Sixel::ImageSource{ imageAssetsRoot / \"progress-sixel/folders_only.png\" };\r\n            m_arrow = Sixel::ImageSource{ imageAssetsRoot / \"progress-sixel/arrow_only.png\" };\r\n\r\n            m_folder.Resize(renderControls);\r\n            m_folder.ApplyPalette(palette);\r\n\r\n            Sixel::RenderControls arrowControls = renderControls;\r\n            arrowControls.InterpolationMode = Sixel::InterpolationMode::Linear;\r\n            m_arrow.Resize(arrowControls);\r\n            m_arrow.ApplyPalette(palette);\r\n\r\n            m_compositor.Palette(std::move(palette));\r\n            m_compositor.AddView(m_arrow.Copy());\r\n            m_compositor.AddView(m_folder.Copy());\r\n        }\r\n\r\n        void ShowSpinner() override\r\n        {\r\n            if (!m_spinnerJob.valid() && !m_spinnerRunning && !m_canceled)\r\n            {\r\n                m_spinnerRunning = true;\r\n                m_spinnerJob = std::async(std::launch::async, &SixelIndefiniteSpinner::ShowSpinnerInternal, this);\r\n            }\r\n        }\r\n\r\n        void StopSpinner() override\r\n        {\r\n            if (!m_canceled && m_spinnerJob.valid() && m_spinnerRunning)\r\n            {\r\n                m_canceled = true;\r\n                m_spinnerJob.get();\r\n            }\r\n        }\r\n\r\n        void SetMessage(std::string_view message) override\r\n        {\r\n            ProgressVisualizerBase::SetMessage(message);\r\n        }\r\n\r\n        std::shared_ptr<Utility::NormalizedString> Message() override\r\n        {\r\n            return ProgressVisualizerBase::Message();\r\n        }\r\n\r\n    private:\r\n        std::atomic<bool> m_canceled = false;\r\n        std::atomic<bool> m_spinnerRunning = false;\r\n        std::future<void> m_spinnerJob;\r\n        Sixel::ImageSource m_folder;\r\n        Sixel::ImageSource m_arrow;\r\n        Sixel::Compositor m_compositor;\r\n\r\n        void ShowSpinnerInternal()\r\n        {\r\n            // First wait for a small amount of time to enable a fast task to skip\r\n            // showing anything, or a progress task to skip straight to progress.\r\n            Sleep(100);\r\n\r\n            if (!m_canceled)\r\n            {\r\n                // Additional VT-based progress reporting, for terminals that support it\r\n                m_out << Progress::Construct(Progress::State::Indeterminate);\r\n\r\n                // Indent two spaces for the spinner, but three here so that we can overwrite it in the loop.\r\n                std::string_view indent = \"  \";\r\n                std::shared_ptr<Utility::NormalizedString> message = ProgressVisualizerBase::Message();\r\n                size_t messageLength = message ? Utility::UTF8ColumnWidth(*message) : 0;\r\n\r\n                UINT imageHeight = m_compositor.Controls().PixelHeight;\r\n\r\n                for (size_t i = 0; !m_canceled; ++i)\r\n                {\r\n                    m_out << '\\r' << indent;\r\n\r\n                    // Move arrow down one pixel each time\r\n                    m_compositor[0].Translate(0, i % imageHeight, true);\r\n                    m_compositor.RenderTo(m_out);\r\n\r\n                    message = ProgressVisualizerBase::Message();\r\n                    size_t newLength = (message ? Utility::UTF8ColumnWidth(*message) : 0);\r\n\r\n                    std::string eraser;\r\n                    if (newLength < messageLength)\r\n                    {\r\n                        eraser = std::string(messageLength - newLength, ' ');\r\n                    }\r\n\r\n                    messageLength = newLength;\r\n\r\n                    m_out << VirtualTerminal::Cursor::Position::Forward(3) << (message ? *message : std::string{}) << eraser << std::flush;\r\n                    Sleep(100);\r\n                }\r\n\r\n                ClearLine();\r\n\r\n                m_out << Progress::Construct(Progress::State::None);\r\n            }\r\n\r\n            m_canceled = false;\r\n            m_spinnerRunning = false;\r\n        }\r\n    };\r\n\r\n    // Displays progress with a sixel image.\r\n    class SixelProgressBar : public ProgressVisualizerBase, public IProgressBar\r\n    {\r\n    public:\r\n        SixelProgressBar(BaseStream& stream, bool enableVT) :\r\n            ProgressVisualizerBase(stream, enableVT)\r\n        {\r\n            static constexpr UINT s_colorsForBelt = 20;\r\n\r\n            Sixel::RenderControls imageRenderControls;\r\n            imageRenderControls.RenderSizeInCells(2, 1);\r\n\r\n            // This image matches the target pixel size. If changing the target size, choose the most appropriate image.\r\n            std::filesystem::path imageAssetsRoot = Runtime::GetPathTo(Runtime::PathName::ImageAssets);\r\n            THROW_WIN32_IF(ERROR_FILE_NOT_FOUND, imageAssetsRoot.empty());\r\n\r\n            m_icon = Sixel::ImageSource{ imageAssetsRoot / \"AppList.targetsize-20.png\" };\r\n            m_icon.Resize(imageRenderControls);\r\n            imageRenderControls.ColorCount = Sixel::Palette::MaximumColorCount - s_colorsForBelt;\r\n            Sixel::Palette iconPalette = m_icon.CreatePalette(imageRenderControls);\r\n\r\n            // TODO: Move to real location\r\n            m_belt = Sixel::ImageSource{ imageAssetsRoot / \"progress-sixel/conveyor.png\" };\r\n            m_belt.Resize(imageRenderControls);\r\n            imageRenderControls.ColorCount = s_colorsForBelt;\r\n            imageRenderControls.InterpolationMode = Sixel::InterpolationMode::Linear;\r\n            Sixel::Palette beltPalette = m_belt.CreatePalette(imageRenderControls);\r\n\r\n            Sixel::Palette combinedPalette{ iconPalette, beltPalette };\r\n\r\n            m_icon.ApplyPalette(combinedPalette);\r\n            m_belt.ApplyPalette(combinedPalette);\r\n\r\n            m_compositor.Palette(std::move(combinedPalette));\r\n            m_compositor.AddView(m_icon.Copy());\r\n            m_compositor.AddView(m_belt.Copy());\r\n            m_compositor.Controls().TransparencyEnabled = false;\r\n            m_compositor.Controls().RenderSizeInCells(s_ProgressBarCellWidth, 1);\r\n        }\r\n\r\n        void ShowProgress(uint64_t current, uint64_t maximum, ProgressType type) override\r\n        {\r\n            if (current < m_lastCurrent)\r\n            {\r\n                ClearLine();\r\n            }\r\n\r\n            m_out << TextFormat::Default;\r\n\r\n            m_out << \"\\r  \";\r\n\r\n            if (maximum)\r\n            {\r\n\r\n                double percentage = static_cast<double>(current) / maximum;\r\n\r\n                // Translate icon so that its leading edge is the progress line\r\n                INT translation = static_cast<INT>((percentage * m_compositor.Controls().PixelWidth) - m_compositor[0].Width());\r\n\r\n                m_compositor[0].Translate(translation, 0, false);\r\n                m_compositor[1].Translate(translation, 0, true);\r\n                m_compositor.RenderTo(m_out);\r\n\r\n                m_out << VirtualTerminal::Cursor::Position::Forward(s_ProgressBarCellWidth + 2);\r\n\r\n                switch (type)\r\n                {\r\n                case AppInstaller::ProgressType::Bytes:\r\n                    OutputBytes(m_out, current);\r\n                    m_out << \" / \";\r\n                    OutputBytes(m_out, maximum);\r\n                    break;\r\n                case AppInstaller::ProgressType::Percent:\r\n                default:\r\n                    m_out << static_cast<int>(percentage * 100) << '%';\r\n                    break;\r\n                }\r\n\r\n                // Additional VT-based progress reporting, for terminals that support it\r\n                m_out << Progress::Construct(Progress::State::Normal, static_cast<int>(percentage * 100));\r\n            }\r\n            else\r\n            {\r\n                switch (type)\r\n                {\r\n                case AppInstaller::ProgressType::Bytes:\r\n                    OutputBytes(m_out, current);\r\n                    break;\r\n                case AppInstaller::ProgressType::Percent:\r\n                    m_out << current << '%';\r\n                    break;\r\n                default:\r\n                    m_out << current << \" unknowns\";\r\n                    break;\r\n                }\r\n            }\r\n\r\n            m_lastCurrent = current;\r\n            m_isVisible = true;\r\n        }\r\n\r\n        void EndProgress(bool hideProgressWhenDone) override\r\n        {\r\n            if (m_isVisible)\r\n            {\r\n                if (hideProgressWhenDone)\r\n                {\r\n                    ClearLine();\r\n                }\r\n                else\r\n                {\r\n                    m_out << std::endl;\r\n                }\r\n\r\n                if (VT_Enabled())\r\n                {\r\n                    // We always clear the VT-based progress bar, even if hideProgressWhenDone is false\r\n                    // since it would be confusing for users if progress continues to be shown after winget exits\r\n                    // (it is typically not automatically cleared by terminals on process exit)\r\n                    m_out << Progress::Construct(Progress::State::None);\r\n                }\r\n\r\n                m_isVisible = false;\r\n            }\r\n        }\r\n\r\n    private:\r\n        std::atomic<bool> m_isVisible = false;\r\n        uint64_t m_lastCurrent = 0;\r\n        Sixel::ImageSource m_icon;\r\n        Sixel::ImageSource m_belt;\r\n        Sixel::Compositor m_compositor;\r\n    };\r\n\r\n    std::unique_ptr<IIndefiniteSpinner> IIndefiniteSpinner::CreateForStyle(BaseStream& stream, bool enableVT, VisualStyle style, const std::function<bool()>& sixelSupported)\r\n    {\r\n        std::unique_ptr<IIndefiniteSpinner> result;\r\n\r\n        switch (style)\r\n        {\r\n        case VisualStyle::NoVT:\r\n        case VisualStyle::Retro:\r\n        case VisualStyle::Accent:\r\n        case VisualStyle::Rainbow:\r\n            result = std::make_unique<CharacterIndefiniteSpinner>(stream, enableVT, style);\r\n            break;\r\n        case VisualStyle::Sixel:\r\n            if (sixelSupported())\r\n            {\r\n                try\r\n                {\r\n                    result = std::make_unique<SixelIndefiniteSpinner>(stream, enableVT);\r\n                }\r\n                CATCH_LOG();\r\n            }\r\n\r\n            if (!result)\r\n            {\r\n                result = std::make_unique<CharacterIndefiniteSpinner>(stream, enableVT, VisualStyle::Accent);\r\n            }\r\n            break;\r\n        case VisualStyle::Disabled:\r\n            break;\r\n        default:\r\n            THROW_HR(E_NOTIMPL);\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::unique_ptr<IProgressBar> IProgressBar::CreateForStyle(BaseStream& stream, bool enableVT, VisualStyle style, const std::function<bool()>& sixelSupported)\r\n    {\r\n        std::unique_ptr<IProgressBar> result;\r\n\r\n        switch (style)\r\n        {\r\n        case VisualStyle::NoVT:\r\n        case VisualStyle::Retro:\r\n        case VisualStyle::Accent:\r\n        case VisualStyle::Rainbow:\r\n            result = std::make_unique<CharacterProgressBar>(stream, enableVT, style);\r\n            break;\r\n        case VisualStyle::Sixel:\r\n            if (sixelSupported())\r\n            {\r\n                try\r\n                {\r\n                    result = std::make_unique<SixelProgressBar>(stream, enableVT);\r\n                }\r\n                CATCH_LOG();\r\n            }\r\n\r\n            if (!result)\r\n            {\r\n                result = std::make_unique<CharacterProgressBar>(stream, enableVT, VisualStyle::Accent);\r\n            }\r\n            break;\r\n        case VisualStyle::Disabled:\r\n            break;\r\n        default:\r\n            THROW_HR(E_NOTIMPL);\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/ExecutionProgress.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ChannelStreams.h\"\r\n#include <AppInstallerProgress.h>\r\n#include <AppInstallerStrings.h>\r\n#include <winget/UserSettings.h>\r\n\r\n#include <functional>\r\n#include <memory>\r\n#include <string>\r\n#include <string_view>\r\n\r\nnamespace AppInstaller::CLI::Execution\r\n{\r\n    // Displays an indefinite spinner.\r\n    struct IIndefiniteSpinner\r\n    {\r\n        virtual ~IIndefiniteSpinner() = default;\r\n\r\n        // Set the message for the spinner.\r\n        virtual void SetMessage(std::string_view message) = 0;\r\n\r\n        // Get the current message for the spinner.\r\n        virtual std::shared_ptr<Utility::NormalizedString> Message() = 0;\r\n\r\n        // Show the indefinite spinner.\r\n        virtual void ShowSpinner() = 0;\r\n\r\n        // Stop showing the indefinite spinner.\r\n        virtual void StopSpinner() = 0;\r\n\r\n        // Creates an indefinite spinner for the given style.\r\n        static std::unique_ptr<IIndefiniteSpinner> CreateForStyle(BaseStream& stream, bool enableVT, AppInstaller::Settings::VisualStyle style, const std::function<bool()>& sixelSupported);\r\n    };\r\n\r\n    // Displays a progress bar.\r\n    struct IProgressBar\r\n    {\r\n        virtual ~IProgressBar() = default;\r\n\r\n        // Show progress with the given values.\r\n        virtual void ShowProgress(uint64_t current, uint64_t maximum, ProgressType type) = 0;\r\n\r\n        // Stop showing progress.\r\n        virtual void EndProgress(bool hideProgressWhenDone) = 0;\r\n\r\n        // Creates a progress bar for the given style.\r\n        static std::unique_ptr<IProgressBar> CreateForStyle(BaseStream& stream, bool enableVT, AppInstaller::Settings::VisualStyle style, const std::function<bool()>& sixelSupported);\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/ExecutionReporter.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ExecutionReporter.h\"\r\n#include <AppInstallerErrors.h>\r\n\r\n\r\nnamespace AppInstaller::CLI::Execution\r\n{\r\n    using namespace Settings;\r\n    using namespace VirtualTerminal;\r\n\r\n    const Sequence& HelpCommandEmphasis = TextFormat::Foreground::Bright;\r\n    const Sequence& HelpArgumentEmphasis = TextFormat::Foreground::Bright;\r\n    const Sequence& ManifestInfoEmphasis = TextFormat::Foreground::Bright;\r\n    const Sequence& SourceInfoEmphasis = TextFormat::Foreground::Bright;\r\n    const Sequence& NameEmphasis = TextFormat::Foreground::BrightCyan;\r\n    const Sequence& IdEmphasis = TextFormat::Foreground::BrightCyan;\r\n    const Sequence& UrlEmphasis = TextFormat::Foreground::BrightBlue;\r\n    const Sequence& PromptEmphasis = TextFormat::Foreground::Bright;\r\n    const Sequence& ConvertToUpgradeFlowEmphasis = TextFormat::Foreground::BrightYellow;\r\n    const Sequence& ConfigurationIntentEmphasis = TextFormat::Foreground::Bright;\r\n    const Sequence& ConfigurationUnitEmphasis = TextFormat::Foreground::BrightCyan;\r\n    const Sequence& AuthenticationEmphasis = TextFormat::Foreground::BrightYellow;\r\n\r\n    namespace\r\n    {\r\n        DWORD GetStdHandleType(DWORD stdHandle)\r\n        {\r\n            DWORD result = FILE_TYPE_UNKNOWN;\r\n\r\n            HANDLE handle = GetStdHandle(stdHandle);\r\n            if (handle != INVALID_HANDLE_VALUE && handle != NULL)\r\n            {\r\n                result = GetFileType(handle);\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n\r\n    Reporter::Reporter() :\r\n        Reporter(std::cout, std::cin)\r\n    {\r\n        m_outStreamFileType = GetStdHandleType(STD_OUTPUT_HANDLE);\r\n        m_inStreamFileType = GetStdHandleType(STD_INPUT_HANDLE);\r\n    }\r\n\r\n    Reporter::Reporter(std::ostream& outStream, std::istream& inStream) :\r\n        Reporter(std::make_shared<BaseStream>(outStream, true, ConsoleModeRestore::Instance().IsVTEnabled()), inStream)\r\n    {\r\n        SetProgressSink(this);\r\n    }\r\n\r\n    Reporter::Reporter(std::shared_ptr<BaseStream> outStream, std::istream& inStream) :\r\n        m_out(outStream),\r\n        m_in(inStream)\r\n    {\r\n        auto sixelSupported = [&]() { return SixelsSupported(); };\r\n        m_spinner = IIndefiniteSpinner::CreateForStyle(*m_out, ConsoleModeRestore::Instance().IsVTEnabled(), VisualStyle::Accent, sixelSupported);\r\n        m_progressBar = IProgressBar::CreateForStyle(*m_out, ConsoleModeRestore::Instance().IsVTEnabled(), VisualStyle::Accent, sixelSupported);\r\n\r\n        SetProgressSink(this);\r\n    }\r\n\r\n    Reporter::~Reporter()\r\n    {\r\n        this->CloseOutputStream();\r\n    }\r\n\r\n    Reporter::Reporter(const Reporter& other, clone_t) :\r\n        Reporter(other.m_out, other.m_in)\r\n    {\r\n        m_outStreamFileType = other.m_outStreamFileType;\r\n        m_inStreamFileType = other.m_inStreamFileType;\r\n\r\n        SetChannel(other.m_channel);\r\n\r\n        if (other.m_style.has_value())\r\n        {\r\n            SetStyle(*other.m_style);\r\n        }\r\n    }\r\n\r\n    std::optional<PrimaryDeviceAttributes> Reporter::GetPrimaryDeviceAttributes()\r\n    {\r\n        if (ConsoleModeRestore::Instance().IsVTEnabled())\r\n        {\r\n            return PrimaryDeviceAttributes{ m_out->Get(), m_in };\r\n        }\r\n        else\r\n        {\r\n            return std::nullopt;\r\n        }\r\n    }\r\n\r\n    OutputStream Reporter::GetOutputStream(Level level)\r\n    {\r\n        // If the level is not enabled, return a default stream which is disabled\r\n        if (WI_AreAllFlagsClear(m_enabledLevels, level))\r\n        {\r\n            return OutputStream(*m_out, false, false);\r\n        }\r\n\r\n        OutputStream result = GetBasicOutputStream();\r\n\r\n        switch (level)\r\n        {\r\n        case Level::Verbose:\r\n            result.AddFormat(TextFormat::Default);\r\n            break;\r\n        case Level::Info:\r\n            result.AddFormat(TextFormat::Default);\r\n            break;\r\n        case Level::Warning:\r\n            result.AddFormat(TextFormat::Foreground::BrightYellow);\r\n            break;\r\n        case Level::Error:\r\n            result.AddFormat(TextFormat::Foreground::BrightRed);\r\n            break;\r\n        default:\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    OutputStream Reporter::GetBasicOutputStream()\r\n    {\r\n        return { *m_out, m_channel == Channel::Output };\r\n    }\r\n\r\n    void Reporter::SetChannel(Channel channel)\r\n    {\r\n        m_channel = channel;\r\n\r\n        if (m_channel != Channel::Output)\r\n        {\r\n            // Disable progress for non-output channels\r\n            m_spinner.reset();\r\n            m_progressBar.reset();\r\n        }\r\n    }\r\n\r\n    void Reporter::SetStyle(VisualStyle style)\r\n    {\r\n        m_style = style;\r\n\r\n        if (m_channel == Channel::Output)\r\n        {\r\n            auto sixelSupported = [&]() { return SixelsSupported(); };\r\n            m_spinner = IIndefiniteSpinner::CreateForStyle(*m_out, ConsoleModeRestore::Instance().IsVTEnabled(), style, sixelSupported);\r\n            m_progressBar = IProgressBar::CreateForStyle(*m_out, ConsoleModeRestore::Instance().IsVTEnabled(), style, sixelSupported);\r\n        }\r\n\r\n        if (style == VisualStyle::NoVT)\r\n        {\r\n            m_out->SetVTEnabled(false);\r\n        }\r\n    }\r\n\r\n    std::istream& Reporter::RawInputStream()\r\n    {\r\n        return m_in;\r\n    }\r\n\r\n    bool Reporter::InputStreamIsInteractive() const\r\n    {\r\n        AICLI_LOG(CLI, Verbose, << \"Reporter::m_inStreamFileType is \" << m_inStreamFileType);\r\n        return m_inStreamFileType == FILE_TYPE_CHAR;\r\n    }\r\n\r\n    bool Reporter::PromptForBoolResponse(Resource::LocString message, Level level, bool resultIfDisabled)\r\n    {\r\n        auto out = GetOutputStream(level);\r\n\r\n        if (!out.IsEnabled())\r\n        {\r\n            return resultIfDisabled;\r\n        }\r\n\r\n        const std::vector<BoolPromptOption> options\r\n        {\r\n            BoolPromptOption{ Resource::String::PromptOptionYes, 'Y', true },\r\n            BoolPromptOption{ Resource::String::PromptOptionNo, 'N', false },\r\n        };\r\n\r\n        out << message << std::endl;\r\n\r\n        // Try prompting until we get a recognized option\r\n        for (;;)\r\n        {\r\n            // Output all options\r\n            for (size_t i = 0; i < options.size(); ++i)\r\n            {\r\n                out << PromptEmphasis << \"[\" + options[i].Hotkey.get() + \"] \" + options[i].Label.get();\r\n\r\n                if (i + 1 == options.size())\r\n                {\r\n                    out << PromptEmphasis << \": \";\r\n                }\r\n                else\r\n                {\r\n                    out << \"  \";\r\n                }\r\n            }\r\n\r\n            // Read the response\r\n            std::string response;\r\n            if (!std::getline(m_in, response))\r\n            {\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_PROMPT_INPUT_ERROR);\r\n            }\r\n\r\n            // Find the matching option ignoring whitespace\r\n            Utility::Trim(response);\r\n            for (const auto& option : options)\r\n            {\r\n                if (Utility::CaseInsensitiveEquals(response, option.Label) ||\r\n                    Utility::CaseInsensitiveEquals(response, option.Hotkey))\r\n                {\r\n                    return option.Value;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    void Reporter::PromptForEnter(Level level)\r\n    {\r\n        auto out = GetOutputStream(level);\r\n        if (!out.IsEnabled())\r\n        {\r\n            return;\r\n        }\r\n\r\n        out << std::endl << Resource::String::PressEnterToContinue << std::endl;\r\n        m_in.get();\r\n    }\r\n\r\n    std::filesystem::path Reporter::PromptForPath(Resource::LocString message, Level level, std::filesystem::path resultIfDisabled)\r\n    {\r\n        auto out = GetOutputStream(level);\r\n\r\n        if (!out.IsEnabled())\r\n        {\r\n            return resultIfDisabled;\r\n        }\r\n\r\n        // Try prompting until we get a valid answer\r\n        for (;;)\r\n        {\r\n            out << message << ' ';\r\n\r\n            // Read the response\r\n            std::string response;\r\n            if (!std::getline(m_in, response))\r\n            {\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_PROMPT_INPUT_ERROR);\r\n            }\r\n\r\n            // Validate the path\r\n            std::filesystem::path path{ response };\r\n            if (path.is_absolute())\r\n            {\r\n                return path;\r\n            }\r\n        }\r\n\r\n    }\r\n\r\n    void Reporter::ShowIndefiniteProgress(bool running)\r\n    {\r\n        if (m_spinner)\r\n        {\r\n            if (running)\r\n            {\r\n                m_spinner->ShowSpinner();\r\n            }\r\n            else\r\n            {\r\n                m_spinner->StopSpinner();\r\n            }\r\n        }\r\n    }\r\n\r\n    void Reporter::OnProgress(uint64_t current, uint64_t maximum, ProgressType type)\r\n    {\r\n        ShowIndefiniteProgress(false);\r\n        if (m_progressBar)\r\n        {\r\n            m_progressBar->ShowProgress(current, maximum, type);\r\n        }\r\n    }\r\n\r\n    void Reporter::SetProgressMessage(std::string_view message)\r\n    {\r\n        if (m_spinner)\r\n        {\r\n            m_spinner->SetMessage(message);\r\n        }\r\n    }\r\n\r\n    void Reporter::BeginProgress()\r\n    {\r\n        GetBasicOutputStream() << VirtualTerminal::Cursor::Visibility::DisableShow;\r\n        ShowIndefiniteProgress(true);\r\n    };\r\n\r\n    void Reporter::EndProgress(bool hideProgressWhenDone)\r\n    {\r\n        ShowIndefiniteProgress(false);\r\n        if (m_progressBar)\r\n        {\r\n            m_progressBar->EndProgress(hideProgressWhenDone);\r\n        }\r\n        SetProgressMessage({});\r\n        GetBasicOutputStream() << VirtualTerminal::Cursor::Visibility::EnableShow;\r\n    };\r\n\r\n    Reporter::AsyncProgressScope::AsyncProgressScope(Reporter& reporter, IProgressSink* sink, bool hideProgressWhenDone) :\r\n        m_reporter(reporter), m_callback(sink)\r\n    {\r\n        reporter.SetProgressCallback(&m_callback);\r\n        sink->BeginProgress();\r\n        m_hideProgressWhenDone = hideProgressWhenDone;\r\n    }\r\n\r\n    Reporter::AsyncProgressScope::~AsyncProgressScope()\r\n    {\r\n        m_reporter.get().SetProgressCallback(nullptr);\r\n        m_callback.GetSink()->EndProgress(m_hideProgressWhenDone);\r\n    }\r\n\r\n    ProgressCallback& Reporter::AsyncProgressScope::Callback()\r\n    {\r\n        return m_callback;\r\n    }\r\n\r\n    IProgressCallback* Reporter::AsyncProgressScope::operator->()\r\n    {\r\n        return &m_callback;\r\n    }\r\n\r\n    bool Reporter::AsyncProgressScope::HideProgressWhenDone() const\r\n    {\r\n        return m_hideProgressWhenDone;\r\n    }\r\n\r\n    void Reporter::AsyncProgressScope::HideProgressWhenDone(bool value)\r\n    {\r\n        m_hideProgressWhenDone.store(value);\r\n    }\r\n\r\n    std::unique_ptr<Reporter::AsyncProgressScope> Reporter::BeginAsyncProgress(bool hideProgressWhenDone)\r\n    {\r\n        return std::make_unique<AsyncProgressScope>(*this, m_progressSink.load(), hideProgressWhenDone);\r\n    }\r\n\r\n    void Reporter::SetProgressCallback(ProgressCallback* callback)\r\n    {\r\n        auto lock = m_progressCallbackLock.lock_exclusive();\r\n        // Attempting two progress operations at the same time; not supported.\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), m_progressCallback != nullptr && callback != nullptr);\r\n        m_progressCallback = callback;\r\n    }\r\n\r\n    void Reporter::CancelInProgressTask(bool force, CancelReason reason)\r\n    {\r\n        // TODO: Maybe ask the user if they really want to cancel?\r\n        UNREFERENCED_PARAMETER(force);\r\n        auto lock = m_progressCallbackLock.lock_shared();\r\n        ProgressCallback* callback = m_progressCallback.load();\r\n        if (callback)\r\n        {\r\n            if (!callback->IsCancelledBy(CancelReason::Any))\r\n            {\r\n                callback->SetProgressMessage(Resource::String::CancellingOperation());\r\n                callback->Cancel(reason);\r\n            }\r\n        }\r\n    }\r\n\r\n    void Reporter::CloseOutputStream(bool forceDisable)\r\n    {\r\n        if (forceDisable)\r\n        {\r\n            m_out->Disable();\r\n        }\r\n        m_out->RestoreDefault();\r\n    }\r\n\r\n    void Reporter::SetLevelMask(Level reporterLevel, bool setEnabled) {\r\n\r\n        if (setEnabled)\r\n        {\r\n            WI_SetAllFlags(m_enabledLevels, reporterLevel);\r\n        }\r\n        else\r\n        {\r\n            WI_ClearAllFlags(m_enabledLevels, reporterLevel);\r\n        }\r\n    }\r\n\r\n    bool Reporter::SixelsSupported()\r\n    {\r\n        auto attributes = GetPrimaryDeviceAttributes();\r\n        return (attributes ? attributes->Supports(PrimaryDeviceAttributes::Extension::Sixel) : false);\r\n    }\r\n\r\n    bool Reporter::SixelsEnabled()\r\n    {\r\n        return Settings::User().Get<Settings::Setting::EnableSixelDisplay>() && SixelsSupported();\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/ExecutionReporter.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ExecutionProgress.h\"\r\n#include \"ChannelStreams.h\"\r\n#include \"Resources.h\"\r\n#include \"VTSupport.h\"\r\n#include <AppInstallerProgress.h>\r\n#include <winget/LocIndependent.h>\r\n\r\n#include <wil/resource.h>\r\n\r\n#include <atomic>\r\n#include <iomanip>\r\n#include <istream>\r\n#include <memory>\r\n#include <optional>\r\n#include <ostream>\r\n#include <string>\r\n\r\n\r\nnamespace AppInstaller::CLI::Execution\r\n{\r\n#define WINGET_OSTREAM_FORMAT_HRESULT(hr) \"0x\" << Logging::SetHRFormat << hr\r\n\r\n    // One of the options available to the users when prompting for something.\r\n    struct BoolPromptOption\r\n    {\r\n        BoolPromptOption(Resource::StringId labelId, char hotkey, bool value)\r\n            : Label(labelId), Hotkey(std::string(1, hotkey)), Value(value) {}\r\n\r\n        Utility::LocIndString Hotkey;\r\n        Resource::LocString Label;\r\n\r\n        // Value associated with this option.\r\n        bool Value;\r\n    };\r\n\r\n    // Reporter should be the central place to show workflow status to user.\r\n    struct Reporter : public IProgressSink\r\n    {\r\n        // The channel that the reporter is targeting.\r\n        // Based on commands/arguments, only one of these channels can be chosen.\r\n        enum class Channel\r\n        {\r\n            Output,\r\n            Completion,\r\n            Json,\r\n            Disabled,\r\n        };\r\n\r\n        // The level for the Output channel.\r\n        enum class Level : uint32_t\r\n        {\r\n            None = 0x0,\r\n            Verbose = 0x1,\r\n            Info = 0x2,\r\n            Warning = 0x4,\r\n            Error = 0x8,\r\n            All = Verbose | Info | Warning | Error,\r\n        };\r\n\r\n        Reporter();\r\n        Reporter(std::ostream& outStream, std::istream& inStream);\r\n        Reporter(const Reporter&) = delete;\r\n        Reporter& operator=(const Reporter&) = delete;\r\n\r\n        Reporter(Reporter&&) = default;\r\n        Reporter& operator=(Reporter&&) = default;\r\n\r\n        // Request that a clone be constructed from the given reporter.\r\n        struct clone_t {};\r\n        Reporter(const Reporter& other, clone_t);\r\n\r\n        ~Reporter();\r\n\r\n        // Gets the primary device attributes if available.\r\n        std::optional<VirtualTerminal::PrimaryDeviceAttributes> GetPrimaryDeviceAttributes();\r\n\r\n        // Get a stream for verbose output.\r\n        OutputStream Verbose() { return GetOutputStream(Level::Verbose); }\r\n\r\n        // Get a stream for informational output.\r\n        OutputStream Info() { return GetOutputStream(Level::Info); }\r\n\r\n        // Get a stream for warning output.\r\n        OutputStream Warn() { return GetOutputStream(Level::Warning); }\r\n\r\n        // Get a stream for error output.\r\n        OutputStream Error() { return GetOutputStream(Level::Error); }\r\n\r\n        // Get a stream for outputting completion words.\r\n        OutputStream Completion() { return OutputStream(*m_out, m_channel == Channel::Completion, false); }\r\n\r\n        // Get a stream for outputting completion words.\r\n        OutputStream Json() { return OutputStream(*m_out, m_channel == Channel::Json, false); }\r\n\r\n        // Gets a stream for output of the given level.\r\n        OutputStream GetOutputStream(Level level);\r\n\r\n        void EmptyLine() { GetBasicOutputStream() << std::endl; }\r\n\r\n        // Sets the channel that will be reported to.\r\n        // Only do this once and as soon as the channel is determined.\r\n        void SetChannel(Channel channel);\r\n\r\n        // Sets the visual style (mostly for progress currently)\r\n        void SetStyle(AppInstaller::Settings::VisualStyle style);\r\n\r\n        // Get the raw input stream.\r\n        std::istream& RawInputStream();\r\n\r\n        // Check if the input stream is interactive or not.\r\n        bool InputStreamIsInteractive() const;\r\n\r\n        // Prompts the user, return true if they consented.\r\n        bool PromptForBoolResponse(Resource::LocString message, Level level = Level::Info, bool resultIfDisabled = false);\r\n\r\n        // Prompts the user, continues when Enter is pressed\r\n        void PromptForEnter(Level level = Level::Info);\r\n\r\n        // Prompts the user for a path.\r\n        std::filesystem::path PromptForPath(Resource::LocString message, Level level = Level::Info, std::filesystem::path resultIfDisabled = std::filesystem::path::path());\r\n\r\n        // IProgressSink\r\n        void BeginProgress() override;\r\n        void OnProgress(uint64_t current, uint64_t maximum, ProgressType type) override;\r\n        void SetProgressMessage(std::string_view message) override;\r\n        void EndProgress(bool hideProgressWhenDone) override;\r\n\r\n        // Contains the objects used for async progress and the lifetime of said progress.\r\n        struct AsyncProgressScope\r\n        {\r\n            AsyncProgressScope(Reporter& reporter, IProgressSink* sink, bool hideProgressWhenDone);\r\n            ~AsyncProgressScope();\r\n\r\n            AsyncProgressScope(const AsyncProgressScope&) = delete;\r\n            AsyncProgressScope& operator=(const AsyncProgressScope&) = delete;\r\n\r\n            AsyncProgressScope(AsyncProgressScope&&) = delete;\r\n            AsyncProgressScope& operator=(AsyncProgressScope&&) = delete;\r\n\r\n            ProgressCallback& Callback();\r\n            IProgressCallback* operator->();\r\n\r\n            bool HideProgressWhenDone() const;\r\n            void HideProgressWhenDone(bool value);\r\n\r\n        private:\r\n            std::reference_wrapper<Reporter> m_reporter;\r\n            ProgressCallback m_callback;\r\n            std::atomic_bool m_hideProgressWhenDone;\r\n        };\r\n\r\n        // Runs the given callable of type: auto(IProgressCallback&)\r\n        template <typename F>\r\n        auto ExecuteWithProgress(F&& f, bool hideProgressWhenDone = false)\r\n        {\r\n            auto progressScope = BeginAsyncProgress(hideProgressWhenDone);\r\n            return f(progressScope->Callback());\r\n        }\r\n\r\n        // Begins an asynchronous progress operation.\r\n        std::unique_ptr<AsyncProgressScope> BeginAsyncProgress(bool hideProgressWhenDone = false);\r\n\r\n        // Sets the in progress callback.\r\n        void SetProgressCallback(ProgressCallback* callback);\r\n\r\n        // Cancels the in progress task.\r\n        void CancelInProgressTask(bool force, CancelReason reason);\r\n\r\n        void CloseOutputStream(bool forceDisable = false);\r\n\r\n        void SetProgressSink(IProgressSink* sink)\r\n        {\r\n            m_progressSink = sink;\r\n        }\r\n\r\n        bool IsLevelEnabled(Level reporterLevel)\r\n        {\r\n            return WI_AreAllFlagsSet(m_enabledLevels, reporterLevel);\r\n        }\r\n\r\n        void SetLevelMask(Level reporterLevel, bool setEnabled = true);\r\n\r\n        // Determines if sixels are supported by the current instance.\r\n        bool SixelsSupported();\r\n\r\n        // Determines if sixels are enabled; they must be both supported and enabled by user settings.\r\n        bool SixelsEnabled();\r\n\r\n    private:\r\n        Reporter(std::shared_ptr<BaseStream> outStream, std::istream& inStream);\r\n        // Gets a stream for output for internal use.\r\n        OutputStream GetBasicOutputStream();\r\n\r\n        // Used to show indefinite progress. Currently an indefinite spinner is the form of\r\n        // showing indefinite progress.\r\n        // running: shows indefinite progress if set to true, stops indefinite progress if set to false\r\n        void ShowIndefiniteProgress(bool running);\r\n\r\n        Channel m_channel = Channel::Output;\r\n        std::shared_ptr<BaseStream> m_out;\r\n        std::istream& m_in;\r\n        std::optional<AppInstaller::Settings::VisualStyle> m_style;\r\n        std::unique_ptr<IIndefiniteSpinner> m_spinner;\r\n        std::unique_ptr<IProgressBar> m_progressBar;\r\n        wil::srwlock m_progressCallbackLock;\r\n        std::atomic<ProgressCallback*> m_progressCallback;\r\n        std::atomic<IProgressSink*> m_progressSink;\r\n        DWORD m_outStreamFileType = FILE_TYPE_UNKNOWN;\r\n        DWORD m_inStreamFileType = FILE_TYPE_UNKNOWN;\r\n\r\n        // Enable all levels by default\r\n        Level m_enabledLevels = Level::All;\r\n    };\r\n\r\n    DEFINE_ENUM_FLAG_OPERATORS(Reporter::Level);\r\n\r\n    // Indirection to enable change without tracking down every place\r\n    extern const VirtualTerminal::Sequence& HelpCommandEmphasis;\r\n    extern const VirtualTerminal::Sequence& HelpArgumentEmphasis;\r\n    extern const VirtualTerminal::Sequence& ManifestInfoEmphasis;\r\n    extern const VirtualTerminal::Sequence& SourceInfoEmphasis;\r\n    extern const VirtualTerminal::Sequence& NameEmphasis;\r\n    extern const VirtualTerminal::Sequence& IdEmphasis;\r\n    extern const VirtualTerminal::Sequence& UrlEmphasis;\r\n    extern const VirtualTerminal::Sequence& PromptEmphasis;\r\n    extern const VirtualTerminal::Sequence& ConvertToUpgradeFlowEmphasis;\r\n    extern const VirtualTerminal::Sequence& ConfigurationIntentEmphasis;\r\n    extern const VirtualTerminal::Sequence& ConfigurationUnitEmphasis;\r\n    extern const VirtualTerminal::Sequence& AuthenticationEmphasis;\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Invocation.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <map>\r\n#include <vector>\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    // Contains the raw command line arguments and functionality to iterate and consume them.\r\n    struct Invocation\r\n    {\r\n        Invocation(std::vector<std::string>&& args) : m_args(std::move(args)) {}\r\n\r\n        struct iterator\r\n        {\r\n            iterator(size_t arg, std::vector<std::string>& args) : m_arg(arg), m_args(args) {}\r\n\r\n            iterator(const iterator&) = default;\r\n            iterator& operator=(const iterator&) = default;\r\n\r\n            iterator operator++() { return { ++m_arg, m_args }; }\r\n            iterator operator++(int) { return { m_arg++, m_args }; }\r\n            iterator operator--() { return { --m_arg, m_args }; }\r\n            iterator operator--(int) { return { m_arg--, m_args }; }\r\n\r\n            bool operator==(const iterator& other) const { return m_arg == other.m_arg; }\r\n            bool operator!=(const iterator& other) const { return m_arg != other.m_arg; }\r\n\r\n            const std::string& operator*() const { return m_args[m_arg]; }\r\n            const std::string* operator->() const { return &(m_args[m_arg]); }\r\n\r\n            size_t index() const { return m_arg; }\r\n\r\n        private:\r\n            size_t m_arg;\r\n            std::vector<std::string>& m_args;\r\n        };\r\n\r\n        size_t size() const { return m_args.size(); }\r\n        iterator begin() { return { m_currentFirstArg, m_args }; }\r\n        iterator end() { return { m_args.size(), m_args }; }\r\n        void consume(const iterator& i) { m_currentFirstArg = i.index() + 1; }\r\n\r\n    private:\r\n        std::vector<std::string> m_args;\r\n        size_t m_currentFirstArg = 0;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/PackageCollection.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"PackageCollection.h\"\n\n#include <AppInstallerLogging.h>\n#include <AppInstallerRuntime.h>\n#include <winget/JsonSchemaValidation.h>\n\n#include \"PackagesSchema.h\"\n\n#include <algorithm>\n#include <ostream>\n\nusing namespace AppInstaller::Repository;\n\nnamespace AppInstaller::CLI\n{\n    namespace\n    {\n        // Strings used in the Packages JSON file.\n        // Most will be used to access a JSON value, so they need to be std::string\n        struct StaticStrings\n        {\n            const std::string PackagesJson_Schema = \"$schema\";\n            const std::string PackagesJson_SchemaUri_v1_0 = \"https://aka.ms/winget-packages.schema.1.0.json\";\n            const std::string PackagesJson_SchemaUri_v2_0 = \"https://aka.ms/winget-packages.schema.2.0.json\";\n            const std::string PackagesJson_WinGetVersion = \"WinGetVersion\";\n            const std::string PackagesJson_CreationDate = \"CreationDate\";\n\n            const std::string PackagesJson_Sources = \"Sources\";\n            const std::string PackagesJson_Source_Details = \"SourceDetails\";\n            const std::string PackagesJson_Source_Name = \"Name\";\n            const std::string PackagesJson_Source_Identifier = \"Identifier\";\n            const std::string PackagesJson_Source_Argument = \"Argument\";\n            const std::string PackagesJson_Source_Type = \"Type\";\n\n            const std::string PackagesJson_Packages = \"Packages\";\n            const std::string PackagesJson_Package_Id = \"Id\";\n            const std::string PackagesJson_Package_PackageIdentifier = \"PackageIdentifier\";\n            const std::string PackagesJson_Package_Version = \"Version\";\n            const std::string PackagesJson_Package_Channel = \"Channel\";\n            const std::string PackagesJson_Package_Scope = \"Scope\";\n\n            static const StaticStrings& Instance()\n            {\n                static StaticStrings instance;\n                return instance;\n            }\n        };\n\n        // Gets or creates a property of a JSON object by its name.\n        Json::Value& GetJsonProperty(Json::Value& node, const std::string& propertyName, Json::ValueType valueType)\n        {\n            if (!node.isMember(propertyName))\n            {\n                node[propertyName] = Json::Value{ valueType };\n            }\n            else\n            {\n                THROW_HR_IF(E_NOT_VALID_STATE, node[propertyName].type() != valueType);\n            }\n\n            return node[propertyName];\n        }\n\n        // The interface for a package collection parser.\n        struct IPackageCollectionParser\n        {\n            virtual ~IPackageCollectionParser() = default;\n\n            virtual PackageCollection Parse(const Json::Value& root) = 0;\n        };\n\n        // The parsing code for schema v1.0\n        struct PackageCollectionParser_1_0 : public IPackageCollectionParser\n        {\n            PackageCollection Parse(const Json::Value& root) override\n            {\n                PackageCollection result;\n\n                // Regardless of the fact that the value is required in 1.0, allow it to be optional\n                if (root.isMember(ss.PackagesJson_WinGetVersion))\n                {\n                    result.ClientVersion = root[ss.PackagesJson_WinGetVersion].asString();\n                }\n\n                for (const auto& sourceNode : root[ss.PackagesJson_Sources])\n                {\n                    auto newSource = ParseSourceNode(sourceNode);\n                    auto existingSource = std::find_if(result.Sources.begin(), result.Sources.end(), [&](const PackageCollection::Source& s) { return s.Details.Identifier == newSource.Details.Identifier; });\n                    if (existingSource == result.Sources.end())\n                    {\n                        result.Sources.push_back(std::move(newSource));\n                    }\n                    else\n                    {\n                        existingSource->Packages.insert(existingSource->Packages.end(), newSource.Packages.begin(), newSource.Packages.end());\n                    }\n                }\n\n                return result;\n            }\n\n        protected:\n            // Reads the description of a package from a Package node in the JSON.\n            virtual PackageCollection::Package ParsePackageNode(const Json::Value& packageNode)\n            {\n                std::string id = packageNode[ss.PackagesJson_Package_Id].asString();\n                std::string version = packageNode.isMember(ss.PackagesJson_Package_Version) ? packageNode[ss.PackagesJson_Package_Version].asString() : \"\";\n                std::string channel = packageNode.isMember(ss.PackagesJson_Package_Channel) ? packageNode[ss.PackagesJson_Package_Channel].asString() : \"\";\n                std::string scope = packageNode.isMember(ss.PackagesJson_Package_Scope) ? packageNode[ss.PackagesJson_Package_Scope].asString() : \"\";\n\n                PackageCollection::Package package{ Utility::LocIndString{ id }, Utility::Version{ version }, Utility::Channel{ channel } };\n                package.Scope = Manifest::ConvertToScopeEnum(scope);\n\n                return package;\n            }\n\n            // Reads the description of a Source and all the packages needed from it, from a Source node in the JSON.\n            PackageCollection::Source ParseSourceNode(const Json::Value& sourceNode)\n            {\n                SourceDetails sourceDetails;\n                auto& detailsNode = sourceNode[ss.PackagesJson_Source_Details];\n                sourceDetails.Identifier = Utility::LocIndString{ detailsNode[ss.PackagesJson_Source_Identifier].asString() };\n                sourceDetails.Name = detailsNode[ss.PackagesJson_Source_Name].asString();\n                sourceDetails.Arg = detailsNode[ss.PackagesJson_Source_Argument].asString();\n                sourceDetails.Type = detailsNode[ss.PackagesJson_Source_Type].asString();\n\n                PackageCollection::Source source{ std::move(sourceDetails) };\n                for (const auto& packageNode : sourceNode[ss.PackagesJson_Packages])\n                {\n                    source.Packages.emplace_back(ParsePackageNode(packageNode));\n                }\n\n                return source;\n            }\n\n            const StaticStrings& ss = StaticStrings::Instance();\n        };\n\n        // The parsing code for schema v2.0\n        struct PackageCollectionParser_2_0 : public PackageCollectionParser_1_0\n        {\n        protected:\n            // Reads the description of a package from a Package node in the JSON.\n            PackageCollection::Package ParsePackageNode(const Json::Value& packageNode) override\n            {\n                std::string id = packageNode[ss.PackagesJson_Package_PackageIdentifier].asString();\n                std::string version = packageNode.isMember(ss.PackagesJson_Package_Version) ? packageNode[ss.PackagesJson_Package_Version].asString() : \"\";\n                std::string channel = packageNode.isMember(ss.PackagesJson_Package_Channel) ? packageNode[ss.PackagesJson_Package_Channel].asString() : \"\";\n                std::string scope = packageNode.isMember(ss.PackagesJson_Package_Scope) ? packageNode[ss.PackagesJson_Package_Scope].asString() : \"\";\n\n                PackageCollection::Package package{ Utility::LocIndString{ id }, Utility::Version{ version }, Utility::Channel{ channel } };\n                package.Scope = Manifest::ConvertToScopeEnum(scope);\n\n                return package;\n            }\n        };\n\n        // Creates a minimal root object of a Packages JSON file.\n        Json::Value CreateRoot(const std::string& wingetVersion)\n        {\n            const auto& ss = StaticStrings::Instance();\n\n            Json::Value root{ Json::ValueType::objectValue };\n            root[ss.PackagesJson_WinGetVersion] = wingetVersion;\n            // We only generate the latest schema\n            root[ss.PackagesJson_Schema] = ss.PackagesJson_SchemaUri_v2_0;\n\n            std::stringstream currentTimeStream;\n            Utility::OutputTimePoint(currentTimeStream, std::chrono::system_clock::now(), true);\n            root[ss.PackagesJson_CreationDate] = currentTimeStream.str();\n\n            return root;\n        }\n\n        // Adds a new Package node to a Source node in the Json file, and returns it.\n        Json::Value& AddPackageToSource(Json::Value& sourceNode, const PackageCollection::Package& package)\n        {\n            const auto& ss = StaticStrings::Instance();\n\n            Json::Value packageNode{ Json::ValueType::objectValue };\n            packageNode[ss.PackagesJson_Package_PackageIdentifier] = package.Id.get();\n\n            // Only add version and channel if present.\n            // Packages may not have a channel, or versions may not have been requested.\n            const std::string& version = package.VersionAndChannel.GetVersion().ToString();\n            if (!version.empty())\n            {\n                packageNode[ss.PackagesJson_Package_Version] = version;\n            }\n\n            const std::string& channel = package.VersionAndChannel.GetChannel().ToString();\n            if (!channel.empty())\n            {\n                packageNode[ss.PackagesJson_Package_Channel] = channel;\n            }\n\n            if (package.Scope != Manifest::ScopeEnum::Unknown)\n            {\n                packageNode[ss.PackagesJson_Package_Scope] = std::string{ Manifest::ScopeToString(package.Scope) };\n            }\n\n            return sourceNode[ss.PackagesJson_Packages].append(std::move(packageNode));\n        }\n\n        // Adds a new Source node to the JSON, and returns it.\n        Json::Value& AddSourceNode(Json::Value& root, const PackageCollection::Source& source)\n        {\n            const auto& ss = StaticStrings::Instance();\n\n            Json::Value sourceNode{ Json::ValueType::objectValue };\n\n            Json::Value sourceDetailsNode{ Json::ValueType::objectValue };\n            sourceDetailsNode[ss.PackagesJson_Source_Name] = source.Details.Name;\n            sourceDetailsNode[ss.PackagesJson_Source_Argument] = source.Details.Arg;\n            sourceDetailsNode[ss.PackagesJson_Source_Identifier] = source.Details.Identifier;\n            sourceDetailsNode[ss.PackagesJson_Source_Type] = source.Details.Type;\n            sourceNode[ss.PackagesJson_Source_Details] = std::move(sourceDetailsNode);\n\n            sourceNode[ss.PackagesJson_Packages] = Json::Value{ Json::ValueType::arrayValue };\n\n            auto& sourcesNode = GetJsonProperty(root, ss.PackagesJson_Sources, Json::ValueType::arrayValue);\n            for (const auto& package : source.Packages)\n            {\n                AddPackageToSource(sourceNode, package);\n            }\n\n            return sourcesNode.append(std::move(sourceNode));\n        }\n    }\n\n    namespace PackagesJson\n    {\n        Json::Value CreateJson(const PackageCollection& packages)\n        {\n            Json::Value root = CreateRoot(packages.ClientVersion);\n            for (const auto& source : packages.Sources)\n            {\n                AddSourceNode(root, source);\n            }\n\n            return root;\n        }\n\n        ParseResult TryParseJson(const Json::Value& root)\n        {\n            const auto& ss = StaticStrings::Instance();\n\n            // Find the schema used for the JSON\n            if (!(root.isObject() && root.isMember(ss.PackagesJson_Schema) && root[ss.PackagesJson_Schema].isString()))\n            {\n                AICLI_LOG(CLI, Error, << \"Import file is missing \\\"\" << ss.PackagesJson_Schema << \"\\\" property\");\n                return ParseResult{ ParseResult::Type::MissingSchema };\n            }\n\n            const auto& schemaUri = root[ss.PackagesJson_Schema].asString();\n            Json::Value schemaJson;\n            std::unique_ptr<IPackageCollectionParser> parser;\n            if (schemaUri == ss.PackagesJson_SchemaUri_v1_0)\n            {\n                schemaJson = JsonSchema::LoadResourceAsSchemaDoc(MAKEINTRESOURCE(IDX_PACKAGES_SCHEMA_V1), MAKEINTRESOURCE(PACKAGESSCHEMA_RESOURCE_TYPE));\n                parser = std::make_unique<PackageCollectionParser_1_0>();\n            }\n            else if (schemaUri == ss.PackagesJson_SchemaUri_v2_0)\n            {\n                schemaJson = JsonSchema::LoadResourceAsSchemaDoc(MAKEINTRESOURCE(IDX_PACKAGES_SCHEMA_V2), MAKEINTRESOURCE(PACKAGESSCHEMA_RESOURCE_TYPE));\n                parser = std::make_unique<PackageCollectionParser_2_0>();\n            }\n            else\n            {\n                AICLI_LOG(CLI, Error, << \"Unrecognized schema for import file: \" << schemaUri);\n                return ParseResult{ ParseResult::Type::UnrecognizedSchema };\n            }\n\n            // Validate the JSON against the schema.\n            valijson::Schema schema;\n            JsonSchema::PopulateSchema(schemaJson, schema);\n\n            valijson::ValidationResults results;\n            if (!JsonSchema::Validate(schema, root, results))\n            {\n                return ParseResult{ ParseResult::Type::SchemaValidationFailed, JsonSchema::GetErrorStringFromResults(results) };\n            }\n\n            // Extract the data from the JSON.\n            return ParseResult{ parser->Parse(root) };\n        }\n    }\n}"
  },
  {
    "path": "src/AppInstallerCLICore/PackageCollection.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"AppInstallerDateTime.h\"\n#include \"winget/RepositorySource.h\"\n#include <winget/Manifest.h>\n\n#include <json/json.h>\n\n#include <vector>\n\nnamespace AppInstaller::CLI\n{\n    // Container for data to identify multiple packages to be installed from multiple sources.\n    struct PackageCollection\n    {\n        // Description of a package.\n        // Does not represent the actual package, just enough to find and install it.\n        struct Package\n        {\n            Package() = default;\n            Package(Utility::LocIndString&& id) :\n                Id(std::move(id)) {}\n            Package(Utility::LocIndString&& id, Utility::Version&& version, Utility::Channel&& channel) :\n                Id(std::move(id)), VersionAndChannel(std::move(version), std::move(channel)) {}\n            Package(Utility::LocIndString&& id, Utility::VersionAndChannel&& versionAndChannel) :\n                Id(std::move(id)), VersionAndChannel(std::move(versionAndChannel)) {}\n\n            Utility::LocIndString Id;\n            Utility::VersionAndChannel VersionAndChannel;\n            Manifest::ScopeEnum Scope = Manifest::ScopeEnum::Unknown;\r\n            std::filesystem::path InstalledLocation;\n        };\n\n        // A source along with a set of packages available from it.\n        struct Source\n        {\n            Source() = default;\n            Source(const Repository::SourceDetails& sourceDetails) : Details(sourceDetails) {}\n            Source(Repository::SourceDetails&& sourceDetails) : Details(std::move(sourceDetails)) {}\n\n            Repository::SourceDetails Details;\n            std::vector<Package> Packages;\n        };\n\n        // Version of the WinGet client that produced this collection.\n        std::string ClientVersion;\n\n        // Requests from each individual source.\n        std::vector<Source> Sources;\n    };\n\n    namespace PackagesJson\n    {\n        struct ParseResult\n        {\n            enum class Type\n            {\n                MissingSchema,\n                UnrecognizedSchema,\n                SchemaValidationFailed,\n                Success,\n            };\n\n            ParseResult(Type result) : Result(result) {}\n            ParseResult(Type result, std::string_view errors) : Result(result), Errors(errors) {}\n            ParseResult(PackageCollection&& packages) : Result(Type::Success), Packages(std::move(packages)) {}\n\n            Type Result;\n            PackageCollection Packages;\n            std::string Errors;\n        };\n\n        // Converts a collection of packages to its JSON representation for exporting.\n        Json::Value CreateJson(const PackageCollection& packages);\n\n        // Tries to parse a JSON into a collection of packages.\n        ParseResult TryParseJson(const Json::Value& root);\n    }\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/PortableInstaller.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ExecutionContext.h\"\r\n#include \"PortableInstaller.h\"\r\n#include <winget/Manifest.h>\r\n#include <winget/ManifestCommon.h>\r\n#include <winget/Filesystem.h>\r\n#include <winget/PathVariable.h>\r\n#include <winget/PortableIndex.h>\r\n#include <AppInstallerErrors.h>\r\n#include <AppInstallerRuntime.h>\r\n#include <Workflows/WorkflowBase.h>\r\n\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::Registry;\r\nusing namespace AppInstaller::Registry::Portable;\r\nusing namespace AppInstaller::Registry::Environment;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::SQLite;\r\nusing namespace AppInstaller::Repository::Microsoft;\r\nusing namespace AppInstaller::Repository::Microsoft::Schema;\r\nusing namespace AppInstaller::CLI::Workflow;\r\n\r\nnamespace AppInstaller::CLI::Portable\r\n{\r\n    std::filesystem::path GetPortableLinksLocation(Manifest::ScopeEnum scope)\r\n    {\r\n        if (scope == Manifest::ScopeEnum::Machine)\r\n        {\r\n            return Runtime::GetPathTo(Runtime::PathName::PortableLinksMachineLocation);\r\n        }\r\n        else\r\n        {\r\n            return Runtime::GetPathTo(Runtime::PathName::PortableLinksUserLocation);\r\n        }\r\n    }\r\n\r\n    std::filesystem::path GetPortableInstallRoot(Manifest::ScopeEnum scope, Utility::Architecture arch)\r\n    {\r\n        if (scope == Manifest::ScopeEnum::Machine)\r\n        {\r\n            if (arch == Utility::Architecture::X86)\r\n            {\r\n                return Runtime::GetPathTo(Runtime::PathName::PortablePackageMachineRootX86);\r\n            }\r\n            else\r\n            {\r\n                return Runtime::GetPathTo(Runtime::PathName::PortablePackageMachineRoot);\r\n            }\r\n        }\r\n        else\r\n        {\r\n            return Runtime::GetPathTo(Runtime::PathName::PortablePackageUserRoot);\r\n        }\r\n    }\r\n\r\n    bool VerifyPortableFile(AppInstaller::Portable::PortableFileEntry& entry)\r\n    {\r\n        std::filesystem::path filePath = entry.GetFilePath();\r\n        PortableFileType fileType = entry.FileType;\r\n\r\n        if (fileType == PortableFileType::File)\r\n        {\r\n            if (std::filesystem::exists(filePath))\r\n            {\r\n                SHA256::HashBuffer fileHash = SHA256::ComputeHashFromFile(filePath);\r\n                if (!SHA256::AreEqual(fileHash, SHA256::ConvertToBytes(entry.SHA256)))\r\n                {\r\n                    AICLI_LOG(CLI, Warning, << \"File hash does not match ARP Entry. Expected: \" << entry.SHA256 << \" Actual: \" << SHA256::ConvertToString(fileHash));\r\n                    return false;\r\n                }\r\n            }\r\n        }\r\n        else if (fileType == PortableFileType::Symlink)\r\n        {\r\n            std::filesystem::path symlinkTargetPath{ AppInstaller::Utility::ConvertToUTF16(entry.SymlinkTarget) };\r\n            if (Filesystem::SymlinkExists(filePath) && !Filesystem::VerifySymlink(filePath, symlinkTargetPath))\r\n            {\r\n                AICLI_LOG(CLI, Warning, << \"Symlink target does not match ARP Entry. Expected: \" << symlinkTargetPath << \" Actual: \" << std::filesystem::read_symlink(filePath));\r\n                return false;\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    void PortableInstaller::InstallFile(AppInstaller::Portable::PortableFileEntry& entry)\r\n    {\r\n        PortableFileType fileType = entry.FileType;\r\n        std::filesystem::path filePath = entry.GetFilePath();\r\n\r\n        if (entry.FileType == PortableFileType::File)\r\n        {\r\n            if (std::filesystem::exists(filePath))\r\n            {\r\n                AICLI_LOG(Core, Info, << \"Removing existing portable file at: \" << filePath);\r\n                std::filesystem::remove(filePath);\r\n            }\r\n\r\n            AICLI_LOG(Core, Info, << \"Moving portable exe to: \" << filePath);\r\n\r\n            if (!RecordToIndex)\r\n            {\r\n                CommitToARPEntry(PortableValueName::PortableTargetFullPath, filePath);\r\n                CommitToARPEntry(PortableValueName::SHA256, entry.SHA256);\r\n            }\r\n\r\n            Filesystem::RenameFile(entry.CurrentPath, filePath);\r\n        }\r\n        else if (fileType == PortableFileType::Directory)\r\n        {\r\n            if (Filesystem::IsSameVolume(entry.CurrentPath, filePath))\r\n            {\r\n                AICLI_LOG(Core, Info, << \"Renaming directory to: \" << filePath);\r\n                Filesystem::RenameFile(entry.CurrentPath, filePath);\r\n            }\r\n            else\r\n            {\r\n                // Copy directory instead of renaming as there is a known issue with renaming across drives.\r\n                AICLI_LOG(Core, Info, << \"Copying directory to: \" << filePath);\r\n                std::filesystem::copy(entry.CurrentPath, filePath, std::filesystem::copy_options::overwrite_existing | std::filesystem::copy_options::recursive);\r\n            }\r\n        }\r\n        else if (entry.FileType == PortableFileType::Symlink)\r\n        {\r\n            std::filesystem::path symlinkTargetPath{ Utility::ConvertToUTF16(entry.SymlinkTarget) };\r\n\r\n            if (BinariesDependOnPath && !InstallDirectoryAddedToPath)\r\n            {\r\n                // Scenario indicated by 'ArchiveBinariesDependOnPath' manifest entry.\r\n                // Skip symlink creation for portables dependent on binaries that require the install directory to be added to PATH.\r\n                std::filesystem::path installDirectory = symlinkTargetPath.parent_path();\r\n                AddToPathVariable(installDirectory);\r\n                AICLI_LOG(Core, Info, << \"Install directory added to PATH: \" << installDirectory);\r\n                CommitToARPEntry(PortableValueName::InstallDirectoryAddedToPath, InstallDirectoryAddedToPath = true);\r\n            }\r\n            else if (!InstallDirectoryAddedToPath)\r\n            {\r\n                std::filesystem::file_status status = std::filesystem::status(filePath);\r\n                if (std::filesystem::is_directory(status))\r\n                {\r\n                    AICLI_LOG(CLI, Info, << \"Unable to create symlink. '\" << filePath << \"points to an existing directory.\");\r\n                    THROW_HR(APPINSTALLER_CLI_ERROR_PORTABLE_SYMLINK_PATH_IS_DIRECTORY);\r\n                }\r\n\r\n                if (!RecordToIndex)\r\n                {\r\n                    CommitToARPEntry(PortableValueName::PortableSymlinkFullPath, filePath);\r\n                }\r\n\r\n                if (std::filesystem::remove(filePath))\r\n                {\r\n                    AICLI_LOG(CLI, Info, << \"Removed existing file at \" << filePath);\r\n                    m_stream << Resource::String::OverwritingExistingFileAtMessage(Utility::LocIndView{ filePath.u8string() }) << std::endl;\r\n                }\r\n\r\n                if (Filesystem::CreateSymlink(symlinkTargetPath, filePath))\r\n                {\r\n                    AICLI_LOG(Core, Info, << \"Symlink created at: \" << filePath << \" with target path: \" << symlinkTargetPath);\r\n                }\r\n                else\r\n                {\r\n                    // If symlink creation fails, resort to adding the package directory to PATH.\r\n                    AICLI_LOG(Core, Info, << \"Failed to create symlink at: \" << filePath);\r\n                    AddToPathVariable(symlinkTargetPath.parent_path());\r\n                    CommitToARPEntry(PortableValueName::InstallDirectoryAddedToPath, InstallDirectoryAddedToPath = true);\r\n                }\r\n            }\r\n            m_stream << Resource::String::PortableAliasAdded << ' ' << filePath.stem() << std::endl;\r\n        }\r\n    }\r\n\r\n    void PortableInstaller::RemoveFile(AppInstaller::Portable::PortableFileEntry& entry)\r\n    {\r\n        const auto& filePath = entry.GetFilePath();\r\n        PortableFileType fileType = entry.FileType;\r\n\r\n        if (fileType == PortableFileType::File && std::filesystem::exists(filePath))\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"Deleting portable exe at: \" << filePath);\r\n            std::filesystem::remove(filePath);\r\n        }\r\n        else if (fileType == PortableFileType::Symlink)\r\n        {\r\n            if (Filesystem::SymlinkExists(filePath))\r\n            {\r\n                AICLI_LOG(CLI, Info, << \"Deleting portable symlink at: \" << filePath);\r\n                std::filesystem::remove(filePath);\r\n            }\r\n            else if (InstallDirectoryAddedToPath)\r\n            {\r\n                // If symlink doesn't exist, check if install directory was added to PATH directly and remove.\r\n                RemoveFromPathVariable(std::filesystem::path(Utility::ConvertToUTF16(entry.SymlinkTarget)).parent_path());\r\n            }\r\n        }\r\n        else if (fileType == PortableFileType::Symlink && Filesystem::SymlinkExists(filePath))\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"Deleting portable symlink at: \" << filePath);\r\n            std::filesystem::remove(filePath);\r\n        }\r\n        else if (fileType == PortableFileType::Directory && std::filesystem::exists(filePath))\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"Removing directory at \" << filePath);\r\n            std::filesystem::remove_all(filePath);\r\n        }\r\n    }\r\n\r\n    // TODO: Optimize by applying the difference between expected and desired state.\r\n    void PortableInstaller::ApplyDesiredState()\r\n    {\r\n        std::filesystem::path existingIndexPath = InstallLocation / GetPortableIndexFileName();\r\n        if (std::filesystem::exists(existingIndexPath))\r\n        {\r\n            bool deleteIndex = false;\r\n            {\r\n                PortableIndex existingIndex = PortableIndex::Open(existingIndexPath.u8string(), SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n\r\n                for (auto expectedEntry : m_expectedEntries)\r\n                {\r\n                    RemoveFile(expectedEntry);\r\n                    existingIndex.RemovePortableFile(expectedEntry);\r\n                }\r\n\r\n                deleteIndex = existingIndex.IsEmpty();\r\n            }\r\n\r\n            if (deleteIndex)\r\n            {\r\n                std::filesystem::remove(existingIndexPath);\r\n                AICLI_LOG(CLI, Info, << \"Portable index deleted: \" << existingIndexPath);\r\n            }\r\n        }\r\n        else\r\n        {\r\n            for (auto expectedEntry : m_expectedEntries)\r\n            {\r\n                RemoveFile(expectedEntry);\r\n            }\r\n        }\r\n\r\n        // Check if existing install location differs from the target install location for proper cleanup.\r\n        if (!TargetInstallLocation.empty() && TargetInstallLocation != InstallLocation)\r\n        {\r\n            RemoveInstallDirectory();\r\n        }\r\n\r\n        if (RecordToIndex)\r\n        {\r\n            std::filesystem::path targetIndexPath = TargetInstallLocation / GetPortableIndexFileName();\r\n            PortableIndex targetIndex = std::filesystem::exists(targetIndexPath) ?\r\n                PortableIndex::Open(targetIndexPath.u8string(), SQLiteStorageBase::OpenDisposition::ReadWrite) :\r\n                PortableIndex::CreateNew(targetIndexPath.u8string());\r\n\r\n            for (auto desiredEntry : m_desiredEntries)\r\n            {\r\n                targetIndex.AddOrUpdatePortableFile(desiredEntry);\r\n                InstallFile(desiredEntry);\r\n            }\r\n        }\r\n        else\r\n        {\r\n            for (auto desiredEntry : m_desiredEntries)\r\n            {\r\n                InstallFile(desiredEntry);\r\n            }\r\n        }\r\n    }\r\n\r\n    bool PortableInstaller::VerifyExpectedState()\r\n    {\r\n        for (auto entry : m_expectedEntries)\r\n        {\r\n            if (!VerifyPortableFile(entry))\r\n            {\r\n                AICLI_LOG(CLI, Info, << \"Portable file has been modified: \" << entry.GetFilePath());\r\n                return false;\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    void PortableInstaller::Install(Workflow::OperationType operation)\r\n    {\r\n        // If the operation is an install, the ARP entry should be created first so that a catastrophic failure\r\n        // leaves the system in a state where an uninstall may be possible\r\n        if (operation == Workflow::OperationType::Install)\r\n        {\r\n            RegisterARPEntry();\r\n        }\r\n\r\n        CreateTargetInstallDirectory();\r\n\r\n        ApplyDesiredState();\r\n\r\n        if (!InstallDirectoryAddedToPath)\r\n        {\r\n            AddToPathVariable(GetPortableLinksLocation(GetScope()));\r\n        }\r\n\r\n        // If the operation is an upgrade, the ARP entry should be created last so that a catastrophic failure\r\n        // leaves the system in a state where an upgrade can be re-attempted\r\n        if (operation == Workflow::OperationType::Upgrade)\r\n        {\r\n            RegisterARPEntry();\r\n        }\r\n    }\r\n\r\n    void PortableInstaller::Uninstall()\r\n    {\r\n        ApplyDesiredState();\r\n\r\n        RemoveInstallDirectory();\r\n\r\n        if (!InstallDirectoryAddedToPath)\r\n        {\r\n            RemoveFromPathVariable(GetPortableLinksLocation(GetScope()));\r\n        }\r\n\r\n        m_portableARPEntry.Delete();\r\n        AICLI_LOG(CLI, Info, << \"PortableARPEntry deleted.\");\r\n    }\r\n\r\n    void PortableInstaller::CreateTargetInstallDirectory()\r\n    {\r\n        if (std::filesystem::create_directories(TargetInstallLocation))\r\n        {\r\n            AICLI_LOG(Core, Info, << \"Created target install directory: \" << TargetInstallLocation);\r\n            CommitToARPEntry(PortableValueName::InstallDirectoryCreated, true);\r\n        }\r\n\r\n        CommitToARPEntry(PortableValueName::InstallLocation, TargetInstallLocation);\r\n    }\r\n\r\n    void PortableInstaller::RemoveInstallDirectory()\r\n    {\r\n        if (std::filesystem::exists(InstallLocation) && InstallDirectoryCreated)\r\n        {\r\n            if (Purge)\r\n            {\r\n                m_stream << Resource::String::PurgeInstallDirectory << std::endl;\r\n                const auto& removedFilesCount = std::filesystem::remove_all(InstallLocation);\r\n                AICLI_LOG(CLI, Info, << \"Purged install location directory. Deleted \" << removedFilesCount << \" files or directories\");\r\n            }\r\n            else\r\n            {\r\n                if (std::filesystem::is_empty(InstallLocation))\r\n                {\r\n                    AICLI_LOG(CLI, Info, << \"Removing empty install directory: \" << InstallLocation);\r\n                    std::filesystem::remove(InstallLocation);\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(CLI, Info, << \"Unable to remove install directory as there are remaining files in: \" << InstallLocation);\r\n                    m_stream << Resource::String::FilesRemainInInstallDirectory(Utility::LocIndView{ InstallLocation.u8string() }) << std::endl;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    void PortableInstaller::AddToPathVariable(std::filesystem::path value)\r\n    {\r\n        // Ensure the preferred separator format\r\n        value.make_preferred();\r\n\r\n        if (PathVariable(GetScope()).Append(value))\r\n        {\r\n            AICLI_LOG(Core, Info, << \"Appending portable target directory to PATH registry: \" << value);\r\n            m_stream << Resource::String::ModifiedPathRequiresShellRestart << std::endl;\r\n        }\r\n        else\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"Portable target directory already exists in PATH registry: \" << value);\r\n        }\r\n    }\r\n\r\n    void PortableInstaller::RemoveFromPathVariable(std::filesystem::path value)\r\n    {\r\n        if (std::filesystem::exists(value) && !std::filesystem::is_empty(value))\r\n        {\r\n            AICLI_LOG(Core, Info, << \"Install directory is not empty: \" << value);\r\n        }\r\n        else\r\n        {\r\n\t\t\t// Attempt to remove both the original and the preferred format to ensure removal\r\n            // Necessary for handling old path values associated with winget-cli#5033\r\n            if (PathVariable(GetScope()).Remove(value) || PathVariable(GetScope()).Remove(value.make_preferred()))\r\n            {\r\n                InstallDirectoryAddedToPath = false;\r\n                AICLI_LOG(CLI, Info, << \"Removed target directory from PATH registry: \" << value);\r\n            }\r\n            else\r\n            {\r\n                AICLI_LOG(CLI, Info, << \"Target directory not removed from PATH registry: \" << value);\r\n            }\r\n        }\r\n    }\r\n\r\n    void PortableInstaller::SetAppsAndFeaturesMetadata(const Manifest::Manifest& manifest, const std::vector<AppInstaller::Manifest::AppsAndFeaturesEntry>& entries)\r\n    {\r\n        AppInstaller::Manifest::AppsAndFeaturesEntry entry;\r\n        if (!entries.empty())\r\n        {\r\n            entry = entries[0];\r\n        }\r\n\r\n        if (entry.DisplayName.empty())\r\n        {\r\n            entry.DisplayName = manifest.CurrentLocalization.Get<Manifest::Localization::PackageName>();\r\n        }\r\n        if (entry.DisplayVersion.empty())\r\n        {\r\n            entry.DisplayVersion = manifest.Version;\r\n        }\r\n        if (entry.Publisher.empty())\r\n        {\r\n            entry.Publisher = manifest.CurrentLocalization.Get<Manifest::Localization::Publisher>();\r\n        }\r\n\r\n        DisplayName = entry.DisplayName;\r\n        DisplayVersion = entry.DisplayVersion;\r\n        Publisher = entry.Publisher;\r\n        InstallDate = Utility::GetCurrentDateForARP();\r\n        URLInfoAbout = manifest.CurrentLocalization.Get<Manifest::Localization::PackageUrl>();\r\n        HelpLink = manifest.CurrentLocalization.Get<Manifest::Localization::PublisherSupportUrl>();\r\n    }\r\n\r\n    AppInstaller::Manifest::AppsAndFeaturesEntry PortableInstaller::GetAppsAndFeaturesEntry()\r\n    {\r\n        Manifest::AppsAndFeaturesEntry entry;\r\n\r\n        entry.DisplayName = DisplayName;\r\n        entry.Publisher = Publisher;\r\n        entry.DisplayVersion = DisplayVersion;\r\n        entry.InstallerType = Manifest::InstallerTypeEnum::Portable;\r\n        entry.ProductCode = GetProductCode();\r\n\r\n        return entry;\r\n    }\r\n\r\n    void PortableInstaller::SetExpectedState()\r\n    {\r\n        const auto& indexPath = InstallLocation / GetPortableIndexFileName();\r\n\r\n        if (std::filesystem::exists(indexPath))\r\n        {\r\n            PortableIndex portableIndex = PortableIndex::Open(indexPath.u8string(), SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n            m_expectedEntries = portableIndex.GetAllPortableFiles();\r\n        }\r\n        else\r\n        {\r\n            std::filesystem::path targetFullPath = PortableTargetFullPath;\r\n            std::filesystem::path symlinkFullPath = PortableSymlinkFullPath;\r\n\r\n            // Order matters here so that file entries are removed before symlink entries during uninstall from registry.\r\n            // This is to ensure that the directory is fully uninstalled before attempting to remove from PATH registry.\r\n            if (!targetFullPath.empty())\r\n            {\r\n                m_expectedEntries.emplace_back(std::move(PortableFileEntry::CreateFileEntry({}, targetFullPath, SHA256)));\r\n            }\r\n\r\n            if (!symlinkFullPath.empty())\r\n            {\r\n                m_expectedEntries.emplace_back(std::move(PortableFileEntry::CreateSymlinkEntry(symlinkFullPath, targetFullPath)));\r\n            }\r\n        }\r\n    }\r\n\r\n    PortableInstaller::PortableInstaller(Manifest::ScopeEnum scope, Utility::Architecture arch, const std::string& productCode) :\r\n        m_portableARPEntry(PortableARPEntry(scope, arch, productCode))\r\n    {\r\n        if (ARPEntryExists())\r\n        {\r\n            DisplayName = GetStringValue(PortableValueName::DisplayName);\r\n            DisplayVersion = GetStringValue(PortableValueName::DisplayVersion);\r\n            HelpLink = GetStringValue(PortableValueName::HelpLink);\r\n            InstallDate = GetStringValue(PortableValueName::InstallDate);\r\n            Publisher = GetStringValue(PortableValueName::Publisher);\r\n            SHA256 = GetStringValue(PortableValueName::SHA256);\r\n            URLInfoAbout = GetStringValue(PortableValueName::URLInfoAbout);\r\n            UninstallString = GetStringValue(PortableValueName::UninstallString);\r\n            WinGetInstallerType = GetStringValue(PortableValueName::WinGetInstallerType);\r\n            WinGetPackageIdentifier = GetStringValue(PortableValueName::WinGetPackageIdentifier);\r\n            WinGetSourceIdentifier = GetStringValue(PortableValueName::WinGetSourceIdentifier);\r\n            InstallLocation = GetPathValue(PortableValueName::InstallLocation);\r\n            PortableSymlinkFullPath = GetPathValue(PortableValueName::PortableSymlinkFullPath);\r\n            PortableTargetFullPath = GetPathValue(PortableValueName::PortableTargetFullPath);\r\n            InstallDirectoryAddedToPath = GetBoolValue(PortableValueName::InstallDirectoryAddedToPath);\r\n            InstallDirectoryCreated = GetBoolValue(PortableValueName::InstallDirectoryCreated);\r\n        }\r\n        \r\n        SetExpectedState();\r\n    }\r\n\r\n    void PortableInstaller::RegisterARPEntry()\r\n    {\r\n        CommitToARPEntry(PortableValueName::WinGetPackageIdentifier, WinGetPackageIdentifier);\r\n        CommitToARPEntry(PortableValueName::WinGetSourceIdentifier, WinGetSourceIdentifier);\r\n        CommitToARPEntry(PortableValueName::UninstallString, \"winget uninstall --product-code \" + GetProductCode());\r\n        CommitToARPEntry(PortableValueName::WinGetInstallerType, InstallerTypeToString(Manifest::InstallerTypeEnum::Portable));\r\n        CommitToARPEntry(PortableValueName::DisplayName, DisplayName);\r\n        CommitToARPEntry(PortableValueName::DisplayVersion, DisplayVersion);\r\n        CommitToARPEntry(PortableValueName::Publisher, Publisher);\r\n        CommitToARPEntry(PortableValueName::InstallDate, InstallDate);\r\n        CommitToARPEntry(PortableValueName::URLInfoAbout, URLInfoAbout);\r\n        CommitToARPEntry(PortableValueName::HelpLink, HelpLink);\r\n    }\r\n\r\n    std::string PortableInstaller::GetStringValue(PortableValueName valueName)\r\n    {\r\n        if (m_portableARPEntry[valueName].has_value())\r\n        {\r\n            return m_portableARPEntry[valueName]->GetValue<Value::Type::String>();\r\n        }\r\n        else\r\n        {\r\n            return {};\r\n        }\r\n    }\r\n\r\n    std::filesystem::path PortableInstaller::GetPathValue(PortableValueName valueName)\r\n    {\r\n        if (m_portableARPEntry[valueName].has_value())\r\n        {\r\n            return m_portableARPEntry[valueName]->GetValue<Value::Type::UTF16String>();\r\n        }\r\n        {\r\n            return {};\r\n        }\r\n    }\r\n\r\n    bool PortableInstaller::GetBoolValue(PortableValueName valueName)\r\n    {\r\n        if (m_portableARPEntry[valueName].has_value())\r\n        {\r\n            return m_portableARPEntry[valueName]->GetValue<Value::Type::DWord>();\r\n        }\r\n        else\r\n        {\r\n            return false;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/PortableInstaller.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"winget/PortableARPEntry.h\"\r\n#include \"winget/PortableFileEntry.h\"\r\n#include <Workflows/WorkflowBase.h>\r\n#include <filesystem>\r\n\r\nusing namespace AppInstaller::Registry::Portable;\r\n\r\nnamespace AppInstaller::CLI::Portable\r\n{\r\n    std::filesystem::path GetPortableLinksLocation(Manifest::ScopeEnum scope);\r\n\r\n    std::filesystem::path GetPortableInstallRoot(Manifest::ScopeEnum scope, Utility::Architecture arch);\r\n\r\n    // Object representation of the metadata and functionality required for installing a Portable package. \r\n    struct PortableInstaller\r\n    {\r\n        // These values are initialized based on the values from the entry in ARP\r\n        std::string DisplayName;\r\n        std::string DisplayVersion;\r\n        std::string HelpLink;\r\n        std::string InstallDate;\r\n        std::filesystem::path InstallLocation;\r\n        std::filesystem::path PortableSymlinkFullPath;\r\n        std::filesystem::path PortableTargetFullPath;\r\n        std::string Publisher;\r\n        std::string SHA256;\r\n        std::string URLInfoAbout;\r\n        std::string UninstallString;\r\n        std::string WinGetInstallerType;\r\n        std::string WinGetPackageIdentifier;\r\n        std::string WinGetSourceIdentifier;\r\n        bool InstallDirectoryCreated = false;\r\n        bool BinariesDependOnPath = false;\r\n        // If we fail to create a symlink, add install directory to PATH variable\r\n        bool InstallDirectoryAddedToPath = false;\r\n\r\n        bool IsUpdate = false;\r\n        bool Purge = false;\r\n        bool RecordToIndex = false;\r\n\r\n        // This is the incoming target install location determined from the context args.\r\n        std::filesystem::path TargetInstallLocation;\r\n\r\n        PortableInstaller(Manifest::ScopeEnum scope, Utility::Architecture arch, const std::string& productCode);\r\n\r\n        bool VerifyExpectedState();\r\n\r\n        void SetDesiredState(const std::vector<AppInstaller::Portable::PortableFileEntry>& desiredEntries)\r\n        {\r\n            m_desiredEntries = desiredEntries;\r\n        };\r\n\r\n        void PrepareForCleanUp()\r\n        {\r\n            m_expectedEntries = m_desiredEntries;\r\n            m_desiredEntries = {};\r\n        }\r\n\r\n        void Install(AppInstaller::CLI::Workflow::OperationType operation = Workflow::OperationType::Install);\r\n\r\n        void Uninstall();\r\n\r\n        template<typename T>\r\n        void CommitToARPEntry(PortableValueName valueName, T value)\r\n        {\r\n            m_portableARPEntry.SetValue(valueName, value);\r\n        }\r\n\r\n        std::filesystem::path GetPortableIndexFileName()\r\n        {\r\n            return Utility::ConvertToUTF16(GetProductCode() + \".db\");\r\n        }\r\n\r\n        Manifest::ScopeEnum GetScope() { return m_portableARPEntry.GetScope(); };\r\n\r\n        Utility::Architecture GetArch() { return m_portableARPEntry.GetArchitecture(); };\r\n\r\n        std::string GetProductCode() { return m_portableARPEntry.GetProductCode(); };\r\n\r\n        bool ARPEntryExists() { return m_portableARPEntry.Exists(); };\r\n\r\n        std::string GetOutputMessage()\r\n        {\r\n            return m_stream.str();\r\n        }\r\n\r\n        void SetAppsAndFeaturesMetadata(\r\n            const Manifest::Manifest& manifest,\r\n            const std::vector<AppInstaller::Manifest::AppsAndFeaturesEntry>& entries);\r\n\r\n        AppInstaller::Manifest::AppsAndFeaturesEntry GetAppsAndFeaturesEntry();\r\n\r\n    private:\r\n        PortableARPEntry m_portableARPEntry;\r\n        std::vector<AppInstaller::Portable::PortableFileEntry> m_desiredEntries;\r\n        std::vector<AppInstaller::Portable::PortableFileEntry> m_expectedEntries;\r\n        std::stringstream m_stream;\r\n\r\n        std::string GetStringValue(PortableValueName valueName);\r\n        std::filesystem::path GetPathValue(PortableValueName valueName);\r\n        bool GetBoolValue(PortableValueName valueName);\r\n\r\n        void SetExpectedState();\r\n        void RegisterARPEntry();\r\n\r\n        void ApplyDesiredState();\r\n        void InstallFile(AppInstaller::Portable::PortableFileEntry& desiredState);\r\n        void RemoveFile(AppInstaller::Portable::PortableFileEntry& desiredState);\r\n\r\n        void CreateTargetInstallDirectory();\r\n        void RemoveInstallDirectory();\r\n\r\n        void AddToPathVariable(std::filesystem::path value);\r\n        void RemoveFromPathVariable(std::filesystem::path value);\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/PropertySheet.props",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ImportGroup Label=\"PropertySheets\" />\n  <PropertyGroup Label=\"UserMacros\" />\n    <!--\n    To customize common C++/WinRT project properties: \n    * right-click the project node\n    * expand the Common Properties item\n    * select the C++/WinRT property page\n\n    For more advanced scenarios, and complete documentation, please see:\n    https://github.com/Microsoft/xlang/tree/master/src/package/cppwinrt/nuget \n    -->\n  <PropertyGroup />\n  <ItemDefinitionGroup />\n</Project>"
  },
  {
    "path": "src/AppInstallerCLICore/Public/AppInstallerCLICore.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    // The core function to act against command line input.\r\n    int CoreMain(int argc, wchar_t const** argv);\r\n\r\n    // Initializes the Windows Package Manager COM server.\r\n    void ServerInitialize();\r\n\r\n    // Initializations for InProc invocation.\r\n    void InProcInitialize();\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Public/ConfigurationSetProcessorFactoryRemoting.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <Windows.h>\r\n#include <winrt/Microsoft.Management.Configuration.h>\r\n\r\nnamespace AppInstaller::CLI::ConfigurationRemoting\r\n{\r\n    // The processor engine being used by the factory.\r\n    enum class ProcessorEngine\r\n    {\r\n        // An unknown processor.\r\n        Unknown,\r\n        // Uses PowerShell DSC v2.\r\n        PowerShell,\r\n        // Uses DSC v3.\r\n        DSCv3,\r\n    };\r\n\r\n    std::wstring_view ToString(ProcessorEngine value);\r\n\r\n    // Determines the appropriate processor engine to use for the given configuration set.\r\n    ProcessorEngine DetermineProcessorEngine(winrt::Microsoft::Management::Configuration::ConfigurationSet set);\r\n\r\n    // Creates a factory in another process\r\n    winrt::Microsoft::Management::Configuration::IConfigurationSetProcessorFactory CreateOutOfProcessFactory(ProcessorEngine processorEngine, bool useRunAs = false, const std::string& properties = {}, const std::string& restrictions = {});\r\n\r\n    // Creates a factory that can route configurations to the appropriate internal factory.\r\n    winrt::Microsoft::Management::Configuration::IConfigurationSetProcessorFactory CreateDynamicRuntimeFactory(ProcessorEngine processorEngine);\r\n\r\n    // The property names used with IMap property semantics of remote factories.\r\n    enum class PropertyName\r\n    {\r\n        // The path to the dsc.exe executable.\r\n        // Read / Write\r\n        DscExecutablePath,\r\n        // The path to the dsc.exe executable, as discovered.\r\n        // Read only.\r\n        FoundDscExecutablePath,\r\n        // Whether to request detailed traces from the processor.\r\n        // Read / Write\r\n        DiagnosticTraceEnabled,\r\n        // Getting this value pumps the state machine to determine the best DSC to use.\r\n        // We must respond to the value it returns to properly transition states.\r\n        // Read only.\r\n        FindDscStateMachine,\r\n    };\r\n\r\n    // Gets the string for a property name.\r\n    winrt::hstring ToHString(PropertyName name);\r\n}\r\n\r\n// Export for use by the out of process factory server to report its initialization.\r\nHRESULT WindowsPackageManagerConfigurationCompleteOutOfProcessFactoryInitialization(HRESULT result, void* factory, LPWSTR staticsCallback, LPWSTR completionEventName, DWORD parentProcessId);\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Public/ShutdownMonitoring.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <Windows.h>\r\n#include <AppInstallerProgress.h>\r\n#include <wil/resource.h>\r\n#include <memory>\r\n#include <mutex>\r\n#include <optional>\r\n\r\nnamespace AppInstaller::ShutdownMonitoring\r\n{\r\n    // Type to contain the CTRL signal and window messages handler.\r\n    struct TerminationSignalHandler\r\n    {\r\n        TerminationSignalHandler();\r\n\r\n        ~TerminationSignalHandler();\r\n\r\n        // Gets the singleton handler.\r\n        static std::shared_ptr<TerminationSignalHandler> Instance();\r\n\r\n        // Add a termination listener.\r\n        void AddListener(ICancellable* cancellable);\r\n\r\n        // Remove a termination listener.\r\n        void RemoveListener(ICancellable* cancellable);\r\n\r\n        // Add or remove the listener based on `enabled`.\r\n        static void EnableListener(bool enabled, ICancellable* cancellable);\r\n\r\n        // Gets whether the signal handler is enabled.\r\n        static bool Enabled();\r\n\r\n        // Sets whether the signal handler is enabled; the default is true.\r\n        // When set to false, the signal handler instance will not create signal listeners when created.\r\n        static void Enabled(bool enabled);\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        // Gets the window handle for the message window.\r\n        HWND GetWindowHandle() const;\r\n#endif\r\n\r\n    private:\r\n        void StartAppShutdown();\r\n\r\n        static BOOL WINAPI StaticCtrlHandlerFunction(DWORD ctrlType);\r\n\r\n        static LRESULT WINAPI WindowMessageProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);\r\n\r\n        BOOL CtrlHandlerFunction(DWORD ctrlType);\r\n\r\n        // Terminates the currently attached contexts.\r\n        // Returns FALSE if no contexts attached; TRUE otherwise.\r\n        BOOL InformListeners(CancelReason reason, bool force);\r\n\r\n        void CreateWindowAndStartMessageLoop();\r\n\r\n        std::mutex m_listenersLock;\r\n        std::vector<ICancellable*> m_listeners;\r\n        wil::unique_event m_messageQueueReady;\r\n        wil::unique_hwnd m_windowHandle;\r\n        std::thread m_windowThread;\r\n    };\r\n\r\n    // Coordinates shutdown across server components\r\n    struct ServerShutdownSynchronization\r\n    {\r\n        using ShutdownCompleteCallback = void (*)();\r\n\r\n        // Initializes the monitoring system and sets up a callback to be invoked when shutdown is completed.\r\n        static void Initialize(ShutdownCompleteCallback callback, bool createTerminationSignalHandler = true);\r\n\r\n        // \"Interface\" for a single component to synchronize with.\r\n        struct ComponentSystem\r\n        {\r\n            // Initiate the shutdown process.\r\n            // Components are expected to set flags to prevent any further work from beginning and return as quickly as possible.\r\n            void (*BlockNewWork)(CancelReason reason) = nullptr;\r\n\r\n            // Components are expected to cancel active or pending work as asynchronously as possible.\r\n            void (*BeginShutdown)(CancelReason reason) = nullptr;\r\n\r\n            // Components wait until all active and pending work have completed their \r\n            void (*Wait)() = nullptr;\r\n        };\r\n\r\n        // Adds a component to the system.\r\n        static void AddComponent(const ComponentSystem& component);\r\n\r\n        // Waits for the shutdown to complete.\r\n        static bool WaitForShutdown(std::optional<DWORD> timeout = std::nullopt);\r\n\r\n    private:\r\n        ServerShutdownSynchronization() = default;\r\n        ~ServerShutdownSynchronization();\r\n\r\n        friend TerminationSignalHandler;\r\n\r\n        static ServerShutdownSynchronization& Instance();\r\n\r\n        // Runs the actual shutdown process and invokes the callback.\r\n        void SynchronizeShutdown(CancelReason reason);\r\n\r\n        // Listens for a termination signal.\r\n        void Signal(CancelReason reason);\r\n\r\n        ShutdownCompleteCallback m_callback = nullptr;\r\n        std::mutex m_componentsLock;\r\n        std::vector<ComponentSystem> m_components;\r\n        std::mutex m_threadLock;\r\n        std::thread m_shutdownThread;\r\n        wil::slim_event_manual_reset m_shutdownComplete;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Resources.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Resources.h\"\r\n\r\nusing namespace AppInstaller::Utility::literals;\r\n\r\nnamespace AppInstaller::CLI::Resource\r\n{\r\n    Utility::LocIndView GetFixedString(FixedString fs)\r\n    {\r\n        switch (fs)\r\n        {\r\n        case FixedString::ProductName: return \"Windows Package Manager\"_liv;\r\n        }\r\n\r\n        THROW_HR(E_UNEXPECTED);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Resources.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/Resources.h>\r\n\r\n#include <winrt/Windows.ApplicationModel.Resources.h>\r\n\r\n#include <iostream>\r\n\r\nnamespace AppInstaller::CLI::Resource\r\n{\r\n    using AppInstaller::StringResource::StringId;\r\n    using AppInstaller::Resource::LocString;\r\n\r\n    // Resource string identifiers.\r\n    // This list can mostly be generated by the following PowerShell:\r\n    //  > [xml]$res = Get-Content <winget.resw file path>\r\n    //  > $res.root.data.name | % { \"WINGET_DEFINE_RESOURCE_STRINGID($_);\" }\r\n    //\r\n    struct String\r\n    {\r\n        WINGET_DEFINE_RESOURCE_STRINGID(AcceptPackageAgreementsArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(AcceptSourceAgreementsArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(AdjoinedNotFlagError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(AdjoinedNotFoundError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(AdminSettingDisabled);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(AdminSettingDisableDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(AdminSettingEnabled);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(AdminSettingEnableDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(AdminSettingHeader);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(AllowRebootArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ArchitectureArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ArchiveFailedMalwareScan);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ArchiveFailedMalwareScanOverridden);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ArgumentForSinglePackageProvidedWithMultipleQueries);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(AuthenticationAccountArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(AuthenticationModeArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(AvailableArguments);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(AvailableCommandAliases);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(AvailableCommands);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(AvailableHeader);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(AvailableOptions);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(AvailableSubcommands);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(AvailableUpgrades);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(BothManifestAndSearchQueryProvided);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(Cancelled);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(CancellingOperation);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ChannelArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ClientVersionMismatchError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(Command);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(CommandArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(CommandDoesNotSupportResumeMessage);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(CommandLineArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(CommandRequiresAdmin);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(CompleteCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(CompleteCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationAcceptWarningArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationAllUsersElevated);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationApply);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationApplyingUnit);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationAssert);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationDependencies);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationDescriptionWasTruncated);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationExportAddingToFile);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationExportFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationExportFailedToGetUnitProcessors);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationExportingUnit);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationExportInstallRequiredModule);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationExportInstallRequiredModuleFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationExportSuccessful);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationExportUnitStart);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationExportUnitFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationFailedToApply);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationFailedToGetDetails);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationFailedToTest);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationFieldInvalidType);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationFieldInvalidValue);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationFieldMissing);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationFileArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationFileEmpty);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationFileInvalid);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationFileInvalidYAML);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationFileVersionUnknown);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationGettingDetails);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationGettingResourceSettings);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationGettingUnitProcessors);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationHistoryEmpty);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationHistoryItemArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationHistoryItemNotFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationHistoryRemoveArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationInDesiredState);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationInform);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationInitializing);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationInstallDscPackage);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationInstallDscPackageFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationLocal);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationModuleNameOnly);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationModulePath);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationModulePathArgError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationModules);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationModuleWithDetails);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationNoTestRun);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationNotInDesiredState);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationProcessorPath);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationReadingConfigFile);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationSetStateCompleted);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationSetStateInProgress);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationSetStatePending);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationSetStateUnknown);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationSettings);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationStatusWatchArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationSuccessfullyApplied);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitSuccessfullyApplied);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationSuppressPrologueArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnexpectedTestResult);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitAssertHadNegativeResult);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitFailedConfigSet);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitFailedDuringGet);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitFailedDuringSet);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitFailedDuringTest);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitFailedInternal);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitFailedPrecondition);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitFailedSystemState);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitFailedUnitProcessing);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitHasDuplicateIdentifier);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitHasMissingDependency);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitImportModuleAdmin);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitIsPartOfDependencyCycle);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitManuallySkipped);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitModuleConflict);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitModuleImportFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitModuleNotProvidedWarning);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitMultipleMatches);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitNeedsPrereleaseWarning);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitNotFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitNotFoundInModule);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitNotInCatalogWarning);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitNotPublicWarning);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitNotRunDueToDependency);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitNotRunDueToFailedAssert);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitReturnedInvalidResult);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitSettingConfigRoot);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitSkipped);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitStateCompleted);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitStateInProgress);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitStatePending);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitStateSkipped);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationUnitStateUnknown);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationValidationFoundNoIssues);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationWaitingOnAnother);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationWarning);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationWarningPromptApply);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationWarningPromptTest);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationWarningSetViewTruncated);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigurationWarningValueTruncated);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureExportAll);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureExportArgumentConflictWithAllError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureExportArgumentRequiredError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureExportCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureExportCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureExportModule);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureExportPackageId);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureExportResource);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureExportUnitDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureExportUnitInstallDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureListApplyBegun);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureListApplyEnded);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureListCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureListCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureListFirstApplied);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureListIdentifier);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureListName);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureListOrigin);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureListPath);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureListResult);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureListResultDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureListState);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureListUnit);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureShowCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureShowCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureTestCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureTestCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureValidateCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConfigureValidateCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ConvertInstallFlowToUpgrade);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(CorrelationArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(CountArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(CountOutOfBoundsError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(CustomSwitchesArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DependenciesFlowContainsLoop);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DependenciesFlowDownload);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DependenciesFlowInstall);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DependenciesFlowNoInstallerFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DependenciesFlowNoMatches);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DependenciesFlowNoMinVersion);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DependenciesFlowNoSuitableInstallerFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DependenciesFlowPackageVersionNotFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DependenciesFlowSourceNotFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DependenciesFlowSourceTooManyMatches);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DependenciesManagementError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DependenciesManagementExitMessage);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DependenciesSkippedMessage);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DependencyArgumentMissing);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DependencySourceArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DisableAdminSettingFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DisabledByGroupPolicy);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DisableInteractivityArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(Done);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DownloadCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DownloadCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DownloadDirectoryArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(Downloading);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscAdminSettingsResourceShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscAdminSettingsResourceLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscPackageResourceShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscPackageResourceLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourceFunctionDescriptionGet);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourceFunctionDescriptionSet);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourceFunctionDescriptionWhatIf);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourceFunctionDescriptionTest);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourceFunctionDescriptionDelete);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourceFunctionDescriptionExport);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourceFunctionDescriptionValidate);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourceFunctionDescriptionResolve);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourceFunctionDescriptionAdapter);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourceFunctionDescriptionSchema);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourceFunctionDescriptionManifest);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourcePropertyDescriptionExist);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourcePropertyDescriptionInDesiredState);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourcePropertyDescriptionAcceptAgreements);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourcePropertyDescriptionAdminSettingsSettings);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourcePropertyDescriptionPackageId);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourcePropertyDescriptionPackageSource);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourcePropertyDescriptionPackageVersion);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourcePropertyDescriptionPackageScope);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourcePropertyDescriptionPackageMatchOption);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourcePropertyDescriptionPackageUseLatest);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourcePropertyDescriptionPackageInstallMode);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscUserSettingsFileShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscUserSettingsFileLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourcePropertyDescriptionUserSettingsFileSettings);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourcePropertyDescriptionUserSettingsFileAction);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourcePropertyDescriptionSourceName);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourcePropertyDescriptionSourceArgument);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourcePropertyDescriptionSourceType);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourcePropertyDescriptionSourceTrustLevel);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourcePropertyDescriptionSourceExplicit);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscResourcePropertyDescriptionSourcePriority);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscSourceResourceShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DscSourceResourceLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(EnableAdminSettingFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(EnableWindowsFeaturesSuccess);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(EnablingWindowsFeature);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ErrorCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ErrorCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ErrorInputArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ErrorNumberIsTooLarge);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExactArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExperimentalArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExperimentalCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExperimentalCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExportCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExportCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExportedPackageRequiresLicenseAgreement);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExportIncludeVersionsArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExportSourceArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExtendedFeaturesDisabledMessage);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExtendedFeaturesDisableMessage);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExtendedFeaturesDisablingMessage);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExtendedFeaturesEnableArgumentError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExtendedFeaturesEnabledMessage);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExtendedFeaturesEnableMessage);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExtendedFeaturesEnablingMessage);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExtendedFeaturesNotEnabledMessage);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExternalDependencies);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExtractArchiveFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExtractArchiveSucceeded);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExtractingArchive);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExtraPositionalError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FailedToEnableWindowsFeature);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FailedToEnableWindowsFeatureOverridden);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FailedToEnableWindowsFeatureOverrideRequired);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FailedToInitiateReboot);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FailedToRefreshPathWarning);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FeatureDisabledByAdminSettingMessage);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FeatureDisabledMessage);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FeaturesCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FeaturesCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FeaturesDisabled);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FeaturesEnabled);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FeaturesFeature);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FeaturesLink);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FeaturesMessage);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FeaturesMessageDisabledByBuild);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FeaturesMessageDisabledByPolicy);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FeaturesProperty);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FeaturesStatus);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FileArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FileNotFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FilesRemainInInstallDirectory);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FlagContainAdjoinedError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FontAlreadyInstalled);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FontCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FontCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FontFace);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FontFaces);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FontFamily);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FontFamilyNameArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FontFileNotSupported);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FontDetailsArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FontFilePaths);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FontInstallFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FontListCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FontListCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FontPackage);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FontRollbackFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FontStatus);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FontStatusCorrupt);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FontStatusOK);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FontStatusUnknown);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FontTitle);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FontUninstallFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FontValidationFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FontVersion);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FontWinGetSupported);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ForceArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(GatedVersionArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(GetManifestResultVersionNotFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(HashCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(HashCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(HashOverrideArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(HeaderArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(HeaderArgumentNotApplicableForNonRestSourceWarning);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(HeaderArgumentNotApplicableWithoutSource);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(HelpArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(HelpForDetails);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(HelpLinkPreamble);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(IdArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(IgnoreLocalArchiveMalwareScanArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(IgnoreResumeLimitArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(IgnoreWarningsArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ImportCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ImportCommandReportDependencies);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ImportCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ImportFileArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ImportFileHasInvalidSchema);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ImportIgnorePackageVersionsArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ImportIgnoreUnavailableArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ImportInstallFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ImportSourceNotInstalled);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(IncludePinnedArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(IncludePinnedInListArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(IncludeUnknownArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(IncludeUnknownInListArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(IncompatibleArgumentsProvided);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InitiatingReboot);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallAbandoned);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallationDisclaimer1);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallationDisclaimer2);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallationDisclaimerMSStore);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstalledPackageNotAvailable);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstalledPackageVersionNotAvailable);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstalledScopeArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerAbortsTerminal);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerBlockedByPolicy);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerDownloadAuthenticationFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerDownloadAuthenticationNotSupported);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerDownloadCommandProhibited);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerDownloaded);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerDownloadRequiresAuthentication);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerDownloads);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerElevationExpected);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerFailedSecurityCheck);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerFailedVirusScan);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerFailedWithCode);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerHashMismatchAdminBlock);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerHashMismatchError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerHashMismatchOverridden);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerHashMismatchOverrideRequired);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerHashVerified);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerLogAvailable);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerProhibitsElevation);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerRequiresInstallLocation);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallersAbortTerminal);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallersRequireInstallLocation);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerTypeArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerZeroByteFile);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowInstallSuccess);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowRegistrationDeferred);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodeAlreadyInstalled);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodeBlockedByPolicy);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodeCancelledByUser);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodeContactSupport);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodeCustomError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodeDiskFull);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodeDowngrade);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodeFileInUse);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodeInstallInProgress);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodeInsufficientMemory);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodeInvalidParameter);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodeMissingDependency);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodeNoNetwork);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodePackageInUse);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodePackageInUseByApplication);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodeRebootInitiated);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodeRebootRequiredForInstall);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodeRebootRequiredToFinish);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowReturnCodeSystemNotSupported);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallFlowStartingPackageInstall);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallFullPackageDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallLocationNotProvided);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallScopeDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallStubPackageDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallWaitingOnAnother);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InteractiveArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InvalidAliasError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InvalidArgumentSpecifierError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InvalidArgumentValueError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InvalidArgumentValueErrorWithoutValidValues);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InvalidArgumentWithoutQueryError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InvalidJsonFile);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InvalidNameError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InvalidPathToNestedInstaller);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(KeyDirectoriesHeader);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(LicenseAgreement);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(Links);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ListCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ListCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ListDetailsArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(LocaleArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(LocationArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(LogArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(Logs);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MainCopyrightNotice);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MainHomepage);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ManifestArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ManifestValidationFail);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ManifestValidationSuccess);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ManifestValidationWarning);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(McpCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(McpCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(McpConfigurationPreamble);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MissingArgumentError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ModifiedPathRequiresShellRestart);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MonikerArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MsixArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MsixSignatureHashFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MSStoreAppBlocked);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MSStoreDownloadAuthenticationNotice);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MSStoreDownloadDependencyPackages);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MSStoreDownloadGetDownloadInfo);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MSStoreDownloadGetDownloadInfoFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MSStoreDownloadGetLicense);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MSStoreDownloadGetLicenseFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MSStoreDownloadGetLicenseForbidden);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MSStoreDownloadGetLicenseSuccess);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MSStoreDownloadMainPackages);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MSStoreDownloadMultiplePackagesNotice);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MSStoreDownloadNoApplicablePackageFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MSStoreDownloadPackageDownloaded);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MSStoreDownloadPackageDownloadFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MSStoreDownloadPackageDownloadNotSupported);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MSStoreDownloadPackageDownloadSuccess);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MSStoreDownloadPackageHashMismatch);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MSStoreDownloadPackageHashVerified);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MSStoreDownloadRenameNotSupported);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MSStoreInstallOrUpdateFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MSStoreInstallTryGetEntitlement);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MSStoreRepairFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MSStoreStoreClientBlocked);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MultipleExclusiveArgumentsProvided);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MultipleInstalledPackagesFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MultiplePackagesFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MultiplePackagesFoundFilteredBySourcePriority);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MultipleUnsupportedNestedInstallersSpecified);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MultiQueryArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MultiQueryPackageAlreadyInstalled);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MultiQueryPackageNotFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MultiQuerySearchFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MultiQuerySearchFoundMultiple);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(NameArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(NestedInstallerNotFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(NestedInstallerNotSpecified);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(NestedInstallerNotSupported);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(NoAdminRepairForUserScopePackage);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(NoApplicableInstallers);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(NoExperimentalFeaturesMessage);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(NoInstalledFontFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(NoInstalledPackageFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(NoPackageFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(NoPackageSelectionArgumentProvided);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(NoPackagesFoundInImportFile);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(NoProxyArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(NoProgressArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(NoRepairInfoFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(Notes);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(NoUninstallInfoFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(NoUpgradeArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(NoVTArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(OpenLogsArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(OpenSourceFailedNoMatch);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(OpenSourceFailedNoMatchHelp);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(OpenSourceFailedNoSourceDefined);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(Options);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(OSVersionDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(OutputDirectoryArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(OutputFileArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(OverrideArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(OverwritingExistingFileAtMessage);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(Package);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PackageAgreementsNotAgreedTo);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PackageAgreementsPrompt);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PackageAlreadyInstalled);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PackageDependencies);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PackageIsPinned);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PackageRequiresDependencies);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PendingWorkError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinAddBlockingArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinAddCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinAddCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinAdded);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinAlreadyExists);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinCannotOpenIndex);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinDoesNotExist);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinExistsOverwriting);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinExistsUseForceArg);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinInstalledArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinInstalledSource);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinListCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinListCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinNoPinsExist);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinRemoveCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinRemoveCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinRemovedSuccessfully);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinResetCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinResetCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinResetSuccessful);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinResettingAll);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinResetUseForceArg);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinType);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PinVersion);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PlatformArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PoliciesPolicy);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PortableAliasAdded);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PortableHashMismatchOverridden);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PortableHashMismatchOverrideRequired);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PortableInstallFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PortableLinksMachine);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PortableLinksUser);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PortablePackageAlreadyExists);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PortableRegistryCollisionOverridden);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PortableRoot);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PortableRoot86);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PortableRootUser);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PositionArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PreserveArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PressEnterToContinue);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PrivacyStatement);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ProductCodeArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PromptForInstallRoot);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PromptOptionNo);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PromptOptionYes);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PromptToProceed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ProxyArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PurgeArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(PurgeInstallDirectory);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(QueryArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(RainbowArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(RebootRequiredToEnableWindowsFeatureOverridden);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(RebootRequiredToEnableWindowsFeatureOverrideRequired);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(RelatedLink);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(RenameArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(RepairAbandoned);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(RepairCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(RepairCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(RepairDifferentInstallTechnology);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(RepairFailedWithCode);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(RepairFlowNoMatchingVersion);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(RepairFlowRepairSuccess);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(RepairFlowReturnCodeSystemNotSupported);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(RepairFlowStartingPackageRepair);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(RepairOperationNotSupported);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ReparsePointsNotSupportedError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ReportIdentityForAgreements);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ReportIdentityFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(RequiredArgError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ReservedFilenameError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ResetAdminSettingFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ResetAdminSettingSucceeded);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ResetAllAdminSettingsArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ResetAllAdminSettingsSucceeded);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ResumeCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ResumeCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ResumeIdArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ResumeIdNotFoundError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ResumeLimitExceeded);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ResumeStateDataNotFoundError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(RetroArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SearchCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SearchCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SearchFailureError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SearchFailureErrorListMatches);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SearchFailureErrorNoMatches);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SearchFailureWarning);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SearchId);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SearchMatch);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SearchName);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SearchSource);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SearchTruncated);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SearchVersion);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SeeLineAndColumn);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SetAdminSettingFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SetAdminSettingSucceeded);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SettingLoadFailure);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SettingNameArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SettingsCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SettingsCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SettingsExportCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SettingsExportCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SettingsResetCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SettingsResetCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SettingsSetCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SettingsSetCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SettingsWarningField);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SettingsWarnings);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SettingsWarningValue);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SettingValueArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowChannel);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelAgreements);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelAuthor);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelChannel);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelCopyright);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelCopyrightUrl);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelDependencies);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelDocumentation);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelExternalDependencies);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelInstallationNotes);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelInstaller);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelInstallerLocale);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelInstallerOfflineDistributionSupported);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelInstallerProductId);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelInstallerReleaseDate);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelInstallerSha256);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelInstallerType);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelInstallerUrl);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelLicense);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelLicenseUrl);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelMoniker);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelPackageDependencies);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelPackageUrl);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelPrivacyUrl);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelPublisher);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelPublisherSupportUrl);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelPublisherUrl);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelPurchaseUrl);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelReleaseNotes);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelReleaseNotesUrl);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelTags);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelVersion);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelWindowsFeaturesDependencies);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowLabelWindowsLibrariesDependencies);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowListAvailableUpgrades);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowListInstalledArchitecture);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowListInstalledLocale);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowListInstalledLocation);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowListInstalledScope);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowListInstalledSource);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowListInstallerCategory);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowListLocalIdentifier);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowListPackageFamilyName);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowListProductCode);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowListUpgradeCode);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShowVersion);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SilentArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SingleCharAfterDashError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SkipDependenciesArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DependenciesOnlyArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DependenciesOnlyMessage);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SkipMicrosoftStorePackageLicenseArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceAddAlreadyExistsDifferentArg);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceAddAlreadyExistsDifferentName);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceAddAlreadyExistsMatch);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceAddBegin);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceAddCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceAddCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceAddFailedAuthenticationNotSupported);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceAddOpenSourceFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceAgreementsMarketMessage);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceAgreementsNotAgreedTo);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceAgreementsPrompt);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceAgreementsTitle);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceArgArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceEditCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceEditCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceEditExplicitArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceEditNewValue);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceEditNoChanges);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceEditOldValue);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceEditOne);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceExplicitArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceExportCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceExportCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceListAdditionalSource);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceListAllowedSource);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceListArg);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceListCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceListCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceListData);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceListExplicit);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceListField);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceListIdentifier);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceListName);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceListNoneFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceListNoSources);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceListPriority);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceListTrustLevel);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceListType);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceListUpdated);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceListUpdatedNever);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceListValue);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceNameArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceOpenFailedSuggestion);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceOpenPredefinedFailedSuggestion);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceOpenWithFailedUpdate);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourcePriorityArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceRemoveAll);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceRemoveCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceRemoveCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceRemoveOne);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceRequiresAuthentication);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceResetAll);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceResetCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceResetCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceResetForceArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceResetListAndOverridePreamble);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceResetOne);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceTrustLevelArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceTypeArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceUpdateAll);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceUpdateCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceUpdateCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SourceUpdateOne);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(StateDisabled);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(StateEnabled);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(StateHeader);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SystemArchitecture);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(TagArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(TargetVersionArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ThankYou);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ThirdPartSoftwareNotices);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ToolDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ToolInfoArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ToolVersionArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(TooManyArgError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(TooManyBehaviorsError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UnableToPurgeInstallDirectory);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(Unavailable);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UnexpectedErrorExecutingCommand);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UninstallAbandoned);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UninstallAllVersionsArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UninstallCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UninstallCommandReportDependencies);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UninstallCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UninstallFailedDueToMultipleVersions);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UninstallFailedWithCode);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UninstallFlowStartingPackageUninstall);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UninstallFlowUninstallSuccess);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UninstallPreviousArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UnrecognizedCommand);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UnsupportedArgument);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UpdateAllArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UpdateNoPackagesFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UpdateNoPackagesFoundReason);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UpdateNotApplicable);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UpdateNotApplicableReason);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UpgradeArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UpgradeAvailableForPinned);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UpgradeBlockedByManifest);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UpgradeBlockedByPinCount);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UpgradeCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UpgradeCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UpgradeDifferentInstallTechnology);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UpgradeDifferentInstallTechnologyInNewerVersions);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UpgradeIsPinned);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UpgradePinnedByUserCount);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UpgradeRequireExplicitCount);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UpgradeUnknownVersionCount);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UpgradeUnknownVersionExplanation);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UriNotWellFormed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UriSchemeNotSupported);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(Usage);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UserSettings);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ValidateCommandLongDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ValidateCommandReportDependencies);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ValidateCommandShortDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ValidateManifestArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(VerboseLogsArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(VerifyFileFailedIsDirectory);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(VerifyFileFailedNotExist);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(VerifyFileSignedMsix);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(VerifyPathFailedNotExist);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(VersionArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(VersionsArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(WaitArgumentDescription);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(WindowsFeatureNotFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(WindowsFeaturesDependencies);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(WindowsLibrariesDependencies);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(WindowsPackageManager);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(WindowsPackageManagerPreview);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(WindowsStoreTerms);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(WinGetResourceUnitBothPackageVersionAndUseLatest);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(WinGetResourceUnitDependencySourceNotConfigured);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(WinGetResourceUnitDependencySourceNotDeclaredAsDependency);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(WinGetResourceUnitEmptyContent);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(WinGetResourceUnitFailedToValidatePackage);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(WinGetResourceUnitFailedToValidatePackageMultipleFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(WinGetResourceUnitFailedToValidatePackageNotFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(WinGetResourceUnitFailedToValidatePackageSourceOpenFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(WinGetResourceUnitFailedToValidatePackageVersionNotFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(WinGetResourceUnitKnownSourceConfliction);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(WinGetResourceUnitMissingRecommendedArg);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(WinGetResourceUnitMissingRequiredArg);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(WinGetResourceUnitPackageVersionSpecifiedWithOnlyOnePackageVersion);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(WinGetResourceUnitThirdPartySourceAssertion);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(WinGetResourceUnitThirdPartySourceAssertionForPackage);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(WordArgumentDescription);\r\n    };\r\n\r\n    // Fixed strings are not localized, but we use a similar system to prevent duplication\r\n    enum class FixedString\r\n    {\r\n        ProductName,\r\n    };\r\n\r\n    Utility::LocIndView GetFixedString(FixedString fs);\r\n}\r\n\r\ninline std::ostream& operator<<(std::ostream& out, AppInstaller::CLI::Resource::FixedString fs)\r\n{\r\n    return (out << GetFixedString(fs));\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Search/Search.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <memory>\r\n#include <type_traits>\r\n#include <winrt/base.h>\r\n\r\n// TODO: This code is expected to eventually be placed into its own DLL to support the CLI\r\n//       and OOP COM server for use by OS integration points.\r\n//       For now we will just maintain the ABI with helper C++ wrappers for client use.\r\n\r\n// \"C\" ABI\r\n\r\nusing AICLIString = wchar_t*;\r\nusing AICLICString = wchar_t const*;\r\nusing RepositoryHandle = void*;\r\nusing ApplicationHandle = void*;\r\nusing ManifestHandle = void*;\r\n\r\nwinrt::hresult aicliGetApplicationById(RepositoryHandle repo, AICLICString id, ApplicationHandle* app);\r\n\r\nwinrt::hresult aicliGetManifestByVersion(ApplicationHandle app, AICLICString version, ManifestHandle* man);\r\n\r\nwinrt::hresult aicliGetManifestContents(ManifestHandle man, AICLICString* contents);\r\n\r\nvoid aicliFreeRepository(RepositoryHandle repo);\r\nvoid aicliFreeApplication(ApplicationHandle app);\r\nvoid aicliFreeManifest(ManifestHandle manifest);\r\n\r\n// C++ wrapper\r\n\r\nnamespace AppInstaller::CLI\r\n{\r\n    namespace details\r\n    {\r\n        struct RepositoryDeleter\r\n        {\r\n            void operator()(RepositoryHandle repo) { aicliFreeRepository(repo); }\r\n        };\r\n\r\n        struct ApplicationDeleter\r\n        {\r\n            void operator()(ApplicationHandle app) { aicliFreeApplication(app); }\r\n        };\r\n\r\n        struct ManifestDeleter\r\n        {\r\n            void operator()(ManifestHandle manifest) { aicliFreeManifest(manifest); }\r\n        };\r\n\r\n        using unique_repository = std::unique_ptr<std::remove_pointer_t<RepositoryHandle>, RepositoryDeleter>;\r\n        using unique_application = std::unique_ptr<std::remove_pointer_t<ApplicationHandle>, ApplicationDeleter>;\r\n        using unique_manifest = std::unique_ptr<std::remove_pointer_t<ManifestHandle>, ManifestDeleter>;\r\n\r\n        template <typename Result, typename Func, typename... Args>\r\n        Result CallABIFunc(Func&& f, Args&&... args)\r\n        {\r\n            Result result{};\r\n            winrt::check_hresult(f(std::forward(args)..., &result));\r\n            return result;\r\n        }\r\n    }\r\n\r\n    struct Manifest\r\n    {\r\n        Manifest() = default;\r\n        Manifest(ManifestHandle mh) : m_man(mh) {}\r\n        ~Manifest() = default;\r\n\r\n        Manifest(const Manifest&) = delete;\r\n        Manifest& operator=(const Manifest&) = delete;\r\n\r\n        Manifest(Manifest&&) = default;\r\n        Manifest& operator=(Manifest&&) = default;\r\n\r\n        AICLICString GetManifestContents() const { return details::CallABIFunc<AICLICString>(aicliGetManifestContents, m_man.get()); }\r\n\r\n    private:\r\n        details::unique_manifest m_man;\r\n    };\r\n\r\n    struct Application\r\n    {\r\n        Application() = default;\r\n        Application(ApplicationHandle ah) : m_app(ah) {}\r\n        ~Application() = default;\r\n\r\n        Application(const Application&) = delete;\r\n        Application& operator=(const Application&) = delete;\r\n\r\n        Application(Application&&) = default;\r\n        Application& operator=(Application&&) = default;\r\n\r\n        static Application GetById(AICLICString id) { return details::CallABIFunc<ApplicationHandle>(aicliGetApplicationById, nullptr, id); }\r\n\r\n        Manifest GetManifestByVersion(AICLICString version) const { return details::CallABIFunc<ManifestHandle>(aicliGetManifestByVersion, m_app.get(), version); }\r\n\r\n    private:\r\n        details::unique_application m_app;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/ShutdownMonitoring.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/ShutdownMonitoring.h\"\r\n#include <AppInstallerErrors.h>\r\n#include <AppInstallerLogging.h>\r\n#include <AppInstallerRuntime.h>\r\n#include <winget/COMStaticStorage.h>\r\n\r\nusing namespace std::chrono_literals;\r\n\r\nnamespace AppInstaller::ShutdownMonitoring\r\n{\r\n    static std::atomic_bool s_TerminationSignalHandlerEnabled = true;\r\n\r\n    std::shared_ptr<TerminationSignalHandler> TerminationSignalHandler::Instance()\r\n    {\r\n        struct Singleton : public WinRT::COMStaticStorageBase<TerminationSignalHandler>\r\n        {\r\n            Singleton() : COMStaticStorageBase(L\"WindowsPackageManager.TerminationSignalHandler\") {}\r\n        };\r\n\r\n        static Singleton s_instance;\r\n        return s_instance.Get();\r\n    }\r\n\r\n    void TerminationSignalHandler::AddListener(ICancellable* cancellable)\r\n    {\r\n        std::lock_guard<std::mutex> lock{ m_listenersLock };\r\n\r\n        auto itr = std::find(m_listeners.begin(), m_listeners.end(), cancellable);\r\n        THROW_HR_IF(E_NOT_VALID_STATE, itr != m_listeners.end());\r\n        m_listeners.push_back(cancellable);\r\n    }\r\n\r\n    void TerminationSignalHandler::RemoveListener(ICancellable* cancellable)\r\n    {\r\n        std::lock_guard<std::mutex> lock{ m_listenersLock };\r\n\r\n        auto itr = std::find(m_listeners.begin(), m_listeners.end(), cancellable);\r\n        if (itr == m_listeners.end())\r\n        {\r\n            AICLI_LOG(CLI, Warning, << \"TerminationSignalHandler::RemoveListener did not find requested object\");\r\n        }\r\n        else\r\n        {\r\n            m_listeners.erase(itr);\r\n        }\r\n    }\r\n\r\n    void TerminationSignalHandler::EnableListener(bool enabled, ICancellable* cancellable)\r\n    {\r\n        if (enabled)\r\n        {\r\n            Instance()->AddListener(cancellable);\r\n        }\r\n        else\r\n        {\r\n            Instance()->RemoveListener(cancellable);\r\n        }\r\n    }\r\n\r\n    bool TerminationSignalHandler::Enabled()\r\n    {\r\n        return s_TerminationSignalHandlerEnabled;\r\n    }\r\n\r\n    void TerminationSignalHandler::Enabled(bool enabled)\r\n    {\r\n        s_TerminationSignalHandlerEnabled = enabled;\r\n    }\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n    HWND TerminationSignalHandler::GetWindowHandle() const\r\n    {\r\n        return m_windowHandle.get();\r\n    }\r\n#endif\r\n\r\n    TerminationSignalHandler::TerminationSignalHandler()\r\n    {\r\n        if (!s_TerminationSignalHandlerEnabled)\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"TerminationSignalHandler is disabled, skipping creation of signal listeners\");\r\n            return;\r\n        }\r\n\r\n        // Create message only window.\r\n        m_messageQueueReady.create();\r\n        m_windowThread = std::thread(&TerminationSignalHandler::CreateWindowAndStartMessageLoop, this);\r\n        if (!m_messageQueueReady.wait(100))\r\n        {\r\n            AICLI_LOG(CLI, Warning, << \"Timeout creating winget window\");\r\n        }\r\n\r\n        // Set up ctrl-c handler.\r\n        LOG_IF_WIN32_BOOL_FALSE(SetConsoleCtrlHandler(StaticCtrlHandlerFunction, TRUE));\r\n    }\r\n\r\n    TerminationSignalHandler::~TerminationSignalHandler()\r\n    {\r\n        SetConsoleCtrlHandler(StaticCtrlHandlerFunction, FALSE);\r\n\r\n        // std::thread requires that any managed thread (joinable) be joined or detached before destructing\r\n        if (m_windowThread.joinable())\r\n        {\r\n            if (m_windowHandle)\r\n            {\r\n                // Inform the thread that it should stop.\r\n                PostMessageW(m_windowHandle.get(), WM_DESTROY, 0, 0);\r\n            }\r\n\r\n            m_windowThread.join();\r\n        }\r\n    }\r\n\r\n    void TerminationSignalHandler::StartAppShutdown()\r\n    {\r\n        AICLI_LOG(CLI, Info, << \"Initiating shutdown procedure\");\r\n\r\n        // Lifetime manager sends CTRL-C after the WM_QUERYENDSESSION is processed.\r\n        // If we disable the CTRL-C handler, the default handler will kill us.\r\n        InformListeners(CancelReason::AppShutdown, true);\r\n    }\r\n\r\n    BOOL WINAPI TerminationSignalHandler::StaticCtrlHandlerFunction(DWORD ctrlType)\r\n    {\r\n        return Instance()->CtrlHandlerFunction(ctrlType);\r\n    }\r\n\r\n    LRESULT WINAPI TerminationSignalHandler::WindowMessageProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)\r\n    {\r\n        switch (uMsg)\r\n        {\r\n        case WM_QUERYENDSESSION:\r\n            AICLI_LOG(CLI, Verbose, << \"Received WM_QUERYENDSESSION\");\r\n            Instance()->StartAppShutdown();\r\n            return TRUE;\r\n        case WM_ENDSESSION:\r\n        case WM_CLOSE:\r\n            AICLI_LOG(CLI, Verbose, << \"Received window message type: \" << uMsg);\r\n            // We delay as long as needed during the WM_ENDSESSION as we will be terminated on return.\r\n            ServerShutdownSynchronization::WaitForShutdown();\r\n            DestroyWindow(hWnd);\r\n            break;\r\n        case WM_DESTROY:\r\n            PostQuitMessage(0);\r\n            break;\r\n        default:\r\n            return DefWindowProc(hWnd, uMsg, wParam, lParam);\r\n        }\r\n        return FALSE;\r\n    }\r\n\r\n    BOOL TerminationSignalHandler::CtrlHandlerFunction(DWORD ctrlType)\r\n    {\r\n        // TODO: Move this to be logged per active context when we have thread static globals\r\n        AICLI_LOG(CLI, Info, << \"Got CTRL type: \" << ctrlType);\r\n\r\n        switch (ctrlType)\r\n        {\r\n        case CTRL_C_EVENT:\r\n        case CTRL_BREAK_EVENT:\r\n            return InformListeners(CancelReason::CtrlCSignal, false);\r\n            // According to MSDN, we should never receive these due to having gdi32/user32 loaded in our process.\r\n            // But handle them as a force terminate anyway.\r\n        case CTRL_CLOSE_EVENT:\r\n        case CTRL_LOGOFF_EVENT:\r\n        case CTRL_SHUTDOWN_EVENT:\r\n            return InformListeners(CancelReason::CtrlCSignal, true);\r\n        default:\r\n            return FALSE;\r\n        }\r\n    }\r\n\r\n    // Terminates the currently attached contexts.\r\n    // Returns FALSE if no contexts attached; TRUE otherwise.\r\n    BOOL TerminationSignalHandler::InformListeners(CancelReason reason, bool force)\r\n    {\r\n        BOOL result = FALSE;\r\n\r\n        {\r\n            std::lock_guard<std::mutex> lock{ m_listenersLock };\r\n            result = m_listeners.empty() ? FALSE : TRUE;\r\n\r\n            for (auto& listener : m_listeners)\r\n            {\r\n                listener->Cancel(reason, force);\r\n            }\r\n        }\r\n\r\n        // Notify shutdown synchronization as well\r\n        ServerShutdownSynchronization::Instance().Signal(reason);\r\n\r\n        return result;\r\n    }\r\n\r\n    void TerminationSignalHandler::CreateWindowAndStartMessageLoop()\r\n    {\r\n        PCWSTR windowClass = L\"wingetWindow\";\r\n        HINSTANCE hInstance = GetModuleHandle(NULL);\r\n        if (hInstance == NULL)\r\n        {\r\n            LOG_LAST_ERROR_MSG(\"Failed getting module handle\");\r\n            return;\r\n        }\r\n\r\n        WNDCLASSEX wcex = {};\r\n        wcex.cbSize = sizeof(wcex);\r\n\r\n        wcex.style = CS_NOCLOSE;\r\n        wcex.lpfnWndProc = TerminationSignalHandler::WindowMessageProcedure;\r\n        wcex.cbClsExtra = 0;\r\n        wcex.cbWndExtra = 0;\r\n        wcex.hInstance = hInstance;\r\n        wcex.lpszClassName = windowClass;\r\n\r\n        if (!RegisterClassEx(&wcex))\r\n        {\r\n            LOG_LAST_ERROR_MSG(\"Failed registering window class\");\r\n            return;\r\n        }\r\n\r\n        // Unregister the window class on exiting the thread\r\n        auto classUnregister = wil::scope_exit([&]()\r\n            {\r\n                UnregisterClassW(windowClass, hInstance);\r\n            });\r\n\r\n        m_windowHandle = wil::unique_hwnd(CreateWindow(\r\n            windowClass,\r\n            L\"WingetMessageOnlyWindow\",\r\n            WS_OVERLAPPEDWINDOW,\r\n            0, /* x */\r\n            0, /* y */\r\n            0, /* nWidth */\r\n            0, /* nHeight */\r\n            NULL, /* hWndParent */\r\n            NULL, /* hMenu */\r\n            hInstance,\r\n            NULL)); /* lpParam */\r\n\r\n        HWND windowHandle = m_windowHandle.get();\r\n        if (windowHandle == nullptr)\r\n        {\r\n            LOG_LAST_ERROR_MSG(\"Failed creating window\");\r\n            return;\r\n        }\r\n\r\n        // We must destroy the window first so that the class unregister can succeed\r\n        auto destroyWindow = wil::scope_exit([&]()\r\n            {\r\n                DestroyWindow(windowHandle);\r\n            });\r\n\r\n        ShowWindow(windowHandle, SW_HIDE);\r\n\r\n        // Force message queue to be created.\r\n        MSG msg;\r\n        PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);\r\n        m_messageQueueReady.SetEvent();\r\n\r\n        // Message loop, we send WM_DESTROY to terminate it\r\n        BOOL getMessageResult;\r\n        while ((getMessageResult = GetMessage(&msg, windowHandle, 0, 0)) != 0)\r\n        {\r\n            if (getMessageResult == -1)\r\n            {\r\n                LOG_LAST_ERROR();\r\n                break;\r\n            }\r\n            else if (msg.message == WM_DESTROY)\r\n            {\r\n                break;\r\n            }\r\n            else\r\n            {\r\n                DispatchMessage(&msg);\r\n            }\r\n        }\r\n    }\r\n\r\n    void ServerShutdownSynchronization::Initialize(ShutdownCompleteCallback callback, bool createTerminationSignalHandler)\r\n    {\r\n        Instance().m_callback = callback;\r\n\r\n        // Force the creation of the TerminationSignalHandler singleton so that the process can listen for termination signals even if\r\n        // it never attempts to run anything that explicitly registers for cancellation callbacks.\r\n        if (createTerminationSignalHandler)\r\n        {\r\n            TerminationSignalHandler::Instance();\r\n        }\r\n    }\r\n\r\n    void ServerShutdownSynchronization::AddComponent(const ComponentSystem& component)\r\n    {\r\n        ServerShutdownSynchronization& instance = Instance();\r\n        std::lock_guard<std::mutex> lock{ instance.m_componentsLock };\r\n\r\n        for (const auto& item : instance.m_components)\r\n        {\r\n            if (item.BlockNewWork == component.BlockNewWork ||\r\n                item.BeginShutdown == component.BeginShutdown ||\r\n                item.Wait == component.Wait)\r\n            {\r\n                return;\r\n            }\r\n        }\r\n\r\n        instance.m_components.push_back(component);\r\n    }\r\n\r\n    bool ServerShutdownSynchronization::WaitForShutdown(std::optional<DWORD> timeout)\r\n    {\r\n        ServerShutdownSynchronization& instance = Instance();\r\n\r\n        if (timeout)\r\n        {\r\n            return instance.m_shutdownComplete.wait(timeout.value());\r\n        }\r\n        else\r\n        {\r\n            {\r\n                std::lock_guard<std::mutex> lock{ instance.m_threadLock };\r\n                if (!instance.m_shutdownThread.joinable())\r\n                {\r\n                    AICLI_LOG(Core, Warning, << \"Attempt to wait for shutdown when shutdown has not been initiated.\");\r\n                    return false;\r\n                }\r\n            }\r\n\r\n            return instance.m_shutdownComplete.wait();\r\n        }\r\n    }\r\n\r\n    void ServerShutdownSynchronization::Signal(CancelReason reason)\r\n    {\r\n        std::lock_guard<std::mutex> lock{ m_threadLock };\r\n\r\n        if (!m_shutdownThread.joinable())\r\n        {\r\n            m_shutdownThread = std::thread(&ServerShutdownSynchronization::SynchronizeShutdown, this, reason);\r\n        }\r\n    }\r\n\r\n    ServerShutdownSynchronization::~ServerShutdownSynchronization()\r\n    {\r\n        if (m_shutdownThread.joinable())\r\n        {\r\n            m_shutdownThread.detach();\r\n        }\r\n    }\r\n\r\n    ServerShutdownSynchronization& ServerShutdownSynchronization::Instance()\r\n    {\r\n        static ServerShutdownSynchronization s_instance;\r\n        return s_instance;\r\n    }\r\n\r\n    void ServerShutdownSynchronization::SynchronizeShutdown(CancelReason reason) try\r\n    {\r\n        auto setShutdownComplete = wil::scope_exit([this]() { this->m_shutdownComplete.SetEvent(); });\r\n\r\n        std::vector<ComponentSystem> components;\r\n        {\r\n            std::lock_guard<std::mutex> lock{ m_componentsLock };\r\n            components = m_components;\r\n        }\r\n\r\n        AICLI_LOG(CLI, Verbose, << \"ServerShutdownSynchronization :: BlockNewWork\");\r\n        for (const auto& component : components)\r\n        {\r\n            if (component.BlockNewWork)\r\n            {\r\n                component.BlockNewWork(reason);\r\n            }\r\n        }\r\n\r\n        AICLI_LOG(CLI, Verbose, << \"ServerShutdownSynchronization :: BeginShutdown\");\r\n        for (const auto& component : components)\r\n        {\r\n            if (component.BeginShutdown)\r\n            {\r\n                component.BeginShutdown(reason);\r\n            }\r\n        }\r\n\r\n        AICLI_LOG(CLI, Verbose, << \"ServerShutdownSynchronization :: Wait\");\r\n        for (const auto& component : components)\r\n        {\r\n            if (component.Wait)\r\n            {\r\n                component.Wait();\r\n            }\r\n        }\r\n\r\n        AICLI_LOG(CLI, Verbose, << \"ServerShutdownSynchronization :: ShutdownCompleteCallback\");\r\n        ShutdownCompleteCallback callback = m_callback;\r\n        if (callback)\r\n        {\r\n            callback();\r\n        }\r\n    }\r\n    CATCH_LOG();\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Sixel.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Sixel.h\"\r\n#include <AppInstallerStrings.h>\r\n#include <winget/UserSettings.h>\r\n#include <vector>\r\n#include <sstream>\r\n\r\nnamespace AppInstaller::CLI::VirtualTerminal::Sixel\r\n{\r\n    namespace anon\r\n    {\r\n        wil::com_ptr<IWICImagingFactory> CreateFactory()\r\n        {\r\n            wil::com_ptr<IWICImagingFactory> result;\r\n            THROW_IF_FAILED(CoCreateInstance(\r\n                CLSID_WICImagingFactory,\r\n                NULL,\r\n                CLSCTX_INPROC_SERVER,\r\n                IID_PPV_ARGS(&result)));\r\n            return result;\r\n        }\r\n\r\n        UINT AspectRatioMultiplier(AspectRatio aspectRatio)\r\n        {\r\n            switch (aspectRatio)\r\n            {\r\n            case AspectRatio::OneToOne:\r\n                return 1;\r\n            case AspectRatio::TwoToOne:\r\n                return 2;\r\n            case AspectRatio::ThreeToOne:\r\n                return 3;\r\n            case AspectRatio::FiveToOne:\r\n                return 5;\r\n            default:\r\n                THROW_HR(E_INVALIDARG);\r\n            }\r\n        }\r\n\r\n        // Forces the given bitmap source to evaluate\r\n        wil::com_ptr<IWICBitmap> CacheToBitmap(IWICImagingFactory* factory, IWICBitmapSource* sourceImage)\r\n        {\r\n            wil::com_ptr<IWICBitmap> result;\r\n            THROW_IF_FAILED(factory->CreateBitmapFromSource(sourceImage, WICBitmapCacheOnLoad, &result));\r\n            return result;\r\n        }\r\n\r\n        // Convert [0, 255] => [0, 100]\r\n        UINT32 ByteToPercent(BYTE input)\r\n        {\r\n            return (static_cast<UINT32>(input) * 100 + 127) / 255;\r\n        }\r\n\r\n        // Contains the state for a rendering pass.\r\n        struct RenderState\r\n        {\r\n            RenderState(\r\n                const Palette& palette,\r\n                const std::vector<ImageView>& views,\r\n                const RenderControls& renderControls) :\r\n                m_palette(palette),\r\n                m_views(views),\r\n                m_renderControls(renderControls)\r\n            {\r\n                // Create render buffers\r\n                m_enabledColors.resize(m_palette.Size());\r\n                m_sixelBuffer.resize(m_palette.Size() * m_renderControls.PixelWidth);\r\n            }\r\n\r\n            enum class State\r\n            {\r\n                Initial,\r\n                Pixels,\r\n                Final,\r\n                Terminated,\r\n            };\r\n\r\n            // Advances the render state machine, returning true if `Current` will return a new sequence and false when it will not.\r\n            bool Advance()\r\n            {\r\n                std::stringstream stream;\r\n\r\n                switch (m_currentState)\r\n                {\r\n                case State::Initial:\r\n                    // Initial device control string\r\n                    stream << AICLI_VT_ESCAPE << 'P' << ToIntegral(m_renderControls.AspectRatio) << \";1;q\";\r\n\r\n                    for (size_t i = 0; i < m_palette.Size(); ++i)\r\n                    {\r\n                        // 2 is RGB color space, with values from 0 to 100\r\n                        stream << '#' << i << \";2;\";\r\n\r\n                        WICColor currentColor = m_palette[i];\r\n                        BYTE red = (currentColor >> 16) & 0xFF;\r\n                        BYTE green = (currentColor >> 8) & 0xFF;\r\n                        BYTE blue = (currentColor) & 0xFF;\r\n\r\n                        stream << ByteToPercent(red) << ';' << ByteToPercent(green) << ';' << ByteToPercent(blue);\r\n                    }\r\n\r\n                    m_currentState = State::Pixels;\r\n                    break;\r\n                case State::Pixels:\r\n                {\r\n                    // Disable all colors and set all characters to empty (0x3F)\r\n                    memset(m_enabledColors.data(), 0, m_enabledColors.size());\r\n                    memset(m_sixelBuffer.data(), 0x3F, m_sixelBuffer.size());\r\n\r\n                    // Convert indexed pixel data into per-color sixel lines\r\n                    UINT rowsToProcess = std::min(RenderControls::PixelsPerSixel, m_renderControls.PixelHeight - m_currentPixelRow);\r\n\r\n                    for (UINT rowOffset = 0; rowOffset < rowsToProcess; ++rowOffset)\r\n                    {\r\n                        // The least significant bit is the top of the sixel\r\n                        char sixelBit = 1 << rowOffset;\r\n                        UINT currentRow = m_currentPixelRow + rowOffset;\r\n\r\n                        for (UINT i = 0; i < m_renderControls.PixelWidth; ++i)\r\n                        {\r\n                            const BYTE* pixelPtr = nullptr;\r\n                            size_t colorIndex = 0;\r\n\r\n                            for (const ImageView& view : m_views)\r\n                            {\r\n                                pixelPtr = view.GetPixel(i, currentRow);\r\n\r\n                                if (pixelPtr)\r\n                                {\r\n                                    colorIndex = *pixelPtr;\r\n\r\n                                    // Stop on the first non-transparent pixel we find\r\n                                    if (((m_palette[colorIndex] >> 24) & 0xFF) != 0)\r\n                                    {\r\n                                        break;\r\n                                    }\r\n                                }\r\n                            }\r\n\r\n                            if (pixelPtr)\r\n                            {\r\n                                m_enabledColors[colorIndex] = 1;\r\n                                m_sixelBuffer[(colorIndex * m_renderControls.PixelWidth) + i] += sixelBit;\r\n                            }\r\n                        }\r\n                    }\r\n\r\n                    // Output all sixel color lines\r\n                    bool firstOfRow = true;\r\n\r\n                    for (size_t i = 0; i < m_enabledColors.size(); ++i)\r\n                    {\r\n                        if (m_enabledColors[i])\r\n                        {\r\n                            if (m_renderControls.TransparencyEnabled)\r\n                            {\r\n                                // Don't output color if transparent\r\n                                WICColor currentColor = m_palette[i];\r\n                                BYTE alpha = (currentColor >> 24) & 0xFF;\r\n                                if (alpha == 0)\r\n                                {\r\n                                    continue;\r\n                                }\r\n                            }\r\n\r\n                            if (firstOfRow)\r\n                            {\r\n                                firstOfRow = false;\r\n                            }\r\n                            else\r\n                            {\r\n                                // The carriage return operator resets for another color pass.\r\n                                stream << '$';\r\n                            }\r\n\r\n                            stream << '#' << i;\r\n\r\n                            const char* colorRow = &m_sixelBuffer[i * m_renderControls.PixelWidth];\r\n\r\n                            if (m_renderControls.UseRepeatSequence)\r\n                            {\r\n                                char currentChar = colorRow[0];\r\n                                UINT repeatCount = 1;\r\n\r\n                                for (UINT j = 1; j <= m_renderControls.PixelWidth; ++j)\r\n                                {\r\n                                    // Force processing of a final null character to handle flushing the line\r\n                                    const char nextChar = (j == m_renderControls.PixelWidth ? 0 : colorRow[j]);\r\n\r\n                                    if (nextChar == currentChar)\r\n                                    {\r\n                                        ++repeatCount;\r\n                                    }\r\n                                    else\r\n                                    {\r\n                                        if (repeatCount > 2)\r\n                                        {\r\n                                            stream << '!' << repeatCount;\r\n                                        }\r\n                                        else if (repeatCount == 2)\r\n                                        {\r\n                                            stream << currentChar;\r\n                                        }\r\n\r\n                                        stream << currentChar;\r\n\r\n                                        currentChar = nextChar;\r\n                                        repeatCount = 1;\r\n                                    }\r\n                                }\r\n                            }\r\n                            else\r\n                            {\r\n                                stream << std::string_view{ colorRow, m_renderControls.PixelWidth };\r\n                            }\r\n                        }\r\n                    }\r\n\r\n                    // The new line operator sets up for the next sixel row\r\n                    stream << '-';\r\n\r\n                    m_currentPixelRow += rowsToProcess;\r\n                    if (m_currentPixelRow >= m_renderControls.PixelHeight)\r\n                    {\r\n                        m_currentState = State::Final;\r\n                    }\r\n                }\r\n                    break;\r\n                case State::Final:\r\n                    stream << AICLI_VT_ESCAPE << '\\\\';\r\n                    m_currentState = State::Terminated;\r\n                    break;\r\n                case State::Terminated:\r\n                    m_currentSequence.clear();\r\n                    return false;\r\n                }\r\n\r\n                m_currentSequence = std::move(stream).str();\r\n                return true;\r\n            }\r\n\r\n            Sequence Current() const\r\n            {\r\n                return Sequence{ m_currentSequence };\r\n            }\r\n\r\n        private:\r\n            const Palette& m_palette;\r\n            const std::vector<ImageView>& m_views;\r\n            const RenderControls& m_renderControls;\r\n\r\n            State m_currentState = State::Initial;\r\n            std::vector<char> m_enabledColors;\r\n            std::vector<char> m_sixelBuffer;\r\n            UINT m_currentPixelRow = 0;\r\n            // TODO-C++20: Replace with a view from the stringstream\r\n            std::string m_currentSequence;\r\n        };\r\n    }\r\n\r\n    Palette::Palette(IWICImagingFactory* factory, IWICBitmapSource* bitmapSource, UINT colorCount, bool transparencyEnabled) :\r\n        m_factory(factory)\r\n    {\r\n        THROW_IF_FAILED(m_factory->CreatePalette(&m_paletteObject));\r\n\r\n        THROW_IF_FAILED(m_paletteObject->InitializeFromBitmap(bitmapSource, colorCount, transparencyEnabled));\r\n\r\n        // Extract the palette for render use\r\n        UINT actualColorCount = 0;\r\n        THROW_IF_FAILED(m_paletteObject->GetColorCount(&actualColorCount));\r\n\r\n        m_palette.resize(actualColorCount);\r\n        THROW_IF_FAILED(m_paletteObject->GetColors(actualColorCount, m_palette.data(), &actualColorCount));\r\n    }\r\n\r\n    Palette::Palette(const Palette& first, const Palette& second)\r\n    {\r\n        auto firstPalette = first.m_palette;\r\n        auto secondPalette = second.m_palette;\r\n        std::sort(firstPalette.begin(), firstPalette.end());\r\n        std::sort(secondPalette.begin(), secondPalette.end());\r\n\r\n        // Construct a union of the two palettes\r\n        std::set_union(firstPalette.begin(), firstPalette.end(), secondPalette.begin(), secondPalette.end(), std::back_inserter(m_palette));\r\n        THROW_HR_IF(E_INVALIDARG, m_palette.size() > MaximumColorCount);\r\n\r\n        m_factory = first.m_factory;\r\n        THROW_IF_FAILED(m_factory->CreatePalette(&m_paletteObject));\r\n        THROW_IF_FAILED(m_paletteObject->InitializeCustom(m_palette.data(), static_cast<UINT>(m_palette.size())));\r\n    }\r\n\r\n    IWICPalette* Palette::Get() const\r\n    {\r\n        return m_paletteObject.get();\r\n    }\r\n\r\n    size_t Palette::Size() const\r\n    {\r\n        return m_palette.size();\r\n    }\r\n\r\n    WICColor& Palette::operator[](size_t index)\r\n    {\r\n        return m_palette[index];\r\n    }\r\n\r\n    WICColor Palette::operator[](size_t index) const\r\n    {\r\n        return m_palette[index];\r\n    }\r\n\r\n    ImageView::ImageView(UINT width, UINT height, UINT stride, UINT byteCount, BYTE* bytes) :\r\n        m_viewWidth(width), m_viewHeight(height), m_viewStride(stride), m_viewByteCount(byteCount), m_viewBytes(bytes)\r\n    {}\r\n\r\n    ImageView ImageView::Lock(IWICBitmap* imageSource)\r\n    {\r\n        WICPixelFormatGUID pixelFormat{};\r\n        THROW_IF_FAILED(imageSource->GetPixelFormat(&pixelFormat));\r\n        THROW_HR_IF(ERROR_INVALID_STATE, GUID_WICPixelFormat8bppIndexed != pixelFormat);\r\n\r\n        ImageView result;\r\n\r\n        UINT sourceX = 0;\r\n        UINT sourceY = 0;\r\n        THROW_IF_FAILED(imageSource->GetSize(&sourceX, &sourceY));\r\n        THROW_WIN32_IF(ERROR_BUFFER_OVERFLOW,\r\n            sourceX > static_cast<UINT>(std::numeric_limits<INT>::max()) || sourceY > static_cast<UINT>(std::numeric_limits<INT>::max()));\r\n\r\n        WICRect rect{};\r\n        rect.Width = static_cast<INT>(sourceX);\r\n        rect.Height = static_cast<INT>(sourceY);\r\n\r\n        THROW_IF_FAILED(imageSource->Lock(&rect, WICBitmapLockRead, &result.m_lockedImage));\r\n        THROW_IF_FAILED(result.m_lockedImage->GetSize(&result.m_viewWidth, &result.m_viewHeight));\r\n        THROW_IF_FAILED(result.m_lockedImage->GetStride(&result.m_viewStride));\r\n        THROW_IF_FAILED(result.m_lockedImage->GetDataPointer(&result.m_viewByteCount, &result.m_viewBytes));\r\n\r\n        return result;\r\n    }\r\n\r\n    ImageView ImageView::Copy(IWICBitmapSource* imageSource)\r\n    {\r\n        WICPixelFormatGUID pixelFormat{};\r\n        THROW_IF_FAILED(imageSource->GetPixelFormat(&pixelFormat));\r\n        THROW_HR_IF(ERROR_INVALID_STATE, GUID_WICPixelFormat8bppIndexed != pixelFormat);\r\n\r\n        ImageView result;\r\n\r\n        THROW_IF_FAILED(imageSource->GetSize(&result.m_viewWidth, &result.m_viewHeight));\r\n        THROW_WIN32_IF(ERROR_BUFFER_OVERFLOW,\r\n            result.m_viewWidth > static_cast<UINT>(std::numeric_limits<INT>::max()) || result.m_viewHeight > static_cast<UINT>(std::numeric_limits<INT>::max()));\r\n\r\n        result.m_viewStride = result.m_viewWidth;\r\n        result.m_viewByteCount = result.m_viewStride * result.m_viewHeight;\r\n        result.m_copiedImage = std::make_unique<BYTE[]>(result.m_viewByteCount);\r\n        result.m_viewBytes = result.m_copiedImage.get();\r\n\r\n        THROW_IF_FAILED(imageSource->CopyPixels(nullptr, result.m_viewStride, result.m_viewByteCount, result.m_viewBytes));\r\n\r\n        return result;\r\n    }\r\n\r\n    void ImageView::Translate(INT x, INT y, bool tile)\r\n    {\r\n        m_tile = tile;\r\n\r\n        if (m_tile)\r\n        {\r\n            m_translateX = static_cast<UINT>(m_viewWidth - (x % static_cast<INT>(m_viewWidth)));\r\n            m_translateY = static_cast<UINT>(m_viewHeight - (y % static_cast<INT>(m_viewHeight)));\r\n        }\r\n        else\r\n        {\r\n            m_translateX = static_cast<UINT>(-x);\r\n            m_translateY = static_cast<UINT>(-y);\r\n        }\r\n    }\r\n\r\n    const BYTE* ImageView::GetPixel(UINT x, UINT y) const\r\n    {\r\n        UINT translatedX = x + m_translateX;\r\n        UINT tileCountX = translatedX / m_viewWidth;\r\n        UINT viewX = translatedX % m_viewWidth;\r\n        if (tileCountX && !m_tile)\r\n        {\r\n            return nullptr;\r\n        }\r\n\r\n        UINT translatedY = y + m_translateY;\r\n        UINT tileCountY = translatedY / m_viewHeight;\r\n        UINT viewY = translatedY % m_viewHeight;\r\n        if (tileCountY && !m_tile)\r\n        {\r\n            return nullptr;\r\n        }\r\n\r\n        return m_viewBytes + (static_cast<size_t>(viewY) * m_viewStride) + viewX;\r\n    }\r\n\r\n    UINT ImageView::Width() const\r\n    {\r\n        return m_viewWidth;\r\n    }\r\n\r\n    UINT ImageView::Height() const\r\n    {\r\n        return m_viewHeight;\r\n    }\r\n\r\n    void RenderControls::RenderSizeInCells(UINT width, UINT height)\r\n    {\r\n        PixelWidth = width * CellWidthInPixels;\r\n\r\n        // We don't want to overdraw the row below, so our height must be the largest multiple of 6 that fits in Y cells.\r\n        UINT yInPixels = height * CellHeightInPixels;\r\n        PixelHeight = yInPixels - (yInPixels % PixelsPerSixel);\r\n    }\r\n\r\n    ImageSource::ImageSource(const std::filesystem::path& imageFilePath)\r\n    {\r\n        m_factory = anon::CreateFactory();\r\n\r\n        wil::com_ptr<IWICBitmapDecoder> decoder;\r\n        THROW_IF_FAILED(m_factory->CreateDecoderFromFilename(imageFilePath.c_str(), NULL, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &decoder));\r\n\r\n        wil::com_ptr<IWICBitmapFrameDecode> decodedFrame;\r\n        THROW_IF_FAILED(decoder->GetFrame(0, &decodedFrame));\r\n\r\n        m_sourceImage = anon::CacheToBitmap(m_factory.get(), decodedFrame.get());\r\n    }\r\n\r\n    ImageSource::ImageSource(std::istream& imageStream, Manifest::IconFileTypeEnum imageEncoding) :\r\n        ImageSource(Utility::ReadEntireStreamAsByteArray(imageStream), imageEncoding)\r\n    {\r\n    }\r\n\r\n    ImageSource::ImageSource(const std::vector<uint8_t>& imageBytes, Manifest::IconFileTypeEnum imageEncoding)\r\n    {\r\n        m_factory = anon::CreateFactory();\r\n\r\n        wil::com_ptr<IStream> stream;\r\n        THROW_IF_FAILED(CreateStreamOnHGlobal(nullptr, TRUE, &stream));\r\n\r\n        ULONG written = 0;\r\n        THROW_IF_FAILED(stream->Write(imageBytes.data(), static_cast<ULONG>(imageBytes.size()), &written));\r\n        THROW_IF_FAILED(stream->Seek({}, STREAM_SEEK_SET, nullptr));\r\n\r\n        wil::com_ptr<IWICBitmapDecoder> decoder;\r\n        bool initializeDecoder = true;\r\n\r\n        switch (imageEncoding)\r\n        {\r\n        case Manifest::IconFileTypeEnum::Unknown:\r\n            THROW_IF_FAILED(m_factory->CreateDecoderFromStream(stream.get(), NULL, WICDecodeMetadataCacheOnDemand, &decoder));\r\n            initializeDecoder = false;\r\n            break;\r\n        case Manifest::IconFileTypeEnum::Jpeg:\r\n            THROW_IF_FAILED(m_factory->CreateDecoder(GUID_ContainerFormatJpeg, NULL, &decoder));\r\n            break;\r\n        case Manifest::IconFileTypeEnum::Png:\r\n            THROW_IF_FAILED(m_factory->CreateDecoder(GUID_ContainerFormatPng, NULL, &decoder));\r\n            break;\r\n        case Manifest::IconFileTypeEnum::Ico:\r\n            THROW_IF_FAILED(m_factory->CreateDecoder(GUID_ContainerFormatIco, NULL, &decoder));\r\n            break;\r\n        default:\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n\r\n        if (initializeDecoder)\r\n        {\r\n            THROW_IF_FAILED(decoder->Initialize(stream.get(), WICDecodeMetadataCacheOnDemand));\r\n        }\r\n\r\n        wil::com_ptr<IWICBitmapFrameDecode> decodedFrame;\r\n        THROW_IF_FAILED(decoder->GetFrame(0, &decodedFrame));\r\n\r\n        m_sourceImage = anon::CacheToBitmap(m_factory.get(), decodedFrame.get());\r\n    }\r\n\r\n    void ImageSource::Resize(UINT pixelWidth, UINT pixelHeight, AspectRatio targetRenderRatio, bool stretchToFill, InterpolationMode interpolationMode)\r\n    {\r\n        if ((pixelWidth && pixelHeight) || targetRenderRatio != AspectRatio::OneToOne)\r\n        {\r\n            UINT targetX = pixelWidth;\r\n            UINT targetY = pixelHeight;\r\n\r\n            if (!stretchToFill)\r\n            {\r\n                // We need to calculate which of the sizes needs to be reduced\r\n                UINT sourceImageX = 0;\r\n                UINT sourceImageY = 0;\r\n                THROW_IF_FAILED(m_sourceImage->GetSize(&sourceImageX, &sourceImageY));\r\n\r\n                double doubleTargetX = targetX;\r\n                double doubleTargetY = targetY;\r\n                double doubleSourceImageX = sourceImageX;\r\n                double doubleSourceImageY = sourceImageY;\r\n\r\n                double scaleFactorX = doubleTargetX / doubleSourceImageX;\r\n                double targetY_scaledForX = sourceImageY * scaleFactorX;\r\n                if (targetY_scaledForX > doubleTargetY)\r\n                {\r\n                    // Scaling to make X fill would make Y to large, so we must scale to fill Y\r\n                    targetX = static_cast<UINT>(sourceImageX * (doubleTargetY / doubleSourceImageY));\r\n                }\r\n                else\r\n                {\r\n                    // Scaling to make X fill kept Y under target\r\n                    targetY = static_cast<UINT>(targetY_scaledForX);\r\n                }\r\n            }\r\n\r\n            // Apply aspect ratio scaling\r\n            targetY /= anon::AspectRatioMultiplier(targetRenderRatio);\r\n\r\n            wil::com_ptr<IWICBitmapScaler> scaler;\r\n            THROW_IF_FAILED(m_factory->CreateBitmapScaler(&scaler));\r\n\r\n            THROW_IF_FAILED(scaler->Initialize(m_sourceImage.get(), targetX, targetY, ToEnum<WICBitmapInterpolationMode>(ToIntegral(interpolationMode))));\r\n            m_sourceImage = anon::CacheToBitmap(m_factory.get(), scaler.get());\r\n        }\r\n    }\r\n\r\n    void ImageSource::Resize(const RenderControls& controls)\r\n    {\r\n        Resize(controls.PixelWidth, controls.PixelHeight, controls.AspectRatio, controls.StretchSourceToFill, controls.InterpolationMode);\r\n    }\r\n\r\n    Palette ImageSource::CreatePalette(UINT colorCount, bool transparencyEnabled) const\r\n    {\r\n        return { m_factory.get(), m_sourceImage.get(), colorCount, transparencyEnabled };\r\n    }\r\n\r\n    Palette ImageSource::CreatePalette(const RenderControls& controls) const\r\n    {\r\n        return CreatePalette(controls.ColorCount, controls.TransparencyEnabled);\r\n    }\r\n\r\n    void ImageSource::ApplyPalette(const Palette& palette)\r\n    {\r\n        // Convert to 8bpp indexed\r\n        wil::com_ptr<IWICFormatConverter> converter;\r\n        THROW_IF_FAILED(m_factory->CreateFormatConverter(&converter));\r\n\r\n        // TODO: Determine a better value or enable it to be set\r\n        constexpr double s_alphaThreshold = 0.5;\r\n\r\n        THROW_IF_FAILED(converter->Initialize(m_sourceImage.get(), GUID_WICPixelFormat8bppIndexed, WICBitmapDitherTypeErrorDiffusion, palette.Get(), s_alphaThreshold, WICBitmapPaletteTypeCustom));\r\n        m_sourceImage = anon::CacheToBitmap(m_factory.get(), converter.get());\r\n    }\r\n\r\n    ImageView ImageSource::Lock() const\r\n    {\r\n        return ImageView::Lock(m_sourceImage.get());\r\n    }\r\n\r\n    ImageView ImageSource::Copy() const\r\n    {\r\n        return ImageView::Copy(m_sourceImage.get());\r\n    }\r\n\r\n    void Compositor::Palette(Sixel::Palette palette)\r\n    {\r\n        m_palette = std::move(palette);\r\n    }\r\n\r\n    void Compositor::AddView(ImageView&& view)\r\n    {\r\n        m_views.emplace_back(std::move(view));\r\n    }\r\n\r\n    size_t Compositor::ViewCount() const\r\n    {\r\n        return m_views.size();\r\n    }\r\n\r\n    ImageView& Compositor::operator[](size_t index)\r\n    {\r\n        return m_views[index];\r\n    }\r\n\r\n    const ImageView& Compositor::operator[](size_t index) const\r\n    {\r\n        return m_views[index];\r\n    }\r\n\r\n    RenderControls& Compositor::Controls()\r\n    {\r\n        return m_renderControls;\r\n    }\r\n\r\n    const RenderControls& Compositor::Controls() const\r\n    {\r\n        return m_renderControls;\r\n    }\r\n\r\n    ConstructedSequence Compositor::Render()\r\n    {\r\n        anon::RenderState renderState{ m_palette, m_views, m_renderControls };\r\n\r\n        std::stringstream result;\r\n\r\n        while (renderState.Advance())\r\n        {\r\n            result << renderState.Current().Get();\r\n        }\r\n\r\n        return ConstructedSequence{ std::move(result).str() };\r\n    }\r\n\r\n    void Compositor::RenderTo(Execution::BaseStream& stream)\r\n    {\r\n        anon::RenderState renderState{ m_palette, m_views, m_renderControls };\r\n\r\n        while (renderState.Advance())\r\n        {\r\n            stream << renderState.Current();\r\n        }\r\n    }\r\n\r\n    void Compositor::RenderTo(Execution::OutputStream& stream)\r\n    {\r\n        anon::RenderState renderState{ m_palette, m_views, m_renderControls };\r\n\r\n        while (renderState.Advance())\r\n        {\r\n            stream << renderState.Current();\r\n        }\r\n    }\r\n\r\n    Image::Image(const std::filesystem::path& imageFilePath) :\r\n        m_imageSource(imageFilePath)\r\n    {}\r\n\r\n    Image::Image(std::istream& imageStream, Manifest::IconFileTypeEnum imageEncoding) :\r\n        m_imageSource(imageStream, imageEncoding)\r\n    {}\r\n\r\n    Image::Image(const std::vector<uint8_t>& imageBytes, Manifest::IconFileTypeEnum imageEncoding) :\r\n        m_imageSource(imageBytes, imageEncoding)\r\n    {}\r\n\r\n    Image& Image::AspectRatio(Sixel::AspectRatio aspectRatio)\r\n    {\r\n        m_renderControls.AspectRatio = aspectRatio;\r\n        return *this;\r\n    }\r\n\r\n    Image& Image::Transparency(bool transparencyEnabled)\r\n    {\r\n        m_renderControls.TransparencyEnabled = transparencyEnabled;\r\n        return *this;\r\n    }\r\n\r\n    Image& Image::ColorCount(UINT colorCount)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, colorCount > Palette::MaximumColorCount || colorCount < 2);\r\n        m_renderControls.ColorCount = colorCount;\r\n        return *this;\r\n    }\r\n\r\n    Image& Image::RenderSizeInPixels(UINT width, UINT height)\r\n    {\r\n        m_renderControls.PixelWidth = width;\r\n        m_renderControls.PixelHeight = height;\r\n        return *this;\r\n    }\r\n\r\n    Image& Image::RenderSizeInCells(UINT width, UINT height)\r\n    {\r\n        m_renderControls.RenderSizeInCells(width, height);\r\n        return *this;\r\n    }\r\n\r\n    Image& Image::StretchSourceToFill(bool stretchSourceToFill)\r\n    {\r\n        m_renderControls.StretchSourceToFill = stretchSourceToFill;\r\n        return *this;\r\n    }\r\n\r\n    Image& Image::UseRepeatSequence(bool useRepeatSequence)\r\n    {\r\n        m_renderControls.UseRepeatSequence = useRepeatSequence;\r\n        return *this;\r\n    }\r\n\r\n    ConstructedSequence Image::Render()\r\n    {\r\n        return CreateCompositor().second.Render();\r\n    }\r\n\r\n    void Image::RenderTo(Execution::OutputStream& stream)\r\n    {\r\n        CreateCompositor().second.RenderTo(stream);\r\n    }\r\n\r\n    std::pair<ImageSource, Compositor> Image::CreateCompositor()\r\n    {\r\n        ImageSource localSource{ m_imageSource };\r\n        localSource.Resize(m_renderControls);\r\n\r\n        Palette palette{ localSource.CreatePalette(m_renderControls) };\r\n        localSource.ApplyPalette(palette);\r\n\r\n        ImageView view{ localSource.Lock() };\r\n\r\n        Compositor compositor;\r\n        compositor.Palette(std::move(palette));\r\n        compositor.AddView(std::move(view));\r\n        compositor.Controls() = m_renderControls;\r\n\r\n        return { std::move(localSource), std::move(compositor) };\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Sixel.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ChannelStreams.h\"\r\n#include \"VTSupport.h\"\r\n#include <winget/ManifestLocalization.h>\r\n#include <wincodec.h>\r\n#include <wil/com.h>\r\n#include <filesystem>\r\n\r\nnamespace AppInstaller::CLI::VirtualTerminal::Sixel\r\n{\r\n    // Determines the height to width ratio of the pixels that make up a sixel (a sixel is 6 pixels tall and 1 pixel wide).\r\n    // Note that each cell is always a height of 20 and a width of 10, regardless of the screen resolution of the terminal.\r\n    // The 2:1 ratio will then result in each sixel being 12 of the 20 pixels of a cell.\r\n    enum class AspectRatio\r\n    {\r\n        OneToOne = 7,\r\n        TwoToOne = 0,\r\n        ThreeToOne = 3,\r\n        FiveToOne = 2,\r\n    };\r\n\r\n    // Determines the algorithm used when resizing the image.\r\n    enum class InterpolationMode\r\n    {\r\n        NearestNeighbor = WICBitmapInterpolationModeNearestNeighbor,\r\n        Linear = WICBitmapInterpolationModeLinear,\r\n        Cubic = WICBitmapInterpolationModeCubic,\r\n        Fant = WICBitmapInterpolationModeFant,\r\n        HighQualityCubic = WICBitmapInterpolationModeHighQualityCubic,\r\n    };\r\n\r\n    // Contains the palette used by a sixel image.\r\n    struct Palette\r\n    {\r\n        // Limit to 256 both as the defacto maximum supported colors and to enable always using 8bpp indexed pixel format.\r\n        static constexpr UINT MaximumColorCount = 256;\r\n\r\n        // Creates an empty palette.\r\n        Palette() = default;\r\n\r\n        // Create a palette from the given source image, color count, transparency setting.\r\n        Palette(IWICImagingFactory* factory, IWICBitmapSource* bitmapSource, UINT colorCount, bool transparencyEnabled);\r\n\r\n        // Create a palette combining the two palettes. Throws an exception if there are more than MaximumColorCount unique\r\n        // colors between the two. This can be avoided by intentionally dividing the available colors between the palettes\r\n        // when creating them.\r\n        Palette(const Palette& first, const Palette& second);\r\n\r\n        // Gets the WIC palette object.\r\n        IWICPalette* Get() const;\r\n\r\n        // Gets the color count for the palette.\r\n        size_t Size() const;\r\n\r\n        // Gets the color at the given index in the palette.\r\n        WICColor& operator[](size_t index);\r\n        WICColor operator[](size_t index) const;\r\n\r\n    private:\r\n        wil::com_ptr<IWICImagingFactory> m_factory;\r\n        wil::com_ptr<IWICPalette> m_paletteObject;\r\n        std::vector<WICColor> m_palette;\r\n    };\r\n\r\n    // Allows access to the pixel data of an image source.\r\n    // Can be configured to translate and/or tile the view.\r\n    struct ImageView\r\n    {\r\n        // Creates a non-owning view using the given data.\r\n        ImageView(UINT width, UINT height, UINT stride, UINT byteCount, BYTE* bytes);\r\n\r\n        // Create a view by locking a bitmap.\r\n        // This must be used from the same thread as the bitmap.\r\n        static ImageView Lock(IWICBitmap* imageSource);\r\n\r\n        // Create a view by copying the pixels from the image.\r\n        static ImageView Copy(IWICBitmapSource* imageSource);\r\n\r\n        // Translate the view by the given pixel counts.\r\n        // The pixel at [0, 0] of the original will be at [x, y].\r\n        // If tile is true, the view will % coordinates outside of its dimensions back into its own view.\r\n        // If tile is false, coordinates outside of the view will be null.\r\n        void Translate(INT x, INT y, bool tile);\r\n\r\n        // Gets the pixel of the view at the given coordinate.\r\n        // Returns null if the coordinate is outside of the view.\r\n        const BYTE* GetPixel(UINT x, UINT y) const;\r\n\r\n        // Get the dimensions of the view.\r\n        UINT Width() const;\r\n        UINT Height() const;\r\n\r\n    private:\r\n        ImageView() = default;\r\n\r\n        bool m_tile = false;\r\n        UINT m_translateX = 0;\r\n        UINT m_translateY = 0;\r\n\r\n        wil::com_ptr<IWICBitmapLock> m_lockedImage;\r\n        std::unique_ptr<BYTE[]> m_copiedImage;\r\n\r\n        UINT m_viewWidth = 0;\r\n        UINT m_viewHeight = 0;\r\n        UINT m_viewStride = 0;\r\n        UINT m_viewByteCount = 0;\r\n        BYTE* m_viewBytes = nullptr;\r\n    };\r\n\r\n    // The set of values that defines the rendered output.\r\n    struct RenderControls\r\n    {\r\n        // Yes, its right there in the name but the compiler can't read...\r\n        static constexpr UINT PixelsPerSixel = 6;\r\n\r\n        // Each cell is always a height of 20 and a width of 10, regardless of the screen resolution of the terminal.\r\n        static constexpr UINT CellHeightInPixels = 20;\r\n        static constexpr UINT CellWidthInPixels = 10;\r\n\r\n        Sixel::AspectRatio AspectRatio = AspectRatio::OneToOne;\r\n        bool TransparencyEnabled = true;\r\n        bool StretchSourceToFill = false;\r\n        bool UseRepeatSequence = false;\r\n        UINT ColorCount = Palette::MaximumColorCount;\r\n        UINT PixelWidth = 0;\r\n        UINT PixelHeight = 0;\r\n        Sixel::InterpolationMode InterpolationMode = InterpolationMode::HighQualityCubic;\r\n\r\n        // The resulting sixel image will render to this size in terminal cells,\r\n        // consuming as much as possible of the given size without going over.\r\n        void RenderSizeInCells(UINT width, UINT height);\r\n    };\r\n\r\n    // Contains an image that can be manipulated and rendered to sixels.\r\n    struct ImageSource\r\n    {\r\n        // Create an image source from a file.\r\n        explicit ImageSource(const std::filesystem::path& imageFilePath);\r\n\r\n        // Create an empty image source.\r\n        ImageSource() = default;\r\n\r\n        // Create an image source from a stream.\r\n        ImageSource(std::istream& imageStream, Manifest::IconFileTypeEnum imageEncoding);\r\n\r\n        // Create an image source from bytes.\r\n        ImageSource(const std::vector<uint8_t>& imageBytes, Manifest::IconFileTypeEnum imageEncoding);\r\n\r\n        // Resize the image to the given width and height, factoring in the target aspect ratio for rendering.\r\n        // If stretchToFill is true, the resulting image will be both the given width and height.\r\n        // If false, the resulting image will be at most the given width or height while preserving the aspect ratio.\r\n        void Resize(UINT pixelWidth, UINT pixelHeight, AspectRatio targetRenderRatio, bool stretchToFill = false, InterpolationMode interpolationMode = InterpolationMode::HighQualityCubic);\r\n\r\n        // Resizes the image using the given render controls.\r\n        void Resize(const RenderControls& controls);\r\n\r\n        // Creates a palette from the current image.\r\n        Palette CreatePalette(UINT colorCount, bool transparencyEnabled) const;\r\n\r\n        // Creates a palette from the current image.\r\n        Palette CreatePalette(const RenderControls& controls) const;\r\n\r\n        // Converts the image to be 8bpp indexed for the given palette.\r\n        void ApplyPalette(const Palette& palette);\r\n\r\n        // Create a view by locking the image source.\r\n        // This must be used from the same thread as the image source.\r\n        ImageView Lock() const;\r\n\r\n        // Create a view by copying the pixels from the image source.\r\n        ImageView Copy() const;\r\n\r\n    private:\r\n        wil::com_ptr<IWICImagingFactory> m_factory;\r\n        wil::com_ptr<IWICBitmap> m_sourceImage;\r\n    };\r\n\r\n    // Allows one or more image sources to be rendered to a sixel output.\r\n    struct Compositor\r\n    {\r\n        // Create an empty compositor.\r\n        Compositor() = default;\r\n\r\n        // Set the palette to be used by the compositor.\r\n        void Palette(Palette palette);\r\n\r\n        // Adds a new view to the compositor. Each successive view will be behind all of the others.\r\n        void AddView(ImageView&& view);\r\n\r\n        // Gets the number of views in the compositor.\r\n        size_t ViewCount() const;\r\n\r\n        // Gets the color at the given index in the palette.\r\n        ImageView& operator[](size_t index);\r\n        const ImageView& operator[](size_t index) const;\r\n\r\n        // Get the render controls for the compositor.\r\n        RenderControls& Controls();\r\n        const RenderControls& Controls() const;\r\n\r\n        // Render to sixel format for storage / use multiple times.\r\n        ConstructedSequence Render();\r\n\r\n        // Renders to sixel format directly to the stream.\r\n        void RenderTo(Execution::BaseStream& stream);\r\n\r\n        // Renders to sixel format directly to the stream.\r\n        void RenderTo(Execution::OutputStream& stream);\r\n\r\n    private:\r\n        RenderControls m_renderControls;\r\n        Sixel::Palette m_palette;\r\n        std::vector<ImageView> m_views;\r\n    };\r\n\r\n    // A helpful wrapper around the sixel image primitives that makes rendering a single image easier.\r\n    struct Image\r\n    {\r\n        // Create an image from a file.\r\n        Image(const std::filesystem::path& imageFilePath);\r\n\r\n        // Create an image from a stream.\r\n        Image(std::istream& imageStream, Manifest::IconFileTypeEnum imageEncoding);\r\n\r\n        // Create an image from bytes.\r\n        Image(const std::vector<uint8_t>& imageBytes, Manifest::IconFileTypeEnum imageEncoding);\r\n\r\n        // Set the aspect ratio of the result.\r\n        Image& AspectRatio(AspectRatio aspectRatio);\r\n\r\n        // Determine whether transparency is enabled.\r\n        // This will affect whether transparent pixels are rendered or not.\r\n        Image& Transparency(bool transparencyEnabled);\r\n\r\n        // If transparency is enabled, one of the colors will be reserved for it.\r\n        Image& ColorCount(UINT colorCount);\r\n\r\n        // The resulting sixel image will render to this size in terminal cell pixels.\r\n        Image& RenderSizeInPixels(UINT width, UINT height);\r\n\r\n        // The resulting sixel image will render to this size in terminal cells,\r\n        // consuming as much as possible of the given size without going over.\r\n        Image& RenderSizeInCells(UINT width, UINT height);\r\n\r\n        // Only affects the scaling of the image that occurs when render size is set.\r\n        // When true, the source image will be stretched to fill the target size.\r\n        // When false, the source image will be scaled while keeping its original aspect ratio.\r\n        Image& StretchSourceToFill(bool stretchSourceToFill);\r\n\r\n        // Compresses the output using repeat sequences.\r\n        Image& UseRepeatSequence(bool useRepeatSequence);\r\n\r\n        // Render to sixel format for storage / use multiple times.\r\n        ConstructedSequence Render();\r\n\r\n        // Renders to sixel format directly to the output stream.\r\n        void RenderTo(Execution::OutputStream& stream);\r\n\r\n    private:\r\n        // Creates a compositor for the image using the current render controls.\r\n        std::pair<ImageSource, Compositor> CreateCompositor();\r\n\r\n        ImageSource m_imageSource;\r\n        RenderControls m_renderControls;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/TableOutput.h",
    "content": "﻿// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ExecutionReporter.h\"\r\n#include \"Resources.h\"\r\n\r\n#include <array>\r\n#include <ostream>\r\n#include <string>\r\n#include <vector>\r\n\r\n\r\nnamespace AppInstaller::CLI::Execution\r\n{\r\n    // Enables output data in a table format.\r\n    // TODO: Improve for use with sparse data.\r\n    template <size_t FieldCount>\r\n    struct TableOutput\r\n    {\r\n        using header_t = std::array<Resource::LocString, FieldCount>;\r\n        using line_t = std::array<std::string, FieldCount>;\r\n\r\n        TableOutput(Reporter& reporter, header_t&& header, size_t sizingBuffer = 50) :\r\n            m_reporter(reporter), m_sizingBuffer(sizingBuffer)\r\n        {\r\n            for (size_t i = 0; i < FieldCount; ++i)\r\n            {\r\n                m_columns[i].Name = std::move(header[i]);\r\n                m_columns[i].MinLength = Utility::UTF8ColumnWidth(m_columns[i].Name.get());\r\n                m_columns[i].MaxLength = 0;\r\n            }\r\n        }\r\n\r\n        void OutputLine(line_t&& line)\r\n        {\r\n            m_empty = false;\r\n\r\n            if (m_buffer.size() < m_sizingBuffer)\r\n            {\r\n                m_buffer.emplace_back(std::move(line));\r\n            }\r\n            else\r\n            {\r\n                EvaluateAndFlushBuffer();\r\n                OutputLineToStream(line);\r\n            }\r\n        }\r\n\r\n        void Complete()\r\n        {\r\n            if (!m_empty)\r\n            {\r\n                EvaluateAndFlushBuffer();\r\n            }\r\n        }\r\n\r\n        bool IsEmpty()\r\n        {\r\n            return m_empty;\r\n        }\r\n\r\n    private:\r\n        // A column in the table.\r\n        struct Column\r\n        {\r\n            Resource::LocString Name;\r\n            size_t MinLength = 0;\r\n            size_t MaxLength = 0;\r\n            bool SpaceAfter = true;\r\n        };\r\n\r\n        Reporter& m_reporter;\r\n        std::array<Column, FieldCount> m_columns;\r\n        size_t m_sizingBuffer;\r\n        std::vector<line_t> m_buffer;\r\n        bool m_bufferEvaluated = false;\r\n        bool m_empty = true;\r\n\r\n        void EvaluateAndFlushBuffer()\r\n        {\r\n            if (m_bufferEvaluated)\r\n            {\r\n                return;\r\n            }\r\n\r\n            // Determine the maximum length for all columns\r\n            for (const auto& line : m_buffer)\r\n            {\r\n                for (size_t i = 0; i < FieldCount; ++i)\r\n                {\r\n                    m_columns[i].MaxLength = std::max(m_columns[i].MaxLength, Utility::UTF8ColumnWidth(line[i]));\r\n                }\r\n            }\r\n\r\n            // If there are actually columns with data, then also bring in the minimum size\r\n            for (size_t i = 0; i < FieldCount; ++i)\r\n            {\r\n                if (m_columns[i].MaxLength)\r\n                {\r\n                    m_columns[i].MaxLength = std::max(m_columns[i].MaxLength, m_columns[i].MinLength);\r\n                }\r\n            }\r\n\r\n            // Only output the extra space if:\r\n            // 1. Not the last field\r\n            m_columns[FieldCount - 1].SpaceAfter = false;\r\n\r\n            // 2. Not empty (taken care of by not doing anything if empty)\r\n            // 3. There are non-empty fields after\r\n            for (size_t i = FieldCount - 1; i > 0; --i)\r\n            {\r\n                if (m_columns[i].MaxLength)\r\n                {\r\n                    break;\r\n                }\r\n                else\r\n                {\r\n                    m_columns[i - 1].SpaceAfter = false;\r\n                }\r\n            }\r\n\r\n            // Determine the total width required to not truncate any columns\r\n            size_t totalRequired = 0;\r\n\r\n            for (size_t i = 0; i < FieldCount; ++i)\r\n            {\r\n                totalRequired += m_columns[i].MaxLength + (m_columns[i].SpaceAfter ? 1 : 0);\r\n            }\r\n\r\n            size_t consoleWidth = GetConsoleWidth();\r\n\r\n            // If the total space would be too big, shrink them.\r\n            // We don't want to use the last column, lest we auto-wrap\r\n            if (totalRequired >= consoleWidth)\r\n            {\r\n                size_t extra = (totalRequired - consoleWidth) + 1;\r\n\r\n                while (extra)\r\n                {\r\n                    size_t targetIndex = 0;\r\n                    size_t targetVal = m_columns[0].MaxLength;\r\n                    for (size_t j = 1; j < FieldCount; ++j)\r\n                    {\r\n                        if (m_columns[j].MaxLength > targetVal)\r\n                        {\r\n                            targetIndex = j;\r\n                            targetVal = m_columns[j].MaxLength;\r\n                        }\r\n                    }\r\n                    m_columns[targetIndex].MaxLength -= 1;\r\n                    extra -= 1;\r\n                }\r\n\r\n                totalRequired = consoleWidth - 1;\r\n            }\r\n\r\n            // Header line\r\n            line_t headerLine;\r\n\r\n            for (size_t i = 0; i < FieldCount; ++i)\r\n            {\r\n                headerLine[i] = m_columns[i].Name.get();\r\n            }\r\n\r\n            OutputLineToStream(headerLine);\r\n\r\n            m_reporter.Info() << std::string(totalRequired, '-') << std::endl;\r\n\r\n            for (const auto& line : m_buffer)\r\n            {\r\n                OutputLineToStream(line);\r\n            }\r\n\r\n            m_bufferEvaluated = true;\r\n        }\r\n\r\n        void OutputLineToStream(const line_t& line)\r\n        {\r\n            auto out = m_reporter.Info();\r\n\r\n            for (size_t i = 0; i < FieldCount; ++i)\r\n            {\r\n                const auto& col = m_columns[i];\r\n\r\n                if (col.MaxLength)\r\n                {\r\n                    size_t valueLength = Utility::UTF8ColumnWidth(line[i]);\r\n\r\n                    if (valueLength > col.MaxLength)\r\n                    {\r\n                        size_t actualWidth;\r\n                        out << Utility::UTF8TrimRightToColumnWidth(line[i], col.MaxLength - 1, actualWidth) << \"\\xE2\\x80\\xA6\"; // UTF8 encoding of ellipsis (…) character\r\n\r\n                        // Some characters take 2 unit space, the trimmed string length might be 1 less than the expected length.\r\n                        if (actualWidth != col.MaxLength - 1)\r\n                        {\r\n                            out << ' ';\r\n                        }\r\n\r\n                        if (col.SpaceAfter)\r\n                        {\r\n                            out << ' ';\r\n                        }\r\n                    }\r\n                    else\r\n                    {\r\n                        out << line[i];\r\n\r\n                        if (col.SpaceAfter)\r\n                        {\r\n                            out << std::string(col.MaxLength - valueLength + 1, ' ');\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            out << std::endl;\r\n        }\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/VTSupport.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"VTSupport.h\"\r\n#include <AppInstallerLogging.h>\r\n#include <AppInstallerStrings.h>\r\n\r\nnamespace AppInstaller::CLI::VirtualTerminal\r\n{\r\n    namespace\r\n    {\r\n        TextFormat::Color GetAccentColorFromSystem()\r\n        {\r\n            using namespace winrt::Windows::UI::ViewManagement;\r\n\r\n            UISettings settings;\r\n            auto color = settings.GetColorValue(UIColorType::Accent);\r\n            return { color.R, color.G, color.B };\r\n        }\r\n\r\n        bool InitializeMode(DWORD handle, DWORD& previousMode, std::initializer_list<DWORD> modeModifierFallbacks, DWORD disabledFlags = 0)\r\n        {\r\n            HANDLE hStd = GetStdHandle(handle);\r\n            if (hStd == INVALID_HANDLE_VALUE)\r\n            {\r\n                LOG_LAST_ERROR();\r\n            }\r\n            else if (hStd == NULL)\r\n            {\r\n                AICLI_LOG(CLI, Info, << \"VT not enabled due to null handle [\" << handle << \"]\");\r\n            }\r\n            else\r\n            {\r\n                if (!GetConsoleMode(hStd, &previousMode))\r\n                {\r\n                    // If the user redirects output, the handle will be invalid for this function.\r\n                    // Don't log it in that case.\r\n                    LOG_LAST_ERROR_IF(GetLastError() != ERROR_INVALID_HANDLE);\r\n                }\r\n                else\r\n                {\r\n                    for (DWORD mode : modeModifierFallbacks)\r\n                    {\r\n                        DWORD outMode = (previousMode & ~disabledFlags) | mode;\r\n                        if (!SetConsoleMode(hStd, outMode))\r\n                        {\r\n                            // Even if it is a different error, log it and try to carry on.\r\n                            LOG_LAST_ERROR_IF(GetLastError() != STATUS_INVALID_PARAMETER);\r\n                        }\r\n                        else\r\n                        {\r\n                            return true;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            return false;\r\n        }\r\n\r\n        // Extracts a VT sequence, expected one of the form ESCAPE + prefix + result + suffix, returning the result part.\r\n        std::string ExtractSequence(std::istream& inStream, std::string_view prefix, std::string_view suffix)\r\n        {\r\n            // Force discovery of available input\r\n            std::ignore = inStream.peek();\r\n\r\n            static constexpr std::streamsize s_bufferSize = 1024;\r\n            char buffer[s_bufferSize];\r\n            std::streamsize bytesRead = inStream.readsome(buffer, s_bufferSize);\r\n            THROW_HR_IF(E_UNEXPECTED, bytesRead >= s_bufferSize);\r\n\r\n            std::string_view resultView{ buffer, static_cast<size_t>(bytesRead) };\r\n            size_t escapeIndex = resultView.find(AICLI_VT_ESCAPE[0]);\r\n            if (escapeIndex == std::string_view::npos)\r\n            {\r\n                return {};\r\n            }\r\n\r\n            resultView = resultView.substr(escapeIndex);\r\n            size_t overheadLength = 1 + prefix.length() + suffix.length();\r\n            if (resultView.length() <= overheadLength ||\r\n                resultView.substr(1, prefix.length()) != prefix ||\r\n                resultView.substr(resultView.length() - suffix.length()) != suffix)\r\n            {\r\n                return {};\r\n            }\r\n\r\n            return std::string{ resultView.substr(1 + prefix.length(), resultView.length() - overheadLength) };\r\n        }\r\n    }\r\n\r\n    ConsoleModeRestoreBase::ConsoleModeRestoreBase(DWORD handle) : m_handle(handle) {}\r\n\r\n    ConsoleModeRestoreBase::~ConsoleModeRestoreBase()\r\n    {\r\n        if (m_token)\r\n        {\r\n            LOG_LAST_ERROR_IF(!SetConsoleMode(GetStdHandle(m_handle), m_previousMode));\r\n            m_token = false;\r\n        }\r\n    }\r\n\r\n    ConsoleModeRestore::ConsoleModeRestore() : ConsoleModeRestoreBase(STD_OUTPUT_HANDLE)\r\n    {\r\n        m_token = InitializeMode(STD_OUTPUT_HANDLE, m_previousMode, { ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN, ENABLE_VIRTUAL_TERMINAL_PROCESSING });\r\n    }\r\n\r\n    const ConsoleModeRestore& ConsoleModeRestore::Instance()\r\n    {\r\n        static ConsoleModeRestore s_instance;\r\n        return s_instance;\r\n    }\r\n\r\n    ConsoleInputModeRestore::ConsoleInputModeRestore() : ConsoleModeRestoreBase(STD_INPUT_HANDLE)\r\n    {\r\n        m_token = InitializeMode(STD_INPUT_HANDLE, m_previousMode, { ENABLE_EXTENDED_FLAGS | ENABLE_VIRTUAL_TERMINAL_INPUT }, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);\r\n    }\r\n\r\n    void ConstructedSequence::Append(const Sequence& sequence)\r\n    {\r\n        if (!sequence.Get().empty())\r\n        {\r\n            m_str += sequence.Get();\r\n            Set(m_str);\r\n        }\r\n    }\r\n\r\n    void ConstructedSequence::Clear()\r\n    {\r\n        m_str.clear();\r\n        Set(m_str);\r\n    }\r\n\r\n// The beginning of a Control Sequence Introducer\r\n#define AICLI_VT_CSI        AICLI_VT_ESCAPE \"[\"\r\n\r\n// The beginning of an Operating system command\r\n#define AICLI_VT_OSC        AICLI_VT_ESCAPE \"]\"\r\n\r\n    PrimaryDeviceAttributes::PrimaryDeviceAttributes(std::ostream& outStream, std::istream& inStream)\r\n    {\r\n        try\r\n        {\r\n            ConsoleInputModeRestore inputMode;\r\n            if (!inputMode.IsVTEnabled())\r\n            {\r\n                return;\r\n            }\r\n\r\n            // Send DA1 Primary Device Attributes request\r\n            outStream << AICLI_VT_CSI << \"0c\";\r\n            outStream.flush();\r\n\r\n            // Response is of the form AICLI_VT_CSI ? <conformance level> ; (<extension number> ;)* c\r\n            std::string sequence = ExtractSequence(inStream, \"[?\", \"c\");\r\n            std::vector<std::string> values = Utility::Split(sequence, ';');\r\n\r\n            if (!values.empty())\r\n            {\r\n                m_conformanceLevel = std::stoul(values[0]);\r\n            }\r\n\r\n            for (size_t i = 1; i < values.size(); ++i)\r\n            {\r\n                m_extensions |= 1ull << std::stoul(values[i]);\r\n            }\r\n        }\r\n        CATCH_LOG();\r\n    }\r\n\r\n    bool PrimaryDeviceAttributes::Supports(Extension extension) const\r\n    {\r\n        uint64_t extensionMask = 1ull << ToIntegral(extension);\r\n        return (m_extensions & extensionMask) == extensionMask;\r\n    }\r\n\r\n    namespace Cursor\r\n    {\r\n        namespace Position\r\n        {\r\n            ConstructedSequence Up(int16_t cells)\r\n            {\r\n                THROW_HR_IF(E_INVALIDARG, cells < 0);\r\n                std::ostringstream result;\r\n                result << AICLI_VT_CSI << cells << 'A';\r\n                return ConstructedSequence{ std::move(result).str() };\r\n            }\r\n\r\n            ConstructedSequence Down(int16_t cells)\r\n            {\r\n                THROW_HR_IF(E_INVALIDARG, cells < 0);\r\n                std::ostringstream result;\r\n                result << AICLI_VT_CSI << cells << 'B';\r\n                return ConstructedSequence{ std::move(result).str() };\r\n            }\r\n\r\n            ConstructedSequence Forward(int16_t cells)\r\n            {\r\n                THROW_HR_IF(E_INVALIDARG, cells < 0);\r\n                std::ostringstream result;\r\n                result << AICLI_VT_CSI << cells << 'C';\r\n                return ConstructedSequence{ std::move(result).str() };\r\n            }\r\n\r\n            ConstructedSequence Backward(int16_t cells)\r\n            {\r\n                THROW_HR_IF(E_INVALIDARG, cells < 0);\r\n                std::ostringstream result;\r\n                result << AICLI_VT_CSI << cells << 'D';\r\n                return ConstructedSequence{ std::move(result).str() };\r\n            }\r\n        }\r\n\r\n        namespace Visibility\r\n        {\r\n            const Sequence EnableBlink{ AICLI_VT_CSI \"?12h\" };\r\n            const Sequence DisableBlink{ AICLI_VT_CSI \"?12l\" };\r\n            const Sequence EnableShow{ AICLI_VT_CSI \"?25h\" };\r\n            const Sequence DisableShow{ AICLI_VT_CSI \"?25l\" };\r\n        }\r\n    }\r\n\r\n    namespace TextFormat\r\n    {\r\n// Define a text formatting sequence with an integer id\r\n#define AICLI_VT_TEXTFORMAT(_id_)       AICLI_VT_CSI #_id_ \"m\"\r\n\r\n        const Sequence Default{ AICLI_VT_TEXTFORMAT(0) };\r\n        const Sequence Negative{ AICLI_VT_TEXTFORMAT(7) };\r\n\r\n        Color Color::GetAccentColor()\r\n        {\r\n            static Color accent{ GetAccentColorFromSystem() };\r\n            return accent;\r\n        }\r\n\r\n        namespace Foreground\r\n        {\r\n            const Sequence Bright{ AICLI_VT_TEXTFORMAT(1) };\r\n            const Sequence NoBright{ AICLI_VT_TEXTFORMAT(22) };\r\n\r\n            const Sequence BrightRed{ AICLI_VT_TEXTFORMAT(91) };\r\n            const Sequence BrightGreen{ AICLI_VT_TEXTFORMAT(92) };\r\n            const Sequence BrightYellow{ AICLI_VT_TEXTFORMAT(93) };\r\n            const Sequence BrightBlue{ AICLI_VT_TEXTFORMAT(94) };\r\n            const Sequence BrightMagenta{ AICLI_VT_TEXTFORMAT(95) };\r\n            const Sequence BrightCyan{ AICLI_VT_TEXTFORMAT(96) };\r\n            const Sequence BrightWhite{ AICLI_VT_TEXTFORMAT(97) };\r\n\r\n            ConstructedSequence Extended(const Color& color)\r\n            {\r\n                std::ostringstream result;\r\n                result << AICLI_VT_CSI \"38;2;\" << static_cast<uint32_t>(color.R) << ';' << static_cast<uint32_t>(color.G) << ';' << static_cast<uint32_t>(color.B) << 'm';\r\n                return ConstructedSequence{ std::move(result).str() };\r\n            }\r\n        }\r\n\r\n        namespace Background\r\n        {\r\n            ConstructedSequence Extended(const Color& color)\r\n            {\r\n                std::ostringstream result;\r\n                result << AICLI_VT_CSI \"48;2;\" << static_cast<uint32_t>(color.R) << ';' << static_cast<uint32_t>(color.G) << ';' << static_cast<uint32_t>(color.B) << 'm';\r\n                return ConstructedSequence{ std::move(result).str() };\r\n            }\r\n        }\r\n\r\n        ConstructedSequence Hyperlink(const std::string& text, const std::string& ref)\r\n        {\r\n            std::ostringstream result;\r\n            result << AICLI_VT_OSC \"8;;\" << ref << AICLI_VT_ESCAPE << \"\\\\\" << text << AICLI_VT_OSC << \"8;;\" << AICLI_VT_ESCAPE << \"\\\\\";\r\n            return ConstructedSequence{ std::move(result).str() };\r\n        }\r\n    }\r\n\r\n    namespace TextModification\r\n    {\r\n        const Sequence EraseLineForward{ AICLI_VT_CSI \"0K\" };\r\n        const Sequence EraseLineBackward{ AICLI_VT_CSI \"1K\" };\r\n        const Sequence EraseLineEntirely{ AICLI_VT_CSI \"2K\" };\r\n    }\r\n\r\n    namespace Progress\r\n    {\r\n        ConstructedSequence Construct(State state, std::optional<uint32_t> percentage)\r\n        {\r\n            // See https://conemu.github.io/en/AnsiEscapeCodes.html#ConEmu_specific_OSC\r\n\r\n            THROW_HR_IF(E_BOUNDS, percentage.has_value() && percentage > 100u);\r\n\r\n            // Workaround some quirks in the Windows Terminal implementation of the progress OSC sequence\r\n            switch (state)\r\n            {\r\n            case State::None:\r\n            case State::Indeterminate:\r\n                // Windows Terminal does not recognize the OSC sequence if the progress value is left out.\r\n                // As a workaround, we can specify an arbitrary value since it does not matter for None and Indeterminate states.\r\n                percentage = percentage.value_or(0);\r\n                break;\r\n            case State::Normal:\r\n            case State::Error:\r\n            case State::Paused:\r\n                // Windows Terminal does not support switching progress states without also setting a progress value at the same time,\r\n                // so we disallow this case for now.\r\n                THROW_HR_IF(E_INVALIDARG, !percentage.has_value());\r\n                break;\r\n            }\r\n\r\n            int stateId;\r\n            switch (state)\r\n            {\r\n            case State::None:\r\n                stateId = 0;\r\n                break;\r\n            case State::Indeterminate:\r\n                stateId = 3;\r\n                break;\r\n            case State::Normal:\r\n                stateId = 1;\r\n                break;\r\n            case State::Error:\r\n                stateId = 2;\r\n                break;\r\n            case State::Paused:\r\n                stateId = 4;\r\n                break;\r\n            default:\r\n                THROW_HR(E_UNEXPECTED);\r\n            }\r\n\r\n            std::ostringstream result;\r\n            result << AICLI_VT_OSC \"9;4;\" << stateId << \";\";\r\n            if (percentage.has_value())\r\n            {\r\n                result << percentage.value();\r\n            }\r\n            result << AICLI_VT_ESCAPE << \"\\\\\";\r\n            return ConstructedSequence{ std::move(result).str() };\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/VTSupport.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerLanguageUtilities.h>\r\n\r\n#include <cstdint>\r\n#include <iostream>\r\n#include <optional>\r\n#include <string>\r\n#include <string_view>\r\n\r\n\r\n// The escape character that begins all VT sequences\r\n#define AICLI_VT_ESCAPE     \"\\x1b\"\r\n\r\nnamespace AppInstaller::CLI::VirtualTerminal\r\n{\r\n    // RAII class to enable VT support and restore the console mode.\r\n    struct ConsoleModeRestoreBase\r\n    {\r\n        ConsoleModeRestoreBase(DWORD handle);\r\n        ~ConsoleModeRestoreBase();\r\n\r\n        ConsoleModeRestoreBase(const ConsoleModeRestoreBase&) = delete;\r\n        ConsoleModeRestoreBase& operator=(const ConsoleModeRestoreBase&) = delete;\r\n\r\n        ConsoleModeRestoreBase(ConsoleModeRestoreBase&&) = default;\r\n        ConsoleModeRestoreBase& operator=(ConsoleModeRestoreBase&&) = default;\r\n\r\n        // Returns true if VT support has been enabled for the console.\r\n        bool IsVTEnabled() const { return m_token; }\r\n\r\n    protected:\r\n        DestructionToken m_token = false;\r\n        DWORD m_handle = 0;\r\n        DWORD m_previousMode = 0;\r\n    };\r\n\r\n    // RAII class to enable VT output support and restore the console mode.\r\n    struct ConsoleModeRestore : public ConsoleModeRestoreBase\r\n    {\r\n        ConsoleModeRestore(const ConsoleModeRestore&) = delete;\r\n        ConsoleModeRestore& operator=(const ConsoleModeRestore&) = delete;\r\n\r\n        ConsoleModeRestore(ConsoleModeRestore&&) = default;\r\n        ConsoleModeRestore& operator=(ConsoleModeRestore&&) = default;\r\n\r\n        // Gets the singleton.\r\n        static const ConsoleModeRestore& Instance();\r\n\r\n    private:\r\n        ConsoleModeRestore();\r\n    };\r\n\r\n    // RAII class to enable VT input support and restore the console mode.\r\n    struct ConsoleInputModeRestore : public ConsoleModeRestoreBase\r\n    {\r\n        ConsoleInputModeRestore();\r\n\r\n        ConsoleInputModeRestore(const ConsoleInputModeRestore&) = delete;\r\n        ConsoleInputModeRestore& operator=(const ConsoleInputModeRestore&) = delete;\r\n\r\n        ConsoleInputModeRestore(ConsoleInputModeRestore&&) = default;\r\n        ConsoleInputModeRestore& operator=(ConsoleInputModeRestore&&) = default;\r\n    };\r\n\r\n    // The base for all VT sequences.\r\n    struct Sequence\r\n    {\r\n        constexpr Sequence() = default;\r\n        explicit constexpr Sequence(std::string_view c) : m_chars(c) {}\r\n\r\n        std::string_view Get() const { return m_chars; }\r\n\r\n    protected:\r\n        void Set(const std::string& s) { m_chars = s; }\r\n\r\n    private:\r\n        std::string_view m_chars;\r\n    };\r\n\r\n    // A VT sequence that is constructed at runtime.\r\n    struct ConstructedSequence : public Sequence\r\n    {\r\n        ConstructedSequence() { Set(m_str); }\r\n        explicit ConstructedSequence(std::string s) : m_str(std::move(s)) { Set(m_str); }\r\n\r\n        ConstructedSequence(const ConstructedSequence& other) : m_str(other.m_str) { Set(m_str); }\r\n        ConstructedSequence& operator=(const ConstructedSequence& other) { m_str = other.m_str; Set(m_str); return *this; }\r\n\r\n        ConstructedSequence(ConstructedSequence&& other) noexcept : m_str(std::move(other.m_str)) { Set(m_str); }\r\n        ConstructedSequence& operator=(ConstructedSequence&& other) noexcept { m_str = std::move(other.m_str); Set(m_str); return *this; }\r\n\r\n        void Append(const Sequence& sequence);\r\n\r\n        void Clear();\r\n\r\n    private:\r\n        std::string m_str;\r\n    };\r\n\r\n    // Below are mapped to the sequences described here:\r\n    // https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences\r\n\r\n    // Contains the response to a DA1 (Primary Device Attributes) request.\r\n    struct PrimaryDeviceAttributes\r\n    {\r\n        // Queries the device attributes on creation.\r\n        PrimaryDeviceAttributes(std::ostream& outStream, std::istream& inStream);\r\n\r\n        // The extensions that a device may support.\r\n        enum class Extension\r\n        {\r\n            Columns132 = 1,\r\n            PrinterPort = 2,\r\n            Sixel = 4,\r\n            SelectiveErase = 6,\r\n            SoftCharacterSet = 7,\r\n            UserDefinedKeys = 8,\r\n            NationalReplacementCharacterSets = 9,\r\n            SoftCharacterSet2 = 12,\r\n            EightBitInterface = 14,\r\n            TechnicalCharacterSet = 15,\r\n            WindowingCapability = 18,\r\n            HorizontalScrolling = 21,\r\n            ColorText = 22,\r\n            Greek = 23,\r\n            Turkish = 24,\r\n            RectangularAreaOperations = 28,\r\n            TextMacros = 32,\r\n            ISO_Latin2CharacterSet = 42,\r\n            PC_Term = 44,\r\n            SoftKeyMap = 45,\r\n            ASCII_Emulation = 46,\r\n        };\r\n\r\n        // Determines if the given extension is supported.\r\n        bool Supports(Extension extension) const;\r\n\r\n    private:\r\n        uint32_t m_conformanceLevel = 0;\r\n        uint64_t m_extensions = 0;\r\n    };\r\n\r\n    namespace Cursor\r\n    {\r\n        namespace Position\r\n        {\r\n            ConstructedSequence Up(int16_t cells);\r\n            ConstructedSequence Down(int16_t cells);\r\n            ConstructedSequence Forward(int16_t cells);\r\n            ConstructedSequence Backward(int16_t cells);\r\n        }\r\n\r\n        namespace Visibility\r\n        {\r\n            extern const Sequence EnableBlink;\r\n            extern const Sequence DisableBlink;\r\n            extern const Sequence EnableShow;\r\n            extern const Sequence DisableShow;\r\n        }\r\n    }\r\n\r\n    namespace TextFormat\r\n    {\r\n        // Returns all attributes to the default state prior to modification\r\n        extern const Sequence Default;\r\n\r\n        // Swaps foreground and background colors\r\n        extern const Sequence Negative;\r\n\r\n        // A color, used in constructed sequences.\r\n        struct Color\r\n        {\r\n            uint8_t R;\r\n            uint8_t G;\r\n            uint8_t B;\r\n\r\n            static Color GetAccentColor();\r\n        };\r\n\r\n        namespace Foreground\r\n        {\r\n            // Applies brightness/intensity flag to foreground color\r\n            extern const Sequence Bright;\r\n            // Removes brightness/intensity flag from foreground color\r\n            extern const Sequence NoBright;\r\n\r\n            extern const Sequence BrightRed;\r\n            extern const Sequence BrightGreen;\r\n            extern const Sequence BrightYellow;\r\n            extern const Sequence BrightBlue;\r\n            extern const Sequence BrightMagenta;\r\n            extern const Sequence BrightCyan;\r\n            extern const Sequence BrightWhite;\r\n\r\n            ConstructedSequence Extended(const Color& color);\r\n        }\r\n\r\n        namespace Background\r\n        {\r\n            ConstructedSequence Extended(const Color& color);\r\n        }\r\n\r\n        ConstructedSequence Hyperlink(const std::string& text, const std::string& ref);\r\n    }\r\n\r\n    namespace TextModification\r\n    {\r\n        extern const Sequence EraseLineForward;\r\n        extern const Sequence EraseLineBackward;\r\n        extern const Sequence EraseLineEntirely;\r\n    }\r\n\r\n    namespace Progress\r\n    {\r\n        enum class State\r\n        {\r\n            None,\r\n            Indeterminate,\r\n            Normal,\r\n            Paused,\r\n            Error\r\n        };\r\n\r\n        ConstructedSequence Construct(State state, std::optional<uint32_t> percentage = std::nullopt);\r\n    }\r\n}\r\n\r\ninline std::ostream& operator<<(std::ostream& o, const AppInstaller::CLI::VirtualTerminal::Sequence& s)\r\n{\r\n    return (o << s.Get());\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/ArchiveFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"ArchiveFlow.h\"\n#include \"PortableFlow.h\"\r\n#include \"ShellExecuteInstallerHandler.h\"\n#include <winget/AdminSettings.h>\n#include <winget/Archive.h>\r\n#include <winget/Filesystem.h>\n\nusing namespace AppInstaller::Manifest;\n\nnamespace AppInstaller::CLI::Workflow\n{\n    namespace\n    {\n        constexpr std::wstring_view s_Extracted = L\"extracted\";\n    }\n\n    void ScanArchiveFromLocalManifest(Execution::Context& context)\n    {\n        if (context.Args.Contains(Execution::Args::Type::Manifest))\n        {\n            bool scanResult = Archive::ScanZipFile(context.Get<Execution::Data::InstallerPath>());\n\n            if (scanResult)\n            {\n                AICLI_LOG(CLI, Info, << \"Archive malware scan passed\");\n            }\n            else\n            {\n                if (context.Args.Contains(Execution::Args::Type::IgnoreLocalArchiveMalwareScan) &&\n                    Settings::IsAdminSettingEnabled(Settings::BoolAdminSetting::LocalArchiveMalwareScanOverride))\n                {\n                    AICLI_LOG(CLI, Warning, << \"Archive scan detected malware. Proceeding due to --ignore-local-archive-malware-scan\");\n                    context.Reporter.Warn() << Resource::String::ArchiveFailedMalwareScanOverridden << std::endl;\n                }\n                else\n                {\n                    AICLI_LOG(CLI, Error, << \"Archive malware scan failed\");\n                    context.Reporter.Error() << Resource::String::ArchiveFailedMalwareScan << std::endl;\n                    AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_ARCHIVE_SCAN_FAILED);\n                }\n            }\n        }\n    }\r\n\r\n    void ExtractFilesFromArchive(Execution::Context& context)\r\n    {\r\n        const auto& installerPath = context.Get<Execution::Data::InstallerPath>();\n        std::filesystem::path destinationFolder = installerPath.parent_path() / s_Extracted;\n        std::filesystem::create_directory(destinationFolder);\r\n\r\n        AICLI_LOG(CLI, Info, << \"Extracting archive to: \" << destinationFolder);\n        context.Reporter.Info() << Resource::String::ExtractingArchive << std::endl;\r\n\r\n        if (Settings::User().Get<Settings::Setting::ArchiveExtractionMethod>() == Archive::ExtractionMethod::Tar)\r\n        {\r\n            context << ShellExecuteExtractArchive(installerPath, destinationFolder);\r\n        }\r\n        else\r\n        {\r\n            HRESULT result = AppInstaller::Archive::TryExtractArchive(installerPath, destinationFolder);\r\n\r\n            if (SUCCEEDED(result))\n            {\n                AICLI_LOG(CLI, Info, << \"Successfully extracted archive\");\n                context.Reporter.Info() << Resource::String::ExtractArchiveSucceeded << std::endl;\n            }\n            else\n            {\n                AICLI_LOG(CLI, Info, << \"Failed to extract archive with code \" << result);\n                context.Reporter.Error() << Resource::String::ExtractArchiveFailed << std::endl;\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_EXTRACT_ARCHIVE_FAILED);\n            }\r\n        }\r\n    }\r\n\n    void VerifyAndSetNestedInstaller(Execution::Context& context)\n    {\n        const auto& installer = context.Get<Execution::Data::Installer>().value();\n        if (installer.NestedInstallerFiles.empty())\n        {\n            // Pre-install validation should prevent this from happening\n            AICLI_LOG(CLI, Error, << \"No entries specified for NestedInstallerFiles\");\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_INVALID_MANIFEST);\n        }\n\n        std::filesystem::path targetInstallerPath = context.Get<Execution::Data::InstallerPath>().parent_path() / s_Extracted;\n\n        for (const auto& nestedInstallerFile : installer.NestedInstallerFiles)\n        {\n            const std::filesystem::path& nestedInstallerPath = targetInstallerPath / ConvertToUTF16(nestedInstallerFile.RelativeFilePath);\n            \n            if (Filesystem::PathEscapesBaseDirectory(nestedInstallerPath, targetInstallerPath))\n            {\n                AICLI_LOG(CLI, Error, << \"Path points to a location outside of the install directory: \" << nestedInstallerPath);\n                context.Reporter.Error() << Resource::String::InvalidPathToNestedInstaller << std::endl;\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_INVALID_PATH);\n            }\n            else if (!std::filesystem::exists(nestedInstallerPath))\n            {\n                AICLI_LOG(CLI, Error, << \"Unable to locate nested installer at: \" << nestedInstallerPath);\n                context.Reporter.Error()\n                    << Resource::String::NestedInstallerNotFound(Utility::LocIndView{ nestedInstallerPath.u8string() })\n                    << std::endl;\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_NOT_FOUND);\n            }\n            else if (!DoesInstallerTypeSupportMultipleNestedInstallers(installer.NestedInstallerType))\n            {\n                // Update the installerPath to the extracted non-portable installer. \n                AICLI_LOG(CLI, Info, << \"Setting installerPath to: \" << nestedInstallerPath);\n                targetInstallerPath = nestedInstallerPath;\n            }\n        }\n\n        context.Add<Execution::Data::InstallerPath>(targetInstallerPath);\n    }\n\n    void EnsureValidNestedInstallerMetadataForArchiveInstall(Execution::Context& context)\n    {\n        auto installer = context.Get<Execution::Data::Installer>().value();\n\n        if (IsArchiveType(installer.BaseInstallerType))\n        {\n            if (!IsNestedInstallerTypeSupported(installer.NestedInstallerType))\n            {\n                AICLI_LOG(CLI, Error, << \"Nested installer type not supported: \" << installer.NestedInstallerType);\n                context.Reporter.Error() << Resource::String::NestedInstallerNotSupported << std::endl;\n                AICLI_TERMINATE_CONTEXT(ERROR_NOT_SUPPORTED);\n            }\n\n            auto const& nestedInstallerFiles = installer.NestedInstallerFiles;\n            if (nestedInstallerFiles.empty())\n            {\n                AICLI_LOG(CLI, Error, << \"No entries specified for NestedInstallerFiles\");\n                context.Reporter.Error() << Resource::String::NestedInstallerNotSpecified << std::endl;\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_INVALID_MANIFEST);\n            }\n\n            if (!DoesInstallerTypeSupportMultipleNestedInstallers(installer.NestedInstallerType) && (nestedInstallerFiles.size() != 1))\n            {\n                AICLI_LOG(CLI, Error, << \"Multiple nested installers specified for unsupported nested installerType\");\n                context.Reporter.Error() << Resource::String::MultipleUnsupportedNestedInstallersSpecified << std::endl;\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_INVALID_MANIFEST);\n            }\n        }\n    }\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/ArchiveFlow.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"ExecutionContext.h\"\n\nnamespace AppInstaller::CLI::Workflow\n{\n    // Scans the archive file if downloaded from a local manifest\n    // Required Args: None\n    // Inputs: InstallerPath\n    // Outputs: None\n    void ScanArchiveFromLocalManifest(Execution::Context& context);\n\r\n    // Extracts the files from an archive\n    // Required Args: None\n    // Inputs: InstallerPath\n    // Outputs: None\r\n    void ExtractFilesFromArchive(Execution::Context& context);\r\n\n    // Verifies that the NestedInstaller exists and sets the InstallerPath\n    // Required Args: None\n    // Inputs: Installer, InstallerPath\n    // Outputs: None\n    void VerifyAndSetNestedInstaller(Execution::Context& context);\n\n    // Verifies that the metadata related to the NestedInstaller is valid\n    // Required Args: None\n    // Inputs: Installer, InstallerPath\n    // Outputs: None\n    void EnsureValidNestedInstallerMetadataForArchiveInstall(Execution::Context& context);\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/CompletionFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"CompletionFlow.h\"\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    using namespace AppInstaller::CLI::Execution;\r\n    using namespace AppInstaller::Utility::literals;\r\n\r\n    namespace\r\n    {\r\n        // Outputs the completion string, wrapping it in quotes if needed.\r\n        void OutputCompletionString(Execution::OutputStream& stream, std::string_view value)\r\n        {\r\n            if (value.find_first_of(' ') != std::string_view::npos)\r\n            {\r\n                stream << '\"' << value << '\"' << std::endl;\r\n            }\r\n            else\r\n            {\r\n                stream << value << std::endl;\r\n            }\r\n        }\r\n    }\r\n\r\n    void CompleteSourceName(Execution::Context& context)\r\n    {\r\n        const std::string& word = context.Get<Data::CompletionData>().Word();\r\n        auto stream = context.Reporter.Completion();\r\n\r\n        for (const auto& source : Repository::Source::GetCurrentSources())\r\n        {\r\n            if (word.empty() || Utility::ICUCaseInsensitiveStartsWith(source.Name, word))\r\n            {\r\n                OutputCompletionString(stream, source.Name);\r\n            }\r\n        }\r\n    }\r\n\r\n    void RequireCompletionWordNonEmpty(Execution::Context& context)\r\n    {\r\n        if (context.Get<Data::CompletionData>().Word().empty())\r\n        {\r\n            AICLI_LOG(CLI, Verbose, << \"Completion word empty, cannot complete\");\r\n            AICLI_TERMINATE_CONTEXT(E_NOT_SET);\r\n        }\r\n    }\r\n\r\n    void CompleteWithMatchedField(Execution::Context& context)\r\n    {\r\n        auto& searchResult = context.Get<Execution::Data::SearchResult>();\r\n        auto stream = context.Reporter.Completion();\r\n\r\n        for (size_t i = 0; i < searchResult.Matches.size(); ++i)\r\n        {\r\n            if (searchResult.Matches[i].MatchCriteria.Value.empty())\r\n            {\r\n                OutputCompletionString(stream, searchResult.Matches[i].Package->GetProperty(Repository::PackageProperty::Id));\r\n            }\r\n            else\r\n            {\r\n                OutputCompletionString(stream, searchResult.Matches[i].MatchCriteria.Value);\r\n            }\r\n        }\r\n    }\r\n\r\n    void CompleteWithSearchResultVersions(Execution::Context& context)\r\n    {\r\n        const std::string& word = context.Get<Data::CompletionData>().Word();\r\n        auto stream = context.Reporter.Completion();\r\n\r\n        for (const auto& ap : context.Get<Execution::Data::Package>()->GetAvailable())\r\n        {\r\n            for (const auto& vc : ap->GetVersionKeys())\r\n            {\r\n                if (word.empty() || Utility::ICUCaseInsensitiveStartsWith(vc.Version, word))\r\n                {\r\n                    OutputCompletionString(stream, vc.Version);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    void CompleteWithSearchResultInstalledVersions(Execution::Context& context)\r\n    {\r\n        const std::string& word = context.Get<Data::CompletionData>().Word();\r\n        auto stream = context.Reporter.Completion();\r\n\r\n        auto installedPackage = context.Get<Execution::Data::Package>()->GetInstalled();\r\n\r\n        if (installedPackage)\r\n        {\r\n            for (const auto& vc : installedPackage->GetVersionKeys())\r\n            {\r\n                if (word.empty() || Utility::ICUCaseInsensitiveStartsWith(vc.Version, word))\r\n                {\r\n                    OutputCompletionString(stream, vc.Version);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    void CompleteWithSearchResultChannels(Execution::Context& context)\r\n    {\r\n        const std::string& word = context.Get<Data::CompletionData>().Word();\r\n        auto stream = context.Reporter.Completion();\r\n\r\n        std::vector<std::string> channels;\r\n\r\n        for (const auto& ap : context.Get<Execution::Data::Package>()->GetAvailable())\r\n        {\r\n            for (const auto& vc : ap->GetVersionKeys())\r\n            {\r\n                if ((word.empty() || Utility::ICUCaseInsensitiveStartsWith(vc.Channel, word)) &&\r\n                    std::find(channels.begin(), channels.end(), vc.Channel) == channels.end())\r\n                {\r\n                    channels.emplace_back(vc.Channel);\r\n                }\r\n            }\r\n        }\r\n\r\n        for (const auto& c : channels)\r\n        {\r\n            OutputCompletionString(stream, c);\r\n        }\r\n    }\r\n\r\n    void CompleteWithSingleSemanticsForValue::operator()(Execution::Context& context) const\r\n    {\r\n        switch (m_type)\r\n        {\r\n        case Execution::Args::Type::Query:\r\n        case Execution::Args::Type::MultiQuery:\r\n        case Execution::Args::Type::Id:\r\n        case Execution::Args::Type::Name:\r\n        case Execution::Args::Type::Moniker:\r\n        case Execution::Args::Type::Tag:\r\n        case Execution::Args::Type::Command:\r\n        case Execution::Args::Type::Version:\r\n        case Execution::Args::Type::Channel:\r\n            context <<\r\n                Workflow::OpenSource();\r\n            break;\r\n        }\r\n\r\n        context << CompleteWithSingleSemanticsForValueUsingExistingSource(m_type);\r\n    }\r\n\r\n    void CompleteWithSingleSemanticsForValueUsingExistingSource::operator()(Execution::Context& context) const\r\n    {\r\n        switch (m_type)\r\n        {\r\n        case Execution::Args::Type::Query:\r\n        case Execution::Args::Type::MultiQuery:\r\n            context <<\r\n                Workflow::RequireCompletionWordNonEmpty <<\r\n                Workflow::SearchSourceForSingleCompletion <<\r\n                Workflow::CompleteWithMatchedField;\r\n            break;\r\n        case Execution::Args::Type::Manifest:\r\n            // Intentionally output none to enable pass through to filesystem.\r\n            break;\r\n        case Execution::Args::Type::Id:\r\n            context <<\r\n                Workflow::SearchSourceForCompletionField(Repository::PackageMatchField::Id) <<\r\n                Workflow::CompleteWithMatchedField;\r\n            break;\r\n        case Execution::Args::Type::Name:\r\n            context <<\r\n                Workflow::SearchSourceForCompletionField(Repository::PackageMatchField::Name) <<\r\n                Workflow::CompleteWithMatchedField;\r\n            break;\r\n        case Execution::Args::Type::Moniker:\r\n            context <<\r\n                Workflow::SearchSourceForCompletionField(Repository::PackageMatchField::Moniker) <<\r\n                Workflow::CompleteWithMatchedField;\r\n            break;\r\n        case Execution::Args::Type::Tag:\r\n            context <<\r\n                Workflow::SearchSourceForCompletionField(Repository::PackageMatchField::Tag) <<\r\n                Workflow::CompleteWithMatchedField;\r\n            break;\r\n        case Execution::Args::Type::Command:\r\n            context <<\r\n                Workflow::SearchSourceForCompletionField(Repository::PackageMatchField::Command) <<\r\n                Workflow::CompleteWithMatchedField;\r\n            break;\r\n        case Execution::Args::Type::Version:\r\n            // Here we require that the standard search finds a single entry, and we list those versions.\r\n            context <<\r\n                Workflow::SearchSourceForSingle <<\r\n                Workflow::EnsureOneMatchFromSearchResult(OperationType::Completion) <<\r\n                Workflow::CompleteWithSearchResultVersions;\r\n            break;\r\n        case Execution::Args::Type::TargetVersion:\r\n            // Here we require that the standard search finds a single entry, and we list the installed versions.\r\n            context <<\r\n                Workflow::SearchSourceForSingle <<\r\n                Workflow::EnsureOneMatchFromSearchResult(OperationType::Completion) <<\r\n                Workflow::CompleteWithSearchResultInstalledVersions;\r\n            break;\r\n        case Execution::Args::Type::Channel:\r\n            // Here we require that the standard search finds a single entry, and we list those channels.\r\n            context <<\r\n                Workflow::SearchSourceForSingle <<\r\n                Workflow::EnsureOneMatchFromSearchResult(OperationType::Completion) <<\r\n                Workflow::CompleteWithSearchResultChannels;\r\n            break;\r\n        case Execution::Args::Type::Source:\r\n            context <<\r\n                Workflow::CompleteSourceName;\r\n            break;\r\n        }\r\n    }\r\n\r\n    void CompleteWithEmptySet(Execution::Context& context)\r\n    {\r\n        context.Reporter.Completion() << std::endl;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/CompletionFlow.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ExecutionContext.h\"\r\n#include \"WorkflowBase.h\"\r\n#include <winget/RepositorySearch.h>\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    // Outputs completion possibilities for the source name argument.\r\n    // Required Args: None\r\n    // Inputs: CompletionData\r\n    // Outputs: None\r\n    void CompleteSourceName(Execution::Context& context);\r\n\r\n    // Terminates the context if the completion word is empty.\r\n    // Required Args: None\r\n    // Inputs: CompletionData\r\n    // Outputs: None\r\n    void RequireCompletionWordNonEmpty(Execution::Context& context);\r\n\r\n    // Outputs the matched field for the results.\r\n    // Required Args: None\r\n    // Inputs: SearchResult\r\n    // Outputs: None\r\n    void CompleteWithMatchedField(Execution::Context& context);\r\n\r\n    // Outputs the versions available for the single search result.\r\n    // Required Args: None\r\n    // Inputs: CompletionData, SearchResult\r\n    // Outputs: None\r\n    void CompleteWithSearchResultVersions(Execution::Context& context);\r\n\r\n    // Outputs the channels available for the single search result.\r\n    // Required Args: None\r\n    // Inputs: CompletionData, SearchResult\r\n    // Outputs: None\r\n    void CompleteWithSearchResultChannels(Execution::Context& context);\r\n\r\n    // Executes the appropriate completion flow for the given argument in the context of a command\r\n    // that targets a single manifest (ex. show or install).\r\n    // Required Args: None\r\n    // Inputs: CompletionData\r\n    // Outputs: None\r\n    struct CompleteWithSingleSemanticsForValue : public WorkflowTask\r\n    {\r\n        CompleteWithSingleSemanticsForValue(Execution::Args::Type type) : WorkflowTask(\"CompleteWithSingleSemanticsForValue\"), m_type(type) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        Execution::Args::Type m_type;\r\n    };\r\n\r\n    // Executes the appropriate completion flow for the given argument in the context of a command\r\n    // that targets a single manifest (ex. show or install), using the already open source.\r\n    // Required Args: None\r\n    // Inputs: CompletionData, Source\r\n    // Outputs: None\r\n    struct CompleteWithSingleSemanticsForValueUsingExistingSource : public WorkflowTask\r\n    {\r\n        CompleteWithSingleSemanticsForValueUsingExistingSource(Execution::Args::Type type) : WorkflowTask(\"CompleteWithSingleSemanticsForValueUsingExistingSource\"), m_type(type) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        Execution::Args::Type m_type;\r\n    };\r\n\r\n    // Outputs an empty line to indicate that there are no completions.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: None\r\n    void CompleteWithEmptySet(Execution::Context& context);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/ConfigurationFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigurationFlow.h\"\r\n#include \"ImportExportFlow.h\"\r\n#include \"PromptFlow.h\"\r\n#include \"TableOutput.h\"\r\n#include \"MSStoreInstallerHandler.h\"\r\n#include \"Public/ConfigurationSetProcessorFactoryRemoting.h\"\r\n#include \"ConfigurationCommon.h\"\r\n#include \"ConfigurationWingetDscModuleUnitValidation.h\"\r\n#include \"Commands/DscCommandBase.h\"\r\n#include <AppInstallerDateTime.h>\r\n#include <AppInstallerDownloader.h>\r\n#include <AppInstallerErrors.h>\r\n#include <AppInstallerRuntime.h>\r\n#include <AppInstallerStrings.h>\r\n#include <winget/ExperimentalFeature.h>\r\n#include <winget/SelfManagement.h>\r\n#include <winget/PathTree.h>\r\n#include <winrt/Microsoft.Management.Configuration.h>\r\n\r\nusing namespace AppInstaller::CLI::Execution;\r\nusing namespace winrt::Microsoft::Management::Configuration;\r\nusing namespace winrt::Windows::Foundation;\r\nusing namespace winrt::Windows::Foundation::Collections;\r\nusing namespace winrt::Windows::Storage;\r\nusing namespace AppInstaller::Utility::literals;\r\nusing namespace AppInstaller::SelfManagement;\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n    IConfigurationSetProcessorFactory s_override_IConfigurationSetProcessorFactory;\r\n\r\n    void SetTestConfigurationSetProcessorFactory(IConfigurationSetProcessorFactory factory)\r\n    {\r\n        s_override_IConfigurationSetProcessorFactory = std::move(factory);\r\n    }\r\n#endif\r\n\r\n    namespace anon\r\n    {\r\n        static const AppInstaller::Utility::Version s_MinimumSchemaVersionModuleNameRequiredInType = { \"0.3\" };\r\n\r\n        constexpr std::wstring_view s_Directive_Description = L\"description\";\r\n        constexpr std::wstring_view s_Directive_Module = L\"module\";\r\n        constexpr std::wstring_view s_Directive_AllowPrerelease = L\"allowPrerelease\";\r\n\r\n        constexpr std::wstring_view s_Unit_WinGetPackage = L\"WinGetPackage\";\r\n        constexpr std::wstring_view s_Unit_WinGetSource = L\"WinGetSource\";\r\n\r\n        constexpr std::wstring_view s_UnitType_WinGetPackage_DSCv3 = WINGET_DSCV3_MODULE_NAME_WIDE L\"/Package\";\r\n        constexpr std::wstring_view s_UnitType_WinGetSource_DSCv3 = WINGET_DSCV3_MODULE_NAME_WIDE L\"/Source\";\r\n        constexpr std::wstring_view s_UnitType_WinGetUserSettingsFile_DSCv3 = WINGET_DSCV3_MODULE_NAME_WIDE L\"/UserSettingsFile\";\r\n        constexpr std::wstring_view s_UnitType_WinGetAdminSettings_DSCv3 = WINGET_DSCV3_MODULE_NAME_WIDE L\"/AdminSettings\";\r\n\r\n        constexpr std::wstring_view s_Module_WinGetClient = L\"Microsoft.WinGet.DSC\";\r\n\r\n        constexpr std::wstring_view s_Setting_WinGetPackage_Id = L\"id\";\r\n        constexpr std::wstring_view s_Setting_WinGetPackage_Source = L\"source\";\r\n        constexpr std::wstring_view s_Setting_WinGetPackage_Version = L\"version\";\r\n\r\n        constexpr std::wstring_view s_Setting_WinGetSource_Name = L\"name\";\r\n        constexpr std::wstring_view s_Setting_WinGetSource_Arg = L\"argument\";\r\n        constexpr std::wstring_view s_Setting_WinGetSource_Type = L\"type\";\r\n        constexpr std::wstring_view s_Setting_WinGetSource_TrustLevel = L\"trustLevel\";\r\n        constexpr std::wstring_view s_Setting_WinGetSource_Explicit = L\"explicit\";\r\n        constexpr std::wstring_view s_Setting_WinGetSource_Priority = L\"priority\";\r\n\r\n        constexpr std::wstring_view s_Predefined_PowerShell_PackageId = L\"Microsoft.PowerShell\";\r\n        constexpr std::wstring_view s_Predefined_PowerShell_PackageSource = L\"winget\";\r\n\r\n        constexpr std::string_view s_DscPackage_StoreId_Stable = \"9NVTPZWRC6KQ\";\r\n        constexpr std::string_view s_DscPackage_StoreId_Preview = \"9PCX3HX4HZ0Z\";\r\n\r\n        struct PredefinedResourceInfo\r\n        {\r\n            std::wstring_view UnitType;\r\n            bool ElevationRequired = false;\r\n\r\n            PredefinedResourceInfo(std::wstring_view unitType) : UnitType(unitType) {}\r\n            PredefinedResourceInfo(std::wstring_view unitType, bool elevationRequired) : UnitType(unitType), ElevationRequired(elevationRequired) {}\r\n        };\r\n\r\n        struct PredefinedResource\r\n        {\r\n            // RequiredModule could be empty, meaning no required modules needed.\r\n            std::wstring_view RequiredModule;\r\n\r\n            std::vector<PredefinedResourceInfo> ResourceInfos;\r\n        };\r\n\r\n        std::vector<PredefinedResource> PredefinedResourcesForExport()\r\n        {\r\n            return {\r\n                { {}, { { s_UnitType_WinGetUserSettingsFile_DSCv3 }, { s_UnitType_WinGetAdminSettings_DSCv3, true } } },\r\n                { L\"Microsoft.Windows.Settings\", { { L\"Microsoft.Windows.Settings/WindowsSettings\", true } } },\r\n            };\r\n        }\r\n\r\n        std::vector<std::wstring_view> PackageSettingsExclusionList()\r\n        {\r\n            return {\r\n                L\"Microsoft.WinGet/\",\r\n                L\"Microsoft.WinGet.Dev/\",\r\n                L\"Microsoft.DSC.Debug/\",\r\n                L\"Microsoft.DSC/\",\r\n                L\"Microsoft.DSC.Transitional/\",\r\n                L\"Microsoft.Windows/RebootPending\",\r\n                L\"Microsoft.Windows/Registry\",\r\n                L\"Microsoft.Windows/WMI\",\r\n                L\"Microsoft.Windows/WindowsPowerShell\",\r\n                L\"Microsoft/OSInfo\"\r\n            };\r\n        };\r\n\r\n        Logging::Level ConvertLevel(DiagnosticLevel level)\r\n        {\r\n            switch (level)\r\n            {\r\n            case DiagnosticLevel::Verbose: return Logging::Level::Verbose;\r\n            case DiagnosticLevel::Informational: return Logging::Level::Info;\r\n            case DiagnosticLevel::Warning: return Logging::Level::Warning;\r\n            case DiagnosticLevel::Error: return Logging::Level::Error;\r\n            case DiagnosticLevel::Critical: return Logging::Level::Crit;\r\n            }\r\n\r\n            return Logging::Level::Info;\r\n        }\r\n\r\n        DiagnosticLevel ConvertLevel(Logging::Level level)\r\n        {\r\n            switch (level)\r\n            {\r\n            case Logging::Level::Verbose: return DiagnosticLevel::Verbose;\r\n            case Logging::Level::Info: return DiagnosticLevel::Informational;\r\n            case Logging::Level::Warning: return DiagnosticLevel::Warning;\r\n            case Logging::Level::Error: return DiagnosticLevel::Error;\r\n            case Logging::Level::Crit: return DiagnosticLevel::Critical;\r\n            }\r\n\r\n            return DiagnosticLevel::Informational;\r\n        }\r\n\r\n        Resource::StringId ToResource(ConfigurationUnitIntent intent)\r\n        {\r\n            switch (intent)\r\n            {\r\n            case ConfigurationUnitIntent::Assert: return Resource::String::ConfigurationAssert;\r\n            case ConfigurationUnitIntent::Inform: return Resource::String::ConfigurationInform;\r\n            case ConfigurationUnitIntent::Apply: return Resource::String::ConfigurationApply;\r\n            default: return Resource::StringId::Empty();\r\n            }\r\n        }\r\n\r\n        void InstallDscPackage(Execution::Context& context, std::string_view productId, std::unique_ptr<Reporter::AsyncProgressScope>& progressScope)\r\n        {\r\n            progressScope.reset();\r\n\r\n            context.Reporter.Info() << Resource::String::ConfigurationInstallDscPackage << std::endl;\r\n\r\n            auto installDscContextPtr = context.CreateSubContext();\r\n            Execution::Context& installDscContext = *installDscContextPtr;\r\n            auto previousThreadGlobals = installDscContext.SetForCurrentThread();\r\n\r\n            Manifest::ManifestInstaller dscInstaller;\r\n            dscInstaller.ProductId = productId;\r\n\r\n            installDscContext.Add<Execution::Data::Installer>(std::move(dscInstaller));\r\n            installDscContext.Args.AddArg(Execution::Args::Type::InstallScope, Manifest::ScopeToString(Manifest::ScopeEnum::User));\r\n            installDscContext.Args.AddArg(Execution::Args::Type::Silent);\r\n            installDscContext.Args.AddArg(Execution::Args::Type::Force);\r\n\r\n            installDscContext << MSStoreInstall;\r\n\r\n            if (installDscContext.IsTerminated())\r\n            {\r\n                AICLI_LOG(Config, Error, << \"Failed to install dsc v3 package: \" << productId);\r\n                context.Reporter.Error() << Resource::String::ConfigurationInstallDscPackageFailed << std::endl;\r\n                THROW_WIN32(ERROR_FILE_NOT_FOUND);\r\n            }\r\n\r\n            progressScope = context.Reporter.BeginAsyncProgress(true);\r\n            progressScope->Callback().SetProgressMessage(Resource::String::ConfigurationInitializing());\r\n        }\r\n\r\n        IConfigurationSetProcessorFactory CreateConfigurationSetProcessorFactory(Execution::Context& context)\r\n        {\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n            // Test could override the entire workflow task, but that may require keeping more in sync than simply setting the factory.\r\n            if (s_override_IConfigurationSetProcessorFactory)\r\n            {\r\n                return s_override_IConfigurationSetProcessorFactory;\r\n            }\r\n#endif\r\n\r\n            auto progressScope = context.Reporter.BeginAsyncProgress(true);\r\n            progressScope->Callback().SetProgressMessage(Resource::String::ConfigurationInitializing());\r\n\r\n            // The configuration set must have already been opened to create the proper factory.\r\n            THROW_WIN32_IF(ERROR_INVALID_STATE, !context.Contains(Data::ConfigurationContext));\r\n            const auto& configurationContext = context.Get<Data::ConfigurationContext>();\r\n            THROW_WIN32_IF(ERROR_INVALID_STATE, !configurationContext.Set());\r\n\r\n            IConfigurationSetProcessorFactory factory;\r\n            ConfigurationRemoting::ProcessorEngine processorEngine = ConfigurationRemoting::DetermineProcessorEngine(configurationContext.Set());\r\n\r\n            THROW_HR_IF(WINGET_CONFIG_ERROR_INVALID_FIELD_VALUE, processorEngine == ConfigurationRemoting::ProcessorEngine::Unknown);\r\n\r\n            // Since downgrading is not currently supported, only use dynamic if running limited.\r\n            if (Runtime::IsRunningWithLimitedToken())\r\n            {\r\n                factory = ConfigurationRemoting::CreateDynamicRuntimeFactory(processorEngine);\r\n            }\r\n            else\r\n            {\r\n                factory = ConfigurationRemoting::CreateOutOfProcessFactory(processorEngine);\r\n            }\r\n\r\n            if (processorEngine == ConfigurationRemoting::ProcessorEngine::PowerShell)\r\n            {\r\n                Configuration::SetModulePath(context, factory);\r\n            }\r\n            else if (processorEngine == ConfigurationRemoting::ProcessorEngine::DSCv3)\r\n            {\r\n                auto factoryMap = factory.as<IMap<winrt::hstring, winrt::hstring>>();\r\n\r\n                if (context.Args.Contains(Args::Type::ConfigurationProcessorPath))\r\n                {\r\n                    factoryMap.Insert(ConfigurationRemoting::ToHString(ConfigurationRemoting::PropertyName::DscExecutablePath), Utility::ConvertToUTF16(context.Args.GetArg(Args::Type::ConfigurationProcessorPath)));\r\n                }\r\n                else\r\n                {\r\n                    for (;;)\r\n                    {\r\n                        // Get the next transition for the state machine\r\n                        winrt::hstring nextTransition = factoryMap.Lookup(ConfigurationRemoting::ToHString(ConfigurationRemoting::PropertyName::FindDscStateMachine));\r\n                        AICLI_LOG(Config, Verbose, << \"FindDscStateMachine returned \" << Utility::ConvertToUTF8(nextTransition));\r\n\r\n                        if (nextTransition == L\"Found\")\r\n                        {\r\n                            break;\r\n                        }\r\n                        else if (nextTransition == L\"InstallStable\")\r\n                        {\r\n                            AICLI_LOG(Config, Info, << \"Installing stable DSC package from store...\");\r\n                            InstallDscPackage(context, s_DscPackage_StoreId_Stable, progressScope);\r\n                        }\r\n                        else if (nextTransition == L\"InstallPreview\")\r\n                        {\r\n                            AICLI_LOG(Config, Info, << \"Installing preview DSC package from store...\");\r\n                            InstallDscPackage(context, s_DscPackage_StoreId_Preview, progressScope);\r\n                        }\r\n                        else if (nextTransition == L\"NotFound\")\r\n                        {\r\n                            AICLI_LOG(Config, Error, << \"Failed to find appropriate dsc v3 package, it must be provided by the user.\");\r\n                            context.Reporter.Error() << Resource::String::ConfigurationInstallDscPackageFailed << std::endl;\r\n                            THROW_WIN32(ERROR_FILE_NOT_FOUND);\r\n                        }\r\n                        else\r\n                        {\r\n                            AICLI_LOG(Config, Error, << \"FindDscStateMachine returned unknown value `\" << Utility::ConvertToUTF8(nextTransition) << \"`\");\r\n                            THROW_HR(E_UNEXPECTED);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if (Logging::Log().IsEnabled(Logging::Channel::Config, Logging::Level::Verbose))\r\n                {\r\n                    factoryMap.Insert(ConfigurationRemoting::ToHString(ConfigurationRemoting::PropertyName::DiagnosticTraceEnabled), L\"True\");\r\n                }\r\n            }\r\n\r\n            return factory;\r\n        }\r\n\r\n        void ConfigureProcessorForUse(Execution::Context& context, ConfigurationProcessor&& processor)\r\n        {\r\n            // Set the processor to the current level of the logging.\r\n            processor.MinimumLevel(anon::ConvertLevel(Logging::Log().GetLevel()));\r\n            processor.Caller(L\"winget\");\r\n            // Use same activity as the overall winget command\r\n            processor.ActivityIdentifier(*Logging::Telemetry().GetActivityId());\r\n            // Apply winget telemetry setting to configuration\r\n            processor.GenerateTelemetryEvents(!Settings::User().Get<Settings::Setting::TelemetryDisable>());\r\n\r\n            // Route the configuration diagnostics into the context's diagnostics logging\r\n            processor.Diagnostics([&context](const winrt::Windows::Foundation::IInspectable&, const IDiagnosticInformation& diagnostics)\r\n                {\r\n                    context.GetThreadGlobals().GetDiagnosticLogger().Write(Logging::Channel::Config, anon::ConvertLevel(diagnostics.Level()), Utility::ConvertToUTF8(diagnostics.Message()));\r\n                });\r\n\r\n            if (context.Contains(Data::ConfigurationContext))\r\n            {\r\n                context.Get<Data::ConfigurationContext>().Processor(std::move(processor));\r\n            }\r\n            else\r\n            {\r\n                ConfigurationContext configurationContext;\r\n                configurationContext.Processor(std::move(processor));\r\n\r\n                context.Add<Data::ConfigurationContext>(std::move(configurationContext));\r\n            }\r\n        }\r\n\r\n        winrt::hstring GetValueSetString(const ValueSet& valueSet, std::wstring_view value)\r\n        {\r\n            if (valueSet.HasKey(value))\r\n            {\r\n                auto object = valueSet.Lookup(value);\r\n                IPropertyValue property = object.try_as<IPropertyValue>();\r\n                if (property && property.Type() == PropertyType::String)\r\n                {\r\n                    return property.GetString();\r\n                }\r\n            }\r\n\r\n            return {};\r\n        }\r\n\r\n        std::optional<bool> GetValueSetBool(const ValueSet& valueSet, std::wstring_view value)\r\n        {\r\n            if (valueSet.HasKey(value))\r\n            {\r\n                auto object = valueSet.Lookup(value);\r\n                IPropertyValue property = object.try_as<IPropertyValue>();\r\n                if (property && property.Type() == PropertyType::Boolean)\r\n                {\r\n                    return property.GetBoolean();\r\n                }\r\n            }\r\n\r\n            return {};\r\n        }\r\n\r\n        // Contains the output functions and tracks whether any fields needed to be truncated.\r\n        struct OutputHelper\r\n        {\r\n            OutputHelper(Execution::Context& context) : m_context(context) {}\r\n\r\n            size_t ValuesTruncated = 0;\r\n\r\n            // Converts a string from the configuration API surface for output.\r\n            // All strings coming from the API are external data and not localizable by us.\r\n            Utility::LocIndString ConvertForOutput(const std::string& input, size_t maxLines)\r\n            {\r\n                bool truncated = false;\r\n                auto lines = Utility::SplitIntoLines(input);\r\n\r\n                if (maxLines == 1 && lines.size() > 1)\r\n                {\r\n                    // If the limit was one line, don't allow line breaks but do allow a second line of overflow\r\n                    lines.resize(1);\r\n                    maxLines = 2;\r\n                    truncated = true;\r\n                }\r\n\r\n                if (Utility::LimitOutputLines(lines, GetConsoleWidth(), maxLines))\r\n                {\r\n                    truncated = true;\r\n                }\r\n\r\n                if (truncated)\r\n                {\r\n                    ++ValuesTruncated;\r\n                }\r\n\r\n                return Utility::LocIndString{ Utility::Join(\"\\n\", lines) };\r\n            }\r\n\r\n            Utility::LocIndString ConvertForOutput(const winrt::hstring& input, size_t maxLines)\r\n            {\r\n                return ConvertForOutput(Utility::ConvertToUTF8(input), maxLines);\r\n            }\r\n\r\n            Utility::LocIndString ConvertIdentifier(const winrt::hstring& input)\r\n            {\r\n                return ConvertForOutput(input, 1);\r\n            }\r\n\r\n            Utility::LocIndString ConvertURI(const winrt::hstring& input)\r\n            {\r\n                return ConvertForOutput(input, 1);\r\n            }\r\n\r\n            Utility::LocIndString ConvertValue(const winrt::hstring& input)\r\n            {\r\n                return ConvertForOutput(input, 5);\r\n            }\r\n\r\n            Utility::LocIndString ConvertDetailsIdentifier(const winrt::hstring& input)\r\n            {\r\n                return ConvertForOutput(Utility::ConvertControlCodesToPictures(Utility::ConvertToUTF8(input)), 1);\r\n            }\r\n\r\n            Utility::LocIndString ConvertDetailsURI(const winrt::hstring& input)\r\n            {\r\n                return ConvertForOutput(Utility::ConvertControlCodesToPictures(Utility::ConvertToUTF8(input)), 1);\r\n            }\r\n\r\n            Utility::LocIndString ConvertDetailsValue(const winrt::hstring& input)\r\n            {\r\n                return ConvertForOutput(Utility::ConvertControlCodesToPictures(Utility::ConvertToUTF8(input)), 5);\r\n            }\r\n\r\n            void OutputValueWithTruncationWarningIfNeeded(const winrt::hstring& input)\r\n            {\r\n                size_t truncatedBefore = ValuesTruncated;\r\n                m_context.Reporter.Info() << ConvertValue(input) << '\\n';\r\n\r\n                if (ValuesTruncated > truncatedBefore)\r\n                {\r\n                    m_context.Reporter.Warn() << Resource::String::ConfigurationWarningValueTruncated << std::endl;\r\n                }\r\n            }\r\n\r\n            void OutputPropertyValue(const IPropertyValue property)\r\n            {\r\n                switch (property.Type())\r\n                {\r\n                case PropertyType::String:\r\n                    m_context.Reporter.Info() << ' ';\r\n                    OutputValueWithTruncationWarningIfNeeded(property.GetString());\r\n                    break;\r\n                case PropertyType::Boolean:\r\n                    m_context.Reporter.Info() << ' ' << (property.GetBoolean() ? Utility::LocIndView(\"true\") : Utility::LocIndView(\"false\")) << '\\n';\r\n                    break;\r\n                case PropertyType::Int64:\r\n                    m_context.Reporter.Info() << ' ' << property.GetInt64() << '\\n';\r\n                    break;\r\n                default:\r\n                    m_context.Reporter.Info() << \" [Debug:PropertyType=\"_liv << property.Type() << \"]\\n\"_liv;\r\n                    break;\r\n                }\r\n            }\r\n\r\n            void OutputValueSetAsArray(const ValueSet& valueSetArray, size_t indent)\r\n            {\r\n                Utility::LocIndString indentString{ std::string(indent, ' ') };\r\n\r\n                std::vector<std::pair<int, winrt::Windows::Foundation::IInspectable>> arrayValues;\r\n                for (const auto& arrayValue : valueSetArray)\r\n                {\r\n                    if (arrayValue.Key() != L\"treatAsArray\")\r\n                    {\r\n                        arrayValues.emplace_back(std::make_pair(std::stoi(arrayValue.Key().c_str()), arrayValue.Value()));\r\n                    }\r\n                }\r\n\r\n                std::sort(\r\n                    arrayValues.begin(),\r\n                    arrayValues.end(),\r\n                    [](const std::pair<int, winrt::Windows::Foundation::IInspectable>& a, const std::pair<int, winrt::Windows::Foundation::IInspectable>& b)\r\n                    {\r\n                        return a.first < b.first;\r\n                    });\r\n\r\n                for (const auto& arrayValue : arrayValues)\r\n                {\r\n                    auto arrayObject = arrayValue.second;\r\n                    IPropertyValue arrayProperty = arrayObject.try_as<IPropertyValue>();\r\n\r\n                    m_context.Reporter.Info() << indentString << \"-\";\r\n                    if (arrayProperty)\r\n                    {\r\n                        OutputPropertyValue(arrayProperty);\r\n                    }\r\n                    else\r\n                    {\r\n                        ValueSet arraySubset = arrayObject.as<ValueSet>();\r\n                        auto size = arraySubset.Size();\r\n                        if (size > 0)\r\n                        {\r\n                            // First one is special.\r\n                            auto first = arraySubset.First().Current();\r\n                            m_context.Reporter.Info() << ' ' << ConvertIdentifier(first.Key()) << ':';\r\n\r\n                            auto object = first.Value();\r\n                            IPropertyValue property = object.try_as<IPropertyValue>();\r\n                            if (property)\r\n                            {\r\n                                OutputPropertyValue(property);\r\n                            }\r\n                            else\r\n                            {\r\n                                // If not an IPropertyValue, it must be a ValueSet\r\n                                ValueSet subset = object.as<ValueSet>();\r\n                                m_context.Reporter.Info() << '\\n';\r\n                                OutputValueSet(subset, indent + 4);\r\n                            }\r\n\r\n                            if (size > 1)\r\n                            {\r\n                                arraySubset.Remove(first.Key());\r\n                                OutputValueSet(arraySubset, indent + 2);\r\n                                arraySubset.Insert(first.Key(), first.Value());\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            void OutputValueSet(const ValueSet& valueSet, size_t indent)\r\n            {\r\n                Utility::LocIndString indentString{ std::string(indent, ' ') };\r\n\r\n                for (const auto& value : valueSet)\r\n                {\r\n                    m_context.Reporter.Info() << indentString << ConvertIdentifier(value.Key()) << ':';\r\n\r\n                    auto object = value.Value();\r\n\r\n                    IPropertyValue property = object.try_as<IPropertyValue>();\r\n                    if (property)\r\n                    {\r\n                        OutputPropertyValue(property);\r\n                    }\r\n                    else\r\n                    {\r\n                        // If not an IPropertyValue, it must be a ValueSet\r\n                        ValueSet subset = object.as<ValueSet>();\r\n                        m_context.Reporter.Info() << '\\n';\r\n                        if (subset.HasKey(L\"treatAsArray\"))\r\n                        {\r\n                            OutputValueSetAsArray(subset, indent + 2);\r\n                        }\r\n                        else\r\n                        {\r\n                            OutputValueSet(subset, indent + 2);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            void OutputConfigurationUnitHeader(const ConfigurationUnit& unit, const winrt::hstring& name)\r\n            {\r\n                m_context.Reporter.Info() << ConfigurationUnitEmphasis << ConvertIdentifier(name);\r\n\r\n                if (unit.Environment().Context() == SecurityContext::Elevated)\r\n                {\r\n                    // Shield\r\n                    m_context.Reporter.Info() << \"\\xF0\\x9F\\x9B\\xA1 \"_liv;\r\n                }\r\n\r\n                winrt::hstring identifier = unit.Identifier();\r\n                if (!identifier.empty())\r\n                {\r\n                    m_context.Reporter.Info() << \" [\"_liv << ConvertIdentifier(identifier) << ']';\r\n                }\r\n\r\n                m_context.Reporter.Info() << '\\n';\r\n            }\r\n\r\n            void OutputConfigurationUnitInformation(const ConfigurationUnit& unit)\r\n            {\r\n                IConfigurationUnitProcessorDetails details = unit.Details();\r\n                ValueSet metadata = unit.Metadata();\r\n\r\n                if (details)\r\n                {\r\n                    // -- Sample output when IConfigurationUnitProcessorDetails present --\r\n                    // UnitType <from details> [Identifier]\r\n                    //   UnitDocumentationUri <if present>\r\n                    //   Description <from details first, directives second>\r\n                    //   \"Module\": ModuleName \"by\" Author / Publisher (IsLocal / ModuleSource)\r\n                    //     \"Signed by\": SigningCertificateChain (leaf subject CN)\r\n                    //     PublishedModuleUri / ModuleDocumentationUri <if present>\r\n                    //     ModuleDescription\r\n                    OutputConfigurationUnitHeader(unit, details.UnitType());\r\n\r\n                    auto unitDocumentationUri = details.UnitDocumentationUri();\r\n                    if (unitDocumentationUri)\r\n                    {\r\n                        m_context.Reporter.Info() << \"  \"_liv << ConvertDetailsURI(unitDocumentationUri.DisplayUri()) << '\\n';\r\n                    }\r\n\r\n                    winrt::hstring unitDescriptionFromDetails = details.UnitDescription();\r\n                    if (!unitDescriptionFromDetails.empty())\r\n                    {\r\n                        m_context.Reporter.Info() << \"  \"_liv << ConvertDetailsValue(unitDescriptionFromDetails) << '\\n';\r\n                    }\r\n\r\n                    auto unitDescriptionFromDirectives = GetValueSetString(metadata, s_Directive_Description);\r\n                    if (!unitDescriptionFromDirectives.empty())\r\n                    {\r\n                        m_context.Reporter.Info() << \"  \"_liv;\r\n                        OutputValueWithTruncationWarningIfNeeded(unitDescriptionFromDirectives);\r\n                    }\r\n\r\n                    auto author = ConvertDetailsIdentifier(details.Author());\r\n                    if (author.empty())\r\n                    {\r\n                        author = ConvertDetailsIdentifier(details.Publisher());\r\n                    }\r\n\r\n                    auto moduleName = ConvertDetailsIdentifier(details.ModuleName());\r\n                    if (!moduleName.empty())\r\n                    {\r\n                        if (details.IsLocal())\r\n                        {\r\n                            m_context.Reporter.Info() << \"  \"_liv << Resource::String::ConfigurationModuleWithDetails(moduleName, author, Resource::String::ConfigurationLocal) << '\\n';\r\n                        }\r\n                        else\r\n                        {\r\n                            m_context.Reporter.Info() << \"  \"_liv << Resource::String::ConfigurationModuleWithDetails(moduleName, author, ConvertDetailsIdentifier(details.ModuleSource())) << '\\n';\r\n                        }\r\n                    }\r\n\r\n                    // TODO: Currently the signature information is only for the top files. Maybe each item should be tagged?\r\n                    // TODO: Output signing information with additional details (like whether the certificate is trusted). Doing this with the validate command\r\n                    //       seems like a good time, as that will also need to do the check in order to inform the user on the validation.\r\n                    //       Just saying \"Signed By: Foo\" is going to lead to a false sense of trust if the signature is valid but not actually trusted.\r\n\r\n                    auto moduleUri = details.PublishedModuleUri();\r\n                    if (!moduleUri)\r\n                    {\r\n                        moduleUri = details.ModuleDocumentationUri();\r\n                    }\r\n                    if (moduleUri)\r\n                    {\r\n                        m_context.Reporter.Info() << \"    \"_liv << ConvertDetailsURI(moduleUri.DisplayUri()) << '\\n';\r\n                    }\r\n\r\n                    winrt::hstring moduleDescription = details.ModuleDescription();\r\n                    if (!moduleDescription.empty())\r\n                    {\r\n                        m_context.Reporter.Info() << \"    \"_liv << ConvertDetailsValue(moduleDescription) << '\\n';\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    // -- Sample output when no IConfigurationUnitProcessorDetails present --\r\n                    // Type <from unit> [identifier]\r\n                    //   Description (from directives)\r\n                    //   \"Module\": module <directive>\r\n                    OutputConfigurationUnitHeader(unit, unit.Type());\r\n\r\n                    auto description = GetValueSetString(metadata, s_Directive_Description);\r\n                    if (!description.empty())\r\n                    {\r\n                        m_context.Reporter.Info() << \"  \"_liv;\r\n                        OutputValueWithTruncationWarningIfNeeded(description);\r\n                    }\r\n\r\n                    auto module = GetValueSetString(metadata, s_Directive_Module);\r\n                    if (!module.empty())\r\n                    {\r\n                        m_context.Reporter.Info() << \"  \"_liv << Resource::String::ConfigurationModuleNameOnly(ConvertIdentifier(module)) << '\\n';\r\n                    }\r\n                }\r\n\r\n                // -- Sample output footer --\r\n                //   Dependencies: dep1, dep2, ...\r\n                //   Settings:\r\n                //     <... settings splat>\r\n                auto dependencies = unit.Dependencies();\r\n                if (dependencies.Size() > 0)\r\n                {\r\n                    std::ostringstream allDependencies;\r\n                    for (const winrt::hstring& dependency : dependencies)\r\n                    {\r\n                        allDependencies << ' ' << ConvertIdentifier(dependency);\r\n                    }\r\n                    m_context.Reporter.Info() << \"  \"_liv << Resource::String::ConfigurationDependencies(Utility::LocIndString{ std::move(allDependencies).str() }) << '\\n';\r\n                }\r\n\r\n                ValueSet settings = unit.Settings();\r\n                if (settings.Size() > 0)\r\n                {\r\n                    m_context.Reporter.Info() << \"  \"_liv << Resource::String::ConfigurationSettings << '\\n';\r\n                    OutputValueSet(settings, 4);\r\n                }\r\n\r\n                m_context.Reporter.Info() << std::flush;\r\n            }\r\n\r\n        private:\r\n            Execution::Context& m_context;\r\n        };\r\n\r\n        void OutputConfigurationUnitHeader(Execution::Context& context, const ConfigurationUnit& unit, const winrt::hstring& name)\r\n        {\r\n            OutputHelper helper{ context };\r\n            helper.OutputConfigurationUnitHeader(unit, name);\r\n        }\r\n\r\n        void LogFailedGetConfigurationUnitDetails(const ConfigurationUnit& unit, const IConfigurationUnitResultInformation& resultInformation)\r\n        {\r\n            if (FAILED(resultInformation.ResultCode()))\r\n            {\r\n                AICLI_LOG(Config, Error, << \"Failed to get unit details for \" << Utility::ConvertToUTF8(unit.Type()) << \" : 0x\" <<\r\n                    Logging::SetHRFormat << resultInformation.ResultCode() << '\\n' << Utility::ConvertToUTF8(resultInformation.Description()) << '\\n' <<\r\n                    Utility::ConvertToUTF8(resultInformation.Details()));\r\n            }\r\n        }\r\n\r\n        struct UnitFailedMessageData\r\n        {\r\n            Utility::LocIndString Message;\r\n            bool ShowDescription = true;\r\n        };\r\n\r\n        // TODO: We may need a detailed result code to enable the internal error to be exposed.\r\n        //       Additionally, some of the processor exceptions that generate these errors should be enlightened to produce better, localized descriptions.\r\n        UnitFailedMessageData GetUnitFailedData(const ConfigurationUnit& unit, const IConfigurationUnitResultInformation& resultInformation)\r\n        {\r\n            int32_t resultCode = resultInformation.ResultCode();\r\n\r\n            switch (resultCode)\r\n            {\r\n            case WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER: return { Resource::String::ConfigurationUnitHasDuplicateIdentifier(Utility::LocIndString{ Utility::ConvertToUTF8(unit.Identifier()) }), false };\r\n            case WINGET_CONFIG_ERROR_MISSING_DEPENDENCY: return { Resource::String::ConfigurationUnitHasMissingDependency(Utility::LocIndString{ Utility::ConvertToUTF8(resultInformation.Details()) }), false };\r\n            case WINGET_CONFIG_ERROR_ASSERTION_FAILED: return { Resource::String::ConfigurationUnitAssertHadNegativeResult(), false };\r\n            case WINGET_CONFIG_ERROR_UNIT_NOT_INSTALLED: return { Resource::String::ConfigurationUnitNotFoundInModule(), false };\r\n            case WINGET_CONFIG_ERROR_UNIT_NOT_FOUND_REPOSITORY: return { Resource::String::ConfigurationUnitNotFound(), false };\r\n            case WINGET_CONFIG_ERROR_UNIT_MULTIPLE_MATCHES: return { Resource::String::ConfigurationUnitMultipleMatches(), false };\r\n            case WINGET_CONFIG_ERROR_UNIT_INVOKE_GET: return { Resource::String::ConfigurationUnitFailedDuringGet(), true };\r\n            case WINGET_CONFIG_ERROR_UNIT_INVOKE_TEST: return { Resource::String::ConfigurationUnitFailedDuringTest(), true };\r\n            case WINGET_CONFIG_ERROR_UNIT_INVOKE_SET: return { Resource::String::ConfigurationUnitFailedDuringSet(), true };\r\n            case WINGET_CONFIG_ERROR_UNIT_MODULE_CONFLICT: return { Resource::String::ConfigurationUnitModuleConflict(), false };\r\n            case WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE: return { Resource::String::ConfigurationUnitModuleImportFailed(), false };\r\n            case WINGET_CONFIG_ERROR_UNIT_INVOKE_INVALID_RESULT: return { Resource::String::ConfigurationUnitReturnedInvalidResult(), false };\r\n            case WINGET_CONFIG_ERROR_UNIT_SETTING_CONFIG_ROOT: return { Resource::String::ConfigurationUnitSettingConfigRoot(), false };\r\n            case WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE_ADMIN: return { Resource::String::ConfigurationUnitImportModuleAdmin(), false };\r\n            }\r\n\r\n            switch (resultInformation.ResultSource())\r\n            {\r\n            case ConfigurationUnitResultSource::ConfigurationSet: return { Resource::String::ConfigurationUnitFailedConfigSet(resultCode), true };\r\n            case ConfigurationUnitResultSource::Internal: return { Resource::String::ConfigurationUnitFailedInternal(resultCode), true };\r\n            case ConfigurationUnitResultSource::Precondition: return { Resource::String::ConfigurationUnitFailedPrecondition(resultCode), true };\r\n            case ConfigurationUnitResultSource::SystemState: return { Resource::String::ConfigurationUnitFailedSystemState(resultCode), true };\r\n            case ConfigurationUnitResultSource::UnitProcessing: return { Resource::String::ConfigurationUnitFailedUnitProcessing(resultCode), true };\r\n            }\r\n\r\n            // All other errors use a generic message\r\n            return { Resource::String::ConfigurationUnitFailed(resultCode), true };\r\n        }\r\n\r\n        Utility::LocIndString GetUnitSkippedMessage(const IConfigurationUnitResultInformation& resultInformation)\r\n        {\r\n            int32_t resultCode = resultInformation.ResultCode();\r\n\r\n            switch (resultInformation.ResultCode())\r\n            {\r\n            case WINGET_CONFIG_ERROR_MANUALLY_SKIPPED: return Resource::String::ConfigurationUnitManuallySkipped();\r\n            case WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED: return Resource::String::ConfigurationUnitNotRunDueToDependency();\r\n            case WINGET_CONFIG_ERROR_ASSERTION_FAILED: return Resource::String::ConfigurationUnitNotRunDueToFailedAssert();\r\n            }\r\n\r\n            // If new cases arise and are not handled here, at least have a generic backstop message.\r\n            return Resource::String::ConfigurationUnitSkipped(resultCode);\r\n        }\r\n\r\n        void OutputUnitRunFailure(Context& context, const ConfigurationUnit& unit, const IConfigurationUnitResultInformation& resultInformation)\r\n        {\r\n            std::string description = Utility::Trim(Utility::ConvertToUTF8(resultInformation.Description()));\r\n\r\n            AICLI_LOG_LARGE_STRING(Config, Error, << \"Configuration unit \" << Utility::ConvertToUTF8(unit.Type()) << \"[\" << Utility::ConvertToUTF8(unit.Identifier()) << \"] failed with code 0x\"\r\n                << Logging::SetHRFormat << resultInformation.ResultCode() << \" and error message:\\n\" << description, Utility::ConvertToUTF8(resultInformation.Details()));\r\n\r\n            UnitFailedMessageData messageData = GetUnitFailedData(unit, resultInformation);\r\n            auto error = context.Reporter.Error();\r\n            error << \"  \"_liv << messageData.Message << std::endl;\r\n\r\n            if (messageData.ShowDescription && !description.empty())\r\n            {\r\n                constexpr size_t maximumDescriptionLines = 3;\r\n                size_t consoleWidth = GetConsoleWidth();\r\n                std::vector<std::string> lines = Utility::SplitIntoLines(description, maximumDescriptionLines + 1);\r\n                bool wasLimited = Utility::LimitOutputLines(lines, consoleWidth, maximumDescriptionLines);\r\n\r\n                for (const auto& line : lines)\r\n                {\r\n                    error << line << std::endl;\r\n                }\r\n\r\n                if (wasLimited || !resultInformation.Details().empty())\r\n                {\r\n                    error << Resource::String::ConfigurationDescriptionWasTruncated << std::endl;\r\n                }\r\n            }\r\n        }\r\n\r\n        // Coordinates an active progress scope and cancellation of the operation.\r\n        template<typename OperationT>\r\n        struct ProgressCancellationUnification\r\n        {\r\n            ProgressCancellationUnification(std::unique_ptr<Reporter::AsyncProgressScope>&& progressScope, const OperationT& operation) :\r\n                m_progressScope(std::move(progressScope)), m_operation(operation)\r\n            {\r\n                SetCancellationFunction();\r\n            }\r\n\r\n            void Reset()\r\n            {\r\n                m_cancelScope.reset();\r\n                m_progressScope.reset();\r\n            }\r\n\r\n            Reporter::AsyncProgressScope& Progress() const { return *m_progressScope; }\r\n\r\n            void Progress(std::unique_ptr<Reporter::AsyncProgressScope>&& progressScope)\r\n            {\r\n                m_cancelScope.reset();\r\n                m_progressScope = std::move(progressScope);\r\n                SetCancellationFunction();\r\n            }\r\n\r\n            OperationT& Operation() const { return m_operation; }\r\n\r\n        private:\r\n            void SetCancellationFunction()\r\n            {\r\n                if (m_progressScope)\r\n                {\r\n                    m_cancelScope = m_progressScope->Callback().SetCancellationFunction([this]() { m_operation.Cancel(); });\r\n                }\r\n            }\r\n\r\n            std::unique_ptr<Reporter::AsyncProgressScope> m_progressScope;\r\n            OperationT m_operation;\r\n            IProgressCallback::CancelFunctionRemoval m_cancelScope;\r\n        };\r\n\r\n        template<typename Operation>\r\n        ProgressCancellationUnification<Operation> CreateProgressCancellationUnification(\r\n            std::unique_ptr<Reporter::AsyncProgressScope>&& progressScope,\r\n            const Operation& operation)\r\n        {\r\n            return { std::move(progressScope), operation };\r\n        }\r\n\r\n        // The base type for progress reporting\r\n        template<typename ResultType, typename ProgressType>\r\n        struct ConfigurationSetProgressOutputBase\r\n        {\r\n            using Operation = IAsyncOperationWithProgress<ResultType, ProgressType>;\r\n\r\n            ConfigurationSetProgressOutputBase(Context& context, const Operation& operation) :\r\n                m_context(context), m_unification({}, operation)\r\n            {\r\n                operation.Progress([&](const Operation& operation, const ProgressType& data)\r\n                    {\r\n                        Progress(operation, data);\r\n                    });\r\n            }\r\n\r\n            virtual void Progress(const Operation& operation, const ProgressType& data) = 0;\r\n\r\n        protected:\r\n            void MarkCompleted(const ConfigurationUnit& unit)\r\n            {\r\n                winrt::guid unitInstance = unit.InstanceIdentifier();\r\n                m_unitsCompleted.insert(unitInstance);\r\n            }\r\n\r\n            bool UnitHasPreviouslyCompleted(const ConfigurationUnit& unit)\r\n            {\r\n                winrt::guid unitInstance = unit.InstanceIdentifier();\r\n                return m_unitsCompleted.count(unitInstance) != 0;\r\n            }\r\n\r\n            // Sends VT progress to the console\r\n            void OutputUnitCompletionProgress()\r\n            {\r\n                // TODO: Change progress reporting to enable separation of spinner and VT progress reporting\r\n                //  Preferably we want to be able to have:\r\n                //      1. Spinner with indefinite progress VT before set application begins\r\n                //      2. 1/N VT progress reporting for configuration units while also showing a spinner for the unit itself\r\n            }\r\n\r\n            void BeginProgress()\r\n            {\r\n                m_unification.Progress(m_context.Reporter.BeginAsyncProgress(true));\r\n            }\r\n\r\n            void EndProgress()\r\n            {\r\n                m_unification.Reset();\r\n            }\r\n\r\n            Context& m_context;\r\n\r\n        private:\r\n            ProgressCancellationUnification<Operation> m_unification;\r\n            std::set<winrt::guid> m_unitsCompleted;\r\n        };\r\n\r\n        // Helper to handle progress callbacks from ApplyConfigurationSetAsync\r\n        struct ApplyConfigurationSetProgressOutput final : public ConfigurationSetProgressOutputBase<ApplyConfigurationSetResult, ConfigurationSetChangeData>\r\n        {\r\n            using Operation = ConfigurationSetProgressOutputBase<ApplyConfigurationSetResult, ConfigurationSetChangeData>::Operation;\r\n\r\n            ApplyConfigurationSetProgressOutput(Context& context, const Operation& operation) :\r\n                ConfigurationSetProgressOutputBase(context, operation)\r\n            {\r\n            }\r\n\r\n            void Progress(const Operation& operation, const ConfigurationSetChangeData& data) override\r\n            {\r\n                auto threadContext = m_context.SetForCurrentThread();\r\n\r\n                if (m_isFirstProgress)\r\n                {\r\n                    HandleUnreportedProgress(operation.GetResults());\r\n                }\r\n\r\n                switch (data.Change())\r\n                {\r\n                case ConfigurationSetChangeEventType::SetStateChanged:\r\n                {\r\n                    switch (data.SetState())\r\n                    {\r\n                    case ConfigurationSetState::Pending:\r\n                        m_context.Reporter.Info() << Resource::String::ConfigurationWaitingOnAnother << std::endl;\r\n                        BeginProgress();\r\n                        break;\r\n                    case ConfigurationSetState::InProgress:\r\n                        EndProgress();\r\n                        break;\r\n                    case ConfigurationSetState::Completed:\r\n                        EndProgress();\r\n                        break;\r\n                    }\r\n                }\r\n                    break;\r\n                case ConfigurationSetChangeEventType::UnitStateChanged:\r\n                    HandleUnitProgress(data.Unit(), data.UnitState(), data.ResultInformation());\r\n                    break;\r\n                }\r\n            }\r\n\r\n            // If no progress has been reported, this function will report the given results\r\n            void HandleUnreportedProgress(const ApplyConfigurationSetResult& result)\r\n            {\r\n                if (m_isFirstProgress)\r\n                {\r\n                    m_isFirstProgress = false;\r\n\r\n                    for (const ApplyConfigurationUnitResult& unitResult : result.UnitResults())\r\n                    {\r\n                        HandleUnitProgress(unitResult.Unit(), unitResult.State(), unitResult.ResultInformation());\r\n                    }\r\n                }\r\n            }\r\n\r\n        private:\r\n            void HandleUnitProgress(const ConfigurationUnit& unit, ConfigurationUnitState state, const IConfigurationUnitResultInformation& resultInformation)\r\n            {\r\n                if (UnitHasPreviouslyCompleted(unit))\r\n                {\r\n                    return;\r\n                }\r\n\r\n                switch (state)\r\n                {\r\n                case ConfigurationUnitState::Pending:\r\n                    // The unreported progress handler may send pending units, just ignore them\r\n                    break;\r\n                case ConfigurationUnitState::InProgress:\r\n                    OutputUnitInProgressIfNeeded(unit);\r\n                    BeginProgress();\r\n                    break;\r\n                case ConfigurationUnitState::Completed:\r\n                    OutputUnitInProgressIfNeeded(unit);\r\n                    EndProgress();\r\n                    if (SUCCEEDED(resultInformation.ResultCode()))\r\n                    {\r\n                        m_context.Reporter.Info() << \"  \"_liv << Resource::String::ConfigurationUnitSuccessfullyApplied << std::endl;\r\n                    }\r\n                    else\r\n                    {\r\n                        OutputUnitRunFailure(m_context, unit, resultInformation);\r\n                    }\r\n                    MarkCompleted(unit);\r\n                    OutputUnitCompletionProgress();\r\n                    break;\r\n                case ConfigurationUnitState::Skipped:\r\n                    OutputUnitInProgressIfNeeded(unit);\r\n                    AICLI_LOG(Config, Warning, << \"Configuration unit \" << Utility::ConvertToUTF8(unit.Type()) << \"[\" << Utility::ConvertToUTF8(unit.Identifier()) << \"] was skipped with code 0x\"\r\n                        << Logging::SetHRFormat << resultInformation.ResultCode());\r\n                    m_context.Reporter.Warn() << \"  \"_liv << GetUnitSkippedMessage(resultInformation) << std::endl;\r\n                    MarkCompleted(unit);\r\n                    OutputUnitCompletionProgress();\r\n                    break;\r\n                }\r\n            }\r\n\r\n            void OutputUnitInProgressIfNeeded(const ConfigurationUnit& unit)\r\n            {\r\n                winrt::guid unitInstance = unit.InstanceIdentifier();\r\n                if (m_unitsSeen.count(unitInstance) == 0)\r\n                {\r\n                    m_unitsSeen.insert(unitInstance);\r\n\r\n                    OutputConfigurationUnitHeader(m_context, unit, unit.Details() ? unit.Details().UnitType() : unit.Type());\r\n                }\r\n            }\r\n\r\n            std::set<winrt::guid> m_unitsSeen;\r\n            bool m_isFirstProgress = true;\r\n        };\r\n\r\n        // Helper to handle progress callbacks from TestConfigurationSetAsync\r\n        struct TestConfigurationSetProgressOutput final : public ConfigurationSetProgressOutputBase<TestConfigurationSetResult, TestConfigurationUnitResult>\r\n        {\r\n            using Operation = ConfigurationSetProgressOutputBase<TestConfigurationSetResult, TestConfigurationUnitResult>::Operation;\r\n\r\n            TestConfigurationSetProgressOutput(Context& context, const Operation& operation) :\r\n                ConfigurationSetProgressOutputBase(context, operation)\r\n            {\r\n                // Start the spinner for the first unit being tested since we only receive completions\r\n                BeginProgress();\r\n            }\r\n\r\n            void Progress(const Operation& operation, const TestConfigurationUnitResult& data) override\r\n            {\r\n                auto threadContext = m_context.SetForCurrentThread();\r\n\r\n                if (m_isFirstProgress)\r\n                {\r\n                    HandleUnreportedProgress(operation.GetResults());\r\n                }\r\n\r\n                HandleUnitProgress(data.Unit(), data.TestResult(), data.ResultInformation());\r\n            }\r\n\r\n            // If no progress has been reported, this function will report the given results\r\n            void HandleUnreportedProgress(const TestConfigurationSetResult& result)\r\n            {\r\n                if (m_isFirstProgress)\r\n                {\r\n                    m_isFirstProgress = false;\r\n\r\n                    for (const TestConfigurationUnitResult& unitResult : result.UnitResults())\r\n                    {\r\n                        HandleUnitProgress(unitResult.Unit(), unitResult.TestResult(), unitResult.ResultInformation());\r\n                    }\r\n                }\r\n            }\r\n\r\n        private:\r\n            void HandleUnitProgress(const ConfigurationUnit& unit, ConfigurationTestResult testResult, const IConfigurationUnitResultInformation& resultInformation)\r\n            {\r\n                if (UnitHasPreviouslyCompleted(unit))\r\n                {\r\n                    return;\r\n                }\r\n\r\n                EndProgress();\r\n\r\n                OutputConfigurationUnitHeader(m_context, unit, unit.Details() ? unit.Details().UnitType() : unit.Type());\r\n\r\n                switch (testResult)\r\n                {\r\n                case ConfigurationTestResult::Failed:\r\n                    OutputUnitRunFailure(m_context, unit, resultInformation);\r\n                    break;\r\n                case ConfigurationTestResult::Negative:\r\n                    m_context.Reporter.Warn() << \"  \"_liv << Resource::String::ConfigurationNotInDesiredState << std::endl;\r\n                    break;\r\n                case ConfigurationTestResult::NotRun:\r\n                    m_context.Reporter.Warn() << \"  \"_liv << Resource::String::ConfigurationNoTestRun << std::endl;\r\n                    break;\r\n                case ConfigurationTestResult::Positive:\r\n                    m_context.Reporter.Info() << \"  \"_liv << Resource::String::ConfigurationInDesiredState << std::endl;\r\n                    break;\r\n                default: // ConfigurationTestResult::Unknown\r\n                    m_context.Reporter.Error() << \"  \"_liv << Resource::String::ConfigurationUnexpectedTestResult(ToIntegral(testResult)) << std::endl;\r\n                    break;\r\n                }\r\n\r\n                MarkCompleted(unit);\r\n                OutputUnitCompletionProgress();\r\n                BeginProgress();\r\n            }\r\n\r\n            bool m_isFirstProgress = true;\r\n        };\r\n\r\n        std::string GetNormalizedIdentifier(const winrt::hstring& identifier)\r\n        {\r\n            return Utility::FoldCase(Utility::NormalizedString{ identifier });\r\n        }\r\n\r\n        // Get unit validation order. Make sure dependency units are before units depending on them.\r\n        std::vector<uint32_t> GetConfigurationSetUnitValidationOrder(winrt::Windows::Foundation::Collections::IVectorView<ConfigurationUnit> units)\r\n        {\r\n            // Create id to index map for easier processing.\r\n            std::map<std::string, uint32_t> idToUnitIndex;\r\n            for (uint32_t i = 0; i < units.Size(); ++i)\r\n            {\r\n                auto id = GetNormalizedIdentifier(units.GetAt(i).Identifier());\r\n                if (!id.empty())\r\n                {\r\n                    idToUnitIndex.emplace(std::move(id), i);\r\n                }\r\n            }\r\n\r\n            // We do not need to worry about duplicate id, missing dependency or loops\r\n            // since dependency integrity is already validated in earlier semantic checks.\r\n\r\n            std::vector<uint32_t> validationOrder;\r\n\r\n            std::function<void(const ConfigurationUnit&, uint32_t)> addUnitToValidationOrder =\r\n                [&](const ConfigurationUnit& unit, uint32_t index)\r\n                {\r\n                    if (std::find(validationOrder.begin(), validationOrder.end(), index) == validationOrder.end())\r\n                    {\r\n                        for (auto const& dependencyId : unit.Dependencies())\r\n                        {\r\n                            auto dependencyIndex = idToUnitIndex.find(GetNormalizedIdentifier(dependencyId))->second;\r\n                            addUnitToValidationOrder(units.GetAt(dependencyIndex), dependencyIndex);\r\n                        }\r\n                        validationOrder.emplace_back(index);\r\n                    }\r\n                };\r\n\r\n            for (uint32_t i = 0; i < units.Size(); ++i)\r\n            {\r\n                addUnitToValidationOrder(units.GetAt(i), i);\r\n            }\r\n\r\n            THROW_HR_IF(E_UNEXPECTED, units.Size() != validationOrder.size());\r\n\r\n            return validationOrder;\r\n        }\r\n\r\n        void SetNameAndOrigin(ConfigurationSet& set, std::filesystem::path& absolutePath)\r\n        {\r\n            // TODO: Consider how to properly determine a good value for name and origin.\r\n            set.Name(absolutePath.filename().wstring());\r\n            set.Origin(absolutePath.parent_path().wstring());\r\n            set.Path(absolutePath.wstring());\r\n        }\r\n\r\n        void OpenConfigurationSet(Execution::Context& context, const std::string& argPath, bool allowRemote)\r\n        {\r\n            auto progressScope = context.Reporter.BeginAsyncProgress(true);\r\n            progressScope->Callback().SetProgressMessage(Resource::String::ConfigurationReadingConfigFile());\r\n\r\n            std::wstring argPathWide = Utility::ConvertToUTF16(argPath);\r\n            bool isRemote = Utility::IsUrlRemote(argPath);\r\n            std::filesystem::path absolutePath;\r\n            Streams::IInputStream inputStream = nullptr;\r\n\r\n            if (isRemote)\r\n            {\r\n                if (!allowRemote)\r\n                {\r\n                    AICLI_LOG(Config, Error, << \"Remote files are not supported\");\r\n                    AICLI_TERMINATE_CONTEXT(ERROR_NOT_SUPPORTED);\r\n                }\r\n\r\n                std::ostringstream stringStream;\r\n                ProgressCallback emptyCallback;\r\n                Utility::DownloadToStream(argPath, stringStream, Utility::DownloadType::ConfigurationFile, emptyCallback);\r\n\r\n                auto strContent = stringStream.str();\r\n                std::vector<BYTE> byteContent{ strContent.begin(), strContent.end() };\r\n\r\n                Streams::InMemoryRandomAccessStream memoryStream;\r\n                Streams::DataWriter streamWriter{ memoryStream };\r\n                streamWriter.WriteBytes(byteContent);\r\n                streamWriter.StoreAsync().get();\r\n                streamWriter.DetachStream();\r\n                memoryStream.Seek(0);\r\n                inputStream = memoryStream;\r\n            }\r\n            else\r\n            {\r\n                absolutePath = std::filesystem::weakly_canonical(std::filesystem::path{ argPathWide });\r\n                auto openAction = Streams::FileRandomAccessStream::OpenAsync(absolutePath.wstring(), FileAccessMode::Read);\r\n                auto cancellationScope = progressScope->Callback().SetCancellationFunction([&]() { openAction.Cancel(); });\r\n                inputStream = openAction.get();\r\n            }\r\n\r\n            OpenConfigurationSetResult openResult = nullptr;\r\n            {\r\n                auto openAction = context.Get<Data::ConfigurationContext>().Processor().OpenConfigurationSetAsync(inputStream);\r\n                auto cancellationScope = progressScope->Callback().SetCancellationFunction([&]() { openAction.Cancel(); });\r\n                openResult = openAction.get();\r\n            }\r\n\r\n            progressScope.reset();\r\n\r\n            if (FAILED_LOG(static_cast<HRESULT>(openResult.ResultCode().value)))\r\n            {\r\n                AICLI_LOG(Config, Error, << \"Failed to open configuration set at \" << (isRemote ? argPath : absolutePath.u8string()) << \" with error 0x\" << Logging::SetHRFormat << static_cast<HRESULT>(openResult.ResultCode().value));\r\n\r\n                switch (openResult.ResultCode())\r\n                {\r\n                case WINGET_CONFIG_ERROR_INVALID_FIELD_TYPE:\r\n                    context.Reporter.Error() << Resource::String::ConfigurationFieldInvalidType(Utility::LocIndString{ Utility::ConvertToUTF8(openResult.Field()) }) << std::endl;\r\n                    break;\r\n                case WINGET_CONFIG_ERROR_INVALID_FIELD_VALUE:\r\n                    context.Reporter.Error() << Resource::String::ConfigurationFieldInvalidValue(Utility::LocIndString{ Utility::ConvertToUTF8(openResult.Field()) }, Utility::LocIndString{ Utility::ConvertToUTF8(openResult.Value()) }) << std::endl;\r\n                    break;\r\n                case WINGET_CONFIG_ERROR_MISSING_FIELD:\r\n                    context.Reporter.Error() << Resource::String::ConfigurationFieldMissing(Utility::LocIndString{ Utility::ConvertToUTF8(openResult.Field()) }) << std::endl;\r\n                    break;\r\n                case WINGET_CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION:\r\n                    context.Reporter.Error() << Resource::String::ConfigurationFileVersionUnknown(Utility::LocIndString{ Utility::ConvertToUTF8(openResult.Value()) }) << std::endl;\r\n                    break;\r\n                case WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE:\r\n                case WINGET_CONFIG_ERROR_INVALID_YAML:\r\n                default:\r\n                    context.Reporter.Error() << Resource::String::ConfigurationFileInvalidYAML << std::endl;\r\n                    break;\r\n                }\r\n\r\n                if (openResult.Line() != 0)\r\n                {\r\n                    context.Reporter.Error() << Resource::String::SeeLineAndColumn(openResult.Line(), openResult.Column()) << std::endl;\r\n                }\r\n\r\n                AICLI_TERMINATE_CONTEXT(openResult.ResultCode());\r\n            }\r\n\r\n            ConfigurationSet result = openResult.Set();\r\n\r\n            // Fill out the information about the set based on it coming from a file.\r\n            if (isRemote)\r\n            {\r\n                result.Name(Utility::GetFileNameFromURI(argPath).wstring());\r\n                result.Origin(argPathWide);\r\n                // Do not set path. This means ${WinGetConfigRoot} not supported in remote configs.\r\n            }\r\n            else\r\n            {\r\n                SetNameAndOrigin(result, absolutePath);\r\n            }\r\n\r\n            context.Get<Data::ConfigurationContext>().Set(result);\r\n        }\r\n\r\n        ConfigurationUnit CreateConfigurationUnitFromModuleResource(std::string_view moduleName, std::string_view resourceName, std::string_view descriptionResourceName, const Utility::Version& schemaVersion)\r\n        {\r\n            std::wstring moduleNameWide = Utility::ConvertToUTF16(moduleName);\r\n            std::wstring resourceNameWide = Utility::ConvertToUTF16(resourceName);\r\n\r\n            ConfigurationUnit unit;\r\n            unit.Type(schemaVersion >= s_MinimumSchemaVersionModuleNameRequiredInType ? moduleNameWide + L'/' + resourceNameWide : resourceNameWide);\r\n            unit.Identifier(unit.Type() + L'_' + Utility::ConvertToUTF16(Utility::GetRandomString()));\r\n\r\n            ValueSet directives;\r\n            directives.Insert(s_Directive_Module, PropertyValue::CreateString(moduleNameWide));\r\n\r\n            Utility::LocIndString description;\r\n            if (!descriptionResourceName.empty())\r\n            {\r\n                description = Resource::String::ConfigureExportUnitDescription(Utility::LocIndView{ descriptionResourceName });\r\n            }\r\n            else\r\n            {\r\n                description = Resource::String::ConfigureExportUnitDescription(Utility::LocIndView{ resourceName });\r\n            }\r\n\r\n            directives.Insert(s_Directive_Description, PropertyValue::CreateString(winrt::to_hstring(description.get())));\r\n            unit.Metadata(directives);\r\n\r\n            return unit;\r\n        }\r\n\r\n        ConfigurationUnit CreateConfigurationUnitFromUnitType(std::wstring_view unitType, std::string_view descriptionResourceName = \"\")\r\n        {\r\n            ConfigurationUnit unit;\r\n            unit.Type(unitType);\r\n            unit.Identifier(unit.Type() + L'_' + Utility::ConvertToUTF16(Utility::GetRandomString()));\r\n\r\n            ValueSet directives;\r\n            Utility::LocIndString description;\r\n            if (!descriptionResourceName.empty())\r\n            {\r\n                description = Resource::String::ConfigureExportUnitDescription(Utility::LocIndView{ descriptionResourceName });\r\n            }\r\n            else\r\n            {\r\n                description = Resource::String::ConfigureExportUnitDescription(Utility::LocIndView{ Utility::ConvertToUTF8(unitType) });\r\n            }\r\n\r\n            directives.Insert(s_Directive_Description, PropertyValue::CreateString(winrt::to_hstring(description.get())));\r\n            unit.Metadata(directives);\r\n\r\n            return unit;\r\n        }\r\n\r\n        ConfigurationUnit CreatePowerShellPackageUnit()\r\n        {\r\n            ConfigurationUnit unit = CreateConfigurationUnitFromUnitType(s_UnitType_WinGetPackage_DSCv3, \"Microsoft.PowerShell\");\r\n\r\n            ValueSet settings;\r\n            settings.Insert(s_Setting_WinGetPackage_Id, PropertyValue::CreateString(s_Predefined_PowerShell_PackageId));\r\n            settings.Insert(s_Setting_WinGetPackage_Source, PropertyValue::CreateString(s_Predefined_PowerShell_PackageSource));\r\n            unit.Settings(settings);\r\n\r\n            return unit;\r\n        }\r\n\r\n        ValueSet CreateValueSetFromStringVector(const std::vector<std::wstring>& values)\r\n        {\r\n            ValueSet result;\r\n            size_t index = 0;\r\n\r\n            for (const auto& value : values)\r\n            {\r\n                std::wostringstream strstr;\r\n                strstr << index++;\r\n                result.Insert(strstr.str(), PropertyValue::CreateString(value));\r\n            }\r\n\r\n            result.Insert(L\"treatAsArray\", PropertyValue::CreateBoolean(true));\r\n            return result;\r\n        }\r\n\r\n        // TODO: This is a workaround unit to ensure v2 dsc resource modules. Move to dsc v3 resource when available.\r\n        ConfigurationUnit CreateRequiredModuleUnit(std::wstring_view moduleName, const ConfigurationUnit& dependentUnit)\r\n        {\r\n            std::wstring moduleNameString{ moduleName };\r\n\r\n            ConfigurationUnit unit = CreateConfigurationUnitFromUnitType(L\"Microsoft.DSC.Transitional/RunCommandOnSet\", Utility::ConvertToUTF8(moduleName));\r\n\r\n            ValueSet settings;\r\n            settings.Insert(L\"executable\", PropertyValue::CreateString(L\"pwsh\"));\r\n            std::vector<std::wstring> arguments =\r\n            {\r\n                L\"-NoProfile\",\r\n                L\"-NoLogo\",\r\n                L\"-Command\",\r\n                L\"if (-not (Get-Module -ListAvailable -Name \" + moduleNameString + L\")) { Install-Module -Name \" + moduleNameString + L\" -Confirm:$False -Force -AllowPrerelease -AllowClobber }\"\r\n            };\r\n            settings.Insert(L\"arguments\", CreateValueSetFromStringVector(arguments));\r\n            unit.Settings(settings);\r\n\r\n            unit.Dependencies().Append(dependentUnit.Identifier());\r\n\r\n            return unit;\r\n        }\r\n\r\n        std::wstring GetWinGetSourceUnitType(const ConfigurationContext& configContext)\r\n        {\r\n            Utility::Version schemaVersion = { Utility::ConvertToUTF8(configContext.Set().SchemaVersion()) };\r\n            ConfigurationRemoting::ProcessorEngine processorEngine = ConfigurationRemoting::DetermineProcessorEngine(configContext.Set());\r\n\r\n            if (schemaVersion >= s_MinimumSchemaVersionModuleNameRequiredInType)\r\n            {\r\n                if (processorEngine == ConfigurationRemoting::ProcessorEngine::DSCv3)\r\n                {\r\n                    return std::wstring{ s_UnitType_WinGetSource_DSCv3 };\r\n                }\r\n                else\r\n                {\r\n                    return std::wstring{ s_Module_WinGetClient } + L'/' + std::wstring{ s_Unit_WinGetSource };\r\n                }\r\n            }\r\n            else\r\n            {\r\n                return std::wstring{ s_Unit_WinGetSource };\r\n            }\r\n        }\r\n\r\n        ConfigurationUnit CreateWinGetSourceUnit(const PackageCollection::Source& source, std::wstring_view unitType)\r\n        {\r\n            std::string sourceUnitId = source.Details.Name + '_' + source.Details.Type;\r\n            std::wstring sourceUnitIdWide = Utility::ConvertToUTF16(sourceUnitId);\r\n\r\n            ConfigurationUnit unit;\r\n            unit.Type(unitType);\r\n            unit.Identifier(sourceUnitIdWide);\r\n            unit.Intent(ConfigurationUnitIntent::Apply);\r\n\r\n            auto description = Resource::String::ConfigureExportUnitDescription(Utility::LocIndView{ sourceUnitId });\r\n\r\n            ValueSet directives;\r\n            directives.Insert(s_Directive_Description, PropertyValue::CreateString(winrt::to_hstring(description.get())));\r\n            unit.Metadata(directives);\r\n\r\n            ValueSet settings;\r\n            settings.Insert(s_Setting_WinGetSource_Name, PropertyValue::CreateString(Utility::ConvertToUTF16(source.Details.Name)));\r\n            settings.Insert(s_Setting_WinGetSource_Arg, PropertyValue::CreateString(Utility::ConvertToUTF16(source.Details.Arg)));\r\n            settings.Insert(s_Setting_WinGetSource_Type, PropertyValue::CreateString(Utility::ConvertToUTF16(source.Details.Type)));\r\n            if (WI_IsFlagSet(source.Details.TrustLevel, Repository::SourceTrustLevel::Trusted))\r\n            {\r\n                settings.Insert(s_Setting_WinGetSource_TrustLevel, PropertyValue::CreateString(L\"trusted\"));\r\n            }\r\n            if (source.Details.Explicit)\r\n            {\r\n                settings.Insert(s_Setting_WinGetSource_Explicit, PropertyValue::CreateBoolean(true));\r\n            }\r\n            if (source.Details.Priority != 0)\r\n            {\r\n                settings.Insert(s_Setting_WinGetSource_Priority, PropertyValue::CreateInt32(source.Details.Priority));\r\n            }\r\n            unit.Settings(settings);\r\n\r\n            unit.Environment().Context(SecurityContext::Elevated);\r\n\r\n            return unit;\r\n        }\r\n\r\n        std::wstring GetWinGetPackageUnitType(const ConfigurationContext& configContext)\r\n        {\r\n            Utility::Version schemaVersion = { Utility::ConvertToUTF8(configContext.Set().SchemaVersion()) };\r\n            ConfigurationRemoting::ProcessorEngine processorEngine = ConfigurationRemoting::DetermineProcessorEngine(configContext.Set());\r\n\r\n            if (schemaVersion >= s_MinimumSchemaVersionModuleNameRequiredInType)\r\n            {\r\n                if (processorEngine == ConfigurationRemoting::ProcessorEngine::DSCv3)\r\n                {\r\n                    return std::wstring{ s_UnitType_WinGetPackage_DSCv3 };\r\n                }\r\n                else\r\n                {\r\n                    return std::wstring{ s_Module_WinGetClient } + L'/' + std::wstring{ s_Unit_WinGetPackage };\r\n                }\r\n            }\r\n            else\r\n            {\r\n                return std::wstring{ s_Unit_WinGetPackage };\r\n            }\r\n        }\r\n\r\n        ConfigurationUnit CreateWinGetPackageUnit(const PackageCollection::Package& package, const PackageCollection::Source& source, bool includeVersion, const ConfigurationUnit& dependentUnit, std::wstring_view unitType)\r\n        {\r\n            std::wstring packageIdWide = Utility::ConvertToUTF16(package.Id);\r\n            std::wstring sourceNameWide = Utility::ConvertToUTF16(source.Details.Name);\r\n\r\n            ConfigurationUnit unit;\r\n            unit.Type(unitType);\r\n            unit.Identifier(sourceNameWide + L'_' + packageIdWide);\r\n            unit.Intent(ConfigurationUnitIntent::Apply);\r\n\r\n            auto description = Resource::String::ConfigureExportUnitInstallDescription(package.Id);\r\n\r\n            ValueSet directives;\r\n            directives.Insert(s_Directive_Description, PropertyValue::CreateString(winrt::to_hstring(description.get())));\r\n            unit.Metadata(directives);\r\n\r\n            ValueSet settings;\r\n            settings.Insert(s_Setting_WinGetPackage_Id, PropertyValue::CreateString(packageIdWide));\r\n            settings.Insert(s_Setting_WinGetPackage_Source, PropertyValue::CreateString(sourceNameWide));\r\n            if (includeVersion)\r\n            {\r\n                settings.Insert(s_Setting_WinGetPackage_Version, PropertyValue::CreateString(Utility::ConvertToUTF16(package.VersionAndChannel.GetVersion().ToString())));\r\n            }\r\n            unit.Settings(settings);\r\n\r\n            // TODO: We may consider setting security environment based on installer elevation requirements?\r\n\r\n            // Add dependency if needed.\r\n            if (dependentUnit)\r\n            {\r\n                auto dependencies = winrt::single_threaded_vector<winrt::hstring>();\r\n                dependencies.Append(dependentUnit.Identifier());\r\n                unit.Dependencies(std::move(dependencies));\r\n            }\r\n\r\n            return unit;\r\n        }\r\n\r\n        ApplyConfigurationUnitResult ApplyUnit(Execution::Context& context, ConfigurationUnit& unit)\r\n        {\r\n            unit.Intent(ConfigurationUnitIntent::Apply);\r\n\r\n            auto progressScope = context.Reporter.BeginAsyncProgress(true);\r\n\r\n            progressScope->Callback().SetProgressMessage(Resource::String::ConfigurationApplyingUnit());\r\n\r\n            ApplyConfigurationUnitResult applyResult = nullptr;\r\n            {\r\n                auto applyAction = context.Get<Data::ConfigurationContext>().Processor().ApplyUnitAsync(unit);\r\n                auto cancellationScope = progressScope->Callback().SetCancellationFunction([&]() { applyAction.Cancel(); });\r\n                applyResult = applyAction.get();\r\n            }\r\n\r\n            progressScope.reset();\r\n            return applyResult;\r\n        }\r\n\r\n        GetConfigurationUnitSettingsResult GetUnitSettings(Execution::Context& context, ConfigurationUnit& unit)\r\n        {\r\n            // This assumes there are no required properties for Get, but for example WinGetPackage requires the Id.\r\n            // It is obviously wrong and will be wrong until Export is implemented for DSC v2 and a proper way to inform\r\n            // about input to winget configure export is implemented. Drink the kool-aid and transcend.\r\n            unit.Intent(ConfigurationUnitIntent::Inform);\r\n\r\n            auto progressScope = context.Reporter.BeginAsyncProgress(true);\r\n\r\n            progressScope->Callback().SetProgressMessage(Resource::String::ConfigurationGettingResourceSettings());\r\n\r\n            GetConfigurationUnitSettingsResult getResult = nullptr;\r\n            {\r\n                auto getAction = context.Get<Data::ConfigurationContext>().Processor().GetUnitSettingsAsync(unit);\r\n                auto cancellationScope = progressScope->Callback().SetCancellationFunction([&]() { getAction.Cancel(); });\r\n                getResult = getAction.get();\r\n            }\r\n\r\n            progressScope.reset();\r\n            return getResult;\r\n        }\r\n\r\n        GetAllConfigurationUnitsResult GetAllUnits(Execution::Context& context, ConfigurationUnit& unit)\r\n        {\r\n            unit.Intent(ConfigurationUnitIntent::Inform);\r\n\r\n            auto progressScope = context.Reporter.BeginAsyncProgress(true);\r\n\r\n            progressScope->Callback().SetProgressMessage(Resource::String::ConfigurationExportingUnit());\r\n\r\n            GetAllConfigurationUnitsResult getResult = nullptr;\r\n            {\r\n                auto getAction = context.Get<Data::ConfigurationContext>().Processor().GetAllUnitsAsync(unit);\r\n                auto cancellationScope = progressScope->Callback().SetCancellationFunction([&]() { getAction.Cancel(); });\r\n                getResult = getAction.get();\r\n            }\r\n\r\n            progressScope.reset();\r\n            return getResult;\r\n        }\r\n\r\n        std::vector<ConfigurationUnit> ExportUnit(Execution::Context& context, ConfigurationUnit& unit, bool throwOnFailure = false)\r\n        {\r\n            std::vector<ConfigurationUnit> result;\r\n\r\n            context.Reporter.Info() << Resource::String::ConfigurationExportUnitStart(Utility::LocIndView{ Utility::ConvertToUTF8(unit.Type()) }) << std::endl;\r\n\r\n            // Try export first\r\n            auto exportResult = GetAllUnits(context, unit);\r\n            auto exportResultCode = exportResult.ResultInformation().ResultCode();\r\n            if (SUCCEEDED(exportResultCode))\r\n            {\r\n                for (auto resultUnit : exportResult.Units())\r\n                {\r\n                    result.emplace_back(std::move(resultUnit));\r\n                }\r\n            }\r\n            else\r\n            {\r\n                AICLI_LOG(Config, Warning, << \"Failed GetAllUnits. Will try GetUnitSettings.\");\r\n                LogFailedGetConfigurationUnitDetails(unit, exportResult.ResultInformation());\r\n\r\n                // Try GetUnitSettings if export failed.\r\n                auto getResult = GetUnitSettings(context, unit);\r\n                auto getResultCode = getResult.ResultInformation().ResultCode();\r\n                if (getResultCode == WINGET_CONFIG_ERROR_UNIT_NOT_FOUND_REPOSITORY)\r\n                {\r\n                    // Retry if it fails with not found in the case the module is a pre-released one.\r\n                    AICLI_LOG(Config, Info, << \"Failed GetUnitSettings because module not found. Will try allow prerelease.\");\r\n                    auto directives = unit.Metadata();\r\n                    directives.Insert(s_Directive_AllowPrerelease, PropertyValue::CreateBoolean(true));\r\n                    unit.Metadata(directives);\r\n\r\n                    getResult = GetUnitSettings(context, unit);\r\n                }\r\n\r\n                if (FAILED(getResult.ResultInformation().ResultCode()))\r\n                {\r\n                    AICLI_LOG(Config, Error, << \"Failed Get Unit Settings\");\r\n                    LogFailedGetConfigurationUnitDetails(unit, getResult.ResultInformation());\r\n\r\n                    if (throwOnFailure)\r\n                    {\r\n                        context.Reporter.Error() << Resource::String::ConfigurationExportUnitFailed << std::endl;\r\n                        OutputUnitRunFailure(context, unit, getResult.ResultInformation());\r\n                        THROW_HR(WINGET_CONFIG_ERROR_GET_FAILED);\r\n                    }\r\n                    else\r\n                    {\r\n                        context.Reporter.Warn() << Resource::String::ConfigurationExportUnitFailed << std::endl;\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    unit.Settings(getResult.Settings());\r\n                    result.emplace_back(unit);\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        void AddDependentUnit(std::vector<ConfigurationUnit>& units, const ConfigurationUnit& dependentUnit)\r\n        {\r\n            for (auto& unit : units)\r\n            {\r\n                unit.Dependencies().Append(dependentUnit.Identifier());\r\n            }\r\n        }\r\n\r\n        void AddElevatedEnvironment(std::vector<ConfigurationUnit>& units)\r\n        {\r\n            for (auto& unit : units)\r\n            {\r\n                unit.Environment().Context(SecurityContext::Elevated);\r\n            }\r\n        }\r\n\r\n        std::vector<IConfigurationUnitProcessorDetails> GetAllUnitProcessors(Execution::Context& context)\r\n        {\r\n            ConfigurationContext& configContext = context.Get<Data::ConfigurationContext>();\r\n            std::vector<IConfigurationUnitProcessorDetails> result;\r\n\r\n            // Only supported by dsc v3 processor.\r\n            if (ConfigurationRemoting::ProcessorEngine::DSCv3 == ConfigurationRemoting::DetermineProcessorEngine(configContext.Set()))\r\n            {\r\n                auto progressScope = context.Reporter.BeginAsyncProgress(true);\r\n\r\n                progressScope->Callback().SetProgressMessage(Resource::String::ConfigurationGettingUnitProcessors());\r\n\r\n                {\r\n                    FindUnitProcessorsOptions findOptions;\r\n                    findOptions.UnitDetailFlags(ConfigurationUnitDetailFlags::Local);\r\n                    auto findAction = context.Get<Data::ConfigurationContext>().Processor().FindUnitProcessorsAsync(findOptions);\r\n                    auto cancellationScope = progressScope->Callback().SetCancellationFunction([&]() { findAction.Cancel(); });\r\n                    for (auto unitProcessor : findAction.get())\r\n                    {\r\n                        result.emplace_back(std::move(unitProcessor));\r\n                    }\r\n                }\r\n\r\n                progressScope.reset();\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        void ExportPredefinedResources(Execution::Context& context)\r\n        {\r\n            ConfigurationContext& configContext = context.Get<Data::ConfigurationContext>();\r\n\r\n            // PowerShell package needs to be present for certain predefined modules to work.\r\n            ConfigurationUnit powerShellPackageUnit = CreatePowerShellPackageUnit();\r\n            configContext.Set().Units().Append(powerShellPackageUnit);\r\n\r\n            // Apply the unit to make sure it's on the system.\r\n            context.Reporter.Info() << Resource::String::ConfigurationExportInstallRequiredModule(Utility::LocIndView{ \"Microsoft PowerShell Package\" }) << std::endl;\r\n            auto applyPowerShellResult = ApplyUnit(context, powerShellPackageUnit);\r\n            if (FAILED(applyPowerShellResult.ResultInformation().ResultCode()))\r\n            {\r\n                AICLI_LOG(Config, Warning, << \"Failed to ensure module. [Microsoft PowerShell Package] Related settings may not be exported.\");\r\n                LogFailedGetConfigurationUnitDetails(powerShellPackageUnit, applyPowerShellResult.ResultInformation());\r\n                context.Reporter.Warn() << Resource::String::ConfigurationExportInstallRequiredModuleFailed << std::endl;\r\n            }\r\n\r\n            for (const auto& resources : PredefinedResourcesForExport())\r\n            {\r\n                std::optional<ConfigurationUnit> requiredModuleUnit;\r\n\r\n                if (!resources.RequiredModule.empty())\r\n                {\r\n                    requiredModuleUnit = CreateRequiredModuleUnit(resources.RequiredModule, powerShellPackageUnit);\r\n\r\n                    // Apply the unit to make sure it's on the system.\r\n                    context.Reporter.Info() << Resource::String::ConfigurationExportInstallRequiredModule(Utility::LocIndView{ Utility::ConvertToUTF8(resources.RequiredModule) }) << std::endl;\r\n                    auto applyResult = ApplyUnit(context, requiredModuleUnit.value());\r\n                    if (SUCCEEDED(applyResult.ResultInformation().ResultCode()))\r\n                    {\r\n                        configContext.Set().Units().Append(requiredModuleUnit.value());\r\n                    }\r\n                    else\r\n                    {\r\n                        AICLI_LOG(Config, Warning, << \"Failed to ensure module. [\" << Utility::ConvertToUTF8(resources.RequiredModule) << \"] Related settings will not be exported.\");\r\n                        LogFailedGetConfigurationUnitDetails(requiredModuleUnit.value(), applyResult.ResultInformation());\r\n                        context.Reporter.Warn() << Resource::String::ConfigurationExportInstallRequiredModuleFailed << std::endl;\r\n                        continue;\r\n                    }\r\n                }\r\n\r\n                for (const auto& resourceInfo : resources.ResourceInfos)\r\n                {\r\n                    auto resourceUnit = CreateConfigurationUnitFromUnitType(resourceInfo.UnitType);\r\n                    auto exportedUnits = ExportUnit(context, resourceUnit);\r\n\r\n                    if (requiredModuleUnit)\r\n                    {\r\n                        AddDependentUnit(exportedUnits, requiredModuleUnit.value());\r\n                    }\r\n\r\n                    // The dynamic processor factory does not support operating elevated units without a set.\r\n                    // Luckily the Get/Export for all PreDefinedResources do not require elevation.\r\n                    // Here we add elevation environment to exported results.\r\n                    if (resourceInfo.ElevationRequired)\r\n                    {\r\n                        AddElevatedEnvironment(exportedUnits);\r\n                    }\r\n\r\n                    for (auto exportedUnit : exportedUnits)\r\n                    {\r\n                        configContext.Set().Units().Append(std::move(exportedUnit));\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // Contains a tree of all unit processors by their path.\r\n        struct UnitProcessorTree\r\n        {\r\n        private:\r\n            struct SourceAndPackage\r\n            {\r\n                PackageCollection::Source Source;\r\n                PackageCollection::Package Package;\r\n            };\r\n\r\n            struct Node\r\n            {\r\n                // Packages whose installed location is at this node\r\n                std::vector<SourceAndPackage> Packages;\r\n\r\n                // Units whose location is at this node.\r\n                std::vector<IConfigurationUnitProcessorDetails> Units;\r\n            };\r\n\r\n            Filesystem::PathTree<Node> m_pathTree;\r\n\r\n            Node& FindNodeForFilePath(const winrt::hstring& filePath)\r\n            {\r\n                std::filesystem::path path{ std::wstring{ filePath } };\r\n                return m_pathTree.FindOrInsert(path.parent_path());\r\n            }\r\n\r\n        public:\r\n            UnitProcessorTree(std::vector<IConfigurationUnitProcessorDetails>&& unitProcessors)\r\n            {\r\n                for (auto&& unit : unitProcessors)\r\n                {\r\n                    IConfigurationUnitProcessorDetails3 unitProcessor3;\r\n                    if (unit.try_as(unitProcessor3))\r\n                    {\r\n                        winrt::hstring unitPath = unitProcessor3.Path();\r\n                        AICLI_LOG(Config, Verbose, << \"Found unit `\" << Utility::ConvertToUTF8(unit.UnitType()) << \"` at: \" << Utility::ConvertToUTF8(unitPath));\r\n                        Node& node = FindNodeForFilePath(unitPath);\r\n                        node.Units.emplace_back(std::move(unit));\r\n                    }\r\n                }\r\n            }\r\n\r\n            void PlacePackage(const PackageCollection::Source& source, const PackageCollection::Package& package)\r\n            {\r\n                Node* node = m_pathTree.Find(package.InstalledLocation);\r\n                if (node)\r\n                {\r\n                    node->Packages.emplace_back(SourceAndPackage{ source, package });\r\n                }\r\n            }\r\n\r\n            std::vector<IConfigurationUnitProcessorDetails> GetResourcesForPackage(const PackageCollection::Package& package) const\r\n            {\r\n                std::vector<IConfigurationUnitProcessorDetails> result;\r\n\r\n                m_pathTree.VisitIf(\r\n                    package.InstalledLocation,\r\n                    [&](const Node& node)\r\n                    {\r\n                        for (const auto& unit : node.Units)\r\n                        {\r\n                            result.emplace_back(unit);\r\n                        }\r\n                    },\r\n                    [](const Node& node)\r\n                    {\r\n                        return node.Packages.empty();\r\n                    });\r\n\r\n                return result;\r\n            }\r\n        };\r\n\r\n        void ProcessPackagesForConfigurationExportAll(Execution::Context& context)\r\n        {\r\n            ConfigurationContext& configContext = context.Get<Data::ConfigurationContext>();\r\n            std::wstring sourceUnitType = GetWinGetSourceUnitType(configContext);\r\n            std::wstring packageUnitType = GetWinGetPackageUnitType(configContext);\r\n\r\n            // This will be later used by per package settings export.\r\n            std::vector<IConfigurationUnitProcessorDetails> unitProcessors;\r\n            try\r\n            {\r\n                unitProcessors = GetAllUnitProcessors(context);\r\n            }\r\n            catch (...)\r\n            {\r\n                AICLI_LOG(Config, Warning, << \"Finding unit processors failed. Individual package settings will not be exported.\");\r\n                context.Reporter.Warn() << Resource::String::ConfigurationExportFailedToGetUnitProcessors << std::endl;\r\n            }\r\n\r\n            auto exclusionList = PackageSettingsExclusionList();\r\n\r\n            // Filter out processors in exclusion list.\r\n            for (auto itr = unitProcessors.begin(); itr != unitProcessors.end(); /* itr incremented in the logic */)\r\n            {\r\n                bool processorRemoved = false;\r\n                for (const auto& exclusionItem : exclusionList)\r\n                {\r\n                    if (Utility::CaseInsensitiveStartsWith(itr->UnitType(), exclusionItem))\r\n                    {\r\n                        itr = unitProcessors.erase(itr);\r\n                        processorRemoved = true;\r\n                        break;\r\n                    }\r\n                }\r\n\r\n                if (!processorRemoved)\r\n                {\r\n                    itr++;\r\n                }\r\n            }\r\n\r\n            // Build a tree of the unit processors and place packages onto it to indicate nearest ownership.\r\n            UnitProcessorTree unitProcessorTree{ std::move(unitProcessors) };\r\n\r\n            for (const auto& source : context.Get<Execution::Data::PackageCollection>().Sources)\r\n            {\r\n                for (const auto& package : source.Packages)\r\n                {\r\n                    unitProcessorTree.PlacePackage(source, package);\r\n                }\r\n            }\r\n\r\n            for (const auto& source : context.Get<Execution::Data::PackageCollection>().Sources)\r\n            {\r\n                // Create WinGetSource unit\r\n                ConfigurationUnit sourceUnit = anon::CreateWinGetSourceUnit(source, sourceUnitType);\r\n                configContext.Set().Units().Append(sourceUnit);\r\n\r\n                for (const auto& package : source.Packages)\r\n                {\r\n                    AICLI_LOG(Config, Verbose, << \"Exporting package `\" << package.Id << \"` at: \" << package.InstalledLocation);\r\n\r\n                    auto packageUnit = anon::CreateWinGetPackageUnit(package, source, context.Args.Contains(Args::Type::IncludeVersions), sourceUnit, packageUnitType);\r\n                    configContext.Set().Units().Append(packageUnit);\r\n\r\n                    // Try package settings export.\r\n                    auto unitsForPackage = unitProcessorTree.GetResourcesForPackage(package);\r\n                    for (const auto& unit : unitsForPackage)\r\n                    {\r\n                        winrt::hstring unitType = unit.UnitType();\r\n                        AICLI_LOG(Config, Verbose, << \"  exporting unit `\" << Utility::ConvertToUTF8(unitType));\r\n\r\n                        ConfigurationUnit configUnit = anon::CreateConfigurationUnitFromUnitType(\r\n                            unitType,\r\n                            Utility::ConvertToUTF8(packageUnit.Identifier()));\r\n\r\n                        auto exportedUnits = anon::ExportUnit(context, configUnit);\r\n                        anon::AddDependentUnit(exportedUnits, packageUnit);\r\n\r\n                        for (const auto& exportedUnit : exportedUnits)\r\n                        {\r\n                            configContext.Set().Units().Append(exportedUnit);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        void ProcessPackagesForConfigurationExportSingle(Execution::Context& context)\r\n        {\r\n            ConfigurationContext& configContext = context.Get<Data::ConfigurationContext>();\r\n\r\n            // When exporting single WinGetPackage unit, the WinGetPackage unit can be used as a dependent unit for following configuration unit.\r\n            std::optional<ConfigurationUnit> singlePackageUnit;\r\n\r\n            if (context.Args.Contains(Execution::Args::Type::ConfigurationExportPackageId))\r\n            {\r\n                const auto& exportSources = context.Get<Execution::Data::PackageCollection>().Sources;\r\n                // There should be 1 package under 1 source.\r\n                THROW_HR_IF(E_UNEXPECTED, exportSources.size() != 1 || exportSources[0].Packages.size() != 1);\r\n\r\n                ConfigurationUnit sourceUnit = anon::CreateWinGetSourceUnit(exportSources[0], GetWinGetSourceUnitType(configContext));\r\n                configContext.Set().Units().Append(sourceUnit);\r\n\r\n                singlePackageUnit = anon::CreateWinGetPackageUnit(exportSources[0].Packages[0], exportSources[0], context.Args.Contains(Args::Type::IncludeVersions), sourceUnit, GetWinGetPackageUnitType(configContext));\r\n                configContext.Set().Units().Append(singlePackageUnit.value());\r\n            }\r\n\r\n            if (context.Args.Contains(Execution::Args::Type::ConfigurationExportModule, Execution::Args::Type::ConfigurationExportResource))\r\n            {\r\n                auto configUnit = anon::CreateConfigurationUnitFromModuleResource(\r\n                    context.Args.GetArg(Args::Type::ConfigurationExportModule),\r\n                    context.Args.GetArg(Args::Type::ConfigurationExportResource),\r\n                    singlePackageUnit ? Utility::ConvertToUTF8(singlePackageUnit->Identifier()) : \"\",\r\n                    Utility::Version{ Utility::ConvertToUTF8(configContext.Set().SchemaVersion()) });\r\n\r\n                auto exportedUnits = anon::ExportUnit(context, configUnit, true);\r\n\r\n                if (singlePackageUnit)\r\n                {\r\n                    anon::AddDependentUnit(exportedUnits, singlePackageUnit.value());\r\n                }\r\n\r\n                for (auto exportedUnit : exportedUnits)\r\n                {\r\n                    configContext.Set().Units().Append(exportedUnit);\r\n                }\r\n            }\r\n        }\r\n\r\n        bool HistorySetMatchesInput(const ConfigurationSet& set, const std::string& foldedInput)\r\n        {\r\n            if (foldedInput.empty())\r\n            {\r\n                return false;\r\n            }\r\n\r\n            if (Utility::FoldCase(Utility::NormalizedString{ set.Name() }) == foldedInput)\r\n            {\r\n                return true;\r\n            }\r\n\r\n            std::ostringstream identifierStream;\r\n            identifierStream << set.InstanceIdentifier();\r\n            std::string identifier = identifierStream.str();\r\n            THROW_HR_IF(E_UNEXPECTED, identifier.empty());\r\n\r\n            std::size_t startPosition = 0;\r\n            if (identifier[0] == '{' && foldedInput[0] != '{')\r\n            {\r\n                startPosition = 1;\r\n            }\r\n\r\n            std::string_view identifierView = identifier;\r\n            identifierView = identifierView.substr(startPosition);\r\n\r\n            return Utility::CaseInsensitiveStartsWith(identifierView, foldedInput);\r\n        }\r\n\r\n        Resource::LocString ToLocString(ConfigurationSetState state)\r\n        {\r\n            switch (state)\r\n            {\r\n            case ConfigurationSetState::Pending:\r\n                return Resource::String::ConfigurationSetStatePending;\r\n            case ConfigurationSetState::InProgress:\r\n                return Resource::String::ConfigurationSetStateInProgress;\r\n            case ConfigurationSetState::Completed:\r\n                return Resource::String::ConfigurationSetStateCompleted;\r\n            case ConfigurationSetState::Unknown:\r\n            default:\r\n                return Resource::String::ConfigurationSetStateUnknown;\r\n            }\r\n        }\r\n\r\n        Resource::LocString ToLocString(ConfigurationUnitState state)\r\n        {\r\n            switch (state)\r\n            {\r\n            case ConfigurationUnitState::Pending:\r\n                return Resource::String::ConfigurationUnitStatePending;\r\n            case ConfigurationUnitState::InProgress:\r\n                return Resource::String::ConfigurationUnitStateInProgress;\r\n            case ConfigurationUnitState::Completed:\r\n                return Resource::String::ConfigurationUnitStateCompleted;\r\n            case ConfigurationUnitState::Skipped:\r\n                return Resource::String::ConfigurationUnitStateSkipped;\r\n            case ConfigurationUnitState::Unknown:\r\n            default:\r\n                return Resource::String::ConfigurationUnitStateUnknown;\r\n            }\r\n        }\r\n\r\n        std::string_view ToString(ConfigurationChangeEventType type)\r\n        {\r\n            switch (type)\r\n            {\r\n            case ConfigurationChangeEventType::SetAdded:\r\n                return \"SetAdded\";\r\n            case ConfigurationChangeEventType::SetStateChanged:\r\n                return \"SetStateChanged\";\r\n            case ConfigurationChangeEventType::SetRemoved:\r\n                return \"SetRemoved\";\r\n            case ConfigurationChangeEventType::Unknown:\r\n            default:\r\n                return \"Unknown\";\r\n            }\r\n        }\r\n\r\n        std::string_view ToString(ConfigurationUnitResultSource source)\r\n        {\r\n            switch (source)\r\n            {\r\n            case ConfigurationUnitResultSource::Internal:\r\n                return \"Internal\";\r\n            case ConfigurationUnitResultSource::ConfigurationSet:\r\n                return \"ConfigurationSet\";\r\n            case ConfigurationUnitResultSource::UnitProcessing:\r\n                return \"UnitProcessing\";\r\n            case ConfigurationUnitResultSource::SystemState:\r\n                return \"SystemState\";\r\n            case ConfigurationUnitResultSource::Precondition:\r\n                return \"Precondition\";\r\n            case ConfigurationUnitResultSource::None:\r\n            default:\r\n                return \"None\";\r\n            }\r\n        }\r\n    }\r\n\r\n    void CreateConfigurationProcessor(Context& context)\r\n    {\r\n        anon::ConfigureProcessorForUse(context, ConfigurationProcessor{ anon::CreateConfigurationSetProcessorFactory(context) });\r\n    }\r\n\r\n    void CreateConfigurationProcessorWithoutFactory(Execution::Context& context)\r\n    {\r\n        anon::ConfigureProcessorForUse(context, ConfigurationProcessor{ IConfigurationSetProcessorFactory{ nullptr } });\r\n    }\r\n\r\n    void OpenConfigurationSet(Context& context)\r\n    {\r\n        if (context.Args.Contains(Args::Type::ConfigurationFile))\r\n        {\r\n            std::string argPath{ context.Args.GetArg(Args::Type::ConfigurationFile) };\r\n            anon::OpenConfigurationSet(context, argPath, true);\r\n        }\r\n        else\r\n        {\r\n            THROW_HR_IF(E_UNEXPECTED, !context.Args.Contains(Args::Type::ConfigurationHistoryItem));\r\n\r\n            context <<\r\n                GetConfigurationSetHistory <<\r\n                SelectSetFromHistory;\r\n        }\r\n    }\r\n\r\n    void CreateOrOpenConfigurationSet::operator()(Context& context) const\r\n    {\r\n        std::string argPath{ context.Args.GetArg(Args::Type::OutputFile) };\r\n\r\n        if (std::filesystem::exists(argPath) && !m_createAlways)\r\n        {\r\n            anon::OpenConfigurationSet(context, argPath, false);\r\n        }\r\n        else\r\n        {\r\n            ConfigurationSet set;\r\n            set.SchemaVersion(Utility::ConvertToUTF16(m_defaultSchemaVersion));\r\n            set.Environment().ProcessorIdentifier(ConfigurationRemoting::ToString(ConfigurationRemoting::ProcessorEngine::DSCv3));\r\n\r\n            std::wstring argPathWide = Utility::ConvertToUTF16(argPath);\r\n            auto absolutePath = std::filesystem::weakly_canonical(std::filesystem::path{ argPathWide });\r\n            anon::SetNameAndOrigin(set, absolutePath);\r\n\r\n            context.Get<Data::ConfigurationContext>().Set(set);\r\n        }\r\n    }\r\n\r\n    void ShowConfigurationSet(Context& context)\r\n    {\r\n        ConfigurationContext& configContext = context.Get<Data::ConfigurationContext>();\r\n\r\n        if (configContext.Set().Units().Size() == 0)\r\n        {\r\n            context.Reporter.Warn() << Resource::String::ConfigurationFileEmpty << std::endl;\r\n            // This isn't an error termination, but there is no reason to proceed.\r\n            AICLI_TERMINATE_CONTEXT(S_FALSE);\r\n        }\r\n\r\n        auto gettingDetailString = Resource::String::ConfigurationGettingDetails();\r\n        auto progressScope = context.Reporter.BeginAsyncProgress(true);\r\n        progressScope->Callback().SetProgressMessage(gettingDetailString);\r\n\r\n        auto getDetailsOperation = configContext.Processor().GetSetDetailsAsync(configContext.Set(), ConfigurationUnitDetailFlags::ReadOnly);\r\n        auto unification = anon::CreateProgressCancellationUnification(std::move(progressScope), getDetailsOperation);\r\n\r\n        bool suppressDetailsOutput = context.Args.Contains(Args::Type::ConfigurationSuppressPrologue);\r\n        anon::OutputHelper outputHelper{ context };\r\n        uint32_t unitsShown = 0;\r\n\r\n        if (!suppressDetailsOutput)\r\n        {\r\n            getDetailsOperation.Progress([&](const IAsyncOperationWithProgress<GetConfigurationSetDetailsResult, GetConfigurationUnitDetailsResult>& operation, const GetConfigurationUnitDetailsResult&)\r\n                {\r\n                    auto threadContext = context.SetForCurrentThread();\r\n\r\n                    unification.Reset();\r\n\r\n                    auto unitResults = operation.GetResults().UnitResults();\r\n                    for (unitsShown; unitsShown < unitResults.Size(); ++unitsShown)\r\n                    {\r\n                        GetConfigurationUnitDetailsResult unitResult = unitResults.GetAt(unitsShown);\r\n                        anon::LogFailedGetConfigurationUnitDetails(unitResult.Unit(), unitResult.ResultInformation());\r\n                        outputHelper.OutputConfigurationUnitInformation(unitResult.Unit());\r\n                    }\r\n\r\n                    progressScope = context.Reporter.BeginAsyncProgress(true);\r\n                    progressScope->Callback().SetProgressMessage(gettingDetailString);\r\n                    unification.Progress(std::move(progressScope));\r\n                });\r\n        }\r\n\r\n        HRESULT hr = S_OK;\r\n        GetConfigurationSetDetailsResult result = nullptr;\r\n\r\n        try\r\n        {\r\n            result = getDetailsOperation.get();\r\n        }\r\n        catch (...)\r\n        {\r\n            hr = LOG_CAUGHT_EXCEPTION();\r\n        }\r\n\r\n        unification.Reset();\r\n\r\n        if (context.IsTerminated())\r\n        {\r\n            // The context should only be terminated on us due to cancellation\r\n            context.Reporter.Error() << Resource::String::Cancelled << std::endl;\r\n            return;\r\n        }\r\n\r\n        if (FAILED(hr))\r\n        {\r\n            // Failing to get details might not be fatal, warn about it but proceed\r\n            context.Reporter.Warn() << Resource::String::ConfigurationFailedToGetDetails << std::endl;\r\n        }\r\n\r\n        // Handle any missing progress callbacks that are in the results\r\n        if (result && !suppressDetailsOutput)\r\n        {\r\n            auto unitResults = result.UnitResults();\r\n            if (unitResults)\r\n            {\r\n                for (unitsShown; unitsShown < unitResults.Size(); ++unitsShown)\r\n                {\r\n                    GetConfigurationUnitDetailsResult unitResult = unitResults.GetAt(unitsShown);\r\n                    anon::LogFailedGetConfigurationUnitDetails(unitResult.Unit(), unitResult.ResultInformation());\r\n                    outputHelper.OutputConfigurationUnitInformation(unitResult.Unit());\r\n                }\r\n            }\r\n        }\r\n\r\n        // Handle any units that are NOT in the results (due to an exception part of the way through)\r\n        if (!suppressDetailsOutput)\r\n        {\r\n            auto allUnits = configContext.Set().Units();\r\n            for (unitsShown; unitsShown < allUnits.Size(); ++unitsShown)\r\n            {\r\n                ConfigurationUnit unit = allUnits.GetAt(unitsShown);\r\n                outputHelper.OutputConfigurationUnitInformation(unit);\r\n            }\r\n        }\r\n\r\n        if (outputHelper.ValuesTruncated)\r\n        {\r\n            // Using error to make this stand out from other warnings\r\n            context.Reporter.Error() << Resource::String::ConfigurationWarningSetViewTruncated << std::endl;\r\n        }\r\n    }\r\n\r\n    void ShowConfigurationSetConflicts(Execution::Context& context)\r\n    {\r\n        UNREFERENCED_PARAMETER(context);\r\n    }\r\n\r\n    void ConfirmConfigurationProcessing::operator()(Execution::Context& context) const\r\n    {\r\n        context.Reporter.Warn() << Resource::String::ConfigurationWarning << std::endl;\r\n\r\n        if (!context.Args.Contains(Args::Type::ConfigurationAcceptWarning))\r\n        {\r\n            context << RequireInteractivity(WINGET_CONFIG_ERROR_WARNING_NOT_ACCEPTED);\r\n            if (context.IsTerminated())\r\n            {\r\n                return;\r\n            }\r\n\r\n            auto promptString = m_isApply ? Resource::String::ConfigurationWarningPromptApply : Resource::String::ConfigurationWarningPromptTest;\r\n            if (!context.Reporter.PromptForBoolResponse(promptString, Reporter::Level::Warning, false))\r\n            {\r\n                AICLI_TERMINATE_CONTEXT(WINGET_CONFIG_ERROR_WARNING_NOT_ACCEPTED);\r\n            }\r\n        }\r\n    }\r\n\r\n    void ApplyConfigurationSet(Execution::Context& context)\r\n    {\r\n        ApplyConfigurationSetResult result = nullptr;\r\n        ConfigurationContext& configContext = context.Get<Data::ConfigurationContext>();\r\n\r\n        {\r\n            auto applyOperation = configContext.Processor().ApplySetAsync(configContext.Set(), ApplyConfigurationSetFlags::None);\r\n            anon::ApplyConfigurationSetProgressOutput progress{ context, applyOperation };\r\n\r\n            result = applyOperation.get();\r\n            progress.HandleUnreportedProgress(result);\r\n        }\r\n\r\n        if (FAILED(result.ResultCode()))\r\n        {\r\n            context.Reporter.Error() << Resource::String::ConfigurationFailedToApply << std::endl;\r\n\r\n            // TODO: Summarize failed configuration units, especially if we put more output for each one during execution\r\n\r\n            AICLI_TERMINATE_CONTEXT(result.ResultCode());\r\n        }\r\n        else\r\n        {\r\n            context.Reporter.Info() << Resource::String::ConfigurationSuccessfullyApplied << std::endl;\r\n        }\r\n    }\r\n\r\n    void TestConfigurationSet(Execution::Context& context)\r\n    {\r\n        TestConfigurationSetResult result = nullptr;\r\n        ConfigurationContext& configContext = context.Get<Data::ConfigurationContext>();\r\n\r\n        {\r\n            auto testOperation = configContext.Processor().TestSetAsync(configContext.Set());\r\n            anon::TestConfigurationSetProgressOutput progress{ context, testOperation };\r\n\r\n            result = testOperation.get();\r\n            progress.HandleUnreportedProgress(result);\r\n        }\r\n\r\n        switch (result.TestResult())\r\n        {\r\n        case ConfigurationTestResult::Failed:\r\n            context.Reporter.Error() << Resource::String::ConfigurationFailedToTest << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(WINGET_CONFIG_ERROR_TEST_FAILED);\r\n            break;\r\n        case ConfigurationTestResult::Negative:\r\n            context.Reporter.Warn() << Resource::String::ConfigurationNotInDesiredState << std::endl;\r\n            context.SetTerminationHR(S_FALSE);\r\n            break;\r\n        case ConfigurationTestResult::NotRun:\r\n            context.Reporter.Warn() << Resource::String::ConfigurationNoTestRun << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(WINGET_CONFIG_ERROR_TEST_NOT_RUN);\r\n            break;\r\n        case ConfigurationTestResult::Positive:\r\n            context.Reporter.Info() << Resource::String::ConfigurationInDesiredState << std::endl;\r\n            break;\r\n        default: // ConfigurationTestResult::Unknown\r\n            context.Reporter.Error() << Resource::String::ConfigurationUnexpectedTestResult(ToIntegral(result.TestResult())) << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(E_FAIL);\r\n            break;\r\n        }\r\n    }\r\n\r\n    void ValidateConfigurationSetSemantics(Execution::Context& context)\r\n    {\r\n        ConfigurationContext& configContext = context.Get<Data::ConfigurationContext>();\r\n\r\n        if (configContext.Set().Units().Size() == 0)\r\n        {\r\n            context.Reporter.Warn() << Resource::String::ConfigurationFileEmpty << std::endl;\r\n            // This isn't an error termination, but there is no reason to proceed.\r\n            AICLI_TERMINATE_CONTEXT(S_FALSE);\r\n        }\r\n\r\n        ApplyConfigurationSetResult result = configContext.Processor().ApplySet(configContext.Set(), ApplyConfigurationSetFlags::PerformConsistencyCheckOnly);\r\n\r\n        if (FAILED(result.ResultCode()))\r\n        {\r\n            for (const auto& unitResult : result.UnitResults())\r\n            {\r\n                IConfigurationUnitResultInformation resultInformation = unitResult.ResultInformation();\r\n                winrt::hresult resultCode = resultInformation.ResultCode();\r\n\r\n                if (FAILED(resultCode))\r\n                {\r\n                    ConfigurationUnit unit = unitResult.Unit();\r\n\r\n                    anon::OutputConfigurationUnitHeader(context, unit, unit.Type());\r\n\r\n                    switch (resultCode)\r\n                    {\r\n                    case WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER:\r\n                        context.Reporter.Error() << \"  \"_liv << Resource::String::ConfigurationUnitHasDuplicateIdentifier(Utility::LocIndString{ Utility::ConvertToUTF8(unit.Identifier()) }) << std::endl;\r\n                        break;\r\n                    case WINGET_CONFIG_ERROR_MISSING_DEPENDENCY:\r\n                        context.Reporter.Error() << \"  \"_liv << Resource::String::ConfigurationUnitHasMissingDependency(Utility::LocIndString{ Utility::ConvertToUTF8(resultInformation.Details()) }) << std::endl;\r\n                        break;\r\n                    case WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED:\r\n                        context.Reporter.Error() << \"  \"_liv << Resource::String::ConfigurationUnitIsPartOfDependencyCycle << std::endl;\r\n                        break;\r\n                    default:\r\n                        context.Reporter.Error() << \"  \"_liv << Resource::String::ConfigurationUnitFailed(static_cast<int32_t>(resultCode)) << std::endl;\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n\r\n            AICLI_TERMINATE_CONTEXT(result.ResultCode());\r\n        }\r\n    }\r\n\r\n    void ValidateConfigurationSetUnitProcessors(Execution::Context& context)\r\n    {\r\n        ConfigurationContext& configContext = context.Get<Data::ConfigurationContext>();\r\n\r\n        // TODO: We could optimize this by creating a set with unique resource units\r\n\r\n        // First get the local details\r\n        auto gettingDetailString = Resource::String::ConfigurationGettingDetails();\r\n        auto progressScope = context.Reporter.BeginAsyncProgress(true);\r\n        progressScope->Callback().SetProgressMessage(gettingDetailString);\r\n\r\n        auto getLocalDetailsOperation = configContext.Processor().GetSetDetailsAsync(configContext.Set(), ConfigurationUnitDetailFlags::Local);\r\n        auto unification = anon::CreateProgressCancellationUnification(std::move(progressScope), getLocalDetailsOperation);\r\n\r\n        HRESULT getLocalHR = S_OK;\r\n        GetConfigurationSetDetailsResult getLocalResult = nullptr;\r\n\r\n        try\r\n        {\r\n            getLocalResult = getLocalDetailsOperation.get();\r\n        }\r\n        catch (...)\r\n        {\r\n            getLocalHR = LOG_CAUGHT_EXCEPTION();\r\n        }\r\n\r\n        unification.Reset();\r\n\r\n        if (context.IsTerminated())\r\n        {\r\n            // The context should only be terminated on us due to cancellation\r\n            context.Reporter.Error() << Resource::String::Cancelled << std::endl;\r\n            return;\r\n        }\r\n\r\n        if (FAILED(getLocalHR))\r\n        {\r\n            // Failing to get details might not be fatal, warn about it but proceed\r\n            context.Reporter.Warn() << Resource::String::ConfigurationFailedToGetDetails << std::endl;\r\n        }\r\n\r\n        // Next get the details from the catalog\r\n        progressScope = context.Reporter.BeginAsyncProgress(true);\r\n        progressScope->Callback().SetProgressMessage(gettingDetailString);\r\n\r\n        auto getCatalogDetailsOperation = configContext.Processor().GetSetDetailsAsync(configContext.Set(), ConfigurationUnitDetailFlags::Catalog);\r\n        unification = anon::CreateProgressCancellationUnification(std::move(progressScope), getCatalogDetailsOperation);\r\n\r\n        HRESULT getCatalogHR = S_OK;\r\n        GetConfigurationSetDetailsResult getCatalogResult = nullptr;\r\n\r\n        try\r\n        {\r\n            getCatalogResult = getCatalogDetailsOperation.get();\r\n        }\r\n        catch (...)\r\n        {\r\n            getCatalogHR = LOG_CAUGHT_EXCEPTION();\r\n        }\r\n\r\n        unification.Reset();\r\n\r\n        if (context.IsTerminated())\r\n        {\r\n            // The context should only be terminated on us due to cancellation\r\n            context.Reporter.Error() << Resource::String::Cancelled << std::endl;\r\n            return;\r\n        }\r\n\r\n        if (FAILED(getCatalogHR))\r\n        {\r\n            // Failing to get the catalog details means that we can't really get give much of a meaningful response.\r\n            context.Reporter.Error() << Resource::String::ConfigurationFailedToGetDetails << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(getCatalogHR);\r\n        }\r\n\r\n        auto units = configContext.Set().Units();\r\n        auto localUnitResults = getLocalResult ? getLocalResult.UnitResults() : nullptr;\r\n        if (localUnitResults && units.Size() != localUnitResults.Size())\r\n        {\r\n            AICLI_LOG(Config, Error, << \"The details result size did not match the set size: Set[\" << units.Size() << \"], Local[\" << localUnitResults.Size() << \"]\");\r\n            THROW_HR(WINGET_CONFIG_ERROR_ASSERTION_FAILED);\r\n        }\r\n\r\n        auto catalogUnitResults = getCatalogResult.UnitResults();\r\n        if (units.Size() != catalogUnitResults.Size())\r\n        {\r\n            AICLI_LOG(Config, Error, << \"The details result sizes did not match the set size: Set[\" << units.Size() << \"], Catalog[\" << catalogUnitResults.Size() << \"]\");\r\n            THROW_HR(WINGET_CONFIG_ERROR_ASSERTION_FAILED);\r\n        }\r\n\r\n        bool foundIssue = false;\r\n\r\n        // Now that we have the entire set of local and catalog details, process each unit\r\n        for (uint32_t i = 0; i < units.Size(); ++i)\r\n        {\r\n            const ConfigurationUnit& unit = units.GetAt(i);\r\n            GetConfigurationUnitDetailsResult localUnitResult = localUnitResults ? localUnitResults.GetAt(i) : nullptr;\r\n            GetConfigurationUnitDetailsResult catalogUnitResult = catalogUnitResults.GetAt(i);\r\n            IConfigurationUnitProcessorDetails catalogDetails = catalogUnitResult.Details();\r\n\r\n            bool needsHeader = true;\r\n            auto outputHeaderIfNeeded = [&]()\r\n            {\r\n                if (needsHeader)\r\n                {\r\n                    anon::OutputConfigurationUnitHeader(context, unit, unit.Type());\r\n\r\n                    needsHeader = false;\r\n                    foundIssue = true;\r\n                }\r\n            };\r\n\r\n            if (anon::GetValueSetString(unit.Metadata(), anon::s_Directive_Module).empty())\r\n            {\r\n                outputHeaderIfNeeded();\r\n                context.Reporter.Warn() << \"  \"_liv << Resource::String::ConfigurationUnitModuleNotProvidedWarning << std::endl;\r\n            }\r\n\r\n            if (catalogDetails)\r\n            {\r\n                // Warn if unit is not public\r\n                if (!catalogDetails.IsPublic())\r\n                {\r\n                    outputHeaderIfNeeded();\r\n                    context.Reporter.Warn() << \"  \"_liv << Resource::String::ConfigurationUnitNotPublicWarning << std::endl;\r\n                }\r\n\r\n                // Since it is available, no more checks are needed\r\n                continue;\r\n            }\r\n            // Everything below here is due to not finding in the catalog search\r\n\r\n            if (FAILED(catalogUnitResult.ResultInformation().ResultCode()))\r\n            {\r\n                outputHeaderIfNeeded();\r\n                anon::OutputUnitRunFailure(context, unit, catalogUnitResult.ResultInformation());\r\n                continue;\r\n            }\r\n\r\n            // If not already prerelease, try with prerelease and warn if found\r\n            std::optional<bool> allowPrereleaseDirective = anon::GetValueSetBool(unit.Metadata(), anon::s_Directive_AllowPrerelease);\r\n            if (!allowPrereleaseDirective || !allowPrereleaseDirective.value())\r\n            {\r\n                // Check if the configuration unit is prerelease but the author forgot it\r\n                ConfigurationUnit clone = unit.Copy();\r\n                clone.Metadata().Insert(anon::s_Directive_AllowPrerelease, PropertyValue::CreateBoolean(true));\r\n\r\n                progressScope = context.Reporter.BeginAsyncProgress(true);\r\n                progressScope->Callback().SetProgressMessage(gettingDetailString);\r\n\r\n                auto getUnitDetailsOperation = configContext.Processor().GetUnitDetailsAsync(clone, ConfigurationUnitDetailFlags::Catalog);\r\n                auto unitUnification = anon::CreateProgressCancellationUnification(std::move(progressScope), getUnitDetailsOperation);\r\n\r\n                IConfigurationUnitProcessorDetails prereleaseDetails;\r\n\r\n                try\r\n                {\r\n                    prereleaseDetails = getUnitDetailsOperation.get().Details();\r\n                }\r\n                CATCH_LOG();\r\n\r\n                unification.Reset();\r\n\r\n                if (prereleaseDetails)\r\n                {\r\n                    outputHeaderIfNeeded();\r\n                    context.Reporter.Warn() << \"  \"_liv << Resource::String::ConfigurationUnitNeedsPrereleaseWarning << std::endl;\r\n                    continue;\r\n                }\r\n            }\r\n\r\n            // If module is local, warn that we couldn't find it in the catalog\r\n            if (localUnitResult && localUnitResult.Details())\r\n            {\r\n                outputHeaderIfNeeded();\r\n                context.Reporter.Warn() << \"  \"_liv << Resource::String::ConfigurationUnitNotInCatalogWarning << std::endl;\r\n                continue;\r\n            }\r\n\r\n            // Finally, error that we couldn't find it at all\r\n            outputHeaderIfNeeded();\r\n            context.Reporter.Error() << \"  \"_liv << Resource::String::ConfigurationUnitNotFound << std::endl;\r\n        }\r\n\r\n        if (foundIssue)\r\n        {\r\n            // Indicate that it was not a total success\r\n            AICLI_TERMINATE_CONTEXT(S_FALSE);\r\n        }\r\n    }\r\n\r\n    void ValidateConfigurationSetUnitContents(Execution::Context& context)\r\n    {\r\n        ConfigurationContext& configContext = context.Get<Data::ConfigurationContext>();\r\n        auto units = configContext.Set().Units();\r\n        auto validationOrder = anon::GetConfigurationSetUnitValidationOrder(units.GetView());\r\n\r\n        Configuration::WingetDscModuleUnitValidator wingetUnitValidator;\r\n\r\n        bool foundIssues = false;\r\n        for (const auto index : validationOrder)\r\n        {\r\n            const ConfigurationUnit& unit = units.GetAt(index);\r\n            auto moduleName = Utility::ConvertToUTF8(unit.Details().ModuleName());\r\n            if (Utility::CaseInsensitiveEquals(wingetUnitValidator.ModuleName(), moduleName))\r\n            {\r\n                bool result = wingetUnitValidator.ValidateConfigurationSetUnit(context, unit);\r\n                if (!result)\r\n                {\r\n                    foundIssues = true;\r\n                }\r\n            }\r\n        }\r\n\r\n        if (foundIssues)\r\n        {\r\n            // Indicate that it was not a total success\r\n            AICLI_TERMINATE_CONTEXT(S_FALSE);\r\n        }\r\n    }\r\n\r\n    void ValidateAllGoodMessage(Execution::Context& context)\r\n    {\r\n        context.Reporter.Info() << Resource::String::ConfigurationValidationFoundNoIssues << std::endl;\r\n    }\r\n\r\n    void SearchSourceForPackageExport(Execution::Context& context)\r\n    {\r\n        if (!context.Args.Contains(Args::Type::ConfigurationExportAll) && !context.Args.Contains(Args::Type::ConfigurationExportPackageId))\r\n        {\r\n            // No package export needed.\r\n            return;\r\n        }\r\n\r\n        context <<\r\n            OpenSource() <<\r\n            OpenCompositeSource(Repository::PredefinedSource::Installed);\r\n\r\n        if (context.Args.Contains(Args::Type::ConfigurationExportAll))\r\n        {\r\n            context <<\r\n                SearchSourceForMany <<\r\n                HandleSearchResultFailures <<\r\n                EnsureMatchesFromSearchResult(OperationType::Export) <<\r\n                SelectVersionsToExport;\r\n        }\r\n        else if (context.Args.Contains(Args::Type::ConfigurationExportPackageId))\r\n        {\r\n            context.Args.AddArg(Args::Type::Id, context.Args.GetArg(Args::Type::ConfigurationExportPackageId));\r\n            context <<\r\n                SearchSourceForSingle <<\r\n                Workflow::HandleSearchResultFailures <<\r\n                Workflow::EnsureOneMatchFromSearchResult(OperationType::Export) <<\r\n                SelectVersionsToExport;\r\n        }\r\n    }\r\n\r\n    void PopulateConfigurationSetForExport(Execution::Context& context)\r\n    {\r\n        bool isExportAll = context.Args.Contains(Execution::Args::Type::ConfigurationExportAll);\r\n\r\n        if (isExportAll)\r\n        {\r\n            context <<\r\n                anon::ExportPredefinedResources <<\r\n                SearchSourceForPackageExport <<\r\n                anon::ProcessPackagesForConfigurationExportAll;\r\n        }\r\n        else\r\n        {\r\n            context <<\r\n                SearchSourceForPackageExport <<\r\n                anon::ProcessPackagesForConfigurationExportSingle;\r\n        }\r\n    }\r\n\r\n    void WriteConfigFile(Execution::Context& context)\r\n    {\r\n        try\r\n        {\r\n            std::string argPath{ context.Args.GetArg(Args::Type::OutputFile) };\r\n\r\n            context.Reporter.Info() << Resource::String::ConfigurationExportAddingToFile(Utility::LocIndView{ argPath }) << std::endl;\r\n\r\n            auto tempFilePath = Runtime::GetNewTempFilePath();\r\n\r\n            {\r\n                std::ofstream tempStream{ tempFilePath };\r\n                tempStream << \"# Created using winget configure export \" << Runtime::GetClientVersion().get() << std::endl;\r\n            }\r\n\r\n            auto openAction = Streams::FileRandomAccessStream::OpenAsync(\r\n                tempFilePath.wstring(),\r\n                FileAccessMode::ReadWrite);\r\n\r\n            auto stream = openAction.get();\r\n            stream.Seek(stream.Size());\r\n\r\n            ConfigurationContext& configContext = context.Get<Data::ConfigurationContext>();\r\n            configContext.Set().Serialize(openAction.get());\r\n\r\n            auto absolutePath = std::filesystem::weakly_canonical(std::filesystem::path{ argPath });\r\n            std::filesystem::rename(tempFilePath, absolutePath);\r\n\r\n            context.Reporter.Info() << Resource::String::ConfigurationExportSuccessful << std::endl;\r\n        }\r\n        catch (...)\r\n        {\r\n            context.Reporter.Error() << Resource::String::ConfigurationExportFailed << std::endl;\r\n            throw;\r\n        }\r\n    }\r\n\r\n    void GetConfigurationSetHistory(Execution::Context& context)\r\n    {\r\n        auto progressScope = context.Reporter.BeginAsyncProgress(true);\r\n\r\n        ConfigurationContext& configContext = context.Get<Data::ConfigurationContext>();\r\n        configContext.History(configContext.Processor().GetConfigurationHistory());\r\n    }\r\n\r\n    void ShowConfigurationSetHistory(Execution::Context& context)\r\n    {\r\n        const auto& history = context.Get<Data::ConfigurationContext>().History();\r\n\r\n        if (history.empty())\r\n        {\r\n            context.Reporter.Info() << Resource::String::ConfigurationHistoryEmpty << std::endl;\r\n        }\r\n        else\r\n        {\r\n            TableOutput<4> historyTable{ context.Reporter, { Resource::String::ConfigureListIdentifier, Resource::String::ConfigureListName, Resource::String::ConfigureListState, Resource::String::ConfigureListOrigin } };\r\n\r\n            for (const auto& set : history)\r\n            {\r\n                winrt::hstring origin = set.Path();\r\n                if (origin.empty())\r\n                {\r\n                    origin = set.Origin();\r\n                }\r\n\r\n                historyTable.OutputLine({ Utility::ConvertGuidToString(set.InstanceIdentifier()), Utility::ConvertToUTF8(set.Name()), anon::ToLocString(set.State()), Utility::ConvertToUTF8(origin)});\r\n            }\r\n\r\n            historyTable.Complete();\r\n        }\r\n    }\r\n\r\n    void SelectSetFromHistory(Execution::Context& context)\r\n    {\r\n        ConfigurationContext& configContext = context.Get<Data::ConfigurationContext>();\r\n        ConfigurationSet selectedSet{ nullptr };\r\n\r\n        std::string foldedInput = Utility::FoldCase(context.Args.GetArg(Execution::Args::Type::ConfigurationHistoryItem));\r\n\r\n        for (const ConfigurationSet& historySet : configContext.History())\r\n        {\r\n            if (anon::HistorySetMatchesInput(historySet, foldedInput))\r\n            {\r\n                if (selectedSet)\r\n                {\r\n                    selectedSet = nullptr;\r\n                    break;\r\n                }\r\n                else\r\n                {\r\n                    selectedSet = historySet;\r\n                }\r\n            }\r\n        }\r\n\r\n        if (!selectedSet)\r\n        {\r\n            context.Reporter.Warn() << Resource::String::ConfigurationHistoryItemNotFound << std::endl;\r\n            context << ShowConfigurationSetHistory;\r\n            AICLI_TERMINATE_CONTEXT(WINGET_CONFIG_ERROR_HISTORY_ITEM_NOT_FOUND);\r\n        }\r\n\r\n        configContext.Set(std::move(selectedSet));\r\n    }\r\n\r\n    void RemoveConfigurationSetHistory(Execution::Context& context)\r\n    {\r\n        auto progressScope = context.Reporter.BeginAsyncProgress(true);\r\n        context.Get<Data::ConfigurationContext>().Set().Remove();\r\n    }\r\n\r\n    void SerializeConfigurationSetHistory(Execution::Context& context)\r\n    {\r\n        auto progressScope = context.Reporter.BeginAsyncProgress(true);\r\n        std::filesystem::path absolutePath = std::filesystem::weakly_canonical(std::filesystem::path{ Utility::ConvertToUTF16(context.Args.GetArg(Execution::Args::Type::OutputFile)) });\r\n        auto openAction = Streams::FileRandomAccessStream::OpenAsync(absolutePath.wstring(), FileAccessMode::ReadWrite, StorageOpenOptions::None, Streams::FileOpenDisposition::CreateAlways);\r\n        auto cancellationScope = progressScope->Callback().SetCancellationFunction([&]() { openAction.Cancel(); });\r\n        auto outputStream = openAction.get();\r\n\r\n        context.Get<Data::ConfigurationContext>().Set().Serialize(outputStream);\r\n    }\r\n\r\n    void ShowSingleConfigurationSetHistory(Execution::Context& context)\r\n    {\r\n        const auto& set = context.Get<Data::ConfigurationContext>().Set();\r\n\r\n        // Output a table with name/value pairs for some of the set's properties. Example:\r\n        // \r\n        // Field         Value\r\n        // ----------------------------------------------------\r\n        // Identifier    {7D5CF50E-F3C6-4333-BFE6-5A806F9EBA4E}\r\n        // Name          Test Name\r\n        // Origin        Test Origin\r\n        // Path          Test Path\r\n        // State         Completed\r\n        // First Applied 2024-07-16 21:15:13.000\r\n        // Apply Begun   2024-07-16 21:15:13.000\r\n        // Apply Ended   2024-07-16 21:15:13.000\r\n        Execution::TableOutput<2> table(context.Reporter, { Resource::String::SourceListField, Resource::String::SourceListValue });\r\n\r\n        table.OutputLine({ Resource::LocString{ Resource::String::ConfigureListIdentifier }, Utility::ConvertGuidToString(set.InstanceIdentifier()) });\r\n        table.OutputLine({ Resource::LocString{ Resource::String::ConfigureListName }, Utility::ConvertToUTF8(set.Name()) });\r\n        table.OutputLine({ Resource::LocString{ Resource::String::ConfigureListOrigin }, Utility::ConvertToUTF8(set.Origin()) });\r\n        table.OutputLine({ Resource::LocString{ Resource::String::ConfigureListPath }, Utility::ConvertToUTF8(set.Path()) });\r\n        table.OutputLine({ Resource::LocString{ Resource::String::ConfigureListState }, anon::ToLocString(set.State()) });\r\n        table.OutputLine({ Resource::LocString{ Resource::String::ConfigureListFirstApplied }, Utility::TimePointToString(winrt::clock::to_sys(set.FirstApply())) });\r\n\r\n        auto applyBegun = set.ApplyBegun();\r\n        if (applyBegun != winrt::clock::time_point{})\r\n        {\r\n            table.OutputLine({ Resource::LocString{ Resource::String::ConfigureListApplyBegun }, Utility::TimePointToString(winrt::clock::to_sys(applyBegun)) });\r\n        }\r\n\r\n        auto applyEnded = set.ApplyEnded();\r\n        if (applyEnded != winrt::clock::time_point{})\r\n        {\r\n            table.OutputLine({ Resource::LocString{ Resource::String::ConfigureListApplyEnded }, Utility::TimePointToString(winrt::clock::to_sys(applyEnded)) });\r\n        }\r\n\r\n        table.Complete();\r\n\r\n        context.Reporter.Info() << std::endl;\r\n\r\n        // Output a table with unit state information. Groups are represented by indentation beneath their parent unit. Example:\r\n        //\r\n        // Unit                        State     Result     Details\r\n        // ------------------------------------------------------------\r\n        // Module/Resource [Name]      Completed 0x00000000\r\n        // Module2/Resource [Group]    Completed 0x00000000\r\n        // |-Module3/Resource [Child1] Completed 0x00000000\r\n        // |---Module4/Resource2       Completed 0x80004005 I failed :(\r\n        // |-Module3/Resource [Child2] Completed 0x00000000\r\n        Execution::TableOutput<4> unitTable(context.Reporter, { Resource::String::ConfigureListUnit, Resource::String::ConfigureListState, Resource::String::ConfigureListResult, Resource::String::ConfigureListResultDescription });\r\n\r\n        struct UnitSiblings\r\n        {\r\n            size_t Depth = 0;\r\n            size_t Current = 0;\r\n            std::vector<ConfigurationUnit> Siblings;\r\n        };\r\n\r\n        std::vector<UnitSiblings> stack;\r\n\r\n        {\r\n            UnitSiblings initial;\r\n            auto units = set.Units();\r\n            initial.Siblings.resize(units.Size());\r\n            units.GetMany(0, initial.Siblings);\r\n            stack.emplace_back(std::move(initial));\r\n        }\r\n\r\n        // Each item on the stack is a list of sibling units.\r\n        // Each iteration, we process the Current sibling from the group on top of the stack.\r\n        // If it is a group, we add its children as a new stack item to be processed next.\r\n        while (!stack.empty())\r\n        {\r\n            UnitSiblings& currentSiblings = stack.back();\r\n\r\n            if (currentSiblings.Current >= currentSiblings.Siblings.size())\r\n            {\r\n                stack.pop_back();\r\n                continue;\r\n            }\r\n\r\n            ConfigurationUnit& currentUnit = currentSiblings.Siblings[currentSiblings.Current++];\r\n\r\n            std::ostringstream unitStream;\r\n\r\n            if (currentSiblings.Depth)\r\n            {\r\n                unitStream << '|' << std::string((currentSiblings.Depth * 2) - 1, '-');\r\n            }\r\n\r\n            unitStream << Utility::ConvertToUTF8(currentUnit.Type());\r\n\r\n            auto identifier = currentUnit.Identifier();\r\n            if (!identifier.empty())\r\n            {\r\n                unitStream << \" [\" << Utility::ConvertControlCodesToPictures(Utility::ConvertToUTF8(identifier)) << ']';\r\n            }\r\n\r\n            auto resultInformation = currentUnit.ResultInformation();\r\n            std::ostringstream resultStream;\r\n            std::string resultDetails;\r\n\r\n            if (resultInformation)\r\n            {\r\n                resultStream << \"0x\" << Logging::SetHRFormat << resultInformation.ResultCode();\r\n\r\n                auto description = resultInformation.Description();\r\n                if (description.empty())\r\n                {\r\n                    description = resultInformation.Details();\r\n                }\r\n\r\n                resultDetails = Utility::ConvertControlCodesToPictures(Utility::ConvertToUTF8(description));\r\n            }\r\n\r\n            unitTable.OutputLine({ std::move(unitStream).str(), anon::ToLocString(currentUnit.State()), std::move(resultStream).str(), std::move(resultDetails) });\r\n\r\n            if (currentUnit.IsGroup())\r\n            {\r\n                UnitSiblings unitChildren;\r\n                unitChildren.Depth = currentSiblings.Depth + 1;\r\n                auto units = currentUnit.Units();\r\n                unitChildren.Siblings.resize(units.Size());\r\n                units.GetMany(0, unitChildren.Siblings);\r\n                stack.emplace_back(std::move(unitChildren));\r\n            }\r\n        }\r\n\r\n        unitTable.Complete();\r\n    }\r\n\r\n    void CompleteConfigurationHistoryItem(Execution::Context& context)\r\n    {\r\n        const std::string& word = context.Get<Data::CompletionData>().Word();\r\n        auto stream = context.Reporter.Completion();\r\n\r\n        for (const auto& historyItem : ConfigurationProcessor{ IConfigurationSetProcessorFactory{ nullptr } }.GetConfigurationHistory())\r\n        {\r\n            std::ostringstream identifierStream;\r\n            identifierStream << historyItem.InstanceIdentifier();\r\n            std::string identifier = identifierStream.str();\r\n\r\n            if (word.empty() || Utility::CaseInsensitiveContainsSubstring(identifier, word))\r\n            {\r\n                stream << '\"' << identifier << '\"' << std::endl;\r\n            }\r\n\r\n            std::string name = Utility::ConvertToUTF8(historyItem.Name());\r\n\r\n            if (word.empty() || Utility::CaseInsensitiveStartsWith(name, word))\r\n            {\r\n                stream << '\"' << name << '\"' << std::endl;\r\n            }\r\n        }\r\n    }\r\n\r\n    void MonitorConfigurationStatus(Execution::Context& context)\r\n    {\r\n        auto& configurationContext = context.Get<Data::ConfigurationContext>();\r\n\r\n        std::mutex activeSetMutex;\r\n        ConfigurationSet activeSet{ nullptr };\r\n        decltype(activeSet.ConfigurationSetChange(winrt::auto_revoke, nullptr)) activeSetRevoker;\r\n\r\n        auto setChangeHandler = [&](const ConfigurationSet& set, const ConfigurationSetChangeData& changeData)\r\n            {\r\n                if (changeData.Change() == ConfigurationSetChangeEventType::SetStateChanged)\r\n                {\r\n                    context.Reporter.Info() << \"(SetStateChanged) \" << set.InstanceIdentifier() << \" :: \" << anon::ToLocString(changeData.SetState()) << std::endl;\r\n                }\r\n                else if (changeData.Change() == ConfigurationSetChangeEventType::UnitStateChanged)\r\n                {\r\n                    context.Reporter.Info() << \"(UnitStateChanged) \" << changeData.Unit().InstanceIdentifier() << \" :: \" << anon::ToLocString(changeData.UnitState()) << std::endl;\r\n\r\n                    auto resultInformation = changeData.ResultInformation();\r\n                    if (resultInformation)\r\n                    {\r\n                        context.Reporter.Info() << \"    [\" << anon::ToString(resultInformation.ResultSource()) << \"] :: 0x\" << Logging::SetHRFormat << resultInformation.ResultCode() << std::endl;\r\n                    }\r\n                }\r\n            };\r\n\r\n        auto setActiveSet = [&](const ConfigurationSet& set, bool force)\r\n            {\r\n                std::lock_guard<std::mutex> lock{ activeSetMutex };\r\n\r\n                if (force || !activeSet)\r\n                {\r\n                    activeSet = set;\r\n                    activeSetRevoker = activeSet.ConfigurationSetChange(winrt::auto_revoke, setChangeHandler);\r\n                }\r\n            };\r\n\r\n        auto processorRevoker = configurationContext.Processor().ConfigurationChange(winrt::auto_revoke, [&](const ConfigurationSet& set, const ConfigurationChangeData& changeData)\r\n            {\r\n                context.Reporter.Info() << '[' << anon::ToString(changeData.Change()) << \"] \" << changeData.InstanceIdentifier() << \" :: \" << anon::ToLocString(changeData.State()) << std::endl;\r\n\r\n                if (changeData.Change() == ConfigurationChangeEventType::SetStateChanged && changeData.State() == ConfigurationSetState::InProgress)\r\n                {\r\n                    setActiveSet(set, true);\r\n                }\r\n            });\r\n\r\n        for (ConfigurationSet& historySet : configurationContext.History())\r\n        {\r\n            if (historySet.State() == ConfigurationSetState::InProgress)\r\n            {\r\n                setActiveSet(historySet, false);\r\n            }\r\n        }\r\n\r\n        for (;;)\r\n        {\r\n            std::this_thread::sleep_for(250ms);\r\n            if (context.IsTerminated())\r\n            {\r\n                return;\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/ConfigurationFlow.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ExecutionContext.h\"\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    // Creates a configuration processor with a processor factory for full functionality.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: ConfigurationProcessor\r\n    void CreateConfigurationProcessor(Execution::Context& context);\r\n\r\n    // Creates a configuration processor without a processor factory for reduced functionality.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: ConfigurationProcessor\r\n    void CreateConfigurationProcessorWithoutFactory(Execution::Context& context);\r\n\r\n    // Opens the configuration set.\r\n    // Required Args: ConfigurationFile\r\n    // Inputs: ConfigurationProcessor\r\n    // Outputs: ConfigurationSet\r\n    void OpenConfigurationSet(Execution::Context& context);\r\n\r\n    // Creates or opens the configuration set.\r\n    // Required Args: OutputFile\r\n    // Inputs: ConfigurationProcessor\r\n    // Outputs: ConfigurationSet\r\n    struct CreateOrOpenConfigurationSet : public WorkflowTask\r\n    {\r\n        CreateOrOpenConfigurationSet(std::string defaultSchemaVersion, bool createAlways = false) :\r\n            WorkflowTask(\"CreateOrOpenConfigurationSet\"), m_defaultSchemaVersion(std::move(defaultSchemaVersion)), m_createAlways(createAlways) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        std::string m_defaultSchemaVersion;\r\n        bool m_createAlways = false;\r\n    };\r\n\r\n    // Outputs the configuration set.\r\n    // Required Args: None\r\n    // Inputs: ConfigurationSet\r\n    // Outputs: None\r\n    void ShowConfigurationSet(Execution::Context& context);\r\n\r\n    // Outputs the configuration set.\r\n    // Required Args: None\r\n    // Inputs: ConfigurationProcessor, ConfigurationSet\r\n    // Outputs: None\r\n    void ShowConfigurationSetConflicts(Execution::Context& context);\r\n\r\n    // Handles confirming the configuration set processing should proceed.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: None\r\n    struct ConfirmConfigurationProcessing : public WorkflowTask\r\n    {\r\n        ConfirmConfigurationProcessing(bool isApply) : WorkflowTask(\"ConfirmConfigurationProcessing\"), m_isApply(isApply) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        bool m_isApply;\r\n    };\r\n\r\n    // Applies the configuration set, showing progress as it proceeds.\r\n    // Required Args: None\r\n    // Inputs: ConfigurationProcessor, ConfigurationSet\r\n    // Outputs: None\r\n    void ApplyConfigurationSet(Execution::Context& context);\r\n\r\n    // Tests the configuration set state, showing progress as it proceeds.\r\n    // Required Args: None\r\n    // Inputs: ConfigurationProcessor, ConfigurationSet\r\n    // Outputs: None\r\n    void TestConfigurationSet(Execution::Context& context);\r\n\r\n    // Validates the configuration set semantically.\r\n    // Required Args: None\r\n    // Inputs: ConfigurationProcessor, ConfigurationSet\r\n    // Outputs: None\r\n    void ValidateConfigurationSetSemantics(Execution::Context& context);\r\n\r\n    // Validates that the unit processors referenced by the set are valid/available/etc.\r\n    // Required Args: None\r\n    // Inputs: ConfigurationProcessor, ConfigurationSet\r\n    // Outputs: None\r\n    void ValidateConfigurationSetUnitProcessors(Execution::Context& context);\r\n\r\n    // Validates that specific unit contents referenced by the set are valid/available/etc.\r\n    // Required Args: None\r\n    // Inputs: ConfigurationProcessor, ConfigurationSet\r\n    // Outputs: None\r\n    void ValidateConfigurationSetUnitContents(Execution::Context& context);\r\n\r\n    // Outputs the final message stating that no issues were found.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: None\r\n    void ValidateAllGoodMessage(Execution::Context& context);\r\n\r\n    // Search source for package(s) to be exported in configuration file.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: PackageCollection\r\n    void SearchSourceForPackageExport(Execution::Context& context);\r\n\r\n    // Adds configuration unit(s) with the winget package and/or exports resource given to configuration set.\r\n    // Required Args: None\r\n    // Inputs: ConfigurationProcessor, ConfigurationSet\r\n    // Outputs: None\r\n    void PopulateConfigurationSetForExport(Execution::Context& context);\r\n\r\n    // Write the configuration file.\r\n    // Required Args: OutputFile\r\n    // Inputs: ConfigurationProcessor, ConfigurationSet\r\n    // Outputs: None\r\n    void WriteConfigFile(Execution::Context& context);\r\n\r\n    // Gets the configuration set history.\r\n    // Required Args: None\r\n    // Inputs: ConfigurationProcessor\r\n    // Outputs: ConfigurationSetHistory\r\n    void GetConfigurationSetHistory(Execution::Context& context);\r\n\r\n    // Outputs the configuration set history.\r\n    // Required Args: None\r\n    // Inputs: ConfigurationSetHistory\r\n    // Outputs: None\r\n    void ShowConfigurationSetHistory(Execution::Context& context);\r\n\r\n    // Selects a specific configuration set history item.\r\n    // Required Args: ConfigurationHistoryItem\r\n    // Inputs: ConfigurationSetHistory\r\n    // Outputs: ConfigurationSet\r\n    void SelectSetFromHistory(Execution::Context& context);\r\n\r\n    // Removes the configuration set from history.\r\n    // Required Args: None\r\n    // Inputs: ConfigurationSet\r\n    // Outputs: None\r\n    void RemoveConfigurationSetHistory(Execution::Context& context);\r\n\r\n    // Write the configuration set history item to a file.\r\n    // Required Args: OutputFile\r\n    // Inputs: ConfigurationSet\r\n    // Outputs: None\r\n    void SerializeConfigurationSetHistory(Execution::Context& context);\r\n\r\n    // Outputs a single configuration set (from history).\r\n    // Required Args: None\r\n    // Inputs: ConfigurationSet\r\n    // Outputs: None\r\n    void ShowSingleConfigurationSetHistory(Execution::Context& context);\r\n\r\n    // Completes the configuration history item.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: None\r\n    void CompleteConfigurationHistoryItem(Execution::Context& context);\r\n\r\n    // Monitors configuration status.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: None\r\n    void MonitorConfigurationStatus(Execution::Context& context);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/DependenciesFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n\r\n#include \"pch.h\"\r\n#include \"DependenciesFlow.h\"\r\n#include <winget/ManifestComparator.h>\r\n#include \"InstallFlow.h\"\r\n#include \"winget\\DependenciesGraph.h\"\r\n#include \"DependencyNodeProcessor.h\"\r\n#include \"ShellExecuteInstallerHandler.h\"\r\n\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Manifest;\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    namespace\r\n    {\r\n        // Contains all the information needed to install a dependency package.\r\n        struct DependencyPackageCandidate\r\n        {\r\n            DependencyPackageCandidate(\r\n                std::shared_ptr<Repository::IPackageVersion>&& packageVersion,\r\n                std::shared_ptr<Repository::IPackageVersion>&& installedPackageVersion,\r\n                Manifest::Manifest&& manifest,\r\n                Manifest::ManifestInstaller&& installer)\r\n                : PackageVersion(std::move(packageVersion)), InstalledPackageVersion(std::move(installedPackageVersion)), Manifest(std::move(manifest)), Installer(std::move(installer)) { }\r\n\r\n            std::shared_ptr<Repository::IPackageVersion> PackageVersion;\r\n            std::shared_ptr<Repository::IPackageVersion> InstalledPackageVersion;\r\n            Manifest::Manifest Manifest;\r\n            Manifest::ManifestInstaller Installer;\r\n        };\r\n    }\r\n\r\n    void ReportDependencies::operator()(Execution::Context& context) const\r\n    {\r\n        auto info = context.Reporter.Info();\r\n\r\n        const auto& dependencies = context.Get<Execution::Data::Dependencies>();\r\n        if (dependencies.HasAny())\r\n        {\r\n            info << m_messageId << std::endl;\r\n\r\n            if (dependencies.HasAnyOf(DependencyType::WindowsFeature))\r\n            {\r\n                info << \"  - \" << Resource::String::WindowsFeaturesDependencies << std::endl;\r\n                dependencies.ApplyToType(DependencyType::WindowsFeature, [&info](Dependency dependency) {info << \"      \" << dependency.Id() << std::endl; });\r\n            }\r\n\r\n            if (dependencies.HasAnyOf(DependencyType::WindowsLibrary))\r\n            {\r\n                info << \"  - \" << Resource::String::WindowsLibrariesDependencies << std::endl;\r\n                dependencies.ApplyToType(DependencyType::WindowsLibrary, [&info](Dependency dependency) {info << \"      \" << dependency.Id() << std::endl; });\r\n            }\r\n\r\n            if (dependencies.HasAnyOf(DependencyType::Package))\r\n            {\r\n                info << \"  - \" << Resource::String::PackageDependencies << std::endl;\r\n                dependencies.ApplyToType(DependencyType::Package, [&info](Dependency dependency)\r\n                    {\r\n                        info << \"      \" << dependency.Id();\r\n                        if (dependency.MinVersion)\r\n                        {\r\n                            info << \" [>= \" << dependency.MinVersion.value().ToString() << \"]\";\r\n                        }\r\n                        info << std::endl;\r\n                    });\r\n            }\r\n\r\n            if (dependencies.HasAnyOf(DependencyType::External))\r\n            {\r\n                context.Reporter.Warn() << \"  - \" << Resource::String::ExternalDependencies << std::endl;\r\n                dependencies.ApplyToType(DependencyType::External, [&info](Dependency dependency) {info << \"      \" << dependency.Id() << std::endl; });\r\n            }\r\n        }\r\n    }\r\n\r\n    void GetInstallersDependenciesFromManifest(Execution::Context& context)\r\n    {\r\n        const auto& manifest = context.Get<Execution::Data::Manifest>();\r\n        DependencyList allDependencies;\r\n\r\n        for (const auto& installer : manifest.Installers)\r\n        {\r\n            allDependencies.Add(installer.Dependencies);\r\n        }\r\n\r\n        context.Add<Execution::Data::Dependencies>(std::move(allDependencies));\r\n    }\r\n\r\n    void GetDependenciesFromInstaller(Execution::Context& context)\r\n    {\r\n        const auto& installer = context.Get<Execution::Data::Installer>();\r\n        if (installer)\r\n        {\r\n            context.Add<Execution::Data::Dependencies>(installer->Dependencies);\r\n        }\r\n    }\r\n\r\n    void GetDependenciesInfoForUninstall(Execution::Context& context)\r\n    {\r\n        // TODO make best effort to get the correct installer information, it may be better to have a record of installations and save the correct installers\r\n        context.Add<Execution::Data::Dependencies>(DependencyList()); // sending empty list of dependencies for now\r\n    }\r\n\r\n    void OpenDependencySource(Execution::Context& context)\r\n    {\r\n        if (context.Contains(Execution::Data::PackageVersion))\r\n        {\r\n            const auto& packageVersion = context.Get<Execution::Data::PackageVersion>();\r\n            context.Add<Execution::Data::DependencySource>(packageVersion->GetSource());\r\n        }\r\n        else\r\n        {\r\n            // install from manifest requires --dependency-source to be set\r\n            context <<\r\n                Workflow::OpenSource(true);\r\n        }\r\n\r\n        if (WI_IsFlagClear(context.GetFlags(), Execution::ContextFlag::InstallerDownloadOnly))\r\n        {\r\n            // Installed source is not needed when only downloading the installer.\r\n            context <<\r\n                Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed, true, Repository::CompositeSearchBehavior::AvailablePackages);\r\n        }\r\n    }\r\n\r\n    void EnableWindowsFeaturesDependencies(Execution::Context& context)\r\n    {\r\n        const auto& rootDependencies = context.Get<Execution::Data::Installer>()->Dependencies;\r\n\r\n        if (rootDependencies.Empty() || !rootDependencies.HasAnyOf(DependencyType::WindowsFeature))\r\n        {\r\n            return;\r\n        }\r\n\r\n        context << Workflow::EnsureRunningAsAdmin;\r\n\r\n        if (context.IsTerminated())\r\n        {\r\n            return;\r\n        }\r\n\r\n        bool isCancelled = false;\r\n        bool enableFeaturesFailed = false;\r\n        bool rebootRequired = false;\r\n        bool force = context.Args.Contains(Execution::Args::Type::Force);\r\n\r\n        rootDependencies.ApplyToType(DependencyType::WindowsFeature, [&context, &isCancelled, &enableFeaturesFailed, &force, &rebootRequired](Dependency dependency)\r\n            {\r\n                if (enableFeaturesFailed && !force || isCancelled)\r\n                {\r\n                    return;\r\n                }\r\n\r\n                auto featureName = dependency.Id();\r\n\r\n                auto featureContextPtr = context.CreateSubContext();\r\n                Execution::Context& featureContext = *featureContextPtr;\r\n                auto previousThreadGlobals = featureContext.SetForCurrentThread();\r\n\r\n                featureContext << Workflow::ShellExecuteEnableWindowsFeature(featureName);\r\n\r\n                if (featureContext.IsTerminated())\r\n                {\r\n                    isCancelled = true;\r\n                    return;\r\n                }\r\n\r\n                Utility::LocIndView locIndFeatureName{ featureName };\r\n                DWORD result = featureContext.Get<Execution::Data::OperationReturnCode>();\r\n\r\n                if (result == ERROR_SUCCESS)\r\n                {\r\n                    AICLI_LOG(Core, Info, << \"Successfully enabled [\" << featureName << \"]\");\r\n                }\r\n                else if (result == 0x800f080c) // DISMAPI_E_UNKNOWN_FEATURE\r\n                {\r\n                    AICLI_LOG(Core, Warning, << \"Windows Feature [\" << featureName << \"] does not exist\");\r\n                    enableFeaturesFailed = true;\r\n                    featureContext.Reporter.Warn() << Resource::String::WindowsFeatureNotFound(locIndFeatureName) << std::endl;\r\n                }\r\n                else if (result == ERROR_SUCCESS_REBOOT_REQUIRED)\r\n                {\r\n                    AICLI_LOG(Core, Info, << \"Reboot required for [\" << featureName << \"]\");\r\n                    rebootRequired = true;\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(Core, Error, << \"Failed to enable Windows Feature [\" << featureName << \"] with exit code: \" << result);\r\n                    enableFeaturesFailed = true;\r\n                    featureContext.Reporter.Warn() << Resource::String::FailedToEnableWindowsFeature(locIndFeatureName, result) << std::endl;\r\n                }\r\n            });\r\n\r\n        if (isCancelled)\r\n        {\r\n            context.Reporter.Warn() << Resource::String::InstallAbandoned << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(E_ABORT);\r\n        }\r\n\r\n        if (enableFeaturesFailed)\r\n        {\r\n            if (force)\r\n            {\r\n                context.Reporter.Warn() << Resource::String::FailedToEnableWindowsFeatureOverridden << std::endl;\r\n            }\r\n            else\r\n            {\r\n                context.Reporter.Error() << Resource::String::FailedToEnableWindowsFeatureOverrideRequired << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_INSTALL_DEPENDENCIES);\r\n            }\r\n        }\r\n        else\r\n        {\r\n            if (rebootRequired)\r\n            {\r\n                if (force)\r\n                {\r\n                    context.Reporter.Warn() << Resource::String::RebootRequiredToEnableWindowsFeatureOverridden << std::endl;\r\n                }\r\n                else\r\n                {\r\n                    context.Reporter.Error() << Resource::String::RebootRequiredToEnableWindowsFeatureOverrideRequired << std::endl;\r\n                    context.SetFlags(Execution::ContextFlag::RegisterResume);\r\n                    context.SetFlags(Execution::ContextFlag::RebootRequired);\r\n                    AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_FOR_INSTALL);\r\n                }\r\n            }\r\n            else\r\n            {\r\n                context.Reporter.Info() << Resource::String::EnableWindowsFeaturesSuccess << std::endl;\r\n            }\r\n        }\r\n    }\r\n\r\n    void CreateDependencySubContexts::operator()(Execution::Context& context) const\r\n    {\r\n        if (Settings::User().Get<Settings::Setting::InstallSkipDependencies>() || context.Args.Contains(Execution::Args::Type::SkipDependencies))\r\n        {\r\n            return;\r\n        }\r\n\r\n        auto info = context.Reporter.Info();\r\n        auto error = context.Reporter.Error();\r\n        const auto& rootManifest = context.Get<Execution::Data::Manifest>();\r\n\r\n        Dependency rootAsDependency = Dependency(DependencyType::Package, rootManifest.Id, rootManifest.Version);\r\n\r\n        const auto& rootInstaller = context.Get<Execution::Data::Installer>();\r\n        const auto& rootDependencies = rootInstaller->Dependencies;\r\n\r\n        if (rootDependencies.Empty())\r\n        {\r\n            // If there's no dependencies there's nothing to do aside of logging the outcome\r\n            return;\r\n        }\r\n\r\n        context << OpenDependencySource;\r\n        if (context.IsTerminated())\r\n        {\r\n            info << Resource::String::DependenciesFlowSourceNotFound << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_INTERNAL_ERROR); \r\n        }\r\n\r\n        std::map<string_t, DependencyPackageCandidate> idToPackageMap;\r\n        bool foundError = false;\r\n        DependencyGraph dependencyGraph(rootAsDependency, rootDependencies, \r\n            [&](Dependency node)\r\n            {\r\n                DependencyNodeProcessor nodeProcessor(context);\r\n\r\n                auto result = nodeProcessor.EvaluateDependencies(node);\r\n                DependencyList list = nodeProcessor.GetDependencyList();\r\n                foundError = foundError || (result == DependencyNodeProcessorResult::Error);\r\n\r\n                if (result == DependencyNodeProcessorResult::Success)\r\n                {\r\n                    DependencyPackageCandidate dependencyPackageCandidate{\r\n                        std::move(nodeProcessor.GetPackageLatestVersion()),\r\n                        std::move(nodeProcessor.GetPackageInstalledVersion()),\r\n                        std::move(nodeProcessor.GetManifest()),\r\n                        std::move(nodeProcessor.GetPreferredInstaller()) };\r\n\r\n                    idToPackageMap.emplace(node.Id(), std::move(dependencyPackageCandidate));\r\n                };\r\n\r\n                return list;\r\n            });\r\n\r\n        dependencyGraph.BuildGraph();\r\n\r\n        if (foundError)\r\n        {\r\n            error << Resource::String::DependenciesManagementExitMessage << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_INSTALL_MISSING_DEPENDENCY);\r\n        }\r\n\r\n        if (dependencyGraph.HasLoop())\r\n        {\r\n            context.Reporter.Warn() << Resource::String::DependenciesFlowContainsLoop;\r\n        }\r\n\r\n        const auto& installationOrder = dependencyGraph.GetInstallationOrder();\r\n\r\n        std::vector<std::unique_ptr<Execution::Context>> dependencyPackageContexts;\r\n\r\n        for (auto const& node : installationOrder)\r\n        {\r\n            auto itr = idToPackageMap.find(node.Id());\r\n            // if the package was already installed (with a useful version) or is the root\r\n            // then there will be no installer for it on the map.\r\n            if (itr != idToPackageMap.end())\r\n            {\r\n                auto dependencyContextPtr = context.CreateSubContext();\r\n                Execution::Context& dependencyContext = *dependencyContextPtr;\r\n                auto previousThreadGlobals = dependencyContext.SetForCurrentThread();\r\n\r\n                Logging::Telemetry().LogSelectedInstaller(\r\n                    static_cast<int>(itr->second.Installer.Arch),\r\n                    itr->second.Installer.Url,\r\n                    Manifest::InstallerTypeToString(itr->second.Installer.EffectiveInstallerType()),\r\n                    Manifest::ScopeToString(itr->second.Installer.Scope),\r\n                    itr->second.Installer.Locale);\r\n\r\n                Logging::Telemetry().LogManifestFields(\r\n                    itr->second.Manifest.Id,\r\n                    itr->second.Manifest.DefaultLocalization.Get<Manifest::Localization::PackageName>(),\r\n                    itr->second.Manifest.Version);\r\n\r\n                // Extract the data needed for installing\r\n                dependencyContext.Add<Execution::Data::PackageVersion>(itr->second.PackageVersion);\r\n                dependencyContext.Add<Execution::Data::Manifest>(itr->second.Manifest);\r\n                dependencyContext.Add<Execution::Data::InstalledPackageVersion>(itr->second.InstalledPackageVersion);\r\n                dependencyContext.Add<Execution::Data::Installer>(itr->second.Installer);\r\n\r\n                if (WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::InstallerDownloadOnly))\r\n                {\r\n                    dependencyContext.Add<Execution::Data::DownloadDirectory>(context.Get<Execution::Data::DownloadDirectory>() / L\"Dependencies\");\r\n                }\r\n\r\n                dependencyPackageContexts.emplace_back(std::move(dependencyContextPtr));\r\n            }\r\n        }\r\n\r\n        context.Add<Execution::Data::PackageSubContexts>(std::move(dependencyPackageContexts));\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/DependenciesFlow.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ExecutionContext.h\"\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    // Shows information about dependencies.\r\n    // Required Args: message to use at the beginning, before outputting dependencies\r\n    // Inputs: Dependencies\r\n    // Outputs: None\r\n    struct ReportDependencies : public WorkflowTask\r\n    {\r\n        ReportDependencies(AppInstaller::StringResource::StringId messageId) :\r\n            WorkflowTask(\"ReportDependencies\"), m_messageId(messageId) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        AppInstaller::StringResource::StringId m_messageId;\r\n    };\r\n\r\n    // Gathers all installers dependencies from manifest.\r\n    // Required Args: None\r\n    // Inputs: Manifest\r\n    // Outputs: Dependencies\r\n    void GetInstallersDependenciesFromManifest(Execution::Context& context);\r\n\r\n    // Gathers package dependencies information from installer.\r\n    // Required Args: None\r\n    // Inputs: Installer\r\n    // Outputs: Dependencies\r\n    void GetDependenciesFromInstaller(Execution::Context& context);\r\n\r\n    // TODO: \r\n    // Gathers dependencies information for the uninstall command.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: Dependencies\r\n    void GetDependenciesInfoForUninstall(Execution::Context& context);\r\n\r\n    // Builds the dependency graph and creates the sub contexts for each package dependency.\r\n    // Required Args: None\r\n    // Inputs: Manifest, Installer and DependencySource\r\n    // Outputs: Dependencies\r\n    struct CreateDependencySubContexts : public WorkflowTask\r\n    {\r\n        CreateDependencySubContexts(\r\n            AppInstaller::StringResource::StringId dependencyReportMessage) :\r\n            WorkflowTask(\"CreateDependencySubContexts\"),\r\n            m_dependencyReportMessage(dependencyReportMessage) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n        private:\r\n            AppInstaller::StringResource::StringId m_dependencyReportMessage;\r\n    };\r\n\r\n    // Sets up the source used to get the dependencies.\r\n    // Required Args: None\r\n    // Inputs: PackageVersion, Manifest\r\n    // Outputs: DependencySource\r\n    void OpenDependencySource(Execution::Context& context);\r\n\r\n    // Enables the Windows Feature dependencies.\r\n    // Required Args: None\r\n    // Inputs: Manifest, Installer\r\n    // Outputs: None\r\n    void EnableWindowsFeaturesDependencies(Execution::Context& context);\r\n}"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/DependencyNodeProcessor.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"DependencyNodeProcessor.h\"\n#include \"WorkflowBase.h\"\n#include <winget/PinningData.h>\n#include <winget/PackageVersionSelection.h>\n\nusing namespace AppInstaller::Manifest;\nusing namespace AppInstaller::Repository;\n\nnamespace AppInstaller::CLI::Workflow\n{\n    DependencyNodeProcessor::DependencyNodeProcessor(Execution::Context& context)\n        : m_context(context) {}\n\n    DependencyNodeProcessorResult DependencyNodeProcessor::EvaluateDependencies(Dependency& dependencyNode)\n    {\n        SearchRequest searchRequest;\n        const auto& source = m_context.Get<Execution::Data::DependencySource>();\n        auto error = m_context.Reporter.Error();\n        auto info = m_context.Reporter.Info();\n\n        searchRequest.Filters.emplace_back(PackageMatchFilter(PackageMatchField::Id, MatchType::CaseInsensitive, dependencyNode.Id()));\n\n        const auto& matches = source.Search(searchRequest).Matches;\n\n        if (matches.empty())\n        {\n            error << Resource::String::DependenciesFlowNoMatches << std::endl;\n            return DependencyNodeProcessorResult::Error;\n        }\n\n        if (matches.size() > 1)\n        {\n            auto dependencyNodeId = Utility::LocIndString{ Utility::Normalize(dependencyNode.Id()) };\n            error << Resource::String::DependenciesFlowSourceTooManyMatches(dependencyNodeId) << std::endl;\n            AICLI_LOG(CLI, Error, << \"Too many matches for package \" << dependencyNode.Id());\n            return DependencyNodeProcessorResult::Error;\n        }\n\n        const auto& match = matches.at(0);\n        const auto& package = match.Package;\n        auto packageId = package->GetProperty(PackageProperty::Id);\n        m_nodePackageInstalledVersion = GetInstalledVersion(package);\n        std::shared_ptr<IPackageVersionCollection> availableVersions = GetAvailableVersionsForInstalledVersion(package);\n\n        if (m_context.Args.Contains(Execution::Args::Type::Force))\n        {\n            m_nodePackageLatestVersion = availableVersions->GetLatestVersion();\n        }\n        else\n        {\n            Pinning::PinBehavior pinBehavior = m_context.Args.Contains(Execution::Args::Type::IncludePinned) ? Pinning::PinBehavior::IncludePinned : Pinning::PinBehavior::ConsiderPins;\n\n            Pinning::PinningData pinningData{ Pinning::PinningData::Disposition::ReadOnly };\n            auto evaluator = pinningData.CreatePinStateEvaluator(pinBehavior, m_nodePackageInstalledVersion);\n\n            m_nodePackageLatestVersion = evaluator.GetLatestAvailableVersionForPins(availableVersions);\n        }\n\n        if (m_nodePackageInstalledVersion && dependencyNode.IsVersionOk(Utility::Version(m_nodePackageInstalledVersion->GetProperty(PackageVersionProperty::Version))))\n        {\n            // return empty dependency list,\n            // as we won't keep searching for dependencies for installed packages\n            return DependencyNodeProcessorResult::Skipped;\n        }\n\n        if (!m_nodePackageLatestVersion)\n        {\n            error << Resource::String::DependenciesFlowPackageVersionNotFound(Utility::LocIndView{ Utility::Normalize(packageId) }) << std::endl;\n            AICLI_LOG(CLI, Error, << \"Latest available version not found for package \" << packageId);\n            return DependencyNodeProcessorResult::Error;\n        }\n\n        if (!dependencyNode.IsVersionOk(Utility::Version(m_nodePackageLatestVersion->GetProperty(PackageVersionProperty::Version))))\n        {\n            error << Resource::String::DependenciesFlowNoMinVersion(Utility::LocIndView{ Utility::Normalize(packageId) }) << std::endl;\n            AICLI_LOG(CLI, Error, << \"No suitable min version found for package \" << packageId);\n            return DependencyNodeProcessorResult::Error;\n        }\n\n        m_nodeManifest = m_nodePackageLatestVersion->GetManifest();\n        m_nodeManifest.ApplyLocale();\n\n        if (m_nodeManifest.Installers.empty())\n        {\n            error << Resource::String::DependenciesFlowNoInstallerFound(Utility::LocIndView{ Utility::Normalize(m_nodeManifest.Id) }) << std::endl;\n            AICLI_LOG(CLI, Error, << \"Installer not found for manifest \" << m_nodeManifest.Id << \" with version\" << m_nodeManifest.Version);\n            return DependencyNodeProcessorResult::Error;\n        }\n\n        IPackageVersion::Metadata installationMetadata;\n        if (m_nodePackageInstalledVersion)\n        {\n            installationMetadata = m_nodePackageInstalledVersion->GetMetadata();\n        }\n\n        ManifestComparator manifestComparator(GetManifestComparatorOptions(m_context, installationMetadata));\n        auto [installer, inapplicabilities] = manifestComparator.GetPreferredInstaller(m_nodeManifest);\n\n        if (!installer.has_value())\n        {\n            auto manifestId = Utility::LocIndString{ Utility::Normalize(m_nodeManifest.Id) };\n            auto manifestVersion = Utility::LocIndString{ m_nodeManifest.Version };\n            error << Resource::String::DependenciesFlowNoSuitableInstallerFound(manifestId, manifestVersion) << std::endl;\n            AICLI_LOG(CLI, Error, << \"No suitable installer found for manifest \" << m_nodeManifest.Id << \" with version \" << m_nodeManifest.Version);\n            return DependencyNodeProcessorResult::Error;\n        }\n\n        m_installer = installer.value();\n        m_dependenciesList = m_installer.Dependencies;\n        return DependencyNodeProcessorResult::Success;\n    }\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/DependencyNodeProcessor.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include <winget/RepositorySearch.h>\n#include \"ExecutionContext.h\"\n#include <winget/ManifestCommon.h>\n\nusing namespace AppInstaller::Manifest;\nusing namespace AppInstaller::Repository;\n\nnamespace AppInstaller::CLI::Workflow \n{\n    enum DependencyNodeProcessorResult\n    {\n        Error,\n        Success,\n        Skipped,\n    };\n\n    struct DependencyNodeProcessor\n    {\n        DependencyNodeProcessor(Execution::Context& context);\n\n        DependencyNodeProcessorResult EvaluateDependencies(Dependency& dependencyNode);\n\n        DependencyList GetDependencyList() { return m_dependenciesList; }\n\n        std::shared_ptr<IPackageVersion>  GetPackageLatestVersion() { return m_nodePackageLatestVersion; }\n\n        std::shared_ptr<IPackageVersion> GetPackageInstalledVersion() { return m_nodePackageInstalledVersion; }\n\n        Manifest::Manifest GetManifest() { return m_nodeManifest;  }\n\n        Manifest::ManifestInstaller GetPreferredInstaller() { return m_installer; }\n\n    private:\n        Execution::Context& m_context;\n        DependencyList m_dependenciesList;\n        std::shared_ptr<IPackageVersion> m_nodePackageLatestVersion;\n        std::shared_ptr<IPackageVersion> m_nodePackageInstalledVersion;\n        Manifest::ManifestInstaller m_installer;\n        Manifest::Manifest m_nodeManifest;\n    };\n}"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/DownloadFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"DownloadFlow.h\"\r\n#include \"MSStoreInstallerHandler.h\"\r\n#include <winget/Filesystem.h>\r\n#include <AppInstallerDeployment.h>\r\n#include <AppInstallerDownloader.h>\r\n#include <AppInstallerRuntime.h>\r\n#include <AppInstallerMsixInfo.h>\r\n#include <winget/AdminSettings.h>\r\n#include <winget/GroupPolicy.h>\r\n#include <winget/ManifestYamlWriter.h>\r\n#include <winget/NetworkSettings.h>\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    using namespace AppInstaller::Manifest;\r\n    using namespace AppInstaller::Repository;\r\n    using namespace AppInstaller::Utility;\r\n    using namespace AppInstaller::Settings;\r\n    using namespace std::string_view_literals;\r\n\r\n    namespace\r\n    {\r\n        constexpr std::string_view s_MicrosoftEntraIdAuthorizationHeader = \"Authorization\"sv;\r\n        // By default Azure blob storage does not accept Microsoft Entra Id authentication.\r\n        // https://learn.microsoft.com/en-us/rest/api/storageservices/versioning-for-the-azure-storage-services#authorize-requests-by-using-microsoft-entra-id-shared-key-or-shared-key-lite\r\n        constexpr std::string_view s_AzureBlobStorageApiVersionHeader = \"x-ms-version\"sv;\r\n        constexpr std::string_view s_AzureBlobStorageApiVersionValue = \"2020-04-08\"sv;\r\n\r\n        // Get the base download directory path for the installer.\r\n        // Also creates the directory as necessary.\r\n        std::filesystem::path GetInstallerBaseDownloadPath(Execution::Context& context)\r\n        {\r\n            const auto& manifest = context.Get<Execution::Data::Manifest>();\r\n\r\n            std::filesystem::path tempInstallerPath = Runtime::GetPathTo(Runtime::PathName::Temp);\r\n            tempInstallerPath /= Utility::ConvertToUTF16(manifest.Id + '.' + manifest.Version);\r\n\r\n            std::filesystem::create_directories(tempInstallerPath);\r\n\r\n            return tempInstallerPath;\r\n        }\r\n\r\n        // Get the file extension to be used for the installer file.\r\n        std::wstring_view GetInstallerFileExtension(Execution::Context& context)\r\n        {\r\n            const auto& installer = context.Get<Execution::Data::Installer>();\r\n            switch (installer->BaseInstallerType)\r\n            {\r\n            case InstallerTypeEnum::Burn:\r\n            case InstallerTypeEnum::Exe:\r\n            case InstallerTypeEnum::Inno:\r\n            case InstallerTypeEnum::Nullsoft:\r\n            case InstallerTypeEnum::Portable:\r\n                return L\".exe\"sv;\r\n            case InstallerTypeEnum::Msi:\r\n            case InstallerTypeEnum::Wix:\r\n                return L\".msi\"sv;\r\n            case InstallerTypeEnum::Msix:\r\n                // Note: We may need to distinguish between .msix and .msixbundle in the future.\r\n                return L\".msix\"sv;\r\n            case InstallerTypeEnum::Zip:\r\n                return L\".zip\"sv;\r\n            case InstallerTypeEnum::Font:\r\n                {\r\n                    const auto& fileName = GetFileNameFromURI(installer->Url);\r\n                    if (fileName.has_extension())\r\n                    {\r\n                        return fileName.extension().c_str();\r\n                    }\r\n                    else\r\n                    {\r\n                        THROW_HR(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED));\r\n                    }\r\n                }\r\n            default:\r\n                THROW_HR(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED));\r\n            }\r\n        }\r\n\r\n        // Gets a file name that should not be able to ShellExecute.\r\n        std::filesystem::path GetInstallerPreHashValidationFileName(Execution::Context& context)\r\n        {\r\n            return { SHA256::ConvertToString(context.Get<Execution::Data::Installer>()->Sha256) };\r\n        }\r\n\r\n        // Gets the file name that can be used to ShellExecute the file.\r\n        std::filesystem::path GetInstallerPostHashValidationFileName(Execution::Context& context)\r\n        {\r\n            // Get file name from download URI\r\n            std::filesystem::path filename = GetFileNameFromURI(context.Get<Execution::Data::Installer>()->Url);\r\n            std::wstring_view installerExtension = GetInstallerFileExtension(context);\r\n\r\n            // Assuming that we find a safe stem value in the URI, use it.\r\n            // This should be extremely common, but just in case fall back to the older name style.\r\n            if (filename.has_stem() && ((filename.wstring().size() + installerExtension.size()) < MAX_PATH))\r\n            {\r\n                filename = filename.stem();\r\n            }\r\n            else\r\n            {\r\n                const auto& manifest = context.Get<Execution::Data::Manifest>();\r\n                filename = Utility::ConvertToUTF16(manifest.Id + '.' + manifest.Version);\r\n            }\r\n\r\n            filename += installerExtension;\r\n\r\n            // Make file name suitable for file system path\r\n            filename = Utility::ConvertToUTF16(Utility::MakeSuitablePathPart(filename.u8string()));\r\n\r\n            return filename;\r\n        }\r\n\r\n        // Gets the file name for the downloaded installer in the format of {id}_{version}_{architecture}_{scope}_{installerType}_{locale}.\r\n        std::filesystem::path GetInstallerDownloadOnlyFileName(Execution::Context& context, const std::wstring_view& extension = {})\r\n        {\r\n            const auto& manifest = context.Get<Execution::Data::Manifest>();\r\n            const auto& installer = context.Get<Execution::Data::Installer>().value();\r\n\r\n            std::string packageName = manifest.CurrentLocalization.Get<Localization::PackageName>();\r\n            std::string architecture{ ToString(installer.Arch) };\r\n            std::string installerType{ InstallerTypeToString(installer.EffectiveInstallerType()) };\r\n\r\n            std::string fileName = packageName;\r\n\r\n            if (!Version(manifest.Version).IsUnknown())\r\n            {\r\n                fileName += '_' + manifest.Version;\r\n            }\r\n\r\n            if (installer.Scope != ScopeEnum::Unknown)\r\n            {\r\n                fileName += '_' + std::string{ ScopeToString(installer.Scope) };\r\n            }\r\n\r\n            fileName += '_' + architecture + '_' + installerType;\r\n\r\n            std::string locale = !installer.Locale.empty() ? installer.Locale : manifest.CurrentLocalization.Locale;\r\n            if (!locale.empty())\r\n            {\r\n                fileName += '_' + locale;\r\n            }\r\n\r\n            std::filesystem::path fileNamePath = Utility::ConvertToUTF16(fileName);\r\n\r\n            if (!extension.empty())\r\n            {\r\n                fileNamePath += extension;\r\n            }\r\n            else\r\n            {\r\n                fileNamePath += GetInstallerFileExtension(context);\r\n            }\r\n\r\n            // Make file name suitable for file system path\r\n            fileNamePath = Utility::ConvertToUTF16(Utility::MakeSuitablePathPart(fileNamePath.u8string()));\r\n            return fileNamePath;\r\n        }\r\n\r\n        // Try to remove the installer file, ignoring any errors.\r\n        void RemoveInstallerFile(const std::filesystem::path& path)\r\n        {\r\n            try\r\n            {\r\n                std::filesystem::remove(path);\r\n\r\n                // It is assumed that the parent of the installer path will always be a directory\r\n                // If it isn't, then something went severely wrong. However, we will check that\r\n                // it is a directory here just to be safe. If it is an empty directory, remove it.\r\n\r\n                if (std::filesystem::is_directory(path.parent_path()) &&\r\n                    std::filesystem::is_empty(path.parent_path()))\r\n                {\r\n                    std::filesystem::remove(path.parent_path());\r\n                }\r\n            }\r\n            catch (const std::exception& e)\r\n            {\r\n                AICLI_LOG(CLI, Warning, << \"Failed to remove installer file. Reason: \" << e.what());\r\n            }\r\n            catch (...)\r\n            {\r\n                AICLI_LOG(CLI, Warning, << \"Failed to remove installer file. Reason unknown.\");\r\n            }\r\n\r\n        }\r\n\r\n        // Checks the file hash for an existing installer file.\r\n        // Returns true if the file exists and its hash matches, false otherwise.\r\n        // If the hash does not match, deletes the file.\r\n        bool ExistingInstallerFileHasHashMatch(const SHA256::HashBuffer& expectedHash, const std::filesystem::path& filePath, SHA256::HashDetails& fileHashDetails)\r\n        {\r\n            if (std::filesystem::exists(filePath))\r\n            {\r\n                AICLI_LOG(CLI, Info, << \"Found existing installer file at '\" << filePath << \"'. Verifying file hash.\");\r\n                std::ifstream inStream{ filePath, std::ifstream::binary };\r\n                fileHashDetails = SHA256::ComputeHashDetails(inStream);\r\n\r\n                if (SHA256::AreEqual(expectedHash, fileHashDetails.Hash))\r\n                {\r\n                    return true;\r\n                }\r\n\r\n                AICLI_LOG(CLI, Info, << \"Hash does not match. Removing existing installer file \" << filePath);\r\n                RemoveInstallerFile(filePath);\r\n            }\r\n\r\n            return false;\r\n        }\r\n\r\n        std::string GetInstallerDownloadAuthenticationToken(const AppInstaller::Authentication::AuthenticationInfo& authInfo, Execution::Context& context)\r\n        {\r\n            // First check if authenticator is already created\r\n            auto& authenticatorsMap = context.Get<AppInstaller::CLI::Execution::Data::InstallerDownloadAuthenticators>();\r\n            auto authenticatorItr = authenticatorsMap->find(authInfo);\r\n            if (authenticatorItr == authenticatorsMap->end())\r\n            {\r\n                AppInstaller::Authentication::Authenticator authenticator{ authInfo, GetAuthenticationArguments(context) };\r\n                authenticatorsMap->emplace(authInfo, std::move(authenticator));\r\n            }\r\n\r\n            // Get the authenticator for auth.\r\n            authenticatorItr = authenticatorsMap->find(authInfo);\r\n            THROW_HR_IF(E_UNEXPECTED, authenticatorItr == authenticatorsMap->end());\r\n\r\n            auto authResult = authenticatorItr->second.AuthenticateForToken();\r\n            if (FAILED(authResult.Status))\r\n            {\r\n                AICLI_LOG(Repo, Error, << \"Authentication failed for installer download. Result: \" << authResult.Status);\r\n                THROW_HR_MSG(authResult.Status, \"Failed to authenticate for installer download.\");\r\n            }\r\n\r\n            return authResult.Token;\r\n        }\r\n\r\n        // Get additional headers for installer download request. Auth headers are acquired here.\r\n        std::vector<DownloadRequestHeader> GetInstallerDownloadAuthenticationHeaders(const AppInstaller::Manifest::ManifestInstaller& installer, Execution::Context& context)\r\n        {\r\n            std::vector<DownloadRequestHeader> result;\r\n\r\n            switch (installer.AuthInfo.Type)\r\n            {\r\n            case AppInstaller::Authentication::AuthenticationType::None:\r\n                // No auth needed\r\n                break;\r\n            case AppInstaller::Authentication::AuthenticationType::MicrosoftEntraId:\r\n            case AppInstaller::Authentication::AuthenticationType::MicrosoftEntraIdForAzureBlobStorage:\r\n                context.Reporter.Info() << Execution::AuthenticationEmphasis << Resource::String::InstallerDownloadRequiresAuthentication << std::endl;\r\n                result.push_back({ std::string{ s_MicrosoftEntraIdAuthorizationHeader }, Authentication::CreateBearerToken(GetInstallerDownloadAuthenticationToken(installer.AuthInfo, context)), true });\r\n                if (installer.AuthInfo.Type == AppInstaller::Authentication::AuthenticationType::MicrosoftEntraIdForAzureBlobStorage)\r\n                {\r\n                    result.push_back({ std::string{ s_AzureBlobStorageApiVersionHeader }, std::string{ s_AzureBlobStorageApiVersionValue }, false });\r\n                }\r\n                break;\r\n            case AppInstaller::Authentication::AuthenticationType::Unknown:\r\n            default:\r\n                THROW_HR_MSG(APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED, \"The package installer requires authentication that is not supported.\");\r\n            }\r\n\r\n            // Log result before return\r\n            std::string logMessage = \"Installer download headers: \";\r\n            for (const auto& header : result)\r\n            {\r\n                logMessage += header.Name + \": \" + (header.IsAuth ? \"<Secret>\" : header.Value) + \"; \";\r\n            }\r\n            AICLI_LOG(CLI, Info, << logMessage);\r\n\r\n            return result;\r\n        }\r\n    }\r\n\r\n    void DownloadInstaller(Execution::Context& context)\r\n    {\r\n        // Check if file was already downloaded.\r\n        // This may happen after a failed installation or if the download was done\r\n        // separately before, e.g. on COM scenarios.\r\n        context <<\r\n            ReportExecutionStage(ExecutionStage::Download) <<\r\n            CheckForExistingInstaller;\r\n\r\n        if (context.IsTerminated())\r\n        {\r\n            return;\r\n        }\r\n\r\n        bool installerDownloadOnly = WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::InstallerDownloadOnly);\r\n\r\n        // CheckForExistingInstaller will set the InstallerPath if found\r\n        if (!context.Contains(Execution::Data::InstallerPath))\r\n        {\r\n            const auto& installer = context.Get<Execution::Data::Installer>().value();\r\n            switch (installer.BaseInstallerType)\r\n            {\r\n            case InstallerTypeEnum::Exe:\r\n            case InstallerTypeEnum::Burn:\r\n            case InstallerTypeEnum::Inno:\r\n            case InstallerTypeEnum::Msi:\r\n            case InstallerTypeEnum::Nullsoft:\r\n            case InstallerTypeEnum::Portable: \r\n            case InstallerTypeEnum::Wix:\r\n            case InstallerTypeEnum::Font:\r\n            case InstallerTypeEnum::Zip:\r\n                context << DownloadInstallerFile;\r\n                break;\r\n            case InstallerTypeEnum::Msix:\r\n                // If the signature hash is provided in the manifest and we are doing an install,\r\n                // we can just verify signature hash without a full download and do a streaming install.\r\n                // Even if we have the signature hash, we still do a full download if InstallerDownloadOnly\r\n                // flag is set, or if we need to use a proxy (as deployment APIs won't use proxy for us).\r\n                // Finally, we require the digest API for streaming install as well.\r\n                if (installer.SignatureSha256.empty()\r\n                    || installerDownloadOnly\r\n                    || Network().GetProxyUri()\r\n                    || !Deployment::IsExpectedDigestsSupported())\r\n                {\r\n                    context << DownloadInstallerFile;\r\n                }\r\n                else\r\n                {\r\n                    context << GetMsixSignatureHash;\r\n                }\r\n                break;\r\n            case InstallerTypeEnum::MSStore:\r\n                if (installerDownloadOnly)\r\n                {\r\n                    context <<\r\n                        MSStoreDownload <<\r\n                        ExportManifest;\r\n                }\r\n\r\n                return;\r\n            default:\r\n                THROW_HR(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED));\r\n            }\r\n        }\r\n\r\n        context <<\r\n            VerifyInstallerHash <<\r\n            UpdateInstallerFileMotwIfApplicable <<\r\n            RenameDownloadedInstaller;\r\n\r\n        if (installerDownloadOnly)\r\n        {\r\n            context << ExportManifest;\r\n        }\r\n    }\r\n\r\n    void CheckForExistingInstaller(Execution::Context& context)\r\n    {\r\n        const auto& installer = context.Get<Execution::Data::Installer>().value();\r\n        if (installer.EffectiveInstallerType() == InstallerTypeEnum::MSStore)\r\n        {\r\n            // No installer is downloaded in this case\r\n            return;\r\n        }\r\n\r\n        // Try looking for the file with and without extension.\r\n        auto installerPath = GetInstallerBaseDownloadPath(context);\r\n        auto installerFilename = GetInstallerPreHashValidationFileName(context);\r\n        SHA256::HashDetails fileHashDetails;\r\n        if (!ExistingInstallerFileHasHashMatch(installer.Sha256, installerPath / installerFilename, fileHashDetails))\r\n        {\r\n            installerFilename = GetInstallerPostHashValidationFileName(context);\r\n            if (!ExistingInstallerFileHasHashMatch(installer.Sha256, installerPath / installerFilename, fileHashDetails))\r\n            {\r\n                // No match\r\n                return;\r\n            }\r\n        }\r\n\r\n        AICLI_LOG(CLI, Info, << \"Existing installer file hash matches. Will use existing installer.\");\r\n        context.Add<Execution::Data::InstallerPath>(installerPath / installerFilename);\r\n        context.Add<Execution::Data::DownloadHashInfo>(std::make_pair(installer.Sha256,\r\n            DownloadResult{ std::move(fileHashDetails.Hash), fileHashDetails.SizeInBytes }));\r\n    }\r\n\r\n    void GetInstallerDownloadPath(Execution::Context& context)\r\n    {\r\n        if (!context.Contains(Execution::Data::InstallerPath))\r\n        {\r\n            auto tempInstallerPath = GetInstallerBaseDownloadPath(context);\r\n            tempInstallerPath /= GetInstallerPreHashValidationFileName(context);\r\n            AICLI_LOG(CLI, Info, << \"Generated temp download path: \" << tempInstallerPath);\r\n            context.Add<Execution::Data::InstallerPath>(std::move(tempInstallerPath));\r\n        }\r\n    }\r\n\r\n    void DownloadInstallerFile(Execution::Context& context)\r\n    {\r\n        context << GetInstallerDownloadPath;\r\n        if (context.IsTerminated())\r\n        {\r\n            return;\r\n        }\r\n\r\n        const auto& installer = context.Get<Execution::Data::Installer>().value();\r\n        const auto& installerPath = context.Get<Execution::Data::InstallerPath>();\r\n\r\n        Utility::DownloadInfo downloadInfo{};\r\n        downloadInfo.DisplayName = Resource::GetFixedString(Resource::FixedString::ProductName);\r\n        // Use the SHA256 hash of the installer as the identifier for the download\r\n        downloadInfo.ContentId = SHA256::ConvertToString(installer.Sha256);\r\n\r\n        try\r\n        {\r\n            downloadInfo.RequestHeaders = GetInstallerDownloadAuthenticationHeaders(installer, context);\r\n        }\r\n        catch (const wil::ResultException& re)\r\n        {\r\n            AICLI_LOG(CLI, Error, << \"Authentication failed for installer download. Error code: \" << re.GetErrorCode());\r\n\r\n            if (re.GetErrorCode() == APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED)\r\n            {\r\n                context.Reporter.Error() << Resource::String::InstallerDownloadAuthenticationNotSupported << std::endl;\r\n            }\r\n            else\r\n            {\r\n                context.Reporter.Error() << Resource::String::InstallerDownloadAuthenticationFailed << std::endl;\r\n            }\r\n\r\n            AICLI_TERMINATE_CONTEXT(re.GetErrorCode());\r\n        }\r\n\r\n        context.Reporter.Info() << Resource::String::Downloading << ' ' << Execution::UrlEmphasis << installer.Url << std::endl;\r\n\r\n        DownloadResult downloadResult;\r\n\r\n        constexpr int MaxRetryCount = 2;\r\n        constexpr std::chrono::seconds maximumWaitTimeAllowed = 60s;\r\n        for (int retryCount = 0; retryCount < MaxRetryCount; ++retryCount)\r\n        {\r\n            bool success = false;\r\n            try\r\n            {\r\n                downloadResult = context.Reporter.ExecuteWithProgress(std::bind(Utility::Download,\r\n                    installer.Url,\r\n                    installerPath,\r\n                    Utility::DownloadType::Installer,\r\n                    std::placeholders::_1,\r\n                    downloadInfo));\r\n\r\n                // User cancelled.\r\n                if (downloadResult.Sha256Hash.empty())\r\n                {\r\n                    context.Reporter.Info() << Resource::String::Cancelled << std::endl;\r\n                    AICLI_TERMINATE_CONTEXT(E_ABORT);\r\n                }\r\n\r\n                if (downloadResult.SizeInBytes == 0)\r\n                {\r\n                    AICLI_LOG(CLI, Info, << \"Got zero byte file; retrying download after a short wait...\");\r\n                    std::this_thread::sleep_for(5s);\r\n                }\r\n                else\r\n                {\r\n                    success = true;\r\n                }\r\n            }\r\n            catch (const ServiceUnavailableException& sue)\r\n            {\r\n                if (retryCount < MaxRetryCount - 1)\r\n                {\r\n                    auto waitSecondsForRetry = sue.RetryAfter();\r\n                    if (waitSecondsForRetry > maximumWaitTimeAllowed)\r\n                    {\r\n                        throw;\r\n                    }\r\n\r\n                    bool waitCompleted = context.Reporter.ExecuteWithProgress([&waitSecondsForRetry](IProgressCallback& progress)\r\n                        {\r\n                            return ProgressCallback::Wait(progress, waitSecondsForRetry);\r\n                        });\r\n\r\n                    if (!waitCompleted)\r\n                    {\r\n                        break;\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    throw;\r\n                }\r\n            }\r\n            catch (...)\r\n            {\r\n                if (retryCount < MaxRetryCount - 1)\r\n                {\r\n                    AICLI_LOG(CLI, Info, << \"Failed to download, waiting a bit and retry. Url: \" << installer.Url);\r\n                    Sleep(500);\r\n                }\r\n                else\r\n                {\r\n                    throw;\r\n                }\r\n            }\r\n\r\n            if (success)\r\n            {\r\n                break;\r\n            }\r\n        }\r\n\r\n        context.Add<Execution::Data::DownloadHashInfo>(std::make_pair(installer.Sha256, downloadResult));\r\n    }\r\n\r\n    void GetMsixSignatureHash(Execution::Context& context)\r\n    {\r\n        // We use this when the server won't support streaming install to swap to download.\r\n        bool downloadInstead = false;\r\n\r\n        try\r\n        {\r\n            const auto& installer = context.Get<Execution::Data::Installer>().value();\r\n\r\n            // Signature hash is only used for streaming installs, which don't use proxy\r\n            Msix::MsixInfo msixInfo(installer.Url);\r\n\r\n            DownloadResult hashInfo{ msixInfo.GetSignatureHash() };\r\n            // Value is ASCII for MSIXSTRM\r\n            // A sentinel value to indicate that this is a streaming hash rather than a download.\r\n            // The primary purpose is to prevent us from falling into the code path for zero byte files.\r\n            hashInfo.SizeInBytes = 0x4D5349585354524D;\r\n\r\n            context.Add<Execution::Data::DownloadHashInfo>(std::make_pair(installer.SignatureSha256, hashInfo));\r\n            context.Add<Execution::Data::MsixDigests>({ std::make_pair(installer.Url, msixInfo.GetDigest()) });\r\n        }\r\n        catch (...)\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"Failed to get msix signature hash, fall back to direct download.\");\r\n            downloadInstead = true;\r\n        }\r\n\r\n        if (downloadInstead)\r\n        {\r\n            context << DownloadInstallerFile;\r\n        }\r\n    }\r\n\r\n    void VerifyInstallerHash(Execution::Context& context)\r\n    {\r\n        const auto& [expectedHash, downloadResult] = context.Get<Execution::Data::DownloadHashInfo>();\r\n\r\n        if (!std::equal(\r\n            expectedHash.begin(),\r\n            expectedHash.end(),\r\n            downloadResult.Sha256Hash.begin()))\r\n        {\r\n            bool overrideHashMismatch = context.Args.Contains(Execution::Args::Type::HashOverride);\r\n\r\n            const auto& manifest = context.Get<Execution::Data::Manifest>();\r\n            Logging::Telemetry().LogInstallerHashMismatch(manifest.Id, manifest.Version, manifest.Channel, expectedHash, downloadResult.Sha256Hash, overrideHashMismatch, downloadResult.SizeInBytes, downloadResult.ContentType);\r\n\r\n            if (downloadResult.SizeInBytes == 0)\r\n            {\r\n                context.Reporter.Error() << Resource::String::InstallerZeroByteFile << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_INSTALLER_ZERO_BYTE_FILE);\r\n            }\r\n\r\n            // If running as admin, do not allow the user to override the hash failure.\r\n            if (Runtime::IsRunningAsAdmin())\r\n            {\r\n                context.Reporter.Error() << Resource::String::InstallerHashMismatchAdminBlock << std::endl;\r\n            }\r\n            else if (!Settings::IsAdminSettingEnabled(Settings::BoolAdminSetting::InstallerHashOverride))\r\n            {\r\n                context.Reporter.Error() << Resource::String::InstallerHashMismatchError << std::endl;\r\n            }\r\n            else if (overrideHashMismatch)\r\n            {\r\n                context.Reporter.Warn() << Resource::String::InstallerHashMismatchOverridden << std::endl;\r\n                return;\r\n            }\r\n            else\r\n            {\r\n                context.Reporter.Error() << Resource::String::InstallerHashMismatchOverrideRequired << std::endl;\r\n            }\r\n\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_INSTALLER_HASH_MISMATCH);\r\n        }\r\n        else\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"Installer hash verified\");\r\n            context.Reporter.Info() << Resource::String::InstallerHashVerified << std::endl;\r\n\r\n            context.SetFlags(Execution::ContextFlag::InstallerHashMatched);\r\n\r\n            if (context.Contains(Execution::Data::PackageVersion) &&\r\n                context.Get<Execution::Data::PackageVersion>()->GetSource() &&\r\n                WI_IsFlagSet(context.Get<Execution::Data::PackageVersion>()->GetSource().GetDetails().TrustLevel, SourceTrustLevel::Trusted))\r\n            {\r\n                context.SetFlags(Execution::ContextFlag::InstallerTrusted);\r\n            }\r\n        }\r\n    }\r\n\r\n    void UpdateInstallerFileMotwIfApplicable(Execution::Context& context)\r\n    {\r\n        // An initial MotW is always set to URLZONE_INTERNET at the time the file is downloaded.\r\n        // This function may change that to URLZONE_TRUSTED if appropriate\r\n        if (context.Contains(Execution::Data::InstallerPath))\r\n        {\r\n            if (WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::InstallerTrusted))\r\n            {\r\n                // We know the installer already went through multiple scans and we can trust it.\r\n                Utility::ApplyMotwIfApplicable(context.Get<Execution::Data::InstallerPath>(), URLZONE_TRUSTED);\r\n            }\r\n            else if (WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::InstallerHashMatched))\r\n            {\r\n                // IAttachmentExecute performs some additional scans before setting MotW, for example invoking anti-virus.\r\n                // A policy can be set to always mark files from a given domain as trusted, so only do this\r\n                // on installers with the right hash to prevent trusting unknown installers.\r\n                const auto& installer = context.Get<Execution::Data::Installer>();\r\n                HRESULT hr = Utility::ApplyMotwUsingIAttachmentExecuteIfApplicable(context.Get<Execution::Data::InstallerPath>(), installer.value().Url, URLZONE_INTERNET);\r\n\r\n                // Not using SUCCEEDED(hr) to check since there are cases file is missing after a successful scan\r\n                if (hr != S_OK)\r\n                {\r\n                    switch (hr)\r\n                    {\r\n                    case INET_E_SECURITY_PROBLEM:\r\n                        context.Reporter.Error() << Resource::String::InstallerBlockedByPolicy << std::endl;\r\n                        break;\r\n                    case E_FAIL:\r\n                        context.Reporter.Error() << Resource::String::InstallerFailedVirusScan << std::endl;\r\n                        break;\r\n                    default:\r\n                        context.Reporter.Error() << Resource::String::InstallerFailedSecurityCheck << std::endl;\r\n                    }\r\n\r\n                    AICLI_LOG(Fail, Error, << \"Installer failed security check. Url: \" << installer.value().Url << \" Result: \" << WINGET_OSTREAM_FORMAT_HRESULT(hr));\r\n                    AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_INSTALLER_SECURITY_CHECK_FAILED);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    void ReverifyInstallerHash(Execution::Context& context)\r\n    {\r\n        const auto& installer = context.Get<Execution::Data::Installer>().value();\r\n\r\n        if (context.Contains(Execution::Data::InstallerPath))\r\n        {\r\n            // Get the hash from the installer file\r\n            const auto& installerPath = context.Get<Execution::Data::InstallerPath>();\r\n            std::ifstream inStream{ installerPath, std::ifstream::binary };\r\n            auto existingFileHashDetails = SHA256::ComputeHashDetails(inStream);\r\n            context.Add<Execution::Data::DownloadHashInfo>(std::make_pair(installer.Sha256,\r\n                DownloadResult{ existingFileHashDetails.Hash, existingFileHashDetails.SizeInBytes }));\r\n        }\r\n        else if (installer.EffectiveInstallerType() == InstallerTypeEnum::MSStore)\r\n        {\r\n            // No installer file in this case\r\n            return;\r\n        }\r\n        else if (installer.EffectiveInstallerType() == InstallerTypeEnum::Msix && !installer.SignatureSha256.empty())\r\n        {\r\n            // We didn't download the installer file before. Just verify the signature hash again.\r\n            context << GetMsixSignatureHash;\r\n        }\r\n        else\r\n        {\r\n            // No installer downloaded\r\n            AICLI_LOG(CLI, Error, << \"Installer file not found.\");\r\n            AICLI_TERMINATE_CONTEXT(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));\r\n        }\r\n\r\n        context << VerifyInstallerHash;\r\n    }\r\n\r\n    void RenameDownloadedInstaller(Execution::Context& context)\r\n    {\r\n        if (!context.Contains(Execution::Data::InstallerPath))\r\n        {\r\n            // No installer downloaded, no need to rename anything.\r\n            return;\r\n        }\r\n\r\n        auto& installerPath = context.Get<Execution::Data::InstallerPath>();\r\n        std::filesystem::path renamedDownloadedInstaller;\r\n\r\n        if (WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::InstallerDownloadOnly))\r\n        {\r\n            THROW_HR_IF(E_UNEXPECTED, !context.Contains(Execution::Data::DownloadDirectory));\r\n\r\n            std::filesystem::path downloadDirectory = context.Get<Execution::Data::DownloadDirectory>();\r\n\r\n            if (!std::filesystem::exists(downloadDirectory))\r\n            {\r\n                std::filesystem::create_directories(downloadDirectory);\r\n            }\r\n            else\r\n            {\r\n                THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_CANNOT_MAKE), !std::filesystem::is_directory(downloadDirectory));\r\n            }\r\n\r\n            renamedDownloadedInstaller = downloadDirectory / GetInstallerDownloadOnlyFileName(context);\r\n            Filesystem::RenameFile(installerPath, renamedDownloadedInstaller);\r\n            context.Reporter.Info() << Resource::String::InstallerDownloaded(Utility::LocIndView{ renamedDownloadedInstaller.u8string() }) << std::endl;\r\n        }\r\n        else\r\n        {\r\n            renamedDownloadedInstaller = installerPath;\r\n            renamedDownloadedInstaller.replace_filename(GetInstallerPostHashValidationFileName(context));\r\n\r\n            if (installerPath == renamedDownloadedInstaller)\r\n            {\r\n                // In case we are reusing an existing downloaded file\r\n                return;\r\n            }\r\n\r\n            Filesystem::RenameFile(installerPath, renamedDownloadedInstaller);\r\n        }\r\n\r\n        installerPath.assign(renamedDownloadedInstaller);\r\n        AICLI_LOG(CLI, Info, << \"Successfully renamed downloaded installer. Path: \" << installerPath);\r\n    }\r\n\r\n    void RemoveInstaller(Execution::Context& context)\r\n    {\r\n        // Path may not be present if installed from a URL for MSIX\r\n        if (context.Contains(Execution::Data::InstallerPath))\r\n        {\r\n            const auto& path = context.Get<Execution::Data::InstallerPath>();\r\n            AICLI_LOG(CLI, Info, << \"Removing installer: \" << path);\r\n            RemoveInstallerFile(path);\r\n        }\r\n    }\r\n\r\n    void SetDownloadDirectory(Execution::Context& context)\r\n    {\r\n        if (!WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::InstallerDownloadOnly))\r\n        {\r\n            return;\r\n        }\r\n\r\n        if (context.Args.Contains(Execution::Args::Type::DownloadDirectory))\r\n        {\r\n            context.Add<Execution::Data::DownloadDirectory>(std::filesystem::path{ Utility::ConvertToUTF16(context.Args.GetArg(Execution::Args::Type::DownloadDirectory)) });\r\n        }\r\n        else\r\n        {\r\n            std::filesystem::path downloadsDirectory = Settings::User().Get<Settings::Setting::DownloadDefaultDirectory>();\r\n\r\n            if (downloadsDirectory.empty())\r\n            {\r\n                downloadsDirectory = AppInstaller::Runtime::GetPathTo(AppInstaller::Runtime::PathName::UserProfileDownloads);\r\n            }\r\n\r\n            const auto& manifest = context.Get<Execution::Data::Manifest>();\r\n            std::string packageDownloadFolderName = manifest.Id;\r\n            if (!Utility::Version{ manifest.Version }.IsUnknown())\r\n            {\r\n                packageDownloadFolderName += '_' + manifest.Version;\r\n            }\r\n            context.Add<Execution::Data::DownloadDirectory>(downloadsDirectory / Utility::ConvertToUTF16(packageDownloadFolderName));\r\n        }\r\n    }\r\n\r\n    void ExportManifest(Execution::Context& context)\r\n    {\r\n        const auto& downloadDirectory = context.Get<Execution::Data::DownloadDirectory>();\r\n        const auto& manifest = context.Get<Execution::Data::Manifest>();\r\n        const auto& installer = context.Get<Execution::Data::Installer>();\r\n\r\n        std::filesystem::path manifestFileName = GetInstallerDownloadOnlyFileName(context, L\".yaml\");\r\n        auto manifestDownloadPath = downloadDirectory / manifestFileName;\r\n        YamlWriter::OutputYamlFile(manifest, installer.value(), manifestDownloadPath);\r\n        AICLI_LOG(CLI, Info, << \"Successfully generated manifest yaml. Path: \" << manifestDownloadPath);\r\n    }\r\n\r\n    void EnsureSupportForDownload(Execution::Context& context)\r\n    {\r\n        // No checks needed if not download installer only.\r\n        if (WI_IsFlagClear(context.GetFlags(), Execution::ContextFlag::InstallerDownloadOnly))\r\n        {\r\n            return;\r\n        }\r\n\r\n        const auto& installer = context.Get<Execution::Data::Installer>();\r\n\r\n        if (installer->DownloadCommandProhibited)\r\n        {\r\n            context.Reporter.Error() << Resource::String::InstallerDownloadCommandProhibited << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_DOWNLOAD_COMMAND_PROHIBITED);\r\n        }\r\n    }\r\n\r\n    void InitializeInstallerDownloadAuthenticatorsMap(Execution::Context& context)\r\n    {\r\n        context.Add<Execution::Data::InstallerDownloadAuthenticators>(std::make_shared<std::map<Authentication::AuthenticationInfo, Authentication::Authenticator>>());\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/DownloadFlow.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ExecutionContext.h\"\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    // Composite flow that chooses what to do based on the installer type.\r\n    // Required Args: None\r\n    // Inputs: Manifest, Installer\r\n    // Outputs: None\r\n    void DownloadInstaller(Execution::Context& context);\r\n\r\n    // Check if the desired installer has already been downloaded.\r\n    // Required Args: None\r\n    // Inputs: Manifest, Installer\r\n    // Outputs: HashPair, InstallerPath (only if found)\r\n    void CheckForExistingInstaller(Execution::Context& context);\r\n\r\n    // Computes the download path for the installer file. Does nothing if already determined\r\n    // Required Args: None\r\n    // Inputs: Installer, Manifest\r\n    // Outputs: InstallerPath\r\n    void GetInstallerDownloadPath(Execution::Context& context);\r\n\r\n    // Downloads the file referenced by the Installer.\r\n    // This workflow task is also used by MSStoreDownload task.\r\n    // Required Args: None\r\n    // Inputs: Installer, Manifest\r\n    // Outputs: HashPair, InstallerPath\r\n    void DownloadInstallerFile(Execution::Context& context);\r\n\r\n    // Computes the hash of the MSIX signature file.\r\n    // Required Args: None\r\n    // Inputs: Installer\r\n    // Outputs: HashPair\r\n    void GetMsixSignatureHash(Execution::Context& context);\r\n\r\n    // Re-verify the installer hash. This is used in Com install commands where download and install are in separate phases.\r\n    // Required Args: None\r\n    // Inputs: InstallerPath, Installer\r\n    // Outputs: HashPair\r\n    void ReverifyInstallerHash(Execution::Context& context);\r\n\r\n    // Verifies that the downloaded installer hash matches the hash in the manifest.\r\n    // Required Args: None\r\n    // Inputs: HashPair\r\n    // Outputs: None\r\n    void VerifyInstallerHash(Execution::Context& context);\r\n\r\n    // Update Motw of the downloaded installer if applicable\r\n    // Required Args: None\r\n    // Inputs: HashPair, InstallerPath?, SourceId?\r\n    // Outputs: None\r\n    void UpdateInstallerFileMotwIfApplicable(Execution::Context& context);\r\n\r\n    // This method appends appropriate extension to the downloaded installer.\r\n    // ShellExecute uses file extension to launch the installer appropriately.\r\n    // Required Args: None\r\n    // Inputs: Installer, InstallerPath\r\n    // Modifies: InstallerPath\r\n    // Outputs: None\r\n    void RenameDownloadedInstaller(Execution::Context& context);\r\n\r\n    // Deletes the installer file.\r\n    // Required Args: None\r\n    // Inputs: InstallerPath\r\n    // Outputs: None\r\n    void RemoveInstaller(Execution::Context& context);\r\n\r\n    // Sets the target download directory location if applicable.\r\n    // Required Args: None\r\n    // Inputs: Manifest\r\n    // Outputs: None\r\n    void SetDownloadDirectory(Execution::Context& context);\r\n\r\n    // Exports the manifest yaml file for the downloaded package installer. Only applies to the 'winget download' command.\r\n    // Required Args: None\r\n    // Inputs: Manifest, Installer, DownloadDirectory\r\n    // Outputs: None\r\n    void ExportManifest(Execution::Context& context);\r\n\r\n    // This method ensures requirements of download for later offline installation.\r\n    // Required Args: None\r\n    // Inputs: Installer\r\n    // Outputs: None\r\n    void EnsureSupportForDownload(Execution::Context& context);\r\n\r\n    // This method initializes an empty InstallerDownloadAuthenticators map.\r\n    // InstallerDownloadAuthenticators map is for reusing authenticators when downloading multiple installers.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: New empty InstallerDownloadAuthenticators\r\n    void InitializeInstallerDownloadAuthenticatorsMap(Execution::Context& context);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/FontFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n#include \"pch.h\"\n#include \"FontFlow.h\"\n#include \"TableOutput.h\"\n#include <winget/Fonts.h>\n#include <AppInstallerRuntime.h>\nusing namespace AppInstaller::Utility;\n\nnamespace AppInstaller::CLI::Workflow\n{\n    using namespace AppInstaller::CLI::Execution;\n    using namespace AppInstaller::Fonts;\n\n    namespace\n    {\n        struct InstalledFontFamiliesTableLine\n        {\n            InstalledFontFamiliesTableLine(Utility::LocIndString familyName, int faceCount)\n                : FamilyName(familyName), FaceCount(faceCount) {\n            }\n\n            Utility::LocIndString FamilyName;\n            int FaceCount;\n        };\n\n        struct InstalledFontFacesTableLine\n        {\n            InstalledFontFacesTableLine(Utility::LocIndString familyName, Utility::LocIndString faceName, Utility::LocIndString faceVersion, std::filesystem::path filePath)\n                : FamilyName(familyName), FaceName(faceName), FaceVersion(faceVersion), FilePath(filePath) {\n            }\n\n            Utility::LocIndString FamilyName;\n            Utility::LocIndString FaceName;\n            Utility::LocIndString FaceVersion;\n            std::filesystem::path FilePath;\n        };\n\n        struct InstalledFontFilesTableLine\n        {\n            InstalledFontFilesTableLine(Utility::LocIndString title, Utility::LocIndString packageName, Resource::LocString fontStatus, std::filesystem::path filePath)\n                : Title(title), PackageName(packageName), FontStatus(fontStatus), FilePath(filePath) {\n            }\n\n            Utility::LocIndString Title;\n            Utility::LocIndString PackageName;\n            Resource::LocString FontStatus;\n            std::filesystem::path FilePath;\n        };\n\n        void OutputInstalledFontFamiliesTable(Execution::Context& context, const std::vector<InstalledFontFamiliesTableLine>& lines)\n        {\n            Execution::TableOutput<2> table(context.Reporter, { Resource::String::FontFamily, Resource::String::FontFaces });\n\n            for (auto line : lines)\n            {\n                table.OutputLine({ line.FamilyName, std::to_string(line.FaceCount) });\n            }\n\n            table.Complete();\n        }\n\n        void OutputInstalledFontFacesTable(Execution::Context& context, const std::vector<InstalledFontFacesTableLine>& lines)\n        {\n            Execution::TableOutput<4> table(context.Reporter, { Resource::String::FontFamily, Resource::String::FontFace, Resource::String::FontVersion, Resource::String::FontFilePaths });\n\n            bool anonymizePath = Settings::User().Get<Settings::Setting::AnonymizePathForDisplay>();\n\n            for (auto line : lines)\n            {\n                if (anonymizePath)\n                {\n                    AppInstaller::Runtime::ReplaceProfilePathsWithEnvironmentVariable(line.FilePath);\n                }\n\n                table.OutputLine({ line.FamilyName, line.FaceName, line.FaceVersion, line.FilePath.u8string() });\n            }\n\n            table.Complete();\n        }\n\n        void OutputInstalledFontFilesTable(Execution::Context& context, const std::vector<InstalledFontFilesTableLine>& lines)\n        {\n            Execution::TableOutput<4> table(context.Reporter, { Resource::String::FontTitle, Resource::String::FontPackage, Resource::String::FontStatus, Resource::String::FontFilePaths });\n\n            bool anonymizePath = Settings::User().Get<Settings::Setting::AnonymizePathForDisplay>();\n\n            for (auto line : lines)\n            {\n                if (anonymizePath)\n                {\n                    AppInstaller::Runtime::ReplaceProfilePathsWithEnvironmentVariable(line.FilePath);\n                }\n\n                table.OutputLine({ line.Title, line.PackageName, line.FontStatus, line.FilePath.u8string() });\n            }\n\n            table.Complete();\n        }\n    }\n\n    void ReportInstalledFonts(Execution::Context& context)\n    {\n        Fonts::FontCatalog fontCatalog;\n\n        if (context.Args.Contains(Args::Type::Family))\n        {\n            // TODO: Create custom source and search mechanism for fonts.\n            const auto& familyNameArg = AppInstaller::Utility::ConvertToUTF16(context.Args.GetArg(Args::Type::Family));\n            const auto& fontFamilies = fontCatalog.GetInstalledFontFamilies(familyNameArg);\n\n            if (fontFamilies.empty())\n            {\n                context.Reporter.Info() << Resource::String::NoInstalledFontFound << std::endl;\n                return;\n            }\n\n            std::vector<InstalledFontFacesTableLine> lines;\n\n            for (const auto& fontFamily : fontFamilies)\n            {\n                const auto& familyName = Utility::LocIndString(Utility::ConvertToUTF8(fontFamily.Name));\n\n                for (const auto& fontFace : fontFamily.Faces)\n                {\n                    for (const auto& filePath : fontFace.FilePaths)\n                    {\n                        InstalledFontFacesTableLine line(\n                            familyName,\n                            Utility::LocIndString(Utility::ToLower(Utility::ConvertToUTF8(fontFace.Name))),\n                            Utility::LocIndString(fontFace.Version.ToString()),\n                            filePath.u8string());\n\n                        lines.push_back(std::move(line));\n                    }\n                }\n            }\n\n            OutputInstalledFontFacesTable(context, lines);\n        }\n        else if (context.Args.Contains(Args::Type::Details))\n        {\n            const auto& fontFiles = AppInstaller::Fonts::GetInstalledFontFiles();\n            std::vector<InstalledFontFilesTableLine> lines;\n            for (const auto& fontFile : fontFiles)\n            {\n                Resource::LocString status;\n                switch (fontFile.Status)\n                {\n                case FontStatus::OK:\n                    status = Resource::LocString(Resource::String::FontStatusOK);\n                    break;\n                case FontStatus::Corrupt:\n                    status = Resource::LocString(Resource::String::FontStatusCorrupt);\n                    break;\n                default:\n                    status = Resource::LocString(Resource::String::FontStatusUnknown);\n                    break;\n                }\n\n                InstalledFontFilesTableLine line(\n                    Utility::LocIndString(Utility::ConvertToUTF8(fontFile.Title)),\n                    Utility::LocIndString(Utility::ConvertToUTF8(fontFile.PackageIdentifier)),\n                    status,\n                    fontFile.FilePath.u8string());\n\n                lines.push_back(std::move(line));\n            }\n\n            OutputInstalledFontFilesTable(context, lines);\n        }\n        else\n        {\n            const auto& fontFamilies = fontCatalog.GetInstalledFontFamilies();\n            std::vector<InstalledFontFamiliesTableLine> lines;\n\n            for (const auto& fontFamily : fontFamilies)\n            {\n                InstalledFontFamiliesTableLine line(\n                    Utility::LocIndString(Utility::ConvertToUTF8(fontFamily.Name)),\n                    static_cast<int>(fontFamily.Faces.size())\n                );\n\n                lines.push_back(std::move(line));\n            }\n\n            OutputInstalledFontFamiliesTable(context, lines);\n        }\n    }\n\n    void FontInstallImpl(Execution::Context& context)\n    {\n        context.Reporter.Info() << Resource::String::InstallFlowStartingPackageInstall << std::endl;\n\n        // We will default to User scope.\n        Manifest::ScopeEnum scope = Manifest::ScopeEnum::User;\n        if (context.Args.Contains(Execution::Args::Type::InstallScope))\n        {\n            scope = Manifest::ConvertToScopeEnum(context.Args.GetArg(Execution::Args::Type::InstallScope));\n        }\n\n        Fonts::FontContext fontContext;\n        fontContext.InstallerSource = InstallerSource::WinGet;\n        fontContext.Scope = scope;\n\n        auto& manifest = context.Get<Execution::Data::Manifest>();\n        fontContext.PackageId = ConvertToUTF16(manifest.Id);\n        fontContext.PackageVersion = ConvertToUTF16(manifest.Version);\n\n        if (context.Args.Contains(Execution::Args::Type::Force))\n        {\n            fontContext.Force = true;\n        }\n\n        try\n        {\n            const auto& installerPath = context.Get<Execution::Data::InstallerPath>();\n\n            // InstallerPath will point to a directory if extracted from an archive.\n            if (std::filesystem::is_directory(installerPath))\n            {\n                const std::vector<Manifest::NestedInstallerFile>& nestedInstallerFiles = context.Get<Execution::Data::Installer>()->NestedInstallerFiles;\n                for (const auto& nestedInstallerFile : nestedInstallerFiles)\n                {\n                    fontContext.AddPackageFile(installerPath / ConvertToUTF16(nestedInstallerFile.RelativeFilePath));\n                }\n            }\n            else\n            {\n                fontContext.AddPackageFile(installerPath);\n            }\n\n            const auto& fontValidationResult = Fonts::ValidateFontPackage(fontContext);\n            if (fontValidationResult.Result != FontResult::Success)\n            {\n                context.Reporter.Error() << Resource::String::FontValidationFailed << std::endl;\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_FONT_VALIDATION_FAILED);\n            }\n\n            if (fontValidationResult.HasUnsupportedFonts)\n            {\n                context.Reporter.Error() << Resource::String::FontFileNotSupported << std::endl;\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_SUPPORTED);\n            }\n\n            if (fontValidationResult.Status == FontStatus::OK && !fontContext.Force)\n            {\n                context.Reporter.Warn() << Resource::String::FontAlreadyInstalled << std::endl;\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_FONT_ALREADY_INSTALLED);\n            }\n\n            auto installResult = Fonts::InstallFontPackage(fontContext);\n            if (installResult.Result() != FontResult::Success)\n            {\n                context.Reporter.Error() << Resource::String::FontInstallFailed << std::endl;\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_FONT_INSTALL_FAILED);\n            }\n\n            context.Add<Execution::Data::CorrelatedAppsAndFeaturesEntries>({ fontContext.GetAppsAndFeaturesEntry() });\n            context.Add<Execution::Data::OperationReturnCode>(installResult.HResult);\n        }\n        catch (...)\n        {\n            context.Add<Execution::Data::OperationReturnCode>(Workflow::HandleException(context, std::current_exception()));\n            context.Reporter.Warn() << Resource::String::FontInstallFailed << std::endl;\n\n            try\n            {\n                // The Font Install code handles rollback where appropriate. If we hit an\n                // unexpected exception, try to uninstall anyway to arrive at a consistent\n                // absent state. Since we install side-by-side for versions, this should\n                // only result in an absent state of an installed font if this were a forced\n                // install of an existing version.\n                auto uninstallResult = Fonts::UninstallFontPackage(fontContext);\n                if (uninstallResult.Result() != FontResult::Success)\n                {\n                    context.Reporter.Warn() << Resource::String::FontRollbackFailed << std::endl;\n                }\n            }\n            CATCH_LOG();\n\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_FONT_INSTALL_FAILED);\n        }\n    }\n\n    void FontUninstallImpl(Execution::Context& context)\n    {\n        context.Reporter.Info() << Resource::String::UninstallFlowStartingPackageUninstall << std::endl;\n\n        try\n        {\n            // We will default to installed scope.\n            auto scope = Manifest::ConvertToScopeEnum(context.Get<Execution::Data::InstalledPackageVersion>()->GetMetadata()[Repository::PackageVersionMetadata::InstalledScope]);\n            if (context.Args.Contains(Execution::Args::Type::InstallScope))\n            {\n                scope = Manifest::ConvertToScopeEnum(context.Args.GetArg(Execution::Args::Type::InstallScope));\n            }\n\n            Fonts::FontContext fontContext;\n            fontContext.InstallerSource = InstallerSource::WinGet;\n            if (context.Args.Contains(Execution::Args::Type::Manifest))\n            {\n                const auto& manifest = context.Get<Execution::Data::Manifest>();\n                fontContext.PackageId = ConvertToUTF16(manifest.Id);\n                fontContext.PackageVersion = ConvertToUTF16(manifest.Version);\n                fontContext.Scope = scope;\n            }\n            else\n            {\n                const std::string moniker = context.Get<Execution::Data::InstalledPackageVersion>()->GetProperty(AppInstaller::Repository::PackageVersionProperty::Moniker);\n                const std::string version = context.Get<Execution::Data::InstalledPackageVersion>()->GetProperty(AppInstaller::Repository::PackageVersionProperty::Version);\n                fontContext.PackageId = ConvertToUTF16(moniker);\n                fontContext.PackageVersion = ConvertToUTF16(version);\n                fontContext.Scope = scope;\n            }\n\n            if (fontContext.Scope == Manifest::ScopeEnum::Machine && !Runtime::IsRunningAsAdmin())\n            {\n                context.Reporter.Error() << Resource::String::CommandRequiresAdmin << std::endl;\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_COMMAND_REQUIRES_ADMIN);\n            }\n\n            auto uninstallResult = Fonts::UninstallFontPackage(fontContext);\n            if (uninstallResult.Result() != FontResult::Success)\n            {\n                context.Reporter.Error() << Resource::String::FontUninstallFailed << std::endl;\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_FONT_UNINSTALL_FAILED);\n            }\n\n            context.Add<Execution::Data::OperationReturnCode>(uninstallResult.HResult);\n        }\n        catch (...)\n        {\n            context.Add<Execution::Data::OperationReturnCode>(Workflow::HandleException(context, std::current_exception()));\n            context.Reporter.Error() << Resource::String::FontUninstallFailed << std::endl;\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_FONT_UNINSTALL_FAILED);\n        }\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/FontFlow.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"ExecutionContext.h\"\n\nnamespace AppInstaller::CLI::Workflow\n{\n    // Reports the installed fonts as a table.\n    // Required Args: None\n    // Inputs: None\n    // Outputs: None\n    void ReportInstalledFonts(Execution::Context& context);\n\n    // Installs the font package.\n    // Required Args: None\n    // Inputs: Manifest, Scope, Rename, Location\n    // Outputs: None\n    void FontInstallImpl(Execution::Context& context);\n\n    // Uninstalls the font package.\n    // Required Args: None\n    // Inputs: Manifest, Scope, Rename, Location\n    // Outputs: None\n    void FontUninstallImpl(Execution::Context& context);\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/ImportExportFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"InstallFlow.h\"\r\n#include \"ImportExportFlow.h\"\r\n#include \"UpdateFlow.h\"\r\n#include \"PackageCollection.h\"\r\n#include \"DependenciesFlow.h\"\r\n#include \"WorkflowBase.h\"\r\n#include <winget/RepositorySearch.h>\r\n#include <winget/Runtime.h>\r\n#include <winget/PackageVersionSelection.h>\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    using namespace AppInstaller::Repository;\r\n\r\n    namespace\r\n    {\r\n        SourceDetails GetSourceDetails(const SourceDetails& source)\r\n        {\r\n            return source;\r\n        }\r\n\r\n        SourceDetails GetSourceDetails(const PackageCollection::Source& source)\r\n        {\r\n            return source.Details;\r\n        }\r\n\r\n        SourceDetails GetSourceDetails(const Repository::Source& source)\r\n        {\r\n            return source.GetDetails();\r\n        }\r\n\r\n        // Creates a predicate that determines whether a source matches a description in a SourceDetails.\r\n        template<class T>\r\n        std::function<bool(const T&)> GetSourceDetailsEquivalencePredicate(const SourceDetails& details)\r\n        {\r\n            return [&](const T& source)\r\n            {\r\n                SourceDetails sourceDetails = GetSourceDetails(source);\r\n                return sourceDetails.Type == details.Type && sourceDetails.Identifier == details.Identifier;\r\n            };\r\n        }\r\n\r\n        // Finds a source equivalent to the one specified.\r\n        template<class T>\r\n        typename std::vector<T>::const_iterator FindSource(const std::vector<T>& sources, const SourceDetails& details)\r\n        {\r\n            return std::find_if(sources.begin(), sources.end(), GetSourceDetailsEquivalencePredicate<T>(details));\r\n        }\r\n\r\n        // Finds a source equivalent to the one specified.\r\n        template<class T>\r\n        typename std::vector<T>::iterator FindSource(std::vector<T>& sources, const SourceDetails& details)\r\n        {\r\n            return std::find_if(sources.begin(), sources.end(), GetSourceDetailsEquivalencePredicate<T>(details));\r\n        }\r\n\r\n        // Gets the available version of an installed package.\r\n        // If requested, checks that the installed version is available and reports a warning if it is not.\r\n        std::shared_ptr<IPackageVersion> GetAvailableVersionForInstalledPackage(\r\n            Execution::Context& context,\r\n            std::shared_ptr<ICompositePackage> package,\r\n            Utility::LocIndView version,\r\n            Utility::LocIndView channel,\r\n            bool checkVersion)\r\n        {\r\n            std::shared_ptr<IPackageVersionCollection> availableVersions = GetAvailableVersionsForInstalledVersion(package);\r\n\r\n            if (!checkVersion)\r\n            {\r\n                return availableVersions->GetLatestVersion();\r\n            }\r\n\r\n            auto availablePackageVersion = availableVersions->GetVersion({ \"\", version, channel });\r\n            if (!availablePackageVersion)\r\n            {\r\n                availablePackageVersion = availableVersions->GetLatestVersion();\r\n                if (availablePackageVersion)\r\n                {\r\n                    // Warn installed version is not available.\r\n                    AICLI_LOG(\r\n                        CLI,\r\n                        Info,\r\n                        << \"Installed package version is not available.\"\r\n                        << \" Package Id [\" << availablePackageVersion->GetProperty(PackageVersionProperty::Id) << \"], Version [\" << version << \"], Channel [\" << channel << \"]\"\r\n                        << \". Found Version [\" << availablePackageVersion->GetProperty(PackageVersionProperty::Version) << \"], Channel [\" << availablePackageVersion->GetProperty(PackageVersionProperty::Version) << \"]\");\r\n                    context.Reporter.Warn() << Resource::String::InstalledPackageVersionNotAvailable(availablePackageVersion->GetProperty(PackageVersionProperty::Id), version, channel) << std::endl;\r\n                }\r\n            }\r\n\r\n            return availablePackageVersion;\r\n        }\r\n    }\r\n\r\n    void SelectVersionsToExport(Execution::Context& context)\r\n    {\r\n        const auto& searchResult = context.Get<Execution::Data::SearchResult>();\r\n        const bool includeVersions = context.Args.Contains(Execution::Args::Type::IncludeVersions);\r\n        PackageCollection exportedPackages;\r\n        exportedPackages.ClientVersion = Runtime::GetClientVersion().get();\r\n        auto& exportedSources = exportedPackages.Sources;\r\n        for (const auto& packageMatch : searchResult.Matches)\r\n        {\r\n            auto installedPackageVersion = GetInstalledVersion(packageMatch.Package);\r\n            auto version = installedPackageVersion->GetProperty(PackageVersionProperty::Version);\r\n            auto channel = installedPackageVersion->GetProperty(PackageVersionProperty::Channel);\r\n\r\n            // Find an available version of this package to determine its source.\r\n            auto availablePackageVersion = GetAvailableVersionForInstalledPackage(context, packageMatch.Package, version, channel, includeVersions);\r\n            if (!availablePackageVersion)\r\n            {\r\n                // Report package not found and move to next package.\r\n                AICLI_LOG(CLI, Warning, << \"No available version of package [\" << installedPackageVersion->GetProperty(PackageVersionProperty::Name) << \"] was found to export\");\r\n                context.Reporter.Warn() << Resource::String::InstalledPackageNotAvailable(installedPackageVersion->GetProperty(PackageVersionProperty::Name)) << std::endl;\r\n                continue;\r\n            }\r\n\r\n            const auto& sourceDetails = availablePackageVersion->GetSource().GetDetails();\r\n            AICLI_LOG(CLI, Info,\r\n                << \"Installed package is available. Package Id [\" << availablePackageVersion->GetProperty(PackageVersionProperty::Id) << \"], Source [\" << sourceDetails.Identifier << \"]\");\r\n\r\n            if (!availablePackageVersion->GetManifest().DefaultLocalization.Get<Manifest::Localization::Agreements>().empty())\r\n            {\r\n                // Report that the package requires accepting license terms\r\n                AICLI_LOG(CLI, Warning, << \"Package [\" << installedPackageVersion->GetProperty(PackageVersionProperty::Name) << \"] requires license agreement to install\");\r\n                context.Reporter.Warn() << Resource::String::ExportedPackageRequiresLicenseAgreement(installedPackageVersion->GetProperty(PackageVersionProperty::Name)) << std::endl;\r\n            }\r\n\r\n            // Find the exported source for this package\r\n            auto sourceItr = FindSource(exportedSources, sourceDetails);\r\n            if (sourceItr == exportedSources.end())\r\n            {\r\n                exportedSources.emplace_back(sourceDetails);\r\n                sourceItr = std::prev(exportedSources.end());\r\n            }\r\n\r\n            // Take the Id from the available package because that is the one used in the source,\r\n            // but take the exported version from the installed package if needed.\r\n            PackageCollection::Package exportPackage;\r\n            exportPackage.Id = availablePackageVersion->GetProperty(PackageVersionProperty::Id);\r\n            exportPackage.InstalledLocation = Utility::ConvertToUTF16(installedPackageVersion->GetMetadata()[PackageVersionMetadata::InstalledLocation]);\r\n            if (includeVersions)\r\n            {\r\n                exportPackage.VersionAndChannel = { version.get(), channel.get() };\r\n            }\r\n\r\n            sourceItr->Packages.emplace_back(std::move(exportPackage));\r\n        }\r\n\r\n        context.Add<Execution::Data::PackageCollection>(std::move(exportedPackages));\r\n    }\r\n\r\n    void WriteImportFile(Execution::Context& context)\r\n    {\r\n        auto packages = PackagesJson::CreateJson(context.Get<Execution::Data::PackageCollection>());\r\n\r\n        std::filesystem::path outputFilePath{ context.Args.GetArg(Execution::Args::Type::OutputFile) };\r\n        std::ofstream outputFileStream{ outputFilePath };\r\n        outputFileStream << packages;\r\n    }\r\n\r\n    void ReadImportFile(Execution::Context& context)\r\n    {\r\n        std::ifstream importFile(Utility::ConvertToUTF16(context.Args.GetArg(Execution::Args::Type::ImportFile)));\r\n        THROW_LAST_ERROR_IF(importFile.fail());\r\n\r\n        Json::Value jsonRoot;\r\n        Json::CharReaderBuilder builder;\r\n        Json::String errors;\r\n        if (!Json::parseFromStream(builder, importFile, &jsonRoot, &errors))\r\n        {\r\n            AICLI_LOG(CLI, Error, << \"Failed to read JSON: \" << errors);\r\n            context.Reporter.Error() << Resource::String::InvalidJsonFile << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE);\r\n        }\r\n\r\n        PackagesJson::ParseResult parseResult = PackagesJson::TryParseJson(jsonRoot);\r\n        if (parseResult.Result != PackagesJson::ParseResult::Type::Success)\r\n        {\r\n            context.Reporter.Error() << Resource::String::InvalidJsonFile << std::endl;\r\n            if (parseResult.Result == PackagesJson::ParseResult::Type::MissingSchema ||\r\n                parseResult.Result == PackagesJson::ParseResult::Type::UnrecognizedSchema)\r\n            {\r\n                context.Reporter.Error() << Resource::String::ImportFileHasInvalidSchema << std::endl;\r\n            }\r\n            else if (parseResult.Result == PackagesJson::ParseResult::Type::SchemaValidationFailed)\r\n            {\r\n                context.Reporter.Error() << parseResult.Errors << std::endl;\r\n            }\r\n\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE);\r\n        }\r\n\r\n        PackageCollection& packages = parseResult.Packages;\r\n        if (packages.Sources.empty())\r\n        {\r\n            AICLI_LOG(CLI, Warning, << \"No packages to install\");\r\n            context.Reporter.Info() << Resource::String::NoPackagesFoundInImportFile << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_NO_APPLICATIONS_FOUND);\r\n        }\r\n\r\n        if (context.Args.Contains(Execution::Args::Type::IgnoreVersions))\r\n        {\r\n            // Strip out all the version information as we don't need it.\r\n            for (auto& source : packages.Sources)\r\n            {\r\n                for (auto& package : source.Packages)\r\n                {\r\n                    package.VersionAndChannel = {};\r\n                }\r\n            }\r\n        }\r\n\r\n        context.Add<Execution::Data::PackageCollection>(std::move(packages));\r\n    }\r\n\r\n    void OpenSourcesForImport(Execution::Context& context)\r\n    {\r\n        auto availableSources = Repository::Source::GetCurrentSources();\r\n        for (auto& requiredSource : context.Get<Execution::Data::PackageCollection>().Sources)\r\n        {\r\n            // Find the installed source matching the one described in the collection.\r\n            AICLI_LOG(CLI, Info, << \"Looking for source [\" << requiredSource.Details.Identifier << \"]\");\r\n            auto matchingSource = FindSource(availableSources, requiredSource.Details);\r\n            if (matchingSource != availableSources.end())\r\n            {\r\n                requiredSource.Details.Name = matchingSource->Name;\r\n            }\r\n            else\r\n            {\r\n                AICLI_LOG(CLI, Error, << \"Missing required source: \" << requiredSource.Details.Name);\r\n                context.Reporter.Warn()\r\n                    << Resource::String::ImportSourceNotInstalled(Utility::LocIndView{ requiredSource.Details.Name })\r\n                    << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_SOURCE_NAME_DOES_NOT_EXIST);\r\n            }\r\n\r\n            context << Workflow::OpenNamedSourceForSources(requiredSource.Details.Name);\r\n            if (context.IsTerminated())\r\n            {\r\n                return;\r\n            }\r\n        }\r\n    }\r\n\r\n    void GetSearchRequestsForImport(Execution::Context& context)\r\n    {\r\n        const auto& sources = context.Get<Execution::Data::Sources>();\r\n        std::vector<std::unique_ptr<Execution::Context>> packageSubContexts;\r\n\r\n        // Look for the packages needed from each source independently.\r\n        // If a package is available from multiple sources, this ensures we will get it from the right one.\r\n        for (auto& requiredSource : context.Get<Execution::Data::PackageCollection>().Sources)\r\n        {\r\n            // Find the required source among the open sources. This must exist as we already found them.\r\n            auto sourceItr = FindSource(sources, requiredSource.Details);\r\n            if (sourceItr == sources.end())\r\n            {\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_INTERNAL_ERROR);\r\n            }\r\n\r\n            // Search for all the packages in the source.\r\n            // Each search is done in a sub context to search everything regardless of previous failures.\r\n            Repository::Source source{ context.Get<Execution::Data::Source>(), *sourceItr, CompositeSearchBehavior::AllPackages };\r\n            AICLI_LOG(CLI, Info, << \"Identifying packages requested from source [\" << requiredSource.Details.Identifier << \"]\");\r\n            for (const auto& packageRequest : requiredSource.Packages)\r\n            {\r\n                AICLI_LOG(CLI, Info, << \"Searching for package [\" << packageRequest.Id << \"]\");\r\n\r\n                // Search for the current package\r\n                SearchRequest searchRequest;\r\n                searchRequest.Filters.emplace_back(PackageMatchFilter(PackageMatchField::Id, MatchType::CaseInsensitive, packageRequest.Id.get()));\r\n\r\n                auto searchContextPtr = context.CreateSubContext();\r\n                Execution::Context& searchContext = *searchContextPtr;\r\n                auto previousThreadGlobals = searchContext.SetForCurrentThread();\r\n\r\n                searchContext.Add<Execution::Data::Source>(source);\r\n                searchContext.Add<Execution::Data::SearchRequest>(std::move(searchRequest));\r\n\r\n                if (packageRequest.Scope != Manifest::ScopeEnum::Unknown)\r\n                {\r\n                    // TODO: In the future, it would be better to not have to convert back and forth from a string\r\n                    searchContext.Args.AddArg(Execution::Args::Type::InstallScope, ScopeToString(packageRequest.Scope));\r\n                }\r\n\r\n                auto versionString = packageRequest.VersionAndChannel.GetVersion().ToString();\r\n                if (!versionString.empty())\r\n                {\r\n                    searchContext.Args.AddArg(Execution::Args::Type::Version, versionString);\r\n                }\r\n\r\n                auto channelString = packageRequest.VersionAndChannel.GetChannel().ToString();\r\n                if (!channelString.empty())\r\n                {\r\n                    searchContext.Args.AddArg(Execution::Args::Type::Channel, channelString);\r\n                }\r\n\r\n                packageSubContexts.emplace_back(std::move(searchContextPtr));\r\n            }\r\n        }\r\n\r\n        context.Add<Execution::Data::PackageSubContexts>(std::move(packageSubContexts));\r\n    }\r\n\r\n    void InstallImportedPackages(Execution::Context& context)\r\n    {\r\n        // Inform all dependencies here. During SubContexts processing, dependencies are ignored.\r\n        auto& packageSubContexts = context.Get<Execution::Data::PackageSubContexts>();\r\n        Manifest::DependencyList allDependencies;\r\n        for (auto& packageContext : packageSubContexts)\r\n        {\r\n            allDependencies.Add(packageContext->Get<Execution::Data::Installer>().value().Dependencies);\r\n        }\r\n        context.Add<Execution::Data::Dependencies>(allDependencies);\r\n\r\n        context <<\r\n            ReportDependencies(Resource::String::ImportCommandReportDependencies) <<\r\n            ProcessMultiplePackages(\r\n                Resource::String::ImportCommandReportDependencies, APPINSTALLER_CLI_ERROR_IMPORT_INSTALL_FAILED, ProcessMultiplePackages::Flags::IgnoreDependencies);\r\n\r\n        if (context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_IMPORT_INSTALL_FAILED)\r\n        {\r\n            context.Reporter.Error() << Resource::String::ImportInstallFailed << std::endl;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/ImportExportFlow.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"ExecutionContext.h\"\n\nnamespace AppInstaller::CLI::Workflow\n{\n    // Selects the package versions to list on the exported file\n    // Required Args: None\n    // Inputs: SearchResult\n    // Outputs: PackageCollection\n    void SelectVersionsToExport(Execution::Context& context);\n\n    // Exports a collection of packages to a JSON import file\n    // Required Args: OutputFile\n    // Inputs: PackageCollection\n    // Outputs: None\n    void WriteImportFile(Execution::Context& context);\n\n    // Reads the contents of an import file\n    // Required Args: ImportFile\n    // Inputs: None\n    // Outputs: PackageCollection\n    void ReadImportFile(Execution::Context& context);\n\n    // Opens the sources specified in an import file\n    // Required Args: None\n    // Inputs: PackageCollection\n    // Outputs: Sources\n    void OpenSourcesForImport(Execution::Context& context);\n\n    // Create the search requests and install sub-contexts for all the imported packages.\n    // Needs the sources for all packages and the installed source\n    // Required Args: None\n    // Inputs: PackageCollection, Sources, Source\n    // Outputs: PackageSubContexts\n    //   SubContext Inputs: None\n    //   SubContext Outputs: Source, SearchRequest\n    void GetSearchRequestsForImport(Execution::Context& context);\n\n    // Installs all the packages found in the import file.\n    // Required Args: None\n    // Inputs: PackageSubContexts\n    // Outputs: None\n    void InstallImportedPackages(Execution::Context& context);\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/InstallFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"InstallFlow.h\"\r\n#include \"DownloadFlow.h\"\r\n#include \"FontFlow.h\"\r\n#include \"UninstallFlow.h\"\r\n#include \"UpdateFlow.h\"\r\n#include \"ResumeFlow.h\"\r\n#include \"ShowFlow.h\"\r\n#include \"Resources.h\"\r\n#include \"ShellExecuteInstallerHandler.h\"\r\n#include \"MSStoreInstallerHandler.h\"\r\n#include \"MsiInstallFlow.h\"\r\n#include \"ArchiveFlow.h\"\r\n#include \"PortableFlow.h\"\r\n#include \"WorkflowBase.h\"\r\n#include \"DependenciesFlow.h\"\r\n#include \"PromptFlow.h\"\r\n#include \"SourceFlow.h\"\r\n#include <AppInstallerMsixInfo.h>\r\n#include <AppInstallerDeployment.h>\r\n#include <AppInstallerSynchronization.h>\r\n#include <Argument.h>\r\n#include <Command.h>\r\n#include <winget/ARPCorrelation.h>\r\n#include <winget/Archive.h>\r\n#include <winget/PathVariable.h>\r\n#include <winget/Runtime.h>\r\n\r\nusing namespace winrt::Windows::Foundation;\r\nusing namespace winrt::Windows::Foundation::Collections;\r\nusing namespace winrt::Windows::Management::Deployment;\r\nusing namespace AppInstaller::CLI::Execution;\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Registry::Environment;\r\nusing namespace AppInstaller::Settings;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::Utility::literals;\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    namespace\r\n    {\r\n        bool MightWriteToARP(InstallerTypeEnum type)\r\n        {\r\n            switch (type)\r\n            {\r\n            case InstallerTypeEnum::Exe:\r\n            case InstallerTypeEnum::Burn:\r\n            case InstallerTypeEnum::Inno:\r\n            case InstallerTypeEnum::Msi:\r\n            case InstallerTypeEnum::Nullsoft:\r\n            case InstallerTypeEnum::Wix:\r\n                return true;\r\n            default:\r\n                return false;\r\n            }\r\n        }\r\n\r\n        bool ShouldUseDirectMSIInstall(InstallerTypeEnum type, bool isSilentInstall)\r\n        {\r\n            switch (type)\r\n            {\r\n            case InstallerTypeEnum::Msi:\r\n            case InstallerTypeEnum::Wix:\r\n                return isSilentInstall || ExperimentalFeature::IsEnabled(ExperimentalFeature::Feature::DirectMSI);\r\n            default:\r\n                return false;\r\n            }\r\n        }\r\n\r\n        bool ShouldErrorForUnsupportedArgument(UnsupportedArgumentEnum arg)\r\n        {\r\n            switch (arg)\r\n            {\r\n            case UnsupportedArgumentEnum::Location:\r\n                return true;\r\n            default:\r\n                return false;\r\n            }\r\n        }\r\n\r\n        Execution::Args::Type GetUnsupportedArgumentType(UnsupportedArgumentEnum unsupportedArgument)\r\n        {\r\n            Execution::Args::Type execArg;\r\n\r\n            switch (unsupportedArgument)\r\n            {\r\n            case UnsupportedArgumentEnum::Log:\r\n                execArg = Execution::Args::Type::Log;\r\n                break;\r\n            case UnsupportedArgumentEnum::Location:\r\n                execArg = Execution::Args::Type::InstallLocation;\r\n                break;\r\n            default:\r\n                THROW_HR(E_UNEXPECTED);\r\n            }\r\n\r\n            return execArg;\r\n        }\r\n\r\n        struct ExpectedReturnCode\r\n        {\r\n            ExpectedReturnCode(ExpectedReturnCodeEnum installerReturnCode, HRESULT hr, Resource::StringId message) :\r\n                InstallerReturnCode(installerReturnCode), HResult(hr), Message(message) {}\r\n\r\n            static ExpectedReturnCode GetExpectedReturnCode(ExpectedReturnCodeEnum returnCode)\r\n            {\r\n                switch (returnCode)\r\n                {\r\n                case ExpectedReturnCodeEnum::PackageInUse:\r\n                    return ExpectedReturnCode(returnCode, APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE, Resource::String::InstallFlowReturnCodePackageInUse);\r\n                case ExpectedReturnCodeEnum::PackageInUseByApplication:\r\n                    return ExpectedReturnCode(returnCode, APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE_BY_APPLICATION, Resource::String::InstallFlowReturnCodePackageInUseByApplication);\r\n                case ExpectedReturnCodeEnum::InstallInProgress:\r\n                    return ExpectedReturnCode(returnCode, APPINSTALLER_CLI_ERROR_INSTALL_INSTALL_IN_PROGRESS, Resource::String::InstallFlowReturnCodeInstallInProgress);\r\n                case ExpectedReturnCodeEnum::FileInUse:\r\n                    return ExpectedReturnCode(returnCode, APPINSTALLER_CLI_ERROR_INSTALL_FILE_IN_USE, Resource::String::InstallFlowReturnCodeFileInUse);\r\n                case ExpectedReturnCodeEnum::MissingDependency:\r\n                    return ExpectedReturnCode(returnCode, APPINSTALLER_CLI_ERROR_INSTALL_MISSING_DEPENDENCY, Resource::String::InstallFlowReturnCodeMissingDependency);\r\n                case ExpectedReturnCodeEnum::DiskFull:\r\n                    return ExpectedReturnCode(returnCode, APPINSTALLER_CLI_ERROR_INSTALL_DISK_FULL, Resource::String::InstallFlowReturnCodeDiskFull);\r\n                case ExpectedReturnCodeEnum::InsufficientMemory:\r\n                    return ExpectedReturnCode(returnCode, APPINSTALLER_CLI_ERROR_INSTALL_INSUFFICIENT_MEMORY, Resource::String::InstallFlowReturnCodeInsufficientMemory);\r\n                case ExpectedReturnCodeEnum::InvalidParameter:\r\n                    return ExpectedReturnCode(returnCode, APPINSTALLER_CLI_ERROR_INSTALL_INVALID_PARAMETER, Resource::String::InstallFlowReturnCodeInvalidParameter);\r\n                case ExpectedReturnCodeEnum::NoNetwork:\r\n                    return ExpectedReturnCode(returnCode, APPINSTALLER_CLI_ERROR_INSTALL_NO_NETWORK, Resource::String::InstallFlowReturnCodeNoNetwork);\r\n                case ExpectedReturnCodeEnum::ContactSupport:\r\n                    return ExpectedReturnCode(returnCode, APPINSTALLER_CLI_ERROR_INSTALL_CONTACT_SUPPORT, Resource::String::InstallFlowReturnCodeContactSupport);\r\n                case ExpectedReturnCodeEnum::RebootRequiredToFinish:\r\n                    return ExpectedReturnCode(returnCode, APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_TO_FINISH, Resource::String::InstallFlowReturnCodeRebootRequiredToFinish);\r\n                case ExpectedReturnCodeEnum::RebootRequiredForInstall:\r\n                    return ExpectedReturnCode(returnCode, APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_FOR_INSTALL, Resource::String::InstallFlowReturnCodeRebootRequiredForInstall);\r\n                case ExpectedReturnCodeEnum::RebootInitiated:\r\n                    return ExpectedReturnCode(returnCode, APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_INITIATED, Resource::String::InstallFlowReturnCodeRebootInitiated);\r\n                case ExpectedReturnCodeEnum::CancelledByUser:\r\n                    return ExpectedReturnCode(returnCode, APPINSTALLER_CLI_ERROR_INSTALL_CANCELLED_BY_USER, Resource::String::InstallFlowReturnCodeCancelledByUser);\r\n                case ExpectedReturnCodeEnum::AlreadyInstalled:\r\n                    return ExpectedReturnCode(returnCode, APPINSTALLER_CLI_ERROR_INSTALL_ALREADY_INSTALLED, Resource::String::InstallFlowReturnCodeAlreadyInstalled);\r\n                case ExpectedReturnCodeEnum::Downgrade:\r\n                    return ExpectedReturnCode(returnCode, APPINSTALLER_CLI_ERROR_INSTALL_DOWNGRADE, Resource::String::InstallFlowReturnCodeDowngrade);\r\n                case ExpectedReturnCodeEnum::BlockedByPolicy:\r\n                    return ExpectedReturnCode(returnCode, APPINSTALLER_CLI_ERROR_INSTALL_BLOCKED_BY_POLICY, Resource::String::InstallFlowReturnCodeBlockedByPolicy);\r\n                case ExpectedReturnCodeEnum::SystemNotSupported:\r\n                    return ExpectedReturnCode(returnCode, APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED, Resource::String::InstallFlowReturnCodeSystemNotSupported);\r\n                case ExpectedReturnCodeEnum::Custom:\r\n                    return ExpectedReturnCode(returnCode, APPINSTALLER_CLI_ERROR_INSTALL_CUSTOM_ERROR, Resource::String::InstallFlowReturnCodeCustomError);\r\n                default:\r\n                    THROW_HR(E_UNEXPECTED);\r\n                }\r\n            }\r\n\r\n            ExpectedReturnCodeEnum InstallerReturnCode;\r\n            HRESULT HResult;\r\n            Resource::StringId Message;\r\n        };\r\n\r\n        void CheckForOnlyDependencies(Execution::Context& context)\r\n        {\r\n            if (context.Args.Contains(Execution::Args::Type::DependenciesOnly))\r\n            {\r\n                context.Reporter.Info() << Resource::String::DependenciesOnlyMessage << std::endl;\r\n                // We want the context to terminate, but successfully.\r\n                context.SetTerminationHR(S_OK);\r\n            }\r\n        }\r\n    }\r\n\r\n    namespace details\r\n    {\r\n        // Runs the installer via ShellExecute.\r\n        // Required Args: None\r\n        // Inputs: Installer, InstallerPath\r\n        // Outputs: None\r\n        void ShellExecuteInstall(Execution::Context& context)\r\n        {\r\n            context <<\r\n                GetInstallerArgs <<\r\n                ShellExecuteInstallImpl <<\r\n                ReportInstallerResult(\"ShellExecute\"sv, APPINSTALLER_CLI_ERROR_SHELLEXEC_INSTALL_FAILED);\r\n        }\r\n\r\n        // Runs an MSI installer directly via MSI APIs.\r\n        // Required Args: None\r\n        // Inputs: Installer, InstallerPath\r\n        // Outputs: None\r\n        void DirectMSIInstall(Execution::Context& context)\r\n        {\r\n            context <<\r\n                GetInstallerArgs <<\r\n                DirectMSIInstallImpl <<\r\n                ReportInstallerResult(\"MsiInstallProduct\"sv, APPINSTALLER_CLI_ERROR_MSI_INSTALL_FAILED);\r\n        }\r\n\r\n        // Deploys the MSIX.\r\n        // Required Args: None\r\n        // Inputs: Manifest?, Installer || InstallerPath\r\n        // Outputs: None\r\n        void MsixInstall(Execution::Context& context)\r\n        {\r\n            std::string uri;\r\n            Deployment::Options deploymentOptions;\r\n            if (context.Contains(Execution::Data::InstallerPath))\r\n            {\r\n                uri = context.Get<Execution::Data::InstallerPath>().u8string();\r\n            }\r\n            else\r\n            {\r\n                uri = context.Get<Execution::Data::Installer>()->Url;\r\n                deploymentOptions.ExpectedDigests = context.Get<Execution::Data::MsixDigests>();\r\n            }\r\n\r\n            deploymentOptions.SkipReputationCheck = WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::InstallerTrusted);\r\n\r\n            bool isMachineScope = Manifest::ConvertToScopeEnum(context.Args.GetArg(Execution::Args::Type::InstallScope)) == Manifest::ScopeEnum::Machine;\r\n\r\n            // TODO: There was a bug in deployment api if provision api was called in packaged context.\r\n            // Remove this check when the OS bug is fixed and back ported.\r\n            if (isMachineScope && Runtime::IsRunningInPackagedContext())\r\n            {\r\n                context.Reporter.Error() << Resource::String::InstallFlowReturnCodeSystemNotSupported << std::endl;\r\n                context.Add<Execution::Data::OperationReturnCode>(static_cast<DWORD>(APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED));\r\n                AICLI_LOG(CLI, Error, << \"Device wide install for msix type is not supported in packaged context.\");\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED);\r\n            }\r\n\r\n            context.Reporter.Info() << Resource::String::InstallFlowStartingPackageInstall << std::endl;\r\n\r\n            bool registrationDeferred = false;\r\n\r\n            try\r\n            {\r\n                registrationDeferred = context.Reporter.ExecuteWithProgress([&](IProgressCallback& callback)\r\n                    {\r\n                        if (isMachineScope)\r\n                        {\r\n                            return Deployment::AddPackageMachineScope(uri, deploymentOptions, callback);\r\n                        }\r\n                        else\r\n                        {\r\n                            return Deployment::AddPackageWithDeferredFallback(uri, deploymentOptions, callback);\r\n                        }\r\n                    });\r\n            }\r\n            catch (const wil::ResultException& re)\r\n            {\r\n                context.Add<Execution::Data::OperationReturnCode>(re.GetErrorCode());\r\n                context << ReportInstallerResult(\"MSIX\"sv, re.GetErrorCode(), /* isHResult */ true);\r\n                return;\r\n            }\r\n\r\n            if (registrationDeferred)\r\n            {\r\n                context.Reporter.Warn() << Resource::String::InstallFlowRegistrationDeferred << std::endl;\r\n            }\r\n            else\r\n            {\r\n                context.Reporter.Info() << Resource::String::InstallFlowInstallSuccess << std::endl;\r\n            }\r\n        }\r\n\r\n        // Runs the flow for installing a Portable package.\r\n        // Required Args: None\r\n        // Inputs: Installer, InstallerPath\r\n        // Outputs: None\r\n        void PortableInstall(Execution::Context& context)\r\n        {\r\n            context <<\r\n                InitializePortableInstaller <<\r\n                VerifyPackageAndSourceMatch <<\r\n                PortableInstallImpl <<\r\n                ReportInstallerResult(\"Portable\"sv, APPINSTALLER_CLI_ERROR_PORTABLE_INSTALL_FAILED, true);\r\n        }\r\n\r\n        // Runs the flow for installing a package from an archive.\r\n        // Required Args: None\r\n        // Inputs: Installer, InstallerPath, Manifest\r\n        // Outputs: None\r\n        void ArchiveInstall(Execution::Context& context)\r\n        {\r\n            context <<\r\n                ScanArchiveFromLocalManifest <<\r\n                ExtractFilesFromArchive <<\r\n                VerifyAndSetNestedInstaller <<\r\n                ExecuteInstallerForType(context.Get<Execution::Data::Installer>().value().NestedInstallerType);\r\n        }\r\n\r\n        // Runs the flow for installing a font package.\r\n        // Required Args: None\r\n        // Inputs: Installer, InstallerPath\r\n        // Outputs: None\r\n        void FontInstall(Execution::Context& context)\r\n        {\r\n            context <<\r\n                GetInstallerArgs <<\r\n                FontInstallImpl <<\r\n                ReportInstallerResult(\"Font\"sv, APPINSTALLER_CLI_ERROR_FONT_INSTALL_FAILED, true);\r\n        }\r\n    }\r\n\r\n    bool ExemptFromSingleInstallLocking(InstallerTypeEnum type)\r\n    {\r\n        switch (type)\r\n        {\r\n            // MSStore installs are always MSIX based; MSIX installs are safe to run in parallel.\r\n        case InstallerTypeEnum::Msix:\r\n        case InstallerTypeEnum::MSStore:\r\n            return true;\r\n        default:\r\n            return false;\r\n        }\r\n    }\r\n\r\n    void EnsureApplicableInstaller(Execution::Context& context)\r\n    {\r\n        const auto& installer = context.Get<Execution::Data::Installer>();\r\n\r\n        if (!installer.has_value())\r\n        {\r\n            context.Reporter.Error() << Resource::String::NoApplicableInstallers << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER);\r\n        }\r\n\r\n        context <<\r\n            EnsureSupportForDownload <<\r\n            EnsureSupportForInstall;\r\n    }\r\n\r\n    void CheckForUnsupportedArgs(Execution::Context& context)\r\n    {\r\n        bool messageDisplayed = false;\r\n        const auto& unsupportedArgs = context.Get<Execution::Data::Installer>()->UnsupportedArguments;\r\n        for (auto unsupportedArg : unsupportedArgs)\r\n        {\r\n            const auto& unsupportedArgType = GetUnsupportedArgumentType(unsupportedArg);\r\n            if (context.Args.Contains(unsupportedArgType))\r\n            {\r\n                if (!messageDisplayed)\r\n                {\r\n                    context.Reporter.Warn() << Resource::String::UnsupportedArgument << std::endl;\r\n                    messageDisplayed = true;\r\n                }\r\n\r\n                const auto& executingCommand = context.GetExecutingCommand();\r\n                if (executingCommand != nullptr)\r\n                {\r\n                    const auto& commandArguments = executingCommand->GetArguments();\r\n                    for (const auto& argument : commandArguments)\r\n                    {\r\n                        if (unsupportedArgType == argument.ExecArgType())\r\n                        {\r\n                            const auto& usageString = argument.GetUsageString();\r\n                            if (ShouldErrorForUnsupportedArgument(unsupportedArg))\r\n                            {\r\n                                context.Reporter.Error() << usageString << std::endl;\r\n                                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_UNSUPPORTED_ARGUMENT);\r\n                            }\r\n                            else\r\n                            {\r\n                                context.Reporter.Warn() << usageString << std::endl;\r\n                                break;\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    void ShowInstallationDisclaimer(Execution::Context& context)\r\n    {\r\n        auto installerType = context.Get<Execution::Data::Installer>().value().EffectiveInstallerType();\r\n\r\n        if (installerType == InstallerTypeEnum::MSStore)\r\n        {\r\n            context.Reporter.Info() << Execution::PromptEmphasis << Resource::String::InstallationDisclaimerMSStore << std::endl;\r\n        }\r\n        else\r\n        {\r\n            context.Reporter.Info() <<\r\n                Resource::String::InstallationDisclaimer1 << std::endl <<\r\n                Resource::String::InstallationDisclaimer2 << std::endl;\r\n        }\r\n    }\r\n\r\n    void DisplayInstallationNotes(Execution::Context& context)\r\n    {\r\n        if (!Settings::User().Get<Settings::Setting::DisableInstallNotes>())\r\n        {\r\n            const auto& manifest = context.Get<Execution::Data::Manifest>();\r\n            auto installationNotes = manifest.CurrentLocalization.Get<AppInstaller::Manifest::Localization::InstallationNotes>();\r\n\r\n            if (!installationNotes.empty())\r\n            {\r\n                context.Reporter.Info() << Resource::String::Notes(installationNotes) << std::endl;\r\n            }\r\n        }\r\n    }\r\n\r\n    void ExecuteInstallerForType::operator()(Execution::Context& context) const\r\n    {\r\n        bool isUpdate = WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::InstallerExecutionUseUpdate);\r\n        UpdateBehaviorEnum updateBehavior = context.Get<Execution::Data::Installer>().value().UpdateBehavior;\r\n        bool doUninstallPrevious = isUpdate && (updateBehavior == UpdateBehaviorEnum::UninstallPrevious || context.Args.Contains(Execution::Args::Type::UninstallPrevious));\r\n\r\n        Synchronization::CrossProcessInstallLock lock;\r\n        if (!ExemptFromSingleInstallLocking(m_installerType))\r\n        {\r\n            // Acquire install lock; if the operation is cancelled it will return false so we will also return.\r\n            if (!context.Reporter.ExecuteWithProgress([&](IProgressCallback& callback)\r\n                {\r\n                    callback.SetProgressMessage(Resource::String::InstallWaitingOnAnother());\r\n                    return lock.Acquire(callback);\r\n                }))\r\n            {\r\n                AICLI_LOG(CLI, Info, << \"Abandoning attempt to acquire install lock due to cancellation\");\r\n                return;\r\n            }\r\n        }\r\n\r\n        switch (m_installerType)\r\n        {\r\n        case InstallerTypeEnum::Exe:\r\n        case InstallerTypeEnum::Burn:\r\n        case InstallerTypeEnum::Inno:\r\n        case InstallerTypeEnum::Msi:\r\n        case InstallerTypeEnum::Nullsoft:\r\n        case InstallerTypeEnum::Wix:\r\n            if (doUninstallPrevious)\r\n            {\r\n                context <<\r\n                    GetUninstallInfo <<\r\n                    ExecuteUninstaller;\r\n                context.ClearFlags(Execution::ContextFlag::InstallerExecutionUseUpdate);\r\n            }\r\n            if (ShouldUseDirectMSIInstall(m_installerType, context.Args.Contains(Execution::Args::Type::Silent)))\r\n            {\r\n                context << details::DirectMSIInstall;\r\n            }\r\n            else\r\n            {\r\n                context << details::ShellExecuteInstall;\r\n            }\r\n            break;\r\n        case InstallerTypeEnum::Msix:\r\n            context << details::MsixInstall;\r\n            break;\r\n        case InstallerTypeEnum::MSStore:\r\n            context <<\r\n                EnsureStorePolicySatisfied <<\r\n                (isUpdate ? MSStoreUpdate : MSStoreInstall);\r\n            break;\r\n        case InstallerTypeEnum::Portable:\r\n            if (doUninstallPrevious)\r\n            {\r\n                context <<\r\n                    GetUninstallInfo <<\r\n                    ExecuteUninstaller;\r\n                context.ClearFlags(Execution::ContextFlag::InstallerExecutionUseUpdate);\r\n            }\r\n            context << details::PortableInstall;\r\n            break;\r\n        case InstallerTypeEnum::Zip:\r\n            context << details::ArchiveInstall;\r\n            break;\r\n        case InstallerTypeEnum::Font:\r\n            context << details::FontInstall;\r\n            break;\r\n        default:\r\n            THROW_HR(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED));\r\n        }\r\n    }\r\n\r\n    void EnsureRunningAsAdminForMachineScopeInstall(Execution::Context& context)\r\n    {\r\n        // Admin is required for machine scope install for installer types like portable, msix and msstore.\r\n        auto installerType = context.Get<Execution::Data::Installer>().value().EffectiveInstallerType();\r\n\r\n        if (Manifest::DoesInstallerTypeRequireAdminForMachineScopeInstall(installerType))\r\n        {\r\n            Manifest::ScopeEnum scope = ConvertToScopeEnum(context.Args.GetArg(Execution::Args::Type::InstallScope));\r\n            if (scope == Manifest::ScopeEnum::Machine)\r\n            {\r\n                context << Workflow::EnsureRunningAsAdmin;\r\n            }\r\n        }\r\n    }\r\n\r\n    void ExecuteInstaller(Execution::Context& context)\r\n    {\r\n        context << Workflow::ExecuteInstallerForType(context.Get<Execution::Data::Installer>().value().BaseInstallerType);\r\n    }\r\n\r\n    void ReportInstallerResult::operator()(Execution::Context& context) const\r\n    {\r\n        bool isRepair = WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::InstallerExecutionUseRepair);\r\n\r\n        DWORD installResult = context.Get<Execution::Data::OperationReturnCode>();\r\n        const auto& additionalSuccessCodes = context.Get<Execution::Data::Installer>()->InstallerSuccessCodes;\r\n        if (installResult != 0 && (std::find(additionalSuccessCodes.begin(), additionalSuccessCodes.end(), installResult) == additionalSuccessCodes.end()))\r\n        {\r\n            HRESULT terminationHR = m_hr;\r\n            const auto& expectedReturnCodes = context.Get<Execution::Data::Installer>()->ExpectedReturnCodes;\r\n            auto expectedReturnCodeItr = expectedReturnCodes.find(installResult);\r\n            if (expectedReturnCodeItr != expectedReturnCodes.end() && expectedReturnCodeItr->second.ReturnResponseEnum != ExpectedReturnCodeEnum::Unknown)\r\n            {\r\n                auto returnCode = ExpectedReturnCode::GetExpectedReturnCode(expectedReturnCodeItr->second.ReturnResponseEnum);\r\n                terminationHR = returnCode.HResult;\r\n\r\n                switch (terminationHR)\r\n                {\r\n                case APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_TO_FINISH:\r\n                    // REBOOT_REQUIRED_TO_FINISH is treated as a success since installation has completed but is pending a reboot.\r\n                    context.SetFlags(ContextFlag::RebootRequired);\r\n                    context.Reporter.Warn() << returnCode.Message << std::endl;\r\n                    terminationHR = S_OK;\r\n                    break;\r\n                case APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_FOR_INSTALL:\r\n                    // REBOOT_REQUIRED_FOR_INSTALL is treated as an error since installation has not yet completed.\r\n                    context.SetFlags(ContextFlag::RebootRequired);\r\n                    // TODO: Add separate workflow to handle restart registration for resume.\r\n                    context.SetFlags(ContextFlag::RegisterResume);\r\n                    break;\r\n                }\r\n\r\n                if (FAILED(terminationHR))\r\n                {\r\n                    context.Reporter.Error() << returnCode.Message << std::endl;\r\n                    const auto& returnResponseUrl = expectedReturnCodeItr->second.ReturnResponseUrl;\r\n                    if (!returnResponseUrl.empty())\r\n                    {\r\n                        context.Reporter.Error() << Resource::String::RelatedLink << ' ' << returnResponseUrl << std::endl;\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (FAILED(terminationHR))\r\n            {\r\n                const auto& manifest = context.Get<Execution::Data::Manifest>();\r\n\r\n                if (isRepair)\r\n                {\r\n                    Logging::Telemetry().LogRepairFailure(manifest.Id, manifest.Version, m_installerType, installResult);\r\n                }\r\n                else\r\n                {\r\n                    Logging::Telemetry().LogInstallerFailure(manifest.Id, manifest.Version, manifest.Channel, m_installerType, installResult);\r\n                }\r\n\r\n                if (m_isHResult)\r\n                {\r\n                    context.Reporter.Error()\r\n                        << Resource::String::InstallerFailedWithCode(Utility::LocIndView{ GetUserPresentableMessage(installResult) })\r\n                        << std::endl;\r\n                }\r\n                else\r\n                {\r\n                    context.Reporter.Error()\r\n                        << Resource::String::InstallerFailedWithCode(installResult)\r\n                        << std::endl;\r\n                }\r\n\r\n                // Show installer log path if exists\r\n                if (context.Contains(Execution::Data::LogPath) && std::filesystem::exists(context.Get<Execution::Data::LogPath>()))\r\n                {\r\n                    auto installerLogPath = Utility::LocIndString{ context.Get<Execution::Data::LogPath>().u8string() };\r\n                    context.Reporter.Info() << Resource::String::InstallerLogAvailable(installerLogPath) << std::endl;\r\n                }\r\n\r\n                AICLI_TERMINATE_CONTEXT(terminationHR);\r\n            }\r\n        }\r\n        else\r\n        {\r\n            if (isRepair)\r\n            {\r\n                context.Reporter.Info() << Resource::String::RepairFlowRepairSuccess << std::endl;\r\n            }\r\n            else\r\n            {\r\n                context.Reporter.Info() << Resource::String::InstallFlowInstallSuccess << std::endl;\r\n            }\r\n        }\r\n    }\r\n\r\n    void ReportIdentityAndInstallationDisclaimer(Execution::Context& context)\r\n    {\r\n        context <<\r\n            Workflow::ReportManifestIdentityWithVersion() <<\r\n            Workflow::ShowInstallationDisclaimer;\r\n    }\r\n\r\n    void InstallPackageInstaller(Execution::Context& context)\r\n    {\r\n        context <<\r\n            Workflow::ReportExecutionStage(ExecutionStage::PreExecution) <<\r\n            Workflow::SnapshotARPEntries <<\r\n            Workflow::ReportExecutionStage(ExecutionStage::Execution) <<\r\n            Workflow::ExecuteInstaller <<\r\n            Workflow::ReportExecutionStage(ExecutionStage::PostExecution) <<\r\n            Workflow::ReportARPChanges <<\r\n            Workflow::RecordInstall <<\r\n            Workflow::ForceInstalledCacheUpdate <<\r\n            Workflow::RemoveInstaller <<\r\n            Workflow::DisplayInstallationNotes;\r\n    }\r\n\r\n    void InstallDependencies(Execution::Context& context)\r\n    {\r\n        using Flags = ProcessMultiplePackages::Flags;\r\n\r\n        if (Settings::User().Get<Settings::Setting::InstallSkipDependencies>() || context.Args.Contains(Execution::Args::Type::SkipDependencies))\r\n        {\r\n            context.Reporter.Warn() << Resource::String::DependenciesSkippedMessage << std::endl;\r\n            return;\r\n        }\r\n\r\n        context <<\r\n            GetDependenciesFromInstaller <<\r\n            ReportDependencies(Resource::String::PackageRequiresDependencies) <<\r\n            EnableWindowsFeaturesDependencies <<\r\n            ProcessMultiplePackages(Resource::String::PackageRequiresDependencies, APPINSTALLER_CLI_ERROR_INSTALL_DEPENDENCIES, Flags::IgnoreDependencies | Flags::StopOnFailure | Flags::RefreshPathVariable);\r\n    }\r\n\r\n    void DownloadPackageDependencies(Execution::Context& context)\r\n    {\r\n        using Flags = ProcessMultiplePackages::Flags;\r\n\r\n        if (Settings::User().Get<Settings::Setting::InstallSkipDependencies>() || context.Args.Contains(Execution::Args::Type::SkipDependencies))\r\n        {\r\n            context.Reporter.Warn() << Resource::String::DependenciesSkippedMessage << std::endl;\r\n            return;\r\n        }\r\n\r\n        context <<\r\n            GetDependenciesFromInstaller <<\r\n            ReportDependencies(Resource::String::PackageRequiresDependencies) <<\r\n            CreateDependencySubContexts(Resource::String::PackageRequiresDependencies) <<\r\n            ProcessMultiplePackages(Resource::String::PackageRequiresDependencies, APPINSTALLER_CLI_ERROR_DOWNLOAD_DEPENDENCIES, Flags::IgnoreDependencies | Flags::StopOnFailure | Flags::DownloadOnly);\r\n    }\r\n\r\n    void InstallSinglePackage(Execution::Context& context)\r\n    {\r\n        context <<\r\n            Workflow::CheckForUnsupportedArgs <<\r\n            Workflow::ReportIdentityAndInstallationDisclaimer <<\r\n            Workflow::ShowPromptsForSinglePackage(/* ensureAcceptance */ true) <<\r\n            Workflow::CreateDependencySubContexts(Resource::String::PackageRequiresDependencies) <<\r\n            Workflow::InstallDependencies <<\r\n            CheckForOnlyDependencies <<\r\n            Workflow::DownloadInstaller <<\r\n            Workflow::InstallPackageInstaller <<\r\n            Workflow::RegisterStartupAfterReboot();\r\n    }\r\n\r\n    void EnsureSupportForInstall(Execution::Context& context)\r\n    {\r\n        if (WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::InstallerDownloadOnly))\r\n        {\r\n            return;\r\n        }\r\n\r\n        const auto& installer = context.Get<Execution::Data::Installer>();\r\n\r\n        // This check is only necessary for the Repair workflow when operating on an installer with RepairBehavior set to Installer.\r\n        if (WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::InstallerExecutionUseRepair))\r\n        {\r\n            if (installer->RepairBehavior != RepairBehaviorEnum::Installer)\r\n            {\r\n                return;\r\n            }\r\n\r\n            // At present, the installer repair behavior scenario is restricted to Exe, Inno, Nullsoft, and Burn installer types.\r\n            if (!DoesInstallerTypeRequireRepairBehaviorForRepair(installer->EffectiveInstallerType()))\r\n            {\r\n                return;\r\n            }\r\n        }\r\n\r\n        // This installer cannot be run elevated, but we are running elevated.\r\n        // Implementation of de-elevation is complex; simply block for now.\r\n        if (installer->ElevationRequirement == ElevationRequirementEnum::ElevationProhibited && Runtime::IsRunningAsAdmin())\r\n        {\r\n            AICLI_LOG(CLI, Error, << \"The installer cannot be run from an administrator context.\");\r\n            context.Reporter.Error() << Resource::String::InstallerProhibitsElevation << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_INSTALLER_PROHIBITS_ELEVATION);\r\n        }\r\n\r\n        // This installer cannot be used to upgrade the currently installed application\r\n        // Because the upgrade mechanism may be package-specific, simply block.\r\n        bool isUpdate = WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::InstallerExecutionUseUpdate);\r\n        UpdateBehaviorEnum updateBehavior = installer->UpdateBehavior;\r\n        if (isUpdate && (updateBehavior == UpdateBehaviorEnum::Deny))\r\n        {\r\n            AICLI_LOG(CLI, Error, << \"Manifest specifies update behavior is denied. The attempt will be cancelled.\");\r\n            context.Reporter.Error() << Resource::String::UpgradeBlockedByManifest << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_INSTALL_UPGRADE_NOT_SUPPORTED);\r\n        }\r\n\r\n        context <<\r\n            Workflow::EnsureRunningAsAdminForMachineScopeInstall <<\r\n            Workflow::EnsureSupportForPortableInstall <<\r\n            Workflow::EnsureValidNestedInstallerMetadataForArchiveInstall;\r\n    }\r\n\r\n    ProcessMultiplePackages::ProcessMultiplePackages(\r\n        StringResource::StringId dependenciesReportMessage,\r\n        HRESULT resultOnFailure,\r\n        Flags flags,\r\n        std::vector<HRESULT>&& ignorableInstallResults) :\r\n            WorkflowTask(\"ProcessMultiplePackages\"),\r\n            m_dependenciesReportMessage(dependenciesReportMessage),\r\n            m_resultOnFailure(resultOnFailure),\r\n            m_ignorableInstallResults(std::move(ignorableInstallResults))\r\n    {\r\n        // Inverted\r\n        m_ensurePackageAgreements = !WI_IsFlagSet(flags, Flags::SkipPackageAgreements);\r\n\r\n        m_ignorePackageDependencies = WI_IsFlagSet(flags, Flags::IgnoreDependencies);\r\n        m_stopOnFailure = WI_IsFlagSet(flags, Flags::StopOnFailure);\r\n        m_refreshPathVariable = WI_IsFlagSet(flags, Flags::RefreshPathVariable);\r\n        m_downloadOnly = WI_IsFlagSet(flags, Flags::DownloadOnly);\r\n        m_dependenciesOnly = WI_IsFlagSet(flags, Flags::DependenciesOnly);\r\n    }\r\n\r\n    void ProcessMultiplePackages::operator()(Execution::Context& context) const\r\n    {\r\n        if (!context.Contains(Execution::Data::PackageSubContexts))\r\n        {\r\n            return;\r\n        }\r\n\r\n        bool downloadInstallerOnly = m_downloadOnly ? true : WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::InstallerDownloadOnly);\r\n\r\n        // Show all prompts needed for every package before installing anything\r\n        context << Workflow::ShowPromptsForMultiplePackages(m_ensurePackageAgreements, downloadInstallerOnly);\r\n\r\n        if (context.IsTerminated())\r\n        {\r\n            return;\r\n        }\r\n\r\n        auto& packageSubContexts = context.Get<Execution::Data::PackageSubContexts>();\r\n\r\n        // Report dependencies\r\n        if (!m_ignorePackageDependencies)\r\n        {\r\n            DependencyList allDependencies;\r\n\r\n            for (auto& packageContext : packageSubContexts)\r\n            {\r\n                allDependencies.Add(packageContext->Get<Execution::Data::Installer>().value().Dependencies);\r\n            }\r\n\r\n            if (!allDependencies.Empty())\r\n            {\r\n                if (downloadInstallerOnly)\r\n                {\r\n                    context.Reporter.Info() << Resource::String::DependenciesFlowDownload << std::endl;\r\n                }\r\n                else\r\n                {\r\n                    context.Reporter.Info() << Resource::String::DependenciesFlowInstall << std::endl;\r\n                }\r\n            }\r\n\r\n            context.Add<Execution::Data::Dependencies>(allDependencies);\r\n            context << Workflow::ReportDependencies(m_dependenciesReportMessage);\r\n        }\r\n\r\n        bool allSucceeded = true;\r\n        size_t packagesCount = packageSubContexts.size();\r\n        size_t packagesProgress = 0;\r\n\r\n        if (m_dependenciesOnly)\r\n        {\r\n            context.Reporter.Info() << Resource::String::DependenciesOnlyMessage << std::endl;\r\n        }\r\n\r\n        for (auto& packageContext : packageSubContexts)\r\n        {\r\n            packagesProgress++;\r\n            context.Reporter.Info() << '(' << packagesProgress << '/' << packagesCount << \") \"_liv;\r\n\r\n            // We want to do best effort to install all packages regardless of previous failures\r\n            Execution::Context& currentContext = *packageContext;\r\n            auto previousThreadGlobals = currentContext.SetForCurrentThread();\r\n\r\n            currentContext << Workflow::ReportIdentityAndInstallationDisclaimer;\r\n\r\n            // Prevent individual exceptions from breaking out of the loop\r\n            try\r\n            {\r\n                // Handle dependencies if requested.\r\n                if (!m_ignorePackageDependencies && !downloadInstallerOnly)\r\n                {\r\n                    currentContext <<\r\n                        Workflow::EnableWindowsFeaturesDependencies <<\r\n                        Workflow::CreateDependencySubContexts(m_dependenciesReportMessage) <<\r\n                        Workflow::ProcessMultiplePackages(m_dependenciesReportMessage, APPINSTALLER_CLI_ERROR_INSTALL_DEPENDENCIES, Flags::IgnoreDependencies | Flags::StopOnFailure | Flags::RefreshPathVariable);\r\n                }\r\n\r\n                if (!m_dependenciesOnly)\r\n                {\r\n                    currentContext << Workflow::DownloadInstaller;\r\n\r\n                    if (!downloadInstallerOnly)\r\n                    {\r\n                        currentContext << Workflow::InstallPackageInstaller;\r\n                    }\r\n                }\r\n            }\r\n            catch (...)\r\n            {\r\n                currentContext.SetTerminationHR(Workflow::HandleException(currentContext, std::current_exception()));\r\n            }\r\n\r\n            if (m_refreshPathVariable)\r\n            {\r\n                if (RefreshPathVariableForCurrentProcess())\r\n                {\r\n                    AICLI_LOG(CLI, Info, << \"Successfully refreshed process PATH environment variable.\");\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(CLI, Warning, << \"Failed to refresh process PATH environment variable.\");\r\n                    context.Reporter.Warn() << Resource::String::FailedToRefreshPathWarning << std::endl;\r\n                }\r\n            }\r\n\r\n            currentContext.Reporter.Info() << std::endl;\r\n\r\n            if (currentContext.IsTerminated())\r\n            {\r\n                if (context.IsTerminated() && context.GetTerminationHR() == E_ABORT)\r\n                {\r\n                    // This means that the subcontext being terminated is due to an overall abort\r\n                    context.Reporter.Info() << Resource::String::Cancelled << std::endl;\r\n                    return;\r\n                }\r\n\r\n                if (m_ignorableInstallResults.end() == std::find(m_ignorableInstallResults.begin(), m_ignorableInstallResults.end(), currentContext.GetTerminationHR()))\r\n                {\r\n                    allSucceeded = false;\r\n                    if (m_stopOnFailure)\r\n                    {\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        if (!allSucceeded)\r\n        {\r\n            AICLI_TERMINATE_CONTEXT(m_resultOnFailure);\r\n        }\r\n    }\r\n\r\n    void SnapshotARPEntries(Execution::Context& context) try\r\n    {\r\n        // Ensure that installer type might actually write to ARP, otherwise this is a waste of time\r\n        auto installer = context.Get<Execution::Data::Installer>();\r\n\r\n        if (installer && MightWriteToARP(installer->EffectiveInstallerType()))\r\n        {\r\n            Repository::Correlation::ARPCorrelationData data;\r\n            data.CapturePreInstallSnapshot();\r\n            context.Add<Execution::Data::ARPCorrelationData>(std::move(data));\r\n        }\r\n    }\r\n    CATCH_LOG()\r\n\r\n    void ReportARPChanges(Execution::Context& context) try\r\n    {\r\n        if (!context.Contains(Execution::Data::ARPCorrelationData))\r\n        {\r\n            return;\r\n        }\r\n\r\n        // If the installer claims to have a PackageFamilyName, and that family name is currently registered for the user,\r\n        // let that be the correlated item and skip any attempt at further ARP correlation.\r\n        const auto& installer = context.Get<Execution::Data::Installer>();\r\n\r\n        if (installer && !installer->PackageFamilyName.empty() && Deployment::IsRegistered(installer->PackageFamilyName))\r\n        {\r\n            return;\r\n        }\r\n\r\n        const auto& manifest = context.Get<Execution::Data::Manifest>();\r\n        auto& arpCorrelationData = context.Get<Execution::Data::ARPCorrelationData>();\r\n\r\n        arpCorrelationData.CapturePostInstallSnapshot();\r\n        auto correlationResult = arpCorrelationData.CorrelateForNewlyInstalled(manifest);\r\n\r\n        // Store the ARP entry found to match the package to record it in the tracking catalog later\r\n        if (correlationResult.Package)\r\n        {\r\n            std::vector<AppsAndFeaturesEntry> entries;\r\n\r\n            auto metadata = correlationResult.Package->GetMetadata();\r\n\r\n            AppsAndFeaturesEntry baseEntry;\r\n\r\n            // Display name and publisher are also available as multi properties, but\r\n            // for ARP there will always be only 0 or 1 values.\r\n            baseEntry.DisplayName = correlationResult.Package->GetProperty(PackageVersionProperty::Name).get();\r\n            baseEntry.Publisher = correlationResult.Package->GetProperty(PackageVersionProperty::Publisher).get();\r\n            baseEntry.DisplayVersion = correlationResult.Package->GetProperty(PackageVersionProperty::Version).get();\r\n            baseEntry.InstallerType = Manifest::ConvertToInstallerTypeEnum(metadata[PackageVersionMetadata::InstalledType]);\r\n\r\n            auto productCodes = correlationResult.Package->GetMultiProperty(PackageVersionMultiProperty::ProductCode);\r\n            for (auto&& productCode : productCodes)\r\n            {\r\n                AppsAndFeaturesEntry entry = baseEntry;\r\n                entry.ProductCode = std::move(productCode).get();\r\n                entries.push_back(std::move(entry));\r\n            }\r\n\r\n            auto upgradeCodes = correlationResult.Package->GetMultiProperty(PackageVersionMultiProperty::UpgradeCode);\r\n            for (auto&& upgradeCode : upgradeCodes)\r\n            {\r\n                AppsAndFeaturesEntry entry = baseEntry;\r\n                entry.UpgradeCode = std::move(upgradeCode).get();\r\n                entries.push_back(std::move(entry));\r\n            }\r\n\r\n            context.Add<Data::CorrelatedAppsAndFeaturesEntries>(std::move(entries));\r\n        }\r\n\r\n        // We can only get the source identifier from an active source\r\n        std::string sourceIdentifier;\r\n        if (context.Contains(Execution::Data::PackageVersion))\r\n        {\r\n            sourceIdentifier = context.Get<Execution::Data::PackageVersion>()->GetProperty(PackageVersionProperty::SourceIdentifier);\r\n        }\r\n\r\n        IPackageVersion::Metadata arpEntryMetadata;\r\n        if (correlationResult.Package)\r\n        {\r\n            arpEntryMetadata = correlationResult.Package->GetMetadata();\r\n        }\r\n\r\n        Logging::Telemetry().LogSuccessfulInstallARPChange(\r\n            sourceIdentifier,\r\n            manifest.Id,\r\n            manifest.Version,\r\n            manifest.Channel,\r\n            correlationResult.ChangesToARP,\r\n            correlationResult.MatchesInARP,\r\n            correlationResult.CountOfIntersectionOfChangesAndMatches,\r\n            correlationResult.Package ? static_cast<std::string>(correlationResult.Package->GetProperty(PackageVersionProperty::Name)) : \"\",\r\n            correlationResult.Package ? static_cast<std::string>(correlationResult.Package->GetProperty(PackageVersionProperty::Version)) : \"\",\r\n            correlationResult.Package ? static_cast<std::string>(correlationResult.Package->GetProperty(PackageVersionProperty::Publisher)) : \"\",\r\n            correlationResult.Package ? static_cast<std::string_view>(arpEntryMetadata[PackageVersionMetadata::InstalledLocale]) : \"\"\r\n        );\r\n    }\r\n    CATCH_LOG();\r\n\r\n    void RecordInstall(Context& context)\r\n    {\r\n        // Local manifest installs won't have a package version, and tracking them doesn't provide much\r\n        // value currently. If we ever do use our own database as a primary source of packages that we\r\n        // maintain, this decision will probably have to be reconsidered.\r\n        if (!context.Contains(Data::PackageVersion))\r\n        {\r\n            return;\r\n        }\r\n\r\n        auto manifest = context.Get<Data::Manifest>();\r\n\r\n        // If we have determined an ARP entry matches the installed package,\r\n        // we set its product code in the manifest we record to ensure we can\r\n        // find it in the future.\r\n        // Note that this may overwrite existing information.\r\n        if (context.Contains(Data::CorrelatedAppsAndFeaturesEntries))\r\n        {\r\n            // Use a new Installer entry\r\n            manifest.Installers.emplace_back();\r\n            manifest.Installers.back().AppsAndFeaturesEntries = context.Get<Data::CorrelatedAppsAndFeaturesEntries>();\r\n        }\r\n\r\n        auto trackingCatalog = context.Get<Data::PackageVersion>()->GetSource().GetTrackingCatalog();\r\n\r\n        auto version = trackingCatalog.RecordInstall(\r\n            manifest,\r\n            context.Get<Data::Installer>().value(),\r\n            WI_IsFlagSet(context.GetFlags(), ContextFlag::InstallerExecutionUseUpdate));\r\n\r\n        // Record user intent values. Command args takes precedence. Then previous user intent values.\r\n        Repository::IPackageVersion::Metadata installedMetadata;\r\n        if (context.Contains(Data::InstalledPackageVersion) && context.Get<Execution::Data::InstalledPackageVersion>())\r\n        {\r\n            installedMetadata = context.Get<Data::InstalledPackageVersion>()->GetMetadata();\r\n        }\r\n\r\n        if (context.Args.Contains(Execution::Args::Type::InstallArchitecture))\r\n        {\r\n            version.SetMetadata(Repository::PackageVersionMetadata::UserIntentArchitecture, context.Args.GetArg(Execution::Args::Type::InstallArchitecture));\r\n        }\r\n        else\r\n        {\r\n            auto itr = installedMetadata.find(Repository::PackageVersionMetadata::UserIntentArchitecture);\r\n            if (itr != installedMetadata.end())\r\n            {\r\n                version.SetMetadata(Repository::PackageVersionMetadata::UserIntentArchitecture, itr->second);\r\n            }\r\n        }\r\n\r\n        if (context.Args.Contains(Execution::Args::Type::Locale))\r\n        {\r\n            version.SetMetadata(Repository::PackageVersionMetadata::UserIntentLocale, context.Args.GetArg(Execution::Args::Type::Locale));\r\n        }\r\n        else\r\n        {\r\n            auto itr = installedMetadata.find(Repository::PackageVersionMetadata::UserIntentLocale);\r\n            if (itr != installedMetadata.end())\r\n            {\r\n                version.SetMetadata(Repository::PackageVersionMetadata::UserIntentLocale, itr->second);\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/InstallFlow.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ExecutionContext.h\"\r\n#include <winget/Manifest.h>\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    using namespace std::string_view_literals;\r\n\r\n    // Token specified in installer args will be replaced by proper value.\r\n    static constexpr std::string_view ARG_TOKEN_LOGPATH = \"<LOGPATH>\"sv;\r\n    static constexpr std::string_view ARG_TOKEN_INSTALLPATH = \"<INSTALLPATH>\"sv;\r\n\r\n    // Determines if an installer type is allowed to install/uninstall in parallel.\r\n    bool ExemptFromSingleInstallLocking(AppInstaller::Manifest::InstallerTypeEnum type);\r\n\r\n    namespace details\r\n    {\r\n        // These single type install flows should remain \"internal\" and only ExecuteInstallerForType should be used externally\r\n        // so that all installs can properly handle single install locking.\r\n\r\n        // Runs the installer via ShellExecute.\r\n        // Required Args: None\r\n        // Inputs: Installer, InstallerPath\r\n        // Outputs: None\r\n        void ShellExecuteInstall(Execution::Context& context);\r\n\r\n        // Runs an MSI installer directly via MSI APIs.\r\n        // Required Args: None\r\n        // Inputs: Installer, InstallerPath\r\n        // Outputs: None\r\n        void DirectMSIInstall(Execution::Context& context);\r\n\r\n        // Deploys the MSIX.\r\n        // Required Args: None\r\n        // Inputs: Manifest?, Installer || InstallerPath\r\n        // Outputs: None\r\n        void MsixInstall(Execution::Context& context);\r\n\r\n        // Runs the flow for installing a Portable package.\r\n        // Required Args: None\r\n        // Inputs: Installer, InstallerPath\r\n        // Outputs: None\r\n        void PortableInstall(Execution::Context& context);\r\n\r\n        // Runs the flow for installing a package from an archive.\r\n        // Required Args: None\r\n        // Inputs: Installer, InstallerPath, Manifest\r\n        // Outputs: None\r\n        void ArchiveInstall(Execution::Context& context);\r\n\r\n        // Runs the flow for installing a font package.\r\n        // Required Args: None\r\n        // Inputs: Installer, InstallerPath, Manifest\r\n        // Outputs: None\r\n        void FontInstall(Execution::Context& context);\r\n    }\r\n\r\n    // Ensures that there is an applicable installer.\r\n    // Required Args: None\r\n    // Inputs: Installer\r\n    // Outputs: None\r\n    void EnsureApplicableInstaller(Execution::Context& context);\r\n\r\n    // Shows the installation disclaimer.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: None\r\n    void ShowInstallationDisclaimer(Execution::Context& context);\r\n\r\n    // Displays the installations notes after a successful install.\r\n    // Required Args: None\r\n    // Inputs: InstallationNotes\r\n    // Outputs: None\r\n    void DisplayInstallationNotes(Execution::Context& context);\r\n    \r\n    // Checks if there are any included arguments that are not supported for the package.\r\n    // Required Args: None\r\n    // Inputs: Installer\r\n    // Outputs: None\r\n    void CheckForUnsupportedArgs(Execution::Context& context);\r\n\r\n    // Admin is required for machine scope install for installer types like portable, msix and msstore.\r\n    // Required Args: None\r\n    // Inputs: Installer\r\n    // Outputs: None\r\n    void EnsureRunningAsAdminForMachineScopeInstall(Execution::Context& context);\r\n\r\n    // Composite flow that chooses what to do based on the installer type.\r\n    // Required Args: None\r\n    // Inputs: Installer, InstallerPath\r\n    // Outputs: None\r\n    void ExecuteInstaller(Execution::Context& context);\r\n\r\n    // Composite flow that chooses what to do based on the installer type.\r\n    // Required Args: None\r\n    // Inputs: Installer, InstallerPath\r\n    // Outputs: None\r\n    struct ExecuteInstallerForType : public WorkflowTask\r\n    {\r\n        ExecuteInstallerForType(Manifest::InstallerTypeEnum installerType) : WorkflowTask(\"ExecuteInstallerForType\"), m_installerType(installerType) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        Manifest::InstallerTypeEnum m_installerType;\r\n    };\r\n\r\n    // Verifies parameters for install to ensure success.\r\n    // Required Args: None\r\n    // Inputs: \r\n    // Outputs: None\r\n    void EnsureSupportForInstall(Execution::Context& context);\r\n\r\n    // Reports the return code returned by the installer.\r\n    // Required Args: None\r\n    // Inputs: Manifest, Installer, InstallerResult\r\n    // Outputs: None\r\n    struct ReportInstallerResult : public WorkflowTask\r\n    {\r\n        ReportInstallerResult(std::string_view installerType, HRESULT hr, bool isHResult = false) :\r\n            WorkflowTask(\"ReportInstallerResult\"),\r\n            m_installerType(installerType),\r\n            m_hr(hr),\r\n            m_isHResult(isHResult) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        // Installer type used when reporting failures.\r\n        std::string_view m_installerType;\r\n        // Result to return if the installer failed.\r\n        HRESULT m_hr;\r\n        // Whether the installer result is an HRESULT. This guides how we show it.\r\n        bool m_isHResult;\r\n    };\r\n\r\n    // Reports manifest identity and shows installation disclaimer\r\n    // Required Args: None\r\n    // Inputs: Manifest\r\n    // Outputs: None\r\n    void ReportIdentityAndInstallationDisclaimer(Execution::Context& context);\r\n\r\n    // Installs a specific package installer. See also InstallSinglePackage & ProcessMultiplePackages\r\n    // Required Args: None\r\n    // Inputs: InstallerPath, Manifest, Installer, PackageVersion, InstalledPackageVersion?\r\n    // Outputs: None\r\n    void InstallPackageInstaller(Execution::Context& context);\r\n    \r\n    // Installs the dependencies for a specific package. CreateDependencySubContexts should have been called before this task.\r\n    // Required Args: None\r\n    // Inputs: InstallerPath, Manifest, Installer, PackageVersion, InstalledPackageVersion?\r\n    // Outputs: None\r\n    void InstallDependencies(Execution::Context& context);\r\n\r\n    // Downloads all of the package dependencies of a specific package. Only used in the 'winget download' and COM download flows.\r\n    // Required Args: none\r\n    // Inputs: Manifest, Installer\r\n    // Outputs: None\r\n    void DownloadPackageDependencies(Execution::Context& context);\r\n\r\n    // Installs a single package. This also does the reporting, user interaction, and installer download\r\n    // for single-package installation.\r\n    // RequiredArgs: None\r\n    // Inputs: Manifest, Installer, PackageVersion, InstalledPackageVersion?\r\n    // Outputs: None\r\n    void InstallSinglePackage(Execution::Context& context);\r\n\r\n    // Processes multiple packages by handling download and/or install. This also does the reporting and user interaction needed.\r\n    // Required Args: None\r\n    // Inputs: PackageSubContexts\r\n    // Outputs: None\r\n    struct ProcessMultiplePackages : public WorkflowTask\r\n    {\r\n        // Flags to signal change from default behavior of the task.\r\n        enum class Flags : uint32_t\r\n        {\r\n            None =                  0x00,\r\n            SkipPackageAgreements = 0x01,\r\n            IgnoreDependencies =    0x02,\r\n            StopOnFailure =         0x04,\r\n            RefreshPathVariable =   0x08,\r\n            DownloadOnly =          0x10,\r\n            DependenciesOnly =      0x20,\r\n        };\r\n\r\n        ProcessMultiplePackages(\r\n            StringResource::StringId dependenciesReportMessage,\r\n            HRESULT resultOnFailure,\r\n            Flags flags = Flags::None,\r\n            std::vector<HRESULT>&& ignorableInstallResults = {});\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        HRESULT m_resultOnFailure;\r\n        std::vector<HRESULT> m_ignorableInstallResults;\r\n        StringResource::StringId m_dependenciesReportMessage;\r\n        bool m_ignorePackageDependencies;\r\n        bool m_ensurePackageAgreements;\r\n        bool m_stopOnFailure;\r\n        bool m_refreshPathVariable;\r\n        bool m_downloadOnly;\r\n        bool m_dependenciesOnly;\r\n    };\r\n\r\n    DEFINE_ENUM_FLAG_OPERATORS(ProcessMultiplePackages::Flags);\r\n\r\n    // Stores the existing set of packages in ARP.\r\n    // Required Args: None\r\n    // Inputs: Installer\r\n    // Outputs: ARPSnapshot\r\n    void SnapshotARPEntries(Execution::Context& context);\r\n\r\n    // Reports on the changes between the stored ARPSnapshot and the current values,\r\n    // and stores the product code of the ARP entry found for the package.\r\n    // Required Args: None\r\n    // Inputs: ARPSnapshot?, Manifest, PackageVersion\r\n    // Outputs: CorrelatedAppsAndFeaturesEntries?\r\n    void ReportARPChanges(Execution::Context& context);\r\n\r\n    // Records the installation to the tracking catalog.\r\n    // Required Args: None\r\n    // Inputs: PackageVersion?, Manifest, Installer, CorrelatedAppsAndFeaturesEntries?\r\n    // Outputs: None\r\n    void RecordInstall(Execution::Context& context);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/MSStoreInstallerHandler.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"MSStoreInstallerHandler.h\"\r\n#include \"WorkflowBase.h\"\r\n#include <AppInstallerSHA256.h>\r\n#include <AppInstallerDownloader.h>\r\n#include <AppInstallerRuntime.h>\r\n#include <winget/Filesystem.h>\r\n#include <winget/MSStore.h>\r\n#include <winget/MSStoreDownload.h>\r\n#include <winget/SelfManagement.h>\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    void DownloadInstallerFile(Execution::Context& context);\r\n}\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    using namespace AppInstaller::MSStore;\r\n    using namespace AppInstaller::SelfManagement;\r\n    using namespace winrt::Windows::Foundation;\r\n    using namespace winrt::Windows::Foundation::Collections;\r\n    using namespace winrt::Windows::ApplicationModel::Store::Preview::InstallControl;\r\n\r\n    namespace\r\n    {\r\n        Utility::LocIndString GetErrorCodeString(const HRESULT errorCode)\r\n        {\r\n            std::ostringstream ssError;\r\n            ssError << WINGET_OSTREAM_FORMAT_HRESULT(errorCode);\r\n            return Utility::LocIndString{ ssError.str() };\r\n        }\r\n\r\n        HRESULT EnsureStorePolicySatisfiedImpl(const std::wstring& productId, bool bypassPolicy)\r\n        {\r\n            constexpr std::wstring_view s_StoreClientName = L\"Microsoft.WindowsStore\"sv;\r\n            constexpr std::wstring_view s_StoreClientPublisher = L\"CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US\"sv;\r\n\r\n            // Policy check\r\n            AppInstallManager installManager;\r\n\r\n            if (!bypassPolicy && installManager.IsStoreBlockedByPolicyAsync(s_StoreClientName, s_StoreClientPublisher).get())\r\n            {\r\n                AICLI_LOG(CLI, Error, << \"Store client is blocked by policy. MSStore execution failed.\");\r\n                return APPINSTALLER_CLI_ERROR_MSSTORE_BLOCKED_BY_POLICY;\r\n            }\r\n\r\n            if (!installManager.GetIsAppAllowedToInstallAsync(productId).get())\r\n            {\r\n                AICLI_LOG(CLI, Error, << \"App is blocked by policy. MSStore execution failed. ProductId: \" << Utility::ConvertToUTF8(productId));\r\n                return APPINSTALLER_CLI_ERROR_MSSTORE_APP_BLOCKED_BY_POLICY;\r\n            }\r\n\r\n            return S_OK;\r\n        }\r\n\r\n        void AppInstallerUpdate(bool preferStub, bool bypassPolicy, Execution::Context& context)\r\n        {\r\n            auto appInstId = std::wstring{ s_AppInstallerProductId };\r\n            THROW_IF_FAILED(EnsureStorePolicySatisfiedImpl(appInstId, bypassPolicy));\r\n            SetStubPreferred(preferStub);\r\n\r\n            auto installOperation = MSStoreOperation(MSStoreOperationType::Update, appInstId, Manifest::ScopeEnum::User, true, true);\r\n\r\n            HRESULT hr = S_OK;\r\n            context.Reporter.ExecuteWithProgress(\r\n                [&](IProgressCallback& progress)\r\n                {\r\n                    hr = installOperation.StartAndWaitForOperation(progress);\r\n                });\r\n\r\n            THROW_IF_FAILED(hr);\r\n        }\r\n\r\n        HRESULT DownloadMSStorePackageFile(const MSStore::MSStoreDownloadFile& downloadFile, const std::filesystem::path& downloadDirectory, Execution::Context& context)\r\n        {\r\n            try\r\n            {\r\n                // Create a sub context to execute the package download\r\n                auto subContextPtr = context.CreateSubContext();\r\n                Execution::Context& subContext = *subContextPtr;\r\n                auto previousThreadGlobals = subContext.SetForCurrentThread();\r\n\r\n                // Populate Installer and temp download path for sub context\r\n                Manifest::ManifestInstaller installer;\r\n                installer.Url = downloadFile.Url;\r\n                installer.Sha256 = downloadFile.Sha256;\r\n                subContext.Add<Execution::Data::Installer>(std::move(installer));\r\n\r\n                auto tempInstallerPath = Runtime::GetPathTo(Runtime::PathName::Temp);\r\n                tempInstallerPath /= Utility::SHA256::ConvertToString(downloadFile.Sha256);\r\n                AICLI_LOG(CLI, Info, << \"Generated temp download path: \" << tempInstallerPath);\r\n                subContext.Add<Execution::Data::InstallerPath>(tempInstallerPath);\r\n\r\n                subContext << Workflow::DownloadInstallerFile;\r\n                if (subContext.IsTerminated())\r\n                {\r\n                    RETURN_HR(subContext.GetTerminationHR());\r\n                }\r\n\r\n                // Verify hash\r\n                const auto& hashPair = subContext.Get<Execution::Data::DownloadHashInfo>();\r\n                if (std::equal(hashPair.first.begin(), hashPair.first.end(), hashPair.second.Sha256Hash.begin()))\r\n                {\r\n                    AICLI_LOG(CLI, Info, << \"Microsoft Store package hash verified\");\r\n                    subContext.Reporter.Info() << Resource::String::MSStoreDownloadPackageHashVerified << std::endl;\r\n                    // Trust direct download from Store if hash matched\r\n                    Utility::ApplyMotwIfApplicable(tempInstallerPath, URLZONE_TRUSTED);\r\n                }\r\n                else\r\n                {\r\n                    if (!subContext.Args.Contains(Execution::Args::Type::HashOverride))\r\n                    {\r\n                        AICLI_LOG(CLI, Error, << \"Microsoft Store package hash mismatch\");\r\n                        subContext.Reporter.Error() << Resource::String::MSStoreDownloadPackageHashMismatch << std::endl;\r\n                        RETURN_HR(APPINSTALLER_CLI_ERROR_INSTALLER_HASH_MISMATCH);\r\n                    }\r\n                    else\r\n                    {\r\n                        AICLI_LOG(CLI, Warning, << \"Microsoft Store package hash mismatch, but overridden.\");\r\n                        subContext.Reporter.Warn() << Resource::String::MSStoreDownloadPackageHashMismatch << std::endl;\r\n                    }\r\n                }\r\n\r\n                auto renamedDownloadedPackage = downloadDirectory / Utility::ConvertToUTF16(downloadFile.FileName);\r\n                Filesystem::RenameFile(tempInstallerPath, renamedDownloadedPackage);\r\n                subContext.Reporter.Info() << Resource::String::MSStoreDownloadPackageDownloaded(Utility::LocIndView{ renamedDownloadedPackage.u8string() }) << std::endl;\r\n\r\n                return S_OK;\r\n            }\r\n            catch (...)\r\n            {\r\n                AICLI_LOG(CLI, Error, << \"Microsoft Store package download failed. File: \" << downloadFile.FileName);\r\n                context.Reporter.Error() << Resource::String::MSStoreDownloadPackageDownloadFailed(Utility::LocIndView{ downloadFile.FileName }) << std::endl;\r\n                RETURN_HR(APPINSTALLER_CLI_ERROR_DOWNLOAD_FAILED);\r\n            }\r\n        }\r\n    }\r\n\r\n    void MSStoreInstall(Execution::Context& context)\r\n    {\r\n        auto productId = Utility::ConvertToUTF16(context.Get<Execution::Data::Installer>()->ProductId);\r\n        auto scope = Manifest::ConvertToScopeEnum(context.Args.GetArg(Execution::Args::Type::InstallScope));\r\n        bool isSilentMode = context.Args.Contains(Execution::Args::Type::Silent);\r\n        bool force = context.Args.Contains(Execution::Args::Type::Force);\r\n\r\n        auto installOperation = MSStoreOperation(MSStoreOperationType::Install, productId, scope, isSilentMode, force);\r\n\r\n        context.Reporter.Info() << Resource::String::InstallFlowStartingPackageInstall << std::endl;\r\n\r\n        HRESULT hr = S_OK;\r\n        context.Reporter.ExecuteWithProgress(\r\n            [&](IProgressCallback& progress)\r\n            {\r\n                hr = installOperation.StartAndWaitForOperation(progress);\r\n            });\r\n\r\n        if (SUCCEEDED(hr))\r\n        {\r\n            context.Reporter.Info() << Resource::String::InstallFlowInstallSuccess << std::endl;\r\n        }\r\n        else\r\n        {\r\n            if (hr == APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED)\r\n            {\r\n                context.Reporter.Error() << Resource::String::InstallFlowReturnCodeSystemNotSupported << std::endl;\r\n                context.Add<Execution::Data::OperationReturnCode>(static_cast<DWORD>(APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED));\r\n            }\r\n            else\r\n            {\r\n                auto errorCodeString = GetErrorCodeString(hr);\r\n                context.Reporter.Error() << Resource::String::MSStoreInstallOrUpdateFailed(errorCodeString) << std::endl;\r\n                context.Add<Execution::Data::OperationReturnCode>(hr);\r\n                AICLI_LOG(CLI, Error, << \"MSStore install failed. ProductId: \" << Utility::ConvertToUTF8(productId) << \" HResult: \" << errorCodeString);\r\n            }\r\n\r\n            AICLI_TERMINATE_CONTEXT(hr);\r\n        }\r\n    }\r\n\r\n    void MSStoreUpdate(Execution::Context& context)\r\n    {\r\n        bool isSilentMode = context.Args.Contains(Execution::Args::Type::Silent);\r\n        auto productId = Utility::ConvertToUTF16(context.Get<Execution::Data::Installer>()->ProductId);\r\n        auto scope = Manifest::ConvertToScopeEnum(context.Args.GetArg(Execution::Args::Type::InstallScope));\r\n        bool force = context.Args.Contains(Execution::Args::Type::Force);\r\n\r\n        auto installOperation = MSStoreOperation(MSStoreOperationType::Update, productId, scope, isSilentMode, force);\r\n\r\n        context.Reporter.Info() << Resource::String::InstallFlowStartingPackageInstall << std::endl;\r\n\r\n        HRESULT hr = S_OK;\r\n        context.Reporter.ExecuteWithProgress(\r\n            [&](IProgressCallback& progress)\r\n            {\r\n                hr = installOperation.StartAndWaitForOperation(progress);\r\n            });\r\n\r\n        if (SUCCEEDED(hr))\r\n        {\r\n            context.Reporter.Info() << Resource::String::InstallFlowInstallSuccess << std::endl;\r\n        }\r\n        else\r\n        {\r\n            if (hr == APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE)\r\n            {\r\n                context.Reporter.Info() << Resource::String::UpdateNotApplicable << std::endl\r\n                    << Resource::String::UpdateNotApplicableReason << std::endl;\r\n            }\r\n            else\r\n            {\r\n                auto errorCodeString = GetErrorCodeString(hr);\r\n                context.Reporter.Error() << Resource::String::MSStoreInstallOrUpdateFailed(errorCodeString) << std::endl;\r\n                context.Add<Execution::Data::OperationReturnCode>(hr);\r\n                AICLI_LOG(CLI, Error, << \"MSStore execution failed. ProductId: \" << Utility::ConvertToUTF8(productId) << \" HResult: \" << errorCodeString);\r\n            }\r\n\r\n            AICLI_TERMINATE_CONTEXT(hr);\r\n        }\r\n    }\r\n\r\n    void MSStoreRepair(Execution::Context& context)\r\n    {\r\n        auto productId = Utility::ConvertToUTF16(context.Get<Execution::Data::Installer>()->ProductId);\r\n        auto scope = Manifest::ConvertToScopeEnum(context.Args.GetArg(Execution::Args::Type::InstallScope));\r\n        bool isSilentMode = context.Args.Contains(Execution::Args::Type::Silent);\r\n        bool force = context.Args.Contains(Execution::Args::Type::Force);\r\n\r\n        auto repairOperation = MSStoreOperation(MSStoreOperationType::Repair, productId, scope, isSilentMode, force);\r\n\r\n        context.Reporter.Info() << Resource::String::RepairFlowStartingPackageRepair << std::endl;\r\n\r\n        HRESULT hr = S_OK;\r\n        context.Reporter.ExecuteWithProgress(\r\n            [&](IProgressCallback& progress)\r\n            {\r\n                hr = repairOperation.StartAndWaitForOperation(progress);\r\n            });\r\n\r\n        if (SUCCEEDED(hr))\r\n        {\r\n            context.Reporter.Info() << Resource::String::RepairFlowRepairSuccess << std::endl;\r\n        }\r\n        else\r\n        {\r\n            if (hr == APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED)\r\n            {\r\n                context.Reporter.Error() << Resource::String::InstallFlowReturnCodeSystemNotSupported << std::endl;\r\n                context.Add<Execution::Data::OperationReturnCode>(static_cast<DWORD>(APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED));\r\n            }\r\n            else\r\n            {\r\n                auto errorCodeString = GetErrorCodeString(hr);\r\n                context.Reporter.Error() << Resource::String::MSStoreRepairFailed(errorCodeString) << std::endl;\r\n                context.Add<Execution::Data::OperationReturnCode>(hr);\r\n                AICLI_LOG(CLI, Error, << \"MSStore repair failed. ProductId: \" << Utility::ConvertToUTF8(productId) << \" HResult: \" << errorCodeString);\r\n            }\r\n\r\n            AICLI_TERMINATE_CONTEXT(hr);\r\n        }\r\n    }\r\n\r\n    void MSStoreDownload(Execution::Context& context)\r\n    {\r\n        if (context.Args.Contains(Execution::Args::Type::Rename))\r\n        {\r\n            context.Reporter.Warn() << Resource::String::MSStoreDownloadRenameNotSupported << std::endl;\r\n        }\r\n\r\n        // Authentication notice\r\n        context.Reporter.Warn() << Resource::String::MSStoreDownloadAuthenticationNotice << std::endl;\r\n        context.Reporter.Warn() << Resource::String::MSStoreDownloadMultiplePackagesNotice << std::endl;\r\n\r\n        const auto& installer = context.Get<Execution::Data::Installer>().value();\r\n\r\n        Utility::Architecture requiredArchitecture = Utility::Architecture::Unknown;\r\n        Manifest::PlatformEnum requiredPlatform = Manifest::PlatformEnum::Unknown;\r\n        std::string requiredLocale;\r\n        if (context.Args.Contains(Execution::Args::Type::InstallerArchitecture))\r\n        {\r\n            requiredArchitecture = Utility::ConvertToArchitectureEnum(context.Args.GetArg(Execution::Args::Type::InstallerArchitecture));\r\n        }\r\n        if (context.Args.Contains(Execution::Args::Type::Platform))\r\n        {\r\n            requiredPlatform = Manifest::ConvertToPlatformEnumForMSStoreDownload(context.Args.GetArg(Execution::Args::Type::Platform));\r\n        }\r\n        if (context.Args.Contains(Execution::Args::Type::Locale))\r\n        {\r\n            requiredLocale = context.Args.GetArg(Execution::Args::Type::Locale);\r\n        }\r\n\r\n        MSStoreDownloadContext downloadContext{ installer.ProductId, requiredArchitecture, requiredPlatform, requiredLocale, GetAuthenticationArguments(context) };\r\n\r\n        if (context.Args.Contains(Execution::Args::Type::OSVersion))\r\n        {\r\n            Utility::UInt64Version targetOSVersion{ std::string{ context.Args.GetArg(Execution::Args::Type::OSVersion) } };\r\n            downloadContext.TargetOSVersion(std::move(targetOSVersion));\r\n        }\r\n\r\n        MSStoreDownloadInfo downloadInfo;\r\n        try\r\n        {\r\n            context.Reporter.Info() << Resource::String::MSStoreDownloadGetDownloadInfo << std::endl;\r\n\r\n            downloadInfo = downloadContext.GetDownloadInfo();\r\n        }\r\n        catch (const wil::ResultException& re)\r\n        {\r\n            AICLI_LOG(CLI, Error, << \"Getting MSStore package download info failed. Error code: \" << re.GetErrorCode());\r\n\r\n            switch (re.GetErrorCode())\r\n            {\r\n            case APPINSTALLER_CLI_ERROR_NO_APPLICABLE_DISPLAYCATALOG_PACKAGE:\r\n            case APPINSTALLER_CLI_ERROR_NO_APPLICABLE_SFSCLIENT_PACKAGE:\r\n                context.Reporter.Error() << Resource::String::MSStoreDownloadNoApplicablePackageFound << std::endl;\r\n                break;\r\n            case APPINSTALLER_CLI_ERROR_SFSCLIENT_PACKAGE_NOT_SUPPORTED:\r\n                context.Reporter.Error() << Resource::String::MSStoreDownloadPackageDownloadNotSupported << std::endl;\r\n                break;\r\n            default:\r\n                context.Reporter.Error() << Resource::String::MSStoreDownloadGetDownloadInfoFailed << std::endl;\r\n            }\r\n\r\n            AICLI_TERMINATE_CONTEXT(re.GetErrorCode());\r\n        }\r\n\r\n        bool skipDependencies = context.Args.Contains(Execution::Args::Type::SkipDependencies);\r\n\r\n        // Prepare directories\r\n        std::filesystem::path downloadDirectory = context.Get<Execution::Data::DownloadDirectory>();\r\n        std::filesystem::path dependenciesDirectory = downloadDirectory / L\"Dependencies\";\r\n\r\n        // Create directories if needed.\r\n        auto directoryToCreate = (skipDependencies || downloadInfo.DependencyPackages.empty()) ? downloadDirectory : dependenciesDirectory;\r\n        if (!std::filesystem::exists(directoryToCreate))\r\n        {\r\n            std::filesystem::create_directories(directoryToCreate);\r\n        }\r\n        else\r\n        {\r\n            THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_CANNOT_MAKE), !std::filesystem::is_directory(directoryToCreate));\r\n        }\r\n\r\n        // Download dependency packages\r\n        if (!skipDependencies)\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"Downloading MSStore dependency packages\");\r\n            context.Reporter.Info() << Resource::String::MSStoreDownloadDependencyPackages << std::endl;\r\n\r\n            for (auto const& dependencyPackage : downloadInfo.DependencyPackages)\r\n            {\r\n                THROW_IF_FAILED(DownloadMSStorePackageFile(dependencyPackage, dependenciesDirectory, context));\r\n            }\r\n        }\r\n\r\n        // Download main packages\r\n        AICLI_LOG(CLI, Info, << \"Downloading MSStore main packages\");\r\n        context.Reporter.Info() << Resource::String::MSStoreDownloadMainPackages << std::endl;\r\n        for (auto const& mainPackage : downloadInfo.MainPackages)\r\n        {\r\n            THROW_IF_FAILED(DownloadMSStorePackageFile(mainPackage, downloadDirectory, context));\r\n        }\r\n\r\n        context.Reporter.Info() << Resource::String::MSStoreDownloadPackageDownloadSuccess << std::endl;\r\n\r\n        // Get license\r\n        if (!context.Args.Contains(Execution::Args::Type::SkipMicrosoftStorePackageLicense))\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"Getting MSStore package license\");\r\n            context.Reporter.Info() << Resource::String::MSStoreDownloadGetLicense << std::endl;\r\n\r\n            std::vector<BYTE> licenseContent;\r\n            try\r\n            {\r\n                licenseContent = downloadContext.GetLicense(downloadInfo.ContentId);\r\n            }\r\n            catch (const wil::ResultException& re)\r\n            {\r\n                if (re.GetErrorCode() == APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED_FORBIDDEN)\r\n                {\r\n                    AICLI_LOG(CLI, Warning, << \"Getting MSStore package license failed. The Microsoft Entra Id account does not have privilege.\");\r\n                    context.Reporter.Warn() << Resource::String::MSStoreDownloadGetLicenseForbidden << std::endl;\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(CLI, Warning, << \"Getting MSStore package license failed. Error code: \" << re.GetErrorCode());\r\n                    context.Reporter.Warn() << Resource::String::MSStoreDownloadGetLicenseFailed << std::endl;\r\n                }\r\n\r\n                AICLI_TERMINATE_CONTEXT(re.GetErrorCode());\r\n            }\r\n\r\n            std::filesystem::path licenseFilePath = downloadDirectory / Utility::ConvertToUTF16(installer.ProductId + \"_License.xml\");\r\n            std::ofstream licenseFile(licenseFilePath, std::ofstream::out | std::ofstream::trunc | std::ofstream::binary);\r\n            licenseFile.write((const char *)&licenseContent[0], licenseContent.size());\r\n            licenseFile.flush();\r\n            licenseFile.close();\r\n\r\n            AICLI_LOG(CLI, Info, << \"Getting MSStore package license success\");\r\n            context.Reporter.Info() << Resource::String::MSStoreDownloadGetLicenseSuccess(Utility::LocIndView{ licenseFilePath.u8string() }) << std::endl;\r\n        }\r\n    }\r\n\r\n    void EnsureStorePolicySatisfied(Execution::Context& context)\r\n    {\r\n        auto productId = Utility::ConvertToUTF16(context.Get<Execution::Data::Installer>()->ProductId);\r\n        bool bypassStorePolicy = WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::BypassIsStoreClientBlockedPolicyCheck);\r\n\r\n        HRESULT hr = EnsureStorePolicySatisfiedImpl(productId, bypassStorePolicy);\r\n        if (FAILED(hr))\r\n        {\r\n            if (hr == APPINSTALLER_CLI_ERROR_MSSTORE_BLOCKED_BY_POLICY)\r\n            {\r\n                context.Reporter.Error() << Resource::String::MSStoreStoreClientBlocked << std::endl;\r\n            }\r\n            else if (hr == APPINSTALLER_CLI_ERROR_MSSTORE_APP_BLOCKED_BY_POLICY)\r\n            {\r\n                context.Reporter.Error() << Resource::String::MSStoreAppBlocked << std::endl;\r\n            }\r\n\r\n            AICLI_TERMINATE_CONTEXT(hr);\r\n        }\r\n    }\r\n\r\n    void VerifyIsFullPackage(Execution::Context& context)\r\n    {\r\n        if (IsStubPackage())\r\n        {\r\n            context.Reporter.Error() << Resource::String::ExtendedFeaturesNotEnabledMessage << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB);\r\n        }\r\n    }\r\n\r\n    void EnableExtendedFeatures(Execution::Context& context)\r\n    {\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        AppInstallerUpdate(false, true, context);\r\n#else\r\n        if (IsStubPackage())\r\n        {\r\n            context.Reporter.Info() << Resource::String::ExtendedFeaturesEnablingMessage << std::endl;\r\n            bool bypassStorePolicy = WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::BypassIsStoreClientBlockedPolicyCheck);\r\n            AppInstallerUpdate(false, bypassStorePolicy, context);\r\n        }\r\n        else\r\n        {\r\n            context.Reporter.Info() << Resource::String::ExtendedFeaturesEnabledMessage << std::endl;\r\n        }\r\n#endif\r\n    }\r\n\r\n    void DisableExtendedFeatures(Execution::Context& context)\r\n    {\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        AppInstallerUpdate(true, true, context);\r\n#else\r\n        if (!IsStubPackage())\r\n        {\r\n            context.Reporter.Info() << Resource::String::ExtendedFeaturesDisablingMessage << std::endl;\r\n            bool bypassStorePolicy = WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::BypassIsStoreClientBlockedPolicyCheck);\r\n            AppInstallerUpdate(true, bypassStorePolicy, context);\r\n        }\r\n        else\r\n        {\r\n            context.Reporter.Info() << Resource::String::ExtendedFeaturesDisabledMessage << std::endl;\r\n        }\r\n#endif\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/MSStoreInstallerHandler.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ExecutionContext.h\"\r\n\r\n// MSStoreInstallerHandler handles msstore installers.\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    // Deploys the Store app.\r\n    // Required Args: None\r\n    // Inputs: Installer\r\n    // Outputs: None\r\n    void MSStoreInstall(Execution::Context& context);\r\n\r\n    // Updates the Store app if applicable.\r\n    // Required Args: None\r\n    // Inputs: Installer\r\n    // Outputs: None\r\n    void MSStoreUpdate(Execution::Context& context);\r\n\r\n    // Attempt to repair the installation of an Store app that is already installed\r\n    // Required Args: None\r\n    // Inputs: Installer\r\n    // Outputs: None\r\n    void MSStoreRepair(Execution::Context& context);\r\n\r\n    // Downloads the Store app installer.\r\n    // Required Args: None\r\n    // Inputs: Installer\r\n    // Outputs: None\r\n    void MSStoreDownload(Execution::Context& context);\r\n\r\n    // Ensure the Store app is not blocked by policy.\r\n    // Required Args: None\r\n    // Inputs: Installer\r\n    // Outputs: None\r\n    void EnsureStorePolicySatisfied(Execution::Context& context);\r\n\r\n    // Verifies the full package is installed.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: None\r\n    void VerifyIsFullPackage(Execution::Context& context);\r\n\r\n    // Change stub preference to full and installs full package if needed.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: None\r\n    void EnableExtendedFeatures(Execution::Context& context);\r\n\r\n    // Change stub preference to stub and installs stub package if needed.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: None\r\n    void DisableExtendedFeatures(Execution::Context& context);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/MsiInstallFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"MsiInstallFlow.h\"\r\n#include <winget/MsiExecArguments.h>\r\n#include <winget/Runtime.h>\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    namespace\r\n    {\r\n        std::optional<UINT> InvokeMsiInstallProduct(const std::filesystem::path& installerPath, const Msi::MsiParsedArguments& msiArgs, IProgressCallback&)\r\n        {\r\n            if (msiArgs.LogFile)\r\n            {\r\n                THROW_IF_WIN32_ERROR(MsiEnableLogW(msiArgs.LogMode, msiArgs.LogFile->c_str(), msiArgs.LogAttributes));\r\n            }\r\n            else\r\n            {\r\n                // Disable logging\r\n                THROW_IF_WIN32_ERROR(MsiEnableLogW(0, nullptr, 0));\r\n            }\r\n\r\n            // Returns old UI level. We don't need to reset it so we ignore it.\r\n            MsiSetInternalUI(msiArgs.UILevel, nullptr);\r\n\r\n            // TODO: Use progress callback\r\n            return MsiInstallProductW(installerPath.c_str(), msiArgs.Properties.c_str());\r\n        }\r\n    }\r\n\r\n    void DirectMSIInstallImpl(Execution::Context& context)\r\n    {\r\n        context.Reporter.Info() << Resource::String::InstallFlowStartingPackageInstall << std::endl;\r\n\r\n        const auto& installer = context.Get<Execution::Data::Installer>();\r\n        const std::filesystem::path& installerPath = context.Get<Execution::Data::InstallerPath>();\r\n\r\n        Msi::MsiParsedArguments parsedArgs = Msi::ParseMSIArguments(context.Get<Execution::Data::InstallerArgs>());\r\n\r\n        // Inform of elevation requirements\r\n        if (!Runtime::IsRunningAsAdmin() && installer->ElevationRequirement == Manifest::ElevationRequirementEnum::ElevatesSelf)\r\n        {\r\n            context.Reporter.Warn() << Resource::String::InstallerElevationExpected << std::endl;\r\n        }\r\n\r\n        auto installResult = context.Reporter.ExecuteWithProgress(\r\n            std::bind(InvokeMsiInstallProduct,\r\n                installerPath,\r\n                parsedArgs,\r\n                std::placeholders::_1));\r\n\r\n        if (!installResult)\r\n        {\r\n            context.Reporter.Warn() << Resource::String::InstallAbandoned << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(E_ABORT);\r\n        }\r\n        else\r\n        {\r\n            context.Add<Execution::Data::OperationReturnCode>(installResult.value());\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/MsiInstallFlow.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ExecutionContext.h\"\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    // Ensures that there is an applicable installer.\r\n    // Required Args: None\r\n    // Inputs: InstallerArgs, Installer, InstallerPath, Manifest\r\n    // Outputs: OperationReturnCode\r\n    void DirectMSIInstallImpl(Execution::Context& context);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/MultiQueryFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"MultiQueryFlow.h\"\r\n#include \"UpdateFlow.h\"\r\n\r\nusing namespace AppInstaller::CLI;\r\nusing namespace AppInstaller::CLI::Execution;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Utility::literals;\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    namespace\r\n    {\r\n        Utility::LocIndString GetPackageStringFromSearchRequest(const SearchRequest& searchRequest)\r\n        {\r\n            if (searchRequest.Query)\r\n            {\r\n                return Utility::LocIndString{ searchRequest.Query->Value };\r\n            }\r\n\r\n            if (!searchRequest.Inclusions.empty())\r\n            {\r\n                return Utility::LocIndString{ searchRequest.Inclusions[0].Value };\r\n            }\r\n\r\n            if (!searchRequest.Filters.empty())\r\n            {\r\n                return Utility::LocIndString{ searchRequest.Filters[0].Value };\r\n            }\r\n\r\n            return \"\"_lis;\r\n        }\r\n    }\r\n\r\n    void GetMultiSearchRequests(Execution::Context& context)\r\n    {\r\n        std::vector<std::unique_ptr<Execution::Context>> packageSubContexts;\r\n        auto& source = context.Get<Execution::Data::Source>();\r\n        for (const auto& query : *context.Args.GetArgs(Execution::Args::Type::MultiQuery))\r\n        {\r\n            auto searchContextPtr = context.CreateSubContext();\r\n            Execution::Context& searchContext = *searchContextPtr;\r\n            auto previousThreadGlobals = searchContext.SetForCurrentThread();\r\n\r\n            searchContext.Add<Execution::Data::Source>(source);\r\n            searchContext.Args.AddArg(Execution::Args::Type::Query, query);\r\n\r\n            AICLI_LOG(CLI, Info, << \"Creating search query for package [\" << query << \"]\");\r\n            searchContext << GetSearchRequestForSingle;\r\n\r\n            packageSubContexts.emplace_back(std::move(searchContextPtr));\r\n        }\r\n\r\n        context.Add<Execution::Data::PackageSubContexts>(std::move(packageSubContexts));\r\n    }\r\n\r\n    void SearchSubContextsForSingle::operator()(Execution::Context& context) const\r\n    {\r\n        std::vector<std::unique_ptr<Execution::Context>> packageSubContexts;\r\n        bool foundAll = true;\r\n\r\n        for (auto& searchContextPtr : context.Get<Execution::Data::PackageSubContexts>())\r\n        {\r\n            auto& searchContext = *searchContextPtr;\r\n            SearchRequest searchRequest = searchContext.Get<Execution::Data::SearchRequest>();\r\n            searchContext.Add<Execution::Data::SearchResult>(searchContext.Get<Execution::Data::Source>().Search(searchRequest));\r\n\r\n            switch (m_operationType)\r\n            {\r\n            case OperationType::Install:\r\n            case OperationType::Upgrade:\r\n                searchContext << Workflow::SelectSinglePackageVersionForInstallOrUpgrade(m_operationType);\r\n                break;\r\n            case OperationType::Uninstall:\r\n                searchContext <<\r\n                    Workflow::HandleSearchResultFailures <<\r\n                    Workflow::EnsureOneMatchFromSearchResult(m_operationType);\r\n                break;\r\n            default:\r\n                THROW_HR(E_UNEXPECTED);\r\n            }\r\n\r\n            if (searchContext.IsTerminated())\r\n            {\r\n                if (context.IsTerminated() && context.GetTerminationHR() == E_ABORT)\r\n                {\r\n                    // This means that the subcontext being terminated is due to an overall abort\r\n                    context.Reporter.Info() << Resource::String::Cancelled << std::endl;\r\n                    return;\r\n                }\r\n                else\r\n                {\r\n                    // We already reported the error from the sub-context, but we repeat it here because\r\n                    // for multi-queries we can a bit more verbose as the queries here are easier to report.\r\n                    auto packageString = GetPackageStringFromSearchRequest(searchRequest);\r\n                    auto searchTerminationHR = searchContext.GetTerminationHR();\r\n                    if (searchTerminationHR == APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE ||\r\n                        searchTerminationHR == APPINSTALLER_CLI_ERROR_PACKAGE_ALREADY_INSTALLED)\r\n                    {\r\n                        AICLI_LOG(CLI, Info, << \"Package is already installed: [\" << packageString << \"]\");\r\n                        context.Reporter.Info() << Resource::String::MultiQueryPackageAlreadyInstalled(packageString) << std::endl;\r\n                        continue;\r\n                    }\r\n                    else\r\n                    {\r\n                        if (searchTerminationHR == APPINSTALLER_CLI_ERROR_NO_APPLICATIONS_FOUND)\r\n                        {\r\n                            AICLI_LOG(CLI, Info, << \"Package not found for query: [\" << packageString << \"]\");\r\n                            context.Reporter.Warn() << Resource::String::MultiQueryPackageNotFound(packageString) << std::endl;\r\n                        }\r\n                        else if (searchTerminationHR == APPINSTALLER_CLI_ERROR_MULTIPLE_APPLICATIONS_FOUND)\r\n                        {\r\n                            AICLI_LOG(CLI, Info, << \"Multiple packages found for query: [\" << packageString << \"]\");\r\n                            context.Reporter.Warn() << Resource::String::MultiQuerySearchFoundMultiple(packageString) << std::endl;\r\n                        }\r\n                        else\r\n                        {\r\n                            AICLI_LOG(CLI, Info, << \"Search failed for query: [\" << packageString << \"]\");\r\n                            context.Reporter.Info() << Resource::String::MultiQuerySearchFailed(packageString) << std::endl;\r\n                        }\r\n\r\n                        // Keep searching for the remaining packages and only fail at the end.\r\n                        foundAll = false;\r\n                        continue;\r\n                    }\r\n                }\r\n            }\r\n\r\n            packageSubContexts.emplace_back(std::move(searchContextPtr));\r\n        }\r\n\r\n        if (!foundAll)\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"Not all queries returned one result\");\r\n            if (context.Args.Contains(Execution::Args::Type::IgnoreUnavailable))\r\n            {\r\n                AICLI_LOG(CLI, Info, << \"Ignoring unavailable packages due to command line argument\");\r\n            }\r\n            else\r\n            {\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_NOT_ALL_QUERIES_FOUND_SINGLE);\r\n            }\r\n        }\r\n\r\n        context.Add<Execution::Data::PackageSubContexts>(std::move(packageSubContexts));\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/MultiQueryFlow.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ExecutionContext.h\"\r\n\r\n// Workflow tasks related to dealing with multiple package queries at once.\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    // Gets the search requests for multiple queries from the command line.\r\n    // Required Args: None\r\n    // Inputs: Source\r\n    // Outputs: PackageSubContexts\r\n    //   SubContext Inputs: None\r\n    //   SubContext Outputs: Source, SearchRequest\r\n    void GetMultiSearchRequests(Execution::Context& context);\r\n\r\n    // Performs searches on each of the sub-contexts with the semantics of targeting a single package for each one.\r\n    // Required Args: a value indicating the purpose of the search\r\n    // Inputs: PackageSubContexts\r\n    // Outputs: None\r\n    //   SubContext Inputs: Source, SearchRequest\r\n    //   SubContext Outputs: SearchResult\r\n    struct SearchSubContextsForSingle : public WorkflowTask\r\n    {\r\n        SearchSubContextsForSingle(OperationType operation = OperationType::Install) : WorkflowTask(\"SearchSubContextsForSingle\"), m_operationType(operation) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        OperationType m_operationType;\r\n    };\r\n}"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/PinFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Resources.h\"\r\n#include \"PinFlow.h\"\r\n#include \"TableOutput.h\"\r\n#include <winget/PinningData.h>\r\n#include <winget/RepositorySearch.h>\r\n#include <winget/PackageVersionSelection.h>\r\n\r\nusing namespace AppInstaller::Repository;\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    namespace\r\n    {\r\n        // Creates a Pin appropriate for the context based on the arguments provided\r\n        Pinning::Pin CreatePin(Execution::Context& context, const Pinning::PinKey& pinKey)\r\n        {\r\n            if (context.Args.Contains(Execution::Args::Type::GatedVersion))\r\n            {\r\n                return Pinning::Pin::CreateGatingPin(pinKey, context.Args.GetArg(Execution::Args::Type::GatedVersion));\r\n            }\r\n            else if (context.Args.Contains(Execution::Args::Type::BlockingPin))\r\n            {\r\n                return Pinning::Pin::CreateBlockingPin(pinKey);\r\n            }\r\n            else\r\n            {\r\n                return Pinning::Pin::CreatePinningPin(pinKey);\r\n            }\r\n        }\r\n\r\n        void GetPinKeysForInstalled(const std::shared_ptr<IPackageVersion>& installedVersion, std::set<Pinning::PinKey>& pinKeys)\r\n        {\r\n            auto installedType = Manifest::ConvertToInstallerTypeEnum(installedVersion->GetMetadata()[PackageVersionMetadata::InstalledType]);\r\n            std::vector<Utility::LocIndString> propertyStrings;\r\n\r\n            if (Manifest::DoesInstallerTypeUsePackageFamilyName(installedType))\r\n            {\r\n                propertyStrings = installedVersion->GetMultiProperty(PackageVersionMultiProperty::PackageFamilyName);\r\n            }\r\n            else if (Manifest::DoesInstallerTypeUseProductCode(installedType))\r\n            {\r\n                propertyStrings = installedVersion->GetMultiProperty(PackageVersionMultiProperty::ProductCode);\r\n            }\r\n\r\n            for (const auto& value : propertyStrings)\r\n            {\r\n                pinKeys.emplace(Pinning::PinKey::GetPinKeyForInstalled(value));\r\n            }\r\n        }\r\n\r\n        std::set<Pinning::PinKey> GetPinKeysForPackage(Execution::Context& context)\r\n        {\r\n            auto package = context.Get<Execution::Data::Package>();\r\n\r\n            std::set<Pinning::PinKey> pinKeys;\r\n\r\n            if (context.Args.Contains(Execution::Args::Type::PinInstalled))\r\n            {\r\n                auto installedVersion = GetInstalledVersion(package);\r\n                if (installedVersion)\r\n                {\r\n                    GetPinKeysForInstalled(installedVersion, pinKeys);\r\n                }\r\n            }\r\n            else\r\n            {\r\n                auto availablePackages = package->GetAvailable();\r\n                for (const auto& availablePackage : availablePackages)\r\n                {\r\n                    pinKeys.emplace(\r\n                        availablePackage->GetProperty(PackageProperty::Id).get(),\r\n                        availablePackage->GetSource().GetIdentifier());\r\n                }\r\n            }\r\n\r\n            return pinKeys;\r\n        }\r\n\r\n        // Gets a search request that can be used to find the installed package that corresponds with a pin.\r\n        SearchRequest GetSearchRequestForPin(const Pinning::PinKey& pinKey)\r\n        {\r\n            SearchRequest searchRequest;\r\n            if (pinKey.IsForInstalled())\r\n            {\r\n                searchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::PackageFamilyName, MatchType::Exact, pinKey.PackageId));\r\n                searchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::ProductCode, MatchType::Exact, pinKey.PackageId));\r\n            }\r\n            else\r\n            {\r\n                searchRequest.Filters.emplace_back(PackageMatchField::Id, MatchType::CaseInsensitive, pinKey.PackageId);\r\n            }\r\n\r\n            return searchRequest;\r\n        }\r\n    }\r\n\r\n    void OpenPinningIndex::operator()(Execution::Context& context) const\r\n    {\r\n        auto pinningData = Pinning::PinningData{ m_readOnly ? Pinning::PinningData::Disposition::ReadOnly : Pinning::PinningData::Disposition::ReadWrite };\r\n        if (!m_readOnly && !pinningData)\r\n        {\r\n            AICLI_LOG(CLI, Error, << \"Unable to open pinning index.\");\r\n            context.Reporter.Error() << Resource::String::PinCannotOpenIndex << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_CANNOT_OPEN_PINNING_INDEX);\r\n        }\r\n\r\n        context.Add<Execution::Data::PinningData>(std::move(pinningData));\r\n    }\r\n\r\n    void GetAllPins(Execution::Context& context)\r\n    {\r\n        AICLI_LOG(CLI, Info, << \"Getting all existing pins\");\r\n        context.Add<Execution::Data::Pins>(context.Get<Execution::Data::PinningData>().GetAllPins());\r\n    }\r\n\r\n    void SearchPin(Execution::Context& context)\r\n    {\r\n        auto pinKeys = GetPinKeysForPackage(context);\r\n\r\n        auto package = context.Get<Execution::Data::Package>();\r\n        auto pinningData = context.Get<Execution::Data::PinningData>();\r\n\r\n        std::vector<Pinning::Pin> pins;\r\n        for (const auto& pinKey : pinKeys)\r\n        {\r\n            auto pin = pinningData.GetPin(pinKey);\r\n            if (pin)\r\n            {\r\n                pins.emplace_back(std::move(pin.value()));\r\n            }\r\n        }\r\n\r\n        context.Add<Execution::Data::Pins>(std::move(pins));\r\n    }\r\n\r\n    void AddPin(Execution::Context& context)\r\n    {\r\n        auto pinKeys = GetPinKeysForPackage(context);\r\n\r\n        auto package = context.Get<Execution::Data::Package>();\r\n        auto pinningData = context.Get<Execution::Data::PinningData>();\r\n        auto installedVersion = context.Get<Execution::Data::InstalledPackageVersion>();\r\n\r\n        std::vector<Pinning::Pin> pinsToAddOrUpdate;\r\n        for (const auto& pinKey : pinKeys)\r\n        {\r\n            auto pin = CreatePin(context, pinKey);\r\n            AICLI_LOG(CLI, Info, << \"Evaluating Pin \" << pin.ToString());\r\n\r\n            auto existingPin = pinningData.GetPin(pinKey);\r\n            if (existingPin)\r\n            {\r\n                Utility::LocIndString packageNameToReport;\r\n                if (pinKey.IsForInstalled() && installedVersion)\r\n                {\r\n                    packageNameToReport = installedVersion->GetProperty(PackageVersionProperty::Name);\r\n                }\r\n                else\r\n                {\r\n                    auto availableVersion = GetAvailablePackageFromSource(package, pinKey.SourceId)->GetLatestVersion();\r\n                    if (availableVersion)\r\n                    {\r\n                        packageNameToReport = availableVersion->GetProperty(PackageVersionProperty::Name);\r\n                    }\r\n                }\r\n\r\n                // Pin already exists.\r\n                // If it is the same, we do nothing. If it is different, check for the --force arg\r\n                if (pin == existingPin)\r\n                {\r\n                    AICLI_LOG(CLI, Info, << \"Pin already exists\");\r\n                    context.Reporter.Info() << Resource::String::PinAlreadyExists(packageNameToReport) << std::endl;\r\n                    continue;\r\n                }\r\n\r\n                AICLI_LOG(CLI, Info, << \"Another pin already exists for the package for source \" << pinKey.SourceId);\r\n                if (context.Args.Contains(Execution::Args::Type::Force))\r\n                {\r\n                    AICLI_LOG(CLI, Info, << \"Overwriting pin due to --force argument\");\r\n                    context.Reporter.Warn() << Resource::String::PinExistsOverwriting(packageNameToReport) << std::endl;\r\n                    pinsToAddOrUpdate.push_back(std::move(pin));\r\n                }\r\n                else\r\n                {\r\n                    context.Reporter.Error() << Resource::String::PinExistsUseForceArg(packageNameToReport) << std::endl;\r\n                    AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_PIN_ALREADY_EXISTS);\r\n                }\r\n            }\r\n            else\r\n            {\r\n                pinsToAddOrUpdate.push_back(std::move(pin));\r\n            }\r\n        }\r\n\r\n        if (!pinsToAddOrUpdate.empty())\r\n        {\r\n            for (const auto& pin : pinsToAddOrUpdate)\r\n\r\n            {\r\n                pinningData.AddOrUpdatePin(pin);\r\n            }\r\n\r\n            context.Reporter.Info() << Resource::String::PinAdded << std::endl;\r\n        }\r\n    }\r\n\r\n    void RemovePin(Execution::Context& context)\r\n    {\r\n        auto package = context.Get<Execution::Data::Package>();\r\n        auto pins = context.Get<Execution::Data::Pins>();\r\n\r\n        auto pinningData = context.Get<Execution::Data::PinningData>();\r\n        bool pinExists = false;\r\n\r\n        // Note that if a source was specified in the command line,\r\n        // that will be the only one we get version keys from.\r\n        // So, we remove pins from all sources unless one was provided.\r\n        for (const auto& pin : pins)\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"Removing Pin \" << pin.GetKey().ToString());\r\n            pinningData.RemovePin(pin.GetKey());\r\n            pinExists = true;\r\n        }\r\n\r\n        if (!pinExists)\r\n        {\r\n            AICLI_LOG(CLI, Warning, << \"Pin does not exist\");\r\n            context.Reporter.Warn() << Resource::String::PinDoesNotExist(package->GetProperty(PackageProperty::Name)) << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_PIN_DOES_NOT_EXIST);\r\n        }\r\n\r\n        context.Reporter.Info() << Resource::String::PinRemovedSuccessfully << std::endl;\r\n    }\r\n\r\n    void ReportPins(Execution::Context& context)\r\n    {\r\n        const auto& pins = context.Get<Execution::Data::Pins>();\r\n        if (pins.empty())\r\n        {\r\n            context.Reporter.Info() << Resource::String::PinNoPinsExist << std::endl;\r\n            return;\r\n        }\r\n\r\n        Execution::TableOutput<6> table(context.Reporter,\r\n            {\r\n                Resource::String::SearchName,\r\n                Resource::String::SearchId,\r\n                Resource::String::SearchVersion,\r\n                Resource::String::SearchSource,\r\n                Resource::String::PinType,\r\n                Resource::String::PinVersion,\r\n            });\r\n\r\n        const auto& source = context.Get<Execution::Data::Source>();\r\n        for (const auto& pin : pins)\r\n        {\r\n            const auto& pinKey = pin.GetKey();\r\n            auto searchRequest = GetSearchRequestForPin(pin.GetKey());\r\n            auto searchResult = source.Search(searchRequest);\r\n            for (const auto& match : searchResult.Matches)\r\n            {\r\n                Utility::LocIndString packageName;\r\n                Utility::LocIndString sourceName;\r\n                Utility::LocIndString version;\r\n\r\n                if (pinKey.IsForInstalled())\r\n                {\r\n                    sourceName = Resource::LocString{ Resource::String::PinInstalledSource };\r\n                }\r\n                else\r\n                {\r\n                    // This ensures we get the info from the right source if it exists on multiple\r\n                    auto availablePackage = GetAvailablePackageFromSource(match.Package, pinKey.SourceId);\r\n                    if (availablePackage)\r\n                    {\r\n                        auto availableVersion = availablePackage->GetLatestVersion();\r\n                        if (availableVersion)\r\n                        {\r\n                            packageName = availableVersion->GetProperty(PackageVersionProperty::Name);\r\n                            sourceName = availableVersion->GetProperty(PackageVersionProperty::SourceName);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                auto installedVersion = GetInstalledVersion(match.Package);\r\n                if (installedVersion)\r\n                {\r\n                    packageName = installedVersion->GetProperty(PackageVersionProperty::Name);\r\n                    version = installedVersion->GetProperty(PackageVersionProperty::Version);\r\n                }\r\n\r\n                table.OutputLine({\r\n                    packageName,\r\n                    pinKey.PackageId,\r\n                    version,\r\n                    sourceName,\r\n                    std::string{ ToString(pin.GetType()) },\r\n                    pin.GetGatedVersion().ToString(),\r\n                });\r\n            }\r\n        }\r\n\r\n        table.Complete();\r\n    }\r\n\r\n    void ResetAllPins(Execution::Context& context)\r\n    {\r\n        AICLI_LOG(CLI, Info, << \"Resetting all pins\");\r\n        context.Reporter.Info() << Resource::String::PinResettingAll << std::endl;\r\n\r\n        std::string sourceId;\r\n        if (context.Args.Contains(Execution::Args::Type::Source))\r\n        {\r\n            auto sourceName = context.Args.GetArg(Execution::Args::Type::Source);\r\n            auto sources = Source::GetCurrentSources();\r\n            for (const auto& source : sources)\r\n            {\r\n                if (Utility::CaseInsensitiveEquals(source.Name, sourceName))\r\n                {\r\n                    sourceId = source.Identifier;\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n\r\n        if (context.Get<Execution::Data::PinningData>().ResetAllPins(sourceId))\r\n        {\r\n            context.Reporter.Info() << Resource::String::PinResetSuccessful << std::endl;\r\n        }\r\n        else\r\n        {\r\n            context.Reporter.Info() << Resource::String::PinNoPinsExist << std::endl;\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/PinFlow.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ExecutionContext.h\"\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    // Opens the pinning index for use in future operations.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: PinningIndex\r\n    struct OpenPinningIndex : public WorkflowTask\r\n    {\r\n        OpenPinningIndex(bool readOnly = false) : WorkflowTask(\"OpenPinningIndex\"), m_readOnly(readOnly) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        bool m_readOnly;\r\n    };\r\n\r\n    // Gets all the pins from the index.\r\n    // Required Args: None\r\n    // Inputs: PinningIndex\r\n    // Outputs: Pins\r\n    void GetAllPins(Execution::Context& context);\r\n\r\n    // Searches for all the pins associated with a package.\r\n    // There may be several if a package is available from multiple sources\r\n    // or if the pin is for the installed package.\r\n    // Required Args: None\r\n    // Inputs: PinningIndex, Package\r\n    // Outputs: Pins\r\n    void SearchPin(Execution::Context& context);\r\n\r\n    // Adds a pin for the current package.\r\n    // A separate pin will be added for each source.\r\n    // Required Args: None\r\n    // Inputs: PinningIndex, Package, InstalledVersion?\r\n    // Outputs: None\r\n    void AddPin(Execution::Context& context);\r\n\r\n    // Removes all the pins associated with a package.\r\n    // Required Args: None\r\n    // Inputs: PinningIndex, Package, InstalledPackageVersion\r\n    // Outputs: None\r\n    void RemovePin(Execution::Context& context);\r\n\r\n    // Report the pins in a table.\r\n    // This includes searching for the corresponding installed packages\r\n    // to be able to show more info, like the package name.\r\n    // Required Args: None\r\n    // Inputs: Pins\r\n    // Outputs: None\r\n    void ReportPins(Execution::Context& context);\r\n\r\n    // Resets all the existing pins.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: None\r\n    void ResetAllPins(Execution::Context& context);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/PortableFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"PortableFlow.h\"\n#include \"PortableInstaller.h\"\n#include \"WorkflowBase.h\"\n#include <winget/Filesystem.h>\n#include <winget/PortableFileEntry.h>\n#include <winget/PortableIndex.h>\n\nusing namespace AppInstaller::Manifest;\nusing namespace AppInstaller::Repository;\nusing namespace AppInstaller::Utility;\nusing namespace AppInstaller::CLI::Portable;\nusing namespace AppInstaller::Portable;\nusing namespace AppInstaller::Repository::Microsoft;\n\nnamespace AppInstaller::CLI::Workflow\n{\n    namespace\n    {\n        constexpr std::string_view s_DefaultSource = \"*DefaultSource\"sv;\n\n        std::string GetPortableProductCode(Execution::Context& context)\n        {\n            const std::string& packageId = context.Get<Execution::Data::Manifest>().Id;\n\n            std::string source;\n            if (context.Contains(Execution::Data::PackageVersion))\n            {\n                source = context.Get<Execution::Data::PackageVersion>()->GetSource().GetIdentifier();\n            }\n            else\n            {\n                source = s_DefaultSource;\n            }\n\n            return MakeSuitablePathPart(packageId + \"_\" + source);\n        }\n\n        void EnsureValidArgsForPortableInstall(Execution::Context& context)\n        {\n            std::string_view renameArg = context.Args.GetArg(Execution::Args::Type::Rename);\n\n            try\n            {\n                if (MakeSuitablePathPart(renameArg) != renameArg)\n                {\n                    context.Reporter.Error() << Resource::String::ReservedFilenameError << std::endl;\n                    AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS);\n                }\n            }\n            catch (...)\n            {\n                context.Reporter.Error() << Resource::String::ReservedFilenameError << std::endl;\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS);\n            }\n        }\n\n        void EnsureVolumeSupportsReparsePoints(Execution::Context& context)\n        {\n            Manifest::ScopeEnum scope = ConvertToScopeEnum(context.Args.GetArg(Execution::Args::Type::InstallScope));\n            const std::filesystem::path& symlinkDirectory = GetPortableLinksLocation(scope);\n\n            if (!AppInstaller::Filesystem::SupportsReparsePoints(symlinkDirectory))\n            {\n                context.Reporter.Error() << Resource::String::ReparsePointsNotSupportedError << std::endl;\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_PORTABLE_REPARSE_POINT_NOT_SUPPORTED);\n            }\n        }\n    }\n\n    void VerifyPackageAndSourceMatch(Execution::Context& context)\n    {\n        const std::string& packageIdentifier = context.Get<Execution::Data::Manifest>().Id;\n\n        std::string sourceIdentifier;\n        if (context.Contains(Execution::Data::PackageVersion))\n        {\n            sourceIdentifier = context.Get<Execution::Data::PackageVersion>()->GetSource().GetIdentifier();\n        }\n        else\n        {\n            sourceIdentifier = s_DefaultSource;\n        }\n\n        PortableInstaller& portableInstaller = context.Get<Execution::Data::PortableInstaller>();\n        if (portableInstaller.ARPEntryExists())\n        {\n            if (packageIdentifier != portableInstaller.WinGetPackageIdentifier || sourceIdentifier != portableInstaller.WinGetSourceIdentifier)\n            {\n                if (!context.Args.Contains(Execution::Args::Type::Force))\n                {\n                    AICLI_LOG(CLI, Error, << \"Registry match failed, skipping write to uninstall registry\");\n                    context.Reporter.Error() << Resource::String::PortablePackageAlreadyExists << std::endl;\n                    AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_PORTABLE_PACKAGE_ALREADY_EXISTS);\n                }\n                else\n                {\n                    AICLI_LOG(CLI, Info, << \"Overriding registry match check...\");\n                    context.Reporter.Warn() << Resource::String::PortableRegistryCollisionOverridden << std::endl;\n                }\n            }\n        }\n\n        portableInstaller.WinGetPackageIdentifier = packageIdentifier;\n        portableInstaller.WinGetSourceIdentifier = sourceIdentifier;\n    }\n\n    void InitializePortableInstaller(Execution::Context& context)\n    {\n        Manifest::ScopeEnum scope = Manifest::ScopeEnum::Unknown;\n        bool isUpdate = WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::InstallerExecutionUseUpdate);\n        std::shared_ptr<Repository::IPackageVersion> installedVersion;\n        if (context.Contains(Execution::Data::InstalledPackageVersion))\n        {\n            installedVersion = context.Get<Execution::Data::InstalledPackageVersion>();\n        }\n        if (isUpdate && installedVersion)\n        {\n            IPackageVersion::Metadata installationMetadata = installedVersion->GetMetadata();\n            auto installerScopeItr = installationMetadata.find(Repository::PackageVersionMetadata::InstalledScope);\n            if (installerScopeItr != installationMetadata.end())\n            {\n                scope = Manifest::ConvertToScopeEnum(installerScopeItr->second);\n            }\n        }\n        else\n        {\n            if (context.Args.Contains(Execution::Args::Type::InstallScope))\n            {\n                scope = Manifest::ConvertToScopeEnum(context.Args.GetArg(Execution::Args::Type::InstallScope));\n            }\n            else\n            {\n                Manifest::ScopeEnum requiredScope = Settings::User().Get<Settings::Setting::InstallScopeRequirement>();\n                Manifest::ScopeEnum preferredScope = Settings::User().Get<Settings::Setting::InstallScopePreference>();\n\n                scope = requiredScope != Manifest::ScopeEnum::Unknown ? requiredScope : preferredScope;\n            }\n        }\n\n        const auto& installer = context.Get<Execution::Data::Installer>().value();\n        Utility::Architecture arch = installer.Arch;\n        const std::string& productCode = GetPortableProductCode(context);\n\n        PortableInstaller portableInstaller = PortableInstaller(scope, arch, productCode);\n        portableInstaller.IsUpdate = isUpdate;\n\n        if (IsArchiveType(installer.BaseInstallerType) && installer.ArchiveBinariesDependOnPath)\n        {\n            portableInstaller.BinariesDependOnPath = true;\n        }\n\n        // Set target install directory\n        std::string_view locationArg = context.Args.GetArg(Execution::Args::Type::InstallLocation);\n        std::filesystem::path targetInstallDirectory;\n\n        if (!locationArg.empty())\n        {\n            targetInstallDirectory = std::filesystem::path{ ConvertToUTF16(locationArg) };\n        }\n        else\n        {\n            targetInstallDirectory = GetPortableInstallRoot(scope, arch);\n            targetInstallDirectory /= ConvertToUTF16(productCode);\n        }\n\n        portableInstaller.TargetInstallLocation = targetInstallDirectory;\n        portableInstaller.SetAppsAndFeaturesMetadata(context.Get<Execution::Data::Manifest>(), installer.AppsAndFeaturesEntries);\n        context.Add<Execution::Data::PortableInstaller>(std::move(portableInstaller));\n    }\n\n    std::vector<PortableFileEntry> GetDesiredStateForPortableInstall(Execution::Context& context)\n    {\n        std::filesystem::path& installerPath = context.Get<Execution::Data::InstallerPath>();\n        PortableInstaller& portableInstaller = context.Get<Execution::Data::PortableInstaller>();\n        std::vector<PortableFileEntry> entries;\n\n        const std::filesystem::path& targetInstallDirectory = portableInstaller.TargetInstallLocation;\n        const std::filesystem::path& symlinkDirectory = GetPortableLinksLocation(portableInstaller.GetScope());\n\n        // InstallerPath will point to a directory if it is extracted from an archive.\n        if (std::filesystem::is_directory(installerPath))\n        {\n            portableInstaller.RecordToIndex = true;\n\n            for (const auto& entry : std::filesystem::directory_iterator(installerPath))\n            {\n                std::filesystem::path entryPath = entry.path();\n                PortableFileEntry portableFile;\n                std::filesystem::path relativePath = std::filesystem::relative(entryPath, entryPath.parent_path());\n                std::filesystem::path targetPath = targetInstallDirectory / relativePath;\n\n                if (std::filesystem::is_directory(entryPath))\n                {\n                    entries.emplace_back(std::move(PortableFileEntry::CreateDirectoryEntry(entryPath, targetPath)));\n                }\n                else\n                {\n                    entries.emplace_back(std::move(PortableFileEntry::CreateFileEntry(entryPath, targetPath, {})));\n                }\n            }\n\n            const std::vector<Manifest::NestedInstallerFile>& nestedInstallerFiles = context.Get<Execution::Data::Installer>()->NestedInstallerFiles;\n\n            for (const auto& nestedInstallerFile : nestedInstallerFiles)\n            {\n                const std::filesystem::path& targetPath = targetInstallDirectory / ConvertToUTF16(nestedInstallerFile.RelativeFilePath);\n\n                std::filesystem::path commandAlias;\n                if (nestedInstallerFile.PortableCommandAlias.empty())\n                {\n                    commandAlias = targetPath.filename();\n                }\n                else\n                {\n                    commandAlias = ConvertToUTF16(nestedInstallerFile.PortableCommandAlias);\n                }\n\n                Filesystem::AppendExtension(commandAlias, \".exe\");\n                entries.emplace_back(std::move(PortableFileEntry::CreateSymlinkEntry(symlinkDirectory / commandAlias, targetPath)));\n            }\n        }\n        else\n        {\n            std::string_view renameArg = context.Args.GetArg(Execution::Args::Type::Rename);\n            const std::vector<string_t>& commands = context.Get<Execution::Data::Installer>()->Commands;\n            std::filesystem::path commandAlias = installerPath.filename();\n\n            if (!commands.empty())\n            {\n                commandAlias = ConvertToUTF16(commands[0]);\n            }\n\n            if (!renameArg.empty())\n            {\n                commandAlias = ConvertToUTF16(renameArg);\n            }\n            AppInstaller::Filesystem::AppendExtension(commandAlias, \".exe\");\n\n            const std::filesystem::path& targetFullPath = targetInstallDirectory / commandAlias;\n            entries.emplace_back(std::move(PortableFileEntry::CreateFileEntry(installerPath, targetFullPath, {})));\n            entries.emplace_back(std::move(PortableFileEntry::CreateSymlinkEntry(symlinkDirectory / commandAlias, targetFullPath)));\n        }\n\n        return entries;\n    }\n\n    void PortableInstallImpl(Execution::Context& context)\n    {\n        OperationType installType = WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::InstallerExecutionUseUpdate) ? OperationType::Upgrade : OperationType::Install;\n        \n        PortableInstaller& portableInstaller = context.Get<Execution::Data::PortableInstaller>();\n        try\n        {\n            context.Reporter.Info() << Resource::String::InstallFlowStartingPackageInstall << std::endl;\n\n            std::vector<AppInstaller::Portable::PortableFileEntry> desiredState = GetDesiredStateForPortableInstall(context);\n\n            portableInstaller.SetDesiredState(desiredState);\n\n            if (!portableInstaller.VerifyExpectedState())\n            {\n                if (context.Args.Contains(Execution::Args::Type::Force))\n                {\n                    context.Reporter.Warn() << Resource::String::PortableHashMismatchOverridden << std::endl;\n                }\n                else\n                {\n                    context.Reporter.Warn() << Resource::String::PortableHashMismatchOverrideRequired << std::endl;\n                    AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_PORTABLE_UNINSTALL_FAILED);\n                }\n            }\n\n            portableInstaller.Install(installType);\r\n            context.Add<Execution::Data::CorrelatedAppsAndFeaturesEntries>({ portableInstaller.GetAppsAndFeaturesEntry() });\n            context.Add<Execution::Data::OperationReturnCode>(ERROR_SUCCESS);\n            context.Reporter.Warn() << portableInstaller.GetOutputMessage();\n        }\n        catch (...)\n        {\n            context.Add<Execution::Data::OperationReturnCode>(Workflow::HandleException(context, std::current_exception()));\n\n            if (!portableInstaller.IsUpdate)\n            {\n                context.Reporter.Warn() << Resource::String::PortableInstallFailed << std::endl;\n                portableInstaller.PrepareForCleanUp();\n;               portableInstaller.Uninstall();\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_PORTABLE_UNINSTALL_FAILED);\n            }\n        }\n    }\n\n    void PortableUninstallImpl(Execution::Context& context)\n    {\n        PortableInstaller& portableInstaller = context.Get<Execution::Data::PortableInstaller>();\n\n        try\n        {\n            context.Reporter.Info() << Resource::String::UninstallFlowStartingPackageUninstall << std::endl;\n\n            if (!portableInstaller.VerifyExpectedState())\n            {\n                if (context.Args.Contains(Execution::Args::Type::Force))\n                {\n                    context.Reporter.Warn() << Resource::String::PortableHashMismatchOverridden << std::endl;\n                }\n                else\n                {\n                    context.Reporter.Warn() << Resource::String::PortableHashMismatchOverrideRequired << std::endl;\n                    AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_PORTABLE_UNINSTALL_FAILED);\n                }\n            }\n\n            portableInstaller.Purge = context.Args.Contains(Execution::Args::Type::Purge) ||\n                (!portableInstaller.IsUpdate && Settings::User().Get<Settings::Setting::UninstallPurgePortablePackage>() && !context.Args.Contains(Execution::Args::Type::Preserve));\n\n            portableInstaller.Uninstall();\n            context.Add<Execution::Data::OperationReturnCode>(ERROR_SUCCESS);\n            context.Reporter.Warn() << portableInstaller.GetOutputMessage();\n        }\n        catch (...)\n        {\n            context.Add<Execution::Data::OperationReturnCode>(Workflow::HandleException(context, std::current_exception()));\n        }\n    }\n\n    void EnsureSupportForPortableInstall(Execution::Context& context)\n    {\n        auto installerType = context.Get<Execution::Data::Installer>().value().EffectiveInstallerType();\n\n        if (installerType == InstallerTypeEnum::Portable)\n        {\n            context <<\n                EnsureValidArgsForPortableInstall <<\n                EnsureVolumeSupportsReparsePoints;\n        }\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/PortableFlow.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"ExecutionContext.h\"\n\nnamespace AppInstaller::CLI::Workflow\n{\n    // Installs the portable package.\n    // Required Args: None\n    // Inputs: Manifest, Scope, Rename, Location\n    // Outputs: None\n    void PortableInstallImpl(Execution::Context& context);\n\n    // Uninstalls the portable package.\n    // Required Args: None\n    // Inputs: ProductCode, Scope, Architecture\n    // Outputs: None\n    void PortableUninstallImpl(Execution::Context& context);\n\n    // Verifies that the portable install operation is supported.\n    // Required Args: None\n    // Inputs: Scope, Rename\n    // Outputs: None\n    void EnsureSupportForPortableInstall(Execution::Context& context);\n\n    // Initializes the portable installer.\n    // Required Args: None\n    // Inputs: Scope, Architecture, Manifest, Installer\n    // Outputs: None\n    void InitializePortableInstaller(Execution::Context& context);\n\n    // Verifies that the package identifier and the source identifier match the ARP entry.\n    // Required Args: None\n    // Inputs: Manifest, PackageVersion, PortableInstaller\n    // Outputs: None\n    void VerifyPackageAndSourceMatch(Execution::Context& context);\n}"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/PromptFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"PromptFlow.h\"\n#include \"ShowFlow.h\"\n#include <winget/UserSettings.h>\n\nusing namespace AppInstaller::CLI::Execution;\nusing namespace AppInstaller::Settings;\nusing namespace AppInstaller::Utility::literals;\n\nnamespace AppInstaller::CLI::Workflow\n{\n    namespace\n    {\n        bool IsInteractivityAllowed(Execution::Context& context)\n        {\n            // Interactivity can be disabled for several reasons:\n            //   * We are running in a non-interactive context (e.g., COM call)\n            //   * It is disabled in the settings\n            //   * It was disabled from the command line\n\n            if (WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::DisableInteractivity))\n            {\n                AICLI_LOG(CLI, Verbose, << \"Skipping prompt. Interactivity is disabled due to non-interactive context.\");\n                return false;\n            }\n\n            if (context.Args.Contains(Execution::Args::Type::DisableInteractivity))\n            {\n                AICLI_LOG(CLI, Verbose, << \"Skipping prompt. Interactivity is disabled by command line argument.\");\n                return false;\n            }\n\n            if (Settings::User().Get<Settings::Setting::InteractivityDisable>())\n            {\n                AICLI_LOG(CLI, Verbose, << \"Skipping prompt. Interactivity is disabled in settings.\");\n                return false;\n            }\n\n            return true;\n        }\n\n        bool HandleSourceAgreementsForOneSource(Execution::Context& context, const Repository::Source& source)\n        {\n            auto details = source.GetDetails();\n            AICLI_LOG(CLI, Verbose, << \"Checking Source agreements for source: \" << details.Name);\n\n            if (source.CheckSourceAgreements())\n            {\n                AICLI_LOG(CLI, Verbose, << \"Source agreements satisfied. Source: \" << details.Name);\n                return true;\n            }\n\n            // Show source agreements\n            context.Reporter.Info()\n                << Execution::SourceInfoEmphasis\n                << Resource::String::SourceAgreementsTitle(Utility::LocIndView{ details.Name })\n                << std::endl;\n\n            const auto& agreements = source.GetInformation().SourceAgreements;\n\n            for (const auto& agreement : agreements)\n            {\n                if (!agreement.Label.empty())\n                {\n                    context.Reporter.Info() << Execution::SourceInfoEmphasis << Utility::LocIndString{ agreement.Label } << \": \"_liv;\n                }\n\n                if (!agreement.Text.empty())\n                {\n                    context.Reporter.Info() << Utility::LocIndString{ agreement.Text } << std::endl;\n                }\n\n                if (!agreement.Url.empty())\n                {\n                    context.Reporter.Info() << Utility::LocIndString{ agreement.Url } << std::endl;\n                }\n            }\n\n            // Show message for each individual implicit agreement field\n            auto fields = source.GetAgreementFieldsFromSourceInformation();\n            if (WI_IsFlagSet(fields, Repository::ImplicitAgreementFieldEnum::Market))\n            {\n                context.Reporter.Info() << Resource::String::SourceAgreementsMarketMessage << std::endl;\n            }\n\n            context.Reporter.Info() << std::endl;\n\n            bool accepted = context.Args.Contains(Execution::Args::Type::AcceptSourceAgreements);\n\n            if (!accepted && IsInteractivityAllowed(context))\n            {\n                accepted = context.Reporter.PromptForBoolResponse(Resource::String::SourceAgreementsPrompt);\n            }\n\n            if (accepted)\n            {\n                AICLI_LOG(CLI, Verbose, << \"Source agreements accepted. Source: \" << details.Name);\n                source.SaveAcceptedSourceAgreements();\n            }\n            else\n            {\n                AICLI_LOG(CLI, Verbose, << \"Source agreements not accepted. Source: \" << details.Name);\n            }\n\n            return accepted;\n        }\n\n        // An interface for defining prompts to the user regarding a package.\n        // Note that each prompt may behave differently when running non-interactively\n        // (e.g. failing if it is needed vs. continuing silently), and they may\n        // do some work while checking if the prompt is needed even if no prompt is shown,\n        // so they need to always run.\n        struct PackagePrompt\n        {\n            virtual ~PackagePrompt() = default;\n\n            // Determines whether a package needs this prompt.\n            // Inputs: Manifest, Installer\n            // Outputs: None\n            virtual bool PackageNeedsPrompt(Execution::Context& context) = 0;\n\n            // Prompts for the information needed for a single package.\n            // Inputs: Manifest, Installer\n            // Outputs: None\n            virtual void PromptForSinglePackage(Execution::Context& context) = 0;\n\n            // Prompts for the information needed for multiple packages.\n            // Inputs: Manifest, Installer (for each sub context)\n            // Outputs: None\n            virtual void PromptForMultiplePackages(Execution::Context& context, std::vector<Execution::Context*>& packagesToPrompt) = 0;\n        };\n\n        // Prompt for accepting package agreements.\n        struct PackageAgreementsPrompt : public PackagePrompt\n        {\n            PackageAgreementsPrompt(bool ensureAgreementsAcceptance) : m_ensureAgreementsAcceptance(ensureAgreementsAcceptance) {}\n\n            bool PackageNeedsPrompt(Execution::Context& context) override\n            {\n                const auto& agreements = context.Get<Execution::Data::Manifest>().CurrentLocalization.Get<AppInstaller::Manifest::Localization::Agreements>();\n                return !agreements.empty();\n            }\n\n            void PromptForSinglePackage(Execution::Context& context) override\n            {\n                ShowPackageAgreements(context);\n                EnsurePackageAgreementsAcceptance(context, /* showPrompt */ true);\n            }\n\n            void PromptForMultiplePackages(Execution::Context& context, std::vector<Execution::Context*>& packagesToPrompt) override\n            {\n                for (auto packageContext : packagesToPrompt)\n                {\n                    // Show agreements for each package\n                    Execution::Context& showContext = *packageContext;\n                    auto previousThreadGlobals = showContext.SetForCurrentThread();\n\n                    ShowPackageAgreements(showContext);\n                    if (showContext.IsTerminated())\n                    {\n                        AICLI_TERMINATE_CONTEXT(showContext.GetTerminationHR());\n                    }\n                }\n\n                EnsurePackageAgreementsAcceptance(context, /* showPrompt */ true);\n            }\n\n        private:\n            void ShowPackageAgreements(Execution::Context& context)\n            {\n                const auto& manifest = context.Get<Execution::Data::Manifest>();\n                auto agreements = manifest.CurrentLocalization.Get<AppInstaller::Manifest::Localization::Agreements>();\n\n                if (agreements.empty())\n                {\n                    // Nothing to do\n                    return;\n                }\n\n                context << Workflow::ReportManifestIdentityWithVersion(Resource::String::ReportIdentityForAgreements) << Workflow::ShowAgreementsInfo;\n                context.Reporter.EmptyLine();\n            }\n\n            void EnsurePackageAgreementsAcceptance(Execution::Context& context, bool showPrompt) const\n            {\n                if (!m_ensureAgreementsAcceptance)\n                {\n                    return;\n                }\n\n                if (context.Args.Contains(Execution::Args::Type::AcceptPackageAgreements))\n                {\n                    AICLI_LOG(CLI, Info, << \"Package agreements accepted by CLI flag\");\n                    return;\n                }\n\n                if (showPrompt)\n                {\n                    AICLI_LOG(CLI, Verbose, << \"Prompting to accept package agreements\");\n                    if (IsInteractivityAllowed(context))\n                    {\n                        bool accepted = context.Reporter.PromptForBoolResponse(Resource::String::PackageAgreementsPrompt);\n                        if (accepted)\n                        {\n                            AICLI_LOG(CLI, Info, << \"Package agreements accepted in prompt\");\n                            return;\n                        }\n                        else\n                        {\n                            AICLI_LOG(CLI, Info, << \"Package agreements not accepted in prompt\");\n                        }\n                    }\n                }\n\n                AICLI_LOG(CLI, Error, << \"Package agreements were not agreed to.\");\n                context.Reporter.Error() << Resource::String::PackageAgreementsNotAgreedTo << std::endl;\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED);\n            }\n\n            bool m_ensureAgreementsAcceptance;\n        };\n\n        // Prompt for getting the install root when a package requires it and it is not\n        // specified by the settings.\n        struct InstallRootPrompt : public PackagePrompt\n        {\n            InstallRootPrompt() : m_installLocation(User().Get<Setting::InstallDefaultRoot>()) {}\n\n            bool PackageNeedsPrompt(Execution::Context& context) override\n            {\n                if (context.Get<Execution::Data::Installer>()->InstallLocationRequired &&\n                    !context.Args.Contains(Execution::Args::Type::InstallLocation))\n                {\n                    AICLI_LOG(CLI, Info, << \"Package [\" << context.Get<Execution::Data::Manifest>().Id << \"] requires an install location.\");\n\n                    // An install location is required but one wasn't provided.\n                    // Check if there is a default one from settings.\n                    if (m_installLocation.empty())\n                    {\n                        // We need to prompt\n                        return true;\n                    }\n                    else\n                    {\n                        // Use the default\n                        SetInstallLocation(context);\n                    }\n                }\n\n                return false;\n            }\n\n            void PromptForSinglePackage(Execution::Context& context) override\n            {\n                context.Reporter.Info() << Resource::String::InstallerRequiresInstallLocation << std::endl;\n                PromptForInstallRoot(context);\n\n                // When prompting for a single package, we use the provided location directly.\n                // This is different from when we prompt for multiple packages or use the root in the settings.\n                context.Args.AddArg(Execution::Args::Type::InstallLocation, m_installLocation.u8string());\n            }\n\n            void PromptForMultiplePackages(Execution::Context& context, std::vector<Execution::Context*>& packagesToPrompt) override\n            {\n                // Report packages that will be affected.\n                context.Reporter.Info() << Resource::String::InstallersRequireInstallLocation << std::endl;\n                for (auto packageContext : packagesToPrompt)\n                {\n                    *packageContext << ReportManifestIdentityWithVersion(\" - \"_liv,  Execution::Reporter::Level::Warning);\n                    if (packageContext->IsTerminated())\n                    {\n                        AICLI_TERMINATE_CONTEXT(packageContext->GetTerminationHR());\n                    }\n                }\n\n                PromptForInstallRoot(context);\n\n                // Set the install location for each package.\n                for (auto packageContext : packagesToPrompt)\n                {\n                    SetInstallLocation(*packageContext);\n                }\n            }\n\n        private:\n            void PromptForInstallRoot(Execution::Context& context)\n            {\n                if (!IsInteractivityAllowed(context))\n                {\n                    AICLI_LOG(CLI, Error, << \"Install location is required but was not provided.\");\n                    context.Reporter.Error() << Resource::String::InstallLocationNotProvided << std::endl;\n                    AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_INSTALL_LOCATION_REQUIRED);\n                }\n\n                AICLI_LOG(CLI, Info, << \"Prompting for install root.\");\n                m_installLocation = context.Reporter.PromptForPath(Resource::String::PromptForInstallRoot);\n                if (m_installLocation.empty())\n                {\n                    AICLI_LOG(CLI, Error, << \"Install location is required but the provided path was empty.\");\n                    context.Reporter.Error() << Resource::String::InstallLocationNotProvided << std::endl;\n                    AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_INSTALL_LOCATION_REQUIRED);\n                }\n                AICLI_LOG(CLI, Info, << \"Proceeding with installation using install root: \" << m_installLocation);\n            }\n\n            // Sets the install location for an execution context.\n            // The install location is obtained by appending the package ID to the install root.\n            // This function assumes that m_installLocation is set, either from settings or from the prompt,\n            // and that the context does not already have an install location.\n            void SetInstallLocation(Execution::Context& context)\n            {\n                auto packageId = context.Get<Execution::Data::Manifest>().Id;\n                auto installLocation = m_installLocation;\n                installLocation += \"\\\\\" + packageId;\n                AICLI_LOG(CLI, Info, << \"Setting install location for package [\" << packageId << \"] to: \" << installLocation);\n                context.Args.AddArg(Execution::Args::Type::InstallLocation, installLocation.u8string());\n            }\n\n            std::filesystem::path m_installLocation;\n        };\n\n        // Prompt asking whether to continue when an installer will abort the terminal.\n        struct InstallerAbortsTerminalPrompt : public PackagePrompt\n        {\n            bool PackageNeedsPrompt(Execution::Context& context) override\n            {\n                return context.Get<Execution::Data::Installer>()->InstallerAbortsTerminal;\n            }\n\n            void PromptForSinglePackage(Execution::Context& context) override\n            {\n                AICLI_LOG(CLI, Info, << \"This installer may abort the terminal\");\n                context.Reporter.Warn() << Resource::String::InstallerAbortsTerminal << std::endl;\n                PromptToProceed(context);\n            }\n\n            void PromptForMultiplePackages(Execution::Context& context, std::vector<Execution::Context*>& packagesToPrompt) override\n            {\n                AICLI_LOG(CLI, Info, << \"One or more installers may abort the terminal\");\n                context.Reporter.Warn() << Resource::String::InstallersAbortTerminal << std::endl;\n                for (auto packageContext : packagesToPrompt)\n                {\n                    *packageContext << ReportManifestIdentityWithVersion(\" - \"_liv, Execution::Reporter::Level::Warning);\n                    if (packageContext->IsTerminated())\n                    {\n                        AICLI_TERMINATE_CONTEXT(packageContext->GetTerminationHR());\n                    }\n                }\n\n                PromptToProceed(context);\n            }\n\n        private:\n            void PromptToProceed(Execution::Context& context)\n            {\n                AICLI_LOG(CLI, Info, << \"Prompting before proceeding with installer that aborts terminal.\");\n                if (!IsInteractivityAllowed(context))\n                {\n                    return;\n                }\n\n                bool accepted = context.Reporter.PromptForBoolResponse(Resource::String::PromptToProceed, Reporter::Level::Warning, true);\n                if (accepted)\n                {\n                    AICLI_LOG(CLI, Info, << \"Proceeding with installation\");\n                }\n                else\n                {\n                    AICLI_LOG(CLI, Error, << \"Aborting installation\");\n                    context.Reporter.Error() << Resource::String::Cancelled << std::endl;\n                    AICLI_TERMINATE_CONTEXT(E_ABORT);\n                }\n            }\n        };\n\n        // Gets all the prompts that may be displayed, in order of appearance\n        std::vector<std::unique_ptr<PackagePrompt>> GetPackagePrompts(bool ensureAgreementsAcceptance = true, bool installerDownloadOnly = false)\n        {\n            std::vector<std::unique_ptr<PackagePrompt>> result;\n\n            if (installerDownloadOnly)\n            {\n                result.push_back(std::make_unique<PackageAgreementsPrompt>(ensureAgreementsAcceptance));\n            }\n            else\n            {\n                result.push_back(std::make_unique<PackageAgreementsPrompt>(ensureAgreementsAcceptance));\n                result.push_back(std::make_unique<InstallRootPrompt>());\n                result.push_back(std::make_unique<InstallerAbortsTerminalPrompt>());\n            }\n\n            return result;\n        }\n    }\n\n    void HandleSourceAgreements::operator()(Execution::Context& context) const\n    {\n        bool allAccepted = true;\n\n        if (m_source.IsComposite())\n        {\n            for (auto const& source : m_source.GetAvailableSources())\n            {\n                if (!HandleSourceAgreementsForOneSource(context, source))\n                {\n                    allAccepted = false;\n                }\n            }\n        }\n        else\n        {\n            allAccepted = HandleSourceAgreementsForOneSource(context, m_source);\n        }\n\n        if (!allAccepted)\n        {\n            context.Reporter.Error() << Resource::String::SourceAgreementsNotAgreedTo << std::endl;\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED);\n        }\n    }\n\n    void ShowPromptsForSinglePackage::operator()(Execution::Context& context) const\n    {\n        bool installerDownloadOnly = WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::InstallerDownloadOnly);\n\n        for (auto& prompt : GetPackagePrompts(true, installerDownloadOnly))\n        {\n            // Show the prompt if needed\n            if (prompt->PackageNeedsPrompt(context))\n            {\n                prompt->PromptForSinglePackage(context);\n            }\n\n            if (context.IsTerminated())\n            {\n                return;\n            }\n        }\n    }\n\n    void ShowPromptsForMultiplePackages::operator()(Execution::Context& context) const\n    {\n        for (auto& prompt : GetPackagePrompts(m_ensureAgreementsAcceptance, m_installerDownloadOnly))\n        {\n            // Find which packages need this prompt\n            std::vector<Execution::Context*> packagesToPrompt;\n            for (auto& packageContext : context.Get<Execution::Data::PackageSubContexts>())\n            {\n                if (prompt->PackageNeedsPrompt(*packageContext))\n                {\n                    packagesToPrompt.push_back(packageContext.get());\n                }\n            }\n\n            // Prompt only if needed\n            if (!packagesToPrompt.empty())\n            {\n                prompt->PromptForMultiplePackages(context, packagesToPrompt);\n                if (context.IsTerminated())\n                {\n                    return;\n                }\n            }\n        }\n    }\n\n    void RequireInteractivity::operator()(Execution::Context& context) const\n    {\n        if (!IsInteractivityAllowed(context))\n        {\n            AICLI_TERMINATE_CONTEXT(m_nonInteractiveError);\n        }\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/PromptFlow.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"ExecutionContext.h\"\n\nnamespace AppInstaller::CLI::Workflow\n{\n    // Handles all opened source(s) agreements if needed.\n    // Required Args: The source to be checked for agreements\n    // Inputs: None\n    // Outputs: None\n    struct HandleSourceAgreements : public WorkflowTask\n    {\n        HandleSourceAgreements(Repository::Source source) : WorkflowTask(\"HandleSourceAgreements\"), m_source(std::move(source)) {}\n\n        void operator()(Execution::Context& context) const override;\n\n    private:\n        Repository::Source m_source;\n    };\n\n    // Shows all the prompts required for a single package, e.g. for package agreements\n    // Required Args: None\n    // Inputs: Manifest, Installer\n    // Outputs: None\n    struct ShowPromptsForSinglePackage : public WorkflowTask\n    {\n        ShowPromptsForSinglePackage(bool ensureAgreementsAcceptance) :\n            WorkflowTask(\"ShowPromptsForSinglePackage\"), m_ensureAgreementsAcceptance(ensureAgreementsAcceptance) {}\n\n        void operator()(Execution::Context& context) const override;\n\n    private:\n        bool m_ensureAgreementsAcceptance;\n    };\n\n    // Shows all the prompts required for multiple package, e.g. for package agreements\n    // Required Args: None\n    // Inputs: PackageSubContexts\n    // Outputs: None\n    struct ShowPromptsForMultiplePackages : public WorkflowTask\n    {\n        ShowPromptsForMultiplePackages(bool ensureAgreementsAcceptance, bool installerDownloadOnly) :\n            WorkflowTask(\"ShowPromptsForMultiplePackages\"), m_ensureAgreementsAcceptance(ensureAgreementsAcceptance),\n            m_installerDownloadOnly(installerDownloadOnly) {}\n\n        void operator()(Execution::Context& context) const override;\n\n    private:\n        bool m_ensureAgreementsAcceptance;\n        bool m_installerDownloadOnly;\n    };\n\n    // If the context is not interactive, terminate it with the given HRESULT.\n    // Required Args: None\n    // Inputs: None\n    // Outputs: None\n    struct RequireInteractivity : public WorkflowTask\n    {\n        RequireInteractivity(HRESULT nonInteractiveError) :\n            WorkflowTask(\"RequireInteractivity\"), m_nonInteractiveError(nonInteractiveError) {}\n\n        void operator()(Execution::Context& context) const override;\n\n    private:\n        HRESULT m_nonInteractiveError;\n    };\n}"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/RepairFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"RepairFlow.h\"\r\n#include \"Workflows/ShellExecuteInstallerHandler.h\"\r\n#include \"Workflows/WorkflowBase.h\"\r\n#include \"Workflows/DownloadFlow.h\"\r\n#include \"Workflows/ArchiveFlow.h\"\r\n#include \"Workflows/InstallFlow.h\"\r\n#include \"Workflows/PromptFlow.h\"\r\n#include \"winget/ManifestCommon.h\"\r\n#include \"AppInstallerDeployment.h\"\r\n#include \"AppInstallerMsixInfo.h\"\r\n#include \"AppInstallerSynchronization.h\"\r\n#include \"MSStoreInstallerHandler.h\"\r\n#include <winget/ManifestComparator.h>\r\n#include <winget/PackageVersionSelection.h>\r\n\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Msix;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::CLI::Execution;\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    // Internal implementation details\r\n    namespace\r\n    {\r\n\r\n        void SetUninstallStringInContext(Execution::Context& context)\r\n        {\r\n            const auto& installedPackageVersion = context.Get<Execution::Data::InstalledPackageVersion>();\r\n            IPackageVersion::Metadata packageMetadata = installedPackageVersion->GetMetadata();\r\n\r\n            // Default to silent unless it is not present or interactivity is requested\r\n            auto uninstallCommandItr = packageMetadata.find(PackageVersionMetadata::SilentUninstallCommand);\r\n\r\n            if ((!context.Args.Contains(Execution::Args::Type::Silent) && uninstallCommandItr == packageMetadata.end())\r\n                || context.Args.Contains(Execution::Args::Type::Interactive))\r\n            {\r\n                auto interactiveItr = packageMetadata.find(PackageVersionMetadata::StandardUninstallCommand);\r\n                if (interactiveItr != packageMetadata.end())\r\n                {\r\n                    uninstallCommandItr = interactiveItr;\r\n                }\r\n            }\r\n\r\n            if (uninstallCommandItr == packageMetadata.end())\r\n            {\r\n                context.Reporter.Error() << Resource::String::NoRepairInfoFound << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_NO_REPAIR_INFO_FOUND);\r\n            }\r\n\r\n            context.Add<Execution::Data::UninstallString>(uninstallCommandItr->second);\r\n        }\r\n\r\n        void SetModifyPathInContext(Execution::Context& context)\r\n        {\r\n            const auto& installedPackageVersion = context.Get<Execution::Data::InstalledPackageVersion>();\r\n            IPackageVersion::Metadata packageMetadata = installedPackageVersion->GetMetadata();\r\n\r\n            // Default to silent unless it is not present or interactivity is requested\r\n            auto modifyPathItr = packageMetadata.find(PackageVersionMetadata::StandardModifyCommand);\r\n            if (modifyPathItr == packageMetadata.end())\r\n            {\r\n                context.Reporter.Error() << Resource::String::NoRepairInfoFound << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_NO_REPAIR_INFO_FOUND);\r\n            }\r\n\r\n            context.Add<Execution::Data::ModifyPath>(modifyPathItr->second);\r\n        }\r\n\r\n        void SetProductCodesInContext(Execution::Context& context)\r\n        {\r\n            const auto& installedPackageVersion = context.Get<Execution::Data::InstalledPackageVersion>();\r\n            auto productCodes = installedPackageVersion->GetMultiProperty(PackageVersionMultiProperty::ProductCode);\r\n\r\n            if (productCodes.empty())\r\n            {\r\n                context.Reporter.Error() << Resource::String::NoRepairInfoFound << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_NO_REPAIR_INFO_FOUND);\r\n            }\r\n\r\n            context.Add<Execution::Data::ProductCodes>(productCodes);\r\n        }\r\n\r\n        void SetPackageFamilyNamesInContext(Execution::Context& context)\r\n        {\r\n            const auto& installedPackageVersion = context.Get<Execution::Data::InstalledPackageVersion>();\r\n\r\n            auto packageFamilyNames = installedPackageVersion->GetMultiProperty(PackageVersionMultiProperty::PackageFamilyName);\r\n            if (packageFamilyNames.empty())\r\n            {\r\n                context.Reporter.Error() << Resource::String::NoRepairInfoFound << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_NO_REPAIR_INFO_FOUND);\r\n            }\r\n\r\n            context.Add<Execution::Data::PackageFamilyNames>(packageFamilyNames);\r\n        }\r\n\r\n        InstallerTypeEnum GetInstalledType(Execution::Context& context)\r\n        {\r\n            const auto& installedPackage = context.Get<Execution::Data::InstalledPackageVersion>();\r\n            std::string installedType = installedPackage->GetMetadata()[PackageVersionMetadata::InstalledType];\r\n            return ConvertToInstallerTypeEnum(installedType);\r\n        }\r\n\r\n        void ApplicabilityCheckForInstalledPackage(Execution::Context& context)\r\n        {\r\n            // Installed Package repair applicability check\r\n            const auto& installedPackageVersion = context.Get<Execution::Data::InstalledPackageVersion>();\r\n\r\n            const std::string installerType = context.Get<Execution::Data::InstalledPackageVersion>()->GetMetadata()[PackageVersionMetadata::InstalledType];\r\n            InstallerTypeEnum installerTypeEnum = ConvertToInstallerTypeEnum(installerType);\r\n\r\n            if (installerTypeEnum == InstallerTypeEnum::Portable || installerTypeEnum == InstallerTypeEnum::Unknown)\r\n            {\r\n                context.Reporter.Error() << Resource::String::RepairOperationNotSupported << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_REPAIR_NOT_SUPPORTED);\r\n            }\r\n\r\n            IPackageVersion::Metadata packageMetadata = installedPackageVersion->GetMetadata();\r\n\r\n            auto noModifyItr = packageMetadata.find(PackageVersionMetadata::NoModify);\r\n            std::string noModifyARPFlag = noModifyItr != packageMetadata.end() ? noModifyItr->second : std::string();\r\n\r\n            auto noRepairItr = packageMetadata.find(PackageVersionMetadata::NoRepair);\r\n            std::string noRepairARPFlag = noRepairItr != packageMetadata.end() ? noRepairItr->second : std::string();\r\n\r\n            if (Utility::IsDwordFlagSet(noModifyARPFlag) || Utility::IsDwordFlagSet(noRepairARPFlag))\r\n            {\r\n                context.Reporter.Error() << Resource::String::RepairOperationNotSupported << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_REPAIR_NOT_SUPPORTED);\r\n            }\r\n        }\r\n\r\n        void ApplicabilityCheckForAvailablePackage(Execution::Context& context)\r\n        {\r\n            // Skip the Available Package applicability check for MSI and MSIX repair as they aren't needed.\r\n            if (!context.Contains(Execution::Data::Installer))\r\n            {\r\n                return;\r\n            }\r\n\r\n            // Selected Installer repair applicability check\r\n            auto installerType = context.Get<Execution::Data::Installer>()->EffectiveInstallerType();\r\n            auto repairBehavior = context.Get<Execution::Data::Installer>()->RepairBehavior;\r\n\r\n            if (installerType == InstallerTypeEnum::Portable || installerType == InstallerTypeEnum::Unknown)\r\n            {\r\n                context.Reporter.Error() << Resource::String::RepairOperationNotSupported << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_REPAIR_NOT_SUPPORTED);\r\n            }\r\n\r\n            // Repair behavior is required for Burn, Inno, Nullsoft, Exe installers\r\n            if (DoesInstallerTypeRequireRepairBehaviorForRepair(installerType) &&\r\n                repairBehavior == RepairBehaviorEnum::Unknown)\r\n            {\r\n                context.Reporter.Error() << Resource::String::NoRepairInfoFound << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_NO_REPAIR_INFO_FOUND);\r\n            }\r\n        }\r\n\r\n        void HandleModifyRepairBehavior(Execution::Context& context, std::string& repairCommand)\r\n        {\r\n            SetModifyPathInContext(context);\r\n            repairCommand += context.Get<Execution::Data::ModifyPath>();\r\n        }\r\n\r\n        void HandleInstallerRepairBehavior(Execution::Context& context, InstallerTypeEnum installerType)\r\n        {\r\n            context <<\r\n                ShowInstallationDisclaimer <<\r\n                ShowPromptsForSinglePackage(/* ensureAcceptance */ true) <<\r\n                DownloadInstaller;\r\n\r\n            if (installerType == InstallerTypeEnum::Zip)\r\n            {\r\n                context <<\r\n                    ScanArchiveFromLocalManifest <<\r\n                    ExtractFilesFromArchive <<\r\n                    VerifyAndSetNestedInstaller;\r\n            }\r\n        }\r\n\r\n        void HandleUninstallerRepairBehavior(Execution::Context& context, std::string& repairCommand)\r\n        {\r\n            SetUninstallStringInContext(context);\r\n            repairCommand += context.Get<Execution::Data::UninstallString>();\r\n        }\r\n\r\n        void GenerateRepairString(Execution::Context& context)\r\n        {\r\n            const auto& installer = context.Get<Execution::Data::Installer>();\r\n            auto installerType = installer->BaseInstallerType;\r\n            auto repairBehavior = installer->RepairBehavior;\r\n\r\n            std::string repairCommand;\r\n\r\n            switch (repairBehavior)\r\n            {\r\n            case RepairBehaviorEnum::Modify:\r\n                HandleModifyRepairBehavior(context, repairCommand);\r\n                break;\r\n            case RepairBehaviorEnum::Installer:\r\n                HandleInstallerRepairBehavior(context, installerType);\r\n                break;\r\n            case RepairBehaviorEnum::Uninstaller:\r\n                HandleUninstallerRepairBehavior(context, repairCommand);\r\n                break;\r\n            case RepairBehaviorEnum::Unknown:\r\n            default:\r\n                context.Reporter.Error() << Resource::String::NoRepairInfoFound << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_NO_REPAIR_INFO_FOUND);\r\n            }\r\n\r\n            context <<\r\n                GetInstallerArgs;\r\n\r\n            // If the repair behavior is set to 'Installer', we can proceed with the repair command as is.\r\n            // For repair behaviors other than 'Installer', subsequent steps will be necessary to prepare the repair command.\r\n            if (repairBehavior == RepairBehaviorEnum::Installer)\r\n            {\r\n                return;\r\n            }\r\n\r\n            if (repairCommand.empty())\r\n            {\r\n                context.Reporter.Error() << Resource::String::NoRepairInfoFound << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_NO_REPAIR_INFO_FOUND);\r\n            }\r\n\r\n            repairCommand += \" \";\r\n            repairCommand += context.Get<Execution::Data::InstallerArgs>();\r\n            context.Add<Execution::Data::RepairString>(repairCommand);\r\n        }\r\n\r\n        bool IsInstallerMappingRequired(Execution::Context& context)\r\n        {\r\n            InstallerTypeEnum installerTypeEnum = GetInstalledType(context);\r\n\r\n            switch (installerTypeEnum)\r\n            {\r\n            case InstallerTypeEnum::Msi:\r\n                return false;\r\n            case InstallerTypeEnum::Msix:\r\n                // For MSIX packages that are from the Microsoft Store, selecting an installer is required.\r\n                if (context.Contains(Execution::Data::Package))\r\n                {\r\n                    auto availablePackages = context.Get<Execution::Data::Package>()->GetAvailable();\r\n\r\n                    if (availablePackages.size() == 1 && availablePackages[0]->GetSource() == WellKnownSource::MicrosoftStore)\r\n                    {\r\n                        return true;\r\n                    }\r\n                }\r\n\r\n                // For MSIX packages that are not from the Microsoft Store, selecting an installer is not required.\r\n                return false;\r\n            default:\r\n                return true;\r\n            }\r\n        }\r\n\r\n        void HandleModifyOrUninstallerRepair(Execution::Context& context, RepairBehaviorEnum repairBehavior)\r\n        {\r\n            context <<\r\n                ShellExecuteRepairImpl <<\r\n                ReportRepairResult(RepairBehaviorToString(repairBehavior), APPINSTALLER_CLI_ERROR_EXEC_REPAIR_FAILED);\r\n        }\r\n\r\n        void HandleInstallerRepair(Execution::Context& context, RepairBehaviorEnum repairBehavior)\r\n        {\r\n            context <<\r\n                ShellExecuteInstallImpl <<\r\n                ReportInstallerResult(RepairBehaviorToString(repairBehavior), APPINSTALLER_CLI_ERROR_EXEC_REPAIR_FAILED);\r\n        }\r\n    }\r\n\r\n    void RunRepairForRepairBehaviorBasedInstaller(Execution::Context& context)\r\n    {\r\n        const auto& installer = context.Get<Execution::Data::Installer>();\r\n        auto repairBehavior = installer->RepairBehavior;\r\n\r\n        switch (repairBehavior)\r\n        {\r\n        case RepairBehaviorEnum::Modify:\r\n        case RepairBehaviorEnum::Uninstaller:\r\n            HandleModifyOrUninstallerRepair(context, repairBehavior);\r\n            break;\r\n        case RepairBehaviorEnum::Installer:\r\n            HandleInstallerRepair(context, repairBehavior);\r\n            break;\r\n        default:\r\n            context.Reporter.Error() << Resource::String::NoRepairInfoFound << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_NO_REPAIR_INFO_FOUND);\r\n        }\r\n    }\r\n\r\n    void RepairMsiBasedInstaller(Execution::Context& context)\r\n    {\r\n        context <<\r\n            ShellExecuteMsiExecRepair <<\r\n            ReportRepairResult(\"MsiExec\", APPINSTALLER_CLI_ERROR_EXEC_REPAIR_FAILED);\r\n    }\r\n\r\n    void RepairApplicabilityCheck(Execution::Context& context)\r\n    {\r\n        context <<\r\n            ApplicabilityCheckForInstalledPackage <<\r\n            ApplicabilityCheckForAvailablePackage;\r\n    }\r\n\r\n    void ExecuteRepair(Execution::Context& context)\r\n    {\r\n        InstallerTypeEnum installerTypeEnum = context.Contains(Execution::Data::Installer) ? context.Get<Execution::Data::Installer>()->EffectiveInstallerType() : GetInstalledType(context);\r\n\r\n        Synchronization::CrossProcessInstallLock lock;\r\n\r\n        if (!ExemptFromSingleInstallLocking(installerTypeEnum))\r\n        {\r\n            // Acquire the lock , if the operation is cancelled it will return false so we will also return.\r\n            if (!context.Reporter.ExecuteWithProgress([&](IProgressCallback& callback)\r\n                {\r\n                    callback.SetProgressMessage(Resource::String::InstallWaitingOnAnother());\r\n                    return lock.Acquire(callback);\r\n                }))\r\n            {\r\n                AICLI_LOG(CLI, Info, << \"Abandoning attempt to acquire repair lock due to cancellation\");\r\n                return;\r\n            }\r\n        }\r\n\r\n        switch (installerTypeEnum)\r\n        {\r\n        case InstallerTypeEnum::Exe:\r\n        case InstallerTypeEnum::Burn:\r\n        case InstallerTypeEnum::Inno:\r\n        case InstallerTypeEnum::Nullsoft:\r\n        {\r\n            context <<\r\n                RunRepairForRepairBehaviorBasedInstaller;\r\n        }\r\n        break;\r\n        case InstallerTypeEnum::Msi:\r\n        case InstallerTypeEnum::Wix:\r\n        {\r\n            context <<\r\n                RepairMsiBasedInstaller;\r\n        }\r\n        break;\r\n        case InstallerTypeEnum::Msix:\r\n        {\r\n            context <<\r\n                RepairMsixPackage;\r\n        }\r\n        break;\r\n        case InstallerTypeEnum::MSStore:\r\n        {\r\n            context <<\r\n                EnsureStorePolicySatisfied <<\r\n                MSStoreRepair;\r\n        }\r\n        break;\r\n        case InstallerTypeEnum::Portable:\r\n        default:\r\n            THROW_HR(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED));\r\n        }\r\n    }\r\n\r\n    void GetRepairInfo(Execution::Context& context)\r\n    {\r\n        InstallerTypeEnum installerTypeEnum = context.Contains(Execution::Data::Installer) ? context.Get<Execution::Data::Installer>()->BaseInstallerType : GetInstalledType(context);\r\n\r\n        switch (installerTypeEnum)\r\n        {\r\n            // Exe based installers, for installed package all gets mapped to exe extension.\r\n        case InstallerTypeEnum::Burn:\r\n        case InstallerTypeEnum::Exe:\r\n        case InstallerTypeEnum::Inno:\r\n        case InstallerTypeEnum::Nullsoft:\r\n        {\r\n            context <<\r\n                GenerateRepairString;\r\n        }\r\n        break;\r\n        // MSI based installers, for installed package all gets mapped to msi extension.\r\n        case InstallerTypeEnum::Msi:\r\n        case InstallerTypeEnum::Wix:\r\n        {\r\n            context <<\r\n                SetProductCodesInContext;\r\n        }\r\n        break;\r\n        // MSIX based installers, msix.\r\n        case InstallerTypeEnum::Msix:\r\n        {\r\n            context <<\r\n                SetPackageFamilyNamesInContext;\r\n        }\r\n        break;\r\n        case InstallerTypeEnum::MSStore:\r\n            break;\r\n        case InstallerTypeEnum::Portable:\r\n        default:\r\n            THROW_HR(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED));\r\n        }\r\n    }\r\n\r\n    void RepairMsixPackage(Execution::Context& context)\r\n    {\r\n        bool isMachineScope = Manifest::ConvertToScopeEnum(context.Args.GetArg(Execution::Args::Type::InstallScope)) == Manifest::ScopeEnum::Machine;\r\n\r\n        const auto& packageFamilyNames = context.Get<Execution::Data::PackageFamilyNames>();\r\n        context.Reporter.Info() << Resource::String::RepairFlowStartingPackageRepair << std::endl;\r\n\r\n        for (const auto& packageFamilyName : packageFamilyNames)\r\n        {\r\n            auto packageFullName = Msix::GetPackageFullNameFromFamilyName(packageFamilyName);\r\n\r\n            if (!packageFullName.has_value())\r\n            {\r\n                AICLI_LOG(CLI, Warning, << \"No package found with family name: \" << packageFamilyName);\r\n                continue;\r\n            }\r\n\r\n            AICLI_LOG(CLI, Info, << \"Repairing package: \" << packageFullName.value());\r\n\r\n            try\r\n            {\r\n                if (!isMachineScope)\r\n                {\r\n                    // Best effort repair by registering the package.\r\n                    context.Reporter.ExecuteWithProgress(std::bind(Deployment::RegisterPackage, packageFamilyName, std::placeholders::_1));\r\n                }\r\n                else\r\n                {\r\n                    context.Reporter.Error() << Resource::String::RepairFlowReturnCodeSystemNotSupported << std::endl;\r\n                    context.Add<Execution::Data::OperationReturnCode>(static_cast<DWORD>(APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED));\r\n                    AICLI_LOG(CLI, Error, << \"Device wide repair for msix type is not supported.\");\r\n                    AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED);\r\n                }\r\n            }\r\n            catch (const wil::ResultException& re)\r\n            {\r\n                context.Add<Execution::Data::OperationReturnCode>(re.GetErrorCode());\r\n                context << ReportRepairResult(\"MSIX\", re.GetErrorCode(), true);\r\n                return;\r\n            }\r\n        }\r\n\r\n        context.Reporter.Info() << Resource::String::RepairFlowRepairSuccess << std::endl;\r\n    }\r\n\r\n    void RepairSinglePackage(Execution::Context& context)\r\n    {\r\n        context <<\r\n            RepairApplicabilityCheck <<\r\n            GetRepairInfo <<\r\n            ReportExecutionStage(ExecutionStage::Execution) <<\r\n            ExecuteRepair <<\r\n            ReportExecutionStage(ExecutionStage::PostExecution);\r\n    }\r\n\r\n    void SelectApplicablePackageVersion(Execution::Context& context)\r\n    {\r\n        // If the repair flow is initiated with manifest, then we don't need to select the applicable package version.\r\n        if (context.Args.Contains(Args::Type::Manifest))\r\n        {\r\n            return;\r\n        }\r\n\r\n        const auto& installedPackage = context.Get<Execution::Data::InstalledPackageVersion>();\r\n\r\n        Utility::Version installedVersion = Utility::Version(installedPackage->GetProperty(PackageVersionProperty::Version));\r\n        if (installedVersion.IsUnknown())\r\n        {\r\n            context.Reporter.Error() << Resource::String::NoApplicableInstallers << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER);\r\n        }\r\n\r\n        std::string_view requestedVersion = context.Args.Contains(Execution::Args::Type::TargetVersion) ? context.Args.GetArg(Execution::Args::Type::TargetVersion) : installedVersion.ToString();\r\n        // If it's Store source with only one version unknown, use the unknown version for available version mapping.\r\n        const auto& package = context.Get<Execution::Data::Package>();\r\n        auto packageVersions = GetAvailableVersionsForInstalledVersion(package, installedPackage);\r\n        auto versionKeys = packageVersions->GetVersionKeys();\r\n        if (versionKeys.size() == 1)\r\n        {\r\n            auto packageVersion = packageVersions->GetVersion(versionKeys.at(0));\r\n            if (packageVersion->GetSource().IsWellKnownSource(WellKnownSource::MicrosoftStore) &&\r\n                Utility::Version{ packageVersion->GetProperty(PackageVersionProperty::Version) }.IsUnknown())\r\n            {\r\n                requestedVersion = \"\";\r\n            }\r\n        }\r\n\r\n        context <<\r\n            GetManifestWithVersionFromPackage(\r\n                requestedVersion,\r\n                context.Args.GetArg(Execution::Args::Type::Channel), false);\r\n    }\r\n\r\n    void SelectApplicableInstallerIfNecessary(Execution::Context& context)\r\n    {\r\n        // For MSI installers, the platform provides built-in support for repair via msiexec, hence no need to select an installer.\r\n        // Similarly, for MSIX packages that are not from the Microsoft Store, selecting an installer is not required.\r\n        if (IsInstallerMappingRequired(context))\r\n        {\r\n            context <<\r\n                SelectApplicablePackageVersion <<\r\n                SelectInstaller <<\r\n                EnsureApplicableInstaller;\r\n        }\r\n    }\r\n\r\n    void ReportRepairResult::operator()(Execution::Context& context) const\r\n    {\r\n        DWORD repairResult = context.Get<Execution::Data::OperationReturnCode>();\r\n\r\n        if (repairResult != 0)\r\n        {\r\n            auto& repairPackage = context.Contains(Execution::Data::PackageVersion) ?\r\n                context.Get<Execution::Data::PackageVersion>() :\r\n                context.Get<Execution::Data::InstalledPackageVersion>();\r\n\r\n            Logging::Telemetry().LogRepairFailure(\r\n                repairPackage->GetProperty(PackageVersionProperty::Id),\r\n                repairPackage->GetProperty(PackageVersionProperty::Version),\r\n                m_repairType,\r\n                repairResult);\r\n\r\n            if (m_isHResult)\r\n            {\r\n                context.Reporter.Error()\r\n                    << Resource::String::RepairFailedWithCode(Utility::LocIndView{ GetUserPresentableMessage(repairResult) })\r\n                    << std::endl;\r\n            }\r\n            else\r\n            {\r\n                context.Reporter.Error()\r\n                    << Resource::String::RepairFailedWithCode(repairResult)\r\n                    << std::endl;\r\n            }\r\n\r\n            // Show log path if available\r\n            if (context.Contains(Execution::Data::LogPath) && std::filesystem::exists(context.Get<Execution::Data::LogPath>()))\r\n            {\r\n                auto installerLogPath = Utility::LocIndString{ context.Get<Execution::Data::LogPath>().u8string() };\r\n                context.Reporter.Info() << Resource::String::InstallerLogAvailable(installerLogPath) << std::endl;\r\n            }\r\n\r\n            AICLI_TERMINATE_CONTEXT(m_hr);\r\n        }\r\n        else\r\n        {\r\n            context.Reporter.Info() << Resource::String::RepairFlowRepairSuccess << std::endl;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/RepairFlow.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ExecutionContext.h\"\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    // Execute the repair operation for RepairBehavior based installers.\r\n    // RequiredArgs:None\r\n    // Inputs: RepairBehavior, RepairString\r\n    // Outputs:None\r\n    void RunRepairForRepairBehaviorBasedInstaller(Execution::Context& context);\r\n\r\n    // Execute the repair operation for MSI based installers.\r\n    // RequiredArgs:None\r\n    // Inputs: ProductCodes\r\n    // Outputs:None\r\n    void RepairMsiBasedInstaller(Execution::Context& context);\r\n\r\n    // Applicability check for repair operation.\r\n    // RequiredArgs:None\r\n    // Inputs:InstalledPackageVersion, NoModify ?, NoRepair ?\r\n    // Outputs:None\r\n    void RepairApplicabilityCheck(Execution::Context& context);\r\n\r\n    // Execute the repair operation.\r\n    // RequiredArgs:None\r\n    // Inputs: InstallerType, RepairBehavior ?, RepairString? , ProductCodes?, PackageFamilyNames?\r\n    // Outputs:None\r\n    void ExecuteRepair(Execution::Context& context);\r\n\r\n    // Obtains the necessary information for repair operation.\r\n    // RequiredArgs:None\r\n    // Inputs:InstallerType\r\n    // Outputs:RepairString?, ProductCodes?, PackageFamilyNames?\r\n    void GetRepairInfo(Execution::Context& context);\r\n\r\n    // Perform the repair operation for the MSIX NonStore package.\r\n    // RequiredArgs:None\r\n    // Inputs:PackageFamilyNames , InstallScope?\r\n    // Outputs:None\r\n    void RepairMsixPackage(Execution::Context& context);\r\n\r\n    // Select the applicable package version by matching the installed package version with the available package version.\r\n    // RequiredArgs:None\r\n    // Inputs: Package,InstalledPackageVersion, AvailablePackageVersions\r\n    // Outputs:Manifest, PackageVersion, Installer\r\n    void SelectApplicablePackageVersion(Execution::Context& context);\r\n\r\n    /// <summary>\r\n    /// Select the applicable installer for the installed package if necessary.\r\n    // RequiredArgs:None\r\n    // Inputs: Package,InstalledPackageVersion, AvailablePackageVersions\r\n    // Outputs:Manifest, PackageVersion, Installer\r\n    void SelectApplicableInstallerIfNecessary(Execution::Context& context);\r\n\r\n    // Perform the repair operation for the single package.\r\n    // RequiredArgs:None\r\n    // Inputs: SearchResult, InstalledPackage, ApplicableInstaller\r\n    // Outputs:None\r\n    void RepairSinglePackage(Execution::Context& context);\r\n\r\n    // Reports the result of the repair.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: None\r\n    struct ReportRepairResult : public WorkflowTask\r\n    {\r\n        ReportRepairResult(std::string_view repairType, HRESULT hr, bool isHResult = false) :\r\n            WorkflowTask(\"ReportRepairResult\"),\r\n            m_repairType(repairType),\r\n            m_hr(hr),\r\n            m_isHResult(isHResult) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        // Repair type used for reporting failure.\r\n        std::string_view m_repairType;\r\n        // Result to return if the repair fails.\r\n        HRESULT m_hr;\r\n        // Whether the result is an HRESULT.\r\n        bool m_isHResult;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/ResumeFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"ResumeFlow.h\"\n#include \"winget/Reboot.h\"\n#include <AppInstallerRuntime.h>\n\nnamespace AppInstaller::CLI::Workflow\n{\n    void Checkpoint::operator()(Execution::Context& context) const\n    {\n        if (!Settings::ExperimentalFeature::IsEnabled(Settings::ExperimentalFeature::Feature::Resume))\n        {\n            return;\n        }\n\n        context.Checkpoint(m_checkpointName, m_contextData);\n    }\n\n    void RegisterStartupAfterReboot::operator()(Execution::Context& context) const\n    {\n        if (!Settings::ExperimentalFeature::IsEnabled(Settings::ExperimentalFeature::Feature::Resume))\n        {\n            return;\n        }\n\n        if (WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::RegisterResume))\n        {\n            auto executablePath = AppInstaller::Runtime::GetPathTo(AppInstaller::Runtime::PathName::CLIExecutable);\n\n            // RunOnce registry value must start with the full path of the executable.\n            const auto& resumeId = context.GetResumeId();\n            std::string commandLine = executablePath.u8string() + \" resume -g \" + resumeId;\n            Reboot::WriteToRunOnceRegistry(resumeId, commandLine);\n        }\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/ResumeFlow.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"ExecutionContext.h\"\n\nnamespace AppInstaller::CLI::Workflow\n{\n    // Applies a checkpoint to the context workflow.\n    // Required Args: None\n    // Inputs: Context data, command arguments, client version\n    // Outputs: None\n    struct Checkpoint : public WorkflowTask\n    {\n        Checkpoint(std::string_view checkpointName, std::vector<Execution::Data> contextData) :\n            WorkflowTask(\"Checkpoint\"),\n            m_checkpointName(checkpointName),\n            m_contextData(std::move(contextData)) {}\n\n        void operator()(Execution::Context& context) const override;\n\n    private:\n        std::string_view m_checkpointName;\n        std::vector<Execution::Data> m_contextData;\n    };\n\n    // Registers the resume command to execute upon reboot if applicable. This task always executes even if context terminates.\n    // Required Args: None\n    // Inputs: None\n    // Outputs: None\n    struct RegisterStartupAfterReboot : public WorkflowTask\n    {\n        RegisterStartupAfterReboot() : WorkflowTask(\"RegisterStartupAfterReboot\", /* executeAlways*/ true) {}\n\n        void operator()(Execution::Context & context) const override;\n    };\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/SettingsFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Resources.h\"\r\n#include \"SettingsFlow.h\"\r\n#include <AppInstallerStrings.h>\r\n#include <winget/UserSettings.h>\r\n#include <winget/AdminSettings.h>\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    using namespace AppInstaller::Settings;\r\n    using namespace AppInstaller::Utility;\r\n\r\n    namespace\r\n    {\r\n        struct ExportSettingsJson\r\n        {\r\n            ExportSettingsJson()\r\n            {\r\n                root[\"$schema\"] = \"https://aka.ms/winget-settings-export.schema.json\";\r\n                root[\"adminSettings\"] = Json::ValueType::objectValue;\r\n                root[\"userSettingsFile\"] = UserSettings::SettingsFilePath().u8string();\r\n            }\r\n\r\n            void AddAdminSetting(BoolAdminSetting setting)\r\n            {\r\n                auto str = std::string{ Settings::AdminSettingToString(setting) };\r\n                root[\"adminSettings\"][str] = Settings::IsAdminSettingEnabled(setting);\r\n            }\r\n\r\n            void AddAdminSetting(StringAdminSetting setting)\r\n            {\r\n                auto name = std::string{ Settings::AdminSettingToString(setting) };\r\n                auto value = Settings::GetAdminSetting(setting);\r\n                if (value)\r\n                {\r\n                    root[\"adminSettings\"][name] = value.value();\r\n                }\r\n            }\r\n\r\n            std::string ToJsonString() const\r\n            {\r\n                Json::StreamWriterBuilder writerBuilder;\r\n                writerBuilder.settings_[\"indentation\"] = \"\";\r\n                return Json::writeString(writerBuilder, root);\r\n            }\r\n\r\n        private:\r\n            Json::Value root{ Json::ValueType::objectValue };\r\n        };\r\n    }\r\n\r\n    void EnableAdminSetting(Execution::Context& context)\r\n    {\r\n        auto adminSettingString = context.Args.GetArg(Execution::Args::Type::AdminSettingEnable);\r\n        BoolAdminSetting adminSetting = Settings::StringToBoolAdminSetting(adminSettingString);\r\n        if (Settings::EnableAdminSetting(adminSetting))\r\n        {\r\n            context.Reporter.Info() << Resource::String::AdminSettingEnabled(AdminSettingToString(adminSetting)) << std::endl;\r\n        }\r\n        else\r\n        {\r\n            context.Reporter.Error() << Resource::String::EnableAdminSettingFailed(AdminSettingToString(adminSetting)) << std::endl;\r\n        }\r\n    }\r\n\r\n    void DisableAdminSetting(Execution::Context& context)\r\n    {\r\n        auto adminSettingString = context.Args.GetArg(Execution::Args::Type::AdminSettingDisable);\r\n        BoolAdminSetting adminSetting = Settings::StringToBoolAdminSetting(adminSettingString);\r\n        if (Settings::DisableAdminSetting(adminSetting))\r\n        {\r\n            context.Reporter.Info() << Resource::String::AdminSettingDisabled(AdminSettingToString(adminSetting)) << std::endl;\r\n        }\r\n        else\r\n        {\r\n            context.Reporter.Error() << Resource::String::DisableAdminSettingFailed(AdminSettingToString(adminSetting)) << std::endl;\r\n        }\r\n    }\r\n\r\n    void SetAdminSetting(Execution::Context& context)\r\n    {\r\n        auto adminSettingName = context.Args.GetArg(Execution::Args::Type::SettingName);\r\n        auto adminSettingValue = context.Args.GetArg(Execution::Args::Type::SettingValue);\r\n        StringAdminSetting adminSetting = Settings::StringToStringAdminSetting(adminSettingName);\r\n        if (Settings::SetAdminSetting(adminSetting, adminSettingValue))\r\n        {\r\n            context.Reporter.Info() << Resource::String::SetAdminSettingSucceeded(LocIndString{ adminSettingName }, LocIndString{ adminSettingValue }) << std::endl;\r\n        }\r\n        else\r\n        {\r\n            context.Reporter.Error() << Resource::String::SetAdminSettingFailed(LocIndString{ adminSettingName }) << std::endl;\r\n        }\r\n    }\r\n\r\n    void ResetAdminSetting(Execution::Context& context)\r\n    {\r\n        auto adminSettingName = context.Args.GetArg(Execution::Args::Type::SettingName);\r\n\r\n        // Try as both bool and string setting as we don't know the type\r\n        auto boolAdminSetting = Settings::StringToBoolAdminSetting(adminSettingName);\r\n        auto stringAdminSetting = Settings::StringToStringAdminSetting(adminSettingName);\r\n\r\n        if ((boolAdminSetting != Settings::BoolAdminSetting::Unknown && Settings::DisableAdminSetting(boolAdminSetting))\r\n            || (stringAdminSetting != Settings::StringAdminSetting::Unknown && Settings::ResetAdminSetting(stringAdminSetting)))\r\n        {\r\n            context.Reporter.Info() << Resource::String::ResetAdminSettingSucceeded(LocIndString{ adminSettingName }) << std::endl;\r\n        }\r\n        else\r\n        {\r\n            context.Reporter.Error() << Resource::String::ResetAdminSettingFailed(LocIndString{ adminSettingName }) << std::endl;\r\n        }\r\n    }\r\n\r\n    void ResetAllAdminSettings(Execution::Context& context)\r\n    {\r\n        Settings::ResetAllAdminSettings();\r\n        context.Reporter.Info() << Resource::String::ResetAllAdminSettingsSucceeded << std::endl;\r\n    }\r\n\r\n    void OpenUserSetting(Execution::Context& context)\r\n    {\r\n        // Show warnings only when the setting command is executed.\r\n        if (!User().GetWarnings().empty())\r\n        {\r\n            context.Reporter.Warn() << Resource::String::SettingLoadFailure << std::endl;\r\n            for (const auto& warning : User().GetWarnings())\r\n            {\r\n                auto warn = context.Reporter.Warn();\r\n                warn << warning.Message;\r\n                if (!warning.Path.empty())\r\n                {\r\n                    if (warning.IsFieldWarning)\r\n                    {\r\n                        warn << ' ' << Resource::String::SettingsWarningField(warning.Path);\r\n                    }\r\n                    else\r\n                    {\r\n                        warn << ' ' << warning.Path;\r\n                    }\r\n                }\r\n\r\n                if (!warning.Data.empty())\r\n                {\r\n                    if (warning.IsFieldWarning)\r\n                    {\r\n                        warn << ' ' << Resource::String::SettingsWarningValue(warning.Data);\r\n                    }\r\n                    else\r\n                    {\r\n                        warn <<\r\n                            std::endl <<\r\n                            warning.Data;\r\n                    }\r\n                }\r\n\r\n                warn << std::endl;\r\n            }\r\n        }\r\n\r\n        User().PrepareToShellExecuteFile();\r\n\r\n        auto filePathUTF16 = UserSettings::SettingsFilePath().wstring();\r\n\r\n        // Some versions of windows will fail if no file extension association exists, other will pop up the dialog\r\n        // to make the user pick their default.\r\n        // Kudos to the terminal team for this workaround.\r\n        HINSTANCE res = ShellExecuteW(nullptr, nullptr, filePathUTF16.c_str(), nullptr, nullptr, SW_SHOW);\r\n        if (static_cast<int>(reinterpret_cast<uintptr_t>(res)) <= 32)\r\n        {\r\n            // User doesn't have file type association. Default to notepad\r\n            AICLI_LOG(CLI, Info, << \"Json file type association not found, using notepad.exe\");\r\n            ShellExecuteW(nullptr, nullptr, L\"notepad\", filePathUTF16.c_str(), nullptr, SW_SHOW);\r\n        }\r\n    }\r\n\r\n    void ExportSettings(Execution::Context& context)\r\n    {\r\n        ExportSettingsJson exportSettingsJson;\r\n\r\n        for (const auto& setting : GetAllBoolAdminSettings())\r\n        {\r\n            exportSettingsJson.AddAdminSetting(setting);\r\n        }\r\n\r\n        for (const auto& setting : GetAllStringAdminSettings())\r\n        {\r\n            exportSettingsJson.AddAdminSetting(setting);\r\n        }\r\n\r\n        context.Reporter.Info() << exportSettingsJson.ToJsonString() << std::endl;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/SettingsFlow.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ExecutionContext.h\"\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    // Enables an admin setting.\r\n    // Required Args: AdminSettingEnable\r\n    // Inputs: None\r\n    // Outputs: None\r\n    void EnableAdminSetting(Execution::Context& context);\r\n\r\n    // Disables an admin setting.\r\n    // Required Args: AdminSettingDisable\r\n    // Inputs: None\r\n    // Outputs: None\r\n    void DisableAdminSetting(Execution::Context& context);\r\n\r\n    // Sets the value of an admin setting.\r\n    // Required Args: SettingName, SettingValue\r\n    // Inputs: None\r\n    // Outputs: None\r\n    void SetAdminSetting(Execution::Context& context);\r\n\r\n    // Resets an admin setting to the default.\r\n    // Required Args: SettingName\r\n    // Inputs: None\r\n    // Outputs: None\r\n    void ResetAdminSetting(Execution::Context& context);\r\n\r\n    // Resets all admin settings to the default.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: None\r\n    void ResetAllAdminSettings(Execution::Context& context);\r\n\r\n    // Opens the user settings.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: None\r\n    void OpenUserSetting(Execution::Context& context);\r\n\r\n    // Lists the state of settings.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: None\r\n    void ExportSettings(Execution::Context& context);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/ShellExecuteInstallerHandler.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ShellExecuteInstallerHandler.h\"\r\n#include <AppInstallerFileLogger.h>\r\n#include <AppInstallerRuntime.h>\r\n#include <winget/Filesystem.h>\r\n\r\nusing namespace AppInstaller::CLI;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Repository;\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    namespace\r\n    {\r\n        // ShellExecutes the given path.\r\n        std::optional<DWORD> InvokeShellExecuteEx(const std::filesystem::path& filePath, const std::string& args, bool useRunAs, int show, IProgressCallback& progress)\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"Starting: '\" << filePath.u8string() << \"' with arguments '\" << args << '\\'');\r\n\r\n            SHELLEXECUTEINFOW execInfo = { 0 };\r\n            execInfo.cbSize = sizeof(execInfo);\r\n            execInfo.fMask = SEE_MASK_NOCLOSEPROCESS;\r\n            execInfo.lpFile = filePath.c_str();\r\n            std::wstring argsUtf16 = Utility::ConvertToUTF16(args);\r\n            execInfo.lpParameters = argsUtf16.c_str();\r\n            execInfo.nShow = show;\r\n\r\n            // This installer must be run elevated, but we are not currently.\r\n            // Have ShellExecute elevate the installer since it won't do so itself.\r\n            if (useRunAs)\r\n            {\r\n                execInfo.lpVerb = L\"runas\";\r\n            }\r\n\r\n            THROW_LAST_ERROR_IF(!ShellExecuteExW(&execInfo) || !execInfo.hProcess);\r\n\r\n            wil::unique_process_handle process{ execInfo.hProcess };\r\n\r\n            // Wait for installation to finish\r\n            while (!progress.IsCancelledBy(CancelReason::User))\r\n            {\r\n                DWORD waitResult = WaitForSingleObject(process.get(), 250);\r\n                if (waitResult == WAIT_OBJECT_0)\r\n                {\r\n                    break;\r\n                }\r\n                if (waitResult != WAIT_TIMEOUT)\r\n                {\r\n                    THROW_LAST_ERROR_MSG(\"Unexpected WaitForSingleObjectResult: %lu\", waitResult);\r\n                }\r\n            }\r\n\r\n            if (progress.IsCancelledBy(CancelReason::Any))\r\n            {\r\n                return {};\r\n            }\r\n            else\r\n            {\r\n                DWORD exitCode = 0;\r\n                GetExitCodeProcess(process.get(), &exitCode);\r\n                return exitCode;\r\n            }\r\n        }\r\n\r\n        std::optional<DWORD> InvokeShellExecute(const std::filesystem::path& filePath, const std::string& args, IProgressCallback& progress)\r\n        {\r\n            // Some installers force UI. Setting to SW_HIDE will hide installer UI and installation will never complete.\r\n            // Verified setting to SW_SHOW does not hurt silent mode since no UI will be shown.\r\n            return InvokeShellExecuteEx(filePath, args, false, SW_SHOW, progress);\r\n        }\r\n\r\n        // Gets the escaped installer args.\r\n        std::string GetInstallerArgsTemplate(Execution::Context& context)\r\n        {\r\n            bool isUpdate = WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::InstallerExecutionUseUpdate);\r\n            bool isRepair = WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::InstallerExecutionUseRepair);\r\n\r\n            const auto& installer = context.Get<Execution::Data::Installer>();\r\n            const auto& installerSwitches = installer->Switches;\r\n            std::string installerArgs = {};\r\n\r\n            // Construct install experience arg.\r\n            // SilentWithProgress is default, so look for it first.\r\n            auto experienceArgsItr = installerSwitches.find(InstallerSwitchType::SilentWithProgress);\r\n\r\n            if (context.Args.Contains(Execution::Args::Type::Interactive))\r\n            {\r\n                // If interactive requested, always use Interactive (or nothing). If the installer supports\r\n                // interactive it is usually the default, and thus it is cumbersome to put a blank entry in\r\n                // the manifest.\r\n                experienceArgsItr = installerSwitches.find(InstallerSwitchType::Interactive);\r\n            }\r\n            // If no SilentWithProgress exists, or Silent requested, try to find Silent.\r\n            else if (experienceArgsItr == installerSwitches.end() || context.Args.Contains(Execution::Args::Type::Silent))\r\n            {\r\n                auto silentItr = installerSwitches.find(InstallerSwitchType::Silent);\r\n                // If Silent requested, but doesn't exist, then continue using SilentWithProgress.\r\n                if (silentItr != installerSwitches.end())\r\n                {\r\n                    experienceArgsItr = silentItr;\r\n                }\r\n            }\r\n\r\n            if (experienceArgsItr != installerSwitches.end())\r\n            {\r\n                installerArgs += experienceArgsItr->second;\r\n            }\r\n\r\n            // Construct log path arg.\r\n            if (installerSwitches.find(InstallerSwitchType::Log) != installerSwitches.end())\r\n            {\r\n                installerArgs += ' ' + installerSwitches.at(InstallerSwitchType::Log);\r\n            }\r\n\r\n            // Construct repair arg. Custom switches and other args are not applicable for repair scenario so we can return here.\r\n            if (isRepair)\r\n            {\r\n                if (installerSwitches.find(InstallerSwitchType::Repair) != installerSwitches.end())\r\n                {\r\n                    installerArgs += ' ' + installerSwitches.at(InstallerSwitchType::Repair);\r\n                }\r\n\r\n                return installerArgs;\r\n            }\r\n\r\n            // Construct custom arg.\r\n            if (installerSwitches.find(InstallerSwitchType::Custom) != installerSwitches.end())\r\n            {\r\n                installerArgs += ' ' + installerSwitches.at(InstallerSwitchType::Custom);\r\n            }\r\n\r\n            // Construct custom arg passed in by cli arg\r\n            if (context.Args.Contains(Execution::Args::Type::CustomSwitches))\r\n            {\r\n                std::string_view customSwitches = context.Args.GetArg(Execution::Args::Type::CustomSwitches);\r\n                // Since these arguments are appended to the installer at runtime, it doesn't make sense to append them if empty or whitespace\r\n                if (!Utility::IsEmptyOrWhitespace(customSwitches))\r\n                {\r\n                    installerArgs += ' ' + std::string{ customSwitches };\r\n                }\r\n            }\r\n\r\n            // Construct update arg if applicable\r\n            if (isUpdate && installerSwitches.find(InstallerSwitchType::Update) != installerSwitches.end())\r\n            {\r\n                installerArgs += ' ' + installerSwitches.at(InstallerSwitchType::Update);\r\n            }\r\n\r\n            // Construct install location arg if necessary.\r\n            if (context.Args.Contains(Execution::Args::Type::InstallLocation) &&\r\n                installerSwitches.find(InstallerSwitchType::InstallLocation) != installerSwitches.end())\r\n            {\r\n                installerArgs += ' ' + installerSwitches.at(InstallerSwitchType::InstallLocation);\r\n            }\r\n\r\n            return installerArgs;\r\n        }\r\n\r\n        // Applies values to the template.\r\n        void PopulateInstallerArgsTemplate(Execution::Context& context, std::string& installerArgs)\r\n        {\r\n            // Populate <LogPath> with value from command line or temp path.\r\n            std::string logPath;\r\n            if (context.Args.Contains(Execution::Args::Type::Log))\r\n            {\r\n                logPath = context.Args.GetArg(Execution::Args::Type::Log);\r\n            }\r\n            else\r\n            {\r\n                const auto& manifest = context.Get<Execution::Data::Manifest>();\r\n\r\n                auto path = Runtime::GetPathTo(Runtime::PathName::DefaultLogLocation);\r\n                path /= Utility::ConvertToUTF16(manifest.Id + '.' + manifest.Version);\r\n                path += '-';\r\n                path += Utility::GetCurrentTimeForFilename(true);\r\n                path += Logging::FileLogger::DefaultExt();\r\n\r\n                logPath = path.u8string();\r\n            }\r\n\r\n            if (Utility::FindAndReplace(installerArgs, std::string(ARG_TOKEN_LOGPATH), logPath))\r\n            {\r\n                context.Add<Execution::Data::LogPath>(Utility::ConvertToUTF16(logPath));\r\n            }\r\n\r\n            // Populate <InstallPath> with value from command line.\r\n            if (context.Args.Contains(Execution::Args::Type::InstallLocation))\r\n            {\r\n                Utility::FindAndReplace(installerArgs, std::string(ARG_TOKEN_INSTALLPATH), context.Args.GetArg(Execution::Args::Type::InstallLocation));\r\n            }\r\n\r\n            // Todo: language token support will be implemented later\r\n        }\r\n\r\n        // Gets the arguments for uninstalling an MSI with MsiExec\r\n        std::string GetMsiExecUninstallArgs(Execution::Context& context, const Utility::LocIndString& productCode)\r\n        {\r\n            std::string args = \"/x\" + productCode.get();\r\n\r\n            // https://learn.microsoft.com/en-us/windows/win32/msi/standard-installer-command-line-options\r\n            if (context.Args.Contains(Execution::Args::Type::Silent))\r\n            {\r\n                args += \" /quiet /norestart\";\r\n            }\r\n            else if (!context.Args.Contains(Execution::Args::Type::Interactive))\r\n            {\r\n                args += \" /passive /norestart\";\r\n            }\r\n\r\n            return args;\r\n        }\r\n\r\n        // Gets the arguments for repairing an MSI with MsiExec\r\n        std::string GetMsiExecRepairArgs(Execution::Context& context, const Utility::LocIndString& productCode)\r\n        {\r\n            // https://learn.microsoft.com/en-us/windows/win32/msi/command-line-options\r\n            // Available Options for '/f [p|o|e|d|c|a|u|m|s|v] <Product.msi | ProductCode>'\r\n            // Default parameter for '/f' is 'omus'\r\n            // o - Reinstall all files regardless of version\r\n            // m - Rewrite all required registry entries (This is the default option)\r\n            // u - Rewrite all required user-specific registry entries (This is the default option)\r\n            // s - Overwrite all existing shortcuts (This is the default option)\r\n            std::string args = \"/f \" + productCode.get();\r\n\r\n            // https://learn.microsoft.com/en-us/windows/win32/msi/standard-installer-command-line-options\r\n            if (context.Args.Contains(Execution::Args::Type::Silent))\r\n            {\r\n                args += \" /quiet /norestart\";\r\n            }\r\n            else if (!context.Args.Contains(Execution::Args::Type::Interactive))\r\n            {\r\n                args += \" /passive /norestart\";\r\n            }\r\n\r\n            return args;\r\n        }\r\n    }\r\n\r\n    void ShellExecuteInstallImpl(Execution::Context& context)\r\n    {\r\n        bool isRepair = WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::InstallerExecutionUseRepair);\r\n\r\n        if (isRepair)\r\n        {\r\n            context.Reporter.Info() << Resource::String::RepairFlowStartingPackageRepair << std::endl;\r\n        }\r\n        else\r\n        {\r\n            context.Reporter.Info() << Resource::String::InstallFlowStartingPackageInstall << std::endl;\r\n        }\r\n\r\n        const auto& installer = context.Get<Execution::Data::Installer>();\r\n        const std::string& installerArgs = context.Get<Execution::Data::InstallerArgs>();\r\n\r\n        // Inform of elevation requirements\r\n        bool isElevated = Runtime::IsRunningAsAdmin();\r\n\r\n        // The installer will run elevated, either by direct request or through the installer itself doing so.\r\n        if ((installer->ElevationRequirement == ElevationRequirementEnum::ElevationRequired ||\r\n            installer->ElevationRequirement == ElevationRequirementEnum::ElevatesSelf)\r\n            && !isElevated)\r\n        {\r\n            context.Reporter.Warn() << Resource::String::InstallerElevationExpected << std::endl;\r\n        }\r\n\r\n        // Some installers force UI. Setting to SW_HIDE will hide installer UI and installation will never complete.\r\n        // Verified setting to SW_SHOW does not hurt silent mode since no UI will be shown.\r\n        auto installResult = context.Reporter.ExecuteWithProgress(\r\n            std::bind(InvokeShellExecuteEx,\r\n                context.Get<Execution::Data::InstallerPath>(),\r\n                installerArgs,\r\n                installer->ElevationRequirement == ElevationRequirementEnum::ElevationRequired && !isElevated,\r\n                SW_SHOW,\r\n                std::placeholders::_1));\r\n\r\n        if (!installResult)\r\n        {\r\n            if (isRepair)\r\n            {\r\n                context.Reporter.Warn() << Resource::String::RepairAbandoned << std::endl;\r\n            }\r\n            else\r\n            {\r\n                context.Reporter.Warn() << Resource::String::InstallAbandoned << std::endl;\r\n            }\r\n\r\n            AICLI_TERMINATE_CONTEXT(E_ABORT);\r\n        }\r\n        else\r\n        {\r\n            context.Add<Execution::Data::OperationReturnCode>(installResult.value());\r\n        }\r\n    }\r\n\r\n    void GetInstallerArgs(Execution::Context& context)\r\n    {\r\n        // If override switch is specified, use the override value as installer args.\r\n        if (context.Args.Contains(Execution::Args::Type::Override))\r\n        {\r\n            context.Add<Execution::Data::InstallerArgs>(std::string{ context.Args.GetArg(Execution::Args::Type::Override) });\r\n            return;\r\n        }\r\n\r\n        std::string installerArgs = GetInstallerArgsTemplate(context);\r\n\r\n        PopulateInstallerArgsTemplate(context, installerArgs);\r\n\r\n        AICLI_LOG(CLI, Info, << \"Installer args: \" << installerArgs);\r\n        context.Add<Execution::Data::InstallerArgs>(std::move(installerArgs));\r\n    }\r\n\r\n    void ShellExecuteUninstallImpl(Execution::Context& context)\r\n    {\r\n        context.Reporter.Info() << Resource::String::UninstallFlowStartingPackageUninstall << std::endl;\r\n        std::wstring commandUtf16 = Utility::ConvertToUTF16(context.Get<Execution::Data::UninstallString>());\r\n\r\n        // Parse the command string as application and command line for CreateProcess\r\n        wil::unique_cotaskmem_string app = nullptr;\r\n        wil::unique_cotaskmem_string args = nullptr;\r\n        THROW_IF_FAILED(SHEvaluateSystemCommandTemplate(commandUtf16.c_str(), &app, NULL, &args));\r\n\r\n        auto uninstallResult = context.Reporter.ExecuteWithProgress(\r\n            std::bind(InvokeShellExecute,\r\n                std::filesystem::path(app.get()),\r\n                Utility::ConvertToUTF8(args.get()),\r\n                std::placeholders::_1));\r\n\r\n        if (!uninstallResult)\r\n        {\r\n            context.Reporter.Warn() << Resource::String::UninstallAbandoned << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(E_ABORT);\r\n        }\r\n        else\r\n        {\r\n            context.Add<Execution::Data::OperationReturnCode>(uninstallResult.value());\r\n        }\r\n    }\r\n\r\n    void ShellExecuteRepairImpl(Execution::Context& context)\r\n    {\r\n        context.Reporter.Info() << Resource::String::RepairFlowStartingPackageRepair << std::endl;\r\n\r\n        std::wstring commandUtf16 = Utility::ConvertToUTF16(context.Get<Execution::Data::RepairString>());\r\n\r\n        // When running as admin, block attempt to repair user scope installed package. \r\n        // [NOTE:] This check is to address the security concern related to above scenario.\r\n        if (Runtime::IsRunningAsAdmin())\r\n        {\r\n            auto installedPackageVersion = context.Get<Execution::Data::InstalledPackageVersion>();\r\n            const std::string installedScopeString = installedPackageVersion->GetMetadata()[PackageVersionMetadata::InstalledScope];\r\n            auto scopeEnum = ConvertToScopeEnum(installedScopeString);\r\n\r\n            if (scopeEnum == ScopeEnum::User)\r\n            {\r\n                context.Reporter.Error() << Resource::String::NoAdminRepairForUserScopePackage << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED);\r\n            }\r\n        }\r\n\r\n        // Parse the command string as application and command line for CreateProcess\r\n        wil::unique_cotaskmem_string app = nullptr;\r\n        wil::unique_cotaskmem_string args = nullptr;\r\n        THROW_IF_FAILED(SHEvaluateSystemCommandTemplate(commandUtf16.c_str(), &app, NULL, &args));\r\n\r\n        auto repairResult = context.Reporter.ExecuteWithProgress(\r\n            std::bind(InvokeShellExecute,\r\n                std::filesystem::path(app.get()),\r\n                Utility::ConvertToUTF8(args.get()),\r\n                std::placeholders::_1));\r\n\r\n        if (!repairResult)\r\n        {\r\n            context.Reporter.Error() << Resource::String::RepairAbandoned << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(E_ABORT);\r\n        }\r\n        else\r\n        {\r\n            context.Add<Execution::Data::OperationReturnCode>(repairResult.value());\r\n        }\r\n    }\r\n\r\n    void ShellExecuteMsiExecUninstall(Execution::Context& context)\r\n    {\r\n        const auto& productCodes = context.Get<Execution::Data::ProductCodes>();\r\n        context.Reporter.Info() << Resource::String::UninstallFlowStartingPackageUninstall << std::endl;\r\n\r\n        const std::filesystem::path msiexecPath{ ExpandEnvironmentVariables(L\"%windir%\\\\system32\\\\msiexec.exe\") };\r\n\r\n        for (const auto& productCode : productCodes)\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"Removing: \" << productCode);\r\n            auto uninstallResult = context.Reporter.ExecuteWithProgress(\r\n                std::bind(InvokeShellExecute,\r\n                    msiexecPath,\r\n                    GetMsiExecUninstallArgs(context, productCode),\r\n                    std::placeholders::_1));\r\n\r\n            if (!uninstallResult)\r\n            {\r\n                context.Reporter.Error() << Resource::String::UninstallAbandoned << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(E_ABORT);\r\n            }\r\n            else\r\n            {\r\n                context.Add<Execution::Data::OperationReturnCode>(uninstallResult.value());\r\n            }\r\n        }\r\n    }\r\n\r\n    void ShellExecuteMsiExecRepair(Execution::Context& context)\r\n    {\r\n        const auto& productCodes = context.Get<Execution::Data::ProductCodes>();\r\n        context.Reporter.Info() << Resource::String::RepairFlowStartingPackageRepair << std::endl;\r\n\r\n        const std::filesystem::path msiexecPath{ ExpandEnvironmentVariables(L\"%windir%\\\\system32\\\\msiexec.exe\") };\r\n\r\n        for (const auto& productCode : productCodes)\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"Repairing: \" << productCode);\r\n            auto repairResult = context.Reporter.ExecuteWithProgress(\r\n                std::bind(InvokeShellExecute,\r\n                    msiexecPath,\r\n                    GetMsiExecRepairArgs(context, productCode),\r\n                    std::placeholders::_1));\r\n\r\n            if (!repairResult)\r\n            {\r\n                context.Reporter.Error() << Resource::String::RepairAbandoned << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(E_ABORT);\r\n            }\r\n            else\r\n            {\r\n                context.Add<Execution::Data::OperationReturnCode>(repairResult.value());\r\n            }\r\n        }\r\n    }\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n    std::optional<DWORD> s_EnableWindowsFeatureResult_Override{};\r\n\r\n    void TestHook_SetEnableWindowsFeatureResult_Override(std::optional<DWORD>&& result)\r\n    {\r\n        s_EnableWindowsFeatureResult_Override = std::move(result);\r\n    }\r\n\r\n    std::optional<DWORD> s_DoesWindowsFeatureExistResult_Override{};\r\n\r\n    void TestHook_SetDoesWindowsFeatureExistResult_Override(std::optional<DWORD>&& result)\r\n    {\r\n        s_DoesWindowsFeatureExistResult_Override = std::move(result);\r\n    }\r\n#endif\r\n\r\n    std::filesystem::path GetDismExecutablePath()\r\n    {\r\n        return AppInstaller::Filesystem::GetExpandedPath(\"%windir%\\\\system32\\\\dism.exe\");\r\n    }\r\n\r\n    std::optional<DWORD> DoesWindowsFeatureExist(Execution::Context& context, std::string_view featureName)\r\n    {\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        if (s_DoesWindowsFeatureExistResult_Override)\r\n        {\r\n            return s_DoesWindowsFeatureExistResult_Override;\r\n        }\r\n#endif\r\n\r\n        std::string args = \"/Online /Get-FeatureInfo /FeatureName:\" + std::string{ featureName };\r\n        auto dismExecPath = GetDismExecutablePath();\r\n\r\n        auto getFeatureInfoResult = context.Reporter.ExecuteWithProgress(\r\n            std::bind(InvokeShellExecuteEx,\r\n                dismExecPath,\r\n                args,\r\n                false,\r\n                SW_HIDE,\r\n                std::placeholders::_1));\r\n\r\n        return getFeatureInfoResult;\r\n    }\r\n\r\n    std::optional<DWORD> EnableWindowsFeature(Execution::Context& context, std::string_view featureName)\r\n    {\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        if (s_EnableWindowsFeatureResult_Override)\r\n        {\r\n            return s_EnableWindowsFeatureResult_Override;\r\n        }\r\n#endif\r\n\r\n        std::string args = \"/Online /Enable-Feature /NoRestart /FeatureName:\" + std::string{ featureName };\r\n        auto dismExecPath = GetDismExecutablePath();\r\n\r\n        AICLI_LOG(Core, Info, << \"Enabling Windows Feature [\" << featureName << \"]\");\r\n\r\n        auto enableFeatureResult = context.Reporter.ExecuteWithProgress(\r\n            std::bind(InvokeShellExecuteEx,\r\n                dismExecPath,\r\n                args,\r\n                false,\r\n                SW_HIDE,\r\n                std::placeholders::_1));\r\n\r\n        return enableFeatureResult;\r\n    }\r\n\r\n    void ShellExecuteEnableWindowsFeature::operator()(Execution::Context& context) const\r\n    {\r\n        Utility::LocIndView locIndFeatureName{ m_featureName };\r\n\r\n        std::optional<DWORD> doesFeatureExistResult = DoesWindowsFeatureExist(context, m_featureName);\r\n\r\n        if (!doesFeatureExistResult)\r\n        {\r\n            AICLI_TERMINATE_CONTEXT(E_ABORT);\r\n        }\r\n        else if (doesFeatureExistResult.value() != ERROR_SUCCESS)\r\n        {\r\n            context.Add<Execution::Data::OperationReturnCode>(doesFeatureExistResult.value());\r\n            return;\r\n        }\r\n\r\n        context.Reporter.Info() << Resource::String::EnablingWindowsFeature(locIndFeatureName) << std::endl;\r\n\r\n        std::optional<DWORD> enableFeatureResult = EnableWindowsFeature(context, m_featureName);\r\n\r\n        if (!enableFeatureResult)\r\n        {\r\n            AICLI_TERMINATE_CONTEXT(E_ABORT);\r\n        }\r\n        else\r\n        {\r\n            context.Add<Execution::Data::OperationReturnCode>(enableFeatureResult.value());\r\n        }\r\n    }\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n    std::optional<DWORD> s_ExtractArchiveWithTarResult_Override{};\r\n\r\n    void TestHook_SetExtractArchiveWithTarResult_Override(std::optional<DWORD>&& result)\r\n    {\r\n        s_ExtractArchiveWithTarResult_Override = std::move(result);\r\n    }\r\n#endif\r\n\r\n    void ShellExecuteExtractArchive::operator()(Execution::Context& context) const\r\n    {\r\n        auto tarExecPath = AppInstaller::Filesystem::GetExpandedPath(\"%windir%\\\\system32\\\\tar.exe\");\r\n\r\n        std::string args = \"-xf \\\"\" + m_archivePath.u8string() + \"\\\" -C \\\"\" + m_destPath.u8string() + \"\\\"\";\r\n\r\n        std::optional<DWORD> extractArchiveResult;\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        if (s_ExtractArchiveWithTarResult_Override)\r\n        {\r\n            extractArchiveResult =  *s_ExtractArchiveWithTarResult_Override;\r\n        }\r\n        else\r\n#endif\r\n        {\r\n            extractArchiveResult = context.Reporter.ExecuteWithProgress(\r\n                std::bind(InvokeShellExecuteEx,\r\n                    tarExecPath,\r\n                    args,\r\n                    false,\r\n                    SW_HIDE,\r\n                    std::placeholders::_1));\r\n        }\r\n\r\n        if (!extractArchiveResult)\r\n        {\r\n            AICLI_TERMINATE_CONTEXT(E_ABORT);\r\n        }\r\n\r\n        if (extractArchiveResult.value() == ERROR_SUCCESS)\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"Successfully extracted archive\");\r\n            context.Reporter.Info() << Resource::String::ExtractArchiveSucceeded << std::endl;\r\n        }\r\n        else\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"Failed to extract archive with exit code \" << extractArchiveResult.value());\r\n            context.Reporter.Error() << Resource::String::ExtractArchiveFailed << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_EXTRACT_ARCHIVE_FAILED);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/ShellExecuteInstallerHandler.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerProgress.h>\r\n#include \"ExecutionContext.h\"\r\n\r\n#include <filesystem>\r\n#include <optional>\r\n\r\n// ShellExecuteInstallerHandler handles installers run through ShellExecute.\r\n// Exe, Wix, Nullsoft, Msi and Inno should be handled by this installer handler.\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    // Install is done through invoking ShellExecute on downloaded installer.\r\n    // Required Args: None\r\n    // Inputs: Manifest?, InstallerPath, InstallerArgs\r\n    // Outputs: OperationReturnCode\r\n    void ShellExecuteInstallImpl(Execution::Context& context);\r\n\r\n    // Uninstall is done through invoking ShellExecute on uninstall string.\r\n    // Required Args: None\r\n    // Inputs: UninstallString\r\n    // Outputs: OperationReturnCode\r\n    void ShellExecuteUninstallImpl(Execution::Context& context);\r\n\r\n    // Removes the MSI\r\n    // Required Args: None\r\n    // Inputs: ProductCodes\r\n    // Output: None\r\n    void ShellExecuteMsiExecUninstall(Execution::Context& context);\r\n\r\n    // Gets the installer args from the context.\r\n    // Required Args: None\r\n    // Inputs: Manifest?, Installer, InstallerPath\r\n    // Outputs: InstallerArgs\r\n    void GetInstallerArgs(Execution::Context& context);\r\n\r\n    // Repair is done through invoking ShellExecute on downloaded installer.\r\n    // Required Args: None\r\n    // Inputs: Manifest?, InstallerPath, InstallerArgs\r\n    // Outputs: OperationReturnCode\r\n    void ShellExecuteRepairImpl(Execution::Context& context);\r\n\r\n    // Repair the MSI\r\n    // Required Args: None\r\n    // Inputs: ProductCodes\r\n    // Output: None\r\n    void ShellExecuteMsiExecRepair(Execution::Context& context);\r\n\r\n    // Enables the Windows Feature dependency by invoking ShellExecute on the DISM executable.\r\n    // Required Args: None\r\n    // Inputs: Windows Feature dependency\r\n    // Outputs: None\r\n    struct ShellExecuteEnableWindowsFeature : public WorkflowTask\r\n    {\r\n        ShellExecuteEnableWindowsFeature(std::string_view featureName) : WorkflowTask(\"ShellExecuteEnableWindowsFeature\"), m_featureName(featureName) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        std::string_view m_featureName;\r\n    };\r\n\r\n    // Extracts the installer archive using the tar executable.\r\n    // Required Args: None\r\n    // Inputs: InstallerPath\r\n    // Outputs: None\r\n    struct ShellExecuteExtractArchive : public WorkflowTask\r\n    {\r\n        ShellExecuteExtractArchive(const std::filesystem::path& archivePath, const std::filesystem::path& destPath) : WorkflowTask(\"ShellExecuteExtractArchive\"), m_archivePath(archivePath), m_destPath(destPath) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        std::filesystem::path m_archivePath;\r\n        std::filesystem::path m_destPath;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/ShowFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n\r\n#include \"pch.h\"\r\n#include \"ShowFlow.h\"\r\n#include <winget/ManifestComparator.h>\r\n#include \"TableOutput.h\"\r\n\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::CLI;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::Utility::literals;\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    namespace\r\n    {\r\n        void ShowSingleLineField(Execution::OutputStream& outputStream, StringResource::StringId label, const Manifest::Manifest::string_t& value, bool indent = false)\r\n        {\r\n            Workflow::ShowSingleLineField(outputStream, label, LocIndView{ value }, indent ? 1 : 0);\r\n        }\r\n\r\n        void ShowMultiLineField(Execution::OutputStream& outputStream, StringResource::StringId label, const Manifest::Manifest::string_t& value)\r\n        {\r\n            Workflow::ShowMultiLineField(outputStream, label, LocIndView{ value });\r\n        }\r\n\r\n        void ShowAgreements(Execution::OutputStream& outputStream, const std::vector<Manifest::Agreement>& agreements) {\r\n\r\n            if (agreements.empty()) {\r\n                return;\r\n            }\r\n\r\n            outputStream << Execution::ManifestInfoEmphasis << Resource::String::ShowLabelAgreements << std::endl;\r\n            for (const auto& agreement : agreements) {\r\n\r\n                if (!agreement.Label.empty())\r\n                {\r\n                    outputStream << \"  \"_liv << Execution::ManifestInfoEmphasis << agreement.Label << \": \"_liv;\r\n                }\r\n\r\n                if (!agreement.AgreementText.empty())\r\n                {\r\n                    outputStream << agreement.AgreementText << std::endl;\r\n                }\r\n\r\n                if (!agreement.AgreementUrl.empty())\r\n                {\r\n                    outputStream << agreement.AgreementUrl << std::endl;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    namespace details\r\n    {\r\n        LocIndView GetIndentFor(size_t indentLevel)\r\n        {\r\n            static constexpr std::array<LocIndView, 4> s_indents{ \"\"_liv, \"  \"_liv, \"    \"_liv, \"      \"_liv };\r\n            return s_indents.at(indentLevel);\r\n        }\r\n    }\r\n\r\n    void ShowAgreementsInfo(Execution::Context& context)\r\n    {\r\n        const auto& manifest = context.Get<Execution::Data::Manifest>();\r\n        auto info = context.Reporter.Info();\r\n\r\n        ShowSingleLineField(info, Resource::String::ShowLabelVersion, manifest.Version);\r\n        ShowSingleLineField(info, Resource::String::ShowLabelPublisher, manifest.CurrentLocalization.Get<Manifest::Localization::Publisher>());\r\n        ShowSingleLineField(info, Resource::String::ShowLabelPublisherUrl, manifest.CurrentLocalization.Get<Manifest::Localization::PublisherUrl>());\r\n        ShowSingleLineField(info, Resource::String::ShowLabelPublisherSupportUrl, manifest.CurrentLocalization.Get<Manifest::Localization::PublisherSupportUrl>());\r\n        ShowSingleLineField(info, Resource::String::ShowLabelAuthor, manifest.CurrentLocalization.Get<Manifest::Localization::Author>());\r\n        ShowSingleLineField(info, Resource::String::ShowLabelPackageUrl, manifest.CurrentLocalization.Get<Manifest::Localization::PackageUrl>());\r\n        ShowSingleLineField(info, Resource::String::ShowLabelLicense, manifest.CurrentLocalization.Get<Manifest::Localization::License>());\r\n        ShowSingleLineField(info, Resource::String::ShowLabelLicenseUrl, manifest.CurrentLocalization.Get<Manifest::Localization::LicenseUrl>());\r\n        ShowSingleLineField(info, Resource::String::ShowLabelPrivacyUrl, manifest.CurrentLocalization.Get<Manifest::Localization::PrivacyUrl>());\r\n        ShowSingleLineField(info, Resource::String::ShowLabelCopyright, manifest.CurrentLocalization.Get<Manifest::Localization::Copyright>());\r\n        ShowSingleLineField(info, Resource::String::ShowLabelCopyrightUrl, manifest.CurrentLocalization.Get<Manifest::Localization::CopyrightUrl>());\r\n        ShowSingleLineField(info, Resource::String::ShowLabelPurchaseUrl, manifest.CurrentLocalization.Get<Manifest::Localization::PurchaseUrl>());\r\n        ShowAgreements(info, manifest.CurrentLocalization.Get<Manifest::Localization::Agreements>());\r\n        \r\n    }\r\n\r\n    void ShowManifestInfo(Execution::Context& context)\r\n    {\r\n        context << ShowPackageInfo << ShowInstallerInfo;\r\n    }\r\n\r\n    void ShowPackageInfo(Execution::Context& context)\r\n    {\r\n        const auto& manifest = context.Get<Execution::Data::Manifest>();\r\n        auto info = context.Reporter.Info();\r\n        // Get description from manifest so we can see if it is empty later\r\n        auto description = manifest.CurrentLocalization.Get<Manifest::Localization::Description>();\r\n\r\n        // TODO: Come up with a prettier format\r\n        ShowSingleLineField(info, Resource::String::ShowLabelVersion, manifest.Version);\r\n        ShowSingleLineField(info, Resource::String::ShowLabelPublisher, manifest.CurrentLocalization.Get<Manifest::Localization::Publisher>());\r\n        ShowSingleLineField(info, Resource::String::ShowLabelPublisherUrl, manifest.CurrentLocalization.Get<Manifest::Localization::PublisherUrl>());\r\n        ShowSingleLineField(info, Resource::String::ShowLabelPublisherSupportUrl, manifest.CurrentLocalization.Get<Manifest::Localization::PublisherSupportUrl>());\r\n        ShowSingleLineField(info, Resource::String::ShowLabelAuthor, manifest.CurrentLocalization.Get<Manifest::Localization::Author>());\r\n        ShowSingleLineField(info, Resource::String::ShowLabelMoniker, manifest.Moniker);\r\n        ShowMultiLineField(info,  Resource::String::ShowLabelDescription, description.empty() ? manifest.CurrentLocalization.Get<Manifest::Localization::ShortDescription>() : description);\r\n        ShowSingleLineField(info, Resource::String::ShowLabelPackageUrl, manifest.CurrentLocalization.Get<Manifest::Localization::PackageUrl>());\r\n        ShowSingleLineField(info, Resource::String::ShowLabelLicense, manifest.CurrentLocalization.Get<Manifest::Localization::License>());\r\n        ShowSingleLineField(info, Resource::String::ShowLabelLicenseUrl, manifest.CurrentLocalization.Get<Manifest::Localization::LicenseUrl>());\r\n        ShowSingleLineField(info, Resource::String::ShowLabelPrivacyUrl, manifest.CurrentLocalization.Get<Manifest::Localization::PrivacyUrl>());\r\n        ShowSingleLineField(info, Resource::String::ShowLabelCopyright, manifest.CurrentLocalization.Get<Manifest::Localization::Copyright>());\r\n        ShowSingleLineField(info, Resource::String::ShowLabelCopyrightUrl, manifest.CurrentLocalization.Get<Manifest::Localization::CopyrightUrl>());\r\n        ShowMultiLineField(info,  Resource::String::ShowLabelReleaseNotes, manifest.CurrentLocalization.Get<Manifest::Localization::ReleaseNotes>());\r\n        ShowSingleLineField(info, Resource::String::ShowLabelReleaseNotesUrl, manifest.CurrentLocalization.Get<Manifest::Localization::ReleaseNotesUrl>());\r\n        ShowSingleLineField(info, Resource::String::ShowLabelPurchaseUrl, manifest.CurrentLocalization.Get<Manifest::Localization::PurchaseUrl>());\r\n        ShowMultiLineField(info, Resource::String::ShowLabelInstallationNotes, manifest.CurrentLocalization.Get<Manifest::Localization::InstallationNotes>());\r\n        const auto& documentations = manifest.CurrentLocalization.Get<Manifest::Localization::Documentations>();\r\n        if (!documentations.empty())\r\n        {\r\n            context.Reporter.Info() << Execution::ManifestInfoEmphasis << Resource::String::ShowLabelDocumentation << std::endl;\r\n            for (const auto& documentation : documentations)\r\n            {\r\n                if (!documentation.DocumentUrl.empty())\r\n                {\r\n                    info << \"  \"_liv;\r\n                    if (!documentation.DocumentLabel.empty())\r\n                    {\r\n                        info << Execution::ManifestInfoEmphasis << documentation.DocumentLabel << \": \"_liv;\r\n                    }\r\n\r\n                    info << documentation.DocumentUrl << std::endl;\r\n                }\r\n            }\r\n        }\r\n        ShowMultiValueField(info, Resource::String::ShowLabelTags, manifest.CurrentLocalization.Get<Manifest::Localization::Tags>());\r\n        ShowAgreements(info, manifest.CurrentLocalization.Get<Manifest::Localization::Agreements>());\r\n    }\r\n\r\n    void ShowInstallerInfo(Execution::Context& context)\r\n    {\r\n        const auto& installer = context.Get<Execution::Data::Installer>();\r\n        auto info = context.Reporter.Info();\r\n\r\n        info << Execution::ManifestInfoEmphasis << Resource::String::ShowLabelInstaller << std::endl;\r\n        if (installer)\r\n        {\r\n            Manifest::InstallerTypeEnum effectiveInstallerType = installer->EffectiveInstallerType();\r\n            Manifest::InstallerTypeEnum baseInstallerType = installer->BaseInstallerType;\r\n            std::string shownInstallerType;\r\n            shownInstallerType = Manifest::InstallerTypeToString(effectiveInstallerType);\r\n            if (effectiveInstallerType != baseInstallerType)\r\n            {\r\n                shownInstallerType += \" (\"_liv;\r\n                shownInstallerType += Manifest::InstallerTypeToString(baseInstallerType);\r\n                shownInstallerType += ')';\r\n            }\r\n            ShowSingleLineField(info, Resource::String::ShowLabelInstallerType, shownInstallerType, true);\r\n            ShowSingleLineField(info, Resource::String::ShowLabelInstallerLocale, installer->Locale, true);\r\n            ShowSingleLineField(info, Resource::String::ShowLabelInstallerUrl, installer->Url, true);\r\n            ShowSingleLineField(info, Resource::String::ShowLabelInstallerSha256, (installer->Sha256.empty()) ? \"\" : Utility::SHA256::ConvertToString(installer->Sha256), true);\r\n            ShowSingleLineField(info, Resource::String::ShowLabelInstallerProductId, installer->ProductId, true);\r\n            ShowSingleLineField(info, Resource::String::ShowLabelInstallerReleaseDate, installer->ReleaseDate, true);\r\n            ShowSingleLineField(info, Resource::String::ShowLabelInstallerOfflineDistributionSupported, Utility::ConvertBoolToString(!installer->DownloadCommandProhibited), true);\r\n\r\n            const auto& dependencies = installer->Dependencies;\r\n\r\n            if (dependencies.HasAny())\r\n            {\r\n                info << Execution::ManifestInfoEmphasis << \"  \"_liv << Resource::String::ShowLabelDependencies << ' ' << std::endl;\r\n\r\n                if (dependencies.HasAnyOf(Manifest::DependencyType::WindowsFeature))\r\n                {\r\n                    info << \"    - \"_liv << Resource::String::ShowLabelWindowsFeaturesDependencies << ' ' << std::endl;\r\n                    dependencies.ApplyToType(Manifest::DependencyType::WindowsFeature, [&info](Manifest::Dependency dependency) {info << \"        \"_liv << dependency.Id() << std::endl; });\r\n                }\r\n\r\n                if (dependencies.HasAnyOf(Manifest::DependencyType::WindowsLibrary))\r\n                {\r\n                    info << \"    - \"_liv << Resource::String::ShowLabelWindowsLibrariesDependencies << ' ' << std::endl;\r\n                    dependencies.ApplyToType(Manifest::DependencyType::WindowsLibrary, [&info](Manifest::Dependency dependency) {info << \"        \"_liv << dependency.Id() << std::endl; });\r\n                }\r\n\r\n                if (dependencies.HasAnyOf(Manifest::DependencyType::Package))\r\n                {\r\n                    info << \"    - \"_liv << Resource::String::ShowLabelPackageDependencies << ' ' << std::endl;\r\n                    dependencies.ApplyToType(Manifest::DependencyType::Package, [&info](Manifest::Dependency dependency)\r\n                        {\r\n                            info << \"        \"_liv << dependency.Id();\r\n                            if (dependency.MinVersion)\r\n                            {\r\n                                info << \" [>= \" << dependency.MinVersion.value().ToString() << \"]\";\r\n                            }\r\n                            info << std::endl;\r\n                        });\r\n                }\r\n\r\n                if (dependencies.HasAnyOf(Manifest::DependencyType::External))\r\n                {\r\n                    info << \"    - \"_liv << Resource::String::ShowLabelExternalDependencies << ' ' << std::endl;\r\n                    dependencies.ApplyToType(Manifest::DependencyType::External, [&info](Manifest::Dependency dependency) {info << \"        \"_liv << dependency.Id() << std::endl; });\r\n                }\r\n            }\r\n        }\r\n        else\r\n        {\r\n            context.Reporter.Warn() << \"  \"_liv << Resource::String::NoApplicableInstallers << std::endl;\r\n        }\r\n    }\r\n\r\n    void ShowManifestVersion(Execution::Context& context)\r\n    {\r\n        const auto& manifest = context.Get<Execution::Data::Manifest>();\r\n        Execution::TableOutput<2> table(context.Reporter, { Resource::String::ShowVersion, Resource::String::ShowChannel });\r\n        table.OutputLine({ manifest.Version, manifest.Channel });\r\n        table.Complete();\r\n    }\r\n\r\n    void GetManifest::operator()(Execution::Context& context) const\r\n    {\r\n        if (context.Args.Contains(Execution::Args::Type::Manifest))\r\n        {\r\n            context <<\r\n                GetManifestFromArg;\r\n        }\r\n        else\r\n        {\r\n            context <<\r\n                OpenSource() <<\r\n                SearchSourceForSingle <<\r\n                HandleSearchResultFailures <<\r\n                EnsureOneMatchFromSearchResult(OperationType::Show) <<\r\n                GetManifestFromPackage(m_considerPins);\r\n        }\r\n    }\r\n\r\n    void ShowSingleLineField(Execution::OutputStream& outputStream, StringResource::StringId label, LocIndView value, size_t indentLevel)\r\n    {\r\n        if (value.empty())\r\n        {\r\n            return;\r\n        }\r\n\r\n        outputStream << details::GetIndentFor(indentLevel) << Execution::ManifestInfoEmphasis << label << ' ' << value << '\\n';\r\n    }\r\n\r\n    void ShowMultiLineField(Execution::OutputStream& outputStream, StringResource::StringId label, LocIndView value, size_t indentLevel)\r\n    {\r\n        if (value.empty())\r\n        {\r\n            return;\r\n        }\r\n\r\n        // Treat the lines as separate values for the field\r\n        ShowMultiValueField(outputStream, label, Split(value, '\\n'), indentLevel);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/ShowFlow.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ExecutionContext.h\"\r\n#include <AppInstallerLanguageUtilities.h>\r\n#include <winget/LocIndependent.h>\r\n#include <winget/Resources.h>\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    // Shows information on an application; this is only the information for package agreements\r\n    // Required Args: None\r\n    // Inputs: Manifest\r\n    // Outputs: None\r\n    void ShowAgreementsInfo(Execution::Context& context);\r\n\r\n    // Shows information on an application.\r\n    // Required Args: None\r\n    // Inputs: Manifest, Installer\r\n    // Outputs: None\r\n    void ShowManifestInfo(Execution::Context& context);\r\n\r\n    // Shows information on a package; this is only the information common to all installers.\r\n    // Required Args: None\r\n    // Inputs: Manifest\r\n    // Outputs: None\r\n    void ShowPackageInfo(Execution::Context& context);\r\n\r\n    // Shows information on an installer\r\n    // Required Args: None\r\n    // Inputs: Installer\r\n    // Outputs: None\r\n    void ShowInstallerInfo(Execution::Context& context);\r\n\r\n    // Shows the version for the specific manifest.\r\n    // Required Args: None\r\n    // Inputs: Manifest\r\n    // Outputs: None\r\n    void ShowManifestVersion(Execution::Context& context);\r\n\r\n    // Composite flow that produces a manifest; either from one given on the command line or by searching.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: Manifest\r\n    struct GetManifest : public WorkflowTask\r\n    {\r\n        GetManifest(bool considerPins) : WorkflowTask(\"GetManifest\"), m_considerPins(considerPins) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        bool m_considerPins;\r\n    };\r\n\r\n    // Reusable helpers for `show` style line output\r\n    namespace details\r\n    {\r\n        Utility::LocIndView GetIndentFor(size_t i);\r\n    }\r\n\r\n    void ShowSingleLineField(Execution::OutputStream& outputStream, StringResource::StringId label, Utility::LocIndView value, size_t indentLevel = 0);\r\n\r\n    void ShowMultiLineField(Execution::OutputStream& outputStream, StringResource::StringId label, Utility::LocIndView value, size_t indentLevel = 0);\r\n\r\n    template <typename Container>\r\n    void ShowMultiValueField(Execution::OutputStream& outputStream, StringResource::StringId label, const Container& values, size_t indentLevel = 0)\r\n    {\r\n        if (values.empty())\r\n        {\r\n            return;\r\n        }\r\n\r\n        bool isMultiItem = values.size() > 1;\r\n        outputStream << details::GetIndentFor(indentLevel) << Execution::ManifestInfoEmphasis << label;\r\n        outputStream << (isMultiItem ? '\\n' : ' ');\r\n\r\n        for (const auto& value : values)\r\n        {\r\n            outputStream << details::GetIndentFor(isMultiItem ? indentLevel + 1 : 0) << value << '\\n';\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/SourceFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Resources.h\"\r\n#include \"SourceFlow.h\"\r\n#include \"PromptFlow.h\"\r\n#include \"TableOutput.h\"\r\n#include \"WorkflowBase.h\"\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    using namespace AppInstaller::CLI::Execution;\r\n    using namespace AppInstaller::Settings;\r\n    using namespace AppInstaller::Utility::literals;\r\n\r\n    void GetSourceList(Execution::Context& context)\r\n    {\r\n        context.Add<Execution::Data::SourceList>(Repository::Source::GetCurrentSources());\r\n    }\r\n\r\n    void GetSourceListWithFilter(Execution::Context& context)\r\n    {\r\n        auto currentSources = Repository::Source::GetCurrentSources();\r\n        if (context.Args.Contains(Args::Type::SourceName))\r\n        {\r\n            auto name = Utility::LocIndString{ context.Args.GetArg(Args::Type::SourceName) };\r\n\r\n            for (auto const& source : currentSources)\r\n            {\r\n                if (Utility::ICUCaseInsensitiveEquals(source.Name, name))\r\n                {\r\n                    std::vector<Repository::SourceDetails> sources;\r\n                    sources.emplace_back(source);\r\n                    context.Add<Execution::Data::SourceList>(std::move(sources));\r\n                    return;\r\n                }\r\n            }\r\n\r\n            context.Reporter.Error() << Resource::String::SourceListNoneFound(name) << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_SOURCE_NAME_DOES_NOT_EXIST);\r\n        }\r\n        else\r\n        {\r\n            context.Add<Execution::Data::SourceList>(std::move(currentSources));\r\n        }\r\n    }\r\n\r\n    void CheckSourceListAgainstAdd(Execution::Context& context)\r\n    {\r\n        auto sourceList = context.Get<Execution::Data::SourceList>();\r\n        std::string_view name = context.Args.GetArg(Args::Type::SourceName);\r\n        std::string_view arg = context.Args.GetArg(Args::Type::SourceArg);\r\n        std::string_view type = context.Args.GetArg(Args::Type::SourceType);\r\n\r\n        // In the absence of a specified type, the default is Microsoft.PreIndexed.Package for comparison.\r\n        // The default type assignment to the source takes place during the add operation (Source::Add in Repository.cpp).\r\n        // This is necessary for the comparison to function correctly; otherwise, it would allow the addition of multiple\r\n        // sources with different names but the same argument for all default type cases.\r\n        // For example, the following commands would be allowed, but they acts as different alias to same source:\r\n        //      winget source add \"mysource1\" \"https:\\\\mysource\" --trust - level trusted\r\n        //      winget source add \"mysource2\" \"https:\\\\mysource\" --trust - level trusted\r\n        if (type.empty())\r\n        {\r\n            type = Repository::Source::GetDefaultSourceType();\r\n        }\r\n\r\n        for (const auto& details : sourceList)\r\n        {\r\n            if (Utility::ICUCaseInsensitiveEquals(details.Name, name))\r\n            {\r\n                if (details.Arg == arg)\r\n                {\r\n                    // Name and arg match, indicate this to the user and bail.\r\n                    context.Reporter.Info() << Resource::String::SourceAddAlreadyExistsMatch << std::endl <<\r\n                        \"  \"_liv << details.Name << \" -> \"_liv << details.Arg << std::endl;\r\n                    AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_SOURCE_NAME_ALREADY_EXISTS);\r\n                }\r\n                else\r\n                {\r\n                    context.Reporter.Error() << Resource::String::SourceAddAlreadyExistsDifferentArg << std::endl <<\r\n                        \"  \"_liv << details.Name << \" -> \"_liv << details.Arg << std::endl;\r\n                    AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_SOURCE_NAME_ALREADY_EXISTS);\r\n                }\r\n            }\r\n\r\n            if (!details.Arg.empty() && details.Arg == arg && details.Type == type)\r\n            {\r\n                context.Reporter.Error() << Resource::String::SourceAddAlreadyExistsDifferentName << std::endl <<\r\n                    \"  \"_liv << details.Name << \" -> \"_liv << details.Arg << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_SOURCE_ARG_ALREADY_EXISTS);\r\n            }\r\n        }\r\n    }\r\n\r\n    void AddSource(Execution::Context& context)\r\n    {\r\n        auto& sourceToAdd = context.Get<Execution::Data::Source>();\r\n        auto details = sourceToAdd.GetDetails();\r\n\r\n        context.Reporter.Info() <<\r\n            Resource::String::SourceAddBegin << std::endl <<\r\n            \"  \"_liv << details.Name << \" -> \"_liv << details.Arg << std::endl;\r\n\r\n        auto addFunction = [&](IProgressCallback& progress)->bool { return sourceToAdd.Add(progress); };\r\n        if (!context.Reporter.ExecuteWithProgress(addFunction))\r\n        {\r\n            context.Reporter.Info() << Resource::String::Cancelled << std::endl;\r\n        }\r\n        else\r\n        {\r\n            context.Reporter.Info() << Resource::String::Done << std::endl;\r\n        }\r\n    }\r\n\r\n    void CreateSourceForSourceAdd(Execution::Context& context)\r\n    {\r\n        try\r\n        {\r\n            std::string_view name = context.Args.GetArg(Args::Type::SourceName);\r\n            std::string_view arg = context.Args.GetArg(Args::Type::SourceArg);\r\n            std::string_view type = context.Args.GetArg(Args::Type::SourceType);\r\n\r\n            Repository::SourceTrustLevel trustLevel = Repository::SourceTrustLevel::None;\r\n            if (context.Args.Contains(Execution::Args::Type::SourceTrustLevel))\r\n            {\r\n                std::vector<std::string> trustLevelArgs = Utility::Split(std::string{ context.Args.GetArg(Execution::Args::Type::SourceTrustLevel) }, '|', true);\r\n                trustLevel = Repository::ConvertToSourceTrustLevelFlag(trustLevelArgs);\r\n            }\r\n\r\n            Repository::SourceEdit additionalProperties;\r\n\r\n            if (context.Args.Contains(Args::Type::SourceExplicit))\r\n            {\r\n                additionalProperties.Explicit = true;\r\n            }\r\n\r\n            if (context.Args.Contains(Args::Type::SourcePriority))\r\n            {\r\n                additionalProperties.Priority = Utility::TryConvertStringToInt32(context.Args.GetArg(Args::Type::SourcePriority));\r\n            }\r\n\r\n            Repository::Source sourceToAdd{ name, arg, type, trustLevel, additionalProperties};\r\n\r\n            if (context.Args.Contains(Execution::Args::Type::CustomHeader))\r\n            {\r\n                std::string customHeader{ context.Args.GetArg(Execution::Args::Type::CustomHeader) };\r\n                if (!sourceToAdd.SetCustomHeader(customHeader))\r\n                {\r\n                    context.Reporter.Warn() << Resource::String::HeaderArgumentNotApplicableForNonRestSourceWarning << std::endl;\r\n                }\r\n            }\r\n\r\n            if (sourceToAdd.GetInformation().Authentication.Type == Authentication::AuthenticationType::Unknown)\r\n            {\r\n                context.Reporter.Error() << Resource::String::SourceAddFailedAuthenticationNotSupported << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED);\r\n            }\r\n\r\n            context << Workflow::HandleSourceAgreements(sourceToAdd);\r\n            if (context.IsTerminated())\r\n            {\r\n                return;\r\n            }\r\n\r\n            context.Add<Execution::Data::Source>(std::move(sourceToAdd));\r\n        }\r\n        catch (...)\r\n        {\r\n            context.Reporter.Error() << Resource::String::SourceAddOpenSourceFailed << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_SOURCE_OPEN_FAILED);\r\n        }\r\n    }\r\n\r\n    void ListSources(Execution::Context& context)\r\n    {\r\n        const std::vector<Repository::SourceDetails>& sources = context.Get<Data::SourceList>();\r\n\r\n        if (context.Args.Contains(Args::Type::SourceName))\r\n        {\r\n            // If a source name was specified, list full details of the one and only source.\r\n            const Repository::SourceDetails& source = sources[0];\r\n\r\n            Execution::TableOutput<2> table(context.Reporter, { Resource::String::SourceListField, Resource::String::SourceListValue });\r\n\r\n            table.OutputLine({ Resource::LocString(Resource::String::SourceListName), source.Name });\r\n            table.OutputLine({ Resource::LocString(Resource::String::SourceListType), source.Type });\r\n            table.OutputLine({ Resource::LocString(Resource::String::SourceListArg), source.Arg });\r\n            table.OutputLine({ Resource::LocString(Resource::String::SourceListData), source.Data });\r\n            table.OutputLine({ Resource::LocString(Resource::String::SourceListIdentifier), source.Identifier });\r\n            table.OutputLine({ Resource::LocString(Resource::String::SourceListTrustLevel), Repository::GetSourceTrustLevelForDisplay(source.TrustLevel)});\r\n            table.OutputLine({ Resource::LocString(Resource::String::SourceListExplicit), std::string{ Utility::ConvertBoolToString(source.Explicit) } });\r\n            if (ExperimentalFeature::IsEnabled(ExperimentalFeature::Feature::SourcePriority))\r\n            {\r\n                table.OutputLine({ Resource::LocString(Resource::String::SourceListPriority), std::to_string(source.Priority) });\r\n            }\r\n\r\n            if (source.LastUpdateTime == Utility::ConvertUnixEpochToSystemClock(0))\r\n            {\r\n                table.OutputLine({\r\n                    Resource::LocString(Resource::String::SourceListUpdated),\r\n                    Resource::LocString(Resource::String::SourceListUpdatedNever)\r\n                    });\r\n            }\r\n            else\r\n            {\r\n                std::ostringstream strstr;\r\n                strstr << source.LastUpdateTime;\r\n                table.OutputLine({ Resource::LocString(Resource::String::SourceListUpdated), strstr.str() });\r\n            }\r\n\r\n            table.Complete();\r\n        }\r\n        else\r\n        {\r\n            if (sources.empty())\r\n            {\r\n                context.Reporter.Info() << Resource::String::SourceListNoSources << std::endl;\r\n            }\r\n            else\r\n            {\r\n                Execution::TableOutput<3> table(context.Reporter, { Resource::String::SourceListName, Resource::String::SourceListArg, Resource::String::SourceListExplicit });\r\n                for (const auto& source : sources)\r\n                {\r\n                    table.OutputLine({ source.Name, source.Arg, std::string{ Utility::ConvertBoolToString(source.Explicit) }});\r\n                }\r\n                table.Complete();\r\n            }\r\n        }\r\n    }\r\n\r\n    void UpdateSources(Execution::Context& context)\r\n    {\r\n        if (!context.Args.Contains(Args::Type::SourceName))\r\n        {\r\n            context.Reporter.Info() << Resource::String::SourceUpdateAll << std::endl;\r\n        }\r\n\r\n        const std::vector<Repository::SourceDetails>& sources = context.Get<Data::SourceList>();\r\n\r\n        for (const auto& sd : sources)\r\n        {\r\n            Repository::Source source{ sd.Name };\r\n            context.Reporter.Info() << Resource::String::SourceUpdateOne(Utility::LocIndView{ sd.Name }) << std::endl;\r\n            auto updateFunction = [&](IProgressCallback& progress)->std::vector<Repository::SourceDetails> { return source.Update(progress); };\r\n            auto sourceDetails = context.Reporter.ExecuteWithProgress(updateFunction);\r\n            if (!sourceDetails.empty())\r\n            {\r\n                if (std::chrono::system_clock::now() < sourceDetails[0].DoNotUpdateBefore)\r\n                {\r\n                    context.Reporter.Warn() << Resource::String::Unavailable << std::endl;\r\n                }\r\n                else\r\n                {\r\n                    context.Reporter.Info() << Resource::String::Cancelled << std::endl;\r\n                }\r\n            }\r\n            else\r\n            {\r\n                context.Reporter.Info() << Resource::String::Done << std::endl;\r\n            }\r\n        }\r\n    }\r\n\r\n    void RemoveSources(Execution::Context& context)\r\n    {\r\n        // TODO: We currently only allow removing a single source. If that changes,\r\n        //       we need to check all sources with the Group Policy before removing any of them.\r\n        if (!context.Args.Contains(Args::Type::SourceName))\r\n        {\r\n            context.Reporter.Info() << Resource::String::SourceRemoveAll << std::endl;\r\n        }\r\n\r\n        const std::vector<Repository::SourceDetails>& sources = context.Get<Data::SourceList>();\r\n        for (const auto& sd : sources)\r\n        {\r\n            Repository::Source source{ sd.Name };\r\n            context.Reporter.Info() << Resource::String::SourceRemoveOne(Utility::LocIndView{ sd.Name }) << std::endl;\r\n            auto removeFunction = [&](IProgressCallback& progress)->bool { return source.Remove(progress); };\r\n            if (context.Reporter.ExecuteWithProgress(removeFunction))\r\n            {\r\n                context.Reporter.Info() << Resource::String::Done << std::endl;\r\n            }\r\n            else\r\n            {\r\n                context.Reporter.Info() << Resource::String::Cancelled << std::endl;\r\n            }\r\n        }\r\n    }\r\n\r\n    void EditSources(Execution::Context& context)\r\n    {\r\n        // We are assuming there is only one match, as SourceName is a required parameter.\r\n        const std::vector<Repository::SourceDetails>& sources = context.Get<Data::SourceList>();\r\n\r\n        for (const auto& sd : sources)\r\n        {\r\n            // Get the current source with this name.\r\n            Repository::Source targetSource{ sd.Name };\r\n            auto oldExplicitValue = sd.Explicit;\r\n            auto oldPriorityValue = sd.Priority;\r\n\r\n            Repository::SourceEdit edits;\r\n\r\n            if (context.Args.Contains(Execution::Args::Type::SourceEditExplicit))\r\n            {\r\n                edits.Explicit = Utility::TryConvertStringToBool(context.Args.GetArg(Execution::Args::Type::SourceEditExplicit));\r\n            }\r\n\r\n            if (context.Args.Contains(Execution::Args::Type::SourcePriority))\r\n            {\r\n                edits.Priority = Utility::TryConvertStringToInt32(context.Args.GetArg(Execution::Args::Type::SourcePriority));\r\n            }\r\n\r\n            if (!targetSource.RequiresChanges(edits))\r\n            {\r\n                context.Reporter.Info() << Resource::String::SourceEditNoChanges(Utility::LocIndView{ sd.Name }) << std::endl;\r\n                continue;\r\n            }\r\n\r\n            context.Reporter.Info() << Resource::String::SourceEditOne(Utility::LocIndView{ sd.Name }) << std::endl;\r\n            targetSource.Edit(edits);\r\n\r\n            // Output changed source information table. The name of the source being edited is listed prior to the edits.\r\n            Execution::TableOutput<3> table(context.Reporter, { Resource::String::SourceListField, Resource::String::SourceEditOldValue, Resource::String::SourceEditNewValue });\r\n\r\n            if (edits.Explicit)\r\n            {\r\n                table.OutputLine({ Resource::LocString(Resource::String::SourceListExplicit), std::string{ Utility::ConvertBoolToString(oldExplicitValue) }, std::string{ Utility::ConvertBoolToString(edits.Explicit.value()) } });\r\n            }\r\n\r\n            if (edits.Priority)\r\n            {\r\n                table.OutputLine({ Resource::LocString(Resource::String::SourceListPriority), std::to_string(oldPriorityValue), std::to_string(edits.Priority.value()) });\r\n            }\r\n\r\n            table.Complete();\r\n        }\r\n    }\r\n\r\n    void QueryUserForSourceReset(Execution::Context& context)\r\n    {\r\n        if (!context.Args.Contains(Execution::Args::Type::ForceSourceReset))\r\n        {\r\n            context << GetSourceListWithFilter;\r\n            const std::vector<Repository::SourceDetails>& sources = context.Get<Data::SourceList>();\r\n\r\n            if (!sources.empty())\r\n            {\r\n                context.Reporter.Info() << Resource::String::SourceResetListAndOverridePreamble << std::endl;\r\n\r\n                context << ListSources;\r\n                AICLI_TERMINATE_CONTEXT(E_ABORT);\r\n            }\r\n        }\r\n    }\r\n\r\n    void ResetSourceList(Execution::Context& context)\r\n    {\r\n        const std::vector<Repository::SourceDetails>& sources = context.Get<Data::SourceList>();\r\n\r\n        for (const auto& source : sources)\r\n        {\r\n            context.Reporter.Info() << Resource::String::SourceResetOne(Utility::LocIndView{ source.Name });\r\n            Repository::Source::DropSource(source.Name);\r\n            context.Reporter.Info() << Resource::String::Done << std::endl;\r\n        }\r\n    }\r\n\r\n    void ResetAllSources(Execution::Context& context)\r\n    {\r\n        context.Reporter.Info() << Resource::String::SourceResetAll;\r\n        Repository::Source::DropSource({});\r\n        context.Reporter.Info() << Resource::String::Done << std::endl;\r\n    }\r\n\r\n    void ExportSourceList(Execution::Context& context)\r\n    {\r\n        const std::vector<Repository::SourceDetails>& sources = context.Get<Data::SourceList>();\r\n\r\n        if (sources.empty())\r\n        {\r\n            context.Reporter.Info() << Resource::String::SourceListNoSources << std::endl;\r\n        }\r\n        else\r\n        {\r\n            for (const auto& source : sources)\r\n            {\r\n                SourceFromPolicy s;\r\n                s.Name = source.Name;\r\n                s.Type = source.Type;\r\n                s.Arg = source.Arg;\r\n                s.Data = source.Data;\r\n                s.Identifier = source.Identifier;\r\n\r\n                std::vector<std::string_view> sourceTrustLevels = Repository::SourceTrustLevelFlagToList(source.TrustLevel);\r\n                s.TrustLevel = std::vector<std::string>(sourceTrustLevels.begin(), sourceTrustLevels.end());\r\n                s.Explicit = source.Explicit;\r\n\r\n                if (ExperimentalFeature::IsEnabled(ExperimentalFeature::Feature::SourcePriority))\r\n                {\r\n                    s.Priority = source.Priority;\r\n                }\r\n\r\n                context.Reporter.Info() << s.ToJsonString() << std::endl;\r\n            }\r\n        }\r\n    }\r\n\r\n    void ForceInstalledCacheUpdate(Execution::Context&)\r\n    {\r\n        // Creating this object is currently sufficient to mark the cache as needing an update for the next time it is opened.\r\n        Repository::Source ignore{ Repository::PredefinedSource::InstalledForceCacheUpdate };\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/SourceFlow.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Command.h\"\r\n#include \"ExecutionContext.h\"\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    // Gets the current source list.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: SourceList\r\n    void GetSourceList(Execution::Context& context);\r\n\r\n    // Gets the source list, filtering it if SourceName is present.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: SourceList\r\n    void GetSourceListWithFilter(Execution::Context& context);\r\n\r\n    // Checks the source list against the inputs to ensure a successful add after this.\r\n    // Required Args: SourceName, SourceArg\r\n    // Inputs: SourceList\r\n    // Outputs: None\r\n    void CheckSourceListAgainstAdd(Execution::Context& context);\r\n\r\n    // Adds the source.\r\n    // Required Args: SourceName, SourceArg\r\n    // Inputs: None\r\n    // Outputs: None\r\n    void AddSource(Execution::Context& context);\r\n\r\n    // Opens a source before source add command.\r\n    // Required Args: SourceName, SourceArg\r\n    // Inputs: None\r\n    // Outputs: Source\r\n    void CreateSourceForSourceAdd(Execution::Context& context);\r\n\r\n    // Lists the sources in SourceList.\r\n    // Required Args: None\r\n    // Inputs: SourceList\r\n    // Outputs: None\r\n    void ListSources(Execution::Context& context);\r\n\r\n    // Updates the sources in SourceList.\r\n    // Required Args: None\r\n    // Inputs: SourceList\r\n    // Outputs: None\r\n    void UpdateSources(Execution::Context& context);\r\n\r\n    // Removes the sources in SourceList.\r\n    // Required Args: None\r\n    // Inputs: SourceList\r\n    // Outputs: None\r\n    void RemoveSources(Execution::Context& context);\r\n\r\n    // Asks the user if they are ok with dropping the sources in SourceList.\r\n    // Required Args: None\r\n    // Inputs: SourceList\r\n    // Outputs: None\r\n    void QueryUserForSourceReset(Execution::Context& context);\r\n\r\n    // Drops the sources in SourceList.\r\n    // Required Args: None\r\n    // Inputs: SourceList\r\n    // Outputs: None\r\n    void ResetSourceList(Execution::Context& context);\r\n\r\n    // Drops all sources.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: None\r\n    void ResetAllSources(Execution::Context& context);\r\n\r\n    // Lists the sources in SourceList in a format appropriate for using in Group Policy\r\n    // Required Args: None\r\n    // Inputs: SourceList\r\n    // Outputs: None\r\n    void ExportSourceList(Execution::Context& context);\r\n\r\n    // Forces an update to the cache of installed packages.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: None\r\n    void ForceInstalledCacheUpdate(Execution::Context& context);\r\n\r\n    // Edits a source in SourceList.\r\n    // Required Args: SourceName\r\n    // Inputs: SourceList\r\n    // Outputs: None\r\n    void EditSources(Execution::Context& context);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/UninstallFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"UninstallFlow.h\"\r\n#include \"InstallFlow.h\"\r\n#include \"FontFlow.h\"\r\n#include \"WorkflowBase.h\"\r\n#include \"DependenciesFlow.h\"\r\n#include \"ShellExecuteInstallerHandler.h\"\r\n#include \"AppInstallerMsixInfo.h\"\r\n#include \"PortableFlow.h\"\r\n#include <AppInstallerDeployment.h>\r\n#include <AppInstallerSynchronization.h>\r\n#include <winget/Runtime.h>\r\n#include <winget/PackageVersionSelection.h>\r\n\r\nusing namespace AppInstaller::CLI::Execution;\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Msix;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Registry;\r\nusing namespace AppInstaller::CLI::Portable;\r\nusing namespace AppInstaller::Utility::literals;\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    namespace\r\n    {\r\n        // Helper for RecordUninstall\r\n        struct UninstallCorrelatedSources\r\n        {\r\n            struct Item\r\n            {\r\n                Utility::LocIndString Identifier;\r\n                Source FromSource;\r\n                std::string SourceIdentifier;\r\n            };\r\n\r\n            void AddIfRemoteAndNotPresent(Source&& source, const Utility::LocIndString& identifier)\r\n            {\r\n                const auto details = source.GetDetails();\r\n                if (!source.ContainsAvailablePackages())\r\n                {\r\n                    return;\r\n                }\r\n\r\n                for (const auto& item : Items)\r\n                {\r\n                    if (item.SourceIdentifier == details.Identifier)\r\n                    {\r\n                        return;\r\n                    }\r\n                }\r\n\r\n                Items.emplace_back(Item{ identifier, std::move(source), details.Identifier });\r\n            }\r\n\r\n            void AddIfRemoteAndNotPresent(const std::shared_ptr<IPackageVersion>& packageVersion)\r\n            {\r\n                AddIfRemoteAndNotPresent(packageVersion->GetSource(), packageVersion->GetProperty(PackageVersionProperty::Id));\r\n            }\r\n\r\n            void AddIfRemoteAndNotPresent(const std::shared_ptr<IPackage>& package)\r\n            {\r\n                AddIfRemoteAndNotPresent(package->GetSource(), package->GetProperty(PackageProperty::Id));\r\n            }\r\n\r\n            std::vector<Item> Items;\r\n        };\r\n    }\r\n\r\n    void UninstallSinglePackage(Execution::Context& context)\r\n    {\r\n        std::shared_ptr<ICompositePackage> package = context.Get<Execution::Data::Package>();\r\n        std::shared_ptr<IPackage> installed = package->GetInstalled();\r\n        std::vector<Repository::PackageVersionKey> installedVersionKeys;\r\n        if (installed)\r\n        {\r\n            installedVersionKeys = installed->GetVersionKeys();\r\n        }\r\n\r\n        // Handle multiple installed versions when we have been told to uninstall all of them.\r\n        if (installedVersionKeys.size() > 1 && context.Args.Contains(Execution::Args::Type::AllVersions))\r\n        {\r\n            bool allSucceeded = true;\r\n            size_t versionsCount = installedVersionKeys.size();\r\n            size_t versionsProgress = 0;\r\n\r\n            for (const auto& key : installedVersionKeys)\r\n            {\r\n                context.Reporter.Info() << '(' << ++versionsProgress << '/' << versionsCount << \") \"_liv;\r\n\r\n                // We want to do best effort to uninstall all versions regardless of previous failures\r\n                auto subContextPtr = context.CreateSubContext();\r\n                Execution::Context& uninstallContext = *subContextPtr;\r\n                auto previousThreadGlobals = uninstallContext.SetForCurrentThread();\r\n\r\n                uninstallContext.Add<Execution::Data::Package>(package);\r\n                uninstallContext.Add<Execution::Data::InstalledPackageVersion>(installed->GetVersion(key));\r\n\r\n                // Prevent individual exceptions from breaking out of the loop\r\n                try\r\n                {\r\n                    uninstallContext <<\r\n                        Workflow::UninstallSinglePackageVersion;\r\n                }\r\n                catch (...)\r\n                {\r\n                    uninstallContext.SetTerminationHR(Workflow::HandleException(uninstallContext, std::current_exception()));\r\n                }\r\n\r\n                uninstallContext.Reporter.Info() << std::endl;\r\n\r\n                if (uninstallContext.IsTerminated())\r\n                {\r\n                    if (context.IsTerminated() && context.GetTerminationHR() == E_ABORT)\r\n                    {\r\n                        // This means that the subcontext being terminated is due to an overall abort\r\n                        context.Reporter.Info() << Resource::String::Cancelled << std::endl;\r\n                        return;\r\n                    }\r\n\r\n                    allSucceeded = false;\r\n                }\r\n            }\r\n\r\n            if (!allSucceeded)\r\n            {\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_MULTIPLE_UNINSTALL_FAILED);\r\n            }\r\n        }\r\n        else if (installedVersionKeys.size() > 1 && !context.Args.Contains(Execution::Args::Type::TargetVersion))\r\n        {\r\n            context.Reporter.Error() << Resource::String::UninstallFailedDueToMultipleVersions << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_MULTIPLE_APPLICATIONS_FOUND);\r\n        }\r\n        else\r\n        {\r\n            context <<\r\n                Workflow::GetInstalledPackageVersion <<\r\n                Workflow::UninstallSinglePackageVersion;\r\n        }\r\n    }\r\n\r\n    void UninstallSinglePackageVersion(Execution::Context& context)\r\n    {\r\n        context <<\r\n            Workflow::ReportInstalledPackageVersionIdentity <<\r\n            Workflow::EnsureSupportForUninstall <<\r\n            Workflow::GetUninstallInfo <<\r\n            Workflow::GetDependenciesInfoForUninstall <<\r\n            Workflow::ReportDependencies(Resource::String::UninstallCommandReportDependencies) <<\r\n            Workflow::ReportExecutionStage(ExecutionStage::Execution) <<\r\n            Workflow::ExecuteUninstaller <<\r\n            Workflow::ReportExecutionStage(ExecutionStage::PostExecution) <<\r\n            Workflow::RecordUninstall;\r\n    }\r\n\r\n    void UninstallMultiplePackages(Execution::Context& context)\r\n    {\r\n        bool allSucceeded = true;\r\n        size_t packagesCount = context.Get<Execution::Data::PackageSubContexts>().size();\r\n        size_t packagesProgress = 0;\r\n\r\n        for (auto& packageContext : context.Get<Execution::Data::PackageSubContexts>())\r\n        {\r\n            packagesProgress++;\r\n            context.Reporter.Info() << '(' << packagesProgress << '/' << packagesCount << \") \"_liv;\r\n\r\n            // We want to do best effort to uninstall all packages regardless of previous failures\r\n            Execution::Context& uninstallContext = *packageContext;\r\n            auto previousThreadGlobals = uninstallContext.SetForCurrentThread();\r\n\r\n            // Prevent individual exceptions from breaking out of the loop\r\n            try\r\n            {\r\n                uninstallContext <<\r\n                    Workflow::ReportPackageIdentity <<\r\n                    Workflow::UninstallSinglePackage;\r\n            }\r\n            catch (...)\r\n            {\r\n                uninstallContext.SetTerminationHR(Workflow::HandleException(uninstallContext, std::current_exception()));\r\n            }\r\n\r\n            uninstallContext.Reporter.Info() << std::endl;\r\n\r\n            if (uninstallContext.IsTerminated())\r\n            {\r\n                if (context.IsTerminated() && context.GetTerminationHR() == E_ABORT)\r\n                {\r\n                    // This means that the subcontext being terminated is due to an overall abort\r\n                    context.Reporter.Info() << Resource::String::Cancelled << std::endl;\r\n                    return;\r\n                }\r\n\r\n                allSucceeded = false;\r\n            }\r\n        }\r\n\r\n        if (!allSucceeded)\r\n        {\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_MULTIPLE_UNINSTALL_FAILED);\r\n        }\r\n    }\r\n\r\n    void GetUninstallInfo(Execution::Context& context)\r\n    {\r\n        auto installedPackageVersion = context.Get<Execution::Data::InstalledPackageVersion>();\r\n\r\n        if (!installedPackageVersion)\r\n        {\r\n            AICLI_LOG(CLI, Verbose, << \"No installed package version; cannot get uninstall information.\");\r\n            return;\r\n        }\r\n\r\n        const std::string installedTypeString = installedPackageVersion->GetMetadata()[PackageVersionMetadata::InstalledType];\r\n        switch (ConvertToInstallerTypeEnum(installedTypeString))\r\n        {\r\n        case InstallerTypeEnum::Exe:\r\n        case InstallerTypeEnum::Burn:\r\n        case InstallerTypeEnum::Inno:\r\n        case InstallerTypeEnum::Nullsoft:\r\n        {\r\n            IPackageVersion::Metadata packageMetadata = installedPackageVersion->GetMetadata();\r\n\r\n            // Default to silent unless it is not present or interactivity is requested\r\n            auto uninstallCommandItr = packageMetadata.find(PackageVersionMetadata::SilentUninstallCommand);\r\n            if (uninstallCommandItr == packageMetadata.end() || context.Args.Contains(Execution::Args::Type::Interactive))\r\n            {\r\n                auto interactiveItr = packageMetadata.find(PackageVersionMetadata::StandardUninstallCommand);\r\n                if (interactiveItr != packageMetadata.end())\r\n                {\r\n                    uninstallCommandItr = interactiveItr;\r\n                }\r\n            }\r\n\r\n            if (uninstallCommandItr == packageMetadata.end())\r\n            {\r\n                context.Reporter.Error() << Resource::String::NoUninstallInfoFound << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_NO_UNINSTALL_INFO_FOUND);\r\n            }\r\n\r\n            context.Add<Execution::Data::UninstallString>(uninstallCommandItr->second);\r\n            break;\r\n        }\r\n        case InstallerTypeEnum::Msi:\r\n        case InstallerTypeEnum::Wix:\r\n        {\r\n            // Uninstall strings for MSI don't include UI level (/q) needed to avoid interactivity,\r\n            // so we handle them differently.\r\n            auto productCodes = installedPackageVersion->GetMultiProperty(PackageVersionMultiProperty::ProductCode);\r\n            if (productCodes.empty())\r\n            {\r\n                context.Reporter.Error() << Resource::String::NoUninstallInfoFound << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_NO_UNINSTALL_INFO_FOUND);\r\n            }\r\n\r\n            context.Add<Execution::Data::ProductCodes>(std::move(productCodes));\r\n            break;\r\n        }\r\n        case InstallerTypeEnum::Msix:\r\n        case InstallerTypeEnum::MSStore:\r\n        {\r\n            auto packageFamilyNames = installedPackageVersion->GetMultiProperty(PackageVersionMultiProperty::PackageFamilyName);\r\n            if (packageFamilyNames.empty())\r\n            {\r\n                context.Reporter.Error() << Resource::String::NoUninstallInfoFound << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_NO_UNINSTALL_INFO_FOUND);\r\n            }\r\n\r\n            context.Add<Execution::Data::PackageFamilyNames>(packageFamilyNames);\r\n            break;\r\n        }\r\n        case InstallerTypeEnum::Portable:\r\n        {\r\n            auto productCodes = installedPackageVersion->GetMultiProperty(PackageVersionMultiProperty::ProductCode);\r\n            if (productCodes.empty())\r\n            {\r\n                context.Reporter.Error() << Resource::String::NoUninstallInfoFound << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_NO_UNINSTALL_INFO_FOUND);\r\n            }\r\n\r\n            const std::string installedScope = context.Get<Execution::Data::InstalledPackageVersion>()->GetMetadata()[Repository::PackageVersionMetadata::InstalledScope];\r\n            const std::string installedArch = context.Get<Execution::Data::InstalledPackageVersion>()->GetMetadata()[Repository::PackageVersionMetadata::InstalledArchitecture];\r\n\r\n            PortableInstaller portableInstaller = PortableInstaller(\r\n                Manifest::ConvertToScopeEnum(installedScope),\r\n                Utility::ConvertToArchitectureEnum(installedArch),\r\n                productCodes[0]);\r\n            context.Add<Execution::Data::PortableInstaller>(std::move(portableInstaller));\r\n            break;\r\n        }\r\n        case InstallerTypeEnum::Font:\r\n            break;\r\n\r\n        default:\r\n            THROW_HR(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED));\r\n        }\r\n    }\r\n\r\n    void ExecuteUninstaller(Execution::Context& context)\r\n    {\r\n        auto installedPackageVersion = context.Get<Execution::Data::InstalledPackageVersion>();\r\n\r\n        if (!installedPackageVersion)\r\n        {\r\n            AICLI_LOG(CLI, Verbose, << \"No installed package version; cannot uninstall.\");\r\n            return;\r\n        }\r\n\r\n        const std::string installedTypeString = installedPackageVersion->GetMetadata()[PackageVersionMetadata::InstalledType];\r\n        InstallerTypeEnum installerType = ConvertToInstallerTypeEnum(installedTypeString);\r\n\r\n        Synchronization::CrossProcessInstallLock lock;\r\n        if (!ExemptFromSingleInstallLocking(installerType))\r\n        {\r\n            // Acquire install lock; if the operation is cancelled it will return false so we will also return.\r\n            if (!context.Reporter.ExecuteWithProgress([&](IProgressCallback& callback)\r\n                {\r\n                    callback.SetProgressMessage(Resource::String::InstallWaitingOnAnother());\r\n                    return lock.Acquire(callback);\r\n                }))\r\n            {\r\n                AICLI_LOG(CLI, Info, << \"Abandoning attempt to acquire install lock due to cancellation\");\r\n                return;\r\n            }\r\n        }\r\n\r\n        switch (installerType)\r\n        {\r\n        case InstallerTypeEnum::Exe:\r\n        case InstallerTypeEnum::Burn:\r\n        case InstallerTypeEnum::Inno:\r\n        case InstallerTypeEnum::Nullsoft:\r\n            context <<\r\n                Workflow::ShellExecuteUninstallImpl <<\r\n                ReportUninstallerResult(\"UninstallString\", APPINSTALLER_CLI_ERROR_EXEC_UNINSTALL_COMMAND_FAILED);\r\n            break;\r\n        case InstallerTypeEnum::Msi:\r\n        case InstallerTypeEnum::Wix:\r\n            context <<\r\n                Workflow::ShellExecuteMsiExecUninstall <<\r\n                ReportUninstallerResult(\"MsiExec\", APPINSTALLER_CLI_ERROR_EXEC_UNINSTALL_COMMAND_FAILED);\r\n            break;\r\n        case InstallerTypeEnum::Msix:\r\n        case InstallerTypeEnum::MSStore:\r\n            context << Workflow::MsixUninstall;\r\n            break;\r\n        case InstallerTypeEnum::Portable:\r\n            context <<\r\n                Workflow::PortableUninstallImpl <<\r\n                ReportUninstallerResult(\"PortableUninstall\"sv, APPINSTALLER_CLI_ERROR_PORTABLE_UNINSTALL_FAILED, true);\r\n            break;\r\n        case InstallerTypeEnum::Font:\r\n            context <<\r\n                Workflow::FontUninstallImpl <<\r\n                ReportUninstallerResult(\"Font\"sv, APPINSTALLER_CLI_ERROR_FONT_UNINSTALL_FAILED, true);\r\n            break;\r\n        default:\r\n        THROW_HR(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED));\r\n        }\r\n    }\r\n\r\n    void MsixUninstall(Execution::Context& context)\r\n    {\r\n        bool isMachineScope = Manifest::ConvertToScopeEnum(context.Args.GetArg(Execution::Args::Type::InstallScope)) == Manifest::ScopeEnum::Machine;\r\n\r\n        // TODO: There was a bug in deployment api if deprovision api was called in packaged context.\r\n        // Remove this check when the OS bug is fixed and back ported.\r\n        if (isMachineScope && Runtime::IsRunningInPackagedContext())\r\n        {\r\n            context.Reporter.Error() << Resource::String::InstallFlowReturnCodeSystemNotSupported << std::endl;\r\n            context.Add<Execution::Data::OperationReturnCode>(static_cast<DWORD>(APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED));\r\n            AICLI_LOG(CLI, Error, << \"Device wide uninstall for msix type is not supported in packaged context.\");\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED);\r\n        }\r\n\r\n        const auto& packageFamilyNames = context.Get<Execution::Data::PackageFamilyNames>();\r\n        context.Reporter.Info() << Resource::String::UninstallFlowStartingPackageUninstall << std::endl;\r\n\r\n        for (const auto& packageFamilyName : packageFamilyNames)\r\n        {\r\n            auto packageFullName = Msix::GetPackageFullNameFromFamilyName(packageFamilyName);\r\n            if (!packageFullName.has_value())\r\n            {\r\n                AICLI_LOG(CLI, Warning, << \"No package found with family name: \" << packageFamilyName);\r\n                continue;\r\n            }\r\n\r\n            AICLI_LOG(CLI, Info, << \"Removing MSIX package: \" << packageFullName.value());\r\n            try\r\n            {\r\n                if (isMachineScope)\r\n                {\r\n                    context.Reporter.ExecuteWithProgress(std::bind(Deployment::RemovePackageMachineScope, packageFamilyName, packageFullName.value(), std::placeholders::_1));\r\n                }\r\n                else\r\n                {\r\n                    context.Reporter.ExecuteWithProgress(std::bind(Deployment::RemovePackage, packageFullName.value(), winrt::Windows::Management::Deployment::RemovalOptions::None, std::placeholders::_1));\r\n                }\r\n            }\r\n            catch (const wil::ResultException& re)\r\n            {\r\n                context.Add<Execution::Data::OperationReturnCode>(re.GetErrorCode());\r\n                context << ReportUninstallerResult(\"MSIXUninstall\"sv, re.GetErrorCode(), /* isHResult */ true);\r\n                return;\r\n            }\r\n        }\r\n\r\n        context.Reporter.Info() << Resource::String::UninstallFlowUninstallSuccess << std::endl;\r\n    }\r\n\r\n    void RecordUninstall(Context& context)\r\n    {\r\n        // In order to report an uninstall to every correlated tracking catalog, we first need to find them all.\r\n        auto package = context.Get<Data::Package>();\r\n        UninstallCorrelatedSources correlatedSources;\r\n\r\n        // Start with the installed version\r\n        correlatedSources.AddIfRemoteAndNotPresent(GetInstalledVersion(package));\r\n\r\n        // Then look through all available versions\r\n        for (const auto& availablePackage : package->GetAvailable())\r\n        {\r\n            correlatedSources.AddIfRemoteAndNotPresent(availablePackage);\r\n        }\r\n\r\n        // Finally record the uninstall for each found value\r\n        for (const auto& item : correlatedSources.Items)\r\n        {\r\n            auto trackingCatalog = item.FromSource.GetTrackingCatalog();\r\n            trackingCatalog.RecordUninstall(item.Identifier);\r\n        }\r\n    }\r\n\r\n    void ReportUninstallerResult::operator()(Execution::Context& context) const\r\n    {\r\n        DWORD uninstallResult = context.Get<Execution::Data::OperationReturnCode>();\r\n        if (uninstallResult != 0)\r\n        {\r\n            const auto installedPackageVersion = context.Get<Execution::Data::InstalledPackageVersion>();\r\n            Logging::Telemetry().LogUninstallerFailure(\r\n                installedPackageVersion->GetProperty(PackageVersionProperty::Id),\r\n                installedPackageVersion->GetProperty(PackageVersionProperty::Version),\r\n                m_uninstallerType,\r\n                uninstallResult);\r\n\r\n            if (m_isHResult)\r\n            {\r\n                context.Reporter.Error()\r\n                    << Resource::String::UninstallFailedWithCode(Utility::LocIndView{ GetUserPresentableMessage(uninstallResult) })\r\n                    << std::endl;\r\n            }\r\n            else\r\n            {\r\n                context.Reporter.Error()\r\n                    << Resource::String::UninstallFailedWithCode(uninstallResult)\r\n                    << std::endl;\r\n            }\r\n\r\n            // Show installer log path if exists\r\n            if (context.Contains(Execution::Data::LogPath) && std::filesystem::exists(context.Get<Execution::Data::LogPath>()))\r\n            {\r\n                auto installerLogPath = Utility::LocIndString{ context.Get<Execution::Data::LogPath>().u8string() };\r\n                context.Reporter.Info() << Resource::String::InstallerLogAvailable(installerLogPath) << std::endl;\r\n            }\r\n\r\n            AICLI_TERMINATE_CONTEXT(m_hr);\r\n        }\r\n        else\r\n        {\r\n            context.Reporter.Info() << Resource::String::UninstallFlowUninstallSuccess << std::endl;\r\n        }\r\n    }\r\n\r\n    void EnsureSupportForUninstall(Execution::Context& context)\r\n    {\r\n        auto installedPackageVersion = context.Get<Execution::Data::InstalledPackageVersion>();\r\n        const std::string installedTypeString = installedPackageVersion->GetMetadata()[PackageVersionMetadata::InstalledType];\r\n        auto installedType = ConvertToInstallerTypeEnum(installedTypeString);\r\n        if (installedType == InstallerTypeEnum::Portable)\r\n        {\r\n            const std::string installedScope = installedPackageVersion->GetMetadata()[Repository::PackageVersionMetadata::InstalledScope];\r\n            if (Manifest::ConvertToScopeEnum(installedScope) == Manifest::ScopeEnum::Machine)\r\n            {\r\n                context << EnsureRunningAsAdmin;\r\n            }\r\n        }\r\n        else if (installedType == InstallerTypeEnum::Msix)\r\n        {\r\n            if (Manifest::ConvertToScopeEnum(context.Args.GetArg(Execution::Args::Type::InstallScope)) == Manifest::ScopeEnum::Machine)\r\n            {\r\n                context << EnsureRunningAsAdmin;\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/UninstallFlow.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"ExecutionContext.h\"\n\nnamespace AppInstaller::CLI::Workflow\n{\n    // Uninstalls a single package. This also does the reporting, user interaction, and recording\n    // for single-package uninstallation.\n    // RequiredArgs: None\n    // Inputs: Package\n    // Outputs: None\n    void UninstallSinglePackage(Execution::Context& context);\n\n    // Uninstalls a single package version. This also does the reporting, user interaction, and recording\n    // for single-package uninstallation.\n    // RequiredArgs: None\n    // Inputs: InstalledPackageVersion\n    // Outputs: None\n    void UninstallSinglePackageVersion(Execution::Context& context);\n\n    // Uninstalls multiple packages.\n    // RequiredArgs: None\n    // Inputs: PackageSubContexts\n    // Outputs: None\n    //   SubContext Inputs: Package\n    //   SubContext Outputs: None\n    void UninstallMultiplePackages(Execution::Context& context);\n\n    // Gets the command string or package family names used to uninstall the package.\n    // Required Args: None\n    // Inputs: InstalledPackageVersion\n    // Output: UninstallString?, PackageFamilyNames?\n    void GetUninstallInfo(Execution::Context& context);\n\n    // Uninstalls the package according to its type.\n    // Required Args: None\n    // Inputs: InstalledPackageVersion, UninstallString?, PackageFamilyNames?\n    // Output: None\n    void ExecuteUninstaller(Execution::Context& context);\n\n    // Removes the MSIX.\n    // Required Args: None\n    // Inputs: PackageFamilyNames\n    // Outputs: None\n    void MsixUninstall(Execution::Context& context);\n\n    // Records the uninstall to the tracking catalog.\n    // Required Args: None\n    // Inputs: Package\n    // Outputs: None\n    void RecordUninstall(Execution::Context& context);\n\n    // Reports the return code returned by the Uninstaller.\n    // Required Args: None\n    // Inputs: InstalledPackageVersion\n    // Outputs: None\n    struct ReportUninstallerResult : public WorkflowTask\n    {\n        ReportUninstallerResult(std::string_view uninstallerType, HRESULT hr, bool isHResult = false) :\n            WorkflowTask(\"ReportUninstallerResult\"),\n            m_uninstallerType(uninstallerType),\n            m_hr(hr),\n            m_isHResult(isHResult) {}\n\n        void operator()(Execution::Context& context) const override;\n\n    private:\n        // Uninstaller type used when reporting failures.\n        std::string_view m_uninstallerType;\n        // Result to return if the Uninstaller failed.\n        HRESULT m_hr;\n        // Whether the Uninstaller result is an HRESULT. This guides how we show it.\n        bool m_isHResult;\n    };\n\n    // Verifies that the uninstall operation is supported.\n    // Required Args: None\n    // Inputs: InstalledPackageVersion\n    // Outputs: None\n    void EnsureSupportForUninstall(Execution::Context& context);\n}\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/UpdateFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"WorkflowBase.h\"\r\n#include \"DependenciesFlow.h\"\r\n#include \"InstallFlow.h\"\r\n#include \"UpdateFlow.h\"\r\n#include <winget/ManifestComparator.h>\r\n#include <winget/PinningData.h>\r\n#include <winget/PackageVersionSelection.h>\r\n\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Repository::Microsoft;\r\nusing namespace AppInstaller::Pinning;\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    namespace\r\n    {\r\n        bool IsUpdateVersionAvailable(const Utility::Version& installedVersion, const Utility::Version& updateVersion)\r\n        {\r\n            return installedVersion < updateVersion;\r\n        }\r\n\r\n        void AddToPackageSubContextsIfNotPresent(std::vector<std::unique_ptr<Execution::Context>>& packageSubContexts, std::unique_ptr<Execution::Context> packageContext)\r\n        {\r\n            for (auto const& existing : packageSubContexts)\r\n            {\r\n                if (existing->Get<Execution::Data::Manifest>().Id == packageContext->Get<Execution::Data::Manifest>().Id &&\r\n                    existing->Get<Execution::Data::Manifest>().Version == packageContext->Get<Execution::Data::Manifest>().Version &&\r\n                    existing->Get<Execution::Data::PackageVersion>()->GetProperty(PackageVersionProperty::SourceIdentifier) == packageContext->Get<Execution::Data::PackageVersion>()->GetProperty(PackageVersionProperty::SourceIdentifier))\r\n                {\r\n                    return;\r\n                }\r\n            }\r\n\r\n            packageSubContexts.emplace_back(std::move(packageContext));\r\n        }\r\n    }\r\n\r\n    void SelectLatestApplicableVersion::operator()(Execution::Context& context) const\r\n    {\r\n        auto package = context.Get<Execution::Data::Package>();\r\n        auto installedPackage = context.Get<Execution::Data::InstalledPackageVersion>();\r\n        const bool reportVersionNotFound = m_isSinglePackage;\r\n\r\n        bool isUpgrade = WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::InstallerExecutionUseUpdate);;\r\n        Utility::Version installedVersion;\r\n        if (isUpgrade)\r\n        {\r\n            installedVersion = Utility::Version(installedPackage->GetProperty(PackageVersionProperty::Version));\r\n        }\r\n\r\n        Manifest::ManifestComparator manifestComparator(GetManifestComparatorOptions(context, isUpgrade ? installedPackage->GetMetadata() : IPackageVersion::Metadata{}));\r\n        bool versionFound = false;\r\n        bool installedTypeInapplicable = false;\r\n        bool packagePinned = false;\r\n\r\n        if (isUpgrade && installedVersion.IsUnknown() && !context.Args.Contains(Execution::Args::Type::IncludeUnknown))\r\n        {\r\n            // the package has an unknown version and the user did not request to upgrade it anyway\r\n            if (reportVersionNotFound)\r\n            {\r\n                context.Reporter.Info() << Resource::String::UpgradeUnknownVersionExplanation << std::endl;\r\n            }\r\n\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE);\r\n        }\r\n\r\n        // If we are updating a single package or we got the --include-pinned flag,\r\n        // we include packages with Pinning pins\r\n        const bool includePinned = m_isSinglePackage || context.Args.Contains(Execution::Args::Type::IncludePinned);\r\n\r\n        PinningData pinningData{ PinningData::Disposition::ReadOnly };\r\n        auto evaluator = pinningData.CreatePinStateEvaluator(includePinned ? PinBehavior::IncludePinned : PinBehavior::ConsiderPins, GetInstalledVersion(package));\r\n\r\n        // The version keys should have already been sorted by version\r\n        auto availableVersions = GetAvailableVersionsForInstalledVersion(package);\r\n        const auto& versionKeys = availableVersions->GetVersionKeys();\r\n        // Assume that no update versions are applicable\r\n        bool upgradeVersionAvailable = false;\r\n        for (const auto& key : versionKeys)\r\n        {\r\n            // Check Applicable Version\r\n            if (!isUpgrade || IsUpdateVersionAvailable(installedVersion, Utility::Version(key.Version)))\r\n            {\r\n                // The only way to enter this portion of the statement with isUpgrade is if the version is available\r\n                if (isUpgrade)\r\n                {\r\n                    AICLI_LOG(CLI, Verbose, << \"Updating from [\" << installedVersion.ToString() << \"] to [\" << key.Version << \"]\");\r\n                    upgradeVersionAvailable = true;\r\n                }\r\n\r\n                auto packageVersion = availableVersions->GetVersion(key);\r\n\r\n                // Check if the package is pinned\r\n                PinType pinType = evaluator.EvaluatePinType(packageVersion);\r\n                if (pinType != Pinning::PinType::Unknown)\r\n                {\r\n                    AICLI_LOG(CLI, Info, << \"Package [\" << package->GetProperty(PackageProperty::Id) << \" with Version[\" << key.Version << \"] from Source[\" << key.SourceId << \"] has a Pin with type[\" << ToString(pinType) << \"]\");\r\n                    if (context.Args.Contains(Execution::Args::Type::Force))\r\n                    {\r\n                        AICLI_LOG(CLI, Info, << \"Ignoring pin due to --force argument\");\r\n                    }\r\n                    else\r\n                    {\r\n                        packagePinned = true;\r\n                        continue;\r\n                    }\r\n                }\r\n\r\n                auto manifest = packageVersion->GetManifest();\r\n\r\n                // Check applicable Installer\r\n                auto [installer, inapplicabilities] = manifestComparator.GetPreferredInstaller(manifest);\r\n                if (!installer.has_value())\r\n                {\r\n                    // If there is at least one installer whose only reason is InstalledType.\r\n                    auto onlyInstalledType = std::find(inapplicabilities.begin(), inapplicabilities.end(), Manifest::InapplicabilityFlags::InstalledType);\r\n                    if (onlyInstalledType != inapplicabilities.end())\r\n                    {\r\n                        installedTypeInapplicable = true;\r\n                    }\r\n\r\n                    continue;\r\n                }\r\n\r\n                Logging::Telemetry().LogSelectedInstaller(\r\n                    static_cast<int>(installer->Arch),\r\n                    installer->Url,\r\n                    Manifest::InstallerTypeToString(installer->EffectiveInstallerType()),\r\n                    Manifest::ScopeToString(installer->Scope),\r\n                    installer->Locale);\r\n\r\n                Logging::Telemetry().LogManifestFields(\r\n                    manifest.Id,\r\n                    manifest.DefaultLocalization.Get<Manifest::Localization::PackageName>(),\r\n                    manifest.Version);\r\n\r\n                // Since we already did installer selection, just populate the context Data\r\n                manifest.ApplyLocale(installer->Locale);\r\n                context.Add<Execution::Data::Manifest>(std::move(manifest));\r\n                context.Add<Execution::Data::PackageVersion>(std::move(packageVersion));\r\n                context.Add<Execution::Data::Installer>(std::move(installer));\r\n\r\n                versionFound = true;\r\n                break;\r\n            }\r\n            else\r\n            {\r\n                // Any following versions are not applicable\r\n                break;\r\n            }\r\n        }\r\n\r\n        if (!versionFound)\r\n        {\r\n            if (reportVersionNotFound)\r\n            {\r\n                if (installedTypeInapplicable)\r\n                {\r\n                    context.Reporter.Info() << Resource::String::UpgradeDifferentInstallTechnologyInNewerVersions << std::endl;\r\n                }\r\n                else if (packagePinned)\r\n                {\r\n                    context.Reporter.Info() << Resource::String::UpgradeIsPinned << std::endl;\r\n                    AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_PACKAGE_IS_PINNED);\r\n                }\r\n                else if (isUpgrade)\r\n                {\r\n                    if (!upgradeVersionAvailable)\r\n                    {\r\n                        // This is the case when no newer versions are available in a configured source\r\n                        context.Reporter.Info() << Resource::String::UpdateNoPackagesFound << std::endl\r\n                            << Resource::String::UpdateNoPackagesFoundReason << std::endl;\r\n                    }\r\n                    else\r\n                    {\r\n                        // This is the case when newer versions are available in a configured source, but none are applicable due to OS Version, user requirement, etc.\r\n                        context.Reporter.Info() << Resource::String::UpdateNotApplicable << std::endl\r\n                            << Resource::String::UpdateNotApplicableReason << std::endl;\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    context.Reporter.Error() << Resource::String::NoApplicableInstallers << std::endl;\r\n                }\r\n            }\r\n\r\n            AICLI_TERMINATE_CONTEXT(isUpgrade ? APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE : APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER);\r\n        }\r\n    }\r\n\r\n    void EnsureUpdateVersionApplicable(Execution::Context& context)\r\n    {\r\n        auto installedPackage = context.Get<Execution::Data::InstalledPackageVersion>();\r\n        Utility::Version installedVersion = Utility::Version(installedPackage->GetProperty(PackageVersionProperty::Version));\r\n        Utility::Version updateVersion(context.Get<Execution::Data::Manifest>().Version);\r\n\r\n        if (!IsUpdateVersionAvailable(installedVersion, updateVersion))\r\n        {\r\n            context.Reporter.Info() << Resource::String::UpdateNoPackagesFound << std::endl\r\n                << Resource::String::UpdateNoPackagesFoundReason << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE);\r\n        }\r\n    }\r\n\r\n    void UpdateAllApplicable(Execution::Context& context)\r\n    {\r\n        const auto& matches = context.Get<Execution::Data::SearchResult>().Matches;\r\n        std::vector<std::unique_ptr<Execution::Context>> packageSubContexts;\r\n        bool updateAllFoundUpdate = false;\r\n        int packagesWithUnknownVersionSkipped = 0;\r\n        int packagesThatRequireExplicitSkipped = 0;\r\n\r\n        for (const auto& match : matches)\r\n        {\r\n            // We want to do best effort to update all applicable updates regardless on previous update failure\r\n            auto updateContextPtr = context.CreateSubContext();\r\n            Execution::Context& updateContext = *updateContextPtr;\r\n            auto previousThreadGlobals = updateContext.SetForCurrentThread();\r\n            auto installedVersion = GetInstalledVersion(match.Package);\r\n\r\n            updateContext.Add<Execution::Data::Package>(match.Package);\r\n\r\n            // Filter out packages with unknown installed versions\r\n            if (Utility::Version(installedVersion->GetProperty(PackageVersionProperty::Version)).IsUnknown() &&\r\n                !context.Args.Contains(Execution::Args::Type::IncludeUnknown))\r\n            {\r\n                // we don't know what the package's version is and the user didn't ask to upgrade it anyway.\r\n                AICLI_LOG(CLI, Info, << \"Skipping \" << match.Package->GetProperty(PackageProperty::Id) << \" as it has unknown installed version\");\r\n                ++packagesWithUnknownVersionSkipped;\r\n                continue;\r\n            }\r\n\r\n            updateContext <<\r\n                Workflow::GetInstalledPackageVersion <<\r\n                Workflow::ReportExecutionStage(ExecutionStage::Discovery) <<\r\n                SelectLatestApplicableVersion(false);\r\n\r\n            if (updateContext.GetTerminationHR() == APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE)\r\n            {\r\n                continue;\r\n            }\r\n\r\n            // Filter out packages that require explicit upgrade.\r\n            // User-defined pins are handled when selecting the version to use.\r\n            auto installedMetadata = updateContext.Get<Execution::Data::InstalledPackageVersion>()->GetMetadata();\r\n            auto pinnedState = ConvertToPinTypeEnum(installedMetadata[PackageVersionMetadata::PinnedState]);\r\n            if (pinnedState == PinType::PinnedByManifest)\r\n            {\r\n                // Note that for packages pinned by the manifest\r\n                // this does not consider whether the update to be installed has\r\n                // RequireExplicitUpgrade. While this has the downside of not working with\r\n                // packages installed from another source, it ensures consistency with the\r\n                // list of available updates (there we don't have the selected installer)\r\n                // and at most we will update each package like this once.\r\n                AICLI_LOG(CLI, Info, << \"Skipping \" << match.Package->GetProperty(PackageProperty::Id) << \" as it requires explicit upgrade\");\r\n                ++packagesThatRequireExplicitSkipped;\r\n                continue;\r\n            }\r\n\r\n            updateAllFoundUpdate = true;\r\n\r\n            AddToPackageSubContextsIfNotPresent(packageSubContexts, std::move(updateContextPtr));\r\n        }\r\n\r\n        if (updateAllFoundUpdate)\r\n        {\r\n            context.Add<Execution::Data::PackageSubContexts>(std::move(packageSubContexts));\r\n            context.Reporter.Info() << std::endl;\r\n\r\n            ProcessMultiplePackages::Flags flags = ProcessMultiplePackages::Flags::None;\r\n            if (Settings::User().Get<Settings::Setting::InstallSkipDependencies>() || context.Args.Contains(Execution::Args::Type::SkipDependencies))\r\n            {\r\n                flags = ProcessMultiplePackages::Flags::IgnoreDependencies;\r\n            }\r\n\r\n            context <<\r\n                ProcessMultiplePackages(\r\n                    Resource::String::PackageRequiresDependencies,\r\n                    APPINSTALLER_CLI_ERROR_UPDATE_ALL_HAS_FAILURE,\r\n                    flags,\r\n                    { APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE });\r\n        }\r\n\r\n        if (packagesWithUnknownVersionSkipped > 0)\r\n        {\r\n            AICLI_LOG(CLI, Info, << packagesWithUnknownVersionSkipped << \" package(s) skipped due to unknown installed version\");\r\n            context.Reporter.Info() << Resource::String::UpgradeUnknownVersionCount(packagesWithUnknownVersionSkipped) << std::endl;\r\n        }\r\n\r\n        if (packagesThatRequireExplicitSkipped > 0)\r\n        {\r\n            AICLI_LOG(CLI, Info, << packagesThatRequireExplicitSkipped << \" package(s) skipped due to requiring explicit upgrade\");\r\n            context.Reporter.Info() << Resource::String::UpgradeRequireExplicitCount(packagesThatRequireExplicitSkipped) << std::endl;\r\n        }\r\n    }\r\n\r\n    void SelectSinglePackageVersionForInstallOrUpgrade::operator()(Execution::Context& context) const\r\n    {\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), m_operationType != OperationType::Install && m_operationType != OperationType::Upgrade);\r\n\r\n        context <<\r\n            HandleSearchResultFailures <<\r\n            EnsureOneMatchFromSearchResult(m_operationType) <<\r\n            GetInstalledPackageVersion;\r\n\r\n        if ( m_operationType != OperationType::Upgrade && \r\n            context.Contains(Execution::Data::InstalledPackageVersion) &&\r\n            context.Get<Execution::Data::InstalledPackageVersion>() != nullptr )\r\n        {\r\n            if (context.Args.Contains(Execution::Args::Type::NoUpgrade))\r\n            {\r\n                AICLI_LOG(CLI, Warning, << \"Found installed package, exiting installation.\");\r\n                context.Reporter.Warn() << Resource::String::PackageAlreadyInstalled << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_PACKAGE_ALREADY_INSTALLED);\r\n            }\r\n            else\r\n            {\r\n                AICLI_LOG(CLI, Info, << \"Found installed package, converting to upgrade flow\");\r\n                context.Reporter.Info() << Execution::ConvertToUpgradeFlowEmphasis << Resource::String::ConvertInstallFlowToUpgrade << std::endl;\r\n                context.SetFlags(Execution::ContextFlag::InstallerExecutionUseUpdate);\r\n                m_operationType = OperationType::Upgrade;\r\n            }\r\n        }\r\n\r\n        if (context.Args.Contains(Execution::Args::Type::Version))\r\n        {\r\n            // If version specified, use the version and verify applicability\r\n            context << GetManifestFromPackage(/* considerPins */ true);\r\n\r\n            if (m_operationType == OperationType::Upgrade && !m_allowDowngrade)\r\n            {\r\n                context << EnsureUpdateVersionApplicable;\r\n            }\r\n\r\n            context << SelectInstaller;\r\n        }\r\n        else\r\n        {\r\n            // Iterate through available versions to find latest applicable version.\r\n            // This step also populates Manifest and Installer in context data.\r\n            context << SelectLatestApplicableVersion(true);\r\n        }\r\n\r\n        context << EnsureApplicableInstaller;\r\n    }\r\n\r\n    void InstallOrUpgradeSinglePackage::operator()(Execution::Context& context) const\r\n    {\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), m_operationType != OperationType::Install && m_operationType != OperationType::Upgrade);\r\n\r\n        context <<\r\n            SearchSourceForSingle <<\r\n            SelectSinglePackageVersionForInstallOrUpgrade(m_operationType) <<\r\n            InstallSinglePackage;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/UpdateFlow.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ExecutionContext.h\"\r\n#include \"WorkflowBase.h\"\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    // Iterates through all available versions from a package and find latest applicable version\r\n    // Required Args: bool indicating whether to report update not found\r\n    // Inputs: InstalledPackageVersion?, Package\r\n    // Outputs: Manifest?, Installer?\r\n    struct SelectLatestApplicableVersion : public WorkflowTask\r\n    {\r\n        SelectLatestApplicableVersion(bool isSinglePackage) :\r\n            WorkflowTask(\"SelectLatestApplicableUpdate\"), m_isSinglePackage(isSinglePackage) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        bool m_isSinglePackage;\r\n    };\r\n\r\n    // Ensures the update package has higher version than installed\r\n    // Required Args: None\r\n    // Inputs: Manifest, InstalledPackageVersion\r\n    // Outputs: None\r\n    void EnsureUpdateVersionApplicable(Execution::Context& context);\r\n\r\n    // Update all packages from SearchResult to latest if applicable\r\n    // Required Args: None\r\n    // Inputs: SearchResult\r\n    // Outputs: None\r\n    void UpdateAllApplicable(Execution::Context& context);\r\n\r\n    // Select single package version for install or upgrade\r\n    // Required Args: bool indicating whether the flow is for upgrade\r\n    // Inputs: Source, SearchResult\r\n    // Outputs: None\r\n    struct SelectSinglePackageVersionForInstallOrUpgrade : public WorkflowTask\r\n    {\r\n        SelectSinglePackageVersionForInstallOrUpgrade(OperationType operation, bool allowDowngrade = false) :\r\n            WorkflowTask(\"SelectSinglePackageVersionForInstallOrUpgrade\"), m_operationType(operation), m_allowDowngrade(allowDowngrade) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        mutable OperationType m_operationType;\r\n        bool m_allowDowngrade;\r\n    };\r\n\r\n    // Install or upgrade a single package\r\n    // Required Args: bool indicating whether the flow is for upgrade\r\n    // Inputs: Source\r\n    // Outputs: None\r\n    struct InstallOrUpgradeSinglePackage : public WorkflowTask\r\n    {\r\n        InstallOrUpgradeSinglePackage(OperationType operation) :\r\n            WorkflowTask(\"InstallOrUpgradeSinglePackage\"), m_operationType(operation) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        mutable OperationType m_operationType;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/WorkflowBase.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"WorkflowBase.h\"\r\n#include \"ExecutionContext.h\"\r\n#include <winget/ManifestComparator.h>\r\n#include \"PromptFlow.h\"\r\n#include \"ShowFlow.h\"\r\n#include \"Sixel.h\"\r\n#include \"TableOutput.h\"\r\n#include <winget/FileCache.h>\r\n#include <winget/ExperimentalFeature.h>\r\n#include <winget/ManifestYamlParser.h>\r\n#include <winget/Pin.h>\r\n#include <winget/PinningData.h>\r\n#include <AppInstallerSHA256.h>\r\n#include <winget/Runtime.h>\r\n#include <winget/PackageVersionSelection.h>\r\n#include <winget/IconExtraction.h>\r\n\r\nEXTERN_C IMAGE_DOS_HEADER __ImageBase;\r\n\r\nusing namespace std::string_literals;\r\nusing namespace AppInstaller::Utility::literals;\r\nusing namespace AppInstaller::Pinning;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Settings;\r\nusing namespace winrt::Windows::Foundation;\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    namespace\r\n    {\r\n        std::string GetMatchCriteriaDescriptor(const ResultMatch& match)\r\n        {\r\n            if (match.MatchCriteria.Field != PackageMatchField::Id && match.MatchCriteria.Field != PackageMatchField::Name)\r\n            {\r\n                std::string result{ ToString(match.MatchCriteria.Field) };\r\n                result += \": \";\r\n                result += match.MatchCriteria.Value;\r\n                return result;\r\n            }\r\n            else\r\n            {\r\n                return {};\r\n            }\r\n        }\r\n\r\n        void ReportIdentity(\r\n            Execution::Context& context,\r\n            Utility::LocIndView prefix,\r\n            std::optional<Resource::StringId> label,\r\n            std::string_view name,\r\n            std::string_view id,\r\n            std::string_view version = {},\r\n            Execution::Reporter::Level level = Execution::Reporter::Level::Info)\r\n        {\r\n            auto out = context.Reporter.GetOutputStream(level);\r\n            out << prefix;\r\n            if (label)\r\n            {\r\n                out << *label << ' ';\r\n            }\r\n            out << Execution::NameEmphasis << name << \" [\"_liv << Execution::IdEmphasis << id << ']';\r\n\r\n            if (!version.empty())\r\n            {\r\n                out << ' ' << Resource::String::ShowVersion << ' ' << version;\r\n            }\r\n\r\n            out << std::endl;\r\n        }\r\n\r\n        bool IsSecondIconResolutionBetter(Manifest::IconResolutionEnum current, Manifest::IconResolutionEnum alternative)\r\n        {\r\n            static constexpr std::array<uint8_t, ToIntegral(Manifest::IconResolutionEnum::Square256) + 1> s_iconResolutionOrder\r\n            {\r\n                9, // Unknown\r\n                8, // Custom\r\n                15, // Square16\r\n                14, // Square20\r\n                13, // Square24\r\n                12, // Square30\r\n                11, // Square32\r\n                10, // Square36\r\n                6, // Square40\r\n                5, // Square48\r\n                4, // Square60\r\n                3, // Square64\r\n                2, // Square72\r\n                0, // Square80\r\n                1, // Square96\r\n                7, // Square256\r\n            };\r\n\r\n            return s_iconResolutionOrder.at(ToIntegral(alternative)) < s_iconResolutionOrder.at(ToIntegral(current));\r\n        }\r\n\r\n        // Determines icon fit given two options.\r\n        // Targets an 80x80 icon as the best resolution for this use case.\r\n        // TODO: Consider theme based on current background color.\r\n        bool IsSecondIconBetter(const Manifest::Icon& current, const Manifest::Icon& alternative)\r\n        {\r\n            return IsSecondIconResolutionBetter(current.Resolution, alternative.Resolution);\r\n        }\r\n\r\n        bool IsSecondIconBetter(const ExtractedIconInfo& current, const ExtractedIconInfo& alternative)\r\n        {\r\n            return IsSecondIconResolutionBetter(current.IconResolution, alternative.IconResolution);\r\n        }\r\n\r\n        void ShowIcon(Execution::OutputStream& outputStream, VirtualTerminal::Sixel::Image& icon)\r\n        {\r\n            // Using a height of 4 arbitrarily; allow width up to the entire console.\r\n            UINT imageHeightCells = 4;\r\n            UINT imageWidthCells = static_cast<UINT>(Execution::GetConsoleWidth());\r\n\r\n            icon.RenderSizeInCells(imageWidthCells, imageHeightCells);\r\n            icon.RenderTo(outputStream);\r\n\r\n            // Force the final sixel line to not be overwritten\r\n            outputStream << std::endl;\r\n        }\r\n\r\n        void ShowManifestIcon(Execution::Context& context, const Manifest::Manifest& manifest) try\r\n        {\r\n            if (!context.Reporter.SixelsEnabled())\r\n            {\r\n                return;\r\n            }\r\n\r\n            auto icons = manifest.CurrentLocalization.Get<Manifest::Localization::Icons>();\r\n            const Manifest::Icon* bestFitIcon = nullptr;\r\n\r\n            for (const auto& icon : icons)\r\n            {\r\n                if (!bestFitIcon || IsSecondIconBetter(*bestFitIcon, icon))\r\n                {\r\n                    bestFitIcon = &icon;\r\n                }\r\n            }\r\n\r\n            if (!bestFitIcon)\r\n            {\r\n                return;\r\n            }\r\n\r\n            // Use a cache to hold the icons\r\n            auto splitUri = Utility::SplitFileNameFromURI(bestFitIcon->Url);\r\n            Caching::FileCache fileCache{ Caching::FileCache::Type::Icon, Utility::SHA256::ConvertToString(bestFitIcon->Sha256), { splitUri.first } };\r\n            auto iconStream = fileCache.GetFile(splitUri.second, bestFitIcon->Sha256);\r\n\r\n            VirtualTerminal::Sixel::Image sixelIcon{ *iconStream, bestFitIcon->FileType };\r\n            auto infoOut = context.Reporter.Info();\r\n\r\n            ShowIcon(infoOut, sixelIcon);\r\n        }\r\n        CATCH_LOG();\r\n\r\n        void ShowExtractedIcon(Execution::OutputStream& outputStream, const std::vector<ExtractedIconInfo>& icons) try\r\n        {\r\n            const ExtractedIconInfo* bestFitIcon = nullptr;\r\n\r\n            for (const auto& icon : icons)\r\n            {\r\n                if (!bestFitIcon || IsSecondIconBetter(*bestFitIcon, icon))\r\n                {\r\n                    bestFitIcon = &icon;\r\n                }\r\n            }\r\n\r\n            if (!bestFitIcon)\r\n            {\r\n                return;\r\n            }\r\n\r\n            VirtualTerminal::Sixel::Image sixelIcon{ bestFitIcon->IconContent, bestFitIcon->IconFileType };\r\n            ShowIcon(outputStream, sixelIcon);\r\n        }\r\n        CATCH_LOG();\r\n\r\n        Repository::Source OpenNamedSource(Execution::Context& context, Utility::LocIndView sourceName)\r\n        {\r\n            Repository::Source source;\r\n\r\n            try\r\n            {\r\n                source = Source{ sourceName };\r\n\r\n                if (!source)\r\n                {\r\n                    std::vector<SourceDetails> sources = Source::GetCurrentSources();\r\n\r\n                    if (!sourceName.empty() && !sources.empty())\r\n                    {\r\n                        // A bad name was given, try to help.\r\n                        context.Reporter.Error() << Resource::String::OpenSourceFailedNoMatch(sourceName) << std::endl;\r\n                        context.Reporter.Info() << Resource::String::OpenSourceFailedNoMatchHelp << std::endl;\r\n                        for (const auto& details : sources)\r\n                        {\r\n                            context.Reporter.Info() << \"  \"_liv << details.Name << std::endl;\r\n                        }\r\n\r\n                        AICLI_TERMINATE_CONTEXT_RETURN(APPINSTALLER_CLI_ERROR_SOURCE_NAME_DOES_NOT_EXIST, {});\r\n                    }\r\n                    else\r\n                    {\r\n                        // Even if a name was given, there are no sources\r\n                        context.Reporter.Error() << Resource::String::OpenSourceFailedNoSourceDefined << std::endl;\r\n                        AICLI_TERMINATE_CONTEXT_RETURN(APPINSTALLER_CLI_ERROR_NO_SOURCES_DEFINED, {});\r\n                    }\r\n                }\r\n\r\n                if (context.Args.Contains(Execution::Args::Type::CustomHeader))\r\n                {\r\n                    std::string customHeader{ context.Args.GetArg(Execution::Args::Type::CustomHeader) };\r\n                    if (!source.SetCustomHeader(customHeader))\r\n                    {\r\n                        context.Reporter.Warn() << Resource::String::HeaderArgumentNotApplicableForNonRestSourceWarning << std::endl;\r\n                    }\r\n                }\r\n\r\n                auto openFunction = [&](IProgressCallback& progress)->std::vector<Repository::SourceDetails>\r\n                {\r\n                    source.SetCaller(\"winget-cli\");\r\n                    source.SetAuthenticationArguments(GetAuthenticationArguments(context));\r\n                    source.SetThreadGlobals(context.GetSharedThreadGlobals());\r\n                    return source.Open(progress);\r\n                };\r\n                auto updateFailures = context.Reporter.ExecuteWithProgress(openFunction, true);\r\n\r\n                // We'll only report the source update failure as warning and continue\r\n                for (const auto& s : updateFailures)\r\n                {\r\n                    context.Reporter.Warn() << Resource::String::SourceOpenWithFailedUpdate(Utility::LocIndView{ s.Name }) << std::endl;\r\n                }\r\n\r\n                // Report sources that may need authentication\r\n                if (source.IsComposite())\r\n                {\r\n                    for (const auto& s : source.GetAvailableSources())\r\n                    {\r\n                        if (s.GetInformation().Authentication.Type != Authentication::AuthenticationType::None)\r\n                        {\r\n                            context.Reporter.Info() << Execution::AuthenticationEmphasis << Resource::String::SourceRequiresAuthentication(Utility::LocIndView{ s.GetDetails().Name }) << std::endl;\r\n                        }\r\n                    }\r\n                }\r\n                else if (source.GetInformation().Authentication.Type != Authentication::AuthenticationType::None)\r\n                {\r\n                    context.Reporter.Info() << Execution::AuthenticationEmphasis << Resource::String::SourceRequiresAuthentication(Utility::LocIndView{ source.GetDetails().Name }) << std::endl;\r\n                }\r\n            }\r\n            catch (const wil::ResultException& re)\r\n            {\r\n                context.Reporter.Error() << Resource::String::SourceOpenFailedSuggestion << std::endl;\r\n                if (re.GetErrorCode() == APPINSTALLER_CLI_ERROR_FAILED_TO_OPEN_ALL_SOURCES)\r\n                {\r\n                    // Since we know there must have been multiple errors here, just fail the context rather\r\n                    // than trying to get one of the exceptions back out.\r\n                    AICLI_TERMINATE_CONTEXT_RETURN(APPINSTALLER_CLI_ERROR_FAILED_TO_OPEN_ALL_SOURCES, {});\r\n                }\r\n                else\r\n                {\r\n                    throw;\r\n                }\r\n            }\r\n            catch (...)\r\n            {\r\n                context.Reporter.Error() << Resource::String::SourceOpenFailedSuggestion << std::endl;\r\n                throw;\r\n            }\r\n\r\n            return source;\r\n        }\r\n\r\n        void SearchSourceApplyFilters(Execution::Context& context, SearchRequest& searchRequest, MatchType matchType)\r\n        {\r\n            const auto& args = context.Args;\r\n\r\n            if (args.Contains(Execution::Args::Type::Id))\r\n            {\r\n                searchRequest.Filters.emplace_back(PackageMatchFilter(PackageMatchField::Id, matchType, args.GetArg(Execution::Args::Type::Id)));\r\n            }\r\n\r\n            if (args.Contains(Execution::Args::Type::Name))\r\n            {\r\n                searchRequest.Filters.emplace_back(PackageMatchFilter(PackageMatchField::Name, matchType, args.GetArg(Execution::Args::Type::Name)));\r\n            }\r\n\r\n            if (args.Contains(Execution::Args::Type::Moniker))\r\n            {\r\n                searchRequest.Filters.emplace_back(PackageMatchFilter(PackageMatchField::Moniker, matchType, args.GetArg(Execution::Args::Type::Moniker)));\r\n            }\r\n\r\n            if (args.Contains(Execution::Args::Type::ProductCode))\r\n            {\r\n                searchRequest.Filters.emplace_back(PackageMatchFilter(PackageMatchField::ProductCode, matchType, args.GetArg(Execution::Args::Type::ProductCode)));\r\n            }\r\n\r\n            if (args.Contains(Execution::Args::Type::Tag))\r\n            {\r\n                searchRequest.Filters.emplace_back(PackageMatchFilter(PackageMatchField::Tag, matchType, args.GetArg(Execution::Args::Type::Tag)));\r\n            }\r\n\r\n            if (args.Contains(Execution::Args::Type::Command))\r\n            {\r\n                searchRequest.Filters.emplace_back(PackageMatchFilter(PackageMatchField::Command, matchType, args.GetArg(Execution::Args::Type::Command)));\r\n            }\r\n\r\n            if (args.Contains(Execution::Args::Type::Count))\r\n            {\r\n                searchRequest.MaximumResults = std::stoi(std::string(args.GetArg(Execution::Args::Type::Count)));\r\n            }\r\n        }\r\n\r\n        // Data shown on a line of a table displaying installed packages\r\n        struct InstalledPackagesTableLine\r\n        {\r\n            InstalledPackagesTableLine(\r\n                std::shared_ptr<ICompositePackage> package,\r\n                std::shared_ptr<IPackageVersion> installedVersion,\r\n                const Utility::LocIndString& availableVersion,\r\n                const Utility::LocIndString& source)\r\n                : Package(std::move(package)), InstalledPackageVersion(std::move(installedVersion)), AvailableVersion(availableVersion), Source(source)\r\n            {\r\n                Name = InstalledPackageVersion->GetProperty(PackageVersionProperty::Name);\r\n                Id = Package->GetProperty(PackageProperty::Id);\r\n                InstalledVersion = InstalledPackageVersion->GetProperty(PackageVersionProperty::Version);\r\n            }\r\n\r\n            std::shared_ptr<ICompositePackage> Package;\r\n            std::shared_ptr<IPackageVersion> InstalledPackageVersion;\r\n\r\n            Utility::LocIndString Name;\r\n            Utility::LocIndString Id;\r\n            Utility::LocIndString InstalledVersion;\r\n            Utility::LocIndString AvailableVersion;\r\n            Utility::LocIndString Source;\r\n        };\r\n\r\n        void OutputInstalledPackagesTable(Execution::Context& context, std::vector<InstalledPackagesTableLine>& lines)\r\n        {\r\n            Execution::TableOutput<5> table(context.Reporter,\r\n                {\r\n                    Resource::String::SearchName,\r\n                    Resource::String::SearchId,\r\n                    Resource::String::SearchVersion,\r\n                    Resource::String::AvailableHeader,\r\n                    Resource::String::SearchSource\r\n                });\r\n\r\n            for (auto& line : lines)\r\n            {\r\n                table.OutputLine({\r\n                    line.Name,\r\n                    line.Id,\r\n                    line.InstalledVersion,\r\n                    line.AvailableVersion,\r\n                    line.Source\r\n                    });\r\n            }\r\n\r\n            table.Complete();\r\n        }\r\n\r\n        void ShowMetadataField(\r\n            Execution::OutputStream& outputStream,\r\n            StringResource::StringId label,\r\n            const IPackageVersion::Metadata& metadata,\r\n            PackageVersionMetadata field)\r\n        {\r\n            auto itr = metadata.find(field);\r\n            if (itr != metadata.end())\r\n            {\r\n                ShowSingleLineField(outputStream, label, Utility::LocIndView{ itr->second });\r\n            }\r\n        }\r\n\r\n        // Outputs every package \"line\" with many details, with a format similar to the `show` command.\r\n        void OutputInstalledPackagesDetails(Execution::Context& context, std::vector<InstalledPackagesTableLine>& lines)\r\n        {\r\n            auto info = context.Reporter.Info();\r\n            size_t packageIndex = 0;\r\n            size_t totalLines = lines.size();\r\n            bool shouldGetIcon = context.Reporter.SixelsEnabled();\r\n            for (const auto& line : lines)\r\n            {\r\n                // Identity header including package count indicator if multiple lines provided\r\n                if (totalLines > 1)\r\n                {\r\n                    info << '(' << ++packageIndex << '/' << totalLines << \") \"_liv;\r\n                }\r\n\r\n                ReportIdentity(context, {}, std::nullopt, line.Name, line.Id);\r\n\r\n                auto metadata = line.InstalledPackageVersion->GetMetadata();\r\n                auto productCodes = line.InstalledPackageVersion->GetMultiProperty(PackageVersionMultiProperty::ProductCode);\r\n\r\n                if (shouldGetIcon && !productCodes.empty())\r\n                {\r\n                    Manifest::ScopeEnum scope = Manifest::ScopeEnum::Unknown;\r\n\r\n                    auto itr = metadata.find(PackageVersionMetadata::InstalledScope);\r\n                    if (itr != metadata.end())\r\n                    {\r\n                        scope = Manifest::ConvertToScopeEnum(itr->second);\r\n                    }\r\n\r\n                    auto icons = ExtractIconFromArpEntry(productCodes[0], scope);\r\n                    ShowExtractedIcon(info, icons);\r\n                }\r\n\r\n                ShowSingleLineField(info, Resource::String::ShowLabelVersion, line.InstalledVersion);\r\n                ShowSingleLineField(info, Resource::String::ShowLabelChannel, line.InstalledPackageVersion->GetProperty(PackageVersionProperty::Channel));\r\n                ShowSingleLineField(info, Resource::String::ShowLabelPublisher, line.InstalledPackageVersion->GetProperty(PackageVersionProperty::Publisher));\r\n                auto localIdentifier = line.InstalledPackageVersion->GetProperty(PackageVersionProperty::Id);\r\n                if (line.Id != localIdentifier)\r\n                {\r\n                    ShowSingleLineField(info, Resource::String::ShowListLocalIdentifier, localIdentifier);\r\n                }\r\n\r\n                ShowMultiValueField(info, Resource::String::ShowListPackageFamilyName, line.InstalledPackageVersion->GetMultiProperty(PackageVersionMultiProperty::PackageFamilyName));\r\n                ShowMultiValueField(info, Resource::String::ShowListProductCode, productCodes);\r\n                ShowMultiValueField(info, Resource::String::ShowListUpgradeCode, line.InstalledPackageVersion->GetMultiProperty(PackageVersionMultiProperty::UpgradeCode));\r\n\r\n                ShowMetadataField(info, Resource::String::ShowListInstallerCategory, metadata, PackageVersionMetadata::InstalledType);\r\n                ShowMetadataField(info, Resource::String::ShowListInstalledScope, metadata, PackageVersionMetadata::InstalledScope);\r\n                ShowMetadataField(info, Resource::String::ShowListInstalledArchitecture, metadata, PackageVersionMetadata::InstalledArchitecture);\r\n                ShowMetadataField(info, Resource::String::ShowListInstalledLocale, metadata, PackageVersionMetadata::InstalledLocale);\r\n                ShowMetadataField(info, Resource::String::ShowListInstalledLocation, metadata, PackageVersionMetadata::InstalledLocation);\r\n\r\n                auto source = line.InstalledPackageVersion->GetSource();\r\n                if (source.ContainsAvailablePackages())\r\n                {\r\n                    ShowSingleLineField(info, Resource::String::ShowListInstalledSource, Utility::LocIndView{ source.GetDetails().Name });\r\n                }\r\n\r\n                Utility::Version currentVersion{ line.InstalledVersion };\r\n                bool hasUpgradeVersion = false;\r\n                for (const auto& available : line.Package->GetAvailable())\r\n                {\r\n                    auto latestAvailable = available->GetLatestVersion();\r\n                    auto availableVersion = latestAvailable->GetProperty(PackageVersionProperty::Version);\r\n                    if (Utility::Version{ availableVersion } > currentVersion)\r\n                    {\r\n                        if (!hasUpgradeVersion)\r\n                        {\r\n                            hasUpgradeVersion = true;\r\n                            info << details::GetIndentFor(0) << Execution::ManifestInfoEmphasis << Resource::String::ShowListAvailableUpgrades << '\\n';\r\n                        }\r\n\r\n                        info << details::GetIndentFor(1) << Utility::LocIndView{ available->GetSource().GetDetails().Name } <<\r\n                            \" [\"_liv << availableVersion << \"]\\n\"_liv;\r\n                    }\r\n                }\r\n\r\n                // FUTURE: We could also pull data from the tracking database to show some things that we store there specifically.\r\n            }\r\n        }\r\n\r\n        void OutputInstalledPackages(Execution::Context& context, std::vector<InstalledPackagesTableLine>& lines)\r\n        {\r\n            if (context.Args.Contains(Execution::Args::Type::ListDetails))\r\n            {\r\n                OutputInstalledPackagesDetails(context, lines);\r\n            }\r\n            else\r\n            {\r\n                OutputInstalledPackagesTable(context, lines);\r\n            }\r\n        }\r\n    }\r\n\r\n    bool WorkflowTask::operator==(const WorkflowTask& other) const\r\n    {\r\n        if (m_isFunc && other.m_isFunc)\r\n        {\r\n            return m_func == other.m_func;\r\n        }\r\n        else if (!m_isFunc && !other.m_isFunc)\r\n        {\r\n            return m_name == other.m_name;\r\n        }\r\n        else\r\n        {\r\n            return false;\r\n        }\r\n    }\r\n\r\n    void WorkflowTask::operator()(Execution::Context& context) const\r\n    {\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !m_isFunc);\r\n        m_func(context);\r\n    }\r\n\r\n    void WorkflowTask::Log() const\r\n    {\r\n        if (m_isFunc)\r\n        {\r\n            // Using `00000001`80000000` as base address default when loading dll into windbg as dump file.\r\n            AICLI_LOG(Workflow, Verbose, << \"Running task: 0x\" << m_func << \" [ln 00000001`80000000+\" << std::hex << (reinterpret_cast<char*>(m_func) - reinterpret_cast<char*>(&__ImageBase)) << \"]\");\r\n        }\r\n        else\r\n        {\r\n            AICLI_LOG(Workflow, Verbose, << \"Running task: \" << m_name);\r\n        }\r\n    }\r\n\r\n    Repository::PredefinedSource DetermineInstalledSource(const Execution::Context& context)\r\n    {\r\n        Repository::PredefinedSource installedSource = Repository::PredefinedSource::Installed;\r\n        Manifest::ScopeEnum scope = Manifest::ConvertToScopeEnum(context.Args.GetArg(Execution::Args::Type::InstallScope));\r\n        if (scope == Manifest::ScopeEnum::Machine)\r\n        {\r\n            installedSource = Repository::PredefinedSource::InstalledMachine;\r\n        }\r\n        else if (scope == Manifest::ScopeEnum::User)\r\n        {\r\n            installedSource = Repository::PredefinedSource::InstalledUser;\r\n        }\r\n\r\n        return installedSource;\r\n    }\r\n\r\n    Authentication::AuthenticationArguments GetAuthenticationArguments(const Execution::Context& context)\r\n    {\r\n        AppInstaller::Authentication::AuthenticationArguments authArgs;\r\n\r\n        if (context.Args.Contains(Execution::Args::Type::AuthenticationMode))\r\n        {\r\n            authArgs.Mode = Authentication::ConvertToAuthenticationMode(context.Args.GetArg(Execution::Args::Type::AuthenticationMode));\r\n        }\r\n        else\r\n        {\r\n            // If user did not specify authentication mode, determine based on if disable interactivity flag exists.\r\n            authArgs.Mode = context.Args.Contains(Execution::Args::Type::DisableInteractivity) ? Authentication::AuthenticationMode::Silent : Authentication::AuthenticationMode::SilentPreferred;\r\n        }\r\n\r\n        if (context.Args.Contains(Execution::Args::Type::AuthenticationAccount))\r\n        {\r\n            authArgs.AuthenticationAccount = context.Args.GetArg(Execution::Args::Type::AuthenticationAccount);\r\n        }\r\n\r\n        AICLI_LOG(CLI, Info, << \"Created authentication arguments. Mode: \" << Authentication::AuthenticationModeToString(authArgs.Mode) << \", Account: \" << authArgs.AuthenticationAccount);\r\n\r\n        return authArgs;\r\n    }\r\n\r\n    HRESULT HandleException(Execution::Context* context, std::exception_ptr exception)\r\n    {\r\n        try\r\n        {\r\n            std::rethrow_exception(exception);\r\n        }\r\n        // Exceptions that may occur in the process of executing an arbitrary command\r\n        catch (const wil::ResultException& re)\r\n        {\r\n            // Even though they are logged at their source, log again here for completeness.\r\n            Logging::Telemetry().LogException(Logging::FailureTypeEnum::ResultException, re.what());\r\n            if (context)\r\n            {\r\n                context->Reporter.Error() <<\r\n                    Resource::String::UnexpectedErrorExecutingCommand << ' ' << std::endl <<\r\n                    GetUserPresentableMessage(re) << std::endl;\r\n            }\r\n            return re.GetErrorCode();\r\n        }\r\n        catch (const winrt::hresult_error& hre)\r\n        {\r\n            std::string message = GetUserPresentableMessage(hre);\r\n            Logging::Telemetry().LogException(Logging::FailureTypeEnum::WinrtHResultError, message);\r\n            if (context)\r\n            {\r\n                context->Reporter.Error() <<\r\n                    Resource::String::UnexpectedErrorExecutingCommand << ' ' << std::endl <<\r\n                    message << std::endl;\r\n            }\r\n            return hre.code();\r\n        }\r\n        catch (const Settings::GroupPolicyException& e)\r\n        {\r\n            if (context)\r\n            {\r\n                auto policy = Settings::TogglePolicy::GetPolicy(e.Policy());\r\n                auto policyNameId = policy.PolicyName();\r\n                context->Reporter.Error() << Resource::String::DisabledByGroupPolicy(policyNameId) << std::endl;\r\n            }\r\n            return APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY;\r\n        }\r\n        catch (const std::exception& e)\r\n        {\r\n            Logging::Telemetry().LogException(Logging::FailureTypeEnum::StdException, e.what());\r\n            if (context)\r\n            {\r\n                context->Reporter.Error() <<\r\n                    Resource::String::UnexpectedErrorExecutingCommand << ' ' << std::endl <<\r\n                    GetUserPresentableMessage(e) << std::endl;\r\n            }\r\n            return APPINSTALLER_CLI_ERROR_COMMAND_FAILED;\r\n        }\r\n        catch (...)\r\n        {\r\n            LOG_CAUGHT_EXCEPTION();\r\n            Logging::Telemetry().LogException(Logging::FailureTypeEnum::Unknown, {});\r\n            if (context)\r\n            {\r\n                context->Reporter.Error() <<\r\n                    Resource::String::UnexpectedErrorExecutingCommand << \" ???\"_liv << std::endl;\r\n            }\r\n            return APPINSTALLER_CLI_ERROR_COMMAND_FAILED;\r\n        }\r\n\r\n        return E_UNEXPECTED;\r\n    }\r\n\r\n    HRESULT HandleException(Execution::Context& context, std::exception_ptr exception)\r\n    {\r\n        return HandleException(&context, exception);\r\n    }\r\n\r\n    AppInstaller::Manifest::ManifestComparator::Options GetManifestComparatorOptions(const Execution::Context& context, const IPackageVersion::Metadata& metadata)\r\n    {\r\n        AppInstaller::Manifest::ManifestComparator::Options options;\r\n        bool getAllowedArchitecturesFromMetadata = false;\r\n\r\n        if (context.Contains(Execution::Data::AllowedArchitectures))\r\n        {\r\n            // Com caller can directly set allowed architectures\r\n            options.AllowedArchitectures = context.Get<Execution::Data::AllowedArchitectures>();\r\n        }\r\n        else if (context.Args.Contains(Execution::Args::Type::InstallArchitecture))\r\n        {\r\n            // Arguments provided in command line\r\n            options.AllowedArchitectures.emplace_back(Utility::ConvertToArchitectureEnum(context.Args.GetArg(Execution::Args::Type::InstallArchitecture)));\r\n        }\r\n        else if (context.Args.Contains(Execution::Args::Type::InstallerArchitecture))\r\n        {\r\n            // Arguments provided in command line. Also skips applicability check.\r\n            options.AllowedArchitectures.emplace_back(Utility::ConvertToArchitectureEnum(context.Args.GetArg(Execution::Args::Type::InstallerArchitecture)));\r\n            options.SkipApplicabilityCheck = true;\r\n        }\r\n        else\r\n        {\r\n            getAllowedArchitecturesFromMetadata = true;\r\n        }\r\n\r\n        if (context.Args.Contains(Execution::Args::Type::InstallerType))\r\n        {\r\n            options.RequestedInstallerType = Manifest::ConvertToInstallerTypeEnum(std::string(context.Args.GetArg(Execution::Args::Type::InstallerType)));\r\n        }\r\n\r\n        if (context.Args.Contains(Execution::Args::Type::InstallScope))\r\n        {\r\n            options.RequestedInstallerScope = Manifest::ConvertToScopeEnum(context.Args.GetArg(Execution::Args::Type::InstallScope));\r\n        }\r\n\r\n        if (context.Contains(Execution::Data::AllowUnknownScope))\r\n        {\r\n            options.AllowUnknownScope = context.Get<Execution::Data::AllowUnknownScope>();\r\n        }\r\n\r\n        if (context.Args.Contains(Execution::Args::Type::Locale))\r\n        {\r\n            options.RequestedInstallerLocale = context.Args.GetArg(Execution::Args::Type::Locale);\r\n        }\r\n\r\n        Repository::GetManifestComparatorOptionsFromMetadata(options, metadata, getAllowedArchitecturesFromMetadata);\r\n\r\n        return options;\r\n    }\r\n\r\n    void OpenSource::operator()(Execution::Context& context) const\r\n    {\r\n        std::string_view sourceName;\r\n        if (m_forDependencies)\r\n        {\r\n            if (context.Args.Contains(Execution::Args::Type::DependencySource))\r\n            {\r\n                sourceName = context.Args.GetArg(Execution::Args::Type::DependencySource);\r\n            }\r\n        }\r\n        else\r\n        {\r\n            if (context.Args.Contains(Execution::Args::Type::Source))\r\n            {\r\n                sourceName = context.Args.GetArg(Execution::Args::Type::Source);\r\n            }\r\n        }\r\n\r\n        auto source = OpenNamedSource(context, Utility::LocIndView{ sourceName });\r\n        if (context.IsTerminated())\r\n        {\r\n            return;\r\n        }\r\n\r\n        context << HandleSourceAgreements(source);\r\n        if (context.IsTerminated())\r\n        {\r\n            return;\r\n        }\r\n\r\n        if (m_forDependencies)\r\n        {\r\n            context.Add<Execution::Data::DependencySource>(std::move(source));\r\n        }\r\n        else\r\n        {\r\n            context.Add<Execution::Data::Source>(std::move(source));\r\n        }\r\n    }\r\n\r\n    void OpenNamedSourceForSources::operator()(Execution::Context& context) const\r\n    {\r\n        auto source = OpenNamedSource(context, m_sourceName);\r\n        if (context.IsTerminated())\r\n        {\r\n            return;\r\n        }\r\n\r\n        context << HandleSourceAgreements(source);\r\n        if (context.IsTerminated())\r\n        {\r\n            return;\r\n        }\r\n\r\n        if (!context.Contains(Execution::Data::Sources))\r\n        {\r\n            context.Add<Execution::Data::Sources>({ std::move(source) });\r\n        }\r\n        else\r\n        {\r\n            context.Get<Execution::Data::Sources>().emplace_back(std::move(source));\r\n        }\r\n    }\r\n\r\n    void OpenPredefinedSource::operator()(Execution::Context& context) const\r\n    {\r\n        Repository::Source source;\r\n        try\r\n        {\r\n            source = Source{ m_predefinedSource };\r\n\r\n            // A well known predefined source should return a value.\r\n            THROW_HR_IF(E_UNEXPECTED, !source);\r\n\r\n            auto openFunction = [&](IProgressCallback& progress)->std::vector<Repository::SourceDetails>\r\n            {\r\n                return source.Open(progress);\r\n            };\r\n            context.Reporter.ExecuteWithProgress(openFunction, true);\r\n        }\r\n        catch (...)\r\n        {\r\n            context.Reporter.Error() << Resource::String::SourceOpenPredefinedFailedSuggestion << std::endl;\r\n            throw;\r\n        }\r\n\r\n        if (m_forDependencies)\r\n        {\r\n            context.Add<Execution::Data::DependencySource>(std::move(source));\r\n        }\r\n        else \r\n        {\r\n            context.Add<Execution::Data::Source>(std::move(source));\r\n        }\r\n    }\r\n\r\n    void OpenCompositeSource::operator()(Execution::Context& context) const\r\n    {\r\n        // Get the already open source for use as the available.\r\n        Repository::Source availableSource;\r\n        if (m_forDependencies)\r\n        {\r\n            availableSource = context.Get<Execution::Data::DependencySource>();\r\n        }\r\n        else\r\n        {\r\n            availableSource = context.Get<Execution::Data::Source>();\r\n        }\r\n\r\n        // Open the predefined source.\r\n        context << OpenPredefinedSource(m_predefinedSource, m_forDependencies);\r\n\r\n        // Create the composite source from the two.\r\n        Repository::Source source;\r\n        if (m_forDependencies)\r\n        {\r\n            source = context.Get<Execution::Data::DependencySource>();\r\n        }\r\n        else\r\n        {\r\n            source = context.Get<Execution::Data::Source>();\r\n        }\r\n\r\n        Repository::Source compositeSource{ source, availableSource, m_searchBehavior };\r\n\r\n        // Overwrite the source with the composite.\r\n        if (m_forDependencies)\r\n        {\r\n            context.Add<Execution::Data::DependencySource>(std::move(compositeSource));\r\n        }\r\n        else\r\n        {\r\n            context.Add<Execution::Data::Source>(std::move(compositeSource));\r\n        }\r\n    }\r\n\r\n    void SearchSourceForMany(Execution::Context& context)\r\n    {\r\n        const auto& args = context.Args;\r\n\r\n        MatchType matchType = MatchType::Substring;\r\n        if (args.Contains(Execution::Args::Type::Exact))\r\n        {\r\n            matchType = MatchType::Exact;\r\n        }\r\n\r\n        SearchRequest searchRequest;\r\n\r\n        if (args.Contains(Execution::Args::Type::Query))\r\n        {\r\n            searchRequest.Query.emplace(RequestMatch(matchType, args.GetArg(Execution::Args::Type::Query)));\r\n        }\r\n\r\n        SearchSourceApplyFilters(context, searchRequest, matchType);\r\n\r\n        Logging::Telemetry().LogSearchRequest(\r\n            \"many\",\r\n            args.GetArg(Execution::Args::Type::Query),\r\n            args.GetArg(Execution::Args::Type::Id),\r\n            args.GetArg(Execution::Args::Type::Name),\r\n            args.GetArg(Execution::Args::Type::Moniker),\r\n            args.GetArg(Execution::Args::Type::Tag),\r\n            args.GetArg(Execution::Args::Type::Command),\r\n            searchRequest.MaximumResults,\r\n            searchRequest.ToString());\r\n\r\n        context.Add<Execution::Data::SearchResult>(context.Get<Execution::Data::Source>().Search(searchRequest));\r\n    }\r\n\r\n    void GetSearchRequestForSingle(Execution::Context& context)\r\n    {\r\n        const auto& args = context.Args;\r\n\r\n        MatchType matchType = MatchType::CaseInsensitive;\r\n        if (args.Contains(Execution::Args::Type::Exact))\r\n        {\r\n            matchType = MatchType::Exact;\r\n        }\r\n\r\n        SearchRequest searchRequest;\r\n        // Note: MultiQuery when we need search for single is handled with one sub-context per query.\r\n        if (args.Contains(Execution::Args::Type::Query))\r\n        {\r\n            std::string_view query = args.GetArg(Execution::Args::Type::Query);\r\n\r\n            // Regardless of match type, always use an exact match for the system reference strings.\r\n            searchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::PackageFamilyName, MatchType::Exact, query));\r\n            searchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::ProductCode, MatchType::Exact, query));\r\n            searchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::Id, matchType, query));\r\n            searchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::Name, matchType, query));\r\n            searchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::Moniker, matchType, query));\r\n        }\r\n\r\n        SearchSourceApplyFilters(context, searchRequest, matchType);\r\n\r\n        context.Add<Execution::Data::SearchRequest>(std::move(searchRequest));\r\n    }\r\n\r\n    void SearchSourceForSingle(Execution::Context& context)\r\n    {\r\n        const auto& args = context.Args;\r\n        context << GetSearchRequestForSingle;\r\n        if (!context.IsTerminated())\r\n        {\r\n            const auto& searchRequest = context.Get<Execution::Data::SearchRequest>();\r\n\r\n            Logging::Telemetry().LogSearchRequest(\r\n                \"single\",\r\n                args.GetArg(Execution::Args::Type::Query),\r\n                args.GetArg(Execution::Args::Type::Id),\r\n                args.GetArg(Execution::Args::Type::Name),\r\n                args.GetArg(Execution::Args::Type::Moniker),\r\n                args.GetArg(Execution::Args::Type::Tag),\r\n                args.GetArg(Execution::Args::Type::Command),\r\n                searchRequest.MaximumResults,\r\n                searchRequest.ToString());\r\n\r\n            context.Add<Execution::Data::SearchResult>(context.Get<Execution::Data::Source>().Search(searchRequest));\r\n        }\r\n    }\r\n\r\n    void SearchSourceForManyCompletion(Execution::Context& context)\r\n    {\r\n        MatchType matchType = MatchType::StartsWith;\r\n\r\n        SearchRequest searchRequest;\r\n        std::string_view query = context.Get<Execution::Data::CompletionData>().Word();\r\n        searchRequest.Query.emplace(RequestMatch(matchType, query));\r\n\r\n        SearchSourceApplyFilters(context, searchRequest, matchType);\r\n\r\n        context.Add<Execution::Data::SearchResult>(context.Get<Execution::Data::Source>().Search(searchRequest));\r\n    }\r\n\r\n    void SearchSourceForSingleCompletion(Execution::Context& context)\r\n    {\r\n        MatchType matchType = MatchType::StartsWith;\r\n\r\n        SearchRequest searchRequest;\r\n        std::string_view query = context.Get<Execution::Data::CompletionData>().Word();\r\n        searchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::Id, matchType, query));\r\n        searchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::Name, matchType, query));\r\n        searchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::Moniker, matchType, query));\r\n\r\n        SearchSourceApplyFilters(context, searchRequest, matchType);\r\n\r\n        context.Add<Execution::Data::SearchResult>(context.Get<Execution::Data::Source>().Search(searchRequest));\r\n    }\r\n\r\n    void SearchSourceForCompletionField::operator()(Execution::Context& context) const\r\n    {\r\n        const std::string& word = context.Get<Execution::Data::CompletionData>().Word();\r\n\r\n        SearchRequest searchRequest;\r\n        searchRequest.Inclusions.emplace_back(PackageMatchFilter(m_field, MatchType::StartsWith, word));\r\n\r\n        // If filters are provided, be generous with the search no matter the intended result.\r\n        SearchSourceApplyFilters(context, searchRequest, MatchType::Substring);\r\n\r\n        context.Add<Execution::Data::SearchResult>(context.Get<Execution::Data::Source>().Search(searchRequest));\r\n    }\r\n\r\n    void ReportSearchResult(Execution::Context& context)\r\n    {\r\n        auto& searchResult = context.Get<Execution::Data::SearchResult>();\r\n\r\n        bool sourceIsComposite = context.Get<Execution::Data::Source>().IsComposite();\r\n        Execution::TableOutput<5> table(context.Reporter,\r\n            {\r\n                Resource::String::SearchName,\r\n                Resource::String::SearchId,\r\n                Resource::String::SearchVersion,\r\n                Resource::String::SearchMatch,\r\n                Resource::String::SearchSource\r\n            });\r\n\r\n        for (size_t i = 0; i < searchResult.Matches.size(); ++i)\r\n        {\r\n            auto latestVersion = GetAllAvailableVersions(searchResult.Matches[i].Package)->GetLatestVersion();\r\n\r\n            table.OutputLine({\r\n                latestVersion->GetProperty(PackageVersionProperty::Name),\r\n                latestVersion->GetProperty(PackageVersionProperty::Id),\r\n                latestVersion->GetProperty(PackageVersionProperty::Version),\r\n                GetMatchCriteriaDescriptor(searchResult.Matches[i]),\r\n                sourceIsComposite ? static_cast<std::string>(latestVersion->GetProperty(PackageVersionProperty::SourceName)) : \"\"s\r\n                });\r\n        }\r\n\r\n        table.Complete();\r\n\r\n        if (searchResult.Truncated)\r\n        {\r\n            context.Reporter.Info() << '<' << Resource::String::SearchTruncated << '>' << std::endl;\r\n        }\r\n    }\r\n\r\n    void HandleSearchResultFailures(Execution::Context& context)\r\n    {\r\n        const auto& searchResult = context.Get<Execution::Data::SearchResult>();\r\n\r\n        if (!searchResult.Failures.empty())\r\n        {\r\n            if (WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::TreatSourceFailuresAsWarning))\r\n            {\r\n                auto warn = context.Reporter.Warn();\r\n                for (const auto& failure : searchResult.Failures)\r\n                {\r\n                    warn << Resource::String::SearchFailureWarning(Utility::LocIndView{ failure.SourceName }) << std::endl;\r\n                }\r\n            }\r\n            else\r\n            {\r\n                HRESULT overallHR = S_OK;\r\n                auto error = context.Reporter.Error();\r\n                for (const auto& failure : searchResult.Failures)\r\n                {\r\n                    error << Resource::String::SearchFailureError(Utility::LocIndView{ failure.SourceName }) << std::endl;\r\n                    HRESULT failureHR = HandleException(context, failure.Exception);\r\n\r\n                    // Just take first failure for now\r\n                    if (overallHR == S_OK)\r\n                    {\r\n                        overallHR = failureHR;\r\n                    }\r\n                }\r\n\r\n                if (WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::ShowSearchResultsOnPartialFailure))\r\n                {\r\n                    if (searchResult.Matches.empty())\r\n                    {\r\n                        context.Reporter.Info() << std::endl << Resource::String::SearchFailureErrorNoMatches << std::endl;\r\n                    }\r\n                    else\r\n                    {\r\n                        context.Reporter.Info() << std::endl << Resource::String::SearchFailureErrorListMatches << std::endl;\r\n                        context << ReportMultiplePackageFoundResultWithSource;\r\n                    }\r\n                }\r\n\r\n                context.SetTerminationHR(overallHR);\r\n            }\r\n        }\r\n    }\r\n\r\n    void ReportMultiplePackageFoundResult(Execution::Context& context)\r\n    {\r\n        auto& searchResult = context.Get<Execution::Data::SearchResult>();\r\n\r\n        Execution::TableOutput<2> table(context.Reporter,\r\n            {\r\n                Resource::String::SearchName,\r\n                Resource::String::SearchId\r\n            });\r\n\r\n        for (size_t i = 0; i < searchResult.Matches.size(); ++i)\r\n        {\r\n            auto package = searchResult.Matches[i].Package;\r\n\r\n            table.OutputLine({\r\n                package->GetProperty(PackageProperty::Name),\r\n                package->GetProperty(PackageProperty::Id)\r\n                });\r\n        }\r\n\r\n        table.Complete();\r\n\r\n        if (searchResult.Truncated)\r\n        {\r\n            context.Reporter.Info() << '<' << Resource::String::SearchTruncated << '>' << std::endl;\r\n        }\r\n    }\r\n\r\n    void ReportMultiplePackageFoundResultWithSource(Execution::Context& context)\r\n    {\r\n        auto& searchResult = context.Get<Execution::Data::SearchResult>();\r\n\r\n        Execution::TableOutput<3> table(context.Reporter,\r\n            {\r\n                Resource::String::SearchName,\r\n                Resource::String::SearchId,\r\n                Resource::String::SearchSource\r\n            });\r\n\r\n        for (size_t i = 0; i < searchResult.Matches.size(); ++i)\r\n        {\r\n            auto package = searchResult.Matches[i].Package;\r\n\r\n            std::string sourceName;\r\n            auto available = package->GetAvailable();\r\n            if (!available.empty())\r\n            {\r\n                auto source = available[0]->GetSource();\r\n                if (source)\r\n                {\r\n                    sourceName = source.GetDetails().Name;\r\n                }\r\n            }\r\n\r\n            table.OutputLine({\r\n                package->GetProperty(PackageProperty::Name),\r\n                package->GetProperty(PackageProperty::Id),\r\n                std::move(sourceName)\r\n                });\r\n        }\r\n\r\n        table.Complete();\r\n\r\n        if (searchResult.Truncated)\r\n        {\r\n            context.Reporter.Info() << '<' << Resource::String::SearchTruncated << '>' << std::endl;\r\n        }\r\n    }\r\n\r\n    void ReportListResult::operator()(Execution::Context& context) const\r\n    {\r\n        auto& searchResult = context.Get<Execution::Data::SearchResult>();\r\n\r\n        std::vector<InstalledPackagesTableLine> lines;\r\n        std::vector<InstalledPackagesTableLine> linesForExplicitUpgrade;\r\n        std::vector<InstalledPackagesTableLine> linesForPins;\r\n\r\n        int availableUpgradesCount = 0;\r\n\r\n        // We will show a line with a summary for skipped and pinned packages at the end.\r\n        // The strings suggest using a --include-unknown/pinned argument, so we should\r\n        // ensure that the count is 0 when using the arguments.\r\n        int packagesWithUnknownVersionSkipped = 0;\r\n        int packagesWithUserPinsSkipped = 0;\r\n\r\n        auto &source = context.Get<Execution::Data::Source>();\r\n        bool shouldShowSource = source.IsComposite() && source.GetAvailableSources().size() > 1;\r\n\r\n        PinBehavior pinBehavior;\r\n        if (m_onlyShowUpgrades && !context.Args.Contains(Execution::Args::Type::Force))\r\n        {\r\n            // For listing upgrades, show the version we would upgrade to with the given pins.\r\n            pinBehavior = context.Args.Contains(Execution::Args::Type::IncludePinned) ? PinBehavior::IncludePinned : PinBehavior::ConsiderPins;\r\n        }\r\n        else\r\n        {\r\n            // For listing installed apps or if we are ignoring pins due to --force, show the latest available.\r\n            pinBehavior = PinBehavior::IgnorePins;\r\n        }\r\n\r\n        PinningData pinningData{ PinningData::Disposition::ReadOnly };\r\n\r\n        for (const auto& match : searchResult.Matches)\r\n        {\r\n            auto installedPackage = match.Package->GetInstalled();\r\n            if (!installedPackage)\r\n            {\r\n                continue;\r\n            }\r\n\r\n            // We only want to evaluate update availability for the latest version.\r\n            bool isFirstInstalledVersion = true;\r\n\r\n            for (const auto& installedVersionKey : installedPackage->GetVersionKeys())\r\n            {\r\n                bool isFirstInstalledVersionLocal = isFirstInstalledVersion;\r\n                isFirstInstalledVersion = false;\r\n\r\n                auto installedVersion = installedPackage->GetVersion(installedVersionKey);\r\n\r\n                auto evaluator = pinningData.CreatePinStateEvaluator(pinBehavior, installedVersion);\r\n                auto availableVersions = GetAvailableVersionsForInstalledVersion(match.Package, installedVersion);\r\n\r\n                auto latestVersion = evaluator.GetLatestAvailableVersionForPins(availableVersions);\r\n                bool updateAvailable = isFirstInstalledVersionLocal && evaluator.IsUpdate(latestVersion);\r\n                bool updateIsPinned = false;\r\n\r\n                if (m_onlyShowUpgrades && !context.Args.Contains(Execution::Args::Type::IncludeUnknown) && Utility::Version(installedVersion->GetProperty(PackageVersionProperty::Version)).IsUnknown() && updateAvailable)\r\n                {\r\n                    // We are only showing upgrades, and the user did not request to include packages with unknown versions.\r\n                    ++packagesWithUnknownVersionSkipped;\r\n                    continue;\r\n                }\r\n\r\n                if (m_onlyShowUpgrades && !updateAvailable && isFirstInstalledVersionLocal)\r\n                {\r\n                    // Reuse the evaluator to check if there is an update outside of the pinning\r\n                    auto unpinnedLatestVersion = availableVersions->GetLatestVersion();\r\n                    bool updateAvailableWithoutPins = evaluator.IsUpdate(unpinnedLatestVersion);\r\n\r\n                    if (updateAvailableWithoutPins)\r\n                    {\r\n                        // When given the --include-pinned argument, report blocking and gating pins in a separate table.\r\n                        // Otherwise, simply show a count of them\r\n                        if (context.Args.Contains(Execution::Args::Type::IncludePinned))\r\n                        {\r\n                            updateIsPinned = true;\r\n\r\n                            // Override these so we generate the table line below.\r\n                            latestVersion = std::move(unpinnedLatestVersion);\r\n                            updateAvailable = true;\r\n                        }\r\n                        else\r\n                        {\r\n                            ++packagesWithUserPinsSkipped;\r\n                            continue;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                // The only time we don't want to output a line is when filtering and no update is available.\r\n                if (updateAvailable || !m_onlyShowUpgrades)\r\n                {\r\n                    Utility::LocIndString availableVersion, sourceName;\r\n\r\n                    if (latestVersion)\r\n                    {\r\n                        // Always show the source for correlated packages\r\n                        sourceName = latestVersion->GetProperty(PackageVersionProperty::SourceName);\r\n\r\n                        if (updateAvailable)\r\n                        {\r\n                            availableVersion = latestVersion->GetProperty(PackageVersionProperty::Version);\r\n                            availableUpgradesCount++;\r\n                        }\r\n                    }\r\n\r\n                    // Output using the local PackageName instead of the name in the manifest, to prevent confusion for packages that add multiple\r\n                    // Add/Remove Programs entries.\r\n                    // TODO: De-duplicate this list, and only show (by default) one entry per matched package.\r\n                    InstalledPackagesTableLine line(\r\n                         match.Package,\r\n                         installedVersion,\r\n                         availableVersion,\r\n                         shouldShowSource ? sourceName : Utility::LocIndString()\r\n                    );\r\n\r\n                    auto pinnedState = ConvertToPinTypeEnum(installedVersion->GetMetadata()[PackageVersionMetadata::PinnedState]);\r\n                    if (updateIsPinned)\r\n                    {\r\n                        linesForPins.push_back(std::move(line));\r\n                    }\r\n                    else if (m_onlyShowUpgrades && pinnedState == PinType::PinnedByManifest)\r\n                    {\r\n                        linesForExplicitUpgrade.push_back(std::move(line));\r\n                    }\r\n                    else\r\n                    {\r\n                        lines.push_back(std::move(line));\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        OutputInstalledPackages(context, lines);\r\n\r\n        if (lines.empty())\r\n        {\r\n            context.Reporter.Info() << Resource::String::NoInstalledPackageFound << std::endl;\r\n        }\r\n        else\r\n        {\r\n            if (searchResult.Truncated)\r\n            {\r\n                context.Reporter.Info() << '<' << Resource::String::SearchTruncated << '>' << std::endl;\r\n            }\r\n\r\n            if (m_onlyShowUpgrades)\r\n            {\r\n                context.Reporter.Info() << Resource::String::AvailableUpgrades(availableUpgradesCount) << std::endl;\r\n            }\r\n        }\r\n\r\n        if (!linesForExplicitUpgrade.empty())\r\n        {\r\n            context.Reporter.Info() << std::endl << Resource::String::UpgradeAvailableForPinned << std::endl;\r\n            OutputInstalledPackages(context, linesForExplicitUpgrade);\r\n        }\r\n\r\n        if (!linesForPins.empty())\r\n        {\r\n            context.Reporter.Info() << std::endl << Resource::String::UpgradeBlockedByPinCount(linesForPins.size()) << std::endl;\r\n            OutputInstalledPackages(context, linesForPins);\r\n        }\r\n\r\n        if (m_onlyShowUpgrades)\r\n        {\r\n            if (packagesWithUnknownVersionSkipped > 0)\r\n            {\r\n                AICLI_LOG(CLI, Info, << packagesWithUnknownVersionSkipped << \" package(s) skipped due to unknown installed version\");\r\n                context.Reporter.Info() << Resource::String::UpgradeUnknownVersionCount(packagesWithUnknownVersionSkipped) << std::endl;\r\n            }\r\n\r\n            if (packagesWithUserPinsSkipped > 0)\r\n            {\r\n                AICLI_LOG(CLI, Info, << packagesWithUserPinsSkipped << \" package(s) skipped due to user pins\");\r\n                context.Reporter.Info() << Resource::String::UpgradePinnedByUserCount(packagesWithUserPinsSkipped) << std::endl;\r\n            }\r\n        }\r\n    }\r\n\r\n    void EnsureMatchesFromSearchResult::operator()(Execution::Context& context) const\r\n    {\r\n        auto& searchResult = context.Get<Execution::Data::SearchResult>();\r\n\r\n        Logging::Telemetry().LogSearchResultCount(searchResult.Matches.size());\r\n\r\n        if (searchResult.Matches.size() == 0)\r\n        {\r\n            Logging::Telemetry().LogNoAppMatch();\r\n            \r\n            switch (m_operationType)\r\n            {\r\n                // These search purposes require a package to be found in the Installed Packages\r\n                case OperationType::Export:\r\n                case OperationType::List:\r\n                case OperationType::Uninstall:\r\n                case OperationType::Pin:\r\n                case OperationType::Upgrade:\r\n                case OperationType::Repair:\r\n                    context.Reporter.Info() << Resource::String::NoInstalledPackageFound << std::endl;\r\n                    break;\r\n                case OperationType::Completion:\r\n                case OperationType::Install:\r\n                case OperationType::Search:\r\n                case OperationType::Show:\r\n                case OperationType::Download:\r\n                default:\r\n                    context.Reporter.Info() << Resource::String::NoPackageFound << std::endl;\r\n                    break;\r\n            }\r\n\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_NO_APPLICATIONS_FOUND);\r\n        }\r\n    }\r\n\r\n    void EnsureOneMatchFromSearchResult::operator()(Execution::Context& context) const\r\n    {\r\n        context <<\r\n            EnsureMatchesFromSearchResult(m_operationType);\r\n\r\n        if (!context.IsTerminated())\r\n        {\r\n            auto& searchResult = context.Get<Execution::Data::SearchResult>();\r\n\r\n            bool operationTargetsInstalled = m_operationType == OperationType::Upgrade || m_operationType == OperationType::Uninstall ||\r\n                m_operationType == OperationType::Repair || m_operationType == OperationType::Export;\r\n\r\n            // Try limiting results to highest priority sources\r\n            if (searchResult.Matches.size() > 1 && !operationTargetsInstalled &&\r\n                ExperimentalFeature::IsEnabled(ExperimentalFeature::Feature::SourcePriority))\r\n            {\r\n                // Find the set of matches that have the highest priority\r\n                std::vector<ResultMatch> highestPriorityMatches;\r\n                std::optional<int32_t> highestPriority;\r\n\r\n                for (const auto& match : searchResult.Matches)\r\n                {\r\n                    std::optional<int32_t> priority = GetSourcePriority(match.Package);\r\n\r\n                    // Optional provides overloads that make empty less than valued and empties equal.\r\n                    if (highestPriority < priority)\r\n                    {\r\n                        // Current priority is higher; reset.\r\n                        highestPriority = priority;\r\n                        highestPriorityMatches.clear();\r\n                    }\r\n                    else if (highestPriority == priority)\r\n                    {\r\n                        // Priority is equal, add to the list.\r\n                    }\r\n                    else\r\n                    {\r\n                        // Current priority is lower, ignore the match.\r\n                        continue;\r\n                    }\r\n\r\n                    highestPriorityMatches.emplace_back(match);\r\n                }\r\n\r\n                if (highestPriorityMatches.size() < searchResult.Matches.size())\r\n                {\r\n                    AICLI_LOG(CLI, Info, << \"Replacing search results with only those from the highest priority [\" << (highestPriority ? std::to_string(highestPriority.value()) : \"none\"s) << \"].\");\r\n                    searchResult.Matches = std::move(highestPriorityMatches);\r\n                    context.Reporter.Warn() << Resource::String::MultiplePackagesFoundFilteredBySourcePriority << std::endl;\r\n                }\r\n            }\r\n\r\n            if (searchResult.Matches.size() > 1)\r\n            {\r\n                Logging::Telemetry().LogMultiAppMatch();\r\n\r\n                if (operationTargetsInstalled)\r\n                {\r\n                    context.Reporter.Warn() << Resource::String::MultipleInstalledPackagesFound << std::endl;\r\n                    context << ReportMultiplePackageFoundResult;\r\n                }\r\n                else\r\n                {\r\n                    context.Reporter.Warn() << Resource::String::MultiplePackagesFound << std::endl;\r\n                    context << ReportMultiplePackageFoundResultWithSource;\r\n                }\r\n\r\n                AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_MULTIPLE_APPLICATIONS_FOUND);\r\n            }\r\n\r\n            std::shared_ptr<ICompositePackage> package = searchResult.Matches.at(0).Package;\r\n            Logging::Telemetry().LogAppFound(package->GetProperty(PackageProperty::Name), package->GetProperty(PackageProperty::Id));\r\n\r\n            context.Add<Execution::Data::Package>(std::move(package));\r\n        }\r\n    }\r\n\r\n    void GetManifestWithVersionFromPackage::operator()(Execution::Context& context) const\r\n    {\r\n        PackageVersionKey key(\"\", m_version, m_channel);\r\n\r\n        std::shared_ptr<ICompositePackage> package = context.Get<Execution::Data::Package>();\r\n        std::shared_ptr<IPackageVersion> requestedVersion;\r\n        auto availableVersions = GetAvailableVersionsForInstalledVersion(package);\r\n\r\n        if (m_considerPins)\r\n        {\r\n            bool isPinned = false;\r\n\r\n            PinBehavior pinBehavior;\r\n            if (context.Args.Contains(Execution::Args::Type::Force))\r\n            {\r\n                // --force ignores any pins\r\n                pinBehavior = PinBehavior::IgnorePins;\r\n            }\r\n            else\r\n            {\r\n                pinBehavior = context.Args.Contains(Execution::Args::Type::IncludePinned) ? PinBehavior::IncludePinned : PinBehavior::ConsiderPins;\r\n            }\r\n\r\n            PinningData pinningData{ PinningData::Disposition::ReadOnly };\r\n            auto evaluator = pinningData.CreatePinStateEvaluator(pinBehavior, GetInstalledVersion(package));\r\n\r\n            // TODO: The logic here will probably have to get more difficult once we support channels\r\n            if (Utility::IsEmptyOrWhitespace(m_version) && Utility::IsEmptyOrWhitespace(m_channel))\r\n            {\r\n                requestedVersion = evaluator.GetLatestAvailableVersionForPins(availableVersions);\r\n\r\n                if (!requestedVersion)\r\n                {\r\n                    // Check whether we didn't find the latest version because it was pinned or because there wasn't one\r\n                    auto latestVersion = availableVersions->GetLatestVersion();\r\n                    if (latestVersion)\r\n                    {\r\n                        isPinned = true;\r\n                    }\r\n                }\r\n            }\r\n            else\r\n            {\r\n                requestedVersion = availableVersions->GetVersion(key);\r\n                isPinned = evaluator.EvaluatePinType(requestedVersion) != PinType::Unknown;\r\n            }\r\n\r\n            if (isPinned)\r\n            {\r\n                if (context.Args.Contains(Execution::Args::Type::Force))\r\n                {\r\n                    AICLI_LOG(CLI, Info, << \"Ignoring pin on package due to --force argument\");\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(CLI, Error, << \"The requested package version is unavailable because of a pin\");\r\n                    context.Reporter.Error() << Resource::String::PackageIsPinned << std::endl;\r\n                    AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_PACKAGE_IS_PINNED);\r\n                }\r\n            }\r\n        }\r\n        else\r\n        {\r\n            // The simple case: Just look up the requested version\r\n            requestedVersion = availableVersions->GetVersion(key);\r\n        }\r\n\r\n        std::optional<Manifest::Manifest> manifest;\r\n        if (requestedVersion)\r\n        {\r\n            manifest = requestedVersion->GetManifest();\r\n        }\r\n\r\n        if (!manifest)\r\n        {\r\n            std::ostringstream ssVersionInfo;\r\n            if (!m_version.empty())\r\n            {\r\n                ssVersionInfo << m_version;\r\n            }\r\n            if (!m_channel.empty())\r\n            {\r\n                ssVersionInfo << '[' << m_channel << ']';\r\n            }\r\n\r\n            context.Reporter.Error() << Resource::String::GetManifestResultVersionNotFound(Utility::LocIndView{ ssVersionInfo.str()}) << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_NO_MANIFEST_FOUND);\r\n        }\r\n\r\n        Logging::Telemetry().LogManifestFields(manifest->Id, manifest->DefaultLocalization.Get<Manifest::Localization::PackageName>(), manifest->Version);\r\n\r\n        std::string targetLocale;\r\n        if (context.Args.Contains(Execution::Args::Type::Locale))\r\n        {\r\n            targetLocale = context.Args.GetArg(Execution::Args::Type::Locale);\r\n        }\r\n        manifest->ApplyLocale(targetLocale);\r\n\r\n        context.Add<Execution::Data::Manifest>(std::move(manifest.value()));\r\n        context.Add<Execution::Data::PackageVersion>(std::move(requestedVersion));\r\n    }\r\n\r\n    void GetManifestFromPackage::operator()(Execution::Context& context) const\r\n    {\r\n        context << GetManifestWithVersionFromPackage(\r\n            context.Args.GetArg(Execution::Args::Type::Version),\r\n            context.Args.GetArg(Execution::Args::Type::Channel),\r\n            m_considerPins);\r\n    }\r\n\r\n    void VerifyFile::operator()(Execution::Context& context) const\r\n    {\r\n        std::filesystem::path path = Utility::ConvertToUTF16(context.Args.GetArg(m_arg));\r\n\r\n        if (!std::filesystem::exists(path))\r\n        {\r\n            context.Reporter.Error() << Resource::String::VerifyFileFailedNotExist(Utility::LocIndView{ path.u8string() }) << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));\r\n        }\r\n\r\n        if (std::filesystem::is_directory(path))\r\n        {\r\n            context.Reporter.Error() << Resource::String::VerifyFileFailedIsDirectory(Utility::LocIndView{ path.u8string() }) << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(HRESULT_FROM_WIN32(ERROR_DIRECTORY_NOT_SUPPORTED));\r\n        }\r\n    }\r\n\r\n    void VerifyPath::operator()(Execution::Context& context) const\r\n    {\r\n        std::filesystem::path path = Utility::ConvertToUTF16(context.Args.GetArg(m_arg));\r\n\r\n        if (!std::filesystem::exists(path))\r\n        {\r\n            context.Reporter.Error() << Resource::String::VerifyPathFailedNotExist(Utility::LocIndView{ path.u8string() }) << std::endl;\r\n            AICLI_TERMINATE_CONTEXT(HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND));\r\n        }\r\n    }\r\n\r\n    void VerifyFileOrUri::operator()(Execution::Context& context) const\r\n    {\r\n        // Argument requirement is handled elsewhere.\r\n        if (!context.Args.Contains(m_arg))\r\n        {\r\n            return;\r\n        }\r\n\r\n        auto path = context.Args.GetArg(m_arg);\r\n\r\n        // try uri first\r\n        Uri pathAsUri = nullptr;\r\n        try\r\n        {\r\n            pathAsUri = Uri{ Utility::ConvertToUTF16(path) };\r\n        }\r\n        catch (...) {}\r\n\r\n        if (pathAsUri)\r\n        {\r\n            if (pathAsUri.Suspicious())\r\n            {\r\n                context.Reporter.Error() << Resource::String::UriNotWellFormed(Utility::LocIndView{ path }) << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED));\r\n            }\r\n            // SchemeName() always returns lower case\r\n            else if (L\"file\" == pathAsUri.SchemeName() && !Utility::CaseInsensitiveStartsWith(path, \"file:\"))\r\n            {\r\n                // Uri constructor is smart enough to parse an absolute local file path to file uri.\r\n                // In this case, we should continue with VerifyFile.\r\n                context << VerifyFile(m_arg);\r\n            }\r\n            else if (std::find(m_supportedSchemes.begin(), m_supportedSchemes.end(), pathAsUri.SchemeName()) != m_supportedSchemes.end())\r\n            {\r\n                // Scheme supported.\r\n                return;\r\n            }\r\n            else\r\n            {\r\n                context.Reporter.Error() << Resource::String::UriSchemeNotSupported(Utility::LocIndView{ path }) << std::endl;\r\n                AICLI_TERMINATE_CONTEXT(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED));\r\n            }\r\n        }\r\n        else\r\n        {\r\n            context << VerifyFile(m_arg);\r\n        }\r\n    }\r\n\r\n    void GetManifestFromArg(Execution::Context& context)\r\n    {\r\n        Logging::Telemetry().LogIsManifestLocal(true);\r\n\r\n        context <<\r\n            VerifyPath(Execution::Args::Type::Manifest) <<\r\n            [](Execution::Context& context)\r\n        {\r\n            Manifest::Manifest manifest = Manifest::YamlParser::CreateFromPath(Utility::ConvertToUTF16(context.Args.GetArg(Execution::Args::Type::Manifest)));\r\n            Logging::Telemetry().LogManifestFields(manifest.Id, manifest.DefaultLocalization.Get<Manifest::Localization::PackageName>(), manifest.Version);\r\n\r\n            std::string targetLocale;\r\n            if (context.Args.Contains(Execution::Args::Type::Locale))\r\n            {\r\n                targetLocale = context.Args.GetArg(Execution::Args::Type::Locale);\r\n            }\r\n            manifest.ApplyLocale(targetLocale);\r\n\r\n            context.Add<Execution::Data::Manifest>(std::move(manifest));\r\n        };\r\n    }\r\n\r\n    void ReportPackageIdentity(Execution::Context& context)\r\n    {\r\n        auto package = context.Get<Execution::Data::Package>();\r\n        ReportIdentity(context, {}, Resource::String::ReportIdentityFound, package->GetProperty(PackageProperty::Name), package->GetProperty(PackageProperty::Id));\r\n    }\r\n\r\n    void ReportInstalledPackageVersionIdentity(Execution::Context& context)\r\n    {\r\n        auto package = context.Get<Execution::Data::Package>();\r\n        auto version = context.Get<Execution::Data::InstalledPackageVersion>();\r\n        ReportIdentity(context, {}, Resource::String::ReportIdentityFound, version->GetProperty(PackageVersionProperty::Name), package ? package->GetProperty(PackageProperty::Id) : version->GetProperty(PackageVersionProperty::Id));\r\n    }\r\n\r\n    void ReportManifestIdentity(Execution::Context& context)\r\n    {\r\n        const auto& manifest = context.Get<Execution::Data::Manifest>();\r\n        ReportIdentity(context, {}, Resource::String::ReportIdentityFound, manifest.CurrentLocalization.Get<Manifest::Localization::PackageName>(), manifest.Id);\r\n        ShowManifestIcon(context, manifest);\r\n    }\r\n\r\n    void ReportManifestIdentityWithVersion::operator()(Execution::Context& context) const\r\n    {\r\n        const auto& manifest = context.Get<Execution::Data::Manifest>();\r\n        ReportIdentity(context, m_prefix, m_label, manifest.CurrentLocalization.Get<Manifest::Localization::PackageName>(), manifest.Id, manifest.Version, m_level);\r\n        ShowManifestIcon(context, manifest);\r\n    }\r\n\r\n    void SelectInstaller(Execution::Context& context)\r\n    {\r\n        bool isUpdate = WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::InstallerExecutionUseUpdate);\r\n        bool isRepair = WI_IsFlagSet(context.GetFlags(), Execution::ContextFlag::InstallerExecutionUseRepair);\r\n\r\n        IPackageVersion::Metadata installationMetadata;\r\n\r\n        if (isUpdate || isRepair)\r\n        {\r\n            installationMetadata = context.Get<Execution::Data::InstalledPackageVersion>()->GetMetadata();\r\n        }\r\n\r\n        Manifest::ManifestComparator manifestComparator(GetManifestComparatorOptions(context, installationMetadata));\r\n        auto [installer, inapplicabilities] = manifestComparator.GetPreferredInstaller(context.Get<Execution::Data::Manifest>());\r\n\r\n        if (!installer.has_value())\r\n        {\r\n            auto onlyInstalledType = std::find(inapplicabilities.begin(), inapplicabilities.end(), Manifest::InapplicabilityFlags::InstalledType);\r\n            if (onlyInstalledType != inapplicabilities.end())\r\n            {\r\n                if (isRepair)\r\n                {\r\n                    context.Reporter.Info() << Resource::String::RepairDifferentInstallTechnology << std::endl;\r\n                    AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_REPAIR_NOT_APPLICABLE);\r\n                }\r\n                else\r\n                {\r\n                    context.Reporter.Info() << Resource::String::UpgradeDifferentInstallTechnology << std::endl;\r\n                    AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (installer.has_value())\r\n        {\r\n            Logging::Telemetry().LogSelectedInstaller(\r\n                static_cast<int>(installer->Arch),\r\n                installer->Url,\r\n                Manifest::InstallerTypeToString(installer->EffectiveInstallerType()),\r\n                Manifest::ScopeToString(installer->Scope),\r\n                installer->Locale);\r\n        }\r\n\r\n        context.Add<Execution::Data::Installer>(installer);\r\n    }\r\n\r\n    void EnsureRunningAsAdmin(Execution::Context& context)\r\n    {\r\n        if (!Runtime::IsRunningAsAdmin())\r\n        {\r\n            context.Reporter.Error() << Resource::String::CommandRequiresAdmin;\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_COMMAND_REQUIRES_ADMIN);\r\n        }\r\n    }\r\n\r\n    void EnsureFeatureEnabled::operator()(Execution::Context& context) const\r\n    {\r\n        if (!Settings::ExperimentalFeature::IsEnabled(m_feature))\r\n        {\r\n            context.Reporter.Error()\r\n                << Resource::String::FeatureDisabledMessage(Utility::LocIndView{ Settings::ExperimentalFeature::GetFeature(m_feature).JsonName() })\r\n                << std::endl;\r\n            AICLI_LOG(CLI, Error, << Settings::ExperimentalFeature::GetFeature(m_feature).Name() << \" feature is disabled. Execution cancelled.\");\r\n            AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_EXPERIMENTAL_FEATURE_DISABLED);\r\n        }\r\n    }\r\n\r\n    void SearchSourceUsingManifest(Execution::Context& context)\r\n    {\r\n        const auto& manifest = context.Get<Execution::Data::Manifest>();\r\n        auto source = context.Get<Execution::Data::Source>();\r\n\r\n        // First try search using ProductId or PackageFamilyName\r\n        for (const auto& installer : manifest.Installers)\r\n        {\r\n            SearchRequest searchRequest;\r\n            if (!installer.PackageFamilyName.empty())\r\n            {\r\n                searchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::PackageFamilyName, MatchType::Exact, installer.PackageFamilyName));\r\n            }\r\n            else if (!installer.ProductCode.empty())\r\n            {\r\n                searchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::ProductCode, MatchType::Exact, installer.ProductCode));\r\n            }\r\n            else if (installer.EffectiveInstallerType() == Manifest::InstallerTypeEnum::Portable)\r\n            {\r\n                const auto& productCode = Utility::MakeSuitablePathPart(manifest.Id + '_' + source.GetIdentifier());\r\n                searchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::ProductCode, MatchType::CaseInsensitive, Utility::Normalize(productCode)));\r\n            }\r\n            else if (installer.EffectiveInstallerType() == Manifest::InstallerTypeEnum::Font)\r\n            {\r\n                // Font Packages match by Package Id first.\r\n                searchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::Id, MatchType::CaseInsensitive, manifest.Id));\r\n            }\r\n\r\n            if (!searchRequest.Inclusions.empty())\r\n            {\r\n                auto searchResult = source.Search(searchRequest);\r\n\r\n                if (!searchResult.Matches.empty())\r\n                {\r\n                    context.Add<Execution::Data::SearchResult>(std::move(searchResult));\r\n                    return;\r\n                }\r\n            }\r\n        }\r\n\r\n        // If we cannot find a package using PackageFamilyName or ProductId, try manifest Id and Name pair\r\n        SearchRequest searchRequest;\r\n        searchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::Id, MatchType::CaseInsensitive, manifest.Id));\r\n        \r\n        // In case there are same Ids from different sources, filter the result using package name\r\n        for (const auto& localization : manifest.Localizations)\r\n        {\r\n            const auto& localizedPackageName = localization.Get<Manifest::Localization::PackageName>();\r\n            if (!localizedPackageName.empty())\r\n            {\r\n                searchRequest.Filters.emplace_back(PackageMatchField::Name, MatchType::CaseInsensitive, localizedPackageName);\r\n            }\r\n        }\r\n\r\n        searchRequest.Filters.emplace_back(PackageMatchFilter(PackageMatchField::Name, MatchType::CaseInsensitive, manifest.DefaultLocalization.Get<Manifest::Localization::PackageName>()));\r\n\r\n        context.Add<Execution::Data::SearchResult>(source.Search(searchRequest));\r\n    }\r\n\r\n    void GetInstalledPackageVersion(Execution::Context& context)\r\n    {\r\n        std::shared_ptr<IPackage> installed = context.Get<Execution::Data::Package>()->GetInstalled();\r\n\r\n        if (installed)\r\n        {\r\n            // TODO: This may need to be expanded dramatically to enable targeting across a variety of dimensions (architecture, etc.)\r\n            //       Alternatively, if we make it easier to see the fully unique package identifiers, we may avoid that need.\r\n            if (context.Args.Contains(Execution::Args::Type::TargetVersion))\r\n            {\r\n                Repository::PackageVersionKey versionKey{ \"\", context.Args.GetArg(Execution::Args::Type::TargetVersion) , \"\" };\r\n                std::shared_ptr<IPackageVersion> installedVersion = installed->GetVersion(versionKey);\r\n\r\n                if (!installedVersion)\r\n                {\r\n                    context.Reporter.Error() << Resource::String::GetManifestResultVersionNotFound(Utility::LocIndView{ versionKey.Version }) << std::endl;\r\n                    // This error maintains consistency with passing an available version to commands\r\n                    AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_NO_MANIFEST_FOUND);\r\n                }\r\n\r\n                context.Add<Execution::Data::InstalledPackageVersion>(std::move(installedVersion));\r\n            }\r\n            else\r\n            {\r\n                context.Add<Execution::Data::InstalledPackageVersion>(installed->GetLatestVersion());\r\n            }\r\n        }\r\n        else\r\n        {\r\n            context.Add<Execution::Data::InstalledPackageVersion>(nullptr);\r\n        }\r\n    }\r\n\r\n    void ReportExecutionStage::operator()(Execution::Context& context) const\r\n    {\r\n        context.SetExecutionStage(m_stage);\r\n    }\r\n\r\n    void ShowAppVersions(Execution::Context& context)\r\n    {\r\n        auto versions = GetAllAvailableVersions(context.Get<Execution::Data::Package>())->GetVersionKeys();\r\n\r\n        Execution::TableOutput<2> table(context.Reporter, { Resource::String::ShowVersion, Resource::String::ShowChannel });\r\n        for (const auto& version : versions)\r\n        {\r\n            table.OutputLine({ version.Version, version.Channel });\r\n        }\r\n        table.Complete();\r\n    }\r\n}\r\n\r\nAppInstaller::CLI::Execution::Context& operator<<(AppInstaller::CLI::Execution::Context& context, AppInstaller::CLI::Workflow::WorkflowTask::Func f)\r\n{\r\n    return (context << AppInstaller::CLI::Workflow::WorkflowTask(f));\r\n}\r\n\r\nAppInstaller::CLI::Execution::Context& operator<<(AppInstaller::CLI::Execution::Context& context, const AppInstaller::CLI::Workflow::WorkflowTask& task)\r\n{\r\n    if (!context.IsTerminated() || task.ExecuteAlways())\r\n    {\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        if (context.ShouldExecuteWorkflowTask(task))\r\n#endif\r\n        {\r\n            task.Log();\r\n            task(context);\r\n        }\r\n    }\r\n    return context;\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/Workflows/WorkflowBase.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ExecutionArgs.h\"\r\n#include \"ExecutionReporter.h\"\r\n#include <winget/ExperimentalFeature.h>\r\n#include <winget/RepositorySearch.h>\r\n#include <winget/RepositorySource.h>\r\n#include <winget/Authentication.h>\r\n#include <winget/ManifestComparator.h>\r\n\r\n#include <string>\r\n#include <string_view>\r\n\r\nnamespace AppInstaller::CLI::Execution\r\n{\r\n    struct Context;\r\n}\r\n\r\nnamespace AppInstaller::CLI::Workflow\r\n{\r\n    // Values are ordered in a typical workflow stages\r\n    enum class ExecutionStage : uint32_t\r\n    {\r\n        Initial = 0,\r\n        ParseArgs = 1000,\r\n        Discovery = 2000,\r\n        Download = 3000,\r\n        PreExecution = 3500,\r\n        Execution = 4000,\r\n        PostExecution = 5000,\r\n    };\r\n\r\n    enum class OperationType\r\n    {\r\n        Completion,\r\n        Export,\r\n        Install,\r\n        List,\r\n        Pin,\r\n        Search,\r\n        Show,\r\n        Uninstall,\r\n        Upgrade,\r\n        Download,\r\n        Repair,\r\n    };\r\n\r\n    // A task in the workflow.\r\n    struct WorkflowTask\r\n    {\r\n        using Func = void (*)(Execution::Context&);\r\n\r\n        WorkflowTask(Func f) : m_isFunc(true), m_func(f) {}\r\n        WorkflowTask(std::string_view name, bool executeAlways = false) : m_name(name), m_executeAlways(executeAlways) {}\r\n\r\n        virtual ~WorkflowTask() = default;\r\n\r\n        WorkflowTask(const WorkflowTask&) = default;\r\n        WorkflowTask& operator=(const WorkflowTask&) = default;\r\n\r\n        WorkflowTask(WorkflowTask&&) = default;\r\n        WorkflowTask& operator=(WorkflowTask&&) = default;\r\n\r\n        bool operator==(const WorkflowTask& other) const;\r\n\r\n        virtual void operator()(Execution::Context& context) const;\r\n\r\n        const std::string& GetName() const { return m_name; }\r\n        bool IsFunction() const { return m_isFunc; }\r\n        Func Function() const { return m_func; }\r\n        bool ExecuteAlways() const { return m_executeAlways; }\r\n        void Log() const;\r\n\r\n    private:\r\n        bool m_isFunc = false;\r\n        Func m_func = nullptr;\r\n        std::string m_name;\r\n        bool m_executeAlways = false;\r\n    };\r\n\r\n    // Helper to determine installed source to use based on context input.\r\n    Repository::PredefinedSource DetermineInstalledSource(const Execution::Context& context);\r\n\r\n    // Helper to create authentication arguments from context input.\r\n    Authentication::AuthenticationArguments GetAuthenticationArguments(const Execution::Context& context);\r\n\r\n    // Helper to report exceptions and return the HRESULT.\r\n    // If context is null, no output will be attempted.\r\n    HRESULT HandleException(Execution::Context* context, std::exception_ptr exception);\r\n\r\n    // Helper to report exceptions and return the HRESULT.\r\n    HRESULT HandleException(Execution::Context& context, std::exception_ptr exception);\r\n\r\n    // Fills the options from the given context and metadata.\r\n    AppInstaller::Manifest::ManifestComparator::Options GetManifestComparatorOptions(const Execution::Context& context, const Repository::IPackageVersion::Metadata& metadata);\r\n\r\n    // Creates the source object.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: Source\r\n    struct OpenSource : public WorkflowTask\r\n    {\r\n        OpenSource(bool forDependencies = false) : WorkflowTask(\"OpenSource\"), m_forDependencies(forDependencies) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n    \r\n    private:\r\n        bool m_forDependencies;\r\n    };\r\n\r\n    // Creates a source object for a source specified by name, and adds it to the list of open sources.\r\n    // Required Args: None\r\n    // Inputs: Sources?\r\n    // Outputs: Sources\r\n    struct OpenNamedSourceForSources : public WorkflowTask\r\n    {\r\n        OpenNamedSourceForSources(std::string_view sourceName) : WorkflowTask(\"OpenNamedSourceForSources\"), m_sourceName(sourceName) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        Utility::LocIndView m_sourceName;\r\n    };\r\n\r\n    // Creates a source object for a predefined source.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: Source\r\n    struct OpenPredefinedSource : public WorkflowTask\r\n    {\r\n        OpenPredefinedSource(Repository::PredefinedSource source, bool forDependencies = false) : WorkflowTask(\"OpenPredefinedSource\"), m_predefinedSource(source), m_forDependencies(forDependencies) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        Repository::PredefinedSource m_predefinedSource;\r\n        bool m_forDependencies;\r\n    };\r\n\r\n    // Creates a composite source from the given predefined source and the existing source.\r\n    // Required Args: None\r\n    // Inputs: Source\r\n    // Outputs: Source\r\n    struct OpenCompositeSource : public WorkflowTask\r\n    {\r\n        OpenCompositeSource(\r\n            Repository::PredefinedSource source,\r\n            bool forDependencies = false,\r\n            Repository::CompositeSearchBehavior searchBehavior = Repository::CompositeSearchBehavior::Installed) :\r\n            WorkflowTask(\"OpenCompositeSource\"), m_predefinedSource(source), m_forDependencies(forDependencies), m_searchBehavior(searchBehavior) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        Repository::PredefinedSource m_predefinedSource;\r\n        bool m_forDependencies;\r\n        Repository::CompositeSearchBehavior m_searchBehavior;\r\n    };\r\n\r\n    // Performs a search on the source.\r\n    // Required Args: None\r\n    // Inputs: Source\r\n    // Outputs: SearchResult\r\n    void SearchSourceForMany(Execution::Context& context);\r\n\r\n    // Creates a search request object with the semantics of targeting a single package.\r\n    // Required Args: None\r\n    // Inputs: Query, search filters (Id, Name, etc.)\r\n    // Outputs: SearchRequest\r\n    void GetSearchRequestForSingle(Execution::Context& context);\r\n\r\n    // Performs a search on the source with the semantics of targeting a single package.\r\n    // Required Args: None\r\n    // Inputs: Source, SearchRequest\r\n    // Outputs: SearchResult\r\n    void SearchSourceForSingle(Execution::Context& context);\r\n\r\n    // Performs a search on the source with the semantics of targeting many packages,\r\n    // but for completion purposes.\r\n    // Required Args: None\r\n    // Inputs: Source, CompletionData\r\n    // Outputs: SearchResult\r\n    void SearchSourceForManyCompletion(Execution::Context& context);\r\n\r\n    // Performs a search on the source with the semantics of targeting a single package,\r\n    // but for completion purposes.\r\n    // Required Args: None\r\n    // Inputs: Source, CompletionData\r\n    // Outputs: SearchResult\r\n    void SearchSourceForSingleCompletion(Execution::Context& context);\r\n\r\n    // Searches the source for the specific field as a completion.\r\n    // Required Args: None\r\n    // Inputs: CompletionData, Source\r\n    // Outputs: None\r\n    struct SearchSourceForCompletionField : public WorkflowTask\r\n    {\r\n        SearchSourceForCompletionField(Repository::PackageMatchField field) : WorkflowTask(\"SearchSourceForCompletionField\"), m_field(field) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        Repository::PackageMatchField m_field;\r\n    };\r\n\r\n    // Outputs the search results.\r\n    // Required Args: None\r\n    // Inputs: SearchResult\r\n    // Outputs: None\r\n    void ReportSearchResult(Execution::Context& context);\r\n\r\n    // Outputs the search results as the list command would show.\r\n    // Required Args: None\r\n    // Inputs: SearchResult\r\n    // Outputs: None\r\n    struct ReportListResult : public WorkflowTask\r\n    {\r\n        ReportListResult(bool onlyShowUpgrades = false) : WorkflowTask(\"ReportListResult\"), m_onlyShowUpgrades(onlyShowUpgrades) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        bool m_onlyShowUpgrades;\r\n    };\r\n\r\n    // Handles failures in the SearchResult either by warning or failing.\r\n    // Required Args: None\r\n    // Inputs: SearchResult\r\n    // Outputs: None\r\n    void HandleSearchResultFailures(Execution::Context& context);\r\n\r\n    // Outputs the search results when multiple packages found but only one expected.\r\n    // Required Args: None\r\n    // Inputs: SearchResult\r\n    // Outputs: None\r\n    void ReportMultiplePackageFoundResult(Execution::Context& context);\r\n\r\n    // Outputs the search results when multiple packages found but only one expected.\r\n    // Required Args: None\r\n    // Inputs: SearchResult\r\n    // Outputs: None\r\n    void ReportMultiplePackageFoundResultWithSource(Execution::Context& context);\r\n\r\n    // Ensures that there is at least one result in the search.\r\n    // Required Args: bool indicating if the search result is from installed source\r\n    // Inputs: SearchResult\r\n    // Outputs: None\r\n    struct EnsureMatchesFromSearchResult : public WorkflowTask\r\n    {\r\n        EnsureMatchesFromSearchResult(OperationType operation) :\r\n            WorkflowTask(\"EnsureMatchesFromSearchResult\"), m_operationType(operation) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        OperationType m_operationType;\r\n    };\r\n\r\n    // Ensures that there is only one result in the search.\r\n    // Required Args: bool indicating if the search result is from installed source\r\n    // Inputs: SearchResult\r\n    // Outputs: Package\r\n    struct EnsureOneMatchFromSearchResult : public WorkflowTask\r\n    {\r\n        EnsureOneMatchFromSearchResult(OperationType operation) :\r\n            WorkflowTask(\"EnsureOneMatchFromSearchResult\"), m_operationType(operation) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        OperationType m_operationType;\r\n    };\r\n\r\n    // Gets the manifest from package.\r\n    // Required Args: Version and channel; can be empty. A flag indicating whether to consider package pins\r\n    // Inputs: Package\r\n    // Outputs: Manifest, PackageVersion\r\n    struct GetManifestWithVersionFromPackage : public WorkflowTask\r\n    {\r\n        GetManifestWithVersionFromPackage(std::string_view version, std::string_view channel, bool considerPins) :\r\n            WorkflowTask(\"GetManifestWithVersionFromPackage\"), m_version(version), m_channel(channel), m_considerPins(considerPins) {}\r\n\r\n        GetManifestWithVersionFromPackage(const Utility::VersionAndChannel& versionAndChannel, bool considerPins) :\r\n            GetManifestWithVersionFromPackage(versionAndChannel.GetVersion().ToString(), versionAndChannel.GetChannel().ToString(), considerPins) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        std::string_view m_version;\r\n        std::string_view m_channel;\r\n        bool m_considerPins;\r\n    };\r\n\r\n    // Gets the manifest from package.\r\n    // Required Args: A value indicating whether to consider pins\r\n    // Inputs: Package. Optionally Version and Channel\r\n    // Outputs: Manifest, PackageVersion\r\n    struct GetManifestFromPackage : public WorkflowTask\r\n    {\r\n        GetManifestFromPackage(bool considerPins) : WorkflowTask(\"GetManifestFromPackage\"), m_considerPins(considerPins) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        bool m_considerPins;\r\n    };\r\n\r\n    // Ensures the file exists and is not a directory.\r\n    // Required Args: the one given\r\n    // Inputs: None\r\n    // Outputs: None\r\n    struct VerifyFile : public WorkflowTask\r\n    {\r\n        VerifyFile(Execution::Args::Type arg) : WorkflowTask(\"VerifyFile\"), m_arg(arg) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        Execution::Args::Type m_arg;\r\n    };\r\n\r\n    // Ensures the path exists.\r\n    // Required Args: the one given\r\n    // Inputs: None\r\n    // Outputs: None\r\n    struct VerifyPath : public WorkflowTask\r\n    {\r\n        VerifyPath(Execution::Args::Type arg) : WorkflowTask(\"VerifyPath\"), m_arg(arg) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        Execution::Args::Type m_arg;\r\n    };\r\n\r\n    // Ensures the local file exists and is not a directory. Or it's a Uri. Default only https is supported at the moment.\r\n    // Required Args: the one given\r\n    // Inputs: None\r\n    // Outputs: None\r\n    struct VerifyFileOrUri : public WorkflowTask\r\n    {\r\n        VerifyFileOrUri(Execution::Args::Type arg, std::vector<std::wstring> supportedSchemes = { L\"https\" }) :\r\n            WorkflowTask(\"VerifyFileOrUri\"), m_arg(arg), m_supportedSchemes(std::move(supportedSchemes)) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        Execution::Args::Type m_arg;\r\n        std::vector<std::wstring> m_supportedSchemes;\r\n    };\r\n\r\n    // Opens the manifest file provided on the command line.\r\n    // Required Args: Manifest\r\n    // Inputs: None\r\n    // Outputs: Manifest\r\n    void GetManifestFromArg(Execution::Context& context);\r\n\r\n    // Reports the search result's package identity.\r\n    // Required Args: None\r\n    // Inputs: Package\r\n    // Outputs: None\r\n    void ReportPackageIdentity(Execution::Context& context);\r\n\r\n    // Reports the installed package version identity.\r\n    // Required Args: None\r\n    // Inputs: InstalledPackageVersion\r\n    // Outputs: None\r\n    void ReportInstalledPackageVersionIdentity(Execution::Context& context);\r\n\r\n    // Reports the manifest's identity.\r\n    // Required Args: None\r\n    // Inputs: Manifest\r\n    // Outputs: None\r\n    void ReportManifestIdentity(Execution::Context& context);\r\n\r\n    // Reports the manifest's identity with version.\r\n    // Required Args: None\r\n    // Inputs: Manifest\r\n    // Outputs: None\r\n    struct ReportManifestIdentityWithVersion : public WorkflowTask\r\n    {\r\n        ReportManifestIdentityWithVersion(Utility::LocIndView prefix, Execution::Reporter::Level level = Execution::Reporter::Level::Info) :\r\n            WorkflowTask(\"ReportManifestIdentityWithVersion\"), m_prefix(prefix), m_level(level) {}\r\n        ReportManifestIdentityWithVersion(Resource::StringId label = Resource::String::ReportIdentityFound, Execution::Reporter::Level level = Execution::Reporter::Level::Info) :\r\n            WorkflowTask(\"ReportManifestIdentityWithVersion\"), m_label(label), m_level(level) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        Utility::LocIndView m_prefix;\r\n        std::optional<Resource::StringId> m_label;\r\n        Execution::Reporter::Level m_level;\r\n    };\r\n\r\n    // Selects the installer from the manifest, if one is applicable.\r\n    // Required Args: None\r\n    // Inputs: Manifest\r\n    // Outputs: Installer\r\n    void SelectInstaller(Execution::Context& context);\r\n\r\n    // Ensures that the process is running as admin.\r\n    // Required Args: None\r\n    // Inputs: None\r\n    // Outputs: None\r\n    void EnsureRunningAsAdmin(Execution::Context& context);\r\n\r\n    // Ensures that the feature is enabled.\r\n    // Required Args: the desired feature\r\n    // Inputs: None\r\n    // Outputs: None\r\n    struct EnsureFeatureEnabled : public WorkflowTask\r\n    {\r\n        EnsureFeatureEnabled(Settings::ExperimentalFeature::Feature feature) : WorkflowTask(\"EnsureFeatureEnabled\"), m_feature(feature) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        Settings::ExperimentalFeature::Feature m_feature;\r\n    };\r\n\r\n    // Performs a search on the source with the semantics of targeting packages matching input manifest\r\n    // Required Args: None\r\n    // Inputs: Source, Manifest\r\n    // Outputs: SearchResult\r\n    void SearchSourceUsingManifest(Execution::Context& context);\r\n\r\n    // Gets the installed package version\r\n    // Required Args: None\r\n    // Inputs: Package\r\n    // Outputs: InstalledPackageVersion\r\n    void GetInstalledPackageVersion(Execution::Context& context);\r\n\r\n    // Shows all versions for an application.\r\n    // Required Args: None\r\n    // Inputs: SearchResult [only operates on first match]\r\n    // Outputs: None\r\n    void ShowAppVersions(Execution::Context& context);\r\n\r\n    // Reports execution stage in a workflow\r\n    // Required Args: ExecutionStage\r\n    // Inputs: ExecutionStage?\r\n    // Outputs: ExecutionStage\r\n    struct ReportExecutionStage : public WorkflowTask\r\n    {\r\n        ReportExecutionStage(ExecutionStage stage) : WorkflowTask(\"ReportExecutionStage\"), m_stage(stage) {}\r\n\r\n        void operator()(Execution::Context& context) const override;\r\n\r\n    private:\r\n        ExecutionStage m_stage;\r\n    };\r\n}\r\n\r\n// Passes the context to the function if it has not been terminated; returns the context.\r\nAppInstaller::CLI::Execution::Context& operator<<(AppInstaller::CLI::Execution::Context& context, AppInstaller::CLI::Workflow::WorkflowTask::Func f);\r\n\r\n// Passes the context to the task if it has not been terminated; returns the context.\r\nAppInstaller::CLI::Execution::Context& operator<<(AppInstaller::CLI::Execution::Context& context, const AppInstaller::CLI::Workflow::WorkflowTask& task);\r\n"
  },
  {
    "path": "src/AppInstallerCLICore/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<packages>\r\n  <package id=\"Microsoft.Windows.CppWinRT\" version=\"2.0.250303.1\" targetFramework=\"native\" />\r\n  <package id=\"Microsoft.Windows.ImplementationLibrary\" version=\"1.0.250325.1\" targetFramework=\"native\" />\r\n</packages>"
  },
  {
    "path": "src/AppInstallerCLICore/pch.cpp",
    "content": "﻿// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n"
  },
  {
    "path": "src/AppInstallerCLICore/pch.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n\r\n#define NOMINMAX\r\n#include <windows.h>\r\n#include <shellapi.h>\r\n#include <WinInet.h>\r\n#include <msi.h>\r\n#include <wincodec.h>\r\n\r\n#pragma warning( push )\r\n#pragma warning ( disable : 4458 4100 6031 4702 26439 )\r\n#include <valijson/schema.hpp>\r\n#include <valijson/schema_parser.hpp>\r\n#include <valijson/validator.hpp>\r\n#include <valijson/adapters/jsoncpp_adapter.hpp>\r\n#pragma warning( pop )\r\n\r\n#include <algorithm>\r\n#include <array>\r\n#include <atomic>\r\n#include <csignal>\r\n#include <iostream>\r\n#include <fstream>\r\n#include <future>\r\n#include <functional>\r\n#include <iterator>\r\n#include <memory>\r\n#include <mutex>\r\n#include <numeric>\r\n#include <optional>\r\n#include <queue>\r\n#include <set>\r\n#include <sstream>\r\n#include <string>\r\n#include <string_view>\r\n#include <vector>\r\n\r\n#include <winrt/Windows.Foundation.h>\r\n#include <winrt/Windows.Foundation.Collections.h>\r\n#include <winrt/Windows.Management.Deployment.h>\r\n#include <winrt/Windows.UI.ViewManagement.h>\r\n#include <winrt/Windows.ApplicationModel.h>\r\n#include <winrt/Windows.ApplicationModel.Resources.h>\r\n#include <winrt/Windows.ApplicationModel.Resources.Core.h>\r\n#include <winrt/Windows.ApplicationModel.Store.Preview.InstallControl.h>\r\n#include <winrt/Windows.Storage.Streams.h>\r\n#include <winrt/Windows.Security.Cryptography.Certificates.h>\r\n\r\n#pragma warning( push )\r\n#pragma warning ( disable : 6001 6285 6340 6388 26451 )\r\n#include <wil/resource.h>\r\n#include <wil/result.h>\r\n#include <wil/result_macros.h>\r\n#include <wil/safecast.h>\r\n#include <wil/com.h>\r\n#include <wil/registry_helpers.h>\r\n#pragma warning( pop )\r\n\r\n#include <wrl/client.h>\r\n#include <wrl/implements.h>\r\n#include <AppxPackaging.h>\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/AppInstallerCLIE2ETests.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <TargetFramework>net8.0-windows</TargetFramework>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\AppInstallerCLIE2ETests\\</OutDir>\r\n    <IsPackable>false</IsPackable>\r\n    <Platforms>x64;x86</Platforms>\r\n    <OutputType>Library</OutputType>\r\n    <DocumentationFile>$(OutDir)\\AppInstallerCLIE2ETests.xml</DocumentationFile>\r\n    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup>\r\n    <!-- Disable warning for CS1591 because auto generated Microsoft.Management.Deployment -->\r\n    <!-- For our code, we still have stylecops acting on it. -->\r\n    <NoWarn>1591</NoWarn>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Release'\">\r\n    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <PackageReference Include=\"Microsoft.PowerShell.SDK\" />\r\n    <PackageReference Include=\"Newtonsoft.Json\" />\r\n    <PackageReference Include=\"Microsoft.Msix.Utils\" />\r\n    <PackageReference Include=\"Microsoft.Win32.Registry\" />\r\n    <PackageReference Include=\"Microsoft.Windows.CsWinRT\" />\r\n    <PackageReference Include=\"nunit\" />\r\n    <PackageReference Include=\"NUnit3TestAdapter\" />\r\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" />\r\n    <PackageReference Include=\"StyleCop.Analyzers\">\r\n      <PrivateAssets>all</PrivateAssets>\r\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\r\n    </PackageReference>\r\n    <PackageReference Include=\"System.Data.SqlClient\" />\r\n    <PackageReference Include=\"System.Text.RegularExpressions\" />\r\n  </ItemGroup>\r\n\r\n  <!-- CsWinRT properties -->\r\n  <PropertyGroup>\r\n    <CsWinRTWindowsMetadata>10.0.26100.0</CsWinRTWindowsMetadata>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <Content Include=\"TestData\\**\">\r\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\r\n    </Content>\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <Content Include=\"..\\..\\doc\\admx\\DesktopAppInstaller.admx\" Link=\"TestData\\DesktopAppInstaller.admx\">\r\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\r\n    </Content>\r\n    <AdditionalFiles Include=\"..\\stylecop.json\" Link=\"stylecop.json\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\IndexCreationTool\\IndexCreationTool.csproj\" />\r\n    <ProjectReference Include=\"..\\Microsoft.Management.Deployment.Projection\\Microsoft.Management.Deployment.Projection.csproj\" />\r\n    <ProjectReference Include=\"..\\Microsoft.Management.Deployment.InProc\\Microsoft.Management.Deployment.InProc.vcxproj\">\r\n      <ReferenceOutputAssembly>False</ReferenceOutputAssembly>\r\n    </ProjectReference>\r\n    <ProjectReference Include=\"..\\WindowsPackageManager\\WindowsPackageManager.vcxproj\">\r\n      <ReferenceOutputAssembly>False</ReferenceOutputAssembly>\r\n    </ProjectReference>\r\n    <ProjectReference Include=\"..\\WinGetSourceCreator\\WinGetSourceCreator.csproj\" />\r\n    <ProjectReference Include=\"..\\WinGetTestCommon\\WinGetTestCommon.csproj\" />\r\n    <ProjectReference Include=\"..\\WinGetUtil\\WinGetUtil.vcxproj\">\r\n      <ReferenceOutputAssembly>False</ReferenceOutputAssembly>\r\n    </ProjectReference>\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <None Update=\"Test.runsettings\">\r\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\r\n    </None>\r\n  </ItemGroup>\r\n\r\n  <Target Name=\"PostBuild\" AfterTargets=\"PostBuildEvent\">\r\n      <!-- Rename dll to align with the expected search pattern performed by CsWinRT -->\r\n    <Copy SourceFiles=\"$(TargetDir)..\\Microsoft.Management.Deployment.InProc\\Microsoft.Management.Deployment.InProc.dll\" DestinationFiles=\"$(TargetDir)Microsoft.Management.Deployment.dll\" />\r\n    <Copy SourceFiles=\"$(TargetDir)..\\WindowsPackageManager\\WindowsPackageManager.dll\" DestinationFiles=\"$(TargetDir)WindowsPackageManager.dll\" />\r\n    <Copy SourceFiles=\"$(TargetDir)..\\WinGetUtil\\WinGetUtil.dll\" DestinationFiles=\"$(TargetDir)WinGetUtil.dll\" />\r\n  </Target>\r\n</Project>\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/AppShutdownTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"AppShutdownTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using System;\r\n    using System.Diagnostics;\r\n    using System.IO;\r\n    using System.Threading;\r\n    using System.Threading.Tasks;\r\n    using System.Xml;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// `test appshutdown` command tests.\r\n    /// </summary>\r\n    public class AppShutdownTests\r\n    {\r\n        /// <summary>\r\n        /// Runs winget test appshutdown and register the application to force a WM_QUERYENDSESSION message.\r\n        /// </summary>\r\n        [Test]\r\n        [Ignore(\"This test relied on a signal to terminate that was determined to be problematic. We may need OS fixes to test it when elevated.\")]\r\n        public void RegisterApplicationTest()\r\n        {\r\n            if (!TestSetup.Parameters.PackagedContext)\r\n            {\r\n                Assert.Ignore(\"Not packaged context.\");\r\n            }\r\n\r\n            if (!TestCommon.ExecutingAsAdministrator && TestCommon.IsCIEnvironment)\r\n            {\r\n                Assert.Ignore(\"This test won't work on Window Server as non-admin\");\r\n            }\r\n\r\n            if (!Environment.Is64BitProcess)\r\n            {\r\n                // My guess is that HAM terminates us faster after the CTRL-C on x86...\r\n                Assert.Ignore(\"This test is flaky when run as x86.\");\r\n            }\r\n\r\n            if (string.IsNullOrEmpty(TestSetup.Parameters.AICLIPackagePath))\r\n            {\r\n                throw new NullReferenceException(\"AICLIPackagePath\");\r\n            }\r\n\r\n            var appxManifest = Path.Combine(TestSetup.Parameters.AICLIPackagePath, \"AppxManifest.xml\");\r\n            if (!File.Exists(appxManifest))\r\n            {\r\n                throw new FileNotFoundException(appxManifest);\r\n            }\r\n\r\n            // In order to registering the application we need a higher version number and pass the force app shutdown flag.\r\n            // Doing it the long way.\r\n            var xmlDoc = new XmlDocument();\r\n            XmlNamespaceManager namespaces = new XmlNamespaceManager(xmlDoc.NameTable);\r\n            namespaces.AddNamespace(\"n\", \"http://schemas.microsoft.com/appx/manifest/foundation/windows10\");\r\n            xmlDoc.Load(appxManifest);\r\n            var identityNode = xmlDoc.SelectSingleNode(\"/n:Package/n:Identity\", namespaces);\r\n            if (identityNode == null)\r\n            {\r\n                throw new NullReferenceException(\"Identity node\");\r\n            }\r\n\r\n            var versionAttribute = identityNode.Attributes[\"Version\"];\r\n            if (versionAttribute == null)\r\n            {\r\n                throw new NullReferenceException(\"Version attribute\");\r\n            }\r\n\r\n            var ogVersion = new Version(versionAttribute.Value);\r\n            var newVersion = new Version(ogVersion.Major, ogVersion.Minor, ogVersion.Build, ogVersion.Revision + 1);\r\n            versionAttribute.Value = newVersion.ToString();\r\n            xmlDoc.Save(appxManifest);\r\n\r\n            // This just waits for the app termination event.\r\n            var testCmdTask = new Task<TestCommon.RunCommandResult>(() =>\r\n            {\r\n                return TestCommon.RunAICLICommand(\"test\", \"appshutdown --verbose\", timeOut: 300000, throwOnTimeout: false);\r\n            });\r\n\r\n            // Register the app with the updated version.\r\n            var registerTask = new Task<bool>(() =>\r\n            {\r\n                return TestCommon.InstallMsixRegister(TestSetup.Parameters.AICLIPackagePath, true, false);\r\n            });\r\n\r\n            // Give it a little time.\r\n            testCmdTask.Start();\r\n            Thread.Sleep(30000);\r\n            registerTask.Start();\r\n\r\n            Task.WaitAll(new Task[] { testCmdTask, registerTask }, 360000);\r\n\r\n            // The ctrl-c command terminates the batch file before the exit code file gets created.\r\n            // Look for the output.\r\n            Assert.True(testCmdTask.Result.StdOut.Contains(\"Succeeded waiting for app shutdown event\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Runs winget test can-unload-now expecting that it cannot be unloaded.\r\n        /// </summary>\r\n        [Test]\r\n        public void CanUnloadNowTest()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"test\", \"can-unload-now --verbose\");\r\n\r\n            var lines = result.StdOut.Split('\\n', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);\r\n\r\n            Assert.AreEqual(5, lines.Length);\r\n            Assert.True(lines[0].Contains(\"Internal objects:\"));\r\n            Assert.False(lines[0].Contains(\"Internal objects: 0\"));\r\n            Assert.True(lines[1].Contains(\"External objects: 0\"));\r\n            Assert.True(lines[2].Contains(\"DllCanUnloadNow\"));\r\n            Assert.True(lines[3].Contains(\"Internal objects: 0\"));\r\n            Assert.True(lines[4].Contains(\"External objects: 0\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Runs winget test term-signal-handler to check for proper thread termination.\r\n        /// </summary>\r\n        [Test]\r\n        public void TermSignalHandler()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"test\", \"term-signal-handler --verbose\");\r\n            Assert.True(result.StdOut.Contains(\"Got a window handle\"));\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/BaseCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"BaseCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// Base command.\r\n    /// </summary>\r\n    public class BaseCommand\r\n    {\r\n        /// <summary>\r\n        /// Set up.\r\n        /// </summary>\r\n        [OneTimeSetUp]\r\n        public void BaseSetup()\r\n        {\r\n            this.ResetTestSource();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tear down.\r\n        /// </summary>\r\n        [OneTimeTearDown]\r\n        public void BaseTeardown()\r\n        {\r\n            TestCommon.TearDownTestSource();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Reset test source.\r\n        /// </summary>\r\n        /// <param name=\"useGroupPolicyForTestSource\">Use group policy from test source.</param>\r\n        public void ResetTestSource(bool useGroupPolicyForTestSource = false)\r\n        {\r\n            // TODO: If/when cert pinning is implemented on the packaged index source, useGroupPolicyForTestSource should be set to default true\r\n            //       to enable testing it by default.  Until then, leaving this here...\r\n            TestCommon.SetupTestSource(useGroupPolicyForTestSource);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/ConfigureCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigureCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using System;\r\n    using System.IO;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// `Configure` command tests.\r\n    /// </summary>\r\n    public class ConfigureCommand\r\n    {\r\n        private const string CommandAndAgreementsAndVerbose = \"configure --accept-configuration-agreements --verbose\";\r\n\r\n        /// <summary>\r\n        /// Ensures that the test resources manifests are present.\r\n        /// </summary>\r\n        public static void EnsureTestResourcePresence()\r\n        {\r\n            DSCv3ResourceTestBase.EnsureTestResourcePresence();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Setup done once before all the tests here.\r\n        /// </summary>\r\n        [OneTimeSetUp]\r\n        public void OneTimeSetup()\r\n        {\r\n            this.DeleteResourceArtifacts();\r\n            EnsureTestResourcePresence();\r\n            TestCommon.SetupTestSource(false);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Teardown done once after all the tests here.\r\n        /// </summary>\r\n        [OneTimeTearDown]\r\n        public void OneTimeTeardown()\r\n        {\r\n            this.DeleteResourceArtifacts();\r\n            TestCommon.TearDownTestSource();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Simple test to confirm that a resource without a module specified can be discovered in the PSGallery.\r\n        /// Intentionally has no settings to force a failure, but only after acquiring the module.\r\n        /// </summary>\r\n        [Test]\r\n        [Ignore(\"PS Gallery tests are unreliable.\")]\r\n        public void ConfigureFromGallery()\r\n        {\r\n            TestCommon.EnsureModuleState(Constants.GalleryTestModuleName, present: false);\r\n\r\n            var result = TestCommon.RunAICLICommand(CommandAndAgreementsAndVerbose, TestCommon.GetTestDataFile(\"Configuration\\\\PSGallery_NoModule_NoSettings.yml\"), timeOut: 120000);\r\n            Assert.AreEqual(Constants.ErrorCode.CONFIG_ERROR_SET_APPLY_FAILED, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"The configuration unit failed while attempting to test the current system state.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Simple test to confirm that a resource with a module specified can be discovered in a local repository that doesn't support resource discovery.\r\n        /// </summary>\r\n        [Test]\r\n        public void ConfigureFromTestRepo()\r\n        {\r\n            TestCommon.EnsureModuleState(Constants.SimpleTestModuleName, present: false);\r\n\r\n            var result = TestCommon.RunAICLICommand(CommandAndAgreementsAndVerbose, TestCommon.GetTestDataFile(\"Configuration\\\\Configure_TestRepo.yml\"));\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            // The configuration creates a file next to itself with the given contents\r\n            string targetFilePath = TestCommon.GetTestDataFile(\"Configuration\\\\Configure_TestRepo.txt\");\r\n            FileAssert.Exists(targetFilePath);\r\n            Assert.AreEqual(\"Contents!\", File.ReadAllText(targetFilePath));\r\n\r\n            Assert.True(Directory.Exists(\r\n                Path.Combine(\r\n                    TestCommon.GetExpectedModulePath(TestCommon.TestModuleLocation.Default),\r\n                    Constants.SimpleTestModuleName)));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Simple test to confirm that the module was installed to the location specified in the DefaultModuleRoot settings.\r\n        /// </summary>\r\n        [Test]\r\n        public void ConfigureFromTestRepo_DefaultModuleRootSetting()\r\n        {\r\n            TestCommon.EnsureModuleState(Constants.SimpleTestModuleName, present: false);\r\n            string moduleTestDir = TestCommon.GetRandomTestDir();\r\n            WinGetSettingsHelper.ConfigureConfigureBehavior(Constants.DefaultModuleRoot, moduleTestDir);\r\n\r\n            string args = TestCommon.GetTestDataFile(\"Configuration\\\\Configure_TestRepo_Location.yml\");\r\n            var result = TestCommon.RunAICLICommand(CommandAndAgreementsAndVerbose, args);\r\n\r\n            WinGetSettingsHelper.ConfigureConfigureBehavior(Constants.DefaultModuleRoot, string.Empty);\r\n            bool moduleExists = Directory.Exists(Path.Combine(moduleTestDir, Constants.SimpleTestModuleName));\r\n            if (moduleExists)\r\n            {\r\n                // Clean test directory to avoid impacting other tests.\r\n                Directory.Delete(moduleTestDir, true);\r\n            }\r\n\r\n            Assert.AreEqual(0, result.ExitCode);\r\n            Assert.True(moduleExists);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Simple test to confirm that the module was installed in the right location.\r\n        /// </summary>\r\n        /// <param name=\"location\">Location to pass.</param>\r\n        [TestCase(TestCommon.TestModuleLocation.CurrentUser)]\r\n        [TestCase(TestCommon.TestModuleLocation.AllUsers)]\r\n        [TestCase(TestCommon.TestModuleLocation.WinGetModulePath)]\r\n        [TestCase(TestCommon.TestModuleLocation.Custom)]\r\n        [TestCase(TestCommon.TestModuleLocation.Default)]\r\n        public void ConfigureFromTestRepo_Location(TestCommon.TestModuleLocation location)\r\n        {\r\n            TestCommon.EnsureModuleState(Constants.SimpleTestModuleName, present: false);\r\n\r\n            string args = TestCommon.GetTestDataFile(\"Configuration\\\\Configure_TestRepo_Location.yml\");\r\n            if (location == TestCommon.TestModuleLocation.CurrentUser)\r\n            {\r\n                args += \" --module-path currentuser\";\r\n            }\r\n            else if (location == TestCommon.TestModuleLocation.AllUsers)\r\n            {\r\n                args += \" --module-path allusers\";\r\n            }\r\n            else if (location == TestCommon.TestModuleLocation.Default)\r\n            {\r\n                args += \" --module-path default\";\r\n            }\r\n            else if (location == TestCommon.TestModuleLocation.Custom)\r\n            {\r\n                args += \" --module-path \" + TestCommon.GetExpectedModulePath(location);\r\n            }\r\n\r\n            var result = TestCommon.RunAICLICommand(CommandAndAgreementsAndVerbose, args);\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            Assert.True(Directory.Exists(Path.Combine(\r\n                TestCommon.GetExpectedModulePath(location),\r\n                Constants.SimpleTestModuleName)));\r\n        }\r\n\r\n        /// <summary>\r\n        /// One resource fails, but the other is not dependent and should be executed.\r\n        /// </summary>\r\n        [Test]\r\n        public void IndependentResourceWithSingleFailure()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(CommandAndAgreementsAndVerbose, TestCommon.GetTestDataFile(\"Configuration\\\\IndependentResources_OneFailure.yml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.CONFIG_ERROR_SET_APPLY_FAILED, result.ExitCode);\r\n\r\n            // The configuration creates a file next to itself with the given contents\r\n            string targetFilePath = TestCommon.GetTestDataFile(\"Configuration\\\\IndependentResources_OneFailure.txt\");\r\n            FileAssert.Exists(targetFilePath);\r\n            Assert.AreEqual(\"Contents!\", File.ReadAllText(targetFilePath));\r\n        }\r\n\r\n        /// <summary>\r\n        /// One resource fails, and the dependent resource should not be executed.\r\n        /// </summary>\r\n        [Test]\r\n        public void DependentResourceWithFailure()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(CommandAndAgreementsAndVerbose, TestCommon.GetTestDataFile(\"Configuration\\\\DependentResources_Failure.yml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.CONFIG_ERROR_SET_APPLY_FAILED, result.ExitCode);\r\n\r\n            // The configuration creates a file next to itself with the given contents\r\n            string targetFilePath = TestCommon.GetTestDataFile(\"Configuration\\\\DependentResources_Failure.txt\");\r\n            FileAssert.DoesNotExist(targetFilePath);\r\n        }\r\n\r\n        /// <summary>\r\n        /// The configuration server unexpectedly exits. Winget should continue to operate properly.\r\n        /// </summary>\r\n        [Test]\r\n        public void ConfigServerUnexpectedExit()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(CommandAndAgreementsAndVerbose, TestCommon.GetTestDataFile(\"Configuration\\\\ConfigServerUnexpectedExit.yml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.CONFIG_ERROR_SET_APPLY_FAILED, result.ExitCode);\r\n\r\n            // The configuration creates a file next to itself with the given contents\r\n            string targetFilePath = TestCommon.GetTestDataFile(\"Configuration\\\\ConfigServerUnexpectedExit.txt\");\r\n            FileAssert.DoesNotExist(targetFilePath);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Resource name case-insensitive test.\r\n        /// </summary>\r\n        [Test]\r\n        public void ResourceCaseInsensitive()\r\n        {\r\n            TestCommon.EnsureModuleState(Constants.SimpleTestModuleName, present: false);\r\n\r\n            var result = TestCommon.RunAICLICommand(CommandAndAgreementsAndVerbose, TestCommon.GetTestDataFile(\"Configuration\\\\ResourceCaseInsensitive.yml\"));\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            // The configuration creates a file next to itself with the given contents\r\n            string targetFilePath = TestCommon.GetTestDataFile(\"Configuration\\\\ResourceCaseInsensitive.txt\");\r\n            FileAssert.Exists(targetFilePath);\r\n            Assert.AreEqual(\"Contents!\", File.ReadAllText(targetFilePath));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Simple test to configure from an https configuration file.\r\n        /// </summary>\r\n        [Test]\r\n        public void ConfigureFromHttpsConfigurationFile()\r\n        {\r\n            string args = $\"{Constants.TestSourceUrl}/TestData/Configuration/Configure_TestRepo_Location.yml\";\r\n\r\n            var result = TestCommon.RunAICLICommand(CommandAndAgreementsAndVerbose, args);\r\n            Assert.AreEqual(0, result.ExitCode);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Runs a configuration, then changes the state and runs it again from history.\r\n        /// </summary>\r\n        [Test]\r\n        public void ConfigureFromHistory()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(CommandAndAgreementsAndVerbose, TestCommon.GetTestDataFile(\"Configuration\\\\Configure_TestRepo.yml\"));\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            // The configuration creates a file next to itself with the given contents\r\n            string targetFilePath = TestCommon.GetTestDataFile(\"Configuration\\\\Configure_TestRepo.txt\");\r\n            FileAssert.Exists(targetFilePath);\r\n            Assert.AreEqual(\"Contents!\", File.ReadAllText(targetFilePath));\r\n\r\n            File.WriteAllText(targetFilePath, \"Changed contents!\");\r\n\r\n            string guid = TestCommon.GetConfigurationInstanceIdentifierFor(\"Configure_TestRepo.yml\");\r\n            result = TestCommon.RunAICLICommand(CommandAndAgreementsAndVerbose, $\"-h {guid}\");\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            FileAssert.Exists(targetFilePath);\r\n            Assert.AreEqual(\"Contents!\", File.ReadAllText(targetFilePath));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Specifies the module path to an \"elevated\" server.\r\n        /// </summary>\r\n        [Test]\r\n        public void SpecifyModulePathToHighIntegrityServer()\r\n        {\r\n            string configFile = TestCommon.GetTestDataFile(\"Configuration\\\\GetPSModulePath.yml\");\r\n            string testDirectory = TestCommon.GetRandomTestDir();\r\n\r\n            var result = TestCommon.RunAICLICommand(CommandAndAgreementsAndVerbose, $\"{configFile} --module-path \\\"{testDirectory}\\\"\");\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            string testFile = Path.Join(TestCommon.GetTestDataFile(\"Configuration\"), \"PSModulePath.txt\");\r\n            Assert.True(File.Exists(testFile));\r\n            string testFileContents = File.ReadAllText(testFile);\r\n            Assert.True(testFileContents.StartsWith(testDirectory));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Runs a DSCv3 configuration, then changes the state and runs it again from history.\r\n        /// </summary>\r\n        [Test]\r\n        public void ConfigureThroughHistory_DSCv3()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(CommandAndAgreementsAndVerbose, TestCommon.GetTestDataFile(\"Configuration\\\\ShowDetails_DSCv3.yml\"));\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            // The configuration creates a file next to itself with the given contents\r\n            string targetFilePath = TestCommon.GetTestDataFile(\"Configuration\\\\ShowDetails_DSCv3.txt\");\r\n            FileAssert.Exists(targetFilePath);\r\n            Assert.AreEqual(\"DSCv3 Contents!\", File.ReadAllText(targetFilePath));\r\n\r\n            File.WriteAllText(targetFilePath, \"Changed contents!\");\r\n\r\n            string guid = TestCommon.GetConfigurationInstanceIdentifierFor(\"ShowDetails_DSCv3.yml\");\r\n            result = TestCommon.RunAICLICommand(CommandAndAgreementsAndVerbose, $\"-h {guid}\");\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            FileAssert.Exists(targetFilePath);\r\n            Assert.AreEqual(\"DSCv3 Contents!\", File.ReadAllText(targetFilePath));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Ensures that the test file resource schema function works.\r\n        /// </summary>\r\n        [Test]\r\n        public void TestFileResourceSchema()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"dscv3 test-file\", \"--schema\");\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            var lines = result.StdOut.Split(\"\\r\\n\", StringSplitOptions.RemoveEmptyEntries);\r\n            Assert.AreEqual(1, lines.Length);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Export all with specific package id.\r\n        /// </summary>\r\n        [Test]\r\n        public void DSCv3_Export()\r\n        {\r\n            // Reset state\r\n            var result = TestCommon.RunAICLICommand(\"dscv3 test-json\", \"--delete\");\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            // Configure properties\r\n            string propertyName1 = \"prop1\";\r\n            string propertyName2 = \"prop2\";\r\n            string propertyValue1 = \"val1\";\r\n            string propertyValue2 = \"val2\";\r\n\r\n            string propertySetFormatString = \"{{ \\\"property\\\": \\\"{0}\\\", \\\"value\\\": \\\"{1}\\\" }}\";\r\n\r\n            result = TestCommon.RunAICLICommand(\"dscv3 test-json\", \"--set\", string.Format(propertySetFormatString, propertyName1, propertyValue1));\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            result = TestCommon.RunAICLICommand(\"dscv3 test-json\", \"--set\", string.Format(propertySetFormatString, propertyName2, propertyValue2));\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            // Export\r\n            var exportDir = TestCommon.GetRandomTestDir();\r\n            var exportFile = Path.Combine(exportDir, \"exported.yml\");\r\n\r\n            result = TestCommon.RunAICLICommand(\"test config-export-units\", $\"-o {exportFile} --resource Microsoft.WinGet.Dev/TestJSON --verbose\");\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            Assert.True(File.Exists(exportFile));\r\n            string exportText = File.ReadAllText(exportFile);\r\n            Assert.True(exportText.Contains(\"Microsoft.WinGet.Dev/TestJSON\"));\r\n            Assert.True(exportText.Contains(propertyName1));\r\n            Assert.True(exportText.Contains(propertyName2));\r\n            Assert.True(exportText.Contains(propertyValue1));\r\n            Assert.True(exportText.Contains(propertyValue2));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Simple test to confirm that a resource with a module specified can be discovered in a local repository that doesn't support resource discovery.\r\n        /// </summary>\r\n        [Test]\r\n        public void ConfigureFromTestRepo_DSCv3()\r\n        {\r\n            TestCommon.EnsureModuleState(Constants.SimpleTestModuleName, present: true, repository: Constants.TestRepoName);\r\n            this.DeleteResourceArtifacts();\r\n\r\n            var result = TestCommon.RunAICLICommand(CommandAndAgreementsAndVerbose, TestCommon.GetTestDataFile(\"Configuration\\\\Configure_TestRepo_DSCv3.yml\"), timeOut: 300000);\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            // The configuration creates a file next to itself with the given contents\r\n            string targetFilePath = TestCommon.GetTestDataFile(\"Configuration\\\\Configure_TestRepo.txt\");\r\n            FileAssert.Exists(targetFilePath);\r\n            Assert.AreEqual(\"Contents!\", File.ReadAllText(targetFilePath));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Find unit processors tests.\r\n        /// </summary>\r\n        [Test]\r\n        public void ConfigureFindUnitProcessors()\r\n        {\r\n            // Find all unit processors.\r\n            var result = TestCommon.RunAICLICommand(\"test config-find-unit-processors\", string.Empty, timeOut: 300000);\r\n            Assert.AreEqual(0, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Microsoft/OSInfo\"));\r\n\r\n            // Setup TestExeInstaller with dsc resources.\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestExeInstaller --override \\\"/InstallDir {installDir} /GenerateDscResourceFiles\\\"\");\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            // Find unit processors filtering to install location.\r\n            result = TestCommon.RunAICLICommand(\"test config-find-unit-processors\", $\"-l {installDir}\");\r\n            Assert.AreEqual(0, result.ExitCode);\r\n            Assert.False(result.StdOut.Contains(\"Microsoft/OSInfo\"));\r\n            Assert.True(result.StdOut.Contains(\"AppInstallerTest/TestResource\"));\r\n\r\n            // Find unit processors filtering to unknown location.\r\n            var unknownDir = TestCommon.GetRandomTestDir();\r\n            result = TestCommon.RunAICLICommand(\"test config-find-unit-processors\", $\"-l {unknownDir}\");\r\n            Assert.AreEqual(0, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"No unit processors found.\"));\r\n\r\n            // Clean up\r\n            result = TestCommon.RunAICLICommand(\"uninstall\", \"AppInstallerTest.TestExeInstaller\");\r\n            Assert.AreEqual(0, result.ExitCode);\r\n        }\r\n\r\n        /// <summary>\r\n        /// RunCommandOnSet test.\r\n        /// </summary>\r\n        [Test]\r\n        public void RunCommandOnSetResourceTest()\r\n        {\r\n            var testDir = TestCommon.GetRandomTestDir();\r\n            var testConfigFile = Path.Combine(testDir, \"RunCommandOnSet.yml\");\r\n            File.Copy(TestCommon.GetTestDataFile(\"Configuration\\\\RunCommandOnSet.yml\"), testConfigFile);\r\n\r\n            var content = File.ReadAllText(testConfigFile);\r\n            content = content.Replace(\"<PathToBeReplaced>\", testDir);\r\n            File.WriteAllText(testConfigFile, content);\r\n\r\n            var result = TestCommon.RunAICLICommand(CommandAndAgreementsAndVerbose, testConfigFile, timeOut: 300000);\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            // Verify test file created.\r\n            string targetFilePath = Path.Combine(testDir, \"TestFile.txt\");\r\n            FileAssert.Exists(targetFilePath);\r\n            string testContent = File.ReadAllText(targetFilePath);\r\n            Assert.True(testContent.Contains(\"TestContent\"));\r\n        }\r\n\r\n        private void DeleteResourceArtifacts()\r\n        {\r\n            // Delete all .txt files in the test directory; they are placed there by the tests\r\n            foreach (string file in Directory.GetFiles(TestCommon.GetTestDataFile(\"Configuration\"), \"*.txt\"))\r\n            {\r\n                File.Delete(file);\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/ConfigureExportCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigureExportCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using System.IO;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\r\n    using NUnit.Framework.Internal;\r\n\r\n    /// <summary>\r\n    /// `Configure export` command tests.\r\n    /// </summary>\r\n    public class ConfigureExportCommand\r\n    {\r\n        private const string Command = \"configure export\";\r\n        private const string ShowCommand = \"configure show\";\r\n\r\n        private string previousPathValue = string.Empty;\r\n\r\n        /// <summary>\r\n        /// Set up.\r\n        /// </summary>\r\n        [OneTimeSetUp]\r\n        public void BaseSetup()\r\n        {\r\n            TestCommon.SetupTestSource(false);\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestPackageExport -v 1.0.0.0 --silent -l {installDir}\");\r\n            this.previousPathValue = System.Environment.GetEnvironmentVariable(\"PATH\");\r\n\r\n            // The installer puts DSCv3 resources in both locations\r\n            System.Environment.SetEnvironmentVariable(\"PATH\", this.previousPathValue + \";\" + installDir + \";\" + installDir + \"\\\\SubDirectory\");\r\n            DSCv3ResourceTestBase.EnsureTestResourcePresence();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tear down.\r\n        /// </summary>\r\n        [OneTimeTearDown]\r\n        public void BaseTeardown()\r\n        {\r\n            TestCommon.RunAICLICommand(\"uninstall\", \"AppInstallerTest.TestPackageExport\");\r\n            TestCommon.TearDownTestSource();\r\n            if (!string.IsNullOrEmpty(this.previousPathValue))\r\n            {\r\n                System.Environment.SetEnvironmentVariable(\"PATH\", this.previousPathValue);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Export a specific package.\r\n        /// </summary>\r\n        [Test]\r\n        public void ExportTestPackage()\r\n        {\r\n            var exportDir = TestCommon.GetRandomTestDir();\r\n            var exportFile = Path.Combine(exportDir, \"exported.yml\");\r\n            var result = TestCommon.RunAICLICommand(Command, $\"--package-id AppInstallerTest.TestPackageExport -o {exportFile}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(File.Exists(exportFile));\r\n\r\n            // Check exported file is readable and validate content\r\n            var showResult = TestCommon.RunAICLICommand(ShowCommand, $\"-f {exportFile}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, showResult.ExitCode);\r\n            Assert.True(showResult.StdOut.Contains(\"Microsoft.WinGet.Dev/Source\"));\r\n            Assert.True(showResult.StdOut.Contains($\"[{Constants.TestSourceName}_{Constants.TestSourceType}]\"));\r\n            Assert.True(showResult.StdOut.Contains($\"type: {Constants.TestSourceType}\"));\r\n            Assert.True(showResult.StdOut.Contains($\"argument: {Constants.TestSourceUrl}\"));\r\n            Assert.True(showResult.StdOut.Contains($\"name: {Constants.TestSourceName}\"));\r\n\r\n            Assert.True(showResult.StdOut.Contains(\"Microsoft.WinGet.Dev/Package\"));\r\n            Assert.True(showResult.StdOut.Contains($\"[{Constants.TestSourceName}_AppInstallerTest.TestPackageExport]\"));\r\n            Assert.True(showResult.StdOut.Contains($\"Dependencies: {Constants.TestSourceName}_{Constants.TestSourceType}\"));\r\n            Assert.True(showResult.StdOut.Contains(\"id: AppInstallerTest.TestPackageExport\"));\r\n            Assert.True(showResult.StdOut.Contains($\"source: {Constants.TestSourceName}\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Export a specific package with related configuration.\r\n        /// </summary>\r\n        [Test]\r\n        public void ExportTestPackageWithPackageSettings()\r\n        {\r\n            var exportDir = TestCommon.GetRandomTestDir();\r\n            var exportFile = Path.Combine(exportDir, \"exported.yml\");\r\n            var result = TestCommon.RunAICLICommand(Command, $\"--package-id AppInstallerTest.TestPackageExport --module AppInstallerTest --resource TestResource -o {exportFile}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(File.Exists(exportFile));\r\n\r\n            // Check exported file is readable and validate content\r\n            var showResult = TestCommon.RunAICLICommand(ShowCommand, $\"-f {exportFile}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, showResult.ExitCode);\r\n            Assert.True(showResult.StdOut.Contains(\"Microsoft.WinGet.Dev/Source\"));\r\n            Assert.True(showResult.StdOut.Contains($\"[{Constants.TestSourceName}_{Constants.TestSourceType}]\"));\r\n            Assert.True(showResult.StdOut.Contains($\"type: {Constants.TestSourceType}\"));\r\n            Assert.True(showResult.StdOut.Contains($\"argument: {Constants.TestSourceUrl}\"));\r\n            Assert.True(showResult.StdOut.Contains($\"name: {Constants.TestSourceName}\"));\r\n\r\n            Assert.True(showResult.StdOut.Contains(\"Microsoft.WinGet.Dev/Package\"));\r\n            Assert.True(showResult.StdOut.Contains($\"[{Constants.TestSourceName}_AppInstallerTest.TestPackageExport]\"));\r\n            Assert.True(showResult.StdOut.Contains($\"Dependencies: {Constants.TestSourceName}_{Constants.TestSourceType}\"));\r\n            Assert.True(showResult.StdOut.Contains(\"id: AppInstallerTest.TestPackageExport\"));\r\n            Assert.True(showResult.StdOut.Contains($\"source: {Constants.TestSourceName}\"));\r\n\r\n            Assert.True(showResult.StdOut.Contains(\"AppInstallerTest/TestResource\"));\r\n            Assert.True(showResult.StdOut.Contains($\"Dependencies: {Constants.TestSourceName}_AppInstallerTest.TestPackageExport\"));\r\n            Assert.True(showResult.StdOut.Contains(\"data: TestData\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Export a specific package with version.\r\n        /// </summary>\r\n        [Test]\r\n        public void ExportTestPackageWithVersion()\r\n        {\r\n            var exportDir = TestCommon.GetRandomTestDir();\r\n            var exportFile = Path.Combine(exportDir, \"exported.yml\");\r\n            var result = TestCommon.RunAICLICommand(Command, $\"--package-id AppInstallerTest.TestPackageExport --include-versions -o {exportFile}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(File.Exists(exportFile));\r\n\r\n            // Check exported file is readable and validate content\r\n            var showResult = TestCommon.RunAICLICommand(ShowCommand, $\"-f {exportFile}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, showResult.ExitCode);\r\n            Assert.True(showResult.StdOut.Contains(\"Microsoft.WinGet.Dev/Source\"));\r\n            Assert.True(showResult.StdOut.Contains($\"[{Constants.TestSourceName}_{Constants.TestSourceType}]\"));\r\n            Assert.True(showResult.StdOut.Contains($\"type: {Constants.TestSourceType}\"));\r\n            Assert.True(showResult.StdOut.Contains($\"argument: {Constants.TestSourceUrl}\"));\r\n            Assert.True(showResult.StdOut.Contains($\"name: {Constants.TestSourceName}\"));\r\n\r\n            Assert.True(showResult.StdOut.Contains(\"Microsoft.WinGet.Dev/Package\"));\r\n            Assert.True(showResult.StdOut.Contains($\"[{Constants.TestSourceName}_AppInstallerTest.TestPackageExport]\"));\r\n            Assert.True(showResult.StdOut.Contains($\"Dependencies: {Constants.TestSourceName}_{Constants.TestSourceType}\"));\r\n            Assert.True(showResult.StdOut.Contains(\"id: AppInstallerTest.TestPackageExport\"));\r\n            Assert.True(showResult.StdOut.Contains($\"source: {Constants.TestSourceName}\"));\r\n            Assert.True(showResult.StdOut.Contains(\"version: 1.0.0.0\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Export all.\r\n        /// </summary>\r\n        [Test]\r\n        public void ExportAll()\r\n        {\r\n            var exportDir = TestCommon.GetRandomTestDir();\r\n            var exportFile = Path.Combine(exportDir, \"exported.yml\");\r\n            var result = TestCommon.RunAICLICommand(Command, $\"--all --verbose -o {exportFile}\", timeOut: 1200000);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(File.Exists(exportFile));\r\n\r\n            // Check exported file is readable and validate content\r\n            var showResult = TestCommon.RunAICLICommand(ShowCommand, $\"-f {exportFile}\", timeOut: 1200000);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, showResult.ExitCode);\r\n\r\n            Assert.True(showResult.StdOut.Contains(\"Microsoft.PowerShell\"));\r\n\r\n            Assert.True(showResult.StdOut.Contains(\"Microsoft.WinGet.Dev/UserSettingsFile\"));\r\n            Assert.True(showResult.StdOut.Contains(\"Microsoft.WinGet.Dev/AdminSettings\"));\r\n            Assert.True(showResult.StdOut.Contains(\"Microsoft.Windows.Settings/WindowsSettings\"));\r\n\r\n            Assert.True(showResult.StdOut.Contains(\"Microsoft.WinGet.Dev/Source\"));\r\n            Assert.True(showResult.StdOut.Contains($\"[{Constants.TestSourceName}_{Constants.TestSourceType}]\"));\r\n            Assert.True(showResult.StdOut.Contains($\"type: {Constants.TestSourceType}\"));\r\n            Assert.True(showResult.StdOut.Contains($\"argument: {Constants.TestSourceUrl}\"));\r\n            Assert.True(showResult.StdOut.Contains($\"name: {Constants.TestSourceName}\"));\r\n\r\n            Assert.True(showResult.StdOut.Contains(\"Microsoft.WinGet.Dev/Package\"));\r\n            Assert.True(showResult.StdOut.Contains($\"[{Constants.TestSourceName}_AppInstallerTest.TestPackageExport]\"));\r\n            Assert.True(showResult.StdOut.Contains($\"Dependencies: {Constants.TestSourceName}_{Constants.TestSourceType}\"));\r\n            Assert.True(showResult.StdOut.Contains(\"id: AppInstallerTest.TestPackageExport\"));\r\n            Assert.True(showResult.StdOut.Contains($\"source: {Constants.TestSourceName}\"));\r\n\r\n            Assert.True(showResult.StdOut.Contains(\"AppInstallerTest/TestResource\"));\r\n            Assert.True(showResult.StdOut.Contains($\"Dependencies: {Constants.TestSourceName}_AppInstallerTest.TestPackageExport\"));\r\n            Assert.True(showResult.StdOut.Contains(\"data: TestData\"));\r\n\r\n            Assert.True(showResult.StdOut.Contains(\"AppInstallerTest/TestResource.SubDirectory\"));\r\n            Assert.True(showResult.StdOut.Contains($\"Dependencies: {Constants.TestSourceName}_AppInstallerTest.TestPackageExport\"));\r\n            Assert.True(showResult.StdOut.Contains(\"data: TestData\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Export a specific package that's not installed.\r\n        /// </summary>\r\n        [Test]\r\n        public void ExportFailedWithNotFoundPackage()\r\n        {\r\n            var exportDir = TestCommon.GetRandomTestDir();\r\n            var exportFile = Path.Combine(exportDir, \"exported.yml\");\r\n            var result = TestCommon.RunAICLICommand(Command, $\"--package-id NotFound.NotFound -o {exportFile}\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Export all with specific package id.\r\n        /// </summary>\r\n        [Test]\r\n        public void ExportFailedWithAllAndSpecificPackage()\r\n        {\r\n            var exportDir = TestCommon.GetRandomTestDir();\r\n            var exportFile = Path.Combine(exportDir, \"exported.yml\");\r\n            var result = TestCommon.RunAICLICommand(Command, $\"--all --package-id AppInstallerTest.TestPackageExport -o {exportFile}\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_INVALID_CL_ARGUMENTS, result.ExitCode);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/ConfigureListCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigureListCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using System.IO;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// `Configure list` command tests.\r\n    /// </summary>\r\n    public class ConfigureListCommand\r\n    {\r\n        private const string ConfigureWithAgreementsAndVerbose = \"configure --accept-configuration-agreements --verbose\";\r\n        private const string ConfigureTestRepoFile = \"Configure_TestRepo.yml\";\r\n\r\n        /// <summary>\r\n        /// Teardown done once after all the tests here.\r\n        /// </summary>\r\n        [OneTimeTearDown]\r\n        public void OneTimeTeardown()\r\n        {\r\n            this.DeleteTxtFiles();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Applies a configuration, then verifies that it is in the overall list.\r\n        /// </summary>\r\n        [Test]\r\n        public void ListAllConfigurations()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(ConfigureWithAgreementsAndVerbose, TestCommon.GetTestDataFile(\"Configuration\\\\Configure_TestRepo.yml\"));\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            result = TestCommon.RunAICLICommand(\"configure list\", \"--verbose\");\r\n            Assert.AreEqual(0, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(ConfigureTestRepoFile));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Applies a configuration (to ensure at least one exists), gets the overall list, then the details about the first configuration.\r\n        /// </summary>\r\n        [Test]\r\n        public void ListSpecificConfiguration()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(ConfigureWithAgreementsAndVerbose, TestCommon.GetTestDataFile(\"Configuration\\\\Configure_TestRepo.yml\"));\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            string guid = TestCommon.GetConfigurationInstanceIdentifierFor(ConfigureTestRepoFile);\r\n            result = TestCommon.RunAICLICommand(\"configure list\", $\"-h {guid}\");\r\n            Assert.AreEqual(0, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(guid));\r\n            Assert.True(result.StdOut.Contains(ConfigureTestRepoFile));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Applies a configuration (to ensure at least one exists), gets the overall list, then the removes the first configuration.\r\n        /// </summary>\r\n        [Test]\r\n        public void RemoveConfiguration()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(ConfigureWithAgreementsAndVerbose, TestCommon.GetTestDataFile(\"Configuration\\\\Configure_TestRepo.yml\"));\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            string guid = TestCommon.GetConfigurationInstanceIdentifierFor(ConfigureTestRepoFile);\r\n            result = TestCommon.RunAICLICommand(\"configure list\", $\"-h {guid} --remove\");\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            result = TestCommon.RunAICLICommand(\"configure list\", \"--verbose\");\r\n            Assert.AreEqual(0, result.ExitCode);\r\n            Assert.False(result.StdOut.Contains(guid));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Applies a configuration (to ensure at least one exists), gets the overall list, then the outputs the first configuration.\r\n        /// </summary>\r\n        [Test]\r\n        public void OutputConfiguration()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(ConfigureWithAgreementsAndVerbose, TestCommon.GetTestDataFile(\"Configuration\\\\Configure_TestRepo.yml\"));\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            string guid = TestCommon.GetConfigurationInstanceIdentifierFor(ConfigureTestRepoFile);\r\n            string tempFile = TestCommon.GetRandomTestFile(\".yml\");\r\n            result = TestCommon.RunAICLICommand(\"configure list\", $\"-h {guid} --output {tempFile}\");\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            result = TestCommon.RunAICLICommand(\"configure validate\", $\"--verbose {tempFile}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_FALSE, result.ExitCode);\r\n        }\r\n\r\n        private void DeleteTxtFiles()\r\n        {\r\n            // Delete all .txt files in the test directory; they are placed there by the tests\r\n            foreach (string file in Directory.GetFiles(TestCommon.GetTestDataFile(\"Configuration\"), \"*.txt\"))\r\n            {\r\n                File.Delete(file);\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/ConfigureShowCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigureShowCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using System.IO;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using Microsoft.Win32;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// `Configure show` command tests.\r\n    /// </summary>\r\n    public class ConfigureShowCommand\r\n    {\r\n        /// <summary>\r\n        /// Setup done once before all the tests here.\r\n        /// </summary>\r\n        [OneTimeSetUp]\r\n        public void OneTimeSetup()\r\n        {\r\n            this.DeleteResourceArtifacts();\r\n            ConfigureCommand.EnsureTestResourcePresence();\r\n        }\r\n\r\n        /// <summary>\r\n        /// One time teardown.\r\n        /// </summary>\r\n        [OneTimeTearDown]\r\n        public void OneTimeTearDown()\r\n        {\r\n            this.DeleteResourceArtifacts();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Simple test to confirm that a resource without a module specified can be discovered in the PSGallery.\r\n        /// </summary>\r\n        [Test]\r\n        [Ignore(\"PS Gallery tests are unreliable.\")]\r\n        public void ShowDetailsFromGallery()\r\n        {\r\n            TestCommon.EnsureModuleState(Constants.GalleryTestModuleName, present: false);\r\n\r\n            var result = TestCommon.RunAICLICommand(\"configure show\", $\"{TestCommon.GetTestDataFile(\"Configuration\\\\PSGallery_NoModule_NoSettings.yml\")} --verbose\", timeOut: 120000);\r\n            Assert.AreEqual(0, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(Constants.PSGalleryName));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Simple test to confirm that a resource with a module specified can be discovered in a local repository that doesn't support resource discovery.\r\n        /// </summary>\r\n        [Test]\r\n        public void ShowDetailsFromTestRepo()\r\n        {\r\n            TestCommon.EnsureModuleState(Constants.SimpleTestModuleName, present: false);\r\n\r\n            var result = TestCommon.RunAICLICommand(\"configure show\", $\"{TestCommon.GetTestDataFile(\"Configuration\\\\ShowDetails_TestRepo.yml\")} --verbose\");\r\n            Assert.AreEqual(0, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(Constants.TestRepoName));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Simple test to confirm that a resource that is already locally available shows that way.\r\n        /// </summary>\r\n        /// <param name=\"location\">The location the module should be before running.</param>\r\n        [TestCase(TestCommon.TestModuleLocation.CurrentUser)]\r\n        [TestCase(TestCommon.TestModuleLocation.AllUsers)]\r\n        [TestCase(TestCommon.TestModuleLocation.WinGetModulePath)]\r\n        [TestCase(TestCommon.TestModuleLocation.Custom)]\r\n        public void ShowDetailsFromLocal(TestCommon.TestModuleLocation location)\r\n        {\r\n            TestCommon.EnsureModuleState(Constants.SimpleTestModuleName, present: true, repository: Constants.TestRepoName, location: location);\r\n\r\n            string args = $\"{TestCommon.GetTestDataFile(\"Configuration\\\\ShowDetails_TestRepo.yml\")} --verbose\";\r\n            if (location == TestCommon.TestModuleLocation.Custom)\r\n            {\r\n                args += \" --module-path \" + TestCommon.GetExpectedModulePath(location);\r\n            }\r\n\r\n            var result = TestCommon.RunAICLICommand(\"configure show\", args);\r\n            Assert.AreEqual(0, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(Constants.LocalModuleDescriptor));\r\n        }\r\n\r\n        /// <summary>\r\n        /// A schema 0.3 config file is allowed with the experimental feature.\r\n        /// </summary>\r\n        [Test]\r\n        public void ShowDetails_Schema0_3_Succeeds()\r\n        {\r\n            TestCommon.EnsureModuleState(Constants.SimpleTestModuleName, present: false);\r\n\r\n            var result = TestCommon.RunAICLICommand(\"configure show\", $\"{TestCommon.GetTestDataFile(\"Configuration\\\\ShowDetails_TestRepo_0_3.yml\")} --verbose\");\r\n            Assert.AreEqual(0, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(Constants.TestRepoName));\r\n        }\r\n\r\n        /// <summary>\r\n        /// A schema 0.3 config file with parameters is blocked.\r\n        /// </summary>\r\n        [Test]\r\n        public void ShowDetails_Schema0_3_Parameters()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"configure show\", TestCommon.GetTestDataFile(\"Configuration\\\\WithParameters_0_3.yml\"));\r\n            Assert.AreEqual(0, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Failed to get detailed information about the configuration.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Simple test to show details from a https configuration file.\r\n        /// </summary>\r\n        [Test]\r\n        public void ShowDetailsFromHttpsConfigurationFile()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"configure show\", $\"{Constants.TestSourceUrl}/TestData/Configuration/ShowDetails_TestRepo.yml --verbose\");\r\n            Assert.AreEqual(0, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(Constants.TestRepoName));\r\n        }\r\n\r\n        /// <summary>\r\n        /// This test ensures that there is not significant overflow from large strings in the configuration file.\r\n        /// </summary>\r\n        [Test]\r\n        public void ShowTruncatedDetailsAndFileContent()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"configure show\", $\"{TestCommon.GetTestDataFile(\"Configuration\\\\LargeContentStrings.yml\")} --verbose\");\r\n            Assert.AreEqual(0, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"<this value has been truncated; inspect the file contents for the complete text>\"));\r\n            Assert.True(result.StdOut.Contains(\"Some of the data present in the configuration file was truncated for this output; inspect the file contents for the complete content.\"));\r\n            Assert.False(result.StdOut.Contains(\"Line5\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Runs a configuration, then shows it from history.\r\n        /// </summary>\r\n        [Test]\r\n        public void ShowFromHistory()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"configure --accept-configuration-agreements --verbose\", TestCommon.GetTestDataFile(\"Configuration\\\\Configure_TestRepo.yml\"));\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            string guid = TestCommon.GetConfigurationInstanceIdentifierFor(\"Configure_TestRepo.yml\");\r\n            result = TestCommon.RunAICLICommand(\"configure show\", $\"-h {guid}\");\r\n            Assert.AreEqual(0, result.ExitCode);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Runs a configuration, then shows it from history.\r\n        /// </summary>\r\n        [Test]\r\n        public void ShowWithBadProcessorIdentifier()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"configure show\", $\"{TestCommon.GetTestDataFile(\"Configuration\\\\Unknown_Processor.yml\")} --verbose\");\r\n            Assert.AreEqual(Constants.ErrorCode.CONFIG_ERROR_INVALID_FIELD_VALUE, result.ExitCode);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Simple test to confirm that a resource is discoverable with DSC v3.\r\n        /// </summary>\r\n        [Test]\r\n        public void ShowDetails_DSCv3()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"configure show\", $\"{TestCommon.GetTestDataFile(\"Configuration\\\\ShowDetails_DSCv3.yml\")} --verbose\");\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            var outputLines = result.StdOut.Split('\\n');\r\n            int startLine = -1;\r\n            for (int i = 0; i < outputLines.Length; ++i)\r\n            {\r\n                if (outputLines[i].Trim() == \"Microsoft.WinGet.Dev/TestFile [Test File]\")\r\n                {\r\n                    startLine = i;\r\n                }\r\n            }\r\n\r\n            Assert.AreNotEqual(-1, startLine);\r\n            Assert.LessOrEqual(3, outputLines.Length - startLine);\r\n\r\n            // outputLines[1] should contain the discovered resource string if working properly.\r\n            Assert.AreEqual(\"Description 1.\", outputLines[startLine + 2].Trim());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Runs a DSCv3 configuration, then shows it from history.\r\n        /// </summary>\r\n        [Test]\r\n        public void ShowFromHistory_DSCv3()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"configure --accept-configuration-agreements --verbose\", TestCommon.GetTestDataFile(\"Configuration\\\\ShowDetails_DSCv3.yml\"));\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            string guid = TestCommon.GetConfigurationInstanceIdentifierFor(\"ShowDetails_DSCv3.yml\");\r\n            result = TestCommon.RunAICLICommand(\"configure show\", $\"-h {guid} --\");\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            var outputLines = result.StdOut.Split('\\n');\r\n            int startLine = -1;\r\n            for (int i = 0; i < outputLines.Length; ++i)\r\n            {\r\n                if (outputLines[i].Trim() == \"Microsoft.WinGet.Dev/TestFile [Test File]\")\r\n                {\r\n                    startLine = i;\r\n                }\r\n            }\r\n\r\n            Assert.AreNotEqual(-1, startLine);\r\n            Assert.LessOrEqual(3, outputLines.Length - startLine);\r\n\r\n            // outputLines[1] should contain the discovered resource string if working properly.\r\n            Assert.AreEqual(\"Description 1.\", outputLines[startLine + 2].Trim());\r\n        }\r\n\r\n        private void DeleteResourceArtifacts()\r\n        {\r\n            // Delete all .txt files in the test directory; they are placed there by the tests\r\n            foreach (string file in Directory.GetFiles(TestCommon.GetTestDataFile(\"Configuration\"), \"*.txt\"))\r\n            {\r\n                File.Delete(file);\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/ConfigureTestCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigureTestCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using System.IO;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using Microsoft.Win32;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// `Configure test` command tests.\r\n    /// </summary>\r\n    public class ConfigureTestCommand\r\n    {\r\n        private const string CommandAndAgreements = \"configure test --accept-configuration-agreements\";\r\n\r\n        /// <summary>\r\n        /// Setup done once before all the tests here.\r\n        /// </summary>\r\n        [OneTimeSetUp]\r\n        public void OneTimeSetup()\r\n        {\r\n            this.DeleteResourceArtifacts();\r\n            ConfigureCommand.EnsureTestResourcePresence();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Teardown done once after all the tests here.\r\n        /// </summary>\r\n        [OneTimeTearDown]\r\n        public void OneTimeTeardown()\r\n        {\r\n            this.DeleteResourceArtifacts();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Checks for a resource not in the desired state.\r\n        /// </summary>\r\n        [Test]\r\n        public void ConfigureTest_NotInDesiredState()\r\n        {\r\n            TestCommon.EnsureModuleState(Constants.SimpleTestModuleName, present: false);\r\n            this.DeleteResourceArtifacts();\r\n\r\n            var result = TestCommon.RunAICLICommand(CommandAndAgreements, TestCommon.GetTestDataFile(\"Configuration\\\\Configure_TestRepo.yml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.S_FALSE, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"System is not in the described configuration state.\"));\r\n            Assert.True(result.StdOut.Contains(\"Module: xE2ETestResource\")); // Details from the resource should appear if the initial details are shown\r\n        }\r\n\r\n        /// <summary>\r\n        /// Checks for a resource in a desired state.\r\n        /// </summary>\r\n        [Test]\r\n        public void ConfigureTest_InDesiredState()\r\n        {\r\n            TestCommon.EnsureModuleState(Constants.SimpleTestModuleName, present: false);\r\n            this.DeleteResourceArtifacts();\r\n\r\n            // Set up the expected state\r\n            File.WriteAllText(TestCommon.GetTestDataFile(\"Configuration\\\\Configure_TestRepo.txt\"), \"Contents!\");\r\n\r\n            var result = TestCommon.RunAICLICommand(CommandAndAgreements, TestCommon.GetTestDataFile(\"Configuration\\\\Configure_TestRepo.yml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"System is in the described configuration state.\"));\r\n            Assert.True(result.StdOut.Contains(\"Module: xE2ETestResource\")); // Details from the resource should appear if the initial details are shown\r\n        }\r\n\r\n        /// <summary>\r\n        /// One resource fails.\r\n        /// </summary>\r\n        [Test]\r\n        public void ConfigureTest_TestFailure()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(CommandAndAgreements, TestCommon.GetTestDataFile(\"Configuration\\\\IndependentResources_OneFailure.yml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.CONFIG_ERROR_TEST_FAILED, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Some of the configuration units failed while testing their state.\"));\r\n            Assert.True(result.StdOut.Contains(\"System is not in the described configuration state.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test from https configuration file.\r\n        /// </summary>\r\n        [Test]\r\n        public void ConfigureTest_HttpsConfigurationFile()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(CommandAndAgreements, $\"{Constants.TestSourceUrl}/TestData/Configuration/Configure_TestRepo_Location.yml\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"System is in the described configuration state.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Runs a configuration, then tests it from history.\r\n        /// </summary>\r\n        [Test]\r\n        public void TestFromHistory()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"configure --accept-configuration-agreements --verbose\", TestCommon.GetTestDataFile(\"Configuration\\\\Configure_TestRepo.yml\"));\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            // The configuration creates a file next to itself with the given contents\r\n            string targetFilePath = TestCommon.GetTestDataFile(\"Configuration\\\\Configure_TestRepo.txt\");\r\n            FileAssert.Exists(targetFilePath);\r\n            Assert.AreEqual(\"Contents!\", File.ReadAllText(targetFilePath));\r\n\r\n            string guid = TestCommon.GetConfigurationInstanceIdentifierFor(\"Configure_TestRepo.yml\");\r\n            result = TestCommon.RunAICLICommand(CommandAndAgreements, $\"-h {guid}\");\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            File.WriteAllText(targetFilePath, \"Changed contents!\");\r\n\r\n            result = TestCommon.RunAICLICommand(CommandAndAgreements, $\"-h {guid}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_FALSE, result.ExitCode);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Simple test to confirm that a resource is testable with DSC v3.\r\n        /// </summary>\r\n        [Test]\r\n        public void ConfigureTest_DSCv3()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(CommandAndAgreements, $\"{TestCommon.GetTestDataFile(\"Configuration\\\\ShowDetails_DSCv3.yml\")} --verbose\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_FALSE, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"System is not in the described configuration state.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests that --suppress-initial-details will suppress the initial details output.\r\n        /// </summary>\r\n        [Test]\r\n        public void ConfigureTest_SuppressInitialDetails()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"configure --accept-configuration-agreements --suppress-initial-details\", TestCommon.GetTestDataFile(\"Configuration\\\\Configure_TestRepo.yml\"));\r\n            Assert.AreEqual(0, result.ExitCode);\r\n            Assert.False(result.StdOut.Contains(\"Module: xE2ETestResource\")); // Details from the resource should not appear if the initial details are suppressed\r\n        }\r\n\r\n        private void DeleteResourceArtifacts()\r\n        {\r\n            // Delete all .txt files in the test directory; they are placed there by the tests\r\n            foreach (string file in Directory.GetFiles(TestCommon.GetTestDataFile(\"Configuration\"), \"*.txt\"))\r\n            {\r\n                File.Delete(file);\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/ConfigureValidateCommand.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigureValidateCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// `Configure validate` command tests.\r\n    /// </summary>\r\n    public class ConfigureValidateCommand\r\n    {\r\n        private const string Command = \"configure validate\";\r\n\r\n        /// <summary>\r\n        /// Set up.\r\n        /// </summary>\r\n        [OneTimeSetUp]\r\n        public void BaseSetup()\r\n        {\r\n            TestCommon.SetupTestSource(false);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tear down.\r\n        /// </summary>\r\n        [OneTimeTearDown]\r\n        public void BaseTeardown()\r\n        {\r\n            TestCommon.TearDownTestSource();\r\n        }\r\n\r\n        /// <summary>\r\n        /// The configuration file is empty.\r\n        /// </summary>\r\n        [Test]\r\n        public void EmptyFile()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(Command, TestCommon.GetTestDataFile(\"Configuration\\\\Empty.yml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.CONFIG_ERROR_INVALID_YAML, result.ExitCode);\r\n        }\r\n\r\n        /// <summary>\r\n        /// The configuration file is not configuration YAML.\r\n        /// </summary>\r\n        [Test]\r\n        public void NotConfigurationYAML()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(Command, TestCommon.GetTestDataFile(\"Configuration\\\\NotConfig.yml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.CONFIG_ERROR_MISSING_FIELD, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"$schema\"));\r\n            Assert.True(result.StdOut.Contains(\"missing\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// The configuration file does not specify the schema version.\r\n        /// </summary>\r\n        [Test]\r\n        public void NoVersion()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(Command, TestCommon.GetTestDataFile(\"Configuration\\\\NoVersion.yml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.CONFIG_ERROR_MISSING_FIELD, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"configurationVersion\"));\r\n            Assert.True(result.StdOut.Contains(\"missing\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// The configuration file schema version is not known.\r\n        /// </summary>\r\n        [Test]\r\n        public void UnknownVersion()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(Command, TestCommon.GetTestDataFile(\"Configuration\\\\UnknownVersion.yml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Configuration file version\"));\r\n            Assert.True(result.StdOut.Contains(\"is not known.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// The resources node is not the correct type in YAML.\r\n        /// </summary>\r\n        [Test]\r\n        public void ResourcesIsWrongType()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(Command, TestCommon.GetTestDataFile(\"Configuration\\\\ResourcesNotASequence.yml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.CONFIG_ERROR_INVALID_FIELD_TYPE, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"resources\"));\r\n            Assert.True(result.StdOut.Contains(\"wrong type\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// The unit node is not the correct type in YAML.\r\n        /// </summary>\r\n        [Test]\r\n        public void UnitIsWrongType()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(Command, TestCommon.GetTestDataFile(\"Configuration\\\\UnitNotAMap.yml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.CONFIG_ERROR_INVALID_FIELD_TYPE, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"resources[0]\"));\r\n            Assert.True(result.StdOut.Contains(\"wrong type\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// The resource name is missing.\r\n        /// </summary>\r\n        [Test]\r\n        public void NoResourceName()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(Command, TestCommon.GetTestDataFile(\"Configuration\\\\NoResourceName.yml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.CONFIG_ERROR_INVALID_FIELD_VALUE, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"resource\"));\r\n            Assert.True(result.StdOut.Contains(\"invalid value\"));\r\n            Assert.True(result.StdOut.Contains(\"Module/\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// The resource name module does not match the directives module.\r\n        /// </summary>\r\n        [Test]\r\n        public void ModuleMismatch()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(Command, TestCommon.GetTestDataFile(\"Configuration\\\\ModuleMismatch.yml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.CONFIG_ERROR_INVALID_FIELD_VALUE, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"module\"));\r\n            Assert.True(result.StdOut.Contains(\"invalid value\"));\r\n            Assert.True(result.StdOut.Contains(\"DifferentModule\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// The configuration contains multiple resources with the same identifier.\r\n        /// </summary>\r\n        [Test]\r\n        public void DuplicateIdentifiers()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(Command, TestCommon.GetTestDataFile(\"Configuration\\\\DuplicateIdentifiers.yml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.CONFIG_ERROR_DUPLICATE_IDENTIFIER, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"The configuration contains the identifier `same` multiple times.\"));\r\n            Assert.False(result.StdOut.Contains(\"NotMentioned\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// The configuration does not contain the dependency.\r\n        /// </summary>\r\n        [Test]\r\n        public void MissingDependency()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(Command, TestCommon.GetTestDataFile(\"Configuration\\\\MissingDependency.yml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.CONFIG_ERROR_MISSING_DEPENDENCY, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"The dependency `missing` was not found within the configuration.\"));\r\n            Assert.False(result.StdOut.Contains(\"xE2ETestResource\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// The configuration contains a dependency cycle.\r\n        /// </summary>\r\n        [Test]\r\n        public void DependencyCycle()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(Command, TestCommon.GetTestDataFile(\"Configuration\\\\DependencyCycle.yml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.CONFIG_ERROR_SET_DEPENDENCY_CYCLE, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"This configuration unit is part of a dependency cycle.\"));\r\n            Assert.False(result.StdOut.Contains(\"NotMentioned\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// The configuration unit is not available in a public catalog.\r\n        /// </summary>\r\n        [Test]\r\n        public void ResourceIsNotPublic()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(Command, TestCommon.GetTestDataFile(\"Configuration\\\\Configure_TestRepo.yml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.S_FALSE, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"not available publicly\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// The configuration unit is not found.\r\n        /// </summary>\r\n        [Test]\r\n        public void ResourceIsNotFound()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(Command, TestCommon.GetTestDataFile(\"Configuration\\\\ResourceNotFound.yml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.S_FALSE, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"The configuration unit could not be found.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// The module was not provided.\r\n        /// </summary>\r\n        [Test]\r\n        public void ModuleNotProvided()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(Command, TestCommon.GetTestDataFile(\"Configuration\\\\PSGallery_NoModule_NoSettings.yml\"), timeOut: 120000);\r\n            Assert.AreEqual(Constants.ErrorCode.S_FALSE, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"The module was not provided.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// No issues detected (yet).\r\n        /// </summary>\r\n        [Test]\r\n        public void NoIssuesDetected()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(Command, TestCommon.GetTestDataFile(\"Configuration\\\\PSGallery_NoSettings.yml\"), timeOut: 120000);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Validation found no issues.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// No issues detected (yet) from https configuration file.\r\n        /// </summary>\r\n        [Test]\r\n        public void NoIssuesDetected_HttpsConfigurationFile()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(Command, $\"{Constants.TestSourceUrl}/TestData/Configuration/PSGallery_NoSettings.yml\", timeOut: 120000);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Validation found no issues.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// No issues detected from WinGet resource units.\r\n        /// </summary>\r\n        [Test]\r\n        public void NoIssuesDetected_WinGetDscResource()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(Command, TestCommon.GetTestDataFile(\"Configuration\\\\WinGetDscResourceValidate_Good.yml\"), timeOut: 120000);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Validation found no issues.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// No issues detected from WinGet resource units.\r\n        /// </summary>\r\n        [Test]\r\n        public void ValidateWinGetDscResource_DependencySourceMissing()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(Command, TestCommon.GetTestDataFile(\"Configuration\\\\WinGetDscResourceValidate_DependencySourceMissing.yml\"), timeOut: 120000);\r\n            Assert.AreEqual(Constants.ErrorCode.S_FALSE, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"WinGetPackage configuration unit package depends on a third-party source not previously configured. Package Id: AppInstallerTest.TestExeInstaller; Source: TestSource\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// No issues detected from WinGet resource units.\r\n        /// </summary>\r\n        [Test]\r\n        public void ValidateWinGetDscResource_PackageNotFound()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(Command, TestCommon.GetTestDataFile(\"Configuration\\\\WinGetDscResourceValidate_PackageNotFound.yml\"), timeOut: 120000);\r\n            Assert.AreEqual(Constants.ErrorCode.S_FALSE, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"WinGetPackage configuration unit package cannot be validated. Package not found. Package Id: AppInstallerTest.DoesNotExist\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// No issues detected from WinGet resource units.\r\n        /// </summary>\r\n        [Test]\r\n        public void ValidateWinGetDscResource_PackageVersionNotFound()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(Command, TestCommon.GetTestDataFile(\"Configuration\\\\WinGetDscResourceValidate_PackageVersionNotFound.yml\"), timeOut: 120000);\r\n            Assert.AreEqual(Constants.ErrorCode.S_FALSE, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"WinGetPackage configuration unit package cannot be validated. Package version not found. Package Id: AppInstallerTest.TestExeInstaller; Version 101.0.101.0\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// No issues detected from WinGet resource units.\r\n        /// </summary>\r\n        [Test]\r\n        public void ValidateWinGetDscResource_SourceOpenFailed()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(Command, TestCommon.GetTestDataFile(\"Configuration\\\\WinGetDscResourceValidate_SourceOpenFailed.yml\"), timeOut: 120000);\r\n            Assert.AreEqual(Constants.ErrorCode.S_FALSE, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"WinGetPackage configuration unit package cannot be validated. Source open failed. Package Id: AppInstallerTest.TestExeInstaller; Source: TestSourceV2\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// No issues detected from WinGet resource units.\r\n        /// </summary>\r\n        [Test]\r\n        public void ValidateWinGetDscResource_VersionSpecifiedWithOnlyOneVersionAvailable()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(Command, TestCommon.GetTestDataFile(\"Configuration\\\\WinGetDscResourceValidate_VersionSpecifiedWithOnlyOneVersionAvailable.yml\"), timeOut: 120000);\r\n            Assert.AreEqual(Constants.ErrorCode.S_FALSE, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"WinGetPackage configuration unit package specified with a specific version while only one package version is available. Package Id: AppInstallerTest.TestValidManifest; Version: 1.0.0.0\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// No issues detected from WinGet resource units.\r\n        /// </summary>\r\n        [Test]\r\n        public void ValidateWinGetDscResource_VersionSpecifiedWithUseLatest()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(Command, TestCommon.GetTestDataFile(\"Configuration\\\\WinGetDscResourceValidate_VersionSpecifiedWithUseLatest.yml\"), timeOut: 120000);\r\n            Assert.AreEqual(Constants.ErrorCode.S_FALSE, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"WinGetPackage declares both UseLatest and Version. Package Id: AppInstallerTest.TestExeInstaller\"));\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/Constants.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"Constants.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    /// <summary>\r\n    /// Constants.\r\n    /// </summary>\r\n    public class Constants\r\n    {\r\n#pragma warning disable SA1600 // ElementsMustBeDocumented\r\n#pragma warning disable SA1310 // Field names should not contain underscore\r\n\r\n        // Runtime test parameters\r\n        public const string PackagedContextParameter = \"PackagedContext\";\r\n        public const string AICLIPathParameter = \"AICLIPath\";\r\n        public const string AICLIPackagePathParameter = \"AICLIPackagePath\";\r\n        public const string VerboseLoggingParameter = \"VerboseLogging\";\r\n        public const string LooseFileRegistrationParameter = \"LooseFileRegistration\";\r\n        public const string InvokeCommandInDesktopPackageParameter = \"InvokeCommandInDesktopPackage\";\r\n        public const string StaticFileRootPathParameter = \"StaticFileRootPath\";\r\n        public const string LocalServerCertPathParameter = \"LocalServerCertPath\";\r\n        public const string ExeInstallerPathParameter = \"ExeTestInstallerPath\";\r\n        public const string MsiInstallerPathParameter = \"MsiTestInstallerPath\";\r\n        public const string MsiInstallerV2PathParameter = \"MsiTestInstallerV2Path\";\r\n        public const string MsixInstallerPathParameter = \"MsixTestInstallerPath\";\r\n        public const string FontPathParameter = \"FontTestPath\";\r\n        public const string PackageCertificatePathParameter = \"PackageCertificatePath\";\r\n        public const string PowerShellModulePathParameter = \"PowerShellModulePath\";\r\n        public const string SkipTestSourceParameter = \"SkipTestSource\";\r\n        public const string ForcedExperimentalFeaturesParameter = \"ForcedExperimentalFeatures\";\r\n        public const string InprocTestbedPathParameter = \"InprocTestbedPath\";\r\n        public const string InprocTestbedUseTestPackageParameter = \"InprocTestbedUseTestPackage\";\r\n\r\n        // Test Sources\r\n        public const string DefaultWingetSourceName = @\"winget\";\r\n        public const string DefaultWingetSourceUrl = @\"https://winget.azureedge.net/cache\";\r\n        public const string DefaultMSStoreSourceName = @\"msstore\";\r\n        public const string DefaultMSStoreSourceUrl = @\"https://storeedgefd.dsx.mp.microsoft.com/v9.0\";\r\n        public const string DefaultMSStoreSourceType = \"Microsoft.Rest\";\r\n        public const string DefaultMSStoreSourceIdentifier = \"StoreEdgeFD\";\r\n        public const string TestSourceName = @\"TestSource\";\r\n        public const string TestAlternateSourceName = @\"TestSource2\";\r\n        public const string TestSourceUrl = @\"https://localhost:5001/TestKit\";\r\n        public const string TestSourceType = \"Microsoft.PreIndexed.Package\";\r\n        public const string TestSourceIdentifier = @\"WingetE2E.Tests_8wekyb3d8bbwe\";\r\n\r\n        public const string AICLIPackageFamilyName = \"WinGetDevCLI_8wekyb3d8bbwe\";\r\n        public const string AICLIPackageName = \"WinGetDevCLI\";\r\n        public const string AICLIPackagePublisherHash = \"8wekyb3d8bbwe\";\r\n        public const string AICLIAppId = \"WinGetDev\";\r\n\r\n        public const string TestPackage = \"TëstPackage.msix\";\r\n        public const string ExeInstaller = \"AppInstallerTestExeInstaller\";\r\n        public const string MsiInstaller = \"AppInstallerTestMsiInstaller\";\r\n        public const string MsixInstaller = \"AppInstallerTestMsixInstaller\";\r\n        public const string ZipInstaller = \"AppInstallerTestZipInstaller\";\r\n        public const string ExeInstallerFileName = \"AppInstallerTestExeInstaller.exe\";\r\n        public const string MsiInstallerFileName = \"AppInstallerTestMsiInstaller.msi\";\r\n        public const string MsiInstallerV2FileName = \"AppInstallerTestMsiInstallerV2.msi\";\r\n        public const string MsixInstallerFileName = \"AppInstallerTestMsixInstaller.msix\";\r\n        public const string ZipInstallerFileName = \"AppInstallerTestZipInstaller.zip\";\r\n        public const string FontFileName = \"AppInstallerTestFont.ttf\";\r\n        public const string ModifyRepairInstaller = \"AppInstallerTest.TestModifyRepair\";\r\n        public const string IndexPackage = \"source.msix\";\r\n        public const string MakeAppx = \"makeappx.exe\";\r\n        public const string SignTool = \"signtool.exe\";\r\n        public const string IndexCreationTool = \"IndexCreationTool\";\r\n        public const string WinGetUtil = \"WinGetUtil\";\r\n        public const string E2ETestLogsPathPackaged = @\"Packages\\WinGetDevCLI_8wekyb3d8bbwe\\LocalState\\DiagOutputDir\";\r\n        public const string E2ETestLogsPathUnpackaged = @\"WinGet\\defaultState\";\r\n        public const string CheckpointDirectoryPackaged = @\"Packages\\WinGetDevCLI_8wekyb3d8bbwe\\LocalState\\Checkpoints\";\r\n        public const string CheckpointDirectoryUnpackaged = @\"Microsoft\\WinGet\\State\\defaultState\\Checkpoints\";\r\n\r\n        // Installer filename\r\n        public const string TestCommandExe = \"testCommand.exe\";\r\n        public const string AppInstallerTestExeInstallerExe = \"AppInstallerTestExeInstaller.exe\";\r\n        public const string AppInstallerTestMsiInstallerMsi = \"AppInstallerTestMsiInstaller.msi\";\r\n        public const string AppInstallerTestZipInstallerZip = \"AppInstallerTestZipInstaller.zip\";\r\n\r\n        // Test installers' package IDs\r\n        public const string ExeInstallerPackageId = \"AppInstallerTest.TestExeInstaller\";\r\n        public const string MsiInstallerPackageId = \"AppInstallerTest.TestMsiInstaller\";\r\n        public const string MsixInstallerPackageId = \"AppInstallerTest.TestMsixInstaller\";\r\n        public const string PortableExePackageId = \"AppInstallerTest.TestPortableExe\";\r\n        public const string PortableExeWithCommandPackageId = \"AppInstallerTest.TestPortableExeWithCommand\";\r\n\r\n        public const string ExeInstalledDefaultProductCode = \"{A499DD5E-8DC5-4AD2-911A-BCD0263295E9}\";\r\n        public const string MsiInstallerProductCode = \"{A5D36CF1-1993-4F63-BFB4-3ACD910D36A1}\";\r\n        public const string MsixInstallerName = \"6c6338fe-41b7-46ca-8ba6-b5ad5312bb0e\";\r\n        public const string MsixInstallerPackageFamilyName = \"6c6338fe-41b7-46ca-8ba6-b5ad5312bb0e_8wekyb3d8bbwe\";\r\n\r\n        public const string TestExeInstalledFileName = \"TestExeInstalled.txt\";\r\n        public const string TestExeUninstallerFileName = \"UninstallTestExe.bat\";\r\n        public const string TestExeUninstalledFileName = \"TestExeUninstalled.txt\";\r\n        public const string TestExeRepairCompletedFileName = \"TestExeRepairCompleted.txt\";\r\n\r\n        // PowerShell Cmdlets\r\n        public const string FindCmdlet = \"Find-WinGetPackage\";\r\n        public const string GetCmdlet = \"Get-WinGetPackage\";\r\n        public const string GetSourceCmdlet = \"Get-WinGetSource\";\r\n        public const string InstallCmdlet = \"Install-WinGetPackage\";\r\n        public const string UninstallCmdlet = \"Uninstall-WinGetPackage\";\r\n        public const string UpdateCmdlet = \"Update-WinGetPackage\";\r\n\r\n        public const string WindowsPackageManagerServer = \"WindowsPackageManagerServer\";\r\n\r\n        // Locations\r\n        public const string LocalAppData = \"LocalAppData\";\r\n        public const string Dependencies = \"Dependencies\";\r\n\r\n        // Package dir\r\n        public const string PortableExePackageDirName = $\"{PortableExePackageId}_{TestSourceIdentifier}\";\r\n        public const string PortableExeWithCommandPackageDirName = $\"{PortableExeWithCommandPackageId}_{TestSourceIdentifier}\";\r\n\r\n        // Registry keys\r\n        public const string WinGetPackageIdentifier = \"WinGetPackageIdentifier\";\r\n        public const string WinGetSourceIdentifier = \"WinGetSourceIdentifier\";\r\n        public const string UninstallSubKey = @\"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\";\r\n        public const string PathSubKey_User = @\"Environment\";\r\n        public const string PathSubKey_Machine = @\"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment\";\r\n        public const string FontsSubKey = @\"Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts\";\r\n\r\n        // User settings\r\n        public const string ArchiveExtractionMethod = \"archiveExtractionMethod\";\r\n        public const string PortablePackageUserRoot = \"portablePackageUserRoot\";\r\n        public const string PortablePackageMachineRoot = \"portablePackageMachineRoot\";\r\n        public const string InstallBehaviorScope = \"scope\";\r\n        public const string InstallerTypes = \"installerTypes\";\r\n        public const string DefaultModuleRoot = \"defaultModuleRoot\";\r\n\r\n        // Configuration\r\n        public const string PSGalleryName = \"PSGallery\";\r\n        public const string TestRepoName = \"AppInstallerCLIE2ETestsRepo\";\r\n        public const string GalleryTestModuleName = \"XmlContentDsc\";\r\n        public const string SimpleTestModuleName = \"xE2ETestResource\";\r\n        public const string LocalModuleDescriptor = \"[Local]\";\r\n        public const string TestRegistryPath = \"Software\\\\Microsoft\\\\WinGet\\\\Tests\";\r\n\r\n        // Group Policy Error Message\r\n        public const string BlockByWinGetPolicyErrorMessage = \"This operation is disabled by Group Policy : Enable Windows Package Manager\";\r\n\r\n        /// <summary>\r\n        /// Error codes.\r\n        /// </summary>\r\n        public class ErrorCode\r\n        {\r\n            public const int S_OK = 0;\r\n            public const int S_FALSE = 1;\r\n            public const int ERROR_FILE_NOT_FOUND = unchecked((int)0x80070002);\r\n            public const int ERROR_PATH_NOT_FOUND = unchecked((int)0x80070003);\r\n            public const int E_INVALIDARG = unchecked((int)0x80070057);\r\n            public const int ERROR_NO_RANGES_PROCESSED = unchecked((int)0x80070138);\r\n            public const int OPC_E_ZIP_MISSING_END_OF_CENTRAL_DIRECTORY = unchecked((int)0x8051100F);\r\n            public const int ERROR_OLD_WIN_VERSION = unchecked((int)0x8007047E);\r\n            public const int HTTP_E_STATUS_NOT_FOUND = unchecked((int)0x80190194);\r\n            public const int E_ABORT = unchecked((int)0x80004004);\r\n\r\n            // AICLI custom HRESULTs\r\n            public const int ERROR_INTERNAL_ERROR = unchecked((int)0x8A150001);\r\n            public const int ERROR_INVALID_CL_ARGUMENTS = unchecked((int)0x8A150002);\r\n            public const int ERROR_COMMAND_FAILED = unchecked((int)0x8A150003);\r\n            public const int ERROR_MANIFEST_FAILED = unchecked((int)0x8A150004);\r\n            public const int ERROR_CTRL_SIGNAL_RECEIVED = unchecked((int)0x8A150005);\r\n            public const int ERROR_SHELLEXEC_INSTALL_FAILED = unchecked((int)0x8A150006);\r\n            public const int ERROR_UNSUPPORTED_MANIFESTVERSION = unchecked((int)0x8A150007);\r\n            public const int ERROR_DOWNLOAD_FAILED = unchecked((int)0x8A150008);\r\n            public const int ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX = unchecked((int)0x8A150009);\r\n            public const int ERROR_INDEX_INTEGRITY_COMPROMISED = unchecked((int)0x8A15000A);\r\n            public const int ERROR_SOURCES_INVALID = unchecked((int)0x8A15000B);\r\n            public const int ERROR_SOURCE_NAME_ALREADY_EXISTS = unchecked((int)0x8A15000C);\r\n            public const int ERROR_INVALID_SOURCE_TYPE = unchecked((int)0x8A15000D);\r\n            public const int ERROR_PACKAGE_IS_BUNDLE = unchecked((int)0x8A15000E);\r\n            public const int ERROR_SOURCE_DATA_MISSING = unchecked((int)0x8A15000F);\r\n            public const int ERROR_NO_APPLICABLE_INSTALLER = unchecked((int)0x8A150010);\r\n            public const int ERROR_INSTALLER_HASH_MISMATCH = unchecked((int)0x8A150011);\r\n            public const int ERROR_SOURCE_NAME_DOES_NOT_EXIST = unchecked((int)0x8A150012);\r\n            public const int ERROR_SOURCE_ARG_ALREADY_EXISTS = unchecked((int)0x8A150013);\r\n            public const int ERROR_NO_APPLICATIONS_FOUND = unchecked((int)0x8A150014);\r\n            public const int ERROR_NO_SOURCES_DEFINED = unchecked((int)0x8A150015);\r\n            public const int ERROR_MULTIPLE_APPLICATIONS_FOUND = unchecked((int)0x8A150016);\r\n            public const int ERROR_NO_MANIFEST_FOUND = unchecked((int)0x8A150017);\r\n            public const int ERROR_EXTENSION_PUBLIC_FAILED = unchecked((int)0x8A150018);\r\n            public const int ERROR_COMMAND_REQUIRES_ADMIN = unchecked((int)0x8A150019);\r\n            public const int ERROR_SOURCE_NOT_SECURE = unchecked((int)0x8A15001A);\r\n            public const int ERROR_MSSTORE_BLOCKED_BY_POLICY = unchecked((int)0x8A15001B);\r\n            public const int ERROR_MSSTORE_APP_BLOCKED_BY_POLICY = unchecked((int)0x8A15001C);\r\n            public const int ERROR_EXPERIMENTAL_FEATURE_DISABLED = unchecked((int)0x8A15001D);\r\n            public const int ERROR_MSSTORE_INSTALL_FAILED = unchecked((int)0x8A15001E);\r\n            public const int ERROR_COMPLETE_INPUT_BAD = unchecked((int)0x8A15001F);\r\n            public const int ERROR_YAML_INIT_FAILED = unchecked((int)0x8A150020);\r\n            public const int ERROR_INVALID_MAPPING_KEY = unchecked((int)0x8A150021);\r\n            public const int ERROR_DUPLICATE_MAPPING_KEY = unchecked((int)0x8A150022);\r\n            public const int ERROR_YAML_INVALID_OPERATION = unchecked((int)0x8A150023);\r\n            public const int ERROR_YAML_DOC_BUILD_FAILED = unchecked((int)0x8A150024);\r\n            public const int ERROR_YAML_INVALID_EMITTER_STATE = unchecked((int)0x8A150025);\r\n            public const int ERROR_YAML_INVALID_DATA = unchecked((int)0x8A150026);\r\n            public const int ERROR_LIBYAML_ERROR = unchecked((int)0x8A150027);\r\n            public const int ERROR_MANIFEST_VALIDATION_WARNING = unchecked((int)0x8A150028);\r\n            public const int ERROR_MANIFEST_VALIDATION_FAILURE = unchecked((int)0x8A150029);\r\n            public const int ERROR_INVALID_MANIFEST = unchecked((int)0x8A15002A);\r\n            public const int ERROR_UPDATE_NOT_APPLICABLE = unchecked((int)0x8A15002B);\r\n            public const int ERROR_UPDATE_ALL_HAS_FAILURE = unchecked((int)0x8A15002C);\r\n            public const int ERROR_INSTALLER_SECURITY_CHECK_FAILED = unchecked((int)0x8A15002D);\r\n            public const int ERROR_DOWNLOAD_SIZE_MISMATCH = unchecked((int)0x8A15002E);\r\n            public const int ERROR_NO_UNINSTALL_INFO_FOUND = unchecked((int)0x8A15002F);\r\n            public const int ERROR_EXEC_UNINSTALL_COMMAND_FAILED = unchecked((int)0x8A150030);\r\n            public const int ERROR_ICU_BREAK_ITERATOR_ERROR = unchecked((int)0x8A150031);\r\n            public const int ERROR_ICU_CASEMAP_ERROR = unchecked((int)0x8A150032);\r\n            public const int ERROR_ICU_REGEX_ERROR = unchecked((int)0x8A150033);\r\n            public const int ERROR_IMPORT_INSTALL_FAILED = unchecked((int)0x8A150034);\r\n            public const int ERROR_NOT_ALL_PACKAGES_FOUND = unchecked((int)0x8A150035);\r\n            public const int ERROR_JSON_INVALID_FILE = unchecked((int)0x8A150036);\r\n            public const int ERROR_SOURCE_NOT_REMOTE = unchecked((int)0x8A150037);\r\n            public const int ERROR_UNSUPPORTED_RESTSOURCE = unchecked((int)0x8A150038);\r\n            public const int ERROR_RESTSOURCE_INVALID_DATA = unchecked((int)0x8A150039);\r\n            public const int ERROR_BLOCKED_BY_POLICY = unchecked((int)0x8A15003A);\r\n            public const int ERROR_RESTAPI_INTERNAL_ERROR = unchecked((int)0x8A15003B);\r\n            public const int ERROR_RESTSOURCE_INVALID_URL = unchecked((int)0x8A15003C);\r\n            public const int ERROR_RESTAPI_UNSUPPORTED_MIME_TYPE = unchecked((int)0x8A15003D);\r\n            public const int ERROR_RESTSOURCE_INVALID_VERSION = unchecked((int)0x8A15003E);\r\n            public const int ERROR_SOURCE_DATA_INTEGRITY_FAILURE = unchecked((int)0x8A15003F);\r\n            public const int ERROR_STREAM_READ_FAILURE = unchecked((int)0x8A150040);\r\n            public const int ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED = unchecked((int)0x8A150041);\r\n            public const int ERROR_PROMPT_INPUT_ERROR = unchecked((int)0x8A150042);\r\n            public const int ERROR_UNSUPPORTED_SOURCE_REQUEST = unchecked((int)0x8A150043);\r\n            public const int ERROR_RESTAPI_ENDPOINT_NOT_FOUND = unchecked((int)0x8A150044);\r\n            public const int ERROR_SOURCE_OPEN_FAILED = unchecked((int)0x8A150045);\r\n            public const int ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED = unchecked((int)0x8A150046);\r\n            public const int ERROR_CUSTOMHEADER_EXCEEDS_MAXLENGTH = unchecked((int)0x8A150047);\r\n            public const int ERROR_MISSING_RESOURCE_FILE = unchecked((int)0x8A150048);\r\n            public const int ERROR_MSI_INSTALL_FAILED = unchecked((int)0x8A150049);\r\n            public const int ERROR_INVALID_MSIEXEC_ARGUMENT = unchecked((int)0x8A15004A);\r\n            public const int ERROR_FAILED_TO_OPEN_ALL_SOURCES = unchecked((int)0x8A15004B);\r\n            public const int ERROR_DEPENDENCIES_VALIDATION_FAILED = unchecked((int)0x8A15004C);\r\n            public const int ERROR_MISSING_PACKAGE = unchecked((int)0x8A15004D);\r\n            public const int ERROR_INVALID_TABLE_COLUMN = unchecked((int)0x8A15004E);\r\n            public const int ERROR_UPGRADE_VERSION_NOT_NEWER = unchecked((int)0x8A15004F);\r\n            public const int ERROR_UPGRADE_VERSION_UNKNOWN = unchecked((int)0x8A150050);\r\n            public const int ERROR_ICU_CONVERSION_ERROR = unchecked((int)0x8A150051);\r\n            public const int ERROR_PORTABLE_INSTALL_FAILED = unchecked((int)0x8A150052);\r\n            public const int ERROR_PORTABLE_REPARSE_POINT_NOT_SUPPORTED = unchecked((int)0x8A150053);\r\n            public const int ERROR_PORTABLE_PACKAGE_ALREADY_EXISTS = unchecked((int)0x8A150054);\r\n            public const int ERROR_PORTABLE_SYMLINK_PATH_IS_DIRECTORY = unchecked((int)0x8A150055);\r\n            public const int ERROR_INSTALLER_PROHIBITS_ELEVATION = unchecked((int)0x8A150056);\r\n            public const int ERROR_PORTABLE_UNINSTALL_FAILED = unchecked((int)0x8A150057);\r\n            public const int ERROR_ARP_VERSION_VALIDATION_FAILED = unchecked((int)0x8A150058);\r\n            public const int ERROR_UNSUPPORTED_ARGUMENT = unchecked((int)0x8A150059);\r\n            public const int ERROR_BIND_WITH_EMBEDDED_NULL = unchecked((int)0x8A15005A);\r\n            public const int ERROR_NESTEDINSTALLER_NOT_FOUND = unchecked((int)0x8A15005B);\r\n            public const int ERROR_EXTRACT_ARCHIVE_FAILED = unchecked((int)0x8A15005C);\r\n            public const int ERROR_NESTEDINSTALLER_INVALID_PATH = unchecked((int)0x8A15005D);\r\n            public const int ERROR_PINNED_CERTIFICATE_MISMATCH = unchecked((int)0x8A15005E);\r\n            public const int ERROR_INSTALL_LOCATION_REQUIRED = unchecked((int)0x8A15005F);\r\n            public const int ERROR_ARCHIVE_SCAN_FAILED = unchecked((int)0x8A150060);\r\n            public const int ERROR_PACKAGE_ALREADY_INSTALLED = unchecked((int)0x8A150061);\r\n            public const int ERROR_PIN_ALREADY_EXISTS = unchecked((int)0x8A150062);\r\n            public const int ERROR_PIN_DOES_NOT_EXIST = unchecked((int)0x8A150063);\r\n            public const int ERROR_CANNOT_OPEN_PINNING_INDEX = unchecked((int)0x8A150064);\r\n            public const int ERROR_MULTIPLE_INSTALL_FAILED = unchecked((int)0x8A150065);\r\n            public const int ERROR_MULTIPLE_UNINSTALL_FAILED = unchecked((int)0x8A150066);\r\n            public const int ERROR_NOT_ALL_QUERIES_FOUND_SINGLE = unchecked((int)0x8A150067);\r\n            public const int ERROR_PACKAGE_IS_PINNED = unchecked((int)0x8A150068);\r\n            public const int ERROR_PACKAGE_IS_STUB = unchecked((int)0x8A150069);\r\n            public const int ERROR_APPTERMINATION_RECEIVED = unchecked((int)0x8A15006A);\r\n            public const int ERROR_DOWNLOAD_DEPENDENCIES = unchecked((int)0x8A15006B);\r\n            public const int ERROR_DOWNLOAD_COMMAND_PROHIBITED = unchecked((int)0x8A15006C);\r\n            public const int ERROR_SERVICE_UNAVAILABLE = unchecked((int)0x8A15006D);\r\n            public const int ERROR_RESUME_ID_NOT_FOUND = unchecked((int)0x8A15006E);\r\n            public const int ERROR_CLIENT_VERSION_MISMATCH = unchecked((int)0x8A15006F);\r\n            public const int ERROR_INVALID_RESUME_STATE = unchecked((int)0x8A150070);\r\n            public const int ERROR_CANNOT_OPEN_CHECKPOINT_INDEX = unchecked((int)0x8A150071);\r\n\r\n            public const int ERROR_NO_REPAIR_INFO_FOUND = unchecked((int)0x8A150079);\r\n            public const int ERROR_REPAIR_NOT_SUPPORTED = unchecked((int)0x8A15007C);\r\n            public const int ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED = unchecked((int)0x8A15007D);\r\n\r\n            public const int ERROR_INSTALLER_ZERO_BYTE_FILE = unchecked((int)0x8A150086);\r\n            public const int ERROR_FONT_INSTALL_FAILED = unchecked((int)0x8A150087);\r\n            public const int ERROR_FONT_FILE_NOT_SUPPORTED = unchecked((int)0x8A150088);\r\n\r\n            public const int ERROR_INSTALL_PACKAGE_IN_USE = unchecked((int)0x8A150101);\r\n            public const int ERROR_INSTALL_INSTALL_IN_PROGRESS = unchecked((int)0x8A150102);\r\n            public const int ERROR_INSTALL_FILE_IN_USE = unchecked((int)0x8A150103);\r\n            public const int ERROR_INSTALL_MISSING_DEPENDENCY = unchecked((int)0x8A150104);\r\n            public const int ERROR_INSTALL_DISK_FULL = unchecked((int)0x8A150105);\r\n            public const int ERROR_INSTALL_INSUFFICIENT_MEMORY = unchecked((int)0x8A150106);\r\n            public const int ERROR_INSTALL_NO_NETWORK = unchecked((int)0x8A150107);\r\n            public const int ERROR_INSTALL_CONTACT_SUPPORT = unchecked((int)0x8A150108);\r\n            public const int ERROR_INSTALL_REBOOT_REQUIRED_TO_FINISH = unchecked((int)0x8A150109);\r\n            public const int ERROR_INSTALL_REBOOT_REQUIRED_FOR_INSTALL = unchecked((int)0x8A15010A);\r\n            public const int ERROR_INSTALL_REBOOT_INITIATED = unchecked((int)0x8A15010B);\r\n            public const int ERROR_INSTALL_CANCELLED_BY_USER = unchecked((int)0x8A15010C);\r\n            public const int ERROR_INSTALL_ALREADY_INSTALLED = unchecked((int)0x8A15010D);\r\n            public const int ERROR_INSTALL_DOWNGRADE = unchecked((int)0x8A15010E);\r\n            public const int ERROR_INSTALL_BLOCKED_BY_POLICY = unchecked((int)0x8A15010F);\r\n            public const int ERROR_INSTALL_DEPENDENCIES = unchecked((int)0x8A150110);\r\n            public const int ERROR_INSTALL_PACKAGE_IN_USE_BY_APPLICATION = unchecked((int)0x8A150111);\r\n            public const int ERROR_INSTALL_INVALID_PARAMETER = unchecked((int)0x8A150112);\r\n            public const int ERROR_INSTALL_SYSTEM_NOT_SUPPORTED = unchecked((int)0x8A150113);\r\n            public const int APPINSTALLER_CLI_ERROR_INSTALL_UPGRADE_NOT_SUPPORTED = unchecked((int)0x8A150114);\r\n\r\n            public const int INSTALLED_STATUS_ARP_ENTRY_NOT_FOUND = unchecked((int)0x8A150201);\r\n            public const int INSTALLED_STATUS_INSTALL_LOCATION_NOT_APPLICABLE = unchecked((int)0x0A150202);\r\n            public const int INSTALLED_STATUS_INSTALL_LOCATION_NOT_FOUND = unchecked((int)0x8A150203);\r\n            public const int INSTALLED_STATUS_FILE_HASH_MISMATCH = unchecked((int)0x8A150204);\r\n            public const int INSTALLED_STATUS_FILE_NOT_FOUND = unchecked((int)0x8A150205);\r\n            public const int INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK = unchecked((int)0x0A150206);\r\n            public const int INSTALLED_STATUS_FILE_ACCESS_ERROR = unchecked((int)0x8A150207);\r\n\r\n            public const int CONFIG_ERROR_INVALID_CONFIGURATION_FILE = unchecked((int)0x8A15C001);\r\n            public const int CONFIG_ERROR_INVALID_YAML = unchecked((int)0x8A15C002);\r\n            public const int CONFIG_ERROR_INVALID_FIELD_TYPE = unchecked((int)0x8A15C003);\r\n            public const int CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION = unchecked((int)0x8A15C004);\r\n            public const int CONFIG_ERROR_SET_APPLY_FAILED = unchecked((int)0x8A15C005);\r\n            public const int CONFIG_ERROR_DUPLICATE_IDENTIFIER = unchecked((int)0x8A15C006);\r\n            public const int CONFIG_ERROR_MISSING_DEPENDENCY = unchecked((int)0x8A15C007);\r\n            public const int CONFIG_ERROR_DEPENDENCY_UNSATISFIED = unchecked((int)0x8A15C008);\r\n            public const int CONFIG_ERROR_ASSERTION_FAILED = unchecked((int)0x8A15C009);\r\n            public const int CONFIG_ERROR_MANUALLY_SKIPPED = unchecked((int)0x8A15C00A);\r\n            public const int CONFIG_ERROR_WARNING_NOT_ACCEPTED = unchecked((int)0x8A15C00B);\r\n            public const int CONFIG_ERROR_SET_DEPENDENCY_CYCLE = unchecked((int)0x8A15C00C);\r\n            public const int CONFIG_ERROR_INVALID_FIELD_VALUE = unchecked((int)0x8A15C00D);\r\n            public const int CONFIG_ERROR_MISSING_FIELD = unchecked((int)0x8A15C00E);\r\n            public const int CONFIG_ERROR_TEST_FAILED = unchecked((int)0x8A15C00F);\r\n            public const int CONFIG_ERROR_TEST_NOT_RUN = unchecked((int)0x8A15C010);\r\n            public const int WINGET_CONFIG_ERROR_GET_FAILED = unchecked((int)0x8A15C011);\r\n\r\n            public const int CONFIG_ERROR_UNIT_NOT_INSTALLED = unchecked((int)0x8A15C101);\r\n            public const int CONFIG_ERROR_UNIT_NOT_FOUND_REPOSITORY = unchecked((int)0x8A15C102);\r\n            public const int CONFIG_ERROR_UNIT_MULTIPLE_MATCHES = unchecked((int)0x8A15C103);\r\n            public const int CONFIG_ERROR_UNIT_INVOKE_GET = unchecked((int)0x8A15C104);\r\n            public const int CONFIG_ERROR_UNIT_INVOKE_TEST = unchecked((int)0x8A15C105);\r\n            public const int CONFIG_ERROR_UNIT_INVOKE_SET = unchecked((int)0x8A15C106);\r\n            public const int CONFIG_ERROR_UNIT_MODULE_CONFLICT = unchecked((int)0x8A15C107);\r\n            public const int CONFIG_ERROR_UNIT_IMPORT_MODULE = unchecked((int)0x8A15C108);\r\n            public const int CONFIG_ERROR_UNIT_INVOKE_INVALID_RESULT = unchecked((int)0x8A15C109);\r\n            public const int CONFIG_ERROR_UNIT_SETTING_CONFIG_ROOT = unchecked((int)0x8A15C110);\r\n            public const int CONFIG_ERROR_UNIT_IMPORT_MODULE_ADMIN = unchecked((int)0x8A15C111);\r\n        }\r\n\r\n#pragma warning restore SA1310 // Field names should not contain underscore\r\n#pragma warning restore SA1600 // ElementsMustBeDocumented\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/DSCv3AdminSettingsResourceCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"DSCv3AdminSettingsResourceCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using System.Collections.Generic;\r\n    using System.Text.Json;\r\n    using System.Text.Json.Nodes;\r\n    using System.Text.Json.Serialization;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// `Configure` command tests.\r\n    /// </summary>\r\n    [System.Diagnostics.CodeAnalysis.SuppressMessage(\"StyleCop.CSharp.SpacingRules\", \"SA1010:Opening square brackets should be spaced correctly\", Justification = \"https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3687 pending SC 1.2 release\")]\r\n    [System.Diagnostics.CodeAnalysis.SuppressMessage(\"StyleCop.CSharp.SpacingRules\", \"SA1011:Closing square brackets should be spaced correctly\", Justification = \"https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3687 pending SC 1.2 release\")]\r\n    public class DSCv3AdminSettingsResourceCommand : DSCv3ResourceTestBase\r\n    {\r\n        private const string AdminSettingsResource = \"admin-settings\";\r\n        private const string SettingsPropertyName = \"settings\";\r\n\r\n        // Bool settings\r\n        private const string BypassCertificatePinningForMicrosoftStore = \"BypassCertificatePinningForMicrosoftStore\";\r\n        private const string InstallerHashOverride = \"InstallerHashOverride\";\r\n        private const string LocalArchiveMalwareScanOverride = \"LocalArchiveMalwareScanOverride\";\r\n        private const string LocalManifestFiles = \"LocalManifestFiles\";\r\n        private const string ProxyCommandLineOptions = \"ProxyCommandLineOptions\";\r\n\r\n        // String settings\r\n        private const string DefaultProxy = \"DefaultProxy\";\r\n\r\n        // Not a setting\r\n        private const string NotAnAdminSettingName = \"NotAnAdminSetting\";\r\n\r\n        /// <summary>\r\n        /// Setup done once before all the tests here.\r\n        /// </summary>\r\n        [OneTimeSetUp]\r\n        public void OneTimeSetup()\r\n        {\r\n            EnsureTestResourcePresence();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Teardown done once after all the tests here.\r\n        /// </summary>\r\n        [OneTimeTearDown]\r\n        public void OneTimeTeardown()\r\n        {\r\n            ResetAllSettings();\r\n            GroupPolicyHelper.DeleteExistingPolicies();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Set up.\r\n        /// </summary>\r\n        [SetUp]\r\n        public void Setup()\r\n        {\r\n            ResetAllSettings();\r\n            GroupPolicyHelper.DeleteExistingPolicies();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `get` on the `admin-settings` resource with the value not present.\r\n        /// </summary>\r\n        /// <param name=\"function\">The resource function to invoke.</param>\r\n        [TestCase(GetFunction)]\r\n        [TestCase(ExportFunction)]\r\n        public void AdminSettings_Get(string function)\r\n        {\r\n            var result = RunDSCv3Command(AdminSettingsResource, function, null);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            AdminSettingsResourceData output = GetSingleOutputLineAs<AdminSettingsResourceData>(result.StdOut);\r\n            Assert.IsNotNull(output);\r\n            Assert.IsNotNull(output.Settings);\r\n            Assert.IsTrue(output.Settings.ContainsKey(LocalManifestFiles));\r\n            Assert.IsFalse(output.Settings.ContainsKey(DefaultProxy));\r\n            Assert.IsFalse(output.Settings.ContainsKey(NotAnAdminSettingName));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `test` on the `admin-settings` resource with a bool setting.\r\n        /// </summary>\r\n        /// <param name=\"settingName\">The setting to test.</param>\r\n        [TestCase(BypassCertificatePinningForMicrosoftStore)]\r\n        [TestCase(InstallerHashOverride)]\r\n        [TestCase(LocalArchiveMalwareScanOverride)]\r\n        [TestCase(LocalManifestFiles)]\r\n        [TestCase(ProxyCommandLineOptions)]\r\n        public void AdminSettings_Test_BoolSetting(string settingName)\r\n        {\r\n            AdminSettingsResourceData resourceData = new AdminSettingsResourceData() { Settings = new JsonObject() };\r\n\r\n            resourceData.Settings[settingName] = true;\r\n            var result = RunDSCv3Command(AdminSettingsResource, TestFunction, resourceData);\r\n            AssertTestOfBoolSetting(ref result, settingName, false, true);\r\n\r\n            resourceData.Settings[settingName] = false;\r\n            result = RunDSCv3Command(AdminSettingsResource, TestFunction, resourceData);\r\n            AssertTestOfBoolSetting(ref result, settingName, false, false);\r\n\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, TestCommon.RunAICLICommand(\"settings\", $\"--enable {settingName}\").ExitCode);\r\n\r\n            resourceData.Settings[settingName] = false;\r\n            result = RunDSCv3Command(AdminSettingsResource, TestFunction, resourceData);\r\n            AssertTestOfBoolSetting(ref result, settingName, true, false);\r\n\r\n            resourceData.Settings[settingName] = true;\r\n            result = RunDSCv3Command(AdminSettingsResource, TestFunction, resourceData);\r\n            AssertTestOfBoolSetting(ref result, settingName, true, true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `test` on the `admin-settings` resource with a string setting.\r\n        /// </summary>\r\n        /// <param name=\"settingName\">The setting to test.</param>\r\n        [TestCase(DefaultProxy)]\r\n        public void AdminSettings_Test_StringSetting(string settingName)\r\n        {\r\n            const string testValue = \"A string to test\";\r\n            const string differentTestValue = \"A different value\";\r\n\r\n            AdminSettingsResourceData resourceData = new AdminSettingsResourceData() { Settings = new JsonObject() };\r\n\r\n            resourceData.Settings[settingName] = null;\r\n            var result = RunDSCv3Command(AdminSettingsResource, TestFunction, resourceData);\r\n            AssertTestOfStringSetting(ref result, settingName, null, null);\r\n\r\n            resourceData.Settings[settingName] = testValue;\r\n            result = RunDSCv3Command(AdminSettingsResource, TestFunction, resourceData);\r\n            AssertTestOfStringSetting(ref result, settingName, null, testValue);\r\n\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, TestCommon.RunAICLICommand(\"settings set\", $\"{settingName} \\\"{testValue}\\\"\").ExitCode);\r\n\r\n            resourceData.Settings[settingName] = null;\r\n            result = RunDSCv3Command(AdminSettingsResource, TestFunction, resourceData);\r\n            AssertTestOfStringSetting(ref result, settingName, testValue, null);\r\n\r\n            resourceData.Settings[settingName] = testValue;\r\n            result = RunDSCv3Command(AdminSettingsResource, TestFunction, resourceData);\r\n            AssertTestOfStringSetting(ref result, settingName, testValue, testValue);\r\n\r\n            resourceData.Settings[settingName] = differentTestValue;\r\n            result = RunDSCv3Command(AdminSettingsResource, TestFunction, resourceData);\r\n            AssertTestOfStringSetting(ref result, settingName, testValue, differentTestValue);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `test` on the `admin-settings` resource with a complex input.\r\n        /// </summary>\r\n        [Test]\r\n        public void AdminSettings_Test_Complex()\r\n        {\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, TestCommon.RunAICLICommand(\"settings\", $\"--enable {LocalArchiveMalwareScanOverride}\").ExitCode);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, TestCommon.RunAICLICommand(\"settings\", $\"--enable {LocalManifestFiles}\").ExitCode);\r\n\r\n            AdminSettingsResourceData resourceData = new AdminSettingsResourceData() { Settings = new JsonObject() };\r\n            resourceData.Settings[LocalArchiveMalwareScanOverride] = true;\r\n            resourceData.Settings[BypassCertificatePinningForMicrosoftStore] = false;\r\n            resourceData.Settings[DefaultProxy] = null;\r\n\r\n            var result = RunDSCv3Command(AdminSettingsResource, TestFunction, resourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            (AdminSettingsResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<AdminSettingsResourceData>(result.StdOut);\r\n            Assert.IsNotNull(output);\r\n            Assert.IsTrue(output.InDesiredState);\r\n            Assert.IsNotNull(output.Settings);\r\n\r\n            AssertDiffState(diff, []);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `set` on the `admin-settings` resource with a bool setting.\r\n        /// </summary>\r\n        /// <param name=\"settingName\">The setting to test.</param>\r\n        [TestCase(BypassCertificatePinningForMicrosoftStore)]\r\n        [TestCase(InstallerHashOverride)]\r\n        [TestCase(LocalArchiveMalwareScanOverride)]\r\n        [TestCase(LocalManifestFiles)]\r\n        [TestCase(ProxyCommandLineOptions)]\r\n        public void AdminSettings_Set_BoolSetting(string settingName)\r\n        {\r\n            AdminSettingsResourceData resourceData = new AdminSettingsResourceData() { Settings = new JsonObject() };\r\n\r\n            resourceData.Settings[settingName] = true;\r\n            var result = RunDSCv3Command(AdminSettingsResource, SetFunction, resourceData);\r\n            AssertSetOfBoolSetting(ref result, settingName, false, true);\r\n\r\n            result = RunDSCv3Command(AdminSettingsResource, SetFunction, resourceData);\r\n            AssertSetOfBoolSetting(ref result, settingName, true, true);\r\n\r\n            resourceData.Settings[settingName] = false;\r\n            result = RunDSCv3Command(AdminSettingsResource, SetFunction, resourceData);\r\n            AssertSetOfBoolSetting(ref result, settingName, true, false);\r\n\r\n            result = RunDSCv3Command(AdminSettingsResource, SetFunction, resourceData);\r\n            AssertSetOfBoolSetting(ref result, settingName, false, false);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `set` on the `admin-settings` resource with a string setting.\r\n        /// </summary>\r\n        /// <param name=\"settingName\">The setting to test.</param>\r\n        [TestCase(DefaultProxy)]\r\n        public void AdminSettings_Set_StringSetting(string settingName)\r\n        {\r\n            const string testValue = \"A string to test\";\r\n            const string differentTestValue = \"A different value\";\r\n\r\n            AdminSettingsResourceData resourceData = new AdminSettingsResourceData() { Settings = new JsonObject() };\r\n\r\n            resourceData.Settings[settingName] = null;\r\n            var result = RunDSCv3Command(AdminSettingsResource, SetFunction, resourceData);\r\n            AssertSetOfStringSetting(ref result, settingName, null, null);\r\n\r\n            resourceData.Settings[settingName] = testValue;\r\n            result = RunDSCv3Command(AdminSettingsResource, SetFunction, resourceData);\r\n            AssertSetOfStringSetting(ref result, settingName, null, testValue);\r\n\r\n            resourceData.Settings[settingName] = testValue;\r\n            result = RunDSCv3Command(AdminSettingsResource, SetFunction, resourceData);\r\n            AssertSetOfStringSetting(ref result, settingName, testValue, testValue);\r\n\r\n            resourceData.Settings[settingName] = differentTestValue;\r\n            result = RunDSCv3Command(AdminSettingsResource, SetFunction, resourceData);\r\n            AssertSetOfStringSetting(ref result, settingName, testValue, differentTestValue);\r\n\r\n            resourceData.Settings[settingName] = null;\r\n            result = RunDSCv3Command(AdminSettingsResource, SetFunction, resourceData);\r\n            AssertSetOfStringSetting(ref result, settingName, differentTestValue, null);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `set` on the `admin-settings` resource with a complex input.\r\n        /// </summary>\r\n        [Test]\r\n        public void AdminSettings_Set_Complex()\r\n        {\r\n            const string testValue = \"A string to test\";\r\n\r\n            AdminSettingsResourceData resourceData = new AdminSettingsResourceData() { Settings = new JsonObject() };\r\n            resourceData.Settings[LocalArchiveMalwareScanOverride] = true;\r\n            resourceData.Settings[BypassCertificatePinningForMicrosoftStore] = false;\r\n            resourceData.Settings[DefaultProxy] = testValue;\r\n\r\n            var result = RunDSCv3Command(AdminSettingsResource, SetFunction, resourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            (AdminSettingsResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<AdminSettingsResourceData>(result.StdOut);\r\n            Assert.IsNotNull(output);\r\n            Assert.IsNotNull(output.Settings);\r\n            Assert.AreEqual(JsonValueKind.True, output.Settings[LocalArchiveMalwareScanOverride].AsValue().GetValueKind());\r\n            Assert.AreEqual(JsonValueKind.False, output.Settings[BypassCertificatePinningForMicrosoftStore].AsValue().GetValueKind());\r\n            Assert.AreEqual(testValue, output.Settings[DefaultProxy].AsValue().GetValue<string>());\r\n\r\n            AssertDiffState(diff, [ SettingsPropertyName ]);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `set` on the `admin-settings` resource attempting to change a setting with group policy enabled.\r\n        /// </summary>\r\n        [Test]\r\n        public void AdminSettings_Set_GroupPolicyBlocked()\r\n        {\r\n            GroupPolicyHelper.EnableHashOverride.Disable();\r\n\r\n            AdminSettingsResourceData resourceData = new AdminSettingsResourceData() { Settings = new JsonObject() };\r\n            resourceData.Settings[InstallerHashOverride] = true;\r\n\r\n            var result = RunDSCv3Command(AdminSettingsResource, SetFunction, resourceData);\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, result.ExitCode);\r\n        }\r\n\r\n        private static void ResetAllSettings()\r\n        {\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, TestCommon.RunAICLICommand(\"settings reset\", \"--all\").ExitCode);\r\n        }\r\n\r\n        private static void AssertTestOfBoolSetting(ref TestCommon.RunCommandResult result, string settingName, bool expectedState, bool testState)\r\n        {\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            bool inDesiredState = expectedState == testState;\r\n\r\n            (AdminSettingsResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<AdminSettingsResourceData>(result.StdOut);\r\n            Assert.IsNotNull(output);\r\n            Assert.AreEqual(inDesiredState, output.InDesiredState);\r\n            Assert.IsNotNull(output.Settings);\r\n            Assert.IsTrue(output.Settings.ContainsKey(settingName));\r\n            Assert.AreEqual(expectedState ? JsonValueKind.True : JsonValueKind.False, output.Settings[settingName].AsValue().GetValueKind());\r\n\r\n            AssertDiffState(diff, inDesiredState ? [] : [ SettingsPropertyName ]);\r\n        }\r\n\r\n        private static void AssertSetOfBoolSetting(ref TestCommon.RunCommandResult result, string settingName, bool previousState, bool desiredState)\r\n        {\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            bool inDesiredState = previousState == desiredState;\r\n\r\n            (AdminSettingsResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<AdminSettingsResourceData>(result.StdOut);\r\n            Assert.IsNotNull(output);\r\n            Assert.IsNotNull(output.Settings);\r\n            Assert.IsTrue(output.Settings.ContainsKey(settingName));\r\n            Assert.AreEqual(desiredState ? JsonValueKind.True : JsonValueKind.False, output.Settings[settingName].AsValue().GetValueKind());\r\n\r\n            AssertDiffState(diff, inDesiredState ? [] : [ SettingsPropertyName ]);\r\n        }\r\n\r\n        private static void AssertTestOfStringSetting(ref TestCommon.RunCommandResult result, string settingName, string expectedState, string testState)\r\n        {\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            bool inDesiredState = expectedState == testState;\r\n\r\n            (AdminSettingsResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<AdminSettingsResourceData>(result.StdOut);\r\n            Assert.IsNotNull(output);\r\n            Assert.AreEqual(inDesiredState, output.InDesiredState);\r\n            Assert.IsNotNull(output.Settings);\r\n            if (expectedState != null)\r\n            {\r\n                Assert.IsTrue(output.Settings.ContainsKey(settingName));\r\n                Assert.AreEqual(expectedState, output.Settings[settingName].AsValue().GetValue<string>());\r\n            }\r\n            else\r\n            {\r\n                Assert.IsFalse(output.Settings.ContainsKey(settingName));\r\n            }\r\n\r\n            AssertDiffState(diff, inDesiredState ? [] : [SettingsPropertyName]);\r\n        }\r\n\r\n        private static void AssertSetOfStringSetting(ref TestCommon.RunCommandResult result, string settingName, string previousState, string desiredState)\r\n        {\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            bool inDesiredState = previousState == desiredState;\r\n\r\n            (AdminSettingsResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<AdminSettingsResourceData>(result.StdOut);\r\n            Assert.IsNotNull(output);\r\n            Assert.IsNotNull(output.Settings);\r\n            if (desiredState != null)\r\n            {\r\n                Assert.IsTrue(output.Settings.ContainsKey(settingName));\r\n                Assert.AreEqual(desiredState, output.Settings[settingName].AsValue().GetValue<string>());\r\n            }\r\n            else\r\n            {\r\n                Assert.IsFalse(output.Settings.ContainsKey(settingName));\r\n            }\r\n\r\n            AssertDiffState(diff, inDesiredState ? [] : [SettingsPropertyName]);\r\n        }\r\n\r\n        private class AdminSettingsResourceData\r\n        {\r\n            [JsonPropertyName(InDesiredStatePropertyName)]\r\n            public bool? InDesiredState { get; set; }\r\n\r\n            public JsonObject Settings { get; set; }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/DSCv3PackageResourceCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"DSCv3PackageResourceCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using System.Collections.Generic;\r\n    using System.Text.Json.Serialization;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// `Configure` command tests.\r\n    /// </summary>\r\n    [System.Diagnostics.CodeAnalysis.SuppressMessage(\"StyleCop.CSharp.SpacingRules\", \"SA1010:Opening square brackets should be spaced correctly\", Justification = \"https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3687 pending SC 1.2 release\")]\r\n    [System.Diagnostics.CodeAnalysis.SuppressMessage(\"StyleCop.CSharp.SpacingRules\", \"SA1011:Closing square brackets should be spaced correctly\", Justification = \"https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3687 pending SC 1.2 release\")]\r\n    public class DSCv3PackageResourceCommand : DSCv3ResourceTestBase\r\n    {\r\n        private const string DefaultPackageIdentifier = Constants.ExeInstallerPackageId;\r\n        private const string DefaultPackageLowVersion = \"1.0.0.0\";\r\n        private const string DefaultPackageMidVersion = \"1.1.0.0\";\r\n        private const string DefaultPackageHighVersion = \"2.0.0.0\";\r\n        private const string PackageResource = \"package\";\r\n        private const string VersionPropertyName = \"version\";\r\n        private const string UseLatestPropertyName = \"useLatest\";\r\n\r\n        /// <summary>\r\n        /// Setup done once before all the tests here.\r\n        /// </summary>\r\n        [OneTimeSetUp]\r\n        public void OneTimeSetup()\r\n        {\r\n            TestCommon.SetupTestSource();\r\n            WinGetSettingsHelper.ConfigureLoggingLevel(\"verbose\");\r\n            EnsureTestResourcePresence();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Teardown done once after all the tests here.\r\n        /// </summary>\r\n        [OneTimeTearDown]\r\n        public void OneTimeTeardown()\r\n        {\r\n            RemoveTestPackage();\r\n            WinGetSettingsHelper.ConfigureLoggingLevel(null);\r\n            TestCommon.TearDownTestSource();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Set up.\r\n        /// </summary>\r\n        [SetUp]\r\n        public void Setup()\r\n        {\r\n            // Try clean up TestExeInstaller for failure cases where cleanup is not successful\r\n            RemoveTestPackage();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `get` on the `package` resource with the value not present.\r\n        /// </summary>\r\n        [Test]\r\n        public void Package_Get_NotPresent()\r\n        {\r\n            PackageResourceData packageResourceData = new PackageResourceData() { Identifier = DefaultPackageIdentifier };\r\n\r\n            var result = RunDSCv3Command(PackageResource, GetFunction, packageResourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            PackageResourceData output = GetSingleOutputLineAs<PackageResourceData>(result.StdOut);\r\n            Assert.IsNotNull(output);\r\n            Assert.False(output.Exist);\r\n            Assert.AreEqual(packageResourceData.Identifier, output.Identifier);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `get` on the `package` resource with the package not existing.\r\n        /// </summary>\r\n        [Test]\r\n        public void Package_Get_UnknownIdentifier()\r\n        {\r\n            PackageResourceData packageResourceData = new PackageResourceData() { Identifier = \"Not.An.Existing.Identifier.123456789.ABCDEFG\" };\r\n\r\n            var result = RunDSCv3Command(PackageResource, GetFunction, packageResourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            PackageResourceData output = GetSingleOutputLineAs<PackageResourceData>(result.StdOut);\r\n            Assert.IsNotNull(output);\r\n            Assert.False(output.Exist);\r\n            Assert.AreEqual(packageResourceData.Identifier, output.Identifier);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `get` on the `package` resource with the value present.\r\n        /// </summary>\r\n        [Test]\r\n        public void Package_Get_Present()\r\n        {\r\n            var setupInstall = TestCommon.RunAICLICommand(\"install\", $\"--id {DefaultPackageIdentifier} --version {DefaultPackageLowVersion}\");\r\n            Assert.AreEqual(0, setupInstall.ExitCode);\r\n\r\n            PackageResourceData packageResourceData = new PackageResourceData() { Identifier = DefaultPackageIdentifier };\r\n\r\n            var result = RunDSCv3Command(PackageResource, GetFunction, packageResourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            PackageResourceData output = GetSingleOutputLineAs<PackageResourceData>(result.StdOut);\r\n            AssertExistingPackageResourceData(output, DefaultPackageLowVersion);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `get` on the `package` resource with the value present and supplying most inputs.\r\n        /// </summary>\r\n        [Test]\r\n        public void Package_Get_MuchInput()\r\n        {\r\n            var setupInstall = TestCommon.RunAICLICommand(\"install\", $\"--id {DefaultPackageIdentifier} --version {DefaultPackageLowVersion}\");\r\n            Assert.AreEqual(0, setupInstall.ExitCode);\r\n\r\n            PackageResourceData packageResourceData = new PackageResourceData()\r\n            {\r\n                Identifier = DefaultPackageIdentifier,\r\n                Source = Constants.TestSourceName,\r\n                MatchOption = \"equals\",\r\n            };\r\n\r\n            var result = RunDSCv3Command(PackageResource, GetFunction, packageResourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            PackageResourceData output = GetSingleOutputLineAs<PackageResourceData>(result.StdOut);\r\n            AssertExistingPackageResourceData(output, DefaultPackageLowVersion);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `test` on the `package` resource with the value not present.\r\n        /// </summary>\r\n        [Test]\r\n        public void Package_Test_NotPresent()\r\n        {\r\n            PackageResourceData packageResourceData = new PackageResourceData() { Identifier = DefaultPackageIdentifier };\r\n\r\n            var result = RunDSCv3Command(PackageResource, TestFunction, packageResourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            (PackageResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<PackageResourceData>(result.StdOut);\r\n            Assert.IsNotNull(output);\r\n            Assert.False(output.Exist);\r\n            Assert.AreEqual(packageResourceData.Identifier, output.Identifier);\r\n            Assert.False(output.InDesiredState);\r\n\r\n            AssertDiffState(diff, [ ExistPropertyName ]);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `test` on the `package` resource with the value present.\r\n        /// </summary>\r\n        [Test]\r\n        public void Package_Test_SimplePresent()\r\n        {\r\n            var setupInstall = TestCommon.RunAICLICommand(\"install\", $\"--id {DefaultPackageIdentifier} --version {DefaultPackageLowVersion}\");\r\n            Assert.AreEqual(0, setupInstall.ExitCode);\r\n\r\n            PackageResourceData packageResourceData = new PackageResourceData() { Identifier = DefaultPackageIdentifier };\r\n\r\n            var result = RunDSCv3Command(PackageResource, TestFunction, packageResourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            (PackageResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<PackageResourceData>(result.StdOut);\r\n            AssertExistingPackageResourceData(output, DefaultPackageLowVersion);\r\n            Assert.True(output.InDesiredState);\r\n\r\n            AssertDiffState(diff, []);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `test` on the `package` resource with a version that matches.\r\n        /// </summary>\r\n        [Test]\r\n        public void Package_Test_VersionMatch()\r\n        {\r\n            var setupInstall = TestCommon.RunAICLICommand(\"install\", $\"--id {DefaultPackageIdentifier} --version {DefaultPackageLowVersion}\");\r\n            Assert.AreEqual(0, setupInstall.ExitCode);\r\n\r\n            PackageResourceData packageResourceData = new PackageResourceData()\r\n            {\r\n                Identifier = DefaultPackageIdentifier,\r\n                Version = DefaultPackageLowVersion,\r\n            };\r\n\r\n            var result = RunDSCv3Command(PackageResource, TestFunction, packageResourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            (PackageResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<PackageResourceData>(result.StdOut);\r\n            AssertExistingPackageResourceData(output, DefaultPackageLowVersion);\r\n            Assert.True(output.InDesiredState);\r\n\r\n            AssertDiffState(diff, []);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `test` on the `package` resource with a version that does not match.\r\n        /// </summary>\r\n        [Test]\r\n        public void Package_Test_VersionMismatch()\r\n        {\r\n            var setupInstall = TestCommon.RunAICLICommand(\"install\", $\"--id {DefaultPackageIdentifier} --version {DefaultPackageLowVersion}\");\r\n            Assert.AreEqual(0, setupInstall.ExitCode);\r\n\r\n            PackageResourceData packageResourceData = new PackageResourceData()\r\n            {\r\n                Identifier = DefaultPackageIdentifier,\r\n                Version = DefaultPackageMidVersion,\r\n            };\r\n\r\n            var result = RunDSCv3Command(PackageResource, TestFunction, packageResourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            (PackageResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<PackageResourceData>(result.StdOut);\r\n            AssertExistingPackageResourceData(output, DefaultPackageLowVersion);\r\n            Assert.False(output.InDesiredState);\r\n\r\n            AssertDiffState(diff, [ VersionPropertyName ]);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `test` on the `package` resource with a version that is the latest.\r\n        /// </summary>\r\n        [Test]\r\n        public void Package_Test_Latest()\r\n        {\r\n            var setupInstall = TestCommon.RunAICLICommand(\"install\", $\"--id {DefaultPackageIdentifier}\");\r\n            Assert.AreEqual(0, setupInstall.ExitCode);\r\n\r\n            PackageResourceData packageResourceData = new PackageResourceData()\r\n            {\r\n                Identifier = DefaultPackageIdentifier,\r\n                UseLatest = true,\r\n            };\r\n\r\n            var result = RunDSCv3Command(PackageResource, TestFunction, packageResourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            (PackageResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<PackageResourceData>(result.StdOut);\r\n            AssertExistingPackageResourceData(output, DefaultPackageHighVersion);\r\n            Assert.True(output.InDesiredState);\r\n\r\n            AssertDiffState(diff, []);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `test` on the `package` resource with a version that is not the latest.\r\n        /// </summary>\r\n        [Test]\r\n        public void Package_Test_NotLatest()\r\n        {\r\n            var setupInstall = TestCommon.RunAICLICommand(\"install\", $\"--id {DefaultPackageIdentifier} --version {DefaultPackageMidVersion}\");\r\n            Assert.AreEqual(0, setupInstall.ExitCode);\r\n\r\n            PackageResourceData packageResourceData = new PackageResourceData()\r\n            {\r\n                Identifier = DefaultPackageIdentifier,\r\n                UseLatest = true,\r\n            };\r\n\r\n            var result = RunDSCv3Command(PackageResource, TestFunction, packageResourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            (PackageResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<PackageResourceData>(result.StdOut);\r\n            AssertExistingPackageResourceData(output, DefaultPackageMidVersion);\r\n            Assert.False(output.InDesiredState);\r\n\r\n            AssertDiffState(diff, [ UseLatestPropertyName ]);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `set` on the `package` resource when the package is not present, and again afterward.\r\n        /// </summary>\r\n        [Test]\r\n        public void Package_Set_SimpleRepeated()\r\n        {\r\n            PackageResourceData packageResourceData = new PackageResourceData()\r\n            {\r\n                Identifier = DefaultPackageIdentifier,\r\n            };\r\n\r\n            var result = RunDSCv3Command(PackageResource, SetFunction, packageResourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            (PackageResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<PackageResourceData>(result.StdOut);\r\n            AssertExistingPackageResourceData(output, DefaultPackageHighVersion, ignoreLatest: true);\r\n\r\n            AssertDiffState(diff, [ ExistPropertyName ]);\r\n\r\n            // Set again should be a no-op\r\n            result = RunDSCv3Command(PackageResource, SetFunction, packageResourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            (output, diff) = GetSingleOutputLineAndDiffAs<PackageResourceData>(result.StdOut);\r\n            AssertExistingPackageResourceData(output, DefaultPackageHighVersion);\r\n\r\n            AssertDiffState(diff, []);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `set` on the `package` resource to ensure that it is not present.\r\n        /// </summary>\r\n        [Test]\r\n        public void Package_Set_Remove()\r\n        {\r\n            var setupInstall = TestCommon.RunAICLICommand(\"install\", $\"--id {DefaultPackageIdentifier}\");\r\n            Assert.AreEqual(0, setupInstall.ExitCode);\r\n\r\n            PackageResourceData packageResourceData = new PackageResourceData()\r\n            {\r\n                Identifier = DefaultPackageIdentifier,\r\n                Exist = false,\r\n            };\r\n\r\n            var result = RunDSCv3Command(PackageResource, SetFunction, packageResourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            (PackageResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<PackageResourceData>(result.StdOut);\r\n            Assert.IsNotNull(output);\r\n            Assert.False(output.Exist);\r\n            Assert.AreEqual(packageResourceData.Identifier, output.Identifier);\r\n\r\n            AssertDiffState(diff, [ ExistPropertyName ]);\r\n\r\n            // Call `get` to ensure the result\r\n            PackageResourceData packageResourceDataForGet = new PackageResourceData()\r\n            {\r\n                Identifier = DefaultPackageIdentifier,\r\n            };\r\n\r\n            result = RunDSCv3Command(PackageResource, GetFunction, packageResourceDataForGet);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            output = GetSingleOutputLineAs<PackageResourceData>(result.StdOut);\r\n            Assert.IsNotNull(output);\r\n            Assert.False(output.Exist);\r\n            Assert.AreEqual(packageResourceDataForGet.Identifier, output.Identifier);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `set` on the `package` resource to request the latest version when a lower version is installed.\r\n        /// </summary>\r\n        [Test]\r\n        public void Package_Set_Latest()\r\n        {\r\n            var setupInstall = TestCommon.RunAICLICommand(\"install\", $\"--id {DefaultPackageIdentifier} --version {DefaultPackageMidVersion}\");\r\n            Assert.AreEqual(0, setupInstall.ExitCode);\r\n\r\n            PackageResourceData packageResourceData = new PackageResourceData()\r\n            {\r\n                Identifier = DefaultPackageIdentifier,\r\n                UseLatest = true,\r\n            };\r\n\r\n            var result = RunDSCv3Command(PackageResource, SetFunction, packageResourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            (PackageResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<PackageResourceData>(result.StdOut);\r\n            AssertExistingPackageResourceData(output, DefaultPackageHighVersion, ignoreLatest: true);\r\n\r\n            AssertDiffState(diff, [ UseLatestPropertyName ]);\r\n\r\n            // Call `get` to ensure the result\r\n            PackageResourceData packageResourceDataForGet = new PackageResourceData()\r\n            {\r\n                Identifier = DefaultPackageIdentifier,\r\n            };\r\n\r\n            result = RunDSCv3Command(PackageResource, GetFunction, packageResourceDataForGet);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            output = GetSingleOutputLineAs<PackageResourceData>(result.StdOut);\r\n            AssertExistingPackageResourceData(output, DefaultPackageHighVersion);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `set` on the `package` resource to request a specific version when a lower version is installed.\r\n        /// </summary>\r\n        [Test]\r\n        public void Package_Set_SpecificVersionUpgrade()\r\n        {\r\n            var setupInstall = TestCommon.RunAICLICommand(\"install\", $\"--id {DefaultPackageIdentifier} --version {DefaultPackageLowVersion}\");\r\n            Assert.AreEqual(0, setupInstall.ExitCode);\r\n\r\n            PackageResourceData packageResourceData = new PackageResourceData()\r\n            {\r\n                Identifier = DefaultPackageIdentifier,\r\n                Version = DefaultPackageMidVersion,\r\n            };\r\n\r\n            var result = RunDSCv3Command(PackageResource, SetFunction, packageResourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            (PackageResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<PackageResourceData>(result.StdOut);\r\n            AssertExistingPackageResourceData(output, DefaultPackageMidVersion, ignoreLatest: true);\r\n\r\n            AssertDiffState(diff, [ VersionPropertyName ]);\r\n\r\n            // Call `get` to ensure the result\r\n            PackageResourceData packageResourceDataForGet = new PackageResourceData()\r\n            {\r\n                Identifier = DefaultPackageIdentifier,\r\n            };\r\n\r\n            result = RunDSCv3Command(PackageResource, GetFunction, packageResourceDataForGet);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            output = GetSingleOutputLineAs<PackageResourceData>(result.StdOut);\r\n            AssertExistingPackageResourceData(output, DefaultPackageMidVersion);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `set` on the `package` resource to request a specific version when a higher version is installed.\r\n        /// </summary>\r\n        [Test]\r\n        public void Package_Set_SpecificVersionDowngrade()\r\n        {\r\n            var setupInstall = TestCommon.RunAICLICommand(\"install\", $\"--id {DefaultPackageIdentifier}\");\r\n            Assert.AreEqual(0, setupInstall.ExitCode);\r\n\r\n            PackageResourceData packageResourceData = new PackageResourceData()\r\n            {\r\n                Identifier = DefaultPackageIdentifier,\r\n                Version = DefaultPackageMidVersion,\r\n            };\r\n\r\n            var result = RunDSCv3Command(PackageResource, SetFunction, packageResourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            (PackageResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<PackageResourceData>(result.StdOut);\r\n            AssertExistingPackageResourceData(output, DefaultPackageMidVersion, ignoreLatest: true);\r\n\r\n            AssertDiffState(diff, [ VersionPropertyName ]);\r\n\r\n            // Call `get` to ensure the result\r\n            PackageResourceData packageResourceDataForGet = new PackageResourceData()\r\n            {\r\n                Identifier = DefaultPackageIdentifier,\r\n            };\r\n\r\n            result = RunDSCv3Command(PackageResource, GetFunction, packageResourceDataForGet);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            output = GetSingleOutputLineAs<PackageResourceData>(result.StdOut);\r\n            AssertExistingPackageResourceData(output, DefaultPackageMidVersion);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `export` on the `package` resource without providing any input.\r\n        /// </summary>\r\n        [Test]\r\n        public void Package_Export_NoInput()\r\n        {\r\n            var setupInstall = TestCommon.RunAICLICommand(\"install\", $\"--id {DefaultPackageIdentifier}\");\r\n            Assert.AreEqual(0, setupInstall.ExitCode);\r\n\r\n            var result = RunDSCv3Command(PackageResource, ExportFunction, \" \");\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            List<PackageResourceData> output = GetOutputLinesAs<PackageResourceData>(result.StdOut);\r\n\r\n            bool foundDefaultPackage = false;\r\n            foreach (PackageResourceData item in output)\r\n            {\r\n                if (item.Identifier == DefaultPackageIdentifier)\r\n                {\r\n                    foundDefaultPackage = true;\r\n                    Assert.IsNull(item.Version);\r\n                    break;\r\n                }\r\n            }\r\n\r\n            Assert.IsTrue(foundDefaultPackage);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `export` on the `package` resource providing input to request that versions be included.\r\n        /// </summary>\r\n        [Test]\r\n        public void Package_Export_RequestVersions()\r\n        {\r\n            var setupInstall = TestCommon.RunAICLICommand(\"install\", $\"--id {DefaultPackageIdentifier} --version {DefaultPackageLowVersion}\");\r\n            Assert.AreEqual(0, setupInstall.ExitCode);\r\n\r\n            PackageResourceData packageResourceData = new PackageResourceData()\r\n            {\r\n                UseLatest = false,\r\n            };\r\n\r\n            var result = RunDSCv3Command(PackageResource, ExportFunction, packageResourceData, 300000);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            List<PackageResourceData> output = GetOutputLinesAs<PackageResourceData>(result.StdOut);\r\n\r\n            bool foundDefaultPackage = false;\r\n            foreach (PackageResourceData item in output)\r\n            {\r\n                if (item.Identifier == DefaultPackageIdentifier)\r\n                {\r\n                    foundDefaultPackage = true;\r\n                    Assert.AreEqual(DefaultPackageLowVersion, item.Version);\r\n                }\r\n                else\r\n                {\r\n                    Assert.IsNotNull(item.Version);\r\n                    Assert.IsNotEmpty(item.Version);\r\n                }\r\n            }\r\n\r\n            Assert.IsTrue(foundDefaultPackage);\r\n        }\r\n\r\n        private static void RemoveTestPackage()\r\n        {\r\n            PackageResourceData packageResourceData = new PackageResourceData()\r\n            {\r\n                Identifier = DefaultPackageIdentifier,\r\n                Exist = false,\r\n            };\r\n\r\n            var result = RunDSCv3Command(PackageResource, SetFunction, packageResourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n        }\r\n\r\n        private static void AssertExistingPackageResourceData(PackageResourceData output, string version, bool ignoreLatest = false)\r\n        {\r\n            Assert.IsNotNull(output);\r\n            Assert.True(output.Exist);\r\n            Assert.AreEqual(DefaultPackageIdentifier, output.Identifier);\r\n            Assert.AreEqual(version, output.Version);\r\n\r\n            if (!ignoreLatest)\r\n            {\r\n                if (version == DefaultPackageHighVersion)\r\n                {\r\n                    Assert.True(output.UseLatest);\r\n                }\r\n                else\r\n                {\r\n                    Assert.False(output.UseLatest);\r\n                }\r\n            }\r\n        }\r\n\r\n        private class PackageResourceData\r\n        {\r\n            [JsonPropertyName(ExistPropertyName)]\r\n            public bool? Exist { get; set; }\r\n\r\n            [JsonPropertyName(InDesiredStatePropertyName)]\r\n            public bool? InDesiredState { get; set; }\r\n\r\n            [JsonPropertyName(\"id\")]\r\n            public string Identifier { get; set; }\r\n\r\n            public string Source { get; set; }\r\n\r\n            public string Version { get; set; }\r\n\r\n            public string MatchOption { get; set; }\r\n\r\n            public bool? UseLatest { get; set; }\r\n\r\n            public string InstallMode { get; set; }\r\n\r\n            public bool? AcceptAgreements { get; set; }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/DSCv3ResourceTestBase.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"DSCv3ResourceTestBase.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.IO;\r\n    using System.Text.Json;\r\n    using System.Text.Json.Serialization;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// Provides common functionality for DSC v3 resource tests.\r\n    /// </summary>\r\n    public class DSCv3ResourceTestBase\r\n    {\r\n        /// <summary>\r\n        /// The string for the `get` function.\r\n        /// </summary>\r\n        public const string GetFunction = \"get\";\r\n\r\n        /// <summary>\r\n        /// The string for the `test` function.\r\n        /// </summary>\r\n        public const string TestFunction = \"test\";\r\n\r\n        /// <summary>\r\n        /// The string for the `set` function.\r\n        /// </summary>\r\n        public const string SetFunction = \"set\";\r\n\r\n        /// <summary>\r\n        /// The string for the `export` function.\r\n        /// </summary>\r\n        public const string ExportFunction = \"export\";\r\n\r\n        /// <summary>\r\n        /// The string for the `_exist` property name.\r\n        /// </summary>\r\n        public const string ExistPropertyName = \"_exist\";\r\n\r\n        /// <summary>\r\n        /// The string for the `_inDesiredState` property name.\r\n        /// </summary>\r\n        public const string InDesiredStatePropertyName = \"_inDesiredState\";\r\n\r\n        /// <summary>\r\n        /// Write the resource manifests out to the WindowsApps alias directory.\r\n        /// </summary>\r\n        public static void EnsureTestResourcePresence()\r\n        {\r\n            string outputDirectory = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), \"Microsoft\\\\WindowsApps\");\r\n            Assert.IsNotEmpty(outputDirectory);\r\n\r\n            var result = TestCommon.RunAICLICommand($\"dscv3\", $\"--manifest -o {outputDirectory}\");\r\n            Assert.AreEqual(0, result.ExitCode);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Runs a DSC v3 resource command.\r\n        /// </summary>\r\n        /// <param name=\"resource\">The resource to target.</param>\r\n        /// <param name=\"function\">The resource function to run.</param>\r\n        /// <param name=\"input\">Input for the function; supports null, direct string, or JSON serialization of complex objects.</param>\r\n        /// <param name=\"timeOut\">The maximum time to wait in milliseconds.</param>\r\n        /// <param name=\"throwOnTimeout\">Whether to throw on a timeout or simply return the incomplete result.</param>\r\n        /// <returns>A RunCommandResult containing the process exit code and output and error streams.</returns>\r\n        protected static TestCommon.RunCommandResult RunDSCv3Command(string resource, string function, object input, int timeOut = 60000, bool throwOnTimeout = true)\r\n        {\r\n            return TestCommon.RunAICLICommand($\"dscv3 {resource}\", $\"--{function}\", ConvertToJSON(input), timeOut, throwOnTimeout);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Asserts that a RunCommandResult contains a success for a DSC v3 resource command run.\r\n        /// </summary>\r\n        /// <param name=\"result\">The result of a DSC v3 resource command run.</param>\r\n        protected static void AssertSuccessfulResourceRun(ref TestCommon.RunCommandResult result)\r\n        {\r\n            Assert.AreEqual(0, result.ExitCode);\r\n            Assert.IsNotEmpty(result.StdOut);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the output as lines.\r\n        /// </summary>\r\n        /// <param name=\"output\">The output stream from a DSC v3 resource command.</param>\r\n        /// <returns>The lines of the output.</returns>\r\n        protected static string[] GetOutputLines(string output)\r\n        {\r\n            return output.TrimEnd().Split(Environment.NewLine);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Asserts that the output is a single line and deserializes that line as JSON.\r\n        /// </summary>\r\n        /// <typeparam name=\"T\">The type to deserialize from JSON.</typeparam>\r\n        /// <param name=\"output\">The output stream from a DSC v3 resource command.</param>\r\n        /// <returns>The object as deserialized.</returns>\r\n        protected static T GetSingleOutputLineAs<T>(string output)\r\n        {\r\n            string[] lines = GetOutputLines(output);\r\n            Assert.AreEqual(1, lines.Length);\r\n\r\n            return JsonSerializer.Deserialize<T>(lines[0], GetDefaultJsonOptions());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Asserts that the output is two lines and deserializes them as a JSON object and JSON string array.\r\n        /// </summary>\r\n        /// <typeparam name=\"T\">The type to deserialize from JSON.</typeparam>\r\n        /// <param name=\"output\">The output stream from a DSC v3 resource command.</param>\r\n        /// <returns>The object as deserialized and the contents of the string array.</returns>\r\n        protected static (T, List<string>) GetSingleOutputLineAndDiffAs<T>(string output)\r\n        {\r\n            string[] lines = GetOutputLines(output);\r\n            Assert.AreEqual(2, lines.Length);\r\n\r\n            var options = GetDefaultJsonOptions();\r\n            return (JsonSerializer.Deserialize<T>(lines[0], options), JsonSerializer.Deserialize<List<string>>(lines[1], options));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Deserializes all lines as JSON objects.\r\n        /// </summary>\r\n        /// <typeparam name=\"T\">The type to deserialize from JSON.</typeparam>\r\n        /// <param name=\"output\">The output stream from a DSC v3 resource command.</param>\r\n        /// <returns>A List of objects as deserialized.</returns>\r\n        protected static List<T> GetOutputLinesAs<T>(string output)\r\n        {\r\n            List<T> result = new List<T>();\r\n            string[] lines = GetOutputLines(output);\r\n            var options = GetDefaultJsonOptions();\r\n\r\n            foreach (string line in lines)\r\n            {\r\n                result.Add(JsonSerializer.Deserialize<T>(line, options));\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Requires that the diff from a resource command contain the same set of strings as expected.\r\n        /// </summary>\r\n        /// <param name=\"diff\">The diff from a resource command.</param>\r\n        /// <param name=\"expected\">The expected strings.</param>\r\n        protected static void AssertDiffState(List<string> diff, IList<string> expected)\r\n        {\r\n            Assert.IsNotNull(diff);\r\n            Assert.AreEqual(expected.Count, diff.Count);\r\n\r\n            foreach (string item in expected)\r\n            {\r\n                Assert.Contains(item, diff);\r\n            }\r\n        }\r\n\r\n        private static JsonSerializerOptions GetDefaultJsonOptions()\r\n        {\r\n            return new JsonSerializerOptions()\r\n            {\r\n                DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,\r\n                PropertyNamingPolicy = JsonNamingPolicy.CamelCase,\r\n                Converters =\r\n                {\r\n                    new JsonStringEnumConverter(),\r\n                },\r\n            };\r\n        }\r\n\r\n        private static string ConvertToJSON(object value) => value switch\r\n        {\r\n            string s => s,\r\n            null => null,\r\n            _ => JsonSerializer.Serialize(value, GetDefaultJsonOptions()),\r\n        };\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/DSCv3SourceResourceCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"DSCv3SourceResourceCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using System.Collections.Generic;\r\n    using System.Text.Json.Serialization;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// `Configure` command tests.\r\n    /// </summary>\r\n    [System.Diagnostics.CodeAnalysis.SuppressMessage(\"StyleCop.CSharp.SpacingRules\", \"SA1010:Opening square brackets should be spaced correctly\", Justification = \"https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3687 pending SC 1.2 release\")]\r\n    [System.Diagnostics.CodeAnalysis.SuppressMessage(\"StyleCop.CSharp.SpacingRules\", \"SA1011:Closing square brackets should be spaced correctly\", Justification = \"https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3687 pending SC 1.2 release\")]\r\n    public class DSCv3SourceResourceCommand : DSCv3ResourceTestBase\r\n    {\r\n        private const string DefaultSourceName = \"SourceResourceTestSource\";\r\n        private const string DefaultSourceType = \"Microsoft.Test.Configurable\";\r\n        private const string DefaultTrustLevel = \"none\";\r\n        private const string TrustedTrustLevel = \"trusted\";\r\n        private const bool DefaultExplicitState = false;\r\n        private const int DefaultPriority = 0;\r\n        private const string SourceResource = \"source\";\r\n        private const string ArgumentPropertyName = \"argument\";\r\n        private const string TypePropertyName = \"type\";\r\n        private const string TrustLevelPropertyName = \"trustLevel\";\r\n        private const string ExplicitPropertyName = \"explicit\";\r\n        private const string PriorityPropertyName = \"priority\";\r\n\r\n        private static string DefaultSourceArgForCmdLine\r\n        {\r\n            get { return CreateSourceArgument(true); }\r\n        }\r\n\r\n        private static string NonDefaultSourceArgForCmdLine\r\n        {\r\n            get { return CreateSourceArgument(true, 1, 1); }\r\n        }\r\n\r\n        private static string DefaultSourceArgDirect\r\n        {\r\n            get { return CreateSourceArgument(false); }\r\n        }\r\n\r\n        private static string NonDefaultSourceArgDirect\r\n        {\r\n            get { return CreateSourceArgument(false, 1, 1); }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Setup done once before all the tests here.\r\n        /// </summary>\r\n        [OneTimeSetUp]\r\n        public void OneTimeSetup()\r\n        {\r\n            TestCommon.SetupTestSource();\r\n            EnsureTestResourcePresence();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Teardown done once after all the tests here.\r\n        /// </summary>\r\n        [OneTimeTearDown]\r\n        public void OneTimeTeardown()\r\n        {\r\n            RemoveTestSource();\r\n            TestCommon.TearDownTestSource();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Set up.\r\n        /// </summary>\r\n        [SetUp]\r\n        public void Setup()\r\n        {\r\n            RemoveTestSource();\r\n            WinGetSettingsHelper.ConfigureFeature(\"sourcePriority\", true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `get` on the `source` resource with the value not present.\r\n        /// </summary>\r\n        [Test]\r\n        public void Source_Get_NotPresent()\r\n        {\r\n            SourceResourceData resourceData = new SourceResourceData() { Name = DefaultSourceName };\r\n\r\n            var result = RunDSCv3Command(SourceResource, GetFunction, resourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            SourceResourceData output = GetSingleOutputLineAs<SourceResourceData>(result.StdOut);\r\n            Assert.IsNotNull(output);\r\n            Assert.False(output.Exist);\r\n            Assert.AreEqual(resourceData.Name, output.Name);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `get` on the `source` resource with the value present.\r\n        /// </summary>\r\n        [Test]\r\n        public void Source_Get_Present()\r\n        {\r\n            var setup = TestCommon.RunAICLICommand(\"source add\", $\"--name {DefaultSourceName} --arg {DefaultSourceArgForCmdLine} --type {DefaultSourceType} --explicit\");\r\n            Assert.AreEqual(0, setup.ExitCode);\r\n\r\n            SourceResourceData resourceData = new SourceResourceData() { Name = DefaultSourceName };\r\n\r\n            var result = RunDSCv3Command(SourceResource, GetFunction, resourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            SourceResourceData output = GetSingleOutputLineAs<SourceResourceData>(result.StdOut);\r\n            AssertExistingSourceResourceData(output, DefaultSourceArgDirect, DefaultTrustLevel, true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `test` on the `source` resource with the value not present.\r\n        /// </summary>\r\n        [Test]\r\n        public void Source_Test_NotPresent()\r\n        {\r\n            SourceResourceData resourceData = new SourceResourceData() { Name = DefaultSourceName };\r\n\r\n            var result = RunDSCv3Command(SourceResource, TestFunction, resourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            (SourceResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<SourceResourceData>(result.StdOut);\r\n            Assert.IsNotNull(output);\r\n            Assert.False(output.Exist);\r\n            Assert.AreEqual(resourceData.Name, output.Name);\r\n            Assert.False(output.InDesiredState);\r\n\r\n            AssertDiffState(diff, [ ExistPropertyName ]);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `test` on the `source` resource with the value present.\r\n        /// </summary>\r\n        [Test]\r\n        public void Source_Test_SimplePresent()\r\n        {\r\n            var setup = TestCommon.RunAICLICommand(\"source add\", $\"--name {DefaultSourceName} --arg {DefaultSourceArgForCmdLine} --type {DefaultSourceType}\");\r\n            Assert.AreEqual(0, setup.ExitCode);\r\n\r\n            SourceResourceData resourceData = new SourceResourceData() { Name = DefaultSourceName };\r\n\r\n            var result = RunDSCv3Command(SourceResource, TestFunction, resourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            (SourceResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<SourceResourceData>(result.StdOut);\r\n            AssertExistingSourceResourceData(output, DefaultSourceArgDirect, DefaultTrustLevel, DefaultExplicitState);\r\n            Assert.True(output.InDesiredState);\r\n\r\n            AssertDiffState(diff, []);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `test` on the `source` resource with an argument that matches.\r\n        /// </summary>\r\n        /// <param name=\"useDefaultArgument\">The argument to use when adding the existing source.</param>\r\n        /// <param name=\"trustLevel\">The trust level to use when adding the existing source.</param>\r\n        /// <param name=\"isExplicit\">The explicit state to use when adding the existing source.</param>\r\n        /// <param name=\"priority\">The priority to use when adding the existing source.</param>\r\n        /// <param name=\"targetProperty\">The property to target for the test.</param>\r\n        [TestCase(false, DefaultTrustLevel, true, 42, ArgumentPropertyName)]\r\n        [TestCase(true, DefaultTrustLevel, false, 14, TypePropertyName)]\r\n        [TestCase(false, TrustedTrustLevel, false, 42, TrustLevelPropertyName)]\r\n        [TestCase(true, DefaultTrustLevel, true, 39, ExplicitPropertyName)]\r\n        [TestCase(true, DefaultTrustLevel, true, 1, PriorityPropertyName)]\r\n        public void Source_Test_PropertyMatch(bool useDefaultArgument, string trustLevel, bool isExplicit, int priority, string targetProperty)\r\n        {\r\n            var setup = TestCommon.RunAICLICommand(\"source add\", $\"--name {DefaultSourceName} --arg {(useDefaultArgument ? DefaultSourceArgForCmdLine : NonDefaultSourceArgForCmdLine)} --type {DefaultSourceType} --trust-level {trustLevel} {(isExplicit ? \"--explicit\" : string.Empty)} --priority {priority}\");\r\n            Assert.AreEqual(0, setup.ExitCode);\r\n\r\n            SourceResourceData resourceData = new SourceResourceData() { Name = DefaultSourceName };\r\n\r\n            switch (targetProperty)\r\n            {\r\n                case ArgumentPropertyName:\r\n                    resourceData.Argument = useDefaultArgument ? DefaultSourceArgDirect : NonDefaultSourceArgDirect;\r\n                    break;\r\n                case TypePropertyName:\r\n                    resourceData.Type = DefaultSourceType;\r\n                    break;\r\n                case TrustLevelPropertyName:\r\n                    resourceData.TrustLevel = trustLevel;\r\n                    break;\r\n                case ExplicitPropertyName:\r\n                    resourceData.Explicit = isExplicit;\r\n                    break;\r\n                case PriorityPropertyName:\r\n                    resourceData.Priority = priority;\r\n                    break;\r\n                default:\r\n                    Assert.Fail($\"{targetProperty} is not a handled case.\");\r\n                    break;\r\n            }\r\n\r\n            var result = RunDSCv3Command(SourceResource, TestFunction, resourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            (SourceResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<SourceResourceData>(result.StdOut);\r\n            AssertExistingSourceResourceData(output, useDefaultArgument ? DefaultSourceArgDirect : NonDefaultSourceArgDirect, trustLevel, isExplicit);\r\n            Assert.True(output.InDesiredState);\r\n\r\n            AssertDiffState(diff, []);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `test` on the `source` resource with a argument that does not match.\r\n        /// </summary>\r\n        /// <param name=\"useDefaultArgument\">The argument to use when adding the existing source.</param>\r\n        /// <param name=\"trustLevel\">The trust level to use when adding the existing source.</param>\r\n        /// <param name=\"isExplicit\">The explicit state to use when adding the existing source.</param>\r\n        /// <param name=\"priority\">The priority to use when adding the existing source.</param>\r\n        /// <param name=\"targetProperty\">The property to target for the test.</param>\r\n        /// <param name=\"testValue\">The value to test against.</param>\r\n        [TestCase(false, DefaultTrustLevel, true, 2, ArgumentPropertyName, true)]\r\n        [TestCase(false, DefaultTrustLevel, false, 13, TrustLevelPropertyName, TrustedTrustLevel)]\r\n        [TestCase(true, DefaultTrustLevel, true, 42, ExplicitPropertyName, false)]\r\n        [TestCase(true, DefaultTrustLevel, true, 8, PriorityPropertyName, 76)]\r\n        public void Source_Test_PropertyMismatch(bool useDefaultArgument, string trustLevel, bool isExplicit, int priority, string targetProperty, object testValue)\r\n        {\r\n            var setup = TestCommon.RunAICLICommand(\"source add\", $\"--name {DefaultSourceName} --arg {(useDefaultArgument ? DefaultSourceArgForCmdLine : NonDefaultSourceArgForCmdLine)} --type {DefaultSourceType} --trust-level {trustLevel} {(isExplicit ? \"--explicit\" : string.Empty)} --priority {priority}\");\r\n            Assert.AreEqual(0, setup.ExitCode);\r\n\r\n            SourceResourceData resourceData = new SourceResourceData() { Name = DefaultSourceName };\r\n\r\n            switch (targetProperty)\r\n            {\r\n                case ArgumentPropertyName:\r\n                    resourceData.Argument = (bool)testValue ? DefaultSourceArgDirect : NonDefaultSourceArgDirect;\r\n                    break;\r\n                case TrustLevelPropertyName:\r\n                    resourceData.TrustLevel = (string)testValue;\r\n                    break;\r\n                case ExplicitPropertyName:\r\n                    resourceData.Explicit = (bool)testValue;\r\n                    break;\r\n                case PriorityPropertyName:\r\n                    resourceData.Priority = (int)testValue;\r\n                    break;\r\n                default:\r\n                    Assert.Fail($\"{targetProperty} is not a handled case.\");\r\n                    break;\r\n            }\r\n\r\n            var result = RunDSCv3Command(SourceResource, TestFunction, resourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            (SourceResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<SourceResourceData>(result.StdOut);\r\n            AssertExistingSourceResourceData(output, useDefaultArgument ? DefaultSourceArgDirect : NonDefaultSourceArgDirect, trustLevel, isExplicit);\r\n            Assert.False(output.InDesiredState);\r\n\r\n            AssertDiffState(diff, [ targetProperty ]);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `test` on the `source` resource with all properties matching.\r\n        /// </summary>\r\n        [Test]\r\n        public void Source_Test_AllMatch()\r\n        {\r\n            var setup = TestCommon.RunAICLICommand(\"source add\", $\"--name {DefaultSourceName} --arg {NonDefaultSourceArgForCmdLine} --type {DefaultSourceType} --trust-level {TrustedTrustLevel} --explicit --priority 42\");\r\n            Assert.AreEqual(0, setup.ExitCode);\r\n\r\n            SourceResourceData resourceData = new SourceResourceData()\r\n            {\r\n                Name = DefaultSourceName,\r\n                Argument = NonDefaultSourceArgDirect,\r\n                Type = DefaultSourceType,\r\n                TrustLevel = TrustedTrustLevel,\r\n                Explicit = true,\r\n                Priority = 42,\r\n            };\r\n\r\n            var result = RunDSCv3Command(SourceResource, TestFunction, resourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            (SourceResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<SourceResourceData>(result.StdOut);\r\n            AssertExistingSourceResourceData(output, resourceData);\r\n            Assert.True(output.InDesiredState);\r\n\r\n            AssertDiffState(diff, []);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `set` on the `source` resource when the source is not present, and again afterward.\r\n        /// </summary>\r\n        [Test]\r\n        public void Source_Set_SimpleRepeated()\r\n        {\r\n            SourceResourceData resourceData = new SourceResourceData()\r\n            {\r\n                Name = DefaultSourceName,\r\n                Argument = NonDefaultSourceArgDirect,\r\n                Type = DefaultSourceType,\r\n            };\r\n\r\n            var result = RunDSCv3Command(SourceResource, SetFunction, resourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            (SourceResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<SourceResourceData>(result.StdOut);\r\n            AssertExistingSourceResourceData(output, resourceData);\r\n\r\n            AssertDiffState(diff, [ ExistPropertyName ]);\r\n\r\n            // Set again should be a no-op\r\n            result = RunDSCv3Command(SourceResource, SetFunction, resourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            (output, diff) = GetSingleOutputLineAndDiffAs<SourceResourceData>(result.StdOut);\r\n            AssertExistingSourceResourceData(output, resourceData);\r\n\r\n            AssertDiffState(diff, []);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `set` on the `source` resource to ensure that it is not present.\r\n        /// </summary>\r\n        [Test]\r\n        public void Source_Set_Remove()\r\n        {\r\n            var setup = TestCommon.RunAICLICommand(\"source add\", $\"--name {DefaultSourceName} --arg {DefaultSourceArgForCmdLine} --type {DefaultSourceType} --explicit\");\r\n            Assert.AreEqual(0, setup.ExitCode);\r\n\r\n            SourceResourceData resourceData = new SourceResourceData()\r\n            {\r\n                Name = DefaultSourceName,\r\n                Exist = false,\r\n            };\r\n\r\n            var result = RunDSCv3Command(SourceResource, SetFunction, resourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            (SourceResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<SourceResourceData>(result.StdOut);\r\n            Assert.IsNotNull(output);\r\n            Assert.False(output.Exist);\r\n            Assert.AreEqual(resourceData.Name, output.Name);\r\n\r\n            AssertDiffState(diff, [ ExistPropertyName ]);\r\n\r\n            // Call `get` to ensure the result\r\n            SourceResourceData resourceDataForGet = new SourceResourceData()\r\n            {\r\n                Name = DefaultSourceName,\r\n            };\r\n\r\n            result = RunDSCv3Command(SourceResource, GetFunction, resourceDataForGet);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            output = GetSingleOutputLineAs<SourceResourceData>(result.StdOut);\r\n            Assert.IsNotNull(output);\r\n            Assert.False(output.Exist);\r\n            Assert.AreEqual(resourceDataForGet.Name, output.Name);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `set` on the `source` resource with an existing item, replacing it.\r\n        /// </summary>\r\n        [Test]\r\n        public void Source_Set_Replace()\r\n        {\r\n            var setup = TestCommon.RunAICLICommand(\"source add\", $\"--name {DefaultSourceName} --arg {DefaultSourceArgForCmdLine} --type {DefaultSourceType}\");\r\n            Assert.AreEqual(0, setup.ExitCode);\r\n\r\n            SourceResourceData resourceData = new SourceResourceData()\r\n            {\r\n                Name = DefaultSourceName,\r\n                Argument = DefaultSourceArgDirect,\r\n                Type = DefaultSourceType,\r\n                TrustLevel = TrustedTrustLevel,\r\n                Explicit = true,\r\n            };\r\n\r\n            var result = RunDSCv3Command(SourceResource, SetFunction, resourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            (SourceResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<SourceResourceData>(result.StdOut);\r\n            AssertExistingSourceResourceData(output, resourceData);\r\n\r\n            AssertDiffState(diff, [ TrustLevelPropertyName, ExplicitPropertyName ]);\r\n\r\n            // Call `get` to ensure the result\r\n            SourceResourceData resourceDataForGet = new SourceResourceData()\r\n            {\r\n                Name = DefaultSourceName,\r\n            };\r\n\r\n            result = RunDSCv3Command(SourceResource, GetFunction, resourceDataForGet);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            output = GetSingleOutputLineAs<SourceResourceData>(result.StdOut);\r\n            AssertExistingSourceResourceData(output, resourceData);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `set` on the `source` resource with an existing item, editing it due to only changing editable properties.\r\n        /// </summary>\r\n        [Test]\r\n        public void Source_Set_Replace_Edit()\r\n        {\r\n            var setup = TestCommon.RunAICLICommand(\"source add\", $\"--name {DefaultSourceName} --arg {DefaultSourceArgForCmdLine} --type {DefaultSourceType}\");\r\n            Assert.AreEqual(0, setup.ExitCode);\r\n\r\n            SourceResourceData resourceData = new SourceResourceData()\r\n            {\r\n                Name = DefaultSourceName,\r\n                Explicit = true,\r\n                Priority = 42,\r\n            };\r\n\r\n            var result = RunDSCv3Command(SourceResource, SetFunction, resourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            (SourceResourceData output, List<string> diff) = GetSingleOutputLineAndDiffAs<SourceResourceData>(result.StdOut);\r\n            AssertExistingSourceResourceData(output, resourceData);\r\n\r\n            AssertDiffState(diff, [ExplicitPropertyName, PriorityPropertyName]);\r\n\r\n            // Call `get` to ensure the result\r\n            SourceResourceData resourceDataForGet = new SourceResourceData()\r\n            {\r\n                Name = DefaultSourceName,\r\n            };\r\n\r\n            result = RunDSCv3Command(SourceResource, GetFunction, resourceDataForGet);\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            output = GetSingleOutputLineAs<SourceResourceData>(result.StdOut);\r\n            AssertExistingSourceResourceData(output, resourceData);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls `export` on the `source` resource without providing any input.\r\n        /// </summary>\r\n        [Test]\r\n        public void Source_Export_NoInput()\r\n        {\r\n            var setup = TestCommon.RunAICLICommand(\"source add\", $\"--name {DefaultSourceName} --arg {DefaultSourceArgForCmdLine} --type {DefaultSourceType}\");\r\n            Assert.AreEqual(0, setup.ExitCode);\r\n\r\n            var result = RunDSCv3Command(SourceResource, ExportFunction, \" \");\r\n            AssertSuccessfulResourceRun(ref result);\r\n\r\n            List<SourceResourceData> output = GetOutputLinesAs<SourceResourceData>(result.StdOut);\r\n\r\n            bool foundDefaultSource = false;\r\n            foreach (SourceResourceData item in output)\r\n            {\r\n                if (item.Name == DefaultSourceName)\r\n                {\r\n                    foundDefaultSource = true;\r\n                    Assert.AreEqual(DefaultSourceName, item.Name);\r\n                    Assert.AreEqual(DefaultSourceArgDirect, item.Argument);\r\n                    Assert.AreEqual(DefaultSourceType, item.Type);\r\n                    Assert.AreEqual(DefaultTrustLevel, item.TrustLevel);\r\n                    Assert.AreEqual(DefaultExplicitState, item.Explicit);\r\n                    Assert.AreEqual(DefaultPriority, item.Priority);\r\n                    break;\r\n                }\r\n            }\r\n\r\n            Assert.IsTrue(foundDefaultSource);\r\n        }\r\n\r\n        private static void RemoveTestSource()\r\n        {\r\n            SourceResourceData resourceData = new SourceResourceData()\r\n            {\r\n                Name = DefaultSourceName,\r\n                Exist = false,\r\n            };\r\n\r\n            var result = RunDSCv3Command(SourceResource, SetFunction, resourceData);\r\n            AssertSuccessfulResourceRun(ref result);\r\n        }\r\n\r\n        private static void AssertExistingSourceResourceData(SourceResourceData output, SourceResourceData input)\r\n        {\r\n            AssertExistingSourceResourceData(output, input.Argument, input.TrustLevel, input.Explicit, input.Priority);\r\n        }\r\n\r\n        private static void AssertExistingSourceResourceData(SourceResourceData output, string argument, string trustLevel = null, bool? isExplicit = null, int? priority = null)\r\n        {\r\n            Assert.IsNotNull(output);\r\n            Assert.True(output.Exist);\r\n            Assert.AreEqual(DefaultSourceName, output.Name);\r\n\r\n            if (argument != null)\r\n            {\r\n                Assert.AreEqual(argument, output.Argument);\r\n            }\r\n\r\n            Assert.AreEqual(DefaultSourceType, output.Type);\r\n\r\n            if (trustLevel != null)\r\n            {\r\n                Assert.AreEqual(trustLevel, output.TrustLevel);\r\n            }\r\n\r\n            if (isExplicit != null)\r\n            {\r\n                Assert.AreEqual(isExplicit, output.Explicit);\r\n            }\r\n\r\n            if (priority != null)\r\n            {\r\n                Assert.AreEqual(priority, output.Priority);\r\n            }\r\n        }\r\n\r\n        private static string CreateSourceArgument(bool forCommandLine = false, int openHR = 0, int searchHR = 0)\r\n        {\r\n            const string CommandLineFormat = @\"\"\"{{\"\"\"\"OpenHR\"\"\"\": {0}, \"\"\"\"SearchHR\"\"\"\": {1} }}\"\"\";\r\n            const string DirectFormat = @\"{{\"\"OpenHR\"\": {0}, \"\"SearchHR\"\": {1} }}\";\r\n            return string.Format(forCommandLine ? CommandLineFormat : DirectFormat, openHR, searchHR);\r\n        }\r\n\r\n        private class SourceResourceData\r\n        {\r\n            [JsonPropertyName(ExistPropertyName)]\r\n            public bool? Exist { get; set; }\r\n\r\n            [JsonPropertyName(InDesiredStatePropertyName)]\r\n            public bool? InDesiredState { get; set; }\r\n\r\n            public string Name { get; set; }\r\n\r\n            public string Argument { get; set; }\r\n\r\n            public string Type { get; set; }\r\n\r\n            public string TrustLevel { get; set; }\r\n\r\n            public bool? Explicit { get; set; }\r\n\r\n            public bool? AcceptAgreements { get; set; }\r\n\r\n            public int? Priority { get; set; }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/DSCv3UserSettingsFileResourceCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"DSCv3UserSettingsFileResourceCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests;\r\n\r\nusing AppInstallerCLIE2ETests.Helpers;\r\nusing NUnit.Framework;\r\nusing System.Collections.Generic;\r\nusing System.IO;\r\nusing System.Text.Json.Nodes;\r\nusing System.Text.Json.Serialization;\r\n\r\n/// <summary>\r\n/// `Configure` command tests.\r\n/// </summary>\r\n[System.Diagnostics.CodeAnalysis.SuppressMessage(\"StyleCop.CSharp.SpacingRules\", \"SA1010:Opening square brackets should be spaced correctly\", Justification = \"https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3687 pending SC 1.2 release\")]\r\n[System.Diagnostics.CodeAnalysis.SuppressMessage(\"StyleCop.CSharp.SpacingRules\", \"SA1011:Closing square brackets should be spaced correctly\", Justification = \"https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3687 pending SC 1.2 release\")]\r\npublic class DSCv3UserSettingsFileResourceCommand : DSCv3ResourceTestBase\r\n{\r\n    private const string UserSettingsFileResource = \"user-settings-file\";\r\n    private const string SettingsPropertyName = \"settings\";\r\n    private const string ActionPropertyValueFull = \"Full\";\r\n    private const string ActionPropertyValuePartial = \"Partial\";\r\n    private const string SettingsMock = \"mock\";\r\n    private const string SettingsMockObject = \"mockObject\";\r\n    private const string SettingsMockNested = \"mockNested\";\r\n\r\n    /// <summary>\r\n    /// Setup done once before all the tests here.\r\n    /// </summary>\r\n    [OneTimeSetUp]\r\n    public void OneTimeSetup()\r\n    {\r\n        TestCommon.SetupTestSource();\r\n        EnsureTestResourcePresence();\r\n    }\r\n\r\n    /// <summary>\r\n    /// Teardown done once after all the tests here.\r\n    /// </summary>\r\n    [OneTimeTearDown]\r\n    public void OneTimeTeardown()\r\n    {\r\n        WinGetSettingsHelper.InitializeWingetSettings();\r\n    }\r\n\r\n    /// <summary>\r\n    /// Set up.\r\n    /// </summary>\r\n    [SetUp]\r\n    public void Setup()\r\n    {\r\n        // Reset the settings to default before each test.\r\n        WinGetSettingsHelper.InitializeWingetSettings();\r\n        WinGetSettingsHelper.ConfigureFeature(\"dsc3\", true);\r\n    }\r\n\r\n    /// <summary>\r\n    /// Calls `get` on the `user-settings-file` resource.\r\n    /// </summary>\r\n    [Test]\r\n    public void UserSettingsFile_Get()\r\n    {\r\n        var expected = GetCurrentUserSettings();\r\n        var getOutput = Get(new ());\r\n\r\n        Assert.IsNotNull(getOutput);\r\n        Assert.IsNull(getOutput.Action);\r\n        AssertSettingsAreEqual(expected, getOutput.Settings);\r\n    }\r\n\r\n    /// <summary>\r\n    /// Calls `set` on the `user-settings-file` resource with no diff.\r\n    /// </summary>\r\n    /// <param name=\"action\">The action value.</param>\r\n    [Test]\r\n    [TestCase(ActionPropertyValueFull)]\r\n    [TestCase(ActionPropertyValuePartial)]\r\n    public void UserSettingsFile_Set_NoDiff(string action)\r\n    {\r\n        var setSettings = GetSettingsArg(action);\r\n\r\n        (var setOutput, var setDiff) = Set(new () { Action = action, Settings = setSettings });\r\n\r\n        var expected = GetCurrentUserSettings();\r\n\r\n        Assert.IsNotNull(setOutput);\r\n        Assert.AreEqual(action, setOutput.Action);\r\n        AssertSettingsAreEqual(expected, setOutput.Settings);\r\n        AssertDiffState(setDiff, []);\r\n    }\r\n\r\n    /// <summary>\r\n    /// Calls `set` on the `user-settings-file` resource to add fields.\r\n    /// </summary>\r\n    /// <param name=\"action\">The action value.</param>\r\n    [Test]\r\n    [TestCase(ActionPropertyValueFull)]\r\n    [TestCase(ActionPropertyValuePartial)]\r\n    public void UserSettingsFile_Set_AddFields(string action)\r\n    {\r\n        // Call `set` to add mock properties to the settings\r\n        var setSettings = GetSettingsArg(action);\r\n        AddOrModifyMockProperties(setSettings, \"mock\");\r\n\r\n        (var setOutput, var setDiff) = Set(new () { Action = action, Settings = setSettings });\r\n\r\n        var expected = GetCurrentUserSettings();\r\n\r\n        // Assert that the settings are added\r\n        Assert.IsNotNull(setOutput);\r\n        Assert.AreEqual(action, setOutput.Action);\r\n        AssertMockProperties(setOutput.Settings, \"mock\");\r\n        AssertSettingsAreEqual(expected, setOutput.Settings);\r\n        AssertDiffState(setDiff, [ SettingsPropertyName ]);\r\n    }\r\n\r\n    /// <summary>\r\n    /// Calls `set` on the `user-settings-file` resource to ensure action is partial by default.\r\n    /// </summary>\r\n    [Test]\r\n    public void UserSettingsFile_Set_ActionIsPartialByDefault()\r\n    {\r\n        // Call `set` to add mock properties to the settings\r\n        var setSettings = GetSettingsArg(ActionPropertyValuePartial);\r\n        AddOrModifyMockProperties(setSettings, \"mock\");\r\n\r\n        var expected = GetCurrentUserSettings();\r\n        AddOrModifyMockProperties(expected, \"mock\");\r\n\r\n        (var setOutput, var setDiff) = Set(new () { Settings = setSettings });\r\n\r\n        // Assert that the settings are added\r\n        Assert.IsNotNull(setOutput);\r\n        Assert.AreEqual(setOutput.Action, ActionPropertyValuePartial);\r\n        AssertMockProperties(setOutput.Settings, \"mock\");\r\n        AssertSettingsAreEqual(expected, setOutput.Settings);\r\n        AssertDiffState(setDiff, [ SettingsPropertyName ]);\r\n    }\r\n\r\n    /// <summary>\r\n    /// Calls `set` on the `user-settings-file` resource to update fields.\r\n    /// </summary>\r\n    /// <param name=\"action\">The action value.</param>\r\n    [Test]\r\n    [TestCase(ActionPropertyValueFull)]\r\n    [TestCase(ActionPropertyValuePartial)]\r\n    public void UserSettingsFile_Set_UpdateFields(string action)\r\n    {\r\n        // Add mock properties to the settings\r\n        var set1Settings = new JsonObject();\r\n        AddOrModifyMockProperties(set1Settings, \"mock_old\");\r\n        Set(new () { Action = ActionPropertyValuePartial, Settings = set1Settings });\r\n\r\n        // Call `set` to update the settings\r\n        var set2Settings = GetSettingsArg(action);\r\n        AddOrModifyMockProperties(set2Settings, \"mock_new\");\r\n\r\n        (var setOutput, var setDiff) = Set(new () { Action = action, Settings = set2Settings });\r\n\r\n        var expected = GetCurrentUserSettings();\r\n\r\n        // Assert that the settings are updated\r\n        Assert.IsNotNull(setOutput);\r\n        Assert.AreEqual(action, setOutput.Action);\r\n        AssertMockProperties(setOutput.Settings, \"mock_new\");\r\n        AssertSettingsAreEqual(expected, setOutput.Settings);\r\n        AssertDiffState(setDiff, [ SettingsPropertyName ]);\r\n    }\r\n\r\n    /// <summary>\r\n    /// Calls `test` on the `user-settings-file` resource to check if the settings are in desired state.\r\n    /// </summary>\r\n    /// <param name=\"action\">The action value.</param>\r\n    [Test]\r\n    [TestCase(ActionPropertyValueFull)]\r\n    [TestCase(ActionPropertyValuePartial)]\r\n    public void UserSettingsFile_Test_InDesiredState(string action)\r\n    {\r\n        // Add mock properties to the settings\r\n        var setSettings = new JsonObject();\r\n        AddOrModifyMockProperties(setSettings, \"mock\");\r\n        Set(new () { Action = ActionPropertyValuePartial, Settings = setSettings });\r\n\r\n        // Call `test` to check the settings\r\n        var testSettings = GetSettingsArg(action);\r\n        AddOrModifyMockProperties(testSettings, \"mock\");\r\n\r\n        (var testOutput, var testDiff) = Test(new () { Action = action, Settings = testSettings });\r\n\r\n        var expected = GetCurrentUserSettings();\r\n\r\n        // Assert that the settings are in desired state\r\n        Assert.IsNotNull(testOutput);\r\n        Assert.AreEqual(action, testOutput.Action);\r\n        AssertMockProperties(testOutput.Settings, \"mock\");\r\n        AssertSettingsAreEqual(expected, testOutput.Settings);\r\n        Assert.IsTrue(testOutput.InDesiredState);\r\n        AssertDiffState(testDiff, []);\r\n    }\r\n\r\n    /// <summary>\r\n    /// Calls `test` on the `user-settings-file` resource to check if the settings are not in desired state.\r\n    /// </summary>\r\n    /// <param name=\"action\">The action value.</param>\r\n    [Test]\r\n    [TestCase(ActionPropertyValueFull)]\r\n    [TestCase(ActionPropertyValuePartial)]\r\n    public void UserSettingsFile_Test_NotInDesiredState(string action)\r\n    {\r\n        // Add mock properties to the settings\r\n        var setSettings = new JsonObject();\r\n        AddOrModifyMockProperties(setSettings, \"mock_set\");\r\n        Set(new () { Action = ActionPropertyValuePartial, Settings = setSettings });\r\n\r\n        // Call `test` to check the settings\r\n        var testSettings = GetSettingsArg(action);\r\n        AddOrModifyMockProperties(testSettings, \"mock_test\");\r\n\r\n        (var testOutput, var testDiff) = Test(new () { Action = action, Settings = testSettings });\r\n\r\n        var expected = GetCurrentUserSettings();\r\n\r\n        // Assert that the settings are not in desired state\r\n        Assert.IsNotNull(testOutput);\r\n        Assert.AreEqual(action, testOutput.Action);\r\n        AssertMockProperties(testOutput.Settings, \"mock_set\");\r\n        AssertSettingsAreEqual(expected, testOutput.Settings);\r\n        Assert.IsFalse(testOutput.InDesiredState);\r\n        AssertDiffState(testDiff, [ SettingsPropertyName ]);\r\n    }\r\n\r\n    /// <summary>\r\n    /// Calls `export` on the `user-settings-file` resource to export the settings.\r\n    /// </summary>\r\n    [Test]\r\n    public void UserSettingsFile_Export()\r\n    {\r\n        var expected = GetCurrentUserSettings();\r\n        var exportOutput = Export(new ());\r\n\r\n        Assert.IsNotNull(exportOutput);\r\n        Assert.IsNull(exportOutput.Action);\r\n        AssertSettingsAreEqual(expected, exportOutput.Settings);\r\n    }\r\n\r\n    /// <summary>\r\n    /// Calls `get` on the `user-settings-file` resource.\r\n    /// </summary>\r\n    /// <param name=\"resourceData\">The input resource data.</param>\r\n    /// <returns>The output resource data.</returns>\r\n    private static UserSettingsFileResourceData Get(UserSettingsFileResourceData resourceData)\r\n    {\r\n        var result = RunDSCv3Command(UserSettingsFileResource, GetFunction, resourceData);\r\n        AssertSuccessfulResourceRun(ref result);\r\n        return GetSingleOutputLineAs<UserSettingsFileResourceData>(result.StdOut);\r\n    }\r\n\r\n    /// <summary>\r\n    /// Calls `set` on the `user-settings-file` resource.\r\n    /// </summary>\r\n    /// <param name=\"resourceData\">The input resource data.</param>\r\n    /// <returns>The output resource data and the diff.</returns>\r\n    private static (UserSettingsFileResourceData, List<string>) Set(UserSettingsFileResourceData resourceData)\r\n    {\r\n        var result = RunDSCv3Command(UserSettingsFileResource, SetFunction, resourceData);\r\n        AssertSuccessfulResourceRun(ref result);\r\n        return GetSingleOutputLineAndDiffAs<UserSettingsFileResourceData>(result.StdOut);\r\n    }\r\n\r\n    /// <summary>\r\n    /// Calls `test` on the `user-settings-file` resource.\r\n    /// </summary>\r\n    /// <param name=\"resourceData\">The input resource data.</param>\r\n    /// <returns>The output resource data and the diff.</returns>\r\n    private static (UserSettingsFileResourceData, List<string>) Test(UserSettingsFileResourceData resourceData)\r\n    {\r\n        var result = RunDSCv3Command(UserSettingsFileResource, TestFunction, resourceData);\r\n        AssertSuccessfulResourceRun(ref result);\r\n        return GetSingleOutputLineAndDiffAs<UserSettingsFileResourceData>(result.StdOut);\r\n    }\r\n\r\n    /// <summary>\r\n    /// Calls `export` on the `user-settings-file` resource.\r\n    /// </summary>\r\n    /// <param name=\"resourceData\">The input resource data.</param>\r\n    /// <returns>The output resource data.</returns>\r\n    private static UserSettingsFileResourceData Export(UserSettingsFileResourceData resourceData)\r\n    {\r\n        var result = RunDSCv3Command(UserSettingsFileResource, ExportFunction, resourceData);\r\n        AssertSuccessfulResourceRun(ref result);\r\n        return GetSingleOutputLineAs<UserSettingsFileResourceData>(result.StdOut);\r\n    }\r\n\r\n    /// <summary>\r\n    /// Gets the current user settings from the settings file.\r\n    /// </summary>\r\n    /// <returns>The current user settings as a JsonObject.</returns>\r\n    private static JsonObject GetCurrentUserSettings()\r\n    {\r\n        var settingsContent = File.ReadAllText(WinGetSettingsHelper.GetUserSettingsPath());\r\n        return JsonNode.Parse(settingsContent).AsObject();\r\n    }\r\n\r\n    /// <summary>\r\n    /// Adds or modifies mock properties in the settings.\r\n    /// </summary>\r\n    /// <param name=\"settings\">Target settings.</param>\r\n    /// <param name=\"value\">The mock value.</param>\r\n    private static void AddOrModifyMockProperties(JsonObject settings, string value)\r\n    {\r\n        settings[SettingsMock] = value;\r\n        settings[SettingsMockObject] ??= new JsonObject();\r\n        settings[SettingsMockObject][SettingsMockNested] = value;\r\n    }\r\n\r\n    /// <summary>\r\n    /// Asserts that the settings contain the expected mock properties.\r\n    /// </summary>\r\n    /// <param name=\"settings\">Target settings.</param>\r\n    /// <param name=\"value\">The expected mock value.</param>\r\n    private static void AssertMockProperties(JsonObject settings, string value)\r\n    {\r\n        Assert.IsNotNull(settings);\r\n        Assert.IsTrue(settings.ContainsKey(SettingsMock));\r\n        Assert.AreEqual(settings[SettingsMock].ToString(), value);\r\n        Assert.IsTrue(settings.ContainsKey(SettingsMockObject));\r\n        Assert.IsTrue(settings[SettingsMockObject].AsObject().ContainsKey(SettingsMockNested));\r\n        Assert.AreEqual(settings[SettingsMockObject][SettingsMockNested].ToString(), value);\r\n    }\r\n\r\n    /// <summary>\r\n    /// Asserts that the diff state is as expected.\r\n    /// </summary>\r\n    /// <param name=\"expected\">The expected settings.</param>\r\n    /// <param name=\"actual\">The actual settings.</param>\r\n    private static void AssertSettingsAreEqual(JsonObject expected, JsonObject actual)\r\n    {\r\n        Assert.IsTrue(JsonNode.DeepEquals(expected, actual));\r\n    }\r\n\r\n    /// <summary>\r\n    /// Gets the settings argument based on the action.\r\n    /// </summary>\r\n    /// <param name=\"action\">The action value.</param>\r\n    /// <returns>The settings argument as a JsonObject.</returns>\r\n    private static JsonObject GetSettingsArg(string action) => action == ActionPropertyValueFull ? GetCurrentUserSettings() : new ();\r\n\r\n    private class UserSettingsFileResourceData\r\n    {\r\n        [JsonPropertyName(InDesiredStatePropertyName)]\r\n        public bool? InDesiredState { get; set; }\r\n\r\n        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]\r\n        public string Action { get; set; }\r\n\r\n        public JsonObject Settings { get; set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/DownloadCommand.cs",
    "content": "// -----------------------------------------------------------------------------\n// <copyright file=\"DownloadCommand.cs\" company=\"Microsoft Corporation\">\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\n// </copyright>\n// -----------------------------------------------------------------------------\n\nnamespace AppInstallerCLIE2ETests\n{\n    using System.IO;\n    using AppInstallerCLIE2ETests.Helpers;\n    using Microsoft.Management.Deployment;\n    using NUnit.Framework;\n    using Windows.System;\n\n    /// <summary>\n    /// Test download command.\n    /// </summary>\n    public class DownloadCommand : BaseCommand\n    {\n        /// <summary>\n        /// Downloads the test installer and its package dependencies.\n        /// </summary>\n        [Test]\n        public void DownloadDependencies()\n        {\n            var downloadDir = TestCommon.GetRandomTestDir();\n            var result = TestCommon.RunAICLICommand(\"download\", $\"AppInstallerTest.PackageDependency --download-directory {downloadDir}\");\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\n            var dependenciesDir = Path.Combine(downloadDir, Constants.Dependencies);\n            TestCommon.AssertInstallerDownload(dependenciesDir, \"TestPortableExe\", \"3.0.0.0\", ProcessorArchitecture.X64, TestCommon.Scope.Unknown, PackageInstallerType.Portable, \"en-US\");\n            TestCommon.AssertInstallerDownload(downloadDir, \"TestPackageDependency\", \"1.0.0.0\", ProcessorArchitecture.X64, TestCommon.Scope.Unknown, PackageInstallerType.Exe, \"en-US\");\n        }\n\n        /// <summary>\n        /// Downloads the test installer and skips dependencies.\n        /// </summary>\n        [Test]\n        public void DownloadDependencies_Skip()\n        {\n            var downloadDir = TestCommon.GetRandomTestDir();\n            var result = TestCommon.RunAICLICommand(\"download\", $\"AppInstallerTest.PackageDependency --skip-dependencies --download-directory {downloadDir}\");\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\n            Assert.True(result.StdOut.Contains(\"Dependencies skipped.\"));\n            Assert.IsFalse(Directory.Exists(Path.Combine(downloadDir, Constants.Dependencies)));\n            TestCommon.AssertInstallerDownload(downloadDir, \"TestPackageDependency\", \"1.0.0.0\", ProcessorArchitecture.X64, TestCommon.Scope.Unknown, PackageInstallerType.Exe, \"en-US\");\n        }\n\n        /// <summary>\n        /// Downloads the test installer to the default downloads directory.\n        /// </summary>\n        [Test]\n        public void DownloadToDefaultDirectory()\n        {\n            var packageVersion = \"2.0.0.0\";\n            var result = TestCommon.RunAICLICommand(\"download\", $\"{Constants.ExeInstallerPackageId} --version {packageVersion}\");\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\n            string downloadDir = Path.Combine(TestCommon.GetDefaultDownloadDirectory(), $\"{Constants.ExeInstallerPackageId}_{packageVersion}\");\n            TestCommon.AssertInstallerDownload(downloadDir, \"TestExeInstaller\", packageVersion, ProcessorArchitecture.X86, TestCommon.Scope.User, PackageInstallerType.Exe);\n        }\n\n        /// <summary>\n        /// Downloads the test installer to a specified directory.\n        /// </summary>\n        [Test]\n        public void DownloadToDirectory()\n        {\n            var downloadDir = TestCommon.GetRandomTestDir();\n            var result = TestCommon.RunAICLICommand(\"download\", $\"{Constants.ExeInstallerPackageId} --download-directory {downloadDir}\");\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\n            TestCommon.AssertInstallerDownload(downloadDir, \"TestExeInstaller\", \"2.0.0.0\", ProcessorArchitecture.X86, TestCommon.Scope.User, PackageInstallerType.Exe);\n        }\n\r\n        /// <summary>\n        /// Downloads the test installer with Arm64.\n        /// </summary>\n        [Test]\n        public void DownloadWithArm64()\n        {\n            var downloadDir = TestCommon.GetRandomTestDir();\n            var result = TestCommon.RunAICLICommand(\"download\", $\"AppInstallerTest.TestMultipleInstallers --scope user --download-directory {downloadDir} --architecture Arm64\");\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n#pragma warning disable CA1416 // Validate platform compatibility. Arm64 is not reachable.\r\n            TestCommon.AssertInstallerDownload(downloadDir, \"TestMultipleInstallers\", \"1.0.0.0\", ProcessorArchitecture.Arm64, TestCommon.Scope.User, PackageInstallerType.Nullsoft, \"en-US\");\r\n#pragma warning restore CA1416\r\n        }\r\n\n        /// <summary>\n        /// Downloads the test installer using the user scope argument.\n        /// </summary>\n        [Test]\n        public void DownloadWithUserScope()\n        {\n            var downloadDir = TestCommon.GetRandomTestDir();\n            var result = TestCommon.RunAICLICommand(\"download\", $\"AppInstallerTest.TestMultipleInstallers --scope user --download-directory {downloadDir}\");\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\n            TestCommon.AssertInstallerDownload(downloadDir, \"TestMultipleInstallers\", \"1.0.0.0\", ProcessorArchitecture.X64, TestCommon.Scope.User, PackageInstallerType.Nullsoft, \"en-US\");\n        }\n\n        /// <summary>\n        /// Downloads the test installer using the machine scope argument.\n        /// </summary>\n        [Test]\n        public void DownloadWithMachineScope()\n        {\n            var downloadDir = TestCommon.GetRandomTestDir();\n            var result = TestCommon.RunAICLICommand(\"download\", $\"AppInstallerTest.TestMultipleInstallers --scope machine --download-directory {downloadDir}\");\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\n            TestCommon.AssertInstallerDownload(downloadDir, \"TestMultipleInstallers\", \"1.0.0.0\", ProcessorArchitecture.X86, TestCommon.Scope.Machine, PackageInstallerType.Msi, \"en-US\");\n        }\n\n        /// <summary>\n        /// Downloads the test installer using the 'zip' installer type argument. Verifies that base installer types such as 'zip' are still supported.\n        /// </summary>\n        [Test]\n        public void DownloadWithZipInstallerTypeArg()\n        {\n            var downloadDir = TestCommon.GetRandomTestDir();\n            var result = TestCommon.RunAICLICommand(\"download\", $\"AppInstallerTest.TestMultipleInstallers --installer-type zip --download-directory {downloadDir}\");\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\n            TestCommon.AssertInstallerDownload(downloadDir, \"TestMultipleInstallers\", \"1.0.0.0\", ProcessorArchitecture.X64, TestCommon.Scope.Unknown, PackageInstallerType.Exe, \"zh-CN\", true);\n        }\n\n        /// <summary>\n        /// Downloads the test installer using the installer type argument.\n        /// </summary>\n        [Test]\n        public void DownloadWithInstallerTypeArg()\n        {\n            var downloadDir = TestCommon.GetRandomTestDir();\n            var result = TestCommon.RunAICLICommand(\"download\", $\"AppInstallerTest.TestMultipleInstallers --installer-type msi --download-directory {downloadDir}\");\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\n            TestCommon.AssertInstallerDownload(downloadDir, \"TestMultipleInstallers\", \"1.0.0.0\", ProcessorArchitecture.X86, TestCommon.Scope.Machine, PackageInstallerType.Msi, \"en-US\");\n        }\n\n        /// <summary>\n        /// Downloads the test installer using the architecture argument.\n        /// </summary>\n        [Test]\n        public void DownloadWithArchitectureArg()\n        {\n            var downloadDir = TestCommon.GetRandomTestDir();\n            var result = TestCommon.RunAICLICommand(\"download\", $\"AppInstallerTest.TestMultipleInstallers --architecture x86 --download-directory {downloadDir}\");\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\n            TestCommon.AssertInstallerDownload(downloadDir, \"TestMultipleInstallers\", \"1.0.0.0\", ProcessorArchitecture.X86, TestCommon.Scope.Machine, PackageInstallerType.Msi, \"en-US\");\n        }\n\n        /// <summary>\n        /// Downloads the test installer using the locale argument.\n        /// </summary>\n        [Test]\n        public void DownloadWithLocaleArg()\n        {\n            var downloadDir = TestCommon.GetRandomTestDir();\n            var result = TestCommon.RunAICLICommand(\"download\", $\"AppInstallerTest.TestMultipleInstallers --locale zh-CN --download-directory {downloadDir}\");\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\n            TestCommon.AssertInstallerDownload(downloadDir, \"TestMultipleInstallers\", \"1.0.0.0\", ProcessorArchitecture.X64, TestCommon.Scope.Unknown, PackageInstallerType.Exe, \"zh-CN\", true);\n        }\n\n        /// <summary>\n        /// Downloads the test installer with a hash mismatch.\n        /// </summary>\n        [Test]\n        public void DownloadWithHashMismatch()\n        {\n            var downloadDir = TestCommon.GetRandomTestDir();\n            var errorResult = TestCommon.RunAICLICommand(\"download\", $\"AppInstallerTest.TestExeSha256Mismatch --download-directory {downloadDir}\");\n            Assert.AreEqual(Constants.ErrorCode.ERROR_INSTALLER_HASH_MISMATCH, errorResult.ExitCode);\n        }\n\n        /// <summary>\n        /// Downloads the zero byte test installer with a hash mismatch.\n        /// </summary>\n        [Test]\n        public void DownloadZeroByteFileWithHashMismatch()\n        {\n            var downloadDir = TestCommon.GetRandomTestDir();\n            var errorResult = TestCommon.RunAICLICommand(\"download\", $\"ZeroByteFile.IncorrectHash --download-directory {downloadDir}\");\n            Assert.AreEqual(Constants.ErrorCode.ERROR_INSTALLER_ZERO_BYTE_FILE, errorResult.ExitCode);\n        }\n\n        /// <summary>\n        /// Downloads the zero byte test installer.\n        /// </summary>\n        [Test]\n        public void DownloadZeroByteFile()\n        {\n            var downloadDir = TestCommon.GetRandomTestDir();\n            var result = TestCommon.RunAICLICommand(\"download\", $\"ZeroByteFile.CorrectHash --download-directory {downloadDir}\");\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\n            TestCommon.AssertInstallerDownload(downloadDir, \"ZeroByteFile-CorrectHash\", \"1.0.0.0\", ProcessorArchitecture.X86, TestCommon.Scope.Unknown, PackageInstallerType.Exe, \"en-US\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/ErrorCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ErrorCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// Test error command.\r\n    /// </summary>\r\n    public class ErrorCommand\r\n    {\r\n        /// <summary>\r\n        /// Reset settings file to avoid affecting output from error command.\r\n        /// </summary>\r\n        [OneTimeSetUp]\r\n        public void OneTimeSetup()\r\n        {\r\n            WinGetSettingsHelper.InitializeWingetSettings();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests 0.\r\n        /// </summary>\r\n        [Test]\r\n        public void Success()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"error\", \"0\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"0x00000000\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests 0x8a15c001.\r\n        /// </summary>\r\n        [Test]\r\n        public void HexError()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"error\", \"0x8a15c001\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"0x8a15c001\"));\r\n            Assert.True(result.StdOut.Contains(\"WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests a number larger than an HRESULT.\r\n        /// </summary>\r\n        [Test]\r\n        public void HexErrorTooBig()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"error\", \"0x8a15c0014\");\r\n            Assert.AreEqual(Constants.ErrorCode.E_INVALIDARG, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"The given number is too large to be an HRESULT.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests 2316681217.\r\n        /// </summary>\r\n        [Test]\r\n        public void DecimalError()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"error\", \"2316681217\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"0x8a15c001\"));\r\n            Assert.True(result.StdOut.Contains(\"WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests -1978335191.\r\n        /// </summary>\r\n        [Test]\r\n        public void NegativeDecimalError()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"error\", \"-- -1978335191\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"0x8a150029\"));\r\n            Assert.True(result.StdOut.Contains(\"APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_FAILURE\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests 0x8a15c000.\r\n        /// </summary>\r\n        [Test]\r\n        public void HexErrorNotFound()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"error\", \"0x8a15c000\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"0x8a15c000\"));\r\n            Assert.True(result.StdOut.Contains(\"Unknown error code\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests 0xA150202.\r\n        /// </summary>\r\n        [Test]\r\n        public void NonError()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"error\", \"0xA150202\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"0x0a150202\"));\r\n            Assert.True(result.StdOut.Contains(\"WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_APPLICABLE\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE.\r\n        /// </summary>\r\n        [Test]\r\n        public void Symbol()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"error\", \"WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"0x8a15c001\"));\r\n            Assert.True(result.StdOut.Contains(\"WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE\"));\r\n            Assert.AreEqual(2, result.StdOut.Split('\\n', System.StringSplitOptions.RemoveEmptyEntries).Length);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests config.\r\n        /// </summary>\r\n        [Test]\r\n        public void String()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"error\", \"config\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"0x8a15c001\"));\r\n            Assert.True(result.StdOut.Contains(\"WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE\"));\r\n            Assert.True(result.StdOut.Contains(\"0x8a15c110\"));\r\n            Assert.True(result.StdOut.Contains(\"WINGET_CONFIG_ERROR_UNIT_SETTING_CONFIG_ROOT\"));\r\n\r\n            // This contains config in it's message.\r\n            Assert.True(result.StdOut.Contains(\"0x8a150038\"));\r\n            Assert.True(result.StdOut.Contains(\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE\"));\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/FeaturesCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"FeaturesCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// Features command tests.\r\n    /// </summary>\r\n    public class FeaturesCommand : BaseCommand\r\n    {\r\n        /// <summary>\r\n        /// Set up.\r\n        /// </summary>\r\n        [SetUp]\r\n        public void Setup()\r\n        {\r\n            WinGetSettingsHelper.InitializeAllFeatures(false);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tear down.\r\n        /// </summary>\r\n        [TearDown]\r\n        public void TearDown()\r\n        {\r\n            WinGetSettingsHelper.InitializeAllFeatures(false);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests winget features.\r\n        /// </summary>\r\n        [Test]\r\n        public void DisplayFeatures()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"features\", string.Empty);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Direct MSI Installation\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests enabled winget features.\r\n        /// </summary>\r\n        [Test]\r\n        public void EnableExperimentalFeatures()\r\n        {\r\n            WinGetSettingsHelper.ConfigureFeature(\"experimentalArg\", true);\r\n            WinGetSettingsHelper.ConfigureFeature(\"experimentalCmd\", true);\r\n            WinGetSettingsHelper.ConfigureFeature(\"directMSI\", true);\r\n            WinGetSettingsHelper.ConfigureFeature(\"resume\", true);\r\n            WinGetSettingsHelper.ConfigureFeature(\"fonts\", true);\r\n            var result = TestCommon.RunAICLICommand(\"features\", string.Empty);\r\n            Assert.True(result.StdOut.Contains(\"Enabled\"));\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/FontCommand.cs",
    "content": "// -----------------------------------------------------------------------------\n// <copyright file=\"FontCommand.cs\" company=\"Microsoft Corporation\">\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\n// </copyright>\n// -----------------------------------------------------------------------------\n\nnamespace AppInstallerCLIE2ETests\n{\n    using AppInstallerCLIE2ETests.Helpers;\n    using NUnit.Framework;\n\n    /// <summary>\n    /// Test font command.\n    /// </summary>\n    public class FontCommand : BaseCommand\n    {\n        /// <summary>\n        /// One time set up.\n        /// </summary>\n        [OneTimeSetUp]\n        public void OneTimeSetup()\n        {\n            WinGetSettingsHelper.ConfigureFeature(\"fonts\", true);\n        }\n\n        /// <summary>\n        /// Test install a font with user scope.\n        /// </summary>\n        [Test]\n        public void InstallFont_UserScope()\n        {\n            var fontPackageName = \"AppInstallerTest.TestFont\";\n            var fontPackageVersion = \"1.0.0.0\";\n            var installResult = TestCommon.RunAICLICommand(\"install\", fontPackageName);\n            Assert.AreEqual(Constants.ErrorCode.S_OK, installResult.ExitCode);\n            Assert.True(installResult.StdOut.Contains(\"Successfully installed\"));\n            TestCommon.VerifyFontPackage(fontPackageName, fontPackageVersion, TestCommon.Scope.User);\n\n            var uninstallResult = TestCommon.RunAICLICommand(\"uninstall\", fontPackageName);\n            Assert.AreEqual(Constants.ErrorCode.S_OK, uninstallResult.ExitCode);\n            TestCommon.VerifyFontPackage(fontPackageName, fontPackageVersion, TestCommon.Scope.User, false);\n        }\n\n        /// <summary>\n        /// Test install a font with machine scope.\n        /// </summary>\n        [Test]\n        public void InstallFont_MachineScope()\n        {\n            var fontPackageName = \"AppInstallerTest.TestFont\";\n            var fontPackageVersion = \"1.0.0.0\";\n            var result = TestCommon.RunAICLICommand(\"install\", $\"{fontPackageName} --scope Machine\");\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\n            TestCommon.VerifyFontPackage(fontPackageName, fontPackageVersion, TestCommon.Scope.Machine);\n\n            var uninstallResult = TestCommon.RunAICLICommand(\"uninstall\", fontPackageName);\n            Assert.AreEqual(Constants.ErrorCode.S_OK, uninstallResult.ExitCode);\n            TestCommon.VerifyFontPackage(fontPackageName, fontPackageVersion, TestCommon.Scope.Machine, false);\n        }\n\n        /// <summary>\n        /// Test install an invalid font file.\n        /// </summary>\n        [Test]\n        public void InstallInvalidFont()\n        {\n            var result = TestCommon.RunAICLICommand(\"install\", \"AppInstallerTest.TestInvalidFont\");\n            Assert.AreEqual(Constants.ErrorCode.ERROR_FONT_FILE_NOT_SUPPORTED, result.ExitCode);\n            Assert.True(result.StdOut.Contains(\"One or more fonts in the font package is not supported and cannot be installed.\"));\n        }\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/GroupPolicy.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"GroupPolicy.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// Tests for enforcement of Group Policy.\r\n    /// Behavior is better tested in the unit tests; these tests mostly ensure match between the code and the definition.\r\n    /// </summary>\r\n    public class GroupPolicy : BaseCommand\r\n    {\r\n        /// <summary>\r\n        /// Set up.\r\n        /// </summary>\r\n        [SetUp]\r\n        public void Setup()\r\n        {\r\n            WinGetSettingsHelper.InitializeAllFeatures(false);\r\n            GroupPolicyHelper.DeleteExistingPolicies();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tear down.\r\n        /// </summary>\r\n        [TearDown]\r\n        public void TearDown()\r\n        {\r\n            WinGetSettingsHelper.InitializeAllFeatures(false);\r\n            GroupPolicyHelper.DeleteExistingPolicies();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test winget search is disabled by policy.\r\n        /// </summary>\r\n        [Test]\r\n        public void PolicyEnableWinget()\r\n        {\r\n            GroupPolicyHelper.EnableWinget.Disable();\r\n            var result = TestCommon.RunAICLICommand(\"search\", \"foo\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, result.ExitCode);\r\n\r\n            // Scenario if Policy WinGet is disabled but Policy EnableWindowsPackageManagerCommandLineInterfaces is Enabled.\r\n            GroupPolicyHelper.EnableWinGetCommandLineInterfaces.Enable();\r\n            result = TestCommon.RunAICLICommand(\"search\", \"foo\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, result.ExitCode);\r\n\r\n            // Scenario if Policy WinGet is disabled but Policy EnableWindowsPackageManagerCommandLineInterfaces is Not-Configured.\r\n            GroupPolicyHelper.EnableWinGetCommandLineInterfaces.SetNotConfigured();\r\n            result = TestCommon.RunAICLICommand(\"search\", \"foo\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, result.ExitCode);\r\n\r\n            // Scenario if Policy WinGet is enabled but Policy EnableWindowsPackageManagerCommandLineInterfaces is disabled.\r\n            GroupPolicyHelper.EnableWinget.Enable();\r\n            GroupPolicyHelper.EnableWinGetCommandLineInterfaces.Disable();\r\n            result = TestCommon.RunAICLICommand(\"search\", \"foo\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, result.ExitCode);\r\n\r\n            // Scenario if Policy WinGet is Not-Configured  but Policy EnableWindowsPackageManagerCommandLineInterfaces is disabled.\r\n            GroupPolicyHelper.EnableWinget.SetNotConfigured();\r\n            GroupPolicyHelper.EnableWinGetCommandLineInterfaces.Disable();\r\n            result = TestCommon.RunAICLICommand(\"search\", \"foo\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, result.ExitCode);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test winget settings is disable by policy.\r\n        /// </summary>\r\n        [Test]\r\n        public void EnableSettings()\r\n        {\r\n            GroupPolicyHelper.EnableSettings.Disable();\r\n            var result = TestCommon.RunAICLICommand(\"settings\", string.Empty);\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, result.ExitCode);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test experimental features policy.\r\n        /// </summary>\r\n        [Test]\r\n        public void EnableExperimentalFeatures()\r\n        {\r\n            WinGetSettingsHelper.ConfigureFeature(\"experimentalCmd\", true);\r\n            var result = TestCommon.RunAICLICommand(\"experimental\", string.Empty);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n\r\n            // An experimental feature disabled by Group Policy behaves the same as one that is not enabled.\r\n            // The expected result is a command line error as the argument validation rejects this.\r\n            GroupPolicyHelper.EnableExperimentalFeatures.Disable();\r\n            result = TestCommon.RunAICLICommand(\"experimental\", string.Empty);\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_INVALID_CL_ARGUMENTS, result.ExitCode);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install via manifest is disabled by policy.\r\n        /// </summary>\r\n        [Test]\r\n        public void EnableLocalManifests()\r\n        {\r\n            GroupPolicyHelper.EnableLocalManifests.Disable();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"-m {TestCommon.GetTestDataFile(@\"Manifests\\TestExeInstaller.yaml\")}\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, result.ExitCode);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install without checking the hash is disabled by policy.\r\n        /// </summary>\r\n        [Test]\r\n        public void EnableHashOverride()\r\n        {\r\n            GroupPolicyHelper.EnableHashOverride.Disable();\r\n            var result = TestCommon.RunAICLICommand(\"install\", \"AnyPackage --ignore-security-hash\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, result.ExitCode);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install ignoring the malware scan is disabled by policy.\r\n        /// </summary>\r\n        [Test]\r\n        public void EnableIgnoreLocalArchiveMalwareScanOverride()\r\n        {\r\n            GroupPolicyHelper.EnableLocalArchiveMalwareScanOverride.Disable();\r\n            var result = TestCommon.RunAICLICommand(\"install\", \"AnyPackage --ignore-local-archive-malware-scan\");\r\n\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, result.ExitCode);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test winget source is enabled by policy.\r\n        /// </summary>\r\n        [Test]\r\n        public void EnableDefaultSource()\r\n        {\r\n            // Default sources are disabled during setup so they are missing.\r\n            var result = TestCommon.RunAICLICommand(\"source list\", \"winget\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode);\r\n\r\n            GroupPolicyHelper.EnableDefaultSource.Enable();\r\n            result = TestCommon.RunAICLICommand(\"source list\", \"winget\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test store source is enabled by policy.\r\n        /// </summary>\r\n        [Test]\r\n        public void EnableMicrosoftStoreSource()\r\n        {\r\n            // Default sources are disabled during setup so they are missing.\r\n            var result = TestCommon.RunAICLICommand(\"source list\", \"msstore\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode);\r\n\r\n            GroupPolicyHelper.EnableMicrosoftStoreSource.Enable();\r\n            result = TestCommon.RunAICLICommand(\"source list\", \"msstore\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test font source is enabled by policy.\r\n        /// </summary>\r\n        [Test]\r\n        public void EnableFontSource()\r\n        {\r\n            GroupPolicyHelper.EnableFontSource.Disable();\r\n            var result = TestCommon.RunAICLICommand(\"source list\", \"winget-font\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode);\r\n\r\n            GroupPolicyHelper.EnableFontSource.Enable();\r\n            result = TestCommon.RunAICLICommand(\"source list\", \"winget-font\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test additional sources are enabled by policy.\r\n        /// </summary>\r\n        [Test]\r\n        public void EnableAdditionalSources()\r\n        {\r\n            // Remove the test source, then add it with policy.\r\n            TestCommon.RunAICLICommand(\"source remove\", \"TestSource\");\r\n            var result = TestCommon.RunAICLICommand(\"source list\", \"TestSource\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode);\r\n\r\n            GroupPolicyHelper.EnableAdditionalSources.SetEnabledList(new string[]\r\n            {\r\n                \"{\\\"Arg\\\":\\\"https://localhost:5001/TestKit\\\",\\\"Data\\\":\\\"WingetE2E.Tests_8wekyb3d8bbwe\\\",\\\"Identifier\\\":\\\"WingetE2E.Tests_8wekyb3d8bbwe\\\",\\\"Name\\\":\\\"TestSource\\\",\\\"Type\\\":\\\"Microsoft.PreIndexed.Package\\\"}\",\r\n            });\r\n\r\n            result = TestCommon.RunAICLICommand(\"source list\", \"TestSource\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test additional sources with trust levels and explicit are enabled by policy.\r\n        /// </summary>\r\n        [Test]\r\n        public void EnableAdditionalSources_TrustLevel_Explicit()\r\n        {\r\n            // Remove the test source, then add it with policy.\r\n            TestCommon.RunAICLICommand(\"source remove\", \"TestSource\");\r\n            var result = TestCommon.RunAICLICommand(\"source list\", \"TestSource\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode);\r\n\r\n            GroupPolicyHelper.EnableAdditionalSources.SetEnabledList(new string[]\r\n            {\r\n                \"{\\\"Arg\\\":\\\"https://localhost:5001/TestKit\\\",\\\"Data\\\":\\\"WingetE2E.Tests_8wekyb3d8bbwe\\\",\\\"Identifier\\\":\\\"WingetE2E.Tests_8wekyb3d8bbwe\\\",\\\"Name\\\":\\\"TestSource\\\",\\\"Type\\\":\\\"Microsoft.PreIndexed.Package\\\",\\\"TrustLevel\\\":[\\\"Trusted\\\"],\\\"Explicit\\\":true}\",\r\n            });\r\n\r\n            result = TestCommon.RunAICLICommand(\"source list\", \"TestSource\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Trust Level\"));\r\n            Assert.True(result.StdOut.Contains(\"Trusted\"));\r\n\r\n            var searchResult = TestCommon.RunAICLICommand(\"search\", \"TestExampleInstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_NO_SOURCES_DEFINED, searchResult.ExitCode);\r\n            Assert.True(searchResult.StdOut.Contains(\"No sources defined; add one with 'source add' or reset to defaults with 'source reset'\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test enable allowed sources.\r\n        /// </summary>\r\n        [Test]\r\n        public void EnableAllowedSources()\r\n        {\r\n            // Try listing the test source. We should only see it if it is allowed.\r\n            // With allowed sources disabled:\r\n            GroupPolicyHelper.EnableAllowedSources.Disable();\r\n            var result = TestCommon.RunAICLICommand(\"source list\", \"TestSource\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode);\r\n\r\n            // With allowed sources enabled, but not listing the test source:\r\n            GroupPolicyHelper.EnableAdditionalSources.SetEnabledList(new string[]\r\n            {\r\n                \"{\\\"Arg\\\":\\\"An argument\\\",\\\"Data\\\":\\\"Some data\\\",\\\"Identifier\\\":\\\"Test id\\\",\\\"Name\\\":\\\"NotTestSource\\\",\\\"Type\\\":\\\"Microsoft.PreIndexed.Package\\\"}\",\r\n            });\r\n\r\n            result = TestCommon.RunAICLICommand(\"source list\", \"TestSource\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode);\r\n\r\n            // With the test source allowed:\r\n            GroupPolicyHelper.EnableAdditionalSources.SetEnabledList(new string[]\r\n            {\r\n                \"{\\\"Arg\\\":\\\"https://localhost:5001/TestKit\\\",\\\"Data\\\":\\\"WingetE2E.Tests_8wekyb3d8bbwe\\\",\\\"Identifier\\\":\\\"WingetE2E.Tests_8wekyb3d8bbwe\\\",\\\"Name\\\":\\\"TestSource\\\",\\\"Type\\\":\\\"Microsoft.PreIndexed.Package\\\"}\",\r\n            });\r\n\r\n            result = TestCommon.RunAICLICommand(\"source list\", \"TestSource\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests source auto update policy.\r\n        /// </summary>\r\n        [Test]\r\n        public void SourceAutoUpdateInterval()\r\n        {\r\n            // Test this policy by inspecting the result of --info\r\n            GroupPolicyHelper.SourceAutoUpdateInterval.SetEnabledValue(123);\r\n            var result = TestCommon.RunAICLICommand(string.Empty, \"--info\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.IsTrue(result.StdOut.Contains(\"Source Auto Update Interval In Minutes 123\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test configuration is disabled by policy.\r\n        /// </summary>\r\n        [Test]\r\n        public void EnableConfiguration()\r\n        {\r\n            GroupPolicyHelper.EnableConfiguration.Disable();\r\n            var result = TestCommon.RunAICLICommand(\"configure\", TestCommon.GetTestDataFile(\"Configuration\\\\ShowDetails_TestRepo.yml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, result.ExitCode);\r\n\r\n            result = TestCommon.RunAICLICommand(\"configure show\", TestCommon.GetTestDataFile(\"Configuration\\\\ShowDetails_TestRepo.yml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, result.ExitCode);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/GroupPolicyHelper.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"GroupPolicyHelper.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.IO;\r\n    using System.Linq;\r\n    using System.Xml.Linq;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using Microsoft.Win32;\r\n    using Newtonsoft.Json;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// Helper for setting Group Policy settings.\r\n    /// This helper reads the keys and values to use directly from the ADMX file to ensure that the names\r\n    /// used by the source code are correct.\r\n    /// </summary>\r\n    /// <remarks>\r\n    /// This helper modifies the policies for winget configured in the machine.\r\n    /// </remarks>\r\n    public class GroupPolicyHelper\r\n    {\r\n        private const string PoliciesDefinitionFileName = \"DesktopAppInstaller.admx\";\r\n        private static Lazy<XElement> policyDefinitions = new Lazy<XElement>(() =>\r\n        {\r\n            string filePath = TestCommon.GetTestDataFile(PoliciesDefinitionFileName);\r\n            string fileText = File.ReadAllText(filePath);\r\n            return XElement.Parse(fileText);\r\n        });\r\n\r\n        /// <summary>\r\n        /// Name of the policy. Used to identify it in the file.\r\n        /// </summary>\r\n        private string name;\r\n\r\n        /// <summary>\r\n        /// ID of the value element of this policy (if it has one).\r\n        /// This assumes that each policy has a single value element.\r\n        /// </summary>\r\n        private string elementId;\r\n\r\n        private GroupPolicyHelper(string name)\r\n        {\r\n            this.name = name;\r\n        }\r\n\r\n        private GroupPolicyHelper(string name, string elementId)\r\n        {\r\n            this.name = name;\r\n            this.elementId = elementId;\r\n        }\r\n\r\n        // Policies available.\r\n\r\n        /// <summary>\r\n        /// Gets the Enable winget policy.\r\n        /// </summary>\r\n        public static GroupPolicyHelper EnableWinget { get; private set; } = new GroupPolicyHelper(\"EnableAppInstaller\");\r\n\r\n        /// <summary>\r\n        /// Gets the Enable Windows Package Manager CommandLine Interfaces policy.\r\n        /// </summary>\r\n        public static GroupPolicyHelper EnableWinGetCommandLineInterfaces { get; private set; } = new GroupPolicyHelper(\"EnableWindowsPackageManagerCommandLineInterfaces\");\r\n\r\n        /// <summary>\r\n        /// Gets the Enable settings policy.\r\n        /// </summary>\r\n        public static GroupPolicyHelper EnableSettings { get; private set; } = new GroupPolicyHelper(\"EnableSettings\");\r\n\r\n        /// <summary>\r\n        /// Gets the Enable experimental features policy.\r\n        /// </summary>\r\n        public static GroupPolicyHelper EnableExperimentalFeatures { get; private set; } = new GroupPolicyHelper(\"EnableExperimentalFeatures\");\r\n\r\n        /// <summary>\r\n        /// Gets the Enable local manifest policy.\r\n        /// </summary>\r\n        public static GroupPolicyHelper EnableLocalManifests { get; private set; } = new GroupPolicyHelper(\"EnableLocalManifestFiles\");\r\n\r\n        /// <summary>\r\n        /// Gets the Enable hash override policy.\r\n        /// </summary>\r\n        public static GroupPolicyHelper EnableHashOverride { get; private set; } = new GroupPolicyHelper(\"EnableHashOverride\");\r\n\r\n        /// <summary>\r\n        /// Gets the Enable ignore malware scan policy.\r\n        /// </summary>\r\n        public static GroupPolicyHelper EnableLocalArchiveMalwareScanOverride { get; private set; } = new GroupPolicyHelper(\"EnableLocalArchiveMalwareScanOverride\");\r\n\r\n        /// <summary>\r\n        /// Gets the Enable default source policy.\r\n        /// </summary>\r\n        public static GroupPolicyHelper EnableDefaultSource { get; private set; } = new GroupPolicyHelper(\"EnableDefaultSource\");\r\n\r\n        /// <summary>\r\n        /// Gets the Enable store source policy.\r\n        /// </summary>\r\n        public static GroupPolicyHelper EnableMicrosoftStoreSource { get; private set; } = new GroupPolicyHelper(\"EnableMicrosoftStoreSource\");\r\n\r\n        /// <summary>\r\n        /// Gets the Enable font source policy.\r\n        /// </summary>\r\n        public static GroupPolicyHelper EnableFontSource { get; private set; } = new GroupPolicyHelper(\"EnableFontSource\");\r\n\r\n        /// <summary>\r\n        /// Gets the Enable additional sources policy.\r\n        /// </summary>\r\n        public static GroupPolicyHelper EnableAdditionalSources { get; private set; } = new GroupPolicyHelper(\"EnableAdditionalSources\", \"AdditionalSources\");\r\n\r\n        /// <summary>\r\n        /// Gets the Enable allowed sources policy.\r\n        /// </summary>\r\n        public static GroupPolicyHelper EnableAllowedSources { get; private set; } = new GroupPolicyHelper(\"EnableAllowedSources\", \"AllowedSources\");\r\n\r\n        /// <summary>\r\n        /// Gets the Enable Windows Package Manager Configuration Interfaces policy.\r\n        /// </summary>\r\n        public static GroupPolicyHelper EnableConfiguration { get; private set; } = new GroupPolicyHelper(\"EnableWindowsPackageManagerConfiguration\");\r\n\r\n        /// <summary>\r\n        /// Gets the Enable Windows Package Manager proxy command line options policy.\r\n        /// </summary>\r\n        public static GroupPolicyHelper EnableProxyCommandLineOptions { get; private set; } = new GroupPolicyHelper(\"EnableWindowsPackageManagerProxyCommandLineOptions\");\r\n\r\n        /// <summary>\r\n        /// Gets the Enable auto update interval policy.\r\n        /// </summary>\r\n        public static GroupPolicyHelper SourceAutoUpdateInterval { get; private set; } = new GroupPolicyHelper(\"SourceAutoUpdateInterval\", \"SourceAutoUpdateInterval\");\r\n\r\n        private static GroupPolicyHelper[] AllPolicies { get; set; } = new GroupPolicyHelper[]\r\n        {\r\n            EnableWinget,\r\n            EnableSettings,\r\n            EnableExperimentalFeatures,\r\n            EnableLocalManifests,\r\n            EnableHashOverride,\r\n            EnableLocalArchiveMalwareScanOverride,\r\n            EnableDefaultSource,\r\n            EnableMicrosoftStoreSource,\r\n            EnableFontSource,\r\n            EnableAdditionalSources,\r\n            EnableAllowedSources,\r\n            SourceAutoUpdateInterval,\r\n            EnableWinGetCommandLineInterfaces,\r\n            EnableConfiguration,\r\n            EnableProxyCommandLineOptions,\r\n        };\r\n\r\n        /// <summary>\r\n        /// Gets the content of the ADMX file as an XML.\r\n        /// </summary>\r\n        private static XElement PolicyDefinitions => policyDefinitions.Value;\r\n\r\n        /// <summary>\r\n        /// Gets the XML element that defines this policy.\r\n        /// </summary>\r\n        // The XML structure is like this:\r\n        // <policyDefinitions ...>\r\n        //   ...\r\n        //   <policies>\r\n        //     <policy name=\"...\" ... />\r\n        //   </policies>\r\n        // </policyDefinitions>\r\n        private XElement PolicyElement => PolicyDefinitions\r\n            .Element(XmlNames.Policies)\r\n            .Elements(XmlNames.Policy)\r\n            .First(policy => policy.Attribute(XmlNames.Attributes.Name).Value == this.name);\r\n\r\n        /// <summary>\r\n        /// Gets the path to the registry key that backs this policy.\r\n        /// </summary>\r\n        private string KeyPath => this.PolicyElement.Attribute(XmlNames.Attributes.Key).Value;\r\n\r\n        /// <summary>\r\n        /// Gets the name of the registry value that backs this policy.\r\n        /// </summary>\r\n        private string ValueName => this.PolicyElement.Attribute(XmlNames.Attributes.ValueName)?.Value;\r\n\r\n        /// <summary>\r\n        /// Gets the XElement that defines the single value element of this policy.\r\n        /// This only works if the policy has a single element for its value.\r\n        /// </summary>\r\n        // Looks for something like this:\r\n        // <policy>\r\n        //   <elements>\r\n        //     <something id=\"...\" />\r\n        //   </elements>\r\n        // </policy>\r\n        // We use only list and decimal elements.\r\n        private XElement ValueElement => this.PolicyElement\r\n            .Element(XmlNames.Elements)\r\n            .Elements()\r\n            .First(element => element.Attribute(XmlNames.Attributes.Id).Value == this.elementId);\r\n\r\n        /// <summary>\r\n        /// Deletes all of the existing policies from the registry.\r\n        /// </summary>\r\n        public static void DeleteExistingPolicies()\r\n        {\r\n            foreach (var policy in AllPolicies)\r\n            {\r\n                policy.SetNotConfigured();\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Sets the policy to the Enabled state.\r\n        /// This will fail if the policy's EnabledValue does not exist or is not exactly as expected.\r\n        /// </summary>\r\n        public void Enable()\r\n        {\r\n            // The expected format is like this:\r\n            // <enabledValue>\r\n            //   <decimal value=\"1\" />\r\n            // </enabledValue>\r\n            // We expect the value to always be 1, but still parse it to catch errors in the ADMX.\r\n            int enabledValue = GetDecimalValue(this.PolicyElement.Element(XmlNames.EnabledValue));\r\n            using (RegistryKey key = this.GetKey())\r\n            {\r\n                key.SetValue(this.ValueName, enabledValue);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Sets the policy to the Disabled state.\r\n        /// This will fail if the policy's DisabledValue does not exist or is not exactly as expected.\r\n        /// </summary>\r\n        public void Disable()\r\n        {\r\n            // The expected format is like this:\r\n            // <enabledValue>\r\n            //   <decimal value=\"0\" />\r\n            // </enabledValue>\r\n            // We expect the value to always be 0, but still parse it to catch errors in the ADMX.\r\n            int disabledValue = GetDecimalValue(this.PolicyElement.Element(XmlNames.DisabledValue));\r\n            using (RegistryKey key = this.GetKey())\r\n            {\r\n                key.SetValue(this.ValueName, disabledValue);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Sets the policy to the Not Configured state.\r\n        /// This deletes the value associated with the policy, including its list if it has one.\r\n        /// </summary>\r\n        public void SetNotConfigured()\r\n        {\r\n            // Delete the enabled/disabled value\r\n            if (this.ValueName != null)\r\n            {\r\n                using (RegistryKey key = this.GetKey())\r\n                {\r\n                    key.DeleteValue(this.ValueName, throwOnMissingValue: false);\r\n                }\r\n            }\r\n\r\n            // Delete the value element\r\n            if (this.elementId != null)\r\n            {\r\n                if (this.ValueElement.Name == XmlNames.List)\r\n                {\r\n                    // Lists are stored in separate keys.\r\n                    Registry.LocalMachine.DeleteSubKeyTree(this.ValueElement.Attribute(XmlNames.Attributes.Key).Value, throwOnMissingSubKey: false);\r\n                }\r\n                else if (this.ValueElement.Name == XmlNames.Decimal)\r\n                {\r\n                    // Decimals are stored in single values\r\n                    using (RegistryKey key = this.GetKey())\r\n                    {\r\n                        key.DeleteValue(this.ValueElement.Attribute(XmlNames.Attributes.ValueName).Value, throwOnMissingValue: false);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Sets the value of the policy when enabled.\r\n        /// This uses only the \"elements\" of the policy, not the \"enabledValue\".\r\n        /// The type used in the registry is chosen automatically.\r\n        /// </summary>\r\n        /// <param name=\"value\">Value of the policy.</param>\r\n        public void SetEnabledValue(object value)\r\n        {\r\n            using (RegistryKey key = this.GetKey())\r\n            {\r\n                key.SetValue(\r\n                    this.ValueElement.Attribute(XmlNames.Attributes.ValueName).Value,\r\n                    value);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Sets the list value of the policy when enabled.\r\n        /// This sets from the \"elements\" and also sets the enabled value as lists are also gated by a toggle.\r\n        /// This will fail if the value of the policy is not a list.\r\n        /// </summary>\r\n        /// <param name=\"values\">Values to set in the list.</param>\r\n        public void SetEnabledList(IEnumerable<string> values)\r\n        {\r\n            this.Enable();\r\n\r\n            // Delete the existing list\r\n            string listKeyPath = this.ValueElement.Attribute(XmlNames.Attributes.Key).Value;\r\n            Registry.LocalMachine.DeleteSubKeyTree(listKeyPath, throwOnMissingSubKey: false);\r\n\r\n            // Create and fill the key.\r\n            // This assumes that the values don't need to have special names or prefixes.\r\n            var listKey = Registry.LocalMachine.CreateSubKey(listKeyPath);\r\n            int index = 0;\r\n            foreach (string value in values)\r\n            {\r\n                TestContext.Out.WriteLine($\"Setting {this.name} list value: {value}\");\r\n                listKey.SetValue(index++.ToString(), value);\r\n            }\r\n\r\n            listKey.Close();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Sets the list value of the policy when enabled.\r\n        /// This sets from the \"elements\" and also sets the enabled value as lists are also gated by a toggle.\r\n        /// This will fail if the value of the policy is not a list.\r\n        /// </summary>\r\n        /// <param name=\"values\">Values to set in the list.</param>\r\n        public void SetEnabledList(IEnumerable<GroupPolicySource> values)\r\n        {\r\n            this.SetEnabledList(values.Select(source => JsonConvert.SerializeObject(source)));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the value from a \"decimal\" child element.\r\n        /// </summary>\r\n        /// <param name=\"element\">Element containing the decimal.</param>\r\n        /// <returns>Value in the element.</returns>\r\n        private static int GetDecimalValue(XElement element)\r\n        {\r\n            // Reads a child that looks like this:\r\n            // <decimal value=\"X\" />\r\n            return int.Parse(element.Element(XmlNames.Decimal).Attribute(XmlNames.Attributes.Value).Value);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the registry key backing this policy.\r\n        /// </summary>\r\n        /// <remarks>\r\n        /// This assumes that all the policies are machine-wide.\r\n        /// If this changes, we will need to parse the class=\"machine|user\" attribute.\r\n        /// </remarks>\r\n        private RegistryKey GetKey()\r\n        {\r\n            return Registry.LocalMachine.CreateSubKey(this.KeyPath);\r\n        }\r\n\r\n        /// <summary>\r\n        /// A group policy source object as used by AdditionalSources and AllowedSources.\r\n        /// </summary>\r\n        public class GroupPolicySource\r\n        {\r\n            /// <summary>\r\n            /// Gets or sets the source name.\r\n            /// </summary>\r\n            public string Name { get; set; }\r\n\r\n            /// <summary>\r\n            /// Gets or sets the source arg.\r\n            /// </summary>\r\n            public string Arg { get; set; }\r\n\r\n            /// <summary>\r\n            /// Gets or sets the source type.\r\n            /// </summary>\r\n            public string Type { get; set; }\r\n\r\n            /// <summary>\r\n            /// Gets or sets the source data.\r\n            /// </summary>\r\n            public string Data { get; set; }\r\n\r\n            /// <summary>\r\n            /// Gets or sets the source identifier.\r\n            /// </summary>\r\n            public string Identifier { get; set; }\r\n\r\n            /// <summary>\r\n            /// Gets or sets certificate pinning.\r\n            /// </summary>\r\n            public GroupPolicyCertificatePinning CertificatePinning { get; set; }\r\n\r\n            /// <summary>\r\n            /// Gets or sets the source trust levels.\r\n            /// </summary>\r\n            public string[] TrustLevel { get; set; }\r\n\r\n            /// <summary>\r\n            /// Gets or sets a value indicating whether the source is explicit.\r\n            /// </summary>\r\n            public bool Explicit { get; set; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Group policy certificate pinning.\r\n        /// </summary>\r\n        public class GroupPolicyCertificatePinning\r\n        {\r\n            /// <summary>\r\n            /// Gets or sets the cert pinning chains.\r\n            /// </summary>\r\n            public GroupPolicyCertificatePinningChain[] Chains { get; set; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Group policy certificate pinning chain.\r\n        /// </summary>\r\n        public class GroupPolicyCertificatePinningChain\r\n        {\r\n            /// <summary>\r\n            /// Gets or sets the cert pinning details.\r\n            /// </summary>\r\n            public GroupPolicyCertificatePinningDetails[] Chain { get; set; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Group policy certificate pinning details.\r\n        /// </summary>\r\n        public class GroupPolicyCertificatePinningDetails\r\n        {\r\n            /// <summary>\r\n            /// Gets or sets the validation.\r\n            /// </summary>\r\n            public string[] Validation { get; set; }\r\n\r\n            /// <summary>\r\n            /// Gets or sets the embedded cert.\r\n            /// </summary>\r\n            public string EmbeddedCertificate { get; set; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Names of the XML elements and attributes that make up the definition file.\r\n        /// </summary>\r\n        private static class XmlNames\r\n        {\r\n            // Root element\r\n            public static readonly XName PolicyDefinitions = XName.Get(\"policyDefinitions\", Namespace);\r\n\r\n            public static readonly XName Policies = XName.Get(\"policies\", Namespace);\r\n            public static readonly XName Policy = XName.Get(\"policy\", Namespace);\r\n\r\n            public static readonly XName EnabledValue = XName.Get(\"enabledValue\", Namespace);\r\n            public static readonly XName DisabledValue = XName.Get(\"disabledValue\", Namespace);\r\n            public static readonly XName Elements = XName.Get(\"elements\", Namespace);\r\n\r\n            public static readonly XName Decimal = XName.Get(\"decimal\", Namespace);\r\n            public static readonly XName List = XName.Get(\"list\", Namespace);\r\n\r\n            private const string Namespace = \"http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions\";\r\n\r\n            public static class Attributes\r\n            {\r\n                public const string Name = \"name\";\r\n                public const string Value = \"value\";\r\n                public const string Id = \"id\";\r\n                public const string Key = \"key\";\r\n                public const string ValueName = \"valueName\";\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/HashCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"HashCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\r\n    using NUnit.Framework.Internal;\r\n\r\n    /// <summary>\r\n    /// Test hash command.\r\n    /// </summary>\r\n    public class HashCommand : BaseCommand\r\n    {\r\n        /// <summary>\r\n        /// Test hash file.\r\n        /// </summary>\r\n        [Test]\r\n        public void HashFile()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"hash\", TestCommon.GetTestDataFile(\"AppInstallerTestMsiInstaller.msi\"));\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"21d90ee9b3569590c624836ef50bf39791c7184869c227eedc00585e1f39b4de\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test hash msix.\r\n        /// </summary>\r\n        [Test]\r\n        public void HashMSIX()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"hash\", TestCommon.GetTestDataFile(Constants.TestPackage) + \" -m\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"08917b781939a7796746b5e2349e1f1d83b6c15599b60cd3f62816f15e565fc4\"));\r\n            Assert.True(result.StdOut.Contains(\"223b318c4b1154a1fb72b1bc23422810faa5ce899a8e774ba2a02834b2058f00\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test hash invalid msix.\r\n        /// </summary>\r\n        [Test]\r\n        public void HashInvalidMSIX()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"hash\", TestCommon.GetTestDataFile(\"AppInstallerTestMsiInstaller.msi\") + \" -m\");\r\n            Assert.AreEqual(Constants.ErrorCode.OPC_E_ZIP_MISSING_END_OF_CENTRAL_DIRECTORY, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"21d90ee9b3569590c624836ef50bf39791c7184869c227eedc00585e1f39b4de\"));\r\n            Assert.True(result.StdOut.Contains(\"Please verify that the input file is a valid, signed MSIX.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test hash file not found.\r\n        /// </summary>\r\n        [Test]\r\n        public void HashFileNotFound()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"hash\", TestCommon.GetTestDataFile(\"DoesNot.Exist\"));\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_FILE_NOT_FOUND, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"File does not exist\"));\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/Helpers/TestCommon.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"TestCommon.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests.Helpers\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.Diagnostics;\r\n    using System.IO;\r\n    using System.Linq;\r\n    using System.Management.Automation;\r\n    using System.Reflection;\r\n    using System.Security.Principal;\r\n    using System.Text;\r\n    using System.Threading;\r\n    using AppInstallerCLIE2ETests;\r\n    using AppInstallerCLIE2ETests.PowerShell;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.Win32;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// Test common.\r\n    /// </summary>\r\n    public static class TestCommon\r\n    {\r\n        /// <summary>\r\n        /// Scope.\r\n        /// </summary>\r\n        public enum Scope\r\n        {\r\n            /// <summary>\r\n            /// None.\r\n            /// </summary>\r\n            Unknown,\r\n\r\n            /// <summary>\r\n            /// User.\r\n            /// </summary>\r\n            User,\r\n\r\n            /// <summary>\r\n            /// Machine.\r\n            /// </summary>\r\n            Machine,\r\n        }\r\n\r\n        /// <summary>\r\n        /// The type of location.\r\n        /// </summary>\r\n        public enum TestModuleLocation\r\n        {\r\n            /// <summary>\r\n            /// Current user.\r\n            /// </summary>\r\n            CurrentUser,\r\n\r\n            /// <summary>\r\n            /// All users.\r\n            /// </summary>\r\n            AllUsers,\r\n\r\n            /// <summary>\r\n            /// Winget module path.\r\n            /// </summary>\r\n            WinGetModulePath,\r\n\r\n            /// <summary>\r\n            /// Custom.\r\n            /// </summary>\r\n            Custom,\r\n\r\n            /// <summary>\r\n            /// Default winget configure.\r\n            /// </summary>\r\n            Default,\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets a value indicating whether the current assembly is executing in an administrative context.\r\n        /// </summary>\r\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"Interoperability\", \"CA1416:Validate platform compatibility\", Justification = \"Windows only API\")]\r\n        public static bool ExecutingAsAdministrator\r\n        {\r\n            get\r\n            {\r\n                WindowsIdentity identity = WindowsIdentity.GetCurrent();\r\n                WindowsPrincipal principal = new (identity);\r\n                return principal.IsInRole(WindowsBuiltInRole.Administrator);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets a value indicating whether the test is running in the CI build.\r\n        /// </summary>\r\n        public static bool IsCIEnvironment\r\n        {\r\n            get\r\n            {\r\n                return Environment.GetEnvironmentVariable(\"BUILD_BUILDNUMBER\") != null;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Run winget command.\r\n        /// </summary>\r\n        /// <param name=\"command\">Command to run.</param>\r\n        /// <param name=\"parameters\">Parameters.</param>\r\n        /// <param name=\"stdIn\">Optional std in.</param>\r\n        /// <param name=\"timeOut\">Optional timeout.</param>\r\n        /// <param name=\"throwOnTimeout\">Throw on timeout.</param>\r\n        /// <returns>The result of the command.</returns>\r\n        public static RunCommandResult RunAICLICommand(string command, string parameters, string stdIn = null, int timeOut = 60000, bool throwOnTimeout = true)\r\n        {\r\n            string correlationParameter = \" --correlation \" + Guid.NewGuid().ToString();\r\n\r\n            // Don't include correlation when the call has an option ending `--` value.\r\n            foreach (string part in parameters.Split(' ', StringSplitOptions.TrimEntries))\r\n            {\r\n                if (part == \"--\")\r\n                {\r\n                    correlationParameter = string.Empty;\r\n                }\r\n            }\r\n\r\n            return RunAICLICommandViaDirectProcess(command, parameters + correlationParameter, stdIn, timeOut, throwOnTimeout);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Run command.\r\n        /// </summary>\r\n        /// <param name=\"fileName\">File name.</param>\r\n        /// <param name=\"args\">Args.</param>\r\n        /// <param name=\"timeOut\">Time out.</param>\r\n        /// <param name=\"throwOnFailure\">If true, throw instead of returning false on a failure.</param>\r\n        /// <returns>True if exit code is 0.</returns>\r\n        public static bool RunCommand(string fileName, string args = \"\", int timeOut = 60000, bool throwOnFailure = false)\r\n        {\r\n            RunCommandResult result = RunCommandWithResult(fileName, args, timeOut);\r\n\r\n            if (result.ExitCode != 0)\r\n            {\r\n                TestContext.Out.WriteLine($\"Command failed with: {result.ExitCode}\");\r\n                if (throwOnFailure)\r\n                {\r\n                    throw new RunCommandException(fileName, args, result);\r\n                }\r\n\r\n                return false;\r\n            }\r\n            else\r\n            {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Run command with result.\r\n        /// </summary>\r\n        /// <param name=\"fileName\">File name.</param>\r\n        /// <param name=\"args\">Args.</param>\r\n        /// <param name=\"timeOut\">Optional timeout.</param>\r\n        /// <returns>Command result.</returns>\r\n        public static RunCommandResult RunCommandWithResult(string fileName, string args, int timeOut = 60000)\r\n        {\r\n            TestContext.Out.WriteLine($\"Running command: {fileName} {args}\");\r\n\r\n            Process p = new Process();\r\n            p.StartInfo = new ProcessStartInfo(fileName, args);\r\n            p.StartInfo.RedirectStandardOutput = true;\r\n            p.StartInfo.RedirectStandardError = true;\r\n            p.Start();\r\n\r\n            RunCommandResult result = new ();\r\n            if (p.WaitForExit(timeOut))\r\n            {\r\n                result.ExitCode = p.ExitCode;\r\n                result.StdOut = p.StandardOutput.ReadToEnd();\r\n                result.StdErr = p.StandardError.ReadToEnd();\r\n\r\n                if (TestSetup.Parameters.VerboseLogging)\r\n                {\r\n                    TestContext.Out.WriteLine($\"Command run finished. {fileName} {args} {timeOut}. Output: {result.StdOut} Error: {result.StdErr}\");\r\n                }\r\n            }\r\n            else\r\n            {\r\n                throw new TimeoutException($\"Command run timed out. {fileName} {args} {timeOut}\");\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Get test file path.\r\n        /// </summary>\r\n        /// <param name=\"fileName\">Test file name.</param>\r\n        /// <returns>Path of test file.</returns>\r\n        public static string GetTestFile(string fileName)\r\n        {\r\n            return Path.Combine(TestContext.CurrentContext.TestDirectory, fileName);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Get test data file path.\r\n        /// </summary>\r\n        /// <param name=\"fileName\">File name.</param>\r\n        /// <returns>Test file data path.</returns>\r\n        public static string GetTestDataFile(string fileName)\r\n        {\r\n            return GetTestFile(Path.Combine(\"TestData\", fileName));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Get test work directory. Creates if not exists.\r\n        /// </summary>\r\n        /// <returns>The work directory.</returns>\r\n        public static string GetTestWorkDir()\r\n        {\r\n            string workDir = Path.Combine(TestContext.CurrentContext.TestDirectory, \"WorkDirectory\");\r\n            Directory.CreateDirectory(workDir);\r\n            return workDir;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Create random test directory.\r\n        /// </summary>\r\n        /// <returns>Path of new test directory.</returns>\r\n        public static string GetRandomTestDir()\r\n        {\r\n            string randDir = Path.Combine(GetTestWorkDir(), Path.GetRandomFileName());\r\n            Directory.CreateDirectory(randDir);\r\n            return randDir;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates new random file name. File is not created.\r\n        /// </summary>\r\n        /// <param name=\"extension\">Extension of random file.</param>\r\n        /// <returns>Path of random file.</returns>\r\n        public static string GetRandomTestFile(string extension)\r\n        {\r\n            return Path.Combine(GetTestWorkDir(), Path.GetRandomFileName() + extension);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Install msix package via PowerShell.\r\n        /// </summary>\r\n        /// <param name=\"file\">Msix file.</param>\r\n        /// <returns>True if installed.</returns>\r\n        public static bool InstallMsix(string file)\r\n        {\r\n            return RunCommand(\"powershell\", $\"Add-AppxPackage \\\"{file}\\\"\", throwOnFailure: true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Install and register msix package via appx manifest.\r\n        /// </summary>\r\n        /// <param name=\"packagePath\">Path to package.</param>\r\n        /// <param name=\"forceShutdown\">Force shutdown.</param>\r\n        /// <param name=\"throwOnFailure\">Throw on failure.</param>\r\n        /// <returns>True if installed correctly.</returns>\r\n        public static bool InstallMsixRegister(string packagePath, bool forceShutdown = false, bool throwOnFailure = true)\r\n        {\r\n            string manifestFile = Path.Combine(packagePath, \"AppxManifest.xml\");\r\n\r\n            var command = $\"Add-AppxPackage -Register \\\"{manifestFile}\\\"\";\r\n            if (forceShutdown)\r\n            {\r\n                command += \" -ForceTargetApplicationShutdown\";\r\n            }\r\n\r\n            return RunCommand(\"powershell\", command, throwOnFailure: throwOnFailure);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Remove msix package.\r\n        /// </summary>\r\n        /// <param name=\"name\">Package to remove.</param>\r\n        /// <param name=\"isProvisioned\">Whether the package is provisioned.</param>\r\n        /// <returns>True if removed correctly.</returns>\r\n        public static bool RemoveMsix(string name, bool isProvisioned = false)\r\n        {\r\n            if (isProvisioned)\r\n            {\r\n                return RunCommand(\"powershell\", $\"Get-AppxProvisionedPackage -Online | Where-Object {{$_.PackageName -like \\\"*{name}*\\\"}} | Remove-AppxProvisionedPackage -Online -AllUsers\") &&\r\n                    RunCommand(\"powershell\", $\"Get-AppxPackage \\\"{name}\\\" | Remove-AppxPackage -AllUsers\");\r\n            }\r\n            else\r\n            {\r\n                return RunCommand(\"powershell\", $\"Get-AppxPackage \\\"{name}\\\" | Remove-AppxPackage\");\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the portable symlink directory.\r\n        /// </summary>\r\n        /// <param name=\"scope\">Scope.</param>\r\n        /// <returns>The path of the symlinks.</returns>\r\n        public static string GetPortableSymlinkDirectory(Scope scope)\r\n        {\r\n            if (scope == Scope.User)\r\n            {\r\n                return Path.Combine(Environment.GetEnvironmentVariable(\"LocalAppData\"), \"Microsoft\", \"WinGet\", \"Links\");\r\n            }\r\n            else\r\n            {\r\n                return Path.Combine(Environment.GetEnvironmentVariable(\"ProgramFiles\"), \"WinGet\", \"Links\");\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the portable package directory.\r\n        /// </summary>\r\n        /// <returns>The portable package directory.</returns>\r\n        public static string GetPortablePackagesDirectory()\r\n        {\r\n            return Path.Combine(Environment.GetEnvironmentVariable(\"LocalAppData\"), \"Microsoft\", \"WinGet\", \"Packages\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the default download directory for the download command.\r\n        /// </summary>\r\n        /// <returns>The default download directory.</returns>\r\n        public static string GetDefaultDownloadDirectory()\r\n        {\r\n            return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), \"Downloads\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the checkpoints directory based on whether the command is invoked in desktop package or not.\r\n        /// </summary>\r\n        /// <returns>The default checkpoints directory.</returns>\r\n        public static string GetCheckpointsDirectory()\r\n        {\r\n            if (TestSetup.Parameters.PackagedContext)\r\n            {\r\n                return Path.Combine(Environment.GetEnvironmentVariable(\"LocalAppData\"), Constants.CheckpointDirectoryPackaged);\r\n            }\r\n            else\r\n            {\r\n                return Path.Combine(Environment.GetEnvironmentVariable(\"LocalAppData\"), Constants.CheckpointDirectoryUnpackaged);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the fonts directory based on scope.\r\n        /// </summary>\r\n        /// <param name=\"scope\">Scope.</param>\r\n        /// <returns>The path of the fonts directory.</returns>\r\n        public static string GetFontsDirectory(Scope scope)\r\n        {\r\n            if (scope == Scope.Machine)\r\n            {\r\n                return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), \"Fonts\");\r\n            }\r\n            else\r\n            {\r\n                return Path.Combine(Environment.GetEnvironmentVariable(\"LocalAppData\"), \"Microsoft\", \"Windows\", \"Fonts\");\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verify font package.\r\n        /// </summary>\r\n        /// <param name=\"packageName\">Name of the package.</param>\r\n        /// <param name=\"packageVersion\">Name of the package version.</param>\r\n        /// <param name=\"scope\">Scope.</param>\r\n        /// <param name=\"shouldExist\">If package should exist.</param>\r\n        public static void VerifyFontPackage(\r\n            string packageName,\r\n            string packageVersion,\r\n            Scope scope = Scope.User,\r\n            bool shouldExist = true)\r\n        {\r\n            RegistryKey baseKey = (scope == Scope.Machine) ? Registry.LocalMachine : Registry.CurrentUser;\r\n\r\n            var fileList = new List<string>();\r\n            using (RegistryKey fontsRegistryKey = baseKey.OpenSubKey(Constants.FontsSubKey, true))\r\n            {\r\n                using var winGetRootKey = fontsRegistryKey.OpenSubKey(\"Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\");\r\n                if (shouldExist)\r\n                {\r\n                    Assert.IsNotNull(winGetRootKey);\r\n                }\r\n                else\r\n                {\r\n                    return;\r\n                }\r\n\r\n                using var packageNameSubkey = winGetRootKey.OpenSubKey(packageName);\r\n                if (shouldExist)\r\n                {\r\n                    Assert.IsNotNull(packageNameSubkey);\r\n                }\r\n\r\n                if (packageNameSubkey is not null)\r\n                {\r\n                    using var versionSubkey = packageNameSubkey.OpenSubKey(packageVersion);\r\n\r\n                    if (shouldExist)\r\n                    {\r\n                        Assert.IsNotNull(versionSubkey);\r\n                    }\r\n                    else\r\n                    {\r\n                        Assert.IsNull(versionSubkey);\r\n                    }\r\n\r\n                    if (versionSubkey is not null)\r\n                    {\r\n                        var valueNames = versionSubkey.GetValueNames();\r\n                        foreach (var valueName in valueNames)\r\n                        {\r\n                            fileList.Add(versionSubkey.GetValue(valueName).ToString());\r\n                        }\r\n\r\n                        Assert.AreEqual(valueNames.Length, fileList.Count);\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Verify each package file we expect to exist actually exists.\r\n            foreach (var file in fileList)\r\n            {\r\n                Assert.IsTrue(File.Exists(file));\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verify portable package.\r\n        /// </summary>\r\n        /// <param name=\"installDir\">Install dir.</param>\r\n        /// <param name=\"commandAlias\">Command alias.</param>\r\n        /// <param name=\"filename\">File name.</param>\r\n        /// <param name=\"productCode\">Product code.</param>\r\n        /// <param name=\"shouldExist\">Should exists.</param>\r\n        /// <param name=\"scope\">Scope.</param>\r\n        /// <param name=\"installDirectoryAddedToPath\">Install directory added to path instead of the symlink directory.</param>\r\n        public static void VerifyPortablePackage(\r\n            string installDir,\r\n            string commandAlias,\r\n            string filename,\r\n            string productCode,\r\n            bool shouldExist,\r\n            Scope scope = Scope.User,\r\n            bool installDirectoryAddedToPath = false)\r\n        {\r\n            // When portables are installed, if the exe path is inside a directory it will not be aliased\r\n            // if the exe path is at the root level, it will be aliased. Therefore, if either exist, the exe exists\r\n            string exePath = Path.Combine(installDir, filename);\r\n            string exeAliasedPath = Path.Combine(installDir, commandAlias);\r\n            bool exeExists = File.Exists(exePath) || File.Exists(exeAliasedPath);\r\n\r\n            string symlinkDirectory = GetPortableSymlinkDirectory(scope);\r\n            string symlinkPath = Path.Combine(symlinkDirectory, commandAlias);\r\n            bool symlinkExists = File.Exists(symlinkPath);\r\n\r\n            bool portableEntryExists;\r\n            RegistryKey baseKey = scope == Scope.User ? Registry.CurrentUser : Registry.LocalMachine;\r\n            string uninstallSubKey = Constants.UninstallSubKey;\r\n            using (RegistryKey uninstallRegistryKey = baseKey.OpenSubKey(uninstallSubKey, true))\r\n            {\r\n                RegistryKey portableEntry = uninstallRegistryKey.OpenSubKey(productCode, true);\r\n                portableEntryExists = portableEntry != null;\r\n            }\r\n\r\n            bool isAddedToPath;\r\n            string pathSubKey = scope == Scope.User ? Constants.PathSubKey_User : Constants.PathSubKey_Machine;\r\n            using (RegistryKey environmentRegistryKey = baseKey.OpenSubKey(pathSubKey, true))\r\n            {\r\n                string pathName = \"Path\";\r\n                var currentPathValue = (string)environmentRegistryKey.GetValue(pathName);\r\n                var portablePathValue = (installDirectoryAddedToPath ? installDir : symlinkDirectory) + ';';\r\n                isAddedToPath = currentPathValue.Contains(portablePathValue);\r\n            }\r\n\r\n            // Always clean up as best effort.\r\n            RunAICLICommand(\"uninstall\", $\"--product-code {productCode} --force\");\r\n\r\n            Assert.AreEqual(shouldExist, exeExists, $\"Expected portable exe path: {exePath}\");\r\n            Assert.AreEqual(shouldExist && !installDirectoryAddedToPath, symlinkExists, $\"Expected portable symlink path: {symlinkPath}\");\r\n            Assert.AreEqual(shouldExist, portableEntryExists, $\"Expected {productCode} subkey in path: {uninstallSubKey}\");\r\n            Assert.AreEqual(shouldExist, isAddedToPath, $\"Expected path variable: {(installDirectoryAddedToPath ? installDir : symlinkDirectory)}\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Copies log files to the path %TEMP%\\E2ETestLogs.\r\n        /// </summary>\r\n        public static void PublishE2ETestLogs()\r\n        {\r\n            string tempPath = Path.GetTempPath();\r\n            string localAppDataPath = Environment.GetEnvironmentVariable(\"LocalAppData\");\r\n            string testLogsPackagedSourcePath = Path.Combine(localAppDataPath, Constants.E2ETestLogsPathPackaged);\r\n            string testLogsUnpackagedSourcePath = Path.Combine(tempPath, Constants.E2ETestLogsPathUnpackaged);\r\n            string testLogsDestPath = Path.Combine(tempPath, \"E2ETestLogs\");\r\n            string testLogsPackagedDestPath = Path.Combine(testLogsDestPath, \"Packaged\");\r\n            string testLogsUnpackagedDestPath = Path.Combine(testLogsDestPath, \"Unpackaged\");\r\n\r\n            if (Directory.Exists(testLogsPackagedSourcePath))\r\n            {\r\n                CopyDirectory(testLogsPackagedSourcePath, testLogsPackagedDestPath);\r\n            }\r\n\r\n            if (Directory.Exists(testLogsUnpackagedSourcePath))\r\n            {\r\n                CopyDirectory(testLogsUnpackagedSourcePath, testLogsUnpackagedDestPath);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the server certificate as a hex string.\r\n        /// </summary>\r\n        /// <returns>Hex string.</returns>\r\n        public static string GetTestServerCertificateHexString()\r\n        {\r\n            if (string.IsNullOrEmpty(TestSetup.Parameters.LocalServerCertPath))\r\n            {\r\n                throw new Exception($\"{Constants.LocalServerCertPathParameter} not set.\");\r\n            }\r\n\r\n            if (!File.Exists(TestSetup.Parameters.LocalServerCertPath))\r\n            {\r\n                throw new FileNotFoundException(TestSetup.Parameters.LocalServerCertPath);\r\n            }\r\n\r\n            return Convert.ToHexString(File.ReadAllBytes(TestSetup.Parameters.LocalServerCertPath));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verify exe installer correctly.\r\n        /// </summary>\r\n        /// <param name=\"installDir\">Install directory.</param>\r\n        /// <param name=\"expectedContent\">Optional expected content.</param>\r\n        /// <returns>True if success.</returns>\r\n        public static bool VerifyTestExeInstalled(string installDir, string expectedContent = null)\r\n        {\r\n            bool verifyInstallSuccess = true;\r\n\r\n            if (!File.Exists(Path.Combine(installDir, Constants.TestExeInstalledFileName)))\r\n            {\r\n                TestContext.Out.WriteLine($\"TestExeInstalled.exe not found at {installDir}\");\r\n                verifyInstallSuccess = false;\r\n            }\r\n\r\n            if (verifyInstallSuccess && !string.IsNullOrEmpty(expectedContent))\r\n            {\r\n                string content = File.ReadAllText(Path.Combine(installDir, Constants.TestExeInstalledFileName));\r\n                TestContext.Out.WriteLine($\"TestExeInstalled.exe content: {content}\");\r\n                verifyInstallSuccess = content.Contains(expectedContent);\r\n            }\r\n\r\n            return verifyInstallSuccess;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies if the repair of the test executable was successful.\r\n        /// </summary>\r\n        /// <param name=\"installDir\">The directory where the test executable is installed.</param>\r\n        /// <param name=\"expectedContent\">The expected content in the test executable file. This is optional.</param>\r\n        /// <returns>Returns true if the repair was successful, false otherwise.</returns>\r\n        public static bool VerifyTestExeRepairSuccessful(string installDir, string expectedContent = null)\r\n        {\r\n            bool verifyRepairSuccess = true;\r\n\r\n            if (!File.Exists(Path.Combine(installDir, Constants.TestExeRepairCompletedFileName)))\r\n            {\r\n                TestContext.Out.WriteLine($\"{Constants.TestExeRepairCompletedFileName} not found at {installDir}\");\r\n                verifyRepairSuccess = false;\r\n            }\r\n\r\n            if (verifyRepairSuccess && !string.IsNullOrEmpty(expectedContent))\r\n            {\r\n                string content = File.ReadAllText(Path.Combine(installDir, Constants.TestExeRepairCompletedFileName));\r\n                TestContext.Out.WriteLine($\"TestExeRepairCompleted.txt content: {content}\");\r\n                verifyRepairSuccess = content.Contains(expectedContent);\r\n            }\r\n\r\n            return verifyRepairSuccess;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Assert installer and manifest downloaded correctly and cleanup.\r\n        /// </summary>\r\n        /// <param name=\"downloadDir\">Download directory.</param>\r\n        /// <param name=\"name\">Package name.</param>\r\n        /// <param name=\"version\">Package version.</param>\r\n        /// <param name=\"arch\">Installer architecture.</param>\r\n        /// <param name=\"scope\">Installer scope.</param>\r\n        /// <param name=\"installerType\">Installer type.</param>\r\n        /// <param name=\"locale\">Installer locale.</param>\r\n        /// <param name=\"isArchive\">Boolean value indicating whether the installer is an archive.</param>\r\n        /// <param name=\"cleanup\">Boolean value indicating whether to remove the installer file and directory.</param>\r\n        public static void AssertInstallerDownload(\r\n            string downloadDir,\r\n            string name,\r\n            string version,\r\n            Windows.System.ProcessorArchitecture arch,\r\n            Scope scope,\r\n            PackageInstallerType installerType,\r\n            string locale = null,\r\n            bool isArchive = false,\r\n            bool cleanup = true)\r\n        {\r\n            string expectedFileName = $\"{name}_{version}\";\r\n\r\n            if (scope != Scope.Unknown)\r\n            {\r\n                expectedFileName += $\"_{scope}\";\r\n            }\r\n\r\n            expectedFileName += $\"_{arch}_{installerType}\";\r\n\r\n            if (!string.IsNullOrEmpty(locale))\r\n            {\r\n                expectedFileName += $\"_{locale}\";\r\n            }\r\n\r\n            string installerExtension;\r\n            if (isArchive)\r\n            {\r\n                installerExtension = \".zip\";\r\n            }\r\n            else\r\n            {\r\n                installerExtension = installerType switch\r\n                {\r\n                    PackageInstallerType.Msi => \".msi\",\r\n                    PackageInstallerType.Msix => \".msix\",\r\n                    _ => \".exe\"\r\n                };\r\n            }\r\n\r\n            string installerDownloadPath = Path.Combine(downloadDir, expectedFileName + installerExtension);\r\n            string manifestDownloadPath = Path.Combine(downloadDir, expectedFileName + \".yaml\");\r\n\r\n            Assert.IsTrue(Directory.Exists(downloadDir), $\"Download directory does not exist: {downloadDir}\");\r\n            Assert.IsTrue(File.Exists(installerDownloadPath), $\"Installer file does not exist: {installerDownloadPath}\");\r\n            Assert.IsTrue(File.Exists(manifestDownloadPath), $\"Manifest file does not exist: {manifestDownloadPath}\");\r\n\r\n            if (cleanup)\r\n            {\r\n                Directory.Delete(downloadDir, true);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Best effort test exe cleanup.\r\n        /// </summary>\r\n        /// <param name=\"installDir\">Install directory.</param>\r\n        public static void BestEffortTestExeCleanup(string installDir)\r\n        {\r\n            var uninstallerPath = Path.Combine(installDir, Constants.TestExeUninstallerFileName);\r\n            if (File.Exists(uninstallerPath))\r\n            {\r\n                RunCommand(Path.Combine(installDir, Constants.TestExeUninstallerFileName));\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Best effort test exe cleanup and install directory cleanup.\r\n        /// </summary>\r\n        /// <param name=\"installDir\">Install directory.</param>\r\n        public static void CleanupTestExeAndDirectory(string installDir)\r\n        {\r\n            // Always try clean up and ignore clean up failure\r\n            BestEffortTestExeCleanup(installDir);\r\n\r\n            // Delete the install directory to reclaim disk space\r\n            if (Directory.Exists(installDir))\r\n            {\r\n                Directory.Delete(installDir, true);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verify exe installer correctly and then uninstall it.\r\n        /// </summary>\r\n        /// <param name=\"installDir\">Install directory.</param>\r\n        /// <param name=\"expectedContent\">Optional expected content.</param>\r\n        /// <returns>True if success.</returns>\r\n        public static bool VerifyTestExeInstalledAndCleanup(string installDir, string expectedContent = null)\r\n        {\r\n            bool verifyInstallSuccess = VerifyTestExeInstalled(installDir, expectedContent);\r\n\r\n            // Always try clean up and ignore clean up failure\r\n            BestEffortTestExeCleanup(installDir);\r\n\r\n            return verifyInstallSuccess;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verify exe repair completed and cleanup.\r\n        /// </summary>\r\n        /// <param name=\"installDir\">Install directory.</param>\r\n        /// <param name=\"expectedContent\">Optional expected context.</param>\r\n        /// <returns>True if success.</returns>\r\n        public static bool VerifyTestExeRepairCompletedAndCleanup(string installDir, string expectedContent = null)\r\n        {\r\n            bool verifyRepairSuccess = VerifyTestExeRepairSuccessful(installDir, expectedContent);\r\n            CleanupTestExeAndDirectory(installDir);\r\n\r\n            return verifyRepairSuccess;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verify msi installed correctly.\r\n        /// </summary>\r\n        /// <param name=\"installDir\">Installed directory.</param>\r\n        /// <returns>True if success.</returns>\r\n        public static bool VerifyTestMsiInstalledAndCleanup(string installDir)\r\n        {\r\n            string pathToCheck = Path.Combine(installDir, Constants.AppInstallerTestExeInstallerExe);\r\n            if (!File.Exists(pathToCheck))\r\n            {\r\n                TestContext.Out.WriteLine($\"File not found: {pathToCheck}\");\r\n                return false;\r\n            }\r\n\r\n            return RunCommand(\"msiexec.exe\", $\"/qn /x {Constants.MsiInstallerProductCode}\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verify msix installed correctly.\r\n        /// </summary>\r\n        /// <param name=\"isProvisioned\">Whether the package is provisioned.</param>\r\n        /// <returns>True if success.</returns>\r\n        public static bool VerifyTestMsixInstalledAndCleanup(bool isProvisioned = false)\r\n        {\r\n            var result = RunCommandWithResult(\"powershell\", $\"Get-AppxPackage {Constants.MsixInstallerName}\");\r\n\r\n            if (!result.StdOut.Contains(Constants.MsixInstallerName))\r\n            {\r\n                return false;\r\n            }\r\n\r\n            if (isProvisioned)\r\n            {\r\n                result = RunCommandWithResult(\"powershell\", $\"Get-AppxProvisionedPackage -Online | Where-Object {{$_.PackageName -like \\\"*{Constants.MsixInstallerName}*\\\"}}\");\r\n                if (!result.StdOut.Contains(Constants.MsixInstallerName))\r\n                {\r\n                    return false;\r\n                }\r\n            }\r\n\r\n            return RemoveMsix(Constants.MsixInstallerName, isProvisioned);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verify test exe uninstalled.\r\n        /// </summary>\r\n        /// <param name=\"installDir\">Installed directory.</param>\r\n        /// <returns>True if success.</returns>\r\n        public static bool VerifyTestExeUninstalled(string installDir)\r\n        {\r\n            return File.Exists(Path.Combine(installDir, Constants.TestExeUninstalledFileName));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verify msi uninstalled.\r\n        /// </summary>\r\n        /// <param name=\"installDir\">Install directory.</param>\r\n        /// <returns>True if success.</returns>\r\n        public static bool VerifyTestMsiUninstalled(string installDir)\r\n        {\r\n            return !File.Exists(Path.Combine(installDir, Constants.AppInstallerTestExeInstallerExe));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verify msix uninstalled.\r\n        /// </summary>\r\n        /// <param name=\"isProvisioned\">Whether the package is provisioned.</param>\r\n        /// <returns>True if success.</returns>\r\n        public static bool VerifyTestMsixUninstalled(bool isProvisioned = false)\r\n        {\r\n            bool isUninstalled = false;\r\n            var result = RunCommandWithResult(\"powershell\", $\"Get-AppxPackage {Constants.MsixInstallerName}\");\r\n            isUninstalled = string.IsNullOrWhiteSpace(result.StdOut);\r\n\r\n            if (isProvisioned)\r\n            {\r\n                result = RunCommandWithResult(\"powershell\", $\"Get-AppxProvisionedPackage -Online | Where-Object {{$_.PackageName -like \\\"*{Constants.MsixInstallerName}*\\\"}}\");\r\n                isUninstalled = isUninstalled && string.IsNullOrWhiteSpace(result.StdOut);\r\n            }\r\n\r\n            return isUninstalled;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Modify uninstalled registry key.\r\n        /// </summary>\r\n        /// <param name=\"productCode\">Product code.</param>\r\n        /// <param name=\"name\">Name.</param>\r\n        /// <param name=\"value\">Value.</param>\r\n        public static void ModifyPortableARPEntryValue(string productCode, string name, string value)\r\n        {\r\n            using (RegistryKey uninstallRegistryKey = Registry.CurrentUser.OpenSubKey(Constants.UninstallSubKey, true))\r\n            {\r\n                RegistryKey entry = uninstallRegistryKey.OpenSubKey(productCode, true);\r\n                entry.SetValue(name, value);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Set up test source.\r\n        /// </summary>\r\n        /// <param name=\"useGroupPolicyForTestSource\">Use group policy.</param>\r\n        public static void SetupTestSource(bool useGroupPolicyForTestSource = false)\r\n        {\r\n            // Remove the test source so that its package is also removed.\r\n            RunAICLICommand(\"source remove\", Constants.TestSourceName);\r\n\r\n            RunAICLICommand(\"source reset\", \"--force\");\r\n            RunAICLICommand(\"source remove\", Constants.DefaultWingetSourceName);\r\n            RunAICLICommand(\"source remove\", Constants.DefaultMSStoreSourceName);\r\n\r\n            // TODO: If/when cert pinning is implemented on the packaged index source, useGroupPolicyForTestSource should be set to default true\r\n            //       to enable testing it by default.  Until then, leaving this here...\r\n            if (useGroupPolicyForTestSource)\r\n            {\r\n                GroupPolicyHelper.EnableAdditionalSources.SetEnabledList(new GroupPolicyHelper.GroupPolicySource[]\r\n                {\r\n                    new GroupPolicyHelper.GroupPolicySource\r\n                    {\r\n                        Name = Constants.TestSourceName,\r\n                        Arg = Constants.TestSourceUrl,\r\n                        Type = Constants.TestSourceType,\r\n                        Data = Constants.TestSourceIdentifier,\r\n                        Identifier = Constants.TestSourceIdentifier,\r\n                        CertificatePinning = new GroupPolicyHelper.GroupPolicyCertificatePinning\r\n                        {\r\n                            Chains = new GroupPolicyHelper.GroupPolicyCertificatePinningChain[]\r\n                            {\r\n                                new GroupPolicyHelper.GroupPolicyCertificatePinningChain\r\n                                {\r\n                                    Chain = new GroupPolicyHelper.GroupPolicyCertificatePinningDetails[]\r\n                                    {\r\n                                        new GroupPolicyHelper.GroupPolicyCertificatePinningDetails\r\n                                        {\r\n                                            Validation = new string[] { \"publickey\" },\r\n                                            EmbeddedCertificate = GetTestServerCertificateHexString(),\r\n                                        },\r\n                                    },\r\n                                },\r\n                            },\r\n                        },\r\n                        TrustLevel = new string[] { \"None\" },\r\n                        Explicit = false,\r\n                    },\r\n                });\r\n            }\r\n            else\r\n            {\r\n                GroupPolicyHelper.EnableAdditionalSources.SetNotConfigured();\r\n                RunAICLICommand(\"source add\", $\"{Constants.TestSourceName} {Constants.TestSourceUrl} --trust-level trusted\");\r\n            }\r\n\r\n            Thread.Sleep(2000);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tear down test source.\r\n        /// </summary>\r\n        public static void TearDownTestSource()\r\n        {\r\n            RunAICLICommand(\"source remove\", Constants.TestSourceName);\r\n            RunAICLICommand(\"source reset\", \"--force\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Ensures that a module is in the desired state.\r\n        /// </summary>\r\n        /// <param name=\"moduleName\">The module.</param>\r\n        /// <param name=\"present\">Whether the module is present or not.</param>\r\n        /// <param name=\"repository\">The repository to get the module from if needed.</param>\r\n        /// <param name=\"location\">The location to install the module.</param>\r\n        public static void EnsureModuleState(string moduleName, bool present, string repository = null, TestCommon.TestModuleLocation location = TestModuleLocation.CurrentUser)\r\n        {\r\n            string wingetModulePath = TestCommon.GetExpectedModulePath(TestModuleLocation.WinGetModulePath);\r\n            string customPath = TestCommon.GetExpectedModulePath(TestModuleLocation.Custom);\r\n\r\n            ICollection<PSModuleInfo> e2eModule;\r\n            bool isPresent = false;\r\n            {\r\n                using var pwsh = new PowerShellHost();\r\n                pwsh.AddModulePath($\"{wingetModulePath};{customPath}\");\r\n\r\n                e2eModule = pwsh.PowerShell.AddCommand(\"Get-Module\").AddParameter(\"Name\", moduleName).AddParameter(\"ListAvailable\").Invoke<PSModuleInfo>();\r\n                isPresent = e2eModule.Any();\r\n            }\r\n\r\n            TestContext.Out.WriteLine($\"EnsureModuleState: {moduleName}[present:{present}] => isPresent:{isPresent}\");\r\n\r\n            if (isPresent)\r\n            {\r\n                // If the module was saved in a different location we can't Uninstall-Module.\r\n                foreach (var module in e2eModule)\r\n                {\r\n                    var moduleBase = module.Path;\r\n                    while (Path.GetFileName(moduleBase) != moduleName)\r\n                    {\r\n                        moduleBase = Path.GetDirectoryName(moduleBase);\r\n                    }\r\n\r\n                    if (!present)\r\n                    {\r\n                        TestContext.Out.WriteLine($\"EnsureModuleState: Removing {moduleName} to match present=false\");\r\n                        Directory.Delete(moduleBase, true);\r\n                    }\r\n                    else\r\n                    {\r\n                        // Must be present in the right location.\r\n                        var expectedLocation = TestCommon.GetExpectedModulePath(location);\r\n                        if (!moduleBase.StartsWith(expectedLocation))\r\n                        {\r\n                            TestContext.Out.WriteLine($\"EnsureModuleState: Removing {moduleName} as it is not in the correct location\");\r\n                            Directory.Delete(moduleBase, true);\r\n                            isPresent = false;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (!isPresent && present)\r\n            {\r\n                if (location == TestModuleLocation.CurrentUser ||\r\n                    location == TestModuleLocation.AllUsers)\r\n                {\r\n                    using var pwsh = new PowerShellHost();\r\n                    pwsh.AddModulePath($\"{wingetModulePath};{customPath}\");\r\n                    pwsh.PowerShell.AddCommand(\"Install-Module\").AddParameter(\"Name\", moduleName).AddParameter(\"Force\");\r\n\r\n                    if (!string.IsNullOrEmpty(repository))\r\n                    {\r\n                        pwsh.PowerShell.AddParameter(\"Repository\", repository);\r\n                    }\r\n\r\n                    if (location == TestModuleLocation.CurrentUser)\r\n                    {\r\n                        pwsh.PowerShell.AddParameter(\"Scope\", \"CurrentUser\");\r\n                    }\r\n                    else if (location == TestModuleLocation.AllUsers)\r\n                    {\r\n                        pwsh.PowerShell.AddParameter(\"Scope\", \"AllUsers\");\r\n                    }\r\n\r\n                    TestContext.Out.WriteLine($\"EnsureModuleState: Installing module {moduleName} to {location}\");\r\n                    _ = pwsh.PowerShell.Invoke();\r\n                }\r\n                else\r\n                {\r\n                    string path = customPath;\r\n                    if (location == TestModuleLocation.WinGetModulePath ||\r\n                        location == TestModuleLocation.Default)\r\n                    {\r\n                        path = wingetModulePath;\r\n                    }\r\n\r\n                    using var pwsh = new PowerShellHost();\r\n                    pwsh.AddModulePath($\"{wingetModulePath};{customPath}\");\r\n                    pwsh.PowerShell.AddCommand(\"Save-Module\").AddParameter(\"Name\", moduleName).AddParameter(\"Path\", path).AddParameter(\"Force\");\r\n\r\n                    if (!string.IsNullOrEmpty(repository))\r\n                    {\r\n                        pwsh.PowerShell.AddParameter(\"Repository\", repository);\r\n                    }\r\n\r\n                    TestContext.Out.WriteLine($\"EnsureModuleState: Saving module {moduleName} to {path}\");\r\n                    _ = pwsh.PowerShell.Invoke();\r\n                }\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates an ARP entry from the given values.\r\n        /// </summary>\r\n        /// <param name=\"productCode\">Product code of the entry.</param>\r\n        /// <param name=\"properties\">The properties to set in the entry.</param>\r\n        /// <param name=\"scope\">Scope of the entry.</param>\r\n        public static void CreateARPEntry(\r\n            string productCode,\r\n            object properties,\r\n            Scope scope = Scope.User)\r\n        {\r\n            RegistryKey baseKey = scope == Scope.User ? Registry.CurrentUser : Registry.LocalMachine;\r\n            using (RegistryKey uninstallRegistryKey = baseKey.OpenSubKey(Constants.UninstallSubKey, true))\r\n            {\r\n                RegistryKey entry = uninstallRegistryKey.CreateSubKey(productCode, true);\r\n\r\n                foreach (PropertyInfo property in properties.GetType().GetProperties())\r\n                {\r\n                    entry.SetValue(property.Name, property.GetValue(properties));\r\n                }\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Removes an ARP entry.\r\n        /// </summary>\r\n        /// <param name=\"productCode\">Product code of the entry.</param>\r\n        /// <param name=\"scope\">Scope of the entry.</param>\r\n        public static void RemoveARPEntry(\r\n            string productCode,\r\n            Scope scope = Scope.User)\r\n        {\r\n            RegistryKey baseKey = scope == Scope.User ? Registry.CurrentUser : Registry.LocalMachine;\r\n            using (RegistryKey uninstallRegistryKey = baseKey.OpenSubKey(Constants.UninstallSubKey, true))\r\n            {\r\n                uninstallRegistryKey.DeleteSubKey(productCode);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Copies the contents of a given directory from a source path to a destination path.\r\n        /// </summary>\r\n        /// <param name=\"sourceDirName\">Source directory name.</param>\r\n        /// <param name=\"destDirName\">Destination directory name.</param>\r\n        public static void CopyDirectory(string sourceDirName, string destDirName)\r\n        {\r\n            DirectoryInfo dir = new DirectoryInfo(sourceDirName);\r\n            DirectoryInfo[] dirs = dir.GetDirectories();\r\n\r\n            if (!Directory.Exists(destDirName))\r\n            {\r\n                Directory.CreateDirectory(destDirName);\r\n            }\r\n\r\n            FileInfo[] files = dir.GetFiles();\r\n            foreach (FileInfo file in files)\r\n            {\r\n                string temppath = Path.Combine(destDirName, file.Name);\r\n                file.CopyTo(temppath, false);\r\n            }\r\n\r\n            foreach (DirectoryInfo subdir in dirs)\r\n            {\r\n                string temppath = Path.Combine(destDirName, subdir.Name);\r\n                CopyDirectory(subdir.FullName, temppath);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the expected module path.\r\n        /// </summary>\r\n        /// <param name=\"location\">Location.</param>\r\n        /// <returns>The expected path of the module.</returns>\r\n        public static string GetExpectedModulePath(TestModuleLocation location)\r\n        {\r\n            switch (location)\r\n            {\r\n                case TestModuleLocation.CurrentUser:\r\n                    return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), @\"PowerShell\\Modules\");\r\n                case TestModuleLocation.AllUsers:\r\n                    return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), @\"PowerShell\\Modules\");\r\n                case TestModuleLocation.WinGetModulePath:\r\n                case TestModuleLocation.Default:\r\n                    return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @\"Microsoft\\WinGet\\Configuration\\Modules\");\r\n                case TestModuleLocation.Custom:\r\n                    return Path.Combine(Path.GetTempPath(), \"E2ECustomModules\");\r\n                default:\r\n                    throw new ArgumentException(location.ToString());\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the instance identifier of the first configuration history item with name in its output line.\r\n        /// </summary>\r\n        /// <param name=\"name\">The string to search for.</param>\r\n        /// <returns>The instance identifier of a configuration that matched the search, or an empty string if none did.</returns>\r\n        public static string GetConfigurationInstanceIdentifierFor(string name)\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"configure list\", string.Empty);\r\n            Assert.AreEqual(0, result.ExitCode);\r\n\r\n            string[] lines = result.StdOut.Split('\\n', StringSplitOptions.RemoveEmptyEntries);\r\n\r\n            foreach (string line in lines)\r\n            {\r\n                if (line.Contains(name))\r\n                {\r\n                    // Find the first GUID in the output\r\n                    int left = line.IndexOf('{');\r\n                    int right = line.IndexOfAny(new char[] { '}', '…' });\r\n                    Assert.AreNotEqual(-1, left);\r\n                    Assert.AreNotEqual(-1, right);\r\n                    Assert.LessOrEqual(right - left, 38);\r\n\r\n                    return line.Substring(left, right - left);\r\n                }\r\n            }\r\n\r\n            return string.Empty;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Copy the installer file to the ARP InstallSource directory.\r\n        /// </summary>\r\n        /// <param name=\"installerFilePath\">Test installer to be copied.</param>\r\n        /// <param name=\"productCode\">Installer Product.</param>\r\n        /// <param name=\"useWoW6432Node\">is WoW6432Node to use.</param>\r\n        /// <returns>Returns the installer source directory if the file operation is successful, otherwise returns an empty string.</returns>\r\n        public static string CopyInstallerFileToARPInstallSourceDirectory(string installerFilePath, string productCode, bool useWoW6432Node = false)\r\n        {\r\n            if (string.IsNullOrEmpty(installerFilePath))\r\n            {\r\n                new ArgumentNullException(nameof(installerFilePath));\r\n            }\r\n\r\n            if (!File.Exists(installerFilePath))\r\n            {\r\n                new FileNotFoundException(installerFilePath);\r\n            }\r\n\r\n            string outputDirectory = string.Empty;\r\n\r\n            // Define the registry paths for both x64 and x86\r\n            string registryPath = useWoW6432Node\r\n                ? $@\"SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{productCode}\"\r\n                : $@\"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{productCode}\";\r\n\r\n            // Open the registry key where the uninstall information is stored\r\n            using (RegistryKey key = Registry.LocalMachine.OpenSubKey(registryPath))\r\n            {\r\n                if (key != null)\r\n                {\r\n                    // Read the InstallSource value\r\n                    string arpInstallSourceDirectory = key.GetValue(\"InstallSource\") as string;\r\n\r\n                    if (!string.IsNullOrEmpty(arpInstallSourceDirectory))\r\n                    {\r\n                        // Copy the MSI installer to the InstallSource directory\r\n                        string installerFileName = Path.GetFileName(installerFilePath);\r\n                        string installerDestinationPath = Path.Combine(arpInstallSourceDirectory, installerFileName);\r\n\r\n                        if (!Directory.Exists(arpInstallSourceDirectory))\r\n                        {\r\n                            Directory.CreateDirectory(arpInstallSourceDirectory);\r\n                        }\r\n\r\n                        File.Copy(installerFilePath, installerDestinationPath, true);\r\n\r\n                        outputDirectory = arpInstallSourceDirectory;\r\n                    }\r\n                }\r\n            }\r\n\r\n            return outputDirectory;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Run winget command via direct process.\r\n        /// </summary>\r\n        /// <param name=\"executablePath\">The executable to run.</param>\r\n        /// <param name=\"command\">Command to run.</param>\r\n        /// <param name=\"parameters\">Parameters.</param>\r\n        /// <param name=\"stdIn\">Optional std in.</param>\r\n        /// <param name=\"timeOut\">Optional timeout.</param>\r\n        /// <param name=\"throwOnTimeout\">Throw on timeout.</param>\r\n        /// <returns>The result of the command.</returns>\r\n        public static RunCommandResult RunProcess(string executablePath, string command, string parameters, string stdIn, int timeOut, bool throwOnTimeout)\r\n        {\r\n            string inputMsg =\r\n                    \"Exe path: \" + executablePath +\r\n                    \" Command: \" + command +\r\n                    \" Parameters: \" + parameters +\r\n                    (string.IsNullOrEmpty(stdIn) ? string.Empty : \" StdIn: \" + stdIn) +\r\n                    \" Timeout: \" + timeOut;\r\n\r\n            TestContext.Out.WriteLine($\"Starting command run. {inputMsg}\");\r\n\r\n            RunCommandResult result = new ();\r\n            Process p = new Process();\r\n            p.StartInfo = new ProcessStartInfo(executablePath, command + ' ' + parameters);\r\n            p.StartInfo.UseShellExecute = false;\r\n\r\n            p.StartInfo.StandardOutputEncoding = Encoding.UTF8;\r\n            p.StartInfo.RedirectStandardOutput = true;\r\n            StringBuilder outputData = new ();\r\n            p.OutputDataReceived += (sender, args) =>\r\n            {\r\n                if (args.Data != null)\r\n                {\r\n                    outputData.AppendLine(args.Data);\r\n                }\r\n            };\r\n\r\n            p.StartInfo.StandardErrorEncoding = Encoding.UTF8;\r\n            p.StartInfo.RedirectStandardError = true;\r\n            StringBuilder errorData = new ();\r\n            p.ErrorDataReceived += (sender, args) =>\r\n            {\r\n                if (args.Data != null)\r\n                {\r\n                    errorData.AppendLine(args.Data);\r\n                }\r\n            };\r\n\r\n            if (!string.IsNullOrEmpty(stdIn))\r\n            {\r\n                p.StartInfo.RedirectStandardInput = true;\r\n            }\r\n\r\n            p.Start();\r\n            p.BeginOutputReadLine();\r\n            p.BeginErrorReadLine();\r\n\r\n            if (!string.IsNullOrEmpty(stdIn))\r\n            {\r\n                p.StandardInput.Write(stdIn);\r\n                p.StandardInput.Close();\r\n            }\r\n\r\n            if (p.WaitForExit(timeOut))\r\n            {\r\n                // According to documentation, this extra call will ensure that the redirected streams\r\n                // have finished reading all of the data.\r\n                p.WaitForExit();\r\n\r\n                result.ExitCode = p.ExitCode;\r\n                result.StdOut = outputData.ToString();\r\n                result.StdErr = errorData.ToString();\r\n\r\n                TestContext.Out.WriteLine(\"Command run completed with exit code: \" + result.ExitCode);\r\n\r\n                if (!string.IsNullOrEmpty(result.StdErr))\r\n                {\r\n                    TestContext.Error.WriteLine(\"Command run error. Error: \" + result.StdErr);\r\n                }\r\n\r\n                if (TestSetup.Parameters.VerboseLogging)\r\n                {\r\n                    TestContext.Out.WriteLine(\"Command run output. Output:\\n\" + result.StdOut ?? \"<null>\");\r\n                }\r\n            }\r\n            else if (throwOnTimeout)\r\n            {\r\n                throw new TimeoutException($\"Direct command run timed out: {command} {parameters}\");\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Run winget command via direct process.\r\n        /// </summary>\r\n        /// <param name=\"command\">Command to run.</param>\r\n        /// <param name=\"parameters\">Parameters.</param>\r\n        /// <param name=\"stdIn\">Optional std in.</param>\r\n        /// <param name=\"timeOut\">Optional timeout.</param>\r\n        /// <param name=\"throwOnTimeout\">Throw on timeout.</param>\r\n        /// <returns>The result of the command.</returns>\r\n        private static RunCommandResult RunAICLICommandViaDirectProcess(string command, string parameters, string stdIn, int timeOut, bool throwOnTimeout)\r\n        {\r\n            return RunProcess(TestSetup.Parameters.AICLIPath, command, parameters, stdIn, timeOut, throwOnTimeout);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Run command result.\r\n        /// </summary>\r\n        public struct RunCommandResult\r\n        {\r\n            /// <summary>\r\n            /// Exit code.\r\n            /// </summary>\r\n            public int ExitCode;\r\n\r\n            /// <summary>\r\n            /// StdOut.\r\n            /// </summary>\r\n            public string StdOut;\r\n\r\n            /// <summary>\r\n            /// StdErr.\r\n            /// </summary>\r\n            public string StdErr;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/Helpers/TestIndex.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"TestIndex.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests.Helpers\r\n{\r\n    using System;\r\n    using System.IO;\r\n    using System.Text.Json;\r\n    using Microsoft.WinGetSourceCreator;\r\n    using WinGetSourceCreator.Model;\r\n\r\n    /// <summary>\r\n    /// Test index setup.\r\n    /// </summary>\r\n    public static class TestIndex\r\n    {\r\n        static TestIndex()\r\n        {\r\n            // Expected path for the installers.\r\n            TestIndex.ExeInstaller = Path.Combine(TestSetup.Parameters.StaticFileRootPath, Constants.ExeInstaller, Constants.ExeInstallerFileName);\r\n            TestIndex.MsiInstaller = Path.Combine(TestSetup.Parameters.StaticFileRootPath, Constants.MsiInstaller, Constants.MsiInstallerFileName);\r\n            TestIndex.MsiInstallerV2 = Path.Combine(TestSetup.Parameters.StaticFileRootPath, Constants.MsiInstaller, Constants.MsiInstallerV2FileName);\r\n            TestIndex.MsixInstaller = Path.Combine(TestSetup.Parameters.StaticFileRootPath, Constants.MsixInstaller, Constants.MsixInstallerFileName);\r\n            TestIndex.ZipInstaller = Path.Combine(TestSetup.Parameters.StaticFileRootPath, Constants.ZipInstaller, Constants.ZipInstallerFileName);\r\n            TestIndex.Font = Path.Combine(TestSetup.Parameters.StaticFileRootPath, Constants.FontFileName, Constants.FontFileName);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the signed exe installer path used by the manifests in the E2E test.\r\n        /// </summary>\r\n        public static string ExeInstaller { get; private set; }\r\n\r\n        /// <summary>\r\n        /// Gets the signed msi installer path used by the manifests in the E2E test.\r\n        /// </summary>\r\n        public static string MsiInstaller { get; private set; }\r\n\r\n        /// <summary>\r\n        /// Gets the signed msi installerV2 path used by the manifests in the E2E test.\r\n        /// </summary>\r\n        public static string MsiInstallerV2 { get; private set; }\r\n\r\n        /// <summary>\r\n        /// Gets the signed msix installer path used by the manifests in the E2E test.\r\n        /// </summary>\r\n        public static string MsixInstaller { get; private set; }\r\n\r\n        /// <summary>\r\n        /// Gets the zip installer path used by the manifests in the E2E test.\r\n        /// </summary>\r\n        public static string ZipInstaller { get; private set; }\r\n\r\n        /// <summary>\r\n        /// Gets the font file path used by the manifests in the E2E test.\r\n        /// </summary>\r\n        public static string Font { get; private set; }\r\n\r\n        /// <summary>\r\n        /// Generate test source.\r\n        /// </summary>\r\n        public static void GenerateE2ESource()\r\n        {\r\n            var testParams = TestSetup.Parameters;\r\n\r\n            if (string.IsNullOrEmpty(testParams.ExeInstallerPath))\r\n            {\r\n                throw new ArgumentNullException($\"{Constants.ExeInstallerPathParameter} is required\");\r\n            }\r\n\r\n            if (!File.Exists(testParams.ExeInstallerPath))\r\n            {\r\n                throw new FileNotFoundException(testParams.ExeInstallerPath);\r\n            }\r\n\r\n            if (string.IsNullOrEmpty(testParams.MsiInstallerPath))\r\n            {\r\n                throw new ArgumentNullException($\"{Constants.MsiInstallerPathParameter} is required\");\r\n            }\r\n\r\n            if (!File.Exists(testParams.MsiInstallerPath))\r\n            {\r\n                throw new FileNotFoundException(testParams.MsiInstallerPath);\r\n            }\r\n\r\n            if (string.IsNullOrEmpty(testParams.MsiInstallerV2Path))\r\n            {\r\n                throw new ArgumentNullException($\"{Constants.MsiInstallerV2PathParameter} is required\");\r\n            }\r\n\r\n            if (!File.Exists(testParams.MsiInstallerV2Path))\r\n            {\r\n                throw new FileNotFoundException(testParams.MsiInstallerV2Path);\r\n            }\r\n\r\n            if (string.IsNullOrEmpty(testParams.MsixInstallerPath))\r\n            {\r\n                throw new ArgumentNullException($\"{Constants.MsixInstallerPathParameter} is required\");\r\n            }\r\n\r\n            if (!File.Exists(testParams.MsixInstallerPath))\r\n            {\r\n                throw new FileNotFoundException(testParams.MsixInstallerPath);\r\n            }\r\n\r\n            if (string.IsNullOrEmpty(testParams.FontPath))\r\n            {\r\n                throw new ArgumentNullException($\"{Constants.FontPathParameter} is required\");\r\n            }\r\n\r\n            if (!File.Exists(testParams.FontPath))\r\n            {\r\n                throw new FileNotFoundException(testParams.FontPath);\r\n            }\r\n\r\n            if (string.IsNullOrEmpty(testParams.PackageCertificatePath))\r\n            {\r\n                throw new ArgumentNullException($\"{Constants.PackageCertificatePathParameter} is required\");\r\n            }\r\n\r\n            if (!File.Exists(testParams.PackageCertificatePath))\r\n            {\r\n                throw new FileNotFoundException(testParams.PackageCertificatePath);\r\n            }\r\n\r\n            LocalSource e2eSource = new ()\r\n            {\r\n                AppxManifest = TestCommon.GetTestDataFile(Path.Combine(\"Package\", \"AppxManifest.xml\")),\r\n                WorkingDirectory = testParams.StaticFileRootPath,\r\n                LocalManifests = new ()\r\n                {\r\n                    TestCommon.GetTestDataFile(\"Manifests\"),\r\n                },\r\n                LocalInstallers = new ()\r\n                {\r\n                    new LocalInstaller\r\n                    {\r\n                        Type = InstallerType.Exe,\r\n                        Name = Path.Combine(Constants.ExeInstaller, Constants.ExeInstallerFileName),\r\n                        Input = testParams.ExeInstallerPath,\r\n                        HashToken = \"<EXEHASH>\",\r\n                    },\r\n                    new LocalInstaller\r\n                    {\r\n                        Type = InstallerType.Msi,\r\n                        Name = Path.Combine(Constants.MsiInstaller, Constants.MsiInstallerFileName),\r\n                        Input = testParams.MsiInstallerPath,\r\n                        HashToken = \"<MSIHASH>\",\r\n                    },\r\n                    new LocalInstaller\r\n                    {\r\n                        Type = InstallerType.Msi,\r\n                        Name = Path.Combine(Constants.MsiInstaller, Constants.MsiInstallerV2FileName),\r\n                        Input = testParams.MsiInstallerPath,\r\n                        HashToken = \"<MSIHASHV2>\",\r\n                    },\r\n                    new LocalInstaller\r\n                    {\r\n                        Type = InstallerType.Msix,\r\n                        Name = Path.Combine(Constants.MsixInstaller, Constants.MsixInstallerFileName),\r\n                        Input = testParams.MsixInstallerPath,\r\n                        HashToken = \"<MSIXHASH>\",\r\n                        SignatureToken = \"<SIGNATUREHASH>\",\r\n                    },\r\n                    new LocalInstaller\r\n                    {\r\n                        Type = InstallerType.Font,\r\n                        Name = Path.Combine(Constants.FontFileName, Constants.FontFileName),\r\n                        Input = testParams.FontPath,\r\n                        HashToken = \"<FONTHASH>\",\r\n                    },\r\n                },\r\n                DynamicInstallers = new ()\r\n                {\r\n                    new DynamicInstaller\r\n                    {\r\n                        Type = InstallerType.Zip,\r\n                        Name = Path.Combine(Constants.ZipInstaller, Constants.ZipInstallerFileName),\r\n                        Input = new ()\r\n                        {\r\n                            ExeInstaller,\r\n                            MsiInstaller,\r\n                            MsixInstaller,\r\n                        },\r\n                        HashToken = \"<ZIPHASH>\",\r\n                    },\r\n                },\r\n                Signature = new ()\r\n                {\r\n                    CertFile = testParams.PackageCertificatePath,\r\n                },\r\n            };\r\n\r\n            WinGetLocalSource.CreateLocalSource(e2eSource);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/Helpers/TestSetup.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"TestSetup.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests.Helpers\r\n{\r\n    using System;\r\n    using System.IO;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// Singleton class with test parameters.\r\n    /// </summary>\r\n    internal class TestSetup\r\n    {\r\n        private static readonly Lazy<TestSetup> Lazy = new (() => new TestSetup());\r\n\r\n        private string settingFilePath = null;\r\n\r\n        private TestSetup()\r\n        {\r\n            if (TestContext.Parameters.Count == 0)\r\n            {\r\n                this.IsDefault = true;\r\n            }\r\n\r\n            // Read TestParameters and set runtime variables\r\n            this.PackagedContext = this.InitializeBoolParam(Constants.PackagedContextParameter, true);\r\n            this.VerboseLogging = this.InitializeBoolParam(Constants.VerboseLoggingParameter, true);\r\n            this.LooseFileRegistration = this.InitializeBoolParam(Constants.LooseFileRegistrationParameter);\r\n            this.SkipTestSource = this.InitializeBoolParam(Constants.SkipTestSourceParameter, this.IsDefault);\r\n            this.InprocTestbedUseTestPackage = this.InitializeBoolParam(Constants.InprocTestbedUseTestPackageParameter);\r\n\r\n            // For packaged context, default to AppExecutionAlias\r\n            this.AICLIPath = this.InitializeStringParam(Constants.AICLIPathParameter, this.PackagedContext ? \"WinGetDev.exe\" : TestCommon.GetTestFile(\"winget.exe\"));\r\n            this.AICLIPackagePath = this.InitializeStringParam(Constants.AICLIPackagePathParameter, TestCommon.GetTestFile(\"AppInstallerCLIPackage.appxbundle\"));\r\n\r\n            this.StaticFileRootPath = this.InitializeDirectoryParam(Constants.StaticFileRootPathParameter, Path.GetTempPath());\r\n\r\n            this.LocalServerCertPath = this.InitializeFileParam(Constants.LocalServerCertPathParameter);\r\n            this.PackageCertificatePath = this.InitializeFileParam(Constants.PackageCertificatePathParameter);\r\n            this.ExeInstallerPath = this.InitializeFileParam(Constants.ExeInstallerPathParameter);\r\n            this.MsiInstallerPath = this.InitializeFileParam(Constants.MsiInstallerPathParameter);\r\n            this.MsixInstallerPath = this.InitializeFileParam(Constants.MsixInstallerPathParameter);\r\n            this.MsiInstallerV2Path = this.InitializeFileParam(Constants.MsiInstallerV2PathParameter);\r\n            this.FontPath = this.InitializeFileParam(Constants.FontPathParameter);\r\n            this.InprocTestbedPath = this.InitializeFileParam(Constants.InprocTestbedPathParameter);\r\n\r\n            this.ForcedExperimentalFeatures = this.InitializeStringArrayParam(Constants.ForcedExperimentalFeaturesParameter);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the instance object.\r\n        /// </summary>\r\n        public static TestSetup Parameters\r\n        {\r\n            get\r\n            {\r\n                return Lazy.Value;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the cli path.\r\n        /// </summary>\r\n        public string AICLIPath { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the package path.\r\n        /// </summary>\r\n        public string AICLIPackagePath { get; }\r\n\r\n        /// <summary>\r\n        /// Gets a value indicating whether the test runs in package context.\r\n        /// </summary>\r\n        public bool PackagedContext { get; }\r\n\r\n        /// <summary>\r\n        /// Gets a value indicating whether the test uses verbose logging.\r\n        /// </summary>\r\n        public bool VerboseLogging { get; }\r\n\r\n        /// <summary>\r\n        /// Gets a value indicating whether to use loose file registration.\r\n        /// </summary>\r\n        public bool LooseFileRegistration { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the static file root path.\r\n        /// </summary>\r\n        public string StaticFileRootPath { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the local server cert path.\r\n        /// </summary>\r\n        public string LocalServerCertPath { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the exe installer path.\r\n        /// </summary>\r\n        public string ExeInstallerPath { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the msi installer path.\r\n        /// </summary>\r\n        public string MsiInstallerPath { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the msi installer V2 path.\r\n        /// </summary>\r\n        public string MsiInstallerV2Path { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the msix installer path.\r\n        /// </summary>\r\n        public string MsixInstallerPath { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the zip installer path.\r\n        /// </summary>\r\n        public string ZipInstallerPath { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the font path.\r\n        /// </summary>\r\n        public string FontPath { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the package cert path.\r\n        /// </summary>\r\n        public string PackageCertificatePath { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the inproc testbed executable path.\r\n        /// </summary>\r\n        public string InprocTestbedPath { get; }\r\n\r\n        /// <summary>\r\n        /// Gets a value indicating whether to use the test package or not.\r\n        /// </summary>\r\n        public bool InprocTestbedUseTestPackage { get; }\r\n\r\n        /// <summary>\r\n        /// Gets a value indicating whether to skip creating test source.\r\n        /// </summary>\r\n        public bool SkipTestSource { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the settings json path.\r\n        /// </summary>\r\n        public string SettingsJsonFilePath\r\n        {\r\n            get\r\n            {\r\n                if (this.settingFilePath == null)\r\n                {\r\n                    this.settingFilePath = WinGetSettingsHelper.GetUserSettingsPath();\r\n                }\r\n\r\n                return this.settingFilePath;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the experimental features that should be forcibly enabled.\r\n        /// </summary>\r\n        public string[] ForcedExperimentalFeatures { get; }\r\n\r\n        /// <summary>\r\n        /// Gets a value indicating whether is the default parameters.\r\n        /// </summary>\r\n        public bool IsDefault { get; }\r\n\r\n        private bool InitializeBoolParam(string paramName, bool defaultValue = false)\r\n        {\r\n            if (this.IsDefault || !TestContext.Parameters.Exists(paramName))\r\n            {\r\n                return defaultValue;\r\n            }\r\n\r\n            return TestContext.Parameters.Get(paramName).Equals(\"true\", StringComparison.OrdinalIgnoreCase);\r\n        }\r\n\r\n        private string InitializeStringParam(string paramName, string defaultValue = null)\r\n        {\r\n            if (this.IsDefault || !TestContext.Parameters.Exists(paramName))\r\n            {\r\n                return defaultValue;\r\n            }\r\n\r\n            return TestContext.Parameters.Get(paramName);\r\n        }\r\n\r\n        private string[] InitializeStringArrayParam(string paramName, string[] defaultValue = null)\r\n        {\r\n            if (this.IsDefault || !TestContext.Parameters.Exists(paramName))\r\n            {\r\n                return defaultValue;\r\n            }\r\n\r\n            return TestContext.Parameters.Get(paramName).Split('|', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);\r\n        }\r\n\r\n        private string InitializeFileParam(string paramName, string defaultValue = null)\r\n        {\r\n            if (!TestContext.Parameters.Exists(paramName))\r\n            {\r\n                return defaultValue;\r\n            }\r\n\r\n            var value = TestContext.Parameters.Get(paramName);\r\n\r\n            if (!File.Exists(value))\r\n            {\r\n                throw new FileNotFoundException($\"{paramName}: {value}\");\r\n            }\r\n\r\n            return value;\r\n        }\r\n\r\n        private string InitializeDirectoryParam(string paramName, string defaultValue = null)\r\n        {\r\n            if (!TestContext.Parameters.Exists(paramName))\r\n            {\r\n                return defaultValue;\r\n            }\r\n\r\n            var value = TestContext.Parameters.Get(paramName);\r\n\r\n            if (!Directory.Exists(value))\r\n            {\r\n                throw new DirectoryNotFoundException($\"{paramName}: {value}\");\r\n            }\r\n\r\n            return value;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/Helpers/WinGetSettingsHelper.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"WinGetSettingsHelper.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests.Helpers\r\n{\r\n    using System.Collections;\r\n    using System.IO;\r\n    using Newtonsoft.Json;\r\n    using Newtonsoft.Json.Linq;\r\n\r\n    /// <summary>\r\n    /// Helper class to set winget settings.\r\n    /// </summary>\r\n    internal static class WinGetSettingsHelper\r\n    {\r\n        /// <summary>\r\n        /// Gets or sets the experimental features that should be forcibly enabled.\r\n        /// </summary>\r\n        public static string[] ForcedExperimentalFeatures { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets the user settings path by calling winget settings export.\r\n        /// </summary>\r\n        /// <returns>Expanded path for user settings.</returns>\r\n        public static string GetUserSettingsPath()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"settings\", \"export\");\r\n            var output = result.StdOut;\r\n            var serialized = JObject.Parse(output);\r\n            return (string)serialized.GetValue(\"userSettingsFile\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Initialize settings.\r\n        /// </summary>\r\n        public static void InitializeWingetSettings()\r\n        {\r\n            Hashtable experimentalFeatures = new Hashtable();\r\n\r\n            var forcedExperimentalFeatures = ForcedExperimentalFeatures;\r\n            if (forcedExperimentalFeatures != null)\r\n            {\r\n                foreach (var feature in forcedExperimentalFeatures)\r\n                {\r\n                    experimentalFeatures[feature] = true;\r\n                }\r\n            }\r\n\r\n            var settingsJson = new Hashtable()\r\n            {\r\n                {\r\n                    \"$schema\",\r\n                    \"https://aka.ms/winget-settings.schema.json\"\r\n                },\r\n                {\r\n                    \"experimentalFeatures\",\r\n                    experimentalFeatures\r\n                },\r\n                {\r\n                    \"debugging\",\r\n                    new Hashtable()\r\n                    {\r\n                        { \"enableSelfInitiatedMinidump\", true },\r\n                        { \"keepAllLogFiles\", true },\r\n                    }\r\n                },\r\n                {\r\n                    \"installBehavior\",\r\n                    new Hashtable()\r\n                    {\r\n                    }\r\n                },\r\n                {\r\n                    \"configureBehavior\",\r\n                    new Hashtable()\r\n                    {\r\n                    }\r\n                },\r\n            };\r\n\r\n            // Run winget one time to initialize settings directory\r\n            // when running in unpackaged context\r\n            TestCommon.RunAICLICommand(string.Empty, \"-v\");\r\n\r\n            SetWingetSettings(JsonConvert.SerializeObject(settingsJson, Formatting.Indented));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Configure experimental features.\r\n        /// </summary>\r\n        /// <param name=\"featureName\">Feature name.</param>\r\n        /// <param name=\"status\">Status.</param>\r\n        public static void ConfigureFeature(string featureName, bool status)\r\n        {\r\n            JObject settingsJson = GetJsonSettingsObject(\"experimentalFeatures\");\r\n            ConfigureFeature(settingsJson, featureName, status);\r\n            SetWingetSettings(settingsJson);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Configure the install behavior.\r\n        /// </summary>\r\n        /// <param name=\"settingName\">Setting name.</param>\r\n        /// <param name=\"value\">Setting value.</param>\r\n        public static void ConfigureInstallBehavior(string settingName, string value)\r\n        {\r\n            JObject settingsJson = GetJsonSettingsObject(\"installBehavior\");\r\n            var installBehavior = settingsJson[\"installBehavior\"];\r\n            installBehavior[settingName] = value;\r\n\r\n            SetWingetSettings(settingsJson);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Configure the configuration behavior.\r\n        /// </summary>\r\n        /// <param name=\"settingName\">Setting name.</param>\r\n        /// <param name=\"value\">Setting value.</param>\r\n        public static void ConfigureConfigureBehavior(string settingName, string value)\r\n        {\r\n            JObject settingsJson = GetJsonSettingsObject(\"configureBehavior\");\r\n            var configureBehavior = settingsJson[\"configureBehavior\"];\r\n            configureBehavior[settingName] = value;\r\n\r\n            SetWingetSettings(settingsJson);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Configure the install behavior preferences.\r\n        /// </summary>\r\n        /// <param name=\"settingName\">Setting name.</param>\r\n        /// <param name=\"value\">Setting value.</param>\r\n        public static void ConfigureInstallBehaviorPreferences(string settingName, string value)\r\n        {\r\n            JObject settingsJson = GetJsonSettingsObject(\"installBehavior\");\r\n            var installBehavior = settingsJson[\"installBehavior\"];\r\n\r\n            if (installBehavior[\"preferences\"] == null)\r\n            {\r\n                installBehavior[\"preferences\"] = new JObject();\r\n            }\r\n\r\n            var preferences = installBehavior[\"preferences\"];\r\n            preferences[settingName] = value;\r\n\r\n            SetWingetSettings(settingsJson);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Configure the install behavior preferences.\r\n        /// </summary>\r\n        /// <param name=\"settingName\">Setting name.</param>\r\n        /// <param name=\"value\">Setting value array.</param>\r\n        public static void ConfigureInstallBehaviorPreferences(string settingName, string[] value)\r\n        {\r\n            JObject settingsJson = GetJsonSettingsObject(\"installBehavior\");\r\n            var installBehavior = settingsJson[\"installBehavior\"];\r\n\r\n            if (installBehavior[\"preferences\"] == null)\r\n            {\r\n                installBehavior[\"preferences\"] = new JObject();\r\n            }\r\n\r\n            var preferences = installBehavior[\"preferences\"];\r\n            preferences[settingName] = new JArray(value);\r\n\r\n            SetWingetSettings(settingsJson);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Configure the install behavior requirements.\r\n        /// </summary>\r\n        /// <param name=\"settingName\">Setting name.</param>\r\n        /// <param name=\"value\">Setting value.</param>\r\n        public static void ConfigureInstallBehaviorRequirements(string settingName, string value)\r\n        {\r\n            JObject settingsJson = GetJsonSettingsObject(\"installBehavior\");\r\n            var installBehavior = settingsJson[\"installBehavior\"];\r\n\r\n            if (installBehavior[\"requirements\"] == null)\r\n            {\r\n                installBehavior[\"requirements\"] = new JObject();\r\n            }\r\n\r\n            var requirements = installBehavior[\"requirements\"];\r\n            requirements[settingName] = value;\r\n\r\n            SetWingetSettings(settingsJson);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Configure the install behavior requirements.\r\n        /// </summary>\r\n        /// <param name=\"settingName\">Setting name.</param>\r\n        /// <param name=\"value\">Setting value array.</param>\r\n        public static void ConfigureInstallBehaviorRequirements(string settingName, string[] value)\r\n        {\r\n            JObject settingsJson = GetJsonSettingsObject(\"installBehavior\");\r\n            var installBehavior = settingsJson[\"installBehavior\"];\r\n\r\n            if (installBehavior[\"requirements\"] == null)\r\n            {\r\n                installBehavior[\"requirements\"] = new JObject();\r\n            }\r\n\r\n            var requirements = installBehavior[\"requirements\"];\r\n            requirements[settingName] = new JArray(value);\r\n\r\n            SetWingetSettings(settingsJson);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Initialize all features.\r\n        /// </summary>\r\n        /// <param name=\"status\">Initialized feature value.</param>\r\n        public static void InitializeAllFeatures(bool status)\r\n        {\r\n            JObject settingsJson = GetJsonSettingsObject(\"experimentalFeatures\");\r\n\r\n            ConfigureFeature(settingsJson, \"experimentalArg\", status);\r\n            ConfigureFeature(settingsJson, \"experimentalCmd\", status);\r\n            ConfigureFeature(settingsJson, \"directMSI\", status);\r\n            ConfigureFeature(settingsJson, \"windowsFeature\", status);\r\n            ConfigureFeature(settingsJson, \"resume\", status);\r\n            ConfigureFeature(settingsJson, \"reboot\", status);\r\n            ConfigureFeature(settingsJson, \"fonts\", status);\r\n            ConfigureFeature(settingsJson, \"sourcePriority\", status);\r\n\r\n            SetWingetSettings(settingsJson);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Configure the logging level for the settings.\r\n        /// </summary>\r\n        /// <param name=\"level\">The logging level to set; null removes the value.</param>\r\n        public static void ConfigureLoggingLevel(string level)\r\n        {\r\n            JObject settingsJson = GetJsonSettingsObject(\"logging\");\r\n\r\n            if (level == null)\r\n            {\r\n                settingsJson[\"logging\"][\"level\"]?.Parent?.Remove();\r\n            }\r\n            else\r\n            {\r\n                settingsJson[\"logging\"][\"level\"] = new JValue(level);\r\n            }\r\n\r\n            SetWingetSettings(settingsJson);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Configure experimental features.\r\n        /// </summary>\r\n        /// <param name=\"settingsJson\">The settings JSON object to modify.</param>\r\n        /// <param name=\"featureName\">Feature name.</param>\r\n        /// <param name=\"status\">Status.</param>\r\n        private static void ConfigureFeature(JObject settingsJson, string featureName, bool status)\r\n        {\r\n            var experimentalFeatures = settingsJson[\"experimentalFeatures\"];\r\n            experimentalFeatures[featureName] = status;\r\n        }\r\n\r\n        private static JObject GetJsonSettingsObject(string objectName)\r\n        {\r\n            JObject settingsJson = JObject.Parse(File.ReadAllText(TestSetup.Parameters.SettingsJsonFilePath));\r\n\r\n            if (!settingsJson.ContainsKey(objectName))\r\n            {\r\n                settingsJson[objectName] = new JObject();\r\n            }\r\n\r\n            return settingsJson;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Converts a JObject to a string and writes to the settings file.\r\n        /// </summary>\r\n        /// <param name=\"settingsJson\">Settings to set.</param>\r\n        private static void SetWingetSettings(JObject settingsJson)\r\n        {\r\n            var forcedExperimentalFeatures = ForcedExperimentalFeatures;\r\n            if (forcedExperimentalFeatures != null)\r\n            {\r\n                foreach (var feature in forcedExperimentalFeatures)\r\n                {\r\n                    ConfigureFeature(settingsJson, feature, true);\r\n                }\r\n            }\r\n\r\n            SetWingetSettings(settingsJson.ToString());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Writes string to settings file.\r\n        /// </summary>\r\n        /// <param name=\"settings\">Settings as string.</param>\r\n        private static void SetWingetSettings(string settings)\r\n        {\r\n            File.WriteAllText(TestSetup.Parameters.SettingsJsonFilePath, settings);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/ImportCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ImportCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\n{\n    using System.IO;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\n\n    /// <summary>\r\n    /// Import command tests.\r\n    /// </summary>\n    public class ImportCommand : BaseCommand\n    {\n        /// <summary>\r\n        /// Set up.\r\n        /// </summary>\n        [SetUp]\n        public void Setup()\n        {\n            this.CleanupTestExe();\n        }\n\n        /// <summary>\r\n        /// Test import v1.\r\n        /// </summary>\n        [Test]\n        public void ImportSuccessful_1_0()\n        {\n            var result = TestCommon.RunAICLICommand(\"import\", this.GetTestImportFile(\"ImportFile-Good.1.0.json\"));\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\n            Assert.True(this.VerifyTestExeInstalled());\n            this.UninstallTestExe();\n        }\n\n        /// <summary>\r\n        /// Test import v2.\r\n        /// </summary>\n        [Test]\n        public void ImportSuccessful_2_0()\n        {\n            var result = TestCommon.RunAICLICommand(\"import\", this.GetTestImportFile(\"ImportFile-Good.2.0.json\"));\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\n            Assert.True(this.VerifyTestExeInstalled());\n            this.UninstallTestExe();\n        }\n\n        /// <summary>\r\n        /// Test import invalid file.\r\n        /// </summary>\n        [Test]\n        public void ImportInvalidFile()\n        {\n            // Verify failure when trying to import with an invalid file\n            var result = TestCommon.RunAICLICommand(\"import\", this.GetTestImportFile(\"ImportFile-Bad-Invalid.json\"));\n            Assert.AreEqual(Constants.ErrorCode.ERROR_JSON_INVALID_FILE, result.ExitCode);\n            Assert.True(result.StdOut.Contains(\"JSON file is not valid\"));\n        }\n\n        /// <summary>\r\n        /// Test import from an unknown source.\r\n        /// </summary>\n        [Test]\n        public void ImportUnknownSource()\n        {\n            // Verify failure when trying to import from an unknown source\n            var result = TestCommon.RunAICLICommand(\"import\", this.GetTestImportFile(\"ImportFile-Bad-UnknownSource.json\"));\n            Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode);\n            Assert.True(result.StdOut.Contains(\"Source required for import is not installed\"));\n        }\n\n        /// <summary>\r\n        /// Test import for an unknown package.\r\n        /// </summary>\n        [Test]\n        public void ImportUnavailablePackage()\n        {\n            // Verify failure when trying to import an unavailable package\n            var result = TestCommon.RunAICLICommand(\"import\", this.GetTestImportFile(\"ImportFile-Bad-UnknownPackage.json\"));\n            Assert.AreEqual(Constants.ErrorCode.ERROR_NOT_ALL_QUERIES_FOUND_SINGLE, result.ExitCode);\n            Assert.True(result.StdOut.Contains(\"Package not found: MissingPackage\"));\n        }\n\n        /// <summary>\r\n        /// Test import when the package version is not present.\r\n        /// </summary>\n        [Test]\n        public void ImportUnavailableVersion()\n        {\n            // Verify failure when trying to import an unavailable package\n            var result = TestCommon.RunAICLICommand(\"import\", this.GetTestImportFile(\"ImportFile-Bad-UnknownPackageVersion.json\"));\n            Assert.AreEqual(Constants.ErrorCode.ERROR_NOT_ALL_QUERIES_FOUND_SINGLE, result.ExitCode);\n            Assert.True(result.StdOut.Contains(\"Search failed for: AppInstallerTest.TestExeInstaller\"));\n        }\n\n        /// <summary>\r\n        /// Test import when the package is already installed.\r\n        /// </summary>\n        [Test]\n        public void ImportAlreadyInstalled()\n        {\n            // Verify success with message when trying to import a package that is already installed\n            var installDir = TestCommon.GetRandomTestDir();\n            TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestExeInstaller -l {installDir}\");\n            var result = TestCommon.RunAICLICommand(\"import\", $\"{this.GetTestImportFile(\"ImportFile-Good.1.0.json\")}\");\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\n            Assert.True(result.StdOut.Contains(\"Package is already installed\"));\n            Assert.False(this.VerifyTestExeInstalled());\n            this.UninstallTestExe();\n        }\n\n        /// <summary>\r\n        /// Test Import with an exported file.\r\n        /// </summary>\n        [Test]\n        public void ImportExportedFile()\n        {\n            // Verify success when importing an exported list of packages.\n            // First install the test package to ensure it is exported.\n            TestCommon.RunAICLICommand(\"install\", Constants.ExeInstallerPackageId);\n\n            var jsonFile = TestCommon.GetRandomTestFile(\".json\");\n            TestCommon.RunAICLICommand(\"export\", $\"{jsonFile} -s TestSource\");\n\n            // Uninstall the package to ensure we can install it again\n            this.UninstallTestExe();\n\n            // Import the file\n            var result = TestCommon.RunAICLICommand(\"import\", jsonFile);\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\n            Assert.True(this.VerifyTestExeInstalled());\n            this.UninstallTestExe();\n        }\n\n        private string GetTestImportFile(string importFileName)\n        {\n            return TestCommon.GetTestDataFile(Path.Combine(\"ImportFiles\", importFileName));\n        }\n\n        private bool VerifyTestExeInstalled(string installDir = null)\n        {\n            if (string.IsNullOrEmpty(installDir))\n            {\n                // Default location used by installer\n                installDir = Path.GetTempPath();\n            }\n\n            return File.Exists(Path.Combine(installDir, Constants.TestExeInstalledFileName));\n        }\n\n        private void UninstallTestExe()\n        {\n            TestCommon.RunAICLICommand(\"uninstall\", Constants.ExeInstallerPackageId);\n        }\n\n        private void CleanupTestExe()\n        {\n            this.UninstallTestExe();\n            File.Delete(Path.Combine(Path.GetTempPath(), Constants.TestExeInstalledFileName));\n            File.Delete(Path.Combine(Path.GetTempPath(), Constants.TestExeUninstallerFileName));\n        }\n    }\n}"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/InprocTestbedTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"InprocTestbedTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using System.IO;\r\n    using System.Reflection;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// Tests that run the inproc testbed targeting COM lifetime.\r\n    /// </summary>\r\n    public class InprocTestbedTests\r\n    {\r\n        /// <summary>\r\n        /// The activation type to use when creating objects.\r\n        /// </summary>\r\n        public enum ActivationType\r\n        {\r\n            /// <summary>\r\n            /// Use the WinRT type name for activation via C++/WinRT object construction.\r\n            /// </summary>\r\n            ClassName,\r\n\r\n            /// <summary>\r\n            /// Use the CLSID for activation via C++/WinRT `create_instance`.\r\n            /// </summary>\r\n            CoCreateInstance,\r\n        }\r\n\r\n        /// <summary>\r\n        /// Control when the module will allow signal that it can be unloaded if all objects are released.\r\n        /// This does not affect the loader by taking additional references to the module.\r\n        /// </summary>\r\n        public enum UnloadBehavior\r\n        {\r\n            /// <summary>\r\n            /// Allows the unload check function to proceed with object count checks and unload when possible.\r\n            /// </summary>\r\n            Allow,\r\n\r\n            /// <summary>\r\n            /// Prevents the unload check until just before COM is uninitialized.\r\n            /// </summary>\r\n            AtUninitialize,\r\n\r\n            /// <summary>\r\n            /// Prevents the unload check at all times.\r\n            /// </summary>\r\n            Never,\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the path to the inproc testbed executable.\r\n        /// </summary>\r\n        private string InprocTestbedPath { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the string that contains the package identity to use for the tests.\r\n        /// </summary>\r\n        private string TargetPackageInformation { get; set; }\r\n\r\n        /// <summary>\r\n        /// Setup done once before all the tests here.\r\n        /// </summary>\r\n        [OneTimeSetUp]\r\n        public void OneTimeSetup()\r\n        {\r\n            this.InprocTestbedPath = TestSetup.Parameters.InprocTestbedPath;\r\n\r\n            if (string.IsNullOrWhiteSpace(this.InprocTestbedPath))\r\n            {\r\n                string assemblyLocation = Assembly.GetExecutingAssembly().Location;\r\n                this.InprocTestbedPath = Path.Join(Path.GetDirectoryName(assemblyLocation), \"..\\\\ComInprocTestbed\\\\ComInprocTestbed.exe\");\r\n            }\r\n\r\n            if (TestSetup.Parameters.InprocTestbedUseTestPackage)\r\n            {\r\n                this.TargetPackageInformation = $\"-pkg {Constants.ExeInstallerPackageId} -src {Constants.TestSourceName} -url {Constants.TestSourceUrl}\";\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Executes the testbed as simply as possible to ensure integrations.\r\n        /// </summary>\r\n        [Test]\r\n        public void DefaultTest()\r\n        {\r\n            this.RunInprocTestbed(new TestbedParameters() { WorkTestSleepInterval = 1000 });\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests using the CLSID with CoCreateInstance.\r\n        /// </summary>\r\n        /// <param name=\"leakCOM\">Control whether COM should be uninitialized at the end of the process.</param>\r\n        /// <param name=\"unloadBehavior\">Set the unload behavior for the test.</param>\r\n        /// <param name=\"workTestSleep\">Sets the number of milliseconds to sleep between each work/test iteration.</param>\r\n        [Test]\r\n        [TestCase(false, UnloadBehavior.AtUninitialize)]\r\n        [TestCase(false, UnloadBehavior.Never)]\r\n        [TestCase(true, UnloadBehavior.Allow, 1000)]\r\n        [TestCase(true, UnloadBehavior.Never)]\r\n        public void CLSID_Tests(bool leakCOM, UnloadBehavior unloadBehavior, int? workTestSleep = null)\r\n        {\r\n            this.RunInprocTestbed(new TestbedParameters()\r\n            {\r\n                ActivationType = ActivationType.CoCreateInstance,\r\n                LeakCOM = leakCOM,\r\n                UnloadBehavior = unloadBehavior,\r\n                Iterations = 10,\r\n                WorkTestSleepInterval = workTestSleep,\r\n            });\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests using C++/WinRT object activation through the type name.\r\n        /// </summary>\r\n        /// <param name=\"freeCachedFactories\">Control whether the C++/WinRT factory cache will be cleared between iterations.</param>\r\n        /// <param name=\"leakCOM\">Control whether COM should be uninitialized at the end of the process.</param>\r\n        /// <param name=\"unloadBehavior\">Set the unload behavior for the test.</param>\r\n        /// <param name=\"workTestSleep\">Sets the number of milliseconds to sleep between each work/test iteration.</param>\r\n        [Test]\r\n        [TestCase(false, false, UnloadBehavior.AtUninitialize)]\r\n        [TestCase(false, false, UnloadBehavior.Never)]\r\n        [TestCase(false, true, UnloadBehavior.Allow)]\r\n        [TestCase(false, true, UnloadBehavior.Never)]\r\n        [TestCase(true, false, UnloadBehavior.AtUninitialize)]\r\n        [TestCase(true, false, UnloadBehavior.Never)]\r\n        [TestCase(true, true, UnloadBehavior.Allow, 1000)]\r\n        [TestCase(true, true, UnloadBehavior.Never)]\r\n        public void TypeName_Tests(bool freeCachedFactories, bool leakCOM, UnloadBehavior unloadBehavior, int? workTestSleep = null)\r\n        {\r\n            this.RunInprocTestbed(new TestbedParameters()\r\n            {\r\n                ActivationType = ActivationType.ClassName,\r\n                ClearFactories = freeCachedFactories,\r\n                LeakCOM = leakCOM,\r\n                UnloadBehavior = unloadBehavior,\r\n                Iterations = 10,\r\n                WorkTestSleepInterval = workTestSleep,\r\n            });\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests that disable the termination signal handling.\r\n        /// </summary>\r\n        /// <param name=\"disableTerminationSignals\">Control whether the module should listen to termination signals.</param>\r\n        /// <param name=\"unloadBehavior\">Set the unload behavior for the test.</param>\r\n        /// <param name=\"workTestSleep\">Sets the number of milliseconds to sleep between each work/test iteration.</param>\r\n        [Test]\r\n        [TestCase(true, UnloadBehavior.Allow, 1000)]\r\n        [TestCase(true, UnloadBehavior.Never)]\r\n        [TestCase(false, UnloadBehavior.Allow, 1000)]\r\n        [TestCase(false, UnloadBehavior.Never)]\r\n        public void TerminationSignal_Tests(bool disableTerminationSignals, UnloadBehavior unloadBehavior, int? workTestSleep = null)\r\n        {\r\n            this.RunInprocTestbed(new TestbedParameters()\r\n            {\r\n                ActivationType = ActivationType.CoCreateInstance,\r\n                DisableTerminationSignals = disableTerminationSignals,\r\n                UnloadBehavior = unloadBehavior,\r\n                Iterations = 10,\r\n                WorkTestSleepInterval = workTestSleep,\r\n            });\r\n        }\r\n\r\n        private void RunInprocTestbed(TestbedParameters parameters, int timeout = 300000)\r\n        {\r\n            string builtParameters = string.Empty;\r\n\r\n            if (parameters.ActivationType != null)\r\n            {\r\n                builtParameters += $\"-activation {parameters.ActivationType} \";\r\n            }\r\n\r\n            if (!parameters.ClearFactories)\r\n            {\r\n                builtParameters += \"-keep-factories \";\r\n            }\r\n\r\n            if (parameters.LeakCOM)\r\n            {\r\n                builtParameters += \"-leak-com \";\r\n            }\r\n\r\n            if (parameters.UnloadBehavior != null)\r\n            {\r\n                builtParameters += $\"-unload {parameters.UnloadBehavior} \";\r\n            }\r\n\r\n            if (parameters.Test != null)\r\n            {\r\n                builtParameters += $\"-test {parameters.Test} \";\r\n            }\r\n\r\n            if (parameters.Iterations != null)\r\n            {\r\n                builtParameters += $\"-itr {parameters.Iterations} \";\r\n            }\r\n\r\n            if (parameters.WorkTestSleepInterval != null)\r\n            {\r\n                builtParameters += $\"-work-test-sleep {parameters.WorkTestSleepInterval} \";\r\n            }\r\n\r\n            if (parameters.DisableTerminationSignals)\r\n            {\r\n                builtParameters += $\"-no-term \";\r\n            }\r\n\r\n            var result = TestCommon.RunProcess(this.InprocTestbedPath, this.TargetPackageInformation, builtParameters, null, timeout, true);\r\n            Assert.AreEqual(0, result.ExitCode);\r\n        }\r\n\r\n        /// <summary>\r\n        /// The parameters to provide for running tests.\r\n        /// </summary>\r\n        private class TestbedParameters\r\n        {\r\n            internal ActivationType? ActivationType { get; init; } = null;\r\n\r\n            internal bool ClearFactories { get; init; } = true;\r\n\r\n            internal bool LeakCOM { get; init; } = false;\r\n\r\n            internal UnloadBehavior? UnloadBehavior { get; init; } = null;\r\n\r\n            internal string Test { get; init; } = \"unload_check\";\r\n\r\n            internal int? Iterations { get; init; } = null;\r\n\r\n            internal int? WorkTestSleepInterval { get; init; } = null;\r\n\r\n            internal bool DisableTerminationSignals { get; init; } = false;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/InstallCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"InstallCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using System;\r\n    using System.IO;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// Test install command.\r\n    /// </summary>\r\n    public class InstallCommand : BaseCommand\r\n    {\r\n        /// <summary>\r\n        /// One time set up.\r\n        /// </summary>\r\n        [OneTimeSetUp]\r\n        public void OneTimeSetup()\r\n        {\r\n            WinGetSettingsHelper.ConfigureFeature(\"sourcePriority\", true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Set up.\r\n        /// </summary>\r\n        [SetUp]\r\n        public void Setup()\r\n        {\r\n            // Try clean up TestExeInstaller for failure cases where cleanup is not successful\r\n            TestCommon.RunAICLICommand(\"uninstall\", \"AppInstallerTest.TestExeInstaller\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test package doesn't exist.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallAppDoesNotExist()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"install\", \"DoesNotExist\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"No package found matching input criteria.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test multiple matches found.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallWithMultipleAppsMatchingQuery()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"install\", \"TestExeInstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_MULTIPLE_APPLICATIONS_FOUND, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Multiple packages found matching input criteria. Please refine the input.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install exe.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallExe()\r\n        {\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestExeInstaller --silent -l {installDir}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, \"/execustom\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test inapplicable os version.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallExeWithInsufficientMinOsVersion()\r\n        {\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"InapplicableOsVersion --silent -l {installDir}\");\r\n\r\n            // MinOSVersion is moved to installer level, the check is performed during installer selection\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICABLE_INSTALLER, result.ExitCode);\r\n            Assert.False(TestCommon.VerifyTestExeInstalledAndCleanup(installDir));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install exe hash mismatch.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallExeWithHashMismatch()\r\n        {\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"TestExeSha256Mismatch --silent -l {installDir}\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_INSTALLER_HASH_MISMATCH, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Installer hash does not match\"));\r\n            Assert.False(TestCommon.VerifyTestExeInstalledAndCleanup(installDir));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install inno.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallWithInno()\r\n        {\r\n            // Install test inno, manifest does not provide silent switch, we should be populating the default\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"TestInnoInstaller --silent -l {installDir}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, \"/VERYSILENT\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install burn.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallBurn()\r\n        {\r\n            // Install test burn, manifest does not provide silent switch, we should be populating the default\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"TestBurnInstaller --silent -l {installDir}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, \"/quiet\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install nullsoft.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallNullSoft()\r\n        {\r\n            // Install test Nullsoft, manifest does not provide silent switch, we should be populating the default\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"TestNullsoftInstaller --silent -l {installDir}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, \"/S\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install msi.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallMSI()\r\n        {\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"TestMsiInstaller --silent -l {installDir}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n            Assert.True(TestCommon.VerifyTestMsiInstalledAndCleanup(installDir));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install msix.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallMSIX()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"TestMsixInstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n            Assert.True(TestCommon.VerifyTestMsixInstalledAndCleanup());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install msix machine scope.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallMSIXMachineScope()\r\n        {\r\n            // TODO: Provision and Deprovision api not supported in build server.\r\n            Assert.Ignore();\r\n\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"TestMsixInstaller --scope machine\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n            Assert.True(TestCommon.VerifyTestMsixInstalledAndCleanup(true));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install msix with signature hash.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallMSIXWithSignature()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"TestMsixWithSignatureHash\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n            Assert.True(TestCommon.VerifyTestMsixInstalledAndCleanup());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install msix with signature hash machine scope.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallMSIXWithSignatureMachineScope()\r\n        {\r\n            // TODO: Provision and Deprovision api not supported in build server.\r\n            Assert.Ignore();\r\n\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"TestMsixWithSignatureHash --scope machine\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n            Assert.True(TestCommon.VerifyTestMsixInstalledAndCleanup(true));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test msix hash mismatch.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallMSIXWithSignatureHashMismatch()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"TestMsixSignatureHashMismatch\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_INSTALLER_HASH_MISMATCH, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Installer hash does not match\"));\r\n            Assert.False(TestCommon.VerifyTestMsixInstalledAndCleanup());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install with alternate source failure.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallExeWithAlternateSourceFailure()\r\n        {\r\n            TestCommon.RunAICLICommand(\"source add\", \"failSearch \\\"{ \\\"\\\"SearchHR\\\"\\\": \\\"\\\"0x80070002\\\"\\\" }\\\" Microsoft.Test.Configurable --header \\\"{}\\\"\");\r\n\r\n            try\r\n            {\r\n                var installDir = TestCommon.GetRandomTestDir();\r\n                var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestExeInstaller --silent -l {installDir}\");\r\n                Assert.AreEqual(unchecked((int)0x80070002), result.ExitCode);\r\n                Assert.True(result.StdOut.Contains(\"Failed when searching source: failSearch\"));\r\n                Assert.True(result.StdOut.Contains(\"AppInstallerTest.TestExeInstaller\"));\r\n                Assert.False(result.StdOut.Contains(\"Successfully installed\"));\r\n                Assert.False(TestCommon.VerifyTestExeInstalledAndCleanup(installDir));\r\n            }\r\n            finally\r\n            {\r\n                this.ResetTestSource();\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install portable package.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallPortableExe()\r\n        {\r\n            string installDir = TestCommon.GetPortablePackagesDirectory();\r\n            string packageId, commandAlias, fileName, packageDirName, productCode;\r\n            packageId = \"AppInstallerTest.TestPortableExe\";\r\n            packageDirName = productCode = packageId + \"_\" + Constants.TestSourceIdentifier;\r\n            commandAlias = fileName = \"AppInstallerTestExeInstaller.exe\";\r\n\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"{packageId}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            // If no location specified, default behavior is to create a package directory with the name \"{packageId}_{sourceId}\"\r\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install portable package with command.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallPortableExeWithCommand()\r\n        {\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            string packageId, commandAlias, fileName, productCode;\r\n            packageId = \"AppInstallerTest.TestPortableExeWithCommand\";\r\n            productCode = packageId + \"_\" + Constants.TestSourceIdentifier;\r\n            fileName = \"AppInstallerTestExeInstaller.exe\";\r\n            commandAlias = \"testCommand.exe\";\r\n\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"{packageId} -l {installDir}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n            TestCommon.VerifyPortablePackage(installDir, commandAlias, fileName, productCode, true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install portable package with rename.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallPortableExeWithRename()\r\n        {\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            string packageId, productCode, renameArgValue;\r\n            packageId = \"AppInstallerTest.TestPortableExeWithCommand\";\r\n            productCode = packageId + \"_\" + Constants.TestSourceIdentifier;\r\n            renameArgValue = \"testRename.exe\";\r\n\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"{packageId} -l {installDir} --rename {renameArgValue}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n            TestCommon.VerifyPortablePackage(installDir, renameArgValue, renameArgValue, productCode, true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install portable package invalid rename.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallPortableInvalidRename()\r\n        {\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            string packageId, renameArgValue;\r\n            packageId = \"AppInstallerTest.TestPortableExeWithCommand\";\r\n            renameArgValue = \"test?\";\r\n\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"{packageId} -l {installDir} --rename {renameArgValue}\");\r\n            Assert.AreNotEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"The specified filename is not a valid filename\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install portable package with reserve names.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallPortableReservedNames()\r\n        {\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            string packageId, renameArgValue;\r\n            packageId = \"AppInstallerTest.TestPortableExeWithCommand\";\r\n            renameArgValue = \"CON\";\r\n\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"{packageId} -l {installDir} --rename {renameArgValue}\");\r\n            Assert.AreNotEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"The specified filename is not a valid filename\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install portable package to an existing directory.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallPortableToExistingDirectory()\r\n        {\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var existingDir = Path.Combine(installDir, \"testDirectory\");\r\n            Directory.CreateDirectory(existingDir);\r\n\r\n            string packageId, commandAlias, fileName, productCode;\r\n            packageId = \"AppInstallerTest.TestPortableExe\";\r\n            productCode = packageId + \"_\" + Constants.TestSourceIdentifier;\r\n            commandAlias = fileName = \"AppInstallerTestExeInstaller.exe\";\r\n\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"{packageId} -l {existingDir}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n            TestCommon.VerifyPortablePackage(existingDir, commandAlias, fileName, productCode, true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install portable package. Symlink is a directory.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallPortableFailsWithCleanup()\r\n        {\r\n            string packageId, commandAlias;\r\n            packageId = \"AppInstallerTest.TestPortableExe\";\r\n            commandAlias = \"AppInstallerTestExeInstaller.exe\";\r\n\r\n            // Create a directory with the same name as the symlink in order to cause install to fail.\r\n            string symlinkDirectory = TestCommon.GetPortableSymlinkDirectory(TestCommon.Scope.User);\r\n            string conflictDirectory = Path.Combine(symlinkDirectory, commandAlias);\r\n\r\n            Directory.CreateDirectory(conflictDirectory);\r\n\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"{packageId}\");\r\n\r\n            // Remove directory prior to assertions as this will impact other tests if assertions fail.\r\n            Directory.Delete(conflictDirectory, true);\r\n\r\n            Assert.AreNotEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Unable to create symlink\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test reinstalling portable package.\r\n        /// </summary>\r\n        [Test]\r\n        public void ReinstallPortable()\r\n        {\r\n            string installDir = TestCommon.GetPortablePackagesDirectory();\r\n            string packageId, commandAlias, fileName, packageDirName, productCode;\r\n            packageId = \"AppInstallerTest.TestPortableExe\";\r\n            packageDirName = productCode = packageId + \"_\" + Constants.TestSourceIdentifier;\r\n            commandAlias = fileName = \"AppInstallerTestExeInstaller.exe\";\r\n\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"{packageId}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n\r\n            string symlinkDirectory = TestCommon.GetPortableSymlinkDirectory(TestCommon.Scope.User);\r\n            string symlinkPath = Path.Combine(symlinkDirectory, commandAlias);\r\n\r\n            // Clean first install should not display file overwrite message.\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n            Assert.False(result.StdOut.Contains($\"Overwriting existing file: {symlinkPath}\"));\r\n\r\n            // Perform second install and verify that file overwrite message is displayed.\r\n            var result2 = TestCommon.RunAICLICommand(\"install\", $\"{packageId} --force\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode);\r\n            Assert.True(result2.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test installing portable package user scope.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallPortable_UserScope()\r\n        {\r\n            string installDir = TestCommon.GetRandomTestDir();\r\n            WinGetSettingsHelper.ConfigureInstallBehavior(Constants.PortablePackageUserRoot, installDir);\r\n\r\n            string packageId, commandAlias, fileName, packageDirName, productCode;\r\n            packageId = \"AppInstallerTest.TestPortableExe\";\r\n            packageDirName = productCode = packageId + \"_\" + Constants.TestSourceIdentifier;\r\n            commandAlias = fileName = \"AppInstallerTestExeInstaller.exe\";\r\n\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"{packageId} --scope user\");\r\n            WinGetSettingsHelper.ConfigureInstallBehavior(Constants.PortablePackageUserRoot, string.Empty);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install portable package machine scope.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallPortable_MachineScope()\r\n        {\r\n            string installDir = TestCommon.GetRandomTestDir();\r\n            WinGetSettingsHelper.ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, installDir);\r\n\r\n            string packageId, commandAlias, fileName, packageDirName, productCode;\r\n            packageId = \"AppInstallerTest.TestPortableExe\";\r\n            packageDirName = productCode = packageId + \"_\" + Constants.TestSourceIdentifier;\r\n            commandAlias = fileName = \"AppInstallerTestExeInstaller.exe\";\r\n\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"{packageId} --scope machine\");\r\n            WinGetSettingsHelper.ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, string.Empty);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true, TestCommon.Scope.Machine);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install portable package with settings set to user install scope.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallPortable_InstallScopePreference_User()\r\n        {\r\n            string installDir = TestCommon.GetRandomTestDir();\r\n            WinGetSettingsHelper.ConfigureInstallBehavior(Constants.PortablePackageUserRoot, installDir);\r\n            WinGetSettingsHelper.ConfigureInstallBehaviorPreferences(Constants.InstallBehaviorScope, \"user\");\r\n\r\n            string packageId, commandAlias, fileName, packageDirName, productCode;\r\n            packageId = \"AppInstallerTest.TestPortableExe\";\r\n            packageDirName = productCode = packageId + \"_\" + Constants.TestSourceIdentifier;\r\n            commandAlias = fileName = \"AppInstallerTestExeInstaller.exe\";\r\n\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"{packageId}\");\r\n            WinGetSettingsHelper.ConfigureInstallBehavior(Constants.PortablePackageUserRoot, string.Empty);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install portable package with settings set to machine install scope.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallPortable_InstallScopePreference_Machine()\r\n        {\r\n            string installDir = TestCommon.GetRandomTestDir();\r\n            WinGetSettingsHelper.ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, installDir);\r\n            WinGetSettingsHelper.ConfigureInstallBehaviorPreferences(Constants.InstallBehaviorScope, \"machine\");\r\n\r\n            string packageId, commandAlias, fileName, packageDirName, productCode;\r\n            packageId = \"AppInstallerTest.TestPortableExe\";\r\n            packageDirName = productCode = packageId + \"_\" + Constants.TestSourceIdentifier;\r\n            commandAlias = fileName = \"AppInstallerTestExeInstaller.exe\";\r\n\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"{packageId}\");\r\n            WinGetSettingsHelper.ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, string.Empty);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true, TestCommon.Scope.Machine);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install zip exe.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallZip_Exe()\r\n        {\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestZipInstallerWithExe --silent -l {installDir}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, \"/execustom\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install zip portable.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallZip_Portable()\r\n        {\r\n            string installDir = TestCommon.GetPortablePackagesDirectory();\r\n            string packageId, commandAlias, fileName, packageDirName, productCode;\r\n            packageId = \"AppInstallerTest.TestZipInstallerWithPortable\";\r\n            packageDirName = productCode = packageId + \"_\" + Constants.TestSourceIdentifier;\r\n            commandAlias = \"TestPortable.exe\";\r\n            fileName = \"AppInstallerTestExeInstaller.exe\";\r\n\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"{packageId}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true, TestCommon.Scope.User);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install zip portable with binaries that depend on PATH variable.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallZip_ArchivePortableWithBinariesDependentOnPath()\r\n        {\r\n            string installDir = TestCommon.GetPortablePackagesDirectory();\r\n            string packageId, commandAlias, fileName, packageDirName, productCode;\r\n            packageId = \"AppInstallerTest.ArchivePortableWithBinariesDependentOnPath\";\r\n            packageDirName = productCode = packageId + \"_\" + Constants.TestSourceIdentifier;\r\n            commandAlias = \"TestPortable.exe\";\r\n            fileName = \"AppInstallerTestExeInstaller.exe\";\r\n\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"{packageId}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true, TestCommon.Scope.User, true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install zip with invalid relative file path.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallZipWithInvalidRelativeFilePath()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestZipInvalidRelativePath\");\r\n            Assert.AreNotEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Invalid relative file path to the nested installer; path points to a location outside of the install directory\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install zip msi.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallZipWithMsi()\r\n        {\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestZipInstallerWithMsi --silent -l {installDir}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n            Assert.True(TestCommon.VerifyTestMsiInstalledAndCleanup(installDir));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install zip msix.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallZipWithMsix()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestZipInstallerWithMsix\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n            Assert.True(TestCommon.VerifyTestMsixInstalledAndCleanup());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install zip exe by extracting with tar.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallZip_ExtractWithTar()\r\n        {\r\n            WinGetSettingsHelper.ConfigureInstallBehavior(Constants.ArchiveExtractionMethod, \"tar\");\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestZipInstallerWithExe --silent -l {installDir}\");\r\n            WinGetSettingsHelper.ConfigureInstallBehavior(Constants.ArchiveExtractionMethod, string.Empty);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, \"/execustom\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install an installed package and convert to upgrade.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallExeFoundExistingConvertToUpgrade()\r\n        {\r\n            var baseDir = TestCommon.GetRandomTestDir();\r\n            var baseResult = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestExeInstaller -v 1.0.0.0 --silent -l {baseDir}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, baseResult.ExitCode);\r\n            Assert.True(baseResult.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            // Install will convert to upgrade\r\n            var upgradeDir = TestCommon.GetRandomTestDir();\r\n            var upgradeResult = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestExeInstaller --silent -l {upgradeDir}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, upgradeResult.ExitCode);\r\n            Assert.True(upgradeResult.StdOut.Contains(\"Trying to upgrade the installed package...\"));\r\n            Assert.True(upgradeResult.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(baseDir));\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(upgradeDir, \"/Version 2.0.0.0\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install an installed package without an available upgrade.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallExeFoundExistingConvertToUpgradeNoAvailableUpgrade()\r\n        {\r\n            var baseDir = TestCommon.GetRandomTestDir();\r\n            var baseResult = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestExeInstaller -v 2.0.0.0 --silent -l {baseDir}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, baseResult.ExitCode);\r\n            Assert.True(baseResult.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            // Install will convert to upgrade\r\n            var upgradeDir = TestCommon.GetRandomTestDir();\r\n            var upgradeResult = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestExeInstaller --silent -l {upgradeDir}\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_UPDATE_NOT_APPLICABLE, upgradeResult.ExitCode);\r\n            Assert.True(upgradeResult.StdOut.Contains(\"Trying to upgrade the installed package...\"));\r\n            Assert.True(upgradeResult.StdOut.Contains(\"No available upgrade\"));\r\n\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(baseDir));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test force installing a package.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallExeWithLatestInstalledWithForce()\r\n        {\r\n            var baseDir = TestCommon.GetRandomTestDir();\r\n            var baseResult = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestExeInstaller -v 2.0.0.0 --silent -l {baseDir}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, baseResult.ExitCode);\r\n            Assert.True(baseResult.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            // Install will not convert to upgrade\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var installResult = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestExeInstaller -v 1.0.0.0 --silent -l {installDir} --force\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, installResult.ExitCode);\r\n            Assert.True(installResult.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(baseDir));\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, \"/execustom\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install a package with an invalid Windows Feature dependency.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallWithWindowsFeatureDependency_FeatureNotFound()\r\n        {\r\n            var testDir = TestCommon.GetRandomTestDir();\r\n            var installResult = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.WindowsFeature -l {testDir}\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_INSTALL_DEPENDENCIES, installResult.ExitCode);\r\n            Assert.True(installResult.StdOut.Contains(\"The feature [invalidFeature] was not found.\"));\r\n            Assert.True(installResult.StdOut.Contains(\"Failed to enable Windows Feature dependencies. To proceed with installation, use '--force'.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install a package with a Windows Feature dependency using the force argument.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallWithWindowsFeatureDependency_Force()\r\n        {\r\n            var testDir = TestCommon.GetRandomTestDir();\r\n            var installResult = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.WindowsFeature --silent --force -l {testDir}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, installResult.ExitCode);\r\n            Assert.True(installResult.StdOut.Contains(\"Failed to enable Windows Feature dependencies; proceeding due to --force\"));\r\n            Assert.True(installResult.StdOut.Contains(\"Successfully installed\"));\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(testDir));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install a package with a package dependency that requires the PATH environment variable to be refreshed between dependency installs.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallWithPackageDependency_RefreshPathVariable()\r\n        {\r\n            var testDir = TestCommon.GetRandomTestDir();\r\n            string installDir = TestCommon.GetPortablePackagesDirectory();\r\n            var installResult = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.PackageDependencyRequiresPathRefresh -l {testDir}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, installResult.ExitCode);\r\n            Assert.True(installResult.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            // Portable package is used as a dependency. Ensure that it is installed and cleaned up successfully.\r\n            string portablePackageId, commandAlias, fileName, packageDirName, productCode;\r\n            portablePackageId = \"AppInstallerTest.TestPortableExeWithCommand\";\r\n            packageDirName = productCode = portablePackageId + \"_\" + Constants.TestSourceIdentifier;\r\n            fileName = \"AppInstallerTestExeInstaller.exe\";\r\n            commandAlias = \"testCommand.exe\";\r\n\r\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true);\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(testDir));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install a package with a package dependency and specify dependencies only.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallWithPackageDependency_DependenciesOnly()\r\n        {\r\n            var testDir = TestCommon.GetRandomTestDir();\r\n            string installDir = TestCommon.GetPortablePackagesDirectory();\r\n            var installResult = TestCommon.RunAICLICommand(\"install\", $\"-q AppInstallerTest.PackageDependencyRequiresPathRefresh -l {testDir} --dependencies-only\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, installResult.ExitCode);\r\n            Assert.True(installResult.StdOut.Contains(\"Installing dependencies only. The package itself will not be installed.\"));\r\n            Assert.True(installResult.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            // Portable package is used as a dependency. Ensure that it is installed and cleaned up successfully.\r\n            string portablePackageId, commandAlias, fileName, packageDirName, productCode;\r\n            portablePackageId = \"AppInstallerTest.TestPortableExeWithCommand\";\r\n            packageDirName = productCode = portablePackageId + \"_\" + Constants.TestSourceIdentifier;\r\n            fileName = \"AppInstallerTestExeInstaller.exe\";\r\n            commandAlias = \"testCommand.exe\";\r\n\r\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true);\r\n            Assert.False(TestCommon.VerifyTestExeInstalledAndCleanup(testDir));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install a package using a specific installer type.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallWithInstallerTypeArgument()\r\n        {\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestMultipleInstallers --silent -l {installDir} --installer-type exe\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, \"/execustom\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install package with installer type preference settings.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallWithInstallerTypePreference()\r\n        {\r\n            string[] installerTypePreference = { \"nullsoft\" };\r\n            WinGetSettingsHelper.ConfigureInstallBehaviorPreferences(Constants.InstallerTypes, installerTypePreference);\r\n\r\n            string installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestMultipleInstallers --silent -l {installDir}\");\r\n\r\n            // Reset installer type preferences.\r\n            WinGetSettingsHelper.ConfigureInstallBehaviorPreferences(Constants.InstallerTypes, Array.Empty<string>());\r\n\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir), \"/S\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install package with installer type requirement settings.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallWithInstallerTypeRequirement()\r\n        {\r\n            string[] installerTypeRequirement = { \"inno\" };\r\n            WinGetSettingsHelper.ConfigureInstallBehaviorRequirements(Constants.InstallerTypes, installerTypeRequirement);\r\n\r\n            string installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestMultipleInstallers --silent -l {installDir}\");\r\n\r\n            // Reset installer type requirements.\r\n            WinGetSettingsHelper.ConfigureInstallBehaviorRequirements(Constants.InstallerTypes, Array.Empty<string>());\r\n\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICABLE_INSTALLER, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"No applicable installer found; see logs for more details.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// This test flow is intended to test an EXE that actually installs an MSIX internally, and whose name+publisher\r\n        /// information resembles an existing installation. Given this, the goal is to get correlation to stick to the\r\n        /// MSIX rather than the ARP entry that we would match with in the absence of the package family name being present.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallExeThatInstallsMSIX()\r\n        {\r\n            string targetPackageIdentifier = \"AppInstallerTest.TestExeInstallerInstallsMSIX\";\r\n            string fakeProductCode = \"e35f5799-cce3-41fd-886c-c36fcb7104fe\";\r\n\r\n            // Insert fake ARP entry as if a non-MSIX version of the package is already installed.\r\n            // The name here must not match the normalized name of the package, but be close enough to meet\r\n            // the confidence requirements for correlation after an install operation (so we drop one word here).\r\n            TestCommon.CreateARPEntry(fakeProductCode, new\r\n            {\r\n                DisplayName = \"EXE Installer that Installs MSIX\",\r\n                Publisher = \"AppInstallerTest\",\r\n                DisplayVersion = \"1.0.0\",\r\n            });\r\n\r\n            // We should not find it before installing because the normalized name doesn't match\r\n            var result = TestCommon.RunAICLICommand(\"list\", targetPackageIdentifier);\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode);\r\n\r\n            // Add the MSIX to simulate an installer doing it\r\n            TestCommon.InstallMsix(TestIndex.MsixInstaller);\r\n\r\n            // Install our exe that \"installs\" the MSIX\r\n            result = TestCommon.RunAICLICommand(\"install\", $\"{targetPackageIdentifier} --force\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n\r\n            // We should find the package now, and it should be correlated to the MSIX (although we don't actually know that from this probe)\r\n            result = TestCommon.RunAICLICommand(\"list\", targetPackageIdentifier);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n\r\n            // Remove the MSIX outside of winget's knowledge to keep the tracking data.\r\n            TestCommon.RemoveMsix(Constants.MsixInstallerName);\r\n\r\n            // We should not find the package now that the MSIX is gone, confirming that it was correlated\r\n            result = TestCommon.RunAICLICommand(\"list\", targetPackageIdentifier);\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode);\r\n\r\n            TestCommon.RemoveARPEntry(fakeProductCode);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install source priority.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallExeWithSourcePriority()\r\n        {\r\n            // This test source always returns a single package from search\r\n            TestCommon.RunAICLICommand(\"source add\", \"dummyPackage \\\"{ \\\"\\\"ContainsPackage\\\"\\\": true }\\\" Microsoft.Test.Configurable --header \\\"{}\\\"\");\r\n\r\n            try\r\n            {\r\n                // Attempt install with equal (default) priorities\r\n                var installDir = TestCommon.GetRandomTestDir();\r\n                var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestExeInstaller --silent -l {installDir}\");\r\n                Assert.AreEqual(Constants.ErrorCode.ERROR_MULTIPLE_APPLICATIONS_FOUND, result.ExitCode);\r\n                Assert.False(TestCommon.VerifyTestExeInstalledAndCleanup(installDir));\r\n\r\n                // Change the priority of the primary test source to be higher\r\n                TestCommon.RunAICLICommand(\"source edit\", $\"{Constants.TestSourceName} --priority 1\");\r\n\r\n                result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestExeInstaller --silent -l {installDir}\");\r\n                Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n                Assert.True(result.StdOut.Contains(\"AppInstallerTest.TestExeInstaller\"));\r\n                Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n                Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir));\r\n            }\r\n            finally\r\n            {\r\n                this.ResetTestSource();\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/Interop/BaseInterop.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"BaseInterop.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests.Interop\n{\n    using System.Collections.Generic;\n    using System.Linq;\n    using Microsoft.Management.Deployment;\n    using Microsoft.Management.Deployment.Projection;\n    using NUnit.Framework;\n\n    /// <summary>\r\n    /// Base interop class.\r\n    /// </summary>\n    public abstract class BaseInterop\n    {\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"BaseInterop\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"initializer\">Initializer.</param>\r\n        public BaseInterop(IInstanceInitializer initializer)\n        {\n            this.TestFactory = new (initializer);\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the test factory.\r\n        /// </summary>\n        public WinGetProjectionFactory TestFactory { get; }\r\n\r\n        /// <summary>\n        /// Find one filtered package from a provided package catalog reference.\n        /// </summary>\n        /// <param name=\"packageCatalogReference\">Package catalog reference.</param>\n        /// <param name=\"field\">Package match field.</param>\n        /// <param name=\"option\">Package field match option.</param>\n        /// <param name=\"value\">Package match value.</param>\n        /// <returns>List of matches.</returns>\n        public MatchResult FindOnePackage(\n            PackageCatalogReference packageCatalogReference,\n            PackageMatchField field,\n            PackageFieldMatchOption option,\n            string value)\n        {\n            var findPackages = this.FindAllPackages(packageCatalogReference, field, option, value);\n            Assert.AreEqual(1, findPackages.Count, $\"Expected exactly one package but found {findPackages.Count}\");\n            return findPackages.First();\n        }\n\n        /// <summary>\n        /// Find all filtered package from a provided package catalog reference.\n        /// </summary>\n        /// <param name=\"packageCatalogReference\">Package catalog reference.</param>\n        /// <param name=\"field\">Package match field.</param>\n        /// <param name=\"option\">Package field match option.</param>\n        /// <param name=\"value\">Package match value.</param>\n        /// <returns>List of matches.</returns>\n        protected IReadOnlyList<MatchResult> FindAllPackages(\n            PackageCatalogReference packageCatalogReference,\n            PackageMatchField field,\n            PackageFieldMatchOption option,\n            string value)\n        {\n            Assert.NotNull(packageCatalogReference, \"Package catalog reference cannot be null\");\n\n            // Prepare filter\n            var filter = this.TestFactory.CreatePackageMatchFilter();\n            filter.Field = field;\n            filter.Option = option;\n            filter.Value = value;\n\n            // Add filter\n            var findPackageOptions = this.TestFactory.CreateFindPackagesOptions();\n            findPackageOptions.Filters.Add(filter);\n\n            // Connect and find package\n            var source = packageCatalogReference.Connect().PackageCatalog;\n\n            return source.FindPackages(findPackageOptions).Matches;\n        }\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/Interop/CheckInstalledStatusInterop.cs",
    "content": "// -----------------------------------------------------------------------------\n// <copyright file=\"CheckInstalledStatusInterop.cs\" company=\"Microsoft Corporation\">\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\n// </copyright>\n// -----------------------------------------------------------------------------\n\nnamespace AppInstallerCLIE2ETests.Interop\n{\n    using System;\n    using System.IO;\n    using System.Threading.Tasks;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using Microsoft.Management.Deployment;\n    using Microsoft.Management.Deployment.Projection;\n    using NUnit.Framework;\n    using WinRT;\n\n    /// <summary>\n    /// Tests check installed status.\n    /// </summary>\n    [TestFixtureSource(typeof(InstanceInitializersSource), nameof(InstanceInitializersSource.InProcess), Category = nameof(InstanceInitializersSource.InProcess))]\n    [TestFixtureSource(typeof(InstanceInitializersSource), nameof(InstanceInitializersSource.OutOfProcess), Category = nameof(InstanceInitializersSource.OutOfProcess))]\n    public class CheckInstalledStatusInterop : BaseInterop\n    {\n        private string installDir;\n        private string defaultInstallDir = Path.Combine(Path.GetTempPath(), \"TestInstalledStatus\");\n        private PackageManager packageManager;\n        private PackageCatalogReference testSource;\n\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"CheckInstalledStatusInterop\"/> class.\n        /// </summary>\n        /// <param name=\"initializer\">Initializer.</param>\n        public CheckInstalledStatusInterop(IInstanceInitializer initializer)\n            : base(initializer)\n        {\n        }\n\n        /// <summary>\n        /// Test setup.\n        /// </summary>\n        [SetUp]\n        public void SetUp()\n        {\n            this.packageManager = this.TestFactory.CreatePackageManager();\n            this.testSource = this.packageManager.GetPackageCatalogByName(Constants.TestSourceName);\n            this.installDir = TestCommon.GetRandomTestDir();\n        }\n\n        /// <summary>\n        /// Clean up.\n        /// </summary>\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous operation.</returns>\n        [TearDown]\n        public async Task Cleanup()\n        {\n            // Find and uninstall the test package if applicable.\n            var options = this.TestFactory.CreateCreateCompositePackageCatalogOptions();\n            options.Catalogs.Add(this.testSource);\n            options.CompositeSearchBehavior = CompositeSearchBehavior.AllCatalogs;\n            var compositeSource = this.packageManager.CreateCompositePackageCatalog(options);\n            var searchResult = this.FindOnePackage(compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestCheckInstalledStatus\");\n            if (searchResult.CatalogPackage.InstalledVersion != null)\n            {\n                var uninstallOptions = this.TestFactory.CreateUninstallOptions();\n                var uninstallResult = await this.packageManager.UninstallPackageAsync(searchResult.CatalogPackage, uninstallOptions);\n                Assert.AreEqual(UninstallResultStatus.Ok, uninstallResult.Status);\n            }\n\n            // Remove default install location\n            if (Directory.Exists(this.defaultInstallDir))\n            {\n                Directory.Delete(this.defaultInstallDir, true);\n            }\n        }\n\n        /// <summary>\n        /// Tests arp entries match.\n        /// </summary>\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous operation.</returns>\n        [Test]\n        public async Task CheckInstalledStatusArpVersionMatched()\n        {\n            // Find and install the test package.\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestCheckInstalledStatus\");\n            var installOptions = this.TestFactory.CreateInstallOptions();\n            installOptions.ReplacementInstallerArguments = $\"/InstallDir {this.installDir} /ProductID CheckInstalledStatusProductId /DisplayName TestCheckInstalledStatus /Version 1.0\";\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\n\n            // Add the data file listed in the manifest\n            File.WriteAllText(Path.Combine(this.installDir, \"data.txt\"), \"Test\");\n\n            // Search from composite source again after installation\n            var options = this.TestFactory.CreateCreateCompositePackageCatalogOptions();\n            options.Catalogs.Add(this.testSource);\n            options.CompositeSearchBehavior = CompositeSearchBehavior.AllCatalogs;\n            var compositeSource = this.packageManager.CreateCompositePackageCatalog(options);\n            searchResult = this.FindOnePackage(compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestCheckInstalledStatus\");\n\n            // Check installed status\n            var checkResult = await searchResult.CatalogPackage.CheckInstalledStatusAsync();\n            Assert.AreEqual(CheckInstalledStatusResultStatus.Ok, checkResult.Status);\n            Assert.AreEqual(1, checkResult.PackageInstalledStatus.Count);\n\n            // Installer info\n            var installerInstalledStatus = checkResult.PackageInstalledStatus[0];\n            Assert.AreEqual(Windows.System.ProcessorArchitecture.Neutral, installerInstalledStatus.InstallerInfo.Architecture);\n            Assert.AreEqual(PackageInstallerType.Exe, installerInstalledStatus.InstallerInfo.InstallerType);\n            Assert.AreEqual(PackageInstallerType.Unknown, installerInstalledStatus.InstallerInfo.NestedInstallerType);\n            Assert.AreEqual(PackageInstallerScope.Unknown, installerInstalledStatus.InstallerInfo.Scope);\n\n            // Installer status\n            Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntry, installerInstalledStatus.InstallerInstalledStatus[0].Type);\n            Assert.AreEqual(Constants.ErrorCode.S_OK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[0]));\n            Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntryInstallLocation, installerInstalledStatus.InstallerInstalledStatus[1].Type);\n            Assert.AreEqual(this.installDir, installerInstalledStatus.InstallerInstalledStatus[1].Path);\n            Assert.AreEqual(Constants.ErrorCode.S_OK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[1]));\n            Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntryInstallLocationFile, installerInstalledStatus.InstallerInstalledStatus[2].Type);\n            Assert.AreEqual(Path.Combine(this.installDir, \"data.txt\"), installerInstalledStatus.InstallerInstalledStatus[2].Path);\n            Assert.AreEqual(Constants.ErrorCode.S_OK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[2]));\n            Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntryInstallLocationFile, installerInstalledStatus.InstallerInstalledStatus[3].Type);\n            Assert.AreEqual(Path.Combine(this.installDir, \"TestExeInstalled.txt\"), installerInstalledStatus.InstallerInstalledStatus[3].Path);\n            Assert.AreEqual(Constants.ErrorCode.INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[3]));\n            Assert.AreEqual(InstalledStatusType.DefaultInstallLocation, installerInstalledStatus.InstallerInstalledStatus[4].Type);\n            Assert.AreEqual(this.defaultInstallDir, Path.GetFullPath(installerInstalledStatus.InstallerInstalledStatus[4].Path));\n            Assert.AreEqual(Constants.ErrorCode.INSTALLED_STATUS_INSTALL_LOCATION_NOT_FOUND, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[4]));\n        }\n\n        /// <summary>\n        /// Test arp entries no version matched.\n        /// </summary>\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous operation.</returns>\n        [Test]\n        public async Task CheckInstalledStatusArpVersionNotMatched()\n        {\n            // Find and install the test package.\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestCheckInstalledStatus\");\n            var installOptions = this.TestFactory.CreateInstallOptions();\n            installOptions.ReplacementInstallerArguments = $\"/InstallDir {this.installDir} /ProductID CheckInstalledStatusProductId /DisplayName TestCheckInstalledStatus /Version 2.0\";\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\n\n            // Add the data file listed in the manifest\n            File.WriteAllText(Path.Combine(this.installDir, \"data.txt\"), \"Test\");\n\n            // Search from composite source again after installation\n            var options = this.TestFactory.CreateCreateCompositePackageCatalogOptions();\n            options.Catalogs.Add(this.testSource);\n            options.CompositeSearchBehavior = CompositeSearchBehavior.AllCatalogs;\n            var compositeSource = this.packageManager.CreateCompositePackageCatalog(options);\n            searchResult = this.FindOnePackage(compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestCheckInstalledStatus\");\n\n            // Check installed status\n            var checkResult = await searchResult.CatalogPackage.CheckInstalledStatusAsync(InstalledStatusType.AllAppsAndFeaturesEntryChecks);\n            Assert.AreEqual(CheckInstalledStatusResultStatus.Ok, checkResult.Status);\n            Assert.AreEqual(1, checkResult.PackageInstalledStatus.Count);\n\n            var installerInstalledStatus = checkResult.PackageInstalledStatus[0];\n            Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntry, installerInstalledStatus.InstallerInstalledStatus[0].Type);\n            Assert.AreEqual(Constants.ErrorCode.S_OK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[0]));\n            Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntryInstallLocation, installerInstalledStatus.InstallerInstalledStatus[1].Type);\n            Assert.AreEqual(this.installDir, installerInstalledStatus.InstallerInstalledStatus[1].Path);\n            Assert.AreEqual(Constants.ErrorCode.S_OK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[1]));\n            Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntryInstallLocationFile, installerInstalledStatus.InstallerInstalledStatus[2].Type);\n            Assert.AreEqual(Path.Combine(this.installDir, \"data.txt\"), installerInstalledStatus.InstallerInstalledStatus[2].Path);\n            Assert.AreEqual(Constants.ErrorCode.INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[2]));\n            Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntryInstallLocationFile, installerInstalledStatus.InstallerInstalledStatus[3].Type);\n            Assert.AreEqual(Path.Combine(this.installDir, \"TestExeInstalled.txt\"), installerInstalledStatus.InstallerInstalledStatus[3].Path);\n            Assert.AreEqual(Constants.ErrorCode.INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[3]));\n        }\n\n        /// <summary>\n        /// Test arp entries file not found.\n        /// </summary>\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous operation.</returns>\n        [Test]\n        public async Task CheckInstalledStatusArpVersionMatchedFileNotFound()\n        {\n            // Find and install the test package.\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestCheckInstalledStatus\");\n            var installOptions = this.TestFactory.CreateInstallOptions();\n            installOptions.ReplacementInstallerArguments = $\"/InstallDir {this.installDir} /ProductID CheckInstalledStatusProductId /DisplayName TestCheckInstalledStatus /Version 1.0\";\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\n\n            // Search from composite source again after installation\n            var options = this.TestFactory.CreateCreateCompositePackageCatalogOptions();\n            options.Catalogs.Add(this.testSource);\n            options.CompositeSearchBehavior = CompositeSearchBehavior.AllCatalogs;\n            var compositeSource = this.packageManager.CreateCompositePackageCatalog(options);\n            searchResult = this.FindOnePackage(compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestCheckInstalledStatus\");\n\n            // Check installed status\n            var checkResult = await searchResult.CatalogPackage.CheckInstalledStatusAsync(InstalledStatusType.AllAppsAndFeaturesEntryChecks);\n            Assert.AreEqual(CheckInstalledStatusResultStatus.Ok, checkResult.Status);\n            Assert.AreEqual(1, checkResult.PackageInstalledStatus.Count);\n\n            var installerInstalledStatus = checkResult.PackageInstalledStatus[0];\n            Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntry, installerInstalledStatus.InstallerInstalledStatus[0].Type);\n            Assert.AreEqual(Constants.ErrorCode.S_OK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[0]));\n            Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntryInstallLocation, installerInstalledStatus.InstallerInstalledStatus[1].Type);\n            Assert.AreEqual(this.installDir, installerInstalledStatus.InstallerInstalledStatus[1].Path);\n            Assert.AreEqual(Constants.ErrorCode.S_OK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[1]));\n            Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntryInstallLocationFile, installerInstalledStatus.InstallerInstalledStatus[2].Type);\n            Assert.AreEqual(Path.Combine(this.installDir, \"data.txt\"), installerInstalledStatus.InstallerInstalledStatus[2].Path);\n            Assert.AreEqual(Constants.ErrorCode.INSTALLED_STATUS_FILE_NOT_FOUND, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[2]));\n            Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntryInstallLocationFile, installerInstalledStatus.InstallerInstalledStatus[3].Type);\n            Assert.AreEqual(Path.Combine(this.installDir, \"TestExeInstalled.txt\"), installerInstalledStatus.InstallerInstalledStatus[3].Path);\n            Assert.AreEqual(Constants.ErrorCode.INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[3]));\n        }\n\n        /// <summary>\n        /// Test arp entries hash mismatch.\n        /// </summary>\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous operation.</returns>\n        [Test]\n        public async Task CheckInstalledStatusArpVersionMatchedFileHashMisMatch()\n        {\n            // Find and install the test package.\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestCheckInstalledStatus\");\n            var installOptions = this.TestFactory.CreateInstallOptions();\n            installOptions.ReplacementInstallerArguments = $\"/InstallDir {this.installDir} /ProductID CheckInstalledStatusProductId /DisplayName TestCheckInstalledStatus /Version 1.0\";\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\n\n            // Add the data file listed in the manifest\n            File.WriteAllText(Path.Combine(this.installDir, \"data.txt\"), \"WrongData\");\n\n            // Search from composite source again after installation\n            var options = this.TestFactory.CreateCreateCompositePackageCatalogOptions();\n            options.Catalogs.Add(this.testSource);\n            options.CompositeSearchBehavior = CompositeSearchBehavior.AllCatalogs;\n            var compositeSource = this.packageManager.CreateCompositePackageCatalog(options);\n            searchResult = this.FindOnePackage(compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestCheckInstalledStatus\");\n\n            // Check installed status\n            var checkResult = await searchResult.CatalogPackage.CheckInstalledStatusAsync(InstalledStatusType.AllAppsAndFeaturesEntryChecks);\n            Assert.AreEqual(CheckInstalledStatusResultStatus.Ok, checkResult.Status);\n            Assert.AreEqual(1, checkResult.PackageInstalledStatus.Count);\n\n            var installerInstalledStatus = checkResult.PackageInstalledStatus[0];\n            Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntry, installerInstalledStatus.InstallerInstalledStatus[0].Type);\n            Assert.AreEqual(Constants.ErrorCode.S_OK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[0]));\n            Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntryInstallLocation, installerInstalledStatus.InstallerInstalledStatus[1].Type);\n            Assert.AreEqual(this.installDir, installerInstalledStatus.InstallerInstalledStatus[1].Path);\n            Assert.AreEqual(Constants.ErrorCode.S_OK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[1]));\n            Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntryInstallLocationFile, installerInstalledStatus.InstallerInstalledStatus[2].Type);\n            Assert.AreEqual(Path.Combine(this.installDir, \"data.txt\"), installerInstalledStatus.InstallerInstalledStatus[2].Path);\n            Assert.AreEqual(Constants.ErrorCode.INSTALLED_STATUS_FILE_HASH_MISMATCH, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[2]));\n            Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntryInstallLocationFile, installerInstalledStatus.InstallerInstalledStatus[3].Type);\n            Assert.AreEqual(Path.Combine(this.installDir, \"TestExeInstalled.txt\"), installerInstalledStatus.InstallerInstalledStatus[3].Path);\n            Assert.AreEqual(Constants.ErrorCode.INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[3]));\n        }\n\n        /// <summary>\n        /// Test arp entries default install location not found.\n        /// </summary>\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous operation.</returns>\n        [Test]\n        public async Task CheckInstalledStatusArpNotFoundDefaultInstallLocationFound()\n        {\n            // Add the data file listed in the manifest to default install location.\n            Directory.CreateDirectory(this.defaultInstallDir);\n            File.WriteAllText(Path.Combine(this.defaultInstallDir, \"data.txt\"), \"Test\");\n\n            // Search from composite source without installation\n            var options = this.TestFactory.CreateCreateCompositePackageCatalogOptions();\n            options.Catalogs.Add(this.testSource);\n            options.CompositeSearchBehavior = CompositeSearchBehavior.AllCatalogs;\n            var compositeSource = this.packageManager.CreateCompositePackageCatalog(options);\n            var searchResult = this.FindOnePackage(compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestCheckInstalledStatus\");\n\n            // Check installed status\n            var checkResult = await searchResult.CatalogPackage.CheckInstalledStatusAsync();\n            Assert.AreEqual(CheckInstalledStatusResultStatus.Ok, checkResult.Status);\n            Assert.AreEqual(1, checkResult.PackageInstalledStatus.Count);\n\n            var installerInstalledStatus = checkResult.PackageInstalledStatus[0];\n            Assert.AreEqual(InstalledStatusType.AppsAndFeaturesEntry, installerInstalledStatus.InstallerInstalledStatus[0].Type);\n            Assert.AreEqual(Constants.ErrorCode.INSTALLED_STATUS_ARP_ENTRY_NOT_FOUND, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[0]));\n            Assert.AreEqual(InstalledStatusType.DefaultInstallLocation, installerInstalledStatus.InstallerInstalledStatus[1].Type);\n            Assert.AreEqual(this.defaultInstallDir, Path.GetFullPath(installerInstalledStatus.InstallerInstalledStatus[1].Path));\n            Assert.AreEqual(Constants.ErrorCode.S_OK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[1]));\n            Assert.AreEqual(InstalledStatusType.DefaultInstallLocationFile, installerInstalledStatus.InstallerInstalledStatus[2].Type);\n            Assert.AreEqual(Path.Combine(this.defaultInstallDir, \"data.txt\"), Path.GetFullPath(installerInstalledStatus.InstallerInstalledStatus[2].Path));\n            Assert.AreEqual(Constants.ErrorCode.INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[2]));\n            Assert.AreEqual(InstalledStatusType.DefaultInstallLocationFile, installerInstalledStatus.InstallerInstalledStatus[3].Type);\n            Assert.AreEqual(Path.Combine(this.defaultInstallDir, \"TestExeInstalled.txt\"), Path.GetFullPath(installerInstalledStatus.InstallerInstalledStatus[3].Path));\n            Assert.AreEqual(Constants.ErrorCode.INSTALLED_STATUS_FILE_NOT_FOUND, GetHResultFromInstalledStatus(installerInstalledStatus.InstallerInstalledStatus[3]));\n        }\n\n        // CsWinrt maps success error codes(e.g. INSTALLED_STATUS_INSTALL_LOCATION_NOT_APPLICABLE) to null exception.\n        // In this case we cannot get the exact hresult by calling winrt projection api.\n        // This method is created to directly get hresult from the InstalledStatus object for the tests to compare.\n        private static unsafe int GetHResultFromInstalledStatus(InstalledStatus status)\n        {\n            if (status.Status != null)\n            {\n                return status.Status.HResult;\n            }\n            else\n            {\n                IObjectReference objRef = ((IWinRTObject)status).NativeObject;\n                ABI.System.Exception exception = default;\n                (*(delegate* unmanaged[Stdcall] <IntPtr, out global::ABI.System.Exception, int>**)objRef.ThisPtr)[8](objRef.ThisPtr, out exception);\n                return exception.hr;\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/Interop/DownloadInterop.cs",
    "content": "// -----------------------------------------------------------------------------\n// <copyright file=\"DownloadInterop.cs\" company=\"Microsoft Corporation\">\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\n// </copyright>\n// -----------------------------------------------------------------------------\n\nnamespace AppInstallerCLIE2ETests.Interop\n{\n    using System;\n    using System.IO;\n    using System.Threading.Tasks;\n    using AppInstallerCLIE2ETests.Helpers;\n    using Microsoft.Management.Deployment;\n    using Microsoft.Management.Deployment.Projection;\n    using NUnit.Framework;\n    using Windows.System;\n\n    /// <summary>\n    /// Download interop.\n    /// </summary>\n    [TestFixtureSource(typeof(InstanceInitializersSource), nameof(InstanceInitializersSource.InProcess), Category = nameof(InstanceInitializersSource.InProcess))]\n    [TestFixtureSource(typeof(InstanceInitializersSource), nameof(InstanceInitializersSource.OutOfProcess), Category = nameof(InstanceInitializersSource.OutOfProcess))]\n    public class DownloadInterop : BaseInterop\n    {\n        private PackageManager packageManager;\n        private PackageCatalogReference testSource;\n\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"DownloadInterop\"/> class.\n        /// </summary>\n        /// <param name=\"initializer\">Initializer.</param>\n        public DownloadInterop(IInstanceInitializer initializer)\n            : base(initializer)\n        {\n        }\n\n        /// <summary>\n        /// Set up.\n        /// </summary>\n        [SetUp]\n        public void SetUp()\n        {\n            this.packageManager = this.TestFactory.CreatePackageManager();\n            this.testSource = this.packageManager.GetPackageCatalogByName(Constants.TestSourceName);\n        }\n\n        /// <summary>\n        /// Downloads the test installer and its package dependencies.\n        /// </summary>\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\n        [Test]\n        public async Task DownloadDependencies()\n        {\n            // Find package\n            var downloadDir = TestCommon.GetRandomTestDir();\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.PackageDependency\");\n\n            // Configure installation\n            var downloadOptions = this.TestFactory.CreateDownloadOptions();\n            downloadOptions.AcceptPackageAgreements = true;\n            downloadOptions.DownloadDirectory = downloadDir;\n\n            // Download\n            var downloadResult = await this.packageManager.DownloadPackageAsync(searchResult.CatalogPackage, downloadOptions);\n\n            // Assert\n            Assert.AreEqual(DownloadResultStatus.Ok, downloadResult.Status);\n            var dependenciesDir = Path.Combine(downloadDir, Constants.Dependencies);\n            TestCommon.AssertInstallerDownload(dependenciesDir, \"TestPortableExe\", \"3.0.0.0\", ProcessorArchitecture.X64, TestCommon.Scope.Unknown, PackageInstallerType.Portable, \"en-US\");\n            TestCommon.AssertInstallerDownload(downloadDir, \"TestPackageDependency\", \"1.0.0.0\", ProcessorArchitecture.X64, TestCommon.Scope.Unknown, PackageInstallerType.Exe, \"en-US\");\n        }\n\n        /// <summary>\n        /// Downloads the test installer and skips dependencies.\n        /// </summary>\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\n        [Test]\n        public async Task DownloadDependencies_Skip()\n        {\n            // Find package\n            var downloadDir = TestCommon.GetRandomTestDir();\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.PackageDependency\");\n\n            // Configure installation\n            var downloadOptions = this.TestFactory.CreateDownloadOptions();\n            downloadOptions.AcceptPackageAgreements = true;\n            downloadOptions.DownloadDirectory = downloadDir;\n            downloadOptions.SkipDependencies = true;\n\n            // Download\n            var downloadResult = await this.packageManager.DownloadPackageAsync(searchResult.CatalogPackage, downloadOptions);\n\n            // Assert\n            Assert.AreEqual(DownloadResultStatus.Ok, downloadResult.Status);\n            var dependenciesDir = Path.Combine(downloadDir, Constants.Dependencies);\n            Assert.IsFalse(Directory.Exists(dependenciesDir));\n            TestCommon.AssertInstallerDownload(downloadDir, \"TestPackageDependency\", \"1.0.0.0\", ProcessorArchitecture.X64, TestCommon.Scope.Unknown, PackageInstallerType.Exe, \"en-US\");\n        }\n\n        /// <summary>\n        /// Download the installer to the default directory.\n        /// </summary>\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\n        [Test]\n        public async Task DownloadToDefaultDirectory()\n        {\n            // Find package\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestExeInstaller\");\n\n            // Configure installation\n            var downloadOptions = this.TestFactory.CreateDownloadOptions();\n            downloadOptions.AcceptPackageAgreements = true;\n\n            // Download\n            var downloadResult = await this.packageManager.DownloadPackageAsync(searchResult.CatalogPackage, downloadOptions);\n\n            // Assert\n            var packageVersion = \"2.0.0.0\";\n            Assert.AreEqual(DownloadResultStatus.Ok, downloadResult.Status);\n            string downloadDir = Path.Combine(TestCommon.GetDefaultDownloadDirectory(), $\"{Constants.ExeInstallerPackageId}_{packageVersion}\");\n            TestCommon.AssertInstallerDownload(downloadDir, \"TestExeInstaller\", packageVersion, ProcessorArchitecture.X86, TestCommon.Scope.User, PackageInstallerType.Exe);\n        }\n\n        /// <summary>\n        /// Download the installer to a specified directory.\n        /// </summary>\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\n        [Test]\n        public async Task DownloadToDirectory()\n        {\n            // Find package\n            var downloadDir = TestCommon.GetRandomTestDir();\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestExeInstaller\");\n\n            // Configure installation\n            var downloadOptions = this.TestFactory.CreateDownloadOptions();\n            downloadOptions.AcceptPackageAgreements = true;\n            downloadOptions.DownloadDirectory = downloadDir;\n\n            // Download\n            var downloadResult = await this.packageManager.DownloadPackageAsync(searchResult.CatalogPackage, downloadOptions);\n\n            // Assert\n            Assert.AreEqual(DownloadResultStatus.Ok, downloadResult.Status);\n            TestCommon.AssertInstallerDownload(downloadDir, \"TestExeInstaller\", \"2.0.0.0\", ProcessorArchitecture.X86, TestCommon.Scope.User, PackageInstallerType.Exe);\n        }\n\n        /// <summary>\n        /// Download the installer using the user scope argument.\n        /// </summary>\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\n        [Test]\n        public async Task DownloadWithUserScope()\n        {\n            // Find package\n            var downloadDir = TestCommon.GetRandomTestDir();\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestMultipleInstallers\");\n\n            // Configure installation\n            var downloadOptions = this.TestFactory.CreateDownloadOptions();\n            downloadOptions.AcceptPackageAgreements = true;\n            downloadOptions.DownloadDirectory = downloadDir;\n            downloadOptions.Scope = PackageInstallScope.User;\n\n            // Download\n            var downloadResult = await this.packageManager.DownloadPackageAsync(searchResult.CatalogPackage, downloadOptions);\n\n            // Assert\n            Assert.AreEqual(DownloadResultStatus.Ok, downloadResult.Status);\n            TestCommon.AssertInstallerDownload(downloadDir, \"TestMultipleInstallers\", \"1.0.0.0\", ProcessorArchitecture.X64, TestCommon.Scope.User, PackageInstallerType.Nullsoft, \"en-US\");\n        }\n\n        /// <summary>\n        /// Download the installer using the machine scope argument.\n        /// </summary>\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\n        [Test]\n        public async Task DownloadWithMachineScope()\n        {\n            // Find package\n            var downloadDir = TestCommon.GetRandomTestDir();\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestMultipleInstallers\");\n\n            // Configure installation\n            var downloadOptions = this.TestFactory.CreateDownloadOptions();\n            downloadOptions.AcceptPackageAgreements = true;\n            downloadOptions.DownloadDirectory = downloadDir;\n            downloadOptions.Scope = PackageInstallScope.System;\n\n            // Download\n            var downloadResult = await this.packageManager.DownloadPackageAsync(searchResult.CatalogPackage, downloadOptions);\n\n            // Assert\n            Assert.AreEqual(DownloadResultStatus.Ok, downloadResult.Status);\n            TestCommon.AssertInstallerDownload(downloadDir, \"TestMultipleInstallers\", \"1.0.0.0\", ProcessorArchitecture.X86, TestCommon.Scope.Machine, PackageInstallerType.Msi, \"en-US\");\n        }\n\n        /// <summary>\n        /// Download the test installer using the 'zip' installer type argument.\n        /// </summary>\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\n        [Test]\n        public async Task DownloadWithZipInstallerTypeArg()\n        {\n            // Find package\n            var downloadDir = TestCommon.GetRandomTestDir();\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestMultipleInstallers\");\n\n            // Configure installation\n            var downloadOptions = this.TestFactory.CreateDownloadOptions();\n            downloadOptions.AcceptPackageAgreements = true;\n            downloadOptions.DownloadDirectory = downloadDir;\n            downloadOptions.InstallerType = PackageInstallerType.Zip;\n\n            // Download\n            var downloadResult = await this.packageManager.DownloadPackageAsync(searchResult.CatalogPackage, downloadOptions);\n\n            // Assert\n            Assert.AreEqual(DownloadResultStatus.Ok, downloadResult.Status);\n            TestCommon.AssertInstallerDownload(downloadDir, \"TestMultipleInstallers\", \"1.0.0.0\", ProcessorArchitecture.X64, TestCommon.Scope.Unknown, PackageInstallerType.Exe, \"zh-CN\", true);\n        }\n\n        /// <summary>\n        /// Downloads the test installer using the installer type argument.\n        /// </summary>\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\n        [Test]\n        public async Task DownloadWithInstallerTypeArg()\n        {\n            // Find package\n            var downloadDir = TestCommon.GetRandomTestDir();\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestMultipleInstallers\");\n\n            // Configure installation\n            var downloadOptions = this.TestFactory.CreateDownloadOptions();\n            downloadOptions.AcceptPackageAgreements = true;\n            downloadOptions.DownloadDirectory = downloadDir;\n            downloadOptions.InstallerType = PackageInstallerType.Msi;\n\n            // Download\n            var downloadResult = await this.packageManager.DownloadPackageAsync(searchResult.CatalogPackage, downloadOptions);\n\n            // Assert\n            Assert.AreEqual(DownloadResultStatus.Ok, downloadResult.Status);\n            TestCommon.AssertInstallerDownload(downloadDir, \"TestMultipleInstallers\", \"1.0.0.0\", ProcessorArchitecture.X86, TestCommon.Scope.Machine, PackageInstallerType.Msi, \"en-US\");\n        }\n\n        /// <summary>\n        /// Downloads the test installer using the architecture argument.\n        /// </summary>\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\n        [Test]\n        public async Task DownloadWithArchitectureArg()\n        {\n            // Find package\n            var downloadDir = TestCommon.GetRandomTestDir();\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestMultipleInstallers\");\n\n            // Configure installation\n            var downloadOptions = this.TestFactory.CreateDownloadOptions();\n            downloadOptions.AcceptPackageAgreements = true;\n            downloadOptions.DownloadDirectory = downloadDir;\n            downloadOptions.Architecture = ProcessorArchitecture.X86;\n\n            // Download\n            var downloadResult = await this.packageManager.DownloadPackageAsync(searchResult.CatalogPackage, downloadOptions);\n\n            // Assert\n            Assert.AreEqual(DownloadResultStatus.Ok, downloadResult.Status);\n            TestCommon.AssertInstallerDownload(downloadDir, \"TestMultipleInstallers\", \"1.0.0.0\", ProcessorArchitecture.X86, TestCommon.Scope.Machine, PackageInstallerType.Msi, \"en-US\");\n        }\n\n        /// <summary>\n        /// Downloads the test installer using the locale argument.\n        /// </summary>\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\n        [Test]\n        public async Task DownloadWithLocaleArg()\n        {\n            // Find package\n            var downloadDir = TestCommon.GetRandomTestDir();\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestMultipleInstallers\");\n\n            // Configure installation\n            var downloadOptions = this.TestFactory.CreateDownloadOptions();\n            downloadOptions.AcceptPackageAgreements = true;\n            downloadOptions.DownloadDirectory = downloadDir;\n            downloadOptions.Locale = \"zh-CN\";\n\n            // Download\n            var downloadResult = await this.packageManager.DownloadPackageAsync(searchResult.CatalogPackage, downloadOptions);\n\n            // Assert\n            Assert.AreEqual(DownloadResultStatus.Ok, downloadResult.Status);\n            TestCommon.AssertInstallerDownload(downloadDir, \"TestMultipleInstallers\", \"1.0.0.0\", ProcessorArchitecture.X64, TestCommon.Scope.Unknown, PackageInstallerType.Exe, \"zh-CN\", true);\n        }\n\n        /// <summary>\n        /// Downloads the test installer with a hash mismatch.\n        /// </summary>\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\n        [Test]\n        public async Task DownloadWithHashMismatch()\n        {\n            // Find package\n            var downloadDir = TestCommon.GetRandomTestDir();\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestExeSha256Mismatch\");\n\n            // Configure installation\n            var downloadOptions = this.TestFactory.CreateDownloadOptions();\n            downloadOptions.AcceptPackageAgreements = true;\n            downloadOptions.DownloadDirectory = downloadDir;\n\n            // Download\n            var downloadResult = await this.packageManager.DownloadPackageAsync(searchResult.CatalogPackage, downloadOptions);\n\n            // Assert\n            Assert.AreEqual(DownloadResultStatus.DownloadError, downloadResult.Status);\n        }\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/Interop/FindPackagesInterop.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"FindPackagesInterop.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests.Interop\n{\r\n    using System;\r\n    using Microsoft.Management.Deployment;\n    using Microsoft.Management.Deployment.Projection;\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// Test find package interop.\r\n    /// </summary>\n    [TestFixtureSource(typeof(InstanceInitializersSource), nameof(InstanceInitializersSource.InProcess), Category = nameof(InstanceInitializersSource.InProcess))]\n    [TestFixtureSource(typeof(InstanceInitializersSource), nameof(InstanceInitializersSource.OutOfProcess), Category = nameof(InstanceInitializersSource.OutOfProcess))]\n    public class FindPackagesInterop : BaseInterop\n    {\n        private PackageManager packageManager;\n        private PackageCatalogReference testSource;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"FindPackagesInterop\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"initializer\">Initializer.</param>\r\n        public FindPackagesInterop(IInstanceInitializer initializer)\n            : base(initializer)\n        {\n        }\n\n        /// <summary>\r\n        /// Set up.\r\n        /// </summary>\n        [SetUp]\n        public void SetUp()\n        {\n            this.packageManager = this.TestFactory.CreatePackageManager();\n            this.testSource = this.packageManager.GetPackageCatalogByName(Constants.TestSourceName);\n        }\n\n        /// <summary>\r\n        /// Test find package. no package.\r\n        /// </summary>\n        [Test]\n        public void FindPackageDoesNotExist()\n        {\n            // Find package\n            var searchResult = this.FindAllPackages(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"DoesNotExist\");\n\n            // Assert\n            Assert.AreEqual(0, searchResult.Count);\n        }\n\n        /// <summary>\r\n        /// Test find package with multiple match.\r\n        /// </summary>\n        [Test]\n        public void FindPackagesMultipleMatchingQuery()\n        {\n            // Find package\n            var searchResult = this.FindAllPackages(this.testSource, PackageMatchField.Name, PackageFieldMatchOption.Equals, \"TestExeInstaller\");\n\n            // Assert\n            Assert.AreEqual(2, searchResult.Count);\n        }\n\n        /// <summary>\r\n        /// Test to find a package and verify the CatalogPackageMetadata COM output.\r\n        /// </summary>\n        [Test]\n        public void FindPackagesVerifyDefaultLocaleFields()\r\n        {\r\n            var searchResult = this.FindAllPackages(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.CatalogPackageMetadata\");\r\n\n            Assert.AreEqual(1, searchResult.Count);\n\n            var catalogPackage = searchResult[0].CatalogPackage;\n            var packageVersionId = catalogPackage.AvailableVersions[0];\n            var packageVersionInfo = catalogPackage.GetPackageVersionInfo(packageVersionId);\n            var catalogPackageMetadata = packageVersionInfo.GetCatalogPackageMetadata();\n\n            Assert.AreEqual(\"testAuthor\", catalogPackageMetadata.Author);\n            Assert.AreEqual(\"AppInstallerTest\", catalogPackageMetadata.Publisher);\n            Assert.AreEqual(\"https://testPublisherUrl.com\", catalogPackageMetadata.PublisherUrl);\n            Assert.AreEqual(\"https://testPublisherSupportUrl.com\", catalogPackageMetadata.PublisherSupportUrl);\n            Assert.AreEqual(\"https://testPrivacyUrl.com\", catalogPackageMetadata.PrivacyUrl);\n\n            Assert.AreEqual(\"https://testPackageUrl.com\", catalogPackageMetadata.PackageUrl);\n            Assert.AreEqual(\"testLicense\", catalogPackageMetadata.License);\n            Assert.AreEqual(\"https://testLicenseUrl.com\", catalogPackageMetadata.LicenseUrl);\n            Assert.AreEqual(\"testCopyright\", catalogPackageMetadata.Copyright);\n            Assert.AreEqual(\"https://testCopyrightUrl.com\", catalogPackageMetadata.CopyrightUrl);\n            Assert.AreEqual(\"testDescription\", catalogPackageMetadata.Description);\n            Assert.AreEqual(\"testShortDescription\", catalogPackageMetadata.ShortDescription);\n            Assert.AreEqual(\"https://testPurchaseUrl.com\", catalogPackageMetadata.PurchaseUrl);\n\n            var tags = catalogPackageMetadata.Tags;\n            Assert.AreEqual(2, tags.Count);\n            Assert.AreEqual(\"tag1\", tags[0]);\n            Assert.AreEqual(\"tag2\", tags[1]);\n            Assert.AreEqual(\"testReleaseNotes\", catalogPackageMetadata.ReleaseNotes);\n            Assert.AreEqual(\"https://testReleaseNotes.net\", catalogPackageMetadata.ReleaseNotesUrl);\n            Assert.AreEqual(\"testInstallationNotes\", catalogPackageMetadata.InstallationNotes);\n\n            var packageAgreements = catalogPackageMetadata.Agreements;\n            Assert.AreEqual(1, packageAgreements.Count);\n\n            var agreement = packageAgreements[0];\n            Assert.AreEqual(\"testAgreementLabel\", agreement.Label);\n            Assert.AreEqual(\"testAgreementText\", agreement.Text);\n            Assert.AreEqual(\"https://testAgreementUrl.net\", agreement.Url);\r\n\r\n            var documentations = catalogPackageMetadata.Documentations;\r\n            Assert.AreEqual(1, documentations.Count);\r\n\r\n            var documentation = documentations[0];\r\n            Assert.AreEqual(\"testDocumentLabel\", documentation.DocumentLabel);\r\n            Assert.AreEqual(\"https://testDocumentUrl.com\", documentation.DocumentUrl);\r\n\r\n            var icons = catalogPackageMetadata.Icons;\r\n            Assert.AreEqual(1, icons.Count);\r\n\r\n            var icon = icons[0];\r\n            Assert.AreEqual(\"https://testIcon\", icon.Url);\r\n            Assert.AreEqual(IconFileType.Ico, icon.FileType);\r\n            Assert.AreEqual(IconTheme.Default, icon.Theme);\r\n            Assert.AreEqual(IconResolution.Custom, icon.Resolution);\r\n            Assert.AreEqual(Convert.FromHexString(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\"), icon.Sha256);\r\n        }\n\n        /// <summary>\r\n        /// Verifies that an exception is thrown if the provided locale string is invalid.\r\n        /// </summary>\n        [Test]\r\n        public void FindPackagesInvalidLocale()\r\n        {\r\n            var searchResult = this.FindAllPackages(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.CatalogPackageMetadata\");\r\n            var catalogPackage = searchResult[0].CatalogPackage;\r\n            var packageVersionId = catalogPackage.AvailableVersions[0];\r\n            var packageVersionInfo = catalogPackage.GetPackageVersionInfo(packageVersionId);\n            Assert.Throws<System.ArgumentException>(() => packageVersionInfo.GetCatalogPackageMetadata(\"badLocale\"));\r\n        }\n\n        /// <summary>\r\n        /// Verifies that the correct CatalogPackageMetadata is exposed when specifying a locale.\r\n        /// </summary>\n        [Test]\n        public void FindPackagesGetCatalogPackageMetadataLocale()\r\n        {\r\n            var searchResult = this.FindAllPackages(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.MultipleLocale\");\r\n            Assert.AreEqual(1, searchResult.Count);\n\r\n            var catalogPackage = searchResult[0].CatalogPackage;\r\n            var packageVersionId = catalogPackage.AvailableVersions[0];\n            var packageVersionInfo = catalogPackage.GetPackageVersionInfo(packageVersionId);\n            var catalogPackageMetadata = packageVersionInfo.GetCatalogPackageMetadata(\"zh-CN\");\r\n\r\n            Assert.AreEqual(\"zh-CN\", catalogPackageMetadata.Locale);\r\n            Assert.AreEqual(\"localeLicense\", catalogPackageMetadata.License);\r\n            Assert.AreEqual(\"localePackageName\", catalogPackageMetadata.PackageName);\r\n            Assert.AreEqual(\"localePublisher\", catalogPackageMetadata.Publisher);\r\n            Assert.AreEqual(\"localeReleaseNotes\", catalogPackageMetadata.ReleaseNotes);\r\n            Assert.AreEqual(\"https://localeReleaseNotesUrl.com\", catalogPackageMetadata.ReleaseNotesUrl);\r\n            Assert.AreEqual(\"https://localePurchaseUrl.com\", catalogPackageMetadata.PurchaseUrl);\r\n\r\n            var tags = catalogPackageMetadata.Tags;\n            Assert.AreEqual(2, tags.Count);\n            Assert.AreEqual(\"tag1\", tags[0]);\n            Assert.AreEqual(\"tag2\", tags[1]);\r\n\r\n            var packageAgreements = catalogPackageMetadata.Agreements;\n            Assert.AreEqual(1, packageAgreements.Count);\n\n            var agreement = packageAgreements[0];\n            Assert.AreEqual(\"localeAgreementLabel\", agreement.Label);\n            Assert.AreEqual(\"localeAgreement\", agreement.Text);\n            Assert.AreEqual(\"https://localeAgreementUrl.net\", agreement.Url);\r\n\r\n            var documentations = catalogPackageMetadata.Documentations;\r\n            Assert.AreEqual(1, documentations.Count);\r\n\r\n            var documentation = documentations[0];\r\n            Assert.AreEqual(\"localeDocumentLabel\", documentation.DocumentLabel);\r\n            Assert.AreEqual(\"https://localeDocumentUrl.com\", documentation.DocumentUrl);\r\n\r\n            var icons = catalogPackageMetadata.Icons;\r\n            Assert.AreEqual(1, icons.Count);\r\n\r\n            var icon = icons[0];\r\n            Assert.AreEqual(\"https://localeTestIcon\", icon.Url);\r\n            Assert.AreEqual(IconFileType.Png, icon.FileType);\r\n            Assert.AreEqual(IconTheme.Light, icon.Theme);\r\n            Assert.AreEqual(IconResolution.Square32, icon.Resolution);\r\n            Assert.AreEqual(Convert.FromHexString(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321\"), icon.Sha256);\r\n        }\n\n        /// <summary>\r\n        /// Verifies that GetCatalogPackageMetadata returns the correct metadata based on the specified locale.\r\n        /// </summary>\n        [Test]\n        public void FindPackagesGetAllCatalogPackageMetadata()\r\n        {\r\n            var searchResult = this.FindAllPackages(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.MultipleLocale\");\r\n            Assert.AreEqual(1, searchResult.Count);\n\r\n            var catalogPackage = searchResult[0].CatalogPackage;\r\n            var packageVersionId = catalogPackage.AvailableVersions[0];\n            var packageVersionInfo = catalogPackage.GetPackageVersionInfo(packageVersionId);\n\n            var catalogPackageMetadata1 = packageVersionInfo.GetCatalogPackageMetadata(\"zh-CN\");\n            Assert.AreEqual(\"zh-CN\", catalogPackageMetadata1.Locale);\n\n            var catalogPackageMetadata2 = packageVersionInfo.GetCatalogPackageMetadata(\"en-GB\");\n            Assert.AreEqual(\"en-GB\", catalogPackageMetadata2.Locale);\r\n            Assert.AreEqual(\"packageNameUK\", catalogPackageMetadata2.PackageName);\r\n        }\n\n        /// <summary>\r\n        /// Verifies that GetCatalogPackageMetadata returns the correct metadata based on the specified locale.\r\n        /// </summary>\n        [Test]\n        public void FindPackagesGetVersionMetadata()\r\n        {\r\n            var searchResult = this.FindAllPackages(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.MultipleLocale\");\r\n            Assert.AreEqual(1, searchResult.Count);\n\r\n            var catalogPackage = searchResult[0].CatalogPackage;\r\n            var packageVersionId = catalogPackage.AvailableVersions[0];\n            var packageVersionInfo = catalogPackage.GetPackageVersionInfo(packageVersionId);\n\n            string metadata = packageVersionInfo.GetMetadata(PackageVersionMetadataField.SilentUninstallCommand);\r\n            Assert.IsEmpty(metadata);\r\n        }\n    }\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/Interop/GroupPolicyForInterop.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"GroupPolicyForInterop.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests.Interop\r\n{\r\n    using System;\r\n    using System.IO;\r\n    using System.Text;\r\n    using System.Threading;\r\n    using System.Threading.Tasks;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.Management.Deployment.Projection;\r\n    using Microsoft.WinGet.SharedLib.Exceptions;\r\n    using NUnit.Framework;\r\n    using Windows.System;\r\n\r\n    /// <summary>\r\n    /// Group Policy Tests for COM/WinRT Interop classes.\r\n    /// </summary>\r\n    [TestFixtureSource(typeof(InstanceInitializersSource), nameof(InstanceInitializersSource.InProcess), Category = nameof(InstanceInitializersSource.InProcess))]\r\n    [TestFixtureSource(typeof(InstanceInitializersSource), nameof(InstanceInitializersSource.OutOfProcess), Category = nameof(InstanceInitializersSource.OutOfProcess))]\r\n    public class GroupPolicyForInterop : BaseInterop\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"GroupPolicyForInterop\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"initializer\">Initializer.</param>\r\n        public GroupPolicyForInterop(IInstanceInitializer initializer)\r\n          : base(initializer)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test setup.\r\n        /// </summary>\r\n        [SetUp]\r\n        public void SetUp()\r\n        {\r\n            GroupPolicyHelper.DeleteExistingPolicies();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Clean up.\r\n        /// </summary>\r\n        [TearDown]\r\n        public void CleanUp()\r\n        {\r\n            GroupPolicyHelper.DeleteExistingPolicies();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test class Tear down.\r\n        /// </summary>\r\n        [OneTimeTearDown]\r\n        public void TestClassTearDown()\r\n        {\r\n            // Restore the tests source if it was removed as the affects subsequent tests.\r\n            TestCommon.SetupTestSource();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Validates disabling WinGetPolicy should block COM/WinRT Objects creation (InProcess and OutOfProcess).\r\n        /// </summary>\r\n        [Test]\r\n        public void DisableWinGetPolicy()\r\n        {\r\n            GroupPolicyHelper.EnableWinget.Disable();\r\n\r\n            GroupPolicyException groupPolicyException = Assert.Catch<GroupPolicyException>(() => { PackageManager packageManager = this.TestFactory.CreatePackageManager(); });\r\n            Assert.AreEqual(Constants.BlockByWinGetPolicyErrorMessage, groupPolicyException.Message);\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, groupPolicyException.HResult);\r\n\r\n            groupPolicyException = Assert.Catch<GroupPolicyException>(() => { FindPackagesOptions findPackagesOptions = this.TestFactory.CreateFindPackagesOptions(); });\r\n            Assert.AreEqual(Constants.BlockByWinGetPolicyErrorMessage, groupPolicyException.Message);\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, groupPolicyException.HResult);\r\n\r\n            groupPolicyException = Assert.Catch<GroupPolicyException>(() => { CreateCompositePackageCatalogOptions createCompositePackageCatalogOptions = this.TestFactory.CreateCreateCompositePackageCatalogOptions(); });\r\n            Assert.AreEqual(Constants.BlockByWinGetPolicyErrorMessage, groupPolicyException.Message);\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, groupPolicyException.HResult);\r\n\r\n            groupPolicyException = Assert.Catch<GroupPolicyException>(() => { InstallOptions installOptions = this.TestFactory.CreateInstallOptions(); });\r\n            Assert.AreEqual(Constants.BlockByWinGetPolicyErrorMessage, groupPolicyException.Message);\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, groupPolicyException.HResult);\r\n\r\n            groupPolicyException = Assert.Catch<GroupPolicyException>(() => { UninstallOptions uninstallOptions = this.TestFactory.CreateUninstallOptions(); });\r\n            Assert.AreEqual(Constants.BlockByWinGetPolicyErrorMessage, groupPolicyException.Message);\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, groupPolicyException.HResult);\r\n\r\n            groupPolicyException = Assert.Catch<GroupPolicyException>(() => { DownloadOptions downloadOptions = this.TestFactory.CreateDownloadOptions(); });\r\n            Assert.AreEqual(Constants.BlockByWinGetPolicyErrorMessage, groupPolicyException.Message);\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, groupPolicyException.HResult);\r\n\r\n            groupPolicyException = Assert.Catch<GroupPolicyException>(() => { PackageMatchFilter packageMatchFilter = this.TestFactory.CreatePackageMatchFilter(); });\r\n            Assert.AreEqual(Constants.BlockByWinGetPolicyErrorMessage, groupPolicyException.Message);\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, groupPolicyException.HResult);\r\n\r\n            groupPolicyException = Assert.Catch<GroupPolicyException>(() => { RepairOptions repairOptions = this.TestFactory.CreateRepairOptions(); });\r\n            Assert.AreEqual(Constants.BlockByWinGetPolicyErrorMessage, groupPolicyException.Message);\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, groupPolicyException.HResult);\r\n\r\n            groupPolicyException = Assert.Catch<GroupPolicyException>(() => { AddPackageCatalogOptions packageManagerSettings = this.TestFactory.CreateAddPackageCatalogOptions(); });\r\n            Assert.AreEqual(Constants.BlockByWinGetPolicyErrorMessage, groupPolicyException.Message);\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, groupPolicyException.HResult);\r\n\r\n            groupPolicyException = Assert.Catch<GroupPolicyException>(() => { RemovePackageCatalogOptions packageManagerSettings = this.TestFactory.CreateRemovePackageCatalogOptions(); });\r\n            Assert.AreEqual(Constants.BlockByWinGetPolicyErrorMessage, groupPolicyException.Message);\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, groupPolicyException.HResult);\r\n\r\n            groupPolicyException = Assert.Catch<GroupPolicyException>(() => { EditPackageCatalogOptions packageManagerSettings = this.TestFactory.CreateEditPackageCatalogOptions(); });\r\n            Assert.AreEqual(Constants.BlockByWinGetPolicyErrorMessage, groupPolicyException.Message);\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, groupPolicyException.HResult);\r\n\r\n            // PackageManagerSettings is not implemented in context OutOfProcDev\r\n            if (this.TestFactory.Context == ClsidContext.InProc)\r\n            {\r\n                groupPolicyException = Assert.Catch<GroupPolicyException>(() => { PackageManagerSettings packageManagerSettings = this.TestFactory.CreatePackageManagerSettings(); });\r\n                Assert.AreEqual(Constants.BlockByWinGetPolicyErrorMessage, groupPolicyException.Message);\r\n                Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, groupPolicyException.HResult);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Validates disabling the EnableWindowsPackageManagerCommandLineInterfaces policy should still allow COM calls.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task DisableWinGetCommandLineInterfacesPolicy()\r\n        {\r\n            GroupPolicyHelper.EnableWinGetCommandLineInterfaces.Disable();\r\n\r\n            PackageManager packageManager = this.TestFactory.CreatePackageManager();\r\n            string installDir = TestCommon.GetRandomTestDir();\r\n\r\n            // Create composite package catalog source\r\n            var options = this.TestFactory.CreateCreateCompositePackageCatalogOptions();\r\n            var testSource = packageManager.GetPackageCatalogByName(Constants.TestSourceName);\r\n            Assert.NotNull(testSource, $\"{Constants.TestSourceName} cannot be null\");\r\n            options.Catalogs.Add(testSource);\r\n            options.CompositeSearchBehavior = CompositeSearchBehavior.AllCatalogs;\r\n            PackageCatalogReference compositeSource = packageManager.CreateCompositePackageCatalog(options);\r\n\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, Constants.ModifyRepairInstaller);\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n            installOptions.AcceptPackageAgreements = true;\r\n            installOptions.ReplacementInstallerArguments = $\"/InstallDir {installDir} /Version 2.0.0.0 /DisplayName TestModifyRepair /UseHKLM\";\r\n\r\n            // Install\r\n            var installResult = await packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\r\n\r\n            // Find package again, but this time it should detect the installed version\r\n            searchResult = this.FindOnePackage(compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, Constants.ModifyRepairInstaller);\r\n            Assert.NotNull(searchResult.CatalogPackage.InstalledVersion);\r\n\r\n            // Repair\r\n            var repairOptions = this.TestFactory.CreateRepairOptions();\r\n            repairOptions.PackageRepairMode = PackageRepairMode.Silent;\r\n            var repairResult = await packageManager.RepairPackageAsync(searchResult.CatalogPackage, repairOptions);\r\n            Assert.AreEqual(RepairResultStatus.Ok, repairResult.Status);\r\n\r\n            // Uninstall\r\n            var uninstallResult = await packageManager.UninstallPackageAsync(searchResult.CatalogPackage, this.TestFactory.CreateUninstallOptions());\r\n            Assert.AreEqual(UninstallResultStatus.Ok, uninstallResult.Status);\r\n            Assert.True(TestCommon.VerifyTestExeUninstalled(installDir));\r\n\r\n            // Clean up.\r\n            if (Directory.Exists(installDir))\r\n            {\r\n                Directory.Delete(installDir, true);\r\n            }\r\n\r\n            // Download\r\n            var downloadResult = await packageManager.DownloadPackageAsync(searchResult.CatalogPackage, this.TestFactory.CreateDownloadOptions());\r\n            Assert.AreEqual(DownloadResultStatus.Ok, downloadResult.Status);\r\n            var packageVersion = \"2.0.0.0\";\r\n            string downloadDir = Path.Combine(TestCommon.GetDefaultDownloadDirectory(), $\"{Constants.ModifyRepairInstaller}_{packageVersion}\");\r\n            TestCommon.AssertInstallerDownload(downloadDir, \"TestModifyRepair\", packageVersion, ProcessorArchitecture.X86, TestCommon.Scope.Unknown, PackageInstallerType.Burn, \"en-US\");\r\n\r\n            // Add, update and remove package catalog\r\n            await this.AddUpdateRemovePackageCatalog();\r\n        }\r\n\r\n        private async Task AddUpdateRemovePackageCatalog()\r\n        {\r\n            // Remove the tests source if it exists.\r\n            await this.RemovePackageCatalog();\r\n\r\n            PackageManager packageManager = this.TestFactory.CreatePackageManager();\r\n\r\n            // Add package catalog\r\n            AddPackageCatalogOptions options = this.TestFactory.CreateAddPackageCatalogOptions();\r\n            options.SourceUri = Constants.TestSourceUrl;\r\n            options.Name = Constants.TestSourceName;\r\n            options.TrustLevel = PackageCatalogTrustLevel.Trusted;\r\n\r\n            var addCatalogResult = await packageManager.AddPackageCatalogAsync(options);\r\n            Assert.IsNotNull(addCatalogResult);\r\n            Assert.AreEqual(AddPackageCatalogStatus.Ok, addCatalogResult.Status);\r\n\r\n            // Get package catalog\r\n            var packageCatalog = packageManager.GetPackageCatalogByName(options.Name);\r\n\r\n            Assert.IsNotNull(packageCatalog);\r\n            Assert.AreEqual(options.Name, packageCatalog.Info.Name);\r\n            Assert.AreEqual(options.SourceUri, packageCatalog.Info.Argument);\r\n            var lastUpdatedTime = packageCatalog.Info.LastUpdateTime;\r\n\r\n            // Update package catalog\r\n            // Sleep for 30 seconds to make sure the last updated time is different after the refresh.\r\n            Thread.Sleep(TimeSpan.FromSeconds(30));\r\n\r\n            var updateResult = await packageCatalog.RefreshPackageCatalogAsync();\r\n            Assert.IsNotNull(updateResult);\r\n            Assert.AreEqual(RefreshPackageCatalogStatus.Ok, updateResult.Status);\r\n\r\n            packageCatalog = packageManager.GetPackageCatalogByName(options.Name);\r\n            Assert.IsTrue(packageCatalog.Info.LastUpdateTime > lastUpdatedTime);\r\n\r\n            // Remove package catalog\r\n            await this.RemovePackageCatalog();\r\n        }\r\n\r\n        private async Task RemovePackageCatalog()\r\n        {\r\n            PackageManager packageManager = this.TestFactory.CreatePackageManager();\r\n\r\n            // Remove the tests source if it exists.\r\n            RemovePackageCatalogOptions removePackageCatalogOptions = this.TestFactory.CreateRemovePackageCatalogOptions();\r\n            removePackageCatalogOptions.Name = Constants.TestSourceName;\r\n\r\n            var removeCatalogResult = await packageManager.RemovePackageCatalogAsync(removePackageCatalogOptions);\r\n            Assert.IsNotNull(removeCatalogResult);\r\n            Assert.AreEqual(RemovePackageCatalogStatus.Ok, removeCatalogResult.Status);\r\n\r\n            var packageCatalog = packageManager.GetPackageCatalogByName(removePackageCatalogOptions.Name);\r\n            Assert.IsNull(packageCatalog);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/Interop/InstallInterop.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"InstallInterop.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests.Interop\r\n{\r\n    using System;\r\n    using System.IO;\r\n    using System.Threading.Tasks;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.Management.Deployment.Projection;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// Install interop.\r\n    /// </summary>\r\n    [TestFixtureSource(typeof(InstanceInitializersSource), nameof(InstanceInitializersSource.InProcess), Category = nameof(InstanceInitializersSource.InProcess))]\r\n    [TestFixtureSource(typeof(InstanceInitializersSource), nameof(InstanceInitializersSource.OutOfProcess), Category = nameof(InstanceInitializersSource.OutOfProcess))]\r\n    public class InstallInterop : BaseInterop\r\n    {\r\n        private string installDir;\r\n        private PackageManager packageManager;\r\n        private PackageCatalogReference testSource;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"InstallInterop\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"initializer\">Initializer.</param>\r\n        public InstallInterop(IInstanceInitializer initializer)\r\n            : base(initializer)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Set up.\r\n        /// </summary>\r\n        [SetUp]\r\n        public void SetUp()\r\n        {\r\n            this.packageManager = this.TestFactory.CreatePackageManager();\r\n            this.testSource = this.packageManager.GetPackageCatalogByName(Constants.TestSourceName);\r\n            this.installDir = TestCommon.GetRandomTestDir();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Install exe.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task InstallExe()\r\n        {\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestExeInstaller\");\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n            installOptions.PackageInstallMode = PackageInstallMode.Silent;\r\n            installOptions.PreferredInstallLocation = this.installDir;\r\n            installOptions.AcceptPackageAgreements = true;\r\n\r\n            // Install\r\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n\r\n            // Assert\r\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(this.installDir));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install with inapplicable os version.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task InstallExeWithInsufficientMinOsVersion()\r\n        {\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Name, PackageFieldMatchOption.Equals, \"InapplicableOsVersion\");\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n            installOptions.PackageInstallMode = PackageInstallMode.Silent;\r\n            installOptions.PreferredInstallLocation = this.installDir;\r\n\r\n            // Install\r\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n\r\n            // Assert\r\n            Assert.AreEqual(InstallResultStatus.NoApplicableInstallers, installResult.Status);\r\n            Assert.False(TestCommon.VerifyTestExeInstalledAndCleanup(this.installDir));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install with hash mismatch.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task InstallExeWithHashMismatch()\r\n        {\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Name, PackageFieldMatchOption.Equals, \"TestExeSha256Mismatch\");\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n            installOptions.PackageInstallMode = PackageInstallMode.Silent;\r\n            installOptions.PreferredInstallLocation = this.installDir;\r\n\r\n            // Install\r\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n\r\n            // Assert\r\n            Assert.AreEqual(InstallResultStatus.DownloadError, installResult.Status);\r\n            Assert.False(TestCommon.VerifyTestExeInstalledAndCleanup(this.installDir));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test installing inno installer.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task InstallWithInno()\r\n        {\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Name, PackageFieldMatchOption.Equals, \"TestInnoInstaller\");\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n            installOptions.PackageInstallMode = PackageInstallMode.Silent;\r\n            installOptions.PreferredInstallLocation = this.installDir;\r\n\r\n            // Install\r\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n\r\n            // Assert\r\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(this.installDir));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test installing burn installer.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task InstallBurn()\r\n        {\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Name, PackageFieldMatchOption.Equals, \"TestBurnInstaller\");\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n            installOptions.PackageInstallMode = PackageInstallMode.Silent;\r\n            installOptions.PreferredInstallLocation = this.installDir;\r\n\r\n            // Install\r\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n\r\n            // Assert\r\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(this.installDir));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test installing nullsoft installer.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task InstallNullSoft()\r\n        {\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Name, PackageFieldMatchOption.Equals, \"TestNullsoftInstaller\");\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n            installOptions.PackageInstallMode = PackageInstallMode.Silent;\r\n            installOptions.PreferredInstallLocation = this.installDir;\r\n\r\n            // Install\r\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n\r\n            // Assert\r\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(this.installDir));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test installing msi.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task InstallMSI()\r\n        {\r\n            if (string.IsNullOrEmpty(TestIndex.MsiInstaller))\r\n            {\r\n                Assert.Ignore(\"MSI installer not available\");\r\n            }\r\n\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Name, PackageFieldMatchOption.Equals, \"TestMsiInstaller\");\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n            installOptions.PackageInstallMode = PackageInstallMode.Silent;\r\n            installOptions.PreferredInstallLocation = this.installDir;\r\n\r\n            // Install\r\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n\r\n            // Assert\r\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\r\n            Assert.True(TestCommon.VerifyTestMsiInstalledAndCleanup(this.installDir));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test installing an msix.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task InstallMSIX()\r\n        {\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Name, PackageFieldMatchOption.Equals, \"TestMsixInstaller\");\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n\r\n            // Install\r\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n\r\n            // Assert\r\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\r\n            Assert.True(TestCommon.VerifyTestMsixInstalledAndCleanup());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test installing msix with machine scope.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task InstallMSIXMachineScope()\r\n        {\r\n            // TODO: Provision and Deprovision api not supported in build server.\r\n            Assert.Ignore();\r\n\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Name, PackageFieldMatchOption.Equals, \"TestMsixInstaller\");\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n            installOptions.PackageInstallScope = PackageInstallScope.System;\r\n\r\n            // Install\r\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n\r\n            // Assert\r\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\r\n            Assert.True(TestCommon.VerifyTestMsixInstalledAndCleanup(true));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test installing msix with signature.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task InstallMSIXWithSignature()\r\n        {\r\n            // Task to investigate installation error\r\n            // TODO: https://task.ms/40489822\r\n            Assert.Ignore();\r\n\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Name, PackageFieldMatchOption.Equals, \"TestMsixWithSignatureHash\");\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n\r\n            // Install\r\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n\r\n            // Assert\r\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\r\n            Assert.True(TestCommon.VerifyTestMsixInstalledAndCleanup());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test installing msix with signature machine scope.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task InstallMSIXWithSignatureMachineScope()\r\n        {\r\n            // TODO: Provision and Deprovision api not supported in build server.\r\n            Assert.Ignore();\r\n\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Name, PackageFieldMatchOption.Equals, \"TestMsixWithSignatureHash\");\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n            installOptions.PackageInstallScope = PackageInstallScope.System;\r\n\r\n            // Install\r\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n\r\n            // Assert\r\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\r\n            Assert.True(TestCommon.VerifyTestMsixInstalledAndCleanup(true));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test installing msix with signature hash mismatch.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task InstallMSIXWithSignatureHashMismatch()\r\n        {\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Name, PackageFieldMatchOption.Equals, \"TestMsixSignatureHashMismatch\");\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n\r\n            // Install\r\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n\r\n            // Assert\r\n            Assert.AreEqual(InstallResultStatus.DownloadError, installResult.Status);\r\n            Assert.False(TestCommon.VerifyTestMsixInstalledAndCleanup());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test installing exe.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallExeWithAlternateSourceFailure()\r\n        {\r\n            // Add mock source\r\n            TestCommon.RunAICLICommand(\"source add\", \"failSearch \\\"{ \\\"\\\"SearchHR\\\"\\\": \\\"\\\"0x80070002\\\"\\\" }\\\" Microsoft.Test.Configurable --header \\\"{}\\\"\");\r\n\r\n            // Get mock source\r\n            var failSearchSource = this.packageManager.GetPackageCatalogByName(\"failSearch\");\r\n\r\n            // Find package\r\n            var searchResult = this.FindAllPackages(failSearchSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestExeInstaller\");\r\n\r\n            // Assert\r\n            Assert.NotNull(failSearchSource);\r\n            Assert.AreEqual(0, searchResult.Count);\r\n\r\n            // Remove mock source\r\n            TestCommon.RunAICLICommand(\"source remove\", \"failSearch\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test installing portable exe.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task InstallPortableExe()\r\n        {\r\n            string installDir = Path.Combine(Environment.GetEnvironmentVariable(Constants.LocalAppData), \"Microsoft\", \"WinGet\", \"Packages\");\r\n            string productCode = Constants.PortableExePackageDirName;\r\n            string commandAlias = $\"{Constants.ExeInstaller}.exe\";\r\n            string fileName = $\"{Constants.ExeInstaller}.exe\";\r\n\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, Constants.PortableExePackageId);\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n\r\n            // Install\r\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n\r\n            // Assert\r\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\r\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, Constants.PortableExePackageDirName), commandAlias, fileName, productCode, true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test installing portable exe with command.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task InstallPortableExeWithCommand()\r\n        {\r\n            string productCode = Constants.PortableExeWithCommandPackageDirName;\r\n            string fileName = Constants.AppInstallerTestExeInstallerExe;\r\n            string commandAlias = Constants.TestCommandExe;\r\n\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, Constants.PortableExeWithCommandPackageId);\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n            installOptions.PreferredInstallLocation = this.installDir;\r\n\r\n            // Install\r\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n\r\n            // Assert\r\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\r\n            TestCommon.VerifyPortablePackage(this.installDir, commandAlias, fileName, productCode, true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test installing portable package to existing directory.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task InstallPortableToExistingDirectory()\r\n        {\r\n            var existingDir = Path.Combine(this.installDir, \"testDirectory\");\r\n            Directory.CreateDirectory(existingDir);\r\n\r\n            string productCode = Constants.PortableExePackageDirName;\r\n            string commandAlias = Constants.AppInstallerTestExeInstallerExe;\r\n            string fileName = Constants.AppInstallerTestExeInstallerExe;\r\n\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, Constants.PortableExePackageId);\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n            installOptions.PreferredInstallLocation = existingDir;\r\n\r\n            // Install\r\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n\r\n            // Assert\r\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\r\n            TestCommon.VerifyPortablePackage(existingDir, commandAlias, fileName, productCode, true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test installing portable package where it fails on clean up.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task InstallPortableFailsWithCleanup()\r\n        {\r\n            if (this.TestFactory.Context == ClsidContext.InProc)\r\n            {\r\n                // Task to investigate validation error when running in-process\r\n                // TODO: https://task.ms/40489822\r\n                Assert.Ignore();\r\n            }\r\n\r\n            string winGetDir = Path.Combine(Environment.GetEnvironmentVariable(Constants.LocalAppData), \"Microsoft\", \"WinGet\");\r\n            string installDir = Path.Combine(winGetDir, \"Packages\");\r\n            string symlinkDirectory = Path.Combine(winGetDir, \"Links\");\r\n            string packageDirName = Constants.PortableExePackageDirName;\r\n            string productCode = Constants.PortableExePackageDirName;\r\n            string commandAlias = Constants.AppInstallerTestExeInstallerExe;\r\n            string fileName = Constants.AppInstallerTestExeInstallerExe;\r\n            string conflictDirectory = Path.Combine(symlinkDirectory, commandAlias);\r\n\r\n            // Create a directory with the same name as the symlink in order to cause install to fail.\r\n            Directory.CreateDirectory(conflictDirectory);\r\n\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, Constants.PortableExePackageId);\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n\r\n            // Install\r\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n\r\n            // Assert\r\n            Assert.AreEqual(InstallResultStatus.InstallError, installResult.Status);\r\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, false);\r\n            Directory.Delete(conflictDirectory, true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test installing a package with user scope.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task InstallRequireUserScope()\r\n        {\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestExeInstallerNoScope\");\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n            installOptions.PackageInstallMode = PackageInstallMode.Silent;\r\n            installOptions.PreferredInstallLocation = this.installDir;\r\n            installOptions.PackageInstallScope = PackageInstallScope.User;\r\n\r\n            // Install\r\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n\r\n            // Assert\r\n            Assert.AreEqual(InstallResultStatus.NoApplicableInstallers, installResult.Status);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test installing package with user scope or unknown.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task InstallRequireUserScopeAndUnknown()\r\n        {\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestExeInstallerNoScope\");\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n            installOptions.PackageInstallMode = PackageInstallMode.Silent;\r\n            installOptions.PreferredInstallLocation = this.installDir;\r\n            installOptions.PackageInstallScope = PackageInstallScope.UserOrUnknown;\r\n\r\n            // Install\r\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n\r\n            // Assert\r\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test installing package with agreements and accepting those agreements.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task InstallWithAgreementsAccepted()\r\n        {\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.CatalogPackageMetadata\");\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n            installOptions.PackageInstallMode = PackageInstallMode.Silent;\r\n            installOptions.PreferredInstallLocation = this.installDir;\r\n            installOptions.AcceptPackageAgreements = true;\r\n\r\n            // Install\r\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n\r\n            // Assert\r\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test installing package with agreements and not accepting those agreements.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task InstallWithAgreementsNotAccepted()\r\n        {\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.CatalogPackageMetadata\");\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n            installOptions.PackageInstallMode = PackageInstallMode.Silent;\r\n            installOptions.PreferredInstallLocation = this.installDir;\r\n            installOptions.AcceptPackageAgreements = false;\r\n\r\n            // Install\r\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n\r\n            // Assert\r\n            Assert.AreEqual(InstallResultStatus.PackageAgreementsNotAccepted, installResult.Status);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test installing a package with a package dependency and passing in the 'skip-dependencies' install option.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task InstallWithSkipDependencies()\r\n        {\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.PackageDependency\");\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n            installOptions.PackageInstallMode = PackageInstallMode.Silent;\r\n            installOptions.PreferredInstallLocation = this.installDir;\r\n            installOptions.AcceptPackageAgreements = true;\r\n            installOptions.SkipDependencies = true;\r\n\r\n            // Install\r\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n\r\n            // Assert that only the exe installer is installed and not the portable package dependency.\r\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(this.installDir));\r\n\r\n            string installDir = Path.Combine(Environment.GetEnvironmentVariable(Constants.LocalAppData), \"Microsoft\", \"WinGet\", \"Packages\");\r\n            string productCode = Constants.PortableExePackageDirName;\r\n            string commandAlias = $\"{Constants.ExeInstaller}.exe\";\r\n            string fileName = $\"{Constants.ExeInstaller}.exe\";\r\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, Constants.PortableExePackageDirName), commandAlias, fileName, productCode, false);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test installing a package with a specific installer type install option.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task InstallWithInstallerType()\r\n        {\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestMultipleInstallers\");\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n            installOptions.PackageInstallMode = PackageInstallMode.Silent;\r\n            installOptions.PreferredInstallLocation = this.installDir;\r\n            installOptions.InstallerType = PackageInstallerType.Msi;\r\n            installOptions.AcceptPackageAgreements = true;\r\n\r\n            // Install\r\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n\r\n            // Assert\r\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\r\n            Assert.True(TestCommon.VerifyTestMsiInstalledAndCleanup(this.installDir));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test to verify the GetApplicableInstaller() COM call returns the correct manifest installer metadata.\r\n        /// </summary>\r\n        [Test]\r\n        public void GetApplicableInstaller()\r\n        {\r\n            // Find package\r\n            var searchResult = this.FindAllPackages(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.PackageInstallerInfo\");\r\n            Assert.AreEqual(1, searchResult.Count);\r\n\r\n            // Configure installation\r\n            var catalogPackage = searchResult[0].CatalogPackage;\r\n            var packageVersionId = catalogPackage.AvailableVersions[0];\r\n            var packageVersionInfo = catalogPackage.GetPackageVersionInfo(packageVersionId);\r\n\r\n            // Use install options with no applicable match.\r\n            var badInstallOptions = this.TestFactory.CreateInstallOptions();\r\n            badInstallOptions.PackageInstallScope = PackageInstallScope.System;\r\n\r\n            Assert.IsNull(packageVersionInfo.GetApplicableInstaller(badInstallOptions));\r\n\r\n            // Use install options with valid applicable match.\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n            installOptions.PackageInstallScope = PackageInstallScope.User;\r\n            var packageInstallerInfo = packageVersionInfo.GetApplicableInstaller(installOptions);\r\n\r\n            // Assert\r\n            Assert.IsNotNull(packageInstallerInfo);\r\n            Assert.AreEqual(ElevationRequirement.ElevationRequired, packageInstallerInfo.ElevationRequirement);\r\n            Assert.AreEqual(Windows.System.ProcessorArchitecture.X64, packageInstallerInfo.Architecture);\r\n            Assert.AreEqual(PackageInstallerType.Zip, packageInstallerInfo.InstallerType);\r\n            Assert.AreEqual(PackageInstallerType.Exe, packageInstallerInfo.NestedInstallerType);\r\n            Assert.AreEqual(PackageInstallerScope.User, packageInstallerInfo.Scope);\r\n            Assert.AreEqual(\"en-US\", packageInstallerInfo.Locale);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Install exe and verify that we can find it as installed after.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task InstallExe_VerifyInstalledCatalog()\r\n        {\r\n            var installedCatalogReference = this.packageManager.GetLocalPackageCatalog(LocalPackageCatalog.InstalledPackages);\r\n\r\n            // Ensure package is not installed\r\n            var installedResult = this.FindAllPackages(installedCatalogReference, PackageMatchField.ProductCode, PackageFieldMatchOption.Equals, Constants.ExeInstalledDefaultProductCode);\r\n            Assert.IsNotNull(installedResult);\r\n            Assert.AreEqual(0, installedResult.Count);\r\n\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestExeInstaller\");\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n            installOptions.PackageInstallMode = PackageInstallMode.Silent;\r\n            installOptions.PreferredInstallLocation = this.installDir;\r\n            installOptions.AcceptPackageAgreements = true;\r\n\r\n            // Install\r\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n\r\n            // Assert\r\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\r\n\r\n            // Check installed catalog after\r\n            this.FindOnePackage(installedCatalogReference, PackageMatchField.ProductCode, PackageFieldMatchOption.Equals, Constants.ExeInstalledDefaultProductCode);\r\n\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(this.installDir));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Install msix and verify that we can find it as installed after.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task InstallMSIX_VerifyInstalledCatalog()\r\n        {\r\n            var installedCatalogReference = this.packageManager.GetLocalPackageCatalog(LocalPackageCatalog.InstalledPackages);\r\n\r\n            // Ensure package is not installed\r\n            var installedResult = this.FindAllPackages(installedCatalogReference, PackageMatchField.PackageFamilyName, PackageFieldMatchOption.Equals, Constants.MsixInstallerPackageFamilyName);\r\n            Assert.IsNotNull(installedResult);\r\n            Assert.AreEqual(0, installedResult.Count);\r\n\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(this.testSource, PackageMatchField.Name, PackageFieldMatchOption.Equals, \"TestMsixInstaller\");\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n\r\n            // Install\r\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n\r\n            // Assert\r\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\r\n\r\n            // Check installed catalog after\r\n            this.FindOnePackage(installedCatalogReference, PackageMatchField.PackageFamilyName, PackageFieldMatchOption.Equals, Constants.MsixInstallerPackageFamilyName);\r\n\r\n            Assert.True(TestCommon.VerifyTestMsixInstalledAndCleanup());\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/Interop/InstanceInitializersSource.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"InstanceInitializersSource.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests.Interop\n{\n    using Microsoft.Management.Deployment.Projection;\n\n    /// <summary>\n    /// Source class for running tests in-process and out-of-process.\n    /// </summary>\n    public class InstanceInitializersSource\n    {\n        /// <summary>\n        /// List of in-process instance initializers passed as argument to the test class constructor.\n        /// </summary>\n        public static readonly IInstanceInitializer[] InProcess =\n        {\n            new ActivationFactoryInstanceInitializer(),\n        };\n\n        /// <summary>\n        /// List of out-of-process instance initializers passed as argument to the test class constructor.\n        /// </summary>\n        public static readonly IInstanceInitializer[] OutOfProcess =\n        {\n            new LocalServerInstanceInitializer()\n            {\n                AllowLowerTrustRegistration = true,\n                UseDevClsids = true,\n            },\n        };\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/Interop/InteropSetUpFixture.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"InteropSetUpFixture.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests.Interop\n{\n    using System;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\n\n    /// <summary>\r\n    /// Interop set up fixture.\r\n    /// </summary>\n    [SetUpFixture]\n    public class InteropSetUpFixture\n    {\n        /// <summary>\r\n        /// One time set up.\r\n        /// </summary>\n        [OneTimeSetUp]\n        public void Setup()\n        {\n            TestCommon.SetupTestSource();\r\n        }\n\n        /// <summary>\r\n        /// Tear down.\r\n        /// </summary>\n        [OneTimeTearDown]\n        public void TearDown()\n        {\n            try\n            {\n                GC.Collect();\n                GC.WaitForPendingFinalizers();\n\n                TestCommon.TearDownTestSource();\n            }\n            catch\n            {\n                // If the COM objects were not yet disposed and lock acquired\n                // when connecting to test source was not released, then just\n                // exit process since all tests have already executed.\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/Interop/PackageCatalogInterop.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"PackageCatalogInterop.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\nnamespace AppInstallerCLIE2ETests.Interop\r\n{\r\n    using System;\r\n    using System.IO;\r\n    using System.Threading;\r\n    using System.Threading.Tasks;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using Microsoft.CodeAnalysis;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.Management.Deployment.Projection;\r\n    using NUnit.Framework;\r\n    using Windows.System;\r\n\r\n    /// <summary>\r\n    /// Package catalog interop class.\r\n    /// </summary>\r\n    [TestFixtureSource(typeof(InstanceInitializersSource), nameof(InstanceInitializersSource.InProcess), Category = nameof(InstanceInitializersSource.InProcess))]\r\n    [TestFixtureSource(typeof(InstanceInitializersSource), nameof(InstanceInitializersSource.OutOfProcess), Category = nameof(InstanceInitializersSource.OutOfProcess))]\r\n    public class PackageCatalogInterop : BaseInterop\r\n    {\r\n        private PackageManager packageManager;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"PackageCatalogInterop\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"initializer\">initializer.</param>\r\n        public PackageCatalogInterop(IInstanceInitializer initializer)\r\n            : base(initializer)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Set up.\r\n        /// </summary>\r\n        [SetUp]\r\n        public void Setup()\r\n        {\r\n            // Remove the tests source if it exists.\r\n            TestCommon.RunAICLICommand(\"source remove\", Constants.TestSourceName);\r\n\r\n            this.packageManager = this.TestFactory.CreatePackageManager();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Add and remove package catalog.\r\n        /// </summary>\r\n        /// <returns> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task AddRemovePackageCatalog()\r\n        {\r\n            AddPackageCatalogOptions options = this.TestFactory.CreateAddPackageCatalogOptions();\r\n            options.SourceUri = Constants.TestSourceUrl;\r\n            options.Name = Constants.TestSourceName;\r\n            options.TrustLevel = PackageCatalogTrustLevel.Trusted;\r\n\r\n            await this.AddAndValidatePackageCatalogAsync(options, AddPackageCatalogStatus.Ok);\r\n\r\n            RemovePackageCatalogOptions removePackageCatalogOptions = this.TestFactory.CreateRemovePackageCatalogOptions();\r\n            removePackageCatalogOptions.Name = Constants.TestSourceName;\r\n            var removeCatalogResult = await this.packageManager.RemovePackageCatalogAsync(removePackageCatalogOptions);\r\n            Assert.IsNotNull(removeCatalogResult);\r\n            Assert.AreEqual(RemovePackageCatalogStatus.Ok, removeCatalogResult.Status);\r\n\r\n            var testSource = this.packageManager.GetPackageCatalogByName(Constants.TestSourceName);\r\n            Assert.IsNull(testSource);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Add package catalog with invalid options.\r\n        /// </summary>\r\n        [Test]\r\n        public void AddPackageCatalogWithInvalidOptions()\r\n        {\r\n            // Add package catalog with null options.\r\n            Assert.ThrowsAsync<NullReferenceException>(async () => await this.packageManager.AddPackageCatalogAsync(null));\r\n\r\n            // Add package catalog with empty options.\r\n            Assert.ThrowsAsync<ArgumentException>(async () => await this.packageManager.AddPackageCatalogAsync(this.TestFactory.CreateAddPackageCatalogOptions()));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Add package catalog with a duplicate name and verify it returns SourceNameExists.\r\n        /// </summary>\r\n        /// <returns>representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task AddPackageCatalog_DuplicateName_ReturnsSourceNameExists()\r\n        {\r\n            AddPackageCatalogOptions options = this.TestFactory.CreateAddPackageCatalogOptions();\r\n            options.SourceUri = Constants.TestSourceUrl;\r\n            options.Name = Constants.TestSourceName;\r\n            options.TrustLevel = PackageCatalogTrustLevel.Trusted;\r\n\r\n            await this.AddAndValidatePackageCatalogAsync(options, AddPackageCatalogStatus.Ok);\r\n\r\n            // Add the same package catalog again.\r\n            await this.AddAndValidatePackageCatalogAsync(options, AddPackageCatalogStatus.InvalidOptions, Constants.ErrorCode.ERROR_SOURCE_NAME_ALREADY_EXISTS);\r\n\r\n            // Remove the tests source if it exists.\r\n            RemovePackageCatalogOptions removePackageCatalogOptions = this.TestFactory.CreateRemovePackageCatalogOptions();\r\n            removePackageCatalogOptions.Name = Constants.TestSourceName;\r\n            await this.RemoveAndValidatePackageCatalogAsync(removePackageCatalogOptions, RemovePackageCatalogStatus.Ok);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Add package catalog with a duplicate source uri and verify it returns SourceArg AlreadyExists.\r\n        /// </summary>\r\n        /// <returns>representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task AddPackageCatalog_DuplicateSourceUri_ReturnSourceArgAlreadyExists()\r\n        {\r\n            AddPackageCatalogOptions options = this.TestFactory.CreateAddPackageCatalogOptions();\r\n            options.SourceUri = Constants.TestSourceUrl;\r\n            options.Name = Constants.TestSourceName;\r\n            options.TrustLevel = PackageCatalogTrustLevel.Trusted;\r\n\r\n            await this.AddAndValidatePackageCatalogAsync(options, AddPackageCatalogStatus.Ok);\r\n\r\n            // Add the same package catalog again.\r\n            options.Name = \"TestSource2\";\r\n            await this.AddAndValidatePackageCatalogAsync(options, AddPackageCatalogStatus.InvalidOptions, Constants.ErrorCode.ERROR_SOURCE_ARG_ALREADY_EXISTS);\r\n\r\n            // Remove the tests source if it exists.\r\n            RemovePackageCatalogOptions removePackageCatalogOptions = this.TestFactory.CreateRemovePackageCatalogOptions();\r\n            removePackageCatalogOptions.Name = Constants.TestSourceName;\r\n            await this.RemoveAndValidatePackageCatalogAsync(removePackageCatalogOptions, RemovePackageCatalogStatus.Ok);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Add package catalog with invalid source uri.\r\n        /// </summary>\r\n        /// <returns>representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task AddPackageCatalogWithInvalidSourceUri()\r\n        {\r\n            AddPackageCatalogOptions options = this.TestFactory.CreateAddPackageCatalogOptions();\r\n            options.SourceUri = \"InvalidUri\";\r\n            options.Name = Constants.TestSourceName;\r\n            options.TrustLevel = PackageCatalogTrustLevel.Trusted;\r\n\r\n            await this.AddAndValidatePackageCatalogAsync(options, AddPackageCatalogStatus.InternalError);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Add package catalog with insecure source uri.\r\n        /// </summary>\r\n        /// <returns>representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task AddPackageCatalogWithHttpSourceUri()\r\n        {\r\n            AddPackageCatalogOptions options = this.TestFactory.CreateAddPackageCatalogOptions();\r\n            options.SourceUri = \"http://microsoft.com\";\r\n            options.Name = \"Insecure\";\r\n            options.TrustLevel = PackageCatalogTrustLevel.Trusted;\r\n\r\n            await this.AddAndValidatePackageCatalogAsync(options, AddPackageCatalogStatus.InvalidOptions, Constants.ErrorCode.ERROR_SOURCE_NOT_SECURE);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Add package catalog with invalid type.\r\n        /// </summary>\r\n        /// <returns>representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task AddPackageCatalogWithInvalidType()\r\n        {\r\n            AddPackageCatalogOptions options = this.TestFactory.CreateAddPackageCatalogOptions();\r\n            options.SourceUri = Constants.TestSourceUrl;\r\n            options.Name = Constants.TestSourceName;\r\n            options.Type = \"InvalidType\";\r\n\r\n            await this.AddAndValidatePackageCatalogAsync(options, AddPackageCatalogStatus.InvalidOptions, Constants.ErrorCode.ERROR_INVALID_SOURCE_TYPE);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Add, update and remove package catalog.\r\n        /// </summary>\r\n        /// <returns> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task AddUpdateRemovePackageCatalog()\r\n        {\r\n            AddPackageCatalogOptions options = this.TestFactory.CreateAddPackageCatalogOptions();\r\n            options.SourceUri = Constants.TestSourceUrl;\r\n            options.Name = Constants.TestSourceName;\r\n            options.TrustLevel = PackageCatalogTrustLevel.Trusted;\r\n\r\n            await this.AddCatalogAndVerifyStatusAsync(options, AddPackageCatalogStatus.Ok);\r\n\r\n            var packageCatalog = this.GetAndValidatePackageCatalog(options);\r\n            var lastUpdatedTime = packageCatalog.Info.LastUpdateTime;\r\n\r\n            // Sleep for 30 seconds to make sure the last updated time is different after the refresh.\r\n            Thread.Sleep(TimeSpan.FromSeconds(30));\r\n\r\n            var updateResult = await packageCatalog.RefreshPackageCatalogAsync();\r\n            Assert.IsNotNull(updateResult);\r\n            Assert.AreEqual(RefreshPackageCatalogStatus.Ok, updateResult.Status);\r\n\r\n            packageCatalog = this.GetAndValidatePackageCatalog(options);\r\n            Assert.IsTrue(packageCatalog.Info.LastUpdateTime > lastUpdatedTime);\r\n\r\n            RemovePackageCatalogOptions removePackageCatalogOptions = this.TestFactory.CreateRemovePackageCatalogOptions();\r\n            removePackageCatalogOptions.Name = Constants.TestSourceName;\r\n            await this.RemoveAndValidatePackageCatalogAsync(removePackageCatalogOptions, RemovePackageCatalogStatus.Ok);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Add, remove package catalog with PreserveData filed set..\r\n        /// </summary>\r\n        /// <returns> representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task AddRemovePackageCatalogWithPreserveDataFiledSet()\r\n        {\r\n            AddPackageCatalogOptions options = this.TestFactory.CreateAddPackageCatalogOptions();\r\n            options.SourceUri = Constants.TestSourceUrl;\r\n            options.Name = Constants.TestSourceName;\r\n            options.TrustLevel = PackageCatalogTrustLevel.Trusted;\r\n\r\n            await this.AddAndValidatePackageCatalogAsync(options, AddPackageCatalogStatus.Ok);\r\n\r\n            RemovePackageCatalogOptions removePackageCatalogOptions = this.TestFactory.CreateRemovePackageCatalogOptions();\r\n            removePackageCatalogOptions.Name = Constants.TestSourceName;\r\n            removePackageCatalogOptions.PreserveData = true;\r\n\r\n            await this.RemoveAndValidatePackageCatalogAsync(removePackageCatalogOptions, RemovePackageCatalogStatus.Ok);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Remove package catalog with invalid options.\r\n        /// </summary>\r\n        [Test]\r\n        public void RemovePackageCatalogWithInvalidOptions()\r\n        {\r\n            // Remove package catalog with null options.\r\n            Assert.ThrowsAsync<NullReferenceException>(async () => await this.packageManager.RemovePackageCatalogAsync(null));\r\n\r\n            // Remove package catalog with empty options.\r\n            Assert.ThrowsAsync<ArgumentException>(async () => await this.packageManager.RemovePackageCatalogAsync(this.TestFactory.CreateRemovePackageCatalogOptions()));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Remove a package catalog that is not present.\r\n        /// </summary>\r\n        /// <returns>representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task RemoveNonExistingPackageCatalog()\r\n        {\r\n            RemovePackageCatalogOptions removePackageCatalogOptions = this.TestFactory.CreateRemovePackageCatalogOptions();\r\n            removePackageCatalogOptions.Name = Constants.TestSourceName;\r\n\r\n            await this.RemoveAndValidatePackageCatalogAsync(removePackageCatalogOptions, RemovePackageCatalogStatus.InvalidOptions, Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Edit package catalog with invalid options.\r\n        /// </summary>\r\n        [Test]\r\n        public void EditPackageCatalogWithInvalidOptions()\r\n        {\r\n            // Edit package catalog with null options.\r\n            Assert.Throws<NullReferenceException>(() => this.packageManager.EditPackageCatalog(null));\r\n\r\n            // Edit package catalog with empty options.\r\n            Assert.Throws<ArgumentException>(() => this.packageManager.EditPackageCatalog(this.TestFactory.CreateEditPackageCatalogOptions()));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Edit a package catalog that is not present.\r\n        /// </summary>\r\n        [Test]\r\n        public void EditNonExistingPackageCatalog()\r\n        {\r\n            EditPackageCatalogOptions editPackageCatalogOptions = this.TestFactory.CreateEditPackageCatalogOptions();\r\n            editPackageCatalogOptions.Name = Constants.TestSourceName;\r\n\r\n            this.EditAndValidatePackageCatalog(editPackageCatalogOptions, EditPackageCatalogStatus.InvalidOptions, Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Edit a package catalog that is not present.\r\n        /// </summary>\r\n        /// <returns>representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task AddEditRemovePackageCatalog()\r\n        {\r\n            // Add\r\n            AddPackageCatalogOptions options = this.TestFactory.CreateAddPackageCatalogOptions();\r\n            options.SourceUri = Constants.TestSourceUrl;\r\n            options.Name = Constants.TestSourceName;\r\n            options.TrustLevel = PackageCatalogTrustLevel.Trusted;\r\n            options.Explicit = true;\r\n            options.Priority = 12;\r\n\r\n            await this.AddAndValidatePackageCatalogAsync(options, AddPackageCatalogStatus.Ok);\r\n\r\n            // Edit\r\n            EditPackageCatalogOptions editOptions = this.TestFactory.CreateEditPackageCatalogOptions();\r\n            editOptions.Name = Constants.TestSourceName;\r\n            editOptions.Explicit = false;\r\n            editOptions.Priority = 42;\r\n            this.EditAndValidatePackageCatalog(editOptions, EditPackageCatalogStatus.Ok);\r\n\r\n            // Remove\r\n            RemovePackageCatalogOptions removePackageCatalogOptions = this.TestFactory.CreateRemovePackageCatalogOptions();\r\n            removePackageCatalogOptions.Name = Constants.TestSourceName;\r\n            var removeCatalogResult = await this.packageManager.RemovePackageCatalogAsync(removePackageCatalogOptions);\r\n            Assert.IsNotNull(removeCatalogResult);\r\n            Assert.AreEqual(RemovePackageCatalogStatus.Ok, removeCatalogResult.Status);\r\n\r\n            var testSource = this.packageManager.GetPackageCatalogByName(Constants.TestSourceName);\r\n            Assert.IsNull(testSource);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test class Tear down.\r\n        /// </summary>\r\n        [OneTimeTearDown]\r\n        public void TestClassTearDown()\r\n        {\r\n            // Restore the tests source if it was removed as the affects subsequent tests.\r\n            TestCommon.SetupTestSource();\r\n        }\r\n\r\n        private async Task AddCatalogAndVerifyStatusAsync(AddPackageCatalogOptions addPackageCatalogOptions, AddPackageCatalogStatus expectedStatus, int expectedErrorCode = 0)\r\n        {\r\n            var addCatalogResult = await this.packageManager.AddPackageCatalogAsync(addPackageCatalogOptions);\r\n            Assert.IsNotNull(addCatalogResult);\r\n            Assert.AreEqual(expectedStatus, addCatalogResult.Status);\r\n\r\n            if (expectedStatus != AddPackageCatalogStatus.Ok && expectedErrorCode != 0)\r\n            {\r\n                Assert.AreEqual(expectedErrorCode, addCatalogResult.ExtendedErrorCode.HResult);\r\n            }\r\n        }\r\n\r\n        private PackageCatalogReference GetAndValidatePackageCatalog(AddPackageCatalogOptions addPackageCatalogOptions)\r\n        {\r\n            var packageCatalog = this.packageManager.GetPackageCatalogByName(addPackageCatalogOptions.Name);\r\n\r\n            Assert.IsNotNull(packageCatalog);\r\n            Assert.AreEqual(addPackageCatalogOptions.Name, packageCatalog.Info.Name);\r\n            Assert.AreEqual(addPackageCatalogOptions.SourceUri, packageCatalog.Info.Argument);\r\n            Assert.AreEqual(addPackageCatalogOptions.Explicit, packageCatalog.Info.Explicit);\r\n            Assert.AreEqual(addPackageCatalogOptions.Priority, packageCatalog.Info.Priority);\r\n\r\n            return packageCatalog;\r\n        }\r\n\r\n        private async Task AddAndValidatePackageCatalogAsync(AddPackageCatalogOptions addPackageCatalogOptions, AddPackageCatalogStatus expectedStatus, int expectedErrorCode = 0)\r\n        {\r\n            // Add the package catalog and verify the status\r\n            var addCatalogResult = await this.packageManager.AddPackageCatalogAsync(addPackageCatalogOptions);\r\n            Assert.IsNotNull(addCatalogResult);\r\n            Assert.AreEqual(expectedStatus, addCatalogResult.Status);\r\n\r\n            if (expectedStatus != AddPackageCatalogStatus.Ok)\r\n            {\r\n                // Only validate the error code if the status is not Ok and the expected error code is not 0\r\n                if (expectedErrorCode != 0)\r\n                {\r\n                    Assert.AreEqual(expectedErrorCode, addCatalogResult.ExtendedErrorCode.HResult);\r\n                }\r\n\r\n                return;\r\n            }\r\n\r\n            // Validate the added package catalog if the status is Ok\r\n            this.GetAndValidatePackageCatalog(addPackageCatalogOptions);\r\n        }\r\n\r\n        private async Task RemoveAndValidatePackageCatalogAsync(RemovePackageCatalogOptions removePackageCatalogOptions, RemovePackageCatalogStatus expectedStatus, int expectedErrorCode = 0)\r\n        {\r\n            var removeCatalogResult = await this.packageManager.RemovePackageCatalogAsync(removePackageCatalogOptions);\r\n            Assert.IsNotNull(removeCatalogResult);\r\n            Assert.AreEqual(expectedStatus, removeCatalogResult.Status);\r\n\r\n            if (expectedStatus != RemovePackageCatalogStatus.Ok && expectedErrorCode != 0)\r\n            {\r\n                Assert.AreEqual(expectedErrorCode, removeCatalogResult.ExtendedErrorCode.HResult);\r\n                return;\r\n            }\r\n\r\n            var packageCatalog = this.packageManager.GetPackageCatalogByName(removePackageCatalogOptions.Name);\r\n            Assert.IsNull(packageCatalog);\r\n        }\r\n\r\n        private void EditAndValidatePackageCatalog(EditPackageCatalogOptions editPackageCatalogOptions, EditPackageCatalogStatus expectedStatus, int expectedErrorCode = 0)\r\n        {\r\n            var editCatalogResult = this.packageManager.EditPackageCatalog(editPackageCatalogOptions);\r\n            Assert.IsNotNull(editCatalogResult);\r\n            Assert.AreEqual(expectedStatus, editCatalogResult.Status);\r\n\r\n            if (expectedStatus != EditPackageCatalogStatus.Ok && expectedErrorCode != 0)\r\n            {\r\n                Assert.AreEqual(expectedErrorCode, editCatalogResult.ExtendedErrorCode.HResult);\r\n                return;\r\n            }\r\n\r\n            // Verify edits are correct.\r\n            var packageCatalog = this.packageManager.GetPackageCatalogByName(editPackageCatalogOptions.Name);\r\n            if (editPackageCatalogOptions.Explicit != null)\r\n            {\r\n                Assert.AreEqual(packageCatalog.Info.Explicit, editPackageCatalogOptions.Explicit);\r\n            }\r\n\r\n            if (editPackageCatalogOptions.Priority != null)\r\n            {\r\n                Assert.AreEqual(packageCatalog.Info.Priority, editPackageCatalogOptions.Priority);\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/Interop/RepairInterop.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"RepairInterop.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests.Interop\r\n{\r\n    using System;\r\n    using System.IO;\r\n    using System.Linq;\r\n    using System.Text;\r\n    using System.Threading.Tasks;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.Management.Deployment.Projection;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// Repair Interop Tests for COM/WinRT Interop classes.\r\n    /// </summary>\r\n    [TestFixtureSource(typeof(InstanceInitializersSource), nameof(InstanceInitializersSource.InProcess), Category = nameof(InstanceInitializersSource.InProcess))]\r\n    [TestFixtureSource(typeof(InstanceInitializersSource), nameof(InstanceInitializersSource.OutOfProcess), Category = nameof(InstanceInitializersSource.OutOfProcess))]\r\n    public class RepairInterop : BaseInterop\r\n    {\r\n        private string installDir;\r\n        private PackageManager packageManager;\r\n        private PackageCatalogReference compositeSource;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"RepairInterop\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"initializer\">Initializer.</param>\r\n        public RepairInterop(IInstanceInitializer initializer)\r\n            : base(initializer)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test setup.\r\n        /// </summary>\r\n        [SetUp]\r\n        public void Init()\r\n        {\r\n            this.packageManager = this.TestFactory.CreatePackageManager();\r\n            this.installDir = TestCommon.GetRandomTestDir();\r\n\r\n            // Create a composite source\r\n            var options = this.TestFactory.CreateCreateCompositePackageCatalogOptions();\r\n            var testSource = this.packageManager.GetPackageCatalogByName(Constants.TestSourceName);\r\n            Assert.NotNull(testSource, $\"{Constants.TestSourceName} cannot be null\");\r\n            options.Catalogs.Add(testSource);\r\n            options.CompositeSearchBehavior = CompositeSearchBehavior.AllCatalogs;\r\n            this.compositeSource = this.packageManager.CreateCompositePackageCatalog(options);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test Repair MSI Installer.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test. </returns>\r\n        [Test]\r\n        public async Task RepairMSIInstaller()\r\n        {\r\n            string msiInstallerPackageId = \"AppInstallerTest.TestMsiRepair\";\r\n            var searchResult = await this.FindAndInstallPackage(msiInstallerPackageId, this.installDir, null);\r\n\r\n            // Note: The 'msiexec repair' command requires the original installer file to be present at the location registered in the ARP (Add/Remove Programs).\r\n            // In our test scenario, the MSI installer file is initially placed in a temporary location and then deleted, which can cause the repair operation to fail.\r\n            // To work around this, we copy the installer file to the ARP source directory before running the repair command.\r\n            // A more permanent solution would be to modify the MSI installer to cache the installer file in a known location and register that location as the installer source.\r\n            // This would allow the 'msiexec repair' command to function as expected.\r\n            string installerSourceDir = TestCommon.CopyInstallerFileToARPInstallSourceDirectory(TestCommon.GetTestDataFile(\"AppInstallerTestMsiInstallerV2.msi\"), Constants.MsiInstallerProductCode, true);\r\n\r\n            // Repair the package\r\n            await this.RepairPackageAndValidateStatus(searchResult.CatalogPackage, this.TestFactory.CreateRepairOptions(), RepairResultStatus.Ok);\r\n\r\n            // Cleanup\r\n            Assert.True(TestCommon.VerifyTestMsiInstalledAndCleanup(this.installDir));\r\n\r\n            if (installerSourceDir != null && Directory.Exists(installerSourceDir))\r\n            {\r\n                Directory.Delete(installerSourceDir, true);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test Repair MSIX Installer.\r\n        /// </summary>\r\n        /// <returns>representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task RepairNonStoreMSIXPackage()\r\n        {\r\n            string msixPackageId = \"AppInstallerTest.TestMsixInstaller\";\r\n            var searchResult = await this.FindAndInstallPackage(msixPackageId, this.installDir, null);\r\n\r\n            // Repair the package\r\n            await this.RepairPackageAndValidateStatus(searchResult.CatalogPackage, this.TestFactory.CreateRepairOptions(), RepairResultStatus.Ok);\r\n\r\n            // Cleanup\r\n            Assert.True(TestCommon.VerifyTestMsixInstalledAndCleanup());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test MSIX non-store package repair with machine scope.\r\n        /// </summary>\r\n        /// <returns>representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task RepairNonStoreMsixPackageWithMachineScope()\r\n        {\r\n            var findPackages = this.FindAllPackages(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.ContainsCaseInsensitive, \"Microsoft.Paint\");\r\n\r\n            if (findPackages == null || findPackages.Count == 0)\r\n            {\r\n                Assert.Ignore(\"Test skipped as Microsoft.Paint_8wekyb3d8bbwe can't be found.\");\r\n            }\r\n\r\n            var searchResult = findPackages.First();\r\n\r\n            if (searchResult == null || searchResult.CatalogPackage == null || searchResult.CatalogPackage.InstalledVersion == null)\r\n            {\r\n                Assert.Ignore(\"Test skipped as Microsoft.Paint_8wekyb3d8bbwe is not installed.\");\r\n            }\r\n\r\n            // Repair the package\r\n            var repairOptions = this.TestFactory.CreateRepairOptions();\r\n            repairOptions.PackageRepairScope = PackageRepairScope.System;\r\n\r\n            await this.RepairPackageAndValidateStatus(searchResult.CatalogPackage, repairOptions, RepairResultStatus.RepairError, Constants.ErrorCode.ERROR_INSTALL_SYSTEM_NOT_SUPPORTED);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test repair of a Burn installer that has a \"modify\" repair behavior specified in the manifest.\r\n        /// </summary>\r\n        /// <returns>representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task RepairBurnInstallerWithModifyBehavior()\r\n        {\r\n            var replaceInstallerArguments = this.GetReplacementArguments(this.installDir, \"2.0.0.0\", \"TestModifyRepair\", useHKLM: true);\r\n            var searchResult = await this.FindAndInstallPackage(Constants.ModifyRepairInstaller, this.installDir, replaceInstallerArguments.ToString());\r\n\r\n            // Repair the package\r\n            var repairOptions = this.TestFactory.CreateRepairOptions();\r\n            repairOptions.PackageRepairMode = PackageRepairMode.Silent;\r\n\r\n            await this.RepairPackageAndValidateStatus(searchResult.CatalogPackage, repairOptions, RepairResultStatus.Ok);\r\n\r\n            // Cleanup\r\n            Assert.True(TestCommon.VerifyTestExeRepairCompletedAndCleanup(this.installDir, \"Modify Repair operation\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests the repair operation of a Burn installer that was installed in user scope but is being repaired in an admin context.\r\n        /// </summary>\r\n        /// <returns>representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task RepairBurnInstallerInAdminContextWithUserScopeInstall()\r\n        {\r\n            if (this.TestFactory.Context != ClsidContext.InProc)\r\n            {\r\n                Assert.Ignore(\"Test is only applicable for InProc context.\");\r\n            }\r\n\r\n            string replaceInstallerArguments = this.GetReplacementArguments(this.installDir, \"2.0.0.0\", \"TestUserScopeInstallRepairInAdminContext\");\r\n            var searchResult = await this.FindAndInstallPackage(\"AppInstallerTest.TestUserScopeInstallRepairInAdminContext\", this.installDir, replaceInstallerArguments);\r\n\r\n            // Repair the package\r\n            var repairOptions = this.TestFactory.CreateRepairOptions();\r\n            repairOptions.PackageRepairMode = PackageRepairMode.Silent;\r\n\r\n            await this.RepairPackageAndValidateStatus(searchResult.CatalogPackage, repairOptions, RepairResultStatus.RepairError, Constants.ErrorCode.ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED);\r\n\r\n            // Cleanup\r\n            TestCommon.CleanupTestExeAndDirectory(this.installDir);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test repair of a Exe installer that has a \"uninstaller\" repair behavior specified in the manifest and NoModify ARP flag set.\r\n        /// </summary>\r\n        /// <returns>representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task RepairBurnInstallerWithModifyBehaviorAndNoModifyFlag()\r\n        {\r\n            string replaceInstallerArguments = this.GetReplacementArguments(this.installDir, \"2.0.0.0\", \"TestModifyRepairWithNoModify\", useHKLM: true, noModify: true);\r\n            var searchResult = await this.FindAndInstallPackage(\"AppInstallerTest.TestModifyRepairWithNoModify\", this.installDir, replaceInstallerArguments);\r\n\r\n            // Repair the package\r\n            var repairOptions = this.TestFactory.CreateRepairOptions();\r\n            repairOptions.PackageRepairMode = PackageRepairMode.Silent;\r\n\r\n            await this.RepairPackageAndValidateStatus(searchResult.CatalogPackage, repairOptions, RepairResultStatus.RepairError, Constants.ErrorCode.ERROR_REPAIR_NOT_SUPPORTED);\r\n\r\n            // Cleanup\r\n            TestCommon.CleanupTestExeAndDirectory(this.installDir);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests the scenario where the repair operation is not supported for Portable Installer type.\r\n        /// </summary>\r\n        /// <returns>representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task RepairOperationNotSupportedForPortableInstaller()\r\n        {\r\n            string installDir = TestCommon.GetPortablePackagesDirectory();\r\n            string packageId, commandAlias, fileName, packageDirName, productCode;\r\n            packageId = \"AppInstallerTest.TestPortableExe\";\r\n            packageDirName = productCode = packageId + \"_\" + Constants.TestSourceIdentifier;\r\n            commandAlias = fileName = \"AppInstallerTestExeInstaller.exe\";\r\n\r\n            var searchResult = await this.FindAndInstallPackage(packageId, null, null);\r\n\r\n            // Repair the package\r\n            var repairOptions = this.TestFactory.CreateRepairOptions();\r\n            repairOptions.PackageRepairMode = PackageRepairMode.Silent;\r\n\r\n            await this.RepairPackageAndValidateStatus(searchResult.CatalogPackage, repairOptions, RepairResultStatus.RepairError, Constants.ErrorCode.ERROR_REPAIR_NOT_SUPPORTED);\r\n\r\n            // If no location specified, default behavior is to create a package directory with the name \"{packageId}_{sourceId}\"\r\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test repair of a Exe installer that has a \"uninstaller\" repair behavior specified in the manifest.\r\n        /// </summary>\r\n        /// <returns>representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task RepairExeInstallerWithUninstallerBehavior()\r\n        {\r\n            string replaceInstallerArguments = this.GetReplacementArguments(this.installDir, \"2.0.0.0\", \"UninstallerRepair\", useHKLM: true);\r\n            var searchResult = await this.FindAndInstallPackage(\"AppInstallerTest.UninstallerRepair\", this.installDir, replaceInstallerArguments);\r\n\r\n            // Repair the package\r\n            await this.RepairPackageAndValidateStatus(searchResult.CatalogPackage, this.TestFactory.CreateRepairOptions(), RepairResultStatus.Ok);\r\n\r\n            // Cleanup\r\n            Assert.True(TestCommon.VerifyTestExeRepairCompletedAndCleanup(this.installDir, \"Uninstaller Repair operation\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test repair of a Exe installer that has a \"uninstaller\" repair behavior specified in the manifest and NoRepair ARP flag set.\r\n        /// </summary>\r\n        /// <returns>representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task RepairExeInstallerWithUninstallerBehaviorAndNoRepairFlag()\r\n        {\r\n            string replaceInstallerArguments = this.GetReplacementArguments(this.installDir, \"2.0.0.0\", \"UninstallerRepairWithNoRepair\", useHKLM: true, noRepair: true);\r\n            var searchResult = await this.FindAndInstallPackage(\"AppInstallerTest.UninstallerRepairWithNoRepair\", this.installDir, replaceInstallerArguments);\r\n\r\n            // Repair the package\r\n            await this.RepairPackageAndValidateStatus(searchResult.CatalogPackage, this.TestFactory.CreateRepairOptions(), RepairResultStatus.RepairError, Constants.ErrorCode.ERROR_REPAIR_NOT_SUPPORTED);\r\n\r\n            // Cleanup\r\n            TestCommon.CleanupTestExeAndDirectory(this.installDir);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test repair of a Nullsoft installer that has a \"uninstaller\" repair behavior specified in the manifest.\r\n        /// </summary>\r\n        /// <returns>representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task RepairNullsoftInstallerWithUninstallerBehavior()\r\n        {\r\n            string replaceInstallerArguments = this.GetReplacementArguments(this.installDir, \"2.0.0.0\", \"NullsoftUninstallerRepair\", useHKLM: true);\r\n            var searchResult = await this.FindAndInstallPackage(\"AppInstallerTest.NullsoftUninstallerRepair\", this.installDir, replaceInstallerArguments.ToString());\r\n\r\n            // Repair the package\r\n            await this.RepairPackageAndValidateStatus(searchResult.CatalogPackage, this.TestFactory.CreateRepairOptions(), RepairResultStatus.Ok);\r\n\r\n            // Cleanup\r\n            Assert.True(TestCommon.VerifyTestExeRepairCompletedAndCleanup(this.installDir, \"Uninstaller Repair operation\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test repair of a Inno installer that has a \"installer\" repair behavior specified in the manifest.\r\n        /// </summary>\r\n        /// <returns>representing the asynchronous unit test.</returns>\r\n        [Test]\r\n        public async Task RepairInnoInstallerWithInstallerRepairBehavior()\r\n        {\r\n            string replaceInstallerArguments = this.GetReplacementArguments(this.installDir, \"2.0.0.0\", \"TestInstallerRepair\", useHKLM: true);\r\n            var searchResult = await this.FindAndInstallPackage(\"AppInstallerTest.TestInstallerRepair\", this.installDir, replaceInstallerArguments);\r\n\r\n            // Repair the package\r\n            await this.RepairPackageAndValidateStatus(searchResult.CatalogPackage, this.TestFactory.CreateRepairOptions(), RepairResultStatus.Ok);\r\n\r\n            // Cleanup\r\n            Assert.True(TestCommon.VerifyTestExeRepairCompletedAndCleanup(this.installDir, \"Installer Repair operation\"));\r\n        }\r\n\r\n        private async Task<MatchResult> FindAndInstallPackage(string packageId, string installDir, string replacementInstallerArguments)\r\n        {\r\n            // Find a package\r\n            var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId);\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n            installOptions.PackageInstallMode = PackageInstallMode.Silent;\r\n\r\n            if (!string.IsNullOrEmpty(installDir))\r\n            {\r\n                installOptions.PreferredInstallLocation = installDir;\r\n            }\r\n\r\n            if (!string.IsNullOrEmpty(replacementInstallerArguments))\r\n            {\r\n                installOptions.ReplacementInstallerArguments = replacementInstallerArguments;\r\n            }\r\n\r\n            // Install the package\r\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\r\n\r\n            // Find package again, but this time it should be detected as installed\r\n            searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId);\r\n            Assert.NotNull(searchResult.CatalogPackage.InstalledVersion);\r\n\r\n            // Return the search result\r\n            return searchResult;\r\n        }\r\n\r\n        private async Task RepairPackageAndValidateStatus(CatalogPackage package, RepairOptions repairOptions, RepairResultStatus expectedStatus, int expectedErrorCode = 0)\r\n        {\r\n            var repairResult = await this.packageManager.RepairPackageAsync(package, repairOptions);\r\n            Assert.AreEqual(expectedStatus, repairResult.Status);\r\n\r\n            if (expectedStatus != RepairResultStatus.Ok)\r\n            {\r\n                Assert.AreEqual(expectedErrorCode, repairResult.ExtendedErrorCode.HResult);\r\n            }\r\n        }\r\n\r\n        private string GetReplacementArguments(string installDir, string version, string displayName, bool useHKLM = false, bool noModify = false, bool noRepair = false)\r\n        {\r\n            var replacementArguments = new StringBuilder($\"/InstallDir {installDir} /Version {version} /DisplayName {displayName}\");\r\n\r\n            // Machine scope install.\r\n            if (useHKLM)\r\n            {\r\n                replacementArguments.Append($\" /UseHKLM\");\r\n            }\r\n\r\n            // Instructs test installer to set NoModify ARP flag.\r\n            if (noModify)\r\n            {\r\n                replacementArguments.Append($\" /NoModify\");\r\n            }\r\n\r\n            // Instructs test installer to set NoRepair ARP flag.\r\n            if (noRepair)\r\n            {\r\n                replacementArguments.Append($\" /NoRepair\");\r\n            }\r\n\r\n            return replacementArguments.ToString();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/Interop/Shutdown.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"Shutdown.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests.Interop\r\n{\r\n    using System;\r\n    using System.Threading.Tasks;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.Management.Deployment.Projection;\r\n    using NUnit.Framework;\r\n    using WinGetTestCommon;\r\n\r\n    /// <summary>\r\n    /// Shutdown testing.\r\n    /// </summary>\r\n    [TestFixtureSource(typeof(InstanceInitializersSource), nameof(InstanceInitializersSource.OutOfProcess), Category = nameof(InstanceInitializersSource.OutOfProcess))]\r\n    public class Shutdown : BaseInterop\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"Shutdown\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"initializer\">Initializer.</param>\r\n        public Shutdown(IInstanceInitializer initializer)\r\n            : base(initializer)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Checks that shutdown will proceed even though an object is active.\r\n        /// </summary>\r\n        [Test]\r\n        public void NoActiveOperations()\r\n        {\r\n            var packageManager = this.TestFactory.CreatePackageManager();\r\n\r\n            var servers = WinGetServerInstance.GetInstances();\r\n            Assert.AreEqual(1, servers.Count);\r\n\r\n            var server = servers[0];\r\n            Assert.IsTrue(server.HasWindow);\r\n\r\n            // This is the call pattern from Windows\r\n            this.SendMessageAndLog(server, WindowMessage.QueryEndSession);\r\n            this.SendMessageAndLog(server, WindowMessage.EndSession);\r\n            this.SendMessageAndLog(server, WindowMessage.Close);\r\n\r\n            Assert.IsTrue(server.Process.WaitForExit(5000));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Checks that shutdown will proceed even though an operation is active.\r\n        /// </summary>\r\n        /// <returns>The task.</returns>\r\n        [Test]\r\n        public async Task ActiveInstallOperation()\r\n        {\r\n            var packageManager = this.TestFactory.CreatePackageManager();\r\n            var testSource = packageManager.GetPackageCatalogByName(Constants.TestSourceName);\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n\r\n            var servers = WinGetServerInstance.GetInstances();\r\n            Assert.AreEqual(1, servers.Count);\r\n\r\n            var server = servers[0];\r\n            Assert.IsTrue(server.HasWindow);\r\n\r\n            // Find package\r\n            var searchResult = this.FindOnePackage(testSource, PackageMatchField.Name, PackageFieldMatchOption.Equals, \"InapplicableOsVersion\");\r\n\r\n            // Configure installation\r\n            var installOptions = this.TestFactory.CreateInstallOptions();\r\n            installOptions.PackageInstallMode = PackageInstallMode.Silent;\r\n            installOptions.PreferredInstallLocation = installDir;\r\n\r\n            // Install\r\n            var installOperation = packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\r\n\r\n            // This is the call pattern from Windows\r\n            this.SendMessageAndLog(server, WindowMessage.QueryEndSession);\r\n            this.SendMessageAndLog(server, WindowMessage.EndSession);\r\n            this.SendMessageAndLog(server, WindowMessage.Close);\r\n\r\n            Assert.IsTrue(server.Process.WaitForExit(5000));\r\n\r\n            InstallResult installResult = null;\r\n            Exception exception = null;\r\n\r\n            try\r\n            {\r\n                installResult = await installOperation;\r\n            }\r\n            catch (Exception ex)\r\n            {\r\n                exception = ex;\r\n            }\r\n\r\n            // We just expect some kind of signal to indicate the failed attempt.\r\n            if (installResult != null)\r\n            {\r\n                Assert.AreNotEqual(InstallResultStatus.Ok, installResult.Status);\r\n            }\r\n            else\r\n            {\r\n                Assert.NotNull(exception);\r\n            }\r\n\r\n            Assert.False(TestCommon.VerifyTestExeInstalledAndCleanup(installDir));\r\n        }\r\n\r\n        private void SendMessageAndLog(WinGetServerInstance server, WindowMessage message)\r\n        {\r\n            TestContext.Out.WriteLine($\"Sending message {message} to process {server.Process.Id}...\");\r\n            try\r\n            {\r\n                if (server.SendMessage(message))\r\n                {\r\n                    TestContext.Out.WriteLine(\"... succeeded.\");\r\n                }\r\n                else\r\n                {\r\n                    TestContext.Out.WriteLine(\"... failed.\");\r\n                }\r\n            }\r\n            catch (Exception e)\r\n            {\r\n                TestContext.Out.WriteLine($\"... had exception: {e.Message}\");\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/Interop/UninstallInterop.cs",
    "content": "// -----------------------------------------------------------------------------\n// <copyright file=\"UninstallInterop.cs\" company=\"Microsoft Corporation\">\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\n// </copyright>\n// -----------------------------------------------------------------------------\n\nnamespace AppInstallerCLIE2ETests.Interop\n{\n    using System;\n    using System.IO;\n    using System.Threading.Tasks;\n    using AppInstallerCLIE2ETests.Helpers;\n    using Microsoft.Management.Deployment;\n    using Microsoft.Management.Deployment.Projection;\n    using NUnit.Framework;\n\n    /// <summary>\n    /// Test uninstall interop.\n    /// </summary>\n    [TestFixtureSource(typeof(InstanceInitializersSource), nameof(InstanceInitializersSource.InProcess), Category = nameof(InstanceInitializersSource.InProcess))]\n    [TestFixtureSource(typeof(InstanceInitializersSource), nameof(InstanceInitializersSource.OutOfProcess), Category = nameof(InstanceInitializersSource.OutOfProcess))]\n    public class UninstallInterop : BaseInterop\n    {\n        private string installDir;\n        private PackageManager packageManager;\n        private PackageCatalogReference compositeSource;\n\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"UninstallInterop\"/> class.\n        /// </summary>\n        /// <param name=\"initializer\">Initializer.</param>\n        public UninstallInterop(IInstanceInitializer initializer)\n            : base(initializer)\n        {\n        }\n\n        /// <summary>\n        /// Set up.\n        /// </summary>\n        [SetUp]\n        public void Init()\n        {\n            this.packageManager = this.TestFactory.CreatePackageManager();\n            this.installDir = TestCommon.GetRandomTestDir();\n\n            // Create composite package catalog source\n            var options = this.TestFactory.CreateCreateCompositePackageCatalogOptions();\n            var testSource = this.packageManager.GetPackageCatalogByName(Constants.TestSourceName);\n            Assert.NotNull(testSource, $\"{Constants.TestSourceName} cannot be null\");\n            options.Catalogs.Add(testSource);\n            options.CompositeSearchBehavior = CompositeSearchBehavior.AllCatalogs;\n            this.compositeSource = this.packageManager.CreateCompositePackageCatalog(options);\n        }\n\n        /// <summary>\n        /// Test uninstall exe.\n        /// </summary>\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\n        [Test]\n        public async Task UninstallTestExe()\n        {\n            // Find package\n            var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, Constants.ExeInstallerPackageId);\n\n            // Configure installation\n            var installOptions = this.TestFactory.CreateInstallOptions();\n            installOptions.PackageInstallMode = PackageInstallMode.Silent;\n            installOptions.PreferredInstallLocation = this.installDir;\n\n            // Install\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\n\n            // Find package again, but this time it should detect the installed version\n            searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, Constants.ExeInstallerPackageId);\n            Assert.NotNull(searchResult.CatalogPackage.InstalledVersion);\n\n            // Uninstall\n            var uninstallResult = await this.packageManager.UninstallPackageAsync(searchResult.CatalogPackage, this.TestFactory.CreateUninstallOptions());\n            Assert.AreEqual(UninstallResultStatus.Ok, uninstallResult.Status);\n            Assert.True(TestCommon.VerifyTestExeUninstalled(this.installDir));\n        }\n\n        /// <summary>\n        /// Test uninstall msi.\n        /// </summary>\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\n        [Test]\n        public async Task UninstallTestMsi()\n        {\n            if (string.IsNullOrEmpty(TestIndex.MsiInstaller))\n            {\n                Assert.Ignore(\"MSI installer not available\");\n            }\n\n            // Find package\n            var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, Constants.MsiInstallerPackageId);\n\n            // Configure installation\n            var installOptions = this.TestFactory.CreateInstallOptions();\n            installOptions.PreferredInstallLocation = this.installDir;\n\n            // Install\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\n\n            // Find package again, but this time it should detect the installed version\n            searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, Constants.MsiInstallerPackageId);\n            Assert.NotNull(searchResult.CatalogPackage.InstalledVersion);\n\n            // Uninstall\n            var uninstallResult = await this.packageManager.UninstallPackageAsync(searchResult.CatalogPackage, this.TestFactory.CreateUninstallOptions());\n            Assert.AreEqual(UninstallResultStatus.Ok, uninstallResult.Status);\n            Assert.True(TestCommon.VerifyTestMsiUninstalled(this.installDir));\n        }\n\n        /// <summary>\n        /// Test uninstall msix.\n        /// </summary>\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\n        [Test]\n        public async Task UninstallTestMsix()\n        {\n            // Find package\n            var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, Constants.MsixInstallerPackageId);\n\n            // Configure installation\n            var installOptions = this.TestFactory.CreateInstallOptions();\n\n            // Install\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\n\n            // Find package again, but this time it should detect the installed version\n            searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, Constants.MsixInstallerPackageId);\n            Assert.NotNull(searchResult.CatalogPackage.InstalledVersion);\n\n            // Uninstall\n            var uninstallResult = await this.packageManager.UninstallPackageAsync(searchResult.CatalogPackage, this.TestFactory.CreateUninstallOptions());\n            Assert.AreEqual(UninstallResultStatus.Ok, uninstallResult.Status);\n            Assert.True(TestCommon.VerifyTestMsixUninstalled());\n        }\n\n        /// <summary>\n        /// Test uninstall msix with machine scope.\n        /// </summary>\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\n        [Test]\n        public async Task UninstallTestMsixMachineScope()\n        {\n            // TODO: Provision and Deprovision api not supported in build server.\n            Assert.Ignore();\n\n            // Find package\n            var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, Constants.MsixInstallerPackageId);\n\n            // Configure installation\n            var installOptions = this.TestFactory.CreateInstallOptions();\n            installOptions.PackageInstallScope = PackageInstallScope.System;\n\n            // Install\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\n\n            // Find package again, but this time it should detect the installed version\n            searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, Constants.MsixInstallerPackageId);\n            Assert.NotNull(searchResult.CatalogPackage.InstalledVersion);\n\n            // Uninstall\n            var uninstallOptions = this.TestFactory.CreateUninstallOptions();\n            uninstallOptions.PackageUninstallScope = PackageUninstallScope.System;\n\n            var uninstallResult = await this.packageManager.UninstallPackageAsync(searchResult.CatalogPackage, uninstallOptions);\n            Assert.AreEqual(UninstallResultStatus.Ok, uninstallResult.Status);\n            Assert.True(TestCommon.VerifyTestMsixUninstalled(true));\n        }\n\n        /// <summary>\n        /// Test uninstall portable package.\n        /// </summary>\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\n        [Test]\n        public async Task UninstallPortable()\n        {\n            string installDir = Path.Combine(Environment.GetEnvironmentVariable(Constants.LocalAppData), \"Microsoft\", \"WinGet\", \"Packages\");\n            string packageDirName = Constants.PortableExePackageDirName;\n            string productCode = Constants.PortableExePackageDirName;\n            string commandAlias = Constants.AppInstallerTestExeInstallerExe;\n            string fileName = Constants.AppInstallerTestExeInstallerExe;\n\n            // Find package\n            var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, Constants.PortableExePackageId);\n\n            // Configure installation\n            var installOptions = this.TestFactory.CreateInstallOptions();\n\n            // Install\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\n\n            // Find package again, but this time it should detect the installed version\n            searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, Constants.PortableExePackageId);\n            Assert.NotNull(searchResult.CatalogPackage.InstalledVersion);\n\n            // Uninstall\n            var uninstallResult = await this.packageManager.UninstallPackageAsync(searchResult.CatalogPackage, this.TestFactory.CreateUninstallOptions());\n            Assert.AreEqual(UninstallResultStatus.Ok, uninstallResult.Status);\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, false);\n        }\n\n        /// <summary>\n        /// Test uninstall portable package with product code.\n        /// </summary>\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\n        [Test]\n        public async Task UninstallPortableWithProductCode()\n        {\n            string installDir = Path.Combine(Environment.GetEnvironmentVariable(Constants.LocalAppData), \"Microsoft\", \"WinGet\", \"Packages\");\n            string packageDirName = Constants.PortableExePackageDirName;\n            string productCode = Constants.PortableExePackageDirName;\n            string commandAlias = Constants.AppInstallerTestExeInstallerExe;\n            string fileName = Constants.AppInstallerTestExeInstallerExe;\n\n            // Find package\n            var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, Constants.PortableExePackageId);\n\n            // Configure installation\n            var installOptions = this.TestFactory.CreateInstallOptions();\n\n            // Install\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\n\n            // Find package again, but this time it should detect the installed version\n            searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.ProductCode, PackageFieldMatchOption.Equals, productCode);\n            Assert.NotNull(searchResult.CatalogPackage.InstalledVersion);\n\n            // Uninstall\n            var uninstallResult = await this.packageManager.UninstallPackageAsync(searchResult.CatalogPackage, this.TestFactory.CreateUninstallOptions());\n            Assert.AreEqual(UninstallResultStatus.Ok, uninstallResult.Status);\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, false);\n        }\n\n        /// <summary>\n        /// Test uninstall portable package modified symlink.\n        /// </summary>\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\n        [Test]\n        public async Task UninstallPortableModifiedSymlink()\n        {\n            string packageId = Constants.PortableExePackageId;\n            string commandAlias = Constants.AppInstallerTestExeInstallerExe;\n            string symlinkDirectory = Path.Combine(Environment.GetEnvironmentVariable(Constants.LocalAppData), \"Microsoft\", \"WinGet\", \"Links\");\n            string symlinkPath = Path.Combine(symlinkDirectory, commandAlias);\n\n            // Find package\n            var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId);\n\n            // Configure installation\n            var installOptions = this.TestFactory.CreateInstallOptions();\n\n            // Install\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\n\n            // Replace symlink with modified symlink\n            File.Delete(symlinkPath);\n            FileSystemInfo modifiedSymlinkInfo = File.CreateSymbolicLink(symlinkPath, \"fakeTargetExe\");\n\n            // Find package again, but this time it should detect the installed version\n            searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId);\n            Assert.NotNull(searchResult.CatalogPackage.InstalledVersion);\n\n            // Uninstall\n            var uninstallResult = await this.packageManager.UninstallPackageAsync(searchResult.CatalogPackage, this.TestFactory.CreateUninstallOptions());\n            Assert.AreEqual(UninstallResultStatus.UninstallError, uninstallResult.Status);\n            Assert.True(modifiedSymlinkInfo.Exists, \"Modified symlink should still exist\");\n\n            // Remove modified symlink as to not interfere with other tests\n            modifiedSymlinkInfo.Delete();\r\n\r\n            // Uninstall again to clean up.\n            await this.packageManager.UninstallPackageAsync(searchResult.CatalogPackage, this.TestFactory.CreateUninstallOptions());\n        }\n\n        /// <summary>\n        /// Test uninstall not indexed.\n        /// </summary>\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\n        [Test]\n        public async Task UninstallNotIndexed()\n        {\n            const string customProductCode = \"{f08fc03c-0b7e-4fca-9b3c-3a384d18a9f3}\";\n\n            // Find package\n            var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, Constants.ExeInstallerPackageId);\n\n            // Configure installation\n            var installOptions = this.TestFactory.CreateInstallOptions();\n            installOptions.ReplacementInstallerArguments = $\"/ProductID {customProductCode} /InstallDir {this.installDir}\";\n\n            // Install\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\n\n            // Find package again, but this time it should detect the installed version\n            searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.ProductCode, PackageFieldMatchOption.Equals, customProductCode);\n            Assert.NotNull(searchResult.CatalogPackage.InstalledVersion);\n\n            // Uninstall\n            var uninstallResult = await this.packageManager.UninstallPackageAsync(searchResult.CatalogPackage, this.TestFactory.CreateUninstallOptions());\n            Assert.AreEqual(UninstallResultStatus.Ok, uninstallResult.Status);\n            Assert.True(TestCommon.VerifyTestExeUninstalled(this.installDir));\n        }\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/Interop/UpgradeInterop.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"UpgradeInterop.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests.Interop\n{\n    using System;\n    using System.Collections.Generic;\n    using System.IO;\r\n    using System.Linq;\r\n    using System.Threading.Tasks;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using Microsoft.Management.Deployment;\n    using Microsoft.Management.Deployment.Projection;\n    using NUnit.Framework;\n\n    /// <summary>\r\n    /// Test upgrade interop.\r\n    /// </summary>\n    [TestFixtureSource(typeof(InstanceInitializersSource), nameof(InstanceInitializersSource.InProcess), Category = nameof(InstanceInitializersSource.InProcess))]\n    [TestFixtureSource(typeof(InstanceInitializersSource), nameof(InstanceInitializersSource.OutOfProcess), Category = nameof(InstanceInitializersSource.OutOfProcess))]\n    public class UpgradeInterop : BaseInterop\n    {\n        private PackageManager packageManager;\n        private PackageCatalogReference compositeSource;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"UpgradeInterop\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"initializer\">Initializer.</param>\r\n        public UpgradeInterop(IInstanceInitializer initializer)\n            : base(initializer)\n        {\n        }\n\n        /// <summary>\r\n        /// Set up.\r\n        /// </summary>\n        [SetUp]\n        public void Init()\n        {\n            this.packageManager = this.TestFactory.CreatePackageManager();\n\n            // Create composite package catalog source\n            var options = this.TestFactory.CreateCreateCompositePackageCatalogOptions();\n            var testSource = this.packageManager.GetPackageCatalogByName(Constants.TestSourceName);\n            Assert.NotNull(testSource, $\"{Constants.TestSourceName} cannot be null\");\n            options.Catalogs.Add(testSource);\n            options.CompositeSearchBehavior = CompositeSearchBehavior.AllCatalogs;\n            this.compositeSource = this.packageManager.CreateCompositePackageCatalog(options);\n        }\r\n\r\n        /// <summary>\r\n        /// Tests upgrade portable package.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\n        [Test]\n        public async Task UpgradePortable()\n        {\n            string installDir = Path.Combine(Environment.GetEnvironmentVariable(Constants.LocalAppData), \"Microsoft\", \"WinGet\", \"Packages\");\n            string packageId = Constants.PortableExePackageId;\n            string packageDirName = Constants.PortableExePackageDirName;\n            string productCode = Constants.PortableExePackageDirName;\n            string commandAlias = Constants.AppInstallerTestExeInstallerExe;\n            string fileName = Constants.AppInstallerTestExeInstallerExe;\n\n            // Find package\n            var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId);\n\n            // Configure install options\n            var installOptions = this.TestFactory.CreateInstallOptions();\n            installOptions.PackageVersionId = First(searchResult.CatalogPackage.AvailableVersions, i => i.Version == \"1.0.0.0\");\n\n            // Install\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\n\n            // Find package again, but this time it should detect the installed version\n            searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId);\n            Assert.AreEqual(\"1.0.0.0\", searchResult.CatalogPackage.InstalledVersion?.Version);\n\n            // Configure upgrade options\n            var upgradeOptions = this.TestFactory.CreateInstallOptions();\n            upgradeOptions.PackageVersionId = First(searchResult.CatalogPackage.AvailableVersions, i => i.Version == \"2.0.0.0\");\n\n            // Upgrade\n            var upgradeResult = await this.packageManager.UpgradePackageAsync(searchResult.CatalogPackage, upgradeOptions);\n            Assert.AreEqual(InstallResultStatus.Ok, upgradeResult.Status);\n\n            // Find package again, but this time it should detect the upgraded installed version\n            searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId);\n            Assert.AreEqual(\"2.0.0.0\", searchResult.CatalogPackage.InstalledVersion?.Version);\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true);\n        }\n\n        /// <summary>\r\n        /// Test upgrade portable package with arp mismatch.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\n        [Test]\n        public async Task UpgradePortableARPMismatch()\n        {\n            string installDir = Path.Combine(Environment.GetEnvironmentVariable(Constants.LocalAppData), \"Microsoft\", \"WinGet\", \"Packages\");\n            string packageId = Constants.PortableExePackageId;\n            string packageDirName = Constants.PortableExePackageDirName;\n            string productCode = Constants.PortableExePackageDirName;\n            string commandAlias = Constants.AppInstallerTestExeInstallerExe;\n            string fileName = Constants.AppInstallerTestExeInstallerExe;\n\n            // Find package\n            var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId);\n\n            // Configure install options\n            var installOptions = this.TestFactory.CreateInstallOptions();\n            installOptions.PackageVersionId = First(searchResult.CatalogPackage.AvailableVersions, i => i.Version == \"1.0.0.0\");\n\n            // Install\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\n\n            // Modify packageId to cause mismatch.\n            TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetPackageIdentifier, \"testPackageId\");\n\n            // Find package again, but this time it should detect the installed version\n            searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId);\n            Assert.NotNull(searchResult.CatalogPackage.InstalledVersion);\n\n            // Configure upgrade options\n            var upgradeOptions = this.TestFactory.CreateInstallOptions();\n            upgradeOptions.PackageVersionId = First(searchResult.CatalogPackage.AvailableVersions, i => i.Version == \"2.0.0.0\");\n\n            // Upgrade\n            var upgradeResult = await this.packageManager.UpgradePackageAsync(searchResult.CatalogPackage, upgradeOptions);\n            Assert.AreEqual(InstallResultStatus.InstallError, upgradeResult.Status);\n            Assert.AreEqual(Constants.ErrorCode.ERROR_PORTABLE_PACKAGE_ALREADY_EXISTS, upgradeResult.ExtendedErrorCode.HResult);\n\n            // Find package again, it should have not been upgraded\n            searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId);\n            Assert.AreEqual(\"1.0.0.0\", searchResult.CatalogPackage.InstalledVersion.Version);\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true);\n        }\n\n        /// <summary>\r\n        /// Test upgrade portable package force.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\n        [Test]\n        public async Task UpgradePortableForcedOverride()\n        {\n            string installDir = Path.Combine(Environment.GetEnvironmentVariable(Constants.LocalAppData), \"Microsoft\", \"WinGet\", \"Packages\");\n            string packageId = Constants.PortableExePackageId;\n            string packageDirName = Constants.PortableExePackageDirName;\n            string productCode = Constants.PortableExePackageDirName;\n            string commandAlias = Constants.AppInstallerTestExeInstallerExe;\n            string fileName = Constants.AppInstallerTestExeInstallerExe;\n\n            // Find package\n            var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId);\n\n            // Configure install options\n            var installOptions = this.TestFactory.CreateInstallOptions();\n            installOptions.PackageVersionId = First(searchResult.CatalogPackage.AvailableVersions, i => i.Version == \"1.0.0.0\");\n\n            // Install\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\n\n            // Modify packageId and sourceId to cause mismatch.\n            TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetPackageIdentifier, \"testPackageId\");\n            TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetSourceIdentifier, \"testSourceId\");\n\n            // Find package again, but this time it should detect the installed version\n            searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId);\n            Assert.NotNull(searchResult.CatalogPackage.InstalledVersion);\n\n            // Configure upgrade options\n            var upgradeOptions = this.TestFactory.CreateInstallOptions();\n            upgradeOptions.PackageVersionId = First(searchResult.CatalogPackage.AvailableVersions, i => i.Version == \"2.0.0.0\");\n            upgradeOptions.Force = true;\n\n            // Upgrade\n            var upgradeResult = await this.packageManager.UpgradePackageAsync(searchResult.CatalogPackage, upgradeOptions);\n            Assert.AreEqual(InstallResultStatus.Ok, upgradeResult.Status);\n\n            // Find package again, but this time it should detect the upgraded installed version\n            searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId);\n            Assert.AreEqual(\"2.0.0.0\", searchResult.CatalogPackage.InstalledVersion.Version);\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true);\n        }\n\n        /// <summary>\r\n        /// Test upgrade portable package uninstall previous.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\n        [Test]\n        public async Task UpgradePortableUninstallPrevious()\n        {\n            string installDir = Path.Combine(Environment.GetEnvironmentVariable(Constants.LocalAppData), \"Microsoft\", \"WinGet\", \"Packages\");\n            string packageId = Constants.PortableExePackageId;\n            string packageDirName = Constants.PortableExePackageDirName;\n            string productCode = Constants.PortableExePackageDirName;\n            string commandAlias = Constants.AppInstallerTestExeInstallerExe;\n            string fileName = Constants.AppInstallerTestExeInstallerExe;\n\n            // Find package\n            var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId);\n\n            // Configure install options\n            var installOptions = this.TestFactory.CreateInstallOptions();\n            installOptions.PackageVersionId = First(searchResult.CatalogPackage.AvailableVersions, i => i.Version == \"1.0.0.0\");\n\n            // Install\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\n\n            // Find package again, but this time it should detect the installed version\n            searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId);\n            Assert.AreEqual(\"1.0.0.0\", searchResult.CatalogPackage.InstalledVersion.Version);\n\n            // Configure upgrade options\n            var upgradeOptions = this.TestFactory.CreateInstallOptions();\n            upgradeOptions.PackageVersionId = First(searchResult.CatalogPackage.AvailableVersions, i => i.Version == \"3.0.0.0\");\n\n            // Upgrade\n            var upgradeResult = await this.packageManager.UpgradePackageAsync(searchResult.CatalogPackage, upgradeOptions);\n            Assert.AreEqual(InstallResultStatus.Ok, upgradeResult.Status);\n\n            // Find package again, but this time it should detect the upgraded installed version\n            searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, packageId);\n            Assert.AreEqual(\"3.0.0.0\", searchResult.CatalogPackage.InstalledVersion.Version);\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true);\n        }\r\n\r\n        /// <summary>\r\n        /// Tests IsUpdateAvailable.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\n        [Test]\n        public async Task TestIsUpdateAvailable_ApplicableTrue()\n        {\r\n            // Find and install the test package. Install the version 1.0.0.0.\r\n            var installDir = TestCommon.GetRandomTestDir();\n            var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestExeInstaller\");\n            var installOptions = this.TestFactory.CreateInstallOptions();\n            installOptions.PreferredInstallLocation = installDir;\r\n            installOptions.PackageVersionId = First(searchResult.CatalogPackage.AvailableVersions, i => i.Version == \"1.0.0.0\");\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\r\n\r\n            // Find package again, but this time it should detect the installed version.\r\n            searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestExeInstaller\");\r\n\r\n            // The installed version is 1.0.0.0.\n            Assert.AreEqual(\"1.0.0.0\", searchResult.CatalogPackage.InstalledVersion.Version);\r\n\r\n            // IsUpdateAvailable is true.\r\n            Assert.True(searchResult.CatalogPackage.IsUpdateAvailable);\r\n\r\n            // Uninstall to clean up.\r\n            var uninstallOptions = this.TestFactory.CreateUninstallOptions();\r\n            var uninstallResult = await this.packageManager.UninstallPackageAsync(searchResult.CatalogPackage, uninstallOptions);\n        }\r\n\r\n        /// <summary>\r\n        /// Tests applicability check is performed for IsUpdateAvailable api.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\n        [Test]\n        public async Task TestIsUpdateAvailable_ApplicableFalse()\n        {\r\n            // Find and install the test package. Install the version 1.0.0.0.\r\n            var installDir = TestCommon.GetRandomTestDir();\n            var searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestUpgradeApplicability\");\n            var installOptions = this.TestFactory.CreateInstallOptions();\n            installOptions.PreferredInstallLocation = installDir;\r\n            installOptions.PackageVersionId = First(searchResult.CatalogPackage.AvailableVersions, i => i.Version == \"1.0.0.0\");\n            var installResult = await this.packageManager.InstallPackageAsync(searchResult.CatalogPackage, installOptions);\n            Assert.AreEqual(InstallResultStatus.Ok, installResult.Status);\r\n\r\n            // Find package again, but this time it should detect the installed version.\r\n            searchResult = this.FindOnePackage(this.compositeSource, PackageMatchField.Id, PackageFieldMatchOption.Equals, \"AppInstallerTest.TestUpgradeApplicability\");\r\n\r\n            // The installed version is 1.0.0.0.\n            Assert.AreEqual(\"1.0.0.0\", searchResult.CatalogPackage.InstalledVersion.Version);\r\n\r\n            // There is version 2.0.0.0 in the package available versions.\r\n            Assert.NotNull(First(searchResult.CatalogPackage.AvailableVersions, i => i.Version == \"2.0.0.0\"));\r\n\r\n            // IsUpdateAvailable is false due to applicability check. Only arm64 in version 2.0.0.0.\r\n            Assert.False(searchResult.CatalogPackage.IsUpdateAvailable);\r\n\r\n            // Uninstall to clean up.\r\n            var uninstallOptions = this.TestFactory.CreateUninstallOptions();\r\n            var uninstallResult = await this.packageManager.UninstallPackageAsync(searchResult.CatalogPackage, uninstallOptions);\n        }\n\n        // Cannot use foreach or Linq for out-of-process IVector\n        // Bug: https://github.com/microsoft/CsWinRT/issues/1205\n        private static T First<T>(IReadOnlyList<T> list, Func<T, bool> condition)\n        {\n            if (list == null || condition == null)\n            {\n                throw new ArgumentNullException();\n            }\n\n            for (int i = 0; i < list.Count; ++i)\n            {\n                var item = list[i];\n                if (condition(item))\n                {\n                    return item;\n                }\n            }\n\n            throw new InvalidOperationException(\"No element satisfies the condition\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/ListCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ListCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using System.IO;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// List command tests.\r\n    /// </summary>\r\n    public class ListCommand : BaseCommand\r\n    {\r\n        /// <summary>\r\n        /// Test list winget.\r\n        /// </summary>\r\n        [Test]\r\n        public void ListSelf()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"list\", Constants.AICLIPackageFamilyName);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(Constants.AICLIPackageName));\r\n            Assert.True(result.StdOut.Contains(Constants.AICLIPackagePublisherHash));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test list after installing a package.\r\n        /// </summary>\r\n        [Test]\r\n        public void ListAfterInstall()\r\n        {\r\n            System.Guid guid = System.Guid.NewGuid();\r\n            string productCode = guid.ToString();\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n\r\n            // DisplayName must be set to avoid conflicts with other packages that use the same exe installer.\r\n            string displayName = \"TestExeInstaller\";\r\n            string localAppDataPath = System.Environment.GetEnvironmentVariable(Constants.LocalAppData);\r\n            string logFilePath = System.IO.Path.Combine(localAppDataPath, Constants.E2ETestLogsPathPackaged);\r\n            logFilePath = System.IO.Path.Combine(logFilePath, \"ListAfterInstall-\" + System.IO.Path.GetRandomFileName() + \".log\");\r\n\r\n            var result = TestCommon.RunAICLICommand(\"list\", productCode);\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode);\r\n\r\n            result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestExeInstaller --override \\\"/InstallDir {installDir} /ProductID {productCode} /LogFile {logFilePath} /DisplayName {displayName}\\\"\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n\r\n            result = TestCommon.RunAICLICommand(\"list\", productCode);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"AppInstallerTest.TestExeInstaller\"));\r\n            Assert.True(result.StdOut.Contains(\"1.0.0.0\"));\r\n            Assert.True(result.StdOut.Contains(\"2.0.0.0\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test expected entries after list.\r\n        /// </summary>\r\n        [Test]\r\n        public void ListWithArpVersionMapping()\r\n        {\r\n            // No mapping performed\r\n            this.ArpVersionMappingTest(\"AppInstallerTest.TestArpVersionSameVersion\", \"TestArpVersionSameVersion\", \"0.5\", \"0.5\", \"< 1.0\");\r\n\r\n            // Partial mapping performed(i.e. only if version falls within arp version range)\r\n            this.ArpVersionMappingTest(\"AppInstallerTest.TestArpVersionOppositeOrder\", \"TestArpVersionOppositeOrder\", \"10.1\", \"1.0\", \"10.1\");\r\n            this.ArpVersionMappingTest(\"AppInstallerTest.TestArpVersionOppositeOrder\", \"TestArpVersionOppositeOrder\", \"9.9\", \"9.9\", \"> 2.0\");\r\n\r\n            // Full mapping performed\r\n            this.ArpVersionMappingTest(\"AppInstallerTest.TestArpVersionSameOrder\", \"TestArpVersionSameOrder\", \"7.0\", \"< 1.0\", \"7.0\");\r\n            this.ArpVersionMappingTest(\"AppInstallerTest.TestArpVersionSameOrder\", \"TestArpVersionSameOrder\", \"10.1\", \"1.0\", \"10.1\");\r\n            this.ArpVersionMappingTest(\"AppInstallerTest.TestArpVersionSameOrder\", \"TestArpVersionSameOrder\", \"10.7\", \"< 2.0\", \"10.7\");\r\n            this.ArpVersionMappingTest(\"AppInstallerTest.TestArpVersionSameOrder\", \"TestArpVersionSameOrder\", \"11.1\", \"2.0\", \"11.1\");\r\n            this.ArpVersionMappingTest(\"AppInstallerTest.TestArpVersionSameOrder\", \"TestArpVersionSameOrder\", \"12.0\", \"> 2.0\", \"12.0\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test list with upgrade code.\r\n        /// </summary>\r\n        [Test]\r\n        public void ListWithUpgradeCode()\r\n        {\r\n            // Installs the MSI installer using the TestMsiInstaller package.\r\n            // Then tries listing the TestMsiInstallerUpgradeCode package, which should\r\n            // be correlated to it by the UpgradeCode.\r\n            if (string.IsNullOrEmpty(TestIndex.MsiInstaller))\r\n            {\r\n                Assert.Ignore(\"MSI installer not available\");\r\n            }\r\n\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, TestCommon.RunAICLICommand(\"install\", $\"TestMsiInstaller --silent -l {installDir}\").ExitCode);\r\n\r\n            var result = TestCommon.RunAICLICommand(\"list\", \"TestMsiInstallerUpgradeCode\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"AppInstallerTest.TestMsiInstallerUpgradeCode\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test list with exe installed with machine scope.\r\n        /// </summary>\r\n        [Test]\r\n        public void ListWithScopeExeInstalledAsMachine()\r\n        {\r\n            System.Guid guid = System.Guid.NewGuid();\r\n            string identifier = \"AppInstallerTest.TestExeInstaller\";\r\n            string productCode = guid.ToString();\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"{identifier} --override \\\"/InstallDir {installDir} /ProductID {productCode} /UseHKLM\\\"\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n\r\n            // List with user scope will not find the package\r\n            result = TestCommon.RunAICLICommand(\"list\", $\"{productCode} --scope user\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode);\r\n            Assert.False(result.StdOut.Contains(identifier));\r\n\r\n            // List with machine scope will find the package\r\n            result = TestCommon.RunAICLICommand(\"list\", $\"{productCode} --scope machine\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(identifier));\r\n\r\n            TestCommon.RunCommand(Path.Combine(installDir, Constants.TestExeUninstallerFileName));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test list with exe installed with user scope.\r\n        /// </summary>\r\n        [Test]\r\n        public void ListWithScopeExeInstalledAsUser()\r\n        {\r\n            System.Guid guid = System.Guid.NewGuid();\r\n            string identifier = \"AppInstallerTest.TestExeInstaller\";\r\n            string productCode = guid.ToString();\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"{identifier} --override \\\"/InstallDir {installDir} /ProductID {productCode}\\\"\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n\r\n            // List with user scope will find the package\r\n            result = TestCommon.RunAICLICommand(\"list\", $\"{productCode} --scope user\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(identifier));\r\n\r\n            // List with machine scope will not find the package\r\n            result = TestCommon.RunAICLICommand(\"list\", $\"{productCode} --scope machine\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode);\r\n            Assert.False(result.StdOut.Contains(identifier));\r\n\r\n            TestCommon.RunCommand(Path.Combine(installDir, Constants.TestExeUninstallerFileName));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test list with msix installed with machine scope.\r\n        /// </summary>\r\n        [Test]\r\n        public void ListWithScopeMsixInstalledAsMachine()\r\n        {\r\n            // TODO: Provision and Deprovision api not supported in build server.\r\n            Assert.Ignore();\r\n\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"{Constants.MsixInstallerPackageId} --scope machine\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n\r\n            // List with user scope will also find the package because msix is provisioned for all users\r\n            result = TestCommon.RunAICLICommand(\"list\", $\"{Constants.MsixInstallerPackageId} --scope user\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(Constants.MsixInstallerPackageId));\r\n\r\n            // List with machine scope will find the package\r\n            result = TestCommon.RunAICLICommand(\"list\", $\"{Constants.MsixInstallerPackageId} --scope machine\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(Constants.MsixInstallerPackageId));\r\n\r\n            TestCommon.RemoveMsix(Constants.MsixInstallerName, true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test list with msix installed with user scope.\r\n        /// </summary>\r\n        [Test]\r\n        public void ListWithScopeMsixInstalledAsUser()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"{Constants.MsixInstallerPackageId} --scope user\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n\r\n            // List with user scope will find the package\r\n            result = TestCommon.RunAICLICommand(\"list\", $\"{Constants.MsixInstallerPackageId} --scope user\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(Constants.MsixInstallerPackageId));\r\n\r\n            // List with machine scope will not find the package\r\n            result = TestCommon.RunAICLICommand(\"list\", $\"{Constants.MsixInstallerPackageId} --scope machine\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode);\r\n            Assert.False(result.StdOut.Contains(Constants.MsixInstallerPackageId));\r\n\r\n            TestCommon.RemoveMsix(Constants.MsixInstallerName);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test package correlation with same package name but different architecture is correct.\r\n        /// </summary>\r\n        [Test]\r\n        public void ListWithMappingWithArchitecture()\r\n        {\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestMappingWithArchitectureX86 -l {installDir}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n\r\n            // List with AppInstallerTest.TestMappingWithArchitectureX64 (from available to installed scenario) will not find the package.\r\n            result = TestCommon.RunAICLICommand(\"list\", \"AppInstallerTest.TestMappingWithArchitectureX64\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode);\r\n            Assert.False(result.StdOut.Contains(\"AppInstallerTest.TestMappingWithArchitectureX64\"));\r\n\r\n            // List with AppInstallerTest.TestMappingWithArchitectureX86 (from available to installed scenario) will find the package.\r\n            result = TestCommon.RunAICLICommand(\"list\", \"AppInstallerTest.TestMappingWithArchitectureX86\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"AppInstallerTest.TestMappingWithArchitectureX86\"));\r\n\r\n            // List with product code (from installed to available scenario) will find the AppInstallerTest.TestMappingWithArchitectureX86 package.\r\n            result = TestCommon.RunAICLICommand(\"list\", \"{0e426f01-b682-4e67-a357-52f9ecb4590d}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"AppInstallerTest.TestMappingWithArchitectureX86\"));\r\n\r\n            // best effort clean up\r\n            TestCommon.RunCommand(Path.Combine(installDir, Constants.TestExeUninstallerFileName));\r\n        }\r\n\r\n        private void ArpVersionMappingTest(string packageIdentifier, string displayNameOverride, string displayVersionOverride, string expectedListVersion, string notExpectedListVersion = \"\")\r\n        {\r\n            System.Guid guid = System.Guid.NewGuid();\r\n            string productCode = guid.ToString();\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n\r\n            var result = TestCommon.RunAICLICommand(\"list\", productCode);\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode);\r\n\r\n            result = TestCommon.RunAICLICommand(\"install\", $\"{packageIdentifier} --override \\\"/InstallDir {installDir} /ProductID {productCode} /DisplayName {displayNameOverride} /Version {displayVersionOverride}\\\"\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n\r\n            result = TestCommon.RunAICLICommand(\"list\", productCode);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n\r\n            Assert.True(result.StdOut.Contains(packageIdentifier));\r\n            Assert.True(result.StdOut.Contains(expectedListVersion));\r\n            if (!string.IsNullOrEmpty(notExpectedListVersion))\r\n            {\r\n                Assert.False(result.StdOut.Contains(notExpectedListVersion));\r\n            }\r\n\r\n            // Try clean up\r\n            if (File.Exists(Path.Combine(installDir, Constants.TestExeInstalledFileName)))\r\n            {\r\n                TestCommon.RunCommand(Path.Combine(installDir, Constants.TestExeUninstallerFileName));\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/Pinning.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"Pinning.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using System.IO;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\r\n    using static AppInstallerCLIE2ETests.Helpers.TestCommon;\r\n\r\n    /// <summary>\r\n    /// Test upgrading pinned packages.\r\n    /// </summary>\r\n    public class Pinning : BaseCommand\r\n    {\r\n        /// <summary>\r\n        /// Set up for all tests.\r\n        /// </summary>\r\n        [SetUp]\r\n        public void Setup()\r\n        {\r\n            // All tests use TestExeInstaller; try to clean it up for failure cases,\r\n            // then install the base version for pinning\r\n            TestCommon.RunAICLICommand(\"uninstall\", \"AppInstallerTest.TestExeInstaller\");\r\n            TestCommon.RunAICLICommand(\"install\", \"AppInstallerTest.TestExeInstaller -v 1.0.0.0\");\r\n            TestCommon.RunAICLICommand(\"pin remove\", \"AppInstallerTest.TestExeInstaller\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Clean up done after all the tests here.\r\n        /// </summary>\r\n        [OneTimeTearDown]\r\n        public void OneTimeTearDown()\r\n        {\r\n            TestCommon.RunAICLICommand(\"pin remove\", \"AppInstallerTest.TestExeInstaller\");\r\n            TestCommon.RunAICLICommand(\"uninstall\", \"AppInstallerTest.TestExeInstaller\");\r\n        }\r\n\r\n        // All tests do roughly the same with different types of pins:\r\n        // * Check that the available version shown by list is the latest\r\n        // * Check that the available version shown by upgrade is appropriate for the pin,\r\n        //   including checks with flags to include pinned.\r\n        // * Check that an upgrade installs the right version\r\n\r\n        /// <summary>\r\n        /// Tests upgrading a package when there are no pins on it.\r\n        /// </summary>\r\n        [Test]\r\n        public void UpgradeWithNoPins()\r\n        {\r\n            RunCommandResult result;\r\n\r\n            result = TestCommon.RunAICLICommand(\"list\", \"AppInstallerTest.TestExeInstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.IsTrue(result.StdOut.Contains(\"2.0.0.0\"), \"List shows the latest available version\");\r\n\r\n            result = TestCommon.RunAICLICommand(\"upgrade\", string.Empty);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.IsTrue(result.StdOut.Contains(\"2.0.0.0\"), \"The latest upgrade-able version is the same if there are no pins\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests upgrading a package when it has a pinning pin.\r\n        /// </summary>\r\n        [Test]\r\n        public void UpgradeWithPinningPin()\r\n        {\r\n            RunCommandResult result;\r\n            string installDir = Path.GetTempPath();\r\n\r\n            // The base version of this app does not log /Version, but it still includes the version number in the log file name.\r\n            Assert.True(TestCommon.VerifyTestExeInstalled(installDir, \"1.0.0.0\"), \"Base version installed\");\r\n\r\n            result = TestCommon.RunAICLICommand(\"pin add\", \"AppInstallerTest.TestExeInstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n\r\n            result = TestCommon.RunAICLICommand(\"list\", \"AppInstallerTest.TestExeInstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.IsTrue(result.StdOut.Contains(\"2.0.0.0\"), \"List shows the latest available version\");\r\n\r\n            result = TestCommon.RunAICLICommand(\"upgrade\", string.Empty);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.IsFalse(result.StdOut.Contains(\"2.0.0.0\"), \"Pin hides latest available version\");\r\n            Assert.IsTrue(result.StdOut.Contains(\"package(s) have pins that prevent upgrade\"));\r\n\r\n            result = TestCommon.RunAICLICommand(\"upgrade\", \"--all\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode, \"Upgrade succeeds with nothing to upgrade\");\r\n\r\n            Assert.True(TestCommon.VerifyTestExeInstalled(installDir, \"1.0.0.0\"), \"No newer version installed\");\r\n\r\n            result = TestCommon.RunAICLICommand(\"upgrade\", \"--include-pinned\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.IsTrue(result.StdOut.Contains(\"2.0.0.0\"), \"Argument makes available version show up\");\r\n\r\n            result = TestCommon.RunAICLICommand(\"upgrade\", \"--all --include-pinned\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode, \"Upgrade succeeds\");\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, \"/Version 2.0.0.0\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests upgrading a package when it has a gating pin that allows updating to another version.\r\n        /// </summary>\r\n        [Test]\r\n        public void UpgradeWithGatingPin()\r\n        {\r\n            RunCommandResult result;\r\n            string installDir = Path.GetTempPath();\r\n\r\n            var pinResult = TestCommon.RunAICLICommand(\"pin add\", \"AppInstallerTest.TestExeInstaller --version 1.0.*\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, pinResult.ExitCode);\r\n\r\n            result = TestCommon.RunAICLICommand(\"list\", \"AppInstallerTest.TestExeInstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.IsTrue(result.StdOut.Contains(\"2.0.0.0\"), \"List shows the latest available version\");\r\n\r\n            result = TestCommon.RunAICLICommand(\"upgrade\", string.Empty);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.IsFalse(result.StdOut.Contains(\"2.0.0.0\"), \"Pin hides latest available version\");\r\n            Assert.IsTrue(result.StdOut.Contains(\"1.0.1.0\"), \"Version matching pin gated version shows up\");\r\n\r\n            result = TestCommon.RunAICLICommand(\"upgrade\", \"--all\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode, \"Upgrade succeeds\");\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, \"/Version 1.0.1.0\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests upgrading a package when it has a gating pin that blocks all other versions.\r\n        /// </summary>\r\n        [Test]\r\n        public void UpgradeWithGatingPinToCurrent()\r\n        {\r\n            RunCommandResult result;\r\n\r\n            result = TestCommon.RunAICLICommand(\"pin add\", \"AppInstallerTest.TestExeInstaller --version 1.0.0.*\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n\r\n            result = TestCommon.RunAICLICommand(\"list\", \"AppInstallerTest.TestExeInstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.IsTrue(result.StdOut.Contains(\"2.0.0.0\"), \"List shows the latest available version\");\r\n\r\n            result = TestCommon.RunAICLICommand(\"upgrade\", string.Empty);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.IsFalse(result.StdOut.Contains(\"2.0.0.0\"), \"Pin hides latest available version\");\r\n            Assert.IsTrue(result.StdOut.Contains(\"package(s) have pins that prevent upgrade\"));\r\n\r\n            result = TestCommon.RunAICLICommand(\"upgrade\", \"AppInstallerTest.TestExeInstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_PACKAGE_IS_PINNED, result.ExitCode, \"No upgrades available due to pin\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests upgrading a package when it has a blocking pin.\r\n        /// </summary>\r\n        [Test]\r\n        public void UpgradeWithBlockingPin()\r\n        {\r\n            RunCommandResult result;\r\n\r\n            var pinResult = TestCommon.RunAICLICommand(\"pin add\", \"AppInstallerTest.TestExeInstaller --blocking\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, pinResult.ExitCode);\r\n\r\n            result = TestCommon.RunAICLICommand(\"list\", \"AppInstallerTest.TestExeInstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.IsTrue(result.StdOut.Contains(\"2.0.0.0\"), \"List shows the latest available version\");\r\n\r\n            result = TestCommon.RunAICLICommand(\"upgrade\", string.Empty);\r\n            Assert.IsFalse(result.StdOut.Contains(\"2.0.0.0\"), \"Pin hides latest available version\");\r\n            Assert.IsTrue(result.StdOut.Contains(\"package(s) have pins that prevent upgrade\"));\r\n\r\n            result = TestCommon.RunAICLICommand(\"upgrade\", \"AppInstallerTest.TestExeInstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_PACKAGE_IS_PINNED, result.ExitCode, \"No upgrades available due to pin\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests upgrading a package when it has a pinning pin and the --force flag is used.\r\n        /// </summary>\r\n        [Test]\r\n        public void ForceUpgradeWithPinningPin()\r\n        {\r\n            RunCommandResult result;\r\n            string installDir = Path.GetTempPath();\r\n\r\n            result = TestCommon.RunAICLICommand(\"pin add\", \"AppInstallerTest.TestExeInstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n\r\n            result = TestCommon.RunAICLICommand(\"upgrade\", \"--force\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.IsTrue(result.StdOut.Contains(\"2.0.0.0\"), \"--force argument shows latest version\");\r\n\r\n            result = TestCommon.RunAICLICommand(\"upgrade\", \"--all --force\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, \"/Version 2.0.0.0\"), \"--force argument installs last version despite pin\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests upgrading a package when it has a gating pin and the --force flag is used.\r\n        /// </summary>\r\n        [Test]\r\n        public void ForceUpgradeWithGatingPin()\r\n        {\r\n            RunCommandResult result;\r\n            string installDir = Path.GetTempPath();\r\n\r\n            var pinResult = TestCommon.RunAICLICommand(\"pin add\", \"AppInstallerTest.TestExeInstaller --version 1.0.*\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, pinResult.ExitCode);\r\n\r\n            result = TestCommon.RunAICLICommand(\"upgrade\", \"--force\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.IsTrue(result.StdOut.Contains(\"2.0.0.0\"), \"--force argument shows latest version\");\r\n\r\n            result = TestCommon.RunAICLICommand(\"upgrade\", \"--all --force\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode, \"Upgrade succeeds\");\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, \"/Version 2.0.0.0\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests upgrading a package when it has a blocking pin and the --force flag is used.\r\n        /// </summary>\r\n        [Test]\r\n        public void ForceUpgradeWithBlockingPin()\r\n        {\r\n            RunCommandResult result;\r\n            string installDir = Path.GetTempPath();\r\n\r\n            var pinResult = TestCommon.RunAICLICommand(\"pin add\", \"AppInstallerTest.TestExeInstaller --blocking\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, pinResult.ExitCode);\r\n\r\n            result = TestCommon.RunAICLICommand(\"upgrade\", \"--force\");\r\n            Assert.IsTrue(result.StdOut.Contains(\"2.0.0.0\"), \"--force argument shows latest version\");\r\n\r\n            result = TestCommon.RunAICLICommand(\"upgrade\", \"--all --force\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode, \"Upgrade succeeds\");\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, \"/Version 2.0.0.0\"));\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/PowerShell/PowerShellHost.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"PowerShellHost.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests.PowerShell\r\n{\r\n    using System;\r\n    using System.Collections;\r\n    using System.Management.Automation;\r\n    using System.Management.Automation.Runspaces;\r\n    using Microsoft.PowerShell;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// Helper class to run powershell commands.\r\n    /// </summary>\r\n    internal class PowerShellHost : IDisposable\r\n    {\r\n        private readonly Runspace runspace = null;\r\n\r\n        private bool disposed = false;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"PowerShellHost\"/> class.\r\n        /// </summary>\r\n        public PowerShellHost()\r\n        {\r\n            InitialSessionState initialSessionState = InitialSessionState.CreateDefault();\r\n            initialSessionState.ExecutionPolicy = ExecutionPolicy.Unrestricted;\r\n\r\n            this.runspace = RunspaceFactory.CreateRunspace(initialSessionState);\r\n            this.runspace.Open();\r\n            this.VerifyErrorState();\r\n\r\n            this.PowerShell = PowerShell.Create(this.runspace);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Finalizes an instance of the <see cref=\"PowerShellHost\"/> class.\r\n        /// </summary>\r\n        ~PowerShellHost() => this.Dispose(false);\r\n\r\n        /// <summary>\r\n        /// Gets PowerShell.\r\n        /// </summary>\r\n        public PowerShell PowerShell { get; private set; } = null;\r\n\r\n        /// <summary>\r\n        /// Dispose.\r\n        /// </summary>\r\n        public void Dispose()\r\n        {\r\n            this.Dispose(true);\r\n            GC.SuppressFinalize(this);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Add module path.\r\n        /// </summary>\r\n        /// <param name=\"path\">Path.</param>\r\n        public void AddModulePath(string path)\r\n        {\r\n            var newModulePath = this.PowerShell.Runspace.SessionStateProxy.PSVariable.GetValue(\"env:PSModulePath\") + $\";{path}\";\r\n            this.PowerShell.Runspace.SessionStateProxy.PSVariable.Set(\"env:PSModulePath\", newModulePath);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Protected implementation of dispose pattern.\r\n        /// </summary>\r\n        /// <param name=\"disposing\">Dispose.</param>\r\n        protected virtual void Dispose(bool disposing)\r\n        {\r\n            if (!this.disposed)\r\n            {\r\n                if (disposing)\r\n                {\r\n                    this.PowerShell.Dispose();\r\n                    this.runspace.Dispose();\r\n                }\r\n\r\n                this.disposed = true;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// The most common error is that the module was not found.\r\n        /// </summary>\r\n        private void VerifyErrorState()\r\n        {\r\n            var errors = (ArrayList)this.runspace.SessionStateProxy.PSVariable.GetValue(\"Error\");\r\n\r\n            if (errors.Count > 0)\r\n            {\r\n                string errorMessage = \"PSVariable Error:\";\r\n                foreach (var error in errors)\r\n                {\r\n                    errorMessage += Environment.NewLine + ((ErrorRecord)error).Exception.Message;\r\n                }\r\n\r\n                TestContext.Error.WriteLine(errorMessage);\r\n                throw new Exception(errorMessage);\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/Properties/AssemblyInfo.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"AssemblyInfo.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\n[assembly: System.Runtime.Versioning.SupportedOSPlatform(\"windows10.0.17763\")]\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/README.md",
    "content": "# How to Run End-To-End Tests for Windows Package Manager Client\n\nMost of the tests require having the local test source added into winget. The local test source must be hosted in a localhost web server.\n\n## Run locally\nThe E2E tests are built on the nunit testing framework and can be configured with a Test.runsettings file. The project has its own default parameters but typically you will want to expand it by modifying **src\\AppInstallerCLIE2ETests\\Test.runsettings** with the parameters that you want and set it up by opening **Test Explorer - Settings - Configure Run Settings point to file: src\\AppInstallerCLIE2ETests\\Test.runsettings**\n\nIf your tests uses the test source see the [LocalhostWebServer](#LocalhostWebServer) and [WinGetSourceCreator](#WinGetSourceCreator) sections.\n\n### Run settings.\n|Parameter| Description  |\n|--|--|\n| PackagedContext | Indicates if the test should be run under packaged context |\n| VerboseLogging | Turn on/off verbose logging in the test result |\n| AICLIPath | The AICLI executable under test. If using loose file registration and using Invoke-Command when         AppExecutionAlias is not available, this will be relative path to package root. |\n| AICLIPackagePath | Used in packaged context. Path to the package containing executable under test. If LooseFileRegistration is true, this should be path to unpackaged root. |\n| LooseFileRegistration | Bool to set if loose file registration should be used. |\n| InvokeCommandInDesktopPackage | Bool to indicate using Invoke-CommandInDesktopPackage for test execution. This is used when AppExecutionAlias is not available, or disabled. |\n| StaticFileRootPath | Path to the set of static test files that will be served as the source for testing purposes. This path should be identical to the one provided to the LocalHostWebServer|\n| MsixTestInstallerPath | The MSIX (or APPX) Installer executable under test. |\n| ExeTestInstallerPath |The Exe Installer executable under test. |\n| MsiTestInstallerPath | The MSI Installer executable under test. |\n| PackageCertificatePath | Signing Certificate Path used to certify test index source package |\n| PowerShellModulePath | Path to the PowerShell module manifest file under test |\n| PowerShellModulePath | The local server cert file |\n| SkipTestSource | I solemnly swear the test won't use the local test source or the source is already set up. |\n\n#### Example of Test.runsettings with completed parameters:\nAssuming you clone winget-cli in c:\\dev, the localhost web server is running in c:\\dev\\TestLocalIndex (without creating the test source) and you built x64 Debug, this should cover most of the tests.\n\n    <RunSettings>\n        <TestRunParameters>\n            <Parameter name=\"PackagedContext\" value=\"false\" />\n            <Parameter name=\"VerboseLogging\" value=\"true\" />\n            <Parameter name=\"AICLIPath\" value=\"c:\\dev\\winget-cli\\src\\AppInstallerCLIPackage\\bin\\x64\\Debug\\AppInstallerCLI\\winget.exe\" />\n            <Parameter name=\"InvokeCommandInDesktopPackage\" value=\"false\" />\n            <Parameter name=\"StaticFileRootPath\" value=\"c:\\dev\\TestLocalIndex\" />\n            <Parameter name=\"MsixTestInstallerPath\" value=\"C:\\dev\\Temp\\AppInstallerTestMsixInstaller.msix\" />\n            <Parameter name=\"ExeTestInstallerPath\" value=\"c:\\dev\\winget-cli\\src\\x64\\Debug\\AppInstallerTestExeInstaller\\AppInstallerTestExeInstaller.exe\" />\n            <Parameter name=\"MsiTestInstallerPath\" value=\"c:\\dev\\winget-cli\\src\\AppInstallerCLIE2ETests\\TestData\\AppInstallerTestMsiInstaller.msi\" />\n            <Parameter name=\"PackageCertificatePath\" value=\"C:\\dev\\Temp\\packageCertificate.pfx\"/>\n            <Parameter name=\"PowerShellModulePath\" value=\"c:\\dev\\winget-cli\\src\\x64\\Debug\\PowerShell\\Microsoft.WinGet.Client.psd1\" />\n        </TestRunParameters>\n    </RunSettings>\n\nThe easiest way to generate AppInstallerTestMsixInstaller.msix is by running makeappx pack for c:\\dev\\winget-cli\\src\\AppInstallerTestMsixInstaller\\bin\\x64\\Debug.\n\n#### Log Files\nAfter running the E2E Tests, the logs can be found in the following paths:\n\n- **%LOCALAPPDATA%\\Packages\\WinGetDevCLI_8wekyb3d8bbwe\\LocalState\\DiagOutputDir**\n- **%LOCALAPPDATA%\\E2ETestLogs**\n- **%TEMP%\\WinGet\\defaultState**\n\n## LocalhostWebServer\nThe src\\Tool\\LocalhostWebServer project generates an executable that serves static test files from a given directory path through a HTTPS local loopback server in order to maintain a closed and controlled repository for resources used for testing purposes.\n\n### Start localhost web server\n\nThe localhost web server needs to be running for the duration of the tests. The easiest way to run it is to use src\\Tool\\LocalhostWebServer\\Run-LocalhostWebServer.ps1 in a different PowerShell session.\n\n|Parameter | Type | Description |\n|--|--|--|\n| **BuildRoot** | Mandatory | The output path of the LocalhostWebServer project. Normally something like <winget repo root>\\src\\<arch>\\<configuration>\\LocalhostWebServer\n| **StaticFileRoot** | Mandatory | Path to serve static root directory. If the directory path does not exist, a new directory will be created for you. |\n| **CertPath** | Mandatory | Path to HTTPS Developer Certificate. A self signed developer certificate will need to be created in order to  verify localhost https. |\n| **CertPassword** | Mandatory | HTTPS Developer Certificate Password |\n| **Port** | Optional | Port number [Default Port Number: 5001] |\n| **OutCertFile** | Optional | The exported certificate used |\n| **LocalSourceJson** | Optional | The local source definition. If set generates the source. |\r\n| **ForcedExperimentalFeatures** | Optional | Experimental features that should be forcibly enabled always. |\n\n### How to create and trust an ASP.NET Core HTTPS Development Certificate\nWindows Package Manager Client (WinGet.exe) requires new sources added to the WinGet repositories be securely accessed through HTTPS. Therefore, in order to verify the LocalhostWebServer, you will need to create a self-signed development certificate to verify the localhost address. \n\n- Open command prompt in administrator mode\n- Run **dotnet dev-certs https --trust** in the command line\n- Open up **certmgr** (search Manage User Certificates in Windows search bar) \n- Locate the newly created localhost certificate in the Personal/Certificates folder with a friendly name of \"ASP.NET Core HTTPS development certificate\"\n- Right click on the certificate --> All Tasks --> Export..\n- Click Yes to export the private key\n- Export file using Personal Information Exchange (.pfx) file format\n- Create and confirm password using SHA256 encryption (any password will work, just make sure to remember it for later)\n- Save HTTPS development certificate and refer its certificate path and password when launching the Localhost Webserver\n\n## WinGetSourceCreator\nThe src\\WinGetSourceCreator is a project that helps generate a new winget source for local development. It is consumed by IndexCreationTool, LocalhostWebServer and AppInstallerCLIE2ETests projects. It supports:\n- Prepare installers by signing them and placing then in the working directory and computing their hashes. For msix, signature hash is also supported.\n- Generate zip installers.\n- Generate the signed source.msix and index.db.\n\nLocalSource is the object that contains the definition of the source. A json serialized version of it is the input for IndexCreationTool and LocalhostWebServer.\n\nExample:\n```\n{\n  # If running E2E this is must be the StaticFileRoot used for the localhost web server\n  \"WorkingDirectory\": \"c:/dev/temp/TestLocalIndex\",\n\n  # The appx manifest to generate the source.msix file.\n  \"AppxManifest\": \"c:/dev/winget-cli/src/AppInstallerCLIE2ETests/TestData/Package/AppxManifest.xml\",\n\n  # A list of directories or files to copy. If a directory, it copies all the *.yaml files preserving subdirectories.\n  \"LocalManifests\": [\n    \"c:/dev/winget-cli/src/x86/Release/AppInstallerCLIE2ETests/TestData/Manifests\"\n  ],\n\n  # The signature to use.\n  \"Signature\": {\n    \"CertFile\": \"cert.pfx\",\n    \"Password\": \"1324\",\n\n    # If set it will modify the Package Identity Publisher in the AppxManifest.xml\n    \"Publisher\": \"CN:ThousandSunny\"\n  }\n\n  # Installers that are already present in the machine, by default the installers will be signed using their Signature\n  # property if set or the top level one.\n  \"LocalInstallers\": [\n    {\n      \"Type\": \"exe\",\n      \"Input\": \"c:/dev/winget-cli/src/x64/Debug/AppInstallerTestExeInstaller\\AppInstallerTestExeInstaller.exe\",\n\n      # Name of the installer to be copied and signed if needed.\n      \"Name\": \"AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\",\n\n      # The token in the manifests for this installer. This will be replaces at copy manifests time.\n      \"HashToken\": \"<EXEHASH>\"\n\n      # Overrides top level one.\n      \"Signature\": {\n          \"CertFile\": \"cert2.pfx\",\n          \"Password\": \"2345\",\n      }\n    },\n    {\n      \"Type\": \"msi\",\n      \"Input\": \"c:/dev/winget-cli/src/AppInstallerCLIE2ETests/TestData/AppInstallerTestMsiInstaller.msi\",\n      \"Name\": \"AppInstallerTestMsiInstaller/AppInstallerTestMsiInstaller.msi\",\n      \"HashToken\": \"<MSIHASH>\"\n\n      # Don't sign this.\n      \"SkipSignature\": true\n    },\n    {\n      \"Type\": \"msix\",\n      \"Input\": \"D:/dev/temp/AppInstallerTestMsixInstaller.msix\",\n      \"Name\": \"AppInstallerTestMsixInstaller/AppInstallerTestMsixInstaller.msix\",\n      \"HashToken\": \"<MSIXHASH>\",\n\n      # Only supported by where type is msix. Package must be signed, either already signed or signed when copied.\n      \"SignatureToken\": \"<SIGNATUREHASH>\",\n    }\n  ],\n\n  # These are installers that are generated on the go. Currently only zip is supported.\n  \"DynamicInstallers\": [\n    {\n      # Zip installers are never signed.\n      \"Type\": \"zip\",\n\n      # List of files to zip. Does not preserve subdirectories.\n      \"Input\": [\n        \"D:/dev/temp/TestLocalIndex/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\",\n        \"D:/dev/temp/TestLocalIndex/AppInstallerTestMsiInstaller/AppInstallerTestMsiInstaller.msi\",\n        \"D:/dev/temp/TestLocalIndex/AppInstallerTestMsixInstaller/AppInstallerTestMsixInstaller.msix\"\n      ],\n\n      \"Name\": \"AppInstallerTestZipInstaller/AppInstallerTestZipInstaller.zip\",\n\n      \"HashToken\": \"<ZIPHASH>\"\n    }\n  ],\n}\n```\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/RepairCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"RepairCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using System.IO;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// Test Repair command.\r\n    /// </summary>\r\n    public class RepairCommand : BaseCommand\r\n    {\r\n        /// <summary>\r\n        /// One time setup.\r\n        /// </summary>\r\n        [OneTimeSetUp]\r\n        public void OneTimeSetup()\r\n        {\r\n            // Try clean up AppInstallerTest.TestMsiInstaller for failure cases where cleanup is not successful\r\n            TestCommon.RunAICLICommand(\"uninstall\", \"AppInstallerTest.TestMsiInstaller\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test  MSI installer repair.\r\n        /// </summary>\r\n        [Test]\r\n        public void RepairMSIInstaller()\r\n        {\r\n            if (string.IsNullOrEmpty(TestIndex.MsiInstallerV2))\r\n            {\r\n                Assert.Ignore(\"MSI installer not available\");\r\n            }\r\n\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestMsiRepair --silent -l {installDir}\");\r\n\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            // Note: The 'msiexec repair' command requires the original installer file to be present at the location registered in the ARP (Add/Remove Programs).\r\n            // In our test scenario, the MSI installer file is initially placed in a temporary location and then deleted, which can cause the repair operation to fail.\r\n            // To work around this, we copy the installer file to the ARP source directory before running the repair command.\r\n            // A more permanent solution would be to modify the MSI installer to cache the installer file in a known location and register that location as the installer source.\r\n            // This would allow the 'msiexec repair' command to function as expected.\r\n            string installerSourceDir = TestCommon.CopyInstallerFileToARPInstallSourceDirectory(TestCommon.GetTestDataFile(\"AppInstallerTestMsiInstallerV2.msi\"), Constants.MsiInstallerProductCode, true);\r\n\r\n            result = TestCommon.RunAICLICommand(\"repair\", \"AppInstallerTest.TestMsiRepair\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Repair operation completed successfully\"));\r\n            Assert.True(TestCommon.VerifyTestMsiInstalledAndCleanup(installDir));\r\n\r\n            if (installerSourceDir != null && Directory.Exists(installerSourceDir))\r\n            {\r\n                Directory.Delete(installerSourceDir, true);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test  MSIX non-store package repair.\r\n        /// </summary>\r\n        [Test]\r\n        public void RepairNonStoreMSIXPackage()\r\n        {\r\n            // install a test msix package from TestSource and then repair it.\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestMsixInstaller --silent -l {installDir}\");\r\n\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            result = TestCommon.RunAICLICommand(\"repair\", \"AppInstallerTest.TestMsixInstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Repair operation completed successfully\"));\r\n            Assert.True(TestCommon.VerifyTestMsixInstalledAndCleanup());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test MSIX non-store package repair with machine scope.\r\n        /// </summary>\r\n        [Test]\r\n        public void RepairNonStoreMsixPackageWithMachineScope()\r\n        {\r\n            // Selecting Microsoft.Paint_8wekyb3d8bbwe because it's a system package suitable for this scenario.\r\n            // First, we need to ensure this package is installed, otherwise, we skip the test.\r\n            var result = TestCommon.RunAICLICommand(\"list\", \"Microsoft.Paint_8wekyb3d8bbwe\");\r\n\r\n            if (result.ExitCode != Constants.ErrorCode.S_OK)\r\n            {\r\n                Assert.Ignore(\"Test skipped as Microsoft.Paint_8wekyb3d8bbwe is not installed.\");\r\n            }\r\n\r\n            Assert.True(result.StdOut.Contains(\"Microsoft.Paint\"));\r\n\r\n            result = TestCommon.RunAICLICommand(\"repair\", \"Microsoft.Paint_8wekyb3d8bbwe --scope machine\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_INSTALL_SYSTEM_NOT_SUPPORTED, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"The current system configuration does not support the repair of this package.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test repair of a Burn installer that has a \"modify\" repair behavior specified in the manifest.\r\n        /// </summary>\r\n        [Test]\r\n        public void RepairBurnInstallerWithModifyBehavior()\r\n        {\r\n            // install a test burn package from TestSource and then repair it.\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestModifyRepair -v 2.0.0.0 --silent -l {installDir}\");\r\n\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            result = TestCommon.RunAICLICommand(\"repair\", \"AppInstallerTest.TestModifyRepair\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Repair operation completed successfully\"));\r\n            Assert.True(TestCommon.VerifyTestExeRepairCompletedAndCleanup(installDir, \"Modify Repair operation\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests the repair operation of a Burn installer that was installed in user scope but is being repaired in an admin context.\r\n        /// </summary>\r\n        [Test]\r\n        public void RepairBurnInstallerInAdminContextWithUserScopeInstall()\r\n        {\r\n            // install a test burn package from TestSource and then repair it.\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestUserScopeInstallRepairInAdminContext -v 2.0.0.0 --silent -l {installDir}\");\r\n\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            result = TestCommon.RunAICLICommand(\"repair\", \"AppInstallerTest.TestUserScopeInstallRepairInAdminContext\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"The package installed for user scope cannot be repaired when running with administrator privileges.\"));\r\n            TestCommon.CleanupTestExeAndDirectory(installDir);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests the repair operation of a Burn installer that lacks a repair behavior.\r\n        /// </summary>\r\n        [Test]\r\n        public void RepairBurnInstallerMissingRepairBehavior()\r\n        {\r\n            // install a test burn package from TestSource and then repair it.\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestMissingRepairBehavior -v 2.0.0.0 --silent -l {installDir}\");\r\n\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            result = TestCommon.RunAICLICommand(\"repair\", \"AppInstallerTest.TestMissingRepairBehavior\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_NO_REPAIR_INFO_FOUND, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"The repair command for this package cannot be found. Please reach out to the package publisher for support.\"));\r\n            TestCommon.CleanupTestExeAndDirectory(installDir);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test repair of a Exe installer that has a \"uninstaller\" repair behavior specified in the manifest and NoModify ARP flag set.\r\n        /// </summary>\r\n        [Test]\r\n        public void RepairBurnInstallerWithWithModifyBehaviorAndNoModifyFlag()\r\n        {\r\n            // install a test Exe package from TestSource and then repair it.\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestModifyRepairWithNoModify -v 2.0.0.0 --silent -l {installDir}\");\r\n\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            result = TestCommon.RunAICLICommand(\"repair\", \"AppInstallerTest.TestModifyRepairWithNoModify\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_REPAIR_NOT_SUPPORTED, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"The installer technology in use does not support repair.\"));\r\n            TestCommon.CleanupTestExeAndDirectory(installDir);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests the scenario where the repair operation is not supported for Portable Installer type.\r\n        /// </summary>\r\n        [Test]\r\n        public void RepairOperationNotSupportedForPortableInstaller()\r\n        {\r\n            string installDir = TestCommon.GetPortablePackagesDirectory();\r\n            string packageId, commandAlias, fileName, packageDirName, productCode;\r\n            packageId = \"AppInstallerTest.TestPortableExe\";\r\n            packageDirName = productCode = packageId + \"_\" + Constants.TestSourceIdentifier;\r\n            commandAlias = fileName = \"AppInstallerTestExeInstaller.exe\";\r\n\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"{packageId}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            result = TestCommon.RunAICLICommand(\"repair\", \"AppInstallerTest.TestPortableExe\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_REPAIR_NOT_SUPPORTED, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"The installer technology in use does not support repair.\"));\r\n\r\n            // If no location specified, default behavior is to create a package directory with the name \"{packageId}_{sourceId}\"\r\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test repair of a Exe installer that has a \"uninstaller\" repair behavior specified in the manifest.\r\n        /// </summary>\r\n        [Test]\r\n        public void RepairExeInstallerWithUninstallerBehavior()\r\n        {\r\n            // install a test Exe package from TestSource and then repair it.\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.UninstallerRepair -v 2.0.0.0 --silent -l {installDir}\");\r\n\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            result = TestCommon.RunAICLICommand(\"repair\", \"AppInstallerTest.UninstallerRepair\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Repair operation completed successfully\"));\r\n            Assert.True(TestCommon.VerifyTestExeRepairCompletedAndCleanup(installDir, \"Uninstaller Repair operation\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test repair of a Exe installer that has a \"uninstaller\" repair behavior specified in the manifest and NoRepair ARP flag set.\r\n        /// </summary>\r\n        [Test]\r\n        public void RepairExeInstallerWithUninstallerBehaviorAndNoRepairFlag()\r\n        {\r\n            // install a test Exe package from TestSource and then repair it.\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.UninstallerRepairWithNoRepair -v 2.0.0.0 --silent -l {installDir}\");\r\n\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            result = TestCommon.RunAICLICommand(\"repair\", \"AppInstallerTest.UninstallerRepairWithNoRepair\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_REPAIR_NOT_SUPPORTED, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"The installer technology in use does not support repair.\"));\r\n            TestCommon.CleanupTestExeAndDirectory(installDir);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test repair of a Nullsoft installer that has a \"uninstaller\" repair behavior specified in the manifest.\r\n        /// </summary>\r\n        [Test]\r\n        public void RepairNullsoftInstallerWithUninstallerBehavior()\r\n        {\r\n            // install a test Nullsoft package from TestSource and then repair it.\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.UninstallerRepair -v 2.0.0.0 --silent -l {installDir}\");\r\n\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            result = TestCommon.RunAICLICommand(\"repair\", \"AppInstallerTest.UninstallerRepair\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Repair operation completed successfully\"));\r\n            Assert.True(TestCommon.VerifyTestExeRepairCompletedAndCleanup(installDir, \"Uninstaller Repair operation\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test repair of a Inno installer that has a \"installer\" repair behavior specified in the manifest.\r\n        /// </summary>\r\n        [Test]\r\n        public void RepairInnoInstallerWithInstallerBehavior()\r\n        {\r\n            // install a test Inno package from TestSource and then repair it.\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestInstallerRepair -v 2.0.0.0 --silent -l {installDir}\");\r\n\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            result = TestCommon.RunAICLICommand(\"repair\", \"AppInstallerTest.TestInstallerRepair\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Repair operation completed successfully\"));\r\n            Assert.True(TestCommon.VerifyTestExeRepairCompletedAndCleanup(installDir, \"Installer Repair operation\"));\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/ResumeCommand.cs",
    "content": "// -----------------------------------------------------------------------------\n// <copyright file=\"ResumeCommand.cs\" company=\"Microsoft Corporation\">\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\n// </copyright>\n// -----------------------------------------------------------------------------\n\nnamespace AppInstallerCLIE2ETests\n{\n    using System.IO;\n    using System.Linq;\n    using AppInstallerCLIE2ETests.Helpers;\n    using NUnit.Framework;\n\n    /// <summary>\n    /// Test download command.\n    /// </summary>\n    public class ResumeCommand : BaseCommand\n    {\n        /// <summary>\n        /// One time setup.\n        /// </summary>\n        [OneTimeSetUp]\n        public void OneTimeSetup()\n        {\n            WinGetSettingsHelper.ConfigureFeature(\"resume\", true);\n        }\n\n        /// <summary>\n        /// One time teardown.\n        /// </summary>\n        [OneTimeTearDown]\n        public void OneTimeTearDown()\n        {\n            WinGetSettingsHelper.ConfigureFeature(\"resume\", false);\n        }\n\n        /// <summary>\n        /// Installs a test exe installer and verifies that the checkpoint index is cleaned up.\n        /// </summary>\n        [Test]\n        public void InstallExe_VerifyIndexDoesNotExist()\n        {\n            var checkpointsDir = TestCommon.GetCheckpointsDirectory();\n\n            // If the checkpoints directory does not yet exist, set to 0. The directory should be created when the command is invoked.\n            int initialCheckpointsCount = Directory.Exists(checkpointsDir) ? Directory.GetFiles(checkpointsDir).Length : 0;\n\n            var installDir = TestCommon.GetRandomTestDir();\n            var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestExeInstaller --silent -l {installDir}\");\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, \"/execustom\"));\n\n            int actualCheckpointsCount = Directory.GetFiles(checkpointsDir).Length;\n\n            // The checkpoints count should not change as the index file should be cleaned up after a successful install.\n            Assert.AreEqual(initialCheckpointsCount, actualCheckpointsCount);\n        }\n\n        /// <summary>\n        /// Verifies that an error message is shown when a resume id does not exist.\n        /// </summary>\n        [Test]\n        public void ResumeIdNotFound()\n        {\n            var resumeResult = TestCommon.RunAICLICommand(\"resume\", \"-g invalidResumeId\");\n            Assert.AreEqual(Constants.ErrorCode.ERROR_RESUME_ID_NOT_FOUND, resumeResult.ExitCode);\n        }\n\n        /// <summary>\r\n        /// Test install a package that returns REBOOT_REQUIRED_TO_FINISH and verify that the checkpoint database is properly cleaned up.\r\n        /// </summary>\r\n        [Test]\r\n        public void InstallRequiresRebootToFinish()\r\n        {\r\n            var checkpointsDir = TestCommon.GetCheckpointsDirectory();\r\n            int initialCheckpointsCount = Directory.Exists(checkpointsDir) ? Directory.GetDirectories(checkpointsDir).Length : 0;\r\n\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"TestRebootRequired --custom \\\"/ExitCode 9\\\" -l {installDir}\");\r\n\r\n            // REBOOT_REQUIRED_TO_FINISH is treated as a success.\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Restart your PC to finish installation.\"));\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir));\r\n\r\n            int actualCheckpointsCount = Directory.GetDirectories(checkpointsDir).Length;\r\n\r\n            // Checkpoint database should be cleaned up since resume is not needed to complete installation.\r\n            Assert.AreEqual(initialCheckpointsCount, actualCheckpointsCount);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test install a package that returns REBOOT_REQUIRED_FOR_INSTALL and verify that resume command can be called successfully.\r\n        /// </summary>\n        [Test]\n        public void InstallRequiresRebootForInstall()\r\n        {\r\n            var checkpointsDir = TestCommon.GetCheckpointsDirectory();\n\n            int initialCheckpointsCount = Directory.Exists(checkpointsDir) ? Directory.GetDirectories(checkpointsDir).Length : 0;\n\n            var installDir = TestCommon.GetRandomTestDir();\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"TestRebootRequired --custom \\\"/ExitCode 10\\\" -l {installDir}\");\n            Assert.AreEqual(Constants.ErrorCode.ERROR_INSTALL_REBOOT_REQUIRED_FOR_INSTALL, result.ExitCode);\n            Assert.True(result.StdOut.Contains(\"Your PC will restart to finish installation.\"));\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir));\r\n\n            int actualCheckpointsCount = Directory.GetDirectories(checkpointsDir).Length;\n            Assert.AreEqual(initialCheckpointsCount + 1, actualCheckpointsCount);\n\n            var checkpointsDirectoryInfo = new DirectoryInfo(checkpointsDir);\n\n            var checkpoint = checkpointsDirectoryInfo.GetDirectories()\n             .OrderByDescending(f => f.LastWriteTime)\n             .First();\n\n            // Resume output should be the same as the install result.\n            var resumeResult = TestCommon.RunAICLICommand(\"resume\", $\"-g {checkpoint.Name}\");\n            Assert.AreEqual(Constants.ErrorCode.ERROR_INSTALL_REBOOT_REQUIRED_FOR_INSTALL, resumeResult.ExitCode);\n            Assert.True(resumeResult.StdOut.Contains(\"Your PC will restart to finish installation.\"));\r\n            Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir));\r\n        }\n    }\n}"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/RunCommandException.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"RunCommandException.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using System;\r\n    using static AppInstallerCLIE2ETests.Helpers.TestCommon;\r\n\r\n    /// <summary>\r\n    /// An exception that occurred when running a command.\r\n    /// </summary>\r\n    internal class RunCommandException : Exception\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"RunCommandException\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fileName\">The file name of the command.</param>\r\n        /// <param name=\"args\">The arguments for the command.</param>\r\n        /// <param name=\"result\">The `RunCommand` result.</param>\r\n        public RunCommandException(string fileName, string args, RunCommandResult result)\r\n            : base($\"Command `{fileName} {args}` failed with: {result.ExitCode}\\nOut: {result.StdOut}\\nErr: {result.StdErr}\")\r\n        {\r\n            this.FileName = fileName;\r\n            this.Arguments = args;\r\n            this.Result = result;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or initializes the file name.\r\n        /// </summary>\r\n        public string FileName { get; private init; }\r\n\r\n        /// <summary>\r\n        /// Gets or initializes the arguments.\r\n        /// </summary>\r\n        public string Arguments { get; private init; }\r\n\r\n        /// <summary>\r\n        /// Gets or initializes the result object.\r\n        /// </summary>\r\n        public RunCommandResult Result { get; private init; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/SearchCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"SearchCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// Test search command.\r\n    /// </summary>\r\n    public class SearchCommand : BaseCommand\r\n    {\r\n        /// <summary>\r\n        /// Test search without args.\r\n        /// </summary>\r\n        [Test]\r\n        public void SearchWithoutArgs()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"search\", string.Empty);\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_INVALID_CL_ARGUMENTS, result.ExitCode);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test search with query.\r\n        /// </summary>\r\n        [Test]\r\n        public void SearchQuery()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"search\", \"TestExampleInstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"TestExampleInstaller\"));\r\n            Assert.True(result.StdOut.Contains(\"AppInstallerTest.TestExampleInstaller\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test search with alias.\r\n        /// </summary>\r\n        public void SearchUsingAlias()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"find\", \"TestExampleInstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"TestExampleInstaller\"));\r\n            Assert.True(result.StdOut.Contains(\"AppInstallerTest.TestExampleInstaller\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test search with name.\r\n        /// </summary>\r\n        [Test]\r\n        public void SearchWithName()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"search\", \"--name testexampleinstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"TestExampleInstaller\"));\r\n            Assert.True(result.StdOut.Contains(\"AppInstallerTest.TestExampleInstaller\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test search with Id.\r\n        /// </summary>\r\n        [Test]\r\n        public void SearchWithID()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"search\", \"--id appinstallertest.testexampleinstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"TestExampleInstaller\"));\r\n            Assert.True(result.StdOut.Contains(\"AppInstallerTest.TestExampleInstaller\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test search with invalid name.\r\n        /// </summary>\r\n        [Test]\r\n        public void SearchWithInvalidName()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"search\", \"--name InvalidName\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"No package found matching input criteria.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test search where it returns multiple results.\r\n        /// </summary>\r\n        [Test]\r\n        public void SearchReturnsMultiple()\r\n        {\r\n            // Search Microsoft should return multiple\r\n            var result = TestCommon.RunAICLICommand(\"search\", \"AppInstallerTest\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"AppInstallerTest.TestExeInstaller\"));\r\n            Assert.True(result.StdOut.Contains(\"AppInstallerTest.TestBurnInstaller\"));\r\n            Assert.True(result.StdOut.Contains(\"AppInstallerTest.TestExampleInstaller\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test search with exact name.\r\n        /// </summary>\r\n        [Test]\r\n        public void SearchWithExactName()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"search\", \"--exact TestExampleInstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"TestExampleInstaller\"));\r\n            Assert.True(result.StdOut.Contains(\"AppInstallerTest.TestExampleInstaller\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test search with exact ID.\r\n        /// </summary>\r\n        [Test]\r\n        public void SearchWithExactID()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"search\", \"--exact AppInstallerTest.TestExampleInstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"TestExampleInstaller\"));\r\n            Assert.True(result.StdOut.Contains(\"AppInstallerTest.TestExampleInstaller\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test search with exact case-sensitive.\r\n        /// </summary>\r\n        [Test]\r\n        public void SearchWithExactArgCaseSensitivity()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"search\", \"--exact testexampleinstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"No package found matching input criteria.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test search with a failed source.\r\n        /// </summary>\r\n        [Test]\r\n        public void SearchWithSingleSourceFailure()\r\n        {\r\n            TestCommon.RunAICLICommand(\"source add\", \"failSearch \\\"{ \\\"\\\"OpenHR\\\"\\\": \\\"\\\"0x80070002\\\"\\\" }\\\" Microsoft.Test.Configurable --header \\\"{}\\\"\");\r\n\r\n            try\r\n            {\r\n                var result = TestCommon.RunAICLICommand(\"search\", \"--exact AppInstallerTest.TestExampleInstaller\");\r\n                Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n                Assert.True(result.StdOut.Contains(\"Failed when searching source; results will not be included: failSearch\"));\r\n                Assert.True(result.StdOut.Contains(\"TestExampleInstaller\"));\r\n                Assert.True(result.StdOut.Contains(\"AppInstallerTest.TestExampleInstaller\"));\r\n            }\r\n            finally\r\n            {\r\n                this.ResetTestSource();\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test search with bad pin.\r\n        /// </summary>\r\n        [Test]\r\n        public void SearchStoreWithBadPin()\r\n        {\r\n            // Configure as close as possible to the real chain but use the test cert for everything\r\n            // This will at least force the public key to be checked rather than simply failing based on chain length\r\n            GroupPolicyHelper.EnableAdditionalSources.SetEnabledList(new GroupPolicyHelper.GroupPolicySource[]\r\n            {\r\n                    new GroupPolicyHelper.GroupPolicySource\r\n                    {\r\n                        Name = Constants.TestAlternateSourceName,\r\n                        Arg = Constants.DefaultMSStoreSourceUrl,\r\n                        Type = Constants.DefaultMSStoreSourceType,\r\n                        Data = string.Empty,\r\n                        Identifier = Constants.DefaultMSStoreSourceIdentifier,\r\n                        CertificatePinning = new GroupPolicyHelper.GroupPolicyCertificatePinning\r\n                        {\r\n                            Chains = new GroupPolicyHelper.GroupPolicyCertificatePinningChain[]\r\n                            {\r\n                                new GroupPolicyHelper.GroupPolicyCertificatePinningChain\r\n                                {\r\n                                    Chain = new GroupPolicyHelper.GroupPolicyCertificatePinningDetails[]\r\n                                    {\r\n                                        new GroupPolicyHelper.GroupPolicyCertificatePinningDetails\r\n                                        {\r\n                                            Validation = new string[] { \"publickey\" },\r\n                                            EmbeddedCertificate = TestCommon.GetTestServerCertificateHexString(),\r\n                                        },\r\n                                        new GroupPolicyHelper.GroupPolicyCertificatePinningDetails\r\n                                        {\r\n                                            Validation = new string[] { \"subject\", \"issuer\" },\r\n                                            EmbeddedCertificate = TestCommon.GetTestServerCertificateHexString(),\r\n                                        },\r\n                                        new GroupPolicyHelper.GroupPolicyCertificatePinningDetails\r\n                                        {\r\n                                            Validation = new string[] { \"subject\", \"issuer\" },\r\n                                            EmbeddedCertificate = TestCommon.GetTestServerCertificateHexString(),\r\n                                        },\r\n                                    },\r\n                                },\r\n                            },\r\n                        },\r\n                        TrustLevel = new string[] { \"None\" },\r\n                        Explicit = false,\r\n                    },\r\n            });\r\n\r\n            try\r\n            {\r\n                var result = TestCommon.RunAICLICommand(\"search\", $\"-s {Constants.TestAlternateSourceName} foo --verbose-logs\");\r\n                Assert.AreEqual(Constants.ErrorCode.ERROR_PINNED_CERTIFICATE_MISMATCH, result.ExitCode);\r\n            }\r\n            finally\r\n            {\r\n                this.ResetTestSource();\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/SetUpFixture.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"SetUpFixture.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using Microsoft.Win32;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// Set up fixture.\r\n    /// </summary>\r\n    [SetUpFixture]\r\n    public class SetUpFixture\r\n    {\r\n        private static bool shouldDisableDevModeOnExit = true;\r\n        private static bool shouldRevertDefaultFileTypeRiskOnExit = true;\r\n        private static bool shouldDoAnyTeardown = true;\r\n        private static string defaultFileTypes = string.Empty;\r\n\r\n        /// <summary>\r\n        /// Set up.\r\n        /// </summary>\r\n        [OneTimeSetUp]\r\n        public void Setup()\r\n        {\r\n            var testParams = TestSetup.Parameters;\r\n\r\n            if (testParams.IsDefault)\r\n            {\r\n                // If no parameters are provided, use defaults that work locally.\r\n                // This allows the user to assume responsibility for setup.\r\n                shouldDoAnyTeardown = false;\r\n            }\r\n            else\r\n            {\r\n                shouldDisableDevModeOnExit = this.EnableDevMode(true);\r\n\r\n                shouldRevertDefaultFileTypeRiskOnExit = this.DecreaseFileTypeRisk(\".exe;.msi\", false);\r\n\r\n                if (testParams.PackagedContext)\r\n                {\r\n                    if (testParams.LooseFileRegistration)\r\n                    {\r\n                        Assert.True(TestCommon.InstallMsixRegister(testParams.AICLIPackagePath), $\"InstallMsixRegister : {testParams.AICLIPackagePath}\");\r\n                    }\r\n                    else\r\n                    {\r\n                        Assert.True(TestCommon.InstallMsix(testParams.AICLIPackagePath), $\"InstallMsix : {testParams.AICLIPackagePath}\");\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (!testParams.SkipTestSource)\r\n            {\r\n                TestIndex.GenerateE2ESource();\r\n            }\r\n\r\n            WinGetSettingsHelper.ForcedExperimentalFeatures = testParams.ForcedExperimentalFeatures;\r\n            WinGetSettingsHelper.InitializeWingetSettings();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tear down.\r\n        /// </summary>\r\n        [OneTimeTearDown]\r\n        public void TearDown()\r\n        {\r\n            if (shouldDoAnyTeardown)\r\n            {\r\n                if (shouldDisableDevModeOnExit)\r\n                {\r\n                    this.EnableDevMode(false);\r\n                }\r\n\r\n                if (shouldRevertDefaultFileTypeRiskOnExit)\r\n                {\r\n                    this.DecreaseFileTypeRisk(defaultFileTypes, true);\r\n                }\r\n\r\n                TestCommon.PublishE2ETestLogs();\r\n\r\n                if (TestSetup.Parameters.PackagedContext)\r\n                {\r\n                    TestCommon.RemoveMsix(Constants.AICLIPackageName);\r\n                }\r\n            }\r\n        }\r\n\r\n        // Returns whether there's a change to the dev mode state after execution\r\n        private bool EnableDevMode(bool enable)\r\n        {\r\n            var appModelUnlockKey = Registry.LocalMachine.CreateSubKey(@\"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModelUnlock\");\r\n\r\n            if (enable)\r\n            {\r\n                var value = appModelUnlockKey.GetValue(\"AllowDevelopmentWithoutDevLicense\");\r\n                if (value == null || (int)value == 0)\r\n                {\r\n                    appModelUnlockKey.SetValue(\"AllowDevelopmentWithoutDevLicense\", 1, RegistryValueKind.DWord);\r\n                    return true;\r\n                }\r\n            }\r\n            else\r\n            {\r\n                var value = appModelUnlockKey.GetValue(\"AllowDevelopmentWithoutDevLicense\");\r\n                if (value != null && ((int)value) != 0)\r\n                {\r\n                    appModelUnlockKey.SetValue(\"AllowDevelopmentWithoutDevLicense\", 0, RegistryValueKind.DWord);\r\n                    return true;\r\n                }\r\n            }\r\n\r\n            return false;\r\n        }\r\n\r\n        private bool DecreaseFileTypeRisk(string fileTypes, bool revert)\r\n        {\r\n            var defaultFileTypeRiskKey = Registry.CurrentUser.CreateSubKey(@\"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Associations\");\r\n            string value = (string)defaultFileTypeRiskKey.GetValue(\"DefaultFileTypeRisk\");\r\n\r\n            if (revert)\r\n            {\r\n                defaultFileTypeRiskKey.SetValue(\"LowRiskFileTypes\", fileTypes);\r\n                return false;\r\n            }\r\n            else\r\n            {\r\n                if (string.IsNullOrEmpty(value))\r\n                {\r\n                    defaultFileTypes = string.Empty;\r\n                    defaultFileTypeRiskKey.SetValue(\"LowRiskFileTypes\", fileTypes);\r\n                }\r\n                else\r\n                {\r\n                    defaultFileTypes = value;\r\n                    defaultFileTypeRiskKey.SetValue(\"LowRiskFileTypes\", string.Concat(value, fileTypes));\r\n                }\r\n\r\n                return true;\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/ShowCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ShowCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// Test show command.\r\n    /// </summary>\r\n    public class ShowCommand : BaseCommand\r\n    {\r\n        /// <summary>\r\n        /// Test show with no args.\r\n        /// </summary>\r\n        [Test]\r\n        public void ShowWithNoArgs()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"show\", string.Empty);\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_INVALID_CL_ARGUMENTS, result.ExitCode);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test show no match.\r\n        /// </summary>\r\n        [Test]\r\n        public void ShowWithNoMatches()\r\n        {\r\n            // Show with 0 search match shows a \"please refine input\"\r\n            var result = TestCommon.RunAICLICommand(\"show\", $\"DoesNotExist\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"No package found matching input criteria.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test show with substring match.\r\n        /// </summary>\r\n        [Test]\r\n        public void ShowWithSubstringMatch()\r\n        {\r\n            // Show with a substring match still returns 0 results\r\n            var result = TestCommon.RunAICLICommand(\"show\", $\"AppInstallerTest\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"No package found matching input criteria.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test show with name match.\r\n        /// </summary>\r\n        [Test]\r\n        public void ShowWithNameMatch()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"show\", $\"--name testexampleinstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Found TestExampleInstaller [AppInstallerTest.TestExampleInstaller]\"));\r\n            Assert.True(result.StdOut.Contains(\"TestExampleInstaller\"));\r\n            Assert.True(result.StdOut.Contains(\"AppInstallerTest.TestExampleInstaller\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test show with id match.\r\n        /// </summary>\r\n        [Test]\r\n        public void ShowWithIDMatch()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"show\", $\"--id appinstallertest.testexampleinstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Found TestExampleInstaller [AppInstallerTest.TestExampleInstaller]\"));\r\n            Assert.True(result.StdOut.Contains(\"TestExampleInstaller\"));\r\n            Assert.True(result.StdOut.Contains(\"AppInstallerTest.TestExampleInstaller\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test show versions.\r\n        /// </summary>\r\n        [Test]\r\n        public void ShowWithVersions()\r\n        {\r\n            // Show with --versions list the versions\r\n            var result = TestCommon.RunAICLICommand(\"show\", $\"TestExampleInstaller --versions\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"TestExampleInstaller\"));\r\n            Assert.True(result.StdOut.Contains(\"AppInstallerTest.TestExampleInstaller\"));\r\n            Assert.True(result.StdOut.Contains(\"1.2.3.4\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test show with exact match name.\r\n        /// </summary>\r\n        [Test]\r\n        public void ShowWithExactName()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"show\", $\"--exact TestExampleInstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Found TestExampleInstaller [AppInstallerTest.TestExampleInstaller]\"));\r\n            Assert.True(result.StdOut.Contains(\"TestExampleInstaller\"));\r\n            Assert.True(result.StdOut.Contains(\"AppInstallerTest.TestExampleInstaller\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test show with exact id.\r\n        /// </summary>\r\n        [Test]\r\n        public void ShowWithExactID()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"show\", $\"--exact AppInstallerTest.TestExampleInstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Found TestExampleInstaller [AppInstallerTest.TestExampleInstaller]\"));\r\n            Assert.True(result.StdOut.Contains(\"TestExampleInstaller\"));\r\n            Assert.True(result.StdOut.Contains(\"AppInstallerTest.TestExampleInstaller\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test show with exact args.\r\n        /// </summary>\r\n        [Test]\r\n        public void ShowWithExactArgCaseSensitivity()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"show\", $\"--exact testexampleinstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"No package found matching input criteria.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test show with installer type.\r\n        /// </summary>\r\n        [Test]\r\n        public void ShowWithInstallerTypeArg()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"show\", $\"--id AppInstallerTest.TestMultipleInstallers --installer-type msi\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Found TestMultipleInstallers [AppInstallerTest.TestMultipleInstallers]\"));\r\n            Assert.True(result.StdOut.Contains(\"Installer Type: msi\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test show with an archive installer type.\r\n        /// </summary>\r\n        [Test]\r\n        public void ShowWithZipInstallerTypeArg()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"show\", $\"--id AppInstallerTest.TestMultipleInstallers --installer-type zip\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Found TestMultipleInstallers [AppInstallerTest.TestMultipleInstallers]\"));\r\n            Assert.True(result.StdOut.Contains(\"Installer Type: exe (zip)\"));\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/SourceCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"SourceCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// Test source command.\r\n    /// </summary>\r\n    public class SourceCommand : BaseCommand\r\n    {\r\n        /// <summary>\r\n        /// One time set up.\r\n        /// </summary>\r\n        [OneTimeSetUp]\r\n        public void OneTimeSetup()\r\n        {\r\n            WinGetSettingsHelper.ConfigureFeature(\"sourcePriority\", true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test set up.\r\n        /// </summary>\r\n        [SetUp]\r\n        public void Setup()\r\n        {\r\n            this.ResetTestSource(false);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test source add.\r\n        /// </summary>\r\n        [Test]\r\n        public void SourceAdd()\r\n        {\r\n            // TODO: Our test source package is being rejected by SmartScreen on the build server.\r\n            //       Reenable when SmartScreen issue is solved or removed.\r\n            Assert.Ignore();\r\n\r\n            var result = TestCommon.RunAICLICommand(\"source add\", $\"SourceTest {Constants.TestSourceUrl}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Done\"));\r\n            TestCommon.RunAICLICommand(\"source remove\", $\"-n SourceTest\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test source add with trust level.\r\n        /// </summary>\r\n        [Test]\r\n        public void SourceAddWithTrustLevel()\r\n        {\r\n            // Remove the test source.\r\n            TestCommon.RunAICLICommand(\"source remove\", Constants.TestSourceName);\r\n\r\n            var result = TestCommon.RunAICLICommand(\"source add\", $\"SourceTest {Constants.TestSourceUrl} --trust-level trusted\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Done\"));\r\n\r\n            var listResult = TestCommon.RunAICLICommand(\"source list\", $\"-n SourceTest\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, listResult.ExitCode);\r\n            Assert.True(listResult.StdOut.Contains(\"Trust Level\"));\r\n            Assert.True(listResult.StdOut.Contains(\"Trusted\"));\r\n            TestCommon.RunAICLICommand(\"source remove\", $\"-n SourceTest\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test source add with store origin trust level.\r\n        /// </summary>\r\n        [Test]\r\n        public void SourceAddWithStoreOriginTrustLevel()\r\n        {\r\n            // Remove the test source.\r\n            TestCommon.RunAICLICommand(\"source remove\", Constants.TestSourceName);\r\n\r\n            var result = TestCommon.RunAICLICommand(\"source add\", $\"SourceTest {Constants.TestSourceUrl} --trust-level storeOrigin\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_DATA_INTEGRITY_FAILURE, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"The source data is corrupted or tampered\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test source add with explicit flag. Packages should only appear if the source is explicitly declared.\r\n        /// </summary>\r\n        [Test]\r\n        public void SourceAddWithExplicit()\r\n        {\r\n            // Remove the test source.\r\n            TestCommon.RunAICLICommand(\"source remove\", Constants.TestSourceName);\r\n\r\n            var result = TestCommon.RunAICLICommand(\"source add\", $\"SourceTest {Constants.TestSourceUrl} --trust-level trusted --explicit\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Done\"));\r\n\r\n            var searchResult = TestCommon.RunAICLICommand(\"search\", \"TestExampleInstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_NO_SOURCES_DEFINED, searchResult.ExitCode);\r\n            Assert.True(searchResult.StdOut.Contains(\"No sources defined; add one with 'source add' or reset to defaults with 'source reset'\"));\r\n\r\n            var searchResult2 = TestCommon.RunAICLICommand(\"search\", \"TestExampleInstaller --source SourceTest\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, searchResult2.ExitCode);\r\n            Assert.True(searchResult2.StdOut.Contains(\"TestExampleInstaller\"));\r\n            Assert.True(searchResult2.StdOut.Contains(\"AppInstallerTest.TestExampleInstaller\"));\r\n            TestCommon.RunAICLICommand(\"source remove\", $\"-n SourceTest\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test source add with a priority value.\r\n        /// </summary>\r\n        [Test]\r\n        public void SourceAddWithPriority()\r\n        {\r\n            // Remove the test source.\r\n            TestCommon.RunAICLICommand(\"source remove\", Constants.TestSourceName);\r\n\r\n            var result = TestCommon.RunAICLICommand(\"source add\", $\"SourceTest {Constants.TestSourceUrl} --priority 42\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Done\"));\r\n\r\n            var listResult = TestCommon.RunAICLICommand(\"source list\", \"SourceTest\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, listResult.ExitCode);\r\n            Assert.True(listResult.StdOut.Contains(\"42\"));\r\n\r\n            var exportResult = TestCommon.RunAICLICommand(\"source export\", string.Empty);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, listResult.ExitCode);\r\n            Assert.True(exportResult.StdOut.Contains(\"42\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test source add with duplicate name.\r\n        /// </summary>\r\n        [Test]\r\n        public void SourceAddWithDuplicateName()\r\n        {\r\n            // Add source with duplicate name should fail\r\n            var result = TestCommon.RunAICLICommand(\"source add\", $\"{Constants.TestSourceName} https://microsoft.com\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_ALREADY_EXISTS, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"A source with the given name already exists and refers to a different location\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test source add with duplicate source url.\r\n        /// </summary>\r\n        [Test]\r\n        public void SourceAddWithDuplicateSourceUrl()\r\n        {\r\n            // Add source with duplicate url should fail\r\n            var result = TestCommon.RunAICLICommand(\"source add\", $\"TestSource2 {Constants.TestSourceUrl}\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_ARG_ALREADY_EXISTS, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"A source with a different name already refers to this location\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test source add with invalid url.\r\n        /// </summary>\r\n        [Test]\r\n        public void SourceAddWithInvalidURL()\r\n        {\r\n            // Add source with invalid url should fail\r\n            var result = TestCommon.RunAICLICommand(\"source add\", $\"AnotherSource {Constants.TestSourceUrl}/Invalid/Directory/Dont/Add/Me\");\r\n            Assert.AreEqual(Constants.ErrorCode.HTTP_E_STATUS_NOT_FOUND, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"An unexpected error occurred while executing the command\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test source add with http url.\r\n        /// </summary>\r\n        [Test]\r\n        public void SourceAddWithHttpURL()\r\n        {\r\n            // Add source with an HTTP url should fail\r\n            var result = TestCommon.RunAICLICommand(\"source add\", \"Insecure http://microsoft.com\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NOT_SECURE, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"error occurred while executing the command\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test source list with no args.\r\n        /// </summary>\r\n        [Test]\r\n        public void SourceListWithNoArgs()\r\n        {\r\n            // List with no args should list all available sources\r\n            var result = TestCommon.RunAICLICommand(\"source list\", string.Empty);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(Constants.TestSourceUrl));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test source list with name.\r\n        /// </summary>\r\n        [Test]\r\n        public void SourceListWithName()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"source list\", $\"-n {Constants.TestSourceName}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(Constants.TestSourceName));\r\n            Assert.True(result.StdOut.Contains(Constants.TestSourceUrl));\r\n            Assert.True(result.StdOut.Contains(\"Microsoft.PreIndexed.Package\"));\r\n            Assert.True(result.StdOut.Contains(\"Trust Level\"));\r\n            Assert.True(result.StdOut.Contains(\"Updated\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test source list name mismatch.\r\n        /// </summary>\r\n        [Test]\r\n        public void SourceListNameMismatch()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"source list\", \"-n UnknownName\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Did not find a source named\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test source update.\r\n        /// </summary>\r\n        [Test]\r\n        public void SourceUpdate()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"source update\", $\"-n {Constants.TestSourceName}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Done\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test source update with invalid name.\r\n        /// </summary>\r\n        [Test]\r\n        public void SourceUpdateWithInvalidName()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"source update\", \"-n UnknownName\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Did not find a source named: UnknownName\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test source remove by name.\r\n        /// </summary>\r\n        [Test]\r\n        public void SourceRemoveValidName()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"source remove\", $\"-n {Constants.TestSourceName}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Done\"));\r\n            this.ResetTestSource(false);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test source remove with invalid name.\r\n        /// </summary>\r\n        [Test]\r\n        public void SourceRemoveInvalidName()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"source remove\", \"-n UnknownName\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Did not find a source named: UnknownName\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test source reset.\r\n        /// </summary>\r\n        [Test]\r\n        public void SourceReset()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"source reset\", string.Empty);\r\n            Assert.True(result.StdOut.Contains(\"The following sources will be reset if the --force option is given:\"));\r\n            Assert.True(result.StdOut.Contains(Constants.TestSourceName));\r\n            Assert.True(result.StdOut.Contains(Constants.TestSourceUrl));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test source reset force.\r\n        /// </summary>\r\n        [Test]\r\n        public void SourceForceReset()\r\n        {\r\n            // Force Reset Sources\r\n            var result = TestCommon.RunAICLICommand(\"source reset\", \"--force\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Resetting all sources...Done\"));\r\n\r\n            // Verify sources have been reset\r\n            result = TestCommon.RunAICLICommand(\"source list\", string.Empty);\r\n            Assert.True(result.StdOut.Contains(\"winget\"));\r\n            Assert.True(result.StdOut.Contains(\"https://cdn.winget.microsoft.com/cache\"));\r\n            Assert.False(result.StdOut.Contains(Constants.TestSourceName));\r\n            Assert.False(result.StdOut.Contains(Constants.TestSourceUrl));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test source edit with explicit flag, edit the source to not be explicit.\r\n        /// </summary>\r\n        [Test]\r\n        public void SourceEdit()\r\n        {\r\n            // Remove the test source.\r\n            TestCommon.RunAICLICommand(\"source remove\", Constants.TestSourceName);\r\n\r\n            // Add source as explicit and verify it is explicit.\r\n            var addResult = TestCommon.RunAICLICommand(\"source add\", $\"SourceTest {Constants.TestSourceUrl} --trust-level trusted --explicit\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, addResult.ExitCode);\r\n            Assert.True(addResult.StdOut.Contains(\"Done\"));\r\n\r\n            var searchResult = TestCommon.RunAICLICommand(\"search\", \"TestExampleInstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_NO_SOURCES_DEFINED, searchResult.ExitCode);\r\n            Assert.True(searchResult.StdOut.Contains(\"No sources defined; add one with 'source add' or reset to defaults with 'source reset'\"));\r\n\r\n            // Run the edit, this should be S_OK with \"Done\" as it changed the state to not-explicit.\r\n            var editResult = TestCommon.RunAICLICommand(\"source edit\", $\"SourceTest --explicit false\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, editResult.ExitCode);\r\n            Assert.True(editResult.StdOut.Contains(\"Explicit\"));\r\n\r\n            // Run it again, this should result in S_OK with no changes and a message that the source is already in that state.\r\n            var editResult2 = TestCommon.RunAICLICommand(\"source edit\", $\"SourceTest --explicit false\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, editResult2.ExitCode);\r\n            Assert.True(editResult2.StdOut.Contains(\"The source named 'SourceTest' is already in the desired state.\"));\r\n\r\n            // Now verify it is no longer explicit by running the search again without adding the source parameter.\r\n            var searchResult2 = TestCommon.RunAICLICommand(\"search\", \"TestExampleInstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, searchResult2.ExitCode);\r\n            Assert.True(searchResult2.StdOut.Contains(\"TestExampleInstaller\"));\r\n            Assert.True(searchResult2.StdOut.Contains(\"AppInstallerTest.TestExampleInstaller\"));\r\n            TestCommon.RunAICLICommand(\"source remove\", $\"-n SourceTest\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test source edit with priority.\r\n        /// </summary>\r\n        [Test]\r\n        public void SourceEdit_Priority()\r\n        {\r\n            // Remove the test source.\r\n            TestCommon.RunAICLICommand(\"source remove\", Constants.TestSourceName);\r\n\r\n            var addResult = TestCommon.RunAICLICommand(\"source add\", $\"SourceTest {Constants.TestSourceUrl}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, addResult.ExitCode);\r\n            Assert.True(addResult.StdOut.Contains(\"Done\"));\r\n\r\n            // Run the edit, this should be S_OK with \"Done\" as it changed the state\r\n            var editResult = TestCommon.RunAICLICommand(\"source edit\", $\"SourceTest --priority 14\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, editResult.ExitCode);\r\n            Assert.True(editResult.StdOut.Contains(\"14\"));\r\n\r\n            // Run it again, this should result in S_OK with no changes and a message that the source is already in that state.\r\n            var editResult2 = TestCommon.RunAICLICommand(\"source edit\", $\"SourceTest --priority 14\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, editResult2.ExitCode);\r\n            Assert.True(editResult2.StdOut.Contains(\"The source named 'SourceTest' is already in the desired state.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test override of a default source via edit command.\r\n        /// </summary>\r\n        [Test]\r\n        public void SourceEditOverrideDefault()\r\n        {\r\n            // Force Reset Sources\r\n            var resetResult = TestCommon.RunAICLICommand(\"source reset\", \"--force\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, resetResult.ExitCode);\r\n\r\n            // Verify it is explicit true. Explicit is the only boolean value in the output.\r\n            var listResult = TestCommon.RunAICLICommand(\"source list\", \"winget-font\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, listResult.ExitCode);\r\n            Assert.True(listResult.StdOut.Contains(\"true\"));\r\n\r\n            var editResult = TestCommon.RunAICLICommand(\"source edit\", \"winget-font -e false\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, editResult.ExitCode);\r\n            Assert.True(editResult.StdOut.Contains(\"Explicit\"));\r\n\r\n            // Verify that after edit it is now explicit false.\r\n            var listResult2 = TestCommon.RunAICLICommand(\"source list\", \"winget-font\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, listResult2.ExitCode);\r\n            Assert.True(listResult2.StdOut.Contains(\"false\"));\r\n\r\n            // Remove the source. This should correctly tombstone it, even though it is overridden.\r\n            var removeResult = TestCommon.RunAICLICommand(\"source remove\", \"winget-font\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, removeResult.ExitCode);\r\n            Assert.True(removeResult.StdOut.Contains(\"Done\"));\r\n\r\n            var listResult3 = TestCommon.RunAICLICommand(\"source list\", \"winget-font\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, listResult3.ExitCode);\r\n\r\n            // Force Reset Sources\r\n            var resetResult2 = TestCommon.RunAICLICommand(\"source reset\", \"--force\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, resetResult2.ExitCode);\r\n\r\n            // Verify it is back to being explicit true.\r\n            var listResult4 = TestCommon.RunAICLICommand(\"source list\", \"winget-font\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, listResult4.ExitCode);\r\n            Assert.True(listResult4.StdOut.Contains(\"true\"));\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/Test.runsettings",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n\r\n<RunSettings>\r\n  <!-- \r\n  Parameters used by tests at run time.\r\n\r\n    PackagedContext: Indicates if the test should be run under packaged context\r\n    VerboseLogging: Turn on/off verbose logging in the test result\r\n    AICLIPath: The AICLI executable under test.\r\n               If using loose file registration and using Invoke-Command when\r\n               AppExecutionAlias is not available, this will be relative path to package root.\r\n    AICLIPackagePath: Used in packaged context. Path to the package containing executable under test.\r\n                      If LooseFileRegistration is true, this should be path to unpackaged root.\r\n    LooseFileRegistration: Bool to set if loose file registration should be used.\r\n    InvokeCommandInDesktopPackage: Bool to indicate using Invoke-CommandInDesktopPackage for test execution.\r\n                                   This is used when AppExecutionAlias is not available, or disabled.\r\n    StaticFileRootPath: Path to the set of static test files that will be served as the source for testing purposes.\r\n    MsiTestInstallerPath: The Msi Installer executable under test.\r\n    MsixTestInstallerPath: The MSIX (or APPX) Installer executable under test.\r\n    ExeTestInstallerPath: The Exe Installer executable under test.\r\n    PackageCertificatePath: Signing Certificate Path used to certify Index Source Package.\r\n    PowerShellModulePath: Path to the PowerShell module manifest file under test.\r\n    LocalServerCertPathParameter: The cert used for the local server.\r\n    SkipTestSource: I solemnly swear the test won't use the local test source or the source is already set up.\r\n  -->\r\n  <TestRunParameters>\r\n    <Parameter name=\"PackagedContext\" value=\"true\" />\r\n    <Parameter name=\"VerboseLogging\" value=\"false\" />\r\n    <Parameter name=\"AICLIPath\" value=\"AppInst.exe\" />\r\n    <Parameter name=\"AICLIPackagePath\" value=\"AppInstallerCLIPackage.appxbundle\" />\r\n    <Parameter name=\"LooseFileRegistration\" value=\"false\" />\r\n    <Parameter name=\"InvokeCommandInDesktopPackage\" value=\"false\" />\r\n    <Parameter name=\"StaticFileRootPath\" value=\"TestLocalIndex\" />\r\n    <Parameter name=\"MsiTestInstallerPath\" value=\"MsiTestInstaller.msi\" />\r\n    <Parameter name=\"MsixTestInstallerPath\" value=\"MsixTestInstaller.msix\" />\r\n    <Parameter name=\"ExeTestInstallerPath\" value=\"ExeTestInstaller.exe\" />\r\n    <Parameter name=\"FontTestPath\" value=\"AppInstallerTestFont.ttf\" />\r\n    <Parameter name=\"PackageCertificatePath\" value=\"certificate.pfx\"/>\r\n    <Parameter name=\"PowerShellModulePath\" value=\"TestPowerShellModule.psd1\" />\r\n    <Parameter name=\"LocalServerCertPathParameter\" value=\"servercert.cer\" />\r\n    <Parameter name=\"SkipTestSource\" value=\"false\" />\r\n  </TestRunParameters>\r\n</RunSettings>\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/ConfigServerUnexpectedExit.yml",
    "content": "properties:\r\n    configurationVersion: 0.2\r\n    resources:\r\n      - resource: xE2ETestResource/E2ETestResourceCrash\r\n        id: first\r\n        directives:\r\n          repository: AppInstallerCLIE2ETestsRepo\r\n        settings:\r\n          key: Foo\r\n      - resource: xE2ETestResource/E2EFileResource\r\n        dependsOn:\r\n          - first\r\n        directives:\r\n          repository: AppInstallerCLIE2ETestsRepo\r\n        settings:\r\n          Path: ${WinGetConfigRoot}\\ConfigServerUnexpectedExit.txt\r\n          Content: Contents!\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/Configure_TestRepo.yml",
    "content": "properties:\r\n    configurationVersion: 0.2\r\n    resources:\r\n      - resource: xE2ETestResource/E2EFileResource\r\n        directives:\r\n          repository: AppInstallerCLIE2ETestsRepo\r\n        settings:\r\n          Path: ${WinGetConfigRoot}\\Configure_TestRepo.txt\r\n          Content: Contents!\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/Configure_TestRepo_DSCv3.yml",
    "content": "$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json\r\nmetadata:\r\n  winget:\r\n    processor: dscv3\r\nresources:\r\n  - name: Test File\r\n    type: xE2ETestResource/E2EFileResource\r\n    properties:\r\n      Path: ${WinGetConfigRoot}\\Configure_TestRepo.txt\r\n      Content: Contents!\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/Configure_TestRepo_Location.yml",
    "content": "properties:\r\n    configurationVersion: 0.2\r\n    assertions:\r\n      - resource: xE2ETestResource/E2ETestResource\r\n        directives:\r\n          repository: AppInstallerCLIE2ETestsRepo\r\n        settings:\r\n          SecretCode: 4815162342"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/DependencyCycle.yml",
    "content": "properties:\r\n    configurationVersion: 0.2\r\n    resources:\r\n      - resource: xE2ETestResource/E2ETestResourceThrows\r\n        id: A\r\n        dependsOn:\r\n          - B\r\n        directives:\r\n          repository: AppInstallerCLIE2ETestsRepo\r\n        settings:\r\n          key: Foo\r\n      - resource: xE2ETestResource/E2EFileResource\r\n        id: B\r\n        dependsOn:\r\n          - A\r\n        directives:\r\n          repository: AppInstallerCLIE2ETestsRepo\r\n        settings:\r\n          Path: ${WinGetConfigRoot}\\IndependentResources_OneFailure.txt\r\n          Content: Contents!\r\n      - resource: NotMentioned\r\n        settings:\r\n          A: B\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/DependentResources_Failure.yml",
    "content": "properties:\r\n    configurationVersion: 0.2\r\n    resources:\r\n      - resource: xE2ETestResource/E2ETestResourceThrows\r\n        id: first\r\n        directives:\r\n          repository: AppInstallerCLIE2ETestsRepo\r\n        settings:\r\n          key: Foo\r\n      - resource: xE2ETestResource/E2EFileResource\r\n        dependsOn:\r\n          - first\r\n        directives:\r\n          repository: AppInstallerCLIE2ETestsRepo\r\n        settings:\r\n          Path: ${WinGetConfigRoot}\\DependentResources_Failure.txt\r\n          Content: Contents!\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/DuplicateIdentifiers.yml",
    "content": "properties:\r\n    configurationVersion: 0.2\r\n    resources:\r\n      - resource: xE2ETestResource/E2ETestResourceThrows\r\n        id: same\r\n        directives:\r\n          repository: AppInstallerCLIE2ETestsRepo\r\n        settings:\r\n          key: Foo\r\n      - resource: xE2ETestResource/E2EFileResource\r\n        id: same\r\n        directives:\r\n          repository: AppInstallerCLIE2ETestsRepo\r\n        settings:\r\n          Path: ${WinGetConfigRoot}\\IndependentResources_OneFailure.txt\r\n          Content: Contents!\r\n      - resource: NotMentioned\r\n        settings:\r\n          A: B\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/Empty.yml",
    "content": ""
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/GetPSModulePath.yml",
    "content": "$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json\r\nmetadata:\r\n  1e62d683-2999-44e7-81f7-6f8f35e8d731: true\r\nresources:\r\n  - name: Name1\r\n    type: xE2ETestResource/E2ETestResourcePSModulePath\r\n    metadata:\r\n      repository: AppInstallerCLIE2ETestsRepo\r\n      securityContext: elevated\r\n    properties:\r\n      outputPath: ${WinGetConfigRoot}\\PSModulePath.txt\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/IndependentResources_OneFailure.yml",
    "content": "properties:\r\n    configurationVersion: 0.2\r\n    resources:\r\n      - resource: xE2ETestResource/E2ETestResourceThrows\r\n        directives:\r\n          repository: AppInstallerCLIE2ETestsRepo\r\n        settings:\r\n          key: Foo\r\n      - resource: xE2ETestResource/E2EFileResource\r\n        directives:\r\n          repository: AppInstallerCLIE2ETestsRepo\r\n        settings:\r\n          Path: ${WinGetConfigRoot}\\IndependentResources_OneFailure.txt\r\n          Content: Contents!\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/Init-TestRepository.ps1",
    "content": "# Copyright (c) Microsoft Corporation.\r\n# Licensed under the MIT License.\r\n[CmdletBinding()]\r\nparam(\r\n    [string]$ModulesPath,\r\n\r\n    [string]$RepositoryPath,\r\n\r\n    [string]$RepositoryName,\r\n\r\n    [switch]$Force\r\n)\r\n\r\nif ([System.String]::IsNullOrEmpty($ModulesPath))\r\n{\r\n    $ModulesPath = Join-Path $PSScriptRoot \"Modules\"\r\n}\r\n\r\nif ([System.String]::IsNullOrEmpty($RepositoryPath))\r\n{\r\n    $RepositoryPath = Join-Path ([System.IO.Path]::GetTempPath()) (New-Guid)\r\n}\r\n\r\nif ([System.String]::IsNullOrEmpty($RepositoryName))\r\n{\r\n    $RepositoryName = \"AppInstallerCLIE2ETestsRepo\"\r\n}\r\n\r\nif ($Force) {\r\n    $null = New-Item -Path $RepositoryPath -ItemType Directory -Force\r\n} else {\r\n    $null = New-Item -Path $RepositoryPath -ItemType Directory -ErrorAction Inquire\r\n}\r\n\r\n$Local:existingRepository = Get-PSRepository -Name $RepositoryName -ErrorAction Ignore\r\nif ($Local:existingRepository)\r\n{\r\n    if ($Force)\r\n    {\r\n        Unregister-PSRepository -Name $RepositoryName\r\n    }\r\n    else\r\n    {\r\n        throw \"Repository named $RepositoryName is already registered. Use -Force to overwrite it.\"\r\n    }\r\n}\r\n\r\n$null = Register-PSRepository -Name $RepositoryName -SourceLocation $RepositoryPath -ScriptSourceLocation $RepositoryPath\r\n\r\n$Local:allItems = Get-ChildItem $ModulesPath\r\n\r\n$Local:progressActivity = \"Publishing modules to $RepositoryPath\"\r\nWrite-Progress -Activity $Local:progressActivity\r\n\r\n[Int32]$Local:modulesPublished = 0\r\n\r\n$Local:allItems | ForEach-Object -Process {\r\n    $Local:modulePath = $_.FullName\r\n    Write-Verbose \"Publishing $Local:modulePath\"\r\n    Publish-Module -Path $Local:modulePath -Repository $RepositoryName -Force\r\n    $Local:modulesPublished += 1\r\n    Write-Progress -Activity $Local:progressActivity -PercentComplete (($Local:modulesPublished * 100) / $Local:allItems.Count)\r\n}\r\n\r\nWrite-Progress -Activity $Local:progressActivity -Completed\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/LargeContentStrings.yml",
    "content": "properties:\r\n    configurationVersion: 0.2\r\n    resources:\r\n      - resource: xE2EMalicious/E2EMalicious\r\n        id: firstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirst\r\n        directives:\r\n          repository: AppInstallerCLIE2ETestsRepo\r\n          description: \"Line1\\nLine2\\nLine3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3\\nLine4\\nLine5\\nLine6\"\r\n        settings:\r\n          key: Foo\r\n          description: \"Line1\\nLine2\\nLine3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3\\nLine4\\nLine5\\nLine6\"\r\n      - resource: Unknown\r\n        dependsOn:\r\n          - firstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirstfirst\r\n        directives:\r\n          module: UnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknownUnknown\r\n          repository: AppInstallerCLIE2ETestsRepo\r\n          description: \"Line1\\nLine2\\nLine3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3\\nLine4\\nLine5\\nLine6\"\r\n        settings:\r\n          Path: ${WinGetConfigRoot}\\ConfigServerUnexpectedExit.txt\r\n          Content: Contents!\r\n          description: \"Line1\\nLine2\\nLine3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3Line3\\nLine4\\nLine5\\nLine6\"\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/MissingDependency.yml",
    "content": "properties:\r\n    configurationVersion: 0.2\r\n    resources:\r\n      - resource: xE2ETestResource/E2ETestResourceThrows\r\n        id: same\r\n        directives:\r\n          repository: AppInstallerCLIE2ETestsRepo\r\n        settings:\r\n          key: Foo\r\n      - resource: xE2ETestResource/E2EFileResource\r\n        dependsOn:\r\n          - same\r\n        directives:\r\n          repository: AppInstallerCLIE2ETestsRepo\r\n        settings:\r\n          Path: ${WinGetConfigRoot}\\IndependentResources_OneFailure.txt\r\n          Content: Contents!\r\n      - resource: MissingDependency\r\n        dependsOn:\r\n          - missing\r\n        settings:\r\n          A: B\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/ModuleMismatch.yml",
    "content": "properties:\r\n  configurationVersion: 0.2\r\n  resources:\r\n    - resource: Module/Resource\r\n      id: Identifier\r\n      directives:\r\n        module: DifferentModule\r\n      settings:\r\n        SettingInt: 1"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/Modules/xE2EMalicious/xE2EMalicious.psd1",
    "content": "﻿#\r\n# Module manifest for module 'xE2ETestResource'\r\n#\r\n\r\n@{\r\n\r\nRootModule = 'xE2EMalicious.psm1'\r\nModuleVersion = '0.0.0.1'\r\nGUID = 'a0be43e8-ac22-4244-8efc-7263dfa50b92'\r\nCompatiblePSEditions = 'Core'\r\nAuthor = \"WinGet Dev Team\"\r\nCompanyName = 'Microsoft Corporation'\r\nCopyright = '(c) Microsoft Corporation. All rights reserved.'\r\nDescription = \"PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests | PowerShell module with DSC resources for unit tests\"\r\nPowerShellVersion = '7.2'\r\nFunctionsToExport = @()\r\nCmdletsToExport = @()\r\nDscResourcesToExport = @(\r\n    'E2EMalicious'\r\n)\r\nHelpInfoURI = 'https://www.contoso.com/help'\r\n\r\n# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.\r\nPrivateData = @{\r\n\r\n    PSData = @{\r\n        ProjectUri = 'https://github.com/microsoft/winget-cli'\r\n        IconUri = 'https://www.contoso.com/icons/icon.png'\r\n    }\r\n\r\n}\r\n\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/Modules/xE2EMalicious/xE2EMalicious.psm1",
    "content": "﻿# E2E module with resources.\r\n\r\nenum Ensure\r\n{\r\n    Absent\r\n    Present\r\n}\r\n\r\n# This resource just checks if a file is there or not with and if its with the specified content.\r\n[DscResource()]\r\nclass E2EMalicious\r\n{\r\n    [DscProperty(Key)]\r\n    [string] $Path\r\n\r\n    [DscProperty()]\r\n    [Ensure] $Ensure = [Ensure]::Present\r\n\r\n    [DscProperty()]\r\n    [string] $Content = $null\r\n\r\n    [E2EFileResource] Get()\r\n    {\r\n        if ([string]::IsNullOrEmpty($this.Path))\r\n        {\r\n            throw\r\n        }\r\n\r\n        $fileContent = $null\r\n        if (Test-Path -Path $this.Path -PathType Leaf)\r\n        {\r\n            $fileContent = Get-Content $this.Path -Raw\r\n        }\r\n\r\n        $result = @{\r\n            Path = $this.Path\r\n            Content = $fileContent\r\n        }\r\n\r\n        return $result\r\n    }\r\n\r\n    [bool] Test()\r\n    {\r\n        $get = $this.Get()\r\n\r\n        if (Test-Path -Path $this.Path -PathType Leaf)\r\n        {\r\n            if ($this.Ensure -eq [Ensure]::Present)\r\n            {\r\n                return $this.Content -eq $get.Content\r\n            }\r\n        }\r\n        elseif ($this.Ensure -eq [Ensure]::Absent)\r\n        {\r\n            return $true\r\n        }\r\n\r\n        return $false\r\n    }\r\n\r\n    [void] Set()\r\n    {\r\n        if (-not $this.Test())\r\n        {\r\n            if (Test-Path -Path $this.Path -PathType Leaf)\r\n            {\r\n                if ($this.Ensure -eq [Ensure]::Present)\r\n                {\r\n                    Set-Content $this.Path $this.Content -NoNewline\r\n                }\r\n                else\r\n                {\r\n                    Remove-Item $this.Path\r\n                }\r\n            }\r\n            else\r\n            {\r\n                if ($this.Ensure -eq [Ensure]::Present)\r\n                {\r\n                    Set-Content $this.Path $this.Content -NoNewline\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/Modules/xE2ETestResource/xE2ETestResource.psd1",
    "content": "#\r\n# Module manifest for module 'xE2ETestResource'\r\n#\r\n\r\n@{\r\n\r\nRootModule = 'xE2ETestResource.psm1'\r\nModuleVersion = '0.0.0.1'\r\nGUID = 'a0be43e8-ac22-4244-8efc-7263dfa50b8c'\r\nCompatiblePSEditions = 'Core'\r\nAuthor = 'WinGet Dev Team'\r\nCompanyName = 'Microsoft Corporation'\r\nCopyright = '(c) Microsoft Corporation. All rights reserved.'\r\nDescription = 'PowerShell module with DSC resources for unit tests'\r\nPowerShellVersion = '7.2'\r\nFunctionsToExport = @()\r\nCmdletsToExport = @()\r\nDscResourcesToExport = @(\r\n    'E2EFileResource'\r\n    'E2ETestResource'\r\n    'E2ETestResourceThrows'\r\n    'E2ETestResourceError'\r\n    'E2ETestResourceTypes'\r\n    'E2ETestResourceCrash'\r\n    'E2ETestResourcePID'\r\n    'E2ETestResourcePSModulePath'\r\n)\r\nHelpInfoURI = 'https://www.contoso.com/help'\r\n\r\n# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.\r\nPrivateData = @{\r\n\r\n    PSData = @{\r\n        ProjectUri = 'https://github.com/microsoft/winget-cli'\r\n        IconUri = 'https://www.contoso.com/icons/icon.png'\r\n    }\r\n\r\n}\r\n\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/Modules/xE2ETestResource/xE2ETestResource.psm1",
    "content": "# E2E module with resources.\r\n\r\nenum Ensure\r\n{\r\n    Absent\r\n    Present\r\n}\r\n\r\n# This resource just checks if a file is there or not with and if its with the specified content.\r\n[DscResource()]\r\nclass E2EFileResource\r\n{\r\n    [DscProperty(Key)]\r\n    [string] $Path\r\n\r\n    [DscProperty()]\r\n    [Ensure] $Ensure = [Ensure]::Present\r\n\r\n    [DscProperty()]\r\n    [string] $Content = $null\r\n\r\n    [E2EFileResource] Get()\r\n    {\r\n        if ([string]::IsNullOrEmpty($this.Path))\r\n        {\r\n            throw\r\n        }\r\n\r\n        $fileContent = $null\r\n        if (Test-Path -Path $this.Path -PathType Leaf)\r\n        {\r\n            $fileContent = Get-Content $this.Path -Raw\r\n        }\r\n\r\n        $result = @{\r\n            Path = $this.Path\r\n            Content = $fileContent\r\n        }\r\n\r\n        return $result\r\n    }\r\n\r\n    [bool] Test()\r\n    {\r\n        $get = $this.Get()\r\n\r\n        if (Test-Path -Path $this.Path -PathType Leaf)\r\n        {\r\n            if ($this.Ensure -eq [Ensure]::Present)\r\n            {\r\n                return $this.Content -eq $get.Content\r\n            }\r\n        }\r\n        elseif ($this.Ensure -eq [Ensure]::Absent)\r\n        {\r\n            return $true\r\n        }\r\n\r\n        return $false\r\n    }\r\n\r\n    [void] Set()\r\n    {\r\n        if (-not $this.Test())\r\n        {\r\n            if (Test-Path -Path $this.Path -PathType Leaf)\r\n            {\r\n                if ($this.Ensure -eq [Ensure]::Present)\r\n                {\r\n                    Set-Content $this.Path $this.Content -NoNewline\r\n                }\r\n                else\r\n                {\r\n                    Remove-Item $this.Path\r\n                }\r\n            }\r\n            else\r\n            {\r\n                if ($this.Ensure -eq [Ensure]::Present)\r\n                {\r\n                    Set-Content $this.Path $this.Content -NoNewline\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\n[DscResource()]\r\nclass E2ETestResource\r\n{\r\n    [DscProperty(Key)]\r\n    [string] $key\r\n\r\n    [DscProperty(Mandatory)]\r\n    [string] $secretCode\r\n\r\n    [E2ETestResource] Get()\r\n    {\r\n        $result = @{\r\n            key = \"E2ETestResourceKey\"\r\n        }\r\n        return $result\r\n    }\r\n\r\n    [bool] Test()\r\n    {\r\n        return $this.secretCode -eq \"4815162342\"\r\n    }\r\n\r\n    [void] Set()\r\n    {\r\n        if (-not $this.Test())\r\n        {\r\n            $global:DSCMachineStatus = 1\r\n        }\r\n    }\r\n}\r\n\r\n[DscResource()]\r\nclass E2ETestResourceThrows\r\n{\r\n    [DscProperty(Key)]\r\n    [string] $key\r\n\r\n    [E2ETestResourceThrows] Get()\r\n    {\r\n        $result = @{\r\n            key = \"E2ETestResourceThrowsKey\"\r\n        }\r\n        throw \"throws in Get\"\r\n        return $result\r\n    }\r\n\r\n    [bool] Test()\r\n    {\r\n        throw \"throws in Test\"\r\n        return $false\r\n    }\r\n\r\n    [void] Set()\r\n    {\r\n        throw \"throws in Set\"\r\n    }\r\n}\r\n\r\n[DscResource()]\r\nclass E2ETestResourceError\r\n{\r\n    [DscProperty(Key)]\r\n    [string] $key\r\n\r\n    [E2ETestResourceError] Get()\r\n    {\r\n        $result = @{\r\n            key = \"E2ETestResourceErrorKey\"\r\n        }\r\n        Write-Error \"Error in Get\"\r\n        return $result\r\n    }\r\n\r\n    [bool] Test()\r\n    {\r\n        Write-Error \"Error in Test\"\r\n        return $true\r\n    }\r\n\r\n    [void] Set()\r\n    {\r\n        Write-Error \"Error in Set\"\r\n    }\r\n}\r\n\r\n[DscResource()]\r\nclass E2ETestResourceTypes\r\n{\r\n    [DscProperty(Key)]\r\n    [string] $key\r\n\r\n    [DscProperty()]\r\n    [boolean] $boolProperty\r\n\r\n    [DscProperty()]\r\n    [int] $intProperty;\r\n\r\n    [DscProperty()]\r\n    [double] $doubleProperty;\r\n\r\n    [DscProperty()]\r\n    [char] $charProperty;\r\n\r\n    [DscProperty()]\r\n    [Hashtable] $hashtableProperty;\r\n\r\n    [E2ETestResourceTypes] Get()\r\n    {\r\n        $result = @{\r\n            key = \"E2ETestResourceTypesKey\"\r\n            boolProperty = $false\r\n            intProperty = 0\r\n            doubleProperty = 0.0\r\n            charProperty = 'z'\r\n            hashtableProperty = @{}\r\n        }\r\n        return $result\r\n    }\r\n\r\n    [bool] Test()\r\n    {\r\n        # Because we can't get the error stream from a class based resource, I throw so is easier to know if\r\n        # there's something wrong.\r\n        if ($this.boolProperty -ne $true)\r\n        {\r\n            throw \"Failed boolProperty\"\r\n        }\r\n\r\n        if ($this.intProperty -ne 3)\r\n        {\r\n            throw \"Failed intProperty. Got $($this.intProperty)\"\r\n        }\r\n\r\n        if ($this.doubleProperty -ne -9.876)\r\n        {\r\n            throw \"Failed doubleProperty Got $($this.doubleProperty)\"\r\n        }\r\n\r\n        if ($this.charProperty -ne 'f')\r\n        {\r\n            throw \"Failed charProperty Got $($this.charProperty)\"\r\n        }\r\n\r\n        if ($this.hashtableProperty.ContainsKey(\"secretStringKey\"))\r\n        {\r\n            if ($this.hashtableProperty[\"secretStringKey\"] -ne \"secretCode\")\r\n            {\r\n                throw \"Failed comparing value of `$hashtableProperty.secretStringKey Got $($this.hashtableProperty[\"secretStringKey\"])\"\r\n            }\r\n        }\r\n        else\r\n        {\r\n            throw \"Failed finding secretStringKey in hashtableProperty\"\r\n        }\r\n\r\n        if ($this.hashtableProperty.ContainsKey(\"secretIntKey\"))\r\n        {\r\n            if ($this.hashtableProperty[\"secretIntKey\"] -ne 123456)\r\n            {\r\n                throw \"Failed comparing value of `$hashtableProperty.secretIntKey Got $($this.hashtableProperty[\"secretIntKey\"])\"\r\n            }\r\n        }\r\n        else\r\n        {\r\n            throw \"Failed finding secretIntKey in hashtableProperty\"\r\n        }\r\n\r\n        return $true\r\n    }\r\n\r\n    [void] Set()\r\n    {\r\n        # no-op\r\n    }\r\n}\r\n\r\n# This resource \"crashes\" the containing process (really it just exits)\r\n[DscResource()]\r\nclass E2ETestResourceCrash\r\n{\r\n    [DscProperty(Key)]\r\n    [string] $key\r\n\r\n    [E2ETestResourceCrash] Get()\r\n    {\r\n        $result = @{\r\n            key = \"E2ETestResourceCrashKey\"\r\n        }\r\n        [System.Environment]::Exit(0)\r\n        return $result\r\n    }\r\n\r\n    [bool] Test()\r\n    {\r\n        [System.Environment]::Exit(0)\r\n        return $true\r\n    }\r\n\r\n    [void] Set()\r\n    {\r\n        [System.Environment]::Exit(0)\r\n    }\r\n}\r\n\r\n# This resource writes the current PID to the provided file path.\r\n[DscResource()]\r\nclass E2ETestResourcePID\r\n{\r\n    [DscProperty(Key)]\r\n    [string] $key\r\n\r\n    [DscProperty(Mandatory)]\r\n    [string] $directoryPath\r\n\r\n    [E2ETestResourcePID] Get()\r\n    {\r\n        $result = @{\r\n            key = \"E2ETestResourcePID\"\r\n            directoryPath = $this.directoryPath\r\n        }\r\n\r\n        return $result\r\n    }\r\n\r\n    [bool] Test()\r\n    {\r\n        return $false\r\n    }\r\n\r\n    [void] Set()\r\n    {\r\n        if (Test-Path -Path $this.directoryPath)\r\n        {\r\n            $processId = [System.Diagnostics.Process]::GetCurrentProcess().Id\r\n            $filePath = Join-Path -Path $this.directoryPath -ChildPath \"$processId.txt\"\r\n            New-Item -Path $filePath -ItemType File -Force  \r\n        }\r\n    }\r\n}\r\n\r\n# This resource writes the current PSModulePath to the provided file path.\r\n[DscResource()]\r\nclass E2ETestResourcePSModulePath\r\n{\r\n    [DscProperty(Key)]\r\n    [string] $key\r\n\r\n    [DscProperty(Mandatory)]\r\n    [string] $outputPath\r\n\r\n    [E2ETestResourcePSModulePath] Get()\r\n    {\r\n        $result = @{\r\n            key = \"E2ETestResourcePSModulePath\"\r\n            outputPath = $this.outputPath\r\n        }\r\n\r\n        return $result\r\n    }\r\n\r\n    [bool] Test()\r\n    {\r\n        return $false\r\n    }\r\n\r\n    [void] Set()\r\n    {\r\n        Set-Content -Path $this.outputPath -Value $env:PSModulePath -Force\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/NoResourceName.yml",
    "content": "properties:\r\n  configurationVersion: 0.2\r\n  resources:\r\n    - resource: Module/\r\n      id: Identifier\r\n      settings:\r\n        SettingInt: 1"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/NoVersion.yml",
    "content": "properties:\r\n  value: 1"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/NotConfig.yml",
    "content": "yaml: true"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/PSGallery_NoModule_NoSettings.yml",
    "content": "properties:\r\n    configurationVersion: 0.1\r\n    resources:\r\n      - resource: XmlFileContentResource\r\n        directives:\r\n          description: Set XML file contents\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/PSGallery_NoSettings.yml",
    "content": "properties:\r\n    configurationVersion: 0.2\r\n    resources:\r\n      - resource: XmlContentDsc/XmlFileContentResource\r\n        directives:\r\n          description: Set XML file contents\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/ResourceCaseInsensitive.yml",
    "content": "properties:\r\n    configurationVersion: 0.2\r\n    resources:\r\n      - resource: xE2ETestResource/e2efileresource\r\n        directives:\r\n          repository: AppInstallerCLIE2ETestsRepo\r\n        settings:\r\n          Path: ${WinGetConfigRoot}\\ResourceCaseInsensitive.txt\r\n          Content: Contents!\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/ResourceNotFound.yml",
    "content": "properties:\r\n    configurationVersion: 0.2\r\n    resources:\r\n      - resource: moduleThatDoesNotExist/resourceThatDoesNotExist\r\n        directives:\r\n          repository: AppInstallerCLIE2ETestsRepo\r\n        settings:\r\n          key: Foo\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/ResourcesNotASequence.yml",
    "content": "properties:\r\n  configurationVersion: 0.1\r\n  resources: 1"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/RunCommandOnSet.yml",
    "content": "$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json\r\nmetadata:\r\n  winget:\r\n    processor: dscv3\r\nresources:\r\n  - name: Test RunCommandOnSet\r\n    type: Microsoft.DSC.Transitional/RunCommandOnSet\r\n    properties:\r\n      executable: pwsh\r\n      arguments:\r\n        - -NoProfile\r\n        - -NoLogo\r\n        - -Command\r\n        - |\r\n          Set-Content -Path <PathToBeReplaced>\\TestFile.txt -Value 'TestContent'\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/ShowDetails_DSCv3.yml",
    "content": "$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json\r\nmetadata:\r\n  winget:\r\n    processor: dscv3\r\nresources:\r\n  - name: Test File\r\n    type: Microsoft.WinGet.Dev/TestFile\r\n    metadata:\r\n      description: Description 1.\r\n    properties:\r\n      path: ${WinGetConfigRoot}\\ShowDetails_DSCv3.txt\r\n      content: DSCv3 Contents!\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/ShowDetails_TestRepo.yml",
    "content": "properties:\r\n    configurationVersion: 0.2\r\n    resources:\r\n      - resource: xE2ETestResource/E2EFileResource\r\n        directives:\r\n          repository: AppInstallerCLIE2ETestsRepo\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/ShowDetails_TestRepo_0_3.yml",
    "content": "$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json\r\nresources:\r\n  - name: Name1\r\n    type: xE2ETestResource/E2EFileResource\r\n    metadata:\r\n      repository: AppInstallerCLIE2ETestsRepo\r\n    properties:\r\n      prop1: 3\r\n      prop2: '4'\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/UnitNotAMap.yml",
    "content": "properties:\r\n  configurationVersion: 0.1\r\n  resources:\r\n    - string"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/UnknownVersion.yml",
    "content": "properties:\r\n  configurationVersion: 99999999"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/Unknown_Processor.yml",
    "content": "$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json\r\nmetadata:\r\n  winget:\r\n    processor: unknown\r\nresources:\r\n  - name: Name1\r\n    type: xE2ETestResource/E2EFileResource\r\n    metadata:\r\n      repository: AppInstallerCLIE2ETestsRepo\r\n    properties:\r\n      prop1: 3\r\n      prop2: '4'\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/WinGetDscResourceValidate_DependencySourceMissing.yml",
    "content": "properties:\n  configurationVersion: 0.2.0\n  resources:\n    - resource: Microsoft.WinGet.DSC/WinGetPackage\n      id: testPackage\n      directives:\n        description: Install Test Package\n        allowPrerelease: true\n      settings:\n        id: AppInstallerTest.TestExeInstaller\n        source: TestSource\n        version: \"1.0.1.0\"\n "
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/WinGetDscResourceValidate_Good.yml",
    "content": "properties:\n  configurationVersion: 0.2.0\n  resources:\n    - resource: Microsoft.WinGet.DSC/WinGetSource\n      id: configureSource\n      directives:\n        description: Add test source\n        allowPrerelease: true\n      settings:\n        Name: TestSource\n        Argument: \"https://localhost:5001/TestKit\"\n    - resource: Microsoft.WinGet.DSC/WinGetPackage\n      id: testPackage\n      dependsOn:\n        - configureSource\n      directives:\n        description: Install Test Package\n        allowPrerelease: true\n      settings:\n        id: AppInstallerTest.TestExeInstaller\n        source: TestSource\n        version: \"1.0.1.0\"\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/WinGetDscResourceValidate_PackageNotFound.yml",
    "content": "properties:\n  configurationVersion: 0.2.0\n  resources:\n    - resource: Microsoft.WinGet.DSC/WinGetSource\n      id: configureSource\n      directives:\n        description: Add test source\n        allowPrerelease: true\n      settings:\n        Name: TestSource\n        Argument: \"https://localhost:5001/TestKit\"\n    - resource: Microsoft.WinGet.DSC/WinGetPackage\n      id: testPackage\n      dependsOn:\n        - configureSource\n      directives:\n        description: Install Test Package\n        allowPrerelease: true\n      settings:\n        id: AppInstallerTest.DoesNotExist\n        source: TestSource\n        version: \"1.0.1.0\"\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/WinGetDscResourceValidate_PackageVersionNotFound.yml",
    "content": "properties:\n  configurationVersion: 0.2.0\n  resources:\n    - resource: Microsoft.WinGet.DSC/WinGetSource\n      id: configureSource\n      directives:\n        description: Add test source\n        allowPrerelease: true\n      settings:\n        Name: TestSource\n        Argument: \"https://localhost:5001/TestKit\"\n    - resource: Microsoft.WinGet.DSC/WinGetPackage\n      id: testPackage\n      dependsOn:\n        - configureSource\n      directives:\n        description: Install Test Package\n        allowPrerelease: true\n      settings:\n        id: AppInstallerTest.TestExeInstaller\n        source: TestSource\n        version: \"101.0.101.0\"\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/WinGetDscResourceValidate_SourceOpenFailed.yml",
    "content": "properties:\n  configurationVersion: 0.2.0\n  resources:\n    - resource: Microsoft.WinGet.DSC/WinGetSource\n      id: configureSource\n      directives:\n        description: Add test source\n        allowPrerelease: true\n      settings:\n        Name: TestSourceV2\n        Argument: \"https://localhost:5001/TestKit\"\n    - resource: Microsoft.WinGet.DSC/WinGetPackage\n      id: testPackage\n      dependsOn:\n        - configureSource\n      directives:\n        description: Install Test Package\n        allowPrerelease: true\n      settings:\n        id: AppInstallerTest.TestExeInstaller\n        source: TestSourceV2\n        version: \"1.0.1.0\"\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/WinGetDscResourceValidate_VersionSpecifiedWithOnlyOneVersionAvailable.yml",
    "content": "properties:\n  configurationVersion: 0.2.0\n  resources:\n    - resource: Microsoft.WinGet.DSC/WinGetSource\n      id: configureSource\n      directives:\n        description: Add test source\n        allowPrerelease: true\n      settings:\n        Name: TestSource\n        Argument: \"https://localhost:5001/TestKit\"\n    - resource: Microsoft.WinGet.DSC/WinGetPackage\n      id: testPackage\n      dependsOn:\n        - configureSource\n      directives:\n        description: Install Test Package\n        allowPrerelease: true\n      settings:\n        id: AppInstallerTest.TestValidManifest\n        source: TestSource\n        version: \"1.0.0.0\"\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/WinGetDscResourceValidate_VersionSpecifiedWithUseLatest.yml",
    "content": "properties:\n  configurationVersion: 0.2.0\n  resources:\n    - resource: Microsoft.WinGet.DSC/WinGetSource\n      id: configureSource\n      directives:\n        description: Add test source\n        allowPrerelease: true\n      settings:\n        Name: TestSource\n        Argument: \"https://localhost:5001/TestKit\"\n    - resource: Microsoft.WinGet.DSC/WinGetPackage\n      id: testPackage\n      dependsOn:\n        - configureSource\n      directives:\n        description: Install Test Package\n        allowPrerelease: true\n      settings:\n        id: AppInstallerTest.TestExeInstaller\n        source: TestSource\n        version: \"1.0.1.0\"\n        useLatest: true\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Configuration/WithParameters_0_3.yml",
    "content": "$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json\r\nparameters:\r\n  param1:\r\n    type: string\r\n    defaultValue: value\r\nresources:\r\n  - name: Name1\r\n    type: xE2ETestResource/E2EFileResource\r\n    metadata:\r\n      repository: AppInstallerCLIE2ETestsRepo\r\n    properties:\r\n      prop1: 3\r\n      prop2: '4'\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/ImportFiles/ImportFile-Bad-Invalid.json",
    "content": "\"A valid JSON file that does not conform to the schema\""
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/ImportFiles/ImportFile-Bad-UnknownPackage.json",
    "content": "{\n  \"$schema\": \"https://aka.ms/winget-packages.schema.1.0.json\",\n  \"CreationDate\": \"2021-01-01T12:00:00.000-00:00\",\n  \"Sources\": [\n    {\n      \"Packages\": [\n        {\n          \"Id\": \"MissingPackage\",\n          \"Version\": \"1.0.0.0\"\n        }\n      ],\n      \"SourceDetails\": {\n        \"Name\": \"TestSource\",\n        \"Argument\": \"https://localhost:5001/TestKit\",\n        \"Identifier\": \"WingetE2E.Tests_8wekyb3d8bbwe\",\n        \"Type\": \"Microsoft.PreIndexed.Package\"\n      }\n    }\n  ],\n  \"WinGetVersion\": \"1.0.0\"\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/ImportFiles/ImportFile-Bad-UnknownPackageVersion.json",
    "content": "{\n  \"$schema\": \"https://aka.ms/winget-packages.schema.2.0.json\",\n  \"CreationDate\": \"2021-01-01T12:00:00.000-00:00\",\n  \"Sources\": [\n    {\n      \"Packages\": [\n        {\n          \"PackageIdentifier\": \"AppInstallerTest.TestExeInstaller\",\n          \"Version\": \"4.3.2.1\"\n        }\n      ],\n      \"SourceDetails\": {\n        \"Name\": \"TestSource\",\n        \"Argument\": \"https://localhost:5001/TestKit\",\n        \"Identifier\": \"WingetE2E.Tests_8wekyb3d8bbwe\",\n        \"Type\": \"Microsoft.PreIndexed.Package\"\n      }\n    }\n  ]\n}"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/ImportFiles/ImportFile-Bad-UnknownSource.json",
    "content": "{\n  \"$schema\": \"https://aka.ms/winget-packages.schema.1.0.json\",\n  \"CreationDate\": \"2021-01-01T12:00:00.000-00:00\",\n  \"Sources\": [\n    {\n      \"Packages\": [\n        {\n          \"Id\": \"AppInstallerTest.TestExeInstaller\",\n          \"Version\": \"1.0.0.0\"\n        }\n      ],\n      \"SourceDetails\": {\n        \"Name\": \"TestSource\",\n        \"Argument\": \"https://localhost\",\n        \"Identifier\": \"WingetE2E.UnknownTestSource_8wekyb3d8bbwe\",\n        \"Type\": \"Microsoft.PreIndexed.Package\"\n      }\n    }\n  ],\n  \"WinGetVersion\": \"1.0.0\"\n}"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/ImportFiles/ImportFile-Good.1.0.json",
    "content": "{\n  \"$schema\": \"https://aka.ms/winget-packages.schema.1.0.json\",\n  \"CreationDate\": \"2021-01-01T12:00:00.000-00:00\",\n  \"Sources\": [\n    {\n      \"Packages\": [\n        {\n          \"Id\": \"AppInstallerTest.TestExeInstaller\",\n          \"Version\": \"1.0.0.0\"\n        }\n      ],\n      \"SourceDetails\": {\n        \"Name\": \"TestSource\",\n        \"Argument\": \"https://localhost:5001/TestKit\",\n        \"Identifier\": \"WingetE2E.Tests_8wekyb3d8bbwe\",\n        \"Type\": \"Microsoft.PreIndexed.Package\"\n      }\n    }\n  ],\n  \"WinGetVersion\": \"1.0.0\"\n}"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/ImportFiles/ImportFile-Good.2.0.json",
    "content": "{\n  \"$schema\": \"https://aka.ms/winget-packages.schema.2.0.json\",\n  \"CreationDate\": \"2021-01-01T12:00:00.000-00:00\",\n  \"Sources\": [\n    {\n      \"Packages\": [\n        {\n          \"PackageIdentifier\": \"AppInstallerTest.TestExeInstaller\",\n          \"Version\": \"1.0.0.0\"\n        }\n      ],\n      \"SourceDetails\": {\n        \"Name\": \"TestSource\",\n        \"Argument\": \"https://localhost:5001/TestKit\",\n        \"Identifier\": \"WingetE2E.Tests_8wekyb3d8bbwe\",\n        \"Type\": \"Microsoft.PreIndexed.Package\"\n      }\n    }\n  ],\n  \"WinGetVersion\": \"1.0.0\"\n}"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/IndexPackageManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Package xmlns=\"http://schemas.microsoft.com/appx/manifest/foundation/windows10\"\r\n         xmlns:uap4=\"http://schemas.microsoft.com/appx/manifest/uap/windows10/4\"\r\n         IgnorableNamespaces=\"uap4\">\r\n\r\n  <Identity Name=\"AppInstallerSQLiteIndex-e2etest\"\r\n            ProcessorArchitecture=\"neutral\"\r\n            Publisher=\"CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US\"\r\n            Version=\"1.0.0.0\" />\r\n\r\n  <Properties>\r\n    <DisplayName>Microsoft WinGet Source</DisplayName>\r\n    <PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>\r\n    <Logo>Assets\\AppPackageStoreLogo.png</Logo>\r\n  </Properties>\r\n\r\n  <Dependencies>\r\n    <TargetDeviceFamily Name=\"Windows.Universal\" MinVersion=\"10.0.17763.0\" MaxVersionTested=\"10.0.18287.0\" />\r\n  </Dependencies>\r\n\r\n  <Applications>\r\n    <Application Id=\"SourceData\">\r\n      <uap:VisualElements DisplayName=\"Source data for Microsoft WinGet\" Square150x150Logo=\"Assets\\AppPackageStoreLogo.scale-150.png\" Square44x44Logo=\"Assets\\AppPackageStoreLogo.scale-100.png\" Description=\"Source data for Microsoft WinGet.\" BackgroundColor=\"#0078d7\" AppListEntry=\"none\" />\r\n      <Extensions>\r\n        <uap3:Extension Category=\"windows.appExtension\">\r\n          <uap3:AppExtension Name=\"com.microsoft.winget.source\"\r\n                             Id=\"IndexDB\"\r\n                             DisplayName=\"Source data for Microsoft WinGet\"\r\n                             Description=\"Source data for Microsoft WinGet\"\r\n                             PublicFolder=\"Public\">\r\n          </uap3:AppExtension>\r\n        </uap3:Extension>\r\n      </Extensions>\r\n    </Application>\r\n  </Applications>\r\n\r\n  <Resources>\r\n    <Resource Language=\"und\" />\r\n  </Resources>\r\n\r\n</Package>"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestArpVersionMapping_OppositeOrder_1.0.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.2.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestArpVersionOppositeOrder\r\nPackageVersion: '1.0'\r\nPackageName: TestArpVersionOppositeOrder\r\nPackageLocale: en-US\r\nPublisher: Microsoft\r\nLicense: Test\r\nShortDescription: E2E test for arp version test.\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    InstallerType: exe\r\n    InstallerSha256: <EXEHASH>\r\n    AppsAndFeaturesEntries:\r\n    - DisplayVersion: \"10.0\"\r\n    - DisplayVersion: \"10.5\"\r\nManifestType: singleton\r\nManifestVersion: 1.2.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestArpVersionMapping_OppositeOrder_2.0.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.2.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestArpVersionOppositeOrder\r\nPackageVersion: '2.0'\r\nPackageName: TestArpVersionOppositeOrder\r\nPackageLocale: en-US\r\nPublisher: Microsoft\r\nLicense: Test\r\nShortDescription: E2E test for arp version test.\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    InstallerType: exe\r\n    InstallerSha256: <EXEHASH>\r\n    AppsAndFeaturesEntries:\r\n    - DisplayVersion: \"9.0\"\r\n    - DisplayVersion: \"9.5\"\r\nManifestType: singleton\r\nManifestVersion: 1.2.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestArpVersionMapping_SameAsPackageVersion.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.2.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestArpVersionSameVersion\r\nPackageVersion: '1.0'\r\nPackageName: TestArpVersionSameVersion\r\nPackageLocale: en-US\r\nPublisher: Microsoft\r\nLicense: Test\r\nShortDescription: E2E test for arp version test.\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    InstallerType: exe\r\n    InstallerSha256: <EXEHASH>\r\n    AppsAndFeaturesEntries:\r\n    - DisplayVersion: \"1.0\"\r\nManifestType: singleton\r\nManifestVersion: 1.2.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestArpVersionMapping_SameOrder_1.0.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.2.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestArpVersionSameOrder\r\nPackageVersion: '1.0'\r\nPackageName: TestArpVersionSameOrder\r\nPackageLocale: en-US\r\nPublisher: Microsoft\r\nLicense: Test\r\nShortDescription: E2E test for arp version test.\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    InstallerType: exe\r\n    InstallerSha256: <EXEHASH>\r\n    AppsAndFeaturesEntries:\r\n    - DisplayVersion: \"10.0\"\r\n    - DisplayVersion: \"10.5\"\r\nManifestType: singleton\r\nManifestVersion: 1.2.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestArpVersionMapping_SameOrder_2.0.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.2.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestArpVersionSameOrder\r\nPackageVersion: '2.0'\r\nPackageName: TestArpVersionSameOrder\r\nPackageLocale: en-US\r\nPublisher: Microsoft\r\nLicense: Test\r\nShortDescription: E2E test for arp version test.\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    InstallerType: exe\r\n    InstallerSha256: <EXEHASH>\r\n    AppsAndFeaturesEntries:\r\n    - DisplayVersion: \"11.0\"\r\n    - DisplayVersion: \"11.5\"\r\nManifestType: singleton\r\nManifestVersion: 1.2.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestBurnInstaller.MissingRepairBehavior.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.7.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestMissingRepairBehavior\r\nPackageVersion: 2.0.0.0\r\nPackageLocale: en-US\r\nPackageName: TestMissingRepairBehavior\r\nPublisher: AppInstallerTest\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n      InstallerType: burn\r\n      InstallerSha256: <EXEHASH>\r\n      ProductCode: '{A499DD5E-8DC5-4AD2-911A-BCD0263295E9}'\r\n      InstallerSwitches:\r\n        InstallLocation: /InstallDir <INSTALLPATH>\r\n        Custom: /Version 2.0.0.0 /DisplayName TestMissingRepairBehavior /UseHKLM\r\n        Repair: /repair\r\nManifestType: singleton\r\nManifestVersion: 1.7.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestBurnInstaller.ModifyRepair.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.7.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestModifyRepair\r\nPackageVersion: 2.0.0.0\r\nPackageLocale: en-US\r\nPackageName: TestModifyRepair\r\nPublisher: AppInstallerTest\r\nRepairBehavior: modify\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n      InstallerType: burn\r\n      InstallerSha256: <EXEHASH>\r\n      ProductCode: '{A499DD5E-8DC5-4AD2-911A-BCD0263295E9}'\r\n      InstallerSwitches:\r\n        InstallLocation: /InstallDir <INSTALLPATH>\r\n        Custom: /Version 2.0.0.0 /DisplayName TestModifyRepair /UseHKLM\r\n        Repair: /repair\r\nManifestType: singleton\r\nManifestVersion: 1.7.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestBurnInstaller.ModifyRepairWithNoModify.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.7.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestModifyRepairWithNoModify\r\nPackageVersion: 2.0.0.0\r\nPackageLocale: en-US\r\nPackageName: TestModifyRepairWithNoModify\r\nPublisher: AppInstallerTest\r\nRepairBehavior: modify\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n      InstallerType: burn\r\n      InstallerSha256: <EXEHASH>\r\n      ProductCode: '{A499DD5E-8DC5-4AD2-911A-BCD0263295E9}'\r\n      InstallerSwitches:\r\n        InstallLocation: /InstallDir <INSTALLPATH>\r\n        Custom: /Version 2.0.0.0 /DisplayName TestModifyRepairWithNoModify /UseHKLM /NoModify\r\n        Repair: /repair\r\nManifestType: singleton\r\nManifestVersion: 1.7.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestBurnInstaller.UserScopeInstallRepairInAdminContext.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.7.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestUserScopeInstallRepairInAdminContext\r\nPackageVersion: 2.0.0.0\r\nPackageLocale: en-US\r\nPackageName: TestUserScopeInstallRepairInAdminContext\r\nPublisher: AppInstallerTest\r\nRepairBehavior: modify\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n      InstallerType: burn\r\n      InstallerSha256: <EXEHASH>\r\n      ProductCode: '{A499DD5E-8DC5-4AD2-911A-BCD0263295E9}'\r\n      ElevationRequirement: elevationRequired\r\n      InstallerSwitches:\r\n        InstallLocation: /InstallDir <INSTALLPATH>\r\n        Custom: /Version 2.0.0.0 /DisplayName TestUserScopeInstallRepairInAdminContext\r\n        Repair: /repair\r\nManifestType: singleton\r\nManifestVersion: 1.7.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestBurnInstaller.yaml",
    "content": "Id: AppInstallerTest.TestBurnInstaller\r\nName: TestBurnInstaller\r\nVersion: 1.0.0.0\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n\r\n    Sha256: <EXEHASH>\r\n    InstallerType: burn\r\n    Switches:\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestExampleInstaller.yaml",
    "content": "Id: AppInstallerTest.TestExampleInstaller\r\nName: TestExampleInstaller\r\nVersion: 1.2.3.4\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    Sha256: <EXEHASH>\r\n    InstallerType: exe\r\n    Switches:\r\n      Custom: /execustom\r\n      SilentWithProgress: /exeswp\r\n      Silent: /exesilent\r\n      Interactive: /exeinteractive\r\n      Language: /exeenus\r\n      Log: /exelog <LOGPATH>\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestExeInstaller.1.0.1.0.yaml",
    "content": "Id: AppInstallerTest.TestExeInstaller\r\nName: TestExeInstaller\r\nVersion: 1.0.1.0\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Scope: user\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    Sha256: <EXEHASH>\r\n    InstallerType: exe\r\n    ProductCode: '{A499DD5E-8DC5-4AD2-911A-BCD0263295E9}'\r\n    Switches:\r\n      Custom: /execustom /Version 1.0.1.0\r\n      SilentWithProgress: /exeswp\r\n      Silent: /exesilent\r\n      Interactive: /exeinteractive\r\n      Language: /exeenus\r\n      Log: /exelog <LOGPATH>\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\n  - Arch: x86\r\n    Scope: machine\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    Sha256: <EXEHASH>\r\n    InstallerType: exe\r\n    ProductCode: '{A499DD5E-8DC5-4AD2-911A-BCD0263295E9}'\r\n    Switches:\r\n      Custom: /execustom /Version 1.0.1.0 /UseHKLM\r\n      SilentWithProgress: /exeswp\r\n      Silent: /exesilent\r\n      Interactive: /exeinteractive\r\n      Language: /exeenus\r\n      Log: /exelog <LOGPATH>\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestExeInstaller.1.1.0.0.yaml",
    "content": "Id: AppInstallerTest.TestExeInstaller\r\nName: TestExeInstaller\r\nVersion: 1.1.0.0\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Scope: user\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    Sha256: <EXEHASH>\r\n    InstallerType: exe\r\n    ProductCode: '{A499DD5E-8DC5-4AD2-911A-BCD0263295E9}'\r\n    Switches:\r\n      Custom: /execustom /Version 1.1.0.0\r\n      SilentWithProgress: /exeswp\r\n      Silent: /exesilent\r\n      Interactive: /exeinteractive\r\n      Language: /exeenus\r\n      Log: /exelog <LOGPATH>\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\n  - Arch: x86\r\n    Scope: machine\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    Sha256: <EXEHASH>\r\n    InstallerType: exe\r\n    ProductCode: '{A499DD5E-8DC5-4AD2-911A-BCD0263295E9}'\r\n    Switches:\r\n      Custom: /execustom /Version 1.1.0.0 /UseHKLM\r\n      SilentWithProgress: /exeswp\r\n      Silent: /exesilent\r\n      Interactive: /exeinteractive\r\n      Language: /exeenus\r\n      Log: /exelog <LOGPATH>\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestExeInstaller.2.0.0.0.yaml",
    "content": "Id: AppInstallerTest.TestExeInstaller\r\nName: TestExeInstaller\r\nVersion: 2.0.0.0\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Scope: user\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    Sha256: <EXEHASH>\r\n    InstallerType: exe\r\n    ProductCode: '{A499DD5E-8DC5-4AD2-911A-BCD0263295E9}'\r\n    Switches:\r\n      Custom: /execustom /Version 2.0.0.0\r\n      SilentWithProgress: /exeswp\r\n      Silent: /exesilent\r\n      Interactive: /exeinteractive\r\n      Language: /exeenus\r\n      Log: /exelog <LOGPATH>\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\n  - Arch: x86\r\n    Scope: machine\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    Sha256: <EXEHASH>\r\n    InstallerType: exe\r\n    ProductCode: '{A499DD5E-8DC5-4AD2-911A-BCD0263295E9}'\r\n    Switches:\r\n      Custom: /execustom /Version 2.0.0.0 /UseHKLM\r\n      SilentWithProgress: /exeswp\r\n      Silent: /exesilent\r\n      Interactive: /exeinteractive\r\n      Language: /exeenus\r\n      Log: /exelog <LOGPATH>\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestExeInstaller.RebootRequired.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.6.0.schema.json\n\nPackageIdentifier: AppInstallerTest.RebootRequired\nPackageVersion: 1.0.0.0\nPackageLocale: en-US\nPackageName: TestRebootRequired\nShortDescription: Emulates an installer that requires a reboot to finish.\nPublisher: Microsoft Corporation\nLicense: Test\nInstallers:\n  - Architecture: x64\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\n    InstallerType: exe\n    InstallerSha256: <EXEHASH>\n    InstallerSwitches:\n      SilentWithProgress: /exeswp\n      Silent: /exesilent\n      Interactive: /exeinteractive\n      Language: /exeenus\n      Log: /LogFile <LOGPATH>\n      InstallLocation: /InstallDir <INSTALLPATH>\n    ExpectedReturnCodes:\n      - InstallerReturnCode: 9\n        ReturnResponse: rebootRequiredToFinish\n        ReturnResponseUrl: https://DefaultReturnResponseUrl.com\n      - InstallerReturnCode: 10\n        ReturnResponse: rebootRequiredForInstall\n        ReturnResponseUrl: https://DefaultReturnResponseUrl.com\nManifestType: singleton\nManifestVersion: 1.6.0\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestExeInstaller.UninstallerRepair.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.7.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.UninstallerRepair\r\nPackageVersion: 2.0.0.0\r\nPackageLocale: en-US\r\nPackageName: UninstallerRepair\r\nPublisher: AppInstallerTest\r\nRepairBehavior: uninstaller\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n      InstallerType: exe\r\n      InstallerSha256: <EXEHASH>\r\n      ProductCode: '{A499DD5E-8DC5-4AD2-911A-BCD0263295E9}'\r\n      InstallerSwitches:\r\n        InstallLocation: /InstallDir <INSTALLPATH>\r\n        Custom: /Version 2.0.0.0 /DisplayName UninstallerRepair /UseHKLM\r\n        Repair: /repair\r\nManifestType: singleton\r\nManifestVersion: 1.7.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestExeInstaller.UninstallerRepairWithNoRepair.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.7.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.UninstallerRepairWithNoRepair\r\nPackageVersion: 2.0.0.0\r\nPackageLocale: en-US\r\nPackageName: UninstallerRepairWithNoRepair\r\nPublisher: AppInstallerTest\r\nRepairBehavior: uninstaller\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n      InstallerType: exe\r\n      InstallerSha256: <EXEHASH>\r\n      ProductCode: '{A499DD5E-8DC5-4AD2-911A-BCD0263295E9}'\r\n      InstallerSwitches:\r\n        InstallLocation: /InstallDir <INSTALLPATH>\r\n        Custom: /Version 2.0.0.0 /DisplayName UninstallerRepairWithNoRepair /UseHKLM /NoRepair\r\n        Repair: /repair\r\nManifestType: singleton\r\nManifestVersion: 1.7.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestExeInstaller.WindowsFeature.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.WindowsFeature\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: TestWindowsFeature\r\nShortDescription: Installs exe installer with valid Windows Features dependencies\r\nPublisher: Microsoft Corporation\r\nLicense: Test\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    InstallerType: exe\r\n    InstallerSha256: <EXEHASH>\r\n    InstallerSwitches:\r\n      SilentWithProgress: /exeswp\r\n      Silent: /exesilent\r\n      Interactive: /exeinteractive\r\n      Language: /exeenus\r\n      Log: /LogFile <LOGPATH>\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\n    Dependencies:\r\n      WindowsFeatures:\r\n      - netfx3\r\n      - invalidFeature\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestExeInstaller.yaml",
    "content": "Id: AppInstallerTest.TestExeInstaller\r\nName: TestExeInstaller\r\nVersion: 1.0.0.0\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Scope: user\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    Sha256: <EXEHASH>\r\n    InstallerType: exe\r\n    ProductCode: '{A499DD5E-8DC5-4AD2-911A-BCD0263295E9}'\r\n    Switches:\r\n      Custom: /execustom\r\n      SilentWithProgress: /exeswp\r\n      Silent: /exesilent\r\n      Interactive: /exeinteractive\r\n      Language: /exeenus\r\n      Log: /LogFile <LOGPATH>\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\n  - Arch: x86\r\n    Scope: machine\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    Sha256: <EXEHASH>\r\n    InstallerType: exe\r\n    ProductCode: '{A499DD5E-8DC5-4AD2-911A-BCD0263295E9}'\r\n    Switches:\r\n      Custom: /execustom /UseHKLM\r\n      SilentWithProgress: /exeswp\r\n      Silent: /exesilent\r\n      Interactive: /exeinteractive\r\n      Language: /exeenus\r\n      Log: /LogFile <LOGPATH>\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestExeInstallerForExport.yaml",
    "content": "Id: AppInstallerTest.TestPackageExport\r\nName: TestPackageExport\r\nVersion: 1.0.0.0\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    Sha256: <EXEHASH>\r\n    InstallerType: exe\r\n    ProductCode: '{92e3d4e5-6e3d-4ae4-b9f0-b7e0a5f25b91}'\r\n    Switches:\r\n      Custom: '/ProductID {92e3d4e5-6e3d-4ae4-b9f0-b7e0a5f25b91} /DisplayName TestPackageExport /GenerateDscResourceFiles'\r\n      SilentWithProgress: /exeswp\r\n      Silent: /exesilent\r\n      Interactive: /exeinteractive\r\n      Language: /exeenus\r\n      Log: /LogFile <LOGPATH>\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestExeInstaller_CatalogPackageMetadata.yaml",
    "content": "# Manifest for verifying the output of the CatalogPackageMetadata COM object.\r\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.5.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.CatalogPackageMetadata\r\nPackageVersion: 1.0.0.0\r\nPackageName: TestCatalogPackageMetadata\r\nPackageLocale: en-US\r\nPublisher: AppInstallerTest\r\nLicense: testLicense\r\nShortDescription: testShortDescription\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    InstallerType: exe\r\n    InstallerSha256: <EXEHASH>\r\n    InstallerSwitches:\r\n      Custom: /execustom\r\n      SilentWithProgress: /exeswp\r\n      Silent: /exesilent\r\n      Interactive: /exeinteractive\r\n      Language: /exeenus\r\n      Log: /LogFile <LOGPATH>\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\nAgreements:\r\n  - AgreementLabel: testAgreementLabel\r\n    Agreement: testAgreementText\r\n    AgreementUrl: https://testAgreementUrl.net\r\nPublisherUrl: https://testPublisherUrl.com\r\nPublisherSupportUrl: https://testPublisherSupportUrl.com\r\nPrivacyUrl: https://testPrivacyUrl.com\r\nAuthor: testAuthor\r\nPackageUrl: https://testPackageUrl.com\r\nLicenseUrl: https://testLicenseUrl.com\r\nCopyright: testCopyright\r\nCopyrightUrl: https://testCopyrightUrl.com\r\nDescription: testDescription\r\nMoniker: testMoniker\r\nPurchaseUrl: https://testPurchaseUrl.com\r\nTags:\r\n  - \"tag1\"\r\n  - \"tag2\"\r\nReleaseNotes: testReleaseNotes\r\nReleaseNotesUrl: https://testReleaseNotes.net\r\nInstallationNotes: testInstallationNotes\r\nDocumentations:\r\n  - DocumentLabel: testDocumentLabel\r\n    DocumentUrl: https://testDocumentUrl.com\r\nIcons:\r\n  - IconUrl: https://testIcon\r\n    IconFileType: ico\r\n    IconResolution: custom\r\n    IconTheme: default\r\n    IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\r\nManifestType: singleton\r\nManifestVersion: 1.5.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestExeInstaller_InapplicableOsVersion.yaml",
    "content": "Id: AppInstallerTest.InapplicableOsVersion\r\nName: InapplicableOsVersion\r\nVersion: 1.0.0.0\r\nPublisher: AppInstallerTest\r\nMinOSVersion: 11.0.0.0\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    Sha256: <EXEHASH>\r\n    InstallerType: exe\r\n    Switches:\r\n      Custom: /execustom\r\n      SilentWithProgress: /exeswp\r\n      Silent: /exesilent\r\n      Interactive: /exeinteractive\r\n      Language: /exeenus\r\n      Log: /exelog <LOGPATH>\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestExeInstaller_InstallMSIX.yaml",
    "content": "Id: AppInstallerTest.TestExeInstallerInstallsMSIX\r\nName: EXE Installer that Installs MSIX - extra\r\nVersion: 1.0.0.0\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    Sha256: <EXEHASH>\r\n    InstallerType: exe\r\n    PackageFamilyName: 6c6338fe-41b7-46ca-8ba6-b5ad5312bb0e_8wekyb3d8bbwe\r\n    Switches:\r\n      Custom: /execustom\r\n      SilentWithProgress: /exeswp\r\n      Silent: /exesilent\r\n      Interactive: /exeinteractive\r\n      Language: /exeenus\r\n      Log: /LogFile <LOGPATH>\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestExeInstaller_MultipleLocale.yaml",
    "content": "# Manifest for verifying multiple locales\nPackageIdentifier: AppInstallerTest.MultipleLocale\nPackageVersion: 1.0.0.0\nPackageName: TestMultipleLocale\nPackageLocale: en-US\nPublisher: AppInstallerTest\nLicense: testLicense\nLicenseUrl: https://testLicenseUrl.com\nShortDescription: testShortDescription\nInstallers:\n  - Architecture: x64\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\n    InstallerType: exe\n    InstallerSha256: <EXEHASH>\n    InstallerSwitches:\n      Custom: /execustom\n      SilentWithProgress: /exeswp\n      Silent: /exesilent\n      Interactive: /exeinteractive\n      Language: /exeenus\n      Log: /LogFile <LOGPATH>\n      InstallLocation: /InstallDir <INSTALLPATH>\nAgreements:\n  - AgreementLabel: testAgreementLabel\n    Agreement: testAgreementText\n    AgreementUrl: https://testAgreementUrl.net\nLocalization:\n- Author: localeAuthor\n  Copyright: localeCopyright\n  License: localeLicense\n  LicenseUrl: https://localeLicenseUrl.com\n  PackageLocale: zh-CN\n  PackageName: localePackageName\n  PackageUrl: https://localePackageUrl.com\n  Publisher: localePublisher\n  PublisherSupportUrl: https://localePublisherSupportUrl.com\n  PublisherUrl: https://localePublisherUrl.com\n  Moniker: localeMoniker\n  PurchaseUrl: https://localePurchaseUrl.com\n  ReleaseNotes: localeReleaseNotes\n  ReleaseNotesUrl: https://localeReleaseNotesUrl.com\n  Agreements:\n  - AgreementLabel: localeAgreementLabel\n    Agreement: localeAgreement\n    AgreementUrl: https://localeAgreementUrl.net\n  Documentations:\n  - DocumentLabel: localeDocumentLabel\n    DocumentUrl: https://localeDocumentUrl.com\n  Icons:\n  - IconUrl: https://localeTestIcon\n    IconFileType: png\n    IconResolution: 32x32\n    IconTheme: light\n    IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321\n  Tags:\n  - tag1\n  - tag2\n- PackageLocale: en-GB\n  PackageName: packageNameUK\n  License: licenseUK\n  Publisher: publisherUK\nManifestType: merged\nManifestVersion: 1.5.0"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestExeInstaller_NoScope.yaml",
    "content": "Id: AppInstallerTest.TestExeInstallerNoScope\r\nName: TestExeInstallerNoScope\r\nVersion: 1.0.0.0\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    Sha256: <EXEHASH>\r\n    InstallerType: exe\r\n    ProductCode: '{A499DD5E-8DC5-4AD2-911A-BCD0263295E9}'\r\n    Switches:\r\n      Custom: /execustom\r\n      SilentWithProgress: /exeswp\r\n      Silent: /exesilent\r\n      Interactive: /exeinteractive\r\n      Language: /exeenus\r\n      Log: /LogFile <LOGPATH>\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestExeInstaller_PackageDependency.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\n\nPackageIdentifier: AppInstallerTest.PackageDependency\nPackageVersion: 1.0.0.0\nPackageLocale: en-US\nPackageName: TestPackageDependency\nShortDescription: Installs a package with a package dependency.\nPublisher: AppInstallerTest\nLicense: testLicense\nInstallers:\n  - Architecture: x64\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\n    InstallerType: exe\n    InstallerSha256: <EXEHASH>\n    InstallerSwitches:\n      Silent: /exesilent\n      SilentWithProgress: /exeswp\n      Log: /LogFile <LOGPATH>\n      InstallLocation: /InstallDir <INSTALLPATH>\n    Dependencies:\n      PackageDependencies:\n      - PackageIdentifier: AppInstallerTest.TestPortableExe\nManifestType: singleton\nManifestVersion: 1.4.0\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestExeInstaller_PackageDependencyRequiresPathRefresh.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\n\nPackageIdentifier: AppInstallerTest.PackageDependencyRequiresPathRefresh\nPackageVersion: 1.0.0.0\nPackageLocale: en-US\nPackageName: TestPackageDependencyWithPathRefresh\nShortDescription: Installs a portable package dependency that modifies the PATH environment variable during installation, which is then invoked by the main installer.\nPublisher: AppInstallerTest\nLicense: testLicense\nInstallers:\n  - Architecture: x64\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\n    InstallerType: exe\n    InstallerSha256: <EXEHASH>\n    InstallerSwitches:\n      Custom: /AliasToExecute testCommand /AliasArguments /NoOperation\n      Silent: /exesilent\n      SilentWithProgress: /exeswp\n      Log: /LogFile <LOGPATH>\n      InstallLocation: /InstallDir <INSTALLPATH>\n    Dependencies:\n      PackageDependencies:\n      - PackageIdentifier: AppInstallerTest.TestPortableExeWithCommand\nManifestType: singleton\nManifestVersion: 1.4.0\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestExeInstaller_PathVariableRefresh.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\n\nPackageIdentifier: AppInstallerTest.PathVariableRefresh\nPackageVersion: 1.0.0.0\nPackageLocale: en-US\nPackageName: TestPathVariableRefresh\nShortDescription: Emulates an installer that invokes a command that only becomes available once the PATH environment variable is refreshed.\nPublisher: Microsoft Corporation\nLicense: Test\nInstallers:\n  - Architecture: x64\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\n    InstallerType: exe\n    InstallerSha256: <EXEHASH>\n    InstallerSwitches:\n      Custom: /AliasToExecute testCommand.exe /AliasArguments /NoOperation\n      SilentWithProgress: /exeswp\n      Silent: /exesilent\n      Interactive: /exeinteractive\n      Language: /exeenus\n      Log: /LogFile <LOGPATH>\n      InstallLocation: /InstallDir <INSTALLPATH>\nManifestType: singleton\nManifestVersion: 1.4.0\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestExeInstaller_Sha256Mismatch.yaml",
    "content": "Id: AppInstallerTest.TestExeSha256Mismatch\r\nName: TestExeSha256Mismatch\r\nVersion: 1.0.0.0\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    Sha256: 0000000000000000000000000000000000000000000000000000000000000000\r\n    InstallerType: exe\r\n    Switches:\r\n      Custom: /execustom\r\n      SilentWithProgress: /exeswp\r\n      Silent: /exesilent\r\n      Interactive: /exeinteractive\r\n      Language: /exeenus\r\n      Log: /exelog <LOGPATH>\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestFont.yaml",
    "content": "PackageIdentifier: AppInstallerTest.TestFont\nPackageVersion: 1.0.0.0\nPackageName: TestFont\nPackageLocale: en-US\nPublisher: AppInstallerTest\nLicense: Test\nShortDescription: E2E test for font install.\nInstallers:\n  - Architecture: x64\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestFont/AppInstallerTestFont.ttf\n    InstallerType: font\n    InstallerSha256: <FONTHASH>\nManifestType: singleton\nManifestVersion: 1.12.0\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestGoodManifestV1_10-SchemaHeader.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.10.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.SchemaHeader\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Schema Header\r\nPublisher: Microsoft Corporation\r\nLicense: Test\r\nShortDescription: This manifest with schema header\r\n\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerUrl: https://ThisIsNotUsed\r\n    InstallerType: msi\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestType: singleton\r\nManifestVersion: 1.10.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestInnoInstaller.InstallerRepair.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.7.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestInstallerRepair\r\nPackageVersion: 2.0.0.0\r\nPackageLocale: en-US\r\nPackageName: TestInstallerRepair\r\nPublisher: AppInstallerTest\r\nRepairBehavior: installer\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n      InstallerType: inno\r\n      InstallerSha256: <EXEHASH>\r\n      ProductCode: '{A499DD5E-8DC5-4AD2-911A-BCD0263295E9}'\r\n      InstallerSwitches:\r\n        InstallLocation: /InstallDir <INSTALLPATH>\r\n        Custom: /Version 2.0.0.0 /DisplayName TestInstallerRepair /UseHKLM\r\n        Repair: /repair /UseHKLM\r\nManifestType: singleton\r\nManifestVersion: 1.7.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestInnoInstaller.yaml",
    "content": "Id: AppInstallerTest.TestInnoInstaller\r\nName: TestInnoInstaller\r\nVersion: 1.0.0.0\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    Sha256: <EXEHASH>\r\n    InstallerType: inno\r\n    Switches:\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestInstalledStatus.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestCheckInstalledStatus\r\nPackageVersion: '1.0'\r\nPackageName: TestCheckInstalledStatus\r\nPackageLocale: en-US\r\nPublisher: Microsoft\r\nLicense: Test\r\nShortDescription: E2E test for check installed status test.\r\nInstallers:\r\n  - Architecture: neutral\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    InstallerType: exe\r\n    InstallerSha256: <EXEHASH>\r\n    ProductCode: CheckInstalledStatusProductId\r\n    InstallationMetadata:\r\n      DefaultInstallLocation: \"%TEMP%\\\\TestInstalledStatus\"\r\n      Files:\r\n      - RelativeFilePath: \"data.txt\"\r\n        # Hash value is for a txt file with \"Test\" as content in utf8\r\n        FileSha256: 532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25\r\n        FileType: other\r\n      - RelativeFilePath: \"TestExeInstalled.txt\"\r\n        FileType: other\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestInvalidFont.yaml",
    "content": "PackageIdentifier: AppInstallerTest.TestInvalidFont\nPackageVersion: 1.0.0.0\nPackageName: TestInvalidFont\nPackageLocale: en-US\nPublisher: AppInstallerTest\nLicense: Test\nShortDescription: E2E test for installing an invalid font.\nInstallers:\n  - Architecture: x64\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\n    InstallerType: font\n    InstallerSha256: <EXEHASH>\nManifestType: singleton\nManifestVersion: 1.11.0\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestInvalidManifest.yaml",
    "content": "Id: TestInvalidManifest TestInvalidManifest\r\nName: TestInvalidManifest\r\nVersion: 1.0.0.0\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    Sha256: <EXEHASH>\r\n    InstallerType: exe\r\n    Switches:\r\n      Custom: /execustom\r\n      SilentWithProgress: /exeswp\r\n      Silent: /exesilent\r\n      Interactive: /exeinteractive\r\n      Language: /exeenus\r\n      Log: /exelog <LOGPATH>\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestMappingWithArchitectureX64.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.2.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestMappingWithArchitectureX64\r\nPackageVersion: '1.0'\r\nPackageName: TestMappingWithArchitecture\r\nPackageLocale: en-US\r\nPublisher: Microsoft\r\nLicense: Test\r\nShortDescription: E2E test for mapping with architecture.\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    InstallerType: exe\r\n    InstallerSha256: <EXEHASH>\r\n    AppsAndFeaturesEntries:\r\n    - DisplayName: \"TestMappingWithArchitecture(X64)\"\r\n    InstallerSwitches:\r\n      Custom: '/DisplayName TestMappingWithArchitecture(X64) /ProductID {0e426f01-b682-4e67-a357-52f9ecb4590d}'\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\nManifestType: singleton\r\nManifestVersion: 1.2.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestMappingWithArchitectureX86.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.2.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestMappingWithArchitectureX86\r\nPackageVersion: 1.0\r\nPackageName: TestMappingWithArchitecture\r\nPackageLocale: en-US\r\nPublisher: Microsoft\r\nLicense: Test\r\nShortDescription: E2E test for mapping with architecture.\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    InstallerType: exe\r\n    InstallerSha256: <EXEHASH>\r\n    AppsAndFeaturesEntries:\r\n    - DisplayName: \"TestMappingWithArchitecture(X86)\"\r\n    InstallerSwitches:\r\n      Custom: '/DisplayName TestMappingWithArchitecture(X86) /ProductID {0e426f01-b682-4e67-a357-52f9ecb4590d}'\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\nManifestType: singleton\r\nManifestVersion: 1.2.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestMsiInstaller.Repair.yaml",
    "content": "# Uses the MSI installer;\r\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.7.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestMsiRepair\r\nPackageVersion: 2.0.0.0\r\nPackageLocale: en-US\r\nPackageName: TestMsiInstallerV2\r\nPublisher: AppInstallerTest\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestMsiInstaller/AppInstallerTestMsiInstallerV2.msi\r\n      InstallerType: msi\r\n      InstallerSha256: <MSIHASHV2>\r\n      ProductCode: '{A5D36CF1-1993-4F63-BFB4-3ACD910D36A1}'\r\nManifestType: singleton\r\nManifestVersion: 1.7.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestMsiInstaller.yaml",
    "content": "Id: AppInstallerTest.TestMsiInstaller\r\nName: TestMsiInstaller\r\nVersion: 1.0.0.0\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestMsiInstaller/AppInstallerTestMsiInstaller.msi\r\n    Sha256: <MSIHASH>\r\n    InstallerType: msi\r\n    ProductCode: '{A5D36CF1-1993-4F63-BFB4-3ACD910D36A1}'\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestMsiInstaller_UpgradeCode.yaml",
    "content": "﻿# Uses the MSI installer; doesn't list the ProductCode, only the UpgradeCode\r\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.1.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestMsiInstallerUpgradeCode\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: TestMsiInstallerUpgradeCode\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nShortDescription: Test Installer\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestMsiInstaller/AppInstallerTestMsiInstaller.msi\r\n      InstallerType: msi\r\n      InstallerSha256: <MSIHASH>\r\n      AppsAndFeaturesEntries:\r\n        - UpgradeCode: '{B9CF9DD5-D46F-4CE0-BFC9-633BF9D3A6F4}'\r\nManifestType: singleton\r\nManifestVersion: 1.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestMsixInstaller.yaml",
    "content": "Id: AppInstallerTest.TestMsixInstaller\r\nName: TestMsixInstaller\r\nVersion: 1.0.0.0\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestMsixInstaller/AppInstallerTestMsixInstaller.msix\r\n    Sha256: <MSIXHASH>\r\n    InstallerType: msix\r\n    PackageFamilyName: 6c6338fe-41b7-46ca-8ba6-b5ad5312bb0e_8wekyb3d8bbwe\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestMsixInstaller_SignatureHashMismatch.yaml",
    "content": "Id: AppInstallerTest.TestMsixSignatureHashMismatch\r\nName: TestMsixSignatureHashMismatch\r\nVersion: 1.0.0.0\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestMsixInstaller/AppInstallerTestMsixInstaller.msix\r\n    Sha256: <MSIXHASH>\r\n    SignatureSha256: 0000000000000000000000000000000000000000000000000000000000000000\r\n    InstallerType: msix\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestMsixInstaller_WithSignatureHash.yaml",
    "content": "Id: AppInstallerTest.TestMsixWithSignatureHash\r\nName: TestMsixWithSignatureHash\r\nVersion: 1.0.0.0\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestMsixInstaller/AppInstallerTestMsixInstaller.msix\r\n    Sha256: <MSIXHASH>\r\n    SignatureSha256: <SIGNATUREHASH>\r\n    InstallerType: msix\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestMultipleInstallers.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestMultipleInstallers\r\nPackageVersion: 1.0.0.0\r\nPackageName: TestMultipleInstallers\r\nPackageLocale: en-US\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nShortDescription: E2E test manifest with multiple installers\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    InstallerType: nullsoft\r\n    InstallerSha256: <EXEHASH>\r\n    Scope: user\r\n    InstallerSwitches:\r\n        InstallLocation: /InstallDir <INSTALLPATH>\r\n  - Architecture: arm64\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    InstallerType: nullsoft\r\n    InstallerSha256: <EXEHASH>\r\n    Scope: user\r\n    InstallerSwitches:\r\n        InstallLocation: /InstallDir <INSTALLPATH>\r\n  - Architecture: x86\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestMsiInstaller/AppInstallerTestMsiInstaller.msi\r\n    InstallerSha256: <MSIHASH>\r\n    InstallerType: msi\r\n    ProductCode: '{A5D36CF1-1993-4F63-BFB4-3ACD910D36A1}'\r\n    Scope: machine\r\n  - Architecture: x64\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestZipInstaller/AppInstallerTestZipInstaller.zip\r\n    InstallerType: zip\r\n    InstallerLocale: zh-CN\r\n    ProductCode: '{E1880465-8CC2-4033-90AE-DE4E7FDBA26E}'\r\n    InstallerSha256: <ZIPHASH>\r\n    NestedInstallerType: exe\r\n    NestedInstallerFiles:\r\n      - RelativeFilePath: AppInstallerTestExeInstaller.exe\r\n    InstallerSwitches:\r\n      Custom: /execustom /productID {E1880465-8CC2-4033-90AE-DE4E7FDBA26E}\r\n      SilentWithProgress: /exeswp\r\n      Silent: /exesilent\r\n      Interactive: /exeinteractive\r\n      Language: /exeenus\r\n      Log: /LogFile <LOGPATH>\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestNullsoftInstaller.UninstallerRepair.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.7.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.NullsoftUninstallerRepair\r\nPackageVersion: 2.0.0.0\r\nPackageLocale: en-US\r\nPackageName: NullsoftUninstallerRepair\r\nPublisher: AppInstallerTest\r\nRepairBehavior: uninstaller\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n      InstallerType: exe\r\n      InstallerSha256: <EXEHASH>\r\n      ProductCode: '{A499DD5E-8DC5-4AD2-911A-BCD0263295E9}'\r\n      InstallerSwitches:\r\n        InstallLocation: /InstallDir <INSTALLPATH>\r\n        Custom: /Version 2.0.0.0 /DisplayName NullsoftUninstallerRepair /UseHKLM\r\n        Repair: /repair\r\nManifestType: singleton\r\nManifestVersion: 1.7.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestNullsoftInstaller.yaml",
    "content": "Id: AppInstallerTest.TestNullsoftInstaller\r\nName: TestNullsoftInstaller\r\nVersion: 1.0.0.0\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    Sha256: <EXEHASH>\r\n    InstallerType: nullsoft\r\n    Switches:\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestPortableInstaller.2.0.0.0.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.2.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestPortableExe\r\nPackageVersion: 2.0.0.0\r\nPackageName: TestPortableExe\r\nPackageLocale: en-US\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nShortDescription: E2E test for portable install.\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    InstallerType: portable\r\n    InstallerSha256: <EXEHASH>\r\nManifestType: singleton\r\nManifestVersion: 1.2.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestPortableInstaller.3.0.0.0_UninstallPrevious.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.2.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestPortableExe\r\nPackageVersion: 3.0.0.0\r\nPackageName: TestPortableExe\r\nPackageLocale: en-US\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nShortDescription: E2E test for portable install.\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    InstallerType: portable\r\n    InstallerSha256: <EXEHASH>\r\n    UpgradeBehavior: uninstallPrevious\r\nManifestType: singleton\r\nManifestVersion: 1.2.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestPortableInstaller.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.2.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestPortableExe\r\nPackageVersion: 1.0.0.0\r\nPackageName: TestPortableExe\r\nPackageLocale: en-US\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nShortDescription: E2E test for portable install.\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    InstallerType: portable\r\n    InstallerSha256: <EXEHASH>\r\nManifestType: singleton\r\nManifestVersion: 1.2.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestPortableInstallerUninstallPrevious.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.2.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestPortableExe\r\nPackageVersion: 1.1.0.0\r\nPackageName: TestPortableExe\r\nPackageLocale: en-US\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nShortDescription: E2E test for portable install.\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    InstallerType: portable\r\n    InstallerSha256: <EXEHASH>\r\n    UpgradeBehavior: uninstallPrevious\r\nManifestType: singleton\r\nManifestVersion: 1.2.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestPortableInstaller_WithCommand.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.2.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestPortableExeWithCommand\r\nPackageVersion: 1.0.0.0\r\nPackageName: TestPortableExeWithCommand\r\nPackageLocale: en-US\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nShortDescription: E2E test for portable install with command value.\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    InstallerType: portable\r\n    InstallerSha256: <EXEHASH>\r\n    Commands:\r\n     - testCommand\r\nManifestType: singleton\r\nManifestVersion: 1.2.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestUpgradeAddsDependency.1.0.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestUpgradeAddsDependency\r\nPackageVersion: '1.0'\r\nPackageName: TestUpgradeAddsDependency\r\nPackageLocale: en-US\r\nPublisher: Microsoft\r\nLicense: Test\r\nShortDescription: E2E test for adding a new package dependency during an upgrade.\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    InstallerType: exe\r\n    InstallerSha256: <EXEHASH>\r\n    ProductCode: '{fda6c0e2-0977-482f-bda1-9bd025457b81}'\r\n    InstallerSwitches:\r\n      Custom: '/ProductID {fda6c0e2-0977-482f-bda1-9bd025457b81}'\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestUpgradeAddsDependency.2.0.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestUpgradeAddsDependency\r\nPackageVersion: '2.0'\r\nPackageName: TestUpgradeAddsDependency\r\nPackageLocale: en-US\r\nPublisher: Microsoft\r\nLicense: Test\r\nShortDescription: E2E test for adding a new package dependency during an upgrade.\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    InstallerType: exe\r\n    InstallerSha256: <EXEHASH>\r\n    ProductCode: '{fda6c0e2-0977-482f-bda1-9bd025457b81}'\r\n    InstallerSwitches:\r\n      Custom: '/ProductID {fda6c0e2-0977-482f-bda1-9bd025457b81}'\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\n    Dependencies:\r\n      PackageDependencies:\r\n      - PackageIdentifier: AppInstallerTest.TestUpgradeAddsDependencyDependent\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestUpgradeAddsDependencyDependent.1.0.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestUpgradeAddsDependencyDependent\r\nPackageVersion: '1.0'\r\nPackageName: TestUpgradeAddsDependencyDependent\r\nPackageLocale: en-US\r\nPublisher: Microsoft\r\nLicense: Test\r\nShortDescription: E2E test for adding a new package dependency during an upgrade.\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    InstallerType: exe\r\n    InstallerSha256: <EXEHASH>\r\n    UpgradeBehavior: uninstallPrevious\r\n    ProductCode: '{648274a3-17aa-4731-8bf1-5854ca61e475}'\r\n    InstallerSwitches:\r\n      Custom: '/ProductID {648274a3-17aa-4731-8bf1-5854ca61e475}'\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestUpgradeAvailableApi.1.0.0.0.yaml",
    "content": "Id: AppInstallerTest.TestUpgradeApplicability\r\nName: TestUpgradeApplicability\r\nVersion: 1.0.0.0\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    Sha256: <EXEHASH>\r\n    InstallerType: exe\r\n    ProductCode: '{bfb0f666-99d5-433d-8a2e-32f31d4f8e48}'\r\n    Switches:\r\n      Custom: '/ProductID {bfb0f666-99d5-433d-8a2e-32f31d4f8e48} /DisplayName TestUpgradeApplicability'\r\n      SilentWithProgress: /exeswp\r\n      Silent: /exesilent\r\n      Interactive: /exeinteractive\r\n      Language: /exeenus\r\n      Log: /LogFile <LOGPATH>\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestUpgradeAvailableApi.2.0.0.0.yaml",
    "content": "Id: AppInstallerTest.TestUpgradeApplicability\r\nName: TestUpgradeApplicability\r\nVersion: 2.0.0.0\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nInstallers:\r\n  - Arch: arm64\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    Sha256: <EXEHASH>\r\n    InstallerType: exe\r\n    ProductCode: '{bfb0f666-99d5-433d-8a2e-32f31d4f8e48}'\r\n    Switches:\r\n      Custom: '/ProductID {bfb0f666-99d5-433d-8a2e-32f31d4f8e48} /DisplayName TestUpgradeApplicability'\r\n      SilentWithProgress: /exeswp\r\n      Silent: /exesilent\r\n      Interactive: /exeinteractive\r\n      Language: /exeenus\r\n      Log: /LogFile <LOGPATH>\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestUpgradeDeny.1.0.0.0.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.6.0.schema.json\n\nPackageIdentifier: AppInstallerTest.TestUpgradeDeny\nPackageVersion: 1.0.0.0\nPackageName: TestUpgradeDeny\nPackageLocale: en-US\nPublisher: AppInstallerTest\nLicense: Test\nShortDescription: E2E test for upgrade deny.\nInstallers:\n  - Architecture: x64\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\n    InstallerType: portable\n    InstallerSha256: <EXEHASH>\n    UpgradeBehavior: deny\nManifestType: singleton\nManifestVersion: 1.6.0\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestUpgradeDeny.2.0.0.0.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.6.0.schema.json\n\nPackageIdentifier: AppInstallerTest.TestUpgradeDeny\nPackageVersion: 2.0.0.0\nPackageName: TestUpgradeDeny\nPackageLocale: en-US\nPublisher: AppInstallerTest\nLicense: Test\nShortDescription: E2E test for upgrade deny.\nInstallers:\n  - Architecture: x64\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\n    InstallerType: portable\n    InstallerSha256: <EXEHASH>\n    UpgradeBehavior: deny\nManifestType: singleton\nManifestVersion: 1.6.0\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestValidManifest.yaml",
    "content": "Id: AppInstallerTest.TestValidManifest\r\nName: TestValidManifest\r\nVersion: 1.0.0.0\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    Sha256: 0000000000000000000000000000000000000000000000000000000000000000\r\n    InstallerType: exe\r\n    Switches:\r\n      Custom: /execustom\r\n      SilentWithProgress: /exeswp\r\n      Silent: /exesilent\r\n      Interactive: /exeinteractive\r\n      Language: /exeenus\r\n      Log: /exelog <LOGPATH>\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestWarningManifest.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.6.0.schema.json\r\n\r\nPackageIdentifier: TestWarning.Manifest\r\nPackageName: TestWarningManifest\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    InstallerSha256: 0000000000000000000000000000000000000000000000000000000000000000\r\n    InstallerType: exe\r\nShortDescription: This manifest should have only warnings, no errors\r\nManifestType: singleton\r\nManifestVersion: 1.6.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestWarningManifestV1_10-SchemaHeaderInvalid.yaml",
    "content": "# yaml-language-server= $schema=https://aka.ms/winget-manifest.singleton.1.10.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.SchemaHeaderInvalid\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Schema Header Invalid\r\nPublisher: Microsoft Corporation\r\nLicense: Test\r\nShortDescription: This manifest has an invalid schema header\r\n\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerUrl: https://ThisIsNotUsed\r\n    InstallerType: msi\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestType: singleton\r\nManifestVersion: 1.10.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestWarningManifestV1_10-SchemaHeaderManifestTypeMismatch.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.10.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.SchemaHeaderManifestTypeMismatch\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Schema Header ManifestType Mismatch\r\nPublisher: Microsoft Corporation\r\nLicense: Test\r\nShortDescription: This manifest has a mismatched ManisfestType in the schema header\r\n\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerUrl: https://ThisIsNotUsed\r\n    InstallerType: msi\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestType: singleton\r\nManifestVersion: 1.10.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestWarningManifestV1_10-SchemaHeaderNotFound.yaml",
    "content": "PackageIdentifier: AppInstallerCliTest.SchemaHeaderNotFound\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Schema Header Not Found\r\nPublisher: Microsoft Corporation\r\nLicense: Test\r\nShortDescription: This manifest has a missing schema header\r\n\r\nInstallers: \r\n  - Architecture: x86\r\n    InstallerUrl: https://ThisIsNotUsed\r\n    InstallerType: msi\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestType: singleton\r\nManifestVersion: 1.10.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestWarningManifestV1_10-SchemaHeaderURLPatternMismatch.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest-invalid.singleton.1.10.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.SchemaHeaderURLPatternMismatch\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Schema Header URL Pattern Mismatch\r\nPublisher: Microsoft Corporation\r\nLicense: Test\r\nShortDescription: This manifest has a mismatched schema header URL pattern\r\n\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerUrl: https://ThisIsNotUsed\r\n    InstallerType: msi\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestType: singleton\r\nManifestVersion: 1.10.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestWarningManifestV1_10-SchemaHeaderVersionMismatch.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.9.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.SchemaHeaderVersionMismatch\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Schema Header ManifestVersion Mismatch\r\nPublisher: Microsoft Corporation\r\nLicense: Test\r\nShortDescription: This manifest has a mismatched ManisfestVersion in the schema header\r\n\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerUrl: https://ThisIsNotUsed\r\n    InstallerType: msi\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestType: singleton\r\nManifestVersion: 1.10.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestZipInstaller_Exe.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestZipInstallerWithExe\r\nPackageVersion: 1.0.0.0\r\nPackageName: TestZipInstallerWithExe\r\nPackageLocale: en-US\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nShortDescription: E2E test for installing a zip with exe.\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestZipInstaller/AppInstallerTestZipInstaller.zip\r\n    InstallerType: zip\r\n    ProductCode: '{E1880465-8CC2-4033-90AE-DE4E7FDBA26E}'\r\n    InstallerSha256: <ZIPHASH>\r\n    NestedInstallerType: exe\r\n    NestedInstallerFiles:\r\n      - RelativeFilePath: AppInstallerTestExeInstaller.exe\r\n    InstallerSwitches:\r\n      Custom: /execustom /productID {E1880465-8CC2-4033-90AE-DE4E7FDBA26E}\r\n      SilentWithProgress: /exeswp\r\n      Silent: /exesilent\r\n      Interactive: /exeinteractive\r\n      Language: /exeenus\r\n      Log: /LogFile <LOGPATH>\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestZipInstaller_Exe_InvalidRelativeFilePath.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestZipInvalidRelativePath\r\nPackageVersion: 1.0.0.0\r\nPackageName: TestZipInvalidRelativePath\r\nPackageLocale: en-US\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nShortDescription: E2E test for installing a zip with a bad relative file path.\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestZipInstaller/AppInstallerTestZipInstaller.zip\r\n    InstallerType: zip\r\n    ProductCode: '{E1880465-8CC2-4033-90AE-DE4E7FDBA26E}'\r\n    InstallerSha256: <ZIPHASH>\r\n    NestedInstallerType: exe\r\n    NestedInstallerFiles:\r\n      - RelativeFilePath: ../../AppInstallerTestExeInstaller.exe\r\n    InstallerSwitches:\r\n      Custom: /productID {E1880465-8CC2-4033-90AE-DE4E7FDBA26E}\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestZipInstaller_Msi.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestZipInstallerWithMsi\r\nPackageVersion: 1.0.0.0\r\nPackageName: TestZipInstallerWithMsi\r\nPackageLocale: en-US\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nShortDescription: E2E test for installing a zip with msi.\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestZipInstaller/AppInstallerTestZipInstaller.zip\r\n    InstallerType: zip\r\n    ProductCode: '{A5D36CF1-1993-4F63-BFB4-3ACD910D36A1}'\r\n    InstallerSha256: <ZIPHASH>\r\n    NestedInstallerType: msi\r\n    NestedInstallerFiles:\r\n      - RelativeFilePath: AppInstallerTestMsiInstaller.msi\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestZipInstaller_Msix.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestZipInstallerWithMsix\r\nPackageVersion: 1.0.0.0\r\nPackageName: TestZipInstallerWithMsix\r\nPackageLocale: en-US\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nShortDescription: E2E test for installing a zip with msix.\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestZipInstaller/AppInstallerTestZipInstaller.zip\r\n    InstallerType: zip\r\n    ProductCode: '{A5D36CF1-1993-4F63-BFB4-3ACD910D36A1}'\r\n    InstallerSha256: <ZIPHASH>\r\n    NestedInstallerType: msix\r\n    NestedInstallerFiles:\r\n      - RelativeFilePath: AppInstallerTestMsixInstaller.msix\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestZipInstaller_PackageInstallerInfo.yaml",
    "content": "# Test manifest for verifying the behavior of retrieving a PackageInstallerInfo COM object.\r\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.PackageInstallerInfo\r\nPackageVersion: 1.0.0.0\r\nPackageName: TestPackageInstallerInfo\r\nPackageLocale: en-US\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nShortDescription: E2E test for PackageInstallerInfo COM object.\r\nInstallers:\r\n  - Architecture: x64\r\n    Scope: user\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestZipInstaller/AppInstallerTestZipInstaller.zip\r\n    InstallerType: zip\r\n    InstallerSha256: <EXEHASH>\r\n    NestedInstallerType: exe\r\n    NestedInstallerFiles:\r\n      - RelativeFilePath: AppInstallerTestExeInstaller.exe\r\n    ElevationRequirement: elevationRequired\r\n    InstallerLocale: en-US\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestZipInstaller_Portable.2.0.0.0.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestZipInstallerWithPortable\r\nPackageVersion: 2.0.0.0\r\nPackageName: TestZipInstallerWithPortable\r\nPackageLocale: en-US\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nShortDescription: E2E test for installing a zip with portable.\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestZipInstaller/AppInstallerTestZipInstaller.zip\r\n    InstallerType: zip\r\n    InstallerSha256: <ZIPHASH>\r\n    NestedInstallerType: portable\r\n    NestedInstallerFiles:\r\n      - RelativeFilePath: AppInstallerTestExeInstaller.exe\r\n        PortableCommandAlias: TestPortable\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestZipInstaller_Portable.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerTest.TestZipInstallerWithPortable\r\nPackageVersion: 1.0.0.0\r\nPackageName: TestZipInstallerWithPortable\r\nPackageLocale: en-US\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nShortDescription: E2E test for installing a zip with portable.\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestZipInstaller/AppInstallerTestZipInstaller.zip\r\n    InstallerType: zip\r\n    InstallerSha256: <ZIPHASH>\r\n    NestedInstallerType: portable\r\n    NestedInstallerFiles:\r\n      - RelativeFilePath: AppInstallerTestExeInstaller.exe\r\n        PortableCommandAlias: TestPortable\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TestZipInstaller_Portable_BinariesDependOnPath.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.9.0.schema.json\n\nPackageIdentifier: AppInstallerTest.ArchivePortableWithBinariesDependentOnPath\nPackageVersion: 1.0.0.0\nPackageName: TestArchivePortableWithBinariesDependentOnPath\nPackageLocale: en-US\nPublisher: AppInstallerTest\nLicense: Test\nShortDescription: E2E test for installing a zip containing a portable with binaries that depend on the PATH variable.\nInstallers:\n  - Architecture: x64\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestZipInstaller/AppInstallerTestZipInstaller.zip\n    InstallerType: zip\n    InstallerSha256: <ZIPHASH>\n    NestedInstallerType: portable\n    NestedInstallerFiles:\n      - RelativeFilePath: AppInstallerTestExeInstaller.exe\n        PortableCommandAlias: TestPortable\n    ArchiveBinariesDependOnPath: true\nManifestType: singleton\nManifestVersion: 1.9.0\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/TëstExeInstaller.yaml",
    "content": "Id: AppInstallerTest.TëstExeInstaller\r\nName: TestExeInstaller\r\nVersion: 1.0.0.0\r\nPublisher: AppInstallerTest\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\r\n    Sha256: 0000000000000000000000000000000000000000000000000000000000000000\r\n    InstallerType: exe\r\n    Switches:\r\n      Custom: /execustom\r\n      SilentWithProgress: /exeswp\r\n      Silent: /exesilent\r\n      Interactive: /exeinteractive\r\n      Language: /exeenus\r\n      Log: /exelog <LOGPATH>\r\n      InstallLocation: /InstallDir <INSTALLPATH>\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/ZeroByteFile_CorrectHash.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.6.0.schema.json\r\n\r\nPackageIdentifier: ZeroByteFile.CorrectHash\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: ZeroByteFile-CorrectHash\r\nShortDescription: Points to a zero byte installer file using the correct hash\r\nPublisher: Microsoft Corporation\r\nLicense: Test\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerUrl: https://localhost:5001/TestKit/TestData/empty\r\n    InstallerType: exe\r\n    InstallerSha256: E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855\r\nManifestType: singleton\r\nManifestVersion: 1.6.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Manifests/ZeroByteFile_IncorrectHash.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.6.0.schema.json\r\n\r\nPackageIdentifier: ZeroByteFile.IncorrectHash\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: ZeroByteFile-IncorrectHash\r\nShortDescription: Points to a zero byte installer file using the incorrect hash\r\nPublisher: Microsoft Corporation\r\nLicense: Test\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerUrl: https://localhost:5001/TestKit/TestData/empty\r\n    InstallerType: exe\r\n    InstallerSha256: BAD0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852BBAD\r\nManifestType: singleton\r\nManifestVersion: 1.6.0\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/Package/AppxManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Package xmlns=\"http://schemas.microsoft.com/appx/manifest/foundation/windows10\"\r\n         xmlns:uap=\"http://schemas.microsoft.com/appx/manifest/uap/windows10\"\r\n         xmlns:uap3=\"http://schemas.microsoft.com/appx/manifest/uap/windows10/3\"\r\n         IgnorableNamespaces=\"uap uap3\">\r\n\r\n  <Identity Name=\"WingetE2E.Tests\"\r\n            ProcessorArchitecture=\"neutral\"\r\n            Publisher=\"CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US\"\r\n            Version=\"2020.805.713.335\" />\r\n\r\n  <Properties>\r\n    <DisplayName>WinGet E2E Source</DisplayName>\r\n    <PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>\r\n    <Logo>Assets\\AppPackageStoreLogo.png</Logo>\r\n  </Properties>\r\n\r\n  <Dependencies>\r\n    <TargetDeviceFamily Name=\"Windows.Universal\" MinVersion=\"10.0.17763.0\" MaxVersionTested=\"10.0.18287.0\" />\r\n  </Dependencies>\r\n\r\n  <Applications>\r\n    <Application Id=\"SourceData\">\r\n      <uap:VisualElements DisplayName=\"WinGet E2E Source\"\r\n                          Square150x150Logo=\"Assets\\AppPackageStoreLogo.scale-150.png\"\r\n                          Square44x44Logo=\"Assets\\AppPackageStoreLogo.scale-100.png\"\r\n                          Description=\"WinGet E2E Source\"\r\n                          BackgroundColor=\"#0078d7\"\r\n                          AppListEntry=\"none\" />\r\n      <Extensions>\r\n        <uap3:Extension Category=\"windows.appExtension\">\r\n          <uap3:AppExtension Name=\"com.microsoft.winget.source\"\r\n                             Id=\"IndexDB\"\r\n                             DisplayName=\"WinGet Source\"\r\n                             Description=\"WinGet Source\"\r\n                             PublicFolder=\"Public\">\r\n          </uap3:AppExtension>\r\n        </uap3:Extension>\r\n      </Extensions>\r\n    </Application>\r\n  </Applications>\r\n\r\n  <Resources>\r\n    <Resource Language=\"und\" />\r\n  </Resources>\r\n\r\n</Package>\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/README.md",
    "content": "## AppInstallerTestMsiInstaller.msi\r\nDue to MSI projects requiring a special extension, we have simply checked in a built version of the test MSI.  To create a new one, which may be needed if the test EXE inside it needs to be updated:\r\n\r\n1. Ensure that the extension is installed locally\r\n\r\n    a. [Microsoft Visual Studio Installer Projects 2022](https://marketplace.visualstudio.com/items?itemName=VisualStudioClient.MicrosoftVisualStudio2022InstallerProjects)\r\n2. Set configuration to \"Release|x86\"\r\n3. Build AppInstallerTestMsiInstaller project\r\n4. Check in new MSI over the one in TestData"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/WinGetUtil/InstallerMetadata/MergeSubmissionMismatch.json",
    "content": "{\n    \"version\": \"1.0\",\n    \"metadatas\": [\n        {\n            \"version\": \"1.0\",\n            \"productVersionMin\": \"1.0\",\n            \"productVersionMax\": \"1.0\",\n            \"metadata\": [\n                {\n                    \"installerHash\": \"ABCD\",\n                    \"submissionIdentifier\": \"1\",\n                    \"AppsAndFeaturesEntries\": [\n                        {\n                            \"DisplayName\": \"Name\",\n                            \"Publisher\": \"Publisher\",\n                            \"DisplayVersion\": \"1.0\",\n                            \"ProductCode\": \"{46210E3D-EBB3-43D4-B9BB-48A7DB0F9B93}\",\n                            \"InstallerType\": 3\n                        }\n                    ]\n                }\n            ]\n        },\n        {\n            \"version\": \"1.0\",\n            \"productVersionMin\": \"1.0\",\n            \"productVersionMax\": \"1.0\",\n            \"metadata\": [\n                {\n                    \"installerHash\": \"EFGH\",\n                    \"submissionIdentifier\": \"2\",\n                    \"AppsAndFeaturesEntries\": [\n                        {\n                            \"DisplayName\": \"Name\",\n                            \"Publisher\": \"Publisher\",\n                            \"DisplayVersion\": \"1.0\",\n                            \"ProductCode\": \"{46210E3D-EBB3-43D4-B9BB-48A7DB0F9B93}\",\n                            \"InstallerType\": 3\n                        }\n                    ]\n                }\n            ]\n        }\n    ]\n}"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/WinGetUtil/InstallerMetadata/MergeValid.json",
    "content": "{\n    \"version\": \"1.0\",\n    \"metadatas\": [\n        {\n            \"version\": \"1.0\",\n            \"productVersionMin\": \"1.0\",\n            \"productVersionMax\": \"1.0\",\n            \"metadata\": [\n                {\n                    \"installerHash\": \"ABCD\",\n                    \"submissionIdentifier\": \"1\",\n                    \"AppsAndFeaturesEntries\": [\n                        {\n                            \"DisplayName\": \"Name\",\n                            \"Publisher\": \"Publisher\",\n                            \"DisplayVersion\": \"1.0\",\n                            \"ProductCode\": \"{46210E3D-EBB3-43D4-B9BB-48A7DB0F9B93}\",\n                            \"InstallerType\": 3\n                        }\n                    ]\n                }\n            ]\n        },\n        {\n            \"version\": \"1.0\",\n            \"productVersionMin\": \"1.0\",\n            \"productVersionMax\": \"1.0\",\n            \"metadata\": [\n                {\n                    \"installerHash\": \"EFGH\",\n                    \"submissionIdentifier\": \"1\",\n                    \"AppsAndFeaturesEntries\": [\n                        {\n                            \"DisplayName\": \"Name\",\n                            \"Publisher\": \"Publisher\",\n                            \"DisplayVersion\": \"1.0\",\n                            \"ProductCode\": \"{46210E3D-EBB3-43D4-B9BB-48A7DB0F9B93}\",\n                            \"InstallerType\": 3\n                        }\n                    ]\n                }\n            ]\n        }\n    ]\n}"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/WinGetUtil/InstallerMetadata/Minimal.json",
    "content": "{\n    \"version\": \"1.0\",\n    \"supportedMetadataVersion\": \"1.0\",\n    \"submissionData\": {\n        \"submissionIdentifier\": \"1\"\n    },\n    \"packageData\": {\n        \"installerHash\": \"ABCD\",\n        \"DefaultLocale\": {\n            \"PackageLocale\": \"en-us\",\n            \"PackageName\": \"Name\",\n            \"Publisher\":  \"Publisher\"\n        }\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/WinGetUtil/Manifests/Merged/WinGetUtilTest.Add.yaml",
    "content": "Installers:\n- Architecture: x86\n  InstallerSha256: 0000000000000000000000000000000000000000000000000000000000000000\n  InstallerType: exe\n  InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\nLicense: Test\nManifestType: merged\nManifestVersion: 1.1.0\nMinimumOSVersion: 10.0.0.0\nPackageIdentifier: AppInstallerTest.WinGetUtilTest\nPackageLocale: en-US\nPackageName: AppInstallerTest\nPackageVersion: 1.0.0.0\nPublisher: AppInstallerTest\nTags:\n- add\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/WinGetUtil/Manifests/Merged/WinGetUtilTest.Update.yaml",
    "content": "Installers:\n- Architecture: x86\n  InstallerSha256: 0000000000000000000000000000000000000000000000000000000000000000\n  InstallerType: exe\n  InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\nLicense: Test\nManifestType: merged\nManifestVersion: 1.1.0\nMinimumOSVersion: 10.0.0.0\nPackageIdentifier: AppInstallerTest.WinGetUtilTest\nPackageLocale: en-US\nPackageName: AppInstallerTest\nPackageVersion: 1.0.0.0\nPublisher: AppInstallerTest\nTags:\n- update\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/WinGetUtil/Manifests/Unmerged/ValidateManifest/WinGetUtilTest.installer.yaml",
    "content": "PackageIdentifier: AppInstallerTest.WinGetUtilTest\nPackageVersion: \"1.0.0.0\"\nMinimumOSVersion: 10.0.0.0\nInstallers:\n  - Architecture: x86\n    InstallerUrl: https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\n    InstallerType: nullsoft\n    InstallerSha256: 0000000000000000000000000000000000000000000000000000000000000000\nManifestType: installer\nManifestVersion: 1.1.0\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/WinGetUtil/Manifests/Unmerged/ValidateManifest/WinGetUtilTest.locale.en-US.yaml",
    "content": "PackageIdentifier: AppInstallerTest.WinGetUtilTest\nPackageVersion: \"1.0.0.0\"\nPackageLocale: en-US\nPublisher: AppInstallerTest\nLicense: Test\nPackageName: AppInstallerTest\nShortDescription: WinGetUtilTest\nManifestType: defaultLocale\nManifestVersion: 1.1.0\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/WinGetUtil/Manifests/Unmerged/ValidateManifest/WinGetUtilTest.yaml",
    "content": "PackageIdentifier: AppInstallerTest.WinGetUtilTest\nPackageVersion: \"1.0.0.0\"\nDefaultLocale: en-US\nManifestType: version\nManifestVersion: 1.1.0\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/empty",
    "content": ""
  },
  {
    "path": "src/AppInstallerCLIE2ETests/TestData/localsource.json",
    "content": "{\r\n  \"AppxManifest\": \"%BUILD_SOURCESDIRECTORY%/src/AppInstallerCLIE2ETests/TestData/Package/AppxManifest.xml\",\r\n  \"WorkingDirectory\": \"%AGENT_TEMPDIRECTORY%/TestLocalIndex\",\r\n  \"LocalManifests\": [\r\n    \"%BUILD_SOURCESDIRECTORY%/src/AppInstallerCLIE2ETests/TestData/Manifests\"\r\n  ],\r\n  \"LocalInstallers\": [\r\n    {\r\n      \"Type\": \"exe\",\r\n      \"Name\": \"AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\",\r\n      \"Input\": \"%BUILDOUTDIR%/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\",\r\n      \"HashToken\": \"<EXEHASH>\"\r\n    },\r\n    {\r\n      \"Type\": \"msi\",\r\n      \"Name\": \"AppInstallerTestMsiInstaller/AppInstallerTestMsiInstaller.msi\",\r\n      \"Input\": \"%BUILD_SOURCESDIRECTORY%/src/AppInstallerCLIE2ETests/TestData/AppInstallerTestMsiInstaller.msi\",\r\n      \"HashToken\": \"<MSIHASH>\"\r\n    },\r\n    {\r\n      \"Type\": \"msi\",\r\n      \"Name\": \"AppInstallerTestMsiInstaller/AppInstallerTestMsiInstallerV2.msi\",\r\n      \"Input\": \"%BUILD_SOURCESDIRECTORY%/src/AppInstallerCLIE2ETests/TestData/AppInstallerTestMsiInstallerV2.msi\",\r\n      \"HashToken\": \"<MSIHASHV2>\"\r\n    },\r\n    {\r\n      \"Type\": \"msix\",\r\n      \"Name\": \"AppInstallerTestMsixInstaller/AppInstallerTestMsixInstaller.msix\",\r\n      \"Input\": \"%BUILD_ARTIFACTSTAGINGDIRECTORY%/AppInstallerTestMsixInstaller.msix\",\r\n      \"HashToken\": \"<MSIXHASH>\",\r\n      \"SignatureToken\": \"<SIGNATUREHASH>\"\r\n    },\r\n    {\r\n      \"Type\": \"font\",\r\n      \"Name\": \"AppInstallerTestFont/AppInstallerTestFont.ttf\",\r\n      \"Input\": \"%BUILD_SOURCESDIRECTORY%/src/AppInstallerCLIE2ETests/TestData/AppInstallerTestFont.ttf\",\r\n      \"HashToken\": \"<FONTHASH>\"\r\n    }\r\n  ],\r\n  \"DynamicInstallers\": [\r\n    {\r\n      \"Type\": \"zip\",\r\n      \"Name\": \"AppInstallerTestZipInstaller/AppInstallerTestZipInstaller.zip\",\r\n      \"Input\": [\r\n        \"%AGENT_TEMPDIRECTORY%/TestLocalIndex/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\",\r\n        \"%AGENT_TEMPDIRECTORY%/TestLocalIndex/AppInstallerTestMsiInstaller/AppInstallerTestMsiInstaller.msi\",\r\n        \"%AGENT_TEMPDIRECTORY%/TestLocalIndex/AppInstallerTestMsixInstaller/AppInstallerTestMsixInstaller.msix\"\r\n      ],\r\n      \"HashToken\": \"<ZIPHASH>\"\r\n    }\r\n  ],\r\n  \"Signature\": {\r\n    \"CertFile\": \"%TestSigningCert_PfxPath%\",\r\n    \"Password\": \"%TestSigningCert_Password%\"\r\n  }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/UninstallCommand.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"UninstallCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using System.IO;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// Test uninstall command.\r\n    /// </summary>\r\n    public class UninstallCommand : BaseCommand\r\n    {\r\n        // Custom product code for overriding the default in the test exe\r\n        private const string CustomProductCode = \"{f08fc03c-0b7e-4fca-9b3c-3a384d18a9f3}\";\r\n\r\n        // File written when uninstalling the test exe\r\n        private const string UninstallTestExeUninstalledFile = \"TestExeUninstalled.txt\";\r\n\r\n        // Name of a file installed by the MSI that will be removed during uninstall\r\n        private const string UninstallTestMsiInstalledFile = \"AppInstallerTestExeInstaller.exe\";\r\n\r\n        // Package name of the test MSIX package\r\n        private const string UninstallTestMsixName = \"6c6338fe-41b7-46ca-8ba6-b5ad5312bb0e\";\r\n\r\n        /// <summary>\r\n        /// Test uninstall exe.\r\n        /// </summary>\r\n        [Test]\r\n        public void UninstallTestExe()\r\n        {\r\n            // Uninstall an Exe\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            TestCommon.RunAICLICommand(\"install\", $\"{Constants.ExeInstallerPackageId} --silent -l {installDir}\");\r\n            var result = TestCommon.RunAICLICommand(\"uninstall\", Constants.ExeInstallerPackageId);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully uninstalled\"));\r\n            Assert.True(TestCommon.VerifyTestExeUninstalled(installDir));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test uninstall msi.\r\n        /// </summary>\r\n        [Test]\r\n        public void UninstallTestMsi()\r\n        {\r\n            if (string.IsNullOrEmpty(TestIndex.MsiInstaller))\r\n            {\r\n                Assert.Ignore(\"MSI installer not available\");\r\n            }\r\n\r\n            // Uninstall an MSI\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            TestCommon.RunAICLICommand(\"install\", $\"{Constants.MsiInstallerPackageId} -l {installDir}\");\r\n            var result = TestCommon.RunAICLICommand(\"uninstall\", Constants.MsiInstallerPackageId);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully uninstalled\"));\r\n            Assert.True(TestCommon.VerifyTestMsiUninstalled(installDir));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test uninstall msix.\r\n        /// </summary>\r\n        [Test]\r\n        public void UninstallTestMsix()\r\n        {\r\n            // Uninstall an MSIX\r\n            TestCommon.RunAICLICommand(\"install\", Constants.MsixInstallerPackageId);\r\n            var result = TestCommon.RunAICLICommand(\"uninstall\", Constants.MsixInstallerPackageId);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully uninstalled\"));\r\n            Assert.True(TestCommon.VerifyTestMsixUninstalled());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test uninstall msix package with machine scope.\r\n        /// </summary>\r\n        [Test]\r\n        public void UninstallTestMsixMachineScope()\r\n        {\r\n            // TODO: Provision and Deprovision api not supported in build server.\r\n            Assert.Ignore();\r\n\r\n            // Uninstall an MSIX\r\n            TestCommon.RunAICLICommand(\"install\", $\"{Constants.MsixInstallerPackageId} --scope machine\");\r\n            var result = TestCommon.RunAICLICommand(\"uninstall\", $\"{Constants.MsixInstallerPackageId} --scope machine\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully uninstalled\"));\r\n            Assert.True(TestCommon.VerifyTestMsixUninstalled(true));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test uninstall portable package.\r\n        /// </summary>\r\n        [Test]\r\n        public void UninstallPortable()\r\n        {\r\n            // Uninstall a Portable\r\n            string installDir = Path.Combine(System.Environment.GetEnvironmentVariable(\"LocalAppData\"), \"Microsoft\", \"WinGet\", \"Packages\");\r\n            string packageId, commandAlias, fileName, packageDirName, productCode;\r\n            packageId = \"AppInstallerTest.TestPortableExe\";\r\n            packageDirName = productCode = packageId + \"_\" + Constants.TestSourceIdentifier;\r\n            commandAlias = fileName = \"AppInstallerTestExeInstaller.exe\";\r\n\r\n            TestCommon.RunAICLICommand(\"install\", $\"{packageId}\");\r\n            var result = TestCommon.RunAICLICommand(\"uninstall\", $\"{packageId}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully uninstalled\"));\r\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, false);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test uninstall portable package with product code.\r\n        /// </summary>\r\n        [Test]\r\n        public void UninstallPortableWithProductCode()\r\n        {\r\n            // Uninstall a Portable with ProductCode\r\n            string installDir = TestCommon.GetPortablePackagesDirectory();\r\n            string packageId, commandAlias, fileName, packageDirName, productCode;\r\n            packageId = \"AppInstallerTest.TestPortableExe\";\r\n            packageDirName = productCode = packageId + \"_\" + Constants.TestSourceIdentifier;\r\n            commandAlias = fileName = \"AppInstallerTestExeInstaller.exe\";\r\n\r\n            TestCommon.RunAICLICommand(\"install\", $\"{packageId}\");\r\n            var result = TestCommon.RunAICLICommand(\"uninstall\", $\"--product-code {productCode}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully uninstalled\"));\r\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, false);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test uninstall portable package with modified symlink.\r\n        /// </summary>\r\n        [Test]\r\n        public void UninstallPortableModifiedSymlink()\r\n        {\r\n            string installDir = TestCommon.GetPortablePackagesDirectory();\r\n            string packageId, commandAlias, fileName, packageDirName, productCode;\r\n            packageId = \"AppInstallerTest.TestPortableExe\";\r\n            packageDirName = productCode = packageId + \"_\" + Constants.TestSourceIdentifier;\r\n            commandAlias = fileName = \"AppInstallerTestExeInstaller.exe\";\r\n\r\n            TestCommon.RunAICLICommand(\"install\", $\"{packageId}\");\r\n\r\n            string symlinkDirectory = TestCommon.GetPortableSymlinkDirectory(TestCommon.Scope.User);\r\n            string symlinkPath = Path.Combine(symlinkDirectory, commandAlias);\r\n\r\n            // Replace symlink with modified symlink\r\n            File.Delete(symlinkPath);\r\n            FileSystemInfo modifiedSymlinkInfo = File.CreateSymbolicLink(symlinkPath, \"fakeTargetExe\");\r\n\r\n            var result = TestCommon.RunAICLICommand(\"uninstall\", $\"{packageId}\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_PORTABLE_UNINSTALL_FAILED, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Unable to remove Portable package as it has been modified; to override this check use --force\"));\r\n            Assert.True(modifiedSymlinkInfo.Exists, \"Modified symlink should still exist\");\r\n\r\n            // Try again with --force\r\n            var result2 = TestCommon.RunAICLICommand(\"uninstall\", $\"{packageId} --force\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode);\r\n            Assert.True(result2.StdOut.Contains(\"Portable package has been modified; proceeding due to --force\"));\r\n            Assert.True(result2.StdOut.Contains(\"Successfully uninstalled\"));\r\n\r\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, false);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test uninstall zip portable package.\r\n        /// </summary>\r\n        [Test]\r\n        public void UninstallZip_Portable()\r\n        {\r\n            string installDir = TestCommon.GetPortablePackagesDirectory();\r\n            string packageId, commandAlias, fileName, packageDirName, productCode;\r\n            packageId = \"AppInstallerTest.TestZipInstallerWithPortable\";\r\n            packageDirName = productCode = packageId + \"_\" + Constants.TestSourceIdentifier;\r\n            commandAlias = \"TestPortable.exe\";\r\n            fileName = \"AppInstallerTestExeInstaller.exe\";\r\n\r\n            var testResult = TestCommon.RunAICLICommand(\"install\", $\"{packageId}\");\r\n            var result = TestCommon.RunAICLICommand(\"uninstall\", $\"{packageId}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully uninstalled\"));\r\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, false);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test uninstall not indexed.\r\n        /// </summary>\r\n        [Test]\r\n        public void UninstallNotIndexed()\r\n        {\r\n            // Uninstalls a package found with ARP not matching any known manifest.\r\n            // Install the test EXE providing a custom Product Code so that it cannot be mapped\r\n            // back to its manifest, then uninstall it using its Product Code\r\n            var installDir = TestCommon.GetRandomTestDir();\r\n            TestCommon.RunAICLICommand(\"install\", $\"{Constants.ExeInstallerPackageId} --override \\\"/ProductID {CustomProductCode} /InstallDir {installDir}\");\r\n            var result = TestCommon.RunAICLICommand(\"uninstall\", CustomProductCode);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully uninstalled\"));\r\n            Assert.True(TestCommon.VerifyTestExeUninstalled(installDir));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test uninstalled app not found.\r\n        /// </summary>\r\n        [Test]\r\n        public void UninstallAppNotInstalled()\r\n        {\r\n            // Verify failure when trying to uninstall an app that is not installed.\r\n            var result = TestCommon.RunAICLICommand(\"uninstall\", $\"TestMsixInstaller\");\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"No installed package found matching input criteria.\"));\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/UpgradeCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"UpgradeCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using System.IO;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// Test upgrade command.\r\n    /// </summary>\r\n    public class UpgradeCommand : BaseCommand\r\n    {\r\n        private static readonly string DenyUpgradePackage = \"AppInstallerTest.TestUpgradeDeny\";\r\n\r\n        /// <summary>\r\n        /// Tear down.\r\n        /// </summary>\r\n        [TearDown]\r\n        public void TearDown()\r\n        {\r\n            // Due to its properties, this being present is problematic.\r\n            TestCommon.RunAICLICommand(\"uninstall\", DenyUpgradePackage);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test upgrade portable package.\r\n        /// </summary>\r\n        [Test]\r\n        public void UpgradePortable()\r\n        {\r\n            string installDir = TestCommon.GetPortablePackagesDirectory();\r\n            string packageId, commandAlias, fileName, packageDirName, productCode;\r\n            packageId = \"AppInstallerTest.TestPortableExe\";\r\n            packageDirName = productCode = packageId + \"_\" + Constants.TestSourceIdentifier;\r\n            commandAlias = fileName = \"AppInstallerTestExeInstaller.exe\";\r\n\r\n            var result = TestCommon.RunAICLICommand(\"install\", \"AppInstallerTest.TestPortableExe -v 1.0.0.0\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            var result2 = TestCommon.RunAICLICommand(\"upgrade\", $\"{packageId} -v 2.0.0.0\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode);\r\n            Assert.True(result2.StdOut.Contains(\"Successfully installed\"));\r\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test upgrade portable package.\r\n        /// </summary>\r\n        [Test]\r\n        public void UpgradePortableNonAsciiPath()\r\n        {\r\n            string installDir = Path.Combine(TestCommon.GetRandomTestDir(), \"Tést\");\r\n            string packageId, commandAlias, fileName, productCode;\r\n            packageId = \"AppInstallerTest.TestPortableExe\";\r\n            productCode = packageId + \"_\" + Constants.TestSourceIdentifier;\r\n            commandAlias = fileName = \"AppInstallerTestExeInstaller.exe\";\r\n\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestPortableExe -v 1.0.0.0 -l {installDir}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            var result2 = TestCommon.RunAICLICommand(\"upgrade\", $\"{packageId} -v 2.0.0.0 -l {installDir}\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode);\r\n            Assert.True(result2.StdOut.Contains(\"Successfully installed\"));\r\n            TestCommon.VerifyPortablePackage(installDir, commandAlias, fileName, productCode, true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test upgrade portable package with arp mismatch.\r\n        /// </summary>\r\n        [Test]\r\n        public void UpgradePortableARPMismatch()\r\n        {\r\n            string packageId = \"AppInstallerTest.TestPortableExe\";\r\n            string productCode = packageId + \"_\" + Constants.TestSourceIdentifier;\r\n\r\n            var installResult = TestCommon.RunAICLICommand(\"install\", \"AppInstallerTest.TestPortableExe -v 1.0.0.0\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, installResult.ExitCode);\r\n            Assert.True(installResult.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            // Modify packageId to cause mismatch.\r\n            TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetPackageIdentifier, \"testPackageId\");\r\n\r\n            var upgradeResult = TestCommon.RunAICLICommand(\"upgrade\", $\"{packageId} -v 2.0.0.0\");\r\n\r\n            // Reset and perform uninstall cleanup\r\n            TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetPackageIdentifier, packageId);\r\n            TestCommon.RunAICLICommand(\"uninstall\", $\"--product-code {productCode}\");\r\n\r\n            Assert.AreNotEqual(Constants.ErrorCode.S_OK, upgradeResult.ExitCode);\r\n            Assert.True(upgradeResult.StdOut.Contains(\"Portable package from a different source already exists\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test upgrade portable package force override.\r\n        /// </summary>\r\n        [Test]\r\n        public void UpgradePortableForcedOverride()\r\n        {\r\n            string installDir = TestCommon.GetPortablePackagesDirectory();\r\n            string packageId, commandAlias, fileName, packageDirName, productCode;\r\n            packageId = \"AppInstallerTest.TestPortableExe\";\r\n            packageDirName = productCode = packageId + \"_\" + Constants.TestSourceIdentifier;\r\n            commandAlias = fileName = \"AppInstallerTestExeInstaller.exe\";\r\n\r\n            var installResult = TestCommon.RunAICLICommand(\"install\", \"AppInstallerTest.TestPortableExe -v 1.0.0.0\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, installResult.ExitCode);\r\n            Assert.True(installResult.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            // Modify packageId and sourceId to cause mismatch.\r\n            TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetPackageIdentifier, \"testPackageId\");\r\n            TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetSourceIdentifier, \"testSourceId\");\r\n\r\n            var upgradeResult = TestCommon.RunAICLICommand(\"upgrade\", $\"{packageId} -v 2.0.0.0 --force\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, upgradeResult.ExitCode);\r\n            Assert.True(upgradeResult.StdOut.Contains(\"Successfully installed\"));\r\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test upgrade portable package uninstall previous version.\r\n        /// </summary>\r\n        [Test]\r\n        public void UpgradePortableUninstallPrevious()\r\n        {\r\n            string installDir = TestCommon.GetPortablePackagesDirectory();\r\n            string packageId, commandAlias, fileName, packageDirName, productCode;\r\n            packageId = \"AppInstallerTest.TestPortableExe\";\r\n            packageDirName = productCode = packageId + \"_\" + Constants.TestSourceIdentifier;\r\n            commandAlias = fileName = \"AppInstallerTestExeInstaller.exe\";\r\n\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"{packageId} -v 1.0.0.0\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            var result2 = TestCommon.RunAICLICommand(\"upgrade\", $\"{packageId} -v 3.0.0.0\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode);\r\n            Assert.True(result2.StdOut.Contains(\"Successfully installed\"));\r\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test upgrade with deny behavior.\r\n        /// </summary>\r\n        [Test]\r\n        public void UpgradeBehaviorDeny()\r\n        {\r\n            string packageId = DenyUpgradePackage;\r\n\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"{packageId} -v 1.0.0.0\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            var result2 = TestCommon.RunAICLICommand(\"upgrade\", $\"{packageId} -v 2.0.0.0\");\r\n            Assert.AreEqual(Constants.ErrorCode.APPINSTALLER_CLI_ERROR_INSTALL_UPGRADE_NOT_SUPPORTED, result2.ExitCode);\r\n            Assert.True(result2.StdOut.Contains(\"package cannot be upgraded using WinGet\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test upgrade portable package machine scope.\r\n        /// </summary>\r\n        [Test]\r\n        public void UpgradePortableMachineScope()\r\n        {\r\n            string installDir = TestCommon.GetRandomTestDir();\r\n            WinGetSettingsHelper.ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, installDir);\r\n\r\n            string packageId, commandAlias, fileName, packageDirName, productCode;\r\n            packageId = \"AppInstallerTest.TestPortableExe\";\r\n            packageDirName = productCode = packageId + \"_\" + Constants.TestSourceIdentifier;\r\n            commandAlias = fileName = \"AppInstallerTestExeInstaller.exe\";\r\n\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"{packageId} -v 1.0.0.0 --scope machine\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            var result2 = TestCommon.RunAICLICommand(\"upgrade\", $\"{packageId} -v 2.0.0.0\");\r\n            WinGetSettingsHelper.ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, string.Empty);\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode);\r\n            Assert.True(result2.StdOut.Contains(\"Successfully installed\"));\r\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true, TestCommon.Scope.Machine);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test upgrade zip portable package.\r\n        /// </summary>\r\n        [Test]\r\n        public void UpgradeZip_Portable()\r\n        {\r\n            string installDir = TestCommon.GetPortablePackagesDirectory();\r\n            string packageId, commandAlias, fileName, packageDirName, productCode;\r\n            packageId = \"AppInstallerTest.TestZipInstallerWithPortable\";\r\n            packageDirName = productCode = packageId + \"_\" + Constants.TestSourceIdentifier;\r\n            commandAlias = \"TestPortable.exe\";\r\n            fileName = \"AppInstallerTestExeInstaller.exe\";\r\n\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestZipInstallerWithPortable -v 1.0.0.0\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Successfully installed\"));\r\n\r\n            var result2 = TestCommon.RunAICLICommand(\"upgrade\", $\"{packageId} -v 2.0.0.0\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode);\r\n            Assert.True(result2.StdOut.Contains(\"Successfully installed\"));\r\n            TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true, TestCommon.Scope.User);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test upgrade when a new dependency is added that is not installed.\r\n        /// </summary>\r\n        [Test]\r\n        public void UpgradeAddsDependency()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"install\", $\"AppInstallerTest.TestUpgradeAddsDependency -v 1.0 --verbose\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n\r\n            result = TestCommon.RunAICLICommand(\"upgrade\", $\"AppInstallerTest.TestUpgradeAddsDependency\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/ValidateCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ValidateCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests\r\n{\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\r\n\r\n    /// <summary>\r\n    /// Test validate command.\r\n    /// </summary>\r\n    public class ValidateCommand : BaseCommand\r\n    {\r\n        /// <summary>\r\n        /// Test validate manifest.\r\n        /// </summary>\r\n        [Test]\r\n        public void ValidateManifest()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"validate\", TestCommon.GetTestDataFile(\"Manifests\\\\TestValidManifest.yaml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Manifest validation succeeded.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test validate manifest with extended characters.\r\n        /// </summary>\r\n        [Test]\r\n        public void ValidateManifestWithExtendedCharacter()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"validate\", TestCommon.GetTestDataFile(\"Manifests\\\\TstExeInstaller.yaml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Manifest validation succeeded.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test validate invalid manifest.\r\n        /// </summary>\r\n        [Test]\r\n        public void ValidateInvalidManifest()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"validate\", TestCommon.GetTestDataFile(\"Manifests\\\\TestInvalidManifest.yaml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_MANIFEST_VALIDATION_FAILURE, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Manifest validation failed.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test validate manifest with warnings.\r\n        /// </summary>\r\n        [Test]\r\n        public void ValidateManifestWithWarnings()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"validate\", TestCommon.GetTestDataFile(\"Manifests\\\\TestWarningManifest.yaml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_MANIFEST_VALIDATION_WARNING, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Manifest validation succeeded with warnings.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test validate manifest with warnings suppressed.\r\n        /// </summary>\r\n        [Test]\r\n        public void ValidateManifestSuppressWarnings()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"validate\", TestCommon.GetTestDataFile(\"Manifests\\\\TestWarningManifest.yaml\") + \" --ignore-warnings\");\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n            Assert.False(result.StdOut.Contains(\"Manifest validation succeeded with warnings.\"));\r\n            Assert.True(result.StdOut.Contains(\"Manifest validation succeeded.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test validate manifest that doesn't exist.\r\n        /// </summary>\r\n        [Test]\r\n        public void ValidateManifestDoesNotExist()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"validate\", TestCommon.GetTestDataFile(\"Manifests\\\\DoesNotExist\"));\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_PATH_NOT_FOUND, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Path does not exist\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test validate manifest with invalid schema and expect warnings.\r\n        /// </summary>\r\n        [Test]\r\n        public void ValidateManifestV1_10_SchemaHeaderExpectWarnings()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"validate\", TestCommon.GetTestDataFile(\"Manifests\\\\TestWarningManifestV1_10-SchemaHeaderNotFound.yaml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_MANIFEST_VALIDATION_WARNING, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Manifest validation succeeded with warnings.\"));\r\n            Assert.True(result.StdOut.Contains(\"Manifest Warning: Schema header not found.\"));\r\n\r\n            result = TestCommon.RunAICLICommand(\"validate\", TestCommon.GetTestDataFile(\"Manifests\\\\TestWarningManifestV1_10-SchemaHeaderInvalid.yaml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_MANIFEST_VALIDATION_WARNING, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Manifest validation succeeded with warnings.\"));\r\n            Assert.True(result.StdOut.Contains(\"Manifest Warning: The schema header is invalid. Please verify that the schema header is present and formatted correctly.\"));\r\n\r\n            result = TestCommon.RunAICLICommand(\"validate\", TestCommon.GetTestDataFile(\"Manifests\\\\TestWarningManifestV1_10-SchemaHeaderURLPatternMismatch.yaml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_MANIFEST_VALIDATION_WARNING, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Manifest validation succeeded with warnings.\"));\r\n            Assert.True(result.StdOut.Contains(\"Manifest Warning: The schema header URL does not match the expected pattern\"));\r\n\r\n            result = TestCommon.RunAICLICommand(\"validate\", TestCommon.GetTestDataFile(\"Manifests\\\\TestWarningManifestV1_10-SchemaHeaderManifestTypeMismatch.yaml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_MANIFEST_VALIDATION_WARNING, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Manifest validation succeeded with warnings.\"));\r\n            Assert.True(result.StdOut.Contains(\"Manifest Warning: The manifest type in the schema header does not match the ManifestType property value in the manifest.\"));\r\n\r\n            result = TestCommon.RunAICLICommand(\"validate\", TestCommon.GetTestDataFile(\"Manifests\\\\TestWarningManifestV1_10-SchemaHeaderVersionMismatch.yaml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.ERROR_MANIFEST_VALIDATION_WARNING, result.ExitCode);\r\n            Assert.True(result.StdOut.Contains(\"Manifest validation succeeded with warnings.\"));\r\n            Assert.True(result.StdOut.Contains(\"Manifest Warning: The manifest version in the schema header does not match the ManifestVersion property value in the manifest.\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test validate manifest with valid schema header.\r\n        /// </summary>\r\n        [Test]\r\n        public void ValidateManifestV1_10_SchemaHeaderExpectNoWarning()\r\n        {\r\n            var result = TestCommon.RunAICLICommand(\"validate\", TestCommon.GetTestDataFile(\"Manifests\\\\TestGoodManifestV1_10-SchemaHeader.yaml\"));\r\n            Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilCompareVersions.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"WinGetUtilCompareVersions.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests.WinGetUtil\n{\n    using NUnit.Framework;\n\n    /// <summary>\r\n    /// Test winget util compare versions.\r\n    /// </summary>\n    public class WinGetUtilCompareVersions\n    {\n        /// <summary>\r\n        /// Test compare versions.\r\n        /// </summary>\r\n        /// <param name=\"version1\">Version 1.</param>\r\n        /// <param name=\"version2\">Version 2.</param>\r\n        /// <param name=\"expectedResult\">Expected result.</param>\n        [Test]\n        //// V1 = V2\n        [TestCase(\"1.0.0.0\", \"1.0.0.0\", 0)]\n        [TestCase(\"1.0.0\", \"1.0.0.0\", 0)]\n        [TestCase(\"1.0\", \"1.0.0.0\", 0)]\n        [TestCase(\"1\", \"1.0.0.0\", 0)]\n        //// V1 > V2\n        [TestCase(\"1.0.0.1\", \"1.0.0.0\", 1)]\n        [TestCase(\"1.0.1.0\", \"1.0.0.0\", 1)]\n        [TestCase(\"1.1.0.0\", \"1.0.0.0\", 1)]\n        [TestCase(\"2.0.0.0\", \"1.0.0.0\", 1)]\n        //// V1 < V2\n        [TestCase(\"1.0.0.0\", \"1.0.0.1\", -1)]\n        [TestCase(\"1.0.0.0\", \"1.0.1.0\", -1)]\n        [TestCase(\"1.0.0.0\", \"1.1.0.0\", -1)]\n        [TestCase(\"1.0.0.0\", \"2.0.0.0\", -1)]\n        public void WinGetUtil_CompareVersions(string version1, string version2, int expectedResult)\n        {\n            // Compare versions\n            WinGetUtilWrapper.WinGetCompareVersions(version1, version2, out int result);\n            Assert.AreEqual(expectedResult, result);\n        }\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilDownload.cs",
    "content": "﻿// -----------------------------------------------------------------------------\n// <copyright file=\"WinGetUtilDownload.cs\" company=\"Microsoft Corporation\">\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\n// </copyright>\n// -----------------------------------------------------------------------------\n\nnamespace AppInstallerCLIE2ETests.WinGetUtil\n{\n    using System.IO;\n    using System.Linq;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\n\n    /// <summary>\n    /// Test winget util download.\n    /// </summary>\n    public class WinGetUtilDownload\n    {\n        /// <summary>\n        /// Test download.\n        /// </summary>\n        [Test]\n        public void WinGetUtil_Download()\n        {\n            uint hashSize = 32;\n            byte[] sha256Hash = new byte[hashSize];\n            string installerUrl = @\"https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe\";\n            string filePath = TestCommon.GetRandomTestFile(\".exe\");\n\n            // Download\n            WinGetUtilWrapper.WinGetDownload(installerUrl, filePath, sha256Hash, hashSize);\n\n            Assert.True(File.Exists(filePath));\n            Assert.False(sha256Hash.All(byteVal => byteVal == 0));\n        }\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilInstallerMetadataCollection.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"WinGetUtilInstallerMetadataCollection.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests.WinGetUtil\n{\n    using System;\n    using System.IO;\n    using System.Runtime.InteropServices;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using Newtonsoft.Json;\n    using NUnit.Framework;\n\n    /// <summary>\r\n    /// Test winget util installer metadata.\r\n    /// </summary>\n    public class WinGetUtilInstallerMetadataCollection\n    {\n        /// <summary>\r\n        /// Test begin complete installer metadata.\r\n        /// </summary>\n        [Test]\n        public void WinGetUtil_BeginCompleteInstallerMetadataCollection()\n        {\n            string logFilePath = TestCommon.GetRandomTestFile(\".log\");\n            string inputJson = TestCommon.GetTestDataFile(@\"WinGetUtil\\InstallerMetadata\\Minimal.json\");\n            string outputFilePath = TestCommon.GetRandomTestFile(\".json\");\n\n            WinGetUtilWrapper.WinGetBeginInstallerMetadataCollection(\n                inputJson,\n                logFilePath,\n                WinGetUtilWrapper.WinGetBeginInstallerMetadataCollectionOptions.WinGetBeginInstallerMetadataCollectionOption_InputIsFilePath,\n                out IntPtr collectionHandle);\n\n            Assert.AreNotEqual(IntPtr.Zero, collectionHandle);\n            Assert.True(File.Exists(logFilePath));\n\n            WinGetUtilWrapper.WinGetCompleteInstallerMetadataCollection(\n                collectionHandle,\n                outputFilePath,\n                WinGetUtilWrapper.WinGetCompleteInstallerMetadataCollectionOptions.WinGetCompleteInstallerMetadataCollectionOption_None);\n\n            string outputJson = File.ReadAllText(outputFilePath);\n            Assert.IsNotEmpty(JsonConvert.DeserializeObject(outputJson).ToString());\n        }\n\n        /// <summary>\r\n        /// Test merge installer metadata.\r\n        /// </summary>\n        [Test]\n        public void WinGetUtil_MergeInstallerMetadata_Success()\n        {\n            string logFilePath = TestCommon.GetRandomTestFile(\".log\");\n            string inputJsonPath = TestCommon.GetTestDataFile(@\"WinGetUtil\\InstallerMetadata\\MergeValid.json\");\n            string inputJson = File.ReadAllText(inputJsonPath);\n\n            WinGetUtilWrapper.WinGetMergeInstallerMetadata(\n               inputJson,\n               out string outputJson,\n               0,\n               logFilePath,\n               WinGetUtilWrapper.WinGetMergeInstallerMetadataOptions.WinGetMergeInstallerMetadataOptions_None);\n\n            Assert.True(File.Exists(logFilePath));\n            Assert.IsNotEmpty(JsonConvert.DeserializeObject(outputJson).ToString());\n        }\n\n        /// <summary>\r\n        /// Test merge installer metadata failed.\r\n        /// </summary>\n        [Test]\n        public void WinGetUtil_MergeInstallerMetadata_Fail_SubmissionMismatch()\n        {\n            string logFilePath = TestCommon.GetRandomTestFile(\".log\");\n            string inputJsonPath = TestCommon.GetTestDataFile(@\"WinGetUtil\\InstallerMetadata\\MergeSubmissionMismatch.json\");\n            string inputJson = File.ReadAllText(inputJsonPath);\n\n            Assert.Throws<COMException>(() =>\n            {\n                WinGetUtilWrapper.WinGetMergeInstallerMetadata(\n                   inputJson,\n                   out string outputJson,\n                   0,\n                   logFilePath,\n                   WinGetUtilWrapper.WinGetMergeInstallerMetadataOptions.WinGetMergeInstallerMetadataOptions_None);\n            });\n\n            Assert.True(File.Exists(logFilePath));\n        }\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilLog.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"WinGetUtilLog.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests.WinGetUtil\n{\n    using System.IO;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\n\n    /// <summary>\r\n    /// Test winget util log.\r\n    /// </summary>\n    public class WinGetUtilLog\n    {\n        /// <summary>\r\n        /// Test logging functions.\r\n        /// </summary>\n        [Test]\n        public void WinGetUtil_Logging()\n        {\n            string filePath = TestCommon.GetRandomTestFile(\".log\");\n\n            // Init logging\n            WinGetUtilWrapper.WinGetLoggingInit(filePath);\n            Assert.True(File.Exists(filePath));\n\n            // Terminate logging\n            WinGetUtilWrapper.WinGetLoggingTerm(filePath);\n        }\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilManifest.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"WinGetUtilManifest.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests.WinGetUtil\n{\n    using System;\n    using System.IO;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\n\n    /// <summary>\r\n    /// Test winget util manifest.\r\n    /// </summary>\n    public class WinGetUtilManifest\n    {\n        private IntPtr indexHandle;\n\n        /// <summary>\r\n        /// Set up.\r\n        /// </summary>\n        [SetUp]\n        public void SetUp()\n        {\n            this.indexHandle = IntPtr.Zero;\n            var sqliteFile = TestCommon.GetRandomTestFile(\".db\");\n            uint majorVersion = 1;\n            uint minorVersion = 2;\n            WinGetUtilWrapper.WinGetSQLiteIndexCreate(sqliteFile, majorVersion, minorVersion, out this.indexHandle);\n        }\n\n        /// <summary>\r\n        /// Tear down.\r\n        /// </summary>\n        [TearDown]\n        public void TearDown()\n        {\n            WinGetUtilWrapper.WinGetSQLiteIndexClose(this.indexHandle);\n        }\n\n        /// <summary>\r\n        /// Test validate manifest.\r\n        /// </summary>\r\n        /// <param name=\"createManifestOption\">Create manifest options.</param>\n        [Test]\n        [TestCase(WinGetUtilWrapper.CreateManifestOption.NoValidation)]\n        [TestCase(WinGetUtilWrapper.CreateManifestOption.SchemaAndSemanticValidation)]\n        public void WinGetUtil_ValidateManifest_Success(WinGetUtilWrapper.CreateManifestOption createManifestOption)\n        {\n            string manifestsDir = TestCommon.GetTestDataFile(@\"WinGetUtil\\Manifests\\Unmerged\\ValidateManifest\");\n            string mergedManifestPath = TestCommon.GetRandomTestFile(\".yaml\");\n\n            // Create manifest\n            WinGetUtilWrapper.WinGetCreateManifest(\n                manifestsDir,\n                out bool succeeded,\n                out IntPtr manifestHandle,\n                out string createFailureMessage,\n                mergedManifestPath,\n                createManifestOption);\n\n            Assert.True(succeeded);\n            Assert.AreNotEqual(IntPtr.Zero, manifestHandle);\n            Assert.IsNull(createFailureMessage);\n            Assert.True(File.Exists(mergedManifestPath));\n\n            // Validate manifest\n            WinGetUtilWrapper.WinGetValidateManifestV3(\n                manifestHandle,\n                this.indexHandle,\n                out WinGetUtilWrapper.ValidateManifestResultCode resultCode,\n                out string validateFailureMessage,\n                WinGetUtilWrapper.ValidateManifestOptionV2.ArpVersionValidation,\n                WinGetUtilWrapper.ValidateManifestOperationType.Add);\n\n            Assert.AreEqual(WinGetUtilWrapper.ValidateManifestResultCode.Success, resultCode);\n            Assert.IsEmpty(validateFailureMessage);\n\n            // Close manifest\n            WinGetUtilWrapper.WinGetCloseManifest(manifestHandle);\n        }\r\n\r\n        /// <summary>\r\n        /// Test validate manifest with schema header.\r\n        /// </summary>\r\n        /// <param name=\"createManifestOption\">Create manifest options.</param>\r\n        [Test]\r\n        [TestCase(WinGetUtilWrapper.CreateManifestOption.NoValidation)]\n        [TestCase(WinGetUtilWrapper.CreateManifestOption.SchemaAndSemanticValidation)]\r\n        public void WinGetUtil_ValidateManifest_V1_10_WithSchemaHeader_Success(WinGetUtilWrapper.CreateManifestOption createManifestOption)\r\n        {\r\n            string manifestsFilePath = TestCommon.GetTestDataFile(@\"Manifests\\TestGoodManifestV1_10-SchemaHeader.yaml\");\r\n\r\n            // Create manifest\r\n            WinGetUtilWrapper.WinGetCreateManifest(\r\n                manifestsFilePath,\r\n                out bool succeeded,\r\n                out IntPtr manifestHandle,\r\n                out string createFailureMessage,\r\n                string.Empty,\r\n                createManifestOption);\r\n\r\n            Assert.True(succeeded);\r\n            Assert.AreNotEqual(IntPtr.Zero, manifestHandle);\r\n            Assert.IsNull(createFailureMessage);\r\n\r\n            // Close manifest\r\n            WinGetUtilWrapper.WinGetCloseManifest(manifestHandle);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test validate manifest with schema header for failure scenarios.\r\n        /// </summary>\r\n        /// <param name=\"createManifestOption\">Create manifest options.</param>\r\n        [Test]\r\n        [TestCase(WinGetUtilWrapper.CreateManifestOption.SchemaAndSemanticValidation)]\r\n        public void WinGetUtil_ValidateManifest_V1_10_WithSchemaHeader_Failure(WinGetUtilWrapper.CreateManifestOption createManifestOption)\r\n        {\r\n            // Schema header not found\r\n            string manifestsFilePath = TestCommon.GetTestDataFile(@\"Manifests\\TestWarningManifestV1_10-SchemaHeaderNotFound.yaml\");\r\n            string expectedError = \"Manifest Error: Schema header not found.\";\r\n            ValidateSchemaHeaderFailure(manifestsFilePath, createManifestOption, expectedError);\r\n\r\n            // Schema header invalid\r\n            manifestsFilePath = TestCommon.GetTestDataFile(@\"Manifests\\TestWarningManifestV1_10-SchemaHeaderInvalid.yaml\");\r\n            expectedError = \"Manifest Error: The schema header is invalid. Please verify that the schema header is present and formatted correctly.\";\r\n            ValidateSchemaHeaderFailure(manifestsFilePath, createManifestOption, expectedError);\r\n\r\n            // Schema header URL pattern mismatch\r\n            manifestsFilePath = TestCommon.GetTestDataFile(@\"Manifests\\TestWarningManifestV1_10-SchemaHeaderURLPatternMismatch.yaml\");\r\n            expectedError = \"Manifest Error: The schema header URL does not match the expected pattern.\";\r\n            ValidateSchemaHeaderFailure(manifestsFilePath, createManifestOption, expectedError);\r\n\r\n            // Schema header manifest type mismatch\r\n            manifestsFilePath = TestCommon.GetTestDataFile(@\"Manifests\\TestWarningManifestV1_10-SchemaHeaderManifestTypeMismatch.yaml\");\r\n            expectedError = \"Manifest Error: The manifest type in the schema header does not match the ManifestType property value in the manifest.\";\r\n            ValidateSchemaHeaderFailure(manifestsFilePath, createManifestOption, expectedError);\r\n\r\n            // Schema header version mismatch\r\n            manifestsFilePath = TestCommon.GetTestDataFile(@\"Manifests\\TestWarningManifestV1_10-SchemaHeaderVersionMismatch.yaml\");\r\n            expectedError = \"Manifest Error: The manifest version in the schema header does not match the ManifestVersion property value in the manifest.\";\r\n            ValidateSchemaHeaderFailure(manifestsFilePath, createManifestOption, expectedError);\r\n        }\r\n\r\n        private static void ValidateSchemaHeaderFailure(string manifestsFilePath, WinGetUtilWrapper.CreateManifestOption createManifestOption, string expectedError)\r\n        {\r\n            // Create manifest\r\n            WinGetUtilWrapper.WinGetCreateManifest(\r\n                manifestsFilePath,\r\n                out bool succeeded,\r\n                out IntPtr manifestHandle,\r\n                out string createFailureMessage,\r\n                string.Empty,\r\n                createManifestOption);\r\n\r\n            Assert.False(succeeded);\r\n            Assert.AreEqual(IntPtr.Zero, manifestHandle);\r\n            Assert.IsNotNull(createFailureMessage);\r\n            Assert.IsTrue(createFailureMessage.Contains(expectedError));\r\n        }\r\n    }\r\n}\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilSQLiteIndex.cs",
    "content": "﻿// -----------------------------------------------------------------------------\n// <copyright file=\"WinGetUtilSQLiteIndex.cs\" company=\"Microsoft Corporation\">\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\n// </copyright>\n// -----------------------------------------------------------------------------\n\nnamespace AppInstallerCLIE2ETests.WinGetUtil\n{\n    using System;\n    using System.IO;\n    using System.Runtime.InteropServices;\r\n    using AppInstallerCLIE2ETests.Helpers;\r\n    using NUnit.Framework;\n\n    /// <summary>\n    /// WinGetUtil sql index tests.\n    /// </summary>\n    public class WinGetUtilSQLiteIndex\n    {\n        private readonly uint majorVersion = 1;\n        private readonly uint minorVersion = 2;\n\n        // Manifest example 1\n        private readonly string addManifestsFile = TestCommon.GetTestDataFile(@\"WinGetUtil\\Manifests\\Merged\\WinGetUtilTest.Add.yaml\");\n        private readonly string updateManifestsFile = TestCommon.GetTestDataFile(@\"WinGetUtil\\Manifests\\Merged\\WinGetUtilTest.Update.yaml\");\n        private readonly string relativePath = @\"manifests\\a\\AppInstallerTest\\WinGetUtilTest\\1.0.0.0\\WinGetTest.yaml\";\n\n        private string sqlitePath;\n\n        /// <summary>\n        /// Set up.\n        /// </summary>\n        [SetUp]\n        public void SetUp()\n        {\n             this.sqlitePath = TestCommon.GetRandomTestFile(\".sql\");\n        }\n\n        /// <summary>\n        /// Test add manifest.\n        /// </summary>\n        [Test]\n        public void WinGetUtil_SQLiteIndex_AddManifest()\n        {\n            this.SQLiteIndex((indexHandle) =>\n            {\n                // Add manifest\n                WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, this.addManifestsFile, this.relativePath);\n            });\n        }\n\n        /// <summary>\n        /// Test update manifest.\n        /// </summary>\n        [Test]\n        public void WinGetUtil_SQLiteIndex_UpdateManifest_Success()\n        {\n            this.SQLiteIndex((indexHandle) =>\n            {\n                // Add manifest\n                WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, this.addManifestsFile, this.relativePath);\n\n                // Update manifest\n                WinGetUtilWrapper.WinGetSQLiteIndexUpdateManifest(indexHandle, this.updateManifestsFile, this.relativePath, out bool indexModified);\n                Assert.True(indexModified);\n            });\n        }\n\n        /// <summary>\n        /// Test update manifest file not found.\n        /// </summary>\n        [Test]\n        public void WinGetUtil_SQLiteIndex_UpdateManifest_Fail_NotFound()\n        {\n            this.SQLiteIndex((indexHandle) =>\n            {\n                // Update non-existing manifest\n                Assert.Throws<COMException>(() =>\n                {\n                    WinGetUtilWrapper.WinGetSQLiteIndexUpdateManifest(indexHandle, this.updateManifestsFile, this.relativePath, out bool indexModified);\n                });\n            });\n        }\n\n        /// <summary>\n        /// Test remove manifest.\n        /// </summary>\n        [Test]\n        public void WinGetUtil_SQLiteIndex_RemoveManifest_Success()\n        {\n            this.SQLiteIndex((indexHandle) =>\n            {\n                // Add manifest\n                WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, this.addManifestsFile, this.relativePath);\n\n                // Remove manifest\n                WinGetUtilWrapper.WinGetSQLiteIndexRemoveManifest(indexHandle, this.addManifestsFile, this.relativePath);\n            });\n        }\n\n        /// <summary>\n        /// Test remove manifest file not found.\n        /// </summary>\n        [Test]\n        public void WinGetUtil_SQLiteIndex_RemoveManifest_Fail_NotFound()\n        {\n            this.SQLiteIndex((indexHandle) =>\n            {\n                // Remove non-existing manifest\n                Assert.Throws<COMException>(() =>\n                {\n                    WinGetUtilWrapper.WinGetSQLiteIndexRemoveManifest(indexHandle, this.addManifestsFile, this.relativePath);\n                });\n            });\n        }\n\n        /// <summary>\n        /// Test open and closing index.\n        /// </summary>\n        [Test]\n        public void WinGetUtil_SQLiteIndex_OpenClose()\n        {\n            this.SQLiteIndex((_) =>\n            {\n                // Open\n                WinGetUtilWrapper.WinGetSQLiteIndexOpen(this.sqlitePath, out IntPtr indexHandle);\n\n                // Add manifest\n                WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, this.addManifestsFile, this.relativePath);\n\n                // Close\n                WinGetUtilWrapper.WinGetSQLiteIndexClose(indexHandle);\n            });\n        }\n\n        /// <summary>\n        /// Test check consistency.\n        /// </summary>\n        [Test]\n        public void WinGetUtil_SQLiteIndex_CheckConsistency()\n        {\n            this.SQLiteIndex((indexHandle) =>\n            {\n                // Add manifest\n                WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, this.addManifestsFile, this.relativePath);\n\n                // Prepare for packaging\n                WinGetUtilWrapper.WinGetSQLiteIndexPrepareForPackaging(indexHandle);\n\n                // Check consistency\n                WinGetUtilWrapper.WinGetSQLiteIndexCheckConsistency(indexHandle, out bool succeeded);\n                Assert.True(succeeded);\n            });\n        }\n\n        /// <summary>\n        /// Create and close an sqlite index file.\n        /// </summary>\n        /// <param name=\"execute\">Function to execute.</param>\n        private void SQLiteIndex(Action<IntPtr> execute)\n        {\n            // Create\n            WinGetUtilWrapper.WinGetSQLiteIndexCreate(this.sqlitePath, this.majorVersion, this.minorVersion, out IntPtr indexHandle);\n            Assert.True(File.Exists(this.sqlitePath));\n            Assert.AreNotEqual(IntPtr.Zero, indexHandle);\n\n            // Execute provided function\n            execute(indexHandle);\n\n            // Close\n            WinGetUtilWrapper.WinGetSQLiteIndexClose(indexHandle);\n        }\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilWrapper.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"WinGetUtilWrapper.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace AppInstallerCLIE2ETests.WinGetUtil\n{\n    using System;\n    using System.Runtime.InteropServices;\n\n    /// <summary>\n    /// Wrapper class for WinGetUtil exports.\n    /// For more details about methods in this class visit WinGetUtil.h file.\n    /// </summary>\n    public class WinGetUtilWrapper\n    {\n        private const string DllName = @\"WinGetUtil.dll\";\n\n        /// <summary>\r\n        /// Create manifest flags.\r\n        /// </summary>\n        [Flags]\n        public enum CreateManifestOption\n        {\n            /// <summary>\r\n            /// No validation.\r\n            /// </summary>\n            NoValidation = 0,\n\n            /// <summary>\r\n            /// Schema validation.\r\n            /// </summary>\n            SchemaValidation = 0x1,\n\n            /// <summary>\r\n            /// Schema and semantic validation.\r\n            /// </summary>\n            SchemaAndSemanticValidation = 0x2,\n\n            /// <summary>\r\n            /// Return error on verified publisher.\r\n            /// </summary>\n            ReturnErrorOnVerifiedPublisherFields = 0x1000,\n        }\n\n        /// <summary>\r\n        /// Validate manifests results.\r\n        /// </summary>\n        [Flags]\n        public enum ValidateManifestResultCode\n        {\n            /// <summary>\r\n            /// Success.\r\n            /// </summary>\n            Success = 0,\n\n            /// <summary>\r\n            /// Dependencies validation failure.\r\n            /// </summary>\n            DependenciesValidationFailure = 0x1,\n\n            /// <summary>\r\n            /// Arp version validation failure.\r\n            /// </summary>\n            ArpVersionValidationFailure = 0x2,\n\n            /// <summary>\r\n            /// Installer validation failure.\r\n            /// </summary>\n            InstallerValidationFailure = 0x4,\n\n            /// <summary>\r\n            /// Single manifest package has dependencies.\r\n            /// </summary>\n            SingleManifestPackageHasDependencies = 0x10000,\n\n            /// <summary>\r\n            /// Multi manifest package has dependencies.\r\n            /// </summary>\n            MultiManifestPackageHasDependencies = 0x20000,\n\n            /// <summary>\r\n            /// Missing manifest dependencies.\r\n            /// </summary>\n            MissingManifestDependenciesNode = 0x40000,\n\n            /// <summary>\r\n            /// No suitable min version dependencies.\r\n            /// </summary>\n            NoSuitableMinVersionDependency = 0x80000,\n\n            /// <summary>\r\n            /// Found dependency loop.\r\n            /// </summary>\n            FoundDependencyLoop = 0x100000,\n\n            /// <summary>\r\n            /// Internal error.\r\n            /// </summary>\n            InternalError = 0x1000,\n        }\n\n        /// <summary>\r\n        /// ValidateManifestOptionV2 flags.\r\n        /// </summary>\n        [Flags]\n        public enum ValidateManifestOptionV2\n        {\n            /// <summary>\r\n            /// None.\r\n            /// </summary>\n            None = 0,\n\n            /// <summary>\r\n            /// Dependencies validation.\r\n            /// </summary>\n            DependenciesValidation = 0x1,\n\n            /// <summary>\r\n            /// Arp version validation.\r\n            /// </summary>\n            ArpVersionValidation = 0x2,\n\n            /// <summary>\r\n            /// Installer validation.\r\n            /// </summary>\n            InstallerValidation = 0x4,\n        }\n\n        /// <summary>\r\n        /// Validate manifest operation type.\r\n        /// </summary>\n        public enum ValidateManifestOperationType\n        {\n            /// <summary>\r\n            /// Add.\r\n            /// </summary>\n            Add = 0,\n\n            /// <summary>\r\n            /// Update.\r\n            /// </summary>\n            Update = 1,\n\n            /// <summary>\r\n            /// Delete.\r\n            /// </summary>\n            Delete = 2,\n        }\n\n        /// <summary>\r\n        /// Begin installer metadata collection options.\r\n        /// </summary>\n        public enum WinGetBeginInstallerMetadataCollectionOptions\n        {\n            /// <summary>\r\n            /// None.\r\n            /// </summary>\n            WinGetBeginInstallerMetadataCollectionOption_None = 0,\n\n            /// <summary>\r\n            /// Input is file path.\r\n            /// </summary>\n            WinGetBeginInstallerMetadataCollectionOption_InputIsFilePath = 0x1,\n\n            /// <summary>\r\n            /// Input is URI.\r\n            /// </summary>\n            WinGetBeginInstallerMetadataCollectionOption_InputIsURI = 0x2,\n        }\n\n        /// <summary>\r\n        /// Complete installer metadata collection.\r\n        /// </summary>\n        public enum WinGetCompleteInstallerMetadataCollectionOptions\n        {\n            /// <summary>\r\n            /// None.\r\n            /// </summary>\n            WinGetCompleteInstallerMetadataCollectionOption_None = 0,\n\n            /// <summary>\r\n            /// Abandon.\r\n            /// </summary>\n            WinGetCompleteInstallerMetadataCollectionOption_Abandon = 0x1,\n        }\n\n        /// <summary>\r\n        /// Merge installer metadata.\r\n        /// </summary>\n        public enum WinGetMergeInstallerMetadataOptions\n        {\n            /// <summary>\r\n            /// None.\r\n            /// </summary>\n            WinGetMergeInstallerMetadataOptions_None = 0,\n        }\n\n        /// <summary>\r\n        /// WinGetCompareVersion from wingetutil.dll .\r\n        /// </summary>\r\n        /// <param name=\"version1\">Version.</param>\r\n        /// <param name=\"version2\">Other version.</param>\r\n        /// <param name=\"comparisonResult\">Result of comparison.</param>\n        [DllImport(DllName, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, PreserveSig = false)]\n        public static extern void WinGetCompareVersions(string version1, string version2, [MarshalAs(UnmanagedType.U4)] out int comparisonResult);\n\n        /// <summary>\r\n        /// WinGetDownload from wingetutil.dll .\r\n        /// </summary>\r\n        /// <param name=\"url\">Url.</param>\r\n        /// <param name=\"filePath\">File path where to download.</param>\r\n        /// <param name=\"sha256Hash\">SHA256 hash.</param>\r\n        /// <param name=\"sha256HashLength\">SHA256 hash length.</param>\n        [DllImport(DllName, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, PreserveSig = false)]\n        public static extern void WinGetDownload(string url, string filePath, [MarshalAs(UnmanagedType.LPArray)] byte[] sha256Hash, uint sha256HashLength);\n\n        /// <summary>\r\n        /// WinGetLoggingInit from wingetutil.dll .\r\n        /// </summary>\r\n        /// <param name=\"logPath\">Log path.</param>\n        [DllImport(DllName, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, PreserveSig = false)]\n        public static extern void WinGetLoggingInit(string logPath);\n\n        /// <summary>\r\n        /// WinGetLoggingTerm from wingetutil.dll .\r\n        /// </summary>\r\n        /// <param name=\"logPath\">Log path.</param>\n        [DllImport(DllName, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, PreserveSig = false)]\n        public static extern void WinGetLoggingTerm(string logPath);\n\n        /// <summary>\r\n        /// WinGetCreateManifest from wingetutil.dll .\r\n        /// </summary>\r\n        /// <param name=\"inputPath\">Input path.</param>\r\n        /// <param name=\"succeeded\">Succeeded.</param>\r\n        /// <param name=\"manifestHandle\">Manifest handle.</param>\r\n        /// <param name=\"failureMessage\">Failure message.</param>\r\n        /// <param name=\"mergedManifestPath\">Merge manifest path.</param>\r\n        /// <param name=\"option\">Option.</param>\n        [DllImport(DllName, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, PreserveSig = false)]\n        public static extern void WinGetCreateManifest(\n            string inputPath,\n            [MarshalAs(UnmanagedType.U1)] out bool succeeded,\n            out IntPtr manifestHandle,\n            [MarshalAs(UnmanagedType.BStr)] out string failureMessage,\n            string mergedManifestPath,\n            CreateManifestOption option);\n\n        /// <summary>\r\n        /// WinGetCloseManifest from wingetutil.dll .\r\n        /// </summary>\r\n        /// <param name=\"manifest\">Manifest.</param>\n        [DllImport(DllName, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, PreserveSig = false)]\n        public static extern void WinGetCloseManifest(IntPtr manifest);\n\n        /// <summary>\r\n        /// WinGetValidateManifestV3 from wingetutil.dll .\r\n        /// </summary>\r\n        /// <param name=\"manifestHandle\">Manifest handle.</param>\r\n        /// <param name=\"indexHandle\">Index handle.</param>\r\n        /// <param name=\"result\">Result.</param>\r\n        /// <param name=\"failureMessage\">Failure message.</param>\r\n        /// <param name=\"option\">Option.</param>\r\n        /// <param name=\"operationType\">Operation type.</param>\n        [DllImport(DllName, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, PreserveSig = false)]\n        public static extern void WinGetValidateManifestV3(\n            IntPtr manifestHandle,\n            IntPtr indexHandle,\n            out ValidateManifestResultCode result,\n            [MarshalAs(UnmanagedType.BStr)] out string failureMessage,\n            ValidateManifestOptionV2 option,\n            ValidateManifestOperationType operationType);\n\n        /// <summary>\r\n        /// WinGetSQLiteIndexCreate from wingetutil.dll .\r\n        /// </summary>\r\n        /// <param name=\"filePath\">File path.</param>\r\n        /// <param name=\"majorVersion\">Major version.</param>\r\n        /// <param name=\"minorVersion\">Minor version.</param>\r\n        /// <param name=\"index\">Index.</param>\n        [DllImport(DllName, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, PreserveSig = false)]\n        public static extern void WinGetSQLiteIndexCreate(string filePath, uint majorVersion, uint minorVersion, out IntPtr index);\n\n        /// <summary>\r\n        /// WinGetSQLiteIndexOpen from wingetutil.dll .\r\n        /// </summary>\r\n        /// <param name=\"filePath\">File path.</param>\r\n        /// <param name=\"index\">Index.</param>\n        [DllImport(DllName, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, PreserveSig = false)]\n        public static extern void WinGetSQLiteIndexOpen(string filePath, out IntPtr index);\n\n        /// <summary>\r\n        /// WinGetSQLiteIndexClose from wingetutil.dll .\r\n        /// </summary>\r\n        /// <param name=\"index\">Index.</param>\n        [DllImport(DllName, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, PreserveSig = false)]\n        public static extern void WinGetSQLiteIndexClose(IntPtr index);\n\n        /// <summary>\r\n        /// WinGetSQLiteIndexAddManifest from wingetutil.dll .\r\n        /// </summary>\r\n        /// <param name=\"index\">Index.</param>\r\n        /// <param name=\"manifestPath\">Manifest path.</param>\r\n        /// <param name=\"relativePath\">Relative path.</param>\n        [DllImport(DllName, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, PreserveSig = false)]\n        public static extern void WinGetSQLiteIndexAddManifest(IntPtr index, string manifestPath, string relativePath);\n\n        /// <summary>\r\n        /// WinGetSQLiteIndexUpdateManifest from wingetutil.dll .\r\n        /// </summary>\r\n        /// <param name=\"index\">Index.</param>\r\n        /// <param name=\"manifestPath\">Manifest path.</param>\r\n        /// <param name=\"relativePath\">Relative path.</param>\r\n        /// <param name=\"indexModified\">Index modified.</param>\n        [DllImport(DllName, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, PreserveSig = false)]\n        public static extern void WinGetSQLiteIndexUpdateManifest(\n            IntPtr index,\n            string manifestPath,\n            string relativePath,\n            [MarshalAs(UnmanagedType.U1)] out bool indexModified);\n\n        /// <summary>\r\n        /// WinGetSQLiteIndexRemoveManifest from wingetutil.dll .\r\n        /// </summary>\r\n        /// <param name=\"index\">Index.</param>\r\n        /// <param name=\"manifestPath\">Manifest path.</param>\r\n        /// <param name=\"relativePath\">Relative path.</param>\n        [DllImport(DllName, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, PreserveSig = false)]\n        public static extern void WinGetSQLiteIndexRemoveManifest(IntPtr index, string manifestPath, string relativePath);\n\n        /// <summary>\r\n        /// WinGetSQLiteIndexPrepareForPackaging from wingetutil.dll .\r\n        /// </summary>\r\n        /// <param name=\"index\">Index.</param>\n        [DllImport(DllName, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, PreserveSig = false)]\n        public static extern void WinGetSQLiteIndexPrepareForPackaging(IntPtr index);\n\n        /// <summary>\r\n        /// WinGetSQLiteIndexCheckConsistency from wingetutil.dll .\r\n        /// </summary>\r\n        /// <param name=\"index\">Index.</param>\r\n        /// <param name=\"succeeded\">Succeeded.</param>\n        [DllImport(DllName, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, PreserveSig = false)]\n        public static extern void WinGetSQLiteIndexCheckConsistency(IntPtr index, [MarshalAs(UnmanagedType.U1)] out bool succeeded);\n\n        /// <summary>\r\n        /// WinGetBeginInstallerMetadataCollection from wingetutil.dll .\r\n        /// </summary>\r\n        /// <param name=\"inputJSON\">Input json.</param>\r\n        /// <param name=\"logFilePath\">Log file path.</param>\r\n        /// <param name=\"options\">Options.</param>\r\n        /// <param name=\"collectionHandle\">Collection handle.</param>\n        [DllImport(DllName, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, PreserveSig = false)]\n        public static extern void WinGetBeginInstallerMetadataCollection(\n            string inputJSON,\n            string logFilePath,\n            WinGetBeginInstallerMetadataCollectionOptions options,\n            out IntPtr collectionHandle);\n\n        /// <summary>\r\n        /// WinGetCompleteInstallerMetadataCollection from wingetutil.dll .\r\n        /// </summary>\r\n        /// <param name=\"collectionHandle\">Collection handle.</param>\r\n        /// <param name=\"outputFilePath\">Output file path.</param>\r\n        /// <param name=\"options\">Options.</param>\n        [DllImport(DllName, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, PreserveSig = false)]\n        public static extern void WinGetCompleteInstallerMetadataCollection(\n            IntPtr collectionHandle,\n            string outputFilePath,\n            WinGetCompleteInstallerMetadataCollectionOptions options);\n\n        /// <summary>\r\n        /// WinGetMergeInstallerMetadata from wingetutil.dll .\r\n        /// </summary>\r\n        /// <param name=\"inputJSON\">Input json.</param>\r\n        /// <param name=\"outputJSON\">Output json.</param>\r\n        /// <param name=\"maximumOutputSizeInBytes\">Maximum output size in bytes.</param>\r\n        /// <param name=\"logFilePath\">Log file path.</param>\r\n        /// <param name=\"options\">Options.</param>\n        [DllImport(DllName, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, PreserveSig = false)]\n        public static extern void WinGetMergeInstallerMetadata(\n            string inputJSON,\n            [MarshalAs(UnmanagedType.BStr)] out string outputJSON,\n            uint maximumOutputSizeInBytes,\n            string logFilePath,\n            WinGetMergeInstallerMetadataOptions options);\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLIPackage/AppInstallerCLIPackage.wapproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"15.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <PropertyGroup Condition=\"'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '15.0'\">\r\n    <VisualStudioVersion>15.0</VisualStudioVersion>\r\n  </PropertyGroup>\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|x86\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x86</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x86\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x86</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|ARM64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|ARM64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|AnyCPU\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>AnyCPU</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|AnyCPU\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>AnyCPU</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <PropertyGroup>\r\n    <WapProjPath Condition=\"'$(WapProjPath)'==''\">$(MSBuildExtensionsPath)\\Microsoft\\DesktopBridge\\</WapProjPath>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(WapProjPath)\\Microsoft.DesktopBridge.props\" />\r\n  <PropertyGroup>\r\n    <ProjectGuid>6aa3791a-0713-4548-a357-87a323e7ac3a</ProjectGuid>\r\n    <TargetPlatformVersion>10.0.26100.0</TargetPlatformVersion>\r\n    <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>\r\n    <DefaultLanguage>en-US</DefaultLanguage>\r\n    <AppxPackageSigningEnabled>false</AppxPackageSigningEnabled>\r\n    <EntryPointProjectUniqueName>..\\AppInstallerCLI\\AppInstallerCLI.vcxproj</EntryPointProjectUniqueName>\r\n  </PropertyGroup>\r\n  <ItemGroup>\r\n    <AppxManifest Include=\"Package.appxmanifest\">\r\n      <SubType>Designer</SubType>\r\n    </AppxManifest>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Content Include=\"Images\\progress-sixel\\arrow_only.png\" />\r\n    <Content Include=\"Images\\progress-sixel\\conveyor.png\" />\r\n    <Content Include=\"Images\\progress-sixel\\folders_only.png\" />\r\n    <Content Include=\"Images\\SplashScreen.scale-200_altform-colorful_theme-dark.png\" />\r\n    <Content Include=\"Images\\SplashScreen.scale-200_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\SplashScreen.scale-400.png\" />\r\n    <Content Include=\"Images\\SplashScreen.scale-400_altform-colorful_theme-dark.png\" />\r\n    <Content Include=\"Images\\SplashScreen.scale-400_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\StoreDisplay-150.png\" />\r\n    <Content Include=\"Images\\StoreDisplay-300.png\" />\r\n    <Content Include=\"Images\\StoreDisplay-71.png\" />\r\n    <Content Include=\"Images\\StoreLogo.scale-100.png\" />\r\n    <Content Include=\"Images\\StoreLogo.scale-100_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\StoreLogo.scale-125.png\" />\r\n    <Content Include=\"Images\\StoreLogo.scale-125_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\StoreLogo.scale-150.png\" />\r\n    <Content Include=\"Images\\StoreLogo.scale-150_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\StoreLogo.scale-200.png\" />\r\n    <Content Include=\"Images\\StoreLogo.scale-200_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\StoreLogo.scale-400.png\" />\r\n    <Content Include=\"Images\\StoreLogo.scale-400_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\WideTile.scale-100.png\" />\r\n    <Content Include=\"Images\\WideTile.scale-100_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\WideTile.scale-125.png\" />\r\n    <Content Include=\"Images\\WideTile.scale-125_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\WideTile.scale-150.png\" />\r\n    <Content Include=\"Images\\WideTile.scale-150_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\WideTile.scale-200.png\" />\r\n    <Content Include=\"Images\\WideTile.scale-200_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\WideTile.scale-400.png\" />\r\n    <Content Include=\"Images\\WideTile.scale-400_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\AppList.scale-100.png\" />\r\n    <Content Include=\"Images\\AppList.scale-100_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\AppList.scale-125.png\" />\r\n    <Content Include=\"Images\\AppList.scale-125_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\AppList.scale-150.png\" />\r\n    <Content Include=\"Images\\AppList.scale-150_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\AppList.scale-200.png\" />\r\n    <Content Include=\"Images\\AppList.scale-200_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\AppList.scale-400.png\" />\r\n    <Content Include=\"Images\\AppList.scale-400_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-16.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-16_altform-lightunplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-16_altform-unplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-20.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-20_altform-lightunplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-20_altform-unplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-24.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-24_altform-lightunplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-24_altform-unplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-256.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-256_altform-lightunplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-256_altform-unplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-30.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-30_altform-lightunplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-30_altform-unplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-32.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-32_altform-lightunplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-32_altform-unplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-36.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-36_altform-lightunplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-36_altform-unplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-40.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-40_altform-lightunplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-40_altform-unplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-48.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-48_altform-lightunplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-48_altform-unplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-56.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-56_altform-lightunplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-56_altform-unplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-60.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-60_altform-lightunplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-60_altform-unplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-64.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-64_altform-lightunplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-64_altform-unplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-72.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-72_altform-lightunplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-72_altform-unplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-80.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-80_altform-lightunplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-80_altform-unplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-96.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-96_altform-lightunplated.png\" />\r\n    <Content Include=\"Images\\AppList.targetsize-96_altform-unplated.png\" />\r\n    <Content Include=\"Images\\LargeTile.scale-100.png\" />\r\n    <Content Include=\"Images\\LargeTile.scale-100_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\LargeTile.scale-125.png\" />\r\n    <Content Include=\"Images\\LargeTile.scale-125_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\LargeTile.scale-150.png\" />\r\n    <Content Include=\"Images\\LargeTile.scale-150_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\LargeTile.scale-200.png\" />\r\n    <Content Include=\"Images\\LargeTile.scale-200_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\LargeTile.scale-400.png\" />\r\n    <Content Include=\"Images\\LargeTile.scale-400_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\MedTile.scale-100.png\" />\r\n    <Content Include=\"Images\\MedTile.scale-100_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\MedTile.scale-125.png\" />\r\n    <Content Include=\"Images\\MedTile.scale-125_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\MedTile.scale-150.png\" />\r\n    <Content Include=\"Images\\MedTile.scale-150_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\MedTile.scale-200.png\" />\r\n    <Content Include=\"Images\\MedTile.scale-200_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\MedTile.scale-400.png\" />\r\n    <Content Include=\"Images\\MedTile.scale-400_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\SmallTile.scale-100.png\" />\r\n    <Content Include=\"Images\\SmallTile.scale-100_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\SmallTile.scale-125.png\" />\r\n    <Content Include=\"Images\\SmallTile.scale-125_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\SmallTile.scale-150.png\" />\r\n    <Content Include=\"Images\\SmallTile.scale-150_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\SmallTile.scale-200.png\" />\r\n    <Content Include=\"Images\\SmallTile.scale-200_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\SmallTile.scale-400.png\" />\r\n    <Content Include=\"Images\\SmallTile.scale-400_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\SplashScreen.scale-100.png\" />\r\n    <Content Include=\"Images\\SplashScreen.scale-100_altform-colorful_theme-dark.png\" />\r\n    <Content Include=\"Images\\SplashScreen.scale-100_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\SplashScreen.scale-125.png\" />\r\n    <Content Include=\"Images\\SplashScreen.scale-125_altform-colorful_theme-dark.png\" />\r\n    <Content Include=\"Images\\SplashScreen.scale-125_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\SplashScreen.scale-150.png\" />\r\n    <Content Include=\"Images\\SplashScreen.scale-150_altform-colorful_theme-dark.png\" />\r\n    <Content Include=\"Images\\SplashScreen.scale-150_altform-colorful_theme-light.png\" />\r\n    <Content Include=\"Images\\SplashScreen.scale-200.png\" />\r\n    <None Include=\"Execute-AppxRecipe.ps1\" />\r\n    <None Include=\"Register-WingetdevAutoComplete.ps1\" />\r\n    <PRIResource Include=\"Shared\\Strings\\en-us\\winget.resw\">\r\n      <SubType>Designer</SubType>\r\n    </PRIResource>\r\n    <PRIResource Include=\"shared\\strings\\de-DE\\winget.resw\" Condition=\"Exists('shared\\strings\\de-DE\\winget.resw')\" />\r\n    <PRIResource Include=\"shared\\strings\\es-ES\\winget.resw\" Condition=\"Exists('shared\\strings\\es-ES\\winget.resw')\" />\r\n    <PRIResource Include=\"shared\\strings\\fr-FR\\winget.resw\" Condition=\"Exists('shared\\strings\\fr-FR\\winget.resw')\" />\r\n    <PRIResource Include=\"shared\\strings\\it-IT\\winget.resw\" Condition=\"Exists('shared\\strings\\it-IT\\winget.resw')\" />\r\n    <PRIResource Include=\"shared\\strings\\ja-JP\\winget.resw\" Condition=\"Exists('shared\\strings\\ja-JP\\winget.resw')\" />\r\n    <PRIResource Include=\"shared\\strings\\ko-KR\\winget.resw\" Condition=\"Exists('shared\\strings\\ko-KR\\winget.resw')\" />\r\n    <PRIResource Include=\"shared\\strings\\pt-BR\\winget.resw\" Condition=\"Exists('shared\\strings\\pt-BR\\winget.resw')\" />\r\n    <PRIResource Include=\"shared\\strings\\ru-RU\\winget.resw\" Condition=\"Exists('shared\\strings\\ru-RU\\winget.resw')\" />\r\n    <PRIResource Include=\"shared\\strings\\zh-CN\\winget.resw\" Condition=\"Exists('shared\\strings\\zh-CN\\winget.resw')\" />\r\n    <PRIResource Include=\"shared\\strings\\zh-TW\\winget.resw\" Condition=\"Exists('shared\\strings\\zh-TW\\winget.resw')\" />\r\n    <PRIResource Include=\"Shared\\Strings\\en-us\\Resources.resw\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\AppInstallerCLI\\AppInstallerCLI.vcxproj\" />\r\n    <ProjectReference Include=\"..\\WinGetServer\\WinGetServer.vcxproj\" />\r\n  </ItemGroup>\r\n  <Import Project=\"$(WapProjPath)\\Microsoft.DesktopBridge.targets\" />\r\n  <PropertyGroup Label=\"Configuration\">\r\n    <PostBuildEvent>\r\n      copy \"$(TargetDir)\\resources.pri\" \"$(ProjectDir)\\..\\$(Platform)\\$(Configuration)\\AppInstallerCLI\\resources.pri\"\r\n      copy \"$(TargetDir)\\resources.pri\" \"$(TargetDir)\\AppInstallerCLI\\resources.pri\"\r\n    </PostBuildEvent>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Platform)'=='ARM64'\">\r\n    <ConfigServerRid>win-arm64</ConfigServerRid>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Platform)'=='x64'\">\r\n    <ConfigServerRid>win-x64</ConfigServerRid>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Platform)'=='x86'\">\r\n    <ConfigServerRid>win-x86</ConfigServerRid>\r\n  </PropertyGroup>\r\n  <Target Name=\"WinGetGenerateDSCv3Manifests\" BeforeTargets=\"WinGetIncludeAdditionalFilesInPackage\">\r\n    <Message Importance=\"normal\" Text=\"Generating DSCv3 manifests...\" />\r\n    <Copy SourceFiles=\"$(SolutionDir)\\$(PlatformTarget)\\$(Configuration)\\WindowsPackageManager\\WindowsPackageManager.dll\" DestinationFolder=\"$(SolutionDir)\\$(PlatformTarget)\\$(Configuration)\\AppInstallerCLI\" SkipUnchangedFiles=\"true\" />\r\n    <Exec Command=\"$(SolutionDir)\\$(PlatformTarget)\\$(Configuration)\\AppInstallerCLI\\winget.exe dscv3 --manifest -o $(SolutionDir)\\$(PlatformTarget)\\$(Configuration)\\AppInstallerCLI\\DSCv3Manifests\" />\r\n    <Message Importance=\"normal\" Text=\"DSCv3 manifests generated.\" />\r\n  </Target>\r\n  <Target Name=\"WinGetIncludeAdditionalFilesInPackage\" AfterTargets=\"_ComputeAppxPackagePayload\">\r\n    <PropertyGroup>\r\n      <WinGetAdditionalPackageFileRoot>$(SolutionDir)</WinGetAdditionalPackageFileRoot>\r\n      <WinGetDotNetDirectoryName>DotNet</WinGetDotNetDirectoryName>\r\n    </PropertyGroup>\r\n    <Message Importance=\"normal\" Text=\"WinGetAdditionalPackageFileRoot = $(WinGetAdditionalPackageFileRoot)\" />\r\n    <ItemGroup>\r\n      <WinGetAdditionalPackageFile Include=\"$(WinGetAdditionalPackageFileRoot)\\$(PlatformTarget)\\$(Configuration)\\WindowsPackageManager\\WindowsPackageManager.dll\">\r\n        <PackagePath>WindowsPackageManager.dll</PackagePath>\r\n      </WinGetAdditionalPackageFile>\r\n      <WinGetAdditionalPackageFile Include=\"$(WinGetAdditionalPackageFileRoot)\\$(PlatformTarget)\\$(Configuration)\\Microsoft.Management.Deployment\\Microsoft.Management.Deployment.winmd\">\r\n        <PackagePath>Microsoft.Management.Deployment.winmd</PackagePath>\r\n      </WinGetAdditionalPackageFile>\r\n      <WinGetAdditionalPackageFile Include=\"$(WinGetAdditionalPackageFileRoot)\\$(PlatformTarget)\\$(Configuration)\\Microsoft.Management.Configuration\\Microsoft.Management.Configuration.dll\">\r\n        <PackagePath>Microsoft.Management.Configuration.dll</PackagePath>\r\n      </WinGetAdditionalPackageFile>\r\n      <WinGetAdditionalPackageFile Include=\"$(WinGetAdditionalPackageFileRoot)\\$(PlatformTarget)\\$(Configuration)\\Microsoft.Management.Configuration\\Microsoft.Management.Configuration.winmd\">\r\n        <PackagePath>Microsoft.Management.Configuration.winmd</PackagePath>\r\n      </WinGetAdditionalPackageFile>\r\n      <WinGetAdditionalPackageFile Include=\"$(WinGetAdditionalPackageFileRoot)\\$(PlatformTarget)\\$(Configuration)\\ConfigurationRemotingServer\\net8.0-windows10.0.26100.0\\$(ConfigServerRid)\\**\\*\">\r\n        <PackagePath>$(WinGetDotNetDirectoryName)</PackagePath>\r\n        <Recurse>true</Recurse>\r\n      </WinGetAdditionalPackageFile>\r\n      <WinGetAdditionalPackageFile Include=\"$(WinGetAdditionalPackageFileRoot)\\$(PlatformTarget)\\$(Configuration)\\Microsoft.Management.Deployment.OutOfProc\\Microsoft.Management.Deployment.OutOfProc.dll\">\r\n        <PackagePath>$(WinGetDotNetDirectoryName)\\Microsoft.Management.Deployment.dll</PackagePath>\r\n      </WinGetAdditionalPackageFile>\r\n      <WinGetAdditionalPackageFile Include=\"$(SolutionDir)\\PowerShell\\ExternalModules\\**\\*\">\r\n        <PackagePath>ExternalModules</PackagePath>\r\n        <Recurse>true</Recurse>\r\n      </WinGetAdditionalPackageFile>\r\n      <WinGetAdditionalPackageFile Include=\"$(SolutionDir)\\$(PlatformTarget)\\$(Configuration)\\AppInstallerCLI\\DSCv3Manifests\\*\">\r\n        <PackagePath>.</PackagePath>\r\n        <Recurse>true</Recurse>\r\n      </WinGetAdditionalPackageFile>\r\n    </ItemGroup>\r\n    <Error Condition=\"!Exists('%(WinGetAdditionalPackageFile.Identity)')\" Text=\"%(WinGetAdditionalPackageFile.Identity) was not found\" />\r\n    <!-- Single (non-recursive) file items -->\r\n    <Message Importance=\"normal\" Condition=\"'%(WinGetAdditionalPackageFile.Recurse)'!='true' AND Exists('%(WinGetAdditionalPackageFile.Identity)')\" Text=\"%(WinGetAdditionalPackageFile.Identity) -&gt; %(WinGetAdditionalPackageFile.PackagePath)\" />\r\n    <ItemGroup>\r\n      <AppxPackagePayload Condition=\"'%(WinGetAdditionalPackageFile.Recurse)'!='true'\" Include=\"%(WinGetAdditionalPackageFile.Identity)\" KeepDuplicates=\"false\">\r\n        <TargetPath>%(WinGetAdditionalPackageFile.PackagePath)</TargetPath>\r\n      </AppxPackagePayload>\r\n    </ItemGroup>\r\n    <!-- Recursive file items -->\r\n    <Message Importance=\"normal\" Condition=\"'%(WinGetAdditionalPackageFile.Recurse)'=='true' AND Exists('%(WinGetAdditionalPackageFile.Identity)')\" Text=\"%(WinGetAdditionalPackageFile.Identity) -&gt; %(WinGetAdditionalPackageFile.PackagePath)\\%(WinGetAdditionalPackageFile.RecursiveDir)%(WinGetAdditionalPackageFile.Filename)%(WinGetAdditionalPackageFile.Extension)\" />\r\n    <ItemGroup>\r\n      <AppxPackagePayload Condition=\"'%(WinGetAdditionalPackageFile.Recurse)'=='true'\" Include=\"%(WinGetAdditionalPackageFile.Identity)\" KeepDuplicates=\"false\">\r\n        <TargetPath>%(WinGetAdditionalPackageFile.PackagePath)\\%(WinGetAdditionalPackageFile.RecursiveDir)%(WinGetAdditionalPackageFile.Filename)%(WinGetAdditionalPackageFile.Extension)</TargetPath>\r\n      </AppxPackagePayload>\r\n    </ItemGroup>\r\n  </Target>\r\n</Project>"
  },
  {
    "path": "src/AppInstallerCLIPackage/Execute-AppxRecipe.ps1",
    "content": "# Copyright (c) Microsoft Corporation.\r\n# Licensed under the MIT License.\r\n[CmdletBinding()]\r\nparam(\r\n    [Parameter(Mandatory=$true,Position=0)]\r\n    [string]$AppxRecipePath,\r\n\r\n    [string]$LayoutPath,\r\n\r\n    [switch]$Force\r\n)\r\n\r\n[xml]$Local:recipe = Get-Content $AppxRecipePath\r\n\r\nif ([System.String]::IsNullOrEmpty($LayoutPath))\r\n{\r\n    $LayoutPath = $Local:recipe.Project.PropertyGroup.LayoutDir\r\n}\r\n\r\n$Local:namespace = @{\r\n    ns = \"http://schemas.microsoft.com/developer/msbuild/2003\"\r\n}\r\n\r\n$Local:manifestElement = Select-Xml -Xml $Local:recipe -Namespace $Local:namespace -XPath \"//ns:AppXManifest\" | Select-Object -ExpandProperty Node\r\n$Local:packageFileElements = Select-Xml -Xml $Local:recipe -Namespace $Local:namespace -XPath \"//ns:AppxPackagedFile\" | Select-Object -ExpandProperty Node\r\n\r\n$Local:allItems = $Local:packageFileElements + $Local:manifestElement\r\n\r\n$Local:progressActivity = \"Copying files to $LayoutPath\"\r\nWrite-Progress -Activity $Local:progressActivity\r\n\r\nif ($Force) {\r\n    $null = New-Item -Path $LayoutPath -ItemType Directory -Force\r\n} else {\r\n    New-Item -Path $LayoutPath -ItemType Directory -ErrorAction Inquire\r\n}\r\n\r\n[Int32]$Local:filesCopied = 0\r\n\r\n$Local:allItems | ForEach-Object -Process {\r\n    $Local:sourcePath = $_.Include\r\n    $Local:destinationPath = Join-Path $LayoutPath $_.PackagePath\r\n    Write-Verbose \"$Local:sourcePath => $Local:destinationPath\"\r\n    $null = New-Item -Path ([System.IO.Path]::GetDirectoryName($Local:destinationPath)) -ItemType Directory -Force\r\n    Copy-Item -Path $Local:sourcePath -Destination $Local:destinationPath\r\n    $Local:filesCopied += 1\r\n    Write-Progress -Activity $Local:progressActivity -PercentComplete (($Local:filesCopied * 100) / $Local:allItems.Count)\r\n}\r\n\r\nWrite-Progress -Activity $Local:progressActivity -Completed\r\n"
  },
  {
    "path": "src/AppInstallerCLIPackage/Package.appxmanifest",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Package \r\n  xmlns=\"http://schemas.microsoft.com/appx/manifest/foundation/windows10\"\r\n  xmlns:uap=\"http://schemas.microsoft.com/appx/manifest/uap/windows10\"\r\n  xmlns:uap3=\"http://schemas.microsoft.com/appx/manifest/uap/windows10/3\"\r\n  xmlns:uap5=\"http://schemas.microsoft.com/appx/manifest/uap/windows10/5\"\r\n  xmlns:rescap=\"http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities\"\r\n  xmlns:com=\"http://schemas.microsoft.com/appx/manifest/com/windows10\"\r\n  xmlns:desktop6=\"http://schemas.microsoft.com/appx/manifest/desktop/windows10/6\"\r\n  IgnorableNamespaces=\"uap uap3 uap5 rescap desktop6\">\r\n  <Identity Name=\"WinGetDevCLI\" Publisher=\"CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US\" Version=\"0.0.2.0\" />\r\n  <Properties>\r\n    <DisplayName>WinGet Dev CLI</DisplayName>\r\n    <PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>\r\n    <Logo>Images\\StoreLogo.png</Logo>\r\n    <desktop6:FileSystemWriteVirtualization>disabled</desktop6:FileSystemWriteVirtualization>\r\n    <desktop6:RegistryWriteVirtualization>disabled</desktop6:RegistryWriteVirtualization>\r\n  </Properties>\r\n  <Dependencies>\r\n    <!-- Minimum supported version is 1809 (October 2018 Update, aka RS5) -->\r\n    <TargetDeviceFamily Name=\"Windows.Desktop\" MinVersion=\"10.0.17763.0\" MaxVersionTested=\"10.0.19033.0\" />\r\n  </Dependencies>\r\n  <Resources>\r\n    <Resource Language=\"x-generate\" />\r\n  </Resources>\r\n  <Applications>\r\n    <Application Id=\"WinGetDev\" Executable=\"AppInstallerCLI\\winget.exe\" EntryPoint=\"Windows.FullTrustApplication\">\r\n      <uap:VisualElements DisplayName=\"WinGet Dev Client\" Square150x150Logo=\"Images\\MedTile.png\" Square44x44Logo=\"Images\\AppList.png\" Description=\"The WinGet dev client.\" BackgroundColor=\"#0078d7\" AppListEntry=\"none\" >\r\n        <uap:DefaultTile/>\r\n      </uap:VisualElements >\r\n      <Extensions>\r\n        <uap3:Extension Category=\"windows.appExtensionHost\">\r\n          <uap3:AppExtensionHost>\r\n            <uap3:Name>com.microsoft.winget.source</uap3:Name>\r\n          </uap3:AppExtensionHost>\r\n        </uap3:Extension>\r\n        <uap5:Extension Category=\"windows.appExecutionAlias\">\r\n          <uap5:AppExecutionAlias>\r\n            <uap5:ExecutionAlias Alias=\"WinGetDev.exe\" />\r\n          </uap5:AppExecutionAlias>\r\n        </uap5:Extension>\r\n        <uap3:Extension Category=\"windows.fileTypeAssociation\">\r\n          <uap3:FileTypeAssociation Name=\"configuration\" Parameters=\"configure &quot;%1&quot; --wait\">\r\n            <uap:SupportedFileTypes>\r\n              <uap:FileType>.wingetdev</uap:FileType>\r\n            </uap:SupportedFileTypes>\r\n            <uap:DisplayName>WinGetDev configuration file</uap:DisplayName>\r\n          </uap3:FileTypeAssociation>\r\n        </uap3:Extension>\r\n      </Extensions>\r\n    </Application>\r\n    <Application Id=\"WinGetComServer\" Executable=\"WinGetServer\\WindowsPackageManagerServer.exe\" EntryPoint=\"Windows.FullTrustApplication\">\r\n      <uap:VisualElements DisplayName=\"WinGet Dev COM Server\" Square150x150Logo=\"Images\\MedTile.png\" Square44x44Logo=\"Images\\AppList.png\" Description=\"The WinGet COM server.\" BackgroundColor=\"#0078d7\" AppListEntry=\"none\" >\r\n        <uap:DefaultTile/>\r\n      </uap:VisualElements >\r\n      <Extensions>\r\n        <uap5:Extension Category=\"windows.appExecutionAlias\">\r\n          <uap5:AppExecutionAlias>\r\n            <uap5:ExecutionAlias Alias=\"WindowsPackageManagerServerDev.exe\" />\r\n          </uap5:AppExecutionAlias>\r\n        </uap5:Extension>\r\n        <com:Extension Category=\"windows.comServer\">\r\n          <com:ComServer>\r\n            <com:ExeServer Executable=\"WinGetServer\\WindowsPackageManagerServer.exe\" DisplayName=\"Windows Package Manager Server\" LaunchAndActivationPermission=\"O:SYG:SYD:(A;;11;;;IU)(A;;11;;;SY)(A;;11;;;BA)(A;;11;;;AC)S:P(ML;;NX;;;S-1-16-8192)\">\r\n              <com:Class Id =\"74CB3139-B7C5-4B9E-9388-E6616DEA288C\" DisplayName=\"PackageManager Server\">\r\n              </com:Class>\r\n              <com:Class Id =\"1BD8FF3A-EC50-4F69-AEEE-DF4C9D3BAA96\" DisplayName=\"FindPackagesOptions Server\">\r\n              </com:Class>\r\n              <com:Class Id =\"EE160901-B317-4EA7-9CC6-5355C6D7D8A7\" DisplayName=\"CreateCompositePackageCatalogOptions Server\">\r\n              </com:Class>\r\n              <com:Class Id =\"44FE0580-62F7-44D4-9E91-AA9614AB3E86\" DisplayName=\"InstallOptions Server\">\r\n              </com:Class>\r\n              <com:Class Id =\"3F85B9F4-487A-4C48-9035-2903F8A6D9E8\" DisplayName=\"PackageMatchFilter Server\">\r\n              </com:Class>\r\n              <com:Class Id =\"AA2A5C04-1AD9-46C4-B74F-6B334AD7EB8C\" DisplayName=\"UninstallOptions Server\">\r\n              </com:Class>\r\n              <com:Class Id =\"8EF324ED-367C-4880-83E5-BB2ABD0B72F6\" DisplayName=\"DownloadOptions Server\">\r\n              </com:Class>\r\n              <com:Class Id =\"6484A61D-50FA-41F0-B71E-F4370C6EB37C\" DisplayName=\"AuthenticationArguments Server\">\r\n              </com:Class>\r\n              <com:Class Id =\"E62BB1E7-C7B2-4AEC-9E28-FB649B30FF03\" DisplayName=\"RepairOptions Server\">\r\n              </com:Class>\r\n              <com:Class Id=\"D58C7E4C-70E6-476C-A5D4-80341ED80252\" DisplayName=\"AddPackageCatalogOptions Server\">\r\n              </com:Class>\r\n              <com:Class Id=\"87A96609-1A39-4955-BE72-7174E147B7DC\" DisplayName=\"RemovePackageCatalogOptions Server\">\r\n              </com:Class>\r\n              <com:Class Id=\"29B19238-81AD-4A8E-A2FC-ADF17C38CAEB\" DisplayName=\"EditPackageCatalogOptions Server\">\r\n              </com:Class>\r\n            </com:ExeServer>\r\n          </com:ComServer>\r\n        </com:Extension>\r\n        <com:Extension Category=\"windows.comServer\">\r\n          <com:ComServer>\r\n            <com:ExeServer Executable=\"WinGetServer\\WindowsPackageManagerServer.exe\" DisplayName=\"Windows Package Manager Configuration Server\">\r\n              <com:Class Id =\"C9ED7917-66AB-4E31-A92A-F65F18EF7933\" DisplayName=\"Configuration Statics Server\">\r\n              </com:Class>\r\n            </com:ExeServer>\r\n          </com:ComServer>\r\n        </com:Extension>\r\n      </Extensions>\r\n    </Application>\r\n    <Application Id=\"WinGetMCPServer\" Executable=\"DotNet\\WinGetMCPServer.exe\" EntryPoint=\"Windows.FullTrustApplication\">\r\n      <uap:VisualElements DisplayName=\"WinGet Dev MCP Server\" Square150x150Logo=\"Images\\MedTile.png\" Square44x44Logo=\"Images\\AppList.png\" Description=\"The WinGet MCP server.\" BackgroundColor=\"#0078d7\" AppListEntry=\"none\" >\r\n        <uap:DefaultTile/>\r\n      </uap:VisualElements >\r\n      <Extensions>\r\n        <uap5:Extension Category=\"windows.appExecutionAlias\">\r\n          <uap5:AppExecutionAlias>\r\n            <uap5:ExecutionAlias Alias=\"WindowsPackageManagerMCPServerDev.exe\" />\r\n          </uap5:AppExecutionAlias>\r\n        </uap5:Extension>\r\n      </Extensions>\r\n    </Application>\r\n  </Applications>\r\n  <Extensions>\r\n    <Extension Category=\"windows.activatableClass.proxyStub\">\r\n      <ProxyStub ClassId=\"00000355-0000-0000-C000-000000000046\">\r\n        <Path>Microsoft.Management.Configuration.winmd</Path>\r\n        <Interface Name=\"Windows.Foundation.Collections.IIterable`1&lt;Microsoft.Management.Configuration.ConfigurationUnit&gt;\" InterfaceId=\"0BB82BF3-EC6D-55DB-B399-08813A4EB204\" />\r\n        <Interface Name=\"Windows.Foundation.Collections.IIterable`1&lt;Microsoft.Management.Configuration.ConfigurationSet&gt;\" InterfaceId=\"6D54B059-3766-5DC9-81E3-83587EB3A58E\" />\r\n        <Interface Name=\"Windows.Foundation.Collections.IIterable`1&lt;Microsoft.Management.Configuration.ConfigurationConflict&gt;\" InterfaceId=\"41A1F29F-518B-5776-BCF2-E42FC9DDE32A\" />\r\n        <Interface Name=\"Windows.Foundation.Collections.IIterable`1&lt;Microsoft.Management.Configuration.ConfigurationParameter&gt;\" InterfaceId=\"4257159F-6172-5202-A45D-4C4303A6C2C2\" />\r\n        <Interface Name=\"Windows.Foundation.Collections.IIterable`1&lt;Microsoft.Management.Configuration.IConfigurationUnitSettingDetails&gt;\" InterfaceId=\"FC91924A-215F-50A7-9AEE-254B4D7A50CB\" />\r\n        <Interface Name=\"Windows.Foundation.Collections.IIterable`1&lt;Microsoft.Management.Configuration.ConfigurationConflictSetting&gt;\" InterfaceId=\"EB1E5A3C-A444-5394-B7B3-F1593937E31E\" />\r\n        <Interface Name=\"Windows.Foundation.Collections.IIterable`1&lt;Microsoft.Management.Configuration.GetConfigurationUnitDetailsResult&gt;\" InterfaceId=\"3A034399-0F2B-51C2-A9C5-4BC6E9940068\" />\r\n        <Interface Name=\"Windows.Foundation.Collections.IIterable`1&lt;Microsoft.Management.Configuration.ApplyConfigurationUnitResult&gt;\" InterfaceId=\"0E2334B9-8431-5A9D-B3AA-62D4FB5B5749\" />\r\n        <Interface Name=\"Windows.Foundation.Collections.IIterable`1&lt;Microsoft.Management.Configuration.TestConfigurationUnitResult&gt;\" InterfaceId=\"73848262-86D4-5FFC-8353-8408C4E649DE\" />\r\n        <Interface Name=\"Windows.Foundation.Collections.IIterable`1&lt;Microsoft.Management.Configuration.IApplyGroupMemberSettingsResult&gt;\" InterfaceId=\"5086070C-F468-5B00-8352-50FB420BA8B0\" />\r\n        <Interface Name=\"Windows.Foundation.Collections.IIterable`1&lt;Microsoft.Management.Configuration.ITestSettingsResult&gt;\" InterfaceId=\"2D28E6AA-7036-5D78-9B58-9456F1E332FE\" />\r\n        <Interface Name=\"Windows.Foundation.Collections.IIterable`1&lt;Microsoft.Management.Configuration.ConfigurationEnvironment&gt;\" InterfaceId=\"47B18106-976B-5532-8E81-F58D304DFA43\" />\r\n        <Interface Name=\"Windows.Foundation.Collections.IIterable`1&lt;Microsoft.Management.Configuration.IConfigurationUnitProcessorDetails&gt;\" InterfaceId=\"055865E9-B633-5AD6-9C8F-55DFCD668E74\" />\r\n        <Interface Name=\"Microsoft.Management.Configuration.IConfigurationUnitProcessorDetails2\" InterfaceId=\"E89623ED-76E2-5145-B920-D09659554E35\" />\r\n        <Interface Name=\"Microsoft.Management.Configuration.IConfigurationUnitProcessorDetails3\" InterfaceId=\"81511CCA-632B-560A-AFE8-D55555EB9937\" />\r\n        <Interface Name=\"Microsoft.Management.Configuration.IGetAllSettingsConfigurationUnitProcessor\" InterfaceId=\"72EB8304-D8D3-57D4-9940-7C1C4AD8C40C\" />\r\n        <Interface Name=\"Microsoft.Management.Configuration.IGetAllUnitsConfigurationUnitProcessor\" InterfaceId=\"D5CB3357-8AD6-5A3C-8695-057C01867D5F\" />\r\n        <Interface Name=\"Microsoft.Management.Configuration.IFindUnitProcessorsSetProcessor\" InterfaceId=\"620628DF-A5DE-591A-B738-FD8370B4E95C\" />\r\n        <Interface Name=\"Microsoft.Management.Configuration.IConfigurationStatics2\" InterfaceId=\"540BE073-F2EF-5375-83AA-8E23086B0669\" />\r\n        <Interface Name=\"Microsoft.Management.Configuration.IConfigurationStatics3\" InterfaceId=\"C84E137B-90E5-5F63-931D-F0497BBCA847\" />\r\n        <Interface Name=\"Microsoft.Management.Configuration.SetProcessorFactory.IPwshConfigurationSetProcessorFactoryProperties\" InterfaceId=\"2C298A30-BD3B-5D00-BCD1-2EB633AB7E3B\" />\r\n      </ProxyStub>\r\n    </Extension>\r\n    <Extension Category=\"windows.activatableClass.inProcessServer\">\r\n      <InProcessServer>\r\n        <Path>Microsoft.Management.Configuration.dll</Path>\r\n        <ActivatableClass ActivatableClassId=\"Microsoft.Management.Configuration.ConfigurationUnit\" ThreadingModel=\"both\" />\r\n        <ActivatableClass ActivatableClassId=\"Microsoft.Management.Configuration.ConfigurationSet\" ThreadingModel=\"both\" />\r\n        <ActivatableClass ActivatableClassId=\"Microsoft.Management.Configuration.ConfigurationProcessor\" ThreadingModel=\"both\" />\r\n        <ActivatableClass ActivatableClassId=\"Microsoft.Management.Configuration.ConfigurationParameter\" ThreadingModel=\"both\" />\r\n        <ActivatableClass ActivatableClassId=\"Microsoft.Management.Configuration.FindUnitProcessorsOptions\" ThreadingModel=\"both\" />\r\n      </InProcessServer>\r\n    </Extension>\r\n  </Extensions>\r\n  <Capabilities>\r\n    <rescap:Capability Name=\"runFullTrust\" />\r\n    <rescap:Capability Name=\"packageManagement\" />\r\n    <rescap:Capability Name=\"unvirtualizedResources\" />\r\n  </Capabilities>\r\n</Package>\r\n"
  },
  {
    "path": "src/AppInstallerCLIPackage/Register-WingetdevAutoComplete.ps1",
    "content": "Register-ArgumentCompleter -Native -CommandName wingetdev -ScriptBlock {\r\n    param($wordToComplete, $commandAst, $cursorPosition)\r\n        [Console]::InputEncoding = [Console]::OutputEncoding = $OutputEncoding = [System.Text.Utf8Encoding]::new()\r\n        $Local:word = $wordToComplete.Replace('\"', '\"\"')\r\n        $Local:ast = $commandAst.ToString().Replace('\"', '\"\"')\r\n        wingetdev complete --word=\"$Local:word\" --commandline \"$Local:ast\" --position $cursorPosition | ForEach-Object {\r\n            [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)\r\n        }\r\n}"
  },
  {
    "path": "src/AppInstallerCLIPackage/Shared/Strings/en-us/Resources.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<root>\r\n  <!-- \r\n    Microsoft ResX Schema \r\n    \r\n    Version 2.0\r\n    \r\n    The primary goals of this format is to allow a simple XML format \r\n    that is mostly human readable. The generation and parsing of the \r\n    various data types are done through the TypeConverter classes \r\n    associated with the data types.\r\n    \r\n    Example:\r\n    \r\n    ... ado.net/XML headers & schema ...\r\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\r\n    <resheader name=\"version\">2.0</resheader>\r\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\r\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\r\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\r\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\r\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\r\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\r\n    </data>\r\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\r\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\r\n        <comment>This is a comment</comment>\r\n    </data>\r\n                \r\n    There are any number of \"resheader\" rows that contain simple \r\n    name/value pairs.\r\n    \r\n    Each data row contains a name, and value. The row also contains a \r\n    type or mimetype. Type corresponds to a .NET class that support \r\n    text/value conversion through the TypeConverter architecture. \r\n    Classes that don't support this are serialized and stored with the \r\n    mimetype set.\r\n    \r\n    The mimetype is used for serialized objects, and tells the \r\n    ResXResourceReader how to depersist the object. This is currently not \r\n    extensible. For a given mimetype the value must be set accordingly:\r\n    \r\n    Note - application/x-microsoft.net.object.binary.base64 is the format \r\n    that the ResXResourceWriter will generate, however the reader can \r\n    read any of the formats listed below.\r\n    \r\n    mimetype: application/x-microsoft.net.object.binary.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\r\n            : and then encoded with base64 encoding.\r\n    \r\n    mimetype: application/x-microsoft.net.object.soap.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\r\n            : and then encoded with base64 encoding.\r\n\r\n    mimetype: application/x-microsoft.net.object.bytearray.base64\r\n    value   : The object must be serialized into a byte array \r\n            : using a System.ComponentModel.TypeConverter\r\n            : and then encoded with base64 encoding.\r\n    -->\r\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\r\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\r\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\r\n      <xsd:complexType>\r\n        <xsd:choice maxOccurs=\"unbounded\">\r\n          <xsd:element name=\"metadata\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"assembly\">\r\n            <xsd:complexType>\r\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"data\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"resheader\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n        </xsd:choice>\r\n      </xsd:complexType>\r\n    </xsd:element>\r\n  </xsd:schema>\r\n  <resheader name=\"resmimetype\">\r\n    <value>text/microsoft-resx</value>\r\n  </resheader>\r\n  <resheader name=\"version\">\r\n    <value>2.0</value>\r\n  </resheader>\r\n  <resheader name=\"reader\">\r\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n  <resheader name=\"writer\">\r\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n  <data name=\"DoNotAddStringsHere\" xml:space=\"preserve\">\r\n    <value>Not Localized</value>\r\n    <comment>{Locked} This file is required to establish the basic expected subresource in the resource map. It is not used to facilitate localization with other projects.</comment>\r\n  </data>\r\n</root>"
  },
  {
    "path": "src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<root>\r\n  <!-- \r\n    Microsoft ResX Schema \r\n    \r\n    Version 2.0\r\n    \r\n    The primary goals of this format is to allow a simple XML format \r\n    that is mostly human readable. The generation and parsing of the \r\n    various data types are done through the TypeConverter classes \r\n    associated with the data types.\r\n    \r\n    Example:\r\n    \r\n    ... ado.net/XML headers & schema ...\r\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\r\n    <resheader name=\"version\">2.0</resheader>\r\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\r\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\r\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\r\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\r\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\r\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\r\n    </data>\r\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\r\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\r\n        <comment>This is a comment</comment>\r\n    </data>\r\n                \r\n    There are any number of \"resheader\" rows that contain simple \r\n    name/value pairs.\r\n    \r\n    Each data row contains a name, and value. The row also contains a \r\n    type or mimetype. Type corresponds to a .NET class that support \r\n    text/value conversion through the TypeConverter architecture. \r\n    Classes that don't support this are serialized and stored with the \r\n    mimetype set.\r\n    \r\n    The mimetype is used for serialized objects, and tells the \r\n    ResXResourceReader how to depersist the object. This is currently not \r\n    extensible. For a given mimetype the value must be set accordingly:\r\n    \r\n    Note - application/x-microsoft.net.object.binary.base64 is the format \r\n    that the ResXResourceWriter will generate, however the reader can \r\n    read any of the formats listed below.\r\n    \r\n    mimetype: application/x-microsoft.net.object.binary.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\r\n            : and then encoded with base64 encoding.\r\n    \r\n    mimetype: application/x-microsoft.net.object.soap.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\r\n            : and then encoded with base64 encoding.\r\n\r\n    mimetype: application/x-microsoft.net.object.bytearray.base64\r\n    value   : The object must be serialized into a byte array \r\n            : using a System.ComponentModel.TypeConverter\r\n            : and then encoded with base64 encoding.\r\n    -->\r\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\r\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\r\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\r\n      <xsd:complexType>\r\n        <xsd:choice maxOccurs=\"unbounded\">\r\n          <xsd:element name=\"metadata\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"assembly\">\r\n            <xsd:complexType>\r\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"data\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"resheader\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n        </xsd:choice>\r\n      </xsd:complexType>\r\n    </xsd:element>\r\n  </xsd:schema>\r\n  <resheader name=\"resmimetype\">\r\n    <value>text/microsoft-resx</value>\r\n  </resheader>\r\n  <resheader name=\"version\">\r\n    <value>2.0</value>\r\n  </resheader>\r\n  <resheader name=\"reader\">\r\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n  <resheader name=\"writer\">\r\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n  <data name=\"AdjoinedNotFlagError\" xml:space=\"preserve\">\r\n    <value>Adjoined alias is not a flag: '{0}'</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an adjoined alias that is not a flag argument. {0} is a placeholder replaced by the user input argument (e.g. '-ab').</comment>\r\n  </data>\r\n  <data name=\"AdjoinedNotFoundError\" xml:space=\"preserve\">\r\n    <value>Adjoined flag alias not found: '{0}'</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an adjoined flag alias argument that was not found. {0} is a placeholder replaced by the user input argument (e.g. '-ab').</comment>\r\n  </data>\r\n  <data name=\"AvailableArguments\" xml:space=\"preserve\">\r\n    <value>The following arguments are available:</value>\r\n    <comment>Message displayed to inform the user about the available command line arguments.</comment>\r\n  </data>\r\n  <data name=\"AvailableCommandAliases\" xml:space=\"preserve\">\r\n    <value>The following command aliases are available:</value>\r\n    <comment>Message displayed to inform the user about the available command line alias arguments.</comment>\r\n  </data>\r\n  <data name=\"AvailableCommands\" xml:space=\"preserve\">\r\n    <value>The following commands are available:</value>\r\n    <comment>Title displayed to inform the user about the available commands.</comment>\r\n  </data>\r\n  <data name=\"AvailableHeader\" xml:space=\"preserve\">\r\n    <value>Available</value>\r\n    <comment>As in \"a new version is available to upgrade to\".</comment>\r\n  </data>\r\n  <data name=\"AvailableOptions\" xml:space=\"preserve\">\r\n    <value>The following options are available:</value>\r\n    <comment>Message displayed to inform the user about the available options.</comment>\r\n  </data>\r\n  <data name=\"AvailableSubcommands\" xml:space=\"preserve\">\r\n    <value>The following sub-commands are available:</value>\r\n    <comment>Message displayed to inform the user about the available nested commands that run in context of the selected command.</comment>\r\n  </data>\r\n  <data name=\"AvailableUpgrades\" xml:space=\"preserve\">\r\n    <value>{0} upgrades available.</value>\r\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about available package upgrades. {0} is a placeholder replaced by the number of package upgrades.</comment>\r\n  </data>\r\n  <data name=\"ChannelArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Use the specified channel; default is general audience</value>\r\n  </data>\r\n  <data name=\"Command\" xml:space=\"preserve\">\r\n    <value>command</value>\r\n    <comment>Label displayed for a command to give the software.</comment>\r\n  </data>\r\n  <data name=\"CommandArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Filter results by command</value>\r\n    <comment>Description message displayed to inform the user about filtering the search results by a package command.</comment>\r\n  </data>\r\n  <data name=\"CommandLineArgumentDescription\" xml:space=\"preserve\">\r\n    <value>The full command line for completion</value>\r\n  </data>\r\n  <data name=\"CommandRequiresAdmin\" xml:space=\"preserve\">\r\n    <value>This command requires administrator privileges to execute.</value>\r\n  </data>\r\n  <data name=\"CompleteCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>This command can be used to request context sensitive command line completion. The command line, cursor position, and word to be completed are passed in. The output is a set of potential values based on the inputs, with one possible value per line.</value>\r\n  </data>\r\n  <data name=\"CompleteCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Enables context sensitive command line completion</value>\r\n  </data>\r\n  <data name=\"CountArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Show no more than specified number of results (between 1 and 1000)</value>\r\n  </data>\r\n  <data name=\"Done\" xml:space=\"preserve\">\r\n    <value>Done</value>\r\n    <comment>Label displayed when an operation completes or is done executing.</comment>\r\n  </data>\r\n  <data name=\"ExactArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Find package using exact match</value>\r\n    <comment>Description message displayed to inform the user about finding an application package using an exact matching criteria.</comment>\r\n  </data>\r\n  <data name=\"ExperimentalArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Experimental argument for demonstration purposes</value>\r\n  </data>\r\n  <data name=\"ExperimentalCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>This command is an example on how to implement an experimental feature. To turn on go to 'winget settings' and enable experimentalCmd or experimentalArg features.</value>\r\n    <comment>{Locked=\"winget settings\"}</comment>\r\n  </data>\r\n  <data name=\"ExperimentalCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Experimental feature example</value>\r\n  </data>\r\n  <data name=\"ExtraPositionalError\" xml:space=\"preserve\">\r\n    <value>Found a positional argument when none was expected: '{0}'</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an extra positional argument when none was expected. {0} is a placeholder replaced by the user's extra argument input.</comment>\r\n  </data>\r\n  <data name=\"FeatureDisabledMessage\" xml:space=\"preserve\">\r\n    <value>This feature is a work in progress, and may be changed dramatically or removed altogether in the future. To enable it, edit your settings ('winget settings') to include the experimental feature: '{0}'</value>\r\n    <comment>{Locked=\"winget settings\",\"{0}\"}. Error message displayed when the user uses an experimental feature that is disabled. {0} is a placeholder replaced by the experimental feature name.</comment>\r\n  </data>\r\n  <data name=\"FeaturesCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Shows the status of experimental features. Experimental features can be turned on via 'winget settings'.</value>\r\n    <comment>{Locked=\"winget settings\"}</comment>\r\n  </data>\r\n  <data name=\"FeaturesCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Shows the status of experimental features</value>\r\n  </data>\r\n  <data name=\"FeaturesDisabled\" xml:space=\"preserve\">\r\n    <value>Disabled</value>\r\n  </data>\r\n  <data name=\"FeaturesEnabled\" xml:space=\"preserve\">\r\n    <value>Enabled</value>\r\n  </data>\r\n  <data name=\"FeaturesFeature\" xml:space=\"preserve\">\r\n    <value>Feature</value>\r\n  </data>\r\n  <data name=\"FeaturesLink\" xml:space=\"preserve\">\r\n    <value>Link</value>\r\n  </data>\r\n  <data name=\"FeaturesMessage\" xml:space=\"preserve\">\r\n    <value>The following experimental features are in progress.\r\nThey can be configured through the settings file 'winget settings'.</value>\r\n    <comment>{Locked=\"winget settings\"}</comment>\r\n  </data>\r\n  <data name=\"FeaturesProperty\" xml:space=\"preserve\">\r\n    <value>Property</value>\r\n  </data>\r\n  <data name=\"FeaturesStatus\" xml:space=\"preserve\">\r\n    <value>Status</value>\r\n  </data>\r\n  <data name=\"FileArgumentDescription\" xml:space=\"preserve\">\r\n    <value>File to be hashed</value>\r\n  </data>\r\n  <data name=\"FlagContainAdjoinedError\" xml:space=\"preserve\">\r\n    <value>Flag argument cannot contain adjoined value: '{0}'</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a flag argument containing an unexpected adjoined value. {0} is a placeholder replaced by the user input.</comment>\r\n  </data>\r\n  <data name=\"HashCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Computes the hash of a local file, appropriate for entry into a manifest.  It can also compute the hash of the signature file of an MSIX package to enable streaming installations.</value>\r\n  </data>\r\n  <data name=\"HashCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Helper to hash installer files</value>\r\n  </data>\r\n  <data name=\"HelpArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Shows help about the selected command</value>\r\n  </data>\r\n  <data name=\"HelpForDetails\" xml:space=\"preserve\">\r\n    <value>For more details on a specific command, pass it the help argument.</value>\r\n  </data>\r\n  <data name=\"HelpLinkPreamble\" xml:space=\"preserve\">\r\n    <value>More help can be found at: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a link where they can learn more about the subject context. {0} is a placeholder replaced by a website address.</comment>\r\n  </data>\r\n  <data name=\"IdArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Filter results by id</value>\r\n  </data>\r\n  <data name=\"IgnoreWarningsArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Suppresses warning outputs</value>\r\n  </data>\r\n  <data name=\"InstallationDisclaimer1\" xml:space=\"preserve\">\r\n    <value>This application is licensed to you by its owner.</value>\r\n  </data>\r\n  <data name=\"InstallationDisclaimer2\" xml:space=\"preserve\">\r\n    <value>Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.</value>\r\n  </data>\r\n  <data name=\"InstallationDisclaimerMSStore\" xml:space=\"preserve\">\r\n    <value>This package is provided through Microsoft Store. WinGet may need to acquire the package from Microsoft Store on behalf of the current user.</value>\r\n    <comment>{Locked=\"WinGet\"}</comment>\r\n  </data>\r\n  <data name=\"InstallCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Installs the selected package, either found by searching a configured source or directly from a manifest. By default, the query must case-insensitively match the id, name, or moniker of the package. Other fields can be used by passing their appropriate option. By default, install command will check package installed status and try to perform an upgrade if applicable. Override with --force to perform a direct install.</value>\r\n    <comment>{Locked=\"--force\"}; id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\r\n  </data>\r\n  <data name=\"InstallCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Installs the given package</value>\r\n  </data>\r\n  <data name=\"InstallerHashMismatchAdminBlock\" xml:space=\"preserve\">\r\n    <value>Installer hash does not match; this cannot be overridden when running as admin</value>\r\n  </data>\r\n  <data name=\"InstallerHashMismatchOverridden\" xml:space=\"preserve\">\r\n    <value>Installer hash does not match; proceeding due to --ignore-security-hash</value>\r\n    <comment>{Locked=\"--ignore-security-hash\"}</comment>\r\n  </data>\r\n  <data name=\"InstallerHashMismatchOverrideRequired\" xml:space=\"preserve\">\r\n    <value>Installer hash does not match; to override this check use --ignore-security-hash</value>\r\n    <comment>{Locked=\"--ignore-security-hash\"}</comment>\r\n  </data>\r\n  <data name=\"InstallerHashVerified\" xml:space=\"preserve\">\r\n    <value>Successfully verified installer hash</value>\r\n  </data>\r\n  <data name=\"InstallFlowInstallSuccess\" xml:space=\"preserve\">\r\n    <value>Successfully installed</value>\r\n  </data>\r\n  <data name=\"InstallFlowStartingPackageInstall\" xml:space=\"preserve\">\r\n    <value>Starting package install...</value>\r\n  </data>\r\n  <data name=\"HashOverrideArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Ignore the installer hash check failure</value>\r\n  </data>\r\n  <data name=\"IgnoreLocalArchiveMalwareScanArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Ignore the malware scan performed as part of installing an archive type package from local manifest</value>\r\n  </data>\r\n  <data name=\"InteractiveArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Request interactive installation; user input may be needed</value>\r\n  </data>\r\n  <data name=\"InvalidAliasError\" xml:space=\"preserve\">\r\n    <value>Argument alias was not recognized for the current command: '{0}'</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a command line argument alias that was not recognized for a selected command. {0} is a placeholder replaced by the user's argument alias input (e.g. '-a').</comment>\r\n  </data>\r\n  <data name=\"InvalidArgumentSpecifierError\" xml:space=\"preserve\">\r\n    <value>Invalid argument specifier: '{0}'</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an invalid argument specifier. {0} is a placeholder replaced by an argument specifier (e.g. '-').</comment>\r\n  </data>\r\n  <data name=\"InvalidNameError\" xml:space=\"preserve\">\r\n    <value>Argument name was not recognized for the current command: '{0}'</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an unrecognized command line argument name for the selected command. {0} is a placeholder replaced by the user's argument name input (e.g. '--example').</comment>\r\n  </data>\r\n  <data name=\"KeyDirectoriesHeader\" xml:space=\"preserve\">\r\n    <value>WinGet Directories</value>\r\n    <comment>{Locked=\"WinGet\"} Header for a table detailing the directories WinGet uses for key operations like logging and portable installs</comment>\r\n  </data>\r\n  <data name=\"LocaleArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Locale to use (BCP47 format)</value>\r\n    <comment>{Locked=\"BCP47\"}</comment>\r\n  </data>\r\n  <data name=\"LicenseAgreement\" xml:space=\"preserve\">\r\n    <value>License Agreement</value>\r\n  </data>\r\n  <data name=\"Links\" xml:space=\"preserve\">\r\n    <value>Links</value>\r\n    <comment>Links to different webpages</comment>\r\n  </data>\r\n  <data name=\"ListCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>The list command displays the packages installed on the system, as well as whether an upgrade is available. Additional options can be provided to filter the output, much like the search command.</value>\r\n    <comment>{Locked=\"list\",\"search\"}</comment>\r\n  </data>\r\n  <data name=\"ListCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Display installed packages</value>\r\n  </data>\r\n  <data name=\"LocationArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Location to install to (if supported)</value>\r\n  </data>\r\n  <data name=\"LogArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Log location (if supported)</value>\r\n  </data>\r\n  <data name=\"MainCopyrightNotice\" xml:space=\"preserve\">\r\n    <value>© 2026 Microsoft. All rights reserved.</value>\r\n  </data>\r\n  <data name=\"MainHomepage\" xml:space=\"preserve\">\r\n    <value>Homepage</value>\r\n    <comment>The primary webpage for the software</comment>\r\n  </data>\r\n  <data name=\"ManifestArgumentDescription\" xml:space=\"preserve\">\r\n    <value>The path to the manifest of the package</value>\r\n  </data>\r\n  <data name=\"ManifestValidationFail\" xml:space=\"preserve\">\r\n    <value>Manifest validation failed.</value>\r\n  </data>\r\n  <data name=\"ManifestValidationSuccess\" xml:space=\"preserve\">\r\n    <value>Manifest validation succeeded.</value>\r\n  </data>\r\n  <data name=\"ManifestValidationWarning\" xml:space=\"preserve\">\r\n    <value>Manifest validation succeeded with warnings.</value>\r\n  </data>\r\n  <data name=\"MissingArgumentError\" xml:space=\"preserve\">\r\n    <value>Argument value required, but none found: '{0}'</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user does not provide a required command line argument value. {0} is a placeholder replaced by the argument name.</comment>\r\n  </data>\r\n  <data name=\"MonikerArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Filter results by moniker</value>\r\n  </data>\r\n  <data name=\"MsixArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Input file will be treated as msix; signature hash will be provided if signed</value>\r\n  </data>\r\n  <data name=\"MsixSignatureHashFailed\" xml:space=\"preserve\">\r\n    <value>Failed to calculate MSIX signature hash.</value>\r\n  </data>\r\n  <data name=\"MSStoreAppBlocked\" xml:space=\"preserve\">\r\n    <value>Failed to install or upgrade Microsoft Store package because the specific app is blocked by policy</value>\r\n  </data>\r\n  <data name=\"MSStoreInstallOrUpdateFailed\" xml:space=\"preserve\">\r\n    <value>Failed to install or upgrade Microsoft Store package. Error code: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when a Microsoft Store application package fails to install or upgrade. {0} is a placeholder replaced by an error code.</comment>\r\n  </data>\r\n  <data name=\"MSStoreStoreClientBlocked\" xml:space=\"preserve\">\r\n    <value>Failed to install or upgrade Microsoft Store package because Microsoft Store client is blocked by policy</value>\r\n  </data>\r\n  <data name=\"MSStoreInstallTryGetEntitlement\" xml:space=\"preserve\">\r\n    <value>Verifying/Requesting package acquisition...</value>\r\n  </data>\r\n  <data name=\"MultipleInstalledPackagesFound\" xml:space=\"preserve\">\r\n    <value>Multiple installed packages found matching input criteria. Please refine the input.</value>\r\n  </data>\r\n  <data name=\"MultiplePackagesFound\" xml:space=\"preserve\">\r\n    <value>Multiple packages found matching input criteria. Please refine the input.</value>\r\n  </data>\r\n  <data name=\"NameArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Filter results by name</value>\r\n  </data>\r\n  <data name=\"NoApplicableInstallers\" xml:space=\"preserve\">\r\n    <value>No applicable installer found; see logs for more details.</value>\r\n  </data>\r\n  <data name=\"NoExperimentalFeaturesMessage\" xml:space=\"preserve\">\r\n    <value>There are currently no experimental features available. </value>\r\n  </data>\r\n  <data name=\"NoInstalledPackageFound\" xml:space=\"preserve\">\r\n    <value>No installed package found matching input criteria.</value>\r\n  </data>\r\n  <data name=\"NoPackageFound\" xml:space=\"preserve\">\r\n    <value>No package found matching input criteria.</value>\r\n  </data>\r\n  <data name=\"NoVTArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Disables VirtualTerminal display</value>\r\n    <comment>{Locked=\"VirtualTerminal\"}</comment>\r\n  </data>\r\n  <data name=\"OpenLogsArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Open the default logs location</value>\r\n  </data>\r\n  <data name=\"Options\" xml:space=\"preserve\">\r\n    <value>options</value>\r\n    <comment>Options to change how a command works</comment>\r\n  </data>\r\n  <data name=\"OverrideArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Override arguments to be passed on to the installer</value>\r\n  </data>\r\n  <data name=\"Package\" xml:space=\"preserve\">\r\n    <value>Package: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Label displayed for a software package. {0} is a placeholder replaced by the software package name.</comment>\r\n  </data>\r\n  <data name=\"PendingWorkError\" xml:space=\"preserve\">\r\n    <value>Oops, we forgot to do this...</value>\r\n  </data>\r\n  <data name=\"PositionArgumentDescription\" xml:space=\"preserve\">\r\n    <value>The position of the cursor within the command line</value>\r\n  </data>\r\n  <data name=\"PrivacyStatement\" xml:space=\"preserve\">\r\n    <value>Privacy Statement</value>\r\n  </data>\r\n  <data name=\"QueryArgumentDescription\" xml:space=\"preserve\">\r\n    <value>The query used to search for a package</value>\r\n  </data>\r\n  <data name=\"RainbowArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Progress display a rainbow of colors</value>\r\n  </data>\r\n  <data name=\"RequiredArgError\" xml:space=\"preserve\">\r\n    <value>Required argument not provided: '{0}'</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user does not provide a required command line argument. {0} is a placeholder replaced by an argument name.</comment>\r\n  </data>\r\n  <data name=\"RetroArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Progress display as the default color</value>\r\n  </data>\r\n  <data name=\"SearchCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Searches for packages from configured sources.</value>\r\n  </data>\r\n  <data name=\"SearchCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Find and show basic info of packages</value>\r\n  </data>\r\n  <data name=\"SearchId\" xml:space=\"preserve\">\r\n    <value>Id</value>\r\n    <comment>Abbreviation of Identifier.</comment>\r\n  </data>\r\n  <data name=\"SearchMatch\" xml:space=\"preserve\">\r\n    <value>Match</value>\r\n  </data>\r\n  <data name=\"SearchName\" xml:space=\"preserve\">\r\n    <value>Name</value>\r\n  </data>\r\n  <data name=\"SearchSource\" xml:space=\"preserve\">\r\n    <value>Source</value>\r\n  </data>\r\n  <data name=\"SearchTruncated\" xml:space=\"preserve\">\r\n    <value>additional entries truncated due to result limit</value>\r\n  </data>\r\n  <data name=\"SearchVersion\" xml:space=\"preserve\">\r\n    <value>Version</value>\r\n  </data>\r\n  <data name=\"SettingLoadFailure\" xml:space=\"preserve\">\r\n    <value>The following failures were found validating the settings:</value>\r\n  </data>\r\n  <data name=\"SettingsCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Open settings in the default json text editor. If no editor is configured, opens settings in notepad. For available settings see https://aka.ms/winget-settings This command can also be used to set administrator settings by providing the --enable or --disable arguments</value>\r\n    <comment>{Locked=\"--enable\"} {Locked=\"--disable\"}</comment>\r\n  </data>\r\n  <data name=\"SettingsCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Open settings or set administrator settings</value>\r\n  </data>\r\n  <data name=\"SettingsWarnings\" xml:space=\"preserve\">\r\n    <value>Unexpected error while loading settings. Please verify your settings by running the 'settings' command.</value>\r\n    <comment>{Locked=\"'settings'\"}</comment>\r\n  </data>\r\n  <data name=\"ShowChannel\" xml:space=\"preserve\">\r\n    <value>Channel</value>\r\n  </data>\r\n  <data name=\"ShowCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Shows information on a specific package. By default, the query must case-insensitively match the id, name, or moniker of the package. Other fields can be used by passing their appropriate option.</value>\r\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\r\n  </data>\r\n  <data name=\"ShowCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Shows information about a package</value>\r\n  </data>\r\n  <data name=\"ShowVersion\" xml:space=\"preserve\">\r\n    <value>Version</value>\r\n  </data>\r\n  <data name=\"SilentArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Request silent installation</value>\r\n  </data>\r\n  <data name=\"SingleCharAfterDashError\" xml:space=\"preserve\">\r\n    <value>Only the single character alias can occur after a single -: '{0}'</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides more than a single character command line alias argument after an alias argument specifier '-'. {0} is a placeholder replaced by the user's argument input.</comment>\r\n  </data>\r\n  <data name=\"SourceAddAlreadyExistsDifferentArg\" xml:space=\"preserve\">\r\n    <value>A source with the given name already exists and refers to a different location:</value>\r\n  </data>\r\n  <data name=\"SourceAddAlreadyExistsDifferentName\" xml:space=\"preserve\">\r\n    <value>A source with a different name already refers to this location:</value>\r\n  </data>\r\n  <data name=\"SourceAddAlreadyExistsMatch\" xml:space=\"preserve\">\r\n    <value>A source with the given name already exists and refers to the same location:</value>\r\n  </data>\r\n  <data name=\"SourceAddBegin\" xml:space=\"preserve\">\r\n    <value>Adding source:</value>\r\n  </data>\r\n  <data name=\"SourceAddCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Add a new source. A source provides the data for you to discover and install packages. Only add a new source if you trust it as a secure location.</value>\r\n  </data>\r\n  <data name=\"SourceAddCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Add a new source</value>\r\n  </data>\r\n  <data name=\"SourceArgArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Argument given to the source</value>\r\n  </data>\r\n  <data name=\"SourceArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Find package using the specified source</value>\r\n  </data>\r\n  <data name=\"SourceCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Manage sources with the sub-commands. A source provides the data for you to discover and install packages. Only add a new source if you trust it as a secure location.</value>\r\n  </data>\r\n  <data name=\"SourceCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Manage sources of packages</value>\r\n  </data>\r\n  <data name=\"SourceEditCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Edit properties of an existing source. A source provides the data for you to discover and install packages.</value>\r\n  </data>\r\n  <data name=\"SourceEditCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Edit properties of a source</value>\r\n  </data>\r\n  <data name=\"SourceEditOne\" xml:space=\"preserve\">\r\n    <value>Editing source: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being edited. {0} is a placeholder replaced by the repository source name.</comment>\r\n  </data>\r\n  <data name=\"SourceEditNoChanges\" xml:space=\"preserve\">\r\n    <value>The source named '{0}' is already in the desired state.</value>\r\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being edited. {0} is a placeholder replaced by the repository source name.</comment>\r\n  </data>\r\n  <data name=\"SourceListArg\" xml:space=\"preserve\">\r\n    <value>Argument</value>\r\n    <comment>Value given to source.</comment>\r\n  </data>\r\n  <data name=\"SourceListCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>List all current sources, or full details of a specific source.</value>\r\n  </data>\r\n  <data name=\"SourceListCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>List current sources</value>\r\n  </data>\r\n  <data name=\"SourceListData\" xml:space=\"preserve\">\r\n    <value>Data</value>\r\n    <comment>Data stored by the source.</comment>\r\n  </data>\r\n  <data name=\"SourceListField\" xml:space=\"preserve\">\r\n    <value>Field</value>\r\n    <comment>The name of a piece of information about a source.</comment>\r\n  </data>\r\n  <data name=\"SourceListName\" xml:space=\"preserve\">\r\n    <value>Name</value>\r\n    <comment>The name of the source.</comment>\r\n  </data>\r\n  <data name=\"SourceListIdentifier\" xml:space=\"preserve\">\r\n    <value>Identifier</value>\r\n    <comment>The source's unique identifier.</comment>\r\n  </data>\r\n  <data name=\"SourceListNoneFound\" xml:space=\"preserve\">\r\n    <value>Did not find a source named: {0}</value>\r\n    <comment>Error message displayed when the user provides a repository source name that was not found. {0} is a placeholder replaced by the user input.</comment>\r\n  </data>\r\n  <data name=\"SourceListNoSources\" xml:space=\"preserve\">\r\n    <value>There are no sources configured.</value>\r\n  </data>\r\n  <data name=\"SourceListType\" xml:space=\"preserve\">\r\n    <value>Type</value>\r\n    <comment>The kind of source.</comment>\r\n  </data>\r\n  <data name=\"SourceListUpdated\" xml:space=\"preserve\">\r\n    <value>Updated</value>\r\n    <comment>The last time the source was updated.</comment>\r\n  </data>\r\n  <data name=\"SourceListUpdatedNever\" xml:space=\"preserve\">\r\n    <value>never</value>\r\n    <comment>The source has never been updated.</comment>\r\n  </data>\r\n  <data name=\"SourceListValue\" xml:space=\"preserve\">\r\n    <value>Value</value>\r\n    <comment>The value of information about a source.</comment>\r\n  </data>\r\n  <data name=\"SourceNameArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Name of the source</value>\r\n  </data>\r\n  <data name=\"SourceOpenFailedSuggestion\" xml:space=\"preserve\">\r\n    <value>Failed when opening source(s); try the 'source reset' command if the problem persists.</value>\r\n    <comment>{Locked=\"source reset\"}</comment>\r\n  </data>\r\n  <data name=\"SourceOpenPredefinedFailedSuggestion\" xml:space=\"preserve\">\r\n    <value>Failed to open the predefined source; please report to WinGet maintainers.</value>\r\n    <comment>{Locked=\"WinGet\"}</comment>\r\n  </data>\r\n  <data name=\"SourceRemoveAll\" xml:space=\"preserve\">\r\n    <value>Removing all sources...</value>\r\n  </data>\r\n  <data name=\"SourceRemoveCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Remove a specific source.</value>\r\n  </data>\r\n  <data name=\"SourceRemoveCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Remove current sources</value>\r\n  </data>\r\n  <data name=\"SourceRemoveOne\" xml:space=\"preserve\">\r\n    <value>Removing source: {0}...</value>\r\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being removed. {0} is a placeholder replaced by the repository source name.</comment>\r\n  </data>\r\n  <data name=\"SourceResetAll\" xml:space=\"preserve\">\r\n    <value>Resetting all sources...</value>\r\n  </data>\r\n  <data name=\"SourceResetCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>This command drops existing sources, potentially leaving any local data behind. Without any argument, it will drop all sources and add the defaults. If a named source is provided, only that source will be dropped.</value>\r\n  </data>\r\n  <data name=\"SourceResetCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Reset sources</value>\r\n  </data>\r\n  <data name=\"SourceResetForceArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Forces the reset of the sources</value>\r\n  </data>\r\n  <data name=\"SourceResetListAndOverridePreamble\" xml:space=\"preserve\">\r\n    <value>The following sources will be reset if the --force option is given:</value>\r\n    <comment>{Locked=\"--force\"}</comment>\r\n  </data>\r\n  <data name=\"SourceResetOne\" xml:space=\"preserve\">\r\n    <value>Resetting source: {0}...</value>\r\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a repository source that is currently being reset. {0} is a placeholder replaced by the repository source name.</comment>\r\n  </data>\r\n  <data name=\"SourceTypeArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Type of the source</value>\r\n  </data>\r\n  <data name=\"SourceUpdateAll\" xml:space=\"preserve\">\r\n    <value>Updating all sources...</value>\r\n  </data>\r\n  <data name=\"SourceUpdateCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Update all sources, or only a specific source.</value>\r\n  </data>\r\n  <data name=\"SourceUpdateCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Update current sources</value>\r\n  </data>\r\n  <data name=\"SourceUpdateOne\" xml:space=\"preserve\">\r\n    <value>Updating source: {0}...</value>\r\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about a registered repository source that is currently being updated. {0} is a placeholder replaced by the repository source name.</comment>\r\n  </data>\r\n  <data name=\"TagArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Filter results by tag</value>\r\n  </data>\r\n  <data name=\"ThankYou\" xml:space=\"preserve\">\r\n    <value>Thank you for using WinGet</value>\r\n    <comment>{Locked=\"WinGet\"}</comment>\r\n  </data>\r\n  <data name=\"ThirdPartSoftwareNotices\" xml:space=\"preserve\">\r\n    <value>Third Party Notices</value>\r\n  </data>\r\n  <data name=\"ToolDescription\" xml:space=\"preserve\">\r\n    <value>The winget command line utility enables installing applications and other packages from the command line.</value>\r\n  </data>\r\n  <data name=\"ToolInfoArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Display general info of the tool</value>\r\n  </data>\r\n  <data name=\"ToolVersionArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Display the version of the tool</value>\r\n  </data>\r\n  <data name=\"TooManyArgError\" xml:space=\"preserve\">\r\n    <value>Argument provided more times than allowed: '{0}'</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a command line argument more times than it is allowed. {0} is a placeholder replaced by the user's argument name input.</comment>\r\n  </data>\r\n  <data name=\"TooManyBehaviorsError\" xml:space=\"preserve\">\r\n    <value>More than one execution behavior argument provided: '{0}'</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides more than one execution behavior argument when installing an application package. {0} is a placeholder replaced by the user specified execution behaviors (e.g. 'silent|interactive').</comment>\r\n  </data>\r\n  <data name=\"UnexpectedErrorExecutingCommand\" xml:space=\"preserve\">\r\n    <value>An unexpected error occurred while executing the command:</value>\r\n  </data>\r\n  <data name=\"UninstallPreviousArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Uninstall the previous version of the package during upgrade</value>\r\n  </data>\r\n  <data name=\"UnrecognizedCommand\" xml:space=\"preserve\">\r\n    <value>Unrecognized command: '{0}'</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an unrecognized command. {0} is a placeholder replaced by the user input.</comment>\r\n  </data>\r\n  <data name=\"UpdateAllArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Upgrade all installed packages to latest if available</value>\r\n  </data>\r\n  <data name=\"UpdateNotApplicable\" xml:space=\"preserve\">\r\n    <value>No applicable upgrade found.</value>\r\n  </data>\r\n  <data name=\"UpdateNotApplicableReason\" xml:space=\"preserve\">\r\n    <value>A newer package version is available in a configured source, but it does not apply to your system or requirements.</value>\r\n  </data>\r\n  <data name=\"UpdateNoPackagesFound\" xml:space=\"preserve\">\r\n    <value>No available upgrade found.</value>\r\n  </data>\r\n  <data name=\"UpdateNoPackagesFoundReason\" xml:space=\"preserve\">\r\n    <value>No newer package versions are available from the configured sources.</value>\r\n  </data>\r\n  <data name=\"UpgradeCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Upgrades the selected package, either found by searching the installed packages list or directly from a manifest. By default, the query must case-insensitively match the id, name, or moniker of the package. Other fields can be used by passing their appropriate option. When no arguments are given, shows the packages with upgrades available</value>\r\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\r\n  </data>\r\n  <data name=\"UpgradeCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Shows and performs available upgrades</value>\r\n  </data>\r\n  <data name=\"Usage\" xml:space=\"preserve\">\r\n    <value>usage: {0} {1}</value>\r\n    <comment>{Locked=\"{0} {1}\"} Message displayed to provide the user with instructions on how to use a command. {0} is a placeholder replaced by the program name (e.g. 'winget'). {1} is a placeholder replaced by the pattern for using the selected command.</comment>\r\n  </data>\r\n  <data name=\"ValidateCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Validates a manifest using a strict set of guidelines. This is intended to enable you to check your manifest before submitting to a repo.</value>\r\n  </data>\r\n  <data name=\"ValidateCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Validates a manifest file</value>\r\n  </data>\r\n  <data name=\"ValidateManifestArgumentDescription\" xml:space=\"preserve\">\r\n    <value>The path to the manifest to be validated</value>\r\n  </data>\r\n  <data name=\"VerboseLogsArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Enables verbose logging for winget</value>\r\n  </data>\r\n  <data name=\"VerifyFileSignedMsix\" xml:space=\"preserve\">\r\n    <value>Please verify that the input file is a valid, signed MSIX.</value>\r\n  </data>\r\n  <data name=\"VersionArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Use the specified version; default is the latest version</value>\r\n  </data>\r\n  <data name=\"VersionsArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Show available versions of the package</value>\r\n  </data>\r\n  <data name=\"WordArgumentDescription\" xml:space=\"preserve\">\r\n    <value>The value provided before completion is requested</value>\r\n  </data>\r\n  <data name=\"GetManifestResultVersionNotFound\" xml:space=\"preserve\">\r\n    <value>No version found matching: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to upgrade an application package to a version that was not found. {0} is a placeholder replaced by the user's provided upgrade package version.</comment>\r\n  </data>\r\n  <data name=\"OpenSourceFailedNoMatch\" xml:space=\"preserve\">\r\n    <value>No sources match the given value: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to install or upgrade an application package from a repository source that was not found. {0} is a placeholder replaced by the user's repository source name input.</comment>\r\n  </data>\r\n  <data name=\"OpenSourceFailedNoMatchHelp\" xml:space=\"preserve\">\r\n    <value>The configured sources are:</value>\r\n  </data>\r\n  <data name=\"OpenSourceFailedNoSourceDefined\" xml:space=\"preserve\">\r\n    <value>No sources defined; add one with 'source add' or reset to defaults with 'source reset'</value>\r\n    <comment>{Locked=\"source add\",\"source reset\"}</comment>\r\n  </data>\r\n  <data name=\"ReportIdentityFound\" xml:space=\"preserve\">\r\n    <value>Found</value>\r\n  </data>\r\n  <data name=\"VerifyFileFailedIsDirectory\" xml:space=\"preserve\">\r\n    <value>Path is a directory: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system path that is a directory. {0} is a placeholder replaced by the provided directory path.</comment>\r\n  </data>\r\n  <data name=\"VerifyFileFailedNotExist\" xml:space=\"preserve\">\r\n    <value>File does not exist: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system file that does not exist. {0} is a placeholder replaced by the provided file path.</comment>\r\n  </data>\r\n  <data name=\"BothManifestAndSearchQueryProvided\" xml:space=\"preserve\">\r\n    <value>Both local manifest and search query arguments are provided</value>\r\n  </data>\r\n  <data name=\"Logs\" xml:space=\"preserve\">\r\n    <value>Logs</value>\r\n    <comment>Label displayed for diagnostic files containing information about the application use.</comment>\r\n  </data>\r\n  <data name=\"InstallerBlockedByPolicy\" xml:space=\"preserve\">\r\n    <value>The installer is blocked by policy</value>\r\n  </data>\r\n  <data name=\"InstallerFailedSecurityCheck\" xml:space=\"preserve\">\r\n    <value>The installer failed security check</value>\r\n  </data>\r\n  <data name=\"InstallerFailedVirusScan\" xml:space=\"preserve\">\r\n    <value>An anti-virus product reports an infection in the installer</value>\r\n  </data>\r\n  <data name=\"SourceOpenWithFailedUpdate\" xml:space=\"preserve\">\r\n    <value>Failed in attempting to update the source: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to update the repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\r\n  </data>\r\n  <data name=\"UninstallCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Uninstalls the selected package, either found by searching the installed packages list or directly from a manifest. By default, the query must case-insensitively match the id, name, or moniker of the package. Other fields can be used by passing their appropriate option.</value>\r\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\r\n  </data>\r\n  <data name=\"UninstallCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Uninstalls the given package</value>\r\n  </data>\r\n  <data name=\"UninstallFlowStartingPackageUninstall\" xml:space=\"preserve\">\r\n    <value>Starting package uninstall...</value>\r\n  </data>\r\n  <data name=\"UninstallFlowUninstallSuccess\" xml:space=\"preserve\">\r\n    <value>Successfully uninstalled</value>\r\n  </data>\r\n  <data name=\"NoUninstallInfoFound\" xml:space=\"preserve\">\r\n    <value>WinGet cannot locate the uninstall command for this package. Please reach out to the package publisher for support.</value>\r\n    <comment>{Locked=\"WinGet\"}</comment>\r\n  </data>\r\n  <data name=\"UninstallAbandoned\" xml:space=\"preserve\">\r\n    <value>Uninstallation abandoned</value>\r\n  </data>\r\n  <data name=\"UninstallFailedWithCode\" xml:space=\"preserve\">\r\n    <value>Uninstall failed with exit code: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to uninstall an application package fails. {0} is a placeholder replaced by an error code.</comment>\r\n  </data>\r\n  <data name=\"ExportCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Exports a list of the installed packages</value>\r\n  </data>\r\n  <data name=\"ImportCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Installs all the packages listed in a file.</value>\r\n  </data>\r\n  <data name=\"ImportCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Installs all the packages in a file</value>\r\n  </data>\r\n  <data name=\"OutputFileArgumentDescription\" xml:space=\"preserve\">\r\n    <value>File where the result is to be written</value>\r\n  </data>\r\n  <data name=\"ImportFileArgumentDescription\" xml:space=\"preserve\">\r\n    <value>File describing the packages to install</value>\r\n  </data>\r\n  <data name=\"ExportSourceArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Export packages from the specified source</value>\r\n  </data>\r\n  <data name=\"ExportCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Writes a list of the installed packages to a file. The packages can then be installed with the import command.</value>\r\n    <comment>{Locked=\"import\"}</comment>\r\n  </data>\r\n  <data name=\"ImportInstallFailed\" xml:space=\"preserve\">\r\n    <value>One or more imported packages failed to install</value>\r\n  </data>\r\n  <data name=\"ImportSourceNotInstalled\" xml:space=\"preserve\">\r\n    <value>Source required for import is not installed: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to import application package(s) from a repository source that is not installed. {0} is a placeholder replaced by the repository source name.</comment>\r\n  </data>\r\n  <data name=\"InstalledPackageNotAvailable\" xml:space=\"preserve\">\r\n    <value>Installed package is not available from any source: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Warning message displayed when the user attempts to export an installed application package that is not available from any repository source. {0} is a placeholder replaced by the installed package name.</comment>\r\n  </data>\r\n  <data name=\"InstalledPackageVersionNotAvailable\" xml:space=\"preserve\">\r\n    <value>Installed version of package is not available from any source: {0} {1} {2}</value>\r\n    <comment>{Locked=\"{0} {1} {2}\"} Warning message displayed when the user attempts to export an installed application package with a version that is not available from any repository source. {0} is a placeholder replaced by the installed package identifier. {1} is a placeholder replaced by the installed package version. {2} is a placeholder replaced by the installed package channel.</comment>\r\n  </data>\r\n  <data name=\"NoPackagesInImportFile\" xml:space=\"preserve\">\r\n    <value>No packages found in import file</value>\r\n  </data>\r\n  <data name=\"InvalidJsonFile\" xml:space=\"preserve\">\r\n    <value>JSON file is not valid</value>\r\n  </data>\r\n  <data name=\"MultiQueryPackageAlreadyInstalled\" xml:space=\"preserve\">\r\n    <value>Package is already installed: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user that an application package is already installed. {0} is a placeholder replaced by the package identifier or search query.</comment>\r\n  </data>\r\n  <data name=\"ImportIgnoreUnavailableArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Ignore unavailable packages</value>\r\n  </data>\r\n  <data name=\"ExportIncludeVersionsArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Include package versions in export file</value>\r\n  </data>\r\n  <data name=\"ImportIgnoreVersionsArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Ignore package versions from import file</value>\r\n  </data>\r\n  <data name=\"VerifyPathFailedNotExist\" xml:space=\"preserve\">\r\n    <value>Path does not exist: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a system path argument value that does not exist. {0} is a placeholder replaced by the user's provided path.</comment>\r\n  </data>\r\n  <data name=\"ImportFileHasInvalidSchema\" xml:space=\"preserve\">\r\n    <value>The JSON file does not specify a recognized schema.</value>\r\n  </data>\r\n  <data name=\"InstallScopeDescription\" xml:space=\"preserve\">\r\n    <value>Select install scope (user or machine)</value>\r\n    <comment>{Locked=\"user\",\"machine\"} This argument allows the user to select between installing for just the user or for the entire machine.</comment>\r\n  </data>\r\n  <data name=\"InvalidArgumentValueError\" xml:space=\"preserve\">\r\n    <value>The value provided for the `{0}` argument is invalid; valid values are: {1}</value>\r\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message displayed when the user provides an invalid command line argument value. {0} is a placeholder replaced by the argument name. {1} is a placeholder replaced by a list of valid options.</comment>\r\n  </data>\r\n  <data name=\"DisabledByGroupPolicy\" xml:space=\"preserve\">\r\n    <value>This operation is disabled by Group Policy: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user performs a command operation that is disabled by a group policy. {0} is a placeholder replaced by a group policy description.</comment>\r\n  </data>\r\n  <data name=\"PolicyAdditionalSources\" xml:space=\"preserve\">\r\n    <value>Enable Additional Windows App Installer Sources</value>\r\n  </data>\r\n  <data name=\"PolicyAllowedSources\" xml:space=\"preserve\">\r\n    <value>Enable Windows App Installer Allowed Sources</value>\r\n  </data>\r\n  <data name=\"PolicyEnableDefaultSource\" xml:space=\"preserve\">\r\n    <value>Enable Windows App Installer Default Source</value>\r\n  </data>\r\n  <data name=\"PolicyEnableExperimentalFeatures\" xml:space=\"preserve\">\r\n    <value>Enable Windows App Installer Experimental Features</value>\r\n  </data>\r\n  <data name=\"PolicyEnableMSStoreSource\" xml:space=\"preserve\">\r\n    <value>Enable Windows App Installer Microsoft Store Source</value>\r\n  </data>\r\n  <data name=\"PolicyEnableFontSource\" xml:space=\"preserve\">\r\n    <value>Enable Windows App Installer Font Source</value>\r\n  </data>\r\n  <data name=\"PolicyEnableWinGetSettings\" xml:space=\"preserve\">\r\n    <value>Enable Windows Package Manager Settings</value>\r\n  </data>\r\n  <data name=\"PolicyEnableWinGet\" xml:space=\"preserve\">\r\n    <value>Enable Windows Package Manager</value>\r\n  </data>\r\n  <data name=\"PolicyEnableWindowsPackageManagerCommandLineInterfaces\" xml:space=\"preserve\">\r\n    <value>Enable Windows Package Manager command line interfaces</value>\r\n  </data>\r\n  <data name=\"PolicySourceAutoUpdateInterval\" xml:space=\"preserve\">\r\n    <value>Set Windows Package Manager Source Auto Update Interval In Minutes</value>\r\n  </data>\r\n  <data name=\"PoliciesPolicy\" xml:space=\"preserve\">\r\n    <value>Group Policy</value>\r\n    <comment>Header for a table listing active Group Policies</comment>\r\n  </data>\r\n  <data name=\"PolicyEnableLocalManifests\" xml:space=\"preserve\">\r\n    <value>Enable Windows App Installer Local Manifest Files</value>\r\n  </data>\r\n  <data name=\"PolicyEnableBypassCertificatePinningForMicrosoftStore\" xml:space=\"preserve\">\r\n    <value>Enable Windows App Installer Microsoft Store Source Pinned Certificate Bypass</value>\r\n  </data>\r\n  <data name=\"PolicyEnableLocalArchiveMalwareScanOverride\" xml:space=\"preserve\">\r\n    <value>Enable Windows App Installer Local Archive Malware Scan Override</value>\r\n  </data>\r\n  <data name=\"SettingsWarningField\" xml:space=\"preserve\">\r\n    <value>Field: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Warning message displayed when a user setting field has invalid syntax or semantics. {0} is a placeholder replaced by the setting field path.</comment>\r\n  </data>\r\n  <data name=\"SettingsWarningInvalidFieldFormat\" xml:space=\"preserve\">\r\n    <value>Invalid field format.</value>\r\n  </data>\r\n  <data name=\"SettingsWarningInvalidFieldValue\" xml:space=\"preserve\">\r\n    <value>Invalid field value.</value>\r\n  </data>\r\n  <data name=\"SettingsWarningInvalidValueFromPolicy\" xml:space=\"preserve\">\r\n    <value>Invalid setting from Group Policy.</value>\r\n  </data>\r\n  <data name=\"SettingsWarningLoadedBackupSettings\" xml:space=\"preserve\">\r\n    <value>Loaded settings from backup file.</value>\r\n  </data>\r\n  <data name=\"SettingsWarningParseError\" xml:space=\"preserve\">\r\n    <value>Error parsing file:</value>\r\n  </data>\r\n  <data name=\"SettingsWarningValue\" xml:space=\"preserve\">\r\n    <value>Value: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Warning message displayed when a user setting value has invalid syntax or semantics. {0} is a placeholder replaced by the setting data value.</comment>\r\n  </data>\r\n  <data name=\"FeaturesMessageDisabledByPolicy\" xml:space=\"preserve\">\r\n    <value>The following experimental features are in progress.\r\nConfiguration is disabled due to Group Policy.</value>\r\n  </data>\r\n  <data name=\"InstallerHashMismatchError\" xml:space=\"preserve\">\r\n    <value>Installer hash does not match.</value>\r\n  </data>\r\n  <data name=\"PolicyEnableHashOverride\" xml:space=\"preserve\">\r\n    <value>Enable Windows App Installer Hash Override</value>\r\n  </data>\r\n  <data name=\"SourceExportCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Export current sources as JSON for Group Policy.</value>\r\n  </data>\r\n  <data name=\"SourceExportCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Export current sources</value>\r\n  </data>\r\n  <data name=\"SourceListAdditionalSource\" xml:space=\"preserve\">\r\n    <value>Additional source</value>\r\n    <comment>An additional source required by policy.</comment>\r\n  </data>\r\n  <data name=\"SourceListAllowedSource\" xml:space=\"preserve\">\r\n    <value>Allowed source</value>\r\n    <comment>A source that the user is allowed to add.</comment>\r\n  </data>\r\n  <data name=\"InvalidArgumentValueErrorWithoutValidValues\" xml:space=\"preserve\">\r\n    <value>The value provided for the `{0}` argument is invalid</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides an invalid command line argument value. {0} is a placeholder replaced by the argument name.</comment>\r\n  </data>\r\n  <data name=\"Cancelled\" xml:space=\"preserve\">\r\n    <value>Cancelled</value>\r\n  </data>\r\n  <data name=\"ExternalDependencies\" xml:space=\"preserve\">\r\n    <value>External</value>\r\n  </data>\r\n  <data name=\"ImportCommandReportDependencies\" xml:space=\"preserve\">\r\n    <value>The packages found in this import have the following dependencies:</value>\r\n    <comment>Import command sentence showed before reporting dependencies</comment>\r\n  </data>\r\n  <data name=\"PackageRequiresDependencies\" xml:space=\"preserve\">\r\n    <value>This package requires the following dependencies:</value>\r\n    <comment>Message shown before reporting dependencies</comment>\r\n  </data>\r\n  <data name=\"DependenciesFlowInstall\" xml:space=\"preserve\">\r\n    <value>Installing dependencies:</value>\r\n  </data>\r\n  <data name=\"DependenciesFlowSourceNotFound\" xml:space=\"preserve\">\r\n    <value>Dependency source not found</value>\r\n  </data>\r\n  <data name=\"DependenciesFlowSourceTooManyMatches\" xml:space=\"preserve\">\r\n    <value>Package search yield more than one result: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when application packages search yield more than one result. {0} is a placeholder replaced by the dependency package identifier.</comment>\r\n  </data>\r\n  <data name=\"DependenciesFlowPackageVersionNotFound\" xml:space=\"preserve\">\r\n    <value>Latest version not found for package: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when no suitable version found for the specific application package. {0} is a placeholder replaced by the package identifier.</comment>\r\n  </data>\r\n  <data name=\"DependenciesFlowNoInstallerFound\" xml:space=\"preserve\">\r\n    <value>No installers found: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when no installer found for a manifest. {0} is a placeholder replaced by the manifest identifier.</comment>\r\n  </data>\r\n  <data name=\"DependenciesFlowNoMinVersion\" xml:space=\"preserve\">\r\n    <value>Minimum required version not available for package: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the minimum required version is not available for an application package. {0} is a placeholder replaced by the package identifier.</comment>\r\n  </data>\r\n  <data name=\"DependenciesFlowNoMatches\" xml:space=\"preserve\">\r\n    <value>No matches</value>\r\n    <comment>When package search yields no matches</comment>\r\n  </data>\r\n  <data name=\"DependenciesFlowContainsLoop\" xml:space=\"preserve\">\r\n    <value>Has loop</value>\r\n    <comment>Dependency graph has loop</comment>\r\n  </data>\r\n  <data name=\"DependenciesFlowNoSuitableInstallerFound\" xml:space=\"preserve\">\r\n    <value>No suitable installer found for manifest: {0} version {1}</value>\r\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message displayed when an attempt to get a preferred installer for a manifest fails. {0} is a placeholder replaced by the manifest identifier. {1} is a placeholder replaced by the manifest version.</comment>\r\n  </data>\r\n  <data name=\"DependenciesManagementError\" xml:space=\"preserve\">\r\n    <value>Error processing package dependencies. Do you wish to continue installation?</value>\r\n    <comment>Prompt message shown when dependencies processing yields errors.</comment>\r\n  </data>\r\n  <data name=\"DependenciesManagementExitMessage\" xml:space=\"preserve\">\r\n    <value>Error processing package dependencies. Exiting...</value>\r\n  </data>\r\n  <data name=\"PackageDependencies\" xml:space=\"preserve\">\r\n    <value>Packages</value>\r\n  </data>\r\n  <data name=\"UninstallCommandReportDependencies\" xml:space=\"preserve\">\r\n    <value>This package had dependencies that may not be needed anymore:</value>\r\n    <comment>Uninstall command sentence showed before reporting dependencies</comment>\r\n  </data>\r\n  <data name=\"ValidateCommandReportDependencies\" xml:space=\"preserve\">\r\n    <value>Manifest has the following dependencies that were not validated; ensure that they are valid:</value>\r\n    <comment>Validate command sentence showed before reporting dependencies</comment>\r\n  </data>\r\n  <data name=\"WindowsFeaturesDependencies\" xml:space=\"preserve\">\r\n    <value>Windows Features</value>\r\n  </data>\r\n  <data name=\"WindowsLibrariesDependencies\" xml:space=\"preserve\">\r\n    <value>Windows Libraries</value>\r\n  </data>\r\n  <data name=\"DependencySourceArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Find package dependencies using the specified source</value>\r\n    <comment>For getting package type dependencies when installing from a local manifest</comment>\r\n  </data>\r\n  <data name=\"WindowsStoreTerms\" xml:space=\"preserve\">\r\n    <value>Windows Store Terms</value>\r\n  </data>\r\n  <data name=\"AcceptPackageAgreementsArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Accept all license agreements for packages</value>\r\n  </data>\r\n  <data name=\"ExportedPackageRequiresLicenseAgreement\" xml:space=\"preserve\">\r\n    <value>Exported package requires license agreement to install: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Warning message displayed when an exported application package requires license agreement to install. {0} is a placeholder replaced by the package name.</comment>\r\n  </data>\r\n  <data name=\"PackageAgreementsPrompt\" xml:space=\"preserve\">\r\n    <value>The publisher requires that you view the above information and accept the agreements before installing.\r\nDo you agree to the terms?</value>\r\n  </data>\r\n  <data name=\"PackageAgreementsNotAgreedTo\" xml:space=\"preserve\">\r\n    <value>Package agreements were not agreed to. Operation cancelled.</value>\r\n  </data>\r\n  <data name=\"ShowLabelAgreements\" xml:space=\"preserve\">\r\n    <value>Agreements:</value>\r\n  </data>\r\n  <data name=\"ShowLabelAuthor\" xml:space=\"preserve\">\r\n    <value>Author:</value>\r\n  </data>\r\n  <data name=\"ShowLabelDescription\" xml:space=\"preserve\">\r\n    <value>Description:</value>\r\n  </data>\r\n  <data name=\"ShowLabelInstaller\" xml:space=\"preserve\">\r\n    <value>Installer:</value>\r\n  </data>\r\n  <data name=\"ShowLabelInstallerLocale\" xml:space=\"preserve\">\r\n    <value>Installer Locale:</value>\r\n  </data>\r\n  <data name=\"ShowLabelInstallerProductId\" xml:space=\"preserve\">\r\n    <value>Store Product Id:</value>\r\n  </data>\r\n  <data name=\"ShowLabelInstallerSha256\" xml:space=\"preserve\">\r\n    <value>Installer SHA256:</value>\r\n  </data>\r\n  <data name=\"ShowLabelInstallerType\" xml:space=\"preserve\">\r\n    <value>Installer Type:</value>\r\n  </data>\r\n  <data name=\"ShowLabelInstallerUrl\" xml:space=\"preserve\">\r\n    <value>Installer Url:</value>\r\n  </data>\r\n  <data name=\"ShowLabelLicense\" xml:space=\"preserve\">\r\n    <value>License:</value>\r\n  </data>\r\n  <data name=\"ShowLabelLicenseUrl\" xml:space=\"preserve\">\r\n    <value>License Url:</value>\r\n  </data>\r\n  <data name=\"ShowLabelMoniker\" xml:space=\"preserve\">\r\n    <value>Moniker:</value>\r\n  </data>\r\n  <data name=\"ShowLabelPackageUrl\" xml:space=\"preserve\">\r\n    <value>Homepage:</value>\r\n  </data>\r\n  <data name=\"ShowLabelPublisher\" xml:space=\"preserve\">\r\n    <value>Publisher:</value>\r\n  </data>\r\n  <data name=\"ShowLabelTags\" xml:space=\"preserve\">\r\n    <value>Tags:</value>\r\n  </data>\r\n  <data name=\"ShowLabelVersion\" xml:space=\"preserve\">\r\n    <value>Version:</value>\r\n  </data>\r\n  <data name=\"ShowLabelDependencies\" xml:space=\"preserve\">\r\n    <value>Dependencies:</value>\r\n  </data>\r\n  <data name=\"ShowLabelWindowsFeaturesDependencies\" xml:space=\"preserve\">\r\n    <value>Windows Features:</value>\r\n  </data>\r\n  <data name=\"ShowLabelWindowsLibrariesDependencies\" xml:space=\"preserve\">\r\n    <value>Windows Libraries:</value>\r\n  </data>\r\n  <data name=\"ShowLabelPackageDependencies\" xml:space=\"preserve\">\r\n    <value>Package Dependencies:</value>\r\n  </data>\r\n  <data name=\"ShowLabelExternalDependencies\" xml:space=\"preserve\">\r\n    <value>External Dependencies:</value>\r\n  </data>\r\n  <data name=\"PromptOptionNo\" xml:space=\"preserve\">\r\n    <value>No</value>\r\n  </data>\r\n  <data name=\"PromptOptionYes\" xml:space=\"preserve\">\r\n    <value>Yes</value>\r\n  </data>\r\n  <data name=\"SourceAddOpenSourceFailed\" xml:space=\"preserve\">\r\n    <value>Failed to open the added source.</value>\r\n  </data>\r\n  <data name=\"AcceptSourceAgreementsArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Accept all source agreements during source operations</value>\r\n  </data>\r\n  <data name=\"SourceAgreementsTitle\" xml:space=\"preserve\">\r\n    <value>The `{0}` source requires that you view the following agreements before using.</value>\r\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user that a repository source requires viewing agreements before using. {0} is a placeholder replaced by the repository source name.</comment>\r\n  </data>\r\n  <data name=\"SourceAgreementsPrompt\" xml:space=\"preserve\">\r\n    <value>Do you agree to all the source agreements terms?</value>\r\n  </data>\r\n  <data name=\"SourceAgreementsNotAgreedTo\" xml:space=\"preserve\">\r\n    <value>One or more of the source agreements were not agreed to. Operation cancelled. Please accept the source agreements or remove the corresponding sources.</value>\r\n  </data>\r\n  <data name=\"SourceAgreementsMarketMessage\" xml:space=\"preserve\">\r\n    <value>The source requires the current machine's 2-letter geographic region to be sent to the backend service to function properly (ex. \"US\").</value>\r\n  </data>\r\n  <data name=\"InstallFlowRegistrationDeferred\" xml:space=\"preserve\">\r\n    <value>Successfully installed. Restart the application to complete the upgrade.</value>\r\n  </data>\r\n  <data name=\"HeaderArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Optional Windows-Package-Manager REST source HTTP header</value>\r\n  </data>\r\n  <data name=\"HeaderArgumentNotApplicableForNonRestSourceWarning\" xml:space=\"preserve\">\r\n    <value>Ignoring the optional header as it is not applicable for this source.</value>\r\n  </data>\r\n  <data name=\"HeaderArgumentNotApplicableWithoutSource\" xml:space=\"preserve\">\r\n    <value>The optional header is not applicable without specifying a source: '{0}'</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user performs an operation (e.g install) and provides the HTTP 'header' argument without specifying the repository source. {0} is a placeholder replaced by the header argument name.</comment>\r\n  </data>\r\n  <data name=\"ShowLabelInstallerReleaseDate\" xml:space=\"preserve\">\r\n    <value>Release Date:</value>\r\n  </data>\r\n  <data name=\"ShowLabelInstallerOfflineDistributionSupported\" xml:space=\"preserve\">\r\n    <value>Offline Distribution Supported:</value>\r\n  </data>\r\n  <data name=\"ShowLabelPublisherUrl\" xml:space=\"preserve\">\r\n    <value>Publisher Url:</value>\r\n  </data>\r\n  <data name=\"ShowLabelPurchaseUrl\" xml:space=\"preserve\">\r\n    <value>Purchase Url:</value>\r\n  </data>\r\n  <data name=\"ShowLabelPublisherSupportUrl\" xml:space=\"preserve\">\r\n    <value>Publisher Support Url:</value>\r\n  </data>\r\n  <data name=\"ShowLabelPrivacyUrl\" xml:space=\"preserve\">\r\n    <value>Privacy Url:</value>\r\n  </data>\r\n  <data name=\"ShowLabelCopyright\" xml:space=\"preserve\">\r\n    <value>Copyright:</value>\r\n  </data>\r\n  <data name=\"ShowLabelCopyrightUrl\" xml:space=\"preserve\">\r\n    <value>Copyright Url:</value>\r\n  </data>\r\n  <data name=\"ShowLabelReleaseNotes\" xml:space=\"preserve\">\r\n    <value>Release Notes:</value>\r\n  </data>\r\n  <data name=\"ShowLabelReleaseNotesUrl\" xml:space=\"preserve\">\r\n    <value>Release Notes Url:</value>\r\n  </data>\r\n  <data name=\"SearchFailureWarning\" xml:space=\"preserve\">\r\n    <value>Failed when searching source; results will not be included: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Warning message displayed when searching a repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\r\n  </data>\r\n  <data name=\"SearchFailureError\" xml:space=\"preserve\">\r\n    <value>Failed when searching source: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when searching a repository source fails. {0} is a placeholder replaced by the repository source name.</comment>\r\n  </data>\r\n  <data name=\"FeatureDisabledByAdminSettingMessage\" xml:space=\"preserve\">\r\n    <value>This feature needs to be enabled by administrators. To enable it, run 'winget settings --enable {0}' as administrator.</value>\r\n    <comment>{Locked=\"winget settings --enable\", \"{0}\"}. Error message displayed when the user uses a feature that needs to be enabled by administrators. {0} is a placeholder replaced by the admin setting.</comment>\r\n  </data>\r\n  <data name=\"AdminSettingEnableDescription\" xml:space=\"preserve\">\r\n    <value>Enables the specific administrator setting</value>\r\n  </data>\r\n  <data name=\"AdminSettingDisableDescription\" xml:space=\"preserve\">\r\n    <value>Disables the specific administrator setting</value>\r\n  </data>\r\n  <data name=\"AdminSettingEnabled\" xml:space=\"preserve\">\r\n    <value>Enabled admin setting '{0}'.</value>\r\n    <comment>{Locked=\"{0}\"} Message displayed when the user enables an admin setting. {0} is a placeholder replaced by the setting name.</comment>\r\n  </data>\r\n  <data name=\"AdminSettingDisabled\" xml:space=\"preserve\">\r\n    <value>Disabled admin setting '{0}'.</value>\r\n    <comment>{Locked=\"{0}\"} Message displayed when the user disables an admin setting. {0} is a placeholder replaced by the setting name.</comment>\r\n  </data>\r\n  <data name=\"AdminSettingHeader\" xml:space=\"preserve\">\r\n    <value>Admin Setting</value>\r\n    <comment>Header for a table displaying admin settings.</comment>\r\n  </data>\r\n  <data name=\"InstallFlowReturnCodePackageInUse\" xml:space=\"preserve\">\r\n    <value>Application is currently running. Exit the application then try again.</value>\r\n  </data>\r\n  <data name=\"InstallFlowReturnCodePackageInUseByApplication\" xml:space=\"preserve\">\r\n    <value>Files modified by the installer are currently in use by a different application. Exit the applications then try again.</value>\r\n  </data>\r\n  <data name=\"InstallFlowReturnCodeInstallInProgress\" xml:space=\"preserve\">\r\n    <value>Another installation is already in progress. Try again later.</value>\r\n  </data>\r\n  <data name=\"InstallFlowReturnCodeFileInUse\" xml:space=\"preserve\">\r\n    <value>One or more files are being used. Exit the application then try again.</value>\r\n  </data>\r\n  <data name=\"InstallFlowReturnCodeMissingDependency\" xml:space=\"preserve\">\r\n    <value>This package has a dependency missing from your system.</value>\r\n  </data>\r\n  <data name=\"InstallFlowReturnCodeDiskFull\" xml:space=\"preserve\">\r\n    <value>There's no more space on your PC. Make space, then try again.</value>\r\n  </data>\r\n  <data name=\"InstallFlowReturnCodeInsufficientMemory\" xml:space=\"preserve\">\r\n    <value>There's not enough memory available to install. Close other applications then try again.</value>\r\n  </data>\r\n  <data name=\"InstallFlowReturnCodeInvalidParameter\" xml:space=\"preserve\">\r\n    <value>One of the installation parameters is invalid. The package installation log may have additional details.</value>\r\n  </data>\r\n  <data name=\"InstallFlowReturnCodeNoNetwork\" xml:space=\"preserve\">\r\n    <value>This application requires internet connectivity. Connect to a network then try again.</value>\r\n  </data>\r\n  <data name=\"InstallFlowReturnCodeContactSupport\" xml:space=\"preserve\">\r\n    <value>This application encountered an error during installation. Contact support.</value>\r\n  </data>\r\n  <data name=\"InstallFlowReturnCodeRebootRequiredToFinish\" xml:space=\"preserve\">\r\n    <value>Restart your PC to finish installation.</value>\r\n  </data>\r\n  <data name=\"InstallFlowReturnCodeRebootRequiredForInstall\" xml:space=\"preserve\">\r\n    <value>Your PC will restart to finish installation.</value>\r\n  </data>\r\n  <data name=\"InstallFlowReturnCodeRebootInitiated\" xml:space=\"preserve\">\r\n    <value>Installation failed. Restart your PC then try again.</value>\r\n  </data>\r\n  <data name=\"InstallFlowReturnCodeCancelledByUser\" xml:space=\"preserve\">\r\n    <value>You cancelled the installation.</value>\r\n  </data>\r\n  <data name=\"InstallFlowReturnCodeAlreadyInstalled\" xml:space=\"preserve\">\r\n    <value>Another version of this application is already installed.</value>\r\n  </data>\r\n  <data name=\"InstallFlowReturnCodeDowngrade\" xml:space=\"preserve\">\r\n    <value>A higher version of this application is already installed.</value>\r\n  </data>\r\n  <data name=\"InstallFlowReturnCodeBlockedByPolicy\" xml:space=\"preserve\">\r\n    <value>Organization policies are preventing installation. Contact your admin.</value>\r\n  </data>\r\n  <data name=\"InstallFlowReturnCodeSystemNotSupported\" xml:space=\"preserve\">\r\n    <value>The current system configuration does not support the installation of this package.</value>\r\n  </data>\r\n  <data name=\"InstallFlowReturnCodeCustomError\" xml:space=\"preserve\">\r\n    <value>Installation failed with a custom installer error. Contact package support.</value>\r\n  </data>\r\n  <data name=\"InstallAbandoned\" xml:space=\"preserve\">\r\n    <value>Installation abandoned</value>\r\n  </data>\r\n  <data name=\"InstallerFailedWithCode\" xml:space=\"preserve\">\r\n    <value>Installer failed with exit code: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the application installer fails. {0} is a placeholder replaced by an error code.</comment>\r\n  </data>\r\n  <data name=\"InstallerLogAvailable\" xml:space=\"preserve\">\r\n    <value>Installer log is available at: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Message displayed to inform the user about the system path of a diagnostic files containing information about the installer. {0} is a placeholder replaced by the diagnostic file system path.</comment>\r\n  </data>\r\n  <data name=\"SearchFailureErrorListMatches\" xml:space=\"preserve\">\r\n    <value>The following packages were found among the working sources.\r\nPlease specify one of them using the --source option to proceed.</value>\r\n    <comment>{Locked=\"--source\"} \"working sources\" as in \"sources that are working correctly\"</comment>\r\n  </data>\r\n  <data name=\"SearchFailureErrorNoMatches\" xml:space=\"preserve\">\r\n    <value>No packages were found among the working sources.</value>\r\n    <comment>\"working sources\" as in \"sources that are working correctly\"</comment>\r\n  </data>\r\n  <data name=\"FeaturesMessageDisabledByBuild\" xml:space=\"preserve\">\r\n    <value>This is a stable release of the Windows Package Manager. If you would like to try experimental features, please install a pre-release build. Instructions are available on GitHub at https://github.com/microsoft/winget-cli.</value>\r\n    <comment>{Locked=\"https://github.com/microsoft/winget-cli\"}</comment>\r\n  </data>\r\n  <data name=\"WindowsPackageManager\" xml:space=\"preserve\">\r\n    <value>Windows Package Manager v{0}</value>\r\n    <comment>{Locked=\"{0}\"} Label displaying the product name and version. {0} is a placeholder replaced by the product version.</comment>\r\n  </data>\r\n  <data name=\"ImportIgnorePackageVersionsArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Ignore package versions in import file</value>\r\n  </data>\r\n  <data name=\"CountOutOfBoundsError\" xml:space=\"preserve\">\r\n    <value>The requested number of results must be between 1 and 1000.</value>\r\n  </data>\r\n  <data name=\"CustomSwitchesArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Arguments to be passed on to the installer in addition to the defaults</value>\r\n  </data>\r\n  <data name=\"UpgradeDifferentInstallTechnologyInNewerVersions\" xml:space=\"preserve\">\r\n    <value>A newer version was found, but the install technology is different from the current version installed. Please uninstall the package and install the newer version.</value>\r\n  </data>\r\n  <data name=\"UpgradeDifferentInstallTechnology\" xml:space=\"preserve\">\r\n    <value>The install technology of the newer version specified is different from the current version installed. Please uninstall the package and install the newer version.</value>\r\n  </data>\r\n  <data name=\"WindowsPackageManagerPreview\" xml:space=\"preserve\">\r\n    <value>Windows Package Manager (Preview) v{0}</value>\r\n    <comment>{Locked=\"{0}\"} Label displaying the preview product name and pre-release version. {0} is a placeholder replaced by the product version.</comment>\r\n  </data>\r\n  <data name=\"ArchitectureArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Select the architecture</value>\r\n  </data>\r\n  <data name=\"IncludeUnknownArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Upgrade packages even if their current version cannot be determined</value>\r\n  </data>\r\n  <data name=\"IncludeUnknownInListArgumentDescription\" xml:space=\"preserve\">\r\n    <value>List packages even if their current version cannot be determined. Can only be used with the --upgrade-available argument</value>\r\n    <comment>{Locked=\"--upgrade-available\"}</comment>\r\n  </data>\r\n  <data name=\"UpgradeUnknownVersionExplanation\" xml:space=\"preserve\">\r\n    <value>This package's version number cannot be determined. To upgrade it anyway, add the argument --include-unknown to your previous command.</value>\r\n    <comment>{Locked=\"--include-unknown\"}</comment>\r\n  </data>\r\n  <data name=\"UpgradeUnknownVersionCount\" xml:space=\"preserve\">\r\n    <value>{0} package(s) have version numbers that cannot be determined. Use --include-unknown to see all results.</value>\r\n    <comment>{Locked=\"{0}\",\"--include-unknown\"} {0} is a placeholder that is replaced by an integer number of packages that do not have notated versions. </comment>\r\n  </data>\r\n  <data name=\"UpgradeRequireExplicitCount\" xml:space=\"preserve\">\r\n    <value>{0} package(s) are pinned and need to be explicitly upgraded.</value>\r\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by an integer number of packages that require explicit upgrades.</comment>\r\n  </data>\r\n  <data name=\"InvalidArgumentWithoutQueryError\" xml:space=\"preserve\">\r\n    <value>The arguments provided can only be used with a query.</value>\r\n  </data>\r\n  <data name=\"SystemArchitecture\" xml:space=\"preserve\">\r\n    <value>System Architecture: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Label displayed for the system architecture. {0} is a placeholder replaced by the value of the system architecture (e.g. X64).</comment>\r\n  </data>\r\n  <data name=\"PreserveArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Retains all files and directories created by the package (portable)</value>\r\n  </data>\r\n  <data name=\"PurgeArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Deletes all files and directories in the package directory (portable)</value>\r\n  </data>\r\n  <data name=\"PressEnterToContinue\" xml:space=\"preserve\">\r\n    <value>Press Enter to continue . . .</value>\r\n  </data>\r\n  <data name=\"RenameArgumentDescription\" xml:space=\"preserve\">\r\n    <value>The value to rename the executable file (portable)</value>\r\n  </data>\r\n  <data name=\"WaitArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Prompts the user to press any key before exiting</value>\r\n  </data>\r\n  <data name=\"InstallerElevationExpected\" xml:space=\"preserve\">\r\n    <value>The installer will request to run as administrator. Expect a prompt.</value>\r\n  </data>\r\n  <data name=\"InstallerProhibitsElevation\" xml:space=\"preserve\">\r\n    <value>The installer cannot be run from an administrator context.</value>\r\n  </data>\r\n  <data name=\"ModifiedPathRequiresShellRestart\" xml:space=\"preserve\">\r\n    <value>Path environment variable modified; restart your shell to use the new value.</value>\r\n  </data>\r\n  <data name=\"ProductCodeArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Filters using the product code</value>\r\n  </data>\r\n  <data name=\"PortableRegistryCollisionOverridden\" xml:space=\"preserve\">\r\n    <value>A portable package with the same name but from a different source already exists; proceeding due to --force</value>\r\n    <comment>{Locked=\"--force\"}</comment>\r\n  </data>\r\n  <data name=\"ReparsePointsNotSupportedError\" xml:space=\"preserve\">\r\n    <value>The volume does not support reparse points</value>\r\n  </data>\r\n  <data name=\"ReservedFilenameError\" xml:space=\"preserve\">\r\n    <value>The specified filename is not a valid filename</value>\r\n  </data>\r\n  <data name=\"OverwritingExistingFileAtMessage\" xml:space=\"preserve\">\r\n    <value>Overwriting existing file: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Warning message displayed to inform the user that an existing file is being overwritten. {0} is a placeholder replaced by the file system path.</comment>\r\n  </data>\r\n  <data name=\"NoPackageSelectionArgumentProvided\" xml:space=\"preserve\">\r\n    <value>No package selection argument was provided; see the help for details about finding a package.</value>\r\n  </data>\r\n  <data name=\"PortableAliasAdded\" xml:space=\"preserve\">\r\n    <value>Command line alias added:</value>\r\n  </data>\r\n  <data name=\"PortableLinksMachine\" xml:space=\"preserve\">\r\n    <value>Portable Links Directory (Machine)</value>\r\n  </data>\r\n  <data name=\"PortableLinksUser\" xml:space=\"preserve\">\r\n    <value>Portable Links Directory (User)</value>\r\n  </data>\r\n  <data name=\"PortableRootUser\" xml:space=\"preserve\">\r\n    <value>Portable Package Root (User)</value>\r\n  </data>\r\n  <data name=\"PortableRoot\" xml:space=\"preserve\">\r\n    <value>Portable Package Root</value>\r\n  </data>\r\n  <data name=\"PortableRoot86\" xml:space=\"preserve\">\r\n    <value>Portable Package Root (x86)</value>\r\n  </data>\r\n  <data name=\"PortableInstallFailed\" xml:space=\"preserve\">\r\n    <value>Portable install failed; Cleaning up...</value>\r\n  </data>\r\n  <data name=\"PortableHashMismatchOverridden\" xml:space=\"preserve\">\r\n    <value>Portable package has been modified; proceeding due to --force</value>\r\n    <comment>{Locked=\"--force\"}</comment>\r\n  </data>\r\n  <data name=\"PortableHashMismatchOverrideRequired\" xml:space=\"preserve\">\r\n    <value>Unable to remove Portable package as it has been modified; to override this check use --force</value>\r\n    <comment>{Locked=\"--force\"}</comment>\r\n  </data>\r\n  <data name=\"FilesRemainInInstallDirectory\" xml:space=\"preserve\">\r\n    <value>Files remain in install directory: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Warning message displayed when files remain in install directory. {0} is a placeholder replaced by the directory path.</comment>\r\n  </data>\r\n  <data name=\"PurgeInstallDirectory\" xml:space=\"preserve\">\r\n    <value>Purging install directory...</value>\r\n  </data>\r\n  <data name=\"UnableToPurgeInstallDirectory\" xml:space=\"preserve\">\r\n    <value>Cannot purge install directory as it was not created by WinGet</value>\r\n    <comment>{Locked=\"WinGet\"}</comment>\r\n  </data>\r\n  <data name=\"RelatedLink\" xml:space=\"preserve\">\r\n    <value>Related Link</value>\r\n  </data>\r\n  <data name=\"ShowLabelDocumentation\" xml:space=\"preserve\">\r\n    <value>Documentation:</value>\r\n  </data>\r\n  <data name=\"Notes\" xml:space=\"preserve\">\r\n    <value>Notes: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Label displayed for installation notes. {0} is a placeholder replaced by installation notes.</comment>\r\n  </data>\r\n  <data name=\"ShowLabelInstallationNotes\" xml:space=\"preserve\">\r\n    <value>Installation Notes:</value>\r\n  </data>\r\n  <data name=\"UnsupportedArgument\" xml:space=\"preserve\">\r\n    <value>A provided argument is not supported for this package</value>\r\n  </data>\r\n  <data name=\"ExtractArchiveFailed\" xml:space=\"preserve\">\r\n    <value>Failed to extract the contents of the archive</value>\r\n  </data>\r\n  <data name=\"NestedInstallerNotFound\" xml:space=\"preserve\">\r\n    <value>Nested installer file does not exist. Ensure the specified relative path of the nested installer matches: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when nested installer file does not exist. {0} is a placeholder replaced by the nested installer file path.</comment>\r\n  </data>\r\n  <data name=\"InvalidPathToNestedInstaller\" xml:space=\"preserve\">\r\n    <value>Invalid relative file path to the nested installer; path points to a location outside of the install directory</value>\r\n  </data>\r\n  <data name=\"NestedInstallerNotSpecified\" xml:space=\"preserve\">\r\n    <value>No nested installers specified for this package</value>\r\n  </data>\r\n  <data name=\"MultipleUnsupportedNestedInstallersSpecified\" xml:space=\"preserve\">\r\n    <value>Only one nested installer can be specified for an archive installer unless it is a portable or font nested installer</value>\r\n  </data>\r\n  <data name=\"IncompatibleArgumentsProvided\" xml:space=\"preserve\">\r\n    <value>Incompatible command line arguments provided</value>\r\n  </data>\r\n  <data name=\"UpgradeArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Lists only packages which have an upgrade available</value>\r\n  </data>\r\n  <data name=\"UpgradeAvailableForPinned\" xml:space=\"preserve\">\r\n    <value>The following packages have an upgrade available, but require explicit targeting for upgrade:</value>\r\n    <comment>\"require explicit targeting for upgrade\" means that the package will not be upgraded with all others unless an extra flag is added, or the package is mentioned explicitly</comment>\r\n  </data>\r\n  <data name=\"Downloading\" xml:space=\"preserve\">\r\n    <value>Downloading</value>\r\n    <comment>Label displayed while downloading an application installer.</comment>\r\n  </data>\r\n  <data name=\"NestedInstallerNotSupported\" xml:space=\"preserve\">\r\n    <value>The nested installer type is not supported</value>\r\n  </data>\r\n  <data name=\"InstallerAbortsTerminal\" xml:space=\"preserve\">\r\n    <value>This installer is known to restart the terminal or shell</value>\r\n  </data>\r\n  <data name=\"InstallerRequiresInstallLocation\" xml:space=\"preserve\">\r\n    <value>This package requires an install location</value>\r\n  </data>\r\n  <data name=\"InstallersAbortTerminal\" xml:space=\"preserve\">\r\n    <value>The following installers are known to restart the terminal or shell:</value>\r\n  </data>\r\n  <data name=\"InstallersRequireInstallLocation\" xml:space=\"preserve\">\r\n    <value>The following installers require an install location:</value>\r\n  </data>\r\n  <data name=\"PromptForInstallRoot\" xml:space=\"preserve\">\r\n    <value>Specify the install root:</value>\r\n  </data>\r\n  <data name=\"PromptToProceed\" xml:space=\"preserve\">\r\n    <value>Do you want to proceed?</value>\r\n  </data>\r\n  <data name=\"ReportIdentityForAgreements\" xml:space=\"preserve\">\r\n    <value>Agreements for</value>\r\n    <comment>This will be followed by a package name, and then a list of license agreements</comment>\r\n  </data>\r\n  <data name=\"InstallLocationNotProvided\" xml:space=\"preserve\">\r\n    <value>Install location is required by the package but it was not provided</value>\r\n  </data>\r\n  <data name=\"DisableInteractivityArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Disable interactive prompts</value>\r\n    <comment>Description for a command line argument, shown next to it in the help</comment>\r\n  </data>\r\n  <data name=\"ConvertInstallFlowToUpgrade\" xml:space=\"preserve\">\r\n    <value>Found an existing package already installed. Trying to upgrade the installed package...</value>\r\n  </data>\r\n  <data name=\"ForceArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Direct run the command and continue with non security related issues</value>\r\n    <comment>Description for a command line argument, shown next to it in the help</comment>\r\n  </data>\r\n  <data name=\"PortablePackageAlreadyExists\" xml:space=\"preserve\">\r\n    <value>Portable package from a different source already exists</value>\r\n  </data>\r\n  <data name=\"ExtractArchiveSucceeded\" xml:space=\"preserve\">\r\n    <value>Successfully extracted archive</value>\r\n  </data>\r\n  <data name=\"ExtractingArchive\" xml:space=\"preserve\">\r\n    <value>Extracting archive...</value>\r\n  </data>\r\n  <data name=\"ArchiveFailedMalwareScan\" xml:space=\"preserve\">\r\n    <value>Archive scan detected malware. To override this check use --ignore-local-archive-malware-scan</value>\r\n    <comment>{Locked=\"--ignore-local-archive-malware-scan\"}</comment>\r\n  </data>\r\n  <data name=\"ArchiveFailedMalwareScanOverridden\" xml:space=\"preserve\">\r\n    <value>Archive scan detected malware. Proceeding due to --ignore-local-archive-malware-scan</value>\r\n    <comment>{Locked=\"--ignore-local-archive-malware-scan\"}</comment>\r\n  </data>\r\n  <data name=\"NoUpgradeArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Skips upgrade if an installed version already exists</value>\r\n  </data>\r\n  <data name=\"PackageAlreadyInstalled\" xml:space=\"preserve\">\r\n    <value>A package version is already installed. Installation cancelled.</value>\r\n  </data>\r\n  <data name=\"EnableAdminSettingFailed\" xml:space=\"preserve\">\r\n    <value>Cannot enable {0}. This setting is controlled by policy. For more information contact your system administrator.</value>\r\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\r\n  </data>\r\n  <data name=\"DisableAdminSettingFailed\" xml:space=\"preserve\">\r\n    <value>Cannot disable {0}. This setting is controlled by policy. For more information contact your system administrator.</value>\r\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\r\n  </data>\r\n  <data name=\"PinAddCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Add a new pin. A pin can limit the Windows Package Manager from upgrade a package to specific ranges of versions, or it can prevent it from upgrading the package altogether. A pinned package may still upgrade on its own and be upgraded from outside the Windows Package Manager. By default, a pinned package can be upgraded by mentioning it explicitly in the 'upgrade' command or by adding the '--include-pinned' flag to 'winget upgrade --all'.</value>\r\n    <comment>{Locked{\"'upgrade'\"} Locked{\"--include-pinned\"} Locked{\"winget upgrade --all\"}</comment>\r\n  </data>\r\n  <data name=\"PinAddCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Add a new pin</value>\r\n  </data>\r\n  <data name=\"PinCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Manage package pins with the sub-commands. A pin can limit the Windows Package Manager from upgrading a package to specific ranges of versions, or it can prevent it from upgrading the package altogether. A pinned package may still upgrade on its own and be upgraded from outside the Windows Package Manager.</value>\r\n  </data>\r\n  <data name=\"PinCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Manage package pins</value>\r\n  </data>\r\n  <data name=\"PinListCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>List all current pins, or full details of a specific pin.</value>\r\n  </data>\r\n  <data name=\"PinListCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>List current pins</value>\r\n  </data>\r\n  <data name=\"PinRemoveCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Remove a specific package pin.</value>\r\n  </data>\r\n  <data name=\"PinRemoveCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Remove a package pin</value>\r\n  </data>\r\n  <data name=\"PinResetCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Reset all existing pins.</value>\r\n  </data>\r\n  <data name=\"PinResetCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Reset pins</value>\r\n  </data>\r\n  <data name=\"GatedVersionArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Version to which to pin the package. The wildcard '*' can be used as the last version part</value>\r\n  </data>\r\n  <data name=\"PinAddBlockingArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Block from upgrading until the pin is removed, preventing override arguments</value>\r\n  </data>\r\n  <data name=\"PinInstalledArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Pin a specific installed version</value>\r\n  </data>\r\n  <data name=\"PinInstalledSource\" xml:space=\"preserve\">\r\n    <value>Installed</value>\r\n    <comment>Value used in a table to indicate that a package comes from the list of packages installed in the machine</comment>\r\n  </data>\r\n  <data name=\"SettingsExportCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Export settings as JSON</value>\r\n  </data>\r\n  <data name=\"SettingsExportCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Export settings</value>\r\n  </data>\r\n  <data name=\"UserSettings\" xml:space=\"preserve\">\r\n    <value>User Settings</value>\r\n    <comment>Label displayed for the file containing the user settings.</comment>\r\n  </data>\r\n  <data name=\"SettingsWarningUsingDefault\" xml:space=\"preserve\">\r\n    <value>Settings file couldn't load. Using default values.</value>\r\n  </data>\r\n  <data name=\"InstalledScopeArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Select installed package scope filter (user or machine)</value>\r\n    <comment>{Locked=\"user\",\"machine\"} This argument allows the user to select installed packages for just the user or for the entire machine.</comment>\r\n  </data>\r\n  <data name=\"PinAdded\" xml:space=\"preserve\">\r\n    <value>Pin added successfully</value>\r\n  </data>\r\n  <data name=\"PinAlreadyExists\" xml:space=\"preserve\">\r\n    <value>There is already a pin for package {0}</value>\r\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that will be replaced by a package name. The message is shown when attempting to add a pin for a package that is already pinned.</comment>\r\n  </data>\r\n  <data name=\"PinExistsOverwriting\" xml:space=\"preserve\">\r\n    <value>A pin already exists for package {0}. Overwriting due to the --force argument.</value>\r\n    <comment>{Locked=\"--force\"}{Locked=\"--force\",\"{0}\"} {0} is a placeholder that will be replaced by a package name.</comment>\r\n  </data>\r\n  <data name=\"PinExistsUseForceArg\" xml:space=\"preserve\">\r\n    <value>A pin already exists for package {0}. Use the --force argument to overwrite it.</value>\r\n    <comment>{Locked=\"--force\",\"{0}\"} {0} is a placeholder that will be replaced by a package name.</comment>\r\n  </data>\r\n  <data name=\"PinResettingAll\" xml:space=\"preserve\">\r\n    <value>Resetting all current pins.</value>\r\n  </data>\r\n  <data name=\"PinResetUseForceArg\" xml:space=\"preserve\">\r\n    <value>Use the --force argument to reset all pins. The following pins would be removed:</value>\r\n    <comment>{Locked=\"--force\"}</comment>\r\n  </data>\r\n  <data name=\"PinType\" xml:space=\"preserve\">\r\n    <value>Pin type</value>\r\n  </data>\r\n  <data name=\"PinDoesNotExist\" xml:space=\"preserve\">\r\n    <value>There is no pin for package {0}</value>\r\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that will be replaced by a package name. The message is shown when attempting to delete a pin for a package that is not pinned.</comment>\r\n  </data>\r\n  <data name=\"PinNoPinsExist\" xml:space=\"preserve\">\r\n    <value>There are no pins configured.</value>\r\n    <comment>Shown when listing or modifying existing pins if there are none.</comment>\r\n  </data>\r\n  <data name=\"PinResetSuccessful\" xml:space=\"preserve\">\r\n    <value>Pins reset successfully</value>\r\n    <comment>Shown after resetting (deleting) all the pins</comment>\r\n  </data>\r\n  <data name=\"PinCannotOpenIndex\" xml:space=\"preserve\">\r\n    <value>Unable to open pin database.</value>\r\n    <comment>Error message for when we cannot open the database containing package pins.</comment>\r\n  </data>\r\n  <data name=\"ArgumentForSinglePackageProvidedWithMultipleQueries\" xml:space=\"preserve\">\r\n    <value>An argument was provided that can only be used for single package</value>\r\n  </data>\r\n  <data name=\"MultipleExclusiveArgumentsProvided\" xml:space=\"preserve\">\r\n    <value>Multiple mutually exclusive arguments provided: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message shown when mutually incompatible command line arguments are used. {0} is a placeholder replaced by the arguments that cannot be specified together</comment>\r\n  </data>\r\n  <data name=\"DependencyArgumentMissing\" xml:space=\"preserve\">\r\n    <value>Argument {0} can only be used with {1}</value>\r\n    <comment>{Locked=\"{0}\",\"{1}\"} Error message shown when having an argument needs another to be present, but that is missing. {0} and {1} are replaced by the arguments. For example \"Argument --include-unknown can only be used with --upgrade\"</comment>\r\n  </data>\r\n  <data name=\"StateDisabled\" xml:space=\"preserve\">\r\n    <value>Disabled</value>\r\n    <comment>As in enabled/disabled</comment>\r\n  </data>\r\n  <data name=\"StateEnabled\" xml:space=\"preserve\">\r\n    <value>Enabled</value>\r\n    <comment>As in enabled/disabled</comment>\r\n  </data>\r\n  <data name=\"StateHeader\" xml:space=\"preserve\">\r\n    <value>State</value>\r\n    <comment>Header for a table listing the state (enabled/disabled) of Group Policies and Settings</comment>\r\n  </data>\r\n  <data name=\"MultiQueryArgumentDescription\" xml:space=\"preserve\">\r\n    <value>The query used to search for a package</value>\r\n  </data>\r\n  <data name=\"MultiQueryPackageNotFound\" xml:space=\"preserve\">\r\n    <value>Package not found: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches returns no results. {0} is a placeholder replaced by the package name or query.</comment>\r\n  </data>\r\n  <data name=\"MultiQuerySearchFoundMultiple\" xml:space=\"preserve\">\r\n    <value>Multiple packages found for: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches returns more than one result. {0} is a placeholder replaced by the package name or query.</comment>\r\n  </data>\r\n  <data name=\"MultiQuerySearchFailed\" xml:space=\"preserve\">\r\n    <value>Search failed for: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user attempts to search for multiple application packages and one of the searches fails. This message is for generic failures, we have more specific messages for when the search returns no results, or when it returns more than one result. {0} is a placeholder replaced by the package name or query.</comment>\r\n  </data>\r\n  <data name=\"UpgradeBlockedByPinCount\" xml:space=\"preserve\">\r\n    <value>{0} package(s) have a pin that needs to be removed before upgrade</value>\r\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by an integer number of packages with pins that prevent upgrade</comment>\r\n  </data>\r\n  <data name=\"UpgradeBlockedByManifest\" xml:space=\"preserve\">\r\n    <value>The package cannot be upgraded using WinGet. Please use the method provided by the publisher for upgrading this package.</value>\r\n    <comment>{Locked=\"WinGet\"}</comment>\r\n  </data>\r\n  <data name=\"IncludePinnedArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Upgrade packages even if they have a non-blocking pin</value>\r\n  </data>\r\n  <data name=\"IncludePinnedInListArgumentDescription\" xml:space=\"preserve\">\r\n    <value>List packages even if they have a pin that prevents upgrade. Can only be used with the --upgrade-available argument</value>\r\n    <comment>{Locked=\"--upgrade-available\"}</comment>\r\n  </data>\r\n  <data name=\"PinRemovedSuccessfully\" xml:space=\"preserve\">\r\n    <value>Pin removed successfully</value>\r\n  </data>\r\n  <data name=\"UpgradeIsPinned\" xml:space=\"preserve\">\r\n    <value>A newer version was found, but the package has a pin that prevents from upgrading it.</value>\r\n  </data>\r\n  <data name=\"PackageIsPinned\" xml:space=\"preserve\">\r\n    <value>The package is pinned and cannot be upgraded. Use the 'winget pin' command to view and edit pins. Some pin types can be bypassed with the --include-pinned argument.</value>\r\n    <comment>{Locked=\"winget pin\",\"--include-pinned\"} Error shown when we block an upgrade due to the package being pinned</comment>\r\n  </data>\r\n  <data name=\"UpgradePinnedByUserCount\" xml:space=\"preserve\">\r\n    <value>{0} package(s) have pins that prevent upgrade. Use the 'winget pin' command to view and edit pins. Using the '--include-pinned' argument may show more results.</value>\r\n    <comment>{Locked=\"winget pin\",\"--include-pinned\"} {0} is a placeholder replaced by an integer number of packages</comment>\r\n  </data>\r\n  <data name=\"ConfigureCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Ensures that the system matches the desired state as described by the provided configuration. May download/execute processors in order to achieve the desired state. The configuration and the processors should be checked to ensure that they are trustworthy before applying them.</value>\r\n  </data>\r\n  <data name=\"ConfigureCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Configures the system into a desired state</value>\r\n  </data>\r\n  <data name=\"ConfigureShowCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Shows details of the provided configuration. By default, will not modify the system, but some options will cause files to be downloaded and/or loaded.</value>\r\n  </data>\r\n  <data name=\"ConfigureShowCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Shows details of a configuration</value>\r\n  </data>\r\n  <data name=\"ConfigureTestCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Checks that the system matches the desired state as described by the provided configuration. May download/execute processors in order to test the desired state. The configuration and the processors should be checked to ensure that they are trustworthy before executing them.</value>\r\n  </data>\r\n  <data name=\"ConfigureTestCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Checks the system against a desired state</value>\r\n  </data>\r\n  <data name=\"ConfigureValidateCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Validates a configuration file for correctness.</value>\r\n  </data>\r\n  <data name=\"ConfigureValidateCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Validates a configuration file</value>\r\n  </data>\r\n  <data name=\"ConfigurationFieldInvalidType\" xml:space=\"preserve\">\r\n    <value>The field '{0}' in the configuration file is the wrong type.</value>\r\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the field name from the file.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationFileArgumentDescription\" xml:space=\"preserve\">\r\n    <value>The path to the configuration file</value>\r\n  </data>\r\n  <data name=\"ConfigurationFileInvalid\" xml:space=\"preserve\">\r\n    <value>The configuration file is invalid.</value>\r\n  </data>\r\n  <data name=\"ConfigurationFileVersionUnknown\" xml:space=\"preserve\">\r\n    <value>Configuration file version {0} is not known.</value>\r\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the version of the configuration file.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationAcceptWarningArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Accepts the configuration warning, preventing an interactive prompt</value>\r\n  </data>\r\n  <data name=\"ConfigurationApply\" xml:space=\"preserve\">\r\n    <value>Apply</value>\r\n    <comment>Indicates that this item is used to write state</comment>\r\n  </data>\r\n  <data name=\"ConfigurationAssert\" xml:space=\"preserve\">\r\n    <value>Assert</value>\r\n    <comment>Indicates that this item is used to check/assert the state rather than write to it</comment>\r\n  </data>\r\n  <data name=\"ConfigurationDependencies\" xml:space=\"preserve\">\r\n    <value>Dependencies:{0}</value>\r\n    <comment>{Locked=\"{0}\"} Label displaying a list of dependencies. {0} is replaced with a space separated list of identifiers referencing other items.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationFailedToApply\" xml:space=\"preserve\">\r\n    <value>Some of the configuration was not applied successfully.</value>\r\n  </data>\r\n  <data name=\"ConfigurationFailedToGetDetails\" xml:space=\"preserve\">\r\n    <value>Failed to get detailed information about the configuration.</value>\r\n  </data>\r\n  <data name=\"ConfigurationInform\" xml:space=\"preserve\">\r\n    <value>Inform</value>\r\n    <comment>Indicates that this item is used to retrieve values for future use rather than writing them</comment>\r\n  </data>\r\n  <data name=\"ConfigurationLocal\" xml:space=\"preserve\">\r\n    <value>Local</value>\r\n    <comment>Used to indicate that the item is present on the device.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationModuleNameOnly\" xml:space=\"preserve\">\r\n    <value>Module: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Label displaying a module name. {0} is replaced with the name of the module from the user input file.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationModuleWithDetails\" xml:space=\"preserve\">\r\n    <value>Module: {0} by {1} [{2}]</value>\r\n    <comment>{Locked=\"{0}\",\"{1}\",\"{2}\"} Label displaying module information. {0} is replaced by the module name. {1} is replaced by the module author. {2} is replaced by a string indicating the source of the module.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationSettings\" xml:space=\"preserve\">\r\n    <value>Settings:</value>\r\n    <comment>Label for the values that are used as inputs for this item when applying state</comment>\r\n  </data>\r\n  <data name=\"ConfigurationSuccessfullyApplied\" xml:space=\"preserve\">\r\n    <value>Configuration successfully applied.</value>\r\n  </data>\r\n  <data name=\"ConfigurationUnitSuccessfullyApplied\" xml:space=\"preserve\">\r\n    <value>Unit successfully applied.</value>\r\n  </data>\r\n  <data name=\"ConfigurationWaitingOnAnother\" xml:space=\"preserve\">\r\n    <value>Another configuration is being applied to the system. This configuration will continue as soon as is possible...</value>\r\n  </data>\r\n  <data name=\"ConfigurationWarning\" xml:space=\"preserve\">\r\n    <value>You are responsible for understanding the configuration settings you are choosing to execute. Microsoft is not responsible for the configuration file you have authored or imported. This configuration may change settings in Windows, install software, change software settings (including security settings), and accept user agreements to third-party packages and services on your behalf.  By running this configuration file, you acknowledge that you understand and agree to these resources and settings. Any applications installed are licensed to you by their owners. Microsoft is not responsible for, nor does it grant any licenses to, third-party packages or services.</value>\r\n    <comment>Legal approved. Do not change without approval.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationWarningPromptApply\" xml:space=\"preserve\">\r\n    <value>Have you reviewed the configuration and would you like to proceed applying it to the system?</value>\r\n    <comment>PM approved.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationFileEmpty\" xml:space=\"preserve\">\r\n    <value>The configuration is empty.</value>\r\n  </data>\r\n  <data name=\"WindowsFeatureNotFound\" xml:space=\"preserve\">\r\n    <value>The feature [{0}] was not found.</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when a Windows feature was not found on the system.</comment>\r\n  </data>\r\n  <data name=\"FailedToEnableWindowsFeatureOverrideRequired\" xml:space=\"preserve\">\r\n    <value>Failed to enable Windows Feature dependencies. To proceed with installation, use '--force'.</value>\r\n    <comment>{Locked=\"--force\"}</comment>\r\n  </data>\r\n  <data name=\"RebootRequiredToEnableWindowsFeatureOverrideRequired\" xml:space=\"preserve\">\r\n    <value>Reboot required to fully enable the Windows Feature(s); to override this check use '--force'.</value>\r\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.</comment>\r\n  </data>\r\n  <data name=\"FailedToEnableWindowsFeatureOverridden\" xml:space=\"preserve\">\r\n    <value>Failed to enable Windows Feature dependencies; proceeding due to --force</value>\r\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.\r\n{Locked=\"--force\"}</comment>\r\n  </data>\r\n  <data name=\"EnablingWindowsFeature\" xml:space=\"preserve\">\r\n    <value>Enabling [{0}]...</value>\r\n    <comment>{Locked=\"{0}\"} Message displayed to the user regarding which Windows Feature is being enabled.</comment>\r\n  </data>\r\n  <data name=\"FailedToEnableWindowsFeature\" xml:space=\"preserve\">\r\n    <value>Failed to enable [{0}] feature: {1}</value>\r\n    <comment>{Locked=\"{0}\",\"{1}\"}  An error when enabling a Windows Feature. {0} is a placeholder for the name of the Windows Feature.\r\n{1} is a placeholder for the unrecognized error code.</comment>\r\n  </data>\r\n  <data name=\"RebootRequiredToEnableWindowsFeatureOverridden\" xml:space=\"preserve\">\r\n    <value>Reboot required to fully enable the Windows Feature(s); proceeding due to --force</value>\r\n    <comment>\"Windows Feature(s)\" is the name of the options Windows features setting.</comment>\r\n  </data>\r\n  <data name=\"InstallWaitingOnAnother\" xml:space=\"preserve\">\r\n    <value>Waiting for another install/uninstall to complete...</value>\r\n  </data>\r\n  <data name=\"PinVersion\" xml:space=\"preserve\">\r\n    <value>Pinned version</value>\r\n    <comment>Table header for the version to which a package is pinned; meaning it should not update from that version.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationDescriptionWasTruncated\" xml:space=\"preserve\">\r\n    <value>&lt;See the log file for additional details&gt;</value>\r\n    <comment>The brackets are intended to make the value stand out from other text which it will follow. Any locale appropriate mechanism that achieves this is acceptable.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationGettingDetails\" xml:space=\"preserve\">\r\n    <value>Retrieving configuration details</value>\r\n  </data>\r\n  <data name=\"ConfigurationInitializing\" xml:space=\"preserve\">\r\n    <value>Initializing configuration system</value>\r\n  </data>\r\n  <data name=\"ConfigurationReadingConfigFile\" xml:space=\"preserve\">\r\n    <value>Reading configuration file</value>\r\n  </data>\r\n  <data name=\"ConfigurationUnitAssertHadNegativeResult\" xml:space=\"preserve\">\r\n    <value>The system is not in the desired state asserted by the configuration.</value>\r\n  </data>\r\n  <data name=\"ConfigurationUnitFailed\" xml:space=\"preserve\">\r\n    <value>This configuration unit failed for an unknown reason: {0}</value>\r\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationUnitFailedConfigSet\" xml:space=\"preserve\">\r\n    <value>The configuration unit failed due to the configuration: {0}</value>\r\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationUnitFailedDuringGet\" xml:space=\"preserve\">\r\n    <value>The configuration unit failed while attempting to get the current system state.</value>\r\n  </data>\r\n  <data name=\"ConfigurationUnitFailedDuringSet\" xml:space=\"preserve\">\r\n    <value>The configuration unit failed while attempting to apply the desired state.</value>\r\n  </data>\r\n  <data name=\"ConfigurationUnitFailedDuringTest\" xml:space=\"preserve\">\r\n    <value>The configuration unit failed while attempting to test the current system state.</value>\r\n  </data>\r\n  <data name=\"ConfigurationUnitFailedInternal\" xml:space=\"preserve\">\r\n    <value>The configuration unit failed due to an internal error: {0}</value>\r\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationUnitFailedPrecondition\" xml:space=\"preserve\">\r\n    <value>The configuration unit failed due to a precondition not being valid: {0}</value>\r\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationUnitFailedSystemState\" xml:space=\"preserve\">\r\n    <value>The configuration unit failed due to the system state: {0}</value>\r\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationUnitFailedUnitProcessing\" xml:space=\"preserve\">\r\n    <value>The configuration unit failed while attempting to run: {0}</value>\r\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationUnitHasDuplicateIdentifier\" xml:space=\"preserve\">\r\n    <value>The configuration contains the identifier `{0}` multiple times.</value>\r\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by the identifier string from the user input file.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationUnitHasMissingDependency\" xml:space=\"preserve\">\r\n    <value>The dependency `{0}` was not found within the configuration.</value>\r\n    <comment>{Locked=\"{0}\"} {0} is a placeholder that is replaced by the identifier string from the user input file.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationUnitManuallySkipped\" xml:space=\"preserve\">\r\n    <value>This configuration unit was manually skipped.</value>\r\n  </data>\r\n  <data name=\"ConfigurationUnitModuleConflict\" xml:space=\"preserve\">\r\n    <value>The module for the configuration unit is available in multiple locations with the same version.</value>\r\n  </data>\r\n  <data name=\"ConfigurationUnitModuleImportFailed\" xml:space=\"preserve\">\r\n    <value>Loading the module for the configuration unit failed.</value>\r\n  </data>\r\n  <data name=\"ConfigurationUnitMultipleMatches\" xml:space=\"preserve\">\r\n    <value>Multiple matches were found for the configuration unit; specify the module to select the correct one.</value>\r\n  </data>\r\n  <data name=\"ConfigurationUnitNotFound\" xml:space=\"preserve\">\r\n    <value>The configuration unit could not be found.</value>\r\n  </data>\r\n  <data name=\"ConfigurationUnitNotFoundInModule\" xml:space=\"preserve\">\r\n    <value>The configuration unit was not in the module as expected.</value>\r\n  </data>\r\n  <data name=\"ConfigurationUnitNotRunDueToDependency\" xml:space=\"preserve\">\r\n    <value>This configuration unit was not run because a dependency failed or was not run.</value>\r\n  </data>\r\n  <data name=\"ConfigurationUnitNotRunDueToFailedAssert\" xml:space=\"preserve\">\r\n    <value>This configuration unit was not run because an assert failed or was false.</value>\r\n  </data>\r\n  <data name=\"ConfigurationUnitReturnedInvalidResult\" xml:space=\"preserve\">\r\n    <value>The configuration unit returned an unexpected result during execution.</value>\r\n  </data>\r\n  <data name=\"ConfigurationUnitSkipped\" xml:space=\"preserve\">\r\n    <value>This configuration unit was not run for an unknown reason: {0}</value>\r\n    <comment>{Locked=\"{0}\"} {0} is a placeholder for the unrecognized error code.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationFieldInvalidValue\" xml:space=\"preserve\">\r\n    <value>The field '{0}' has an invalid value: {1}</value>\r\n    <comment>{Locked=\"{0}\",\"{1}\"} An error in reading a configuration file. {0} is a placeholder replaced by the field name from the file. {1} is a placeholder for the invalid value.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationFieldMissing\" xml:space=\"preserve\">\r\n    <value>The field '{0}' is missing or empty.</value>\r\n    <comment>{Locked=\"{0}\"} An error in reading a configuration file. {0} is a placeholder replaced by the expected field name from the file.</comment>\r\n  </data>\r\n  <data name=\"SeeLineAndColumn\" xml:space=\"preserve\">\r\n    <value>See line {0}, column {1} in the file.</value>\r\n    <comment>{Locked=\"{0}\",\"{1}\"} Indicates the file location of the error, {0} and {1} are placeholders for numbers of the line and column, respectively.</comment>\r\n  </data>\r\n  <data name=\"CancellingOperation\" xml:space=\"preserve\">\r\n    <value>Cancelling operation</value>\r\n  </data>\r\n  <data name=\"InstallStubPackageDescription\" xml:space=\"preserve\">\r\n    <value>Install the stub package for AppInstaller</value>\r\n  </data>\r\n  <data name=\"InstallFullPackageDescription\" xml:space=\"preserve\">\r\n    <value>Install the full package for AppInstaller</value>\r\n  </data>\r\n  <data name=\"ExtendedFeaturesEnableMessage\" xml:space=\"preserve\">\r\n    <value>Enable extended features. Requires store access.</value>\r\n  </data>\r\n  <data name=\"ExtendedFeaturesEnableArgumentError\" xml:space=\"preserve\">\r\n    <value>Option '--enable' and '--disable' cannot be used with other arguments.</value>\r\n    <comment>{Locked=\"--enable\", \"--disable\"}</comment>\r\n  </data>\r\n  <data name=\"ExtendedFeaturesEnablingMessage\" xml:space=\"preserve\">\r\n    <value>Enabling extended features. Requires store access.</value>\r\n  </data>\r\n  <data name=\"ExtendedFeaturesNotEnabledMessage\" xml:space=\"preserve\">\r\n    <value>Extended features are not enabled. Run `winget configure --enable` to enable them.</value>\r\n    <comment>{Locked=\"winget configure --enable\"}</comment>\r\n  </data>\r\n  <data name=\"ExtendedFeaturesEnabledMessage\" xml:space=\"preserve\">\r\n    <value>Extended features are enabled.</value>\r\n  </data>\r\n  <data name=\"ExtendedFeaturesDisableMessage\" xml:space=\"preserve\">\r\n    <value>Disable extended features. Requires store access.</value>\r\n  </data>\r\n  <data name=\"ExtendedFeaturesDisablingMessage\" xml:space=\"preserve\">\r\n    <value>Disabling extended features. Requires store access.</value>\r\n  </data>\r\n  <data name=\"ExtendedFeaturesDisabledMessage\" xml:space=\"preserve\">\r\n    <value>Extended features are disabled.</value>\r\n  </data>\r\n  <data name=\"SkipDependenciesArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Skips processing package dependencies and Windows features</value>\r\n  </data>\r\n  <data name=\"DependenciesOnlyArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Installs only the dependencies of the package</value>\r\n  </data>\r\n  <data name=\"DependenciesOnlyMessage\" xml:space=\"preserve\">\r\n    <value>Installing dependencies only. The package itself will not be installed.</value>\r\n  </data>\r\n  <data name=\"DependenciesSkippedMessage\" xml:space=\"preserve\">\r\n    <value>Dependencies skipped.</value>\r\n  </data>\r\n  <data name=\"FailedToRefreshPathWarning\" xml:space=\"preserve\">\r\n    <value>Failed to refresh PATH variable for process. Subsequent installs that depend on changes to the PATH variable may fail.</value>\r\n    <comment>{Locked=\"PATH\"}</comment>\r\n  </data>\r\n  <data name=\"ConfigurationFailedToTest\" xml:space=\"preserve\">\r\n    <value>Some of the configuration units failed while testing their state.</value>\r\n  </data>\r\n  <data name=\"ConfigurationInDesiredState\" xml:space=\"preserve\">\r\n    <value>System is in the described configuration state.</value>\r\n  </data>\r\n  <data name=\"ConfigurationNoTestRun\" xml:space=\"preserve\">\r\n    <value>Configuration state was not tested.</value>\r\n  </data>\r\n  <data name=\"ConfigurationNotInDesiredState\" xml:space=\"preserve\">\r\n    <value>System is not in the described configuration state.</value>\r\n  </data>\r\n  <data name=\"ConfigurationUnexpectedTestResult\" xml:space=\"preserve\">\r\n    <value>Unexpected test result: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message. {0} will be replaced with the unexpected value (a number).</comment>\r\n  </data>\r\n  <data name=\"ConfigurationWarningPromptTest\" xml:space=\"preserve\">\r\n    <value>Have you reviewed the configuration and would you like to proceed verifying it against the system?</value>\r\n  </data>\r\n  <data name=\"ConfigurationFileInvalidYAML\" xml:space=\"preserve\">\r\n    <value>The configuration file is not a valid YAML file.</value>\r\n    <comment>{Locked=\"YAML\"} YAML is a file format name.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationUnitIsPartOfDependencyCycle\" xml:space=\"preserve\">\r\n    <value>This configuration unit is part of a dependency cycle.</value>\r\n  </data>\r\n  <data name=\"ConfigurationValidationFoundNoIssues\" xml:space=\"preserve\">\r\n    <value>Validation found no issues.</value>\r\n  </data>\r\n  <data name=\"ConfigurationUnitNeedsPrereleaseWarning\" xml:space=\"preserve\">\r\n    <value>The configuration unit is only available as a prerelease, but it is not marked that way in the configuration. Add `allowPrerelease: true` to the `directives`.</value>\r\n    <comment>{Locked=\"allowPrerelease: true\",\"directives\"} These are values in the configuration file that are not localized.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationUnitNotInCatalogWarning\" xml:space=\"preserve\">\r\n    <value>The configuration unit was found locally, but could not be found in any configured catalog. Ensure that it is present on any system before applying the configuration.</value>\r\n  </data>\r\n  <data name=\"ConfigurationUnitNotPublicWarning\" xml:space=\"preserve\">\r\n    <value>The configuration unit is not available publicly; ensure that anyone who will use this configuration has access to it.</value>\r\n  </data>\r\n  <data name=\"ConfigurationUnitModuleNotProvidedWarning\" xml:space=\"preserve\">\r\n    <value>The module was not provided. Specifying the module improves performance and prevents future name collisions.</value>\r\n  </data>\r\n  <data name=\"DownloadCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Downloads the installer from the selected package, either found by searching a configured source or directly from a manifest. By default, the query must case-insensitively match the id, name, or moniker of the package. Other fields can be used by passing their appropriate option. By default, download command will download the appropriate installer to the user's Downloads folder.</value>\r\n  </data>\r\n  <data name=\"DownloadCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Downloads the installer from a given package</value>\r\n  </data>\r\n  <data name=\"DownloadDirectoryArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Directory where the installers are downloaded to</value>\r\n  </data>\r\n  <data name=\"DependenciesFlowDownload\" xml:space=\"preserve\">\r\n    <value>Downloading dependencies:</value>\r\n  </data>\r\n  <data name=\"InstallerDownloaded\" xml:space=\"preserve\">\r\n    <value>Installer downloaded: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Full path of the downloaded installer.</comment>\r\n  </data>\r\n  <data name=\"InstallerTypeArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Select the installer type</value>\r\n  </data>\r\n  <data name=\"InstallerDownloads\" xml:space=\"preserve\">\r\n    <value>Installer Downloads</value>\r\n  </data>\r\n  <data name=\"InstallerDownloadCommandProhibited\" xml:space=\"preserve\">\r\n    <value>Installer is prohibited from being downloaded for later offline installation. </value>\r\n  </data>\r\n  <data name=\"ConfigurationAllUsersElevated\" xml:space=\"preserve\">\r\n    <value>`--module-path allusers` requires administrator privileges to execute.</value>\r\n    <comment>{Locked=\"--module-path allusers\"}</comment>\r\n  </data>\r\n  <data name=\"ConfigurationModulePath\" xml:space=\"preserve\">\r\n    <value>Specifies the location on the local computer to store modules. Default %LOCALAPPDATA%\\Microsoft\\WinGet\\Configuration\\Modules</value>\r\n    <comment>{Locked=\"%LOCALAPPDATA%\\Microsoft\\WinGet\\Configuration\\Modules\"}</comment>\r\n  </data>\r\n  <data name=\"ConfigurationModulePathArgError\" xml:space=\"preserve\">\r\n    <value>`--module-path` value must be `currentuser`, `allusers`, `default`, or an absolute path.</value>\r\n    <comment>{Locked=\"{--module-path}, {currentuser}, {allusers}, {default}}</comment>\r\n  </data>\r\n  <data name=\"PolicyEnableWinGetConfiguration\" xml:space=\"preserve\">\r\n    <value>Enable Windows Package Manager Configuration</value>\r\n  </data>\r\n  <data name=\"ErrorCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Retrieve information about errors. Given a number, the output will contain details about the error, including the symbol name if it is a WinGet specific error. Given a string, the WinGet specific errors are searched for this value.</value>\r\n    <comment>{Locked=\"WinGet\"}</comment>\r\n  </data>\r\n  <data name=\"ErrorCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Get information on errors</value>\r\n  </data>\r\n  <data name=\"ErrorInputArgumentDescription\" xml:space=\"preserve\">\r\n    <value>A value to search within the error information</value>\r\n  </data>\r\n  <data name=\"ErrorNumberIsTooLarge\" xml:space=\"preserve\">\r\n    <value>The given number is too large to be an HRESULT.</value>\r\n  </data>\r\n  <data name=\"UnknownErrorCode\" xml:space=\"preserve\">\r\n    <value>Unknown error code</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INTERNAL_ERROR\" xml:space=\"preserve\">\r\n    <value>Internal Error</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS\" xml:space=\"preserve\">\r\n    <value>Invalid command line arguments</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_COMMAND_FAILED\" xml:space=\"preserve\">\r\n    <value>Executing command failed</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_FAILED\" xml:space=\"preserve\">\r\n    <value>Opening manifest failed</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_CTRL_SIGNAL_RECEIVED\" xml:space=\"preserve\">\r\n    <value>Cancellation signal received</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_SHELLEXEC_INSTALL_FAILED\" xml:space=\"preserve\">\r\n    <value>Running ShellExecute failed</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_MANIFESTVERSION\" xml:space=\"preserve\">\r\n    <value>Cannot process manifest. The manifest version is higher than supported. Please update the client.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_FAILED\" xml:space=\"preserve\">\r\n    <value>Downloading installer failed</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX\" xml:space=\"preserve\">\r\n    <value>Cannot write to index; it is a higher schema version</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INDEX_INTEGRITY_COMPROMISED\" xml:space=\"preserve\">\r\n    <value>The index is corrupt</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCES_INVALID\" xml:space=\"preserve\">\r\n    <value>The configured source information is corrupt</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NAME_ALREADY_EXISTS\" xml:space=\"preserve\">\r\n    <value>The source name is already configured</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_SOURCE_TYPE\" xml:space=\"preserve\">\r\n    <value>The source type is invalid</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_BUNDLE\" xml:space=\"preserve\">\r\n    <value>The MSIX file is a bundle, not a package</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_DATA_MISSING\" xml:space=\"preserve\">\r\n    <value>Data required by the source is missing</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER\" xml:space=\"preserve\">\r\n    <value>None of the installers are applicable for the current system</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_HASH_MISMATCH\" xml:space=\"preserve\">\r\n    <value>The installer file's hash does not match the manifest</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NAME_DOES_NOT_EXIST\" xml:space=\"preserve\">\r\n    <value>The source name does not exist</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_ARG_ALREADY_EXISTS\" xml:space=\"preserve\">\r\n    <value>The source location is already configured under another name</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICATIONS_FOUND\" xml:space=\"preserve\">\r\n    <value>No packages found</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_SOURCES_DEFINED\" xml:space=\"preserve\">\r\n    <value>No sources are configured</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_APPLICATIONS_FOUND\" xml:space=\"preserve\">\r\n    <value>Multiple packages found matching the criteria</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_MANIFEST_FOUND\" xml:space=\"preserve\">\r\n    <value>No manifest found matching the criteria</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_EXTENSION_PUBLIC_FAILED\" xml:space=\"preserve\">\r\n    <value>Failed to get Public folder from source package</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_COMMAND_REQUIRES_ADMIN\" xml:space=\"preserve\">\r\n    <value>Command requires administrator privileges to run</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NOT_SECURE\" xml:space=\"preserve\">\r\n    <value>The source location is not secure</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\r\n    <value>The Microsoft Store client is blocked by policy</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_APP_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\r\n    <value>The Microsoft Store app is blocked by policy</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_EXPERIMENTAL_FEATURE_DISABLED\" xml:space=\"preserve\">\r\n    <value>The feature is currently under development. It can be enabled using `winget settings`.</value>\r\n    <comment>{Locked=\"winget settings\"}</comment>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_MSSTORE_INSTALL_FAILED\" xml:space=\"preserve\">\r\n    <value>Failed to install the Microsoft Store app</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_COMPLETE_INPUT_BAD\" xml:space=\"preserve\">\r\n    <value>Failed to perform auto complete</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED\" xml:space=\"preserve\">\r\n    <value>Failed to initialize YAML parser</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_MAPPING_KEY\" xml:space=\"preserve\">\r\n    <value>Encountered an invalid YAML key</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY\" xml:space=\"preserve\">\r\n    <value>Encountered a duplicate YAML key</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_OPERATION\" xml:space=\"preserve\">\r\n    <value>Invalid YAML operation</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_DOC_BUILD_FAILED\" xml:space=\"preserve\">\r\n    <value>Failed to build YAML doc</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_EMITTER_STATE\" xml:space=\"preserve\">\r\n    <value>Invalid YAML emitter state</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_YAML_INVALID_DATA\" xml:space=\"preserve\">\r\n    <value>Invalid YAML data</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_LIBYAML_ERROR\" xml:space=\"preserve\">\r\n    <value>LibYAML error</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_WARNING\" xml:space=\"preserve\">\r\n    <value>Manifest validation succeeded with warning</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_FAILURE\" xml:space=\"preserve\">\r\n    <value>Manifest validation failed</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_MANIFEST\" xml:space=\"preserve\">\r\n    <value>Manifest is invalid</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE\" xml:space=\"preserve\">\r\n    <value>No applicable update found</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_UPDATE_ALL_HAS_FAILURE\" xml:space=\"preserve\">\r\n    <value>winget upgrade --all completed with failures</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_SECURITY_CHECK_FAILED\" xml:space=\"preserve\">\r\n    <value>Installer failed security check</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_SIZE_MISMATCH\" xml:space=\"preserve\">\r\n    <value>Download size does not match expected content length</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_UNINSTALL_INFO_FOUND\" xml:space=\"preserve\">\r\n    <value>Uninstall command not found</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_EXEC_UNINSTALL_COMMAND_FAILED\" xml:space=\"preserve\">\r\n    <value>Running uninstall command failed</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_BREAK_ITERATOR_ERROR\" xml:space=\"preserve\">\r\n    <value>ICU break iterator error</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_CASEMAP_ERROR\" xml:space=\"preserve\">\r\n    <value>ICU casemap error</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_REGEX_ERROR\" xml:space=\"preserve\">\r\n    <value>ICU regex error</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_IMPORT_INSTALL_FAILED\" xml:space=\"preserve\">\r\n    <value>Failed to install one or more imported packages</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_NOT_ALL_PACKAGES_FOUND\" xml:space=\"preserve\">\r\n    <value>Could not find one or more requested packages</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE\" xml:space=\"preserve\">\r\n    <value>Json file is invalid</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_NOT_REMOTE\" xml:space=\"preserve\">\r\n    <value>The source location is not remote</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE\" xml:space=\"preserve\">\r\n    <value>The configured rest source is not supported</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA\" xml:space=\"preserve\">\r\n    <value>Invalid data returned by rest source</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\r\n    <value>Operation is blocked by Group Policy</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_INTERNAL_ERROR\" xml:space=\"preserve\">\r\n    <value>Rest API internal error</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_URL\" xml:space=\"preserve\">\r\n    <value>Invalid rest source url</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_UNSUPPORTED_MIME_TYPE\" xml:space=\"preserve\">\r\n    <value>Unsupported MIME type returned by rest API</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_VERSION\" xml:space=\"preserve\">\r\n    <value>Invalid rest source contract version</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE\" xml:space=\"preserve\">\r\n    <value>The source data is corrupted or tampered</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_STREAM_READ_FAILURE\" xml:space=\"preserve\">\r\n    <value>Error reading from the stream</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED\" xml:space=\"preserve\">\r\n    <value>Package agreements were not agreed to</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_PROMPT_INPUT_ERROR\" xml:space=\"preserve\">\r\n    <value>Error reading input in prompt</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST\" xml:space=\"preserve\">\r\n    <value>The search request is not supported by one or more sources</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_RESTAPI_ENDPOINT_NOT_FOUND\" xml:space=\"preserve\">\r\n    <value>The rest API endpoint is not found.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_OPEN_FAILED\" xml:space=\"preserve\">\r\n    <value>Failed to open the source.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED\" xml:space=\"preserve\">\r\n    <value>Source agreements were not agreed to</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_CUSTOMHEADER_EXCEEDS_MAXLENGTH\" xml:space=\"preserve\">\r\n    <value>Header size exceeds the allowable limit of 1024 characters. Please reduce the size and try again.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_MISSING_RESOURCE_FILE\" xml:space=\"preserve\">\r\n    <value>Missing resource file</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_MSI_INSTALL_FAILED\" xml:space=\"preserve\">\r\n    <value>Running MSI install failed</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT\" xml:space=\"preserve\">\r\n    <value>Arguments for msiexec are invalid</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_FAILED_TO_OPEN_ALL_SOURCES\" xml:space=\"preserve\">\r\n    <value>Failed to open one or more sources</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED\" xml:space=\"preserve\">\r\n    <value>Failed to validate dependencies</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_MISSING_PACKAGE\" xml:space=\"preserve\">\r\n    <value>One or more package is missing</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_TABLE_COLUMN\" xml:space=\"preserve\">\r\n    <value>Invalid table column</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_NOT_NEWER\" xml:space=\"preserve\">\r\n    <value>The upgrade version is not newer than the installed version</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_UNKNOWN\" xml:space=\"preserve\">\r\n    <value>Upgrade version is unknown and override is not specified</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_ICU_CONVERSION_ERROR\" xml:space=\"preserve\">\r\n    <value>ICU conversion error</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_INSTALL_FAILED\" xml:space=\"preserve\">\r\n    <value>Failed to install portable package</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_REPARSE_POINT_NOT_SUPPORTED\" xml:space=\"preserve\">\r\n    <value>Volume does not support reparse points</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_PACKAGE_ALREADY_EXISTS\" xml:space=\"preserve\">\r\n    <value>Portable package from a different source already exists.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_SYMLINK_PATH_IS_DIRECTORY\" xml:space=\"preserve\">\r\n    <value>Unable to create symlink. Path points to a directory.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_PROHIBITS_ELEVATION\" xml:space=\"preserve\">\r\n    <value>The installer cannot be run from an administrator context.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_PORTABLE_UNINSTALL_FAILED\" xml:space=\"preserve\">\r\n    <value>Failed to uninstall portable package</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_ARP_VERSION_VALIDATION_FAILED\" xml:space=\"preserve\">\r\n    <value>Failed to validate DisplayVersion values against index.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_UNSUPPORTED_ARGUMENT\" xml:space=\"preserve\">\r\n    <value>One or more arguments are not supported.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_BIND_WITH_EMBEDDED_NULL\" xml:space=\"preserve\">\r\n    <value>Embedded null characters are disallowed for SQLite</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_NOT_FOUND\" xml:space=\"preserve\">\r\n    <value>Failed to find the nested installer in the archive.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_EXTRACT_ARCHIVE_FAILED\" xml:space=\"preserve\">\r\n    <value>Failed to extract archive.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_INVALID_PATH\" xml:space=\"preserve\">\r\n    <value>Invalid relative file path to nested installer provided.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_PINNED_CERTIFICATE_MISMATCH\" xml:space=\"preserve\">\r\n    <value>The server certificate did not match any of the expected values.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_LOCATION_REQUIRED\" xml:space=\"preserve\">\r\n    <value>Install location must be provided.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_ARCHIVE_SCAN_FAILED\" xml:space=\"preserve\">\r\n    <value>Archive malware scan failed.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_ALREADY_INSTALLED\" xml:space=\"preserve\">\r\n    <value>Found at least one version of the package installed.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_PIN_ALREADY_EXISTS\" xml:space=\"preserve\">\r\n    <value>A pin already exists for the package.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_PIN_DOES_NOT_EXIST\" xml:space=\"preserve\">\r\n    <value>There is no pin for the package.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_OPEN_PINNING_INDEX\" xml:space=\"preserve\">\r\n    <value>Unable to open the pin database.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_INSTALL_FAILED\" xml:space=\"preserve\">\r\n    <value>One or more applications failed to install</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_MULTIPLE_UNINSTALL_FAILED\" xml:space=\"preserve\">\r\n    <value>One or more applications failed to uninstall</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_NOT_ALL_QUERIES_FOUND_SINGLE\" xml:space=\"preserve\">\r\n    <value>One or more queries did not return exactly one match</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_PINNED\" xml:space=\"preserve\">\r\n    <value>The package has a pin that prevents upgrade.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB\" xml:space=\"preserve\">\r\n    <value>The package currently installed is the stub package</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_APPTERMINATION_RECEIVED\" xml:space=\"preserve\">\r\n    <value>Application shutdown signal received</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_DEPENDENCIES\" xml:space=\"preserve\">\r\n    <value>Failed to download package dependencies.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_DOWNLOAD_COMMAND_PROHIBITED\" xml:space=\"preserve\">\r\n    <value>Failed to download package. Download for offline installation is prohibited.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_SERVICE_UNAVAILABLE\" xml:space=\"preserve\">\r\n    <value>A required service is busy or unavailable. Try again later.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_RESUME_ID_NOT_FOUND\" xml:space=\"preserve\">\r\n    <value>The guid provided does not correspond to a valid resume state.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_CLIENT_VERSION_MISMATCH\" xml:space=\"preserve\">\r\n    <value>The current client version did not match the client version of the saved state.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_RESUME_STATE\" xml:space=\"preserve\">\r\n    <value>The resume state data is invalid.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_CANNOT_OPEN_CHECKPOINT_INDEX\" xml:space=\"preserve\">\r\n    <value>Unable to open the checkpoint database.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_RESUME_LIMIT_EXCEEDED\" xml:space=\"preserve\">\r\n    <value>Exceeded max resume limit.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INVALID_AUTHENTICATION_INFO\" xml:space=\"preserve\">\r\n    <value>Invalid authentication info.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED\" xml:space=\"preserve\">\r\n    <value>Authentication method not supported.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED\" xml:space=\"preserve\">\r\n    <value>Authentication failed.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_INTERACTIVE_REQUIRED\" xml:space=\"preserve\">\r\n    <value>Authentication failed. Interactive authentication required.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_CANCELLED_BY_USER\" xml:space=\"preserve\">\r\n    <value>Authentication failed. User cancelled.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_AUTHENTICATION_INCORRECT_ACCOUNT\" xml:space=\"preserve\">\r\n    <value>Authentication failed. Authenticated account is not the desired account.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE\" xml:space=\"preserve\">\r\n    <value>Application is currently running. Exit the application then try again.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INSTALL_IN_PROGRESS\" xml:space=\"preserve\">\r\n    <value>Another installation is already in progress. Try again later.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_FILE_IN_USE\" xml:space=\"preserve\">\r\n    <value>One or more file is being used. Exit the application then try again.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_MISSING_DEPENDENCY\" xml:space=\"preserve\">\r\n    <value>This package has a dependency missing from your system.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DISK_FULL\" xml:space=\"preserve\">\r\n    <value>There's no more space on your PC. Make space, then try again.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INSUFFICIENT_MEMORY\" xml:space=\"preserve\">\r\n    <value>There's not enough memory available to install. Close other applications then try again.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_NO_NETWORK\" xml:space=\"preserve\">\r\n    <value>This application requires internet connectivity. Connect to a network then try again.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CONTACT_SUPPORT\" xml:space=\"preserve\">\r\n    <value>This application encountered an error during installation. Contact support.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_TO_FINISH\" xml:space=\"preserve\">\r\n    <value>Restart your PC to finish installation.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_FOR_INSTALL\" xml:space=\"preserve\">\r\n    <value>Installation failed. Restart your PC then try again.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_INITIATED\" xml:space=\"preserve\">\r\n    <value>Your PC will restart to finish installation.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CANCELLED_BY_USER\" xml:space=\"preserve\">\r\n    <value>You cancelled the installation.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_ALREADY_INSTALLED\" xml:space=\"preserve\">\r\n    <value>Another version of this application is already installed.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DOWNGRADE\" xml:space=\"preserve\">\r\n    <value>A higher version of this application is already installed.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_BLOCKED_BY_POLICY\" xml:space=\"preserve\">\r\n    <value>Organization policies are preventing installation. Contact your admin.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_DEPENDENCIES\" xml:space=\"preserve\">\r\n    <value>Failed to install package dependencies.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE_BY_APPLICATION\" xml:space=\"preserve\">\r\n    <value>Application is currently in use by another application.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_INVALID_PARAMETER\" xml:space=\"preserve\">\r\n    <value>Invalid parameter.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED\" xml:space=\"preserve\">\r\n    <value>Package not supported by the system.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_UPGRADE_NOT_SUPPORTED\" xml:space=\"preserve\">\r\n    <value>The installer does not support upgrading an existing package.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALL_CUSTOM_ERROR\" xml:space=\"preserve\">\r\n    <value>Installation failed with a custom installer error.</value>\r\n  </data>\r\n  <data name=\"WINGET_INSTALLED_STATUS_ARP_ENTRY_NOT_FOUND\" xml:space=\"preserve\">\r\n    <value>The Apps and Features Entry for the package could not be found.</value>\r\n  </data>\r\n  <data name=\"WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_APPLICABLE\" xml:space=\"preserve\">\r\n    <value>The install location is not applicable.</value>\r\n  </data>\r\n  <data name=\"WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_FOUND\" xml:space=\"preserve\">\r\n    <value>The install location could not be found.</value>\r\n  </data>\r\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_HASH_MISMATCH\" xml:space=\"preserve\">\r\n    <value>The hash of the existing file did not match.</value>\r\n  </data>\r\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_NOT_FOUND\" xml:space=\"preserve\">\r\n    <value>File not found.</value>\r\n  </data>\r\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK\" xml:space=\"preserve\">\r\n    <value>The file was found but the hash was not checked.</value>\r\n  </data>\r\n  <data name=\"WINGET_INSTALLED_STATUS_FILE_ACCESS_ERROR\" xml:space=\"preserve\">\r\n    <value>The file could not be accessed.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE\" xml:space=\"preserve\">\r\n    <value>The configuration file is invalid.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_YAML\" xml:space=\"preserve\">\r\n    <value>The YAML syntax is invalid.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_FIELD_TYPE\" xml:space=\"preserve\">\r\n    <value>A configuration field has an invalid type.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION\" xml:space=\"preserve\">\r\n    <value>The configuration has an unknown version.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_SET_APPLY_FAILED\" xml:space=\"preserve\">\r\n    <value>An error occurred while applying the configuration.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER\" xml:space=\"preserve\">\r\n    <value>The configuration contains a duplicate identifier.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_MISSING_DEPENDENCY\" xml:space=\"preserve\">\r\n    <value>The configuration is missing a dependency.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED\" xml:space=\"preserve\">\r\n    <value>The configuration has an unsatisfied dependency.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_ASSERTION_FAILED\" xml:space=\"preserve\">\r\n    <value>An assertion for the configuration unit failed.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_MANUALLY_SKIPPED\" xml:space=\"preserve\">\r\n    <value>The configuration was manually skipped.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_WARNING_NOT_ACCEPTED\" xml:space=\"preserve\">\r\n    <value>The user declined to continue execution.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_SET_DEPENDENCY_CYCLE\" xml:space=\"preserve\">\r\n    <value>The dependency graph contains a cycle which cannot be resolved.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_INVALID_FIELD_VALUE\" xml:space=\"preserve\">\r\n    <value>The configuration has an invalid field value.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_MISSING_FIELD\" xml:space=\"preserve\">\r\n    <value>The configuration is missing a field.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_TEST_FAILED\" xml:space=\"preserve\">\r\n    <value>Some of the configuration units failed while testing their state.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_TEST_NOT_RUN\" xml:space=\"preserve\">\r\n    <value>Configuration state was not tested.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_NOT_INSTALLED\" xml:space=\"preserve\">\r\n    <value>The configuration unit was not installed.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_NOT_FOUND_REPOSITORY\" xml:space=\"preserve\">\r\n    <value>The configuration unit could not be found.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_MULTIPLE_MATCHES\" xml:space=\"preserve\">\r\n    <value>Multiple matches were found for the configuration unit; specify the module to select the correct one.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_GET\" xml:space=\"preserve\">\r\n    <value>The configuration unit failed while attempting to get the current system state.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_TEST\" xml:space=\"preserve\">\r\n    <value>The configuration unit failed while attempting to test the current system state.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_SET\" xml:space=\"preserve\">\r\n    <value>The configuration unit failed while attempting to apply the desired state.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_MODULE_CONFLICT\" xml:space=\"preserve\">\r\n    <value>The module for the configuration unit is available in multiple locations with the same version.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE\" xml:space=\"preserve\">\r\n    <value>Loading the module for the configuration unit failed.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_INVOKE_INVALID_RESULT\" xml:space=\"preserve\">\r\n    <value>The configuration unit returned an unexpected result during execution.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_SETTING_CONFIG_ROOT\" xml:space=\"preserve\">\r\n    <value>A unit contains a setting that requires the config root.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR\" xml:space=\"preserve\">\r\n    <value>Operation is not supported by the configuration processor.</value>\r\n  </data>\r\n  <data name=\"Unavailable\" xml:space=\"preserve\">\r\n    <value>Unavailable</value>\r\n  </data>\r\n  <data name=\"EnableWindowsFeaturesSuccess\" xml:space=\"preserve\">\r\n    <value>Successfully enabled Windows Features dependencies</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE_ADMIN\" xml:space=\"preserve\">\r\n    <value>Loading the module for the configuration unit failed because it requires administrator privileges to run.</value>\r\n  </data>\r\n  <data name=\"ConfigurationUnitSettingConfigRoot\" xml:space=\"preserve\">\r\n    <value>A unit contains a setting that requires the config root.</value>\r\n  </data>\r\n  <data name=\"ConfigurationUnitImportModuleAdmin\" xml:space=\"preserve\">\r\n    <value>Loading the module for the configuration unit failed because it requires administrator privileges to run.</value>\r\n  </data>\r\n  <data name=\"ResumeCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Resumes execution of a previously saved command by passing in the unique identifier of the saved command. This is used to resume an executed command that may have been terminated due to a reboot.</value>\r\n  </data>\r\n  <data name=\"ResumeCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Resumes execution of a previously saved command.</value>\r\n  </data>\r\n  <data name=\"ResumeIdArgumentDescription\" xml:space=\"preserve\">\r\n    <value>The unique identifier of the saved state to resume</value>\r\n  </data>\r\n  <data name=\"ClientVersionMismatchError\" xml:space=\"preserve\">\r\n    <value>Resuming the state from a different client version is not supported: {0}</value>\r\n    <comment>{Locked= \"{0}\"} Message displayed to inform the user that the client version of the resume state does not match the current client version. {0} is a placeholder for the client version that created the resume state.</comment>\r\n  </data>\r\n  <data name=\"ResumeIdNotFoundError\" xml:space=\"preserve\">\r\n    <value>The resume state does not exist: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the user provides a guid that does not correspond to a valid saved state. {0} is a placeholder replaced by the provided guid string.</comment>\r\n  </data>\r\n  <data name=\"ResumeStateDataNotFoundError\" xml:space=\"preserve\">\r\n    <value>No data found in the resume state.</value>\r\n  </data>\r\n  <data name=\"CommandDoesNotSupportResumeMessage\" xml:space=\"preserve\">\r\n    <value>This command does not support resuming.</value>\r\n  </data>\r\n  <data name=\"AllowRebootArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Allows a reboot if applicable</value>\r\n  </data>\r\n  <data name=\"InitiatingReboot\" xml:space=\"preserve\">\r\n    <value>Initiating reboot to complete operation...</value>\r\n  </data>\r\n  <data name=\"FailedToInitiateReboot\" xml:space=\"preserve\">\r\n    <value>Failed to initiate a reboot.</value>\r\n  </data>\r\n  <data name=\"ResumeLimitExceeded\" xml:space=\"preserve\">\r\n    <value>Resume operation exceeds the allowable limit of {0} resume(s). To manually resume, run the command `{1}`.</value>\r\n    <comment>{Locked=\"{0}\", \"{1}\"} {0} is a placeholder that is replaced by an integer number of the number of allowed resumes. {1} is a placeholder for the command to run to perform a manual resume.</comment>\r\n  </data>\r\n  <data name=\"IgnoreResumeLimitArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Ignore the limit on resuming a saved state</value>\r\n  </data>\r\n  <data name=\"UriSchemeNotSupported\" xml:space=\"preserve\">\r\n    <value>Uri scheme not supported: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the provided uri is not supported. {0} is a placeholder replaced by the provided uri.</comment>\r\n  </data>\r\n  <data name=\"UriNotWellFormed\" xml:space=\"preserve\">\r\n    <value>Uri not well formed: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when the provided uri is not well formed. {0} is a placeholder replaced by the provided uri.</comment>\r\n  </data>\r\n  <data name=\"WinGetResourceUnitEmptyContent\" xml:space=\"preserve\">\r\n    <value>Failed to parse {0} configuration unit settings content or settings content is empty.</value>\r\n    <comment>{Locked=\"{0}\"} {0} is a placeholder replaced by the input winget configure resource unit type.</comment>\r\n  </data>\r\n  <data name=\"WinGetResourceUnitMissingRequiredArg\" xml:space=\"preserve\">\r\n    <value>{0} configuration unit is missing required argument: {1}</value>\r\n    <comment>{Locked=\"{0},{1}\"} {0} is a placeholder for the input winget configure resource unit type. {1} is placeholder for the missing arg.</comment>\r\n  </data>\r\n  <data name=\"WinGetResourceUnitMissingRecommendedArg\" xml:space=\"preserve\">\r\n    <value>{0} configuration unit is missing recommended argument: {1}</value>\r\n    <comment>{Locked=\"{0},{1}\"} {0} is a placeholder for the input winget configure resource unit type. {1} is placeholder for the missing arg.</comment>\r\n  </data>\r\n  <data name=\"WinGetResourceUnitKnownSourceConfliction\" xml:space=\"preserve\">\r\n    <value>WinGetSource configuration unit conflicts with a known source: {0}</value>\r\n    <comment>{Locked=\"WinGetSource,{0}\"} {0} is a placeholder for the input winget source in the configuration unit settings.</comment>\r\n  </data>\r\n  <data name=\"WinGetResourceUnitThirdPartySourceAssertion\" xml:space=\"preserve\">\r\n    <value>WinGetSource configuration unit asserts on a third-party source: {0}</value>\r\n    <comment>{Locked=\"WinGetSource,{0}\"} {0} is a placeholder for the input winget source in the configuration unit settings.</comment>\r\n  </data>\r\n  <data name=\"WinGetResourceUnitBothPackageVersionAndUseLatest\" xml:space=\"preserve\">\r\n    <value>WinGetPackage declares both UseLatest and Version. Package Id: {0}</value>\r\n    <comment>{Locked=\"WinGetPackage,UseLatest,Version,{0}\"}</comment>\r\n  </data>\r\n  <data name=\"WinGetResourceUnitThirdPartySourceAssertionForPackage\" xml:space=\"preserve\">\r\n    <value>WinGetPackage configuration unit asserts on a package from third-party source. Package Id: {0}; Source: {1}</value>\r\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\r\n  </data>\r\n  <data name=\"WinGetResourceUnitDependencySourceNotConfigured\" xml:space=\"preserve\">\r\n    <value>WinGetPackage configuration unit package depends on a third-party source not previously configured. Package Id: {0}; Source: {1}</value>\r\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\r\n  </data>\r\n  <data name=\"WinGetResourceUnitDependencySourceNotDeclaredAsDependency\" xml:space=\"preserve\">\r\n    <value>WinGetPackage configuration unit package depends on a 3rd party source. It is recommended to declare the dependency in uni dependsOn section. Package Id: {0}; Source: {1}</value>\r\n    <comment>{Locked=\"WinGetPackage,dependsOn,{0},{1}\"}</comment>\r\n  </data>\r\n  <data name=\"WinGetResourceUnitFailedToValidatePackageSourceOpenFailed\" xml:space=\"preserve\">\r\n    <value>WinGetPackage configuration unit package cannot be validated. Source open failed. Package Id: {0}; Source: {1}</value>\r\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\r\n  </data>\r\n  <data name=\"WinGetResourceUnitFailedToValidatePackageNotFound\" xml:space=\"preserve\">\r\n    <value>WinGetPackage configuration unit package cannot be validated. Package not found. Package Id: {0}</value>\r\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\r\n  </data>\r\n  <data name=\"WinGetResourceUnitFailedToValidatePackageMultipleFound\" xml:space=\"preserve\">\r\n    <value>WinGetPackage configuration unit package cannot be validated. More than one package found. Package Id: {0}</value>\r\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\r\n  </data>\r\n  <data name=\"WinGetResourceUnitFailedToValidatePackageVersionNotFound\" xml:space=\"preserve\">\r\n    <value>WinGetPackage configuration unit package cannot be validated. Package version not found. Package Id: {0}; Version {1}</value>\r\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\r\n  </data>\r\n  <data name=\"WinGetResourceUnitPackageVersionSpecifiedWithOnlyOnePackageVersion\" xml:space=\"preserve\">\r\n    <value>WinGetPackage configuration unit package specified with a specific version while only one package version is available. Package Id: {0}; Version: {1}</value>\r\n    <comment>{Locked=\"WinGetPackage,{0},{1}\"}</comment>\r\n  </data>\r\n  <data name=\"WinGetResourceUnitFailedToValidatePackage\" xml:space=\"preserve\">\r\n    <value>WinGetPackage configuration unit package cannot be validated. Package Id: {0}</value>\r\n    <comment>{Locked=\"WinGetPackage,{0}\"}</comment>\r\n  </data>\r\n  <data name=\"AuthenticationModeArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Specify authentication window preference (silent, silentPreferred, or interactive)</value>\r\n    <comment>{Locked=\"silent\",\"silentPreferred\",\"interactive\"} This argument allows the user to select authentication window popup behavior.</comment>\r\n  </data>\r\n  <data name=\"AuthenticationAccountArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Specify the account to be used for authentication</value>\r\n  </data>\r\n  <data name=\"SourceAddFailedAuthenticationNotSupported\" xml:space=\"preserve\">\r\n    <value>Failed to add source. This WinGet version does not support the source's authentication method. Try upgrading to latest WinGet version.</value>\r\n    <comment>{Locked=\"WinGet\"}</comment>\r\n  </data>\r\n  <data name=\"SourceRequiresAuthentication\" xml:space=\"preserve\">\r\n    <value>The {0} source requires authentication. Authentication prompt may appear when necessary. Authenticated information will be shared with the source for access authorization.</value>\r\n    <comment>{Locked=\"{0}\"}</comment>\r\n  </data>\r\n  <data name=\"RepairCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Repairs the selected package, either found by searching the installed packages list or directly from a manifest. By default, the query must case-insensitively match the id, name, or moniker of the package. Other fields can be used by passing their appropriate option.</value>\r\n    <comment>id, name, and moniker are all named values in our context, and may benefit from not being translated. The match must be for any of them, with comparison ignoring case.</comment>\r\n  </data>\r\n  <data name=\"RepairCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Repairs the selected package</value>\r\n  </data>\r\n  <data name=\"NoRepairInfoFound\" xml:space=\"preserve\">\r\n    <value>The repair command for this package cannot be found. Please reach out to the package publisher for support.</value>\r\n  </data>\r\n  <data name=\"RepairDifferentInstallTechnology\" xml:space=\"preserve\">\r\n    <value>The installer technology in use does not match the version currently installed.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_REPAIR_INFO_FOUND\" xml:space=\"preserve\">\r\n    <value>Repair command not found.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_REPAIR_NOT_SUPPORTED\" xml:space=\"preserve\">\r\n    <value>The installer technology in use doesn't support repair.</value>\r\n  </data>\r\n  <data name=\"RepairFlowRepairSuccess\" xml:space=\"preserve\">\r\n    <value>Repair operation completed successfully.</value>\r\n  </data>\r\n  <data name=\"RepairAbandoned\" xml:space=\"preserve\">\r\n    <value>Repair abandoned</value>\r\n  </data>\r\n  <data name=\"RepairFlowStartingPackageRepair\" xml:space=\"preserve\">\r\n    <value>Starting package repair...</value>\r\n  </data>\r\n  <data name=\"MSStoreRepairFailed\" xml:space=\"preserve\">\r\n    <value>Failed to repair Microsoft Store package. Error code: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when a Microsoft Store application package fails to repair. {0} is a placeholder replaced by an error code.</comment>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_EXEC_REPAIR_FAILED\" xml:space=\"preserve\">\r\n    <value>Repair operation failed.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_REPAIR_NOT_APPLICABLE\" xml:space=\"preserve\">\r\n    <value>Repair operation is not applicable.</value>\r\n  </data>\r\n  <data name=\"RepairFlowNoMatchingVersion\" xml:space=\"preserve\">\r\n    <value>No matching package versions are available from the configured sources.</value>\r\n  </data>\r\n  <data name=\"RepairFlowReturnCodeSystemNotSupported\" xml:space=\"preserve\">\r\n    <value>The current system configuration does not support the repair of this package.</value>\r\n  </data>\r\n  <data name=\"RepairOperationNotSupported\" xml:space=\"preserve\">\r\n    <value>The installer technology in use does not support repair.</value>\r\n  </data>\r\n  <data name=\"NoAdminRepairForUserScopePackage\" xml:space=\"preserve\">\r\n    <value>The package installed for user scope cannot be repaired when running with administrator privileges.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED\" xml:space=\"preserve\">\r\n    <value>Repair operations involving administrator privileges are not permitted on packages installed within the user scope.</value>\r\n  </data>\r\n  <data name=\"RepairFailedWithCode\" xml:space=\"preserve\">\r\n    <value>Repair failed with exit code: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Error message displayed when an attempt to repair an application package fails. {0} is a placeholder replaced by an error code.</comment>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_SQLITE_CONNECTION_TERMINATED\" xml:space=\"preserve\">\r\n    <value>The SQLite connection was terminated to prevent corruption.</value>\r\n  </data>\r\n  <data name=\"UninstallAllVersionsArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Uninstall all versions</value>\r\n  </data>\r\n  <data name=\"TargetVersionArgumentDescription\" xml:space=\"preserve\">\r\n    <value>The version to act upon</value>\r\n  </data>\r\n  <data name=\"UninstallFailedDueToMultipleVersions\" xml:space=\"preserve\">\r\n    <value>Multiple versions of this package are installed. Either refine the search, pass the `--version` argument to select one, or pass the `--all-versions` flag to uninstall all of them.</value>\r\n    <comment>{Locked=\"--version,--all-versions\"}</comment>\r\n  </data>\r\n  <data name=\"PolicyEnableProxyCommandLineOptions\" xml:space=\"preserve\">\r\n    <value>Enable Windows Package Manager proxy command line options</value>\r\n    <comment>Describes a Group Policy that can enable the use of the --proxy option to set a proxy</comment>\r\n  </data>\r\n  <data name=\"ProxyArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Set a proxy to use for this execution</value>\r\n  </data>\r\n  <data name=\"NoProxyArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Disable the use of proxy for this execution</value>\r\n  </data>\r\n  <data name=\"NoProgressArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Disables the progress bar and spinner</value>\r\n  </data>\r\n  <data name=\"ResetAdminSettingFailed\" xml:space=\"preserve\">\r\n    <value>Cannot reset {0}. This setting is controlled by policy. For more information contact your system administrator.</value>\r\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\r\n  </data>\r\n  <data name=\"ResetAdminSettingSucceeded\" xml:space=\"preserve\">\r\n    <value>Reset admin setting '{0}'.</value>\r\n    <comment>{Locked=\"{0}\"} Message displayed after the user resets an admin setting to its default value. Reset is used as verb in past tense. {0} is a placeholder replaced by the setting name.</comment>\r\n  </data>\r\n  <data name=\"SetAdminSettingFailed\" xml:space=\"preserve\">\r\n    <value>Cannot set {0}. This setting is controlled by policy. For more information contact your system administrator.</value>\r\n    <comment>{Locked=\"{0}\"} The value will be replaced with the feature name</comment>\r\n  </data>\r\n  <data name=\"SetAdminSettingSucceeded\" xml:space=\"preserve\">\r\n    <value>Set admin setting '{0}' to '{1}'.</value>\r\n    <comment>{Locked=\"{0}\"} Message displayed after the user sets the value of an admin setting. Set is used as a verb in past tense. {0} is a placeholder replaced by the setting name. {1} is a placeholder replaced </comment>\r\n  </data>\r\n  <data name=\"SettingNameArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Name of the setting to modify</value>\r\n  </data>\r\n  <data name=\"SettingValueArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Value to set for the setting.</value>\r\n  </data>\r\n  <data name=\"SettingsResetCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Resets an admin setting to its default value.</value>\r\n  </data>\r\n  <data name=\"SettingsResetCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Resets an admin setting to its default value.</value>\r\n  </data>\r\n  <data name=\"SettingsSetCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Sets the value of an admin setting.</value>\r\n  </data>\r\n  <data name=\"SettingsSetCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Sets the value of an admin setting.</value>\r\n  </data>\r\n  <data name=\"SourceExplicitArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Excludes a source from discovery unless specified</value>\r\n  </data>\r\n  <data name=\"SourceEditExplicitArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Excludes a source from discovery (true or false)</value>\r\n  </data>\r\n  <data name=\"SourceListExplicit\" xml:space=\"preserve\">\r\n    <value>Explicit</value>\r\n    <comment>Used as a header in a table that shows the properties of a \"source\". In this context, \"explicit\" means that the source needs to be explicitly specified or directly designated to be used, as opposed to being implicitly included.</comment>\r\n  </data>\r\n  <data name=\"SourceTrustLevelArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Trust level of the source (none or trusted)</value>\r\n  </data>\r\n  <data name=\"SourceListTrustLevel\" xml:space=\"preserve\">\r\n    <value>Trust Level</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_DISPLAYCATALOG_API_FAILED\" xml:space=\"preserve\">\r\n    <value>Failed to get Microsoft Store package catalog.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_DISPLAYCATALOG_PACKAGE\" xml:space=\"preserve\">\r\n    <value>No applicable Microsoft Store package found from Microsoft Store package catalog.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_SFSCLIENT_API_FAILED\" xml:space=\"preserve\">\r\n    <value>Failed to get Microsoft Store package download information.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_NO_APPLICABLE_SFSCLIENT_PACKAGE\" xml:space=\"preserve\">\r\n    <value>No applicable Microsoft Store package found for download.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED\" xml:space=\"preserve\">\r\n    <value>Failed to retrieve Microsoft Store package license.</value>\r\n  </data>\r\n  <data name=\"MSStoreDownloadNoApplicablePackageFound\" xml:space=\"preserve\">\r\n    <value>No applicable Microsoft Store package found.</value>\r\n  </data>\r\n  <data name=\"MSStoreDownloadPackageHashVerified\" xml:space=\"preserve\">\r\n    <value>Successfully verified Microsoft Store package hash</value>\r\n  </data>\r\n  <data name=\"MSStoreDownloadPackageHashMismatch\" xml:space=\"preserve\">\r\n    <value>Microsoft Store package hash mismatch</value>\r\n  </data>\r\n  <data name=\"MSStoreDownloadPackageDownloaded\" xml:space=\"preserve\">\r\n    <value>Microsoft Store package downloaded: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Full path of the downloaded package.</comment>\r\n  </data>\r\n  <data name=\"MSStoreDownloadPackageDownloadFailed\" xml:space=\"preserve\">\r\n    <value>Microsoft Store package download failed: {0}</value>\r\n    <comment>{Locked=\"{0}\"} Package name.</comment>\r\n  </data>\r\n  <data name=\"MSStoreDownloadPackageDownloadSuccess\" xml:space=\"preserve\">\r\n    <value>Microsoft Store package download completed</value>\r\n  </data>\r\n  <data name=\"MSStoreDownloadMainPackages\" xml:space=\"preserve\">\r\n    <value>Downloading main packages from Microsoft Store...</value>\r\n  </data>\r\n  <data name=\"MSStoreDownloadDependencyPackages\" xml:space=\"preserve\">\r\n    <value>Downloading dependency packages from Microsoft Store...</value>\r\n  </data>\r\n  <data name=\"MSStoreDownloadGetDownloadInfo\" xml:space=\"preserve\">\r\n    <value>Retrieving Microsoft Store package download information</value>\r\n  </data>\r\n  <data name=\"MSStoreDownloadGetDownloadInfoFailed\" xml:space=\"preserve\">\r\n    <value>Failed to retrieve Microsoft Store package download information</value>\r\n  </data>\r\n  <data name=\"MSStoreDownloadGetLicense\" xml:space=\"preserve\">\r\n    <value>Retrieving Microsoft Store package license</value>\r\n  </data>\r\n  <data name=\"MSStoreDownloadGetLicenseSuccess\" xml:space=\"preserve\">\r\n    <value>Microsoft Store package license saved: {0}</value>\r\n    <comment>{Locked=\"{0}\"} License file full path.</comment>\r\n  </data>\r\n  <data name=\"MSStoreDownloadGetLicenseFailed\" xml:space=\"preserve\">\r\n    <value>Failed to retrieve Microsoft Store package license</value>\r\n  </data>\r\n  <data name=\"MSStoreDownloadRenameNotSupported\" xml:space=\"preserve\">\r\n    <value>Microsoft Store package download does not support --rename argument. Microsoft Store package will use names provided by Microsoft Store catalog.</value>\r\n    <comment>{Locked=\"--rename\"}</comment>\r\n  </data>\r\n  <data name=\"MSStoreDownloadAuthenticationNotice\" xml:space=\"preserve\">\r\n    <value>Microsoft Store package download requires Microsoft Entra Id authentication. Authentication prompt may appear when necessary. Authenticated information will be shared with Microsoft services for access authorization. For Microsoft Store package licensing, the Microsoft Entra Id account needs to be a member of Global Administrator, User Administrator, or License Administrator.</value>\r\n    <comment>{Locked=\"Global Administrator,User Administrator,License Administrator\"}</comment>\r\n  </data>\r\n  <data name=\"SkipMicrosoftStorePackageLicenseArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Skips retrieving Microsoft Store package offline license</value>\r\n  </data>\r\n  <data name=\"PlatformArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Select the target platform</value>\r\n  </data>\r\n  <data name=\"ConfigurationExportAddingToFile\" xml:space=\"preserve\">\r\n    <value>Adding configuration file: {0}</value>\r\n    <comment>{Locked=\"{0}\"}</comment>\r\n  </data>\r\n  <data name=\"ConfigurationExportSuccessful\" xml:space=\"preserve\">\r\n    <value>Successfully exported</value>\r\n  </data>\r\n  <data name=\"ConfigurationGettingResourceSettings\" xml:space=\"preserve\">\r\n    <value>Getting configuration settings...</value>\r\n  </data>\r\n  <data name=\"ConfigureExportArgumentRequiredError\" xml:space=\"preserve\">\r\n    <value>At least --packageId and/or --module with --resource must be provided. Or use --all to export all package configurations.</value>\r\n    <comment>{Locked=\"--packageId,--module, --resource, --all\"}</comment>\r\n  </data>\r\n  <data name=\"ConfigureExportArgumentConflictWithAllError\" xml:space=\"preserve\">\r\n    <value>Arguments --packageId, --module and --resource cannot be used with --all.</value>\r\n    <comment>{Locked=\"--packageId,--module, --resource, --all\"}</comment>\r\n  </data>\r\n  <data name=\"ConfigureExportCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Exports configuration resources to a configuration file. When used with --all, exports all package configurations. When used with --packageId, exports a WinGetPackage resource of the given package id. When used with --module and --resource, gets the settings of the resource and exports it to the configuration file. If the output configuration file already exists, appends the exported configuration resources.</value>\r\n    <comment>{Locked=\"WinGetPackage,--packageId,--module, --resource\"}</comment>\r\n  </data>\r\n  <data name=\"ConfigureExportCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Exports configuration resources to a configuration file.</value>\r\n  </data>\r\n  <data name=\"ConfigureExportModule\" xml:space=\"preserve\">\r\n    <value>The module of the resource to export.</value>\r\n  </data>\r\n  <data name=\"ConfigureExportPackageId\" xml:space=\"preserve\">\r\n    <value>The package identifier to export.</value>\r\n  </data>\r\n  <data name=\"ConfigureExportResource\" xml:space=\"preserve\">\r\n    <value>The configuration resource to export.</value>\r\n  </data>\r\n  <data name=\"ConfigureExportAll\" xml:space=\"preserve\">\r\n    <value>Exports all package configurations.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_GET_FAILED\" xml:space=\"preserve\">\r\n    <value>The configuration unit failed getting its properties.</value>\r\n  </data>\r\n  <data name=\"ConfigurationExportFailed\" xml:space=\"preserve\">\r\n    <value>Failed exporting configuration.</value>\r\n  </data>\r\n  <data name=\"ConfigureExportUnitDescription\" xml:space=\"preserve\">\r\n    <value>Configure {0}</value>\r\n    <comment>{Locked=\"{0}\"}</comment>\r\n  </data>\r\n  <data name=\"ConfigureExportUnitInstallDescription\" xml:space=\"preserve\">\r\n    <value>Install {0}</value>\r\n    <comment>{Locked=\"{0}\"}</comment>\r\n  </data>\r\n  <data name=\"ConfigurationWarningSetViewTruncated\" xml:space=\"preserve\">\r\n    <value>Some of the data present in the configuration file was truncated for this output; inspect the file contents for the complete content.</value>\r\n  </data>\r\n  <data name=\"ConfigurationWarningValueTruncated\" xml:space=\"preserve\">\r\n    <value>&lt;this value has been truncated; inspect the file contents for the complete text&gt;</value>\r\n    <comment>Keep some form of separator like the \"&lt;&gt;\" around the text so that it stands out from the preceding text.</comment>\r\n  </data>\r\n  <data name=\"ConfigureListCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Shows the high level details for configurations that have been applied to the system. This data can then be used with `configure` commands to get more details.</value>\r\n    <comment>{Locked=\"`configure`\"}</comment>\r\n  </data>\r\n  <data name=\"ConfigureListCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Shows configuration history</value>\r\n  </data>\r\n  <data name=\"ConfigurationHistoryEmpty\" xml:space=\"preserve\">\r\n    <value>There are no configurations in the history.</value>\r\n  </data>\r\n  <data name=\"ConfigurationHistoryItemArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Select items from history</value>\r\n  </data>\r\n  <data name=\"ConfigurationHistoryItemNotFound\" xml:space=\"preserve\">\r\n    <value>No single configuration could be found that matched the provided data. Provide either the full name or part of the identifier that unambiguously matches the desired configuration.</value>\r\n  </data>\r\n  <data name=\"ConfigurationHistoryRemoveArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Remove the item from history</value>\r\n  </data>\r\n  <data name=\"ConfigureListFirstApplied\" xml:space=\"preserve\">\r\n    <value>First Applied</value>\r\n    <comment>Column header for date values indicating when a configuration was first applied to the system.</comment>\r\n  </data>\r\n  <data name=\"ConfigureListIdentifier\" xml:space=\"preserve\">\r\n    <value>Identifier</value>\r\n  </data>\r\n  <data name=\"ConfigureListName\" xml:space=\"preserve\">\r\n    <value>Name</value>\r\n  </data>\r\n  <data name=\"ConfigureListOrigin\" xml:space=\"preserve\">\r\n    <value>Origin</value>\r\n  </data>\r\n  <data name=\"ConfigureListPath\" xml:space=\"preserve\">\r\n    <value>Path</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_HISTORY_ITEM_NOT_FOUND\" xml:space=\"preserve\">\r\n    <value>The specified configuration could not be found.</value>\r\n  </data>\r\n  <data name=\"ConfigurationSetStateCompleted\" xml:space=\"preserve\">\r\n    <value>Completed</value>\r\n    <comment>The state of processing an item.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationSetStateInProgress\" xml:space=\"preserve\">\r\n    <value>In progress</value>\r\n    <comment>The state of processing an item.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationSetStatePending\" xml:space=\"preserve\">\r\n    <value>Pending</value>\r\n    <comment>The state of processing an item.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationSetStateUnknown\" xml:space=\"preserve\">\r\n    <value>Unknown</value>\r\n    <comment>The state of processing an item.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationStatusWatchArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Monitor configuration status.</value>\r\n    <comment>As in \"to monitor the status of a configuration being applied\".</comment>\r\n  </data>\r\n  <data name=\"ConfigurationUnitStateCompleted\" xml:space=\"preserve\">\r\n    <value>Completed</value>\r\n    <comment>The state of processing an item.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationUnitStateInProgress\" xml:space=\"preserve\">\r\n    <value>In progress</value>\r\n    <comment>The state of processing an item.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationUnitStatePending\" xml:space=\"preserve\">\r\n    <value>Pending</value>\r\n    <comment>The state of processing an item.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationUnitStateSkipped\" xml:space=\"preserve\">\r\n    <value>Skipped</value>\r\n    <comment>The state of processing an item.</comment>\r\n  </data>\r\n  <data name=\"ConfigurationUnitStateUnknown\" xml:space=\"preserve\">\r\n    <value>Unknown</value>\r\n    <comment>The state of processing an item.</comment>\r\n  </data>\r\n  <data name=\"ConfigureListApplyBegun\" xml:space=\"preserve\">\r\n    <value>Apply Started</value>\r\n    <comment>When the configuration application started.</comment>\r\n  </data>\r\n  <data name=\"ConfigureListApplyEnded\" xml:space=\"preserve\">\r\n    <value>Apply Ended</value>\r\n    <comment>When the configuration application ended.</comment>\r\n  </data>\r\n  <data name=\"ConfigureListResult\" xml:space=\"preserve\">\r\n    <value>Result</value>\r\n  </data>\r\n  <data name=\"ConfigureListResultDescription\" xml:space=\"preserve\">\r\n    <value>Details</value>\r\n  </data>\r\n  <data name=\"ConfigureListState\" xml:space=\"preserve\">\r\n    <value>State</value>\r\n    <comment>The state of processing an item.</comment>\r\n  </data>\r\n  <data name=\"ConfigureListUnit\" xml:space=\"preserve\">\r\n    <value>Unit</value>\r\n  </data>\r\n  <data name=\"StoreInstall_PackageNotAvailableForCurrentSystem\" xml:space=\"preserve\">\r\n    <value>The package is not compatible with the current Windows version or platform.</value>\r\n  </data>\r\n  <data name=\"ConfigurationSuppressPrologueArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Suppress showing initial configuration details when possible</value>\r\n  </data>\r\n  <data name=\"MSStoreDownloadMultiplePackagesNotice\" xml:space=\"preserve\">\r\n    <value>Multiple Microsoft Store packages may be downloaded targeting different platforms and architectures. --platform, --architecture can be used to filter the packages.</value>\r\n    <comment>{Locked=\"--platform--architecture\"}</comment>\r\n  </data>\r\n  <data name=\"MSStoreDownloadGetLicenseForbidden\" xml:space=\"preserve\">\r\n    <value>Failed to retrieve Microsoft Store package license. The Microsoft Entra Id account is not a member of Global Administrator, User Administrator, or License Administrator. Use --skip-license to skip retrieving Microsoft Store package license.</value>\r\n    <comment>{Locked=\"Global Administrator,User Administrator,License Administrator,--skip-license\"}</comment>\r\n  </data>\r\n  <data name=\"MSStoreDownloadPackageDownloadNotSupported\" xml:space=\"preserve\">\r\n    <value>The Microsoft Store package does not support download.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_SFSCLIENT_PACKAGE_NOT_SUPPORTED\" xml:space=\"preserve\">\r\n    <value>The Microsoft Store package does not support download.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED_FORBIDDEN\" xml:space=\"preserve\">\r\n    <value>Failed to retrieve Microsoft Store package license. The Microsoft Entra Id account does not have required privilege.</value>\r\n  </data>\r\n  <data name=\"WINGET_CONFIG_ERROR_PARAMETER_INTEGRITY_BOUNDARY\" xml:space=\"preserve\">\r\n    <value>Parameter cannot be passed across integrity boundary.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_INSTALLER_ZERO_BYTE_FILE\" xml:space=\"preserve\">\r\n    <value>Downloaded zero byte installer; ensure that your network connection is working properly.</value>\r\n  </data>\r\n  <data name=\"InstallerZeroByteFile\" xml:space=\"preserve\">\r\n    <value>Downloaded zero byte installer; ensure that your network connection is working properly.</value>\r\n  </data>\r\n  <data name=\"FontCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>Manage fonts</value>\r\n  </data>\r\n  <data name=\"FontCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>Manage fonts with sub-commands. Fonts can be installed, upgraded, or uninstalled similar to packages. </value>\r\n  </data>\r\n  <data name=\"FontFamily\" xml:space=\"preserve\">\r\n    <value>Family</value>\r\n    <comment>\"Family\" represents the font family such as 'Arial' or 'Times New Roman'.</comment>\r\n  </data>\r\n  <data name=\"FontFaces\" xml:space=\"preserve\">\r\n    <value>Faces</value>\r\n    <comment>\"Faces\" represents the typeface of the font family such as 'Bold' or 'Italic'</comment>\r\n  </data>\r\n  <data name=\"FontFamilyNameArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Filter results by family name</value>\r\n    <comment>\"Family\" represents the font family such as 'Arial' or 'Times New Roman'.</comment>\r\n  </data>\r\n  <data name=\"FontFace\" xml:space=\"preserve\">\r\n    <value>Face</value>\r\n    <comment>\"Face\" represents the typeface of a font family such as 'Bold' or 'Italic'</comment>\r\n  </data>\r\n  <data name=\"FontFilePaths\" xml:space=\"preserve\">\r\n    <value>Paths</value>\r\n  </data>\r\n  <data name=\"NoInstalledFontFound\" xml:space=\"preserve\">\r\n    <value>No installed font found matching input criteria.</value>\r\n  </data>\r\n  <data name=\"FontListCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>List installed fonts</value>\r\n  </data>\r\n  <data name=\"FontListCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>List all installed fonts, all font files, or full details of a specific font.</value>\r\n  </data>\r\n  <data name=\"FontVersion\" xml:space=\"preserve\">\r\n    <value>Version</value>\r\n  </data>\r\n  <data name=\"ConfigurationModules\" xml:space=\"preserve\">\r\n    <value>Configuration Modules</value>\r\n    <comment>PowerShell Modules that are used for the Configuration feature</comment>\r\n  </data>\r\n  <data name=\"InstallerDownloadRequiresAuthentication\" xml:space=\"preserve\">\r\n    <value>The package installer requires authentication. Authentication prompt may appear when necessary. Authenticated information will be shared with the installer download url.</value>\r\n  </data>\r\n  <data name=\"InstallerDownloadAuthenticationNotSupported\" xml:space=\"preserve\">\r\n    <value>Failed to download installer. This WinGet version does not support the installer download authentication method. Try upgrading to latest WinGet version.</value>\r\n    <comment>{Locked=\"WinGet\"}</comment>\r\n  </data>\r\n  <data name=\"InstallerDownloadAuthenticationFailed\" xml:space=\"preserve\">\r\n    <value>Failed to download installer. Authentication failed.</value>\r\n  </data>\r\n  <data name=\"ConfigurationProcessorPath\" xml:space=\"preserve\">\r\n    <value>Specify the path to the configuration processor</value>\r\n  </data>\r\n  <data name=\"DscCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>DSC v3 resource commands</value>\r\n    <comment>DSC stands for \"Desired State Configuration\". It should already have a locked translation.</comment>\r\n  </data>\r\n  <data name=\"DscCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>The sub-commands here implement Desired State Configuration (DSC) v3 resources for configuring WinGet and packages.</value>\r\n    <comment>{Locked=\"WinGet\"}</comment>\r\n  </data>\r\n  <data name=\"DscResourceFunctionDescriptionGet\" xml:space=\"preserve\">\r\n    <value>Get the resource state</value>\r\n  </data>\r\n  <data name=\"DscResourceFunctionDescriptionSet\" xml:space=\"preserve\">\r\n    <value>Set the resource state</value>\r\n  </data>\r\n  <data name=\"DscResourceFunctionDescriptionWhatIf\" xml:space=\"preserve\">\r\n    <value>Describe required state changes</value>\r\n  </data>\r\n  <data name=\"DscResourceFunctionDescriptionTest\" xml:space=\"preserve\">\r\n    <value>Test the resource state</value>\r\n  </data>\r\n  <data name=\"DscResourceFunctionDescriptionDelete\" xml:space=\"preserve\">\r\n    <value>Delete the resource state</value>\r\n  </data>\r\n  <data name=\"DscResourceFunctionDescriptionExport\" xml:space=\"preserve\">\r\n    <value>Get all state instances</value>\r\n  </data>\r\n  <data name=\"DscResourceFunctionDescriptionValidate\" xml:space=\"preserve\">\r\n    <value>Validate group contents</value>\r\n  </data>\r\n  <data name=\"DscResourceFunctionDescriptionResolve\" xml:space=\"preserve\">\r\n    <value>Resolve external state</value>\r\n  </data>\r\n  <data name=\"DscResourceFunctionDescriptionAdapter\" xml:space=\"preserve\">\r\n    <value>Run the adapter</value>\r\n  </data>\r\n  <data name=\"DscResourceFunctionDescriptionSchema\" xml:space=\"preserve\">\r\n    <value>Get the resource schema</value>\r\n  </data>\r\n  <data name=\"DscResourceFunctionDescriptionManifest\" xml:space=\"preserve\">\r\n    <value>Get the resource manifest</value>\r\n  </data>\r\n  <data name=\"DscPackageResourceShortDescription\" xml:space=\"preserve\">\r\n    <value>Manage package state</value>\r\n  </data>\r\n  <data name=\"DscPackageResourceLongDescription\" xml:space=\"preserve\">\r\n    <value>Manage packages through WinGet.</value>\r\n    <comment>{Locked=\"WinGet\"}</comment>\r\n  </data>\r\n  <data name=\"DscResourcePropertyDescriptionExist\" xml:space=\"preserve\">\r\n    <value>Indicates whether an instance should or does exist.</value>\r\n  </data>\r\n  <data name=\"DscResourcePropertyDescriptionInDesiredState\" xml:space=\"preserve\">\r\n    <value>Indicates whether an instance is in the desired state.</value>\r\n  </data>\r\n  <data name=\"DscResourcePropertyDescriptionPackageId\" xml:space=\"preserve\">\r\n    <value>The identifier of the package.</value>\r\n  </data>\r\n  <data name=\"DscResourcePropertyDescriptionPackageSource\" xml:space=\"preserve\">\r\n    <value>The source of the package.</value>\r\n  </data>\r\n  <data name=\"DscResourcePropertyDescriptionPackageVersion\" xml:space=\"preserve\">\r\n    <value>The version of the package.</value>\r\n  </data>\r\n  <data name=\"DscResourcePropertyDescriptionPackageMatchOption\" xml:space=\"preserve\">\r\n    <value>The method for matching the identifier with a package.</value>\r\n  </data>\r\n  <data name=\"DscResourcePropertyDescriptionPackageUseLatest\" xml:space=\"preserve\">\r\n    <value>Indicate that the latest available version of the package should be installed.</value>\r\n  </data>\r\n  <data name=\"DscResourcePropertyDescriptionPackageInstallMode\" xml:space=\"preserve\">\r\n    <value>The install mode to use if needed.</value>\r\n  </data>\r\n  <data name=\"DscResourcePropertyDescriptionPackageScope\" xml:space=\"preserve\">\r\n    <value>The target scope of the package.</value>\r\n  </data>\r\n  <data name=\"DscResourcePropertyDescriptionAcceptAgreements\" xml:space=\"preserve\">\r\n    <value>Indicates whether to accept agreements for sources and packages.</value>\r\n  </data>\r\n  <data name=\"DscUserSettingsFileShortDescription\" xml:space=\"preserve\">\r\n    <value>Manage user settings file</value>\r\n  </data>\r\n  <data name=\"DscUserSettingsFileLongDescription\" xml:space=\"preserve\">\r\n    <value>Manage the user settings of WinGet.</value>\r\n    <comment>{Locked=\"WinGet\"}</comment>\r\n  </data>\r\n  <data name=\"DscResourcePropertyDescriptionUserSettingsFileSettings\" xml:space=\"preserve\">\r\n    <value>The settings json file content.</value>\r\n  </data>\r\n  <data name=\"DscResourcePropertyDescriptionUserSettingsFileAction\" xml:space=\"preserve\">\r\n    <value>The action used to apply the settings.</value>\r\n  </data>\r\n  <data name=\"CorrelationArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Value is logged for correlation</value>\r\n  </data>\r\n  <data name=\"DscSourceResourceShortDescription\" xml:space=\"preserve\">\r\n    <value>Manage source configuration</value>\r\n  </data>\r\n  <data name=\"DscSourceResourceLongDescription\" xml:space=\"preserve\">\r\n    <value>Manage the sources of WinGet.</value>\r\n    <comment>{Locked=\"WinGet\"}</comment>\r\n  </data>\r\n  <data name=\"DscResourcePropertyDescriptionSourceName\" xml:space=\"preserve\">\r\n    <value>The name to use for the source.</value>\r\n  </data>\r\n  <data name=\"DscResourcePropertyDescriptionSourceArgument\" xml:space=\"preserve\">\r\n    <value>The argument for the source.</value>\r\n  </data>\r\n  <data name=\"DscResourcePropertyDescriptionSourceType\" xml:space=\"preserve\">\r\n    <value>The type of the source.</value>\r\n  </data>\r\n  <data name=\"DscResourcePropertyDescriptionSourceTrustLevel\" xml:space=\"preserve\">\r\n    <value>The trust level of the source.</value>\r\n  </data>\r\n  <data name=\"DscResourcePropertyDescriptionSourceExplicit\" xml:space=\"preserve\">\r\n    <value>Whether the source is included when calls don't specify a source.</value>\r\n  </data>\r\n  <data name=\"ConfigurationApplyingUnit\" xml:space=\"preserve\">\r\n    <value>Applying configuration unit...</value>\r\n  </data>\r\n  <data name=\"ConfigurationExportingUnit\" xml:space=\"preserve\">\r\n    <value>Exporting configuration unit...</value>\r\n  </data>\r\n  <data name=\"ConfigurationGettingUnitProcessors\" xml:space=\"preserve\">\r\n    <value>Getting configuration unit processors...</value>\r\n  </data>\r\n  <data name=\"ConfigurationExportInstallRequiredModule\" xml:space=\"preserve\">\r\n    <value>Ensure required module for export [{0}]</value>\r\n    <comment>{Locked=\"{0}\"}</comment>\r\n  </data>\r\n  <data name=\"ConfigurationExportInstallRequiredModuleFailed\" xml:space=\"preserve\">\r\n    <value>Failed to test or acquire required module. Related settings will not be exported.</value>\r\n  </data>\r\n  <data name=\"ConfigurationExportUnitStart\" xml:space=\"preserve\">\r\n    <value>Export [{0}]</value>\r\n    <comment>{Locked=\"{0}\"}</comment>\r\n  </data>\r\n  <data name=\"ConfigurationExportUnitFailed\" xml:space=\"preserve\">\r\n    <value>Failed to export the resource.</value>\r\n  </data>\r\n  <data name=\"ConfigurationExportFailedToGetUnitProcessors\" xml:space=\"preserve\">\r\n    <value>Failed to get unit processors. Individual package settings will not be exported.</value>\r\n  </data>\r\n  <data name=\"OutputDirectoryArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Directory where the results are to be written</value>\r\n  </data>\r\n  <data name=\"ConfigurationInstallDscPackage\" xml:space=\"preserve\">\r\n    <value>Desired State Configuration package not found on the system. Installing the package...</value>\r\n  </data>\r\n  <data name=\"ConfigurationInstallDscPackageFailed\" xml:space=\"preserve\">\r\n    <value>Failed to install Desired State Configuration package. Install the package manually or provide the path to dsc.exe through --processor-path argument.</value>\r\n    <comment>{Locked=\"dsc.exe\",\"--processor-path\"}</comment>\r\n  </data>\r\n  <data name=\"DscResourcePropertyDescriptionAdminSettingsSettings\" xml:space=\"preserve\">\r\n    <value>An object containing the administrator settings and their values.</value>\r\n  </data>\r\n  <data name=\"DscAdminSettingsResourceShortDescription\" xml:space=\"preserve\">\r\n    <value>Manage administrator settings</value>\r\n  </data>\r\n  <data name=\"DscAdminSettingsResourceLongDescription\" xml:space=\"preserve\">\r\n    <value>Manage the administrator settings of WinGet.</value>\r\n    <comment>{Locked=\"WinGet\"}</comment>\r\n  </data>\r\n  <data name=\"ResetAllAdminSettingsArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Resets all admin settings</value>\r\n  </data>\r\n  <data name=\"ResetAllAdminSettingsSucceeded\" xml:space=\"preserve\">\r\n    <value>All admin settings reset.</value>\r\n  </data>\r\n  <data name=\"McpCommandShortDescription\" xml:space=\"preserve\">\r\n    <value>MCP information</value>\r\n    <comment>MCP stands for Model Context Protocol and should probably remain as-is</comment>\r\n  </data>\r\n  <data name=\"McpCommandLongDescription\" xml:space=\"preserve\">\r\n    <value>MCP (Model Context Protocol) information for the Windows Package Manager.</value>\r\n  </data>\r\n  <data name=\"McpConfigurationPreamble\" xml:space=\"preserve\">\r\n    <value>To manually configure the Windows Package Manager MCP server with your MCP client, use the following JSON fragment in the `servers` object:</value>\r\n    <comment>{Locked=\"`servers`\"}\r\nMCP stands for Model Context Protocol and should probably remain as-is.\r\nAn unlocalized JSON fragment will follow on another line.</comment>\r\n  </data>\r\n  <data name=\"PolicyEnableMcpServer\" xml:space=\"preserve\">\r\n    <value>Enable Windows Package Manager MCP Server</value>\r\n  </data>\r\n  <data name=\"OSVersionDescription\" xml:space=\"preserve\">\r\n    <value>Target OS version</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_INSTALL_FAILED\" xml:space=\"preserve\">\r\n    <value>Failed installing one or more fonts.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_SUPPORTED\" xml:space=\"preserve\">\r\n    <value>Font file is not supported and cannot be installed.</value>\r\n  </data>\r\n  <data name=\"FontFileNotSupported\" xml:space=\"preserve\">\r\n    <value>One or more fonts in the font package is not supported and cannot be installed.</value>\r\n  </data>\r\n  <data name=\"FontInstallFailed\" xml:space=\"preserve\">\r\n    <value>Font install failed; cleaning up.</value>\r\n  </data>\r\n  <data name=\"FontAlreadyInstalled\" xml:space=\"preserve\">\r\n    <value>Font already installed.</value>\r\n  </data>\r\n  <data name=\"FontPackage\" xml:space=\"preserve\">\r\n    <value>Package Id</value>\r\n  </data>\r\n  <data name=\"FontWinGetSupported\" xml:space=\"preserve\">\r\n    <value>WinGet Supported</value>\r\n  </data>\r\n  <data name=\"FontTitle\" xml:space=\"preserve\">\r\n    <value>Title</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_FOUND\" xml:space=\"preserve\">\r\n    <value>Font file not found.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_UNINSTALL_FAILED\" xml:space=\"preserve\">\r\n    <value>Font uninstall failed. The font may not be in a good state. Try uninstalling after a restart.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_VALIDATION_FAILED\" xml:space=\"preserve\">\r\n    <value>Font validation failed.</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_ROLLBACK_FAILED\" xml:space=\"preserve\">\r\n    <value>Font rollback failed. The font may not be in a good state. Try uninstalling after a restart.</value>\r\n  </data>\r\n  <data name=\"FontDetailsArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Show font file detailed information.</value>\r\n  </data>\r\n  <data name=\"FontValidationFailed\" xml:space=\"preserve\">\r\n    <value>Validation of the font package failed.</value>\r\n  </data>\r\n  <data name=\"FontRollbackFailed\" xml:space=\"preserve\">\r\n    <value>Rollback attempt for failed font install was unsuccessful. A restart may be required to successfully uninstall the font.</value>\r\n  </data>\r\n  <data name=\"FontUninstallFailed\" xml:space=\"preserve\">\r\n    <value>Font package uninstall failed. This is often due to the fonts being in use by the system or an application. Uninstall may be successful after restarting your computer.</value>\r\n  </data>\r\n  <data name=\"FontStatusOK\" xml:space=\"preserve\">\r\n    <value>OK</value>\r\n    <comment>\"OK\" means the font is in a good healthy state</comment>\r\n  </data>\r\n  <data name=\"FontStatusCorrupt\" xml:space=\"preserve\">\r\n    <value>Corrupt</value>\r\n    <comment>\"Corrupt\" refers to an install that is in a corrupted or bad state, and needs repair.</comment>\r\n  </data>\r\n  <data name=\"FontStatus\" xml:space=\"preserve\">\r\n    <value>Status</value>\r\n  </data>\r\n  <data name=\"FontStatusUnknown\" xml:space=\"preserve\">\r\n    <value>Unknown</value>\r\n  </data>\r\n  <data name=\"APPINSTALLER_CLI_ERROR_FONT_ALREADY_INSTALLED\" xml:space=\"preserve\">\r\n    <value>Font package is already installed.</value>\r\n  </data>\r\n  <data name=\"ListDetailsArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Show detailed information about packages</value>\r\n    <comment>Providing this argument causes the CLI to output additional details about installed application packages.</comment>\r\n  </data>\r\n  <data name=\"ShowLabelChannel\" xml:space=\"preserve\">\r\n    <value>Channel:</value>\r\n    <comment>Precedes a string value that names the delivery channel for the software package (ex. stable, beta).</comment>\r\n  </data>\r\n  <data name=\"ShowListLocalIdentifier\" xml:space=\"preserve\">\r\n    <value>Local Identifier:</value>\r\n    <comment>Precedes a value that is the unique identifier for the installed package on the local system.</comment>\r\n  </data>\r\n  <data name=\"ShowListPackageFamilyName\" xml:space=\"preserve\">\r\n    <value>Package Family Name:</value>\r\n    <comment>Precedes a value that is the APPX/MSIX package family name of the installed package.</comment>\r\n  </data>\r\n  <data name=\"ShowListProductCode\" xml:space=\"preserve\">\r\n    <value>Product Code:</value>\r\n    <comment>Precedes a value that is the Add/Remove Programs identifier in the registry. This is also the Product Code value as defined in MSI installers.</comment>\r\n  </data>\r\n  <data name=\"ShowListUpgradeCode\" xml:space=\"preserve\">\r\n    <value>Upgrade Code:</value>\r\n    <comment>Precedes a value that is the MSI Upgrade Code for the installed package.</comment>\r\n  </data>\r\n  <data name=\"ShowListInstalledScope\" xml:space=\"preserve\">\r\n    <value>Installed Scope:</value>\r\n    <comment>Precedes a value that is the scope of the installation of the package (ex. user, machine).</comment>\r\n  </data>\r\n  <data name=\"ShowListInstalledArchitecture\" xml:space=\"preserve\">\r\n    <value>Installed Architecture:</value>\r\n    <comment>Precedes a value that is the installed architecture of the package (ex. x86, x64, ARM64).</comment>\r\n  </data>\r\n  <data name=\"ShowListInstalledLocale\" xml:space=\"preserve\">\r\n    <value>Installed Locale:</value>\r\n    <comment>Precedes a value that is the locale of the installed package.</comment>\r\n  </data>\r\n  <data name=\"ShowListInstalledLocation\" xml:space=\"preserve\">\r\n    <value>Installed Location:</value>\r\n    <comment>Precedes a value that is the directory path to the installed package.</comment>\r\n  </data>\r\n  <data name=\"ShowListInstalledSource\" xml:space=\"preserve\">\r\n    <value>Origin Source:</value>\r\n    <comment>Precedes a value that names the package source where the installed package originated from.</comment>\r\n  </data>\r\n  <data name=\"ShowListAvailableUpgrades\" xml:space=\"preserve\">\r\n    <value>Available Upgrades:</value>\r\n    <comment>Precedes a list of package upgrades available for the installed package.</comment>\r\n  </data>\r\n  <data name=\"ShowListInstallerCategory\" xml:space=\"preserve\">\r\n    <value>Installer Category:</value>\r\n    <comment>Precedes a value that indicates the category of the installer for the installed package (ex. exe, msi, msix).</comment>\r\n  </data>\r\n  <data name=\"SourceEditOldValue\" xml:space=\"preserve\">\r\n    <value>Old Value</value>\r\n    <comment>Column title for listing edit changes.</comment>\r\n  </data>\r\n  <data name=\"SourceEditNewValue\" xml:space=\"preserve\">\r\n    <value>New Value</value>\r\n    <comment>Column title for listing the new value.</comment>\r\n  </data>\r\n  <data name=\"SourcePriorityArgumentDescription\" xml:space=\"preserve\">\r\n    <value>Priority; higher numbers first</value>\r\n    <comment>This argument sets the numerical priority of the source. Higher values will be first in priority.</comment>\r\n  </data>\r\n  <data name=\"SourceListPriority\" xml:space=\"preserve\">\r\n    <value>Priority</value>\r\n    <comment>Label for the priority of the source with respect to other sources. Higher values come first in the order.</comment>\r\n  </data>\r\n  <data name=\"DscResourcePropertyDescriptionSourcePriority\" xml:space=\"preserve\">\r\n    <value>The priority of the source. Higher values are sorted first in the order.</value>\r\n  </data>\r\n  <data name=\"MultiplePackagesFoundFilteredBySourcePriority\" xml:space=\"preserve\">\r\n    <value>Results have been filtered to the highest matched source priority.</value>\r\n    <comment>A warning message to indicate to the user that the results of a search have been filtered by choosing only those matching the highest source priority amongst the results.</comment>\r\n  </data>\r\n</root>\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/ARPChanges.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestSource.h\"\r\n#include \"TestHooks.h\"\r\n#include <Workflows/WorkflowBase.h>\r\n#include <Workflows/InstallFlow.h>\r\n#include <winget/Manifest.h>\r\n#include <winget/ARPCorrelationAlgorithms.h>\r\n#include <Microsoft/PredefinedInstalledSourceFactory.h>\r\n#include <winget/PackageVersionSelection.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller;\r\nusing namespace AppInstaller::CLI;\r\nusing namespace AppInstaller::CLI::Execution;\r\nusing namespace AppInstaller::CLI::Workflow;\r\nusing namespace AppInstaller::Logging;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Repository::Correlation;\r\n\r\nstruct TestTelemetry : public TelemetryTraceLogger\r\n{\r\n    void LogSuccessfulInstallARPChange(\r\n        std::string_view sourceIdentifier,\r\n        std::string_view packageIdentifier,\r\n        std::string_view packageVersion,\r\n        std::string_view packageChannel,\r\n        size_t changesToARP,\r\n        size_t matchesInARP,\r\n        size_t countOfIntersectionOfChangesAndMatches,\r\n        std::string_view arpName,\r\n        std::string_view arpVersion,\r\n        std::string_view arpPublisher,\r\n        std::string_view arpLanguage) const noexcept override\r\n    {\r\n        WasLogSuccessfulInstallARPChangeCalled = true;\r\n        if (OnLogSuccessfulInstallARPChange)\r\n        {\r\n            OnLogSuccessfulInstallARPChange(\r\n                sourceIdentifier, packageIdentifier, packageVersion, packageChannel,\r\n                changesToARP, matchesInARP, countOfIntersectionOfChangesAndMatches,\r\n                arpName, arpVersion, arpPublisher, arpLanguage);\r\n        }\r\n    }\r\n\r\n    std::function<void(\r\n        std::string_view, std::string_view, std::string_view, std::string_view,\r\n        size_t, size_t, size_t,\r\n        std::string_view, std::string_view, std::string_view, std::string_view)> OnLogSuccessfulInstallARPChange;\r\n\r\n    mutable bool WasLogSuccessfulInstallARPChangeCalled = false;\r\n};\r\n\r\nstruct ARPTestContext : public Context\r\n{\r\n    ARPTestContext(Manifest::InstallerTypeEnum installerType = Manifest::InstallerTypeEnum::Exe) :\r\n        Context(OStream, IStream), SourceFactory([this](const SourceDetails&) { return Source; })\r\n    {\r\n        // Put installer in to control whether arp change code cares to run\r\n        Manifest::ManifestInstaller installer;\r\n        installer.BaseInstallerType = installerType;\r\n        Add<Data::Installer>(std::move(installer));\r\n\r\n        // Put in an empty manifest by default\r\n        Manifest::Manifest manifest;\r\n        manifest.Id = \"Installing.Id\";\r\n        manifest.Version = \"Installing.Version\";\r\n        manifest.Channel = \"Installing.Channel\";\r\n        manifest.DefaultLocalization.Add<Manifest::Localization::PackageName>(\"Installing.Name\");\r\n        Add<Data::Manifest>(std::move(manifest));\r\n\r\n        // Set up logger to intercept event\r\n        Logger = std::make_shared<TestTelemetry>();\r\n        TestHook_SetTelemetryOverride(Logger);\r\n\r\n        Logger->OnLogSuccessfulInstallARPChange = [this](\r\n            std::string_view sourceIdentifier,\r\n            std::string_view packageIdentifier,\r\n            std::string_view packageVersion,\r\n            std::string_view packageChannel,\r\n            size_t changesToARP,\r\n            size_t matchesInARP,\r\n            size_t countOfIntersectionOfChangesAndMatches,\r\n            std::string_view arpName,\r\n            std::string_view arpVersion,\r\n            std::string_view arpPublisher,\r\n            std::string_view arpLanguage)\r\n        {\r\n            SourceIdentifier = sourceIdentifier;\r\n            PackageIdentifier = packageIdentifier;\r\n            PackageVersion = packageVersion;\r\n            PackageChannel = packageChannel;\r\n            ChangesToARP = changesToARP;\r\n            MatchesInARP = matchesInARP;\r\n            CountOfIntersectionOfChangesAndMatches = countOfIntersectionOfChangesAndMatches;\r\n            ARPName = arpName;\r\n            ARPVersion = arpVersion;\r\n            ARPPublisher = arpPublisher;\r\n            ARPLanguage = arpLanguage;\r\n        };\r\n\r\n        // Inject our source\r\n        TestHook_SetSourceFactoryOverride(std::string{ Repository::Microsoft::PredefinedInstalledSourceFactory::Type() }, SourceFactory);\r\n\r\n        Source = std::make_shared<TestSource>();\r\n        Source->SearchFunction = [&](const SearchRequest& request)\r\n        {\r\n            return request.IsForEverything() ? EverythingResult : MatchResult;\r\n        };\r\n\r\n        // The package version is used to get the source identifier\r\n        Add<Data::PackageVersion>(TestPackageVersion::Make(Get<Data::Manifest>(), Source));\r\n\r\n        // Populate everything result with a few items\r\n        AddEverythingResult(\"Id1\", \"Name1\", \"Publisher1\", \"1.0\");\r\n        AddEverythingResult(\"Id2\", \"Name2\", \"Publisher2\", \"2.0\");\r\n    }\r\n\r\n    ~ARPTestContext()\r\n    {\r\n        TestHook_ClearSourceFactoryOverrides();\r\n        TestHook_SetTelemetryOverride({});\r\n    }\r\n\r\n    void AddEverythingResult(std::string_view id, std::string_view name, std::string_view publisher, std::string_view version)\r\n    {\r\n        AddResult(EverythingResult, id, name, publisher, version);\r\n    }\r\n\r\n    void AddMatchResult(std::string_view id, std::string_view name, std::string_view publisher, std::string_view version)\r\n    {\r\n        AddResult(MatchResult, id, name, publisher, version);\r\n    }\r\n\r\n    void ExpectEvent(size_t arpChanges, size_t matches, size_t overlap, const std::shared_ptr<ICompositePackage>& arpEntry = nullptr)\r\n    {\r\n        REQUIRE(Logger->WasLogSuccessfulInstallARPChangeCalled);\r\n\r\n        const auto& manifest = Get<Data::Manifest>();\r\n\r\n        REQUIRE(Source->GetIdentifier() == SourceIdentifier);\r\n        REQUIRE(manifest.Id == PackageIdentifier);\r\n        REQUIRE(manifest.Version == PackageVersion);\r\n        REQUIRE(manifest.Channel == PackageChannel);\r\n        REQUIRE(arpChanges == ChangesToARP);\r\n        REQUIRE(matches == MatchesInARP);\r\n        REQUIRE(overlap == CountOfIntersectionOfChangesAndMatches);\r\n\r\n        if (arpEntry)\r\n        {\r\n            auto version = GetInstalledVersion(arpEntry);\r\n            REQUIRE(version->GetProperty(PackageVersionProperty::Name) == ARPName);\r\n            REQUIRE(version->GetProperty(PackageVersionProperty::Version) == ARPVersion);\r\n\r\n            auto metadata = version->GetMetadata();\r\n            REQUIRE(metadata[PackageVersionMetadata::Publisher] == ARPPublisher);\r\n            REQUIRE(metadata[PackageVersionMetadata::InstalledLocale] == ARPLanguage);\r\n        }\r\n        else\r\n        {\r\n            REQUIRE(ARPName.empty());\r\n            REQUIRE(ARPVersion.empty());\r\n            REQUIRE(ARPPublisher.empty());\r\n            REQUIRE(ARPLanguage.empty());\r\n        }\r\n    }\r\n\r\n    std::ostringstream OStream;\r\n    std::istringstream IStream;\r\n    std::shared_ptr<TestTelemetry> Logger;\r\n    TestSourceFactory SourceFactory;\r\n    std::shared_ptr<TestSource> Source;\r\n    SearchResult EverythingResult;\r\n    SearchResult MatchResult;\r\n\r\n    // EventData\r\n    std::string SourceIdentifier;\r\n    std::string PackageIdentifier;\r\n    std::string PackageVersion;\r\n    std::string PackageChannel;\r\n    size_t ChangesToARP;\r\n    size_t MatchesInARP;\r\n    size_t CountOfIntersectionOfChangesAndMatches;\r\n    std::string ARPName;\r\n    std::string ARPVersion;\r\n    std::string ARPPublisher;\r\n    std::string ARPLanguage;\r\n\r\n    private:\r\n        void AddResult(SearchResult& result, std::string_view id, std::string_view name, std::string_view publisher, std::string_view version)\r\n        {\r\n            PackageMatchFilter defaultFilter{ PackageMatchField::Id, MatchType::Exact };\r\n            Manifest::Manifest manifest;\r\n\r\n            manifest.Id = id;\r\n            manifest.DefaultLocalization.Add<Manifest::Localization::PackageName>(name);\r\n            manifest.DefaultLocalization.Add<Manifest::Localization::Publisher>(publisher);\r\n            manifest.Version = version;\r\n            manifest.Installers.push_back({});\r\n\r\n            TestPackage::MetadataMap metadata;\r\n            metadata[PackageVersionMetadata::Publisher] = publisher;\r\n\r\n            result.Matches.emplace_back(TestCompositePackage::Make(manifest, std::move(metadata), std::vector<Manifest::Manifest>{}, Source), defaultFilter);\r\n        }\r\n};\r\n\r\n// Override the correlation heuristic by an empty one to ensure that these tests\r\n// consider only the exact matching.\r\nstruct TestHeuristicOverride\r\n{\r\n    TestHeuristicOverride()\r\n    {\r\n        IARPMatchConfidenceAlgorithm::OverrideInstance(&m_algorithm);\r\n    }\r\n\r\n    ~TestHeuristicOverride()\r\n    {\r\n        IARPMatchConfidenceAlgorithm::ResetInstance();\r\n    }\r\n\r\nprivate:\r\n    EmptyMatchConfidenceAlgorithm m_algorithm;\r\n};\r\n\r\nTEST_CASE(\"ARPChanges_MSIX_Ignored\", \"[ARPChanges][workflow]\")\r\n{\r\n    TestHeuristicOverride heuristicOverride;\r\n    ARPTestContext context(Manifest::InstallerTypeEnum::Msix);\r\n\r\n    context << SnapshotARPEntries;\r\n\r\n    REQUIRE(!context.Contains(Data::ARPCorrelationData));\r\n\r\n    context << ReportARPChanges;\r\n\r\n    REQUIRE(!context.Logger->WasLogSuccessfulInstallARPChangeCalled);\r\n}\r\n\r\nTEST_CASE(\"ARPChanges_CheckSnapshot\", \"[ARPChanges][workflow]\")\r\n{\r\n    TestHeuristicOverride heuristicOverride;\r\n    ARPTestContext context;\r\n\r\n    context << SnapshotARPEntries;\r\n\r\n    REQUIRE(context.Contains(Data::ARPCorrelationData));\r\n\r\n    auto snapshot = context.Get<Data::ARPCorrelationData>().GetPreInstallSnapshot();\r\n\r\n    REQUIRE(context.EverythingResult.Matches.size() == snapshot.size());\r\n\r\n    // Destructively match\r\n    for (const auto& match : context.EverythingResult.Matches)\r\n    {\r\n        bool found = false;\r\n        for (auto itr = snapshot.begin(); itr != snapshot.end(); ++itr)\r\n        {\r\n            if (match.Package->GetProperty(PackageProperty::Id) == std::get<0>(*itr))\r\n            {\r\n                REQUIRE(GetInstalledVersion(match.Package)->GetProperty(PackageVersionProperty::Version) == std::get<1>(*itr));\r\n                REQUIRE(GetInstalledVersion(match.Package)->GetProperty(PackageVersionProperty::Channel) == std::get<2>(*itr));\r\n\r\n                snapshot.erase(itr);\r\n                found = true;\r\n                break;\r\n            }\r\n        }\r\n        REQUIRE(found);\r\n    }\r\n\r\n    REQUIRE(snapshot.empty());\r\n}\r\n\r\nTEST_CASE(\"ARPChanges_NoChange_NoMatch\", \"[ARPChanges][workflow]\")\r\n{\r\n    TestHeuristicOverride heuristicOverride;\r\n    ARPTestContext context;\r\n\r\n    context << SnapshotARPEntries;\r\n    REQUIRE(context.Contains(Data::ARPCorrelationData));\r\n\r\n    context << ReportARPChanges;\r\n    context.ExpectEvent(0, 0, 0);\r\n}\r\n\r\nTEST_CASE(\"ARPChanges_NoChange_SingleMatch\", \"[ARPChanges][workflow]\")\r\n{\r\n    TestHeuristicOverride heuristicOverride;\r\n    ARPTestContext context;\r\n\r\n    context << SnapshotARPEntries;\r\n    REQUIRE(context.Contains(Data::ARPCorrelationData));\r\n\r\n    context.AddMatchResult(\"MatchId1\", \"MatchName1\", \"MatchPublisher1\", \"MatchVersion1\");\r\n\r\n    context << ReportARPChanges;\r\n    context.ExpectEvent(0, 1, 0, context.MatchResult.Matches[0].Package);\r\n}\r\n\r\nTEST_CASE(\"ARPChanges_NoChange_MultiMatch\", \"[ARPChanges][workflow]\")\r\n{\r\n    TestHeuristicOverride heuristicOverride;\r\n    ARPTestContext context;\r\n\r\n    context << SnapshotARPEntries;\r\n    REQUIRE(context.Contains(Data::ARPCorrelationData));\r\n\r\n    context.AddMatchResult(\"MatchId1\", \"MatchName1\", \"MatchPublisher1\", \"MatchVersion1\");\r\n    context.AddMatchResult(\"MatchId2\", \"MatchName2\", \"MatchPublisher2\", \"MatchVersion2\");\r\n\r\n    context << ReportARPChanges;\r\n    context.ExpectEvent(0, 2, 0);\r\n}\r\n\r\nTEST_CASE(\"ARPChanges_SingleChange_NoMatch\", \"[ARPChanges][workflow]\")\r\n{\r\n    TestHeuristicOverride heuristicOverride;\r\n    ARPTestContext context;\r\n\r\n    context << SnapshotARPEntries;\r\n    REQUIRE(context.Contains(Data::ARPCorrelationData));\r\n\r\n    context.AddEverythingResult(\"EverythingId1\", \"EverythingName1\", \"EverythingPublisher1\", \"EverythingVersion1\");\r\n\r\n    context << ReportARPChanges;\r\n    context.ExpectEvent(1, 0, 0);\r\n}\r\n\r\nTEST_CASE(\"ARPChanges_SingleChange_SingleMatch\", \"[ARPChanges][workflow]\")\r\n{\r\n    TestHeuristicOverride heuristicOverride;\r\n    ARPTestContext context;\r\n\r\n    context << SnapshotARPEntries;\r\n    REQUIRE(context.Contains(Data::ARPCorrelationData));\r\n\r\n    context.AddEverythingResult(\"EverythingId1\", \"EverythingName1\", \"EverythingPublisher1\", \"EverythingVersion1\");\r\n    context.AddMatchResult(\"MatchId1\", \"MatchName1\", \"MatchPublisher1\", \"MatchVersion1\");\r\n\r\n    context << ReportARPChanges;\r\n    context.ExpectEvent(1, 1, 0, context.MatchResult.Matches.back().Package);\r\n}\r\n\r\nTEST_CASE(\"ARPChanges_SingleChange_MultiMatch\", \"[ARPChanges][workflow]\")\r\n{\r\n    TestHeuristicOverride heuristicOverride;\r\n    ARPTestContext context;\r\n\r\n    context << SnapshotARPEntries;\r\n    REQUIRE(context.Contains(Data::ARPCorrelationData));\r\n\r\n    context.AddEverythingResult(\"EverythingId1\", \"EverythingName1\", \"EverythingPublisher1\", \"EverythingVersion1\");\r\n    context.AddMatchResult(\"MatchId1\", \"MatchName1\", \"MatchPublisher1\", \"MatchVersion1\");\r\n    context.MatchResult.Matches.emplace_back(context.EverythingResult.Matches.back());\r\n\r\n    context << ReportARPChanges;\r\n    context.ExpectEvent(1, 2, 1, context.EverythingResult.Matches.back().Package);\r\n}\r\n\r\nTEST_CASE(\"ARPChanges_MultiChange_NoMatch\", \"[ARPChanges][workflow]\")\r\n{\r\n    TestHeuristicOverride heuristicOverride;\r\n    ARPTestContext context;\r\n\r\n    context << SnapshotARPEntries;\r\n    REQUIRE(context.Contains(Data::ARPCorrelationData));\r\n\r\n    context.AddEverythingResult(\"EverythingId1\", \"EverythingName1\", \"EverythingPublisher1\", \"EverythingVersion1\");\r\n    context.AddEverythingResult(\"EverythingId2\", \"EverythingName2\", \"EverythingPublisher2\", \"EverythingVersion2\");\r\n\r\n    context << ReportARPChanges;\r\n    context.ExpectEvent(2, 0, 0);\r\n}\r\n\r\nTEST_CASE(\"ARPChanges_MultiChange_SingleMatch_NoOverlap\", \"[ARPChanges][workflow]\")\r\n{\r\n    TestHeuristicOverride heuristicOverride;\r\n    ARPTestContext context;\r\n\r\n    context << SnapshotARPEntries;\r\n    REQUIRE(context.Contains(Data::ARPCorrelationData));\r\n\r\n    context.AddEverythingResult(\"EverythingId1\", \"EverythingName1\", \"EverythingPublisher1\", \"EverythingVersion1\");\r\n    context.AddEverythingResult(\"EverythingId2\", \"EverythingName2\", \"EverythingPublisher2\", \"EverythingVersion2\");\r\n    context.AddMatchResult(\"MatchId1\", \"MatchName1\", \"MatchPublisher1\", \"MatchVersion1\");\r\n\r\n    context << ReportARPChanges;\r\n    context.ExpectEvent(2, 1, 0, context.MatchResult.Matches.back().Package);\r\n}\r\n\r\nTEST_CASE(\"ARPChanges_MultiChange_SingleMatch_Overlap\", \"[ARPChanges][workflow]\")\r\n{\r\n    TestHeuristicOverride heuristicOverride;\r\n    ARPTestContext context;\r\n\r\n    context << SnapshotARPEntries;\r\n    REQUIRE(context.Contains(Data::ARPCorrelationData));\r\n\r\n    context.AddEverythingResult(\"EverythingId1\", \"EverythingName1\", \"EverythingPublisher1\", \"EverythingVersion1\");\r\n    context.AddEverythingResult(\"EverythingId2\", \"EverythingName2\", \"EverythingPublisher2\", \"EverythingVersion2\");\r\n    context.MatchResult.Matches.emplace_back(context.EverythingResult.Matches.back());\r\n\r\n    context << ReportARPChanges;\r\n    context.ExpectEvent(2, 1, 1, context.MatchResult.Matches.back().Package);\r\n}\r\n\r\nTEST_CASE(\"ARPChanges_MultiChange_MultiMatch_NoOverlap\", \"[ARPChanges][workflow]\")\r\n{\r\n    TestHeuristicOverride heuristicOverride;\r\n    ARPTestContext context;\r\n\r\n    context << SnapshotARPEntries;\r\n    REQUIRE(context.Contains(Data::ARPCorrelationData));\r\n\r\n    context.AddEverythingResult(\"EverythingId1\", \"EverythingName1\", \"EverythingPublisher1\", \"EverythingVersion1\");\r\n    context.AddEverythingResult(\"EverythingId2\", \"EverythingName2\", \"EverythingPublisher2\", \"EverythingVersion2\");\r\n    context.AddMatchResult(\"MatchId1\", \"MatchName1\", \"MatchPublisher1\", \"MatchVersion1\");\r\n    context.AddMatchResult(\"MatchId2\", \"MatchName2\", \"MatchPublisher2\", \"MatchVersion2\");\r\n\r\n    context << ReportARPChanges;\r\n    context.ExpectEvent(2, 2, 0);\r\n}\r\n\r\nTEST_CASE(\"ARPChanges_MultiChange_MultiMatch_SingleOverlap\", \"[ARPChanges][workflow]\")\r\n{\r\n    TestHeuristicOverride heuristicOverride;\r\n    ARPTestContext context;\r\n\r\n    context << SnapshotARPEntries;\r\n    REQUIRE(context.Contains(Data::ARPCorrelationData));\r\n\r\n    context.AddEverythingResult(\"EverythingId1\", \"EverythingName1\", \"EverythingPublisher1\", \"EverythingVersion1\");\r\n    context.AddEverythingResult(\"EverythingId2\", \"EverythingName2\", \"EverythingPublisher2\", \"EverythingVersion2\");\r\n    context.AddMatchResult(\"MatchId1\", \"MatchName1\", \"MatchPublisher1\", \"MatchVersion1\");\r\n    context.MatchResult.Matches.emplace_back(context.EverythingResult.Matches.back());\r\n\r\n    context << ReportARPChanges;\r\n    context.ExpectEvent(2, 2, 1, context.MatchResult.Matches.back().Package);\r\n}\r\n\r\nTEST_CASE(\"ARPChanges_MultiChange_MultiMatch_MultiOverlap\", \"[ARPChanges][workflow]\")\r\n{\r\n    TestHeuristicOverride heuristicOverride;\r\n    ARPTestContext context;\r\n\r\n    context << SnapshotARPEntries;\r\n    REQUIRE(context.Contains(Data::ARPCorrelationData));\r\n\r\n    context.AddEverythingResult(\"EverythingId1\", \"EverythingName1\", \"EverythingPublisher1\", \"EverythingVersion1\");\r\n    context.MatchResult.Matches.emplace_back(context.EverythingResult.Matches.back());\r\n    context.AddEverythingResult(\"EverythingId2\", \"EverythingName2\", \"EverythingPublisher2\", \"EverythingVersion2\");\r\n    context.MatchResult.Matches.emplace_back(context.EverythingResult.Matches.back());\r\n\r\n    context << ReportARPChanges;\r\n    context.ExpectEvent(2, 2, 2);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/AdminSettings.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"TestCommon.h\"\n#include \"TestSettings.h\"\n#include <winget/AdminSettings.h>\n\nusing namespace AppInstaller::Settings;\nusing namespace TestCommon;\n\nTEST_CASE(\"AdminSetting_Enable\", \"[adminSettings]\")\n{\n    WHEN(\"Group policy\")\n    {\n        SECTION(\"Not configured\")\n        {\n            GroupPolicyTestOverride policies;\n            policies.SetState(TogglePolicy::Policy::LocalManifestFiles, PolicyState::NotConfigured);\n            REQUIRE(EnableAdminSetting(BoolAdminSetting::LocalManifestFiles));\n        }\n\n        SECTION(\"Enabled\")\n        {\n            GroupPolicyTestOverride policies;\n            policies.SetState(TogglePolicy::Policy::LocalManifestFiles, PolicyState::Enabled);\n            REQUIRE(EnableAdminSetting(BoolAdminSetting::LocalManifestFiles));\n        }\n\n        SECTION(\"Disabled\")\n        {\n            GroupPolicyTestOverride policies;\n            policies.SetState(TogglePolicy::Policy::LocalManifestFiles, PolicyState::Disabled);\n            REQUIRE_FALSE(EnableAdminSetting(BoolAdminSetting::LocalManifestFiles));\n        }\n    }\n}\n\nTEST_CASE(\"AdminSetting_Disable\", \"[adminSettings]\")\n{\n    WHEN(\"Group policy\")\n    {\n        SECTION(\"Not configured\")\n        {\n            GroupPolicyTestOverride policies;\n            policies.SetState(TogglePolicy::Policy::LocalManifestFiles, PolicyState::NotConfigured);\n            REQUIRE(DisableAdminSetting(BoolAdminSetting::LocalManifestFiles));\n        }\n\n        SECTION(\"Enabled\")\n        {\n            GroupPolicyTestOverride policies;\n            policies.SetState(TogglePolicy::Policy::LocalManifestFiles, PolicyState::Enabled);\n            REQUIRE_FALSE(DisableAdminSetting(BoolAdminSetting::LocalManifestFiles));\n        }\n\n        SECTION(\"Disabled\")\n        {\n            GroupPolicyTestOverride policies;\n            policies.SetState(TogglePolicy::Policy::LocalManifestFiles, PolicyState::Disabled);\n            REQUIRE(DisableAdminSetting(BoolAdminSetting::LocalManifestFiles));\n        }\n    }\n}\n\nTEST_CASE(\"AdminSetting_AllSettingsAreImplemented\", \"[adminSettings]\")\n{\n    for (auto adminSetting : GetAllBoolAdminSettings())\n    {\n        // If we forget to add it to the conversion, it returns Unknown/None\n        REQUIRE(AdminSettingToString(adminSetting) != AdminSettingToString(BoolAdminSetting::Unknown));\n        REQUIRE(StringToBoolAdminSetting(AdminSettingToString(adminSetting)) != BoolAdminSetting::Unknown);\n        REQUIRE(GetAdminSettingPolicy(adminSetting) != TogglePolicy::Policy::None);\n\n        GroupPolicyTestOverride policies;\n        policies.SetState(GetAdminSettingPolicy(adminSetting), PolicyState::NotConfigured);\n\n        // We should be able to configure the state.\n        // If we forget to add it, it won't persist.\n        REQUIRE(EnableAdminSetting(adminSetting));\n        REQUIRE(IsAdminSettingEnabled(adminSetting));\n        REQUIRE(DisableAdminSetting(adminSetting));\n        REQUIRE_FALSE(IsAdminSettingEnabled(adminSetting));\n    }\n}"
  },
  {
    "path": "src/AppInstallerCLITests/AppInstallerCLITests.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" />\r\n  <PropertyGroup Label=\"Globals\">\r\n    <CppWinRTOptimized>true</CppWinRTOptimized>\r\n    <CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>\r\n    <CppWinRTGenerateWindowsMetadata>true</CppWinRTGenerateWindowsMetadata>\r\n    <MinimalCoreWin>true</MinimalCoreWin>\r\n    <VCProjectVersion>15.0</VCProjectVersion>\r\n    <ProjectGuid>{89b1aab4-2bbc-4b65-9ed7-a01d5cf88230}</ProjectGuid>\r\n    <Keyword>Win32Proj</Keyword>\r\n    <RootNamespace>AppInstallerCLITests</RootNamespace>\r\n    <WindowsTargetPlatformVersion>10.0.26100.0</WindowsTargetPlatformVersion>\r\n    <WindowsTargetPlatformMinVersion>10.0.17763.0</WindowsTargetPlatformMinVersion>\r\n    <ProjectName>AppInstallerCLITests</ProjectName>\r\n    <CppWinRTParameters>\r\n    </CppWinRTParameters>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|ARM64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|Win32\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|ARM64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|Win32\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <PropertyGroup Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Debug'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n    <LinkIncremental>true</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Release'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <LinkIncremental>false</LinkIncremental>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\r\n  <ImportGroup Label=\"ExtensionSettings\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"Shared\">\r\n    <Import Project=\"..\\ManifestSchema\\ManifestSchema.vcxitems\" Label=\"Shared\" />\r\n    <Import Project=\"..\\WinGetSchemas\\WinGetSchemas.vcxitems\" Label=\"Shared\" />\r\n    <Import Project=\"..\\CertificateResources\\CertificateResources.vcxitems\" Label=\"Shared\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"PropertySheet.props\" />\r\n  </ImportGroup>\r\n  <PropertyGroup Label=\"UserMacros\" />\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n  </PropertyGroup>\r\n  <PropertyGroup Label=\"Vcpkg\">\r\n    <VcpkgApplocalDeps>false</VcpkgApplocalDeps>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(ProjectDir)\\..\\vcpkg.props\" />\r\n  <ItemDefinitionGroup>\r\n    <ClCompile>\r\n      <PrecompiledHeader>Use</PrecompiledHeader>\r\n      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>\r\n      <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>\r\n      <PreprocessorDefinitions>_CONSOLE;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <DisableSpecificWarnings>5321;%(DisableSpecificWarnings)</DisableSpecificWarnings>\r\n      <AdditionalOptions>%(AdditionalOptions) /permissive- /bigobj /D _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING</AdditionalOptions>\r\n    </ClCompile>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Debug'\">\r\n    <ClCompile>\r\n      <Optimization>Disabled</Optimization>\r\n      <PreprocessorDefinitions>_NO_ASYNCRTIMP;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">$(MSBuildThisFileDirectory)..\\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\\AppInstallerRepositoryCore\\Public;$(MSBuildThisFileDirectory)..\\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\\AppInstallerCommonCore\\Public;$(MSBuildThisFileDirectory)..\\AppInstallerSharedLib\\Public;$(MSBuildThisFileDirectory)..\\AppInstallerCLICore\\Public;$(MSBuildThisFileDirectory)..\\AppInstallerCLICore;$(ProjectDir)..\\SfsClient\\sfs-client\\client\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">$(MSBuildThisFileDirectory)..\\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\\AppInstallerRepositoryCore\\Public;$(MSBuildThisFileDirectory)..\\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\\AppInstallerCommonCore\\Public;$(MSBuildThisFileDirectory)..\\AppInstallerSharedLib\\Public;$(MSBuildThisFileDirectory)..\\AppInstallerCLICore\\Public;$(MSBuildThisFileDirectory)..\\AppInstallerCLICore;$(ProjectDir)..\\SfsClient\\sfs-client\\client\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</TreatWarningAsError>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <AdditionalDependencies Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">wininet.lib;shell32.lib;winsqlite3.lib;shlwapi.lib;icuuc.lib;icuin.lib;urlmon.lib;Advapi32.lib;winhttp.lib;onecoreuap.lib;msi.lib;gdi32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\n      <AdditionalDependencies Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">wininet.lib;shell32.lib;winsqlite3.lib;shlwapi.lib;icuuc.lib;icuin.lib;urlmon.lib;Advapi32.lib;winhttp.lib;onecoreuap.lib;msi.lib;gdi32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\n      <DelayLoadDLLs Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">gdi32.dll</DelayLoadDLLs>\r\n      <DelayLoadDLLs Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">gdi32.dll</DelayLoadDLLs>\r\n    </Link>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">$(ProjectDir)..\\manifest\\shared.manifest</AdditionalManifestFiles>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">$(ProjectDir)..\\manifest\\shared.manifest</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <PostBuildEvent>\r\n      <Command Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">copy \"$(ProjectDir)..\\AppInstallerCLIPackage\\bin\\$(PlatformTarget)\\$(configuration)\\resources.pri\" \"$(TargetDir)\\resources.pri\"</Command>\r\n      <Command Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">copy \"$(ProjectDir)..\\AppInstallerCLIPackage\\bin\\$(PlatformTarget)\\$(configuration)\\resources.pri\" \"$(TargetDir)\\resources.pri\"</Command>\r\n    </PostBuildEvent>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Platform)'=='Win32'\">\r\n    <ClCompile>\r\n      <PreprocessorDefinitions>_NO_ASYNCRTIMP;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">$(MSBuildThisFileDirectory)..\\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\\AppInstallerRepositoryCore\\Public;$(MSBuildThisFileDirectory)..\\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\\AppInstallerCommonCore\\Public;$(MSBuildThisFileDirectory)..\\AppInstallerSharedLib\\Public;$(MSBuildThisFileDirectory)..\\AppInstallerCLICore\\Public;$(MSBuildThisFileDirectory)..\\AppInstallerCLICore;$(ProjectDir)..\\SfsClient\\sfs-client\\client\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</TreatWarningAsError>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <AdditionalDependencies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">wininet.lib;shell32.lib;winsqlite3.lib;shlwapi.lib;icuuc.lib;icuin.lib;urlmon.lib;Advapi32.lib;winhttp.lib;onecoreuap.lib;msi.lib;gdi32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\n      <DelayLoadDLLs Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">gdi32.dll</DelayLoadDLLs>\r\n    </Link>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">$(ProjectDir)..\\manifest\\shared.manifest</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <PostBuildEvent>\r\n      <Command Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">copy \"$(ProjectDir)..\\AppInstallerCLIPackage\\bin\\$(PlatformTarget)\\$(configuration)\\resources.pri\" \"$(TargetDir)\\resources.pri\"</Command>\r\n    </PostBuildEvent>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Release'\">\r\n    <ClCompile>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>_NO_ASYNCRTIMP;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">$(MSBuildThisFileDirectory)..\\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\\AppInstallerRepositoryCore\\Public;$(MSBuildThisFileDirectory)..\\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\\AppInstallerCommonCore\\Public;$(MSBuildThisFileDirectory)..\\AppInstallerSharedLib\\Public;$(MSBuildThisFileDirectory)..\\AppInstallerCLICore\\Public;$(MSBuildThisFileDirectory)..\\AppInstallerCLICore;$(ProjectDir)..\\SfsClient\\sfs-client\\client\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">$(MSBuildThisFileDirectory)..\\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\\AppInstallerRepositoryCore\\Public;$(MSBuildThisFileDirectory)..\\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\\AppInstallerCommonCore\\Public;$(MSBuildThisFileDirectory)..\\AppInstallerSharedLib\\Public;$(MSBuildThisFileDirectory)..\\AppInstallerCLICore\\Public;$(MSBuildThisFileDirectory)..\\AppInstallerCLICore;$(ProjectDir)..\\SfsClient\\sfs-client\\client\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">$(MSBuildThisFileDirectory)..\\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\\AppInstallerRepositoryCore\\Public;$(MSBuildThisFileDirectory)..\\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\\AppInstallerCommonCore\\Public;$(MSBuildThisFileDirectory)..\\AppInstallerSharedLib\\Public;$(MSBuildThisFileDirectory)..\\AppInstallerCLICore\\Public;$(MSBuildThisFileDirectory)..\\AppInstallerCLICore;$(ProjectDir)..\\SfsClient\\sfs-client\\client\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">true</TreatWarningAsError>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <AdditionalDependencies Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">wininet.lib;shell32.lib;winsqlite3.lib;shlwapi.lib;icuuc.lib;icuin.lib;urlmon.lib;Advapi32.lib;winhttp.lib;onecoreuap.lib;msi.lib;gdi32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\n      <AdditionalDependencies Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">wininet.lib;shell32.lib;winsqlite3.lib;shlwapi.lib;icuuc.lib;icuin.lib;urlmon.lib;Advapi32.lib;winhttp.lib;onecoreuap.lib;msi.lib;gdi32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\n      <AdditionalDependencies Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">wininet.lib;shell32.lib;winsqlite3.lib;shlwapi.lib;icuuc.lib;icuin.lib;urlmon.lib;Advapi32.lib;winhttp.lib;onecoreuap.lib;msi.lib;gdi32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">/debug:full /debugtype:cv,fixup /incremental:no %(AdditionalOptions)</AdditionalOptions>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">/debug:full /debugtype:cv,fixup /incremental:no %(AdditionalOptions)</AdditionalOptions>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">/debug:full /debugtype:cv,fixup /incremental:no %(AdditionalOptions)</AdditionalOptions>\r\n      <DelayLoadDLLs Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">gdi32.dll</DelayLoadDLLs>\r\n      <DelayLoadDLLs Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">gdi32.dll</DelayLoadDLLs>\r\n      <DelayLoadDLLs Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">gdi32.dll</DelayLoadDLLs>\r\n    </Link>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">$(ProjectDir)..\\manifest\\shared.manifest</AdditionalManifestFiles>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">$(ProjectDir)..\\manifest\\shared.manifest</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">$(ProjectDir)..\\manifest\\shared.manifest</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <PostBuildEvent>\r\n      <Command Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">copy \"$(ProjectDir)..\\AppInstallerCLIPackage\\bin\\$(PlatformTarget)\\$(configuration)\\resources.pri\" \"$(TargetDir)\\resources.pri\"</Command>\r\n    </PostBuildEvent>\r\n    <PostBuildEvent>\r\n      <Command Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">copy \"$(ProjectDir)..\\AppInstallerCLIPackage\\bin\\$(PlatformTarget)\\$(configuration)\\resources.pri\" \"$(TargetDir)\\resources.pri\"</Command>\r\n      <Command Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">copy \"$(ProjectDir)..\\AppInstallerCLIPackage\\bin\\$(PlatformTarget)\\$(configuration)\\resources.pri\" \"$(TargetDir)\\resources.pri\"</Command>\r\n    </PostBuildEvent>\r\n  </ItemDefinitionGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"DependenciesTestSource.h\" />\r\n    <ClInclude Include=\"pch.h\" />\r\n    <ClInclude Include=\"TestCommon.h\" />\r\n    <ClInclude Include=\"TestConfiguration.h\" />\r\n    <ClInclude Include=\"TestRestRequestHandler.h\" />\r\n    <ClInclude Include=\"TestHooks.h\" />\r\n    <ClInclude Include=\"TestSettings.h\" />\r\n    <ClInclude Include=\"TestSource.h\" />\r\n    <ClInclude Include=\"WorkflowCommon.h\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"AdminSettings.cpp\" />\r\n    <ClCompile Include=\"AppShutdown.cpp\" />\r\n    <ClCompile Include=\"Archive.cpp\" />\r\n    <ClCompile Include=\"Argument.cpp\" />\r\n    <ClCompile Include=\"ARPChanges.cpp\" />\r\n    <ClCompile Include=\"ArpHelper.cpp\" />\r\n    <ClCompile Include=\"Certificates.cpp\" />\r\n    <ClCompile Include=\"CheckpointDatabase.cpp\" />\r\n    <ClCompile Include=\"Command.cpp\" />\r\n    <ClCompile Include=\"Completion.cpp\" />\r\n    <ClCompile Include=\"CompositeSource.cpp\" />\r\n    <ClCompile Include=\"ContextOrchestrator.cpp\" />\r\n    <ClCompile Include=\"Correlation.cpp\" />\r\n    <ClCompile Include=\"CustomHeader.cpp\" />\r\n    <ClCompile Include=\"DateTime.cpp\" />\r\n    <ClCompile Include=\"Dependencies.cpp\" />\r\n    <ClCompile Include=\"Downloader.cpp\" />\r\n    <ClCompile Include=\"DownloadFlow.cpp\" />\r\n    <ClCompile Include=\"Errors.cpp\" />\r\n    <ClCompile Include=\"ExperimentalFeature.cpp\" />\r\n    <ClCompile Include=\"ExportFlow.cpp\" />\r\n    <ClCompile Include=\"FileCache.cpp\" />\r\n    <ClCompile Include=\"FileLogger.cpp\" />\r\n    <ClCompile Include=\"Filesystem.cpp\" />\r\n    <ClCompile Include=\"FolderFileWatcher.cpp\" />\r\n    <ClCompile Include=\"FontHelper.cpp\" />\r\n    <ClCompile Include=\"Fonts.cpp\" />\r\n    <ClCompile Include=\"GroupPolicy.cpp\" />\r\n    <ClCompile Include=\"HashCommand.cpp\" />\r\n    <ClCompile Include=\"HttpClientHelper.cpp\" />\r\n    <ClCompile Include=\"IconExtraction.cpp\" />\r\n    <ClCompile Include=\"ImportFlow.cpp\" />\r\n    <ClCompile Include=\"InstallDependenciesFlow.cpp\" />\r\n    <ClCompile Include=\"InstallerMetadataCollectionContext.cpp\" />\r\n    <ClCompile Include=\"InstallFlow.cpp\" />\r\n    <ClCompile Include=\"ManifestComparator.cpp\" />\r\n    <ClCompile Include=\"JsonHelper.cpp\" />\r\n    <ClCompile Include=\"MatchCriteriaResolver.cpp\" />\r\n    <ClCompile Include=\"MsiExecArguments.cpp\" />\r\n    <ClCompile Include=\"MsixInfo.cpp\" />\r\n    <ClCompile Include=\"MsixManifest.cpp\" />\r\n    <ClCompile Include=\"MSStoreDownloadFlow.cpp\" />\r\n    <ClCompile Include=\"NameNormalization.cpp\" />\r\n    <ClCompile Include=\"PackageCollection.cpp\" />\r\n    <ClCompile Include=\"PackageDependenciesValidationUtil.cpp\" />\r\n    <ClCompile Include=\"PackageTrackingCatalog.cpp\" />\r\n    <ClCompile Include=\"PackageVersionDataManifest.cpp\" />\r\n    <ClCompile Include=\"PathVariable.cpp\" />\r\n    <ClCompile Include=\"PinFlow.cpp\" />\r\n    <ClCompile Include=\"PinningIndex.cpp\" />\r\n    <ClCompile Include=\"PortableInstaller.cpp\" />\r\n    <ClCompile Include=\"PortableIndex.cpp\" />\r\n    <ClCompile Include=\"PredefinedInstalledSource.cpp\" />\r\n    <ClCompile Include=\"PreIndexedPackageSource.cpp\" />\r\n    <ClCompile Include=\"PromptFlow.cpp\" />\r\n    <ClCompile Include=\"Regex.cpp\" />\r\n    <ClCompile Include=\"Registry.cpp\" />\r\n    <ClCompile Include=\"Resources.cpp\" />\r\n    <ClCompile Include=\"Rest.cpp\" />\r\n    <ClCompile Include=\"RestClient.cpp\" />\r\n    <ClCompile Include=\"RestInterface_1_0.cpp\" />\r\n    <ClCompile Include=\"RestInterface_1_1.cpp\" />\r\n    <ClCompile Include=\"RestInterface_1_10.cpp\" />\r\n    <ClCompile Include=\"RestInterface_1_12.cpp\" />\r\n    <ClCompile Include=\"RestInterface_1_4.cpp\" />\r\n    <ClCompile Include=\"RestInterface_1_5.cpp\" />\r\n    <ClCompile Include=\"RestInterface_1_6.cpp\" />\r\n    <ClCompile Include=\"RestInterface_1_7.cpp\" />\r\n    <ClCompile Include=\"RestInterface_1_9.cpp\" />\r\n    <ClCompile Include=\"ResumeFlow.cpp\" />\r\n    <ClCompile Include=\"Runtime.cpp\" />\r\n    <ClCompile Include=\"SearchRequestSerializer.cpp\" />\r\n    <ClCompile Include=\"ShowFlow.cpp\" />\r\n    <ClCompile Include=\"Sixel.cpp\" />\r\n    <ClCompile Include=\"SourceFlow.cpp\" />\r\n    <ClCompile Include=\"SQLiteDynamicStorage.cpp\" />\r\n    <ClCompile Include=\"SQLiteIndexSource.cpp\" />\r\n    <ClCompile Include=\"Strings.cpp\" />\r\n    <ClCompile Include=\"TestConfiguration.cpp\" />\r\n    <ClCompile Include=\"TestRestRequestHandler.cpp\" />\r\n    <ClCompile Include=\"TestSettings.cpp\" />\r\n    <ClCompile Include=\"TestSource.cpp\" />\r\n    <ClCompile Include=\"UninstallFlow.cpp\" />\r\n    <ClCompile Include=\"UpdateFlow.cpp\" />\r\n    <ClCompile Include=\"UserSettings.cpp\" />\r\n    <ClCompile Include=\"Versions.cpp\" />\r\n    <ClCompile Include=\"WindowsFeature.cpp\" />\r\n    <ClCompile Include=\"WorkFlow.cpp\" />\r\n    <ClCompile Include=\"LanguageUtilities.cpp\" />\r\n    <ClCompile Include=\"main.cpp\">\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">NotUsing</PrecompiledHeader>\r\n    </ClCompile>\r\n    <ClCompile Include=\"pch.cpp\">\r\n      <PrecompiledHeader>Create</PrecompiledHeader>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Settings.cpp\" />\r\n    <ClCompile Include=\"Sources.cpp\" />\r\n    <ClCompile Include=\"SQLiteIndex.cpp\" />\r\n    <ClCompile Include=\"SQLiteWrapper.cpp\" />\r\n    <ClCompile Include=\"Synchronization.cpp\" />\r\n    <ClCompile Include=\"TestCommon.cpp\" />\r\n    <ClCompile Include=\"WorkflowCommon.cpp\" />\r\n    <ClCompile Include=\"WorkflowGroupPolicy.cpp\" />\r\n    <ClCompile Include=\"Yaml.cpp\" />\r\n    <ClCompile Include=\"YamlManifest.cpp\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\DownloadFlowTest_DownloadCommandProhibited.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\DownloadFlowTest_MSStore.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_EncodedUrl.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_Exe.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_InvalidFileCharacterUrl.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_Msix_DownloadFlow.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_Msix_StreamingFlow.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_MSStore.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_MultipleDependencies.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_AbortsTerminal.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_InstallLocationRequired.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_NoApplicableArchitecture.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_NonZeroExitCode.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_LicenseAgreement.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_ExpectedReturnCodes.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_InstallationNotes.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_Portable.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_Portable_WithCommand.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_UnknownVersion.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_UnsupportedArguments.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_WindowsFeatures.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_Zip_Exe.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_Zip_MissingNestedInstaller.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_Zip_MultipleNonPortableNestedInstallers.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_Zip_UnsupportedNestedInstaller.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ImportFile-Bad-Invalid.json\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ImportFile-Bad-Malformed.json\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ImportFile-Bad-UnknownPackage.json\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ImportFile-Bad-UnknownPackageVersion.json\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ImportFile-Bad-UnknownSource.json\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ImportFile-Good.json\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ImportFile-Good-AlreadyInstalled.json\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ImportFile-Good-MachineScope.json\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ImportFile-Good-Dependencies.json\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ImportFile-Good-WithLicenseAgreement.json\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <None Include=\"packages.config\" />\r\n    <None Include=\"PropertySheet.props\" />\r\n    <CopyFileToFolders Include=\"TestData\\InstallerArgTest_Inno_NoSwitches.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallerArgTest_Inno_WithSwitches.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallerArgTest_Msi_NoSwitches.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallerArgTest_Msi_WithSwitches.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\index.1.0.0.0.msix\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\index.1.0.0.0.signed.msix\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\index.2.0.0.0.msix\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\index.2.0.0.0.signed.msix\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\TestSignedApp.msix\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\TestZip.zip\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <None Include=\"Run-TestsInPackage.ps1\" />\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-ArchInvalid.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-ArchMissing.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-DifferentCase-camelCase.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-DifferentCase-lower.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-DifferentCase-UPPER.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-DuplicateKey-DifferentCase-lower.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-DuplicateKey-DifferentCase.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-DuplicateKey.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-DuplicateReturnCode-ExpectedCodes.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-DuplicateReturnCode-SuccessCodes.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-DuplicateSha256.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-IdInvalid.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-IdMissing.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InconsistentSha256.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallersMissing.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeExe-NoSilent.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeExe-NoSilentRoot.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeExeRoot-NoSilent.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeExeRoot-NoSilentRoot.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeInvalid.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeMissing.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypePortable-InvalidScope.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypePortable-InvalidAppsAndFeatures.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypePortable-InvalidCommands.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeZip-DuplicateCommandAlias.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeZip-DuplicateRelativeFilePath.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeZip-InvalidRelativeFilePath.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeZip-MissingRelativeFilePath.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeZip-MultipleNestedInstallers.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeZip-NoNestedInstallerFile.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeZip-NoNestedInstallerType.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerUniqueness-DefaultScope.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerUniqueness-DefaultValues.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerUniqueness-SameLang.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerUniqueness.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InvalidLocale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InvalidManifestVersionValue.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-LicenseMissing.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-NameMissing.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-PublisherMissing.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-Sha256Invalid.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-Sha256Missing.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-SwitchInvalid.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-UnknownProperty.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-UnsupportedVersion.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-UrlInvalid.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-UrlMissing.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-VersionInvalid.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-VersionMissing.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-ApproximateVersionInArpVersion.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-ApproximateVersionInPackageVersion.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-InstallerTypeExe-Silent.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-InstallerTypeExe-SilentRoot.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-InstallerTypeExeRoot-Silent.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-InstallerTypeExeRoot-SilentRoot.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-InstallerUniqueness-DefaultLang.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-InstallerUniqueness-DiffLangs.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-InstallerUniqueness-DiffScope.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-Minimum-InstallerType.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-Minimum.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-MultiLocale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-Switches.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-Spaces.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-AllDependencyTypes.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-DefaultExpectedReturnCodeInInstallerSuccessCodes.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-MultipleArpVersionDeclared.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-NoArpVersionDeclared.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-SingleArpVersionDeclared.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Encoding-ANSI.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Encoding-UTF16BE-BOM.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Encoding-UTF16BE.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Encoding-UTF16LE-BOM.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Encoding-UTF16LE.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Encoding-UTF8-BOM.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Encoding-UTF8.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-PackageFamilyNameOnMSI.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-ProductCodeOnMSIX.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-AppsAndFeaturesEntriesOnMSIX.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-SystemReferenceComplex.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InvalidUpdateBehavior.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-Channel-NotSupported.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\UpdateFlowTest_Exe.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\UpdateFlowTest_Exe_ARPInstallerType.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\UpdateFlowTest_Exe_2.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\UpdateFlowTest_Exe_2_LicenseAgreement.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\UpdateFlowTest_Exe_UnsupportedArgs.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\UpdateFlowTest_ExeDependencies.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\UpdateFlowTest_ExpectedReturnCodes.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\UpdateFlowTest_Msix.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\UpdateFlowTest_Msix_LicenseAgreement.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\UpdateFlowTest_Portable.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\UpdateFlowTest_Zip_Exe.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InputNames.txt\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InputPublishers.txt\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InputARPData.txt\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\NormalizationInitialIds.txt\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1-Singleton.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_1-Singleton.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_2-Singleton.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_4-Singleton.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_5-Singleton.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_6-Singleton.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_7-Singleton.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_9-Singleton.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_10-Singleton.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_12-Singleton.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_10-InstallerAuthentication.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1\\ManifestV1-MultiFile-DefaultLocale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1\\ManifestV1-MultiFile-Installer.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1\\ManifestV1-MultiFile-Locale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1\\ManifestV1-MultiFile-Version.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_1\\ManifestV1_1-MultiFile-DefaultLocale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_1\\ManifestV1_1-MultiFile-Installer.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_1\\ManifestV1_1-MultiFile-Locale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_1\\ManifestV1_1-MultiFile-Version.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_2\\ManifestV1_2-MultiFile-DefaultLocale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_2\\ManifestV1_2-MultiFile-Installer.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_2\\ManifestV1_2-MultiFile-Locale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_2\\ManifestV1_2-MultiFile-Version.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_4\\ManifestV1_4-MultiFile-DefaultLocale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_4\\ManifestV1_4-MultiFile-Installer.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_4\\ManifestV1_4-MultiFile-Locale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_4\\ManifestV1_4-MultiFile-Version.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_5\\ManifestV1_5-MultiFile-DefaultLocale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_5\\ManifestV1_5-MultiFile-Installer.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_5\\ManifestV1_5-MultiFile-Locale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_5\\ManifestV1_5-MultiFile-Version.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_6\\ManifestV1_6-MultiFile-DefaultLocale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_6\\ManifestV1_6-MultiFile-Installer.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_6\\ManifestV1_6-MultiFile-Locale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_6\\ManifestV1_6-MultiFile-Version.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_7\\ManifestV1_7-MultiFile-DefaultLocale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_7\\ManifestV1_7-MultiFile-Installer.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_7\\ManifestV1_7-MultiFile-Locale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_7\\ManifestV1_7-MultiFile-Version.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_9\\ManifestV1_9-MultiFile-DefaultLocale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_9\\ManifestV1_9-MultiFile-Installer.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_9\\ManifestV1_9-MultiFile-Locale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_9\\ManifestV1_9-MultiFile-Version.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_10\\ManifestV1_10-MultiFile-DefaultLocale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_10\\ManifestV1_10-MultiFile-Installer.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_10\\ManifestV1_10-MultiFile-Locale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_10\\ManifestV1_10-MultiFile-Version.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_12\\ManifestV1_12-MultiFile-DefaultLocale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_12\\ManifestV1_12-MultiFile-Installer.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_12\\ManifestV1_12-MultiFile-Locale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_12\\ManifestV1_12-MultiFile-Version.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Installer_Exe_Dependencies.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Installer_Msix_WFDependency.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Installer_Exe_DependenciesOnRoot.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Installer_Exe_DependenciesMultideclaration.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-MsixInstaller.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InconsistentMsixInstallerFields.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-MissingMsixInstallerFields.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-NoSupportedPlatforms.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Installer-Bad-NoSupportedPlatforms.msix\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Installer-Good.msix\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Installer-Good.msixbundle\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Installer-Good-WithStub.msixbundle\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Installer-Signed-Good.msix\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Installer-Signed-Good.msixbundle\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InconsistentSignedMsixInstallerFields.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-SignedMsixInstaller.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-MsixBundleInstaller.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-MsixBundleInstaller-WithStub.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InconsistentMsixBundleInstallerFields.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-SignedMsixBundleInstaller.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InconsistentSignedMsixBundleInstallerFields.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-MsixInstaller-PackageVersion.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Node-Types.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\notepad.exe\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\notepad.ico\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Shadow\\V1_5\\ManifestV1_5-Shadow-DefaultLocale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Shadow\\V1_5\\ManifestV1_5-Shadow-Locale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Shadow\\V1_5\\ManifestV1_5-Shadow-Locale2.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Shadow\\V1_5\\ManifestV1_5-Shadow-Shadow.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Shadow\\V1_5\\ManifestV1_5-Shadow-Shadow2.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Shadow\\V1_5\\ManifestV1_5-Shadow-Installer.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Node-Merge.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Node-Merge2.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Node-Mapping.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ContainsEscapeControlCode.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ContainsTooManyNestedLayers.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_10-Bad-SchemaHeaderInvalid.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_10-Bad-SchemaHeaderManifestTypeMismatch.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_10-Bad-SchemaHeaderManifestVersionMismatch.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_10-Bad-SchemaHeaderNotFound.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_10-Bad-SchemaHeaderURLPatternMismatch.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-InstallerTypeZip-PortableExe.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeZip-PortableNotExe.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeZip-PortableNotExe_Root.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\TestFont.ttf\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-MSIX-in-AppsAndFeatures.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-MSIX-in-Archive.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_28-Singleton.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_28\\ManifestV1_28-MultiFile-DefaultLocale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_28\\ManifestV1_28-MultiFile-Installer.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_28\\ManifestV1_28-MultiFile-Locale.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_28\\ManifestV1_28-MultiFile-Version.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_28-PowerShellDSC.yaml\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\AppInstallerCLICore\\AppInstallerCLICore.vcxproj\">\r\n      <Project>{1c6e0108-2860-4b17-9f7e-fa5c6c1f3d3d}</Project>\r\n    </ProjectReference>\r\n    <ProjectReference Include=\"..\\AppInstallerCommonCore\\AppInstallerCommonCore.vcxproj\">\r\n      <Project>{5890d6ed-7c3b-40f3-b436-b54f640d9e65}</Project>\r\n    </ProjectReference>\r\n    <ProjectReference Include=\"..\\AppInstallerRepositoryCore\\AppInstallerRepositoryCore.vcxproj\">\r\n      <Project>{5eb88068-5fb9-4e69-89b2-72dbc5e068f9}</Project>\r\n    </ProjectReference>\r\n    <ProjectReference Include=\"..\\Microsoft.Management.Configuration\\Microsoft.Management.Configuration.vcxproj\">\r\n      <Project>{ca460806-5e41-4e97-9a3d-1d74b433b663}</Project>\r\n    </ProjectReference>\r\n    <ProjectReference Include=\"..\\SfsClient\\SfsClient.vcxproj\">\r\n      <Project>{1b9077b3-8923-4ecd-8fc9-b3190fcbe4d4}</Project>\r\n    </ProjectReference>\r\n  </ItemGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\r\n  <ImportGroup Label=\"ExtensionTargets\">\r\n    <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets')\" />\r\n    <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" />\r\n  </ImportGroup>\r\n  <Target Name=\"EnsureNuGetPackageBuildImports\" BeforeTargets=\"PrepareForBuild\">\r\n    <PropertyGroup>\r\n      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>\r\n    </PropertyGroup>\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets'))\" />\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props'))\" />\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets'))\" />\r\n  </Target>\r\n</Project>"
  },
  {
    "path": "src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup>\r\n    <Filter Include=\"Source Files\">\r\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Header Files\">\r\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r\n      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Resource Files\">\r\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"TestData\">\r\n      <UniqueIdentifier>{d5cac203-3846-4b39-a1cd-8de9303757b4}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"TestData\\MultiFileManifestV1\">\r\n      <UniqueIdentifier>{69fcd25c-e737-4d28-a6d1-39ce491bf293}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"TestData\\MultiFileManifestV1_1\">\r\n      <UniqueIdentifier>{81fadc81-4327-4b9e-b588-97155b770aa3}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"TestData\\MultiFileManifestV1_2\">\r\n      <UniqueIdentifier>{0215df7f-7a73-4cc0-9589-adf401329e59}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"TestData\\MultiFileManifestV1_4\">\r\n      <UniqueIdentifier>{52b26063-ccff-40ae-a420-243327dcca25}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"TestData\\MultiFileManifestV1_5\">\r\n      <UniqueIdentifier>{488e9b7a-d72e-470c-b73a-5abcb83ca2c6}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"TestData\\MultiFileManifestV1_6\">\r\n      <UniqueIdentifier>{82dd5390-16ce-4a4c-a61a-148013890cc4}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"TestData\\MultiFileManifestV1_7\">\r\n      <UniqueIdentifier>{3e7d4dff-5513-46dd-95d2-f616c867ebe4}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"TestData\\MultiFileManifestV1_9\">\r\n      <UniqueIdentifier>{3499d391-99c1-4fa3-ba8d-0ce846c2497b}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"TestData\\MultiFileManifestV1_10\">\r\n      <UniqueIdentifier>{69069174-d4b1-4070-80c0-37d416b07128}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"TestData\\MultiFileManifestV1_12\">\r\n      <UniqueIdentifier>{d6d7e50d-394d-4486-8f93-4a5312ca4bf6}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Source Files\\CLI\">\r\n      <UniqueIdentifier>{b35e1a8b-1961-46d5-98e5-adc8e52c54a9}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Source Files\\Common\">\r\n      <UniqueIdentifier>{d055e02a-59c9-4ae4-9405-579dac6ff59b}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Source Files\\Repository\">\r\n      <UniqueIdentifier>{13d4d227-0f04-4e57-a663-c3c535438ab3}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"TestData\\Shadow\">\r\n      <UniqueIdentifier>{6f8102b7-ea5f-4379-bb59-067ced63d970}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"TestData\\Shadow\\V1_5\">\r\n      <UniqueIdentifier>{6bd68492-3f96-4023-af35-63249cd18158}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"TestData\\MultiFileManifestV1_28\">\r\n      <UniqueIdentifier>{0e5f9ff4-6f22-46eb-8538-1c560a008f06}</UniqueIdentifier>\r\n    </Filter>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"pch.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"TestCommon.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"TestHooks.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"TestSource.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"TestSettings.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"TestRestRequestHandler.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"DependenciesTestSource.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"WorkflowCommon.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"TestConfiguration.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"pch.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"main.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"TestCommon.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"TestSource.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"TestSettings.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ARPChanges.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Command.cpp\">\r\n      <Filter>Source Files\\CLI</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Completion.cpp\">\r\n      <Filter>Source Files\\CLI</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"CompositeSource.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Correlation.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"CustomHeader.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Dependencies.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Downloader.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ExperimentalFeature.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"GroupPolicy.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"HashCommand.cpp\">\r\n      <Filter>Source Files\\CLI</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"HttpClientHelper.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"InstallerMetadataCollectionContext.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"JsonHelper.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"LanguageUtilities.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"MSStoreDownloadFlow.cpp\">\r\n      <Filter>Source Files\\CLI</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"MsiExecArguments.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"MsixInfo.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"MsixManifest.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"NameNormalization.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PackageCollection.cpp\">\r\n      <Filter>Source Files\\CLI</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PackageTrackingCatalog.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PortableIndex.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PredefinedInstalledSource.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PreIndexedPackageSource.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Regex.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Registry.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"RestClient.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"RestInterface_1_0.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"RestInterface_1_1.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ResumeFlow.cpp\">\r\n      <Filter>Source Files\\CLI</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"SearchRequestSerializer.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Settings.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Sources.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"SQLiteIndex.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"SQLiteIndexSource.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"SQLiteWrapper.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Strings.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Synchronization.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"TestRestRequestHandler.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"UserSettings.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Versions.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"WorkFlow.cpp\">\r\n      <Filter>Source Files\\CLI</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"WorkflowGroupPolicy.cpp\">\r\n      <Filter>Source Files\\CLI</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"YamlManifest.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Certificates.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Runtime.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Archive.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"FolderFileWatcher.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Resources.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PortableInstaller.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PackageDependenciesValidationUtil.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"AdminSettings.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"InstallFlow.cpp\">\r\n      <Filter>Source Files\\CLI</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ShowFlow.cpp\">\r\n      <Filter>Source Files\\CLI</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"UpdateFlow.cpp\">\r\n      <Filter>Source Files\\CLI</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"UninstallFlow.cpp\">\r\n      <Filter>Source Files\\CLI</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ImportFlow.cpp\">\r\n      <Filter>Source Files\\CLI</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ExportFlow.cpp\">\r\n      <Filter>Source Files\\CLI</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"InstallDependenciesFlow.cpp\">\r\n      <Filter>Source Files\\CLI</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PromptFlow.cpp\">\r\n      <Filter>Source Files\\CLI</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"SourceFlow.cpp\">\r\n      <Filter>Source Files\\CLI</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"WorkflowCommon.cpp\">\r\n      <Filter>Source Files\\CLI</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PinningIndex.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PinFlow.cpp\">\r\n      <Filter>Source Files\\CLI</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Argument.cpp\">\r\n      <Filter>Source Files\\CLI</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"TestConfiguration.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"WindowsFeature.cpp\">\r\n      <Filter>Source Files\\CLI</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Filesystem.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"RestInterface_1_4.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"RestInterface_1_5.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"IconExtraction.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PathVariable.cpp\">\r\n      <Filter>Source Files\\CLI</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"RestInterface_1_6.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"DownloadFlow.cpp\">\r\n      <Filter>Source Files\\CLI</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Errors.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"CheckpointDatabase.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"DateTime.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ArpHelper.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"AppShutdown.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"RestInterface_1_7.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PackageVersionDataManifest.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Yaml.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"FileCache.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"SQLiteDynamicStorage.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Sixel.cpp\">\r\n      <Filter>Source Files\\CLI</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"RestInterface_1_9.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Fonts.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"RestInterface_1_10.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"RestInterface_1_12.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ManifestComparator.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ContextOrchestrator.cpp\">\r\n      <Filter>Source Files\\CLI</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"FontHelper.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"FileLogger.cpp\">\r\n      <Filter>Source Files\\Common</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"MatchCriteriaResolver.cpp\">\r\n      <Filter>Source Files\\Repository</Filter>\r\n    </ClCompile>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"PropertySheet.props\" />\r\n    <None Include=\"packages.config\" />\r\n    <None Include=\"Run-TestsInPackage.ps1\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-ApproximateVersionInArpVersion.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-ApproximateVersionInPackageVersion.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-AppsAndFeaturesEntriesOnMSIX.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-ArchInvalid.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-ArchMissing.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-Channel-NotSupported.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-DifferentCase-camelCase.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-DifferentCase-lower.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-DifferentCase-UPPER.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-DuplicateKey.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-DuplicateKey-DifferentCase.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-DuplicateKey-DifferentCase-lower.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-DuplicateReturnCode-ExpectedCodes.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-DuplicateReturnCode-SuccessCodes.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-DuplicateSha256.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-IdInvalid.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-IdMissing.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InconsistentSha256.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallersMissing.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeExe-NoSilent.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeExe-NoSilentRoot.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeExeRoot-NoSilent.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeExeRoot-NoSilentRoot.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeInvalid.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeMissing.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypePortable-InvalidScope.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypePortable-InvalidAppsAndFeatures.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypePortable-InvalidCommands.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeZip-DuplicateCommandAlias.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeZip-DuplicateRelativeFilePath.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeZip-InvalidRelativeFilePath.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeZip-MissingRelativeFilePath.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeZip-MultipleNestedInstallers.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeZip-NoNestedInstallerFile.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeZip-NoNestedInstallerType.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerUniqueness.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerUniqueness-DefaultScope.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerUniqueness-DefaultValues.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerUniqueness-SameLang.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InvalidLocale.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InvalidManifestVersionValue.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InvalidUpdateBehavior.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-LicenseMissing.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-NameMissing.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-PackageFamilyNameOnMSI.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-PublisherMissing.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-ProductCodeOnMSIX.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-Sha256Invalid.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-Sha256Missing.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-SwitchInvalid.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-UnknownProperty.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-UnsupportedVersion.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-UrlInvalid.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-UrlMissing.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-VersionInvalid.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-VersionMissing.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Encoding-ANSI.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Encoding-UTF8.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Encoding-UTF16LE-BOM.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Encoding-UTF8-BOM.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Encoding-UTF16BE.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Encoding-UTF16BE-BOM.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Encoding-UTF16LE.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-AllDependencyTypes.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-DefaultExpectedReturnCodeInInstallerSuccessCodes.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-InstallerTypeExeRoot-Silent.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-InstallerTypeExeRoot-SilentRoot.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-InstallerTypeExe-Silent.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-InstallerTypeExe-SilentRoot.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-InstallerUniqueness-DefaultLang.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-InstallerUniqueness-DiffLangs.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-InstallerUniqueness-DiffScope.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-Minimum.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-Minimum-InstallerType.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-MultiLocale.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-MultipleArpVersionDeclared.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-NoArpVersionDeclared.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-SingleArpVersionDeclared.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-Spaces.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-Switches.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-SystemReferenceComplex.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\index.1.0.0.0.msix\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\index.1.0.0.0.signed.msix\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\index.2.0.0.0.msix\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\index.2.0.0.0.signed.msix\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\TestSignedApp.msix\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\TestZip.zip\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\DownloadFlowTest_DownloadCommandProhibited.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\DownloadFlowTest_MSStore.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_NoApplicableArchitecture.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_NonZeroExitCode.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_Msix_StreamingFlow.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_Msix_DownloadFlow.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_EncodedUrl.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_Exe.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_InvalidFileCharacterUrl.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_LicenseAgreement.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_MSStore.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_MultipleDependencies.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_AbortsTerminal.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_ExpectedReturnCodes.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_InstallationNotes.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_InstallLocationRequired.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_Portable.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_Portable_WithCommand.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_UnknownVersion.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_UnsupportedArguments.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_WindowsFeatures.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_Zip_Exe.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_Zip_MissingNestedInstaller.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_Zip_MultipleNonPortableNestedInstallers.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallFlowTest_Zip_UnsupportedNestedInstaller.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallerArgTest_Msi_WithSwitches.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallerArgTest_Msi_NoSwitches.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallerArgTest_Inno_WithSwitches.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InstallerArgTest_Inno_NoSwitches.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\UpdateFlowTest_Exe.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\UpdateFlowTest_Exe_ARPInstallerType.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\UpdateFlowTest_Exe_2.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\UpdateFlowTest_Exe_2_LicenseAgreement.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\UpdateFlowTest_Exe_UnsupportedArgs.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\UpdateFlowTest_ExeDependencies.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\UpdateFlowTest_ExpectedReturnCodes.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\UpdateFlowTest_Msix.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\UpdateFlowTest_Msix_LicenseAgreement.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\UpdateFlowTest_Portable.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\UpdateFlowTest_Zip_Exe.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ImportFile-Good.json\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ImportFile-Good-AlreadyInstalled.json\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ImportFile-Good-WithLicenseAgreement.json\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ImportFile-Good-Dependencies.json\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ImportFile-Good-MachineScope.json\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ImportFile-Bad-Invalid.json\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ImportFile-Bad-Malformed.json\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ImportFile-Bad-UnknownPackage.json\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ImportFile-Bad-UnknownPackageVersion.json\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ImportFile-Bad-UnknownSource.json\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InputNames.txt\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InputPublishers.txt\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\NormalizationInitialIds.txt\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1-Singleton.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_1-Singleton.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_2-Singleton.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_4-Singleton.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_5-Singleton.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_6-Singleton.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_7-Singleton.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_9-Singleton.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_10-Singleton.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_12-Singleton.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_10-InstallerAuthentication.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1\\ManifestV1-MultiFile-DefaultLocale.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1\\ManifestV1-MultiFile-Installer.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1\\ManifestV1-MultiFile-Locale.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1\\ManifestV1-MultiFile-Version.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_1\\ManifestV1_1-MultiFile-DefaultLocale.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_1</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_1\\ManifestV1_1-MultiFile-Installer.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_1</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_1\\ManifestV1_1-MultiFile-Locale.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_1</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_1\\ManifestV1_1-MultiFile-Version.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_1</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_2\\ManifestV1_2-MultiFile-DefaultLocale.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_2</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_2\\ManifestV1_2-MultiFile-Installer.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_2</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_2\\ManifestV1_2-MultiFile-Locale.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_2</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_2\\ManifestV1_2-MultiFile-Version.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_2</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_4\\ManifestV1_4-MultiFile-DefaultLocale.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_4</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_4\\ManifestV1_4-MultiFile-Installer.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_4</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_4\\ManifestV1_4-MultiFile-Locale.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_4</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_4\\ManifestV1_4-MultiFile-Version.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_4</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_5\\ManifestV1_5-MultiFile-DefaultLocale.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_5</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_5\\ManifestV1_5-MultiFile-Installer.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_5</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_5\\ManifestV1_5-MultiFile-Locale.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_5</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_5\\ManifestV1_5-MultiFile-Version.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_5</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_6\\ManifestV1_6-MultiFile-DefaultLocale.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_6</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_6\\ManifestV1_6-MultiFile-Installer.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_6</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_6\\ManifestV1_6-MultiFile-Locale.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_6</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_6\\ManifestV1_6-MultiFile-Version.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_6</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_7\\ManifestV1_7-MultiFile-DefaultLocale.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_7</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_7\\ManifestV1_7-MultiFile-Installer.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_7</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_7\\ManifestV1_7-MultiFile-Locale.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_7</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_7\\ManifestV1_7-MultiFile-Version.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_7</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_9\\ManifestV1_9-MultiFile-DefaultLocale.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_9</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_9\\ManifestV1_9-MultiFile-Installer.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_9</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_9\\ManifestV1_9-MultiFile-Locale.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_9</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_9\\ManifestV1_9-MultiFile-Version.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_9</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_10\\ManifestV1_10-MultiFile-DefaultLocale.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_10</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_10\\ManifestV1_10-MultiFile-Installer.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_10</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_10\\ManifestV1_10-MultiFile-Locale.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_10</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_10\\ManifestV1_10-MultiFile-Version.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_10</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_12\\ManifestV1_12-MultiFile-DefaultLocale.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_12</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_12\\ManifestV1_12-MultiFile-Installer.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_12</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_12\\ManifestV1_12-MultiFile-Locale.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_12</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_12\\ManifestV1_12-MultiFile-Version.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_12</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Installer_Exe_Dependencies.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Installer_Msix_WFDependency.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Installer_Exe_DependenciesOnRoot.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Installer_Exe_DependenciesMultideclaration.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\InputARPData.txt\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-MsixInstaller.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InconsistentMsixInstallerFields.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-MissingMsixInstallerFields.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-MsixInstaller-PackageVersion.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-NoSupportedPlatforms.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Installer-Bad-NoSupportedPlatforms.msix\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Installer-Good.msix\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Installer-Good.msixbundle\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Installer-Good-WithStub.msixbundle\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Installer-Signed-Good.msix\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Installer-Signed-Good.msixbundle\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InconsistentSignedMsixInstallerFields.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-SignedMsixInstaller.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-MsixBundleInstaller.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-MsixBundleInstaller-WithStub.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InconsistentMsixBundleInstallerFields.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-SignedMsixBundleInstaller.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InconsistentSignedMsixBundleInstallerFields.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Node-Types.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\notepad.exe\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\notepad.ico\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Shadow\\V1_5\\ManifestV1_5-Shadow-DefaultLocale.yaml\">\r\n      <Filter>TestData\\Shadow\\V1_5</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Shadow\\V1_5\\ManifestV1_5-Shadow-Locale.yaml\">\r\n      <Filter>TestData\\Shadow\\V1_5</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Shadow\\V1_5\\ManifestV1_5-Shadow-Locale2.yaml\">\r\n      <Filter>TestData\\Shadow\\V1_5</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Shadow\\V1_5\\ManifestV1_5-Shadow-Shadow.yaml\">\r\n      <Filter>TestData\\Shadow\\V1_5</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Shadow\\V1_5\\ManifestV1_5-Shadow-Shadow2.yaml\">\r\n      <Filter>TestData\\Shadow\\V1_5</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Shadow\\V1_5\\ManifestV1_5-Shadow-Installer.yaml\">\r\n      <Filter>TestData\\Shadow\\V1_5</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Node-Merge.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Node-Merge2.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Node-Mapping.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ContainsEscapeControlCode.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ContainsTooManyNestedLayers.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_10-Bad-SchemaHeaderInvalid.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_10-Bad-SchemaHeaderManifestTypeMismatch.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_10-Bad-SchemaHeaderManifestVersionMismatch.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_10-Bad-SchemaHeaderNotFound.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_10-Bad-SchemaHeaderURLPatternMismatch.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Good-InstallerTypeZip-PortableExe.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeZip-PortableNotExe.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-Bad-InstallerTypeZip-PortableNotExe_Root.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\TestFont.ttf\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_28\\ManifestV1_28-MultiFile-DefaultLocale.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_28</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_28\\ManifestV1_28-MultiFile-Installer.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_28</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_28\\ManifestV1_28-MultiFile-Locale.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_28</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\MultiFileManifestV1_28\\ManifestV1_28-MultiFile-Version.yaml\">\r\n      <Filter>TestData\\MultiFileManifestV1_28</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-MSIX-in-AppsAndFeatures.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\Manifest-MSIX-in-Archive.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_28-PowerShellDSC.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n    <CopyFileToFolders Include=\"TestData\\ManifestV1_28-Singleton.yaml\">\r\n      <Filter>TestData</Filter>\r\n    </CopyFileToFolders>\r\n  </ItemGroup>\r\n</Project>"
  },
  {
    "path": "src/AppInstallerCLITests/AppShutdown.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include <winget/Runtime.h>\n#include \"Commands/TestCommand.h\"\n\nusing namespace AppInstaller::CLI;\n\nTEST_CASE(\"AppShutdown_WindowMessage\", \"[appShutdown]\")\n{\n    if (AppInstaller::Runtime::IsRunningAsAdmin() && AppInstaller::Runtime::IsRunningInPackagedContext())\n    {\n        WARN(\"Test can't run as admin in package context\");\n        return;\n    }\n\n    std::ostringstream output;\n    Execution::Context context{ output, std::cin };\n    context.Args.AddArg(Execution::Args::Type::Force);\n\n    TestAppShutdownCommand appShutdownCmd({});\n    appShutdownCmd.Execute(context);\n\n    REQUIRE(context.IsTerminated());\n    REQUIRE(S_OK == context.GetTerminationHR());\n}\n"
  },
  {
    "path": "src/AppInstallerCLITests/Archive.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <winget/Archive.h>\r\n\r\nusing namespace AppInstaller::Archive;\r\nusing namespace TestCommon;\r\n\r\nconstexpr std::string_view s_ZipFile = \"TestZip.zip\";\r\n\r\nTEST_CASE(\"Extract_ZipArchive\", \"[archive]\")\r\n{\r\n    TestCommon::TempDirectory tempDirectory(\"TempDirectory\");\r\n    TestDataFile testZip(s_ZipFile);\r\n\r\n    const auto& testZipPath = testZip.GetPath();\r\n    const auto& tempDirectoryPath = tempDirectory.GetPath();\r\n\r\n    HRESULT hr = TryExtractArchive(testZipPath, tempDirectoryPath);\r\n\r\n    std::filesystem::path expectedPath = tempDirectoryPath / \"test.txt\";\r\n    REQUIRE(SUCCEEDED(hr));\r\n    REQUIRE(std::filesystem::exists(expectedPath));\r\n}\r\n\r\nTEST_CASE(\"Scan_ZipArchive\", \"[archive]\")\r\n{\r\n    TestDataFile testZip(s_ZipFile);\r\n\r\n    const auto& testZipPath = testZip.GetPath();\r\n    bool result = ScanZipFile(testZipPath);\r\n    REQUIRE(result);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/Argument.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <Argument.h>\r\n\r\nusing namespace AppInstaller::CLI;\r\n\r\nTEST_CASE(\"EnsureAllArgumentsDefined\", \"[argument]\")\r\n{\r\n    using Arg_t = std::underlying_type_t<Execution::Args::Type>;\r\n    for (Arg_t i = static_cast<Arg_t>(0); i < static_cast<Arg_t>(Execution::Args::Type::Max); ++i)\r\n    {\r\n        REQUIRE_NOTHROW(ArgumentCommon::ForType(static_cast<Execution::Args::Type>(i)));\r\n    }\r\n}"
  },
  {
    "path": "src/AppInstallerCLITests/ArpHelper.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestHooks.h\"\r\n#include \"Microsoft/ARPHelper.h\"\r\n#include \"AppInstallerStrings.h\"\r\n\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Repository::Microsoft;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::Registry;\r\n\r\n\r\nTEST_CASE(\"ARPHelper_Watcher\", \"[ARPHelper]\")\r\n{\r\n    ARPHelper helper;\r\n\r\n    wil::unique_event callbackEvent;\r\n    callbackEvent.create();\r\n\r\n    ScopeEnum scopeCallback = ScopeEnum::Unknown;\r\n    Architecture architectureCallback = Architecture::Unknown;\r\n\r\n    ScopeEnum scopeTarget = ScopeEnum::Machine;\r\n    Architecture architectureTarget = Architecture::X86;\r\n\r\n    auto fakeRoot = TestCommon::RegCreateVolatileTestRoot();\r\n    TestHook::SetGetARPKey_Override arpOverride([&](ScopeEnum scope, Architecture arch)\r\n        {\r\n            if (scope == scopeTarget && arch == architectureTarget)\r\n            {\r\n                return Key(fakeRoot.get(), L\"\");\r\n            }\r\n            else\r\n            {\r\n                return Key{};\r\n            }\r\n        });\r\n\r\n    auto watchers = helper.CreateRegistryWatchers(scopeTarget, [&](ScopeEnum scope, Architecture arch, wil::RegistryChangeKind)\r\n        {\r\n            scopeCallback = scope;\r\n            architectureCallback = arch;\r\n            callbackEvent.SetEvent();\r\n        });\r\n\r\n    auto arpKey = helper.GetARPKey(scopeTarget, architectureTarget);\r\n    REQUIRE(!!arpKey);\r\n\r\n    GUID guid;\r\n    std::ignore = CoCreateGuid(&guid);\r\n    std::ostringstream stream;\r\n    stream << guid;\r\n\r\n    auto testKey = TestCommon::RegCreateVolatileSubKey(arpKey, ConvertToUTF16(stream.str()));\r\n\r\n    REQUIRE(callbackEvent.wait(1000));\r\n    REQUIRE(scopeTarget == scopeCallback);\r\n    REQUIRE(architectureTarget == architectureCallback);\r\n\r\n    // Reset for changing a value\r\n    scopeCallback = ScopeEnum::Unknown;\r\n    architectureCallback = Architecture::Unknown;\r\n\r\n    TestCommon::SetRegistryValue(testKey.get(), L\"testValue\", L\"valueValue\");\r\n\r\n    REQUIRE(callbackEvent.wait(1000));\r\n    REQUIRE(scopeTarget == scopeCallback);\r\n    REQUIRE(architectureTarget == architectureCallback);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/Certificates.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <winget/Certificates.h>\r\n#include <CertificateResources.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller;\r\nusing namespace AppInstaller::Certificates;\r\n\r\n\r\nTEST_CASE(\"Certificates_NoPinningSucceeds\", \"[certificates]\")\r\n{\r\n    PinningDetails expected;\r\n    expected.LoadCertificate(IDX_CERTIFICATE_STORE_ROOT_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::None);\r\n\r\n    PinningDetails actual;\r\n    actual.LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE);\r\n\r\n    REQUIRE(CertificatePinningValidationResult::Accepted == expected.Validate(actual.GetCertificate(), CertificateChainPosition::Leaf));\r\n}\r\n\r\nTEST_CASE(\"Certificates_PublicKeyMismatch\", \"[certificates]\")\r\n{\r\n    PinningDetails expected;\r\n    expected.LoadCertificate(IDX_CERTIFICATE_STORE_ROOT_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::PublicKey);\r\n\r\n    PinningDetails actual;\r\n    actual.LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE);\r\n\r\n    REQUIRE(CertificatePinningValidationResult::Rejected == expected.Validate(actual.GetCertificate(), CertificateChainPosition::Leaf));\r\n}\r\n\r\nTEST_CASE(\"Certificates_PublicKeyMatch\", \"[certificates]\")\r\n{\r\n    PinningDetails expected;\r\n    expected.LoadCertificate(IDX_CERTIFICATE_STORE_ROOT_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::PublicKey);\r\n\r\n    PinningDetails actual;\r\n    actual.LoadCertificate(IDX_CERTIFICATE_STORE_ROOT_2, CERTIFICATE_RESOURCE_TYPE);\r\n\r\n    REQUIRE(CertificatePinningValidationResult::Accepted == expected.Validate(actual.GetCertificate(), CertificateChainPosition::Root));\r\n}\r\n\r\nTEST_CASE(\"Certificates_SubjectMismatch\", \"[certificates]\")\r\n{\r\n    PinningDetails expected;\r\n    expected.LoadCertificate(IDX_CERTIFICATE_STORE_ROOT_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::Subject);\r\n\r\n    PinningDetails actual;\r\n    actual.LoadCertificate(IDX_CERTIFICATE_STORE_INTERMEDIATE_2, CERTIFICATE_RESOURCE_TYPE);\r\n\r\n    REQUIRE(CertificatePinningValidationResult::Rejected == expected.Validate(actual.GetCertificate(), CertificateChainPosition::Intermediate));\r\n}\r\n\r\nTEST_CASE(\"Certificates_SubjectMatch\", \"[certificates]\")\r\n{\r\n    PinningDetails expected;\r\n    expected.LoadCertificate(IDX_CERTIFICATE_STORE_INTERMEDIATE_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::Subject);\r\n\r\n    PinningDetails actual;\r\n    actual.LoadCertificate(IDX_CERTIFICATE_STORE_INTERMEDIATE_2, CERTIFICATE_RESOURCE_TYPE);\r\n\r\n    REQUIRE(CertificatePinningValidationResult::Accepted == expected.Validate(actual.GetCertificate(), CertificateChainPosition::Intermediate));\r\n}\r\n\r\nTEST_CASE(\"Certificates_IssuerMismatch\", \"[certificates]\")\r\n{\r\n    PinningDetails expected;\r\n    expected.LoadCertificate(IDX_CERTIFICATE_STORE_INTERMEDIATE_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::Issuer);\r\n\r\n    PinningDetails actual;\r\n    actual.LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE);\r\n\r\n    REQUIRE(CertificatePinningValidationResult::Rejected == expected.Validate(actual.GetCertificate(), CertificateChainPosition::Leaf));\r\n}\r\n\r\nTEST_CASE(\"Certificates_IssuerMatch\", \"[certificates]\")\r\n{\r\n    PinningDetails expected;\r\n    expected.LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::Issuer);\r\n\r\n    PinningDetails actual;\r\n    actual.LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE);\r\n\r\n    REQUIRE(CertificatePinningValidationResult::Accepted == expected.Validate(actual.GetCertificate(), CertificateChainPosition::Leaf));\r\n}\r\n\r\nTEST_CASE(\"Certificates_ChainLengthDiffers\", \"[certificates]\")\r\n{\r\n    PinningChain chain;\r\n    auto chainElement = chain.Root();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_ROOT_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::PublicKey);\r\n    chainElement = chainElement.Next();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::Subject | PinningVerificationType::Issuer);\r\n\r\n    PinningConfiguration config;\r\n    config.AddChain(chain);\r\n\r\n    PinningDetails details;\r\n    details.LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE);\r\n\r\n    REQUIRE(!config.Validate(details.GetCertificate()));\r\n}\r\n\r\nTEST_CASE(\"Certificates_ChainLengthDiffers_Partial\", \"[certificates]\")\r\n{\r\n    PinningChain chain;\r\n    auto chainElement = chain.Root();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_ROOT_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::PublicKey);\r\n    chainElement = chainElement.Next();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_INTERMEDIATE_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::Subject | PinningVerificationType::Issuer);\r\n    chain.PartialChain();\r\n\r\n    PinningConfiguration config;\r\n    config.AddChain(chain);\r\n\r\n    PinningDetails details;\r\n    details.LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE);\r\n\r\n    REQUIRE(config.Validate(details.GetCertificate()));\r\n}\r\n\r\nTEST_CASE(\"CertificateChain_AnyIssuer_Intermediate\", \"[certificates]\")\r\n{\r\n    PinningChain chain;\r\n    auto chainElement = chain.Root();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_INTERMEDIATE_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::PublicKey | PinningVerificationType::AnyIssuer | PinningVerificationType::RequireNonLeaf);\r\n    chain.PartialChain();\r\n\r\n    PinningConfiguration config;\r\n    config.AddChain(chain);\r\n\r\n    PinningDetails details;\r\n    details.LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE);\r\n\r\n    REQUIRE(config.Validate(details.GetCertificate()));\r\n}\r\n\r\nTEST_CASE(\"CertificateChain_AnyIssuer_IntermediateDiffers\", \"[certificates]\")\r\n{\r\n    PinningChain chain;\r\n    auto chainElement = chain.Root();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_INTERMEDIATE_1, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::PublicKey | PinningVerificationType::AnyIssuer | PinningVerificationType::RequireNonLeaf);\r\n    chain.PartialChain();\r\n\r\n    PinningConfiguration config;\r\n    config.AddChain(chain);\r\n\r\n    PinningDetails details;\r\n    details.LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE);\r\n\r\n    REQUIRE(!config.Validate(details.GetCertificate()));\r\n}\r\n\r\nTEST_CASE(\"CertificateChain_AnyIssuer_IntermediateAndLeaf\", \"[certificates]\")\r\n{\r\n    PinningChain chain;\r\n    auto chainElement = chain.Root();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_INTERMEDIATE_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::PublicKey | PinningVerificationType::AnyIssuer | PinningVerificationType::RequireNonLeaf);\r\n    chainElement = chainElement.Next();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::Subject | PinningVerificationType::Issuer);\r\n    chain.PartialChain();\r\n\r\n    PinningConfiguration config;\r\n    config.AddChain(chain);\r\n\r\n    PinningDetails details;\r\n    details.LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE);\r\n\r\n    REQUIRE(config.Validate(details.GetCertificate()));\r\n}\r\n\r\nTEST_CASE(\"CertificateChain_AnyIssuer_Leaf\", \"[certificates]\")\r\n{\r\n    PinningChain chain;\r\n    auto chainElement = chain.Root();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::PublicKey | PinningVerificationType::AnyIssuer);\r\n    chain.PartialChain();\r\n\r\n    PinningConfiguration config;\r\n    config.AddChain(chain);\r\n\r\n    PinningDetails details;\r\n    details.LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE);\r\n\r\n    REQUIRE(config.Validate(details.GetCertificate()));\r\n}\r\n\r\nTEST_CASE(\"CertificateChain_AnyIssuer_LeafDiffers\", \"[certificates]\")\r\n{\r\n    PinningChain chain;\r\n    auto chainElement = chain.Root();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_1, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::PublicKey | PinningVerificationType::AnyIssuer);\r\n    chain.PartialChain();\r\n\r\n    PinningConfiguration config;\r\n    config.AddChain(chain);\r\n\r\n    PinningDetails details;\r\n    details.LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE);\r\n\r\n    REQUIRE(!config.Validate(details.GetCertificate()));\r\n}\r\n\r\nTEST_CASE(\"CertificateChain_AnyIssuer_SameLeaf_RequireNonLeaf\", \"[certificates]\")\r\n{\r\n    PinningChain chain;\r\n    auto chainElement = chain.Root();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::PublicKey | PinningVerificationType::AnyIssuer | PinningVerificationType::RequireNonLeaf);\r\n    chain.PartialChain();\r\n\r\n    PinningConfiguration config;\r\n    config.AddChain(chain);\r\n\r\n    PinningDetails details;\r\n    details.LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE);\r\n\r\n    REQUIRE(!config.Validate(details.GetCertificate()));\r\n}\r\n\r\nTEST_CASE(\"Certificates_EmptyChainRejects\", \"[certificates]\")\r\n{\r\n    PinningChain chain;\r\n\r\n    PinningConfiguration config;\r\n    config.AddChain(chain);\r\n\r\n    PinningDetails details;\r\n    details.LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE);\r\n\r\n    REQUIRE(!config.Validate(details.GetCertificate()));\r\n}\r\n\r\nTEST_CASE(\"Certificates_ChainOrderDiffers\", \"[certificates]\")\r\n{\r\n    PinningChain chain;\r\n    auto chainElement = chain.Root();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_ROOT_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::PublicKey);\r\n    chainElement = chainElement.Next();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::Subject | PinningVerificationType::Issuer);\r\n    chainElement = chainElement.Next();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_INTERMEDIATE_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::Subject | PinningVerificationType::Issuer);\r\n\r\n    PinningConfiguration config;\r\n    config.AddChain(chain);\r\n\r\n    PinningDetails details;\r\n    details.LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE);\r\n\r\n    REQUIRE(!config.Validate(details.GetCertificate()));\r\n}\r\n\r\nTEST_CASE(\"Certificates_StoreChain_BuiltInTest\", \"[certificates]\")\r\n{\r\n    PinningChain chain;\r\n    auto chainElement = chain.Root();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_ROOT_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::PublicKey);\r\n    chainElement = chainElement.Next();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_INTERMEDIATE_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::Subject | PinningVerificationType::Issuer);\r\n    chainElement = chainElement.Next();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::Subject | PinningVerificationType::Issuer);\r\n\r\n    PinningConfiguration config;\r\n    config.AddChain(chain);\r\n\r\n    PinningDetails details;\r\n    details.LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE);\r\n\r\n    REQUIRE(config.Validate(details.GetCertificate()));\r\n}\r\n\r\nTEST_CASE(\"Certificates_MultipleChains_Success\", \"[certificates]\")\r\n{\r\n    PinningChain chainOutOfOrder;\r\n    auto chainElement = chainOutOfOrder.Root();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_ROOT_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::PublicKey);\r\n    chainElement = chainElement.Next();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::Subject | PinningVerificationType::Issuer);\r\n    chainElement = chainElement.Next();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_INTERMEDIATE_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::Subject | PinningVerificationType::Issuer);\r\n\r\n    PinningConfiguration config;\r\n    config.AddChain(chainOutOfOrder);\r\n\r\n    PinningChain chain;\r\n    chainElement = chain.Root();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_ROOT_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::PublicKey);\r\n    chainElement = chainElement.Next();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_INTERMEDIATE_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::Subject | PinningVerificationType::Issuer);\r\n    chainElement = chainElement.Next();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::Subject | PinningVerificationType::Issuer);\r\n\r\n    config.AddChain(chain);\r\n\r\n    PinningDetails details;\r\n    details.LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE);\r\n\r\n    REQUIRE(config.Validate(details.GetCertificate()));\r\n}\r\n\r\nTEST_CASE(\"CertificateChain_Position\", \"[certificates]\")\r\n{\r\n    CertificateChainPosition positions[3]{ CertificateChainPosition::Unknown, CertificateChainPosition::Unknown, CertificateChainPosition::Unknown };\r\n\r\n    PinningChain chain;\r\n    auto chainElement = chain.Root();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_ROOT_2, CERTIFICATE_RESOURCE_TYPE).SetCustomValidationFunction([&](const PinningDetails&, PCCERT_CONTEXT, CertificateChainPosition position) { positions[0] = position; return true; });\r\n    chainElement = chainElement.Next();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_INTERMEDIATE_2, CERTIFICATE_RESOURCE_TYPE).SetCustomValidationFunction([&](const PinningDetails&, PCCERT_CONTEXT, CertificateChainPosition position) { positions[1] = position; return true; });\r\n    chainElement = chainElement.Next();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE).SetCustomValidationFunction([&](const PinningDetails&, PCCERT_CONTEXT, CertificateChainPosition position) { positions[2] = position; return true; });\r\n\r\n    PinningConfiguration config;\r\n    config.AddChain(chain);\r\n\r\n    PinningDetails details;\r\n    details.LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE);\r\n\r\n    REQUIRE(config.Validate(details.GetCertificate()));\r\n\r\n    REQUIRE(CertificateChainPosition::Root == positions[0]);\r\n    REQUIRE(CertificateChainPosition::Intermediate == positions[1]);\r\n    REQUIRE(CertificateChainPosition::Leaf == positions[2]);\r\n}\r\n\r\nTEST_CASE(\"CertificateChain_Position_SelfSigned\", \"[certificates]\")\r\n{\r\n    CertificateChainPosition positions[1]{ CertificateChainPosition::Unknown };\r\n\r\n    PinningChain chain;\r\n    auto chainElement = chain.Root();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_ROOT_2, CERTIFICATE_RESOURCE_TYPE).SetCustomValidationFunction([&](const PinningDetails&, PCCERT_CONTEXT, CertificateChainPosition position) { positions[0] = position; return true; });\r\n\r\n    PinningConfiguration config;\r\n    config.AddChain(chain);\r\n\r\n    PinningDetails details;\r\n    details.LoadCertificate(IDX_CERTIFICATE_STORE_ROOT_2, CERTIFICATE_RESOURCE_TYPE);\r\n\r\n    REQUIRE(config.Validate(details.GetCertificate()));\r\n\r\n    REQUIRE((CertificateChainPosition::Root | CertificateChainPosition::Leaf) == positions[0]);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/CheckpointDatabase.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"TestCommon.h\"\n#include <winget/CheckpointDatabase.h>\n#include <Public/winget/Checkpoint.h>\n\nusing namespace std::string_literals;\nusing namespace TestCommon;\nusing namespace AppInstaller::Repository::Microsoft;\nusing namespace AppInstaller::SQLite;\nusing namespace AppInstaller::Checkpoints;\n\nTEST_CASE(\"CheckpointDatabaseCreateLatestAndReopen\", \"[checkpointDatabase]\")\n{\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\n\n    Version versionCreated;\n\n    // Create the database\n    {\n        std::shared_ptr<CheckpointDatabase> database = CheckpointDatabase::CreateNew(tempFile, Version::Latest());\n        versionCreated = database->GetVersion();\n    }\n\n    // Reopen the database\n    {\n        INFO(\"Trying with ReadWrite\");\n        std::shared_ptr<CheckpointDatabase> database = CheckpointDatabase::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\n        Version versionRead = database->GetVersion();\n        REQUIRE(versionRead == versionCreated);\n    }\n}\n\nTEST_CASE(\"CheckpointDatabase_WriteAndRemoveMetadata\", \"[checkpointDatabase]\")\n{\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\n\n    std::string_view testCheckpointName = \"testCheckpoint\"sv;\n    std::string testCommand = \"install\";\n    std::string testClientVersion = \"1.20.1234\";\n\n    {\n        std::shared_ptr<CheckpointDatabase> database = CheckpointDatabase::CreateNew(tempFile, { 1, 0 });\n        CheckpointDatabase::IdType checkpointId = database->AddCheckpoint(testCheckpointName);\n        database->SetDataValue(checkpointId, AutomaticCheckpointData::Command, {}, { testCommand });\n        database->SetDataValue(checkpointId, AutomaticCheckpointData::ClientVersion, {}, { testClientVersion });\n    }\n\n    {\n        std::shared_ptr<CheckpointDatabase> database = CheckpointDatabase::Open(tempFile);\n        const auto& checkpointIds = database->GetCheckpointIds();\n        REQUIRE_FALSE(checkpointIds.empty());\n\n        auto checkpointId = checkpointIds[0];\n        REQUIRE(testCommand == database->GetDataFieldSingleValue(checkpointId, AutomaticCheckpointData::Command, {}));\n        REQUIRE(testClientVersion == database->GetDataFieldSingleValue(checkpointId, AutomaticCheckpointData::ClientVersion, {}));\n\n        database->RemoveDataType(checkpointId, AutomaticCheckpointData::Command);\n        database->RemoveDataType(checkpointId, AutomaticCheckpointData::ClientVersion);\n    }\n\n    {\n        std::shared_ptr<CheckpointDatabase> database = CheckpointDatabase::Open(tempFile);\n        const auto& checkpointIds = database->GetCheckpointIds();\n        REQUIRE_FALSE(checkpointIds.empty());\n\n        auto checkpointId = checkpointIds[0];\n        REQUIRE(database->GetDataTypes(checkpointId).empty());\n    }\n}\n\nTEST_CASE(\"CheckpointDatabase_WriteContextData\", \"[checkpointDatabase]\")\n{\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\n\n    std::string_view testCheckpoint = \"testCheckpoint\"sv;\n\n    std::string fieldName1 = \"field1\";\n    std::string fieldName2 = \"field2\";\n\n    std::string testValue1 = \"value1\";\n    std::string testValue2 = \"value2\";\n    std::string testValue3 = \"value3\";\n\n    {\n        std::shared_ptr<CheckpointDatabase> database = CheckpointDatabase::CreateNew(tempFile, { 1, 0 });\n        CheckpointDatabase::IdType checkpointId = database->AddCheckpoint(testCheckpoint);\n\n        // Add multiple fields.\n        database->SetDataValue(checkpointId, AutomaticCheckpointData::Arguments, fieldName1, { testValue1 });\n        database->SetDataValue(checkpointId, AutomaticCheckpointData::Arguments, fieldName2, { testValue2, testValue3 });\n    }\n\n    {\n        std::shared_ptr<CheckpointDatabase> database = CheckpointDatabase::Open(tempFile);\n        const auto& checkpointIds = database->GetCheckpointIds();\n        REQUIRE_FALSE(checkpointIds.empty());\n\n        auto automaticCheckpointId = checkpointIds.back();\n\n        const auto& fieldNames = database->GetDataFieldNames(automaticCheckpointId, AutomaticCheckpointData::Arguments);\n\n        REQUIRE(fieldNames[0] == fieldName1);\n        REQUIRE(fieldNames[1] == fieldName2);\n\n        REQUIRE(testValue1 == database->GetDataFieldSingleValue(automaticCheckpointId, AutomaticCheckpointData::Arguments, fieldName1));\n\n        const auto& multiValues = database->GetDataFieldMultiValue(automaticCheckpointId, AutomaticCheckpointData::Arguments, fieldName2);\n\n        REQUIRE(testValue2 == multiValues[0]);\n        REQUIRE(testValue3 == multiValues[1]);\n    }\n}\n\nTEST_CASE(\"CheckpointDatabase_CheckpointOrder\", \"[checkpointDatabase]\")\n{\n    // Verifies that the checkpoints are shown in reverse order (latest first).\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\n\n    {\n        std::shared_ptr<CheckpointDatabase> database = CheckpointDatabase::CreateNew(tempFile, { 1, 0 });\n        database->AddCheckpoint(\"firstCheckpoint\"sv);\n        database->AddCheckpoint(\"secondCheckpoint\"sv);\n        database->AddCheckpoint(\"thirdCheckpoint\"sv);\n    }\n\n    {\n        std::shared_ptr<CheckpointDatabase> database = CheckpointDatabase::Open(tempFile);\n        const auto& checkpointIds = database->GetCheckpointIds();\n        REQUIRE(checkpointIds.size() == 3);\n        REQUIRE(checkpointIds[0] == 3);\n        REQUIRE(checkpointIds[1] == 2);\n        REQUIRE(checkpointIds[2] == 1);\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLITests/Command.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <Command.h>\r\n#include <AppInstallerStrings.h>\r\n#include <Commands/RootCommand.h>\r\n\r\nusing namespace std::string_literals;\r\nusing namespace std::string_view_literals;\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller;\r\nusing namespace AppInstaller::CLI;\r\nusing namespace AppInstaller::CLI::Execution;\r\n\r\nstd::string GetCommandName(const std::unique_ptr<Command>& command)\r\n{\r\n    return std::string{ command->FullName() };\r\n}\r\n\r\nstd::vector<std::string_view> GetCommandAliases(const std::unique_ptr<Command>& command)\r\n{\r\n    return std::vector<std::string_view> { command->Aliases() };\r\n}\r\n\r\nstd::string GetArgumentName(const Argument& arg)\r\n{\r\n    return std::string{ arg.Name() };\r\n}\r\n\r\nstd::string GetArgumentAlternateName(const Argument& arg)\r\n{\r\n    if (arg.AlternateName() == Argument::NoAlternateName)\r\n    {\r\n        return {};\r\n    }\r\n    else\r\n    {\r\n        return std::string{ arg.AlternateName() };\r\n    }\r\n}\r\n\r\nstd::string GetArgumentAlias(const Argument& arg)\r\n{\r\n    if (arg.Alias() == ArgumentCommon::NoAlias)\r\n    {\r\n        return {};\r\n    }\r\n    else\r\n    {\r\n        return std::string(1, arg.Alias());\r\n    }\r\n}\r\n\r\nbool StringIsLowercase(const std::string& s)\r\n{\r\n    return Utility::ToLower(s) == s;\r\n}\r\n\r\ntemplate <typename Enumerable, typename Op>\r\nvoid EnsureStringsAreLowercaseAndNoCollisions(const std::string& info, const Enumerable& e, Op& op, std::unordered_set<std::string>& values, bool requireLower = true)\r\n{\r\n    INFO(info);\r\n\r\n    for (const auto& val : e)\r\n    {\r\n        std::string valString = op(val);\r\n        if (valString.empty())\r\n        {\r\n            continue;\r\n        }\r\n        INFO(valString);\r\n\r\n        if (requireLower)\r\n        {\r\n            REQUIRE(StringIsLowercase(valString));\r\n        }\r\n\r\n        REQUIRE(values.find(valString) == values.end());\r\n\r\n        values.emplace(std::move(valString));\r\n    }\r\n}\r\n\r\ntemplate <typename Enumerable, typename Op>\r\nvoid EnsureStringsAreLowercaseAndNoCollisions(const std::string& info, const Enumerable& e, Op& op, bool requireLower = true)\r\n{\r\n    std::unordered_set<std::string> values;\r\n    EnsureStringsAreLowercaseAndNoCollisions(info, e, op, values, requireLower);\r\n}\r\n\r\ntemplate <typename Enumerable, typename Op>\r\nvoid EnsureVectorStringViewsAreLowercaseAndNoCollisions(const std::string& info, const Enumerable& e, Op& op, std::unordered_set<std::string>& values, bool requireLower = true)\r\n{\r\n    INFO(info);\r\n\r\n    for (const auto& val : e)\r\n    { \r\n        std::vector<std::string_view> aliasVector = op(val);\r\n        std::vector<std::string> valVector(aliasVector.begin(), aliasVector.end());\r\n        if (valVector.empty())\r\n        {\r\n            continue;\r\n        }\r\n        // When op returns a vector, we need to ensure every value in the vector does not cause a collision\r\n        for (auto& valString : valVector)\r\n        {\r\n            INFO(valString);\r\n\r\n            if (requireLower)\r\n            {\r\n                REQUIRE(StringIsLowercase(valString));\r\n            }\r\n\r\n            REQUIRE(values.find(valString) == values.end());\r\n            values.emplace(std::move(valString));\r\n        }\r\n    }\r\n}\r\n\r\nvoid EnsureCommandConsistency(const Command& command)\r\n{\r\n    // Command names and aliases exist in the same space, so both need to be checked as a set\r\n    // However, collisions do not occur between levels, so the full name must be used to check for collision\r\n    std::unordered_set<std::string> allCommandAliasNames; \r\n    EnsureStringsAreLowercaseAndNoCollisions(command.FullName() + \" commands\", command.GetCommands(), GetCommandName, allCommandAliasNames);\r\n    EnsureVectorStringViewsAreLowercaseAndNoCollisions(command.FullName() + \" aliases\", command.GetCommands(), GetCommandAliases, allCommandAliasNames);\r\n\r\n    auto args = command.GetArguments();\r\n    Argument::GetCommon(args);\r\n\r\n    // Argument names and alternate names exist in the same space, so both need to be checked as a set\r\n    std::unordered_set<std::string> allArgumentNames;\r\n    EnsureStringsAreLowercaseAndNoCollisions(command.FullName() + \" argument names\", args, GetArgumentName, allArgumentNames);\r\n    EnsureStringsAreLowercaseAndNoCollisions(command.FullName() + \" argument alternate name\", args, GetArgumentAlternateName, allArgumentNames);\r\n    // Argument aliases use a different space than the names and can be checked separately\r\n    EnsureStringsAreLowercaseAndNoCollisions(command.FullName() + \" argument alias\", args, GetArgumentAlias, false);\r\n\r\n    // No : allowed in commands\r\n    for (const auto& comm : command.GetCommands())\r\n    {\r\n        INFO(command.FullName());\r\n        INFO(comm->Name());\r\n\r\n        REQUIRE(comm->Name().find_first_of(Command::ParentSplitChar) == std::string_view::npos);\r\n    }\r\n\r\n    // No = allowed in arguments\r\n    // All positional args should be listed first\r\n    bool foundNonPositional = false;\r\n    bool queryArgPresent = false;\r\n    bool multiQueryArgPresent = false;\r\n    for (const auto& arg : command.GetArguments())\r\n    {\r\n        INFO(command.FullName());\r\n        INFO(arg.Name());\r\n\r\n        REQUIRE(arg.Name().find_first_of(APPINSTALLER_CLI_ARGUMENT_SPLIT_CHAR) == std::string_view::npos);\r\n\r\n        if (arg.Type() == ArgumentType::Positional)\r\n        {\r\n            REQUIRE(!foundNonPositional);\r\n        }\r\n        else\r\n        {\r\n            foundNonPositional = true;\r\n        }\r\n\r\n        if (arg.ExecArgType() == Execution::Args::Type::Query)\r\n        {\r\n            queryArgPresent = true;\r\n        }\r\n\r\n        if (arg.ExecArgType() == Execution::Args::Type::MultiQuery)\r\n        {\r\n            multiQueryArgPresent = true;\r\n        }\r\n    }\r\n\r\n    REQUIRE((!queryArgPresent || !multiQueryArgPresent));\r\n\r\n    // Recurse for all subcommands\r\n    for (const auto& sub : command.GetCommands())\r\n    {\r\n        EnsureCommandConsistency(*sub.get());\r\n    }\r\n}\r\n\r\n// This test ensure that the command tree we expose does not have any inconsistencies.\r\n//  1. No command name collisions\r\n//  2. All command names are lower cased\r\n//  3. No argument name collisions\r\n//  4. All arguments are lower cased\r\n//  5. No argument alias collisions\r\n//  6. All argument alias are lower cased\r\n//  7. No argument names contain '='\r\n//  8. All positional arguments are first in the list\r\n//  9. No command includes both Query and MultiQuery arguments\r\nTEST_CASE(\"EnsureCommandTreeConsistency\", \"[command]\")\r\n{\r\n    RootCommand root;\r\n    EnsureCommandConsistency(root);\r\n}\r\n\r\nstruct TestCommand : public Command\r\n{\r\n    TestCommand(std::vector<Argument> args) : Command(\"test\", \"\"), m_args(std::move(args)) {}\r\n\r\n    std::vector<Argument> GetArguments() const override\r\n    {\r\n        return m_args;\r\n    }\r\n\r\n    CLI::Resource::LocString ShortDescription() const override { return {}; }\r\n    CLI::Resource::LocString LongDescription() const override { return {}; }\r\n\r\n    std::vector<Argument> m_args;\r\n};\r\n\r\n// Matcher that lets us verify CommandExceptions.\r\nstruct CommandExceptionMatcher : public Catch::Matchers::MatcherBase<CommandException>\r\n{\r\n    CommandExceptionMatcher(CLI::Resource::LocString message) : m_expectedMessage(std::move(message)) {}\r\n\r\n    bool match(const CommandException& ce) const override\r\n    {\r\n        return ce.Message() == m_expectedMessage;\r\n    }\r\n\r\n    std::string describe() const override\r\n    {\r\n        std::ostringstream result;\r\n        result << \"has message == \" << m_expectedMessage;\r\n        return result.str();\r\n    }\r\n\r\nprivate:\r\n    CLI::Resource::LocString m_expectedMessage;\r\n};\r\n\r\nnamespace Catch {\r\n    template<>\r\n    struct StringMaker<CommandException> {\r\n        static std::string convert(CommandException const& ce) {\r\n            return Utility::Format(\"CommandException{ '{0}' }\", ce.Message().get());\r\n        }\r\n    };\r\n}\r\n\r\n#define REQUIRE_COMMAND_EXCEPTION(_expr_, _arg_)     REQUIRE_THROWS_MATCHES(_expr_, CommandException, CommandExceptionMatcher(_arg_))\r\n\r\nvoid RequireValueParsedToArg(const std::string& value, const Argument& arg, const Args& args)\r\n{\r\n    REQUIRE(args.Contains(arg.ExecArgType()));\r\n    REQUIRE(value == args.GetArg(arg.ExecArgType()));\r\n}\r\n\r\nvoid RequireValuesParsedToArg(const std::vector<std::string>& values, Args::Type execArgType, const Args& args)\r\n{\r\n    REQUIRE(args.Contains(execArgType));\r\n    REQUIRE(args.GetCount(execArgType) == values.size());\r\n\r\n    auto argValues = args.GetArgs(execArgType);\r\n    for (size_t i = 0; i < values.size(); ++i)\r\n    {\r\n        REQUIRE(argValues->at(i) == values[i]);\r\n    }\r\n}\r\n\r\nvoid RequireValuesParsedToArg(const std::vector<std::string>& values, const Argument& arg, const Args& args)\r\n{\r\n    RequireValuesParsedToArg(values, arg.ExecArgType(), args);\r\n}\r\n\r\n// Description used for tests; doesn't need to be anything in particular.\r\nstatic constexpr CLI::Resource::StringId DefaultDesc{ L\"\"sv };\r\n\r\nTEST_CASE(\"ParseArguments_MultiplePositional\", \"[command]\")\r\n{\r\n    Args args;\r\n    TestCommand command({\r\n            Argument{ \"pos1\", 'p', Args::Type::Channel, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"std1\", 's', Args::Type::Command, DefaultDesc, ArgumentType::Standard },\r\n            Argument{ \"pos2\", 'q', Args::Type::Count, DefaultDesc, ArgumentType::Positional },\r\n        });\r\n\r\n    std::vector<std::string> values{ \"val1\", \"val2\" };\r\n    Invocation inv{ std::vector<std::string>(values) };\r\n\r\n    command.ParseArguments(inv, args);\r\n\r\n    RequireValueParsedToArg(values[0], command.m_args[0], args);\r\n    RequireValueParsedToArg(values[1], command.m_args[2], args);\r\n}\r\n\r\nTEST_CASE(\"ParseArguments_ForcePositional\", \"[command]\")\r\n{\r\n    Args args;\r\n    TestCommand command({\r\n            Argument{ \"pos1\", 'p', Args::Type::Channel, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"std1\", 's', Args::Type::Command, DefaultDesc, ArgumentType::Standard },\r\n            Argument{ \"pos2\", 'q', Args::Type::Count, DefaultDesc, ArgumentType::Positional },\r\n        });\r\n\r\n    std::vector<std::string> values{ \"val1\", \"--\", \"-std1\" };\r\n    Invocation inv{ std::vector<std::string>(values) };\r\n\r\n    command.ParseArguments(inv, args);\r\n\r\n    RequireValueParsedToArg(values[0], command.m_args[0], args);\r\n    RequireValueParsedToArg(values[2], command.m_args[2], args);\r\n}\r\n\r\nTEST_CASE(\"ParseArguments_TooManyPositional\", \"[command]\")\r\n{\r\n    Args args;\r\n    TestCommand command({\r\n            Argument{ \"pos1\", 'p', Args::Type::Channel, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"std1\", 's', Args::Type::Command, DefaultDesc, ArgumentType::Standard },\r\n        });\r\n\r\n    std::vector<std::string> values{ \"val1\", \"--\", \"-std1\" };\r\n    Invocation inv{ std::vector<std::string>(values) };\r\n\r\n    REQUIRE_COMMAND_EXCEPTION(command.ParseArguments(inv, args), CLI::Resource::String::ExtraPositionalError(Utility::LocIndView{ values[2] }));\r\n}\r\n\r\nTEST_CASE(\"ParseArguments_InvalidChar\", \"[command]\")\r\n{\r\n    Args args;\r\n    TestCommand command({\r\n            Argument{ \"pos1\", 'p', Args::Type::Channel, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"std1\", 's', Args::Type::Command, DefaultDesc, ArgumentType::Standard },\r\n            Argument{ \"pos2\", 'q', Args::Type::Count, DefaultDesc, ArgumentType::Positional },\r\n        });\r\n\r\n    std::vector<std::string> values{ \"val1\", \"-\", \"-std1\" };\r\n    Invocation inv{ std::vector<std::string>(values) };\r\n\r\n    REQUIRE_COMMAND_EXCEPTION(command.ParseArguments(inv, args), CLI::Resource::String::InvalidArgumentSpecifierError(Utility::LocIndView{ values[1] }));\r\n}\r\n\r\nTEST_CASE(\"ParseArguments_InvalidAlias\", \"[command]\")\r\n{\r\n    Args args;\r\n    TestCommand command({\r\n            Argument{ \"pos1\", 'p', Args::Type::Channel, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"std1\", 's', Args::Type::Command, DefaultDesc, ArgumentType::Standard },\r\n            Argument{ \"pos2\", 'q', Args::Type::Count, DefaultDesc, ArgumentType::Positional },\r\n        });\r\n\r\n    std::vector<std::string> values{ \"val1\", \"-b\", \"-std1\" };\r\n    Invocation inv{ std::vector<std::string>(values) };\r\n\r\n    REQUIRE_COMMAND_EXCEPTION(command.ParseArguments(inv, args), CLI::Resource::String::InvalidAliasError(Utility::LocIndView{ values[1] }));\r\n}\r\n\r\nTEST_CASE(\"ParseArguments_MultiFlag\", \"[command]\")\r\n{\r\n    Args args;\r\n    TestCommand command({\r\n            Argument{ \"pos1\", 'p', Args::Type::Channel, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"flag1\", 's', Args::Type::Command, DefaultDesc, ArgumentType::Flag },\r\n            Argument{ \"pos2\", 'q', Args::Type::Count, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"flag2\", 't', Args::Type::Exact, DefaultDesc, ArgumentType::Flag },\r\n        });\r\n\r\n    std::vector<std::string> values{ \"val1\", \"-st\", \"val2\" };\r\n    Invocation inv{ std::vector<std::string>(values) };\r\n\r\n    command.ParseArguments(inv, args);\r\n\r\n    REQUIRE(args.Contains(command.m_args[1].ExecArgType()));\r\n    REQUIRE(args.Contains(command.m_args[3].ExecArgType()));\r\n}\r\n\r\nTEST_CASE(\"ParseArguments_FlagThenUnknown\", \"[command]\")\r\n{\r\n    Args args;\r\n    TestCommand command({\r\n            Argument{ \"pos1\", 'p', Args::Type::Channel, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"flag1\", 's', Args::Type::Command, DefaultDesc, ArgumentType::Flag },\r\n            Argument{ \"pos2\", 'q', Args::Type::Count, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"flag2\", 't', Args::Type::Exact, DefaultDesc, ArgumentType::Flag },\r\n        });\r\n\r\n    std::vector<std::string> values{ \"val1\", \"-sr\", \"val2\" };\r\n    Invocation inv{ std::vector<std::string>(values) };\r\n\r\n    REQUIRE_COMMAND_EXCEPTION(command.ParseArguments(inv, args), CLI::Resource::String::AdjoinedNotFoundError(Utility::LocIndView{ values[1] }));\r\n}\r\n\r\nTEST_CASE(\"ParseArguments_FlagThenNonFlag\", \"[command]\")\r\n{\r\n    Args args;\r\n    TestCommand command({\r\n            Argument{ \"pos1\", 'p', Args::Type::Channel, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"flag1\", 's', Args::Type::Command, DefaultDesc, ArgumentType::Flag },\r\n            Argument{ \"pos2\", 'q', Args::Type::Count, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"flag2\", 't', Args::Type::Exact, DefaultDesc, ArgumentType::Flag },\r\n        });\r\n\r\n    std::vector<std::string> values{ \"val1\", \"-sp\", \"val2\" };\r\n    Invocation inv{ std::vector<std::string>(values) };\r\n\r\n    REQUIRE_COMMAND_EXCEPTION(command.ParseArguments(inv, args), CLI::Resource::String::AdjoinedNotFlagError(Utility::LocIndView{ values[1] }));\r\n}\r\n\r\nTEST_CASE(\"ParseArguments_NameUsingAliasSpecifier\", \"[command]\")\r\n{\r\n    Args args;\r\n    TestCommand command({\r\n            Argument{ \"pos1\", 'p', Args::Type::Channel, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"std1\", 's', Args::Type::Command, DefaultDesc, ArgumentType::Standard },\r\n            Argument{ \"pos2\", 'q', Args::Type::Count, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"flag1\", 'f', Args::Type::Exact, DefaultDesc, ArgumentType::Flag },\r\n        });\r\n\r\n    std::vector<std::string> values{ \"another\", \"-flag1\" };\r\n    Invocation inv{ std::vector<std::string>(values) };\r\n\r\n    REQUIRE_COMMAND_EXCEPTION(command.ParseArguments(inv, args), CLI::Resource::String::AdjoinedNotFoundError(Utility::LocIndView{ values[1] }));\r\n}\r\n\r\nTEST_CASE(\"ParseArguments_AliasWithAdjoinedValue\", \"[command]\")\r\n{\r\n    Args args;\r\n    TestCommand command({\r\n            Argument{ \"pos1\", 'p', Args::Type::Channel, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"std1\", 's', Args::Type::Command, DefaultDesc, ArgumentType::Standard },\r\n            Argument{ \"pos2\", 'q', Args::Type::Count, DefaultDesc, ArgumentType::Positional },\r\n        });\r\n\r\n    std::vector<std::string> values{ \"-s=Val1\" };\r\n    Invocation inv{ std::vector<std::string>(values) };\r\n\r\n    command.ParseArguments(inv, args);\r\n\r\n    RequireValueParsedToArg(values[0].substr(3), command.m_args[1], args);\r\n}\r\n\r\nTEST_CASE(\"ParseArguments_AliasWithSeparatedValue\", \"[command]\")\r\n{\r\n    Args args;\r\n    TestCommand command({\r\n            Argument{ \"pos1\", 'p', Args::Type::Channel, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"std1\", 's', Args::Type::Command, DefaultDesc, ArgumentType::Standard },\r\n            Argument{ \"pos2\", 'q', Args::Type::Count, DefaultDesc, ArgumentType::Positional },\r\n        });\r\n\r\n    std::vector<std::string> values{ \"-s\", \"Val1\" };\r\n    Invocation inv{ std::vector<std::string>(values) };\r\n\r\n    command.ParseArguments(inv, args);\r\n\r\n    RequireValueParsedToArg(values[1], command.m_args[1], args);\r\n}\r\n\r\nTEST_CASE(\"ParseArguments_AliasWithSeparatedValueMissing\", \"[command]\")\r\n{\r\n    Args args;\r\n    TestCommand command({\r\n            Argument{ \"pos1\", 'p', Args::Type::Channel, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"std1\", 's', Args::Type::Command, DefaultDesc, ArgumentType::Standard },\r\n            Argument{ \"pos2\", 'q', Args::Type::Count, DefaultDesc, ArgumentType::Positional },\r\n        });\r\n\r\n    std::vector<std::string> values{ \"-s\" };\r\n    Invocation inv{ std::vector<std::string>(values) };\r\n\r\n    REQUIRE_COMMAND_EXCEPTION(command.ParseArguments(inv, args), CLI::Resource::String::MissingArgumentError(Utility::LocIndView{ values[0] }));\r\n}\r\n\r\nTEST_CASE(\"ParseArguments_NameWithAdjoinedValue\", \"[command]\")\r\n{\r\n    Args args;\r\n    TestCommand command({\r\n            Argument{ \"pos1\", 'p', Args::Type::Channel, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"std1\", 's', Args::Type::Command, DefaultDesc, ArgumentType::Standard },\r\n            Argument{ \"pos2\", 'q', Args::Type::Count, DefaultDesc, ArgumentType::Positional },\r\n        });\r\n\r\n    std::vector<std::string> values{ \"--pos1=Val1\" };\r\n    Invocation inv{ std::vector<std::string>(values) };\r\n\r\n    command.ParseArguments(inv, args);\r\n\r\n    RequireValueParsedToArg(values[0].substr(7), command.m_args[0], args);\r\n}\r\n\r\nTEST_CASE(\"ParseArguments_AlternateNameWithAdjoinedValue\", \"[command]\")\r\n{\r\n    Args args;\r\n    TestCommand command({\r\n            Argument{ \"pos1\", 'p', \"p1\", Args::Type::Channel, DefaultDesc, ArgumentType::Positional},\r\n            Argument{ \"std1\", 's', Args::Type::Command, DefaultDesc, ArgumentType::Standard },\r\n            Argument{ \"pos2\", 'q', Args::Type::Count, DefaultDesc, ArgumentType::Positional },\r\n        });\r\n\r\n    std::vector<std::string> values{ \"--p1=Val1\" };\r\n    Invocation inv{ std::vector<std::string>(values) };\r\n\r\n    command.ParseArguments(inv, args);\r\n\r\n    RequireValueParsedToArg(values[0].substr(5), command.m_args[0], args);\r\n}\r\n\r\nTEST_CASE(\"ParseArguments_NameFlag\", \"[command]\")\r\n{\r\n    Args args;\r\n    TestCommand command({\r\n            Argument{ \"pos1\", 'p', Args::Type::Channel, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"std1\", 's', Args::Type::Command, DefaultDesc, ArgumentType::Standard },\r\n            Argument{ \"pos2\", 'q', Args::Type::Count, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"flag1\", 'f', Args::Type::Exact, DefaultDesc, ArgumentType::Flag },\r\n        });\r\n\r\n    std::vector<std::string> values{ \"--flag1\", \"arbitrary\" };\r\n    Invocation inv{ std::vector<std::string>(values) };\r\n\r\n    command.ParseArguments(inv, args);\r\n\r\n    RequireValueParsedToArg(values[1], command.m_args[0], args);\r\n    REQUIRE(args.Contains(command.m_args[3].ExecArgType()));\r\n}\r\n\r\nTEST_CASE(\"ParseArguments_NameFlagWithAdjoinedValue\", \"[command]\")\r\n{\r\n    Args args;\r\n    TestCommand command({\r\n            Argument{ \"pos1\", 'p', Args::Type::Channel, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"std1\", 's', Args::Type::Command, DefaultDesc, ArgumentType::Standard },\r\n            Argument{ \"pos2\", 'q', Args::Type::Count, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"flag1\", 'f', Args::Type::Exact, DefaultDesc, ArgumentType::Flag },\r\n        });\r\n\r\n    std::vector<std::string> values{ \"another\", \"--flag1=arbitrary\" };\r\n    Invocation inv{ std::vector<std::string>(values) };\r\n\r\n    REQUIRE_COMMAND_EXCEPTION(command.ParseArguments(inv, args), CLI::Resource::String::FlagContainAdjoinedError(Utility::LocIndView{ values[1] }));\r\n}\r\n\r\nTEST_CASE(\"ParseArguments_NameWithSeparatedValue\", \"[command]\")\r\n{\r\n    Args args;\r\n    TestCommand command({\r\n            Argument{ \"pos1\", 'p', Args::Type::Channel, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"std1\", 's', Args::Type::Command, DefaultDesc, ArgumentType::Standard },\r\n            Argument{ \"pos2\", 'q', Args::Type::Count, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"flag1\", 'f', Args::Type::Exact, DefaultDesc, ArgumentType::Flag },\r\n        });\r\n\r\n    std::vector<std::string> values{ \"--pos2\", \"arbitrary\" };\r\n    Invocation inv{ std::vector<std::string>(values) };\r\n\r\n    command.ParseArguments(inv, args);\r\n\r\n    RequireValueParsedToArg(values[1], command.m_args[2], args);\r\n}\r\n\r\nTEST_CASE(\"ParseArguments_NameWithSeparatedValueMissing\", \"[command]\")\r\n{\r\n    Args args;\r\n    TestCommand command({\r\n            Argument{ \"pos1\", 'p', Args::Type::Channel, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"std1\", 's', Args::Type::Command, DefaultDesc, ArgumentType::Standard },\r\n            Argument{ \"pos2\", 'q', Args::Type::Count, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"flag1\", 'f', Args::Type::Exact, DefaultDesc, ArgumentType::Flag },\r\n        });\r\n\r\n    std::vector<std::string> values{ \"--pos2\" };\r\n    Invocation inv{ std::vector<std::string>(values) };\r\n\r\n    REQUIRE_COMMAND_EXCEPTION(command.ParseArguments(inv, args), CLI::Resource::String::MissingArgumentError(Utility::LocIndView{ values[0] }));\r\n}\r\n\r\nTEST_CASE(\"ParseArguments_UnknownName\", \"[command]\")\r\n{\r\n    Args args;\r\n    TestCommand command({\r\n            Argument{ \"pos1\", 'p', Args::Type::Channel, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"std1\", 's', Args::Type::Command, DefaultDesc, ArgumentType::Standard },\r\n            Argument{ \"pos2\", 'q', Args::Type::Count, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"flag1\", 'f', Args::Type::Exact, DefaultDesc, ArgumentType::Flag },\r\n        });\r\n\r\n    std::vector<std::string> values{ \"another\", \"--nope\" };\r\n    Invocation inv{ std::vector<std::string>(values) };\r\n\r\n    REQUIRE_COMMAND_EXCEPTION(command.ParseArguments(inv, args), CLI::Resource::String::InvalidNameError(Utility::LocIndView{ values[1] }));\r\n}\r\n\r\nTEST_CASE(\"ParseArguments_PositionalWithMultipleValues\", \"[command]\")\r\n{\r\n    Args args;\r\n    TestCommand command({\r\n            Argument{ \"multi\", 'm', Args::Type::MultiQuery, DefaultDesc, ArgumentType::Positional }.SetCountLimit(5),\r\n        });\r\n\r\n    std::vector<std::string> values{ \"value1\" \"value2\", \"value3\" };\r\n    Invocation inv{ std::vector<std::string>(values) };\r\n\r\n    command.ParseArguments(inv, args);\r\n    RequireValuesParsedToArg(values, command.m_args[0], args);\r\n}\r\n\r\nTEST_CASE(\"ParseArguments_PositionalWithMultipleValuesAndOtherArgs\", \"[command]\")\r\n{\r\n    Args args;\r\n    TestCommand command({\r\n            Argument{ \"pos1\", 'p', Args::Type::Source, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"pos2\", 'q', Args::Type::All, DefaultDesc, ArgumentType::Positional },\r\n            Argument{ \"multi\", 'm', Args::Type::MultiQuery, DefaultDesc, ArgumentType::Positional }.SetCountLimit(5),\r\n            Argument{ \"flag\", 'f', Args::Type::BlockingPin, DefaultDesc, ArgumentType::Flag },\r\n        });\r\n\r\n    std::vector<std::string> values{ \"positional\", \"-q\", \"anotherPos\", \"multiValue1\", \"multiValue2\", \"-f\" };\r\n    Invocation inv{ std::vector<std::string>(values) };\r\n\r\n    command.ParseArguments(inv, args);\r\n    RequireValueParsedToArg(values[0], command.m_args[0], args);\r\n    RequireValueParsedToArg(values[2], command.m_args[1], args);\r\n    RequireValuesParsedToArg({ values[3], values[4] }, command.m_args[2], args);\r\n    REQUIRE(args.Contains(command.m_args[3].ExecArgType()));\r\n}\r\n\r\nTEST_CASE(\"ParseArguments_PositionalWithMultipleValuesAndName\", \"[command]\")\r\n{\r\n    Args args;\r\n    TestCommand command({\r\n            Argument{ \"multi\", 'm', Args::Type::MultiQuery, DefaultDesc, ArgumentType::Positional }.SetCountLimit(5),\r\n        });\r\n\r\n    std::vector<std::string> values{ \"--multi\", \"one\", \"two\", \"three\" };\r\n    Invocation inv{ std::vector<std::string>(values) };\r\n\r\n    command.ParseArguments(inv, args);\r\n    RequireValuesParsedToArg({ values[1], values[2], values[3] }, command.m_args[0], args);\r\n}\r\n\r\nTEST_CASE(\"ParseArguments_MultiQueryConvertedToSingleQuery\", \"[command]\")\r\n{\r\n    Args args;\r\n    TestCommand command({\r\n            Argument{ \"multi\", 'm', Args::Type::MultiQuery, DefaultDesc, ArgumentType::Positional }.SetCountLimit(5),\r\n        });\r\n\r\n    std::vector<std::string> values{ \"singleValue\" };\r\n    Invocation inv{ std::vector<std::string>(values) };\r\n\r\n    // ParseArguments converts MultiQuery args with a single value into Query args\r\n    command.ParseArguments(inv, args);\r\n    RequireValuesParsedToArg({ values[0] }, Args::Type::Query, args);\r\n}\r\n\r\nTEST_CASE(\"ParseArguments_PositionalWithTooManyValues\", \"[command]\")\r\n{\r\n    Args args;\r\n    TestCommand command({\r\n            Argument{ \"multi\", 'm', Args::Type::MultiQuery, DefaultDesc, ArgumentType::Positional }.SetCountLimit(5),\r\n        });\r\n\r\n    std::vector<std::string> values{ \"1\", \"2\", \"3\", \"4\", \"5\", \"tooMany\" };\r\n    Invocation inv{ std::vector<std::string>(values) };\r\n\r\n    REQUIRE_COMMAND_EXCEPTION(command.ParseArguments(inv, args), CLI::Resource::String::ExtraPositionalError(Utility::LocIndView{ values.back() }));\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/Completion.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <AppInstallerErrors.h>\r\n#include <Command.h>\r\n#include <Commands/CompleteCommand.h>\r\n#include <Commands/RootCommand.h>\r\n#include <Commands/SourceCommand.h>\r\n#include <CompletionData.h>\r\n\r\nusing namespace std::string_literals;\r\nusing namespace std::string_view_literals;\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller;\r\nusing namespace AppInstaller::CLI;\r\nusing namespace AppInstaller::CLI::Execution;\r\n\r\n\r\nTEST_CASE(\"CompletionData_EmptyWord_PositionAtEnd\", \"[complete]\")\r\n{\r\n    CompletionData cd{ \"\", \"winget \", \"7\" };\r\n    REQUIRE(cd.Word() == \"\");\r\n    REQUIRE(cd.BeforeWord().size() == 0);\r\n    REQUIRE(cd.AfterWord().size() == 0);\r\n}\r\n\r\nTEST_CASE(\"CompletionData_EmptyWord_PositionPastEnd\", \"[complete]\")\r\n{\r\n    CompletionData cd{ \"\", \"winget \", \"8\" };\r\n    REQUIRE(cd.Word() == \"\");\r\n    REQUIRE(cd.BeforeWord().size() == 0);\r\n    REQUIRE(cd.AfterWord().size() == 0);\r\n}\r\n\r\nTEST_CASE(\"CompletionData_EmptyWord_PositionCorrect\", \"[complete]\")\r\n{\r\n    CompletionData cd{ \"\", \"winget install\", \"7\" };\r\n    REQUIRE(cd.Word() == \"\");\r\n    REQUIRE(cd.BeforeWord().size() == 0);\r\n    REQUIRE(cd.AfterWord().size() == 1);\r\n}\r\n\r\n\r\nTEST_CASE(\"CompletionData_EmptyWord_PositionOffset\", \"[complete]\")\r\n{\r\n    CompletionData cd{ \"\", \"winget install PowerToys --version\", \"17\" };\r\n    REQUIRE(cd.Word() == \"\");\r\n    REQUIRE(cd.BeforeWord().size() == 1);\r\n    REQUIRE(cd.AfterWord().size() == 2);\r\n}\r\n\r\nTEST_CASE(\"CompletionData_Word_NoMatch\", \"[complete]\")\r\n{\r\n    auto lambda = []() { CompletionData cd{ \"foo\", \"winget install PowerToys --version\", \"17\" }; };\r\n    REQUIRE_THROWS_HR(lambda(), APPINSTALLER_CLI_ERROR_COMPLETE_INPUT_BAD);\r\n}\r\n\r\nTEST_CASE(\"CompletionData_Word_SingleMatch\", \"[complete]\")\r\n{\r\n    CompletionData cd{ \"power\", \"winget install power --version\", \"17\" };\r\n    REQUIRE(cd.Word() == \"power\");\r\n    REQUIRE(cd.BeforeWord().size() == 1);\r\n    REQUIRE(cd.AfterWord().size() == 1);\r\n}\r\n\r\nTEST_CASE(\"CompletionData_Word_MultiMatch_PositionCorrect\", \"[complete]\")\r\n{\r\n    CompletionData cd{ \"power\", \"winget install power --id power\", \"27\" };\r\n    REQUIRE(cd.Word() == \"power\");\r\n    REQUIRE(cd.BeforeWord().size() == 3);\r\n    REQUIRE(cd.AfterWord().size() == 0);\r\n}\r\n\r\nTEST_CASE(\"CompletionData_Word_MultiMatch_PositionOffset\", \"[complete]\")\r\n{\r\n    CompletionData cd{ \"power\", \"winget install power --id power\", \"21\" };\r\n    REQUIRE(cd.Word() == \"power\");\r\n    REQUIRE(cd.BeforeWord().size() == 1);\r\n    REQUIRE(cd.AfterWord().size() == 2);\r\n}\r\n\r\nTEST_CASE(\"CompletionData_UTF8_EmptyWord_End\", \"[complete]\")\r\n{\r\n    CompletionData cd{ \"\", u8\"winget install \\x175\\x12b\\x14b\\x1e5\\x229\\x288 --version \", \"32\" };\r\n    REQUIRE(cd.Word() == \"\");\r\n    REQUIRE(cd.BeforeWord().size() == 3);\r\n    REQUIRE(cd.AfterWord().size() == 0);\r\n}\r\n\r\nTEST_CASE(\"CompletionData_UTF8_EmptyWord_Middle\", \"[complete]\")\r\n{\r\n    CompletionData cd{ \"\", u8\"winget install \\x175\\x12b\\x14b\\x1e5\\x229\\x288 --version \", \"22\" };\r\n    REQUIRE(cd.Word() == \"\");\r\n    REQUIRE(cd.BeforeWord().size() == 2);\r\n    REQUIRE(cd.AfterWord().size() == 1);\r\n}\r\n\r\nTEST_CASE(\"CompletionData_UTF8_UTF8Word\", \"[complete]\")\r\n{\r\n    CompletionData cd{ u8\"\\x175\\x12b\\x14b\\x1e5\\x229\\x288\", u8\"winget install \\x175\\x12b\\x14b\\x1e5\\x229\\x288 --version \", \"18\" };\r\n    REQUIRE(cd.Word() == u8\"\\x175\\x12b\\x14b\\x1e5\\x229\\x288\");\r\n    REQUIRE(cd.BeforeWord().size() == 1);\r\n    REQUIRE(cd.AfterWord().size() == 1);\r\n}\r\n\r\nvoid OutputAllSubCommands(Command& command, std::ostream& out, std::string_view filter = {})\r\n{\r\n    for (const auto& c : command.GetCommands())\r\n    {\r\n        if (Utility::CaseInsensitiveStartsWith(c->Name(), filter))\r\n        {\r\n            out << c->Name() << std::endl;\r\n        }\r\n    }\r\n}\r\n\r\nvoid OutputAllArgumentNames(Command& command, std::ostream& out, std::string_view filter = {}, bool includeCommon = true)\r\n{\r\n    auto args = command.GetArguments();\r\n    if (includeCommon)\r\n    {\r\n        Argument::GetCommon(args);\r\n    }\r\n\r\n    for (const auto& a : args)\r\n    {\r\n        if (Utility::CaseInsensitiveStartsWith(a.Name(), filter))\r\n        {\r\n            out << APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_CHAR << APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_CHAR << a.Name() << std::endl;\r\n        }\r\n    }\r\n}\r\n\r\nvoid OutputAllArgumentAliases(Command& command, std::ostream& out, bool includeCommon = true)\r\n{\r\n    auto args = command.GetArguments();\r\n    if (includeCommon)\r\n    {\r\n        Argument::GetCommon(args);\r\n    }\r\n\r\n    for (const auto& a : args)\r\n    {\r\n        if (a.Alias() != ArgumentCommon::NoAlias)\r\n        {\r\n            out << APPINSTALLER_CLI_ARGUMENT_IDENTIFIER_CHAR << a.Alias() << std::endl;\r\n        }\r\n    }\r\n}\r\n\r\nTEST_CASE(\"CompleteCommand_FindRoot\", \"[complete]\")\r\n{\r\n    std::stringstream out, in;\r\n    Context context{ out, in };\r\n\r\n    CompleteCommand command{ \"test\" };\r\n    context.Args.AddArg(Args::Type::Word, \"\"sv);\r\n    context.Args.AddArg(Args::Type::CommandLine, \"winget \"sv);\r\n    context.Args.AddArg(Args::Type::Position, \"7\"sv);\r\n    command.Execute(context);\r\n\r\n    // Create expected values\r\n    RootCommand expectedCommand;\r\n    std::stringstream expected;\r\n    OutputAllSubCommands(expectedCommand, expected);\r\n    OutputAllArgumentNames(expectedCommand, expected);\r\n\r\n    REQUIRE(out.str() == expected.str());\r\n}\r\n\r\nTEST_CASE(\"CompleteCommand_FindSource\", \"[complete]\")\r\n{\r\n    std::stringstream out, in;\r\n    Context context{ out, in };\r\n\r\n    CompleteCommand command{ \"test\" };\r\n    context.Args.AddArg(Args::Type::Word, \"\"sv);\r\n    context.Args.AddArg(Args::Type::CommandLine, \"winget source \"sv);\r\n    context.Args.AddArg(Args::Type::Position, \"14\"sv);\r\n    command.Execute(context);\r\n\r\n    // Create expected values\r\n    SourceCommand expectedCommand{ \"test\" };\r\n    std::stringstream expected;\r\n    OutputAllSubCommands(expectedCommand, expected);\r\n    OutputAllArgumentNames(expectedCommand, expected);\r\n\r\n    REQUIRE(out.str() == expected.str());\r\n}\r\n\r\nTEST_CASE(\"CompleteCommand_FindSourceAdd\", \"[complete]\")\r\n{\r\n    std::stringstream out, in;\r\n    Context context{ out, in };\r\n\r\n    CompleteCommand command{ \"test\" };\r\n    context.Args.AddArg(Args::Type::Word, \"\"sv);\r\n    context.Args.AddArg(Args::Type::CommandLine, \"winget source add \"sv);\r\n    context.Args.AddArg(Args::Type::Position, \"18\"sv);\r\n    command.Execute(context);\r\n\r\n    // Create expected values\r\n    SourceAddCommand expectedCommand{ \"test\" };\r\n    std::stringstream expected;\r\n    OutputAllSubCommands(expectedCommand, expected);\r\n    OutputAllArgumentNames(expectedCommand, expected);\r\n\r\n    REQUIRE(out.str() == expected.str());\r\n}\r\n\r\nstruct CompletionTestCommand : public Command\r\n{\r\n    CompletionTestCommand() : Command(\"test\", \"\") {}\r\n    CompletionTestCommand(std::string_view name) : Command(name, \"\") {}\r\n\r\n    std::vector<std::unique_ptr<Command>> GetCommands() const override\r\n    {\r\n        std::vector<std::unique_ptr<Command>> result;\r\n\r\n        for (const auto& sc : SubCommandNames)\r\n        {\r\n            result.emplace_back(std::make_unique<CompletionTestCommand>(sc));\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<Argument> GetArguments() const override\r\n    {\r\n        return Arguments;\r\n    }\r\n\r\n    CLI::Resource::LocString ShortDescription() const override { return {}; }\r\n    CLI::Resource::LocString LongDescription() const override { return {}; }\r\n\r\n    using Command::Complete;\r\n\r\n    void Complete(Execution::Context& context, Execution::Args::Type valueType) const override\r\n    {\r\n        if (ArgumentValueCallback)\r\n        {\r\n            ArgumentValueCallback(context, valueType);\r\n        }\r\n    }\r\n\r\n    std::vector<std::string> SubCommandNames;\r\n    std::vector<Argument> Arguments;\r\n    std::function<void(Context&, Execution::Args::Type)> ArgumentValueCallback;\r\n};\r\n\r\nstruct CompletionTestContext\r\n{\r\n    CompletionTestContext(std::string_view word, std::string_view commandLine, std::string_view position) :\r\n        context(out, in)\r\n    {\r\n        context.Reporter.SetChannel(Execution::Reporter::Channel::Completion);\r\n        context.Add<Data::CompletionData>(CompletionData{ word, commandLine, position });\r\n    }\r\n\r\n    std::stringstream out;\r\n    std::stringstream in;\r\n    Context context;\r\n};\r\n\r\nTEST_CASE(\"CommandComplete_Simple\", \"[complete]\")\r\n{\r\n    CompletionTestContext ctc{ \"\", \"winget \", \"7\" };\r\n\r\n    CompletionTestCommand command;\r\n    command.SubCommandNames = { \"test1\", \"test2\" };\r\n    command.Arguments = { Argument{ \"arg1\", 'a', Args::Type::Query, CLI::Resource::String::Done, ArgumentType::Standard } };\r\n    command.ArgumentValueCallback = [&](Context&, Execution::Args::Type) { FAIL(\"No argument value should be requested\"); };\r\n    command.Complete(ctc.context);\r\n\r\n    // Create expected values\r\n    std::stringstream expected;\r\n    OutputAllSubCommands(command, expected);\r\n    OutputAllArgumentNames(command, expected);\r\n\r\n    REQUIRE(ctc.out.str() == expected.str());\r\n}\r\n\r\nTEST_CASE(\"CommandComplete_PartialCommandMatch\", \"[complete]\")\r\n{\r\n    CompletionTestContext ctc{ \"cart\", \"winget cart\", \"11\" };\r\n\r\n    CompletionTestCommand command;\r\n    command.SubCommandNames = { \"car\", \"cart\", \"cartesian\", \"carpet\" };\r\n    command.ArgumentValueCallback = [&](Context&, Execution::Args::Type) { FAIL(\"No argument value should be requested\"); };\r\n    command.Complete(ctc.context);\r\n\r\n    // Create expected values\r\n    std::stringstream expected;\r\n    OutputAllSubCommands(command, expected, \"cart\");\r\n    OutputAllArgumentNames(command, expected, \"cart\");\r\n\r\n    REQUIRE(ctc.out.str() == expected.str());\r\n}\r\n\r\nTEST_CASE(\"CommandComplete_CommandsNotAllowed\", \"[complete]\")\r\n{\r\n    CompletionTestContext ctc{ \"\", \"winget foobar \", \"14\" };\r\n\r\n    CompletionTestCommand command;\r\n    command.SubCommandNames = { \"car\", \"cart\", \"cartesian\", \"carpet\" };\r\n    command.ArgumentValueCallback = [&](Context&, Execution::Args::Type) { FAIL(\"No argument value should be requested\"); };\r\n    command.Complete(ctc.context);\r\n\r\n    // Create expected values\r\n    std::stringstream expected;\r\n    OutputAllArgumentNames(command, expected);\r\n\r\n    REQUIRE(ctc.out.str() == expected.str());\r\n}\r\n\r\nTEST_CASE(\"CommandComplete_Routing1\", \"[complete]\")\r\n{\r\n    CompletionTestContext ctc{ \"\", \"winget --arg1 \", \"14\" };\r\n\r\n    CompletionTestCommand command;\r\n    command.SubCommandNames = { \"car\", \"cart\", \"cartesian\", \"carpet\" };\r\n    command.Arguments = {\r\n        Argument{ \"arg1\", '1', Args::Type::Query, CLI::Resource::String::Done, ArgumentType::Standard },\r\n        Argument{ \"arg2\", '2', Args::Type::Channel, CLI::Resource::String::Done, ArgumentType::Standard },\r\n    };\r\n    Args::Type argType = static_cast<Args::Type>(-1);\r\n    command.ArgumentValueCallback = [&](Context&, Execution::Args::Type type) { argType = type; };\r\n    command.Complete(ctc.context);\r\n\r\n    // Create expected values\r\n    std::stringstream expected;\r\n\r\n    REQUIRE(ctc.out.str() == expected.str());\r\n    REQUIRE(argType == command.Arguments[0].ExecArgType());\r\n}\r\n\r\nTEST_CASE(\"CommandComplete_Routing2\", \"[complete]\")\r\n{\r\n    CompletionTestContext ctc{ \"\", \"winget --arg2 \", \"14\" };\r\n\r\n    CompletionTestCommand command;\r\n    command.SubCommandNames = { \"car\", \"cart\", \"cartesian\", \"carpet\" };\r\n    command.Arguments = {\r\n        Argument{ \"arg1\", '1', Args::Type::Query, CLI::Resource::String::Done, ArgumentType::Standard },\r\n        Argument{ \"arg2\", '2', Args::Type::Channel, CLI::Resource::String::Done, ArgumentType::Standard },\r\n    };\r\n    Args::Type argType = static_cast<Args::Type>(-1);\r\n    command.ArgumentValueCallback = [&](Context&, Execution::Args::Type type) { argType = type; };\r\n    command.Complete(ctc.context);\r\n\r\n    // Create expected values\r\n    std::stringstream expected;\r\n\r\n    REQUIRE(ctc.out.str() == expected.str());\r\n    REQUIRE(argType == command.Arguments[1].ExecArgType());\r\n}\r\n\r\nTEST_CASE(\"CommandComplete_PositionalRouting\", \"[complete]\")\r\n{\r\n    CompletionTestContext ctc{ \"\", \"winget \", \"7\" };\r\n\r\n    CompletionTestCommand command;\r\n    command.SubCommandNames = { \"car\", \"cart\", \"cartesian\", \"carpet\" };\r\n    command.Arguments = {\r\n        Argument{ \"arg1\", '1', Args::Type::Query, CLI::Resource::String::Done, ArgumentType::Standard },\r\n        Argument{ \"arg2\", '2', Args::Type::Channel, CLI::Resource::String::Done, ArgumentType::Positional },\r\n    };\r\n    Args::Type argType = static_cast<Args::Type>(-1);\r\n    command.ArgumentValueCallback = [&](Context&, Execution::Args::Type type) { argType = type; };\r\n    command.Complete(ctc.context);\r\n\r\n    // Create expected values\r\n    std::stringstream expected;\r\n    OutputAllSubCommands(command, expected);\r\n    OutputAllArgumentNames(command, expected);\r\n\r\n    REQUIRE(ctc.out.str() == expected.str());\r\n    REQUIRE(argType == command.Arguments[1].ExecArgType());\r\n}\r\n\r\nTEST_CASE(\"CommandComplete_PositionalRoutingAfterArgs\", \"[complete]\")\r\n{\r\n    CompletionTestContext ctc{ \"\", \"winget --arg1 value \", \"20\" };\r\n\r\n    CompletionTestCommand command;\r\n    command.SubCommandNames = { \"car\", \"cart\", \"cartesian\", \"carpet\" };\r\n    command.Arguments = {\r\n        Argument{ \"arg1\", '1', Args::Type::Query, CLI::Resource::String::Done, ArgumentType::Standard },\r\n        Argument{ \"arg2\", '2', Args::Type::Channel, CLI::Resource::String::Done, ArgumentType::Positional },\r\n    };\r\n    Args::Type argType = static_cast<Args::Type>(-1);\r\n    command.ArgumentValueCallback = [&](Context&, Execution::Args::Type type) { argType = type; };\r\n    command.Complete(ctc.context);\r\n\r\n    // Create expected values\r\n    std::stringstream expected;\r\n    OutputAllArgumentNames(command, expected);\r\n\r\n    REQUIRE(ctc.out.str() == expected.str());\r\n    REQUIRE(argType == command.Arguments[1].ExecArgType());\r\n}\r\n\r\nTEST_CASE(\"CommandComplete_PositionalRoutingAfterDoubleDash\", \"[complete]\")\r\n{\r\n    CompletionTestContext ctc{ \"\", \"winget -- \", \"10\" };\r\n\r\n    CompletionTestCommand command;\r\n    command.SubCommandNames = { \"car\", \"cart\", \"cartesian\", \"carpet\" };\r\n    command.Arguments = {\r\n        Argument{ \"arg1\", '1', Args::Type::Query, CLI::Resource::String::Done, ArgumentType::Standard },\r\n        Argument{ \"arg2\", '2', Args::Type::Channel, CLI::Resource::String::Done, ArgumentType::Positional },\r\n    };\r\n    Args::Type argType = static_cast<Args::Type>(-1);\r\n    command.ArgumentValueCallback = [&](Context&, Execution::Args::Type type) { argType = type; };\r\n    command.Complete(ctc.context);\r\n\r\n    // Create expected values\r\n    std::stringstream expected;\r\n\r\n    REQUIRE(ctc.out.str() == expected.str());\r\n    REQUIRE(argType == command.Arguments[1].ExecArgType());\r\n}\r\n\r\nTEST_CASE(\"CommandComplete_ArgNamesAfterDash\", \"[complete]\")\r\n{\r\n    CompletionTestContext ctc{ \"-\", \"winget -\", \"8\" };\r\n\r\n    CompletionTestCommand command;\r\n    command.SubCommandNames = { \"car\", \"cart\", \"cartesian\", \"carpet\" };\r\n    command.Arguments = {\r\n        Argument{ \"arg1\", '1', Args::Type::Query, CLI::Resource::String::Done, ArgumentType::Standard },\r\n        Argument{ \"arg2\", '2', Args::Type::Channel, CLI::Resource::String::Done, ArgumentType::Positional },\r\n    };\r\n    command.ArgumentValueCallback = [&](Context&, Execution::Args::Type) { FAIL(\"No argument value should be requested\"); };\r\n    command.Complete(ctc.context);\r\n\r\n    // Create expected values\r\n    std::stringstream expected;\r\n    OutputAllArgumentNames(command, expected);\r\n\r\n    REQUIRE(ctc.out.str() == expected.str());\r\n}\r\n\r\nTEST_CASE(\"CommandComplete_AliasNames\", \"[complete]\")\r\n{\r\n    CompletionTestContext ctc{ \"-a\", \"winget -a\", \"9\" };\r\n\r\n    CompletionTestCommand command;\r\n    command.SubCommandNames = { \"car\", \"cart\", \"cartesian\", \"carpet\" };\r\n    command.Arguments = {\r\n        Argument{ \"arg1\", '1', Args::Type::Query, CLI::Resource::String::Done, ArgumentType::Standard },\r\n        Argument{ \"arg2\", '2', Args::Type::Channel, CLI::Resource::String::Done, ArgumentType::Positional },\r\n    };\r\n    command.ArgumentValueCallback = [&](Context&, Execution::Args::Type) { FAIL(\"No argument value should be requested\"); };\r\n    command.Complete(ctc.context);\r\n\r\n    // Create expected values\r\n    std::stringstream expected;\r\n    OutputAllArgumentAliases(command, expected);\r\n\r\n    REQUIRE(ctc.out.str() == expected.str());\r\n}\r\n\r\nTEST_CASE(\"CommandComplete_ArgNamesFilter\", \"[complete]\")\r\n{\r\n    CompletionTestContext ctc{ \"--a\", \"winget --a\", \"10\" };\r\n\r\n    CompletionTestCommand command;\r\n    command.SubCommandNames = { \"car\", \"cart\", \"cartesian\", \"carpet\" };\r\n    command.Arguments = {\r\n        Argument{ \"arg1\", '1', Args::Type::Query, CLI::Resource::String::Done, ArgumentType::Standard },\r\n        Argument{ \"arg2\", '2', Args::Type::Channel, CLI::Resource::String::Done, ArgumentType::Positional },\r\n        Argument{ \"foo1\", '2', Args::Type::Channel, CLI::Resource::String::Done, ArgumentType::Positional },\r\n    };\r\n    command.ArgumentValueCallback = [&](Context&, Execution::Args::Type) { FAIL(\"No argument value should be requested\"); };\r\n    command.Complete(ctc.context);\r\n\r\n    // Create expected values\r\n    std::stringstream expected;\r\n    OutputAllArgumentNames(command, expected, \"a\");\r\n\r\n    REQUIRE(ctc.out.str() == expected.str());\r\n}\r\n\r\nTEST_CASE(\"CommandComplete_IgnoreBadArgs\", \"[complete]\")\r\n{\r\n    CompletionTestContext ctc{ \"\", \"winget foo bar --arg1 \", \"22\" };\r\n\r\n    CompletionTestCommand command;\r\n    command.SubCommandNames = { \"car\", \"cart\", \"cartesian\", \"carpet\" };\r\n    command.Arguments = {\r\n        Argument{ \"arg1\", '1', Args::Type::Query, CLI::Resource::String::Done, ArgumentType::Standard },\r\n        Argument{ \"arg2\", '2', Args::Type::Channel, CLI::Resource::String::Done, ArgumentType::Standard },\r\n    };\r\n    Args::Type argType = static_cast<Args::Type>(-1);\r\n    command.ArgumentValueCallback = [&](Context&, Execution::Args::Type type) { argType = type; };\r\n    command.Complete(ctc.context);\r\n\r\n    // Create expected values\r\n    std::stringstream expected;\r\n\r\n    REQUIRE(ctc.out.str() == expected.str());\r\n    REQUIRE(argType == command.Arguments[0].ExecArgType());\r\n}\r\n\r\nTEST_CASE(\"CommandComplete_OtherArgsParsed\", \"[complete]\")\r\n{\r\n    CompletionTestContext ctc{ \"\", \"winget --arg1 value1  --arg2 value2\", \"21\" };\r\n\r\n    CompletionTestCommand command;\r\n    command.SubCommandNames = { \"car\", \"cart\", \"cartesian\", \"carpet\" };\r\n    command.Arguments = {\r\n        Argument{ \"arg1\", '1', Args::Type::Query, CLI::Resource::String::Done, ArgumentType::Standard },\r\n        Argument{ \"arg2\", '2', Args::Type::Channel, CLI::Resource::String::Done, ArgumentType::Standard },\r\n    };\r\n    command.ArgumentValueCallback = [&](Context&, Execution::Args::Type) { FAIL(\"No argument value should be requested\"); };\r\n    command.Complete(ctc.context);\r\n\r\n    // Create expected values\r\n    std::stringstream expected;\r\n    OutputAllArgumentNames(command, expected);\r\n\r\n    REQUIRE(ctc.out.str() == expected.str());\r\n    REQUIRE(ctc.context.Args.Contains(command.Arguments[0].ExecArgType()));\r\n    REQUIRE(ctc.context.Args.GetArg(command.Arguments[0].ExecArgType()) == \"value1\");\r\n    REQUIRE(ctc.context.Args.Contains(command.Arguments[1].ExecArgType()));\r\n    REQUIRE(ctc.context.Args.GetArg(command.Arguments[1].ExecArgType()) == \"value2\");\r\n}\r\n\r\nTEST_CASE(\"CommandComplete_Complex\", \"[complete]\")\r\n{\r\n    CompletionTestContext ctc{ \"\", \"winget foo --arg1 value1 bar junk --arg2 \", \"41\" };\r\n\r\n    CompletionTestCommand command;\r\n    command.SubCommandNames = { \"car\", \"cart\", \"cartesian\", \"carpet\" };\r\n    command.Arguments = {\r\n        Argument{ \"arg1\", '1', Args::Type::Query, CLI::Resource::String::Done, ArgumentType::Standard },\r\n        Argument{ \"arg2\", '2', Args::Type::Channel, CLI::Resource::String::Done, ArgumentType::Standard },\r\n    };\r\n    Args::Type argType = static_cast<Args::Type>(-1);\r\n    command.ArgumentValueCallback = [&](Context&, Execution::Args::Type type) { argType = type; };\r\n    command.Complete(ctc.context);\r\n\r\n    // Create expected values\r\n    std::stringstream expected;\r\n\r\n    REQUIRE(ctc.out.str() == expected.str());\r\n    REQUIRE(argType == command.Arguments[1].ExecArgType());\r\n    REQUIRE(ctc.context.Args.Contains(command.Arguments[0].ExecArgType()));\r\n    REQUIRE(ctc.context.Args.GetArg(command.Arguments[0].ExecArgType()) == \"value1\");\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/CompositeSource.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestSource.h\"\r\n#include \"TestHooks.h\"\r\n#include <CompositeSource.h>\r\n#include <Microsoft/SQLiteIndexSource.h>\r\n#include <Microsoft/PinningIndex.h>\r\n#include <PackageTrackingCatalogSourceFactory.h>\r\n#include <winget/Pin.h>\r\n#include <winget/PinningData.h>\r\n#include <winget/PackageVersionSelection.h>\r\n\r\nusing namespace std::string_literals;\r\nusing namespace std::string_view_literals;\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller;\r\nusing namespace AppInstaller::Pinning;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Repository::Microsoft;\r\nusing namespace AppInstaller::Utility;\r\n\r\nconstexpr std::string_view s_Everything_Query = \"everything\"sv;\r\n\r\n// A test source that has two modes:\r\n//  1. A request that IsForEverything returns the stored result. This models the\r\n//      incoming search request to a CompositeSource.\r\n//  2. A request that is not for everything invokes TestSource::SearchFunction to\r\n//      enable verification of expectations.\r\nstruct ComponentTestSource : public TestSource\r\n{\r\n    ComponentTestSource() = default;\r\n\r\n    ComponentTestSource(std::string_view identifier, SourceOrigin origin = SourceOrigin::Default)\r\n    {\r\n        Details.Identifier = identifier;\r\n        Details.Origin = origin;\r\n    }\r\n\r\n    SearchResult Search(const SearchRequest& request) const override\r\n    {\r\n        if (request.Query && request.Query.value().Value == s_Everything_Query)\r\n        {\r\n            return Everything;\r\n        }\r\n        else\r\n        {\r\n            return TestSource::Search(request);\r\n        }\r\n    }\r\n\r\n    SearchResult Everything;\r\n};\r\n\r\n// A helper to make matches.\r\nstruct Criteria : public PackageMatchFilter\r\n{\r\n    Criteria() : PackageMatchFilter(PackageMatchField::Id, MatchType::Wildcard, \"\"sv) {}\r\n    Criteria(PackageMatchField field) : PackageMatchFilter(field, MatchType::Wildcard, \"\"sv) {}\r\n};\r\n\r\nManifest::Manifest MakeDefaultManifest(std::string_view version = \"1.0\"sv)\r\n{\r\n    Manifest::Manifest result;\r\n\r\n    result.Id = \"Id\";\r\n    result.DefaultLocalization.Add<Manifest::Localization::PackageName>(\"Name\");\r\n    result.DefaultLocalization.Add<Manifest::Localization::Publisher>(\"Publisher\");\r\n    result.Version = version;\r\n    result.Installers.push_back({});\r\n\r\n    return result;\r\n}\r\n\r\nstruct TestManifestHelper\r\n{\r\n    TestManifestHelper() : m_manifest(MakeDefaultManifest()) {}\r\n\r\n    TestManifestHelper& WithId(const std::string& id)\r\n    {\r\n        m_manifest.Id = id;\r\n        return *this;\r\n    }\r\n\r\n    TestManifestHelper& WithVersion(std::string_view version)\r\n    {\r\n        m_manifest.Version = version;\r\n        return *this;\r\n    }\r\n\r\n    TestManifestHelper& WithChannel(const std::string& channel)\r\n    {\r\n        m_manifest.Channel = channel;\r\n        return *this;\r\n    }\r\n\r\n    TestManifestHelper& WithDefaultName(std::string_view name)\r\n    {\r\n        m_manifest.DefaultLocalization.Add<Manifest::Localization::PackageName>(std::string{ name });\r\n        return *this;\r\n    }\r\n\r\n    TestManifestHelper& WithPFN(const std::string& pfn)\r\n    {\r\n        m_manifest.Installers[0].PackageFamilyName = pfn;\r\n        return *this;\r\n    }\r\n\r\n    TestManifestHelper& WithPC(const std::string& pc)\r\n    {\r\n        m_manifest.Installers[0].ProductCode = pc;\r\n        return *this;\r\n    }\r\n\r\n    TestManifestHelper& WithType(Manifest::InstallerTypeEnum type)\r\n    {\r\n        m_manifest.Installers[0].BaseInstallerType = type;\r\n        return *this;\r\n    }\r\n\r\n    TestManifestHelper& WithDisplayVersion(std::string_view version)\r\n    {\r\n        if (m_manifest.Installers[0].AppsAndFeaturesEntries.empty())\r\n        {\r\n            m_manifest.Installers[0].AppsAndFeaturesEntries.emplace_back();\r\n        }\r\n        m_manifest.Installers[0].AppsAndFeaturesEntries[0].DisplayVersion = version;\r\n        return *this;\r\n    }\r\n\r\n    operator const Manifest::Manifest& () const\r\n    {\r\n        return m_manifest;\r\n    }\r\n\r\nprivate:\r\n    Manifest::Manifest m_manifest;\r\n};\r\n\r\nstruct TestPackageHelper\r\n{\r\n    TestPackageHelper(bool isInstalled, std::shared_ptr<ISource> source = {}) :\r\n        m_isInstalled(isInstalled), m_source(source)\r\n    {\r\n        m_manifestHelpers.emplace_back();\r\n    }\r\n\r\n    TestPackageHelper& HideSRS(bool value = true)\r\n    {\r\n        m_hideSystemReferenceStrings = value;\r\n        return *this;\r\n    }\r\n\r\n    std::shared_ptr<TestCompositePackage> ToPackage()\r\n    {\r\n        if (!m_package)\r\n        {\r\n            if (m_isInstalled)\r\n            {\r\n                m_package = TestCompositePackage::Make(this->operator const Manifest::Manifest&(), m_metadata, std::vector<Manifest::Manifest>(), m_source);\r\n            }\r\n            else\r\n            {\r\n                std::vector<Manifest::Manifest> manifests;\r\n\r\n                for (const auto& helper : m_manifestHelpers)\r\n                {\r\n                    manifests.emplace_back(helper.operator const AppInstaller::Manifest::Manifest &());\r\n                }\r\n\r\n                m_package = TestCompositePackage::Make(manifests, m_source, m_hideSystemReferenceStrings);\r\n            }\r\n        }\r\n\r\n        return m_package;\r\n    }\r\n\r\n    operator std::shared_ptr<ICompositePackage>()\r\n    {\r\n        return ToPackage();\r\n    }\r\n\r\n    TestPackageHelper& WithId(const std::string& id)\r\n    {\r\n        THROW_HR_IF(E_UNEXPECTED, m_manifestHelpers.size() != 1);\r\n        m_manifestHelpers[0].WithId(id);\r\n        return *this;\r\n    }\r\n\r\n    TestPackageHelper& WithVersion(std::string_view version)\r\n    {\r\n        THROW_HR_IF(E_UNEXPECTED, m_manifestHelpers.size() != 1);\r\n        m_manifestHelpers[0].WithVersion(version);\r\n        return *this;\r\n    }\r\n\r\n    TestPackageHelper& WithChannel(const std::string& channel)\r\n    {\r\n        THROW_HR_IF(E_UNEXPECTED, m_manifestHelpers.size() != 1);\r\n        m_manifestHelpers[0].WithChannel(channel);\r\n        return *this;\r\n    }\r\n\r\n    TestPackageHelper& WithDefaultName(std::string_view name)\r\n    {\r\n        THROW_HR_IF(E_UNEXPECTED, m_manifestHelpers.size() != 1);\r\n        m_manifestHelpers[0].WithDefaultName(name);\r\n        return *this;\r\n    }\r\n\r\n    TestPackageHelper& WithPFN(const std::string& pfn)\r\n    {\r\n        THROW_HR_IF(E_UNEXPECTED, m_manifestHelpers.size() != 1);\r\n        m_manifestHelpers[0].WithPFN(pfn);\r\n        return *this;\r\n    }\r\n\r\n    TestPackageHelper& WithPC(const std::string& pc)\r\n    {\r\n        THROW_HR_IF(E_UNEXPECTED, m_manifestHelpers.size() != 1);\r\n        m_manifestHelpers[0].WithPC(pc);\r\n        return *this;\r\n    }\r\n\r\n    TestPackageHelper& WithType(Manifest::InstallerTypeEnum type)\r\n    {\r\n        THROW_HR_IF(E_UNEXPECTED, m_manifestHelpers.size() != 1);\r\n        m_manifestHelpers[0].WithType(type);\r\n        return *this;\r\n    }\r\n\r\n    TestPackageHelper& WithDisplayVersion(std::string_view version)\r\n    {\r\n        THROW_HR_IF(E_UNEXPECTED, m_manifestHelpers.size() != 1);\r\n        m_manifestHelpers[0].WithDisplayVersion(version);\r\n        return *this;\r\n    }\r\n\r\n    TestPackageHelper& WithMetadata(PackageVersionMetadata metadata, const std::string& value)\r\n    {\r\n        THROW_HR_IF(E_UNEXPECTED, !m_isInstalled);\r\n        m_metadata[metadata] = value;\r\n        return *this;\r\n    }\r\n\r\n    operator const Manifest::Manifest& () const\r\n    {\r\n        THROW_HR_IF(E_UNEXPECTED, m_manifestHelpers.size() != 1);\r\n        return m_manifestHelpers[0];\r\n    }\r\n\r\n    TestManifestHelper& MakeManifest()\r\n    {\r\n        THROW_HR_IF(E_UNEXPECTED, m_isInstalled);\r\n        m_manifestHelpers.emplace_back();\r\n        return m_manifestHelpers.back();\r\n    }\r\n\r\nprivate:\r\n    bool m_isInstalled;\r\n    std::vector<TestManifestHelper> m_manifestHelpers;\r\n    std::shared_ptr<ISource> m_source;\r\n    std::shared_ptr<TestCompositePackage> m_package;\r\n    bool m_hideSystemReferenceStrings = false;\r\n    TestCompositePackage::MetadataMap m_metadata;\r\n};\r\n\r\n// A helper to create the sources used by the majority of tests in this file.\r\nstruct CompositeTestSetup\r\n{\r\n    CompositeTestSetup(CompositeSearchBehavior behavior = CompositeSearchBehavior::Installed) : Composite(\"*Tests\")\r\n    {\r\n        Installed = std::make_shared<ComponentTestSource>(\"InstalledTestSource1\", SourceOrigin::Predefined);\r\n        Available = std::make_shared<ComponentTestSource>(\"AvailableTestSource1\");\r\n        Composite.SetInstalledSource(Source{ Installed }, behavior);\r\n        Composite.AddAvailableSource(Source{ Available });\r\n    }\r\n\r\n    SearchResult Search(bool disableDataChecks = false)\r\n    {\r\n        size_t initialCountOfCallsRequiringVersionData = Available->CountOfCallsRequiringVersionData;\r\n        size_t initialCountOfCallsRequiringManifestData = Available->CountOfCallsRequiringManifestData;\r\n\r\n        SearchRequest request;\r\n        request.Query = RequestMatch(MatchType::Exact, s_Everything_Query);\r\n        auto result = Composite.Search(request);\r\n\r\n        // We want to prevent calls to these functions for Search as they can require network or I/O activity.\r\n        size_t countOfCallsRequiringVersionData = Available->CountOfCallsRequiringVersionData - initialCountOfCallsRequiringVersionData;\r\n        size_t countOfCallsRequiringManifestData = Available->CountOfCallsRequiringManifestData - initialCountOfCallsRequiringManifestData;\r\n        if (!disableDataChecks && (countOfCallsRequiringVersionData || countOfCallsRequiringManifestData))\r\n        {\r\n            std::ostringstream stream;\r\n            stream << \"Version data calls [\" << countOfCallsRequiringVersionData << \"] : Manifest data calls [\" << countOfCallsRequiringManifestData << \"]\";\r\n            FAIL(stream.str());\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    TestPackageHelper MakeInstalled(std::shared_ptr<ISource> source)\r\n    {\r\n        return { /* isInstalled */ true, std::move(source)};\r\n    }\r\n\r\n    TestPackageHelper MakeInstalled()\r\n    {\r\n        return MakeInstalled(Installed);\r\n    }\r\n\r\n    TestPackageHelper MakeAvailable(std::shared_ptr<ISource> source)\r\n    {\r\n        return { /* isInstalled */ false, std::move(source) };\r\n    }\r\n\r\n    TestPackageHelper MakeAvailable()\r\n    {\r\n        return MakeAvailable(Available);\r\n    }\r\n\r\n    std::shared_ptr<ComponentTestSource> Installed;\r\n    std::shared_ptr<ComponentTestSource> Available;\r\n    CompositeSource Composite;\r\n};\r\n\r\n// A helper to create the sources used by the majority of tests in this file.\r\nstruct CompositeWithTrackingTestSetup : public CompositeTestSetup\r\n{\r\n    CompositeWithTrackingTestSetup() : TrackingFactory([&](const SourceDetails&) { return Tracking; })\r\n    {\r\n        Tracking = std::make_shared<SQLiteIndexSource>(SourceDetails{}, SQLiteIndex::CreateNew(SQLITE_MEMORY_DB_CONNECTION_TARGET));\r\n        TestHook_SetSourceFactoryOverride(std::string{ PackageTrackingCatalogSourceFactory::Type() }, TrackingFactory);\r\n    }\r\n\r\n    ~CompositeWithTrackingTestSetup()\r\n    {\r\n        TestHook_ClearSourceFactoryOverrides();\r\n    }\r\n\r\n    TestSourceFactory TrackingFactory;\r\n    std::shared_ptr<SQLiteIndexSource> Tracking;\r\n};\r\n\r\nbool SearchRequestIncludes(const std::vector<PackageMatchFilter>& filters, PackageMatchField field, MatchType type, std::optional<std::string> value = {})\r\n{\r\n    bool found = false;\r\n\r\n    for (const PackageMatchFilter& filter : filters)\r\n    {\r\n        if (filter.Field == field && filter.Type == type &&\r\n            (!value || filter.Value == value.value()))\r\n        {\r\n            found = true;\r\n        }\r\n    }\r\n\r\n    return found;\r\n}\r\n\r\nvoid RequireSearchRequestIncludes(const std::vector<PackageMatchFilter>& filters, PackageMatchField field, MatchType type, std::optional<std::string> value = {})\r\n{\r\n    REQUIRE(SearchRequestIncludes(filters, field, type, value));\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_PackageFamilyName_NotAvailable\", \"[CompositeSource]\")\r\n{\r\n    // Pre-folded for easier ==\r\n    std::string pfn = \"sortof_apfn\";\r\n\r\n    CompositeTestSetup setup;\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithPFN(pfn), Criteria());\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(GetInstalledVersion(result.Matches[0].Package));\r\n    REQUIRE(result.Matches[0].Package->GetAvailable().empty());\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_PackageFamilyName_Available\", \"[CompositeSource]\")\r\n{\r\n    std::string pfn = \"sortof_apfn\";\r\n\r\n    CompositeTestSetup setup;\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithPFN(pfn), Criteria());\r\n    setup.Available->SearchFunction = [&](const SearchRequest& request)\r\n    {\r\n        RequireSearchRequestIncludes(request.Inclusions, PackageMatchField::PackageFamilyName, MatchType::Exact, pfn);\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(setup.MakeAvailable().WithPFN(pfn), Criteria());\r\n        return result;\r\n    };\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(GetInstalledVersion(result.Matches[0].Package));\r\n    REQUIRE(result.Matches[0].Package->GetAvailable().size() == 1);\r\n    REQUIRE(result.Matches[0].Package->GetAvailable()[0]->GetVersionKeys().size() == 1);\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_ProductCode_NotAvailable\", \"[CompositeSource]\")\r\n{\r\n    std::string pc = \"thiscouldbeapc\";\r\n\r\n    CompositeTestSetup setup;\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithPC(pc), Criteria());\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(GetInstalledVersion(result.Matches[0].Package));\r\n    REQUIRE(result.Matches[0].Package->GetAvailable().empty());\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_ProductCode_Available\", \"[CompositeSource]\")\r\n{\r\n    std::string pc = \"thiscouldbeapc\";\r\n\r\n    CompositeTestSetup setup;\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithPC(pc), Criteria());\r\n    setup.Available->SearchFunction = [&](const SearchRequest& request)\r\n    {\r\n        RequireSearchRequestIncludes(request.Inclusions, PackageMatchField::ProductCode, MatchType::Exact, pc);\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(setup.MakeAvailable().WithPC(pc), Criteria());\r\n        return result;\r\n    };\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(GetInstalledVersion(result.Matches[0].Package));\r\n    REQUIRE(result.Matches[0].Package->GetAvailable().size() == 1);\r\n    REQUIRE(result.Matches[0].Package->GetAvailable()[0]->GetVersionKeys().size() == 1);\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_NameAndPublisher_Match\", \"[CompositeSource]\")\r\n{\r\n    CompositeTestSetup setup;\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled(), Criteria());\r\n    setup.Available->SearchFunction = [&](const SearchRequest& request)\r\n    {\r\n        RequireSearchRequestIncludes(request.Inclusions, PackageMatchField::NormalizedNameAndPublisher, MatchType::Exact);\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(setup.MakeAvailable(), Criteria());\r\n        return result;\r\n    };\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(GetInstalledVersion(result.Matches[0].Package));\r\n    REQUIRE(result.Matches[0].Package->GetAvailable().size() == 1);\r\n    REQUIRE(result.Matches[0].Package->GetAvailable()[0]->GetVersionKeys().size() == 1);\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_MultiMatch_FindsStrongMatch\", \"[CompositeSource]\")\r\n{\r\n    std::string name = \"MatchingName\";\r\n\r\n    CompositeTestSetup setup;\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithPFN(\"sortof_apfn\"), Criteria());\r\n    setup.Available->SearchFunction = [&](const SearchRequest&)\r\n    {\r\n        SearchResult result;\r\n        result.Matches.emplace_back(setup.MakeAvailable().WithId(\"A different ID\"), Criteria(PackageMatchField::NormalizedNameAndPublisher));\r\n        result.Matches.emplace_back(setup.MakeAvailable().WithDefaultName(name), Criteria(PackageMatchField::PackageFamilyName));\r\n        return result;\r\n    };\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(GetInstalledVersion(result.Matches[0].Package));\r\n    REQUIRE(result.Matches[0].Package->GetAvailable().size() == 1);\r\n    REQUIRE(result.Matches[0].Package->GetAvailable()[0]->GetVersionKeys().size() == 1);\r\n    auto version = result.Matches[0].Package->GetAvailable()[0]->GetLatestVersion();\r\n    REQUIRE(version->GetProperty(PackageVersionProperty::Name).get() == name);\r\n    REQUIRE(!Version(version->GetProperty(PackageVersionProperty::Version)).IsUnknown());\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_MultiMatch_DoesNotFindStrongMatch\", \"[CompositeSource]\")\r\n{\r\n    CompositeTestSetup setup;\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithPFN(\"sortof_apfn\"), Criteria());\r\n    setup.Available->SearchFunction = [&](const SearchRequest&)\r\n    {\r\n        SearchResult result;\r\n        result.Matches.emplace_back(setup.MakeAvailable().WithId(\"A different ID\"), Criteria(PackageMatchField::NormalizedNameAndPublisher));\r\n        result.Matches.emplace_back(setup.MakeAvailable().WithId(\"Another diff ID\"), Criteria(PackageMatchField::NormalizedNameAndPublisher));\r\n        return result;\r\n    };\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(GetInstalledVersion(result.Matches[0].Package));\r\n    REQUIRE(result.Matches[0].Package->GetAvailable().empty());\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_FoundByBothRootSearches\", \"[CompositeSource]\")\r\n{\r\n    std::string pfn = \"sortof_apfn\";\r\n\r\n    CompositeTestSetup setup;\r\n    auto installedPackage = setup.MakeInstalled().WithPFN(pfn);\r\n    auto availablePackage = setup.MakeAvailable().WithPFN(pfn);\r\n\r\n    setup.Installed->Everything.Matches.emplace_back(installedPackage, Criteria());\r\n    setup.Installed->SearchFunction = [&](const SearchRequest& request)\r\n    {\r\n        RequireSearchRequestIncludes(request.Inclusions, PackageMatchField::PackageFamilyName, MatchType::Exact, pfn);\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(installedPackage, Criteria());\r\n        return result;\r\n    };\r\n\r\n    setup.Available->Everything.Matches.emplace_back(availablePackage, Criteria());\r\n    setup.Available->SearchFunction = [&](const SearchRequest& request)\r\n    {\r\n        RequireSearchRequestIncludes(request.Inclusions, PackageMatchField::PackageFamilyName, MatchType::Exact, pfn);\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(availablePackage, Criteria());\r\n        return result;\r\n    };\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(GetInstalledVersion(result.Matches[0].Package));\r\n    REQUIRE(result.Matches[0].Package->GetAvailable().size() == 1);\r\n    REQUIRE(result.Matches[0].Package->GetAvailable()[0]->GetVersionKeys().size() == 1);\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_OnlyAvailableFoundByRootSearch\", \"[CompositeSource]\")\r\n{\r\n    std::string pfn = \"sortof_apfn\";\r\n\r\n    CompositeTestSetup setup;\r\n    setup.Installed->SearchFunction = [&](const SearchRequest& request)\r\n    {\r\n        RequireSearchRequestIncludes(request.Inclusions, PackageMatchField::PackageFamilyName, MatchType::Exact, pfn);\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(setup.MakeInstalled().WithPFN(pfn), Criteria(PackageMatchField::PackageFamilyName));\r\n        return result;\r\n    };\r\n\r\n    std::shared_ptr<TestCompositePackage> availablePackage = setup.MakeAvailable().WithPFN(pfn).ToPackage();\r\n    setup.Available->Everything.Matches.emplace_back(availablePackage, Criteria());\r\n    setup.Available->SearchFunction = [&](const SearchRequest& request)\r\n    {\r\n        RequireSearchRequestIncludes(request.Inclusions, PackageMatchField::PackageFamilyName, MatchType::Exact, pfn);\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(availablePackage, Criteria(PackageMatchField::PackageFamilyName));\r\n        return result;\r\n    };\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(GetInstalledVersion(result.Matches[0].Package));\r\n    REQUIRE(result.Matches[0].Package->GetAvailable().size() == 1);\r\n    REQUIRE(result.Matches[0].Package->GetAvailable()[0]->GetVersionKeys().size() == 1);\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_FoundByAvailableRootSearch_NotInstalled\", \"[CompositeSource]\")\r\n{\r\n    std::string pfn = \"sortof_apfn\";\r\n\r\n    CompositeTestSetup setup;\r\n    setup.Available->Everything.Matches.emplace_back(setup.MakeAvailable().WithPFN(pfn), Criteria());\r\n    setup.Available->SearchFunction = [&](const SearchRequest& request)\r\n    {\r\n        RequireSearchRequestIncludes(request.Inclusions, PackageMatchField::PackageFamilyName, MatchType::Exact, pfn);\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(setup.MakeAvailable().WithPFN(pfn), Criteria());\r\n        return result;\r\n    };\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.empty());\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_UpdateWithBetterMatchCriteria\", \"[CompositeSource]\")\r\n{\r\n    std::string pfn = \"sortof_apfn\";\r\n    MatchType originalType = MatchType::Wildcard;\r\n    MatchType type = MatchType::Exact;\r\n\r\n    CompositeTestSetup setup;\r\n    auto installedPackage = setup.MakeInstalled().WithPFN(pfn);\r\n    auto availablePackage = setup.MakeAvailable().WithPFN(pfn);\r\n\r\n    setup.Installed->Everything.Matches.emplace_back(installedPackage, Criteria());\r\n\r\n    setup.Available->SearchFunction = [&](const SearchRequest& request)\r\n    {\r\n        RequireSearchRequestIncludes(request.Inclusions, PackageMatchField::PackageFamilyName, MatchType::Exact, pfn);\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(availablePackage, Criteria());\r\n        return result;\r\n    };\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(GetInstalledVersion(result.Matches[0].Package));\r\n    REQUIRE(result.Matches[0].Package->GetAvailable().size() == 1);\r\n    REQUIRE(result.Matches[0].Package->GetAvailable()[0]->GetVersionKeys().size() == 1);\r\n    REQUIRE(result.Matches[0].MatchCriteria.Type == originalType);\r\n\r\n    // Now make the source root search find it with a better criteria\r\n    setup.Installed->SearchFunction = [&](const SearchRequest& request)\r\n    {\r\n        RequireSearchRequestIncludes(request.Inclusions, PackageMatchField::PackageFamilyName, MatchType::Exact, pfn);\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(installedPackage, Criteria());\r\n        return result;\r\n    };\r\n\r\n    setup.Available->Everything.Matches.emplace_back(availablePackage, PackageMatchFilter(PackageMatchField::Id, type, \"\"sv));\r\n\r\n    result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(GetInstalledVersion(result.Matches[0].Package));\r\n    REQUIRE(result.Matches[0].Package->GetAvailable().size() == 1);\r\n    REQUIRE(result.Matches[0].Package->GetAvailable()[0]->GetVersionKeys().size() == 1);\r\n    REQUIRE(result.Matches[0].MatchCriteria.Type == type);\r\n}\r\n\r\nTEST_CASE(\"CompositePackage_PropertyFromInstalled\", \"[CompositeSource]\")\r\n{\r\n    std::string id = \"Special test ID\";\r\n\r\n    CompositeTestSetup setup;\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithId(id), Criteria());\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(result.Matches[0].Package->GetProperty(PackageProperty::Id) == id);\r\n}\r\n\r\nTEST_CASE(\"CompositePackage_PropertyFromAvailable\", \"[CompositeSource]\")\r\n{\r\n    std::string id = \"Special test ID\";\r\n    std::string pfn = \"sortof_apfn\";\r\n\r\n    CompositeTestSetup setup;\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithPFN(pfn), Criteria());\r\n    setup.Available->SearchFunction = [&](const SearchRequest&)\r\n    {\r\n        SearchResult result;\r\n        result.Matches.emplace_back(setup.MakeAvailable().WithId(id), Criteria());\r\n        return result;\r\n    };\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(result.Matches[0].Package->GetProperty(PackageProperty::Id) == id);\r\n}\r\n\r\nTEST_CASE(\"CompositePackage_AvailableVersions_ChannelFilteredOut\", \"[CompositeSource]\")\r\n{\r\n    std::string pfn = \"sortof_apfn\";\r\n    std::string channel = \"Channel\";\r\n\r\n    CompositeTestSetup setup;\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithPFN(pfn), Criteria());\r\n    setup.Available->SearchFunction = [&](const SearchRequest&)\r\n    {\r\n        Manifest::Manifest noChannel = MakeDefaultManifest();\r\n        noChannel.Version = \"1.0\";\r\n\r\n        Manifest::Manifest hasChannel = MakeDefaultManifest();\r\n        hasChannel.Channel = channel;\r\n        hasChannel.Version = \"2.0\";\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(TestCompositePackage::Make(std::vector<Manifest::Manifest>{ noChannel, hasChannel }, setup.Available), Criteria());\r\n        REQUIRE(result.Matches[0].Package->GetAvailable().size() == 1);\r\n        REQUIRE(result.Matches[0].Package->GetAvailable()[0]->GetVersionKeys().size() == 2);\r\n        return result;\r\n    };\r\n\r\n    // Disable data checks as we call one of the data methods as validation in the search\r\n    SearchResult result = setup.Search(true);\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(result.Matches[0].Package->GetAvailable().size() == 1);\r\n    auto package = result.Matches[0].Package->GetAvailable()[0];\r\n\r\n    auto versionKeys = package->GetVersionKeys();\r\n    REQUIRE(versionKeys.size() == 2);\r\n\r\n    auto availableVersions = GetAvailableVersionsForInstalledVersion(result.Matches[0].Package);\r\n    auto availableVersionKeys = availableVersions->GetVersionKeys();\r\n    REQUIRE(availableVersionKeys.size() == 1);\r\n    REQUIRE(availableVersionKeys[0].Channel.empty());\r\n\r\n    auto latestVersion = availableVersions->GetLatestVersion();\r\n    REQUIRE(latestVersion);\r\n    REQUIRE(latestVersion->GetProperty(PackageVersionProperty::Channel).get().empty());\r\n}\r\n\r\nTEST_CASE(\"CompositePackage_AvailableVersions_NoChannelFilteredOut\", \"[CompositeSource]\")\r\n{\r\n    std::string pfn = \"sortof_apfn\";\r\n    std::string channel = \"Channel\";\r\n\r\n    CompositeTestSetup setup;\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithPFN(pfn).WithChannel(channel), Criteria());\r\n    setup.Available->SearchFunction = [&](const SearchRequest&)\r\n    {\r\n        Manifest::Manifest noChannel = MakeDefaultManifest();\r\n        noChannel.Version = \"1.0\";\r\n\r\n        Manifest::Manifest hasChannel = MakeDefaultManifest();\r\n        hasChannel.Channel = channel;\r\n        hasChannel.Version = \"2.0\";\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(TestCompositePackage::Make(std::vector<Manifest::Manifest>{ noChannel, hasChannel }, setup.Available), Criteria());\r\n        REQUIRE(result.Matches[0].Package->GetAvailable().size() == 1);\r\n        REQUIRE(result.Matches[0].Package->GetAvailable()[0]->GetVersionKeys().size() == 2);\r\n        return result;\r\n    };\r\n\r\n    // Disable data checks as we call one of the data methods as validation in the search\r\n    SearchResult result = setup.Search(true);\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(result.Matches[0].Package->GetAvailable().size() == 1);\r\n    auto package = result.Matches[0].Package->GetAvailable()[0];\r\n\r\n    auto versionKeys = package->GetVersionKeys();\r\n    REQUIRE(versionKeys.size() == 2);\r\n\r\n    auto availableVersions = GetAvailableVersionsForInstalledVersion(result.Matches[0].Package);\r\n    auto availableVersionKeys = availableVersions->GetVersionKeys();\r\n    REQUIRE(availableVersionKeys.size() == 1);\r\n    REQUIRE(availableVersionKeys[0].Channel == channel);\r\n\r\n    auto latestVersion = availableVersions->GetLatestVersion();\r\n    REQUIRE(latestVersion);\r\n    REQUIRE(latestVersion->GetProperty(PackageVersionProperty::Channel).get() == channel);\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_MultipleAvailableSources_MatchAll\", \"[CompositeSource]\")\r\n{\r\n    TestCommon::TestUserSettings testSettings;\r\n\r\n    std::string pfn = \"sortof_apfn\";\r\n    std::string firstName = \"Name1\";\r\n    std::string secondName = \"Name2\";\r\n\r\n    CompositeTestSetup setup;\r\n    std::shared_ptr<ComponentTestSource> secondAvailable = std::make_shared<ComponentTestSource>();\r\n    setup.Composite.AddAvailableSource(Source{ secondAvailable });\r\n\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithPFN(pfn), Criteria());\r\n\r\n    setup.Available->SearchFunction = [&](const SearchRequest& request)\r\n    {\r\n        RequireSearchRequestIncludes(request.Inclusions, PackageMatchField::PackageFamilyName, MatchType::Exact, pfn);\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(setup.MakeAvailable().WithDefaultName(firstName), Criteria());\r\n        return result;\r\n    };\r\n\r\n    secondAvailable->SearchFunction = [&](const SearchRequest& request)\r\n    {\r\n        RequireSearchRequestIncludes(request.Inclusions, PackageMatchField::PackageFamilyName, MatchType::Exact, pfn);\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(setup.MakeAvailable(secondAvailable).WithDefaultName(secondName), Criteria());\r\n        return result;\r\n    };\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(GetInstalledVersion(result.Matches[0].Package));\r\n    REQUIRE(result.Matches[0].Package->GetAvailable().size() == 2);\r\n    REQUIRE(result.Matches[0].Package->GetAvailable()[0]->GetProperty(PackageProperty::Name).get() == firstName);\r\n    REQUIRE(result.Matches[0].Package->GetAvailable()[1]->GetProperty(PackageProperty::Name).get() == secondName);\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_MultipleAvailableSources_MatchSecond\", \"[CompositeSource]\")\r\n{\r\n    std::string pfn = \"sortof_apfn\";\r\n    std::string firstName = \"Name1\";\r\n    std::string secondName = \"Name2\";\r\n\r\n    CompositeTestSetup setup;\r\n    std::shared_ptr<ComponentTestSource> secondAvailable = std::make_shared<ComponentTestSource>();\r\n    setup.Composite.AddAvailableSource(Source{ secondAvailable });\r\n\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithPFN(pfn), Criteria());\r\n\r\n    secondAvailable->SearchFunction = [&](const SearchRequest& request)\r\n    {\r\n        RequireSearchRequestIncludes(request.Inclusions, PackageMatchField::PackageFamilyName, MatchType::Exact, pfn);\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(setup.MakeAvailable().WithDefaultName(secondName), Criteria());\r\n        return result;\r\n    };\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(GetInstalledVersion(result.Matches[0].Package));\r\n    REQUIRE(result.Matches[0].Package->GetAvailable().size() == 1);\r\n    REQUIRE(result.Matches[0].Package->GetAvailable()[0]->GetProperty(PackageProperty::Name).get() == secondName);\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_MultipleAvailableSources_ReverseMatchBoth\", \"[CompositeSource]\")\r\n{\r\n    std::string pfn = \"sortof_apfn\";\r\n\r\n    CompositeTestSetup setup;\r\n    auto installedPackage = setup.MakeInstalled().WithPFN(pfn);\r\n\r\n    std::shared_ptr<ComponentTestSource> secondAvailable = std::make_shared<ComponentTestSource>();\r\n    setup.Composite.AddAvailableSource(Source{ secondAvailable });\r\n\r\n    setup.Installed->SearchFunction = [&](const SearchRequest& request)\r\n    {\r\n        RequireSearchRequestIncludes(request.Inclusions, PackageMatchField::PackageFamilyName, MatchType::Exact, pfn);\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(installedPackage, Criteria(PackageMatchField::PackageFamilyName));\r\n        return result;\r\n    };\r\n\r\n    setup.Available->Everything.Matches.emplace_back(setup.MakeAvailable().WithPFN(pfn), Criteria());\r\n    secondAvailable->Everything.Matches.emplace_back(setup.MakeAvailable().WithPFN(pfn), Criteria());\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(GetInstalledVersion(result.Matches[0].Package));\r\n    REQUIRE(result.Matches[0].Package->GetAvailable().size() == 2);\r\n    REQUIRE(result.Matches[0].Package->GetAvailable()[0]->GetVersionKeys().size() == 1);\r\n    REQUIRE(result.Matches[0].Package->GetAvailable()[1]->GetVersionKeys().size() == 1);\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_IsSame\", \"[CompositeSource]\")\r\n{\r\n    CompositeTestSetup setup;\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithPFN(\"sortof_apfn\"), Criteria());\r\n\r\n    SearchResult result1 = setup.Search();\r\n    REQUIRE(result1.Matches.size() == 1);\r\n\r\n    SearchResult result2 = setup.Search();\r\n    REQUIRE(result2.Matches.size() == 1);\r\n\r\n    REQUIRE(result1.Matches[0].Package->GetInstalled());\r\n    REQUIRE(result1.Matches[0].Package->GetInstalled()->IsSame(result1.Matches[0].Package->GetInstalled().get()));\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_AvailableSearchFailure\", \"[CompositeSource]\")\r\n{\r\n    HRESULT expectedHR = E_BLUETOOTH_ATT_ATTRIBUTE_NOT_FOUND;\r\n    std::string pfn = \"sortof_apfn\";\r\n\r\n    std::shared_ptr<ComponentTestSource> AvailableSucceeds = std::make_shared<ComponentTestSource>();\r\n    AvailableSucceeds->SearchFunction = [&](const SearchRequest&)\r\n    {\r\n        SearchResult result;\r\n        result.Matches.emplace_back(TestPackageHelper{ /* isInstalled */ false }.WithPFN(pfn), Criteria());\r\n        return result;\r\n    };\r\n\r\n    std::shared_ptr<ComponentTestSource> AvailableFails = std::make_shared<ComponentTestSource>();\r\n    AvailableFails->SearchFunction = [&](const SearchRequest&) -> SearchResult { THROW_HR(expectedHR); };\r\n    AvailableFails->Details.Name = \"The one that fails\";\r\n\r\n    CompositeSource Composite(\"*CompositeSource_AvailableSearchFailure\");\r\n    Composite.AddAvailableSource(Source{ AvailableSucceeds });\r\n    Composite.AddAvailableSource(Source{ AvailableFails });\r\n\r\n    SearchResult result = Composite.Search({});\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(result.Matches[0].Package->GetAvailable().size() == 1);\r\n\r\n    auto pfns = result.Matches[0].Package->GetAvailable()[0]->GetLatestVersion()->GetMultiProperty(PackageVersionMultiProperty::PackageFamilyName);\r\n    REQUIRE(pfns.size() == 1);\r\n    REQUIRE(pfns[0] == pfn);\r\n\r\n    REQUIRE(result.Failures.size() == 1);\r\n    REQUIRE(result.Failures[0].SourceName == AvailableFails->Details.Name);\r\n\r\n    HRESULT searchFailure = S_OK;\r\n    try\r\n    {\r\n        std::rethrow_exception(result.Failures[0].Exception);\r\n    }\r\n    catch (const wil::ResultException& re)\r\n    {\r\n        searchFailure = re.GetErrorCode();\r\n    }\r\n    catch (...) {}\r\n\r\n    REQUIRE(searchFailure == expectedHR);\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_InstalledToAvailableCorrelationSearchFailure\", \"[CompositeSource]\")\r\n{\r\n    HRESULT expectedHR = E_BLUETOOTH_ATT_ATTRIBUTE_NOT_LONG;\r\n    std::string pfn = \"sortof_apfn\";\r\n\r\n    CompositeTestSetup setup;\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithPFN(pfn), Criteria());\r\n    setup.Available->Everything.Matches.emplace_back(setup.MakeAvailable().WithPFN(pfn), Criteria());\r\n\r\n    std::shared_ptr<ComponentTestSource> AvailableFails = std::make_shared<ComponentTestSource>();\r\n    AvailableFails->SearchFunction = [&](const SearchRequest&) -> SearchResult { THROW_HR(expectedHR); };\r\n    AvailableFails->Details.Name = \"The one that fails\";\r\n\r\n    setup.Composite.AddAvailableSource(Source{ AvailableFails });\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n\r\n    REQUIRE(result.Failures.size() == 1);\r\n    REQUIRE(result.Failures[0].SourceName == AvailableFails->Details.Name);\r\n\r\n    HRESULT searchFailure = S_OK;\r\n    try\r\n    {\r\n        std::rethrow_exception(result.Failures[0].Exception);\r\n    }\r\n    catch (const wil::ResultException& re)\r\n    {\r\n        searchFailure = re.GetErrorCode();\r\n    }\r\n    catch (...) {}\r\n\r\n    REQUIRE(searchFailure == expectedHR);\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_InstalledAvailableSearchFailure\", \"[CompositeSource]\")\r\n{\r\n    HRESULT expectedHR = E_BLUETOOTH_ATT_ATTRIBUTE_NOT_LONG;\r\n    std::string pfn = \"sortof_apfn\";\r\n\r\n    CompositeTestSetup setup;\r\n    setup.Available->SearchFunction = [&](const SearchRequest&)\r\n    {\r\n        SearchResult result;\r\n        result.Matches.emplace_back(setup.MakeAvailable().WithPFN(pfn), Criteria());\r\n        return result;\r\n    };\r\n\r\n    std::shared_ptr<ComponentTestSource> AvailableFails = std::make_shared<ComponentTestSource>();\r\n    AvailableFails->SearchFunction = [&](const SearchRequest&) -> SearchResult { THROW_HR(expectedHR); };\r\n    AvailableFails->Details.Name = \"The one that fails\";\r\n\r\n    setup.Composite.AddAvailableSource(Source{ AvailableFails });\r\n\r\n    setup.Composite.SetInstalledSource(Source{ setup.Installed }, CompositeSearchBehavior::AvailablePackages);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch{ MatchType::Exact, \"whatever\" };\r\n    SearchResult result = setup.Composite.Search(request);\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n\r\n    REQUIRE(result.Failures.size() == 1);\r\n    REQUIRE(result.Failures[0].SourceName == AvailableFails->Details.Name);\r\n\r\n    HRESULT searchFailure = S_OK;\r\n    try\r\n    {\r\n        std::rethrow_exception(result.Failures[0].Exception);\r\n    }\r\n    catch (const wil::ResultException& re)\r\n    {\r\n        searchFailure = re.GetErrorCode();\r\n    }\r\n    catch (...) {}\r\n\r\n    REQUIRE(searchFailure == expectedHR);\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_TrackingPackageFound\", \"[CompositeSource]\")\r\n{\r\n    std::string availableID = \"Available.ID\";\r\n    std::string pfn = \"sortof_apfn\";\r\n\r\n    CompositeWithTrackingTestSetup setup;\r\n    auto installedPackage = setup.MakeInstalled().WithPFN(pfn);\r\n    auto availablePackage = setup.MakeAvailable().WithPFN(pfn).WithId(availableID).WithDefaultName(s_Everything_Query);\r\n\r\n    setup.Installed->Everything.Matches.emplace_back(installedPackage, Criteria());\r\n    setup.Installed->SearchFunction = [&](const SearchRequest& request)\r\n    {\r\n        RequireSearchRequestIncludes(request.Inclusions, PackageMatchField::PackageFamilyName, MatchType::Exact, pfn);\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(installedPackage, Criteria());\r\n        return result;\r\n    };\r\n\r\n    setup.Available->Everything.Matches.emplace_back(availablePackage, Criteria());\r\n    setup.Available->SearchFunction = [&](const SearchRequest& request)\r\n    {\r\n        if (request.Filters.empty())\r\n        {\r\n            RequireSearchRequestIncludes(request.Inclusions, PackageMatchField::PackageFamilyName, MatchType::Exact, pfn);\r\n        }\r\n        else\r\n        {\r\n            REQUIRE(request.Filters.size() == 1);\r\n            RequireSearchRequestIncludes(request.Filters, PackageMatchField::Id, MatchType::CaseInsensitive, availableID);\r\n        }\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(availablePackage, Criteria());\r\n        return result;\r\n    };\r\n\r\n    setup.Tracking->GetIndex().AddManifest(availablePackage);\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(result.Matches[0].Package);\r\n    REQUIRE(GetInstalledVersion(result.Matches[0].Package));\r\n    REQUIRE(result.Matches[0].Package->GetInstalled()->GetSource().GetIdentifier() == setup.Available->Details.Identifier);\r\n    REQUIRE(GetInstalledVersion(result.Matches[0].Package)->GetSource().GetIdentifier() == setup.Available->Details.Identifier);\r\n    REQUIRE(result.Matches[0].Package->GetAvailable().size() == 1);\r\n    REQUIRE(result.Matches[0].Package->GetAvailable()[0]->GetLatestVersion());\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_TrackingPackageFound_MetadataPopulatedFromTracking\", \"[CompositeSource]\")\r\n{\r\n    std::string availableID = \"Available.ID\";\r\n    std::string pfn = \"sortof_apfn\";\r\n\r\n    CompositeWithTrackingTestSetup setup;\r\n    auto installedPackage = setup.MakeInstalled().WithPFN(pfn);\r\n    auto availablePackage = setup.MakeAvailable().WithPFN(pfn).WithId(availableID).WithDefaultName(s_Everything_Query);\r\n\r\n    setup.Installed->Everything.Matches.emplace_back(installedPackage, Criteria());\r\n    setup.Installed->SearchFunction = [&](const SearchRequest& request)\r\n    {\r\n        RequireSearchRequestIncludes(request.Inclusions, PackageMatchField::PackageFamilyName, MatchType::Exact, pfn);\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(installedPackage, Criteria());\r\n        return result;\r\n    };\r\n\r\n    setup.Available->Everything.Matches.emplace_back(availablePackage, Criteria());\r\n    setup.Available->SearchFunction = [&](const SearchRequest& request)\r\n    {\r\n        if (request.Filters.empty())\r\n        {\r\n            RequireSearchRequestIncludes(request.Inclusions, PackageMatchField::PackageFamilyName, MatchType::Exact, pfn);\r\n        }\r\n        else\r\n        {\r\n            REQUIRE(request.Filters.size() == 1);\r\n            RequireSearchRequestIncludes(request.Filters, PackageMatchField::Id, MatchType::CaseInsensitive, availableID);\r\n        }\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(availablePackage, Criteria());\r\n        return result;\r\n    };\r\n\r\n    auto manifestId = setup.Tracking->GetIndex().AddManifest(availablePackage);\r\n\r\n    // Add test PackageVersionMetadata to be populated to InstalledVersion metadata\r\n    setup.Tracking->GetIndex().SetMetadataByManifestId(manifestId, Repository::PackageVersionMetadata::TrackingWriteTime, \"100\");\r\n    setup.Tracking->GetIndex().SetMetadataByManifestId(manifestId, Repository::PackageVersionMetadata::UserIntentArchitecture, \"X86\");\r\n    setup.Tracking->GetIndex().SetMetadataByManifestId(manifestId, Repository::PackageVersionMetadata::UserIntentLocale, \"en-US\");\r\n    setup.Tracking->GetIndex().SetMetadataByManifestId(manifestId, Repository::PackageVersionMetadata::InstalledArchitecture, \"X86\");\r\n    setup.Tracking->GetIndex().SetMetadataByManifestId(manifestId, Repository::PackageVersionMetadata::InstalledLocale, \"en-US\");\r\n    setup.Tracking->GetIndex().SetMetadataByManifestId(manifestId, Repository::PackageVersionMetadata::PinnedState, \"PinnedByManifest\");\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(result.Matches[0].Package);\r\n    REQUIRE(GetInstalledVersion(result.Matches[0].Package));\r\n\r\n    auto metadata = GetInstalledVersion(result.Matches[0].Package)->GetMetadata();\r\n    REQUIRE(metadata[Repository::PackageVersionMetadata::UserIntentArchitecture] == \"X86\");\r\n    REQUIRE(metadata[Repository::PackageVersionMetadata::UserIntentLocale] == \"en-US\");\r\n    REQUIRE(metadata[Repository::PackageVersionMetadata::InstalledArchitecture] == \"X86\");\r\n    REQUIRE(metadata[Repository::PackageVersionMetadata::InstalledLocale] == \"en-US\");\r\n    REQUIRE(metadata[Repository::PackageVersionMetadata::PinnedState] == \"PinnedByManifest\");\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_TrackingFound_AvailableNot\", \"[CompositeSource]\")\r\n{\r\n    std::string availableID = \"Available.ID\";\r\n    std::string pfn = \"sortof_apfn\";\r\n\r\n    CompositeWithTrackingTestSetup setup;\r\n    auto installedPackage = setup.MakeInstalled().WithPFN(pfn);\r\n    auto availablePackage = setup.MakeAvailable().WithPFN(pfn).WithId(availableID).WithDefaultName(s_Everything_Query);\r\n\r\n    setup.Installed->Everything.Matches.emplace_back(installedPackage, Criteria());\r\n    setup.Installed->SearchFunction = [&](const SearchRequest& request)\r\n    {\r\n        RequireSearchRequestIncludes(request.Inclusions, PackageMatchField::PackageFamilyName, MatchType::Exact, pfn);\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(installedPackage, Criteria());\r\n        return result;\r\n    };\r\n\r\n    setup.Tracking->GetIndex().AddManifest(availablePackage);\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(result.Matches[0].Package);\r\n    REQUIRE(GetInstalledVersion(result.Matches[0].Package));\r\n    REQUIRE(result.Matches[0].Package->GetInstalled()->GetSource().GetIdentifier() == setup.Available->Details.Identifier);\r\n    REQUIRE(GetInstalledVersion(result.Matches[0].Package)->GetSource().GetIdentifier() == setup.Available->Details.Identifier);\r\n    REQUIRE(result.Matches[0].Package->GetAvailable().empty());\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_TrackingFound_AvailablePath\", \"[CompositeSource]\")\r\n{\r\n    CompositeWithTrackingTestSetup setup;\r\n\r\n    std::string availableID = \"Available.ID\";\r\n    std::string pfn = \"sortof_apfn\";\r\n\r\n    auto installedPackage = setup.MakeInstalled().WithPFN(pfn);\r\n    auto availablePackage = setup.MakeAvailable().WithPFN(pfn).WithId(availableID).WithDefaultName(s_Everything_Query);\r\n\r\n    setup.Installed->SearchFunction = [&](const SearchRequest& request)\r\n    {\r\n        RequireSearchRequestIncludes(request.Inclusions, PackageMatchField::PackageFamilyName, MatchType::Exact, pfn);\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(installedPackage, Criteria(PackageMatchField::PackageFamilyName));\r\n        return result;\r\n    };\r\n\r\n    setup.Available->Everything.Matches.emplace_back(availablePackage, Criteria());\r\n    setup.Available->SearchFunction = [&](const SearchRequest& request)\r\n    {\r\n        REQUIRE(request.Filters.size() == 1);\r\n        RequireSearchRequestIncludes(request.Filters, PackageMatchField::Id, MatchType::CaseInsensitive, availableID);\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(availablePackage, Criteria());\r\n        return result;\r\n    };\r\n\r\n    setup.Tracking->GetIndex().AddManifest(availablePackage);\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(result.Matches[0].Package);\r\n    REQUIRE(GetInstalledVersion(result.Matches[0].Package));\r\n    REQUIRE(result.Matches[0].Package->GetInstalled()->GetSource().GetIdentifier() == setup.Available->Details.Identifier);\r\n    REQUIRE(GetInstalledVersion(result.Matches[0].Package)->GetSource().GetIdentifier() == setup.Available->Details.Identifier);\r\n    REQUIRE(result.Matches[0].Package->GetAvailable().size() == 1);\r\n    REQUIRE(result.Matches[0].Package->GetAvailable()[0]->GetLatestVersion());\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_TrackingFound_NotInstalled\", \"[CompositeSource]\")\r\n{\r\n    std::string availableID = \"Available.ID\";\r\n    std::string pfn = \"sortof_apfn\";\r\n\r\n    CompositeWithTrackingTestSetup setup;\r\n    auto installedPackage = setup.MakeInstalled().WithPFN(pfn);\r\n    auto availablePackage = setup.MakeAvailable().WithPFN(pfn).WithId(availableID).WithDefaultName(s_Everything_Query);\r\n\r\n    setup.Available->Everything.Matches.emplace_back(availablePackage, Criteria());\r\n\r\n    setup.Tracking->GetIndex().AddManifest(availablePackage);\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.empty());\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_NullInstalledVersion\", \"[CompositeSource]\")\r\n{\r\n    CompositeTestSetup setup;\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeAvailable(), Criteria());\r\n\r\n    // We are mostly testing to see if a null installed version causes an AV or not\r\n    SearchResult result = setup.Search();\r\n    REQUIRE(result.Matches.size() == 0);\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_NullAvailableVersion\", \"[CompositeSource]\")\r\n{\r\n    CompositeTestSetup setup{ CompositeSearchBehavior::AvailablePackages };\r\n    setup.Available->Everything.Matches.emplace_back(setup.MakeInstalled(), Criteria());\r\n\r\n    // We are mostly testing to see if a null available version causes an AV or not\r\n    REQUIRE_THROWS_HR(setup.Search(), E_UNEXPECTED);\r\n}\r\n\r\nstruct ExpectedResultForPinBehavior\r\n{\r\n    ExpectedResultForPinBehavior(bool isUpdateAvailable, std::optional<std::string> latestAvailableVersion)\r\n        : IsUpdateAvailable(isUpdateAvailable), LatestAvailableVersion(latestAvailableVersion) {}\r\n    ExpectedResultForPinBehavior() {}\r\n\r\n    bool IsUpdateAvailable = false;\r\n    std::optional<std::string> LatestAvailableVersion;\r\n};\r\n\r\nstruct ExpectedPackageVersionKey : public PackageVersionKey\r\n{\r\n    ExpectedPackageVersionKey(Utility::NormalizedString sourceId, Utility::NormalizedString version, Utility::NormalizedString channel, PinType pinType) :\r\n        PackageVersionKey(sourceId, version, channel), PinnedState(pinType) {}\r\n\r\n    PinType PinnedState;\r\n};\r\n\r\nstruct ExpectedResultsForPinning\r\n{\r\n    std::map<PinBehavior, ExpectedResultForPinBehavior> ResultsForPinBehavior;\r\n    std::vector<ExpectedPackageVersionKey> AvailableVersions;\r\n};\r\n\r\nvoid RequireExpectedResultsWithPin(std::shared_ptr<ICompositePackage> package, const ExpectedResultsForPinning& expectedResult, std::shared_ptr<IPackageVersion> packageVersion = {})\r\n{\r\n    PinningData pinningData{ PinningData::Disposition::ReadOnly };\r\n    auto availableVersions = GetAvailableVersionsForInstalledVersion(package);\r\n\r\n    if (!packageVersion)\r\n    {\r\n        packageVersion = GetInstalledVersion(package);\r\n    }\r\n\r\n    for (const auto& entry : expectedResult.ResultsForPinBehavior)\r\n    {\r\n        auto pinBehavior = entry.first;\r\n        const auto& result = entry.second;\r\n\r\n        auto evaluator = pinningData.CreatePinStateEvaluator(pinBehavior, packageVersion);\r\n        auto latestAvailable = evaluator.GetLatestAvailableVersionForPins(availableVersions);\r\n\r\n        REQUIRE(evaluator.IsUpdate(latestAvailable) == result.IsUpdateAvailable);\r\n\r\n        if (result.LatestAvailableVersion.has_value())\r\n        {\r\n            REQUIRE(latestAvailable);\r\n            REQUIRE(latestAvailable->GetManifest().Version == result.LatestAvailableVersion.value());\r\n        }\r\n        else\r\n        {\r\n            REQUIRE(!latestAvailable);\r\n        }\r\n    }\r\n\r\n    auto availableVersionKeys = availableVersions->GetVersionKeys();\r\n    REQUIRE(availableVersionKeys.size() == expectedResult.AvailableVersions.size());\r\n    for (size_t i = 0; i < availableVersionKeys.size(); ++i)\r\n    {\r\n        auto evaluator = pinningData.CreatePinStateEvaluator(PinBehavior::ConsiderPins, packageVersion);\r\n\r\n        auto availableVersion = availableVersions->GetVersion(expectedResult.AvailableVersions[i]);\r\n        REQUIRE(availableVersion);\r\n        REQUIRE(availableVersionKeys[i].SourceId == expectedResult.AvailableVersions[i].SourceId);\r\n        REQUIRE(availableVersionKeys[i].Version == expectedResult.AvailableVersions[i].Version);\r\n        REQUIRE(evaluator.EvaluatePinType(availableVersion) == expectedResult.AvailableVersions[i].PinnedState);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_Pinning_AvailableVersionPinned\", \"[CompositeSource][PinFlow]\")\r\n{\r\n    // We use an installed package that has 3 available versions: v1.0.0, v1.0.1 and v1.1.0.\r\n    // Installed is v1.0.1\r\n    // We then test the 4 possible pin states (unpinned, Pinned, Blocked, Gated)\r\n    // with the 3 possible pin search behaviors (ignore, consider, include pinned)\r\n    TempFile indexFile(\"pinningIndex\", \".db\");\r\n    TestHook::SetPinningIndex_Override pinningIndexOverride(indexFile.GetPath());\r\n\r\n    TestUserSettings userSettings;\r\n    CompositeTestSetup setup;\r\n\r\n    auto installedPackage = setup.MakeInstalled().WithVersion(\"1.0.1\"sv);\r\n    setup.Installed->Everything.Matches.emplace_back(installedPackage, Criteria());\r\n\r\n    setup.Available->SearchFunction = [&](const SearchRequest&)\r\n    {\r\n        auto manifest1 = MakeDefaultManifest(\"1.0.0\"sv);\r\n        auto manifest2 = MakeDefaultManifest(\"1.0.1\"sv);\r\n        auto manifest3 = MakeDefaultManifest(\"1.1.0\"sv);\r\n        auto package = TestCompositePackage::Make(\r\n            std::vector<Manifest::Manifest>{ manifest3, manifest2, manifest1 },\r\n            setup.Available);\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(package, Criteria());\r\n        return result;\r\n    };\r\n\r\n    ExpectedResultsForPinning expectedResult;\r\n    // The result when ignoring pins is always the same\r\n    expectedResult.ResultsForPinBehavior[PinBehavior::IgnorePins] = { /* IsUpdateAvailable */ true, /* LatestAvailableVersion */ \"1.1.0\" };\r\n\r\n    PinKey pinKey(\"Id\", setup.Available->Details.Identifier);\r\n    auto pinningIndex = PinningIndex::OpenOrCreateDefault();\r\n    REQUIRE(pinningIndex);\r\n\r\n    SECTION(\"Unpinned\")\r\n    {\r\n        // If there are no pins, the result should not change if we consider them\r\n        expectedResult.ResultsForPinBehavior[PinBehavior::ConsiderPins] = expectedResult.ResultsForPinBehavior[PinBehavior::IgnorePins];\r\n        expectedResult.ResultsForPinBehavior[PinBehavior::IncludePinned] = expectedResult.ResultsForPinBehavior[PinBehavior::IgnorePins];\r\n        expectedResult.AvailableVersions = {\r\n            { \"AvailableTestSource1\", \"1.1.0\", \"\", Pinning::PinType::Unknown },\r\n            { \"AvailableTestSource1\", \"1.0.1\", \"\", Pinning::PinType::Unknown },\r\n            { \"AvailableTestSource1\", \"1.0.0\", \"\", Pinning::PinType::Unknown },\r\n        };\r\n    }\r\n    SECTION(\"Pinned\")\r\n    {\r\n        pinningIndex->AddPin(Pin::CreatePinningPin(PinKey{ pinKey }));\r\n\r\n        // Pinning pins are ignored with --include-pinned\r\n        expectedResult.ResultsForPinBehavior[PinBehavior::IncludePinned] = expectedResult.ResultsForPinBehavior[PinBehavior::IgnorePins];\r\n\r\n        expectedResult.ResultsForPinBehavior[PinBehavior::ConsiderPins] = { /* IsUpdateAvailable */ false, /* LatestAvailableVersion */ {} };\r\n        expectedResult.AvailableVersions = {\r\n            { \"AvailableTestSource1\", \"1.1.0\", \"\", Pinning::PinType::Pinning },\r\n            { \"AvailableTestSource1\", \"1.0.1\", \"\", Pinning::PinType::Pinning },\r\n            { \"AvailableTestSource1\", \"1.0.0\", \"\", Pinning::PinType::Pinning },\r\n        };\r\n    }\r\n    SECTION(\"Blocked\")\r\n    {\r\n        pinningIndex->AddPin(Pin::CreateBlockingPin(PinKey{ pinKey }));\r\n        expectedResult.ResultsForPinBehavior[PinBehavior::ConsiderPins] = { /* IsUpdateAvailable */ false, /* LatestAvailableVersion */ {} };\r\n\r\n        // Blocking pins are not affected by --include-pinned\r\n        expectedResult.ResultsForPinBehavior[PinBehavior::IncludePinned] = expectedResult.ResultsForPinBehavior[PinBehavior::ConsiderPins];\r\n\r\n        expectedResult.AvailableVersions = {\r\n            { \"AvailableTestSource1\", \"1.1.0\", \"\", Pinning::PinType::Blocking },\r\n            { \"AvailableTestSource1\", \"1.0.1\", \"\", Pinning::PinType::Blocking },\r\n            { \"AvailableTestSource1\", \"1.0.0\", \"\", Pinning::PinType::Blocking },\r\n        };\r\n    }\r\n    SECTION(\"Gated to 1.*\")\r\n    {\r\n        pinningIndex->AddPin(Pin::CreateGatingPin(PinKey{ pinKey }, GatedVersion{ \"1.*\"sv }));\r\n        expectedResult.ResultsForPinBehavior[PinBehavior::ConsiderPins] = { /* IsUpdateAvailable */ true, /* LatestAvailableVersion */ \"1.1.0\" };\r\n\r\n        // Gating pins are not affected by --include-pinned\r\n        expectedResult.ResultsForPinBehavior[PinBehavior::IncludePinned] = expectedResult.ResultsForPinBehavior[PinBehavior::ConsiderPins];\r\n\r\n        expectedResult.AvailableVersions = {\r\n            { \"AvailableTestSource1\", \"1.1.0\", \"\", Pinning::PinType::Unknown },\r\n            { \"AvailableTestSource1\", \"1.0.1\", \"\", Pinning::PinType::Unknown },\r\n            { \"AvailableTestSource1\", \"1.0.0\", \"\", Pinning::PinType::Unknown },\r\n        };\r\n    }\r\n    SECTION(\"Gated to 1.0.*\")\r\n    {\r\n        pinningIndex->AddPin(Pin::CreateGatingPin(PinKey{ pinKey }, GatedVersion{ \"1.0.*\"sv }));\r\n        expectedResult.ResultsForPinBehavior[PinBehavior::ConsiderPins] = { /* IsUpdateAvailable */ false, /* LatestAvailableVersion */ \"1.0.1\" };\r\n\r\n        // Gating pins are not affected by --include-pinned\r\n        expectedResult.ResultsForPinBehavior[PinBehavior::IncludePinned] = expectedResult.ResultsForPinBehavior[PinBehavior::ConsiderPins];\r\n\r\n        expectedResult.AvailableVersions = {\r\n            { \"AvailableTestSource1\", \"1.1.0\", \"\", Pinning::PinType::Gating },\r\n            { \"AvailableTestSource1\", \"1.0.1\", \"\", Pinning::PinType::Unknown },\r\n            { \"AvailableTestSource1\", \"1.0.0\", \"\", Pinning::PinType::Unknown },\r\n        };\r\n    }\r\n\r\n    SearchResult result = setup.Search();\r\n    REQUIRE(result.Matches.size() == 1);\r\n    auto package = result.Matches[0].Package;\r\n    REQUIRE(package);\r\n\r\n    RequireExpectedResultsWithPin(package, expectedResult);\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_Pinning_OneSourcePinned\", \"[CompositeSource][PinFlow]\")\r\n{\r\n    // We use an installed package that has 2 available sources.\r\n    // If one of them is pinned, we should still get the updates from the other one.\r\n    TempFile indexFile(\"pinningIndex\", \".db\");\r\n    TestHook::SetPinningIndex_Override pinningIndexOverride(indexFile.GetPath());\r\n\r\n    TestUserSettings userSettings;\r\n    CompositeTestSetup setup;\r\n\r\n    auto installedPackage = setup.MakeInstalled().WithVersion(\"1.0\"sv);\r\n    setup.Installed->Everything.Matches.emplace_back(installedPackage, Criteria());\r\n\r\n    setup.Available->SearchFunction = [&](const SearchRequest&)\r\n    {\r\n        auto package = TestCompositePackage::Make(std::vector<Manifest::Manifest>{ MakeDefaultManifest(\"2.0\"sv) }, setup.Available);\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(package, Criteria());\r\n        return result;\r\n    };\r\n\r\n    std::shared_ptr<ComponentTestSource> secondAvailable = std::make_shared<ComponentTestSource>(\"SecondTestSource\");\r\n    setup.Composite.AddAvailableSource(Source{ secondAvailable });\r\n    secondAvailable->SearchFunction = [&](const SearchRequest&)\r\n    {\r\n        auto package = TestCompositePackage::Make(std::vector<Manifest::Manifest>{ MakeDefaultManifest(\"1.1\"sv) }, secondAvailable);\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(package, Criteria());\r\n        return result;\r\n    };\r\n\r\n    {\r\n        PinKey pinKey(\"Id\", setup.Available->Details.Identifier);\r\n        auto pinningIndex = PinningIndex::OpenOrCreateDefault();\r\n        REQUIRE(pinningIndex);\r\n        pinningIndex->AddPin(Pin::CreatePinningPin(PinKey{ pinKey }));\r\n    }\r\n\r\n    ExpectedResultsForPinning expectedResult;\r\n    expectedResult.ResultsForPinBehavior[PinBehavior::IgnorePins] = { /* IsUpdateAvailable */ true, /* LatestAvailableVersion */ \"2.0\" };\r\n    expectedResult.ResultsForPinBehavior[PinBehavior::ConsiderPins] = { /* IsUpdateAvailable */ true, /* LatestAvailableVersion */ \"1.1\" };\r\n    expectedResult.ResultsForPinBehavior[PinBehavior::IncludePinned] = { /* IsUpdateAvailable */ true, /* LatestAvailableVersion */ \"2.0\" };\r\n    expectedResult.AvailableVersions = {\r\n        { \"AvailableTestSource1\", \"2.0\", \"\", Pinning::PinType::Pinning },\r\n        { \"SecondTestSource\", \"1.1\", \"\", Pinning::PinType::Unknown },\r\n    };\r\n\r\n    SearchResult result = setup.Search();\r\n    REQUIRE(result.Matches.size() == 1);\r\n    auto package = result.Matches[0].Package;\r\n    REQUIRE(package);\r\n    RequireExpectedResultsWithPin(package, expectedResult);\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_Pinning_OneSourceGated\", \"[CompositeSource][PinFlow]\")\r\n{\r\n    // We use an installed package that has 2 available sources.\r\n    // If one of them has a gating pin, we should still get the updates from it\r\n    TempFile indexFile(\"pinningIndex\", \".db\");\r\n    TestHook::SetPinningIndex_Override pinningIndexOverride(indexFile.GetPath());\r\n\r\n    TestUserSettings userSettings;\r\n    CompositeTestSetup setup;\r\n\r\n    auto installedPackage = setup.MakeInstalled().WithVersion(\"1.0.1\"sv);\r\n    setup.Installed->Everything.Matches.emplace_back(installedPackage, Criteria());\r\n\r\n    setup.Available->SearchFunction = [&](const SearchRequest&)\r\n    {\r\n        auto package = TestCompositePackage::Make(\r\n            std::vector<Manifest::Manifest>{\r\n                MakeDefaultManifest(\"2.0\"sv),\r\n                MakeDefaultManifest(\"1.2\"sv),\r\n            },\r\n            setup.Available);\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(package, Criteria());\r\n        return result;\r\n    };\r\n\r\n    std::shared_ptr<ComponentTestSource> secondAvailable = std::make_shared<ComponentTestSource>(\"SecondTestSource\");\r\n    setup.Composite.AddAvailableSource(Source{ secondAvailable });\r\n    secondAvailable->SearchFunction = [&](const SearchRequest&)\r\n    {\r\n        auto package = TestCompositePackage::Make(std::vector<Manifest::Manifest>{ MakeDefaultManifest(\"1.1\"sv) }, secondAvailable);\r\n\r\n        SearchResult result;\r\n        result.Matches.emplace_back(package, Criteria());\r\n        return result;\r\n    };\r\n\r\n    {\r\n        PinKey pinKey(\"Id\", setup.Available->Details.Identifier);\r\n        auto pinningIndex = PinningIndex::OpenOrCreateDefault();\r\n        REQUIRE(pinningIndex);\r\n        pinningIndex->AddPin(Pin::CreateGatingPin(PinKey{ pinKey }, GatedVersion{ \"1.*\"sv }));\r\n    }\r\n\r\n    ExpectedResultsForPinning expectedResult;\r\n    expectedResult.ResultsForPinBehavior[PinBehavior::IgnorePins] = { /* IsUpdateAvailable */ true, /* LatestAvailableVersion */ \"2.0\" };\r\n    expectedResult.ResultsForPinBehavior[PinBehavior::ConsiderPins] = { /* IsUpdateAvailable */ true, /* LatestAvailableVersion */ \"1.2\" };\r\n    expectedResult.ResultsForPinBehavior[PinBehavior::IncludePinned] = { /* IsUpdateAvailable */ true, /* LatestAvailableVersion */ \"1.2\" };\r\n    expectedResult.AvailableVersions = {\r\n        { \"AvailableTestSource1\", \"2.0\", \"\", Pinning::PinType::Gating },\r\n        { \"AvailableTestSource1\", \"1.2\", \"\", Pinning::PinType::Unknown },\r\n        { \"SecondTestSource\", \"1.1\", \"\", Pinning::PinType::Unknown },\r\n    };\r\n\r\n    SearchResult result = setup.Search();\r\n    REQUIRE(result.Matches.size() == 1);\r\n    auto package = result.Matches[0].Package;\r\n    REQUIRE(package);\r\n    RequireExpectedResultsWithPin(package, expectedResult);\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_Pinning_MultipleInstalled\", \"[CompositeSource][PinFlow]\")\r\n{\r\n    // Tests the case where multiple installed packages match to a single available package.\r\n    // If one of the two installed packages is pinned, when searching we should get\r\n    // two Composite packages, with only one of them pinned.\r\n    TempFile indexFile(\"pinningIndex\", \".db\");\r\n    TestHook::SetPinningIndex_Override pinningIndexOverride(indexFile.GetPath());\r\n\r\n    TestUserSettings userSettings;\r\n    \r\n    std::string packageId = \"packageId\";\r\n    std::string productCode1 = \"product-code1\";\r\n    std::string productCode2 = \"product-code2\";\r\n\r\n    CompositeTestSetup setup;\r\n\r\n    // Installed packages differ in product code and version\r\n    auto installedPackage1 = setup.MakeInstalled().WithId(productCode1).WithPC(productCode1).WithVersion(\"1.1\"sv);\r\n    auto installedPackage2 = setup.MakeInstalled().WithId(productCode2).WithPC(productCode2).WithVersion(\"1.2\"sv);\r\n\r\n    setup.Installed->SearchFunction = [&](const SearchRequest& request)\r\n    {\r\n        bool isSearchById = SearchRequestIncludes(request.Inclusions, PackageMatchField::Id, MatchType::Exact, packageId);\r\n\r\n        SearchResult result;\r\n        if (isSearchById || SearchRequestIncludes(request.Inclusions, PackageMatchField::ProductCode, MatchType::Exact, productCode1))\r\n        {\r\n            result.Matches.emplace_back(installedPackage1, Criteria(request.Inclusions[0].Field));\r\n        }\r\n\r\n        if (isSearchById || SearchRequestIncludes(request.Inclusions, PackageMatchField::ProductCode, MatchType::Exact, productCode2))\r\n        {\r\n            result.Matches.emplace_back(installedPackage2, Criteria(request.Inclusions[0].Field));\r\n        }\r\n\r\n        return result;\r\n    };\r\n\r\n    // Available package has the same ID, no product code, and different version from both the installed packages;\r\n    setup.Available->SearchFunction = [&](const SearchRequest&)\r\n    {\r\n        SearchResult result;\r\n        result.Matches.emplace_back(setup.MakeAvailable().WithId(packageId).WithVersion(\"2.0\"sv), Criteria());\r\n        return result;\r\n    };\r\n\r\n    // We will pin the first package only\r\n    PinKey pinKey = PinKey::GetPinKeyForInstalled(productCode1);\r\n    auto pinningIndex = PinningIndex::OpenOrCreateDefault();\r\n    REQUIRE(pinningIndex);\r\n\r\n    // We will check the pinning status for both installed packages\r\n    ExpectedResultsForPinning expectedResult1;\r\n    ExpectedResultsForPinning expectedResult2;\r\n\r\n    expectedResult1.ResultsForPinBehavior[PinBehavior::IgnorePins]\r\n        = { /* IsUpdateAvailable */ true, /* LatestAvailableVersion */ \"2.0\" };\r\n\r\n    // The second package is never pinned, so its result is always the same\r\n    expectedResult2.ResultsForPinBehavior[PinBehavior::IgnorePins]\r\n        = expectedResult2.ResultsForPinBehavior[PinBehavior::ConsiderPins]\r\n        = expectedResult2.ResultsForPinBehavior[PinBehavior::IncludePinned]\r\n        = { /* IsUpdateAvailable */ true, /* LatestAvailableVersion */ \"2.0\" };\r\n    expectedResult2.AvailableVersions = {\r\n        { \"AvailableTestSource1\", \"2.0\", \"\", Pinning::PinType::Unknown },\r\n    };\r\n\r\n    SECTION(\"Unpinned\")\r\n    {\r\n        // If there are no pins, the result should not change if we consider them\r\n        expectedResult1.ResultsForPinBehavior[PinBehavior::ConsiderPins]\r\n            = expectedResult1.ResultsForPinBehavior[PinBehavior::IncludePinned]\r\n            = expectedResult1.ResultsForPinBehavior[PinBehavior::IgnorePins];\r\n        expectedResult1.AvailableVersions = {\r\n            { \"AvailableTestSource1\", \"2.0\", \"\", Pinning::PinType::Unknown },\r\n        };\r\n    }\r\n    SECTION(\"Pinned\")\r\n    {\r\n        pinningIndex->AddPin(Pin::CreatePinningPin(PinKey{ pinKey }));\r\n\r\n        // Pinning pins are ignored with --include-pinned\r\n        expectedResult1.ResultsForPinBehavior[PinBehavior::IncludePinned] = expectedResult1.ResultsForPinBehavior[PinBehavior::IgnorePins];\r\n\r\n        expectedResult1.ResultsForPinBehavior[PinBehavior::ConsiderPins] = { /* IsUpdateAvailable */ false, /* LatestAvailableVersion */ {} };\r\n        expectedResult1.AvailableVersions = {\r\n            { \"AvailableTestSource1\", \"2.0\", \"\", Pinning::PinType::Pinning },\r\n        };\r\n    }\r\n    SECTION(\"Blocked\")\r\n    {\r\n        pinningIndex->AddPin(Pin::CreateBlockingPin(PinKey{ pinKey }));\r\n        expectedResult1.ResultsForPinBehavior[PinBehavior::ConsiderPins] = { /* IsUpdateAvailable */ false, /* LatestAvailableVersion */ {} };\r\n\r\n        // Blocking pins are not affected by --include-pinned\r\n        expectedResult1.ResultsForPinBehavior[PinBehavior::IncludePinned] = expectedResult1.ResultsForPinBehavior[PinBehavior::ConsiderPins];\r\n\r\n        expectedResult1.AvailableVersions = {\r\n            { \"AvailableTestSource1\", \"2.0\", \"\", Pinning::PinType::Blocking },\r\n        };\r\n    }\r\n\r\n    SearchRequest searchRequest;\r\n    searchRequest.Inclusions.emplace_back(PackageMatchField::Id, MatchType::Exact, packageId);\r\n    SearchResult result = setup.Composite.Search(searchRequest);\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    auto installedPackage = result.Matches[0].Package->GetInstalled();\r\n    REQUIRE(installedPackage);\r\n    auto installedVersions = installedPackage->GetVersionKeys();\r\n    REQUIRE(installedVersions.size() == 2);\r\n\r\n    // Here we assume that the order we return the packages in the installed source\r\n    // search is preserved. We'll need to change it if that stops being the case.\r\n    auto packageVersion1 = installedPackage->GetVersion(installedVersions[1]);\r\n    REQUIRE(packageVersion1);\r\n\r\n    auto packageVersion2 = installedPackage->GetVersion(installedVersions[0]);\r\n    REQUIRE(packageVersion2);\r\n\r\n    RequireExpectedResultsWithPin(result.Matches[0].Package, expectedResult1, packageVersion1);\r\n    RequireExpectedResultsWithPin(result.Matches[0].Package, expectedResult2, packageVersion2);\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_CorrelateToInstalledContainsManifestData\", \"[CompositeSource]\")\r\n{\r\n    CompositeTestSetup setup;\r\n    setup.Installed->SearchFunction = [&](const SearchRequest& request)\r\n    {\r\n        if (request.Purpose == SearchPurpose::CorrelationToInstalled)\r\n        {\r\n            bool expectedSearchFound = false;\r\n            for (const auto& inclusion : request.Inclusions)\r\n            {\r\n                if (inclusion.Field == PackageMatchField::ProductCode && inclusion.Value == \"hello\")\r\n                {\r\n                    expectedSearchFound = true;\r\n                    break;\r\n                }\r\n            }\r\n\r\n            REQUIRE(expectedSearchFound);\r\n        }\r\n\r\n        SearchResult result;\r\n        return result;\r\n    };\r\n    setup.Available->SearchFunction = [&](const SearchRequest&)\r\n    {\r\n        SearchResult result;\r\n        result.Matches.emplace_back(setup.MakeAvailable().WithPC(\"hello\"), Criteria());\r\n        return result;\r\n    };\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Exact, \"NotForEverything\");\r\n    SearchResult result = setup.Composite.Search(request);\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_Respects_FeatureFlag_ManifestMayContainAdditionalSystemReferenceStrings\", \"[CompositeSource]\")\r\n{\r\n    std::string id = \"Special test ID\";\r\n    std::string productCode1 = \"product-code1\";\r\n\r\n    CompositeTestSetup setup;\r\n    bool productCodeSearched = false;\r\n    setup.Installed->SearchFunction = [&](const SearchRequest& request)\r\n        {\r\n            for (const auto& inclusion : request.Inclusions)\r\n            {\r\n                if (inclusion.Field == PackageMatchField::ProductCode)\r\n                {\r\n                    productCodeSearched = true;\r\n                }\r\n            }\r\n\r\n            return SearchResult{};\r\n        };\r\n    setup.Available->SearchFunction = [&](const SearchRequest&)\r\n        {\r\n            SearchResult result;\r\n            result.Matches.emplace_back(setup.MakeAvailable().WithId(id).WithPC(productCode1).HideSRS(), Criteria());\r\n            return result;\r\n        };\r\n\r\n    SECTION(\"Feature false\")\r\n    {\r\n        SearchRequest request;\r\n        request.Query = RequestMatch(MatchType::Exact, \"NotForEverything\");\r\n        SearchResult result = setup.Composite.Search(request);\r\n\r\n        REQUIRE(!productCodeSearched);\r\n    }\r\n    SECTION(\"Feature true\")\r\n    {\r\n        setup.Available->QueryFeatureFlagFunction = [](SourceFeatureFlag flag)\r\n            {\r\n                return (flag == SourceFeatureFlag::ManifestMayContainAdditionalSystemReferenceStrings);\r\n            };\r\n\r\n        SearchRequest request;\r\n        request.Query = RequestMatch(MatchType::Exact, \"NotForEverything\");\r\n        SearchResult result = setup.Composite.Search(request);\r\n\r\n        REQUIRE(productCodeSearched);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_SxS_TwoVersions_NoAvailable\", \"[CompositeSource][SideBySide]\")\r\n{\r\n    std::string productCode1 = \"PC1\";\r\n    std::string productCode2 = \"PC2\";\r\n\r\n    CompositeTestSetup setup;\r\n    auto availablePackage = setup.MakeAvailable();\r\n\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithVersion(\"1.0\").WithPC(productCode1), Criteria());\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithVersion(\"2.0\").WithPC(productCode2), Criteria());\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 2);\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_SxS_TwoVersions_DifferentAvailable\", \"[CompositeSource][SideBySide]\")\r\n{\r\n    std::string productCode1 = \"PC1\";\r\n    std::string productCode2 = \"PC2\";\r\n\r\n    CompositeTestSetup setup;\r\n    auto availablePackage1 = setup.MakeAvailable().ToPackage();\r\n    auto availablePackage2 = setup.MakeAvailable().ToPackage();\r\n\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithVersion(\"1.0\").WithPC(productCode1), Criteria());\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithVersion(\"2.0\").WithPC(productCode2), Criteria());\r\n\r\n    setup.Available->SearchFunction = [&](const SearchRequest& request)\r\n        {\r\n            SearchResult result;\r\n\r\n            std::string productCode;\r\n            for (const auto& item : request.Inclusions)\r\n            {\r\n                if (item.Field == PackageMatchField::ProductCode)\r\n                {\r\n                    productCode = item.Value;\r\n                    break;\r\n                }\r\n            }\r\n\r\n            if (productCode == productCode1)\r\n            {\r\n                result.Matches.emplace_back(availablePackage1, Criteria());\r\n            }\r\n            else if (productCode == productCode1)\r\n            {\r\n                result.Matches.emplace_back(availablePackage2, Criteria());\r\n            }\r\n\r\n            return result;\r\n        };\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 2);\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_SxS_TwoVersions_SameAvailable\", \"[CompositeSource][SideBySide]\")\r\n{\r\n    std::string version1 = \"1.0\";\r\n    std::string version2 = \"2.0\";\r\n    std::string productCode1 = \"PC1\";\r\n    std::string productCode2 = \"PC2\";\r\n\r\n    CompositeTestSetup setup;\r\n    auto availablePackage = setup.MakeAvailable().ToPackage();\r\n\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithVersion(version1).WithPC(productCode1), Criteria());\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithVersion(version2).WithPC(productCode2), Criteria());\r\n\r\n    setup.Available->SearchFunction = [&](const SearchRequest&)\r\n        {\r\n            SearchResult result;\r\n            result.Matches.emplace_back(availablePackage, Criteria());\r\n            return result;\r\n        };\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    auto package = result.Matches[0].Package;\r\n    REQUIRE(package);\r\n    auto installedPackage = package->GetInstalled();\r\n    REQUIRE(installedPackage);\r\n    auto installedVersions = installedPackage->GetVersionKeys();\r\n    REQUIRE(installedVersions.size() == 2);\r\n    REQUIRE(std::any_of(installedVersions.begin(), installedVersions.end(), [&](const PackageVersionKey& key) { return key.Version == version1; }));\r\n    REQUIRE(std::any_of(installedVersions.begin(), installedVersions.end(), [&](const PackageVersionKey& key) { return key.Version == version2; }));\r\n    auto availablePackages = package->GetAvailable();\r\n    REQUIRE(availablePackages.size() == 1);\r\n    REQUIRE(availablePackages[0]->IsSame(availablePackage->Available[0].get()));\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_SxS_ThreeVersions_SameAvailable\", \"[CompositeSource][SideBySide]\")\r\n{\r\n    std::string version1 = \"1.0\";\r\n    std::string version2 = \"2.0\";\r\n    std::string version3 = \"3.0\";\r\n    std::string productCode1 = \"PC1\";\r\n    std::string productCode2 = \"PC2\";\r\n    std::string productCode3 = \"PC3\";\r\n\r\n    CompositeTestSetup setup;\r\n    auto availablePackage = setup.MakeAvailable().ToPackage();\r\n\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithVersion(version1).WithPC(productCode1), Criteria());\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithVersion(version2).WithPC(productCode2), Criteria());\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithVersion(version3).WithPC(productCode3), Criteria());\r\n\r\n    setup.Available->SearchFunction = [&](const SearchRequest&)\r\n        {\r\n            SearchResult result;\r\n            result.Matches.emplace_back(availablePackage, Criteria());\r\n            return result;\r\n        };\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    auto package = result.Matches[0].Package;\r\n    REQUIRE(package);\r\n    auto installedPackage = package->GetInstalled();\r\n    REQUIRE(installedPackage);\r\n    auto installedVersions = installedPackage->GetVersionKeys();\r\n    REQUIRE(installedVersions.size() == 3);\r\n    REQUIRE(std::any_of(installedVersions.begin(), installedVersions.end(), [&](const PackageVersionKey& key) { return key.Version == version1; }));\r\n    REQUIRE(std::any_of(installedVersions.begin(), installedVersions.end(), [&](const PackageVersionKey& key) { return key.Version == version2; }));\r\n    REQUIRE(std::any_of(installedVersions.begin(), installedVersions.end(), [&](const PackageVersionKey& key) { return key.Version == version3; }));\r\n    auto availablePackages = package->GetAvailable();\r\n    REQUIRE(availablePackages.size() == 1);\r\n    REQUIRE(availablePackages[0]->IsSame(availablePackage->Available[0].get()));\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_SxS_TwoVersions_SameAvailable_Tracking\", \"[CompositeSource][SideBySide]\")\r\n{\r\n    std::string version1 = \"1.0\";\r\n    std::string version2 = \"2.0\";\r\n    std::string productCode1 = \"PC1\";\r\n    std::string productCode2 = \"PC2\";\r\n\r\n    CompositeWithTrackingTestSetup setup;\r\n    auto installedPackage1 = setup.MakeInstalled().WithVersion(version1).WithPC(productCode1);\r\n    auto availablePackage = setup.MakeAvailable().ToPackage();\r\n\r\n    setup.Installed->Everything.Matches.emplace_back(installedPackage1, Criteria());\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithVersion(version2).WithPC(productCode2), Criteria());\r\n    setup.Tracking->GetIndex().AddManifest(installedPackage1);\r\n\r\n    setup.Available->SearchFunction = [&](const SearchRequest&)\r\n        {\r\n            SearchResult result;\r\n            result.Matches.emplace_back(availablePackage, Criteria());\r\n            return result;\r\n        };\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    auto package = result.Matches[0].Package;\r\n    REQUIRE(package);\r\n    auto installedPackage = package->GetInstalled();\r\n    REQUIRE(installedPackage);\r\n    auto installedVersions = installedPackage->GetVersionKeys();\r\n    REQUIRE(installedVersions.size() == 2);\r\n    REQUIRE(std::any_of(installedVersions.begin(), installedVersions.end(), [&](const PackageVersionKey& key) { return key.Version == version1; }));\r\n    REQUIRE(std::any_of(installedVersions.begin(), installedVersions.end(), [&](const PackageVersionKey& key) { return key.Version == version2; }));\r\n    auto availablePackages = package->GetAvailable();\r\n    REQUIRE(availablePackages.size() == 1);\r\n    REQUIRE(availablePackages[0]->IsSame(availablePackage->Available[0].get()));\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_SxS_Available_TwoVersions_SameAvailable\", \"[CompositeSource][SideBySide]\")\r\n{\r\n    std::string version1 = \"1.0\";\r\n    std::string version2 = \"2.0\";\r\n    std::string productCode1 = \"PC1\";\r\n    std::string productCode2 = \"PC2\";\r\n\r\n    CompositeTestSetup setup;\r\n    auto availablePackage = setup.MakeAvailable().ToPackage();\r\n\r\n    setup.Installed->SearchFunction = [&](const SearchRequest&)\r\n        {\r\n            SearchResult result;\r\n            result.Matches.emplace_back(setup.MakeInstalled().WithVersion(version1).WithPC(productCode1), Criteria());\r\n            result.Matches.emplace_back(setup.MakeInstalled().WithVersion(version2).WithPC(productCode2), Criteria());\r\n            return result;\r\n        };\r\n\r\n    setup.Available->Everything.Matches.emplace_back(availablePackage, Criteria());\r\n\r\n    SearchResult result = setup.Search();\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    auto package = result.Matches[0].Package;\r\n    REQUIRE(package);\r\n    auto installedPackage = package->GetInstalled();\r\n    REQUIRE(installedPackage);\r\n    auto installedVersions = installedPackage->GetVersionKeys();\r\n    REQUIRE(installedVersions.size() == 2);\r\n    REQUIRE(std::any_of(installedVersions.begin(), installedVersions.end(), [&](const PackageVersionKey& key) { return key.Version == version1; }));\r\n    REQUIRE(std::any_of(installedVersions.begin(), installedVersions.end(), [&](const PackageVersionKey& key) { return key.Version == version2; }));\r\n    auto availablePackages = package->GetAvailable();\r\n    REQUIRE(availablePackages.size() == 1);\r\n    REQUIRE(availablePackages[0]->IsSame(availablePackage->Available[0].get()));\r\n}\r\n\r\nTEST_CASE(\"CompositeSource_MappedVersions_ProperSorting\", \"[CompositeSource]\")\r\n{\r\n    std::string installedID = \"Installed.Id\";\r\n    std::string availableID = \"Available.Id\";\r\n    auto type = Manifest::InstallerTypeEnum::Exe;\r\n    std::string pfn = \"MY_PFN\";\r\n    std::string version1 = \"1000.0\";\r\n    std::string version2 = \"2000.0\";\r\n    std::string versionMapped1 = \"1.0\";\r\n    std::string versionMapped2 = \"2.0\";\r\n\r\n    CompositeTestSetup setup;\r\n\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithId(installedID).WithPFN(pfn).WithVersion(version1).WithMetadata(PackageVersionMetadata::InstalledType, \"exe\"), Criteria());\r\n    setup.Installed->Everything.Matches.emplace_back(setup.MakeInstalled().WithId(installedID).WithPFN(pfn).WithVersion(version2).WithMetadata(PackageVersionMetadata::InstalledType, \"exe\"), Criteria());\r\n\r\n    setup.Available->SearchFunction = [&](const SearchRequest&)\r\n        {\r\n            auto package = setup.MakeAvailable();\r\n            package.WithId(availableID).WithType(type).WithPFN(pfn).WithVersion(versionMapped1).WithDisplayVersion(version1);\r\n            package.MakeManifest().WithId(availableID).WithType(type).WithPFN(pfn).WithVersion(versionMapped2).WithDisplayVersion(version2);\r\n\r\n            SearchResult result;\r\n            result.Matches.emplace_back(package, Criteria());\r\n            return result;\r\n        };\r\n\r\n    SearchResult result = setup.Search(true);\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    auto package = result.Matches[0].Package;\r\n    REQUIRE(package);\r\n    auto installedPackage = package->GetInstalled();\r\n    REQUIRE(installedPackage);\r\n    auto installedVersions = installedPackage->GetVersionKeys();\r\n    REQUIRE(installedVersions.size() == 2);\r\n    REQUIRE(installedVersions[0].Version == versionMapped2);\r\n    REQUIRE(installedVersions[1].Version == versionMapped1);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/ContextOrchestrator.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"TestCommon.h\"\n#include <ContextOrchestrator.h>\n#include <winget/ManifestYamlParser.h>\n\nusing namespace TestCommon;\nusing namespace AppInstaller::CLI;\nusing namespace AppInstaller::CLI::Execution;\nusing namespace AppInstaller::Manifest;\n\r\nstatic constexpr DWORD c_DefaultWaitInMs = 5000;\r\n\nstruct TestCOMContext : public COMContext\n{\n    TestCOMContext() = default;\n\n    std::function<void()> DownloadCallback;\n\n    void InvokeDownload()\n    {\n        if (DownloadCallback)\n        {\n            DownloadCallback();\n        }\n    }\n\n    std::function<void()> OperationCallback;\n\n    void InvokeOperation()\n    {\n        if (OperationCallback)\n        {\n            OperationCallback();\n        }\n    }\n};\n\nstruct TestDownloadCommand : public Command\n{\n    TestDownloadCommand() : Command(\"download\", \"tests\") {}\n\n    Resource::LocString ShortDescription() const override { return {}; }\n    Resource::LocString LongDescription() const override { return {}; }\n    void ValidateArguments(Execution::Args&) const override {}\n\n    void Execute(Context& context) const override\n    {\n        static_cast<TestCOMContext*>(&context)->InvokeDownload();\n    }\n};\n\nstruct TestOperationCommand : public Command\n{\n    TestOperationCommand() : Command(\"operation\", \"tests\") {}\n\n    Resource::LocString ShortDescription() const override { return {}; }\n    Resource::LocString LongDescription() const override { return {}; }\n    void ValidateArguments(Execution::Args&) const override {}\n\n    void Execute(Context& context) const override\n    {\n        static_cast<TestCOMContext*>(&context)->InvokeOperation();\n    }\n};\n\nstruct TestQueueItem\n{\n    TestCOMContext* Context = nullptr;\n    std::shared_ptr<OrchestratorQueueItem> QueueItem;\n};\n\nTestQueueItem CreateTestItem(std::optional<std::string> packageName = std::nullopt)\n{\n    TestQueueItem result;\n\n    std::unique_ptr<TestCOMContext> context = std::make_unique<TestCOMContext>();\n    // Forcibly initialize the thread globals objects\n    context->GetThreadGlobals().SetForCurrentThread();\n\n    TestDataFile testManifest(\"Manifest-Good.yaml\");\r\n    auto manifest = YamlParser::CreateFromPath(testManifest);\r\n\r\n    if (packageName)\r\n    {\r\n        manifest.Id = packageName.value();\r\n    }\r\n\n    context->Add<Data::Manifest>(std::move(manifest));\n\n    result.Context = context.get();\n\r\n    // Marking it an uninstall removes the extra work adding the items to the installing index\n    result.QueueItem = std::make_shared<OrchestratorQueueItem>(OrchestratorQueueItemId(AppInstaller::Utility::ConvertToUTF16(packageName.value_or(\"package\")), L\"source\"), std::move(context), PackageOperationType::Uninstall);\n\n    result.QueueItem->AddCommand(std::make_unique<TestDownloadCommand>());\n    result.QueueItem->AddCommand(std::make_unique<TestOperationCommand>());\n\n    return result;\n}\n\n// Runs an item through the orchestrator to ensure the basic functionality\nTEST_CASE(\"ContextOrchestrator_UnitTestExecution\", \"[context_orchestrator]\")\n{\n    ContextOrchestrator orchestrator;\n\n    auto testItem = CreateTestItem();\n\n    wil::slim_event_manual_reset operationEvent;\n    testItem.Context->OperationCallback = [&]() { operationEvent.SetEvent(); };\n\n    orchestrator.EnqueueAndRunItem(testItem.QueueItem);\n\n    REQUIRE(operationEvent.wait(c_DefaultWaitInMs));\n    REQUIRE(testItem.QueueItem->GetCompletedEvent().wait(c_DefaultWaitInMs));\n    REQUIRE(orchestrator.WaitForRunningItems(c_DefaultWaitInMs));\n}\n\nTEST_CASE(\"ContextOrchestrator_Disabled_NewEnqueue\", \"[context_orchestrator]\")\n{\n    ContextOrchestrator orchestrator;\n    auto testItem = CreateTestItem();\n\r\n    auto reason = AppInstaller::CancelReason::AppShutdown;\r\n    orchestrator.Disable(reason);\n    REQUIRE_THROWS_HR(orchestrator.EnqueueAndRunItem(testItem.QueueItem), AppInstaller::ToHRESULT(reason));\n}\n\nTEST_CASE(\"ContextOrchestrator_Disabled_QueueTransition\", \"[context_orchestrator]\")\n{\n    ContextOrchestrator orchestrator;\n\n    auto testItem = CreateTestItem();\n\n    wil::slim_event_manual_reset downloadEvent;\n    testItem.Context->DownloadCallback = [&]() { downloadEvent.wait(); };\n\n    orchestrator.EnqueueAndRunItem(testItem.QueueItem);\r\n\r\n    auto reason = AppInstaller::CancelReason::AppShutdown;\r\n    orchestrator.Disable(reason);\r\n\r\n    downloadEvent.SetEvent();\n\n    REQUIRE(testItem.QueueItem->GetCompletedEvent().wait(c_DefaultWaitInMs));\r\n    REQUIRE(testItem.Context->IsTerminated());\r\n    // Context translates our shutdown HRs to E_ABORT\n    REQUIRE(E_ABORT == testItem.Context->GetTerminationHR());\n}\n\n// While item in { Queued, Running } in both queues, cancel everything\nTEST_CASE(\"ContextOrchestrator_CancelAllItems\", \"[context_orchestrator]\")\n{\r\n    // Limit to one thread for downloads so we can get a queued item\n    ContextOrchestrator orchestrator{ 1 };\r\n\n    auto downloadQueued = CreateTestItem(\"downloadQueued\");\n    auto downloadRunning = CreateTestItem(\"downloadRunning\");\n    wil::slim_event_manual_reset downloadBegunEvent;\n    wil::slim_event_manual_reset downloadWaitingEvent;\n    downloadRunning.Context->DownloadCallback = [&]()\r\n        {\r\n            downloadBegunEvent.SetEvent();\r\n            downloadWaitingEvent.wait();\r\n        };\r\n\n    auto operationQueued = CreateTestItem(\"operationQueued\");\n    auto operationRunning = CreateTestItem(\"operationRunning\");\n    wil::slim_event_manual_reset operationBegunEvent;\n    wil::slim_event_manual_reset operationWaitingEvent;\n    operationRunning.Context->OperationCallback = [&]()\r\n        {\r\n            operationBegunEvent.SetEvent();\r\n            operationWaitingEvent.wait();\r\n        };\r\n\n    orchestrator.EnqueueAndRunItem(operationRunning.QueueItem);\n    orchestrator.EnqueueAndRunItem(operationQueued.QueueItem);\n    orchestrator.EnqueueAndRunItem(downloadRunning.QueueItem);\n    orchestrator.EnqueueAndRunItem(downloadQueued.QueueItem);\r\n\r\n    operationBegunEvent.wait(c_DefaultWaitInMs);\r\n    downloadBegunEvent.wait(c_DefaultWaitInMs);\r\n\r\n    INFO(\"Pre-shutdown state: \\n\" << orchestrator.GetStatusString());\r\n\r\n    auto reason = AppInstaller::CancelReason::AppShutdown;\r\n    orchestrator.Disable(reason);\r\n    orchestrator.CancelQueuedItems(reason);\r\n\r\n    operationWaitingEvent.SetEvent();\r\n    downloadWaitingEvent.SetEvent();\r\n\n    if (!orchestrator.WaitForRunningItems(c_DefaultWaitInMs))\r\n    {\r\n        INFO(\"Post-wait state: \\n\" << orchestrator.GetStatusString());\r\n        FAIL(\"Timed out waiting for orchestrator to empty\");\r\n    }\r\n\r\n    auto checkQueueItem = [](TestQueueItem& item)\r\n        {\n            REQUIRE(item.QueueItem->GetCompletedEvent().wait(0));\r\n            REQUIRE(item.Context->IsTerminated());\n            REQUIRE(E_ABORT == item.Context->GetTerminationHR());\r\n        };\r\n\n    checkQueueItem(downloadQueued);\n    checkQueueItem(downloadRunning);\n    checkQueueItem(operationQueued);\n    checkQueueItem(operationRunning);\n}\n"
  },
  {
    "path": "src/AppInstallerCLITests/Correlation.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestSource.h\"\r\n\r\n#include <winget/ARPCorrelation.h>\r\n#include <winget/ARPCorrelationAlgorithms.h>\r\n#include <winget/Manifest.h>\r\n#include <winget/RepositorySearch.h>\r\n\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Repository::Correlation;\r\nusing namespace AppInstaller::Utility;\r\n\r\nusing namespace TestCommon;\r\n\r\n// Data for defining a test case\r\nstruct TestCase\r\n{\r\n    // Actual app data\r\n    std::string AppName;\r\n    std::string AppPublisher;\r\n\r\n    // Data in ARP\r\n    std::string ARPName;\r\n    std::string ARPPublisher;\r\n\r\n    bool IsMatch;\r\n};\r\n\r\n// Definition of a collection of test cases that we evaluate\r\n// together to get a single aggregate result\r\nstruct DataSet\r\n{\r\n    // Details about the apps we are trying to correlate\r\n    std::vector<TestCase> TestCases;\r\n\r\n    // Additional ARP entries to use as \"noise\" for the correlation\r\n    std::vector<ARPEntry> ARPNoise;\r\n\r\n    // Thresholds for considering a run of an heuristic against\r\n    // this data set \"good\".\r\n    // Values are ratios to the total number of test cases\r\n    double RequiredTrueMatchRatio;\r\n    double RequiredTrueMismatchRatio;\r\n    double RequiredFalseMatchRatio;\r\n    double RequiredFalseMismatchRatio;\r\n};\r\n\r\n// Aggregate result of running an heuristic against a data set.\r\nstruct ResultSummary\r\n{\r\n    size_t TrueMatches;\r\n    size_t TrueMismatches;\r\n    size_t FalseMatches;\r\n    size_t FalseMismatches;\r\n    std::chrono::milliseconds TotalTime;\r\n\r\n    size_t TotalCases() const\r\n    {\r\n        return TrueMatches + TrueMismatches + FalseMatches + FalseMismatches;\r\n    }\r\n\r\n    auto AverageMatchingTime() const\r\n    {\r\n        return TotalTime / TotalCases();\r\n    }\r\n};\r\n\r\nManifest GetManifestFromTestCase(const TestCase& testCase)\r\n{\r\n    Manifest manifest;\r\n    manifest.DefaultLocalization.Add<Localization::PackageName>(testCase.AppName);\r\n    manifest.DefaultLocalization.Add<Localization::Publisher>(testCase.AppPublisher);\r\n    manifest.Localizations.push_back(manifest.DefaultLocalization);\r\n    return manifest;\r\n}\r\n\r\nARPEntry GetARPEntryFromTestCase(const TestCase& testCase, bool isNew)\r\n{\r\n    Manifest arpManifest;\r\n    arpManifest.DefaultLocalization.Add<Localization::PackageName>(testCase.ARPName);\r\n    arpManifest.DefaultLocalization.Add<Localization::Publisher>(testCase.ARPPublisher);\r\n    arpManifest.Localizations.push_back(arpManifest.DefaultLocalization);\r\n    return ARPEntry{ TestPackage::Make(arpManifest, TestPackage::MetadataMap{}), isNew };\r\n}\r\n\r\nARPEntry GetExistingARPEntryFromTestCase(const TestCase& testCase)\r\n{\r\n    return GetARPEntryFromTestCase(testCase, /* isNew */ false);\r\n}\r\n\r\nvoid ReportMatch(std::string_view label, std::string_view appName, std::string_view appPublisher, std::string_view arpName, std::string_view arpPublisher)\r\n{\r\n    WARN(label << '\\n' <<\r\n        \"\\tApp name      = \" << appName << '\\n' <<\r\n        \"\\tApp publisher = \" << appPublisher << '\\n' <<\r\n        \"\\tARP name      = \" << arpName << '\\n' <<\r\n        \"\\tARP publisher = \" << arpPublisher);\r\n}\r\n\r\nResultSummary EvaluateDataSetWithHeuristic(const DataSet& dataSet, IARPMatchConfidenceAlgorithm& correlationAlgorithm, bool reportErrors = false)\r\n{\r\n    ResultSummary result{};\r\n    auto startTime = std::chrono::steady_clock::now();\r\n\r\n    // Each entry under test will be pushed at the end of this\r\n    // and removed at the end.\r\n    auto arpEntries = dataSet.ARPNoise;\r\n\r\n    for (const auto& testCase : dataSet.TestCases)\r\n    {\r\n        arpEntries.push_back(GetARPEntryFromTestCase(testCase, /* isNew */ true));\r\n        ARPHeuristicsCorrelationResult correlationResult = FindARPEntryForNewlyInstalledPackageWithHeuristics(GetManifestFromTestCase(testCase), arpEntries, correlationAlgorithm);\r\n        auto match = correlationResult.Package;\r\n        arpEntries.pop_back();\r\n\r\n        if (match)\r\n        {\r\n            auto matchName = match->GetProperty(PackageVersionProperty::Name);\r\n            auto matchPublisher = match->GetProperty(PackageVersionProperty::Publisher);\r\n\r\n            // The strings get normalized when added to the manifest, so we have\r\n            // to normalize for the comparison.\r\n            if (matchName == NormalizedString(testCase.ARPName) && matchPublisher == NormalizedString(testCase.ARPPublisher))\r\n            {\r\n                ++result.TrueMatches;\r\n            }\r\n            else\r\n            {\r\n                ++result.FalseMatches;\r\n\r\n                if (reportErrors)\r\n                {\r\n                    ReportMatch(\"False match\", testCase.AppName, testCase.AppPublisher, matchName, matchPublisher);\r\n                }\r\n            }\r\n        }\r\n        else\r\n        {\r\n            if (testCase.IsMatch)\r\n            {\r\n                ++result.FalseMismatches;\r\n\r\n                if (reportErrors)\r\n                {\r\n                    ReportMatch(\"False mismatch\", testCase.AppName, testCase.AppPublisher, testCase.ARPName, testCase.ARPPublisher);\r\n                }\r\n            }\r\n            else\r\n            {\r\n                ++result.TrueMismatches;\r\n            }\r\n        }\r\n    }\r\n\r\n    auto endTime = std::chrono::steady_clock::now();\r\n    result.TotalTime = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);\r\n\r\n    return result;\r\n}\r\n\r\nvoid ReportResults(ResultSummary results)\r\n{\r\n    // This uses WARN to report as that is always shown regardless of the test result.\r\n    // We may want to re-consider reporting in some other way\r\n    WARN(\"Total cases:       \" << results.TotalCases() << '\\n' <<\r\n         \"True matches:      \" << results.TrueMatches << '\\n' <<\r\n         \"False matches:     \" << results.FalseMatches << '\\n' <<\r\n         \"True mismatches:   \" << results.TrueMismatches << '\\n' <<\r\n         \"False mismatches:  \" << results.FalseMismatches << '\\n' <<\r\n         \"Total matching time:   \" << results.TotalTime.count() << \"ms\\n\" <<\r\n         \"Average matching time: \" << results.AverageMatchingTime().count() << \"ms\");\r\n}\r\n\r\nvoid ReportAndEvaluateResults(ResultSummary results, const DataSet& dataSet)\r\n{\r\n    ReportResults(results);\r\n\r\n    // Required True ratio is a lower limit. The more results we get right, the better.\r\n    // Required False ratio is an upper limit. The fewer results we get wrong, the better.\r\n    REQUIRE(results.TrueMatches >= results.TotalCases() * dataSet.RequiredTrueMatchRatio);\r\n    REQUIRE(results.TrueMismatches >= results.TotalCases() * dataSet.RequiredTrueMismatchRatio);\r\n    REQUIRE(results.FalseMatches <= results.TotalCases() * dataSet.RequiredFalseMatchRatio);\r\n    REQUIRE(results.FalseMismatches <= results.TotalCases()* dataSet.RequiredFalseMismatchRatio);\r\n}\r\n\r\n// TODO: Define multiple data sets\r\n//   - Data set with many apps.\r\n//   - Data set with popular apps. The match requirements should be higher\r\n//   - Data set(s) in other languages.\r\n//   - Data set where not everything has a match\r\n\r\nstd::vector<TestCase> LoadTestData()\r\n{\r\n    // Creates test cases from the test data file.\r\n    // The format of the file is one case per line, each with pipe (|) separated values.\r\n    // Each row contains: AppId, AppName, AppPublisher, ARPDisplayName, ARPDisplayVersion, ARPPublisherName, ARPProductCode\r\n    // TODO: Add more test cases; particularly for non-matches\r\n    std::ifstream testDataStream(TestCommon::TestDataFile(\"InputARPData.txt\").GetPath());\r\n    REQUIRE(testDataStream);\r\n\r\n    std::vector<TestCase> testCases;\r\n\r\n    std::string line;\r\n    while (std::getline(testDataStream, line))\r\n    {\r\n        std::stringstream ss{ line };\r\n\r\n        TestCase testCase;\r\n        std::string appId;\r\n        std::string arpDisplayVersion;\r\n        std::string arpProductCode;\r\n        std::getline(ss, appId, '|');\r\n        std::getline(ss, testCase.AppName, '|');\r\n        std::getline(ss, testCase.AppPublisher, '|');\r\n        std::getline(ss, testCase.ARPName, '|');\r\n        std::getline(ss, arpDisplayVersion, '|');\r\n        std::getline(ss, testCase.ARPPublisher, '|');\r\n        std::getline(ss, arpProductCode, '|');\r\n\r\n        testCase.IsMatch = true;\r\n\r\n        testCases.push_back(std::move(testCase));\r\n    }\r\n\r\n    return testCases;\r\n}\r\n\r\nDataSet GetDataSet_NoNoise()\r\n{\r\n    DataSet dataSet;\r\n    dataSet.TestCases = LoadTestData();\r\n\r\n    // Arbitrary values. We should refine them as the algorithm gets better.\r\n    dataSet.RequiredTrueMatchRatio = 0.81;\r\n    dataSet.RequiredFalseMatchRatio = 0;\r\n    dataSet.RequiredTrueMismatchRatio = 0; // There are no expected mismatches in this data set\r\n    dataSet.RequiredFalseMismatchRatio = 0.25;\r\n\r\n    return dataSet;\r\n}\r\n\r\nDataSet GetDataSet_WithNoise()\r\n{\r\n    DataSet dataSet;\r\n    auto baseTestCases = LoadTestData();\r\n\r\n    std::transform(baseTestCases.begin(), baseTestCases.end(), std::back_inserter(dataSet.ARPNoise), GetExistingARPEntryFromTestCase);\r\n    dataSet.TestCases = std::move(baseTestCases);\r\n\r\n    // Arbitrary values. We should refine them as the algorithm gets better.\r\n    dataSet.RequiredTrueMatchRatio = 0.81;\r\n    dataSet.RequiredFalseMatchRatio = 0; // This should always stay at 0\r\n    dataSet.RequiredTrueMismatchRatio = 0; // There are no expected mismatches in this data set\r\n    dataSet.RequiredFalseMismatchRatio = 0.25;\r\n\r\n    return dataSet;\r\n}\r\n\r\n// Hide this test as it takes too long to run.\r\n// It is useful for comparing multiple algorithms, but for\r\n// regular testing we need only check that the chosen algorithm\r\n// performs well.\r\nTEMPLATE_TEST_CASE(\"Correlation_MeasureAlgorithmPerformance\", \"[correlation][.]\",\r\n    EmptyMatchConfidenceAlgorithm,\r\n    WordsEditDistanceMatchConfidenceAlgorithm)\r\n{\r\n    // Each section loads a different data set,\r\n    // and then they are all handled the same\r\n    DataSet dataSet;\r\n    SECTION(\"No ARP noise\")\r\n    {\r\n        dataSet = GetDataSet_NoNoise();\r\n    }\r\n    SECTION(\"With ARP noise\")\r\n    {\r\n        dataSet = GetDataSet_WithNoise();\r\n    }\r\n\r\n    TestType measure;\r\n    auto results = EvaluateDataSetWithHeuristic(dataSet, measure);\r\n    ReportResults(results);\r\n}\r\n\r\nTEST_CASE(\"Correlation_ChosenHeuristicIsGood\", \"[correlation]\")\r\n{\r\n    // Each section loads a different data set,\r\n    // and then they are all handled the same\r\n    DataSet dataSet;\r\n    SECTION(\"No ARP noise\")\r\n    {\r\n        dataSet = GetDataSet_NoNoise();\r\n    }\r\n    SECTION(\"With ARP noise\")\r\n    {\r\n        dataSet = GetDataSet_WithNoise();\r\n    }\r\n\r\n    // Use only the measure we ultimately pick\r\n    auto& algorithm = IARPMatchConfidenceAlgorithm::Instance();\r\n    auto results = EvaluateDataSetWithHeuristic(dataSet, algorithm, /* reportErrors */ true);\r\n    ReportAndEvaluateResults(results, dataSet);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/CustomHeader.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestHooks.h\"\r\n#include \"TestSettings.h\"\r\n#include \"TestSource.h\"\r\n#include \"TestRestRequestHandler.h\"\r\n#include <Rest/Schema/1_1/Interface.h>\r\n#include <winget/JsonUtil.h>\r\n#include <Rest/RestClient.h>\r\n#include <winget/Settings.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller;\r\nusing namespace AppInstaller::Http;\r\nusing namespace AppInstaller::Settings;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Repository::Rest;\r\nusing namespace AppInstaller::Repository::Rest::Schema;\r\nusing namespace AppInstaller::Repository::Rest::Schema::V1_0;\r\n\r\nnamespace\r\n{\r\n    utility::string_t CustomHeaderName = L\"Windows-Package-Manager\";\r\n\r\n    constexpr std::string_view s_EmptySources = R\"(\r\n        Sources:\r\n        )\"sv;\r\n\r\n    utility::string_t sampleSearchResponse = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : [\r\n               {\r\n              \"PackageIdentifier\": \"git.package\",\r\n              \"PackageName\": \"package\",\r\n              \"Publisher\": \"git\",\r\n              \"Versions\": [\r\n                {   \"PackageVersion\": \"1.0.0\" }]\r\n            }]\r\n        })delimiter\");\r\n}\r\n\r\n// In RestClient.cpp tests\r\nextern RestClient CreateRestClient(\r\n    const std::string& restApi,\r\n    const std::optional<std::string>& customHeader,\r\n    std::string_view caller,\r\n    const Http::HttpClientHelper& helper,\r\n    const Authentication::AuthenticationArguments& authArgs = {});\r\n\r\nTEST_CASE(\"RestClient_CustomHeader\", \"[RestSource][CustomHeader]\")\r\n{\r\n    utility::string_t sample = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : {\r\n              \"SourceIdentifier\": \"Source123\",\r\n              \"ServerSupportedVersions\": [\r\n                \"1.0.0\",\r\n                \"2.0.0\"]\r\n        }})delimiter\");\r\n\r\n    std::optional<std::string> customHeader = \"Testing custom header\";\r\n    auto header = std::make_pair<>(CustomHeaderName, JSON::GetUtilityString(customHeader.value()));\r\n    HttpClientHelper helper{ GetHeaderVerificationHandler(web::http::status_codes::OK, sample, header) };\r\n    RestClient client = CreateRestClient(utility::conversions::to_utf8string(\"https://restsource.com/api\"), customHeader, {}, helper);\r\n    REQUIRE(client.GetSourceIdentifier() == \"Source123\");\r\n}\r\n\r\nTEST_CASE(\"RestSourceSearch_CustomHeader\", \"[RestSource][CustomHeader]\")\r\n{\r\n    utility::string_t customHeader = L\"Testing custom header\";\r\n    auto header = std::make_pair<>(CustomHeaderName, customHeader);\r\n    HttpClientHelper helper{ GetHeaderVerificationHandler(web::http::status_codes::OK, sampleSearchResponse, header) };\r\n    std::unordered_map<utility::string_t, utility::string_t> headers;\r\n    headers.emplace(CustomHeaderName, customHeader);\r\n\r\n    V1_1::Interface v1_1{ \"https://restsource.com/api\", std::move(helper) , {}, headers};\r\n    Schema::IRestClient::SearchResult searchResponse = v1_1.Search({});\r\n    REQUIRE(searchResponse.Matches.size() == 1);\r\n    Schema::IRestClient::Package package = searchResponse.Matches.at(0);\r\n}\r\n\r\nTEST_CASE(\"RestSourceSearch_WhitespaceCustomHeader\", \"[RestSource][CustomHeader]\")\r\n{\r\n    utility::string_t customHeader = L\"    \";\r\n    auto header = std::make_pair<>(CustomHeaderName, customHeader);\r\n    HttpClientHelper helper{ GetHeaderVerificationHandler(web::http::status_codes::OK, sampleSearchResponse, header) };\r\n    std::unordered_map<utility::string_t, utility::string_t> headers;\r\n    headers.emplace(CustomHeaderName, customHeader);\r\n\r\n    V1_1::Interface v1_1{ \"https://restsource.com/api\", std::move(helper), {}, headers };\r\n    Schema::IRestClient::SearchResult searchResponse = v1_1.Search({});\r\n    REQUIRE(searchResponse.Matches.size() == 1);\r\n}\r\n\r\nTEST_CASE(\"RestSourceSearch_NoCustomHeader\", \"[RestSource][CustomHeader]\")\r\n{\r\n    utility::string_t customHeader = L\"    \";\r\n    auto header = std::make_pair<>(CustomHeaderName, customHeader);\r\n    HttpClientHelper helper{ GetHeaderVerificationHandler(web::http::status_codes::OK, sampleSearchResponse, header) };\r\n    std::unordered_map<utility::string_t, utility::string_t> headers;\r\n    headers.emplace(CustomHeaderName, customHeader);\r\n\r\n    V1_1::Interface v1_1{ \"https://restsource.com/api\", std::move(helper), {}, {} };\r\n    REQUIRE_THROWS_HR(v1_1.Search({}), APPINSTALLER_CLI_ERROR_RESTAPI_INTERNAL_ERROR);\r\n}\r\n\r\nTEST_CASE(\"RestSourceSearch_CustomHeaderExceedingSize\", \"[RestSource][CustomHeader]\")\r\n{\r\n    std::string customHeader = \"This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. This is a custom header that is longer than 1024 characters. \";\r\n    auto header = std::make_pair<>(CustomHeaderName, JSON::GetUtilityString(customHeader));\r\n    HttpClientHelper helper{ GetHeaderVerificationHandler(web::http::status_codes::OK, sampleSearchResponse, header) };\r\n\r\n    REQUIRE_THROWS_HR(CreateRestClient(utility::conversions::to_utf8string(\"https://restsource.com/api\"), customHeader, {}, helper),\r\n        APPINSTALLER_CLI_ERROR_CUSTOMHEADER_EXCEEDS_MAXLENGTH);\r\n}\r\n\r\nTEST_CASE(\"RestClient_CustomUserAgentHeader\", \"[RestSource][CustomHeader]\")\r\n{\r\n    utility::string_t sample = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : {\r\n              \"SourceIdentifier\": \"Source123\",\r\n              \"ServerSupportedVersions\": [\r\n                \"1.0.0\",\r\n                \"2.0.0\"]\r\n        }})delimiter\");\r\n\r\n    std::string testCaller = \"TestCaller\";\r\n    auto header = std::make_pair<>(web::http::header_names::user_agent, JSON::GetUtilityString(Runtime::GetUserAgent(testCaller)));\r\n    HttpClientHelper helper{ GetHeaderVerificationHandler(web::http::status_codes::OK, sample, header) };\r\n    RestClient client = CreateRestClient(utility::conversions::to_utf8string(\"https://restsource.com/api\"), {}, testCaller, helper);\r\n    REQUIRE(client.GetSourceIdentifier() == \"Source123\");\r\n}\r\n\r\nTEST_CASE(\"RestClient_DefaultUserAgentHeader\", \"[RestSource][CustomHeader]\")\r\n{\r\n    utility::string_t sample = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : {\r\n              \"SourceIdentifier\": \"Source123\",\r\n              \"ServerSupportedVersions\": [\r\n                \"1.0.0\",\r\n                \"2.0.0\"]\r\n        }})delimiter\");\r\n\r\n    auto header = std::make_pair<>(web::http::header_names::user_agent, JSON::GetUtilityString(Runtime::GetDefaultUserAgent()));\r\n    HttpClientHelper helper{ GetHeaderVerificationHandler(web::http::status_codes::OK, sample, header) };\r\n    RestClient client = CreateRestClient(utility::conversions::to_utf8string(\"https://restsource.com/api\"), {}, {}, helper);\r\n    REQUIRE(client.GetSourceIdentifier() == \"Source123\");\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/DateTime.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <AppInstallerDateTime.h>\r\n\r\nusing namespace AppInstaller::Utility;\r\nusing namespace TestCommon;\r\nusing namespace std::chrono;\r\n\r\nnamespace Catch\r\n{\r\n    template<>\r\n    struct StringMaker<std::chrono::system_clock::time_point>\r\n    {\r\n        static std::string convert(const std::chrono::system_clock::time_point& value)\r\n        {\r\n            std::ostringstream stream;\r\n            OutputTimePoint(stream, value);\r\n            return std::move(stream).str();\r\n        }\r\n    };\r\n}\r\n\r\nvoid VerifyGetTimePointFromVersion(std::string_view version, int year, int month, int day, int hour, int minute)\r\n{\r\n    system_clock::time_point result = GetTimePointFromVersion(UInt64Version{ std::string{ version } });\r\n\r\n    tm time{};\r\n    auto tt = system_clock::to_time_t(result);\r\n    _gmtime64_s(&time, &tt);\r\n\r\n    REQUIRE(year == time.tm_year + 1900);\r\n    REQUIRE(month == time.tm_mon + 1);\r\n    REQUIRE(day == time.tm_mday);\r\n    REQUIRE(hour == time.tm_hour);\r\n    REQUIRE(minute == time.tm_min);\r\n}\r\n\r\nstd::string StringFromTimePoint(system_clock::time_point input)\r\n{\r\n    tm time{};\r\n    auto tt = system_clock::to_time_t(input);\r\n    _gmtime64_s(&time, &tt);\r\n\r\n    std::ostringstream stream;\r\n    stream << time.tm_year + 1900 << '.' << ((time.tm_mon + 1) * 100) + time.tm_mday << '.' << ((time.tm_hour + 1) * 100) + time.tm_min;\r\n    return std::move(stream).str();\r\n}\r\n\r\nTEST_CASE(\"GetTimePointFromVersion\", \"[datetime]\")\r\n{\r\n    // Years out of range\r\n    REQUIRE(GetTimePointFromVersion(UInt64Version{ \"1969.1231.2459.0\" }) == system_clock::time_point::min());\r\n    REQUIRE(GetTimePointFromVersion(UInt64Version{ \"3001.101.100.0\" }) == system_clock::time_point::min());\r\n\r\n    // Months out of range\r\n    REQUIRE(GetTimePointFromVersion(UInt64Version{ \"2023.1.100.0\" }) == system_clock::time_point::min());\r\n    REQUIRE(GetTimePointFromVersion(UInt64Version{ \"2023.1301.100.0\" }) == system_clock::time_point::min());\r\n\r\n    // Days out of range\r\n    REQUIRE(GetTimePointFromVersion(UInt64Version{ \"2023.100.100.0\" }) == system_clock::time_point::min());\r\n    REQUIRE(GetTimePointFromVersion(UInt64Version{ \"2023.132.100.0\" }) == system_clock::time_point::min());\r\n\r\n    // Hours out of range\r\n    REQUIRE(GetTimePointFromVersion(UInt64Version{ \"2023.101.0.0\" }) == system_clock::time_point::min());\r\n    REQUIRE(GetTimePointFromVersion(UInt64Version{ \"2023.101.2500.0\" }) == system_clock::time_point::min());\r\n\r\n    // Minutes out of range\r\n    REQUIRE(GetTimePointFromVersion(UInt64Version{ \"2023.101.160.0\" }) == system_clock::time_point::min());\r\n\r\n    // In range baseline\r\n    VerifyGetTimePointFromVersion(\"2023.101.100.0\", 2023, 1, 1, 0, 0);\r\n\r\n    // Time for presents!\r\n    VerifyGetTimePointFromVersion(\"2023.1225.814.0\", 2023, 12, 25, 7, 14);\r\n\r\n    // Epoch time\r\n    REQUIRE(GetTimePointFromVersion(UInt64Version{ \"1970.101.100.0\" }) == system_clock::time_point{});\r\n\r\n    // Round trip now\r\n    system_clock::time_point now = system_clock::now();\r\n    REQUIRE(GetTimePointFromVersion(UInt64Version{ StringFromTimePoint(now) }) == time_point_cast<minutes>(now));\r\n}\r\n\r\nTEST_CASE(\"ShortFileTime\", \"[datetime]\")\r\n{\r\n    auto shortTime = GetCurrentTimeForFilename(true);\r\n    auto longTime = GetCurrentTimeForFilename(false);\r\n    INFO(shortTime);\r\n    INFO(longTime);\r\n    REQUIRE(shortTime.length() < longTime.length());\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/Dependencies.cpp",
    "content": "#include \"pch.h\"\n#include \"TestCommon.h\"\n#include \"TestSource.h\"\n#include \"DependenciesTestSource.h\"\n#include <winget/DependenciesGraph.h>\n#include <Workflows/DependencyNodeProcessor.h>\n#include <AppInstallerErrors.h>\n#include <AppInstallerRuntime.h>\n#include <AppInstallerStrings.h>\n#include <Workflows/DependenciesFlow.h>\n#include <Workflows/WorkflowBase.h>\n#include <winget/ManifestYamlParser.h>\n#include <winget/PathVariable.h>\n#include <winget/RepositorySource.h>\n#include <Resources.h>\n\nusing namespace winrt::Windows::Foundation;\nusing namespace winrt::Windows::Management::Deployment;\nusing namespace TestCommon;\nusing namespace AppInstaller::CLI;\nusing namespace AppInstaller::CLI::Execution;\nusing namespace AppInstaller::CLI::Workflow;\nusing namespace AppInstaller::Logging;\nusing namespace AppInstaller::Manifest;\nusing namespace AppInstaller::Repository;\nusing namespace AppInstaller::Settings;\nusing namespace AppInstaller::Utility;\nusing namespace AppInstaller::Utility::literals;\n\nTEST_CASE(\"DependencyGraph_BFirst\", \"[dependencyGraph][dependencies]\")\n{\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\n    std::vector<Dependency> installationOrder;\n\n    const auto& manifest = CreateFakeManifestWithDependencies(\"NeedsToInstallBFirst\");\n    const auto& installers = manifest.Installers;\n    const Dependency& rootAsDependency = Dependency(DependencyType::Package, manifest.Id);\n    DependencyList rootDependencies;\n    std::for_each(installers.begin(), installers.end(), [&](ManifestInstaller installer) { rootDependencies.Add(installer.Dependencies); });\n\n    DependencyGraph graph(rootAsDependency, rootDependencies, [&](Dependency)\n        {\n            DependencyList dependencyList;\n            auto dependencyManifest = CreateFakeManifestWithDependencies(manifest.Id);\n\n            for (auto installer : dependencyManifest.Installers)\n            {\n                dependencyList.Add(installer.Dependencies);\n            }\n\n            return dependencyList;\n        });\n\n    graph.BuildGraph();\n\n    installationOrder = graph.GetInstallationOrder();\n\n    REQUIRE(installationOrder.size() == 3);\n    REQUIRE(installationOrder.at(0).Id() == \"C\");\n    REQUIRE(installationOrder.at(1).Id() == \"B\");\n    REQUIRE(installationOrder.at(2).Id() == \"NeedsToInstallBFirst\");\n}\n\nTEST_CASE(\"DependencyGraph_InStackNoLoop\", \"[dependencyGraph][dependencies]\")\n{\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\n    std::vector<Dependency> installationOrder;\n\n    const auto& manifest = CreateFakeManifestWithDependencies(\"DependencyAlreadyInStackButNoLoop\");\n    const auto& installers = manifest.Installers;\n    const Dependency& rootAsDependency = Dependency(DependencyType::Package, manifest.Id);\n    DependencyList rootDependencies;\n    std::for_each(installers.begin(), installers.end(), [&](ManifestInstaller installer) { rootDependencies.Add(installer.Dependencies); });\n\n    DependencyGraph graph(rootAsDependency, rootDependencies, [&](Dependency)\n        {\n            DependencyList dependencyList;\n            auto dependencyManifest = CreateFakeManifestWithDependencies(manifest.Id);\n\n            for (auto installer : dependencyManifest.Installers)\n            {\n                dependencyList.Add(installer.Dependencies);\n            }\n\n            return dependencyList;\n        });\n\n    graph.BuildGraph();\n\n    installationOrder = graph.GetInstallationOrder();\n\n    REQUIRE(installationOrder.size() == 3);\n    REQUIRE(installationOrder.at(0).Id() == \"F\");\n    REQUIRE(installationOrder.at(1).Id() == \"C\");\n    REQUIRE(installationOrder.at(2).Id() == \"DependencyAlreadyInStackButNoLoop\");\n}\n\nTEST_CASE(\"DependencyGraph_EasyToSeeLoop\", \"[dependencyGraph][dependencies]\")\n{\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\n    std::vector<Dependency> installationOrder;\n\n    const auto& manifest = CreateFakeManifestWithDependencies(\"EasyToSeeLoop\");\n    const auto& installers = manifest.Installers;\n    const Dependency& rootAsDependency = Dependency(DependencyType::Package, manifest.Id);\n    DependencyList rootDependencies;\n    std::for_each(installers.begin(), installers.end(), [&](ManifestInstaller installer) { rootDependencies.Add(installer.Dependencies); });\n\n    DependencyGraph graph(rootAsDependency, rootDependencies, [&](Dependency) {\n        DependencyList dependencyList;\n        auto dependencyManifest = CreateFakeManifestWithDependencies(manifest.Id);\n\n        for (auto installer : dependencyManifest.Installers)\n        {\n            dependencyList.Add(installer.Dependencies);\n        }\n\n        return dependencyList;\n        });\n\n    graph.BuildGraph();\n\n    installationOrder = graph.GetInstallationOrder();\n\n    bool hasLoop = graph.HasLoop();\n\n    REQUIRE(hasLoop);\n\n    REQUIRE(installationOrder.size() == 2);\n    REQUIRE(installationOrder.at(0).Id() == \"D\");\n    REQUIRE(installationOrder.at(1).Id() == \"EasyToSeeLoop\");\n}\n\nTEST_CASE(\"DependencyNodeProcessor_SkipInstalled\", \"[dependencies]\")\n{\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\n\n    std::ostringstream installOutput;\n    Context context{ installOutput, std::cin };\n\n    Manifest manifest = CreateFakeManifestWithDependencies(\"installed1\");\n\n    context.Add<Execution::Data::DependencySource>(Source{ std::make_shared<DependenciesTestSource>() });\n    DependencyNodeProcessor nodeProcessor(context);\n\n    Dependency rootAsDependency(DependencyType::Package, manifest.Id);\n\n    DependencyNodeProcessorResult result = nodeProcessor.EvaluateDependencies(rootAsDependency);\n    REQUIRE(result == DependencyNodeProcessorResult::Skipped);\n}\n\nTEST_CASE(\"DependencyNodeProcessor_NoInstallers\", \"[dependencies]\")\n{\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\n\n    std::ostringstream installOutput;\n    Context context { installOutput, std::cin };\n\n    Manifest manifest = CreateFakeManifestWithDependencies(\"withoutInstallers\");\n\n    context.Add<Execution::Data::DependencySource>(Source{ std::make_shared<DependenciesTestSource>() });\n    DependencyNodeProcessor nodeProcessor(context);\n\n    Dependency rootAsDependency(DependencyType::Package, manifest.Id);\n\n    DependencyNodeProcessorResult result = nodeProcessor.EvaluateDependencies(rootAsDependency);\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::DependenciesFlowNoInstallerFound(\"withoutInstallers\"_liv))) != std::string::npos);\n    REQUIRE(result == DependencyNodeProcessorResult::Error);\n}\n\nTEST_CASE(\"DependencyNodeProcessor_StackOrderIsOk\", \"[dependencies]\")\n{\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\n\n    std::ostringstream installOutput;\n    Context context{ installOutput, std::cin };\n\n    Manifest manifest = CreateFakeManifestWithDependencies(\"StackOrderIsOk\");\n\n    context.Add<Execution::Data::DependencySource>(Source{ std::make_shared<DependenciesTestSource>() });\n    DependencyNodeProcessor nodeProcessor(context);\n\n    Dependency rootAsDependency(DependencyType::Package, manifest.Id);\n\n    DependencyNodeProcessorResult result = nodeProcessor.EvaluateDependencies(rootAsDependency);\n    auto dependencyList = nodeProcessor.GetDependencyList();\n    REQUIRE(dependencyList.Size() == 1);\n    REQUIRE(dependencyList.HasDependency(Dependency(DependencyType::Package, \"C\")));\n    REQUIRE(result == DependencyNodeProcessorResult::Success);\n}\n\nTEST_CASE(\"DependencyNodeProcessor_NoMatches\", \"[dependencies]\")\n{\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\n\n    std::ostringstream installOutput;\n    Context context{ installOutput, std::cin };\n\n    Manifest manifest = CreateFakeManifestWithDependencies(\"NoMatches\");\n\n    context.Add<Execution::Data::DependencySource>(Source{ std::make_shared<DependenciesTestSource>() });\n    DependencyNodeProcessor nodeProcessor(context);\n\n    Dependency rootAsDependency(DependencyType::Package, manifest.Id);\n\n    DependencyNodeProcessorResult result = nodeProcessor.EvaluateDependencies(rootAsDependency);\n    auto dependencyList = nodeProcessor.GetDependencyList();\n    REQUIRE(dependencyList.Size() == 0);\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::DependenciesFlowNoMatches)) != std::string::npos);\n    REQUIRE(result == DependencyNodeProcessorResult::Error);\n}\n\nTEST_CASE(\"DependencyList_Add_MinVersion\", \"[dependencies]\")\n{\n    DependencyType type = DependencyType::Package;\n    std::string identifier = \"Identifier\";\n\n    DependencyList list;\n    Dependency dependencyWithoutMinVersion{ type, identifier };\n    Dependency dependencyWithLowerMinVersion{ type, identifier, \"1.0\" };\n    Dependency dependencyWithHigherMinVersion{ type, identifier, \"3.0\" };\n\n    Dependency dependencyToAdd{ type, identifier, \"2.0\" };\n\n    SECTION(\"Existing dependency has no min version, added does\")\n    {\n        list.Add(dependencyWithoutMinVersion);\n        list.Add(dependencyToAdd);\n\n        const Dependency* dependency = list.HasDependency(dependencyToAdd);\n        REQUIRE(dependency != nullptr);\n        REQUIRE(dependency->MinVersion.has_value());\n        REQUIRE(dependency->MinVersion == dependencyToAdd.MinVersion);\n    }\n    SECTION(\"Existing dependency has lower min version\")\n    {\n        list.Add(dependencyWithLowerMinVersion);\n        list.Add(dependencyToAdd);\n\n        const Dependency* dependency = list.HasDependency(dependencyToAdd);\n        REQUIRE(dependency != nullptr);\n        REQUIRE(dependency->MinVersion.has_value());\n        REQUIRE(dependency->MinVersion == dependencyToAdd.MinVersion);\n    }\n    SECTION(\"Existing dependency has higher min version\")\n    {\n        list.Add(dependencyWithHigherMinVersion);\n        list.Add(dependencyToAdd);\n\n        const Dependency* dependency = list.HasDependency(dependencyToAdd);\n        REQUIRE(dependency != nullptr);\n        REQUIRE(dependency->MinVersion.has_value());\n        REQUIRE(dependency->MinVersion == dependencyWithHigherMinVersion.MinVersion);\n    }\n    SECTION(\"Existing dependency has no min version, neither does added\")\n    {\n        list.Add(dependencyWithoutMinVersion);\n        list.Add(dependencyWithoutMinVersion);\n\n        const Dependency* dependency = list.HasDependency(dependencyToAdd);\n        REQUIRE(dependency != nullptr);\n        REQUIRE(!dependency->MinVersion.has_value());\n    }\n    SECTION(\"Existing dependency has min version, added does not\")\n    {\n        list.Add(dependencyWithHigherMinVersion);\n        list.Add(dependencyWithoutMinVersion);\n\n        const Dependency* dependency = list.HasDependency(dependencyToAdd);\n        REQUIRE(dependency != nullptr);\n        REQUIRE(dependency->MinVersion.has_value());\n        REQUIRE(dependency->MinVersion == dependencyWithHigherMinVersion.MinVersion);\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLITests/DependenciesTestSource.h",
    "content": "#pragma once\n\n#include \"pch.h\"\n#include \"TestSource.h\"\n#include \"TestCommon.h\"\n#include \"AppInstallerVersions.h\"\n#include <Public/winget/RepositorySource.h>\n#include <winget/ManifestYamlParser.h>\n\nusing namespace AppInstaller::Repository;\nusing namespace AppInstaller::Manifest;\nusing namespace AppInstaller::Utility;\n\nnamespace TestCommon\n{\n    namespace \n    {\n        Manifest CreateFakeManifestWithDependencies(std::string input)\n        {\n            auto manifest = YamlParser::CreateFromPath(TestDataFile(\"Installer_Exe_Dependencies.yaml\"));\n            manifest.Id = input;\n            manifest.Moniker = input;\n\n            auto& installer = manifest.Installers.at(0);\n            installer.ProductId = input;\n            installer.Dependencies.Clear();\n\n            string_t defaultFakeVersion(\"0.0.1-defaultFakeVersion\");\n\n            if (input == \"withoutInstallers\")\n            {\n                manifest.Installers.clear();\n                return manifest;\n            }\n\n            /*\n            * Dependencies:\n            *   \"A\": Depends on the test\n            *   B: NoDependency\n            *   C: B\n            *   D: E\n            *   E: D\n            *   F: B\n            *   G: C\n            *   H: G, B\n            *\n            *   installed1\n            *   minVersion1.0\n            *   minVersion1.5\n            *   requires1.5: minVersion1.5\n            *   minVersion2.0 //invalid version (not returned as result)\n            */\n\n            //-- predefined\n            if (input == \"C\")\n            {\n                installer.Dependencies.Add(Dependency(DependencyType::Package, \"B\", defaultFakeVersion));\n            }\n            if (input == \"D\")\n            {\n                installer.Dependencies.Add(Dependency(DependencyType::Package, \"E\", defaultFakeVersion));\n            }\n            if (input == \"E\")\n            {\n                installer.Dependencies.Add(Dependency(DependencyType::Package, \"D\", defaultFakeVersion));\n            }\n            if (input == \"F\")\n            {\n                installer.Dependencies.Add(Dependency(DependencyType::Package, \"B\", defaultFakeVersion));\n            }\n            if (input == \"G\")\n            {\n                installer.Dependencies.Add(Dependency(DependencyType::Package, \"C\", defaultFakeVersion));\n            }\n            if (input == \"H\")\n            {\n                installer.Dependencies.Add(Dependency(DependencyType::Package, \"G\", defaultFakeVersion));\n                installer.Dependencies.Add(Dependency(DependencyType::Package, \"B\", defaultFakeVersion));\n            }\n            if (input == \"installed1\")\n            {\n                installer.Dependencies.Add(Dependency(DependencyType::Package, \"installed1Dep\", defaultFakeVersion));\n            }\n            if (input == \"minVersion1.0\")\n            {\n                manifest.Id = \"minVersion\";\n                manifest.Version = \"1.0\";\n            }\n            if (input == \"minVersion1.5\")\n            {\n                manifest.Id = \"minVersion\";\n                manifest.Version = \"1.5\";\n            }\n            if (input == \"requires1.5\")\n            {\n                installer.Dependencies.Add(Dependency(DependencyType::Package, \"minVersion\", \"1.5\"));\n            }\n\n            // depends on test\n            if (input == \"StackOrderIsOk\")\n            {\n                installer.Dependencies.Add(Dependency(DependencyType::Package, \"C\", defaultFakeVersion));\n            }\n            if (input == \"NeedsToInstallBFirst\")\n            {\n                installer.Dependencies.Add(Dependency(DependencyType::Package, \"B\", defaultFakeVersion));\n                installer.Dependencies.Add(Dependency(DependencyType::Package, \"C\", defaultFakeVersion));\n            }\n            if (input == \"EasyToSeeLoop\")\n            {\n                installer.Dependencies.Add(Dependency(DependencyType::Package, \"D\", defaultFakeVersion));\n            }\n            if (input == \"DependencyAlreadyInStackButNoLoop\")\n            {\n                installer.Dependencies.Add(Dependency(DependencyType::Package, \"C\", defaultFakeVersion));\n                installer.Dependencies.Add(Dependency(DependencyType::Package, \"F\", defaultFakeVersion));\n            }\n            if (input == \"PathBetweenBranchesButNoLoop\")\n            {\n                installer.Dependencies.Add(Dependency(DependencyType::Package, \"C\", defaultFakeVersion));\n                installer.Dependencies.Add(Dependency(DependencyType::Package, \"H\", defaultFakeVersion));\n            }\n            if (input == \"DependenciesInstalled\")\n            {\n                installer.Dependencies.Add(Dependency(DependencyType::Package, \"installed1\", defaultFakeVersion));\n            }\n            if (input == \"DependenciesValidMinVersions\")\n            {\n                installer.Dependencies.Add(Dependency(DependencyType::Package, \"minVersion\", \"1.0\"));\n            }\n            if (input == \"DependenciesValidMinVersionsMultiple\")\n            {\n                installer.Dependencies.Add(Dependency(DependencyType::Package, \"minVersion\", \"1.0\"));\n                installer.Dependencies.Add(Dependency(DependencyType::Package, \"requires1.5\"));\n            }\n\n            return manifest;\n        }\n    }\n\n    struct DependenciesTestSource : public TestSource\n    {\n        SearchResult Search(const SearchRequest& request) const override\n        {\n            SearchResult result;\n\n            std::string input;\n\n            if (request.Query)\n            {\n                input = request.Query->Value;\n            }\n            else if (!request.Inclusions.empty())\n            {\n                input = request.Inclusions[0].Value;\n            }\n            else if (!request.Filters.empty())\n            {\n                input = request.Filters[0].Value;\n            }\n\n            bool installed = false;\n            if (input == \"installed1\")\n            {\n                installed  = true;\n            }\n\n            if (input == \"NoMatches\")\n            {\n                return result;\n            }\n\n            Manifest manifest;\n            if (input == \"MultipleDependenciesFromManifest\")\n            {\n                manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallFlowTest_MultipleDependencies.yaml\"));\n            }\n            else\n            {\n                manifest = CreateFakeManifestWithDependencies(input);\n            }\n\n            //TODO:\n            // test for installed packages and packages that need upgrades\n            // test for different min Version of dependencies\n            if (installed)\n            {\n                //auto manifest2 = YamlParser::CreateFromPath(TestDataFile(\"UpdateFlowTest_Exe.yaml\"));\n                result.Matches.emplace_back(\n                    ResultMatch(\n                        TestCompositePackage::Make(\n                            manifest,\n                            TestCompositePackage::MetadataMap{ { PackageVersionMetadata::InstalledType, \"Exe\" } },\n                            std::vector<Manifest>{ manifest },\n                            shared_from_this()\n                        ),\n                        PackageMatchFilter(PackageMatchField::Id, MatchType::CaseInsensitive, manifest.Id)));\n            }\n            else\n            {\n                result.Matches.emplace_back(\n                    ResultMatch(\n                        TestCompositePackage::Make(\n                            std::vector<Manifest>{ manifest },\n                            shared_from_this()\n                        ),\n                        PackageMatchFilter(PackageMatchField::Id, MatchType::CaseInsensitive, manifest.Id)));\n            }\n\n            return result;\n        }\n    };\n\n}\n"
  },
  {
    "path": "src/AppInstallerCLITests/DownloadFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestHooks.h\"\r\n#include \"AppInstallerRuntime.h\"\r\n#include \"WorkflowCommon.h\"\r\n#include <Commands/DownloadCommand.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller;\r\nusing namespace AppInstaller::Authentication;\r\nusing namespace AppInstaller::CLI;\r\n\r\nTEST_CASE(\"DownloadFlow_DownloadCommandProhibited\", \"[DownloadFlow][workflow]\")\r\n{\r\n    std::ostringstream downloadOutput;\r\n    TestContext context{ downloadOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"DownloadFlowTest_DownloadCommandProhibited.yaml\").GetPath().u8string());\r\n\r\n    DownloadCommand download({});\r\n    download.Execute(context);\r\n    INFO(downloadOutput.str());\r\n\r\n    // Verify AppInfo is printed\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_DOWNLOAD_COMMAND_PROHIBITED);\r\n    REQUIRE(downloadOutput.str().find(CLI::Resource::LocString(CLI::Resource::String::InstallerDownloadCommandProhibited).get()) != std::string::npos);\r\n}\r\n\r\nAppInstaller::Utility::DownloadResult ValidateAzureBlobStorageAuthHeaders(\r\n    const std::string&,\r\n    const std::filesystem::path& dest,\r\n    AppInstaller::Utility::DownloadType,\r\n    AppInstaller::IProgressCallback&,\r\n    std::optional<AppInstaller::Utility::DownloadInfo> info)\r\n{\r\n    REQUIRE(info);\r\n    REQUIRE(info->RequestHeaders.size() > 0);\r\n    REQUIRE(info->RequestHeaders[0].IsAuth);\r\n    REQUIRE(info->RequestHeaders[0].Name == \"Authorization\");\r\n    REQUIRE(info->RequestHeaders[0].Value == \"Bearer TestToken\");\r\n    REQUIRE_FALSE(info->RequestHeaders[1].IsAuth);\r\n    REQUIRE(info->RequestHeaders[1].Name == \"x-ms-version\");\r\n    // Not validating x-ms-version value\r\n\r\n    std::ofstream file(dest, std::ofstream::out);\r\n    file << \"test\";\r\n    file.close();\r\n\r\n    AppInstaller::Utility::DownloadResult result;\r\n    result.Sha256Hash = AppInstaller::Utility::SHA256::ConvertToBytes(\"65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\");\r\n    return result;\r\n}\r\n\r\nTEST_CASE(\"DownloadFlow_DownloadWithInstallerAuthenticationSuccess\", \"[DownloadFlow][workflow]\")\r\n{\r\n    if (Runtime::IsRunningAsSystem())\r\n    {\r\n        WARN(\"Test does not support running as system. Skipped.\");\r\n        return;\r\n    }\r\n\r\n    // Set authentication success result override\r\n    std::string expectedToken = \"TestToken\";\r\n    AuthenticationResult authResultOverride;\r\n    authResultOverride.Status = S_OK;\r\n    authResultOverride.Token = expectedToken;\r\n    TestHook::SetAuthenticationResult_Override setAuthenticationResultOverride(authResultOverride);\r\n\r\n    // Set auth header validation override\r\n    TestHook::SetDownloadResult_Function_Override downloadFunctionOverride({ &ValidateAzureBlobStorageAuthHeaders });\r\n\r\n    std::ostringstream downloadOutput;\r\n    TestContext context{ downloadOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"ManifestV1_10-InstallerAuthentication.yaml\").GetPath().u8string());\r\n    TestCommon::TempDirectory tempDirectory(\"TempDownload\");\r\n    context.Args.AddArg(Execution::Args::Type::DownloadDirectory, tempDirectory.GetPath().u8string());\r\n\r\n    DownloadCommand download({});\r\n    download.Execute(context);\r\n    INFO(downloadOutput.str());\r\n\r\n    // Verify success\r\n    REQUIRE_FALSE(context.IsTerminated());\r\n    REQUIRE(context.GetTerminationHR() == S_OK);\r\n}\r\n\r\nTEST_CASE(\"DownloadFlow_DownloadWithInstallerAuthenticationNotSupported\", \"[DownloadFlow][workflow]\")\r\n{\r\n    if (Runtime::IsRunningAsSystem())\r\n    {\r\n        WARN(\"Test does not support running as system. Skipped.\");\r\n        return;\r\n    }\r\n\r\n    // Set authentication failed result\r\n    AuthenticationResult authResultOverride;\r\n    authResultOverride.Status = APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED;\r\n    TestHook::SetAuthenticationResult_Override setAuthenticationResultOverride(authResultOverride);\r\n\r\n    std::ostringstream downloadOutput;\r\n    TestContext context{ downloadOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"ManifestV1_10-InstallerAuthentication.yaml\").GetPath().u8string());\r\n\r\n    DownloadCommand download({});\r\n    download.Execute(context);\r\n    INFO(downloadOutput.str());\r\n\r\n    // Verify AppInfo is printed\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED);\r\n    REQUIRE(downloadOutput.str().find(CLI::Resource::LocString(CLI::Resource::String::InstallerDownloadAuthenticationNotSupported).get()) != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"DownloadFlow_DownloadWithInstallerAuthenticationFailed\", \"[DownloadFlow][workflow]\")\r\n{\r\n    if (Runtime::IsRunningAsSystem())\r\n    {\r\n        WARN(\"Test does not support running as system. Skipped.\");\r\n        return;\r\n    }\r\n\r\n    // Set authentication failed result\r\n    AuthenticationResult authResultOverride;\r\n    authResultOverride.Status = APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED;\r\n    TestHook::SetAuthenticationResult_Override setAuthenticationResultOverride(authResultOverride);\r\n\r\n    std::ostringstream downloadOutput;\r\n    TestContext context{ downloadOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"ManifestV1_10-InstallerAuthentication.yaml\").GetPath().u8string());\r\n\r\n    DownloadCommand download({});\r\n    download.Execute(context);\r\n    INFO(downloadOutput.str());\r\n\r\n    // Verify AppInfo is printed\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED);\r\n    REQUIRE(downloadOutput.str().find(CLI::Resource::LocString(CLI::Resource::String::InstallerDownloadAuthenticationFailed).get()) != std::string::npos);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/Downloader.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"AppInstallerDownloader.h\"\r\n#include \"AppInstallerSHA256.h\"\r\n#include \"HttpStream/HttpLocalCache.h\"\r\n\r\nusing namespace AppInstaller;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace std::string_literals;\r\n\r\nTEST_CASE(\"DownloadValidFileAndVerifyHash\", \"[Downloader]\")\r\n{\r\n    TestCommon::TempFile tempFile(\"downloader_test\"s, \".test\"s);\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    // Todo: point to files from our repo when the repo goes public\r\n    ProgressCallback callback;\r\n    auto result = Download(\"https://raw.githubusercontent.com/microsoft/msix-packaging/master/LICENSE\", tempFile.GetPath(), DownloadType::Manifest, callback);\r\n\r\n    REQUIRE(!result.Sha256Hash.empty());\r\n    auto resultHash = result.Sha256Hash;\r\n\r\n    auto expectedHash = SHA256::ConvertToBytes(\"d2a45116709136462ee7a1c42f0e75f0efa258fe959b1504dc8ea4573451b759\");\r\n    REQUIRE(std::equal(\r\n        expectedHash.begin(),\r\n        expectedHash.end(),\r\n        resultHash.begin()));\r\n\r\n    uint64_t expectedFileSize = 1119;\r\n    REQUIRE(result.SizeInBytes == expectedFileSize);\r\n    REQUIRE(std::filesystem::file_size(tempFile.GetPath()) == expectedFileSize);\r\n\r\n    REQUIRE(result.ContentType);\r\n    REQUIRE(!result.ContentType.value().empty());\r\n\r\n    // Verify motw content\r\n    std::filesystem::path motwFile(tempFile);\r\n    motwFile += \":Zone.Identifier:$data\";\r\n    std::ifstream motwStream(motwFile);\r\n    std::stringstream motwContent;\r\n    motwContent << motwStream.rdbuf();\r\n    std::string motwContentStr = motwContent.str();\r\n    REQUIRE(motwContentStr.find(\"ZoneId=3\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"DownloadValidFileAndCancel\", \"[Downloader]\")\r\n{\r\n    TestCommon::TempFile tempFile(\"downloader_test\"s, \".test\"s);\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    ProgressCallback callback;\r\n\r\n    DownloadResult waitResult;\r\n    std::thread waitThread([&]\r\n        {\r\n            waitResult = Download(\"https://aka.ms/win32-x64-user-stable\", tempFile.GetPath(), DownloadType::Installer, callback);\r\n        });\r\n\r\n    callback.Cancel();\r\n\r\n    waitThread.join();\r\n\r\n    REQUIRE(waitResult.Sha256Hash.empty());\r\n}\r\n\r\nTEST_CASE(\"DownloadInvalidUrl\", \"[Downloader]\")\r\n{\r\n    TestCommon::TempFile tempFile(\"downloader_test\"s, \".test\"s);\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    ProgressCallback callback;\r\n\r\n    REQUIRE_THROWS(Download(\"blargle-flargle-fluff\", tempFile.GetPath(), DownloadType::Installer, callback));\r\n}\r\n\r\nTEST_CASE(\"HttpStream_ReadLastFullPage\", \"[HttpStream]\")\r\n{\r\n    Microsoft::WRL::ComPtr<IStream> stream;\r\n    STATSTG stat = { 0 };\r\n\r\n    for (size_t i = 0; i < 10; ++i)\r\n    {\r\n        stream = GetReadOnlyStreamFromURI(\"https://aka.ms/win32-x64-user-stable\");\r\n\r\n        stat = { 0 };\r\n        REQUIRE(stream->Stat(&stat, STATFLAG_NONAME) == S_OK);\r\n\r\n        if (stat.cbSize.QuadPart > 0)\r\n        {\r\n            break;\r\n        }\r\n\r\n        Sleep(500);\r\n    }\r\n\r\n    {\r\n        INFO(\"https://aka.ms/win32-x64-user-stable gave back a 0 byte file\");\r\n        REQUIRE(stream);\r\n    }\r\n\r\n    LARGE_INTEGER seek;\r\n    seek.QuadPart = (stat.cbSize.QuadPart / HttpStream::HttpLocalCache::PAGE_SIZE) * HttpStream::HttpLocalCache::PAGE_SIZE;\r\n    REQUIRE(stream->Seek(seek, STREAM_SEEK_SET, nullptr) == S_OK);\r\n\r\n    std::unique_ptr<BYTE[]> buffer = std::make_unique<BYTE[]>(HttpStream::HttpLocalCache::PAGE_SIZE);\r\n    ULONG read = 0;\r\n    REQUIRE(stream->Read(buffer.get(), static_cast<ULONG>(HttpStream::HttpLocalCache::PAGE_SIZE), &read) >= S_OK);\r\n    REQUIRE(read == (stat.cbSize.QuadPart % HttpStream::HttpLocalCache::PAGE_SIZE));\r\n}\r\n\r\nTEST_CASE(\"CacheControl\", \"[Downloader]\")\r\n{\r\n    SECTION(\"Empty\")\r\n    {\r\n        CacheControlPolicy test{ L\"\" };\r\n        REQUIRE(!test.Present);\r\n    }\r\n    SECTION(\"Space\")\r\n    {\r\n        CacheControlPolicy test{ L\" \" };\r\n        REQUIRE(!test.Present);\r\n    }\r\n    SECTION(\"Standard\")\r\n    {\r\n        CacheControlPolicy test{ L\"public, max-age=77287\" };\r\n        REQUIRE(test.Present);\r\n        REQUIRE(test.Public);\r\n        REQUIRE(!test.NoCache);\r\n        REQUIRE(!test.NoStore);\r\n        REQUIRE(test.MaxAge == 77287);\r\n    }\r\n    SECTION(\"All\")\r\n    {\r\n        CacheControlPolicy test{ L\"public, no-cache, no-store, max-age = 77\" };\r\n        REQUIRE(test.Present);\r\n        REQUIRE(test.Public);\r\n        REQUIRE(test.NoCache);\r\n        REQUIRE(test.NoStore);\r\n        REQUIRE(test.MaxAge == 77);\r\n    }\r\n    SECTION(\"Casing\")\r\n    {\r\n        CacheControlPolicy test{ L\"Public, Max-Age=42\" };\r\n        REQUIRE(test.Present);\r\n        REQUIRE(test.Public);\r\n        REQUIRE(!test.NoCache);\r\n        REQUIRE(!test.NoStore);\r\n        REQUIRE(test.MaxAge == 42);\r\n    }\r\n    SECTION(\"Unknown\")\r\n    {\r\n        CacheControlPolicy test{ L\"public, max-age=77287, not-real\" };\r\n        REQUIRE(test.Present);\r\n        REQUIRE(test.Public);\r\n        REQUIRE(!test.NoCache);\r\n        REQUIRE(!test.NoStore);\r\n        REQUIRE(test.MaxAge == 77287);\r\n    }\r\n    SECTION(\"MaxAge Negative\")\r\n    {\r\n        CacheControlPolicy test{ L\"max-age=-1\" };\r\n        REQUIRE(test.MaxAge == CacheControlPolicy::MaximumMaxAge);\r\n    }\r\n    SECTION(\"MaxAge not a number\")\r\n    {\r\n        CacheControlPolicy test{ L\"max-age=FOO\" };\r\n        REQUIRE(test.MaxAge == 0);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/Errors.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <AppInstallerErrors.h>\r\n\r\nusing namespace AppInstaller;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace std::string_literals;\r\n\r\nTEST_CASE(\"EnsureSortedErrorList\", \"[errors]\")\r\n{\r\n    auto errors = Errors::GetWinGetErrors();\r\n    for (size_t i = 1; i < errors.size(); ++i)\r\n    {\r\n        INFO(errors[i - 1]->Symbol() << \" then \" << errors[i]->Symbol());\r\n        REQUIRE(errors[i]->Value() > errors[i - 1]->Value());\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/ExperimentalFeature.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"TestCommon.h\"\n#include \"TestSettings.h\"\n#include <winget/ExperimentalFeature.h>\n#include <winget/Settings.h>\n\n#include <AppInstallerErrors.h>\n\nusing namespace AppInstaller::Settings;\nusing namespace TestCommon;\n\nTEST_CASE(\"ExperimentalFeature None\", \"[experimentalFeature]\")\n{\n    // Make sure Feature::None is always enabled.\n    REQUIRE(ExperimentalFeature::IsEnabled(ExperimentalFeature::Feature::None));\n\n    // Make sure to throw requesting Feature::None\n    REQUIRE_THROWS_HR(ExperimentalFeature::GetFeature(ExperimentalFeature::Feature::None), E_UNEXPECTED);\n\n    // Make sure Feature::None is not disabled by Group Policy\n    auto policiesKey = RegCreateVolatileTestRoot();\n    SetRegistryValue(policiesKey.get(), ExperimentalFeaturesPolicyValueName, false);\n    GroupPolicyTestOverride policies{ policiesKey.get() };\n    REQUIRE(ExperimentalFeature::IsEnabled(ExperimentalFeature::Feature::None));\n}\n\nTEST_CASE(\"ExperimentalFeature ExperimentalCmd\", \"[experimentalFeature]\")\n{\n    auto again = DeleteUserSettingsFiles();\n\n    SECTION(\"Feature off default\")\n    {\n        UserSettingsTest userSettingTest;\r\n\n        REQUIRE_FALSE(ExperimentalFeature::IsEnabled(ExperimentalFeature::Feature::ExperimentalCmd, userSettingTest));\n    }\n    SECTION(\"Feature on\")\n    {\n        std::string_view json = R\"({ \"experimentalFeatures\": { \"experimentalCmd\": true } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\r\n\n        REQUIRE(ExperimentalFeature::IsEnabled(ExperimentalFeature::Feature::ExperimentalCmd, userSettingTest));\n    }\n    SECTION(\"Feature off\")\n    {\n        std::string_view json = R\"({ \"experimentalFeatures\": { \"experimentalCmd\": false } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\r\n\n        REQUIRE_FALSE(ExperimentalFeature::IsEnabled(ExperimentalFeature::Feature::ExperimentalCmd, userSettingTest));\n    }\n    SECTION(\"Invalid value\")\n    {\n        std::string_view json = R\"({ \"experimentalFeatures\": { \"experimentalCmd\": \"string\" } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\r\n\n        REQUIRE_FALSE(ExperimentalFeature::IsEnabled(ExperimentalFeature::Feature::ExperimentalCmd, userSettingTest));\n    }\n    SECTION(\"Disabled by group policy\")\n    {\n        auto policiesKey = RegCreateVolatileTestRoot();\n        SetRegistryValue(policiesKey.get(), ExperimentalFeaturesPolicyValueName, false);\n        GroupPolicyTestOverride policies{ policiesKey.get() };\n\n        std::string_view json = R\"({ \"experimentalFeatures\": { \"experimentalCmd\": true } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\r\n\n        REQUIRE_FALSE(ExperimentalFeature::IsEnabled(ExperimentalFeature::Feature::ExperimentalCmd, userSettingTest));\n    }\n}"
  },
  {
    "path": "src/AppInstallerCLITests/ExportFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"WorkflowCommon.h\"\r\n#include <Commands/ExportCommand.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::CLI;\r\n\r\nTEST_CASE(\"ExportFlow_ExportAll\", \"[ExportFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile exportResultPath(\"TestExport.json\");\r\n\r\n    std::ostringstream exportOutput;\r\n    TestContext context{ exportOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({\r\n        TSR::TestInstaller_Exe,\r\n        TSR::TestInstaller_Exe_UnknownVersion,\r\n        TSR::TestInstaller_Msix,\r\n        TSR::TestInstaller_MSStore,\r\n        TSR::TestInstaller_Portable,\r\n        TSR::TestInstaller_Zip,\r\n        }));\r\n    context.Args.AddArg(Execution::Args::Type::OutputFile, exportResultPath);\r\n\r\n    ExportCommand exportCommand({});\r\n    exportCommand.Execute(context);\r\n    INFO(exportOutput.str());\r\n\r\n    // Verify contents of exported collection\r\n    const auto& exportedCollection = context.Get<Execution::Data::PackageCollection>();\r\n    REQUIRE(exportedCollection.Sources.size() == 1);\r\n    REQUIRE(exportedCollection.Sources[0].Details.Identifier == \"*TestSource\");\r\n\r\n    const auto& exportedPackages = exportedCollection.Sources[0].Packages;\r\n    REQUIRE(exportedPackages.size() == 6);\r\n    REQUIRE(exportedPackages.end() != std::find_if(exportedPackages.begin(), exportedPackages.end(), [](const auto& p)\r\n        {\r\n            return p.Id == \"AppInstallerCliTest.TestExeInstaller\" && p.VersionAndChannel.GetVersion().ToString().empty();\r\n        }));\r\n    REQUIRE(exportedPackages.end() != std::find_if(exportedPackages.begin(), exportedPackages.end(), [](const auto& p)\r\n        {\r\n            return p.Id == \"AppInstallerCliTest.TestMsixInstaller\" && p.VersionAndChannel.GetVersion().ToString().empty();\r\n        }));\r\n    REQUIRE(exportedPackages.end() != std::find_if(exportedPackages.begin(), exportedPackages.end(), [](const auto& p)\r\n        {\r\n            return p.Id == \"AppInstallerCliTest.TestMSStoreInstaller\" && p.VersionAndChannel.GetVersion().ToString().empty();\r\n        }));\r\n    REQUIRE(exportedPackages.end() != std::find_if(exportedPackages.begin(), exportedPackages.end(), [](const auto& p)\r\n        {\r\n            return p.Id == \"AppInstallerCliTest.TestPortableInstaller\" && p.VersionAndChannel.GetVersion().ToString().empty();\r\n        }));\r\n    REQUIRE(exportedPackages.end() != std::find_if(exportedPackages.begin(), exportedPackages.end(), [](const auto& p)\r\n        {\r\n            return p.Id == \"AppInstallerCliTest.TestZipInstaller\" && p.VersionAndChannel.GetVersion().ToString().empty();\r\n        }));\r\n    REQUIRE(exportedPackages.end() != std::find_if(exportedPackages.begin(), exportedPackages.end(), [](const auto& p)\r\n        {\r\n            return p.Id == \"AppInstallerCliTest.TestExeUnknownVersion\" && p.VersionAndChannel.GetVersion().ToString().empty();\r\n        }));\r\n}\r\n\r\nTEST_CASE(\"ExportFlow_ExportAll_WithVersions\", \"[ExportFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile exportResultPath(\"TestExport.json\");\r\n\r\n    std::ostringstream exportOutput;\r\n    TestContext context{ exportOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({\r\n        TSR::TestInstaller_Exe,\r\n        TSR::TestInstaller_Exe_UnknownVersion,\r\n        TSR::TestInstaller_Msix,\r\n        TSR::TestInstaller_MSStore,\r\n        TSR::TestInstaller_Portable,\r\n        TSR::TestInstaller_Zip,\r\n        }));\r\n    context.Args.AddArg(Execution::Args::Type::OutputFile, exportResultPath);\r\n    context.Args.AddArg(Execution::Args::Type::IncludeVersions);\r\n\r\n    ExportCommand exportCommand({});\r\n    exportCommand.Execute(context);\r\n    INFO(exportOutput.str());\r\n\r\n    // Verify contents of exported collection\r\n    const auto& exportedCollection = context.Get<Execution::Data::PackageCollection>();\r\n    REQUIRE(exportedCollection.Sources.size() == 1);\r\n    REQUIRE(exportedCollection.Sources[0].Details.Identifier == \"*TestSource\");\r\n\r\n    const auto& exportedPackages = exportedCollection.Sources[0].Packages;\r\n    REQUIRE(exportedPackages.size() == 6);\r\n    REQUIRE(exportedPackages.end() != std::find_if(exportedPackages.begin(), exportedPackages.end(), [](const auto& p)\r\n        {\r\n            return p.Id == \"AppInstallerCliTest.TestExeInstaller\" && p.VersionAndChannel.GetVersion().ToString() == \"1.0.0.0\";\r\n        }));\r\n    REQUIRE(exportedPackages.end() != std::find_if(exportedPackages.begin(), exportedPackages.end(), [](const auto& p)\r\n        {\r\n            return p.Id == \"AppInstallerCliTest.TestMsixInstaller\" && p.VersionAndChannel.GetVersion().ToString() == \"1.0.0.0\";\r\n        }));\r\n    REQUIRE(exportedPackages.end() != std::find_if(exportedPackages.begin(), exportedPackages.end(), [](const auto& p)\r\n        {\r\n            return p.Id == \"AppInstallerCliTest.TestMSStoreInstaller\" && p.VersionAndChannel.GetVersion().ToString() == \"1.0.0.0\";\r\n        }));\r\n    REQUIRE(exportedPackages.end() != std::find_if(exportedPackages.begin(), exportedPackages.end(), [](const auto& p)\r\n        {\r\n            return p.Id == \"AppInstallerCliTest.TestPortableInstaller\" && p.VersionAndChannel.GetVersion().ToString() == \"1.0.0.0\";\r\n        }));\r\n    REQUIRE(exportedPackages.end() != std::find_if(exportedPackages.begin(), exportedPackages.end(), [](const auto& p)\r\n        {\r\n            return p.Id == \"AppInstallerCliTest.TestZipInstaller\" && p.VersionAndChannel.GetVersion().ToString() == \"1.0.0.0\";\r\n        }));\r\n    REQUIRE(exportedPackages.end() != std::find_if(exportedPackages.begin(), exportedPackages.end(), [](const auto& p)\r\n        {\r\n            return p.Id == \"AppInstallerCliTest.TestExeUnknownVersion\" && p.VersionAndChannel.GetVersion().ToString() == \"unknown\";\r\n        }));\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/FileCache.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <AppInstallerStrings.h>\r\n#include <winget/FileCache.h>\r\n\r\nusing namespace AppInstaller::Caching;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace TestCommon;\r\n\r\nstruct TestFileCache\r\n{\r\n    struct UpstreamFileInfo\r\n    {\r\n        TestDataFile OriginalFile;\r\n        std::filesystem::path Offset;\r\n        std::filesystem::path UpstreamPath;\r\n        std::vector<uint8_t> Contents;\r\n        SHA256::HashBuffer ContentHash;\r\n    };\r\n\r\n    TestFileCache(std::string identifier = {}, size_t upstreamCount = 1)\r\n    {\r\n        if (identifier.empty())\r\n        {\r\n            identifier = ConvertToUTF8(CreateNewGuidNameWString());\r\n        }\r\n\r\n        std::vector<std::string> upstreamStrings;\r\n\r\n        for (size_t i = 0; i < upstreamCount; ++i)\r\n        {\r\n            UpstreamSources.emplace_back(\"TestFileCache\");\r\n            upstreamStrings.emplace_back(UpstreamSources.back().GetPath().u8string());\r\n        }\r\n\r\n        CachePtr = std::make_unique<FileCache>(FileCache::Type::Tests, std::move(identifier), std::move(upstreamStrings));\r\n    }\r\n\r\n    FileCache& Cache() { return *CachePtr; }\r\n    FileCache* operator->() { return CachePtr.get(); }\r\n\r\n    UpstreamFileInfo PrepareUpstreamFile(const std::filesystem::path& testDataFile, const std::filesystem::path& offset = {}, size_t index = 0)\r\n    {\r\n        UpstreamFileInfo result{ testDataFile };\r\n\r\n        auto dataFilePath = result.OriginalFile.GetPath();\r\n\r\n        result.Offset = offset.empty() ? dataFilePath.filename() : offset;\r\n        result.UpstreamPath = UpstreamSources[index].GetPath() / result.Offset;\r\n\r\n        std::filesystem::copy_file(dataFilePath, result.UpstreamPath);\r\n\r\n        std::ifstream fileStream{ dataFilePath, std::ios_base::in | std::ios_base::binary };\r\n        result.Contents = ReadEntireStreamAsByteArray(fileStream);\r\n\r\n        result.ContentHash = SHA256::ComputeHash(result.Contents);\r\n\r\n        return result;\r\n    }\r\n\r\n    std::filesystem::path GetCacheFilePath(const UpstreamFileInfo& upstreamFileInfo)\r\n    {\r\n        std::filesystem::path result = CachePtr->GetDetails().GetCachePath() / upstreamFileInfo.Offset;\r\n        std::filesystem::create_directories(result.parent_path());\r\n        return result;\r\n    }\r\n\r\n    std::unique_ptr<std::istream> GetFile(const UpstreamFileInfo& upstreamFileInfo)\r\n    {\r\n        return CachePtr->GetFile(upstreamFileInfo.Offset, upstreamFileInfo.ContentHash);\r\n    }\r\n\r\n    void RequireCachedFile(const UpstreamFileInfo& upstreamFileInfo)\r\n    {\r\n        std::filesystem::path cachedFilePath = GetCacheFilePath(upstreamFileInfo);\r\n        REQUIRE(std::filesystem::is_regular_file(cachedFilePath));\r\n        REQUIRE(SHA256::AreEqual(upstreamFileInfo.ContentHash, SHA256::ComputeHashFromFile(cachedFilePath)));\r\n    }\r\n\r\n    std::unique_ptr<FileCache> CachePtr;\r\n    std::vector<TempDirectory> UpstreamSources;\r\n};\r\n\r\nTEST_CASE(\"FileCache_TypeLocationsDiffer\", \"[file_cache]\")\r\n{\r\n    std::string identifier = \"identifier\";\r\n    std::string identifier2 = \"identifier2\";\r\n\r\n    REQUIRE(FileCache(FileCache::Type::IndexV1_Manifest, identifier, {}).GetDetails().GetCachePath() != FileCache(FileCache::Type::IndexV2_Manifest, identifier, {}).GetDetails().GetCachePath());\r\n    REQUIRE(FileCache(FileCache::Type::IndexV1_Manifest, identifier, {}).GetDetails().GetCachePath() != FileCache(FileCache::Type::IndexV2_PackageVersionData, identifier, {}).GetDetails().GetCachePath());\r\n    REQUIRE(FileCache(FileCache::Type::IndexV2_Manifest, identifier, {}).GetDetails().GetCachePath() != FileCache(FileCache::Type::IndexV2_PackageVersionData, identifier, {}).GetDetails().GetCachePath());\r\n\r\n    REQUIRE(FileCache(FileCache::Type::IndexV1_Manifest, identifier, {}).GetDetails().GetCachePath() != FileCache(FileCache::Type::IndexV1_Manifest, identifier2, {}).GetDetails().GetCachePath());\r\n    REQUIRE(FileCache(FileCache::Type::IndexV2_Manifest, identifier, {}).GetDetails().GetCachePath() != FileCache(FileCache::Type::IndexV2_Manifest, identifier2, {}).GetDetails().GetCachePath());\r\n    REQUIRE(FileCache(FileCache::Type::IndexV2_PackageVersionData, identifier, {}).GetDetails().GetCachePath() != FileCache(FileCache::Type::IndexV2_PackageVersionData, identifier2, {}).GetDetails().GetCachePath());\r\n}\r\n\r\nTEST_CASE(\"FileCache_TypeLocationsSame\", \"[file_cache]\")\r\n{\r\n    std::string identifier = \"identifier\";\r\n    std::string source = \"source\";\r\n\r\n    REQUIRE(FileCache(FileCache::Type::IndexV1_Manifest, identifier, {}).GetDetails().GetCachePath() == FileCache(FileCache::Type::IndexV1_Manifest, identifier, { source }).GetDetails().GetCachePath());\r\n    REQUIRE(FileCache(FileCache::Type::IndexV2_Manifest, identifier, {}).GetDetails().GetCachePath() == FileCache(FileCache::Type::IndexV2_Manifest, identifier, { source }).GetDetails().GetCachePath());\r\n    REQUIRE(FileCache(FileCache::Type::IndexV2_PackageVersionData, identifier, {}).GetDetails().GetCachePath() == FileCache(FileCache::Type::IndexV2_PackageVersionData, identifier, { source }).GetDetails().GetCachePath());\r\n}\r\n\r\nTEST_CASE(\"FileCache_NoCachedFile\", \"[file_cache]\")\r\n{\r\n    TestFileCache testFileCache;\r\n    INFO(\"Cache location: \" << testFileCache->GetDetails().GetCachePath().u8string());\r\n\r\n    auto sourceFile = testFileCache.PrepareUpstreamFile(\"Manifest-Good-SystemReferenceComplex.yaml\");\r\n\r\n    auto cachedStream = testFileCache.GetFile(sourceFile);\r\n\r\n    REQUIRE(cachedStream);\r\n    REQUIRE(SHA256::AreEqual(sourceFile.ContentHash, SHA256::ComputeHash(ReadEntireStreamAsByteArray(*cachedStream))));\r\n\r\n    testFileCache.RequireCachedFile(sourceFile);\r\n}\r\n\r\nTEST_CASE(\"FileCache_CachedFileIsDirectory\", \"[file_cache]\")\r\n{\r\n    TestFileCache testFileCache;\r\n    INFO(\"Cache location: \" << testFileCache->GetDetails().GetCachePath().u8string());\r\n\r\n    auto sourceFile = testFileCache.PrepareUpstreamFile(\"Manifest-Good.yaml\");\r\n    std::filesystem::create_directories(testFileCache.GetCacheFilePath(sourceFile));\r\n\r\n    auto cachedStream = testFileCache.GetFile(sourceFile);\r\n\r\n    REQUIRE(cachedStream);\r\n    REQUIRE(SHA256::AreEqual(sourceFile.ContentHash, SHA256::ComputeHash(ReadEntireStreamAsByteArray(*cachedStream))));\r\n\r\n    testFileCache.RequireCachedFile(sourceFile);\r\n}\r\n\r\nTEST_CASE(\"FileCache_CachedFileGoodHash\", \"[file_cache]\")\r\n{\r\n    TestFileCache testFileCache;\r\n    INFO(\"Cache location: \" << testFileCache->GetDetails().GetCachePath().u8string());\r\n\r\n    auto sourceFile = testFileCache.PrepareUpstreamFile(\"InstallFlowTest_MSStore.yaml\");\r\n    std::filesystem::copy_file(sourceFile.OriginalFile, testFileCache.GetCacheFilePath(sourceFile));\r\n\r\n    auto cachedStream = testFileCache.GetFile(sourceFile);\r\n\r\n    REQUIRE(cachedStream);\r\n    REQUIRE(SHA256::AreEqual(sourceFile.ContentHash, SHA256::ComputeHash(ReadEntireStreamAsByteArray(*cachedStream))));\r\n\r\n    testFileCache.RequireCachedFile(sourceFile);\r\n}\r\n\r\nTEST_CASE(\"FileCache_CachedFileBadHash\", \"[file_cache]\")\r\n{\r\n    TestFileCache testFileCache;\r\n    INFO(\"Cache location: \" << testFileCache->GetDetails().GetCachePath().u8string());\r\n\r\n    auto sourceFile = testFileCache.PrepareUpstreamFile(\"ManifestV1-MultiFile-Version.yaml\");\r\n    std::filesystem::copy_file(TestDataFile(\"Manifest-Bad-ProductCodeOnMSIX.yaml\"), testFileCache.GetCacheFilePath(sourceFile));\r\n\r\n    auto cachedStream = testFileCache.GetFile(sourceFile);\r\n\r\n    REQUIRE(cachedStream);\r\n    REQUIRE(SHA256::AreEqual(sourceFile.ContentHash, SHA256::ComputeHash(ReadEntireStreamAsByteArray(*cachedStream))));\r\n\r\n    testFileCache.RequireCachedFile(sourceFile);\r\n}\r\n\r\nTEST_CASE(\"FileCache_CachedFileLockedExclusive\", \"[file_cache]\")\r\n{\r\n    TestFileCache testFileCache;\r\n    INFO(\"Cache location: \" << testFileCache->GetDetails().GetCachePath().u8string());\r\n\r\n    auto sourceFile = testFileCache.PrepareUpstreamFile(\"ManifestV1-MultiFile-Installer.yaml\");\r\n    TestDataFile wrongFileOriginal = TestDataFile(\"Manifest-Bad-InvalidLocale.yaml\");\r\n    std::filesystem::path wrongFilePath = testFileCache.GetCacheFilePath(sourceFile);\r\n    std::filesystem::copy_file(wrongFileOriginal, wrongFilePath);\r\n    wil::unique_handle exclusiveFileHandle{ CreateFileW(wrongFilePath.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL) };\r\n\r\n    auto cachedStream = testFileCache.GetFile(sourceFile);\r\n\r\n    REQUIRE(cachedStream);\r\n    REQUIRE(SHA256::AreEqual(sourceFile.ContentHash, SHA256::ComputeHash(ReadEntireStreamAsByteArray(*cachedStream))));\r\n}\r\n\r\nTEST_CASE(\"FileCache_FirstUpstreamDoesNotHaveFile\", \"[file_cache]\")\r\n{\r\n    TestFileCache testFileCache({}, 2);\r\n    INFO(\"Cache location: \" << testFileCache->GetDetails().GetCachePath().u8string());\r\n\r\n    auto sourceFile = testFileCache.PrepareUpstreamFile(\"Manifest-Good-MultiLocale.yaml\", {}, 1);\r\n\r\n    auto cachedStream = testFileCache.GetFile(sourceFile);\r\n\r\n    REQUIRE(cachedStream);\r\n    REQUIRE(SHA256::AreEqual(sourceFile.ContentHash, SHA256::ComputeHash(ReadEntireStreamAsByteArray(*cachedStream))));\r\n\r\n    testFileCache.RequireCachedFile(sourceFile);\r\n}\r\n\r\nTEST_CASE(\"FileCache_FirstUpstreamHasBadHash\", \"[file_cache]\")\r\n{\r\n    TestFileCache testFileCache({}, 2);\r\n    INFO(\"Cache location: \" << testFileCache->GetDetails().GetCachePath().u8string());\r\n\r\n    auto badFile = testFileCache.PrepareUpstreamFile(\"Manifest-Bad-VersionMissing.yaml\", {}, 0);\r\n    auto sourceFile = testFileCache.PrepareUpstreamFile(\"Manifest-Good-MultiLocale.yaml\", {}, 1);\r\n\r\n    auto cachedStream = testFileCache.GetFile(sourceFile);\r\n\r\n    REQUIRE(cachedStream);\r\n    REQUIRE(SHA256::AreEqual(sourceFile.ContentHash, SHA256::ComputeHash(ReadEntireStreamAsByteArray(*cachedStream))));\r\n\r\n    testFileCache.RequireCachedFile(sourceFile);\r\n}\r\n\r\nTEST_CASE(\"FileCache_NoUpstreamSources\", \"[file_cache]\")\r\n{\r\n    TestFileCache testFileCache(\"\", 0);\r\n    INFO(\"Cache location: \" << testFileCache->GetDetails().GetCachePath().u8string());\r\n\r\n    REQUIRE_THROWS_HR(testFileCache->GetFile(\"any_file\", SHA256::ComputeHash(\"garbage\")), E_NOT_SET);\r\n}\r\n\r\nTEST_CASE(\"FileCache_PathTooLong\", \"[file_cache]\")\r\n{\r\n    TestFileCache testFileCache(std::string(260, 'a'));\r\n    INFO(\"Cache location: \" << testFileCache->GetDetails().GetCachePath().u8string());\r\n\r\n    auto sourceFile = testFileCache.PrepareUpstreamFile(\"Manifest-Good-SystemReferenceComplex.yaml\");\r\n\r\n    auto cachedStream = testFileCache.GetFile(sourceFile);\r\n\r\n    REQUIRE(cachedStream);\r\n    REQUIRE(SHA256::AreEqual(sourceFile.ContentHash, SHA256::ComputeHash(ReadEntireStreamAsByteArray(*cachedStream))));\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/FileLogger.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <AppInstallerFileLogger.h>\r\n#include <AppInstallerStrings.h>\r\n\r\nusing namespace AppInstaller::Logging;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace TestCommon;\r\n\r\n\r\nstd::string GetHeaderString()\r\n{\r\n    return \"TIME [CHAN] Header Message\";\r\n}\r\n\r\nstd::string GetLargeString()\r\n{\r\n    return \"[===|Clearly defined start to large string|===]\\r\\n\"\r\n        \"While this string does not need to be particularly unique, it is still good if it is not easily duplicated by any other random set of data.\\r\\n\"\r\n        \"It should also end in a character that is not used in any other way within these tests, so please don't include that character when writing tests.\\r\\n\"\r\n        \"That character is &\";\r\n}\r\n\r\nnamespace\r\n{\r\n#define WINGET_DEFINE_STRING_ENUM(_enum_,_value_) constexpr std::string_view _enum_##_##_value_ = #_value_##sv\r\n\r\n    WINGET_DEFINE_STRING_ENUM(TagState, Unset);\r\n    WINGET_DEFINE_STRING_ENUM(TagState, SetAtStart);\r\n    WINGET_DEFINE_STRING_ENUM(TagState, SetAfterLogging);\r\n\r\n    WINGET_DEFINE_STRING_ENUM(MaximumSizeState, Zero);\r\n    WINGET_DEFINE_STRING_ENUM(MaximumSizeState, SmallerThanLargeString);\r\n    WINGET_DEFINE_STRING_ENUM(MaximumSizeState, EqualToLargeString);\r\n    WINGET_DEFINE_STRING_ENUM(MaximumSizeState, SlightlyLargerThanLargeString);\r\n    WINGET_DEFINE_STRING_ENUM(MaximumSizeState, MuchLargerThanLargeString);\r\n\r\n    constexpr std::string_view WrapIndicator = \"--- log file has wrapped ---\"sv;\r\n    // The amount of extra size that is allowed (total indicator size + newline + newlines from test strings)\r\n    constexpr size_t ExtraAllowedSize = 68;\r\n\r\n    constexpr size_t NewLineCharacterCount = 2;\r\n    constexpr size_t SmallDifferenceSize = 10;\r\n    constexpr AppInstaller::Logging::Channel DefaultChannel = AppInstaller::Logging::Channel::Core;\r\n    constexpr AppInstaller::Logging::Level DefaultLevel = AppInstaller::Logging::Level::Info;\r\n\r\n    void ValidateFileContents(const std::filesystem::path& file, const std::vector<std::string_view>& expectedContents, size_t maximumSize)\r\n    {\r\n        std::ifstream fileStream{ file, std::ios::binary };\r\n        auto fileContents = ReadEntireStream(fileStream);\r\n        std::string_view fileContentsView = fileContents;\r\n\r\n        std::string fileContentsCopy = fileContents;\r\n        FindAndReplace(fileContentsCopy, \"\\r\", \"\\\\r\");\r\n        FindAndReplace(fileContentsCopy, \"\\n\", \"\\\\n\");\r\n        INFO(\"File contents:\\n\" << fileContentsCopy);\r\n\r\n        if (maximumSize)\r\n        {\r\n            REQUIRE(maximumSize + ExtraAllowedSize >= fileContents.size());\r\n        }\r\n\r\n        size_t currentPosition = 0;\r\n        for (std::string_view expectedContent : expectedContents)\r\n        {\r\n            REQUIRE(currentPosition < fileContents.size());\r\n\r\n            if (expectedContent == WrapIndicator)\r\n            {\r\n                auto endLinePosition = fileContentsView.find('\\n', currentPosition);\r\n                REQUIRE(endLinePosition != -1);\r\n                REQUIRE(endLinePosition >= expectedContent.size() + NewLineCharacterCount);\r\n                auto actualContent = fileContentsView.substr(endLinePosition + 1 - expectedContent.size() - NewLineCharacterCount, expectedContent.size());\r\n                REQUIRE(expectedContent == actualContent);\r\n                currentPosition = endLinePosition + 1;\r\n            }\r\n            else\r\n            {\r\n                auto actualContent = fileContentsView.substr(currentPosition, expectedContent.size());\r\n                REQUIRE(expectedContent == actualContent);\r\n                currentPosition += expectedContent.size() + NewLineCharacterCount;\r\n            }\r\n        }\r\n    }\r\n\r\n    void FileLogger_MaximumSize_Test(std::string_view tagState, std::string_view sizeState)\r\n    {\r\n        auto headerString = GetHeaderString();\r\n        auto largeString = GetLargeString();\r\n\r\n        // Determine maximum size\r\n        size_t maximumSize = 0;\r\n\r\n        if (sizeState == MaximumSizeState_SmallerThanLargeString)\r\n        {\r\n            maximumSize = largeString.size() - SmallDifferenceSize;\r\n        }\r\n        else if (sizeState == MaximumSizeState_EqualToLargeString)\r\n        {\r\n            maximumSize = largeString.size();\r\n        }\r\n        else if (sizeState == MaximumSizeState_SlightlyLargerThanLargeString)\r\n        {\r\n            maximumSize = largeString.size() + SmallDifferenceSize;\r\n        }\r\n        else if (sizeState == MaximumSizeState_MuchLargerThanLargeString)\r\n        {\r\n            maximumSize = largeString.size() * 2;\r\n        }\r\n\r\n        INFO(\"Tag State: \" << tagState << \", Size State: \" << sizeState << \"[\" << maximumSize << \"]\");\r\n\r\n        TempFile tempFile{ \"FileLogger_MaximumSize\", \".log\" };\r\n        FileLogger logger{ tempFile };\r\n\r\n        INFO(\"File: \" << tempFile.GetPath().u8string());\r\n\r\n        logger.SetMaximumSize(wil::safe_cast<std::ofstream::off_type>(maximumSize));\r\n\r\n        // Set tag and log strings\r\n        size_t tagPosition = 0;\r\n        if (tagState == TagState_SetAtStart)\r\n        {\r\n            logger.SetTag(Tag::HeadersComplete);\r\n        }\r\n\r\n        logger.WriteDirect(DefaultChannel, DefaultLevel, headerString);\r\n\r\n        if (tagState == TagState_SetAfterLogging)\r\n        {\r\n            logger.SetTag(Tag::HeadersComplete);\r\n            tagPosition = headerString.size() + NewLineCharacterCount;\r\n        }\r\n\r\n        // Due to text output in the logger, log with \\n only\r\n        std::string largeStringWithoutCarriageReturn = largeString;\r\n        FindAndReplace(largeStringWithoutCarriageReturn, \"\\r\\n\", \"\\n\");\r\n\r\n        logger.WriteDirect(DefaultChannel, DefaultLevel, largeStringWithoutCarriageReturn);\r\n\r\n        // Calculate current state\r\n        size_t maximumAvailableSpace = std::numeric_limits<size_t>::max();\r\n        size_t currentAvailableSpace = std::numeric_limits<size_t>::max();\r\n        if (maximumSize)\r\n        {\r\n            maximumAvailableSpace = maximumSize - tagPosition;\r\n            currentAvailableSpace = maximumSize - headerString.size() - NewLineCharacterCount;\r\n        }\r\n\r\n        bool shouldWrap = largeString.size() > currentAvailableSpace;\r\n\r\n        INFO(\"Maximum Available: \" << maximumAvailableSpace << \", Current Available: \" << currentAvailableSpace << \", ShouldWrap: \" << shouldWrap);\r\n\r\n        std::vector<std::string_view> expectedFileContents;\r\n\r\n        if (tagPosition || !shouldWrap)\r\n        {\r\n            expectedFileContents.push_back(headerString);\r\n        }\r\n\r\n        if (shouldWrap)\r\n        {\r\n            expectedFileContents.push_back(WrapIndicator);\r\n        }\r\n\r\n        std::string_view largeStringView = largeString;\r\n        expectedFileContents.push_back(largeStringView.substr(0, std::min(largeString.size(), maximumAvailableSpace)));\r\n\r\n        ValidateFileContents(tempFile, expectedFileContents, maximumSize);\r\n\r\n        // Log again\r\n        INFO(\"Second time logging large string\");\r\n        logger.WriteDirect(DefaultChannel, DefaultLevel, largeStringWithoutCarriageReturn);\r\n\r\n        // The maximum size is twice the large log, so anything with a limit will wrap\r\n        shouldWrap = maximumSize != 0;\r\n\r\n        expectedFileContents.clear();\r\n\r\n        if (tagPosition || !shouldWrap)\r\n        {\r\n            expectedFileContents.push_back(headerString);\r\n        }\r\n\r\n        if (shouldWrap)\r\n        {\r\n            expectedFileContents.push_back(WrapIndicator);\r\n        }\r\n        else\r\n        {\r\n            expectedFileContents.push_back(largeStringView);\r\n        }\r\n\r\n        expectedFileContents.push_back(largeStringView.substr(0, std::min(largeString.size(), maximumAvailableSpace)));\r\n\r\n        ValidateFileContents(tempFile, expectedFileContents, maximumSize);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"FileLogger_MaximumSize\", \"[logging]\")\r\n{\r\n    auto tagState = GENERATE(TagState_Unset, TagState_SetAtStart, TagState_SetAfterLogging);\r\n    auto sizeState = GENERATE(MaximumSizeState_Zero, MaximumSizeState_SmallerThanLargeString, MaximumSizeState_EqualToLargeString, MaximumSizeState_SlightlyLargerThanLargeString, MaximumSizeState_MuchLargerThanLargeString);\r\n    FileLogger_MaximumSize_Test(tagState, sizeState);\r\n}\r\n\r\nTEST_CASE(\"FileLogger_MaximumSize_ManyWraps\", \"[logging]\")\r\n{\r\n    TempFile tempFile{ \"FileLogger_ManyWraps\", \".log\" };\r\n    FileLogger logger{ tempFile };\r\n\r\n    INFO(\"File: \" << tempFile.GetPath().u8string());\r\n\r\n    size_t maximumSize = 1000;\r\n    logger.SetMaximumSize(static_cast<std::ofstream::off_type>(maximumSize));\r\n\r\n    std::string header = GetHeaderString();\r\n    header += \" !Now with more header!\";\r\n    std::string largeString = \"[*=INIT=*]Now we just need another few dozen characters, which shouldn't be that hard to get. Wow, made it already.\";\r\n    std::string_view largeStringView = largeString;\r\n    size_t initSize = 10;\r\n\r\n    logger.WriteDirect(DefaultChannel, DefaultLevel, header);\r\n    logger.SetTag(Tag::HeadersComplete);\r\n\r\n    // Use the default seed value as we want arbitrary but reproducible results\r\n    std::default_random_engine randomEngine;\r\n    std::uniform_int_distribution<> sizeDistribution(static_cast<int>(initSize), 100);\r\n\r\n    // We should expect ~500 wraps on average\r\n    for (size_t i = 0; i < 9999; ++i)\r\n    {\r\n        logger.WriteDirect(DefaultChannel, DefaultLevel, largeStringView.substr(0, sizeDistribution(randomEngine)));\r\n    }\r\n\r\n    // We want the header to be preserved, followed by the wrap indicator, and at a minimum we should see the first few characters in the log string\r\n    std::vector<std::string_view> expectedFileContents;\r\n    expectedFileContents.push_back(header);\r\n    expectedFileContents.push_back(WrapIndicator);\r\n    expectedFileContents.push_back(largeStringView.substr(0, initSize));\r\n\r\n    ValidateFileContents(tempFile, expectedFileContents, maximumSize);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/Filesystem.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <winget/Filesystem.h>\r\n#include <winget/PathTree.h>\r\n#include <AppInstallerStrings.h>\r\n\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::Filesystem;\r\nusing namespace TestCommon;\r\n\r\nTEST_CASE(\"PathEscapesDirectory\", \"[filesystem]\")\r\n{\r\n    TestCommon::TempDirectory tempDirectory(\"TempDirectory\");\r\n    const std::filesystem::path& basePath = tempDirectory.GetPath();\r\n\r\n    std::string badRelativePath = \"../../target.exe\";\r\n    std::string badRelativePath2 = \"test/../../target.exe\";\r\n    std::string goodRelativePath = \"target.exe\";\r\n    std::string goodRelativePath2 = \"test/../test1/target.exe\";\r\n\r\n    std::filesystem::path badPath = basePath / badRelativePath;\r\n    std::filesystem::path badPath2 = basePath / badRelativePath2;\r\n    std::filesystem::path goodPath = basePath / goodRelativePath;\r\n    std::filesystem::path goodPath2 = basePath / goodRelativePath2;\r\n\r\n    REQUIRE(PathEscapesBaseDirectory(badPath, basePath));\r\n    REQUIRE(PathEscapesBaseDirectory(badPath2, basePath));\r\n    REQUIRE_FALSE(PathEscapesBaseDirectory(goodPath, basePath));\r\n    REQUIRE_FALSE(PathEscapesBaseDirectory(goodPath2, basePath));\r\n}\r\n\r\nTEST_CASE(\"VerifySymlink\", \"[filesystem]\")\r\n{\r\n    TestCommon::TempDirectory tempDirectory(\"TempDirectory\");\r\n    const std::filesystem::path& basePath = tempDirectory.GetPath();\r\n\r\n    std::filesystem::path testFilePath = basePath / \"testFile.txt\";\r\n    std::filesystem::path symlinkPath = basePath / \"symlink.exe\";\r\n\r\n    TestCommon::TempFile testFile(testFilePath);\r\n    std::ofstream file2(testFile, std::ofstream::out);\r\n    file2.close();\r\n\r\n    std::filesystem::create_symlink(testFile.GetPath(), symlinkPath);\r\n\r\n    REQUIRE(SymlinkExists(symlinkPath));\r\n    REQUIRE(VerifySymlink(symlinkPath, testFilePath));\r\n    REQUIRE_FALSE(VerifySymlink(symlinkPath, \"badPath\"));\r\n\r\n    std::filesystem::remove(testFilePath);\r\n\r\n    // Ensure that symlink existence does not check the target\r\n    REQUIRE(SymlinkExists(symlinkPath));\r\n\r\n    std::filesystem::remove(symlinkPath);\r\n\r\n    REQUIRE_FALSE(SymlinkExists(symlinkPath));\r\n}\r\n\r\nTEST_CASE(\"VerifyIsSameVolume\", \"[filesystem]\")\r\n{\r\n    // Note: Pipeline build machine uses 'D:\\' as the volume.\r\n    std::filesystem::path path1 = L\"C:\\\\Program Files\\\\WinGet\\\\Packages\";\r\n    std::filesystem::path path2 = L\"c:\\\\Users\\\\testUser\\\\AppData\\\\Local\\\\Microsoft\\\\WinGet\\\\Packages\";\r\n    std::filesystem::path path3 = L\"localPath\\\\test\\\\folder\";\r\n    std::filesystem::path path4 = L\"test\\\\folder\";\r\n    std::filesystem::path path5 = L\"D:\\\\test\\\\folder\";\r\n    std::filesystem::path path6 = L\"F:\\\\test\\\\folder\";\r\n    std::filesystem::path path7 = L\"d:\\\\randomFolder\";\r\n    std::filesystem::path path8 = L\"f:\\\\randomFolder\";\r\n    std::filesystem::path path9 = L\"a\";\r\n    std::filesystem::path path10 = L\"b\";\r\n\r\n    REQUIRE(IsSameVolume(path1, path2));\r\n    if (IsSameVolume(path5, path5))\r\n    {\r\n        REQUIRE(IsSameVolume(path5, path7));\r\n    }\r\n    REQUIRE(IsSameVolume(path3, path4));\r\n    REQUIRE(IsSameVolume(path9, path10));\r\n\r\n    REQUIRE_FALSE(IsSameVolume(path1, path5));\r\n    REQUIRE_FALSE(IsSameVolume(path1, path6));\r\n    REQUIRE_FALSE(IsSameVolume(path2, path5));\r\n    REQUIRE_FALSE(IsSameVolume(path2, path6));\r\n    REQUIRE_FALSE(IsSameVolume(path3, path6));\r\n    REQUIRE_FALSE(IsSameVolume(path5, path6));\r\n    REQUIRE_FALSE(IsSameVolume(path4, path6));\r\n    REQUIRE_FALSE(IsSameVolume(path6, path8));\r\n}\r\n\r\nTEST_CASE(\"ReplaceCommonPathPrefix\", \"[filesystem]\")\r\n{\r\n    std::filesystem::path prefix = \"C:\\\\test1\\\\test2\";\r\n    std::string replacement = \"%TEST%\";\r\n\r\n    std::filesystem::path shouldReplace = \"C:\\\\test1\\\\test2\\\\subdir1\\\\subdir2\";\r\n    REQUIRE(ReplaceCommonPathPrefix(shouldReplace, prefix, replacement));\r\n    REQUIRE(shouldReplace.u8string() == (replacement + \"\\\\subdir1\\\\subdir2\"));\r\n\r\n    std::filesystem::path shouldNotReplace = \"C:\\\\test1\\\\test3\\\\subdir1\\\\subdir2\";\r\n    REQUIRE(!ReplaceCommonPathPrefix(shouldNotReplace, prefix, replacement));\r\n    REQUIRE(shouldNotReplace.u8string() == \"C:\\\\test1\\\\test3\\\\subdir1\\\\subdir2\");\r\n}\r\n\r\nTEST_CASE(\"GetExecutablePathForProcess\", \"[filesystem]\")\r\n{\r\n    std::filesystem::path thisExecutable = GetExecutablePathForProcess(GetCurrentProcess());\r\n    REQUIRE(!thisExecutable.empty());\r\n    REQUIRE(thisExecutable.is_absolute());\r\n    REQUIRE(thisExecutable.has_filename());\r\n    REQUIRE(thisExecutable.has_extension());\r\n    REQUIRE(thisExecutable.filename() == L\"AppInstallerCLITests.exe\");\r\n}\r\n\r\nTEST_CASE(\"PathTree_InsertAndFind\", \"[filesystem][pathtree]\")\r\n{\r\n    PathTree<bool> pathTree;\r\n\r\n    std::filesystem::path path1 = L\"C:\\\\test\";\r\n    std::filesystem::path path1sub = L\"C:\\\\test\\\\sub\";\r\n    std::filesystem::path path2 = L\"C:\\\\diff\";\r\n    std::filesystem::path path3 = L\"D:\\\\test\";\r\n\r\n    REQUIRE(nullptr == pathTree.Find(path1));\r\n    pathTree.FindOrInsert(path1) = true;\r\n\r\n    REQUIRE(nullptr != pathTree.Find(path1));\r\n    REQUIRE(*pathTree.Find(path1));\r\n\r\n    REQUIRE(nullptr == pathTree.Find(path1sub));\r\n    REQUIRE(nullptr == pathTree.Find(path2));\r\n    REQUIRE(nullptr == pathTree.Find(path3));\r\n}\r\n\r\nTEST_CASE(\"PathTree_InsertAndFind_Negative\", \"[filesystem][pathtree]\")\r\n{\r\n    PathTree<bool> pathTree;\r\n    pathTree.FindOrInsert(L\"C:\\\\a\\\\aa\\\\aaa\");\r\n\r\n    REQUIRE(nullptr == pathTree.Find({}));\r\n    REQUIRE_THROWS_HR(pathTree.FindOrInsert({}), E_INVALIDARG);\r\n}\r\n\r\nsize_t CountVisited(const PathTree<bool>& pathTree, const std::filesystem::path& path, std::function<bool(const bool&)> predicate)\r\n{\r\n    size_t result = 0;\r\n    pathTree.VisitIf(path, [&](const bool&) { ++result; }, predicate);\r\n    return result;\r\n}\r\n\r\nTEST_CASE(\"PathTree_VisitIf_Count\", \"[filesystem][pathtree]\")\r\n{\r\n    PathTree<bool> pathTree;\r\n\r\n    pathTree.FindOrInsert(L\"C:\\\\a\\\\aa\\\\aaa\") = true;\r\n    pathTree.FindOrInsert(L\"C:\\\\a\\\\aa\\\\bbb\") = true;\r\n    pathTree.FindOrInsert(L\"C:\\\\a\\\\aa\\\\ccc\") = false;\r\n    pathTree.FindOrInsert(L\"C:\\\\a\\\\aa\") = true;\r\n\r\n    pathTree.FindOrInsert(L\"C:\\\\a\\\\bb\\\\aaa\") = false;\r\n    pathTree.FindOrInsert(L\"C:\\\\a\\\\bb\\\\bbb\") = true;\r\n    pathTree.FindOrInsert(L\"C:\\\\a\\\\bb\\\\ccc\") = false;\r\n    pathTree.FindOrInsert(L\"C:\\\\a\\\\bb\") = true;\r\n\r\n    pathTree.FindOrInsert(L\"C:\\\\a\\\\cc\\\\aaa\") = true;\r\n    pathTree.FindOrInsert(L\"C:\\\\a\\\\cc\\\\bbb\") = false;\r\n    pathTree.FindOrInsert(L\"C:\\\\a\\\\cc\\\\ccc\") = false;\r\n    pathTree.FindOrInsert(L\"C:\\\\a\\\\cc\") = false;\r\n\r\n    pathTree.FindOrInsert(L\"C:\\\\a\") = true;\r\n    pathTree.FindOrInsert(L\"C:\\\\b\") = false;\r\n    pathTree.FindOrInsert(L\"D:\\\\a\") = false;\r\n\r\n    auto always = [](const bool&) { return true; };\r\n    auto never = [](const bool&) { return false; };\r\n    auto if_input = [](const bool& b) { return b; };\r\n\r\n    REQUIRE(0 == CountVisited(pathTree, {}, always));\r\n\r\n    REQUIRE(15 == CountVisited(pathTree, L\"C:\\\\\", always));\r\n    REQUIRE(2 == CountVisited(pathTree, L\"D:\\\\\", always));\r\n    REQUIRE(0 == CountVisited(pathTree, L\"E:\\\\\", always));\r\n\r\n    REQUIRE(1 == CountVisited(pathTree, L\"C:\\\\\", never));\r\n    REQUIRE(1 == CountVisited(pathTree, L\"D:\\\\\", never));\r\n    REQUIRE(0 == CountVisited(pathTree, L\"E:\\\\\", never));\r\n\r\n    REQUIRE(7 == CountVisited(pathTree, L\"C:\\\\\", if_input));\r\n    REQUIRE(6 == CountVisited(pathTree, L\"C:\\\\a\", if_input));\r\n    REQUIRE(2 == CountVisited(pathTree, L\"C:\\\\a\\\\cc\", if_input));\r\n    REQUIRE(1 == CountVisited(pathTree, L\"D:\\\\\", if_input));\r\n    REQUIRE(0 == CountVisited(pathTree, L\"E:\\\\\", if_input));\r\n}\r\n\r\nTEST_CASE(\"PathTree_VisitIf_Correct\", \"[filesystem][pathtree]\")\r\n{\r\n    PathTree<std::pair<bool, bool>> pathTree;\r\n\r\n    pathTree.FindOrInsert(L\"C:\\\\a\\\\aa\\\\aaa\") = { true, true };\r\n    pathTree.FindOrInsert(L\"C:\\\\a\\\\aa\\\\bbb\") = { true, true };\r\n    pathTree.FindOrInsert(L\"C:\\\\a\\\\aa\\\\ccc\") = { false, false };\r\n    pathTree.FindOrInsert(L\"C:\\\\a\\\\aa\") = { true, true };\r\n\r\n    pathTree.FindOrInsert(L\"C:\\\\a\\\\bb\\\\aaa\") = { false, false };\r\n    pathTree.FindOrInsert(L\"C:\\\\a\\\\bb\\\\bbb\") = { true, true };\r\n    pathTree.FindOrInsert(L\"C:\\\\a\\\\bb\\\\ccc\") = { false, false };\r\n    pathTree.FindOrInsert(L\"C:\\\\a\\\\bb\") = { true, true };\r\n\r\n    pathTree.FindOrInsert(L\"C:\\\\a\\\\cc\\\\aaa\") = { true, true };\r\n    pathTree.FindOrInsert(L\"C:\\\\a\\\\cc\\\\bbb\") = { false, false };\r\n    pathTree.FindOrInsert(L\"C:\\\\a\\\\cc\\\\ccc\") = { false, false };\r\n    pathTree.FindOrInsert(L\"C:\\\\a\\\\cc\") = { false, false };\r\n\r\n    pathTree.FindOrInsert(L\"C:\\\\a\") = { true, true };\r\n    pathTree.FindOrInsert(L\"C:\\\\b\") = { false, false };\r\n    pathTree.FindOrInsert(L\"C:\") = { true, false };\r\n\r\n    auto check_input = [](const std::pair<bool, bool>& p) { REQUIRE(p.first); };\r\n    auto if_input = [](const std::pair<bool, bool>& p) { return p.second; };\r\n\r\n    pathTree.VisitIf(L\"C:\", check_input, if_input);\r\n}\r\n\r\nTEST_CASE(\"GetFileInfoFor\", \"[filesystem]\")\r\n{\r\n    TestCommon::TempDirectory tempDirectory{ \"GetFileInfoFor\" };\r\n\r\n    auto now = std::filesystem::file_time_type::clock::now();\r\n\r\n    std::this_thread::sleep_for(1s);\r\n    auto file1 = tempDirectory.CreateTempFile(\"c.txt\");\r\n    std::string file1Content = \"File 1 Content!\";\r\n    std::ofstream{ file1 } << file1Content;\r\n    std::this_thread::sleep_for(1s);\r\n    auto file2 = tempDirectory.CreateTempFile(\"b.txt\");\r\n    std::string file2Content = \"More Content! Better Content!\";\r\n    std::ofstream{ file2 } << file2Content;\r\n    std::this_thread::sleep_for(1s);\r\n    auto file3 = tempDirectory.CreateTempFile(\"a.txt\");\r\n    std::string file3Content = \"Maybe less is better?\";\r\n    std::ofstream{ file3 } << file3Content;\r\n\r\n    auto fileInfo = GetFileInfoFor(tempDirectory);\r\n    REQUIRE(3 == fileInfo.size());\r\n\r\n    // Sort with oldest first\r\n    std::sort(fileInfo.begin(), fileInfo.end(), [](const FileInfo& a, const FileInfo& b) { return a.LastWriteTime < b.LastWriteTime; });\r\n\r\n    REQUIRE(fileInfo[0].Path == file1.GetPath());\r\n    REQUIRE(fileInfo[0].LastWriteTime > now);\r\n    REQUIRE(fileInfo[0].Size == file1Content.size());\r\n\r\n    REQUIRE(fileInfo[1].Path == file2.GetPath());\r\n    REQUIRE(fileInfo[1].LastWriteTime > fileInfo[0].LastWriteTime);\r\n    REQUIRE(fileInfo[1].Size == file2Content.size());\r\n\r\n    REQUIRE(fileInfo[2].Path == file3.GetPath());\r\n    REQUIRE(fileInfo[2].LastWriteTime > fileInfo[1].LastWriteTime);\r\n    REQUIRE(fileInfo[2].Size == file3Content.size());\r\n}\r\n\r\nvoid RequireFilePaths(const std::vector<FileInfo>& files, std::initializer_list<const char*> paths)\r\n{\r\n    REQUIRE(paths.size() == files.size());\r\n    size_t i = 0;\r\n    for (const char* val : paths)\r\n    {\r\n        REQUIRE(val == files[i++].Path.u8string());\r\n    }\r\n}\r\n\r\nTEST_CASE(\"FilterToFilesExceedingLimits\", \"[filesystem]\")\r\n{\r\n    auto now = std::filesystem::file_time_type::clock::now();\r\n\r\n    std::vector<FileInfo> files\r\n    {\r\n        { \"a\", now, 42 },\r\n        { \"b\", now - 32min, 45321 },\r\n        { \"c\", now - 84min, 24567 },\r\n        { \"d\", now - 4h, 876312 },\r\n        { \"e\", now - 18h, 2908534 },\r\n        { \"f\", now - 47h, 312 },\r\n        { \"g\", now - 132h, 74321 },\r\n        { \"h\", now - 4567h, 6573423 },\r\n    };\r\n\r\n    // Give the sort inside FilterToFilesExceedingLimits something to do\r\n    std::shuffle(files.begin(), files.end(), std::mt19937{});\r\n    FileLimits limits{};\r\n\r\n    SECTION(\"No limits\")\r\n    {\r\n        FilterToFilesExceedingLimits(files, limits);\r\n        // Without limits, nothing exceeds them\r\n        REQUIRE(files.empty());\r\n    }\r\n    SECTION(\"Age - 1h\")\r\n    {\r\n        limits.Age = 1h;\r\n        FilterToFilesExceedingLimits(files, limits);\r\n        RequireFilePaths(files, { \"h\", \"g\", \"f\", \"e\", \"d\", \"c\" });\r\n    }\r\n    SECTION(\"Age - 2h\")\r\n    {\r\n        limits.Age = 2h;\r\n        FilterToFilesExceedingLimits(files, limits);\r\n        RequireFilePaths(files, { \"h\", \"g\", \"f\", \"e\", \"d\" });\r\n    }\r\n    SECTION(\"Age - 24h\")\r\n    {\r\n        limits.Age = 24h;\r\n        FilterToFilesExceedingLimits(files, limits);\r\n        RequireFilePaths(files, { \"h\", \"g\", \"f\" });\r\n    }\r\n    SECTION(\"Age - 7d\")\r\n    {\r\n        limits.Age = 7 * 24h;\r\n        FilterToFilesExceedingLimits(files, limits);\r\n        RequireFilePaths(files, { \"h\" });\r\n    }\r\n    SECTION(\"Age - 365d\")\r\n    {\r\n        limits.Age = 365 * 24h;\r\n        FilterToFilesExceedingLimits(files, limits);\r\n        REQUIRE(files.empty());\r\n    }\r\n    SECTION(\"Size - 1MB\")\r\n    {\r\n        limits.TotalSizeInMB = 1;\r\n        FilterToFilesExceedingLimits(files, limits);\r\n        RequireFilePaths(files, { \"h\", \"g\", \"f\", \"e\" });\r\n    }\r\n    SECTION(\"Size - 2MB\")\r\n    {\r\n        limits.TotalSizeInMB = 2;\r\n        FilterToFilesExceedingLimits(files, limits);\r\n        RequireFilePaths(files, { \"h\", \"g\", \"f\", \"e\" });\r\n    }\r\n    SECTION(\"Size - 3MB\")\r\n    {\r\n        limits.TotalSizeInMB = 3;\r\n        FilterToFilesExceedingLimits(files, limits);\r\n        RequireFilePaths(files, { \"h\", \"g\", \"f\", \"e\" });\r\n    }\r\n    SECTION(\"Size - 4MB\")\r\n    {\r\n        limits.TotalSizeInMB = 4;\r\n        FilterToFilesExceedingLimits(files, limits);\r\n        RequireFilePaths(files, { \"h\" });\r\n    }\r\n    SECTION(\"Size - 100MB\")\r\n    {\r\n        limits.TotalSizeInMB = 100;\r\n        FilterToFilesExceedingLimits(files, limits);\r\n        REQUIRE(files.empty());\r\n    }\r\n    SECTION(\"Count - 1\")\r\n    {\r\n        limits.Count = 1;\r\n        FilterToFilesExceedingLimits(files, limits);\r\n        RequireFilePaths(files, { \"h\", \"g\", \"f\", \"e\", \"d\", \"c\", \"b\" });\r\n    }\r\n    SECTION(\"Count - 2\")\r\n    {\r\n        limits.Count = 2;\r\n        FilterToFilesExceedingLimits(files, limits);\r\n        RequireFilePaths(files, { \"h\", \"g\", \"f\", \"e\", \"d\", \"c\" });\r\n    }\r\n    SECTION(\"Count - 4\")\r\n    {\r\n        limits.Count = 4;\r\n        FilterToFilesExceedingLimits(files, limits);\r\n        RequireFilePaths(files, { \"h\", \"g\", \"f\", \"e\" });\r\n    }\r\n    SECTION(\"Count - 7\")\r\n    {\r\n        limits.Count = 7;\r\n        FilterToFilesExceedingLimits(files, limits);\r\n        RequireFilePaths(files, { \"h\" });\r\n    }\r\n    SECTION(\"Count - 8\")\r\n    {\r\n        limits.Count = 8;\r\n        FilterToFilesExceedingLimits(files, limits);\r\n        REQUIRE(files.empty());\r\n    }\r\n    SECTION(\"Count - 100\")\r\n    {\r\n        limits.Count = 100;\r\n        FilterToFilesExceedingLimits(files, limits);\r\n        REQUIRE(files.empty());\r\n    }\r\n    SECTION(\"Mix - 24h - 2MB - 4\")\r\n    {\r\n        limits.Age = 24h;\r\n        limits.TotalSizeInMB = 2;\r\n        limits.Count = 4;\r\n        FilterToFilesExceedingLimits(files, limits);\r\n        RequireFilePaths(files, { \"h\", \"g\", \"f\", \"e\" });\r\n    }\r\n    SECTION(\"Mix - 2h - 2MB - 4\")\r\n    {\r\n        limits.Age = 2h;\r\n        limits.TotalSizeInMB = 2;\r\n        limits.Count = 4;\r\n        FilterToFilesExceedingLimits(files, limits);\r\n        RequireFilePaths(files, { \"h\", \"g\", \"f\", \"e\", \"d\" });\r\n    }\r\n    SECTION(\"Mix - 24h - 1MB - 4\")\r\n    {\r\n        limits.Age = 24h;\r\n        limits.TotalSizeInMB = 1;\r\n        limits.Count = 4;\r\n        FilterToFilesExceedingLimits(files, limits);\r\n        RequireFilePaths(files, { \"h\", \"g\", \"f\", \"e\" });\r\n    }\r\n    SECTION(\"Mix - 24h - 2MB - 2\")\r\n    {\r\n        limits.Age = 24h;\r\n        limits.TotalSizeInMB = 2;\r\n        limits.Count = 2;\r\n        FilterToFilesExceedingLimits(files, limits);\r\n        RequireFilePaths(files, { \"h\", \"g\", \"f\", \"e\", \"d\", \"c\" });\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/FolderFileWatcher.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"TestCommon.h\"\n#include <winget/FolderFileWatcher.h>\n\nusing namespace TestCommon;\nusing namespace AppInstaller;\n\nnamespace\n{\n    void WriteText(const std::filesystem::path& path)\n    {\n        std::ofstream fileStream{ path };\n        fileStream << \"text\";\n    }\n\n    std::filesystem::path RemoveRoot(const std::filesystem::path& prefix, const std::filesystem::path& source)\n    {\n        auto prefixItr = prefix.begin();\n        auto sourceItr = source.begin();\n\n        while (prefixItr != prefix.end() && sourceItr != source.end())\n        {\n            if (*prefixItr != *sourceItr)\n            {\n                break;\n            }\n\n            ++prefixItr;\n            ++sourceItr;\n        }\n\n        std::filesystem::path result{};\n        if (prefixItr == prefix.end())\n        {\n            for (; sourceItr != source.end(); ++sourceItr)\n            {\n                if (result.empty())\n                {\n                    result = *sourceItr;\n                }\n                else\n                {\n                    result /= *sourceItr;\n                }\n            }\n        }\n\n        return result;\n    }\n}\n\nTEST_CASE(\"FolderFileWatcher_CreateNewFiles\", \"[FolderFileWatcher]\")\n{\n    TempDirectory dirToWatch(\"FolderFileWatcher_CreateNewFiles_\", true);\n\n    Utility::FolderFileWatcher folderFileWatcher(dirToWatch.GetPath());\n    folderFileWatcher.Start();\n\n    TempFile tempFile1(dirToWatch.GetPath(), \"file1_\", \".txt\");\n    WriteText(tempFile1.GetPath());\n\n    TempFile tempFile2(dirToWatch.GetPath(), \"file2_\", \".txt\");\n    WriteText(tempFile2.GetPath());\n    \n    std::filesystem::path newTestDir = dirToWatch.GetPath();\n    newTestDir /= \"testDir\";\n    std::filesystem::create_directories(newTestDir);\n\n    TempFile tempFile3(newTestDir, \"file3_\", \".txt\");\n    WriteText(tempFile3.GetPath());\n\n    std::this_thread::sleep_for(100ms);\n    folderFileWatcher.Stop();\n\n    auto& watchedFiles = folderFileWatcher.Files();\n\n    auto tempFile1RelativePath = RemoveRoot(dirToWatch, tempFile1.GetPath());\n    auto foundTempFile1 = watchedFiles.find(tempFile1RelativePath);\n    REQUIRE(foundTempFile1 != watchedFiles.cend());\n\n    auto tempFile2RelativePath = RemoveRoot(dirToWatch, tempFile2.GetPath());\n    auto foundTempFile2 = watchedFiles.find(tempFile2RelativePath);\n    REQUIRE(foundTempFile2 != watchedFiles.cend());\n\n    auto tempFile3RelativePath = RemoveRoot(dirToWatch, tempFile3.GetPath());\n    auto foundTempFile3 = watchedFiles.find(tempFile3RelativePath);\n    REQUIRE(foundTempFile3 != watchedFiles.cend());\n}\n\nTEST_CASE(\"FolderFileWatcher_CreateAfterStop\", \"[FolderFileWatcher]\")\n{\n    TempDirectory dirToWatch(\"FolderFileWatcher_CreateAfterStop_\", true);\n\n    Utility::FolderFileWatcher folderFileWatcher(dirToWatch.GetPath());\n    folderFileWatcher.Start();\n\n    TempFile tempFile1(dirToWatch.GetPath(), \"file1_\", \".txt\");\n    WriteText(tempFile1.GetPath());\n\n    std::this_thread::sleep_for(100ms);\n    folderFileWatcher.Stop();\n\n    TempFile tempFile2(dirToWatch.GetPath(), \"file2_\", \".txt\");\n    WriteText(tempFile2.GetPath());\n\n    auto& watchedFiles = folderFileWatcher.Files();\n\n    auto tempFile1RelativePath = RemoveRoot(dirToWatch, tempFile1.GetPath());\n    auto foundTempFile1 = watchedFiles.find(tempFile1RelativePath);\n    REQUIRE(foundTempFile1 != watchedFiles.cend());\n\n    auto tempFile2RelativePath = RemoveRoot(dirToWatch, tempFile2.GetPath());\n    auto foundTempFile2 = watchedFiles.find(tempFile2RelativePath);\n    REQUIRE(foundTempFile2 == watchedFiles.cend());\n}\n\nTEST_CASE(\"FolderFileWatcher_CreateNewFilesAndRename\", \"[FolderFileWatcher]\")\n{\n    TempDirectory dirToWatch(\"FolderFileWatcher_CreateNewFilesAndRename_\", true);\n\n    Utility::FolderFileWatcher folderFileWatcher(dirToWatch.GetPath());\n    folderFileWatcher.Start();\n\n    std::filesystem::path tempFile1Path = dirToWatch.GetPath() / \"file1.txt\";\n    TempFile tempFile1(tempFile1Path);\n    WriteText(tempFile1Path);\n\n    std::filesystem::path newTestDir = dirToWatch.GetPath();\n    newTestDir /= \"testDir\";\n    std::filesystem::create_directories(newTestDir);\n\n    std::filesystem::path tempFile2Path = newTestDir / \"file2.txt\";\n    TempFile tempFile2(tempFile2Path);\n    WriteText(tempFile2Path);\n\n    std::filesystem::path tempFile1PathRenamed = dirToWatch.GetPath() / \"file1_renamed.txt\";\n    std::filesystem::path tempFile2PathRenamed = newTestDir / \"file2_renamed.txt\";\n\n    tempFile1.Rename(tempFile1PathRenamed);\n    tempFile2.Rename(tempFile2PathRenamed);\n\n    std::this_thread::sleep_for(100ms);\n    folderFileWatcher.Stop();\n\n    auto& watchedFiles = folderFileWatcher.Files();\n\n    auto tempFile1RelativePath = RemoveRoot(dirToWatch, tempFile1Path);\n    auto foundTempFile1 = watchedFiles.find(tempFile1RelativePath);\n    REQUIRE(foundTempFile1 == watchedFiles.cend());\n\n    auto tempFile1RenamedRelativePath = RemoveRoot(dirToWatch, tempFile1PathRenamed);\n    auto foundTempFile1Renamed = watchedFiles.find(tempFile1RenamedRelativePath);\n    REQUIRE(foundTempFile1Renamed != watchedFiles.cend());\n\n    auto tempFile2RelativePath = RemoveRoot(dirToWatch, tempFile2Path);\n    auto foundTempFile2 = watchedFiles.find(tempFile2RelativePath);\n    REQUIRE(foundTempFile2 == watchedFiles.cend());\n\n    auto tempFile2RenamedRelativePath = RemoveRoot(dirToWatch, tempFile2PathRenamed);\n    auto foundTempFile2Renamed = watchedFiles.find(tempFile2RenamedRelativePath);\n    REQUIRE(foundTempFile2Renamed != watchedFiles.cend());\n}\n\nTEST_CASE(\"FolderFileWatcher_CreateNewFilesAndDelete\", \"[FolderFileWatcher]\")\n{\n    TempDirectory dirToWatch(\"FolderFileWatcher_CreateNewFilesAndDelete_\", true);\n\n    Utility::FolderFileWatcher folderFileWatcher(dirToWatch.GetPath());\n    folderFileWatcher.Start();\n\n    TempFile tempFile1(dirToWatch.GetPath(), \"file1_\", \".txt\");\n    WriteText(tempFile1.GetPath());\n\n    std::filesystem::path newTestDir = dirToWatch.GetPath();\n    newTestDir /= \"testDir\";\n    std::filesystem::create_directories(newTestDir);\n\n    TempFile tempFile2(newTestDir, \"file2_\", \".txt\");\n    WriteText(tempFile2.GetPath());\n\n    // Create files and delete them.\n    std::filesystem::path tempFile3Path;\n    std::filesystem::path tempFile4Path;\n    {\n        TempFile tempFile3(dirToWatch.GetPath(), \"file3_\", \".txt\");\n        tempFile3Path = tempFile3.GetPath();\n        WriteText(tempFile3Path);\n        std::filesystem::remove(tempFile3Path);\n\n        TempFile tempFile4(newTestDir, \"file4_\", \".txt\");\n        tempFile4Path = tempFile4.GetPath();\n        WriteText(tempFile4Path);\n        std::filesystem::remove(tempFile4Path);\n    }\n\n    std::this_thread::sleep_for(100ms);\n    folderFileWatcher.Stop();\n\n    auto& watchedFiles = folderFileWatcher.Files();\n\n    auto tempFile1RelativePath = RemoveRoot(dirToWatch, tempFile1.GetPath());\n    auto foundTempFile1 = watchedFiles.find(tempFile1RelativePath);\n    REQUIRE(foundTempFile1 != watchedFiles.cend());\n\n    auto tempFile2RelativePath = RemoveRoot(dirToWatch, tempFile2.GetPath());\n    auto foundTempFile2 = watchedFiles.find(tempFile2RelativePath);\n    REQUIRE(foundTempFile2 != watchedFiles.cend());\n\n    auto tempFile3RelativePath = RemoveRoot(dirToWatch, tempFile3Path);\n    auto foundTempFile3 = watchedFiles.find(tempFile3RelativePath);\n    REQUIRE(foundTempFile3 == watchedFiles.cend());\n\n    auto tempFile4RelativePath = RemoveRoot(dirToWatch, tempFile4Path);\n    auto foundTempFile4 = watchedFiles.find(tempFile4RelativePath);\n    REQUIRE(foundTempFile4 == watchedFiles.cend());\n}\n\nTEST_CASE(\"FolderFileWatcher_Extension_CreateNewFiles\", \"[FolderFileWatcher]\")\n{\n    TempDirectory dirToWatch(\"FolderFileWatcher_Extension_CreateNewFiles\", true);\n\n    Utility::FolderFileWatcher folderFileExtensionWatcher(dirToWatch.GetPath(), \".yaml\");\n    folderFileExtensionWatcher.Start();\n\n    TempFile tempFile1(dirToWatch.GetPath(), \"file1_\", \".txt\");\n    WriteText(tempFile1.GetPath());\n\n    TempFile tempFile2(dirToWatch.GetPath(), \"file2_\", \".yaml\");\n    WriteText(tempFile2.GetPath());\n\n    std::filesystem::path newTestDir = dirToWatch.GetPath();\n    newTestDir /= \"testDir\";\n    std::filesystem::create_directories(newTestDir);\n\n    TempFile tempFile3(newTestDir, \"file3_\", \".txt\");\n    WriteText(tempFile3.GetPath());\n\n    TempFile tempFile4(newTestDir, \"file4_\", \".yaml\");\n    WriteText(tempFile4.GetPath());\n\n    std::this_thread::sleep_for(100ms);\n    folderFileExtensionWatcher.Stop();\n\n    auto& watchedFiles = folderFileExtensionWatcher.Files();\n\n    auto tempFile1RelativePath = RemoveRoot(dirToWatch, tempFile1.GetPath());\n    auto foundTempFile1 = watchedFiles.find(tempFile1RelativePath);\n    REQUIRE(foundTempFile1 == watchedFiles.cend());\n\n    auto tempFile2RelativePath = RemoveRoot(dirToWatch, tempFile2.GetPath());\n    auto foundTempFile2 = watchedFiles.find(tempFile2RelativePath);\n    REQUIRE(foundTempFile2 != watchedFiles.cend());\n\n    auto tempFile3RelativePath = RemoveRoot(dirToWatch, tempFile3.GetPath());\n    auto foundTempFile3 = watchedFiles.find(tempFile3RelativePath);\n    REQUIRE(foundTempFile3 == watchedFiles.cend());\n\n    auto tempFile4RelativePath = RemoveRoot(dirToWatch, tempFile4.GetPath());\n    auto foundTempFile4 = watchedFiles.find(tempFile4RelativePath);\n    REQUIRE(foundTempFile4 != watchedFiles.cend());\n}\n\nTEST_CASE(\"FolderFileWatcher_Extension_CreateAfterStop\", \"[FolderFileWatcher]\")\n{\n    TempDirectory dirToWatch(\"FolderFileWatcher_Extension_CreateAfterStop\", true);\n\n    Utility::FolderFileWatcher folderFileExtensionWatcher(dirToWatch.GetPath(), \".txt\");\n    folderFileExtensionWatcher.Start();\n\n    TempFile tempFile1(dirToWatch.GetPath(), \"file1_\", \".txt\");\n    WriteText(tempFile1.GetPath());\n\n    std::this_thread::sleep_for(100ms);\n    folderFileExtensionWatcher.Stop();\n\n    TempFile tempFile2(dirToWatch.GetPath(), \"file2_\", \".txt\");\n    WriteText(tempFile2.GetPath());\n\n    auto& watchedFiles = folderFileExtensionWatcher.Files();\n\n    auto tempFile1RelativePath = RemoveRoot(dirToWatch, tempFile1.GetPath());\n    auto foundTempFile1 = watchedFiles.find(tempFile1RelativePath);\n    REQUIRE(foundTempFile1 != watchedFiles.cend());\n\n    auto tempFile2RelativePath = RemoveRoot(dirToWatch, tempFile2.GetPath());\n    auto foundTempFile2 = watchedFiles.find(tempFile2RelativePath);\n    REQUIRE(foundTempFile2 == watchedFiles.cend());\n}\n\nTEST_CASE(\"FolderFileWatcher_Extension_CreateNewFilesAndRename\", \"[FolderFileWatcher]\")\n{\n    TempDirectory dirToWatch(\"FolderFileWatcher_Extension_CreateNewFilesAndRename\", true);\n\n    Utility::FolderFileWatcher folderFileExtensionWatcher(dirToWatch.GetPath(), \".txt\");\n    folderFileExtensionWatcher.Start();\n\n    std::filesystem::path tempFile1Path = dirToWatch.GetPath() / \"file1.txt\";\n    TempFile tempFile1(tempFile1Path);\n    WriteText(tempFile1Path);\n\n    std::filesystem::path newTestDir = dirToWatch.GetPath();\n    newTestDir /= \"testDir\";\n    std::filesystem::create_directories(newTestDir);\n\n    std::filesystem::path tempFile2Path = newTestDir / \"file2.txt\";\n    TempFile tempFile2(tempFile2Path);\n    WriteText(tempFile2Path);\n\n    std::filesystem::path tempFile1PathRenamed = dirToWatch.GetPath() / \"file1_renamed.txt\";\n    std::filesystem::path tempFile2PathRenamed = newTestDir / \"file2_renamed.txt\";\n\n    tempFile1.Rename(tempFile1PathRenamed);\n    tempFile2.Rename(tempFile2PathRenamed);\n\n    std::this_thread::sleep_for(100ms);\n    folderFileExtensionWatcher.Stop();\n\n    auto& watchedFiles = folderFileExtensionWatcher.Files();\n\n    auto tempFile1RelativePath = RemoveRoot(dirToWatch, tempFile1Path);\n    auto foundTempFile1 = watchedFiles.find(tempFile1RelativePath);\n    REQUIRE(foundTempFile1 == watchedFiles.cend());\n\n    auto tempFile1RenamedRelativePath = RemoveRoot(dirToWatch, tempFile1PathRenamed);\n    auto foundTempFile1Renamed = watchedFiles.find(tempFile1RenamedRelativePath);\n    REQUIRE(foundTempFile1Renamed != watchedFiles.cend());\n\n    auto tempFile2RelativePath = RemoveRoot(dirToWatch, tempFile2Path);\n    auto foundTempFile2 = watchedFiles.find(tempFile2RelativePath);\n    REQUIRE(foundTempFile2 == watchedFiles.cend());\n\n    auto tempFile2RenamedRelativePath = RemoveRoot(dirToWatch, tempFile2PathRenamed);\n    auto foundTempFile2Renamed = watchedFiles.find(tempFile2RenamedRelativePath);\n    REQUIRE(foundTempFile2Renamed != watchedFiles.cend());\n}\n\nTEST_CASE(\"FolderFileWatcher_Extension_CreateNewFilesAndDelete\", \"[FolderFileWatcher]\")\n{\n    TempDirectory dirToWatch(\"FolderFileWatcher_Extension_CreateNewFilesAndDelete\", true);\n\n    Utility::FolderFileWatcher folderFileExtensionWatcher(dirToWatch.GetPath(), \".txt\");\n    folderFileExtensionWatcher.Start();\n\n    TempFile tempFile1(dirToWatch.GetPath(), \"file1_\", \".txt\");\n    WriteText(tempFile1.GetPath());\n\n    std::filesystem::path newTestDir = dirToWatch.GetPath();\n    newTestDir /= \"testDir\";\n    std::filesystem::create_directories(newTestDir);\n\n    TempFile tempFile2(newTestDir, \"file2_\", \".txt\");\n    WriteText(tempFile2.GetPath());\n\n    // Create files and delete them.\n    std::filesystem::path tempFile3Path;\n    std::filesystem::path tempFile4Path;\n    {\n        TempFile tempFile3(dirToWatch.GetPath(), \"file3_\", \".txt\");\n        tempFile3Path = tempFile3.GetPath();\n        WriteText(tempFile3Path);\n        std::filesystem::remove(tempFile3Path);\n\n        TempFile tempFile4(newTestDir, \"file4_\", \".txt\");\n        tempFile4Path = tempFile4.GetPath();\n        WriteText(tempFile4Path);\n        std::filesystem::remove(tempFile4Path);\n    }\n\n    std::this_thread::sleep_for(100ms);\n    folderFileExtensionWatcher.Stop();\n\n    auto& watchedFiles = folderFileExtensionWatcher.Files();\n\n    auto tempFile1RelativePath = RemoveRoot(dirToWatch, tempFile1.GetPath());\n    auto foundTempFile1 = watchedFiles.find(tempFile1RelativePath);\n    REQUIRE(foundTempFile1 != watchedFiles.cend());\n\n    auto tempFile2RelativePath = RemoveRoot(dirToWatch, tempFile2.GetPath());\n    auto foundTempFile2 = watchedFiles.find(tempFile2RelativePath);\n    REQUIRE(foundTempFile2 != watchedFiles.cend());\n\n    auto tempFile3RelativePath = RemoveRoot(dirToWatch, tempFile3Path);\n    auto foundTempFile3 = watchedFiles.find(tempFile3RelativePath);\n    REQUIRE(foundTempFile3 == watchedFiles.cend());\n\n    auto tempFile4RelativePath = RemoveRoot(dirToWatch, tempFile4Path);\n    auto foundTempFile4 = watchedFiles.find(tempFile4RelativePath);\n    REQUIRE(foundTempFile4 == watchedFiles.cend());\n}\n"
  },
  {
    "path": "src/AppInstallerCLITests/FontHelper.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"TestCommon.h\"\n#include \"TestHooks.h\"\n#include \"AppInstallerStrings.h\"\n#include \"Microsoft/FontHelper.h\"\n\nusing namespace AppInstaller::Manifest;\nusing namespace AppInstaller::Repository::Microsoft;\nusing namespace AppInstaller::Utility;\nusing namespace AppInstaller::Registry;\n\n\nTEST_CASE(\"FontHelper_Watcher\", \"[FontHelper]\")\n{\n    FontHelper helper;\n\n    wil::unique_event callbackEvent;\n    callbackEvent.create();\n\n    ScopeEnum scopeCallback = ScopeEnum::Unknown;\n    ScopeEnum scopeTarget = ScopeEnum::Machine;\n\n    auto fakeRoot = TestCommon::RegCreateVolatileTestRoot();\n    TestHook::SetGetFontRegistryRoot_Override fontRootOverride([&](ScopeEnum scope)\n        {\n            if (scope == scopeTarget)\n            {\n                return Key(fakeRoot.get(), L\"\");\n            }\n            else\n            {\n                return Key{};\n            }\n        });\n\n    auto watchers = std::vector<wil::unique_registry_watcher>();\n    helper.AddRegistryWatchers(scopeTarget, [&](ScopeEnum scope, wil::RegistryChangeKind)\n        {\n            scopeCallback = scope;\n            callbackEvent.SetEvent();\n        }, watchers);\n\n    GUID guid;\n    std::ignore = CoCreateGuid(&guid);\n    std::ostringstream stream;\n    stream << guid;\n\n    auto testKey = TestCommon::RegCreateVolatileSubKey(fakeRoot.get(), ConvertToUTF16(stream.str()));\n    REQUIRE(callbackEvent.wait(1000));\n    REQUIRE(scopeTarget == scopeCallback);\n\n    // Reset for changing a value\n    scopeCallback = ScopeEnum::Unknown;\n    TestCommon::SetRegistryValue(testKey.get(), L\"testValue\", L\"valueValue\");\n\n    REQUIRE(callbackEvent.wait(1000));\n    REQUIRE(scopeTarget == scopeCallback);\n}\n"
  },
  {
    "path": "src/AppInstallerCLITests/Fonts.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"TestCommon.h\"\n#include <AppInstallerRuntime.h>\n#include <winget/Fonts.h>\n\nusing namespace AppInstaller::Fonts;\nusing namespace AppInstaller::Manifest;\nusing namespace TestCommon;\n\nconstexpr std::wstring_view s_testFontName = L\"Times New Roman\";\nconstexpr std::string_view s_FontFile = \"TestFont.ttf\";\nconstexpr std::string_view s_FontFileTemp = \"TestFont_temp.ttf\";\nconstexpr std::string_view s_InvalidFontFile = \"Installer-Good.msix\";\n\nTEST_CASE(\"GetInstalledFonts\", \"[fonts]\")\n{\n    FontCatalog fontCatalog;\n    std::vector<FontFamily> installedFontFamilies;\n    REQUIRE_NOTHROW(installedFontFamilies = fontCatalog.GetInstalledFontFamilies());\n    REQUIRE(installedFontFamilies.size() > 0);\n}\n\nTEST_CASE(\"GetSingleFontFamily\", \"[fonts]\")\n{\n    FontCatalog fontCatalog;\n    std::vector<FontFamily> fontFamily;\n    REQUIRE_NOTHROW(fontFamily = fontCatalog.GetInstalledFontFamilies(std::wstring(s_testFontName)));\n    REQUIRE_FALSE(fontFamily.empty());\n    FontFamily singleFontFamily = fontFamily[0];\n    REQUIRE(AppInstaller::Utility::CaseInsensitiveEquals(singleFontFamily.Name, s_testFontName));\n    REQUIRE(singleFontFamily.Faces.size() > 0);\n}\n\nTEST_CASE(\"GetInvalidFontFamily\", \"[fonts]\")\n{\n    FontCatalog fontCatalog;\n    std::vector<FontFamily> fontFamily;\n    REQUIRE_NOTHROW(fontFamily = fontCatalog.GetInstalledFontFamilies(L\"Invalid Font\"));\n    REQUIRE(fontFamily.empty());\n}\n\nTEST_CASE(\"ValidFontFile\", \"[fonts]\")\n{\n    TestDataFile testFont(s_FontFile);\n    const auto& testFontPath = testFont.GetPath();\n    FontCatalog fontCatalog;\n    DWRITE_FONT_FILE_TYPE fontFileType;\n    REQUIRE(fontCatalog.IsFontFileSupported(testFontPath, fontFileType));\n    REQUIRE(fontFileType == DWRITE_FONT_FILE_TYPE::DWRITE_FONT_FILE_TYPE_TRUETYPE);\n}\n\nTEST_CASE(\"GetFontFileInfo\", \"[fonts]\")\n{\n    TestDataFile testFont(s_FontFile);\n    auto context = FontContext();\n    context.Scope = ScopeEnum::User;\n    context.PackageId = L\"TestPackage\";\n    context.PackageVersion = L\"1.0.0.0\";\n    context.InstallerSource = InstallerSource::WinGet;\n    const auto& fontFileInfo = CreateFontFileInfo(context, testFont.GetPath());\n    REQUIRE(fontFileInfo.Status == FontStatus::Absent);\n}\n\nTEST_CASE(\"InvalidFontFile\", \"[fonts]\")\n{\n    TestDataFile testFont(s_InvalidFontFile);\n    const auto& testFontPath = testFont.GetPath();\n    FontCatalog fontCatalog;\n    DWRITE_FONT_FILE_TYPE fontFileType;\n    REQUIRE_FALSE(fontCatalog.IsFontFileSupported(testFontPath, fontFileType));\n    REQUIRE(fontFileType == DWRITE_FONT_FILE_TYPE::DWRITE_FONT_FILE_TYPE_UNKNOWN);\n}\n\nTEST_CASE(\"GetInstalledFontFiles\", \"[fonts]\")\n{\n    const auto& fontFiles = GetInstalledFontFiles();\n\n    // There should be at least one font installed on the system.\n    REQUIRE(fontFiles.size() > 0);\n}\n\nTEST_CASE(\"ValidateInvalidFontPackage\", \"[fonts]\")\n{\n    TestDataFile testFont(s_InvalidFontFile);\n    auto context = FontContext();\n    context.Scope = ScopeEnum::User;\n    context.PackageId = L\"TestPackage\";\n    context.PackageVersion = L\"1.0.0.0\";\n    context.InstallerSource = InstallerSource::WinGet;\n    context.AddPackageFile(testFont.GetPath());\n    const auto& fontValidationResult = ValidateFontPackage(context);\n    REQUIRE(fontValidationResult.HResult == S_OK);\n    REQUIRE(fontValidationResult.Result == FontResult::Success);\n    REQUIRE(fontValidationResult.HasUnsupportedFonts == true);\n    REQUIRE(fontValidationResult.Status == FontStatus::Absent);\n}\n\nTEST_CASE(\"ValidateValidFontPackage\", \"[fonts]\")\n{\n    TestDataFile testFont(s_FontFile);\n    auto context = FontContext();\n    context.Scope = ScopeEnum::User;\n    context.PackageId = L\"TestPackage\";\n    context.PackageVersion = L\"1.0.0.0\";\n    context.InstallerSource = InstallerSource::WinGet;\n    context.AddPackageFile(testFont.GetPath());\n    const auto& fontValidationResult = ValidateFontPackage(context);\n    REQUIRE(fontValidationResult.HResult == S_OK);\n    REQUIRE(fontValidationResult.Result == FontResult::Success);\n    REQUIRE(fontValidationResult.HasUnsupportedFonts == false);\n    REQUIRE(fontValidationResult.Status == FontStatus::Absent);\n}\n\nTEST_CASE(\"InstallInvalidFontPackageUser\", \"[fonts]\")\n{\n    TestDataFile testFont(s_InvalidFontFile);\n    auto context = FontContext();\n    context.PackageId = L\"TestPackage\";\n    context.PackageVersion = L\"1.0.0.0\";\n    context.InstallerSource = InstallerSource::WinGet;\n    context.Scope = ScopeEnum::User;\n    context.AddPackageFile(testFont.GetPath());\n    const auto& result = InstallFontPackage(context);\n    REQUIRE(result.HResult == APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_SUPPORTED);\n}\n\nTEST_CASE(\"RemoveFontPackageUser\", \"[fonts]\")\n{\n    TestDataFile testFont(s_FontFile);\n\n    // Calling remove should always be successful when font doesn't exist.\n    auto context = FontContext();\n    context.PackageId = L\"TestPackage\";\n    context.PackageVersion = L\"1.0.0.0\";\n    context.InstallerSource = InstallerSource::WinGet;\n    context.Scope = ScopeEnum::User;\n    context.AddPackageFile(testFont.GetPath());\n\n    const auto& result = UninstallFontPackage(context);\n    REQUIRE(result.HResult == S_OK);\n\n    auto fontValidationResult = ValidateFontPackage(context);\n    REQUIRE(fontValidationResult.Status == FontStatus::Absent);\n}\n\nTEST_CASE(\"InstallValidFontPackageUser\", \"[fonts]\")\n{\n    // The test will move the file, so for idempotency we need\n    // to use a file that can be replaced.\n    TestDataFile testFontBase(s_FontFile);\n    TestCommon::TempDirectory tempDirectory(\"TempDirectory\");\n    std::filesystem::path testFontCopyPath = tempDirectory.GetPath() / s_FontFileTemp;\n    if (!std::filesystem::exists(testFontCopyPath))\n    {\n        std::filesystem::copy(testFontBase.GetPath(), testFontCopyPath);\n    }\n\n    // Use the copied font for the test\n    TestDataFile testFont(testFontCopyPath);\n    auto context = FontContext();\n    context.PackageId = L\"TestPackage\";\n    context.PackageVersion = L\"1.0.0.0\";\n    context.InstallerSource = InstallerSource::WinGet;\n    context.Scope = ScopeEnum::User;\n    context.Force = true;\n    context.AddPackageFile(testFont.GetPath());\n\n    auto preinstallValidation = ValidateFontPackage(context);\n    REQUIRE(preinstallValidation.Status == FontStatus::Absent);\n\n    auto installResult = InstallFontPackage(context);\n    REQUIRE(installResult.HResult == S_OK);\n\n    auto postinstallValidation = ValidateFontPackage(context);\n    REQUIRE(postinstallValidation.Status == FontStatus::OK);\n\n    auto uninstallResult = UninstallFontPackage(context);\n    REQUIRE(uninstallResult.HResult == S_OK);\n\n    auto postuninstallValidation = ValidateFontPackage(context);\n    REQUIRE(postuninstallValidation.Status == FontStatus::Absent);\n}\n\nTEST_CASE(\"RemoveFontPackageMachine\", \"[fonts]\")\n{\n    if (!AppInstaller::Runtime::IsRunningAsAdmin())\n    {\n        WARN(\"Test requires admin privilege. Skipped.\");\n        return;\n    }\n\n    TestDataFile testFont(s_FontFile);\n\n    // Calling remove should always be successful when font doesn't exist.\n    auto context = FontContext();\n    context.PackageId = L\"TestPackage\";\n    context.PackageVersion = L\"1.0.0.0\";\n    context.InstallerSource = InstallerSource::WinGet;\n    context.Scope = ScopeEnum::Machine;\n    context.AddPackageFile(testFont.GetPath());\n\n    const auto& result = UninstallFontPackage(context);\n    REQUIRE(result.HResult == S_OK);\n\n    auto fontValidationResult = ValidateFontPackage(context);\n    REQUIRE(fontValidationResult.Status == FontStatus::Absent);\n}\n\nTEST_CASE(\"InstallValidFontPackageMachine\", \"[fonts]\")\n{\n    if (!AppInstaller::Runtime::IsRunningAsAdmin())\n    {\n        WARN(\"Test requires admin privilege. Skipped.\");\n        return;\n    }\n\n    // The test will move the file, so for idempotency we need\n    // to use a file that can be replaced.\n    TestDataFile testFontBase(s_FontFile);\n    TestCommon::TempDirectory tempDirectory(\"TempDirectory\");\n    std::filesystem::path testFontCopyPath = tempDirectory.GetPath() / s_FontFileTemp;\n    if (!std::filesystem::exists(testFontCopyPath))\n    {\n        std::filesystem::copy(testFontBase.GetPath(), testFontCopyPath);\n    }\n\n    // Use the copied font for the test\n    TestDataFile testFont(testFontCopyPath);\n\n    auto context = FontContext();\n    context.PackageId = L\"TestPackage\";\n    context.PackageVersion = L\"1.0.0.0\";\n    context.InstallerSource = InstallerSource::WinGet;\n    context.Scope = ScopeEnum::Machine;\n    context.Force = true;\n    context.AddPackageFile(testFont.GetPath());\n\n    auto preinstallValidation = ValidateFontPackage(context);\n    REQUIRE(preinstallValidation.Status == FontStatus::Absent);\n\n    auto installResult = InstallFontPackage(context);\n    REQUIRE(installResult.HResult == S_OK);\n\n    auto postinstallValidation = ValidateFontPackage(context);\n    REQUIRE(postinstallValidation.Status == FontStatus::OK);\n\n    auto uninstallResult = UninstallFontPackage(context);\n    REQUIRE(uninstallResult.HResult == S_OK);\n\n    auto postuninstallValidation = ValidateFontPackage(context);\n    REQUIRE(postuninstallValidation.Status == FontStatus::Absent);\n}\n"
  },
  {
    "path": "src/AppInstallerCLITests/GroupPolicy.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestSettings.h\"\r\n#include \"winget/GroupPolicy.h\"\r\n#include <AppInstallerStrings.h>\r\n#include <CertificateResources.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::Settings;\r\nusing namespace std::string_view_literals;\r\n\r\nnamespace\r\n{\r\n    std::wstring GetSourceJson(std::wstring_view name, std::wstring_view arg, std::wstring_view type, std::wstring_view data, std::wstring_view identifier, std::wstring_view trustLevel, std::wstring_view isExplicit, std::wstring_view pinningConfig = {})\r\n    {\r\n        std::wstringstream json;\r\n        json << L\"{ \\\"Name\\\":\\\"\" << name << L\"\\\", \\\"Arg\\\":\\\"\" << arg << L\"\\\", \\\"Type\\\":\\\"\" << type << L\"\\\", \\\"Data\\\":\\\"\" << data << L\"\\\", \\\"Identifier\\\":\\\"\" << identifier << L\"\\\", \\\"TrustLevel\\\":\" << trustLevel << L\", \\\"Explicit\\\":\" << isExplicit;\r\n        if (!pinningConfig.empty())\r\n        {\r\n            json << L\", \\\"CertificatePinning\\\":\" << pinningConfig;\r\n        }\r\n        json << \" }\";\r\n        return json.str();\r\n    }\r\n}\r\n\r\nTEST_CASE(\"GroupPolicy_NoPolicies\", \"[groupPolicy]\")\r\n{\r\n    auto policiesKey = RegCreateVolatileTestRoot();\r\n    GroupPolicy groupPolicy{ policiesKey.get() };\r\n\r\n    // Policies setting a value should be empty\r\n    REQUIRE(!groupPolicy.GetValue<ValuePolicy::SourceAutoUpdateIntervalInMinutes>().has_value());\r\n    REQUIRE(!groupPolicy.GetValue<ValuePolicy::AdditionalSources>().has_value());\r\n    REQUIRE(!groupPolicy.GetValue<ValuePolicy::AllowedSources>().has_value());\r\n\r\n    // Everything should be not configured\r\n    for (const auto& policy : TogglePolicy::GetAllPolicies())\r\n    {\r\n        REQUIRE(groupPolicy.GetState(policy.GetPolicy()) == PolicyState::NotConfigured);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"GroupPolicy_UpdateInterval\", \"[groupPolicy]\")\r\n{\r\n    auto policiesKey = RegCreateVolatileTestRoot();\r\n\r\n    SECTION(\"Good value\")\r\n    {\r\n        SetRegistryValue(policiesKey.get(), SourceUpdateIntervalPolicyValueName, 5);\r\n        GroupPolicy groupPolicy{ policiesKey.get() };\r\n\r\n        auto policy = groupPolicy.GetValue<ValuePolicy::SourceAutoUpdateIntervalInMinutes>();\r\n        REQUIRE(policy.has_value());\r\n        REQUIRE(*policy == 5);\r\n    }\r\n\r\n    SECTION(\"Wrong type\")\r\n    {\r\n        SetRegistryValue(policiesKey.get(), SourceUpdateIntervalPolicyValueName, L\"Wrong\");\r\n        GroupPolicy groupPolicy{ policiesKey.get() };\r\n\r\n        auto policy = groupPolicy.GetValue<ValuePolicy::SourceAutoUpdateIntervalInMinutes>();\r\n        REQUIRE(!policy.has_value());\r\n    }\r\n}\r\n\r\n\r\nTEST_CASE(\"GroupPolicy_UpdateInterval_OldName\", \"[groupPolicy]\")\r\n{\r\n    auto policiesKey = RegCreateVolatileTestRoot();\r\n\r\n    SECTION(\"New name shadows old\")\r\n    {\r\n        SECTION(\"When old is valid\")\r\n        {\r\n            SetRegistryValue(policiesKey.get(), SourceUpdateIntervalPolicyOldValueName, 3);\r\n        }\r\n        SECTION(\"When old is invalid\")\r\n        {\r\n            SetRegistryValue(policiesKey.get(), SourceUpdateIntervalPolicyOldValueName, L\"Invalid type\");\r\n        }\r\n\r\n        SetRegistryValue(policiesKey.get(), SourceUpdateIntervalPolicyValueName, 1);\r\n        GroupPolicy groupPolicy{ policiesKey.get() };\r\n\r\n        auto policy = groupPolicy.GetValue<ValuePolicy::SourceAutoUpdateIntervalInMinutes>();\r\n        REQUIRE(policy.has_value());\r\n        REQUIRE(*policy == 1);\r\n    }\r\n\r\n    SECTION(\"Fallback to old name\")\r\n    {\r\n        SECTION(\"When new name has invalid data\")\r\n        {\r\n            SetRegistryValue(policiesKey.get(), SourceUpdateIntervalPolicyValueName, L\"Wrong type\");\r\n            SetRegistryValue(policiesKey.get(), SourceUpdateIntervalPolicyOldValueName, 20);\r\n            GroupPolicy groupPolicy{ policiesKey.get() };\r\n\r\n            // We should not fall back on this case\r\n            auto policy = groupPolicy.GetValue<ValuePolicy::SourceAutoUpdateIntervalInMinutes>();\r\n            REQUIRE(!policy.has_value());\r\n        }\r\n        SECTION(\"When new name is missing\")\r\n        {\r\n            // Don't add the registry value with the new name\r\n            SetRegistryValue(policiesKey.get(), SourceUpdateIntervalPolicyOldValueName, 20);\r\n            GroupPolicy groupPolicy{ policiesKey.get() };\r\n\r\n            auto policy = groupPolicy.GetValue<ValuePolicy::SourceAutoUpdateIntervalInMinutes>();\r\n            REQUIRE(policy.has_value());\r\n            REQUIRE(*policy == 20);\r\n        }\r\n    }\r\n}\r\n\r\nTEST_CASE(\"GroupPolicy_Sources\", \"[groupPolicy]\")\r\n{\r\n    auto policiesKey = RegCreateVolatileTestRoot();\r\n\r\n    // Note that the following tests mix using Additional/Allowed sources policy.\r\n    SECTION(\"Single source\")\r\n    {\r\n        // We can read single source correctly\r\n        auto additionalSourcesKey = RegCreateVolatileSubKey(policiesKey.get(), AdditionalSourcesPolicyKeyName);\r\n        SetRegistryValue(additionalSourcesKey.get(), L\"0\", GetSourceJson(L\"source-name\", L\"source-arg\", L\"source-type\", L\"source-data\", L\"source-identifier\", L\"[\\\"Trusted\\\", \\\"StoreOrigin\\\"]\", L\"true\"), REG_SZ);\r\n        GroupPolicy groupPolicy{ policiesKey.get() };\r\n\r\n        auto policy = groupPolicy.GetValue<ValuePolicy::AdditionalSources>();\r\n        REQUIRE(policy.has_value());\r\n        REQUIRE(policy->size() == 1);\r\n        REQUIRE(policy.value()[0].Name == \"source-name\");\r\n        REQUIRE(policy.value()[0].Arg == \"source-arg\");\r\n        REQUIRE(policy.value()[0].Type == \"source-type\");\r\n        REQUIRE(policy.value()[0].Data == \"source-data\");\r\n        REQUIRE(policy.value()[0].Identifier == \"source-identifier\");\r\n        REQUIRE(policy.value()[0].TrustLevel[0] == \"Trusted\");\r\n        REQUIRE(policy.value()[0].TrustLevel[1] == \"StoreOrigin\");\r\n        REQUIRE(policy.value()[0].Explicit == true);\r\n    }\r\n    SECTION(\"Missing field\")\r\n    {\r\n        // A single missing field causes the source to not be read.\r\n        // \"Type\" is missing here.\r\n        std::wstring sourceJson = L\"{ \\\"Name\\\":\\\"source_name\\\", \\\"Arg\\\":\\\"source_arg\\\", \\\"Data\\\":\\\"source_data\\\", \\\"Identifier\\\":\\\"source_identifier\\\" }\";\r\n        auto additionalSourcesKey = RegCreateVolatileSubKey(policiesKey.get(), AllowedSourcesPolicyKeyName);\r\n        SetRegistryValue(additionalSourcesKey.get(), L\"0\", sourceJson, REG_SZ);\r\n        GroupPolicy groupPolicy{ policiesKey.get() };\r\n\r\n        auto policy = groupPolicy.GetValue<ValuePolicy::AllowedSources>();\r\n        REQUIRE(policy.has_value());\r\n        REQUIRE(policy->empty());\r\n    }\r\n    SECTION(\"Invalid field\")\r\n    {\r\n        // A single invalid field causes the source to not be read.\r\n        // \"Data\" is invalid as it is an object, not a string.\r\n        std::wstring sourceJson = L\"{ \\\"Name\\\":\\\"source_name\\\", \\\"Arg\\\":\\\"source_arg\\\", \\\"Data\\\":{}, \\\"Type\\\":\\\"source_type\\\", \\\"Identifier\\\":\\\"source_identifier\\\" }\";\r\n        auto additionalSourcesKey = RegCreateVolatileSubKey(policiesKey.get(), AdditionalSourcesPolicyKeyName);\r\n        SetRegistryValue(additionalSourcesKey.get(), L\"0\", sourceJson, REG_SZ);\r\n        GroupPolicy groupPolicy{ policiesKey.get() };\r\n\r\n        auto policy = groupPolicy.GetValue<ValuePolicy::AdditionalSources>();\r\n        REQUIRE(policy.has_value());\r\n        REQUIRE(policy->empty());\r\n    }\r\n    SECTION(\"Invalid source JSON\")\r\n    {\r\n        // An invalid source JSON causes the source to not be read.\r\n        auto additionalSourcesKey = RegCreateVolatileSubKey(policiesKey.get(), AllowedSourcesPolicyKeyName);\r\n        SetRegistryValue(additionalSourcesKey.get(), L\"0\", L\"not a JSON\", REG_SZ);\r\n        GroupPolicy groupPolicy{ policiesKey.get() };\r\n\r\n        auto policy = groupPolicy.GetValue<ValuePolicy::AllowedSources>();\r\n        REQUIRE(policy.has_value());\r\n        REQUIRE(policy->empty());\r\n    }\r\n    SECTION(\"Missing key\")\r\n    {\r\n        // If the key does not exist we should not get anything.\r\n        GroupPolicy groupPolicy{ policiesKey.get() };\r\n\r\n        auto policy = groupPolicy.GetValue<ValuePolicy::AdditionalSources>();\r\n        REQUIRE_FALSE(policy.has_value());\r\n    }\r\n    SECTION(\"Empty key\")\r\n    {\r\n        // If the key is empty we should get an empty list.\r\n        // Note that the policy editor doesn't actually create empty keys.\r\n        auto additionalSourcesKey = RegCreateVolatileSubKey(policiesKey.get(), AllowedSourcesPolicyKeyName);\r\n        GroupPolicy groupPolicy{ policiesKey.get() };\r\n\r\n        auto policy = groupPolicy.GetValue<ValuePolicy::AllowedSources>();\r\n        REQUIRE(policy.has_value());\r\n        REQUIRE(policy->empty());\r\n    }\r\n    SECTION(\"Valid list\")\r\n    {\r\n        // We should be able to read multiple values.\r\n        // No specific order is required, but it will likely be the same.\r\n        auto additionalSourcesKey = RegCreateVolatileSubKey(policiesKey.get(), AdditionalSourcesPolicyKeyName);\r\n        SetRegistryValue(additionalSourcesKey.get(), L\"0\", GetSourceJson(L\"s0-name\", L\"s0-arg\", L\"s0-type\", L\"s0-data\", L\"s0-identifier\", L\"[\\\"None\\\"]\", L\"true\"), REG_SZ);\r\n        SetRegistryValue(additionalSourcesKey.get(), L\"1\", GetSourceJson(L\"s1-name\", L\"s1-arg\", L\"s1-type\", L\"s1-data\", L\"s1-identifier\", L\"[\\\"Trusted\\\", \\\"StoreOrigin\\\"]\", L\"false\"), REG_SZ);\r\n        SetRegistryValue(additionalSourcesKey.get(), L\"2\", GetSourceJson(L\"s2-name\", L\"s2-arg\", L\"s2-type\", L\"s2-data\", L\"s2-identifier\", L\"[\\\"StoreOrigin\\\", \\\"Trusted\\\"]\", L\"true\"), REG_SZ);\r\n        GroupPolicy groupPolicy{ policiesKey.get() };\r\n\r\n        auto policy = groupPolicy.GetValue<ValuePolicy::AdditionalSources>();\r\n        REQUIRE(policy.has_value());\r\n        REQUIRE(policy->size() == 3);\r\n\r\n        REQUIRE(policy.value()[0].Name == \"s0-name\");\r\n        REQUIRE(policy.value()[0].Arg == \"s0-arg\");\r\n        REQUIRE(policy.value()[0].Type == \"s0-type\");\r\n        REQUIRE(policy.value()[0].Data == \"s0-data\");\r\n        REQUIRE(policy.value()[0].Identifier == \"s0-identifier\");\r\n        REQUIRE(policy.value()[0].TrustLevel[0] == \"None\");\r\n        REQUIRE(policy.value()[0].Explicit == true);\r\n\r\n        REQUIRE(policy.value()[1].Name == \"s1-name\");\r\n        REQUIRE(policy.value()[1].Arg == \"s1-arg\");\r\n        REQUIRE(policy.value()[1].Type == \"s1-type\");\r\n        REQUIRE(policy.value()[1].Data == \"s1-data\");\r\n        REQUIRE(policy.value()[1].Identifier == \"s1-identifier\");\r\n        REQUIRE(policy.value()[1].TrustLevel[0] == \"Trusted\");\r\n        REQUIRE(policy.value()[1].TrustLevel[1] == \"StoreOrigin\");\r\n        REQUIRE(policy.value()[1].Explicit == false);\r\n\r\n        REQUIRE(policy.value()[2].Name == \"s2-name\");\r\n        REQUIRE(policy.value()[2].Arg == \"s2-arg\");\r\n        REQUIRE(policy.value()[2].Type == \"s2-type\");\r\n        REQUIRE(policy.value()[2].Data == \"s2-data\");\r\n        REQUIRE(policy.value()[2].Identifier == \"s2-identifier\");\r\n        REQUIRE(policy.value()[2].TrustLevel[0] == \"StoreOrigin\");\r\n        REQUIRE(policy.value()[2].TrustLevel[1] == \"Trusted\");\r\n        REQUIRE(policy.value()[2].Explicit == true);\r\n    }\r\n    SECTION(\"Invalid source in list\")\r\n    {\r\n        // If a single source is invalid we should still get all others\r\n        auto additionalSourcesKey = RegCreateVolatileSubKey(policiesKey.get(), AdditionalSourcesPolicyKeyName);\r\n        SetRegistryValue(additionalSourcesKey.get(), L\"0\", GetSourceJson(L\"s0-name\", L\"s0-arg\", L\"s0-type\", L\"s0-data\", L\"s0-identifier\", L\"[\\\"Trusted\\\", \\\"StoreOrigin\\\"]\", L\"false\"), REG_SZ);\r\n        SetRegistryValue(additionalSourcesKey.get(), L\"1\", L\"not a source\", REG_SZ);\r\n        SetRegistryValue(additionalSourcesKey.get(), L\"2\", GetSourceJson(L\"s2-name\", L\"s2-arg\", L\"s2-type\", L\"s2-data\", L\"s2-identifier\", L\"[\\\"StoreOrigin\\\", \\\"Trusted\\\"]\", L\"true\"), REG_SZ);\r\n        GroupPolicy groupPolicy{ policiesKey.get() };\r\n\r\n        auto policy = groupPolicy.GetValue<ValuePolicy::AdditionalSources>();\r\n        REQUIRE(policy.has_value());\r\n        REQUIRE(policy->size() == 2);\r\n\r\n        REQUIRE(policy.value()[0].Name == \"s0-name\");\r\n        REQUIRE(policy.value()[0].Arg == \"s0-arg\");\r\n        REQUIRE(policy.value()[0].Type == \"s0-type\");\r\n        REQUIRE(policy.value()[0].Data == \"s0-data\");\r\n        REQUIRE(policy.value()[0].Identifier == \"s0-identifier\");\r\n        REQUIRE(policy.value()[0].TrustLevel[0] == \"Trusted\");\r\n        REQUIRE(policy.value()[0].TrustLevel[1] == \"StoreOrigin\");\r\n        REQUIRE(policy.value()[0].Explicit == false);\r\n\r\n        REQUIRE(policy.value()[1].Name == \"s2-name\");\r\n        REQUIRE(policy.value()[1].Arg == \"s2-arg\");\r\n        REQUIRE(policy.value()[1].Type == \"s2-type\");\r\n        REQUIRE(policy.value()[1].Data == \"s2-data\");\r\n        REQUIRE(policy.value()[1].Identifier == \"s2-identifier\");\r\n        REQUIRE(policy.value()[1].TrustLevel[0] == \"StoreOrigin\");\r\n        REQUIRE(policy.value()[1].TrustLevel[1] == \"Trusted\");\r\n        REQUIRE(policy.value()[1].Explicit == true);\r\n    }\r\n    SECTION(\"Exported JSON\")\r\n    {\r\n        // Policy should be able to use an exported JSON strings\r\n        SourceFromPolicy source;\r\n        source.Name = \"json-name\";\r\n        source.Type = \"json-type\";\r\n        source.Arg = \"json-arg\";\r\n        source.Data = \"json-data\";\r\n        source.Identifier = \"json-id\";\r\n        source.TrustLevel = {\"Trusted\", \"StoreOrigin\"};\r\n        source.Explicit = false;\r\n\r\n        auto additionalSourcesKey = RegCreateVolatileSubKey(policiesKey.get(), AllowedSourcesPolicyKeyName);\r\n        SetRegistryValue(additionalSourcesKey.get(), L\"0\", AppInstaller::Utility::ConvertToUTF16(source.ToJsonString()));\r\n        GroupPolicy groupPolicy{ policiesKey.get() };\r\n\r\n        auto policy = groupPolicy.GetValue<ValuePolicy::AllowedSources>();\r\n        REQUIRE(policy.has_value());\r\n        REQUIRE(policy->size() == 1);\r\n        REQUIRE(policy.value()[0].Name == source.Name);\r\n        REQUIRE(policy.value()[0].Arg == source.Arg);\r\n        REQUIRE(policy.value()[0].Type == source.Type);\r\n        REQUIRE(policy.value()[0].Data == source.Data);\r\n        REQUIRE(policy.value()[0].Identifier == source.Identifier);\r\n        REQUIRE(policy.value()[0].TrustLevel[0] == source.TrustLevel[0]); // Trusted\r\n        REQUIRE(policy.value()[0].TrustLevel[1] == source.TrustLevel[1]); // StoreOrigin\r\n        REQUIRE(policy.value()[0].Explicit == source.Explicit);\r\n    }\r\n    SECTION(\"Source with PinningConfiguration\")\r\n    {\r\n        using namespace AppInstaller::Certificates;\r\n\r\n        auto additionalSourcesKey = RegCreateVolatileSubKey(policiesKey.get(), AdditionalSourcesPolicyKeyName);\r\n\r\n        PinningDetails rootCert;\r\n        rootCert.LoadCertificate(IDX_CERTIFICATE_STORE_ROOT_2, CERTIFICATE_RESOURCE_TYPE);\r\n        PinningDetails intermediateCert;\r\n        intermediateCert.LoadCertificate(IDX_CERTIFICATE_STORE_INTERMEDIATE_2, CERTIFICATE_RESOURCE_TYPE);\r\n        PinningDetails leafCert;\r\n        leafCert.LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE);\r\n\r\n        auto getBytesString = [](const PinningDetails& details)\r\n        {\r\n            std::vector<BYTE> bytes;\r\n            bytes.assign(details.GetCertificate()->pbCertEncoded, details.GetCertificate()->pbCertEncoded + details.GetCertificate()->cbCertEncoded);\r\n            return AppInstaller::Utility::ConvertToUTF16(AppInstaller::Utility::ConvertToHexString(bytes));\r\n        };\r\n\r\n        std::wostringstream pinningConfig;\r\n        pinningConfig <<\r\nLR\"({\r\n    \"Chains\": [{\r\n        \"Chain\":[\r\n            { \"Validation\": [\"publickey\"], \"EmbeddedCertificate\": \")\" << getBytesString(rootCert) << LR\"(\" },\r\n            { \"Validation\": [\"subject\",\"issuer\"], \"EmbeddedCertificate\": \")\" << getBytesString(intermediateCert) << LR\"(\" },\r\n            { \"Validation\": [\"subject\",\"issuer\"], \"EmbeddedCertificate\": \")\" << getBytesString(leafCert) << LR\"(\" }\r\n        ]\r\n    }]\r\n})\";\r\n\r\n        SetRegistryValue(additionalSourcesKey.get(), L\"0\", GetSourceJson(L\"source-name\", L\"source-arg\", L\"source-type\", L\"source-data\", L\"source-identifier\", L\"[\\\"Trusted\\\", \\\"StoreOrigin\\\"]\", L\"true\", pinningConfig.str()), REG_SZ);\r\n        GroupPolicy groupPolicy{ policiesKey.get() };\r\n\r\n        auto policy = groupPolicy.GetValue<ValuePolicy::AdditionalSources>();\r\n        REQUIRE(policy.has_value());\r\n        REQUIRE(policy->size() == 1);\r\n        const auto& sourceInfo = policy.value()[0];\r\n        REQUIRE(sourceInfo.Name == \"source-name\");\r\n        REQUIRE(sourceInfo.Arg == \"source-arg\");\r\n        REQUIRE(sourceInfo.Type == \"source-type\");\r\n        REQUIRE(sourceInfo.Data == \"source-data\");\r\n        REQUIRE(sourceInfo.Identifier == \"source-identifier\");\r\n        REQUIRE(sourceInfo.TrustLevel[0] == \"Trusted\");\r\n        REQUIRE(sourceInfo.TrustLevel[1] == \"StoreOrigin\");\r\n        REQUIRE(sourceInfo.Explicit == true);\r\n\r\n        // Use loaded pinning config and validate against leaf certificate\r\n        REQUIRE(!sourceInfo.PinningConfiguration.IsEmpty());\r\n        REQUIRE(sourceInfo.PinningConfiguration.Validate(leafCert.GetCertificate()));\r\n    }\r\n}\r\n\r\nTEST_CASE(\"GroupPolicy_Toggle\", \"[groupPolicy]\")\r\n{\r\n    auto policiesKey = RegCreateVolatileTestRoot();\r\n\r\n    SECTION(\"'None' is not configured\")\r\n    {\r\n        GroupPolicy groupPolicy{ policiesKey.get() };\r\n        REQUIRE(groupPolicy.GetState(TogglePolicy::Policy::None) == PolicyState::NotConfigured);\r\n        REQUIRE(groupPolicy.IsEnabled(TogglePolicy::Policy::None));\r\n    }\r\n\r\n    SECTION(\"Enabled\")\r\n    {\r\n        SetRegistryValue(policiesKey.get(), WinGetPolicyValueName, 1);\r\n        GroupPolicy groupPolicy{ policiesKey.get() };\r\n        REQUIRE(groupPolicy.GetState(TogglePolicy::Policy::WinGet) == PolicyState::Enabled);\r\n        REQUIRE(groupPolicy.IsEnabled(TogglePolicy::Policy::WinGet));\r\n    }\r\n\r\n    SECTION(\"Disabled\")\r\n    {\r\n        SetRegistryValue(policiesKey.get(), LocalManifestsPolicyValueName, 0);\r\n        GroupPolicy groupPolicy{ policiesKey.get() };\r\n        REQUIRE(groupPolicy.GetState(TogglePolicy::Policy::LocalManifestFiles) == PolicyState::Disabled);\r\n        REQUIRE_FALSE(groupPolicy.IsEnabled(TogglePolicy::Policy::LocalManifestFiles));\r\n    }\r\n\r\n    SECTION(\"Wrong type\")\r\n    {\r\n        SetRegistryValue(policiesKey.get(), ExperimentalFeaturesPolicyValueName, L\"Wrong\");\r\n        GroupPolicy groupPolicy{ policiesKey.get() };\r\n        REQUIRE(groupPolicy.GetState(TogglePolicy::Policy::DefaultSource) == PolicyState::NotConfigured);\r\n        REQUIRE(groupPolicy.IsEnabled(TogglePolicy::Policy::DefaultSource));\r\n    }\r\n}\r\n\r\nTEST_CASE(\"GroupPolicy_AllEnabled\", \"[groupPolicy]\")\r\n{\r\n    auto policiesKey = RegCreateVolatileTestRoot();\r\n    SetRegistryValue(policiesKey.get(), WinGetPolicyValueName, 1);\r\n    SetRegistryValue(policiesKey.get(), WinGetSettingsPolicyValueName, 1);\r\n    SetRegistryValue(policiesKey.get(), ExperimentalFeaturesPolicyValueName, 1);\r\n    SetRegistryValue(policiesKey.get(), LocalManifestsPolicyValueName, 1);\r\n    SetRegistryValue(policiesKey.get(), EnableHashOverridePolicyValueName, 1);\r\n    SetRegistryValue(policiesKey.get(), EnableLocalArchiveMalwareScanOverridePolicyValueName, 1);\r\n    SetRegistryValue(policiesKey.get(), DefaultSourcePolicyValueName, 1);\r\n    SetRegistryValue(policiesKey.get(), MSStoreSourcePolicyValueName, 1);\r\n    SetRegistryValue(policiesKey.get(), FontSourcePolicyValueName, 1);\r\n    SetRegistryValue(policiesKey.get(), AdditionalSourcesPolicyValueName, 1);\r\n    SetRegistryValue(policiesKey.get(), AllowedSourcesPolicyValueName, 1);\r\n    SetRegistryValue(policiesKey.get(), BypassCertificatePinningForMicrosoftStoreValueName, 1);\r\n    SetRegistryValue(policiesKey.get(), EnableWindowsPackageManagerCommandLineInterfaces, 1);\r\n    SetRegistryValue(policiesKey.get(), ConfigurationPolicyValueName, 1);\r\n    SetRegistryValue(policiesKey.get(), ProxyCommandLineOptionsPolicyValueName, 1);\r\n    SetRegistryValue(policiesKey.get(), McpServerValueName, 1);\r\n\r\n    GroupPolicy groupPolicy{ policiesKey.get() };\r\n    for (const auto& policy : TogglePolicy::GetAllPolicies())\r\n    {\r\n        REQUIRE(groupPolicy.GetState(policy.GetPolicy()) == PolicyState::Enabled);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/HashCommand.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"Commands/HashCommand.h\"\r\n\r\nusing namespace std::string_literals;\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::CLI;\r\n\r\nTEST_CASE(\"HashCommandWithTestMsix\", \"[Sha256Hash]\")\r\n{\r\n    std::ostringstream hashOutput;\r\n    Execution::Context context{ hashOutput, std::cin };\r\n    context.Args.AddArg(Execution::Args::Type::HashFile, TestDataFile(\"TestSignedApp.msix\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::Msix);\r\n    HashCommand hashCommand({});\r\n\r\n    hashCommand.Execute(context);\r\n\r\n    REQUIRE(hashOutput.str().find(\"Sha256: 6a2d3683fa19bf00e58e07d1313d20a5f5735ebbd6a999d33381d28740ee07ea\") != std::string::npos);\r\n    REQUIRE(hashOutput.str().find(\"SignatureSha256: 138781c3e6f635240353f3d14d1d57bdcb89413e49be63b375e6a5d7b93b0d07\") != std::string::npos);\r\n}"
  },
  {
    "path": "src/AppInstallerCLITests/HttpClientHelper.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestRestRequestHandler.h\"\r\n#include <AppInstallerErrors.h>\r\n#include <AppInstallerRuntime.h>\r\n#include <AppInstallerStrings.h>\r\n#include <winget/Certificates.h>\r\n#include <winget/HttpClientHelper.h>\r\n#include <CertificateResources.h>\r\n#include <winget/JsonUtil.h>\r\n\r\nusing namespace AppInstaller::Http;\r\nusing namespace AppInstaller::Runtime;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::Certificates;\r\n\r\nTEST_CASE(\"ExtractJsonResponse_UnsupportedMimeType\", \"[RestSource][RestSearch]\")\r\n{\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, L\"\", web::http::details::mime_types::text_plain) };\r\n    REQUIRE_THROWS_HR(helper.HandleGet(L\"https://testUri\"), APPINSTALLER_CLI_ERROR_RESTAPI_UNSUPPORTED_MIME_TYPE);\r\n}\r\n\r\nTEST_CASE(\"ValidateAndExtractResponse_ServiceUnavailable\", \"[RestSource]\")\r\n{\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::ServiceUnavailable) };\r\n    REQUIRE_THROWS_HR(helper.HandleGet(L\"https://testUri\"), APPINSTALLER_CLI_ERROR_SERVICE_UNAVAILABLE);\r\n}\r\n\r\nTEST_CASE(\"ValidateAndExtractResponse_NotFound\", \"[RestSource]\")\r\n{\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::NotFound) };\r\n    REQUIRE_THROWS_HR(helper.HandleGet(L\"https://testUri\"), APPINSTALLER_CLI_ERROR_RESTAPI_ENDPOINT_NOT_FOUND);\r\n}\r\n\r\nTEST_CASE(\"EnsureDefaultUserAgent\", \"[RestSource]\")\r\n{\r\n    HttpClientHelper helper{ GetTestRestRequestHandler([](const web::http::http_request& request)\r\n        {\r\n            auto itr = request.headers().find(web::http::header_names::user_agent);\r\n            if (itr != request.headers().end() &&\r\n                itr->second.find(ConvertToUTF16(GetClientVersion())) != utility::string_t::npos &&\r\n                itr->second.find(ConvertToUTF16(GetPackageVersion())) != utility::string_t::npos)\r\n            {\r\n                return web::http::status_codes::OK;\r\n            }\r\n            else\r\n            {\r\n                return web::http::status_codes::BadRequest;\r\n            }\r\n        }) };\r\n\r\n    SECTION(\"GET\")\r\n    {\r\n        REQUIRE_NOTHROW(helper.HandleGet(L\"https://testUri\"));\r\n    }\r\n    SECTION(\"POST\")\r\n    {\r\n        REQUIRE_NOTHROW(helper.HandlePost(L\"https://testUri\", {}));\r\n    }\r\n}\r\n\r\nTEST_CASE(\"HttpClientHelper_PinningConfiguration\", \"[RestSource]\")\r\n{\r\n    // Create the Store chain config\r\n    PinningChain chain;\r\n    auto chainElement = chain.Root();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_ROOT_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::PublicKey);\r\n    chainElement = chainElement.Next();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_INTERMEDIATE_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::Subject | PinningVerificationType::Issuer);\r\n    chainElement = chainElement.Next();\r\n    chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::Subject | PinningVerificationType::Issuer);\r\n\r\n    PinningConfiguration config;\r\n    config.AddChain(chain);\r\n\r\n    HttpClientHelper helper;\r\n    helper.SetPinningConfiguration(config);\r\n\r\n    REQUIRE_THROWS_HR(helper.HandleGet(L\"https://github.com\"), APPINSTALLER_CLI_ERROR_PINNED_CERTIFICATE_MISMATCH);\r\n}\r\n\r\nTEST_CASE(\"HttpClientHelper_CallerCharacters\", \"[RestSource]\")\r\n{\r\n    HttpClientHelper::HttpRequestHeaders headers;\r\n    headers.emplace(web::http::header_names::user_agent, AppInstaller::JSON::GetUtilityString(AppInstaller::Runtime::GetUserAgent(\"\\xe6\\xb5\\x8b\\xe8\\xaf\\x95\")));\r\n\r\n    HttpClientHelper helper;\r\n    REQUIRE_THROWS_HR(helper.HandleGet(L\"https://github.com\", headers), APPINSTALLER_CLI_ERROR_RESTAPI_UNSUPPORTED_MIME_TYPE);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/IconExtraction.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <winget/IconExtraction.h>\r\n#include <AppInstallerStrings.h>\r\n\r\nusing namespace AppInstaller::Repository;\r\n\r\nTEST_CASE(\"ExtractIconFromBinaryFile\", \"IconExtraction\")\r\n{\r\n    auto extracted = ExtractIconFromBinaryFile(TestCommon::TestDataFile{ \"notepad.exe\" }.GetPath());\r\n\r\n    std::ifstream expectedIconFile{ TestCommon::TestDataFile{ \"notepad.ico\" }.GetPath(), std::ios::in | std::ios::binary};\r\n    auto expected = AppInstaller::Utility::ReadEntireStreamAsByteArray(expectedIconFile);\r\n\r\n    REQUIRE(expected == extracted);\r\n}"
  },
  {
    "path": "src/AppInstallerCLITests/ImportFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestHooks.h\"\r\n#include \"WorkflowCommon.h\"\r\n#include <Commands/ImportCommand.h>\r\n#include <winget/Settings.h>\r\n#include <Workflows/ImportExportFlow.h>\r\n#include <Workflows/ShellExecuteInstallerHandler.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::CLI;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Utility::literals;\r\n\r\nvoid OverrideForImportSource(TestContext& context, bool useTestCompositeSource = false)\r\n{\r\n    auto testCompositeSource = CreateTestSource({\r\n        TSR::TestInstaller_Exe,\r\n        TSR::TestInstaller_Exe_Dependencies,\r\n        TSR::TestInstaller_Exe_LicenseAgreement,\r\n        TSR::TestInstaller_Exe_NothingInstalled,\r\n        TSR::TestInstaller_Msix,\r\n        TSR::TestInstaller_Msix_WFDependency,\r\n        });\r\n\r\n    context.Override({ \"OpenPredefinedSource\", [=](TestContext& context)\r\n    {\r\n        auto installedSource = useTestCompositeSource ? testCompositeSource : std::make_shared<TestSource>();\r\n        context.Add<Execution::Data::Source>(Source{ installedSource });\r\n    } });\r\n\r\n    context.Override({ Workflow::OpenSourcesForImport, [=](TestContext& context)\r\n    {\r\n        context.Add<Execution::Data::Sources>(std::vector<Source>{ Source{ testCompositeSource } });\r\n    } });\r\n}\r\n\r\nTEST_CASE(\"ImportFlow_Successful\", \"[ImportFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile exeInstallResultPath(\"TestExeInstalled.txt\");\r\n    TestCommon::TempFile msixInstallResultPath(\"TestMsixInstalled.txt\");\r\n\r\n    std::ostringstream importOutput;\r\n    TestContext context{ importOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForImportSource(context);\r\n    OverrideForMSIX(context);\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::ImportFile, TestDataFile(\"ImportFile-Good.json\").GetPath().string());\r\n\r\n    ImportCommand importCommand({});\r\n    importCommand.Execute(context);\r\n    INFO(importOutput.str());\r\n\r\n    // Verify all packages were installed\r\n    REQUIRE(std::filesystem::exists(exeInstallResultPath.GetPath()));\r\n    REQUIRE(std::filesystem::exists(msixInstallResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"ImportFlow_PackageAlreadyInstalled\", \"[ImportFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile exeInstallResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream importOutput;\r\n    TestContext context{ importOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForImportSource(context, true);\r\n    context.Args.AddArg(Execution::Args::Type::ImportFile, TestDataFile(\"ImportFile-Good-AlreadyInstalled.json\").GetPath().string());\r\n\r\n    ImportCommand importCommand({});\r\n    importCommand.Execute(context);\r\n    INFO(importOutput.str());\r\n\r\n    // Exe should not have been installed again\r\n    REQUIRE(!std::filesystem::exists(exeInstallResultPath.GetPath()));\r\n    REQUIRE(importOutput.str().find(Resource::LocString(Resource::String::MultiQueryPackageAlreadyInstalled(\"AppInstallerCliTest.TestExeInstaller\"_liv)).get()) != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"ImportFlow_IgnoreVersions\", \"[ImportFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile exeInstallResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream importOutput;\r\n    TestContext context{ importOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForImportSource(context);\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::ImportFile, TestDataFile(\"ImportFile-Good-AlreadyInstalled.json\").GetPath().string());\r\n    context.Args.AddArg(Execution::Args::Type::IgnoreVersions);\r\n\r\n    ImportCommand importCommand({});\r\n    importCommand.Execute(context);\r\n    INFO(importOutput.str());\r\n\r\n    // Specified version is already installed. It should have been updated since we ignored the version.\r\n    REQUIRE(std::filesystem::exists(exeInstallResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"ImportFlow_MissingSource\", \"[ImportFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile exeInstallResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream importOutput;\r\n    TestContext context{ importOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    context.Args.AddArg(Execution::Args::Type::ImportFile, TestDataFile(\"ImportFile-Bad-UnknownSource.json\").GetPath().string());\r\n\r\n    ImportCommand importCommand({});\r\n    importCommand.Execute(context);\r\n    INFO(importOutput.str());\r\n\r\n    // Installer should not be called\r\n    REQUIRE(!std::filesystem::exists(exeInstallResultPath.GetPath()));\r\n    REQUIRE(importOutput.str().find(Resource::LocString(Resource::String::ImportSourceNotInstalled(\"TestSource\"_liv)).get()) != std::string::npos);\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_SOURCE_NAME_DOES_NOT_EXIST);\r\n}\r\n\r\nTEST_CASE(\"ImportFlow_MissingPackage\", \"[ImportFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile exeInstallResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream importOutput;\r\n    TestContext context{ importOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForImportSource(context);\r\n    context.Args.AddArg(Execution::Args::Type::ImportFile, TestDataFile(\"ImportFile-Bad-UnknownPackage.json\").GetPath().string());\r\n\r\n    ImportCommand importCommand({});\r\n    importCommand.Execute(context);\r\n    INFO(importOutput.str());\r\n\r\n    // Installer should not be called\r\n    REQUIRE(!std::filesystem::exists(exeInstallResultPath.GetPath()));\r\n    REQUIRE(importOutput.str().find(Resource::LocString(Resource::String::MultiQueryPackageNotFound(\"MissingPackage\"_liv)).get()) != std::string::npos);\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_NOT_ALL_QUERIES_FOUND_SINGLE);\r\n}\r\n\r\nTEST_CASE(\"ImportFlow_IgnoreMissingPackage\", \"[ImportFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile exeInstallResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream importOutput;\r\n    TestContext context{ importOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForImportSource(context);\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::ImportFile, TestDataFile(\"ImportFile-Bad-UnknownPackage.json\").GetPath().string());\r\n    context.Args.AddArg(Execution::Args::Type::IgnoreUnavailable);\r\n\r\n    ImportCommand importCommand({});\r\n    importCommand.Execute(context);\r\n    INFO(importOutput.str());\r\n\r\n    // Verify installer was called for the package that was available.\r\n    REQUIRE(std::filesystem::exists(exeInstallResultPath.GetPath()));\r\n    REQUIRE(importOutput.str().find(Resource::LocString(Resource::String::MultiQueryPackageNotFound(\"MissingPackage\"_liv)).get()) != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"ImportFlow_MissingVersion\", \"[ImportFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile exeInstallResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream importOutput;\r\n    TestContext context{ importOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForImportSource(context);\r\n    context.Args.AddArg(Execution::Args::Type::ImportFile, TestDataFile(\"ImportFile-Bad-UnknownPackageVersion.json\").GetPath().string());\r\n\r\n    ImportCommand importCommand({});\r\n    importCommand.Execute(context);\r\n    INFO(importOutput.str());\r\n\r\n    // Installer should not be called\r\n    REQUIRE(!std::filesystem::exists(exeInstallResultPath.GetPath()));\r\n    REQUIRE(importOutput.str().find(Resource::LocString(Resource::String::MultiQuerySearchFailed(\"AppInstallerCliTest.TestExeInstaller\"_liv)).get()) != std::string::npos);\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_NOT_ALL_QUERIES_FOUND_SINGLE);\r\n}\r\n\r\nTEST_CASE(\"ImportFlow_MalformedJsonFile\", \"[ImportFlow][workflow]\")\r\n{\r\n    std::ostringstream importOutput;\r\n    TestContext context{ importOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    context.Args.AddArg(Execution::Args::Type::ImportFile, TestDataFile(\"ImportFile-Bad-Malformed.json\").GetPath().string());\r\n\r\n    ImportCommand importCommand({});\r\n    importCommand.Execute(context);\r\n    INFO(importOutput.str());\r\n\r\n    // Command should have failed\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE);\r\n}\r\n\r\nTEST_CASE(\"ImportFlow_InvalidJsonFile\", \"[ImportFlow][workflow]\")\r\n{\r\n    std::ostringstream importOutput;\r\n    TestContext context{ importOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    context.Args.AddArg(Execution::Args::Type::ImportFile, TestDataFile(\"ImportFile-Bad-Invalid.json\").GetPath().string());\r\n\r\n    ImportCommand importCommand({});\r\n    importCommand.Execute(context);\r\n    INFO(importOutput.str());\r\n\r\n    // Command should have failed\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE);\r\n}\r\n\r\nTEST_CASE(\"ImportFlow_MachineScope\", \"[ImportFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile exeInstallResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream importOutput;\r\n    TestContext context{ importOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForImportSource(context);\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::ImportFile, TestDataFile(\"ImportFile-Good-MachineScope.json\").GetPath().string());\r\n\r\n    ImportCommand importCommand({});\r\n    importCommand.Execute(context);\r\n    INFO(importOutput.str());\r\n\r\n    // Verify all packages were installed\r\n    REQUIRE(std::filesystem::exists(exeInstallResultPath.GetPath()));\r\n    std::ifstream installResultFile(exeInstallResultPath.GetPath());\r\n    REQUIRE(installResultFile.is_open());\r\n    std::string installResultStr;\r\n    std::getline(installResultFile, installResultStr);\r\n    REQUIRE(installResultStr.find(\"/scope=machine\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"ImportFlow_Dependencies\", \"[ImportFlow][workflow][dependencies]\")\r\n{\r\n    std::ostringstream importOutput;\r\n    TestContext context{ importOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForImportSource(context);\r\n    OverrideForMSIX(context);\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::ImportFile, TestDataFile(\"ImportFile-Good-Dependencies.json\").GetPath().string());\r\n\r\n    ImportCommand importCommand({});\r\n    importCommand.Execute(context);\r\n    INFO(importOutput.str());\r\n\r\n    // Verify dependencies for all packages are informed\r\n    REQUIRE(importOutput.str().find(Resource::LocString(Resource::String::ImportCommandReportDependencies).get()) != std::string::npos);\r\n    REQUIRE(importOutput.str().find(\"PreviewIIS\") != std::string::npos);\r\n    REQUIRE(importOutput.str().find(\"Preview VC Runtime\") != std::string::npos);\r\n    REQUIRE(importOutput.str().find(\"Hyper-V\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"ImportFlow_LicenseAgreement\", \"[ImportFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile exeInstallResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream importOutput;\r\n    TestContext context{ importOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForImportSource(context);\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::ImportFile, TestDataFile(\"ImportFile-Good-WithLicenseAgreement.json\").GetPath().string());\r\n    context.Args.AddArg(Execution::Args::Type::AcceptPackageAgreements);\r\n\r\n    ImportCommand importCommand({});\r\n    importCommand.Execute(context);\r\n    INFO(importOutput.str());\r\n\r\n    // Verify agreements are shown\r\n    REQUIRE(importOutput.str().find(\"Agreement for EXE\") != std::string::npos);\r\n    REQUIRE(importOutput.str().find(\"This is the agreement for the EXE\") != std::string::npos);\r\n\r\n    // Verify all packages were installed\r\n    REQUIRE(std::filesystem::exists(exeInstallResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"ImportFlow_LicenseAgreement_NotAccepted\", \"[ImportFlow][workflow]\")\r\n{\r\n    // Say \"No\" at the agreements prompt\r\n    std::istringstream importInput{ \"n\" };\r\n\r\n    std::ostringstream importOutput;\r\n    TestContext context{ importOutput, importInput };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForImportSource(context);\r\n    context.Args.AddArg(Execution::Args::Type::ImportFile, TestDataFile(\"ImportFile-Good-WithLicenseAgreement.json\").GetPath().string());\r\n\r\n    ImportCommand importCommand({});\r\n    importCommand.Execute(context);\r\n    INFO(importOutput.str());\r\n\r\n    // Verify agreements are shown\r\n    REQUIRE(importOutput.str().find(\"Agreement for EXE\") != std::string::npos);\r\n    REQUIRE(importOutput.str().find(\"This is the agreement for the EXE\") != std::string::npos);\r\n\r\n    // Command should have failed\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/InstallDependenciesFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"WorkflowCommon.h\"\r\n#include \"DependenciesTestSource.h\"\r\n#include <Commands/InstallCommand.h>\r\n#include <Commands/COMCommand.h>\r\n#include <Workflows/DependenciesFlow.h>\r\n#include <Workflows/DownloadFlow.h>\r\n#include <Workflows/InstallFlow.h>\r\n#include <Workflows/ShellExecuteInstallerHandler.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::CLI;\r\nusing namespace AppInstaller::CLI::Workflow;\r\nusing namespace AppInstaller::Repository;\r\n\r\nvoid OverrideOpenSourceForDependencies(TestContext& context)\r\n{\r\n    context.Override({ \"OpenSource\", [](TestContext& context)\r\n    {\r\n        context.Add<Execution::Data::Source>(Source{ std::make_shared<DependenciesTestSource>() });\r\n    } });\r\n\r\n    context.Override({ Workflow::OpenDependencySource, [](TestContext& context)\r\n    {\r\n        context.Add<Execution::Data::DependencySource>(Source{ std::make_shared<DependenciesTestSource>() });\r\n    } });\r\n}\r\n\r\nvoid OverrideForProcessMultiplePackages(TestContext& context)\r\n{\r\n    context.Override({ ProcessMultiplePackages(\r\n        Resource::String::PackageRequiresDependencies,\r\n        APPINSTALLER_CLI_ERROR_INSTALL_DEPENDENCIES,\r\n        ProcessMultiplePackages::Flags::SkipPackageAgreements | ProcessMultiplePackages::Flags::IgnoreDependencies), [](TestContext&)\r\n    {\r\n\r\n    } });\r\n}\r\n\r\nvoid OverrideShellExecute(TestContext& context, std::vector<std::string>& installationOrder)\r\n{\r\n    context.Override({ ShellExecuteInstallImpl, [&installationOrder](TestContext& c)\r\n        {\r\n            installationOrder.push_back(c.Get<Execution::Data::Manifest>().Id);\r\n            c.Add<Execution::Data::OperationReturnCode>(0);\r\n        } });\r\n}\r\n\r\nTEST_CASE(\"DependencyGraph_SkipInstalled\", \"[InstallFlow][workflow][dependencyGraph][dependencies]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n\r\n    Manifest manifest = CreateFakeManifestWithDependencies(\"DependenciesInstalled\");\r\n    OverrideOpenDependencySource(context);\r\n\r\n    context.Add<Execution::Data::DependencySource>(Source{ std::make_shared<DependenciesTestSource>() });\r\n    context.Add<Execution::Data::Manifest>(manifest);\r\n    context.Add<Execution::Data::Installer>(manifest.Installers[0]);\r\n\r\n    context << CreateDependencySubContexts(Resource::String::PackageRequiresDependencies);\r\n\r\n    auto& dependencyPackages = context.Get<Execution::Data::PackageSubContexts>();\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::DependenciesFlowContainsLoop)) == std::string::npos);\r\n    REQUIRE(dependencyPackages.size() == 0);\r\n}\r\n\r\nTEST_CASE(\"DependencyGraph_validMinVersions\", \"[InstallFlow][workflow][dependencyGraph][dependencies]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    Manifest manifest = CreateFakeManifestWithDependencies(\"DependenciesValidMinVersions\");\r\n    OverrideOpenDependencySource(context);\r\n\r\n    context.Add<Execution::Data::DependencySource>(Source{ std::make_shared<DependenciesTestSource>() });\r\n    context.Add<Execution::Data::Manifest>(manifest);\r\n    context.Add<Execution::Data::Installer>(manifest.Installers[0]);\r\n\r\n    context << CreateDependencySubContexts(Resource::String::PackageRequiresDependencies);\r\n\r\n    auto& dependencyPackages = context.Get<Execution::Data::PackageSubContexts>();\r\n\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::DependenciesFlowContainsLoop)) == std::string::npos);\r\n    REQUIRE(dependencyPackages.size() == 1);\r\n    REQUIRE(dependencyPackages.at(0)->Get<Execution::Data::Manifest>().Id == \"minVersion\");\r\n    // minVersion 1.5 is available but this requires 1.0 so that version is installed\r\n    REQUIRE(dependencyPackages.at(0)->Get<Execution::Data::Manifest>().Version == \"1.0\");\r\n}\r\n\r\nTEST_CASE(\"DependencyGraph_PathNoLoop\", \"[InstallFlow][workflow][dependencyGraph][dependencies]\", )\r\n{\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    Manifest manifest = CreateFakeManifestWithDependencies(\"PathBetweenBranchesButNoLoop\");\r\n    OverrideOpenDependencySource(context);\r\n\r\n    context.Add<Execution::Data::DependencySource>(Source{ std::make_shared<DependenciesTestSource>() });\r\n    context.Add<Execution::Data::Manifest>(manifest);\r\n    context.Add<Execution::Data::Installer>(manifest.Installers[0]);\r\n\r\n    context << CreateDependencySubContexts(Resource::String::PackageRequiresDependencies);\r\n\r\n    auto& dependencyPackages = context.Get<Execution::Data::PackageSubContexts>();\r\n\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::DependenciesFlowContainsLoop)) == std::string::npos);\r\n\r\n    // Verify installers are called in order\r\n    REQUIRE(dependencyPackages.size() == 4);\r\n    REQUIRE(dependencyPackages.at(0)->Get<Execution::Data::Manifest>().Id == \"B\");\r\n    REQUIRE(dependencyPackages.at(1)->Get<Execution::Data::Manifest>().Id == \"C\");\r\n    REQUIRE(dependencyPackages.at(2)->Get<Execution::Data::Manifest>().Id == \"G\");\r\n    REQUIRE(dependencyPackages.at(3)->Get<Execution::Data::Manifest>().Id == \"H\");\r\n}\r\n\r\nTEST_CASE(\"DependencyGraph_StackOrderIsOk\", \"[InstallFlow][workflow][dependencyGraph][dependencies]\")\r\n{\r\n    std::vector<Dependency> installationOrder;\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideOpenSourceForDependencies(context);\r\n    OverrideForShellExecute(context, installationOrder);\r\n\r\n    context.Args.AddArg(Execution::Args::Type::Query, \"StackOrderIsOk\"sv);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::DependenciesFlowContainsLoop)) == std::string::npos);\r\n\r\n    // Verify installers are called in order\r\n    REQUIRE(installationOrder.size() == 3);\r\n    REQUIRE(installationOrder.at(0).Id() == \"B\");\r\n    REQUIRE(installationOrder.at(1).Id() == \"C\");\r\n    REQUIRE(installationOrder.at(2).Id() == \"StackOrderIsOk\");\r\n}\r\n\r\nTEST_CASE(\"DependencyGraph_MultipleDependenciesFromManifest\", \"[InstallFlow][workflow][dependencyGraph][dependencies]\")\r\n{\r\n    std::vector<Dependency> installationOrder;\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideOpenSourceForDependencies(context);\r\n    OverrideForShellExecute(context, installationOrder);\r\n    OverrideEnableWindowsFeaturesDependencies(context);\r\n\r\n    context.Args.AddArg(Execution::Args::Type::Query, \"MultipleDependenciesFromManifest\"sv);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::DependenciesFlowContainsLoop)) == std::string::npos);\r\n\r\n    // Verify installers are called in order\r\n    REQUIRE(installationOrder.size() == 3);\r\n    REQUIRE(installationOrder.at(0).Id() == \"Dependency1\");\r\n    REQUIRE(installationOrder.at(1).Id() == \"Dependency2\");\r\n    REQUIRE(installationOrder.at(2).Id() == \"AppInstallerCliTest.TestExeInstaller.MultipleDependencies\");\r\n}\r\n\r\nTEST_CASE(\"InstallerWithoutDependencies_RootDependenciesAreUsed\", \"[dependencies]\")\r\n{\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n    OverrideOpenDependencySource(context);\r\n    OverrideEnableWindowsFeaturesDependencies(context);\r\n\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"Installer_Exe_DependenciesOnRoot.yaml\").GetPath().u8string());\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify root dependencies are shown\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::PackageRequiresDependencies).get()) != std::string::npos);\r\n    REQUIRE(installOutput.str().find(\"PreviewIISOnRoot\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallerWithDependencies_SkipDependencies\", \"[dependencies]\")\r\n{\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"Installer_Exe_Dependencies.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::SkipDependencies);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::DependenciesSkippedMessage).get()) != std::string::npos);\r\n    REQUIRE_FALSE(installOutput.str().find(Resource::LocString(Resource::String::PackageRequiresDependencies).get()) != std::string::npos);\r\n    REQUIRE_FALSE(installOutput.str().find(\"PreviewIIS\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallerWithDependencies_IgnoreDependenciesSetting\", \"[dependencies]\")\r\n{\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"Installer_Exe_Dependencies.yaml\").GetPath().u8string());\r\n\r\n    TestUserSettings settings;\r\n    settings.Set<AppInstaller::Settings::Setting::InstallSkipDependencies>({ true });\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::DependenciesSkippedMessage).get()) != std::string::npos);\r\n    REQUIRE_FALSE(installOutput.str().find(Resource::LocString(Resource::String::PackageRequiresDependencies).get()) != std::string::npos);\r\n    REQUIRE_FALSE(installOutput.str().find(\"PreviewIIS\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallerWithDependencies_DependenciesOnly\", \"[dependencies]\")\r\n{\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideOpenDependencySource(context);\r\n    OverrideEnableWindowsFeaturesDependencies(context);\r\n\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"Installer_Exe_Dependencies.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::DependenciesOnly);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Dependencies should be reported and installed\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::PackageRequiresDependencies).get()) != std::string::npos);\r\n    REQUIRE(installOutput.str().find(\"PreviewIIS\") != std::string::npos);\r\n    // DependenciesOnly message should be shown\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::DependenciesOnlyMessage).get()) != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"DependenciesMultideclaration_InstallerDependenciesPreference\", \"[dependencies]\")\r\n{\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n    OverrideOpenDependencySource(context);\r\n    OverrideEnableWindowsFeaturesDependencies(context);\r\n\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"Installer_Exe_DependenciesMultideclaration.yaml\").GetPath().u8string());\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify installer dependencies are shown\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::PackageRequiresDependencies).get()) != std::string::npos);\r\n    REQUIRE(installOutput.str().find(\"PreviewIIS\") != std::string::npos);\r\n    // and root dependencies are not\r\n    REQUIRE(installOutput.str().find(\"PreviewIISOnRoot\") == std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_Dependencies\", \"[InstallFlow][workflow][dependencies]\")\r\n{\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n    OverrideOpenDependencySource(context);\r\n    OverrideEnableWindowsFeaturesDependencies(context);\r\n\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"Installer_Exe_Dependencies.yaml\").GetPath().u8string());\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify all types of dependencies are printed\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::PackageRequiresDependencies).get()) != std::string::npos);\r\n    REQUIRE(installOutput.str().find(\"PreviewIIS\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_Dependencies_COM\", \"[InstallFlow][workflow][dependencies]\")\r\n{\r\n    std::vector<std::string> installationOrder;\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n    OverrideShellExecute(context, installationOrder);\r\n    OverrideOpenDependencySource(context);\r\n    OverrideEnableWindowsFeaturesDependencies(context);\r\n    context.Override({ ReverifyInstallerHash, [](TestContext&) {} });\r\n\r\n    context.Add<Execution::Data::Manifest>(YamlParser::CreateFromPath(TestDataFile(\"InstallFlowTest_MultipleDependencies.yaml\")));\r\n\r\n    COMDownloadCommand download({});\r\n    download.Execute(context);\r\n\r\n    REQUIRE(installationOrder.size() == 0);\r\n\r\n    COMInstallCommand install({});\r\n    REQUIRE_NOTHROW(install.Execute(context));\r\n\r\n    REQUIRE(context.GetTerminationHR() == S_OK);\r\n\r\n    // Verify installers are called in order\r\n    REQUIRE(installationOrder.size() == 3);\r\n    REQUIRE(installationOrder.at(0) == \"Dependency1\");\r\n    REQUIRE(installationOrder.at(1) == \"Dependency2\");\r\n    REQUIRE(installationOrder.at(2) == \"AppInstallerCliTest.TestExeInstaller.MultipleDependencies\");\r\n}\r\n\r\n// TODO:\r\n// add dependencies for installer tests to DependenciesTestSource (or a new one)\r\n// add tests for min version dependency solving\r\n// add tests that check for correct installation of dependencies (not only the order)\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/InstallFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"WorkflowCommon.h\"\r\n#include \"TestHooks.h\"\r\n#include <AppInstallerFileLogger.h>\r\n#include <AppInstallerStrings.h>\r\n#include <AppInstallerSynchronization.h>\r\n#include <Commands/InstallCommand.h>\r\n#include <Commands/UninstallCommand.h>\r\n#include <winget/AdminSettings.h>\r\n#include <winget/PathVariable.h>\r\n#include <winget/Settings.h>\r\n#include <winget/ManifestYamlParser.h>\r\n#include <Workflows/ArchiveFlow.h>\r\n#include <Workflows/DownloadFlow.h>\r\n#include <Workflows/MsiInstallFlow.h>\r\n#include <Workflows/ShellExecuteInstallerHandler.h>\r\n\r\nusing namespace winrt::Windows::Foundation;\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::CLI;\r\nusing namespace AppInstaller::CLI::Execution;\r\nusing namespace AppInstaller::CLI::Workflow;\r\nusing namespace AppInstaller::Logging;\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Settings;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::Utility::literals;\r\n\r\nvoid OverrideForDirectMsi(TestContext& context)\r\n{\r\n    OverrideForCheckExistingInstaller(context);\r\n\r\n    context.Override({ DownloadInstallerFile, [](TestContext& context)\r\n    {\r\n        context.Add<Data::DownloadHashInfo>({ {}, {} });\r\n        // We don't have an msi installer for tests, but we won't execute it anyway\r\n        context.Add<Data::InstallerPath>(TestDataFile(\"AppInstallerTestExeInstaller.exe\"));\r\n    } });\r\n\r\n    context.Override({ RenameDownloadedInstaller, [](TestContext&)\r\n    {\r\n    } });\r\n\r\n    OverrideForUpdateInstallerMotw(context);\r\n\r\n    context.Override({ DirectMSIInstallImpl, [](TestContext& context)\r\n    {\r\n            // Write out the install command\r\n            std::filesystem::path temp = std::filesystem::temp_directory_path();\r\n            temp /= \"TestMsiInstalled.txt\";\r\n            std::ofstream file(temp, std::ofstream::out);\r\n            file << context.Get<Execution::Data::InstallerArgs>();\r\n            file.close();\r\n\r\n            context.Add<Execution::Data::OperationReturnCode>(0);\r\n        } });\r\n}\r\n\r\nTEST_CASE(\"ExeInstallFlowWithTestManifest\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_Exe.yaml\").GetPath().u8string());\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify Installer is called and parameters are passed in.\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n    std::ifstream installResultFile(installResultPath.GetPath());\r\n    REQUIRE(installResultFile.is_open());\r\n    std::string installResultStr;\r\n    std::getline(installResultFile, installResultStr);\r\n    REQUIRE(installResultStr.find(\"/custom\") != std::string::npos);\r\n    REQUIRE(installResultStr.find(\"/silentwithprogress\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_RenameFromEncodedUrl\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCheckExistingInstaller(context);\r\n    context.Override({ DownloadInstallerFile, [](TestContext& context)\r\n    {\r\n        context.Add<Data::DownloadHashInfo>({ {}, {} });\r\n        auto installerPath = std::filesystem::temp_directory_path();\r\n        installerPath /= \"EncodedUrlTest.exe\";\r\n        std::filesystem::copy(TestDataFile(\"AppInstallerTestExeInstaller.exe\"), installerPath, std::filesystem::copy_options::overwrite_existing);\r\n        context.Add<Data::InstallerPath>(installerPath);\r\n    } });\r\n    OverrideForUpdateInstallerMotw(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_EncodedUrl.yaml\").GetPath().u8string());\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify Installer is called and parameters are passed in.\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n    std::ifstream installResultFile(installResultPath.GetPath());\r\n    REQUIRE(installResultFile.is_open());\r\n    std::string installResultStr;\r\n    std::getline(installResultFile, installResultStr);\r\n    REQUIRE(installResultStr.find(\"/encodedUrl\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_RenameFromInvalidFileCharacterUrl\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCheckExistingInstaller(context);\r\n    context.Override({ DownloadInstallerFile, [](TestContext& context)\r\n    {\r\n        context.Add<Data::DownloadHashInfo>({ {}, {} });\r\n        auto installerPath = std::filesystem::temp_directory_path();\r\n        installerPath /= \"InvalidFileCharacterUrlTest.exe\";\r\n        std::filesystem::copy(TestDataFile(\"AppInstallerTestExeInstaller.exe\"), installerPath, std::filesystem::copy_options::overwrite_existing);\r\n        context.Add<Data::InstallerPath>(installerPath);\r\n    } });\r\n    OverrideForUpdateInstallerMotw(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_InvalidFileCharacterUrl.yaml\").GetPath().u8string());\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify Installer is called and parameters are passed in.\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n    std::ifstream installResultFile(installResultPath.GetPath());\r\n    REQUIRE(installResultFile.is_open());\r\n    std::string installResultStr;\r\n    std::getline(installResultFile, installResultStr);\r\n    REQUIRE(installResultStr.find(\"/invalidFileCharacterUrl\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlowNonZeroExitCode\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_NonZeroExitCode.yaml\").GetPath().u8string());\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify Installer is called and parameters are passed in.\r\n    REQUIRE(context.GetTerminationHR() == S_OK);\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n    std::ifstream installResultFile(installResultPath.GetPath());\r\n    REQUIRE(installResultFile.is_open());\r\n    std::string installResultStr;\r\n    std::getline(installResultFile, installResultStr);\r\n    REQUIRE(installResultStr.find(\"/ExitCode 0x80070005\") != std::string::npos);\r\n    REQUIRE(installResultStr.find(\"/silentwithprogress\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_InstallationNotes\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_InstallationNotes.yaml\").GetPath().u8string());\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify installation notes are displayed\r\n    REQUIRE(context.GetTerminationHR() == S_OK);\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n    REQUIRE(installOutput.str().find(\"testInstallationNotes\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_UnsupportedArguments_Warn\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n    TestCommon::TempDirectory tempDirectory(\"TempDirectory\", false);\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_UnsupportedArguments.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::Log, tempDirectory);\r\n\r\n    InstallCommand install({});\r\n    context.SetExecutingCommand(&install);\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify unsupported arguments warn message is shown\r\n    REQUIRE(context.GetTerminationHR() == S_OK);\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::UnsupportedArgument).get()) != std::string::npos);\r\n    REQUIRE(installOutput.str().find(\"-o,--log\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_UnsupportedArguments_Error\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n    TestCommon::TempDirectory tempDirectory(\"TempDirectory\", false);\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_UnsupportedArguments.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::InstallLocation, tempDirectory);\r\n\r\n    InstallCommand install({});\r\n    context.SetExecutingCommand(&install);\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify unsupported arguments error message is shown \r\n    REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_UNSUPPORTED_ARGUMENT);\r\n    REQUIRE(!std::filesystem::exists(installResultPath.GetPath()));\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::UnsupportedArgument).get()) != std::string::npos);\r\n    REQUIRE(installOutput.str().find(\"-l,--location\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_UnsupportedArguments_NotProvided\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_UnsupportedArguments.yaml\").GetPath().u8string());\r\n\r\n    InstallCommand install({});\r\n    context.SetExecutingCommand(&install);\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify unsupported arguments error message is not shown when not provided\r\n    REQUIRE(context.GetTerminationHR() == S_OK);\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::UnsupportedArgument).get()) == std::string::npos);\r\n    REQUIRE(installOutput.str().find(\"-o,--log\") == std::string::npos);\r\n    REQUIRE(installOutput.str().find(\"-l,--location\") == std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_ExpectedReturnCodes\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_ExpectedReturnCodes.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::Override, \"/ExitCode 8\"sv);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify install failed with the right message\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_INSTALL_CONTACT_SUPPORT);\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::InstallFlowReturnCodeContactSupport).get()) != std::string::npos);\r\n    REQUIRE(installOutput.str().find(\"https://TestReturnResponseUrl\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlowWithNonApplicableArchitecture\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_NoApplicableArchitecture.yaml\").GetPath().u8string());\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER);\r\n\r\n    // Verify Installer was not called\r\n    REQUIRE(!std::filesystem::exists(installResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_Zip_Exe\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n    OverrideForExtractInstallerFromArchive(context);\r\n    OverrideForVerifyAndSetNestedInstaller(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_Zip_Exe.yaml\").GetPath().u8string());\r\n\r\n    TestHook::SetScanArchiveResult_Override scanArchiveResultOverride(true);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify Installer is called and parameters are passed in.\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n    std::ifstream installResultFile(installResultPath.GetPath());\r\n    REQUIRE(installResultFile.is_open());\r\n    std::string installResultStr;\r\n    std::getline(installResultFile, installResultStr);\r\n    REQUIRE(installResultStr.find(\"/custom\") != std::string::npos);\r\n    REQUIRE(installResultStr.find(\"/silentwithprogress\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_Zip_BadRelativePath\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n    OverrideForExtractInstallerFromArchive(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_Zip_Exe.yaml\").GetPath().u8string());\r\n\r\n    TestHook::SetScanArchiveResult_Override scanArchiveResultOverride(true);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_NOT_FOUND);\r\n\r\n    // Verify Installer was not called\r\n    REQUIRE(!std::filesystem::exists(installResultPath.GetPath()));\r\n    auto relativePath = context.Get<Execution::Data::InstallerPath>().parent_path() / \"extracted\" / \"relativeFilePath\";\r\n    auto expectedMessage = Resource::String::NestedInstallerNotFound(AppInstaller::Utility::LocIndString{ relativePath.u8string()});\r\n    REQUIRE(installOutput.str().find(Resource::LocString(expectedMessage).get()) != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_Zip_MissingNestedInstaller\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_Zip_MissingNestedInstaller.yaml\").GetPath().u8string());\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_INVALID_MANIFEST);\r\n\r\n    // Verify Installer was not called\r\n    REQUIRE(!std::filesystem::exists(installResultPath.GetPath()));\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::NestedInstallerNotSpecified).get()) != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_Zip_UnsupportedNestedInstaller\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_Zip_UnsupportedNestedInstaller.yaml\").GetPath().u8string());\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    REQUIRE_TERMINATED_WITH(context, ERROR_NOT_SUPPORTED);\r\n\r\n    // Verify Installer was not called\r\n    REQUIRE(!std::filesystem::exists(installResultPath.GetPath()));\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::NestedInstallerNotSupported).get()) != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_Zip_MultipleNonPortableNestedInstallers\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_Zip_MultipleNonPortableNestedInstallers.yaml\").GetPath().u8string());\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_INVALID_MANIFEST);\r\n\r\n    // Verify Installer was not called\r\n    REQUIRE(!std::filesystem::exists(installResultPath.GetPath()));\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::MultipleUnsupportedNestedInstallersSpecified).get()) != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_Zip_ArchiveScanFailed\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_Zip_Exe.yaml\").GetPath().u8string());\r\n\r\n    TestHook::SetScanArchiveResult_Override scanArchiveResultOverride(false);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_ARCHIVE_SCAN_FAILED);\r\n\r\n    // Verify Installer was not called\r\n    REQUIRE(!std::filesystem::exists(installResultPath.GetPath()));\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::ArchiveFailedMalwareScan).get()) != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_Zip_ArchiveScanOverride_AdminSettingDisabled\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_Zip_Exe.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::IgnoreLocalArchiveMalwareScan);\r\n\r\n    DisableAdminSetting(AppInstaller::Settings::BoolAdminSetting::LocalArchiveMalwareScanOverride);\r\n\r\n    TestHook::SetScanArchiveResult_Override scanArchiveResultOverride(false);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_ARCHIVE_SCAN_FAILED);\r\n\r\n    // Verify Installer was not called\r\n    REQUIRE(!std::filesystem::exists(installResultPath.GetPath()));\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::ArchiveFailedMalwareScan).get()) != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_Zip_ArchiveScanOverride_AdminSettingEnabled\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n    OverrideForExtractInstallerFromArchive(context);\r\n    OverrideForVerifyAndSetNestedInstaller(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_Zip_Exe.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::IgnoreLocalArchiveMalwareScan);\r\n\r\n    EnableAdminSetting(AppInstaller::Settings::BoolAdminSetting::LocalArchiveMalwareScanOverride);\r\n\r\n    TestHook::SetScanArchiveResult_Override scanArchiveResultOverride(false);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify override message is displayed to the user.\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::ArchiveFailedMalwareScanOverridden).get()) != std::string::npos);\r\n\r\n    // Verify Installer is called and parameters are passed in.\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n    std::ifstream installResultFile(installResultPath.GetPath());\r\n    REQUIRE(installResultFile.is_open());\r\n    std::string installResultStr;\r\n    std::getline(installResultFile, installResultStr);\r\n    REQUIRE(installResultStr.find(\"/custom\") != std::string::npos);\r\n    REQUIRE(installResultStr.find(\"/silentwithprogress\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"ExtractInstallerFromArchive_InvalidZip\", \"[InstallFlow][workflow]\")\r\n{\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallFlowTest_Zip_Exe.yaml\"));\r\n    context.Add<Data::Manifest>(manifest);\r\n    context.Add<Data::Installer>(manifest.Installers.at(0));\r\n\r\n    // Provide an invalid zip file which should be handled appropriately.\r\n    context.Add<Data::InstallerPath>(TestDataFile(\"AppInstallerTestExeInstaller.exe\"));\r\n    context << ExtractFilesFromArchive;\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_EXTRACT_ARCHIVE_FAILED);\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::ExtractArchiveFailed).get()) != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"ExtractInstallerFromArchiveWithTar\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TestUserSettings testSettings;\r\n    testSettings.Set<Setting::ArchiveExtractionMethod>(AppInstaller::Archive::ExtractionMethod::Tar);\r\n\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n\r\n    OverrideForShellExecute(context);\r\n    OverrideForVerifyAndSetNestedInstaller(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_Zip_Exe.yaml\").GetPath().u8string());\r\n\r\n    TestHook::SetScanArchiveResult_Override scanArchiveResultOverride(true);\r\n    TestHook::SetExtractArchiveWithTarResult_Override setExtractArchiveWithTarResultOverride(ERROR_SUCCESS);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::ExtractArchiveSucceeded).get()) != std::string::npos);\r\n\r\n    // Verify Installer is called and parameters are passed in.\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n    std::ifstream installResultFile(installResultPath.GetPath());\r\n    REQUIRE(installResultFile.is_open());\r\n    std::string installResultStr;\r\n    std::getline(installResultFile, installResultStr);\r\n    REQUIRE(installResultStr.find(\"/custom\") != std::string::npos);\r\n    REQUIRE(installResultStr.find(\"/silentwithprogress\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"ExtractInstallerFromArchiveWithTar_InvalidZip\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TestUserSettings testSettings;\r\n    testSettings.Set<Setting::ArchiveExtractionMethod>(AppInstaller::Archive::ExtractionMethod::Tar);\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallFlowTest_Zip_Exe.yaml\"));\r\n    context.Add<Data::Manifest>(manifest);\r\n    context.Add<Data::Installer>(manifest.Installers.at(0));\r\n\r\n    // Provide an invalid zip file which should be handled appropriately.\r\n    context.Add<Data::InstallerPath>(TestDataFile(\"AppInstallerTestExeInstaller.exe\"));\r\n    context << ExtractFilesFromArchive;\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_EXTRACT_ARCHIVE_FAILED);\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::ExtractArchiveFailed).get()) != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"MSStoreInstallFlowWithTestManifest\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestMSStoreInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForMSStore(context, false);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_MSStore.yaml\").GetPath().u8string());\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify Installer is called and parameters are passed in.\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n    std::ifstream installResultFile(installResultPath.GetPath());\r\n    REQUIRE(installResultFile.is_open());\r\n    std::string installResultStr;\r\n    std::getline(installResultFile, installResultStr);\r\n    REQUIRE(installResultStr.find(\"9WZDNCRFJ364\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"MsixInstallFlow_DownloadFlow\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestMsixInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForMSIX(context);\r\n    OverrideForUpdateInstallerMotw(context);\r\n    // Todo: point to files from our repo when the repo goes public\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_Msix_DownloadFlow.yaml\").GetPath().u8string());\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify Installer is called and a local file is used as package Uri.\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n    std::ifstream installResultFile(installResultPath.GetPath());\r\n    REQUIRE(installResultFile.is_open());\r\n    std::string installResultStr;\r\n    std::getline(installResultFile, installResultStr);\r\n    Uri uri = Uri(ConvertToUTF16(installResultStr));\r\n    REQUIRE(uri.SchemeName() == L\"file\");\r\n}\r\n\r\nTEST_CASE(\"MsixInstallFlow_StreamingFlow\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestMsixInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForMSIX(context);\r\n    OverrideForCheckExistingInstaller(context);\r\n    // Todo: point to files from our repo when the repo goes public\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_Msix_StreamingFlow.yaml\").GetPath().u8string());\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify Installer is called and a http address is used as package Uri.\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n    std::ifstream installResultFile(installResultPath.GetPath());\r\n    REQUIRE(installResultFile.is_open());\r\n    std::string installResultStr;\r\n    std::getline(installResultFile, installResultStr);\r\n    Uri uri = Uri(ConvertToUTF16(installResultStr));\r\n    REQUIRE(uri.SchemeName() == L\"https\");\r\n}\r\n\r\nTEST_CASE(\"MsiInstallFlow_DirectMsi\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestMsiInstalled.txt\");\r\n\r\n    TestCommon::TestUserSettings testSettings;\r\n    testSettings.Set<Setting::EFDirectMSI>(true);\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForDirectMsi(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallerArgTest_Msi_NoSwitches.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::Silent);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify Installer is called and parameters are passed in.\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n    std::ifstream installResultFile(installResultPath.GetPath());\r\n    REQUIRE(installResultFile.is_open());\r\n    std::string installResultStr;\r\n    std::getline(installResultFile, installResultStr);\r\n    REQUIRE(installResultStr.find(\"/quiet\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_Portable\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempDirectory tempDirectory(\"TestPortableInstallRoot\", false);\r\n    TestCommon::TempFile portableInstallResultPath(\"TestPortableInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForPortableInstallFlow(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_Portable.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::InstallLocation, tempDirectory);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    REQUIRE(std::filesystem::exists(portableInstallResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_Portable_SymlinkCreationFail\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempDirectory tempDirectory(\"TestPortableInstallRoot\", false);\r\n    std::ostringstream installOutput;\r\n    TestContext installContext{ installOutput, std::cin };\r\n    auto PreviousThreadGlobals = installContext.SetForCurrentThread();\r\n    OverridePortableInstaller(installContext);\r\n    TestHook::SetCreateSymlinkResult_Override createSymlinkResultOverride(false);\r\n    const auto& targetDirectory = tempDirectory.GetPath();\r\n    const auto& portableTargetPath = targetDirectory / \"AppInstallerTestExeInstaller.exe\";\r\n    installContext.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_Portable.yaml\").GetPath().u8string());\r\n    installContext.Args.AddArg(Execution::Args::Type::InstallLocation, targetDirectory.u8string());\r\n    installContext.Args.AddArg(Execution::Args::Type::InstallScope, \"user\"sv);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(installContext);\r\n\r\n    {\r\n        INFO(installOutput.str());\r\n\r\n        // Use CHECK to allow the uninstall to still occur\r\n        CHECK(std::filesystem::exists(portableTargetPath));\r\n        CHECK(AppInstaller::Registry::Environment::PathVariable(AppInstaller::Manifest::ScopeEnum::User).Contains(targetDirectory));\r\n    }\r\n\r\n    // Perform uninstall\r\n    std::ostringstream uninstallOutput;\r\n    TestContext uninstallContext{ uninstallOutput, std::cin };\r\n    auto previousThreadGlobals = uninstallContext.SetForCurrentThread();\r\n    uninstallContext.Args.AddArg(Execution::Args::Type::Name, \"AppInstaller Test Portable Exe\"sv);\r\n    uninstallContext.Args.AddArg(Execution::Args::Type::AcceptSourceAgreements);\r\n\r\n    UninstallCommand uninstall({});\r\n    uninstall.Execute(uninstallContext);\r\n    INFO(uninstallOutput.str());\r\n    REQUIRE_FALSE(std::filesystem::exists(portableTargetPath));\r\n}\r\n\r\nTEST_CASE(\"PortableInstallFlow_UserScope\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempDirectory tempDirectory(\"TestPortableInstallRoot\", false);\r\n    TestCommon::TempFile portableInstallResultPath(\"TestPortableInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForPortableInstallFlow(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_Portable.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::InstallLocation, tempDirectory);\r\n    context.Args.AddArg(Execution::Args::Type::InstallScope, \"user\"sv);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    REQUIRE(std::filesystem::exists(portableInstallResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"PortableInstallFlow_MachineScope\", \"[InstallFlow][workflow]\")\r\n{\r\n    if (!AppInstaller::Runtime::IsRunningAsAdmin())\r\n    {\r\n        WARN(\"Test requires admin privilege. Skipped.\");\r\n        return;\r\n    }\r\n\r\n    TestCommon::TempDirectory tempDirectory(\"TestPortableInstallRoot\", false);\r\n    TestCommon::TempFile portableInstallResultPath(\"TestPortableInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForPortableInstallFlow(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_Portable.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::InstallLocation, tempDirectory);\r\n    context.Args.AddArg(Execution::Args::Type::InstallScope, \"machine\"sv);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n    REQUIRE(std::filesystem::exists(portableInstallResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"ShellExecuteHandlerInstallerArgs\", \"[InstallFlow][workflow]\")\r\n{\r\n    {\r\n        std::ostringstream installOutput;\r\n        TestContext context{ installOutput, std::cin };\r\n        auto previousThreadGlobals = context.SetForCurrentThread();\r\n        // Default Msi type with no args passed in, no switches specified in manifest\r\n        auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallerArgTest_Msi_NoSwitches.yaml\"));\r\n        context.Add<Data::Manifest>(manifest);\r\n        context.Add<Data::Installer>(manifest.Installers.at(0));\r\n        context.Add<Data::InstallerPath>(TestDataFile(\"AppInstallerTestExeInstaller.exe\"));\r\n        context << GetInstallerArgs;\r\n        std::string installerArgs = context.Get<Data::InstallerArgs>();\r\n        REQUIRE(installerArgs.find(\"/passive\") != std::string::npos);\r\n        REQUIRE(installerArgs.find(FileLogger::DefaultPrefix()) != std::string::npos);\r\n        REQUIRE(installerArgs.find(manifest.Id) != std::string::npos);\r\n        REQUIRE(installerArgs.find(manifest.Version) != std::string::npos);\r\n    }\r\n\r\n    {\r\n        std::ostringstream installOutput;\r\n        TestContext context{ installOutput, std::cin };\r\n        auto previousThreadGlobals = context.SetForCurrentThread();\r\n        // Msi type with /silent and /log and /custom and /installlocation, no switches specified in manifest\r\n        auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallerArgTest_Msi_NoSwitches.yaml\"));\r\n        context.Args.AddArg(Execution::Args::Type::Silent);\r\n        context.Args.AddArg(Execution::Args::Type::Log, \"MyLog.log\"sv);\r\n        context.Args.AddArg(Execution::Args::Type::InstallLocation, \"MyDir\"sv);\r\n        context.Add<Data::Manifest>(manifest);\r\n        context.Add<Data::Installer>(manifest.Installers.at(0));\r\n        context << GetInstallerArgs;\r\n        std::string installerArgs = context.Get<Data::InstallerArgs>();\r\n        REQUIRE(installerArgs.find(\"/quiet\") != std::string::npos);\r\n        REQUIRE(installerArgs.find(\"/log \\\"MyLog.log\\\"\") != std::string::npos);\r\n        REQUIRE(installerArgs.find(\"TARGETDIR=\\\"MyDir\\\"\") != std::string::npos);\r\n    }\r\n\r\n    {\r\n        std::ostringstream installOutput;\r\n        TestContext context{ installOutput, std::cin };\r\n        auto previousThreadGlobals = context.SetForCurrentThread();\r\n        // Msi type with /silent and /log and /custom and /installlocation, switches specified in manifest\r\n        auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallerArgTest_Msi_WithSwitches.yaml\"));\r\n        context.Args.AddArg(Execution::Args::Type::Silent);\r\n        context.Args.AddArg(Execution::Args::Type::Log, \"MyLog.log\"sv);\r\n        context.Args.AddArg(Execution::Args::Type::InstallLocation, \"MyDir\"sv);\r\n        context.Add<Data::Manifest>(manifest);\r\n        context.Add<Data::Installer>(manifest.Installers.at(0));\r\n        context << GetInstallerArgs;\r\n        std::string installerArgs = context.Get<Data::InstallerArgs>();\r\n        REQUIRE(installerArgs.find(\"/mysilent\") != std::string::npos); // Use declaration in manifest\r\n        REQUIRE(installerArgs.find(\"/mylog=\\\"MyLog.log\\\"\") != std::string::npos); // Use declaration in manifest\r\n        REQUIRE(installerArgs.find(\"/mycustom\") != std::string::npos); // Use declaration in manifest\r\n        REQUIRE(installerArgs.find(\"/myinstalldir=\\\"MyDir\\\"\") != std::string::npos); // Use declaration in manifest\r\n    }\r\n\r\n    {\r\n        std::ostringstream installOutput;\r\n        TestContext context{ installOutput, std::cin };\r\n        auto previousThreadGlobals = context.SetForCurrentThread();\r\n        // Default Inno type with no args passed in, no switches specified in manifest\r\n        auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallerArgTest_Inno_NoSwitches.yaml\"));\r\n        context.Add<Data::Manifest>(manifest);\r\n        context.Add<Data::Installer>(manifest.Installers.at(0));\r\n        context.Add<Data::InstallerPath>(TestDataFile(\"AppInstallerTestExeInstaller.exe\"));\r\n        context << GetInstallerArgs;\r\n        std::string installerArgs = context.Get<Data::InstallerArgs>();\r\n        REQUIRE(installerArgs.find(\"/SILENT\") != std::string::npos);\r\n        REQUIRE(installerArgs.find(FileLogger::DefaultPrefix()) != std::string::npos);\r\n        REQUIRE(installerArgs.find(manifest.Id) != std::string::npos);\r\n        REQUIRE(installerArgs.find(manifest.Version) != std::string::npos);\r\n    }\r\n\r\n    {\r\n        std::ostringstream installOutput;\r\n        TestContext context{ installOutput, std::cin };\r\n        auto previousThreadGlobals = context.SetForCurrentThread();\r\n        // Inno type with /silent and /log and /custom and /installlocation, no switches specified in manifest\r\n        auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallerArgTest_Inno_NoSwitches.yaml\"));\r\n        context.Args.AddArg(Execution::Args::Type::Silent);\r\n        context.Args.AddArg(Execution::Args::Type::Log, \"MyLog.log\"sv);\r\n        context.Args.AddArg(Execution::Args::Type::InstallLocation, \"MyDir\"sv);\r\n        context.Add<Data::Manifest>(manifest);\r\n        context.Add<Data::Installer>(manifest.Installers.at(0));\r\n        context << GetInstallerArgs;\r\n        std::string installerArgs = context.Get<Data::InstallerArgs>();\r\n        REQUIRE(installerArgs.find(\"/VERYSILENT\") != std::string::npos);\r\n        REQUIRE(installerArgs.find(\"/LOG=\\\"MyLog.log\\\"\") != std::string::npos);\r\n        REQUIRE(installerArgs.find(\"/DIR=\\\"MyDir\\\"\") != std::string::npos);\r\n    }\r\n\r\n    {\r\n        std::ostringstream installOutput;\r\n        TestContext context{ installOutput, std::cin };\r\n        auto previousThreadGlobals = context.SetForCurrentThread();\r\n        // Inno type with /silent and /log and /custom and /installlocation, switches specified in manifest\r\n        auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallerArgTest_Inno_WithSwitches.yaml\"));\r\n        context.Args.AddArg(Execution::Args::Type::Silent);\r\n        context.Args.AddArg(Execution::Args::Type::Log, \"MyLog.log\"sv);\r\n        context.Args.AddArg(Execution::Args::Type::InstallLocation, \"MyDir\"sv);\r\n        context.Add<Data::Manifest>(manifest);\r\n        context.Add<Data::Installer>(manifest.Installers.at(0));\r\n        context << GetInstallerArgs;\r\n        std::string installerArgs = context.Get<Data::InstallerArgs>();\r\n        REQUIRE(installerArgs.find(\"/mysilent\") != std::string::npos); // Use declaration in manifest\r\n        REQUIRE(installerArgs.find(\"/mylog=\\\"MyLog.log\\\"\") != std::string::npos); // Use declaration in manifest\r\n        REQUIRE(installerArgs.find(\"/mycustom\") != std::string::npos); // Use declaration in manifest\r\n        REQUIRE(installerArgs.find(\"/myinstalldir=\\\"MyDir\\\"\") != std::string::npos); // Use declaration in manifest\r\n    }\r\n\r\n    {\r\n        std::ostringstream installOutput;\r\n        TestContext context{ installOutput, std::cin };\r\n        auto previousThreadGlobals = context.SetForCurrentThread();\r\n        // Inno type with /silent and /log and /custom and /installlocation, switches specified in manifest and --custom argument used in cli\r\n        auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallerArgTest_Inno_WithSwitches.yaml\"));\r\n        context.Args.AddArg(Execution::Args::Type::Silent);\r\n        context.Args.AddArg(Execution::Args::Type::Log, \"MyLog.log\"sv);\r\n        context.Args.AddArg(Execution::Args::Type::InstallLocation, \"MyDir\"sv);\r\n        context.Args.AddArg(Execution::Args::Type::CustomSwitches, \"/MyAppendedSwitch\"sv);\r\n        context.Add<Data::Manifest>(manifest);\r\n        context.Add<Data::Installer>(manifest.Installers.at(0));\r\n        context << GetInstallerArgs;\r\n        std::string installerArgs = context.Get<Data::InstallerArgs>();\r\n        REQUIRE(installerArgs.find(\"/mysilent\") != std::string::npos); // Use declaration in manifest\r\n        REQUIRE(installerArgs.find(\"/mylog=\\\"MyLog.log\\\"\") != std::string::npos); // Use declaration in manifest\r\n        REQUIRE(installerArgs.find(\"/mycustom\") != std::string::npos); // Use declaration in manifest\r\n        REQUIRE(installerArgs.find(\"/myinstalldir=\\\"MyDir\\\"\") != std::string::npos); // Use declaration in manifest\r\n        REQUIRE(installerArgs.find(\"/MyAppendedSwitch\") != std::string::npos); // Use declaration from argument\r\n    }\r\n\r\n    {\r\n        std::ostringstream installOutput;\r\n        TestContext context{ installOutput, std::cin };\r\n        auto previousThreadGlobals = context.SetForCurrentThread();\r\n        // Inno type with /silent and /log and /custom and /installlocation, switches specified in manifest and whitespace-only --custom argument used in cli\r\n        auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallerArgTest_Inno_WithSwitches.yaml\"));\r\n        context.Args.AddArg(Execution::Args::Type::Silent);\r\n        context.Args.AddArg(Execution::Args::Type::CustomSwitches, \"\\t\"sv);\r\n        context.Add<Data::Manifest>(manifest);\r\n        context.Add<Data::Installer>(manifest.Installers.at(0));\r\n        context << GetInstallerArgs;\r\n        std::string installerArgs = context.Get<Data::InstallerArgs>();\r\n        REQUIRE(installerArgs.find(\"/mysilent\") != std::string::npos); // Use declaration in manifest\r\n        REQUIRE(installerArgs.find(\"\\t\") == std::string::npos); // Whitespace only Custom switches should not be appended\r\n    }\r\n\r\n    {\r\n        std::ostringstream installOutput;\r\n        TestContext context{ installOutput, std::cin };\r\n        auto previousThreadGlobals = context.SetForCurrentThread();\r\n        // Override switch specified. The whole arg passed to installer is overridden.\r\n        auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallerArgTest_Inno_WithSwitches.yaml\"));\r\n        context.Args.AddArg(Execution::Args::Type::Silent);\r\n        context.Args.AddArg(Execution::Args::Type::Log, \"MyLog.log\"sv);\r\n        context.Args.AddArg(Execution::Args::Type::InstallLocation, \"MyDir\"sv);\r\n        context.Args.AddArg(Execution::Args::Type::Override, \"/OverrideEverything\"sv);\r\n        context.Add<Data::Manifest>(manifest);\r\n        context.Add<Data::Installer>(manifest.Installers.at(0));\r\n        context << GetInstallerArgs;\r\n        std::string installerArgs = context.Get<Data::InstallerArgs>();\r\n        REQUIRE(installerArgs == \"/OverrideEverything\"); // Use value specified in override switch\r\n    }\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_SearchAndInstall\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForOpenSource(context, CreateTestSource({ TSR::TestQuery_ReturnOne }), true);\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestQuery_ReturnOne.Query);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify Installer is called and parameters are passed in.\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n    std::ifstream installResultFile(installResultPath.GetPath());\r\n    REQUIRE(installResultFile.is_open());\r\n    std::string installResultStr;\r\n    std::getline(installResultFile, installResultStr);\r\n    REQUIRE(installResultStr.find(\"/custom\") != std::string::npos);\r\n    REQUIRE(installResultStr.find(\"/silentwithprogress\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_SearchFoundNoApp\", \"[InstallFlow][workflow]\")\r\n{\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForOpenSource(context, CreateTestSource({}), true);\r\n    context.Args.AddArg(Execution::Args::Type::Query, \"TestQueryReturnZero\"sv);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify proper message is printed\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::NoPackageFound).get()) != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_SearchFoundMultipleApp\", \"[InstallFlow][workflow]\")\r\n{\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForOpenSource(context, CreateTestSource({ TSR::TestQuery_ReturnTwo }), true);\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestQuery_ReturnTwo.Query);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify proper message is printed\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::MultiplePackagesFound).get()) != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_LicenseAgreement\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_LicenseAgreement.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::AcceptPackageAgreements);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify agreements are shown\r\n    REQUIRE(installOutput.str().find(\"Agreement with text\") != std::string::npos);\r\n    REQUIRE(installOutput.str().find(\"This is the text of the agreement.\") != std::string::npos);\r\n    REQUIRE(installOutput.str().find(\"Agreement with URL\") != std::string::npos);\r\n    REQUIRE(installOutput.str().find(\"https://TestAgreementUrl\") != std::string::npos);\r\n\r\n    // Verify Installer is called.\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_LicenseAgreement_Prompt\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    // Accept the agreements by saying \"Yes\" at the prompt\r\n    std::istringstream installInput{ \"y\" };\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, installInput };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_LicenseAgreement.yaml\").GetPath().u8string());\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify prompt was shown\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::PackageAgreementsPrompt).get()) != std::string::npos);\r\n\r\n    // Verify agreements are shown\r\n    REQUIRE(installOutput.str().find(\"Agreement with text\") != std::string::npos);\r\n    REQUIRE(installOutput.str().find(\"This is the text of the agreement.\") != std::string::npos);\r\n    REQUIRE(installOutput.str().find(\"Agreement with URL\") != std::string::npos);\r\n    REQUIRE(installOutput.str().find(\"https://TestAgreementUrl\") != std::string::npos);\r\n\r\n    // Verify Installer is called.\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_LicenseAgreement_NotAccepted\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    // Say \"No\" at the agreements prompt\r\n    std::istringstream installInput{ \"n\" };\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, installInput };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_LicenseAgreement.yaml\").GetPath().u8string());\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify agreements are shown\r\n    REQUIRE(installOutput.str().find(\"Agreement with text\") != std::string::npos);\r\n    REQUIRE(installOutput.str().find(\"This is the text of the agreement.\") != std::string::npos);\r\n    REQUIRE(installOutput.str().find(\"Agreement with URL\") != std::string::npos);\r\n    REQUIRE(installOutput.str().find(\"https://TestAgreementUrl\") != std::string::npos);\r\n\r\n    // Verify installation failed\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED);\r\n    REQUIRE_FALSE(std::filesystem::exists(installResultPath.GetPath()));\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::PackageAgreementsNotAgreedTo).get()) != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlowMultiLocale_RequirementNotSatisfied\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"Manifest-Good-MultiLocale.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::Locale, \"en-US\"sv);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER);\r\n\r\n    // Verify Installer was not called\r\n    REQUIRE(!std::filesystem::exists(installResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"InstallFlowMultiLocale_RequirementSatisfied\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"Manifest-Good-MultiLocale.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::Locale, \"fr-FR\"sv);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify Installer is called and parameters are passed in.\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n    std::ifstream installResultFile(installResultPath.GetPath());\r\n    REQUIRE(installResultFile.is_open());\r\n    std::string installResultStr;\r\n    std::getline(installResultFile, installResultStr);\r\n    REQUIRE(installResultStr.find(\"/fr-FR\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlowMultiLocale_PreferenceNoBetterLocale\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"Manifest-Good-MultiLocale.yaml\").GetPath().u8string());\r\n\r\n    TestUserSettings settings;\r\n    settings.Set<AppInstaller::Settings::Setting::InstallLocalePreference>({ \"zh-CN\" });\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify Installer is called and parameters are passed in.\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n    std::ifstream installResultFile(installResultPath.GetPath());\r\n    REQUIRE(installResultFile.is_open());\r\n    std::string installResultStr;\r\n    std::getline(installResultFile, installResultStr);\r\n    REQUIRE(installResultStr.find(\"/unknown\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlowMultiLocale_PreferenceWithBetterLocale\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"Manifest-Good-MultiLocale.yaml\").GetPath().u8string());\r\n\r\n    TestUserSettings settings;\r\n    settings.Set<AppInstaller::Settings::Setting::InstallLocalePreference>({ \"en-US\" });\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify Installer is called and parameters are passed in.\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n    std::ifstream installResultFile(installResultPath.GetPath());\r\n    REQUIRE(installResultFile.is_open());\r\n    std::string installResultStr;\r\n    std::getline(installResultFile, installResultStr);\r\n    REQUIRE(installResultStr.find(\"/en-GB\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_InstallMultiple\", \"[InstallFlow][workflow][MultiQuery]\")\r\n{\r\n    TestCommon::TempFile exeInstallResultPath(\"TestExeInstalled.txt\");\r\n    TestCommon::TempFile msixInstallResultPath(\"TestMsixInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForMSIX(context);\r\n    OverrideForShellExecute(context);\r\n    OverrideForOpenSource(context, CreateTestSource({ TSR::TestInstaller_Exe, TSR::TestInstaller_Msix }), true);\r\n    context.Args.AddArg(Execution::Args::Type::MultiQuery, TSR::TestInstaller_Exe.Query);\r\n    context.Args.AddArg(Execution::Args::Type::MultiQuery, TSR::TestInstaller_Msix.Query);\r\n\r\n    InstallCommand installCommand({});\r\n    installCommand.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify all packages were installed\r\n    REQUIRE(std::filesystem::exists(exeInstallResultPath.GetPath()));\r\n    REQUIRE(std::filesystem::exists(msixInstallResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_InstallMultiple_SearchFailed\", \"[InstallFlow][workflow][MultiQuery]\")\r\n{\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForOpenSource(context, CreateTestSource({ TSR::TestInstaller_Exe }), true);\r\n    context.Args.AddArg(Execution::Args::Type::MultiQuery, TSR::TestInstaller_Exe.Query);\r\n    context.Args.AddArg(Execution::Args::Type::MultiQuery, TSR::TestInstaller_Msix.Query);\r\n\r\n    InstallCommand installCommand({});\r\n    installCommand.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_NOT_ALL_QUERIES_FOUND_SINGLE);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_InstallAcquiresLock\", \"[InstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForOpenSource(context, CreateTestSource({ TSR::TestQuery_ReturnOne }), true);\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestQuery_ReturnOne.Query);\r\n\r\n    wil::unique_event enteredShellExecute;\r\n    enteredShellExecute.create();\r\n    wil::unique_event canLeaveShellExecute;\r\n    canLeaveShellExecute.create();\r\n    AppInstaller::ProgressCallback progress;\r\n\r\n    context.Override({ ShellExecuteInstallImpl, [&](TestContext& context)\r\n        {\r\n            enteredShellExecute.SetEvent();\r\n            canLeaveShellExecute.wait(500);\r\n            ShellExecuteInstallImpl(context);\r\n        }});\r\n\r\n    {\r\n        std::thread otherThread([&]() {\r\n            InstallCommand install({});\r\n            install.Execute(context);\r\n            });\r\n\r\n        REQUIRE(enteredShellExecute.wait(5000));\r\n\r\n        AppInstaller::Synchronization::CrossProcessInstallLock mainThreadLock;\r\n        REQUIRE(!mainThreadLock.TryAcquireNoWait());\r\n\r\n        canLeaveShellExecute.SetEvent();\r\n        otherThread.join();\r\n    }\r\n\r\n    INFO(installOutput.str());\r\n\r\n    // Verify Installer is called and parameters are passed in.\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n    std::ifstream installResultFile(installResultPath.GetPath());\r\n    REQUIRE(installResultFile.is_open());\r\n    std::string installResultStr;\r\n    std::getline(installResultFile, installResultStr);\r\n    REQUIRE(installResultStr.find(\"/custom\") != std::string::npos);\r\n    REQUIRE(installResultStr.find(\"/silentwithprogress\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_InstallWithReboot\", \"[InstallFlow][workflow][reboot]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n    TestCommon::TestUserSettings testSettings;\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_ExpectedReturnCodes.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::AllowReboot);\r\n\r\n    context.Override({ ShellExecuteInstallImpl, [&](TestContext& context)\r\n    {\r\n        // APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_TO_INSTALL (should be treated as an installer error)\r\n        context.Add<Data::OperationReturnCode>(10);\r\n    } });\r\n\r\n    SECTION(\"Reboot success\")\r\n    {\r\n        TestHook::SetInitiateRebootResult_Override initiateRebootResultOverride(true);\r\n\r\n        InstallCommand install({});\r\n        install.Execute(context);\r\n        INFO(installOutput.str());\r\n\r\n        REQUIRE(context.IsTerminated());\r\n        REQUIRE(!std::filesystem::exists(installResultPath.GetPath()));\r\n        REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::InitiatingReboot).get()) != std::string::npos);\r\n        REQUIRE_FALSE(installOutput.str().find(Resource::LocString(Resource::String::FailedToInitiateReboot).get()) != std::string::npos);\r\n    }\r\n    SECTION(\"Reboot failed\")\r\n    {\r\n        TestHook::SetInitiateRebootResult_Override initiateRebootResultOverride(false);\r\n\r\n        InstallCommand install({});\r\n        install.Execute(context);\r\n        INFO(installOutput.str());\r\n\r\n        REQUIRE(context.IsTerminated());\r\n        REQUIRE(!std::filesystem::exists(installResultPath.GetPath()));\r\n        REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::InitiatingReboot).get()) != std::string::npos);\r\n        REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::FailedToInitiateReboot).get()) != std::string::npos);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/InstallerMetadataCollectionContext.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestSource.h\"\r\n#include \"TestHooks.h\"\r\n\r\n#include <winget/InstallerMetadataCollectionContext.h>\r\n\r\nusing namespace AppInstaller;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Repository::Correlation;\r\nusing namespace AppInstaller::Repository::Metadata;\r\nusing namespace TestCommon;\r\n\r\nnamespace\r\n{\r\n    // Indicates to set minimal defaults on TestInput\r\n    struct MinimalDefaults_t {} MinimalDefaults;\r\n\r\n    struct TestInput\r\n    {\r\n        TestInput() = default;\r\n\r\n        TestInput(MinimalDefaults_t)\r\n        {\r\n            Version = \"1.0\";\r\n            SupportedMetadataVersion = \"1.0\";\r\n            SubmissionIdentifier = \"1\";\r\n            InstallerHash = \"ABCD\";\r\n            PackageData = std::make_optional<Manifest::Manifest>();\r\n            PackageData->DefaultLocalization.Locale = \"en-us\";\r\n            PackageData->DefaultLocalization.Add<Manifest::Localization::PackageName>(\"Name\");\r\n            PackageData->DefaultLocalization.Add<Manifest::Localization::Publisher>(\"Publisher\");\r\n        }\r\n\r\n        TestInput(MinimalDefaults_t, const std::string& productVersion, const std::string& productCode, Manifest::InstallerTypeEnum installerType) : TestInput(MinimalDefaults)\r\n        {\r\n            CurrentMetadata = std::make_optional<ProductMetadata>();\r\n            CurrentMetadata->SchemaVersion.Assign(\"1.0\");\r\n            CurrentMetadata->ProductVersionMin.Assign(productVersion);\r\n            CurrentMetadata->ProductVersionMax.Assign(productVersion);\r\n            auto& installerMetadata = CurrentMetadata->InstallerMetadataMap[InstallerHash.value()];\r\n            installerMetadata.SubmissionIdentifier = SubmissionIdentifier.value();\r\n            installerMetadata.AppsAndFeaturesEntries.push_back({});\r\n            auto& entry = installerMetadata.AppsAndFeaturesEntries.back();\r\n            entry.DisplayName = PackageData->DefaultLocalization.Get<Manifest::Localization::PackageName>();\r\n            entry.Publisher = PackageData->DefaultLocalization.Get<Manifest::Localization::Publisher>();\r\n            entry.DisplayVersion = productVersion;\r\n            entry.ProductCode = productCode;\r\n            entry.InstallerType = installerType;\r\n        }\r\n\r\n        std::optional<std::string> Version;\r\n        std::optional<std::string> SupportedMetadataVersion;\r\n        std::optional<ProductMetadata> CurrentMetadata;\r\n        std::optional<web::json::value> SubmissionData;\r\n        std::optional<std::string> SubmissionIdentifier;\r\n        std::optional<std::string> InstallerHash;\r\n        // Schema 1.0 only cares about DefaultLocale and Locales\r\n        std::optional<Manifest::Manifest> PackageData;\r\n\r\n        std::wstring ToJSON()\r\n        {\r\n            web::json::value json;\r\n\r\n            if (Version)\r\n            {\r\n                json[L\"version\"] = JSON::GetStringValue(Version.value());\r\n            }\r\n\r\n            if (SupportedMetadataVersion)\r\n            {\r\n                json[L\"supportedMetadataVersion\"] = JSON::GetStringValue(SupportedMetadataVersion.value());\r\n            }\r\n\r\n            if (CurrentMetadata)\r\n            {\r\n                json[L\"currentMetadata\"] = CurrentMetadata->ToJson(CurrentMetadata->SchemaVersion, 0);\r\n            }\r\n\r\n            if (SubmissionData)\r\n            {\r\n                json[L\"submissionData\"] = SubmissionData.value();\r\n            }\r\n            else if (SubmissionIdentifier)\r\n            {\r\n                web::json::value submissionData;\r\n                submissionData[L\"submissionIdentifier\"] = JSON::GetStringValue(SubmissionIdentifier.value());\r\n                json[L\"submissionData\"] = std::move(submissionData);\r\n            }\r\n\r\n            if (InstallerHash || PackageData)\r\n            {\r\n                web::json::value packageData;\r\n\r\n                if (InstallerHash)\r\n                {\r\n                    packageData[L\"installerHash\"] = JSON::GetStringValue(InstallerHash.value());\r\n                }\r\n\r\n                if (PackageData)\r\n                {\r\n                    packageData[L\"DefaultLocale\"] = LocaleToJSON(PackageData->DefaultLocalization);\r\n\r\n                    // TODO: Implement other locales\r\n                }\r\n\r\n                json[L\"packageData\"] = std::move(packageData);\r\n            }\r\n\r\n            return json.serialize();\r\n        }\r\n\r\n    private:\r\n        web::json::value LocaleToJSON(const Manifest::ManifestLocalization& localization) const\r\n        {\r\n            web::json::value locale;\r\n\r\n            locale[L\"PackageLocale\"] = JSON::GetStringValue(localization.Locale);\r\n\r\n            if (localization.Contains(Manifest::Localization::PackageName))\r\n            {\r\n                locale[L\"PackageName\"] = JSON::GetStringValue(localization.Get<Manifest::Localization::PackageName>());\r\n            }\r\n\r\n            if (localization.Contains(Manifest::Localization::Publisher))\r\n            {\r\n                locale[L\"Publisher\"] = JSON::GetStringValue(localization.Get<Manifest::Localization::Publisher>());\r\n            }\r\n\r\n            // TODO: Implement any other needed fields\r\n\r\n            return locale;\r\n        }\r\n    };\r\n\r\n    struct TestOutput\r\n    {\r\n        TestOutput(const std::string& json) : OriginalJSON(json)\r\n        {\r\n            web::json::value input = web::json::value::parse(Utility::ConvertToUTF16(json));\r\n\r\n            auto versionString = JSON::GetRawStringValueFromJsonNode(input, L\"version\");\r\n            if (versionString)\r\n            {\r\n                Version = std::move(versionString);\r\n            }\r\n\r\n            auto submissionDataValue = JSON::GetJsonValueFromNode(input, L\"submissionData\");\r\n            if (submissionDataValue)\r\n            {\r\n                SubmissionData = submissionDataValue.value();\r\n            }\r\n\r\n            auto installerHashString = JSON::GetRawStringValueFromJsonNode(input, L\"installerHash\");\r\n            if (installerHashString)\r\n            {\r\n                InstallerHash = std::move(installerHashString);\r\n            }\r\n\r\n            auto statusString = JSON::GetRawStringValueFromJsonNode(input, L\"status\");\r\n            if (statusString)\r\n            {\r\n                Status = std::move(statusString);\r\n            }\r\n\r\n            auto metadataValue = JSON::GetJsonValueFromNode(input, L\"metadata\");\r\n            if (metadataValue && !metadataValue->get().is_null())\r\n            {\r\n                Metadata = std::make_optional<ProductMetadata>();\r\n                Metadata->FromJson(metadataValue->get());\r\n            }\r\n\r\n            auto diagnosticsValue = JSON::GetJsonValueFromNode(input, L\"diagnostics\");\r\n            if (diagnosticsValue)\r\n            {\r\n                auto errorHRNumber = JSON::GetRawIntValueFromJsonNode(diagnosticsValue.value(), L\"errorHR\");\r\n                if (errorHRNumber)\r\n                {\r\n                    ErrorHR = std::move(errorHRNumber);\r\n                }\r\n\r\n                auto errorTextString = JSON::GetRawStringValueFromJsonNode(diagnosticsValue.value(), L\"errorText\");\r\n                if (errorTextString)\r\n                {\r\n                    ErrorText = std::move(errorTextString);\r\n                }\r\n            }\r\n        }\r\n\r\n        std::string OriginalJSON;\r\n\r\n        std::optional<std::string> Version;\r\n        std::optional<web::json::value> SubmissionData;\r\n        std::optional<std::string> InstallerHash;\r\n        std::optional<std::string> Status;\r\n        std::optional<ProductMetadata> Metadata;\r\n        std::optional<HRESULT> ErrorHR;\r\n        std::optional<std::string> ErrorText;\r\n\r\n        bool IsError() const\r\n        {\r\n            return Status && Status.value() == \"Error\";\r\n        }\r\n\r\n        bool IsSuccess() const\r\n        {\r\n            return Status && Status.value() == \"Success\";\r\n        }\r\n\r\n        bool IsLowConfidence() const\r\n        {\r\n            return Status && Status.value() == \"LowConfidence\";\r\n        }\r\n\r\n        void ValidateFieldPresence() const\r\n        {\r\n            REQUIRE(Version);\r\n            REQUIRE(SubmissionData);\r\n            REQUIRE(InstallerHash);\r\n            REQUIRE(Status);\r\n\r\n            REQUIRE(IsSuccess() == Metadata.has_value());\r\n\r\n            REQUIRE(IsError() == ErrorHR.has_value());\r\n            REQUIRE(IsError() == ErrorText.has_value());\r\n        }\r\n    };\r\n\r\n    struct TestARPCorrelationData : public ARPCorrelationData\r\n    {\r\n        ARPCorrelationResult CorrelateForNewlyInstalled(const Manifest::Manifest&, const ARPCorrelationSettings&) override\r\n        {\r\n            return CorrelateForNewlyInstalledResult;\r\n        }\r\n\r\n        ARPCorrelationResult CorrelateForNewlyInstalledResult;\r\n    };\r\n\r\n    struct TestInstalledFilesCorrelation : public InstalledFilesCorrelation\r\n    {\r\n        Correlation::InstallationMetadata CorrelateForNewlyInstalled(const Manifest::Manifest&, const std::string&) override\r\n        {\r\n            return InstallationMetadata;\r\n        }\r\n\r\n        void StartFileWatcher() override {}\r\n\r\n        void StopFileWatcher() override {}\r\n\r\n        Correlation::InstallationMetadata InstallationMetadata;\r\n    };\r\n\r\n    InstallerMetadataCollectionContext CreateTestContext(\r\n        std::unique_ptr<ARPCorrelationData>&& data,\r\n        std::unique_ptr<InstalledFilesCorrelation>&& installedFiles,\r\n        TestInput& input)\r\n    {\r\n        return { std::move(data), std::move(installedFiles), input.ToJSON() };\r\n    }\r\n\r\n    InstallerMetadataCollectionContext CreateTestContext(std::unique_ptr<ARPCorrelationData>&& data, TestInput& input)\r\n    {\r\n        return { std::move(data), std::make_unique<TestInstalledFilesCorrelation>(), input.ToJSON()};\r\n    }\r\n\r\n    InstallerMetadataCollectionContext CreateTestContext(TestInput& input)\r\n    {\r\n        return CreateTestContext(std::make_unique<TestARPCorrelationData>(), input);\r\n    }\r\n\r\n    TestOutput GetOutput(InstallerMetadataCollectionContext& context)\r\n    {\r\n        std::ostringstream strstr;\r\n        context.Complete(strstr);\r\n\r\n        return { strstr.str() };\r\n    }\r\n\r\n    TestOutput GetOutput(TestInput& input)\r\n    {\r\n        InstallerMetadataCollectionContext context = CreateTestContext(input);\r\n        return GetOutput(context);\r\n    }\r\n\r\n    void BadInputTest(TestInput& input)\r\n    {\r\n        TestOutput output = GetOutput(input);\r\n        REQUIRE(output.IsError());\r\n        output.ValidateFieldPresence();\r\n    }\r\n\r\n    ProductMetadata MakeProductMetadata(std::string_view submissionIdentifier = \"Submission 1\", const std::string& installerHash = \"ABCD\")\r\n    {\r\n        ProductMetadata result;\r\n        result.SchemaVersion.Assign(\"1.0\");\r\n        result.ProductVersionMin.Assign(\"1.0\");\r\n        result.ProductVersionMax.Assign(\"1.0\");\r\n        auto& installerMetadata = result.InstallerMetadataMap[installerHash];\r\n        installerMetadata.SubmissionIdentifier = submissionIdentifier;\r\n        installerMetadata.AppsAndFeaturesEntries.push_back({});\r\n        auto& entry = installerMetadata.AppsAndFeaturesEntries.back();\r\n        entry.DisplayName = \"Name\";\r\n        entry.Publisher = \"Publisher\";\r\n        entry.DisplayVersion = \"1.0\";\r\n        entry.ProductCode = \"{guid}\";\r\n        entry.InstallerType = Manifest::InstallerTypeEnum::Msi;\r\n        return result;\r\n    }\r\n\r\n    struct TestMerge\r\n    {\r\n        TestMerge() = default;\r\n\r\n        TestMerge(MinimalDefaults_t)\r\n        {\r\n            Version = \"1.0\";\r\n            Metadatas = std::make_optional<std::vector<ProductMetadata>>();\r\n            Metadatas->emplace_back(MakeProductMetadata());\r\n        }\r\n\r\n        std::optional<std::string> Version;\r\n        std::optional<std::vector<ProductMetadata>> Metadatas;\r\n\r\n        std::wstring ToJSON()\r\n        {\r\n            web::json::value json;\r\n\r\n            if (Version)\r\n            {\r\n                json[L\"version\"] = JSON::GetStringValue(Version.value());\r\n            }\r\n\r\n            if (Metadatas)\r\n            {\r\n                web::json::value metadatasArray;\r\n\r\n                if (Metadatas->empty())\r\n                {\r\n                    metadatasArray = web::json::value::array();\r\n                }\r\n                else\r\n                {\r\n                    size_t index = 0;\r\n                    for (auto& value : Metadatas.value())\r\n                    {\r\n                        metadatasArray[index++] = value.ToJson(value.SchemaVersion, 0);\r\n                    }\r\n                }\r\n\r\n                json[L\"metadatas\"] = std::move(metadatasArray);\r\n            }\r\n\r\n            return json.serialize();\r\n        }\r\n    };\r\n}\r\n\r\nTEST_CASE(\"MetadataCollection_MinimumInput\", \"[metadata_collection]\")\r\n{\r\n    TestInput input(MinimalDefaults);\r\n    TestOutput output = GetOutput(input);\r\n    REQUIRE(!output.IsError());\r\n    output.ValidateFieldPresence();\r\n\r\n    REQUIRE(output.Version.value() == input.Version.value());\r\n    REQUIRE(output.InstallerHash.value() == input.InstallerHash.value());\r\n}\r\n\r\nTEST_CASE(\"MetadataCollection_SubmissionDataCopied\", \"[metadata_collection]\")\r\n{\r\n    TestInput input(MinimalDefaults);\r\n\r\n    web::json::value submissionData;\r\n    std::wstring testValueName = L\"testValueName\";\r\n    std::string testValueValue = \"Test value value\";\r\n    submissionData[L\"submissionIdentifier\"] = JSON::GetStringValue(\"Required identifier\");\r\n    submissionData[testValueName] = JSON::GetStringValue(testValueValue);\r\n\r\n    input.SubmissionData = submissionData;\r\n\r\n    TestOutput output = GetOutput(input);\r\n    REQUIRE(!output.IsError());\r\n    output.ValidateFieldPresence();\r\n\r\n    REQUIRE(output.Version.value() == input.Version.value());\r\n    REQUIRE(output.InstallerHash.value() == input.InstallerHash.value());\r\n    auto outputValue = JSON::GetRawStringValueFromJsonNode(output.SubmissionData.value(), testValueName);\r\n    REQUIRE(outputValue);\r\n    REQUIRE(outputValue.value() == testValueValue);\r\n}\r\n\r\nTEST_CASE(\"MetadataCollection_BadInput\", \"[metadata_collection]\")\r\n{\r\n    TestInput input(MinimalDefaults);\r\n\r\n#define RESET_FIELD_SECTION(_field_) \\\r\n    SECTION(\"No \" #_field_) \\\r\n    { \\\r\n        input._field_.reset(); \\\r\n        BadInputTest(input); \\\r\n    }\r\n\r\n    RESET_FIELD_SECTION(Version);\r\n    RESET_FIELD_SECTION(SupportedMetadataVersion);\r\n    RESET_FIELD_SECTION(SubmissionIdentifier);\r\n    RESET_FIELD_SECTION(InstallerHash);\r\n    RESET_FIELD_SECTION(PackageData);\r\n\r\n#undef RESET_FIELD_SECTION\r\n}\r\n\r\nTEST_CASE(\"MetadataCollection_LowConfidence\", \"[metadata_collection]\")\r\n{\r\n    TestInput input(MinimalDefaults);\r\n    // The default test correlation object won't have a package correlation set\r\n    TestOutput output = GetOutput(input);\r\n    REQUIRE(output.IsLowConfidence());\r\n    REQUIRE(!output.Metadata);\r\n    output.ValidateFieldPresence();\r\n}\r\n\r\nTEST_CASE(\"MetadataCollection_NewPackage\", \"[metadata_collection]\")\r\n{\r\n    TestInput input(MinimalDefaults);\r\n    auto correlationData = std::make_unique<TestARPCorrelationData>();\r\n\r\n    Manifest::Manifest manifest;\r\n    manifest.DefaultLocalization.Add<Manifest::Localization::PackageName>(\"Test Package Name\");\r\n    manifest.DefaultLocalization.Add<Manifest::Localization::Publisher>(\"Test Publisher\");\r\n    manifest.Version = \"1.2.3\";\r\n    manifest.Installers.push_back({});\r\n    manifest.Installers[0].ProductCode = \"{guid}\";\r\n\r\n    IPackageVersion::Metadata metadata;\r\n    metadata[PackageVersionMetadata::InstalledType] = Manifest::InstallerTypeToString(Manifest::InstallerTypeEnum::Msi);\r\n    metadata[PackageVersionMetadata::InstalledScope] = Manifest::ScopeToString(Manifest::ScopeEnum::User);\r\n\r\n    correlationData->CorrelateForNewlyInstalledResult.Package = std::make_shared<TestPackageVersion>(manifest, metadata);\r\n\r\n    InstallerMetadataCollectionContext context = CreateTestContext(std::move(correlationData), input);\r\n    TestOutput output = GetOutput(context);\r\n\r\n    REQUIRE(output.IsSuccess());\r\n    output.ValidateFieldPresence();\r\n\r\n    REQUIRE(output.Metadata->ProductVersionMin.ToString() == output.Metadata->ProductVersionMax.ToString());\r\n    REQUIRE(output.Metadata->ProductVersionMin.ToString() == manifest.Version);\r\n    REQUIRE(output.Metadata->InstallerMetadataMap.size() == 1);\r\n    REQUIRE(output.Metadata->InstallerMetadataMap.count(input.InstallerHash.value()) == 1);\r\n    const auto& entry = output.Metadata->InstallerMetadataMap[input.InstallerHash.value()];\r\n    REQUIRE(entry.SubmissionIdentifier == input.SubmissionIdentifier.value());\r\n    REQUIRE(entry.Scope.empty());\r\n    REQUIRE(entry.AppsAndFeaturesEntries.size() == 1);\r\n    REQUIRE(entry.AppsAndFeaturesEntries[0].DisplayName == manifest.DefaultLocalization.Get<Manifest::Localization::PackageName>());\r\n    REQUIRE(entry.AppsAndFeaturesEntries[0].Publisher == manifest.DefaultLocalization.Get<Manifest::Localization::Publisher>());\r\n    REQUIRE(entry.AppsAndFeaturesEntries[0].DisplayVersion == manifest.Version);\r\n    REQUIRE(entry.AppsAndFeaturesEntries[0].ProductCode == manifest.Installers[0].ProductCode);\r\n    REQUIRE(entry.AppsAndFeaturesEntries[0].InstallerType == Manifest::InstallerTypeEnum::Msi);\r\n    REQUIRE(output.Metadata->HistoricalMetadataList.empty());\r\n}\r\n\r\nTEST_CASE(\"MetadataCollection_SameSubmission_SameInstaller\", \"[metadata_collection]\")\r\n{\r\n    std::string version = \"1.3.5\";\r\n    std::string productCode = \"{guid}\";\r\n    Manifest::InstallerTypeEnum installerType = Manifest::InstallerTypeEnum::Msi;\r\n\r\n    TestInput input(MinimalDefaults, version, productCode, installerType);\r\n    auto correlationData = std::make_unique<TestARPCorrelationData>();\r\n\r\n    Manifest::Manifest manifest;\r\n    manifest.DefaultLocalization.Add<Manifest::Localization::PackageName>(\"Different Language Name\");\r\n    // Same publisher\r\n    manifest.DefaultLocalization.Add<Manifest::Localization::Publisher>(input.CurrentMetadata->InstallerMetadataMap.begin()->second.AppsAndFeaturesEntries[0].Publisher);\r\n    manifest.Version = version;\r\n    manifest.Installers.push_back({});\r\n    manifest.Installers[0].ProductCode = productCode;\r\n\r\n    IPackageVersion::Metadata metadata;\r\n    metadata[PackageVersionMetadata::InstalledType] = Manifest::InstallerTypeToString(installerType);\r\n\r\n    correlationData->CorrelateForNewlyInstalledResult.Package = std::make_shared<TestPackageVersion>(manifest, metadata);\r\n\r\n    InstallerMetadataCollectionContext context = CreateTestContext(std::move(correlationData), input);\r\n    TestOutput output = GetOutput(context);\r\n\r\n    REQUIRE(output.IsSuccess());\r\n    output.ValidateFieldPresence();\r\n\r\n    REQUIRE(output.Metadata->ProductVersionMin.ToString() == output.Metadata->ProductVersionMax.ToString());\r\n    REQUIRE(output.Metadata->ProductVersionMin.ToString() == manifest.Version);\r\n    REQUIRE(output.Metadata->InstallerMetadataMap.size() == 1);\r\n    REQUIRE(output.Metadata->InstallerMetadataMap.count(input.InstallerHash.value()) == 1);\r\n    const auto& entry = output.Metadata->InstallerMetadataMap[input.InstallerHash.value()];\r\n    REQUIRE(entry.SubmissionIdentifier == input.SubmissionIdentifier.value());\r\n    REQUIRE(entry.AppsAndFeaturesEntries.size() == 2);\r\n\r\n    // One should have all values, and the other should have just a different name\r\n    // Base which one is which off of whether Publisher is set\r\n    for (const auto& featureEntry : entry.AppsAndFeaturesEntries)\r\n    {\r\n        if (featureEntry.Publisher.empty())\r\n        {\r\n            REQUIRE(featureEntry.DisplayName == manifest.DefaultLocalization.Get<Manifest::Localization::PackageName>());\r\n            REQUIRE(featureEntry.DisplayVersion.empty());\r\n            REQUIRE(featureEntry.ProductCode.empty());\r\n            REQUIRE(featureEntry.InstallerType == Manifest::InstallerTypeEnum::Unknown);\r\n        }\r\n        else\r\n        {\r\n            REQUIRE(featureEntry.DisplayName == input.CurrentMetadata->InstallerMetadataMap.begin()->second.AppsAndFeaturesEntries[0].DisplayName);\r\n            REQUIRE(featureEntry.Publisher == manifest.DefaultLocalization.Get<Manifest::Localization::Publisher>());\r\n            REQUIRE(featureEntry.DisplayVersion == manifest.Version);\r\n            REQUIRE(featureEntry.ProductCode == manifest.Installers[0].ProductCode);\r\n            REQUIRE(featureEntry.InstallerType == Manifest::InstallerTypeEnum::Msi);\r\n        }\r\n    }\r\n    REQUIRE(output.Metadata->HistoricalMetadataList.empty());\r\n}\r\n\r\nTEST_CASE(\"MetadataCollection_SameSubmission_NewInstaller\", \"[metadata_collection]\")\r\n{\r\n    std::string versionPresent = \"1.3.5\";\r\n    std::string versionIncoming = \"1.3.5.1\";\r\n    std::string productCodePresent = \"{guid}\";\r\n    std::string productCodeIncoming = \"{guid_different}\";\r\n    Manifest::InstallerTypeEnum installerType = Manifest::InstallerTypeEnum::Msi;\r\n\r\n    TestInput input(MinimalDefaults, versionPresent, productCodePresent, installerType);\r\n    // Change the incoming hash to be new\r\n    input.InstallerHash = input.InstallerHash.value() + \"_DIFFERENT\";\r\n    auto correlationData = std::make_unique<TestARPCorrelationData>();\r\n\r\n    Manifest::Manifest manifest;\r\n    manifest.DefaultLocalization.Add<Manifest::Localization::PackageName>(\"Name (but different architecture)\");\r\n    // Same publisher\r\n    manifest.DefaultLocalization.Add<Manifest::Localization::Publisher>(input.CurrentMetadata->InstallerMetadataMap.begin()->second.AppsAndFeaturesEntries[0].Publisher);\r\n    manifest.Version = versionIncoming;\r\n    manifest.Installers.push_back({});\r\n    manifest.Installers[0].ProductCode = productCodeIncoming;\r\n\r\n    IPackageVersion::Metadata metadata;\r\n    metadata[PackageVersionMetadata::InstalledType] = Manifest::InstallerTypeToString(installerType);\r\n\r\n    correlationData->CorrelateForNewlyInstalledResult.Package = std::make_shared<TestPackageVersion>(manifest, metadata);\r\n\r\n    InstallerMetadataCollectionContext context = CreateTestContext(std::move(correlationData), input);\r\n    TestOutput output = GetOutput(context);\r\n\r\n    REQUIRE(output.IsSuccess());\r\n    output.ValidateFieldPresence();\r\n\r\n    REQUIRE(output.Metadata->ProductVersionMin.ToString() == versionPresent);\r\n    REQUIRE(output.Metadata->ProductVersionMax.ToString() == versionIncoming);\r\n    REQUIRE(output.Metadata->InstallerMetadataMap.size() == 2);\r\n\r\n    for (const auto& installerMetadata : output.Metadata->InstallerMetadataMap)\r\n    {\r\n        const auto& entry = installerMetadata.second;\r\n\r\n        REQUIRE(entry.SubmissionIdentifier == input.SubmissionIdentifier.value());\r\n        REQUIRE(entry.AppsAndFeaturesEntries.size() == 1);\r\n\r\n        const auto& featureEntry = entry.AppsAndFeaturesEntries.front();\r\n        REQUIRE(featureEntry.Publisher == manifest.DefaultLocalization.Get<Manifest::Localization::Publisher>());\r\n\r\n        if (featureEntry.ProductCode == productCodePresent)\r\n        {\r\n            REQUIRE(featureEntry.DisplayName == input.CurrentMetadata->InstallerMetadataMap.begin()->second.AppsAndFeaturesEntries[0].DisplayName);\r\n            REQUIRE(featureEntry.DisplayVersion == versionPresent);\r\n            REQUIRE(featureEntry.InstallerType == Manifest::InstallerTypeEnum::Msi);\r\n        }\r\n        else\r\n        {\r\n            REQUIRE(featureEntry.DisplayName == manifest.DefaultLocalization.Get<Manifest::Localization::PackageName>());\r\n            REQUIRE(featureEntry.DisplayVersion == versionIncoming);\r\n            REQUIRE(featureEntry.InstallerType == Manifest::InstallerTypeEnum::Msi);\r\n            REQUIRE(featureEntry.ProductCode == productCodeIncoming);\r\n        }\r\n    }\r\n\r\n    REQUIRE(output.Metadata->HistoricalMetadataList.empty());\r\n}\r\n\r\nTEST_CASE(\"MetadataCollection_NewSubmission\", \"[metadata_collection]\")\r\n{\r\n    std::string versionPresent = \"1.3.5\";\r\n    std::string versionIncoming = \"1.4.0\";\r\n    std::string productCodePresent = \"{guid}\";\r\n    std::string productCodeIncoming = \"{guid_different}\";\r\n    Manifest::InstallerTypeEnum installerType = Manifest::InstallerTypeEnum::Msi;\r\n\r\n    TestInput input(MinimalDefaults, versionPresent, productCodePresent, installerType);\r\n    input.SubmissionIdentifier = input.SubmissionIdentifier.value() + \"_NEW\";\r\n    input.InstallerHash = input.InstallerHash.value() + \"_DIFFERENT\";\r\n    auto correlationData = std::make_unique<TestARPCorrelationData>();\r\n\r\n    Manifest::Manifest manifest;\r\n    manifest.DefaultLocalization.Add<Manifest::Localization::PackageName>(input.CurrentMetadata->InstallerMetadataMap.begin()->second.AppsAndFeaturesEntries[0].DisplayName);\r\n    manifest.DefaultLocalization.Add<Manifest::Localization::Publisher>(input.CurrentMetadata->InstallerMetadataMap.begin()->second.AppsAndFeaturesEntries[0].Publisher);\r\n    manifest.Version = versionIncoming;\r\n    manifest.Installers.push_back({});\r\n    manifest.Installers[0].ProductCode = productCodeIncoming;\r\n\r\n    IPackageVersion::Metadata metadata;\r\n    metadata[PackageVersionMetadata::InstalledType] = Manifest::InstallerTypeToString(installerType);\r\n\r\n    correlationData->CorrelateForNewlyInstalledResult.Package = std::make_shared<TestPackageVersion>(manifest, metadata);\r\n\r\n    InstallerMetadataCollectionContext context = CreateTestContext(std::move(correlationData), input);\r\n    TestOutput output = GetOutput(context);\r\n\r\n    REQUIRE(output.IsSuccess());\r\n    output.ValidateFieldPresence();\r\n\r\n    REQUIRE(output.Metadata->ProductVersionMin.ToString() == output.Metadata->ProductVersionMax.ToString());\r\n    REQUIRE(output.Metadata->ProductVersionMin.ToString() == manifest.Version);\r\n    REQUIRE(output.Metadata->InstallerMetadataMap.size() == 1);\r\n    REQUIRE(output.Metadata->InstallerMetadataMap.count(input.InstallerHash.value()) == 1);\r\n    const auto& entry = output.Metadata->InstallerMetadataMap[input.InstallerHash.value()];\r\n    REQUIRE(entry.SubmissionIdentifier == input.SubmissionIdentifier.value());\r\n    REQUIRE(entry.AppsAndFeaturesEntries.size() == 1);\r\n    REQUIRE(entry.AppsAndFeaturesEntries[0].DisplayName == manifest.DefaultLocalization.Get<Manifest::Localization::PackageName>());\r\n    REQUIRE(entry.AppsAndFeaturesEntries[0].Publisher == manifest.DefaultLocalization.Get<Manifest::Localization::Publisher>());\r\n    REQUIRE(entry.AppsAndFeaturesEntries[0].DisplayVersion == manifest.Version);\r\n    REQUIRE(entry.AppsAndFeaturesEntries[0].ProductCode == manifest.Installers[0].ProductCode);\r\n    REQUIRE(entry.AppsAndFeaturesEntries[0].InstallerType == Manifest::InstallerTypeEnum::Msi);\r\n\r\n    REQUIRE(output.Metadata->HistoricalMetadataList.size() == 1);\r\n    const auto& historicalEntry = output.Metadata->HistoricalMetadataList[0];\r\n    REQUIRE(historicalEntry.ProductVersionMin.ToString() == input.CurrentMetadata->ProductVersionMin.ToString());\r\n    REQUIRE(historicalEntry.ProductVersionMax.ToString() == input.CurrentMetadata->ProductVersionMax.ToString());\r\n    const auto& appsAndFeaturesEntry = input.CurrentMetadata->InstallerMetadataMap.begin()->second.AppsAndFeaturesEntries.front();\r\n    REQUIRE(historicalEntry.Names.size() == 1);\r\n    REQUIRE(*historicalEntry.Names.begin() == appsAndFeaturesEntry.DisplayName);\r\n    REQUIRE(historicalEntry.ProductCodes.size() == 1);\r\n    REQUIRE(*historicalEntry.ProductCodes.begin() == appsAndFeaturesEntry.ProductCode);\r\n    REQUIRE(historicalEntry.Publishers.size() == 1);\r\n    REQUIRE(*historicalEntry.Publishers.begin() == appsAndFeaturesEntry.Publisher);\r\n}\r\n\r\nTEST_CASE(\"MetadataCollection_Merge_Empty\", \"[metadata_collection]\")\r\n{\r\n    TestMerge mergeData{ MinimalDefaults };\r\n    mergeData.Metadatas->clear();\r\n\r\n    REQUIRE_THROWS_HR(InstallerMetadataCollectionContext::Merge(mergeData.ToJSON(), 0, {}), E_NOT_SET);\r\n}\r\n\r\nTEST_CASE(\"MetadataCollection_Merge_SubmissionMismatch\", \"[metadata_collection]\")\r\n{\r\n    TestMerge mergeData{ MinimalDefaults };\r\n    mergeData.Metadatas->emplace_back(MakeProductMetadata(\"Submission 2\"));\r\n\r\n    REQUIRE_THROWS_HR(InstallerMetadataCollectionContext::Merge(mergeData.ToJSON(), 0, {}), E_NOT_VALID_STATE);\r\n}\r\n\r\nTEST_CASE(\"MetadataCollection_Merge_DifferentInstallers\", \"[metadata_collection]\")\r\n{\r\n    TestMerge mergeData{ MinimalDefaults };\r\n    mergeData.Metadatas->emplace_back(MakeProductMetadata(mergeData.Metadatas->at(0).InstallerMetadataMap.begin()->second.SubmissionIdentifier, \"EFGH\"));\r\n\r\n    std::wstring mergeResult = InstallerMetadataCollectionContext::Merge(mergeData.ToJSON(), 0, {});\r\n    REQUIRE(!mergeResult.empty());\r\n\r\n    ProductMetadata mergeMetadata;\r\n    mergeMetadata.FromJson(web::json::value::parse(mergeResult));\r\n\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.size() == 2);\r\n    for (const auto& item : mergeMetadata.InstallerMetadataMap)\r\n    {\r\n        REQUIRE(item.second.AppsAndFeaturesEntries.size() == 1);\r\n        REQUIRE(!item.second.AppsAndFeaturesEntries[0].DisplayName.empty());\r\n        REQUIRE(!item.second.AppsAndFeaturesEntries[0].Publisher.empty());\r\n        REQUIRE(!item.second.AppsAndFeaturesEntries[0].DisplayVersion.empty());\r\n        REQUIRE(!item.second.AppsAndFeaturesEntries[0].ProductCode.empty());\r\n    }\r\n}\r\n\r\nTEST_CASE(\"MetadataCollection_Merge_SameInstaller\", \"[metadata_collection]\")\r\n{\r\n    TestMerge mergeData{ MinimalDefaults };\r\n    mergeData.Metadatas->emplace_back(MakeProductMetadata());\r\n\r\n    std::wstring mergeResult = InstallerMetadataCollectionContext::Merge(mergeData.ToJSON(), 0, {});\r\n    REQUIRE(!mergeResult.empty());\r\n\r\n    ProductMetadata mergeMetadata;\r\n    mergeMetadata.FromJson(web::json::value::parse(mergeResult));\r\n\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.size() == 1);\r\n    for (const auto& item : mergeMetadata.InstallerMetadataMap)\r\n    {\r\n        REQUIRE(item.second.AppsAndFeaturesEntries.size() == 1);\r\n        REQUIRE(!item.second.AppsAndFeaturesEntries[0].DisplayName.empty());\r\n        REQUIRE(!item.second.AppsAndFeaturesEntries[0].Publisher.empty());\r\n        REQUIRE(!item.second.AppsAndFeaturesEntries[0].DisplayVersion.empty());\r\n        REQUIRE(!item.second.AppsAndFeaturesEntries[0].ProductCode.empty());\r\n    }\r\n}\r\n\r\nTEST_CASE(\"MetadataCollection_NewPackage_1_1\", \"[metadata_collection]\")\r\n{\r\n    TestInput input(MinimalDefaults);\r\n    input.SupportedMetadataVersion = \"1.1\";\r\n    auto correlationData = std::make_unique<TestARPCorrelationData>();\r\n\r\n    Manifest::Manifest manifest;\r\n    manifest.DefaultLocalization.Add<Manifest::Localization::PackageName>(\"Test Package Name\");\r\n    manifest.DefaultLocalization.Add<Manifest::Localization::Publisher>(\"Test Publisher\");\r\n    manifest.Version = \"1.2.3\";\r\n    manifest.Installers.push_back({});\r\n    manifest.Installers[0].ProductCode = \"{guid}\";\r\n\r\n    IPackageVersion::Metadata metadata;\r\n    metadata[PackageVersionMetadata::InstalledType] = Manifest::InstallerTypeToString(Manifest::InstallerTypeEnum::Msi);\r\n    metadata[PackageVersionMetadata::InstalledScope] = Manifest::ScopeToString(Manifest::ScopeEnum::User);\r\n\r\n    correlationData->CorrelateForNewlyInstalledResult.Package = std::make_shared<TestPackageVersion>(manifest, metadata);\r\n\r\n    InstallerMetadataCollectionContext context = CreateTestContext(std::move(correlationData), input);\r\n    TestOutput output = GetOutput(context);\r\n\r\n    REQUIRE(output.IsSuccess());\r\n    output.ValidateFieldPresence();\r\n\r\n    REQUIRE(output.Metadata->ProductVersionMin.ToString() == output.Metadata->ProductVersionMax.ToString());\r\n    REQUIRE(output.Metadata->ProductVersionMin.ToString() == manifest.Version);\r\n    REQUIRE(output.Metadata->InstallerMetadataMap.size() == 1);\r\n    REQUIRE(output.Metadata->InstallerMetadataMap.count(input.InstallerHash.value()) == 1);\r\n    const auto& entry = output.Metadata->InstallerMetadataMap[input.InstallerHash.value()];\r\n    REQUIRE(entry.SubmissionIdentifier == input.SubmissionIdentifier.value());\r\n    REQUIRE(entry.Scope == metadata[PackageVersionMetadata::InstalledScope]);\r\n    REQUIRE(entry.AppsAndFeaturesEntries.size() == 1);\r\n    REQUIRE(entry.AppsAndFeaturesEntries[0].DisplayName == manifest.DefaultLocalization.Get<Manifest::Localization::PackageName>());\r\n    REQUIRE(entry.AppsAndFeaturesEntries[0].Publisher == manifest.DefaultLocalization.Get<Manifest::Localization::Publisher>());\r\n    REQUIRE(entry.AppsAndFeaturesEntries[0].DisplayVersion == manifest.Version);\r\n    REQUIRE(entry.AppsAndFeaturesEntries[0].ProductCode == manifest.Installers[0].ProductCode);\r\n    REQUIRE(entry.AppsAndFeaturesEntries[0].InstallerType == Manifest::InstallerTypeEnum::Msi);\r\n    REQUIRE(output.Metadata->HistoricalMetadataList.empty());\r\n}\r\n\r\nTEST_CASE(\"MetadataCollection_NewPackage_NoScope\", \"[metadata_collection]\")\r\n{\r\n    TestInput input(MinimalDefaults);\r\n    input.SupportedMetadataVersion = \"1.1\";\r\n    auto correlationData = std::make_unique<TestARPCorrelationData>();\r\n\r\n    Manifest::Manifest manifest;\r\n    manifest.DefaultLocalization.Add<Manifest::Localization::PackageName>(\"Test Package Name\");\r\n    manifest.DefaultLocalization.Add<Manifest::Localization::Publisher>(\"Test Publisher\");\r\n    manifest.Version = \"1.2.3\";\r\n    manifest.Installers.push_back({});\r\n    manifest.Installers[0].ProductCode = \"{guid}\";\r\n\r\n    IPackageVersion::Metadata metadata;\r\n    metadata[PackageVersionMetadata::InstalledType] = Manifest::InstallerTypeToString(Manifest::InstallerTypeEnum::Msi);\r\n\r\n    correlationData->CorrelateForNewlyInstalledResult.Package = std::make_shared<TestPackageVersion>(manifest, metadata);\r\n\r\n    InstallerMetadataCollectionContext context = CreateTestContext(std::move(correlationData), input);\r\n    TestOutput output = GetOutput(context);\r\n\r\n    REQUIRE(output.IsSuccess());\r\n    output.ValidateFieldPresence();\r\n\r\n    REQUIRE(output.Metadata->InstallerMetadataMap.size() == 1);\r\n    REQUIRE(output.Metadata->InstallerMetadataMap.count(input.InstallerHash.value()) == 1);\r\n    const auto& entry = output.Metadata->InstallerMetadataMap[input.InstallerHash.value()];\r\n    REQUIRE(entry.Scope.empty());\r\n}\r\n\r\nTEST_CASE(\"MetadataCollection_SameSubmission_SameInstaller_Scopes\", \"[metadata_collection]\")\r\n{\r\n    std::string version = \"1.3.5\";\r\n    std::string productCode = \"{guid}\";\r\n    Manifest::InstallerTypeEnum installerType = Manifest::InstallerTypeEnum::Msi;\r\n    std::string currentScope = GENERATE(std::string{},\r\n        Manifest::ScopeToString(Manifest::ScopeEnum::Unknown),\r\n        Manifest::ScopeToString(Manifest::ScopeEnum::User),\r\n        Manifest::ScopeToString(Manifest::ScopeEnum::Machine));\r\n    std::string newScope{ Manifest::ScopeToString(Manifest::ScopeEnum::User) };\r\n\r\n    INFO(currentScope);\r\n\r\n    TestInput input(MinimalDefaults, version, productCode, installerType);\r\n    input.SupportedMetadataVersion = \"1.1\";\r\n    input.CurrentMetadata->SchemaVersion = { \"1.1\" };\r\n    input.CurrentMetadata->InstallerMetadataMap.begin()->second.Scope = currentScope;\r\n    auto correlationData = std::make_unique<TestARPCorrelationData>();\r\n\r\n    Manifest::Manifest manifest;\r\n    manifest.DefaultLocalization.Add<Manifest::Localization::PackageName>(\"Different Language Name\");\r\n    // Same publisher\r\n    manifest.DefaultLocalization.Add<Manifest::Localization::Publisher>(input.CurrentMetadata->InstallerMetadataMap.begin()->second.AppsAndFeaturesEntries[0].Publisher);\r\n    manifest.Version = version;\r\n    manifest.Installers.push_back({});\r\n    manifest.Installers[0].ProductCode = productCode;\r\n\r\n    IPackageVersion::Metadata metadata;\r\n    metadata[PackageVersionMetadata::InstalledType] = Manifest::InstallerTypeToString(installerType);\r\n    metadata[PackageVersionMetadata::InstalledScope] = newScope;\r\n\r\n    correlationData->CorrelateForNewlyInstalledResult.Package = std::make_shared<TestPackageVersion>(manifest, metadata);\r\n\r\n    InstallerMetadataCollectionContext context = CreateTestContext(std::move(correlationData), input);\r\n    TestOutput output = GetOutput(context);\r\n\r\n    REQUIRE(output.IsSuccess());\r\n    output.ValidateFieldPresence();\r\n\r\n    REQUIRE(output.Metadata->InstallerMetadataMap.size() == 1);\r\n    REQUIRE(output.Metadata->InstallerMetadataMap.count(input.InstallerHash.value()) == 1);\r\n    const auto& entry = output.Metadata->InstallerMetadataMap[input.InstallerHash.value()];\r\n\r\n    if (currentScope.empty())\r\n    {\r\n        REQUIRE(entry.Scope == newScope);\r\n    }\r\n    else if (currentScope != newScope)\r\n    {\r\n        // If Unknown, should stay Unknown\r\n        // If different, should become Unknown\r\n        REQUIRE(entry.Scope == Manifest::ScopeToString(Manifest::ScopeEnum::Unknown));\r\n    }\r\n    else\r\n    {\r\n        // If same, should not change\r\n        REQUIRE(entry.Scope == currentScope);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"MetadataCollection_Merge_SameInstaller_Scopes\", \"[metadata_collection]\")\r\n{\r\n    TestMerge mergeData{ MinimalDefaults };\r\n    mergeData.Metadatas->emplace_back(MakeProductMetadata());\r\n\r\n    std::string currentScope = GENERATE(std::string{},\r\n        Manifest::ScopeToString(Manifest::ScopeEnum::Unknown),\r\n        Manifest::ScopeToString(Manifest::ScopeEnum::User),\r\n        Manifest::ScopeToString(Manifest::ScopeEnum::Machine));\r\n    std::string newScope{ Manifest::ScopeToString(Manifest::ScopeEnum::Machine) };\r\n\r\n    INFO(currentScope);\r\n\r\n    mergeData.Metadatas->at(0).SchemaVersion = { \"1.1\" };\r\n    mergeData.Metadatas->at(0).InstallerMetadataMap.begin()->second.Scope = currentScope;\r\n    mergeData.Metadatas->at(1).SchemaVersion = { \"1.1\" };\r\n    mergeData.Metadatas->at(1).InstallerMetadataMap.begin()->second.Scope = newScope;\r\n\r\n    std::wstring mergeResult = InstallerMetadataCollectionContext::Merge(mergeData.ToJSON(), 0, {});\r\n    REQUIRE(!mergeResult.empty());\r\n\r\n    ProductMetadata mergeMetadata;\r\n    mergeMetadata.FromJson(web::json::value::parse(mergeResult));\r\n\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.size() == 1);\r\n    for (const auto& item : mergeMetadata.InstallerMetadataMap)\r\n    {\r\n        if (currentScope.empty())\r\n        {\r\n            REQUIRE(item.second.Scope == newScope);\r\n        }\r\n        else if (currentScope != newScope)\r\n        {\r\n            // If Unknown, should stay Unknown\r\n            // If different, should become Unknown\r\n            REQUIRE(item.second.Scope == Manifest::ScopeToString(Manifest::ScopeEnum::Unknown));\r\n        }\r\n        else\r\n        {\r\n            // If same, should not change\r\n            REQUIRE(item.second.Scope == currentScope);\r\n        }\r\n    }\r\n}\r\n\r\nTEST_CASE(\"MetadataCollection_NewPackage_1_2\", \"[metadata_collection]\")\r\n{\r\n    TestInput input(MinimalDefaults);\r\n    input.SupportedMetadataVersion = \"1.2\";\r\n    auto correlationData = std::make_unique<TestARPCorrelationData>();\r\n    auto installedFilesData = std::make_unique<TestInstalledFilesCorrelation>();\r\n\r\n    Manifest::Manifest manifest;\r\n    manifest.DefaultLocalization.Add<Manifest::Localization::PackageName>(\"Test Package Name\");\r\n    manifest.DefaultLocalization.Add<Manifest::Localization::Publisher>(\"Test Publisher\");\r\n    manifest.Version = \"1.2.3\";\r\n    manifest.Installers.push_back({});\r\n    manifest.Installers[0].ProductCode = \"{guid}\";\r\n\r\n    IPackageVersion::Metadata metadata;\r\n    metadata[PackageVersionMetadata::InstalledType] = Manifest::InstallerTypeToString(Manifest::InstallerTypeEnum::Msi);\r\n    metadata[PackageVersionMetadata::InstalledScope] = Manifest::ScopeToString(Manifest::ScopeEnum::User);\r\n\r\n    correlationData->CorrelateForNewlyInstalledResult.Package = std::make_shared<TestPackageVersion>(manifest, metadata);\r\n\r\n    Correlation::InstallationMetadata installedFiles;\r\n    installedFiles.InstalledFiles.DefaultInstallLocation = \"%TEMP%\\\\TestApp\";\r\n    Manifest::InstalledFile installedFile;\r\n    installedFile.RelativeFilePath = \"test.exe\";\r\n    installedFile.FileSha256 = Utility::SHA256::ConvertToBytes(\"d2a45116709136462ee7a1c42f0e75f0efa258fe959b1504dc8ea4573451b759\");\r\n    installedFile.FileType = Manifest::InstalledFileTypeEnum::Launch;\r\n    installedFile.InvocationParameter = \"invocation\";\r\n    installedFile.DisplayName = \"name\";\r\n    installedFiles.InstalledFiles.Files.emplace_back(std::move(installedFile));\r\n    Correlation::InstalledStartupLinkFile startupLink;\r\n    startupLink.RelativeFilePath = \"TestApp.lnk\";\r\n    startupLink.FileType = Manifest::InstalledFileTypeEnum::Launch;\r\n    installedFiles.StartupLinkFiles.emplace_back(std::move(startupLink));\r\n\r\n    installedFilesData->InstallationMetadata = std::move(installedFiles);\r\n\r\n    std::vector<AppInstaller::Repository::ExtractedIconInfo> testIcons;\r\n    AppInstaller::Repository::ExtractedIconInfo iconInfo;\r\n    iconInfo.IconContent = Utility::SHA256::ConvertToBytes(\"d2a45116709136462ee7a1c42f0e75f0efa258fe959b1504dc8ea4573451b700\");\r\n    iconInfo.IconSha256 = Utility::SHA256::ConvertToBytes(\"d2a45116709136462ee7a1c42f0e75f0efa258fe959b1504dc8ea4573451b759\");\r\n    iconInfo.IconFileType = Manifest::IconFileTypeEnum::Ico;\r\n    iconInfo.IconResolution = Manifest::IconResolutionEnum::Custom;\r\n    iconInfo.IconTheme = Manifest::IconThemeEnum::Default;\r\n    testIcons.emplace_back(std::move(iconInfo));\r\n\r\n    TestHook::SetExtractIconFromArpEntryResult_Override iconsOverride{ testIcons };\r\n\r\n    InstallerMetadataCollectionContext context = CreateTestContext(std::move(correlationData), std::move(installedFilesData), input);\r\n    TestOutput output = GetOutput(context);\r\n\r\n    REQUIRE(output.IsSuccess());\r\n    output.ValidateFieldPresence();\r\n\r\n    REQUIRE(output.Metadata->ProductVersionMin.ToString() == output.Metadata->ProductVersionMax.ToString());\r\n    REQUIRE(output.Metadata->ProductVersionMin.ToString() == manifest.Version);\r\n    REQUIRE(output.Metadata->InstallerMetadataMap.size() == 1);\r\n    REQUIRE(output.Metadata->InstallerMetadataMap.count(input.InstallerHash.value()) == 1);\r\n    const auto& entry = output.Metadata->InstallerMetadataMap[input.InstallerHash.value()];\r\n    REQUIRE(entry.SubmissionIdentifier == input.SubmissionIdentifier.value());\r\n    REQUIRE(entry.Scope == metadata[PackageVersionMetadata::InstalledScope]);\r\n    REQUIRE(entry.AppsAndFeaturesEntries.size() == 1);\r\n    REQUIRE(entry.AppsAndFeaturesEntries[0].DisplayName == manifest.DefaultLocalization.Get<Manifest::Localization::PackageName>());\r\n    REQUIRE(entry.AppsAndFeaturesEntries[0].Publisher == manifest.DefaultLocalization.Get<Manifest::Localization::Publisher>());\r\n    REQUIRE(entry.AppsAndFeaturesEntries[0].DisplayVersion == manifest.Version);\r\n    REQUIRE(entry.AppsAndFeaturesEntries[0].ProductCode == manifest.Installers[0].ProductCode);\r\n    REQUIRE(entry.AppsAndFeaturesEntries[0].InstallerType == Manifest::InstallerTypeEnum::Msi);\r\n    REQUIRE(entry.InstalledFiles.has_value());\r\n    REQUIRE(entry.InstalledFiles->DefaultInstallLocation == \"%TEMP%\\\\TestApp\");\r\n    REQUIRE(entry.InstalledFiles->Files.size() == 1);\r\n    REQUIRE(entry.InstalledFiles->Files[0].RelativeFilePath == \"test.exe\");\r\n    REQUIRE(entry.InstalledFiles->Files[0].FileSha256 == Utility::SHA256::ConvertToBytes(\"d2a45116709136462ee7a1c42f0e75f0efa258fe959b1504dc8ea4573451b759\"));\r\n    REQUIRE(entry.InstalledFiles->Files[0].FileType == Manifest::InstalledFileTypeEnum::Launch);\r\n    REQUIRE(entry.InstalledFiles->Files[0].InvocationParameter == \"invocation\");\r\n    REQUIRE(entry.InstalledFiles->Files[0].DisplayName == \"name\");\r\n    REQUIRE(entry.StartupLinkFiles.has_value());\r\n    REQUIRE(entry.StartupLinkFiles->size() == 1);\r\n    REQUIRE(entry.StartupLinkFiles->at(0).RelativeFilePath == \"TestApp.lnk\");\r\n    REQUIRE(entry.StartupLinkFiles->at(0).FileType == Manifest::InstalledFileTypeEnum::Launch);\r\n    REQUIRE(entry.Icons.size() == 1);\r\n    REQUIRE(entry.Icons[0].IconContent == Utility::SHA256::ConvertToBytes(\"d2a45116709136462ee7a1c42f0e75f0efa258fe959b1504dc8ea4573451b700\"));\r\n    REQUIRE(entry.Icons[0].IconSha256 == Utility::SHA256::ConvertToBytes(\"d2a45116709136462ee7a1c42f0e75f0efa258fe959b1504dc8ea4573451b759\"));\r\n    REQUIRE(entry.Icons[0].IconFileType == Manifest::IconFileTypeEnum::Ico);\r\n    REQUIRE(entry.Icons[0].IconResolution == Manifest::IconResolutionEnum::Custom);\r\n    REQUIRE(entry.Icons[0].IconTheme == Manifest::IconThemeEnum::Default);\r\n    REQUIRE(output.Metadata->HistoricalMetadataList.empty());\r\n}\r\n\r\nTEST_CASE(\"MetadataCollection_NewPackage_NoInstallationMetadata_NoIcons\", \"[metadata_collection]\")\r\n{\r\n    TestInput input(MinimalDefaults);\r\n    input.SupportedMetadataVersion = \"1.2\";\r\n    auto correlationData = std::make_unique<TestARPCorrelationData>();\r\n\r\n    Manifest::Manifest manifest;\r\n    manifest.DefaultLocalization.Add<Manifest::Localization::PackageName>(\"Test Package Name\");\r\n    manifest.DefaultLocalization.Add<Manifest::Localization::Publisher>(\"Test Publisher\");\r\n    manifest.Version = \"1.2.3\";\r\n    manifest.Installers.push_back({});\r\n    manifest.Installers[0].ProductCode = \"{guid}\";\r\n\r\n    IPackageVersion::Metadata metadata;\r\n    metadata[PackageVersionMetadata::InstalledType] = Manifest::InstallerTypeToString(Manifest::InstallerTypeEnum::Msi);\r\n\r\n    correlationData->CorrelateForNewlyInstalledResult.Package = std::make_shared<TestPackageVersion>(manifest, metadata);\r\n\r\n    std::vector<AppInstaller::Repository::ExtractedIconInfo> testIcons;\r\n    TestHook::SetExtractIconFromArpEntryResult_Override iconsOverride{ testIcons };\r\n\r\n    InstallerMetadataCollectionContext context = CreateTestContext(std::move(correlationData), input);\r\n    TestOutput output = GetOutput(context);\r\n\r\n    REQUIRE(output.IsSuccess());\r\n    output.ValidateFieldPresence();\r\n\r\n    REQUIRE(output.Metadata->InstallerMetadataMap.size() == 1);\r\n    REQUIRE(output.Metadata->InstallerMetadataMap.count(input.InstallerHash.value()) == 1);\r\n    const auto& entry = output.Metadata->InstallerMetadataMap[input.InstallerHash.value()];\r\n    REQUIRE(entry.Scope.empty());\r\n    REQUIRE_FALSE(entry.InstalledFiles.has_value());\r\n    REQUIRE_FALSE(entry.StartupLinkFiles.has_value());\r\n    REQUIRE(entry.Icons.size() == 0);\r\n}\r\n\r\nTEST_CASE(\"MetadataCollection_SameSubmission_SameInstaller_InstallationMetadata_Icons\", \"[metadata_collection]\")\r\n{\r\n    std::string version = \"1.3.5\";\r\n    std::string productCode = \"{guid}\";\r\n    Manifest::InstallerTypeEnum installerType = Manifest::InstallerTypeEnum::Msi;\r\n\r\n    TestInput input(MinimalDefaults, version, productCode, installerType);\r\n    input.SupportedMetadataVersion = \"1.2\";\r\n    input.CurrentMetadata->SchemaVersion = { \"1.2\" };\r\n\r\n    Manifest::InstallationMetadataInfo installedFiles;\r\n    installedFiles.DefaultInstallLocation = \"%TEMP%\\\\TestApp\";\r\n    Manifest::InstalledFile installedFile;\r\n    installedFile.RelativeFilePath = \"test.exe\";\r\n    installedFile.FileSha256 = Utility::SHA256::ConvertToBytes(\"d2a45116709136462ee7a1c42f0e75f0efa258fe959b1504dc8ea4573451b759\");\r\n    installedFile.FileType = Manifest::InstalledFileTypeEnum::Launch;\r\n    installedFile.InvocationParameter = \"invocation\";\r\n    installedFile.DisplayName = \"name\";\r\n    installedFiles.Files.emplace_back(std::move(installedFile));\r\n    input.CurrentMetadata->InstallerMetadataMap.begin()->second.InstalledFiles = std::move(installedFiles);\r\n\r\n    std::vector<InstalledStartupLinkFile> startupLinkFiles;\r\n    Correlation::InstalledStartupLinkFile startupLink;\r\n    startupLink.RelativeFilePath = \"TestApp.lnk\";\r\n    startupLink.FileType = Manifest::InstalledFileTypeEnum::Launch;\r\n    startupLinkFiles.emplace_back(std::move(startupLink));\r\n    input.CurrentMetadata->InstallerMetadataMap.begin()->second.StartupLinkFiles = std::move(startupLinkFiles);\r\n\r\n    std::vector<AppInstaller::Repository::ExtractedIconInfo> testIcons;\r\n    AppInstaller::Repository::ExtractedIconInfo iconInfo;\r\n    iconInfo.IconContent = Utility::SHA256::ConvertToBytes(\"d2a45116709136462ee7a1c42f0e75f0efa258fe959b1504dc8ea4573451b700\");\r\n    iconInfo.IconSha256 = Utility::SHA256::ConvertToBytes(\"d2a45116709136462ee7a1c42f0e75f0efa258fe959b1504dc8ea4573451b759\");\r\n    iconInfo.IconFileType = Manifest::IconFileTypeEnum::Ico;\r\n    iconInfo.IconResolution = Manifest::IconResolutionEnum::Custom;\r\n    iconInfo.IconTheme = Manifest::IconThemeEnum::Default;\r\n    testIcons.emplace_back(std::move(iconInfo));\r\n    input.CurrentMetadata->InstallerMetadataMap.begin()->second.Icons = std::move(testIcons);\r\n\r\n    auto correlationData = std::make_unique<TestARPCorrelationData>();\r\n    auto installedFilesData = std::make_unique<TestInstalledFilesCorrelation>();\r\n\r\n    Manifest::Manifest manifest;\r\n    manifest.DefaultLocalization.Add<Manifest::Localization::PackageName>(\"Different Language Name\");\r\n    // Same publisher\r\n    manifest.DefaultLocalization.Add<Manifest::Localization::Publisher>(input.CurrentMetadata->InstallerMetadataMap.begin()->second.AppsAndFeaturesEntries[0].Publisher);\r\n    manifest.Version = version;\r\n    manifest.Installers.push_back({});\r\n    manifest.Installers[0].ProductCode = productCode;\r\n\r\n    IPackageVersion::Metadata metadata;\r\n    metadata[PackageVersionMetadata::InstalledType] = Manifest::InstallerTypeToString(installerType);\r\n\r\n    correlationData->CorrelateForNewlyInstalledResult.Package = std::make_shared<TestPackageVersion>(manifest, metadata);\r\n\r\n    Correlation::InstallationMetadata newInstalledFiles;\r\n    newInstalledFiles.InstalledFiles.DefaultInstallLocation = \"%TEMP%\\\\NewTestApp\";\r\n    Manifest::InstalledFile newInstalledFile;\r\n    newInstalledFile.RelativeFilePath = \"test.exe\";\r\n    newInstalledFile.FileSha256 = Utility::SHA256::ConvertToBytes(\"d2a45116709136462ee7a1c42f0e75f0efa258fe959b1504dc8ea4573451b759\");\r\n    newInstalledFile.FileType = Manifest::InstalledFileTypeEnum::Launch;\r\n    newInstalledFile.InvocationParameter = \"invocation\";\r\n    newInstalledFile.DisplayName = \"name\";\r\n    newInstalledFiles.InstalledFiles.Files.emplace_back(std::move(newInstalledFile));\r\n    Correlation::InstalledStartupLinkFile newStartupLink;\r\n    newStartupLink.RelativeFilePath = \"NewTestApp.lnk\";\r\n    newStartupLink.FileType = Manifest::InstalledFileTypeEnum::Launch;\r\n    newInstalledFiles.StartupLinkFiles.emplace_back(std::move(newStartupLink));\r\n\r\n    installedFilesData->InstallationMetadata = std::move(newInstalledFiles);\r\n\r\n    std::vector<AppInstaller::Repository::ExtractedIconInfo> newTestIcons;\r\n    AppInstaller::Repository::ExtractedIconInfo newIconInfo;\r\n    newIconInfo.IconContent = Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\");\r\n    newIconInfo.IconSha256 = Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df8499\");\r\n    newIconInfo.IconFileType = Manifest::IconFileTypeEnum::Jpeg;\r\n    newIconInfo.IconResolution = Manifest::IconResolutionEnum::Square16;\r\n    newIconInfo.IconTheme = Manifest::IconThemeEnum::Light;\r\n    newTestIcons.emplace_back(std::move(newIconInfo));\r\n\r\n    TestHook::SetExtractIconFromArpEntryResult_Override iconsOverride{ newTestIcons };\r\n\r\n    InstallerMetadataCollectionContext context = CreateTestContext(std::move(correlationData), std::move(installedFilesData), input);\r\n    TestOutput output = GetOutput(context);\r\n\r\n    REQUIRE(output.IsSuccess());\r\n    output.ValidateFieldPresence();\r\n\r\n    REQUIRE(output.Metadata->InstallerMetadataMap.size() == 1);\r\n    REQUIRE(output.Metadata->InstallerMetadataMap.count(input.InstallerHash.value()) == 1);\r\n    const auto& entry = output.Metadata->InstallerMetadataMap[input.InstallerHash.value()];\r\n\r\n    // Conflicting installed files entries get removed.\r\n    REQUIRE(entry.InstalledFiles.has_value());\r\n    REQUIRE_FALSE(entry.InstalledFiles->HasData());\r\n    // Non duplicate startup links get added.\r\n    REQUIRE(entry.StartupLinkFiles.has_value());\r\n    REQUIRE(entry.StartupLinkFiles->size() == 2);\r\n    // New detected icons always take over\r\n    REQUIRE(entry.Icons.size() == 1);\r\n    REQUIRE(entry.Icons[0].IconContent == Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\"));\r\n    REQUIRE(entry.Icons[0].IconSha256 == Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df8499\"));\r\n    REQUIRE(entry.Icons[0].IconFileType == Manifest::IconFileTypeEnum::Jpeg);\r\n    REQUIRE(entry.Icons[0].IconResolution == Manifest::IconResolutionEnum::Square16);\r\n    REQUIRE(entry.Icons[0].IconTheme == Manifest::IconThemeEnum::Light);\r\n}\r\n\r\nTEST_CASE(\"MetadataCollection_Merge_SameInstaller_InstalledFiles\", \"[metadata_collection]\")\r\n{\r\n    TestMerge mergeData{ MinimalDefaults };\r\n    mergeData.Metadatas->emplace_back(MakeProductMetadata());\r\n\r\n    Manifest::InstallationMetadataInfo installedFiles;\r\n    installedFiles.DefaultInstallLocation = \"%TEMP%\\\\TestApp\";\r\n    Manifest::InstalledFile installedFile;\r\n    installedFile.RelativeFilePath = \"test.exe\";\r\n    installedFile.FileSha256 = Utility::SHA256::ConvertToBytes(\"d2a45116709136462ee7a1c42f0e75f0efa258fe959b1504dc8ea4573451b759\");\r\n    installedFile.FileType = Manifest::InstalledFileTypeEnum::Launch;\r\n    installedFile.InvocationParameter = \"invocation\";\r\n    installedFile.DisplayName = \"name\";\r\n    installedFiles.Files.emplace_back(std::move(installedFile));\r\n\r\n    mergeData.Metadatas->at(0).SchemaVersion = { \"1.2\" };\r\n    mergeData.Metadatas->at(0).InstallerMetadataMap.begin()->second.InstalledFiles = installedFiles;\r\n\r\n    // Different default install location clears whole data\r\n    Manifest::InstallationMetadataInfo newInstalledFiles = installedFiles;\r\n    newInstalledFiles.DefaultInstallLocation = \"%TEMP%\\\\NewTestApp\";\r\n    mergeData.Metadatas->at(1).SchemaVersion = { \"1.2\" };\r\n\r\n    mergeData.Metadatas->at(1).InstallerMetadataMap.begin()->second.InstalledFiles = newInstalledFiles;\r\n    std::wstring mergeResult = InstallerMetadataCollectionContext::Merge(mergeData.ToJSON(), 0, {});\r\n    REQUIRE(!mergeResult.empty());\r\n\r\n    ProductMetadata mergeMetadata;\r\n    mergeMetadata.FromJson(web::json::value::parse(mergeResult));\r\n\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.size() == 1);\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.begin()->second.InstalledFiles.has_value());\r\n    REQUIRE_FALSE(mergeMetadata.InstallerMetadataMap.begin()->second.InstalledFiles->HasData());\r\n\r\n    // Different RelativeFilePath clears the file entry\r\n    Manifest::InstallationMetadataInfo newInstalledFiles2 = installedFiles;\r\n    newInstalledFiles2.Files[0].RelativeFilePath = \"test2.exe\";\r\n    mergeData.Metadatas->at(1).InstallerMetadataMap.begin()->second.InstalledFiles = newInstalledFiles2;\r\n    mergeResult = InstallerMetadataCollectionContext::Merge(mergeData.ToJSON(), 0, {});\r\n    REQUIRE(!mergeResult.empty());\r\n\r\n    mergeMetadata.FromJson(web::json::value::parse(mergeResult));\r\n\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.size() == 1);\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.begin()->second.InstalledFiles.has_value());\r\n    REQUIRE_FALSE(mergeMetadata.InstallerMetadataMap.begin()->second.InstalledFiles->DefaultInstallLocation.empty());\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.begin()->second.InstalledFiles->Files.empty());\r\n\r\n    // Different other fields clears the fields themselves\r\n    Manifest::InstallationMetadataInfo newInstalledFiles3 = installedFiles;\r\n    newInstalledFiles3.Files[0].DisplayName = \"name2\";\r\n    newInstalledFiles3.Files[0].FileSha256 = Utility::SHA256::ConvertToBytes(\"d2a45116709136462ee7a1c42f0e75f0efa258fe959b1504dc8ea4573451b756\");\r\n    newInstalledFiles3.Files[0].InvocationParameter = \"invocation2\";\r\n    newInstalledFiles3.Files[0].FileType = Manifest::InstalledFileTypeEnum::Uninstall;\r\n    mergeData.Metadatas->at(1).InstallerMetadataMap.begin()->second.InstalledFiles = newInstalledFiles3;\r\n    mergeResult = InstallerMetadataCollectionContext::Merge(mergeData.ToJSON(), 0, {});\r\n    REQUIRE(!mergeResult.empty());\r\n\r\n    mergeMetadata.FromJson(web::json::value::parse(mergeResult));\r\n\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.size() == 1);\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.begin()->second.InstalledFiles.has_value());\r\n    REQUIRE_FALSE(mergeMetadata.InstallerMetadataMap.begin()->second.InstalledFiles->DefaultInstallLocation.empty());\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.begin()->second.InstalledFiles->Files.size() == 1);\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.begin()->second.InstalledFiles->Files[0].RelativeFilePath == \"test.exe\");\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.begin()->second.InstalledFiles->Files[0].DisplayName == \"\");\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.begin()->second.InstalledFiles->Files[0].InvocationParameter == \"\");\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.begin()->second.InstalledFiles->Files[0].FileType == Manifest::InstalledFileTypeEnum::Unknown);\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.begin()->second.InstalledFiles->Files[0].FileSha256.empty());\r\n}\r\n\r\nTEST_CASE(\"MetadataCollection_Merge_SameInstaller_StartupLinkFiles\", \"[metadata_collection]\")\r\n{\r\n    TestMerge mergeData{ MinimalDefaults };\r\n    mergeData.Metadatas->emplace_back(MakeProductMetadata());\r\n\r\n    std::vector<InstalledStartupLinkFile> startupLinkFiles;\r\n    Correlation::InstalledStartupLinkFile startupLink;\r\n    startupLink.RelativeFilePath = \"TestApp.lnk\";\r\n    startupLink.FileType = Manifest::InstalledFileTypeEnum::Launch;\r\n    startupLinkFiles.emplace_back(std::move(startupLink));\r\n\r\n    mergeData.Metadatas->at(0).SchemaVersion = { \"1.2\" };\r\n    mergeData.Metadatas->at(0).InstallerMetadataMap.begin()->second.StartupLinkFiles = startupLinkFiles;\r\n\r\n    // Different relative file path gets added\r\n    std::vector<InstalledStartupLinkFile> newStartupLinkFiles = startupLinkFiles;\r\n    newStartupLinkFiles[0].RelativeFilePath = \"TestApp2.lnk\";\r\n\r\n    mergeData.Metadatas->at(1).SchemaVersion = { \"1.2\" };\r\n    mergeData.Metadatas->at(1).InstallerMetadataMap.begin()->second.StartupLinkFiles = newStartupLinkFiles;\r\n    std::wstring mergeResult = InstallerMetadataCollectionContext::Merge(mergeData.ToJSON(), 0, {});\r\n    REQUIRE(!mergeResult.empty());\r\n\r\n    ProductMetadata mergeMetadata;\r\n    mergeMetadata.FromJson(web::json::value::parse(mergeResult));\r\n\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.size() == 1);\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.begin()->second.StartupLinkFiles.has_value());\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.begin()->second.StartupLinkFiles->size() == 2);\r\n\r\n    // Different other fields clears the fields themselves\r\n    std::vector<InstalledStartupLinkFile> newStartupLinkFiles2 = startupLinkFiles;\r\n    newStartupLinkFiles2[0].FileType = Manifest::InstalledFileTypeEnum::Uninstall;\r\n    mergeData.Metadatas->at(1).InstallerMetadataMap.begin()->second.StartupLinkFiles = newStartupLinkFiles2;\r\n    mergeResult = InstallerMetadataCollectionContext::Merge(mergeData.ToJSON(), 0, {});\r\n    REQUIRE(!mergeResult.empty());\r\n\r\n    mergeMetadata.FromJson(web::json::value::parse(mergeResult));\r\n\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.size() == 1);\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.begin()->second.StartupLinkFiles.has_value());\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.begin()->second.StartupLinkFiles->size() == 1);\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.begin()->second.StartupLinkFiles->at(0).RelativeFilePath == \"TestApp.lnk\");\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.begin()->second.StartupLinkFiles->at(0).FileType == Manifest::InstalledFileTypeEnum::Unknown);\r\n}\r\n\r\nTEST_CASE(\"MetadataCollection_Merge_SameInstaller_Icons\", \"[metadata_collection]\")\r\n{\r\n    TestMerge mergeData{ MinimalDefaults };\r\n    mergeData.Metadatas->emplace_back(MakeProductMetadata());\r\n\r\n    std::vector<AppInstaller::Repository::ExtractedIconInfo> testIcons;\r\n    AppInstaller::Repository::ExtractedIconInfo iconInfo;\r\n    iconInfo.IconContent = Utility::SHA256::ConvertToBytes(\"d2a45116709136462ee7a1c42f0e75f0efa258fe959b1504dc8ea4573451b700\");\r\n    iconInfo.IconSha256 = Utility::SHA256::ConvertToBytes(\"d2a45116709136462ee7a1c42f0e75f0efa258fe959b1504dc8ea4573451b759\");\r\n    iconInfo.IconFileType = Manifest::IconFileTypeEnum::Ico;\r\n    iconInfo.IconResolution = Manifest::IconResolutionEnum::Custom;\r\n    iconInfo.IconTheme = Manifest::IconThemeEnum::Default;\r\n    testIcons.emplace_back(std::move(iconInfo));\r\n\r\n    mergeData.Metadatas->at(0).SchemaVersion = { \"1.2\" };\r\n    mergeData.Metadatas->at(0).InstallerMetadataMap.begin()->second.Icons = testIcons;\r\n\r\n    // Different test icons\r\n    std::vector<AppInstaller::Repository::ExtractedIconInfo> newTestIcons;\r\n    AppInstaller::Repository::ExtractedIconInfo newIconInfo;\r\n    newIconInfo.IconContent = Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\");\r\n    newIconInfo.IconSha256 = Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df8499\");\r\n    newIconInfo.IconFileType = Manifest::IconFileTypeEnum::Jpeg;\r\n    newIconInfo.IconResolution = Manifest::IconResolutionEnum::Square16;\r\n    newIconInfo.IconTheme = Manifest::IconThemeEnum::Light;\r\n    newTestIcons.emplace_back(std::move(newIconInfo));\r\n\r\n    mergeData.Metadatas->at(1).SchemaVersion = { \"1.2\" };\r\n    mergeData.Metadatas->at(1).InstallerMetadataMap.begin()->second.Icons = newTestIcons;\r\n    std::wstring mergeResult = InstallerMetadataCollectionContext::Merge(mergeData.ToJSON(), 0, {});\r\n    REQUIRE(!mergeResult.empty());\r\n\r\n    ProductMetadata mergeMetadata;\r\n    mergeMetadata.FromJson(web::json::value::parse(mergeResult));\r\n\r\n    // New data always take over\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.size() == 1);\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.begin()->second.Icons.size() == 1);\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.begin()->second.Icons[0].IconContent == Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\"));\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.begin()->second.Icons[0].IconSha256 == Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df8499\"));\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.begin()->second.Icons[0].IconFileType == Manifest::IconFileTypeEnum::Jpeg);\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.begin()->second.Icons[0].IconResolution == Manifest::IconResolutionEnum::Square16);\r\n    REQUIRE(mergeMetadata.InstallerMetadataMap.begin()->second.Icons[0].IconTheme == Manifest::IconThemeEnum::Light);\r\n}"
  },
  {
    "path": "src/AppInstallerCLITests/JsonHelper.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <winget/JsonUtil.h>\r\n#include \"cpprest/json.h\"\r\n\r\nusing namespace AppInstaller;\r\n\r\nweb::json::value GetTestJsonObject()\r\n{\r\n    web::json::value jsonObject = web::json::value::object();\r\n    jsonObject[L\"Key1\"] = web::json::value::string(L\"Value1\");\r\n    jsonObject[L\"Key2\"] = web::json::value::string(L\"Value2\");\r\n    jsonObject[L\"IntKey\"] = 100;\r\n\r\n    web::json::value arrayValue = web::json::value::array();\r\n    arrayValue[0] = web::json::value::string(L\"ArrayValue1\");\r\n    arrayValue[1] = web::json::value::string(L\"ArrayValue2\");\r\n    arrayValue[2] = web::json::value::string(L\"ArrayValue3\");\r\n    jsonObject[L\"Array\"] = arrayValue;\r\n\r\n    return jsonObject;\r\n}\r\n\r\nTEST_CASE(\"GetUtilityString\", \"[RestSource]\")\r\n{\r\n    REQUIRE(JSON::GetUtilityString(\"cpprest\") == L\"cpprest\");\r\n    REQUIRE(JSON::GetUtilityString(\"  \") == L\"  \");\r\n}\r\n\r\nTEST_CASE(\"GetJsonValueFromNode\", \"[RestSource]\")\r\n{\r\n    web::json::value jsonObject = GetTestJsonObject();\r\n    std::optional<std::reference_wrapper<const web::json::value>> actual = JSON::GetJsonValueFromNode(jsonObject, L\"Key1\");\r\n    REQUIRE(actual);\r\n    REQUIRE(actual.value().get().as_string() == L\"Value1\");\r\n\r\n    std::optional<std::reference_wrapper<const web::json::value>> absentKey = JSON::GetJsonValueFromNode(jsonObject, L\"Key3\");\r\n    REQUIRE(!absentKey);\r\n\r\n    web::json::value emptyObject;\r\n    std::optional<std::reference_wrapper<const web::json::value>> empty = JSON::GetJsonValueFromNode(emptyObject, L\"Key1\");\r\n    REQUIRE(!empty);\r\n}\r\n\r\nTEST_CASE(\"GetRawStringValueFromJsonValue\", \"[RestSource]\")\r\n{\r\n    std::optional<std::string> stringTest = JSON::GetRawStringValueFromJsonValue(web::json::value::string(L\"cpprest \"));\r\n    REQUIRE(stringTest);\r\n    REQUIRE(stringTest.value() == \"cpprest \");\r\n\r\n    std::optional<std::string> emptyTest = JSON::GetRawStringValueFromJsonValue(web::json::value::string(L\"   \"));\r\n    REQUIRE(emptyTest);\r\n    REQUIRE(emptyTest.value() == \"   \");\r\n\r\n    web::json::value obj;\r\n    std::optional<std::string> nullTest = JSON::GetRawStringValueFromJsonValue(obj);\r\n    REQUIRE(!nullTest);\r\n\r\n    web::json::value integer = 100;\r\n    std::optional<std::string> mismatchFieldTest = JSON::GetRawStringValueFromJsonValue(integer);\r\n    REQUIRE(!mismatchFieldTest);\r\n}\r\n\r\nTEST_CASE(\"GetRawStringValueFromJsonNode\", \"[RestSource]\")\r\n{\r\n    web::json::value jsonObject = GetTestJsonObject();\r\n\r\n    std::optional<std::string> stringTest = JSON::GetRawStringValueFromJsonNode(jsonObject, L\"Key1\");\r\n    REQUIRE(stringTest);\r\n    REQUIRE(stringTest.value() == \"Value1\");\r\n\r\n    std::optional<std::string> emptyTest = JSON::GetRawStringValueFromJsonNode(jsonObject, L\"Key3\");\r\n    REQUIRE(!emptyTest);\r\n\r\n    std::optional<std::string> mismatchFieldTest = JSON::GetRawStringValueFromJsonNode(jsonObject, L\"IntKey\");\r\n    REQUIRE(!mismatchFieldTest);\r\n}\r\n\r\nTEST_CASE(\"GetRawIntValueFromJsonValue\", \"[RestSource]\")\r\n{\r\n    web::json::value jsonObject = 100;\r\n    std::optional<int> expected = JSON::GetRawIntValueFromJsonValue(jsonObject);\r\n    REQUIRE(expected);\r\n    REQUIRE(expected.value() == 100);\r\n\r\n    std::optional<int> mismatchFieldTest = JSON::GetRawIntValueFromJsonValue(web::json::value::string(L\"cpprest\"));\r\n    REQUIRE(!mismatchFieldTest);\r\n}\r\n\r\nTEST_CASE(\"GetRawJsonArrayFromJsonNode\", \"[RestSource]\")\r\n{\r\n    web::json::value jsonObject = GetTestJsonObject();\r\n    std::optional<std::reference_wrapper<const web::json::array>> expected = JSON::GetRawJsonArrayFromJsonNode(jsonObject, L\"Array\");\r\n    REQUIRE(expected);\r\n    REQUIRE(expected.value().get().size() == 3);\r\n    REQUIRE(expected.value().get().at(0).as_string() == L\"ArrayValue1\");\r\n\r\n    std::optional<std::reference_wrapper<const web::json::array>> mismatchFieldTest = JSON::GetRawJsonArrayFromJsonNode(jsonObject, L\"Keyword\");\r\n    REQUIRE(!mismatchFieldTest);\r\n}\r\n\r\nTEST_CASE(\"GetRawStringArrayFromJsonNode\", \"[RestSource]\")\r\n{\r\n    web::json::value jsonObject = GetTestJsonObject();\r\n    std::vector<std::string> expected = JSON::GetRawStringArrayFromJsonNode(jsonObject, L\"Array\");\r\n    REQUIRE(expected.size() == 3);\r\n    REQUIRE(expected[0] == \"ArrayValue1\");\r\n\r\n    std::vector<std::string> mismatchFieldTest = JSON::GetRawStringArrayFromJsonNode(jsonObject, L\"Keyword\");\r\n    REQUIRE(mismatchFieldTest.size() == 0);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/LanguageUtilities.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <AppInstallerLanguageUtilities.h>\r\n\r\nusing namespace AppInstaller;\r\n\r\n\r\nTEST_CASE(\"DestructionToken\", \"[langutil]\")\r\n{\r\n    DestructionToken beginToken = true;\r\n    DestructionToken endToken = false;\r\n\r\n    REQUIRE(beginToken);\r\n    REQUIRE(!endToken);\r\n\r\n    endToken = std::move(beginToken);\r\n\r\n    REQUIRE(!beginToken);\r\n    REQUIRE(endToken);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/MSStoreDownloadFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestHooks.h\"\r\n#include \"TestRestRequestHandler.h\"\r\n#include \"WorkflowCommon.h\"\r\n#include <AppInstallerStrings.h>\r\n#include <AppInstallerSHA256.h>\r\n#include <winget/JsonUtil.h>\r\n#include <Commands/DownloadCommand.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::CLI;\r\nusing namespace AppInstaller::CLI::Execution;\r\nusing namespace AppInstaller::Settings;\r\nusing namespace AppInstaller::Utility::literals;\r\n\r\nutility::string_t TestDisplayCatalogResponse = _XPLATSTR(\r\n    R\"delimiter(\r\n    {\r\n      \"Product\": {\r\n        \"DisplaySkuAvailabilities\": [\r\n          {\r\n            \"Sku\": {\r\n              \"SkuId\": \"0015\",\r\n              \"Properties\": {\r\n                \"Packages\": [\r\n                  {\r\n                    \"PackageId\": \"PackageEnglish\",\r\n                    \"Architectures\": [ \"x64\", \"arm\" ],\r\n                    \"Languages\": [ \"en-US\", \"en-GB\" ],\r\n                    \"PackageFormat\": \"Appx\",\r\n                    \"ContentId\": \"LicenseContentId\",\r\n                    \"FulfillmentData\": {\r\n                      \"WuCategoryId\": \"TestCategoryIdEnglish\"\r\n                    }\r\n                  },\r\n                  {\r\n                    \"PackageId\": \"PackageFrench\",\r\n                    \"Architectures\": [ \"x64\", \"arm\" ],\r\n                    \"Languages\": [ \"fr-FR\" ],\r\n                    \"PackageFormat\": \"Appx\",\r\n                    \"ContentId\": \"LicenseContentId\",\r\n                    \"FulfillmentData\": {\r\n                      \"WuCategoryId\": \"TestCategoryIdFrench\"\r\n                    }\r\n                  }\r\n                ]\r\n              }\r\n            }\r\n          }\r\n        ]\r\n      }\r\n    })delimiter\");\r\n\r\nutility::string_t TestLicensingResponseRaw = _XPLATSTR(\r\n    R\"delimiter(\r\n    {\r\n      \"license\": {\r\n        \"keys\": [\r\n          {\r\n            \"value\": \"<LicenseContent>\"\r\n          }\r\n        ]\r\n      }\r\n    })delimiter\");\r\n\r\nstd::string LicenseContent = \"TestLicense\";\r\n\r\nutility::string_t TestLicensingResponse = AppInstaller::Utility::ReplaceWhileCopying(\r\n    TestLicensingResponseRaw, L\"<LicenseContent>\",\r\n    AppInstaller::Utility::ConvertToUTF16(AppInstaller::JSON::Base64Encode(std::vector<BYTE>{ LicenseContent.begin(), LicenseContent.end() })));\r\n\r\nutility::string_t TestDisplayCatalogResponse_TargetSkuNotFound = _XPLATSTR(\r\n    R\"delimiter(\r\n    {\r\n      \"Product\": {\r\n        \"DisplaySkuAvailabilities\": [\r\n          {\r\n            \"Sku\": {\r\n              \"SkuId\": \"0011\",\r\n              \"Properties\": {\r\n                \"Packages\": [\r\n                  {\r\n                    \"PackageId\": \"PackageEnglish\",\r\n                    \"Architectures\": [ \"x64\", \"arm\" ],\r\n                    \"Languages\": [ \"en-US\", \"en-GB\" ],\r\n                    \"PackageFormat\": \"Appx\",\r\n                    \"ContentId\": \"LicenseContentId\",\r\n                    \"FulfillmentData\": {\r\n                      \"WuCategoryId\": \"TestCategoryIdEnglish\"\r\n                    }\r\n                  }\r\n                ]\r\n              }\r\n            }\r\n          }\r\n        ]\r\n      }\r\n    })delimiter\");\r\n\r\nstd::vector<SFS::AppContent> GetSfsAppContentsOverrideFunction(std::string_view wuCategoryId)\r\n{\r\n    std::string wuCategoryIdStr{ wuCategoryId };\r\n\r\n    std::vector<SFS::AppContent> result;\r\n\r\n    std::unique_ptr<SFS::ContentId> contentId;\r\n    std::vector<SFS::AppPrerequisiteContent> dependencies;\r\n    std::vector<SFS::AppFile> packages;\r\n    std::unique_ptr<SFS::AppContent> appContent;\r\n\r\n    std::vector<BYTE> sha256Bytes = AppInstaller::Utility::SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798223CD4FEBAB1D734A07C2E51E56A28E0DF8123\");\r\n    std::string base64EncodedSha256 = AppInstaller::JSON::Base64Encode(sha256Bytes);\r\n\r\n    {\r\n        // Create dependencies content\r\n        std::unique_ptr<SFS::ContentId> dependencyContentId;\r\n        std::vector<SFS::AppFile> dependencyPackages;\r\n        std::unique_ptr<SFS::AppPrerequisiteContent> dependencyContent;\r\n\r\n        std::ignore = SFS::ContentId::Make(\"testDependency\", \"testDependency\", \"1.0.0.0\", dependencyContentId);\r\n\r\n        std::unique_ptr<SFS::AppFile> dependencyX64;\r\n        std::ignore = SFS::AppFile::Make(\r\n            wuCategoryIdStr + \".appx\",\r\n            \"https://NotUsed/\" + wuCategoryIdStr + \"/dependency/x64\",\r\n            100,\r\n            { { SFS::HashType::Sha256, base64EncodedSha256 } },\r\n            { SFS::Architecture::Amd64 },\r\n            { \"Universal=10.0.0.0\" },\r\n            wuCategoryIdStr + \".Dependency_1.2.3.4_x64__8wekyb3d8bbwe\",\r\n            dependencyX64);\r\n        dependencyPackages.emplace_back(std::move(*dependencyX64));\r\n\r\n        // Lower target OS dependency\r\n        std::unique_ptr<SFS::AppFile> dependencyX64_lower;\r\n        std::ignore = SFS::AppFile::Make(\r\n            wuCategoryIdStr + \".appx\",\r\n            \"https://NotUsed/\" + wuCategoryIdStr + \"/dependency/x64\",\r\n            100,\r\n            { { SFS::HashType::Sha256, base64EncodedSha256 } },\r\n            { SFS::Architecture::Amd64 },\r\n            { \"Universal=9.0.0.0\" },\r\n            wuCategoryIdStr + \".Dependency_0.9.3.4_x64__8wekyb3d8bbwe\",\r\n            dependencyX64_lower);\r\n        dependencyPackages.emplace_back(std::move(*dependencyX64_lower));\r\n\r\n        std::unique_ptr<SFS::AppFile> dependencyArm;\r\n        std::ignore = SFS::AppFile::Make(\r\n            wuCategoryIdStr + \".appx\",\r\n            \"https://NotUsed/\" + wuCategoryIdStr + \"/dependency/arm\",\r\n            100,\r\n            { { SFS::HashType::Sha256, base64EncodedSha256 } },\r\n            { SFS::Architecture::Arm },\r\n            { \"Universal=10.0.0.0\" },\r\n            wuCategoryIdStr + \".Dependency_1.2.3.4_arm__8wekyb3d8bbwe\",\r\n            dependencyArm);\r\n        dependencyPackages.emplace_back(std::move(*dependencyArm));\r\n\r\n        std::ignore = SFS::AppPrerequisiteContent::Make(std::move(dependencyContentId), std::move(dependencyPackages), dependencyContent);\r\n\r\n        dependencies.emplace_back(std::move(*dependencyContent));\r\n    }\r\n\r\n    {\r\n        // Create main packages\r\n\r\n        // Good candidate x64\r\n        std::unique_ptr<SFS::AppFile> packageX64;\r\n        std::ignore = SFS::AppFile::Make(\r\n            wuCategoryIdStr + \".appx\",\r\n            \"https://NotUsed/\" + wuCategoryIdStr + \"/x64\",\r\n            100,\r\n            { { SFS::HashType::Sha256, base64EncodedSha256 } },\r\n            { SFS::Architecture::Amd64 },\r\n            { \"Desktop=10.0.0.0\" },\r\n            wuCategoryIdStr + \"_1.0.0.0_x64__8wekyb3d8bbwe\",\r\n            packageX64);\r\n        packages.emplace_back(std::move(*packageX64));\r\n\r\n        // Good candidate x64, lower minimum OS version, lower package version\r\n        std::unique_ptr<SFS::AppFile> packageX64_lower;\r\n        std::ignore = SFS::AppFile::Make(\r\n            wuCategoryIdStr + \".appx\",\r\n            \"https://NotUsed/\" + wuCategoryIdStr + \"/x64\",\r\n            100,\r\n            { { SFS::HashType::Sha256, base64EncodedSha256 } },\r\n            { SFS::Architecture::Amd64 },\r\n            { \"Desktop=9.0.0.0\" },\r\n            wuCategoryIdStr + \"_0.9.0.0_x64__8wekyb3d8bbwe\",\r\n            packageX64_lower);\r\n        packages.emplace_back(std::move(*packageX64_lower));\r\n\r\n        // Good candidate arm\r\n        std::unique_ptr<SFS::AppFile> packageArm;\r\n        std::ignore = SFS::AppFile::Make(\r\n            wuCategoryIdStr + \".appx\",\r\n            \"https://NotUsed/\" + wuCategoryIdStr + \"/arm\",\r\n            100,\r\n            { { SFS::HashType::Sha256, base64EncodedSha256 } },\r\n            { SFS::Architecture::Arm },\r\n            { \"Desktop=10.0.0.0\" },\r\n            wuCategoryIdStr + \"_1.0.0.0_arm__8wekyb3d8bbwe\",\r\n            packageArm);\r\n        packages.emplace_back(std::move(*packageArm));\r\n\r\n        // Good candidate IoT\r\n        std::unique_ptr<SFS::AppFile> packageIoT;\r\n        std::ignore = SFS::AppFile::Make(\r\n            wuCategoryIdStr + \".appx\",\r\n            \"https://NotUsed/\" + wuCategoryIdStr + \"/IoT/arm\",\r\n            100,\r\n            { { SFS::HashType::Sha256, base64EncodedSha256 } },\r\n            { SFS::Architecture::Arm },\r\n            { \"IoT=10.0.0.0\" },\r\n            wuCategoryIdStr + \".IoT_1.0.0.0_arm__8wekyb3d8bbwe\",\r\n            packageIoT);\r\n        packages.emplace_back(std::move(*packageIoT));\r\n\r\n        // Good candidate IoT has newer version\r\n        std::unique_ptr<SFS::AppFile> packageIoT2;\r\n        std::ignore = SFS::AppFile::Make(\r\n            wuCategoryIdStr + \".appx\",\r\n            \"https://NotUsed/\" + wuCategoryIdStr + \"/IoT/arm/2.0\",\r\n            100,\r\n            { { SFS::HashType::Sha256, base64EncodedSha256 } },\r\n            { SFS::Architecture::Arm },\r\n            { \"IoT=10.0.0.0\" },\r\n            wuCategoryIdStr + \".IoT_2.0.0.0_arm__8wekyb3d8bbwe\",\r\n            packageIoT2);\r\n        packages.emplace_back(std::move(*packageIoT2));\r\n\r\n        // Candidate unsupported platform\r\n        std::unique_ptr<SFS::AppFile> packageXbox;\r\n        std::ignore = SFS::AppFile::Make(\r\n            wuCategoryIdStr + \".appx\",\r\n            \"https://NotUsed/\" + wuCategoryIdStr + \"/Xbox/arm\",\r\n            100,\r\n            { { SFS::HashType::Sha256, base64EncodedSha256 } },\r\n            { SFS::Architecture::Arm },\r\n            { \"Xbox=10.0.0.0\" },\r\n            wuCategoryIdStr + \".Xbox_1.0.0.0_arm__8wekyb3d8bbwe\",\r\n            packageXbox);\r\n        packages.emplace_back(std::move(*packageXbox));\r\n\r\n        // Candidate unsupported filetype\r\n        std::unique_ptr<SFS::AppFile> packageData;\r\n        std::ignore = SFS::AppFile::Make(\r\n            wuCategoryIdStr + \".cab\",\r\n            \"https://NotUsed/\" + wuCategoryIdStr + \"/cab\",\r\n            100,\r\n            { { SFS::HashType::Sha256, base64EncodedSha256 } },\r\n            { SFS::Architecture::Arm },\r\n            { \"Desktop=10.0.0.0\" },\r\n            wuCategoryIdStr + \".Data_1.0.0.0_arm__8wekyb3d8bbwe\",\r\n            packageData);\r\n        packages.emplace_back(std::move(*packageData));\r\n    }\r\n\r\n    std::ignore = SFS::ContentId::Make(\"test\", \"test\", \"1.0.0.0\", contentId);\r\n    std::ignore = SFS::AppContent::Make(std::move(contentId), \"updateId\", std::move(dependencies), std::move(packages), appContent);\r\n\r\n    result.emplace_back(std::move(*appContent));\r\n\r\n    return result;\r\n}\r\n\r\nTEST_CASE(\"MSStoreDownloadFlow_Success\", \"[MSStoreDownloadFlow][workflow]\")\r\n{\r\n    TestCommon::TempDirectory tempDirectory(\"TestDownloadDirectory\", false);\r\n\r\n    std::ostringstream downloadOutput;\r\n    TestContext context{ downloadOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideDownloadInstallerFileForMSStoreDownload(context);\r\n    TestHook::SetDisplayCatalogHttpPipelineStage_Override displayCatalogOverride(GetTestRestRequestHandler(web::http::status_codes::OK, TestDisplayCatalogResponse));\r\n    TestHook::SetSfsClientAppContents_Override sfsClientOverride({ &GetSfsAppContentsOverrideFunction });\r\n    TestHook::SetLicensingHttpPipelineStage_Override licensingOverride(GetTestRestRequestHandler(web::http::status_codes::OK, TestLicensingResponse));\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"DownloadFlowTest_MSStore.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::DownloadDirectory, tempDirectory);\r\n    context.Args.AddArg(Execution::Args::Type::Locale, \"en-US\"sv);\r\n\r\n    DownloadCommand download({});\r\n    download.Execute(context);\r\n    REQUIRE(context.GetTerminationHR() == S_OK);\r\n    INFO(downloadOutput.str());\r\n\r\n    // Verify downloaded files\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath()));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"Dependencies\"));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"Dependencies\" / L\"TestCategoryIdEnglish.Dependency_1.2.3.4_Universal_X64.appx\"));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"Dependencies\" / L\"TestCategoryIdEnglish.Dependency_1.2.3.4_Universal_Arm.appx\"));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"TestCategoryIdEnglish_1.0.0.0_Desktop_X64.appx\"));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"TestCategoryIdEnglish_1.0.0.0_Desktop_Arm.appx\"));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"TestCategoryIdEnglish.IoT_2.0.0.0_IoT_Arm.appx\"));\r\n\r\n    // Verify license\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"9WZDNCRFJ364_License.xml\"));\r\n    std::ifstream licenseFile(tempDirectory.GetPath() / L\"9WZDNCRFJ364_License.xml\");\r\n    REQUIRE(licenseFile.is_open());\r\n    std::string licenseFileStr;\r\n    std::getline(licenseFile, licenseFileStr);\r\n    REQUIRE(licenseFileStr == LicenseContent);\r\n\r\n    // Verify unsupported packages filtered out\r\n    REQUIRE_FALSE(std::filesystem::exists(tempDirectory.GetPath() / L\"TestCategoryIdEnglish.IoT_1.0.0.0_IoT_Arm.appx\"));\r\n    REQUIRE_FALSE(std::filesystem::exists(tempDirectory.GetPath() / L\"TestCategoryIdEnglish.Xbox_1.0.0.0_Xbox_Arm.appx\"));\r\n    REQUIRE_FALSE(std::filesystem::exists(tempDirectory.GetPath() / L\"TestCategoryIdEnglish.Data_1.0.0.0_Desktop_Arm.cab\"));\r\n}\r\n\r\nTEST_CASE(\"MSStoreDownloadFlow_Success_SkipDependencies\", \"[MSStoreDownloadFlow][workflow]\")\r\n{\r\n    TestCommon::TempDirectory tempDirectory(\"TestDownloadDirectory\", false);\r\n\r\n    std::ostringstream downloadOutput;\r\n    TestContext context{ downloadOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideDownloadInstallerFileForMSStoreDownload(context);\r\n    TestHook::SetDisplayCatalogHttpPipelineStage_Override displayCatalogOverride(GetTestRestRequestHandler(web::http::status_codes::OK, TestDisplayCatalogResponse));\r\n    TestHook::SetSfsClientAppContents_Override sfsClientOverride({ &GetSfsAppContentsOverrideFunction });\r\n    TestHook::SetLicensingHttpPipelineStage_Override licensingOverride(GetTestRestRequestHandler(web::http::status_codes::OK, TestLicensingResponse));\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"DownloadFlowTest_MSStore.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::DownloadDirectory, tempDirectory);\r\n    context.Args.AddArg(Execution::Args::Type::Locale, \"en-US\"sv);\r\n    context.Args.AddArg(Execution::Args::Type::SkipDependencies);\r\n\r\n    DownloadCommand download({});\r\n    download.Execute(context);\r\n    REQUIRE(context.GetTerminationHR() == S_OK);\r\n    INFO(downloadOutput.str());\r\n\r\n    // Verify downloaded files\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath()));\r\n    REQUIRE_FALSE(std::filesystem::exists(tempDirectory.GetPath() / L\"Dependencies\"));\r\n    REQUIRE_FALSE(std::filesystem::exists(tempDirectory.GetPath() / L\"Dependencies\" / L\"TestCategoryIdEnglish.Dependency_1.2.3.4_Universal_X64.appx\"));\r\n    REQUIRE_FALSE(std::filesystem::exists(tempDirectory.GetPath() / L\"Dependencies\" / L\"TestCategoryIdEnglish.Dependency_1.2.3.4_Universal_Arm.appx\"));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"TestCategoryIdEnglish_1.0.0.0_Desktop_X64.appx\"));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"TestCategoryIdEnglish_1.0.0.0_Desktop_Arm.appx\"));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"TestCategoryIdEnglish.IoT_2.0.0.0_IoT_Arm.appx\"));\r\n\r\n    // Verify license\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"9WZDNCRFJ364_License.xml\"));\r\n    std::ifstream licenseFile(tempDirectory.GetPath() / L\"9WZDNCRFJ364_License.xml\");\r\n    REQUIRE(licenseFile.is_open());\r\n    std::string licenseFileStr;\r\n    std::getline(licenseFile, licenseFileStr);\r\n    REQUIRE(licenseFileStr == LicenseContent);\r\n}\r\n\r\nTEST_CASE(\"MSStoreDownloadFlow_Success_SkipLicense\", \"[MSStoreDownloadFlow][workflow]\")\r\n{\r\n    TestCommon::TempDirectory tempDirectory(\"TestDownloadDirectory\", false);\r\n\r\n    std::ostringstream downloadOutput;\r\n    TestContext context{ downloadOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideDownloadInstallerFileForMSStoreDownload(context);\r\n    TestHook::SetDisplayCatalogHttpPipelineStage_Override displayCatalogOverride(GetTestRestRequestHandler(web::http::status_codes::OK, TestDisplayCatalogResponse));\r\n    TestHook::SetSfsClientAppContents_Override sfsClientOverride({ &GetSfsAppContentsOverrideFunction });\r\n    TestHook::SetLicensingHttpPipelineStage_Override licensingOverride(GetTestRestRequestHandler(web::http::status_codes::OK, TestLicensingResponse));\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"DownloadFlowTest_MSStore.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::DownloadDirectory, tempDirectory);\r\n    context.Args.AddArg(Execution::Args::Type::Locale, \"en-US\"sv);\r\n    context.Args.AddArg(Execution::Args::Type::SkipMicrosoftStorePackageLicense);\r\n\r\n    DownloadCommand download({});\r\n    download.Execute(context);\r\n    REQUIRE(context.GetTerminationHR() == S_OK);\r\n    INFO(downloadOutput.str());\r\n\r\n    // Verify downloaded files\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath()));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"Dependencies\"));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"Dependencies\" / L\"TestCategoryIdEnglish.Dependency_1.2.3.4_Universal_X64.appx\"));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"Dependencies\" / L\"TestCategoryIdEnglish.Dependency_1.2.3.4_Universal_Arm.appx\"));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"TestCategoryIdEnglish_1.0.0.0_Desktop_X64.appx\"));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"TestCategoryIdEnglish_1.0.0.0_Desktop_Arm.appx\"));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"TestCategoryIdEnglish.IoT_2.0.0.0_IoT_Arm.appx\"));\r\n\r\n    // Verify license\r\n    REQUIRE_FALSE(std::filesystem::exists(tempDirectory.GetPath() / L\"9WZDNCRFJ364_License.xml\"));\r\n}\r\n\r\nTEST_CASE(\"MSStoreDownloadFlow_Success_SpecificLocale\", \"[MSStoreDownloadFlow][workflow]\")\r\n{\r\n    TestCommon::TempDirectory tempDirectory(\"TestDownloadDirectory\", false);\r\n\r\n    std::ostringstream downloadOutput;\r\n    TestContext context{ downloadOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideDownloadInstallerFileForMSStoreDownload(context);\r\n    TestHook::SetDisplayCatalogHttpPipelineStage_Override displayCatalogOverride(GetTestRestRequestHandler(web::http::status_codes::OK, TestDisplayCatalogResponse));\r\n    TestHook::SetSfsClientAppContents_Override sfsClientOverride({ &GetSfsAppContentsOverrideFunction });\r\n    TestHook::SetLicensingHttpPipelineStage_Override licensingOverride(GetTestRestRequestHandler(web::http::status_codes::OK, TestLicensingResponse));\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"DownloadFlowTest_MSStore.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::DownloadDirectory, tempDirectory);\r\n    context.Args.AddArg(Execution::Args::Type::Locale, \"fr-FR\"sv);\r\n\r\n    DownloadCommand download({});\r\n    download.Execute(context);\r\n    REQUIRE(context.GetTerminationHR() == S_OK);\r\n    INFO(downloadOutput.str());\r\n\r\n    // Verify downloaded files\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath()));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"Dependencies\"));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"Dependencies\" / L\"TestCategoryIdFrench.Dependency_1.2.3.4_Universal_X64.appx\"));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"Dependencies\" / L\"TestCategoryIdFrench.Dependency_1.2.3.4_Universal_Arm.appx\"));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"TestCategoryIdFrench_1.0.0.0_Desktop_X64.appx\"));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"TestCategoryIdFrench_1.0.0.0_Desktop_Arm.appx\"));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"TestCategoryIdFrench.IoT_2.0.0.0_IoT_Arm.appx\"));\r\n\r\n    // Verify license\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"9WZDNCRFJ364_License.xml\"));\r\n    std::ifstream licenseFile(tempDirectory.GetPath() / L\"9WZDNCRFJ364_License.xml\");\r\n    REQUIRE(licenseFile.is_open());\r\n    std::string licenseFileStr;\r\n    std::getline(licenseFile, licenseFileStr);\r\n    REQUIRE(licenseFileStr == LicenseContent);\r\n}\r\n\r\nTEST_CASE(\"MSStoreDownloadFlow_Success_SpecificArchitecture\", \"[MSStoreDownloadFlow][workflow]\")\r\n{\r\n    TestCommon::TempDirectory tempDirectory(\"TestDownloadDirectory\", false);\r\n\r\n    std::ostringstream downloadOutput;\r\n    TestContext context{ downloadOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideDownloadInstallerFileForMSStoreDownload(context);\r\n    TestHook::SetDisplayCatalogHttpPipelineStage_Override displayCatalogOverride(GetTestRestRequestHandler(web::http::status_codes::OK, TestDisplayCatalogResponse));\r\n    TestHook::SetSfsClientAppContents_Override sfsClientOverride({ &GetSfsAppContentsOverrideFunction });\r\n    TestHook::SetLicensingHttpPipelineStage_Override licensingOverride(GetTestRestRequestHandler(web::http::status_codes::OK, TestLicensingResponse));\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"DownloadFlowTest_MSStore.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::DownloadDirectory, tempDirectory);\r\n    context.Args.AddArg(Execution::Args::Type::Locale, \"en-US\"sv);\r\n    context.Args.AddArg(Execution::Args::Type::InstallerArchitecture, \"x64\"sv);\r\n\r\n    DownloadCommand download({});\r\n    download.Execute(context);\r\n    REQUIRE(context.GetTerminationHR() == S_OK);\r\n    INFO(downloadOutput.str());\r\n\r\n    // Verify downloaded files\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath()));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"Dependencies\"));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"Dependencies\" / L\"TestCategoryIdEnglish.Dependency_1.2.3.4_Universal_x64.appx\"));\r\n    REQUIRE_FALSE(std::filesystem::exists(tempDirectory.GetPath() / L\"Dependencies\" / L\"TestCategoryIdEnglish.Dependency_1.2.3.4_Universal_Arm.appx\"));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"TestCategoryIdEnglish_1.0.0.0_Desktop_X64.appx\"));\r\n    REQUIRE_FALSE(std::filesystem::exists(tempDirectory.GetPath() / L\"TestCategoryIdEnglish_1.0.0.0_Desktop_Arm.appx\"));\r\n    REQUIRE_FALSE(std::filesystem::exists(tempDirectory.GetPath() / L\"TestCategoryIdEnglish.IoT_2.0.0.0_IoT_Arm.appx\"));\r\n\r\n    // Verify license\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"9WZDNCRFJ364_License.xml\"));\r\n    std::ifstream licenseFile(tempDirectory.GetPath() / L\"9WZDNCRFJ364_License.xml\");\r\n    REQUIRE(licenseFile.is_open());\r\n    std::string licenseFileStr;\r\n    std::getline(licenseFile, licenseFileStr);\r\n    REQUIRE(licenseFileStr == LicenseContent);\r\n}\r\n\r\nTEST_CASE(\"MSStoreDownloadFlow_Success_SpecificPlatform\", \"[MSStoreDownloadFlow][workflow]\")\r\n{\r\n    TestCommon::TempDirectory tempDirectory(\"TestDownloadDirectory\", false);\r\n\r\n    std::ostringstream downloadOutput;\r\n    TestContext context{ downloadOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideDownloadInstallerFileForMSStoreDownload(context);\r\n    TestHook::SetDisplayCatalogHttpPipelineStage_Override displayCatalogOverride(GetTestRestRequestHandler(web::http::status_codes::OK, TestDisplayCatalogResponse));\r\n    TestHook::SetSfsClientAppContents_Override sfsClientOverride({ &GetSfsAppContentsOverrideFunction });\r\n    TestHook::SetLicensingHttpPipelineStage_Override licensingOverride(GetTestRestRequestHandler(web::http::status_codes::OK, TestLicensingResponse));\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"DownloadFlowTest_MSStore.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::DownloadDirectory, tempDirectory);\r\n    context.Args.AddArg(Execution::Args::Type::Locale, \"en-US\"sv);\r\n    context.Args.AddArg(Execution::Args::Type::Platform, \"Windows.IoT\"sv);\r\n\r\n    DownloadCommand download({});\r\n    download.Execute(context);\r\n    REQUIRE(context.GetTerminationHR() == S_OK);\r\n    INFO(downloadOutput.str());\r\n\r\n    // Verify downloaded files\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath()));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"Dependencies\"));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"Dependencies\" / L\"TestCategoryIdEnglish.Dependency_1.2.3.4_Universal_X64.appx\"));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"Dependencies\" / L\"TestCategoryIdEnglish.Dependency_1.2.3.4_Universal_Arm.appx\"));\r\n    REQUIRE_FALSE(std::filesystem::exists(tempDirectory.GetPath() / L\"TestCategoryIdEnglish_1.0.0.0_Desktop_X64.appx\"));\r\n    REQUIRE_FALSE(std::filesystem::exists(tempDirectory.GetPath() / L\"TestCategoryIdEnglish_1.0.0.0_Desktop_Arm.appx\"));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"TestCategoryIdEnglish.IoT_2.0.0.0_IoT_Arm.appx\"));\r\n\r\n    // Verify license\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"9WZDNCRFJ364_License.xml\"));\r\n    std::ifstream licenseFile(tempDirectory.GetPath() / L\"9WZDNCRFJ364_License.xml\");\r\n    REQUIRE(licenseFile.is_open());\r\n    std::string licenseFileStr;\r\n    std::getline(licenseFile, licenseFileStr);\r\n    REQUIRE(licenseFileStr == LicenseContent);\r\n}\r\n\r\nTEST_CASE(\"MSStoreDownloadFlow_Fail_TargetSkuNotFound\", \"[MSStoreDownloadFlow][workflow]\")\r\n{\r\n    TestCommon::TempDirectory tempDirectory(\"TestDownloadDirectory\", false);\r\n\r\n    std::ostringstream downloadOutput;\r\n    TestContext context{ downloadOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    TestHook::SetDisplayCatalogHttpPipelineStage_Override displayCatalogOverride(GetTestRestRequestHandler(web::http::status_codes::OK, TestDisplayCatalogResponse_TargetSkuNotFound));\r\n    TestHook::SetSfsClientAppContents_Override sfsClientOverride({ &GetSfsAppContentsOverrideFunction });\r\n    TestHook::SetLicensingHttpPipelineStage_Override licensingOverride(GetTestRestRequestHandler(web::http::status_codes::OK, TestLicensingResponse));\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"DownloadFlowTest_MSStore.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::DownloadDirectory, tempDirectory);\r\n    context.Args.AddArg(Execution::Args::Type::Locale, \"en-US\"sv);\r\n\r\n    DownloadCommand download({});\r\n    download.Execute(context);\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_NO_APPLICABLE_DISPLAYCATALOG_PACKAGE);\r\n    INFO(downloadOutput.str());\r\n}\r\n\r\nTEST_CASE(\"MSStoreDownloadFlow_Fail_LocaleNotApplicable\", \"[MSStoreDownloadFlow][workflow]\")\r\n{\r\n    TestCommon::TempDirectory tempDirectory(\"TestDownloadDirectory\", false);\r\n\r\n    std::ostringstream downloadOutput;\r\n    TestContext context{ downloadOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    TestHook::SetDisplayCatalogHttpPipelineStage_Override displayCatalogOverride(GetTestRestRequestHandler(web::http::status_codes::OK, TestDisplayCatalogResponse));\r\n    TestHook::SetSfsClientAppContents_Override sfsClientOverride({ &GetSfsAppContentsOverrideFunction });\r\n    TestHook::SetLicensingHttpPipelineStage_Override licensingOverride(GetTestRestRequestHandler(web::http::status_codes::OK, TestLicensingResponse));\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"DownloadFlowTest_MSStore.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::DownloadDirectory, tempDirectory);\r\n    context.Args.AddArg(Execution::Args::Type::Locale, \"ja-JP\"sv);\r\n\r\n    DownloadCommand download({});\r\n    download.Execute(context);\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_NO_APPLICABLE_DISPLAYCATALOG_PACKAGE);\r\n    INFO(downloadOutput.str());\r\n}\r\n\r\nTEST_CASE(\"MSStoreDownloadFlow_Fail_ArchitectureNotApplicable\", \"[MSStoreDownloadFlow][workflow]\")\r\n{\r\n    TestCommon::TempDirectory tempDirectory(\"TestDownloadDirectory\", false);\r\n\r\n    std::ostringstream downloadOutput;\r\n    TestContext context{ downloadOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    TestHook::SetDisplayCatalogHttpPipelineStage_Override displayCatalogOverride(GetTestRestRequestHandler(web::http::status_codes::OK, TestDisplayCatalogResponse));\r\n    TestHook::SetSfsClientAppContents_Override sfsClientOverride({ &GetSfsAppContentsOverrideFunction });\r\n    TestHook::SetLicensingHttpPipelineStage_Override licensingOverride(GetTestRestRequestHandler(web::http::status_codes::OK, TestLicensingResponse));\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"DownloadFlowTest_MSStore.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::DownloadDirectory, tempDirectory);\r\n    context.Args.AddArg(Execution::Args::Type::Locale, \"en-US\"sv);\r\n    context.Args.AddArg(Execution::Args::Type::InstallerArchitecture, \"arm64\"sv);\r\n\r\n    DownloadCommand download({});\r\n    download.Execute(context);\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_NO_APPLICABLE_DISPLAYCATALOG_PACKAGE);\r\n    INFO(downloadOutput.str());\r\n}\r\n\r\nTEST_CASE(\"MSStoreDownloadFlow_Fail_PlatformNotApplicable\", \"[MSStoreDownloadFlow][workflow]\")\r\n{\r\n    TestCommon::TempDirectory tempDirectory(\"TestDownloadDirectory\", false);\r\n\r\n    std::ostringstream downloadOutput;\r\n    TestContext context{ downloadOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    TestHook::SetDisplayCatalogHttpPipelineStage_Override displayCatalogOverride(GetTestRestRequestHandler(web::http::status_codes::OK, TestDisplayCatalogResponse));\r\n    TestHook::SetSfsClientAppContents_Override sfsClientOverride({ &GetSfsAppContentsOverrideFunction });\r\n    TestHook::SetLicensingHttpPipelineStage_Override licensingOverride(GetTestRestRequestHandler(web::http::status_codes::OK, TestLicensingResponse));\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"DownloadFlowTest_MSStore.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::DownloadDirectory, tempDirectory);\r\n    context.Args.AddArg(Execution::Args::Type::Locale, \"en-US\"sv);\r\n    context.Args.AddArg(Execution::Args::Type::Platform, \"Windows.Holographic\"sv);\r\n\r\n    DownloadCommand download({});\r\n    download.Execute(context);\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_NO_APPLICABLE_SFSCLIENT_PACKAGE);\r\n    INFO(downloadOutput.str());\r\n}\r\n\r\nTEST_CASE(\"MSStoreDownloadFlow_Fail_Licensing\", \"[MSStoreDownloadFlow][workflow]\")\r\n{\r\n    TestCommon::TempDirectory tempDirectory(\"TestDownloadDirectory\", false);\r\n\r\n    std::ostringstream downloadOutput;\r\n    TestContext context{ downloadOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideDownloadInstallerFileForMSStoreDownload(context);\r\n    TestHook::SetDisplayCatalogHttpPipelineStage_Override displayCatalogOverride(GetTestRestRequestHandler(web::http::status_codes::OK, TestDisplayCatalogResponse));\r\n    TestHook::SetSfsClientAppContents_Override sfsClientOverride({ &GetSfsAppContentsOverrideFunction });\r\n    TestHook::SetLicensingHttpPipelineStage_Override licensingOverride(GetTestRestRequestHandler(web::http::status_codes::InternalError));\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"DownloadFlowTest_MSStore.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::DownloadDirectory, tempDirectory);\r\n    context.Args.AddArg(Execution::Args::Type::Locale, \"en-US\"sv);\r\n\r\n    DownloadCommand download({});\r\n    download.Execute(context);\r\n    REQUIRE_TERMINATED_WITH(context, MAKE_HRESULT(SEVERITY_ERROR, FACILITY_HTTP, web::http::status_codes::InternalError));\r\n    INFO(downloadOutput.str());\r\n}\r\n\r\nTEST_CASE(\"MSStoreDownloadFlow_Fail_Licensing_Forbidden\", \"[MSStoreDownloadFlow][workflow]\")\r\n{\r\n    TestCommon::TempDirectory tempDirectory(\"TestDownloadDirectory\", false);\r\n\r\n    std::ostringstream downloadOutput;\r\n    TestContext context{ downloadOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideDownloadInstallerFileForMSStoreDownload(context);\r\n    TestHook::SetDisplayCatalogHttpPipelineStage_Override displayCatalogOverride(GetTestRestRequestHandler(web::http::status_codes::OK, TestDisplayCatalogResponse));\r\n    TestHook::SetSfsClientAppContents_Override sfsClientOverride({ &GetSfsAppContentsOverrideFunction });\r\n    TestHook::SetLicensingHttpPipelineStage_Override licensingOverride(GetTestRestRequestHandler(web::http::status_codes::Forbidden));\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"DownloadFlowTest_MSStore.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::DownloadDirectory, tempDirectory);\r\n    context.Args.AddArg(Execution::Args::Type::Locale, \"en-US\"sv);\r\n\r\n    DownloadCommand download({});\r\n    download.Execute(context);\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED_FORBIDDEN);\r\n    INFO(downloadOutput.str());\r\n}\r\n\r\nTEST_CASE(\"MSStoreDownloadFlow_Success_TargetOSVersion\", \"[MSStoreDownloadFlow][workflow]\")\r\n{\r\n    TestCommon::TempDirectory tempDirectory(\"TestDownloadDirectory\", false);\r\n\r\n    std::ostringstream downloadOutput;\r\n    TestContext context{ downloadOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideDownloadInstallerFileForMSStoreDownload(context);\r\n    TestHook::SetDisplayCatalogHttpPipelineStage_Override displayCatalogOverride(GetTestRestRequestHandler(web::http::status_codes::OK, TestDisplayCatalogResponse));\r\n    TestHook::SetSfsClientAppContents_Override sfsClientOverride({ &GetSfsAppContentsOverrideFunction });\r\n    TestHook::SetLicensingHttpPipelineStage_Override licensingOverride(GetTestRestRequestHandler(web::http::status_codes::OK, TestLicensingResponse));\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"DownloadFlowTest_MSStore.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::DownloadDirectory, tempDirectory);\r\n    context.Args.AddArg(Execution::Args::Type::Locale, \"en-US\"sv);\r\n    context.Args.AddArg(Execution::Args::Type::Platform, \"Windows.Desktop\"sv);\r\n    context.Args.AddArg(Execution::Args::Type::OSVersion, \"9.0.0.0\"sv);\r\n\r\n    DownloadCommand download({});\r\n    download.Execute(context);\r\n    REQUIRE(context.GetTerminationHR() == S_OK);\r\n    INFO(downloadOutput.str());\r\n\r\n    // Verify downloaded files\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath()));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"Dependencies\"));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"Dependencies\" / L\"TestCategoryIdEnglish.Dependency_0.9.3.4_Universal_X64.appx\"));\r\n    REQUIRE_FALSE(std::filesystem::exists(tempDirectory.GetPath() / L\"Dependencies\" / L\"TestCategoryIdEnglish.Dependency_1.2.3.4_Universal_Arm.appx\"));\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"TestCategoryIdEnglish_0.9.0.0_Desktop_X64.appx\"));\r\n    REQUIRE_FALSE(std::filesystem::exists(tempDirectory.GetPath() / L\"TestCategoryIdEnglish_1.0.0.0_Desktop_Arm.appx\"));\r\n    REQUIRE_FALSE(std::filesystem::exists(tempDirectory.GetPath() / L\"TestCategoryIdEnglish.IoT_2.0.0.0_IoT_Arm.appx\"));\r\n\r\n    // Verify license\r\n    REQUIRE(std::filesystem::exists(tempDirectory.GetPath() / L\"9WZDNCRFJ364_License.xml\"));\r\n    std::ifstream licenseFile(tempDirectory.GetPath() / L\"9WZDNCRFJ364_License.xml\");\r\n    REQUIRE(licenseFile.is_open());\r\n    std::string licenseFileStr;\r\n    std::getline(licenseFile, licenseFileStr);\r\n    REQUIRE(licenseFileStr == LicenseContent);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/ManifestComparator.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <ExecutionContext.h>\r\n#include <COMContext.h>\r\n#include <winget/ManifestComparator.h>\r\n#include <winget/UserSettings.h>\r\n#include <Workflows/WorkflowBase.h>\r\n\r\nusing namespace std::string_literals;\r\nusing namespace std::string_view_literals;\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::CLI::Workflow;\r\nusing namespace AppInstaller::CLI::Execution;\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Settings;\r\nusing namespace AppInstaller::Utility;\r\n\r\nusing Manifest = ::AppInstaller::Manifest::Manifest;\r\n\r\nstruct ManifestComparatorTestContext : public NullStream, Context\r\n{\r\n    ManifestComparatorTestContext() : NullStream(), Context(*m_nullOut, *m_nullIn) {}\r\n};\r\n\r\nconst ManifestInstaller& AddInstaller(\r\n    Manifest& manifest,\r\n    Architecture architecture,\r\n    InstallerTypeEnum installerType,\r\n    ScopeEnum scope = ScopeEnum::Unknown,\r\n    std::string minOSVersion = {},\r\n    std::string locale = {},\r\n    std::vector<Architecture> unsupportedOSArchitectures = {},\r\n    MarketsInfo markets = {})\r\n{\r\n    ManifestInstaller toAdd;\r\n    toAdd.Arch = architecture;\r\n    toAdd.BaseInstallerType = installerType;\r\n    toAdd.Scope = scope;\r\n    toAdd.MinOSVersion = minOSVersion;\r\n    toAdd.Locale = locale;\r\n    toAdd.UnsupportedOSArchitectures = unsupportedOSArchitectures;\r\n    toAdd.Markets = markets;\r\n\r\n    manifest.Installers.emplace_back(std::move(toAdd));\r\n\r\n    return manifest.Installers.back();\r\n}\r\n\r\ntemplate<typename T>\r\nvoid RequireVectorsEqual(const std::vector<T>& actual, const std::vector<T>& expected)\r\n{\r\n    REQUIRE(actual.size() == expected.size());\r\n    \r\n    for (std::size_t i = 0; i < actual.size(); ++i)\r\n    {\r\n        REQUIRE(actual[i] == expected[i]);\r\n    }\r\n}\r\n\r\nvoid RequireInstaller(const std::optional<ManifestInstaller>& actual, const ManifestInstaller& expected)\r\n{\r\n    REQUIRE(actual);\r\n    REQUIRE(actual->Arch == expected.Arch);\r\n    REQUIRE(actual->EffectiveInstallerType() == expected.EffectiveInstallerType());\r\n    REQUIRE(actual->Scope == expected.Scope);\r\n    REQUIRE(actual->MinOSVersion == expected.MinOSVersion);\r\n    REQUIRE(actual->Locale == expected.Locale);\r\n\r\n    RequireVectorsEqual(actual->Markets.AllowedMarkets, expected.Markets.AllowedMarkets);\r\n    RequireVectorsEqual(actual->Markets.ExcludedMarkets, expected.Markets.ExcludedMarkets);\r\n}\r\n\r\nvoid RequireInapplicabilities(const std::vector<InapplicabilityFlags>& inapplicabilities, const std::vector<InapplicabilityFlags>& expected)\r\n{\r\n    RequireVectorsEqual(inapplicabilities, expected);\r\n}\r\n\r\nvoid RequireInapplicabilityType(const std::vector<InapplicabilityFlags>& inapplicabilities, InapplicabilityFlags expected)\r\n{\r\n    REQUIRE(!inapplicabilities.empty());\r\n    for (std::size_t i = 0; i < inapplicabilities.size(); ++i)\r\n    {\r\n        REQUIRE(inapplicabilities[i] == expected);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"ManifestComparator_OSFilter_Low\", \"[manifest_comparator]\")\r\n{\r\n    Manifest manifest;\r\n    AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Exe, ScopeEnum::Unknown, \"10.0.99999.0\");\r\n\r\n    ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, {}));\r\n    auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n    REQUIRE(!result);\r\n    RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::OSVersion });\r\n}\r\n\r\nTEST_CASE(\"ManifestComparator_OSFilter_High\", \"[manifest_comparator]\")\r\n{\r\n    Manifest manifest;\r\n    ManifestInstaller expected = AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Exe, ScopeEnum::Unknown, \"10.0.0.0\");\r\n\r\n    ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, {}));\r\n    auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n    RequireInstaller(result, expected);\r\n    REQUIRE(inapplicabilities.size() == 0);\r\n}\r\n\r\nTEST_CASE(\"ManifestComparator_InstalledScopeFilter_Unknown\", \"[manifest_comparator]\")\r\n{\r\n    Manifest manifest;\r\n    ManifestInstaller unknown = AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Msi, ScopeEnum::Unknown);\r\n\r\n    SECTION(\"Nothing Installed\")\r\n    {\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        // Only because it is first\r\n        RequireInstaller(result, unknown);\r\n        REQUIRE(inapplicabilities.size() == 0);\r\n    }\r\n    SECTION(\"User Installed\")\r\n    {\r\n        IPackageVersion::Metadata metadata;\r\n        metadata[PackageVersionMetadata::InstalledScope] = ScopeToString(ScopeEnum::User);\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, metadata));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, unknown);\r\n        REQUIRE(inapplicabilities.size() == 0);\r\n    }\r\n    SECTION(\"Machine Installed\")\r\n    {\r\n        IPackageVersion::Metadata metadata;\r\n        metadata[PackageVersionMetadata::InstalledScope] = ScopeToString(ScopeEnum::Machine);\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, metadata));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, unknown);\r\n        REQUIRE(inapplicabilities.size() == 0);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"ManifestComparator_InstalledScopeFilter\", \"[manifest_comparator]\")\r\n{\r\n    Manifest manifest;\r\n    ManifestInstaller user = AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Msi, ScopeEnum::User);\r\n    ManifestInstaller machine = AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Msi, ScopeEnum::Machine);\r\n\r\n    SECTION(\"Nothing Installed\")\r\n    {\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        // Only because it is first\r\n        RequireInstaller(result, user);\r\n        REQUIRE(inapplicabilities.size() == 0);\r\n    }\r\n    SECTION(\"User Installed\")\r\n    {\r\n        IPackageVersion::Metadata metadata;\r\n        metadata[PackageVersionMetadata::InstalledScope] = ScopeToString(ScopeEnum::User);\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, metadata));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, user);\r\n        RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::InstalledScope });\r\n    }\r\n    SECTION(\"Machine Installed\")\r\n    {\r\n        IPackageVersion::Metadata metadata;\r\n        metadata[PackageVersionMetadata::InstalledScope] = ScopeToString(ScopeEnum::Machine);\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, metadata));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, machine);\r\n        RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::InstalledScope });\r\n    }\r\n}\r\n\r\nTEST_CASE(\"ManifestComparator_InstalledTypeFilter\", \"[manifest_comparator]\")\r\n{\r\n    Manifest manifest;\r\n    ManifestInstaller msi = AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Msi);\r\n    ManifestInstaller msix = AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Msix);\r\n\r\n    SECTION(\"Nothing Installed\")\r\n    {\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        // Only because it is first\r\n        RequireInstaller(result, msi);\r\n        REQUIRE(inapplicabilities.size() == 0);\r\n    }\r\n    SECTION(\"MSI Installed\")\r\n    {\r\n        IPackageVersion::Metadata metadata;\r\n        metadata[PackageVersionMetadata::InstalledType] = InstallerTypeToString(InstallerTypeEnum::Msi);\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, metadata));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, msi);\r\n        RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::InstalledType });\r\n    }\r\n    SECTION(\"MSIX Installed\")\r\n    {\r\n        IPackageVersion::Metadata metadata;\r\n        metadata[PackageVersionMetadata::InstalledType] = InstallerTypeToString(InstallerTypeEnum::Msix);\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, metadata));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, msix);\r\n        RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::InstalledType });\r\n    }\r\n}\r\n\r\nTEST_CASE(\"ManifestComparator_InstalledTypeCompare\", \"[manifest_comparator]\")\r\n{\r\n    Manifest manifest;\r\n    ManifestInstaller burn = AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Burn);\r\n    ManifestInstaller exe = AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Exe);\r\n\r\n    SECTION(\"Nothing Installed\")\r\n    {\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        // Only because it is first\r\n        RequireInstaller(result, burn);\r\n        REQUIRE(inapplicabilities.size() == 0);\r\n    }\r\n    SECTION(\"Exe Installed\")\r\n    {\r\n        IPackageVersion::Metadata metadata;\r\n        metadata[PackageVersionMetadata::InstalledType] = InstallerTypeToString(InstallerTypeEnum::Exe);\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, metadata));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, burn);\r\n        REQUIRE(inapplicabilities.size() == 0);\r\n    }\r\n    SECTION(\"Inno Installed\")\r\n    {\r\n        IPackageVersion::Metadata metadata;\r\n        metadata[PackageVersionMetadata::InstalledType] = InstallerTypeToString(InstallerTypeEnum::Inno);\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, metadata));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, burn);\r\n        REQUIRE(inapplicabilities.size() == 0);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"ManifestComparator_ScopeFilter\", \"[manifest_comparator]\")\r\n{\r\n    Manifest manifest;\r\n    ManifestInstaller user = AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Msi, ScopeEnum::User);\r\n    ManifestInstaller machine = AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Msi, ScopeEnum::Machine);\r\n\r\n    SECTION(\"Nothing Required\")\r\n    {\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        // Only because it is first\r\n        RequireInstaller(result, user);\r\n        REQUIRE(inapplicabilities.size() == 0);\r\n    }\r\n    SECTION(\"User Required\")\r\n    {\r\n        ManifestComparatorTestContext context;\r\n        context.Args.AddArg(Args::Type::InstallScope, ScopeToString(ScopeEnum::User));\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(context, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, user);\r\n        RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::Scope });\r\n    }\r\n    SECTION(\"Machine Required\")\r\n    {\r\n        ManifestComparatorTestContext context;\r\n        context.Args.AddArg(Args::Type::InstallScope, ScopeToString(ScopeEnum::Machine));\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(context, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, machine);\r\n        RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::Scope });\r\n    }\r\n}\r\n\r\nTEST_CASE(\"ManifestComparator_ScopeCompare\", \"[manifest_comparator]\")\r\n{\r\n    Manifest manifest;\r\n    ManifestInstaller machine = AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Msi, ScopeEnum::Machine);\r\n    ManifestInstaller user = AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Msi, ScopeEnum::User);\r\n\r\n    SECTION(\"No Preference\")\r\n    {\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        // The default preference is user\r\n        RequireInstaller(result, user);\r\n        REQUIRE(inapplicabilities.size() == 0);\r\n    }\r\n    SECTION(\"User Preference\")\r\n    {\r\n        TestUserSettings settings;\r\n        settings.Set<Setting::InstallScopePreference>(ScopeEnum::User);\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, user);\r\n        REQUIRE(inapplicabilities.size() == 0);\r\n    }\r\n    SECTION(\"Machine Preference\")\r\n    {\r\n        TestUserSettings settings;\r\n        settings.Set<Setting::InstallScopePreference>(ScopeEnum::Machine);\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, machine);\r\n        REQUIRE(inapplicabilities.size() == 0);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"ManifestComparator_LocaleComparator_Installed_WithUnknown\", \"[manifest_comparator]\")\r\n{\r\n    Manifest manifest;\r\n    ManifestInstaller unknown = AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Msi, ScopeEnum::User, \"\", \"\");\r\n    ManifestInstaller enGB = AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Msi, ScopeEnum::User, \"\", \"en-GB\");\r\n\r\n    SECTION(\"Nothing Installed en-US preference\")\r\n    {\r\n        TestUserSettings settings;\r\n        settings.Set<Setting::InstallLocalePreference>({ \"en-US\" });\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        // Only because it is first\r\n        RequireInstaller(result, enGB);\r\n        REQUIRE(inapplicabilities.size() == 0);\r\n    }\r\n    SECTION(\"en-US Installed\")\r\n    {\r\n        IPackageVersion::Metadata metadata;\r\n        metadata[PackageVersionMetadata::InstalledLocale] = \"en-US\";\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, metadata));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, enGB);\r\n        REQUIRE(inapplicabilities.size() == 0);\r\n    }\r\n    SECTION(\"zh-CN Installed\")\r\n    {\r\n        IPackageVersion::Metadata metadata;\r\n        metadata[PackageVersionMetadata::InstalledLocale] = \"zh-CN\";\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, metadata));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, unknown);\r\n        RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::InstalledLocale });\r\n    }\r\n}\r\n\r\nTEST_CASE(\"ManifestComparator_LocaleComparator_Installed\", \"[manifest_comparator]\")\r\n{\r\n    Manifest manifest;\r\n    ManifestInstaller frFR = AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Msi, ScopeEnum::User, \"\", \"fr-FR\");\r\n    ManifestInstaller enGB = AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Msi, ScopeEnum::User, \"\", \"en-GB\");\r\n\r\n    SECTION(\"Nothing Installed en-US preference\")\r\n    {\r\n        TestUserSettings settings;\r\n        settings.Set<Setting::InstallLocalePreference>({ \"en-US\" });\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        // Only because it is first\r\n        RequireInstaller(result, enGB);\r\n        REQUIRE(inapplicabilities.size() == 0);\r\n    }\r\n    SECTION(\"en-US Installed\")\r\n    {\r\n        IPackageVersion::Metadata metadata;\r\n        metadata[PackageVersionMetadata::InstalledLocale] = \"en-US\";\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, metadata));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, enGB);\r\n        RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::InstalledLocale });\r\n    }\r\n    SECTION(\"zh-CN Installed\")\r\n    {\r\n        IPackageVersion::Metadata metadata;\r\n        metadata[PackageVersionMetadata::InstalledLocale] = \"zh-CN\";\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, metadata));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        REQUIRE(!result);\r\n        RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::InstalledLocale, InapplicabilityFlags::InstalledLocale });\r\n    }\r\n    SECTION(\"en-US installed but fr-fr as user intent\")\r\n    {\r\n        IPackageVersion::Metadata metadata;\r\n        metadata[PackageVersionMetadata::InstalledLocale] = \"en-US\";\r\n        metadata[PackageVersionMetadata::UserIntentLocale] = \"fr-FR\";\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, metadata));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, frFR);\r\n        RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::InstalledLocale }); // en-US inapplicable\r\n    }\r\n    SECTION(\"en-US installed but zh-CN as user intent\")\r\n    {\r\n        IPackageVersion::Metadata metadata;\r\n        metadata[PackageVersionMetadata::InstalledLocale] = \"en-US\";\r\n        metadata[PackageVersionMetadata::UserIntentLocale] = \"zh-CN\";\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, metadata));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        REQUIRE(!result);\r\n        RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::InstalledLocale, InapplicabilityFlags::InstalledLocale });\r\n    }\r\n}\r\n\r\nTEST_CASE(\"ManifestComparator_LocaleComparator\", \"[manifest_comparator]\")\r\n{\r\n    Manifest manifest;\r\n    ManifestInstaller unknown = AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Msi, ScopeEnum::User, \"\", \"\");\r\n    ManifestInstaller frFR = AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Msi, ScopeEnum::User, \"\", \"fr-FR\");\r\n    ManifestInstaller enGB = AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Msi, ScopeEnum::User, \"\", \"en-GB\");\r\n\r\n    SECTION(\"en-GB Required\")\r\n    {\r\n        ManifestComparatorTestContext context;\r\n        context.Args.AddArg(Args::Type::Locale, \"en-GB\"s);\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(context, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, enGB);\r\n        RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::Locale , InapplicabilityFlags::Locale });\r\n    }\r\n    SECTION(\"zh-CN Required\")\r\n    {\r\n        ManifestComparatorTestContext context;\r\n        context.Args.AddArg(Args::Type::Locale, \"zh-CN\"s);\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(context, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        REQUIRE(!result);\r\n        RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::Locale , InapplicabilityFlags::Locale, InapplicabilityFlags::Locale });\r\n    }\r\n    SECTION(\"en-US Preference\")\r\n    {\r\n        TestUserSettings settings;\r\n        settings.Set<Setting::InstallLocalePreference>({ \"en-US\" });\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, enGB);\r\n        REQUIRE(inapplicabilities.size() == 0);\r\n    }\r\n    SECTION(\"zh-CN Preference\")\r\n    {\r\n        TestUserSettings settings;\r\n        settings.Set<Setting::InstallLocalePreference>({ \"zh-CN\" });\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, unknown);\r\n        REQUIRE(inapplicabilities.size() == 0);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"ManifestComparator_AllowedArchitecture_x64_only\", \"[manifest_comparator]\")\r\n{\r\n    Manifest manifest;\r\n    ManifestInstaller x86 = AddInstaller(manifest, Architecture::X86, InstallerTypeEnum::Msi, ScopeEnum::User, \"\", \"\");\r\n\r\n    ManifestComparatorTestContext context;\r\n    context.Add<Data::AllowedArchitectures>({ Architecture::X64 });\r\n\r\n    ManifestComparator mc(GetManifestComparatorOptions(context, {}));\r\n    auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n    REQUIRE(!result);\r\n    RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::MachineArchitecture });\r\n}\r\n\r\nTEST_CASE(\"ManifestComparator_AllowedArchitecture\", \"[manifest_comparator]\")\r\n{\r\n    Manifest manifest;\r\n    ManifestInstaller x86 = AddInstaller(manifest, Architecture::X86, InstallerTypeEnum::Msi, ScopeEnum::User, \"\", \"\");\r\n    ManifestInstaller x64 = AddInstaller(manifest, Architecture::X64, InstallerTypeEnum::Msi, ScopeEnum::User, \"\", \"\");\r\n    ManifestInstaller arm = AddInstaller(manifest, Architecture::Arm, InstallerTypeEnum::Msi, ScopeEnum::User, \"\", \"\");\r\n    ManifestInstaller arm64 = AddInstaller(manifest, Architecture::Arm64, InstallerTypeEnum::Msi, ScopeEnum::User, \"\", \"\");\r\n\r\n    SECTION(\"x86 Preference\")\r\n    {\r\n        ManifestComparatorTestContext context;\r\n        context.Add<Data::AllowedArchitectures>({ Architecture::X86, Architecture::X64 });\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(context, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, x86);\r\n        RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::MachineArchitecture, InapplicabilityFlags::MachineArchitecture });\r\n    }\r\n    SECTION(\"Unknown\")\r\n    {\r\n        ManifestComparatorTestContext context;\r\n        context.Add<Data::AllowedArchitectures>({ Architecture::Unknown });\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(context, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        REQUIRE(result);\r\n        REQUIRE(result->Arch == GetApplicableArchitectures()[0]);\r\n        RequireInapplicabilityType(inapplicabilities, InapplicabilityFlags::MachineArchitecture);\r\n    }\r\n    SECTION(\"x86 and Unknown\")\r\n    {\r\n        ManifestComparatorTestContext context;\r\n        context.Add<Data::AllowedArchitectures>({ Architecture::X86, Architecture::Unknown });\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(context, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, x86);\r\n        RequireInapplicabilityType(inapplicabilities, InapplicabilityFlags::MachineArchitecture);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"ManifestComparator_Architectures_WithUserIntent\", \"[manifest_comparator]\")\r\n{\r\n    Manifest manifest;\r\n    ManifestInstaller x86 = AddInstaller(manifest, Architecture::X86, InstallerTypeEnum::Msi, ScopeEnum::User, \"\", \"\");\r\n    ManifestInstaller x64 = AddInstaller(manifest, Architecture::X64, InstallerTypeEnum::Msi, ScopeEnum::User, \"\", \"\");\r\n\r\n    SECTION(\"x86 installed\")\r\n    {\r\n        IPackageVersion::Metadata metadata;\r\n        metadata[PackageVersionMetadata::InstalledArchitecture] = \"x86\";\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, metadata));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, x86);\r\n        REQUIRE(inapplicabilities.size() == 0);\r\n    }\r\n    SECTION(\"x86 installed but x64 as user intent\")\r\n    {\r\n        IPackageVersion::Metadata metadata;\r\n        metadata[PackageVersionMetadata::InstalledArchitecture] = \"x86\";\r\n        metadata[PackageVersionMetadata::UserIntentArchitecture] = \"x64\";\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, metadata));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, x64);\r\n        RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::MachineArchitecture });\r\n    }\r\n    SECTION(\"x86 installed but x64 as user intent\")\r\n    {\r\n        Manifest x86OnlyManifest;\r\n        AddInstaller(x86OnlyManifest, Architecture::X86, InstallerTypeEnum::Msi, ScopeEnum::User, \"\", \"\");\r\n\r\n        IPackageVersion::Metadata metadata;\r\n        metadata[PackageVersionMetadata::InstalledArchitecture] = \"x86\";\r\n        metadata[PackageVersionMetadata::UserIntentArchitecture] = \"x64\";\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, metadata));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(x86OnlyManifest);\r\n\r\n        REQUIRE(!result);\r\n        RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::MachineArchitecture });\r\n    }\r\n}\r\n\r\nTEST_CASE(\"ManifestComparator_UnsupportedOSArchitecture\", \"[manifest_comparator]\")\r\n{\r\n    auto systemArchitecture = GetSystemArchitecture();\r\n    auto applicableArchitectures = GetApplicableArchitectures();\r\n\r\n    // Try to find an applicable architecture that is not the system architecture\r\n    auto itr = std::find_if(applicableArchitectures.begin(), applicableArchitectures.end(), [&](const auto& arch) { return arch != systemArchitecture; });\r\n    if (itr == applicableArchitectures.end())\r\n    {\r\n        // This test requires having an applicable architecture different from the system one.\r\n        // TODO: Does this actually happen in any arch we use?\r\n        return;\r\n    }\r\n\r\n    auto applicableArchitecture = *itr;\r\n\r\n    Manifest manifest;\r\n\r\n    SECTION(\"System is unsupported\")\r\n    {\r\n        ManifestInstaller installer = AddInstaller(manifest, applicableArchitecture, InstallerTypeEnum::Msi, {}, {}, {}, { systemArchitecture });\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        REQUIRE(!result);\r\n        RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::MachineArchitecture });\r\n    }\r\n    SECTION(\"Other is unsupported\")\r\n    {\r\n        ManifestInstaller installer = AddInstaller(manifest, applicableArchitecture, InstallerTypeEnum::Msi, {}, {}, {}, { applicableArchitecture });\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, installer);\r\n        REQUIRE(inapplicabilities.empty());\r\n    }\r\n}\r\n\r\nTEST_CASE(\"ManifestComparator_Inapplicabilities\", \"[manifest_comparator]\")\r\n{\r\n    Manifest manifest;\r\n    ManifestInstaller installer = AddInstaller(manifest, Architecture::Arm64, InstallerTypeEnum::Exe, ScopeEnum::User, \"10.0.99999.0\", \"es-MX\");\r\n\r\n    ManifestComparatorTestContext context;\r\n    context.Add<Data::AllowedArchitectures>({ Architecture::X86 });\r\n    context.Args.AddArg(Args::Type::InstallScope, ScopeToString(ScopeEnum::Machine));\r\n    context.Args.AddArg(Args::Type::Locale, \"en-GB\"s);\r\n\r\n    IPackageVersion::Metadata metadata;\r\n    metadata[PackageVersionMetadata::InstalledType] = InstallerTypeToString(InstallerTypeEnum::Msix);\r\n\r\n    ManifestComparator mc(GetManifestComparatorOptions(context, metadata));\r\n    auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n    REQUIRE(!result);\r\n    RequireInapplicabilities(\r\n        inapplicabilities,\r\n        { InapplicabilityFlags::OSVersion | InapplicabilityFlags::InstalledType | InapplicabilityFlags::Locale | InapplicabilityFlags::Scope | InapplicabilityFlags::MachineArchitecture });\r\n}\r\n\r\nTEST_CASE(\"ManifestComparator_MarketFilter\", \"[manifest_comparator]\")\r\n{\r\n    Manifest manifest;\r\n\r\n    // Get current market.\r\n    winrt::Windows::Globalization::GeographicRegion region;\r\n    Manifest::string_t currentMarket{ region.CodeTwoLetter() };\r\n\r\n    SECTION(\"Applicable\")\r\n    {\r\n        MarketsInfo markets;\r\n        SECTION(\"Allowed\")\r\n        {\r\n            markets.AllowedMarkets = { currentMarket };\r\n        }\r\n        SECTION(\"Not excluded\")\r\n        {\r\n            markets.ExcludedMarkets = { \"XX\" };\r\n        }\r\n\r\n        ManifestInstaller installer = AddInstaller(manifest, Architecture::X86, InstallerTypeEnum::Exe, {}, {}, {}, {}, markets);\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, installer);\r\n        REQUIRE(inapplicabilities.empty());\r\n    }\r\n\r\n    SECTION(\"Inapplicable\")\r\n    {\r\n        MarketsInfo markets;\r\n        SECTION(\"Excluded\")\r\n        {\r\n            markets.ExcludedMarkets = { currentMarket };\r\n        }\r\n        SECTION(\"Not allowed\")\r\n        {\r\n            markets.AllowedMarkets = { \"XX\" };\r\n        }\r\n\r\n        ManifestInstaller installer = AddInstaller(manifest, Architecture::X86, InstallerTypeEnum::Exe, {}, {}, {}, {}, markets);\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        REQUIRE(!result);\r\n        RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::Market});\r\n    }\r\n}\r\n\r\nTEST_CASE(\"ManifestComparator_Scope_AllowUnknown\", \"[manifest_comparator]\")\r\n{\r\n    Manifest manifest;\r\n    ManifestInstaller expected = AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Exe, ScopeEnum::Unknown);\r\n\r\n    ManifestComparatorTestContext testContext;\r\n    testContext.Args.AddArg(Args::Type::InstallScope, ScopeToString(ScopeEnum::User));\r\n\r\n    SECTION(\"Default\")\r\n    {\r\n        ManifestComparator mc(GetManifestComparatorOptions(testContext, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        REQUIRE(!result);\r\n        RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::Scope });\r\n    }\r\n    SECTION(\"Allow Unknown\")\r\n    {\r\n        testContext.Add<Data::AllowUnknownScope>(true);\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(testContext, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, expected);\r\n        REQUIRE(inapplicabilities.size() == 0);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"ManifestComparator_InstallerType\", \"[manifest_comparator]\")\r\n{\r\n    Manifest manifest;\r\n    ManifestInstaller msi = AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Msi, ScopeEnum::User);\r\n    ManifestInstaller exe = AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Exe, ScopeEnum::User);\r\n    ManifestInstaller msix = AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Msix, ScopeEnum::User);\r\n\r\n    SECTION(\"Msi arg requirement\")\r\n    {\r\n        ManifestComparatorTestContext context;\r\n        context.Args.AddArg(Args::Type::InstallerType, \"msi\"s);\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(context, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, msi);\r\n        RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::InstallerType, InapplicabilityFlags::InstallerType });\r\n    }\r\n    SECTION(\"Msix arg requirement\")\r\n    {\r\n        ManifestComparatorTestContext context;\r\n        context.Args.AddArg(Args::Type::InstallerType, \"msix\"s);\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(context, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, msix);\r\n        RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::InstallerType, InapplicabilityFlags::InstallerType });\r\n    }\r\n    SECTION(\"Portable arg requirement\")\r\n    {\r\n        ManifestComparatorTestContext context;\r\n        context.Args.AddArg(Args::Type::InstallerType, \"portable\"s);\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(context, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        REQUIRE(!result);\r\n        RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::InstallerType, InapplicabilityFlags::InstallerType, InapplicabilityFlags::InstallerType });\r\n    }\r\n    SECTION(\"Exe preference\")\r\n    {\r\n        TestUserSettings settings;\r\n        settings.Set<Setting::InstallerTypePreference>({ InstallerTypeEnum::Exe });\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, exe);\r\n        REQUIRE(inapplicabilities.size() == 0);\r\n    }\r\n    SECTION(\"Preference does not exist\")\r\n    {\r\n        TestUserSettings settings;\r\n        settings.Set<Setting::InstallerTypePreference>({ InstallerTypeEnum::Portable });\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, msi);\r\n        REQUIRE(inapplicabilities.size() == 0);\r\n    }\r\n    SECTION(\"Multiple preferences\")\r\n    {\r\n        TestUserSettings settings;\r\n        settings.Set<Setting::InstallerTypePreference>({ InstallerTypeEnum::Exe, InstallerTypeEnum::Msix });\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, exe);\r\n        REQUIRE(inapplicabilities.size() == 0);\r\n    }\r\n    SECTION(\"Multiple preferences alternate order\")\r\n    {\r\n        TestUserSettings settings;\r\n        settings.Set<Setting::InstallerTypePreference>({ InstallerTypeEnum::Msix, InstallerTypeEnum::Exe });\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, msix);\r\n        REQUIRE(inapplicabilities.size() == 0);\r\n    }\r\n    SECTION(\"Exe requirement\")\r\n    {\r\n        TestUserSettings settings;\r\n        settings.Set<Setting::InstallerTypeRequirement>({ InstallerTypeEnum::Exe });\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        RequireInstaller(result, exe);\r\n        RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::InstallerType, InapplicabilityFlags::InstallerType });\r\n    }\r\n    SECTION(\"Inno requirement\")\r\n    {\r\n        TestUserSettings settings;\r\n        settings.Set<Setting::InstallerTypeRequirement>({ InstallerTypeEnum::Inno });\r\n\r\n        ManifestComparator mc(GetManifestComparatorOptions(ManifestComparatorTestContext{}, {}));\r\n        auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n        REQUIRE(!result);\r\n        RequireInapplicabilities(inapplicabilities, { InapplicabilityFlags::InstallerType, InapplicabilityFlags::InstallerType, InapplicabilityFlags::InstallerType });\r\n    }\r\n}\r\n\r\nTEST_CASE(\"ManifestComparator_MachineArchitecture_Strong_Scope_Weak\", \"[manifest_comparator]\")\r\n{\r\n    Manifest manifest;\r\n    ManifestInstaller system = AddInstaller(manifest, GetSystemArchitecture(), InstallerTypeEnum::Msi, ScopeEnum::Unknown, \"\", \"\");\r\n    ManifestInstaller user = AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Msi, ScopeEnum::User, \"\", \"\");\r\n\r\n    ManifestComparatorTestContext context;\r\n\r\n    ManifestComparator mc(GetManifestComparatorOptions(context, {}));\r\n    auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n    RequireInstaller(result, system);\r\n}\r\n\r\nTEST_CASE(\"ManifestComparator_InstallerCompatibilitySet_Weaker_Than_Architecture\", \"[manifest_comparator]\")\r\n{\r\n    Manifest manifest;\r\n    ManifestInstaller target = AddInstaller(manifest, GetSystemArchitecture(), InstallerTypeEnum::Wix, ScopeEnum::Unknown, \"\", \"\");\r\n    ManifestInstaller foil = AddInstaller(manifest, Architecture::Neutral, InstallerTypeEnum::Msi, ScopeEnum::Unknown, \"\", \"\");\r\n\r\n    ManifestComparatorTestContext context;\r\n\r\n    IPackageVersion::Metadata installationMetadata;\r\n    installationMetadata[PackageVersionMetadata::InstalledType] = InstallerTypeToString(foil.EffectiveInstallerType());\r\n\r\n    ManifestComparator mc(GetManifestComparatorOptions(context, installationMetadata));\r\n    auto [result, inapplicabilities] = mc.GetPreferredInstaller(manifest);\r\n\r\n    RequireInstaller(result, target);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/MatchCriteriaResolver.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"TestCommon.h\"\n#include \"TestHooks.h\"\n#include \"TestSource.h\"\n#include \"AppInstallerStrings.h\"\n#include \"MatchCriteriaResolver.h\"\n\nusing namespace AppInstaller;\nusing namespace AppInstaller::Repository;\nusing namespace AppInstaller::Utility;\nusing namespace TestCommon;\n\r\n\r\nvoid RequireMatchCriteria(const PackageMatchFilter& expected, const PackageMatchFilter& actual)\r\n{\n    REQUIRE(expected.Field == actual.Field);\n    REQUIRE(expected.Type == actual.Type);\n    REQUIRE(expected.Value == actual.Value);\n}\n\nTEST_CASE(\"MatchCriteriaResolver_MatchType\", \"[MatchCriteriaResolver]\")\n{\r\n    Manifest::Manifest manifest;\n    PackageMatchFilter expected{ PackageMatchField::Id, MatchType::Wildcard, \"Not set by test\" };\r\n    std::string searchString = \"Search\";\r\n\r\n    SECTION(\"Exact\")\r\n    {\n        manifest.Id = searchString;\r\n        expected.Type = MatchType::Exact;\n    }\r\n    SECTION(\"Case Insensitive\")\r\n    {\n        manifest.Id = \"search\";\r\n        expected.Type = MatchType::CaseInsensitive;\n    }\r\n    SECTION(\"Starts With\")\r\n    {\n        manifest.Id = \"Search Result\";\r\n        expected.Type = MatchType::StartsWith;\n    }\r\n    SECTION(\"Substring\")\r\n    {\n        manifest.Id = \"Contains searches within\";\r\n        expected.Type = MatchType::Substring;\n    }\r\n    SECTION(\"None\")\r\n    {\r\n        expected.Field = PackageMatchField::Unknown;\n    }\r\n\r\n    expected.Value = manifest.Id;\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch{ MatchType::Substring, searchString };\r\n\r\n    TestPackageVersion packageVersion(manifest);\r\n\r\n    PackageMatchFilter actual = FindBestMatchCriteria(request, &packageVersion);\r\n    RequireMatchCriteria(expected, actual);\n}\n\nTEST_CASE(\"MatchCriteriaResolver_MatchField\", \"[MatchCriteriaResolver]\")\n{\r\n    Manifest::Manifest manifest;\r\n    Utility::NormalizedString searchString = \"Search\";\n    auto foldedSearchString = Utility::FoldCase(searchString);\n    PackageMatchFilter expected{ PackageMatchField::Unknown, MatchType::Exact, searchString };\r\n\r\n    SECTION(\"Identifier\")\r\n    {\n        manifest.Id = searchString;\r\n        expected.Field = PackageMatchField::Id;\n    }\r\n    SECTION(\"Name\")\r\n    {\n        manifest.DefaultLocalization.Add<Manifest::Localization::PackageName>(searchString);\n        expected.Field = PackageMatchField::Name;\n    }\r\n    SECTION(\"Moniker\")\r\n    {\n        manifest.Moniker = searchString;\n        expected.Field = PackageMatchField::Moniker;\n    }\r\n    SECTION(\"Command\")\r\n    {\n        manifest.Installers.emplace_back().Commands.emplace_back(searchString);\n        expected.Field = PackageMatchField::Command;\n    }\r\n    SECTION(\"Tag\")\r\n    {\n        manifest.DefaultLocalization.Add<Manifest::Localization::Tags>({ searchString });\n        expected.Field = PackageMatchField::Tag;\n    }\r\n    SECTION(\"Package Family Name\")\r\n    {\n        manifest.Installers.emplace_back().PackageFamilyName = searchString;\n        expected.Field = PackageMatchField::PackageFamilyName;\r\n        // Folded by test package version\r\n        expected.Type = MatchType::CaseInsensitive;\r\n        expected.Value = foldedSearchString;\n    }\r\n    SECTION(\"Product Code\")\r\n    {\n        manifest.Installers.emplace_back().ProductCode = searchString;\n        expected.Field = PackageMatchField::ProductCode;\r\n        // Folded by test package version\r\n        expected.Type = MatchType::CaseInsensitive;\n        expected.Value = foldedSearchString;\n    }\r\n    SECTION(\"Upgrade Code\")\r\n    {\n        manifest.Installers.emplace_back().AppsAndFeaturesEntries.emplace_back().UpgradeCode = searchString;\n        expected.Field = PackageMatchField::UpgradeCode;\r\n        // Folded by test package version\r\n        expected.Type = MatchType::CaseInsensitive;\n        expected.Value = foldedSearchString;\n    }\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch{ MatchType::Substring, searchString };\r\n\r\n    TestPackageVersion packageVersion(manifest);\r\n\r\n    PackageMatchFilter actual = FindBestMatchCriteria(request, &packageVersion);\r\n    RequireMatchCriteria(expected, actual);\n}\n\nTEST_CASE(\"MatchCriteriaResolver_Complex\", \"[MatchCriteriaResolver]\")\n{\r\n    Manifest::Manifest manifest;\r\n    Utility::NormalizedString searchString = \"Search\";\n    auto foldedSearchString = Utility::FoldCase(searchString);\n    PackageMatchFilter expected{ PackageMatchField::Tag, MatchType::Exact, searchString };\r\n\n    manifest.Id = \"Identifer search substring\";\n    manifest.DefaultLocalization.Add<Manifest::Localization::PackageName>(\"Search name starts\");\n    manifest.Moniker = foldedSearchString;\n    manifest.Installers.emplace_back().Commands.emplace_back(\"Command search string\");\n    manifest.DefaultLocalization.Add<Manifest::Localization::Tags>({ searchString });\n    manifest.Installers.emplace_back().PackageFamilyName = searchString;\n    manifest.Installers.emplace_back().ProductCode = searchString;\n    manifest.Installers.emplace_back().AppsAndFeaturesEntries.emplace_back().UpgradeCode = searchString;\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch{ MatchType::Substring, searchString };\r\n\r\n    TestPackageVersion packageVersion(manifest);\r\n\r\n    PackageMatchFilter actual = FindBestMatchCriteria(request, &packageVersion);\r\n    RequireMatchCriteria(expected, actual);\n}\n"
  },
  {
    "path": "src/AppInstallerCLITests/MsiExecArguments.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <winget/MsiExecArguments.h>\r\n#include <AppInstallerErrors.h>\r\n\r\nusing namespace std::string_view_literals;\r\nusing namespace AppInstaller;\r\n\r\nTEST_CASE(\"MsiExecArgs_ParseEmpty\", \"[msiexec]\")\r\n{\r\n    std::vector<std::string_view> emptyArguments = { \"\"sv, \"  \", \"\\t\" };\r\n\r\n    for (const auto argString : emptyArguments)\r\n    {\r\n        auto args = Msi::ParseMSIArguments(argString);\r\n        REQUIRE(!args.LogFile.has_value());\r\n        REQUIRE(args.UILevel == INSTALLUILEVEL_DEFAULT);\r\n        REQUIRE(args.Properties.empty());\r\n    }\r\n}\r\n\r\nTEST_CASE(\"MsiExecArgs_ParseUILevel\", \"[msiexec]\")\r\n{\r\n    {\r\n        auto args = Msi::ParseMSIArguments(\"/qn\"sv);\r\n        REQUIRE(!args.LogFile.has_value());\r\n        REQUIRE(args.UILevel == (INSTALLUILEVEL_NONE | INSTALLUILEVEL_UACONLY));\r\n        REQUIRE(args.Properties.empty());\r\n    }\r\n\r\n    {\r\n        auto args = Msi::ParseMSIArguments(\"/qb+\"sv);\r\n        REQUIRE(!args.LogFile.has_value());\r\n        REQUIRE(args.UILevel == (INSTALLUILEVEL_BASIC | INSTALLUILEVEL_ENDDIALOG));\r\n        REQUIRE(args.Properties.empty());\r\n    }\r\n\r\n    {\r\n        auto args = Msi::ParseMSIArguments(\"/q\"sv);\r\n        REQUIRE(!args.LogFile.has_value());\r\n        REQUIRE(args.UILevel == (INSTALLUILEVEL_NONE | INSTALLUILEVEL_UACONLY));\r\n        REQUIRE(args.Properties.empty());\r\n    }\r\n\r\n    {\r\n        auto args = Msi::ParseMSIArguments(\"/qr\"sv);\r\n        REQUIRE(!args.LogFile.has_value());\r\n        REQUIRE(args.UILevel == (INSTALLUILEVEL_REDUCED));\r\n        REQUIRE(args.Properties.empty());\r\n    }\r\n\r\n    REQUIRE_THROWS_HR(Msi::ParseMSIArguments(\"/qr-\"sv), APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT);\r\n    REQUIRE_THROWS_HR(Msi::ParseMSIArguments(\"/q arg\"sv), APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT);\r\n}\r\n\r\nTEST_CASE(\"MsiExecArgs_ParseLogMode\", \"[msiexec]\")\r\n{\r\n    {\r\n        auto args = Msi::ParseMSIArguments(\"/l file.txt\"sv);\r\n        REQUIRE(args.LogMode == Msi::DefaultLogMode);\r\n        REQUIRE(args.LogAttributes == 0);\r\n        REQUIRE(args.LogFile == L\"file.txt\"sv);\r\n        REQUIRE(args.UILevel == INSTALLUILEVEL_DEFAULT);\r\n        REQUIRE(args.Properties.empty());\r\n    }\r\n\r\n    {\r\n        auto args = Msi::ParseMSIArguments(\"/le errors.txt\"sv);\r\n        REQUIRE(args.LogMode == INSTALLLOGMODE_ERROR);\r\n        REQUIRE(args.LogAttributes == 0);\r\n        REQUIRE(args.LogFile == L\"errors.txt\"sv);\r\n        REQUIRE(args.UILevel == INSTALLUILEVEL_DEFAULT);\r\n        REQUIRE(args.Properties.empty());\r\n    }\r\n\r\n    {\r\n        auto args = Msi::ParseMSIArguments(\"/l! flush.txt\"sv);\r\n        REQUIRE(args.LogMode == Msi::DefaultLogMode);\r\n        REQUIRE(args.LogAttributes == INSTALLLOGATTRIBUTES_FLUSHEACHLINE);\r\n        REQUIRE(args.LogFile == L\"flush.txt\"sv);\r\n        REQUIRE(args.UILevel == INSTALLUILEVEL_DEFAULT);\r\n        REQUIRE(args.Properties.empty());\r\n    }\r\n\r\n    {\r\n        auto args = Msi::ParseMSIArguments(\"/l\\\"i\\\" \\\"quoted path.txt\\\"\"sv);\r\n        REQUIRE(args.LogMode == INSTALLLOGMODE_INFO);\r\n        REQUIRE(args.LogAttributes == 0);\r\n        REQUIRE(args.LogFile == L\"quoted path.txt\"sv);\r\n        REQUIRE(args.UILevel == INSTALLUILEVEL_DEFAULT);\r\n        REQUIRE(args.Properties.empty());\r\n    }\r\n\r\n    {\r\n        auto args = Msi::ParseMSIArguments(\"/liwpx+! log.txt\"sv);\r\n        REQUIRE(args.LogMode == (INSTALLLOGMODE_INFO | INSTALLLOGMODE_WARNING | INSTALLLOGMODE_PROPERTYDUMP | INSTALLLOGMODE_EXTRADEBUG));\r\n        REQUIRE(args.LogAttributes == (INSTALLLOGATTRIBUTES_FLUSHEACHLINE | INSTALLLOGATTRIBUTES_APPEND));\r\n        REQUIRE(args.LogFile == L\"log.txt\"sv);\r\n        REQUIRE(args.UILevel == INSTALLUILEVEL_DEFAULT);\r\n        REQUIRE(args.Properties.empty());\r\n    }\r\n\r\n    {\r\n        auto args = Msi::ParseMSIArguments(\"/l* all.txt\"sv);\r\n        REQUIRE(args.LogMode == Msi::AllLogMode);\r\n        REQUIRE(args.LogAttributes == 0);\r\n        REQUIRE(args.LogFile == L\"all.txt\"sv);\r\n        REQUIRE(args.UILevel == INSTALLUILEVEL_DEFAULT);\r\n        REQUIRE(args.Properties.empty());\r\n    }\r\n\r\n    {\r\n        auto args = Msi::ParseMSIArguments(\"/l* \\\"without closing quote.txt\"sv);\r\n        REQUIRE(args.LogMode == Msi::AllLogMode);\r\n        REQUIRE(args.LogAttributes == 0);\r\n        REQUIRE(args.LogFile == L\"without closing quote.txt\"sv);\r\n        REQUIRE(args.UILevel == INSTALLUILEVEL_DEFAULT);\r\n        REQUIRE(args.Properties.empty());\r\n    }\r\n\r\n    REQUIRE_THROWS_HR(Msi::ParseMSIArguments(\"/l\"sv), APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT);\r\n    REQUIRE_THROWS_HR(Msi::ParseMSIArguments(\"/lz log.txt\"sv), APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT);\r\n}\r\n\r\nTEST_CASE(\"MsiExecArgs_ParseProperties\", \"[msiexec]\")\r\n{\r\n    {\r\n        auto args = Msi::ParseMSIArguments(\"PROPERTY=value\"sv);\r\n        REQUIRE(!args.LogFile.has_value());\r\n        REQUIRE(args.UILevel == INSTALLUILEVEL_DEFAULT);\r\n        REQUIRE(args.Properties == L\" PROPERTY=value\"sv);\r\n    }\r\n\r\n    {\r\n        auto args = Msi::ParseMSIArguments(\"EMPTY=\"sv);\r\n        REQUIRE(!args.LogFile.has_value());\r\n        REQUIRE(args.UILevel == INSTALLUILEVEL_DEFAULT);\r\n        REQUIRE(args.Properties == L\" EMPTY=\"sv);\r\n    }\r\n\r\n    {\r\n        auto args = Msi::ParseMSIArguments(\"PROPERTY=\\\"quoted value\\\"\"sv);\r\n        REQUIRE(!args.LogFile.has_value());\r\n        REQUIRE(args.UILevel == INSTALLUILEVEL_DEFAULT);\r\n        REQUIRE(args.Properties == L\" PROPERTY=\\\"quoted value\\\"\"sv);\r\n    }\r\n\r\n    {\r\n        auto args = Msi::ParseMSIArguments(\"PROPERTY=\\\"escaped \\\"\\\" quotes\\\"\"sv);\r\n        REQUIRE(!args.LogFile.has_value());\r\n        REQUIRE(args.UILevel == INSTALLUILEVEL_DEFAULT);\r\n        REQUIRE(args.Properties == L\" PROPERTY=\\\"escaped \\\"\\\" quotes\\\"\"sv);\r\n    }\r\n\r\n    {\r\n        auto args = Msi::ParseMSIArguments(\"PROPERTY1=value1       PROPERTY2=value2\"sv);\r\n        REQUIRE(!args.LogFile.has_value());\r\n        REQUIRE(args.UILevel == INSTALLUILEVEL_DEFAULT);\r\n        REQUIRE(args.Properties == L\" PROPERTY1=value1 PROPERTY2=value2\"sv);\r\n    }\r\n\r\n    REQUIRE_THROWS_HR(Msi::ParseMSIArguments(\"NOSEPARATOR\"sv), APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT);\r\n    REQUIRE_THROWS_HR(Msi::ParseMSIArguments(\"$NOTAPROPERTY=value\"sv), APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT);\r\n    REQUIRE_THROWS_HR(Msi::ParseMSIArguments(\"PROPERTY=not quoted\"sv), APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT);\r\n    REQUIRE_THROWS_HR(Msi::ParseMSIArguments(\"PROPERTY=\\\"bad \\\"internal\\\" quotes\\\"\"sv), APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT);\r\n    REQUIRE_THROWS_HR(Msi::ParseMSIArguments(\"PROPERTY=\\\"mismatched quote\"sv), APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT);\r\n}\r\n\r\nTEST_CASE(\"MsiExecArgs_ParseMultipleOptions\", \"[msiexec]\")\r\n{\r\n    {\r\n        auto args = Msi::ParseMSIArguments(\"/li first.txt /le second.txt\"sv);\r\n        REQUIRE(args.LogMode == INSTALLLOGMODE_ERROR);\r\n        REQUIRE(args.LogAttributes == 0);\r\n        REQUIRE(args.LogFile == L\"second.txt\"sv);\r\n        REQUIRE(args.UILevel == INSTALLUILEVEL_DEFAULT);\r\n        REQUIRE(args.Properties.empty());\r\n    }\r\n\r\n    {\r\n        auto args = Msi::ParseMSIArguments(\"PROPERTY1=value1 /qb  PROPERTY2= /lw file.txt\"sv);\r\n        REQUIRE(args.LogMode == INSTALLLOGMODE_WARNING);\r\n        REQUIRE(args.LogAttributes == 0);\r\n        REQUIRE(args.LogFile == L\"file.txt\"sv);\r\n        REQUIRE(args.UILevel == INSTALLUILEVEL_BASIC);\r\n        REQUIRE(args.Properties == L\" PROPERTY1=value1 PROPERTY2=\");\r\n    }\r\n}\r\n\r\nTEST_CASE(\"MsiExecArgs_ParseLongOptions\", \"[msiexec]\")\r\n{\r\n    {\r\n        auto args = Msi::ParseMSIArguments(\"/quiet\"sv);\r\n        REQUIRE(!args.LogFile.has_value());\r\n        REQUIRE(args.UILevel == (INSTALLUILEVEL_NONE | INSTALLUILEVEL_UACONLY));\r\n        REQUIRE(args.Properties.empty());\r\n    }\r\n\r\n    {\r\n        auto args = Msi::ParseMSIArguments(\"/passive\"sv);\r\n        REQUIRE(!args.LogFile.has_value());\r\n        REQUIRE(args.UILevel == (INSTALLUILEVEL_BASIC | INSTALLUILEVEL_PROGRESSONLY | INSTALLUILEVEL_HIDECANCEL));\r\n        REQUIRE(args.Properties == L\" REBOOTPROMPT=S\"sv);\r\n    }\r\n\r\n    {\r\n        auto args = Msi::ParseMSIArguments(\"/NoRestart\"sv);\r\n        REQUIRE(!args.LogFile.has_value());\r\n        REQUIRE(args.UILevel == INSTALLUILEVEL_DEFAULT);\r\n        REQUIRE(args.Properties == L\" REBOOT=ReallySuppress\"sv);\r\n    }\r\n}"
  },
  {
    "path": "src/AppInstallerCLITests/MsixInfo.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <AppInstallerMsixInfo.h>\r\n#include <AppInstallerDownloader.h>\r\n#include <AppInstallerRuntime.h>\r\n\r\nusing namespace std::string_literals;\r\nusing namespace std::string_view_literals;\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller;\r\n\r\nconstexpr std::string_view s_MsixFile_1 = \"index.1.0.0.0.msix\";\r\nconstexpr std::string_view s_MsixFile_2 = \"index.2.0.0.0.msix\";\r\nconstexpr std::string_view s_MsixFileSigned_1 = \"index.1.0.0.0.signed.msix\";\r\n\r\nTEST_CASE(\"MsixInfo_GetPackageFullName\", \"[msixinfo]\")\r\n{\r\n    TestDataFile index(s_MsixFile_1);\r\n    Msix::MsixInfo msix(index.GetPath());\r\n\r\n    std::string expectedFullName = \"AppInstallerCLITestsFakeIndex_1.0.0.0_neutral__125rzkzqaqjwj\";\r\n    std::string actualFullName = msix.GetPackageFullName();\r\n\r\n    REQUIRE(expectedFullName == actualFullName);\r\n}\r\n\r\nTEST_CASE(\"MsixInfo_CompareToSelf\", \"[msixinfo]\")\r\n{\r\n    TestDataFile index(s_MsixFile_1);\r\n    Msix::MsixInfo msix(index.GetPath());\r\n\r\n    REQUIRE(!msix.IsNewerThan(index.GetPath().u8string()));\r\n}\r\n\r\nTEST_CASE(\"MsixInfo_CompareToOlder\", \"[msixinfo]\")\r\n{\r\n    TestDataFile index1(s_MsixFile_1);\r\n    TestDataFile index2(s_MsixFile_2);\r\n    Msix::MsixInfo msix2(index2.GetPath());\r\n\r\n    REQUIRE(msix2.IsNewerThan(index1));\r\n}\r\n\r\nTEST_CASE(\"MsixInfo_WriteFile\", \"[msixinfo]\")\r\n{\r\n    TestDataFile index(s_MsixFile_1);\r\n    Msix::MsixInfo msix(index.GetPath());\r\n\r\n    TempFile file{ \"msixtest_file\"s, \".bin\"s };\r\n    ProgressCallback callback;\r\n\r\n    msix.WriteToFile(\"Public\\\\index.db\", file, callback);\r\n\r\n    REQUIRE(1 == std::filesystem::file_size(file));\r\n}\r\n\r\nTEST_CASE(\"MsixInfo_ValidateMsixTrustInfo\", \"[msixinfo]\")\r\n{\r\n    if (!Runtime::IsRunningAsAdmin())\r\n    {\r\n        WARN(\"Test requires admin privilege. Skipped.\");\r\n        return;\r\n    }\r\n\r\n    TestDataFile notSigned{ s_MsixFile_1 };\r\n    Msix::WriteLockedMsixFile notSignedWriteLocked{ notSigned };\r\n    REQUIRE_FALSE(notSignedWriteLocked.ValidateTrustInfo(false));\r\n\r\n    TestDataFile testSigned{ s_MsixFileSigned_1 };\r\n    Msix::WriteLockedMsixFile testSignedWriteLocked{ testSigned };\r\n\r\n    // Remove the cert if already trusted\r\n    bool certExistsBeforeTest = UninstallCertFromSignedPackage(testSigned);\r\n\r\n    REQUIRE_FALSE(testSignedWriteLocked.ValidateTrustInfo(false));\r\n\r\n    // Add the cert to trusted\r\n    InstallCertFromSignedPackage(testSigned);\r\n\r\n    REQUIRE(testSignedWriteLocked.ValidateTrustInfo(false));\r\n    REQUIRE_FALSE(testSignedWriteLocked.ValidateTrustInfo(true));\r\n\r\n    TestCommon::TempFile microsoftSigned{ \"testIndex\"s, \".msix\"s };\r\n    ProgressCallback callback;\r\n    Utility::Download(\"https://cdn.winget.microsoft.com/cache/source2.msix\", microsoftSigned.GetPath(), Utility::DownloadType::Index, callback);\r\n\r\n    Msix::WriteLockedMsixFile microsoftSignedWriteLocked{ microsoftSigned };\r\n    REQUIRE(microsoftSignedWriteLocked.ValidateTrustInfo(true));\r\n\r\n    if (!certExistsBeforeTest)\r\n    {\r\n        UninstallCertFromSignedPackage(testSigned);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"MsixInfo_GetPackageIdInfoFromFullName\", \"[msixinfo]\")\r\n{\r\n    auto testPackageIdInfo = Msix::GetPackageIdInfoFromFullName(\"Microsoft.NET.Native.Framework.2.2_2.2.29512.0_arm64__8wekyb3d8bbwe\");\r\n    REQUIRE(testPackageIdInfo.Name == \"Microsoft.NET.Native.Framework.2.2\");\r\n    REQUIRE(testPackageIdInfo.Version == Utility::UInt64Version{ \"2.2.29512.0\" });\r\n\r\n    auto testPackageIdInfo2 = Msix::GetPackageIdInfoFromFullName(\"Microsoft.DoesNotExist_1.2.3.4_neutral_~_8wekyb3d8bbwe\");\r\n    REQUIRE(testPackageIdInfo2.Name == \"Microsoft.DoesNotExist\");\r\n    REQUIRE(testPackageIdInfo2.Version == Utility::UInt64Version{ \"1.2.3.4\" });\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/MsixManifest.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"TestCommon.h\"\n#include <AppInstallerMsixInfo.h>\n#include <AppInstallerDownloader.h>\n#include <AppInstallerRuntime.h>\n#include <winget/MsixManifest.h>\n\nusing namespace TestCommon;\nusing namespace AppInstaller;\nusing namespace AppInstaller::Msix;\nusing namespace Microsoft::WRL;\n\nnamespace\n{\n    // Input values\n    constexpr std::string_view installerGoodMsix = \"Installer-Good.msix\";\n    constexpr std::string_view installerGoodMsixBundle = \"Installer-Good.msixbundle\";\n\n    // Expected\n    constexpr std::string_view expectedFamilyName = \"FakeInstallerForTesting_125rzkzqaqjwj\";\n    PackageVersion expectedPackageVersion { 0xAAAABBBBCCCCDDDD };\n    constexpr std::string_view expectedWindowsDesktopName = \"Windows.Desktop\";\n    OSVersion expectedWindowsDesktopMinVersion { \"10.0.16299.0\" };\n    OSVersion expectedWindowsUniversalMinVersion { \"10.0.0.0\" };\n}\n\nTEST_CASE(\"MsixManifest_ValidateFieldsParsedFromManifestReader\", \"[MsixManifest]\")\n{\n    ComPtr<IAppxManifestReader> manifestReader;\n    REQUIRE(GetMsixPackageManifestReader(installerGoodMsix, &manifestReader));\n\n    Msix::MsixPackageManifest msixManifest(manifestReader);\n    REQUIRE(expectedFamilyName == msixManifest.GetIdentity().GetPackageFamilyName());\n    REQUIRE(expectedPackageVersion == msixManifest.GetIdentity().GetVersion());\n    REQUIRE(2 == msixManifest.GetTargetDeviceFamilies().size());\n    REQUIRE(expectedWindowsUniversalMinVersion == msixManifest.GetMinimumOSVersionForSupportedPlatforms().value());\n\n    auto targets = msixManifest.GetTargetDeviceFamilies();\n    auto windowsDesktop = std::find_if(targets.begin(), targets.end(), [](auto& t) { return t.GetMinVersion() == expectedWindowsDesktopMinVersion; });\n    REQUIRE(windowsDesktop != targets.end());\n\n    auto windowsUniversal = std::find_if(targets.begin(), targets.end(), [](auto& t) { return t.GetMinVersion() == expectedWindowsUniversalMinVersion; });\n    REQUIRE(windowsUniversal != targets.end());\n}\n\nTEST_CASE(\"MsixManifest_ValidateFieldsParsedFromMsix\", \"[MsixManifest]\")\n{\n    TestDataFile testFile(installerGoodMsix);\n    MsixInfo msixInfo(testFile.GetPath());\n\n    auto appPackageManifests = msixInfo.GetAppPackageManifests();\n    REQUIRE(1 == appPackageManifests.size());\n\n    auto &appPackageManifest = appPackageManifests[0];\n    REQUIRE(expectedFamilyName == appPackageManifest.GetIdentity().GetPackageFamilyName());\n    REQUIRE(expectedPackageVersion == appPackageManifest.GetIdentity().GetVersion());\n    REQUIRE(2 == appPackageManifest.GetTargetDeviceFamilies().size());\n    REQUIRE(expectedWindowsUniversalMinVersion == appPackageManifest.GetMinimumOSVersionForSupportedPlatforms().value());\n\n    auto targets = appPackageManifest.GetTargetDeviceFamilies();\n    auto windowsDesktop = std::find_if(targets.begin(), targets.end(), [](auto& t) { return t.GetMinVersion() == expectedWindowsDesktopMinVersion; });\n    REQUIRE(windowsDesktop != targets.end());\n\n    auto windowsUniversal = std::find_if(targets.begin(), targets.end(), [](auto& t) { return t.GetMinVersion() == expectedWindowsUniversalMinVersion; });\n    REQUIRE(windowsUniversal != targets.end());\n}\n\nTEST_CASE(\"MsixManifest_ValidateFieldsParsedFromMsixBundle\", \"[MsixManifest]\")\n{\n    TestDataFile testFile(installerGoodMsixBundle);\n    MsixInfo msixInfo(testFile.GetPath());\n    \n    auto appPackageManifests = msixInfo.GetAppPackageManifests();\n    REQUIRE(2 == appPackageManifests.size());\n\n    for (auto& appPackageManifest : appPackageManifests)\n    {\n        REQUIRE(expectedFamilyName == appPackageManifest.GetIdentity().GetPackageFamilyName());\n        REQUIRE(expectedPackageVersion == appPackageManifest.GetIdentity().GetVersion());\n        REQUIRE(1 == appPackageManifest.GetTargetDeviceFamilies().size());\n        REQUIRE(expectedWindowsDesktopName == appPackageManifest.GetTargetDeviceFamilies().front().GetName());\n        REQUIRE(expectedWindowsDesktopMinVersion == appPackageManifest.GetTargetDeviceFamilies().front().GetMinVersion());\n        REQUIRE(expectedWindowsDesktopMinVersion == appPackageManifest.GetMinimumOSVersionForSupportedPlatforms().value());\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLITests/NameNormalization.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <winget/NameNormalization.h>\r\n\r\nusing namespace std::string_view_literals;\r\nusing namespace AppInstaller::Utility;\r\n\r\n\r\n// This skipped test case can be used to update the test file.\r\n// It writes back to the output content location, so you must manually\r\n// copy the file(s) back to the git managed location to update.\r\nTEST_CASE(\"NameNorm_Update_Database_Initial\", \"[.]\")\r\n{\r\n    std::ifstream namesStream(TestCommon::TestDataFile(\"InputNames.txt\").GetPath());\r\n    REQUIRE(namesStream);\r\n    std::ifstream publishersStream(TestCommon::TestDataFile(\"InputPublishers.txt\").GetPath());\r\n    REQUIRE(publishersStream);\r\n    std::ofstream resultsStream(TestCommon::TestDataFile(\"NormalizationInitialIdsUpdate.txt\").GetPath(), std::ofstream::out | std::ofstream::trunc | std::ofstream::binary);\r\n    REQUIRE(resultsStream);\r\n\r\n    // Far larger than any one value; hopefully\r\n    char name[4096]{};\r\n    char publisher[4096]{};\r\n\r\n    NameNormalizer normer(NormalizationVersion::Initial);\r\n\r\n    for (;;)\r\n    {\r\n        namesStream.getline(name, ARRAYSIZE(name));\r\n        publishersStream.getline(publisher, ARRAYSIZE(publisher));\r\n\r\n        if (namesStream || publishersStream)\r\n        {\r\n            REQUIRE(namesStream);\r\n            REQUIRE(publishersStream);\r\n\r\n            INFO(\"Name[\" << name << \"], Publisher[\" << publisher << \"]\");\r\n\r\n            auto normalized = normer.Normalize(name, publisher);\r\n\r\n            std::string normalizedId = normalized.Publisher();\r\n            normalizedId += '.';\r\n            normalizedId += normalized.Name();\r\n\r\n            resultsStream << normalizedId << std::endl;\r\n            REQUIRE(resultsStream);\r\n        }\r\n        else\r\n        {\r\n            break;\r\n        }\r\n    }\r\n}\r\n\r\n// If this test is failing, either changes to winget code or the ICU binaries have caused it.\r\n// This will impact the functionality of the PreIndexedPackageSource, as it is the primary\r\n// mechanism used to cross reference packages installed outside of winget with those in the\r\n// source.\r\nTEST_CASE(\"NameNorm_Database_Initial\", \"[name_norm]\")\r\n{\r\n    std::ifstream namesStream(TestCommon::TestDataFile(\"InputNames.txt\").GetPath());\r\n    REQUIRE(namesStream);\r\n    std::ifstream publishersStream(TestCommon::TestDataFile(\"InputPublishers.txt\").GetPath());\r\n    REQUIRE(publishersStream);\r\n    std::ifstream resultsStream(TestCommon::TestDataFile(\"NormalizationInitialIds.txt\").GetPath());\r\n    REQUIRE(resultsStream);\r\n\r\n    // Far larger than any one value; hopefully\r\n    char name[4096]{};\r\n    char publisher[4096]{};\r\n    char expectedId[4096]{};\r\n\r\n    NameNormalizer normer(NormalizationVersion::Initial);\r\n\r\n    for (;;)\r\n    {\r\n        namesStream.getline(name, ARRAYSIZE(name));\r\n        publishersStream.getline(publisher, ARRAYSIZE(publisher));\r\n        resultsStream.getline(expectedId, ARRAYSIZE(expectedId));\r\n\r\n        if (namesStream || publishersStream || resultsStream)\r\n        {\r\n            REQUIRE(namesStream);\r\n            REQUIRE(publishersStream);\r\n            REQUIRE(resultsStream);\r\n\r\n            INFO(\"Name[\" << name << \"], Publisher[\" << publisher << \"]\");\r\n\r\n            auto normalized = normer.Normalize(name, publisher);\r\n\r\n            std::string normalizedId = normalized.Publisher();\r\n            normalizedId += '.';\r\n            normalizedId += normalized.Name();\r\n\r\n            REQUIRE(expectedId == normalizedId);\r\n        }\r\n        else\r\n        {\r\n            break;\r\n        }\r\n    }\r\n}\r\n\r\nTEST_CASE(\"NameNorm_Architecture\", \"[name_norm]\")\r\n{\r\n    NameNormalizer normer(NormalizationVersion::Initial);\r\n\r\n    REQUIRE(normer.Normalize(\"Name\", {}).Architecture() == Architecture::Unknown);\r\n    REQUIRE(normer.Normalize(\"Name x86\", {}).Architecture() == Architecture::X86);\r\n    REQUIRE(normer.Normalize(\"Name x86_64\", {}).Architecture() == Architecture::X64);\r\n    REQUIRE(normer.Normalize(\"Name (64 bit)\", {}).Architecture() == Architecture::X64);\r\n    REQUIRE(normer.Normalize(\"Name 32/64 bit\", {}).Architecture() == Architecture::Unknown);\r\n    REQUIRE(normer.Normalize(\"Fox86\", {}).Architecture() == Architecture::Unknown);\r\n}\r\n\r\nTEST_CASE(\"NameNorm_Locale\", \"[name_norm]\")\r\n{\r\n    NameNormalizer normer(NormalizationVersion::Initial);\r\n\r\n    REQUIRE(normer.Normalize(\"Name\", {}).Locale() == \"\");\r\n    REQUIRE(normer.Normalize(\"Name en-US\", {}).Locale() == \"en-us\");\r\n    REQUIRE(normer.Normalize(\"Name (es-mx)\", {}).Locale() == \"es-mx\");\r\n    REQUIRE(normer.Normalize(\"Names-mx\", {}).Locale() == \"\");\r\n}\r\n\r\nTEST_CASE(\"NameNorm_KBNumbers\", \"[name_norm]\")\r\n{\r\n    NameNormalizer normer(NormalizationVersion::Initial);\r\n\r\n    REQUIRE(normer.Normalize(\"Fix for (KB42)\", {}).Name() == \"FixforKB42\");\r\n}\r\n\r\nTEST_CASE(\"NameNorm_Initial_PreserveWhitespace\", \"[name_norm]\")\r\n{\r\n    NameNormalizer normer(NormalizationVersion::InitialPreserveWhiteSpace);\r\n\r\n    REQUIRE(normer.NormalizeName(\"Some Name\").Name() == \"Some Name\");\r\n    REQUIRE(normer.NormalizePublisher(\"Some Publisher Corp\") == \"Some Publisher\");\r\n}\r\n\r\nTEST_CASE(\"NameNorm_GetNormalizedName_GetNormalizedFields\", \"[name_norm]\")\r\n{\r\n    NameNormalizer normer(NormalizationVersion::Initial);\r\n\r\n    auto normalizedName = normer.NormalizeName(\"Name(X64)\");\r\n    REQUIRE(normalizedName.GetNormalizedName(NormalizationField::None) == \"Name\");\r\n    REQUIRE(normalizedName.GetNormalizedName(NormalizationField::Architecture) == \"Name(X64)\");\r\n    REQUIRE(normalizedName.GetNormalizedFields() == NormalizationField::Architecture);\r\n\r\n    auto normalizedName2 = normer.NormalizeName(\"Name\");\r\n    REQUIRE(normalizedName2.GetNormalizedName(NormalizationField::None) == \"Name\");\r\n    REQUIRE(normalizedName2.GetNormalizedName(NormalizationField::Architecture) == \"Name\");\r\n    REQUIRE(normalizedName2.GetNormalizedFields() == NormalizationField::None);\r\n}"
  },
  {
    "path": "src/AppInstallerCLITests/PackageCollection.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"TestCommon.h\"\n\n#include <winget/Regex.h>\n#include <PackageCollection.h>\n\n// Duplicating here because a change to these values in the product *REALLY* needs to be thought through.\nusing namespace std::string_literals;\nusing namespace std::string_view_literals;\n\nusing namespace AppInstaller::CLI;\nusing namespace AppInstaller::Repository;\nusing namespace AppInstaller::Utility;\n\nconst std::string s_PackagesJson_Schema = \"$schema\";\nconst std::string s_PackagesJson_SchemaUri_v2_0 = \"https://aka.ms/winget-packages.schema.2.0.json\";\nconst std::string s_PackagesJson_WinGetVersion = \"WinGetVersion\";\nconst std::string s_PackagesJson_CreationDate = \"CreationDate\";\n\nconst std::string s_PackagesJson_Sources = \"Sources\";\nconst std::string s_PackagesJson_Source_Details = \"SourceDetails\";\nconst std::string s_PackagesJson_Source_Name = \"Name\";\nconst std::string s_PackagesJson_Source_Identifier = \"Identifier\";\nconst std::string s_PackagesJson_Source_Argument = \"Argument\";\nconst std::string s_PackagesJson_Source_Type = \"Type\";\n\nconst std::string s_PackagesJson_Packages = \"Packages\";\nconst std::string s_PackagesJson_Package_PackageIdentifier = \"PackageIdentifier\";\nconst std::string s_PackagesJson_Package_Version = \"Version\";\nconst std::string s_PackagesJson_Package_Channel = \"Channel\";\n\nnamespace\n{\n\n    Json::Value ParseJsonString(const std::string& jsonString)\n    {\n        Json::Value root;\n        std::stringstream{ jsonString } >> root;\n        return root;\n    }\n\n    void ValidateJsonStringProperty(const Json::Value& node, const std::string& propertyName, std::string_view expectedValue, bool allowMissing = false)\n    {\n        if (allowMissing && expectedValue.empty() && !node.isMember(propertyName))\n        {\n            return;\n        }\n\n        REQUIRE(node.isMember(propertyName));\n        REQUIRE(node[propertyName].isString());\r\n        if (!expectedValue.empty())\r\n        {\r\n            REQUIRE(node[propertyName].asString() == expectedValue);\r\n        }\n    }\n\n    const Json::Value& GetAndValidateJsonProperty(const Json::Value& node, const std::string& propertyName, Json::ValueType valueType)\n    {\n        REQUIRE(node.isMember(propertyName));\n        REQUIRE(node[propertyName].type() == valueType);\n        return node[propertyName];\n    }\n\n    void ValidateJsonWithCollection(const Json::Value& root, const PackageCollection& collection)\n    {\n        ValidateJsonStringProperty(root, s_PackagesJson_Schema, s_PackagesJson_SchemaUri_v2_0);\n        ValidateJsonStringProperty(root, s_PackagesJson_WinGetVersion, collection.ClientVersion);\n        // valijson now validates the date-time format, just check the string property exists.\n        ValidateJsonStringProperty(root, s_PackagesJson_CreationDate, \"\");\n\n        const auto& jsonSources = GetAndValidateJsonProperty(root, s_PackagesJson_Sources, Json::ValueType::arrayValue);\n        REQUIRE(jsonSources.size() == collection.Sources.size());\n\n        // Expect the order to be the same. Not really needed, but it makes things easier.\n        auto jsonSourceItr = jsonSources.begin();\n        auto sourceItr = collection.Sources.begin();\n        for (; jsonSourceItr != jsonSources.end(); ++jsonSourceItr, ++sourceItr)\n        {\n            REQUIRE(jsonSourceItr->isObject());\n            const auto& jsonSourceDetails = GetAndValidateJsonProperty(*jsonSourceItr, s_PackagesJson_Source_Details, Json::ValueType::objectValue);\n            ValidateJsonStringProperty(jsonSourceDetails, s_PackagesJson_Source_Name, sourceItr->Details.Name);\n            ValidateJsonStringProperty(jsonSourceDetails, s_PackagesJson_Source_Argument, sourceItr->Details.Arg);\n            ValidateJsonStringProperty(jsonSourceDetails, s_PackagesJson_Source_Type, sourceItr->Details.Type);\n            ValidateJsonStringProperty(jsonSourceDetails, s_PackagesJson_Source_Identifier, sourceItr->Details.Identifier);\n\n            const auto& jsonPackages = GetAndValidateJsonProperty(*jsonSourceItr, s_PackagesJson_Packages, Json::ValueType::arrayValue);\n            REQUIRE(jsonPackages.size() == sourceItr->Packages.size());\n\n            auto jsonPackageItr = jsonPackages.begin();\n            auto packageItr = sourceItr->Packages.begin();\n            for (; jsonPackageItr != jsonPackages.end(); ++jsonPackageItr, ++packageItr)\n            {\n                REQUIRE(jsonPackageItr->isObject());\n                ValidateJsonStringProperty(*jsonPackageItr, s_PackagesJson_Package_PackageIdentifier, packageItr->Id);\n                ValidateJsonStringProperty(*jsonPackageItr, s_PackagesJson_Package_Version, packageItr->VersionAndChannel.GetVersion().ToString(), true);\n                ValidateJsonStringProperty(*jsonPackageItr, s_PackagesJson_Package_Channel, packageItr->VersionAndChannel.GetChannel().ToString(), true);\n            }\n        }\n    }\n\n    void ValidateEqualCollections(const PackageCollection& first, const PackageCollection& second)\n    {\n        REQUIRE(first.ClientVersion == second.ClientVersion);\n        REQUIRE(first.Sources.size() == second.Sources.size());\n\n        auto firstSourceItr = first.Sources.begin();\n        auto secondSourceItr = second.Sources.begin();\n        for (; firstSourceItr != first.Sources.end(); ++firstSourceItr, ++secondSourceItr)\n        {\n            REQUIRE(firstSourceItr->Details.Name == secondSourceItr->Details.Name);\n            REQUIRE(firstSourceItr->Details.Arg == secondSourceItr->Details.Arg);\n            REQUIRE(firstSourceItr->Details.Type == secondSourceItr->Details.Type);\n            REQUIRE(firstSourceItr->Details.Identifier == secondSourceItr->Details.Identifier);\n\n            REQUIRE(firstSourceItr->Packages.size() == secondSourceItr->Packages.size());\n            auto firstPackageItr = firstSourceItr->Packages.begin();\n            auto secondPackageItr = secondSourceItr->Packages.begin();\n            for (; firstPackageItr != firstSourceItr->Packages.end(); ++firstPackageItr, ++secondPackageItr)\n            {\n                REQUIRE(firstPackageItr->Id == secondPackageItr->Id);\n                REQUIRE(firstPackageItr->VersionAndChannel.ToString() == secondPackageItr->VersionAndChannel.ToString());\n            }\n        }\n    }\n}\n\nTEST_CASE(\"PackageCollection_Write_SingleSource\", \"[PackageCollection]\")\n{\n    PackageCollection::Source source;\n    source.Details.Name = \"TestSource\";\n    source.Details.Arg = \"https://aka.ms/winget\";\n    source.Details.Type = \"Microsoft.PreIndexed.Package\";\n    source.Details.Identifier = \"TestSourceId\";\n\n    source.Packages.emplace_back(LocIndString{ \"test.package1\"sv }, Version{ \"1.0.1\" }, Channel{ \"\" });\n    source.Packages.emplace_back(LocIndString{ \"test.package2\"sv }, Version{ \"2\" }, Channel{ \"Public\" });\n\n    PackageCollection pc\n    {\n        \"0.1.2.3\",\n        std::vector<PackageCollection::Source>{ source }\n    };\n\n    ValidateJsonWithCollection(PackagesJson::CreateJson(pc), pc);\n}\n\nTEST_CASE(\"PackageCollection_Write_MultipleSources\", \"[PackageCollection]\")\n{\n    PackageCollection::Source source1;\n    source1.Details.Name = \"TestSource\";\n    source1.Details.Arg = \"https://aka.ms/winget\";\n    source1.Details.Type = \"Microsoft.PreIndexed.Package\";\n    source1.Details.Identifier = \"TestSourceId\";\n    source1.Packages.emplace_back(LocIndString{ \"test.package1\"sv }, Version{ \"1.0.1\" }, Channel{ \"\" });\n\n    PackageCollection::Source source2;\n    source2.Details.Name = \"TestSource2\";\n    source2.Details.Arg = \"https://aka.ms/winget\";\n    source2.Details.Type = \"*Test\";\n    source2.Details.Identifier = \"SecondId\";\n    source2.Packages.emplace_back(LocIndString{ \"test.package2\"sv }, Version{ \"2.1.0\" }, Channel{ \"Beta\" });\n\n    PackageCollection pc\n    {\n        \"1.0.0.0\",\n        std::vector<PackageCollection::Source>{ source1, source2 }\n    };\n\n    ValidateJsonWithCollection(PackagesJson::CreateJson(pc), pc);\n}\n\nTEST_CASE(\"PackageCollection_Read_SingleSource_1_0\", \"[PackageCollection]\")\n{\n    auto json = ParseJsonString(R\"(\n    {\n      \"$schema\": \"https://aka.ms/winget-packages.schema.1.0.json\",\n      \"CreationDate\": \"2021-01-01T12:00:00.000-00:00\",\n      \"Sources\": [\n        {\n          \"Packages\": [\n            {\n              \"Id\": \"test.WithVersion\",\n              \"Version\": \"0.1\",\n              \"Channel\": \"Preview\"\n            },\n            {\n              \"Id\": \"test.NoVersion\"\n            }\n          ],\n          \"SourceDetails\": {\n            \"Argument\": \"https://aka.ms/winget\",\n            \"Identifier\": \"TestSourceId\",\n            \"Name\": \"TestSource\",\n            \"Type\": \"Microsoft.PreIndexed.Package\"\n          }\n        }\n      ],\n      \"WinGetVersion\": \"1.0.0\"\n    })\");\n\n    auto parseResult = PackagesJson::TryParseJson(json);\n    REQUIRE(parseResult.Result == PackagesJson::ParseResult::Type::Success);\n    REQUIRE(parseResult.Errors.empty());\n\n    PackageCollection::Source source;\n    source.Details.Name = \"TestSource\";\n    source.Details.Arg = \"https://aka.ms/winget\";\n    source.Details.Type = \"Microsoft.PreIndexed.Package\";\n    source.Details.Identifier = \"TestSourceId\";\n\n    source.Packages.emplace_back(LocIndString{ \"test.WithVersion\"sv }, Version{ \"0.1\" }, Channel{ \"Preview\" });\n    source.Packages.emplace_back(LocIndString{ \"test.NoVersion\"sv }, Version{ \"\" }, Channel{ \"\" });\n\n    PackageCollection expected\n    {\n        \"1.0.0\",\n        std::vector<PackageCollection::Source>{ source }\n    };\n\n    ValidateEqualCollections(parseResult.Packages, expected);\n}\n\nTEST_CASE(\"PackageCollection_Read_SingleSource_2_0\", \"[PackageCollection]\")\n{\n    auto json = ParseJsonString(R\"(\n    {\n      \"$schema\": \"https://aka.ms/winget-packages.schema.2.0.json\",\n      \"CreationDate\": \"2021-01-01T12:00:00.000-00:00\",\n      \"Sources\": [\n        {\n          \"Packages\": [\n            {\n              \"PackageIdentifier\": \"test.WithVersion\",\n              \"Version\": \"0.1\",\n              \"Channel\": \"Preview\"\n            },\n            {\n              \"PackageIdentifier\": \"test.NoVersion\"\n            }\n          ],\n          \"SourceDetails\": {\n            \"Argument\": \"https://aka.ms/winget\",\n            \"Identifier\": \"TestSourceId\",\n            \"Name\": \"TestSource\",\n            \"Type\": \"Microsoft.PreIndexed.Package\"\n          }\n        }\n      ]\n    })\");\n\n    auto parseResult = PackagesJson::TryParseJson(json);\n    REQUIRE(parseResult.Result == PackagesJson::ParseResult::Type::Success);\n    REQUIRE(parseResult.Errors.empty());\n\n    PackageCollection::Source source;\n    source.Details.Name = \"TestSource\";\n    source.Details.Arg = \"https://aka.ms/winget\";\n    source.Details.Type = \"Microsoft.PreIndexed.Package\";\n    source.Details.Identifier = \"TestSourceId\";\n\n    source.Packages.emplace_back(LocIndString{ \"test.WithVersion\"sv }, Version{ \"0.1\" }, Channel{ \"Preview\" });\n    source.Packages.emplace_back(LocIndString{ \"test.NoVersion\"sv }, Version{ \"\" }, Channel{ \"\" });\n\n    PackageCollection expected\n    {\n        \"\",\n        std::vector<PackageCollection::Source>{ source }\n    };\n\n    ValidateEqualCollections(parseResult.Packages, expected);\n}\n\nTEST_CASE(\"PackageCollection_Read_MultipleSources_1_0\", \"[PackageCollection]\")\n{\n    auto json = ParseJsonString(R\"(\n    {\n      \"$schema\": \"https://aka.ms/winget-packages.schema.1.0.json\",\n      \"CreationDate\": \"2021-01-01T12:00:00.000-00:00\",\n      \"WinGetVersion\": \"1.0.0\",\n      \"Sources\": [\n        {\n          \"SourceDetails\": {\n            \"Argument\": \"//firstSource\",\n            \"Identifier\": \"Id1\",\n            \"Name\": \"First\",\n            \"Type\": \"Microsoft.PreIndexed.Package\"\n          },\n          \"Packages\": [\n            {\n              \"Id\": \"test\"\n            }\n          ]\n        },\n        {\n          \"SourceDetails\": {\n            \"Argument\": \"//secondSource\",\n            \"Identifier\": \"Id2\",\n            \"Name\": \"Second\",\n            \"Type\": \"*TestSource\"\n          },\n          \"Packages\": [\n            {\n              \"Id\": \"test2\",\n              \"Version\": \"1.0\"\n            }\n          ]\n        }\n      ]\n    })\");\n\n\n    auto parseResult = PackagesJson::TryParseJson(json);\n    REQUIRE(parseResult.Result == PackagesJson::ParseResult::Type::Success);\n    REQUIRE(parseResult.Errors.empty());\n\n    PackageCollection::Source source1;\n    source1.Details.Name = \"First\";\n    source1.Details.Arg = \"//firstSource\";\n    source1.Details.Type = \"Microsoft.PreIndexed.Package\";\n    source1.Details.Identifier = \"Id1\";\n    source1.Packages.emplace_back(LocIndString{ \"test\"sv }, Version{ \"\" }, Channel{ \"\" });\n\n    PackageCollection::Source source2;\n    source2.Details.Name = \"Second\";\n    source2.Details.Arg = \"//secondSource\";\n    source2.Details.Type = \"*TestSource\";\n    source2.Details.Identifier = \"Id2\";\n    source2.Packages.emplace_back(LocIndString{ \"test2\"sv }, Version{ \"1.0\" }, Channel{ \"\" });\n\n    PackageCollection expected\n    {\n        \"1.0.0\",\n        std::vector<PackageCollection::Source>{ source1, source2 }\n    };\n\n    ValidateEqualCollections(parseResult.Packages, expected);\n}\n\nTEST_CASE(\"PackageCollection_Read_MultipleSources_2_0\", \"[PackageCollection]\")\n{\n    auto json = ParseJsonString(R\"(\n    {\n      \"$schema\": \"https://aka.ms/winget-packages.schema.2.0.json\",\n      \"CreationDate\": \"2021-01-01T12:00:00.000-00:00\",\n      \"WinGetVersion\": \"1.0.0\",\n      \"Sources\": [\n        {\n          \"SourceDetails\": {\n            \"Argument\": \"//firstSource\",\n            \"Identifier\": \"Id1\",\n            \"Name\": \"First\",\n            \"Type\": \"Microsoft.PreIndexed.Package\"\n          },\n          \"Packages\": [\n            {\n              \"PackageIdentifier\": \"test\"\n            }\n          ]\n        },\n        {\n          \"SourceDetails\": {\n            \"Argument\": \"//secondSource\",\n            \"Identifier\": \"Id2\",\n            \"Name\": \"Second\",\n            \"Type\": \"*TestSource\"\n          },\n          \"Packages\": [\n            {\n              \"PackageIdentifier\": \"test2\",\n              \"Version\": \"1.0\"\n            }\n          ]\n        }\n      ]\n    })\");\n\n\n    auto parseResult = PackagesJson::TryParseJson(json);\n    REQUIRE(parseResult.Result == PackagesJson::ParseResult::Type::Success);\n    REQUIRE(parseResult.Errors.empty());\n\n    PackageCollection::Source source1;\n    source1.Details.Name = \"First\";\n    source1.Details.Arg = \"//firstSource\";\n    source1.Details.Type = \"Microsoft.PreIndexed.Package\";\n    source1.Details.Identifier = \"Id1\";\n    source1.Packages.emplace_back(LocIndString{ \"test\"sv }, Version{ \"\" }, Channel{ \"\" });\n\n    PackageCollection::Source source2;\n    source2.Details.Name = \"Second\";\n    source2.Details.Arg = \"//secondSource\";\n    source2.Details.Type = \"*TestSource\";\n    source2.Details.Identifier = \"Id2\";\n    source2.Packages.emplace_back(LocIndString{ \"test2\"sv }, Version{ \"1.0\" }, Channel{ \"\" });\n\n    PackageCollection expected\n    {\n        \"1.0.0\",\n        std::vector<PackageCollection::Source>{ source1, source2 }\n    };\n\n    ValidateEqualCollections(parseResult.Packages, expected);\n}\n\nTEST_CASE(\"PackageCollection_Read_RepeatedSource\", \"[PackageCollection]\")\n{\n    auto json = ParseJsonString(R\"(\n    {\n      \"$schema\": \"https://aka.ms/winget-packages.schema.1.0.json\",\n      \"CreationDate\": \"2021-01-01T12:00:00.000-00:00\",\n      \"WinGetVersion\": \"1.0.0\",\n      \"Sources\": [\n        {\n          \"SourceDetails\": {\n            \"Argument\": \"//firstSource\",\n            \"Identifier\": \"Id1\",\n            \"Name\": \"First\",\n            \"Type\": \"Microsoft.PreIndexed.Package\"\n          },\n          \"Packages\": [\n            {\n              \"Id\": \"test\"\n            }\n          ]\n        },\n        {\n          \"SourceDetails\": {\n            \"Argument\": \"//secondSource\",\n            \"Identifier\": \"Id2\",\n            \"Name\": \"Second\",\n            \"Type\": \"*TestSource\"\n          },\n          \"Packages\": [\n            {\n              \"Id\": \"test2\",\n              \"Version\": \"1.0\"\n            }\n          ]\n        },\n        {\n          \"SourceDetails\": {\n            \"Argument\": \"//secondSource\",\n            \"Identifier\": \"Id2\",\n            \"Name\": \"Second\",\n            \"Type\": \"*TestSource\"\n          },\n          \"Packages\": [\n            {\n              \"Id\": \"test3\",\n              \"Version\": \"1.2\"\n            }\n          ]\n        }\n      ]\n    })\");\n\n\n    auto parseResult = PackagesJson::TryParseJson(json);\n    REQUIRE(parseResult.Result == PackagesJson::ParseResult::Type::Success);\n    REQUIRE(parseResult.Errors.empty());\n\n    PackageCollection::Source source1;\n    source1.Details.Name = \"First\";\n    source1.Details.Arg = \"//firstSource\";\n    source1.Details.Type = \"Microsoft.PreIndexed.Package\";\n    source1.Details.Identifier = \"Id1\";\n    source1.Packages.emplace_back(LocIndString{ \"test\"sv }, Version{ \"\" }, Channel{ \"\" });\n\n    PackageCollection::Source source2;\n    source2.Details.Name = \"Second\";\n    source2.Details.Arg = \"//secondSource\";\n    source2.Details.Type = \"*TestSource\";\n    source2.Details.Identifier = \"Id2\";\n    source2.Packages.emplace_back(LocIndString{ \"test2\"sv }, Version{ \"1.0\" }, Channel{ \"\" });\n    source2.Packages.emplace_back(LocIndString{ \"test3\"sv }, Version{ \"1.2\" }, Channel{ \"\" });\n\n    PackageCollection expected\n    {\n        \"1.0.0\",\n        std::vector<PackageCollection::Source>{ source1, source2 }\n    };\n\n    ValidateEqualCollections(parseResult.Packages, expected);\n}\n\nTEST_CASE(\"PackageCollection_Read_MissingSchema\", \"[PackageCollection]\")\n{\n    auto json = ParseJsonString(R\"(\n    {\n      \"CreationDate\": \"2021-01-01T12:00:00.000-00:00\",\n      \"Sources\": [\n        {\n          \"Packages\": [\n            {\n              \"Id\": \"test.test\"\n            }\n          ],\n          \"SourceDetails\": {\n            \"Argument\": \"https://aka.ms/winget\",\n            \"Identifier\": \"TestSourceId\",\n            \"Name\": \"TestSource\",\n            \"Type\": \"Microsoft.PreIndexed.Package\"\n          }\n        }\n      ],\n      \"WinGetVersion\": \"1.0.0\"\n    })\");\n\n    auto parseResult = PackagesJson::TryParseJson(json);\n    REQUIRE(parseResult.Result == PackagesJson::ParseResult::Type::MissingSchema);\n\n    json = ParseJsonString(\"\\\"Not even a JSON object\\\"\");\n\n    parseResult = PackagesJson::TryParseJson(json);\n    REQUIRE(parseResult.Result == PackagesJson::ParseResult::Type::MissingSchema);\n}\n\nTEST_CASE(\"PackageCollection_Read_WrongSchema\", \"[PackageCollection]\")\n{\n    auto json = ParseJsonString(R\"(\n    {\n      \"$schema\": \"https://aka.ms/winget-settings.schema.json\",\n      \"CreationDate\": \"2021-01-01T12:00:00.000-00:00\",\n      \"Sources\": [\n        {\n          \"Packages\": [\n            {\n              \"Id\": \"test.test\"\n            }\n          ],\n          \"SourceDetails\": {\n            \"Argument\": \"https://aka.ms/winget\",\n            \"Identifier\": \"TestSourceId\",\n            \"Name\": \"TestSource\",\n            \"Type\": \"Microsoft.PreIndexed.Package\"\n          }\n        }\n      ],\n      \"WinGetVersion\": \"1.0.0\"\n    })\");\n\n    auto parseResult = PackagesJson::TryParseJson(json);\n    REQUIRE(parseResult.Result == PackagesJson::ParseResult::Type::UnrecognizedSchema);\n}\n\nTEST_CASE(\"PackageCollection_Read_SchemaValidationFail\", \"[PackageCollection]\")\n{\n    auto json = ParseJsonString(R\"(\n    {\n      \"$schema\": \"https://aka.ms/winget-packages.schema.1.0.json\",\n      \"CreationDate\": \"2021-01-01T12:00:00.000-00:00\",\n      \"NotSources\": [\n        {\n          \"Packages\": [\n            {\n              \"Id\": \"test.test\"\n            }\n          ],\n          \"SourceDetails\": {\n            \"Argument\": \"https://aka.ms/winget\",\n            \"Identifier\": \"TestSourceId\",\n            \"Name\": \"TestSource\",\n            \"Type\": \"Microsoft.PreIndexed.Package\"\n          }\n        }\n      ],\n      \"WinGetVersion\": \"1.0.0\"\n    })\");\n\n    auto parseResult = PackagesJson::TryParseJson(json);\n    INFO(parseResult.Errors);\n\n    REQUIRE(parseResult.Result == PackagesJson::ParseResult::Type::SchemaValidationFailed);\n    REQUIRE(parseResult.Errors.find(\"Missing required property 'Sources'.\") != std::string::npos);\n}\n\nTEST_CASE(\"PackageCollection_Read_SchemaValidationFail_Id\", \"[PackageCollection]\")\n{\n    auto json = ParseJsonString(R\"(\n    {\n      \"$schema\": \"https://aka.ms/winget-packages.schema.1.0.json\",\n      \"CreationDate\": \"2021-01-01T12:00:00.000-00:00\",\n      \"Sources\": [\n        {\n          \"Packages\": [\n            {\n              \"NotId\": \"test.test\"\n            }\n          ],\n          \"SourceDetails\": {\n            \"Argument\": \"https://aka.ms/winget\",\n            \"Identifier\": \"TestSourceId\",\n            \"Name\": \"TestSource\",\n            \"Type\": \"Microsoft.PreIndexed.Package\"\n          }\n        }\n      ],\n      \"WinGetVersion\": \"1.0.0\"\n    })\");\n\n    auto parseResult = PackagesJson::TryParseJson(json);\n    INFO(parseResult.Errors);\n\n    REQUIRE(parseResult.Result == PackagesJson::ParseResult::Type::SchemaValidationFailed);\n    REQUIRE(parseResult.Errors.find(\"Missing required property 'Id'.\") != std::string::npos);\n}\n\nTEST_CASE(\"PackageCollection_Read_BadTimeStamp\", \"[PackageCollection]\")\n{\n    auto json = ParseJsonString(R\"(\n    {\n      \"$schema\": \"https://aka.ms/winget-packages.schema.1.0.json\",\n      \"CreationDate\": \"2021- 1- 1 12:00:00.000\",\n      \"Sources\": [\n        {\n          \"Packages\": [\n            {\n              \"Id\": \"test\"\n            }\n          ],\n          \"SourceDetails\": {\n            \"Argument\": \"https://aka.ms/winget\",\n            \"Identifier\": \"TestSourceId\",\n            \"Name\": \"TestSource\",\n            \"Type\": \"Microsoft.PreIndexed.Package\"\n          }\n        }\n      ],\n      \"WinGetVersion\": \"1.0.0\"\n    })\");\n\n    auto parseResult = PackagesJson::TryParseJson(json);\n    INFO(parseResult.Errors);\n\n    REQUIRE(parseResult.Result == PackagesJson::ParseResult::Type::SchemaValidationFailed);\r\n    REQUIRE_FALSE(parseResult.Errors.empty());\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/PackageDependenciesValidationUtil.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"TestCommon.h\"\n#include \"TestSource.h\"\n#include <public/winget/PackageDependenciesValidationUtil.h>\n\nusing namespace AppInstaller::Manifest;\n\nTEST_CASE(\"GetValidationResultFromException\", \"[PackageDependenciesValidationUtil][dependencies]\")\n{\n    std::map<WinGetManifestDependenciesErrorResult, const ManifestException> dependenciesErrorMessageMap =\n    {\n        { WinGetManifestDependenciesErrorResult::SingleManifestPackageHasDependencies, ManifestException {  { ManifestError::SingleManifestPackageHasDependencies }, APPINSTALLER_CLI_ERROR_MANIFEST_FAILED } },\n        { WinGetManifestDependenciesErrorResult::MultiManifestPackageHasDependencies, ManifestException {  { ManifestError::MultiManifestPackageHasDependencies }, APPINSTALLER_CLI_ERROR_MANIFEST_FAILED } },\n        { WinGetManifestDependenciesErrorResult::MissingManifestDependenciesNode, ManifestException {  { ManifestError::MissingManifestDependenciesNode }, APPINSTALLER_CLI_ERROR_MANIFEST_FAILED } },\n        { WinGetManifestDependenciesErrorResult::NoSuitableMinVersionDependency, ManifestException {  { ManifestError::NoSuitableMinVersionDependency }, APPINSTALLER_CLI_ERROR_MANIFEST_FAILED } },\n        { WinGetManifestDependenciesErrorResult::FoundDependencyLoop, ManifestException {  { ManifestError::FoundDependencyLoop }, APPINSTALLER_CLI_ERROR_MANIFEST_FAILED } },\n    };\n\n    for (auto current : dependenciesErrorMessageMap)\n    {\n        REQUIRE(GetDependenciesValidationResultFromException(current.second) == current.first);\n    }\n}"
  },
  {
    "path": "src/AppInstallerCLITests/PackageTrackingCatalog.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <Microsoft/SQLiteIndexSource.h>\r\n#include <winget/ManifestYamlParser.h>\r\n#include <winget/PackageTrackingCatalog.h>\r\n\r\nusing namespace std::string_literals;\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Repository::Microsoft;\r\nusing namespace AppInstaller::SQLite;\r\nusing namespace AppInstaller::Utility;\r\n\r\nnamespace\r\n{\r\n    static Source SimpleTestSetup(const std::string& filePath, SourceDetails& details, Manifest& manifest, std::string& relativePath)\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::CreateNew(filePath, AppInstaller::SQLite::Version::Latest(), SQLiteIndex::CreateOptions::SupportPathless | SQLiteIndex::CreateOptions::DisableDependenciesSupport);\r\n\r\n        TestDataFile testManifest(\"Manifest-Good.yaml\");\r\n        manifest = YamlParser::CreateFromPath(testManifest);\r\n\r\n        relativePath = testManifest.GetPath().filename().u8string();\r\n\r\n        index.AddManifest(manifest, relativePath);\r\n\r\n        details.Identifier = \"*SimpleTestSetup\";\r\n        details.Name = \"TestName\";\r\n        details.Type = \"TestType\";\r\n        details.Arg = testManifest.GetPath().parent_path().u8string();\r\n        details.Data = \"\";\r\n\r\n        auto result = std::make_shared<SQLiteIndexSource>(details, std::move(index));\r\n\r\n        PackageTrackingCatalog::RemoveForSource(result->GetIdentifier());\r\n\r\n        return { result };\r\n    }\r\n\r\n    struct TestCatalog : public PackageTrackingCatalog\r\n    {\r\n        using PackageTrackingCatalog::CreateForSource;\r\n    };\r\n\r\n    PackageTrackingCatalog CreatePackageTrackingCatalogForSource(const Source& source)\r\n    {\r\n        return TestCatalog::CreateForSource(source);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"TrackingCatalog_Create\", \"[tracking_catalog]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SourceDetails details;\r\n    Manifest manifest;\r\n    std::string relativePath;\r\n    auto source = SimpleTestSetup(tempFile, details, manifest, relativePath);\r\n\r\n    PackageTrackingCatalog catalog = CreatePackageTrackingCatalogForSource(source);\r\n}\r\n\r\nTEST_CASE(\"TrackingCatalog_Install\", \"[tracking_catalog]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SourceDetails details;\r\n    Manifest manifest;\r\n    std::string relativePath;\r\n    auto source = SimpleTestSetup(tempFile, details, manifest, relativePath);\r\n\r\n    PackageTrackingCatalog catalog = CreatePackageTrackingCatalogForSource(source);\r\n\r\n    SearchRequest request;\r\n    request.Filters.emplace_back(PackageMatchField::Id, MatchType::Exact, manifest.Id);\r\n\r\n    SearchResult resultBefore = catalog.Search(request);\r\n    REQUIRE(resultBefore.Matches.size() == 0);\r\n\r\n    catalog.RecordInstall(manifest, manifest.Installers[0], false);\r\n\r\n    SearchResult resultAfter = catalog.Search(request);\r\n    REQUIRE(resultAfter.Matches.size() == 1);\r\n    REQUIRE(resultAfter.Matches[0].Package->GetAvailable().size() == 1);\r\n\r\n    auto trackingVersion = resultAfter.Matches[0].Package->GetAvailable()[0]->GetLatestVersion();\r\n    REQUIRE(trackingVersion);\r\n\r\n    auto metadata = trackingVersion->GetMetadata();\r\n    REQUIRE(metadata.find(PackageVersionMetadata::TrackingWriteTime) != metadata.end());\r\n}\r\n\r\nTEST_CASE(\"TrackingCatalog_Reinstall\", \"[tracking_catalog]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SourceDetails details;\r\n    Manifest manifest;\r\n    std::string relativePath;\r\n    auto source = SimpleTestSetup(tempFile, details, manifest, relativePath);\r\n\r\n    PackageTrackingCatalog catalog = CreatePackageTrackingCatalogForSource(source);\r\n\r\n    SearchRequest request;\r\n    request.Filters.emplace_back(PackageMatchField::Id, MatchType::Exact, manifest.Id);\r\n\r\n    catalog.RecordInstall(manifest, manifest.Installers[0], false);\r\n\r\n    SearchResult resultBefore = catalog.Search(request);\r\n    REQUIRE(resultBefore.Matches.size() == 1);\r\n    REQUIRE(resultBefore.Matches[0].Package->GetAvailable().size() == 1);\r\n    REQUIRE(resultBefore.Matches[0].Package->GetAvailable()[0]->GetLatestVersion()->GetProperty(PackageVersionProperty::Name) ==\r\n        manifest.DefaultLocalization.Get<Localization::PackageName>());\r\n\r\n    // Change name\r\n    std::string newName = \"New Package Name\";\r\n    manifest.DefaultLocalization.Add<Localization::PackageName>(newName);\r\n\r\n    catalog.RecordInstall(manifest, manifest.Installers[0], false);\r\n\r\n    SearchResult resultAfter = catalog.Search(request);\r\n    REQUIRE(resultAfter.Matches.size() == 1);\r\n    REQUIRE(resultAfter.Matches[0].Package->GetAvailable().size() == 1);\r\n    REQUIRE(resultAfter.Matches[0].Package->GetAvailable()[0]->GetLatestVersion()->GetProperty(PackageVersionProperty::Name) ==\r\n        newName);\r\n}\r\n\r\nTEST_CASE(\"TrackingCatalog_Upgrade\", \"[tracking_catalog]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SourceDetails details;\r\n    Manifest manifest;\r\n    std::string relativePath;\r\n    auto source = SimpleTestSetup(tempFile, details, manifest, relativePath);\r\n\r\n    PackageTrackingCatalog catalog = CreatePackageTrackingCatalogForSource(source);\r\n\r\n    SearchRequest request;\r\n    request.Filters.emplace_back(PackageMatchField::Id, MatchType::Exact, manifest.Id);\r\n\r\n    catalog.RecordInstall(manifest, manifest.Installers[0], false);\r\n\r\n    SearchResult resultBefore = catalog.Search(request);\r\n    REQUIRE(resultBefore.Matches.size() == 1);\r\n    REQUIRE(resultBefore.Matches[0].Package->GetAvailable().size() == 1);\r\n    REQUIRE(resultBefore.Matches[0].Package->GetAvailable()[0]->GetLatestVersion()->GetProperty(PackageVersionProperty::Version) ==\r\n        manifest.Version);\r\n\r\n    // Change version\r\n    manifest.Version = \"99.1.2.3\";\r\n\r\n    catalog.RecordInstall(manifest, manifest.Installers[0], true);\r\n\r\n    SearchResult resultAfter = catalog.Search(request);\r\n    REQUIRE(resultAfter.Matches.size() == 1);\r\n    REQUIRE(resultAfter.Matches[0].Package->GetAvailable().size() == 1);\r\n    REQUIRE(resultAfter.Matches[0].Package->GetAvailable()[0]->GetLatestVersion()->GetProperty(PackageVersionProperty::Version) ==\r\n        manifest.Version);\r\n}\r\n\r\nTEST_CASE(\"TrackingCatalog_Uninstall\", \"[tracking_catalog]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SourceDetails details;\r\n    Manifest manifest;\r\n    std::string relativePath;\r\n    auto source = SimpleTestSetup(tempFile, details, manifest, relativePath);\r\n\r\n    PackageTrackingCatalog catalog = CreatePackageTrackingCatalogForSource(source);\r\n\r\n    SearchRequest request;\r\n    request.Filters.emplace_back(PackageMatchField::Id, MatchType::Exact, manifest.Id);\r\n\r\n    catalog.RecordInstall(manifest, manifest.Installers[0], false);\r\n\r\n    SearchResult resultBefore = catalog.Search(request);\r\n    REQUIRE(resultBefore.Matches.size() == 1);\r\n\r\n    catalog.RecordUninstall(LocIndString{ manifest.Id });\r\n\r\n    SearchResult resultAfter = catalog.Search(request);\r\n    REQUIRE(resultAfter.Matches.size() == 0);\r\n}\r\n\r\nTEST_CASE(\"TrackingCatalog_Overlapping_ARP_Range\", \"[tracking_catalog]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SourceDetails details;\r\n    Manifest manifest;\r\n    std::string relativePath;\r\n    auto source = SimpleTestSetup(tempFile, details, manifest, relativePath);\r\n\r\n    REQUIRE(manifest.Installers.size() >= 2);\r\n    AppsAndFeaturesEntry appEntry{};\r\n    appEntry.DisplayVersion = \"1.23\";\r\n    manifest.Installers[0].AppsAndFeaturesEntries.emplace_back(appEntry);\r\n    appEntry.DisplayVersion = \"1.24\";\r\n    manifest.Installers[1].AppsAndFeaturesEntries.emplace_back(appEntry);\r\n\r\n    PackageTrackingCatalog catalog = CreatePackageTrackingCatalogForSource(source);\r\n\r\n    SearchRequest request;\r\n    request.Filters.emplace_back(PackageMatchField::Id, MatchType::Exact, manifest.Id);\r\n\r\n    catalog.RecordInstall(manifest, manifest.Installers[0], false);\r\n\r\n    SearchResult resultBefore = catalog.Search(request);\r\n    REQUIRE(resultBefore.Matches.size() == 1);\r\n    REQUIRE(resultBefore.Matches[0].Package->GetAvailable().size() == 1);\r\n    REQUIRE(resultBefore.Matches[0].Package->GetAvailable()[0]->GetLatestVersion()->GetProperty(PackageVersionProperty::Version) ==\r\n        manifest.Version);\r\n\r\n    // Change version\r\n    manifest.Version = \"99.1.2.3\";\r\n\r\n    catalog.RecordInstall(manifest, manifest.Installers[0], true);\r\n\r\n    SearchResult resultAfter = catalog.Search(request);\r\n    REQUIRE(resultAfter.Matches.size() == 1);\r\n    REQUIRE(resultAfter.Matches[0].Package->GetAvailable().size() == 1);\r\n    REQUIRE(resultAfter.Matches[0].Package->GetAvailable()[0]->GetLatestVersion()->GetProperty(PackageVersionProperty::Version) ==\r\n        manifest.Version);\r\n}\r\n\r\nTEST_CASE(\"TrackingCatalog_Corrupt\", \"[tracking_catalog]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SourceDetails details;\r\n    Manifest manifest;\r\n    std::string relativePath;\r\n    auto source = SimpleTestSetup(tempFile, details, manifest, relativePath);\r\n\r\n    SearchRequest request;\r\n    request.Filters.emplace_back(PackageMatchField::Id, MatchType::Exact, manifest.Id);\r\n\r\n    std::filesystem::path catalogFile;\r\n\r\n    {\r\n        // Add data to initial database\r\n        PackageTrackingCatalog catalog = CreatePackageTrackingCatalogForSource(source);\r\n\r\n        SearchResult resultBefore = catalog.Search(request);\r\n        REQUIRE(resultBefore.Matches.size() == 0);\r\n\r\n        catalog.RecordInstall(manifest, manifest.Installers[0], false);\r\n\r\n        SearchResult resultAfter = catalog.Search(request);\r\n        REQUIRE(resultAfter.Matches.size() == 1);\r\n        REQUIRE(resultAfter.Matches[0].Package->GetAvailable().size() == 1);\r\n\r\n        catalogFile = catalog.GetFilePath();\r\n    }\r\n\r\n    {\r\n        std::ofstream file{ catalogFile, std::ios_base::trunc };\r\n        file << \"Corrupted!\";\r\n    }\r\n\r\n    {\r\n        // Open database again after \"corruption\"\r\n        PackageTrackingCatalog catalog = CreatePackageTrackingCatalogForSource(source);\r\n\r\n        // Should not find anything in new database\r\n        SearchResult resultBefore = catalog.Search(request);\r\n        REQUIRE(resultBefore.Matches.size() == 0);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/PackageVersionDataManifest.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"TestCommon.h\"\n#include <winget/PackageVersionDataManifest.h>\n\nusing namespace TestCommon;\nusing namespace AppInstaller;\nusing namespace AppInstaller::Manifest;\nusing namespace AppInstaller::Utility;\n\r\nvoid RequireVersionDataEqual(const PackageVersionDataManifest::VersionData& first, const PackageVersionDataManifest::VersionData& second)\r\n{\r\n    REQUIRE(first.Version == second.Version);\r\n    REQUIRE(first.ArpMinVersion == second.ArpMinVersion);\r\n    REQUIRE(first.ArpMaxVersion == second.ArpMaxVersion);\r\n    REQUIRE(first.ManifestRelativePath == second.ManifestRelativePath);\r\n    REQUIRE(first.ManifestHash == second.ManifestHash);\r\n}\r\n\nTEST_CASE(\"PackageVersionDataManifest_Empty\", \"[PackageVersionDataManifest]\")\n{\n    PackageVersionDataManifest original;\r\n\r\n    PackageVersionDataManifest copy;\r\n    copy.Deserialize(original.Serialize());\r\n\r\n    REQUIRE(original.Versions().empty());\n    REQUIRE(copy.Versions().empty());\n}\n\nTEST_CASE(\"PackageVersionDataManifest_Single_Simple\", \"[PackageVersionDataManifest]\")\n{\n    PackageVersionDataManifest original;\r\n    original.AddVersion({ VersionAndChannel{ Version{ \"1.0\" }, Channel{} }, {}, {}, \"path\", \"hash\" });\r\n\r\n    PackageVersionDataManifest copy;\r\n    copy.Deserialize(original.Serialize());\r\n\r\n    REQUIRE(original.Versions().size() == 1);\n    REQUIRE(copy.Versions().size() == 1);\r\n\r\n    RequireVersionDataEqual(copy.Versions()[0], original.Versions()[0]);\n}\n\nTEST_CASE(\"PackageVersionDataManifest_Single_Complete\", \"[PackageVersionDataManifest]\")\n{\n    PackageVersionDataManifest original;\r\n    original.AddVersion({ VersionAndChannel{ Version{ \"1.0\" }, Channel{} }, \".99\", \"1.01\", \"path\", \"hash\"});\r\n\r\n    PackageVersionDataManifest copy;\r\n    copy.Deserialize(original.Serialize());\r\n\r\n    REQUIRE(original.Versions().size() == 1);\n    REQUIRE(copy.Versions().size() == 1);\r\n\r\n    RequireVersionDataEqual(copy.Versions()[0], original.Versions()[0]);\n}\n\nTEST_CASE(\"PackageVersionDataManifest_Multiple\", \"[PackageVersionDataManifest]\")\n{\n    PackageVersionDataManifest original;\r\n    original.AddVersion({ VersionAndChannel{ Version{ \"1.0\" }, Channel{} }, \".99\", \"1.01\", \"path\", \"hash\" });\r\n    original.AddVersion({ VersionAndChannel{ Version{ \"1.1\" }, Channel{} }, \"1.99\", \"2.01\", \"path2\", \"hash2\" });\r\n    original.AddVersion({ VersionAndChannel{ Version{ \"1.2\" }, Channel{} }, {}, {}, \"path2\", \"hash2\" });\r\n    original.AddVersion({ VersionAndChannel{ Version{ \"2.0\" }, Channel{} }, \"3.99\", \"15.01\", \"path4\", \"hash4\" });\r\n\r\n    PackageVersionDataManifest copy;\r\n    copy.Deserialize(original.Serialize());\r\n\r\n    REQUIRE(original.Versions().size() == copy.Versions().size());\r\n\r\n    for (size_t i = 0; i < original.Versions().size(); ++i)\r\n    {\r\n        INFO(i);\r\n        RequireVersionDataEqual(copy.Versions()[i], original.Versions()[i]);\r\n    }\n}\n\nTEST_CASE(\"PackageVersionDataManifest_CompressionRoundTrip\", \"[PackageVersionDataManifest]\")\n{\n    PackageVersionDataManifest original;\r\n    original.AddVersion({ VersionAndChannel{ Version{ \"1.0\" }, Channel{} }, \".99\", \"1.01\", \"path\", \"hash\" });\r\n    original.AddVersion({ VersionAndChannel{ Version{ \"1.1\" }, Channel{} }, \"1.99\", \"2.01\", \"path2\", \"hash2\" });\r\n    original.AddVersion({ VersionAndChannel{ Version{ \"1.2\" }, Channel{} }, {}, {}, \"path2\", \"hash2\" });\r\n    original.AddVersion({ VersionAndChannel{ Version{ \"2.0\" }, Channel{} }, \"3.99\", \"15.01\", \"path4\", \"hash4\" });\r\n\r\n    std::string serialized = original.Serialize();\r\n    auto compressed = PackageVersionDataManifest::CreateCompressor().Compress(serialized);\r\n\r\n    auto decompressed = PackageVersionDataManifest::CreateDecompressor().Decompress(compressed);\r\n\r\n    PackageVersionDataManifest copy;\r\n    copy.Deserialize(decompressed);\r\n\r\n    REQUIRE(original.Versions().size() == copy.Versions().size());\r\n\r\n    for (size_t i = 0; i < original.Versions().size(); ++i)\r\n    {\r\n        INFO(i);\r\n        RequireVersionDataEqual(copy.Versions()[i], original.Versions()[i]);\r\n    }\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/PathVariable.cpp",
    "content": "#include \"pch.h\"\n#include \"TestCommon.h\"\n#include <AppInstallerRuntime.h>\n#include <Resources.h>\n#include <winget/PathVariable.h>\n#include <winget/Filesystem.h>\n\nusing namespace AppInstaller::Manifest;\nusing namespace AppInstaller::Registry::Environment;\n\nTEST_CASE(\"PathVariable_EnforceReadOnly\", \"[pathVariable]\")\n{\n    auto pathVariable = PathVariable(ScopeEnum::User, true);\n    REQUIRE_THROWS_HR(pathVariable.Append(\"testString\"), E_ACCESSDENIED);\n    REQUIRE_THROWS_HR(pathVariable.Remove(\"testString\"), E_ACCESSDENIED);\n}\n\nTEST_CASE(\"PathVariable_Append_NoSemiColon\", \"[pathVariable]\")\n{\n    if (!AppInstaller::Runtime::IsRunningAsAdmin())\n    {\n        WARN(\"Test requires admin privilege. Skipped.\");\n        return;\n    }\n\n    auto pathVariable = PathVariable(ScopeEnum::User);\n    std::filesystem::path testPath{ \"testString\" };\n    REQUIRE_FALSE(pathVariable.Contains(testPath));\n    REQUIRE(pathVariable.Append(testPath));\n    REQUIRE(pathVariable.Contains(testPath));\n\n    // Verify that the path value ends with a ';' and not include \";;\"\n    std::string pathValue = pathVariable.GetPathValue();\n    REQUIRE(pathValue.back() == ';');\n    REQUIRE(pathValue.find(\";;\") == std::string::npos);\n\n    REQUIRE(pathVariable.Remove(testPath));\n    REQUIRE_FALSE(pathVariable.Contains(testPath));\n}\n\nTEST_CASE(\"PathVariable_Append_WithSemicolon\", \"[pathVariable]\")\n{\n    if (!AppInstaller::Runtime::IsRunningAsAdmin())\n    {\n        WARN(\"Test requires admin privilege. Skipped.\");\n        return;\n    }\n\n    auto pathVariable = PathVariable(ScopeEnum::User);\n    std::filesystem::path testPath{ \"testString;\" };\n    REQUIRE_FALSE(pathVariable.Contains(testPath));\n    REQUIRE(pathVariable.Append(testPath));\n    REQUIRE(pathVariable.Contains(testPath));\n\n    // Verify that the path value ends with a ';' and does not include \";;\"\n    std::string pathValue = pathVariable.GetPathValue();\n    REQUIRE(pathValue.back() == ';');\n    REQUIRE(pathValue.find(\";;\") == std::string::npos);\n\n    REQUIRE(pathVariable.Remove(testPath));\n    REQUIRE_FALSE(pathVariable.Contains(testPath));\n}\n\nstd::wstring GetCurrentProcessPathVariable()\n{\n    size_t requiredSize;\n    _wgetenv_s(&requiredSize, nullptr, 0, L\"PATH\");\n\n    if (requiredSize > 0)\n    {\n        auto buffer = std::make_unique<wchar_t[]>(requiredSize);\n        errno_t errorResult = _wgetenv_s(&requiredSize, buffer.get(), requiredSize, L\"PATH\");\n        if (errorResult == 0)\n        {\n            return std::wstring(buffer.get());\n        }\n    }\n    return {};\n}\n\nTEST_CASE(\"RefreshEnvironmentVariable_User\", \"[pathVariable]\")\n{\n    if (!AppInstaller::Runtime::IsRunningAsAdmin())\n    {\n        WARN(\"Test requires admin privilege. Skipped.\");\n        return;\n    }\n\n    std::wstring testPathEntry = L\"testUserPathEntry\";\n    auto pathVariable = AppInstaller::Registry::Environment::PathVariable(ScopeEnum::User);\n    pathVariable.Append(testPathEntry);\n\n    std::wstring initialPathValue = GetCurrentProcessPathVariable();\n    bool firstCheck = initialPathValue.find(testPathEntry) != std::string::npos;\n\n    AppInstaller::Registry::Environment::RefreshPathVariableForCurrentProcess();\n\n    std::wstring updatedPathValue = GetCurrentProcessPathVariable();\n    bool secondCheck = updatedPathValue.find(testPathEntry) != std::string::npos;\n\n    pathVariable.Remove(testPathEntry);\n\n    REQUIRE_FALSE(firstCheck);\n    REQUIRE(secondCheck);\n}\n\nTEST_CASE(\"RefreshEnvironmentVariable_System\", \"[pathVariable]\")\n{\n    if (!AppInstaller::Runtime::IsRunningAsAdmin())\n    {\n        WARN(\"Test requires admin privilege. Skipped.\");\n        return;\n    }\n\n    std::wstring testPathEntry = L\"testSystemPathEntry\";\n    auto pathVariable = AppInstaller::Registry::Environment::PathVariable(ScopeEnum::Machine);\n    pathVariable.Append(testPathEntry);\n\n    std::wstring initialPathValue = GetCurrentProcessPathVariable();\n    bool firstCheck = initialPathValue.find(testPathEntry) != std::string::npos;\n\n    AppInstaller::Registry::Environment::RefreshPathVariableForCurrentProcess();\n\n    std::wstring updatedPathValue = GetCurrentProcessPathVariable();\n    bool secondCheck = updatedPathValue.find(testPathEntry) != std::string::npos;\n\n    pathVariable.Remove(testPathEntry);\n\n    REQUIRE_FALSE(firstCheck);\n    REQUIRE(secondCheck);\n}\n\nTEST_CASE(\"VerifyPathRefreshExpandsValues\", \"[pathVariable]\")\n{\n    if (!AppInstaller::Runtime::IsRunningAsAdmin())\n    {\n        WARN(\"Test requires admin privilege. Skipped.\");\n        return;\n    }\n\n    std::filesystem::path testEntry{ \"%USERPROFILE%\\\\testPath\" };\n    auto pathVariable = AppInstaller::Registry::Environment::PathVariable(ScopeEnum::User);\n    pathVariable.Append(testEntry);\n\n    std::wstring initialPathValue = GetCurrentProcessPathVariable();\n    bool firstCheck = initialPathValue.find(testEntry) != std::string::npos;\n\n    AppInstaller::Registry::Environment::RefreshPathVariableForCurrentProcess();\n\n    // %USERPROFILE% should be replaced with the actual path.\n    std::wstring updatedPathValue = GetCurrentProcessPathVariable();\n    std::wstring expandedTestPath = AppInstaller::Filesystem::GetExpandedPath(testEntry.u8string());\n    bool secondCheck = updatedPathValue.find(expandedTestPath) != std::string::npos;\n\n    pathVariable.Remove(testEntry);\n\n    REQUIRE_FALSE(firstCheck);\n    REQUIRE(secondCheck);\n}\n"
  },
  {
    "path": "src/AppInstallerCLITests/PinFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"WorkflowCommon.h\"\r\n#include \"TestHooks.h\"\r\n#include <Commands/PinCommand.h>\r\n#include <Workflows/PinFlow.h>\r\n#include <Microsoft/PinningIndex.h>\r\n#include <AppInstallerRuntime.h>\r\n#include <AppInstallerVersions.h>\r\n#include <winget/PinningData.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::CLI;\r\nusing namespace AppInstaller::CLI::Workflow;\r\nusing namespace AppInstaller::Repository::Microsoft;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::Pinning;\r\nusing namespace AppInstaller::SQLite;\r\n\r\nTEST_CASE(\"PinFlow_Add\", \"[PinFlow][workflow]\")\r\n{\r\n    TempFile indexFile(\"pinningIndex\", \".db\");\r\n    TestHook::SetPinningIndex_Override pinningIndexOverride(indexFile.GetPath());\r\n\r\n    std::ostringstream pinAddOutput;\r\n    TestContext addContext{ pinAddOutput, std::cin };\r\n    OverrideForCompositeInstalledSource(addContext, CreateTestSource({ TSR::TestInstaller_Exe }));\r\n    addContext.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe.Query);\r\n    addContext.Args.AddArg(Execution::Args::Type::BlockingPin);\r\n\r\n    PinAddCommand pinAdd({});\r\n    pinAdd.Execute(addContext);\r\n    INFO(pinAddOutput.str());\r\n\r\n    SECTION(\"Pin is saved\")\r\n    {\r\n        auto index = PinningIndex::Open(indexFile.GetPath().u8string(), SQLiteStorageBase::OpenDisposition::Read);\r\n        auto pins = index.GetAllPins();\r\n        REQUIRE(pins.size() == 1);\r\n        REQUIRE(pins[0].GetType() == PinType::Blocking);\r\n        REQUIRE(pins[0].GetGatedVersion().ToString() == \"\");\r\n        REQUIRE(pins[0].GetKey().PackageId == \"AppInstallerCliTest.TestExeInstaller\");\r\n        REQUIRE(pins[0].GetKey().SourceId == \"*TestSource\");\r\n\r\n        std::ostringstream pinListOutput;\r\n        TestContext listContext{ pinListOutput, std::cin };\r\n        OverrideForCompositeInstalledSource(listContext, CreateTestSource({ TSR::TestInstaller_Exe }));\r\n        listContext.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe.Query);\r\n\r\n        PinListCommand pinList({});\r\n        pinList.Execute(listContext);\r\n\r\n        INFO(pinListOutput.str());\r\n        REQUIRE(pinListOutput.str().find(\"AppInstallerCliTest.TestExeInstaller\"));\r\n        REQUIRE(pinListOutput.str().find(\"Blocking\"));\r\n    }\r\n    SECTION(\"Remove pin\")\r\n    {\r\n        std::ostringstream pinRemoveOutput;\r\n        TestContext removeContext{ pinRemoveOutput, std::cin };\r\n        OverrideForCompositeInstalledSource(removeContext, CreateTestSource({ TSR::TestInstaller_Exe }));\r\n        removeContext.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe.Query);\r\n\r\n        PinRemoveCommand pinRemove({});\r\n        pinRemove.Execute(removeContext);\r\n        INFO(pinRemoveOutput.str());\r\n\r\n        auto index = PinningIndex::Open(indexFile.GetPath().u8string(), SQLiteStorageBase::OpenDisposition::Read);\r\n        auto pins = index.GetAllPins();\r\n        REQUIRE(pins.empty());\r\n    }\r\n    SECTION(\"Reset pins\")\r\n    {\r\n        std::ostringstream pinResetOutput;\r\n        TestContext resetContext{ pinResetOutput, std::cin };\r\n\r\n        SECTION(\"Without --force\")\r\n        {\r\n            OverrideForCompositeInstalledSource(resetContext, CreateTestSource({ TSR::TestInstaller_Exe }));\r\n            PinResetCommand pinReset({});\r\n            pinReset.Execute(resetContext);\r\n            INFO(pinResetOutput.str());\r\n\r\n            auto index = PinningIndex::Open(indexFile.GetPath().u8string(), SQLiteStorageBase::OpenDisposition::Read);\r\n            auto pins = index.GetAllPins();\r\n            REQUIRE(pins.size() == 1);\r\n        }\r\n        SECTION(\"With --force\")\r\n        {\r\n            resetContext.Args.AddArg(Execution::Args::Type::Force);\r\n\r\n            PinResetCommand pinReset({});\r\n            pinReset.Execute(resetContext);\r\n            INFO(pinResetOutput.str());\r\n\r\n            auto index = PinningIndex::Open(indexFile.GetPath().u8string(), SQLiteStorageBase::OpenDisposition::Read);\r\n            auto pins = index.GetAllPins();\r\n            REQUIRE(pins.empty());\r\n        }\r\n    }\r\n    SECTION(\"Update pin\")\r\n    {\r\n        std::ostringstream pinUpdateOutput;\r\n        TestContext updateContext{ pinUpdateOutput, std::cin };\r\n        OverrideForCompositeInstalledSource(updateContext, CreateTestSource({ TSR::TestInstaller_Exe }));\r\n        updateContext.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe.Query);\r\n\r\n        SECTION(\"Without --force\")\r\n        {\r\n            PinAddCommand pinUpdate({});\r\n            pinUpdate.Execute(updateContext);\r\n            INFO(pinUpdateOutput.str());\r\n            REQUIRE_TERMINATED_WITH(updateContext, APPINSTALLER_CLI_ERROR_PIN_ALREADY_EXISTS);\r\n\r\n            auto index = PinningIndex::Open(indexFile.GetPath().u8string(), SQLiteStorageBase::OpenDisposition::Read);\r\n            auto pins = index.GetAllPins();\r\n            REQUIRE(pins.size() == 1);\r\n            REQUIRE(pins[0].GetType() == PinType::Blocking);\r\n        }\r\n        SECTION(\"With --force\")\r\n        {\r\n            updateContext.Args.AddArg(Execution::Args::Type::Force);\r\n\r\n            PinAddCommand pinUpdate({});\r\n            pinUpdate.Execute(updateContext);\r\n            INFO(pinUpdateOutput.str());\r\n\r\n            auto index = PinningIndex::Open(indexFile.GetPath().u8string(), SQLiteStorageBase::OpenDisposition::Read);\r\n            auto pins = index.GetAllPins();\r\n            REQUIRE(pins.size() == 1);\r\n            REQUIRE(pins[0].GetType() == PinType::Pinning);\r\n        }\r\n    }\r\n}\r\n\r\nTEST_CASE(\"PinFlow_Add_NotFound\", \"[PinFlow][workflow]\")\r\n{\r\n    TempFile indexFile(\"pinningIndex\", \".db\");\r\n    TestHook::SetPinningIndex_Override pinningIndexOverride(indexFile.GetPath());\r\n\r\n    std::ostringstream pinAddOutput;\r\n    TestContext addContext{ pinAddOutput, std::cin };\r\n    OverrideForCompositeInstalledSource(addContext, CreateTestSource({}));\r\n    addContext.Args.AddArg(Execution::Args::Type::Query, \"This package doesn't exist\"sv);\r\n\r\n    PinAddCommand pinAdd({});\r\n    pinAdd.Execute(addContext);\r\n    INFO(pinAddOutput.str());\r\n\r\n    REQUIRE_TERMINATED_WITH(addContext, APPINSTALLER_CLI_ERROR_NO_APPLICATIONS_FOUND);\r\n}\r\n\r\nTEST_CASE(\"PinFlow_ListEmpty\", \"[PinFlow][workflow]\")\r\n{\r\n    TempFile indexFile(\"pinningIndex\", \".db\");\r\n    TestHook::SetPinningIndex_Override pinningIndexOverride(indexFile.GetPath());\r\n\r\n    std::ostringstream pinListOutput;\r\n    TestContext listContext{ pinListOutput, std::cin };\r\n    OverrideForCompositeInstalledSource(listContext, CreateTestSource({}));\r\n\r\n    PinListCommand pinList({});\r\n    pinList.Execute(listContext);\r\n    INFO(pinListOutput.str());\r\n\r\n     REQUIRE(pinListOutput.str().find(Resource::LocString(Resource::String::PinNoPinsExist)) != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"PinFlow_RemoveNonExisting\", \"[PinFlow][workflow]\")\r\n{\r\n    TempFile indexFile(\"pinningIndex\", \".db\");\r\n    TestHook::SetPinningIndex_Override pinningIndexOverride(indexFile.GetPath());\r\n\r\n    std::ostringstream pinRemoveOutput;\r\n    TestContext removeContext{ pinRemoveOutput, std::cin };\r\n    OverrideForCompositeInstalledSource(removeContext, CreateTestSource({ TSR::TestInstaller_Exe }));\r\n    removeContext.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe.Query);\r\n\r\n    PinRemoveCommand pinRemove({});\r\n    pinRemove.Execute(removeContext);\r\n    INFO(pinRemoveOutput.str());\r\n\r\n    REQUIRE_TERMINATED_WITH(removeContext, APPINSTALLER_CLI_ERROR_PIN_DOES_NOT_EXIST);\r\n}\r\n\r\nTEST_CASE(\"PinFlow_ResetEmpty\", \"[PinFlow][workflow]\")\r\n{\r\n    TempFile indexFile(\"pinningIndex\", \".db\");\r\n    TestHook::SetPinningIndex_Override pinningIndexOverride(indexFile.GetPath());\r\n\r\n    std::ostringstream pinResetOutput;\r\n    TestContext resetContext{ pinResetOutput, std::cin };\r\n    resetContext.Args.AddArg(Execution::Args::Type::Force);\r\n\r\n    PinResetCommand pinReset({});\r\n    pinReset.Execute(resetContext);\r\n    INFO(pinResetOutput.str());\r\n\r\n    REQUIRE(pinResetOutput.str().find(Resource::LocString(Resource::String::PinNoPinsExist)) != std::string::npos);\r\n}"
  },
  {
    "path": "src/AppInstallerCLITests/PinningIndex.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <Microsoft/PinningIndex.h>\r\n#include <Microsoft/Schema/IPinningIndex.h>\r\n#include <Microsoft/Schema/Pinning_1_0/PinTable.h>\r\n#include <winget/Pin.h>\r\n\r\nusing namespace std::string_literals;\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::Pinning;\r\nusing namespace AppInstaller::Repository::Microsoft;\r\nusing namespace AppInstaller::SQLite;\r\nusing namespace AppInstaller::Repository::Microsoft::Schema;\r\n\r\nTEST_CASE(\"PinningIndexCreateLatestAndReopen\", \"[pinningIndex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Version versionCreated;\r\n\r\n    // Create the index\r\n    {\r\n        PinningIndex index = PinningIndex::CreateNew(tempFile, Version::Latest());\r\n        versionCreated = index.GetVersion();\r\n    }\r\n\r\n    // Reopen the index for read only\r\n    {\r\n        INFO(\"Trying with Read\");\r\n        PinningIndex index = PinningIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::Read);\r\n        Version versionRead = index.GetVersion();\r\n        REQUIRE(versionRead == versionCreated);\r\n    }\r\n\r\n    // Reopen the index for read/write\r\n    {\r\n        INFO(\"Trying with ReadWrite\");\r\n        PinningIndex index = PinningIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n        Version versionRead = index.GetVersion();\r\n        REQUIRE(versionRead == versionCreated);\r\n    }\r\n\r\n    // Reopen the index for immutable read\r\n    {\r\n        INFO(\"Trying with Immutable\");\r\n        PinningIndex index = PinningIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::Immutable);\r\n        Version versionRead = index.GetVersion();\r\n        REQUIRE(versionRead == versionCreated);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"PinningIndexAddEntryToTable\", \"[pinningIndex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Pin pin = Pin::CreateBlockingPin({ \"pkgId\", \"sourceId\" });\r\n\r\n    {\r\n        PinningIndex index = PinningIndex::CreateNew(tempFile, { 1, 0 });\r\n        index.AddPin(pin);\r\n    }\r\n\r\n    {\r\n        // Open it directly to directly test table state\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n\r\n        auto pins = Pinning_V1_0::PinTable::GetAllPins(connection);\r\n        REQUIRE(pins.size() == 1);\r\n        REQUIRE(pins[0] == pin);\r\n\r\n        auto pinFromIndex = Pinning_V1_0::PinTable::GetPinById(connection, 1);\r\n        REQUIRE(pinFromIndex.has_value());\r\n        REQUIRE(pinFromIndex.value() == pin);\r\n\r\n        REQUIRE(pinFromIndex->GetType() == pin.GetType());\r\n        REQUIRE(pinFromIndex->GetKey() == pin.GetKey());\r\n    }\r\n\r\n    {\r\n        PinningIndex index = PinningIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n        index.RemovePin(pin.GetKey());\r\n    }\r\n\r\n    {\r\n        // Open it directly to directly test table state\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n        REQUIRE(Pinning_V1_0::PinTable::GetAllPins(connection).empty());\r\n        REQUIRE(!Pinning_V1_0::PinTable::GetPinById(connection, 1));\r\n    }\r\n}\r\n\r\nTEST_CASE(\"PinningIndex_AddUpdateRemove\", \"[pinningIndex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Pin pin = Pin::CreateGatingPin({ \"pkgId\", \"srcId\" }, { \"1.0.*\"sv });\r\n    Pin updatedPin = Pin::CreatePinningPin({ \"pkgId\", \"srcId\" });\r\n\r\n    {\r\n        PinningIndex index = PinningIndex::CreateNew(tempFile, { 1, 0 });\r\n        index.AddPin(pin);\r\n        REQUIRE(index.UpdatePin(updatedPin));\r\n    }\r\n\r\n    {\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadOnly);\r\n        auto pinFromIndex = Pinning_V1_0::PinTable::GetPinById(connection, 1);\r\n        REQUIRE(pinFromIndex.has_value());\r\n        REQUIRE(pinFromIndex.value() == updatedPin);\r\n    }\r\n\r\n    {\r\n        PinningIndex index = PinningIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n        index.RemovePin(updatedPin.GetKey());\r\n    }\r\n\r\n    {\r\n        // Open it directly to directly test table state\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n        REQUIRE(Pinning_V1_0::PinTable::GetAllPins(connection).empty());\r\n        REQUIRE(!Pinning_V1_0::PinTable::GetPinById(connection, 1));\r\n    }\r\n}\r\n\r\nTEST_CASE(\"PinningIndex_ResetAll\", \"[pinningIndex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Pin pin1 = Pin::CreateBlockingPin({ \"pkg1\", \"src1\" });\r\n    Pin pin2 = Pin::CreatePinningPin({ \"pkg2\", \"src2\" });\r\n\r\n    // Add two pins to the index, then check that they show up when queried\r\n    PinningIndex index = PinningIndex::CreateNew(tempFile, { 1, 0 });\r\n    index.AddPin(pin1);\r\n    index.AddPin(pin2);\r\n\r\n    REQUIRE(index.GetAllPins().size() == 2);\r\n    REQUIRE(index.GetPin(pin1.GetKey()).has_value());\r\n    REQUIRE(index.GetPin(pin2.GetKey()).has_value());\r\n    REQUIRE(!index.GetPin({ \"pkg\", \"src\" }).has_value());\r\n\r\n    // Reset the index, then check that there are no pins\r\n    index.ResetAllPins();\r\n    REQUIRE(index.GetAllPins().empty());\r\n    REQUIRE(!index.GetPin(pin1.GetKey()).has_value());\r\n    REQUIRE(!index.GetPin(pin2.GetKey()).has_value());\r\n}\r\n\r\nTEST_CASE(\"PinningIndex_AddDuplicatePin\", \"[pinningIndex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Pin pin = Pin::CreateGatingPin({ \"pkg\", \"src\" }, { \"1.*\"sv });\r\n\r\n    PinningIndex index = PinningIndex::CreateNew(tempFile, { 1, 0 });\r\n    index.AddPin(pin);\r\n\r\n    REQUIRE_THROWS(index.AddPin(pin), ERROR_ALREADY_EXISTS);\r\n}"
  },
  {
    "path": "src/AppInstallerCLITests/PortableIndex.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <winget/SQLiteWrapper.h>\r\n#include <winget/SQLiteStorageBase.h>\r\n#include <Microsoft/Schema/IPortableIndex.h>\r\n#include <winget/PortableIndex.h>\r\n#include <Microsoft/Schema/Portable_1_0/PortableTable.h>\r\n#include <winget/PortableFileEntry.h>\r\n\r\nusing namespace std::string_literals;\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::Portable;\r\nusing namespace AppInstaller::Repository::Microsoft;\r\nusing namespace AppInstaller::SQLite;\r\nusing namespace AppInstaller::Repository::Microsoft::Schema;\r\n\r\nvoid CreateFakePortableFile(PortableFileEntry& file)\r\n{\r\n    file.SetFilePath(\"testPortableFile.exe\");\r\n    file.FileType = PortableFileType::File;\r\n    file.SHA256 = \"f0e4c2f76c58916ec258f246851bea091d14d4247a2fc3e18694461b1816e13b\";\r\n    file.SymlinkTarget = \"testSymlinkTarget.exe\";\r\n}\r\n\r\nTEST_CASE(\"PortableIndexCreateLatestAndReopen\", \"[portableIndex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Version versionCreated;\r\n\r\n    // Create the index\r\n    {\r\n        PortableIndex index = PortableIndex::CreateNew(tempFile, Version::Latest());\r\n        versionCreated = index.GetVersion();\r\n    }\r\n\r\n    // Reopen the index for read only\r\n    {\r\n        INFO(\"Trying with Read\");\r\n        PortableIndex index = PortableIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::Read);\r\n        Version versionRead = index.GetVersion();\r\n        REQUIRE(versionRead == versionCreated);\r\n    }\r\n\r\n    // Reopen the index for read/write\r\n    {\r\n        INFO(\"Trying with ReadWrite\");\r\n        PortableIndex index = PortableIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n        Version versionRead = index.GetVersion();\r\n        REQUIRE(versionRead == versionCreated);\r\n    }\r\n\r\n    // Reopen the index for immutable read\r\n    {\r\n        INFO(\"Trying with Immutable\");\r\n        PortableIndex index = PortableIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::Immutable);\r\n        Version versionRead = index.GetVersion();\r\n        REQUIRE(versionRead == versionCreated);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"PortableIndexAddEntryToTable\", \"[portableIndex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    PortableFileEntry portableFile;\r\n    CreateFakePortableFile(portableFile);\r\n\r\n    {\r\n        PortableIndex index = PortableIndex::CreateNew(tempFile, { 1, 0 });\r\n        index.AddPortableFile(portableFile);\r\n    }\r\n\r\n    {\r\n        // Open it directly to directly test table state\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n        REQUIRE(!Schema::Portable_V1_0::PortableTable::IsEmpty(connection));\r\n    }\r\n\r\n    {\r\n        PortableIndex index = PortableIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n        index.RemovePortableFile(portableFile);\r\n    }\r\n\r\n    {\r\n        // Open it directly to directly test table state\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n        REQUIRE(Schema::Portable_V1_0::PortableTable::IsEmpty(connection));\r\n    }\r\n}\r\n\r\nTEST_CASE(\"PortableIndex_AddUpdateRemove\", \"[portableIndex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    PortableFileEntry portableFile;\r\n    CreateFakePortableFile(portableFile);\r\n\r\n    PortableIndex index = PortableIndex::CreateNew(tempFile, { 1, 0 });\r\n    index.AddPortableFile(portableFile);\r\n\r\n    // Apply changes to portable file\r\n    std::string updatedHash = \"2db8ae7657c6622b04700137740002c51c36588e566651c9f67b4b096c8ad18b\";\r\n    portableFile.FileType = PortableFileType::Symlink;\r\n    portableFile.SHA256 = updatedHash;\r\n    portableFile.SymlinkTarget = \"fakeSymlinkTarget.exe\";\r\n\r\n    REQUIRE(index.UpdatePortableFile(portableFile));\r\n\r\n    {\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadOnly);\r\n        auto fileFromIndex = Schema::Portable_V1_0::PortableTable::GetPortableFileById(connection, 1);\r\n        REQUIRE(fileFromIndex.has_value());\r\n        REQUIRE(fileFromIndex->GetFilePath() == portableFile.GetFilePath());\r\n        REQUIRE(fileFromIndex->FileType == PortableFileType::Symlink);\r\n        REQUIRE(fileFromIndex->SHA256 == updatedHash);\r\n        REQUIRE(fileFromIndex->SymlinkTarget == \"fakeSymlinkTarget.exe\");\r\n    }\r\n\r\n    {\r\n        PortableIndex index2 = PortableIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n        index2.RemovePortableFile(portableFile);\r\n    }\r\n\r\n    {\r\n        // Open it directly to directly test table state\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n        REQUIRE(Schema::Portable_V1_0::PortableTable::IsEmpty(connection));\r\n    }\r\n}\r\n\r\nTEST_CASE(\"PortableIndex_UpdateFile_CaseInsensitive\", \"[portableIndex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    PortableFileEntry portableFile;\r\n    CreateFakePortableFile(portableFile);\r\n\r\n    PortableIndex index = PortableIndex::CreateNew(tempFile, { 1, 0 });\r\n    index.AddPortableFile(portableFile);\r\n\r\n    // By default, portable file path is set to \"testPortableFile.exe\"\r\n    // Change file path to all upper case should still successfully update.\r\n    portableFile.SetFilePath(\"TESTPORTABLEFILE.exe\");\r\n    std::string updatedHash = \"2db8ae7657c6622b04700137740002c51c36588e566651c9f67b4b096c8ad18b\";\r\n    portableFile.FileType = PortableFileType::Symlink;\r\n    portableFile.SHA256 = updatedHash;\r\n    portableFile.SymlinkTarget = \"fakeSymlinkTarget.exe\";\r\n\r\n    REQUIRE(index.UpdatePortableFile(portableFile));\r\n\r\n    {\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadOnly);\r\n        auto fileFromIndex = Schema::Portable_V1_0::PortableTable::GetPortableFileById(connection, 1);\r\n        REQUIRE(fileFromIndex.has_value());\r\n        REQUIRE(fileFromIndex->GetFilePath() == portableFile.GetFilePath());\r\n        REQUIRE(fileFromIndex->FileType == PortableFileType::Symlink);\r\n        REQUIRE(fileFromIndex->SHA256 == updatedHash);\r\n        REQUIRE(fileFromIndex->SymlinkTarget == \"fakeSymlinkTarget.exe\");\r\n    }\r\n}\r\n\r\nTEST_CASE(\"PortableIndex_AddDuplicateFile\", \"[portableIndex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    PortableFileEntry portableFile;\r\n    CreateFakePortableFile(portableFile);\r\n\r\n    PortableIndex index = PortableIndex::CreateNew(tempFile, { 1, 0 });\r\n    index.AddPortableFile(portableFile);\r\n\r\n    // Change file path to all upper case. Adding duplicate file should fail.\r\n    portableFile.SetFilePath(\"TESTPORTABLEFILE.exe\");\r\n    REQUIRE_THROWS(index.AddPortableFile(portableFile), ERROR_ALREADY_EXISTS);\r\n}\r\n\r\nTEST_CASE(\"PortableIndex_RemoveWithId\", \"[portableIndex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    PortableFileEntry portableFile;\r\n    CreateFakePortableFile(portableFile);\r\n\r\n    PortableIndex index = PortableIndex::CreateNew(tempFile, { 1, 0 });\r\n    index.AddPortableFile(portableFile);\r\n\r\n    {\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n        REQUIRE(Portable_V1_0::PortableTable::ExistsById(connection, 1));\r\n        Portable_V1_0::PortableTable::DeleteById(connection, 1);\r\n        REQUIRE_FALSE(Portable_V1_0::PortableTable::ExistsById(connection, 1));\r\n    }\r\n}"
  },
  {
    "path": "src/AppInstallerCLITests/PortableInstaller.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <PortableInstaller.h>\r\n#include <Public/AppInstallerArchitecture.h>\r\n#include <winget/Filesystem.h>\r\n#include <winget/Manifest.h>\r\n#include <winget/PathVariable.h>\r\n#include <winget/PortableARPEntry.h>\r\n#include <winget/SQLiteStorageBase.h>\r\n#include <Microsoft/Schema/IPortableIndex.h>\r\n#include <winget/PortableIndex.h>\r\n\r\nusing namespace std::string_literals;\r\nusing namespace AppInstaller::CLI::Portable;\r\nusing namespace AppInstaller::Filesystem;\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Registry::Environment;\r\nusing namespace AppInstaller::Repository::Microsoft;\r\nusing namespace AppInstaller::SQLite;\r\nusing namespace AppInstaller::Repository::Microsoft::Schema;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::CLI::Workflow;\r\nusing namespace TestCommon;\r\n\r\nTEST_CASE(\"PortableInstaller_InstallToRegistry\", \"[PortableInstaller]\")\r\n{\r\n    TempDirectory tempDirectory = TestCommon::TempDirectory(\"TempDirectory\", false);\r\n\r\n    std::vector<PortableFileEntry> desiredTestState;\r\n\r\n    TestCommon::TempFile testPortable(\"testPortable.txt\");\r\n    std::ofstream file(testPortable, std::ofstream::out);\r\n    file.close();\r\n\r\n    std::filesystem::path targetPath = tempDirectory.GetPath() / \"testPortable.txt\";\r\n    std::filesystem::path symlinkPath = tempDirectory.GetPath() / \"testSymlink.exe\";\r\n\r\n    desiredTestState.emplace_back(std::move(PortableFileEntry::CreateFileEntry(testPortable.GetPath(), targetPath, {})));\r\n    desiredTestState.emplace_back(std::move(PortableFileEntry::CreateSymlinkEntry(symlinkPath, targetPath)));\r\n\r\n    PortableInstaller portableInstaller = PortableInstaller(ScopeEnum::User, Architecture::X64, \"testProductCode\");\r\n    portableInstaller.TargetInstallLocation = tempDirectory.GetPath();\r\n    portableInstaller.SetDesiredState(desiredTestState);\r\n    REQUIRE(portableInstaller.VerifyExpectedState());\r\n\r\n    portableInstaller.Install(AppInstaller::CLI::Workflow::OperationType::Install);\r\n\r\n    auto entry = portableInstaller.GetAppsAndFeaturesEntry();\r\n    REQUIRE(entry.ProductCode == portableInstaller.GetProductCode());\r\n\r\n    PortableInstaller portableInstaller2 = PortableInstaller(ScopeEnum::User, Architecture::X64, \"testProductCode\");\r\n    REQUIRE(portableInstaller2.ARPEntryExists());\r\n    REQUIRE(std::filesystem::exists(portableInstaller2.PortableTargetFullPath));\r\n    REQUIRE(AppInstaller::Filesystem::SymlinkExists(portableInstaller2.PortableSymlinkFullPath));\r\n\r\n    portableInstaller2.Uninstall();\r\n    REQUIRE_FALSE(std::filesystem::exists(portableInstaller2.PortableTargetFullPath));\r\n    REQUIRE_FALSE(AppInstaller::Filesystem::SymlinkExists(portableInstaller2.PortableSymlinkFullPath));\r\n    REQUIRE_FALSE(std::filesystem::exists(portableInstaller2.InstallLocation));\r\n}\r\n\r\nTEST_CASE(\"PortableInstaller_InstallToIndex_CreateInstallRoot\", \"[PortableInstaller]\")\r\n{\r\n    TempDirectory installRootDirectory = TestCommon::TempDirectory(\"PortableInstallRoot\", false);\r\n\r\n    std::vector<PortableFileEntry> desiredTestState;\r\n\r\n    TestCommon::TempFile testPortable(\"testPortable.txt\");\r\n    std::ofstream file1(testPortable, std::ofstream::out);\r\n    file1.close();\r\n\r\n    TestCommon::TempFile testPortable2(\"testPortable2.txt\");\r\n    std::ofstream file2(testPortable2, std::ofstream::out);\r\n    file2.close();\r\n\r\n    TestCommon::TempDirectory testDirectoryFolder(\"testDirectory\", true);\r\n\r\n    std::filesystem::path installRootPath = installRootDirectory.GetPath();\r\n    std::filesystem::path targetPath = installRootPath / \"testPortable.txt\";\r\n    std::filesystem::path targetPath2 = installRootPath / \"testPortable2.txt\";\r\n    std::filesystem::path symlinkPath = installRootPath / \"testSymlink.exe\";\r\n    std::filesystem::path symlinkPath2 = installRootPath / \"testSymlink2.exe\";\r\n    std::filesystem::path directoryPath = installRootPath / \"testDirectory\";\r\n\r\n    desiredTestState.emplace_back(std::move(PortableFileEntry::CreateFileEntry(testPortable.GetPath(), targetPath, {})));\r\n    desiredTestState.emplace_back(std::move(PortableFileEntry::CreateFileEntry(testPortable2.GetPath(), targetPath2, {})));\r\n    desiredTestState.emplace_back(std::move(PortableFileEntry::CreateSymlinkEntry(symlinkPath, targetPath)));\r\n    desiredTestState.emplace_back(std::move(PortableFileEntry::CreateSymlinkEntry(symlinkPath2, targetPath2)));\r\n    desiredTestState.emplace_back(std::move(PortableFileEntry::CreateDirectoryEntry(testDirectoryFolder.GetPath(), directoryPath)));\r\n\r\n    PortableInstaller portableInstaller = PortableInstaller(ScopeEnum::User, Architecture::X64, \"testProductCode\");\r\n    portableInstaller.TargetInstallLocation = installRootDirectory.GetPath();\r\n    portableInstaller.RecordToIndex = true;\r\n    portableInstaller.SetDesiredState(desiredTestState);\r\n    REQUIRE(portableInstaller.VerifyExpectedState());\r\n\r\n    portableInstaller.Install(AppInstaller::CLI::Workflow::OperationType::Install);\r\n\r\n    REQUIRE(std::filesystem::exists(installRootPath / portableInstaller.GetPortableIndexFileName()));\r\n    REQUIRE(std::filesystem::exists(targetPath));\r\n    REQUIRE(std::filesystem::exists(targetPath2));\r\n    REQUIRE(AppInstaller::Filesystem::SymlinkExists(symlinkPath));\r\n    REQUIRE(AppInstaller::Filesystem::SymlinkExists(symlinkPath2));\r\n    REQUIRE(std::filesystem::exists(directoryPath));\r\n\r\n    PortableInstaller portableInstaller2 = PortableInstaller(ScopeEnum::User, Architecture::X64, \"testProductCode\");\r\n    REQUIRE(portableInstaller2.ARPEntryExists());\r\n\r\n    portableInstaller2.Uninstall();\r\n\r\n    // Install root directory should be removed since it was created.\r\n    REQUIRE_FALSE(std::filesystem::exists(installRootPath));\r\n    REQUIRE_FALSE(std::filesystem::exists(targetPath));\r\n    REQUIRE_FALSE(std::filesystem::exists(targetPath2));\r\n    REQUIRE_FALSE(AppInstaller::Filesystem::SymlinkExists(symlinkPath));\r\n    REQUIRE_FALSE(AppInstaller::Filesystem::SymlinkExists(symlinkPath2));\r\n    REQUIRE_FALSE(std::filesystem::exists(directoryPath));\r\n}\r\n\r\nTEST_CASE(\"PortableInstaller_InstallToIndex_ExistingInstallRoot\", \"[PortableInstaller]\")\r\n{\r\n    TempDirectory installRootDirectory = TestCommon::TempDirectory(\"PortableInstallRoot\", true);\r\n\r\n    std::vector<PortableFileEntry> desiredTestState;\r\n\r\n    TestCommon::TempFile testPortable(\"testPortable.txt\");\r\n    std::ofstream file1(testPortable, std::ofstream::out);\r\n    file1.close();\r\n\r\n    TestCommon::TempFile testPortable2(\"testPortable2.txt\");\r\n    std::ofstream file2(testPortable2, std::ofstream::out);\r\n    file2.close();\r\n\r\n    TestCommon::TempDirectory testDirectoryFolder(\"testDirectory\", true);\r\n\r\n    std::filesystem::path installRootPath = installRootDirectory.GetPath();\r\n    std::filesystem::path targetPath = installRootPath / \"testPortable.txt\";\r\n    std::filesystem::path targetPath2 = installRootPath / \"testPortable2.txt\";\r\n    std::filesystem::path symlinkPath = installRootPath / \"testSymlink.exe\";\r\n    std::filesystem::path symlinkPath2 = installRootPath / \"testSymlink2.exe\";\r\n    std::filesystem::path directoryPath = installRootPath / \"testDirectory\";\r\n\r\n    desiredTestState.emplace_back(std::move(PortableFileEntry::CreateFileEntry(testPortable.GetPath(), targetPath, {})));\r\n    desiredTestState.emplace_back(std::move(PortableFileEntry::CreateFileEntry(testPortable2.GetPath(), targetPath2, {})));\r\n    desiredTestState.emplace_back(std::move(PortableFileEntry::CreateSymlinkEntry(symlinkPath, targetPath)));\r\n    desiredTestState.emplace_back(std::move(PortableFileEntry::CreateSymlinkEntry(symlinkPath2, targetPath2)));\r\n    desiredTestState.emplace_back(std::move(PortableFileEntry::CreateDirectoryEntry(testDirectoryFolder.GetPath(), directoryPath)));\r\n\r\n    PortableInstaller portableInstaller = PortableInstaller(ScopeEnum::User, Architecture::X64, \"testProductCode\");\r\n    portableInstaller.TargetInstallLocation = installRootDirectory.GetPath();\r\n    portableInstaller.RecordToIndex = true;\r\n    portableInstaller.SetDesiredState(desiredTestState);\r\n    REQUIRE(portableInstaller.VerifyExpectedState());\r\n\r\n    portableInstaller.Install(AppInstaller::CLI::Workflow::OperationType::Install);\r\n\r\n    REQUIRE(std::filesystem::exists(installRootPath / portableInstaller.GetPortableIndexFileName()));\r\n    REQUIRE(std::filesystem::exists(targetPath));\r\n    REQUIRE(std::filesystem::exists(targetPath2));\r\n    REQUIRE(AppInstaller::Filesystem::SymlinkExists(symlinkPath));\r\n    REQUIRE(AppInstaller::Filesystem::SymlinkExists(symlinkPath2));\r\n    REQUIRE(std::filesystem::exists(directoryPath));\r\n\r\n    PortableInstaller portableInstaller2 = PortableInstaller(ScopeEnum::User, Architecture::X64, \"testProductCode\");\r\n    REQUIRE(portableInstaller2.ARPEntryExists());\r\n\r\n    portableInstaller2.Uninstall();\r\n\r\n    // Install root directory should still exist since it was created previously.\r\n    REQUIRE(std::filesystem::exists(installRootPath));\r\n    REQUIRE_FALSE(std::filesystem::exists(targetPath));\r\n    REQUIRE_FALSE(std::filesystem::exists(targetPath2));\r\n    REQUIRE_FALSE(AppInstaller::Filesystem::SymlinkExists(symlinkPath));\r\n    REQUIRE_FALSE(AppInstaller::Filesystem::SymlinkExists(symlinkPath2));\r\n    REQUIRE_FALSE(std::filesystem::exists(directoryPath));\r\n}\r\n\r\nTEST_CASE(\"PortableInstaller_UnicodeSymlinkPath\", \"[PortableInstaller]\")\r\n{\r\n    TempDirectory tempDirectory = TestCommon::TempDirectory(\"TempDirectory\", false);\r\n\r\n    // Modify install location path to include unicode characters.\r\n    std::filesystem::path testInstallLocation = tempDirectory.GetPath() / std::filesystem::path{ ConvertToUTF16(\"романтический\") };\r\n\r\n    std::vector<PortableFileEntry> desiredTestState;\r\n\r\n    TestCommon::TempFile testPortable(\"testPortable.txt\");\r\n    std::ofstream file(testPortable, std::ofstream::out);\r\n    file.close();\r\n\r\n    std::filesystem::path targetPath = testInstallLocation / \"testPortable.txt\";\r\n    std::filesystem::path symlinkPath = tempDirectory.GetPath() / \"testSymlink.exe\";\r\n\r\n    desiredTestState.emplace_back(std::move(PortableFileEntry::CreateFileEntry(testPortable.GetPath(), targetPath, {})));\r\n    desiredTestState.emplace_back(std::move(PortableFileEntry::CreateSymlinkEntry(symlinkPath, targetPath)));\r\n\r\n    PortableInstaller portableInstaller = PortableInstaller(ScopeEnum::User, Architecture::X64, \"testProductCode\");\r\n    portableInstaller.TargetInstallLocation = testInstallLocation;\r\n    portableInstaller.SetDesiredState(desiredTestState);\r\n    REQUIRE(portableInstaller.VerifyExpectedState());\r\n\r\n    portableInstaller.Install(AppInstaller::CLI::Workflow::OperationType::Install);\r\n\r\n    PortableInstaller portableInstaller2 = PortableInstaller(ScopeEnum::User, Architecture::X64, \"testProductCode\");\r\n    REQUIRE(portableInstaller2.ARPEntryExists());\r\n    REQUIRE(std::filesystem::exists(portableInstaller2.PortableTargetFullPath));\r\n    REQUIRE(AppInstaller::Filesystem::SymlinkExists(portableInstaller2.PortableSymlinkFullPath));\r\n\r\n    portableInstaller2.Uninstall();\r\n    REQUIRE_FALSE(std::filesystem::exists(portableInstaller2.PortableTargetFullPath));\r\n    REQUIRE_FALSE(AppInstaller::Filesystem::SymlinkExists(portableInstaller2.PortableSymlinkFullPath));\r\n    REQUIRE_FALSE(std::filesystem::exists(portableInstaller2.InstallLocation));\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/PreIndexedPackageSource.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestSource.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestSettings.h\"\r\n#include <winget/RepositorySource.h>\r\n#include <AppInstallerRuntime.h>\r\n#include <AppInstallerStrings.h>\r\n#include <Microsoft/PreIndexedPackageSourceFactory.h>\r\n#include <winget/Settings.h>\r\n\r\nusing namespace std::string_literals;\r\nusing namespace std::string_view_literals;\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Runtime;\r\nusing namespace AppInstaller::Settings;\r\nusing namespace AppInstaller::Utility;\r\n\r\nnamespace fs = std::filesystem;\r\n\r\nconstexpr std::string_view s_RepositorySettings_UserSources = \"usersources\"sv;\r\n\r\nconstexpr std::string_view s_MsixFile_1 = \"index.1.0.0.0.signed.msix\";\r\nconstexpr std::string_view s_MsixFile_2 = \"index.2.0.0.0.signed.msix\";\r\nconstexpr std::string_view s_Msix_FamilyName = \"AppInstallerCLITestsFakeIndex_8wekyb3d8bbwe\";\r\nconstexpr std::string_view s_IndexMsixName = \"source.msix\"sv;\r\n\r\nvoid CopyIndexFileToDirectory(const fs::path& from, const fs::path& to)\r\n{\r\n    fs::path toFile = to;\r\n    toFile /= s_IndexMsixName;\r\n    if (fs::exists(toFile))\r\n    {\r\n        fs::remove(toFile);\r\n    }\r\n    fs::copy_file(from, toFile);\r\n}\r\n\r\nfs::path GetPathToFileDir()\r\n{\r\n    fs::path result = GetPathTo(Runtime::PathName::LocalState);\r\n    result /= AppInstaller::Repository::Microsoft::PreIndexedPackageSourceFactory::Type();\r\n    result /= s_Msix_FamilyName;\r\n    return result;\r\n}\r\n\r\nstd::string GetContents(const fs::path& file)\r\n{\r\n    REQUIRE(fs::exists(file));\r\n    std::ifstream stream(file);\r\n    return ReadEntireStream(stream);\r\n}\r\n\r\nvoid CleanSources()\r\n{\r\n    RemoveSetting(Stream::UserSources);\r\n    RemoveSetting(Stream::SourcesMetadata);\r\n    fs::remove_all(GetPathToFileDir());\r\n}\r\n\r\nTEST_CASE(\"PIPS_Add\", \"[pips]\")\r\n{\r\n    if (!Runtime::IsRunningAsAdmin())\r\n    {\r\n        WARN(\"Test requires admin privilege. Skipped.\");\r\n        return;\r\n    }\r\n\r\n    CleanSources();\r\n\r\n    TempDirectory dir(\"pipssource\");\r\n    TestDataFile index(s_MsixFile_1);\r\n    CopyIndexFileToDirectory(index, dir);\r\n\r\n    bool shouldCleanCert = InstallCertFromSignedPackage(index);\r\n\r\n    SourceDetails details;\r\n    details.Name = \"TestName\";\r\n    details.Type = AppInstaller::Repository::Microsoft::PreIndexedPackageSourceFactory::Type();\r\n    details.Arg = dir;\r\n    ProgressCallback callback;\r\n\r\n    AddSource(details, callback);\r\n\r\n    fs::path state = GetPathToFileDir();\r\n    REQUIRE(fs::exists(state));\r\n\r\n    fs::path indexMsix = state;\r\n    indexMsix /= s_IndexMsixName;\r\n    REQUIRE(fs::exists(indexMsix));\r\n    REQUIRE(fs::file_size(indexMsix) > 0);\r\n\r\n    if (shouldCleanCert)\r\n    {\r\n        UninstallCertFromSignedPackage(index);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"PIPS_UpdateSameVersion\", \"[pips]\")\r\n{\r\n    if (!Runtime::IsRunningAsAdmin())\r\n    {\r\n        WARN(\"Test requires admin privilege. Skipped.\");\r\n        return;\r\n    }\r\n\r\n    CleanSources();\r\n\r\n    TempDirectory dir(\"pipssource\");\r\n    TestDataFile index(s_MsixFile_1);\r\n    CopyIndexFileToDirectory(index, dir);\r\n\r\n    bool shouldCleanCert = InstallCertFromSignedPackage(index);\r\n\r\n    SourceDetails details;\r\n    details.Name = \"TestName\";\r\n    details.Type = AppInstaller::Repository::Microsoft::PreIndexedPackageSourceFactory::Type();\r\n    details.Arg = dir;\r\n    TestProgress callback;\r\n\r\n    AddSource(details, callback);\r\n\r\n    fs::path state = GetPathToFileDir();\r\n    REQUIRE(fs::exists(state));\r\n\r\n    bool progressCalled = false;\r\n    callback.m_OnProgress = [&](uint64_t, uint64_t, ProgressType) { progressCalled = true; };\r\n\r\n    UpdateSource(details.Name, callback);\r\n    REQUIRE(!progressCalled);\r\n\r\n    if (shouldCleanCert)\r\n    {\r\n        UninstallCertFromSignedPackage(index);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"PIPS_UpdateNewVersion\", \"[pips]\")\r\n{\r\n    if (!Runtime::IsRunningAsAdmin())\r\n    {\r\n        WARN(\"Test requires admin privilege. Skipped.\");\r\n        return;\r\n    }\r\n\r\n    CleanSources();\r\n\r\n    TempDirectory dir(\"pipssource\");\r\n    TestDataFile indexMsix1(s_MsixFile_1);\r\n    CopyIndexFileToDirectory(indexMsix1, dir);\r\n\r\n    bool shouldCleanCert = InstallCertFromSignedPackage(indexMsix1);\r\n\r\n    SourceDetails details;\r\n    details.Name = \"TestName\";\r\n    details.Type = AppInstaller::Repository::Microsoft::PreIndexedPackageSourceFactory::Type();\r\n    details.Arg = dir;\r\n    TestProgress callback;\r\n\r\n    AddSource(details, callback);\r\n\r\n    fs::path state = GetPathToFileDir();\r\n    REQUIRE(fs::exists(state));\r\n\r\n    fs::path indexMsix = state;\r\n    indexMsix /= s_IndexMsixName;\r\n    std::string indexContents1 = GetContents(indexMsix);\r\n\r\n    TestDataFile indexMsix2(s_MsixFile_2);\r\n    CopyIndexFileToDirectory(indexMsix2, dir);\r\n\r\n    bool progressCalled = false;\r\n    callback.m_OnProgress = [&](uint64_t, uint64_t, ProgressType) { progressCalled = true; };\r\n\r\n    UpdateSource(details.Name, callback);\r\n    REQUIRE(progressCalled);\r\n\r\n    std::string indexContents2 = GetContents(indexMsix);\r\n    REQUIRE(indexContents1 != indexContents2);\r\n\r\n    if (shouldCleanCert)\r\n    {\r\n        UninstallCertFromSignedPackage(indexMsix1);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"PIPS_Remove\", \"[pips]\")\r\n{\r\n    if (!Runtime::IsRunningAsAdmin())\r\n    {\r\n        WARN(\"Test requires admin privilege. Skipped.\");\r\n        return;\r\n    }\r\n\r\n    CleanSources();\r\n\r\n    TempDirectory dir(\"pipssource\");\r\n    TestDataFile index(s_MsixFile_1);\r\n    CopyIndexFileToDirectory(index, dir);\r\n\r\n    bool shouldCleanCert = InstallCertFromSignedPackage(index);\r\n\r\n    SourceDetails details;\r\n    details.Name = \"TestName\";\r\n    details.Type = AppInstaller::Repository::Microsoft::PreIndexedPackageSourceFactory::Type();\r\n    details.Arg = dir;\r\n    ProgressCallback callback;\r\n\r\n    AddSource(details, callback);\r\n\r\n    fs::path state = GetPathToFileDir();\r\n    REQUIRE(fs::exists(state));\r\n\r\n    fs::path indexMsix = state;\r\n    indexMsix /= s_IndexMsixName;\r\n    REQUIRE(fs::exists(indexMsix));\r\n\r\n    RemoveSource(details.Name, callback);\r\n    REQUIRE(!fs::exists(state));\r\n\r\n    if (shouldCleanCert)\r\n    {\r\n        UninstallCertFromSignedPackage(index);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/PredefinedInstalledSource.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <ISource.h>\r\n#include <AppInstallerRuntime.h>\r\n#include <AppInstallerStrings.h>\r\n#include <Microsoft/PredefinedInstalledSourceFactory.h>\r\n#include <Microsoft/ARPHelper.h>\r\n#include <Microsoft/SQLiteIndexSource.h>\r\n\r\nusing namespace std::string_literals;\r\nusing namespace std::string_view_literals;\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller;\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Runtime;\r\nusing namespace AppInstaller::Utility;\r\n\r\nusing SQLiteIndex = AppInstaller::Repository::Microsoft::SQLiteIndex;\r\nusing SQLiteIndexSource = AppInstaller::Repository::Microsoft::SQLiteIndexSource;\r\nusing Factory = AppInstaller::Repository::Microsoft::PredefinedInstalledSourceFactory;\r\nusing ARPHelper = AppInstaller::Repository::Microsoft::ARPHelper;\r\n\r\nconstexpr std::string_view s_TestScope = \"TestScope\"sv;\r\n\r\nstruct ARPEntry\r\n{\r\n    ARPEntry(std::string entryName) : EntryName(std::move(entryName)) {}\r\n    ARPEntry(std::string entryName, std::optional<std::string> displayName, std::optional<std::string> displayVersion, bool systemComponent = false) :\r\n        EntryName(std::move(entryName)), DisplayName(std::move(displayName)), DisplayVersion(std::move(displayVersion)), SystemComponent(systemComponent) {}\r\n\r\n    std::string EntryName;\r\n    std::optional<std::string> DisplayName;\r\n    std::optional<std::string> DisplayVersion;\r\n    std::optional<std::string> Publisher;\r\n    std::optional<std::string> InstallLocation;\r\n    std::optional<std::string> UninstallString;\r\n    std::optional<std::string> QuietUninstallString;\r\n    std::optional<bool> WindowsInstaller;\r\n    std::optional<bool> SystemComponent;\r\n};\r\n\r\nvoid AddARPValueToKey(HKEY key, const std::wstring& name, const std::optional<std::string>& value)\r\n{\r\n    if (value)\r\n    {\r\n        SetRegistryValue(key, name, ConvertToUTF16(value.value()));\r\n    }\r\n}\r\n\r\nvoid AddARPValueToKey(HKEY key, const std::wstring& name, const std::optional<bool>& value)\r\n{\r\n    if (value)\r\n    {\r\n        SetRegistryValue(key, name, (value.value() ? 1 : 0));\r\n    }\r\n}\r\n\r\nvoid AddARPEntryToKey(HKEY key, const ARPHelper& helper, const ARPEntry& entry)\r\n{\r\n    auto subkey = RegCreateVolatileSubKey(key, ConvertToUTF16(entry.EntryName));\r\n\r\n#define ADD_ARP_VALUE(_name_) AddARPValueToKey(subkey.get(), helper._name_, entry._name_)\r\n    ADD_ARP_VALUE(DisplayName);\r\n    ADD_ARP_VALUE(DisplayVersion);\r\n    ADD_ARP_VALUE(Publisher);\r\n    ADD_ARP_VALUE(InstallLocation);\r\n    ADD_ARP_VALUE(UninstallString);\r\n    ADD_ARP_VALUE(QuietUninstallString);\r\n    ADD_ARP_VALUE(WindowsInstaller);\r\n    ADD_ARP_VALUE(SystemComponent);\r\n#undef ADD_ARP_VALUE\r\n}\r\n\r\nvoid AddARPEntriesToKey(HKEY key, const ARPHelper& helper, const std::vector<ARPEntry>& entries)\r\n{\r\n    for (const auto& entry : entries)\r\n    {\r\n        AddARPEntryToKey(key, helper, entry);\r\n    }\r\n}\r\n\r\nSQLiteIndex::MetadataResult::const_iterator Find(const SQLiteIndex::MetadataResult& metadata, PackageVersionMetadata value)\r\n{\r\n    return std::find_if(metadata.begin(), metadata.end(), [value](const auto& m) { return m.first == value; });\r\n}\r\n\r\nvoid VerifyInstalledType(const SQLiteIndex::MetadataResult& metadata, InstallerTypeEnum type)\r\n{\r\n    auto itr = Find(metadata, PackageVersionMetadata::InstalledType);\r\n    REQUIRE(itr != metadata.end());\r\n    REQUIRE(ConvertToInstallerTypeEnum(itr->second) == type);\r\n}\r\n\r\nvoid VerifyTestScope(const SQLiteIndex::MetadataResult& metadata)\r\n{\r\n    auto itr = Find(metadata, PackageVersionMetadata::InstalledScope);\r\n    REQUIRE(itr != metadata.end());\r\n    REQUIRE(itr->second == s_TestScope);\r\n}\r\n\r\nvoid VerifyMetadataString(const SQLiteIndex::MetadataResult& metadata, PackageVersionMetadata pvm, const std::optional<std::string>& value)\r\n{\r\n    auto itr = Find(metadata, pvm);\r\n    if (value)\r\n    {\r\n        REQUIRE(itr != metadata.end());\r\n        REQUIRE(itr->second == value.value());\r\n    }\r\n    else\r\n    {\r\n        REQUIRE(itr == metadata.end());\r\n    }\r\n}\r\n\r\nvoid VerifyEntryAgainstIndex(const SQLiteIndex& index, SQLiteIndex::IdType manifestId, const ARPEntry& entry)\r\n{\r\n    REQUIRE(index.GetPropertyByPrimaryId(manifestId, PackageVersionProperty::Name) == entry.DisplayName);\r\n    REQUIRE(index.GetPropertyByPrimaryId(manifestId, PackageVersionProperty::Version) == entry.DisplayVersion);\r\n\r\n    REQUIRE(index.GetMultiPropertyByPrimaryId(manifestId, PackageVersionMultiProperty::PackageFamilyName).empty());\r\n    auto productCodes = index.GetMultiPropertyByPrimaryId(manifestId, PackageVersionMultiProperty::ProductCode);\r\n    REQUIRE(productCodes.size() == 1);\r\n    REQUIRE(productCodes[0] == FoldCase(static_cast<std::string_view>(entry.EntryName)));\r\n\r\n    auto metadata = index.GetMetadataByManifestId(manifestId);\r\n\r\n    VerifyInstalledType(metadata, entry.WindowsInstaller.value_or(false) ? InstallerTypeEnum::Msi : InstallerTypeEnum::Exe);\r\n    VerifyTestScope(metadata);\r\n    VerifyMetadataString(metadata, PackageVersionMetadata::Publisher, entry.Publisher);\r\n    VerifyMetadataString(metadata, PackageVersionMetadata::InstalledLocation, entry.InstallLocation);\r\n    VerifyMetadataString(metadata, PackageVersionMetadata::StandardUninstallCommand, entry.UninstallString);\r\n    VerifyMetadataString(metadata, PackageVersionMetadata::SilentUninstallCommand, entry.QuietUninstallString);\r\n}\r\n\r\nstd::shared_ptr<ISource> CreatePredefinedInstalledSource(Factory::Filter filter = Factory::Filter::None)\r\n{\r\n    SourceDetails details;\r\n    details.Type = Factory::Type();\r\n    details.Arg = Factory::FilterToString(filter);\r\n\r\n    TestProgress progress;\r\n\r\n    auto factory = Factory::Create();\r\n    return factory->Create(details)->Open(progress);\r\n}\r\n\r\nSQLiteIndex CreateMemoryIndex()\r\n{\r\n    return SQLiteIndex::CreateNew(SQLITE_MEMORY_DB_CONNECTION_TARGET, SQLite::Version::Latest(), SQLiteIndex::CreateOptions::SupportPathless);\r\n}\r\n\r\nTEST_CASE(\"ARPHelper_GetARPForArchitecture\", \"[arphelper][list]\")\r\n{\r\n    auto systemArch = GetSystemArchitecture();\r\n\r\n    ARPHelper helper;\r\n\r\n    auto nativeMachineKey = helper.GetARPKey(ScopeEnum::Machine, systemArch);\r\n    REQUIRE(nativeMachineKey);\r\n}\r\n\r\nTEST_CASE(\"ARPHelper_GetBoolValue_DoesNotExist\", \"[arphelper][list]\")\r\n{\r\n    auto root = RegCreateVolatileTestRoot();\r\n    Registry::Key key(root.get());\r\n    std::wstring valueName = L\"TestValueName\";\r\n\r\n    ARPHelper helper;\r\n\r\n    REQUIRE_FALSE(helper.GetBoolValue(key, valueName));\r\n}\r\n\r\nTEST_CASE(\"ARPHelper_GetBoolValue_NotDword\", \"[arphelper][list]\")\r\n{\r\n    auto root = RegCreateVolatileTestRoot();\r\n    Registry::Key key(root.get());\r\n    std::wstring valueName = L\"TestValueName\";\r\n\r\n    SetRegistryValue(root.get(), valueName, L\"True\");\r\n\r\n    ARPHelper helper;\r\n\r\n    REQUIRE_FALSE(helper.GetBoolValue(key, valueName));\r\n}\r\n\r\nTEST_CASE(\"ARPHelper_GetBoolValue_Zero\", \"[arphelper][list]\")\r\n{\r\n    auto root = RegCreateVolatileTestRoot();\r\n    Registry::Key key(root.get());\r\n    std::wstring valueName = L\"TestValueName\";\r\n\r\n    SetRegistryValue(root.get(), valueName, 0);\r\n\r\n    ARPHelper helper;\r\n\r\n    REQUIRE_FALSE(helper.GetBoolValue(key, valueName));\r\n}\r\n\r\nTEST_CASE(\"ARPHelper_GetBoolValue_One\", \"[arphelper][list]\")\r\n{\r\n    auto root = RegCreateVolatileTestRoot();\r\n    Registry::Key key(root.get());\r\n    std::wstring valueName = L\"TestValueName\";\r\n\r\n    SetRegistryValue(root.get(), valueName, 1);\r\n\r\n    ARPHelper helper;\r\n\r\n    REQUIRE(helper.GetBoolValue(key, valueName));\r\n}\r\n\r\nTEST_CASE(\"ARPHelper_GetBoolValue_FortyTwo\", \"[arphelper][list]\")\r\n{\r\n    auto root = RegCreateVolatileTestRoot();\r\n    Registry::Key key(root.get());\r\n    std::wstring valueName = L\"TestValueName\";\r\n\r\n    SetRegistryValue(root.get(), valueName, 42);\r\n\r\n    ARPHelper helper;\r\n\r\n    REQUIRE(helper.GetBoolValue(key, valueName));\r\n}\r\n\r\nTEST_CASE(\"ARPHelper_DetermineVersion_DisplayVersion\", \"[arphelper][list]\")\r\n{\r\n    auto root = RegCreateVolatileTestRoot();\r\n    Registry::Key key(root.get());\r\n\r\n    ARPHelper helper;\r\n\r\n    SetRegistryValue(root.get(), helper.DisplayVersion, L\"1.0\");\r\n    SetRegistryValue(root.get(), helper.Version, 0x0207002A);\r\n    SetRegistryValue(root.get(), helper.VersionMajor, 3);\r\n    SetRegistryValue(root.get(), helper.VersionMinor, 14);\r\n\r\n    auto result = helper.DetermineVersion(key);\r\n    REQUIRE(result == \"1.0\");\r\n}\r\n\r\nTEST_CASE(\"ARPHelper_DetermineVersion_Version\", \"[arphelper][list]\")\r\n{\r\n    auto root = RegCreateVolatileTestRoot();\r\n    Registry::Key key(root.get());\r\n\r\n    ARPHelper helper;\r\n\r\n    SetRegistryValue(root.get(), helper.Version, 0x0207002A);\r\n    SetRegistryValue(root.get(), helper.VersionMajor, 3);\r\n    SetRegistryValue(root.get(), helper.VersionMinor, 14);\r\n\r\n    auto result = helper.DetermineVersion(key);\r\n    REQUIRE(result == \"3.14\");\r\n}\r\n\r\nTEST_CASE(\"ARPHelper_DetermineVersion_VersionMajorMinor\", \"[arphelper][list]\")\r\n{\r\n    auto root = RegCreateVolatileTestRoot();\r\n    Registry::Key key(root.get());\r\n\r\n    ARPHelper helper;\r\n\r\n    SetRegistryValue(root.get(), helper.VersionMajor, 3);\r\n    SetRegistryValue(root.get(), helper.VersionMinor, 14);\r\n\r\n    auto result = helper.DetermineVersion(key);\r\n    REQUIRE(result == \"3.14\");\r\n}\r\n\r\nTEST_CASE(\"ARPHelper_DetermineVersion_Unknown\", \"[arphelper][list]\")\r\n{\r\n    auto root = RegCreateVolatileTestRoot();\r\n    Registry::Key key(root.get());\r\n\r\n    ARPHelper helper;\r\n\r\n    auto result = helper.DetermineVersion(key);\r\n    REQUIRE(result == Version::CreateUnknown().ToString());\r\n}\r\n\r\nTEST_CASE(\"ARPHelper_PopulateIndexFromKey_Single\", \"[arphelper][list]\")\r\n{\r\n    auto root = RegCreateVolatileTestRoot();\r\n    Registry::Key key(root.get());\r\n\r\n    ARPHelper helper;\r\n\r\n    // Create a single ARP entry under the root\r\n    ARPEntry entry(\"SingleEntry\");\r\n\r\n    entry.DisplayName = \"Test Name\";\r\n    entry.DisplayVersion = \"1.2\";\r\n    entry.Publisher = \"Test Publisher\";\r\n    entry.InstallLocation = \"TestLocation\";\r\n    entry.UninstallString = \"Test Uninstall\";\r\n    entry.QuietUninstallString = \"Test Quiet Uninstall\";\r\n    entry.WindowsInstaller = true;\r\n\r\n    AddARPEntryToKey(root.get(), helper, entry);\r\n\r\n    auto index = CreateMemoryIndex();\r\n    helper.PopulateIndexFromKey(index, key, s_TestScope, \"TestArchitecture\");\r\n\r\n    auto result = index.Search({});\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    VerifyEntryAgainstIndex(index, result.Matches[0].first, entry);\r\n}\r\n\r\nTEST_CASE(\"ARPHelper_PopulateIndexFromKey_SingleValid\", \"[arphelper][list]\")\r\n{\r\n    auto root = RegCreateVolatileTestRoot();\r\n    Registry::Key key(root.get());\r\n\r\n    ARPHelper helper;\r\n\r\n    // Create a single ARP entry under the root\r\n    ARPEntry entry(\"SingleEntry\");\r\n\r\n    entry.DisplayName = \"Test Name\";\r\n    entry.DisplayVersion = \"1.2\";\r\n    entry.Publisher = \"Test Publisher\";\r\n    entry.InstallLocation = \"TestLocation\";\r\n    entry.UninstallString = \"Test Uninstall\";\r\n    entry.QuietUninstallString = \"Test Quiet Uninstall\";\r\n    entry.WindowsInstaller = false;\r\n\r\n    AddARPEntryToKey(root.get(), helper, entry);\r\n\r\n    // Name and version must exist, as well as not being a system component.\r\n    AddARPEntriesToKey(root.get(), helper, {\r\n        { \"ValidButIsSystemComponent\", \"A\", \"0.1\", true },\r\n        { \"NoName\", {}, \"0.2\" },\r\n        { \"Nothing\" },\r\n        });\r\n\r\n    auto index = CreateMemoryIndex();\r\n    helper.PopulateIndexFromKey(index, key, s_TestScope, \"TestArchitecture\");\r\n\r\n    auto result = index.Search({});\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    VerifyEntryAgainstIndex(index, result.Matches[0].first, entry);\r\n}\r\n\r\nTEST_CASE(\"ARPHelper_PopulateIndexFromKey_Two\", \"[arphelper][list]\")\r\n{\r\n    auto root = RegCreateVolatileTestRoot();\r\n    Registry::Key key(root.get());\r\n\r\n    ARPHelper helper;\r\n\r\n    ARPEntry entry1(\"FirstEntry\");\r\n    entry1.DisplayName = \"Test Name\";\r\n    entry1.DisplayVersion = \"1.2\";\r\n    entry1.Publisher = \"Test Publisher\";\r\n    entry1.InstallLocation = \"TestLocation\";\r\n    entry1.UninstallString = \"Test Uninstall\";\r\n    entry1.QuietUninstallString = \"Test Quiet Uninstall\";\r\n    entry1.WindowsInstaller = true;\r\n\r\n    ARPEntry entry2(\"SecondEntry\");\r\n    entry2.DisplayName = \"Different Test Name\";\r\n    entry2.DisplayVersion = \"31.4\";\r\n    entry2.Publisher = \"Different Test Publisher\";\r\n    entry2.InstallLocation = \"DifferentTestLocation\";\r\n    entry2.UninstallString = \"Different Test Uninstall\";\r\n    entry2.QuietUninstallString = \"Different Test Quiet Uninstall\";\r\n\r\n    AddARPEntryToKey(root.get(), helper, entry1);\r\n    AddARPEntryToKey(root.get(), helper, entry2);\r\n\r\n    auto index = CreateMemoryIndex();\r\n    helper.PopulateIndexFromKey(index, key, s_TestScope, \"TestArchitecture\");\r\n\r\n    REQUIRE(index.Search({}).Matches.size() == 2);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Exact, entry1.EntryName);\r\n    auto result = index.Search(request);\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    VerifyEntryAgainstIndex(index, result.Matches[0].first, entry1);\r\n\r\n    request.Query = RequestMatch(MatchType::Exact, entry2.EntryName);\r\n    result = index.Search(request);\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    VerifyEntryAgainstIndex(index, result.Matches[0].first, entry2);\r\n}\r\n\r\nTEST_CASE(\"PredefinedInstalledSource_Create\", \"[installed][list]\")\r\n{\r\n    auto source = CreatePredefinedInstalledSource();\r\n}\r\n\r\nTEST_CASE(\"PredefinedInstalledSource_Search\", \"[installed][list]\")\r\n{\r\n    auto source = CreatePredefinedInstalledSource();\r\n\r\n    SearchRequest request;\r\n\r\n    auto results = source->Search(request);\r\n\r\n    REQUIRE_FALSE(results.Matches.empty());\r\n}\r\n\r\nstd::string GetDatabaseIdentifier(const std::shared_ptr<Repository::ISource>& source)\r\n{\r\n    return reinterpret_cast<SQLiteIndexSource*>(source->CastTo(ISourceType::SQLiteIndexSource))->GetIndex().GetDatabaseIdentifier();\r\n}\r\n\r\nvoid RequirePackagesHaveSameNames(std::shared_ptr<ISource>& source1, std::shared_ptr<ISource>& source2)\r\n{\r\n    auto result1 = source1->Search({});\r\n    REQUIRE(!result1.Matches.empty());\r\n\r\n    // Ensure that all packages have the same name values\r\n    for (const auto& match : result1.Matches)\r\n    {\r\n        std::string packageId = match.Package->GetProperty(PackageProperty::Id).get();\r\n        INFO(packageId);\r\n\r\n        SearchRequest id2;\r\n        id2.Inclusions.emplace_back(PackageMatchFilter{ PackageMatchField::Id, MatchType::CaseInsensitive, packageId });\r\n        auto result2 = source2->Search(id2);\r\n        REQUIRE(result2.Matches.size() == 1);\r\n        REQUIRE(match.Package->GetProperty(PackageProperty::Name) == result2.Matches[0].Package->GetProperty(PackageProperty::Name));\r\n    }\r\n}\r\n\r\nTEST_CASE(\"PredefinedInstalledSource_Create_Cached\", \"[installed][list][installed-cache]\")\r\n{\r\n    auto source1 = CreatePredefinedInstalledSource();\r\n    auto source2 = CreatePredefinedInstalledSource();\r\n\r\n    // Ensure the same identifier (which should mean the cache was not updated)\r\n    REQUIRE(\r\n        GetDatabaseIdentifier(source1)\r\n        ==\r\n        GetDatabaseIdentifier(source2)\r\n    );\r\n\r\n    RequirePackagesHaveSameNames(source1, source2);\r\n    RequirePackagesHaveSameNames(source2, source1);\r\n}\r\n\r\nTEST_CASE(\"PredefinedInstalledSource_Create_ForceCacheUpdate\", \"[installed][list][installed-cache]\")\r\n{\r\n    auto source1 = CreatePredefinedInstalledSource();\r\n    auto source2 = CreatePredefinedInstalledSource(Factory::Filter::NoneWithForcedCacheUpdate);\r\n\r\n    // Ensure different identifier (which should mean the cache was updated)\r\n    REQUIRE(\r\n        GetDatabaseIdentifier(source1)\r\n        !=\r\n        GetDatabaseIdentifier(source2)\r\n    );\r\n\r\n    RequirePackagesHaveSameNames(source1, source2);\r\n    RequirePackagesHaveSameNames(source2, source1);\r\n}\r\n\r\nTEST_CASE(\"PredefinedInstalledSource_Create_ForceCacheUpdate_StillCached\", \"[installed][list][installed-cache]\")\r\n{\r\n    auto source1 = CreatePredefinedInstalledSource();\r\n    auto source2 = CreatePredefinedInstalledSource(Factory::Filter::NoneWithForcedCacheUpdate);\r\n    auto source3 = CreatePredefinedInstalledSource();\r\n\r\n    CAPTURE(GetDatabaseIdentifier(source1), GetDatabaseIdentifier(source2), GetDatabaseIdentifier(source3));\r\n\r\n    // Ensure different identifier (which should mean the cache was updated)\r\n    REQUIRE(\r\n        GetDatabaseIdentifier(source1)\r\n        !=\r\n        GetDatabaseIdentifier(source2)\r\n    );\r\n\r\n    // Ensure the same identifier (which should mean the cache was not updated)\r\n    REQUIRE(\r\n        GetDatabaseIdentifier(source2)\r\n        ==\r\n        GetDatabaseIdentifier(source3)\r\n    );\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/PromptFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"WorkflowCommon.h\"\r\n#include <Commands/InstallCommand.h>\r\n#include <Workflows/PromptFlow.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::CLI;\r\nusing namespace AppInstaller::Settings;\r\n\r\nTEST_CASE(\"PromptFlow_InteractivityDisabled\", \"[PromptFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n    TestCommon::TestUserSettings testSettings;\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_LicenseAgreement.yaml\").GetPath().u8string());\r\n\r\n    SECTION(\"Disabled by setting\")\r\n    {\r\n        testSettings.Set<Setting::InteractivityDisable>(true);\r\n    }\r\n    SECTION(\"Disabled by arg\")\r\n    {\r\n        context.Args.AddArg(Execution::Args::Type::DisableInteractivity);\r\n    }\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify prompt is not shown\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::PackageAgreementsPrompt).get()) == std::string::npos);\r\n\r\n    // Verify installation failed\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED);\r\n    REQUIRE_FALSE(std::filesystem::exists(installResultPath.GetPath()));\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::PackageAgreementsNotAgreedTo).get()) != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"PromptFlow_InstallerAbortsTerminal_Proceed\", \"[PromptFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    // Accept that the installer may abort the terminal by saying \"Yes\" at the prompt\r\n    std::istringstream installInput{ \"y\" };\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, installInput };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_AbortsTerminal.yaml\").GetPath().u8string());\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify prompt is shown\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::InstallerAbortsTerminal).get()) != std::string::npos);\r\n\r\n    // Verify Installer is called.\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"PromptFlow_InstallerAbortsTerminal_Cancel\", \"[PromptFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    // Cancel the installation by saying \"No\" at the prompt that the installer may abort the terminal\r\n    std::istringstream installInput{ \"n\" };\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, installInput };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_AbortsTerminal.yaml\").GetPath().u8string());\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify prompt is shown\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::InstallerAbortsTerminal).get()) != std::string::npos);\r\n\r\n    // Verify installation failed\r\n    REQUIRE_TERMINATED_WITH(context, E_ABORT);\r\n    REQUIRE_FALSE(std::filesystem::exists(installResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"PromptFlow_InstallLocationRequired\", \"[PromptFlow][workflow]\")\r\n{\r\n    TestCommon::TempDirectory installLocation(\"TempDirectory\");\r\n    TestCommon::TestUserSettings testSettings;\r\n\r\n    std::istringstream installInput;\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, installInput };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_InstallLocationRequired.yaml\").GetPath().u8string());\r\n\r\n    bool shouldShowPrompt = false;\r\n    std::filesystem::path installResultPath = installLocation.GetPath() / \"TestExeInstalled.txt\";\r\n    SECTION(\"From argument\")\r\n    {\r\n        context.Args.AddArg(Execution::Args::Type::InstallLocation, installLocation.GetPath().string());\r\n    }\r\n    SECTION(\"From settings\")\r\n    {\r\n        testSettings.Set<Setting::InstallDefaultRoot>(installLocation.GetPath().string());\r\n\r\n        // When using the default location from settings, the Package ID is appended to the root\r\n        auto installLocationWithPackageId = installLocation.GetPath() / \"AppInstallerCliTest.TestInstaller\";\r\n        std::filesystem::create_directory(installLocationWithPackageId);\r\n        installResultPath = installLocationWithPackageId / \"TestExeInstalled.txt\";\r\n    }\r\n    SECTION(\"From prompt\")\r\n    {\r\n        installInput.str(installLocation.GetPath().string());\r\n        shouldShowPrompt = true;\r\n    }\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    bool promptShown = installOutput.str().find(Resource::LocString(Resource::String::InstallerRequiresInstallLocation).get()) != std::string::npos;\r\n    REQUIRE(shouldShowPrompt == promptShown);\r\n\r\n    // Verify Installer is called with the right parameters\r\n    REQUIRE(std::filesystem::exists(installResultPath));\r\n    std::ifstream installResultFile(installResultPath);\r\n    REQUIRE(installResultFile.is_open());\r\n    std::string installResultStr;\r\n    std::getline(installResultFile, installResultStr);\r\n    const auto installDirArgument = \"/InstallDir \" + installLocation.GetPath().string();\r\n    REQUIRE(installResultStr.find(installDirArgument) != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"PromptFlow_InstallLocationRequired_Missing\", \"[PromptFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_InstallLocationRequired.yaml\").GetPath().u8string());\r\n    // Disable interactivity so that there is not prompt and we cannot get the required location\r\n    context.Args.AddArg(Execution::Args::Type::DisableInteractivity);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify prompt is shown\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::InstallerRequiresInstallLocation).get()) != std::string::npos);\r\n\r\n    // Verify installation failed\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_INSTALL_LOCATION_REQUIRED);\r\n    REQUIRE_FALSE(std::filesystem::exists(installResultPath.GetPath()));\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/PropertySheet.props",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ImportGroup Label=\"PropertySheets\" />\n  <PropertyGroup Label=\"UserMacros\" />\n    <!--\n    To customize common C++/WinRT project properties: \n    * right-click the project node\n    * expand the Common Properties item\n    * select the C++/WinRT property page\n\n    For more advanced scenarios, and complete documentation, please see:\n    https://github.com/Microsoft/cppwinrt/tree/master/nuget \n    -->\n  <PropertyGroup />\n  <ItemDefinitionGroup />\n</Project>"
  },
  {
    "path": "src/AppInstallerCLITests/Regex.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <winget/Regex.h>\r\n#include <AppInstallerStrings.h>\r\n\r\nusing namespace std::string_view_literals;\r\nusing namespace AppInstaller::Regex;\r\n\r\n\r\nTEST_CASE(\"Regex_Construction\", \"[regex]\")\r\n{\r\n    Expression empty;\r\n    REQUIRE(!empty);\r\n\r\n    Expression lowerVowels(\"(a|e|i|o|u)\");\r\n    REQUIRE(lowerVowels);\r\n\r\n    // Ensure functionality to later verify against copy\r\n    REQUIRE(lowerVowels.IsMatch(L\"a\"));\r\n    REQUIRE(!lowerVowels.IsMatch(L\"b\"));\r\n\r\n    Expression copy = lowerVowels;\r\n    REQUIRE(copy);\r\n\r\n    // Ensure that the copy can also work\r\n    REQUIRE(lowerVowels.IsMatch(L\"a\"));\r\n    REQUIRE(copy.IsMatch(L\"a\"));\r\n\r\n    REQUIRE(!lowerVowels.IsMatch(L\"b\"));\r\n    REQUIRE(!copy.IsMatch(L\"b\"));\r\n\r\n    Expression moved = std::move(copy);\r\n    REQUIRE(moved);\r\n\r\n    REQUIRE(moved.IsMatch(L\"a\"));\r\n    REQUIRE(!moved.IsMatch(L\"b\"));\r\n}\r\n\r\nTEST_CASE(\"Regex_IsMatch\", \"[regex]\")\r\n{\r\n    Expression ArchitectureX32{ R\"((X32|X86)(?=\\P{Nd}|$)(?:\\sEDITION)?)\", Options::CaseInsensitive };\r\n\r\n    REQUIRE(ArchitectureX32.IsMatch(L\"X32\"));\r\n    REQUIRE(ArchitectureX32.IsMatch(L\"X86 edition\"));\r\n\r\n    REQUIRE(!ArchitectureX32.IsMatch(L\"Not a match\"));\r\n    REQUIRE(!ArchitectureX32.IsMatch(L\"X86 editions\"));\r\n}\r\n\r\nTEST_CASE(\"Regex_Replace\", \"[regex]\")\r\n{\r\n    Expression test{ R\"((b|d\\s|vy))\" };\r\n    REQUIRE(test.Replace(L\"The bright and swervy\", {}) == std::wstring{ L\"The right answer\" });\r\n\r\n    Expression vowels{ \"(a|e|i|o|u)\", Options::CaseInsensitive };\r\n    REQUIRE(vowels.Replace(L\"The QUICK brown fox jumped over the lazy dog.\", L\"[$0]\") == std::wstring{ L\"Th[e] Q[U][I]CK br[o]wn f[o]x j[u]mp[e]d [o]v[e]r th[e] l[a]zy d[o]g.\" });\r\n}\r\n\r\nTEST_CASE(\"Regex_ForEach\", \"[regex]\")\r\n{\r\n    std::wstring input = L\"The words in the Sentence but no more\";\r\n    std::vector<std::wstring> expected = { L\"The\", L\"words\", L\"in\", L\"the\", L\"Sentence\" };\r\n\r\n    Expression test{ R\"(\\S+)\" };\r\n\r\n    size_t i = 0;\r\n    test.ForEach(input,\r\n        [&](bool isMatch, std::wstring_view text)\r\n        {\r\n            if (!isMatch)\r\n            {\r\n                REQUIRE(text == L\" \");\r\n                return true;\r\n            }\r\n            else\r\n            {\r\n                REQUIRE(i < expected.size());\r\n                REQUIRE(text == expected[i]);\r\n                ++i;\r\n\r\n                return i < expected.size();\r\n            }\r\n        });\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/Registry.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <AppInstallerStrings.h>\r\n#include <winget/Registry.h>\r\n\r\nusing namespace std::string_literals;\r\nusing namespace std::string_view_literals;\r\nusing namespace AppInstaller::Registry;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace TestCommon;\r\n\r\nTEST_CASE(\"EmptyKey\", \"[registry]\")\r\n{\r\n    Key key;\r\n    REQUIRE(!key);\r\n}\r\n\r\nTEST_CASE(\"Constructor_NotFound\", \"[registry]\")\r\n{\r\n    Key key;\r\n    REQUIRE_THROWS_HR(key = Key(HKEY_LOCAL_MACHINE, L\"SOFTWARE\\\\Foo\\\\Bar\\\\Does\\\\Not\\\\Exist\"), HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));\r\n}\r\n\r\nTEST_CASE(\"OpenIfExists_NotFound\", \"[registry]\")\r\n{\r\n    Key key = Key::OpenIfExists(HKEY_LOCAL_MACHINE, L\"SOFTWARE\\\\Foo\\\\Bar\\\\Does\\\\Not\\\\Exist\");\r\n    REQUIRE(!key);\r\n}\r\n\r\nTEST_CASE(\"CreateKeyAndDelete\", \"[registry]\")\r\n{\r\n    std::wstring subkey = L\"Foo\\\\Bar\";\r\n    wil::unique_hkey root = RegCreateVolatileTestRoot();\r\n    Key key = Key::Create(root.get(), subkey, REG_OPTION_VOLATILE);\r\n    REQUIRE(key);\r\n    Key::Delete(root.get(), subkey, KEY_WOW64_64KEY);\r\n    Key secondKey = Key::OpenIfExists(root.get(), subkey);\r\n    REQUIRE(!secondKey);\r\n}\r\n\r\nTEST_CASE(\"SetKeyValue\", \"[registry]\")\r\n{\r\n    std::wstring valueName = L\"TestValueName\";\r\n    std::wstring valueValue = L\"TestValueValue\";\r\n    std::wstring subkey = L\"FooBar\";\r\n\r\n    wil::unique_hkey root = RegCreateVolatileTestRoot();\r\n    Key key = Key::Create(root.get(), subkey, REG_OPTION_VOLATILE);\r\n    key.SetValue(valueName, valueValue, REG_SZ);\r\n    auto value = key[valueName];\r\n    REQUIRE(value);\r\n    REQUIRE(value->GetType() == Value::Type::String);\r\n    REQUIRE(value->GetValue<Value::Type::String>() == ConvertToUTF8(valueValue));\r\n}\r\n\r\nTEST_CASE(\"DeleteKeyValue\", \"[registry]\")\r\n{\r\n    std::wstring valueName = L\"TestValueName\";\r\n    std::wstring valueValue = L\"TestValueValue\";\r\n    std::wstring subkey = L\"FooBar\";\r\n\r\n    wil::unique_hkey root = RegCreateVolatileTestRoot();\r\n    Key key = Key::Create(root.get(), subkey, REG_OPTION_VOLATILE);\r\n\r\n    key.SetValue(valueName, valueValue, REG_SZ);\r\n    auto value = key[valueName];\r\n    REQUIRE(value);\r\n\r\n    key.DeleteValue(valueName);\r\n    value = key[valueName];\r\n    REQUIRE(!value);\r\n}\r\n\r\nTEST_CASE(\"EnumerateKeys\", \"[registry]\")\r\n{\r\n    wil::unique_hkey root = RegCreateVolatileTestRoot();\r\n\r\n    std::vector<std::wstring> subKeyNames = { L\"A\", L\"BEE\", L\"SEE\", L\"deigh\" };\r\n    for (const auto& name : subKeyNames)\r\n    {\r\n        RegCreateVolatileSubKey(root.get(), name);\r\n    }\r\n\r\n    Key key{ root.get(), L\"\" };\r\n\r\n    for (const auto& subkey : key)\r\n    {\r\n        INFO(subkey.Name());\r\n\r\n        std::wstring nameUtf16 = ConvertToUTF16(subkey.Name());\r\n\r\n        auto itr = std::find(subKeyNames.begin(), subKeyNames.end(), nameUtf16);\r\n        if (itr == subKeyNames.end())\r\n        {\r\n            FAIL();\r\n        }\r\n        else\r\n        {\r\n            subKeyNames.erase(itr);\r\n        }\r\n\r\n        Key sk = subkey.Open();\r\n        REQUIRE(sk);\r\n    }\r\n\r\n    REQUIRE(subKeyNames.empty());\r\n}\r\n\r\nTEST_CASE(\"Values_String\", \"[registry]\")\r\n{\r\n    std::wstring valueName = L\"TestValueName\";\r\n    std::wstring valueValue = L\"TestValueValue\";\r\n\r\n    wil::unique_hkey root = RegCreateVolatileTestRoot();\r\n    SetRegistryValue(root.get(), valueName, valueValue);\r\n\r\n    Key key{ root.get(), L\"\" };\r\n\r\n    auto value = key[valueName];\r\n    REQUIRE(value);\r\n    REQUIRE(value->GetType() == Value::Type::String);\r\n    REQUIRE(value->GetValue<Value::Type::String>() == ConvertToUTF8(valueValue));\r\n}\r\n\r\nTEST_CASE(\"Values_WideStringWithNarrowNull\", \"[registry]\")\r\n{\r\n    std::wstring valueName = L\"TestValueName\";\r\n    std::wstring valueValue = L\"TestValueValue\";\r\n\r\n    wil::unique_hkey root = RegCreateVolatileTestRoot();\r\n\r\n    // Copy the bytes from the string value into a byte vector\r\n    std::vector<BYTE> valueBytes;\r\n    valueBytes.resize((valueValue.length() + 1) * sizeof(wchar_t));\r\n    memcpy_s(valueBytes.data(), valueBytes.size(), valueValue.c_str(), (valueValue.length() + 1) * sizeof(wchar_t));\r\n    // Remove the last byte to make a narrow null\r\n    valueBytes.resize(valueBytes.size() - 1);\r\n\r\n    SetRegistryValue(root.get(), valueName, valueBytes, REG_SZ);\r\n\r\n    Key key{ root.get(), L\"\" };\r\n\r\n    auto value = key[valueName];\r\n    REQUIRE(value);\r\n    REQUIRE(value->GetType() == Value::Type::String);\r\n    REQUIRE(value->GetValue<Value::Type::String>() == ConvertToUTF8(valueValue));\r\n}\r\n\r\nTEST_CASE(\"Values_ExpandString\", \"[registry]\")\r\n{\r\n    std::wstring valueName = L\"TestValueName\";\r\n    std::wstring valueValue = L\"%TEMP%\";\r\n\r\n    wil::unique_hkey root = RegCreateVolatileTestRoot();\r\n    SetRegistryValue(root.get(), valueName, valueValue, REG_EXPAND_SZ);\r\n\r\n    Key key{ root.get(), L\"\" };\r\n\r\n    auto value = key[valueName];\r\n    REQUIRE(value);\r\n    REQUIRE(value->GetType() == Value::Type::ExpandString);\r\n    REQUIRE(value->GetValue<Value::Type::String>() == ConvertToUTF8(valueValue));\r\n\r\n    wchar_t buffer[MAX_PATH];\r\n    GetTempPathW(ARRAYSIZE(buffer), buffer);\r\n\r\n    std::string tempPath = ConvertToUTF8(buffer);\r\n    if (!tempPath.empty() && tempPath.back() == '\\\\')\r\n    {\r\n        tempPath.resize(tempPath.size() - 1);\r\n    }\r\n\r\n    REQUIRE(value->GetValue<Value::Type::ExpandString>() == tempPath);\r\n}\r\n\r\nTEST_CASE(\"Values_Binary\", \"[registry]\")\r\n{\r\n    std::wstring valueName = L\"TestValueName\";\r\n    std::vector<BYTE> valueValue = { 2, 7, 3, 14, 42 };\r\n\r\n    wil::unique_hkey root = RegCreateVolatileTestRoot();\r\n    SetRegistryValue(root.get(), valueName, valueValue);\r\n\r\n    Key key{ root.get(), L\"\" };\r\n\r\n    auto value = key[valueName];\r\n    REQUIRE(value);\r\n    REQUIRE(value->GetType() == Value::Type::Binary);\r\n\r\n    auto result = value->GetValue<Value::Type::Binary>();\r\n    REQUIRE(result.size() == valueValue.size());\r\n    for (size_t i = 0; i < result.size(); ++i)\r\n    {\r\n        INFO(i);\r\n        REQUIRE(result[i] == valueValue[i]);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"Values_DWORD\", \"[registry]\")\r\n{\r\n    std::wstring valueName = L\"TestValueName\";\r\n    DWORD valueValue = 42;\r\n\r\n    wil::unique_hkey root = RegCreateVolatileTestRoot();\r\n    SetRegistryValue(root.get(), valueName, valueValue);\r\n\r\n    Key key{ root.get(), L\"\" };\r\n\r\n    auto value = key[valueName];\r\n    REQUIRE(value);\r\n    REQUIRE(value->GetType() == Value::Type::DWord);\r\n    REQUIRE(value->GetValue<Value::Type::DWord>() == valueValue);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/Resources.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"TestCommon.h\"\n#include <AppInstallerStrings.h>\n#include <ChannelStreams.h>\n#include <ExecutionReporter.h>\n\nusing namespace std::string_view_literals;\nusing namespace AppInstaller::Utility;\nusing namespace AppInstaller::Utility::literals;\nusing namespace AppInstaller::CLI;\n\n#define WINGET_TEST_OUTPUT_STREAM(_expected_, _input_) \\\n    do { \\\n        std::istringstream iInput; \\\n        std::ostringstream oInput; \\\n        std::istringstream iExpected; \\\n        std::ostringstream oExpected; \\\n        Execution::Reporter(oInput, iInput).Info() << _input_; \\\n        Execution::Reporter(oExpected, iExpected).Info() << _expected_; \\\n        REQUIRE(oExpected.str()== oInput.str()); \\\n    } while(0);\n\nTEST_CASE(\"Resources_StringId\", \"[resources]\")\n{\n    WINGET_TEST_OUTPUT_STREAM(\n        \"Filter results by command\"_liv,\n        Resource::String::CommandArgumentDescription\n    );\n}\n\nTEST_CASE(\"Resources_StringIdWithPlaceholders_LocIndString\", \"[resources]\")\n{\n    WINGET_TEST_OUTPUT_STREAM(\n        \"The value provided for the `First` argument is invalid; valid values are: Second\"_liv ,\n        Resource::String::InvalidArgumentValueError(\"First\"_liv, \"Second\"_liv)\n    );\n}\n\nTEST_CASE(\"Resources_StringIdWithPlaceholders_StringId\", \"[resources]\")\n{\n    WINGET_TEST_OUTPUT_STREAM(\n        \"This operation is disabled by Group Policy: Enable Additional Windows App Installer Sources\"_liv ,\n        Resource::String::DisabledByGroupPolicy(AppInstaller::StringResource::String::PolicyAdditionalSources)\n    );\n}\n\nTEST_CASE(\"Resources_StringIdWithPlaceholders_Arithmetic\", \"[resources]\")\n{\n    WINGET_TEST_OUTPUT_STREAM(\n        \"42 upgrades available.\"_liv ,\n        Resource::String::AvailableUpgrades(42)\n    );\n}\n"
  },
  {
    "path": "src/AppInstallerCLITests/Rest.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"cpprest/json.h\"\r\n#include <winget/Rest.h>\r\n\r\nusing namespace AppInstaller::Rest;\r\n\r\nTEST_CASE(\"ValidateAndGetRestAPIBaseUri\", \"[RestSource]\")\r\n{\r\n    REQUIRE(GetRestAPIBaseUri(\"https://restsource.azurewebsites.net/api/   \") == L\"https://restsource.azurewebsites.net/api\");\r\n    REQUIRE(GetRestAPIBaseUri(\"http://rest_sourc e.azurewebsites.net/api\") == L\"http://rest_sourc%20e.azurewebsites.net/api\");\r\n    REQUIRE(GetRestAPIBaseUri(\"http://restsource.azurewebsites.net/v1.0/%v1\") == L\"http://restsource.azurewebsites.net/v1.0/%25v1\");\r\n}\r\n\r\nTEST_CASE(\"IsValidUri\", \"[RestSource]\")\r\n{\r\n    REQUIRE(IsValidUri(L\"http://rest%20source.azurewebsites.net/api\"));\r\n    REQUIRE(!IsValidUri(L\"http://rest source.azurewebsites.net/api\"));\r\n}\r\n\r\nTEST_CASE(\"AppendPathToUri\", \"[RestSource]\")\r\n{\r\n    REQUIRE(AppendPathToUri(L\"http://restsource.azurewebsites.net/api/\", L\"/path\") == L\"http://restsource.azurewebsites.net/api/path\");\r\n    REQUIRE(AppendPathToUri(L\"http://restsource.azurewebsites.net/api/\", L\"/pat  h\") == L\"http://restsource.azurewebsites.net/api/pat%20%20h\");\r\n    REQUIRE(AppendPathToUri(L\"http://restsource.azurewebsites.net/api/\", L\"/path+version\") == L\"http://restsource.azurewebsites.net/api/path%2Bversion\");\r\n}\r\n\r\nTEST_CASE(\"AppendQueryParamsToUri\", \"[RestSource]\")\r\n{\r\n    utility::string_t url = L\"http://restsource.azurewebsites.net/api\";\r\n    std::map<std::string_view, std::string> queryParams;\r\n    queryParams.emplace(\"Version\", \"1.0 .0\");\r\n    queryParams.emplace(\"Channel\", \"beta+\");\r\n\r\n    REQUIRE(AppendQueryParamsToUri(url, queryParams) == L\"http://restsource.azurewebsites.net/api?Channel=beta%2B&Version=1.0%20.0\");\r\n}\r\n\r\nTEST_CASE(\"GetUniqueItems\", \"[RestSource]\")\r\n{\r\n    std::vector<std::string> list;\r\n    REQUIRE(GetUniqueItems(list).size() == 0);\r\n\r\n    std::vector<std::string> listWithDuplicates;\r\n    listWithDuplicates.emplace_back(\"object1\");\r\n    listWithDuplicates.emplace_back(\"object1\");\r\n    listWithDuplicates.emplace_back(\"object2\");\r\n    listWithDuplicates.emplace_back(\"object2\");\r\n    listWithDuplicates.emplace_back(\"object3\");\r\n    std::vector<std::string> result = GetUniqueItems(listWithDuplicates);\r\n    REQUIRE(result.size() == 3);\r\n    REQUIRE(result.at(0) == \"object1\");\r\n    REQUIRE(result.at(1) == \"object2\");\r\n    REQUIRE(result.at(2) == \"object3\");\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/RestClient.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestRestRequestHandler.h\"\r\n#include <Rest/RestClient.h>\r\n#include <Rest/RestInformationCache.h>\r\n#include <Rest/Schema/IRestClient.h>\r\n#include <Rest/Schema/InformationResponseDeserializer.h>\r\n#include <AppInstallerVersions.h>\r\n#include <AppInstallerErrors.h>\r\n#include <AppInstallerRuntime.h>\r\n\r\nusing namespace AppInstaller;\r\nusing namespace AppInstaller::Http;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::Repository::Rest;\r\nusing namespace AppInstaller::Repository::Rest::Schema;\r\n\r\nconst std::string TestRestUri = \"http://restsource.net\";\r\n\r\nRestClient CreateRestClient(\r\n    const std::string& restApi,\r\n    const std::optional<std::string>& customHeader,\r\n    std::string_view caller,\r\n    const Http::HttpClientHelper& helper,\r\n    const Authentication::AuthenticationArguments& authArgs = {})\r\n{\r\n    return RestClient::Create(restApi, customHeader, caller, helper, RestClient::GetInformation(restApi, customHeader, caller, helper), authArgs);\r\n}\r\n\r\nTEST_CASE(\"GetLatestCommonVersion\", \"[RestSource]\")\r\n{\r\n    std::set<AppInstaller::Utility::Version> wingetSupportedContracts = { Version {\"1.0.0\"}, Version {\"1.2.0\"} };\r\n    std::vector<std::string> versions{ \"1.0.0\", \"2.0.0\", \"1.2.0\" };\r\n    std::optional<Version> actual = RestClient::GetLatestCommonVersion(versions, wingetSupportedContracts);\r\n    REQUIRE(actual);\r\n    REQUIRE(actual.value().ToString() == \"1.2.0\");\r\n}\r\n\r\nTEST_CASE(\"GetLatestCommonVersion_OnlyMajorMinorVersionMatched\", \"[RestSource]\")\r\n{\r\n    std::set<AppInstaller::Utility::Version> wingetSupportedContracts = { Version {\"1.0.0\"}, Version {\"1.2.0\"} };\r\n    std::vector<std::string> versions{ \"1.0.0\", \"2.0.0\", \"1.2.1\" };\r\n    std::optional<Version> actual = RestClient::GetLatestCommonVersion(versions, wingetSupportedContracts);\r\n    REQUIRE(actual);\r\n    REQUIRE(actual.value().ToString() == \"1.2.0\");\r\n}\r\n\r\nTEST_CASE(\"GetLatestCommonVersion_UnsupportedVersion\", \"[RestSource]\")\r\n{\r\n    std::set<AppInstaller::Utility::Version> wingetSupportedContracts = { Version {\"3.0.0\"}, Version {\"4.2.0\"} };\r\n    std::vector<std::string> versions{ \"1.0.0\", \"2.0.0\" };\r\n    std::optional<Version> actual = RestClient::GetLatestCommonVersion(versions, wingetSupportedContracts);\r\n    REQUIRE(!actual);\r\n}\r\n\r\nTEST_CASE(\"GetSupportedInterface\", \"[RestSource]\")\r\n{\r\n    IRestClient::Information info{ \"TestId\", { \"1.0.0\" } };\r\n\r\n    Version version{ \"1.0.0\" };\r\n    REQUIRE(RestClient::GetSupportedInterface(TestRestUri, {}, info, {}, version, {})->GetVersion() == version);\r\n\r\n    // Update this test to next version so that we don't forget to add to supported versions before rest e2e tests are available.\r\n    Version invalid{ \"1.13.0\" };\r\n    REQUIRE_THROWS_HR(RestClient::GetSupportedInterface(TestRestUri, {}, info, {}, invalid, {}), APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_VERSION);\r\n\r\n    Authentication::AuthenticationArguments authArgs;\r\n    authArgs.Mode = Authentication::AuthenticationMode::Silent;\r\n    Version version_1_7{ \"1.7.0\" };\r\n\r\n    // GetSupportedInterface throws on unknown authentication type.\r\n    IRestClient::Information infoWithUnknownAuthenticationType{ \"TestId\", { \"1.7.0\" } };\r\n    infoWithUnknownAuthenticationType.Authentication.Type = Authentication::AuthenticationType::Unknown;\r\n    REQUIRE_THROWS_HR(RestClient::GetSupportedInterface(TestRestUri, {}, infoWithUnknownAuthenticationType, authArgs, version_1_7, {}), APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED);\r\n\r\n    // GetSupportedInterface throws on invalid authentication info.\r\n    IRestClient::Information infoWithInvalidAuthenticationInfo{ \"TestId\", { \"1.7.0\" } };\r\n    infoWithInvalidAuthenticationInfo.Authentication.Type = Authentication::AuthenticationType::MicrosoftEntraId;\r\n    REQUIRE_THROWS_HR(RestClient::GetSupportedInterface(TestRestUri, {}, infoWithInvalidAuthenticationInfo, authArgs, version_1_7, {}), APPINSTALLER_CLI_ERROR_INVALID_AUTHENTICATION_INFO);\r\n}\r\n\r\nTEST_CASE(\"GetInformation_Success\", \"[RestSource]\")\r\n{\r\n    utility::string_t sample = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : {\r\n              \"SourceIdentifier\": \"Source123\",\r\n              \"ServerSupportedVersions\": [\r\n                \"1.0.0\",\r\n                \"1.1.0\"\r\n               ],\r\n              \"SourceAgreements\": {\r\n                \"AgreementsIdentifier\": \"agreementV1\",\r\n                \"Agreements\": [{\r\n                    \"AgreementLabel\": \"EULA\",\r\n                    \"Agreement\": \"this is store agreement\",\r\n                    \"AgreementUrl\": \"https://store.agreement\"\r\n                  }\r\n                ]\r\n              },\r\n              \"RequiredQueryParameters\": [\r\n                \"Market\"\r\n              ],\r\n              \"RequiredPackageMatchFields\": [\r\n                \"Market\"\r\n              ],\r\n              \"UnsupportedQueryParameters\": [\r\n                \"Moniker\"\r\n              ],\r\n              \"UnsupportedPackageMatchFields\": [\r\n                \"Moniker\"\r\n              ]\r\n        }})delimiter\");\r\n\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, sample) };\r\n    IRestClient::Information information = RestClient::GetInformation(TestRestUri, {}, {}, helper);\r\n    REQUIRE(information.SourceIdentifier == \"Source123\");\r\n    REQUIRE(information.ServerSupportedVersions.size() == 2);\r\n    REQUIRE(information.ServerSupportedVersions.at(0) == \"1.0.0\");\r\n    REQUIRE(information.ServerSupportedVersions.at(1) == \"1.1.0\");\r\n    REQUIRE(information.SourceAgreementsIdentifier == \"agreementV1\");\r\n    REQUIRE(information.SourceAgreements.size() == 1);\r\n    REQUIRE(information.SourceAgreements.at(0).Label == \"EULA\");\r\n    REQUIRE(information.SourceAgreements.at(0).Text == \"this is store agreement\");\r\n    REQUIRE(information.SourceAgreements.at(0).Url == \"https://store.agreement\");\r\n    REQUIRE(information.RequiredQueryParameters.size() == 1);\r\n    REQUIRE(information.RequiredQueryParameters.at(0) == \"Market\");\r\n    REQUIRE(information.RequiredPackageMatchFields.size() == 1);\r\n    REQUIRE(information.RequiredPackageMatchFields.at(0) == \"Market\");\r\n    REQUIRE(information.UnsupportedQueryParameters.size() == 1);\r\n    REQUIRE(information.UnsupportedQueryParameters.at(0) == \"Moniker\");\r\n    REQUIRE(information.UnsupportedPackageMatchFields.size() == 1);\r\n    REQUIRE(information.UnsupportedPackageMatchFields.at(0) == \"Moniker\");\r\n    REQUIRE(information.Authentication.Type == Authentication::AuthenticationType::None);\r\n    REQUIRE_FALSE(information.Authentication.MicrosoftEntraIdInfo.has_value());\r\n}\r\n\r\nTEST_CASE(\"GetInformation_WithAuthenticationInfo_Success\", \"[RestSource]\")\r\n{\r\n    utility::string_t sample = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : {\r\n              \"SourceIdentifier\": \"Source123\",\r\n              \"ServerSupportedVersions\": [\r\n                \"1.7.0\"\r\n               ],\r\n              \"SourceAgreements\": {\r\n                \"AgreementsIdentifier\": \"agreementV1\",\r\n                \"Agreements\": [{\r\n                    \"AgreementLabel\": \"EULA\",\r\n                    \"Agreement\": \"this is store agreement\",\r\n                    \"AgreementUrl\": \"https://store.agreement\"\r\n                  }\r\n                ]\r\n              },\r\n              \"RequiredQueryParameters\": [\r\n                \"Market\"\r\n              ],\r\n              \"RequiredPackageMatchFields\": [\r\n                \"Market\"\r\n              ],\r\n              \"UnsupportedQueryParameters\": [\r\n                \"Moniker\"\r\n              ],\r\n              \"UnsupportedPackageMatchFields\": [\r\n                \"Moniker\"\r\n              ],\r\n              \"Authentication\": {\r\n                \"AuthenticationType\": \"microsoftEntraId\",\r\n                \"MicrosoftEntraIdAuthenticationInfo\" : {\r\n                  \"Resource\": \"GUID\",\r\n                  \"Scope\" : \"test\"\r\n                }\r\n              }\r\n        }})delimiter\");\r\n\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, sample) };\r\n    IRestClient::Information information = RestClient::GetInformation(TestRestUri, {}, {}, helper);\r\n    REQUIRE(information.SourceIdentifier == \"Source123\");\r\n    REQUIRE(information.ServerSupportedVersions.size() == 1);\r\n    REQUIRE(information.ServerSupportedVersions.at(0) == \"1.7.0\");\r\n    REQUIRE(information.SourceAgreementsIdentifier == \"agreementV1\");\r\n    REQUIRE(information.SourceAgreements.size() == 1);\r\n    REQUIRE(information.SourceAgreements.at(0).Label == \"EULA\");\r\n    REQUIRE(information.SourceAgreements.at(0).Text == \"this is store agreement\");\r\n    REQUIRE(information.SourceAgreements.at(0).Url == \"https://store.agreement\");\r\n    REQUIRE(information.RequiredQueryParameters.size() == 1);\r\n    REQUIRE(information.RequiredQueryParameters.at(0) == \"Market\");\r\n    REQUIRE(information.RequiredPackageMatchFields.size() == 1);\r\n    REQUIRE(information.RequiredPackageMatchFields.at(0) == \"Market\");\r\n    REQUIRE(information.UnsupportedQueryParameters.size() == 1);\r\n    REQUIRE(information.UnsupportedQueryParameters.at(0) == \"Moniker\");\r\n    REQUIRE(information.UnsupportedPackageMatchFields.size() == 1);\r\n    REQUIRE(information.UnsupportedPackageMatchFields.at(0) == \"Moniker\");\r\n    REQUIRE(information.Authentication.Type == Authentication::AuthenticationType::MicrosoftEntraId);\r\n    REQUIRE(information.Authentication.MicrosoftEntraIdInfo.has_value());\r\n    REQUIRE(information.Authentication.MicrosoftEntraIdInfo->Resource == \"GUID\");\r\n    REQUIRE(information.Authentication.MicrosoftEntraIdInfo->Scope == \"test\");\r\n}\r\n\r\nTEST_CASE(\"GetInformation_Fail_AgreementsWithoutIdentifier\", \"[RestSource]\")\r\n{\r\n    utility::string_t sample = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : {\r\n              \"SourceIdentifier\": \"Source123\",\r\n              \"ServerSupportedVersions\": [\r\n                \"1.0.0\",\r\n                \"1.1.0\"],\r\n              \"SourceAgreements\": {\r\n                \"Agreements\": [{\r\n                    \"AgreementLabel\": \"EULA\",\r\n                    \"Agreement\": \"this is store agreement\",\r\n                    \"AgreementUrl\": \"https://store.agreement\"\r\n                  }\r\n                ]\r\n              }\r\n        }})delimiter\");\r\n\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, sample) };\r\n    REQUIRE_THROWS_HR(RestClient::GetInformation(TestRestUri, {}, {}, helper), APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE);\r\n}\r\n\r\nTEST_CASE(\"GetInformation_Fail_InvalidMicrosoftEntraIdInfo\", \"[RestSource]\")\r\n{\r\n    utility::string_t sample1 = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : {\r\n              \"SourceIdentifier\": \"Source123\",\r\n              \"ServerSupportedVersions\": [\r\n                \"1.7.0\"\r\n               ],\r\n              \"Authentication\": {\r\n                \"AuthenticationType\": \"microsoftEntraId\"\r\n              }\r\n        }})delimiter\");\r\n\r\n    HttpClientHelper helper1{ GetTestRestRequestHandler(web::http::status_codes::OK, sample1) };\r\n    REQUIRE_THROWS_HR(RestClient::GetInformation(TestRestUri, {}, {}, helper1), APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE);\r\n\r\n    utility::string_t sample2 = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : {\r\n              \"SourceIdentifier\": \"Source123\",\r\n              \"ServerSupportedVersions\": [\r\n                \"1.7.0\"\r\n               ],\r\n              \"Authentication\": {\r\n                \"AuthenticationType\": \"microsoftEntraId\",\r\n                \"MicrosoftEntraIdAuthenticationInfo\" : {\r\n                  \"Resource\": \"\",\r\n                  \"Scope\" : \"test\"\r\n                }\r\n              }\r\n        }})delimiter\");\r\n\r\n    HttpClientHelper helper2{ GetTestRestRequestHandler(web::http::status_codes::OK, sample2) };\r\n    REQUIRE_THROWS_HR(RestClient::GetInformation(TestRestUri, {}, {}, helper2), APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE);\r\n\r\n    utility::string_t sample3 = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : {\r\n              \"SourceIdentifier\": \"Source123\",\r\n              \"ServerSupportedVersions\": [\r\n                \"1.7.0\"\r\n               ],\r\n              \"Authentication\": {\r\n                \"AuthenticationType\": \"microsoftEntraId\",\r\n                \"MicrosoftEntraIdAuthenticationInfo\" : {\r\n                  \"Scope\" : \"test\"\r\n                }\r\n              }\r\n        }})delimiter\");\r\n\r\n    HttpClientHelper helper3{ GetTestRestRequestHandler(web::http::status_codes::OK, sample3) };\r\n    REQUIRE_THROWS_HR(RestClient::GetInformation(TestRestUri, {}, {}, helper3), APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE);\r\n\r\n    utility::string_t sample4 = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : {\r\n              \"SourceIdentifier\": \"Source123\",\r\n              \"ServerSupportedVersions\": [\r\n                \"1.7.0\"\r\n               ],\r\n              \"Authentication\": {\r\n                \"AuthenticationType\": \"microsoftEntraIdForAzureBlobStorage\"\r\n              }\r\n        }})delimiter\");\r\n\r\n    HttpClientHelper helper4{ GetTestRestRequestHandler(web::http::status_codes::OK, sample4) };\r\n    Authentication::AuthenticationArguments authArgs;\r\n    authArgs.Mode = Authentication::AuthenticationMode::Silent;\r\n    Version version_1_7{ \"1.7.0\" };\r\n    REQUIRE_THROWS_HR(RestClient::GetSupportedInterface(TestRestUri, {}, RestClient::GetInformation(TestRestUri, {}, {}, helper4), authArgs, version_1_7, {}), APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED);\r\n}\r\n\r\nTEST_CASE(\"RestClientCreate_UnsupportedVersion\", \"[RestSource]\")\r\n{\r\n    utility::string_t sample = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : {\r\n              \"SourceIdentifier\": \"Source123\",\r\n              \"ServerSupportedVersions\": [\r\n                \"1.2.0\",\r\n                \"2.0.0\"]\r\n        }})delimiter\");\r\n\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, sample) };\r\n    REQUIRE_THROWS_HR(CreateRestClient(\"https://restsource.com/api\", {}, {}, helper), APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE);\r\n}\r\n\r\nTEST_CASE(\"RestClientCreate_UnsupportedAuthenticationMethod\", \"[RestSource]\")\r\n{\r\n    utility::string_t sample = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : {\r\n              \"SourceIdentifier\": \"Source123\",\r\n              \"ServerSupportedVersions\": [\r\n                \"1.7.0\"\r\n               ],\r\n              \"Authentication\": {\r\n                \"AuthenticationType\": \"unknown\"\r\n              }\r\n        }})delimiter\");\r\n\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, sample) };\r\n    Authentication::AuthenticationArguments authArgs;\r\n    authArgs.Mode = Authentication::AuthenticationMode::Silent;\r\n    REQUIRE_THROWS_HR(CreateRestClient(\"https://restsource.com/api\", {}, {}, helper, authArgs), APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED);\r\n}\r\n\r\nTEST_CASE(\"RestClientCreate_InvalidAuthenticationArguments\", \"[RestSource]\")\r\n{\r\n    utility::string_t sample = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : {\r\n              \"SourceIdentifier\": \"Source123\",\r\n              \"ServerSupportedVersions\": [\r\n                \"1.7.0\"\r\n               ],\r\n              \"Authentication\": {\r\n                \"AuthenticationType\": \"microsoftEntraId\",\r\n                \"MicrosoftEntraIdAuthenticationInfo\" : {\r\n                  \"Resource\" : \"test\"\r\n                }\r\n              }\r\n        }})delimiter\");\r\n\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, sample) };\r\n    Authentication::AuthenticationArguments authArgs;\r\n    authArgs.Mode = Authentication::AuthenticationMode::Unknown;\r\n    REQUIRE_THROWS_HR(CreateRestClient(\"https://restsource.com/api\", {}, {}, helper, authArgs), E_UNEXPECTED);\r\n}\r\n\r\nTEST_CASE(\"RestClientCreate_1.0_Success\", \"[RestSource]\")\r\n{\r\n    utility::string_t sample = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : {\r\n              \"SourceIdentifier\": \"Source123\",\r\n              \"ServerSupportedVersions\": [\r\n                \"1.0.0\",\r\n                \"2.0.0\"]\r\n        }})delimiter\");\r\n\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, sample) };\r\n    RestClient client = CreateRestClient(TestRestUri, {}, {}, helper);\r\n    REQUIRE(client.GetSourceIdentifier() == \"Source123\");\r\n}\r\n\r\nTEST_CASE(\"RestClientCreate_1.1_Success\", \"[RestSource]\")\r\n{\r\n    utility::string_t sample = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : {\r\n              \"SourceIdentifier\": \"Source123\",\r\n              \"ServerSupportedVersions\": [\r\n                \"1.0.0\",\r\n                \"1.1.0\"],\r\n              \"SourceAgreements\": {\r\n                \"AgreementsIdentifier\": \"agreementV1\",\r\n                \"Agreements\": [{\r\n                    \"AgreementLabel\": \"EULA\",\r\n                    \"Agreement\": \"this is store agreement\",\r\n                    \"AgreementUrl\": \"https://store.agreement\"\r\n                  }\r\n                ]\r\n              },\r\n              \"RequiredQueryParameters\": [\r\n                \"Market\"\r\n              ],\r\n              \"RequiredPackageMatchFields\": [\r\n                \"Market\"\r\n              ],\r\n              \"UnsupportedQueryParameters\": [\r\n                \"Moniker\"\r\n              ],\r\n              \"UnsupportedPackageMatchFields\": [\r\n                \"Moniker\"\r\n              ]\r\n        }})delimiter\");\r\n\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, sample) };\r\n    RestClient client = CreateRestClient(TestRestUri, {}, {}, helper);\r\n    REQUIRE(client.GetSourceIdentifier() == \"Source123\");\r\n    auto information = client.GetSourceInformation();\r\n    REQUIRE(information.SourceAgreementsIdentifier == \"agreementV1\");\r\n    REQUIRE(information.SourceAgreements.size() == 1);\r\n    REQUIRE(information.SourceAgreements.at(0).Label == \"EULA\");\r\n    REQUIRE(information.SourceAgreements.at(0).Text == \"this is store agreement\");\r\n    REQUIRE(information.SourceAgreements.at(0).Url == \"https://store.agreement\");\r\n    REQUIRE(information.RequiredQueryParameters.size() == 1);\r\n    REQUIRE(information.RequiredQueryParameters.at(0) == \"Market\");\r\n    REQUIRE(information.RequiredPackageMatchFields.size() == 1);\r\n    REQUIRE(information.RequiredPackageMatchFields.at(0) == \"Market\");\r\n    REQUIRE(information.UnsupportedQueryParameters.size() == 1);\r\n    REQUIRE(information.UnsupportedQueryParameters.at(0) == \"Moniker\");\r\n    REQUIRE(information.UnsupportedPackageMatchFields.size() == 1);\r\n    REQUIRE(information.UnsupportedPackageMatchFields.at(0) == \"Moniker\");\r\n}\r\n\r\nTEST_CASE(\"RestClientCreate_1.7_Success\", \"[RestSource]\")\r\n{\r\n    if (Runtime::IsRunningAsSystem())\r\n    {\r\n        WARN(\"Test does not support running as system. Skipped.\");\r\n        return;\r\n    }\r\n\r\n    utility::string_t sample = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : {\r\n              \"SourceIdentifier\": \"Source123\",\r\n              \"ServerSupportedVersions\": [\r\n                \"1.7.0\"\r\n               ],\r\n              \"SourceAgreements\": {\r\n                \"AgreementsIdentifier\": \"agreementV1\",\r\n                \"Agreements\": [{\r\n                    \"AgreementLabel\": \"EULA\",\r\n                    \"Agreement\": \"this is store agreement\",\r\n                    \"AgreementUrl\": \"https://store.agreement\"\r\n                  }\r\n                ]\r\n              },\r\n              \"RequiredQueryParameters\": [\r\n                \"Market\"\r\n              ],\r\n              \"RequiredPackageMatchFields\": [\r\n                \"Market\"\r\n              ],\r\n              \"UnsupportedQueryParameters\": [\r\n                \"Moniker\"\r\n              ],\r\n              \"UnsupportedPackageMatchFields\": [\r\n                \"Moniker\"\r\n              ],\r\n              \"Authentication\": {\r\n                \"AuthenticationType\": \"microsoftEntraId\",\r\n                \"MicrosoftEntraIdAuthenticationInfo\" : {\r\n                  \"Resource\": \"GUID\",\r\n                  \"Scope\" : \"test\"\r\n                }\r\n              }\r\n        }})delimiter\");\r\n\r\n    Authentication::AuthenticationArguments authArgs;\r\n    authArgs.Mode = Authentication::AuthenticationMode::Silent;\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, sample) };\r\n    RestClient client = CreateRestClient(TestRestUri, {}, {}, helper, authArgs);\r\n    REQUIRE(client.GetSourceIdentifier() == \"Source123\");\r\n    auto information = client.GetSourceInformation();\r\n    REQUIRE(information.SourceAgreementsIdentifier == \"agreementV1\");\r\n    REQUIRE(information.SourceAgreements.size() == 1);\r\n    REQUIRE(information.SourceAgreements.at(0).Label == \"EULA\");\r\n    REQUIRE(information.SourceAgreements.at(0).Text == \"this is store agreement\");\r\n    REQUIRE(information.SourceAgreements.at(0).Url == \"https://store.agreement\");\r\n    REQUIRE(information.RequiredQueryParameters.size() == 1);\r\n    REQUIRE(information.RequiredQueryParameters.at(0) == \"Market\");\r\n    REQUIRE(information.RequiredPackageMatchFields.size() == 1);\r\n    REQUIRE(information.RequiredPackageMatchFields.at(0) == \"Market\");\r\n    REQUIRE(information.UnsupportedQueryParameters.size() == 1);\r\n    REQUIRE(information.UnsupportedQueryParameters.at(0) == \"Moniker\");\r\n    REQUIRE(information.UnsupportedPackageMatchFields.size() == 1);\r\n    REQUIRE(information.UnsupportedPackageMatchFields.at(0) == \"Moniker\");\r\n    REQUIRE(information.Authentication.Type == Authentication::AuthenticationType::MicrosoftEntraId);\r\n    REQUIRE(information.Authentication.MicrosoftEntraIdInfo.has_value());\r\n    REQUIRE(information.Authentication.MicrosoftEntraIdInfo->Resource == \"GUID\");\r\n    REQUIRE(information.Authentication.MicrosoftEntraIdInfo->Scope == \"test\");\r\n}\r\n\r\n// Simulate the msstore cache round trip using real world data.\r\nTEST_CASE(\"RestInformationCache_RoundTrip\", \"[RestInformationCache]\")\r\n{\r\n    Settings::Stream{ Settings::Stream::RestInformationCache }.Remove();\r\n\r\n    std::wstring endpoint = L\"https://test-url-com/information\";\r\n    CacheControlPolicy cacheControl{ L\"public, max-age=77287\" };\r\n    auto response = web::json::value::parse(\r\nR\"delimiter({\r\n    \"$type\": \"Microsoft.Marketplace.Storefront.StoreEdgeFD.BusinessLogic.Response.PackageMetadata.PackageMetadataResponse, StoreEdgeFD\",\r\n    \"Data\": {\r\n        \"$type\": \"Microsoft.Marketplace.Storefront.StoreEdgeFD.BusinessLogic.Response.PackageMetadata.PackageMetadataData, StoreEdgeFD\",\r\n        \"SourceIdentifier\": \"StoreEdgeFD\",\r\n        \"SourceAgreements\": {\r\n            \"$type\": \"Microsoft.Marketplace.Storefront.StoreEdgeFD.BusinessLogic.Response.PackageMetadata.SourceAgreements, StoreEdgeFD\",\r\n            \"AgreementsIdentifier\": \"StoreEdgeFD\",\r\n            \"Agreements\": [\r\n                {\r\n                    \"$type\": \"Microsoft.Marketplace.Storefront.StoreEdgeFD.BusinessLogic.Response.PackageManifest.AgreementDetail, StoreEdgeFD\",\r\n                    \"AgreementLabel\": \"Terms of Transaction\",\r\n                    \"AgreementUrl\": \"https://aka.ms/microsoft-store-terms-of-transaction\"\r\n                }\r\n            ]\r\n        },\r\n        \"ServerSupportedVersions\": [ \"1.0.0\", \"1.1.0\", \"1.6.0\" ],\r\n        \"RequiredQueryParameters\": [ \"market\" ],\r\n        \"RequiredPackageMatchFields\": [ \"market\" ]\r\n    }\r\n})delimiter\");\r\n\r\n    RestInformationCache cache;\r\n    cache.Cache(endpoint, {}, {}, cacheControl, response);\r\n    auto cachedValue = cache.Get(endpoint, {}, {});\r\n\r\n    REQUIRE(cachedValue.has_value());\r\n\r\n    InformationResponseDeserializer deserializer;\r\n    const auto expected = deserializer.Deserialize(response);\r\n    const auto& actual = cachedValue.value();\r\n\r\n    REQUIRE(expected.SourceIdentifier == actual.SourceIdentifier);\r\n    REQUIRE(expected.SourceAgreementsIdentifier == actual.SourceAgreementsIdentifier);\r\n    REQUIRE(expected.SourceAgreements.size() == actual.SourceAgreements.size());\r\n    REQUIRE(1 == actual.SourceAgreements.size());\r\n    REQUIRE(expected.SourceAgreements[0].Label == actual.SourceAgreements[0].Label);\r\n    REQUIRE(expected.SourceAgreements[0].Text == actual.SourceAgreements[0].Text);\r\n    REQUIRE(expected.SourceAgreements[0].Url == actual.SourceAgreements[0].Url);\r\n\r\n    REQUIRE(expected.ServerSupportedVersions.size() == actual.ServerSupportedVersions.size());\r\n    for (const auto& expectedVersion : expected.ServerSupportedVersions)\r\n    {\r\n        REQUIRE(std::find(actual.ServerSupportedVersions.begin(), actual.ServerSupportedVersions.end(), expectedVersion) != actual.ServerSupportedVersions.end());\r\n    }\r\n\r\n    REQUIRE(expected.RequiredQueryParameters.size() == actual.RequiredQueryParameters.size());\r\n    REQUIRE(1 == actual.RequiredQueryParameters.size());\r\n    REQUIRE(expected.RequiredQueryParameters[0] == actual.RequiredQueryParameters[0]);\r\n\r\n    REQUIRE(expected.RequiredPackageMatchFields.size() == actual.RequiredPackageMatchFields.size());\r\n    REQUIRE(1 == actual.RequiredPackageMatchFields.size());\r\n    REQUIRE(expected.RequiredPackageMatchFields[0] == actual.RequiredPackageMatchFields[0]);\r\n}\r\n\r\nweb::json::value CreateInformationResponse(std::string_view identifier)\r\n{\r\n    std::ostringstream stream;\r\n    stream << R\"({ \"Data\": { \"SourceIdentifier\": \")\" << identifier << R\"(\", \"ServerSupportedVersions\": [ \"1.0.0\" ] } })\";\r\n\r\n    return web::json::value::parse(stream.str());\r\n}\r\n\r\nTEST_CASE(\"RestInformationCache_Get\", \"[RestInformationCache]\")\r\n{\r\n    Settings::Stream{ Settings::Stream::RestInformationCache }.Remove();\r\n\r\n    std::wstring endpoint1 = L\"https://test-url1-com/information\";\r\n    std::wstring endpoint2 = L\"https://test-url2-com/information\";\r\n    std::wstring endpointNotPresent = L\"https://test-url-not-present-com/information\";\r\n    std::string header = \"Header\";\r\n    std::string caller = \"Caller\";\r\n    std::string publicEndpoint1Identifier = \"Identifier1\";\r\n    std::string privateEndpoint1Identifier = \"Identifier2\";\r\n    std::string privateEndpoint2Identifier = \"Identifier3\";\r\n    auto publicEndpoint1Response = CreateInformationResponse(publicEndpoint1Identifier);\r\n    auto privateEndpoint1Response = CreateInformationResponse(privateEndpoint1Identifier);\r\n    auto privateEndpoint2Response = CreateInformationResponse(privateEndpoint2Identifier);\r\n\r\n    RestInformationCache cache;\r\n\r\n    // Cache:\r\n    //  1. public and private for same endpoint\r\n    cache.Cache(endpoint1, header, caller, { L\"public\" }, publicEndpoint1Response);\r\n    cache.Cache(endpoint1, header, caller, {}, privateEndpoint1Response);\r\n    //  2. another endpoint with private data (same headers)\r\n    cache.Cache(endpoint2, header, caller, {}, privateEndpoint2Response);\r\n\r\n    SECTION(\"Same headers prefers private\")\r\n    {\r\n        auto cachedValue = cache.Get(endpoint1, header, caller);\r\n        REQUIRE(cachedValue.has_value());\r\n        REQUIRE(privateEndpoint1Identifier == cachedValue->SourceIdentifier);\r\n    }\r\n    SECTION(\"Different headers falls back to public\")\r\n    {\r\n        auto cachedValue = cache.Get(endpoint1, \"Different\", \"Different\");\r\n        REQUIRE(cachedValue.has_value());\r\n        REQUIRE(publicEndpoint1Identifier == cachedValue->SourceIdentifier);\r\n    }\r\n    SECTION(\"Second endpoint\")\r\n    {\r\n        auto cachedValue = cache.Get(endpoint2, header, caller);\r\n        REQUIRE(cachedValue.has_value());\r\n        REQUIRE(privateEndpoint2Identifier == cachedValue->SourceIdentifier);\r\n    }\r\n    SECTION(\"Second endpoint different headers\")\r\n    {\r\n        auto cachedValue = cache.Get(endpoint2, {}, {});\r\n        REQUIRE(!cachedValue.has_value());\r\n    }\r\n    SECTION(\"Missing endpoint\")\r\n    {\r\n        auto cachedValue = cache.Get(endpointNotPresent, header, caller);\r\n        REQUIRE(!cachedValue.has_value());\r\n    }\r\n}\r\n\r\nTEST_CASE(\"RestInformationCache_Cache_NoStore\", \"[RestInformationCache]\")\r\n{\r\n    Settings::Stream{ Settings::Stream::RestInformationCache }.Remove();\r\n\r\n    std::wstring endpoint = L\"https://test-url-com/information\";\r\n\r\n    RestInformationCache cache;\r\n    cache.Cache(endpoint, {}, {}, { L\"no-store\" }, CreateInformationResponse(\"Identifier\"));\r\n\r\n    auto cachedValue = cache.Get(endpoint, {}, {});\r\n    REQUIRE(!cachedValue.has_value());\r\n}\r\n\r\nTEST_CASE(\"RestInformationCache_Cache_Expiration\", \"[RestInformationCache]\")\r\n{\r\n    Settings::Stream{ Settings::Stream::RestInformationCache }.Remove();\r\n\r\n    std::wstring endpoint = L\"https://test-url-com/information\";\r\n\r\n    RestInformationCache cache;\r\n    cache.Cache(endpoint, {}, {}, { L\"max-age=2\" }, CreateInformationResponse(\"Identifier\"));\r\n\r\n    auto cachedValue = cache.Get(endpoint, {}, {});\r\n    REQUIRE(cachedValue.has_value());\r\n\r\n    std::this_thread::sleep_for(5s);\r\n\r\n    cachedValue = cache.Get(endpoint, {}, {});\r\n    REQUIRE(!cachedValue.has_value());\r\n}\r\n\r\nTEST_CASE(\"RestInformationCache_Cache_Overwrite\", \"[RestInformationCache]\")\r\n{\r\n    Settings::Stream{ Settings::Stream::RestInformationCache }.Remove();\r\n\r\n    std::wstring endpoint = L\"https://test-url-com/information\";\r\n    std::string identifier1 = \"Identifier1\";\r\n    std::string identifier2 = \"Identifier2\";\r\n\r\n    RestInformationCache cache;\r\n    cache.Cache(endpoint, {}, {}, {}, CreateInformationResponse(identifier1));\r\n\r\n    auto cachedValue = cache.Get(endpoint, {}, {});\r\n    REQUIRE(cachedValue.has_value());\r\n    REQUIRE(identifier1 == cachedValue->SourceIdentifier);\r\n\r\n    cache.Cache(endpoint, {}, {}, {}, CreateInformationResponse(identifier2));\r\n\r\n    cachedValue = cache.Get(endpoint, {}, {});\r\n    REQUIRE(cachedValue.has_value());\r\n    REQUIRE(identifier2 == cachedValue->SourceIdentifier);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/RestInterface_1_0.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestRestRequestHandler.h\"\r\n#include <Rest/Schema/1_0/Interface.h>\r\n#include <Rest/Schema/IRestClient.h>\r\n#include <AppInstallerVersions.h>\r\n#include <AppInstallerErrors.h>\r\n#include <winget/ManifestValidation.h>\r\n#include <AppInstallerSHA256.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::Http;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Repository::Rest;\r\nusing namespace AppInstaller::Repository::Rest::Schema;\r\nusing namespace AppInstaller::Repository::Rest::Schema::V1_0;\r\n\r\nnamespace\r\n{\r\n    const std::string TestRestUriString = \"http://restsource.com/api\";\r\n\r\n    utility::string_t GetGoodManifest_RequiredFields()\r\n    {\r\n        return _XPLATSTR(\r\n            R\"delimiter({\r\n        \"Data\": {\r\n            \"PackageIdentifier\": \"Foo.Bar\",\r\n            \"Versions\": [\r\n                {\r\n                    \"PackageVersion\": \"5.0.0\",\r\n                    \"DefaultLocale\": {\r\n                        \"PackageLocale\": \"en-us\",\r\n                        \"Publisher\": \"Foo\",\r\n                        \"PackageName\": \"Bar\",\r\n                        \"License\": \"Foo bar license\",\r\n                        \"ShortDescription\": \"Foo bar description\"\r\n                    },\r\n                    \"Installers\": [\r\n                        {\r\n                            \"Architecture\": \"x64\",\r\n                            \"InstallerSha256\": \"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\",\r\n                            \"InstallerType\": \"exe\",\r\n                            \"InstallerUrl\": \"https://installer.example.com/foobar.exe\"\r\n                        }\r\n                    ]\r\n                }\r\n            ]\r\n        }\r\n    })delimiter\");\r\n    }\r\n\r\n    utility::string_t GetManifestsResponse_MultipleVersions()\r\n    {\r\n        return _XPLATSTR(\r\n            R\"delimiter({\r\n        \"Data\": {\r\n            \"PackageIdentifier\": \"Foo.Bar\",\r\n            \"Versions\": [\r\n                {\r\n                    \"PackageVersion\": \"5.0.0\",\r\n                    \"DefaultLocale\": {\r\n                        \"PackageLocale\": \"en-us\",\r\n                        \"Publisher\": \"Foo\",\r\n                        \"PackageName\": \"Bar\",\r\n                        \"License\": \"Foo bar license\",\r\n                        \"ShortDescription\": \"Foo bar description\"\r\n                    },\r\n                    \"Installers\": [\r\n                        {\r\n                            \"Architecture\": \"x64\",\r\n                            \"InstallerSha256\": \"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\",\r\n                            \"InstallerType\": \"exe\",\r\n                            \"InstallerUrl\": \"https://installer.example.com/foobar.exe\"\r\n                        }\r\n                    ]\r\n                },\r\n                {\r\n                    \"PackageVersion\": \"6.0.0\",\r\n                    \"DefaultLocale\": {\r\n                        \"PackageLocale\": \"en-us\",\r\n                        \"Publisher\": \"Foo\",\r\n                        \"PackageName\": \"Bar\",\r\n                        \"License\": \"Foo bar license\",\r\n                        \"ShortDescription\": \"Foo bar description\"\r\n                    },\r\n                    \"Installers\": [\r\n                        {\r\n                            \"Architecture\": \"x64\",\r\n                            \"InstallerSha256\": \"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\",\r\n                            \"InstallerType\": \"exe\",\r\n                            \"InstallerUrl\": \"https://installer.example.com/foobar.exe\"\r\n                        }\r\n                    ]\r\n                }\r\n            ]\r\n        }\r\n    })delimiter\");\r\n    }\r\n\r\n    struct GoodManifest_AllFields\r\n    {\r\n        utility::string_t GetSampleManifest_AllFields()\r\n        {\r\n            return _XPLATSTR(\r\n                R\"delimiter(\r\n        {\r\n          \"Data\": {\r\n            \"PackageIdentifier\": \"Foo.Bar\",\r\n            \"Versions\": [\r\n              {\r\n                \"PackageVersion\": \"3.0.0abc\",\r\n                \"DefaultLocale\": {\r\n                  \"PackageLocale\": \"en-US\",\r\n                  \"Publisher\": \"Foo\",\r\n                  \"PublisherUrl\": \"http://publisher.net\",\r\n                  \"PublisherSupportUrl\": \"http://publisherSupport.net\",\r\n                  \"PrivacyUrl\": \"http://packagePrivacyUrl.net\",\r\n                  \"Author\": \"FooBar\",\r\n                  \"PackageName\": \"Bar\",\r\n                  \"PackageUrl\": \"http://packageUrl.net\",\r\n                  \"License\": \"Foo Bar License\",\r\n                  \"LicenseUrl\": \"http://licenseUrl.net\",\r\n                  \"Copyright\": \"Foo Bar Copyright\",\r\n                  \"CopyrightUrl\": \"http://copyrightUrl.net\",\r\n                  \"ShortDescription\": \"Foo bar is a foo bar.\",\r\n                  \"Description\": \"Foo bar is a placeholder.\",\r\n                  \"Tags\": [\r\n                    \"FooBar\",\r\n                    \"Foo\",\r\n                    \"Bar\"\r\n                  ],\r\n                  \"Moniker\": \"FooBarMoniker\"\r\n                },\r\n                \"Channel\": \"\",\r\n                \"Locales\": [\r\n                  {\r\n                    \"PackageLocale\": \"fr-Fr\",\r\n                    \"Publisher\": \"Foo French\",\r\n                    \"PublisherUrl\": \"http://publisher-fr.net\",\r\n                    \"PublisherSupportUrl\": \"http://publisherSupport-fr.net\",\r\n                    \"PrivacyUrl\": \"http://packagePrivacyUrl-fr.net\",\r\n                    \"Author\": \"FooBar French\",\r\n                    \"PackageName\": \"Bar\",\r\n                    \"PackageUrl\": \"http://packageUrl-fr.net\",\r\n                    \"License\": \"Foo Bar License\",\r\n                    \"LicenseUrl\": \"http://licenseUrl-fr.net\",\r\n                    \"Copyright\": \"Foo Bar Copyright\",\r\n                    \"CopyrightUrl\": \"http://copyrightUrl-fr.net\",\r\n                    \"ShortDescription\": \"Foo bar is a foo bar French.\",\r\n                    \"Description\": \"Foo bar is a placeholder French.\",\r\n                    \"Tags\": [\r\n                      \"FooBarFr\",\r\n                      \"FooFr\",\r\n                      \"BarFr\"\r\n                    ]\r\n                  }\r\n                ],\r\n                \"Installers\": [\r\n                  {\r\n                    \"InstallerSha256\": \"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\",\r\n                    \"InstallerUrl\": \"http://foobar.exe\",\r\n                    \"Architecture\": \"x86\",\r\n                    \"InstallerLocale\": \"en-US\",\r\n                    \"Platform\": [\r\n                      \"Windows.Desktop\"\r\n                    ],\r\n                    \"MinimumOSVersion\": \"1078\",\r\n                    \"InstallerType\": \"msix\",\r\n                    \"Scope\": \"user\",\r\n                    \"SignatureSha256\": \"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\",\r\n                    \"InstallModes\": [\r\n                      \"interactive\"\r\n                    ],\r\n                    \"InstallerSwitches\": {\r\n                      \"Silent\": \"/s\",\r\n                      \"SilentWithProgress\": \"/s\",\r\n                      \"Interactive\": \"/i\",\r\n                      \"InstallLocation\": \"C:\\\\Users\\\\User1\",\r\n                      \"Log\": \"/l\",\r\n                      \"Upgrade\": \"/u\",\r\n                      \"Custom\": \"/custom\"\r\n                    },\r\n                    \"InstallerSuccessCodes\": [\r\n                      0\r\n                    ],\r\n                    \"UpgradeBehavior\": \"install\",\r\n                    \"Commands\": [\r\n                      \"command1\"\r\n                    ],\r\n                    \"Protocols\": [\r\n                       \"protocol1\"\r\n                    ],\r\n                    \"FileExtensions\": [\r\n                      \".file-extension\"\r\n                    ],\r\n                    \"Dependencies\": {\r\n                      \"WindowsFeatures\": [\r\n                        \"feature1\"\r\n                      ],\r\n                      \"WindowsLibraries\": [\r\n                        \"library1\"\r\n                      ],\r\n                      \"PackageDependencies\": [\r\n                        {\r\n                          \"PackageIdentifier\": \"Foo.Baz\",\r\n                          \"MinimumVersion\": \"2.0.0\"\r\n                        }\r\n                      ],\r\n                      \"ExternalDependencies\": [\r\n                        \"FooBarBaz\"\r\n                      ]\r\n                    },\r\n                    \"PackageFamilyName\": \"FooBar.PackageFamilyName\",\r\n                    \"ProductCode\": \"\",\r\n                    \"Capabilities\": [\r\n                      \"Bluetooth\"\r\n                    ],\r\n                    \"RestrictedCapabilities\": [\r\n                      \"restrictedCapability\"\r\n                    ]\r\n                  }\r\n                ]\r\n              }\r\n            ]\r\n          },\r\n          \"ContinuationToken\": \"abcd\"\r\n        })delimiter\");\r\n        }\r\n\r\n        void VerifyLocalizations_AllFields(const Manifest& manifest)\r\n        {\r\n            REQUIRE(manifest.DefaultLocalization.Locale == \"en-US\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Publisher>() == \"Foo\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PublisherUrl>() == \"http://publisher.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PublisherSupportUrl>() == \"http://publisherSupport.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PrivacyUrl>() == \"http://packagePrivacyUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Author>() == \"FooBar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageName>() == \"Bar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageUrl>() == \"http://packageUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::License>() == \"Foo Bar License\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::LicenseUrl>() == \"http://licenseUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Copyright>() == \"Foo Bar Copyright\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::CopyrightUrl>() == \"http://copyrightUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ShortDescription>() == \"Foo bar is a foo bar.\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Description>() == \"Foo bar is a placeholder.\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().size() == 3);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(0) == \"FooBar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(1) == \"Foo\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(2) == \"Bar\");\r\n\r\n            REQUIRE(manifest.Localizations.size() == 1);\r\n            ManifestLocalization frenchLocalization = manifest.Localizations.at(0);\r\n            REQUIRE(frenchLocalization.Locale == \"fr-Fr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Publisher>() == \"Foo French\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PublisherUrl>() == \"http://publisher-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PublisherSupportUrl>() == \"http://publisherSupport-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PrivacyUrl>() == \"http://packagePrivacyUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Author>() == \"FooBar French\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PackageName>() == \"Bar\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PackageUrl>() == \"http://packageUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::License>() == \"Foo Bar License\");\r\n            REQUIRE(frenchLocalization.Get<Localization::LicenseUrl>() == \"http://licenseUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Copyright>() == \"Foo Bar Copyright\");\r\n            REQUIRE(frenchLocalization.Get<Localization::CopyrightUrl>() == \"http://copyrightUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::ShortDescription>() == \"Foo bar is a foo bar French.\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Description>() == \"Foo bar is a placeholder French.\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().size() == 3);\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(0) == \"FooBarFr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(1) == \"FooFr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(2) == \"BarFr\");\r\n        }\r\n\r\n        void VerifyInstallers_AllFields(const Manifest& manifest)\r\n        {\r\n            REQUIRE(manifest.Installers.size() == 1);\r\n\r\n            ManifestInstaller actualInstaller = manifest.Installers.at(0);\r\n            REQUIRE(actualInstaller.Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\"));\r\n            REQUIRE(actualInstaller.Url == \"http://foobar.exe\");\r\n            REQUIRE(actualInstaller.Arch == Architecture::X86);\r\n            REQUIRE(actualInstaller.Locale == \"en-US\");\r\n            REQUIRE(actualInstaller.Platform.size() == 1);\r\n            REQUIRE(actualInstaller.Platform[0] == PlatformEnum::Desktop);\r\n            REQUIRE(actualInstaller.MinOSVersion == \"1078\");\r\n            REQUIRE(actualInstaller.BaseInstallerType == InstallerTypeEnum::Msix);\r\n            REQUIRE(actualInstaller.Scope == ScopeEnum::User);\r\n            REQUIRE(actualInstaller.SignatureSha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\"));\r\n            REQUIRE(actualInstaller.InstallModes.size() == 1);\r\n            REQUIRE(actualInstaller.InstallModes.at(0) == InstallModeEnum::Interactive);\r\n            REQUIRE(actualInstaller.Switches.size() == 7);\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Silent) == \"/s\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::SilentWithProgress) == \"/s\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Interactive) == \"/i\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::InstallLocation) == \"C:\\\\Users\\\\User1\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Log) == \"/l\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Update) == \"/u\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Custom) == \"/custom\");\r\n            REQUIRE(actualInstaller.InstallerSuccessCodes.size() == 1);\r\n            REQUIRE(actualInstaller.InstallerSuccessCodes.at(0) == 0);\r\n            REQUIRE(actualInstaller.UpdateBehavior == UpdateBehaviorEnum::Install);\r\n            REQUIRE(actualInstaller.Commands.at(0) == \"command1\");\r\n            REQUIRE(actualInstaller.Protocols.at(0) == \"protocol1\");\r\n            REQUIRE(actualInstaller.FileExtensions.at(0) == \".file-extension\");\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::WindowsFeature, \"feature1\"));\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::WindowsLibrary, \"library1\"));\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::Package, \"Foo.Baz\", \"2.0.0\"));\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::External, \"FooBarBaz\"));\r\n            REQUIRE(actualInstaller.PackageFamilyName == \"FooBar.PackageFamilyName\");\r\n            REQUIRE(actualInstaller.ProductCode == \"\");\r\n            REQUIRE(actualInstaller.Capabilities.at(0) == \"Bluetooth\");\r\n            REQUIRE(actualInstaller.RestrictedCapabilities.at(0) == \"restrictedCapability\");\r\n        }\r\n    };\r\n}\r\n\r\nTEST_CASE(\"Search_GoodResponse\", \"[RestSource][Interface_1_0]\")\r\n{\r\n    utility::string_t sample = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : [\r\n               {\r\n              \"PackageIdentifier\": \"git.package\",\r\n              \"PackageName\": \"package\",\r\n              \"Publisher\": \"git\",\r\n              \"Versions\": [\r\n                {   \"PackageVersion\": \"1.0.0\" },\r\n                {   \"PackageVersion\": \"2.0.0\" }]\r\n            }]\r\n        })delimiter\");\r\n\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) };\r\n    Interface v1{ TestRestUriString, std::move(helper) };\r\n    Schema::IRestClient::SearchResult searchResponse = v1.Search({});\r\n    REQUIRE(searchResponse.Matches.size() == 1);\r\n    Schema::IRestClient::Package package = searchResponse.Matches.at(0);\r\n    REQUIRE(package.PackageInformation.PackageIdentifier.compare(\"git.package\") == 0);\r\n    REQUIRE(package.PackageInformation.Publisher.compare(\"git\") == 0);\r\n    REQUIRE(package.PackageInformation.PackageName.compare(\"package\") == 0);\r\n    REQUIRE(package.Versions.size() == 2);\r\n    REQUIRE(package.Versions.at(0).VersionAndChannel.GetVersion().ToString().compare(\"1.0.0\") == 0);\r\n    REQUIRE(package.Versions.at(1).VersionAndChannel.GetVersion().ToString().compare(\"2.0.0\") == 0);\r\n}\r\n\r\nTEST_CASE(\"Search_GoodResponse_AllFields\", \"[RestSource][Interface_1_0]\")\r\n{\r\n    utility::string_t sample = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : [\r\n               {\r\n              \"PackageIdentifier\": \"git.package\",\r\n              \"PackageName\": \"package\",\r\n              \"Publisher\": \"git\",\r\n              \"Versions\": [\r\n                {\r\n                    \"PackageVersion\": \"1.0.0\",\r\n                    \"PackageFamilyNames\" : [\r\n                        \"pfn1\",\r\n                        \"pfn2\",\r\n                        \"pfn2\"\r\n                    ],\r\n                    \"ProductCodes\" : [\r\n                        \"pc1\",\r\n                        \"pc2\"\r\n                    ]\r\n                }]\r\n            }]\r\n        })delimiter\");\r\n\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) };\r\n    Interface v1{ TestRestUriString, std::move(helper) };\r\n    Schema::IRestClient::SearchResult searchResponse = v1.Search({});\r\n    REQUIRE(searchResponse.Matches.size() == 1);\r\n    Schema::IRestClient::Package package = searchResponse.Matches.at(0);\r\n    REQUIRE(package.PackageInformation.PackageIdentifier.compare(\"git.package\") == 0);\r\n    REQUIRE(package.PackageInformation.Publisher.compare(\"git\") == 0);\r\n    REQUIRE(package.PackageInformation.PackageName.compare(\"package\") == 0);\r\n    REQUIRE(package.Versions.size() == 1);\r\n    REQUIRE(package.Versions.at(0).VersionAndChannel.GetVersion().ToString().compare(\"1.0.0\") == 0);\r\n    REQUIRE(package.Versions.at(0).PackageFamilyNames.size() == 2);\r\n    REQUIRE(package.Versions.at(0).PackageFamilyNames.at(0) == \"pfn1\");\r\n    REQUIRE(package.Versions.at(0).PackageFamilyNames.at(1) == \"pfn2\");\r\n    REQUIRE(package.Versions.at(0).ProductCodes.at(0) == \"pc1\");\r\n    REQUIRE(package.Versions.at(0).ProductCodes.at(1) == \"pc2\");\r\n}\r\n\r\nTEST_CASE(\"Search_GoodResponse_404AsEmpty\", \"[RestSource][Interface_1_0]\")\r\n{\r\n    utility::string_t notFoundResponse = _XPLATSTR(\r\n        R\"delimiter({\"code\":\"DataNotFound\",\"data\":[],\"details\":[],\"innererror\":{\"code\":\"DataNotFound\",\"data\":[],\"details\":[],\"message\":\"Product is not present\",\"source\":\"StoreEdgeFD\"},\"message\":\"Product is not present\",\"source\":\"StoreEdgeFD\"})delimiter\");\r\n\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::NotFound, std::move(notFoundResponse)) };\r\n    Interface v1{ TestRestUriString, std::move(helper) };\r\n    Schema::IRestClient::SearchResult searchResponse = v1.Search({});\r\n    REQUIRE(searchResponse.Matches.size() == 0);\r\n}\r\n\r\nTEST_CASE(\"Search_ContinuationToken\", \"[RestSource][Interface_1_0]\")\r\n{\r\n    utility::string_t sample = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : [\r\n               {\r\n              \"PackageIdentifier\": \"git.package\",\r\n              \"PackageName\": \"package\",\r\n              \"Publisher\": \"git\",\r\n              \"Versions\": [\r\n                {   \"PackageVersion\": \"1.0.0\" }]\r\n            },\r\n            {\r\n              \"PackageIdentifier\": \"foo.package\",\r\n              \"PackageName\": \"package\",\r\n              \"Publisher\": \"foo\",\r\n              \"Versions\": [\r\n                {   \"PackageVersion\": \"1.0.0\" }]\r\n            }],\r\n           \"ContinuationToken\" : \"abcd-ct=\"\r\n        })delimiter\");\r\n\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) };\r\n    Interface v1{ TestRestUriString, std::move(helper) };\r\n    SearchRequest request{};\r\n    request.MaximumResults = 9;\r\n    Schema::IRestClient::SearchResult results = v1.Search(request);\r\n    REQUIRE(results.Matches.size() == request.MaximumResults);\r\n\r\n    SearchRequest requestWithSize1{};\r\n    requestWithSize1.MaximumResults = 1;\r\n    Schema::IRestClient::SearchResult resultsWithSize1 = v1.Search(requestWithSize1);\r\n    REQUIRE(resultsWithSize1.Matches.size() == requestWithSize1.MaximumResults);\r\n}\r\n\r\nTEST_CASE(\"Search_BadResponse_NoVersions\", \"[RestSource][Interface_1_0]\")\r\n{\r\n    utility::string_t sample = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : [\r\n               {\r\n              \"PackageIdentifier\": \"git.package\",\r\n              \"PackageName\": \"package\",\r\n              \"Publisher\": \"git\",\r\n              \"Versions\": null }]\r\n        })delimiter\");\r\n\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) };\r\n    Interface v1{ TestRestUriString, std::move(helper) };\r\n    REQUIRE_THROWS_HR(v1.Search({}), APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA);\r\n}\r\n\r\nTEST_CASE(\"Search_BadResponse_NotFoundCode\", \"[RestSource][Interface_1_0]\")\r\n{\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::NotFound) };\r\n    Interface v1{ TestRestUriString, std::move(helper) };\r\n    REQUIRE_THROWS_HR(v1.Search({}), APPINSTALLER_CLI_ERROR_RESTAPI_ENDPOINT_NOT_FOUND);\r\n}\r\n\r\nTEST_CASE(\"Search_Optimized_ManifestResponse\", \"[RestSource][Interface_1_0]\")\r\n{\r\n    utility::string_t sample = GetGoodManifest_RequiredFields();\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) };\r\n    AppInstaller::Repository::SearchRequest request;\r\n    PackageMatchFilter filter{ PackageMatchField::Id, MatchType::Exact, \"Foo\" };\r\n    request.Filters.emplace_back(std::move(filter));\r\n    Interface v1{ TestRestUriString, std::move(helper) };\r\n    Schema::IRestClient::SearchResult result = v1.Search(request);\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(result.Matches[0].Versions.size() == 1);\r\n    REQUIRE(result.Matches[0].Versions[0].VersionAndChannel.GetVersion().ToString() == \"5.0.0\");\r\n    REQUIRE(result.Matches[0].Versions[0].VersionAndChannel.GetChannel().ToString() == \"\");\r\n    REQUIRE(result.Matches[0].Versions[0].Manifest);\r\n    \r\n    // Verify manifest is populated\r\n    Manifest manifest = result.Matches[0].Versions[0].Manifest.value();\r\n    REQUIRE(manifest.Id == \"Foo.Bar\");\r\n    REQUIRE(manifest.Version == \"5.0.0\");\r\n    REQUIRE(manifest.DefaultLocalization.Locale == \"en-us\");\r\n    REQUIRE(manifest.DefaultLocalization.Get<Localization::Publisher>() == \"Foo\");\r\n    REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageName>() == \"Bar\");\r\n    REQUIRE(manifest.DefaultLocalization.Get<Localization::License>() == \"Foo bar license\");\r\n    REQUIRE(manifest.DefaultLocalization.Get<Localization::ShortDescription>() == \"Foo bar description\");\r\n    REQUIRE(manifest.Installers.size() == 1);\r\n    REQUIRE(manifest.Installers[0].Arch == Architecture::X64);\r\n    REQUIRE(manifest.Installers[0].Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\"));\r\n    REQUIRE(manifest.Installers[0].BaseInstallerType == InstallerTypeEnum::Exe);\r\n    REQUIRE(manifest.Installers[0].Url == \"https://installer.example.com/foobar.exe\");\r\n}\r\n\r\nTEST_CASE(\"Search_Optimized_ManifestResponse_MultipleVersions\", \"[RestSource][Interface_1_0]\")\r\n{\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, GetManifestsResponse_MultipleVersions()) };\r\n    AppInstaller::Repository::SearchRequest request;\r\n    PackageMatchFilter filter{ PackageMatchField::Id, MatchType::Exact, \"Foo.Bar\" };\r\n    request.Filters.emplace_back(std::move(filter));\r\n    Interface v1{ TestRestUriString, std::move(helper) };\r\n    Schema::IRestClient::SearchResult result = v1.Search(request);\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(result.Matches[0].Versions.size() == 2);\r\n    REQUIRE(result.Matches[0].Versions[0].VersionAndChannel.GetVersion().ToString() == \"5.0.0\");\r\n    REQUIRE(result.Matches[0].Versions[0].Manifest);\r\n    REQUIRE(result.Matches[0].Versions[1].VersionAndChannel.GetVersion().ToString() == \"6.0.0\");\r\n    REQUIRE(result.Matches[0].Versions[1].Manifest);\r\n}\r\n\r\nTEST_CASE(\"Search_Optimized_NoResponse_NotFoundCode\", \"[RestSource][Interface_1_0]\")\r\n{\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::NotFound) };\r\n    AppInstaller::Repository::SearchRequest request;\r\n    PackageMatchFilter filter{ PackageMatchField::Id, MatchType::Exact, \"Foo\" };\r\n    request.Filters.emplace_back(std::move(filter));\r\n    Interface v1{ TestRestUriString, std::move(helper) };\r\n    REQUIRE_THROWS_HR(v1.Search(request), APPINSTALLER_CLI_ERROR_RESTAPI_ENDPOINT_NOT_FOUND);\r\n}\r\n\r\nTEST_CASE(\"GetManifests_GoodResponse\", \"[RestSource][Interface_1_0]\")\r\n{\r\n    GoodManifest_AllFields sampleManifest;\r\n    utility::string_t sample = sampleManifest.GetSampleManifest_AllFields();\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) };\r\n    Interface v1{ TestRestUriString, std::move(helper) };\r\n    std::vector<Manifest> manifests = v1.GetManifests(\"Foo.Bar\");\r\n    REQUIRE(manifests.size() == 1);\r\n\r\n    // Verify manifest is populated\r\n    Manifest manifest = manifests[0];\r\n    REQUIRE(manifest.Id == \"Foo.Bar\");\r\n    REQUIRE(manifest.Version == \"3.0.0abc\");\r\n    REQUIRE(manifest.Moniker == \"FooBarMoniker\");\r\n    REQUIRE(manifest.Channel == \"\");\r\n    REQUIRE(manifest.ManifestVersion == AppInstaller::Manifest::ManifestVer{ \"1.0.0\" });\r\n    sampleManifest.VerifyLocalizations_AllFields(manifest);\r\n    sampleManifest.VerifyInstallers_AllFields(manifest);\r\n}\r\n\r\nTEST_CASE(\"GetManifests_GoodResponse_404AsEmpty\", \"[RestSource][Interface_1_0]\")\r\n{\r\n    utility::string_t notFoundResponse = _XPLATSTR(\r\n        R\"delimiter({\"code\":\"DataNotFound\",\"data\":[],\"details\":[],\"innererror\":{\"code\":\"DataNotFound\",\"data\":[],\"details\":[],\"message\":\"Product is not present\",\"source\":\"StoreEdgeFD\"},\"message\":\"Product is not present\",\"source\":\"StoreEdgeFD\"})delimiter\");\r\n\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::NotFound, std::move(notFoundResponse)) };\r\n    Interface v1{ TestRestUriString, std::move(helper) };\r\n    std::vector<Manifest> manifests = v1.GetManifests(\"Foo.Bar\");\r\n    REQUIRE(manifests.size() == 0);\r\n}\r\n\r\nTEST_CASE(\"GetManifests_GoodResponse_MultipleVersions\", \"[RestSource][Interface_1_0]\")\r\n{\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, GetManifestsResponse_MultipleVersions()) };\r\n    Interface v1{ TestRestUriString, std::move(helper) };\r\n\r\n    // GetManifests\r\n    std::vector<Manifest> manifests = v1.GetManifests(\"Foo.Bar\");\r\n    REQUIRE(manifests.size() == 2);\r\n    REQUIRE(manifests[0].Version == \"5.0.0\");\r\n    REQUIRE(manifests[1].Version == \"6.0.0\");\r\n}\r\n\r\nTEST_CASE(\"GetManifests_BadResponse_SuccessCode\", \"[RestSource][Interface_1_0]\")\r\n{\r\n    utility::string_t badManifest = _XPLATSTR(\r\n        R\"delimiter({\r\n        \"Data\": {\r\n            \"PackageIdentifier\": \"Foo.Bar\",\r\n            \"Versions\": [\r\n                {\r\n                    \"PackageVersion\": \"5.0.0\"\r\n                }\r\n            ]\r\n        }\r\n    })delimiter\");\r\n\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(badManifest)) };\r\n    Interface v1{ TestRestUriString, std::move(helper) };\r\n    REQUIRE_THROWS_HR(v1.GetManifests(\"Foo.Bar\"), APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA);\r\n}\r\n\r\nTEST_CASE(\"GetManifests_NotFoundCode\", \"[RestSource][Interface_1_0]\")\r\n{\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::NotFound) };\r\n    Interface v1{ TestRestUriString, std::move(helper) };\r\n    REQUIRE_THROWS_HR(v1.GetManifests(\"Foo.Bar\"), APPINSTALLER_CLI_ERROR_RESTAPI_ENDPOINT_NOT_FOUND);\r\n}\r\n\r\nTEST_CASE(\"GetManifests_GoodResponse_UnknownInstaller\", \"[RestSource][Interface_1_0]\")\r\n{\r\n    utility::string_t msstoreInstallerResponse = _XPLATSTR(\r\n        R\"delimiter({\r\n        \"Data\": {\r\n            \"PackageIdentifier\": \"Foo.Bar\",\r\n            \"Versions\": [\r\n                {\r\n                    \"PackageVersion\": \"5.0.0\",\r\n                    \"DefaultLocale\": {\r\n                        \"PackageLocale\": \"en-us\",\r\n                        \"Publisher\": \"Foo\",\r\n                        \"PackageName\": \"Bar\",\r\n                        \"License\": \"Foo bar license\",\r\n                        \"ShortDescription\": \"Foo bar description\"\r\n                    },\r\n                    \"Installers\": [\r\n                        {\r\n                            \"Architecture\": \"x64\",\r\n                            \"InstallerType\": \"msstore\",\r\n                            \"MSStoreProductIdentifier\": \"9nblggh4nns1\"\r\n                        }\r\n                    ]\r\n                }\r\n            ]\r\n        }\r\n    })delimiter\");\r\n\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(msstoreInstallerResponse)) };\r\n    Interface v1{ TestRestUriString, std::move(helper) };\r\n    std::vector<Manifest> manifests = v1.GetManifests(\"Foo.Bar\");\r\n    REQUIRE(manifests.size() == 1);\r\n\r\n    // Verify manifest is populated and manifest validation passed\r\n    Manifest& manifest = manifests[0];\r\n    REQUIRE(manifest.Installers.size() == 1);\r\n    REQUIRE(manifest.Installers.at(0).BaseInstallerType == InstallerTypeEnum::Unknown);\r\n    REQUIRE(manifest.Installers.at(0).ProductId.empty());\r\n}\r\n\r\nTEST_CASE(\"GetManifestByVersion_GoodResponse_MultipleVersions_VersionFound\", \"[RestSource][Interface_1_0]\")\r\n{\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, GetManifestsResponse_MultipleVersions()) };\r\n    Interface v1{ TestRestUriString, std::move(helper) };\r\n\r\n    // GetManifests\r\n    std::optional<Manifest> manifest = v1.GetManifestByVersion(\"Foo.Bar\", \"5.0.0\", \"\");\r\n    REQUIRE(manifest.has_value());\r\n    REQUIRE(manifest->Version == \"5.0.0\");\r\n}\r\n\r\nTEST_CASE(\"GetManifestByVersion_GoodResponse_MultipleVersions_VersionNotFound\", \"[RestSource][Interface_1_0]\")\r\n{\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, GetManifestsResponse_MultipleVersions()) };\r\n    Interface v1{ TestRestUriString, std::move(helper) };\r\n\r\n    // GetManifests\r\n    std::optional<Manifest> manifest = v1.GetManifestByVersion(\"Foo.Bar\", \"7.0.0\", \"\");\r\n    REQUIRE_FALSE(manifest.has_value());\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/RestInterface_1_1.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestRestRequestHandler.h\"\r\n#include <Rest/Schema/1_1/Interface.h>\r\n#include <Rest/Schema/IRestClient.h>\r\n#include <AppInstallerVersions.h>\r\n#include <AppInstallerErrors.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::Http;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Repository::Rest;\r\nusing namespace AppInstaller::Repository::Rest::Schema;\r\nusing namespace AppInstaller::Repository::Rest::Schema::V1_1;\r\n\r\nnamespace\r\n{\r\n    const std::string TestRestUriString = \"http://restsource.com/api\";\r\n\r\n    IRestClient::Information GetTestSourceInformation()\r\n    {\r\n        IRestClient::Information result;\r\n\r\n        result.RequiredPackageMatchFields.emplace_back(\"Market\");\r\n        result.RequiredQueryParameters.emplace_back(\"Market\");\r\n        result.UnsupportedPackageMatchFields.emplace_back(\"Moniker\");\r\n        result.UnsupportedQueryParameters.emplace_back(\"Channel\");\r\n\r\n        return result;\r\n    }\r\n\r\n    struct GoodManifest_AllFields\r\n    {\r\n        utility::string_t GetSampleManifest_AllFields()\r\n        {\r\n            return _XPLATSTR(\r\n                R\"delimiter(\r\n        {\r\n          \"Data\": {\r\n            \"PackageIdentifier\": \"Foo.Bar\",\r\n            \"Versions\": [\r\n              {\r\n                \"PackageVersion\": \"3.0.0abc\",\r\n                \"DefaultLocale\": {\r\n                  \"PackageLocale\": \"en-US\",\r\n                  \"Publisher\": \"Foo\",\r\n                  \"PublisherUrl\": \"http://publisher.net\",\r\n                  \"PublisherSupportUrl\": \"http://publisherSupport.net\",\r\n                  \"PrivacyUrl\": \"http://packagePrivacyUrl.net\",\r\n                  \"Author\": \"FooBar\",\r\n                  \"PackageName\": \"Bar\",\r\n                  \"PackageUrl\": \"http://packageUrl.net\",\r\n                  \"License\": \"Foo Bar License\",\r\n                  \"LicenseUrl\": \"http://licenseUrl.net\",\r\n                  \"Copyright\": \"Foo Bar Copyright\",\r\n                  \"CopyrightUrl\": \"http://copyrightUrl.net\",\r\n                  \"ShortDescription\": \"Foo bar is a foo bar.\",\r\n                  \"Description\": \"Foo bar is a placeholder.\",\r\n                  \"Tags\": [\r\n                    \"FooBar\",\r\n                    \"Foo\",\r\n                    \"Bar\"\r\n                  ],\r\n                  \"Moniker\": \"FooBarMoniker\",\r\n                  \"ReleaseNotes\": \"Default release notes\",\r\n                  \"ReleaseNotesUrl\": \"https://DefaultReleaseNotes.net\",\r\n                  \"Agreements\": [{\r\n                    \"AgreementLabel\": \"DefaultLabel\",\r\n                    \"Agreement\": \"DefaultText\",\r\n                    \"AgreementUrl\": \"https://DefaultAgreementUrl.net\"\r\n                  }]\r\n                },\r\n                \"Channel\": \"\",\r\n                \"Locales\": [\r\n                  {\r\n                    \"PackageLocale\": \"fr-Fr\",\r\n                    \"Publisher\": \"Foo French\",\r\n                    \"PublisherUrl\": \"http://publisher-fr.net\",\r\n                    \"PublisherSupportUrl\": \"http://publisherSupport-fr.net\",\r\n                    \"PrivacyUrl\": \"http://packagePrivacyUrl-fr.net\",\r\n                    \"Author\": \"FooBar French\",\r\n                    \"PackageName\": \"Bar\",\r\n                    \"PackageUrl\": \"http://packageUrl-fr.net\",\r\n                    \"License\": \"Foo Bar License\",\r\n                    \"LicenseUrl\": \"http://licenseUrl-fr.net\",\r\n                    \"Copyright\": \"Foo Bar Copyright\",\r\n                    \"CopyrightUrl\": \"http://copyrightUrl-fr.net\",\r\n                    \"ShortDescription\": \"Foo bar is a foo bar French.\",\r\n                    \"Description\": \"Foo bar is a placeholder French.\",\r\n                    \"Tags\": [\r\n                      \"FooBarFr\",\r\n                      \"FooFr\",\r\n                      \"BarFr\"\r\n                    ],\r\n                    \"ReleaseNotes\": \"Release notes\",\r\n                    \"ReleaseNotesUrl\": \"https://ReleaseNotes.net\",\r\n                    \"Agreements\": [{\r\n                      \"AgreementLabel\": \"Label\",\r\n                      \"Agreement\": \"Text\",\r\n                      \"AgreementUrl\": \"https://AgreementUrl.net\"\r\n                    }]\r\n                  }\r\n                ],\r\n                \"Installers\": [\r\n                  {\r\n                    \"InstallerSha256\": \"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\",\r\n                    \"InstallerUrl\": \"http://foobar.exe\",\r\n                    \"Architecture\": \"x86\",\r\n                    \"InstallerLocale\": \"en-US\",\r\n                    \"Platform\": [\r\n                      \"Windows.Desktop\"\r\n                    ],\r\n                    \"MinimumOSVersion\": \"1078\",\r\n                    \"InstallerType\": \"msi\",\r\n                    \"Scope\": \"user\",\r\n                    \"InstallModes\": [\r\n                      \"interactive\"\r\n                    ],\r\n                    \"InstallerSwitches\": {\r\n                      \"Silent\": \"/s\",\r\n                      \"SilentWithProgress\": \"/s\",\r\n                      \"Interactive\": \"/i\",\r\n                      \"InstallLocation\": \"C:\\\\Users\\\\User1\",\r\n                      \"Log\": \"/l\",\r\n                      \"Upgrade\": \"/u\",\r\n                      \"Custom\": \"/custom\"\r\n                    },\r\n                    \"InstallerSuccessCodes\": [\r\n                      0\r\n                    ],\r\n                    \"UpgradeBehavior\": \"install\",\r\n                    \"Commands\": [\r\n                      \"command1\"\r\n                    ],\r\n                    \"Protocols\": [\r\n                       \"protocol1\"\r\n                    ],\r\n                    \"FileExtensions\": [\r\n                      \".file-extension\"\r\n                    ],\r\n                    \"Dependencies\": {\r\n                      \"WindowsFeatures\": [\r\n                        \"feature1\"\r\n                      ],\r\n                      \"WindowsLibraries\": [\r\n                        \"library1\"\r\n                      ],\r\n                      \"PackageDependencies\": [\r\n                        {\r\n                          \"PackageIdentifier\": \"Foo.Baz\",\r\n                          \"MinimumVersion\": \"2.0.0\"\r\n                        }\r\n                      ],\r\n                      \"ExternalDependencies\": [\r\n                        \"FooBarBaz\"\r\n                      ]\r\n                    },\r\n                    \"ProductCode\": \"5b6e0f8a-3bbf-4a17-aefd-024c2b3e075d\",\r\n                    \"ReleaseDate\": \"2021-01-01\",\r\n                    \"InstallerAbortsTerminal\": true,\r\n                    \"InstallLocationRequired\": true,\r\n                    \"RequireExplicitUpgrade\": true,\r\n                    \"UnsupportedOSArchitectures\": [ \"arm\" ],\r\n                    \"ElevationRequirement\": \"elevatesSelf\",\r\n                    \"AppsAndFeaturesEntries\": [{\r\n                      \"DisplayName\": \"DisplayName\",\r\n                      \"DisplayVersion\": \"DisplayVersion\",\r\n                      \"Publisher\": \"Publisher\",\r\n                      \"ProductCode\": \"ProductCode\",\r\n                      \"UpgradeCode\": \"UpgradeCode\",\r\n                      \"InstallerType\": \"exe\"\r\n                    }],\r\n                    \"Markets\" : {\r\n                      \"AllowedMarkets\": [ \"US\" ]\r\n                    },\r\n                    \"ExpectedReturnCodes\": [{\r\n                      \"InstallerReturnCode\": 3,\r\n                      \"ReturnResponse\": \"InstallInProgress\"\r\n                    }]\r\n                  }\r\n                ]\r\n              }\r\n            ]\r\n          },\r\n          \"ContinuationToken\": \"abcd\"\r\n        })delimiter\");\r\n        }\r\n\r\n        void VerifyLocalizations_AllFields(const Manifest& manifest)\r\n        {\r\n            REQUIRE(manifest.DefaultLocalization.Locale == \"en-US\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Publisher>() == \"Foo\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PublisherUrl>() == \"http://publisher.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PublisherSupportUrl>() == \"http://publisherSupport.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PrivacyUrl>() == \"http://packagePrivacyUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Author>() == \"FooBar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageName>() == \"Bar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageUrl>() == \"http://packageUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::License>() == \"Foo Bar License\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::LicenseUrl>() == \"http://licenseUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Copyright>() == \"Foo Bar Copyright\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::CopyrightUrl>() == \"http://copyrightUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ShortDescription>() == \"Foo bar is a foo bar.\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Description>() == \"Foo bar is a placeholder.\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().size() == 3);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(0) == \"FooBar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(1) == \"Foo\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(2) == \"Bar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ReleaseNotes>() == \"Default release notes\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ReleaseNotesUrl>() == \"https://DefaultReleaseNotes.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().size() == 1);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).Label == \"DefaultLabel\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).AgreementText == \"DefaultText\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).AgreementUrl == \"https://DefaultAgreementUrl.net\");\r\n\r\n            REQUIRE(manifest.Localizations.size() == 1);\r\n            ManifestLocalization frenchLocalization = manifest.Localizations.at(0);\r\n            REQUIRE(frenchLocalization.Locale == \"fr-Fr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Publisher>() == \"Foo French\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PublisherUrl>() == \"http://publisher-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PublisherSupportUrl>() == \"http://publisherSupport-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PrivacyUrl>() == \"http://packagePrivacyUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Author>() == \"FooBar French\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PackageName>() == \"Bar\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PackageUrl>() == \"http://packageUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::License>() == \"Foo Bar License\");\r\n            REQUIRE(frenchLocalization.Get<Localization::LicenseUrl>() == \"http://licenseUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Copyright>() == \"Foo Bar Copyright\");\r\n            REQUIRE(frenchLocalization.Get<Localization::CopyrightUrl>() == \"http://copyrightUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::ShortDescription>() == \"Foo bar is a foo bar French.\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Description>() == \"Foo bar is a placeholder French.\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().size() == 3);\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(0) == \"FooBarFr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(1) == \"FooFr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(2) == \"BarFr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::ReleaseNotes>() == \"Release notes\");\r\n            REQUIRE(frenchLocalization.Get<Localization::ReleaseNotesUrl>() == \"https://ReleaseNotes.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().size() == 1);\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).Label == \"Label\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).AgreementText == \"Text\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).AgreementUrl == \"https://AgreementUrl.net\");\r\n        }\r\n\r\n        void VerifyInstallers_AllFields(const Manifest& manifest)\r\n        {\r\n            REQUIRE(manifest.Installers.size() == 1);\r\n\r\n            ManifestInstaller actualInstaller = manifest.Installers.at(0);\r\n            REQUIRE(actualInstaller.Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\"));\r\n            REQUIRE(actualInstaller.Url == \"http://foobar.exe\");\r\n            REQUIRE(actualInstaller.Arch == Architecture::X86);\r\n            REQUIRE(actualInstaller.Locale == \"en-US\");\r\n            REQUIRE(actualInstaller.Platform.size() == 1);\r\n            REQUIRE(actualInstaller.Platform[0] == PlatformEnum::Desktop);\r\n            REQUIRE(actualInstaller.MinOSVersion == \"1078\");\r\n            REQUIRE(actualInstaller.BaseInstallerType == InstallerTypeEnum::Msi);\r\n            REQUIRE(actualInstaller.Scope == ScopeEnum::User);\r\n            REQUIRE(actualInstaller.InstallModes.size() == 1);\r\n            REQUIRE(actualInstaller.InstallModes.at(0) == InstallModeEnum::Interactive);\r\n            REQUIRE(actualInstaller.Switches.size() == 7);\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Silent) == \"/s\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::SilentWithProgress) == \"/s\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Interactive) == \"/i\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::InstallLocation) == \"C:\\\\Users\\\\User1\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Log) == \"/l\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Update) == \"/u\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Custom) == \"/custom\");\r\n            REQUIRE(actualInstaller.InstallerSuccessCodes.size() == 1);\r\n            REQUIRE(actualInstaller.InstallerSuccessCodes.at(0) == 0);\r\n            REQUIRE(actualInstaller.UpdateBehavior == UpdateBehaviorEnum::Install);\r\n            REQUIRE(actualInstaller.Commands.at(0) == \"command1\");\r\n            REQUIRE(actualInstaller.Protocols.at(0) == \"protocol1\");\r\n            REQUIRE(actualInstaller.FileExtensions.at(0) == \".file-extension\");\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::WindowsFeature, \"feature1\"));\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::WindowsLibrary, \"library1\"));\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::Package, \"Foo.Baz\", \"2.0.0\"));\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::External, \"FooBarBaz\"));\r\n            REQUIRE(actualInstaller.PackageFamilyName == \"\");\r\n            REQUIRE(actualInstaller.ProductCode == \"5b6e0f8a-3bbf-4a17-aefd-024c2b3e075d\");\r\n            REQUIRE(actualInstaller.ReleaseDate == \"2021-01-01\");\r\n            REQUIRE(actualInstaller.InstallerAbortsTerminal);\r\n            REQUIRE(actualInstaller.InstallLocationRequired);\r\n            REQUIRE(actualInstaller.RequireExplicitUpgrade);\r\n            REQUIRE(actualInstaller.ElevationRequirement == ElevationRequirementEnum::ElevatesSelf);\r\n            REQUIRE(actualInstaller.UnsupportedOSArchitectures.size() == 1);\r\n            REQUIRE(actualInstaller.UnsupportedOSArchitectures.at(0) == Architecture::Arm);\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.size() == 1);\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).DisplayName == \"DisplayName\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).DisplayVersion == \"DisplayVersion\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).Publisher == \"Publisher\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).ProductCode == \"ProductCode\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).UpgradeCode == \"UpgradeCode\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).InstallerType == InstallerTypeEnum::Exe);\r\n            REQUIRE(actualInstaller.Markets.AllowedMarkets.size() == 1);\r\n            REQUIRE(actualInstaller.Markets.AllowedMarkets.at(0) == \"US\");\r\n            REQUIRE(actualInstaller.ExpectedReturnCodes.at(3).ReturnResponseEnum == ExpectedReturnCodeEnum::InstallInProgress);\r\n        }\r\n    };\r\n}\r\n\r\nTEST_CASE(\"Search_BadResponse_UnsupportedPackageMatchFields\", \"[RestSource][Interface_1_1]\")\r\n{\r\n    utility::string_t sample = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : [],\r\n            \"UnsupportedPackageMatchFields\" : [ \"Moniker\" ]\r\n        })delimiter\");\r\n\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) };\r\n    Interface v1_1{ TestRestUriString, std::move(helper), GetTestSourceInformation(), {} };\r\n    AppInstaller::Repository::SearchRequest request;\r\n    PackageMatchFilter filter{ PackageMatchField::Name, MatchType::Exact, \"Foo\" };\r\n    request.Filters.emplace_back(std::move(filter));\r\n    REQUIRE_THROWS_HR(v1_1.Search(request), APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST);\r\n}\r\n\r\nTEST_CASE(\"Search_BadResponse_RequiredPackageMatchFields\", \"[RestSource][Interface_1_1]\")\r\n{\r\n    utility::string_t sample = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : [],\r\n            \"RequiredPackageMatchFields\" : [ \"Moniker\" ]\r\n        })delimiter\");\r\n\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) };\r\n    Interface v1_1{ TestRestUriString, std::move(helper), GetTestSourceInformation(), {} };\r\n    AppInstaller::Repository::SearchRequest request;\r\n    PackageMatchFilter filter{ PackageMatchField::Name, MatchType::Exact, \"Foo\" };\r\n    request.Filters.emplace_back(std::move(filter));\r\n    REQUIRE_THROWS_HR(v1_1.Search(request), APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST);\r\n}\r\n\r\nTEST_CASE(\"GetManifests_BadResponse_UnsupportedQueryParameters\", \"[RestSource][Interface_1_1]\")\r\n{\r\n    utility::string_t sample = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : null,\r\n            \"UnsupportedQueryParameters\" : [ \"Channel\" ]\r\n        })delimiter\");\r\n\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) };\r\n    Interface v1_1{ TestRestUriString, std::move(helper), GetTestSourceInformation(), {} };\r\n    REQUIRE_THROWS_HR(v1_1.GetManifests(\"Foo\"), APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST);\r\n}\r\n\r\nTEST_CASE(\"GetManifests_BadResponse_RequiredQueryParameters\", \"[RestSource][Interface_1_1]\")\r\n{\r\n    utility::string_t sample = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : null,\r\n            \"RequiredQueryParameters\" : [ \"Version\" ]\r\n        })delimiter\");\r\n\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) };\r\n    Interface v1_1{ TestRestUriString, std::move(helper), GetTestSourceInformation(), {} };\r\n    REQUIRE_THROWS_HR(v1_1.GetManifests(\"Foo\"), APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST);\r\n}\r\n\r\nTEST_CASE(\"Search_BadRequest_UnsupportedPackageMatchFields\", \"[RestSource][Interface_1_1]\")\r\n{\r\n    utility::string_t sample = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : [\r\n               {\r\n              \"PackageIdentifier\": \"git.package\",\r\n              \"PackageName\": \"package\",\r\n              \"Publisher\": \"git\",\r\n              \"Versions\": [\r\n                {   \"PackageVersion\": \"1.0.0\" },\r\n                {   \"PackageVersion\": \"2.0.0\" }]\r\n            }]\r\n        })delimiter\");\r\n\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) };\r\n    Interface v1_1{ TestRestUriString, std::move(helper), GetTestSourceInformation(), {} };\r\n    AppInstaller::Repository::SearchRequest request;\r\n    PackageMatchFilter filter{ PackageMatchField::Moniker, MatchType::Exact, \"Foo\" };\r\n    request.Filters.emplace_back(std::move(filter));\r\n    REQUIRE_THROWS_HR(v1_1.Search(request), APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST);\r\n}\r\n\r\nTEST_CASE(\"Search_GoodRequest_OnlyMarketRequired\", \"[RestSource][Interface_1_1]\")\r\n{\r\n    utility::string_t sample = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : [\r\n               {\r\n              \"PackageIdentifier\": \"git.package\",\r\n              \"PackageName\": \"package\",\r\n              \"Publisher\": \"git\",\r\n              \"Versions\": [\r\n                {   \"PackageVersion\": \"1.0.0\" },\r\n                {   \"PackageVersion\": \"2.0.0\" }]\r\n            }]\r\n        })delimiter\");\r\n\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) };\r\n    Interface v1_1{ TestRestUriString, std::move(helper), GetTestSourceInformation(), {} };\r\n    AppInstaller::Repository::SearchRequest request;\r\n    PackageMatchFilter filter{ PackageMatchField::Name, MatchType::Exact, \"Foo\" };\r\n    request.Filters.emplace_back(std::move(filter));\r\n    Schema::IRestClient::SearchResult searchResponse = v1_1.Search(request);\r\n    REQUIRE(searchResponse.Matches.size() == 1);\r\n    Schema::IRestClient::Package package = searchResponse.Matches.at(0);\r\n    REQUIRE(package.PackageInformation.PackageIdentifier.compare(\"git.package\") == 0);\r\n    REQUIRE(package.PackageInformation.Publisher.compare(\"git\") == 0);\r\n    REQUIRE(package.PackageInformation.PackageName.compare(\"package\") == 0);\r\n    REQUIRE(package.Versions.size() == 2);\r\n    REQUIRE(package.Versions.at(0).VersionAndChannel.GetVersion().ToString().compare(\"1.0.0\") == 0);\r\n    REQUIRE(package.Versions.at(1).VersionAndChannel.GetVersion().ToString().compare(\"2.0.0\") == 0);\r\n}\r\n\r\nTEST_CASE(\"GetManifests_BadRequest_UnsupportedQueryParameters\", \"[RestSource][Interface_1_1]\")\r\n{\r\n    utility::string_t sample = _XPLATSTR(\r\n        R\"delimiter({\r\n        \"Data\": {\r\n            \"PackageIdentifier\": \"Foo.Bar\",\r\n            \"Versions\": [\r\n                {\r\n                    \"PackageVersion\": \"5.0.0\",\r\n                    \"DefaultLocale\": {\r\n                        \"PackageLocale\": \"en-us\",\r\n                        \"Publisher\": \"Foo\",\r\n                        \"PackageName\": \"Bar\",\r\n                        \"License\": \"Foo bar license\",\r\n                        \"ShortDescription\": \"Foo bar description\"\r\n                    },\r\n                    \"Installers\": [\r\n                        {\r\n                            \"Architecture\": \"x64\",\r\n                            \"InstallerSha256\": \"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\",\r\n                            \"InstallerType\": \"exe\",\r\n                            \"InstallerUrl\": \"https://installer.example.com/foobar.exe\"\r\n                        }\r\n                    ]\r\n                }\r\n            ]\r\n        }\r\n    })delimiter\");\r\n\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) };\r\n    Interface v1_1{ TestRestUriString, std::move(helper), GetTestSourceInformation(), {} };\r\n    REQUIRE_THROWS_HR(v1_1.GetManifestByVersion(\"Foo\", \"1.0\", \"beta\"), APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST);\r\n}\r\n\r\nTEST_CASE(\"GetManifests_GoodRequest_OnlyMarketRequired\", \"[RestSource][Interface_1_1]\")\r\n{\r\n    utility::string_t sample = _XPLATSTR(\r\n        R\"delimiter({\r\n        \"Data\": {\r\n            \"PackageIdentifier\": \"Foo.Bar\",\r\n            \"Versions\": [\r\n                {\r\n                    \"PackageVersion\": \"5.0.0\",\r\n                    \"DefaultLocale\": {\r\n                        \"PackageLocale\": \"en-us\",\r\n                        \"Publisher\": \"Foo\",\r\n                        \"PackageName\": \"Bar\",\r\n                        \"License\": \"Foo bar license\",\r\n                        \"ShortDescription\": \"Foo bar description\"\r\n                    },\r\n                    \"Installers\": [\r\n                        {\r\n                            \"Architecture\": \"x64\",\r\n                            \"InstallerSha256\": \"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\",\r\n                            \"InstallerType\": \"exe\",\r\n                            \"InstallerUrl\": \"https://installer.example.com/foobar.exe\"\r\n                        }\r\n                    ]\r\n                }\r\n            ]\r\n        }\r\n    })delimiter\");\r\n\r\n    IRestClient::Information info = GetTestSourceInformation();\r\n    info.UnsupportedQueryParameters.clear();\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) };\r\n    Interface v1_1{ TestRestUriString, std::move(helper), info, {} };\r\n    auto manifestResult = v1_1.GetManifestByVersion(\"Foo\", \"5.0.0\", \"\");\r\n    REQUIRE(manifestResult.has_value());\r\n    const Manifest& manifest = manifestResult.value();\r\n    REQUIRE(manifest.Id == \"Foo.Bar\");\r\n    REQUIRE(manifest.Version == \"5.0.0\");\r\n    REQUIRE(manifest.DefaultLocalization.Locale == \"en-us\");\r\n    REQUIRE(manifest.DefaultLocalization.Get<Localization::Publisher>() == \"Foo\");\r\n    REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageName>() == \"Bar\");\r\n    REQUIRE(manifest.DefaultLocalization.Get<Localization::License>() == \"Foo bar license\");\r\n    REQUIRE(manifest.DefaultLocalization.Get<Localization::ShortDescription>() == \"Foo bar description\");\r\n    REQUIRE(manifest.Installers.size() == 1);\r\n    REQUIRE(manifest.Installers[0].Arch == Architecture::X64);\r\n    REQUIRE(manifest.Installers[0].Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\"));\r\n    REQUIRE(manifest.Installers[0].BaseInstallerType == InstallerTypeEnum::Exe);\r\n    REQUIRE(manifest.Installers[0].Url == \"https://installer.example.com/foobar.exe\");\r\n}\r\n\r\nTEST_CASE(\"GetManifests_GoodResponse_MSStoreType\", \"[RestSource][Interface_1_1]\")\r\n{\r\n    utility::string_t msstoreInstallerResponse = _XPLATSTR(\r\n        R\"delimiter({\r\n        \"Data\": {\r\n            \"PackageIdentifier\": \"Foo.Bar\",\r\n            \"Versions\": [\r\n                {\r\n                    \"PackageVersion\": \"5.0.0\",\r\n                    \"DefaultLocale\": {\r\n                        \"PackageLocale\": \"en-us\",\r\n                        \"Publisher\": \"Foo\",\r\n                        \"PackageName\": \"Bar\",\r\n                        \"License\": \"Foo bar license\",\r\n                        \"ShortDescription\": \"Foo bar description\"\r\n                    },\r\n                    \"Installers\": [\r\n                        {\r\n                            \"Architecture\": \"x64\",\r\n                            \"InstallerType\": \"msstore\",\r\n                            \"MSStoreProductIdentifier\": \"9nblggh4nns1\"\r\n                        }\r\n                    ]\r\n                }\r\n            ]\r\n        }\r\n    })delimiter\");\r\n\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(msstoreInstallerResponse)) };\r\n    Interface v1_1{ TestRestUriString, std::move(helper), GetTestSourceInformation(), {} };\r\n    std::vector<Manifest> manifests = v1_1.GetManifests(\"Foo.Bar\");\r\n    REQUIRE(manifests.size() == 1);\r\n\r\n    // Verify manifest is populated and manifest validation passed\r\n    Manifest manifest = manifests[0];\r\n    REQUIRE(manifest.Installers.size() == 1);\r\n    REQUIRE(manifest.Installers.at(0).BaseInstallerType == InstallerTypeEnum::MSStore);\r\n    REQUIRE(manifest.Installers.at(0).ProductId == \"9nblggh4nns1\");\r\n}\r\n\r\nTEST_CASE(\"GetManifests_GoodResponse_V1_1\", \"[RestSource][Interface_1_1]\")\r\n{\r\n    GoodManifest_AllFields sampleManifest;\r\n    utility::string_t sample = sampleManifest.GetSampleManifest_AllFields();\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) };\r\n    Interface v1_1{ TestRestUriString, std::move(helper), {} };\r\n    std::vector<Manifest> manifests = v1_1.GetManifests(\"Foo.Bar\");\r\n    REQUIRE(manifests.size() == 1);\r\n\r\n    // Verify manifest is populated\r\n    Manifest& manifest = manifests[0];\r\n    REQUIRE(manifest.Id == \"Foo.Bar\");\r\n    REQUIRE(manifest.Version == \"3.0.0abc\");\r\n    REQUIRE(manifest.Moniker == \"FooBarMoniker\");\r\n    REQUIRE(manifest.Channel == \"\");\r\n    REQUIRE(manifest.ManifestVersion == AppInstaller::Manifest::ManifestVer{ \"1.1.0\" });\r\n    sampleManifest.VerifyLocalizations_AllFields(manifest);\r\n    sampleManifest.VerifyInstallers_AllFields(manifest);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/RestInterface_1_10.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestRestRequestHandler.h\"\r\n#include <Rest/Schema/1_10/Interface.h>\r\n#include <Rest/Schema/IRestClient.h>\r\n#include <AppInstallerVersions.h>\r\n#include <AppInstallerErrors.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::Http;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Repository::Rest;\r\nusing namespace AppInstaller::Repository::Rest::Schema;\r\nusing namespace AppInstaller::Repository::Rest::Schema::V1_10;\r\n\r\nnamespace\r\n{\r\n    const std::string TestRestUriString = \"http://restsource.com/api\";\r\n\r\n    struct GoodManifest_AllFields\r\n    {\r\n        utility::string_t GetSampleManifest_AllFields()\r\n        {\r\n            return _XPLATSTR(\r\n                R\"delimiter(\r\n        {\r\n          \"Data\": {\r\n            \"PackageIdentifier\": \"Foo.Bar\",\r\n            \"Versions\": [\r\n              {\r\n                \"PackageVersion\": \"3.0.0abc\",\r\n                \"DefaultLocale\": {\r\n                  \"PackageLocale\": \"en-US\",\r\n                  \"Publisher\": \"Foo\",\r\n                  \"PublisherUrl\": \"http://publisher.net\",\r\n                  \"PublisherSupportUrl\": \"http://publisherSupport.net\",\r\n                  \"PrivacyUrl\": \"http://packagePrivacyUrl.net\",\r\n                  \"Author\": \"FooBar\",\r\n                  \"PackageName\": \"Bar\",\r\n                  \"PackageUrl\": \"http://packageUrl.net\",\r\n                  \"License\": \"Foo Bar License\",\r\n                  \"LicenseUrl\": \"http://licenseUrl.net\",\r\n                  \"Copyright\": \"Foo Bar Copyright\",\r\n                  \"CopyrightUrl\": \"http://copyrightUrl.net\",\r\n                  \"ShortDescription\": \"Foo bar is a foo bar.\",\r\n                  \"Description\": \"Foo bar is a placeholder.\",\r\n                  \"Tags\": [\r\n                    \"FooBar\",\r\n                    \"Foo\",\r\n                    \"Bar\"\r\n                  ],\r\n                  \"Moniker\": \"FooBarMoniker\",\r\n                  \"ReleaseNotes\": \"Default release notes\",\r\n                  \"ReleaseNotesUrl\": \"https://DefaultReleaseNotes.net\",\r\n                  \"Agreements\": [{\r\n                    \"AgreementLabel\": \"DefaultLabel\",\r\n                    \"Agreement\": \"DefaultText\",\r\n                    \"AgreementUrl\": \"https://DefaultAgreementUrl.net\"\r\n                  }],\r\n                  \"PurchaseUrl\": \"http://DefaultPurchaseUrl.net\",\r\n                  \"InstallationNotes\": \"Default Installation Notes\",\r\n                  \"Documentations\": [{\r\n                    \"DocumentLabel\": \"Default Document Label\",\r\n                    \"DocumentUrl\": \"http://DefaultDocumentUrl.net\"\r\n                  }],\r\n                  \"Icons\": [{\r\n                    \"IconUrl\": \"https://DefaultTestIcon\",\r\n                    \"IconFileType\": \"ico\",\r\n                    \"IconResolution\": \"custom\",\r\n                    \"IconTheme\": \"default\",\r\n                    \"IconSha256\": \"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\"\r\n                  }]\r\n                },\r\n                \"Channel\": \"\",\r\n                \"Locales\": [\r\n                  {\r\n                    \"PackageLocale\": \"fr-Fr\",\r\n                    \"Publisher\": \"Foo French\",\r\n                    \"PublisherUrl\": \"http://publisher-fr.net\",\r\n                    \"PublisherSupportUrl\": \"http://publisherSupport-fr.net\",\r\n                    \"PrivacyUrl\": \"http://packagePrivacyUrl-fr.net\",\r\n                    \"Author\": \"FooBar French\",\r\n                    \"PackageName\": \"Bar\",\r\n                    \"PackageUrl\": \"http://packageUrl-fr.net\",\r\n                    \"License\": \"Foo Bar License\",\r\n                    \"LicenseUrl\": \"http://licenseUrl-fr.net\",\r\n                    \"Copyright\": \"Foo Bar Copyright\",\r\n                    \"CopyrightUrl\": \"http://copyrightUrl-fr.net\",\r\n                    \"ShortDescription\": \"Foo bar is a foo bar French.\",\r\n                    \"Description\": \"Foo bar is a placeholder French.\",\r\n                    \"Tags\": [\r\n                      \"FooBarFr\",\r\n                      \"FooFr\",\r\n                      \"BarFr\"\r\n                    ],\r\n                    \"ReleaseNotes\": \"Release notes\",\r\n                    \"ReleaseNotesUrl\": \"https://ReleaseNotes.net\",\r\n                    \"Agreements\": [{\r\n                      \"AgreementLabel\": \"Label\",\r\n                      \"Agreement\": \"Text\",\r\n                      \"AgreementUrl\": \"https://AgreementUrl.net\"\r\n                    }],\r\n                    \"PurchaseUrl\": \"http://purchaseUrl.net\",\r\n                    \"InstallationNotes\": \"Installation Notes\",\r\n                    \"Documentations\": [{\r\n                      \"DocumentLabel\": \"Document Label\",\r\n                      \"DocumentUrl\": \"http://documentUrl.net\"\r\n                    }],\r\n                    \"Icons\": [{\r\n                      \"IconUrl\": \"https://testIcon\",\r\n                      \"IconFileType\": \"png\",\r\n                      \"IconResolution\": \"32x32\",\r\n                      \"IconTheme\": \"light\",\r\n                      \"IconSha256\": \"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321\"\r\n                    }]\r\n                  }\r\n                ],)delimiter\") _XPLATSTR(R\"delimiter(\r\n                \"Installers\": [\r\n                  {\r\n                    \"InstallerSha256\": \"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\",\r\n                    \"InstallerUrl\": \"http://foobar.zip\",\r\n                    \"Architecture\": \"x86\",\r\n                    \"InstallerLocale\": \"en-US\",\r\n                    \"Platform\": [\r\n                      \"Windows.Desktop\"\r\n                    ],\r\n                    \"MinimumOSVersion\": \"1078\",\r\n                    \"InstallerType\": \"zip\",\r\n                    \"Scope\": \"user\",\r\n                    \"InstallModes\": [\r\n                      \"interactive\"\r\n                    ],\r\n                    \"InstallerSwitches\": {\r\n                      \"Silent\": \"/s\",\r\n                      \"SilentWithProgress\": \"/s\",\r\n                      \"Interactive\": \"/i\",\r\n                      \"InstallLocation\": \"C:\\\\Users\\\\User1\",\r\n                      \"Log\": \"/l\",\r\n                      \"Upgrade\": \"/u\",\r\n                      \"Custom\": \"/custom\",\r\n                      \"Repair\": \"/repair\"\r\n                    },\r\n                    \"InstallerSuccessCodes\": [\r\n                      0\r\n                    ],\r\n                    \"UpgradeBehavior\": \"deny\",\r\n                    \"Commands\": [\r\n                      \"command1\"\r\n                    ],\r\n                    \"Protocols\": [\r\n                       \"protocol1\"\r\n                    ],\r\n                    \"FileExtensions\": [\r\n                      \".file-extension\"\r\n                    ],\r\n                    \"Dependencies\": {\r\n                      \"WindowsFeatures\": [\r\n                        \"feature1\"\r\n                      ],\r\n                      \"WindowsLibraries\": [\r\n                        \"library1\"\r\n                      ],\r\n                      \"PackageDependencies\": [\r\n                        {\r\n                          \"PackageIdentifier\": \"Foo.Baz\",\r\n                          \"MinimumVersion\": \"2.0.0\"\r\n                        }\r\n                      ],\r\n                      \"ExternalDependencies\": [\r\n                        \"FooBarBaz\"\r\n                      ]\r\n                    },\r\n                    \"ProductCode\": \"5b6e0f8a-3bbf-4a17-aefd-024c2b3e075d\",\r\n                    \"ReleaseDate\": \"2021-01-01\",\r\n                    \"InstallerAbortsTerminal\": true,\r\n                    \"InstallLocationRequired\": true,\r\n                    \"RequireExplicitUpgrade\": true,\r\n                    \"UnsupportedOSArchitectures\": [ \"arm\" ],\r\n                    \"ElevationRequirement\": \"elevatesSelf\",\r\n                    \"AppsAndFeaturesEntries\": [{\r\n                      \"DisplayName\": \"DisplayName\",\r\n                      \"DisplayVersion\": \"DisplayVersion\",\r\n                      \"Publisher\": \"Publisher\",\r\n                      \"ProductCode\": \"ProductCode\",\r\n                      \"UpgradeCode\": \"UpgradeCode\",\r\n                      \"InstallerType\": \"exe\"\r\n                    }],\r\n                    \"Markets\" : {\r\n                      \"AllowedMarkets\": [ \"US\" ]\r\n                    },\r\n                    \"ExpectedReturnCodes\": [{\r\n                      \"InstallerReturnCode\": 3,\r\n                      \"ReturnResponse\": \"custom\",\r\n                      \"ReturnResponseUrl\": \"http://returnResponseUrl.net\"\r\n                    }],\r\n                    \"NestedInstallerType\": \"portable\",\r\n                    \"DisplayInstallWarnings\": true,\r\n                    \"UnsupportedArguments\": [ \"log\" ],\r\n                    \"NestedInstallerFiles\": [{\r\n                      \"RelativeFilePath\": \"test\\\\app.exe\",\r\n                      \"PortableCommandAlias\": \"test.exe\"\r\n                    }],\r\n                    \"InstallationMetadata\": {\r\n                      \"DefaultInstallLocation\": \"%TEMP%\\\\DefaultInstallLocation\",\r\n                      \"Files\": [{\r\n                        \"RelativeFilePath\": \"test\\\\app.exe\",\r\n                        \"FileSha256\": \"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\",\r\n                        \"FileType\": \"launch\",\r\n                        \"InvocationParameter\": \"/parameter\",\r\n                        \"DisplayName\": \"test\"\r\n                      }]\r\n                    },\r\n                    \"DownloadCommandProhibited\": true,\r\n                    \"RepairBehavior\": \"uninstaller\",\r\n                    \"ArchiveBinariesDependOnPath\": true,\r\n                    \"Authentication\": {\r\n                      \"AuthenticationType\": \"microsoftEntraId\",\r\n                      \"MicrosoftEntraIdAuthenticationInfo\" : {\r\n                        \"Resource\": \"TestResource\",\r\n                        \"Scope\" : \"TestScope\"\r\n                      }\r\n                    }\r\n                  }\r\n                ]\r\n              }\r\n            ]\r\n          },\r\n          \"ContinuationToken\": \"abcd\"\r\n        })delimiter\");\r\n        }\r\n\r\n        void VerifyLocalizations_AllFields(const AppInstaller::Manifest::Manifest& manifest)\r\n        {\r\n            REQUIRE(manifest.DefaultLocalization.Locale == \"en-US\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Publisher>() == \"Foo\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PublisherUrl>() == \"http://publisher.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PublisherSupportUrl>() == \"http://publisherSupport.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PrivacyUrl>() == \"http://packagePrivacyUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Author>() == \"FooBar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageName>() == \"Bar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageUrl>() == \"http://packageUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::License>() == \"Foo Bar License\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::LicenseUrl>() == \"http://licenseUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Copyright>() == \"Foo Bar Copyright\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::CopyrightUrl>() == \"http://copyrightUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ShortDescription>() == \"Foo bar is a foo bar.\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Description>() == \"Foo bar is a placeholder.\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().size() == 3);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(0) == \"FooBar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(1) == \"Foo\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(2) == \"Bar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ReleaseNotes>() == \"Default release notes\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ReleaseNotesUrl>() == \"https://DefaultReleaseNotes.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().size() == 1);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).Label == \"DefaultLabel\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).AgreementText == \"DefaultText\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).AgreementUrl == \"https://DefaultAgreementUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PurchaseUrl>() == \"http://DefaultPurchaseUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::InstallationNotes>() == \"Default Installation Notes\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().size() == 1);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().at(0).DocumentLabel == \"Default Document Label\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().at(0).DocumentUrl == \"http://DefaultDocumentUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().size() == 1);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Url == \"https://DefaultTestIcon\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).FileType == IconFileTypeEnum::Ico);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Resolution == IconResolutionEnum::Custom);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Theme == IconThemeEnum::Default);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\"));\r\n\r\n            REQUIRE(manifest.Localizations.size() == 1);\r\n            ManifestLocalization frenchLocalization = manifest.Localizations.at(0);\r\n            REQUIRE(frenchLocalization.Locale == \"fr-Fr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Publisher>() == \"Foo French\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PublisherUrl>() == \"http://publisher-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PublisherSupportUrl>() == \"http://publisherSupport-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PrivacyUrl>() == \"http://packagePrivacyUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Author>() == \"FooBar French\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PackageName>() == \"Bar\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PackageUrl>() == \"http://packageUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::License>() == \"Foo Bar License\");\r\n            REQUIRE(frenchLocalization.Get<Localization::LicenseUrl>() == \"http://licenseUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Copyright>() == \"Foo Bar Copyright\");\r\n            REQUIRE(frenchLocalization.Get<Localization::CopyrightUrl>() == \"http://copyrightUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::ShortDescription>() == \"Foo bar is a foo bar French.\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Description>() == \"Foo bar is a placeholder French.\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().size() == 3);\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(0) == \"FooBarFr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(1) == \"FooFr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(2) == \"BarFr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::ReleaseNotes>() == \"Release notes\");\r\n            REQUIRE(frenchLocalization.Get<Localization::ReleaseNotesUrl>() == \"https://ReleaseNotes.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().size() == 1);\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).Label == \"Label\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).AgreementText == \"Text\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).AgreementUrl == \"https://AgreementUrl.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PurchaseUrl>() == \"http://purchaseUrl.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::InstallationNotes>() == \"Installation Notes\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Documentations>().size() == 1);\r\n            REQUIRE(frenchLocalization.Get<Localization::Documentations>().at(0).DocumentLabel == \"Document Label\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Documentations>().at(0).DocumentUrl == \"http://documentUrl.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().size() == 1);\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Url == \"https://testIcon\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).FileType == IconFileTypeEnum::Png);\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Resolution == IconResolutionEnum::Square32);\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Theme == IconThemeEnum::Light);\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321\"));\r\n        }\r\n\r\n        void VerifyInstallers_AllFields(const AppInstaller::Manifest::Manifest& manifest)\r\n        {\r\n            REQUIRE(manifest.Installers.size() == 1);\r\n\r\n            ManifestInstaller actualInstaller = manifest.Installers.at(0);\r\n            REQUIRE(actualInstaller.Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\"));\r\n            REQUIRE(actualInstaller.Url == \"http://foobar.zip\");\r\n            REQUIRE(actualInstaller.Arch == Architecture::X86);\r\n            REQUIRE(actualInstaller.Locale == \"en-US\");\r\n            REQUIRE(actualInstaller.Platform.size() == 1);\r\n            REQUIRE(actualInstaller.Platform[0] == PlatformEnum::Desktop);\r\n            REQUIRE(actualInstaller.MinOSVersion == \"1078\");\r\n            REQUIRE(actualInstaller.BaseInstallerType == InstallerTypeEnum::Zip);\r\n            REQUIRE(actualInstaller.Scope == ScopeEnum::User);\r\n            REQUIRE(actualInstaller.InstallModes.size() == 1);\r\n            REQUIRE(actualInstaller.InstallModes.at(0) == InstallModeEnum::Interactive);\r\n            REQUIRE(actualInstaller.Switches.size() == 8);\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Silent) == \"/s\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::SilentWithProgress) == \"/s\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Interactive) == \"/i\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::InstallLocation) == \"C:\\\\Users\\\\User1\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Log) == \"/l\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Update) == \"/u\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Custom) == \"/custom\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Repair) == \"/repair\");\r\n            REQUIRE(actualInstaller.InstallerSuccessCodes.size() == 1);\r\n            REQUIRE(actualInstaller.InstallerSuccessCodes.at(0) == 0);\r\n            REQUIRE(actualInstaller.UpdateBehavior == UpdateBehaviorEnum::Deny);\r\n            REQUIRE(actualInstaller.Commands.at(0) == \"command1\");\r\n            REQUIRE(actualInstaller.Protocols.at(0) == \"protocol1\");\r\n            REQUIRE(actualInstaller.FileExtensions.at(0) == \".file-extension\");\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::WindowsFeature, \"feature1\"));\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::WindowsLibrary, \"library1\"));\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::Package, \"Foo.Baz\", \"2.0.0\"));\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::External, \"FooBarBaz\"));\r\n            REQUIRE(actualInstaller.PackageFamilyName == \"\");\r\n            REQUIRE(actualInstaller.ProductCode == \"5b6e0f8a-3bbf-4a17-aefd-024c2b3e075d\");\r\n            REQUIRE(actualInstaller.ReleaseDate == \"2021-01-01\");\r\n            REQUIRE(actualInstaller.InstallerAbortsTerminal);\r\n            REQUIRE(actualInstaller.InstallLocationRequired);\r\n            REQUIRE(actualInstaller.RequireExplicitUpgrade);\r\n            REQUIRE(actualInstaller.ElevationRequirement == ElevationRequirementEnum::ElevatesSelf);\r\n            REQUIRE(actualInstaller.UnsupportedOSArchitectures.size() == 1);\r\n            REQUIRE(actualInstaller.UnsupportedOSArchitectures.at(0) == Architecture::Arm);\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.size() == 1);\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).DisplayName == \"DisplayName\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).DisplayVersion == \"DisplayVersion\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).Publisher == \"Publisher\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).ProductCode == \"ProductCode\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).UpgradeCode == \"UpgradeCode\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).InstallerType == InstallerTypeEnum::Exe);\r\n            REQUIRE(actualInstaller.Markets.AllowedMarkets.size() == 1);\r\n            REQUIRE(actualInstaller.Markets.AllowedMarkets.at(0) == \"US\");\r\n            REQUIRE(actualInstaller.ExpectedReturnCodes.at(3).ReturnResponseEnum == ExpectedReturnCodeEnum::Custom);\r\n            REQUIRE(actualInstaller.ExpectedReturnCodes.at(3).ReturnResponseUrl == \"http://returnResponseUrl.net\");\r\n            REQUIRE(actualInstaller.NestedInstallerType == InstallerTypeEnum::Portable);\r\n            REQUIRE(actualInstaller.DisplayInstallWarnings);\r\n            REQUIRE(actualInstaller.UnsupportedArguments.size() == 1);\r\n            REQUIRE(actualInstaller.UnsupportedArguments.at(0) == UnsupportedArgumentEnum::Log);\r\n            REQUIRE(actualInstaller.NestedInstallerFiles.size() == 1);\r\n            REQUIRE(actualInstaller.NestedInstallerFiles.at(0).RelativeFilePath == \"test\\\\app.exe\");\r\n            REQUIRE(actualInstaller.NestedInstallerFiles.at(0).PortableCommandAlias == \"test.exe\");\r\n            REQUIRE(actualInstaller.InstallationMetadata.DefaultInstallLocation == \"%TEMP%\\\\DefaultInstallLocation\");\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.size() == 1);\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).RelativeFilePath == \"test\\\\app.exe\");\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).FileType == InstalledFileTypeEnum::Launch);\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).FileSha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\"));\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).InvocationParameter == \"/parameter\");\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).DisplayName == \"test\");\r\n            REQUIRE(actualInstaller.DownloadCommandProhibited);\r\n            REQUIRE(actualInstaller.RepairBehavior == RepairBehaviorEnum::Uninstaller);\r\n            REQUIRE(actualInstaller.ArchiveBinariesDependOnPath);\r\n            REQUIRE(actualInstaller.AuthInfo.Type == AppInstaller::Authentication::AuthenticationType::MicrosoftEntraId);\r\n            REQUIRE(actualInstaller.AuthInfo.MicrosoftEntraIdInfo.has_value());\r\n            REQUIRE(actualInstaller.AuthInfo.MicrosoftEntraIdInfo->Resource == \"TestResource\");\r\n            REQUIRE(actualInstaller.AuthInfo.MicrosoftEntraIdInfo->Scope == \"TestScope\");\r\n        }\r\n    };\r\n}\r\n\r\nTEST_CASE(\"GetManifests_GoodResponse_V1_10\", \"[RestSource][Interface_1_10]\")\r\n{\r\n    GoodManifest_AllFields sampleManifest;\r\n    utility::string_t sample = sampleManifest.GetSampleManifest_AllFields();\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) };\r\n    Interface v1_10{ TestRestUriString, std::move(helper), {} };\r\n    std::vector<Manifest> manifests = v1_10.GetManifests(\"Foo.Bar\");\r\n    REQUIRE(manifests.size() == 1);\r\n\r\n    // Verify manifest is populated\r\n    Manifest& manifest = manifests[0];\r\n    REQUIRE(manifest.Id == \"Foo.Bar\");\r\n    REQUIRE(manifest.Version == \"3.0.0abc\");\r\n    REQUIRE(manifest.Moniker == \"FooBarMoniker\");\r\n    REQUIRE(manifest.Channel == \"\");\r\n    REQUIRE(manifest.ManifestVersion == AppInstaller::Manifest::ManifestVer{ \"1.10.0\" });\r\n    sampleManifest.VerifyLocalizations_AllFields(manifest);\r\n    sampleManifest.VerifyInstallers_AllFields(manifest);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/RestInterface_1_12.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"TestCommon.h\"\n#include \"TestRestRequestHandler.h\"\n#include <Rest/Schema/1_12/Interface.h>\n#include <Rest/Schema/IRestClient.h>\n#include <AppInstallerVersions.h>\n#include <AppInstallerErrors.h>\n\nusing namespace TestCommon;\nusing namespace AppInstaller::Http;\nusing namespace AppInstaller::Utility;\nusing namespace AppInstaller::Manifest;\nusing namespace AppInstaller::Repository;\nusing namespace AppInstaller::Repository::Rest;\nusing namespace AppInstaller::Repository::Rest::Schema;\nusing namespace AppInstaller::Repository::Rest::Schema::V1_12;\n\nnamespace\n{\n    const std::string TestRestUriString = \"http://restsource.com/api\";\n\n    struct GoodManifest_AllFields\n    {\n        utility::string_t GetSampleManifest_AllFields()\n        {\n            return _XPLATSTR(\n                R\"delimiter(\n        {\n          \"Data\": {\n            \"PackageIdentifier\": \"Foo.Bar\",\n            \"Versions\": [\n              {\n                \"PackageVersion\": \"3.0.0abc\",\n                \"DefaultLocale\": {\n                  \"PackageLocale\": \"en-US\",\n                  \"Publisher\": \"Foo\",\n                  \"PublisherUrl\": \"http://publisher.net\",\n                  \"PublisherSupportUrl\": \"http://publisherSupport.net\",\n                  \"PrivacyUrl\": \"http://packagePrivacyUrl.net\",\n                  \"Author\": \"FooBar\",\n                  \"PackageName\": \"Bar\",\n                  \"PackageUrl\": \"http://packageUrl.net\",\n                  \"License\": \"Foo Bar License\",\n                  \"LicenseUrl\": \"http://licenseUrl.net\",\n                  \"Copyright\": \"Foo Bar Copyright\",\n                  \"CopyrightUrl\": \"http://copyrightUrl.net\",\n                  \"ShortDescription\": \"Foo bar is a foo bar.\",\n                  \"Description\": \"Foo bar is a placeholder.\",\n                  \"Tags\": [\n                    \"FooBar\",\n                    \"Foo\",\n                    \"Bar\"\n                  ],\n                  \"Moniker\": \"FooBarMoniker\",\n                  \"ReleaseNotes\": \"Default release notes\",\n                  \"ReleaseNotesUrl\": \"https://DefaultReleaseNotes.net\",\n                  \"Agreements\": [{\n                    \"AgreementLabel\": \"DefaultLabel\",\n                    \"Agreement\": \"DefaultText\",\n                    \"AgreementUrl\": \"https://DefaultAgreementUrl.net\"\n                  }],\n                  \"PurchaseUrl\": \"http://DefaultPurchaseUrl.net\",\n                  \"InstallationNotes\": \"Default Installation Notes\",\n                  \"Documentations\": [{\n                    \"DocumentLabel\": \"Default Document Label\",\n                    \"DocumentUrl\": \"http://DefaultDocumentUrl.net\"\n                  }],\n                  \"Icons\": [{\n                    \"IconUrl\": \"https://DefaultTestIcon\",\n                    \"IconFileType\": \"ico\",\n                    \"IconResolution\": \"custom\",\n                    \"IconTheme\": \"default\",\n                    \"IconSha256\": \"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\"\n                  }]\n                },\n                \"Channel\": \"\",\n                \"Locales\": [\n                  {\n                    \"PackageLocale\": \"fr-Fr\",\n                    \"Publisher\": \"Foo French\",\n                    \"PublisherUrl\": \"http://publisher-fr.net\",\n                    \"PublisherSupportUrl\": \"http://publisherSupport-fr.net\",\n                    \"PrivacyUrl\": \"http://packagePrivacyUrl-fr.net\",\n                    \"Author\": \"FooBar French\",\n                    \"PackageName\": \"Bar\",\n                    \"PackageUrl\": \"http://packageUrl-fr.net\",\n                    \"License\": \"Foo Bar License\",\n                    \"LicenseUrl\": \"http://licenseUrl-fr.net\",\n                    \"Copyright\": \"Foo Bar Copyright\",\n                    \"CopyrightUrl\": \"http://copyrightUrl-fr.net\",\n                    \"ShortDescription\": \"Foo bar is a foo bar French.\",\n                    \"Description\": \"Foo bar is a placeholder French.\",\n                    \"Tags\": [\n                      \"FooBarFr\",\n                      \"FooFr\",\n                      \"BarFr\"\n                    ],\n                    \"ReleaseNotes\": \"Release notes\",\n                    \"ReleaseNotesUrl\": \"https://ReleaseNotes.net\",\n                    \"Agreements\": [{\n                      \"AgreementLabel\": \"Label\",\n                      \"Agreement\": \"Text\",\n                      \"AgreementUrl\": \"https://AgreementUrl.net\"\n                    }],\n                    \"PurchaseUrl\": \"http://purchaseUrl.net\",\n                    \"InstallationNotes\": \"Installation Notes\",\n                    \"Documentations\": [{\n                      \"DocumentLabel\": \"Document Label\",\n                      \"DocumentUrl\": \"http://documentUrl.net\"\n                    }],\n                    \"Icons\": [{\n                      \"IconUrl\": \"https://testIcon\",\n                      \"IconFileType\": \"png\",\n                      \"IconResolution\": \"32x32\",\n                      \"IconTheme\": \"light\",\n                      \"IconSha256\": \"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321\"\n                    }]\n                  }\n                ],)delimiter\") _XPLATSTR(R\"delimiter(\n                \"Installers\": [\n                  {\n                    \"InstallerSha256\": \"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\",\n                    \"InstallerUrl\": \"http://foobar.zip\",\n                    \"Architecture\": \"x86\",\n                    \"InstallerLocale\": \"en-US\",\n                    \"Platform\": [\n                      \"Windows.Desktop\"\n                    ],\n                    \"MinimumOSVersion\": \"1078\",\n                    \"InstallerType\": \"zip\",\n                    \"Scope\": \"user\",\n                    \"InstallModes\": [\n                      \"interactive\"\n                    ],\n                    \"InstallerSwitches\": {\n                      \"Silent\": \"/s\",\n                      \"SilentWithProgress\": \"/s\",\n                      \"Interactive\": \"/i\",\n                      \"InstallLocation\": \"C:\\\\Users\\\\User1\",\n                      \"Log\": \"/l\",\n                      \"Upgrade\": \"/u\",\n                      \"Custom\": \"/custom\",\n                      \"Repair\": \"/repair\"\n                    },\n                    \"InstallerSuccessCodes\": [\n                      0\n                    ],\n                    \"UpgradeBehavior\": \"deny\",\n                    \"Commands\": [\n                      \"command1\"\n                    ],\n                    \"Protocols\": [\n                       \"protocol1\"\n                    ],\n                    \"FileExtensions\": [\n                      \".file-extension\"\n                    ],\n                    \"Dependencies\": {\n                      \"WindowsFeatures\": [\n                        \"feature1\"\n                      ],\n                      \"WindowsLibraries\": [\n                        \"library1\"\n                      ],\n                      \"PackageDependencies\": [\n                        {\n                          \"PackageIdentifier\": \"Foo.Baz\",\n                          \"MinimumVersion\": \"2.0.0\"\n                        }\n                      ],\n                      \"ExternalDependencies\": [\n                        \"FooBarBaz\"\n                      ]\n                    },\n                    \"ProductCode\": \"5b6e0f8a-3bbf-4a17-aefd-024c2b3e075d\",\n                    \"ReleaseDate\": \"2021-01-01\",\n                    \"InstallerAbortsTerminal\": true,\n                    \"InstallLocationRequired\": true,\n                    \"RequireExplicitUpgrade\": true,\n                    \"UnsupportedOSArchitectures\": [ \"arm\" ],\n                    \"ElevationRequirement\": \"elevatesSelf\",\n                    \"AppsAndFeaturesEntries\": [{\n                      \"DisplayName\": \"DisplayName\",\n                      \"DisplayVersion\": \"DisplayVersion\",\n                      \"Publisher\": \"Publisher\",\n                      \"ProductCode\": \"ProductCode\",\n                      \"UpgradeCode\": \"UpgradeCode\",\n                      \"InstallerType\": \"exe\"\n                    }],\n                    \"Markets\" : {\n                      \"AllowedMarkets\": [ \"US\" ]\n                    },\n                    \"ExpectedReturnCodes\": [{\n                      \"InstallerReturnCode\": 3,\n                      \"ReturnResponse\": \"custom\",\n                      \"ReturnResponseUrl\": \"http://returnResponseUrl.net\"\n                    }],\n                    \"NestedInstallerType\": \"portable\",\n                    \"DisplayInstallWarnings\": true,\n                    \"UnsupportedArguments\": [ \"log\" ],\n                    \"NestedInstallerFiles\": [{\n                      \"RelativeFilePath\": \"test\\\\app.exe\",\n                      \"PortableCommandAlias\": \"test.exe\"\n                    }],\n                    \"InstallationMetadata\": {\n                      \"DefaultInstallLocation\": \"%TEMP%\\\\DefaultInstallLocation\",\n                      \"Files\": [{\n                        \"RelativeFilePath\": \"test\\\\app.exe\",\n                        \"FileSha256\": \"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\",\n                        \"FileType\": \"launch\",\n                        \"InvocationParameter\": \"/parameter\",\n                        \"DisplayName\": \"test\"\n                      }]\n                    },\n                    \"DownloadCommandProhibited\": true,\n                    \"RepairBehavior\": \"uninstaller\",\n                    \"ArchiveBinariesDependOnPath\": true,\n                    \"Authentication\": {\n                      \"AuthenticationType\": \"microsoftEntraId\",\n                      \"MicrosoftEntraIdAuthenticationInfo\" : {\n                        \"Resource\": \"TestResource\",\n                        \"Scope\" : \"TestScope\"\n                      }\n                    }\n                  }\n                ]\n              }\n            ]\n          },\n          \"ContinuationToken\": \"abcd\"\n        })delimiter\");\n        }\n\n        void VerifyLocalizations_AllFields(const AppInstaller::Manifest::Manifest& manifest)\n        {\n            REQUIRE(manifest.DefaultLocalization.Locale == \"en-US\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Publisher>() == \"Foo\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PublisherUrl>() == \"http://publisher.net\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PublisherSupportUrl>() == \"http://publisherSupport.net\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PrivacyUrl>() == \"http://packagePrivacyUrl.net\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Author>() == \"FooBar\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageName>() == \"Bar\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageUrl>() == \"http://packageUrl.net\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::License>() == \"Foo Bar License\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::LicenseUrl>() == \"http://licenseUrl.net\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Copyright>() == \"Foo Bar Copyright\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::CopyrightUrl>() == \"http://copyrightUrl.net\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ShortDescription>() == \"Foo bar is a foo bar.\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Description>() == \"Foo bar is a placeholder.\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().size() == 3);\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(0) == \"FooBar\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(1) == \"Foo\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(2) == \"Bar\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ReleaseNotes>() == \"Default release notes\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ReleaseNotesUrl>() == \"https://DefaultReleaseNotes.net\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().size() == 1);\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).Label == \"DefaultLabel\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).AgreementText == \"DefaultText\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).AgreementUrl == \"https://DefaultAgreementUrl.net\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PurchaseUrl>() == \"http://DefaultPurchaseUrl.net\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::InstallationNotes>() == \"Default Installation Notes\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().size() == 1);\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().at(0).DocumentLabel == \"Default Document Label\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().at(0).DocumentUrl == \"http://DefaultDocumentUrl.net\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().size() == 1);\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Url == \"https://DefaultTestIcon\");\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).FileType == IconFileTypeEnum::Ico);\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Resolution == IconResolutionEnum::Custom);\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Theme == IconThemeEnum::Default);\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\"));\n\n            REQUIRE(manifest.Localizations.size() == 1);\n            ManifestLocalization frenchLocalization = manifest.Localizations.at(0);\n            REQUIRE(frenchLocalization.Locale == \"fr-Fr\");\n            REQUIRE(frenchLocalization.Get<Localization::Publisher>() == \"Foo French\");\n            REQUIRE(frenchLocalization.Get<Localization::PublisherUrl>() == \"http://publisher-fr.net\");\n            REQUIRE(frenchLocalization.Get<Localization::PublisherSupportUrl>() == \"http://publisherSupport-fr.net\");\n            REQUIRE(frenchLocalization.Get<Localization::PrivacyUrl>() == \"http://packagePrivacyUrl-fr.net\");\n            REQUIRE(frenchLocalization.Get<Localization::Author>() == \"FooBar French\");\n            REQUIRE(frenchLocalization.Get<Localization::PackageName>() == \"Bar\");\n            REQUIRE(frenchLocalization.Get<Localization::PackageUrl>() == \"http://packageUrl-fr.net\");\n            REQUIRE(frenchLocalization.Get<Localization::License>() == \"Foo Bar License\");\n            REQUIRE(frenchLocalization.Get<Localization::LicenseUrl>() == \"http://licenseUrl-fr.net\");\n            REQUIRE(frenchLocalization.Get<Localization::Copyright>() == \"Foo Bar Copyright\");\n            REQUIRE(frenchLocalization.Get<Localization::CopyrightUrl>() == \"http://copyrightUrl-fr.net\");\n            REQUIRE(frenchLocalization.Get<Localization::ShortDescription>() == \"Foo bar is a foo bar French.\");\n            REQUIRE(frenchLocalization.Get<Localization::Description>() == \"Foo bar is a placeholder French.\");\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().size() == 3);\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(0) == \"FooBarFr\");\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(1) == \"FooFr\");\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(2) == \"BarFr\");\n            REQUIRE(frenchLocalization.Get<Localization::ReleaseNotes>() == \"Release notes\");\n            REQUIRE(frenchLocalization.Get<Localization::ReleaseNotesUrl>() == \"https://ReleaseNotes.net\");\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().size() == 1);\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).Label == \"Label\");\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).AgreementText == \"Text\");\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).AgreementUrl == \"https://AgreementUrl.net\");\n            REQUIRE(frenchLocalization.Get<Localization::PurchaseUrl>() == \"http://purchaseUrl.net\");\n            REQUIRE(frenchLocalization.Get<Localization::InstallationNotes>() == \"Installation Notes\");\n            REQUIRE(frenchLocalization.Get<Localization::Documentations>().size() == 1);\n            REQUIRE(frenchLocalization.Get<Localization::Documentations>().at(0).DocumentLabel == \"Document Label\");\n            REQUIRE(frenchLocalization.Get<Localization::Documentations>().at(0).DocumentUrl == \"http://documentUrl.net\");\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().size() == 1);\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Url == \"https://testIcon\");\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).FileType == IconFileTypeEnum::Png);\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Resolution == IconResolutionEnum::Square32);\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Theme == IconThemeEnum::Light);\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321\"));\n        }\n\n        void VerifyInstallers_AllFields(const AppInstaller::Manifest::Manifest& manifest)\n        {\n            REQUIRE(manifest.Installers.size() == 1);\n\n            ManifestInstaller actualInstaller = manifest.Installers.at(0);\n            REQUIRE(actualInstaller.Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\"));\n            REQUIRE(actualInstaller.Url == \"http://foobar.zip\");\n            REQUIRE(actualInstaller.Arch == Architecture::X86);\n            REQUIRE(actualInstaller.Locale == \"en-US\");\n            REQUIRE(actualInstaller.Platform.size() == 1);\n            REQUIRE(actualInstaller.Platform[0] == PlatformEnum::Desktop);\n            REQUIRE(actualInstaller.MinOSVersion == \"1078\");\n            REQUIRE(actualInstaller.BaseInstallerType == InstallerTypeEnum::Zip);\n            REQUIRE(actualInstaller.Scope == ScopeEnum::User);\n            REQUIRE(actualInstaller.InstallModes.size() == 1);\n            REQUIRE(actualInstaller.InstallModes.at(0) == InstallModeEnum::Interactive);\n            REQUIRE(actualInstaller.Switches.size() == 8);\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Silent) == \"/s\");\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::SilentWithProgress) == \"/s\");\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Interactive) == \"/i\");\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::InstallLocation) == \"C:\\\\Users\\\\User1\");\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Log) == \"/l\");\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Update) == \"/u\");\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Custom) == \"/custom\");\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Repair) == \"/repair\");\n            REQUIRE(actualInstaller.InstallerSuccessCodes.size() == 1);\n            REQUIRE(actualInstaller.InstallerSuccessCodes.at(0) == 0);\n            REQUIRE(actualInstaller.UpdateBehavior == UpdateBehaviorEnum::Deny);\n            REQUIRE(actualInstaller.Commands.at(0) == \"command1\");\n            REQUIRE(actualInstaller.Protocols.at(0) == \"protocol1\");\n            REQUIRE(actualInstaller.FileExtensions.at(0) == \".file-extension\");\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::WindowsFeature, \"feature1\"));\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::WindowsLibrary, \"library1\"));\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::Package, \"Foo.Baz\", \"2.0.0\"));\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::External, \"FooBarBaz\"));\n            REQUIRE(actualInstaller.PackageFamilyName == \"\");\n            REQUIRE(actualInstaller.ProductCode == \"5b6e0f8a-3bbf-4a17-aefd-024c2b3e075d\");\n            REQUIRE(actualInstaller.ReleaseDate == \"2021-01-01\");\n            REQUIRE(actualInstaller.InstallerAbortsTerminal);\n            REQUIRE(actualInstaller.InstallLocationRequired);\n            REQUIRE(actualInstaller.RequireExplicitUpgrade);\n            REQUIRE(actualInstaller.ElevationRequirement == ElevationRequirementEnum::ElevatesSelf);\n            REQUIRE(actualInstaller.UnsupportedOSArchitectures.size() == 1);\n            REQUIRE(actualInstaller.UnsupportedOSArchitectures.at(0) == Architecture::Arm);\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.size() == 1);\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).DisplayName == \"DisplayName\");\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).DisplayVersion == \"DisplayVersion\");\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).Publisher == \"Publisher\");\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).ProductCode == \"ProductCode\");\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).UpgradeCode == \"UpgradeCode\");\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).InstallerType == InstallerTypeEnum::Exe);\n            REQUIRE(actualInstaller.Markets.AllowedMarkets.size() == 1);\n            REQUIRE(actualInstaller.Markets.AllowedMarkets.at(0) == \"US\");\n            REQUIRE(actualInstaller.ExpectedReturnCodes.at(3).ReturnResponseEnum == ExpectedReturnCodeEnum::Custom);\n            REQUIRE(actualInstaller.ExpectedReturnCodes.at(3).ReturnResponseUrl == \"http://returnResponseUrl.net\");\n            REQUIRE(actualInstaller.NestedInstallerType == InstallerTypeEnum::Portable);\n            REQUIRE(actualInstaller.DisplayInstallWarnings);\n            REQUIRE(actualInstaller.UnsupportedArguments.size() == 1);\n            REQUIRE(actualInstaller.UnsupportedArguments.at(0) == UnsupportedArgumentEnum::Log);\n            REQUIRE(actualInstaller.NestedInstallerFiles.size() == 1);\n            REQUIRE(actualInstaller.NestedInstallerFiles.at(0).RelativeFilePath == \"test\\\\app.exe\");\n            REQUIRE(actualInstaller.NestedInstallerFiles.at(0).PortableCommandAlias == \"test.exe\");\n            REQUIRE(actualInstaller.InstallationMetadata.DefaultInstallLocation == \"%TEMP%\\\\DefaultInstallLocation\");\n            REQUIRE(actualInstaller.InstallationMetadata.Files.size() == 1);\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).RelativeFilePath == \"test\\\\app.exe\");\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).FileType == InstalledFileTypeEnum::Launch);\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).FileSha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\"));\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).InvocationParameter == \"/parameter\");\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).DisplayName == \"test\");\n            REQUIRE(actualInstaller.DownloadCommandProhibited);\n            REQUIRE(actualInstaller.RepairBehavior == RepairBehaviorEnum::Uninstaller);\n            REQUIRE(actualInstaller.ArchiveBinariesDependOnPath);\n            REQUIRE(actualInstaller.AuthInfo.Type == AppInstaller::Authentication::AuthenticationType::MicrosoftEntraId);\n            REQUIRE(actualInstaller.AuthInfo.MicrosoftEntraIdInfo.has_value());\n            REQUIRE(actualInstaller.AuthInfo.MicrosoftEntraIdInfo->Resource == \"TestResource\");\n            REQUIRE(actualInstaller.AuthInfo.MicrosoftEntraIdInfo->Scope == \"TestScope\");\n        }\n    };\n}\n\nTEST_CASE(\"GetManifests_GoodResponse_V1_12\", \"[RestSource][Interface_1_12]\")\n{\n    GoodManifest_AllFields sampleManifest;\n    utility::string_t sample = sampleManifest.GetSampleManifest_AllFields();\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) };\n    Interface v1_12{ TestRestUriString, std::move(helper), {} };\n    std::vector<Manifest> manifests = v1_12.GetManifests(\"Foo.Bar\");\n    REQUIRE(manifests.size() == 1);\n\n    // Verify manifest is populated\n    Manifest& manifest = manifests[0];\n    REQUIRE(manifest.Id == \"Foo.Bar\");\n    REQUIRE(manifest.Version == \"3.0.0abc\");\n    REQUIRE(manifest.Moniker == \"FooBarMoniker\");\n    REQUIRE(manifest.Channel == \"\");\n    REQUIRE(manifest.ManifestVersion == AppInstaller::Manifest::ManifestVer{ \"1.12.0\" });\n    sampleManifest.VerifyLocalizations_AllFields(manifest);\n    sampleManifest.VerifyInstallers_AllFields(manifest);\n}\n"
  },
  {
    "path": "src/AppInstallerCLITests/RestInterface_1_4.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestRestRequestHandler.h\"\r\n#include <Rest/Schema/1_4/Interface.h>\r\n#include <Rest/Schema/IRestClient.h>\r\n#include <AppInstallerVersions.h>\r\n#include <AppInstallerErrors.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::Http;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Repository::Rest;\r\nusing namespace AppInstaller::Repository::Rest::Schema;\r\nusing namespace AppInstaller::Repository::Rest::Schema::V1_4;\r\n\r\nnamespace\r\n{\r\n    const std::string TestRestUriString = \"http://restsource.com/api\";\r\n\r\n    IRestClient::Information GetTestSourceInformation()\r\n    {\r\n        IRestClient::Information result;\r\n\r\n        result.RequiredPackageMatchFields.emplace_back(\"Market\");\r\n        result.RequiredQueryParameters.emplace_back(\"Market\");\r\n        result.UnsupportedPackageMatchFields.emplace_back(\"Moniker\");\r\n        result.UnsupportedQueryParameters.emplace_back(\"Channel\");\r\n\r\n        return result;\r\n    }\r\n\r\n    struct GoodManifest_AllFields\r\n    {\r\n        utility::string_t GetSampleManifest_AllFields()\r\n        {\r\n            return _XPLATSTR(\r\n                R\"delimiter(\r\n        {\r\n          \"Data\": {\r\n            \"PackageIdentifier\": \"Foo.Bar\",\r\n            \"Versions\": [\r\n              {\r\n                \"PackageVersion\": \"3.0.0abc\",\r\n                \"DefaultLocale\": {\r\n                  \"PackageLocale\": \"en-US\",\r\n                  \"Publisher\": \"Foo\",\r\n                  \"PublisherUrl\": \"http://publisher.net\",\r\n                  \"PublisherSupportUrl\": \"http://publisherSupport.net\",\r\n                  \"PrivacyUrl\": \"http://packagePrivacyUrl.net\",\r\n                  \"Author\": \"FooBar\",\r\n                  \"PackageName\": \"Bar\",\r\n                  \"PackageUrl\": \"http://packageUrl.net\",\r\n                  \"License\": \"Foo Bar License\",\r\n                  \"LicenseUrl\": \"http://licenseUrl.net\",\r\n                  \"Copyright\": \"Foo Bar Copyright\",\r\n                  \"CopyrightUrl\": \"http://copyrightUrl.net\",\r\n                  \"ShortDescription\": \"Foo bar is a foo bar.\",\r\n                  \"Description\": \"Foo bar is a placeholder.\",\r\n                  \"Tags\": [\r\n                    \"FooBar\",\r\n                    \"Foo\",\r\n                    \"Bar\"\r\n                  ],\r\n                  \"Moniker\": \"FooBarMoniker\",\r\n                  \"ReleaseNotes\": \"Default release notes\",\r\n                  \"ReleaseNotesUrl\": \"https://DefaultReleaseNotes.net\",\r\n                  \"Agreements\": [{\r\n                    \"AgreementLabel\": \"DefaultLabel\",\r\n                    \"Agreement\": \"DefaultText\",\r\n                    \"AgreementUrl\": \"https://DefaultAgreementUrl.net\"\r\n                  }],\r\n                  \"PurchaseUrl\": \"http://DefaultPurchaseUrl.net\",\r\n                  \"InstallationNotes\": \"Default Installation Notes\",\r\n                  \"Documentations\": [{\r\n                    \"DocumentLabel\": \"Default Document Label\",\r\n                    \"DocumentUrl\": \"http://DefaultDocumentUrl.net\"\r\n                  }]\r\n                },\r\n                \"Channel\": \"\",\r\n                \"Locales\": [\r\n                  {\r\n                    \"PackageLocale\": \"fr-Fr\",\r\n                    \"Publisher\": \"Foo French\",\r\n                    \"PublisherUrl\": \"http://publisher-fr.net\",\r\n                    \"PublisherSupportUrl\": \"http://publisherSupport-fr.net\",\r\n                    \"PrivacyUrl\": \"http://packagePrivacyUrl-fr.net\",\r\n                    \"Author\": \"FooBar French\",\r\n                    \"PackageName\": \"Bar\",\r\n                    \"PackageUrl\": \"http://packageUrl-fr.net\",\r\n                    \"License\": \"Foo Bar License\",\r\n                    \"LicenseUrl\": \"http://licenseUrl-fr.net\",\r\n                    \"Copyright\": \"Foo Bar Copyright\",\r\n                    \"CopyrightUrl\": \"http://copyrightUrl-fr.net\",\r\n                    \"ShortDescription\": \"Foo bar is a foo bar French.\",\r\n                    \"Description\": \"Foo bar is a placeholder French.\",\r\n                    \"Tags\": [\r\n                      \"FooBarFr\",\r\n                      \"FooFr\",\r\n                      \"BarFr\"\r\n                    ],\r\n                    \"ReleaseNotes\": \"Release notes\",\r\n                    \"ReleaseNotesUrl\": \"https://ReleaseNotes.net\",\r\n                    \"Agreements\": [{\r\n                      \"AgreementLabel\": \"Label\",\r\n                      \"Agreement\": \"Text\",\r\n                      \"AgreementUrl\": \"https://AgreementUrl.net\"\r\n                    }],\r\n                    \"PurchaseUrl\": \"http://purchaseUrl.net\",\r\n                    \"InstallationNotes\": \"Installation Notes\",\r\n                    \"Documentations\": [{\r\n                      \"DocumentLabel\": \"Document Label\",\r\n                      \"DocumentUrl\": \"http://documentUrl.net\"\r\n                    }]\r\n                  }\r\n                ],\r\n                \"Installers\": [\r\n                  {\r\n                    \"InstallerSha256\": \"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\",\r\n                    \"InstallerUrl\": \"http://foobar.zip\",\r\n                    \"Architecture\": \"x86\",\r\n                    \"InstallerLocale\": \"en-US\",\r\n                    \"Platform\": [\r\n                      \"Windows.Desktop\"\r\n                    ],\r\n                    \"MinimumOSVersion\": \"1078\",\r\n                    \"InstallerType\": \"zip\",\r\n                    \"Scope\": \"user\",\r\n                    \"InstallModes\": [\r\n                      \"interactive\"\r\n                    ],\r\n                    \"InstallerSwitches\": {\r\n                      \"Silent\": \"/s\",\r\n                      \"SilentWithProgress\": \"/s\",\r\n                      \"Interactive\": \"/i\",\r\n                      \"InstallLocation\": \"C:\\\\Users\\\\User1\",\r\n                      \"Log\": \"/l\",\r\n                      \"Upgrade\": \"/u\",\r\n                      \"Custom\": \"/custom\"\r\n                    },\r\n                    \"InstallerSuccessCodes\": [\r\n                      0\r\n                    ],\r\n                    \"UpgradeBehavior\": \"install\",\r\n                    \"Commands\": [\r\n                      \"command1\"\r\n                    ],\r\n                    \"Protocols\": [\r\n                       \"protocol1\"\r\n                    ],\r\n                    \"FileExtensions\": [\r\n                      \".file-extension\"\r\n                    ],\r\n                    \"Dependencies\": {\r\n                      \"WindowsFeatures\": [\r\n                        \"feature1\"\r\n                      ],\r\n                      \"WindowsLibraries\": [\r\n                        \"library1\"\r\n                      ],\r\n                      \"PackageDependencies\": [\r\n                        {\r\n                          \"PackageIdentifier\": \"Foo.Baz\",\r\n                          \"MinimumVersion\": \"2.0.0\"\r\n                        }\r\n                      ],\r\n                      \"ExternalDependencies\": [\r\n                        \"FooBarBaz\"\r\n                      ]\r\n                    },\r\n                    \"ProductCode\": \"5b6e0f8a-3bbf-4a17-aefd-024c2b3e075d\",\r\n                    \"ReleaseDate\": \"2021-01-01\",\r\n                    \"InstallerAbortsTerminal\": true,\r\n                    \"InstallLocationRequired\": true,\r\n                    \"RequireExplicitUpgrade\": true,\r\n                    \"UnsupportedOSArchitectures\": [ \"arm\" ],\r\n                    \"ElevationRequirement\": \"elevatesSelf\",\r\n                    \"AppsAndFeaturesEntries\": [{\r\n                      \"DisplayName\": \"DisplayName\",\r\n                      \"DisplayVersion\": \"DisplayVersion\",\r\n                      \"Publisher\": \"Publisher\",\r\n                      \"ProductCode\": \"ProductCode\",\r\n                      \"UpgradeCode\": \"UpgradeCode\",\r\n                      \"InstallerType\": \"exe\"\r\n                    }],\r\n                    \"Markets\" : {\r\n                      \"AllowedMarkets\": [ \"US\" ]\r\n                    },\r\n                    \"ExpectedReturnCodes\": [{\r\n                      \"InstallerReturnCode\": 3,\r\n                      \"ReturnResponse\": \"custom\",\r\n                      \"ReturnResponseUrl\": \"http://returnResponseUrl.net\"\r\n                    }],\r\n                    \"NestedInstallerType\": \"portable\",\r\n                    \"DisplayInstallWarnings\": true,\r\n                    \"UnsupportedArguments\": [ \"log\" ],\r\n                    \"NestedInstallerFiles\": [{\r\n                      \"RelativeFilePath\": \"test\\\\app.exe\",\r\n                      \"PortableCommandAlias\": \"test.exe\"\r\n                    }],\r\n                    \"InstallationMetadata\": {\r\n                      \"DefaultInstallLocation\": \"%TEMP%\\\\DefaultInstallLocation\",\r\n                      \"Files\": [{\r\n                        \"RelativeFilePath\": \"test\\\\app.exe\",\r\n                        \"FileSha256\": \"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\",\r\n                        \"FileType\": \"launch\",\r\n                        \"InvocationParameter\": \"/parameter\",\r\n                        \"DisplayName\": \"test\"\r\n                      }]\r\n                    }\r\n                  }\r\n                ]\r\n              }\r\n            ]\r\n          },\r\n          \"ContinuationToken\": \"abcd\"\r\n        })delimiter\");\r\n        }\r\n\r\n        void VerifyLocalizations_AllFields(const Manifest& manifest)\r\n        {\r\n            REQUIRE(manifest.DefaultLocalization.Locale == \"en-US\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Publisher>() == \"Foo\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PublisherUrl>() == \"http://publisher.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PublisherSupportUrl>() == \"http://publisherSupport.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PrivacyUrl>() == \"http://packagePrivacyUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Author>() == \"FooBar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageName>() == \"Bar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageUrl>() == \"http://packageUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::License>() == \"Foo Bar License\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::LicenseUrl>() == \"http://licenseUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Copyright>() == \"Foo Bar Copyright\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::CopyrightUrl>() == \"http://copyrightUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ShortDescription>() == \"Foo bar is a foo bar.\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Description>() == \"Foo bar is a placeholder.\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().size() == 3);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(0) == \"FooBar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(1) == \"Foo\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(2) == \"Bar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ReleaseNotes>() == \"Default release notes\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ReleaseNotesUrl>() == \"https://DefaultReleaseNotes.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().size() == 1);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).Label == \"DefaultLabel\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).AgreementText == \"DefaultText\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).AgreementUrl == \"https://DefaultAgreementUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PurchaseUrl>() == \"http://DefaultPurchaseUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::InstallationNotes>() == \"Default Installation Notes\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().size() == 1);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().at(0).DocumentLabel == \"Default Document Label\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().at(0).DocumentUrl == \"http://DefaultDocumentUrl.net\");\r\n\r\n            REQUIRE(manifest.Localizations.size() == 1);\r\n            ManifestLocalization frenchLocalization = manifest.Localizations.at(0);\r\n            REQUIRE(frenchLocalization.Locale == \"fr-Fr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Publisher>() == \"Foo French\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PublisherUrl>() == \"http://publisher-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PublisherSupportUrl>() == \"http://publisherSupport-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PrivacyUrl>() == \"http://packagePrivacyUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Author>() == \"FooBar French\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PackageName>() == \"Bar\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PackageUrl>() == \"http://packageUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::License>() == \"Foo Bar License\");\r\n            REQUIRE(frenchLocalization.Get<Localization::LicenseUrl>() == \"http://licenseUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Copyright>() == \"Foo Bar Copyright\");\r\n            REQUIRE(frenchLocalization.Get<Localization::CopyrightUrl>() == \"http://copyrightUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::ShortDescription>() == \"Foo bar is a foo bar French.\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Description>() == \"Foo bar is a placeholder French.\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().size() == 3);\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(0) == \"FooBarFr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(1) == \"FooFr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(2) == \"BarFr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::ReleaseNotes>() == \"Release notes\");\r\n            REQUIRE(frenchLocalization.Get<Localization::ReleaseNotesUrl>() == \"https://ReleaseNotes.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().size() == 1);\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).Label == \"Label\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).AgreementText == \"Text\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).AgreementUrl == \"https://AgreementUrl.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PurchaseUrl>() == \"http://purchaseUrl.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::InstallationNotes>() == \"Installation Notes\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Documentations>().size() == 1);\r\n            REQUIRE(frenchLocalization.Get<Localization::Documentations>().at(0).DocumentLabel == \"Document Label\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Documentations>().at(0).DocumentUrl == \"http://documentUrl.net\");\r\n        }\r\n\r\n        void VerifyInstallers_AllFields(const Manifest& manifest)\r\n        {\r\n            REQUIRE(manifest.Installers.size() == 1);\r\n\r\n            ManifestInstaller actualInstaller = manifest.Installers.at(0);\r\n            REQUIRE(actualInstaller.Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\"));\r\n            REQUIRE(actualInstaller.Url == \"http://foobar.zip\");\r\n            REQUIRE(actualInstaller.Arch == Architecture::X86);\r\n            REQUIRE(actualInstaller.Locale == \"en-US\");\r\n            REQUIRE(actualInstaller.Platform.size() == 1);\r\n            REQUIRE(actualInstaller.Platform[0] == PlatformEnum::Desktop);\r\n            REQUIRE(actualInstaller.MinOSVersion == \"1078\");\r\n            REQUIRE(actualInstaller.BaseInstallerType == InstallerTypeEnum::Zip);\r\n            REQUIRE(actualInstaller.Scope == ScopeEnum::User);\r\n            REQUIRE(actualInstaller.InstallModes.size() == 1);\r\n            REQUIRE(actualInstaller.InstallModes.at(0) == InstallModeEnum::Interactive);\r\n            REQUIRE(actualInstaller.Switches.size() == 7);\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Silent) == \"/s\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::SilentWithProgress) == \"/s\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Interactive) == \"/i\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::InstallLocation) == \"C:\\\\Users\\\\User1\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Log) == \"/l\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Update) == \"/u\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Custom) == \"/custom\");\r\n            REQUIRE(actualInstaller.InstallerSuccessCodes.size() == 1);\r\n            REQUIRE(actualInstaller.InstallerSuccessCodes.at(0) == 0);\r\n            REQUIRE(actualInstaller.UpdateBehavior == UpdateBehaviorEnum::Install);\r\n            REQUIRE(actualInstaller.Commands.at(0) == \"command1\");\r\n            REQUIRE(actualInstaller.Protocols.at(0) == \"protocol1\");\r\n            REQUIRE(actualInstaller.FileExtensions.at(0) == \".file-extension\");\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::WindowsFeature, \"feature1\"));\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::WindowsLibrary, \"library1\"));\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::Package, \"Foo.Baz\", \"2.0.0\"));\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::External, \"FooBarBaz\"));\r\n            REQUIRE(actualInstaller.PackageFamilyName == \"\");\r\n            REQUIRE(actualInstaller.ProductCode == \"5b6e0f8a-3bbf-4a17-aefd-024c2b3e075d\");\r\n            REQUIRE(actualInstaller.ReleaseDate == \"2021-01-01\");\r\n            REQUIRE(actualInstaller.InstallerAbortsTerminal);\r\n            REQUIRE(actualInstaller.InstallLocationRequired);\r\n            REQUIRE(actualInstaller.RequireExplicitUpgrade);\r\n            REQUIRE(actualInstaller.ElevationRequirement == ElevationRequirementEnum::ElevatesSelf);\r\n            REQUIRE(actualInstaller.UnsupportedOSArchitectures.size() == 1);\r\n            REQUIRE(actualInstaller.UnsupportedOSArchitectures.at(0) == Architecture::Arm);\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.size() == 1);\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).DisplayName == \"DisplayName\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).DisplayVersion == \"DisplayVersion\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).Publisher == \"Publisher\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).ProductCode == \"ProductCode\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).UpgradeCode == \"UpgradeCode\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).InstallerType == InstallerTypeEnum::Exe);\r\n            REQUIRE(actualInstaller.Markets.AllowedMarkets.size() == 1);\r\n            REQUIRE(actualInstaller.Markets.AllowedMarkets.at(0) == \"US\");\r\n            REQUIRE(actualInstaller.ExpectedReturnCodes.at(3).ReturnResponseEnum == ExpectedReturnCodeEnum::Custom);\r\n            REQUIRE(actualInstaller.ExpectedReturnCodes.at(3).ReturnResponseUrl == \"http://returnResponseUrl.net\");\r\n            REQUIRE(actualInstaller.NestedInstallerType == InstallerTypeEnum::Portable);\r\n            REQUIRE(actualInstaller.DisplayInstallWarnings);\r\n            REQUIRE(actualInstaller.UnsupportedArguments.size() == 1);\r\n            REQUIRE(actualInstaller.UnsupportedArguments.at(0) == UnsupportedArgumentEnum::Log);\r\n            REQUIRE(actualInstaller.NestedInstallerFiles.size() == 1);\r\n            REQUIRE(actualInstaller.NestedInstallerFiles.at(0).RelativeFilePath == \"test\\\\app.exe\");\r\n            REQUIRE(actualInstaller.NestedInstallerFiles.at(0).PortableCommandAlias == \"test.exe\");\r\n            REQUIRE(actualInstaller.InstallationMetadata.DefaultInstallLocation == \"%TEMP%\\\\DefaultInstallLocation\");\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.size() == 1);\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).RelativeFilePath == \"test\\\\app.exe\");\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).FileType == InstalledFileTypeEnum::Launch);\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).FileSha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\"));\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).InvocationParameter == \"/parameter\");\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).DisplayName == \"test\");\r\n        }\r\n    };\r\n}\r\n\r\nTEST_CASE(\"GetManifests_GoodResponse_V1_4\", \"[RestSource][Interface_1_4]\")\r\n{\r\n    GoodManifest_AllFields sampleManifest;\r\n    utility::string_t sample = sampleManifest.GetSampleManifest_AllFields();\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) };\r\n    Interface v1_4{ TestRestUriString, std::move(helper), {} };\r\n    std::vector<Manifest> manifests = v1_4.GetManifests(\"Foo.Bar\");\r\n    REQUIRE(manifests.size() == 1);\r\n\r\n    // Verify manifest is populated\r\n    Manifest& manifest = manifests[0];\r\n    REQUIRE(manifest.Id == \"Foo.Bar\");\r\n    REQUIRE(manifest.Version == \"3.0.0abc\");\r\n    REQUIRE(manifest.Moniker == \"FooBarMoniker\");\r\n    REQUIRE(manifest.Channel == \"\");\r\n    REQUIRE(manifest.ManifestVersion == AppInstaller::Manifest::ManifestVer{ \"1.4.0\" });\r\n    sampleManifest.VerifyLocalizations_AllFields(manifest);\r\n    sampleManifest.VerifyInstallers_AllFields(manifest);\r\n}\r\n\r\nTEST_CASE(\"Search_GoodResponse_V1_4\", \"[RestSource][Interface_1_4]\")\r\n{\r\n    utility::string_t sample = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : [{\r\n              \"PackageIdentifier\": \"git.package\",\r\n              \"PackageName\": \"package\",\r\n              \"Publisher\": \"git\",\r\n              \"Versions\": [{\r\n                \"PackageVersion\": \"1.0.0\",\r\n                \"PackageFamilyNames\": [\r\n                    \"pfn1\"\r\n                ],\r\n                \"ProductCodes\": [\r\n                    \"pc1\"\r\n                ],\r\n                \"UpgradeCodes\": [\r\n                    \"upgradeCode\"\r\n                ],\r\n                \"AppsAndFeaturesEntryVersions\": [\r\n                    \"2.0\",\r\n                    \"1.0\"\r\n                ]\r\n              }]\r\n            }]\r\n        })delimiter\");\r\n\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) };\r\n    Interface v1_4{ TestRestUriString, std::move(helper), {} };\r\n    Schema::IRestClient::SearchResult searchResponse = v1_4.Search({});\r\n    REQUIRE(searchResponse.Matches.size() == 1);\r\n    Schema::IRestClient::Package package = searchResponse.Matches.at(0);\r\n    REQUIRE(package.PackageInformation.PackageIdentifier.compare(\"git.package\") == 0);\r\n    REQUIRE(package.PackageInformation.Publisher.compare(\"git\") == 0);\r\n    REQUIRE(package.PackageInformation.PackageName.compare(\"package\") == 0);\r\n    REQUIRE(package.Versions.size() == 1);\r\n    REQUIRE(package.Versions.at(0).VersionAndChannel.GetVersion().ToString().compare(\"1.0.0\") == 0);\r\n    REQUIRE(package.Versions.at(0).PackageFamilyNames.size() == 1);\r\n    REQUIRE(package.Versions.at(0).PackageFamilyNames.at(0) == \"pfn1\");\r\n    REQUIRE(package.Versions.at(0).ProductCodes.size() == 1);\r\n    REQUIRE(package.Versions.at(0).ProductCodes.at(0) == \"pc1\");\r\n    REQUIRE(package.Versions.at(0).UpgradeCodes.size() == 1);\r\n    REQUIRE(package.Versions.at(0).UpgradeCodes.at(0) == \"upgradeCode\");\r\n    REQUIRE(package.Versions.at(0).ArpVersions.size() == 2);\r\n    REQUIRE(package.Versions.at(0).ArpVersions.at(0).ToString() == \"1.0\");\r\n    REQUIRE(package.Versions.at(0).ArpVersions.at(1).ToString() == \"2.0\");\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/RestInterface_1_5.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestRestRequestHandler.h\"\r\n#include <Rest/Schema/1_5/Interface.h>\r\n#include <Rest/Schema/IRestClient.h>\r\n#include <AppInstallerVersions.h>\r\n#include <AppInstallerErrors.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::Http;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Repository::Rest;\r\nusing namespace AppInstaller::Repository::Rest::Schema;\r\nusing namespace AppInstaller::Repository::Rest::Schema::V1_5;\r\n\r\nnamespace\r\n{\r\n    const std::string TestRestUriString = \"http://restsource.com/api\";\r\n\r\n    IRestClient::Information GetTestSourceInformation()\r\n    {\r\n        IRestClient::Information result;\r\n\r\n        result.RequiredPackageMatchFields.emplace_back(\"Market\");\r\n        result.RequiredQueryParameters.emplace_back(\"Market\");\r\n        result.UnsupportedPackageMatchFields.emplace_back(\"Moniker\");\r\n        result.UnsupportedQueryParameters.emplace_back(\"Channel\");\r\n\r\n        return result;\r\n    }\r\n\r\n    struct GoodManifest_AllFields\r\n    {\r\n        utility::string_t GetSampleManifest_AllFields()\r\n        {\r\n            return _XPLATSTR(\r\n                R\"delimiter(\r\n        {\r\n          \"Data\": {\r\n            \"PackageIdentifier\": \"Foo.Bar\",\r\n            \"Versions\": [\r\n              {\r\n                \"PackageVersion\": \"3.0.0abc\",\r\n                \"DefaultLocale\": {\r\n                  \"PackageLocale\": \"en-US\",\r\n                  \"Publisher\": \"Foo\",\r\n                  \"PublisherUrl\": \"http://publisher.net\",\r\n                  \"PublisherSupportUrl\": \"http://publisherSupport.net\",\r\n                  \"PrivacyUrl\": \"http://packagePrivacyUrl.net\",\r\n                  \"Author\": \"FooBar\",\r\n                  \"PackageName\": \"Bar\",\r\n                  \"PackageUrl\": \"http://packageUrl.net\",\r\n                  \"License\": \"Foo Bar License\",\r\n                  \"LicenseUrl\": \"http://licenseUrl.net\",\r\n                  \"Copyright\": \"Foo Bar Copyright\",\r\n                  \"CopyrightUrl\": \"http://copyrightUrl.net\",\r\n                  \"ShortDescription\": \"Foo bar is a foo bar.\",\r\n                  \"Description\": \"Foo bar is a placeholder.\",\r\n                  \"Tags\": [\r\n                    \"FooBar\",\r\n                    \"Foo\",\r\n                    \"Bar\"\r\n                  ],\r\n                  \"Moniker\": \"FooBarMoniker\",\r\n                  \"ReleaseNotes\": \"Default release notes\",\r\n                  \"ReleaseNotesUrl\": \"https://DefaultReleaseNotes.net\",\r\n                  \"Agreements\": [{\r\n                    \"AgreementLabel\": \"DefaultLabel\",\r\n                    \"Agreement\": \"DefaultText\",\r\n                    \"AgreementUrl\": \"https://DefaultAgreementUrl.net\"\r\n                  }],\r\n                  \"PurchaseUrl\": \"http://DefaultPurchaseUrl.net\",\r\n                  \"InstallationNotes\": \"Default Installation Notes\",\r\n                  \"Documentations\": [{\r\n                    \"DocumentLabel\": \"Default Document Label\",\r\n                    \"DocumentUrl\": \"http://DefaultDocumentUrl.net\"\r\n                  }],\r\n                  \"Icons\": [{\r\n                    \"IconUrl\": \"https://DefaultTestIcon\",\r\n                    \"IconFileType\": \"ico\",\r\n                    \"IconResolution\": \"custom\",\r\n                    \"IconTheme\": \"default\",\r\n                    \"IconSha256\": \"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\"\r\n                  }]\r\n                },\r\n                \"Channel\": \"\",\r\n                \"Locales\": [\r\n                  {\r\n                    \"PackageLocale\": \"fr-Fr\",\r\n                    \"Publisher\": \"Foo French\",\r\n                    \"PublisherUrl\": \"http://publisher-fr.net\",\r\n                    \"PublisherSupportUrl\": \"http://publisherSupport-fr.net\",\r\n                    \"PrivacyUrl\": \"http://packagePrivacyUrl-fr.net\",\r\n                    \"Author\": \"FooBar French\",\r\n                    \"PackageName\": \"Bar\",\r\n                    \"PackageUrl\": \"http://packageUrl-fr.net\",\r\n                    \"License\": \"Foo Bar License\",\r\n                    \"LicenseUrl\": \"http://licenseUrl-fr.net\",\r\n                    \"Copyright\": \"Foo Bar Copyright\",\r\n                    \"CopyrightUrl\": \"http://copyrightUrl-fr.net\",\r\n                    \"ShortDescription\": \"Foo bar is a foo bar French.\",\r\n                    \"Description\": \"Foo bar is a placeholder French.\",\r\n                    \"Tags\": [\r\n                      \"FooBarFr\",\r\n                      \"FooFr\",\r\n                      \"BarFr\"\r\n                    ],\r\n                    \"ReleaseNotes\": \"Release notes\",\r\n                    \"ReleaseNotesUrl\": \"https://ReleaseNotes.net\",\r\n                    \"Agreements\": [{\r\n                      \"AgreementLabel\": \"Label\",\r\n                      \"Agreement\": \"Text\",\r\n                      \"AgreementUrl\": \"https://AgreementUrl.net\"\r\n                    }],\r\n                    \"PurchaseUrl\": \"http://purchaseUrl.net\",\r\n                    \"InstallationNotes\": \"Installation Notes\",\r\n                    \"Documentations\": [{\r\n                      \"DocumentLabel\": \"Document Label\",\r\n                      \"DocumentUrl\": \"http://documentUrl.net\"\r\n                    }],\r\n                    \"Icons\": [{\r\n                      \"IconUrl\": \"https://testIcon\",\r\n                      \"IconFileType\": \"png\",\r\n                      \"IconResolution\": \"32x32\",\r\n                      \"IconTheme\": \"light\",\r\n                      \"IconSha256\": \"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321\"\r\n                    }]\r\n                  }\r\n                ],)delimiter\") _XPLATSTR(R\"delimiter(\r\n                \"Installers\": [\r\n                  {\r\n                    \"InstallerSha256\": \"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\",\r\n                    \"InstallerUrl\": \"http://foobar.zip\",\r\n                    \"Architecture\": \"x86\",\r\n                    \"InstallerLocale\": \"en-US\",\r\n                    \"Platform\": [\r\n                      \"Windows.Desktop\"\r\n                    ],\r\n                    \"MinimumOSVersion\": \"1078\",\r\n                    \"InstallerType\": \"zip\",\r\n                    \"Scope\": \"user\",\r\n                    \"InstallModes\": [\r\n                      \"interactive\"\r\n                    ],\r\n                    \"InstallerSwitches\": {\r\n                      \"Silent\": \"/s\",\r\n                      \"SilentWithProgress\": \"/s\",\r\n                      \"Interactive\": \"/i\",\r\n                      \"InstallLocation\": \"C:\\\\Users\\\\User1\",\r\n                      \"Log\": \"/l\",\r\n                      \"Upgrade\": \"/u\",\r\n                      \"Custom\": \"/custom\"\r\n                    },\r\n                    \"InstallerSuccessCodes\": [\r\n                      0\r\n                    ],\r\n                    \"UpgradeBehavior\": \"install\",\r\n                    \"Commands\": [\r\n                      \"command1\"\r\n                    ],\r\n                    \"Protocols\": [\r\n                       \"protocol1\"\r\n                    ],\r\n                    \"FileExtensions\": [\r\n                      \".file-extension\"\r\n                    ],\r\n                    \"Dependencies\": {\r\n                      \"WindowsFeatures\": [\r\n                        \"feature1\"\r\n                      ],\r\n                      \"WindowsLibraries\": [\r\n                        \"library1\"\r\n                      ],\r\n                      \"PackageDependencies\": [\r\n                        {\r\n                          \"PackageIdentifier\": \"Foo.Baz\",\r\n                          \"MinimumVersion\": \"2.0.0\"\r\n                        }\r\n                      ],\r\n                      \"ExternalDependencies\": [\r\n                        \"FooBarBaz\"\r\n                      ]\r\n                    },\r\n                    \"ProductCode\": \"5b6e0f8a-3bbf-4a17-aefd-024c2b3e075d\",\r\n                    \"ReleaseDate\": \"2021-01-01\",\r\n                    \"InstallerAbortsTerminal\": true,\r\n                    \"InstallLocationRequired\": true,\r\n                    \"RequireExplicitUpgrade\": true,\r\n                    \"UnsupportedOSArchitectures\": [ \"arm\" ],\r\n                    \"ElevationRequirement\": \"elevatesSelf\",\r\n                    \"AppsAndFeaturesEntries\": [{\r\n                      \"DisplayName\": \"DisplayName\",\r\n                      \"DisplayVersion\": \"DisplayVersion\",\r\n                      \"Publisher\": \"Publisher\",\r\n                      \"ProductCode\": \"ProductCode\",\r\n                      \"UpgradeCode\": \"UpgradeCode\",\r\n                      \"InstallerType\": \"exe\"\r\n                    }],\r\n                    \"Markets\" : {\r\n                      \"AllowedMarkets\": [ \"US\" ]\r\n                    },\r\n                    \"ExpectedReturnCodes\": [{\r\n                      \"InstallerReturnCode\": 3,\r\n                      \"ReturnResponse\": \"custom\",\r\n                      \"ReturnResponseUrl\": \"http://returnResponseUrl.net\"\r\n                    }],\r\n                    \"NestedInstallerType\": \"portable\",\r\n                    \"DisplayInstallWarnings\": true,\r\n                    \"UnsupportedArguments\": [ \"log\" ],\r\n                    \"NestedInstallerFiles\": [{\r\n                      \"RelativeFilePath\": \"test\\\\app.exe\",\r\n                      \"PortableCommandAlias\": \"test.exe\"\r\n                    }],\r\n                    \"InstallationMetadata\": {\r\n                      \"DefaultInstallLocation\": \"%TEMP%\\\\DefaultInstallLocation\",\r\n                      \"Files\": [{\r\n                        \"RelativeFilePath\": \"test\\\\app.exe\",\r\n                        \"FileSha256\": \"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\",\r\n                        \"FileType\": \"launch\",\r\n                        \"InvocationParameter\": \"/parameter\",\r\n                        \"DisplayName\": \"test\"\r\n                      }]\r\n                    }\r\n                  }\r\n                ]\r\n              }\r\n            ]\r\n          },\r\n          \"ContinuationToken\": \"abcd\"\r\n        })delimiter\");\r\n        }\r\n\r\n        void VerifyLocalizations_AllFields(const Manifest& manifest)\r\n        {\r\n            REQUIRE(manifest.DefaultLocalization.Locale == \"en-US\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Publisher>() == \"Foo\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PublisherUrl>() == \"http://publisher.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PublisherSupportUrl>() == \"http://publisherSupport.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PrivacyUrl>() == \"http://packagePrivacyUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Author>() == \"FooBar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageName>() == \"Bar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageUrl>() == \"http://packageUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::License>() == \"Foo Bar License\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::LicenseUrl>() == \"http://licenseUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Copyright>() == \"Foo Bar Copyright\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::CopyrightUrl>() == \"http://copyrightUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ShortDescription>() == \"Foo bar is a foo bar.\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Description>() == \"Foo bar is a placeholder.\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().size() == 3);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(0) == \"FooBar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(1) == \"Foo\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(2) == \"Bar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ReleaseNotes>() == \"Default release notes\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ReleaseNotesUrl>() == \"https://DefaultReleaseNotes.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().size() == 1);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).Label == \"DefaultLabel\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).AgreementText == \"DefaultText\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).AgreementUrl == \"https://DefaultAgreementUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PurchaseUrl>() == \"http://DefaultPurchaseUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::InstallationNotes>() == \"Default Installation Notes\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().size() == 1);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().at(0).DocumentLabel == \"Default Document Label\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().at(0).DocumentUrl == \"http://DefaultDocumentUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().size() == 1);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Url == \"https://DefaultTestIcon\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).FileType == IconFileTypeEnum::Ico);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Resolution == IconResolutionEnum::Custom);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Theme == IconThemeEnum::Default);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\"));\r\n\r\n            REQUIRE(manifest.Localizations.size() == 1);\r\n            ManifestLocalization frenchLocalization = manifest.Localizations.at(0);\r\n            REQUIRE(frenchLocalization.Locale == \"fr-Fr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Publisher>() == \"Foo French\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PublisherUrl>() == \"http://publisher-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PublisherSupportUrl>() == \"http://publisherSupport-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PrivacyUrl>() == \"http://packagePrivacyUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Author>() == \"FooBar French\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PackageName>() == \"Bar\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PackageUrl>() == \"http://packageUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::License>() == \"Foo Bar License\");\r\n            REQUIRE(frenchLocalization.Get<Localization::LicenseUrl>() == \"http://licenseUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Copyright>() == \"Foo Bar Copyright\");\r\n            REQUIRE(frenchLocalization.Get<Localization::CopyrightUrl>() == \"http://copyrightUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::ShortDescription>() == \"Foo bar is a foo bar French.\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Description>() == \"Foo bar is a placeholder French.\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().size() == 3);\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(0) == \"FooBarFr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(1) == \"FooFr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(2) == \"BarFr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::ReleaseNotes>() == \"Release notes\");\r\n            REQUIRE(frenchLocalization.Get<Localization::ReleaseNotesUrl>() == \"https://ReleaseNotes.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().size() == 1);\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).Label == \"Label\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).AgreementText == \"Text\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).AgreementUrl == \"https://AgreementUrl.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PurchaseUrl>() == \"http://purchaseUrl.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::InstallationNotes>() == \"Installation Notes\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Documentations>().size() == 1);\r\n            REQUIRE(frenchLocalization.Get<Localization::Documentations>().at(0).DocumentLabel == \"Document Label\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Documentations>().at(0).DocumentUrl == \"http://documentUrl.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().size() == 1);\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Url == \"https://testIcon\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).FileType == IconFileTypeEnum::Png);\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Resolution == IconResolutionEnum::Square32);\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Theme == IconThemeEnum::Light);\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321\"));\r\n        }\r\n\r\n        void VerifyInstallers_AllFields(const Manifest& manifest)\r\n        {\r\n            REQUIRE(manifest.Installers.size() == 1);\r\n\r\n            ManifestInstaller actualInstaller = manifest.Installers.at(0);\r\n            REQUIRE(actualInstaller.Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\"));\r\n            REQUIRE(actualInstaller.Url == \"http://foobar.zip\");\r\n            REQUIRE(actualInstaller.Arch == Architecture::X86);\r\n            REQUIRE(actualInstaller.Locale == \"en-US\");\r\n            REQUIRE(actualInstaller.Platform.size() == 1);\r\n            REQUIRE(actualInstaller.Platform[0] == PlatformEnum::Desktop);\r\n            REQUIRE(actualInstaller.MinOSVersion == \"1078\");\r\n            REQUIRE(actualInstaller.BaseInstallerType == InstallerTypeEnum::Zip);\r\n            REQUIRE(actualInstaller.Scope == ScopeEnum::User);\r\n            REQUIRE(actualInstaller.InstallModes.size() == 1);\r\n            REQUIRE(actualInstaller.InstallModes.at(0) == InstallModeEnum::Interactive);\r\n            REQUIRE(actualInstaller.Switches.size() == 7);\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Silent) == \"/s\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::SilentWithProgress) == \"/s\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Interactive) == \"/i\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::InstallLocation) == \"C:\\\\Users\\\\User1\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Log) == \"/l\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Update) == \"/u\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Custom) == \"/custom\");\r\n            REQUIRE(actualInstaller.InstallerSuccessCodes.size() == 1);\r\n            REQUIRE(actualInstaller.InstallerSuccessCodes.at(0) == 0);\r\n            REQUIRE(actualInstaller.UpdateBehavior == UpdateBehaviorEnum::Install);\r\n            REQUIRE(actualInstaller.Commands.at(0) == \"command1\");\r\n            REQUIRE(actualInstaller.Protocols.at(0) == \"protocol1\");\r\n            REQUIRE(actualInstaller.FileExtensions.at(0) == \".file-extension\");\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::WindowsFeature, \"feature1\"));\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::WindowsLibrary, \"library1\"));\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::Package, \"Foo.Baz\", \"2.0.0\"));\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::External, \"FooBarBaz\"));\r\n            REQUIRE(actualInstaller.PackageFamilyName == \"\");\r\n            REQUIRE(actualInstaller.ProductCode == \"5b6e0f8a-3bbf-4a17-aefd-024c2b3e075d\");\r\n            REQUIRE(actualInstaller.ReleaseDate == \"2021-01-01\");\r\n            REQUIRE(actualInstaller.InstallerAbortsTerminal);\r\n            REQUIRE(actualInstaller.InstallLocationRequired);\r\n            REQUIRE(actualInstaller.RequireExplicitUpgrade);\r\n            REQUIRE(actualInstaller.ElevationRequirement == ElevationRequirementEnum::ElevatesSelf);\r\n            REQUIRE(actualInstaller.UnsupportedOSArchitectures.size() == 1);\r\n            REQUIRE(actualInstaller.UnsupportedOSArchitectures.at(0) == Architecture::Arm);\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.size() == 1);\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).DisplayName == \"DisplayName\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).DisplayVersion == \"DisplayVersion\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).Publisher == \"Publisher\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).ProductCode == \"ProductCode\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).UpgradeCode == \"UpgradeCode\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).InstallerType == InstallerTypeEnum::Exe);\r\n            REQUIRE(actualInstaller.Markets.AllowedMarkets.size() == 1);\r\n            REQUIRE(actualInstaller.Markets.AllowedMarkets.at(0) == \"US\");\r\n            REQUIRE(actualInstaller.ExpectedReturnCodes.at(3).ReturnResponseEnum == ExpectedReturnCodeEnum::Custom);\r\n            REQUIRE(actualInstaller.ExpectedReturnCodes.at(3).ReturnResponseUrl == \"http://returnResponseUrl.net\");\r\n            REQUIRE(actualInstaller.NestedInstallerType == InstallerTypeEnum::Portable);\r\n            REQUIRE(actualInstaller.DisplayInstallWarnings);\r\n            REQUIRE(actualInstaller.UnsupportedArguments.size() == 1);\r\n            REQUIRE(actualInstaller.UnsupportedArguments.at(0) == UnsupportedArgumentEnum::Log);\r\n            REQUIRE(actualInstaller.NestedInstallerFiles.size() == 1);\r\n            REQUIRE(actualInstaller.NestedInstallerFiles.at(0).RelativeFilePath == \"test\\\\app.exe\");\r\n            REQUIRE(actualInstaller.NestedInstallerFiles.at(0).PortableCommandAlias == \"test.exe\");\r\n            REQUIRE(actualInstaller.InstallationMetadata.DefaultInstallLocation == \"%TEMP%\\\\DefaultInstallLocation\");\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.size() == 1);\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).RelativeFilePath == \"test\\\\app.exe\");\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).FileType == InstalledFileTypeEnum::Launch);\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).FileSha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\"));\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).InvocationParameter == \"/parameter\");\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).DisplayName == \"test\");\r\n        }\r\n    };\r\n}\r\n\r\nTEST_CASE(\"GetManifests_GoodResponse_V1_5\", \"[RestSource][Interface_1_5]\")\r\n{\r\n    GoodManifest_AllFields sampleManifest;\r\n    utility::string_t sample = sampleManifest.GetSampleManifest_AllFields();\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) };\r\n    Interface v1_5{ TestRestUriString, std::move(helper), {} };\r\n    std::vector<Manifest> manifests = v1_5.GetManifests(\"Foo.Bar\");\r\n    REQUIRE(manifests.size() == 1);\r\n\r\n    // Verify manifest is populated\r\n    Manifest& manifest = manifests[0];\r\n    REQUIRE(manifest.Id == \"Foo.Bar\");\r\n    REQUIRE(manifest.Version == \"3.0.0abc\");\r\n    REQUIRE(manifest.Moniker == \"FooBarMoniker\");\r\n    REQUIRE(manifest.Channel == \"\");\r\n    REQUIRE(manifest.ManifestVersion == AppInstaller::Manifest::ManifestVer{ \"1.5.0\" });\r\n    sampleManifest.VerifyLocalizations_AllFields(manifest);\r\n    sampleManifest.VerifyInstallers_AllFields(manifest);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/RestInterface_1_6.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestRestRequestHandler.h\"\r\n#include <Rest/Schema/1_6/Interface.h>\r\n#include <Rest/Schema/IRestClient.h>\r\n#include <AppInstallerVersions.h>\r\n#include <AppInstallerErrors.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::Http;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Repository::Rest;\r\nusing namespace AppInstaller::Repository::Rest::Schema;\r\nusing namespace AppInstaller::Repository::Rest::Schema::V1_6;\r\n\r\nnamespace\r\n{\r\n    const std::string TestRestUriString = \"http://restsource.com/api\";\r\n\r\n    IRestClient::Information GetTestSourceInformation()\r\n    {\r\n        IRestClient::Information result;\r\n\r\n        result.RequiredPackageMatchFields.emplace_back(\"Market\");\r\n        result.RequiredQueryParameters.emplace_back(\"Market\");\r\n        result.UnsupportedPackageMatchFields.emplace_back(\"Moniker\");\r\n        result.UnsupportedQueryParameters.emplace_back(\"Channel\");\r\n\r\n        return result;\r\n    }\r\n\r\n    struct GoodManifest_AllFields\r\n    {\r\n        utility::string_t GetSampleManifest_AllFields()\r\n        {\r\n            return _XPLATSTR(\r\n                R\"delimiter(\r\n        {\r\n          \"Data\": {\r\n            \"PackageIdentifier\": \"Foo.Bar\",\r\n            \"Versions\": [\r\n              {\r\n                \"PackageVersion\": \"3.0.0abc\",\r\n                \"DefaultLocale\": {\r\n                  \"PackageLocale\": \"en-US\",\r\n                  \"Publisher\": \"Foo\",\r\n                  \"PublisherUrl\": \"http://publisher.net\",\r\n                  \"PublisherSupportUrl\": \"http://publisherSupport.net\",\r\n                  \"PrivacyUrl\": \"http://packagePrivacyUrl.net\",\r\n                  \"Author\": \"FooBar\",\r\n                  \"PackageName\": \"Bar\",\r\n                  \"PackageUrl\": \"http://packageUrl.net\",\r\n                  \"License\": \"Foo Bar License\",\r\n                  \"LicenseUrl\": \"http://licenseUrl.net\",\r\n                  \"Copyright\": \"Foo Bar Copyright\",\r\n                  \"CopyrightUrl\": \"http://copyrightUrl.net\",\r\n                  \"ShortDescription\": \"Foo bar is a foo bar.\",\r\n                  \"Description\": \"Foo bar is a placeholder.\",\r\n                  \"Tags\": [\r\n                    \"FooBar\",\r\n                    \"Foo\",\r\n                    \"Bar\"\r\n                  ],\r\n                  \"Moniker\": \"FooBarMoniker\",\r\n                  \"ReleaseNotes\": \"Default release notes\",\r\n                  \"ReleaseNotesUrl\": \"https://DefaultReleaseNotes.net\",\r\n                  \"Agreements\": [{\r\n                    \"AgreementLabel\": \"DefaultLabel\",\r\n                    \"Agreement\": \"DefaultText\",\r\n                    \"AgreementUrl\": \"https://DefaultAgreementUrl.net\"\r\n                  }],\r\n                  \"PurchaseUrl\": \"http://DefaultPurchaseUrl.net\",\r\n                  \"InstallationNotes\": \"Default Installation Notes\",\r\n                  \"Documentations\": [{\r\n                    \"DocumentLabel\": \"Default Document Label\",\r\n                    \"DocumentUrl\": \"http://DefaultDocumentUrl.net\"\r\n                  }],\r\n                  \"Icons\": [{\r\n                    \"IconUrl\": \"https://DefaultTestIcon\",\r\n                    \"IconFileType\": \"ico\",\r\n                    \"IconResolution\": \"custom\",\r\n                    \"IconTheme\": \"default\",\r\n                    \"IconSha256\": \"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\"\r\n                  }]\r\n                },\r\n                \"Channel\": \"\",\r\n                \"Locales\": [\r\n                  {\r\n                    \"PackageLocale\": \"fr-Fr\",\r\n                    \"Publisher\": \"Foo French\",\r\n                    \"PublisherUrl\": \"http://publisher-fr.net\",\r\n                    \"PublisherSupportUrl\": \"http://publisherSupport-fr.net\",\r\n                    \"PrivacyUrl\": \"http://packagePrivacyUrl-fr.net\",\r\n                    \"Author\": \"FooBar French\",\r\n                    \"PackageName\": \"Bar\",\r\n                    \"PackageUrl\": \"http://packageUrl-fr.net\",\r\n                    \"License\": \"Foo Bar License\",\r\n                    \"LicenseUrl\": \"http://licenseUrl-fr.net\",\r\n                    \"Copyright\": \"Foo Bar Copyright\",\r\n                    \"CopyrightUrl\": \"http://copyrightUrl-fr.net\",\r\n                    \"ShortDescription\": \"Foo bar is a foo bar French.\",\r\n                    \"Description\": \"Foo bar is a placeholder French.\",\r\n                    \"Tags\": [\r\n                      \"FooBarFr\",\r\n                      \"FooFr\",\r\n                      \"BarFr\"\r\n                    ],\r\n                    \"ReleaseNotes\": \"Release notes\",\r\n                    \"ReleaseNotesUrl\": \"https://ReleaseNotes.net\",\r\n                    \"Agreements\": [{\r\n                      \"AgreementLabel\": \"Label\",\r\n                      \"Agreement\": \"Text\",\r\n                      \"AgreementUrl\": \"https://AgreementUrl.net\"\r\n                    }],\r\n                    \"PurchaseUrl\": \"http://purchaseUrl.net\",\r\n                    \"InstallationNotes\": \"Installation Notes\",\r\n                    \"Documentations\": [{\r\n                      \"DocumentLabel\": \"Document Label\",\r\n                      \"DocumentUrl\": \"http://documentUrl.net\"\r\n                    }],\r\n                    \"Icons\": [{\r\n                      \"IconUrl\": \"https://testIcon\",\r\n                      \"IconFileType\": \"png\",\r\n                      \"IconResolution\": \"32x32\",\r\n                      \"IconTheme\": \"light\",\r\n                      \"IconSha256\": \"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321\"\r\n                    }]\r\n                  }\r\n                ],)delimiter\") _XPLATSTR(R\"delimiter(\r\n                \"Installers\": [\r\n                  {\r\n                    \"InstallerSha256\": \"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\",\r\n                    \"InstallerUrl\": \"http://foobar.zip\",\r\n                    \"Architecture\": \"x86\",\r\n                    \"InstallerLocale\": \"en-US\",\r\n                    \"Platform\": [\r\n                      \"Windows.Desktop\"\r\n                    ],\r\n                    \"MinimumOSVersion\": \"1078\",\r\n                    \"InstallerType\": \"zip\",\r\n                    \"Scope\": \"user\",\r\n                    \"InstallModes\": [\r\n                      \"interactive\"\r\n                    ],\r\n                    \"InstallerSwitches\": {\r\n                      \"Silent\": \"/s\",\r\n                      \"SilentWithProgress\": \"/s\",\r\n                      \"Interactive\": \"/i\",\r\n                      \"InstallLocation\": \"C:\\\\Users\\\\User1\",\r\n                      \"Log\": \"/l\",\r\n                      \"Upgrade\": \"/u\",\r\n                      \"Custom\": \"/custom\"\r\n                    },\r\n                    \"InstallerSuccessCodes\": [\r\n                      0\r\n                    ],\r\n                    \"UpgradeBehavior\": \"deny\",\r\n                    \"Commands\": [\r\n                      \"command1\"\r\n                    ],\r\n                    \"Protocols\": [\r\n                       \"protocol1\"\r\n                    ],\r\n                    \"FileExtensions\": [\r\n                      \".file-extension\"\r\n                    ],\r\n                    \"Dependencies\": {\r\n                      \"WindowsFeatures\": [\r\n                        \"feature1\"\r\n                      ],\r\n                      \"WindowsLibraries\": [\r\n                        \"library1\"\r\n                      ],\r\n                      \"PackageDependencies\": [\r\n                        {\r\n                          \"PackageIdentifier\": \"Foo.Baz\",\r\n                          \"MinimumVersion\": \"2.0.0\"\r\n                        }\r\n                      ],\r\n                      \"ExternalDependencies\": [\r\n                        \"FooBarBaz\"\r\n                      ]\r\n                    },\r\n                    \"ProductCode\": \"5b6e0f8a-3bbf-4a17-aefd-024c2b3e075d\",\r\n                    \"ReleaseDate\": \"2021-01-01\",\r\n                    \"InstallerAbortsTerminal\": true,\r\n                    \"InstallLocationRequired\": true,\r\n                    \"RequireExplicitUpgrade\": true,\r\n                    \"UnsupportedOSArchitectures\": [ \"arm\" ],\r\n                    \"ElevationRequirement\": \"elevatesSelf\",\r\n                    \"AppsAndFeaturesEntries\": [{\r\n                      \"DisplayName\": \"DisplayName\",\r\n                      \"DisplayVersion\": \"DisplayVersion\",\r\n                      \"Publisher\": \"Publisher\",\r\n                      \"ProductCode\": \"ProductCode\",\r\n                      \"UpgradeCode\": \"UpgradeCode\",\r\n                      \"InstallerType\": \"exe\"\r\n                    }],\r\n                    \"Markets\" : {\r\n                      \"AllowedMarkets\": [ \"US\" ]\r\n                    },\r\n                    \"ExpectedReturnCodes\": [{\r\n                      \"InstallerReturnCode\": 3,\r\n                      \"ReturnResponse\": \"custom\",\r\n                      \"ReturnResponseUrl\": \"http://returnResponseUrl.net\"\r\n                    }],\r\n                    \"NestedInstallerType\": \"portable\",\r\n                    \"DisplayInstallWarnings\": true,\r\n                    \"UnsupportedArguments\": [ \"log\" ],\r\n                    \"NestedInstallerFiles\": [{\r\n                      \"RelativeFilePath\": \"test\\\\app.exe\",\r\n                      \"PortableCommandAlias\": \"test.exe\"\r\n                    }],\r\n                    \"InstallationMetadata\": {\r\n                      \"DefaultInstallLocation\": \"%TEMP%\\\\DefaultInstallLocation\",\r\n                      \"Files\": [{\r\n                        \"RelativeFilePath\": \"test\\\\app.exe\",\r\n                        \"FileSha256\": \"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\",\r\n                        \"FileType\": \"launch\",\r\n                        \"InvocationParameter\": \"/parameter\",\r\n                        \"DisplayName\": \"test\"\r\n                      }]\r\n                    },\r\n                    \"DownloadCommandProhibited\": true\r\n                  }\r\n                ]\r\n              }\r\n            ]\r\n          },\r\n          \"ContinuationToken\": \"abcd\"\r\n        })delimiter\");\r\n        }\r\n\r\n        void VerifyLocalizations_AllFields(const Manifest& manifest)\r\n        {\r\n            REQUIRE(manifest.DefaultLocalization.Locale == \"en-US\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Publisher>() == \"Foo\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PublisherUrl>() == \"http://publisher.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PublisherSupportUrl>() == \"http://publisherSupport.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PrivacyUrl>() == \"http://packagePrivacyUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Author>() == \"FooBar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageName>() == \"Bar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageUrl>() == \"http://packageUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::License>() == \"Foo Bar License\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::LicenseUrl>() == \"http://licenseUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Copyright>() == \"Foo Bar Copyright\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::CopyrightUrl>() == \"http://copyrightUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ShortDescription>() == \"Foo bar is a foo bar.\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Description>() == \"Foo bar is a placeholder.\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().size() == 3);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(0) == \"FooBar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(1) == \"Foo\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(2) == \"Bar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ReleaseNotes>() == \"Default release notes\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ReleaseNotesUrl>() == \"https://DefaultReleaseNotes.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().size() == 1);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).Label == \"DefaultLabel\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).AgreementText == \"DefaultText\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).AgreementUrl == \"https://DefaultAgreementUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PurchaseUrl>() == \"http://DefaultPurchaseUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::InstallationNotes>() == \"Default Installation Notes\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().size() == 1);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().at(0).DocumentLabel == \"Default Document Label\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().at(0).DocumentUrl == \"http://DefaultDocumentUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().size() == 1);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Url == \"https://DefaultTestIcon\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).FileType == IconFileTypeEnum::Ico);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Resolution == IconResolutionEnum::Custom);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Theme == IconThemeEnum::Default);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\"));\r\n\r\n            REQUIRE(manifest.Localizations.size() == 1);\r\n            ManifestLocalization frenchLocalization = manifest.Localizations.at(0);\r\n            REQUIRE(frenchLocalization.Locale == \"fr-Fr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Publisher>() == \"Foo French\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PublisherUrl>() == \"http://publisher-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PublisherSupportUrl>() == \"http://publisherSupport-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PrivacyUrl>() == \"http://packagePrivacyUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Author>() == \"FooBar French\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PackageName>() == \"Bar\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PackageUrl>() == \"http://packageUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::License>() == \"Foo Bar License\");\r\n            REQUIRE(frenchLocalization.Get<Localization::LicenseUrl>() == \"http://licenseUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Copyright>() == \"Foo Bar Copyright\");\r\n            REQUIRE(frenchLocalization.Get<Localization::CopyrightUrl>() == \"http://copyrightUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::ShortDescription>() == \"Foo bar is a foo bar French.\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Description>() == \"Foo bar is a placeholder French.\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().size() == 3);\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(0) == \"FooBarFr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(1) == \"FooFr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(2) == \"BarFr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::ReleaseNotes>() == \"Release notes\");\r\n            REQUIRE(frenchLocalization.Get<Localization::ReleaseNotesUrl>() == \"https://ReleaseNotes.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().size() == 1);\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).Label == \"Label\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).AgreementText == \"Text\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).AgreementUrl == \"https://AgreementUrl.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PurchaseUrl>() == \"http://purchaseUrl.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::InstallationNotes>() == \"Installation Notes\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Documentations>().size() == 1);\r\n            REQUIRE(frenchLocalization.Get<Localization::Documentations>().at(0).DocumentLabel == \"Document Label\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Documentations>().at(0).DocumentUrl == \"http://documentUrl.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().size() == 1);\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Url == \"https://testIcon\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).FileType == IconFileTypeEnum::Png);\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Resolution == IconResolutionEnum::Square32);\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Theme == IconThemeEnum::Light);\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321\"));\r\n        }\r\n\r\n        void VerifyInstallers_AllFields(const Manifest& manifest)\r\n        {\r\n            REQUIRE(manifest.Installers.size() == 1);\r\n\r\n            ManifestInstaller actualInstaller = manifest.Installers.at(0);\r\n            REQUIRE(actualInstaller.Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\"));\r\n            REQUIRE(actualInstaller.Url == \"http://foobar.zip\");\r\n            REQUIRE(actualInstaller.Arch == Architecture::X86);\r\n            REQUIRE(actualInstaller.Locale == \"en-US\");\r\n            REQUIRE(actualInstaller.Platform.size() == 1);\r\n            REQUIRE(actualInstaller.Platform[0] == PlatformEnum::Desktop);\r\n            REQUIRE(actualInstaller.MinOSVersion == \"1078\");\r\n            REQUIRE(actualInstaller.BaseInstallerType == InstallerTypeEnum::Zip);\r\n            REQUIRE(actualInstaller.Scope == ScopeEnum::User);\r\n            REQUIRE(actualInstaller.InstallModes.size() == 1);\r\n            REQUIRE(actualInstaller.InstallModes.at(0) == InstallModeEnum::Interactive);\r\n            REQUIRE(actualInstaller.Switches.size() == 7);\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Silent) == \"/s\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::SilentWithProgress) == \"/s\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Interactive) == \"/i\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::InstallLocation) == \"C:\\\\Users\\\\User1\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Log) == \"/l\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Update) == \"/u\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Custom) == \"/custom\");\r\n            REQUIRE(actualInstaller.InstallerSuccessCodes.size() == 1);\r\n            REQUIRE(actualInstaller.InstallerSuccessCodes.at(0) == 0);\r\n            REQUIRE(actualInstaller.UpdateBehavior == UpdateBehaviorEnum::Deny);\r\n            REQUIRE(actualInstaller.Commands.at(0) == \"command1\");\r\n            REQUIRE(actualInstaller.Protocols.at(0) == \"protocol1\");\r\n            REQUIRE(actualInstaller.FileExtensions.at(0) == \".file-extension\");\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::WindowsFeature, \"feature1\"));\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::WindowsLibrary, \"library1\"));\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::Package, \"Foo.Baz\", \"2.0.0\"));\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::External, \"FooBarBaz\"));\r\n            REQUIRE(actualInstaller.PackageFamilyName == \"\");\r\n            REQUIRE(actualInstaller.ProductCode == \"5b6e0f8a-3bbf-4a17-aefd-024c2b3e075d\");\r\n            REQUIRE(actualInstaller.ReleaseDate == \"2021-01-01\");\r\n            REQUIRE(actualInstaller.InstallerAbortsTerminal);\r\n            REQUIRE(actualInstaller.InstallLocationRequired);\r\n            REQUIRE(actualInstaller.RequireExplicitUpgrade);\r\n            REQUIRE(actualInstaller.ElevationRequirement == ElevationRequirementEnum::ElevatesSelf);\r\n            REQUIRE(actualInstaller.UnsupportedOSArchitectures.size() == 1);\r\n            REQUIRE(actualInstaller.UnsupportedOSArchitectures.at(0) == Architecture::Arm);\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.size() == 1);\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).DisplayName == \"DisplayName\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).DisplayVersion == \"DisplayVersion\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).Publisher == \"Publisher\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).ProductCode == \"ProductCode\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).UpgradeCode == \"UpgradeCode\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).InstallerType == InstallerTypeEnum::Exe);\r\n            REQUIRE(actualInstaller.Markets.AllowedMarkets.size() == 1);\r\n            REQUIRE(actualInstaller.Markets.AllowedMarkets.at(0) == \"US\");\r\n            REQUIRE(actualInstaller.ExpectedReturnCodes.at(3).ReturnResponseEnum == ExpectedReturnCodeEnum::Custom);\r\n            REQUIRE(actualInstaller.ExpectedReturnCodes.at(3).ReturnResponseUrl == \"http://returnResponseUrl.net\");\r\n            REQUIRE(actualInstaller.NestedInstallerType == InstallerTypeEnum::Portable);\r\n            REQUIRE(actualInstaller.DisplayInstallWarnings);\r\n            REQUIRE(actualInstaller.UnsupportedArguments.size() == 1);\r\n            REQUIRE(actualInstaller.UnsupportedArguments.at(0) == UnsupportedArgumentEnum::Log);\r\n            REQUIRE(actualInstaller.NestedInstallerFiles.size() == 1);\r\n            REQUIRE(actualInstaller.NestedInstallerFiles.at(0).RelativeFilePath == \"test\\\\app.exe\");\r\n            REQUIRE(actualInstaller.NestedInstallerFiles.at(0).PortableCommandAlias == \"test.exe\");\r\n            REQUIRE(actualInstaller.InstallationMetadata.DefaultInstallLocation == \"%TEMP%\\\\DefaultInstallLocation\");\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.size() == 1);\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).RelativeFilePath == \"test\\\\app.exe\");\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).FileType == InstalledFileTypeEnum::Launch);\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).FileSha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\"));\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).InvocationParameter == \"/parameter\");\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).DisplayName == \"test\");\r\n            REQUIRE(actualInstaller.DownloadCommandProhibited);\r\n        }\r\n    };\r\n}\r\n\r\nTEST_CASE(\"GetManifests_GoodResponse_V1_6\", \"[RestSource][Interface_1_6]\")\r\n{\r\n    GoodManifest_AllFields sampleManifest;\r\n    utility::string_t sample = sampleManifest.GetSampleManifest_AllFields();\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) };\r\n    Interface v1_6{ TestRestUriString, std::move(helper), {} };\r\n    std::vector<Manifest> manifests = v1_6.GetManifests(\"Foo.Bar\");\r\n    REQUIRE(manifests.size() == 1);\r\n\r\n    // Verify manifest is populated\r\n    Manifest& manifest = manifests[0];\r\n    REQUIRE(manifest.Id == \"Foo.Bar\");\r\n    REQUIRE(manifest.Version == \"3.0.0abc\");\r\n    REQUIRE(manifest.Moniker == \"FooBarMoniker\");\r\n    REQUIRE(manifest.Channel == \"\");\r\n    REQUIRE(manifest.ManifestVersion == AppInstaller::Manifest::ManifestVer{ \"1.6.0\" });\r\n    sampleManifest.VerifyLocalizations_AllFields(manifest);\r\n    sampleManifest.VerifyInstallers_AllFields(manifest);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/RestInterface_1_7.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestHooks.h\"\r\n#include \"TestRestRequestHandler.h\"\r\n#include <Rest/Schema/1_7/Interface.h>\r\n#include <Rest/Schema/IRestClient.h>\r\n#include <AppInstallerVersions.h>\r\n#include <AppInstallerErrors.h>\r\n#include <winget/Authentication.h>\r\n#include <winget/JsonUtil.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller;\r\nusing namespace AppInstaller::Authentication;\r\nusing namespace AppInstaller::Http;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Repository::Rest;\r\nusing namespace AppInstaller::Repository::Rest::Schema;\r\nusing namespace AppInstaller::Repository::Rest::Schema::V1_7;\r\n\r\nnamespace\r\n{\r\n    const std::string TestRestUriString = \"http://restsource.com/api\";\r\n\r\n    IRestClient::Information GetTestSourceInformation()\r\n    {\r\n        IRestClient::Information result;\r\n\r\n        result.Authentication.Type = AuthenticationType::MicrosoftEntraId;\r\n        MicrosoftEntraIdAuthenticationInfo microsoftEntraIdInfo;\r\n        microsoftEntraIdInfo.Resource = \"GUID\";\r\n        result.Authentication.MicrosoftEntraIdInfo = std::move(microsoftEntraIdInfo);\r\n\r\n        return result;\r\n    }\r\n\r\n    AuthenticationArguments GetTestAuthenticationArguments()\r\n    {\r\n        AuthenticationArguments result;\r\n        result.Mode = AuthenticationMode::Silent;\r\n        return result;\r\n    }\r\n\r\n    utility::string_t SampleSearchResponse = _XPLATSTR(\r\n        R\"delimiter({\r\n            \"Data\" : [\r\n               {\r\n              \"PackageIdentifier\": \"git.package\",\r\n              \"PackageName\": \"package\",\r\n              \"Publisher\": \"git\",\r\n              \"Versions\": [\r\n                {   \"PackageVersion\": \"1.0.0\" }]\r\n            }]\r\n        })delimiter\");\r\n\r\n    utility::string_t SampleGetManifestResponse = _XPLATSTR(\r\n        R\"delimiter({\r\n        \"Data\": {\r\n            \"PackageIdentifier\": \"Foo.Bar\",\r\n            \"Versions\": [\r\n                {\r\n                    \"PackageVersion\": \"5.0.0\",\r\n                    \"DefaultLocale\": {\r\n                        \"PackageLocale\": \"en-us\",\r\n                        \"Publisher\": \"Foo\",\r\n                        \"PackageName\": \"Bar\",\r\n                        \"License\": \"Foo bar license\",\r\n                        \"ShortDescription\": \"Foo bar description\"\r\n                    },\r\n                    \"Installers\": [\r\n                        {\r\n                            \"Architecture\": \"x64\",\r\n                            \"InstallerSha256\": \"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\",\r\n                            \"InstallerType\": \"exe\",\r\n                            \"InstallerUrl\": \"https://installer.example.com/foobar.exe\"\r\n                        }\r\n                    ]\r\n                }\r\n            ]\r\n        }\r\n    })delimiter\");\r\n\r\n    struct GoodManifest_AllFields\r\n    {\r\n        utility::string_t GetSampleManifest_AllFields()\r\n        {\r\n            return _XPLATSTR(\r\n                R\"delimiter(\r\n        {\r\n          \"Data\": {\r\n            \"PackageIdentifier\": \"Foo.Bar\",\r\n            \"Versions\": [\r\n              {\r\n                \"PackageVersion\": \"3.0.0abc\",\r\n                \"DefaultLocale\": {\r\n                  \"PackageLocale\": \"en-US\",\r\n                  \"Publisher\": \"Foo\",\r\n                  \"PublisherUrl\": \"http://publisher.net\",\r\n                  \"PublisherSupportUrl\": \"http://publisherSupport.net\",\r\n                  \"PrivacyUrl\": \"http://packagePrivacyUrl.net\",\r\n                  \"Author\": \"FooBar\",\r\n                  \"PackageName\": \"Bar\",\r\n                  \"PackageUrl\": \"http://packageUrl.net\",\r\n                  \"License\": \"Foo Bar License\",\r\n                  \"LicenseUrl\": \"http://licenseUrl.net\",\r\n                  \"Copyright\": \"Foo Bar Copyright\",\r\n                  \"CopyrightUrl\": \"http://copyrightUrl.net\",\r\n                  \"ShortDescription\": \"Foo bar is a foo bar.\",\r\n                  \"Description\": \"Foo bar is a placeholder.\",\r\n                  \"Tags\": [\r\n                    \"FooBar\",\r\n                    \"Foo\",\r\n                    \"Bar\"\r\n                  ],\r\n                  \"Moniker\": \"FooBarMoniker\",\r\n                  \"ReleaseNotes\": \"Default release notes\",\r\n                  \"ReleaseNotesUrl\": \"https://DefaultReleaseNotes.net\",\r\n                  \"Agreements\": [{\r\n                    \"AgreementLabel\": \"DefaultLabel\",\r\n                    \"Agreement\": \"DefaultText\",\r\n                    \"AgreementUrl\": \"https://DefaultAgreementUrl.net\"\r\n                  }],\r\n                  \"PurchaseUrl\": \"http://DefaultPurchaseUrl.net\",\r\n                  \"InstallationNotes\": \"Default Installation Notes\",\r\n                  \"Documentations\": [{\r\n                    \"DocumentLabel\": \"Default Document Label\",\r\n                    \"DocumentUrl\": \"http://DefaultDocumentUrl.net\"\r\n                  }],\r\n                  \"Icons\": [{\r\n                    \"IconUrl\": \"https://DefaultTestIcon\",\r\n                    \"IconFileType\": \"ico\",\r\n                    \"IconResolution\": \"custom\",\r\n                    \"IconTheme\": \"default\",\r\n                    \"IconSha256\": \"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\"\r\n                  }]\r\n                },\r\n                \"Channel\": \"\",\r\n                \"Locales\": [\r\n                  {\r\n                    \"PackageLocale\": \"fr-Fr\",\r\n                    \"Publisher\": \"Foo French\",\r\n                    \"PublisherUrl\": \"http://publisher-fr.net\",\r\n                    \"PublisherSupportUrl\": \"http://publisherSupport-fr.net\",\r\n                    \"PrivacyUrl\": \"http://packagePrivacyUrl-fr.net\",\r\n                    \"Author\": \"FooBar French\",\r\n                    \"PackageName\": \"Bar\",\r\n                    \"PackageUrl\": \"http://packageUrl-fr.net\",\r\n                    \"License\": \"Foo Bar License\",\r\n                    \"LicenseUrl\": \"http://licenseUrl-fr.net\",\r\n                    \"Copyright\": \"Foo Bar Copyright\",\r\n                    \"CopyrightUrl\": \"http://copyrightUrl-fr.net\",\r\n                    \"ShortDescription\": \"Foo bar is a foo bar French.\",\r\n                    \"Description\": \"Foo bar is a placeholder French.\",\r\n                    \"Tags\": [\r\n                      \"FooBarFr\",\r\n                      \"FooFr\",\r\n                      \"BarFr\"\r\n                    ],\r\n                    \"ReleaseNotes\": \"Release notes\",\r\n                    \"ReleaseNotesUrl\": \"https://ReleaseNotes.net\",\r\n                    \"Agreements\": [{\r\n                      \"AgreementLabel\": \"Label\",\r\n                      \"Agreement\": \"Text\",\r\n                      \"AgreementUrl\": \"https://AgreementUrl.net\"\r\n                    }],\r\n                    \"PurchaseUrl\": \"http://purchaseUrl.net\",\r\n                    \"InstallationNotes\": \"Installation Notes\",\r\n                    \"Documentations\": [{\r\n                      \"DocumentLabel\": \"Document Label\",\r\n                      \"DocumentUrl\": \"http://documentUrl.net\"\r\n                    }],\r\n                    \"Icons\": [{\r\n                      \"IconUrl\": \"https://testIcon\",\r\n                      \"IconFileType\": \"png\",\r\n                      \"IconResolution\": \"32x32\",\r\n                      \"IconTheme\": \"light\",\r\n                      \"IconSha256\": \"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321\"\r\n                    }]\r\n                  }\r\n                ],)delimiter\") _XPLATSTR(R\"delimiter(\r\n                \"Installers\": [\r\n                  {\r\n                    \"InstallerSha256\": \"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\",\r\n                    \"InstallerUrl\": \"http://foobar.zip\",\r\n                    \"Architecture\": \"x86\",\r\n                    \"InstallerLocale\": \"en-US\",\r\n                    \"Platform\": [\r\n                      \"Windows.Desktop\"\r\n                    ],\r\n                    \"MinimumOSVersion\": \"1078\",\r\n                    \"InstallerType\": \"zip\",\r\n                    \"Scope\": \"user\",\r\n                    \"InstallModes\": [\r\n                      \"interactive\"\r\n                    ],\r\n                    \"InstallerSwitches\": {\r\n                      \"Silent\": \"/s\",\r\n                      \"SilentWithProgress\": \"/s\",\r\n                      \"Interactive\": \"/i\",\r\n                      \"InstallLocation\": \"C:\\\\Users\\\\User1\",\r\n                      \"Log\": \"/l\",\r\n                      \"Upgrade\": \"/u\",\r\n                      \"Custom\": \"/custom\",\r\n                      \"Repair\": \"/repair\"\r\n                    },\r\n                    \"InstallerSuccessCodes\": [\r\n                      0\r\n                    ],\r\n                    \"UpgradeBehavior\": \"deny\",\r\n                    \"Commands\": [\r\n                      \"command1\"\r\n                    ],\r\n                    \"Protocols\": [\r\n                       \"protocol1\"\r\n                    ],\r\n                    \"FileExtensions\": [\r\n                      \".file-extension\"\r\n                    ],\r\n                    \"Dependencies\": {\r\n                      \"WindowsFeatures\": [\r\n                        \"feature1\"\r\n                      ],\r\n                      \"WindowsLibraries\": [\r\n                        \"library1\"\r\n                      ],\r\n                      \"PackageDependencies\": [\r\n                        {\r\n                          \"PackageIdentifier\": \"Foo.Baz\",\r\n                          \"MinimumVersion\": \"2.0.0\"\r\n                        }\r\n                      ],\r\n                      \"ExternalDependencies\": [\r\n                        \"FooBarBaz\"\r\n                      ]\r\n                    },\r\n                    \"ProductCode\": \"5b6e0f8a-3bbf-4a17-aefd-024c2b3e075d\",\r\n                    \"ReleaseDate\": \"2021-01-01\",\r\n                    \"InstallerAbortsTerminal\": true,\r\n                    \"InstallLocationRequired\": true,\r\n                    \"RequireExplicitUpgrade\": true,\r\n                    \"UnsupportedOSArchitectures\": [ \"arm\" ],\r\n                    \"ElevationRequirement\": \"elevatesSelf\",\r\n                    \"AppsAndFeaturesEntries\": [{\r\n                      \"DisplayName\": \"DisplayName\",\r\n                      \"DisplayVersion\": \"DisplayVersion\",\r\n                      \"Publisher\": \"Publisher\",\r\n                      \"ProductCode\": \"ProductCode\",\r\n                      \"UpgradeCode\": \"UpgradeCode\",\r\n                      \"InstallerType\": \"exe\"\r\n                    }],\r\n                    \"Markets\" : {\r\n                      \"AllowedMarkets\": [ \"US\" ]\r\n                    },\r\n                    \"ExpectedReturnCodes\": [{\r\n                      \"InstallerReturnCode\": 3,\r\n                      \"ReturnResponse\": \"custom\",\r\n                      \"ReturnResponseUrl\": \"http://returnResponseUrl.net\"\r\n                    }],\r\n                    \"NestedInstallerType\": \"portable\",\r\n                    \"DisplayInstallWarnings\": true,\r\n                    \"UnsupportedArguments\": [ \"log\" ],\r\n                    \"NestedInstallerFiles\": [{\r\n                      \"RelativeFilePath\": \"test\\\\app.exe\",\r\n                      \"PortableCommandAlias\": \"test.exe\"\r\n                    }],\r\n                    \"InstallationMetadata\": {\r\n                      \"DefaultInstallLocation\": \"%TEMP%\\\\DefaultInstallLocation\",\r\n                      \"Files\": [{\r\n                        \"RelativeFilePath\": \"test\\\\app.exe\",\r\n                        \"FileSha256\": \"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\",\r\n                        \"FileType\": \"launch\",\r\n                        \"InvocationParameter\": \"/parameter\",\r\n                        \"DisplayName\": \"test\"\r\n                      }]\r\n                    },\r\n                    \"DownloadCommandProhibited\": true,\r\n                    \"RepairBehavior\": \"uninstaller\"\r\n                  }\r\n                ]\r\n              }\r\n            ]\r\n          },\r\n          \"ContinuationToken\": \"abcd\"\r\n        })delimiter\");\r\n        }\r\n\r\n        void VerifyLocalizations_AllFields(const AppInstaller::Manifest::Manifest& manifest)\r\n        {\r\n            REQUIRE(manifest.DefaultLocalization.Locale == \"en-US\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Publisher>() == \"Foo\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PublisherUrl>() == \"http://publisher.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PublisherSupportUrl>() == \"http://publisherSupport.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PrivacyUrl>() == \"http://packagePrivacyUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Author>() == \"FooBar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageName>() == \"Bar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageUrl>() == \"http://packageUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::License>() == \"Foo Bar License\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::LicenseUrl>() == \"http://licenseUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Copyright>() == \"Foo Bar Copyright\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::CopyrightUrl>() == \"http://copyrightUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ShortDescription>() == \"Foo bar is a foo bar.\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Description>() == \"Foo bar is a placeholder.\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().size() == 3);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(0) == \"FooBar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(1) == \"Foo\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(2) == \"Bar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ReleaseNotes>() == \"Default release notes\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ReleaseNotesUrl>() == \"https://DefaultReleaseNotes.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().size() == 1);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).Label == \"DefaultLabel\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).AgreementText == \"DefaultText\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).AgreementUrl == \"https://DefaultAgreementUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PurchaseUrl>() == \"http://DefaultPurchaseUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::InstallationNotes>() == \"Default Installation Notes\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().size() == 1);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().at(0).DocumentLabel == \"Default Document Label\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().at(0).DocumentUrl == \"http://DefaultDocumentUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().size() == 1);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Url == \"https://DefaultTestIcon\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).FileType == IconFileTypeEnum::Ico);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Resolution == IconResolutionEnum::Custom);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Theme == IconThemeEnum::Default);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\"));\r\n\r\n            REQUIRE(manifest.Localizations.size() == 1);\r\n            ManifestLocalization frenchLocalization = manifest.Localizations.at(0);\r\n            REQUIRE(frenchLocalization.Locale == \"fr-Fr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Publisher>() == \"Foo French\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PublisherUrl>() == \"http://publisher-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PublisherSupportUrl>() == \"http://publisherSupport-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PrivacyUrl>() == \"http://packagePrivacyUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Author>() == \"FooBar French\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PackageName>() == \"Bar\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PackageUrl>() == \"http://packageUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::License>() == \"Foo Bar License\");\r\n            REQUIRE(frenchLocalization.Get<Localization::LicenseUrl>() == \"http://licenseUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Copyright>() == \"Foo Bar Copyright\");\r\n            REQUIRE(frenchLocalization.Get<Localization::CopyrightUrl>() == \"http://copyrightUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::ShortDescription>() == \"Foo bar is a foo bar French.\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Description>() == \"Foo bar is a placeholder French.\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().size() == 3);\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(0) == \"FooBarFr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(1) == \"FooFr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(2) == \"BarFr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::ReleaseNotes>() == \"Release notes\");\r\n            REQUIRE(frenchLocalization.Get<Localization::ReleaseNotesUrl>() == \"https://ReleaseNotes.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().size() == 1);\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).Label == \"Label\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).AgreementText == \"Text\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).AgreementUrl == \"https://AgreementUrl.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PurchaseUrl>() == \"http://purchaseUrl.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::InstallationNotes>() == \"Installation Notes\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Documentations>().size() == 1);\r\n            REQUIRE(frenchLocalization.Get<Localization::Documentations>().at(0).DocumentLabel == \"Document Label\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Documentations>().at(0).DocumentUrl == \"http://documentUrl.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().size() == 1);\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Url == \"https://testIcon\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).FileType == IconFileTypeEnum::Png);\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Resolution == IconResolutionEnum::Square32);\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Theme == IconThemeEnum::Light);\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321\"));\r\n        }\r\n\r\n        void VerifyInstallers_AllFields(const AppInstaller::Manifest::Manifest& manifest)\r\n        {\r\n            REQUIRE(manifest.Installers.size() == 1);\r\n\r\n            ManifestInstaller actualInstaller = manifest.Installers.at(0);\r\n            REQUIRE(actualInstaller.Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\"));\r\n            REQUIRE(actualInstaller.Url == \"http://foobar.zip\");\r\n            REQUIRE(actualInstaller.Arch == Architecture::X86);\r\n            REQUIRE(actualInstaller.Locale == \"en-US\");\r\n            REQUIRE(actualInstaller.Platform.size() == 1);\r\n            REQUIRE(actualInstaller.Platform[0] == PlatformEnum::Desktop);\r\n            REQUIRE(actualInstaller.MinOSVersion == \"1078\");\r\n            REQUIRE(actualInstaller.BaseInstallerType == InstallerTypeEnum::Zip);\r\n            REQUIRE(actualInstaller.Scope == ScopeEnum::User);\r\n            REQUIRE(actualInstaller.InstallModes.size() == 1);\r\n            REQUIRE(actualInstaller.InstallModes.at(0) == InstallModeEnum::Interactive);\r\n            REQUIRE(actualInstaller.Switches.size() == 8);\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Silent) == \"/s\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::SilentWithProgress) == \"/s\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Interactive) == \"/i\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::InstallLocation) == \"C:\\\\Users\\\\User1\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Log) == \"/l\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Update) == \"/u\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Custom) == \"/custom\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Repair) == \"/repair\");\r\n            REQUIRE(actualInstaller.InstallerSuccessCodes.size() == 1);\r\n            REQUIRE(actualInstaller.InstallerSuccessCodes.at(0) == 0);\r\n            REQUIRE(actualInstaller.UpdateBehavior == UpdateBehaviorEnum::Deny);\r\n            REQUIRE(actualInstaller.Commands.at(0) == \"command1\");\r\n            REQUIRE(actualInstaller.Protocols.at(0) == \"protocol1\");\r\n            REQUIRE(actualInstaller.FileExtensions.at(0) == \".file-extension\");\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::WindowsFeature, \"feature1\"));\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::WindowsLibrary, \"library1\"));\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::Package, \"Foo.Baz\", \"2.0.0\"));\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::External, \"FooBarBaz\"));\r\n            REQUIRE(actualInstaller.PackageFamilyName == \"\");\r\n            REQUIRE(actualInstaller.ProductCode == \"5b6e0f8a-3bbf-4a17-aefd-024c2b3e075d\");\r\n            REQUIRE(actualInstaller.ReleaseDate == \"2021-01-01\");\r\n            REQUIRE(actualInstaller.InstallerAbortsTerminal);\r\n            REQUIRE(actualInstaller.InstallLocationRequired);\r\n            REQUIRE(actualInstaller.RequireExplicitUpgrade);\r\n            REQUIRE(actualInstaller.ElevationRequirement == ElevationRequirementEnum::ElevatesSelf);\r\n            REQUIRE(actualInstaller.UnsupportedOSArchitectures.size() == 1);\r\n            REQUIRE(actualInstaller.UnsupportedOSArchitectures.at(0) == Architecture::Arm);\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.size() == 1);\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).DisplayName == \"DisplayName\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).DisplayVersion == \"DisplayVersion\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).Publisher == \"Publisher\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).ProductCode == \"ProductCode\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).UpgradeCode == \"UpgradeCode\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).InstallerType == InstallerTypeEnum::Exe);\r\n            REQUIRE(actualInstaller.Markets.AllowedMarkets.size() == 1);\r\n            REQUIRE(actualInstaller.Markets.AllowedMarkets.at(0) == \"US\");\r\n            REQUIRE(actualInstaller.ExpectedReturnCodes.at(3).ReturnResponseEnum == ExpectedReturnCodeEnum::Custom);\r\n            REQUIRE(actualInstaller.ExpectedReturnCodes.at(3).ReturnResponseUrl == \"http://returnResponseUrl.net\");\r\n            REQUIRE(actualInstaller.NestedInstallerType == InstallerTypeEnum::Portable);\r\n            REQUIRE(actualInstaller.DisplayInstallWarnings);\r\n            REQUIRE(actualInstaller.UnsupportedArguments.size() == 1);\r\n            REQUIRE(actualInstaller.UnsupportedArguments.at(0) == UnsupportedArgumentEnum::Log);\r\n            REQUIRE(actualInstaller.NestedInstallerFiles.size() == 1);\r\n            REQUIRE(actualInstaller.NestedInstallerFiles.at(0).RelativeFilePath == \"test\\\\app.exe\");\r\n            REQUIRE(actualInstaller.NestedInstallerFiles.at(0).PortableCommandAlias == \"test.exe\");\r\n            REQUIRE(actualInstaller.InstallationMetadata.DefaultInstallLocation == \"%TEMP%\\\\DefaultInstallLocation\");\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.size() == 1);\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).RelativeFilePath == \"test\\\\app.exe\");\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).FileType == InstalledFileTypeEnum::Launch);\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).FileSha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\"));\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).InvocationParameter == \"/parameter\");\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).DisplayName == \"test\");\r\n            REQUIRE(actualInstaller.DownloadCommandProhibited);\r\n            REQUIRE(actualInstaller.RepairBehavior == RepairBehaviorEnum::Uninstaller);\r\n        }\r\n    };\r\n}\r\n\r\nTEST_CASE(\"GetManifests_GoodRequest_Authentication\", \"[RestSource][Interface_1_7]\")\r\n{\r\n    if (Runtime::IsRunningAsSystem())\r\n    {\r\n        WARN(\"Test does not support running as system. Skipped.\");\r\n        return;\r\n    }\r\n\r\n    std::string expectedToken = \"TestToken\";\r\n\r\n    // Set good authentication result\r\n    AuthenticationResult authResultOverride;\r\n    authResultOverride.Status = S_OK;\r\n    authResultOverride.Token = expectedToken;\r\n    TestHook::SetAuthenticationResult_Override setAuthenticationResultOverride(authResultOverride);\r\n\r\n    // GetManifest should succeed with expected value.\r\n    HttpClientHelper helper{ GetHeaderVerificationHandler(web::http::status_codes::OK, SampleGetManifestResponse, { web::http::header_names::authorization, JSON::GetUtilityString(CreateBearerToken(expectedToken)) }, web::http::status_codes::Unauthorized) };\r\n    Interface v1_7{ TestRestUriString, std::move(helper), GetTestSourceInformation(), {}, GetTestAuthenticationArguments() };\r\n    auto manifestResult = v1_7.GetManifestByVersion(\"Foo.Bar\", \"5.0.0\", \"\");\r\n    REQUIRE(manifestResult.has_value());\r\n    const auto& manifest = manifestResult.value();\r\n    REQUIRE(manifest.Id == \"Foo.Bar\");\r\n    REQUIRE(manifest.Version == \"5.0.0\");\r\n}\r\n\r\nTEST_CASE(\"GetManifests_BadRequest_AuthenticationFailed\", \"[RestSource][Interface_1_7]\")\r\n{\r\n    if (Runtime::IsRunningAsSystem())\r\n    {\r\n        WARN(\"Test does not support running as system. Skipped.\");\r\n        return;\r\n    }\r\n\r\n    std::string expectedToken = \"TestToken\";\r\n\r\n    // Set authentication failed result\r\n    AuthenticationResult authResultOverride;\r\n    authResultOverride.Status = APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED;\r\n    TestHook::SetAuthenticationResult_Override setAuthenticationResultOverride(authResultOverride);\r\n\r\n    // GetManifest should fail with authentication failure\r\n    HttpClientHelper helper{ GetHeaderVerificationHandler(web::http::status_codes::OK, SampleGetManifestResponse, { web::http::header_names::authorization, JSON::GetUtilityString(CreateBearerToken(expectedToken)) }, web::http::status_codes::Unauthorized) };\r\n    Interface v1_7{ TestRestUriString, std::move(helper), GetTestSourceInformation(), {}, GetTestAuthenticationArguments() };\r\n    REQUIRE_THROWS_HR(v1_7.GetManifestByVersion(\"Foo.Bar\", \"5.0.0\", \"\"), APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED);\r\n}\r\n\r\nTEST_CASE(\"GetManifests_BadRequest_InvalidAuthenticationToken\", \"[RestSource][Interface_1_7]\")\r\n{\r\n    if (Runtime::IsRunningAsSystem())\r\n    {\r\n        WARN(\"Test does not support running as system. Skipped.\");\r\n        return;\r\n    }\r\n\r\n    std::string expectedToken = \"TestToken\";\r\n\r\n    // Set authentication result with incorrect token\r\n    AuthenticationResult authResultOverride;\r\n    authResultOverride.Status = S_OK;\r\n    authResultOverride.Token = \"OtherToken\";\r\n    TestHook::SetAuthenticationResult_Override setAuthenticationResultOverride(authResultOverride);\r\n\r\n    // GetManifest should fail with access denied\r\n    HttpClientHelper helper{ GetHeaderVerificationHandler(web::http::status_codes::OK, SampleGetManifestResponse, { web::http::header_names::authorization, JSON::GetUtilityString(CreateBearerToken(expectedToken)) }, web::http::status_codes::Unauthorized) };\r\n    Interface v1_7{ TestRestUriString, std::move(helper), GetTestSourceInformation(), {}, GetTestAuthenticationArguments() };\r\n    REQUIRE_THROWS_HR(v1_7.GetManifestByVersion(\"Foo.Bar\", \"5.0.0\", \"\"), HTTP_E_STATUS_DENIED);\r\n}\r\n\r\nTEST_CASE(\"Search_GoodRequest_Authentication\", \"[RestSource][Interface_1_7]\")\r\n{\r\n    if (Runtime::IsRunningAsSystem())\r\n    {\r\n        WARN(\"Test does not support running as system. Skipped.\");\r\n        return;\r\n    }\r\n\r\n    std::string expectedToken = \"TestToken\";\r\n\r\n    // Set good authentication result\r\n    AuthenticationResult authResultOverride;\r\n    authResultOverride.Status = S_OK;\r\n    authResultOverride.Token = expectedToken;\r\n    TestHook::SetAuthenticationResult_Override setAuthenticationResultOverride(authResultOverride);\r\n\r\n    // Search should succeed with expected value.\r\n    HttpClientHelper helper{ GetHeaderVerificationHandler(web::http::status_codes::OK, SampleSearchResponse, { web::http::header_names::authorization, JSON::GetUtilityString(CreateBearerToken(expectedToken)) }, web::http::status_codes::Unauthorized) };\r\n    Interface v1_7{ TestRestUriString, std::move(helper), GetTestSourceInformation(), {}, GetTestAuthenticationArguments() };\r\n    SearchRequest request;\r\n    PackageMatchFilter filter{ PackageMatchField::Name, MatchType::Exact, \"package\" };\r\n    request.Filters.emplace_back(std::move(filter));\r\n    IRestClient::SearchResult searchResponse = v1_7.Search(request);\r\n    REQUIRE(searchResponse.Matches.size() == 1);\r\n    IRestClient::Package package = searchResponse.Matches.at(0);\r\n    REQUIRE(package.PackageInformation.PackageIdentifier.compare(\"git.package\") == 0);\r\n}\r\n\r\nTEST_CASE(\"Search_BadRequest_AuthenticationFailed\", \"[RestSource][Interface_1_7]\")\r\n{\r\n    if (Runtime::IsRunningAsSystem())\r\n    {\r\n        WARN(\"Test does not support running as system. Skipped.\");\r\n        return;\r\n    }\r\n\r\n    std::string expectedToken = \"TestToken\";\r\n\r\n    // Set authentication failed result\r\n    AuthenticationResult authResultOverride;\r\n    authResultOverride.Status = APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED;\r\n    TestHook::SetAuthenticationResult_Override setAuthenticationResultOverride(authResultOverride);\r\n\r\n    // Search should fail with authentication failure\r\n    HttpClientHelper helper{ GetHeaderVerificationHandler(web::http::status_codes::OK, SampleSearchResponse, { web::http::header_names::authorization, JSON::GetUtilityString(CreateBearerToken(expectedToken)) }, web::http::status_codes::Unauthorized) };\r\n    Interface v1_7{ TestRestUriString, std::move(helper), GetTestSourceInformation(), {}, GetTestAuthenticationArguments() };\r\n    SearchRequest request;\r\n    PackageMatchFilter filter{ PackageMatchField::Name, MatchType::Exact, \"package\" };\r\n    request.Filters.emplace_back(std::move(filter));\r\n    REQUIRE_THROWS_HR(v1_7.Search(request), APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED);\r\n}\r\n\r\nTEST_CASE(\"Search_BadRequest_InvalidAuthenticationToken\", \"[RestSource][Interface_1_7]\")\r\n{\r\n    if (Runtime::IsRunningAsSystem())\r\n    {\r\n        WARN(\"Test does not support running as system. Skipped.\");\r\n        return;\r\n    }\r\n\r\n    std::string expectedToken = \"TestToken\";\r\n\r\n    // Set authentication result with incorrect token\r\n    AuthenticationResult authResultOverride;\r\n    authResultOverride.Status = S_OK;\r\n    authResultOverride.Token = \"OtherToken\";\r\n    TestHook::SetAuthenticationResult_Override setAuthenticationResultOverride(authResultOverride);\r\n\r\n    // Search should fail with access denied\r\n    HttpClientHelper helper{ GetHeaderVerificationHandler(web::http::status_codes::OK, SampleSearchResponse, { web::http::header_names::authorization, JSON::GetUtilityString(CreateBearerToken(expectedToken)) }, web::http::status_codes::Unauthorized) };\r\n    Interface v1_7{ TestRestUriString, std::move(helper), GetTestSourceInformation(), {}, GetTestAuthenticationArguments() };\r\n    SearchRequest request;\r\n    PackageMatchFilter filter{ PackageMatchField::Name, MatchType::Exact, \"package\" };\r\n    request.Filters.emplace_back(std::move(filter));\r\n    REQUIRE_THROWS_HR(v1_7.Search(request), HTTP_E_STATUS_DENIED);\r\n}\r\n\r\nTEST_CASE(\"GetManifests_GoodResponse_V1_7\", \"[RestSource][Interface_1_7]\")\r\n{\r\n    GoodManifest_AllFields sampleManifest;\r\n    utility::string_t sample = sampleManifest.GetSampleManifest_AllFields();\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) };\r\n    Interface v1_7{ TestRestUriString, std::move(helper), {} };\r\n    std::vector<AppInstaller::Manifest::Manifest> manifests = v1_7.GetManifests(\"Foo.Bar\");\r\n    REQUIRE(manifests.size() == 1);\r\n\r\n    // Verify manifest is populated\r\n    AppInstaller::Manifest::Manifest& manifest = manifests[0];\r\n    REQUIRE(manifest.Id == \"Foo.Bar\");\r\n    REQUIRE(manifest.Version == \"3.0.0abc\");\r\n    REQUIRE(manifest.Moniker == \"FooBarMoniker\");\r\n    REQUIRE(manifest.Channel == \"\");\r\n    REQUIRE(manifest.ManifestVersion == AppInstaller::Manifest::ManifestVer{ \"1.7.0\" });\r\n    sampleManifest.VerifyLocalizations_AllFields(manifest);\r\n    sampleManifest.VerifyInstallers_AllFields(manifest);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/RestInterface_1_9.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestRestRequestHandler.h\"\r\n#include <Rest/Schema/1_9/Interface.h>\r\n#include <Rest/Schema/IRestClient.h>\r\n#include <AppInstallerVersions.h>\r\n#include <AppInstallerErrors.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::Http;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Repository::Rest;\r\nusing namespace AppInstaller::Repository::Rest::Schema;\r\nusing namespace AppInstaller::Repository::Rest::Schema::V1_9;\r\n\r\nnamespace\r\n{\r\n    const std::string TestRestUriString = \"http://restsource.com/api\";\r\n\r\n    struct GoodManifest_AllFields\r\n    {\r\n        utility::string_t GetSampleManifest_AllFields()\r\n        {\r\n            return _XPLATSTR(\r\n                R\"delimiter(\r\n        {\r\n          \"Data\": {\r\n            \"PackageIdentifier\": \"Foo.Bar\",\r\n            \"Versions\": [\r\n              {\r\n                \"PackageVersion\": \"3.0.0abc\",\r\n                \"DefaultLocale\": {\r\n                  \"PackageLocale\": \"en-US\",\r\n                  \"Publisher\": \"Foo\",\r\n                  \"PublisherUrl\": \"http://publisher.net\",\r\n                  \"PublisherSupportUrl\": \"http://publisherSupport.net\",\r\n                  \"PrivacyUrl\": \"http://packagePrivacyUrl.net\",\r\n                  \"Author\": \"FooBar\",\r\n                  \"PackageName\": \"Bar\",\r\n                  \"PackageUrl\": \"http://packageUrl.net\",\r\n                  \"License\": \"Foo Bar License\",\r\n                  \"LicenseUrl\": \"http://licenseUrl.net\",\r\n                  \"Copyright\": \"Foo Bar Copyright\",\r\n                  \"CopyrightUrl\": \"http://copyrightUrl.net\",\r\n                  \"ShortDescription\": \"Foo bar is a foo bar.\",\r\n                  \"Description\": \"Foo bar is a placeholder.\",\r\n                  \"Tags\": [\r\n                    \"FooBar\",\r\n                    \"Foo\",\r\n                    \"Bar\"\r\n                  ],\r\n                  \"Moniker\": \"FooBarMoniker\",\r\n                  \"ReleaseNotes\": \"Default release notes\",\r\n                  \"ReleaseNotesUrl\": \"https://DefaultReleaseNotes.net\",\r\n                  \"Agreements\": [{\r\n                    \"AgreementLabel\": \"DefaultLabel\",\r\n                    \"Agreement\": \"DefaultText\",\r\n                    \"AgreementUrl\": \"https://DefaultAgreementUrl.net\"\r\n                  }],\r\n                  \"PurchaseUrl\": \"http://DefaultPurchaseUrl.net\",\r\n                  \"InstallationNotes\": \"Default Installation Notes\",\r\n                  \"Documentations\": [{\r\n                    \"DocumentLabel\": \"Default Document Label\",\r\n                    \"DocumentUrl\": \"http://DefaultDocumentUrl.net\"\r\n                  }],\r\n                  \"Icons\": [{\r\n                    \"IconUrl\": \"https://DefaultTestIcon\",\r\n                    \"IconFileType\": \"ico\",\r\n                    \"IconResolution\": \"custom\",\r\n                    \"IconTheme\": \"default\",\r\n                    \"IconSha256\": \"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\"\r\n                  }]\r\n                },\r\n                \"Channel\": \"\",\r\n                \"Locales\": [\r\n                  {\r\n                    \"PackageLocale\": \"fr-Fr\",\r\n                    \"Publisher\": \"Foo French\",\r\n                    \"PublisherUrl\": \"http://publisher-fr.net\",\r\n                    \"PublisherSupportUrl\": \"http://publisherSupport-fr.net\",\r\n                    \"PrivacyUrl\": \"http://packagePrivacyUrl-fr.net\",\r\n                    \"Author\": \"FooBar French\",\r\n                    \"PackageName\": \"Bar\",\r\n                    \"PackageUrl\": \"http://packageUrl-fr.net\",\r\n                    \"License\": \"Foo Bar License\",\r\n                    \"LicenseUrl\": \"http://licenseUrl-fr.net\",\r\n                    \"Copyright\": \"Foo Bar Copyright\",\r\n                    \"CopyrightUrl\": \"http://copyrightUrl-fr.net\",\r\n                    \"ShortDescription\": \"Foo bar is a foo bar French.\",\r\n                    \"Description\": \"Foo bar is a placeholder French.\",\r\n                    \"Tags\": [\r\n                      \"FooBarFr\",\r\n                      \"FooFr\",\r\n                      \"BarFr\"\r\n                    ],\r\n                    \"ReleaseNotes\": \"Release notes\",\r\n                    \"ReleaseNotesUrl\": \"https://ReleaseNotes.net\",\r\n                    \"Agreements\": [{\r\n                      \"AgreementLabel\": \"Label\",\r\n                      \"Agreement\": \"Text\",\r\n                      \"AgreementUrl\": \"https://AgreementUrl.net\"\r\n                    }],\r\n                    \"PurchaseUrl\": \"http://purchaseUrl.net\",\r\n                    \"InstallationNotes\": \"Installation Notes\",\r\n                    \"Documentations\": [{\r\n                      \"DocumentLabel\": \"Document Label\",\r\n                      \"DocumentUrl\": \"http://documentUrl.net\"\r\n                    }],\r\n                    \"Icons\": [{\r\n                      \"IconUrl\": \"https://testIcon\",\r\n                      \"IconFileType\": \"png\",\r\n                      \"IconResolution\": \"32x32\",\r\n                      \"IconTheme\": \"light\",\r\n                      \"IconSha256\": \"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321\"\r\n                    }]\r\n                  }\r\n                ],)delimiter\") _XPLATSTR(R\"delimiter(\r\n                \"Installers\": [\r\n                  {\r\n                    \"InstallerSha256\": \"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\",\r\n                    \"InstallerUrl\": \"http://foobar.zip\",\r\n                    \"Architecture\": \"x86\",\r\n                    \"InstallerLocale\": \"en-US\",\r\n                    \"Platform\": [\r\n                      \"Windows.Desktop\"\r\n                    ],\r\n                    \"MinimumOSVersion\": \"1078\",\r\n                    \"InstallerType\": \"zip\",\r\n                    \"Scope\": \"user\",\r\n                    \"InstallModes\": [\r\n                      \"interactive\"\r\n                    ],\r\n                    \"InstallerSwitches\": {\r\n                      \"Silent\": \"/s\",\r\n                      \"SilentWithProgress\": \"/s\",\r\n                      \"Interactive\": \"/i\",\r\n                      \"InstallLocation\": \"C:\\\\Users\\\\User1\",\r\n                      \"Log\": \"/l\",\r\n                      \"Upgrade\": \"/u\",\r\n                      \"Custom\": \"/custom\",\r\n                      \"Repair\": \"/repair\"\r\n                    },\r\n                    \"InstallerSuccessCodes\": [\r\n                      0\r\n                    ],\r\n                    \"UpgradeBehavior\": \"deny\",\r\n                    \"Commands\": [\r\n                      \"command1\"\r\n                    ],\r\n                    \"Protocols\": [\r\n                       \"protocol1\"\r\n                    ],\r\n                    \"FileExtensions\": [\r\n                      \".file-extension\"\r\n                    ],\r\n                    \"Dependencies\": {\r\n                      \"WindowsFeatures\": [\r\n                        \"feature1\"\r\n                      ],\r\n                      \"WindowsLibraries\": [\r\n                        \"library1\"\r\n                      ],\r\n                      \"PackageDependencies\": [\r\n                        {\r\n                          \"PackageIdentifier\": \"Foo.Baz\",\r\n                          \"MinimumVersion\": \"2.0.0\"\r\n                        }\r\n                      ],\r\n                      \"ExternalDependencies\": [\r\n                        \"FooBarBaz\"\r\n                      ]\r\n                    },\r\n                    \"ProductCode\": \"5b6e0f8a-3bbf-4a17-aefd-024c2b3e075d\",\r\n                    \"ReleaseDate\": \"2021-01-01\",\r\n                    \"InstallerAbortsTerminal\": true,\r\n                    \"InstallLocationRequired\": true,\r\n                    \"RequireExplicitUpgrade\": true,\r\n                    \"UnsupportedOSArchitectures\": [ \"arm\" ],\r\n                    \"ElevationRequirement\": \"elevatesSelf\",\r\n                    \"AppsAndFeaturesEntries\": [{\r\n                      \"DisplayName\": \"DisplayName\",\r\n                      \"DisplayVersion\": \"DisplayVersion\",\r\n                      \"Publisher\": \"Publisher\",\r\n                      \"ProductCode\": \"ProductCode\",\r\n                      \"UpgradeCode\": \"UpgradeCode\",\r\n                      \"InstallerType\": \"exe\"\r\n                    }],\r\n                    \"Markets\" : {\r\n                      \"AllowedMarkets\": [ \"US\" ]\r\n                    },\r\n                    \"ExpectedReturnCodes\": [{\r\n                      \"InstallerReturnCode\": 3,\r\n                      \"ReturnResponse\": \"custom\",\r\n                      \"ReturnResponseUrl\": \"http://returnResponseUrl.net\"\r\n                    }],\r\n                    \"NestedInstallerType\": \"portable\",\r\n                    \"DisplayInstallWarnings\": true,\r\n                    \"UnsupportedArguments\": [ \"log\" ],\r\n                    \"NestedInstallerFiles\": [{\r\n                      \"RelativeFilePath\": \"test\\\\app.exe\",\r\n                      \"PortableCommandAlias\": \"test.exe\"\r\n                    }],\r\n                    \"InstallationMetadata\": {\r\n                      \"DefaultInstallLocation\": \"%TEMP%\\\\DefaultInstallLocation\",\r\n                      \"Files\": [{\r\n                        \"RelativeFilePath\": \"test\\\\app.exe\",\r\n                        \"FileSha256\": \"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\",\r\n                        \"FileType\": \"launch\",\r\n                        \"InvocationParameter\": \"/parameter\",\r\n                        \"DisplayName\": \"test\"\r\n                      }]\r\n                    },\r\n                    \"DownloadCommandProhibited\": true,\r\n                    \"RepairBehavior\": \"uninstaller\",\r\n                    \"ArchiveBinariesDependOnPath\": true\r\n                  }\r\n                ]\r\n              }\r\n            ]\r\n          },\r\n          \"ContinuationToken\": \"abcd\"\r\n        })delimiter\");\r\n        }\r\n\r\n        void VerifyLocalizations_AllFields(const AppInstaller::Manifest::Manifest& manifest)\r\n        {\r\n            REQUIRE(manifest.DefaultLocalization.Locale == \"en-US\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Publisher>() == \"Foo\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PublisherUrl>() == \"http://publisher.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PublisherSupportUrl>() == \"http://publisherSupport.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PrivacyUrl>() == \"http://packagePrivacyUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Author>() == \"FooBar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageName>() == \"Bar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageUrl>() == \"http://packageUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::License>() == \"Foo Bar License\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::LicenseUrl>() == \"http://licenseUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Copyright>() == \"Foo Bar Copyright\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::CopyrightUrl>() == \"http://copyrightUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ShortDescription>() == \"Foo bar is a foo bar.\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Description>() == \"Foo bar is a placeholder.\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().size() == 3);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(0) == \"FooBar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(1) == \"Foo\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>().at(2) == \"Bar\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ReleaseNotes>() == \"Default release notes\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ReleaseNotesUrl>() == \"https://DefaultReleaseNotes.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().size() == 1);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).Label == \"DefaultLabel\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).AgreementText == \"DefaultText\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).AgreementUrl == \"https://DefaultAgreementUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PurchaseUrl>() == \"http://DefaultPurchaseUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::InstallationNotes>() == \"Default Installation Notes\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().size() == 1);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().at(0).DocumentLabel == \"Default Document Label\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().at(0).DocumentUrl == \"http://DefaultDocumentUrl.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().size() == 1);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Url == \"https://DefaultTestIcon\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).FileType == IconFileTypeEnum::Ico);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Resolution == IconResolutionEnum::Custom);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Theme == IconThemeEnum::Default);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\"));\r\n\r\n            REQUIRE(manifest.Localizations.size() == 1);\r\n            ManifestLocalization frenchLocalization = manifest.Localizations.at(0);\r\n            REQUIRE(frenchLocalization.Locale == \"fr-Fr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Publisher>() == \"Foo French\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PublisherUrl>() == \"http://publisher-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PublisherSupportUrl>() == \"http://publisherSupport-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PrivacyUrl>() == \"http://packagePrivacyUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Author>() == \"FooBar French\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PackageName>() == \"Bar\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PackageUrl>() == \"http://packageUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::License>() == \"Foo Bar License\");\r\n            REQUIRE(frenchLocalization.Get<Localization::LicenseUrl>() == \"http://licenseUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Copyright>() == \"Foo Bar Copyright\");\r\n            REQUIRE(frenchLocalization.Get<Localization::CopyrightUrl>() == \"http://copyrightUrl-fr.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::ShortDescription>() == \"Foo bar is a foo bar French.\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Description>() == \"Foo bar is a placeholder French.\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().size() == 3);\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(0) == \"FooBarFr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(1) == \"FooFr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Tags>().at(2) == \"BarFr\");\r\n            REQUIRE(frenchLocalization.Get<Localization::ReleaseNotes>() == \"Release notes\");\r\n            REQUIRE(frenchLocalization.Get<Localization::ReleaseNotesUrl>() == \"https://ReleaseNotes.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().size() == 1);\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).Label == \"Label\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).AgreementText == \"Text\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Agreements>().at(0).AgreementUrl == \"https://AgreementUrl.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::PurchaseUrl>() == \"http://purchaseUrl.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::InstallationNotes>() == \"Installation Notes\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Documentations>().size() == 1);\r\n            REQUIRE(frenchLocalization.Get<Localization::Documentations>().at(0).DocumentLabel == \"Document Label\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Documentations>().at(0).DocumentUrl == \"http://documentUrl.net\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().size() == 1);\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Url == \"https://testIcon\");\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).FileType == IconFileTypeEnum::Png);\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Resolution == IconResolutionEnum::Square32);\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Theme == IconThemeEnum::Light);\r\n            REQUIRE(frenchLocalization.Get<Localization::Icons>().at(0).Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321\"));\r\n        }\r\n\r\n        void VerifyInstallers_AllFields(const AppInstaller::Manifest::Manifest& manifest)\r\n        {\r\n            REQUIRE(manifest.Installers.size() == 1);\r\n\r\n            ManifestInstaller actualInstaller = manifest.Installers.at(0);\r\n            REQUIRE(actualInstaller.Sha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\"));\r\n            REQUIRE(actualInstaller.Url == \"http://foobar.zip\");\r\n            REQUIRE(actualInstaller.Arch == Architecture::X86);\r\n            REQUIRE(actualInstaller.Locale == \"en-US\");\r\n            REQUIRE(actualInstaller.Platform.size() == 1);\r\n            REQUIRE(actualInstaller.Platform[0] == PlatformEnum::Desktop);\r\n            REQUIRE(actualInstaller.MinOSVersion == \"1078\");\r\n            REQUIRE(actualInstaller.BaseInstallerType == InstallerTypeEnum::Zip);\r\n            REQUIRE(actualInstaller.Scope == ScopeEnum::User);\r\n            REQUIRE(actualInstaller.InstallModes.size() == 1);\r\n            REQUIRE(actualInstaller.InstallModes.at(0) == InstallModeEnum::Interactive);\r\n            REQUIRE(actualInstaller.Switches.size() == 8);\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Silent) == \"/s\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::SilentWithProgress) == \"/s\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Interactive) == \"/i\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::InstallLocation) == \"C:\\\\Users\\\\User1\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Log) == \"/l\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Update) == \"/u\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Custom) == \"/custom\");\r\n            REQUIRE(actualInstaller.Switches.at(InstallerSwitchType::Repair) == \"/repair\");\r\n            REQUIRE(actualInstaller.InstallerSuccessCodes.size() == 1);\r\n            REQUIRE(actualInstaller.InstallerSuccessCodes.at(0) == 0);\r\n            REQUIRE(actualInstaller.UpdateBehavior == UpdateBehaviorEnum::Deny);\r\n            REQUIRE(actualInstaller.Commands.at(0) == \"command1\");\r\n            REQUIRE(actualInstaller.Protocols.at(0) == \"protocol1\");\r\n            REQUIRE(actualInstaller.FileExtensions.at(0) == \".file-extension\");\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::WindowsFeature, \"feature1\"));\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::WindowsLibrary, \"library1\"));\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::Package, \"Foo.Baz\", \"2.0.0\"));\r\n            REQUIRE(actualInstaller.Dependencies.HasExactDependency(DependencyType::External, \"FooBarBaz\"));\r\n            REQUIRE(actualInstaller.PackageFamilyName == \"\");\r\n            REQUIRE(actualInstaller.ProductCode == \"5b6e0f8a-3bbf-4a17-aefd-024c2b3e075d\");\r\n            REQUIRE(actualInstaller.ReleaseDate == \"2021-01-01\");\r\n            REQUIRE(actualInstaller.InstallerAbortsTerminal);\r\n            REQUIRE(actualInstaller.InstallLocationRequired);\r\n            REQUIRE(actualInstaller.RequireExplicitUpgrade);\r\n            REQUIRE(actualInstaller.ElevationRequirement == ElevationRequirementEnum::ElevatesSelf);\r\n            REQUIRE(actualInstaller.UnsupportedOSArchitectures.size() == 1);\r\n            REQUIRE(actualInstaller.UnsupportedOSArchitectures.at(0) == Architecture::Arm);\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.size() == 1);\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).DisplayName == \"DisplayName\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).DisplayVersion == \"DisplayVersion\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).Publisher == \"Publisher\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).ProductCode == \"ProductCode\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).UpgradeCode == \"UpgradeCode\");\r\n            REQUIRE(actualInstaller.AppsAndFeaturesEntries.at(0).InstallerType == InstallerTypeEnum::Exe);\r\n            REQUIRE(actualInstaller.Markets.AllowedMarkets.size() == 1);\r\n            REQUIRE(actualInstaller.Markets.AllowedMarkets.at(0) == \"US\");\r\n            REQUIRE(actualInstaller.ExpectedReturnCodes.at(3).ReturnResponseEnum == ExpectedReturnCodeEnum::Custom);\r\n            REQUIRE(actualInstaller.ExpectedReturnCodes.at(3).ReturnResponseUrl == \"http://returnResponseUrl.net\");\r\n            REQUIRE(actualInstaller.NestedInstallerType == InstallerTypeEnum::Portable);\r\n            REQUIRE(actualInstaller.DisplayInstallWarnings);\r\n            REQUIRE(actualInstaller.UnsupportedArguments.size() == 1);\r\n            REQUIRE(actualInstaller.UnsupportedArguments.at(0) == UnsupportedArgumentEnum::Log);\r\n            REQUIRE(actualInstaller.NestedInstallerFiles.size() == 1);\r\n            REQUIRE(actualInstaller.NestedInstallerFiles.at(0).RelativeFilePath == \"test\\\\app.exe\");\r\n            REQUIRE(actualInstaller.NestedInstallerFiles.at(0).PortableCommandAlias == \"test.exe\");\r\n            REQUIRE(actualInstaller.InstallationMetadata.DefaultInstallLocation == \"%TEMP%\\\\DefaultInstallLocation\");\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.size() == 1);\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).RelativeFilePath == \"test\\\\app.exe\");\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).FileType == InstalledFileTypeEnum::Launch);\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).FileSha256 == AppInstaller::Utility::SHA256::ConvertToBytes(\"011048877dfaef109801b3f3ab2b60afc74f3fc4f7b3430e0c897f5da1df84b6\"));\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).InvocationParameter == \"/parameter\");\r\n            REQUIRE(actualInstaller.InstallationMetadata.Files.at(0).DisplayName == \"test\");\r\n            REQUIRE(actualInstaller.DownloadCommandProhibited);\r\n            REQUIRE(actualInstaller.RepairBehavior == RepairBehaviorEnum::Uninstaller);\r\n            REQUIRE(actualInstaller.ArchiveBinariesDependOnPath);\r\n        }\r\n    };\r\n}\r\n\r\nTEST_CASE(\"GetManifests_GoodResponse_V1_9\", \"[RestSource][Interface_1_9]\")\r\n{\r\n    GoodManifest_AllFields sampleManifest;\r\n    utility::string_t sample = sampleManifest.GetSampleManifest_AllFields();\r\n    HttpClientHelper helper{ GetTestRestRequestHandler(web::http::status_codes::OK, std::move(sample)) };\r\n    Interface v1_9{ TestRestUriString, std::move(helper), {} };\r\n    std::vector<Manifest> manifests = v1_9.GetManifests(\"Foo.Bar\");\r\n    REQUIRE(manifests.size() == 1);\r\n\r\n    // Verify manifest is populated\r\n    Manifest& manifest = manifests[0];\r\n    REQUIRE(manifest.Id == \"Foo.Bar\");\r\n    REQUIRE(manifest.Version == \"3.0.0abc\");\r\n    REQUIRE(manifest.Moniker == \"FooBarMoniker\");\r\n    REQUIRE(manifest.Channel == \"\");\r\n    REQUIRE(manifest.ManifestVersion == AppInstaller::Manifest::ManifestVer{ \"1.9.0\" });\r\n    sampleManifest.VerifyLocalizations_AllFields(manifest);\r\n    sampleManifest.VerifyInstallers_AllFields(manifest);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/ResumeFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"WorkflowCommon.h\"\n#include \"TestHooks.h\"\n#include <Commands/InstallCommand.h>\n#include <Commands/ResumeCommand.h>\n#include <AppInstallerRuntime.h>\n#include <AppInstallerStrings.h>\n#include <AppInstallerVersions.h>\n#include <CheckpointManager.h>\n#include <Workflows/ShellExecuteInstallerHandler.h>\n\nusing namespace std::string_literals;\nusing namespace AppInstaller::CLI;\nusing namespace AppInstaller::Repository::Microsoft;\nusing namespace AppInstaller::Settings;\nusing namespace AppInstaller::Runtime;\nusing namespace TestCommon;\nusing namespace AppInstaller::Checkpoints;\n\nconstexpr std::string_view s_AutomaticCheckpoint = \"automatic\"sv;\nconstexpr std::string_view s_CheckpointsFileName = \"checkpoints.db\"sv;\n\nTEST_CASE(\"ResumeFlow_IndexNotFound\", \"[Resume]\")\n{\n    std::string tempGuidString = \"{ec3a098c-a815-4d52-8866-946c03093a37}\";\n\n    std::ostringstream resumeOutput;\n    TestContext context{ resumeOutput, std::cin };\n    auto previousThreadGlobals = context.SetForCurrentThread();\n    context.Args.AddArg(Execution::Args::Type::ResumeId, tempGuidString);\n\n    ResumeCommand resume({});\n    context.SetExecutingCommand(&resume);\n    resume.Execute(context);\n    INFO(resumeOutput.str());\n\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_RESUME_ID_NOT_FOUND);\n    auto expectedMessage = Resource::String::ResumeIdNotFoundError(AppInstaller::Utility::LocIndString(tempGuidString));\n    REQUIRE(resumeOutput.str().find(Resource::LocString(expectedMessage).get()) != std::string::npos);\n}\n\nTEST_CASE(\"ResumeFlow_InvalidClientVersion\", \"[Resume]\")\n{\n    TestCommon::TempDirectory tempCheckpointRecordDirectory(\"TempCheckpointRecordDirectory\", true);\n\n    const auto& tempCheckpointRecordDirectoryPath = tempCheckpointRecordDirectory.GetPath();\n    TestHook_SetPathOverride(PathName::CheckpointsLocation, tempCheckpointRecordDirectoryPath);\n\n    // Create temp guid and populate with invalid client version.\n    std::string tempGuidString = \"{615339e9-3ac5-4e86-a5ab-c246657aca25}\";\n    auto tempRecordPath = tempCheckpointRecordDirectoryPath / tempGuidString / s_CheckpointsFileName;\n    std::string_view invalidClientVersion = \"1.2.3.4\"sv;\n\n    INFO(\"Using temporary file named: \" << tempRecordPath);\n\n    {\n        // Manually set invalid client version\n        std::filesystem::create_directories(tempRecordPath.parent_path());\n        std::shared_ptr<CheckpointDatabase> checkpointRecord = CheckpointDatabase::CreateNew(tempRecordPath.u8string());\n        CheckpointDatabase::IdType checkpointId = checkpointRecord->AddCheckpoint(s_AutomaticCheckpoint);\n        checkpointRecord->SetDataValue(checkpointId, AutomaticCheckpointData::ClientVersion, {}, { \"1.2.3.4\" });\n    }\n\n    std::ostringstream resumeOutput;\n    TestContext context{ resumeOutput, std::cin };\n    auto previousThreadGlobals = context.SetForCurrentThread();\n    context.Args.AddArg(Execution::Args::Type::ResumeId, tempGuidString);\n\n    ResumeCommand resume({});\n    context.SetExecutingCommand(&resume);\n    resume.Execute(context);\n    INFO(resumeOutput.str());\n\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_CLIENT_VERSION_MISMATCH);\n    auto expectedMessage = Resource::String::ClientVersionMismatchError(AppInstaller::Utility::LocIndString(invalidClientVersion));\n    REQUIRE(resumeOutput.str().find(Resource::LocString(expectedMessage).get()) != std::string::npos);\n}\n\nTEST_CASE(\"ResumeFlow_EmptyIndex\", \"[Resume]\")\n{\n    TestCommon::TempDirectory tempCheckpointRecordDirectory(\"TempCheckpointRecordDirectory\", true);\n\n    const auto& tempCheckpointRecordDirectoryPath = tempCheckpointRecordDirectory.GetPath();\n    TestHook_SetPathOverride(PathName::CheckpointsLocation, tempCheckpointRecordDirectoryPath);\n\n    std::string tempGuidString = \"{43ca664c-3eae-4f73-99ee-18cf83912c02}\";\n    auto tempRecordPath = tempCheckpointRecordDirectoryPath / tempGuidString / s_CheckpointsFileName;\n\n    INFO(\"Using temporary file named: \" << tempRecordPath);\n\n    {\n        std::filesystem::create_directories(tempRecordPath.parent_path());\n        CheckpointDatabase::CreateNew(tempRecordPath.u8string());\n    }\n\n    std::ostringstream resumeOutput;\n    TestContext context{ resumeOutput, std::cin };\n    auto previousThreadGlobals = context.SetForCurrentThread();\n    context.Args.AddArg(Execution::Args::Type::ResumeId, tempGuidString);\n\n    ResumeCommand resume({});\n    context.SetExecutingCommand(&resume);\n    resume.Execute(context);\n    INFO(resumeOutput.str());\n\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_INVALID_RESUME_STATE);\n    REQUIRE(resumeOutput.str().find(Resource::LocString(Resource::String::ResumeStateDataNotFoundError).get()) != std::string::npos);\n}\n\nTEST_CASE(\"ResumeFlow_InstallSuccess\", \"[Resume]\")\n{\n    TestCommon::TempDirectory tempCheckpointRecordDirectory(\"TempCheckpointRecordDirectory\", false);\n\n    const auto& tempCheckpointRecordDirectoryPath = tempCheckpointRecordDirectory.GetPath();\n    TestHook_SetPathOverride(PathName::CheckpointsLocation, tempCheckpointRecordDirectoryPath);\n\n    TestCommon::TestUserSettings testSettings;\n    testSettings.Set<Setting::EFResume>(true);\n\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\n\n    {\n        std::ostringstream installOutput;\n        TestContext context{ installOutput, std::cin };\n        auto previousThreadGlobals = context.SetForCurrentThread();\n        OverrideForShellExecute(context);\n\n        const auto& testManifestPath = TestDataFile(\"InstallFlowTest_Exe.yaml\").GetPath().u8string();\n        context.Args.AddArg(Execution::Args::Type::Manifest, testManifestPath);\n\n        InstallCommand install({});\n        context.SetExecutingCommand(&install);\n        install.Execute(context);\n        INFO(installOutput.str());\n    }\n    \n    // Verify Installer is called and parameters are passed in.\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\n    std::ifstream installResultFile(installResultPath.GetPath());\n    REQUIRE(installResultFile.is_open());\n    std::string installResultStr;\n    std::getline(installResultFile, installResultStr);\n    REQUIRE(installResultStr.find(\"/custom\") != std::string::npos);\n    REQUIRE(installResultStr.find(\"/silentwithprogress\") != std::string::npos);\n\n    // The checkpoint index should not exist if the context succeeded.\n    std::vector<std::filesystem::path> checkpointFiles;\n    for (const auto& entry : std::filesystem::directory_iterator(tempCheckpointRecordDirectoryPath))\n    {\n        checkpointFiles.emplace_back(entry.path());\n    }\n\n    REQUIRE(checkpointFiles.size() == 0);\n}\n\nTEST_CASE(\"ResumeFlow_InstallFailure\", \"[Resume]\")\n{\n    TestCommon::TempDirectory tempCheckpointRecordDirectory(\"TempCheckpointRecordDirectory\", false);\n\n    const auto& tempCheckpointRecordDirectoryPath = tempCheckpointRecordDirectory.GetPath();\n    TestHook_SetPathOverride(PathName::CheckpointsLocation, tempCheckpointRecordDirectoryPath);\n\n    TestCommon::TestUserSettings testSettings;\n    testSettings.Set<Setting::EFResume>(true);\n\n    {\n        std::ostringstream installOutput;\n        TestContext context{ installOutput, std::cin };\n        auto previousThreadGlobals = context.SetForCurrentThread();\n\n        const auto& testManifestPath = TestDataFile(\"InstallFlowTest_UnsupportedArguments.yaml\").GetPath().u8string();\n        context.Args.AddArg(Execution::Args::Type::Manifest, testManifestPath);\n        context.Args.AddArg(Execution::Args::Type::InstallLocation, \"installLocation\"sv);\n\n        InstallCommand install({});\n        context.SetExecutingCommand(&install);\n        install.Execute(context);\n        INFO(installOutput.str());\n\n        // Verify unsupported arguments error message is shown \n        REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_UNSUPPORTED_ARGUMENT);\n    }\n\n    // Checkpoint file should be cleaned up if the hr is not reboot related.\n    REQUIRE(std::filesystem::is_empty(tempCheckpointRecordDirectoryPath));\n}\n\n\nTEST_CASE(\"ResumeFlow_WriteToRunOnceRegistry\", \"[Reboot][Resume][windowsFeature]\")\n{\n    if (!AppInstaller::Runtime::IsRunningAsAdmin())\n    {\n        WARN(\"Test requires admin privilege. Skipped.\");\n        return;\n    }\n\n    TestCommon::TempDirectory tempCheckpointRecordDirectory(\"TempCheckpointRecordDirectory\", false);\n\n    const auto& tempCheckpointRecordDirectoryPath = tempCheckpointRecordDirectory.GetPath();\n    TestHook_SetPathOverride(PathName::CheckpointsLocation, tempCheckpointRecordDirectoryPath);\n\n    TestCommon::TestUserSettings testSettings;\n    testSettings.Set<Setting::EFResume>(true);\n\n    std::ostringstream installOutput;\n    TestContext context{ installOutput, std::cin };\n    auto previousThreadGlobals = context.SetForCurrentThread();\n    OverrideOpenDependencySource(context);\n    OverrideRegisterStartupAfterReboot(context);\n\n    // Override with reboot required HRESULT.\n    auto doesFeatureExistOverride = TestHook::SetDoesWindowsFeatureExistResult_Override(ERROR_SUCCESS);\n    auto setEnableFeatureOverride = TestHook::SetEnableWindowsFeatureResult_Override(ERROR_SUCCESS_REBOOT_REQUIRED);\n    TestHook::SetRegisterForRestartResult_Override registerForRestartResultOverride(false);\n    TestHook::SetInitiateRebootResult_Override initiateRebootResultOverride(false);\n\n    const auto& testManifestPath = TestDataFile(\"InstallFlowTest_WindowsFeatures.yaml\").GetPath().u8string();\n    context.Args.AddArg(Execution::Args::Type::Manifest, testManifestPath);\n    context.Args.AddArg(Execution::Args::Type::AllowReboot);\n\n    InstallCommand install({});\n    install.Execute(context);\n    INFO(installOutput.str());\n\n    REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_FOR_INSTALL);\n}\n\nTEST_CASE(\"ResumeFlow_ResumeLimitExceeded\", \"[Resume]\")\n{\n    if (!AppInstaller::Runtime::IsRunningAsAdmin())\n    {\n        WARN(\"Test requires admin privilege. Skipped.\");\n        return;\n    }\n\n    TestCommon::TempDirectory tempCheckpointsLocationDir(\"TempCheckpointsLocationDir\", true);\n\n    const auto& tempCheckpointRecordDirectoryPath = tempCheckpointsLocationDir.GetPath();\n    TestHook_SetPathOverride(PathName::CheckpointsLocation, tempCheckpointRecordDirectoryPath);\n\n    TestCommon::TestUserSettings testSettings;\n    testSettings.Set<Setting::EFResume>(true);\n    testSettings.Set<Setting::MaxResumes>(1);\n\n    std::filesystem::path testResumeId = L\"testResumeId\";\n    std::filesystem::path tempResumeDir = tempCheckpointRecordDirectoryPath / testResumeId;\n    std::filesystem::path tempCheckpointDatabasePath = tempResumeDir / L\"checkpoints.db\";\n    std::filesystem::create_directory(tempResumeDir);\n\n    {\n        std::shared_ptr<CheckpointDatabase> database = CheckpointDatabase::CreateNew(tempCheckpointDatabasePath.u8string(), {1, 0});\n        std::string_view testCheckpointName = \"testCheckpoint\"sv;\n\n        CheckpointDatabase::IdType checkpointId = database->AddCheckpoint(testCheckpointName);\n        database->SetDataValue(checkpointId, AutomaticCheckpointData::Command, {}, { \"install\" });\n        database->SetDataValue(checkpointId, AutomaticCheckpointData::ClientVersion, {}, { GetClientVersion()});\n        database->SetDataValue(checkpointId, AutomaticCheckpointData::ResumeCount, {}, {\"1\"});\n    }\n\n    {\n        std::ostringstream resumeOutput;\n        TestContext resumeContext{ resumeOutput, std::cin };\n        auto previousThreadGlobals = resumeContext.SetForCurrentThread();\n        resumeContext.Args.AddArg(Execution::Args::Type::ResumeId, testResumeId.u8string());\n\n        ResumeCommand resume({});\n        resume.Execute(resumeContext);\n        INFO(resumeOutput.str());\n        REQUIRE(resumeContext.IsTerminated());\n        REQUIRE(resumeContext.GetTerminationHR() == APPINSTALLER_CLI_ERROR_RESUME_LIMIT_EXCEEDED);\n\n        REQUIRE(resumeOutput.str().find(Resource::LocString(Resource::String::ResumeLimitExceeded('1')).get()) != std::string::npos);\n        REQUIRE(resumeOutput.str().find(\"winget resume -g \" + testResumeId.u8string() + \" --ignore-resume-limit\") != std::string::npos);\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLITests/Run-TestsInPackage.ps1",
    "content": "<#\r\n.SYNOPSIS\r\n    Runs the AppInstallerCLI tests within the packaged context.\r\n.DESCRIPTION\r\n    Registers the loose files generated by the AppInstallerCLIPackage project, then runs the\r\n    existing tests from \"within\" this context.\r\n.PARAMETER BuildRoot\r\n    The root of the build output directory.  If not provided, assumed to be the local default\r\n    location relative to this script.\r\n.PARAMETER PackageRoot\r\n    The root of the package build output directory.  If not provided, assumed to be the local default\r\n    location relative to this script.\r\n.PARAMETER LogTarget\r\n    The file path to log to.\r\n.PARAMETER MdmpTarget\r\n    The path to write a minidump to if the tests crash.\r\n.PARAMETER TestResultsTarget\r\n    The file path to place the test result file in.\r\n.PARAMETER Args\r\n    Additional args to pass to the tests.\r\n.PARAMETER Wait\r\n    Have the test process wait for user input before exiting.\r\n.PARAMETER ScriptWait\r\n    Have the script wait for the output files to be freed before exiting.\r\n#>\r\nparam(\r\n    [Parameter(Mandatory=$false)]\r\n    [string]$BuildRoot,\r\n    \r\n    [Parameter(Mandatory=$false)]\r\n    [string]$PackageRoot,\r\n    \r\n    [Parameter(Mandatory=$false)]\r\n    [string]$LogTarget,\r\n    \r\n    [Parameter(Mandatory=$false)]\r\n    [string]$MdmpTarget,\r\n    \r\n    [Parameter(Mandatory=$false)]\r\n    [string]$TestResultsTarget,\r\n\r\n    [Parameter(Mandatory=$false)]\r\n    [string]$Args,\r\n\r\n    [switch]$Wait,\r\n\r\n    [switch]$ScriptWait\r\n)\r\n\r\nfunction Wait-ForFileClose([string]$Path)\r\n{\r\n    $Local:FileInfo = [System.IO.FileInfo]::new($Path)\r\n    $Local:SleepCount = 0\r\n    $Local:SleepCountMax = 600\r\n\r\n    while ($Local:SleepCount -lt $Local:SleepCountMax)\r\n    {\r\n        try\r\n        {\r\n            [System.IO.FileStream] $Local:Stream = $Local:FileInfo.OpenWrite()\r\n            $Local:Stream.Dispose()\r\n            break\r\n        }\r\n        catch\r\n        {\r\n            Start-Sleep 1\r\n            $Local:SleepCount = $Local:SleepCount + 1\r\n        }\r\n    }\r\n\r\n    if ($Local:SleepCount -ge $Local:SleepCountMax)\r\n    {\r\n        throw \"Timed out waiting for file close: $Path\"\r\n    }\r\n}\r\n\r\nif ([String]::IsNullOrEmpty($BuildRoot))\r\n{\r\n    $BuildRoot = Split-Path -Parent $PSCommandPath;\r\n    $BuildRoot = Join-Path $BuildRoot \"..\\x64\\Debug\";\r\n}\r\n$BuildRoot = Resolve-Path $BuildRoot\r\nWrite-Host \"Using BuildRoot = $BuildRoot\"\r\n\r\nif ([String]::IsNullOrEmpty($PackageRoot))\r\n{\r\n    $PackageRoot = Split-Path -Parent $PSCommandPath;\r\n    $PackageRoot = Join-Path $PackageRoot \"..\\AppInstallerCLIPackage\\bin\\x64\\Debug\";\r\n}\r\n$PackageRoot = Resolve-Path $PackageRoot\r\nWrite-Host \"Using PackageRoot = $PackageRoot\"\r\n\r\nif (![String]::IsNullOrEmpty($LogTarget))\r\n{\r\n    $Local:temp = Split-Path -Parent $LogTarget\r\n    $Local:temp = Resolve-Path $Local:temp\r\n    $LogTarget = Join-Path $Local:temp (Split-Path -Leaf $LogTarget)\r\n    Write-Host \"Using LogTarget = $LogTarget\"\r\n}\r\n\r\nif (![String]::IsNullOrEmpty($MdmpTarget))\r\n{\r\n    $Local:temp = Split-Path -Parent $MdmpTarget\r\n    $Local:temp = Resolve-Path $Local:temp\r\n    $MdmpTarget = Join-Path $Local:temp (Split-Path -Leaf $MdmpTarget)\r\n    Write-Host \"Using MdmpTarget = $MdmpTarget\"\r\n}\r\n\r\nif (![String]::IsNullOrEmpty($TestResultsTarget))\r\n{\r\n    $Local:temp = Split-Path -Parent $TestResultsTarget\r\n    $Local:temp = Resolve-Path $Local:temp\r\n    $TestResultsTarget = Join-Path $Local:temp (Split-Path -Leaf $TestResultsTarget)\r\n    Write-Host \"Using TestResultsTarget = $TestResultsTarget\"\r\n}\r\n\r\n# Register the package; this requires the local package to have been deployed at least once or it won't be built.\r\n$Local:ManifestPath = Join-Path $PackageRoot \"AppxManifest.xml\"\r\nif (-not (Test-Path $Local:ManifestPath))\r\n{\r\n    $Local:ManifestPath = Join-Path $PackageRoot \"AppX\\AppxManifest.xml\"\r\n}\r\nWrite-Host \"Registering manifest at path: $Local:ManifestPath\"\r\nAdd-AppxPackage -Register $Local:ManifestPath\r\n\r\n# Execute the tests from within the package's runtime.\r\n$Local:TestExePath = Join-Path $BuildRoot \"AppInstallerCLITests\\AppInstallerCLITests.exe\"\r\n$Local:TestArgs = $Args\r\n\r\nif ([String]::IsNullOrEmpty($LogTarget))\r\n{\r\n    $Local:TestArgs = $Local:TestArgs + \" -log\"\r\n}\r\nelse\r\n{\r\n    $Local:TestArgs = $Local:TestArgs + \" -logto \"\"$LogTarget\"\"\"\r\n}\r\n\r\nif ([String]::IsNullOrEmpty($MdmpTarget))\r\n{\r\n    $Local:TestArgs = $Local:TestArgs + \" -mdmp\"\r\n}\r\nelse\r\n{\r\n    $Local:TestArgs = $Local:TestArgs + \" -mdmpto \"\"$MdmpTarget\"\"\"\r\n}\r\n\r\nif (![String]::IsNullOrEmpty($TestResultsTarget))\r\n{\r\n    $Local:TestArgs = $Local:TestArgs + \" -s -r junit -o \"\"$TestResultsTarget\"\"\"\r\n}\r\n\r\nif ($Wait)\r\n{\r\n    $Local:TestArgs = $Local:TestArgs + \" -wait\"\r\n}\r\n\r\nWrite-Host \"Executing tests at path: $Local:TestExePath\"\r\nWrite-Host \"Executing tests with args: $Local:TestArgs\"\r\nInvoke-CommandInDesktopPackage -PackageFamilyName WinGetDevCLI_8wekyb3d8bbwe -AppId WinGetDev -Command $Local:TestExePath -Args $Local:TestArgs\r\n\r\nif ($ScriptWait)\r\n{\r\n    try\r\n    {\r\n        Write-Host \"Waiting for output files to be closed...\"\r\n        Start-Sleep 5\r\n        if (![String]::IsNullOrEmpty($LogTarget))\r\n        {\r\n            Wait-ForFileClose $LogTarget\r\n        }\r\n\r\n        if (![String]::IsNullOrEmpty($TestResultsTarget))\r\n        {\r\n            Wait-ForFileClose $TestResultsTarget\r\n        }\r\n        Write-Host \"Done\"\r\n    }\r\n    finally\r\n    {\r\n        Write-Host \"Remove registered package\"\r\n        Get-AppxPackage WinGetDevCLI | Remove-AppxPackage\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/Runtime.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestHooks.h\"\r\n#include <AppInstallerRuntime.h>\r\n#include <winget/Filesystem.h>\r\n\r\nusing namespace AppInstaller;\r\nusing namespace AppInstaller::Filesystem;\r\nusing namespace AppInstaller::Runtime;\r\nusing namespace TestCommon;\r\n\r\nbool CanWriteToPath(const std::filesystem::path& directory, const std::filesystem::path& file = \"test.txt\")\r\n{\r\n    std::ofstream out{ directory / file };\r\n    out << \"Test\";\r\n    return out.good();\r\n}\r\n\r\nvoid RequireAdminOwner(const std::filesystem::path& directory)\r\n{\r\n    wil::unique_hlocal_security_descriptor securityDescriptor;\r\n    PSID ownerSID = nullptr;\r\n    THROW_IF_WIN32_ERROR(GetNamedSecurityInfoW(directory.c_str(), SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, &ownerSID, nullptr, nullptr, nullptr, &securityDescriptor));\r\n\r\n    auto adminSID = wil::make_static_sid(SECURITY_NT_AUTHORITY, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS);\r\n    REQUIRE(EqualSid(adminSID.get(), ownerSID));\r\n}\r\n\r\nTEST_CASE(\"ApplyACL_CurrentUserOwner\", \"[runtime]\")\r\n{\r\n    TempDirectory directory(\"CurrentUserOwner\");\r\n    PathDetails details;\r\n    details.Path = directory;\r\n    details.SetOwner(ACEPrincipal::CurrentUser);\r\n\r\n    details.ApplyACL();\r\n\r\n    REQUIRE(CanWriteToPath(directory));\r\n}\r\n\r\nTEST_CASE(\"ApplyACL_RemoveWriteForUser\", \"[runtime]\")\r\n{\r\n    TempDirectory directory(\"CurrentUserCantWrite\");\r\n    PathDetails details;\r\n    details.Path = directory;\r\n    details.ACL[ACEPrincipal::CurrentUser] = ACEPermissions::ReadExecute;\r\n\r\n    details.ApplyACL();\r\n\r\n    REQUIRE(!CanWriteToPath(directory));\r\n}\r\n\r\nTEST_CASE(\"ApplyACL_AdminOwner\", \"[runtime]\")\r\n{\r\n    TempDirectory directory(\"AdminOwner\");\r\n    PathDetails details;\r\n    details.Path = directory;\r\n    details.SetOwner(ACEPrincipal::Admins);\r\n\r\n    if (IsRunningAsAdmin())\r\n    {\r\n        details.ApplyACL();\r\n        RequireAdminOwner(directory);\r\n        REQUIRE(CanWriteToPath(directory));\r\n    }\r\n    else\r\n    {\r\n        // A non-admin token cannot set the owner to be the Admins group\r\n        REQUIRE_THROWS_HR(details.ApplyACL(), HRESULT_FROM_WIN32(ERROR_INVALID_OWNER));\r\n    }\r\n}\r\n\r\nTEST_CASE(\"ApplyACL_BothOwners\", \"[runtime]\")\r\n{\r\n    TempDirectory directory(\"AdminOwner\");\r\n    PathDetails details;\r\n    details.Path = directory;\r\n    details.ACL[ACEPrincipal::CurrentUser] = ACEPermissions::ReadExecute;\r\n    details.ACL[ACEPrincipal::System] = ACEPermissions::All;\r\n\r\n    if (IsRunningAsSystem())\r\n    {\r\n        // Both cannot be owners\r\n        REQUIRE_THROWS_HR(details.ApplyACL(), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));\r\n    }\r\n    else\r\n    {\r\n        REQUIRE_NOTHROW(details.ApplyACL());\r\n    }\r\n}\r\n\r\nTEST_CASE(\"ApplyACL_CurrentUserOwner_SystemAll\", \"[runtime]\")\r\n{\r\n    TempDirectory directory(\"UserAndSystem\");\r\n    PathDetails details;\r\n    details.Path = directory;\r\n    details.SetOwner(ACEPrincipal::CurrentUser);\r\n    details.ACL[ACEPrincipal::System] = ACEPermissions::All;\r\n\r\n    details.ApplyACL();\r\n\r\n    REQUIRE(CanWriteToPath(directory));\r\n}\r\n\r\nTEST_CASE(\"VerifyDevModeEnabledCheck\", \"[runtime]\")\r\n{\r\n    if (!Runtime::IsRunningAsAdmin())\r\n    {\r\n        WARN(\"Test requires admin privilege. Skipped.\");\r\n        return;\r\n    }\r\n\r\n    bool initialState = IsDevModeEnabled();\r\n\r\n    EnableDevMode(!initialState);\r\n    bool modifiedState = IsDevModeEnabled();\r\n    \r\n    // Revert to original state.\r\n    EnableDevMode(initialState);\r\n    bool revertedState = IsDevModeEnabled();\r\n\r\n    REQUIRE(modifiedState != initialState);\r\n    REQUIRE(revertedState == initialState);\r\n}\r\n\r\nTEST_CASE(\"EnsureUserProfileNotPresentInDisplayPaths\", \"[runtime]\")\r\n{\r\n    // Clear the overrides that we use when testing as they don't consider display purposes\r\n    Runtime::TestHook_ClearPathOverrides();\r\n    auto restorePaths = wil::scope_exit([]() { TestCommon::SetTestPathOverrides(); });\r\n\r\n    std::filesystem::path userProfilePath = Filesystem::GetKnownFolderPath(FOLDERID_Profile);\r\n    std::string userProfileString = userProfilePath.u8string();\r\n\r\n    for (auto i = ToIntegral(ToEnum<Runtime::PathName>(0)); i < ToIntegral(Runtime::PathName::Max); ++i)\r\n    {\r\n        std::filesystem::path displayPath = GetPathTo(ToEnum<Runtime::PathName>(i), true);\r\n        std::string displayPathString = displayPath.u8string();\r\n        INFO(i << \" = \" << displayPathString);\r\n        REQUIRE(displayPathString.find(userProfileString) == std::string::npos);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/SQLiteDynamicStorage.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <AppInstallerErrors.h>\r\n#include <winget/SQLiteDynamicStorage.h>\r\n#include <winget/SQLiteWrapper.h>\r\n#include <winget/SQLiteStatementBuilder.h>\r\n#include <winget/SQLiteVersion.h>\r\n\r\nusing namespace AppInstaller::SQLite;\r\nusing namespace std::string_literals;\r\n\r\nTEST_CASE(\"SQLiteDynamicStorage_UpgradeDetection\", \"[sqlite_dynamic]\")\r\n{\r\n    TestCommon::TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    // Create a database with version 1.0\r\n    SQLiteDynamicStorage storage{ tempFile.GetPath(), Version{ 1, 0 } };\r\n\r\n    {\r\n        auto transactionLock = storage.TryBeginTransaction(\"test\", false);\r\n        REQUIRE(transactionLock);\r\n    }\r\n\r\n    // Update the database to version 2.0\r\n    {\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::Create);\r\n        Version version{ 2, 0 };\r\n        version.SetSchemaVersion(connection);\r\n    }\r\n\r\n    REQUIRE(storage.GetVersion() == Version{ 1, 0 });\r\n\r\n    auto transactionLock = storage.TryBeginTransaction(\"test\", false);\r\n    REQUIRE(!transactionLock);\r\n\r\n    REQUIRE(storage.GetVersion() == Version{ 2, 0 });\r\n\r\n    transactionLock = storage.TryBeginTransaction(\"test\", false);\r\n    REQUIRE(transactionLock);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/SQLiteIndex.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <winget/SQLiteWrapper.h>\r\n#include <PackageDependenciesValidation.h>\r\n#include <ArpVersionValidation.h>\r\n#include <Microsoft/SQLiteIndex.h>\r\n#include <winget/Manifest.h>\r\n#include <AppInstallerStrings.h>\r\n#include <winget/SQLiteMetadataTable.h>\r\n#include <winget/PackageVersionDataManifest.h>\r\n\r\n#include <Microsoft/Schema/1_0/IdTable.h>\r\n#include <Microsoft/Schema/1_0/NameTable.h>\r\n#include <Microsoft/Schema/1_0/MonikerTable.h>\r\n#include <Microsoft/Schema/1_0/VersionTable.h>\r\n#include <Microsoft/Schema/1_0/ChannelTable.h>\r\n#include <Microsoft/Schema/1_0/PathPartTable.h>\r\n#include <Microsoft/Schema/1_0/ManifestTable.h>\r\n#include <Microsoft/Schema/1_0/TagsTable.h>\r\n#include <Microsoft/Schema/1_0/CommandsTable.h>\r\n#include <Microsoft/Schema/1_0/SearchResultsTable.h>\r\n#include <Microsoft/Schema/1_4/DependenciesTable.h>\r\n#include <Microsoft/Schema/2_0/Interface.h>\r\n#include <Microsoft/Schema/2_0/PackageUpdateTrackingTable.h>\r\n\r\nusing namespace std::string_literals;\r\nusing namespace std::string_view_literals;\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Repository::Microsoft;\r\nusing namespace AppInstaller::SQLite;\r\nusing namespace AppInstaller::Utility;\r\n\r\nusing UtilityVersion = AppInstaller::Utility::Version;\r\nusing SQLiteVersion = AppInstaller::SQLite::Version;\r\n\r\nSQLiteIndex CreateTestIndex(const std::string& filePath, std::optional<SQLiteVersion> version = {})\r\n{\r\n    // If no specific version requested, then use generator to run against the last 3 versions.\r\n    if (!version)\r\n    {\r\n        SQLiteVersion latestVersion{ 2, 0 };\r\n        SQLiteVersion versionMinus1 = SQLiteVersion{ 1, 7 };\r\n        SQLiteVersion versionMinus2 = SQLiteVersion{ 1, 6 };\r\n\r\n        version = GENERATE_COPY(SQLiteVersion{ versionMinus2 }, SQLiteVersion{ versionMinus1 }, SQLiteVersion{ latestVersion });\r\n    }\r\n\r\n    return SQLiteIndex::CreateNew(filePath, version.value());\r\n}\r\n\r\nSQLiteVersion TestPrepareForRead(SQLiteIndex& index)\r\n{\r\n    SQLiteVersion latestVersion{ 2, 0 };\r\n    SQLiteVersion versionMinus1 = SQLiteVersion{ 1, 7 };\r\n    SQLiteVersion versionMinus2 = SQLiteVersion{ 1, 6 };\r\n\r\n    index.PrepareForPackaging();\r\n\r\n    if (index.GetVersion() == versionMinus2)\r\n    {\r\n        // Degenerate case where we don't need to do anything\r\n    }\r\n    else if (index.GetVersion() == versionMinus1)\r\n    {\r\n        SQLiteVersion version = GENERATE_COPY(SQLiteVersion{ versionMinus2 }, SQLiteVersion{ versionMinus1 });\r\n\r\n        if (version != versionMinus1)\r\n        {\r\n            index.ForceVersion(version);\r\n            return version;\r\n        }\r\n    }\r\n    else if (index.GetVersion() == latestVersion)\r\n    {\r\n        // This crosses major versions, so leave it at 2.0 always\r\n    }\r\n\r\n    return index.GetVersion();\r\n}\r\n\r\nstd::string GetPathFromManifest(Manifest& manifest)\r\n{\r\n    auto publisher = manifest.Id;\r\n    AppInstaller::Utility::FindAndReplace(publisher, \".\", \"/\");\r\n    \r\n    return AppInstaller::Utility::ToLower(publisher).append(\"/\").append(manifest.Version);\r\n}\r\n\r\nvoid CreateFakeManifest(Manifest& manifest, string_t publisher, string_t version = \"1.0.0\")\r\n{\r\n    manifest.Installers.push_back({});\r\n    manifest.Id = publisher.append(\".\").append(\"Id\");\r\n    manifest.DefaultLocalization.Add<Localization::PackageName>(publisher.append(\" Name\"));\r\n    manifest.Moniker = \"testmoniker\";\r\n    manifest.Version = version;\r\n    manifest.Channel = \"test\";\r\n    manifest.DefaultLocalization.Add<Localization::Tags>({ \"t1\", \"t2\" });\r\n    manifest.Installers[0].Commands = { \"test1\", \"test2\" };\r\n}\r\n\r\nSQLiteIndex SimpleTestSetup(const std::string& filePath, Manifest& manifest, std::optional<SQLiteVersion> version = {})\r\n{\r\n    SQLiteIndex index = CreateTestIndex(filePath, version);\r\n\r\n    string_t publisher = \"Test\";\r\n    CreateFakeManifest(manifest, publisher);\r\n\r\n    auto relativePath = GetPathFromManifest(manifest);\r\n\r\n    index.AddManifest(manifest, relativePath);\r\n\r\n    return index;\r\n}\r\n\r\nstruct IndexFields\r\n{\r\n    IndexFields(\r\n        std::string id,\r\n        std::string name,\r\n        std::string moniker,\r\n        std::string version,\r\n        std::string channel,\r\n        std::vector<NormalizedString> tags,\r\n        std::vector<NormalizedString> commands,\r\n        std::string path\r\n    ) :\r\n        Id(std::move(id)),\r\n        Name(std::move(name)),\r\n        Moniker(std::move(moniker)),\r\n        Version(std::move(version)),\r\n        Channel(std::move(channel)),\r\n        Tags(std::move(tags)),\r\n        Commands(std::move(commands)),\r\n        Path(std::move(path))\r\n    {}\r\n\r\n    IndexFields(\r\n        std::string id,\r\n        std::string name,\r\n        std::string moniker,\r\n        std::string version,\r\n        std::string channel,\r\n        std::vector<NormalizedString> tags,\r\n        std::vector<NormalizedString> commands,\r\n        std::string path,\r\n        std::vector<NormalizedString> packageFamilyNames,\r\n        std::vector<NormalizedString> productCodes\r\n    ) :\r\n        Id(std::move(id)),\r\n        Name(std::move(name)),\r\n        Moniker(std::move(moniker)),\r\n        Version(std::move(version)),\r\n        Channel(std::move(channel)),\r\n        Tags(std::move(tags)),\r\n        Commands(std::move(commands)),\r\n        Path(std::move(path)),\r\n        PackageFamilyNames(std::move(packageFamilyNames)),\r\n        ProductCodes(std::move(productCodes))\r\n    {}\r\n\r\n    IndexFields(\r\n        std::string id,\r\n        std::string name,\r\n        std::string publisher,\r\n        std::string moniker,\r\n        std::string version,\r\n        std::string channel,\r\n        std::vector<NormalizedString> tags,\r\n        std::vector<NormalizedString> commands,\r\n        std::string path,\r\n        std::vector<NormalizedString> packageFamilyNames,\r\n        std::vector<NormalizedString> productCodes\r\n    ) :\r\n        Id(std::move(id)),\r\n        Name(std::move(name)),\r\n        Publisher(std::move(publisher)),\r\n        Moniker(std::move(moniker)),\r\n        Version(std::move(version)),\r\n        Channel(std::move(channel)),\r\n        Tags(std::move(tags)),\r\n        Commands(std::move(commands)),\r\n        Path(std::move(path)),\r\n        PackageFamilyNames(std::move(packageFamilyNames)),\r\n        ProductCodes(std::move(productCodes))\r\n    {}\r\n\r\n    IndexFields(\r\n        std::string id,\r\n        std::string name,\r\n        std::string publisher,\r\n        std::string moniker,\r\n        std::string version,\r\n        std::string channel,\r\n        std::vector<NormalizedString> tags,\r\n        std::vector<NormalizedString> commands,\r\n        std::string path,\r\n        std::vector<NormalizedString> packageFamilyNames,\r\n        std::vector<NormalizedString> productCodes,\r\n        std::string arpName,\r\n        std::string arpPublisher\r\n    ) :\r\n        Id(std::move(id)),\r\n        Name(std::move(name)),\r\n        Publisher(std::move(publisher)),\r\n        Moniker(std::move(moniker)),\r\n        Version(std::move(version)),\r\n        Channel(std::move(channel)),\r\n        Tags(std::move(tags)),\r\n        Commands(std::move(commands)),\r\n        Path(std::move(path)),\r\n        PackageFamilyNames(std::move(packageFamilyNames)),\r\n        ProductCodes(std::move(productCodes)),\r\n        ArpName(std::move(arpName)),\r\n        ArpPublisher(std::move(arpPublisher))\r\n    {}\r\n\r\n    std::string Id;\r\n    std::string Name;\r\n    std::string Publisher;\r\n    std::string Moniker;\r\n    std::string Version;\r\n    std::string Channel;\r\n    std::vector<NormalizedString> Tags;\r\n    std::vector<NormalizedString> Commands;\r\n    std::string Path;\r\n    std::vector<NormalizedString> PackageFamilyNames;\r\n    std::vector<NormalizedString> ProductCodes;\r\n    std::string ArpName;\r\n    std::string ArpPublisher;\r\n};\r\n\r\nSQLiteIndex SearchTestSetup(const std::string& filePath, std::initializer_list<IndexFields> data = {}, std::optional<SQLiteVersion> version = {})\r\n{\r\n    SQLiteIndex index = CreateTestIndex(filePath, version);\r\n\r\n    Manifest manifest;\r\n\r\n    auto addFunc = [&](const IndexFields& d)\r\n    {\r\n        manifest.Id = d.Id;\r\n        manifest.DefaultLocalization.Add<Localization::PackageName>(d.Name);\r\n        manifest.DefaultLocalization.Add<Localization::Publisher>(d.Publisher);\r\n        manifest.Moniker = d.Moniker;\r\n        manifest.Version = d.Version;\r\n        manifest.DefaultLocalization.Add<Localization::Tags>(d.Tags);\r\n\r\n        manifest.Installers.resize(std::max(d.PackageFamilyNames.size(), d.ProductCodes.size()));\r\n\r\n        if (manifest.Installers.size() == 0)\r\n        {\r\n            manifest.Installers.push_back({});\r\n        }\r\n\r\n        manifest.Channel = d.Channel;\r\n        manifest.Installers[0].Commands = d.Commands;\r\n\r\n        for (size_t i = 0; i < d.PackageFamilyNames.size(); ++i)\r\n        {\r\n            manifest.Installers[i].PackageFamilyName = d.PackageFamilyNames[i];\r\n        }\r\n\r\n        for (size_t i = 0; i < d.ProductCodes.size(); ++i)\r\n        {\r\n            manifest.Installers[i].ProductCode = d.ProductCodes[i];\r\n        }\r\n\r\n        if (!d.ArpName.empty() || !d.ArpPublisher.empty())\r\n        {\r\n            manifest.Installers[0].AppsAndFeaturesEntries.push_back({});\r\n            manifest.Installers[0].AppsAndFeaturesEntries[0].DisplayName = d.ArpName;\r\n            manifest.Installers[0].AppsAndFeaturesEntries[0].Publisher = d.ArpPublisher;\r\n        }\r\n\r\n        index.AddManifest(manifest, d.Path);\r\n    };\r\n\r\n    for (const auto& d : data)\r\n    {\r\n        addFunc(d);\r\n    }\r\n\r\n    return index;\r\n}\r\n\r\nbool ArePackageFamilyNameAndProductCodeSupported(const SQLiteIndex& index, const SQLiteVersion& testVersion)\r\n{\r\n    UNSCOPED_INFO(\"Index \" << index.GetVersion() << \" | Test \" << testVersion);\r\n    return (index.GetVersion() >= SQLiteVersion{ 1, 1 } && testVersion >= SQLiteVersion{ 1, 1 });\r\n}\r\n\r\nbool AreNormalizedNameAndPublisherSupported(const SQLiteIndex& index, const SQLiteVersion& testVersion)\r\n{\r\n    UNSCOPED_INFO(\"Index \" << index.GetVersion() << \" | Test \" << testVersion);\r\n    return (index.GetVersion() >= SQLiteVersion{ 1, 2 } && testVersion >= SQLiteVersion{ 1, 2 });\r\n}\r\n\r\nbool IsManifestMetadataSupported(const SQLiteIndex& index, const SQLiteVersion& testVersion)\r\n{\r\n    UNSCOPED_INFO(\"Index \" << index.GetVersion() << \" | Test \" << testVersion);\r\n    return (index.GetVersion() >= SQLiteVersion{ 1, 1 } && testVersion >= SQLiteVersion{ 1, 1 });\r\n}\r\n\r\nbool AreManifestHashesSupported(const SQLiteIndex& index, const SQLiteVersion& testVersion)\r\n{\r\n    UNSCOPED_INFO(\"Index \" << index.GetVersion() << \" | Test \" << testVersion);\r\n    return (index.GetVersion() >= SQLiteVersion{ 1, 3 } && testVersion >= SQLiteVersion{ 1, 3 } && index.GetVersion() < SQLiteVersion{ 2, 0 });\r\n}\r\n\r\nbool AreArpVersionsSupported(const SQLiteIndex& index, const SQLiteVersion& testVersion)\r\n{\r\n    UNSCOPED_INFO(\"Index \" << index.GetVersion() << \" | Test \" << testVersion);\r\n    return (index.GetVersion() >= SQLiteVersion{ 1, 5 } && testVersion >= SQLiteVersion{ 1, 5 });\r\n}\r\n\r\nbool AreArpVersionsNullable(const SQLiteIndex& index)\r\n{\r\n    UNSCOPED_INFO(\"Index \" << index.GetVersion());\r\n    return (index.GetVersion() >= SQLiteVersion{ 2, 0 });\r\n}\r\n\r\nbool IsMapDataFoldingSupported(const SQLiteIndex& index, const SQLiteVersion& testVersion)\r\n{\r\n    UNSCOPED_INFO(\"Index \" << index.GetVersion() << \" | Test \" << testVersion);\r\n    return (index.GetVersion() >= SQLiteVersion{ 1, 7 } && testVersion >= SQLiteVersion{ 1, 7 });\r\n}\r\n\r\nbool IsMapDataFolded(const SQLiteIndex& index)\r\n{\r\n    UNSCOPED_INFO(\"Index \" << index.GetVersion());\r\n    return (index.GetVersion() >= SQLiteVersion{ 1, 7 });\r\n}\r\n\r\nbool AreVersionKeysSupported(const SQLiteIndex& index)\r\n{\r\n    UNSCOPED_INFO(\"Index \" << index.GetVersion());\r\n    return (index.GetVersion() < SQLiteVersion{ 2, 0 });\r\n}\r\n\r\nbool AreChannelsSupported(const SQLiteIndex& index)\r\n{\r\n    UNSCOPED_INFO(\"Index \" << index.GetVersion());\r\n    return (index.GetVersion() < SQLiteVersion{ 2, 0 });\r\n}\r\n\r\nbool AreManifestPathsSupported(const SQLiteIndex& index)\r\n{\r\n    UNSCOPED_INFO(\"Index \" << index.GetVersion());\r\n    return (index.GetVersion() < SQLiteVersion{ 2, 0 });\r\n}\r\n\r\nstd::string GetPropertyStringByKey(const SQLiteIndex& index, rowid_t primaryId, PackageVersionProperty property)\r\n{\r\n    auto result = index.GetPropertyByPrimaryId(primaryId, property);\r\n    REQUIRE(result);\r\n    return result.value();\r\n}\r\n\r\nstd::string GetPropertyStringByKey(const SQLiteIndex& index, rowid_t id, PackageVersionProperty property, std::string_view version, std::string_view channel)\r\n{\r\n    if (AreVersionKeysSupported(index))\r\n    {\r\n        auto manifestId = index.GetManifestIdByKey(id, version, channel);\r\n        REQUIRE(manifestId);\r\n        auto result = index.GetPropertyByPrimaryId(manifestId.value(), property);\r\n        REQUIRE(result);\r\n        return result.value();\r\n    }\r\n    else\r\n    {\r\n        return GetPropertyStringByKey(index, id, property);\r\n    }\r\n}\r\n\r\nstd::string GetPropertyStringById(const SQLiteIndex& index, rowid_t id, PackageVersionProperty property)\r\n{\r\n    if (AreVersionKeysSupported(index))\r\n    {\r\n        auto versions = index.GetVersionKeysById(id);\r\n        REQUIRE(!versions.empty());\r\n        return GetPropertyStringByKey(index, versions[0].ManifestId, property);\r\n    }\r\n    else\r\n    {\r\n        return GetPropertyStringByKey(index, id, property);\r\n    }\r\n}\r\n\r\nstd::string GetIdStringById(const SQLiteIndex& index, rowid_t id)\r\n{\r\n    return GetPropertyStringById(index, id, PackageVersionProperty::Id);\r\n}\r\n\r\nstd::string GetNameStringById(const SQLiteIndex& index, rowid_t id)\r\n{\r\n    return GetPropertyStringById(index, id, PackageVersionProperty::Name);\r\n}\r\n\r\nstd::string GetPathStringByKey(const SQLiteIndex& index, rowid_t id, std::string_view version, std::string_view channel)\r\n{\r\n    return GetPropertyStringByKey(index, id, PackageVersionProperty::RelativePath, version, channel);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndexCreateLatestAndReopen\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteVersion versionCreated;\r\n\r\n    // Create the index\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::CreateNew(tempFile, SQLiteVersion::Latest());\r\n        versionCreated = index.GetVersion();\r\n    }\r\n\r\n    // Reopen the index for read only\r\n    {\r\n        INFO(\"Trying with Read\");\r\n        SQLiteIndex index = SQLiteIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::Read);\r\n        SQLiteVersion versionRead = index.GetVersion();\r\n        REQUIRE(versionRead == versionCreated);\r\n    }\r\n\r\n    // Reopen the index for read/write\r\n    {\r\n        INFO(\"Trying with ReadWrite\");\r\n        SQLiteIndex index = SQLiteIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n        SQLiteVersion versionRead = index.GetVersion();\r\n        REQUIRE(versionRead == versionCreated);\r\n    }\r\n\r\n    // Reopen the index for immutable read\r\n    {\r\n        INFO(\"Trying with Immutable\");\r\n        SQLiteIndex index = SQLiteIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::Immutable);\r\n        SQLiteVersion versionRead = index.GetVersion();\r\n        REQUIRE(versionRead == versionCreated);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndexCreateAndAddManifest\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest manifest;\r\n    std::string relativePath = \"test/id/1.0.0.yaml\";\r\n\r\n    SQLiteIndex index = SimpleTestSetup(tempFile, manifest, SQLiteVersion::Latest());\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndexCreateAndAddManifestFile\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = CreateTestIndex(tempFile);\r\n\r\n    TestDataFile manifestFile{ \"Manifest-Good.yaml\" };\r\n    std::filesystem::path manifestPath{ \"microsoft/msixsdk/microsoft.msixsdk-1.7.32.yaml\" };\r\n\r\n    index.AddManifest(manifestFile, manifestPath);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndexCreateAndAddManifestDuplicate\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest manifest;\r\n\r\n    SQLiteIndex index = SimpleTestSetup(tempFile, manifest);\r\n    auto relativePath = GetPathFromManifest(manifest);\r\n\r\n    // Attempting to add the same manifest at a different path should fail.\r\n    REQUIRE_THROWS_HR(index.AddManifest(manifest, \"differentpath.yaml\"), HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS));\r\n\r\n    // Attempting to add the same manifest with a differently cased Id at a different path should fail.\r\n    manifest.Id = ToLower(manifest.Id);\r\n    REQUIRE_THROWS_HR(index.AddManifest(manifest, \"differentpath.yaml\"), HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS));\r\n\r\n    // Attempting to add a different manifest at the same path should fail.\r\n    manifest.Id += \"-new\";\r\n    REQUIRE_THROWS_HR(index.AddManifest(manifest, relativePath), HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS));\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_VersionReferencedByDependenciesClearsUnusedVersionAndKeepUsedVersion\", \"[sqliteindex][V1_4]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest dependencyManifest1, dependencyManifest2, manifest, isolatedManifest;\r\n    SQLiteIndex index = SimpleTestSetup(tempFile, dependencyManifest1, SQLiteVersion::Latest());\r\n\r\n    auto& publisher2 = \"Test2\";\r\n    CreateFakeManifest(dependencyManifest2, publisher2);\r\n    index.AddManifest(dependencyManifest2, GetPathFromManifest(dependencyManifest2));\r\n\r\n    auto& publisher3 = \"Test3\";\r\n    CreateFakeManifest(manifest, publisher3);\r\n    std::string dependencyOnlyVersion = \"0.0.5\";\r\n    manifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, dependencyManifest1.Id, \"1.0.0\"));\r\n    manifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, dependencyManifest2.Id, dependencyOnlyVersion));\r\n\r\n    index.AddManifest(manifest, GetPathFromManifest(manifest));\r\n    \r\n    // Create a new manifest that depends on v0.0.5\r\n    auto& publisher4 = \"Test4\";\r\n    CreateFakeManifest(isolatedManifest, publisher4);\r\n    isolatedManifest.Version = dependencyOnlyVersion;\r\n    index.AddManifest(isolatedManifest);\r\n\r\n    index.RemoveManifest(isolatedManifest);\r\n    // After deletion that the version(v0.0.5) must be present because it still referenced via dependencies table.\r\n    {\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadOnly);\r\n        REQUIRE(Schema::V1_0::VersionTable::SelectIdByValue(connection, dependencyOnlyVersion).has_value());\r\n    }\r\n\r\n    index.RemoveManifest(manifest);\r\n    // Now, that we've deleted the manifest depending on version(v0.0.5), it should be absent.\r\n    {\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadOnly);\r\n        REQUIRE(!Schema::V1_0::VersionTable::SelectIdByValue(connection, dependencyOnlyVersion).has_value());\r\n    }\r\n    index.RemoveManifest(dependencyManifest1);\r\n    index.RemoveManifest(dependencyManifest2);\r\n    \r\n    // Final sanity check, nothing should be in the version table.\r\n    {\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadOnly);\r\n        REQUIRE(Schema::V1_0::VersionTable::IsEmpty(connection));\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_AddUpdateRemoveManifestWithDependencies\", \"[sqliteindex][V1_4]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest dependencyManifest1, dependencyManifest2, manifest;\r\n    SQLiteIndex index = SimpleTestSetup(tempFile, dependencyManifest1, SQLiteVersion::Latest());\r\n\r\n    auto& publisher2 = \"Test2\";\r\n    CreateFakeManifest(dependencyManifest2, publisher2);\r\n    index.AddManifest(dependencyManifest2, GetPathFromManifest(dependencyManifest2));\r\n\r\n    auto& publisher3 = \"Test3\";\r\n    CreateFakeManifest(manifest, publisher3);\r\n    manifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, dependencyManifest1.Id, \"1.0.0\"));\r\n    manifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, dependencyManifest2.Id, \"1.0.0\"));\r\n\r\n    index.AddManifest(manifest, GetPathFromManifest(manifest));\r\n    index.UpdateManifest(manifest, GetPathFromManifest(manifest));\r\n    index.RemoveManifest(manifest);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_AddManifestWithDependencies_MissingPackage\", \"[sqliteindex][V1_4]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest dependencyManifest1, dependencyManifest2, manifest;\r\n    SQLiteIndex index = SimpleTestSetup(tempFile, dependencyManifest1, SQLiteVersion::Latest());\r\n\r\n    // Publisher2 is not present\r\n    auto& publisher2 = \"Test2\";\r\n    CreateFakeManifest(dependencyManifest2, publisher2);\r\n\r\n    auto& publisher3 = \"Test3\";\r\n    CreateFakeManifest(manifest, publisher3);\r\n    manifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, dependencyManifest1.Id, \"1.0.0\"));\r\n    manifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, dependencyManifest2.Id, \"1.0.0\"));\r\n\r\n    REQUIRE_THROWS_HR(index.AddManifest(manifest, GetPathFromManifest(manifest)), APPINSTALLER_CLI_ERROR_MISSING_PACKAGE);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_AddUpdateRemoveManifestWithDependencies_MissingVersion\", \"[sqliteindex][V1_4]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest dependencyManifest1, dependencyManifest2, manifest;\r\n    SQLiteIndex index = SimpleTestSetup(tempFile, dependencyManifest1, SQLiteVersion::Latest());\r\n\r\n    auto& publisher2 = \"Test2\";\r\n    CreateFakeManifest(dependencyManifest2, publisher2);\r\n    index.AddManifest(dependencyManifest2, GetPathFromManifest(dependencyManifest2));\r\n\r\n    auto& publisher3 = \"Test3\";\r\n    CreateFakeManifest(manifest, publisher3);\r\n    manifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, dependencyManifest1.Id, \"0.0.1\"));\r\n    manifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, dependencyManifest2.Id, \"0.0.2\"));\r\n\r\n    index.AddManifest(manifest, GetPathFromManifest(manifest));\r\n    index.UpdateManifest(manifest, GetPathFromManifest(manifest));\r\n    index.RemoveManifest(manifest);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_AddUpdateRemoveManifestWithDependencies_EmptyManifestVersion\", \"[sqliteindex][V1_4]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest dependencyManifest1, dependencyManifest2, manifest;\r\n    SQLiteIndex index = SimpleTestSetup(tempFile, dependencyManifest1, SQLiteVersion::Latest());\r\n\r\n    auto& publisher2 = \"Test2\";\r\n    CreateFakeManifest(dependencyManifest2, publisher2);\r\n    index.AddManifest(dependencyManifest2, GetPathFromManifest(dependencyManifest2));\r\n\r\n    auto& publisher3 = \"Test3\";\r\n    CreateFakeManifest(manifest, publisher3);\r\n    manifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, dependencyManifest1.Id));\r\n    manifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, dependencyManifest2.Id));\r\n\r\n    index.AddManifest(manifest, GetPathFromManifest(manifest));\r\n    index.UpdateManifest(manifest, GetPathFromManifest(manifest));\r\n    index.RemoveManifest(manifest);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_DependenciesTable_CheckConsistency\", \"[sqliteindex][V1_4]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n    \r\n    {\r\n        Manifest levelOneManifest, levelTwoManifest, levelThreeManifest, topLevelManifest;\r\n        SQLiteIndex index = SimpleTestSetup(tempFile, levelThreeManifest, SQLiteVersion::Latest());\r\n\r\n        constexpr std::string_view levelTwoManifestPublisher = \"LevelTwoManifest\";\r\n        CreateFakeManifest(levelTwoManifest, levelTwoManifestPublisher);\r\n\r\n        levelTwoManifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, levelThreeManifest.Id, \"1.0.0\"));\r\n        index.AddManifest(levelTwoManifest, GetPathFromManifest(levelTwoManifest));\r\n\r\n        constexpr std::string_view levelOneManifestPublisher = \"LevelOneManifest\";\r\n        CreateFakeManifest(levelOneManifest, levelOneManifestPublisher);\r\n        levelOneManifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, levelTwoManifest.Id, \"1.0.0\"));\r\n        index.AddManifest(levelOneManifest, GetPathFromManifest(levelOneManifest));\r\n\r\n        constexpr std::string_view topLevelManifestPublisher = \"TopLevelManifest\";\r\n        CreateFakeManifest(topLevelManifest, topLevelManifestPublisher);\r\n        topLevelManifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, levelOneManifest.Id, \"1.0.0\"));\r\n    }\r\n\r\n    {\r\n        // Open it directly to modify the table\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n        rowid_t nonExistentRowId = 40;\r\n        rowid_t nonExistentManifest = 41;\r\n        rowid_t nonExistentVersion = 42;\r\n        rowid_t nonExistentPackageId = 43;\r\n\r\n        Builder::StatementBuilder builder;\r\n        builder.InsertInto(Schema::V1_4::DependenciesTable::TableName())\r\n            .Values(nonExistentRowId, nonExistentManifest, nonExistentVersion, nonExistentPackageId);\r\n        builder.Execute(connection);\r\n    }\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n\r\n        REQUIRE(!index.CheckConsistency(true));\r\n    }\r\n\r\n    TempFile tempFile2{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile2.GetPath());\r\n\r\n    {\r\n        SQLiteIndex index = CreateTestIndex(tempFile2, SQLiteVersion::Latest());\r\n\r\n        Manifest manifest;\r\n        manifest.Id = \"Foo\";\r\n        manifest.Version = \"10.0\";\r\n\r\n        index.AddManifest(manifest, \"path\");\r\n\r\n        REQUIRE(index.CheckConsistency(true));\r\n\r\n        // Add dependency that does not require min version\r\n        Manifest manifestWithDependency1;\r\n        manifestWithDependency1.Id = \"Bar1\";\r\n        manifestWithDependency1.Version = \"10.0\";\r\n        manifestWithDependency1.Installers.push_back({});\r\n        manifestWithDependency1.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, manifest.Id));\r\n\r\n        index.AddManifest(manifestWithDependency1, \"path1\");\r\n\r\n        REQUIRE(index.CheckConsistency(true));\r\n\r\n        // Add dependency with min version satisfied\r\n        Manifest manifestWithDependency2;\r\n        manifestWithDependency2.Id = \"Bar2\";\r\n        manifestWithDependency2.Version = \"10.0\";\r\n        manifestWithDependency2.Installers.push_back({});\r\n        manifestWithDependency2.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, manifest.Id, \"1.0\"));\r\n\r\n        index.AddManifest(manifestWithDependency2, \"path2\");\r\n\r\n        REQUIRE(index.CheckConsistency(true));\r\n\r\n        // Add dependency with min version not satisfied\r\n        Manifest manifestWithDependency3;\r\n        manifestWithDependency3.Id = \"Bar3\";\r\n        manifestWithDependency3.Version = \"10.0\";\r\n        manifestWithDependency3.Installers.push_back({});\r\n        manifestWithDependency3.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, manifest.Id, \"11.0\"));\r\n\r\n        index.AddManifest(manifestWithDependency3, \"path3\");\r\n\r\n        REQUIRE_FALSE(index.CheckConsistency(true));\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_RemoveManifestFile_NotPresent\", \"[sqliteindex]\")\r\n{\r\n    SQLiteIndex index = CreateTestIndex(SQLITE_MEMORY_DB_CONNECTION_TARGET);\r\n\r\n    TestDataFile manifestFile{ \"Manifest-Good.yaml\" };\r\n    std::filesystem::path manifestPath{ \"microsoft/msixsdk/microsoft.msixsdk-1.7.32.yaml\" };\r\n\r\n    REQUIRE_THROWS_HR(index.RemoveManifest(manifestFile, manifestPath), E_NOT_SET);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_RemoveManifest\", \"[sqliteindex][V1_0]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    std::string manifest1Path = \"test/id/test.id-1.0.0.yaml\";\r\n    Manifest manifest1;\r\n    manifest1.Installers.push_back({});\r\n    manifest1.Id = \"test.id\";\r\n    manifest1.DefaultLocalization.Add<Localization::PackageName>(\"Test Name\");\r\n    manifest1.Moniker = \"testmoniker\";\r\n    manifest1.Version = \"1.0.0\";\r\n    manifest1.Channel = \"test\";\r\n    manifest1.DefaultLocalization.Add<Localization::Tags>({ \"t1\", \"t2\" });\r\n    manifest1.Installers[0].Commands = { \"test1\", \"test2\" };\r\n\r\n    std::string manifest2Path = \"test/woah/test.id-1.0.0.yaml\";\r\n    Manifest manifest2;\r\n    manifest2.Installers.push_back({});\r\n    manifest2.Id = \"test.woah\";\r\n    manifest2.DefaultLocalization.Add<Localization::PackageName>(\"Test Name WOAH\");\r\n    manifest2.Moniker = \"testmoniker\";\r\n    manifest2.Version = \"1.0.0\";\r\n    manifest2.Channel = \"test\";\r\n    manifest2.DefaultLocalization.Add<Localization::Tags>({});\r\n    manifest2.Installers[0].Commands = { \"test1\", \"test2\", \"test3\" };\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::CreateNew(tempFile, { 1, 0 });\r\n\r\n        index.AddManifest(manifest1, manifest1Path);\r\n        index.AddManifest(manifest2, manifest2Path);\r\n\r\n        // Now remove manifest1\r\n        index.RemoveManifest(manifest1, manifest1Path);\r\n    }\r\n\r\n    {\r\n        // Open it directly to directly test table state\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n\r\n        REQUIRE(!Schema::V1_0::ManifestTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::IdTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::NameTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::MonikerTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::VersionTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::ChannelTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::PathPartTable::IsEmpty(connection));\r\n        // Because manifest2 had no tags\r\n        REQUIRE(Schema::V1_0::TagsTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::CommandsTable::IsEmpty(connection));\r\n    }\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n\r\n        // Now remove manifest2\r\n        index.RemoveManifest(manifest2, manifest2Path);\r\n    }\r\n\r\n    // Open it directly to directly test table state\r\n    Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n\r\n    REQUIRE(Schema::V1_0::ManifestTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::IdTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::NameTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::MonikerTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::VersionTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::ChannelTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::PathPartTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::TagsTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::CommandsTable::IsEmpty(connection));\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_RemoveManifestWithDependencies\", \"[sqliteindex][V1_4]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest dependencyManifest1, dependencyManifest2, manifest;\r\n    SQLiteIndex index = SimpleTestSetup(tempFile, dependencyManifest1, SQLiteVersion::Latest());\r\n\r\n    auto& publisher2 = \"Test2\";\r\n    CreateFakeManifest(dependencyManifest2, publisher2);\r\n    index.AddManifest(dependencyManifest2, GetPathFromManifest(dependencyManifest2));\r\n\r\n    auto& publisher3 = \"Test3\";\r\n    CreateFakeManifest(manifest, publisher3);\r\n    manifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, dependencyManifest1.Id, \"1.0.0\"));\r\n    manifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, dependencyManifest2.Id, \"1.0.0\"));\r\n\r\n    index.AddManifest(manifest, GetPathFromManifest(manifest));\r\n\r\n    index.RemoveManifest(manifest, GetPathFromManifest(manifest));\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_ValidateManifestWithDependencies\", \"[sqliteindex][V1_4]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest levelOneManifest, levelTwoManifest, levelThreeManifest, topLevelManifest;\r\n    SQLiteIndex index = SimpleTestSetup(tempFile, levelThreeManifest, SQLiteVersion::Latest());\r\n\r\n    constexpr std::string_view levelTwoManifestPublisher = \"LevelTwoManifest\";\r\n    CreateFakeManifest(levelTwoManifest, levelTwoManifestPublisher);\r\n\r\n    levelTwoManifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, levelThreeManifest.Id, \"1.0.0\"));\r\n    index.AddManifest(levelTwoManifest, GetPathFromManifest(levelTwoManifest));\r\n\r\n    constexpr std::string_view levelOneManifestPublisher = \"LevelOneManifest\";\r\n    CreateFakeManifest(levelOneManifest, levelOneManifestPublisher);\r\n    levelOneManifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, levelTwoManifest.Id, \"1.0.0\"));\r\n    index.AddManifest(levelOneManifest, GetPathFromManifest(levelOneManifest));\r\n\r\n    constexpr std::string_view topLevelManifestPublisher = \"TopLevelManifest\";\r\n    CreateFakeManifest(topLevelManifest, topLevelManifestPublisher);\r\n    topLevelManifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, levelOneManifest.Id, \"1.0.0\"));\r\n    REQUIRE(PackageDependenciesValidation::ValidateManifestDependencies(&index, topLevelManifest));\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_ValidateManifestWithDependenciesHasLoops\", \"[sqliteindex][V1_4]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest levelOneManifest, levelTwoManifest, levelThreeManifest, topLevelManifest;\r\n    SQLiteIndex index = SimpleTestSetup(tempFile, levelThreeManifest, SQLiteVersion::Latest());\r\n\r\n    constexpr std::string_view levelTwoManifestPublisher = \"LevelTwoManifest\";\r\n    CreateFakeManifest(levelTwoManifest, levelTwoManifestPublisher);\r\n\r\n    levelTwoManifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, levelThreeManifest.Id, \"1.0.0\"));\r\n    index.AddManifest(levelTwoManifest, GetPathFromManifest(levelTwoManifest));\r\n\r\n    constexpr std::string_view levelOneManifestPublisher = \"LevelOneManifest\";\r\n    CreateFakeManifest(levelOneManifest, levelOneManifestPublisher);\r\n    levelOneManifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, levelTwoManifest.Id, \"1.0.0\"));\r\n    index.AddManifest(levelOneManifest, GetPathFromManifest(levelOneManifest));\r\n\r\n    constexpr std::string_view topLevelManifestPublisher = \"TopLevelManifest\";\r\n    CreateFakeManifest(topLevelManifest, topLevelManifestPublisher);\r\n    topLevelManifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, levelOneManifest.Id, \"1.0.0\"));\r\n    index.AddManifest(topLevelManifest, GetPathFromManifest(topLevelManifest));\r\n\r\n    levelThreeManifest.Installers.push_back(ManifestInstaller{});\r\n    levelThreeManifest.Installers[1].Dependencies.Add(Dependency(DependencyType::Package, topLevelManifest.Id, \"1.0.0\"));\r\n    REQUIRE_THROWS_HR(\r\n        PackageDependenciesValidation::ValidateManifestDependencies(&index, levelThreeManifest),\r\n        APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_ValidateManifestWithDependenciesMissingNode\", \"[sqliteindex][V1_4]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest levelOneManifest, levelTwoManifest, levelThreeManifest, topLevelManifest;\r\n    SQLiteIndex index = SimpleTestSetup(tempFile, levelThreeManifest, SQLiteVersion::Latest());\r\n\r\n    constexpr std::string_view levelTwoManifestPublisher = \"LevelTwoManifest\";\r\n    CreateFakeManifest(levelTwoManifest, levelTwoManifestPublisher);\r\n\r\n    levelTwoManifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, levelThreeManifest.Id, \"1.0.0\"));\r\n    index.AddManifest(levelTwoManifest, GetPathFromManifest(levelTwoManifest));\r\n\r\n    // This node is missing, because it's not in the index.\r\n    constexpr std::string_view levelOneManifestPublisher = \"LevelOneManifest\";\r\n    CreateFakeManifest(levelOneManifest, levelOneManifestPublisher);\r\n    levelOneManifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, levelTwoManifest.Id, \"1.0.0\"));\r\n\r\n    constexpr std::string_view topLevelManifestPublisher = \"TopLevelManifest\";\r\n    CreateFakeManifest(topLevelManifest, topLevelManifestPublisher);\r\n    topLevelManifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, levelOneManifest.Id, \"1.0.0\"));\r\n    REQUIRE_THROWS_HR(\r\n        PackageDependenciesValidation::ValidateManifestDependencies(&index, topLevelManifest),\r\n        APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_ValidateManifestWithDependenciesNoSuitableMinVersion\", \"[sqliteindex][V1_4]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest levelOneManifest, levelTwoManifest, levelThreeManifest, topLevelManifest;\r\n    SQLiteIndex index = SimpleTestSetup(tempFile, levelThreeManifest, SQLiteVersion::Latest());\r\n\r\n    constexpr std::string_view levelTwoManifestPublisher = \"LevelTwoManifest\";\r\n    CreateFakeManifest(levelTwoManifest, levelTwoManifestPublisher);\r\n\r\n    levelTwoManifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, levelThreeManifest.Id, \"1.0.0\"));\r\n    index.AddManifest(levelTwoManifest, GetPathFromManifest(levelTwoManifest));\r\n\r\n    constexpr std::string_view levelOneManifestPublisher = \"LevelOneManifest\";\r\n    CreateFakeManifest(levelOneManifest, levelOneManifestPublisher);\r\n    levelOneManifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, levelTwoManifest.Id, \"1.0.0\"));\r\n    index.AddManifest(levelOneManifest, GetPathFromManifest(levelOneManifest));\r\n\r\n    constexpr std::string_view topLevelManifestPublisher = \"TopLevelManifest\";\r\n    CreateFakeManifest(topLevelManifest, topLevelManifestPublisher);\r\n    topLevelManifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, levelOneManifest.Id, \"2.0.0\"));\r\n\r\n    REQUIRE_THROWS_HR(\r\n        PackageDependenciesValidation::ValidateManifestDependencies(&index, topLevelManifest),\r\n        APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_ValidateManifestWhenManifestIsDependency_StructureBroken\", \"[sqliteindex][V1_4]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest levelOneManifest, levelTwoManifest, levelThreeManifest, topLevelManifest;\r\n    SQLiteIndex index = SimpleTestSetup(tempFile, levelThreeManifest, SQLiteVersion::Latest());\r\n\r\n    constexpr std::string_view levelTwoManifestPublisher = \"LevelTwoManifest\";\r\n    CreateFakeManifest(levelTwoManifest, levelTwoManifestPublisher);\r\n\r\n    levelTwoManifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, levelThreeManifest.Id, \"1.0.0\"));\r\n    index.AddManifest(levelTwoManifest, GetPathFromManifest(levelTwoManifest));\r\n\r\n    constexpr std::string_view levelOneManifestPublisher = \"LevelOneManifest\";\r\n    CreateFakeManifest(levelOneManifest, levelOneManifestPublisher);\r\n    levelOneManifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, levelTwoManifest.Id, \"1.0.0\"));\r\n    index.AddManifest(levelOneManifest, GetPathFromManifest(levelOneManifest));\r\n\r\n    constexpr std::string_view topLevelManifestPublisher = \"TopLevelManifest\";\r\n    CreateFakeManifest(topLevelManifest, topLevelManifestPublisher);\r\n    topLevelManifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, levelOneManifest.Id, \"1.0.0\"));\r\n    index.AddManifest(topLevelManifest, GetPathFromManifest(topLevelManifest));\r\n\r\n    REQUIRE_THROWS_HR(\r\n        PackageDependenciesValidation::VerifyDependenciesStructureForManifestDelete(&index, levelThreeManifest),\r\n        APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_ValidateManifestWhenManifestIsDependency_StructureNotBroken\", \"[sqliteindex][V1_4]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest levelOneManifest, levelTwoManifest, levelThreeManifest, topLevelManifest, levelThreeManifestV2;\r\n    SQLiteIndex index = SimpleTestSetup(tempFile, levelThreeManifest, SQLiteVersion::Latest());\r\n\r\n    constexpr std::string_view levelTwoManifestPublisher = \"LevelTwoManifest\";\r\n    CreateFakeManifest(levelTwoManifest, levelTwoManifestPublisher);\r\n\r\n    levelTwoManifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, levelThreeManifest.Id, \"1.0.0\"));\r\n    index.AddManifest(levelTwoManifest, GetPathFromManifest(levelTwoManifest));\r\n\r\n    constexpr std::string_view levelOneManifestPublisher = \"LevelOneManifest\";\r\n    CreateFakeManifest(levelOneManifest, levelOneManifestPublisher);\r\n    levelOneManifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, levelTwoManifest.Id, \"1.0.0\"));\r\n    index.AddManifest(levelOneManifest, GetPathFromManifest(levelOneManifest));\r\n\r\n    constexpr std::string_view topLevelManifestPublisher = \"TopLevelManifest\";\r\n    CreateFakeManifest(topLevelManifest, topLevelManifestPublisher);\r\n    topLevelManifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, levelOneManifest.Id, \"1.0.0\"));\r\n    index.AddManifest(topLevelManifest, GetPathFromManifest(topLevelManifest));\r\n\r\n    constexpr std::string_view levelThreeManifestV2Publisher = \"Test\";\r\n    CreateFakeManifest(levelThreeManifestV2, levelThreeManifestV2Publisher, \"2.0.0\");\r\n    index.AddManifest(levelThreeManifestV2, GetPathFromManifest(levelThreeManifestV2));\r\n\r\n    REQUIRE(PackageDependenciesValidation::VerifyDependenciesStructureForManifestDelete(&index, levelThreeManifest));\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_ValidateManifestWhenManifestIsDependency_StructureBroken_NoSuitableOldManifest\", \"[sqliteindex][V1_4]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest levelOneManifest, levelTwoManifest, levelThreeManifest, topLevelManifest, levelThreeManifestV2;\r\n    SQLiteIndex index = SimpleTestSetup(tempFile, levelThreeManifest, SQLiteVersion::Latest());\r\n\r\n    constexpr std::string_view levelThreeManifestV2Publisher = \"Test\";\r\n    CreateFakeManifest(levelThreeManifestV2, levelThreeManifestV2Publisher, \"2.0.0\");\r\n    index.AddManifest(levelThreeManifestV2, GetPathFromManifest(levelThreeManifestV2));\r\n\r\n    constexpr std::string_view levelTwoManifestPublisher = \"LevelTwoManifest\";\r\n    CreateFakeManifest(levelTwoManifest, levelTwoManifestPublisher);\r\n\r\n    levelTwoManifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, levelThreeManifest.Id, \"2.0.0\"));\r\n    index.AddManifest(levelTwoManifest, GetPathFromManifest(levelTwoManifest));\r\n\r\n    constexpr std::string_view levelOneManifestPublisher = \"LevelOneManifest\";\r\n    CreateFakeManifest(levelOneManifest, levelOneManifestPublisher);\r\n    levelOneManifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, levelTwoManifest.Id, \"1.0.0\"));\r\n    index.AddManifest(levelOneManifest, GetPathFromManifest(levelOneManifest));\r\n\r\n    constexpr std::string_view topLevelManifestPublisher = \"TopLevelManifest\";\r\n    CreateFakeManifest(topLevelManifest, topLevelManifestPublisher);\r\n    topLevelManifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, levelOneManifest.Id, \"1.0.0\"));\r\n    index.AddManifest(topLevelManifest, GetPathFromManifest(topLevelManifest)); \r\n\r\n    REQUIRE_THROWS(\r\n        PackageDependenciesValidation::VerifyDependenciesStructureForManifestDelete(&index, levelThreeManifestV2),\r\n        APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_RemoveManifest_EnsureConsistentRowId\", \"[sqliteindex][V1_7]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    std::string manifest1Path = \"test/id/test.id-1.0.0.yaml\";\r\n    Manifest manifest1;\r\n    manifest1.Installers.push_back({});\r\n    manifest1.Id = \"test.id\";\r\n    manifest1.DefaultLocalization.Add<Localization::PackageName>(\"Test Name\");\r\n    manifest1.Moniker = \"testmoniker\";\r\n    manifest1.Version = \"1.0.0\";\r\n    manifest1.Channel = \"test\";\r\n    manifest1.DefaultLocalization.Add<Localization::Tags>({ \"t1\", \"t2\" });\r\n    manifest1.Installers[0].Commands = { \"test1\", \"test2\" };\r\n\r\n    std::string manifest2Path = \"test/woah/test.id-1.0.0.yaml\";\r\n    Manifest manifest2;\r\n    manifest2.Installers.push_back({});\r\n    manifest2.Id = \"test.woah\";\r\n    manifest2.DefaultLocalization.Add<Localization::PackageName>(\"Test Name WOAH\");\r\n    manifest2.Moniker = \"testmoniker\";\r\n    manifest2.Version = \"1.0.0\";\r\n    manifest2.Channel = \"test\";\r\n    manifest2.DefaultLocalization.Add<Localization::Tags>({});\r\n    manifest2.Installers[0].Commands = { \"test1\", \"test2\", \"test3\" };\r\n\r\n    SQLiteIndex index = CreateTestIndex(tempFile, SQLiteVersion{ 1, 7 });\r\n\r\n    index.AddManifest(manifest1, manifest1Path);\r\n    index.AddManifest(manifest2, manifest2Path);\r\n\r\n    // Get the second manifest's id for validating consistency\r\n    SearchRequest request;\r\n    request.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, manifest2.Id));\r\n    auto result = index.Search(request);\r\n\r\n    REQUIRE(result.Matches.size() == 1);\r\n    auto manifest2IdRowId = result.Matches[0].first;\r\n\r\n    auto rowId = index.GetManifestIdByKey(manifest2IdRowId, {}, {});\r\n    REQUIRE(rowId);\r\n    auto manifest2RowId = rowId.value();\r\n\r\n    // Now remove manifest1 and prepare\r\n    index.RemoveManifest(manifest1, manifest1Path);\r\n    index.PrepareForPackaging();\r\n\r\n    // Checking consistency will also uncover issues, but not potentially the same ones as below.\r\n    REQUIRE(index.CheckConsistency(true));\r\n\r\n    // Repeat search to ensure consistent ids\r\n    result = index.Search(request);\r\n    REQUIRE(result.Matches.size() == 1);\r\n    REQUIRE(result.Matches[0].first == manifest2IdRowId);\r\n\r\n    rowId = index.GetManifestIdByKey(manifest2IdRowId, {}, {});\r\n    REQUIRE(rowId);\r\n    REQUIRE(rowId.value() == manifest2RowId);\r\n\r\n    REQUIRE(manifest2.Id == index.GetPropertyByPrimaryId(manifest2RowId, PackageVersionProperty::Id));\r\n    REQUIRE(manifest2.DefaultLocalization.Get<Localization::PackageName>() == index.GetPropertyByPrimaryId(manifest2RowId, PackageVersionProperty::Name));\r\n    REQUIRE(manifest2.Moniker == index.GetPropertyByPrimaryId(manifest2RowId, PackageVersionProperty::Moniker));\r\n    REQUIRE(manifest2.Version == index.GetPropertyByPrimaryId(manifest2RowId, PackageVersionProperty::Version));\r\n    REQUIRE(manifest2.Channel == index.GetPropertyByPrimaryId(manifest2RowId, PackageVersionProperty::Channel));\r\n    REQUIRE(manifest2Path == index.GetPropertyByPrimaryId(manifest2RowId, PackageVersionProperty::RelativePath));\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_RemoveManifestFile\", \"[sqliteindex][V1_0]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::CreateNew(tempFile, { 1, 0 });\r\n\r\n        TestDataFile manifestFile{ \"Manifest-Good.yaml\" };\r\n        std::filesystem::path manifestPath{ \"microsoft/msixsdk/microsoft.msixsdk-1.7.32.yaml\" };\r\n\r\n        index.AddManifest(manifestFile, manifestPath);\r\n\r\n        // Now remove that manifest\r\n        index.RemoveManifest(manifestFile, manifestPath);\r\n    }\r\n\r\n    // Open it directly to directly test table state\r\n    Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n\r\n    REQUIRE(Schema::V1_0::ManifestTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::IdTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::NameTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::MonikerTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::VersionTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::ChannelTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::PathPartTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::TagsTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::CommandsTable::IsEmpty(connection));\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_UpdateManifest\", \"[sqliteindex][V1_4]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    std::string manifestPath = \"test/id/test.id-1.0.0.yaml\";\r\n    Manifest manifest;\r\n    manifest.Installers.push_back({});\r\n    manifest.Id = \"test.id\";\r\n    manifest.DefaultLocalization.Add < Localization::PackageName>(\"Test Name\");\r\n    manifest.Moniker = \"testmoniker\";\r\n    manifest.Version = \"1.0.0\";\r\n    manifest.Channel = \"test\";\r\n    manifest.DefaultLocalization.Add<Localization::Tags>({ \"t1\", \"t2\" });\r\n    manifest.Installers[0].Commands = { \"test1\", \"test2\" };\r\n\r\n    \r\n    {\r\n        auto version = GENERATE(SQLiteVersion{ 1, 0 }, SQLiteVersion::Latest());\r\n        SQLiteIndex index = SQLiteIndex::CreateNew(tempFile, version);\r\n\r\n        index.AddManifest(manifest, manifestPath);\r\n    }\r\n\r\n    {\r\n        // Open it directly to directly test table state\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n\r\n        REQUIRE(!Schema::V1_0::ManifestTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::IdTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::NameTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::MonikerTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::VersionTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::ChannelTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::PathPartTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::TagsTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::CommandsTable::IsEmpty(connection));\r\n    }\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n\r\n        // Update with no updates should return false\r\n        REQUIRE(!index.UpdateManifest(manifest, manifestPath));\r\n\r\n        manifest.DefaultLocalization.Add<Localization::Description>(\"description2\");\r\n\r\n        // Update with no indexed updates should return false\r\n        REQUIRE(!index.UpdateManifest(manifest, manifestPath));\r\n\r\n        // Update with indexed changes\r\n        manifest.DefaultLocalization.Add<Localization::PackageName>(\"Test Name2\");\r\n        manifest.Moniker = \"testmoniker2\";\r\n        manifest.DefaultLocalization.Add<Localization::Tags>({ \"t1\", \"t2\", \"t3\" });\r\n        manifest.Installers[0].Commands = {};\r\n\r\n        REQUIRE(index.UpdateManifest(manifest, manifestPath));\r\n    }\r\n\r\n    {\r\n        // Open it directly to directly test table state\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n\r\n        REQUIRE(!Schema::V1_0::ManifestTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::IdTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::NameTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::MonikerTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::VersionTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::ChannelTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::PathPartTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::TagsTable::IsEmpty(connection));\r\n        // The update removed all commands\r\n        REQUIRE(Schema::V1_0::CommandsTable::IsEmpty(connection));\r\n    }\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n\r\n        // Now remove manifest2\r\n        index.RemoveManifest(manifest, manifestPath);\r\n    }\r\n\r\n    // Open it directly to directly test table state\r\n    Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n\r\n    REQUIRE(Schema::V1_0::ManifestTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::IdTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::NameTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::MonikerTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::VersionTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::ChannelTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::PathPartTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::TagsTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::CommandsTable::IsEmpty(connection));\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_UpdateManifestWithDependencies\", \"[sqliteindex][V1_4]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest dependencyManifest1, dependencyManifest2, manifest, updateManifest;\r\n    SQLiteIndex index = SimpleTestSetup(tempFile, dependencyManifest1, SQLiteVersion::Latest());\r\n\r\n    auto& publisher2 = \"Test2\";\r\n    CreateFakeManifest(dependencyManifest2, publisher2);\r\n    index.AddManifest(dependencyManifest2, GetPathFromManifest(dependencyManifest2));\r\n\r\n    auto& publisher3 = \"Test3\";\r\n    CreateFakeManifest(manifest, publisher3);\r\n    const std::string dependencyPath3 = GetPathFromManifest(manifest);\r\n\r\n    manifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, dependencyManifest1.Id, \"1.0.0\"));\r\n    manifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, dependencyManifest2.Id, \"1.0.0\"));\r\n\r\n    index.AddManifest(manifest, dependencyPath3);\r\n\r\n    auto& publisher4 = \"Test4\";\r\n    CreateFakeManifest(updateManifest, publisher4);\r\n    index.AddManifest(updateManifest, GetPathFromManifest(updateManifest));\r\n    manifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, updateManifest.Id, \"1.0.0\"));\r\n\r\n    REQUIRE(index.UpdateManifest(manifest, dependencyPath3));\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_UpdateManifestWithDependenciesDeleteAndAdd\", \"[sqliteindex][V1_4]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest dependencyManifest1, dependencyManifest2, manifest, updateManifest;\r\n    SQLiteIndex index = SimpleTestSetup(tempFile, dependencyManifest1, SQLiteVersion::Latest());\r\n\r\n    auto& publisher2 = \"Test2\";\r\n    CreateFakeManifest(dependencyManifest2, publisher2);\r\n    index.AddManifest(dependencyManifest2, GetPathFromManifest(dependencyManifest2));\r\n\r\n    auto& publisher3 = \"Test3\";\r\n    CreateFakeManifest(manifest, publisher3);\r\n    const std::string dependencyPath3 = GetPathFromManifest(manifest);\r\n\r\n    manifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, dependencyManifest1.Id, \"1.0.0\"));\r\n    manifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, dependencyManifest2.Id, \"1.0.0\"));\r\n\r\n    index.AddManifest(manifest, dependencyPath3);\r\n\r\n    manifest.Installers[0].Dependencies.Clear();\r\n\r\n    auto& publisher4 = \"Test4\";\r\n    CreateFakeManifest(updateManifest, publisher4);\r\n    index.AddManifest(updateManifest, GetPathFromManifest(updateManifest));\r\n    manifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, updateManifest.Id, \"1.0.0\"));\r\n\r\n    REQUIRE(index.UpdateManifest(manifest, dependencyPath3));\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_UpdateManifestChangePath\", \"[sqliteindex][V1_0]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    std::string manifestPath = \"test/id/test.id-1.0.0.yaml\";\r\n    Manifest manifest;\r\n    manifest.Installers.push_back({});\r\n    manifest.Id = \"test.id\";\r\n    manifest.DefaultLocalization.Add<Localization::PackageName>(\"Test Name\");\r\n    manifest.Moniker = \"testmoniker\";\r\n    manifest.Version = \"1.0.0\";\r\n    manifest.Channel = \"test\";\r\n    manifest.DefaultLocalization.Add<Localization::Tags>({ \"t1\", \"t2\" });\r\n    manifest.Installers[0].Commands = { \"test1\", \"test2\" };\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::CreateNew(tempFile, { 1, 0 });\r\n\r\n        index.AddManifest(manifest, manifestPath);\r\n    }\r\n\r\n    {\r\n        // Open it directly to directly test table state\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n\r\n        REQUIRE(!Schema::V1_0::ManifestTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::IdTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::NameTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::MonikerTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::VersionTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::ChannelTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::PathPartTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::TagsTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::CommandsTable::IsEmpty(connection));\r\n    }\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n\r\n        manifestPath = \"test/newid/test.newid-1.0.0.yaml\";\r\n\r\n        // Update with path update should indicate change\r\n        REQUIRE(index.UpdateManifest(manifest, manifestPath));\r\n    }\r\n\r\n    {\r\n        // Open it directly to directly test table state\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n\r\n        REQUIRE(!Schema::V1_0::ManifestTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::IdTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::NameTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::MonikerTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::VersionTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::ChannelTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::PathPartTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::TagsTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::CommandsTable::IsEmpty(connection));\r\n    }\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n\r\n        // Now remove manifest, with unknown path\r\n        index.RemoveManifest(manifest, \"\");\r\n    }\r\n\r\n    // Open it directly to directly test table state\r\n    Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n\r\n    REQUIRE(Schema::V1_0::ManifestTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::IdTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::NameTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::MonikerTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::VersionTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::ChannelTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::PathPartTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::TagsTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::CommandsTable::IsEmpty(connection));\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_UpdateManifest_Pathless\", \"[sqliteindex][V1_0]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest manifest;\r\n    manifest.Installers.push_back({});\r\n    manifest.Id = \"test.id\";\r\n    manifest.DefaultLocalization.Add < Localization::PackageName>(\"Test Name\");\r\n    manifest.Moniker = \"testmoniker\";\r\n    manifest.Version = \"1.0.0\";\r\n    manifest.Channel = \"test\";\r\n    manifest.DefaultLocalization.Add<Localization::Tags>({ \"t1\", \"t2\" });\r\n    manifest.Installers[0].Commands = { \"test1\", \"test2\" };\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::CreateNew(tempFile, { 1, 0 });\r\n\r\n        index.AddManifest(manifest);\r\n    }\r\n\r\n    {\r\n        // Open it directly to directly test table state\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n\r\n        REQUIRE(!Schema::V1_0::ManifestTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::IdTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::NameTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::MonikerTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::VersionTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::ChannelTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::PathPartTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::TagsTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::CommandsTable::IsEmpty(connection));\r\n    }\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n\r\n        // Update with no updates should return false\r\n        REQUIRE(!index.UpdateManifest(manifest));\r\n\r\n        manifest.DefaultLocalization.Add<Localization::Description>(\"description2\");\r\n\r\n        // Update with no indexed updates should return false\r\n        REQUIRE(!index.UpdateManifest(manifest));\r\n\r\n        // Update with indexed changes\r\n        manifest.DefaultLocalization.Add<Localization::PackageName>(\"Test Name2\");\r\n        manifest.Moniker = \"testmoniker2\";\r\n        manifest.DefaultLocalization.Add<Localization::Tags>({ \"t1\", \"t2\", \"t3\" });\r\n        manifest.Installers[0].Commands = {};\r\n\r\n        REQUIRE(index.UpdateManifest(manifest));\r\n    }\r\n\r\n    {\r\n        // Open it directly to directly test table state\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n\r\n        REQUIRE(!Schema::V1_0::ManifestTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::IdTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::NameTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::MonikerTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::VersionTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::ChannelTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::PathPartTable::IsEmpty(connection));\r\n        REQUIRE(!Schema::V1_0::TagsTable::IsEmpty(connection));\r\n        // The update removed all commands\r\n        REQUIRE(Schema::V1_0::CommandsTable::IsEmpty(connection));\r\n    }\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n\r\n        // Now remove manifest2\r\n        index.RemoveManifest(manifest);\r\n    }\r\n\r\n    // Open it directly to directly test table state\r\n    Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n\r\n    REQUIRE(Schema::V1_0::ManifestTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::IdTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::NameTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::MonikerTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::VersionTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::ChannelTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::TagsTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::CommandsTable::IsEmpty(connection));\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_UpdateManifestChangeCase\", \"[sqliteindex][V1_0]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    std::string manifestPath = \"test/id/test.id-1.0.0.yaml\";\r\n    Manifest manifest;\r\n    manifest.Installers.push_back({});\r\n    manifest.Id = \"test.id\";\r\n    manifest.DefaultLocalization.Add<Localization::PackageName>(\"Test Name\");\r\n    manifest.Moniker = \"testmoniker\";\r\n    manifest.Version = \"1.0.0-test\";\r\n    manifest.Channel = \"test\";\r\n    manifest.DefaultLocalization.Add<Localization::Tags>({ \"t1\", \"t2\" });\r\n    manifest.Installers[0].Commands = { \"test1\", \"test2\" };\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::CreateNew(tempFile, { 1, 0 });\r\n\r\n        index.AddManifest(manifest, manifestPath);\r\n    }\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n\r\n        manifest.Id = \"Test.Id\";\r\n\r\n        // Update with path update should indicate change\r\n        REQUIRE(index.UpdateManifest(manifest, manifestPath));\r\n    }\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n\r\n        manifest.Version = \"1.0.0-Test\";\r\n\r\n        // Update with path update should indicate change\r\n        REQUIRE(index.UpdateManifest(manifest, manifestPath));\r\n    }\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n\r\n        manifest.Channel = \"Test\";\r\n\r\n        // Update with path update should indicate change\r\n        REQUIRE(index.UpdateManifest(manifest, manifestPath));\r\n    }\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n\r\n        manifest.DefaultLocalization.Add<Localization::PackageName>(\"test name\");\r\n\r\n        // Update with path update should indicate change\r\n        REQUIRE(index.UpdateManifest(manifest, manifestPath));\r\n    }\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n\r\n        // Now remove manifest, with unknown path\r\n        index.RemoveManifest(manifest, \"\");\r\n    }\r\n\r\n    // Open it directly to directly test table state\r\n    Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n\r\n    REQUIRE(Schema::V1_0::ManifestTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::IdTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::NameTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::MonikerTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::VersionTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::ChannelTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::PathPartTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::TagsTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::CommandsTable::IsEmpty(connection));\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_IdCaseInsensitivity\", \"[sqliteindex][V1_0]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    std::string manifest1Path = \"test/id/test.id-1.0.0.yaml\";\r\n    Manifest manifest1;\r\n    manifest1.Installers.push_back({});\r\n    manifest1.Id = \"test.id\";\r\n    manifest1.DefaultLocalization.Add<Localization::PackageName>(\"Test Name\");\r\n    manifest1.Moniker = \"testmoniker\";\r\n    manifest1.Version = \"1.0.0\";\r\n    manifest1.DefaultLocalization.Add<Localization::Tags>({ \"t1\", \"t2\" });\r\n    manifest1.Installers[0].Commands = { \"test1\", \"test2\" };\r\n\r\n    std::string manifest2Path = \"test/id/test.id-2.0.0.yaml\";\r\n    Manifest manifest2 = manifest1;\r\n    manifest2.Id = \"Test.Id\";\r\n    manifest1.Version = \"2.0.0\";\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::CreateNew(tempFile, { 1, 0 });\r\n\r\n        index.AddManifest(manifest1, manifest1Path);\r\n\r\n        auto results = index.Search({});\r\n        REQUIRE(results.Matches.size() == 1);\r\n        REQUIRE(manifest1.Id == GetIdStringById(index, results.Matches[0].first));\r\n    }\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n\r\n        index.AddManifest(manifest2, manifest2Path);\r\n\r\n        auto results = index.Search({});\r\n        REQUIRE(results.Matches.size() == 1);\r\n        REQUIRE(manifest2.Id == GetIdStringById(index, results.Matches[0].first));\r\n    }\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n\r\n        manifest1.Id = \"TEST.ID\";\r\n\r\n        REQUIRE(index.UpdateManifest(manifest1, manifest1Path));\r\n\r\n        auto results = index.Search({});\r\n        REQUIRE(results.Matches.size() == 1);\r\n        REQUIRE(manifest1.Id == GetIdStringById(index, results.Matches[0].first));\r\n    }\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n\r\n        index.RemoveManifest(manifest1, manifest1Path);\r\n\r\n        auto results = index.Search({});\r\n        REQUIRE(results.Matches.size() == 1);\r\n        REQUIRE(manifest1.Id == GetIdStringById(index, results.Matches[0].first));\r\n    }\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n\r\n        index.RemoveManifest(manifest2, manifest2Path);\r\n\r\n        auto results = index.Search({});\r\n        REQUIRE(results.Matches.empty());\r\n    }\r\n\r\n    // Open it directly to directly test table state\r\n    Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n\r\n    REQUIRE(Schema::V1_0::ManifestTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::IdTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::NameTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::MonikerTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::VersionTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::ChannelTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::PathPartTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::TagsTable::IsEmpty(connection));\r\n    REQUIRE(Schema::V1_0::CommandsTable::IsEmpty(connection));\r\n}\r\n\r\nTEST_CASE(\"PathPartTable_EnsurePathExists_Negative_Paths\", \"[sqliteindex][V1_0]\")\r\n{\r\n    // Open it directly to directly test pathpart table\r\n    Connection connection = Connection::Create(SQLITE_MEMORY_DB_CONNECTION_TARGET, Connection::OpenDisposition::Create);\r\n\r\n    REQUIRE_THROWS_HR(Schema::V1_0::PathPartTable::EnsurePathExists(connection, R\"()\", false), E_INVALIDARG);\r\n    REQUIRE_THROWS_HR(Schema::V1_0::PathPartTable::EnsurePathExists(connection, R\"(\\)\", false), E_INVALIDARG);\r\n    REQUIRE_THROWS_HR(Schema::V1_0::PathPartTable::EnsurePathExists(connection, R\"(/)\", false), E_INVALIDARG);\r\n    REQUIRE_THROWS_HR(Schema::V1_0::PathPartTable::EnsurePathExists(connection, R\"(C:)\", false), E_INVALIDARG);\r\n    REQUIRE_THROWS_HR(Schema::V1_0::PathPartTable::EnsurePathExists(connection, R\"(C:\\\\)\", false), E_INVALIDARG);\r\n    REQUIRE_THROWS_HR(Schema::V1_0::PathPartTable::EnsurePathExists(connection, R\"(C:\\temp\\path\\file.txt)\", false), E_INVALIDARG);\r\n    REQUIRE_THROWS_HR(Schema::V1_0::PathPartTable::EnsurePathExists(connection, R\"(\\temp\\path\\file.txt)\", false), E_INVALIDARG);\r\n}\r\n\r\nTEST_CASE(\"PathPartTable_EnsurePathExists\", \"[sqliteindex][V1_0]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    // Create the index\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::CreateNew(tempFile, { 1, 0 });\r\n        SQLiteVersion versionCreated = index.GetVersion();\r\n        REQUIRE(versionCreated == SQLiteVersion{ 1, 0 });\r\n    }\r\n\r\n    // Open it directly to directly test pathpart table\r\n    Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n\r\n    // attempt to find path that doesn't exist\r\n    auto result0 = Schema::V1_0::PathPartTable::EnsurePathExists(connection, R\"(a\\b\\c.txt)\", false);\r\n    REQUIRE(!std::get<0>(result0));\r\n\r\n    // add path\r\n    auto result1 = Schema::V1_0::PathPartTable::EnsurePathExists(connection, R\"(a\\b\\c.txt)\", true);\r\n    REQUIRE(std::get<0>(result1));\r\n\r\n    // Second time trying to create should return false and same id\r\n    auto result2 = Schema::V1_0::PathPartTable::EnsurePathExists(connection, R\"(a\\b\\c.txt)\", true);\r\n    REQUIRE(!std::get<0>(result2));\r\n    REQUIRE(std::get<1>(result1) == std::get<1>(result2));\r\n\r\n    // Trying to find but not create should return true because it exists\r\n    auto result3 = Schema::V1_0::PathPartTable::EnsurePathExists(connection, R\"(a\\b\\c.txt)\", false);\r\n    REQUIRE(std::get<0>(result3));\r\n    REQUIRE(std::get<1>(result1) == std::get<1>(result3));\r\n\r\n    // attempt to find a different file\r\n    auto result4 = Schema::V1_0::PathPartTable::EnsurePathExists(connection, R\"(a\\b\\d.txt)\", false);\r\n    REQUIRE(!std::get<0>(result4));\r\n\r\n    // add a different file\r\n    auto result5 = Schema::V1_0::PathPartTable::EnsurePathExists(connection, R\"(a\\b\\d.txt)\", true);\r\n    REQUIRE(std::get<0>(result5));\r\n    REQUIRE(std::get<1>(result1) != std::get<1>(result5));\r\n\r\n    // add the same file but deeper\r\n    auto result6 = Schema::V1_0::PathPartTable::EnsurePathExists(connection, R\"(a\\b\\d\\c.txt)\", true);\r\n    REQUIRE(std::get<0>(result6));\r\n    REQUIRE(std::get<1>(result1) != std::get<1>(result6));\r\n\r\n    // get the deeper file with extra separators\r\n    auto result7 = Schema::V1_0::PathPartTable::EnsurePathExists(connection, R\"(a\\\\b\\d\\\\c.txt)\", true);\r\n    REQUIRE(!std::get<0>(result7));\r\n    REQUIRE(std::get<1>(result6) == std::get<1>(result7));\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_PrepareForPackaging\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = CreateTestIndex(tempFile);\r\n\r\n    TestDataFile manifestFile{ \"Manifest-Good.yaml\" };\r\n    std::filesystem::path manifestPath{ \"microsoft/msixsdk/microsoft.msixsdk-1.7.32.yaml\" };\r\n\r\n    index.AddManifest(manifestFile, manifestPath);\r\n\r\n    index.PrepareForPackaging();\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_IdExactMatch\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest manifest;\r\n    std::string relativePath = \"test/id/1.0.0.yaml\";\r\n    SQLiteIndex index = SimpleTestSetup(tempFile, manifest);\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Exact, manifest.Id);\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n    REQUIRE(results.Matches[0].second.Field == PackageMatchField::Id);\r\n    REQUIRE(results.Matches[0].second.Type == MatchType::Exact);\r\n    REQUIRE(results.Matches[0].second.Value == manifest.Id);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_MultipleMatch\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest manifest;\r\n    std::string relativePath = \"test/id/1.0.0.yaml\";\r\n    SQLiteIndex index = SimpleTestSetup(tempFile, manifest);\r\n\r\n    manifest.Version = \"2.0.0\";\r\n    index.AddManifest(manifest, relativePath + \"2\");\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Exact, manifest.Id);\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n\r\n    if (AreVersionKeysSupported(index))\r\n    {\r\n        auto result = index.GetVersionKeysById(results.Matches[0].first);\r\n        REQUIRE(result.size() == 2);\r\n    }\r\n    else\r\n    {\r\n        REQUIRE_THROWS_HR(index.GetVersionKeysById(results.Matches[0].first), E_NOT_VALID_STATE);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_NoMatch\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest manifest;\r\n    SQLiteIndex index = SimpleTestSetup(tempFile, manifest);\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Exact, \"THIS DOES NOT MATCH ANYTHING!\");\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 0);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_IdString\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest manifest;\r\n    SQLiteIndex index = SimpleTestSetup(tempFile, manifest);\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Exact, manifest.Id);\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n\r\n    auto result = GetIdStringById(index, results.Matches[0].first);\r\n    REQUIRE(result == manifest.Id);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_NameString\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest manifest;\r\n    SQLiteIndex index = SimpleTestSetup(tempFile, manifest);\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Exact, manifest.Id);\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n\r\n    auto result = GetNameStringById(index, results.Matches[0].first);\r\n    REQUIRE(result == manifest.DefaultLocalization.Get<Localization::PackageName>());\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_PathString\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest manifest;\r\n    SQLiteIndex index = SimpleTestSetup(tempFile, manifest);\r\n    auto relativePath = GetPathFromManifest(manifest);\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    if (!AreManifestPathsSupported(index))\r\n    {\r\n        return;\r\n    }\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Exact, manifest.Id);\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n\r\n    auto specificResult = GetPathStringByKey(index, results.Matches[0].first, manifest.Version, manifest.Channel);\r\n    REQUIRE(specificResult == relativePath);\r\n\r\n    auto latestResult = GetPathStringByKey(index, results.Matches[0].first, \"\", manifest.Channel);\r\n    REQUIRE(latestResult == relativePath);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_PathlessString\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest manifest;\r\n    std::string relativePath;\r\n\r\n    SQLiteIndex index = CreateTestIndex(tempFile);\r\n    CreateFakeManifest(manifest, \"Test\");\r\n    index.AddManifest(manifest);\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    if (!AreManifestPathsSupported(index))\r\n    {\r\n        return;\r\n    }\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Exact, manifest.Id);\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n\r\n    auto specificResult = GetPathStringByKey(index, results.Matches[0].first, manifest.Version, manifest.Channel);\r\n    REQUIRE(specificResult == relativePath);\r\n\r\n    auto latestResult = GetPathStringByKey(index, results.Matches[0].first, \"\", manifest.Channel);\r\n    REQUIRE(latestResult == relativePath);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Versions\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest manifest;\r\n    std::string relativePath = \"test/id/1.0.0.yaml\";\r\n    SQLiteIndex index = SimpleTestSetup(tempFile, manifest);\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Exact, manifest.Id);\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n\r\n    if (AreVersionKeysSupported(index))\r\n    {\r\n        auto result = index.GetVersionKeysById(results.Matches[0].first);\r\n        REQUIRE(result.size() == 1);\r\n        REQUIRE(result[0].VersionAndChannel.GetVersion().ToString() == manifest.Version);\r\n        REQUIRE(result[0].VersionAndChannel.GetChannel().ToString() == manifest.Channel);\r\n    }\r\n    else\r\n    {\r\n        REQUIRE_THROWS_HR(index.GetVersionKeysById(results.Matches[0].first), E_NOT_VALID_STATE);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_VersionSorting\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    std::vector<VersionAndChannel> sortedList =\r\n    {\r\n        { UtilityVersion(\"15.0.0\"), Channel(\"\") },\r\n        { UtilityVersion(\"14.0.0\"), Channel(\"\") },\r\n        { UtilityVersion(\"13.2.0\"), Channel(\"\") },\r\n        { UtilityVersion(\"13.2.0-bugfix\"), Channel(\"\") },\r\n        { UtilityVersion(\"13.0.0\"), Channel(\"\") },\r\n        { UtilityVersion(\"16.0.0\"), Channel(\"alpha\") },\r\n        { UtilityVersion(\"15.8.0\"), Channel(\"alpha\") },\r\n        { UtilityVersion(\"15.1.0\"), Channel(\"beta\") },\r\n    };\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id\", \"Name\", \"Moniker\", \"14.0.0\", \"\", { \"foot\" }, { \"com34\" }, \"Path1\" },\r\n        { \"Id\", \"Name\", \"Moniker\", \"16.0.0\", \"alpha\", { \"floor\" }, { \"com3\" }, \"Path2\" },\r\n        { \"Id\", \"Name\", \"Moniker\", \"15.0.0\", \"\", {}, { \"Command\" }, \"Path3\" },\r\n        { \"Id\", \"Name\", \"Moniker\", \"13.2.0\", \"\", {}, { \"Command\" }, \"Path4\" },\r\n        { \"Id\", \"Name\", \"Moniker\", \"15.1.0\", \"beta\", { \"foo\" }, { \"com3\" }, \"Path5\" },\r\n        { \"Id\", \"Name\", \"Moniker\", \"15.8.0\", \"alpha\", { \"foo\" }, { \"com3\" }, \"Path6\" },\r\n        { \"Id\", \"Name\", \"Moniker\", \"13.2.0-bugfix\", \"\", { \"foo\" }, { \"com3\" }, \"Path7\" },\r\n        { \"Id\", \"Name\", \"Moniker\", \"13.0.0\", \"\", { \"foo\" }, { \"com3\" }, \"Path8\" },\r\n        });\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    if (!AreChannelsSupported(index))\r\n    {\r\n        return;\r\n    }\r\n\r\n    SearchRequest request;\r\n    request.Filters.emplace_back(PackageMatchField::Id, MatchType::Exact, \"Id\");\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n\r\n    auto result = index.GetVersionKeysById(results.Matches[0].first);\r\n    REQUIRE(result.size() == sortedList.size());\r\n\r\n    for (size_t i = 0; i < result.size(); ++i)\r\n    {\r\n        const VersionAndChannel& sortedVAC = sortedList[i];\r\n        const VersionAndChannel& resultVAC = result[i].VersionAndChannel;\r\n\r\n        INFO(i);\r\n        REQUIRE(sortedVAC.GetVersion().ToString() == resultVAC.GetVersion().ToString());\r\n        REQUIRE(sortedVAC.GetChannel().ToString() == resultVAC.GetChannel().ToString());\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_PathString_VersionSorting\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    std::vector<VersionAndChannel> sortedList =\r\n    {\r\n        { UtilityVersion(\"15.0.0\"), Channel(\"\") },\r\n        { UtilityVersion(\"14.0.0\"), Channel(\"\") },\r\n        { UtilityVersion(\"13.2.0\"), Channel(\"\") },\r\n        { UtilityVersion(\"13.2.0-bugfix\"), Channel(\"\") },\r\n        { UtilityVersion(\"13.0.0\"), Channel(\"\") },\r\n        { UtilityVersion(\"16.0.0\"), Channel(\"alpha\") },\r\n        { UtilityVersion(\"15.8.0\"), Channel(\"alpha\") },\r\n        { UtilityVersion(\"15.1.0\"), Channel(\"beta\") },\r\n    };\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id\", \"Name\", \"Moniker\", \"14.0.0\", \"\", { \"foot\" }, { \"com34\" }, \"Path1\" },\r\n        { \"Id\", \"Name\", \"Moniker\", \"16.0.0\", \"alpha\", { \"floor\" }, { \"com3\" }, \"Path2\" },\r\n        { \"Id\", \"Name\", \"Moniker\", \"15.0.0\", \"\", {}, { \"Command\" }, \"Path3\" },\r\n        { \"Id\", \"Name\", \"Moniker\", \"13.2.0\", \"\", {}, { \"Command\" }, \"Path4\" },\r\n        { \"Id\", \"Name\", \"Moniker\", \"15.1.0\", \"beta\", { \"foo\" }, { \"com3\" }, \"Path5\" },\r\n        { \"Id\", \"Name\", \"Moniker\", \"15.8.0\", \"alpha\", { \"foo\" }, { \"com3\" }, \"Path6\" },\r\n        { \"Id\", \"Name\", \"Moniker\", \"13.2.0-bugfix\", \"\", { \"foo\" }, { \"com3\" }, \"Path7\" },\r\n        { \"Id\", \"Name\", \"Moniker\", \"13.0.0\", \"\", { \"foo\" }, { \"com3\" }, \"Path8\" },\r\n        });\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    if (!AreChannelsSupported(index))\r\n    {\r\n        return;\r\n    }\r\n\r\n    SearchRequest request;\r\n    request.Filters.emplace_back(PackageMatchField::Id, MatchType::Exact, \"Id\");\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n\r\n    auto result = GetPathStringByKey(index, results.Matches[0].first, \"\", \"\");\r\n    REQUIRE(result == \"Path3\");\r\n\r\n    result = GetPathStringByKey(index, results.Matches[0].first, \"\", \"alpha\");\r\n    REQUIRE(result == \"Path2\");\r\n\r\n    result = GetPathStringByKey(index, results.Matches[0].first, \"\", \"beta\");\r\n    REQUIRE(result == \"Path5\");\r\n\r\n    auto nonResult = index.GetManifestIdByKey(results.Matches[0].first, \"\", \"gamma\");\r\n    REQUIRE(!nonResult.has_value());\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_PathString_CaseInsensitive\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id\", \"Name\", \"Moniker\", \"14.0.0\", \"\", { \"foot\" }, { \"com34\" }, \"Path1\" },\r\n        { \"Id\", \"Name\", \"Moniker\", \"16.0.0\", \"alpha\", { \"floor\" }, { \"com3\" }, \"Path2\" },\r\n        { \"Id\", \"Name\", \"Moniker\", \"15.0.0\", \"\", {}, { \"Command\" }, \"Path3\" },\r\n        { \"Id\", \"Name\", \"Moniker\", \"13.2.0-BUGFIX\", \"\", {}, { \"Command\" }, \"Path4\" },\r\n        { \"Id\", \"Name\", \"Moniker\", \"15.1.0\", \"beta\", { \"foo\" }, { \"com3\" }, \"Path5\" },\r\n        { \"Id\", \"Name\", \"Moniker\", \"15.8.0\", \"alpha\", { \"foo\" }, { \"com3\" }, \"Path6\" },\r\n        { \"Id\", \"Name\", \"Moniker\", \"13.2.0-bugfix\", \"beta\", { \"foo\" }, { \"com3\" }, \"Path7\" },\r\n        { \"Id\", \"Name\", \"Moniker\", \"13.0.0\", \"\", { \"foo\" }, { \"com3\" }, \"Path8\" },\r\n        });\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    if (!AreChannelsSupported(index))\r\n    {\r\n        return;\r\n    }\r\n\r\n    SearchRequest request;\r\n    request.Filters.emplace_back(PackageMatchField::Id, MatchType::Exact, \"Id\");\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n\r\n    auto result = index.GetManifestIdByKey(results.Matches[0].first, \"\", \"Alpha\");\r\n    REQUIRE(result.has_value());\r\n\r\n    result = index.GetManifestIdByKey(results.Matches[0].first, \"13.2.0-BugFix\", \"\");\r\n    REQUIRE(result.has_value());\r\n\r\n    result = index.GetManifestIdByKey(results.Matches[0].first, \"13.2.0-BugFix\", \"BETA\");\r\n    REQUIRE(result.has_value());\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_SearchResultsTableSearches\", \"[sqliteindex][V1_0]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest manifest;\r\n    {\r\n        (void)SimpleTestSetup(tempFile, manifest, SQLiteVersion{ 1, 0 });\r\n    }\r\n\r\n    Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadOnly);\r\n    Schema::V1_0::SearchResultsTable search(connection);\r\n\r\n    std::string value = \"test\";\r\n\r\n    // Perform every type of field and match search\r\n    PackageMatchFilter filter(PackageMatchField::Id, MatchType::Exact, value);\r\n\r\n    for (auto field : { PackageMatchField::Id, PackageMatchField::Name, PackageMatchField::Moniker, PackageMatchField::Tag, PackageMatchField::Command })\r\n    {\r\n        filter.Field = field;\r\n\r\n        for (auto match : { MatchType::Exact, MatchType::Fuzzy, MatchType::FuzzySubstring, MatchType::Substring, MatchType::Wildcard })\r\n        {\r\n            filter.Type = match;\r\n            search.SearchOnField(filter);\r\n        }\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_EmptySearch\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile,{\r\n        { \"Id1\", \"Name\", \"Moniker\", \"Version1\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\" },\r\n        { \"Id1\", \"Name\", \"Moniker\", \"Version2\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path2\" },\r\n        { \"Id2\", \"Name\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path3\" },\r\n        { \"Id3\", \"Name\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path4\" },\r\n        });\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 3);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_Exact\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id\", \"Name\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\" },\r\n        { \"Id2\", \"Name\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path2\" },\r\n        });\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Exact, \"Id\");\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_Substring\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id\", \"Name\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\" },\r\n        { \"Id2\", \"Name\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path2\" },\r\n        });\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Substring, \"Id\");\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 2);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_ExactBeforeSubstring\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id2\", \"Name\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\" },\r\n        { \"Id\", \"Name\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path2\" },\r\n        });\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Substring, \"Id\");\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 2);\r\n\r\n    REQUIRE(GetIdStringById(index, results.Matches[0].first) == \"Id\");\r\n    REQUIRE(GetIdStringById(index, results.Matches[1].first) == \"Id2\");\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_SingleFilter\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id\", \"Name\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\" },\r\n        { \"Id2\", \"Na\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path2\" },\r\n        { \"Id3\", \"No\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path3\" },\r\n        });\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Filters.emplace_back(PackageMatchField::Name, MatchType::Substring, \"a\");\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 2);\r\n\r\n    request.Filters[0].Value = \"e\";\r\n\r\n    results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_Multimatch\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id1\", \"Name\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\" },\r\n        { \"Id1\", \"Name1\", \"Moniker\", \"Version1\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path2\" },\r\n        { \"Id2\", \"Name\", \"Moniker\", \"Version\", \"\", { \"Tag\" }, { \"Command\" }, \"Path3\" },\r\n        { \"Id2\", \"Name\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path4\" },\r\n        { \"Id3\", \"Name\", \"Moniker\", \"Version1\", \"\", { \"Tag\" }, { \"Command\" }, \"Path5\" },\r\n        { \"Id3\", \"Name\", \"Moniker\", \"Version2\", \"\", { \"Tag\" }, { \"Command\" }, \"Path6\" },\r\n        { \"Id3\", \"Name\", \"Moniker\", \"Version3\", \"\", { \"Tag\" }, { \"Command\" }, \"Path7\" },\r\n        });\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    // An empty string should match all substrings\r\n    request.Query = RequestMatch(MatchType::Substring, \"\");\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 3);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_QueryAndFilter\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Nope\", \"Name\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\" },\r\n        { \"Id2\", \"Na\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path2\" },\r\n        { \"Id3\", \"No\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path3\" },\r\n        });\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Substring, \"Id\");\r\n    request.Filters.emplace_back(PackageMatchField::Name, MatchType::Substring, \"Na\");\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n\r\n    auto result = GetIdStringById(index, results.Matches[0].first);\r\n    REQUIRE(result == \"Id2\");\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_QueryAndMultipleFilters\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id1\", \"Name\", \"Moniker\", \"Version\", \"Channel\", { \"foot\" }, { \"com34\" }, \"Path1\" },\r\n        { \"Id1\", \"Name1\", \"Moniker\", \"Version1\", \"Channel\", { \"floor\" }, { \"com3\" }, \"Path2\" },\r\n        { \"Id2\", \"Name\", \"Moniker\", \"Version\", \"\", {}, { \"Command\" }, \"Path3\" },\r\n        { \"Id2\", \"Name\", \"Moniker\", \"Version\", \"Channel\", {}, { \"Command\" }, \"Path4\" },\r\n        { \"Id3\", \"Tagit\", \"Moniker\", \"Version1\", \"\", { \"foo\" }, { \"com3\" }, \"Path5\" },\r\n        { \"Id3\", \"Tagit\", \"Moniker\", \"Version2\", \"\", { \"foo\" }, { \"com3\" }, \"Path6\" },\r\n        { \"Id3\", \"Tagit\", \"new\", \"Version3\", \"\", { \"foo\" }, { \"com3\" }, \"Path7\" },\r\n        });\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Substring, \"tag\");\r\n    request.Filters.emplace_back(PackageMatchField::Command, MatchType::Exact, \"com3\");\r\n    request.Filters.emplace_back(PackageMatchField::Tag, MatchType::Substring, \"foo\");\r\n    request.Filters.emplace_back(PackageMatchField::Moniker, MatchType::Substring, \"new\");\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n\r\n    auto result = GetIdStringById(index, results.Matches[0].first);\r\n    REQUIRE(result == \"Id3\");\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_SimpleICULike\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    // Insert decomposed character: [upper] A + umlaut\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { u8\"\\x41\\x308wesomeApp\", \"HasUmlaut\", \"Moniker\", \"Version\", \"Channel\", { \"foot\" }, { \"com34\" }, \"Path1\" },\r\n        { u8\"AwesomeApp\", \"Nope\", \"Moniker\", \"Version\", \"Channel\", { \"foot\" }, { \"com34\" }, \"Path2\" },\r\n        });\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    // Search for anything containing: [lower] a + umlaut\r\n    request.Filters.emplace_back(PackageMatchField::Id, MatchType::Substring, u8\"\\xE4\");\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n\r\n    auto result = GetNameStringById(index, results.Matches[0].first);\r\n    REQUIRE(result == \"HasUmlaut\");\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_MaximumResults_Equal\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Nope\", \"Name\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\" },\r\n        { \"Id2\", \"Na\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path2\" },\r\n        { \"Id3\", \"No\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path3\" },\r\n        });\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.MaximumResults = 3;\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 3);\r\n    REQUIRE(!results.Truncated);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_MaximumResults_Less\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Nope\", \"Name\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\" },\r\n        { \"Id2\", \"Na\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path2\" },\r\n        { \"Id3\", \"No\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path3\" },\r\n        });\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.MaximumResults = 2;\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 2);\r\n    REQUIRE(results.Truncated);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_MaximumResults_Greater\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Nope\", \"Name\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\" },\r\n        { \"Id2\", \"Na\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path2\" },\r\n        { \"Id3\", \"No\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path3\" },\r\n        });\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.MaximumResults = 4;\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 3);\r\n    REQUIRE(!results.Truncated);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_QueryAndInclusion\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Nope\", \"Name\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\" },\r\n        { \"Id2\", \"Na\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path2\" },\r\n        { \"Id3\", \"No\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path3\" },\r\n        });\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::CaseInsensitive, \"id3\");\r\n    request.Inclusions.emplace_back(PackageMatchField::Name, MatchType::Substring, \"Na\");\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 3);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_InclusionOnly\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Nope\", \"Name\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\" },\r\n        { \"Id2\", \"Na\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path2\" },\r\n        { \"Id3\", \"No\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path3\" },\r\n        });\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Inclusions.emplace_back(PackageMatchField::Name, MatchType::Substring, \"Na\");\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 2);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_InclusionAndFilter\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Nope\", \"Name\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\" },\r\n        { \"Id2\", \"Na\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path2\" },\r\n        { \"Id3\", \"No\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path3\" },\r\n        });\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Inclusions.emplace_back(PackageMatchField::Name, MatchType::Substring, \"Na\");\r\n    request.Filters.emplace_back(PackageMatchField::Name, MatchType::CaseInsensitive, \"name\");\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n\r\n    auto result = GetIdStringById(index, results.Matches[0].first);\r\n    REQUIRE(result == \"Nope\");\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_QueryInclusionAndFilter\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Nope\", \"Name\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\" },\r\n        { \"Id2\", \"Na\", \"monicka\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path2\" },\r\n        { \"Id3\", \"No\", \"moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path3\" },\r\n        });\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Substring, \"id3\");\r\n    request.Inclusions.emplace_back(PackageMatchField::Name, MatchType::Substring, \"na\");\r\n    request.Filters.emplace_back(PackageMatchField::Moniker, MatchType::CaseInsensitive, \"MONIKER\");\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 2);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_CaseInsensitive\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Nope\", \"id3\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\" },\r\n        { \"Id2\", \"Na\", \"Moniker\", \"Version\", \"Channel\", { \"ID3\" }, { \"Command\" }, \"Path2\" },\r\n        { \"Id3\", \"No\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path3\" },\r\n        });\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::CaseInsensitive, \"id3\");\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 3);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_StartsWith\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"NopeId\", \"id3\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\" },\r\n        { \"Id2\", \"Na\", \"Moniker\", \"Version\", \"Channel\", { \"ID3\" }, { \"Command\" }, \"Path2\" },\r\n        { \"Id3\", \"No\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path3\" },\r\n        });\r\n\r\n    TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Inclusions.push_back(PackageMatchFilter(PackageMatchField::Id, MatchType::StartsWith, \"id\"));\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 2);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_Query_PackageFamilyNameSubstring\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id1\", \"Name1\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\", { \"PFN1\" }, { \"PC1\" } },\r\n        { \"Id2\", \"Name2\", \"Moniker\", \"Version\", \"Channel\", { \"ID3\" }, { \"Command\" }, \"Path2\", { \"PFN2\" }, { \"PC2\" } },\r\n        { \"Id3\", \"Name3\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path3\", { \"PFN3\" }, { \"PC3\" } },\r\n        });\r\n\r\n    SQLiteVersion testVersion = TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Substring, \"PFN\");\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 0);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_Query_ProductCodeSubstring\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id1\", \"Name1\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\", { \"PFN1\" }, { \"PC1\" } },\r\n        { \"Id2\", \"Name2\", \"Moniker\", \"Version\", \"Channel\", { \"ID3\" }, { \"Command\" }, \"Path2\", { \"PFN2\" }, { \"PC2\" } },\r\n        { \"Id3\", \"Name3\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path3\", { \"PFN3\" }, { \"PC3\" } },\r\n        });\r\n\r\n    SQLiteVersion testVersion = TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Substring, \"PC\");\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 0);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_Query_PackageFamilyNameMatch\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id1\", \"Name1\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\", { \"PFN1\" }, { \"PC1\" } },\r\n        { \"Id2\", \"Name2\", \"Moniker\", \"Version\", \"Channel\", { \"ID3\" }, { \"Command\" }, \"Path2\", { \"PFN2\" }, { \"PC2\" } },\r\n        { \"Id3\", \"Name3\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path3\", { \"PFN3\" }, { \"PC3\" } },\r\n        });\r\n\r\n    SQLiteVersion testVersion = TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Substring, \"pfn1\");\r\n\r\n    auto results = index.Search(request);\r\n\r\n    if (ArePackageFamilyNameAndProductCodeSupported(index, testVersion))\r\n    {\r\n        REQUIRE(results.Matches.size() == 1);\r\n    }\r\n    else\r\n    {\r\n        REQUIRE(results.Matches.size() == 0);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_Query_ProductCodeMatch\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id1\", \"Name1\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\", { \"PFN1\" }, { \"PC1\" } },\r\n        { \"Id2\", \"Name2\", \"Moniker\", \"Version\", \"Channel\", { \"ID3\" }, { \"Command\" }, \"Path2\", { \"PFN2\" }, { \"PC2\" } },\r\n        { \"Id3\", \"Name3\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path3\", { \"PFN3\" }, { \"PC3\" } },\r\n        });\r\n\r\n    SQLiteVersion testVersion = TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Substring, \"pc2\");\r\n\r\n    auto results = index.Search(request);\r\n\r\n    if (ArePackageFamilyNameAndProductCodeSupported(index, testVersion))\r\n    {\r\n        REQUIRE(results.Matches.size() == 1);\r\n    }\r\n    else\r\n    {\r\n        REQUIRE(results.Matches.size() == 0);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_PackageFamilyNameSubstring\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id1\", \"Name1\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\", { \"PFN1\" }, { \"PC1\" } },\r\n        { \"Id2\", \"Name2\", \"Moniker\", \"Version\", \"Channel\", { \"ID3\" }, { \"Command\" }, \"Path2\", { \"PFN2\" }, { \"PC2\" } },\r\n        { \"Id3\", \"Name3\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path3\", { \"PFN3\" }, { \"PC3\" } },\r\n        });\r\n\r\n    SQLiteVersion testVersion = TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Inclusions.emplace_back(PackageMatchField::PackageFamilyName, MatchType::Substring, \"PFN\");\r\n\r\n    auto results = index.Search(request);\r\n\r\n    if (ArePackageFamilyNameAndProductCodeSupported(index, testVersion))\r\n    {\r\n        REQUIRE(results.Matches.size() == 3);\r\n    }\r\n    else\r\n    {\r\n        REQUIRE(results.Matches.size() == 0);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_ProductCodeSubstring\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id1\", \"Name1\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\", { \"PFN1\" }, { \"PC1\" } },\r\n        { \"Id2\", \"Name2\", \"Moniker\", \"Version\", \"Channel\", { \"ID3\" }, { \"Command\" }, \"Path2\", { \"PFN2\" }, { \"PC2\" } },\r\n        { \"Id3\", \"Name3\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path3\", { \"PFN3\" }, { \"PC3\" } },\r\n        });\r\n\r\n    SQLiteVersion testVersion = TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Inclusions.emplace_back(PackageMatchField::ProductCode, MatchType::Substring, \"PC\");\r\n\r\n    auto results = index.Search(request);\r\n\r\n    if (ArePackageFamilyNameAndProductCodeSupported(index, testVersion))\r\n    {\r\n        REQUIRE(results.Matches.size() == 3);\r\n    }\r\n    else\r\n    {\r\n        REQUIRE(results.Matches.size() == 0);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_PackageFamilyNameMatch\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id1\", \"Name1\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\", { \"PFN1\" }, { \"PC1\" } },\r\n        { \"Id2\", \"Name2\", \"Moniker\", \"Version\", \"Channel\", { \"ID3\" }, { \"Command\" }, \"Path2\", { \"PFN2\" }, { \"PC2\" } },\r\n        { \"Id3\", \"Name3\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path3\", { \"PFN3\" }, { \"PC3\" } },\r\n        });\r\n\r\n    SQLiteVersion testVersion = TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Inclusions.emplace_back(PackageMatchField::PackageFamilyName, MatchType::Exact, \"pfn1\");\r\n\r\n    auto results = index.Search(request);\r\n\r\n    if (ArePackageFamilyNameAndProductCodeSupported(index, testVersion))\r\n    {\r\n        REQUIRE(results.Matches.size() == 1);\r\n    }\r\n    else\r\n    {\r\n        REQUIRE(results.Matches.size() == 0);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Search_ProductCodeMatch\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id1\", \"Name1\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\", { \"PFN1\" }, { \"PC1\" } },\r\n        { \"Id2\", \"Name2\", \"Moniker\", \"Version\", \"Channel\", { \"ID3\" }, { \"Command\" }, \"Path2\", { \"PFN2\" }, { \"PC2\" } },\r\n        { \"Id3\", \"Name3\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path3\", { \"PFN3\" }, { \"PC3\" } },\r\n        });\r\n\r\n    SQLiteVersion testVersion = TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Inclusions.emplace_back(PackageMatchField::ProductCode, MatchType::Exact, \"pc2\");\r\n\r\n    auto results = index.Search(request);\r\n\r\n    if (ArePackageFamilyNameAndProductCodeSupported(index, testVersion))\r\n    {\r\n        REQUIRE(results.Matches.size() == 1);\r\n    }\r\n    else\r\n    {\r\n        REQUIRE(results.Matches.size() == 0);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_CheckConsistency_Failure\", \"[sqliteindex][V1_1]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    std::string manifest1Path = \"test/id/test.id-1.0.0.yaml\";\r\n    Manifest manifest1;\r\n    manifest1.Installers.push_back({});\r\n    manifest1.Id = \"test.id\";\r\n    manifest1.DefaultLocalization.Add<Localization::PackageName>(\"Test Name\");\r\n    manifest1.Moniker = \"testmoniker\";\r\n    manifest1.Version = \"1.0.0\";\r\n    manifest1.Channel = \"test\";\r\n    manifest1.DefaultLocalization.Add<Localization::Tags>({ \"t1\", \"t2\" });\r\n    manifest1.Installers[0].Commands = { \"test1\", \"test2\" };\r\n\r\n    std::string manifest2Path = \"test/woah/test.id-1.0.0.yaml\";\r\n    Manifest manifest2;\r\n    manifest2.Installers.push_back({});\r\n    manifest2.Id = \"test.woah\";\r\n    manifest2.DefaultLocalization.Add<Localization::PackageName>(\"Test Name WOAH\");\r\n    manifest2.Moniker = \"testmoniker\";\r\n    manifest2.Version = \"1.0.0\";\r\n    manifest2.Channel = \"test\";\r\n    manifest2.DefaultLocalization.Add<Localization::Tags>({});\r\n    manifest2.Installers[0].Commands = { \"test1\", \"test2\", \"test3\" };\r\n\r\n    rowid_t manifestRowId = 0;\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::CreateNew(tempFile, { 1, 1 });\r\n\r\n        index.AddManifest(manifest1, manifest1Path);\r\n        index.AddManifest(manifest2, manifest2Path);\r\n\r\n        // Get the first manifest's id for removal\r\n        SearchRequest request;\r\n        request.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, manifest1.Id));\r\n        auto result = index.Search(request);\r\n\r\n        REQUIRE(result.Matches.size() == 1);\r\n        manifestRowId = result.Matches[0].first;\r\n    }\r\n\r\n    {\r\n        // Open it directly to modify the table\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n\r\n        Builder::StatementBuilder builder;\r\n        builder.DeleteFrom(Schema::V1_0::IdTable::TableName()).Where(RowIDName).Equals(manifestRowId);\r\n        builder.Execute(connection);\r\n    }\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n\r\n        REQUIRE(!index.CheckConsistency(true));\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_GetMultiProperty_PackageFamilyName\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id1\", \"Name1\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\", { \"PFN1\", \"PFN2\" }, {} },\r\n        });\r\n\r\n    SQLiteVersion testVersion = TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n\r\n    auto props = index.GetMultiPropertyByPrimaryId(results.Matches[0].first, PackageVersionMultiProperty::PackageFamilyName);\r\n\r\n    if (ArePackageFamilyNameAndProductCodeSupported(index, testVersion))\r\n    {\r\n        REQUIRE(props.size() == 2);\r\n        REQUIRE(std::find(props.begin(), props.end(), FoldCase(\"PFN1\"sv)) != props.end());\r\n        REQUIRE(std::find(props.begin(), props.end(), FoldCase(\"PFN2\"sv)) != props.end());\r\n    }\r\n    else\r\n    {\r\n        REQUIRE(props.empty());\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_GetMultiProperty_ProductCode\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id1\", \"Name1\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\", {}, { \"PC1\", \"PC2\" } },\r\n        });\r\n\r\n    SQLiteVersion testVersion = TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n\r\n    auto props = index.GetMultiPropertyByPrimaryId(results.Matches[0].first, PackageVersionMultiProperty::ProductCode);\r\n\r\n    if (ArePackageFamilyNameAndProductCodeSupported(index, testVersion))\r\n    {\r\n        REQUIRE(props.size() == 2);\r\n        REQUIRE(std::find(props.begin(), props.end(), FoldCase(\"PC1\"sv)) != props.end());\r\n        REQUIRE(std::find(props.begin(), props.end(), FoldCase(\"PC2\"sv)) != props.end());\r\n    }\r\n    else\r\n    {\r\n        REQUIRE(props.empty());\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_GetMultiProperty_Tag\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id1\", \"Name1\", \"Moniker\", \"Version\", \"Channel\", { \"Tag1\", \"Tag2\" }, { \"Command\" }, \"Path1\", {}, { \"PC1\", \"PC2\" } },\r\n        });\r\n\r\n    SQLiteVersion testVersion = TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n\r\n    auto props = index.GetMultiPropertyByPrimaryId(results.Matches[0].first, PackageVersionMultiProperty::Tag);\r\n\r\n    REQUIRE(props.size() == 2);\r\n    REQUIRE(std::find(props.begin(), props.end(), \"Tag1\") != props.end());\r\n    REQUIRE(std::find(props.begin(), props.end(), \"Tag2\") != props.end());\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_GetMultiProperty_Command\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id1\", \"Name1\", \"Moniker\", \"Version\", \"Channel\", { \"Tag1\", \"Tag2\" }, { \"Command\" }, \"Path1\", {}, { \"PC1\", \"PC2\" } },\r\n        });\r\n\r\n    SQLiteVersion testVersion = TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n\r\n    auto props = index.GetMultiPropertyByPrimaryId(results.Matches[0].first, PackageVersionMultiProperty::Command);\r\n\r\n    REQUIRE(props.size() == 1);\r\n    REQUIRE(props[0] == \"Command\");\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_ManifestMetadata\", \"[sqliteindex][V1_7]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id1\", \"Name1\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\", {}, { \"PC1\", \"PC2\" } },\r\n        { \"Id2\", \"Name2\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path2\", { \"PFN1\", \"PFN2\" }, {} },\r\n        }, SQLiteVersion{ 1, 7 });\r\n\r\n    SQLiteVersion testVersion = TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n\r\n    auto results = index.Search(request);\r\n    REQUIRE(results.Matches.size() == 2);\r\n\r\n    for (const auto [id, match] : results.Matches)\r\n    {\r\n        REQUIRE(index.GetMetadataByManifestId(id).empty());\r\n    }\r\n\r\n    auto manifestId1 = results.Matches[0].first;\r\n    auto manifestId2 = results.Matches[1].first;\r\n\r\n    std::string metadataValue = \"data about data\";\r\n\r\n    index.SetMetadataByManifestId(manifestId1, PackageVersionMetadata::InstalledType, metadataValue);\r\n\r\n    if (IsManifestMetadataSupported(index, testVersion))\r\n    {\r\n        auto metadataResult = index.GetMetadataByManifestId(manifestId1);\r\n        REQUIRE(metadataResult.size() == 1);\r\n        REQUIRE(metadataResult[0].first == PackageVersionMetadata::InstalledType);\r\n        REQUIRE(metadataResult[0].second == metadataValue);\r\n    }\r\n    else\r\n    {\r\n        REQUIRE(index.GetMetadataByManifestId(manifestId1).empty());\r\n    }\r\n\r\n    REQUIRE(index.GetMetadataByManifestId(manifestId2).empty());\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_NormNameAndPublisher_Exact\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    std::string testName = \"Name\";\r\n    std::string testPublisher = \"Publisher\";\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id1\", testName, testPublisher, \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\", {}, { \"PC1\", \"PC2\" } },\r\n        });\r\n\r\n    SQLiteVersion testVersion = TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::NormalizedNameAndPublisher, MatchType::Exact, testName, testPublisher));\r\n\r\n    auto results = index.Search(request);\r\n\r\n    if (AreNormalizedNameAndPublisherSupported(index, testVersion))\r\n    {\r\n        REQUIRE(results.Matches.size() == 1);\r\n    }\r\n    else\r\n    {\r\n        REQUIRE(results.Matches.empty());\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_NormNameAndPublisher_Simple\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    std::string testName = \"Name\";\r\n    std::string testPublisher = \"Publisher\";\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id1\", testName, testPublisher, \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\", {}, { \"PC1\", \"PC2\" } },\r\n        });\r\n\r\n    SQLiteVersion testVersion = TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::NormalizedNameAndPublisher, MatchType::Exact, testName + \" 1.0\", testPublisher + \" Corporation\"));\r\n\r\n    auto results = index.Search(request);\r\n\r\n    if (AreNormalizedNameAndPublisherSupported(index, testVersion))\r\n    {\r\n        REQUIRE(results.Matches.size() == 1);\r\n    }\r\n    else\r\n    {\r\n        REQUIRE(results.Matches.empty());\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_NormNameAndPublisher_Complex\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    std::string testName = \"Name\";\r\n    std::string testPublisher = \"Publisher\";\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id1\", testName, testPublisher, \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\", {}, { \"PC1\", \"PC2\" } },\r\n        { \"Id2\", testName, \"Different Publisher\", \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path2\", {}, { \"PC1\", \"PC2\" } },\r\n        });\r\n\r\n    SQLiteVersion testVersion = TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::NormalizedNameAndPublisher, MatchType::Exact, testName + \" 1.0\", testPublisher));\r\n\r\n    auto results = index.Search(request);\r\n\r\n    if (AreNormalizedNameAndPublisherSupported(index, testVersion))\r\n    {\r\n        REQUIRE(results.Matches.size() == 1);\r\n    }\r\n    else\r\n    {\r\n        REQUIRE(results.Matches.empty());\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_NormNameAndPublisher_AppsAndFeatures\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    std::string testName = \"Name\";\r\n    std::string testPublisher = \"Publisher\";\r\n    std::string arpTestName = \"Other Thing\";\r\n    std::string arpTestPublisher = \"Big Company Name\";\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id1\", testName, testPublisher, \"Moniker\", \"Version\", \"Channel\", { \"Tag\" }, { \"Command\" }, \"Path1\", {}, { \"PC1\", \"PC2\" }, arpTestName, arpTestPublisher },\r\n        });\r\n\r\n    SQLiteVersion testVersion = TestPrepareForRead(index);\r\n\r\n    SearchRequest request;\r\n    request.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::NormalizedNameAndPublisher, MatchType::Exact, arpTestName, arpTestPublisher));\r\n\r\n    auto results = index.Search(request);\r\n\r\n    if (AreNormalizedNameAndPublisherSupported(index, testVersion))\r\n    {\r\n        REQUIRE(results.Matches.size() == 1);\r\n    }\r\n    else\r\n    {\r\n        REQUIRE(results.Matches.empty());\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_ManifestHash_Present\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    uint8_t data[4] = { 1, 2, 3, 4 };\r\n    SHA256::HashBuffer hash = SHA256::ComputeHash(data, sizeof(data));\r\n\r\n    SQLiteIndex index = CreateTestIndex(tempFile);\r\n\r\n    Manifest manifest;\r\n    manifest.Id = \"Foo\";\r\n    manifest.Version = \"Bar\";\r\n    manifest.StreamSha256 = hash;\r\n    index.AddManifest(manifest, \"path\");\r\n\r\n    SQLiteVersion testVersion = TestPrepareForRead(index);\r\n\r\n    auto results = index.Search({});\r\n    REQUIRE(results.Matches.size() == 1);\r\n\r\n    auto hashResult = index.GetPropertyByPrimaryId(results.Matches[0].first, PackageVersionProperty::ManifestSHA256Hash);\r\n\r\n    // Regardless of what hash, it should still be a SHA256 hash\r\n    REQUIRE(hashResult);\r\n    auto hashResultBytes = SHA256::ConvertToBytes(hashResult.value());\r\n    REQUIRE(hash.size() == hashResultBytes.size());\r\n\r\n    if (AreManifestHashesSupported(index, testVersion))\r\n    {\r\n        REQUIRE(std::equal(hash.begin(), hash.end(), hashResultBytes.begin()));\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_ManifestHash_Missing\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = CreateTestIndex(tempFile);\r\n\r\n    Manifest manifest;\r\n    manifest.Id = \"Foo\";\r\n    manifest.Version = \"Bar\";\r\n    index.AddManifest(manifest, \"path\");\r\n\r\n    SQLiteVersion testVersion = TestPrepareForRead(index);\r\n\r\n    auto results = index.Search({});\r\n    REQUIRE(results.Matches.size() == 1);\r\n\r\n    auto hashResult = index.GetPropertyByPrimaryId(results.Matches[0].first, PackageVersionProperty::ManifestSHA256Hash);\r\n\r\n    if (AreManifestHashesSupported(index, testVersion))\r\n    {\r\n        REQUIRE(!hashResult);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_ManifestArpVersion_Present_Add\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = CreateTestIndex(tempFile);\r\n\r\n    Manifest manifest;\r\n    manifest.Id = \"Foo\";\r\n    manifest.Version = \"Bar\";\r\n    manifest.Installers.push_back({});\r\n    manifest.Installers[0].BaseInstallerType = InstallerTypeEnum::Exe;\r\n    manifest.Installers[0].AppsAndFeaturesEntries.push_back({});\r\n    manifest.Installers[0].AppsAndFeaturesEntries[0].DisplayVersion = \"1.0\";\r\n    manifest.Installers[0].AppsAndFeaturesEntries.push_back({});\r\n    manifest.Installers[0].AppsAndFeaturesEntries[1].DisplayVersion = \"1.1\";\r\n\r\n    index.AddManifest(manifest, \"path\");\r\n\r\n    SQLiteVersion testVersion = TestPrepareForRead(index);\r\n\r\n    auto results = index.Search({});\r\n    REQUIRE(results.Matches.size() == 1);\r\n\r\n    auto arpMin = index.GetPropertyByPrimaryId(results.Matches[0].first, PackageVersionProperty::ArpMinVersion);\r\n    auto arpMax = index.GetPropertyByPrimaryId(results.Matches[0].first, PackageVersionProperty::ArpMaxVersion);\r\n\r\n    if (AreArpVersionsSupported(index, testVersion))\r\n    {\r\n        REQUIRE(arpMin);\r\n        REQUIRE(UtilityVersion(arpMin.value()) == UtilityVersion(manifest.Installers[0].AppsAndFeaturesEntries[0].DisplayVersion));\r\n        REQUIRE(arpMax);\r\n        REQUIRE(UtilityVersion(arpMax.value()) == UtilityVersion(manifest.Installers[0].AppsAndFeaturesEntries[1].DisplayVersion));\r\n    }\r\n    else\r\n    {\r\n        REQUIRE_FALSE(arpMin);\r\n        REQUIRE_FALSE(arpMax);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_ManifestArpVersion_Present_AddThenUpdate\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = CreateTestIndex(tempFile);\r\n\r\n    Manifest manifest;\r\n    manifest.Id = \"Foo\";\r\n    manifest.Version = \"Bar\";\r\n    manifest.Installers.push_back({});\r\n    manifest.Installers[0].BaseInstallerType = InstallerTypeEnum::Exe;\r\n    manifest.Installers[0].AppsAndFeaturesEntries.push_back({});\r\n    manifest.Installers[0].AppsAndFeaturesEntries[0].DisplayVersion = \"1.0\";\r\n    manifest.Installers[0].AppsAndFeaturesEntries.push_back({});\r\n    manifest.Installers[0].AppsAndFeaturesEntries[1].DisplayVersion = \"1.1\";\r\n\r\n    index.AddManifest(manifest, \"path\");\r\n\r\n    manifest.Installers[0].AppsAndFeaturesEntries[0].DisplayVersion = \"1.1\";\r\n\r\n    index.UpdateManifest(manifest, \"path\");\r\n\r\n    SQLiteVersion testVersion = TestPrepareForRead(index);\r\n\r\n    auto results = index.Search({});\r\n    REQUIRE(results.Matches.size() == 1);\r\n\r\n    auto arpMin = index.GetPropertyByPrimaryId(results.Matches[0].first, PackageVersionProperty::ArpMinVersion);\r\n    auto arpMax = index.GetPropertyByPrimaryId(results.Matches[0].first, PackageVersionProperty::ArpMaxVersion);\r\n\r\n    if (AreArpVersionsSupported(index, testVersion))\r\n    {\r\n        REQUIRE(arpMin);\r\n        REQUIRE(arpMin.value() == \"1.1\");\r\n        REQUIRE(arpMax);\r\n        REQUIRE(arpMax.value() == \"1.1\");\r\n    }\r\n    else\r\n    {\r\n        REQUIRE_FALSE(arpMin);\r\n        REQUIRE_FALSE(arpMax);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_ManifestArpVersion_Empty\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = CreateTestIndex(tempFile);\r\n\r\n    Manifest manifest;\r\n    manifest.Id = \"Foo\";\r\n    manifest.Version = \"Bar\";\r\n    index.AddManifest(manifest, \"path\");\r\n\r\n    SQLiteVersion testVersion = TestPrepareForRead(index);\r\n\r\n    auto results = index.Search({});\r\n    REQUIRE(results.Matches.size() == 1);\r\n\r\n    auto arpMin = index.GetPropertyByPrimaryId(results.Matches[0].first, PackageVersionProperty::ArpMinVersion);\r\n    auto arpMax = index.GetPropertyByPrimaryId(results.Matches[0].first, PackageVersionProperty::ArpMaxVersion);\r\n\r\n    if (AreArpVersionsSupported(index, testVersion) && !AreArpVersionsNullable(index))\r\n    {\r\n        REQUIRE(arpMin);\r\n        REQUIRE(arpMin.value() == \"\");\r\n        REQUIRE(arpMax);\r\n        REQUIRE(arpMax.value() == \"\");\r\n    }\r\n    else\r\n    {\r\n        REQUIRE_FALSE(arpMin);\r\n        REQUIRE_FALSE(arpMax);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_RemoveManifestArpVersionKeepUsedDeleteUnused\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = CreateTestIndex(tempFile, SQLiteVersion::Latest());\r\n\r\n    Manifest manifest;\r\n    manifest.Id = \"Foo\";\r\n    manifest.Version = \"10.0\";\r\n    manifest.Installers.push_back({});\r\n    manifest.Installers[0].BaseInstallerType = InstallerTypeEnum::Exe;\r\n    manifest.Installers[0].AppsAndFeaturesEntries.push_back({});\r\n    manifest.Installers[0].AppsAndFeaturesEntries[0].DisplayVersion = \"1.0\";\r\n    manifest.Installers[0].AppsAndFeaturesEntries.push_back({});\r\n    manifest.Installers[0].AppsAndFeaturesEntries[1].DisplayVersion = \"1.1\";\r\n\r\n    index.AddManifest(manifest, \"path\");\r\n\r\n    Manifest manifest2;\r\n    manifest2.Id = \"Foo2\";\r\n    manifest2.Version = \"1.0\";\r\n    manifest2.Installers.push_back({});\r\n    manifest2.Installers[0].BaseInstallerType = InstallerTypeEnum::Exe;\r\n    manifest2.Installers[0].AppsAndFeaturesEntries.push_back({});\r\n    manifest2.Installers[0].AppsAndFeaturesEntries[0].DisplayVersion = \"10.0\";\r\n\r\n    index.AddManifest(manifest2, \"path2\");\r\n\r\n    // Before removing, \"10.0\", \"1.0\" and \"1.1\" should all exist.\r\n    {\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadOnly);\r\n        REQUIRE(Schema::V1_0::VersionTable::SelectIdByValue(connection, \"10.0\").has_value());\r\n        REQUIRE(Schema::V1_0::VersionTable::SelectIdByValue(connection, \"1.0\").has_value());\r\n        REQUIRE(Schema::V1_0::VersionTable::SelectIdByValue(connection, \"1.1\").has_value());\r\n    }\r\n\r\n    index.RemoveManifest(manifest);\r\n\r\n    // After removing the first manifest, \"10.0\" and \"1.0\" should still stay, \"1.1\" should be removed.\r\n    {\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadOnly);\r\n        REQUIRE(Schema::V1_0::VersionTable::SelectIdByValue(connection, \"10.0\").has_value());\r\n        REQUIRE(Schema::V1_0::VersionTable::SelectIdByValue(connection, \"1.0\").has_value());\r\n        REQUIRE_FALSE(Schema::V1_0::VersionTable::SelectIdByValue(connection, \"1.1\").has_value());\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_ManifestArpVersionConflict_AddThrows\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = CreateTestIndex(tempFile, SQLiteVersion::Latest());\r\n\r\n    Manifest manifest;\r\n    manifest.Id = \"Foo\";\r\n    manifest.Version = \"10.0\";\r\n    manifest.DefaultLocalization.Add<Localization::PackageName>(\"ArpVersionCheckConsistencyTest\");\r\n    manifest.Moniker = \"testmoniker\";\r\n    manifest.Installers.push_back({});\r\n    manifest.Installers[0].BaseInstallerType = InstallerTypeEnum::Exe;\r\n    manifest.Installers[0].AppsAndFeaturesEntries.push_back({});\r\n    manifest.Installers[0].AppsAndFeaturesEntries[0].DisplayVersion = \"1.0\";\r\n    manifest.Installers[0].AppsAndFeaturesEntries.push_back({});\r\n    manifest.Installers[0].AppsAndFeaturesEntries[1].DisplayVersion = \"1.1\";\r\n\r\n    index.AddManifest(manifest, \"path\");\r\n\r\n    REQUIRE(index.CheckConsistency(true));\r\n\r\n    // Add a conflicting one\r\n    manifest.Version = \"10.1\";\r\n\r\n    REQUIRE_THROWS_HR(index.AddManifest(manifest, \"path2\"), APPINSTALLER_CLI_ERROR_ARP_VERSION_VALIDATION_FAILED);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_ManifestArpVersionConflict_UpdateThrows\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = CreateTestIndex(tempFile, SQLiteVersion::Latest());\r\n\r\n    Manifest manifest;\r\n    manifest.Id = \"Foo\";\r\n    manifest.Version = \"10.0\";\r\n    manifest.DefaultLocalization.Add<Localization::PackageName>(\"ArpVersionCheckConsistencyTest\");\r\n    manifest.Moniker = \"testmoniker\";\r\n    manifest.Installers.push_back({});\r\n    manifest.Installers[0].BaseInstallerType = InstallerTypeEnum::Exe;\r\n    manifest.Installers[0].AppsAndFeaturesEntries.push_back({});\r\n    manifest.Installers[0].AppsAndFeaturesEntries[0].DisplayVersion = \"1.0\";\r\n    manifest.Installers[0].AppsAndFeaturesEntries.push_back({});\r\n    manifest.Installers[0].AppsAndFeaturesEntries[1].DisplayVersion = \"1.1\";\r\n\r\n    index.AddManifest(manifest, \"path\");\r\n    REQUIRE(index.CheckConsistency(true));\r\n\r\n    // Add another version\r\n    manifest.Version = \"10.1\";\r\n    manifest.Installers[0].AppsAndFeaturesEntries[0].DisplayVersion = \"2.0\";\r\n    manifest.Installers[0].AppsAndFeaturesEntries[1].DisplayVersion = \"2.1\";\r\n\r\n    index.AddManifest(manifest, \"path2\");\r\n    REQUIRE(index.CheckConsistency(true));\r\n\r\n    // Update to a conflict\r\n    manifest.Installers[0].AppsAndFeaturesEntries[0].DisplayVersion = \"1.0\";\r\n    manifest.Installers[0].AppsAndFeaturesEntries[1].DisplayVersion = \"2.1\";\r\n\r\n    REQUIRE_THROWS_HR(index.UpdateManifest(manifest, \"path2\"), APPINSTALLER_CLI_ERROR_ARP_VERSION_VALIDATION_FAILED);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_ManifestArpVersion_ValidateManifestAgainstIndex\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = CreateTestIndex(tempFile, SQLiteVersion::Latest());\r\n\r\n    Manifest manifest;\r\n    manifest.Id = \"Foo\";\r\n    manifest.Version = \"10.0\";\r\n    manifest.Installers.push_back({});\r\n    manifest.Installers[0].BaseInstallerType = InstallerTypeEnum::Exe;\r\n    manifest.Installers[0].AppsAndFeaturesEntries.push_back({});\r\n    manifest.Installers[0].AppsAndFeaturesEntries[0].DisplayVersion = \"1.0\";\r\n    manifest.Installers[0].AppsAndFeaturesEntries.push_back({});\r\n    manifest.Installers[0].AppsAndFeaturesEntries[1].DisplayVersion = \"1.1\";\r\n\r\n    index.AddManifest(manifest, \"path\");\r\n\r\n    // Updating same version should not result in failure.\r\n    REQUIRE_NOTHROW(ValidateManifestArpVersion(&index, manifest));\r\n\r\n    // Add different version should result in failure.\r\n    manifest.Version = \"10.1\";\r\n    REQUIRE_THROWS(ValidateManifestArpVersion(&index, manifest));\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_CheckConsistency_FindEmbeddedNull\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SQLiteIndex index = CreateTestIndex(tempFile, SQLiteVersion::Latest());\r\n\r\n    Manifest manifest;\r\n    manifest.Id = \"Foo\";\r\n    manifest.Version = \"10.0\";\r\n    manifest.Installers.push_back({});\r\n    manifest.Installers[0].BaseInstallerType = InstallerTypeEnum::Exe;\r\n    manifest.Installers[0].AppsAndFeaturesEntries.push_back({});\r\n    manifest.Installers[0].AppsAndFeaturesEntries[0].DisplayVersion = \"1.0\";\r\n    manifest.Installers[0].AppsAndFeaturesEntries.push_back({});\r\n    manifest.Installers[0].AppsAndFeaturesEntries[1].DisplayVersion = \"1.1\";\r\n\r\n    index.AddManifest(manifest, \"path\");\r\n\r\n    // Inject a null character using SQL without binding since we block it\r\n    Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n    Statement update = Statement::Create(connection, \"Update versions set version = '10.0'||char(0)||'After Null' where version = '10.0'\");\r\n    update.Execute();\r\n\r\n    REQUIRE(!index.CheckConsistency(true));\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_MapDataFolding_Tags\", \"[sqliteindex][mapdatafolding]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    std::string tag1 = \"Tag1\";\r\n    std::string tag2 = \"Tag2\";\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id\", \"Name\", \"Publisher\", \"Moniker\", \"Version1\", \"\", { tag1 }, { \"Command\" }, \"Path1\", {}, { \"PC1\" } },\r\n        { \"Id\", \"Name\", \"Publisher\", \"Moniker\", \"Version2\", \"\", { tag2 }, { \"Command\" }, \"Path2\", {}, { \"PC2\" } },\r\n        });\r\n\r\n    SQLiteVersion testVersion = TestPrepareForRead(index);\r\n\r\n    SearchRequest request1;\r\n    request1.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::Tag, MatchType::Exact, tag1));\r\n    auto results1 = index.Search(request1);\r\n\r\n    SearchRequest request2;\r\n    request2.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::Tag, MatchType::Exact, tag2));\r\n    auto results2 = index.Search(request2);\r\n\r\n    REQUIRE(results1.Matches.size() == 1);\r\n    REQUIRE(results2.Matches.size() == 1);\r\n    REQUIRE(results1.Matches[0].first == results2.Matches[0].first);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_MapDataFolding_PFNs\", \"[sqliteindex][mapdatafolding]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    std::string pfn1 = \"PFN1\";\r\n    std::string pfn2 = \"PFN2\";\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id\", \"Name\", \"Publisher\", \"Moniker\", \"Version1\", \"\", { }, { \"Command\" }, \"Path1\", { pfn1 }, { } },\r\n        { \"Id\", \"Name\", \"Publisher\", \"Moniker\", \"Version2\", \"\", { }, { \"Command\" }, \"Path2\", { pfn2 }, { } },\r\n        });\r\n\r\n    SQLiteVersion testVersion = TestPrepareForRead(index);\r\n\r\n    if (!AreChannelsSupported(index))\r\n    {\r\n        return;\r\n    }\r\n\r\n    SearchRequest request1;\r\n    request1.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::PackageFamilyName, MatchType::Exact, pfn1));\r\n    auto results1 = index.Search(request1);\r\n\r\n    SearchRequest request2;\r\n    request2.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::PackageFamilyName, MatchType::Exact, pfn2));\r\n    auto results2 = index.Search(request2);\r\n\r\n    REQUIRE(results1.Matches.size() == 1);\r\n    REQUIRE(results2.Matches.size() == 1);\r\n    REQUIRE(results1.Matches[0].first == results2.Matches[0].first);\r\n\r\n    auto versionKeys = index.GetVersionKeysById(results1.Matches[0].first);\r\n    REQUIRE(versionKeys.size() == 2);\r\n\r\n    auto manifestId1 = versionKeys[0].ManifestId;\r\n    auto manifestId2 = versionKeys[1].ManifestId;\r\n\r\n    auto pfnValues1 = index.GetMultiPropertyByPrimaryId(manifestId1, PackageVersionMultiProperty::PackageFamilyName);\r\n    auto pfnValues2 = index.GetMultiPropertyByPrimaryId(manifestId2, PackageVersionMultiProperty::PackageFamilyName);\r\n\r\n    if (IsMapDataFoldingSupported(index, testVersion))\r\n    {\r\n        REQUIRE(pfnValues1.size() == 2);\r\n        REQUIRE(pfnValues2.size() == 2);\r\n        REQUIRE(pfnValues1[0] != pfnValues1[1]);\r\n    }\r\n    else if (IsMapDataFolded(index))\r\n    {\r\n        if (manifestId1 > manifestId2)\r\n        {\r\n            REQUIRE(pfnValues1.size() == 2);\r\n            REQUIRE(pfnValues2.size() == 0);\r\n            REQUIRE(pfnValues1[0] != pfnValues1[1]);\r\n        }\r\n        else\r\n        {\r\n            REQUIRE(pfnValues1.size() == 0);\r\n            REQUIRE(pfnValues2.size() == 2);\r\n            REQUIRE(pfnValues2[0] != pfnValues2[1]);\r\n        }\r\n    }\r\n    else\r\n    {\r\n        REQUIRE(pfnValues1.size() == 1);\r\n        REQUIRE(pfnValues2.size() == 1);\r\n        REQUIRE(pfnValues1[0] != pfnValues2[0]);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_MapDataFolding_ProductCodes\", \"[sqliteindex][mapdatafolding]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    std::string pc1 = \"PC1\";\r\n    std::string pc2 = \"PC2\";\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { \"Id\", \"Name\", \"Publisher\", \"Moniker\", \"Version1\", \"\", { }, { \"Command\" }, \"Path1\", { }, { pc1 } },\r\n        { \"Id\", \"Name\", \"Publisher\", \"Moniker\", \"Version2\", \"\", { }, { \"Command\" }, \"Path2\", { }, { pc2 } },\r\n        });\r\n\r\n    SQLiteVersion testVersion = TestPrepareForRead(index);\r\n\r\n    if (!AreChannelsSupported(index))\r\n    {\r\n        return;\r\n    }\r\n\r\n    SearchRequest request1;\r\n    request1.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::ProductCode, MatchType::Exact, pc1));\r\n    auto results1 = index.Search(request1);\r\n\r\n    SearchRequest request2;\r\n    request2.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::ProductCode, MatchType::Exact, pc2));\r\n    auto results2 = index.Search(request2);\r\n\r\n    REQUIRE(results1.Matches.size() == 1);\r\n    REQUIRE(results2.Matches.size() == 1);\r\n    REQUIRE(results1.Matches[0].first == results2.Matches[0].first);\r\n\r\n    auto versionKeys = index.GetVersionKeysById(results1.Matches[0].first);\r\n    REQUIRE(versionKeys.size() == 2);\r\n\r\n    auto manifestId1 = versionKeys[0].ManifestId;\r\n    auto manifestId2 = versionKeys[1].ManifestId;\r\n\r\n    auto pcValues1 = index.GetMultiPropertyByPrimaryId(manifestId1, PackageVersionMultiProperty::ProductCode);\r\n    auto pcValues2 = index.GetMultiPropertyByPrimaryId(manifestId2, PackageVersionMultiProperty::ProductCode);\r\n\r\n    REQUIRE(pcValues1.size() == 1);\r\n    REQUIRE(pcValues2.size() == 1);\r\n    REQUIRE(pcValues1[0] != pcValues2[0]);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_FilePath_Memory\", \"[sqliteindex]\")\r\n{\r\n    SQLiteIndex index = SQLiteIndex::CreateNew(SQLITE_MEMORY_DB_CONNECTION_TARGET);\r\n    auto contextData = index.GetContextData();\r\n    REQUIRE(!contextData.Contains(Schema::Property::DatabaseFilePath));\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_FilePath_Create\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n\r\n    SQLiteIndex index = SQLiteIndex::CreateNew(tempFile);\r\n    auto contextData = index.GetContextData();\r\n    REQUIRE(contextData.Contains(Schema::Property::DatabaseFilePath));\r\n    REQUIRE(contextData.Get<Schema::Property::DatabaseFilePath>() == tempFile.GetPath());\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_FilePath_Open\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::CreateNew(tempFile);\r\n    }\r\n\r\n    SQLiteIndex index = SQLiteIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::Read);\r\n    auto contextData = index.GetContextData();\r\n    REQUIRE(contextData.Contains(Schema::Property::DatabaseFilePath));\r\n    REQUIRE(contextData.Get<Schema::Property::DatabaseFilePath>() == tempFile.GetPath());\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_MigrateTo_Unsupported\", \"[sqliteindex][V1_7]\")\r\n{\r\n    SQLiteIndex index = SQLiteIndex::CreateNew(SQLITE_MEMORY_DB_CONNECTION_TARGET, SQLiteVersion{ 1, 6 });\r\n    REQUIRE(!index.MigrateTo(SQLiteVersion{ 1, 7 }));\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_MigrateTo_Empty\", \"[sqliteindex][V2_0]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::CreateNew(tempFile, SQLiteVersion{ 1, 7 });\r\n        REQUIRE(index.MigrateTo(SQLiteVersion{ 2, 0 }));\r\n        REQUIRE(index.GetVersion() == SQLiteVersion{ 2, 0 });\r\n    }\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::Read);\r\n        REQUIRE(index.GetVersion() == SQLiteVersion{ 2, 0 });\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_MigrateTo_Data\", \"[sqliteindex][V2_0]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    std::string packageId1 = \"Id1\";\r\n    std::string packageId2 = \"Id2\";\r\n    std::string packageId3 = \"Id3\";\r\n\r\n    SQLiteIndex index = SearchTestSetup(tempFile, {\r\n        { packageId1, \"Name1\", \"Moniker\", \"Version\", \"\", { \"Tag\" }, { \"Command\" }, \"Path1\", { \"PFN1\" }, { \"PC1\" } },\r\n        { packageId2, \"Name2\", \"Moniker\", \"Version\", \"\", { \"ID3\" }, { \"Command\" }, \"Path2\", { \"PFN2\" }, { \"PC2\" } },\r\n        { packageId3, \"Name3\", \"Moniker\", \"Version\", \"\", { \"Tag\" }, { \"Command\" }, \"Path3\", { \"PFN3\" }, { \"PC3\" } },\r\n        });\r\n\r\n    auto preMigrationVersion = index.GetVersion();\r\n\r\n    if (preMigrationVersion == SQLiteVersion{ 1, 7 })\r\n    {\r\n        REQUIRE(index.MigrateTo(SQLiteVersion{ 2, 0 }));\r\n        REQUIRE(index.GetVersion() == SQLiteVersion{ 2, 0 });\r\n\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n        auto updateData = Schema::V2_0::PackageUpdateTrackingTable::GetUpdatesSince(connection, 0);\r\n\r\n        REQUIRE(updateData.size() == 3);\r\n        REQUIRE(std::count_if(updateData.begin(), updateData.end(), [&](const auto& x) { return x.PackageIdentifier == packageId1; }) == 1);\r\n        REQUIRE(std::count_if(updateData.begin(), updateData.end(), [&](const auto& x) { return x.PackageIdentifier == packageId2; }) == 1);\r\n        REQUIRE(std::count_if(updateData.begin(), updateData.end(), [&](const auto& x) { return x.PackageIdentifier == packageId3; }) == 1);\r\n    }\r\n    else\r\n    {\r\n        REQUIRE(!index.MigrateTo(SQLiteVersion{ 2, 0 }));\r\n        REQUIRE(index.GetVersion() == preMigrationVersion);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_Property_IntermediateFilePath\", \"[sqliteindex]\")\r\n{\r\n    SQLiteIndex index = SQLiteIndex::CreateNew(SQLITE_MEMORY_DB_CONNECTION_TARGET);\r\n    std::filesystem::path intermediateFilePath = \"A:\\\\Path\";\r\n    index.SetProperty(SQLiteIndex::Property::IntermediateFileOutputPath, intermediateFilePath.u8string());\r\n\r\n    auto contextData = index.GetContextData();\r\n    REQUIRE(contextData.Contains(Schema::Property::IntermediateFileOutputPath));\r\n    REQUIRE(contextData.Get<Schema::Property::IntermediateFileOutputPath>() == intermediateFilePath);\r\n}\r\n\r\nstruct ManifestAndPath\r\n{\r\n    Manifest Manifest;\r\n    std::string Path;\r\n};\r\n\r\nvoid CreateFakeManifestAndPath(\r\n    ManifestAndPath& manifestAndPath,\r\n    const string_t& publisher,\r\n    std::string_view version = \"1.0.0\",\r\n    std::optional<std::string_view> arpMinVersion = {},\r\n    std::optional<std::string_view> arpMaxVersion = {})\r\n{\r\n    CreateFakeManifest(manifestAndPath.Manifest, publisher, version);\r\n    manifestAndPath.Path = ConvertToUTF8(CreateNewGuidNameWString());\r\n    manifestAndPath.Manifest.StreamSha256 = SHA256::ComputeHash(manifestAndPath.Path);\r\n\r\n    if (arpMinVersion)\r\n    {\r\n        manifestAndPath.Manifest.Installers[0].BaseInstallerType = InstallerTypeEnum::Exe;\r\n        manifestAndPath.Manifest.Installers[0].AppsAndFeaturesEntries.push_back({});\r\n        manifestAndPath.Manifest.Installers[0].AppsAndFeaturesEntries.back().DisplayVersion = arpMinVersion.value();\r\n    }\r\n\r\n    if (arpMaxVersion)\r\n    {\r\n        manifestAndPath.Manifest.Installers[0].BaseInstallerType = InstallerTypeEnum::Exe;\r\n        manifestAndPath.Manifest.Installers[0].AppsAndFeaturesEntries.push_back({});\r\n        manifestAndPath.Manifest.Installers[0].AppsAndFeaturesEntries.back().DisplayVersion = arpMaxVersion.value();\r\n    }\r\n}\r\n\r\nstd::filesystem::path GetOnlyChild(const std::filesystem::path& parent)\r\n{\r\n    auto parentDirectoryIterator = std::filesystem::directory_iterator{ parent };\r\n    std::filesystem::path result = parentDirectoryIterator->path();\r\n    REQUIRE(++parentDirectoryIterator == std::filesystem::directory_iterator{});\r\n    return result;\r\n}\r\n\r\nvoid CheckIntermediates(const std::filesystem::path& baseDirectory, const std::vector<std::vector<ManifestAndPath>>& expectedIntermediatesData, std::chrono::seconds sleep = 1s)\r\n{\r\n    std::filesystem::path intermediatesDirectory = baseDirectory / \"packages\";\r\n\r\n    size_t intermediatePackageCount = std::count_if(std::filesystem::directory_iterator{ intermediatesDirectory }, std::filesystem::directory_iterator{}, [](const auto&){ return true; });\r\n    REQUIRE(intermediatePackageCount == expectedIntermediatesData.size());\r\n\r\n    for (const auto& versions : expectedIntermediatesData)\r\n    {\r\n        REQUIRE(!versions.empty());\r\n        INFO(versions[0].Manifest.Id);\r\n        std::filesystem::path packageDirectory = intermediatesDirectory / ConvertToUTF16(versions[0].Manifest.Id);\r\n\r\n        REQUIRE(std::filesystem::exists(packageDirectory));\r\n        std::filesystem::path hashDirectory = GetOnlyChild(packageDirectory);\r\n\r\n        std::filesystem::path versionDataFile = GetOnlyChild(hashDirectory);\r\n        std::ifstream versionDataStream{ versionDataFile, std::ios_base::in | std::ios_base::binary };\r\n        auto versionDataBytes = ReadEntireStreamAsByteArray(versionDataStream);\r\n\r\n        PackageVersionDataManifest versionDataManifest;\r\n        versionDataManifest.Deserialize(PackageVersionDataManifest::CreateDecompressor().Decompress(versionDataBytes));\r\n\r\n        const auto& versionDataVersions = versionDataManifest.Versions();\r\n        REQUIRE(versionDataVersions.size() == versions.size());\r\n\r\n        for (const auto& manifestAndPath : versions)\r\n        {\r\n            const auto& versionDataItr = std::find_if(versionDataVersions.begin(), versionDataVersions.end(), [&](const auto& v) { return v.Version == manifestAndPath.Manifest.Version; });\r\n            REQUIRE(versionDataItr != versionDataVersions.end());\r\n            const auto& versionData = *versionDataItr;\r\n\r\n            REQUIRE(manifestAndPath.Path == versionData.ManifestRelativePath);\r\n            REQUIRE(SHA256::ConvertToString(manifestAndPath.Manifest.StreamSha256) == versionData.ManifestHash);\r\n\r\n            auto versionRange = manifestAndPath.Manifest.GetArpVersionRange();\r\n            if (!versionRange.IsEmpty())\r\n            {\r\n                REQUIRE(versionData.ArpMinVersion);\r\n                REQUIRE(versionRange.GetMinVersion() == versionData.ArpMinVersion.value());\r\n                REQUIRE(versionData.ArpMaxVersion);\r\n                REQUIRE(versionRange.GetMaxVersion() == versionData.ArpMaxVersion.value());\r\n            }\r\n        }\r\n    }\r\n\r\n    // This is needed to force the timestamp to roll over to a new value for the next call to this function.\r\n    // An alternate solution would be to hook the timestamp function and control the values it returns\r\n    // so that we can advance/halt time arbitrarily.\r\n    std::this_thread::sleep_for(sleep);\r\n}\r\n\r\nvoid PrepareAndCheckIntermediates(const std::filesystem::path& baseFile, const std::filesystem::path& preparedFile, const std::vector<std::vector<ManifestAndPath>>& expectedIntermediatesData, std::chrono::seconds sleep = 1s)\r\n{\r\n    TempDirectory intermediatesDirectory{ \"v2_0_intermediates\" };\r\n    INFO(\"Intermediates directory: \" << intermediatesDirectory.GetPath());\r\n\r\n    std::filesystem::copy_file(baseFile, preparedFile, std::filesystem::copy_options::overwrite_existing);\r\n\r\n    SQLiteIndex index = SQLiteIndex::Open(preparedFile.u8string(), SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n    index.SetProperty(SQLiteIndex::Property::IntermediateFileOutputPath, intermediatesDirectory);\r\n    index.PrepareForPackaging();\r\n\r\n    CheckIntermediates(intermediatesDirectory, expectedIntermediatesData, sleep);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_V2_0_UsageFlow_Simple\", \"[sqliteindex][V2_0]\")\r\n{\r\n    TempFile baseFile{ \"v2_0_index_tempdb\"s, \".db\"s };\r\n    TempFile preparedFile{ \"v2_0_index_prepared_tempdb\"s, \".db\"s };\r\n    INFO(\"Using files named: [\" << baseFile.GetPath() << \"] and [\" << preparedFile.GetPath() << \"]\");\r\n\r\n    // Create empty index\r\n    std::ignore = SQLiteIndex::CreateNew(baseFile, SQLiteVersion{ 2, 0 });\r\n\r\n    std::string publisher = \"Publisher\";\r\n    ManifestAndPath manifest1;\r\n    CreateFakeManifestAndPath(manifest1, publisher, \"1.0\");\r\n\r\n    {\r\n        // Open existing file to add a manifest\r\n        SQLiteIndex index = SQLiteIndex::Open(baseFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n        index.SetProperty(SQLiteIndex::Property::PackageUpdateTrackingBaseTime, \"\");\r\n        index.AddManifest(manifest1.Manifest, manifest1.Path);\r\n    }\r\n\r\n    PrepareAndCheckIntermediates(baseFile, preparedFile, { { manifest1 } }, 0s);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_V2_0_UsageFlow_Complex\", \"[sqliteindex][V2_0]\")\r\n{\r\n    TempFile baseFile{ \"v2_0_index_tempdb\"s, \".db\"s };\r\n    TempFile preparedFile{ \"v2_0_index_prepared_tempdb\"s, \".db\"s };\r\n    INFO(\"Using files named: [\" << baseFile.GetPath() << \"] and [\" << preparedFile.GetPath() << \"]\");\r\n\r\n    // Create empty index\r\n    std::ignore = SQLiteIndex::CreateNew(baseFile, SQLiteVersion{ 2, 0 });\r\n\r\n    // Open existing file to add a new package\r\n    std::string Publisher1 = \"Publisher1\";\r\n    ManifestAndPath manifest1;\r\n    CreateFakeManifestAndPath(manifest1, Publisher1, \"1.0\");\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(baseFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n        index.SetProperty(SQLiteIndex::Property::PackageUpdateTrackingBaseTime, \"\");\r\n        index.AddManifest(manifest1.Manifest, manifest1.Path);\r\n    }\r\n\r\n    PrepareAndCheckIntermediates(baseFile, preparedFile, { { manifest1 } });\r\n\r\n    // Open existing file to add another new package\r\n    ManifestAndPath manifest2;\r\n    CreateFakeManifestAndPath(manifest2, \"Publisher2\", \"1.0\");\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(baseFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n        index.SetProperty(SQLiteIndex::Property::PackageUpdateTrackingBaseTime, \"\");\r\n        index.AddManifest(manifest2.Manifest, manifest2.Path);\r\n    }\r\n\r\n    PrepareAndCheckIntermediates(baseFile, preparedFile, { { manifest2 } });\r\n\r\n    // Open existing file to add a new version of existing package\r\n    ManifestAndPath manifest3;\r\n    CreateFakeManifestAndPath(manifest3, Publisher1, \"2.0\");\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(baseFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n        index.SetProperty(SQLiteIndex::Property::PackageUpdateTrackingBaseTime, \"\");\r\n        index.AddManifest(manifest3.Manifest, manifest3.Path);\r\n    }\r\n\r\n    PrepareAndCheckIntermediates(baseFile, preparedFile, { { manifest1, manifest3 } });\r\n\r\n    // Open existing file to add a new version of existing package and update an existing version\r\n    manifest2.Manifest.StreamSha256 = SHA256::ComputeHash(manifest2.Manifest.Id);\r\n\r\n    ManifestAndPath manifest4;\r\n    CreateFakeManifestAndPath(manifest4, Publisher1, \"3.0\");\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(baseFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n        index.SetProperty(SQLiteIndex::Property::PackageUpdateTrackingBaseTime, \"\");\r\n        index.UpdateManifest(manifest2.Manifest, manifest2.Path);\r\n        index.AddManifest(manifest4.Manifest, manifest4.Path);\r\n    }\r\n\r\n    PrepareAndCheckIntermediates(baseFile, preparedFile, { { manifest2 }, { manifest1, manifest3, manifest4 } }, 0s);\r\n}\r\n\r\nvoid MigratePrepareAndCheckIntermediates(const std::filesystem::path& baseFile, const std::filesystem::path& preparedFile, const std::vector<std::vector<ManifestAndPath>>& expectedIntermediatesData)\r\n{\r\n    TempDirectory intermediatesDirectory{ \"v2_0_intermediates\" };\r\n    INFO(\"Intermediates directory: \" << intermediatesDirectory.GetPath());\r\n\r\n    std::filesystem::copy_file(baseFile, preparedFile, std::filesystem::copy_options::overwrite_existing);\r\n\r\n    SQLiteIndex index = SQLiteIndex::Open(preparedFile.u8string(), SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n    index.MigrateTo({ 2, 0 });\r\n    index.SetProperty(SQLiteIndex::Property::IntermediateFileOutputPath, intermediatesDirectory);\r\n    index.PrepareForPackaging();\r\n\r\n    CheckIntermediates(intermediatesDirectory, expectedIntermediatesData, 0s);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_V2_0_UsageFlow_ComplexMigration\", \"[sqliteindex][V2_0]\")\r\n{\r\n    TempFile baseFile{ \"v1_7_index_tempdb\"s, \".db\"s };\r\n    TempFile preparedFile{ \"v2_0_index_prepared_tempdb\"s, \".db\"s };\r\n    INFO(\"Using files named: [\" << baseFile.GetPath() << \"] and [\" << preparedFile.GetPath() << \"]\");\r\n\r\n    // Create empty index\r\n    std::ignore = SQLiteIndex::CreateNew(baseFile, SQLiteVersion{ 1, 7 });\r\n\r\n    // Open existing file to add a new package\r\n    std::string Publisher1 = \"Publisher1\";\r\n    ManifestAndPath manifest1;\r\n    CreateFakeManifestAndPath(manifest1, Publisher1, \"1.0\");\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(baseFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n        index.AddManifest(manifest1.Manifest, manifest1.Path);\r\n    }\r\n\r\n    MigratePrepareAndCheckIntermediates(baseFile, preparedFile, { { manifest1 } });\r\n\r\n    // Open existing file to add another new package\r\n    ManifestAndPath manifest2;\r\n    CreateFakeManifestAndPath(manifest2, \"Publisher2\", \"1.0\");\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(baseFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n        index.AddManifest(manifest2.Manifest, manifest2.Path);\r\n    }\r\n\r\n    MigratePrepareAndCheckIntermediates(baseFile, preparedFile, { {  manifest2 }, { manifest1 } });\r\n\r\n    // Open existing file to add a new version of existing package\r\n    ManifestAndPath manifest3;\r\n    CreateFakeManifestAndPath(manifest3, Publisher1, \"2.0\");\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(baseFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n        index.AddManifest(manifest3.Manifest, manifest3.Path);\r\n    }\r\n\r\n    MigratePrepareAndCheckIntermediates(baseFile, preparedFile, { {  manifest2 }, { manifest1, manifest3 } });\r\n\r\n    // Open existing file to add a new version of existing package and update an existing version\r\n    manifest2.Manifest.StreamSha256 = SHA256::ComputeHash(manifest2.Manifest.Id);\r\n\r\n    ManifestAndPath manifest4;\r\n    CreateFakeManifestAndPath(manifest4, Publisher1, \"3.0\");\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(baseFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n        index.UpdateManifest(manifest2.Manifest, manifest2.Path);\r\n        index.AddManifest(manifest4.Manifest, manifest4.Path);\r\n    }\r\n\r\n    MigratePrepareAndCheckIntermediates(baseFile, preparedFile, { { manifest2 }, { manifest1, manifest3, manifest4 } });\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_DependencyWithCaseMismatch\", \"[sqliteindex][V1_4]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest dependencyManifest1, dependencyManifest2, manifest;\r\n    SQLiteIndex index = SimpleTestSetup(tempFile, dependencyManifest1, SQLiteVersion::Latest());\r\n\r\n    // Must contain some upper case\r\n    auto& publisher2 = \"Test2\";\r\n    CreateFakeManifest(dependencyManifest2, publisher2);\r\n    index.AddManifest(dependencyManifest2, GetPathFromManifest(dependencyManifest2));\r\n\r\n    auto& publisher3 = \"Test3\";\r\n    CreateFakeManifest(manifest, publisher3);\r\n    manifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, dependencyManifest1.Id, \"1.0.0\"));\r\n    manifest.Installers[0].Dependencies.Add(Dependency(DependencyType::Package, ToLower(dependencyManifest2.Id), \"1.0.0\"));\r\n\r\n    index.AddManifest(manifest, GetPathFromManifest(manifest));\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_AddOrUpdateManifest\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    std::string manifestPath = \"test/id/test.id-1.0.0.yaml\";\r\n    Manifest manifest;\r\n    manifest.Installers.push_back({});\r\n    manifest.Id = \"test.id\";\r\n    manifest.DefaultLocalization.Add < Localization::PackageName>(\"Test Name\");\r\n    manifest.Moniker = \"testmoniker\";\r\n    manifest.Version = \"1.0.0\";\r\n    manifest.Channel = \"test\";\r\n    manifest.DefaultLocalization.Add<Localization::Tags>({ \"t1\", \"t2\" });\r\n    manifest.Installers[0].Commands = { \"test1\", \"test2\" };\r\n\r\n    {\r\n        auto version = GENERATE(SQLiteVersion{ 1, 0 }, SQLiteVersion::Latest());\r\n        SQLiteIndex index = SQLiteIndex::CreateNew(tempFile, version);\r\n\r\n        REQUIRE(index.AddOrUpdateManifest(manifest, manifestPath));\r\n    }\r\n\r\n    {\r\n        SQLiteIndex index = SQLiteIndex::Open(tempFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n\r\n        // Update should return false\r\n        REQUIRE(!index.AddOrUpdateManifest(manifest, manifestPath));\r\n\r\n        manifest.DefaultLocalization.Add<Localization::Description>(\"description2\");\r\n\r\n        // Update should return false\r\n        REQUIRE(!index.AddOrUpdateManifest(manifest, manifestPath));\r\n\r\n        // Update with indexed changes should still return false\r\n        manifest.DefaultLocalization.Add<Localization::PackageName>(\"Test Name2\");\r\n        manifest.Moniker = \"testmoniker2\";\r\n        manifest.DefaultLocalization.Add<Localization::Tags>({ \"t1\", \"t2\", \"t3\" });\r\n        manifest.Installers[0].Commands = {};\r\n\r\n        REQUIRE(!index.AddOrUpdateManifest(manifest, manifestPath));\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndex_VersionStringPreserved\", \"[sqliteindex]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Manifest manifest;\r\n    SQLiteIndex index = CreateTestIndex(tempFile);\r\n\r\n    string_t publisher = \"Test\";\r\n    std::string version = GENERATE(\"1.0\", \"1.10\");\r\n\r\n    CreateFakeManifest(manifest, publisher, version);\r\n    index.AddManifest(manifest, GetPathFromManifest(manifest));\r\n\r\n    TempDirectory intermediatesDirectory{ \"v2_0_intermediates\" };\r\n    INFO(\"Intermediates directory: \" << intermediatesDirectory.GetPath());\r\n\r\n    index.SetProperty(SQLiteIndex::Property::IntermediateFileOutputPath, intermediatesDirectory);\r\n    index.PrepareForPackaging();\r\n\r\n    auto results = index.Search({});\r\n    REQUIRE(results.Matches.size() == 1);\r\n\r\n    std::string extractedVersion = GetPropertyStringById(index, results.Matches[0].first, PackageVersionProperty::Version);\r\n\r\n    REQUIRE(extractedVersion == version);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/SQLiteIndexSource.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <Microsoft/SQLiteIndexSource.h>\r\n#include <winget/ManifestYamlParser.h>\r\n\r\nusing namespace std::string_literals;\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Repository::Microsoft;\r\nusing namespace AppInstaller::SQLite;\r\n\r\nusing SQLiteVersion = AppInstaller::SQLite::Version;\r\n\r\nstatic std::shared_ptr<SQLiteIndexSource> SimpleTestSetup(const std::string& filePath, SourceDetails& details, Manifest& manifest, std::string& relativePath, const std::filesystem::path& manifestFile = \"Manifest-Good.yaml\")\r\n{\r\n    SQLiteVersion latest1 = Version::LatestForMajor(1);\r\n    SQLiteVersion latest2 = Version::LatestForMajor(2);\r\n\r\n    const SQLiteVersion versionToUse = GENERATE_COPY(SQLiteVersion{ latest1 }, SQLiteVersion{ latest2 });\r\n\r\n    SQLiteIndex index = SQLiteIndex::CreateNew(filePath, versionToUse);\r\n\r\n    TestDataFile testManifest(manifestFile);\r\n    manifest = YamlParser::CreateFromPath(testManifest);\r\n\r\n    std::filesystem::path testManifestPath = testManifest.GetPath();\r\n    relativePath = testManifestPath.filename().u8string();\r\n\r\n    TempDirectory sourceFilesDirectory{ \"SQLiteIndexSource\" };\r\n    std::filesystem::path sourceFilesDirectoryPath = sourceFilesDirectory.GetPath();\r\n    std::filesystem::create_directories(sourceFilesDirectoryPath);\r\n    std::filesystem::copy_file(testManifestPath, sourceFilesDirectoryPath / relativePath);\r\n    sourceFilesDirectory.Release();\r\n\r\n    index.AddManifest(manifest, relativePath);\r\n\r\n    details.Name = \"TestName\";\r\n    details.Type = \"TestType\";\r\n    details.Arg = sourceFilesDirectoryPath.u8string();\r\n    details.Data = \"\";\r\n    details.Identifier = \"SimpleTestSetup\";\r\n\r\n    if (versionToUse.MajorVersion == 2)\r\n    {\r\n        index.SetProperty(SQLiteIndex::Property::IntermediateFileOutputPath, sourceFilesDirectoryPath.u8string());\r\n    }\r\n\r\n    index.PrepareForPackaging();\r\n\r\n    return std::make_shared<SQLiteIndexSource>(details, std::move(index));\r\n}\r\n\r\nstatic bool SupportsChannel(const std::shared_ptr<SQLiteIndexSource>& source)\r\n{\r\n    return source->GetIndex().GetVersion().MajorVersion == 1;\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndexSource_Search_IdExactMatch\", \"[sqliteindexsource]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SourceDetails details;\r\n    Manifest manifest;\r\n    std::string relativePath;\r\n    std::shared_ptr<SQLiteIndexSource> source = SimpleTestSetup(tempFile, details, manifest, relativePath);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Exact, manifest.Id);\r\n\r\n    auto results = source->Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n    REQUIRE(results.Matches[0].Package);\r\n    REQUIRE(results.Matches[0].MatchCriteria.Field == PackageMatchField::Id);\r\n    REQUIRE(results.Matches[0].MatchCriteria.Type == MatchType::Exact);\r\n    REQUIRE(results.Matches[0].MatchCriteria.Value == manifest.Id);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndexSource_Search_NoMatch\", \"[sqliteindexsource]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SourceDetails details;\r\n    Manifest manifest;\r\n    std::string relativePath;\r\n    std::shared_ptr<SQLiteIndexSource> source = SimpleTestSetup(tempFile, details, manifest, relativePath);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Exact, \"THIS DOES NOT MATCH ANYTHING!\");\r\n\r\n    auto results = source->Search(request);\r\n    REQUIRE(results.Matches.size() == 0);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndexSource_Id\", \"[sqliteindexsource]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SourceDetails details;\r\n    Manifest manifest;\r\n    std::string relativePath;\r\n    std::shared_ptr<SQLiteIndexSource> source = SimpleTestSetup(tempFile, details, manifest, relativePath);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Exact, manifest.Id);\r\n\r\n    auto results = source->Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n    REQUIRE(results.Matches[0].Package);\r\n    auto latestVersion = results.Matches[0].Package->GetAvailable()[0]->GetLatestVersion();\r\n\r\n    REQUIRE(latestVersion->GetProperty(PackageVersionProperty::Id).get() == manifest.Id);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndexSource_Name\", \"[sqliteindexsource]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SourceDetails details;\r\n    Manifest manifest;\r\n    std::string relativePath;\r\n    std::shared_ptr<SQLiteIndexSource> source = SimpleTestSetup(tempFile, details, manifest, relativePath);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Exact, manifest.Id);\r\n\r\n    auto results = source->Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n    REQUIRE(results.Matches[0].Package);\r\n    auto latestVersion = results.Matches[0].Package->GetAvailable()[0]->GetLatestVersion();\r\n\r\n    REQUIRE(latestVersion->GetProperty(PackageVersionProperty::Name).get() == manifest.DefaultLocalization.Get<Localization::PackageName>());\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndexSource_Versions\", \"[sqliteindexsource]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SourceDetails details;\r\n    Manifest manifest;\r\n    std::string relativePath;\r\n    std::shared_ptr<SQLiteIndexSource> source = SimpleTestSetup(tempFile, details, manifest, relativePath);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Exact, manifest.Id);\r\n\r\n    auto results = source->Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n    REQUIRE(results.Matches[0].Package);\r\n    REQUIRE(results.Matches[0].Package->GetAvailable().size() == 1);\r\n\r\n    auto result = results.Matches[0].Package->GetAvailable()[0]->GetVersionKeys();\r\n    REQUIRE(result.size() == 1);\r\n    REQUIRE(result[0].Version == manifest.Version);\r\n    if (SupportsChannel(source))\r\n    {\r\n        REQUIRE(result[0].Channel == manifest.Channel);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndexSource_GetManifest\", \"[sqliteindexsource]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SourceDetails details;\r\n    Manifest manifest;\r\n    std::string relativePath;\r\n    std::shared_ptr<SQLiteIndexSource> source = SimpleTestSetup(tempFile, details, manifest, relativePath);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Exact, manifest.Id);\r\n\r\n    auto results = source->Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n    REQUIRE(results.Matches[0].Package);\r\n    REQUIRE(results.Matches[0].Package->GetAvailable().size() == 1);\r\n    auto package = results.Matches[0].Package->GetAvailable()[0];\r\n\r\n    auto specificResultVersion = package->GetVersion(PackageVersionKey(\"\", manifest.Version, SupportsChannel(source) ? manifest.Channel : \"\"));\r\n    REQUIRE(specificResultVersion);\r\n    auto specificResult = specificResultVersion->GetManifest();\r\n    REQUIRE(specificResult.Id == manifest.Id);\r\n    REQUIRE(specificResult.DefaultLocalization.Get<Localization::PackageName>() == manifest.DefaultLocalization.Get<Localization::PackageName>());\r\n    REQUIRE(specificResult.Version == manifest.Version);\r\n    if (SupportsChannel(source))\r\n    {\r\n        REQUIRE(specificResult.Channel == manifest.Channel);\r\n    }\r\n\r\n    if (SupportsChannel(source))\r\n    {\r\n        auto latestResultVersion = package->GetVersion(PackageVersionKey(\"\", \"\", manifest.Channel));\r\n        REQUIRE(latestResultVersion);\r\n        auto latestResult = latestResultVersion->GetManifest();\r\n        REQUIRE(latestResult.Id == manifest.Id);\r\n        REQUIRE(latestResult.DefaultLocalization.Get<Localization::PackageName>() == manifest.DefaultLocalization.Get<Localization::PackageName>());\r\n        REQUIRE(latestResult.Version == manifest.Version);\r\n        REQUIRE(latestResult.Channel == manifest.Channel);\r\n    }\r\n\r\n    auto noResultVersion = package->GetVersion(PackageVersionKey(\"\", \"blargle\", \"flargle\"));\r\n    REQUIRE(!noResultVersion);\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndexSource_IsSame\", \"[sqliteindexsource]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SourceDetails details;\r\n    Manifest manifest;\r\n    std::string relativePath;\r\n    std::shared_ptr<SQLiteIndexSource> source = SimpleTestSetup(tempFile, details, manifest, relativePath);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Exact, manifest.Id);\r\n\r\n    auto result1 = source->Search(request);\r\n    REQUIRE(result1.Matches.size() == 1);\r\n    REQUIRE(result1.Matches[0].Package->GetAvailable().size() == 1);\r\n\r\n    auto result2 = source->Search(request);\r\n    REQUIRE(result2.Matches.size() == 1);\r\n    REQUIRE(result2.Matches[0].Package->GetAvailable().size() == 1);\r\n\r\n    REQUIRE(result1.Matches[0].Package->GetAvailable()[0]->IsSame(result2.Matches[0].Package->GetAvailable()[0].get()));\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndexSource_Package_ProductCodes\", \"[sqliteindexsource]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SourceDetails details;\r\n    Manifest manifest;\r\n    std::string relativePath;\r\n    std::shared_ptr<SQLiteIndexSource> source = SimpleTestSetup(tempFile, details, manifest, relativePath);\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Exact, manifest.Id);\r\n\r\n    auto results = source->Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n    REQUIRE(results.Matches[0].Package);\r\n\r\n    auto package = results.Matches[0].Package->GetAvailable()[0];\r\n\r\n    auto manifestPCs = manifest.GetProductCodes();\r\n    auto propertyPCs = package->GetMultiProperty(PackageMultiProperty::ProductCode);\r\n    REQUIRE(manifestPCs.size() == 1);\r\n    REQUIRE(propertyPCs.size() == 1);\r\n    REQUIRE(manifestPCs[0] == propertyPCs[0].get());\r\n}\r\n\r\nTEST_CASE(\"SQLiteIndexSource_VersionSelection\", \"[sqliteindexsource]\")\r\n{\r\n    TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    SourceDetails details;\r\n    Manifest manifest;\r\n    std::string relativePath;\r\n    std::shared_ptr<SQLiteIndexSource> source = SimpleTestSetup(tempFile, details, manifest, relativePath, \"InstallFlowTest_Exe.yaml\");\r\n\r\n    SearchRequest request;\r\n    request.Query = RequestMatch(MatchType::Exact, manifest.Id);\r\n\r\n    auto results = source->Search(request);\r\n    REQUIRE(results.Matches.size() == 1);\r\n    REQUIRE(results.Matches[0].Package);\r\n\r\n    auto package = results.Matches[0].Package->GetAvailable()[0];\r\n\r\n    PackageVersionKey key{ {}, \"1\", {} };\r\n    auto version = package->GetVersion(key);\r\n    REQUIRE(version);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/SQLiteWrapper.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <AppInstallerErrors.h>\r\n#include <winget/SQLiteWrapper.h>\r\n#include <winget/SQLiteStatementBuilder.h>\r\n\r\nusing namespace AppInstaller::SQLite;\r\nusing namespace std::string_literals;\r\n\r\nstatic const char* s_firstColumn = \"first\";\r\nstatic const char* s_secondColumn = \"second\";\r\nstatic const char* s_tableName = \"simpletest\";\r\nstatic const char* s_savepoint = \"simplesave\";\r\n\r\nstatic const char* s_CreateSimpleTestTableSQL = R\"(\r\nCREATE TABLE [main].[simpletest](\r\n  [first] INT, \r\n  [second] TEXT);\r\n)\";\r\n\r\nstatic const char* s_insertToSimpleTestTableSQL = R\"(\r\ninsert into simpletest (first, second) values (?, ?)\r\n)\";\r\n\r\nstatic const char* s_selectFromSimpleTestTableSQL = R\"(\r\nselect first, second from simpletest\r\n)\";\r\n\r\nvoid CreateSimpleTestTable(Connection& connection)\r\n{\r\n    Builder::StatementBuilder builder;\r\n    builder.CreateTable(s_tableName).Columns({\r\n        Builder::ColumnBuilder(s_firstColumn, Builder::Type::Int),\r\n        Builder::ColumnBuilder(s_secondColumn, Builder::Type::Text),\r\n        });\r\n\r\n    Statement createTable = builder.Prepare(connection);\r\n    REQUIRE_FALSE(createTable.Step());\r\n    REQUIRE(createTable.GetState() == Statement::State::Completed);\r\n}\r\n\r\nvoid InsertIntoSimpleTestTable(Connection& connection, int firstVal, const std::string& secondVal)\r\n{\r\n    Builder::StatementBuilder builder;\r\n    builder.InsertInto(s_tableName).Columns({ s_firstColumn, s_secondColumn }).Values(firstVal, secondVal);\r\n    Statement insert = builder.Prepare(connection);\r\n\r\n    REQUIRE_FALSE(insert.Step());\r\n    REQUIRE(insert.GetState() == Statement::State::Completed);\r\n}\r\n\r\nvoid UpdateSimpleTestTable(Connection& connection, int firstVal, const std::string& secondVal)\r\n{\r\n    Builder::StatementBuilder update;\r\n    update.Update(s_tableName).Set().Column(s_firstColumn).Equals(firstVal).Column(s_secondColumn).Equals(secondVal);\r\n    update.Execute(connection);\r\n}\r\n\r\nvoid InsertIntoSimpleTestTableWithNull(Connection& connection, int firstVal)\r\n{\r\n    Builder::StatementBuilder builder;\r\n    builder.InsertInto(s_tableName).Columns({ s_firstColumn, s_secondColumn }).Values(firstVal, nullptr);\r\n    Statement insert = builder.Prepare(connection);\r\n\r\n    REQUIRE_FALSE(insert.Step());\r\n    REQUIRE(insert.GetState() == Statement::State::Completed);\r\n}\r\n\r\nvoid SelectFromSimpleTestTableOnlyOneRow(Connection& connection, int firstVal, const std::string& secondVal)\r\n{\r\n    Builder::StatementBuilder builder;\r\n    builder.Select({ s_firstColumn, s_secondColumn }).From(s_tableName);\r\n    Statement select = builder.Prepare(connection);\r\n\r\n    REQUIRE(select.Step());\r\n    REQUIRE(select.GetState() == Statement::State::HasRow);\r\n\r\n    int firstRead = select.GetColumn<int>(0);\r\n    std::string secondRead = select.GetColumn<std::string>(1);\r\n\r\n    REQUIRE(firstVal == firstRead);\r\n    REQUIRE(secondVal == secondRead);\r\n\r\n    auto tuple = select.GetRow<int, std::string>();\r\n\r\n    REQUIRE(firstVal == std::get<0>(tuple));\r\n    REQUIRE(secondVal == std::get<1>(tuple));\r\n\r\n    REQUIRE_FALSE(select.Step());\r\n    REQUIRE(select.GetState() == Statement::State::Completed);\r\n\r\n    select.Reset();\r\n    REQUIRE(select.GetState() == Statement::State::Prepared);\r\n\r\n    REQUIRE(select.Step());\r\n    REQUIRE(select.GetState() == Statement::State::HasRow);\r\n}\r\n\r\nTEST_CASE(\"SQLiteWrapperMemoryCreate\", \"[sqlitewrapper]\")\r\n{\r\n    Connection connection = Connection::Create(SQLITE_MEMORY_DB_CONNECTION_TARGET, Connection::OpenDisposition::Create);\r\n\r\n    CreateSimpleTestTable(connection);\r\n\r\n    int firstVal = 1;\r\n    std::string secondVal = \"test\";\r\n\r\n    InsertIntoSimpleTestTable(connection, firstVal, secondVal);\r\n\r\n    SelectFromSimpleTestTableOnlyOneRow(connection, firstVal, secondVal);\r\n}\r\n\r\nTEST_CASE(\"SQLiteWrapperFileCreateAndReopen\", \"[sqlitewrapper]\")\r\n{\r\n    TestCommon::TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    int firstVal = 1;\r\n    std::string secondVal = \"test\";\r\n\r\n    // Create the DB and some data\r\n    {\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::Create);\r\n\r\n        CreateSimpleTestTable(connection);\r\n\r\n        InsertIntoSimpleTestTable(connection, firstVal, secondVal);\r\n    }\r\n\r\n    // Reopen the DB and read data\r\n    {\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n\r\n        SelectFromSimpleTestTableOnlyOneRow(connection, firstVal, secondVal);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteWrapperSavepointRollback\", \"[sqlitewrapper]\")\r\n{\r\n    Connection connection = Connection::Create(SQLITE_MEMORY_DB_CONNECTION_TARGET, Connection::OpenDisposition::Create);\r\n\r\n    int firstVal = 1;\r\n    std::string secondVal = \"test\";\r\n\r\n    CreateSimpleTestTable(connection);\r\n\r\n    Savepoint savepoint = Savepoint::Create(connection, \"test_savepoint\");\r\n\r\n    InsertIntoSimpleTestTable(connection, firstVal, secondVal);\r\n\r\n    savepoint.Rollback();\r\n\r\n    Statement select = Statement::Create(connection, s_selectFromSimpleTestTableSQL);\r\n    REQUIRE(!select.Step());\r\n    REQUIRE(select.GetState() == Statement::State::Completed);\r\n}\r\n\r\nTEST_CASE(\"SQLiteWrapperSavepointRollbackOnDestruct\", \"[sqlitewrapper]\")\r\n{\r\n    Connection connection = Connection::Create(SQLITE_MEMORY_DB_CONNECTION_TARGET, Connection::OpenDisposition::Create);\r\n\r\n    int firstVal = 1;\r\n    std::string secondVal = \"test\";\r\n\r\n    CreateSimpleTestTable(connection);\r\n\r\n    {\r\n        Savepoint savepoint = Savepoint::Create(connection, \"test_savepoint\");\r\n\r\n        InsertIntoSimpleTestTable(connection, firstVal, secondVal);\r\n    }\r\n\r\n    Statement select = Statement::Create(connection, s_selectFromSimpleTestTableSQL);\r\n    REQUIRE(!select.Step());\r\n    REQUIRE(select.GetState() == Statement::State::Completed);\r\n}\r\n\r\nTEST_CASE(\"SQLiteWrapperSavepointCommit\", \"[sqlitewrapper]\")\r\n{\r\n    Connection connection = Connection::Create(SQLITE_MEMORY_DB_CONNECTION_TARGET, Connection::OpenDisposition::Create);\r\n\r\n    int firstVal = 1;\r\n    std::string secondVal = \"test\";\r\n\r\n    CreateSimpleTestTable(connection);\r\n\r\n    {\r\n        Savepoint savepoint = Savepoint::Create(connection, \"test_savepoint\");\r\n\r\n        InsertIntoSimpleTestTable(connection, firstVal, secondVal);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    SelectFromSimpleTestTableOnlyOneRow(connection, firstVal, secondVal);\r\n}\r\n\r\nTEST_CASE(\"SQLiteWrapperSavepointReuse\", \"[sqlitewrapper]\")\r\n{\r\n    TestCommon::TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    int firstVal = 1;\r\n    std::string secondVal = \"test\";\r\n\r\n    // Create the DB and some data\r\n    {\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::Create);\r\n\r\n        CreateSimpleTestTable(connection);\r\n\r\n        InsertIntoSimpleTestTable(connection, firstVal, secondVal);\r\n    }\r\n\r\n    // Reopen the DB and update with a single savepoint\r\n    {\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n\r\n        Savepoint savepoint = Savepoint::Create(connection, s_savepoint);\r\n\r\n        firstVal = 2;\r\n        secondVal = \"test2\";\r\n        UpdateSimpleTestTable(connection, firstVal, secondVal);\r\n        \r\n        savepoint.Commit();\r\n    }\r\n\r\n    {\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n        SelectFromSimpleTestTableOnlyOneRow(connection, firstVal, secondVal);\r\n    }\r\n\r\n    // Reopen the DB and update with a multiple savepoint\r\n    {\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n\r\n        {\r\n            Savepoint savepoint = Savepoint::Create(connection, s_savepoint);\r\n\r\n            firstVal = 3;\r\n            secondVal = \"test3\";\r\n            UpdateSimpleTestTable(connection, firstVal, secondVal);\r\n        }\r\n\r\n        {\r\n            Savepoint savepoint = Savepoint::Create(connection, s_savepoint);\r\n\r\n            firstVal = 4;\r\n            secondVal = \"test4\";\r\n            UpdateSimpleTestTable(connection, firstVal, secondVal);\r\n\r\n            savepoint.Commit();\r\n        }\r\n    }\r\n\r\n    {\r\n        Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n        SelectFromSimpleTestTableOnlyOneRow(connection, firstVal, secondVal);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteWrapper_EscapeStringForLike\", \"[sqlitewrapper]\")\r\n{\r\n    std::string escape(EscapeCharForLike);\r\n\r\n    std::string input = \"test\";\r\n    std::string output = EscapeStringForLike(input);\r\n    REQUIRE(input == output);\r\n\r\n    input = EscapeCharForLike;\r\n    output = EscapeStringForLike(input);\r\n    REQUIRE((input + input) == output);\r\n\r\n    input = \"%\";\r\n    output = EscapeStringForLike(input);\r\n    REQUIRE((escape + input) == output);\r\n\r\n    input = \"_\";\r\n    output = EscapeStringForLike(input);\r\n    REQUIRE((escape + input) == output);\r\n\r\n    input = \"%_A_%\";\r\n    std::string expected = escape + \"%\" + escape + \"_A\" + escape + \"_\" + escape + \"%\";\r\n    output = EscapeStringForLike(input);\r\n    REQUIRE(expected == output);\r\n}\r\n\r\nTEST_CASE(\"SQLiteWrapper_BindWithEmbeddedNull\", \"[sqlitewrapper]\")\r\n{\r\n    Connection connection = Connection::Create(SQLITE_MEMORY_DB_CONNECTION_TARGET, Connection::OpenDisposition::Create);\r\n\r\n    CreateSimpleTestTable(connection);\r\n\r\n    int firstVal = 1;\r\n    std::string secondVal = \"test\";\r\n    secondVal[1] = '\\0';\r\n\r\n    REQUIRE_THROWS_HR(InsertIntoSimpleTestTable(connection, firstVal, secondVal), APPINSTALLER_CLI_ERROR_BIND_WITH_EMBEDDED_NULL);\r\n}\r\n\r\nTEST_CASE(\"SQLiteWrapper_PrepareFailure\", \"[sqlitewrapper]\")\r\n{\r\n    Connection connection = Connection::Create(SQLITE_MEMORY_DB_CONNECTION_TARGET, Connection::OpenDisposition::Create);\r\n\r\n    CreateSimpleTestTable(connection);\r\n\r\n    Builder::StatementBuilder builder;\r\n    builder.Select({ s_firstColumn, s_secondColumn }).From(std::string{ s_tableName } + \"2\").Where(s_firstColumn).Equals(2);\r\n\r\n    REQUIRE_THROWS_HR(builder.Prepare(connection), MAKE_HRESULT(SEVERITY_ERROR, FACILITY_SQLITE, SQLITE_ERROR));\r\n}\r\n\r\nTEST_CASE(\"SQLiteWrapper_BusyTimeout_None\", \"[sqlitewrapper]\")\r\n{\r\n    TestCommon::TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    wil::unique_event busy, done;\r\n    busy.create();\r\n    done.create();\r\n\r\n    std::thread busyThread([&]()\r\n        {\r\n            Connection threadConnection = Connection::Create(tempFile, Connection::OpenDisposition::Create);\r\n            Statement threadStatement = Statement::Create(threadConnection, \"BEGIN EXCLUSIVE TRANSACTION\");\r\n            threadStatement.Execute();\r\n            busy.SetEvent();\r\n            done.wait(500);\r\n        });\r\n    busyThread.detach();\r\n\r\n    busy.wait(500);\r\n\r\n    Connection testConnection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n    testConnection.SetBusyTimeout(0ms);\r\n    Statement testStatement = Statement::Create(testConnection, \"BEGIN EXCLUSIVE TRANSACTION\");\r\n    REQUIRE_THROWS_HR(testStatement.Execute(), MAKE_HRESULT(SEVERITY_ERROR, FACILITY_SQLITE, SQLITE_BUSY));\r\n\r\n    done.SetEvent();\r\n}\r\n\r\nTEST_CASE(\"SQLiteWrapper_BusyTimeout_Some\", \"[sqlitewrapper]\")\r\n{\r\n    TestCommon::TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    wil::unique_event busy, ready, done;\r\n    busy.create();\r\n    ready.create();\r\n    done.create();\r\n\r\n    std::thread busyThread([&]()\r\n        {\r\n            Connection threadConnection = Connection::Create(tempFile, Connection::OpenDisposition::Create);\r\n            Statement threadBeginStatement = Statement::Create(threadConnection, \"BEGIN EXCLUSIVE TRANSACTION\");\r\n            Statement threadCommitStatement = Statement::Create(threadConnection, \"COMMIT\");\r\n            threadBeginStatement.Execute();\r\n            busy.SetEvent();\r\n            ready.wait(500);\r\n            done.wait(100);\r\n            threadCommitStatement.Execute();\r\n        });\r\n    busyThread.detach();\r\n\r\n    busy.wait(500);\r\n\r\n    Connection testConnection = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n    testConnection.SetBusyTimeout(500ms);\r\n    Statement testStatement = Statement::Create(testConnection, \"BEGIN EXCLUSIVE TRANSACTION\");\r\n    ready.SetEvent();\r\n    testStatement.Execute();\r\n\r\n    done.SetEvent();\r\n}\r\n\r\nTEST_CASE(\"SQLiteWrapper_CloseConnectionOnError\", \"[sqlitewrapper]\")\r\n{\r\n    Connection connection = Connection::Create(SQLITE_MEMORY_DB_CONNECTION_TARGET, Connection::OpenDisposition::Create);\r\n\r\n    Builder::StatementBuilder builder;\r\n    builder.CreateTable(s_tableName).Columns({\r\n        Builder::ColumnBuilder(s_firstColumn, Builder::Type::Int),\r\n        Builder::ColumnBuilder(s_secondColumn, Builder::Type::Text),\r\n        });\r\n\r\n    Statement createTable = builder.Prepare(connection);\r\n    REQUIRE_FALSE(createTable.Step());\r\n    REQUIRE(createTable.GetState() == Statement::State::Completed);\r\n\r\n    createTable.Reset();\r\n    REQUIRE_THROWS(createTable.Step(true));\r\n\r\n    // Do anything that needs the connection\r\n    REQUIRE_THROWS_HR(connection.GetLastInsertRowID(), APPINSTALLER_CLI_ERROR_SQLITE_CONNECTION_TERMINATED);\r\n}\r\n\r\nTEST_CASE(\"SQLBuilder_SimpleSelectBind\", \"[sqlbuilder]\")\r\n{\r\n    Connection connection = Connection::Create(SQLITE_MEMORY_DB_CONNECTION_TARGET, Connection::OpenDisposition::Create);\r\n\r\n    CreateSimpleTestTable(connection);\r\n\r\n    InsertIntoSimpleTestTable(connection, 1, \"1\");\r\n    InsertIntoSimpleTestTable(connection, 2, \"2\");\r\n    InsertIntoSimpleTestTable(connection, 3, \"3\");\r\n\r\n    Builder::StatementBuilder builder;\r\n    builder.Select({ s_firstColumn, s_secondColumn }).From(s_tableName).Where(s_firstColumn).Equals(2);\r\n\r\n    auto statement = builder.Prepare(connection);\r\n\r\n    REQUIRE(statement.Step());\r\n    REQUIRE(statement.GetColumn<int>(0) == 2);\r\n    REQUIRE(statement.GetColumn<std::string>(0) == \"2\");\r\n\r\n    REQUIRE(!statement.Step());\r\n\r\n    Builder::StatementBuilder buildCount;\r\n    buildCount.Select(Builder::RowCount).From(s_tableName);\r\n\r\n    auto rows = buildCount.Prepare(connection);\r\n\r\n    REQUIRE(rows.Step());\r\n    REQUIRE(rows.GetColumn<int>(0) == 3);\r\n\r\n    REQUIRE(!rows.Step());\r\n}\r\n\r\nTEST_CASE(\"SQLBuilder_SimpleSelectUnbound\", \"[sqlbuilder]\")\r\n{\r\n    Connection connection = Connection::Create(SQLITE_MEMORY_DB_CONNECTION_TARGET, Connection::OpenDisposition::Create);\r\n\r\n    CreateSimpleTestTable(connection);\r\n\r\n    InsertIntoSimpleTestTable(connection, 1, \"1\");\r\n    InsertIntoSimpleTestTable(connection, 2, \"2\");\r\n    InsertIntoSimpleTestTable(connection, 3, \"3\");\r\n\r\n    Builder::StatementBuilder builder;\r\n    builder.Select({ s_firstColumn, s_secondColumn }).From(s_tableName).Where(s_firstColumn).Equals(Builder::Unbound);\r\n\r\n    auto statement = builder.Prepare(connection);\r\n\r\n    statement.Bind(1, 2);\r\n\r\n    REQUIRE(statement.Step());\r\n    REQUIRE(statement.GetColumn<int>(0) == 2);\r\n    REQUIRE(statement.GetColumn<std::string>(0) == \"2\");\r\n\r\n    REQUIRE(!statement.Step());\r\n}\r\n\r\nTEST_CASE(\"SQLBuilder_SimpleSelectNull\", \"[sqlbuilder]\")\r\n{\r\n    Connection connection = Connection::Create(SQLITE_MEMORY_DB_CONNECTION_TARGET, Connection::OpenDisposition::Create);\r\n\r\n    CreateSimpleTestTable(connection);\r\n\r\n    InsertIntoSimpleTestTable(connection, 1, \"1\");\r\n    InsertIntoSimpleTestTable(connection, 2, \"2\");\r\n    InsertIntoSimpleTestTableWithNull(connection, 3);\r\n\r\n    Builder::StatementBuilder builder;\r\n    builder.Select({ s_firstColumn, s_secondColumn }).From(s_tableName).Where(s_secondColumn).IsNull();\r\n\r\n    auto statement = builder.Prepare(connection);\r\n\r\n    REQUIRE(statement.Step());\r\n    REQUIRE(statement.GetColumn<int>(0) == 3);\r\n    REQUIRE(statement.GetColumnIsNull(1));\r\n\r\n    REQUIRE(!statement.Step());\r\n}\r\n\r\nTEST_CASE(\"SQLBuilder_SimpleSelectOptional\", \"[sqlbuilder]\")\r\n{\r\n    Connection connection = Connection::Create(SQLITE_MEMORY_DB_CONNECTION_TARGET, Connection::OpenDisposition::Create);\r\n\r\n    CreateSimpleTestTable(connection);\r\n\r\n    InsertIntoSimpleTestTable(connection, 1, \"1\");\r\n    InsertIntoSimpleTestTable(connection, 2, \"2\");\r\n    InsertIntoSimpleTestTableWithNull(connection, 3);\r\n\r\n    std::optional<std::string> secondValue;\r\n\r\n    {\r\n        Builder::StatementBuilder builder;\r\n        builder.Select({ s_firstColumn, s_secondColumn }).From(s_tableName).Where(s_secondColumn).Equals(secondValue);\r\n\r\n        auto statement = builder.Prepare(connection);\r\n\r\n        REQUIRE(statement.Step());\r\n        REQUIRE(statement.GetColumn<int>(0) == 3);\r\n        REQUIRE(statement.GetColumnIsNull(1));\r\n\r\n        REQUIRE(!statement.Step());\r\n    }\r\n\r\n    {\r\n        secondValue = \"2\";\r\n        Builder::StatementBuilder builder;\r\n        builder.Select({ s_firstColumn, s_secondColumn }).From(s_tableName).Where(s_secondColumn).Equals(secondValue);\r\n\r\n        auto statement = builder.Prepare(connection);\r\n\r\n        REQUIRE(statement.Step());\r\n        REQUIRE(statement.GetColumn<int>(0) == 2);\r\n        REQUIRE(statement.GetColumn<std::string>(1) == \"2\");\r\n\r\n        REQUIRE(!statement.Step());\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLBuilder_Update\", \"[sqlbuilder]\")\r\n{\r\n    Connection connection = Connection::Create(SQLITE_MEMORY_DB_CONNECTION_TARGET, Connection::OpenDisposition::Create);\r\n\r\n    CreateSimpleTestTable(connection);\r\n\r\n    int firstVal = 1;\r\n    std::string secondVal = \"test\";\r\n\r\n    InsertIntoSimpleTestTable(connection, firstVal, secondVal);\r\n\r\n    SelectFromSimpleTestTableOnlyOneRow(connection, firstVal, secondVal);\r\n\r\n    firstVal = 2;\r\n    secondVal = \"testing\";\r\n\r\n    UpdateSimpleTestTable(connection, firstVal, secondVal);\r\n\r\n    SelectFromSimpleTestTableOnlyOneRow(connection, firstVal, secondVal);\r\n}\r\n\r\nTEST_CASE(\"SQLBuilder_CaseInsensitive\", \"[sqlbuilder]\")\r\n{\r\n    Connection connection = Connection::Create(SQLITE_MEMORY_DB_CONNECTION_TARGET, Connection::OpenDisposition::Create);\r\n\r\n    Builder::StatementBuilder createTable;\r\n    createTable.CreateTable(s_tableName).Columns({\r\n        Builder::ColumnBuilder(s_firstColumn, Builder::Type::Text).CollateNoCase()\r\n        });\r\n\r\n    createTable.Execute(connection);\r\n\r\n    std::string upperCaseVal = \"TEST\";\r\n    std::string lowerCaseVal = \"test\";\r\n\r\n    {\r\n        INFO(\"Insert initial value\");\r\n        Builder::StatementBuilder builder;\r\n        builder.InsertInto(s_tableName)\r\n            .Columns({ s_firstColumn })\r\n            .Values(upperCaseVal);\r\n\r\n        builder.Execute(connection);\r\n    }\r\n\r\n    {\r\n        INFO(\"Retrieve using case-insensitive value\");\r\n        Builder::StatementBuilder builder;\r\n        builder.Select({ s_firstColumn }).From(s_tableName).Where(s_firstColumn).Equals(lowerCaseVal);\r\n\r\n        auto statement = builder.Prepare(connection);\r\n        REQUIRE(statement.Step());\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLBuilder_CreateTable\", \"[sqlbuilder]\")\r\n{\r\n    Connection connection = Connection::Create(SQLITE_MEMORY_DB_CONNECTION_TARGET, Connection::OpenDisposition::Create);\r\n\r\n    int testRun = GENERATE(0, 1, 2, 3, 4, 5, 6, 7);\r\n\r\n    bool notNull = ((testRun & 1) != 0);\r\n    bool unique = ((testRun & 2) != 0);\r\n    bool pk = ((testRun & 4) != 0);\r\n    CAPTURE(notNull, unique, pk);\r\n\r\n    Builder::StatementBuilder createTable;\r\n    createTable.CreateTable(s_tableName).Columns({\r\n        Builder::ColumnBuilder(s_firstColumn, Builder::Type::Int).NotNull(notNull).Unique(unique).PrimaryKey(pk)\r\n        });\r\n\r\n    createTable.Execute(connection);\r\n\r\n    Builder::StatementBuilder insertBuilder;\r\n    insertBuilder.InsertInto(s_tableName).Columns(s_firstColumn).Values(Builder::Unbound);\r\n\r\n    Statement insertStatement = insertBuilder.Prepare(connection);\r\n\r\n    {\r\n        INFO(\"Insert NULL\");\r\n        insertStatement.Bind(1, nullptr);\r\n\r\n        if (notNull)\r\n        {\r\n            REQUIRE_THROWS_HR(insertStatement.Execute(), MAKE_HRESULT(SEVERITY_ERROR, FACILITY_SQLITE, SQLITE_CONSTRAINT_NOTNULL));\r\n        }\r\n        else\r\n        {\r\n            insertStatement.Execute();\r\n        }\r\n    }\r\n\r\n    {\r\n        INFO(\"Insert unique values\");\r\n        insertStatement.Reset();\r\n        insertStatement.Bind(1, 1);\r\n        insertStatement.Execute();\r\n\r\n        insertStatement.Reset();\r\n        insertStatement.Bind(1, 2);\r\n        insertStatement.Execute();\r\n    }\r\n\r\n    {\r\n        INFO(\"Insert duplicate values\");\r\n        insertStatement.Reset();\r\n        insertStatement.Bind(1, 1);\r\n\r\n        if (unique || pk)\r\n        {\r\n            HRESULT expectedHR = S_OK;\r\n            if (pk)\r\n            {\r\n                expectedHR = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_SQLITE, SQLITE_CONSTRAINT_PRIMARYKEY);\r\n            }\r\n            else\r\n            {\r\n                expectedHR = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_SQLITE, SQLITE_CONSTRAINT_UNIQUE);\r\n            }\r\n            REQUIRE_THROWS_HR(insertStatement.Execute(), expectedHR);\r\n        }\r\n        else\r\n        {\r\n            insertStatement.Execute();\r\n        }\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLBuilder_InsertValueBinding\", \"[sqlbuilder]\")\r\n{\r\n    char const* const columns[] = { \"a\", \"b\", \"c\", \"d\", \"e\", \"f\" };\r\n\r\n    TestCommon::TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::Create);\r\n\r\n    {\r\n        INFO(\"Create table\");\r\n        Builder::StatementBuilder createTable;\r\n        createTable.CreateTable(s_tableName).BeginColumns();\r\n        for (const auto c : columns)\r\n        {\r\n            createTable.Column(Builder::ColumnBuilder(c, Builder::Type::Int));\r\n        }\r\n        createTable.EndColumns();\r\n        createTable.Execute(connection);\r\n    }\r\n\r\n    {\r\n        INFO(\"Insert values\");\r\n        Builder::StatementBuilder insertBuilder;\r\n        insertBuilder.InsertInto(s_tableName).BeginColumns();\r\n        for (const auto c : columns)\r\n        {\r\n            insertBuilder.Column(c);\r\n        }\r\n        insertBuilder.EndColumns().Values(0, 1, 2, 3, 4, 5);\r\n        insertBuilder.Execute(connection);\r\n    }\r\n\r\n    {\r\n        INFO(\"Insert values\");\r\n        Builder::StatementBuilder insertBuilder;\r\n        insertBuilder.InsertInto(s_tableName).BeginColumns();\r\n        for (const auto c : columns)\r\n        {\r\n            insertBuilder.Column(c);\r\n        }\r\n        insertBuilder.EndColumns().BeginValues();\r\n        insertBuilder.Value(5);\r\n        insertBuilder.Value(nullptr);\r\n        insertBuilder.Value(3);\r\n        insertBuilder.Value(std::optional<int>{});\r\n        insertBuilder.Value(std::optional<int>{ 1 });\r\n        insertBuilder.Value(Builder::Unbound);\r\n        insertBuilder.EndValues();\r\n        insertBuilder.Execute(connection);\r\n    }\r\n\r\n    {\r\n        INFO(\"Select values\");\r\n        Builder::StatementBuilder selectBuilder;\r\n        selectBuilder.Select();\r\n        for (const auto c : columns)\r\n        {\r\n            selectBuilder.Column(c);\r\n        }\r\n        selectBuilder.From(s_tableName);\r\n\r\n        Statement select = selectBuilder.Prepare(connection);\r\n        REQUIRE(select.Step());\r\n\r\n        for (int i = 0; i < ARRAYSIZE(columns); ++i)\r\n        {\r\n            REQUIRE(i == select.GetColumn<int>(i));\r\n        }\r\n\r\n        REQUIRE(select.Step());\r\n\r\n        for (int i = 0; i < ARRAYSIZE(columns); ++i)\r\n        {\r\n            if (i & 1)\r\n            {\r\n                REQUIRE(select.GetColumnIsNull(i));\r\n            }\r\n            else\r\n            {\r\n                REQUIRE((5 - i) == select.GetColumn<int>(i));\r\n            }\r\n        }\r\n\r\n        REQUIRE(!select.Step());\r\n    }\r\n}\r\n\r\nTEST_CASE(\"SQLiteWrapperTransactionRollback\", \"[sqlitewrapper]\")\r\n{\r\n    Connection connection = Connection::Create(SQLITE_MEMORY_DB_CONNECTION_TARGET, Connection::OpenDisposition::Create);\r\n\r\n    int firstVal = 1;\r\n    std::string secondVal = \"test\";\r\n\r\n    CreateSimpleTestTable(connection);\r\n\r\n    Transaction transaction = Transaction::Create(connection, \"test_transaction\", false);\r\n\r\n    InsertIntoSimpleTestTable(connection, firstVal, secondVal);\r\n\r\n    transaction.Rollback();\r\n\r\n    Statement select = Statement::Create(connection, s_selectFromSimpleTestTableSQL);\r\n    REQUIRE(!select.Step());\r\n    REQUIRE(select.GetState() == Statement::State::Completed);\r\n}\r\n\r\nTEST_CASE(\"SQLiteWrapperTransactionRollbackOnDestruct\", \"[sqlitewrapper]\")\r\n{\r\n    Connection connection = Connection::Create(SQLITE_MEMORY_DB_CONNECTION_TARGET, Connection::OpenDisposition::Create);\r\n\r\n    int firstVal = 1;\r\n    std::string secondVal = \"test\";\r\n\r\n    CreateSimpleTestTable(connection);\r\n\r\n    {\r\n        Transaction transaction = Transaction::Create(connection, \"test_transaction\", false);\r\n\r\n        InsertIntoSimpleTestTable(connection, firstVal, secondVal);\r\n    }\r\n\r\n    Statement select = Statement::Create(connection, s_selectFromSimpleTestTableSQL);\r\n    REQUIRE(!select.Step());\r\n    REQUIRE(select.GetState() == Statement::State::Completed);\r\n}\r\n\r\nTEST_CASE(\"SQLiteWrapperTransactionCommit\", \"[sqlitewrapper]\")\r\n{\r\n    Connection connection = Connection::Create(SQLITE_MEMORY_DB_CONNECTION_TARGET, Connection::OpenDisposition::Create);\r\n\r\n    int firstVal = 1;\r\n    std::string secondVal = \"test\";\r\n\r\n    CreateSimpleTestTable(connection);\r\n\r\n    {\r\n        Transaction transaction = Transaction::Create(connection, \"test_transaction\", false);\r\n\r\n        InsertIntoSimpleTestTable(connection, firstVal, secondVal);\r\n\r\n        transaction.Commit();\r\n    }\r\n\r\n    SelectFromSimpleTestTableOnlyOneRow(connection, firstVal, secondVal);\r\n}\r\n\r\nTEST_CASE(\"SQLiteWrapperTransactionImmediate\", \"[sqlitewrapper]\")\r\n{\r\n    Connection connection = Connection::Create(SQLITE_MEMORY_DB_CONNECTION_TARGET, Connection::OpenDisposition::Create);\r\n\r\n    int firstVal = 1;\r\n    std::string secondVal = \"test\";\r\n\r\n    CreateSimpleTestTable(connection);\r\n\r\n    {\r\n        Transaction transaction = Transaction::Create(connection, \"test_transaction\", true);\r\n\r\n        InsertIntoSimpleTestTable(connection, firstVal, secondVal);\r\n\r\n        transaction.Commit();\r\n    }\r\n\r\n    SelectFromSimpleTestTableOnlyOneRow(connection, firstVal, secondVal);\r\n}\r\n\r\nTEST_CASE(\"SQLiteWrapperTransactionWriteConflict\", \"[sqlitewrapper]\")\r\n{\r\n    TestCommon::TempFile tempFile{ \"repolibtest_tempdb\"s, \".db\"s };\r\n    INFO(\"Using temporary file named: \" << tempFile.GetPath());\r\n\r\n    Connection connection = Connection::Create(tempFile, Connection::OpenDisposition::Create);\r\n    connection.SetJournalMode(\"WAL\");\r\n\r\n    int firstVal = 1;\r\n    std::string secondVal = \"test\";\r\n\r\n    CreateSimpleTestTable(connection);\r\n\r\n    Connection connection2 = Connection::Create(tempFile, Connection::OpenDisposition::ReadWrite);\r\n    std::chrono::milliseconds busyWait = 250ms;\r\n    connection2.SetBusyTimeout(busyWait);\r\n\r\n    {\r\n        Transaction transaction = Transaction::Create(connection, \"test_transaction\", true);\r\n        InsertIntoSimpleTestTable(connection, firstVal, secondVal);\r\n\r\n        // Start second transaction\r\n        std::chrono::system_clock::time_point start = std::chrono::system_clock::now();\r\n        std::chrono::system_clock::time_point end = start;\r\n        try\r\n        {\r\n            Transaction transaction2 = Transaction::Create(connection2, \"test_transaction2\", true);\r\n        }\r\n        catch (...)\r\n        {\r\n            end = std::chrono::system_clock::now();\r\n        }\r\n\r\n        std::chrono::milliseconds duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);\r\n        REQUIRE(duration >= busyWait);\r\n\r\n        transaction.Commit();\r\n\r\n        Transaction transaction2 = Transaction::Create(connection2, \"test_transaction2\", true);\r\n        InsertIntoSimpleTestTable(connection2, firstVal, secondVal);\r\n    }\r\n\r\n    SelectFromSimpleTestTableOnlyOneRow(connection, firstVal, secondVal);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/SearchRequestSerializer.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestRestRequestHandler.h\"\r\n#include <AppInstallerErrors.h>\r\n#include <Rest/Schema/1_0/Json/SearchRequestSerializer.h>\r\n#include <Rest/Schema/1_1/Json/SearchRequestSerializer.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Repository::Rest::Schema;\r\n\r\nTEST_CASE(\"SearchRequestSerializer_InclusionsFilters\", \"[RestSource]\")\r\n{\r\n    SearchRequest searchRequest;\r\n    searchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::Id, MatchType::Substring, \"Foo.Bar\"));\r\n    searchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::Name, MatchType::Substring, \"Foo\"));\r\n    searchRequest.Filters.emplace_back(PackageMatchFilter(PackageMatchField::Moniker, MatchType::Exact, \"FooBar\"));\r\n    searchRequest.MaximumResults = 10;\r\n\r\n    V1_0::Json::SearchRequestSerializer serializer;\r\n    web::json::value actual = serializer.Serialize(searchRequest);\r\n\r\n    REQUIRE(!actual.is_null());\r\n    REQUIRE(!actual.has_field(L\"FetchAllManifests\"));\r\n    REQUIRE(actual.at(L\"MaximumResults\").as_integer() == static_cast<int>(searchRequest.MaximumResults));\r\n\r\n    // Inclusions\r\n    web::json::array inclusions = actual.at(L\"Inclusions\").as_array();\r\n    REQUIRE(inclusions.size() == 2);\r\n    REQUIRE(inclusions.at(0).at(L\"PackageMatchField\").as_string() == L\"PackageIdentifier\");\r\n    REQUIRE(inclusions.at(1).at(L\"PackageMatchField\").as_string() == L\"PackageName\");\r\n    web::json::value requestMatch = inclusions.at(0).at(L\"RequestMatch\");\r\n    REQUIRE(!requestMatch.is_null());\r\n    REQUIRE(requestMatch.at(L\"KeyWord\").as_string() == L\"Foo.Bar\");\r\n    REQUIRE(requestMatch.at(L\"MatchType\").as_string() == L\"Substring\");\r\n\r\n    // Filters\r\n    web::json::array filters = actual.at(L\"Filters\").as_array();\r\n    REQUIRE(filters.size() == 1);\r\n    REQUIRE(filters.at(0).at(L\"PackageMatchField\").as_string() == L\"Moniker\");\r\n    web::json::value requestMatchFilter = filters.at(0).at(L\"RequestMatch\");\r\n    REQUIRE(!requestMatchFilter.is_null());\r\n    REQUIRE(requestMatchFilter.at(L\"KeyWord\").as_string() == L\"FooBar\");\r\n    REQUIRE(requestMatchFilter.at(L\"MatchType\").as_string() == L\"Exact\");\r\n}\r\n\r\nTEST_CASE(\"SearchRequestSerializer_Query\", \"[RestSource]\")\r\n{\r\n    SearchRequest searchRequest;\r\n    searchRequest.Query = RequestMatch(MatchType::Substring, \"Foo.Bar\");\r\n\r\n    V1_0::Json::SearchRequestSerializer serializer;\r\n    web::json::value actual = serializer.Serialize(std::move(searchRequest));\r\n\r\n    REQUIRE(!actual.is_null());\r\n    web::json::value query = actual.at(L\"Query\");\r\n    REQUIRE(query.at(L\"KeyWord\").as_string() == L\"Foo.Bar\");\r\n    REQUIRE(query.at(L\"MatchType\").as_string() == L\"Substring\");\r\n}\r\n\r\nTEST_CASE(\"SearchRequestSerializer_FetchAllManifests\", \"[RestSource]\")\r\n{\r\n    V1_0::Json::SearchRequestSerializer serializer;\r\n    web::json::value actual = serializer.Serialize({});\r\n\r\n    REQUIRE(!actual.is_null());\r\n    REQUIRE(actual.at(L\"FetchAllManifests\").as_bool());\r\n}\r\n\r\nTEST_CASE(\"SearchRequestSerializer_NewFields\", \"[RestSource]\")\r\n{\r\n    SearchRequest searchRequest;\r\n    searchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::Id, MatchType::Substring, \"Foo.Bar\"));\r\n    searchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::Name, MatchType::Substring, \"Foo\"));\r\n    searchRequest.Filters.emplace_back(PackageMatchFilter(PackageMatchField::Market, MatchType::Exact, \"FooBar\"));\r\n\r\n    V1_0::Json::SearchRequestSerializer serializerV1_0;\r\n    web::json::value actual_1_0 = serializerV1_0.Serialize(searchRequest);\r\n    REQUIRE(!actual_1_0.is_null());\r\n    REQUIRE(actual_1_0.at(L\"Filters\").as_array().size() == 0);\r\n\r\n    V1_1::Json::SearchRequestSerializer serializerV1_1;\r\n    web::json::value actual_1_1 = serializerV1_1.Serialize(searchRequest);\r\n    REQUIRE(!actual_1_1.is_null());\r\n    REQUIRE(actual_1_1.at(L\"Filters\").as_array().size() == 1);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/Settings.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n\r\n#include <AppInstallerRuntime.h>\r\n#include <AppInstallerStrings.h>\r\n#include <winget/Settings.h>\r\n\r\nusing namespace AppInstaller::Runtime;\r\nusing namespace AppInstaller::Settings;\r\nusing namespace AppInstaller::Utility;\r\n\r\nTEST_CASE(\"ReadEmptySetting\", \"[settings]\")\r\n{\r\n    StreamDefinition name{ Type::Standard, \"nonexistentsetting\" };\r\n\r\n    auto result = Stream{ name }.Get();\r\n    REQUIRE(!result);\r\n}\r\n\r\nTEST_CASE(\"SetAndReadSetting\", \"[settings]\")\r\n{\r\n    StreamDefinition name{ Type::Standard, \"testsettingname\" };\r\n    std::string value = \"This is the test setting value\";\r\n\r\n    Stream stream{ name };\r\n    REQUIRE(stream.Set(value));\r\n\r\n    auto result = stream.Get();\r\n    REQUIRE(static_cast<bool>(result));\r\n\r\n    std::string settingValue = ReadEntireStream(*result);\r\n    REQUIRE(value == settingValue);\r\n}\r\n\r\nTEST_CASE(\"SetAndReadSettingInContainer\", \"[settings]\")\r\n{\r\n    StreamDefinition name{ Type::Standard, \"testcontainer/testsettingname\" };\r\n    std::string value = \"This is the test setting value from inside a container\";\r\n\r\n    Stream stream{ name };\r\n    REQUIRE(stream.Set(value));\r\n\r\n    auto result = stream.Get();\r\n    REQUIRE(static_cast<bool>(result));\r\n\r\n    std::string settingValue = ReadEntireStream(*result);\r\n    REQUIRE(value == settingValue);\r\n}\r\n\r\nTEST_CASE(\"RemoveSetting\", \"[settings]\")\r\n{\r\n    StreamDefinition name{ Type::Standard, \"testsettingname\" };\r\n    std::string value = \"This is the test setting value to be removed\";\r\n\r\n    Stream stream{ name };\r\n    REQUIRE(stream.Set(value));\r\n\r\n    {\r\n        auto result = stream.Get();\r\n        REQUIRE(static_cast<bool>(result));\r\n\r\n        std::string settingValue = ReadEntireStream(*result);\r\n        REQUIRE(value == settingValue);\r\n    }\r\n\r\n    stream.Remove();\r\n\r\n    auto result = stream.Get();\r\n    REQUIRE(!static_cast<bool>(result));\r\n}\r\n\r\nTEST_CASE(\"SetAndReadUserFileSetting\", \"[settings]\")\r\n{\r\n    StreamDefinition name{ Type::UserFile, \"userfilesetting\" };\r\n    std::string value = \"This is the test setting value for a user file\";\r\n\r\n    Stream stream{ name };\r\n    REQUIRE(stream.Set(value));\r\n\r\n    auto result = stream.Get();\r\n    REQUIRE(static_cast<bool>(result));\r\n\r\n    std::string settingValue = ReadEntireStream(*result);\r\n    REQUIRE(value == settingValue);\r\n}\r\n\r\nTEST_CASE(\"ReadEmptySecureSetting\", \"[settings]\")\r\n{\r\n    StreamDefinition name{ Type::Secure, \"secure_nonexistentsetting\" };\r\n\r\n    auto result = Stream{ name }.Get();\r\n    REQUIRE(!result);\r\n}\r\n\r\nTEST_CASE(\"SetAndReadSecureSetting\", \"[settings]\")\r\n{\r\n    StreamDefinition name{ Type::Secure, \"secure_testsettingname\" };\r\n    std::string value = \"This is the test setting value\";\r\n\r\n    Stream stream{ name };\r\n    REQUIRE(stream.Set(value));\r\n\r\n    auto result = stream.Get();\r\n    REQUIRE(static_cast<bool>(result));\r\n\r\n    std::string settingValue = ReadEntireStream(*result);\r\n    REQUIRE(value == settingValue);\r\n}\r\n\r\nTEST_CASE(\"SetAndReadSecureSettingInContainer\", \"[settings]\")\r\n{\r\n    StreamDefinition name{ Type::Secure, \"testcontainer/secure_testsettingname\" };\r\n    std::string value = \"This is the test setting value from inside a container\";\r\n\r\n    Stream stream{ name };\r\n    REQUIRE(stream.Set(value));\r\n\r\n    auto result = stream.Get();\r\n    REQUIRE(static_cast<bool>(result));\r\n\r\n    std::string settingValue = ReadEntireStream(*result);\r\n    REQUIRE(value == settingValue);\r\n}\r\n\r\nTEST_CASE(\"RemoveSecureSetting\", \"[settings]\")\r\n{\r\n    StreamDefinition name{ Type::Secure, \"secure_testsettingname\" };\r\n    std::string value = \"This is the test setting value to be removed\";\r\n\r\n    Stream stream{ name };\r\n    REQUIRE(stream.Set(value));\r\n\r\n    {\r\n        auto result = stream.Get();\r\n        REQUIRE(static_cast<bool>(result));\r\n\r\n        std::string settingValue = ReadEntireStream(*result);\r\n        REQUIRE(value == settingValue);\r\n    }\r\n\r\n    stream.Remove();\r\n\r\n    auto result = stream.Get();\r\n    REQUIRE(!static_cast<bool>(result));\r\n}\r\n\r\nTEST_CASE(\"SetAndReadSecureSetting_SecureDataRemoved\", \"[settings]\")\r\n{\r\n    StreamDefinition name{ Type::Secure, \"secure_testsettingname\" };\r\n    std::string value = \"This is the test setting value\";\r\n\r\n    Stream stream{ name };\r\n    REQUIRE(stream.Set(value));\r\n\r\n    auto result = stream.Get();\r\n    REQUIRE(static_cast<bool>(result));\r\n\r\n    std::string settingValue = ReadEntireStream(*result);\r\n    REQUIRE(value == settingValue);\r\n\r\n    std::filesystem::remove(GetPathTo(PathName::SecureSettingsForRead) / name.Name);\r\n\r\n    REQUIRE_THROWS_HR(stream.Get(), SPAPI_E_FILE_HASH_NOT_IN_CATALOG);\r\n}\r\n\r\nTEST_CASE(\"SetAndReadSecureSetting_DataTampered\", \"[settings]\")\r\n{\r\n    StreamDefinition name{ Type::Secure, \"secure_testsettingname\" };\r\n    std::string value = \"This is the test setting value\";\r\n\r\n    Stream stream{ name };\r\n    REQUIRE(stream.Set(value));\r\n\r\n    auto result = stream.Get();\r\n    REQUIRE(static_cast<bool>(result));\r\n\r\n    std::string settingValue = ReadEntireStream(*result);\r\n    REQUIRE(value == settingValue);\r\n\r\n    StreamDefinition insecureName = name;\r\n    insecureName.Type = Type::Standard;\r\n\r\n    REQUIRE(Stream{ insecureName }.Set(\"Tampered data\"));\r\n\r\n    REQUIRE_THROWS_HR(stream.Get(), HRESULT_FROM_WIN32(ERROR_DATA_CHECKSUM_ERROR));\r\n}\r\n\r\nTEST_CASE(\"SetChangeAndReadSetting\", \"[settings]\")\r\n{\r\n    StreamDefinition name{ Type::Standard, \"testsettingname\" };\r\n    std::string value1 = \"This is the test setting value1\";\r\n    std::string value2 = \"This is the test setting value2, which is different\";\r\n    std::string value3 = \"This is the test setting value3; also different\";\r\n\r\n    name.Type = GENERATE(Type::Standard, Type::Secure);\r\n    INFO(ToString(name.Type));\r\n\r\n    // Set the value on stream 1\r\n    Stream stream1{ name };\r\n    REQUIRE(stream1.Set(value1));\r\n\r\n    // Read the value on stream 2 to verify\r\n    {\r\n        Stream stream2{ name };\r\n\r\n        auto result = stream2.Get();\r\n        REQUIRE(static_cast<bool>(result));\r\n\r\n        std::string settingValue = ReadEntireStream(*result);\r\n        REQUIRE(value1 == settingValue);\r\n\r\n        // Set the value on stream 2\r\n        REQUIRE(stream2.Set(value2));\r\n    }\r\n\r\n    // Attempt to set the value on stream 1 again\r\n    REQUIRE(!stream1.Set(value3));\r\n\r\n    // Attempting to set again should still not work\r\n    REQUIRE(!stream1.Set(value3));\r\n\r\n    // Ensure that the value remains value 2\r\n    auto result = stream1.Get();\r\n    REQUIRE(static_cast<bool>(result));\r\n\r\n    std::string settingValue = ReadEntireStream(*result);\r\n    REQUIRE(value2 == settingValue);\r\n\r\n    // Now that we have read it, we can update it\r\n    REQUIRE(stream1.Set(value3));\r\n\r\n    result = stream1.Get();\r\n    REQUIRE(static_cast<bool>(result));\r\n\r\n    settingValue = ReadEntireStream(*result);\r\n    REQUIRE(value3 == settingValue);\r\n}\r\n\r\nTEST_CASE(\"AttemptSetOnNewValue\", \"[settings]\")\r\n{\r\n    StreamDefinition name{ Type::Standard, \"testsettingname\" };\r\n    std::string value1 = \"This is the test setting value1\";\r\n    std::string value2 = \"This is the test setting value2, which is different\";\r\n\r\n    name.Type = GENERATE(Type::Standard, Type::Secure);\r\n    INFO(ToString(name.Type));\r\n\r\n    // Remove the stream\r\n    Stream{ name }.Remove();\r\n\r\n    Stream stream1{ name };\r\n    REQUIRE(!stream1.Get());\r\n\r\n    // Set the value on stream 2\r\n    {\r\n        Stream stream2{ name };\r\n        REQUIRE(stream2.Set(value1));\r\n    }\r\n\r\n    // Attempt to set the value on stream 1 again\r\n    REQUIRE(!stream1.Set(value2));\r\n\r\n    // Attempting to set again should still not work\r\n    REQUIRE(!stream1.Set(value2));\r\n\r\n    // Ensure that the value remains value 2\r\n    auto result = stream1.Get();\r\n    REQUIRE(static_cast<bool>(result));\r\n\r\n    std::string settingValue = ReadEntireStream(*result);\r\n    REQUIRE(value1 == settingValue);\r\n\r\n    // Now that we have read it, we can update it\r\n    REQUIRE(stream1.Set(value2));\r\n\r\n    result = stream1.Get();\r\n    REQUIRE(static_cast<bool>(result));\r\n\r\n    settingValue = ReadEntireStream(*result);\r\n    REQUIRE(value2 == settingValue);\r\n}\r\n\r\nTEST_CASE(\"SetAndReadSettingEncrypted\", \"[settings]\")\r\n{\r\n    StreamDefinition name{ Type::Encrypted, \"encrypted_test_setting\" };\r\n    std::string value = \"This is the test setting value\";\r\n\r\n    Stream stream{ name };\r\n    REQUIRE(stream.Set(value));\r\n\r\n    auto result = stream.Get();\r\n    REQUIRE(static_cast<bool>(result));\r\n\r\n    std::string settingValue = ReadEntireStream(*result);\r\n    REQUIRE(value == settingValue);\r\n\r\n    // Ensure that the data is encrypted\r\n    name.Type = Type::StandardFile;\r\n\r\n    Stream streamDirect{ name };\r\n\r\n    auto resultDirect = streamDirect.Get();\r\n    REQUIRE(static_cast<bool>(resultDirect));\r\n\r\n    std::string settingValueDirect = ReadEntireStream(*resultDirect);\r\n    REQUIRE(value != settingValueDirect);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/ShowFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"WorkflowCommon.h\"\r\n#include <Commands/ShowCommand.h>\r\n#include <Workflows/ShowFlow.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::CLI;\r\n\r\nTEST_CASE(\"ShowFlow_SearchAndShowAppInfo\", \"[ShowFlow][workflow]\")\r\n{\r\n    std::ostringstream showOutput;\r\n    TestContext context{ showOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForOpenSource(context, CreateTestSource({ TSR::TestQuery_ReturnOne }));\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestQuery_ReturnOne.Query);\r\n\r\n    ShowCommand show({});\r\n    show.Execute(context);\r\n    INFO(showOutput.str());\r\n\r\n    // Verify AppInfo is printed\r\n    REQUIRE(showOutput.str().find(\"AppInstallerCliTest.TestExeInstaller\") != std::string::npos);\r\n    REQUIRE(showOutput.str().find(\"AppInstaller Test Exe Installer\") != std::string::npos);\r\n    REQUIRE(showOutput.str().find(\"1.0.0.0\") != std::string::npos);\r\n    REQUIRE(showOutput.str().find(\"https://ThisIsNotUsed\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"ShowFlow_SearchAndShowAppVersion\", \"[ShowFlow][workflow]\")\r\n{\r\n    std::ostringstream showOutput;\r\n    TestContext context{ showOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForOpenSource(context, CreateTestSource({ TSR::TestQuery_ReturnOne }));\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestQuery_ReturnOne.Query);\r\n    context.Args.AddArg(Execution::Args::Type::ListVersions);\r\n\r\n    ShowCommand show({});\r\n    show.Execute(context);\r\n    INFO(showOutput.str());\r\n\r\n    // Verify App version is printed\r\n    REQUIRE(showOutput.str().find(\"1.0.0.0\") != std::string::npos);\r\n    // No manifest info is printed\r\n    REQUIRE(showOutput.str().find(\"  Download Url: https://ThisIsNotUsed\") == std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"ShowFlow_Dependencies\", \"[ShowFlow][workflow][dependencies]\")\r\n{\r\n    std::ostringstream showOutput;\r\n    TestContext context{ showOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"Manifest-Good-AllDependencyTypes.yaml\").GetPath().u8string());\r\n\r\n    ShowCommand show({});\r\n    show.Execute(context);\r\n    INFO(showOutput.str());\r\n\r\n    // Verify all types of dependencies are printed\r\n    REQUIRE(showOutput.str().find(\"Dependencies\") != std::string::npos);\r\n    REQUIRE(showOutput.str().find(\"WindowsFeaturesDep\") != std::string::npos);\r\n    REQUIRE(showOutput.str().find(\"WindowsLibrariesDep\") != std::string::npos);\r\n    // PackageDep1 has minimum version (1.0), PackageDep2 doesn't (shouldn't show [>=...])\r\n    REQUIRE(showOutput.str().find(\"Package.Dep1-x64 [>= 1.0]\") != std::string::npos);\r\n    REQUIRE(showOutput.str().find(\"Package.Dep2-x64\") != std::string::npos);\r\n    REQUIRE(showOutput.str().find(\"Package.Dep2-x64 [\") == std::string::npos);\r\n    REQUIRE(showOutput.str().find(\"ExternalDep\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"ShowFlow_InstallerType\", \"[ShowFlow][workflow]\")\r\n{\r\n    std::ostringstream showOutput;\r\n    TestContext context{ showOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_Exe.yaml\").GetPath().u8string());\r\n\r\n    ShowCommand show({});\r\n    show.Execute(context);\r\n    INFO(showOutput.str());\r\n\r\n    // Verify that just the base installed type is shown;\r\n    REQUIRE(showOutput.str().find(Resource::LocString(Resource::String::ShowLabelInstallerType)) != std::string::npos);\r\n    REQUIRE(showOutput.str().find(\"exe\") != std::string::npos);\r\n\r\n    // If the base installer is incorrectly shown, an open parenthesis would appear after the effective installer type\r\n    REQUIRE(showOutput.str().find(\"exe (\") == std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"ShowFlow_NestedInstallerType\", \"[ShowFlow][workflow]\")\r\n{\r\n    std::ostringstream showOutput;\r\n    TestContext context{ showOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_Zip_Exe.yaml\").GetPath().u8string());\r\n\r\n    ShowCommand show({});\r\n    show.Execute(context);\r\n    INFO(showOutput.str());\r\n\r\n    // Verify that both the effective and base installer types are shown\r\n    REQUIRE(showOutput.str().find(Resource::LocString(Resource::String::ShowLabelInstallerType)) != std::string::npos);\r\n    REQUIRE(showOutput.str().find(\"exe (zip)\") != std::string::npos);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/Sixel.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <Sixel.h>\r\n\r\nusing namespace AppInstaller::CLI::VirtualTerminal::Sixel;\r\n\r\nvoid ValidateGetPixel(std::string_view info, UINT_PTR offset, UINT byteCount, UINT_PTR expected)\r\n{\r\n    INFO(info);\r\n    REQUIRE(offset < byteCount);\r\n    REQUIRE(offset == expected);\r\n}\r\n\r\nTEST_CASE(\"ImageView_GetPixel\", \"[sixel]\")\r\n{\r\n    UINT width = 20;\r\n    UINT height = 20;\r\n    UINT stride = 32;\r\n    UINT byteCount = height * stride;\r\n    BYTE* byteBase = reinterpret_cast<BYTE*>(100);\r\n\r\n    ImageView view{ width, height, stride, byteCount, byteBase };\r\n\r\n    ValidateGetPixel(\"No translation\", view.GetPixel(3, 17) - byteBase, byteCount, 17 * stride + 3);\r\n\r\n    view.Translate(14, 8, true);\r\n    ValidateGetPixel(\"Positive translation (tile)\", view.GetPixel(3, 17) - byteBase, byteCount, 9 * stride + 9);\r\n\r\n    view.Translate(-14, 8, true);\r\n    ValidateGetPixel(\"Negative translation (tile)\", view.GetPixel(3, 17) - byteBase, byteCount, 9 * stride + 17);\r\n\r\n    view.Translate(14, -8, false);\r\n    REQUIRE(view.GetPixel(3, 17) == nullptr);\r\n    ValidateGetPixel(\"Negative translation (no tile)\", view.GetPixel(15, 1) - byteBase, byteCount, 9 * stride + 1);\r\n}\r\n\r\nTEST_CASE(\"Image_Render\", \"[sixel]\")\r\n{\r\n    Image image{ TestCommon::TestDataFile(\"notepad.ico\") };\r\n    REQUIRE(!image.Render().Get().empty());\r\n\r\n    image.AspectRatio(AspectRatio::ThreeToOne);\r\n    image.ColorCount(64);\r\n    image.RenderSizeInCells(2, 1);\r\n    image.UseRepeatSequence(true);\r\n    REQUIRE(!image.Render().Get().empty());\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/SourceFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"WorkflowCommon.h\"\r\n#include \"TestHooks.h\"\r\n#include \"TestSettings.h\"\r\n#include <Commands/SourceCommand.h>\r\n#include <Workflows/PromptFlow.h>\r\n#include <Workflows/SourceFlow.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::CLI;\r\nusing namespace AppInstaller::CLI::Workflow;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Settings;\r\n\r\nvoid OverrideForSourceAddWithAgreements(TestContext& context, bool isAddExpected = true)\r\n{\r\n    context.Override({ EnsureRunningAsAdmin, [](TestContext&)\r\n    {\r\n    } });\r\n\r\n    if (isAddExpected)\r\n    {\r\n        context.Override({ AddSource, [](TestContext&)\r\n        {\r\n        } });\r\n    }\r\n\r\n    context.Override({ CreateSourceForSourceAdd, [](TestContext& context)\r\n    {\r\n        auto testSource = std::make_shared<TestSource>();\r\n        testSource->Information.SourceAgreementsIdentifier = \"AgreementsIdentifier\";\r\n        testSource->Information.SourceAgreements.emplace_back(\"Agreement Label\", \"Agreement Text\", \"https://test\");\r\n        testSource->Information.RequiredPackageMatchFields.emplace_back(\"Market\");\r\n        testSource->Information.RequiredQueryParameters.emplace_back(\"Market\");\r\n        context << Workflow::HandleSourceAgreements(Source{ testSource });\r\n    } });\r\n}\r\n\r\nTEST_CASE(\"SourceAddFlow_Agreement\", \"[SourceAddFlow][workflow]\")\r\n{\r\n    std::ostringstream sourceAddOutput;\r\n    TestContext context{ sourceAddOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForSourceAddWithAgreements(context);\r\n    context.Args.AddArg(Execution::Args::Type::SourceName, \"TestSource\"sv);\r\n    context.Args.AddArg(Execution::Args::Type::SourceType, \"Microsoft.Test\"sv);\r\n    context.Args.AddArg(Execution::Args::Type::SourceArg, \"TestArg\"sv);\r\n    context.Args.AddArg(Execution::Args::Type::AcceptSourceAgreements);\r\n\r\n    SourceAddCommand sourceAdd({});\r\n    sourceAdd.Execute(context);\r\n    INFO(sourceAddOutput.str());\r\n\r\n    // Verify agreements are shown\r\n    REQUIRE(sourceAddOutput.str().find(\"Agreement Label\") != std::string::npos);\r\n    REQUIRE(sourceAddOutput.str().find(\"Agreement Text\") != std::string::npos);\r\n    REQUIRE(sourceAddOutput.str().find(\"https://test\") != std::string::npos);\r\n    REQUIRE(sourceAddOutput.str().find(Resource::LocString(Resource::String::SourceAgreementsMarketMessage).get()) != std::string::npos);\r\n\r\n    // Verify Installer is called.\r\n    REQUIRE(context.GetTerminationHR() == S_OK);\r\n}\r\n\r\nTEST_CASE(\"SourceAddFlow_Agreement_Prompt_Yes\", \"[SourceAddFlow][workflow]\")\r\n{\r\n    // Accept the agreements by saying \"Yes\" at the prompt\r\n    std::istringstream sourceAddInput{ \"y\" };\r\n    std::ostringstream sourceAddOutput;\r\n    TestContext context{ sourceAddOutput, sourceAddInput };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForSourceAddWithAgreements(context);\r\n    context.Args.AddArg(Execution::Args::Type::SourceName, \"TestSource\"sv);\r\n    context.Args.AddArg(Execution::Args::Type::SourceType, \"Microsoft.Test\"sv);\r\n    context.Args.AddArg(Execution::Args::Type::SourceArg, \"TestArg\"sv);\r\n\r\n    SourceAddCommand sourceAdd({});\r\n    sourceAdd.Execute(context);\r\n    INFO(sourceAddOutput.str());\r\n\r\n    // Verify agreements are shown\r\n    REQUIRE(sourceAddOutput.str().find(\"Agreement Label\") != std::string::npos);\r\n    REQUIRE(sourceAddOutput.str().find(\"Agreement Text\") != std::string::npos);\r\n    REQUIRE(sourceAddOutput.str().find(\"https://test\") != std::string::npos);\r\n    REQUIRE(sourceAddOutput.str().find(Resource::LocString(Resource::String::SourceAgreementsMarketMessage).get()) != std::string::npos);\r\n\r\n    // Verify Installer is called.\r\n    REQUIRE(context.GetTerminationHR() == S_OK);\r\n}\r\n\r\nTEST_CASE(\"SourceAddFlow_Agreement_Prompt_No\", \"[SourceAddFlow][workflow]\")\r\n{\r\n    // Accept the agreements by saying \"No\" at the prompt\r\n    std::istringstream sourceAddInput{ \"n\" };\r\n    std::ostringstream sourceAddOutput;\r\n    TestContext context{ sourceAddOutput, sourceAddInput };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForSourceAddWithAgreements(context, false);\r\n    context.Args.AddArg(Execution::Args::Type::SourceName, \"TestSource\"sv);\r\n    context.Args.AddArg(Execution::Args::Type::SourceType, \"Microsoft.Test\"sv);\r\n    context.Args.AddArg(Execution::Args::Type::SourceArg, \"TestArg\"sv);\r\n\r\n    SourceAddCommand sourceAdd({});\r\n    sourceAdd.Execute(context);\r\n    INFO(sourceAddOutput.str());\r\n\r\n    // Verify agreements are shown\r\n    REQUIRE(sourceAddOutput.str().find(\"Agreement Label\") != std::string::npos);\r\n    REQUIRE(sourceAddOutput.str().find(\"Agreement Text\") != std::string::npos);\r\n    REQUIRE(sourceAddOutput.str().find(\"https://test\") != std::string::npos);\r\n    REQUIRE(sourceAddOutput.str().find(Resource::LocString(Resource::String::SourceAgreementsMarketMessage).get()) != std::string::npos);\r\n\r\n    // Verify Installer is called.\r\n    REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED);\r\n}\r\n\r\nTEST_CASE(\"OpenSource_WithCustomHeader\", \"[OpenSource][CustomHeader]\")\r\n{\r\n    SetSetting(Stream::UserSources, R\"(Sources:)\"sv);\r\n    TestHook_ClearSourceFactoryOverrides();\r\n\r\n    SourceDetails details;\r\n    details.Name = \"restsource\";\r\n    details.Type = \"Microsoft.Rest\";\r\n    details.Arg = \"thisIsTheArg\";\r\n    details.Data = \"thisIsTheData\";\r\n\r\n    std::string customHeader = \"Test custom header in Open source Flow\";\r\n\r\n    bool receivedCustomHeader = false;\r\n    TestSourceFactory factory{\r\n        [&](const SourceDetails& sd, std::optional<std::string> header)\r\n        {\r\n            receivedCustomHeader = header.value() == customHeader;\r\n            return std::shared_ptr<ISource>(new TestSource(sd));\r\n        } };\r\n    TestHook_SetSourceFactoryOverride(details.Type, factory);\r\n\r\n    TestProgress progress;\r\n    AddSource(details, progress);\r\n\r\n    std::ostringstream output;\r\n    TestContext context{ output, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    context.Args.AddArg(Execution::Args::Type::Query, \"TestQuery\"sv);\r\n    context.Args.AddArg(Execution::Args::Type::CustomHeader, customHeader);\r\n    context.Args.AddArg(Execution::Args::Type::Source, details.Name);\r\n\r\n    AppInstaller::CLI::Workflow::OpenSource()(context);\r\n    REQUIRE(receivedCustomHeader);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/Sources.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestHooks.h\"\r\n#include \"TestSettings.h\"\r\n#include \"TestSource.h\"\r\n\r\n#include <AppInstallerDateTime.h>\r\n#include <AppInstallerRuntime.h>\r\n#include <AppInstallerStrings.h>\r\n#include <AppInstallerErrors.h>\r\n#include <winget/Settings.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller;\r\nusing namespace AppInstaller::Runtime;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Settings;\r\nusing namespace AppInstaller::Utility;\r\n\r\n// Duplicating here because a change to these values in the product *REALLY* needs to be thought through.\r\nusing namespace std::string_literals;\r\nusing namespace std::string_view_literals;\r\n\r\nconstexpr size_t c_DefaultSourceCount = 3;\r\n\r\nconstexpr std::string_view s_SourcesYaml_Sources = \"Sources\"sv;\r\nconstexpr std::string_view s_SourcesYaml_Source_Name = \"Name\"sv;\r\nconstexpr std::string_view s_SourcesYaml_Source_Type = \"Type\"sv;\r\nconstexpr std::string_view s_SourcesYaml_Source_Arg = \"Arg\"sv;\r\nconstexpr std::string_view s_SourcesYaml_Source_Data = \"Data\"sv;\r\nconstexpr std::string_view s_SourcesYaml_Source_TrustLevel = \"TrustLevel\"sv;\r\nconstexpr std::string_view s_SourcesYaml_Source_Explicit = \"Explicit\"sv;\r\nconstexpr std::string_view s_SourcesYaml_Source_LastUpdate = \"LastUpdate\"sv;\r\n\r\nconstexpr std::string_view s_EmptySources = R\"(\r\nSources:\r\n)\"sv;\r\n\r\nconstexpr std::string_view s_DefaultSourcesTombstoned = R\"(\r\nSources:\r\n  - Name: winget\r\n    Type: \"\"\r\n    Arg: \"\"\r\n    Data: \"\"\r\n    IsTombstone: true\r\n  - Name: msstore\r\n    Type: \"\"\r\n    Arg: \"\"\r\n    Data: \"\"\r\n    IsTombstone: true\r\n  - Name: winget-font\r\n    Type: \"\"\r\n    Arg: \"\"\r\n    Data: \"\"\r\n    IsTombstone: true\r\n)\"sv;\r\n\r\nconstexpr std::string_view s_SingleSource = R\"(\r\nSources:\r\n  - Name: testName\r\n    Type: testType\r\n    Arg: testArg\r\n    Data: testData\r\n    IsTombstone: false\r\n)\"sv;\r\n\r\nconstexpr std::string_view s_SingleSourceOverride = R\"(\r\nSources:\r\n  - Name: winget-font\r\n    Type: \"\"\r\n    Arg: \"\"\r\n    Data: \"\"\r\n    IsTombstone: false\r\n    IsOverride: true\r\n    Explicit: false\r\n    Priority: 12\r\n)\"sv;\r\n\r\nconstexpr std::string_view s_SingleSourceMetadata = R\"(\r\nSources:\r\n  - Name: testName\r\n    LastUpdate: 100\r\n)\"sv;\r\n\r\nconstexpr std::string_view s_SingleSourceMetadataUpdate = R\"(\r\nSources:\r\n  - Name: testName\r\n    LastUpdate: 101\r\n)\"sv;\r\n\r\nconstexpr std::string_view s_DoubleSource = R\"(\r\nSources:\r\n  - Name: testName\r\n    Type: testType\r\n    Arg: testArg\r\n    Data: testData\r\n    IsTombstone: false\r\n  - Name: testName2\r\n    Type: testType\r\n    Arg: testArg2\r\n    Data: testData2\r\n    IsTombstone: false\r\n)\"sv;\r\n\r\nconstexpr std::string_view s_DoubleSourceMetadata = R\"(\r\nSources:\r\n  - Name: testName\r\n    LastUpdate: 100\r\n  - Name: testName2\r\n    LastUpdate: 200\r\n)\"sv;\r\n\r\nconstexpr std::string_view s_ThreeSources = R\"(\r\nSources:\r\n  - Name: testName\r\n    Type: testType\r\n    Arg: testArg\r\n    Data: testData\r\n    IsTombstone: false\r\n    Priority: 1\r\n  - Name: testName2\r\n    Type: testType2\r\n    Arg: testArg2\r\n    Data: testData2\r\n    IsTombstone: false\r\n    Priority: 5\r\n  - Name: testName3\r\n    Type: testType3\r\n    Arg: testArg3\r\n    Data: testData3\r\n    IsTombstone: false\r\n    Priority: 3\r\n  - Name: winget\r\n    Type: \"\"\r\n    Arg: \"\"\r\n    Data: \"\"\r\n    IsTombstone: true\r\n  - Name: msstore\r\n    Type: \"\"\r\n    Arg: \"\"\r\n    Data: \"\"\r\n    IsTombstone: true\r\n  - Name: winget-font\r\n    Type: \"\"\r\n    Arg: \"\"\r\n    Data: \"\"\r\n    IsTombstone: true\r\n)\"sv;\r\n\r\nconstexpr std::string_view s_ThreeSourcesMetadata = R\"(\r\nSources:\r\n  - Name: testName\r\n    LastUpdate: 0\r\n  - Name: testName2\r\n    LastUpdate: 1\r\n  - Name: testName3\r\n    LastUpdate: 2\r\n)\"sv;\r\n\r\nconstexpr std::string_view s_SingleSource_MissingArg = R\"(\r\nSources:\r\n  - Name: testName\r\n    Type: testType\r\n    Data: testData\r\n    IsTombstone: false\r\n)\"sv;\r\n\r\nconstexpr std::string_view s_TwoSource_AggregateSourceTest = R\"(\r\nSources:\r\n  - Name: winget\r\n    Type: testType\r\n    Arg: testArg\r\n    Data: testData\r\n    IsTombstone: false\r\n  - Name: msstore\r\n    Type: testType\r\n    Arg: testArg\r\n    Data: testData\r\n    IsTombstone: false\r\n)\"sv;\r\n\r\nconstexpr std::string_view s_DefaultSourceAsUserSource = R\"(\r\nSources:\r\n  - Name: not-winget\r\n    Type: Microsoft.PreIndexed.Package\r\n    Arg: https://cdn.winget.microsoft.com/cache\r\n    Data: Microsoft.Winget.Source_8wekyb3d8bbwe\r\n    IsTombstone: false\r\n)\"sv;\r\n\r\nconstexpr std::string_view s_UserSourceNamedLikeDefault = R\"(\r\nSources:\r\n  - Name: winget\r\n    Type: testType\r\n    Arg: testArg\r\n    Data: testData\r\n    IsTombstone: false\r\n)\"sv;\r\n\r\nconstexpr std::string_view s_SingleSource_AllProperties= R\"(\r\nSources:\r\n  - Name: testName\r\n    Type: testType\r\n    Arg: testArg\r\n    Data: testData\r\n    IsTombstone: false\r\n    TrustLevel: 3\r\n    Explicit: true\r\n    Priority: 1\r\n)\"sv;\r\n\r\nnamespace\r\n{\r\n    // Helper to create a simple source.\r\n    struct SourcesTestSource : public TestSource\r\n    {\r\n        SourcesTestSource() = default;\r\n        SourcesTestSource(const SourceDetails& details)\r\n        {\r\n            Details = details;\r\n        }\r\n\r\n        static std::shared_ptr<ISource> Create(const SourceDetails& details)\r\n        {\r\n            // using return std::make_shared<TestSource>(details); will crash the x86 test during destruction.\r\n            return std::shared_ptr<ISource>(new SourcesTestSource(details));\r\n        }\r\n\r\n        SearchResult Search(const SearchRequest&) const override\r\n        {\r\n            SearchResult result;\r\n            PackageMatchFilter testMatchFilter1{ PackageMatchField::Id, MatchType::Exact, \"test\" };\r\n            PackageMatchFilter testMatchFilter2{ PackageMatchField::Name, MatchType::Exact, \"test\" };\r\n            PackageMatchFilter testMatchFilter3{ PackageMatchField::Id, MatchType::CaseInsensitive, \"test\" };\r\n            result.Matches.emplace_back(nullptr, testMatchFilter1);\r\n            result.Matches.emplace_back(nullptr, testMatchFilter2);\r\n            result.Matches.emplace_back(nullptr, testMatchFilter3);\r\n            return result;\r\n        }\r\n    };\r\n\r\n    // Failing source for use with s_TwoSource_AggregateSourceTest\r\n    struct FailingSourcesTestSource : public TestSource\r\n    {\r\n        static constexpr HRESULT FailingHR = 0xBADDAD0D;\r\n\r\n        FailingSourcesTestSource() = default;\r\n        FailingSourcesTestSource(const SourceDetails& details)\r\n        {\r\n            Details = details;\r\n        }\r\n\r\n        static std::shared_ptr<ISource> CreateFailWinget(const SourceDetails& details)\r\n        {\r\n            if (details.Name == \"winget\")\r\n            {\r\n                THROW_HR(FailingHR);\r\n            }\r\n\r\n            return std::shared_ptr<ISource>(new FailingSourcesTestSource(details));\r\n        }\r\n\r\n        static std::shared_ptr<ISource> CreateFailAll(const SourceDetails&)\r\n        {\r\n            THROW_HR(FailingHR);\r\n        }\r\n    };\r\n\r\n    void RequireDefaultSourcesAt(const std::vector<SourceDetails>& sources, size_t index)\r\n    {\r\n        REQUIRE(sources.size() >= index + c_DefaultSourceCount);\r\n\r\n        for (size_t i = index; i < sources.size(); ++i)\r\n        {\r\n            INFO(i);\r\n            REQUIRE(sources[i].Origin == SourceOrigin::Default);\r\n        }\r\n    }\r\n}\r\n\r\n\r\nTEST_CASE(\"RepoSources_UserSettingDoesNotExist\", \"[sources]\")\r\n{\r\n    RemoveSetting(Stream::UserSources);\r\n\r\n    std::vector<SourceDetails> sources = GetSources();\r\n    REQUIRE(sources.size() == c_DefaultSourceCount);\r\n    RequireDefaultSourcesAt(sources, 0);\r\n}\r\n\r\nTEST_CASE(\"RepoSources_EmptySourcesList\", \"[sources]\")\r\n{\r\n    SetSetting(Stream::UserSources, s_EmptySources);\r\n\r\n    std::vector<SourceDetails> sources = GetSources();\r\n    REQUIRE(sources.size() == c_DefaultSourceCount);\r\n    RequireDefaultSourcesAt(sources, 0);\r\n}\r\n\r\nTEST_CASE(\"RepoSources_DefaultSourcesTombstoned\", \"[sources]\")\r\n{\r\n    SetSetting(Stream::UserSources, s_DefaultSourcesTombstoned);\r\n\r\n    std::vector<SourceDetails> sources = GetSources();\r\n    REQUIRE(sources.empty());\r\n}\r\n\r\n\r\nTEST_CASE(\"RepoSources_DefaultSourceOverride\", \"[sources]\")\r\n{\r\n    SetSetting(Stream::UserSources, s_EmptySources);\r\n\r\n    // Default font has explicit to true.\r\n    // Font is at index 2 as it is the third one added.\r\n    auto beforeOverride = GetSources();\r\n    REQUIRE(beforeOverride.size() == c_DefaultSourceCount);\r\n    REQUIRE(beforeOverride[2].Name == \"winget-font\");\r\n    REQUIRE(beforeOverride[2].Arg == \"https://cdn.winget.microsoft.com/fonts\");\r\n    REQUIRE(beforeOverride[2].Data == \"Microsoft.Winget.Fonts.Source_8wekyb3d8bbwe\");\r\n    REQUIRE(beforeOverride[2].Type == \"Microsoft.PreIndexed.Package\");\r\n    REQUIRE(beforeOverride[2].Origin == SourceOrigin::Default);\r\n    REQUIRE(beforeOverride[2].Explicit == true);\r\n    REQUIRE(beforeOverride[2].Priority == 0);\r\n\r\n    SetSetting(Stream::UserSources, s_SingleSourceOverride);\r\n    auto afterOverride = GetSources();\r\n\r\n    // The override will change the index value as the Default will be replaced by the override.\r\n    // User sources have higher priority so the override will be at index 0.\r\n    // We expect the same count, and the Name, Arg, Data, and Type properties to all be identical.\r\n    // Only the name is defined in the override setting so all others should be properly populated.\r\n    REQUIRE(afterOverride.size() == c_DefaultSourceCount);\r\n    REQUIRE(afterOverride[0].Name == beforeOverride[2].Name);\r\n    REQUIRE(afterOverride[0].Arg == beforeOverride[2].Arg);\r\n    REQUIRE(afterOverride[0].Data == beforeOverride[2].Data);\r\n    REQUIRE(afterOverride[0].Type == beforeOverride[2].Type);\r\n\r\n    // The only properties we expect to be different are the Origin, which is now User, and Explicit.\r\n    REQUIRE(afterOverride[0].Origin == SourceOrigin::User);\r\n    REQUIRE(afterOverride[0].Explicit == false);\r\n    REQUIRE(afterOverride[0].Priority == 12);\r\n}\r\n\r\nTEST_CASE(\"RepoSources_SingleSource\", \"[sources]\")\r\n{\r\n    SetSetting(Stream::UserSources, s_SingleSource);\r\n    RemoveSetting(Stream::SourcesMetadata);\r\n\r\n    std::vector<SourceDetails> sources = GetSources();\r\n    REQUIRE(sources.size() == c_DefaultSourceCount + 1);\r\n\r\n    REQUIRE(sources[0].Name == \"testName\");\r\n    REQUIRE(sources[0].Type == \"testType\");\r\n    REQUIRE(sources[0].Arg == \"testArg\");\r\n    REQUIRE(sources[0].Data == \"testData\");\r\n    REQUIRE(sources[0].Origin == SourceOrigin::User);\r\n    REQUIRE(sources[0].LastUpdateTime == ConvertUnixEpochToSystemClock(0));\r\n\r\n    RequireDefaultSourcesAt(sources, 1);\r\n}\r\n\r\nTEST_CASE(\"RepoSources_SingleSource_AllProperties\", \"[sources]\")\r\n{\r\n    SetSetting(Stream::UserSources, s_SingleSource_AllProperties);\r\n    RemoveSetting(Stream::SourcesMetadata);\r\n\r\n    std::vector<SourceDetails> sources = GetSources();\r\n    REQUIRE(sources.size() == c_DefaultSourceCount + 1);\r\n\r\n    REQUIRE(sources[0].Name == \"testName\");\r\n    REQUIRE(sources[0].Type == \"testType\");\r\n    REQUIRE(sources[0].Arg == \"testArg\");\r\n    REQUIRE(sources[0].Data == \"testData\");\r\n    REQUIRE(sources[0].Origin == SourceOrigin::User);\r\n    REQUIRE(sources[0].Explicit == true);\r\n    REQUIRE(sources[0].Priority == 1);\r\n    REQUIRE(WI_IsFlagSet(sources[0].TrustLevel, SourceTrustLevel::Trusted));\r\n    REQUIRE(WI_IsFlagSet(sources[0].TrustLevel, SourceTrustLevel::StoreOrigin));\r\n    REQUIRE(sources[0].LastUpdateTime == ConvertUnixEpochToSystemClock(0));\r\n\r\n    RequireDefaultSourcesAt(sources, 1);\r\n}\r\n\r\nTEST_CASE(\"RepoSources_ThreeSources\", \"[sources]\")\r\n{\r\n    SetSetting(Stream::UserSources, s_ThreeSources);\r\n    SetSetting(Stream::SourcesMetadata, s_ThreeSourcesMetadata);\r\n\r\n    const char* suffixStrings[3] = { \"\", \"2\", \"3\" };\r\n    size_t suffixUnsorted[3] = { 0, 1, 2 };\r\n    size_t suffixPrioritySorted[3] = { 1, 2, 0 };\r\n    size_t* suffix = nullptr;\r\n    std::unique_ptr<TestHook::SetSingleExperimentalFeature_Override> override;\r\n\r\n    SECTION(\"Unsorted\")\r\n    {\r\n        suffix = suffixUnsorted;\r\n    }\r\n    SECTION(\"Priority Sorted\")\r\n    {\r\n        override = std::make_unique<TestHook::SetSingleExperimentalFeature_Override>(ExperimentalFeature::Feature::SourcePriority);\r\n        suffix = suffixPrioritySorted;\r\n    }\r\n\r\n    std::vector<SourceDetails> sources = GetSources();\r\n    REQUIRE(sources.size() == 3);\r\n\r\n    for (size_t index = 0; index < 3; ++index)\r\n    {\r\n        size_t i = suffix[index];\r\n\r\n        INFO(\"Source #\" << index << \" [\" << i << \"]\");\r\n        REQUIRE(sources[index].Name == \"testName\"s + suffixStrings[i]);\r\n        REQUIRE(sources[index].Type == \"testType\"s + suffixStrings[i]);\r\n        REQUIRE(sources[index].Arg == \"testArg\"s + suffixStrings[i]);\r\n        REQUIRE(sources[index].Data == \"testData\"s + suffixStrings[i]);\r\n        REQUIRE(sources[index].LastUpdateTime == ConvertUnixEpochToSystemClock(i));\r\n        REQUIRE(sources[index].Origin == SourceOrigin::User);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"RepoSources_InvalidYAML\", \"[sources]\")\r\n{\r\n    SetSetting(Stream::UserSources, \"Name: Value : BAD\");\r\n\r\n    REQUIRE_NOTHROW(GetSources());\r\n}\r\n\r\nTEST_CASE(\"RepoSources_MissingField\", \"[sources]\")\r\n{\r\n    SetSetting(Stream::UserSources, s_SingleSource_MissingArg);\r\n\r\n    REQUIRE_NOTHROW(GetSources());\r\n}\r\n\r\nTEST_CASE(\"RepoSources_AddSource\", \"[sources]\")\r\n{\r\n    SetSetting(Stream::UserSources, s_EmptySources);\r\n    TestHook_ClearSourceFactoryOverrides();\r\n\r\n    SourceDetails details;\r\n    details.Name = \"thisIsTheName\";\r\n    details.Type = \"thisIsTheType\";\r\n    details.Arg = \"thisIsTheArg\";\r\n    details.Data = \"thisIsTheData\";\r\n    details.TrustLevel = Repository::SourceTrustLevel::None;\r\n    details.Explicit = false;\r\n    details.Priority = 42;\r\n\r\n    bool addCalledOnFactory = false;\r\n    TestSourceFactory factory{ SourcesTestSource::Create };\r\n    factory.OnAdd = [&](SourceDetails& sd) { addCalledOnFactory = true; sd.Data = details.Data; };\r\n    TestHook_SetSourceFactoryOverride(details.Type, factory);\r\n\r\n    ProgressCallback progress;\r\n    AddSource(details, progress);\r\n\r\n    REQUIRE(addCalledOnFactory);\r\n\r\n    std::vector<SourceDetails> sources = GetSources();\r\n    REQUIRE(sources.size() == c_DefaultSourceCount + 1);\r\n\r\n    REQUIRE(sources[0].Name == details.Name);\r\n    REQUIRE(sources[0].Type == details.Type);\r\n    REQUIRE(sources[0].Arg == details.Arg);\r\n    REQUIRE(sources[0].Data == details.Data);\r\n    REQUIRE(sources[0].LastUpdateTime != ConvertUnixEpochToSystemClock(0));\r\n    REQUIRE(sources[0].Origin == SourceOrigin::User);\r\n    REQUIRE(sources[0].TrustLevel == details.TrustLevel);\r\n    REQUIRE(sources[0].Explicit == details.Explicit);\r\n    REQUIRE(sources[0].Priority == details.Priority);\r\n\r\n    RequireDefaultSourcesAt(sources, 1);\r\n}\r\n\r\nTEST_CASE(\"RepoSources_AddMultipleSources\", \"[sources]\")\r\n{\r\n    SetSetting(Stream::UserSources, s_EmptySources);\r\n\r\n    SourceDetails details;\r\n    details.Name = \"thisIsTheName\";\r\n    details.Type = \"thisIsTheType\";\r\n    details.Arg = \"thisIsTheArg\";\r\n    details.Data = \"thisIsTheData\";\r\n\r\n    const char* suffix[2] = { \"\", \"2\" };\r\n\r\n    TestSourceFactory factory1{ SourcesTestSource::Create };\r\n    factory1.OnAdd = [&](SourceDetails& sd) { sd.Data = details.Data; };\r\n    TestHook_SetSourceFactoryOverride(details.Type, factory1);\r\n\r\n    ProgressCallback progress;\r\n    AddSource(details, progress);\r\n\r\n    std::vector<SourceDetails> sources = GetSources();\r\n    REQUIRE(sources.size() == c_DefaultSourceCount + 1);\r\n\r\n    REQUIRE(sources[0].Name == details.Name);\r\n    REQUIRE(sources[0].Type == details.Type);\r\n    REQUIRE(sources[0].Arg == details.Arg);\r\n    REQUIRE(sources[0].Data == details.Data);\r\n    REQUIRE(sources[0].LastUpdateTime != ConvertUnixEpochToSystemClock(0));\r\n    REQUIRE(sources[0].Origin == SourceOrigin::User);\r\n\r\n    RequireDefaultSourcesAt(sources, 1);\r\n\r\n    SourceDetails details2;\r\n    details2.Name = details.Name + suffix[1];\r\n    details2.Type = details.Type + suffix[1];\r\n    details2.Arg = details.Arg + suffix[1];\r\n    details2.Data = details.Data + suffix[1];\r\n    TestSourceFactory factory2{ SourcesTestSource::Create };\r\n    factory2.OnAdd = [&](SourceDetails& sd) { sd.Data = details2.Data; };\r\n    TestHook_SetSourceFactoryOverride(details2.Type, factory2);\r\n\r\n    AddSource(details2, progress);\r\n\r\n    sources = GetSources();\r\n    REQUIRE(sources.size() == c_DefaultSourceCount + 2);\r\n\r\n    for (size_t i = 0; i < 2; ++i)\r\n    {\r\n        INFO(\"Source #\" << i);\r\n        REQUIRE(sources[i].Name == details.Name + suffix[i]);\r\n        REQUIRE(sources[i].Type == details.Type + suffix[i]);\r\n        REQUIRE(sources[i].Arg == details.Arg + suffix[i]);\r\n        REQUIRE(sources[i].Data == details.Data + suffix[i]);\r\n        REQUIRE(sources[i].LastUpdateTime != ConvertUnixEpochToSystemClock(0));\r\n        REQUIRE(sources[i].Origin == SourceOrigin::User);\r\n    }\r\n\r\n    RequireDefaultSourcesAt(sources, 2);\r\n}\r\n\r\nTEST_CASE(\"RepoSources_UpdateSource\", \"[sources]\")\r\n{\r\n    using namespace std::chrono_literals;\r\n\r\n    SetSetting(Stream::UserSources, s_EmptySources);\r\n    TestHook_ClearSourceFactoryOverrides();\r\n\r\n    SourceDetails details;\r\n    details.Name = \"thisIsTheName\";\r\n    details.Type = \"thisIsTheType\";\r\n    details.Arg = \"thisIsTheArg\";\r\n    details.Data = \"thisIsTheData\";\r\n\r\n    bool addCalledOnFactory = false;\r\n    TestSourceFactory factory{ SourcesTestSource::Create };\r\n    factory.OnAdd = [&](SourceDetails& sd) { addCalledOnFactory = true; sd.Data = details.Data; };\r\n    TestHook_SetSourceFactoryOverride(details.Type, factory);\r\n\r\n    ProgressCallback progress;\r\n    AddSource(details, progress);\r\n\r\n    REQUIRE(addCalledOnFactory);\r\n\r\n    std::vector<SourceDetails> sources = GetSources();\r\n    REQUIRE(sources.size() == c_DefaultSourceCount + 1);\r\n\r\n    REQUIRE(sources[0].Name == details.Name);\r\n    REQUIRE(sources[0].Type == details.Type);\r\n    REQUIRE(sources[0].Arg == details.Arg);\r\n    REQUIRE(sources[0].Data == details.Data);\r\n    REQUIRE(sources[0].LastUpdateTime != ConvertUnixEpochToSystemClock(0));\r\n    REQUIRE(sources[0].Origin == SourceOrigin::User);\r\n\r\n    RequireDefaultSourcesAt(sources, 1);\r\n\r\n    // Reset for a call to update\r\n    bool updateCalledOnFactory = false;\r\n    auto now = std::chrono::system_clock::now();\r\n    factory.OnUpdate = [&](const SourceDetails&) { updateCalledOnFactory = true; };\r\n\r\n    UpdateSource(details.Name, progress);\r\n\r\n    REQUIRE(updateCalledOnFactory);\r\n\r\n    sources = GetSources();\r\n    REQUIRE(sources.size() == c_DefaultSourceCount + 1);\r\n\r\n    REQUIRE(sources[0].Name == details.Name);\r\n    REQUIRE(sources[0].Type == details.Type);\r\n    REQUIRE(sources[0].Arg == details.Arg);\r\n    REQUIRE(sources[0].Data == details.Data);\r\n    REQUIRE((now - sources[0].LastUpdateTime) < 1s);\r\n}\r\n\r\nTEST_CASE(\"RepoSources_UpdateSourceRetries\", \"[sources]\")\r\n{\r\n    using namespace std::chrono_literals;\r\n\r\n    SetSetting(Stream::UserSources, s_EmptySources);\r\n    TestHook_ClearSourceFactoryOverrides();\r\n\r\n    SourceDetails details;\r\n    details.Name = \"thisIsTheName\";\r\n    details.Type = \"thisIsTheType\";\r\n    details.Arg = \"thisIsTheArg\";\r\n    details.Data = \"thisIsTheData\";\r\n\r\n    TestSourceFactory factory{ SourcesTestSource::Create };\r\n    factory.OnAdd = [&](SourceDetails& sd) { sd.Data = details.Data; };\r\n    TestHook_SetSourceFactoryOverride(details.Type, factory);\r\n\r\n    ProgressCallback progress;\r\n    AddSource(details, progress);\r\n\r\n    // Reset for a call to update\r\n    bool updateShouldThrow = false;\r\n    bool updateCalledOnFactoryAgain = false;\r\n    factory.OnUpdate = [&](const SourceDetails&)\r\n    {\r\n        if (updateShouldThrow)\r\n        {\r\n            updateShouldThrow = false;\r\n            THROW_HR(E_ACCESSDENIED);\r\n        }\r\n        updateCalledOnFactoryAgain = true;\r\n    };\r\n\r\n    UpdateSource(details.Name, progress);\r\n\r\n    REQUIRE(updateCalledOnFactoryAgain);\r\n}\r\n\r\nTEST_CASE(\"RepoSources_RemoveSource\", \"[sources]\")\r\n{\r\n    SetSetting(Stream::UserSources, s_EmptySources);\r\n    TestHook_ClearSourceFactoryOverrides();\r\n\r\n    SourceDetails details;\r\n    details.Name = \"thisIsTheName\";\r\n    details.Type = \"thisIsTheType\";\r\n    details.Arg = \"thisIsTheArg\";\r\n    details.Data = \"thisIsTheData\";\r\n\r\n    bool removeCalledOnFactory = false;\r\n    TestSourceFactory factory{ SourcesTestSource::Create };\r\n    factory.OnRemove = [&](const SourceDetails&) { removeCalledOnFactory = true; };\r\n    TestHook_SetSourceFactoryOverride(details.Type, factory);\r\n\r\n    ProgressCallback progress;\r\n    AddSource(details, progress);\r\n\r\n    std::vector<SourceDetails> sources = GetSources();\r\n    REQUIRE(sources.size() == c_DefaultSourceCount + 1);\r\n\r\n    RemoveSource(details.Name, progress);\r\n\r\n    REQUIRE(removeCalledOnFactory);\r\n\r\n    sources = GetSources();\r\n    REQUIRE(sources.size() == c_DefaultSourceCount);\r\n}\r\n\r\nTEST_CASE(\"RepoSources_RemoveDefaultSource\", \"[sources]\")\r\n{\r\n    SetSetting(Stream::UserSources, s_EmptySources);\r\n    TestHook_ClearSourceFactoryOverrides();\r\n\r\n    std::vector<SourceDetails> sources = GetSources();\r\n    REQUIRE(sources.size() == c_DefaultSourceCount);\r\n    REQUIRE(sources[0].Origin == SourceOrigin::Default);\r\n\r\n    bool removeCalledOnFactory = false;\r\n    TestSourceFactory factory{ SourcesTestSource::Create };\r\n    factory.OnRemove = [&](const SourceDetails&) { removeCalledOnFactory = true; };\r\n    TestHook_SetSourceFactoryOverride(sources[0].Type, factory);\r\n\r\n    ProgressCallback progress;\r\n\r\n    RemoveSource(sources[0].Name, progress);\r\n\r\n    REQUIRE(removeCalledOnFactory);\r\n\r\n    sources = GetSources();\r\n    REQUIRE(sources.size() == c_DefaultSourceCount - 1);\r\n}\r\n\r\nTEST_CASE(\"RepoSources_UpdateOnOpen\", \"[sources]\")\r\n{\r\n    using namespace std::chrono_literals;\r\n\r\n    TestHook_ClearSourceFactoryOverrides();\r\n\r\n    std::string name = \"testName\";\r\n    std::string type = \"testType\";\r\n    std::string arg = \"testArg\";\r\n    std::string data = \"testData\";\r\n\r\n    bool updateCalledOnFactory = false;\r\n    TestSourceFactory factory{ SourcesTestSource::Create };\r\n    factory.OnUpdate = [&](const SourceDetails&) { updateCalledOnFactory = true; };\r\n    factory.ShouldUpdateBeforeOpenResult = true;\r\n    TestHook_SetSourceFactoryOverride(type, factory);\r\n\r\n    SetSetting(Stream::UserSources, s_SingleSource);\r\n\r\n    ProgressCallback progress;\r\n    auto source = OpenSource(name, progress);\r\n\r\n    REQUIRE(updateCalledOnFactory);\r\n\r\n    std::vector<SourceDetails> sources = GetSources();\r\n    REQUIRE(sources.size() == c_DefaultSourceCount + 1);\r\n\r\n    REQUIRE(sources[0].Name == name);\r\n    REQUIRE(sources[0].Type == type);\r\n    REQUIRE(sources[0].Arg == arg);\r\n    REQUIRE(sources[0].Data == data);\r\n    REQUIRE(sources[0].LastUpdateTime != ConvertUnixEpochToSystemClock(0));\r\n}\r\n\r\nTEST_CASE(\"RepoSources_DropSourceByName\", \"[sources]\")\r\n{\r\n    SetSetting(Stream::UserSources, s_ThreeSources);\r\n    SetSetting(Stream::SourcesMetadata, s_ThreeSourcesMetadata);\r\n\r\n    std::vector<SourceDetails> sources = GetSources();\r\n    REQUIRE(sources.size() == 3);\r\n\r\n    DropSource(\"testName\");\r\n\r\n    sources = GetSources();\r\n    REQUIRE(sources.size() == 2);\r\n\r\n    const char* suffix[2] = { \"2\", \"3\" };\r\n\r\n    for (size_t i = 0; i < 2; ++i)\r\n    {\r\n        INFO(\"Source #\" << i);\r\n        REQUIRE(sources[i].Name == \"testName\"s + suffix[i]);\r\n        REQUIRE(sources[i].Type == \"testType\"s + suffix[i]);\r\n        REQUIRE(sources[i].Arg == \"testArg\"s + suffix[i]);\r\n        REQUIRE(sources[i].Data == \"testData\"s + suffix[i]);\r\n        REQUIRE(sources[i].LastUpdateTime == ConvertUnixEpochToSystemClock(i + 1));\r\n        REQUIRE(sources[i].Origin == SourceOrigin::User);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"RepoSources_DropAllSources\", \"[sources]\")\r\n{\r\n    SetSetting(Stream::UserSources, s_ThreeSources);\r\n\r\n    std::vector<SourceDetails> sources = GetSources();\r\n    REQUIRE(sources.size() == 3);\r\n\r\n    DropSource({});\r\n\r\n    sources = GetSources();\r\n    REQUIRE(sources.size() == c_DefaultSourceCount);\r\n    REQUIRE(sources[0].Origin == SourceOrigin::Default);\r\n}\r\n\r\nTEST_CASE(\"RepoSources_SearchAcrossMultipleSources\", \"[sources]\")\r\n{\r\n    TestHook_ClearSourceFactoryOverrides();\r\n    TestSourceFactory factory{ SourcesTestSource::Create };\r\n    TestHook_SetSourceFactoryOverride(\"testType\", factory);\r\n\r\n    SetSetting(Stream::UserSources, s_TwoSource_AggregateSourceTest);\r\n\r\n    ProgressCallback progress;\r\n    auto source = OpenSource(\"\", progress);\r\n\r\n    SearchRequest request;\r\n    auto result = source.Search(request);\r\n    REQUIRE(result.Matches.size() == 6);\r\n    REQUIRE_FALSE(result.Truncated);\r\n    // matches are sorted in expected order\r\n    REQUIRE((result.Matches[0].MatchCriteria.Type == MatchType::Exact && result.Matches[0].MatchCriteria.Field == PackageMatchField::Id));\r\n    REQUIRE((result.Matches[1].MatchCriteria.Type == MatchType::Exact && result.Matches[1].MatchCriteria.Field == PackageMatchField::Id));\r\n    REQUIRE((result.Matches[2].MatchCriteria.Type == MatchType::Exact && result.Matches[2].MatchCriteria.Field == PackageMatchField::Name));\r\n    REQUIRE((result.Matches[3].MatchCriteria.Type == MatchType::Exact && result.Matches[3].MatchCriteria.Field == PackageMatchField::Name));\r\n    REQUIRE((result.Matches[4].MatchCriteria.Type == MatchType::CaseInsensitive && result.Matches[4].MatchCriteria.Field == PackageMatchField::Id));\r\n    REQUIRE((result.Matches[5].MatchCriteria.Type == MatchType::CaseInsensitive && result.Matches[5].MatchCriteria.Field == PackageMatchField::Id));\r\n\r\n    // when truncate required\r\n    request.MaximumResults = 3;\r\n    result = source.Search(request);\r\n    REQUIRE(result.Matches.size() == 3);\r\n    REQUIRE(result.Truncated);\r\n    // matches are sorted in expected order\r\n    REQUIRE((result.Matches[0].MatchCriteria.Type == MatchType::Exact && result.Matches[0].MatchCriteria.Field == PackageMatchField::Id));\r\n    REQUIRE((result.Matches[1].MatchCriteria.Type == MatchType::Exact && result.Matches[1].MatchCriteria.Field == PackageMatchField::Id));\r\n    REQUIRE((result.Matches[2].MatchCriteria.Type == MatchType::Exact && result.Matches[2].MatchCriteria.Field == PackageMatchField::Name));\r\n}\r\n\r\nTEST_CASE(\"RepoSources_GroupPolicy_DefaultSource\", \"[sources][groupPolicy]\")\r\n{\r\n    WHEN(\"Default source is disabled\")\r\n    {\r\n        GroupPolicyTestOverride policies;\r\n        policies.SetState(TogglePolicy::Policy::DefaultSource, PolicyState::Disabled);\r\n\r\n        SECTION(\"Get source\")\r\n        {\r\n            // Listing the sources should not return the default.\r\n            SetSetting(Stream::UserSources, s_EmptySources);\r\n\r\n            auto sources = GetSources();\r\n            REQUIRE(sources.size() == c_DefaultSourceCount - 1);\r\n        }\r\n        SECTION(\"Add default source\")\r\n        {\r\n            // We should not be able to add the default source manually.\r\n            SetSetting(Stream::UserSources, s_EmptySources);\r\n\r\n            ProgressCallback progress;\r\n            SourceDetails details;\r\n            details.Name = \"winget\";\r\n            details.Type = \"Microsoft.PreIndexed.Package\";\r\n            details.Arg = \"https://cdn.winget.microsoft.com/cache\";\r\n            REQUIRE_POLICY_EXCEPTION(\r\n                AddSource(details, progress),\r\n                TogglePolicy::Policy::DefaultSource);\r\n        }\r\n        SECTION(\"Ignore default source from user\")\r\n        {\r\n            // We should ignore any existing user source that is the same as the default.\r\n            SetSetting(Stream::UserSources, s_DefaultSourceAsUserSource);\r\n\r\n            auto sources = GetSources();\r\n            REQUIRE(sources.size() == c_DefaultSourceCount - 1);\r\n        }\r\n        SECTION(\"Add same-name source from user\")\r\n        {\r\n            // We should allow adding sources with the same name as the default but\r\n            // pointing somewhere else.\r\n            SetSetting(Stream::UserSources, s_EmptySources);\r\n            TestHook_ClearSourceFactoryOverrides();\r\n\r\n            SourceDetails details;\r\n            details.Name = \"winget\";\r\n            details.Type = \"someType\";\r\n            details.Arg = \"notWingetRealArg\";\r\n            details.Data = \"someData\";\r\n\r\n            bool addCalledOnFactory = false;\r\n            TestSourceFactory factory{ SourcesTestSource::Create };\r\n            factory.OnAdd = [&](SourceDetails& sd) { addCalledOnFactory = true; sd.Data = details.Data; };\r\n            TestHook_SetSourceFactoryOverride(details.Type, factory);\r\n\r\n            ProgressCallback progress;\r\n            AddSource(details, progress);\r\n\r\n            REQUIRE(addCalledOnFactory);\r\n\r\n            auto sources = GetSources();\r\n            REQUIRE(sources.size() == c_DefaultSourceCount);\r\n\r\n            REQUIRE(sources[0].Name == details.Name);\r\n            REQUIRE(sources[0].Type == details.Type);\r\n            REQUIRE(sources[0].Arg == details.Arg);\r\n            REQUIRE(sources[0].Data == details.Data);\r\n            REQUIRE(sources[0].Origin == SourceOrigin::User);\r\n        }\r\n        SECTION(\"Allow same name source from user\")\r\n        {\r\n            // We should respect existing user sources with the same name.\r\n            // We should allow adding sources with the same name as the default but\r\n            // pointing somewhere else.\r\n            SetSetting(Stream::UserSources, s_UserSourceNamedLikeDefault);\r\n\r\n            auto sources = GetSources();\r\n            REQUIRE(sources.size() == c_DefaultSourceCount);\r\n\r\n            REQUIRE(sources[0].Name == \"winget\");\r\n            REQUIRE(sources[0].Type == \"testType\");\r\n            REQUIRE(sources[0].Arg == \"testArg\");\r\n            REQUIRE(sources[0].Data == \"testData\");\r\n            REQUIRE(sources[0].Origin == SourceOrigin::User);\r\n        }\r\n    }\r\n\r\n    WHEN(\"Default source is enabled\")\r\n    {\r\n        GroupPolicyTestOverride policies;\r\n        policies.SetState(TogglePolicy::Policy::DefaultSource, PolicyState::Enabled);\r\n\r\n        SECTION(\"Remove source is blocked\")\r\n        {\r\n            // We should not be able to remove the default source.\r\n            SetSetting(Stream::UserSources, s_EmptySources);\r\n\r\n            ProgressCallback progress;\r\n            REQUIRE_POLICY_EXCEPTION(\r\n                RemoveSource(\"winget\", progress),\r\n                TogglePolicy::Policy::DefaultSource);\r\n        }\r\n        SECTION(\"Tombstone is overridden\")\r\n        {\r\n            // We should ignore if the default source was already deleted.\r\n            SetSetting(Stream::UserSources, s_DefaultSourcesTombstoned);\r\n\r\n            auto sources = GetSources();\r\n            REQUIRE(sources.size() == 1);\r\n            REQUIRE(sources[0].Name == \"winget\");\r\n            REQUIRE(sources[0].Origin == SourceOrigin::Default);\r\n        }\r\n        SECTION(\"Same name source is overridden\")\r\n        {\r\n            // We should ignore existing user sources with the same name as the default.\r\n            SetSetting(Stream::UserSources, s_UserSourceNamedLikeDefault);\r\n\r\n            auto sources = GetSources();\r\n            REQUIRE(sources.size() == c_DefaultSourceCount);\r\n\r\n            REQUIRE(sources[1].Name == \"winget\");\r\n            REQUIRE(sources[1].Arg == \"https://cdn.winget.microsoft.com/cache\");\r\n            REQUIRE(sources[1].Origin == SourceOrigin::Default);\r\n        }\r\n    }\r\n}\r\n\r\nTEST_CASE(\"RepoSources_GroupPolicy_AdditionalSources\", \"[sources][groupPolicy]\")\r\n{\r\n    WHEN(\"Additional sources are enabled\")\r\n    {\r\n        GroupPolicyTestOverride policies;\r\n        policies.SetState(TogglePolicy::Policy::AdditionalSources, PolicyState::Enabled);\r\n\r\n        SECTION(\"Additional sources are listed\")\r\n        {\r\n            // Getting the current sources should list the additional sources.\r\n            std::vector<SourceFromPolicy> policySources;\r\n            const std::string suffix[3] = { \"\", \"2\", \"3\" };\r\n            for (size_t i = 0; i < 3; ++i)\r\n            {\r\n                SourceFromPolicy source;\r\n                source.Name = \"name\" + suffix[i];\r\n                source.Type = \"type\" + suffix[i];\r\n                source.Arg = \"arg\" + suffix[i];\r\n                source.Data = \"data\" + suffix[i];\r\n                source.Identifier = \"id\" + suffix[i];\r\n                policySources.emplace_back(std::move(source));\r\n            }\r\n\r\n            policies.SetValue<ValuePolicy::AdditionalSources>(policySources);\r\n            SetSetting(Stream::UserSources, s_EmptySources);\r\n\r\n            auto sources = GetSources();\r\n\r\n            // The source list includes the default source\r\n            REQUIRE(sources.size() == policySources.size() + c_DefaultSourceCount);\r\n            REQUIRE(sources.back().Origin == SourceOrigin::Default);\r\n\r\n            for (size_t i = 0; i < policySources.size(); ++i)\r\n            {\r\n                REQUIRE(sources[i].Name == policySources[i].Name);\r\n                REQUIRE(sources[i].Type == policySources[i].Type);\r\n                REQUIRE(sources[i].Arg == policySources[i].Arg);\r\n                REQUIRE(sources[i].Data == policySources[i].Data);\r\n                REQUIRE(sources[i].Identifier == policySources[i].Identifier);\r\n                REQUIRE(sources[i].Origin == SourceOrigin::GroupPolicy);\r\n            }\r\n        }\r\n        SECTION(\"Same-name user source is overridden\")\r\n        {\r\n            // User sources with the same name as an additional source are ignored.\r\n            SourceFromPolicy policySource;\r\n            policySource.Name = \"testName\";\r\n            policySource.Type = \"notTestType\";\r\n            policySource.Arg = \"notTestArg\";\r\n            policySource.Data = \"notTestData\";\r\n            policySource.Identifier = \"notTestId\";\r\n\r\n            policies.SetValue<ValuePolicy::AdditionalSources>({ policySource });\r\n            SetSetting(Stream::UserSources, s_SingleSource);\r\n\r\n            auto sources = GetSources();\r\n\r\n            // The source list includes the default source\r\n            REQUIRE(sources.size() == c_DefaultSourceCount + 1);\r\n            REQUIRE(sources[1].Origin == SourceOrigin::Default);\r\n\r\n            REQUIRE(sources[0].Name == policySource.Name);\r\n            REQUIRE(sources[0].Type == policySource.Type);\r\n            REQUIRE(sources[0].Arg == policySource.Arg);\r\n            REQUIRE(sources[0].Data == policySource.Data);\r\n            REQUIRE(sources[0].Identifier == policySource.Identifier);\r\n            REQUIRE(sources[0].Origin == SourceOrigin::GroupPolicy);\r\n        }\r\n        SECTION(\"Cannot remove additional source\")\r\n        {\r\n            // An additional source cannot be removed.\r\n            SourceFromPolicy policySource;\r\n            policySource.Name = \"name\";\r\n            policySource.Type = \"type\";\r\n            policySource.Arg = \"arg\";\r\n            policySource.Data = \"data\";\r\n            policySource.Identifier = \"id\";\r\n\r\n            bool removeCalledOnFactory = false;\r\n            TestSourceFactory factory{ SourcesTestSource::Create };\r\n            factory.OnRemove = [&](const SourceDetails&) { removeCalledOnFactory = true; };\r\n            TestHook_SetSourceFactoryOverride(policySource.Type, factory);\r\n\r\n            policies.SetValue<ValuePolicy::AdditionalSources>({ policySource });\r\n            SetSetting(Stream::UserSources, s_EmptySources);\r\n\r\n            ProgressCallback progress;\r\n            REQUIRE_POLICY_EXCEPTION(\r\n                RemoveSource(policySource.Name, progress),\r\n                TogglePolicy::Policy::AdditionalSources);\r\n            REQUIRE_FALSE(removeCalledOnFactory);\r\n        }\r\n        SECTION(\"Additional source overrides default\")\r\n        {\r\n            // An additional source with the same name as a default overrides it.\r\n            SourceFromPolicy policySource;\r\n            policySource.Name = \"winget\";\r\n            policySource.Type = \"notDefaultType\";\r\n            policySource.Arg = \"notDefaultArg\";\r\n            policySource.Data = \"notDefaultData\";\r\n            policySource.Identifier = \"notDefaultId\";\r\n\r\n            policies.SetValue<ValuePolicy::AdditionalSources>({ policySource });\r\n            SetSetting(Stream::UserSources, s_EmptySources);\r\n\r\n            auto sources = GetSources();\r\n\r\n            REQUIRE(sources.size() == c_DefaultSourceCount);\r\n            REQUIRE(sources[0].Name == policySource.Name);\r\n            REQUIRE(sources[0].Type == policySource.Type);\r\n            REQUIRE(sources[0].Arg == policySource.Arg);\r\n            REQUIRE(sources[0].Data == policySource.Data);\r\n            REQUIRE(sources[0].Identifier == policySource.Identifier);\r\n            REQUIRE(sources[0].Origin == SourceOrigin::GroupPolicy);\r\n        }\r\n    }\r\n}\r\n\r\nTEST_CASE(\"RepoSources_GroupPolicy_AllowedSources\", \"[sources][groupPolicy]\")\r\n{\r\n    WHEN(\"Allowed sources are enabled\")\r\n    {\r\n        GroupPolicyTestOverride policies;\r\n        policies.SetState(TogglePolicy::Policy::AllowedSources, PolicyState::Enabled);\r\n\r\n        SECTION(\"Add allowed source\")\r\n        {\r\n            // We should be able to add sources in the allow list.\r\n            SourceFromPolicy policySource;\r\n            policySource.Name = \"testName\";\r\n            policySource.Type = \"testType\";\r\n            policySource.Arg = \"testArg\";\r\n            policySource.Data = \"testData\";\r\n            policySource.Identifier = \"testId\";\r\n\r\n            policies.SetValue<ValuePolicy::AllowedSources>({ policySource });\r\n            SetSetting(Stream::UserSources, s_EmptySources);\r\n            TestHook_ClearSourceFactoryOverrides();\r\n\r\n            bool addCalledOnFactory = false;\r\n            TestSourceFactory factory{ SourcesTestSource::Create };\r\n            factory.OnAdd = [&](SourceDetails& sd)\r\n            {\r\n                addCalledOnFactory = true;\r\n                sd.Data = policySource.Data;\r\n                sd.Identifier = policySource.Identifier;\r\n            };\r\n            TestHook_SetSourceFactoryOverride(policySource.Type, factory);\r\n\r\n            ProgressCallback progress;\r\n            SourceDetails details;\r\n            details.Name = policySource.Name;\r\n            details.Type = policySource.Type;\r\n            details.Arg = policySource.Arg;\r\n            AddSource(details, progress);\r\n\r\n            REQUIRE(addCalledOnFactory);\r\n\r\n            // The source list includes the default source\r\n            auto sources = GetSources();\r\n            REQUIRE(sources.size() == c_DefaultSourceCount + 1);\r\n            REQUIRE(sources[1].Origin == SourceOrigin::Default);\r\n\r\n            REQUIRE(sources[0].Name == policySource.Name);\r\n            REQUIRE(sources[0].Type == policySource.Type);\r\n            REQUIRE(sources[0].Arg == policySource.Arg);\r\n            REQUIRE(sources[0].Data == policySource.Data);\r\n            REQUIRE(sources[0].Identifier == policySource.Identifier);\r\n            REQUIRE(sources[0].Origin == SourceOrigin::User);\r\n        }\r\n        SECTION(\"Cannot add non-allowed source\")\r\n        {\r\n            // We should not be allowed to add anything not matching the allow list.\r\n            SourceFromPolicy policySource;\r\n            policySource.Name = \"testName\";\r\n            policySource.Type = \"testType\";\r\n            policySource.Arg = \"testArg\";\r\n            policySource.Data = \"testData\";\r\n            policySource.Identifier = \"testId\";\r\n\r\n            policies.SetValue<ValuePolicy::AllowedSources>({ policySource });\r\n            SetSetting(Stream::UserSources, s_EmptySources);\r\n\r\n            ProgressCallback progress;\r\n            SourceDetails details;\r\n            details.Name = \"notAllowed\";\r\n            details.Type = \"type\";\r\n            details.Arg = \"arg\";\r\n\r\n            bool addCalledOnFactory = false;\r\n            TestSourceFactory factory{ SourcesTestSource::Create };\r\n            factory.OnAdd = [&](SourceDetails&) { addCalledOnFactory = true; };\r\n            TestHook_SetSourceFactoryOverride(details.Type, factory);\r\n\r\n            REQUIRE_POLICY_EXCEPTION(\r\n                AddSource(details, progress),\r\n                TogglePolicy::Policy::AllowedSources);\r\n            REQUIRE_FALSE(addCalledOnFactory);\r\n        }\r\n    }\r\n\r\n    WHEN(\"Allowed sources are disabled\")\r\n    {\r\n        GroupPolicyTestOverride policies;\r\n        policies.SetState(TogglePolicy::Policy::AllowedSources, PolicyState::Disabled);\r\n\r\n        SECTION(\"Cannot add any source\")\r\n        {\r\n            SetSetting(Stream::UserSources, s_EmptySources);\r\n\r\n            ProgressCallback progress;\r\n            SourceDetails details;\r\n            details.Name = \"name\";\r\n            details.Type = \"type\";\r\n            details.Arg = \"arg\";\r\n\r\n            bool addCalledOnFactory = false;\r\n            TestSourceFactory factory{ SourcesTestSource::Create };\r\n            factory.OnAdd = [&](SourceDetails&) { addCalledOnFactory = true; };\r\n            TestHook_SetSourceFactoryOverride(details.Type, factory);\r\n\r\n            REQUIRE_POLICY_EXCEPTION(\r\n                AddSource(details, progress),\r\n                TogglePolicy::Policy::AllowedSources);\r\n            REQUIRE_FALSE(addCalledOnFactory);\r\n\r\n            auto sources = GetSources();\r\n            REQUIRE(sources.size() == c_DefaultSourceCount);\r\n            REQUIRE(sources[0].Origin == SourceOrigin::Default);\r\n        }\r\n        SECTION(\"Existing sources are ignored\")\r\n        {\r\n            SetSetting(Stream::UserSources, s_SingleSource);\r\n\r\n            auto sources = GetSources();\r\n            REQUIRE(sources.size() == c_DefaultSourceCount);\r\n            REQUIRE(sources[0].Origin == SourceOrigin::Default);\r\n        }\r\n    }\r\n}\r\n\r\nTEST_CASE(\"RepoSources_OpenMultipleWithSingleFailure\", \"[sources]\")\r\n{\r\n    TestHook_ClearSourceFactoryOverrides();\r\n    TestSourceFactory factory{ FailingSourcesTestSource::CreateFailWinget };\r\n    TestHook_SetSourceFactoryOverride(\"testType\", factory);\r\n\r\n    SetSetting(Stream::UserSources, s_TwoSource_AggregateSourceTest);\r\n\r\n    ProgressCallback progress;\r\n    auto result = OpenSource(\"\", progress);\r\n\r\n    REQUIRE(result);\r\n\r\n    SearchResult searchResult = result.Search({});\r\n\r\n    REQUIRE(searchResult.Failures.size() == 1);\r\n\r\n    HRESULT openFailure = S_OK;\r\n    try\r\n    {\r\n        std::rethrow_exception(searchResult.Failures[0].Exception);\r\n    }\r\n    catch (const wil::ResultException& re)\r\n    {\r\n        openFailure = re.GetErrorCode();\r\n    }\r\n    catch (...) {}\r\n\r\n    REQUIRE(openFailure == FailingSourcesTestSource::FailingHR);\r\n}\r\n\r\nTEST_CASE(\"RepoSources_OpenMultipleWithTotalFailure\", \"[sources]\")\r\n{\r\n    TestHook_ClearSourceFactoryOverrides();\r\n    TestSourceFactory factory{ FailingSourcesTestSource::CreateFailAll };\r\n    TestHook_SetSourceFactoryOverride(\"testType\", factory);\r\n\r\n    SetSetting(Stream::UserSources, s_TwoSource_AggregateSourceTest);\r\n\r\n    ProgressCallback progress;\r\n    REQUIRE_THROWS_HR(OpenSource(\"\", progress), APPINSTALLER_CLI_ERROR_FAILED_TO_OPEN_ALL_SOURCES);\r\n}\r\n\r\nTEST_CASE(\"RepoSources_UpdateSettingsDuringAction_SourcesUpdate\", \"[sources]\")\r\n{\r\n    SetSetting(Stream::UserSources, s_SingleSource);\r\n    SetSetting(Stream::SourcesMetadata, s_SingleSourceMetadata);\r\n\r\n    std::string userSourcesUpdate{ s_DoubleSource };\r\n    std::string sourcesMetadataUpdate{ s_DoubleSourceMetadata };\r\n\r\n    std::string singleSourceName = \"testName\";\r\n    std::string doubleSourceName = \"testName2\";\r\n\r\n    std::string unusedSourceName = \"unusedName\";\r\n    std::string unusedSourceArg = \"unusedArg\";\r\n    std::string testSourceType = \"testType\";\r\n\r\n    TestHook_ClearSourceFactoryOverrides();\r\n    TestSourceFactory factory{ FailingSourcesTestSource::CreateFailAll };\r\n    auto settingsUpdate = [&](const AppInstaller::Repository::SourceDetails&) \r\n    {\r\n        SetSetting(Stream::UserSources, userSourcesUpdate);\r\n        SetSetting(Stream::SourcesMetadata, sourcesMetadataUpdate);\r\n    };\r\n    factory.OnAdd = settingsUpdate;\r\n    factory.OnUpdate = settingsUpdate;\r\n    factory.OnRemove = settingsUpdate;\r\n    TestHook_SetSourceFactoryOverride(testSourceType, factory);\r\n\r\n    ProgressCallback progress;\r\n\r\n    SECTION(\"Add\")\r\n    {\r\n        SourceDetails addedSource;\r\n        addedSource.Name = unusedSourceName;\r\n        addedSource.Type = testSourceType;\r\n        addedSource.Arg = unusedSourceArg;\r\n        AddSource(addedSource, progress);\r\n\r\n        auto sources = GetSources();\r\n        REQUIRE(sources.size() == 3 + c_DefaultSourceCount);\r\n\r\n        REQUIRE(sources[0].Name == singleSourceName);\r\n        REQUIRE(sources[1].Name == doubleSourceName);\r\n        REQUIRE(sources[2].Name == addedSource.Name);\r\n    }\r\n    SECTION(\"Add conflicting\")\r\n    {\r\n        SourceDetails addedSource;\r\n        addedSource.Name = doubleSourceName;\r\n        addedSource.Type = testSourceType;\r\n        addedSource.Arg = unusedSourceArg;\r\n        REQUIRE_THROWS_HR(AddSource(addedSource, progress), APPINSTALLER_CLI_ERROR_SOURCE_NAME_ALREADY_EXISTS);\r\n    }\r\n    SECTION(\"Update\")\r\n    {\r\n        UpdateSource(singleSourceName, progress);\r\n\r\n        auto sources = GetSources();\r\n        REQUIRE(sources.size() == 2 + c_DefaultSourceCount);\r\n\r\n        REQUIRE(sources[0].Name == singleSourceName);\r\n        REQUIRE(sources[1].Name == doubleSourceName);\r\n    }\r\n    SECTION(\"Remove\")\r\n    {\r\n        RemoveSource(singleSourceName, progress);\r\n\r\n        auto sources = GetSources();\r\n        REQUIRE(sources.size() == 1 + c_DefaultSourceCount);\r\n\r\n        REQUIRE(sources[0].Name == doubleSourceName);\r\n    }\r\n    SECTION(\"Remove already removed\")\r\n    {\r\n        userSourcesUpdate = s_EmptySources;\r\n        sourcesMetadataUpdate = s_EmptySources;\r\n\r\n        RemoveSource(singleSourceName, progress);\r\n\r\n        auto sources = GetSources();\r\n        REQUIRE(sources.size() == c_DefaultSourceCount);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"RepoSources_UpdateSettingsDuringAction_MetadataUpdate\", \"[sources]\")\r\n{\r\n    SetSetting(Stream::UserSources, s_SingleSource);\r\n    SetSetting(Stream::SourcesMetadata, s_SingleSourceMetadata);\r\n\r\n    std::string sourcesMetadataUpdate{ s_SingleSourceMetadataUpdate };\r\n    int64_t updateTime = 101;\r\n\r\n    std::string singleSourceName = \"testName\";\r\n    std::string doubleSourceName = \"testName2\";\r\n\r\n    std::string unusedSourceName = \"unusedName\";\r\n    std::string unusedSourceArg = \"unusedArg\";\r\n    std::string testSourceType = \"testType\";\r\n\r\n    TestHook_ClearSourceFactoryOverrides();\r\n    TestSourceFactory factory{ FailingSourcesTestSource::CreateFailAll };\r\n    auto settingsUpdate = [&](const AppInstaller::Repository::SourceDetails&)\r\n    {\r\n        SetSetting(Stream::SourcesMetadata, sourcesMetadataUpdate);\r\n    };\r\n    factory.OnAdd = settingsUpdate;\r\n    factory.OnUpdate = settingsUpdate;\r\n    factory.OnRemove = settingsUpdate;\r\n    TestHook_SetSourceFactoryOverride(testSourceType, factory);\r\n\r\n    ProgressCallback progress;\r\n\r\n    SECTION(\"Add\")\r\n    {\r\n        SourceDetails addedSource;\r\n        addedSource.Name = unusedSourceName;\r\n        addedSource.Type = testSourceType;\r\n        addedSource.Arg = unusedSourceArg;\r\n        AddSource(addedSource, progress);\r\n\r\n        auto sources = GetSources();\r\n        REQUIRE(sources.size() == 2 + c_DefaultSourceCount);\r\n\r\n        REQUIRE(sources[0].Name == singleSourceName);\r\n        REQUIRE(ConvertSystemClockToUnixEpoch(sources[0].LastUpdateTime) == updateTime);\r\n        REQUIRE(sources[1].Name == addedSource.Name);\r\n    }\r\n    SECTION(\"Update\")\r\n    {\r\n        UpdateSource(singleSourceName, progress);\r\n\r\n        auto sources = GetSources();\r\n        REQUIRE(sources.size() == 1 + c_DefaultSourceCount);\r\n\r\n        REQUIRE(sources[0].Name == singleSourceName);\r\n        REQUIRE(ConvertSystemClockToUnixEpoch(sources[0].LastUpdateTime) > updateTime);\r\n    }\r\n    SECTION(\"Remove\")\r\n    {\r\n        RemoveSource(singleSourceName, progress);\r\n\r\n        auto sources = GetSources();\r\n        REQUIRE(sources.size() == c_DefaultSourceCount);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"RepoSources_RestoringWellKnownSource\", \"[sources]\")\r\n{\r\n    TestHook_ClearSourceFactoryOverrides();\r\n    RemoveSetting(Stream::UserSources);\r\n\r\n    Source storeSource{ WellKnownSource::MicrosoftStore };\r\n    SourceDetails details = storeSource.GetDetails();\r\n    REQUIRE(!details.CertificatePinningConfiguration.IsEmpty());\r\n\r\n    TestSourceFactory factory{ SourcesTestSource::Create };\r\n    TestHook_SetSourceFactoryOverride(details.Type, factory);\r\n\r\n    ProgressCallback progress;\r\n\r\n    REQUIRE(storeSource.Remove(progress));\r\n\r\n    Source storeAfterRemove{ details.Name };\r\n    REQUIRE(!storeAfterRemove);\r\n\r\n    SECTION(\"with well known name\")\r\n    {\r\n        Source addStoreBack{ details.Name, details.Arg, details.Type, Repository::SourceTrustLevel::None, {} };\r\n        REQUIRE(addStoreBack.Add(progress));\r\n\r\n        Source storeAfterAdd{ details.Name };\r\n        REQUIRE(storeAfterAdd);\r\n        REQUIRE(!storeAfterAdd.GetDetails().CertificatePinningConfiguration.IsEmpty());\r\n    }\r\n\r\n    SECTION(\"with different name\")\r\n    {\r\n        std::string newName = details.Name + \"_new\";\r\n        Source addStoreBack{ newName, details.Arg, details.Type, Repository::SourceTrustLevel::None, {} };\r\n        REQUIRE(addStoreBack.Add(progress));\r\n\r\n        Source storeAfterAdd{ newName };\r\n        REQUIRE(storeAfterAdd);\r\n        REQUIRE(storeAfterAdd.GetDetails().CertificatePinningConfiguration.IsEmpty());\r\n    }\r\n}\r\n\r\nTEST_CASE(\"RepoSources_GroupPolicy_BypassCertificatePinningForMicrosoftStore\", \"[sources][groupPolicy]\")\r\n{\r\n    TestHook_ClearSourceFactoryOverrides();\r\n\r\n    SECTION(\"Not configured\")\r\n    {\r\n        GroupPolicyTestOverride policies;\r\n        policies.SetState(TogglePolicy::Policy::BypassCertificatePinningForMicrosoftStore, PolicyState::NotConfigured);\r\n        Source source(WellKnownSource::MicrosoftStore);\r\n        REQUIRE_FALSE(source.GetDetails().CertificatePinningConfiguration.IsEmpty());\r\n    }\r\n\r\n    SECTION(\"Enabled\")\r\n    {\r\n        GroupPolicyTestOverride policies;\r\n        policies.SetState(TogglePolicy::Policy::BypassCertificatePinningForMicrosoftStore, PolicyState::Enabled);\r\n        Source source(WellKnownSource::MicrosoftStore);\r\n        REQUIRE(source.GetDetails().CertificatePinningConfiguration.IsEmpty());\r\n    }\r\n\r\n    SECTION(\"Disabled\")\r\n    {\r\n        GroupPolicyTestOverride policies;\r\n        policies.SetState(TogglePolicy::Policy::BypassCertificatePinningForMicrosoftStore, PolicyState::Disabled);\r\n        Source source(WellKnownSource::MicrosoftStore);\r\n        REQUIRE_FALSE(source.GetDetails().CertificatePinningConfiguration.IsEmpty());\r\n    }\r\n}\r\n\r\nTEST_CASE(\"RepoSources_BuiltInDesktopFrameworkSourceAlwaysCreatable\", \"[sources]\")\r\n{\r\n    Source source(WellKnownSource::DesktopFrameworks);\r\n    REQUIRE(source);\r\n}\r\n\r\nTEST_CASE(\"RepoSources_MicrosoftStore_CertificatePinningLifetimeCheck\", \"[sources]\")\r\n{\r\n    TestHook_ClearSourceFactoryOverrides();\r\n\r\n    GroupPolicyTestOverride policies;\r\n    policies.SetState(TogglePolicy::Policy::BypassCertificatePinningForMicrosoftStore, PolicyState::Disabled);\r\n    Source source(WellKnownSource::MicrosoftStore);\r\n    REQUIRE_FALSE(source.GetDetails().CertificatePinningConfiguration.IsEmpty());\r\n\r\n    // The configuration's remaining lifetime is the *maximum* of the remaining lifetimes of the individual chains.\r\n    // A chain's remaining lifetime is the *minimum* of the remaining lifetimes of the individual certificates.\r\n    // A certificate's remaining lifetime is a value between 0.0 and 1.0 that is the ratio of remaining valid time to total valid time.\r\n\r\n    // The goal of this test is to warn when the pinning configuration may be in danger of expiration; either via certificate validity or\r\n    // more likely by renewals causing the pinning to reject the new, correct certificates. It operates in percentage lifetime to normalize\r\n    // the values across the chain.\r\n    INFO(\"If this test has failed, the pinning certificates may be nearing expiration and should be investigated.\");\r\n    double lifetimePercentage = source.GetDetails().CertificatePinningConfiguration.GetRemainingLifetimePercentage();\r\n    REQUIRE(lifetimePercentage > 0.25);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/Strings.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <AppInstallerStrings.h>\r\n#include <AppInstallerSHA256.h>\r\n#include <ExecutionReporter.h>\r\n\r\nusing namespace std::string_literals;\r\nusing namespace std::string_view_literals;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::Utility::literals;\r\n\r\nTEST_CASE(\"UTF8Length\", \"[strings]\")\r\n{\r\n    REQUIRE(UTF8Length(\"\") == 0);\r\n    REQUIRE(UTF8Length(\"a\") == 1);\r\n    REQUIRE(UTF8Length(\" a b c \") == 7);\r\n    REQUIRE(UTF8Length(\"K\\xC3\\xA4se\") == 4); // \"Käse\"\r\n    REQUIRE(UTF8Length(\"bye\\xE2\\x80\\xA6\") == 4); // \"bye…\"\r\n    REQUIRE(UTF8Length(\"\\xf0\\x9f\\xa6\\x86\") == 1); // [duck emoji]\r\n    REQUIRE(UTF8Length(\"\\xf0\\x9d\\x85\\xa0\\xf0\\x9d\\x85\\xa0\") == 2); // [8th note][8th note]\r\n}\r\n\r\nTEST_CASE(\"UTF8Substring\", \"[strings]\")\r\n{    \r\n    REQUIRE(UTF8Substring(\"\", 0, 0) == \"\");\r\n    REQUIRE(UTF8Substring(\"abcd\", 0, 4) == \"abcd\");\r\n    REQUIRE(UTF8Substring(\"abcd\", 0, 5) == \"abcd\");\r\n    REQUIRE(UTF8Substring(\"abcd\", 0, 2) == \"ab\");\r\n    REQUIRE(UTF8Substring(\"abcd\", 1, 0) == \"\");\r\n    REQUIRE(UTF8Substring(\"abcd\", 1, 1) == \"b\");\r\n    REQUIRE(UTF8Substring(\"abcd\", 1, 3) == \"bcd\");\r\n    REQUIRE(UTF8Substring(\"abcd\", 4, 0) == \"\");\r\n\r\n    const char* s = \"\\xf0\\x9f\\xa6\\x86s like \\xf0\\x9f\\x8c\\x8a\"; // [duck emoji]s like [wave emoji]\r\n    REQUIRE(UTF8Substring(s, 0, 9) == \"\\xf0\\x9f\\xa6\\x86s like \\xf0\\x9f\\x8c\\x8a\");\r\n    REQUIRE(UTF8Substring(s, 0, 1) == \"\\xf0\\x9f\\xa6\\x86\");\r\n    REQUIRE(UTF8Substring(s, 0, 2) == \"\\xf0\\x9f\\xa6\\x86s\");\r\n    REQUIRE(UTF8Substring(s, 1, 7) == \"s like \");\r\n    REQUIRE(UTF8Substring(s, 1, 8) == \"s like \\xf0\\x9f\\x8c\\x8a\");\r\n}\r\n\r\nTEST_CASE(\"UTF8ColumnWidth\", \"[strings]\")\r\n{\r\n    REQUIRE(UTF8ColumnWidth(\"\") == 0);\r\n    REQUIRE(UTF8ColumnWidth(\"a\") == 1);\r\n    REQUIRE(UTF8ColumnWidth(\" a b c \") == 7);\r\n    REQUIRE(UTF8ColumnWidth(\"K\\xC3\\xA4se\") == 4); // \"Käse\"\r\n    REQUIRE(UTF8ColumnWidth(\"bye\\xE2\\x80\\xA6\") == 4); // \"bye…\"\r\n    REQUIRE(UTF8ColumnWidth(\"fi\\xEF\\xAC\\x81\") == 3); // \"fi[fi]\" [fi] is not decoupled\r\n    REQUIRE(UTF8ColumnWidth(\"\\xf0\\x9f\\xa6\\x86\") == 2); // [duck emoji]\r\n    REQUIRE(UTF8ColumnWidth(\"\\xf0\\x9d\\x85\\xa0\\xf0\\x9d\\x85\\xa0\") == 2); // [8th note][8th note]\r\n    REQUIRE(UTF8ColumnWidth(\"\\xe6\\xb5\\x8b\\xe8\\xaf\\x95\") == 4); // 测试\r\n    REQUIRE(UTF8ColumnWidth(\"te\\xe6\\xb5\\x8bs\\xe8\\xaf\\x95t\") == 8); // te测s试t\r\n}\r\n\r\nTEST_CASE(\"UTF8TrimRightToColumnWidth\", \"[strings]\")\r\n{\r\n    size_t actualWidth;\r\n    REQUIRE((UTF8TrimRightToColumnWidth(\"\", 0, actualWidth) == \"\" && actualWidth == 0));\r\n    REQUIRE((UTF8TrimRightToColumnWidth(\"abcd\", 4, actualWidth) == \"abcd\" && actualWidth == 4));\r\n    REQUIRE((UTF8TrimRightToColumnWidth(\"abcd\", 5, actualWidth) == \"abcd\" && actualWidth == 4));\r\n    REQUIRE((UTF8TrimRightToColumnWidth(\"abcd\", 2, actualWidth) == \"ab\" && actualWidth == 2));\r\n\r\n    NormalizedString s{ \"te\\xe6\\xb5\\x8bs\\xe8\\xaf\\x95t\" }; // // te测s试t\r\n    REQUIRE((UTF8TrimRightToColumnWidth(s, 0, actualWidth) == \"\" && actualWidth == 0));\r\n    REQUIRE((UTF8TrimRightToColumnWidth(s, 2, actualWidth) == \"te\" && actualWidth == 2));\r\n    REQUIRE((UTF8TrimRightToColumnWidth(s, 3, actualWidth) == \"te\" && actualWidth == 2));\r\n    REQUIRE((UTF8TrimRightToColumnWidth(s, 4, actualWidth) == \"te\\xe6\\xb5\\x8b\" && actualWidth == 4));\r\n    REQUIRE((UTF8TrimRightToColumnWidth(s, 8, actualWidth) == \"te\\xe6\\xb5\\x8bs\\xe8\\xaf\\x95t\" && actualWidth == 8));\r\n    REQUIRE((UTF8TrimRightToColumnWidth(s, 10, actualWidth) == \"te\\xe6\\xb5\\x8bs\\xe8\\xaf\\x95t\" && actualWidth == 8));\r\n}\r\n\r\nTEST_CASE(\"Normalize\", \"[strings]\")\r\n{\r\n    REQUIRE(Normalize(\"test\") == \"test\");\r\n\r\n    // A + combining Dieresis => single A with umlaut char\r\n    REQUIRE(Normalize(L\"\\x41\\x308\") == L\"\\xC4\");\r\n    // This will stop working in C++20, sigh.\r\n    REQUIRE(Normalize(u8\"\\x41\\x308\") == u8\"\\xC4\");\r\n\r\n    // Ligature fi => f + i\r\n    REQUIRE(Normalize(u8\"\\xFB01\") == u8\"fi\");\r\n}\r\n\r\nTEST_CASE(\"NormalizedString\", \"[strings]\")\r\n{\r\n    REQUIRE(NormalizedString(\"test\") == \"test\");\r\n    std::string input = \"test\";\r\n    REQUIRE(NormalizedString(input) == input);\r\n\r\n    // A + combining Dieresis => single A with umlaut char\r\n    REQUIRE(NormalizedString(std::wstring_view(L\"\\x41\\x308\")) == u8\"\\xC4\");\r\n    // This will stop working in C++20, sigh.\r\n    input = u8\"\\x41\\x308\";\r\n    REQUIRE(NormalizedString(input) == u8\"\\xC4\");\r\n\r\n    // Ligature fi => f + i\r\n    std::string_view input2 = u8\"\\xFB01\";\r\n    REQUIRE(NormalizedString(input2) == u8\"fi\");\r\n\r\n    // Embedded null\r\n    std::string_view input3{ \"Test\\0Case\", 9 };\r\n    REQUIRE(NormalizedString(input3) == \"Test Case\");\r\n}\r\n\r\nTEST_CASE(\"Trim\", \"[strings]\")\r\n{\r\n    std::string str;\r\n    REQUIRE(Trim(str.assign(\"\")) == \"\");\r\n    REQUIRE(Trim(str.assign(\" \")) == \"\");\r\n    REQUIRE(Trim(str.assign(\" \\t \")) == \"\");\r\n    REQUIRE(Trim(str.assign(\" a\")) == \"a\");\r\n    REQUIRE(Trim(str.assign(\"bght \")) == \"bght\");\r\n    REQUIRE(Trim(str.assign(\"\\tStuff\\f\")) == \"Stuff\");\r\n    REQUIRE(Trim(str.assign(\"Multiple words\")) == \"Multiple words\");\r\n    REQUIRE(Trim(str.assign(\"         Multiple words\")) == \"Multiple words\");\r\n    REQUIRE(Trim(str.assign(\"Much after is taken \\f\\n\\r\\t\\v\\v\\t\\r\\n\\f \")) == \"Much after is taken\");\r\n\r\n    REQUIRE(Trim(L\" Test\"sv) == L\"Test\");\r\n    REQUIRE(Trim(L\"   \"sv) == L\"\");\r\n}\r\n\r\nTEST_CASE(\"CaseInsensitiveStartsWith\", \"[strings]\")\r\n{\r\n    REQUIRE(CaseInsensitiveStartsWith(\"startswith\", \"starts\"));\r\n    REQUIRE(CaseInsensitiveStartsWith(\"startswith\", \"STAR\"));\r\n    REQUIRE(CaseInsensitiveStartsWith(\"startswith\", \"startSWITH\"));\r\n    REQUIRE(CaseInsensitiveStartsWith(\"startswith\", \"\"));\r\n\r\n    REQUIRE(!CaseInsensitiveStartsWith(\"starts\", \"startswith\"));\r\n    REQUIRE(!CaseInsensitiveStartsWith(\"\", \"nuffing\"));\r\n    REQUIRE(!CaseInsensitiveStartsWith(\"withstarts\", \"starts\"));\r\n    REQUIRE(!CaseInsensitiveStartsWith(\" starts\", \"starts\"));\r\n}\r\n\r\nTEST_CASE(\"FoldCase\", \"[strings]\")\r\n{\r\n    REQUIRE(FoldCase(\"\"sv) == FoldCase(\"\"sv));\r\n    REQUIRE(FoldCase(\"foldcase\"sv) == FoldCase(\"FOLDCASE\"sv));\r\n    REQUIRE(FoldCase(u8\"f\\xF6ldcase\"sv) == FoldCase(u8\"F\\xD6LDCASE\"sv));\r\n    REQUIRE(FoldCase(u8\"foldc\\x430se\"sv) == FoldCase(u8\"FOLDC\\x410SE\"sv));\r\n}\r\n\r\nTEST_CASE(\"ExpandEnvironmentVariables\", \"[strings]\")\r\n{\r\n    wchar_t buffer[MAX_PATH];\r\n    GetTempPathW(ARRAYSIZE(buffer), buffer);\r\n\r\n    std::wstring tempPath = buffer;\r\n    if (!tempPath.empty() && tempPath.back() == '\\\\')\r\n    {\r\n        tempPath.resize(tempPath.size() - 1);\r\n    }\r\n\r\n    REQUIRE(ExpandEnvironmentVariables(L\"%TEMP%\") == tempPath);\r\n}\r\n\r\nTEST_CASE(\"PathOutput\", \"[strings]\")\r\n{\r\n    std::string original = \"\\xe6\\xb5\\x8b\\xe8\\xaf\\x95\";\r\n    std::filesystem::path path = ConvertToUTF16(original);\r\n    AICLI_LOG(Test, Info, << path);\r\n\r\n    std::istringstream in;\r\n    std::ostringstream out;\r\n    AppInstaller::CLI::Execution::Reporter reporter{ out, in };\r\n\r\n    reporter.Info() << path;\r\n\r\n    std::string output = out.str();\r\n    REQUIRE(output.substr(output.size() - original.size()) == original);\r\n}\r\n\r\nTEST_CASE(\"ReplaceWhileCopying\", \"[strings]\")\r\n{\r\n    REQUIRE(ReplaceWhileCopying(L\"A red apple\", L\"red\", L\"green\") == L\"A green apple\");\r\n    REQUIRE(ReplaceWhileCopying(L\"A red, red apple\", L\"red\", L\"green\") == L\"A green, green apple\");\r\n    REQUIRE(ReplaceWhileCopying(L\"A red, red apple\", L\"ed\", L\"ad\") == L\"A rad, rad apple\");\r\n    REQUIRE(ReplaceWhileCopying(L\"A red apple\", L\"p\", L\"f\") == L\"A red affle\");\r\n    REQUIRE(ReplaceWhileCopying(L\"A red apple\", L\"\", L\"green\") == L\"A red apple\");\r\n}\r\n\r\nTEST_CASE(\"MakeSuitablePathPart\", \"[strings]\")\r\n{\r\n    REQUIRE(MakeSuitablePathPart(\"A\\\\B\") == \"A_B\");\r\n    REQUIRE(MakeSuitablePathPart(\"A\\\\B/\") == \"A_B_\");\r\n    REQUIRE(MakeSuitablePathPart(\"*AB\") == \"_AB\");\r\n    REQUIRE(MakeSuitablePathPart(u8\"f*\\xF6*ldcase\") == u8\"f_\\xF6_ldcase\");\r\n    REQUIRE(MakeSuitablePathPart(\".\") == \"_\");\r\n    REQUIRE(MakeSuitablePathPart(\"..\") == \"._\");\r\n    REQUIRE(MakeSuitablePathPart(std::string(300, ' ')) == SHA256::ConvertToString(SHA256::ComputeHash(std::string(300, ' '))));\r\n    REQUIRE_THROWS_HR(MakeSuitablePathPart(\"COM1\"), E_INVALIDARG);\r\n    REQUIRE_THROWS_HR(MakeSuitablePathPart(\"NUL.txt\"), E_INVALIDARG);\r\n}\r\n\r\nTEST_CASE(\"GetFileNameFromURI\", \"[strings]\")\r\n{\r\n    REQUIRE(GetFileNameFromURI(\"https://github.com/microsoft/winget-cli/pull/1722\").u8string() == \"1722\");\r\n    REQUIRE(GetFileNameFromURI(\"https://github.com/microsoft/winget-cli/README.md\").u8string() == \"README.md\");\r\n    REQUIRE(GetFileNameFromURI(\"https://microsoft.com/\").u8string() == \"\");\r\n}\r\n\r\nvoid ValidateSplitFileName(std::string_view uri, std::string_view base, std::string_view fileName)\r\n{\r\n    auto split = SplitFileNameFromURI(uri);\r\n    REQUIRE(split.first == base);\r\n    REQUIRE(split.second.u8string() == fileName);\r\n}\r\n\r\nTEST_CASE(\"SplitFileNameFromURI\", \"[strings]\")\r\n{\r\n    ValidateSplitFileName(\"https://github.com/microsoft/winget-cli/pull/1722\", \"https://github.com/microsoft/winget-cli/pull/\", \"1722\");\r\n    ValidateSplitFileName(\"https://github.com/microsoft/winget-cli/README.md\", \"https://github.com/microsoft/winget-cli/\", \"README.md\");\r\n    ValidateSplitFileName(\"https://microsoft.com/\", \"https://microsoft.com/\", \"\");\r\n}\r\n\r\nTEST_CASE(\"SplitIntoWords\", \"[strings]\")\r\n{\r\n    REQUIRE(SplitIntoWords(\"A B\") == std::vector<std::string>{ \"A\", \"B\" });\r\n    REQUIRE(SplitIntoWords(\"Some-Thing\") == std::vector<std::string>{ \"Some\", \"Thing\" });\r\n\r\n    // 私のテスト = \"My test\" according to an online translator\r\n    // Split as \"私\" \"の\" \"テスト\"\r\n    REQUIRE(SplitIntoWords(\"\\xe7\\xa7\\x81\\xe3\\x81\\xae\\xe3\\x83\\x86\\xe3\\x82\\xb9\\xe3\\x83\\x88\") == std::vector<std::string>{ \"\\xe7\\xa7\\x81\", \"\\xe3\\x81\\xae\", \"\\xe3\\x83\\x86\\xe3\\x82\\xb9\\xe3\\x83\\x88\" });\r\n}\r\n\r\nTEST_CASE(\"ReplaceEmbeddedNullCharacters\", \"[strings]\")\r\n{\r\n    std::string test = \"Test Parts\";\r\n    test[4] = '\\0';\r\n    ReplaceEmbeddedNullCharacters(test);\r\n    REQUIRE(test == \"Test Parts\");\r\n}\r\n\r\nTEST_CASE(\"HexStrings\", \"[strings]\")\r\n{\r\n    std::vector<uint8_t> buffer{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };\r\n    std::string value = \"000102030405060708090a0b0c0d0e0f\";\r\n\r\n    REQUIRE(value == ConvertToHexString(buffer));\r\n    REQUIRE(std::equal(buffer.begin(), buffer.end(), ParseFromHexString(value).begin()));\r\n}\r\n\r\nTEST_CASE(\"Join\", \"[strings]\")\r\n{\r\n    std::vector<LocIndString> list_0{ };\r\n    std::vector<LocIndString> list_1{ \"A\"_lis };\r\n    std::vector<LocIndString> list_2{ \"A\"_lis, \"B\"_lis };\r\n\r\n    REQUIRE(\"\"_lis == Join(\", \"_liv, list_0));\r\n    REQUIRE(\"A\"_lis == Join(\", \"_liv, list_1));\r\n    REQUIRE(\"A, B\"_lis == Join(\", \"_liv, list_2));\r\n    REQUIRE(\"AB\"_lis == Join(\"\"_liv, list_2));\r\n}\r\n\r\nTEST_CASE(\"Format\", \"[strings]\")\r\n{\r\n    REQUIRE(\"First Second\" == Format(\"{0} {1}\", \"First\", \"Second\"));\r\n    REQUIRE(\"First Second\" == Format(\"{1} {0}\", \"Second\", \"First\"));\r\n    REQUIRE(\"First Second\" == Format(\"{0} {1}\", \"First\", \"Second\", \"(Extra\", \"Input\", \"Ignored)\"));\r\n    REQUIRE(\"First Second First Second\" == Format(\"{0} {1} {0} {1}\", \"First\", \"Second\"));\r\n\r\n    // Note: C++20 std::format will throw an exception for this test case\r\n    REQUIRE(\"First {1}\" == Format(\"{0} {1}\", \"First\"));\r\n}\r\n\r\nTEST_CASE(\"SplitIntoLines\", \"[strings]\")\r\n{\r\n    REQUIRE(SplitIntoLines(\"Boring test\") == std::vector<std::string>{ \"Boring test\" });\r\n    REQUIRE(SplitIntoLines(\r\n        \"I'm Luffy! The Man Who Will Become the Pirate King!\\r-Monkey D. Luffy\") == std::vector<std::string>{ \"I'm Luffy! The Man Who Will Become the Pirate King!\", \"-Monkey D. Luffy\" });\r\n    REQUIRE(SplitIntoLines(\r\n        \"I want live!\\n-Nico Robin\") == std::vector<std::string>{ \"I want live!\", \"-Nico Robin\" });\r\n    REQUIRE(SplitIntoLines(\r\n        \"You want my treasure?\\rYou can have it!\\nI left everything I gathered in one place!\\r\\nYou just have to find it!\")\r\n        == std::vector<std::string>{ \"You want my treasure?\", \"You can have it!\", \"I left everything I gathered in one place!\", \"You just have to find it!\" });\r\n}\r\n\r\nTEST_CASE(\"SplitWithSeparator\", \"[strings]\")\r\n{\r\n    std::vector<std::string> test1 = Split(\"first;second;third\"s, ';');\r\n    REQUIRE(test1.size() == 3);\r\n    REQUIRE(test1[0] == \"first\");\r\n    REQUIRE(test1[1] == \"second\");\r\n    REQUIRE(test1[2] == \"third\");\r\n\r\n    std::vector<std::string> test2 = Split(\"two  spaces\"s, ' ');\r\n    REQUIRE(test2.size() == 3);\r\n    REQUIRE(test2[0] == \"two\");\r\n    REQUIRE(test2[1] == \"\");\r\n    REQUIRE(test2[2] == \"spaces\");\r\n\r\n    std::vector<std::string> test3 = Split(\"test\"s, '.');\r\n    REQUIRE(test3.size() == 1);\r\n    REQUIRE(test3[0] == \"test\");\r\n\r\n    std::vector<std::string> test4 = Split(\" trim |    spaces \"s, '|', true);\r\n    REQUIRE(test4.size() == 2);\r\n    REQUIRE(test4[0] == \"trim\");\r\n    REQUIRE(test4[1] == \"spaces\");\r\n\r\n    std::vector<std::wstring_view> test5 = Split(L\" trim /spaces /  \"sv, '/', true);\r\n    REQUIRE(test5.size() == 3);\r\n    REQUIRE(test5[0] == L\"trim\");\r\n    REQUIRE(test5[1] == L\"spaces\");\r\n    REQUIRE(test5[2] == L\"\");\r\n\r\n    std::vector<std::wstring_view> test6 = Split(L\" \"sv, '/', true);\r\n    REQUIRE(test6.size() == 1);\r\n    REQUIRE(test6[0] == L\"\");\r\n\r\n    std::vector<std::string> test7 = Split(\"\"s, ';');\r\n    REQUIRE(test7.size() == 1);\r\n    REQUIRE(test7[0] == \"\");\r\n}\r\n\r\nTEST_CASE(\"ConvertGuid\", \"[strings]\")\r\n{\r\n    std::string validGuidString = \"{4d1e55b2-f16f-11cf-88cb-001111000030}\";\r\n    GUID guid = { 0x4d1e55b2, 0xf16f, 0x11cf, 0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 };\r\n\r\n    REQUIRE(CaseInsensitiveEquals(ConvertGuidToString(guid), validGuidString));\r\n}\r\n\r\nTEST_CASE(\"FindControlCodeToConvert\", \"[strings]\")\r\n{\r\n    REQUIRE(FindControlCodeToConvert(\"No codes\") == std::string::npos);\r\n    REQUIRE(FindControlCodeToConvert(\"Allowed codes: \\t\\r\\n\") == std::string::npos);\r\n    REQUIRE(FindControlCodeToConvert(\"\\x1bSkipped code\", 1) == std::string::npos);\r\n\r\n    REQUIRE(FindControlCodeToConvert(\"\\x1bUnskipped code\") == 0);\r\n    REQUIRE(FindControlCodeToConvert(\"Escape code: \\x1b\") == 13);\r\n\r\n    std::string_view allCodes{ \"\\x0\\x1\\x2\\x3\\x4\\x5\\x6\\x7\\x8\\xb\\xc\\xe\\xf\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f\\x7f\"sv };\r\n    for (size_t i = 0; i < allCodes.length(); ++i)\r\n    {\r\n        REQUIRE(FindControlCodeToConvert(allCodes, i) == i);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"ConvertControlCodesToPictures\", \"[strings]\")\r\n{\r\n    REQUIRE(ConvertControlCodesToPictures(\"No codes\") == \"No codes\");\r\n    REQUIRE(ConvertControlCodesToPictures(\"Allowed codes: \\t\\r\\n\") == \"Allowed codes: \\t\\r\\n\");\r\n\r\n    REQUIRE(ConvertControlCodesToPictures(\"\\x1b Code First\") == ConvertToUTF8(L\"\\x241b Code First\"));\r\n    REQUIRE(ConvertControlCodesToPictures(\"Escape code: \\x1b\") == ConvertToUTF8(L\"Escape code: \\x241b\"));\r\n\r\n    std::string_view allCodes{ \"\\x0\\x1\\x2\\x3\\x4\\x5\\x6\\x7\\x8\\xb\\xc\\xe\\xf\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f\\x7f\"sv };\r\n    std::wstring_view allPictures{ L\"\\x2400\\x2401\\x2402\\x2403\\x2404\\x2405\\x2406\\x2407\\x2408\\x240b\\x240c\\x240e\\x240f\\x2410\\x2411\\x2412\\x2413\\x2414\\x2415\\x2416\\x2417\\x2418\\x2419\\x241a\\x241b\\x241c\\x241d\\x241e\\x241f\\x2421\"sv };\r\n\r\n    REQUIRE(ConvertControlCodesToPictures(allCodes) == ConvertToUTF8(allPictures));\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/Synchronization.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n\r\n#include <AppInstallerSynchronization.h>\r\n\r\nusing namespace AppInstaller::Synchronization;\r\n\r\nTEST_CASE(\"CPIL_BlocksOthers\", \"[CrossProcessInstallLock]\")\r\n{\r\n    wil::unique_event signal;\r\n    signal.create();\r\n    AppInstaller::ProgressCallback progress;\r\n\r\n    {\r\n        CrossProcessInstallLock mainThreadLock;\r\n        mainThreadLock.Acquire(progress);\r\n\r\n        std::thread otherThread([&signal, &progress]() {\r\n            CrossProcessInstallLock otherThreadLock;\r\n            otherThreadLock.Acquire(progress);\r\n            signal.SetEvent();\r\n            });\r\n        // In the event of bugs, we don't want to block the test waiting forever\r\n        otherThread.detach();\r\n\r\n        REQUIRE(!signal.wait(500));\r\n    }\r\n\r\n    // Upon release of the writer, the other thread should signal\r\n    REQUIRE(signal.wait(500));\r\n}\r\n\r\nTEST_CASE(\"CPIL_CancelEndsWait\", \"[CrossProcessInstallLock]\")\r\n{\r\n    wil::unique_event signal;\r\n    signal.create();\r\n    AppInstaller::ProgressCallback progress;\r\n\r\n    CrossProcessInstallLock mainThreadLock;\r\n    mainThreadLock.Acquire(progress);\r\n\r\n    std::optional<bool> otherThreadAcquireResult = std::nullopt;\r\n\r\n    std::thread otherThread([&]() {\r\n        CrossProcessInstallLock otherThreadLock;\r\n        otherThreadAcquireResult = otherThreadLock.Acquire(progress);\r\n        signal.SetEvent();\r\n        });\r\n    // In the event of bugs, we don't want to block the test waiting forever\r\n    otherThread.detach();\r\n\r\n    REQUIRE(!signal.wait(500));\r\n\r\n    progress.Cancel();\r\n\r\n    // Upon release of the writer, the other thread should signal\r\n    REQUIRE(signal.wait(500));\r\n\r\n    REQUIRE(otherThreadAcquireResult.has_value());\r\n    REQUIRE(!otherThreadAcquireResult.value());\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestCommon.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestHooks.h\"\r\n#include <winget/GroupPolicy.h>\r\n#include <winget/UserSettings.h>\r\n#include <AppInstallerMsixInfo.h>\r\n#include <AppInstallerDownloader.h>\r\n\r\nusing namespace AppInstaller;\r\n\r\nnamespace TestCommon\r\n{\r\n    namespace\r\n    {\r\n        int initRand()\r\n        {\r\n            srand(static_cast<unsigned int>(time(NULL)));\r\n            return rand();\r\n        };\r\n\r\n        inline int getRand()\r\n        {\r\n            static int randStart = initRand();\r\n            return randStart++;\r\n        }\r\n\r\n        inline std::filesystem::path GetFilePath(std::filesystem::path path, const std::string& baseName, const std::string& baseExt)\r\n        {\r\n            path /= baseName + std::to_string(getRand()) + baseExt;\r\n            return path;\r\n        }\r\n\r\n        inline std::filesystem::path GetTempFilePath(const std::string& baseName, const std::string& baseExt)\r\n        {\r\n            std::filesystem::path tempFilePath = std::filesystem::temp_directory_path();\r\n            return GetFilePath(tempFilePath, baseName, baseExt);\r\n        }\r\n\r\n        static TempFileDestructionBehavior s_TempFileDestructorBehavior = TempFileDestructionBehavior::Delete;\r\n        static std::vector<std::filesystem::path> s_TempFilesOnFile;\r\n\r\n        static std::filesystem::path s_TestDataFileBasePath{};\r\n\r\n        bool CleanVolatileTestRoot(HKEY root)\r\n        {\r\n            THROW_IF_WIN32_ERROR(RegDeleteTreeW(root, nullptr));\r\n            return true;\r\n        }\r\n    }\r\n\r\n    TempFile::TempFile(const std::string& baseName, const std::string& baseExt, std::optional<KeepTempFile> keepTempFile)\r\n    {\r\n        _filepath = GetTempFilePath(baseName, baseExt);\r\n        if (!keepTempFile)\r\n        {\r\n            std::filesystem::remove(_filepath);\r\n        }\r\n    }\r\n\r\n    TempFile::TempFile(const std::filesystem::path& parent, const std::string& baseName, const std::string& baseExt, std::optional<KeepTempFile> keepTempFile)\r\n    {\r\n        _filepath = GetFilePath(parent, baseName, baseExt);\r\n        if (!keepTempFile)\r\n        {\r\n            std::filesystem::remove(_filepath);\r\n        }\r\n    }\r\n\r\n    TempFile::TempFile(const std::filesystem::path& filePath, std::optional<KeepTempFile> keepTempFile)\r\n    {\r\n        if (filePath.is_relative())\r\n        {\r\n            _filepath = std::filesystem::temp_directory_path();\r\n            _filepath /= filePath;\r\n        }\r\n        else\r\n        {\r\n            _filepath = filePath;\r\n        }\r\n        if (!keepTempFile)\r\n        {\r\n            std::filesystem::remove(_filepath);\r\n        }\r\n    }\r\n\r\n    TempFile::~TempFile() try\r\n    {\r\n        if (m_destructionToken)\r\n        {\r\n            switch (s_TempFileDestructorBehavior)\r\n            {\r\n            case TempFileDestructionBehavior::Delete:\r\n                std::filesystem::remove_all(_filepath);\r\n                break;\r\n            case TempFileDestructionBehavior::Keep:\r\n                break;\r\n            case TempFileDestructionBehavior::ShellExecuteOnFailure:\r\n                s_TempFilesOnFile.emplace_back(std::move(_filepath));\r\n                break;\r\n            }\r\n        }\r\n    }\r\n    CATCH_LOG_RETURN()\r\n\r\n    void TempFile::Rename(const std::filesystem::path& newFilePath)\r\n    {\r\n        std::filesystem::rename(GetPath(), newFilePath);\r\n        _filepath = newFilePath;\r\n    }\r\n\r\n    void TempFile::Release()\r\n    {\r\n        m_destructionToken = false;\r\n    }\r\n\r\n    void TempFile::SetDestructorBehavior(TempFileDestructionBehavior behavior)\r\n    {\r\n        s_TempFileDestructorBehavior = behavior;\r\n    }\r\n\r\n    void TempFile::SetTestFailed(bool failed)\r\n    {\r\n        if (failed)\r\n        {\r\n            for (const auto& path : s_TempFilesOnFile)\r\n            {\r\n                SHELLEXECUTEINFOW seinfo{};\r\n                seinfo.cbSize = sizeof(seinfo);\r\n                seinfo.lpVerb = L\"open\";\r\n                seinfo.lpFile = path.c_str();\r\n\r\n                ShellExecuteExW(&seinfo);\r\n            }\r\n        }\r\n        else\r\n        {\r\n            s_TempFilesOnFile.clear();\r\n        }\r\n    }\r\n\r\n    TempDirectory::TempDirectory(const std::string& baseName, bool create)\r\n    {\r\n        _filepath = GetTempFilePath(baseName, \"\");\r\n        if (create)\r\n        {\r\n            if (std::filesystem::exists(_filepath))\r\n            {\r\n                std::filesystem::remove_all(_filepath);\r\n            }\r\n            std::filesystem::create_directories(_filepath);\r\n        }\r\n    }\r\n\r\n    TempFile TempDirectory::CreateTempFile(const std::string& baseName, const std::string& baseExt)\r\n    {\r\n        return { _filepath, baseName, baseExt };\r\n    }\r\n\r\n    TempFile TempDirectory::CreateTempFile(const std::string& name)\r\n    {\r\n        return { _filepath / name };\r\n    }\r\n\r\n    std::filesystem::path TestDataFile::GetPath() const\r\n    {\r\n        std::filesystem::path result = s_TestDataFileBasePath;\r\n        result /= m_path;\r\n        return result;\r\n    }\r\n\r\n    void TestDataFile::SetTestDataBasePath(const std::filesystem::path& path)\r\n    {\r\n        s_TestDataFileBasePath = path;\r\n    }\r\n\r\n    void TestProgress::OnProgress(uint64_t current, uint64_t maximum, AppInstaller::ProgressType type)\r\n    {\r\n        if (m_OnProgress)\r\n        {\r\n            m_OnProgress(current, maximum, type);\r\n        }\r\n    }\r\n\r\n    void TestProgress::SetProgressMessage(std::string_view)\r\n    {\r\n    }\r\n\r\n    void TestProgress::BeginProgress()\r\n    {\r\n    }\r\n\r\n    void TestProgress::EndProgress(bool)\r\n    {\r\n    }\r\n\r\n    bool TestProgress::IsCancelledBy(AppInstaller::CancelReason)\r\n    {\r\n        return false;\r\n    }\r\n\r\n    AppInstaller::IProgressCallback::CancelFunctionRemoval TestProgress::SetCancellationFunction(std::function<void()>&&)\r\n    {\r\n        return {};\r\n    }\r\n\r\n    wil::unique_hkey RegCreateVolatileTestRoot()\r\n    {\r\n        // First create/open the real test root\r\n        wil::unique_hkey root;\r\n        THROW_IF_WIN32_ERROR(RegCreateKeyExW(HKEY_CURRENT_USER, L\"Software\\\\Microsoft\\\\WinGet\\\\TestRoot\", 0, nullptr, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, nullptr, &root, nullptr));\r\n\r\n        static bool s_ignored = CleanVolatileTestRoot(root.get());\r\n\r\n        // Create a random name\r\n        GUID name{};\r\n        (void)CoCreateGuid(&name);\r\n\r\n        wchar_t nameBuffer[256];\r\n        (void)StringFromGUID2(name, nameBuffer, ARRAYSIZE(nameBuffer));\r\n\r\n        return RegCreateVolatileSubKey(root.get(), nameBuffer);\r\n    }\r\n\r\n    wil::unique_hkey RegCreateVolatileSubKey(HKEY parent, const std::wstring& name)\r\n    {\r\n        wil::unique_hkey result;\r\n        THROW_IF_WIN32_ERROR(RegCreateKeyExW(parent, name.c_str(), 0, nullptr, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, nullptr, &result, nullptr));\r\n        return result;\r\n    }\r\n\r\n    void SetRegistryValue(HKEY key, const std::wstring& name, const std::wstring& value, DWORD type)\r\n    {\r\n        THROW_IF_WIN32_ERROR(RegSetValueExW(key, name.c_str(), 0, type, reinterpret_cast<const BYTE*>(value.c_str()), static_cast<DWORD>(sizeof(wchar_t) * (value.size() + 1))));\r\n    }\r\n\r\n    void SetRegistryValue(HKEY key, const std::wstring& name, const std::vector<BYTE>& value, DWORD type)\r\n    {\r\n        THROW_IF_WIN32_ERROR(RegSetValueExW(key, name.c_str(), 0, type, reinterpret_cast<const BYTE*>(value.data()), static_cast<DWORD>(value.size())));\r\n    }\r\n\r\n    void SetRegistryValue(HKEY key, const std::wstring& name, DWORD value)\r\n    {\r\n        THROW_IF_WIN32_ERROR(RegSetValueExW(key, name.c_str(), 0, REG_DWORD, reinterpret_cast<const BYTE*>(&value), sizeof(DWORD)));\r\n    }\r\n\r\n    void EnableDevMode(bool enable)\r\n    {\r\n        wil::unique_hkey result;\r\n        THROW_IF_WIN32_ERROR(RegOpenKeyExW(HKEY_LOCAL_MACHINE, L\"SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\AppModelUnlock\", 0, KEY_ALL_ACCESS|KEY_WOW64_64KEY, &result));\r\n        SetRegistryValue(result.get(), L\"AllowDevelopmentWithoutDevLicense\", (enable ? 1 : 0));\r\n    }\r\n\r\n    TestUserSettings::TestUserSettings(bool keepFileSettings)\r\n    {\r\n        if (!keepFileSettings)\r\n        {\r\n            m_settings.clear();\r\n        }\r\n\r\n        AppInstaller::Settings::SetUserSettingsOverride(this);\r\n    }\r\n\r\n    TestUserSettings::~TestUserSettings()\r\n    {\r\n        AppInstaller::Settings::SetUserSettingsOverride(nullptr);\r\n    }\r\n\r\n    std::unique_ptr<TestUserSettings> TestUserSettings::EnableExperimentalFeature(Settings::ExperimentalFeature::Feature feature, bool keepFileSettings)\r\n    {\r\n        std::unique_ptr<TestUserSettings> result = std::make_unique<TestUserSettings>(keepFileSettings);\r\n\r\n        // Due to the template usage, this needs to be updated for any features that want to use it.\r\n        // Currently no feature is used. Uncomment below when a feature needs to be used.\r\n        // switch (feature)\r\n        // {\r\n        // default:\r\n        //     THROW_HR(E_NOTIMPL);\r\n        // }\r\n        UNREFERENCED_PARAMETER(feature);\r\n\r\n        return result;\r\n    }\r\n\r\n    bool InstallCertFromSignedPackage(const std::filesystem::path& package)\r\n    {\r\n        auto [certContext, certStore] = AppInstaller::Msix::GetCertContextFromMsix(package);\r\n\r\n        wil::unique_hcertstore trustedPeopleStore;\r\n        trustedPeopleStore.reset(CertOpenStore(\r\n            CERT_STORE_PROV_SYSTEM_W,\r\n            PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,\r\n            NULL,\r\n            CERT_SYSTEM_STORE_LOCAL_MACHINE,\r\n            L\"TrustedPeople\"));\r\n        THROW_LAST_ERROR_IF(!trustedPeopleStore.get());\r\n\r\n        wil::unique_cert_context existingCert;\r\n        existingCert.reset(CertFindCertificateInStore(\r\n            trustedPeopleStore.get(),\r\n            PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,\r\n            0,\r\n            CERT_FIND_EXISTING,\r\n            certContext.get(),\r\n            nullptr));\r\n\r\n        // Add if it does not already exist in the store\r\n        if (!existingCert.get())\r\n        {\r\n            THROW_LAST_ERROR_IF(!CertAddCertificateContextToStore(\r\n                trustedPeopleStore.get(),\r\n                certContext.get(),\r\n                CERT_STORE_ADD_NEW,\r\n                nullptr));\r\n\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    bool UninstallCertFromSignedPackage(const std::filesystem::path& package)\r\n    {\r\n        auto [certContext, certStore] = AppInstaller::Msix::GetCertContextFromMsix(package);\r\n\r\n        wil::unique_hcertstore trustedPeopleStore;\r\n        trustedPeopleStore.reset(CertOpenStore(\r\n            CERT_STORE_PROV_SYSTEM_W,\r\n            PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,\r\n            NULL,\r\n            CERT_SYSTEM_STORE_LOCAL_MACHINE,\r\n            L\"TrustedPeople\"));\r\n        THROW_LAST_ERROR_IF(!trustedPeopleStore.get());\r\n\r\n        wil::unique_cert_context existingCert;\r\n        existingCert.reset(CertFindCertificateInStore(\r\n            trustedPeopleStore.get(),\r\n            PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,\r\n            0,\r\n            CERT_FIND_EXISTING,\r\n            certContext.get(),\r\n            nullptr));\r\n\r\n        // Remove if it exists in the store\r\n        if (existingCert.get())\r\n        {\r\n            THROW_LAST_ERROR_IF(!CertDeleteCertificateFromStore(existingCert.get()));\r\n\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    bool GetMsixPackageManifestReader(std::string_view testFileName, IAppxManifestReader** manifestReader)\r\n    {\r\n        // Locate test file\r\n        TestDataFile testFile(testFileName);\r\n        auto path = testFile.GetPath().u8string();\r\n\r\n        // Get the stream for the test file\r\n        auto stream = AppInstaller::Utility::GetReadOnlyStreamFromURI(path);\r\n\r\n        // Get manifest from package reader\r\n        Microsoft::WRL::ComPtr<IAppxPackageReader> packageReader;\r\n        return  AppInstaller::Msix::GetPackageReader(stream.Get(), &packageReader)\r\n            && SUCCEEDED(packageReader->GetManifest(manifestReader));\r\n    }\r\n\r\n    std::string RemoveConsoleFormat(const std::string& str)\r\n    {\r\n        // We are looking something that starts with \"\\x1b[0m\"\r\n        if (!str.empty() && str[0] == '\\x1b')\r\n        {\r\n            // Find first m\r\n            auto pos = str.find(\"m\");\r\n            if (pos != std::string::npos)\r\n            {\r\n                return str.substr(pos + 1);\r\n            }\r\n        }\r\n\r\n        return str;\r\n    }\r\n\r\n    Json::Value ConvertToJson(const std::string& content)\r\n    {\r\n        auto contentClean = RemoveConsoleFormat(content);\r\n\r\n        Json::Value root;\r\n        Json::CharReaderBuilder builder;\r\n        const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());\r\n        std::string error;\r\n\r\n        if (!reader->parse(contentClean.c_str(), contentClean.c_str() + contentClean.size(), &root, &error))\r\n        {\r\n            throw error;\r\n        }\r\n\r\n        return root;\r\n    }\r\n\r\n    void SetTestPathOverrides()\r\n    {\r\n        // Force all tests to run against settings inside this container.\r\n        // This prevents test runs from trashing the users actual settings.\r\n        Runtime::TestHook_SetPathOverride(Runtime::PathName::LocalState, Runtime::GetPathTo(Runtime::PathName::LocalState) / \"Tests\");\r\n        Runtime::TestHook_SetPathOverride(Runtime::PathName::UserFileSettings, Runtime::GetPathTo(Runtime::PathName::UserFileSettings) / \"Tests\");\r\n        Runtime::TestHook_SetPathOverride(Runtime::PathName::StandardSettings, Runtime::GetPathTo(Runtime::PathName::StandardSettings) / \"Tests\");\r\n        Runtime::TestHook_SetPathOverride(Runtime::PathName::SecureSettingsForRead, Runtime::GetPathTo(Runtime::PathName::StandardSettings) / \"WinGet_SecureSettings_Tests\");\r\n        Runtime::TestHook_SetPathOverride(Runtime::PathName::SecureSettingsForWrite, Runtime::GetPathDetailsFor(Runtime::PathName::SecureSettingsForRead));\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestCommon.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerLanguageUtilities.h>\r\n#include <AppInstallerLogging.h>\r\n#include <AppInstallerProgress.h>\r\n#include <AppxPackaging.h>\r\n#include <winget/UserSettings.h>\r\n#include <winget/ExperimentalFeature.h>\r\n#include <wil/result.h>\r\n\r\n#include <filesystem>\r\n#include <functional>\r\n#include <memory>\r\n#include <string>\r\n\r\n#define REQUIRE_THROWS_HR(_expr_, _hr_)     REQUIRE_THROWS_MATCHES(_expr_, wil::ResultException, ::TestCommon::ResultExceptionHRMatcher(_hr_))\r\n\r\nnamespace TestCommon\r\n{\r\n    enum class TempFileDestructionBehavior\r\n    {\r\n        Delete,\r\n        Keep,\r\n        ShellExecuteOnFailure,\r\n    };\r\n\r\n    struct KeepTempFile {};\r\n\r\n    // Use this to create a temporary file for testing.\r\n    struct TempFile\r\n    {\r\n        TempFile(const std::string& baseName, const std::string& baseExt, std::optional<KeepTempFile> keepTempFile = {});\r\n        TempFile(const std::filesystem::path& parent, const std::string& baseName, const std::string& baseExt, std::optional<KeepTempFile> keepTempFile = {});\r\n        TempFile(const std::filesystem::path& filePath, std::optional<KeepTempFile> keepTempFile = {});\r\n\r\n        TempFile(const TempFile&) = delete;\r\n        TempFile& operator=(const TempFile&) = delete;\r\n\r\n        TempFile(TempFile&&) = default;\r\n        TempFile& operator=(TempFile&&) = default;\r\n\r\n        ~TempFile();\r\n\r\n        const std::filesystem::path& GetPath() const { return _filepath; }\r\n        operator const std::filesystem::path& () const { return _filepath; }\r\n        operator const std::string() const { return _filepath.u8string(); }\r\n\r\n        void Rename(const std::filesystem::path& newFilePath);\r\n\r\n        void Release();\r\n\r\n        static void SetDestructorBehavior(TempFileDestructionBehavior behavior);\r\n\r\n        static void SetTestFailed(bool failed);\r\n\r\n    protected:\r\n        TempFile() = default;\r\n        std::filesystem::path _filepath;\r\n        AppInstaller::DestructionToken m_destructionToken{ true };\r\n    };\r\n\r\n    // Use to create a temporary directory for testing.\r\n    struct TempDirectory : public TempFile\r\n    {\r\n        TempDirectory(const std::string& baseName, bool create = true);\r\n\r\n        TempFile CreateTempFile(const std::string& baseName, const std::string& baseExt);\r\n        TempFile CreateTempFile(const std::string& name);\r\n    };\r\n\r\n    // Use this to find a test data file when testing.\r\n    struct TestDataFile\r\n    {\r\n        TestDataFile(const std::filesystem::path& path) : m_path(path) {}\r\n\r\n        std::filesystem::path GetPath() const;\r\n        operator std::filesystem::path () const { return GetPath(); }\r\n\r\n        static void SetTestDataBasePath(const std::filesystem::path& path);\r\n\r\n    private:\r\n        std::filesystem::path m_path;\r\n    };\r\n\r\n    // Matcher that lets us verify wil::ResultExceptions have a specific HR.\r\n    struct ResultExceptionHRMatcher : public Catch::Matchers::MatcherBase<wil::ResultException>\r\n    {\r\n        ResultExceptionHRMatcher(HRESULT hr) : m_expectedHR(hr) {}\r\n\r\n        bool match(const wil::ResultException& re) const override\r\n        {\r\n            return re.GetErrorCode() == m_expectedHR;\r\n        }\r\n\r\n        std::string describe() const override\r\n        {\r\n            std::ostringstream result;\r\n            result << \"has HR == 0x\" << AppInstaller::Logging::SetHRFormat << m_expectedHR;\r\n            return result.str();\r\n        }\r\n\r\n    private:\r\n        HRESULT m_expectedHR = S_OK;\r\n    };\r\n\r\n    // An IProgressCallback that is easily hooked.\r\n    struct TestProgress : public AppInstaller::IProgressCallback\r\n    {\r\n        // Inherited via IProgressCallback\r\n        void BeginProgress() override;\r\n        \r\n        void OnProgress(uint64_t current, uint64_t maximum, AppInstaller::ProgressType type) override;\r\n\r\n        void SetProgressMessage(std::string_view message) override;\r\n\r\n        void EndProgress(bool) override;\r\n\r\n        bool IsCancelledBy(AppInstaller::CancelReason) override;\r\n\r\n        CancelFunctionRemoval SetCancellationFunction(std::function<void()>&& f) override;\r\n\r\n        std::function<void(uint64_t, uint64_t, AppInstaller::ProgressType)> m_OnProgress;\r\n    };\r\n\r\n    // Creates a volatile key for testing.\r\n    wil::unique_hkey RegCreateVolatileTestRoot();\r\n\r\n    // Creates a volatile subkey for testing.\r\n    wil::unique_hkey RegCreateVolatileSubKey(HKEY parent, const std::wstring& name);\r\n\r\n    // Set registry values.\r\n    void SetRegistryValue(HKEY key, const std::wstring& name, const std::wstring& value, DWORD type = REG_SZ);\r\n    void SetRegistryValue(HKEY key, const std::wstring& name, const std::vector<BYTE>& value, DWORD type = REG_BINARY);\r\n    void SetRegistryValue(HKEY key, const std::wstring& name, DWORD value);\r\n\r\n    // Enable or disable developer mode.\r\n    void EnableDevMode(bool enable);\r\n\r\n    // Override UserSettings using this class.\r\n    // Automatically overrides the user settings for the lifetime of this object.\r\n    // DOES NOT SUPPORT NESTED USE\r\n    struct TestUserSettings : public AppInstaller::Settings::UserSettings\r\n    {\r\n        TestUserSettings(bool keepFileSettings = false);\r\n        ~TestUserSettings();\r\n\r\n        template <AppInstaller::Settings::Setting S>\r\n        void Set(typename AppInstaller::Settings::details::SettingMapping<S>::value_t&& value)\r\n        {\r\n            m_settings[S].emplace<AppInstaller::Settings::details::SettingIndex(S)>(std::move(value));\r\n        }\r\n\r\n        static std::unique_ptr<TestUserSettings> EnableExperimentalFeature(AppInstaller::Settings::ExperimentalFeature::Feature feature, bool keepFileSettings = false);\r\n    };\r\n\r\n    // Below cert installation/uninstallation methods require admin privilege,\r\n    // tests calling these functions should skip when not running with admin.\r\n    bool InstallCertFromSignedPackage(const std::filesystem::path& package);\r\n    bool UninstallCertFromSignedPackage(const std::filesystem::path& package);\r\n\r\n    // Get manifest reader from a msix file path\r\n    bool GetMsixPackageManifestReader(std::string_view testFileName, IAppxManifestReader** manifestReader);\r\n\r\n    // Removes console format\r\n    std::string RemoveConsoleFormat(const std::string& str);\r\n\r\n    // Convert to Json::Value\r\n    Json::Value ConvertToJson(const std::string& content);\r\n\r\n    // Sets up the test path overrides.\r\n    void SetTestPathOverrides();\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestConfiguration.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestConfiguration.h\"\r\n\r\nusing namespace winrt::Windows::Foundation;\r\nusing namespace winrt::Windows::Foundation::Collections;\r\nusing namespace winrt::Microsoft::Management::Configuration;\r\n\r\nnamespace TestCommon\r\n{\r\n    IConfigurationSetProcessor TestConfigurationSetProcessorFactory::CreateSetProcessor(const ConfigurationSet& configurationSet)\r\n    {\r\n        if (CreateSetProcessorFunc)\r\n        {\r\n            return CreateSetProcessorFunc(configurationSet);\r\n        }\r\n        else\r\n        {\r\n            return winrt::make<TestConfigurationSetProcessor>();\r\n        }\r\n    }\r\n\r\n    winrt::event_token TestConfigurationSetProcessorFactory::Diagnostics(const EventHandler<IDiagnosticInformation>& handler)\r\n    {\r\n        return m_diagnostics.add(handler);\r\n    }\r\n\r\n    void TestConfigurationSetProcessorFactory::Diagnostics(const winrt::event_token& token) noexcept\r\n    {\r\n        m_diagnostics.remove(token);\r\n    }\r\n\r\n    DiagnosticLevel TestConfigurationSetProcessorFactory::MinimumLevel()\r\n    {\r\n        return DiagnosticLevel::Informational;\r\n    }\r\n\r\n    void TestConfigurationSetProcessorFactory::MinimumLevel(DiagnosticLevel)\r\n    {\r\n    }\r\n\r\n    IConfigurationUnitProcessorDetails TestConfigurationSetProcessor::GetUnitProcessorDetails(const ConfigurationUnit& unit, ConfigurationUnitDetailFlags detailFlags)\r\n    {\r\n        if (GetUnitProcessorDetailsFunc)\r\n        {\r\n            return GetUnitProcessorDetailsFunc(unit, detailFlags);\r\n        }\r\n        else\r\n        {\r\n            return winrt::make<TestConfigurationUnitProcessorDetails>(unit);\r\n        }\r\n    }\r\n\r\n    IConfigurationUnitProcessor TestConfigurationSetProcessor::CreateUnitProcessor(const ConfigurationUnit& unit)\r\n    {\r\n        if (CreateUnitProcessorFunc)\r\n        {\r\n            return CreateUnitProcessorFunc(unit);\r\n        }\r\n        else\r\n        {\r\n            return winrt::make<TestConfigurationUnitProcessor>(unit);\r\n        }\r\n    }\r\n\r\n    TestConfigurationUnitProcessorDetails::TestConfigurationUnitProcessorDetails(const ConfigurationUnit& unit) :\r\n        UnitTypeValue(unit.Type())\r\n    {}\r\n\r\n    TestConfigurationUnitProcessor::TestConfigurationUnitProcessor(const ConfigurationUnit& unit) :\r\n        UnitValue(unit)\r\n    {}\r\n\r\n    ITestSettingsResult TestConfigurationUnitProcessor::TestSettings()\r\n    {\r\n        if (TestSettingsFunc)\r\n        {\r\n            return TestSettingsFunc();\r\n        }\r\n        else\r\n        {\r\n            return winrt::make<TestSettingsResultInstance>(UnitValue);\r\n        }\r\n    }\r\n\r\n    IGetSettingsResult TestConfigurationUnitProcessor::GetSettings()\r\n    {\r\n        if (GetSettingsFunc)\r\n        {\r\n            return GetSettingsFunc();\r\n        }\r\n        else\r\n        {\r\n            return winrt::make<GetSettingsResultInstance>(UnitValue);\r\n        }\r\n    }\r\n\r\n    IApplySettingsResult TestConfigurationUnitProcessor::ApplySettings()\r\n    {\r\n        if (ApplySettingsFunc)\r\n        {\r\n            return ApplySettingsFunc();\r\n        }\r\n        else\r\n        {\r\n            return winrt::make<ApplySettingsResultInstance>(UnitValue);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestConfiguration.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winrt/Windows.Foundation.h>\r\n#include <winrt/Windows.Foundation.Collections.h>\r\n#include <winrt/Windows.Security.Cryptography.Certificates.h>\r\n#include <winrt/Microsoft.Management.Configuration.h>\r\n#include <functional>\r\n\r\nnamespace TestCommon\r\n{\r\n    struct TestConfigurationSetProcessorFactory : winrt::implements<TestConfigurationSetProcessorFactory, winrt::Microsoft::Management::Configuration::IConfigurationSetProcessorFactory>\r\n    {\r\n        winrt::Microsoft::Management::Configuration::IConfigurationSetProcessor CreateSetProcessor(const winrt::Microsoft::Management::Configuration::ConfigurationSet& configurationSet);\r\n\r\n        winrt::event_token Diagnostics(const winrt::Windows::Foundation::EventHandler<winrt::Microsoft::Management::Configuration::IDiagnosticInformation>& handler);\r\n        void Diagnostics(const winrt::event_token& token) noexcept;\r\n\r\n        winrt::Microsoft::Management::Configuration::DiagnosticLevel MinimumLevel();\r\n        void MinimumLevel(winrt::Microsoft::Management::Configuration::DiagnosticLevel value);\r\n\r\n        std::function<winrt::Microsoft::Management::Configuration::IConfigurationSetProcessor(const winrt::Microsoft::Management::Configuration::ConfigurationSet&)> CreateSetProcessorFunc;\r\n\r\n    private:\r\n        winrt::event<winrt::Windows::Foundation::EventHandler<winrt::Microsoft::Management::Configuration::IDiagnosticInformation>> m_diagnostics;\r\n    };\r\n\r\n    struct TestConfigurationSetProcessor : winrt::implements<TestConfigurationSetProcessor, winrt::Microsoft::Management::Configuration::IConfigurationSetProcessor>\r\n    {\r\n        winrt::Microsoft::Management::Configuration::IConfigurationUnitProcessorDetails GetUnitProcessorDetails(\r\n            const winrt::Microsoft::Management::Configuration::ConfigurationUnit& unit,\r\n            winrt::Microsoft::Management::Configuration::ConfigurationUnitDetailFlags detailFlags);\r\n\r\n        std::function<winrt::Microsoft::Management::Configuration::IConfigurationUnitProcessorDetails(\r\n            const winrt::Microsoft::Management::Configuration::ConfigurationUnit&,\r\n            winrt::Microsoft::Management::Configuration::ConfigurationUnitDetailFlags)> GetUnitProcessorDetailsFunc;\r\n\r\n        winrt::Microsoft::Management::Configuration::IConfigurationUnitProcessor CreateUnitProcessor(\r\n            const winrt::Microsoft::Management::Configuration::ConfigurationUnit& unit);\r\n\r\n        std::function<winrt::Microsoft::Management::Configuration::IConfigurationUnitProcessor(\r\n            const winrt::Microsoft::Management::Configuration::ConfigurationUnit&)> CreateUnitProcessorFunc;\r\n    };\r\n\r\n    struct TestConfigurationUnitProcessorDetails : winrt::implements<TestConfigurationUnitProcessorDetails, winrt::Microsoft::Management::Configuration::IConfigurationUnitProcessorDetails>\r\n    {\r\n        TestConfigurationUnitProcessorDetails(const winrt::Microsoft::Management::Configuration::ConfigurationUnit& unit);\r\n\r\n        winrt::hstring UnitTypeValue;\r\n        winrt::hstring UnitType() const { return UnitTypeValue; }\r\n\r\n        winrt::hstring UnitDescriptionValue;\r\n        winrt::hstring UnitDescription() const { return UnitDescriptionValue; }\r\n\r\n        winrt::Windows::Foundation::Uri UnitDocumentationUriValue = nullptr;\r\n        winrt::Windows::Foundation::Uri UnitDocumentationUri() const { return UnitDocumentationUriValue; }\r\n\r\n        winrt::Windows::Foundation::Uri UnitIconUriValue = nullptr;\r\n        winrt::Windows::Foundation::Uri UnitIconUri() const { return UnitIconUriValue; }\r\n\r\n        winrt::hstring ModuleNameValue;\r\n        winrt::hstring ModuleName() const { return ModuleNameValue; }\r\n\r\n        winrt::hstring ModuleTypeValue;\r\n        winrt::hstring ModuleType() const { return ModuleTypeValue; }\r\n\r\n        winrt::hstring ModuleSourceValue;\r\n        winrt::hstring ModuleSource() const { return ModuleSourceValue; }\r\n\r\n        winrt::hstring ModuleDescriptionValue;\r\n        winrt::hstring ModuleDescription() const { return ModuleDescriptionValue; }\r\n\r\n        winrt::Windows::Foundation::Uri ModuleDocumentationUriValue = nullptr;\r\n        winrt::Windows::Foundation::Uri ModuleDocumentationUri() const { return ModuleDocumentationUriValue; }\r\n\r\n        winrt::Windows::Foundation::Uri PublishedModuleUriValue = nullptr;\r\n        winrt::Windows::Foundation::Uri PublishedModuleUri() const { return PublishedModuleUriValue; }\r\n\r\n        winrt::hstring VersionValue;\r\n        winrt::hstring Version() const { return VersionValue; }\r\n\r\n        winrt::Windows::Foundation::DateTime PublishedDateValue;\r\n        winrt::Windows::Foundation::DateTime PublishedDate() const { return PublishedDateValue; }\r\n\r\n        bool IsLocalValue = false;\r\n        bool IsLocal() const { return IsLocalValue; }\r\n\r\n        winrt::hstring AuthorValue;\r\n        winrt::hstring Author() const { return AuthorValue; }\r\n\r\n        winrt::hstring PublisherValue;\r\n        winrt::hstring Publisher() const { return PublisherValue; }\r\n\r\n        winrt::Windows::Foundation::Collections::IVector<winrt::Windows::Foundation::IInspectable> SigningInformationValue = nullptr;\r\n        winrt::Windows::Foundation::Collections::IVectorView<winrt::Windows::Foundation::IInspectable> SigningInformation() const { return SigningInformationValue.GetView(); }\r\n\r\n        winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Configuration::IConfigurationUnitSettingDetails> SettingsValue;\r\n        winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Management::Configuration::IConfigurationUnitSettingDetails> Settings() const { return (SettingsValue ? SettingsValue.GetView() : nullptr); }\r\n\r\n        bool IsPublicValue = false;\r\n        bool IsPublic() const { return IsPublicValue; }\r\n    };\r\n\r\n    struct TestConfigurationUnitProcessor : winrt::implements<TestConfigurationUnitProcessor, winrt::Microsoft::Management::Configuration::IConfigurationUnitProcessor>\r\n    {\r\n        TestConfigurationUnitProcessor(\r\n            const winrt::Microsoft::Management::Configuration::ConfigurationUnit& unit);\r\n\r\n        winrt::Microsoft::Management::Configuration::ConfigurationUnit UnitValue;\r\n        winrt::Microsoft::Management::Configuration::ConfigurationUnit Unit() { return UnitValue; }\r\n\r\n        winrt::Microsoft::Management::Configuration::ITestSettingsResult TestSettings();\r\n\r\n        std::function<winrt::Microsoft::Management::Configuration::ITestSettingsResult()> TestSettingsFunc;\r\n\r\n        winrt::Microsoft::Management::Configuration::IGetSettingsResult GetSettings();\r\n\r\n        std::function<winrt::Microsoft::Management::Configuration::IGetSettingsResult()> GetSettingsFunc;\r\n\r\n        winrt::Microsoft::Management::Configuration::IApplySettingsResult ApplySettings();\r\n\r\n        std::function<winrt::Microsoft::Management::Configuration::IApplySettingsResult()> ApplySettingsFunc;\r\n    };\r\n\r\n    struct TestSettingsResultInstance : winrt::implements<TestSettingsResultInstance, winrt::Microsoft::Management::Configuration::ITestSettingsResult>\r\n    {\r\n        TestSettingsResultInstance(const winrt::Microsoft::Management::Configuration::ConfigurationUnit& unit) : m_unit(unit) {}\r\n\r\n        winrt::Microsoft::Management::Configuration::ConfigurationUnit Unit() { return m_unit; }\r\n\r\n        winrt::Microsoft::Management::Configuration::ConfigurationTestResult TestResult() { return m_testResult; }\r\n        void TestResult(winrt::Microsoft::Management::Configuration::ConfigurationTestResult value) { m_testResult = value; }\r\n\r\n        winrt::Microsoft::Management::Configuration::IConfigurationUnitResultInformation ResultInformation() { return m_resultInformation; }\r\n        void ResultInformation(winrt::Microsoft::Management::Configuration::IConfigurationUnitResultInformation value) { m_resultInformation = value; }\r\n\r\n    private:\r\n        winrt::Microsoft::Management::Configuration::ConfigurationUnit m_unit;\r\n        winrt::Microsoft::Management::Configuration::ConfigurationTestResult m_testResult = winrt::Microsoft::Management::Configuration::ConfigurationTestResult::Unknown;\r\n        winrt::Microsoft::Management::Configuration::IConfigurationUnitResultInformation m_resultInformation;\r\n    };\r\n\r\n    struct ApplySettingsResultInstance : winrt::implements<ApplySettingsResultInstance, winrt::Microsoft::Management::Configuration::IApplySettingsResult>\r\n    {\r\n        ApplySettingsResultInstance(const winrt::Microsoft::Management::Configuration::ConfigurationUnit& unit) : m_unit(unit) {}\r\n\r\n        winrt::Microsoft::Management::Configuration::ConfigurationUnit Unit() { return m_unit; }\r\n\r\n        bool RebootRequired() { return m_rebootRequired; }\r\n        void RebootRequired(bool value) { m_rebootRequired = value; }\r\n\r\n        winrt::Microsoft::Management::Configuration::IConfigurationUnitResultInformation ResultInformation() { return m_resultInformation; }\r\n        void ResultInformation(winrt::Microsoft::Management::Configuration::IConfigurationUnitResultInformation value) { m_resultInformation = value; }\r\n\r\n    private:\r\n        winrt::Microsoft::Management::Configuration::ConfigurationUnit m_unit;\r\n        bool m_rebootRequired = false;\r\n        winrt::Microsoft::Management::Configuration::IConfigurationUnitResultInformation m_resultInformation;\r\n    };\r\n\r\n    struct GetSettingsResultInstance : winrt::implements<GetSettingsResultInstance, winrt::Microsoft::Management::Configuration::IGetSettingsResult>\r\n    {\r\n        GetSettingsResultInstance(const winrt::Microsoft::Management::Configuration::ConfigurationUnit& unit) : m_unit(unit) {}\r\n\r\n        winrt::Microsoft::Management::Configuration::ConfigurationUnit Unit() { return m_unit; }\r\n\r\n        winrt::Windows::Foundation::Collections::ValueSet Settings() { return m_settings; }\r\n        void Settings(winrt::Windows::Foundation::Collections::ValueSet value) { m_settings = value; }\r\n\r\n        winrt::Microsoft::Management::Configuration::IConfigurationUnitResultInformation ResultInformation() { return m_resultInformation; }\r\n        void ResultInformation(winrt::Microsoft::Management::Configuration::IConfigurationUnitResultInformation value) { m_resultInformation = value; }\r\n\r\n    private:\r\n        winrt::Microsoft::Management::Configuration::ConfigurationUnit m_unit;\r\n        winrt::Windows::Foundation::Collections::ValueSet m_settings;\r\n        winrt::Microsoft::Management::Configuration::IConfigurationUnitResultInformation m_resultInformation;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ContainsEscapeControlCode.yaml",
    "content": "key: \"This is the ESCAPE control code: \\x1b\"\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ContainsTooManyNestedLayers.yaml",
    "content": "-\r\n  -\r\n    -\r\n      -\r\n        -\r\n          -\r\n            -\r\n              -\r\n                -\r\n                  -\r\n                    -\r\n                      -\r\n                        -\r\n                          -\r\n                            -\r\n                              -\r\n                                -\r\n                                  -\r\n                                    -\r\n                                      -\r\n                                        -\r\n                                          -\r\n                                            -\r\n                                              -\r\n                                                -\r\n                                                  -\r\n                                                    -\r\n                                                      -\r\n                                                        -\r\n                                                          -\r\n                                                            -\r\n                                                              -\r\n                                                                -\r\n                                                                  -\r\n                                                                    -\r\n                                                                      -\r\n                                                                        -\r\n                                                                          -\r\n                                                                            -\r\n                                                                              -\r\n                                                                                -\r\n                                                                                  -\r\n                                                                                    -\r\n                                                                                      -\r\n                                                                                        -\r\n                                                                                          -\r\n                                                                                            -\r\n                                                                                              -\r\n                                                                                                -\r\n                                                                                                  -\r\n                                                                                                    -\r\n                                                                                                      -\r\n                                                                                                        -\r\n                                                                                                          -\r\n                                                                                                            -\r\n                                                                                                              -\r\n                                                                                                                -\r\n                                                                                                                  -\r\n                                                                                                                    -\r\n                                                                                                                      -\r\n                                                                                                                        -\r\n                                                                                                                          -\r\n                                                                                                                            -\r\n                                                                                                                              -\r\n                                                                                                                                -\r\n                                                                                                                                  -\r\n                                                                                                                                    -\r\n                                                                                                                                      -\r\n                                                                                                                                        -\r\n                                                                                                                                          -\r\n                                                                                                                                            -\r\n                                                                                                                                              -\r\n                                                                                                                                                -\r\n                                                                                                                                                  -\r\n                                                                                                                                                    -\r\n                                                                                                                                                      -\r\n                                                                                                                                                        -\r\n                                                                                                                                                          -\r\n                                                                                                                                                            -\r\n                                                                                                                                                              -\r\n                                                                                                                                                                -\r\n                                                                                                                                                                  -\r\n                                                                                                                                                                    -\r\n                                                                                                                                                                      -\r\n                                                                                                                                                                        -\r\n                                                                                                                                                                          -\r\n                                                                                                                                                                            -\r\n                                                                                                                                                                              -\r\n                                                                                                                                                                                -\r\n                                                                                                                                                                                  -\r\n                                                                                                                                                                                    -\r\n                                                                                                                                                                                      -\r\n                                                                                                                                                                                        -\r\n                                                                                                                                                                                          -\r\n                                                                                                                                                                                            -\r\n                                                                                                                                                                                              -\r\n                                                                                                                                                                                                -\r\n                                                                                                                                                                                                  -\r\n                                                                                                                                                                                                    -\r\n                                                                                                                                                                                                      -\r\n                                                                                                                                                                                                        - value\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/DownloadFlowTest_DownloadCommandProhibited.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.6.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.DownloadCommandProhibited\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test DownloadCommandProhibited\r\nPublisher: Microsoft Corporation\r\nAppMoniker: AICLITestDownloadCommandProhibited\r\nLicense: Test\r\nDownloadCommandProhibited: true\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: exe\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestType: singleton\r\nManifestVersion: 1.6.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/DownloadFlowTest_MSStore.yaml",
    "content": "Id: AppInstallerCliTest.TestMSStoreDownload\r\nVersion: Latest\r\nName: AppInstaller Test MSStore Download\r\nPublisher: Microsoft Corporation\r\nAppMoniker: AICLITestMSStore\r\nLicense: Test\r\nInstallers: \r\n  - Arch: x64\r\n    Url: https://ThisIsNotUsed\r\n    InstallerType: msstore\r\n    ProductId: 9WZDNCRFJ364\r\n    Language: en-US\r\n  - Arch: x64\r\n    Url: https://ThisIsNotUsed\r\n    InstallerType: msstore\r\n    ProductId: 9WZDNCRFJ364\r\n    Language: fr-FR\r\n  - Arch: arm\r\n    Url: https://ThisIsNotUsed\r\n    InstallerType: msstore\r\n    ProductId: 9WZDNCRFJ364\r\n    Language: en-US\r\n  - Arch: arm\r\n    Url: https://ThisIsNotUsed\r\n    InstallerType: msstore\r\n    ProductId: 9WZDNCRFJ364\r\n    Language: fr-FR\r\n  - Arch: x64\r\n    Url: https://ThisIsNotUsed\r\n    InstallerType: msstore\r\n    ProductId: 9WZDNCRFJ364\r\n    Language: ja-JP\r\n  - Arch: arm64\r\n    Url: https://ThisIsNotUsed\r\n    InstallerType: msstore\r\n    ProductId: 9WZDNCRFJ364\r\n    Language: en-US\r\nManifestVersion: 0.2.0-msstore\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ImportFile-Bad-Invalid.json",
    "content": "\"A valid JSON file that does not conform to the schema\""
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ImportFile-Bad-Malformed.json",
    "content": "This is not a valid JSON file."
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ImportFile-Bad-UnknownPackage.json",
    "content": "{\n  \"$schema\": \"https://aka.ms/winget-packages.schema.1.0.json\",\n  \"CreationDate\": \"2021-01-01T12:00:00.000-00:00\",\n  \"Sources\": [\n    {\n      \"Packages\": [\n        {\n          \"Id\": \"AppInstallerCliTest.TestExeInstaller\",\n          \"Version\": \"2.0.0.0\"\n        },\n        {\n          \"Id\": \"MissingPackage\",\n          \"Version\": \"1.0.0.0\"\n        }\n      ],\n      \"SourceDetails\": {\n        \"Argument\": \"//arg\",\n        \"Identifier\": \"*TestSource\",\n        \"Name\": \"TestSource\",\n        \"Type\": \"Microsoft.TestSource\"\n      }\n    }\n  ],\n  \"WinGetVersion\": \"1.0.0\"\n}"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ImportFile-Bad-UnknownPackageVersion.json",
    "content": "{\n  \"$schema\": \"https://aka.ms/winget-packages.schema.1.0.json\",\n  \"CreationDate\": \"2021-01-01T12:00:00.000-00:00\",\n  \"Sources\": [\n    {\n      \"Packages\": [\n        {\n          \"Id\": \"AppInstallerCliTest.TestExeInstaller\",\n          \"Version\": \"4.3.2.1\"\n        }\n      ],\n      \"SourceDetails\": {\n        \"Argument\": \"//arg\",\n        \"Identifier\": \"*TestSource\",\n        \"Name\": \"TestSource\",\n        \"Type\": \"Microsoft.TestSource\"\n      }\n    }\n  ],\n  \"WinGetVersion\": \"1.0.0\"\n}"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ImportFile-Bad-UnknownSource.json",
    "content": "{\n  \"$schema\": \"https://aka.ms/winget-packages.schema.1.0.json\",\n  \"CreationDate\": \"2021-01-01T12:00:00.000-00:00\",\n  \"Sources\": [\n    {\n      \"Packages\": [\n        {\n          \"Id\": \"AppInstallerCliTest.TestExeInstaller\",\n          \"Version\": \"1.0.0.0\"\n        }\n      ],\n      \"SourceDetails\": {\n        \"Argument\": \"//bad\",\n        \"Identifier\": \"*BadSource\",\n        \"Name\": \"TestSource\",\n        \"Type\": \"Microsoft.TestSource\"\n      }\n    }\n  ],\n  \"WinGetVersion\": \"1.0.0\"\n}"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ImportFile-Good-AlreadyInstalled.json",
    "content": "{\n  \"$schema\": \"https://aka.ms/winget-packages.schema.1.0.json\",\n  \"CreationDate\": \"2021-01-01T12:00:00.000-00:00\",\n  \"Sources\": [\n    {\n      \"Packages\": [\n        {\n          \"Id\": \"AppInstallerCliTest.TestExeInstaller\",\n          \"Version\": \"1.0.0.0\"\n        }\n      ],\n      \"SourceDetails\": {\n        \"Argument\": \"//arg\",\n        \"Identifier\": \"*TestSource\",\n        \"Name\": \"TestSource\",\n        \"Type\": \"Microsoft.TestSource\"\n      }\n    }\n  ],\n  \"WinGetVersion\": \"1.0.0\"\n}"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ImportFile-Good-Dependencies.json",
    "content": "{\n  \"$schema\": \"https://aka.ms/winget-packages.schema.1.0.json\",\n  \"CreationDate\": \"2021-01-01T12:00:00.000-00:00\",\n  \"Sources\": [\n    {\n      \"Packages\": [\n        {\n          \"Id\": \"AppInstallerCliTest.TestExeInstaller.Dependencies\",\n          \"Version\": \"2.0.0.0\"\n        },\n        {\n          \"Id\": \"AppInstallerCliTest.TestMsixInstaller.WFDep\",\n          \"Version\": \"1.0.0.0\"\n        }\n      ],\n      \"SourceDetails\": {\n        \"Argument\": \"//arg\",\n        \"Identifier\": \"*TestSource\",\n        \"Name\": \"TestSource\",\n        \"Type\": \"Microsoft.TestSource\"\n      }\n    }\n  ],\n  \"WinGetVersion\": \"1.0.0\"\n}"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ImportFile-Good-MachineScope.json",
    "content": "{\r\n  \"$schema\": \"https://aka.ms/winget-packages.schema.1.0.json\",\r\n  \"CreationDate\": \"2021-01-01T12:00:00.000-00:00\",\r\n  \"Sources\": [\r\n    {\r\n      \"Packages\": [\r\n        {\r\n          \"Id\": \"TestExeInstallerWithNothingInstalled\",\r\n          \"Version\": \"1.0.0.0\",\r\n          \"Scope\": \"machine\"\r\n        }\r\n      ],\r\n      \"SourceDetails\": {\r\n        \"Argument\": \"//arg\",\r\n        \"Identifier\": \"*TestSource\",\r\n        \"Name\": \"TestSource\",\r\n        \"Type\": \"Microsoft.TestSource\"\r\n      }\r\n    }\r\n  ],\r\n  \"WinGetVersion\": \"1.0.0\"\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ImportFile-Good-WithLicenseAgreement.json",
    "content": "{\n  \"$schema\": \"https://aka.ms/winget-packages.schema.1.0.json\",\n  \"CreationDate\": \"2021-01-01T12:00:00.000-00:00\",\n  \"Sources\": [\n    {\n      \"Packages\": [\n        {\n          \"Id\": \"TestInstallerWithLicenseAgreement\",\n          \"Version\": \"3.0.0.0\"\n        }\n      ],\n      \"SourceDetails\": {\n        \"Argument\": \"//arg\",\n        \"Identifier\": \"*TestSource\",\n        \"Name\": \"TestSource\",\n        \"Type\": \"Microsoft.TestSource\"\n      }\n    }\n  ],\n  \"WinGetVersion\": \"1.0.0\"\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ImportFile-Good.json",
    "content": "{\n  \"$schema\": \"https://aka.ms/winget-packages.schema.1.0.json\",\n  \"CreationDate\": \"2021-01-01T12:00:00.000-00:00\",\n  \"Sources\": [\n    {\n      \"Packages\": [\n        {\n          \"Id\": \"AppInstallerCliTest.TestExeInstaller\",\n          \"Version\": \"2.0.0.0\"\n        },\n        {\n          \"Id\": \"AppInstallerCliTest.TestMsixInstaller\",\n          \"Version\": \"2.0.0.0\"\n        }\n      ],\n      \"SourceDetails\": {\n        \"Argument\": \"//arg\",\n        \"Identifier\": \"*TestSource\",\n        \"Name\": \"TestSource\",\n        \"Type\": \"Microsoft.TestSource\"\n      }\n    }\n  ],\n  \"WinGetVersion\": \"1.0.0\"\n}"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InputARPData.txt",
    "content": "﻿XP890ZFCZZR294|Studio Fisioterapico Pro|Esposito Software di M. G. Caputo|Studio Fisioterapico Pro Demo||Copyright Esposito Software|Studio Fisioterapico Pro Demo_is1\r\nXP89DCGQ3K6VLD|Microsoft PowerToys|Microsoft Corporation|PowerToys (Preview) x64|0.57.0|Microsoft Corporation|{582f7a19-045d-43d4-89bf-7f8e9479311c}\r\nXP89HZ8SVWTT0M|ElevenClock|Martí Climent|ElevenClock version 3.3.2|3.3.2|SomePythonThings|{D62480B8-71F1-48CE-BEEC-9D3E172C87B5}_is1\r\nXP89HZKG342W76|POWER-KI GUI Client|XPLAB - Research in Automation|POWER-KI GUI|33.11|XPLAB - Research in Automation - Brescia - Italy|{0760E097-F794-4836-9941-8846EA43BE06}\r\nXP89J5462CMGJD|Apache OpenOffice|The Apache Software Foundation|OpenOffice 4.1.11|4.111.9808|Apache Software Foundation|{D2F124FC-5373-4A4A-8C5A-61052A3D34CA}\r\nXP8BTFNM0T53BJ|PolypopLive|Simmetri, Inc.|PolyPop 0.98.222.0|0.98.222.0|Simmetri, Inc.|{75454996-E72B-480E-BB8C-CD743A54C362}_is1\r\nXP8BX12N1KK2QJ|MyLifeOrganized - To-Do List|Andriy Tkachuk|MyLifeOrganized v. 5.1.3|5.1.3|MyLifeOrganized.net|MyLife Organized\r\nXP8CD7JST163BL|BPM Counter|Abyssmedia.com|BPM Counter 3.8.0.0|3.8.0.0|AbyssMedia.com|BPM Counter_is1\r\nXP8CDF4CV9XP5Q|Archivio Esami Clinici|Esposito Software di M. G. Caputo|Archivio Esami Clinici 3.0 Demo||Copyright Esposito Software|Archivio Esami Clinici 3.0 Demo_is1\r\nXP8CF6SB8MX31V|Ashampoo Photo Optimizer 8|Ashampoo|Ashampoo Photo Optimizer 8|8.2.3|Ashampoo GmbH & Co. KG|{91B33C97-5FC6-8971-3444-C57BBE022215}_is1\r\nXP8JJ8VX6VL0Q5|Cleaner One Pro - Free PC Cleaner|Trend Micro Inc.|Cleaner One Pro 6.6.0|6.6.0|Trend Micro, Inc.|99388cc2-2782-5495-bbd2-525df2487901\r\nXP8JJRV6TV79LG|DiskZIP|ZIPmagic Software|DiskZIP|2022.3.1415.932|DiskZIP Computing, Inc.|DiskZIP\r\nXP8JJVZXG23JLN|WorldClock.Classic.ScreenSaver|Fulvio Castelli|WorldClock Screen Saver (Trial)|7.0.12.0|Fulvio Castelli|{EF3BC641-89A9-4703-9DED-19CEE72CEF07}_is1\r\nXP8JK4HZBVF435|Auto Dark Mode|Armin Osaj|Auto Dark Mode|10.1.0.10|Armin Osaj & Samuel Schiegg|{470BC918-3740-4A97-9797-8570A7961130}_is1\r\nXP8JMKMC3GVX23|Wondershare EdrawMax|WONDERSHARE GLOBAL LIMITED|Wondershare EdrawMax(Build 11.1.2.870)|11.1.2.870|EdrawSoft Co.,Ltd.|{037BAB81-3DF7-4381-A72C-A26B57C03548}_is1\r\nXP8JNNTH0LT9F1|ApowerEdit|网旭科技|ApowerEdit V1.7.7.22|1.7.7.22|Apowersoft LIMITED|{3089CCCD-BC5F-4309-A3C1-45B5ACA7A5E7}_is1\r\nXP8K17KD2T7W8V|Ashampoo WinOptimizer 19|Ashampoo|Ashampoo WinOptimizer 19|19.00.23|Ashampoo GmbH & Co. KG|{4209F371-A9E3-7DD2-C1E5-04BB2B081219}_is1\r\nXP8K1F4KDP9DSJ|Autonoleggio N.S.C.|Esposito Software di M. G. Caputo|Autonoleggio NSC 3.0 Demo||Copyright Esposito Software|Autonoleggio NSC 3.0 Demo_is1\r\nXP8K43JX54F7FL|Cute Cursors|Cute Cursors|CuteCursors|1.0.0|Apollo One|{6683BBFB-B899-4755-B260-DF0387D9F872}\r\nXP8K513CFB5K58|Archivio Dipendenti con Foto|Esposito Software di Maria Grazia Caputo|Archivio Dipendenti con Foto Demo||Copyright Esposito Software|Archivio Dipendenti con Foto Demo_is1\r\nXP8LFCZM790F6B|Visual Studio Code - Insiders|Microsoft Corporation|Microsoft Visual Studio Code Insiders (User)|1.67.0|Microsoft Corporation|{217B4C08-948D-4276-BFBB-BEE930AE5A2C}_is1\r\nXP8LFD92C0T8P0|Stampa Tessere Associazioni|Esposito Software di Maria Grazia Caputo|Stampa Tessere Associazioni 5.0 Demo||Copyright Esposito Software|Stampa Tessere Associazioni 5.0 Demo_is1\r\nXP8LG1VTM0XW03|Gestione Protocollo e Pratiche|Esposito Software di Maria Grazia Caputo|Gestione Protocollo e Pratiche Demo||Copyright Esposito Software|Gestione Protocollo e Pratiche Demo_is1\r\nXP8LG2X182JTJ9|Wondershare Dr.Fone - Mobile Device Management|WONDERSHARE GLOBAL LIMITED|Wondershare Dr.Fone (Version 10.9.6)|10.9.6.398|Wondershare Technology Co.,Ltd.|{E8F86DA8-B8E4-42C7-AFD4-EBB692AC43FD}_is1\r\nXP8LG65GV4C7C8|GitMind Mind Map|网旭科技|GitMind 1.0.8|1.0.8|Apowersoft|a0e10d84-6512-552f-a0ec-5dd2e61ffe64\r\nXP8LKPZT4X0Z0P|GOM Player|Gom and Company|GOM Player|2.3.67.5331|GOM & Company|GOM Player\r\nXP8LKWQ22DX3TF|JYL Visitor Windows|JYL Software|JYL Visitor 1.94|1.94|JYL Software|{02ADFF54-7D56-42F1-B517-FDA35F55D2CC}\r\nXP99J3KP4XZ4VV|ZOOM Cloud Meetings|Zoom Video Communications, Inc.|Zoom|5.10.0 (4306)|Zoom Video Communications, Inc.|ZoomUMX\r\nXP99J7FXZD0JDM|Emjysoft eSanté|Emjysoft|Suivi des soins et des remboursements de Santé|3.11|Emjysoft|{6CC28634-D98C-4DE1-9EE7-E121277996F6}_is1\r\nXP99JXDBM4XKFP|Parallels Toolbox|Corel Corporation|Parallels Toolbox|5.1.0.3170|Parallels International GmbH|{5145E2CF-E9FC-48E6-A2B4-E409FC84D059}\r\nXP99K41V2P36RQ|MSIX Editor|InstallAware Software Corporation|InstallAware Msix Editor 1.0|1.0.0.2703|InstallAware Software|InstallAware Msix Editor 1.0\r\nXP99VR1BPSBQJ2|Epic Games Store|Epic Games Inc.|Epic Games Launcher|1.3.23.0|Epic Games, Inc.|{FAC47927-1A6A-4C6E-AD7D-E9756794A4BC}\r\nXP99WSCKQSH7SW|Emjysoft Sauvegarde Facile|Emjysoft|Easy Backup|VersionApplication|Emjysoft|{37215B1A-1990-4F55-936E-C9BA1634EF75}}_is1\r\nXP99WT9NMGB1PN|蜜蜂剪辑|网旭科技|BeeCut V1.7.7.22|1.7.7.22|Apowersoft LIMITED|{CA76BFA8-1862-49D7-B2C7-AE3D6CF40E53}_is1\r\nXP9B0HTG55KTCH|Free Hex Editor Neo|HHD Software Ltd.|HHD Software Free Hex Editor Neo 6.54|6.54.02.6790|HHD Software, Ltd.|{8EB85C0E-DE7D-4A53-BD66-708B8F2C80B0}\r\nXP9B16C2TFN8P1|GOM Mix Pro|Gom and Company|GOM Mix Pro|2.0.4.8|GOM & Company|GOMMixPro\r\nXP9CFZ9PKV0DWS|Automation Workshop|Febooti, SIA|Febooti Automation Workshop|5.1.1.0|Febooti Software|{6114DD12-2516-4465-9275-FB9A8E1A583C}\r\nXP9CRZD7D219NK|FolderSizes|Key Metric Software|FolderSizes 9|9.3.362|Key Metric Software|{587D3069-EFE1-4FC2-B917-01496D5ABF8A}\r\nXP9CRZQDCJ0CC6|LetsView|网旭科技|LetsView V1.1.2.5|1.1.2.5|LetsView LIMITED|{6AA74BE4-9506-4D81-A07C-A40F883C2EA7}_is1\r\nXP9CSP03RV8BX9|Audials One 2022|Audials AG|Audials 2022|22.0.177.0|Audials AG|{3F273072-3D14-479E-B4CD-AC8B1F436DA1}\r\nXP9K4SR87H227Q|VisualNEO Win|SinLios Soluciones Digitales|VisualNEO Win|21.9.9|SinLios|{57147D4D-2492-41EC-A552-FB37C1C7FF3E}_is1\r\nXP9K5VRXFHVP75|Database Creator|Esposito Software di Maria Grazia Caputo|Database Creator Demo||Copyright Esposito Software|Database Creator Demo_is1\r\nXP9K5XN9BRN466|Housecall Free Virus - Malware Scanner|Trend Micro Inc.|HouseCall|1.62|Trend Micro Inc.|{A114E34B-AA5C-4DD8-98A9-3130ACA19491}\r\nXP9KHKZS1M19ZP|x-studio|Simdsoft Limited|x-studio 2022|2022.1.4|Simdsoft Limited|{2F7387D3-EB5F-4CA5-8C42-04C59F922740}\r\nXP9KHM4BK9FZ7Q|Visual Studio Code|Microsoft Corporation|Microsoft Visual Studio Code (User)|1.66.0|Microsoft Corporation|{771FD6B0-FA20-440A-A002-3B3BAC16DC50}_is1\r\nXP9KHPQ5C9MSN2|ZIPmagic|ZIPmagic Software|ZIPmagic|19.19.21|Simon King|ZIPmagic\r\nXP9KHPXMW6RQLL|Gestione Studio Tecnico|Esposito Software di M. G. Caputo|Gestione Studio Tecnico Demo||Copyright Esposito Software|Gestione Studio Tecnico Demo_is1\r\nXP9KHQZV691PF9|PTZ Link|AVer Information|AVer PTZ Link|1.1.1013.0|AVer Information Inc|{AC08D179-14D5-4B93-9684-20DBE0848637}\r\nXP9KM2X7H10448|PCmover Reconfigurator|Laplink Software Inc|Laplink Reconfigurator|1.0.0.1|Laplink Software, Inc.|{BBB86720-65BA-452A-A14D-B152CB506DD8}\r\nXP9M20CZB2C5W8|Powder - Gaming Recorder|Unique Entertainment Experience SAS|Powder 2.5.0|2.5.0|powder-team|2b39bc52-9c37-5fcd-ab25-906727f7c690\r\nXP9MFNDJM19N0G|Gestione Affitti Pro|Esposito Software di M. G. Caputo|Gestione Affitti Pro 4.0 Demo||Copyright Esposito Software|Gestione Affitti Pro 4.0 Demo_is1\r\nXPDBZ0BW87BCTV|POWER-KI Executor|XPLAB - Research in Automation|POWER-KI Executor|33.11|XPLAB  - Research in Automation - Brescia - Italy|{B2B40FB5-0B60-4B47-A1F1-F0254CD0BE04}\r\nXPDBZ4MPRKNN30|Opera GX|Opera Norway AS|Opera GX Stable 82.0.4227.44|82.0.4227.44|Opera Software|Opera GX 82.0.4227.44\r\nXPDC1LX9VNW7Z7|VirtualDJ|Atomix International, S.A.|VirtualDJ 2021|8.5.6747.0|Atomix Productions|{97CFEA35-98EF-4EBC-8AF1-4F161CFCAE86}\r\nXPDC2KHD93HVJW|Stampa Ricevute Generiche|Esposito Software di Maria Grazia Caputo|Stampa Ricevute Generiche Demo||Copyright Esposito Software|Stampa Ricevute Generiche Demo_is1\r\nXPDCFJD1GFFDXD|WorldClock.Classic|Fulvio Castelli|WorldClock (Trial)|7.0.12.0|Fulvio Castelli|{E32193B9-8870-40be-B88A-B302251B8AA7}_is1\r\nXPDCJ80KGNRVSS|TeamSpeak|TeamSpeak Systems GmbH|TeamSpeak|5.0.0|TeamSpeak|{C9D97E1E-B188-4500-A87D-902530E0D1E0}\r\nXPDCK0XGHVWNBK|Trend Micro Antivirus Plus Security|Trend Micro Inc.|Trend Micro Antivirus+|17.7|Trend Micro Inc.|{ABBD4BA8-6703-40D2-AB1E-5BB1F7DB49A4}\r\nXPDDZ434WT2M5Z|SOLARWATT Pro experience|SOLARWATT GmbH|SOLARWATT Experience|2.1.0.4|SOLARWATT|{40CF234F-1D35-4ED8-AAFC-E07EA2FD8B3B}\r\nXPDF9J69VVFMX3|Apowersoft Background Eraser|网旭科技|Apowersoft background eraser V2.3.13|2.3.13|Apowersoft LIMITED|{98EC0F66-C563-40FA-A77A-F2FC558F5DAA}_is1\r\nXPDFF6P40P0M5Q|星愿浏览器|Twinkstar|Twinkstar Browser|7.12.1000.2112|Twinkstar Limited|Twinkstar\r\nXPDLNG5248Q7NC|HttpMaster Express|Borvid, Informacijske storitve, Janez Čas s.p.|HttpMaster Express Edition 5.4.1|5.4.1|Borvid|{B61241AA-F5FC-42C9-A1F9-F6D72D654349}\r\nXPDM19SX6D8V40|JYL Orders Suppliers Windows|JYL Software|JYL Order Suppliers 1.70|1.70|JYL Software|{57DF6E60-F6E4-498F-9637-18D6C0FA08B9}\r\nXPDM4ZR5KJ9JN9|PowerDirector 365 Free - Video Editor, Movie Maker|CyberLink Corp.|CyberLink PowerDirector 365|20.1.2519.0|CyberLink Corp.|{278A8296-12A6-4CD0-8A8E-6947948477C5}\r\nXPDM5Q9J9SFCX9|Stampa Ricevute Pagamento|Esposito Software di M. G. Caputo|Stampa Ricevute Pagamento Demo||Copyright Esposito Software|Stampa Ricevute Pagamento Demo_is1\r\nXPDNG54ZDC79K0|JYL Time Clock Windows|JYL Software|JYL Time Clock 2.22|2.22|JYL Software|{839FD23A-EFE9-4252-AF1A-B8B56ED925F4}\r\nXPDNH1FMW7NB40|火绒安全软件|Beijing Huorong Network Technology Co., Ltd.|Huorong Internet Security|5.0|Beijing Huorong Network Technology Co., Ltd.|HuorongSysdiag\r\nXPDNLQK867NNXF|Ashampoo ZIP Pro 4|Ashampoo|Ashampoo ZIP Pro 4|4.10.22|Ashampoo GmbH & Co. KG|{0A11EA01-1F01-7AF6-20A2-E6F8131AD29C}_is1\r\nXPDNXDPXBRSVXT|WinZip 26|WinZip Computing|WinZip 26.0|26.0.15033|Corel Corporation|{CD95F661-A5C4-44F5-A6AA-ECDD91C2413F}\r\nXPDNXG5333CSVK|Hard Disk Sentinel Professional|Janos Mathe|Hard Disk Sentinel PRO|6.01|Janos Mathe|Hard Disk Sentinel_is1\r\nXPDNZ9TPLKW6TB|Fy Slideshow|Guutara's Notebook|Fy Slideshow|5.6.0|Guutara|{5A4DEC47-8784-4591-983F-A3A6C3C89A46}\r\nXPDNZJFNCR1B07|Avast Free Antivirus|AVAST  Software|Avast Free Antivirus|22.2.6003|Avast Software|Avast Antivirus\r\nXPDP1XPZR8NL28|Studio Medico Pro|Esposito Software di M. G. Caputo|Studio Medico Pro 3.0 Demo||Copyright Esposito Software|Studio Medico Pro 3.0 Demo_is1\r\nXPDP255TRF9WP8|Logspire|Anfibia Software|Logspire 1.0.0.51|1.0.0.51|Anfibia|Logspire_is1\r\nXPDP2X1MMZ4KR8|Ashampoo Burning Studio 23|Ashampoo|Ashampoo Burning Studio 23|23.0.5|Ashampoo GmbH & Co. KG|{91B33C97-2A56-F111-077E-E591CE9D7DE7}_is1\r\nXPFCFBB4FB3D6D|Emjysoft Cleaner|Emjysoft|Emjysoft Cleaner 2022 v4.1|4.1|Emjysoft|{167B1302-A739-42DE-BBD2-4C2F13D1FF51}_is1\r\nXPFCFKCNNTXGQD|Yandex Browser|Yandex|Yandex|21.9.1.686|ООО «ЯНДЕКС»|YandexBrowser\r\nXPFCFL5ZTNFGD7|Wondershare Anireel|WONDERSHARE GLOBAL LIMITED|Wondershare Anireel(Build 1.6.2)||Wondershare Software|Wondershare Anireel_is1\r\nXPFCG86X2PGLDJ|Christmas Elf by Pothos|Pothos|Christmas Elf|||ChristmasElf\r\nXPFCGHHXNH4WBW|Biblioteca e Prestiti Librari|Esposito Software di M. G. Caputo|Gestione Biblioteca e Prestiti Librari 3.0 Demo||Copyright Esposito Software|Gestione Biblioteca e Prestiti Librari 3.0 Demo_is1\r\nXPFCWP0SQWXM3V|CCleaner|Piriform Software Ltd|CCleaner|5.89|Piriform|CCleaner\r\nXPFCXFRDJ8VGPT|Домашняя Бухгалтерия|Keepsoft|Äîìàøíÿÿ áóõãàëòåðèÿ Lite|7.2|Keepsoft|Äîìàøíÿÿ áóõãàëòåðèÿ Lite\r\nXPFCXPF18WNKP6|Total Defense Essential Anti-Virus|Total Defense, Inc.|Total Defense|13.0.0.572|Total Defense, Inc.|TotalDefense\r\nXPFCXS0QVTHDC9|Active@ Disk Editor|LSoft Technologies Inc.|Active@ Disk Editor 7|7|LSoft Technologies Inc|{F40165C8-BD5B-4E42-A40D-396BB707E5B7}_is1\r\nXPFD27PCFQJQ68|TextSeek|Xiamen Zesite Company|TextSeek|2.12.3060|Zesite Company|TextSeek\r\nXPFD28MTCS0GXJ|VisualNEO Web|SinLios Soluciones Digitales|VisualNeoWeb||SinLios|{EEF9B1C5-7E35-4972-A79A-44B2B2C72D3D}_is1\r\nXPFFBRXVQ2L6JN|Coolnew PDF|CoolNewPDF|CoolNew PDF|3.0.0.1|CoolNew Software Corporation|coolnewpdf\r\nXPFFC9N4PVM9N8|Prenotazione Tavoli OK|Esposito Software di Maria Grazia Caputo|Prenotazione Tavoli OK Demo||Copyright Esposito Software|Prenotazione Tavoli OK Demo_is1\r\nXPFFCCM235X204|Fy Memo|Guutara's Notebook|Fy Memo|6.5.0|Guutara|{4BDAE26E-3414-4516-89F9-B6C277029CA5}\r\nXPFFCM599XXT5P|傲软录屏|网旭科技|ApowerREC V1.5.5.18|1.5.5.18|Apowersoft LIMITED|{6F2998B2-21F7-4CEF-94B2-C3919D939CF9}_is1\r\nXPFFH5S3C4Q1CB|傲软抠图|网旭科技|Apowersoft background eraser V2.3.13|2.3.13|Apowersoft LIMITED|{98EC0F66-C563-40FA-A77A-F2FC558F5DAA}_is1\r\nXPFFSV0VCDKTM5|PolicyApplicator Conversion Kit|Hauke Hasselberg|PolicyApplicator Conversion Kit|1.0.11.0|Hauke Götze|{C918DB43-6B86-4364-BEAC-1184D3EE3C07}\r\nXPFFT29L5QQ7RL|SRPG Studio|SapphireSoft|SRPG Studio Trial version 1.251|1.251|SapphireSoft|{FBC98908-FD84-4C92-A539-5DA61EDD7F9F}_is1\r\nXPFFT3RD5FMWX2|Emjysoft Comptabilité Personnelle|Emjysoft|Personal Finance|20.5|Emjysoft|{2369DC9E-11A7-4BAE-A43E-7A4CB477574F}_is1\r\nXPFFTPNN0NNHVQ|Auto Print Order|NAMTUK|AutoPrintOrder 1.10.1215|1.10.1215|Namtuk|{B26EF0DD-2375-4E88-9991-4652AC89FE3F}\r\nXPFM2BJ3RPZ9XB|轻闪PDF编辑|网旭科技|LightPDF Editor V1.2.6.0|1.2.6.0|Apowersoft LIMITED|{161C8BF4-DB06-49A7-B6AC-7CAB7DAF136F}_is1\r\nXPFM306TS4PHH5|Ashampoo Burning Studio FREE|Ashampoo|Ashampoo Burning Studio FREE|1.21.5|Ashampoo GmbH & Co. KG|{91B33C97-91F8-FFB3-581B-BC952C901685}_is1\r\nXPFM5W1J84KQZX|ndCurveMaster|SigmaLab Tomasz Cepowski|ndCurveMaster Trial x64 version 8.2.0.1|8.2.0.1|SigmaLab|{5FB2948C-B95A-49CD-A2ED-62D0A38D7B1C}_is1\r\nXPFMJGWHHCNL5P|傲软投屏—手机/电脑/电视高清投屏神器|网旭科技|ApowerMirror V1.6.5.1|1.6.5.1|APOWERSOFT LIMITED|{a9482532-9c34-478c-80c3-85bdccbb981f}_is1\r\nXPFMKKKLHMMK6Q|Videoteca OK|Esposito Software di Maria Grazia Caputo|Videoteca OK 5.0 Demo||Copyright Esposito Software|Videoteca OK 5.0 Demo_is1\r\nXPFNZJKG6100L4|ASM Visual|gri-software|ASM Visual version 1.1.7|1.1.7|gri-software|{7416EF27-89A5-4819-9996-36C16F49BAEC}_is1\r\nXPFNZKDRP1SXM6|视频转换王|网旭科技|Apowersoft Video Converter Studio V4.8.6.7|4.8.6.7|APOWERSOFT LIMITED|{195E8D7F-292B-4B04-A6E7-E96CAF04C767}_is1\r\nXPFP0G0V147H6D|Wondershare PDFelement|WONDERSHARE GLOBAL LIMITED|Wondershare PDFelement ( Version 8.3.0 )|8.3.0|Wondershare|{343A530C-4726-4091-87E0-F9CC41792CE2}_is1\r\nXPFP2VCXM8D2DB|傲软PDF编辑——一键编辑&转化&压缩&签名PDF文件|网旭科技|ApowerPDF V5.4.2.3|5.4.2.3|Apowersoft LIMITED|{8691C793-7B2C-46C5-9AB2-AB80D129A5EC}_is1\r\nXPFP30KL61D4SC|Wondershare UniConverter|WONDERSHARE GLOBAL LIMITED|Wondershare UniConverter 13(Build 13.5.1.116)|13.5.1.116|Wondershare Software|UniConverter 13_is1\r\nXPFP42D8L456SK|X-VPN - Best VPN Proxy and Wifi Security|Free Connected Limited.|X-VPN|71.0|Free Connected Limited|X-VPN\r\nXPFP42J061BPC1|Documenti Lavori Cantiere|Esposito Software di M. G. Caputo|Documenti Lavori Cantiere Demo||Copyright Esposito Software|Documenti Lavori Cantiere Demo_is1\r\nXPFPFN4LT21PZJ|Studio Dentistico Pro|Esposito Software di M. G. Caputo|Studio Dentistico Pro Demo||Copyright Esposito Software|Studio Dentistico Pro Demo_is1\r\nXPFPFWMVTR0WHP|Ashampoo UnInstaller 11|Ashampoo|Ashampoo UnInstaller 11|11.00.12|Ashampoo GmbH & Co. KG|{4209F371-B84B-F321-6BD3-1D91E2505732}_is1\r\nXPFPFWV5JD80K2|BeeCut|网旭科技|BeeCut V1.7.7.22|1.7.7.22|Apowersoft LIMITED|{CA76BFA8-1862-49D7-B2C7-AE3D6CF40E53}_is1\r\nXPFPLCB36G8V8J|HttpMaster Professional|Borvid, Informacijske storitve, Janez Čas s.p.|HttpMaster Professional Edition 5.4.1|5.4.1|Borvid|{B61241AA-F5FC-42C9-A1F9-F6D72D654349}\r\nXP8CDJNZKFM06W|Visual Studio Community 2019|Microsoft Corporation|Microsoft Visual Studio Installer|3.1.2196.8931|Microsoft Corporation|{6F320B93-EE3C-4826-85E0-ADF79F8D4C61}"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InputNames.txt",
    "content": "0 A.D.\n010 Editor 11.0 (64-bit)\n360安全卫士\n360杀毒\n4K Slideshow Maker 1.8\n4K Stogram\n4K Video Downloader\n4K Video Downloader 4.12\n4K Video to MP3\n4K YouTube to MP3 3.12\n7-Zip 16.04 (x64 edition)\n7-Zip 19.00 (x64 edition)\n7-Zip 20.02 alpha (x64)\n7-Zip ZS 19.00 ZS v1.4.5 R2 (x64)\nAWS Command Line Interface\nAWS Command Line Interface v2\nAWS SAM Command Line Interface\nAXIS Camera Station 5.33\nAbaClient\nAccessibility Insights For Windows v1.1\nActive Directory Authentication Library for SQL Server\nAdobe Acrobat Reader DC - Czech\nAdobe Acrobat Reader DC\nAdobe Acrobat Reader DC MUI\nAdoptOpenJDK JDK with Hotspot 11.0.7.10 (x64)\nAdoptOpenJDK JDK with Hotspot 11.0.8.10 (x64)\nAdoptOpenJDK JDK with Hotspot 14.0.1.7 (x64)\nAdoptOpenJDK JDK with Hotspot 14.0.2.12 (x64)\nAdoptOpenJDK JDK with Hotspot 15.0.0.36 (x64)\nAdoptOpenJDK JDK with Hotspot 8.0.252.09 (x64)\nAdoptOpenJDK JDK with Hotspot 8.0.265.01 (x64)\nAdvanced IP Scanner 2.5\nAdvanced Log Viewer 8.1.0\nAdvanced Port Scanner 2.5\nAdvancedRestClient 15.0.5\nAegisub 8975-master-8d77da3\nAegisub r8942\nAeroZoom 4.0 beta 2\nAlacritty\nAlchemy Beta x64\nAlgodoo v2.1.0\nAltDrag\nAmazon Chime\nAmazon Corretto (x64)\nAmazon Corretto 8 (x64)\nAmazon WorkSpaces\nAnaconda3 2020.07 (Python 3.8.3 64-bit)\nAngry IP Scanner\nAntiMicro\nAppGet\nAppium 1.15.1\nAppium 1.18.3\nArduino\nArmagetron Advanced 0.2.8.3.5\nArtha 1.0.3.0\nAssaultCube 1.2.0.2\nAudacity 2.4.2\nAuthPass version 1.7.9_1605\nAuto Dark Mode\nAutoHotkey 1.1.32.00\nAutoHotkey 1.1.33.02\nAutopsy\nAviSynth 2.6\nAvro Keyboard 5.6.0\nAya\nAzure Cosmos DB Emulator\nAzure Data Studio (User)\nAzure Functions Core Tools - 3.0.2534 (x64)\nAzure IoT Explorer (preview)\nAzure IoT explorer\nBCUninstaller\nBITS Manager\nBKChem-0.13.0\nBOINC\nBPBible 0.5.3.1\nBackup and Sync from Google\nBarrier 2.3.2-snapshot\nBarrier 2.3.3-release\nBeaker Browser 0.8.10\nBeats winlogbeat 7.7.0 (x86_64)\nBeats winlogbeat 7.9.2 (x86_64)\nBeeBEEP 5.8.2\nBeeftext\nBetaflight Configurator\nBeyond Compare 4\nBeyond Compare 4.3.6\nBeyond Compare 4.3.7\nBiglyBT\nBitPay version 4.8.1\nBitwarden\nBleachBit 4.0.0.1628 (current user)\nBlender\nBlueJeans\nBob the Hamster VGA 2008-01-23\nBonjour\nBorderless Gaming\nBot Framework Composer 1.0.0\nBot Framework Composer 1.0.1\nBot Framework Composer 1.0.2\nBot Framework Composer 1.1.1\nBot Framework Emulator 4.10.0\nBot Framework Emulator 4.8.1\nBot Framework Emulator 4.9.0\nBrackets\nBrave\nBrave Nightly\nBulk Rename Utility 3.3.1.0 (64-bit)\nButtercup 1.19.0\nButtercup 1.20.0\nC-Dogs SDL\nCCEnhancer version 4.5.6\nCCleaner\nCDBurnerXP (64 bit)\nCMake\nCORSAIR iCUE Software\nCPUID CPU-Z 1.92\nCPUID CPU-Z 1.93\nCPUID CPU-Z 1.94\nCPUID HWMonitor 1.41\nCPUID HWMonitor 1.42\nCacher\nCaesiumPH 0.9.5\nCamtasia 2019\nCamtasia 2020\nCaprine 2.47.0\nCaprine 2.48.0\nCaption 2.0.1 (only current user)\nCaptura v8.0.0\nCemUI 2.3.3 (only current user)\nCerebro 0.3.2\nCertAid for Windows\nCertDump\nCertify The Web version 5.1.5\nChMac 2.0\nChefDK v4.11.0\nChemAxon ChemCurator\nChemAxon Markush Editor\nChemAxon Marvin Suite 20.13.0\nChemAxon Marvin Suite 20.19.0\nChromium\nCircuit Diagram version 3.0\nCircuit Diagram version 3.1\nCisco Webex Meetings\nCitycraft Launcher 1.9.9\nClamWin Free Antivirus 0.99.4\nClash for Windows 0.11.1\nClash for Windows 0.11.6\nClash for Windows 0.11.8\nClash for Windows 0.9.11\nClassIn\nClementine\nClink v0.4.9\nCloudflare WARP\nCodeBlocks\nCodeLite\nCoffee\nColobot: Gold Edition alpha-0.1.12\nColor Cop 5.4.3\nColorpicker 2.0.3\nConEmu 201011.x64\nConcept2 Utility\nConfigMgr 2012 Toolkit R2\nContasimple Desktop 3.1.0\nCore Temp 1.16\nCouchbase Server 6.5.1-6299 Community Edition\nCouchbase Server 6.5.1-6299 Enterprise Edition\nCozy Drive 3.20.0\nCppcheck x64 2.0\nCrypter 4.0.0\nCryptomator\nCrystalDiskInfo 8.6.1\nCrystalDiskInfo 8.6.2\nCrystalDiskInfo 8.6.2 Kurei Kei Edition\nCrystalDiskInfo 8.6.2 Shizuku Edition\nCrystalDiskInfo 8.7.0\nCrystalDiskInfo 8.8.1\nCrystalDiskInfo 8.8.1 Kurei Kei Edition\nCrystalDiskInfo 8.8.1 Shizuku Edition\nCrystalDiskInfo 8.8.5\nCrystalDiskInfo 8.8.9\nCrystalDiskInfo 8.8.9 Kurei Kei Edition\nCrystalDiskInfo 8.8.9 Shizuku Edition\nCrystalDiskInfo 8_8_2\nCrystalDiskInfo 8_8_2 Kurei Kei Edition\nCrystalDiskInfo 8_8_2 Shizuku Edition\nCrystalDiskMark 7.0.0h\nCrystalDiskMark 7.0.0h Shizuku Edition\nCubicSDR 0.2.5 Installer\nCutePDF Writer\nCyberduck\nDB Browser for SQLite\nDBeaver 7.0.5 (current user)\nDBeaver 7.1.0 (current user)\nDBeaver 7.1.2 (current user)\nDBeaver 7.1.3 (current user)\nDBeaver 7.1.4 (current user)\nDBeaver 7.2.0 (current user)\nDBeaver 7.2.1 (current user)\nDBeaver 7.2.2 (current user)\nDBeaver 7.2.3 (current user)\nDJI Assistant 2 (DJI FPV series) version V2.0.2.11\nDJI Assistant 2 For Aeroscope version V2.0.1.3\nDJI Assistant 2 For Autopilot version V2.0.3.7\nDJI Assistant 2 For Battery Station version V2.0.1.9\nDJI Assistant 2 For MG version V2.0.18.1\nDJI Assistant 2 For Matrice version V2.0.13.2\nDJI Assistant 2 For Mavic version V2.0.14.1\nDJI Assistant 2 For Phantom version V2.0.10.4\nDave Gnukem\nDeepVocalToolBox_beta_1.1.6 version beta_1.1.6\nDeepVocal_beta_1.1.6 version beta_1.1.6\nDeezer 4.19.20\nDefaultAudio\nDefraggler\nDell Command | Update\nDell Update\nDev-C++\nDimension 4 v5.31\nDiscord Media Loader version 1.3.0.0\nDiscord Media Loader version 1.4.0.0\nDitto\nDixa\nDjVuLibre DjView  3.5.27+4.11\nDockStation 1.5.1\nDocker Desktop\nDokan Library 1.3.0.1000 (x64)\nDokan Library 1.4.0.1000 (x64)\nDolphin\nDoomsday 2.2.2.3313\nDopamine\nDoxie 2.12.2\nDropbox\nEGR-SafenetActivation\nEGR-ShellExtension\nEagleGet version 2.1.5.10\nEagleGet version 2.1.6.70\nEasyConnect\nEditPlus (64 bit)\nEduMIPS64\nElasticsearch 7.9.2\nElgato Stream Deck\nEmpoche 0.4.0\nEmpoche 0.4.3\nEncrypto version 1.0.1\nEnglishizeCmd 2.0\nEnpass\nEraser 6.2.0.2986\nEraser 6.2.0.2988\nEraser 6.2.0.2989\nEraser 6.2.0.2990\nEsteem 2.2.7\nEthereum - Geth - Official Go implementation of the Ethereum protocol\nEvernote v. 6.21.2\nEvernote v. 6.24.2\nEverything 1.4.1.969 (x64)\nEverything 1.4.1.986 (x64)\nEverything 1.4.1.988 (x64)\nEverything 1.4.1.988 Lite (x64)\nEverything 1.4.1.992 (x64)\nExpressVPN\nExpresso\nExtreme TuxRacer 0.8 (x64)\nFar Manager 3 x64\nFastCopy\nFastStone Capture 9.3\nFastStone Image Viewer 7.5\nFedora Media Writer\nFerdi 5.5.0\nFiddler Everywhere 1.0.2\nFiddler Everywhere 1.1.0\nFiddler Everywhere 1.1.0-insiders\nFiddler Everywhere 1.1.0-internal\nFiddler Everywhere 1.1.1\nFiddler Everywhere 1.1.1-insiders\nFiddler Everywhere 1.1.1-internal\nFile Converter (64 bit)\nFileSeek 6.4\nFileZilla Client 3.47.0\nFileZilla Client 3.48.1\nFileZilla Client 3.49.1\nFileZilla Client 3.50.0\nFileZilla Client 3.51.0\nFirefox Developer Edition 77.0 (x64 en-US)\nFirefox Developer Edition 78.0 (x64 en-US)\nFirefox Developer Edition 80.0 (x64 en-US)\nFirefox Developer Edition 82.0 (x64 en-US)\nFlashFXP 5\nFlightGear v2018.3.5\nFontBase 2.11.3\nFontForge version 14-03-2020\nFormatFactory 5.3.0.1\nFormatFactory 5.4.5.0\nFoxit PhantomPDF\nFoxit Reader\nFranz 5.5.0\nFreeCommander XE\nFreeMat\nGIMP 2.10.0\nGIMP 2.10.10\nGIMP 2.10.14\nGIMP 2.10.16\nGIMP 2.10.18\nGIMP 2.10.20\nGIMP 2.10.6\nGIMP 2.10.8\nGNU Arm Embedded Toolchain 9-2020-q2-update 9 2020 (remove only)\nGNU Midnight Commander version 4.8.24 (build: 20200521-217)\nGNU Privacy Guard\nGNURadio-3.7\nGOG GALAXY\nGPL Ghostscript\nGSview 5.0\nGarmin Express\nGauge 1.0.6\nGauge 1.1.1\nGeany 1.36\nGeekbench 5\nGephi 0.9.2\nGetDiz\nGit Extensions 3.3.1.7897\nGit Extensions 3.4.1.9675\nGit Extensions 3.4.3.9999\nGit LFS version 2.11.0\nGit version 2.24.1.2\nGit version 2.25.1\nGit version 2.26.2\nGit version 2.27.0\nGit version 2.28.0\nGit version 2.29.0\nGitHub CLI\nGitHub Desktop Machine-Wide Installer\nGitHubReleaseNotes\nGitter\nGlimpse 0.1.2\nGlimpse 0.2.0 (64-bit)\nGlimpse 0.2.0\nGnuCash 3.9\nGnuCash 4.1\nGnuWin32: Grep-2.5.4\nGnuWin32: Make-3.81\nGnuWin32: Wget-1.11.4-1\nGnuWin32: Zip-3.0\nGo Programming Language amd64 go1.13.12\nGo Programming Language amd64 go1.13.13\nGo Programming Language amd64 go1.13.14\nGo Programming Language amd64 go1.13.15\nGo Programming Language amd64 go1.14.10\nGo Programming Language amd64 go1.14.3\nGo Programming Language amd64 go1.14.4\nGo Programming Language amd64 go1.14.5\nGo Programming Language amd64 go1.14.6\nGo Programming Language amd64 go1.14.7\nGo Programming Language amd64 go1.14.8\nGo Programming Language amd64 go1.14.9\nGo Programming Language amd64 go1.15\nGo Programming Language amd64 go1.15.1\nGo Programming Language amd64 go1.15.2\nGo Programming Language amd64 go1.15.3\nGo Programming Language amd64 go1.15beta1\nGoldWave v6.52\nGoogle Chrome\nGoogle Cloud SDK\nGoogle Earth Pro\nGpg4win (3.1.11)\nGpg4win (3.1.13)\nGrafanaEnterprise\nGrafanaOSS\nGrammarly for Microsoft® Office Suite\nGrampsAIO64\nGraphQL Playground 1.8.10\nGraphiQL 0.7.2\nGraphviz\nGreenshot 1.2.10.6\nGrid 1.6.2\nGrindstone 4\nHHD Software Free Hex Editor Neo 6.44\nHM NIS Edit 2.0.3\nHP Cloud Recovery Tool\nHUAWEI Cloud\nHWiNFO64 Version 6.26\nHWiNFO64 Version 6.28\nHWiNFO64 Version 6.30\nHWiNFO64 Version 6.32\nHandyWinGet\nHarmony 0.9.1 (only current user)\nHashTab 5.2.0.14\nHashTab 6.0.0.34\nHeavyLoad V3.6 (64 bit)\nHedgewars\nHeidiSQL 11.0.0.5919\nHeidiSQL 11.0.0.5995\nHeidiSQL 11.0.0.5997\nHeidiSQL 11.0.0.6000\nHeidiSQL 11.0.0.6057\nHelix Core Apps\nHelpNDoc 6.9.0.577 Personal Edition\nHexChat\nHosts File Editor\nHover\nHttpMaster Express Edition 4.7.0\nHttpMaster Express Edition 4.7.1\nHttpMaster Express Edition 4.7.2\nHttpMaster Express Edition 4.7.3\nHttpMaster Professional Edition 4.7.1\nHttpMaster Professional Edition 4.7.2\nHttpMaster Professional Edition 4.7.3\nHuawei QuickApp IDE\nHyne Timber Design 7.5.14.0\nHyperspace Desktop 1.1.3\nIAP Desktop\nIDA Freeware 7.0\nIO Ninja 3\nIPFilter 3.0.2.9-beta\nIRCCloud 0.15.0\nIZArc 4.4\nImageGlass\nInkscape\nInno Setup version 6.0.4\nInno Setup version 6.0.5\nInternetOff 3.0, 32\\64 bit edition\nIntuiter 0.5.0\nIrfanView 4.54 (64-bit)\nIronPython 2.7.10\nIronPython 2.7.9\nIsWiX\nIsoBuster 4.6\nJChem .NET API 20.19.0.482\nJabRef\nJackett\nJami\nJava 8 Update 251 (64-bit)\nJava 8 Update 261 (64-bit)\nJetBrains Toolbox\nJitsi Meet 2.3.1\nJitsi Meet 2.4.1\nJoplin 1.0.201\nJoplin 1.0.216\nJoplin 1.0.233\nJulia 1.4.1\nJulia 1.4.2\nJulia 1.5.1\nK-Lite Codec Pack 15.7.0 Standard\nK-Lite Mega Codec Pack 15.7.0\nKKBOX\nKaku 2.0.2\nKeePass Password Safe 2.44\nKeePass Password Safe 2.45\nKeePass Password Safe 2.46\nKeePassXC\nKeeWeb\nKeybase\nKiCad 5.1.5_1\nKiCad 5.1.6_1\nKiCad 5.1.7_1\nKrisp\nKrita (x64) 4.3.0\nL'Math version r1.6\nLBRY 0.45.1\nLBRY 0.45.2\nLBRY 0.46.2\nLBRY 0.47.0\nLBRY 0.47.1\nLINE\nLINQPad 6\nLLVM\nLMMS 1.2.1\nLMMS 1.2.2\nLOVE 11.3\nLaragon 4.0.15\nLastPass (uninstall only)\nLazarus 2.0.8\nLeague of Legends\nLenovo Migration Assistant\nLenovo System Update\nLens 3.5.1\nLeonflix 0.7.0\nLiberica JDK 11 (64-bit)\nLiberica JDK 11 Full (64-bit)\nLiberica JDK 14 (64-bit)\nLiberica JDK 14 Full (64-bit)\nLiberica JDK 15 (64-bit)\nLiberica JDK 15 Full (64-bit)\nLiberica JDK 8 (64-bit)\nLiberica JDK 8 Full (64-bit)\nLibreCAD\nLibreOffice 7.0.1.2\nLibreOffice 7.0.2.2\nLidarr version 0.7.1\nLightBulb 2.0\nLightBulb 2.2\nLightscreen version 2.4\nLinrad-04.14a version 04.14a\nLisk Hub 1.22.0\nListen1 2.13.0\nListen1 2.5.2\nLocal 5.5.3\nLockHunter 3.3, 32/64 bit\nLogFusion 6.4\nLogFusion 6.4.1\nLogitech Gaming Software 9.02\nLoom 0.37.2\nLyX 2.3.4.4\nLyX 2.3.5.2\nMCX Studio version nightlybuild\nMCX Studio version v2020\nMKVToolNix 46.0.0 (64-bit)\nMKVToolNix 47.0.0 (64-bit)\nMKVToolNix 48.0.0 (64-bit)\nMKVToolNix 49.0.0 (64-bit)\nMKVToolNix 50.0.0 (64-bit)\nMPC-HC 1.7.13 (64-bit)\nMPC-HC 1.9.5 (64-bit)\nMPC-HC 1.9.6 (64-bit)\nMQTT Explorer 0.3.5\nMSIX Core\nMX5\nMY.GAMES GameCenter\nMacType\nMailWasher\nMailWasherPro\nMajsoul Plus 2.0.0\nMakeMKV v1.15.3\nMalwarebytes version 4.2.1.89\nMarble version 2.2.0\nMariaDB 10.5 (x64)\nMark Text 0.16.2\nMarkdown Monster 1.22.8.0\nMarkdown Monster 1.23.0.0\nMarkdown Monster 1.23.12.0\nMarkdown Monster 1.23.14.0\nMarkdown Monster 1.24.12.0\nMarkdown Outlook\nMaster Packager\nMattermost\nMediaInfo 20.09\nMediaInfo-CLI 20.09\nMediaMonkey 4.1\nMeld\nMemurai Developer\nMicrosoft .NET Core SDK 3.1.202 (x64)\nMicrosoft .NET Core SDK 3.1.300 (x64)\nMicrosoft .NET Core SDK 3.1.301 (x64)\nMicrosoft .NET Core SDK 3.1.302 (x64)\nMicrosoft .NET Core SDK 3.1.401 (x64)\nMicrosoft .NET Core SDK 3.1.402 (x64)\nMicrosoft .NET Framework 4.5 Multi-Targeting Pack\nMicrosoft .NET Framework 4.5.1 Multi-Targeting Pack (ENU)\nMicrosoft .NET Framework 4.5.1 Multi-Targeting Pack\nMicrosoft .NET Framework 4.5.1 SDK\nMicrosoft .NET Framework 4.5.2 Multi-Targeting Pack (ENU)\nMicrosoft .NET Framework 4.5.2 Multi-Targeting Pack\nMicrosoft .NET Framework 4.7.2 SDK\nMicrosoft .NET Framework 4.7.2 Targeting Pack\nMicrosoft .NET Framework 4.8 SDK\nMicrosoft .NET Framework 4.8 Targeting Pack\nMicrosoft .NET SDK 5.0.100-preview.5.20279.10 (x64)\nMicrosoft .NET SDK 5.0.100-preview.8.20417.9 (x64)\nMicrosoft .NET SDK 5.0.100-rc.1.20452.10 (x64)\nMicrosoft .NET SDK 5.0.100-rc.2.20479.15 (x64)\nMicrosoft Azure CLI\nMicrosoft Azure Storage Emulator - v5.10\nMicrosoft Azure Storage Explorer version 1.14.0\nMicrosoft Azure Storage Explorer version 1.15.1\nMicrosoft Deployment Toolkit (6.3.8456.1000)\nMicrosoft Edge\nMicrosoft Edge Beta\nMicrosoft Edge Dev\nMicrosoft Garage Mouse without Borders\nMicrosoft Help Viewer 2.2\nMicrosoft Help Viewer 2.3\nMicrosoft MPI (10.1.12498.16)\nMicrosoft MPI (10.1.12498.18)\nMicrosoft MPI SDK (10.1.12498.18)\nMicrosoft ODBC Driver 13 for SQL Server\nMicrosoft ODBC Driver 17 for SQL Server\nMicrosoft OLE DB Driver for SQL Server\nMicrosoft R Open 3.5.3\nMicrosoft R Open 4.0.2\nMicrosoft SQL Server 2012 Native Client \nMicrosoft SQL Server 2014 Management Objects \nMicrosoft SQL Server 2016\nMicrosoft SQL Server 2016 Policies \nMicrosoft SQL Server 2016 T-SQL Language Service \nMicrosoft SQL Server 2016 T-SQL ScriptDom \nMicrosoft SQL Server 2017\nMicrosoft SQL Server 2017 Policies \nMicrosoft SQL Server 2017 T-SQL Language Service \nMicrosoft SQL Server Data-Tier Application Framework (x86)\nMicrosoft SQL Server Management Studio - 16.5.3\nMicrosoft SQL Server Management Studio - 17.9.1\nMicrosoft SQL Server Management Studio - 18.5\nMicrosoft SQL Server Management Studio - 18.5.1\nMicrosoft SQL Server Management Studio - 18.6\nMicrosoft Small Basic v1.2\nMicrosoft System CLR Types for SQL Server 2014\nMicrosoft System CLR Types for SQL Server 2016\nMicrosoft System CLR Types for SQL Server 2017\nMicrosoft Visio Viewer 2016\nMicrosoft Visual Studio 2010 Tools for Office Runtime (x64)\nMicrosoft Visual Studio 2015 Shell (Isolated)\nMicrosoft Visual Studio Code (User)\nMicrosoft Visual Studio Code Insiders (User)\nMicrosoft Visual Studio Tools for Applications 2015\nMicrosoft Visual Studio Tools for Applications 2015 Language Support\nMicrosoft Visual Studio Tools for Applications 2017\nMicrosoft Web Platform Installer 5.1\nMiniconda3 4.7.12 (Python 3.7.4 64-bit)\nMiniconda3 py37_4.8.3 (Python 3.7.7 64-bit)\nMongoDB 4.2.8 2008R2Plus SSL (64 bit)\nMono for Windows (x64)\nMonoGame SDK\nMoonlight Game Streaming Client\nMotrix 1.5.10\nMotrix 1.5.15\nMozilla Firefox 68.8.0 ESR (x64 en-US)\nMozilla Firefox 68.9.0 ESR (x64 en-US)\nMozilla Firefox 76.0.1 (x86 en-US)\nMozilla Firefox 77.0 (x64 en-US)\nMozilla Firefox 77.0.1 (x64 en-US)\nMozilla Firefox 78.0 ESR (x64 en-US)\nMozilla Firefox 78.0.1 (x64 en-US)\nMozilla Firefox 78.0.2 (x64 cs)\nMozilla Firefox 78.0.2 (x64 en-US)\nMozilla Firefox 78.1.0 ESR (x64 en-US)\nMozilla Firefox 78.4.0 ESR (x64 en-US)\nMozilla Firefox 79.0 (x64 en-US)\nMozilla Firefox 80.0 (x64 en-US)\nMozilla Firefox 80.0.1 (x64 en-US)\nMozilla Firefox 81.0 (x64 en-US)\nMozilla Firefox 81.0.1 (x64 en-US)\nMozilla Firefox 81.0.2 (x64 en-US)\nMozilla Firefox 82.0 (x64 en-US)\nMozilla Firefox 82.0.1 (x64 en-US)\nMozilla Firefox 82.0.1 (x64 es-MX)\nMozilla Firefox 82.0.2 (x64 en-US)\nMozilla Maintenance Service\nMozilla Thunderbird 68.10.0 (x64 en-US)\nMozilla Thunderbird 68.8.0 (x86 en-US)\nMozilla Thunderbird 68.9.0 (x64 en-US)\nMozilla Thunderbird 77.0 (x64 en-US)\nMozilla Thunderbird 78.0 (x64 cs)\nMozilla Thunderbird 78.0 (x64 en-US)\nMozilla Thunderbird 78.0.1 (x64 en-US)\nMozilla Thunderbird 78.1.0 (x64 en-US)\nMozilla Thunderbird 78.1.1 (x64 en-US)\nMozilla Thunderbird 78.3.2 (x64 en-US)\nMu\nMullvad VPN 2020.5.0\nMullvad VPN 2020.6.0\nMultilingual App Toolkit 4.0\nMultipass\nMumble 1.3.1\nMumble 1.3.2\nMumble 1.3.3\nMuseScore 3\nMuta 2.1.02\nMyHarmony\nMyPaint\nMySQL Installer - Community\nMypal 28.14.2 (x64 en-US)\nNBTExplorer\nNSwagStudio\nNVDA\nNVIDIA NVIDIA RTX Voice Driver 1.0.0.2\nNVIDIA RTX Voice Application\nNZXT CAM 4.10.1\nNZXT CAM 4.11.0\nNZXT CAM 4.12.0\nNZXT CAM 4.13.0\nNZXT CAM 4.8.0\nNZXT CAM 4.9.2\nNelson-0.4.8.2662 (64 bits)\nNeoLoad 7.3.0\nNetron 4.5.9\nNitro Pro\nNmap 7.80\nNoSQLBooster for MongoDB 4.7.5 (only current user)\nNoSQLBooster for MongoDB 5.2.12\nNoSQLBooster for MongoDB 6.1.8\nNode.js\nNodist\nNordVPN\nNordVPN\nNordVPN network TAP\nNordVPN network TUN\nNoteHighlight2016\nNotepad2-mod 4.2.25.998\nNotion 2.0.8\nNotion 2.0.9\nNpcap 0.9982\nNullpoMino version 7.5\nNullsoft Install System\nOBS Studio\nOHRRPGCE gorgonzola 20200502\nONLYOFFICE Desktop Editors 5.6 (x64)\nOctave 5.2.0\nOneNote Tagging Kit\nOpen Shop Channel Downloader version 1.2.9\nOpen-Shell\nOpenHashTab version 2.2.0\nOpenHashTab version 2.3.0\nOpenJDK 1.8.0_252-2-ojdkbuild\nOpenJDK 11.0.7-1-ojdkbuild\nOpenJDK 13.0.3-1-ojdkbuild\nOpenJDK 14.0.1-1-ojdkbuild\nOpenMPT 1.29 (64-Bit)\nOpenOffice 4.1.7\nOpenRA\nOpenSCAD (remove only)\nOpenSSL (64-bit)\nOpenShot Video Editor version 2.5.1\nOpenTTD 1.10.1\nOpenTTD 1.10.3\nOpenVPN 2.4.9-I601-Win10 \nOpenVPN Configuration Generator x64\nOpenVPN Connect\nOpera GX Stable 68.0.3618.142\nOpera GX Stable 68.0.3618.197\nOpera Stable 68.0.3618.63\nOpera Stable 69.0.3686.36\nOpera Stable 69.0.3686.77\nOpera Stable 70.0.3728.144\nOpera Stable 70.0.3728.95\nOpera Stable 71.0.3770.198\nOracle VM VirtualBox 6.1.10\nOracle VM VirtualBox 6.1.12\nOracle VM VirtualBox 6.1.14\nOracle VM VirtualBox 6.1.16\nOutSystems Development Environment 11\nPDF reDirect (remove only)\nPDFsam Basic\nPKU_Gateway 0.9.8\nPSPad editor\nPacket Sender x64\nPale Moon 28.10.0 (x64 en-US)\nPale Moon 28.9.3 (x64 en-US)\nPandoc 2.10.1\nPandoc 2.11.0.2\nPandoc 2.9.2.1\nParadox Launcher\nParagon Backup & RecoveryÃ¢â€žÂ¢ 17 CE\nParsec\nPasteIntoFile version 2.0\nPeaZip 7.2.1 (WIN64)\nPeaZip 7.3.1 (WIN64)\nPersepolis Download Manager version 3.2.0.0\nPhonerLite 2.84\nPhotoSync\nPicPick\nPicoTorrent\nPlanet Blupi\nPlayStationÃ¢â€žÂ¢Now\nPlaynite\nPlex\nPlex Media Player\nPlex Media Server\nPlexamp 3.0.3\nPlexamp 3.1.0\nPlexamp 3.1.1\nPokerTH\nPostbox 7.0.18 (x86 en-US)\nPostgreSQL 12 \nPostgreSQL 13 \nPowerShell 7-preview-x64\nPowerShell 7-x64\nPowerShell Universal\nPowerToys (Preview)\nPrimesieve version 7.5\nPrivate Internet Access\nProgress Telerik Fiddler\nProject My Screen App\nProtonVPN\nProtonVPNTap\nPuTTY release 0.74 (64-bit)\nPuppet\nPuppet Agent (64-bit)\nPuppet Bolt\nPuppet Development Kit\nPure Data (64-bit) 0.50-2\nPyMODA version 1.1.0\nPython 2.7.18\nPython 3.7 PyAudio-0.2.11\nPython 3.7.7 (64-bit)\nPython 3.8.1 (64-bit)\nPython 3.8.3 (64-bit)\nPython 3.8.4 (64-bit)\nPython 3.8.5 (64-bit)\nPython 3.8.6 (64-bit)\nPython 3.9.0 (64-bit)\nPython Launcher\nQGIS 3.10.6 'A Coru\nQGIS 3.12.3 'Bucuresti'\nQGIS 3.14.0 'Pi'\nQTextPad version 1.4\nQalculate!\nQtSpim\nQuick Picture Viewer\nQuickLook\nQuicken\nR for Windows 4.0.0\nR for Windows 4.0.2\nR for Windows 4.0.3\nRStudio\nRambox 0.7.5\nRapid Environment Editor version 9.2.0.937\nRaspberry Pi Imager\nRawTherapee version 5.8\nReddit Wallpaper Changer\nReko decompiler for x86-64\nRemote Desktop Manager\nRemote Desktop Manager Free\nRemote Mouse version 3.015\nRenderDoc\nRenode\nResponsivelyApp 0.1.5\nRetroShare\nRevo Uninstaller 2.1.7\nRevo Uninstaller Pro 4.3.3\nRobo 3T 1.3.1\nRobo 3T 1.4.1\nRobo 3T 1.4.2\nRocket.Chat 2.17.9\nRocketDock 1.3.5\nRocks'n'Diamonds 4.1.4.1\nRosi\nRoyal TS 5.02.60420.0\nRoyal TS 5.03.60925.0\nRtools 4.0 (4.0.0.28)\nRuby 2.7.1-1-x64\nRuby 2.7.1-1-x64 with MSYS2\nRuby 2.7.2-1-x64\nRunJS 1.10.1\nRunJS 1.11.0\nRust 1.43 (MSVC 64-bit)\nRust 1.44 (GNU 64-bit)\nRust 1.44 (GNU)\nRust 1.44 (MSVC 64-bit)\nRust 1.44 (MSVC)\nRust 1.45 (GNU 64-bit)\nRust 1.45 (GNU)\nRust 1.45 (MSVC 64-bit)\nRust 1.45 (MSVC)\nSIW 2020 v10.6.0915a Trial\nSMPlayer 20.4.2 (x64)\nSSHFS-Win 2020 (x64)\nSVG Explorer Extension 0.1.1\nSamsung DeX\nSatisfactory Mod Launcher 1.0.17\nScratch Desktop 3.11.1\nScreenToGif\nScribus 1.4.8 (64bit)\nScummVM 2.2.0\nSearch Deflector\nSejda PDF Desktop\nSeq\nSharePoint Online Management Shell\nShareX\nSharpKeys\nShotcut\nSigil 1.3.0\nSignal 1.34.1\nSignal 1.34.3\nSignal 1.34.4\nSignal 1.34.5\nSignal 1.36.1\nSignal 1.36.3\nSignal 1.37.2\nSimply Fortran 3\nSitdownMW\nSkype version 8.60\nSkype version 8.64\nSkype version 8.65\nSlack Machine-Wide\nSnagit 2020\nSnakeTail 64-bit v1.9.6.0\nSnoop\nSoapUI 5.5.0\nSonic Pi\nSonos\nSonos Controller\nSoundSwitch 5.0.4.31153\nSourcetree\nSpeedCrunch\nSpek\nStandard Notes 3.4.1\nSteam\nSteel Bank Common Lisp 2.0.0 (X86-64)\nSteelSeries Engine 3.17.9\nStellarium 0.20.1\nStellarium 0.20.2\nStellarium 0.20.3\nStrawberry Perl\nStreamlabs OBS\nStreamlabs OBS 0.23.2\nStreamlabs OBS 0.24.0\nStreamlink\nStreamlink Twitch GUI\nStretchly 1.0.0\nStretchly 1.1.0\nStretchly 1.2.0\nStride\nStudio 2.0 version 2.0\nSublime Merge\nSublime Text 3\nSumatraPDF\nSuperCollider Version 3.11.0\nSuperTuxKart 1.1.0 - 3D open-source arcade racer with a variety characters, tracks, and modes to play\nSurface Duo Emulator version 2020.806.2\nSyncTrayzor (x64) version 1.1.24.0\nSystem Explorer 7.0.0\nTAP-Windows 9.24.2\nTaiga\nTailscale\nTailscale IPN\nTaisei Project\nTaskade 3.1.1\nTaskade 3.2.0\nTd-agent v3.8.0\nTd-agent v4.0.1\nTeXstudio - TeXstudio is a fully featured LaTeX editor.\nTeXworks 0.6.5\nTeamSpeak 3 Client\nTechPowerUp GPU-Z\nTelegram Desktop version 2.1.13\nTelegram Desktop version 2.1.20\nTelegram Desktop version 2.1.6\nTelegram Desktop version 2.2\nTelegram Desktop version 2.3\nTelegram Desktop version 2.3.1\nTelegram Desktop version 2.4.1\nTelegram Desktop version 2.4.3\nTelegram Desktop version 2.4.4\nTera Term 4.105\nTerminus 1.0.117\nTerminus 1.0.119\nTerminus 1.0.120\nTermite\nTesseract-OCR - open source OCR engine\nTexmaker 5.0.4 (64-bit)\nTexnomic SecureDNS Terminal\nTextify v1.8.2\nTickTick version 3.7.1.1\nTightVNC\nTikzEdt 0.2.3\nTiled\nTmNationsForever\nToggl Desktop\nToggl Track\nTortoiseGit 2.10.0.2 (64 bit)\nTortoiseSVN 1.13.1.28686 (64 bit)\nTortoiseSVN 1.14.0.28885 (64 bit)\nTranslucentTB\nTransmission 3.00 (bb6b5a062e) (x64)\nTransmission Remote GUI 5.18\nTrayStatus 4.3\nTrayStatus 4.4\nTreeSize Free V4.4.2\nTreeSize V8.0.2 (64 bit)\nTrelby\nTrillian\nTunnelBear\nTux Paint 0.9.23\nTweeten\nTwinkle Tray 1.12.2\nTwitch\nTypeRefHasher\nUSB Safely Remove 6.3\nUXL Launcher Version 3.3.1.0\nUXL Launcher Version 4.0.0.0\nUltimaker Cura \nUltimaker Cura 4.5\nUltimaker Cura 4.6\nUltraVnc\nUnchecky v1.2\nUnified Remote\nUnity Hub 2.4.2\nUpdate for  (KB2504637)\nUpdate for Microsoft Visual Studio 2015 (KB3095681)\nUplay\nUt Video Codec Suite\nVCV Rack\nVLC media player 3.0.10 (64-bit)\nVLC media player 3.0.11 (64-bit)\nVLC media player 4.0.0 (64-bit)\nVMware Horizon Client\nVMware Player\nVMware Workstation\nVNC Server 6.0.0\nVNC Viewer 6.0.0\nVSCodium (User)\nVSCodium\nVcXsrv\nVim 8.2 (x64)\nVirtViewer 9.0-256 (64-bit)\nVivaldi\nVortex\nVrew 0.4.18\nVulkanSDK 1.2.135.0\nWarzone 2100-3.4.0\nWaterfox Current 2020.05 (x64 en-US)\nWaterfox Current 2020.09 (x64 en-US)\nWaterfox Current 2020.10 (x64 en-US)\nWayk Now\nWeakAuras Companion 3.0.1\nWeakAuras Companion 3.0.2\nWeakAuras Companion 3.0.3\nWeakAuras Companion 3.0.6\nWeka 3.8.4\nWin32DiskImager version 1.0.0\nWinCompose version 0.9.4\nWinDynamicDesktop version 3.4.1.0\nWinDynamicDesktop version 4.2.0.0\nWinDynamicDesktop version 4.3.1.0\nWinFsp 2020\nWinHTTrack Website Copier 3.49-2 (x64)\nWinMerge 2.16.6.0\nWinRAR 5.90 (64-bit)\nWinRAR 5.91 (64-bit)\nWinSCP 5.17.7\nWinZip 24.0\nWinamp\nWindows 10 Update Assistant\nWindows Admin Center\nWindows Assessment and Deployment Kit - Windows 10\nWindows Assessment and Deployment Kit Windows Preinstallation Environment Add-ons - Windows 10\nWindows Driver Kit - Windows 10.0.19041.1\nWindows Driver Package - Dynastream Innovations, Inc. ANT LibUSB Drivers (04/11/2012 1.2.40.201)\nWindows Driver Package - Silicon Labs Software (DSI_SiUSBXp_3_1) USB  (02/06/2007 3.1)\nWindows SDK AddOn\nWindows Software Development Kit - Windows 10.0.17763.132\nWindows Software Development Kit - Windows 10.0.18362.1\nWindows Software Development Kit - Windows 10.0.19041.1\nWireGuard\nWireshark 3.2.2 32-bit\nWireshark 3.2.4 64-bit\nWireshark 3.2.5 64-bit\nWireshark 3.2.7 64-bit\nWizFile v2.06\nWizKey v1.5.0.8\nWizMouse v1.7.0.3\nWizTree v3.33\nWizTree v3.35\nWordPress.com 5.2.0\nWordPress.com 6.0.0\nWordPress.com 6.0.1\nWordPress.com 6.0.2\nWorkrave 1.10.44\nWritage\nX2Go Client for Windows\nXAMPP\nXCA\nXMake build utility\nXMind 10.2.1\nXnView 2.49.4\nXnViewMP 0.97.1\nYarn\nYinxiang Biji v. 6.20.16\nYinxiang Biji v. 6.21.10\nYinxiang Biji v. 6.21.3\nYinxiang Biji v. 6.21.4\nYinxiang Biji v. 6.21.9\nYouTube Music Desktop App 1.11.0\nYubiKey Manager\nZentimo PRO 2.3\nZeroTier One\nZettlr\nZint\nZoom\nZoom Outlook Plugin\nZotero\nZulip\nZulu 3.5.1\nZygor Client Uninstaller\nbalenaEtcher 1.5.100\nbalenaEtcher 1.5.101\nbalenaEtcher 1.5.102\nbalenaEtcher 1.5.106\nbalenaEtcher 1.5.107\nbalenaEtcher 1.5.109\nbalenaEtcher 1.5.88\nbalenaEtcher 1.5.95\nbeatdrop 2.6.2\nbottom\nbutterflow-ui\ncalibre 64bit\ncopytranslator 9.1.0\ndarktable\ndnGREP 2.9.270 (x64)\ndraw.io 13.0.3\ndupeGuru 4.0.4\neM Client\nebbflow\nf.lux\nffftp\nghostwriter version 1.7.1\ngnuplot 5.2 patchlevel 8\ngrepWin x64\nguinget version 0.1.0.1\nguinget version 0.1.1\nguinget version 0.1.2\nhide.me VPN 3.4.0\nhide.me VPN 3.4.1\ni2pd\niSEEK AnswerWorks English Runtime\niTunes\nkdenlive\nkdiff3\nmRemoteNG\nmaxima-5.43.2\nmpv.net version 5.4.8.0\nndm 1.2.0 (only current user)\nnexusfont 2.6 (ver 2.6.2.1870)\nownCloud\npCon.planner PRO\npandoc-plot 0.7.1.0\npgAdmin 4 version 4.22\npgAdmin 4 version 4.23\npgAdmin 4 version 4.26\npgAdmin 4 version 4.27\nqBittorrent 4.2.5\nqBittorrent 4.3.0\nqBittorrent 4.3.0.1\nremoteit 2.5.32\nremoteit 2.6.2\nsbt 1.3.8\nscilab-6.1.0 (64-bit)\nsqlectron 1.31.0\nstretchly 0.21.1\nueli 8.7.0\nueli 8.8.1\nueli 8.9.0\nxmoto 0.6.0\nxmoto 0.6.1\n微软设备健康助手\n支付宝安全控件 5.3.0.3807\n百度网盘\n腾讯QQ\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InputPublishers.txt",
    "content": "Wildfire Games\nSweetScape Software\n360安全中心\n360安全中心\nOpen Media LLC\nOpen Media LLC\nOpen Media LLC\nOpen Media LLC\nOpen Media LLC\nOpen Media LLC\nIgor Pavlov\nIgor Pavlov\nIgor Pavlov\nIgor Pavlov, Tino Reichardt\nAmazon Web Services Developer Relations\nAmazon Web Services\nAWS Serverless Applications\nAxis Communications AB\nAbacus Research AG\nMicrosoft\nMicrosoft Corporation\nAdobe Systems Incorporated\nAdobe Systems Incorporated\nAdobe Systems Incorporated\nAdoptOpenJDK\nAdoptOpenJDK\nAdoptOpenJDK\nAdoptOpenJDK\nAdoptOpenJDK\nAdoptOpenJDK\nAdoptOpenJDK\nFamatech\nOndrej Salplachta\nFamatech\nPawel Psztyc\nAegisub Team\nAegisub Team\na wandersick\nAlacritty\nAlchemy Development Group\nAlgoryx\nStefan Sundin\nAmazon.com, Inc.\nAmazon\nAmazon\nAmazon Web Services, Inc\nAnaconda, Inc.\nAngry IP Scanner\nAntiMicro\nAppGet\nAppium Developers\nAppium Developers\nArduino LLC\nArmagetron Advanced Team\nSundaram Ramaswamy\nRabid Viper Productions\nAudacity Team\nCodeUX.design e.U.\nArmin Osaj\nLexikos\nLexikos\nThe Sleuth Kit\nGPL Public release.\nOmicronLab\n7room\nMicrosoft® Corporation\nMicrosoft Corporation\nMicrosoft\nMicrosoft\nMicrosoft\nMarcin Szeniak\nContoso.com\nBeda Kosata\nSpace Sciences Laboratory, U.C. Berkeley\nBPBible Development Team\nGoogle, Inc.\nDebauchee Open Source Group\nDebauchee Open Source Group\nPaul Frazee\nElastic\nElastic\nMarco Mastroddi Software\nbeeftext.org\nThe Betaflight open source project.\nScooter Software, Inc.\nScooter Software\nScooter Software\nBigly Software\nBitPay\nBitwarden Inc.\nBleachBit\nBlender Foundation\nBlueJeans Network, Inc.\nHamster Republic Productions\nApple Inc.\nAndrew Sampson\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nbrackets.io\nBrave Software Inc\nBrave Software Inc\nTGRMN Software\nButtercup\nButtercup\nC-Dogs SDL Team\nSingularLabs\nPiriform\nCanneverbe Limited\nKitware\nCorsair\nCPUID, Inc.\nCPUID, Inc.\nCPUID, Inc.\nCPUID, Inc.\nCPUID, Inc.\nPenguin Labs, LLC\nSaeraSoft\nTechSmith Corporation\nTechSmith Corporation\nSindre Sorhus\nSindre Sorhus\nGiel Cobben\nMathew Sachin\nRedDucks\nAlexandr Subbotin\nMIT IS&T\nsecana\nWebprofusion Pty Ltd\na wandersick\nChef Software, Inc.\nChemAxon\nChemAxon\nChemAxon\nChemAxon\nThe Chromium Authors\nCircuit Diagram\nCircuit Diagram\nCisco Webex LLC\nDaniel Scalzi\nalch\nFndroid\nFndroid\nFndroid\nFndroid\nBeijing EEO Education Technology Co., Ltd.\nClementine\nMartin Ridgers\nCloudflare, Inc.\nThe Code::Blocks Team\nEran Ifrah\nSteven Cole\nTerranovaTeam\nJay Prall\nToinane\nConEmu-Maximus5\nConcept2 Inc.\nMicrosoft Corporation\nContasimple S.L.\nALCPU\nCouchbase Inc.\nCouchbase Inc.\nCozy Cloud\nThe Cppcheck team\nHabib Rehman\ncryptomator.org\nCrystal Dew World\nCrystal Dew World\nCrystal Dew World\nCrystal Dew World\nCrystal Dew World\nCrystal Dew World\nCrystal Dew World\nCrystal Dew World\nCrystal Dew World\nCrystal Dew World\nCrystal Dew World\nCrystal Dew World\nCrystal Dew World\nCrystal Dew World\nCrystal Dew World\nCrystal Dew World\nCrystal Dew World\ncubicsdr.com\nAcro Software Inc.\niterate GmbH\nDB Browser for SQLite Team\nDBeaver Corp\nDBeaver Corp\nDBeaver Corp\nDBeaver Corp\nDBeaver Corp\nDBeaver Corp\nDBeaver Corp\nDBeaver Corp\nDBeaver Corp\nDJI\nDJI\nDJI\nDJI\nDJI\nDJI\nDJI\nDJI\nTshwaneDJe\nBoxstar\nBoxstar\nDeezer\nAshley Stone\nPiriform\nDell, Inc.\nDell Inc.\nBloodshed Software\nThinking Man Software\nSerraniel\nSerraniel\nScott Brogden\nDixa\nDjVuZone\nDockStation\nDocker Inc.\nDokany Project\nDokany Project\nDolphin Team\ndengine.net\nDigimezzo\nDoxie & Co. LLC\nDropbox, Inc.\nEasternGraphics\nEasternGraphics\nEagleGet\nEagleGet\nLuke Stratman\nES-Computing\nEduMIPS64 Development Team\nElastic\nElgato Systems GmbH\nEmpoche.com\nEmpoche.com\nMacPaw, Inc.\na wandersick\nSinew Software Systems Private Limited\nThe Eraser Project\nThe Eraser Project\nThe Eraser Project\nThe Eraser Project\nEsteem\nEthereum\nEvernote Corp.\nEvernote Corp.\nDavid Carpenter\nDavid Carpenter\nDavid Carpenter\nDavid Carpenter\nvoidtools\nExpressVPN\nUltrapico\nThe ExtremeTuxRacer team\nEugene Roshal & Far Group\nH.Shirouzu\nFastStone Soft\nFastStone Soft\nFedora Project\nAmine Mouafik\nProgress Software Corporation\nProgress Software Corporation\nProgress Software Corporation\nProgress Software Corporation\nProgress Software Corporation\nProgress Software Corporation\nProgress Software Corporation\nAdrien Allard\nBinary Fortress Software\nTim Kosse\nTim Kosse\nTim Kosse\nTim Kosse\nTim Kosse\nMozilla\nMozilla\nMozilla\nMozilla\nOpenSight Software LLC\nThe FlightGear Team\nDominik Levitsky Studio, LLC\nFontForgeBuilds\nFree Time\nFree Time\nFoxit Software Inc.\nFoxit Software Inc.\nStefan Malzner\nMarek Jasinski - www.FreeCommander.com\nHumanity\nThe GIMP Team\nThe GIMP Team\nThe GIMP Team\nThe GIMP Team\nThe GIMP Team\nThe GIMP Team\nThe GIMP Team\nThe GIMP Team\nARM Holdings\nThe Free Software Foundation, Inc.\nThe GnuPG Project\nGCN Development\nGOG.com\nArtifex Software Inc.\nGhostgum Software Pty Ltd\nGarmin Ltd or its subsidiaries\nThoughtWorks Inc.\nThoughtWorks Inc.\nThe Geany developer team\nPrimate Labs Inc.\nGephi\nOutertech\nGit Extensions Team\nGit Extensions Team\nGit Extensions Team\nGitHub, Inc.\nThe Git Development Community\nThe Git Development Community\nThe Git Development Community\nThe Git Development Community\nThe Git Development Community\nThe Git Development Community\nGitHub, Inc.\nGitHub, Inc.\nStef Heyenrath\nTroupe Technology Limited\nGlimpse Project\nGlimpse Project\nGlimpse Project\nGnuCash Development Team\nGnuCash Development Team\nGnuWin32\nGnuWin32\nGnuWin32\nGnuWin32\nhttps://golang.org\nhttps://golang.org\nhttps://golang.org\nhttps://golang.org\nhttps://golang.org\nhttps://golang.org\nhttps://golang.org\nhttps://golang.org\nhttps://golang.org\nhttps://golang.org\nhttps://golang.org\nhttps://golang.org\nhttps://golang.org\nhttps://golang.org\nhttps://golang.org\nhttps://golang.org\nhttps://golang.org\nGoldWave Inc.\nGoogle LLC\nGoogle Inc.\nGoogle\nThe Gpg4win Project\nThe Gpg4win Project\nGrafana Labs\nGrafana Labs\nGrammarly\nThe Gramps project\nGraphcool\nAdam Miskiewicz\nAT&T Research Labs.\nGreenshot\nGrid Team\nEpiforge Software, LLC\nHHD Software, Ltd.\nHector Maurcio Rodriguez Segura\nHP Inc.\nHuawei Software Technologies Co., Ltd.\nMartin Malik - REALiX\nMartin Malik - REALiX\nMartin Malik - REALiX\nMartin Malik - REALiX\nHandyOrg\nVincent L\nImplbits Software\nImplbits Software\nJAM Software\nHedgewars Project\nAnsgar Becker\nAnsgar Becker\nAnsgar Becker\nAnsgar Becker\nAnsgar Becker\nPerforce Software, Inc.\nIBE Software\nHexChat\nScott Lerch\nCaphyon\nBorvid\nBorvid\nBorvid\nBorvid\nBorvid\nBorvid\nBorvid\nHuawei Corporation\nHyne & Son Pty Ltd\nMarquis Kurt\nGoogle Inc\nHex-Rays SA\nTibbo Technology Inc\nDavid Moore\nIRCCloud Ltd.\nIvan Zahariev\nDuong Dieu Phap\nInkscape\njrsoftware.org\njrsoftware.org\nCrystal Rich, Ltd\nseonglae\nIrfan Skiljan\nIronPython Team\nIronPython Team\nISWIX LLC\nSmart Projects\nChemAxon\nJabRef\nJackett\nSavoir-Faire Linux\nOracle Corporation\nOracle Corporation\nJetBrains\nJitsi Team\nJitsi Team\nLaurent Cozic\nLaurent Cozic\nLaurent Cozic\nJulia Language\nJulia Language\nJulia Language\nKLCP\nKLCP\nKKBOX Taiwan Co., Ltd.\nChia-Lung, Chen\nDominik Reichl\nDominik Reichl\nDominik Reichl\nKeePassXC Team\nKeeWeb\nKeybase, Inc.\nKiCad\nKiCad\nKiCad\nKrisp Technologies, Inc\nKrita Foundation\nRoni Lehto\nLBRY Inc.\nLBRY Inc.\nLBRY Inc.\nLBRY Inc.\nLBRY Inc.\nLINE Corporation\nJoseph Albahari\nLLVM\nLMMS Developers\nLMMS Developers\nlove2d.org\nleokhoa\nLastPass\nLazarus Team\nRiot Games, Inc\nLenovo\nLenovo\nLakend Labs, Inc.\nLeonflix\nBellSoft\nBellSoft\nBellSoft\nBellSoft\nBellSoft\nBellSoft\nBellSoft\nBellSoft\nLibreCAD Team\nThe Document Foundation\nThe Document Foundation\nTeam Lidarr\nAlexey 'Tyrrrz' Golub\nAlexey 'Tyrrrz' Golub\nChristian Kaiser\nLeif Asbrink SM5BSZ\nLisk Foundation\nListen 1\nListen 1\nFlywheel\nCrystal Rich Ltd\nBinary Fortress Software\nBinary Fortress Software\nLogitech Inc.\nLoom, Inc.\nLyX Team\nLyX Team\nCOTILab\nCOTILab\nMoritz Bunkus\nMoritz Bunkus\nMoritz Bunkus\nMoritz Bunkus\nMoritz Bunkus\nMPC-HC Team\nMPC-HC Team\nMPC-HC Team\nThomas Nordquist\nMicrosoft\nMaxthon International Limited\nMY.COM B.V.\nFlyingSnow, Samantha Glocker\nFiretrust\nFiretrust\nMajsoul Plus Team\nGuinpinSoft inc\nMalwarebytes\nKDE\nMariaDB Corporation Ab\nJocs\nWest Wind Technologies\nWest Wind Technologies\nWest Wind Technologies\nWest Wind Technologies\nWest Wind Technologies\nMarkdown Outlook\nMaster Packager Ltd.\nMattermost, Inc.\nMediaArea.net\nMediaArea.net\nVentis Media Inc.\nThe Meld project\nJanea Systems\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Garage\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft\nMicrosoft\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nAnaconda, Inc.\nAnaconda, Inc.\nMongoDB Inc.\nXamarin, Inc.\nThe MonoGame Team\nMoonlight Game Streaming Project\nAGALWOOD\nAGALWOOD\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nMozilla\nNicholas H.Tollervey\nMullvad VPN\nMullvad VPN\nMicrosoft Corporation\ncanonical\nThe Mumble Developers\nThe Mumble Developers\nThe Mumble Developers\nWerner Schweer and Others\nYouta Tec\nLogitech\nMartin Renold and the MyPaint Development Team\nOracle Corporation\nFeodor2\nJustin Aquadro\nRico Suter\nNV Access\nNVIDIA Corporation\nNVIDIA Corporation\nNZXT, Inc.\nNZXT, Inc.\nNZXT, Inc.\nNZXT, Inc.\nNZXT, Inc.\nNZXT, Inc.\nAllan CORNET\nNeotys\nLutz Roeder\nNitro\nNmap Project\nqinghai\nqinghai\nqinghai\nNode.js Foundation\nNodist\nNordVPN\nTEFINCOM S.A.\nNordVPN\nNordVPN\nCodingRoad\nXhmikosR\nNotion Labs, Incorporated\nNotion Labs, Incorporated\nNmap Project\nNullNoname\nNullsoft and Contributors\nOBS Project\nHamster Republic Productions\nAscensio System SIA\nGNU Octave\nWetHat Lab\nOpen Shop Channel\nThe Open-Shell Team\nnamazso\nnamazso\nojdkbuild open-source project\nojdkbuild open-source project\nojdkbuild open-source project\nojdkbuild open-source project\nOpenMPT Devs\nApache Software Foundation\nOpenRA developers\nThe OpenSCAD Developers\nShining Light Productions\nOpenShot Studios, LLC\nOpenTTD\nOpenTTD\nOpenVPN Technologies, Inc.\nSparkLabs Pty Ltd\nOpenVPN Technologies\nOpera Software\nOpera Software\nOpera Software\nOpera Software\nOpera Software\nOpera Software\nOpera Software\nOpera Software\nOracle Corporation\nOracle Corporation\nOracle Corporation\nOracle Corporation\nOutSystems\nEXP Systems LLC\nSober Lemur S.a.s. di Vacondio Andrea\nCCPKU\nJan Fiala\nNagleCode, LLC\nMoonchild Productions\nMoonchild Productions\nJohn MacFarlane\nJohn MacFarlane\nJohn MacFarlane\nParadox Interactive\nParagon Software GmbH\nParsec Cloud Inc.\nFrancesco Sorge\nGiorgio Tani\nGiorgio Tani\nPersepolis Team\nHeiko Sommerfeldt\ntouchbyte GmbH\nNGWIN\nPicoTorrent contributors.\nblupi.org\nSony Interactive Entertainment Network America LLC\nJosef Nemec\nPlex, Inc.\nPlex\nPlex, Inc.\nPlex, Inc.\nPlex, Inc.\nPlex, Inc.\nwww.pokerth.net\nPostbox, Inc.\nPostgreSQL Global Development Group\nPostgreSQL Global Development Group\nMicrosoft Corporation\nMicrosoft Corporation\nIronman Software, LLC\nMicrosoft\nKim Walisch\nPrivate Internet Access, Inc.\nProgress Software Corporation\nMicrosoft Corporation\nProton Technologies AG\nProton Technologies AG\nSimon Tatham\nPuppet Labs\nPuppet Inc\nPuppet, Inc.\nPuppet Inc\nMiller Puckette\nLancaster University Physics\nPython Software Foundation\nHubert Pham\nPython Software Foundation\nPython Software Foundation\nPython Software Foundation\nPython Software Foundation\nPython Software Foundation\nPython Software Foundation\nPython Software Foundation\nPython Software Foundation\nQGIS Development Team\nQGIS Development Team\nQGIS Development Team\nMichael Hansen\nHanna Knutsson\nLarusStone\nModule Art\nPaddy Xu\nQuicken\nR Core Team\nR Core Team\nR Core Team\nRStudio\nRambox\nOleg Danilov\nRaspberry Pi\nrawtherapee.com\nPaul Rawnsley\njklSoft\nDevolutions inc.\nDevolutions inc.\nRemote Mouse\nBaldur Karlsson\nAntmicro\nResponsively\nRetroShare Team\nVS Revo Group, Ltd.\nVS Revo Group, Ltd.\n3T Software Labs Ltd\n3T Software Labs Ltd\n3T Software Labs Ltd\nRocket.Chat Support\nPunk Software\nArtsoft Entertainment\nMarkoBL\ncode4ward GmbH\nRoyal Apps GmbH\nThe R Foundation\nRubyInstaller Team\nRubyInstaller Team\nRubyInstaller Team\nLuke Haas\nLuke Haas\nThe Rust Project Developers\nThe Rust Project Developers\nThe Rust Project Developers\nThe Rust Project Developers\nThe Rust Project Developers\nThe Rust Project Developers\nThe Rust Project Developers\nThe Rust Project Developers\nThe Rust Project Developers\nTopala Software Solutions\nRicardo Villalba\nNavimatics LLC\nDotz Softwares\nSamsung Electronics Co., Ltd.\nmircearoata\nScratch Foundation\nNicke Manarin\nThe Scribus Team\nThe ScummVM Team\nspikespaz\nSejda BV\nDatalust Pty Ltd\nMicrosoft Corporation\nShareX Team\nRandyRants.com\nMeltytech, LLC\nSigil-Ebook\nOpen Whisper Systems\nOpen Whisper Systems\nOpen Whisper Systems\nOpen Whisper Systems\nOpen Whisper Systems\nOpen Whisper Systems\nOpen Whisper Systems\nApproximatrix, LLC\nAshley Stone\nSkype Technologies S.A.\nSkype Technologies S.A.\nSkype Technologies S.A.\nSlack Technologies\nTechSmith Corporation\nSnakeNest.com\nCory Plotts\nSmartBear Software\nSonic Pi\nSonos, Inc.\nSonos, Inc.\nAntoine Aflalo\nAtlassian\nSpeedCrunch\nSpek Project\nStandard Notes\nValve Corporation\nhttp://www.sbcl.org\nSteelSeries ApS\nStellarium team\nStellarium team\nStellarium team\nstrawberryperl.com project\nGeneral Workings, Inc.\nGeneral Workings, Inc.\nGeneral Workings, Inc.\nStreamlink\nSebastian Meyer\nJan Hovancik\nJan Hovancik\nJan Hovancik\nStride\nBrickLink Corporation\nSublime HQ Pty Ltd\nSublime HQ Pty Ltd\nKrzysztof Kowalczyk\nSuperCollider Community\nSuperTuxKart\nMicrosoft\nSyncTrayzor\nMister Group\nOpenVPN Technologies, Inc.\nerengy\nTailscale Inc.\nTailscale Inc.\nTaisei Project\nTaskcade Inc.\nTaskcade Inc.\n\"Treasure Data, Inc\"\nTreasure Data, Inc\nBenito van der Zander\nTeX Users Group\nTeamSpeak Systems GmbH\nTechPowerUp\nTelegram FZ-LLC\nTelegram FZ-LLC\nTelegram FZ-LLC\nTelegram FZ-LLC\nTelegram FZ-LLC\nTelegram FZ-LLC\nTelegram FZ-LLC\nTelegram FZ-LLC\nTelegram FZ-LLC\nTeraTerm Project\nEugene Pankov\nEugene Pankov\nEugene Pankov\nCompuPhase\nTesseract-OCR community\nTexmaker\nTexnomic\nRaMMicHaeL\nAppest.com\nGlavSoft LLC.\nTikzEdt\nmapeditor.org\nNadeo\nToggl\nToggl\nTortoiseGit\nTortoiseSVN\nTortoiseSVN\nTranslucentTB Open Source Developers\nTransmission Project\nYury Sidorov & Transmission Remote GUI working group\nBinary Fortress Software\nBinary Fortress Software\nJAM Software\nJAM Software\nTrelby.org\nCerulean Studios, LLC\nTunnelBear\nNew Breed Software\nInspect Element Inc.\nXander Frangos\nTwitch Interactive, Inc.\nG DATA CyberDefense AG\nSafelyRemove.com\nDrew Naylor\nDrew Naylor\nUltimaker B.V.\nUltimaker B.V.\nUltimaker B.V.\nuvnc bvba\nReason Software Company Inc.\nUnified Intents AB\nUnity Technologies Inc.\nMicrosoft Corporation\nMicrosoft Corporation\nUbisoft\nUMEZAWA Takeshi\nVCV\nVideoLAN\nVideoLAN\nVideoLAN\nVMware, Inc.\nVMware, Inc.\nVMware, Inc.\nRealVNC Ltd\nRealVNC Ltd\nMicrosoft Corporation\nMicrosoft Corporation\nmarha@users.sourceforge.net\nBram Moolenaar et al.\nVirt Manager Project\nVivaldi Technologies AS.\nBlack Tree Gaming Ltd.\nVoyagerX, Inc.\nLunarG, Inc.\nWarzone 2100 Project\nWaterfox\nWaterfox\nWaterfox\nDevolutions Inc.\nBuds\nBuds\nBuds\nBuds\nMachine Learning Group, University of Waikato, Hamilton, NZ\nImageWriter Developers\nSam Hocevar\nTimothy Johnson\nTimothy Johnson\nTimothy Johnson\nNavimatics LLC\nHTTrack\nThingamahoochie Software\nwin.rar GmbH\nwin.rar GmbH\nMartin Prikryl\nCorel Corporation\nWinamp SA\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nDynastream Innovations, Inc.\nSilicon Labs Software\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nMicrosoft Corporation\nWireGuard LLC\nThe Wireshark developer community, https://www.wireshark.org\nThe Wireshark developer community, https://www.wireshark.org\nThe Wireshark developer community, https://www.wireshark.org\nThe Wireshark developer community, https://www.wireshark.org\nAntibody Software\nAntibody Software\nAntibody Software\nAntibody Software\nAntibody Software\nAutomattic Inc.\nAutomattic Inc.\nAutomattic Inc.\nAutomattic Inc.\nRob Caelers & Raymond Penners\nWritage\nX2Go Project\nBitnami\nChristian Hohnstaedt\nThe TBOOX Open Source Group\nXMind Ltd.\nGougelet Pierre-e\nGougelet Pierre-e\nYarn Contributors\nBeijing Yinxiang Biji Technologies Co., Ltd.\nBeijing Yinxiang Biji Technologies Co., Ltd.\nBeijing Yinxiang Biji Technologies Co., Ltd.\nBeijing Yinxiang Biji Technologies Co., Ltd.\nBeijing Yinxiang Biji Technologies Co., Ltd.\nAdler Luiz\nYubico AB\nZentimo.com\nZeroTier, Inc.\nHendrik Erz\nRobin Stuart & BogDan Vatra\nZoom\nZoom\nCorporation for Digital Scholarship\nKandra Labs, Inc.\nSangoma Technologies Corp.\nZygor Guides\nBalena Inc.\nBalena Inc.\nBalena Inc.\nBalena Inc.\nBalena Inc.\nBalena Inc.\nBalena Inc.\nBalena Inc.\nNathaniel Johns\nClement Tsang\nbutterflow-ui @ github\nKovid Goyal\nElliott Zheng\nthe darktable project\ndnGrep Community Contributors\nJGraph\nHardcoded Software\neM Client Inc.\nEbbflow.io\nf.lux Software LLC\nKurata Sayuri\nwereturtle\ngnuplot development team\nStefans Tools\nDrew Naylor\nDrew Naylor\nDrew Naylor\neVenture Limited\neVenture Limited\nPurpleI2P\nVantage Linguistics\nApple Inc.\nKDE e.V.\nKDE e.V.\nNext Generation Software\nMaxima Team\nFrank Skare (stax76)\n720kb\nxiles\nownCloud GmbH\nEasternGraphics\nLaurent P. Ren© de Cotret\nThe pgAdmin Development Team\nThe pgAdmin Development Team\nThe pgAdmin Development Team\nThe pgAdmin Development Team\nThe qBittorrent project\nThe qBittorrent project\nThe qBittorrent project\nremote.it\nremote.it\nLightbend, Inc.\nScilab Enterprises\nThe Sqlectron Team\nJan Hovancik\nOliver Schwendener\nOliver Schwendener\nOliver Schwendener\nHumanity\nHumanity\nMicrosoft Corporation\nAlipay.com Co., Ltd.\n百度在线网络技术（北京）有限公司\n腾讯科技(深圳)有限公司\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallFlowTest_AbortsTerminal.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.1.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestInstaller\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Installer\r\nShortDescription: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExe\r\nLicense: Test\r\nInstallerAbortsTerminal: true\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: exe\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestType: singleton\r\nManifestVersion: 1.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallFlowTest_EncodedUrl.yaml",
    "content": "Id: AppInstallerCliTest.UrlEncodeTest\r\nVersion: 1.0.0.0\r\nName: AppInstaller Test Exe Installer\r\nPublisher: Microsoft Corporation\r\nAppMoniker: AICLITestExe\r\nLicense: Test\r\nProductCode: AppInstallerCliTest.TestExeInstaller\r\nInstallers: \r\n    - Arch: x64\r\n      Url: https://EncodedUrlTest/%E6%B5%8B%E8%AF%95.exe\r\n      InstallerType: exe\r\n      Sha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n      Switches:\r\n        Custom: /encodedUrl\r\n        SilentWithProgress: /silentwithprogress\r\n        Silent: /silence\r\n        Update: /update\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallFlowTest_Exe.yaml",
    "content": "Id: AppInstallerCliTest.TestExeInstaller\r\nVersion: 1.0.0.0\r\nName: AppInstaller Test Exe Installer\r\nPublisher: Microsoft Corporation\r\nAppMoniker: AICLITestExe\r\nLicense: Test\r\nProductCode: AppInstallerCliTest.TestExeInstaller\r\nInstallers: \r\n    - Arch: x64\r\n      Url: https://ThisIsNotUsed\r\n      InstallerType: exe\r\n      Sha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n      Scope: user\r\n      Switches:\r\n        Custom: /custom /scope=user\r\n        SilentWithProgress: /silentwithprogress\r\n        Silent: /silence\r\n        Update: /update\r\n    - Arch: x64\r\n      Url: https://ThisIsNotUsed\r\n      InstallerType: exe\r\n      Sha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n      Scope: machine\r\n      Switches:\r\n        Custom: /custom /scope=machine\r\n        SilentWithProgress: /silentwithprogress\r\n        Silent: /silence\r\n        Update: /update\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallFlowTest_ExpectedReturnCodes.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.2.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.ExpectedReturnCodes\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: TestExeInstallerWithExpectedReturnCodes\r\nShortDescription: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExe\r\nLicense: Test\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: exe\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n      ExpectedReturnCodes:\r\n          - InstallerReturnCode: 1\r\n            ReturnResponse: packageInUse\r\n          - InstallerReturnCode: 2\r\n            ReturnResponse: installInProgress\r\n          - InstallerReturnCode: 3\r\n            ReturnResponse: fileInUse\r\n          - InstallerReturnCode: 4\r\n            ReturnResponse: missingDependency\r\n          - InstallerReturnCode: 5\r\n            ReturnResponse: diskFull\r\n          - InstallerReturnCode: 6\r\n            ReturnResponse: insufficientMemory\r\n          - InstallerReturnCode: 7\r\n            ReturnResponse: noNetwork\r\n          - InstallerReturnCode: 8\r\n            ReturnResponse: contactSupport\r\n            ReturnResponseUrl: https://TestReturnResponseUrl\r\n          - InstallerReturnCode: 9\r\n            ReturnResponse: rebootRequiredToFinish\r\n          - InstallerReturnCode: 10\r\n            ReturnResponse: rebootRequiredForInstall\r\n          - InstallerReturnCode: 11\r\n            ReturnResponse: rebootInitiated\r\n          - InstallerReturnCode: 12\r\n            ReturnResponse: cancelledByUser\r\n          - InstallerReturnCode: 13\r\n            ReturnResponse: alreadyInstalled\r\n          - InstallerReturnCode: 14\r\n            ReturnResponse: downgrade\r\n          - InstallerReturnCode: 15\r\n            ReturnResponse: blockedByPolicy\r\nManifestType: singleton\r\nManifestVersion: 1.2.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallFlowTest_InstallLocationRequired.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.1.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestInstaller\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Installer\r\nShortDescription: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExe\r\nLicense: Test\r\nInstallLocationRequired: true\r\nInstallerSwitches:\r\n    InstallLocation: /InstallDir <INSTALLPATH>\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: exe\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestType: singleton\r\nManifestVersion: 1.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallFlowTest_InstallationNotes.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.2.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestInstaller\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Installer\r\nShortDescription: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExe\r\nLicense: Test\r\nInstallationNotes: testInstallationNotes\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: exe\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestType: singleton\r\nManifestVersion: 1.2.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallFlowTest_InvalidFileCharacterUrl.yaml",
    "content": "Id: AppInstallerCliTest.InvalidFileCharacterUrlTest\r\nVersion: 1.0.0.0\r\nName: AppInstaller Test Exe Installer\r\nPublisher: Microsoft Corporation\r\nAppMoniker: AICLITestExe\r\nLicense: Test\r\nProductCode: AppInstallerCliTest.TestExeInstaller\r\nInstallers: \r\n    - Arch: x64\r\n      Url: https://EncodedUrlTest/te*st.exe\r\n      InstallerType: exe\r\n      Sha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n      Switches:\r\n        Custom: /invalidFileCharacterUrl\r\n        SilentWithProgress: /silentwithprogress\r\n        Silent: /silence\r\n        Update: /update\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallFlowTest_LicenseAgreement.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.1.0.schema.json\r\n\r\nPackageIdentifier: TestInstaller.WithLicenseAgreement\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExe\r\nLicense: Test\r\nShortDescription: TestInstallerWithLicenseAgreement\r\nAgreements:\r\n  - AgreementLabel: Agreement with text\r\n    Agreement: This is the text of the agreement.\r\n  - AgreementLabel: Agreement with URL\r\n    AgreementUrl: https://TestAgreementUrl\r\nInstallerSwitches:\r\n  SilentWithProgress: /silentwithprogress\r\n  Silent: /silence\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerUrl: https://ThisIsNotUsed\r\n    InstallerType: exe\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestType: singleton\r\nManifestVersion: 1.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallFlowTest_MSStore.yaml",
    "content": "Id: AppInstallerCliTest.TestMSStoreInstaller\r\nVersion: Latest\r\nName: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nAppMoniker: AICLITestMSStore\r\nLicense: Test\r\nInstallers: \r\n    - Arch: neutral\r\n      Url: https://ThisIsNotUsed\r\n      InstallerType: msstore\r\n      ProductId: 9WZDNCRFJ364\r\n      PackageFamilyName: Microsoft.SkypeApp_kzf8qxf38zg5c\r\nManifestVersion: 0.2.0-msstore\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallFlowTest_Msix_DownloadFlow.yaml",
    "content": "﻿Id: AppInstallerCliTest.TestMsixInstaller\r\nVersion: 1.0.0.0\r\nName: AppInstaller Test MSIX Installer\r\nPublisher: Microsoft Corporation\r\nAppMoniker: AICLITestMsix\r\nLicense: Test\r\nInstallers: \r\n    - Arch: x64\r\n      Url: https://github.com/microsoft/msix-packaging/blob/master/src/test/testData/unpack/TestAppxPackage_x64.appx?raw=true\r\n      InstallerType: msix\r\n      Sha256: 6a2d3683fa19bf00e58e07d1313d20a5f5735ebbd6a999d33381d28740ee07ea\r\n      PackageFamilyName: 20477fca-282d-49fb-b03e-371dca074f0f_8wekyb3d8bbwe\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallFlowTest_Msix_StreamingFlow.yaml",
    "content": "﻿Id: AppInstallerCliTest.TestMsixInstaller\r\nVersion: 1.0.0.0\r\nName: AppInstaller Test MSIX Installer\r\nPublisher: Microsoft Corporation\r\nAppMoniker: AICLITestMsix\r\nLicense: Test\r\nInstallers: \r\n    - Arch: x64\r\n      Url: https://github.com/microsoft/msix-packaging/blob/master/src/test/testData/unpack/TestAppxPackage_x64.appx?raw=true\r\n      InstallerType: msix\r\n      Sha256: 6a2d3683fa19bf00e58e07d1313d20a5f5735ebbd6a999d33381d28740ee07ea\r\n      SignatureSha256: 138781c3e6f635240353f3d14d1d57bdcb89413e49be63b375e6a5d7b93b0d07\r\n      PackageFamilyName: 20477fca-282d-49fb-b03e-371dca074f0f_8wekyb3d8bbwe\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallFlowTest_MultipleDependencies.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.3.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestExeInstaller.MultipleDependencies\r\nPackageVersion: 1.0.0.0\r\nPackageName: AppInstaller Test Installer\r\nPackageLocale: en-US\r\nPublisher: Microsoft Corporation\r\nShortDescription: Installs exe installer with multiple dependencies\r\nMoniker: AICLITestExe\r\nLicense: Test\r\nInstallerSwitches:\r\n  Custom: /custom\r\n  SilentWithProgress: /silentwithprogress\r\n  Silent: /silence\r\n  Upgrade: /upgrade\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: exe\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n      Dependencies:\r\n        PackageDependencies:\r\n        - PackageIdentifier: Dependency1\r\n        - PackageIdentifier: Dependency2\r\nManifestType: singleton\r\nManifestVersion: 1.3.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallFlowTest_NoApplicableArchitecture.yaml",
    "content": "Id: AppInstallerCliTest.TestInstaller\r\nVersion: 1.0.0.0\r\nName: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nAppMoniker: AICLITestExe\r\nLicense: Test\r\nSwitches:\r\n  Custom: /custom\r\n  SilentWithProgress: /silentwithprogress\r\n  Silent: /silence\r\nInstallers: \r\n    - Arch: unknown\r\n      Url: https://ThisIsNotUsed\r\n      InstallerType: exe\r\n      Sha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallFlowTest_NonZeroExitCode.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.0.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestInstaller\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExe\r\nLicense: Test\r\nShortDescription: AppInstaller Test Installer\r\nInstallerSwitches:\r\n  Custom: /ExitCode 0x80070005\r\n  SilentWithProgress: /silentwithprogress\r\n  Silent: /silence\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: exe\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n      InstallerSuccessCodes:\r\n        - -2147024891\r\nManifestType: singleton\r\nManifestVersion: 1.0.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallFlowTest_Portable.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.2.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestPortableInstaller\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Portable Exe\r\nPublisher: Microsoft Corporation\r\nAppMoniker: AICLITestPortable\r\nLicense: Test\r\nProductCode: AppInstallerCliTest.TestPortableInstaller__TestSource\r\nShortDescription: AppInstaller Test Portable Exe\r\nInstallers:\r\n    - Architecture: x64\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: portable\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestType: singleton\r\nManifestVersion: 1.2.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallFlowTest_Portable_WithCommand.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.2.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestPortableInstaller\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Portable Exe\r\nPublisher: Microsoft Corporation\r\nAppMoniker: AICLITestPortable\r\nLicense: Test\r\nShortDescription: AppInstaller Test Portable Exe\r\nInstallers:\r\n    - Architecture: x64\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: portable\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n      Commands:\r\n        - portableCommand\r\nManifestType: singleton\r\nManifestVersion: 1.2.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallFlowTest_UnknownVersion.yaml",
    "content": "# Test manifest for upgrading a package with an unknown version.\r\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.3.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestExeUnknownVersion\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Exe Unknown Version\r\nPublisher: Microsoft Corporation\r\nAppMoniker: AICLITestExe\r\nLicense: Test\r\nSwitches:\r\n  SilentWithProgress: /silentwithprogress\r\n  Silent: /silence\r\n  Update: /update\r\nInstallers:\r\n    - Architecture: x64\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: exe\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestType: singleton\r\nManifestVersion: 1.3.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallFlowTest_UnsupportedArguments.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.2.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestInstaller\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Installer\r\nShortDescription: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExe\r\nLicense: Test\r\nUnsupportedArguments:\r\n    - log\r\n    - location\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: exe\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestType: singleton\r\nManifestVersion: 1.2.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallFlowTest_WindowsFeatures.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.WindowsFeatures\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Installer\r\nShortDescription: Installs exe installer with valid Windows Features dependencies\r\nPublisher: Microsoft Corporation\r\nLicense: Test\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: exe\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n      InstallerSwitches:\r\n        Custom: /custom /scope=machine\r\n        SilentWithProgress: /silentwithprogress\r\n        Silent: /silence\r\n        Update: /update\r\n      Dependencies:\r\n        WindowsFeatures:\r\n        - testFeature1\r\n        - testFeature2\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallFlowTest_Zip_Exe.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestZipInstaller\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Zip Installer\r\nShortDescription: AppInstaller Test Zip Installer with exe\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestZip\r\nLicense: Test\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: zip\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n      NestedInstallerType: exe\r\n      NestedInstallerFiles:\r\n        - RelativeFilePath: relativeFilePath\r\n      InstallerSwitches:\r\n        Custom: /custom /scope=machine\r\n        SilentWithProgress: /silentwithprogress\r\n        Silent: /silence\r\n        Update: /update\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallFlowTest_Zip_MissingNestedInstaller.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestZipInstaller\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Zip Installer\r\nShortDescription: AppInstaller Test Zip Installer with exe\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestZip\r\nLicense: Test\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: zip\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n      NestedInstallerType: exe\r\n      InstallerSwitches:\r\n        Custom: /custom /scope=machine\r\n        SilentWithProgress: /silentwithprogress\r\n        Silent: /silence\r\n        Update: /update\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallFlowTest_Zip_MultipleNonPortableNestedInstallers.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestZipInstaller\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Zip Installer\r\nShortDescription: AppInstaller Test Zip Installer with exe\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestZip\r\nLicense: Test\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: zip\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n      NestedInstallerType: exe\r\n      NestedInstallerFiles:\r\n        - RelativeFilePath: installerOne.exe\r\n        - RelativeFilePath: installerTwo.exe\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallFlowTest_Zip_UnsupportedNestedInstaller.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestZipInstaller\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Zip Installer\r\nShortDescription: AppInstaller Test Zip Installer with exe\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestZip\r\nLicense: Test\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: zip\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n      NestedInstallerType: msstore\r\n      InstallerSwitches:\r\n        Custom: /custom /scope=machine\r\n        SilentWithProgress: /silentwithprogress\r\n        Silent: /silence\r\n        Update: /update\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallerArgTest_Inno_NoSwitches.yaml",
    "content": "Id: AppInstallerCliTest.TestInstaller\r\nVersion: 1.0.0.0\r\nName: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nAppMoniker: AICLITest\r\nLicense: Test\r\nInstallers: \r\n    - Arch: x64\r\n      Url: https://ThisIsNotUsed\r\n      InstallerType: inno\r\n      Sha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallerArgTest_Inno_WithSwitches.yaml",
    "content": "Id: AppInstallerCliTest.TestInstaller\r\nVersion: 1.0.0.0\r\nName: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nAppMoniker: AICLITest\r\nLicense: Test\r\nInstallers: \r\n    - Arch: x64\r\n      Url: https://ThisIsNotUsed\r\n      InstallerType: inno\r\n      Sha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n      Switches:\r\n        Custom: /mycustom\r\n        SilentWithProgress: /mysilentwithprogress\r\n        Silent: /mysilent\r\n        Log: /mylog=\"<LOGPATH>\"\r\n        InstallLocation: /myinstalldir=\"<INSTALLPATH>\"\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallerArgTest_Msi_NoSwitches.yaml",
    "content": "Id: AppInstallerCliTest.TestInstaller\r\nVersion: 1.0.0.0\r\nName: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nAppMoniker: AICLITest\r\nLicense: Test\r\nInstallers: \r\n    - Arch: x64\r\n      Url: https://ThisIsNotUsed\r\n      InstallerType: msi\r\n      Sha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n      ProductCode: '{A5D36CF1-1993-4F63-BFB4-3ACD910D36A1}'\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/InstallerArgTest_Msi_WithSwitches.yaml",
    "content": "Id: AppInstallerCliTest.TestInstaller\r\nVersion: 1.0.0.0\r\nName: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nAppMoniker: AICLITest\r\nLicense: Test\r\nInstallers: \r\n    - Arch: x64\r\n      Url: https://ThisIsNotUsed\r\n      InstallerType: msi\r\n      Sha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n      ProductCode: '{A5D36CF1-1993-4F63-BFB4-3ACD910D36A1}'\r\n      Switches:\r\n        Custom: /mycustom\r\n        SilentWithProgress: /mysilentwithprogress\r\n        Silent: /mysilent\r\n        Log: /mylog=\"<LOGPATH>\"\r\n        InstallLocation: /myinstalldir=\"<INSTALLPATH>\"\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Installer_Exe_Dependencies.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.0.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestExeInstaller.Dependencies\r\nPackageVersion: '1.0'\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Exe Installer With Package Dep\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExePackageDep\r\nLicense: Test\r\nShortDescription: AppInstaller Test Exe Installer With Package Dep\r\nInstallers:\r\n    - Architecture: x64\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: exe\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n      InstallerSwitches:\r\n        SilentWithProgress: /silentwithprogress\r\n        Silent: /silence\r\n      Dependencies:\r\n        WindowsFeatures:\r\n          - PreviewIIS\r\nManifestType: singleton\r\nManifestVersion: 1.0.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Installer_Exe_DependenciesMultideclaration.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.0.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestExeInstaller.Dependencies\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Exe Installer With Package Dep\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExePackageDep\r\nLicense: Test\r\nShortDescription: AppInstaller Test Exe Installer With Package Dep\r\nDependencies:\r\n    WindowsFeatures:\r\n        - PreviewIISOnRoot\r\nInstallers:\r\n    - Architecture: x64\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: exe\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n      InstallerSwitches:\r\n        SilentWithProgress: /silentwithprogress\r\n        Silent: /silence\r\n      Dependencies:\r\n        WindowsFeatures:\r\n          - PreviewIIS\r\nManifestType: singleton\r\nManifestVersion: 1.0.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Installer_Exe_DependenciesOnRoot.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.0.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestExeInstaller.Dependencies\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Exe Installer With Package Dep\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExePackageDep\r\nLicense: Test\r\nShortDescription: AppInstaller Test Exe Installer With Package Dep\r\nDependencies:\r\n    WindowsFeatures:\r\n        - PreviewIISOnRoot\r\nInstallers:\r\n    - Architecture: x64\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: exe\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n      InstallerSwitches:\r\n        SilentWithProgress: /silentwithprogress\r\n        Silent: /silence\r\nManifestType: singleton\r\nManifestVersion: 1.0.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Installer_Msix_WFDependency.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.0.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestMsixInstaller.WFDep\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test MSIX Installer With Windows Feature Dep\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestMsixWindowsFeatureDep\r\nLicense: Test\r\nShortDescription: AppInstaller Test MSIX Installer With Windows Feature Dep\r\nInstallers:\r\n    - Architecture: x64\r\n      InstallerUrl: https://github.com/microsoft/msix-packaging/blob/master/src/test/testData/unpack/TestAppxPackage_x64.appx?raw=true\r\n      InstallerType: msix\r\n      InstallerSha256: 6a2d3683fa19bf00e58e07d1313d20a5f5735ebbd6a999d33381d28740ee07ea\r\n      PackageFamilyName: 20477fca-282d-49fb-b03e-371dca074f0f_8wekyb3d8bbwe\r\n      Dependencies:\r\n        WindowsFeatures:\r\n          - Hyper-V\r\nManifestType: singleton\r\nManifestVersion: 1.0.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-ApproximateVersionInArpVersion.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.1.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-US\nPublisher: Microsoft\nAuthor: Microsoft\nPackageName: MSIX SDK\nLicense: MIT License\nShortDescription: This is MSIX SDK\n\nInstallers:\n  - Architecture: x86\n    InstallerType: inno\n    InstallerUrl: https://www.microsoft.com/msixsdk/setup.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    AppsAndFeaturesEntries:\n    - DisplayVersion: \"< 12.0\"\n\nManifestType: singleton\nManifestVersion: 1.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-ApproximateVersionInPackageVersion.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.1.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: \"> 1.7.32\"\nPackageLocale: en-US\nPublisher: Microsoft\nAuthor: Microsoft\nPackageName: MSIX SDK\nLicense: MIT License\nShortDescription: This is MSIX SDK\n\nInstallers:\n  - Architecture: x86\n    InstallerType: inno\n    InstallerUrl: https://www.microsoft.com/msixsdk/setup.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n\nManifestType: singleton\nManifestVersion: 1.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-AppsAndFeaturesEntriesOnMSIX.yaml",
    "content": "# Bad manifest. Invalid Arch value\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.1.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageName: MSIX SDK\nPackageVersion: 1.7.32\nPublisher: Microsoft\nLicense: Test\nShortDescription: desc\nPackageLocale: en-US\nInstallers:\n  - Architecture: x86\n    InstallerType: msix\n    InstallerUrl: https://ThisIsNotUsed\n    InstallerSha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\n    AppsAndFeaturesEntries:\n      - DisplayName: DisplayName\n        DisplayVersion: DisplayVersion\n        Publisher: Publisher\n        ProductCode: ProductCode\n        UpgradeCode: UpgradeCode\n\nManifestType: singleton\nManifestVersion: 1.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-ArchInvalid.yaml",
    "content": "# Bad manifest. Invalid Arch value\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nPublisher: Microsoft\nInstallerType: Msi\nLicense: Test\nInstallers:\n  - Arch: NotAnArch\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-ArchMissing.yaml",
    "content": "# Bad manifest. No Name\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nPublisher: Microsoft\nInstallerType: Msi\nLicense: Test\nInstallers:\n  - Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-Channel-NotSupported.yaml",
    "content": "Id: microsoft.msixsdk\r\nName: MSIX SDK\r\nVersion: 1.7.32\r\nPublisher: Microsoft\r\nChannel: release\r\nInstallerType: Msi\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://ThisIsNotUsed\r\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-DifferentCase-UPPER.yaml",
    "content": "# Bad manifest. InstallerType is UPPER\r\nId: microsoft.msixsdk\r\nName: MSIX SDK\r\nVersion: 1.7.32\r\nPublisher: Microsoft\r\nINSTALLERTYPE: Msi\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://ThisIsNotUsed\r\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-DifferentCase-camelCase.yaml",
    "content": "# Bad manifest. InstallerType is camelCased\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nPublisher: Microsoft\ninstallerType: Msi\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-DifferentCase-lower.yaml",
    "content": "# Bad manifest. InstallerType is lower case\r\nId: microsoft.msixsdk\r\nName: MSIX SDK\r\nVersion: 1.7.32\r\nPublisher: Microsoft\r\ninstallertype: Msi\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://ThisIsNotUsed\r\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-DuplicateKey-DifferentCase-lower.yaml",
    "content": "# Bad manifest. Duplicated key with different casing convention.\r\nId: microsoft.msixsdk\r\nName: MSIX SDK\r\nVersion: 1.7.32\r\nPublisher: Microsoft\r\nInstallerType: Msi\r\ninstallertype: Msi\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://ThisIsNotUsed\r\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-DuplicateKey-DifferentCase.yaml",
    "content": "# Bad manifest. Duplicated key with different casing convention.\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nPublisher: Microsoft\nInstallerType: Msi\ninstallerType: Msi\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-DuplicateKey.yaml",
    "content": "# Bad manifest. Duplicated key Id\nId: microsoft.msixsdk\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nPublisher: Microsoft\nInstallerType: Msi\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-DuplicateReturnCode-ExpectedCodes.yaml",
    "content": "# Bad manifest. Expected return codes repeat the same return code\r\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.1.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestInstaller\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Installer\r\nShortDescription: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExe\r\nLicense: Test\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: exe\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n      ExpectedReturnCodes:\r\n        - InstallerReturnCode: 1\r\n          ReturnResponse: packageInUse\r\n        - InstallerReturnCode: 1\r\n          ReturnResponse: installInProgress\r\nManifestType: singleton\r\nManifestVersion: 1.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-DuplicateReturnCode-SuccessCodes.yaml",
    "content": "# Bad manifest. Expected return codes repeat the same return code\r\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.1.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestInstaller\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Installer\r\nShortDescription: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExe\r\nLicense: Test\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: exe\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n      InstallerSuccessCodes:\r\n          - 1\r\n      ExpectedReturnCodes:\r\n          - InstallerReturnCode: 1\r\n            ReturnResponse: packageInUse\r\nManifestType: singleton\r\nManifestVersion: 1.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-DuplicateSha256.yaml",
    "content": "# Bad manifest. Different URLs point to two the same InstallerSha256\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nPublisher: Microsoft\nInstallerType: Msi\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\n    Language: en-US\n  - Arch: x86\n    Url: https://ThisIsNotUsed2\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\n    Language: es-MX\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-IdInvalid.yaml",
    "content": "# Bad manifest. Invalid Id\nId: m i c rosoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nInstallerType: Msi\nPublisher: Microsoft\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-IdMissing.yaml",
    "content": "# Bad manifest. No Id\nName: MSIX SDK\nVersion: 1.7.32\nInstallerType: Msi\nPublisher: Microsoft\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InconsistentMsixBundleInstallerFields.yaml",
    "content": "# Bad manifest: Inconsistent field values in unsigned MSIX bundle\nPackageIdentifier: AppInstallerCliTest.InconsistentMsixBundleInstallerFields\nPackageVersion: 1.2.3.4                           # Mismatching value with msix installer\nPackageLocale: es-MX\nPackageName: es-MX package name\nPublisher: es-MX publisher\nPackageFamilyName: FakeInstallerForTesting_Bad    # Mismatching value with msix installer\nMinimumOSVersion: 5.6.7.8                         # Mismatching value with msix installer\nInstallerType: msix\nInstallers: \n    - Architecture: x64\n      InstallerUrl: Installer-Good.msixbundle\n      SignatureSha256: 0000000000000000000000000000000000000000000000000000000000000000 # Unexpected value for unsigned msix installer\nManifestType: merged\nManifestVersion: 1.0.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InconsistentMsixInstallerFields.yaml",
    "content": "# Bad manifest: Inconsistent field values in unsigned MSIX\nPackageIdentifier: AppInstallerCliTest.InconsistentMsixInstallerFields\nPackageVersion: 1.2.3.4                           # Mismatching value with msix installer\nPackageLocale: es-MX\nPackageName: es-MX package name\nPublisher: es-MX publisher\nPackageFamilyName: FakeInstallerForTesting_Bad    # Mismatching value with msix installer\nMinimumOSVersion: 5.6.7.8                         # Mismatching value with msix installer\nInstallerType: msix\nInstallers: \n    - Architecture: x64\n      InstallerUrl: Installer-Good.msix\n      SignatureSha256: 0000000000000000000000000000000000000000000000000000000000000000 # Unexpected value for unsigned msix installer\nManifestType: merged\nManifestVersion: 1.0.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InconsistentSha256.yaml",
    "content": "# Bad manifest. Same URL points to two different InstallerSha256\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.10.0.schema.json\n\nPackageIdentifier: AppInstallerCliTest.TestPortableInstaller\nPackageVersion: 1.0.0.0\nPackageLocale: en-US\nPackageName: AppInstaller Test Portable Exe\nPublisher: Microsoft Corporation\nAppMoniker: AICLITestPortable\nLicense: Test\nProductCode: AppInstallerCliTest.TestPortableInstaller__TestSource\nShortDescription: Url points to two different InstallerSha256\nInstallers:\n    - Architecture: x86\n      InstallerUrl: https://ThisIsNotUsed\n      InstallerType: portable\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\n    - Architecture: x64\n      InstallerUrl: https://ThisIsNotUsed\n      InstallerType: portable\n      InstallerSha256: A111111111111111111111111111111111111111111111111111111111111111\nManifestType: singleton\nManifestVersion: 1.10.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InconsistentSignedMsixBundleInstallerFields.yaml",
    "content": "# Bad manifest: Inconsistent field values in signed MSIX bundle\nPackageIdentifier: AppInstallerCliTest.InconsistentMsixBundleInstallerFields\nPackageVersion: 1.2.3.4                           # Mismatching value with msix installer\nPackageLocale: es-MX\nPackageName: es-MX package name\nPublisher: es-MX publisher\nPackageFamilyName: FakeInstallerForTesting_Bad    # Mismatching value with msix installer\nMinimumOSVersion: 5.6.7.8                         # Mismatching value with msix installer\nInstallerType: msix\nInstallers: \n    - Architecture: x64\n      InstallerUrl: Installer-Signed-Good.msixbundle\n      SignatureSha256: 0000000000000000000000000000000000000000000000000000000000000000 # Inconsistent signature hash\nManifestType: merged\nManifestVersion: 1.0.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InconsistentSignedMsixInstallerFields.yaml",
    "content": "# Bad manifest: Inconsistent field values in signed MSIX\nPackageIdentifier: AppInstallerCliTest.InconsistentMsixInstallerFields\nPackageVersion: 1.2.3.4                           # Mismatching value with msix installer\nPackageLocale: es-MX\nPackageName: es-MX package name\nPublisher: es-MX publisher\nPackageFamilyName: FakeInstallerForTesting_Bad    # Mismatching value with msix installer\nMinimumOSVersion: 5.6.7.8                         # Mismatching value with msix installer\nInstallerType: msix\nInstallers: \n    - Architecture: x64\n      InstallerUrl: Installer-Signed-Good.msix\n      SignatureSha256: 0000000000000000000000000000000000000000000000000000000000000000 # Inconsistent signature hash\nManifestType: merged\nManifestVersion: 1.0.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InstallerTypeExe-NoSilent.yaml",
    "content": "# Bad manifest. Installer Type exe requires Silent switch.\r\nId: microsoft.msixsdk\r\nName: MSIX SDK\r\nVersion: 1.7.32\r\nPublisher: Microsoft\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://ThisIsNotUsed\r\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\r\n    InstallerType: Exe\r\n    Switches:\r\n      Interactive: /i\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InstallerTypeExe-NoSilentRoot.yaml",
    "content": "# Bad manifest. Installer Type exe requires Silent switch.\r\nId: microsoft.msixsdk\r\nName: MSIX SDK\r\nVersion: 1.7.32\r\nPublisher: Microsoft\r\nLicense: Test\r\nSwitches:\r\n  Interactive: /i\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://ThisIsNotUsed\r\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\r\n    InstallerType: Exe\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InstallerTypeExeRoot-NoSilent.yaml",
    "content": "# Bad manifest. Installer Type exe requires Silent switch.\r\nId: microsoft.msixsdk\r\nName: MSIX SDK\r\nVersion: 1.7.32\r\nPublisher: Microsoft\r\nInstallerType: Exe\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://ThisIsNotUsed\r\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\r\n    Switches:\r\n      Interactive: /i\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InstallerTypeExeRoot-NoSilentRoot.yaml",
    "content": "# Bad manifest. Installer Type exe requires Silent switch.\r\nId: microsoft.msixsdk\r\nName: MSIX SDK\r\nVersion: 1.7.32\r\nPublisher: Microsoft\r\nInstallerType: Exe\r\nLicense: Test\r\nSwitches:\r\n  Interactive: /i\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://ThisIsNotUsed\r\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InstallerTypeInvalid.yaml",
    "content": "# Bad Manifest. Invalid value for InstallerType.\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nPublisher: Microsoft\nInstallerType: NotAType\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InstallerTypeMissing.yaml",
    "content": "# Bad manifest. No InstallerType\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nPublisher: Microsoft\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InstallerTypePortable-InvalidAppsAndFeatures.yaml",
    "content": "# Bad manifest. Installer Type portable can only have zero or one AppsAndFeatureEntry defined.\r\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.2.0.schema.json\r\n\r\nPackageIdentifier: TestInstaller.WithLicenseAgreement\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExe\r\nLicense: Test\r\nShortDescription: TestInstallerWithLicenseAgreement\r\nAppsAndFeaturesEntries:\r\n  - DisplayName: DisplayName1\r\n    DisplayVersion: DisplayVersion1\r\n    Publisher: Publisher1\r\n    ProductCode: ProductCode1\r\n    UpgradeCode: UpgradeCode1\r\n  - DisplayName: DisplayName2\r\n    DisplayVersion: DisplayVersion2\r\n    Publisher: Publisher2\r\n    ProductCode: ProductCode2\r\n    UpgradeCode: UpgradeCode2\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://ThisIsNotUsed\r\n    InstallerType: portable\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n  - Architecture: x86\r\n    InstallerUrl: https://ThisIsNotUsed2\r\n    InstallerType: portable\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n    AppsAndFeaturesEntries:\r\n      - DisplayName: DisplayName1\r\n        DisplayVersion: DisplayVersion1\r\n        Publisher: Publisher1\r\n        ProductCode: ProductCode1\r\n        UpgradeCode: UpgradeCode1\r\n      - DisplayName: DisplayName2\r\n        DisplayVersion: DisplayVersion2\r\n        Publisher: Publisher2\r\n        ProductCode: ProductCode2\r\n        UpgradeCode: UpgradeCode2\r\nManifestType: singleton\r\nManifestVersion: 1.2.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InstallerTypePortable-InvalidCommands.yaml",
    "content": "# Bad manifest. Installer Type portable can only have one or zero commands defined.\r\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.2.0.schema.json\r\n\r\nPackageIdentifier: TestInstaller.WithLicenseAgreement\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExe\r\nLicense: Test\r\nShortDescription: TestInstallerWithLicenseAgreement\r\nCommands:\r\n  - Command1\r\n  - Command2\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://ThisIsNotUsed\r\n    InstallerType: portable\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n  - Architecture: x86\r\n    InstallerUrl: https://ThisIsNotUsed2\r\n    InstallerType: portable\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n    Commands:\r\n      - Command1\r\n      - Command2\r\nManifestType: singleton\r\nManifestVersion: 1.2.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InstallerTypePortable-InvalidScope.yaml",
    "content": "# Bad manifest. Installer Type portable does not support scope and should show a warning.\r\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.2.0.schema.json\r\n\r\nPackageIdentifier: TestInstaller.WithLicenseAgreement\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExe\r\nLicense: Test\r\nShortDescription: TestInstallerWithLicenseAgreement\r\nScope: user\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://ThisIsNotUsed\r\n    InstallerType: portable\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n    Scope: Machine\r\n  - Architecture: x86\r\n    InstallerUrl: https://ThisIsNotUsed2\r\n    InstallerType: portable\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestType: singleton\r\nManifestVersion: 1.2.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InstallerTypeZip-DuplicateCommandAlias.yaml",
    "content": "# Bad manifest. Installer type zip should not have any duplicate PortableCommandAlias values.\r\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: microsoft.msixsdk\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExe\r\nLicense: Test\r\nShortDescription: Test installer for zip without nestedInstallers specified\r\nScope: user\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://ThisIsNotUsed\r\n    InstallerType: zip\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n    NestedInstallerFiles:\r\n      - RelativeFilePath: relativeFilePath1\r\n        PortableCommandAlias: DUPLICATEALIAS\r\n      - RelativeFilePath: relativeFilePath2\r\n        PortableCommandAlias: duplicateAlias\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InstallerTypeZip-DuplicateRelativeFilePath.yaml",
    "content": "# Bad manifest. Installer type zip should not have any duplicate PortableCommandAlias values.\r\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: microsoft.msixsdk\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExe\r\nLicense: Test\r\nShortDescription: Test installer for zip without nestedInstallers specified\r\nScope: user\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://ThisIsNotUsed\r\n    InstallerType: zip\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n    NestedInstallerFiles:\r\n      - RelativeFilePath: RELATIVEFILEPATH\r\n        PortableCommandAlias: alias1\r\n      - RelativeFilePath: relativefilepath\r\n        PortableCommandAlias: alias2\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InstallerTypeZip-InvalidRelativeFilePath.yaml",
    "content": "# Bad manifest. A nested installer file must have a RelativeFilePath specified.\r\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: microsoft.msixsdk\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExe\r\nLicense: Test\r\nShortDescription: Test installer for zip without RelativeFilePath specified\r\nScope: user\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://ThisIsNotUsed\r\n    InstallerType: zip\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n    NestedInstallerType: exe\r\n    NestedInstallerFiles:\r\n      - RelativeFilePath: ../../relativeFilePath\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InstallerTypeZip-MissingRelativeFilePath.yaml",
    "content": "# Bad manifest. A nested installer file must have a RelativeFilePath specified.\r\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: microsoft.msixsdk\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExe\r\nLicense: Test\r\nShortDescription: Test installer for zip without RelativeFilePath specified\r\nScope: user\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://ThisIsNotUsed\r\n    InstallerType: zip\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n    NestedInstallerType: exe\r\n    NestedInstallerFiles:\r\n      - PortableCommandAlias: portableCommandAlias\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InstallerTypeZip-MultipleNestedInstallers.yaml",
    "content": "# Bad manifest. Installer type zip should have exactly one NestedInstaller specified.\r\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: microsoft.msixsdk\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExe\r\nLicense: Test\r\nShortDescription: Test installer for zip with too many nestedInstallers specified.\r\nScope: user\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://ThisIsNotUsed\r\n    InstallerType: zip\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n    NestedInstallerType: msi\r\n    NestedInstallerFiles:\r\n      - RelativeFilePath: relativeFilePath1\r\n        PortableCommandAlias: portableCommandAlias1\r\n      - RelativeFilePath: relativeFilePath2\r\n        PortableCommandAlias: portableCommandAlias2\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InstallerTypeZip-NoNestedInstallerFile.yaml",
    "content": "# Bad manifest. Installer type zip should have exactly one NestedInstaller specified.\r\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: microsoft.msixsdk\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExe\r\nLicense: Test\r\nShortDescription: Test installer for zip without nestedInstallers specified\r\nScope: user\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://ThisIsNotUsed\r\n    InstallerType: zip\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n    NestedInstallerType: exe\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InstallerTypeZip-NoNestedInstallerType.yaml",
    "content": "# Bad manifest. Installer type zip should have exactly one NestedInstaller specified.\r\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: microsoft.msixsdk\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExe\r\nLicense: Test\r\nShortDescription: Test installer for zip without nestedInstallers specified\r\nScope: user\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://ThisIsNotUsed\r\n    InstallerType: zip\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n    NestedInstallerFiles:\r\n      - RelativeFilePath: relativeFilePath\r\n        PortableCommandAlias: portableCommandAlias\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InstallerTypeZip-PortableNotExe.yaml",
    "content": "# Bad manifest. Installer type zip with NestedInstallerType portable should only allow .exe files\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.9.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.0.0.0\nPackageLocale: en-US\nPackageName: AppInstaller Test Installer\nPublisher: Microsoft Corporation\nMoniker: AICLITestExe\nLicense: Test\nShortDescription: Test installer for zip without nestedInstallers specified\nInstallers:\n  - Architecture: x64\n    InstallerUrl: https://ThisIsNotUsed\n    InstallerType: zip\n    NestedInstallerType: portable\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\n    NestedInstallerFiles:\n      - RelativeFilePath: ScriptedApplication.bat\nManifestType: singleton\nManifestVersion: 1.9.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InstallerTypeZip-PortableNotExe_Root.yaml",
    "content": "# Bad manifest. Installer type zip with NestedInstallerType portable should only allow .exe files\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.9.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.0.0.0\nPackageLocale: en-US\nPackageName: AppInstaller Test Installer\nPublisher: Microsoft Corporation\nMoniker: AICLITestExe\nLicense: Test\nShortDescription: Test installer for zip without nestedInstallers specified\nInstallerType: zip\nNestedInstallerType: portable\nNestedInstallerFiles:\n  - RelativeFilePath: ScriptedApplication.bat\nInstallers:\n  - Architecture: x64\n    InstallerUrl: https://ThisIsNotUsed\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\nManifestType: singleton\nManifestVersion: 1.9.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InstallerUniqueness-DefaultScope.yaml",
    "content": "# Bad Manifest. Uniqueness installers same arch, same scope. Default scope is user\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nPublisher: Microsoft\nInstallerType: Msi\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\n    Scope: user\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InstallerUniqueness-DefaultValues.yaml",
    "content": "# Bad Manifest. Uniqueness installers same arch, same default values\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nPublisher: Microsoft\nInstallerType: Msi\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InstallerUniqueness-SameLang.yaml",
    "content": "# Bad Manifest. Uniqueness installers same arch, language and scope\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nPublisher: Microsoft\nInstallerType: Msi\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\n    Language: en-US\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\n    Language: en-US\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InstallerUniqueness.yaml",
    "content": "# Bad Manifest. Uniqueness installers same arch, language and scope\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nPublisher: Microsoft\nInstallerType: Msi\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\n    Language: en-US\n    Scope: user\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\n    Language: en-US\n    Scope: user\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InstallersMissing.yaml",
    "content": "# Bad manifest. Installers missing\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nInstallerType: Msi\nPublisher: Microsoft\nLicense: Test\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InvalidLocale.yaml",
    "content": "# Bad manifest. Invalid locale.\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.0.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.0.0\nPackageName: MSIX SDK\nPublisher: Microsoft\nInstallerType: msi\nLicense: Test\nShortDescription: Test invalid locale\nInstallers:\n  - Architecture: x86\n    InstallerUrl: https://ThisIsNotUsed\n    InstallerSha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\n\nPackageLocale: In-val-id-Lo-ca-le\nManifestType: singleton\nManifestVersion: 1.0.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InvalidManifestVersionValue.yaml",
    "content": "# Bad manifest. Unsupported version\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.0.0.0\nPublisher: Microsoft\nInstallerType: Msi\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\nManifestVersion: 0.1.0-invalid\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-InvalidUpdateBehavior.yaml",
    "content": "# Bad manifest. Invalid UpdateBehavior\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nPublisher: Microsoft\nInstallerType: Msi\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: NotAUrl\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\n    UpdateBehavior: InvalidUpdate\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-LicenseMissing.yaml",
    "content": "Id: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.07.32-beta\nPublisher: Microsoft\nInstallerType: Msi\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-MissingMsixInstallerFields.yaml",
    "content": "PackageIdentifier: AppInstallerCliTest.MissingMsixInstallerFields\nPackageVersion: 43690.48059.52428.56797\nPackageLocale: es-MX\nPackageName: es-MX package name\nPublisher: es-MX publisher\n# PackageFamilyName: FakeInstallerForTesting_125rzkzqaqjwj    # Missing field\n# MinimumOSVersion: 10.0.16299.0                              # Missing field\nInstallerType: msix\nInstallers: \n    - Architecture: x64\n      InstallerUrl: Installer-Good.msix\nManifestType: merged\nManifestVersion: 1.0.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-MsixInstaller-PackageVersion.yaml",
    "content": "PackageIdentifier: AppInstallerCliTest.BadMsixInstaller-PackageVersion\nPackageVersion: test.version # Version cannot be parsed to UINT64\nPackageLocale: es-MX\nPackageName: es-MX package name\nPublisher: es-MX publisher\nPackageFamilyName: FakeInstallerForTesting_125rzkzqaqjwj\nMinimumOSVersion: 10.0.0.0\nInstallerType: msix\nInstallers: \n    - Architecture: x64\n      InstallerUrl: Installer-Good.msix\nManifestType: merged\nManifestVersion: 1.0.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-NameMissing.yaml",
    "content": "# Bad manifest. No Name\nId: microsoft.msixsdk\nVersion: 1.7.32\nPublisher: Microsoft\nInstallerType: Msi\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-NoSupportedPlatforms.yaml",
    "content": "PackageIdentifier: AppInstallerCliTest.NoSupportedPlatforms\nPackageVersion: 43690.48059.52428.56797\nPackageLocale: es-MX\nPackageName: es-MX package name\nPublisher: es-MX publisher\nPackageFamilyName: FakeInstallerForTesting_125rzkzqaqjwj\nMinimumOSVersion: 10.0.16299.0\nInstallerType: msix\nInstallers: \n    - Architecture: x64\n      InstallerUrl: Installer-Bad-NoSupportedPlatforms.msix\nManifestType: merged\nManifestVersion: 1.0.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-PackageFamilyNameOnMSI.yaml",
    "content": "# Bad manifest. Invalid Arch value\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nPublisher: Microsoft\nLicense: Test\nInstallers:\n  - Arch: x86\n    InstallerType: MSI\n    PackageFamilyName: Foo_123456789abcd\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-ProductCodeOnMSIX.yaml",
    "content": "# Bad manifest. Invalid Arch value\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nPublisher: Microsoft\nLicense: Test\nInstallers:\n  - Arch: x86\n    InstallerType: MSIX\n    ProductCode: \"{FOO}\"\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-PublisherMissing.yaml",
    "content": "# Bad manifest. Publisher missing\r\nId: microsoft.msixsdk\r\nName: MSIX SDK\r\nVersion: 1.7.32\r\nInstallerType: Zip\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://ThisIsNotUsed\r\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-Sha256Invalid.yaml",
    "content": "# Bad manifest. Invalid Sha256\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nPublisher: Microsoft\nInstallerType: Msi\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B6\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-Sha256Missing.yaml",
    "content": "# Bad manifest. No Sha256\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nPublisher: Microsoft\nInstallerType: Msi\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-SwitchInvalid.yaml",
    "content": "# Bad manifest. Incorrect switch key.\r\nId: microsoft.msixsdk\r\nName: MSIX SDK\r\nVersion: 1.7.32\r\nPublisher: Microsoft\r\nInstallerType: Exe\r\nLicense: Test\r\nSwitches:\r\n  NotASwitch: /fakeswitch\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://ThisIsNotUsed\r\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-UnknownProperty.yaml",
    "content": "# Bad manifest. Contains a key that is not in the manifest object.\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nPublisher: Microsoft\nInstallerType: Exe\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\nFake: this is Fake\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-UnsupportedVersion.yaml",
    "content": "# Bad manifest. Unsupported version\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.0.0.0\nPublisher: Microsoft\nInstallerType: Msi\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\nManifestVersion: 1000.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-UrlInvalid.yaml",
    "content": "# Bad manifest. Invalid Url\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nPublisher: Microsoft\nInstallerType: Msi\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: NotAUrl\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-UrlMissing.yaml",
    "content": "# Bad manifest. No Url\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nPublisher: Microsoft\nInstallerType: Msi\nLicense: Test\nInstallers:\n  - Arch: x86\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-VersionInvalid.yaml",
    "content": "# Bad manifest. Invalid version\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.0.9-/\nPublisher: Microsoft\nInstallerType: Msi\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Bad-VersionMissing.yaml",
    "content": "# Bad manifest. No Version\nId: microsoft.msixsdk\nName: MSIX SDK\nPublisher: Microsoft\nInstallerType: Msi\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Encoding-ANSI.yaml",
    "content": "Id: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nInstallerType: Msi\nPublisher: Microsoft\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Encoding-UTF8-BOM.yaml",
    "content": "﻿Id: microsoft.msixsdk\nName: MSIX SDK©\nVersion: 1.7.32\nInstallerType: Msi\nPublisher: Microsoft\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Encoding-UTF8.yaml",
    "content": "Id: microsoft.msixsdk\nName: MSIX SDK©\nVersion: 1.7.32\nInstallerType: Msi\nPublisher: Microsoft\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Good-AllDependencyTypes.yaml",
    "content": "# Installer with all types of dependencies\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.0.0.schema.json\n\nPackageIdentifier: AppInstallerCliTest.TestMsixInstaller\nPackageVersion: 1.0.0.0\nPackageLocale: en-US\nPackageName: AppInstaller Test MSIX Installer\nShortDescription: AppInstaller Test MSIX Installer\nPublisher: Microsoft Corporation\nMoniker: AICLITestMsix\nLicense: Test\nInstallers:\n  - Architecture: x64\n    InstallerUrl: https://github.com/microsoft/msix-packaging/blob/master/src/test/testData/unpack/TestAppxPackage_x64.appx?raw=true\n    InstallerType: msix\n    InstallerSha256: 6a2d3683fa19bf00e58e07d1313d20a5f5735ebbd6a999d33381d28740ee07ea\n    PackageFamilyName: 20477fca-282d-49fb-b03e-371dca074f0f_8wekyb3d8bbwe\n    Dependencies:\n      WindowsFeatures:\n        - WindowsFeaturesDep1\n        - WindowsFeaturesDep2\n      WindowsLibraries:\n        - WindowsLibrariesDep\n      PackageDependencies:\n        - PackageIdentifier: Package.Dep1-x64\n          MinimumVersion: '1.0'\n        - PackageIdentifier: Package.Dep2-x64\n      ExternalDependencies:\n        - ExternalDep\nManifestType: singleton\nManifestVersion: 1.0.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Good-DefaultExpectedReturnCodeInInstallerSuccessCodes.yaml",
    "content": "# Default expected return codes exist in InstallerSuccessCodes\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.1.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageName: MSIX SDK\nPackageVersion: 1.07.32-beta\nPublisher: Microsoft\nShortDescription: description\nLicense: Test\nPackageLocale: en-US\nInstallerSuccessCodes:\n- 1603\n- 3010\nInstallers:\n  - Architecture: x86\n    InstallerUrl: https://rubengustorage.blob.core.windows.net/publiccontainer/msixsdk-x86.msi\n    InstallerSha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\n    InstallerType: msi\nManifestType: singleton\nManifestVersion: 1.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Good-InstallerTypeExe-Silent.yaml",
    "content": "# Good manifest. Installer Type exe requires Silent switch.\r\nId: microsoft.msixsdk\r\nName: MSIX SDK\r\nVersion: 1.7.32\r\nPublisher: Microsoft\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://rubengustorage.blob.core.windows.net/publiccontainer/msixsdk-x86.zip\r\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\r\n    InstallerType: Exe\r\n    Switches:\r\n      Silent: /s\r\n      SilentWithProgress: /s\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Good-InstallerTypeExe-SilentRoot.yaml",
    "content": "# Good manifest. Installer Type exe requires Silent switch.\r\nId: microsoft.msixsdk\r\nName: MSIX SDK\r\nVersion: 1.7.32\r\nPublisher: Microsoft\r\nLicense: Test\r\nSwitches:\r\n  Silent: /s\r\n  SilentWithProgress: /s\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://rubengustorage.blob.core.windows.net/publiccontainer/msixsdk-x86.zip\r\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\r\n    InstallerType: Exe\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Good-InstallerTypeExeRoot-Silent.yaml",
    "content": "# Good manifest. Installer Type exe requires Silent switch.\r\nId: microsoft.msixsdk\r\nName: MSIX SDK\r\nVersion: 1.7.32\r\nPublisher: Microsoft\r\nInstallerType: Exe\r\nLicense: Test\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://rubengustorage.blob.core.windows.net/publiccontainer/msixsdk-x86.zip\r\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\r\n    Switches:\r\n      Silent: /s\r\n      SilentWithProgress: /s\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Good-InstallerTypeExeRoot-SilentRoot.yaml",
    "content": "# Good manifest. Installer Type exe requires Silent switch.\r\nId: microsoft.msixsdk\r\nName: MSIX SDK\r\nVersion: 1.7.32\r\nPublisher: Microsoft\r\nInstallerType: Exe\r\nLicense: Test\r\nSwitches:\r\n  Silent: /s\r\n  SilentWithProgress: /s\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://rubengustorage.blob.core.windows.net/publiccontainer/msixsdk-x86.zip\r\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Good-InstallerTypeZip-PortableExe.yaml",
    "content": "# Bad manifest. Installer type zip with NestedInstallerType portable should only allow .exe files\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.9.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.0.0.0\nPackageLocale: en-US\nPackageName: AppInstaller Test Installer\nPublisher: Microsoft Corporation\nMoniker: AICLITestExe\nLicense: Test\nShortDescription: Test installer for zip without nestedInstallers specified\nInstallers:\n  - Architecture: x64\n    InstallerUrl: https://ThisIsNotUsed\n    InstallerType: zip\n    NestedInstallerType: portable\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\n    NestedInstallerFiles:\n      - RelativeFilePath: GoodApplication.exe\nManifestType: singleton\nManifestVersion: 1.9.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Good-InstallerUniqueness-DiffScope.yaml",
    "content": "# Good Manifest. Uniqueness installers different scope same arch\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nPublisher: Microsoft\nInstallerType: Msi\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\n    Scope: user\n  - Arch: x86\n    Url: https://ThisIsNotUsed2\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCE\n    Scope: machine\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Good-Installeruniqueness-DefaultLang.yaml",
    "content": "# Good Manifest. Uniqueness installers different languages same arch, with default language\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nPublisher: Microsoft\nInstallerType: Msi\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\n  - Arch: x86\n    Url: https://ThisIsNotUsed2\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCE\n    Language: en-MX\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Good-Installeruniqueness-DiffLangs.yaml",
    "content": "# Good Manifest. Uniqueness installers different languages same arch\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nPublisher: Microsoft\nInstallerType: Msi\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\n    Language: en-US\n  - Arch: x86\n    Url: https://ThisIsNotUsed2\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCE\n    Language: es-MX\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Good-Minimum-InstallerType.yaml",
    "content": "# Minimum required InstallerType in Installers\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.7.32\nPublisher: Microsoft\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\n    InstallerType: Msi\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Good-Minimum.yaml",
    "content": "# Minimum required\nId: microsoft.msixsdk\nName: MSIX SDK\nVersion: 1.07.32-beta\nPublisher: Microsoft\nInstallerType: Msi\nLicense: Test\nInstallers:\n  - Arch: x86\n    Url: https://ThisIsNotUsed\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Good-MsixBundleInstaller-WithStub.yaml",
    "content": "PackageIdentifier: AppInstallerCliTest.GoodMsixBundleInstaller\nPackageVersion: 43690.48059.52428.56797\nPackageLocale: es-MX\nPackageName: es-MX package name\nPublisher: es-MX publisher\nPackageFamilyName: FakeInstallerForTesting_125rzkzqaqjwj\nMinimumOSVersion: 10.0.16299.0\nInstallerType: msix\nInstallers: \n    - Architecture: x64\n      InstallerUrl: Installer-Good-WithStub.msixbundle\nManifestType: merged\nManifestVersion: 1.0.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Good-MsixBundleInstaller.yaml",
    "content": "PackageIdentifier: AppInstallerCliTest.GoodMsixBundleInstaller\nPackageVersion: 43690.48059.52428.56797\nPackageLocale: es-MX\nPackageName: es-MX package name\nPublisher: es-MX publisher\nPackageFamilyName: FakeInstallerForTesting_125rzkzqaqjwj\nMinimumOSVersion: 10.0.16299.0\nInstallerType: msix\nInstallers: \n    - Architecture: x64\n      InstallerUrl: Installer-Good.msixbundle\nManifestType: merged\nManifestVersion: 1.0.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Good-MsixInstaller.yaml",
    "content": "PackageIdentifier: AppInstallerCliTest.GoodMsixInstaller\nPackageVersion: 43690.48059.52428.56797\nPackageLocale: es-MX\nPackageName: es-MX package name\nPublisher: es-MX publisher\nPackageFamilyName: FakeInstallerForTesting_125rzkzqaqjwj\nMinimumOSVersion: 10.0.0.0\nInstallerType: msix\nInstallers: \n    - Architecture: x64\n      InstallerUrl: Installer-Good.msix\nManifestType: merged\nManifestVersion: 1.0.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Good-MultiLocale.yaml",
    "content": "PackageIdentifier: AppInstallerCliTest.MultiLocaleTest\nPackageVersion: 1.0.0.0\nPackageLocale: es-MX\nPackageName: es-MX package name\nPublisher: es-MX publisher\nMoniker: AICLITestExe\nLicense: Test\nInstallerType: exe\nInstallers: \n    - Architecture: x64\n      InstallerUrl: https://ThisIsNotUsed\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\n      InstallerSwitches:\n        Custom: /unknownLocale\n        SilentWithProgress: /silentwithprogress\n        Silent: /silence\n    - Architecture: x64\n      InstallerUrl: https://ThisIsNotUsed\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\n      InstallerLocale: en-GB\n      InstallerSwitches:\n        Custom: /en-GB\n        SilentWithProgress: /silentwithprogress\n        Silent: /silence\n    - Architecture: x64\n      InstallerUrl: https://ThisIsNotUsed\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\n      InstallerLocale: fr-FR\n      InstallerSwitches:\n        Custom: /fr-FR\n        SilentWithProgress: /silentwithprogress\n        Silent: /silence\nLocalization:\n    - PackageLocale: en-GB\n      PackageName: en-GB package name\n      Publisher: en-GB publisher\n    - PackageLocale: fr-FR\n      PackageName: fr-FR package name\n\nManifestType: merged\nManifestVersion: 1.0.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Good-MultipleArpVersionDeclared.yaml",
    "content": "PackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-US\nPublisher: Microsoft\nAuthor: Microsoft\nPackageName: MSIX SDK\nLicense: MIT License\nShortDescription: This is MSIX SDK\n\nInstallers:\n  - Architecture: x86\n    InstallerType: inno\n    InstallerUrl: https://www.microsoft.com/msixsdk/setup.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    AppsAndFeaturesEntries:\n    - DisplayVersion: \"12.0\"\n  - Architecture: x64\n    InstallerType: inno\n    InstallerUrl: https://www.microsoft.com/msixsdk/setup.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    AppsAndFeaturesEntries:\n    - DisplayVersion: \"13.0\"\n\nManifestType: merged\nManifestVersion: 1.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Good-NoArpVersionDeclared.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.1.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-US\nPublisher: Microsoft\nAuthor: Microsoft\nPackageName: MSIX SDK\nLicense: MIT License\nShortDescription: This is MSIX SDK\n\nInstallers:\n  - Architecture: x86\n    InstallerType: inno\n    InstallerUrl: https://www.microsoft.com/msixsdk/setup.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n\nManifestType: singleton\nManifestVersion: 1.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Good-SignedMsixBundleInstaller.yaml",
    "content": "PackageIdentifier: AppInstallerCliTest.GoodSignedMsixBundleInstaller\nPackageVersion: 43690.48059.52428.56797\nPackageLocale: es-MX\nPackageName: es-MX package name\nPublisher: es-MX publisher\nPackageFamilyName: FakeInstallerForTesting_125rzkzqaqjwj\nMinimumOSVersion: 10.0.16299.0\nInstallerType: msix\nInstallers: \n    - Architecture: x64\n      InstallerUrl: Installer-Signed-Good.msixbundle\n      SignatureSha256: d70bd623f87b6ce4ddba4506c6000cf43ef3af4ab1207f5579ec43400de1623f\nManifestType: merged\nManifestVersion: 1.0.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Good-SignedMsixInstaller.yaml",
    "content": "PackageIdentifier: AppInstallerCliTest.GoodSignedMsixInstaller\nPackageVersion: 43690.48059.52428.56797\nPackageLocale: es-MX\nPackageName: es-MX package name\nPublisher: es-MX publisher\nPackageFamilyName: FakeInstallerForTesting_125rzkzqaqjwj\nMinimumOSVersion: 10.0.0.0\nInstallerType: msix\nInstallers: \n    - Architecture: x64\n      InstallerUrl: Installer-Signed-Good.msix\n      SignatureSha256: 50562001202c8dad456474d3f20903138d0a15c44ee497c3d4f82e85edbf2f97\nManifestType: merged\nManifestVersion: 1.0.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Good-SingleArpVersionDeclared.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.1.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-US\nPublisher: Microsoft\nAuthor: Microsoft\nPackageName: MSIX SDK\nLicense: MIT License\nShortDescription: This is MSIX SDK\n\nInstallers:\n  - Architecture: x86\n    InstallerType: inno\n    InstallerUrl: https://www.microsoft.com/msixsdk/setup.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    AppsAndFeaturesEntries:\n    - DisplayVersion: \"11.0\"\n\nManifestType: singleton\nManifestVersion: 1.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Good-Spaces.yaml",
    "content": "Id:  microsoft.msixsdk  \nName: \" MSIX SDK\"\nAppMoniker: \"msixsdk\"\nVersion: 1.7.32\nPublisher: Microsoft\nChannel: release\nAuthor: Microsoft\nLicense: MIT License\nLicenseUrl: https://github.com/microsoft/msix-packaging/blob/master/LICENSE\nMinOSVersion: 0.0.0.0\nDescription: The MSIX SDK project is an effort to enable developers\nHomepage: https://github.com/microsoft/msix-packaging\nTags: \"msix, appx\"\nCommands: \"makemsix ,makeappx\"\nProtocols: \"protocol1,protocol2\"\nFileExtensions: \"appx,appxbundle,msix,msixbundle\"\n# InstallerType and Switches CAN have a \"default\" value\n# on the root. An installer can override them.\nInstallerType: Zip\nSwitches:\n  Custom: /custom\n  SilentWithProgress: /silentwithprogress\n  Silent: /silence\n  Interactive: /interactive\n  Language: /en-us\n  Log: /log=<LOGPATH>\n  InstallLocation: /dir=<INSTALLPATH>\nInstallers:\n  - Arch: x86\n    Url: https://rubengustorage.blob.core.windows.net/publiccontainer/msixsdkx86.zip\n    Sha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    Language: en-US\n    InstallerType: Zip\n    Scope: user\n    Switches:\n      Custom: /c\n      SilentWithProgress: /sp\n      Silent: /s\n      Interactive: /i\n      Language: /en\n      Log: /l=<LOGPATH>\n      InstallLocation: /d=<INSTALLPATH>\n  - Arch: x64\n    Url: https://rubengustorage.blob.core.windows.net/publiccontainer/msixsdkx64.zip\n    Sha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF0000\n    Language: en-US\n    InstallerType: Zip\n    Scope: user\nLocalization:\n  - Language: es-MX\n    Description: El proyecto MSIX SDK es habilita desarrolladores de diferentes\n    Homepage: https://github.com/microsoft/msix-packaging/es-MX\n    LicenseUrl: https://github.com/microsoft/msix-packaging/blob/master/LICENSE-es-MX\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Good-Switches.yaml",
    "content": "# Good manifest with Switches.\r\nId: microsoft.msixsdk\r\nName: MSIX SDK\r\nVersion: 1.7.32\r\nPublisher: Microsoft\r\nInstallerType: Msi\r\nLicense: Test\r\nSwitches:\r\n  SilentWithProgress: /sp\r\nInstallers:\r\n  - Arch: x86\r\n    Url: https://ThisIsNotUsed\r\n    Sha256: 98B67758CEAFFCBB3FE47838FD0A8D7BD581C2650842D6B2B0E0D49A23270CCD\r\n    Switches:\r\n      Silent: /s\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Good-SystemReferenceComplex.yaml",
    "content": "Id: microsoft.sysrefcomp\nName: Complex System Reference\nVersion: 1.7.32\nPublisher: Microsoft\nLicense: MIT License\nDescription: A complex system reference test file.\nInstallerType: exe\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\nProductCode: \"{Foo}\"\nInstallers:\n  - InstallerType: msix\n    Arch: x86\n    Url: https://rubengustorage.blob.core.windows.net/publiccontainer/msixsdkx86.zip\n    Sha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n  - InstallerType: msi\n    Arch: x86\n    Url: https://rubengustorage.blob.core.windows.net/publiccontainer/msixsdkx86.zip\n    Sha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n  - InstallerType: msix\n    Arch: x64\n    Url: https://rubengustorage.blob.core.windows.net/publiccontainer/msixsdkx86.zip\n    Sha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    PackageFamilyName: Override_8wekyb3d8bbwe\n  - InstallerType: msi\n    Arch: x64\n    Url: https://rubengustorage.blob.core.windows.net/publiccontainer/msixsdkx86.zip\n    Sha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    ProductCode: \"Override\"\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-Good.yaml",
    "content": "Id: microsoft.msixsdk\nName: MSIX SDK\nAppMoniker: msixsdk\nVersion: 1.7.32\nPublisher: Microsoft\nChannel: release\nAuthor: Microsoft\nLicense: MIT License\nLicenseUrl: https://github.com/microsoft/msix-packaging/blob/master/LICENSE\nMinOSVersion: 0.0.0.0\nDescription: The MSIX SDK project is an effort to enable developers\nHomepage: https://github.com/microsoft/msix-packaging\nTags: \"msix,appx\"\nCommands: \"makemsix,makeappx\"\nProtocols: \"protocol1,protocol2\"\nFileExtensions: \"appx,appxbundle,msix,msixbundle\"\n# InstallerType and Switches CAN have a \"default\" value\n# on the root. An installer can override them.\nInstallerType: exe\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\nProductCode: \"{Foo}\"\nUpdateBehavior: UninstallPrevious\nSwitches:\n  Custom: /custom\n  SilentWithProgress: /silentwithprogress\n  Silent: /silence\n  Interactive: /interactive\n  Language: /en-us\n  Log: /log=<LOGPATH>\n  InstallLocation: /dir=<INSTALLPATH>\n  Update: /update\nInstallers:\n  - Arch: x86\n    Url: https://rubengustorage.blob.core.windows.net/publiccontainer/msixsdkx86.zip\n    Sha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    Language: en-US\n    InstallerType: exe\n    Scope: user\n    UpdateBehavior: Install\n    Switches:\n      Custom: /c\n      SilentWithProgress: /sp\n      Silent: /s\n      Interactive: /i\n      Language: /en\n      Log: /l=<LOGPATH>\n      InstallLocation: /d=<INSTALLPATH>\n      Update: /u\n  - Arch: x64\n    Url: https://rubengustorage.blob.core.windows.net/publiccontainer/msixsdkx64.zip\n    Sha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF0000\n    Language: en-US\n    InstallerType: exe\n    Scope: user\nLocalization:\n  - Language: es-MX\n    Description: El proyecto MSIX SDK es habilita desarrolladores de diferentes\n    Homepage: https://github.com/microsoft/msix-packaging/es-MX\n    LicenseUrl: https://github.com/microsoft/msix-packaging/blob/master/LICENSE-es-MX\nManifestVersion: 0.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-MSIX-in-AppsAndFeatures.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.12.0.schema.json\n\nPackageIdentifier: Microsoft.ArchiveContainingMSIX\nPackageVersion: 1.7.32\nPackageLocale: en-US\nPublisher: Microsoft\nPublisherUrl: https://www.microsoft.com\nPublisherSupportUrl: https://www.microsoft.com/support\nPrivacyUrl: https://www.microsoft.com/privacy\nAuthor: Microsoft\nPackageName: MSIX SDK\nPackageUrl: https://www.microsoft.com/msixsdk/home\nLicense: MIT License\nLicenseUrl: https://www.microsoft.com/msixsdk/license\nCopyright: Copyright Microsoft Corporation\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright\nShortDescription: Archive with nested MSIX\nDescription: A manifest containing an archive with a nested MSIX installer\nInstallerLocale: en-US\nInstallerType: exe\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\nAppsAndFeaturesEntries:\n  - DisplayName: DisplayName\n    InstallerType: msix\nInstallerSwitches:\n  Custom: /custom\n  SilentWithProgress: /silentwithprogress\n  Silent: /silence\n  Interactive: /interactive\n  Log: /log=<LOGPATH>\n  InstallLocation: /dir=<INSTALLPATH>\n  Upgrade: /upgrade\n  Repair: /repair\n\nInstallers:\n  - Architecture: x86\n    InstallerLocale: en-GB\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n\nManifestType: singleton\nManifestVersion: 1.12.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Manifest-MSIX-in-Archive.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.12.0.schema.json\n\nPackageIdentifier: Microsoft.ArchiveContainingMSIX\nPackageVersion: 1.7.32\nPackageLocale: en-US\nPublisher: Microsoft\nPublisherUrl: https://www.microsoft.com\nPublisherSupportUrl: https://www.microsoft.com/support\nPrivacyUrl: https://www.microsoft.com/privacy\nAuthor: Microsoft\nPackageName: MSIX SDK\nPackageUrl: https://www.microsoft.com/msixsdk/home\nLicense: MIT License\nLicenseUrl: https://www.microsoft.com/msixsdk/license\nCopyright: Copyright Microsoft Corporation\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright\nShortDescription: Archive with nested MSIX\nDescription: A manifest containing an archive with a nested MSIX installer\nInstallerLocale: en-US\nInstallerType: zip\r\nNestedInstallerType: msix\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\nNestedInstallerFiles:\n  - RelativeFilePath: RelativeFilePath\n    PortableCommandAlias: PortableCommandAlias\n\nInstallers:\n  - Architecture: x86\n    InstallerLocale: en-GB\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n\nManifestType: singleton\nManifestVersion: 1.12.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ManifestV1-Singleton.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.0.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-US\nPublisher: Microsoft\nPublisherUrl: https://www.microsoft.com\nPublisherSupportUrl: https://www.microsoft.com/support\nPrivacyUrl: https://www.microsoft.com/privacy\nAuthor: Microsoft\nPackageName: MSIX SDK\nPackageUrl: https://www.microsoft.com/msixsdk/home\nLicense: MIT License\nLicenseUrl: https://www.microsoft.com/msixsdk/license\nCopyright: Copyright Microsoft Corporation\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright\nShortDescription: This is MSIX SDK\nDescription: The MSIX SDK project is an effort to enable developers\nMoniker: msixsdk\nTags:\n  - \"appxsdk\"\n  - \"msixsdk\"\nInstallerLocale: en-US\nPlatform:\n  - Windows.Desktop\n  - Windows.Universal\nMinimumOSVersion: 10.0.0.0\nInstallerType: exe\nScope: machine\nInstallModes:\n  - interactive\n  - silent\n  - silentWithProgress\nInstallerSwitches:\n  Custom: /custom\n  SilentWithProgress: /silentwithprogress\n  Silent: /silence\n  Interactive: /interactive\n  Log: /log=<LOGPATH>\n  InstallLocation: /dir=<INSTALLPATH>\n  Upgrade: /upgrade\nInstallerSuccessCodes:\n  - 1\n  - 0x80070005\nUpgradeBehavior: uninstallPrevious\nCommands:\n  - makemsix\n  - makeappx\nProtocols:\n  - protocol1\n  - protocol2\nFileExtensions:\n  - appx\n  - msix\n  - appxbundle\n  - msixbundle\nDependencies:\n  WindowsFeatures:\n    - IIS\n  WindowsLibraries:\n    - VC Runtime\n  PackageDependencies:\n    - PackageIdentifier: Microsoft.MsixSdkDep\n      MinimumVersion: 1.0.0\n  ExternalDependencies:\n    - Outside dependencies\nCapabilities:\n  - internetClient\nRestrictedCapabilities:\n  - runFullTrust\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\nProductCode: \"{Foo}\"\n\nInstallers:\n  - Architecture: x86\n    InstallerLocale: en-GB\n    Platform:\n      - Windows.Desktop\n    MinimumOSVersion: 10.0.1.0\n    InstallerType: msix\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    Scope: user\n    InstallModes:\n      - interactive\n    InstallerSwitches:\n      Custom: /c\n      SilentWithProgress: /sp\n      Silent: /s\n      Interactive: /i\n      Log: /l=<LOGPATH>\n      InstallLocation: /d=<INSTALLPATH>\n      Upgrade: /u\n    UpgradeBehavior: install\n    Commands:\n      - makemsixPreview\n      - makeappxPreview\n    Protocols:\n      - protocol1preview\n      - protocol2preview\n    FileExtensions:\n      - appxbundle\n      - msixbundle\n      - appx\n      - msix\n    Dependencies:\n      WindowsFeatures:\n        - PreviewIIS\n      WindowsLibraries:\n        - Preview VC Runtime\n      PackageDependencies:\n        - PackageIdentifier: Microsoft.MsixSdkDepPreview\n          MinimumVersion: 1.0.0\n      ExternalDependencies:\n        - Preview Outside dependencies\n    PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe\n    Capabilities:\n      - internetClientPreview\n    RestrictedCapabilities:\n      - runFullTrustPreview\n\nManifestType: singleton\nManifestVersion: 1.0.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ManifestV1_1-Singleton.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.1.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-US\nPublisher: Microsoft\nPublisherUrl: https://www.microsoft.com\nPublisherSupportUrl: https://www.microsoft.com/support\nPrivacyUrl: https://www.microsoft.com/privacy\nAuthor: Microsoft\nPackageName: MSIX SDK\nPackageUrl: https://www.microsoft.com/msixsdk/home\nLicense: MIT License\nLicenseUrl: https://www.microsoft.com/msixsdk/license\nCopyright: Copyright Microsoft Corporation\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright\nShortDescription: This is MSIX SDK\nDescription: The MSIX SDK project is an effort to enable developers\nMoniker: msixsdk\nTags:\n  - \"appxsdk\"\n  - \"msixsdk\"\nReleaseNotes: Default release notes\nReleaseNotesUrl: https://DefaultReleaseNotes.net\nAgreements:\n  - AgreementLabel: DefaultLabel\n    Agreement: DefaultText\n    AgreementUrl: https://DefaultAgreementUrl.net\nInstallerLocale: en-US\nPlatform:\n  - Windows.Desktop\n  - Windows.Universal\nMinimumOSVersion: 10.0.0.0\nInstallerType: exe\nScope: machine\nInstallModes:\n  - interactive\n  - silent\n  - silentWithProgress\nInstallerSwitches:\n  Custom: /custom\n  SilentWithProgress: /silentwithprogress\n  Silent: /silence\n  Interactive: /interactive\n  Log: /log=<LOGPATH>\n  InstallLocation: /dir=<INSTALLPATH>\n  Upgrade: /upgrade\nInstallerSuccessCodes:\n  - 1\n  - 0x80070005\nUpgradeBehavior: uninstallPrevious\nCommands:\n  - makemsix\n  - makeappx\nProtocols:\n  - protocol1\n  - protocol2\nFileExtensions:\n  - appx\n  - msix\n  - appxbundle\n  - msixbundle\nDependencies:\n  WindowsFeatures:\n    - IIS\n  WindowsLibraries:\n    - VC Runtime\n  PackageDependencies:\n    - PackageIdentifier: Microsoft.MsixSdkDep\n      MinimumVersion: 1.0.0\n  ExternalDependencies:\n    - Outside dependencies\nCapabilities:\n  - internetClient\nRestrictedCapabilities:\n  - runFullTrust\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\nProductCode: \"{Foo}\"\nReleaseDate: 2021-01-01\nInstallerAbortsTerminal: true\nInstallLocationRequired: true\nRequireExplicitUpgrade: true\nElevationRequirement: elevatesSelf\nUnsupportedOSArchitectures:\n  - arm\nAppsAndFeaturesEntries:\n  - DisplayName: DisplayName\n    DisplayVersion: DisplayVersion\n    Publisher: Publisher\n    ProductCode: ProductCode\n    UpgradeCode: UpgradeCode\n    InstallerType: exe\nMarkets:\n  AllowedMarkets:\n    - US\nExpectedReturnCodes:\n  - InstallerReturnCode: 10\n    ReturnResponse: packageInUse\n\nInstallers:\n  - Architecture: x86\n    InstallerLocale: en-GB\n    Platform:\n      - Windows.Desktop\n    MinimumOSVersion: 10.0.1.0\n    InstallerType: msix\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    Scope: user\n    InstallModes:\n      - interactive\n    InstallerSwitches:\n      Custom: /c\n      SilentWithProgress: /sp\n      Silent: /s\n      Interactive: /i\n      Log: /l=<LOGPATH>\n      InstallLocation: /d=<INSTALLPATH>\n      Upgrade: /u\n    UpgradeBehavior: install\n    Commands:\n      - makemsixPreview\n      - makeappxPreview\n    Protocols:\n      - protocol1preview\n      - protocol2preview\n    FileExtensions:\n      - appxbundle\n      - msixbundle\n      - appx\n      - msix\n    Dependencies:\n      WindowsFeatures:\n        - PreviewIIS\n      WindowsLibraries:\n        - Preview VC Runtime\n      PackageDependencies:\n        - PackageIdentifier: Microsoft.MsixSdkDepPreview\n          MinimumVersion: 1.0.0\n      ExternalDependencies:\n        - Preview Outside dependencies\n    PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe\n    Capabilities:\n      - internetClientPreview\n    RestrictedCapabilities:\n      - runFullTrustPreview\n    ReleaseDate: 2021-02-02\n    InstallerAbortsTerminal: false\n    InstallLocationRequired: false\n    RequireExplicitUpgrade: false\n    ElevationRequirement: elevationRequired\n    UnsupportedOSArchitectures:\n      - arm64\n    Markets:\n      ExcludedMarkets:\n        - \"US\"\n    ExpectedReturnCodes:\n      - InstallerReturnCode: 2\n        ReturnResponse: contactSupport\n\nManifestType: singleton\nManifestVersion: 1.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ManifestV1_10-Bad-SchemaHeaderInvalid.yaml",
    "content": "# yaml-language-server= $schema=https://aka.ms/winget-manifest.singleton.1.10.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.SchemaHeaderInvalid\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Schema Header Invalid\r\nPublisher: Microsoft Corporation\r\nLicense: Test\r\nShortDescription: This manifest has an invalid schema header\r\n\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerUrl: https://ThisIsNotUsed\r\n    InstallerType: msi\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestType: singleton\r\nManifestVersion: 1.10.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ManifestV1_10-Bad-SchemaHeaderManifestTypeMismatch.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.10.0.schema.json\r\nPackageIdentifier: AppInstallerCliTest.SchemaHeaderManifestTypeMismatch\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Schema Header ManifestType Mismatch\r\nPublisher: Microsoft Corporation\r\nLicense: Test\r\nShortDescription: This manifest has a mismatched ManisfestType in the schema header\r\n\r\nInstallers: \r\n  - Architecture: x86\r\n    InstallerUrl: https://ThisIsNotUsed\r\n    InstallerType: msi\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestType: singleton\r\nManifestVersion: 1.10.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ManifestV1_10-Bad-SchemaHeaderManifestVersionMismatch.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.9.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.SchemaHeaderVersionMismatch\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Schema Header ManifestVersion Mismatch\r\nPublisher: Microsoft Corporation\r\nLicense: Test\r\nShortDescription: This manifest has a mismatched ManisfestVersion in the schema header\r\n\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerUrl: https://ThisIsNotUsed\r\n    InstallerType: msi\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestType: singleton\r\nManifestVersion: 1.10.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ManifestV1_10-Bad-SchemaHeaderNotFound.yaml",
    "content": "PackageIdentifier: AppInstallerCliTest.SchemaHeaderNotFound\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Schema Header Not Found\r\nPublisher: Microsoft Corporation\r\nLicense: Test\r\nShortDescription: This manifest has a missing schema header\r\n\r\nInstallers: \r\n  - Architecture: x86\r\n    InstallerUrl: https://ThisIsNotUsed\r\n    InstallerType: msi\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestType: singleton\r\nManifestVersion: 1.10.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ManifestV1_10-Bad-SchemaHeaderURLPatternMismatch.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest-invalid.singleton.1.10.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.SchemaHeaderURLPatternMismatch\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Schema Header URL Pattern Mismatch\r\nPublisher: Microsoft Corporation\r\nLicense: Test\r\nShortDescription: This manifest has a mismatched schema header URL pattern\r\n\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerUrl: https://ThisIsNotUsed\r\n    InstallerType: msi\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestType: singleton\r\nManifestVersion: 1.10.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ManifestV1_10-InstallerAuthentication.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.10.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.InstallerAuthentication\r\nPackageVersion: 1.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Installer Authentication\r\nPublisher: Microsoft Corporation\r\nAppMoniker: AICLITestInstallerAuthentication\r\nLicense: Test\r\nAuthentication:\r\n  AuthenticationType: microsoftEntraId\r\n  MicrosoftEntraIdAuthenticationInfo:\r\n    Resource: TestResource\r\n    Scope: TestScope\r\nShortDescription: Test installer for authentication\r\n\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerUrl: https://ThisIsNotUsed\r\n    InstallerType: msi\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n    Authentication:\r\n      AuthenticationType: microsoftEntraIdForAzureBlobStorage\r\nManifestType: singleton\r\nManifestVersion: 1.10.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ManifestV1_10-Singleton.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.10.0.schema.json\r\n\r\nPackageIdentifier: microsoft.msixsdk\r\nPackageVersion: 1.7.32\r\nPackageLocale: en-US\r\nPublisher: Microsoft\r\nPublisherUrl: https://www.microsoft.com\r\nPublisherSupportUrl: https://www.microsoft.com/support\r\nPrivacyUrl: https://www.microsoft.com/privacy\r\nAuthor: Microsoft\r\nPackageName: MSIX SDK\r\nPackageUrl: https://www.microsoft.com/msixsdk/home\r\nLicense: MIT License\r\nLicenseUrl: https://www.microsoft.com/msixsdk/license\r\nCopyright: Copyright Microsoft Corporation\r\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright\r\nShortDescription: This is MSIX SDK\r\nDescription: The MSIX SDK project is an effort to enable developers\r\nMoniker: msixsdk\r\nTags:\r\n  - \"appxsdk\"\r\n  - \"msixsdk\"\r\nReleaseNotes: Default release notes\r\nReleaseNotesUrl: https://DefaultReleaseNotes.net\r\nPurchaseUrl: https://DefaultPurchaseUrl.com\r\nInstallationNotes: Default installation notes\r\nDocumentations:\r\n  - DocumentLabel: Default document label\r\n    DocumentUrl: https://DefaultDocumentUrl.com\r\nIcons:\r\n  - IconUrl: https://testIcon-en-US\r\n    IconFileType: ico\r\n    IconResolution: custom\r\n    IconTheme: default\r\n    IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\r\nAgreements:\r\n  - AgreementLabel: DefaultLabel\r\n    Agreement: DefaultText\r\n    AgreementUrl: https://DefaultAgreementUrl.net\r\nInstallerLocale: en-US\r\nPlatform:\r\n  - Windows.Desktop\r\n  - Windows.Universal\r\nMinimumOSVersion: 10.0.0.0\r\nInstallerType: exe\r\nScope: machine\r\nInstallModes:\r\n  - interactive\r\n  - silent\r\n  - silentWithProgress\r\nInstallerSwitches:\r\n  Custom: /custom\r\n  SilentWithProgress: /silentwithprogress\r\n  Silent: /silence\r\n  Interactive: /interactive\r\n  Log: /log=<LOGPATH>\r\n  InstallLocation: /dir=<INSTALLPATH>\r\n  Upgrade: /upgrade\r\n  Repair: /repair\r\nInstallerSuccessCodes:\r\n  - 1\r\n  - 0x80070005\r\nUpgradeBehavior: uninstallPrevious\r\nRepairBehavior: modify\r\nCommands:\r\n  - makemsix\r\n  - makeappx\r\nProtocols:\r\n  - protocol1\r\n  - protocol2\r\nFileExtensions:\r\n  - appx\r\n  - msix\r\n  - appxbundle\r\n  - msixbundle\r\nDependencies:\r\n  WindowsFeatures:\r\n    - IIS\r\n  WindowsLibraries:\r\n    - VC Runtime\r\n  PackageDependencies:\r\n    - PackageIdentifier: Microsoft.MsixSdkDep\r\n      MinimumVersion: 1.0.0\r\n  ExternalDependencies:\r\n    - Outside dependencies\r\nCapabilities:\r\n  - internetClient\r\nRestrictedCapabilities:\r\n  - runFullTrust\r\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\r\nProductCode: \"{Foo}\"\r\nReleaseDate: 2021-01-01\r\nInstallerAbortsTerminal: true\r\nInstallLocationRequired: true\r\nRequireExplicitUpgrade: true\r\nDisplayInstallWarnings: true\r\nElevationRequirement: elevatesSelf\r\nUnsupportedOSArchitectures:\r\n  - arm\r\nAppsAndFeaturesEntries:\r\n  - DisplayName: DisplayName\r\n    DisplayVersion: DisplayVersion\r\n    Publisher: Publisher\r\n    ProductCode: ProductCode\r\n    UpgradeCode: UpgradeCode\r\n    InstallerType: exe\r\nMarkets:\r\n  AllowedMarkets:\r\n    - US\r\nExpectedReturnCodes:\r\n  - InstallerReturnCode: 10\r\n    ReturnResponse: packageInUse\r\n    ReturnResponseUrl: https://DefaultReturnResponseUrl.com\r\nUnsupportedArguments:\r\n  - log\r\nNestedInstallerType: msi\r\nNestedInstallerFiles:\r\n  - RelativeFilePath: RelativeFilePath\r\n    PortableCommandAlias: PortableCommandAlias\r\nInstallationMetadata:\r\n  DefaultInstallLocation: \"%ProgramFiles%\\\\TestApp\"\r\n  Files:\r\n    - RelativeFilePath: \"main.exe\"\r\n      FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n      FileType: launch\r\n      InvocationParameter: \"/arg\"\r\n      DisplayName: \"DisplayName\"\r\nDownloadCommandProhibited: true\r\nArchiveBinariesDependOnPath: true\r\n\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerLocale: en-GB\r\n    Platform:\r\n      - Windows.Desktop\r\n    MinimumOSVersion: 10.0.1.0\r\n    InstallerType: msix\r\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix\r\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n    SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n    Scope: user\r\n    InstallModes:\r\n      - interactive\r\n    InstallerSwitches:\r\n      Custom: /c\r\n      SilentWithProgress: /sp\r\n      Silent: /s\r\n      Interactive: /i\r\n      Log: /l=<LOGPATH>\r\n      InstallLocation: /d=<INSTALLPATH>\r\n      Upgrade: /u\r\n      Repair: /r\r\n    UpgradeBehavior: install\r\n    Commands:\r\n      - makemsixPreview\r\n      - makeappxPreview\r\n    Protocols:\r\n      - protocol1preview\r\n      - protocol2preview\r\n    FileExtensions:\r\n      - appxbundle\r\n      - msixbundle\r\n      - appx\r\n      - msix\r\n    Dependencies:\r\n      WindowsFeatures:\r\n        - PreviewIIS\r\n      WindowsLibraries:\r\n        - Preview VC Runtime\r\n      PackageDependencies:\r\n        - PackageIdentifier: Microsoft.MsixSdkDepPreview\r\n          MinimumVersion: 1.0.0\r\n      ExternalDependencies:\r\n        - Preview Outside dependencies\r\n    PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe\r\n    Capabilities:\r\n      - internetClientPreview\r\n    RestrictedCapabilities:\r\n      - runFullTrustPreview\r\n    ReleaseDate: 2021-02-02\r\n    InstallerAbortsTerminal: false\r\n    InstallLocationRequired: false\r\n    RequireExplicitUpgrade: false\r\n    DisplayInstallWarnings: false\r\n    ElevationRequirement: elevationRequired\r\n    UnsupportedArguments:\r\n      - location\r\n    UnsupportedOSArchitectures:\r\n      - arm64\r\n    Markets:\r\n      ExcludedMarkets:\r\n        - \"US\"\r\n    ExpectedReturnCodes:\r\n      - InstallerReturnCode: 2\r\n        ReturnResponse: contactSupport\r\n      - InstallerReturnCode: 3\r\n        ReturnResponse: custom\r\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\r\n    DownloadCommandProhibited: false\r\n    ArchiveBinariesDependOnPath: false\r\nManifestType: singleton\r\nManifestVersion: 1.10.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ManifestV1_12-Singleton.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.12.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-US\nPublisher: Microsoft\nPublisherUrl: https://www.microsoft.com\nPublisherSupportUrl: https://www.microsoft.com/support\nPrivacyUrl: https://www.microsoft.com/privacy\nAuthor: Microsoft\nPackageName: MSIX SDK\nPackageUrl: https://www.microsoft.com/msixsdk/home\nLicense: MIT License\nLicenseUrl: https://www.microsoft.com/msixsdk/license\nCopyright: Copyright Microsoft Corporation\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright\nShortDescription: This is MSIX SDK\nDescription: The MSIX SDK project is an effort to enable developers\nMoniker: msixsdk\nTags:\n  - \"appxsdk\"\n  - \"msixsdk\"\nReleaseNotes: Default release notes\nReleaseNotesUrl: https://DefaultReleaseNotes.net\nPurchaseUrl: https://DefaultPurchaseUrl.com\nInstallationNotes: Default installation notes\nDocumentations:\n  - DocumentLabel: Default document label\n    DocumentUrl: https://DefaultDocumentUrl.com\nIcons:\n  - IconUrl: https://testIcon-en-US\n    IconFileType: ico\n    IconResolution: custom\n    IconTheme: default\n    IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\nAgreements:\n  - AgreementLabel: DefaultLabel\n    Agreement: DefaultText\n    AgreementUrl: https://DefaultAgreementUrl.net\nInstallerLocale: en-US\nPlatform:\n  - Windows.Desktop\n  - Windows.Universal\nMinimumOSVersion: 10.0.0.0\nInstallerType: exe\nScope: machine\nInstallModes:\n  - interactive\n  - silent\n  - silentWithProgress\nInstallerSwitches:\n  Custom: /custom\n  SilentWithProgress: /silentwithprogress\n  Silent: /silence\n  Interactive: /interactive\n  Log: /log=<LOGPATH>\n  InstallLocation: /dir=<INSTALLPATH>\n  Upgrade: /upgrade\n  Repair: /repair\nInstallerSuccessCodes:\n  - 1\n  - 0x80070005\nUpgradeBehavior: uninstallPrevious\nRepairBehavior: modify\nCommands:\n  - makemsix\n  - makeappx\nProtocols:\n  - protocol1\n  - protocol2\nFileExtensions:\n  - appx\n  - msix\n  - appxbundle\n  - msixbundle\nDependencies:\n  WindowsFeatures:\n    - IIS\n  WindowsLibraries:\n    - VC Runtime\n  PackageDependencies:\n    - PackageIdentifier: Microsoft.MsixSdkDep\n      MinimumVersion: 1.0.0\n  ExternalDependencies:\n    - Outside dependencies\nCapabilities:\n  - internetClient\nRestrictedCapabilities:\n  - runFullTrust\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\nProductCode: \"{Foo}\"\nReleaseDate: 2021-01-01\nInstallerAbortsTerminal: true\nInstallLocationRequired: true\nRequireExplicitUpgrade: true\nDisplayInstallWarnings: true\nElevationRequirement: elevatesSelf\nUnsupportedOSArchitectures:\n  - arm\nAppsAndFeaturesEntries:\n  - DisplayName: DisplayName\n    DisplayVersion: DisplayVersion\n    Publisher: Publisher\n    ProductCode: ProductCode\n    UpgradeCode: UpgradeCode\n    InstallerType: exe\nMarkets:\n  AllowedMarkets:\n    - US\nExpectedReturnCodes:\n  - InstallerReturnCode: 10\n    ReturnResponse: packageInUse\n    ReturnResponseUrl: https://DefaultReturnResponseUrl.com\nUnsupportedArguments:\n  - log\nNestedInstallerType: msi\nNestedInstallerFiles:\n  - RelativeFilePath: RelativeFilePath\n    PortableCommandAlias: PortableCommandAlias\nInstallationMetadata:\n  DefaultInstallLocation: \"%ProgramFiles%\\\\TestApp\"\n  Files:\n    - RelativeFilePath: \"main.exe\"\n      FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n      FileType: launch\n      InvocationParameter: \"/arg\"\n      DisplayName: \"DisplayName\"\nDownloadCommandProhibited: true\nArchiveBinariesDependOnPath: true\n\nInstallers:\n  - Architecture: x86\n    InstallerLocale: en-GB\n    Platform:\n      - Windows.Desktop\n    MinimumOSVersion: 10.0.1.0\n    InstallerType: msix\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    Scope: user\n    InstallModes:\n      - interactive\n    InstallerSwitches:\n      Custom: /c\n      SilentWithProgress: /sp\n      Silent: /s\n      Interactive: /i\n      Log: /l=<LOGPATH>\n      InstallLocation: /d=<INSTALLPATH>\n      Upgrade: /u\n      Repair: /r\n    UpgradeBehavior: install\n    Commands:\n      - makemsixPreview\n      - makeappxPreview\n    Protocols:\n      - protocol1preview\n      - protocol2preview\n    FileExtensions:\n      - appxbundle\n      - msixbundle\n      - appx\n      - msix\n    Dependencies:\n      WindowsFeatures:\n        - PreviewIIS\n      WindowsLibraries:\n        - Preview VC Runtime\n      PackageDependencies:\n        - PackageIdentifier: Microsoft.MsixSdkDepPreview\n          MinimumVersion: 1.0.0\n      ExternalDependencies:\n        - Preview Outside dependencies\n    PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe\n    Capabilities:\n      - internetClientPreview\n    RestrictedCapabilities:\n      - runFullTrustPreview\n    ReleaseDate: 2021-02-02\n    InstallerAbortsTerminal: false\n    InstallLocationRequired: false\n    RequireExplicitUpgrade: false\n    DisplayInstallWarnings: false\n    ElevationRequirement: elevationRequired\n    UnsupportedArguments:\n      - location\n    UnsupportedOSArchitectures:\n      - arm64\n    Markets:\n      ExcludedMarkets:\n        - \"US\"\n    ExpectedReturnCodes:\n      - InstallerReturnCode: 2\n        ReturnResponse: contactSupport\n      - InstallerReturnCode: 3\n        ReturnResponse: custom\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\n    DownloadCommandProhibited: false\n    ArchiveBinariesDependOnPath: false\nManifestType: singleton\nManifestVersion: 1.12.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ManifestV1_2-Singleton.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.2.0.schema.json\r\n\r\nPackageIdentifier: microsoft.msixsdk\r\nPackageVersion: 1.7.32\r\nPackageLocale: en-US\r\nPublisher: Microsoft\r\nPublisherUrl: https://www.microsoft.com\r\nPublisherSupportUrl: https://www.microsoft.com/support\r\nPrivacyUrl: https://www.microsoft.com/privacy\r\nAuthor: Microsoft\r\nPackageName: MSIX SDK\r\nPackageUrl: https://www.microsoft.com/msixsdk/home\r\nLicense: MIT License\r\nLicenseUrl: https://www.microsoft.com/msixsdk/license\r\nCopyright: Copyright Microsoft Corporation\r\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright\r\nShortDescription: This is MSIX SDK\r\nDescription: The MSIX SDK project is an effort to enable developers\r\nMoniker: msixsdk\r\nTags:\r\n  - \"appxsdk\"\r\n  - \"msixsdk\"\r\nReleaseNotes: Default release notes\r\nReleaseNotesUrl: https://DefaultReleaseNotes.net\r\nPurchaseUrl: https://DefaultPurchaseUrl.com\r\nInstallationNotes: Default installation notes\r\nDocumentations:\r\n  - DocumentLabel: Default document label\r\n    DocumentUrl: https://DefaultDocumentUrl.com\r\nAgreements:\r\n  - AgreementLabel: DefaultLabel\r\n    Agreement: DefaultText\r\n    AgreementUrl: https://DefaultAgreementUrl.net\r\nInstallerLocale: en-US\r\nPlatform:\r\n  - Windows.Desktop\r\n  - Windows.Universal\r\nMinimumOSVersion: 10.0.0.0\r\nInstallerType: exe\r\nScope: machine\r\nInstallModes:\r\n  - interactive\r\n  - silent\r\n  - silentWithProgress\r\nInstallerSwitches:\r\n  Custom: /custom\r\n  SilentWithProgress: /silentwithprogress\r\n  Silent: /silence\r\n  Interactive: /interactive\r\n  Log: /log=<LOGPATH>\r\n  InstallLocation: /dir=<INSTALLPATH>\r\n  Upgrade: /upgrade\r\nInstallerSuccessCodes:\r\n  - 1\r\n  - 0x80070005\r\nUpgradeBehavior: uninstallPrevious\r\nCommands:\r\n  - makemsix\r\n  - makeappx\r\nProtocols:\r\n  - protocol1\r\n  - protocol2\r\nFileExtensions:\r\n  - appx\r\n  - msix\r\n  - appxbundle\r\n  - msixbundle\r\nDependencies:\r\n  WindowsFeatures:\r\n    - IIS\r\n  WindowsLibraries:\r\n    - VC Runtime\r\n  PackageDependencies:\r\n    - PackageIdentifier: Microsoft.MsixSdkDep\r\n      MinimumVersion: 1.0.0\r\n  ExternalDependencies:\r\n    - Outside dependencies\r\nCapabilities:\r\n  - internetClient\r\nRestrictedCapabilities:\r\n  - runFullTrust\r\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\r\nProductCode: \"{Foo}\"\r\nReleaseDate: 2021-01-01\r\nInstallerAbortsTerminal: true\r\nInstallLocationRequired: true\r\nRequireExplicitUpgrade: true\r\nDisplayInstallWarnings: true\r\nElevationRequirement: elevatesSelf\r\nUnsupportedOSArchitectures:\r\n  - arm\r\nAppsAndFeaturesEntries:\r\n  - DisplayName: DisplayName\r\n    DisplayVersion: DisplayVersion\r\n    Publisher: Publisher\r\n    ProductCode: ProductCode\r\n    UpgradeCode: UpgradeCode\r\n    InstallerType: exe\r\nMarkets:\r\n  AllowedMarkets:\r\n    - US\r\nExpectedReturnCodes:\r\n  - InstallerReturnCode: 10\r\n    ReturnResponse: packageInUse\r\n    ReturnResponseUrl: https://DefaultReturnResponseUrl.com\r\nUnsupportedArguments:\r\n  - log\r\n\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerLocale: en-GB\r\n    Platform:\r\n      - Windows.Desktop\r\n    MinimumOSVersion: 10.0.1.0\r\n    InstallerType: msix\r\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix\r\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n    SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n    Scope: user\r\n    InstallModes:\r\n      - interactive\r\n    InstallerSwitches:\r\n      Custom: /c\r\n      SilentWithProgress: /sp\r\n      Silent: /s\r\n      Interactive: /i\r\n      Log: /l=<LOGPATH>\r\n      InstallLocation: /d=<INSTALLPATH>\r\n      Upgrade: /u\r\n    UpgradeBehavior: install\r\n    Commands:\r\n      - makemsixPreview\r\n      - makeappxPreview\r\n    Protocols:\r\n      - protocol1preview\r\n      - protocol2preview\r\n    FileExtensions:\r\n      - appxbundle\r\n      - msixbundle\r\n      - appx\r\n      - msix\r\n    Dependencies:\r\n      WindowsFeatures:\r\n        - PreviewIIS\r\n      WindowsLibraries:\r\n        - Preview VC Runtime\r\n      PackageDependencies:\r\n        - PackageIdentifier: Microsoft.MsixSdkDepPreview\r\n          MinimumVersion: 1.0.0\r\n      ExternalDependencies:\r\n        - Preview Outside dependencies\r\n    PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe\r\n    Capabilities:\r\n      - internetClientPreview\r\n    RestrictedCapabilities:\r\n      - runFullTrustPreview\r\n    ReleaseDate: 2021-02-02\r\n    InstallerAbortsTerminal: false\r\n    InstallLocationRequired: false\r\n    RequireExplicitUpgrade: false\r\n    DisplayInstallWarnings: false\r\n    ElevationRequirement: elevationRequired\r\n    UnsupportedArguments:\r\n      - location\r\n    UnsupportedOSArchitectures:\r\n      - arm64\r\n    Markets:\r\n      ExcludedMarkets:\r\n        - \"US\"\r\n    ExpectedReturnCodes:\r\n      - InstallerReturnCode: 2\r\n        ReturnResponse: contactSupport\r\n      - InstallerReturnCode: 3\r\n        ReturnResponse: custom\r\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\r\nManifestType: singleton\r\nManifestVersion: 1.2.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ManifestV1_28-PowerShellDSC.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.28.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-US\nPublisher: Microsoft\nPublisherUrl: https://www.microsoft.com\nPublisherSupportUrl: https://www.microsoft.com/support\nPrivacyUrl: https://www.microsoft.com/privacy\nAuthor: Microsoft\nPackageName: MSIX SDK\nPackageUrl: https://www.microsoft.com/msixsdk/home\nLicense: MIT License\nLicenseUrl: https://www.microsoft.com/msixsdk/license\nCopyright: Copyright Microsoft Corporation\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright\nShortDescription: This is MSIX SDK\nDescription: The MSIX SDK project is an effort to enable developers\nMoniker: msixsdk\nTags:\n  - \"appxsdk\"\n  - \"msixsdk\"\nReleaseNotes: Default release notes\nReleaseNotesUrl: https://DefaultReleaseNotes.net\nPurchaseUrl: https://DefaultPurchaseUrl.com\nInstallationNotes: Default installation notes\nDocumentations:\n  - DocumentLabel: Default document label\n    DocumentUrl: https://DefaultDocumentUrl.com\nIcons:\n  - IconUrl: https://testIcon-en-US\n    IconFileType: ico\n    IconResolution: custom\n    IconTheme: default\n    IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\nAgreements:\n  - AgreementLabel: DefaultLabel\n    Agreement: DefaultText\n    AgreementUrl: https://DefaultAgreementUrl.net\nInstallerLocale: en-US\nPlatform:\n  - Windows.Desktop\n  - Windows.Universal\nMinimumOSVersion: 10.0.0.0\nInstallerType: exe\nScope: machine\nInstallModes:\n  - interactive\n  - silent\n  - silentWithProgress\nInstallerSwitches:\n  Custom: /custom\n  SilentWithProgress: /silentwithprogress\n  Silent: /silence\n  Interactive: /interactive\n  Log: /log=<LOGPATH>\n  InstallLocation: /dir=<INSTALLPATH>\n  Upgrade: /upgrade\n  Repair: /repair\nInstallerSuccessCodes:\n  - 1\n  - 0x80070005\nUpgradeBehavior: uninstallPrevious\nRepairBehavior: modify\nCommands:\n  - makemsix\n  - makeappx\nProtocols:\n  - protocol1\n  - protocol2\nFileExtensions:\n  - appx\n  - msix\n  - appxbundle\n  - msixbundle\nDependencies:\n  WindowsFeatures:\n    - IIS\n  WindowsLibraries:\n    - VC Runtime\n  PackageDependencies:\n    - PackageIdentifier: Microsoft.MsixSdkDep\n      MinimumVersion: 1.0.0\n  ExternalDependencies:\n    - Outside dependencies\nCapabilities:\n  - internetClient\nRestrictedCapabilities:\n  - runFullTrust\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\nProductCode: \"{Foo}\"\nReleaseDate: 2021-01-01\nInstallerAbortsTerminal: true\nInstallLocationRequired: true\nRequireExplicitUpgrade: true\nDisplayInstallWarnings: true\nElevationRequirement: elevatesSelf\nUnsupportedOSArchitectures:\n  - arm\nAppsAndFeaturesEntries:\n  - DisplayName: DisplayName\n    DisplayVersion: DisplayVersion\n    Publisher: Publisher\n    ProductCode: ProductCode\n    UpgradeCode: UpgradeCode\n    InstallerType: exe\nMarkets:\n  AllowedMarkets:\n    - US\nExpectedReturnCodes:\n  - InstallerReturnCode: 10\n    ReturnResponse: packageInUse\n    ReturnResponseUrl: https://DefaultReturnResponseUrl.com\nUnsupportedArguments:\n  - log\nNestedInstallerType: msi\nNestedInstallerFiles:\n  - RelativeFilePath: RelativeFilePath\n    PortableCommandAlias: PortableCommandAlias\nInstallationMetadata:\n  DefaultInstallLocation: \"%ProgramFiles%\\\\TestApp\"\n  Files:\n    - RelativeFilePath: \"main.exe\"\n      FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n      FileType: launch\n      InvocationParameter: \"/arg\"\n      DisplayName: \"DisplayName\"\nDownloadCommandProhibited: true\nArchiveBinariesDependOnPath: true\r\nDesiredStateConfiguration:\r\n  PowerShell:\r\n    - RepositoryUrl: https://www.powershellgallery.com/api/v2\r\n      ModuleName: Microsoft.WinGet.DSC\r\n      Resources:\r\n        - Name: WinGetUserSettings\r\n        - Name: WinGetAdminSettings\r\n        - Name: WinGetSource\r\n        - Name: WinGetPackageManager\r\n        - Name: WinGetPackage\r\n    - RepositoryUrl: https://mcr.microsoft.com/\r\n      ModuleName: Microsoft.WinGet.DSC\r\n      Resources:\r\n        - Name: WinGetUserSettings\r\n        - Name: WinGetAdminSettings\r\n        - Name: WinGetSource\r\n        - Name: WinGetPackageManager\r\n        - Name: WinGetPackage\r\n  DSCv3:\r\n    Resources:\r\n      - Type: Microsoft.WinGet/AdminSettings\n      - Type: Microsoft.WinGet/Package\n      - Type: Microsoft.WinGet/Source\n      - Type: Microsoft.WinGet/UserSettingsFile\n\nInstallers:\n  - Architecture: x86\n    InstallerLocale: en-GB\n    Platform:\n      - Windows.Desktop\n    MinimumOSVersion: 10.0.1.0\n    InstallerType: msix\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    Scope: user\n    InstallModes:\n      - interactive\n    InstallerSwitches:\n      Custom: /c\n      SilentWithProgress: /sp\n      Silent: /s\n      Interactive: /i\n      Log: /l=<LOGPATH>\n      InstallLocation: /d=<INSTALLPATH>\n      Upgrade: /u\n      Repair: /r\n    UpgradeBehavior: install\n    Commands:\n      - makemsixPreview\n      - makeappxPreview\n    Protocols:\n      - protocol1preview\n      - protocol2preview\n    FileExtensions:\n      - appxbundle\n      - msixbundle\n      - appx\n      - msix\n    Dependencies:\n      WindowsFeatures:\n        - PreviewIIS\n      WindowsLibraries:\n        - Preview VC Runtime\n      PackageDependencies:\n        - PackageIdentifier: Microsoft.MsixSdkDepPreview\n          MinimumVersion: 1.0.0\n      ExternalDependencies:\n        - Preview Outside dependencies\n    PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe\n    Capabilities:\n      - internetClientPreview\n    RestrictedCapabilities:\n      - runFullTrustPreview\n    ReleaseDate: 2021-02-02\n    InstallerAbortsTerminal: false\n    InstallLocationRequired: false\n    RequireExplicitUpgrade: false\n    DisplayInstallWarnings: false\n    ElevationRequirement: elevationRequired\n    UnsupportedArguments:\n      - location\n    UnsupportedOSArchitectures:\n      - arm64\n    Markets:\n      ExcludedMarkets:\n        - \"US\"\n    ExpectedReturnCodes:\n      - InstallerReturnCode: 2\n        ReturnResponse: contactSupport\n      - InstallerReturnCode: 3\n        ReturnResponse: custom\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\n    DownloadCommandProhibited: false\n    ArchiveBinariesDependOnPath: false\nManifestType: singleton\nManifestVersion: 1.28.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ManifestV1_28-Singleton.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.28.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-US\nPublisher: Microsoft\nPublisherUrl: https://www.microsoft.com\nPublisherSupportUrl: https://www.microsoft.com/support\nPrivacyUrl: https://www.microsoft.com/privacy\nAuthor: Microsoft\nPackageName: MSIX SDK\nPackageUrl: https://www.microsoft.com/msixsdk/home\nLicense: MIT License\nLicenseUrl: https://www.microsoft.com/msixsdk/license\nCopyright: Copyright Microsoft Corporation\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright\nShortDescription: This is MSIX SDK\nDescription: The MSIX SDK project is an effort to enable developers\nMoniker: msixsdk\nTags:\n  - \"appxsdk\"\n  - \"msixsdk\"\nReleaseNotes: Default release notes\nReleaseNotesUrl: https://DefaultReleaseNotes.net\nPurchaseUrl: https://DefaultPurchaseUrl.com\nInstallationNotes: Default installation notes\nDocumentations:\n  - DocumentLabel: Default document label\n    DocumentUrl: https://DefaultDocumentUrl.com\nIcons:\n  - IconUrl: https://testIcon-en-US\n    IconFileType: ico\n    IconResolution: custom\n    IconTheme: default\n    IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\nAgreements:\n  - AgreementLabel: DefaultLabel\n    Agreement: DefaultText\n    AgreementUrl: https://DefaultAgreementUrl.net\nInstallerLocale: en-US\nPlatform:\n  - Windows.Desktop\n  - Windows.Universal\nMinimumOSVersion: 10.0.0.0\nInstallerType: exe\nScope: machine\nInstallModes:\n  - interactive\n  - silent\n  - silentWithProgress\nInstallerSwitches:\n  Custom: /custom\n  SilentWithProgress: /silentwithprogress\n  Silent: /silence\n  Interactive: /interactive\n  Log: /log=<LOGPATH>\n  InstallLocation: /dir=<INSTALLPATH>\n  Upgrade: /upgrade\n  Repair: /repair\nInstallerSuccessCodes:\n  - 1\n  - 0x80070005\nUpgradeBehavior: uninstallPrevious\nRepairBehavior: modify\nCommands:\n  - makemsix\n  - makeappx\nProtocols:\n  - protocol1\n  - protocol2\nFileExtensions:\n  - appx\n  - msix\n  - appxbundle\n  - msixbundle\nDependencies:\n  WindowsFeatures:\n    - IIS\n  WindowsLibraries:\n    - VC Runtime\n  PackageDependencies:\n    - PackageIdentifier: Microsoft.MsixSdkDep\n      MinimumVersion: 1.0.0\n  ExternalDependencies:\n    - Outside dependencies\nCapabilities:\n  - internetClient\nRestrictedCapabilities:\n  - runFullTrust\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\nProductCode: \"{Foo}\"\nReleaseDate: 2021-01-01\nInstallerAbortsTerminal: true\nInstallLocationRequired: true\nRequireExplicitUpgrade: true\nDisplayInstallWarnings: true\nElevationRequirement: elevatesSelf\nUnsupportedOSArchitectures:\n  - arm\nAppsAndFeaturesEntries:\n  - DisplayName: DisplayName\n    DisplayVersion: DisplayVersion\n    Publisher: Publisher\n    ProductCode: ProductCode\n    UpgradeCode: UpgradeCode\n    InstallerType: exe\nMarkets:\n  AllowedMarkets:\n    - US\nExpectedReturnCodes:\n  - InstallerReturnCode: 10\n    ReturnResponse: packageInUse\n    ReturnResponseUrl: https://DefaultReturnResponseUrl.com\nUnsupportedArguments:\n  - log\nNestedInstallerType: msi\nNestedInstallerFiles:\n  - RelativeFilePath: RelativeFilePath\n    PortableCommandAlias: PortableCommandAlias\nInstallationMetadata:\n  DefaultInstallLocation: \"%ProgramFiles%\\\\TestApp\"\n  Files:\n    - RelativeFilePath: \"main.exe\"\n      FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n      FileType: launch\n      InvocationParameter: \"/arg\"\n      DisplayName: \"DisplayName\"\nDownloadCommandProhibited: true\nArchiveBinariesDependOnPath: true\r\nDesiredStateConfiguration:\r\n  DSCv3:\r\n    Resources:\r\n      - Type: Microsoft.WinGet/AdminSettings\n      - Type: Microsoft.WinGet/Package\n      - Type: Microsoft.WinGet/Source\n      - Type: Microsoft.WinGet/UserSettingsFile\n\nInstallers:\n  - Architecture: x86\n    InstallerLocale: en-GB\n    Platform:\n      - Windows.Desktop\n    MinimumOSVersion: 10.0.1.0\n    InstallerType: msix\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    Scope: user\n    InstallModes:\n      - interactive\n    InstallerSwitches:\n      Custom: /c\n      SilentWithProgress: /sp\n      Silent: /s\n      Interactive: /i\n      Log: /l=<LOGPATH>\n      InstallLocation: /d=<INSTALLPATH>\n      Upgrade: /u\n      Repair: /r\n    UpgradeBehavior: install\n    Commands:\n      - makemsixPreview\n      - makeappxPreview\n    Protocols:\n      - protocol1preview\n      - protocol2preview\n    FileExtensions:\n      - appxbundle\n      - msixbundle\n      - appx\n      - msix\n    Dependencies:\n      WindowsFeatures:\n        - PreviewIIS\n      WindowsLibraries:\n        - Preview VC Runtime\n      PackageDependencies:\n        - PackageIdentifier: Microsoft.MsixSdkDepPreview\n          MinimumVersion: 1.0.0\n      ExternalDependencies:\n        - Preview Outside dependencies\n    PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe\n    Capabilities:\n      - internetClientPreview\n    RestrictedCapabilities:\n      - runFullTrustPreview\n    ReleaseDate: 2021-02-02\n    InstallerAbortsTerminal: false\n    InstallLocationRequired: false\n    RequireExplicitUpgrade: false\n    DisplayInstallWarnings: false\n    ElevationRequirement: elevationRequired\n    UnsupportedArguments:\n      - location\n    UnsupportedOSArchitectures:\n      - arm64\n    Markets:\n      ExcludedMarkets:\n        - \"US\"\n    ExpectedReturnCodes:\n      - InstallerReturnCode: 2\n        ReturnResponse: contactSupport\n      - InstallerReturnCode: 3\n        ReturnResponse: custom\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\n    DownloadCommandProhibited: false\n    ArchiveBinariesDependOnPath: false\nManifestType: singleton\nManifestVersion: 1.28.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ManifestV1_4-Singleton.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: microsoft.msixsdk\r\nPackageVersion: 1.7.32\r\nPackageLocale: en-US\r\nPublisher: Microsoft\r\nPublisherUrl: https://www.microsoft.com\r\nPublisherSupportUrl: https://www.microsoft.com/support\r\nPrivacyUrl: https://www.microsoft.com/privacy\r\nAuthor: Microsoft\r\nPackageName: MSIX SDK\r\nPackageUrl: https://www.microsoft.com/msixsdk/home\r\nLicense: MIT License\r\nLicenseUrl: https://www.microsoft.com/msixsdk/license\r\nCopyright: Copyright Microsoft Corporation\r\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright\r\nShortDescription: This is MSIX SDK\r\nDescription: The MSIX SDK project is an effort to enable developers\r\nMoniker: msixsdk\r\nTags:\r\n  - \"appxsdk\"\r\n  - \"msixsdk\"\r\nReleaseNotes: Default release notes\r\nReleaseNotesUrl: https://DefaultReleaseNotes.net\r\nPurchaseUrl: https://DefaultPurchaseUrl.com\r\nInstallationNotes: Default installation notes\r\nDocumentations:\r\n  - DocumentLabel: Default document label\r\n    DocumentUrl: https://DefaultDocumentUrl.com\r\nAgreements:\r\n  - AgreementLabel: DefaultLabel\r\n    Agreement: DefaultText\r\n    AgreementUrl: https://DefaultAgreementUrl.net\r\nInstallerLocale: en-US\r\nPlatform:\r\n  - Windows.Desktop\r\n  - Windows.Universal\r\nMinimumOSVersion: 10.0.0.0\r\nInstallerType: exe\r\nScope: machine\r\nInstallModes:\r\n  - interactive\r\n  - silent\r\n  - silentWithProgress\r\nInstallerSwitches:\r\n  Custom: /custom\r\n  SilentWithProgress: /silentwithprogress\r\n  Silent: /silence\r\n  Interactive: /interactive\r\n  Log: /log=<LOGPATH>\r\n  InstallLocation: /dir=<INSTALLPATH>\r\n  Upgrade: /upgrade\r\nInstallerSuccessCodes:\r\n  - 1\r\n  - 0x80070005\r\nUpgradeBehavior: uninstallPrevious\r\nCommands:\r\n  - makemsix\r\n  - makeappx\r\nProtocols:\r\n  - protocol1\r\n  - protocol2\r\nFileExtensions:\r\n  - appx\r\n  - msix\r\n  - appxbundle\r\n  - msixbundle\r\nDependencies:\r\n  WindowsFeatures:\r\n    - IIS\r\n  WindowsLibraries:\r\n    - VC Runtime\r\n  PackageDependencies:\r\n    - PackageIdentifier: Microsoft.MsixSdkDep\r\n      MinimumVersion: 1.0.0\r\n  ExternalDependencies:\r\n    - Outside dependencies\r\nCapabilities:\r\n  - internetClient\r\nRestrictedCapabilities:\r\n  - runFullTrust\r\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\r\nProductCode: \"{Foo}\"\r\nReleaseDate: 2021-01-01\r\nInstallerAbortsTerminal: true\r\nInstallLocationRequired: true\r\nRequireExplicitUpgrade: true\r\nDisplayInstallWarnings: true\r\nElevationRequirement: elevatesSelf\r\nUnsupportedOSArchitectures:\r\n  - arm\r\nAppsAndFeaturesEntries:\r\n  - DisplayName: DisplayName\r\n    DisplayVersion: DisplayVersion\r\n    Publisher: Publisher\r\n    ProductCode: ProductCode\r\n    UpgradeCode: UpgradeCode\r\n    InstallerType: exe\r\nMarkets:\r\n  AllowedMarkets:\r\n    - US\r\nExpectedReturnCodes:\r\n  - InstallerReturnCode: 10\r\n    ReturnResponse: packageInUse\r\n    ReturnResponseUrl: https://DefaultReturnResponseUrl.com\r\nUnsupportedArguments:\r\n  - log\r\nNestedInstallerType: msi\r\nNestedInstallerFiles:\r\n  - RelativeFilePath: RelativeFilePath\r\n    PortableCommandAlias: PortableCommandAlias\r\nInstallationMetadata:\r\n  DefaultInstallLocation: \"%ProgramFiles%\\\\TestApp\"\r\n  Files:\r\n    - RelativeFilePath: \"main.exe\"\r\n      FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n      FileType: launch\r\n      InvocationParameter: \"/arg\"\r\n      DisplayName: \"DisplayName\"\r\n\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerLocale: en-GB\r\n    Platform:\r\n      - Windows.Desktop\r\n    MinimumOSVersion: 10.0.1.0\r\n    InstallerType: msix\r\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix\r\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n    SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n    Scope: user\r\n    InstallModes:\r\n      - interactive\r\n    InstallerSwitches:\r\n      Custom: /c\r\n      SilentWithProgress: /sp\r\n      Silent: /s\r\n      Interactive: /i\r\n      Log: /l=<LOGPATH>\r\n      InstallLocation: /d=<INSTALLPATH>\r\n      Upgrade: /u\r\n    UpgradeBehavior: install\r\n    Commands:\r\n      - makemsixPreview\r\n      - makeappxPreview\r\n    Protocols:\r\n      - protocol1preview\r\n      - protocol2preview\r\n    FileExtensions:\r\n      - appxbundle\r\n      - msixbundle\r\n      - appx\r\n      - msix\r\n    Dependencies:\r\n      WindowsFeatures:\r\n        - PreviewIIS\r\n      WindowsLibraries:\r\n        - Preview VC Runtime\r\n      PackageDependencies:\r\n        - PackageIdentifier: Microsoft.MsixSdkDepPreview\r\n          MinimumVersion: 1.0.0\r\n      ExternalDependencies:\r\n        - Preview Outside dependencies\r\n    PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe\r\n    Capabilities:\r\n      - internetClientPreview\r\n    RestrictedCapabilities:\r\n      - runFullTrustPreview\r\n    ReleaseDate: 2021-02-02\r\n    InstallerAbortsTerminal: false\r\n    InstallLocationRequired: false\r\n    RequireExplicitUpgrade: false\r\n    DisplayInstallWarnings: false\r\n    ElevationRequirement: elevationRequired\r\n    UnsupportedArguments:\r\n      - location\r\n    UnsupportedOSArchitectures:\r\n      - arm64\r\n    Markets:\r\n      ExcludedMarkets:\r\n        - \"US\"\r\n    ExpectedReturnCodes:\r\n      - InstallerReturnCode: 2\r\n        ReturnResponse: contactSupport\r\n      - InstallerReturnCode: 3\r\n        ReturnResponse: custom\r\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ManifestV1_5-Singleton.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.5.0.schema.json\r\n\r\nPackageIdentifier: microsoft.msixsdk\r\nPackageVersion: 1.7.32\r\nPackageLocale: en-US\r\nPublisher: Microsoft\r\nPublisherUrl: https://www.microsoft.com\r\nPublisherSupportUrl: https://www.microsoft.com/support\r\nPrivacyUrl: https://www.microsoft.com/privacy\r\nAuthor: Microsoft\r\nPackageName: MSIX SDK\r\nPackageUrl: https://www.microsoft.com/msixsdk/home\r\nLicense: MIT License\r\nLicenseUrl: https://www.microsoft.com/msixsdk/license\r\nCopyright: Copyright Microsoft Corporation\r\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright\r\nShortDescription: This is MSIX SDK\r\nDescription: The MSIX SDK project is an effort to enable developers\r\nMoniker: msixsdk\r\nTags:\r\n  - \"appxsdk\"\r\n  - \"msixsdk\"\r\nReleaseNotes: Default release notes\r\nReleaseNotesUrl: https://DefaultReleaseNotes.net\r\nPurchaseUrl: https://DefaultPurchaseUrl.com\r\nInstallationNotes: Default installation notes\r\nDocumentations:\r\n  - DocumentLabel: Default document label\r\n    DocumentUrl: https://DefaultDocumentUrl.com\r\nIcons:\r\n  - IconUrl: https://testIcon-en-US\r\n    IconFileType: ico\r\n    IconResolution: custom\r\n    IconTheme: default\r\n    IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\r\nAgreements:\r\n  - AgreementLabel: DefaultLabel\r\n    Agreement: DefaultText\r\n    AgreementUrl: https://DefaultAgreementUrl.net\r\nInstallerLocale: en-US\r\nPlatform:\r\n  - Windows.Desktop\r\n  - Windows.Universal\r\nMinimumOSVersion: 10.0.0.0\r\nInstallerType: exe\r\nScope: machine\r\nInstallModes:\r\n  - interactive\r\n  - silent\r\n  - silentWithProgress\r\nInstallerSwitches:\r\n  Custom: /custom\r\n  SilentWithProgress: /silentwithprogress\r\n  Silent: /silence\r\n  Interactive: /interactive\r\n  Log: /log=<LOGPATH>\r\n  InstallLocation: /dir=<INSTALLPATH>\r\n  Upgrade: /upgrade\r\nInstallerSuccessCodes:\r\n  - 1\r\n  - 0x80070005\r\nUpgradeBehavior: uninstallPrevious\r\nCommands:\r\n  - makemsix\r\n  - makeappx\r\nProtocols:\r\n  - protocol1\r\n  - protocol2\r\nFileExtensions:\r\n  - appx\r\n  - msix\r\n  - appxbundle\r\n  - msixbundle\r\nDependencies:\r\n  WindowsFeatures:\r\n    - IIS\r\n  WindowsLibraries:\r\n    - VC Runtime\r\n  PackageDependencies:\r\n    - PackageIdentifier: Microsoft.MsixSdkDep\r\n      MinimumVersion: 1.0.0\r\n  ExternalDependencies:\r\n    - Outside dependencies\r\nCapabilities:\r\n  - internetClient\r\nRestrictedCapabilities:\r\n  - runFullTrust\r\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\r\nProductCode: \"{Foo}\"\r\nReleaseDate: 2021-01-01\r\nInstallerAbortsTerminal: true\r\nInstallLocationRequired: true\r\nRequireExplicitUpgrade: true\r\nDisplayInstallWarnings: true\r\nElevationRequirement: elevatesSelf\r\nUnsupportedOSArchitectures:\r\n  - arm\r\nAppsAndFeaturesEntries:\r\n  - DisplayName: DisplayName\r\n    DisplayVersion: DisplayVersion\r\n    Publisher: Publisher\r\n    ProductCode: ProductCode\r\n    UpgradeCode: UpgradeCode\r\n    InstallerType: exe\r\nMarkets:\r\n  AllowedMarkets:\r\n    - US\r\nExpectedReturnCodes:\r\n  - InstallerReturnCode: 10\r\n    ReturnResponse: packageInUse\r\n    ReturnResponseUrl: https://DefaultReturnResponseUrl.com\r\nUnsupportedArguments:\r\n  - log\r\nNestedInstallerType: msi\r\nNestedInstallerFiles:\r\n  - RelativeFilePath: RelativeFilePath\r\n    PortableCommandAlias: PortableCommandAlias\r\nInstallationMetadata:\r\n  DefaultInstallLocation: \"%ProgramFiles%\\\\TestApp\"\r\n  Files:\r\n    - RelativeFilePath: \"main.exe\"\r\n      FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n      FileType: launch\r\n      InvocationParameter: \"/arg\"\r\n      DisplayName: \"DisplayName\"\r\n\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerLocale: en-GB\r\n    Platform:\r\n      - Windows.Desktop\r\n    MinimumOSVersion: 10.0.1.0\r\n    InstallerType: msix\r\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix\r\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n    SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n    Scope: user\r\n    InstallModes:\r\n      - interactive\r\n    InstallerSwitches:\r\n      Custom: /c\r\n      SilentWithProgress: /sp\r\n      Silent: /s\r\n      Interactive: /i\r\n      Log: /l=<LOGPATH>\r\n      InstallLocation: /d=<INSTALLPATH>\r\n      Upgrade: /u\r\n    UpgradeBehavior: install\r\n    Commands:\r\n      - makemsixPreview\r\n      - makeappxPreview\r\n    Protocols:\r\n      - protocol1preview\r\n      - protocol2preview\r\n    FileExtensions:\r\n      - appxbundle\r\n      - msixbundle\r\n      - appx\r\n      - msix\r\n    Dependencies:\r\n      WindowsFeatures:\r\n        - PreviewIIS\r\n      WindowsLibraries:\r\n        - Preview VC Runtime\r\n      PackageDependencies:\r\n        - PackageIdentifier: Microsoft.MsixSdkDepPreview\r\n          MinimumVersion: 1.0.0\r\n      ExternalDependencies:\r\n        - Preview Outside dependencies\r\n    PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe\r\n    Capabilities:\r\n      - internetClientPreview\r\n    RestrictedCapabilities:\r\n      - runFullTrustPreview\r\n    ReleaseDate: 2021-02-02\r\n    InstallerAbortsTerminal: false\r\n    InstallLocationRequired: false\r\n    RequireExplicitUpgrade: false\r\n    DisplayInstallWarnings: false\r\n    ElevationRequirement: elevationRequired\r\n    UnsupportedArguments:\r\n      - location\r\n    UnsupportedOSArchitectures:\r\n      - arm64\r\n    Markets:\r\n      ExcludedMarkets:\r\n        - \"US\"\r\n    ExpectedReturnCodes:\r\n      - InstallerReturnCode: 2\r\n        ReturnResponse: contactSupport\r\n      - InstallerReturnCode: 3\r\n        ReturnResponse: custom\r\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\r\nManifestType: singleton\r\nManifestVersion: 1.5.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ManifestV1_6-Singleton.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.6.0.schema.json\r\n\r\nPackageIdentifier: microsoft.msixsdk\r\nPackageVersion: 1.7.32\r\nPackageLocale: en-US\r\nPublisher: Microsoft\r\nPublisherUrl: https://www.microsoft.com\r\nPublisherSupportUrl: https://www.microsoft.com/support\r\nPrivacyUrl: https://www.microsoft.com/privacy\r\nAuthor: Microsoft\r\nPackageName: MSIX SDK\r\nPackageUrl: https://www.microsoft.com/msixsdk/home\r\nLicense: MIT License\r\nLicenseUrl: https://www.microsoft.com/msixsdk/license\r\nCopyright: Copyright Microsoft Corporation\r\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright\r\nShortDescription: This is MSIX SDK\r\nDescription: The MSIX SDK project is an effort to enable developers\r\nMoniker: msixsdk\r\nTags:\r\n  - \"appxsdk\"\r\n  - \"msixsdk\"\r\nReleaseNotes: Default release notes\r\nReleaseNotesUrl: https://DefaultReleaseNotes.net\r\nPurchaseUrl: https://DefaultPurchaseUrl.com\r\nInstallationNotes: Default installation notes\r\nDocumentations:\r\n  - DocumentLabel: Default document label\r\n    DocumentUrl: https://DefaultDocumentUrl.com\r\nIcons:\r\n  - IconUrl: https://testIcon-en-US\r\n    IconFileType: ico\r\n    IconResolution: custom\r\n    IconTheme: default\r\n    IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\r\nAgreements:\r\n  - AgreementLabel: DefaultLabel\r\n    Agreement: DefaultText\r\n    AgreementUrl: https://DefaultAgreementUrl.net\r\nInstallerLocale: en-US\r\nPlatform:\r\n  - Windows.Desktop\r\n  - Windows.Universal\r\nMinimumOSVersion: 10.0.0.0\r\nInstallerType: exe\r\nScope: machine\r\nInstallModes:\r\n  - interactive\r\n  - silent\r\n  - silentWithProgress\r\nInstallerSwitches:\r\n  Custom: /custom\r\n  SilentWithProgress: /silentwithprogress\r\n  Silent: /silence\r\n  Interactive: /interactive\r\n  Log: /log=<LOGPATH>\r\n  InstallLocation: /dir=<INSTALLPATH>\r\n  Upgrade: /upgrade\r\nInstallerSuccessCodes:\r\n  - 1\r\n  - 0x80070005\r\nUpgradeBehavior: uninstallPrevious\r\nCommands:\r\n  - makemsix\r\n  - makeappx\r\nProtocols:\r\n  - protocol1\r\n  - protocol2\r\nFileExtensions:\r\n  - appx\r\n  - msix\r\n  - appxbundle\r\n  - msixbundle\r\nDependencies:\r\n  WindowsFeatures:\r\n    - IIS\r\n  WindowsLibraries:\r\n    - VC Runtime\r\n  PackageDependencies:\r\n    - PackageIdentifier: Microsoft.MsixSdkDep\r\n      MinimumVersion: 1.0.0\r\n  ExternalDependencies:\r\n    - Outside dependencies\r\nCapabilities:\r\n  - internetClient\r\nRestrictedCapabilities:\r\n  - runFullTrust\r\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\r\nProductCode: \"{Foo}\"\r\nReleaseDate: 2021-01-01\r\nInstallerAbortsTerminal: true\r\nInstallLocationRequired: true\r\nRequireExplicitUpgrade: true\r\nDisplayInstallWarnings: true\r\nElevationRequirement: elevatesSelf\r\nUnsupportedOSArchitectures:\r\n  - arm\r\nAppsAndFeaturesEntries:\r\n  - DisplayName: DisplayName\r\n    DisplayVersion: DisplayVersion\r\n    Publisher: Publisher\r\n    ProductCode: ProductCode\r\n    UpgradeCode: UpgradeCode\r\n    InstallerType: exe\r\nMarkets:\r\n  AllowedMarkets:\r\n    - US\r\nExpectedReturnCodes:\r\n  - InstallerReturnCode: 10\r\n    ReturnResponse: packageInUse\r\n    ReturnResponseUrl: https://DefaultReturnResponseUrl.com\r\nUnsupportedArguments:\r\n  - log\r\nNestedInstallerType: msi\r\nNestedInstallerFiles:\r\n  - RelativeFilePath: RelativeFilePath\r\n    PortableCommandAlias: PortableCommandAlias\r\nInstallationMetadata:\r\n  DefaultInstallLocation: \"%ProgramFiles%\\\\TestApp\"\r\n  Files:\r\n    - RelativeFilePath: \"main.exe\"\r\n      FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n      FileType: launch\r\n      InvocationParameter: \"/arg\"\r\n      DisplayName: \"DisplayName\"\r\nDownloadCommandProhibited: true\r\n\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerLocale: en-GB\r\n    Platform:\r\n      - Windows.Desktop\r\n    MinimumOSVersion: 10.0.1.0\r\n    InstallerType: msix\r\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix\r\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n    SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n    Scope: user\r\n    InstallModes:\r\n      - interactive\r\n    InstallerSwitches:\r\n      Custom: /c\r\n      SilentWithProgress: /sp\r\n      Silent: /s\r\n      Interactive: /i\r\n      Log: /l=<LOGPATH>\r\n      InstallLocation: /d=<INSTALLPATH>\r\n      Upgrade: /u\r\n    UpgradeBehavior: install\r\n    Commands:\r\n      - makemsixPreview\r\n      - makeappxPreview\r\n    Protocols:\r\n      - protocol1preview\r\n      - protocol2preview\r\n    FileExtensions:\r\n      - appxbundle\r\n      - msixbundle\r\n      - appx\r\n      - msix\r\n    Dependencies:\r\n      WindowsFeatures:\r\n        - PreviewIIS\r\n      WindowsLibraries:\r\n        - Preview VC Runtime\r\n      PackageDependencies:\r\n        - PackageIdentifier: Microsoft.MsixSdkDepPreview\r\n          MinimumVersion: 1.0.0\r\n      ExternalDependencies:\r\n        - Preview Outside dependencies\r\n    PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe\r\n    Capabilities:\r\n      - internetClientPreview\r\n    RestrictedCapabilities:\r\n      - runFullTrustPreview\r\n    ReleaseDate: 2021-02-02\r\n    InstallerAbortsTerminal: false\r\n    InstallLocationRequired: false\r\n    RequireExplicitUpgrade: false\r\n    DisplayInstallWarnings: false\r\n    ElevationRequirement: elevationRequired\r\n    UnsupportedArguments:\r\n      - location\r\n    UnsupportedOSArchitectures:\r\n      - arm64\r\n    Markets:\r\n      ExcludedMarkets:\r\n        - \"US\"\r\n    ExpectedReturnCodes:\r\n      - InstallerReturnCode: 2\r\n        ReturnResponse: contactSupport\r\n      - InstallerReturnCode: 3\r\n        ReturnResponse: custom\r\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\r\n    DownloadCommandProhibited: false\r\nManifestType: singleton\r\nManifestVersion: 1.6.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ManifestV1_7-Singleton.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.7.0.schema.json\r\n\r\nPackageIdentifier: microsoft.msixsdk\r\nPackageVersion: 1.7.32\r\nPackageLocale: en-US\r\nPublisher: Microsoft\r\nPublisherUrl: https://www.microsoft.com\r\nPublisherSupportUrl: https://www.microsoft.com/support\r\nPrivacyUrl: https://www.microsoft.com/privacy\r\nAuthor: Microsoft\r\nPackageName: MSIX SDK\r\nPackageUrl: https://www.microsoft.com/msixsdk/home\r\nLicense: MIT License\r\nLicenseUrl: https://www.microsoft.com/msixsdk/license\r\nCopyright: Copyright Microsoft Corporation\r\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright\r\nShortDescription: This is MSIX SDK\r\nDescription: The MSIX SDK project is an effort to enable developers\r\nMoniker: msixsdk\r\nTags:\r\n  - \"appxsdk\"\r\n  - \"msixsdk\"\r\nReleaseNotes: Default release notes\r\nReleaseNotesUrl: https://DefaultReleaseNotes.net\r\nPurchaseUrl: https://DefaultPurchaseUrl.com\r\nInstallationNotes: Default installation notes\r\nDocumentations:\r\n  - DocumentLabel: Default document label\r\n    DocumentUrl: https://DefaultDocumentUrl.com\r\nIcons:\r\n  - IconUrl: https://testIcon-en-US\r\n    IconFileType: ico\r\n    IconResolution: custom\r\n    IconTheme: default\r\n    IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\r\nAgreements:\r\n  - AgreementLabel: DefaultLabel\r\n    Agreement: DefaultText\r\n    AgreementUrl: https://DefaultAgreementUrl.net\r\nInstallerLocale: en-US\r\nPlatform:\r\n  - Windows.Desktop\r\n  - Windows.Universal\r\nMinimumOSVersion: 10.0.0.0\r\nInstallerType: exe\r\nScope: machine\r\nInstallModes:\r\n  - interactive\r\n  - silent\r\n  - silentWithProgress\r\nInstallerSwitches:\r\n  Custom: /custom\r\n  SilentWithProgress: /silentwithprogress\r\n  Silent: /silence\r\n  Interactive: /interactive\r\n  Log: /log=<LOGPATH>\r\n  InstallLocation: /dir=<INSTALLPATH>\r\n  Upgrade: /upgrade\r\n  Repair: /repair\r\nInstallerSuccessCodes:\r\n  - 1\r\n  - 0x80070005\r\nUpgradeBehavior: uninstallPrevious\r\nRepairBehavior: modify\r\nCommands:\r\n  - makemsix\r\n  - makeappx\r\nProtocols:\r\n  - protocol1\r\n  - protocol2\r\nFileExtensions:\r\n  - appx\r\n  - msix\r\n  - appxbundle\r\n  - msixbundle\r\nDependencies:\r\n  WindowsFeatures:\r\n    - IIS\r\n  WindowsLibraries:\r\n    - VC Runtime\r\n  PackageDependencies:\r\n    - PackageIdentifier: Microsoft.MsixSdkDep\r\n      MinimumVersion: 1.0.0\r\n  ExternalDependencies:\r\n    - Outside dependencies\r\nCapabilities:\r\n  - internetClient\r\nRestrictedCapabilities:\r\n  - runFullTrust\r\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\r\nProductCode: \"{Foo}\"\r\nReleaseDate: 2021-01-01\r\nInstallerAbortsTerminal: true\r\nInstallLocationRequired: true\r\nRequireExplicitUpgrade: true\r\nDisplayInstallWarnings: true\r\nElevationRequirement: elevatesSelf\r\nUnsupportedOSArchitectures:\r\n  - arm\r\nAppsAndFeaturesEntries:\r\n  - DisplayName: DisplayName\r\n    DisplayVersion: DisplayVersion\r\n    Publisher: Publisher\r\n    ProductCode: ProductCode\r\n    UpgradeCode: UpgradeCode\r\n    InstallerType: exe\r\nMarkets:\r\n  AllowedMarkets:\r\n    - US\r\nExpectedReturnCodes:\r\n  - InstallerReturnCode: 10\r\n    ReturnResponse: packageInUse\r\n    ReturnResponseUrl: https://DefaultReturnResponseUrl.com\r\nUnsupportedArguments:\r\n  - log\r\nNestedInstallerType: msi\r\nNestedInstallerFiles:\r\n  - RelativeFilePath: RelativeFilePath\r\n    PortableCommandAlias: PortableCommandAlias\r\nInstallationMetadata:\r\n  DefaultInstallLocation: \"%ProgramFiles%\\\\TestApp\"\r\n  Files:\r\n    - RelativeFilePath: \"main.exe\"\r\n      FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n      FileType: launch\r\n      InvocationParameter: \"/arg\"\r\n      DisplayName: \"DisplayName\"\r\nDownloadCommandProhibited: true\r\n\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerLocale: en-GB\r\n    Platform:\r\n      - Windows.Desktop\r\n    MinimumOSVersion: 10.0.1.0\r\n    InstallerType: msix\r\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix\r\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n    SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n    Scope: user\r\n    InstallModes:\r\n      - interactive\r\n    InstallerSwitches:\r\n      Custom: /c\r\n      SilentWithProgress: /sp\r\n      Silent: /s\r\n      Interactive: /i\r\n      Log: /l=<LOGPATH>\r\n      InstallLocation: /d=<INSTALLPATH>\r\n      Upgrade: /u\r\n      Repair: /r\r\n    UpgradeBehavior: install\r\n    Commands:\r\n      - makemsixPreview\r\n      - makeappxPreview\r\n    Protocols:\r\n      - protocol1preview\r\n      - protocol2preview\r\n    FileExtensions:\r\n      - appxbundle\r\n      - msixbundle\r\n      - appx\r\n      - msix\r\n    Dependencies:\r\n      WindowsFeatures:\r\n        - PreviewIIS\r\n      WindowsLibraries:\r\n        - Preview VC Runtime\r\n      PackageDependencies:\r\n        - PackageIdentifier: Microsoft.MsixSdkDepPreview\r\n          MinimumVersion: 1.0.0\r\n      ExternalDependencies:\r\n        - Preview Outside dependencies\r\n    PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe\r\n    Capabilities:\r\n      - internetClientPreview\r\n    RestrictedCapabilities:\r\n      - runFullTrustPreview\r\n    ReleaseDate: 2021-02-02\r\n    InstallerAbortsTerminal: false\r\n    InstallLocationRequired: false\r\n    RequireExplicitUpgrade: false\r\n    DisplayInstallWarnings: false\r\n    ElevationRequirement: elevationRequired\r\n    UnsupportedArguments:\r\n      - location\r\n    UnsupportedOSArchitectures:\r\n      - arm64\r\n    Markets:\r\n      ExcludedMarkets:\r\n        - \"US\"\r\n    ExpectedReturnCodes:\r\n      - InstallerReturnCode: 2\r\n        ReturnResponse: contactSupport\r\n      - InstallerReturnCode: 3\r\n        ReturnResponse: custom\r\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\r\n    DownloadCommandProhibited: false\r\nManifestType: singleton\r\nManifestVersion: 1.7.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/ManifestV1_9-Singleton.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.9.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-US\nPublisher: Microsoft\nPublisherUrl: https://www.microsoft.com\nPublisherSupportUrl: https://www.microsoft.com/support\nPrivacyUrl: https://www.microsoft.com/privacy\nAuthor: Microsoft\nPackageName: MSIX SDK\nPackageUrl: https://www.microsoft.com/msixsdk/home\nLicense: MIT License\nLicenseUrl: https://www.microsoft.com/msixsdk/license\nCopyright: Copyright Microsoft Corporation\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright\nShortDescription: This is MSIX SDK\nDescription: The MSIX SDK project is an effort to enable developers\nMoniker: msixsdk\nTags:\n  - \"appxsdk\"\n  - \"msixsdk\"\nReleaseNotes: Default release notes\nReleaseNotesUrl: https://DefaultReleaseNotes.net\nPurchaseUrl: https://DefaultPurchaseUrl.com\nInstallationNotes: Default installation notes\nDocumentations:\n  - DocumentLabel: Default document label\n    DocumentUrl: https://DefaultDocumentUrl.com\nIcons:\n  - IconUrl: https://testIcon-en-US\n    IconFileType: ico\n    IconResolution: custom\n    IconTheme: default\n    IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\nAgreements:\n  - AgreementLabel: DefaultLabel\n    Agreement: DefaultText\n    AgreementUrl: https://DefaultAgreementUrl.net\nInstallerLocale: en-US\nPlatform:\n  - Windows.Desktop\n  - Windows.Universal\nMinimumOSVersion: 10.0.0.0\nInstallerType: exe\nScope: machine\nInstallModes:\n  - interactive\n  - silent\n  - silentWithProgress\nInstallerSwitches:\n  Custom: /custom\n  SilentWithProgress: /silentwithprogress\n  Silent: /silence\n  Interactive: /interactive\n  Log: /log=<LOGPATH>\n  InstallLocation: /dir=<INSTALLPATH>\n  Upgrade: /upgrade\n  Repair: /repair\nInstallerSuccessCodes:\n  - 1\n  - 0x80070005\nUpgradeBehavior: uninstallPrevious\nRepairBehavior: modify\nCommands:\n  - makemsix\n  - makeappx\nProtocols:\n  - protocol1\n  - protocol2\nFileExtensions:\n  - appx\n  - msix\n  - appxbundle\n  - msixbundle\nDependencies:\n  WindowsFeatures:\n    - IIS\n  WindowsLibraries:\n    - VC Runtime\n  PackageDependencies:\n    - PackageIdentifier: Microsoft.MsixSdkDep\n      MinimumVersion: 1.0.0\n  ExternalDependencies:\n    - Outside dependencies\nCapabilities:\n  - internetClient\nRestrictedCapabilities:\n  - runFullTrust\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\nProductCode: \"{Foo}\"\nReleaseDate: 2021-01-01\nInstallerAbortsTerminal: true\nInstallLocationRequired: true\nRequireExplicitUpgrade: true\nDisplayInstallWarnings: true\nElevationRequirement: elevatesSelf\nUnsupportedOSArchitectures:\n  - arm\nAppsAndFeaturesEntries:\n  - DisplayName: DisplayName\n    DisplayVersion: DisplayVersion\n    Publisher: Publisher\n    ProductCode: ProductCode\n    UpgradeCode: UpgradeCode\n    InstallerType: exe\nMarkets:\n  AllowedMarkets:\n    - US\nExpectedReturnCodes:\n  - InstallerReturnCode: 10\n    ReturnResponse: packageInUse\n    ReturnResponseUrl: https://DefaultReturnResponseUrl.com\nUnsupportedArguments:\n  - log\nNestedInstallerType: msi\nNestedInstallerFiles:\n  - RelativeFilePath: RelativeFilePath\n    PortableCommandAlias: PortableCommandAlias\nInstallationMetadata:\n  DefaultInstallLocation: \"%ProgramFiles%\\\\TestApp\"\n  Files:\n    - RelativeFilePath: \"main.exe\"\n      FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n      FileType: launch\n      InvocationParameter: \"/arg\"\n      DisplayName: \"DisplayName\"\nDownloadCommandProhibited: true\nArchiveBinariesDependOnPath: true\n\nInstallers:\n  - Architecture: x86\n    InstallerLocale: en-GB\n    Platform:\n      - Windows.Desktop\n    MinimumOSVersion: 10.0.1.0\n    InstallerType: msix\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    Scope: user\n    InstallModes:\n      - interactive\n    InstallerSwitches:\n      Custom: /c\n      SilentWithProgress: /sp\n      Silent: /s\n      Interactive: /i\n      Log: /l=<LOGPATH>\n      InstallLocation: /d=<INSTALLPATH>\n      Upgrade: /u\n      Repair: /r\n    UpgradeBehavior: install\n    Commands:\n      - makemsixPreview\n      - makeappxPreview\n    Protocols:\n      - protocol1preview\n      - protocol2preview\n    FileExtensions:\n      - appxbundle\n      - msixbundle\n      - appx\n      - msix\n    Dependencies:\n      WindowsFeatures:\n        - PreviewIIS\n      WindowsLibraries:\n        - Preview VC Runtime\n      PackageDependencies:\n        - PackageIdentifier: Microsoft.MsixSdkDepPreview\n          MinimumVersion: 1.0.0\n      ExternalDependencies:\n        - Preview Outside dependencies\n    PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe\n    Capabilities:\n      - internetClientPreview\n    RestrictedCapabilities:\n      - runFullTrustPreview\n    ReleaseDate: 2021-02-02\n    InstallerAbortsTerminal: false\n    InstallLocationRequired: false\n    RequireExplicitUpgrade: false\n    DisplayInstallWarnings: false\n    ElevationRequirement: elevationRequired\n    UnsupportedArguments:\n      - location\n    UnsupportedOSArchitectures:\n      - arm64\n    Markets:\n      ExcludedMarkets:\n        - \"US\"\n    ExpectedReturnCodes:\n      - InstallerReturnCode: 2\n        ReturnResponse: contactSupport\n      - InstallerReturnCode: 3\n        ReturnResponse: custom\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\n    DownloadCommandProhibited: false\n    ArchiveBinariesDependOnPath: false\nManifestType: singleton\nManifestVersion: 1.9.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1/ManifestV1-MultiFile-DefaultLocale.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.0.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-US\nPublisher: Microsoft\nPublisherUrl: https://www.microsoft.com\nPublisherSupportUrl: https://www.microsoft.com/support\nPrivacyUrl: https://www.microsoft.com/privacy\nAuthor: Microsoft\nPackageName: MSIX SDK\nPackageUrl: https://www.microsoft.com/msixsdk/home\nLicense: MIT License\nLicenseUrl: https://www.microsoft.com/msixsdk/license\nCopyright: Copyright Microsoft Corporation\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright\nShortDescription: This is MSIX SDK\nDescription: The MSIX SDK project is an effort to enable developers\nMoniker: msixsdk\nTags:\n  - \"appxsdk\"\n  - \"msixsdk\"\n\nManifestType: defaultLocale\nManifestVersion: 1.0.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1/ManifestV1-MultiFile-Installer.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.0.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nInstallerLocale: en-US\nPlatform:\n  - Windows.Desktop\n  - Windows.Universal\nMinimumOSVersion: 10.0.0.0\nInstallerType: exe\nScope: machine\nInstallModes:\n  - interactive\n  - silent\n  - silentWithProgress\nInstallerSwitches:\n  Custom: /custom\n  SilentWithProgress: /silentwithprogress\n  Silent: /silence\n  Interactive: /interactive\n  Log: /log=<LOGPATH>\n  InstallLocation: /dir=<INSTALLPATH>\n  Upgrade: /upgrade\nInstallerSuccessCodes:\n  - 1\n  - 0x80070005\nUpgradeBehavior: uninstallPrevious\nCommands:\n  - makemsix\n  - makeappx\nProtocols:\n  - protocol1\n  - protocol2\nFileExtensions:\n  - appx\n  - msix\n  - appxbundle\n  - msixbundle\nDependencies:\n  WindowsFeatures:\n    - IIS\n  WindowsLibraries:\n    - VC Runtime\n  PackageDependencies:\n    - PackageIdentifier: Microsoft.MsixSdkDep\n      MinimumVersion: 1.0.0\n  ExternalDependencies:\n    - Outside dependencies\nCapabilities:\n  - internetClient\nRestrictedCapabilities:\n  - runFullTrust\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\nProductCode: \"{Foo}\"\n\nInstallers:\n  - Architecture: x86\n    InstallerLocale: en-GB\n    Platform:\n      - Windows.Desktop\n    MinimumOSVersion: 10.0.1.0\n    InstallerType: msix\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    Scope: user\n    InstallModes:\n      - interactive\n    InstallerSwitches:\n      Custom: /c\n      SilentWithProgress: /sp\n      Silent: /s\n      Interactive: /i\n      Log: /l=<LOGPATH>\n      InstallLocation: /d=<INSTALLPATH>\n      Upgrade: /u\n    UpgradeBehavior: install\n    Commands:\n      - makemsixPreview\n      - makeappxPreview\n    Protocols:\n      - protocol1preview\n      - protocol2preview\n    FileExtensions:\n      - appxbundle\n      - msixbundle\n      - appx\n      - msix\n    Dependencies:\n      WindowsFeatures:\n        - PreviewIIS\n      WindowsLibraries:\n        - Preview VC Runtime\n      PackageDependencies:\n        - PackageIdentifier: Microsoft.MsixSdkDepPreview\n          MinimumVersion: 1.0.0\n      ExternalDependencies:\n        - Preview Outside dependencies\n    PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe\n    Capabilities:\n      - internetClientPreview\n    RestrictedCapabilities:\n      - runFullTrustPreview\n  - Architecture: x64\n    InstallerType: exe\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    ProductCode: \"{Bar}\"\n\nManifestType: installer\nManifestVersion: 1.0.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1/ManifestV1-MultiFile-Locale.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.locale.1.0.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-GB\nPublisher: Microsoft UK\nPublisherUrl: https://www.microsoft.com/UK\nPublisherSupportUrl: https://www.microsoft.com/support/UK\nPrivacyUrl: https://www.microsoft.com/privacy/UK\nAuthor: Microsoft UK\nPackageName: MSIX SDK UK\nPackageUrl: https://www.microsoft.com/msixsdk/home/UK\nLicense: MIT License UK\nLicenseUrl: https://www.microsoft.com/msixsdk/license/UK\nCopyright: Copyright Microsoft Corporation UK\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright/UK\nShortDescription: This is MSIX SDK UK\nDescription: The MSIX SDK project is an effort to enable developers UK\nTags:\n  - \"appxsdkUK\"\n  - \"msixsdkUK\"\n\nManifestType: locale\nManifestVersion: 1.0.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1/ManifestV1-MultiFile-Version.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.0.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nDefaultLocale: en-US\n\nManifestType: version\nManifestVersion: 1.0.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_1/ManifestV1_1-MultiFile-DefaultLocale.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.1.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-US\nPublisher: Microsoft\nPublisherUrl: https://www.microsoft.com\nPublisherSupportUrl: https://www.microsoft.com/support\nPrivacyUrl: https://www.microsoft.com/privacy\nAuthor: Microsoft\nPackageName: MSIX SDK\nPackageUrl: https://www.microsoft.com/msixsdk/home\nLicense: MIT License\nLicenseUrl: https://www.microsoft.com/msixsdk/license\nCopyright: Copyright Microsoft Corporation\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright\nShortDescription: This is MSIX SDK\nDescription: The MSIX SDK project is an effort to enable developers\nMoniker: msixsdk\nTags:\n  - \"appxsdk\"\n  - \"msixsdk\"\nReleaseNotes: Default release notes\nReleaseNotesUrl: https://DefaultReleaseNotes.net\nAgreements:\n  - AgreementLabel: DefaultLabel\n    Agreement: DefaultText\n    AgreementUrl: https://DefaultAgreementUrl.net\n\nManifestType: defaultLocale\nManifestVersion: 1.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_1/ManifestV1_1-MultiFile-Installer.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.1.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nInstallerLocale: en-US\nPlatform:\n  - Windows.Desktop\n  - Windows.Universal\nMinimumOSVersion: 10.0.0.0\nInstallerType: exe\nScope: machine\nInstallModes:\n  - interactive\n  - silent\n  - silentWithProgress\nInstallerSwitches:\n  Custom: /custom\n  SilentWithProgress: /silentwithprogress\n  Silent: /silence\n  Interactive: /interactive\n  Log: /log=<LOGPATH>\n  InstallLocation: /dir=<INSTALLPATH>\n  Upgrade: /upgrade\nInstallerSuccessCodes:\n  - 1\n  - 0x80070005\nUpgradeBehavior: uninstallPrevious\nCommands:\n  - makemsix\n  - makeappx\nProtocols:\n  - protocol1\n  - protocol2\nFileExtensions:\n  - appx\n  - msix\n  - appxbundle\n  - msixbundle\nDependencies:\n  WindowsFeatures:\n    - IIS\n  WindowsLibraries:\n    - VC Runtime\n  PackageDependencies:\n    - PackageIdentifier: Microsoft.MsixSdkDep\n      MinimumVersion: 1.0.0\n  ExternalDependencies:\n    - Outside dependencies\nCapabilities:\n  - internetClient\nRestrictedCapabilities:\n  - runFullTrust\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\nProductCode: \"{Foo}\"\nReleaseDate: 2021-01-01\nInstallerAbortsTerminal: true\nInstallLocationRequired: true\nRequireExplicitUpgrade: true\nElevationRequirement: elevatesSelf\nUnsupportedOSArchitectures:\n  - arm\nAppsAndFeaturesEntries:\n  - DisplayName: DisplayName\n    DisplayVersion: DisplayVersion\n    Publisher: Publisher\n    ProductCode: ProductCode\n    UpgradeCode: UpgradeCode\n    InstallerType: exe\nMarkets:\n  AllowedMarkets:\n    - \"US\"\nExpectedReturnCodes:\n  - InstallerReturnCode: 10\n    ReturnResponse: packageInUse\n\nInstallers:\n  - Architecture: x86\n    InstallerLocale: en-GB\n    Platform:\n      - Windows.Desktop\n    MinimumOSVersion: 10.0.1.0\n    InstallerType: msix\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    Scope: user\n    InstallModes:\n      - interactive\n    InstallerSwitches:\n      Custom: /c\n      SilentWithProgress: /sp\n      Silent: /s\n      Interactive: /i\n      Log: /l=<LOGPATH>\n      InstallLocation: /d=<INSTALLPATH>\n      Upgrade: /u\n    UpgradeBehavior: install\n    Commands:\n      - makemsixPreview\n      - makeappxPreview\n    Protocols:\n      - protocol1preview\n      - protocol2preview\n    FileExtensions:\n      - appxbundle\n      - msixbundle\n      - appx\n      - msix\n    Dependencies:\n      WindowsFeatures:\n        - PreviewIIS\n      WindowsLibraries:\n        - Preview VC Runtime\n      PackageDependencies:\n        - PackageIdentifier: Microsoft.MsixSdkDepPreview\n          MinimumVersion: 1.0.0\n      ExternalDependencies:\n        - Preview Outside dependencies\n    PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe\n    Capabilities:\n      - internetClientPreview\n    RestrictedCapabilities:\n      - runFullTrustPreview\n    ReleaseDate: 2021-02-02\n    InstallerAbortsTerminal: false\n    InstallLocationRequired: false\n    RequireExplicitUpgrade: false\n    ElevationRequirement: elevationRequired\n    UnsupportedOSArchitectures:\n      - arm64\n    Markets:\n      ExcludedMarkets:\n        - \"US\"\n    ExpectedReturnCodes:\n      - InstallerReturnCode: 2\n        ReturnResponse: contactSupport\n  - Architecture: x64\n    InstallerType: exe\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    ProductCode: \"{Bar}\"\n\nManifestType: installer\nManifestVersion: 1.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_1/ManifestV1_1-MultiFile-Locale.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.locale.1.1.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-GB\nPublisher: Microsoft UK\nPublisherUrl: https://www.microsoft.com/UK\nPublisherSupportUrl: https://www.microsoft.com/support/UK\nPrivacyUrl: https://www.microsoft.com/privacy/UK\nAuthor: Microsoft UK\nPackageName: MSIX SDK UK\nPackageUrl: https://www.microsoft.com/msixsdk/home/UK\nLicense: MIT License UK\nLicenseUrl: https://www.microsoft.com/msixsdk/license/UK\nCopyright: Copyright Microsoft Corporation UK\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright/UK\nShortDescription: This is MSIX SDK UK\nDescription: The MSIX SDK project is an effort to enable developers UK\nTags:\n  - \"appxsdkUK\"\n  - \"msixsdkUK\"\nReleaseNotes: Release notes\nReleaseNotesUrl: https://ReleaseNotes.net\nAgreements:\n  - AgreementLabel: Label\n    Agreement: Text\n    AgreementUrl: https://AgreementUrl.net\n\nManifestType: locale\nManifestVersion: 1.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_1/ManifestV1_1-MultiFile-Version.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.1.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nDefaultLocale: en-US\n\nManifestType: version\nManifestVersion: 1.1.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_10/ManifestV1_10-MultiFile-DefaultLocale.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.10.0.schema.json\r\n\r\nPackageIdentifier: microsoft.msixsdk\r\nPackageVersion: 1.7.32\r\nPackageLocale: en-US\r\nPublisher: Microsoft\r\nPublisherUrl: https://www.microsoft.com\r\nPublisherSupportUrl: https://www.microsoft.com/support\r\nPrivacyUrl: https://www.microsoft.com/privacy\r\nAuthor: Microsoft\r\nPackageName: MSIX SDK\r\nPackageUrl: https://www.microsoft.com/msixsdk/home\r\nLicense: MIT License\r\nLicenseUrl: https://www.microsoft.com/msixsdk/license\r\nCopyright: Copyright Microsoft Corporation\r\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright\r\nPurchaseUrl: https://DefaultPurchaseUrl.com\r\nInstallationNotes: \"Default installation notes\"\r\nShortDescription: This is MSIX SDK\r\nDescription: The MSIX SDK project is an effort to enable developers\r\nMoniker: msixsdk\r\nTags:\r\n  - \"appxsdk\"\r\n  - \"msixsdk\"\r\nReleaseNotes: Default release notes\r\nReleaseNotesUrl: https://DefaultReleaseNotes.net\r\nDocumentations:\r\n  - DocumentLabel: Default document label\r\n    DocumentUrl: https://DefaultDocumentUrl.com\r\nIcons:\r\n  - IconUrl: https://testIcon-en-US\r\n    IconFileType: ico\r\n    IconResolution: custom\r\n    IconTheme: default\r\n    IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\r\nAgreements:\r\n  - AgreementLabel: DefaultLabel\r\n    Agreement: DefaultText\r\n    AgreementUrl: https://DefaultAgreementUrl.net\r\nManifestType: defaultLocale\r\nManifestVersion: 1.10.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_10/ManifestV1_10-MultiFile-Installer.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.10.0.schema.json\r\n\r\nPackageIdentifier: microsoft.msixsdk\r\nPackageVersion: 1.7.32\r\nInstallerLocale: en-US\r\nPlatform:\r\n  - Windows.Desktop\r\n  - Windows.Universal\r\nMinimumOSVersion: 10.0.0.0\r\nInstallerType: exe\r\nScope: machine\r\nInstallModes:\r\n  - interactive\r\n  - silent\r\n  - silentWithProgress\r\nInstallerSwitches:\r\n  Custom: /custom\r\n  SilentWithProgress: /silentwithprogress\r\n  Silent: /silence\r\n  Interactive: /interactive\r\n  Log: /log=<LOGPATH>\r\n  InstallLocation: /dir=<INSTALLPATH>\r\n  Upgrade: /upgrade\r\n  Repair: /repair\r\nInstallerSuccessCodes:\r\n  - 1\r\n  - 0x80070005\r\nUpgradeBehavior: uninstallPrevious\r\nRepairBehavior: modify\r\nCommands:\r\n  - makemsix\r\n  - makeappx\r\nProtocols:\r\n  - protocol1\r\n  - protocol2\r\nFileExtensions:\r\n  - appx\r\n  - msix\r\n  - appxbundle\r\n  - msixbundle\r\nDependencies:\r\n  WindowsFeatures:\r\n    - IIS\r\n  WindowsLibraries:\r\n    - VC Runtime\r\n  PackageDependencies:\r\n    - PackageIdentifier: Microsoft.MsixSdkDep\r\n      MinimumVersion: 1.0.0\r\n  ExternalDependencies:\r\n    - Outside dependencies\r\nCapabilities:\r\n  - internetClient\r\nRestrictedCapabilities:\r\n  - runFullTrust\r\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\r\nProductCode: \"{Foo}\"\r\nReleaseDate: 2021-01-01\r\nInstallerAbortsTerminal: true\r\nInstallLocationRequired: true\r\nRequireExplicitUpgrade: true\r\nDisplayInstallWarnings: true\r\nElevationRequirement: elevatesSelf\r\nUnsupportedOSArchitectures:\r\n  - arm\r\nAppsAndFeaturesEntries:\r\n  - DisplayName: DisplayName\r\n    DisplayVersion: DisplayVersion\r\n    Publisher: Publisher\r\n    ProductCode: ProductCode\r\n    UpgradeCode: UpgradeCode\r\n    InstallerType: exe\r\nMarkets:\r\n  AllowedMarkets:\r\n    - \"US\"\r\nExpectedReturnCodes:\r\n  - InstallerReturnCode: 10\r\n    ReturnResponse: packageInUse\r\n    ReturnResponseUrl: https://DefaultReturnResponseUrl.com\r\nUnsupportedArguments:\r\n  - log\r\nNestedInstallerType: msi\r\nNestedInstallerFiles:\r\n  - RelativeFilePath: RelativeFilePath\r\n    PortableCommandAlias: PortableCommandAlias\r\nInstallationMetadata:\r\n  DefaultInstallLocation: \"%ProgramFiles%\\\\TestApp\"\r\n  Files:\r\n    - RelativeFilePath: \"main.exe\"\r\n      FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n      FileType: launch\r\n      InvocationParameter: \"/arg\"\r\n      DisplayName: \"DisplayName\"\r\nDownloadCommandProhibited: true\r\nArchiveBinariesDependOnPath: true\r\n\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerLocale: en-GB\r\n    Platform:\r\n      - Windows.Desktop\r\n    MinimumOSVersion: 10.0.1.0\r\n    InstallerType: msix\r\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix\r\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n    SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n    Scope: user\r\n    InstallModes:\r\n      - interactive\r\n    InstallerSwitches:\r\n      Custom: /c\r\n      SilentWithProgress: /sp\r\n      Silent: /s\r\n      Interactive: /i\r\n      Log: /l=<LOGPATH>\r\n      InstallLocation: /d=<INSTALLPATH>\r\n      Upgrade: /u\r\n      Repair: /r\r\n    UpgradeBehavior: install\r\n    Commands:\r\n      - makemsixPreview\r\n      - makeappxPreview\r\n    Protocols:\r\n      - protocol1preview\r\n      - protocol2preview\r\n    FileExtensions:\r\n      - appxbundle\r\n      - msixbundle\r\n      - appx\r\n      - msix\r\n    Dependencies:\r\n      WindowsFeatures:\r\n        - PreviewIIS\r\n      WindowsLibraries:\r\n        - Preview VC Runtime\r\n      PackageDependencies:\r\n        - PackageIdentifier: Microsoft.MsixSdkDepPreview\r\n          MinimumVersion: 1.0.0\r\n      ExternalDependencies:\r\n        - Preview Outside dependencies\r\n    PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe\r\n    Capabilities:\r\n      - internetClientPreview\r\n    RestrictedCapabilities:\r\n      - runFullTrustPreview\r\n    ReleaseDate: 2021-02-02\r\n    InstallerAbortsTerminal: false\r\n    InstallLocationRequired: false\r\n    RequireExplicitUpgrade: false\r\n    DisplayInstallWarnings: false\r\n    ElevationRequirement: elevationRequired\r\n    UnsupportedOSArchitectures:\r\n      - arm64\r\n    Markets:\r\n      ExcludedMarkets:\r\n        - \"US\"\r\n    ExpectedReturnCodes:\r\n      - InstallerReturnCode: 2\r\n        ReturnResponse: contactSupport\r\n      - InstallerReturnCode: 3\r\n        ReturnResponse: custom\r\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\r\n    UnsupportedArguments:\r\n      - location\r\n    DownloadCommandProhibited: false\r\n    ArchiveBinariesDependOnPath: false\r\n  - Architecture: x64\r\n    InstallerType: exe\r\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\r\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n    ProductCode: \"{Bar}\"\r\n    InstallerSwitches:\r\n      Repair: /r\r\n    UpgradeBehavior: deny\r\n    RepairBehavior: uninstaller\r\n  - Architecture: x86\r\n    InstallerType: portable\r\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.exe\r\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n    DisplayInstallWarnings: false\r\n    Commands:\r\n      - standalone\r\n    ExpectedReturnCodes:\r\n      - InstallerReturnCode: 11\r\n        ReturnResponse: custom\r\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\r\n  - Architecture: x64\r\n    InstallerType: zip\r\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\r\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n    NestedInstallerType: portable\r\n    NestedInstallerFiles:\r\n      - RelativeFilePath: relativeFilePath1\r\n        PortableCommandAlias: portableAlias1\r\n      - RelativeFilePath: relativeFilePath2\r\n        PortableCommandAlias: portableAlias2\r\n    InstallationMetadata:\r\n      DefaultInstallLocation: \"%ProgramFiles%\\\\TestApp2\"\r\n      Files:\r\n      - RelativeFilePath: \"main2.exe\"\r\n        FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n        FileType: other\r\n        InvocationParameter: \"/arg2\"\r\n        DisplayName: \"DisplayName2\"\r\n    ArchiveBinariesDependOnPath: true\r\n  - Architecture: x64\r\n    InstallerType: burn\r\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\r\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\r\n    ProductCode: \"{Bar}\"\r\n    UpgradeBehavior: deny\r\n    RepairBehavior: modify\r\nManifestType: installer\r\nManifestVersion: 1.10.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_10/ManifestV1_10-MultiFile-Locale.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.locale.1.10.0.schema.json\r\n\r\nPackageIdentifier: microsoft.msixsdk\r\nPackageVersion: 1.7.32\r\nPackageLocale: en-GB\r\nPublisher: Microsoft UK\r\nPublisherUrl: https://www.microsoft.com/UK\r\nPublisherSupportUrl: https://www.microsoft.com/support/UK\r\nPrivacyUrl: https://www.microsoft.com/privacy/UK\r\nAuthor: Microsoft UK\r\nPackageName: MSIX SDK UK\r\nPackageUrl: https://www.microsoft.com/msixsdk/home/UK\r\nLicense: MIT License UK\r\nLicenseUrl: https://www.microsoft.com/msixsdk/license/UK\r\nCopyright: Copyright Microsoft Corporation UK\r\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright/UK\r\nShortDescription: This is MSIX SDK UK\r\nDescription: The MSIX SDK project is an effort to enable developers UK\r\nTags:\r\n  - \"appxsdkUK\"\r\n  - \"msixsdkUK\"\r\nReleaseNotes: Release notes\r\nReleaseNotesUrl: https://ReleaseNotes.net\r\nPurchaseUrl: https://DefaultPurchaseUrl.com\r\nInstallationNotes: Default installation notes\r\nAgreements:\r\n  - AgreementLabel: Label\r\n    Agreement: Text\r\n    AgreementUrl: https://AgreementUrl.net\r\nDocumentations:\r\n  - DocumentLabel: Default document label\r\n    DocumentUrl: https://DefaultDocumentUrl.com\r\nIcons:\r\n  - IconUrl: https://localeTestIcon-en-GB\r\n    IconFileType: png\r\n    IconResolution: 32x32\r\n    IconTheme: light\r\n    IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321\r\nManifestType: locale\r\nManifestVersion: 1.10.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_10/ManifestV1_10-MultiFile-Version.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.10.0.schema.json\r\n\r\nPackageIdentifier: microsoft.msixsdk\r\nPackageVersion: 1.7.32\r\nDefaultLocale: en-US\r\nManifestType: version\r\nManifestVersion: 1.10.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_12/ManifestV1_12-MultiFile-DefaultLocale.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.12.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-US\nPublisher: Microsoft\nPublisherUrl: https://www.microsoft.com\nPublisherSupportUrl: https://www.microsoft.com/support\nPrivacyUrl: https://www.microsoft.com/privacy\nAuthor: Microsoft\nPackageName: MSIX SDK\nPackageUrl: https://www.microsoft.com/msixsdk/home\nLicense: MIT License\nLicenseUrl: https://www.microsoft.com/msixsdk/license\nCopyright: Copyright Microsoft Corporation\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright\nPurchaseUrl: https://DefaultPurchaseUrl.com\nInstallationNotes: \"Default installation notes\"\nShortDescription: This is MSIX SDK\nDescription: The MSIX SDK project is an effort to enable developers\nMoniker: msixsdk\nTags:\n  - \"appxsdk\"\n  - \"msixsdk\"\nReleaseNotes: Default release notes\nReleaseNotesUrl: https://DefaultReleaseNotes.net\nDocumentations:\n  - DocumentLabel: Default document label\n    DocumentUrl: https://DefaultDocumentUrl.com\nIcons:\n  - IconUrl: https://testIcon-en-US\n    IconFileType: ico\n    IconResolution: custom\n    IconTheme: default\n    IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\nAgreements:\n  - AgreementLabel: DefaultLabel\n    Agreement: DefaultText\n    AgreementUrl: https://DefaultAgreementUrl.net\nManifestType: defaultLocale\nManifestVersion: 1.12.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_12/ManifestV1_12-MultiFile-Installer.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.12.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nInstallerLocale: en-US\nPlatform:\n  - Windows.Desktop\n  - Windows.Universal\nMinimumOSVersion: 10.0.0.0\nInstallerType: exe\nScope: machine\nInstallModes:\n  - interactive\n  - silent\n  - silentWithProgress\nInstallerSwitches:\n  Custom: /custom\n  SilentWithProgress: /silentwithprogress\n  Silent: /silence\n  Interactive: /interactive\n  Log: /log=<LOGPATH>\n  InstallLocation: /dir=<INSTALLPATH>\n  Upgrade: /upgrade\n  Repair: /repair\nInstallerSuccessCodes:\n  - 1\n  - 0x80070005\nUpgradeBehavior: uninstallPrevious\nRepairBehavior: modify\nCommands:\n  - makemsix\n  - makeappx\nProtocols:\n  - protocol1\n  - protocol2\nFileExtensions:\n  - appx\n  - msix\n  - appxbundle\n  - msixbundle\nDependencies:\n  WindowsFeatures:\n    - IIS\n  WindowsLibraries:\n    - VC Runtime\n  PackageDependencies:\n    - PackageIdentifier: Microsoft.MsixSdkDep\n      MinimumVersion: 1.0.0\n  ExternalDependencies:\n    - Outside dependencies\nCapabilities:\n  - internetClient\nRestrictedCapabilities:\n  - runFullTrust\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\nProductCode: \"{Foo}\"\nReleaseDate: 2021-01-01\nInstallerAbortsTerminal: true\nInstallLocationRequired: true\nRequireExplicitUpgrade: true\nDisplayInstallWarnings: true\nElevationRequirement: elevatesSelf\nUnsupportedOSArchitectures:\n  - arm\nAppsAndFeaturesEntries:\n  - DisplayName: DisplayName\n    DisplayVersion: DisplayVersion\n    Publisher: Publisher\n    ProductCode: ProductCode\n    UpgradeCode: UpgradeCode\n    InstallerType: exe\nMarkets:\n  AllowedMarkets:\n    - \"US\"\nExpectedReturnCodes:\n  - InstallerReturnCode: 10\n    ReturnResponse: packageInUse\n    ReturnResponseUrl: https://DefaultReturnResponseUrl.com\nUnsupportedArguments:\n  - log\nNestedInstallerType: msi\nNestedInstallerFiles:\n  - RelativeFilePath: RelativeFilePath\n    PortableCommandAlias: PortableCommandAlias\nInstallationMetadata:\n  DefaultInstallLocation: \"%ProgramFiles%\\\\TestApp\"\n  Files:\n    - RelativeFilePath: \"main.exe\"\n      FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n      FileType: launch\n      InvocationParameter: \"/arg\"\n      DisplayName: \"DisplayName\"\nDownloadCommandProhibited: true\nArchiveBinariesDependOnPath: true\n\nInstallers:\n  - Architecture: x86\n    InstallerLocale: en-GB\n    Platform:\n      - Windows.Desktop\n    MinimumOSVersion: 10.0.1.0\n    InstallerType: msix\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    Scope: user\n    InstallModes:\n      - interactive\n    InstallerSwitches:\n      Custom: /c\n      SilentWithProgress: /sp\n      Silent: /s\n      Interactive: /i\n      Log: /l=<LOGPATH>\n      InstallLocation: /d=<INSTALLPATH>\n      Upgrade: /u\n      Repair: /r\n    UpgradeBehavior: install\n    Commands:\n      - makemsixPreview\n      - makeappxPreview\n    Protocols:\n      - protocol1preview\n      - protocol2preview\n    FileExtensions:\n      - appxbundle\n      - msixbundle\n      - appx\n      - msix\n    Dependencies:\n      WindowsFeatures:\n        - PreviewIIS\n      WindowsLibraries:\n        - Preview VC Runtime\n      PackageDependencies:\n        - PackageIdentifier: Microsoft.MsixSdkDepPreview\n          MinimumVersion: 1.0.0\n      ExternalDependencies:\n        - Preview Outside dependencies\n    PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe\n    Capabilities:\n      - internetClientPreview\n    RestrictedCapabilities:\n      - runFullTrustPreview\n    ReleaseDate: 2021-02-02\n    InstallerAbortsTerminal: false\n    InstallLocationRequired: false\n    RequireExplicitUpgrade: false\n    DisplayInstallWarnings: false\n    ElevationRequirement: elevationRequired\n    UnsupportedOSArchitectures:\n      - arm64\n    Markets:\n      ExcludedMarkets:\n        - \"US\"\n    ExpectedReturnCodes:\n      - InstallerReturnCode: 2\n        ReturnResponse: contactSupport\n      - InstallerReturnCode: 3\n        ReturnResponse: custom\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\n    UnsupportedArguments:\n      - location\n    DownloadCommandProhibited: false\n    ArchiveBinariesDependOnPath: false\n  - Architecture: x64\n    InstallerType: exe\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    ProductCode: \"{Bar}\"\n    InstallerSwitches:\n      Repair: /r\n    UpgradeBehavior: deny\n    RepairBehavior: uninstaller\n  - Architecture: x86\n    InstallerType: portable\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    DisplayInstallWarnings: false\n    Commands:\n      - standalone\n    ExpectedReturnCodes:\n      - InstallerReturnCode: 11\n        ReturnResponse: custom\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\n  - Architecture: x64\n    InstallerType: zip\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    NestedInstallerType: portable\n    NestedInstallerFiles:\n      - RelativeFilePath: relativeFilePath1\n        PortableCommandAlias: portableAlias1\n      - RelativeFilePath: relativeFilePath2\n        PortableCommandAlias: portableAlias2\n    InstallationMetadata:\n      DefaultInstallLocation: \"%ProgramFiles%\\\\TestApp2\"\n      Files:\n      - RelativeFilePath: \"main2.exe\"\n        FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n        FileType: other\n        InvocationParameter: \"/arg2\"\n        DisplayName: \"DisplayName2\"\n    ArchiveBinariesDependOnPath: true\n  - Architecture: x64\n    InstallerType: burn\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    ProductCode: \"{Bar}\"\n    UpgradeBehavior: deny\n    RepairBehavior: modify\n  - Architecture: neutral\n    InstallerType: zip\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    NestedInstallerType: font\n    NestedInstallerFiles:\n      - RelativeFilePath: relativeFilePath1.otf\n      - RelativeFilePath: relativeFilePath2.ttf\n      - RelativeFilePath: relativeFilePath3.fnt\n      - RelativeFilePath: relativeFilePath4.ttc\n      - RelativeFilePath: relativeFilePath5.otc\n  - Architecture: neutral\n    InstallerType: font\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\nManifestType: installer\nManifestVersion: 1.12.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_12/ManifestV1_12-MultiFile-Locale.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.locale.1.12.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-GB\nPublisher: Microsoft UK\nPublisherUrl: https://www.microsoft.com/UK\nPublisherSupportUrl: https://www.microsoft.com/support/UK\nPrivacyUrl: https://www.microsoft.com/privacy/UK\nAuthor: Microsoft UK\nPackageName: MSIX SDK UK\nPackageUrl: https://www.microsoft.com/msixsdk/home/UK\nLicense: MIT License UK\nLicenseUrl: https://www.microsoft.com/msixsdk/license/UK\nCopyright: Copyright Microsoft Corporation UK\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright/UK\nShortDescription: This is MSIX SDK UK\nDescription: The MSIX SDK project is an effort to enable developers UK\nTags:\n  - \"appxsdkUK\"\n  - \"msixsdkUK\"\nReleaseNotes: Release notes\nReleaseNotesUrl: https://ReleaseNotes.net\nPurchaseUrl: https://DefaultPurchaseUrl.com\nInstallationNotes: Default installation notes\nAgreements:\n  - AgreementLabel: Label\n    Agreement: Text\n    AgreementUrl: https://AgreementUrl.net\nDocumentations:\n  - DocumentLabel: Default document label\n    DocumentUrl: https://DefaultDocumentUrl.com\nIcons:\n  - IconUrl: https://localeTestIcon-en-GB\n    IconFileType: png\n    IconResolution: 32x32\n    IconTheme: light\n    IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321\nManifestType: locale\nManifestVersion: 1.12.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_12/ManifestV1_12-MultiFile-Version.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.12.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nDefaultLocale: en-US\nManifestType: version\nManifestVersion: 1.12.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_2/ManifestV1_2-MultiFile-DefaultLocale.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.2.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-US\nPublisher: Microsoft\nPublisherUrl: https://www.microsoft.com\nPublisherSupportUrl: https://www.microsoft.com/support\nPrivacyUrl: https://www.microsoft.com/privacy\nAuthor: Microsoft\nPackageName: MSIX SDK\nPackageUrl: https://www.microsoft.com/msixsdk/home\nLicense: MIT License\nLicenseUrl: https://www.microsoft.com/msixsdk/license\nCopyright: Copyright Microsoft Corporation\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright\nPurchaseUrl: https://DefaultPurchaseUrl.com\nInstallationNotes: \"Default installation notes\"\nShortDescription: This is MSIX SDK\nDescription: The MSIX SDK project is an effort to enable developers\nMoniker: msixsdk\nTags:\n  - \"appxsdk\"\n  - \"msixsdk\"\nReleaseNotes: Default release notes\nReleaseNotesUrl: https://DefaultReleaseNotes.net\nDocumentations:\n  - DocumentLabel: Default document label\n    DocumentUrl: https://DefaultDocumentUrl.com\nAgreements:\n  - AgreementLabel: DefaultLabel\n    Agreement: DefaultText\n    AgreementUrl: https://DefaultAgreementUrl.net\nManifestType: defaultLocale\nManifestVersion: 1.2.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_2/ManifestV1_2-MultiFile-Installer.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.2.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nInstallerLocale: en-US\nPlatform:\n  - Windows.Desktop\n  - Windows.Universal\nMinimumOSVersion: 10.0.0.0\nInstallerType: exe\nScope: machine\nInstallModes:\n  - interactive\n  - silent\n  - silentWithProgress\nInstallerSwitches:\n  Custom: /custom\n  SilentWithProgress: /silentwithprogress\n  Silent: /silence\n  Interactive: /interactive\n  Log: /log=<LOGPATH>\n  InstallLocation: /dir=<INSTALLPATH>\n  Upgrade: /upgrade\nInstallerSuccessCodes:\n  - 1\n  - 0x80070005\nUpgradeBehavior: uninstallPrevious\nCommands:\n  - makemsix\n  - makeappx\nProtocols:\n  - protocol1\n  - protocol2\nFileExtensions:\n  - appx\n  - msix\n  - appxbundle\n  - msixbundle\nDependencies:\n  WindowsFeatures:\n    - IIS\n  WindowsLibraries:\n    - VC Runtime\n  PackageDependencies:\n    - PackageIdentifier: Microsoft.MsixSdkDep\n      MinimumVersion: 1.0.0\n  ExternalDependencies:\n    - Outside dependencies\nCapabilities:\n  - internetClient\nRestrictedCapabilities:\n  - runFullTrust\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\nProductCode: \"{Foo}\"\nReleaseDate: 2021-01-01\nInstallerAbortsTerminal: true\nInstallLocationRequired: true\nRequireExplicitUpgrade: true\nDisplayInstallWarnings: true\nElevationRequirement: elevatesSelf\nUnsupportedOSArchitectures:\n  - arm\nAppsAndFeaturesEntries:\n  - DisplayName: DisplayName\n    DisplayVersion: DisplayVersion\n    Publisher: Publisher\n    ProductCode: ProductCode\n    UpgradeCode: UpgradeCode\n    InstallerType: exe\nMarkets:\n  AllowedMarkets:\n    - \"US\"\nExpectedReturnCodes:\n  - InstallerReturnCode: 10\n    ReturnResponse: packageInUse\n    ReturnResponseUrl: https://DefaultReturnResponseUrl.com\nUnsupportedArguments:\n  - log\n\nInstallers:\n  - Architecture: x86\n    InstallerLocale: en-GB\n    Platform:\n      - Windows.Desktop\n    MinimumOSVersion: 10.0.1.0\n    InstallerType: msix\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    Scope: user\n    InstallModes:\n      - interactive\n    InstallerSwitches:\n      Custom: /c\n      SilentWithProgress: /sp\n      Silent: /s\n      Interactive: /i\n      Log: /l=<LOGPATH>\n      InstallLocation: /d=<INSTALLPATH>\n      Upgrade: /u\n    UpgradeBehavior: install\n    Commands:\n      - makemsixPreview\n      - makeappxPreview\n    Protocols:\n      - protocol1preview\n      - protocol2preview\n    FileExtensions:\n      - appxbundle\n      - msixbundle\n      - appx\n      - msix\n    Dependencies:\n      WindowsFeatures:\n        - PreviewIIS\n      WindowsLibraries:\n        - Preview VC Runtime\n      PackageDependencies:\n        - PackageIdentifier: Microsoft.MsixSdkDepPreview\n          MinimumVersion: 1.0.0\n      ExternalDependencies:\n        - Preview Outside dependencies\n    PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe\n    Capabilities:\n      - internetClientPreview\n    RestrictedCapabilities:\n      - runFullTrustPreview\n    ReleaseDate: 2021-02-02\n    InstallerAbortsTerminal: false\n    InstallLocationRequired: false\n    RequireExplicitUpgrade: false\n    DisplayInstallWarnings: false\n    ElevationRequirement: elevationRequired\n    UnsupportedOSArchitectures:\n      - arm64\n    Markets:\n      ExcludedMarkets:\n        - \"US\"\n    ExpectedReturnCodes:\n      - InstallerReturnCode: 2\n        ReturnResponse: contactSupport\n      - InstallerReturnCode: 3\n        ReturnResponse: custom\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\n    UnsupportedArguments:\n      - location\n  - Architecture: x64\n    InstallerType: exe\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    ProductCode: \"{Bar}\"\n  - Architecture: x86\n    InstallerType: portable\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    DisplayInstallWarnings: false\n    Commands:\n      - standalone\n    ExpectedReturnCodes:\n     - InstallerReturnCode: 11\n       ReturnResponse: custom\n       ReturnResponseUrl: https://defaultReturnResponseUrl.com\nManifestType: installer\nManifestVersion: 1.2.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_2/ManifestV1_2-MultiFile-Locale.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.locale.1.2.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-GB\nPublisher: Microsoft UK\nPublisherUrl: https://www.microsoft.com/UK\nPublisherSupportUrl: https://www.microsoft.com/support/UK\nPrivacyUrl: https://www.microsoft.com/privacy/UK\nAuthor: Microsoft UK\nPackageName: MSIX SDK UK\nPackageUrl: https://www.microsoft.com/msixsdk/home/UK\nLicense: MIT License UK\nLicenseUrl: https://www.microsoft.com/msixsdk/license/UK\nCopyright: Copyright Microsoft Corporation UK\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright/UK\nShortDescription: This is MSIX SDK UK\nDescription: The MSIX SDK project is an effort to enable developers UK\nTags:\n  - \"appxsdkUK\"\n  - \"msixsdkUK\"\nReleaseNotes: Release notes\nReleaseNotesUrl: https://ReleaseNotes.net\nPurchaseUrl: https://DefaultPurchaseUrl.com\nInstallationNotes: Default installation notes\nAgreements:\n  - AgreementLabel: Label\n    Agreement: Text\n    AgreementUrl: https://AgreementUrl.net\nDocumentations:\n  - DocumentLabel: Default document label\n    DocumentUrl: https://DefaultDocumentUrl.com\nManifestType: locale\nManifestVersion: 1.2.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_2/ManifestV1_2-MultiFile-Version.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.2.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nDefaultLocale: en-US\nManifestType: version\nManifestVersion: 1.2.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_28/ManifestV1_28-MultiFile-DefaultLocale.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.28.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-US\nPublisher: Microsoft\nPublisherUrl: https://www.microsoft.com\nPublisherSupportUrl: https://www.microsoft.com/support\nPrivacyUrl: https://www.microsoft.com/privacy\nAuthor: Microsoft\nPackageName: MSIX SDK\nPackageUrl: https://www.microsoft.com/msixsdk/home\nLicense: MIT License\nLicenseUrl: https://www.microsoft.com/msixsdk/license\nCopyright: Copyright Microsoft Corporation\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright\nPurchaseUrl: https://DefaultPurchaseUrl.com\nInstallationNotes: \"Default installation notes\"\nShortDescription: This is MSIX SDK\nDescription: The MSIX SDK project is an effort to enable developers\nMoniker: msixsdk\nTags:\n  - \"appxsdk\"\n  - \"msixsdk\"\nReleaseNotes: Default release notes\nReleaseNotesUrl: https://DefaultReleaseNotes.net\nDocumentations:\n  - DocumentLabel: Default document label\n    DocumentUrl: https://DefaultDocumentUrl.com\nIcons:\n  - IconUrl: https://testIcon-en-US\n    IconFileType: ico\n    IconResolution: custom\n    IconTheme: default\n    IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\nAgreements:\n  - AgreementLabel: DefaultLabel\n    Agreement: DefaultText\n    AgreementUrl: https://DefaultAgreementUrl.net\nManifestType: defaultLocale\nManifestVersion: 1.28.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_28/ManifestV1_28-MultiFile-Installer.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.28.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nInstallerLocale: en-US\nPlatform:\n  - Windows.Desktop\n  - Windows.Universal\nMinimumOSVersion: 10.0.0.0\nInstallerType: exe\nScope: machine\nInstallModes:\n  - interactive\n  - silent\n  - silentWithProgress\nInstallerSwitches:\n  Custom: /custom\n  SilentWithProgress: /silentwithprogress\n  Silent: /silence\n  Interactive: /interactive\n  Log: /log=<LOGPATH>\n  InstallLocation: /dir=<INSTALLPATH>\n  Upgrade: /upgrade\n  Repair: /repair\nInstallerSuccessCodes:\n  - 1\n  - 0x80070005\nUpgradeBehavior: uninstallPrevious\nRepairBehavior: modify\nCommands:\n  - makemsix\n  - makeappx\nProtocols:\n  - protocol1\n  - protocol2\nFileExtensions:\n  - appx\n  - msix\n  - appxbundle\n  - msixbundle\nDependencies:\n  WindowsFeatures:\n    - IIS\n  WindowsLibraries:\n    - VC Runtime\n  PackageDependencies:\n    - PackageIdentifier: Microsoft.MsixSdkDep\n      MinimumVersion: 1.0.0\n  ExternalDependencies:\n    - Outside dependencies\nCapabilities:\n  - internetClient\nRestrictedCapabilities:\n  - runFullTrust\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\nProductCode: \"{Foo}\"\nReleaseDate: 2021-01-01\nInstallerAbortsTerminal: true\nInstallLocationRequired: true\nRequireExplicitUpgrade: true\nDisplayInstallWarnings: true\nElevationRequirement: elevatesSelf\nUnsupportedOSArchitectures:\n  - arm\nAppsAndFeaturesEntries:\n  - DisplayName: DisplayName\n    DisplayVersion: DisplayVersion\n    Publisher: Publisher\n    ProductCode: ProductCode\n    UpgradeCode: UpgradeCode\n    InstallerType: exe\nMarkets:\n  AllowedMarkets:\n    - \"US\"\nExpectedReturnCodes:\n  - InstallerReturnCode: 10\n    ReturnResponse: packageInUse\n    ReturnResponseUrl: https://DefaultReturnResponseUrl.com\nUnsupportedArguments:\n  - log\nNestedInstallerType: msi\nNestedInstallerFiles:\n  - RelativeFilePath: RelativeFilePath\n    PortableCommandAlias: PortableCommandAlias\nInstallationMetadata:\n  DefaultInstallLocation: \"%ProgramFiles%\\\\TestApp\"\n  Files:\n    - RelativeFilePath: \"main.exe\"\n      FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n      FileType: launch\n      InvocationParameter: \"/arg\"\n      DisplayName: \"DisplayName\"\nDownloadCommandProhibited: true\nArchiveBinariesDependOnPath: true\nDesiredStateConfiguration:\n  DSCv3:\n    Resources:\n      - Type: Microsoft.WinGet/AdminSettings\n      - Type: Microsoft.WinGet/Package\n      - Type: Microsoft.WinGet/Source\n      - Type: Microsoft.WinGet/UserSettingsFile\r\n\nInstallers:\n  - Architecture: x86\n    InstallerLocale: en-GB\n    Platform:\n      - Windows.Desktop\n    MinimumOSVersion: 10.0.1.0\n    InstallerType: msix\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    Scope: user\n    InstallModes:\n      - interactive\n    InstallerSwitches:\n      Custom: /c\n      SilentWithProgress: /sp\n      Silent: /s\n      Interactive: /i\n      Log: /l=<LOGPATH>\n      InstallLocation: /d=<INSTALLPATH>\n      Upgrade: /u\n      Repair: /r\n    UpgradeBehavior: install\n    Commands:\n      - makemsixPreview\n      - makeappxPreview\n    Protocols:\n      - protocol1preview\n      - protocol2preview\n    FileExtensions:\n      - appxbundle\n      - msixbundle\n      - appx\n      - msix\n    Dependencies:\n      WindowsFeatures:\n        - PreviewIIS\n      WindowsLibraries:\n        - Preview VC Runtime\n      PackageDependencies:\n        - PackageIdentifier: Microsoft.MsixSdkDepPreview\n          MinimumVersion: 1.0.0\n      ExternalDependencies:\n        - Preview Outside dependencies\n    PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe\n    Capabilities:\n      - internetClientPreview\n    RestrictedCapabilities:\n      - runFullTrustPreview\n    ReleaseDate: 2021-02-02\n    InstallerAbortsTerminal: false\n    InstallLocationRequired: false\n    RequireExplicitUpgrade: false\n    DisplayInstallWarnings: false\n    ElevationRequirement: elevationRequired\n    UnsupportedOSArchitectures:\n      - arm64\n    Markets:\n      ExcludedMarkets:\n        - \"US\"\n    ExpectedReturnCodes:\n      - InstallerReturnCode: 2\n        ReturnResponse: contactSupport\n      - InstallerReturnCode: 3\n        ReturnResponse: custom\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\n    UnsupportedArguments:\n      - location\n    DownloadCommandProhibited: false\n    ArchiveBinariesDependOnPath: false\n  - Architecture: x64\n    InstallerType: exe\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    ProductCode: \"{Bar}\"\n    InstallerSwitches:\n      Repair: /r\n    UpgradeBehavior: deny\n    RepairBehavior: uninstaller\n    DesiredStateConfiguration:\n      DSCv3:\n        Resources:\n          - Type: None/None\n  - Architecture: x86\n    InstallerType: portable\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    DisplayInstallWarnings: false\n    Commands:\n      - standalone\n    ExpectedReturnCodes:\n      - InstallerReturnCode: 11\n        ReturnResponse: custom\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\r\n    DesiredStateConfiguration:\r\n      DSCv3:\n  - Architecture: x64\n    InstallerType: zip\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    NestedInstallerType: portable\n    NestedInstallerFiles:\n      - RelativeFilePath: relativeFilePath1\n        PortableCommandAlias: portableAlias1\n      - RelativeFilePath: relativeFilePath2\n        PortableCommandAlias: portableAlias2\n    InstallationMetadata:\n      DefaultInstallLocation: \"%ProgramFiles%\\\\TestApp2\"\n      Files:\n      - RelativeFilePath: \"main2.exe\"\n        FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n        FileType: other\n        InvocationParameter: \"/arg2\"\n        DisplayName: \"DisplayName2\"\n    ArchiveBinariesDependOnPath: true\n  - Architecture: x64\n    InstallerType: burn\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    ProductCode: \"{Bar}\"\n    UpgradeBehavior: deny\n    RepairBehavior: modify\n  - Architecture: neutral\n    InstallerType: zip\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    NestedInstallerType: font\n    NestedInstallerFiles:\n      - RelativeFilePath: relativeFilePath1.otf\n      - RelativeFilePath: relativeFilePath2.ttf\n      - RelativeFilePath: relativeFilePath3.fnt\n      - RelativeFilePath: relativeFilePath4.ttc\n      - RelativeFilePath: relativeFilePath5.otc\n  - Architecture: neutral\n    InstallerType: font\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\nManifestType: installer\nManifestVersion: 1.28.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_28/ManifestV1_28-MultiFile-Locale.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.locale.1.28.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-GB\nPublisher: Microsoft UK\nPublisherUrl: https://www.microsoft.com/UK\nPublisherSupportUrl: https://www.microsoft.com/support/UK\nPrivacyUrl: https://www.microsoft.com/privacy/UK\nAuthor: Microsoft UK\nPackageName: MSIX SDK UK\nPackageUrl: https://www.microsoft.com/msixsdk/home/UK\nLicense: MIT License UK\nLicenseUrl: https://www.microsoft.com/msixsdk/license/UK\nCopyright: Copyright Microsoft Corporation UK\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright/UK\nShortDescription: This is MSIX SDK UK\nDescription: The MSIX SDK project is an effort to enable developers UK\nTags:\n  - \"appxsdkUK\"\n  - \"msixsdkUK\"\nReleaseNotes: Release notes\nReleaseNotesUrl: https://ReleaseNotes.net\nPurchaseUrl: https://DefaultPurchaseUrl.com\nInstallationNotes: Default installation notes\nAgreements:\n  - AgreementLabel: Label\n    Agreement: Text\n    AgreementUrl: https://AgreementUrl.net\nDocumentations:\n  - DocumentLabel: Default document label\n    DocumentUrl: https://DefaultDocumentUrl.com\nIcons:\n  - IconUrl: https://localeTestIcon-en-GB\n    IconFileType: png\n    IconResolution: 32x32\n    IconTheme: light\n    IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321\nManifestType: locale\nManifestVersion: 1.28.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_28/ManifestV1_28-MultiFile-Version.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.28.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nDefaultLocale: en-US\nManifestType: version\nManifestVersion: 1.28.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_4/ManifestV1_4-MultiFile-DefaultLocale.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.4.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-US\nPublisher: Microsoft\nPublisherUrl: https://www.microsoft.com\nPublisherSupportUrl: https://www.microsoft.com/support\nPrivacyUrl: https://www.microsoft.com/privacy\nAuthor: Microsoft\nPackageName: MSIX SDK\nPackageUrl: https://www.microsoft.com/msixsdk/home\nLicense: MIT License\nLicenseUrl: https://www.microsoft.com/msixsdk/license\nCopyright: Copyright Microsoft Corporation\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright\nPurchaseUrl: https://DefaultPurchaseUrl.com\nInstallationNotes: \"Default installation notes\"\nShortDescription: This is MSIX SDK\nDescription: The MSIX SDK project is an effort to enable developers\nMoniker: msixsdk\nTags:\n  - \"appxsdk\"\n  - \"msixsdk\"\nReleaseNotes: Default release notes\nReleaseNotesUrl: https://DefaultReleaseNotes.net\nDocumentations:\n  - DocumentLabel: Default document label\n    DocumentUrl: https://DefaultDocumentUrl.com\nAgreements:\n  - AgreementLabel: DefaultLabel\n    Agreement: DefaultText\n    AgreementUrl: https://DefaultAgreementUrl.net\nManifestType: defaultLocale\nManifestVersion: 1.4.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_4/ManifestV1_4-MultiFile-Installer.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.4.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nInstallerLocale: en-US\nPlatform:\n  - Windows.Desktop\n  - Windows.Universal\nMinimumOSVersion: 10.0.0.0\nInstallerType: exe\nScope: machine\nInstallModes:\n  - interactive\n  - silent\n  - silentWithProgress\nInstallerSwitches:\n  Custom: /custom\n  SilentWithProgress: /silentwithprogress\n  Silent: /silence\n  Interactive: /interactive\n  Log: /log=<LOGPATH>\n  InstallLocation: /dir=<INSTALLPATH>\n  Upgrade: /upgrade\nInstallerSuccessCodes:\n  - 1\n  - 0x80070005\nUpgradeBehavior: uninstallPrevious\nCommands:\n  - makemsix\n  - makeappx\nProtocols:\n  - protocol1\n  - protocol2\nFileExtensions:\n  - appx\n  - msix\n  - appxbundle\n  - msixbundle\nDependencies:\n  WindowsFeatures:\n    - IIS\n  WindowsLibraries:\n    - VC Runtime\n  PackageDependencies:\n    - PackageIdentifier: Microsoft.MsixSdkDep\n      MinimumVersion: 1.0.0\n  ExternalDependencies:\n    - Outside dependencies\nCapabilities:\n  - internetClient\nRestrictedCapabilities:\n  - runFullTrust\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\nProductCode: \"{Foo}\"\nReleaseDate: 2021-01-01\nInstallerAbortsTerminal: true\nInstallLocationRequired: true\nRequireExplicitUpgrade: true\nDisplayInstallWarnings: true\nElevationRequirement: elevatesSelf\nUnsupportedOSArchitectures:\n  - arm\nAppsAndFeaturesEntries:\n  - DisplayName: DisplayName\n    DisplayVersion: DisplayVersion\n    Publisher: Publisher\n    ProductCode: ProductCode\n    UpgradeCode: UpgradeCode\n    InstallerType: exe\nMarkets:\n  AllowedMarkets:\n    - \"US\"\nExpectedReturnCodes:\n  - InstallerReturnCode: 10\n    ReturnResponse: packageInUse\n    ReturnResponseUrl: https://DefaultReturnResponseUrl.com\nUnsupportedArguments:\n  - log\nNestedInstallerType: msi\nNestedInstallerFiles:\n  - RelativeFilePath: RelativeFilePath\n    PortableCommandAlias: PortableCommandAlias\nInstallationMetadata:\n  DefaultInstallLocation: \"%ProgramFiles%\\\\TestApp\"\n  Files:\n    - RelativeFilePath: \"main.exe\"\n      FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n      FileType: launch\n      InvocationParameter: \"/arg\"\n      DisplayName: \"DisplayName\"\n\nInstallers:\n  - Architecture: x86\n    InstallerLocale: en-GB\n    Platform:\n      - Windows.Desktop\n    MinimumOSVersion: 10.0.1.0\n    InstallerType: msix\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    Scope: user\n    InstallModes:\n      - interactive\n    InstallerSwitches:\n      Custom: /c\n      SilentWithProgress: /sp\n      Silent: /s\n      Interactive: /i\n      Log: /l=<LOGPATH>\n      InstallLocation: /d=<INSTALLPATH>\n      Upgrade: /u\n    UpgradeBehavior: install\n    Commands:\n      - makemsixPreview\n      - makeappxPreview\n    Protocols:\n      - protocol1preview\n      - protocol2preview\n    FileExtensions:\n      - appxbundle\n      - msixbundle\n      - appx\n      - msix\n    Dependencies:\n      WindowsFeatures:\n        - PreviewIIS\n      WindowsLibraries:\n        - Preview VC Runtime\n      PackageDependencies:\n        - PackageIdentifier: Microsoft.MsixSdkDepPreview\n          MinimumVersion: 1.0.0\n      ExternalDependencies:\n        - Preview Outside dependencies\n    PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe\n    Capabilities:\n      - internetClientPreview\n    RestrictedCapabilities:\n      - runFullTrustPreview\n    ReleaseDate: 2021-02-02\n    InstallerAbortsTerminal: false\n    InstallLocationRequired: false\n    RequireExplicitUpgrade: false\n    DisplayInstallWarnings: false\n    ElevationRequirement: elevationRequired\n    UnsupportedOSArchitectures:\n      - arm64\n    Markets:\n      ExcludedMarkets:\n        - \"US\"\n    ExpectedReturnCodes:\n      - InstallerReturnCode: 2\n        ReturnResponse: contactSupport\n      - InstallerReturnCode: 3\n        ReturnResponse: custom\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\n    UnsupportedArguments:\n      - location\n  - Architecture: x64\n    InstallerType: exe\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    ProductCode: \"{Bar}\"\n  - Architecture: x86\n    InstallerType: portable\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    DisplayInstallWarnings: false\n    Commands:\n      - standalone\n    ExpectedReturnCodes:\n      - InstallerReturnCode: 11\n        ReturnResponse: custom\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\n  - Architecture: x64\n    InstallerType: zip\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    NestedInstallerType: portable\n    NestedInstallerFiles:\n      - RelativeFilePath: relativeFilePath1\n        PortableCommandAlias: portableAlias1\n      - RelativeFilePath: relativeFilePath2\n        PortableCommandAlias: portableAlias2\n    InstallationMetadata:\n      DefaultInstallLocation: \"%ProgramFiles%\\\\TestApp2\"\n      Files:\n      - RelativeFilePath: \"main2.exe\"\n        FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n        FileType: other\n        InvocationParameter: \"/arg2\"\n        DisplayName: \"DisplayName2\"\nManifestType: installer\nManifestVersion: 1.4.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_4/ManifestV1_4-MultiFile-Locale.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.locale.1.4.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-GB\nPublisher: Microsoft UK\nPublisherUrl: https://www.microsoft.com/UK\nPublisherSupportUrl: https://www.microsoft.com/support/UK\nPrivacyUrl: https://www.microsoft.com/privacy/UK\nAuthor: Microsoft UK\nPackageName: MSIX SDK UK\nPackageUrl: https://www.microsoft.com/msixsdk/home/UK\nLicense: MIT License UK\nLicenseUrl: https://www.microsoft.com/msixsdk/license/UK\nCopyright: Copyright Microsoft Corporation UK\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright/UK\nShortDescription: This is MSIX SDK UK\nDescription: The MSIX SDK project is an effort to enable developers UK\nTags:\n  - \"appxsdkUK\"\n  - \"msixsdkUK\"\nReleaseNotes: Release notes\nReleaseNotesUrl: https://ReleaseNotes.net\nPurchaseUrl: https://DefaultPurchaseUrl.com\nInstallationNotes: Default installation notes\nAgreements:\n  - AgreementLabel: Label\n    Agreement: Text\n    AgreementUrl: https://AgreementUrl.net\nDocumentations:\n  - DocumentLabel: Default document label\n    DocumentUrl: https://DefaultDocumentUrl.com\nManifestType: locale\nManifestVersion: 1.4.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_4/ManifestV1_4-MultiFile-Version.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.4.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nDefaultLocale: en-US\nManifestType: version\nManifestVersion: 1.4.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_5/ManifestV1_5-MultiFile-DefaultLocale.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.5.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-US\nPublisher: Microsoft\nPublisherUrl: https://www.microsoft.com\nPublisherSupportUrl: https://www.microsoft.com/support\nPrivacyUrl: https://www.microsoft.com/privacy\nAuthor: Microsoft\nPackageName: MSIX SDK\nPackageUrl: https://www.microsoft.com/msixsdk/home\nLicense: MIT License\nLicenseUrl: https://www.microsoft.com/msixsdk/license\nCopyright: Copyright Microsoft Corporation\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright\nPurchaseUrl: https://DefaultPurchaseUrl.com\nInstallationNotes: \"Default installation notes\"\nShortDescription: This is MSIX SDK\nDescription: The MSIX SDK project is an effort to enable developers\nMoniker: msixsdk\nTags:\n  - \"appxsdk\"\n  - \"msixsdk\"\nReleaseNotes: Default release notes\nReleaseNotesUrl: https://DefaultReleaseNotes.net\nDocumentations:\n  - DocumentLabel: Default document label\n    DocumentUrl: https://DefaultDocumentUrl.com\nIcons:\n  - IconUrl: https://testIcon-en-US\n    IconFileType: ico\n    IconResolution: custom\n    IconTheme: default\n    IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\nAgreements:\n  - AgreementLabel: DefaultLabel\n    Agreement: DefaultText\n    AgreementUrl: https://DefaultAgreementUrl.net\nManifestType: defaultLocale\nManifestVersion: 1.5.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_5/ManifestV1_5-MultiFile-Installer.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.5.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nInstallerLocale: en-US\nPlatform:\n  - Windows.Desktop\n  - Windows.Universal\nMinimumOSVersion: 10.0.0.0\nInstallerType: exe\nScope: machine\nInstallModes:\n  - interactive\n  - silent\n  - silentWithProgress\nInstallerSwitches:\n  Custom: /custom\n  SilentWithProgress: /silentwithprogress\n  Silent: /silence\n  Interactive: /interactive\n  Log: /log=<LOGPATH>\n  InstallLocation: /dir=<INSTALLPATH>\n  Upgrade: /upgrade\nInstallerSuccessCodes:\n  - 1\n  - 0x80070005\nUpgradeBehavior: uninstallPrevious\nCommands:\n  - makemsix\n  - makeappx\nProtocols:\n  - protocol1\n  - protocol2\nFileExtensions:\n  - appx\n  - msix\n  - appxbundle\n  - msixbundle\nDependencies:\n  WindowsFeatures:\n    - IIS\n  WindowsLibraries:\n    - VC Runtime\n  PackageDependencies:\n    - PackageIdentifier: Microsoft.MsixSdkDep\n      MinimumVersion: 1.0.0\n  ExternalDependencies:\n    - Outside dependencies\nCapabilities:\n  - internetClient\nRestrictedCapabilities:\n  - runFullTrust\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\nProductCode: \"{Foo}\"\nReleaseDate: 2021-01-01\nInstallerAbortsTerminal: true\nInstallLocationRequired: true\nRequireExplicitUpgrade: true\nDisplayInstallWarnings: true\nElevationRequirement: elevatesSelf\nUnsupportedOSArchitectures:\n  - arm\nAppsAndFeaturesEntries:\n  - DisplayName: DisplayName\n    DisplayVersion: DisplayVersion\n    Publisher: Publisher\n    ProductCode: ProductCode\n    UpgradeCode: UpgradeCode\n    InstallerType: exe\nMarkets:\n  AllowedMarkets:\n    - \"US\"\nExpectedReturnCodes:\n  - InstallerReturnCode: 10\n    ReturnResponse: packageInUse\n    ReturnResponseUrl: https://DefaultReturnResponseUrl.com\nUnsupportedArguments:\n  - log\nNestedInstallerType: msi\nNestedInstallerFiles:\n  - RelativeFilePath: RelativeFilePath\n    PortableCommandAlias: PortableCommandAlias\nInstallationMetadata:\n  DefaultInstallLocation: \"%ProgramFiles%\\\\TestApp\"\n  Files:\n    - RelativeFilePath: \"main.exe\"\n      FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n      FileType: launch\n      InvocationParameter: \"/arg\"\n      DisplayName: \"DisplayName\"\n\nInstallers:\n  - Architecture: x86\n    InstallerLocale: en-GB\n    Platform:\n      - Windows.Desktop\n    MinimumOSVersion: 10.0.1.0\n    InstallerType: msix\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    Scope: user\n    InstallModes:\n      - interactive\n    InstallerSwitches:\n      Custom: /c\n      SilentWithProgress: /sp\n      Silent: /s\n      Interactive: /i\n      Log: /l=<LOGPATH>\n      InstallLocation: /d=<INSTALLPATH>\n      Upgrade: /u\n    UpgradeBehavior: install\n    Commands:\n      - makemsixPreview\n      - makeappxPreview\n    Protocols:\n      - protocol1preview\n      - protocol2preview\n    FileExtensions:\n      - appxbundle\n      - msixbundle\n      - appx\n      - msix\n    Dependencies:\n      WindowsFeatures:\n        - PreviewIIS\n      WindowsLibraries:\n        - Preview VC Runtime\n      PackageDependencies:\n        - PackageIdentifier: Microsoft.MsixSdkDepPreview\n          MinimumVersion: 1.0.0\n      ExternalDependencies:\n        - Preview Outside dependencies\n    PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe\n    Capabilities:\n      - internetClientPreview\n    RestrictedCapabilities:\n      - runFullTrustPreview\n    ReleaseDate: 2021-02-02\n    InstallerAbortsTerminal: false\n    InstallLocationRequired: false\n    RequireExplicitUpgrade: false\n    DisplayInstallWarnings: false\n    ElevationRequirement: elevationRequired\n    UnsupportedOSArchitectures:\n      - arm64\n    Markets:\n      ExcludedMarkets:\n        - \"US\"\n    ExpectedReturnCodes:\n      - InstallerReturnCode: 2\n        ReturnResponse: contactSupport\n      - InstallerReturnCode: 3\n        ReturnResponse: custom\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\n    UnsupportedArguments:\n      - location\n  - Architecture: x64\n    InstallerType: exe\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    ProductCode: \"{Bar}\"\n  - Architecture: x86\n    InstallerType: portable\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    DisplayInstallWarnings: false\n    Commands:\n      - standalone\n    ExpectedReturnCodes:\n      - InstallerReturnCode: 11\n        ReturnResponse: custom\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\n  - Architecture: x64\n    InstallerType: zip\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    NestedInstallerType: portable\n    NestedInstallerFiles:\n      - RelativeFilePath: relativeFilePath1\n        PortableCommandAlias: portableAlias1\n      - RelativeFilePath: relativeFilePath2\n        PortableCommandAlias: portableAlias2\n    InstallationMetadata:\n      DefaultInstallLocation: \"%ProgramFiles%\\\\TestApp2\"\n      Files:\n      - RelativeFilePath: \"main2.exe\"\n        FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n        FileType: other\n        InvocationParameter: \"/arg2\"\n        DisplayName: \"DisplayName2\"\nManifestType: installer\nManifestVersion: 1.5.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_5/ManifestV1_5-MultiFile-Locale.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.locale.1.5.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-GB\nPublisher: Microsoft UK\nPublisherUrl: https://www.microsoft.com/UK\nPublisherSupportUrl: https://www.microsoft.com/support/UK\nPrivacyUrl: https://www.microsoft.com/privacy/UK\nAuthor: Microsoft UK\nPackageName: MSIX SDK UK\nPackageUrl: https://www.microsoft.com/msixsdk/home/UK\nLicense: MIT License UK\nLicenseUrl: https://www.microsoft.com/msixsdk/license/UK\nCopyright: Copyright Microsoft Corporation UK\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright/UK\nShortDescription: This is MSIX SDK UK\nDescription: The MSIX SDK project is an effort to enable developers UK\nTags:\n  - \"appxsdkUK\"\n  - \"msixsdkUK\"\nReleaseNotes: Release notes\nReleaseNotesUrl: https://ReleaseNotes.net\nPurchaseUrl: https://DefaultPurchaseUrl.com\nInstallationNotes: Default installation notes\nAgreements:\n  - AgreementLabel: Label\n    Agreement: Text\n    AgreementUrl: https://AgreementUrl.net\nDocumentations:\n  - DocumentLabel: Default document label\n    DocumentUrl: https://DefaultDocumentUrl.com\nIcons:\n  - IconUrl: https://localeTestIcon-en-GB\n    IconFileType: png\n    IconResolution: 32x32\n    IconTheme: light\n    IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321\nManifestType: locale\nManifestVersion: 1.5.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_5/ManifestV1_5-MultiFile-Version.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.5.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nDefaultLocale: en-US\nManifestType: version\nManifestVersion: 1.5.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_6/ManifestV1_6-MultiFile-DefaultLocale.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.6.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-US\nPublisher: Microsoft\nPublisherUrl: https://www.microsoft.com\nPublisherSupportUrl: https://www.microsoft.com/support\nPrivacyUrl: https://www.microsoft.com/privacy\nAuthor: Microsoft\nPackageName: MSIX SDK\nPackageUrl: https://www.microsoft.com/msixsdk/home\nLicense: MIT License\nLicenseUrl: https://www.microsoft.com/msixsdk/license\nCopyright: Copyright Microsoft Corporation\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright\nPurchaseUrl: https://DefaultPurchaseUrl.com\nInstallationNotes: \"Default installation notes\"\nShortDescription: This is MSIX SDK\nDescription: The MSIX SDK project is an effort to enable developers\nMoniker: msixsdk\nTags:\n  - \"appxsdk\"\n  - \"msixsdk\"\nReleaseNotes: Default release notes\nReleaseNotesUrl: https://DefaultReleaseNotes.net\nDocumentations:\n  - DocumentLabel: Default document label\n    DocumentUrl: https://DefaultDocumentUrl.com\nIcons:\n  - IconUrl: https://testIcon-en-US\n    IconFileType: ico\n    IconResolution: custom\n    IconTheme: default\n    IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\nAgreements:\n  - AgreementLabel: DefaultLabel\n    Agreement: DefaultText\n    AgreementUrl: https://DefaultAgreementUrl.net\nManifestType: defaultLocale\nManifestVersion: 1.6.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_6/ManifestV1_6-MultiFile-Installer.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.6.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nInstallerLocale: en-US\nPlatform:\n  - Windows.Desktop\n  - Windows.Universal\nMinimumOSVersion: 10.0.0.0\nInstallerType: exe\nScope: machine\nInstallModes:\n  - interactive\n  - silent\n  - silentWithProgress\nInstallerSwitches:\n  Custom: /custom\n  SilentWithProgress: /silentwithprogress\n  Silent: /silence\n  Interactive: /interactive\n  Log: /log=<LOGPATH>\n  InstallLocation: /dir=<INSTALLPATH>\n  Upgrade: /upgrade\nInstallerSuccessCodes:\n  - 1\n  - 0x80070005\nUpgradeBehavior: uninstallPrevious\nCommands:\n  - makemsix\n  - makeappx\nProtocols:\n  - protocol1\n  - protocol2\nFileExtensions:\n  - appx\n  - msix\n  - appxbundle\n  - msixbundle\nDependencies:\n  WindowsFeatures:\n    - IIS\n  WindowsLibraries:\n    - VC Runtime\n  PackageDependencies:\n    - PackageIdentifier: Microsoft.MsixSdkDep\n      MinimumVersion: 1.0.0\n  ExternalDependencies:\n    - Outside dependencies\nCapabilities:\n  - internetClient\nRestrictedCapabilities:\n  - runFullTrust\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\nProductCode: \"{Foo}\"\nReleaseDate: 2021-01-01\nInstallerAbortsTerminal: true\nInstallLocationRequired: true\nRequireExplicitUpgrade: true\nDisplayInstallWarnings: true\nElevationRequirement: elevatesSelf\nUnsupportedOSArchitectures:\n  - arm\nAppsAndFeaturesEntries:\n  - DisplayName: DisplayName\n    DisplayVersion: DisplayVersion\n    Publisher: Publisher\n    ProductCode: ProductCode\n    UpgradeCode: UpgradeCode\n    InstallerType: exe\nMarkets:\n  AllowedMarkets:\n    - \"US\"\nExpectedReturnCodes:\n  - InstallerReturnCode: 10\n    ReturnResponse: packageInUse\n    ReturnResponseUrl: https://DefaultReturnResponseUrl.com\nUnsupportedArguments:\n  - log\nNestedInstallerType: msi\nNestedInstallerFiles:\n  - RelativeFilePath: RelativeFilePath\n    PortableCommandAlias: PortableCommandAlias\nInstallationMetadata:\n  DefaultInstallLocation: \"%ProgramFiles%\\\\TestApp\"\n  Files:\n    - RelativeFilePath: \"main.exe\"\n      FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n      FileType: launch\n      InvocationParameter: \"/arg\"\n      DisplayName: \"DisplayName\"\nDownloadCommandProhibited: true\n\nInstallers:\n  - Architecture: x86\n    InstallerLocale: en-GB\n    Platform:\n      - Windows.Desktop\n    MinimumOSVersion: 10.0.1.0\n    InstallerType: msix\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    Scope: user\n    InstallModes:\n      - interactive\n    InstallerSwitches:\n      Custom: /c\n      SilentWithProgress: /sp\n      Silent: /s\n      Interactive: /i\n      Log: /l=<LOGPATH>\n      InstallLocation: /d=<INSTALLPATH>\n      Upgrade: /u\n    UpgradeBehavior: install\n    Commands:\n      - makemsixPreview\n      - makeappxPreview\n    Protocols:\n      - protocol1preview\n      - protocol2preview\n    FileExtensions:\n      - appxbundle\n      - msixbundle\n      - appx\n      - msix\n    Dependencies:\n      WindowsFeatures:\n        - PreviewIIS\n      WindowsLibraries:\n        - Preview VC Runtime\n      PackageDependencies:\n        - PackageIdentifier: Microsoft.MsixSdkDepPreview\n          MinimumVersion: 1.0.0\n      ExternalDependencies:\n        - Preview Outside dependencies\n    PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe\n    Capabilities:\n      - internetClientPreview\n    RestrictedCapabilities:\n      - runFullTrustPreview\n    ReleaseDate: 2021-02-02\n    InstallerAbortsTerminal: false\n    InstallLocationRequired: false\n    RequireExplicitUpgrade: false\n    DisplayInstallWarnings: false\n    ElevationRequirement: elevationRequired\n    UnsupportedOSArchitectures:\n      - arm64\n    Markets:\n      ExcludedMarkets:\n        - \"US\"\n    ExpectedReturnCodes:\n      - InstallerReturnCode: 2\n        ReturnResponse: contactSupport\n      - InstallerReturnCode: 3\n        ReturnResponse: custom\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\n    UnsupportedArguments:\n      - location\n    DownloadCommandProhibited: false\n  - Architecture: x64\n    InstallerType: exe\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    ProductCode: \"{Bar}\"\n    UpgradeBehavior: deny\n  - Architecture: x86\n    InstallerType: portable\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    DisplayInstallWarnings: false\n    Commands:\n      - standalone\n    ExpectedReturnCodes:\n      - InstallerReturnCode: 11\n        ReturnResponse: custom\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\n  - Architecture: x64\n    InstallerType: zip\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    NestedInstallerType: portable\n    NestedInstallerFiles:\n      - RelativeFilePath: relativeFilePath1\n        PortableCommandAlias: portableAlias1\n      - RelativeFilePath: relativeFilePath2\n        PortableCommandAlias: portableAlias2\n    InstallationMetadata:\n      DefaultInstallLocation: \"%ProgramFiles%\\\\TestApp2\"\n      Files:\n      - RelativeFilePath: \"main2.exe\"\n        FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n        FileType: other\n        InvocationParameter: \"/arg2\"\n        DisplayName: \"DisplayName2\"\nManifestType: installer\nManifestVersion: 1.6.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_6/ManifestV1_6-MultiFile-Locale.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.locale.1.6.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-GB\nPublisher: Microsoft UK\nPublisherUrl: https://www.microsoft.com/UK\nPublisherSupportUrl: https://www.microsoft.com/support/UK\nPrivacyUrl: https://www.microsoft.com/privacy/UK\nAuthor: Microsoft UK\nPackageName: MSIX SDK UK\nPackageUrl: https://www.microsoft.com/msixsdk/home/UK\nLicense: MIT License UK\nLicenseUrl: https://www.microsoft.com/msixsdk/license/UK\nCopyright: Copyright Microsoft Corporation UK\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright/UK\nShortDescription: This is MSIX SDK UK\nDescription: The MSIX SDK project is an effort to enable developers UK\nTags:\n  - \"appxsdkUK\"\n  - \"msixsdkUK\"\nReleaseNotes: Release notes\nReleaseNotesUrl: https://ReleaseNotes.net\nPurchaseUrl: https://DefaultPurchaseUrl.com\nInstallationNotes: Default installation notes\nAgreements:\n  - AgreementLabel: Label\n    Agreement: Text\n    AgreementUrl: https://AgreementUrl.net\nDocumentations:\n  - DocumentLabel: Default document label\n    DocumentUrl: https://DefaultDocumentUrl.com\nIcons:\n  - IconUrl: https://localeTestIcon-en-GB\n    IconFileType: png\n    IconResolution: 32x32\n    IconTheme: light\n    IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321\nManifestType: locale\nManifestVersion: 1.6.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_6/ManifestV1_6-MultiFile-Version.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.6.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nDefaultLocale: en-US\nManifestType: version\nManifestVersion: 1.6.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_7/ManifestV1_7-MultiFile-DefaultLocale.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.7.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-US\nPublisher: Microsoft\nPublisherUrl: https://www.microsoft.com\nPublisherSupportUrl: https://www.microsoft.com/support\nPrivacyUrl: https://www.microsoft.com/privacy\nAuthor: Microsoft\nPackageName: MSIX SDK\nPackageUrl: https://www.microsoft.com/msixsdk/home\nLicense: MIT License\nLicenseUrl: https://www.microsoft.com/msixsdk/license\nCopyright: Copyright Microsoft Corporation\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright\nPurchaseUrl: https://DefaultPurchaseUrl.com\nInstallationNotes: \"Default installation notes\"\nShortDescription: This is MSIX SDK\nDescription: The MSIX SDK project is an effort to enable developers\nMoniker: msixsdk\nTags:\n  - \"appxsdk\"\n  - \"msixsdk\"\nReleaseNotes: Default release notes\nReleaseNotesUrl: https://DefaultReleaseNotes.net\nDocumentations:\n  - DocumentLabel: Default document label\n    DocumentUrl: https://DefaultDocumentUrl.com\nIcons:\n  - IconUrl: https://testIcon-en-US\n    IconFileType: ico\n    IconResolution: custom\n    IconTheme: default\n    IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\nAgreements:\n  - AgreementLabel: DefaultLabel\n    Agreement: DefaultText\n    AgreementUrl: https://DefaultAgreementUrl.net\nManifestType: defaultLocale\nManifestVersion: 1.7.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_7/ManifestV1_7-MultiFile-Installer.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.7.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nInstallerLocale: en-US\nPlatform:\n  - Windows.Desktop\n  - Windows.Universal\nMinimumOSVersion: 10.0.0.0\nInstallerType: exe\nScope: machine\nInstallModes:\n  - interactive\n  - silent\n  - silentWithProgress\nInstallerSwitches:\n  Custom: /custom\n  SilentWithProgress: /silentwithprogress\n  Silent: /silence\n  Interactive: /interactive\n  Log: /log=<LOGPATH>\n  InstallLocation: /dir=<INSTALLPATH>\n  Upgrade: /upgrade\n  Repair: /repair\nInstallerSuccessCodes:\n  - 1\n  - 0x80070005\nUpgradeBehavior: uninstallPrevious\nRepairBehavior: modify\nCommands:\n  - makemsix\n  - makeappx\nProtocols:\n  - protocol1\n  - protocol2\nFileExtensions:\n  - appx\n  - msix\n  - appxbundle\n  - msixbundle\nDependencies:\n  WindowsFeatures:\n    - IIS\n  WindowsLibraries:\n    - VC Runtime\n  PackageDependencies:\n    - PackageIdentifier: Microsoft.MsixSdkDep\n      MinimumVersion: 1.0.0\n  ExternalDependencies:\n    - Outside dependencies\nCapabilities:\n  - internetClient\nRestrictedCapabilities:\n  - runFullTrust\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\nProductCode: \"{Foo}\"\nReleaseDate: 2021-01-01\nInstallerAbortsTerminal: true\nInstallLocationRequired: true\nRequireExplicitUpgrade: true\nDisplayInstallWarnings: true\nElevationRequirement: elevatesSelf\nUnsupportedOSArchitectures:\n  - arm\nAppsAndFeaturesEntries:\n  - DisplayName: DisplayName\n    DisplayVersion: DisplayVersion\n    Publisher: Publisher\n    ProductCode: ProductCode\n    UpgradeCode: UpgradeCode\n    InstallerType: exe\nMarkets:\n  AllowedMarkets:\n    - \"US\"\nExpectedReturnCodes:\n  - InstallerReturnCode: 10\n    ReturnResponse: packageInUse\n    ReturnResponseUrl: https://DefaultReturnResponseUrl.com\nUnsupportedArguments:\n  - log\nNestedInstallerType: msi\nNestedInstallerFiles:\n  - RelativeFilePath: RelativeFilePath\n    PortableCommandAlias: PortableCommandAlias\nInstallationMetadata:\n  DefaultInstallLocation: \"%ProgramFiles%\\\\TestApp\"\n  Files:\n    - RelativeFilePath: \"main.exe\"\n      FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n      FileType: launch\n      InvocationParameter: \"/arg\"\n      DisplayName: \"DisplayName\"\nDownloadCommandProhibited: true\n\nInstallers:\n  - Architecture: x86\n    InstallerLocale: en-GB\n    Platform:\n      - Windows.Desktop\n    MinimumOSVersion: 10.0.1.0\n    InstallerType: msix\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    Scope: user\n    InstallModes:\n      - interactive\n    InstallerSwitches:\n      Custom: /c\n      SilentWithProgress: /sp\n      Silent: /s\n      Interactive: /i\n      Log: /l=<LOGPATH>\n      InstallLocation: /d=<INSTALLPATH>\n      Upgrade: /u\n      Repair: /r\n    UpgradeBehavior: install\n    Commands:\n      - makemsixPreview\n      - makeappxPreview\n    Protocols:\n      - protocol1preview\n      - protocol2preview\n    FileExtensions:\n      - appxbundle\n      - msixbundle\n      - appx\n      - msix\n    Dependencies:\n      WindowsFeatures:\n        - PreviewIIS\n      WindowsLibraries:\n        - Preview VC Runtime\n      PackageDependencies:\n        - PackageIdentifier: Microsoft.MsixSdkDepPreview\n          MinimumVersion: 1.0.0\n      ExternalDependencies:\n        - Preview Outside dependencies\n    PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe\n    Capabilities:\n      - internetClientPreview\n    RestrictedCapabilities:\n      - runFullTrustPreview\n    ReleaseDate: 2021-02-02\n    InstallerAbortsTerminal: false\n    InstallLocationRequired: false\n    RequireExplicitUpgrade: false\n    DisplayInstallWarnings: false\n    ElevationRequirement: elevationRequired\n    UnsupportedOSArchitectures:\n      - arm64\n    Markets:\n      ExcludedMarkets:\n        - \"US\"\n    ExpectedReturnCodes:\n      - InstallerReturnCode: 2\n        ReturnResponse: contactSupport\n      - InstallerReturnCode: 3\n        ReturnResponse: custom\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\n    UnsupportedArguments:\n      - location\n    DownloadCommandProhibited: false\n  - Architecture: x64\n    InstallerType: exe\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    ProductCode: \"{Bar}\"\n    InstallerSwitches:\n      Repair: /r\n    UpgradeBehavior: deny\n    RepairBehavior: uninstaller\n  - Architecture: x86\n    InstallerType: portable\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    DisplayInstallWarnings: false\n    Commands:\n      - standalone\n    ExpectedReturnCodes:\n      - InstallerReturnCode: 11\n        ReturnResponse: custom\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\n  - Architecture: x64\n    InstallerType: zip\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    NestedInstallerType: portable\n    NestedInstallerFiles:\n      - RelativeFilePath: relativeFilePath1\n        PortableCommandAlias: portableAlias1\n      - RelativeFilePath: relativeFilePath2\n        PortableCommandAlias: portableAlias2\n    InstallationMetadata:\n      DefaultInstallLocation: \"%ProgramFiles%\\\\TestApp2\"\n      Files:\n      - RelativeFilePath: \"main2.exe\"\n        FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n        FileType: other\n        InvocationParameter: \"/arg2\"\n        DisplayName: \"DisplayName2\"\n  - Architecture: x64\n    InstallerType: burn\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    ProductCode: \"{Bar}\"\n    UpgradeBehavior: deny\n    RepairBehavior: modify\nManifestType: installer\nManifestVersion: 1.7.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_7/ManifestV1_7-MultiFile-Locale.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.locale.1.7.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-GB\nPublisher: Microsoft UK\nPublisherUrl: https://www.microsoft.com/UK\nPublisherSupportUrl: https://www.microsoft.com/support/UK\nPrivacyUrl: https://www.microsoft.com/privacy/UK\nAuthor: Microsoft UK\nPackageName: MSIX SDK UK\nPackageUrl: https://www.microsoft.com/msixsdk/home/UK\nLicense: MIT License UK\nLicenseUrl: https://www.microsoft.com/msixsdk/license/UK\nCopyright: Copyright Microsoft Corporation UK\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright/UK\nShortDescription: This is MSIX SDK UK\nDescription: The MSIX SDK project is an effort to enable developers UK\nTags:\n  - \"appxsdkUK\"\n  - \"msixsdkUK\"\nReleaseNotes: Release notes\nReleaseNotesUrl: https://ReleaseNotes.net\nPurchaseUrl: https://DefaultPurchaseUrl.com\nInstallationNotes: Default installation notes\nAgreements:\n  - AgreementLabel: Label\n    Agreement: Text\n    AgreementUrl: https://AgreementUrl.net\nDocumentations:\n  - DocumentLabel: Default document label\n    DocumentUrl: https://DefaultDocumentUrl.com\nIcons:\n  - IconUrl: https://localeTestIcon-en-GB\n    IconFileType: png\n    IconResolution: 32x32\n    IconTheme: light\n    IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321\nManifestType: locale\nManifestVersion: 1.7.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_7/ManifestV1_7-MultiFile-Version.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.7.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nDefaultLocale: en-US\nManifestType: version\nManifestVersion: 1.7.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_9/ManifestV1_9-MultiFile-DefaultLocale.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.9.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-US\nPublisher: Microsoft\nPublisherUrl: https://www.microsoft.com\nPublisherSupportUrl: https://www.microsoft.com/support\nPrivacyUrl: https://www.microsoft.com/privacy\nAuthor: Microsoft\nPackageName: MSIX SDK\nPackageUrl: https://www.microsoft.com/msixsdk/home\nLicense: MIT License\nLicenseUrl: https://www.microsoft.com/msixsdk/license\nCopyright: Copyright Microsoft Corporation\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright\nPurchaseUrl: https://DefaultPurchaseUrl.com\nInstallationNotes: \"Default installation notes\"\nShortDescription: This is MSIX SDK\nDescription: The MSIX SDK project is an effort to enable developers\nMoniker: msixsdk\nTags:\n  - \"appxsdk\"\n  - \"msixsdk\"\nReleaseNotes: Default release notes\nReleaseNotesUrl: https://DefaultReleaseNotes.net\nDocumentations:\n  - DocumentLabel: Default document label\n    DocumentUrl: https://DefaultDocumentUrl.com\nIcons:\n  - IconUrl: https://testIcon-en-US\n    IconFileType: ico\n    IconResolution: custom\n    IconTheme: default\n    IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\nAgreements:\n  - AgreementLabel: DefaultLabel\n    Agreement: DefaultText\n    AgreementUrl: https://DefaultAgreementUrl.net\nManifestType: defaultLocale\nManifestVersion: 1.9.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_9/ManifestV1_9-MultiFile-Installer.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.9.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nInstallerLocale: en-US\nPlatform:\n  - Windows.Desktop\n  - Windows.Universal\nMinimumOSVersion: 10.0.0.0\nInstallerType: exe\nScope: machine\nInstallModes:\n  - interactive\n  - silent\n  - silentWithProgress\nInstallerSwitches:\n  Custom: /custom\n  SilentWithProgress: /silentwithprogress\n  Silent: /silence\n  Interactive: /interactive\n  Log: /log=<LOGPATH>\n  InstallLocation: /dir=<INSTALLPATH>\n  Upgrade: /upgrade\n  Repair: /repair\nInstallerSuccessCodes:\n  - 1\n  - 0x80070005\nUpgradeBehavior: uninstallPrevious\nRepairBehavior: modify\nCommands:\n  - makemsix\n  - makeappx\nProtocols:\n  - protocol1\n  - protocol2\nFileExtensions:\n  - appx\n  - msix\n  - appxbundle\n  - msixbundle\nDependencies:\n  WindowsFeatures:\n    - IIS\n  WindowsLibraries:\n    - VC Runtime\n  PackageDependencies:\n    - PackageIdentifier: Microsoft.MsixSdkDep\n      MinimumVersion: 1.0.0\n  ExternalDependencies:\n    - Outside dependencies\nCapabilities:\n  - internetClient\nRestrictedCapabilities:\n  - runFullTrust\nPackageFamilyName: Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\nProductCode: \"{Foo}\"\nReleaseDate: 2021-01-01\nInstallerAbortsTerminal: true\nInstallLocationRequired: true\nRequireExplicitUpgrade: true\nDisplayInstallWarnings: true\nElevationRequirement: elevatesSelf\nUnsupportedOSArchitectures:\n  - arm\nAppsAndFeaturesEntries:\n  - DisplayName: DisplayName\n    DisplayVersion: DisplayVersion\n    Publisher: Publisher\n    ProductCode: ProductCode\n    UpgradeCode: UpgradeCode\n    InstallerType: exe\nMarkets:\n  AllowedMarkets:\n    - \"US\"\nExpectedReturnCodes:\n  - InstallerReturnCode: 10\n    ReturnResponse: packageInUse\n    ReturnResponseUrl: https://DefaultReturnResponseUrl.com\nUnsupportedArguments:\n  - log\nNestedInstallerType: msi\nNestedInstallerFiles:\n  - RelativeFilePath: RelativeFilePath\n    PortableCommandAlias: PortableCommandAlias\nInstallationMetadata:\n  DefaultInstallLocation: \"%ProgramFiles%\\\\TestApp\"\n  Files:\n    - RelativeFilePath: \"main.exe\"\n      FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n      FileType: launch\n      InvocationParameter: \"/arg\"\n      DisplayName: \"DisplayName\"\nDownloadCommandProhibited: true\nArchiveBinariesDependOnPath: true\n\nInstallers:\n  - Architecture: x86\n    InstallerLocale: en-GB\n    Platform:\n      - Windows.Desktop\n    MinimumOSVersion: 10.0.1.0\n    InstallerType: msix\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.msix\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    SignatureSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    Scope: user\n    InstallModes:\n      - interactive\n    InstallerSwitches:\n      Custom: /c\n      SilentWithProgress: /sp\n      Silent: /s\n      Interactive: /i\n      Log: /l=<LOGPATH>\n      InstallLocation: /d=<INSTALLPATH>\n      Upgrade: /u\n      Repair: /r\n    UpgradeBehavior: install\n    Commands:\n      - makemsixPreview\n      - makeappxPreview\n    Protocols:\n      - protocol1preview\n      - protocol2preview\n    FileExtensions:\n      - appxbundle\n      - msixbundle\n      - appx\n      - msix\n    Dependencies:\n      WindowsFeatures:\n        - PreviewIIS\n      WindowsLibraries:\n        - Preview VC Runtime\n      PackageDependencies:\n        - PackageIdentifier: Microsoft.MsixSdkDepPreview\n          MinimumVersion: 1.0.0\n      ExternalDependencies:\n        - Preview Outside dependencies\n    PackageFamilyName: Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe\n    Capabilities:\n      - internetClientPreview\n    RestrictedCapabilities:\n      - runFullTrustPreview\n    ReleaseDate: 2021-02-02\n    InstallerAbortsTerminal: false\n    InstallLocationRequired: false\n    RequireExplicitUpgrade: false\n    DisplayInstallWarnings: false\n    ElevationRequirement: elevationRequired\n    UnsupportedOSArchitectures:\n      - arm64\n    Markets:\n      ExcludedMarkets:\n        - \"US\"\n    ExpectedReturnCodes:\n      - InstallerReturnCode: 2\n        ReturnResponse: contactSupport\n      - InstallerReturnCode: 3\n        ReturnResponse: custom\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\n    UnsupportedArguments:\n      - location\n    DownloadCommandProhibited: false\n    ArchiveBinariesDependOnPath: false\n  - Architecture: x64\n    InstallerType: exe\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    ProductCode: \"{Bar}\"\n    InstallerSwitches:\n      Repair: /r\n    UpgradeBehavior: deny\n    RepairBehavior: uninstaller\n  - Architecture: x86\n    InstallerType: portable\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx86.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    DisplayInstallWarnings: false\n    Commands:\n      - standalone\n    ExpectedReturnCodes:\n      - InstallerReturnCode: 11\n        ReturnResponse: custom\n        ReturnResponseUrl: https://defaultReturnResponseUrl.com\n  - Architecture: x64\n    InstallerType: zip\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    NestedInstallerType: portable\n    NestedInstallerFiles:\n      - RelativeFilePath: relativeFilePath1\n        PortableCommandAlias: portableAlias1\n      - RelativeFilePath: relativeFilePath2\n        PortableCommandAlias: portableAlias2\n    InstallationMetadata:\n      DefaultInstallLocation: \"%ProgramFiles%\\\\TestApp2\"\n      Files:\n      - RelativeFilePath: \"main2.exe\"\n        FileSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n        FileType: other\n        InvocationParameter: \"/arg2\"\n        DisplayName: \"DisplayName2\"\n    ArchiveBinariesDependOnPath: true\n  - Architecture: x64\n    InstallerType: burn\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    ProductCode: \"{Bar}\"\n    UpgradeBehavior: deny\n    RepairBehavior: modify\nManifestType: installer\nManifestVersion: 1.9.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_9/ManifestV1_9-MultiFile-Locale.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.locale.1.9.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-GB\nPublisher: Microsoft UK\nPublisherUrl: https://www.microsoft.com/UK\nPublisherSupportUrl: https://www.microsoft.com/support/UK\nPrivacyUrl: https://www.microsoft.com/privacy/UK\nAuthor: Microsoft UK\nPackageName: MSIX SDK UK\nPackageUrl: https://www.microsoft.com/msixsdk/home/UK\nLicense: MIT License UK\nLicenseUrl: https://www.microsoft.com/msixsdk/license/UK\nCopyright: Copyright Microsoft Corporation UK\nCopyrightUrl: https://www.microsoft.com/msixsdk/copyright/UK\nShortDescription: This is MSIX SDK UK\nDescription: The MSIX SDK project is an effort to enable developers UK\nTags:\n  - \"appxsdkUK\"\n  - \"msixsdkUK\"\nReleaseNotes: Release notes\nReleaseNotesUrl: https://ReleaseNotes.net\nPurchaseUrl: https://DefaultPurchaseUrl.com\nInstallationNotes: Default installation notes\nAgreements:\n  - AgreementLabel: Label\n    Agreement: Text\n    AgreementUrl: https://AgreementUrl.net\nDocumentations:\n  - DocumentLabel: Default document label\n    DocumentUrl: https://DefaultDocumentUrl.com\nIcons:\n  - IconUrl: https://localeTestIcon-en-GB\n    IconFileType: png\n    IconResolution: 32x32\n    IconTheme: light\n    IconSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321\nManifestType: locale\nManifestVersion: 1.9.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/MultiFileManifestV1_9/ManifestV1_9-MultiFile-Version.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.9.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nDefaultLocale: en-US\nManifestType: version\nManifestVersion: 1.9.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Node-Mapping.yaml",
    "content": "key: value\n\nrepeatedkey: repeated value\nRepeatedKey: repeated value\nRepeatedKey: repeated value\n\nMergeNode:\n  Custom: /custom\n  SilentWithProgress: /silentwithprogress\n  Silent: /silence\n\nMergeNode2:\n  silentWithProgress: /silentwithprogress\n  Interactive: /interactive\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Node-Merge.yaml",
    "content": "StrawHats:\r\n  - Name: Monkey D Luffy\r\n    Bounty: 3,000,000,000\r\n  - Name: Roronoa Zoro\r\n    Bounty: 1,111,000,000\r\n  - Name: Nami\r\n    Bounty: 366,000,000\r\n\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Node-Merge2.yaml",
    "content": "StrawHats:\r\n  - name: Monkey d Luffy\r\n    Bounty: 150,000,000\r\n    Fruit: Gomu Gomu no Mi\r\n  - Name: Nico Robin\r\n    Bounty: 930,000,000\r\n    Fruit: Hana Hana no Mi\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Node-Types.yaml",
    "content": "IntegerUnquoted: 12345\r\nIntegerSingleQuoted: '12345'\r\nIntegerDoubleQuoted: \"12345\"\r\n\r\nBooleanTrue: true\r\nStringTrue: 'true'\r\n\r\nBooleanFalse: false\r\nStringFalse: 'false'\r\n\r\nLocalTag: !myTag value"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/NormalizationInitialIds.txt",
    "content": "WildfireGames.0AD\nSweetScapeSoftware.010Editor\n360安全中心.360安全卫士\n360安全中心.360杀毒\nOpenMedia.4KSlideshowMaker\nOpenMedia.4KStogram\nOpenMedia.4KVideoDownloader\nOpenMedia.4KVideoDownloader\nOpenMedia.4KVideotoMP3\nOpenMedia.4KYouTubetoMP3\nIgorPavlov.7Zip\nIgorPavlov.7Zip\nIgorPavlov.7Zipalpha\nIgorPavlovTinoReichardt.7ZipZSZS\nAmazonWebServicesDeveloperRelations.AWSCommandLineInterface\nAmazonWebServices.AWSCommandLineInterface\nAWSServerlessApplications.AWSSAMCommandLineInterface\nAxisCommunications.AXISCameraStation\nAbacusResearch.AbaClient\nMicrosoft.AccessibilityInsightsForWindows\nMicrosoft.ActiveDirectoryAuthenticationLibraryforSQLServer\nAdobeSystems.AdobeAcrobatReaderDCCzech\nAdobeSystems.AdobeAcrobatReaderDC\nAdobeSystems.AdobeAcrobatReaderDCMUI\nAdoptOpenJDK.AdoptOpenJDKJDKwithHotspot\nAdoptOpenJDK.AdoptOpenJDKJDKwithHotspot\nAdoptOpenJDK.AdoptOpenJDKJDKwithHotspot\nAdoptOpenJDK.AdoptOpenJDKJDKwithHotspot\nAdoptOpenJDK.AdoptOpenJDKJDKwithHotspot\nAdoptOpenJDK.AdoptOpenJDKJDKwithHotspot\nAdoptOpenJDK.AdoptOpenJDKJDKwithHotspot\nFamatech.AdvancedIPScanner\nOndrejSalplachta.AdvancedLogViewer\nFamatech.AdvancedPortScanner\nPawelPsztyc.AdvancedRestClient\nAegisubTeam.Aegisub8975master8d77da3\nAegisubTeam.Aegisub\nawandersick.AeroZoombeta2\nAlacritty.Alacritty\nAlchemyDevelopmentGroup.AlchemyBeta\nAlgoryx.Algodoo\nStefanSundin.AltDrag\nAmazoncom.AmazonChime\nAmazon.AmazonCorretto\nAmazon.AmazonCorretto8\nAmazonWebServices.AmazonWorkSpaces\nAnaconda.Anaconda3\nAngryIPScanner.AngryIPScanner\nAntiMicro.AntiMicro\nAppGet.AppGet\nAppiumDevelopers.Appium\nAppiumDevelopers.Appium\nArduino.Arduino\nArmagetronAdvancedTeam.ArmagetronAdvanced\nSundaramRamaswamy.Artha\nRabidViperProductions.AssaultCube\nAudacityTeam.Audacity\nCodeUXdesigneU.AuthPass\nArminOsaj.AutoDarkMode\nLexikos.AutoHotkey\nLexikos.AutoHotkey\nTheSleuthKit.Autopsy\nGPLPublicrelease.AviSynth\nOmicronLab.AvroKeyboard\n7room.Aya\nMicrosoft.AzureCosmosDBEmulator\nMicrosoft.AzureDataStudio\nMicrosoft.AzureFunctionsCoreTools\nMicrosoft.AzureIoTExplorer\nMicrosoft.AzureIoTexplorer\nMarcinSzeniak.BCUninstaller\nContosocom.BITSManager\nBedaKosata.BKChem\nSpaceSciencesLaboratoryUCBerkeley.BOINC\nBPBibleDevelopmentTeam.BPBible\nGoogle.BackupandSyncfromGoogle\nDebaucheeOpenSourceGroup.Barrier\nDebaucheeOpenSourceGroup.Barrier\nPaulFrazee.BeakerBrowser\nElastic.Beatswinlogbeat\nElastic.Beatswinlogbeat\nMarcoMastroddiSoftware.BeeBEEP\nbeeftextorg.Beeftext\nTheBetaflightopensourceproject.BetaflightConfigurator\nScooterSoftware.BeyondCompare4\nScooterSoftware.BeyondCompare\nScooterSoftware.BeyondCompare\nBiglySoftware.BiglyBT\nBitPay.BitPay\nBitwarden.Bitwarden\nBleachBit.BleachBit\nBlenderFoundation.Blender\nBlueJeansNetwork.BlueJeans\nHamsterRepublicProductions.BobtheHamsterVGA\nApple.Bonjour\nAndrewSampson.BorderlessGaming\nMicrosoft.BotFrameworkComposer\nMicrosoft.BotFrameworkComposer\nMicrosoft.BotFrameworkComposer\nMicrosoft.BotFrameworkComposer\nMicrosoft.BotFrameworkEmulator\nMicrosoft.BotFrameworkEmulator\nMicrosoft.BotFrameworkEmulator\nbracketsio.Brackets\nBraveSoftware.Brave\nBraveSoftware.BraveNightly\nTGRMNSoftware.BulkRenameUtility\nButtercup.Buttercup\nButtercup.Buttercup\nCDogsSDLTeam.CDogsSDL\nSingularLabs.CCEnhancer\nPiriform.CCleaner\nCanneverbe.CDBurnerXP\nKitware.CMake\nCorsair.CORSAIRiCUESoftware\nCPUID.CPUIDCPUZ\nCPUID.CPUIDCPUZ\nCPUID.CPUIDCPUZ\nCPUID.CPUIDHWMonitor\nCPUID.CPUIDHWMonitor\nPenguinLabs.Cacher\nSaeraSoft.CaesiumPH\nTechSmith.Camtasia2019\nTechSmith.Camtasia2020\nSindreSorhus.Caprine\nSindreSorhus.Caprine\nGielCobben.Caption\nMathewSachin.Captura\nRedDucks.CemUI\nAlexandrSubbotin.Cerebro\nMITIST.CertAidforWindows\nsecana.CertDump\nWebprofusion.CertifyTheWeb\nawandersick.ChMac\nChefSoftware.ChefDK\nChemAxon.ChemAxonChemCurator\nChemAxon.ChemAxonMarkushEditor\nChemAxon.ChemAxonMarvinSuite\nChemAxon.ChemAxonMarvinSuite\nTheChromiumAuthors.Chromium\nCircuitDiagram.CircuitDiagram\nCircuitDiagram.CircuitDiagram\nCiscoWebex.CiscoWebexMeetings\nDanielScalzi.CitycraftLauncher\nalch.ClamWinFreeAntivirus\nFndroid.ClashforWindows\nFndroid.ClashforWindows\nFndroid.ClashforWindows\nFndroid.ClashforWindows\nBeijingEEOEducationTechnology.ClassIn\nClementine.Clementine\nMartinRidgers.Clink\nCloudflare.CloudflareWARP\nTheCodeBlocksTeam.CodeBlocks\nEranIfrah.CodeLite\nStevenCole.Coffee\nTerranovaTeam.ColobotGoldEditionalpha\nJayPrall.ColorCop\nToinane.Colorpicker\nConEmuMaximus.ConEmu201011\nConcept2.Concept2Utility\nMicrosoft.ConfigMgr2012Toolkit\nContasimple.ContasimpleDesktop\nALCPU.CoreTemp\nCouchbase.CouchbaseServerCommunityEdition\nCouchbase.CouchbaseServerEnterpriseEdition\nCozyCloud.CozyDrive\nTheCppcheckteam.Cppcheck\nHabibRehman.Crypter\ncryptomatororg.Cryptomator\nCrystalDewWorld.CrystalDiskInfo\nCrystalDewWorld.CrystalDiskInfo\nCrystalDewWorld.CrystalDiskInfoKureiKeiEdition\nCrystalDewWorld.CrystalDiskInfoShizukuEdition\nCrystalDewWorld.CrystalDiskInfo\nCrystalDewWorld.CrystalDiskInfo\nCrystalDewWorld.CrystalDiskInfoKureiKeiEdition\nCrystalDewWorld.CrystalDiskInfoShizukuEdition\nCrystalDewWorld.CrystalDiskInfo\nCrystalDewWorld.CrystalDiskInfo\nCrystalDewWorld.CrystalDiskInfoKureiKeiEdition\nCrystalDewWorld.CrystalDiskInfoShizukuEdition\nCrystalDewWorld.CrystalDiskInfo\nCrystalDewWorld.CrystalDiskInfoKureiKeiEdition\nCrystalDewWorld.CrystalDiskInfoShizukuEdition\nCrystalDewWorld.CrystalDiskMark\nCrystalDewWorld.CrystalDiskMarkShizukuEdition\ncubicsdrcom.CubicSDRInstaller\nAcroSoftware.CutePDFWriter\niterate.Cyberduck\nDBBrowserforSQLiteTeam.DBBrowserforSQLite\nDBeaver.DBeaver\nDBeaver.DBeaver\nDBeaver.DBeaver\nDBeaver.DBeaver\nDBeaver.DBeaver\nDBeaver.DBeaver\nDBeaver.DBeaver\nDBeaver.DBeaver\nDBeaver.DBeaver\nDJI.DJIAssistant2\nDJI.DJIAssistant2ForAeroscope\nDJI.DJIAssistant2ForAutopilot\nDJI.DJIAssistant2ForBatteryStation\nDJI.DJIAssistant2ForMG\nDJI.DJIAssistant2ForMatrice\nDJI.DJIAssistant2ForMavic\nDJI.DJIAssistant2ForPhantom\nTshwaneDJe.DaveGnukem\nBoxstar.DeepVocalToolBoxbetaversionbeta\nBoxstar.DeepVocalbetaversionbeta\nDeezer.Deezer\nAshleyStone.DefaultAudio\nPiriform.Defraggler\nDell.DellCommandUpdate\nDell.DellUpdate\nBloodshedSoftware.DevC\nThinkingManSoftware.Dimension4\nSerraniel.DiscordMediaLoader\nSerraniel.DiscordMediaLoader\nScottBrogden.Ditto\nDixa.Dixa\nDjVuZone.DjVuLibreDjView\nDockStation.DockStation\nDocker.DockerDesktop\nDokanyProject.DokanLibrary\nDokanyProject.DokanLibrary\nDolphinTeam.Dolphin\ndenginenet.Doomsday\nDigimezzo.Dopamine\nDoxie.Doxie\nDropbox.Dropbox\nEasternGraphics.EGRSafenetActivation\nEasternGraphics.EGRShellExtension\nEagleGet.EagleGet\nEagleGet.EagleGet\nLukeStratman.EasyConnect\nESComputing.EditPlus\nEduMIPS64DevelopmentTeam.EduMIPS64\nElastic.Elasticsearch\nElgatoSystems.ElgatoStreamDeck\nEmpochecom.Empoche\nEmpochecom.Empoche\nMacPaw.Encrypto\nawandersick.EnglishizeCmd\nSinewSoftwareSystemsPrivate.Enpass\nTheEraserProject.Eraser\nTheEraserProject.Eraser\nTheEraserProject.Eraser\nTheEraserProject.Eraser\nEsteem.Esteem\nEthereum.EthereumGethOfficialGoimplementationoftheEthereumprotocol\nEvernote.Evernotev\nEvernote.Evernotev\nDavidCarpenter.Everything\nDavidCarpenter.Everything\nDavidCarpenter.Everything\nDavidCarpenter.EverythingLite\nvoidtools.Everything\nExpressVPN.ExpressVPN\nUltrapico.Expresso\nTheExtremeTuxRacerteam.ExtremeTuxRacer\nEugeneRoshalFarGroup.FarManager3\nHShirouzu.FastCopy\nFastStoneSoft.FastStoneCapture\nFastStoneSoft.FastStoneImageViewer\nFedoraProject.FedoraMediaWriter\nAmineMouafik.Ferdi\nProgressSoftware.FiddlerEverywhere\nProgressSoftware.FiddlerEverywhere\nProgressSoftware.FiddlerEverywhere\nProgressSoftware.FiddlerEverywhere\nProgressSoftware.FiddlerEverywhere\nProgressSoftware.FiddlerEverywhere\nProgressSoftware.FiddlerEverywhere\nAdrienAllard.FileConverter\nBinaryFortressSoftware.FileSeek\nTimKosse.FileZillaClient\nTimKosse.FileZillaClient\nTimKosse.FileZillaClient\nTimKosse.FileZillaClient\nTimKosse.FileZillaClient\nMozilla.FirefoxDeveloperEdition\nMozilla.FirefoxDeveloperEdition\nMozilla.FirefoxDeveloperEdition\nMozilla.FirefoxDeveloperEdition\nOpenSightSoftware.FlashFXP5\nTheFlightGearTeam.FlightGear\nDominikLevitskyStudio.FontBase\nFontForgeBuilds.FontForge\nFreeTime.FormatFactory\nFreeTime.FormatFactory\nFoxitSoftware.FoxitPhantomPDF\nFoxitSoftware.FoxitReader\nStefanMalzner.Franz\nMarekJasinskiwwwFreeCommandercom.FreeCommanderXE\nHumanity.FreeMat\nTheGIMPTeam.GIMP\nTheGIMPTeam.GIMP\nTheGIMPTeam.GIMP\nTheGIMPTeam.GIMP\nTheGIMPTeam.GIMP\nTheGIMPTeam.GIMP\nTheGIMPTeam.GIMP\nTheGIMPTeam.GIMP\nARM.GNUArmEmbeddedToolchain92020\nTheFreeSoftwareFoundation.GNUMidnightCommander\nTheGnuPGProject.GNUPrivacyGuard\nGCNDevelopment.GNURadio\nGOGcom.GOGGALAXY\nArtifexSoftware.GPLGhostscript\nGhostgumSoftware.GSview\nGarmin.GarminExpress\nThoughtWorks.Gauge\nThoughtWorks.Gauge\nTheGeanydeveloperteam.Geany\nPrimateLabs.Geekbench5\nGephi.Gephi\nOutertech.GetDiz\nGitExtensionsTeam.GitExtensions\nGitExtensionsTeam.GitExtensions\nGitExtensionsTeam.GitExtensions\nGitHub.GitLFS\nTheGitDevelopmentCommunity.Git\nTheGitDevelopmentCommunity.Git\nTheGitDevelopmentCommunity.Git\nTheGitDevelopmentCommunity.Git\nTheGitDevelopmentCommunity.Git\nTheGitDevelopmentCommunity.Git\nGitHub.GitHubCLI\nGitHub.GitHubDesktopMachineWideInstaller\nStefHeyenrath.GitHubReleaseNotes\nTroupeTechnology.Gitter\nGlimpseProject.Glimpse\nGlimpseProject.Glimpse\nGlimpseProject.Glimpse\nGnuCashDevelopmentTeam.GnuCash\nGnuCashDevelopmentTeam.GnuCash\nGnuWin.GnuWin32Grep\nGnuWin.GnuWin32Make\nGnuWin.GnuWin32Wget\nGnuWin.GnuWin32Zip\ngolangorg.GoProgrammingLanguagego\ngolangorg.GoProgrammingLanguagego\ngolangorg.GoProgrammingLanguagego\ngolangorg.GoProgrammingLanguagego\ngolangorg.GoProgrammingLanguagego\ngolangorg.GoProgrammingLanguagego\ngolangorg.GoProgrammingLanguagego\ngolangorg.GoProgrammingLanguagego\ngolangorg.GoProgrammingLanguagego\ngolangorg.GoProgrammingLanguagego\ngolangorg.GoProgrammingLanguagego\ngolangorg.GoProgrammingLanguagego\ngolangorg.GoProgrammingLanguagego\ngolangorg.GoProgrammingLanguagego\ngolangorg.GoProgrammingLanguagego\ngolangorg.GoProgrammingLanguagego\ngolangorg.GoProgrammingLanguagego\nGoldWave.GoldWave\nGoogle.GoogleChrome\nGoogle.GoogleCloudSDK\nGoogle.GoogleEarthPro\nTheGpg4winProject.Gpg4win\nTheGpg4winProject.Gpg4win\nGrafanaLabs.GrafanaEnterprise\nGrafanaLabs.GrafanaOSS\nGrammarly.GrammarlyforMicrosoftOfficeSuite\nTheGrampsproject.GrampsAIO64\nGraphcool.GraphQLPlayground\nAdamMiskiewicz.GraphiQL\nATTResearchLabs.Graphviz\nGreenshot.Greenshot\nGridTeam.Grid\nEpiforgeSoftware.Grindstone4\nHHDSoftware.HHDSoftwareFreeHexEditorNeo\nHectorMaurcioRodriguezSegura.HMNISEdit\nHP.HPCloudRecoveryTool\nHuaweiSoftwareTechnologies.HUAWEICloud\nMartinMalikREALiX.HWiNFO64\nMartinMalikREALiX.HWiNFO64\nMartinMalikREALiX.HWiNFO64\nMartinMalikREALiX.HWiNFO64\nHandyOrg.HandyWinGet\nVincentL.Harmony\nImplbitsSoftware.HashTab\nImplbitsSoftware.HashTab\nJAMSoftware.HeavyLoad\nHedgewarsProject.Hedgewars\nAnsgarBecker.HeidiSQL\nAnsgarBecker.HeidiSQL\nAnsgarBecker.HeidiSQL\nAnsgarBecker.HeidiSQL\nAnsgarBecker.HeidiSQL\nPerforceSoftware.HelixCoreApps\nIBESoftware.HelpNDocPersonalEdition\nHexChat.HexChat\nScottLerch.HostsFileEditor\nCaphyon.Hover\nBorvid.HttpMasterExpressEdition\nBorvid.HttpMasterExpressEdition\nBorvid.HttpMasterExpressEdition\nBorvid.HttpMasterExpressEdition\nBorvid.HttpMasterProfessionalEdition\nBorvid.HttpMasterProfessionalEdition\nBorvid.HttpMasterProfessionalEdition\nHuawei.HuaweiQuickAppIDE\nHyneSon.HyneTimberDesign\nMarquisKurt.HyperspaceDesktop\nGoogle.IAPDesktop\nHexRays.IDAFreeware\nTibboTechnology.IONinja3\nDavidMoore.IPFilter\nIRCCloud.IRCCloud\nIvanZahariev.IZArc\nDuongDieuPhap.ImageGlass\nInkscape.Inkscape\njrsoftwareorg.InnoSetup\njrsoftwareorg.InnoSetup\nCrystalRich.InternetOff\nseonglae.Intuiter\nIrfanSkiljan.IrfanView\nIronPythonTeam.IronPython\nIronPythonTeam.IronPython\nISWIX.IsWiX\nSmartProjects.IsoBuster\nChemAxon.JChemNETAPI\nJabRef.JabRef\nJackett.Jackett\nSavoirFaireLinux.Jami\nOracle.Java8Update251\nOracle.Java8Update261\nJetBrains.JetBrainsToolbox\nJitsiTeam.JitsiMeet\nJitsiTeam.JitsiMeet\nLaurentCozic.Joplin\nLaurentCozic.Joplin\nLaurentCozic.Joplin\nJuliaLanguage.Julia\nJuliaLanguage.Julia\nJuliaLanguage.Julia\nKLCP.KLiteCodecPackStandard\nKLCP.KLiteMegaCodecPack\nKKBOXTaiwan.KKBOX\nChiaLungChen.Kaku\nDominikReichl.KeePassPasswordSafe\nDominikReichl.KeePassPasswordSafe\nDominikReichl.KeePassPasswordSafe\nKeePassXCTeam.KeePassXC\nKeeWeb.KeeWeb\nKeybase.Keybase\nKiCad.KiCad\nKiCad.KiCad\nKiCad.KiCad\nKrispTechnologies.Krisp\nKritaFoundation.Krita\nRoniLehto.LMath\nLBRY.LBRY\nLBRY.LBRY\nLBRY.LBRY\nLBRY.LBRY\nLBRY.LBRY\nLINE.LINE\nJosephAlbahari.LINQPad6\nLLVM.LLVM\nLMMSDevelopers.LMMS\nLMMSDevelopers.LMMS\nlove2dorg.LOVE\nleokhoa.Laragon\nLastPass.LastPass\nLazarusTeam.Lazarus\nRiotGames.LeagueofLegends\nLenovo.LenovoMigrationAssistant\nLenovo.LenovoSystemUpdate\nLakendLabs.Lens\nLeonflix.Leonflix\nBellSoft.LibericaJDK11\nBellSoft.LibericaJDK11Full\nBellSoft.LibericaJDK14\nBellSoft.LibericaJDK14Full\nBellSoft.LibericaJDK15\nBellSoft.LibericaJDK15Full\nBellSoft.LibericaJDK8\nBellSoft.LibericaJDK8Full\nLibreCADTeam.LibreCAD\nTheDocumentFoundation.LibreOffice\nTheDocumentFoundation.LibreOffice\nTeamLidarr.Lidarr\nAlexeyTyrrrzGolub.LightBulb\nAlexeyTyrrrzGolub.LightBulb\nChristianKaiser.Lightscreen\nLeifAsbrinkSM5BSZ.Linrad\nLiskFoundation.LiskHub\nListen.Listen1\nListen.Listen1\nFlywheel.Local\nCrystalRich.LockHunter\nBinaryFortressSoftware.LogFusion\nBinaryFortressSoftware.LogFusion\nLogitech.LogitechGamingSoftware\nLoom.Loom\nLyXTeam.LyX\nLyXTeam.LyX\nCOTILab.MCXStudioversionnightlybuild\nCOTILab.MCXStudio\nMoritzBunkus.MKVToolNix\nMoritzBunkus.MKVToolNix\nMoritzBunkus.MKVToolNix\nMoritzBunkus.MKVToolNix\nMoritzBunkus.MKVToolNix\nMPCHCTeam.MPCHC\nMPCHCTeam.MPCHC\nMPCHCTeam.MPCHC\nThomasNordquist.MQTTExplorer\nMicrosoft.MSIXCore\nMaxthonInternational.MX5\nMYCOM.MYGAMESGameCenter\nFlyingSnowSamanthaGlocker.MacType\nFiretrust.MailWasher\nFiretrust.MailWasherPro\nMajsoulPlusTeam.MajsoulPlus\nGuinpinSoft.MakeMKV\nMalwarebytes.Malwarebytes\nKDE.Marble\nMariaDB.MariaDB\nJocs.MarkText\nWestWindTechnologies.MarkdownMonster\nWestWindTechnologies.MarkdownMonster\nWestWindTechnologies.MarkdownMonster\nWestWindTechnologies.MarkdownMonster\nWestWindTechnologies.MarkdownMonster\nMarkdownOutlook.MarkdownOutlook\nMasterPackager.MasterPackager\nMattermost.Mattermost\nMediaAreanet.MediaInfo\nMediaAreanet.MediaInfoCLI\nVentisMedia.MediaMonkey\nTheMeldproject.Meld\nJaneaSystems.MemuraiDeveloper\nMicrosoft.MicrosoftNETCoreSDK\nMicrosoft.MicrosoftNETCoreSDK\nMicrosoft.MicrosoftNETCoreSDK\nMicrosoft.MicrosoftNETCoreSDK\nMicrosoft.MicrosoftNETCoreSDK\nMicrosoft.MicrosoftNETCoreSDK\nMicrosoft.MicrosoftNETFrameworkMultiTargetingPack\nMicrosoft.MicrosoftNETFrameworkMultiTargetingPack\nMicrosoft.MicrosoftNETFrameworkMultiTargetingPack\nMicrosoft.MicrosoftNETFrameworkSDK\nMicrosoft.MicrosoftNETFrameworkMultiTargetingPack\nMicrosoft.MicrosoftNETFrameworkMultiTargetingPack\nMicrosoft.MicrosoftNETFrameworkSDK\nMicrosoft.MicrosoftNETFrameworkTargetingPack\nMicrosoft.MicrosoftNETFrameworkSDK\nMicrosoft.MicrosoftNETFrameworkTargetingPack\nMicrosoft.MicrosoftNETSDK\nMicrosoft.MicrosoftNETSDK\nMicrosoft.MicrosoftNETSDK\nMicrosoft.MicrosoftNETSDK\nMicrosoft.MicrosoftAzureCLI\nMicrosoft.MicrosoftAzureStorageEmulator\nMicrosoft.MicrosoftAzureStorageExplorer\nMicrosoft.MicrosoftAzureStorageExplorer\nMicrosoft.MicrosoftDeploymentToolkit\nMicrosoft.MicrosoftEdge\nMicrosoft.MicrosoftEdgeBeta\nMicrosoft.MicrosoftEdgeDev\nMicrosoftGarage.MicrosoftGarageMousewithoutBorders\nMicrosoft.MicrosoftHelpViewer\nMicrosoft.MicrosoftHelpViewer\nMicrosoft.MicrosoftMPI\nMicrosoft.MicrosoftMPI\nMicrosoft.MicrosoftMPISDK\nMicrosoft.MicrosoftODBCDriver13forSQLServer\nMicrosoft.MicrosoftODBCDriver17forSQLServer\nMicrosoft.MicrosoftOLEDBDriverforSQLServer\nMicrosoft.MicrosoftROpen\nMicrosoft.MicrosoftROpen\nMicrosoft.MicrosoftSQLServer2012NativeClient\nMicrosoft.MicrosoftSQLServer2014ManagementObjects\nMicrosoft.MicrosoftSQLServer2016\nMicrosoft.MicrosoftSQLServer2016Policies\nMicrosoft.MicrosoftSQLServer2016TSQLLanguageService\nMicrosoft.MicrosoftSQLServer2016TSQLScriptDom\nMicrosoft.MicrosoftSQLServer2017\nMicrosoft.MicrosoftSQLServer2017Policies\nMicrosoft.MicrosoftSQLServer2017TSQLLanguageService\nMicrosoft.MicrosoftSQLServerDataTierApplicationFramework\nMicrosoft.MicrosoftSQLServerManagementStudio\nMicrosoft.MicrosoftSQLServerManagementStudio\nMicrosoft.MicrosoftSQLServerManagementStudio\nMicrosoft.MicrosoftSQLServerManagementStudio\nMicrosoft.MicrosoftSQLServerManagementStudio\nMicrosoft.MicrosoftSmallBasic\nMicrosoft.MicrosoftSystemCLRTypesforSQLServer2014\nMicrosoft.MicrosoftSystemCLRTypesforSQLServer2016\nMicrosoft.MicrosoftSystemCLRTypesforSQLServer2017\nMicrosoft.MicrosoftVisioViewer2016\nMicrosoft.MicrosoftVisualStudio2010ToolsforOfficeRuntime\nMicrosoft.MicrosoftVisualStudio2015Shell\nMicrosoft.MicrosoftVisualStudioCode\nMicrosoft.MicrosoftVisualStudioCodeInsiders\nMicrosoft.MicrosoftVisualStudioToolsforApplications2015\nMicrosoft.MicrosoftVisualStudioToolsforApplications2015LanguageSupport\nMicrosoft.MicrosoftVisualStudioToolsforApplications2017\nMicrosoft.MicrosoftWebPlatformInstaller\nAnaconda.Miniconda3\nAnaconda.Miniconda3py\nMongoDB.MongoDB2008PlusSSL\nXamarin.MonoforWindows\nTheMonoGameTeam.MonoGameSDK\nMoonlightGameStreamingProject.MoonlightGameStreamingClient\nAGALWOOD.Motrix\nAGALWOOD.Motrix\nMozilla.MozillaFirefoxESR\nMozilla.MozillaFirefoxESR\nMozilla.MozillaFirefox\nMozilla.MozillaFirefox\nMozilla.MozillaFirefox\nMozilla.MozillaFirefoxESR\nMozilla.MozillaFirefox\nMozilla.MozillaFirefox\nMozilla.MozillaFirefox\nMozilla.MozillaFirefoxESR\nMozilla.MozillaFirefoxESR\nMozilla.MozillaFirefox\nMozilla.MozillaFirefox\nMozilla.MozillaFirefox\nMozilla.MozillaFirefox\nMozilla.MozillaFirefox\nMozilla.MozillaFirefox\nMozilla.MozillaFirefox\nMozilla.MozillaFirefox\nMozilla.MozillaFirefox\nMozilla.MozillaFirefox\nMozilla.MozillaMaintenanceService\nMozilla.MozillaThunderbird\nMozilla.MozillaThunderbird\nMozilla.MozillaThunderbird\nMozilla.MozillaThunderbird\nMozilla.MozillaThunderbird\nMozilla.MozillaThunderbird\nMozilla.MozillaThunderbird\nMozilla.MozillaThunderbird\nMozilla.MozillaThunderbird\nMozilla.MozillaThunderbird\nNicholasHTollervey.Mu\nMullvadVPN.MullvadVPN\nMullvadVPN.MullvadVPN\nMicrosoft.MultilingualAppToolkit\ncanonical.Multipass\nTheMumbleDevelopers.Mumble\nTheMumbleDevelopers.Mumble\nTheMumbleDevelopers.Mumble\nWernerSchweerandOthers.MuseScore3\nYoutaTec.Muta\nLogitech.MyHarmony\nMartinRenoldandtheMyPaintDevelopmentTeam.MyPaint\nOracle.MySQLInstallerCommunity\nFeodor.Mypal\nJustinAquadro.NBTExplorer\nRicoSuter.NSwagStudio\nNVAccess.NVDA\nNVIDIA.NVIDIANVIDIARTXVoiceDriver\nNVIDIA.NVIDIARTXVoiceApplication\nNZXT.NZXTCAM\nNZXT.NZXTCAM\nNZXT.NZXTCAM\nNZXT.NZXTCAM\nNZXT.NZXTCAM\nNZXT.NZXTCAM\nAllanCORNET.Nelson\nNeotys.NeoLoad\nLutzRoeder.Netron\nNitro.NitroPro\nNmapProject.Nmap\nqinghai.NoSQLBoosterforMongoDB\nqinghai.NoSQLBoosterforMongoDB\nqinghai.NoSQLBoosterforMongoDB\nNodejsFoundation.Nodejs\nNodist.Nodist\nNordVPN.NordVPN\nTEFINCOM.NordVPN\nNordVPN.NordVPNnetworkTAP\nNordVPN.NordVPNnetworkTUN\nCodingRoad.NoteHighlight2016\nXhmikosR.Notepad2mod\nNotionLabs.Notion\nNotionLabs.Notion\nNmapProject.Npcap\nNullNoname.NullpoMino\nNullsoftandContributors.NullsoftInstallSystem\nOBSProject.OBSStudio\nHamsterRepublicProductions.OHRRPGCEgorgonzola20200502\nAscensioSystemSIA.ONLYOFFICEDesktopEditors\nGNUOctave.Octave\nWetHatLab.OneNoteTaggingKit\nOpenShopChannel.OpenShopChannelDownloader\nTheOpenShellTeam.OpenShell\nnamazso.OpenHashTab\nnamazso.OpenHashTab\nojdkbuildopensourceproject.OpenJDK\nojdkbuildopensourceproject.OpenJDK\nojdkbuildopensourceproject.OpenJDK\nojdkbuildopensourceproject.OpenJDK\nOpenMPTDevs.OpenMPT\nApacheSoftwareFoundation.OpenOffice\nOpenRAdevelopers.OpenRA\nTheOpenSCADDevelopers.OpenSCAD\nShiningLightProductions.OpenSSL\nOpenShotStudios.OpenShotVideoEditor\nOpenTTD.OpenTTD\nOpenTTD.OpenTTD\nOpenVPNTechnologies.OpenVPN\nSparkLabs.OpenVPNConfigurationGenerator\nOpenVPNTechnologies.OpenVPNConnect\nOperaSoftware.OperaGXStable\nOperaSoftware.OperaGXStable\nOperaSoftware.OperaStable\nOperaSoftware.OperaStable\nOperaSoftware.OperaStable\nOperaSoftware.OperaStable\nOperaSoftware.OperaStable\nOperaSoftware.OperaStable\nOracle.OracleVMVirtualBox\nOracle.OracleVMVirtualBox\nOracle.OracleVMVirtualBox\nOracle.OracleVMVirtualBox\nOutSystems.OutSystemsDevelopmentEnvironment11\nEXPSystems.PDFreDirect\nSoberLemurSasdiVacondioAndrea.PDFsamBasic\nCCPKU.PKUGateway\nJanFiala.PSPadeditor\nNagleCode.PacketSender\nMoonchildProductions.PaleMoon\nMoonchildProductions.PaleMoon\nJohnMacFarlane.Pandoc\nJohnMacFarlane.Pandoc\nJohnMacFarlane.Pandoc\nParadoxInteractive.ParadoxLauncher\nParagonSoftware.ParagonBackupRecoveryÃâžÂ17CE\nParsecCloud.Parsec\nFrancescoSorge.PasteIntoFile\nGiorgioTani.PeaZip\nGiorgioTani.PeaZip\nPersepolisTeam.PersepolisDownloadManager\nHeikoSommerfeldt.PhonerLite\ntouchbyte.PhotoSync\nNGWIN.PicPick\nPicoTorrentcontributors.PicoTorrent\nblupiorg.PlanetBlupi\nSonyInteractiveEntertainmentNetworkAmerica.PlayStationÃâžÂNow\nJosefNemec.Playnite\nPlex.Plex\nPlex.PlexMediaPlayer\nPlex.PlexMediaServer\nPlex.Plexamp\nPlex.Plexamp\nPlex.Plexamp\nwwwpokerthnet.PokerTH\nPostbox.Postbox\nPostgreSQLGlobalDevelopmentGroup.PostgreSQL12\nPostgreSQLGlobalDevelopmentGroup.PostgreSQL13\nMicrosoft.PowerShell7preview\nMicrosoft.PowerShell7\nIronmanSoftware.PowerShellUniversal\nMicrosoft.PowerToys\nKimWalisch.Primesieve\nPrivateInternetAccess.PrivateInternetAccess\nProgressSoftware.ProgressTelerikFiddler\nMicrosoft.ProjectMyScreenApp\nProtonTechnologies.ProtonVPN\nProtonTechnologies.ProtonVPNTap\nSimonTatham.PuTTY\nPuppetLabs.Puppet\nPuppet.PuppetAgent\nPuppet.PuppetBolt\nPuppet.PuppetDevelopmentKit\nMillerPuckette.PureData\nLancasterUniversityPhysics.PyMODA\nPythonSoftwareFoundation.Python\nHubertPham.PythonPyAudio\nPythonSoftwareFoundation.Python\nPythonSoftwareFoundation.Python\nPythonSoftwareFoundation.Python\nPythonSoftwareFoundation.Python\nPythonSoftwareFoundation.Python\nPythonSoftwareFoundation.Python\nPythonSoftwareFoundation.Python\nPythonSoftwareFoundation.PythonLauncher\nQGISDevelopmentTeam.QGISACoru\nQGISDevelopmentTeam.QGISBucuresti\nQGISDevelopmentTeam.QGISPi\nMichaelHansen.QTextPad\nHannaKnutsson.Qalculate\nLarusStone.QtSpim\nModuleArt.QuickPictureViewer\nPaddyXu.QuickLook\nQuicken.Quicken\nRCoreTeam.RforWindows\nRCoreTeam.RforWindows\nRCoreTeam.RforWindows\nRStudio.RStudio\nRambox.Rambox\nOlegDanilov.RapidEnvironmentEditor\nRaspberryPi.RaspberryPiImager\nrawtherapeecom.RawTherapee\nPaulRawnsley.RedditWallpaperChanger\njklSoft.Rekodecompilerfor\nDevolutions.RemoteDesktopManager\nDevolutions.RemoteDesktopManagerFree\nRemoteMouse.RemoteMouse\nBaldurKarlsson.RenderDoc\nAntmicro.Renode\nResponsively.ResponsivelyApp\nRetroShareTeam.RetroShare\nVSRevoGroup.RevoUninstaller\nVSRevoGroup.RevoUninstallerPro\n3TSoftwareLabs.Robo3T\n3TSoftwareLabs.Robo3T\n3TSoftwareLabs.Robo3T\nRocketChatSupport.RocketChat\nPunkSoftware.RocketDock\nArtsoftEntertainment.RocksnDiamonds\nMarkoBL.Rosi\ncode4ward.RoyalTS\nRoyalApps.RoyalTS\nTheRFoundation.Rtools\nRubyInstallerTeam.Ruby\nRubyInstallerTeam.RubywithMSYS2\nRubyInstallerTeam.Ruby\nLukeHaas.RunJS\nLukeHaas.RunJS\nTheRustProjectDevelopers.Rust\nTheRustProjectDevelopers.Rust\nTheRustProjectDevelopers.Rust\nTheRustProjectDevelopers.Rust\nTheRustProjectDevelopers.Rust\nTheRustProjectDevelopers.Rust\nTheRustProjectDevelopers.Rust\nTheRustProjectDevelopers.Rust\nTheRustProjectDevelopers.Rust\nTopalaSoftwareSolutions.SIW2020aTrial\nRicardoVillalba.SMPlayer\nNavimatics.SSHFSWin2020\nDotzSoftwares.SVGExplorerExtension\nSamsungElectronics.SamsungDeX\nmircearoata.SatisfactoryModLauncher\nScratchFoundation.ScratchDesktop\nNickeManarin.ScreenToGif\nTheScribusTeam.Scribus\nTheScummVMTeam.ScummVM\nspikespaz.SearchDeflector\nSejda.SejdaPDFDesktop\nDatalust.Seq\nMicrosoft.SharePointOnlineManagementShell\nShareXTeam.ShareX\nRandyRantscom.SharpKeys\nMeltytech.Shotcut\nSigilEbook.Sigil\nOpenWhisperSystems.Signal\nOpenWhisperSystems.Signal\nOpenWhisperSystems.Signal\nOpenWhisperSystems.Signal\nOpenWhisperSystems.Signal\nOpenWhisperSystems.Signal\nOpenWhisperSystems.Signal\nApproximatrix.SimplyFortran3\nAshleyStone.SitdownMW\nSkypeTechnologies.Skype\nSkypeTechnologies.Skype\nSkypeTechnologies.Skype\nSlackTechnologies.SlackMachineWide\nTechSmith.Snagit2020\nSnakeNestcom.SnakeTail\nCoryPlotts.Snoop\nSmartBearSoftware.SoapUI\nSonicPi.SonicPi\nSonos.Sonos\nSonos.SonosController\nAntoineAflalo.SoundSwitch\nAtlassian.Sourcetree\nSpeedCrunch.SpeedCrunch\nSpekProject.Spek\nStandardNotes.StandardNotes\nValve.Steam\nwwwsbclorg.SteelBankCommonLisp\nSteelSeries.SteelSeriesEngine\nStellariumteam.Stellarium\nStellariumteam.Stellarium\nStellariumteam.Stellarium\nstrawberryperlcomproject.StrawberryPerl\nGeneralWorkings.StreamlabsOBS\nGeneralWorkings.StreamlabsOBS\nGeneralWorkings.StreamlabsOBS\nStreamlink.Streamlink\nSebastianMeyer.StreamlinkTwitchGUI\nJanHovancik.Stretchly\nJanHovancik.Stretchly\nJanHovancik.Stretchly\nStride.Stride\nBrickLink.Studio\nSublimeHQ.SublimeMerge\nSublimeHQ.SublimeText3\nKrzysztofKowalczyk.SumatraPDF\nSuperColliderCommunity.SuperCollider\nSuperTuxKart.SuperTuxKart3Dopensourcearcaderacerwithavarietycharacterstracksandmodestoplay\nMicrosoft.SurfaceDuoEmulator\nSyncTrayzor.SyncTrayzor\nMisterGroup.SystemExplorer\nOpenVPNTechnologies.TAPWindows\nerengy.Taiga\nTailscale.Tailscale\nTailscale.TailscaleIPN\nTaiseiProject.TaiseiProject\nTaskcade.Taskade\nTaskcade.Taskade\nTreasureData.Tdagent\nTreasureData.Tdagent\nBenitovanderZander.TeXstudioTeXstudioisafullyfeaturedLaTeXeditor\nTeXUsersGroup.TeXworks\nTeamSpeakSystems.TeamSpeak3Client\nTechPowerUp.TechPowerUpGPUZ\nTelegramFZ.TelegramDesktop\nTelegramFZ.TelegramDesktop\nTelegramFZ.TelegramDesktop\nTelegramFZ.TelegramDesktop\nTelegramFZ.TelegramDesktop\nTelegramFZ.TelegramDesktop\nTelegramFZ.TelegramDesktop\nTelegramFZ.TelegramDesktop\nTelegramFZ.TelegramDesktop\nTeraTermProject.TeraTerm\nEugenePankov.Terminus\nEugenePankov.Terminus\nEugenePankov.Terminus\nCompuPhase.Termite\nTesseractOCRcommunity.TesseractOCRopensourceOCRengine\nTexmaker.Texmaker\nTexnomic.TexnomicSecureDNSTerminal\nRaMMicHaeL.Textify\nAppestcom.TickTick\nGlavSoft.TightVNC\nTikzEdt.TikzEdt\nmapeditororg.Tiled\nNadeo.TmNationsForever\nToggl.TogglDesktop\nToggl.TogglTrack\nTortoiseGit.TortoiseGit\nTortoiseSVN.TortoiseSVN\nTortoiseSVN.TortoiseSVN\nTranslucentTBOpenSourceDevelopers.TranslucentTB\nTransmissionProject.Transmission\nYurySidorovTransmissionRemoteGUIworkinggroup.TransmissionRemoteGUI\nBinaryFortressSoftware.TrayStatus\nBinaryFortressSoftware.TrayStatus\nJAMSoftware.TreeSizeFree\nJAMSoftware.TreeSize\nTrelbyorg.Trelby\nCeruleanStudios.Trillian\nTunnelBear.TunnelBear\nNewBreedSoftware.TuxPaint\nInspectElement.Tweeten\nXanderFrangos.TwinkleTray\nTwitchInteractive.Twitch\nGDATACyberDefense.TypeRefHasher\nSafelyRemovecom.USBSafelyRemove\nDrewNaylor.UXLLauncher\nDrewNaylor.UXLLauncher\nUltimaker.UltimakerCura\nUltimaker.UltimakerCura\nUltimaker.UltimakerCura\nuvncbvba.UltraVnc\nReasonSoftware.Unchecky\nUnifiedIntents.UnifiedRemote\nUnityTechnologies.UnityHub\nMicrosoft.UpdateforKB2504637\nMicrosoft.UpdateforMicrosoftVisualStudio2015KB3095681\nUbisoft.Uplay\nUMEZAWATakeshi.UtVideoCodecSuite\nVCV.VCVRack\nVideoLAN.VLCmediaplayer\nVideoLAN.VLCmediaplayer\nVideoLAN.VLCmediaplayer\nVMware.VMwareHorizonClient\nVMware.VMwarePlayer\nVMware.VMwareWorkstation\nRealVNC.VNCServer\nRealVNC.VNCViewer\nMicrosoft.VSCodium\nMicrosoft.VSCodium\nmarhauserssourceforgenet.VcXsrv\nBramMoolenaaretal.Vim\nVirtManagerProject.VirtViewer\nVivaldiTechnologies.Vivaldi\nBlackTreeGaming.Vortex\nVoyagerX.Vrew\nLunarG.VulkanSDK\nWarzoneProject.Warzone\nWaterfox.WaterfoxCurrent\nWaterfox.WaterfoxCurrent\nWaterfox.WaterfoxCurrent\nDevolutions.WaykNow\nBuds.WeakAurasCompanion\nBuds.WeakAurasCompanion\nBuds.WeakAurasCompanion\nBuds.WeakAurasCompanion\nMachineLearningGroupUniversityofWaikatoHamiltonNZ.Weka\nImageWriterDevelopers.Win32DiskImager\nSamHocevar.WinCompose\nTimothyJohnson.WinDynamicDesktop\nTimothyJohnson.WinDynamicDesktop\nTimothyJohnson.WinDynamicDesktop\nNavimatics.WinFsp2020\nHTTrack.WinHTTrackWebsiteCopier\nThingamahoochieSoftware.WinMerge\nwinrar.WinRAR\nwinrar.WinRAR\nMartinPrikryl.WinSCP\nCorel.WinZip\nWinamp.Winamp\nMicrosoft.Windows10UpdateAssistant\nMicrosoft.WindowsAdminCenter\nMicrosoft.WindowsAssessmentandDeploymentKitWindows10\nMicrosoft.WindowsAssessmentandDeploymentKitWindowsPreinstallationEnvironmentAddonsWindows10\nMicrosoft.WindowsDriverKitWindows\nDynastreamInnovations.WindowsDriverPackageDynastreamInnovationsANTLibUSBDrivers\nSiliconLabsSoftware.WindowsDriverPackageSiliconLabsSoftwareUSB\nMicrosoft.WindowsSDKAddOn\nMicrosoft.WindowsSoftwareDevelopmentKitWindows\nMicrosoft.WindowsSoftwareDevelopmentKitWindows\nMicrosoft.WindowsSoftwareDevelopmentKitWindows\nWireGuard.WireGuard\nTheWiresharkdevelopercommunitywwwwiresharkorg.Wireshark\nTheWiresharkdevelopercommunitywwwwiresharkorg.Wireshark\nTheWiresharkdevelopercommunitywwwwiresharkorg.Wireshark\nTheWiresharkdevelopercommunitywwwwiresharkorg.Wireshark\nAntibodySoftware.WizFile\nAntibodySoftware.WizKey\nAntibodySoftware.WizMouse\nAntibodySoftware.WizTree\nAntibodySoftware.WizTree\nAutomattic.WordPresscom\nAutomattic.WordPresscom\nAutomattic.WordPresscom\nAutomattic.WordPresscom\nRobCaelersRaymondPenners.Workrave\nWritage.Writage\nX2GoProject.X2GoClientforWindows\nBitnami.XAMPP\nChristianHohnstaedt.XCA\nTheTBOOXOpenSourceGroup.XMakebuildutility\nXMind.XMind\nGougeletPierree.XnView\nGougeletPierree.XnViewMP\nYarnContributors.Yarn\nBeijingYinxiangBijiTechnologies.YinxiangBijiv\nBeijingYinxiangBijiTechnologies.YinxiangBijiv\nBeijingYinxiangBijiTechnologies.YinxiangBijiv\nBeijingYinxiangBijiTechnologies.YinxiangBijiv\nBeijingYinxiangBijiTechnologies.YinxiangBijiv\nAdlerLuiz.YouTubeMusicDesktopApp\nYubico.YubiKeyManager\nZentimocom.ZentimoPRO\nZeroTier.ZeroTierOne\nHendrikErz.Zettlr\nRobinStuartBogDanVatra.Zint\nZoom.Zoom\nZoom.ZoomOutlookPlugin\nCorporationforDigitalScholarship.Zotero\nKandraLabs.Zulip\nSangomaTechnologies.Zulu\nZygorGuides.ZygorClientUninstaller\nBalena.balenaEtcher\nBalena.balenaEtcher\nBalena.balenaEtcher\nBalena.balenaEtcher\nBalena.balenaEtcher\nBalena.balenaEtcher\nBalena.balenaEtcher\nBalena.balenaEtcher\nNathanielJohns.beatdrop\nClementTsang.bottom\nbutterflowuigithub.butterflowui\nKovidGoyal.calibre\nElliottZheng.copytranslator\nthedarktableproject.darktable\ndnGrepCommunityContributors.dnGREP\nJGraph.drawio\nHardcodedSoftware.dupeGuru\neMClient.eMClient\nEbbflowio.ebbflow\nfluxSoftware.flux\nKurataSayuri.ffftp\nwereturtle.ghostwriter\ngnuplotdevelopmentteam.gnuplotpatchlevel8\nStefansTools.grepWin\nDrewNaylor.guinget\nDrewNaylor.guinget\nDrewNaylor.guinget\neVenture.hidemeVPN\neVenture.hidemeVPN\nPurpleI2P.i2pd\nVantageLinguistics.iSEEKAnswerWorksEnglishRuntime\nApple.iTunes\nKDE.kdenlive\nKDE.kdiff3\nNextGenerationSoftware.mRemoteNG\nMaximaTeam.maxima\nFrankSkare.mpvnet\n720kb.ndm\nxiles.nexusfont\nownCloud.ownCloud\nEasternGraphics.pConplannerPRO\nLaurentPRendeCotret.pandocplot\nThepgAdminDevelopmentTeam.pgAdmin4\nThepgAdminDevelopmentTeam.pgAdmin4\nThepgAdminDevelopmentTeam.pgAdmin4\nThepgAdminDevelopmentTeam.pgAdmin4\nTheqBittorrentproject.qBittorrent\nTheqBittorrentproject.qBittorrent\nTheqBittorrentproject.qBittorrent\nremoteit.remoteit\nremoteit.remoteit\nLightbend.sbt\nScilabEnterprises.scilab\nTheSqlectronTeam.sqlectron\nJanHovancik.stretchly\nOliverSchwendener.ueli\nOliverSchwendener.ueli\nOliverSchwendener.ueli\nHumanity.xmoto\nHumanity.xmoto\nMicrosoft.微软设备健康助手\nAlipaycom.支付宝安全控件\n百度在线网络技术有限公司.百度网盘\n腾讯科技有限公司.腾讯QQ\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Shadow/V1_5/ManifestV1_5-Shadow-DefaultLocale.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.5.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-US\nPackageName: MSIX SDK\nLicense: MIT License\nShortDescription: This is MSIX SDK\nDescription: The MSIX SDK project is an effort to enable developers\nPublisher: Microsoft\nManifestType: defaultLocale\nManifestVersion: 1.5.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Shadow/V1_5/ManifestV1_5-Shadow-Installer.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.5.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nInstallerLocale: en-US\nInstallers:\n  - Architecture: x64\n    InstallerType: exe\n    InstallerUrl: https://www.microsoft.com/msixsdk/msixsdkx64.exe\n    InstallerSha256: 69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\n    ProductCode: \"{Bar}\"\n    InstallerSwitches:\n      Custom: /custom\n      SilentWithProgress: /silentwithprogress\n      Silent: /silence\n      Interactive: /interactive\n      Log: /log=<LOGPATH>\n      InstallLocation: /dir=<INSTALLPATH>\n      Upgrade: /upgrade\nManifestType: installer\nManifestVersion: 1.5.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Shadow/V1_5/ManifestV1_5-Shadow-Locale.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.locale.1.5.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: en-GB\nDescription: The MSIX SDK project is an effort to enable developers UK\nManifestType: locale\nManifestVersion: 1.5.0\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Shadow/V1_5/ManifestV1_5-Shadow-Locale2.yaml",
    "content": "# yaml-language-server: $schema=https://aka.ms/winget-manifest.locale.1.5.0.schema.json\n\nPackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nPackageLocale: es-MX\nDescription: The MSIX SDK project is an effort to enable developers MX\nManifestType: locale\nManifestVersion: 1.5.0\nIcons:\n  - IconUrl: https://localeTestIcon-es-MX\n    IconFileType: png\n    IconResolution: 32x32\n    IconTheme: light\n    IconSha256: '4444444444444444444444444444444444444444444444444444444444444444'\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Shadow/V1_5/ManifestV1_5-Shadow-Shadow.yaml",
    "content": "PackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nManifestType: shadow\nManifestVersion: 1.5.0\nPackageLocale: en-US\nIcons:\n  - IconUrl: https://shadowIcon-default\n    IconFileType: ico\n    IconResolution: custom\n    IconTheme: default\n    IconSha256: 1111111111111111111111111111111111111111111111111111111111111111\nLocalization:\n  - PackageLocale: en-gb\n    Icons:\n    - IconUrl: https://shadowIcon-en-GB\n      IconFileType: png\n      IconResolution: 32x32\n      IconTheme: light\n      IconSha256: 2222222222222222222222222222222222222222222222222222222222222222\n  - PackageLocale: fr-FR\n    Icons:\n    - IconUrl: https://shadowIcon-fr-FR\n      IconFileType: jpeg\n      IconResolution: 20x20\n      IconTheme: dark\n      IconSha256: 3333333333333333333333333333333333333333333333333333333333333333"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/Shadow/V1_5/ManifestV1_5-Shadow-Shadow2.yaml",
    "content": "PackageIdentifier: microsoft.msixsdk\nPackageVersion: 1.7.32\nManifestType: shadow\nManifestVersion: 1.5.0\nPackageLocale: en-US\nIcons:\n  - IconUrl: https://shadowIcon-default2\n    IconFileType: ico\n    IconResolution: custom\n    IconTheme: default\n    IconSha256: 1111111111111111111111111111111111111111111111111111111111111111"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/UpdateFlowTest_Exe.yaml",
    "content": "# Same content with InstallFlowTest_Exe.yaml but with higher version\r\nId: AppInstallerCliTest.TestExeInstaller\r\nVersion: 2.0.0.0\r\nName: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nAppMoniker: AICLITestExe\r\nLicense: Test\r\nSwitches:\r\n  Custom: /custom\r\n  SilentWithProgress: /silentwithprogress\r\n  Silent: /silence\r\n  Update: /update\r\nInstallers: \r\n    - Arch: x64\r\n      Url: https://ThisIsNotUsed\r\n      InstallerType: exe\r\n      Sha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/UpdateFlowTest_ExeDependencies.yaml",
    "content": "# Same content with Installer_Exe_Dependencies but with higher version\r\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.0.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestExeInstaller.Dependencies\r\nPackageVersion: 2.0.0.0\r\nPackageName: AppInstaller Test Installer\r\nPackageLocale: en-US\r\nPublisher: Microsoft Corporation\r\nShortDescription: Upgrade exe installer with dependencies\r\nMoniker: AICLITestExe\r\nLicense: Test\r\nInstallerSwitches:\r\n  Custom: /custom\r\n  SilentWithProgress: /silentwithprogress\r\n  Silent: /silence\r\n  Upgrade: /upgrade\r\nInstallers:\r\n    - Architecture: x64\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: exe\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n      Dependencies:\r\n        WindowsFeatures:\r\n          - PreviewIIS\r\n        WindowsLibraries:\r\n          - Preview VC Runtime\r\nManifestType: singleton\r\nManifestVersion: 1.0.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/UpdateFlowTest_Exe_2.yaml",
    "content": "# Same content with UpdateFlowTest_Exe.yaml but with higher version\r\nId: AppInstallerCliTest.TestExeInstaller\r\nVersion: 3.0.0.0\r\nName: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nAppMoniker: AICLITestExe\r\nLicense: Test\r\nSwitches:\r\n  Custom: /custom /ver3.0.0.0\r\n  SilentWithProgress: /silentwithprogress\r\n  Silent: /silence\r\n  Update: /update\r\nInstallers: \r\n    - Arch: x64\r\n      Url: https://ThisIsNotUsed\r\n      InstallerType: exe\r\n      Sha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/UpdateFlowTest_Exe_2_LicenseAgreement.yaml",
    "content": "# Similar content to UpdateFlowTest_Exe_2.yaml but with Agreements\r\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.1.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestExeInstaller\r\nPackageVersion: 3.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExe\r\nLicense: Test\r\nShortDescription: AppInstaller Test Installer\r\nAgreements:\r\n  - AgreementLabel: Agreement for EXE\r\n    Agreement: This is the agreement for the EXE installer.\r\nInstallerSwitches:\r\n  Custom: /custom /ver3.0.0.0\r\n  SilentWithProgress: /silentwithprogress\r\n  Silent: /silence\r\n  Update: /update\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerUrl: https://ThisIsNotUsed\r\n    InstallerType: exe\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestType: singleton\r\nManifestVersion: 1.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/UpdateFlowTest_Exe_ARPInstallerType.yaml",
    "content": "# Similar content to UpdateFlowTest_Exe.yaml, but with an AppsAndFeaturesEntry specifying installer type\r\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.1.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestExeInstaller\r\nPackageVersion: 2.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExe\r\nLicense: Test\r\nShortDescription: AppInstaller Test Installer\r\nAppsAndFeaturesEntries:\r\n  - InstallerType: msix\r\nInstallerSwitches:\r\n  Custom: /custom /ver2.0.0.0\r\n  SilentWithProgress: /silentwithprogress\r\n  Silent: /silence\r\n  Update: /update\r\nInstallers:\r\n  - Architecture: x86\r\n    InstallerUrl: https://ThisIsNotUsed\r\n    InstallerType: exe\r\n    InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestType: singleton\r\nManifestVersion: 1.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/UpdateFlowTest_Exe_UnsupportedArgs.yaml",
    "content": "# Same content with UpdateFlowTest_Exe.yaml but with higher version and UnsupportedArguments\r\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.2.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestExeInstaller\r\nPackageVersion: 2.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nAppMoniker: AICLITestExe\r\nLicense: Test\r\nSwitches:\r\n  Custom: /custom /ver3.0.0.0\r\n  SilentWithProgress: /silentwithprogress\r\n  Silent: /silence\r\n  Update: /update\r\nUnsupportedArguments:\r\n    - log\r\n    - location\r\nShortDescription: AppInstaller Test Exe Installer\r\nInstallers:\r\n    - Architecture: x64\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: exe\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestType: singleton\r\nManifestVersion: 1.2.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/UpdateFlowTest_ExpectedReturnCodes.yaml",
    "content": "# Same content with InstallFlowTest_ExpectedReturnCodes.yaml but with higher version\r\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.2.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.ExpectedReturnCodes\r\nPackageVersion: 2.0.0.0\r\nPackageLocale: en-US\r\nPackageName: TestExeInstallerWithExpectedReturnCodes\r\nShortDescription: AppInstaller Test Installer\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExe\r\nLicense: Test\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: exe\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n      ExpectedReturnCodes:\r\n          - InstallerReturnCode: 1\r\n            ReturnResponse: packageInUse\r\n          - InstallerReturnCode: 2\r\n            ReturnResponse: installInProgress\r\n          - InstallerReturnCode: 3\r\n            ReturnResponse: fileInUse\r\n          - InstallerReturnCode: 4\r\n            ReturnResponse: missingDependency\r\n          - InstallerReturnCode: 5\r\n            ReturnResponse: diskFull\r\n          - InstallerReturnCode: 6\r\n            ReturnResponse: insufficientMemory\r\n          - InstallerReturnCode: 7\r\n            ReturnResponse: noNetwork\r\n          - InstallerReturnCode: 8\r\n            ReturnResponse: contactSupport\r\n            ReturnResponseUrl: https://TestReturnResponseUrl\r\n          - InstallerReturnCode: 9\r\n            ReturnResponse: rebootRequiredToFinish\r\n          - InstallerReturnCode: 10\r\n            ReturnResponse: rebootRequiredForInstall\r\n          - InstallerReturnCode: 11\r\n            ReturnResponse: rebootInitiated\r\n          - InstallerReturnCode: 12\r\n            ReturnResponse: cancelledByUser\r\n          - InstallerReturnCode: 13\r\n            ReturnResponse: alreadyInstalled\r\n          - InstallerReturnCode: 14\r\n            ReturnResponse: downgrade\r\n          - InstallerReturnCode: 15\r\n            ReturnResponse: blockedByPolicy\r\nManifestType: singleton\r\nManifestVersion: 1.2.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/UpdateFlowTest_Msix.yaml",
    "content": "﻿# Same content with InstallFlowTest_Msix_StreamingFlow.yaml but with higher version\r\nId: AppInstallerCliTest.TestMsixInstaller\r\nVersion: 2.0.0.0\r\nName: AppInstaller Test MSIX Installer\r\nPublisher: Microsoft Corporation\r\nAppMoniker: AICLITestMsix\r\nLicense: Test\r\nInstallers: \r\n    - Arch: x64\r\n      Url: https://github.com/microsoft/msix-packaging/blob/master/src/test/testData/unpack/TestAppxPackage_x64.appx?raw=true\r\n      InstallerType: msix\r\n      Sha256: 6a2d3683fa19bf00e58e07d1313d20a5f5735ebbd6a999d33381d28740ee07ea\r\n      SignatureSha256: 138781c3e6f635240353f3d14d1d57bdcb89413e49be63b375e6a5d7b93b0d07\r\n      PackageFamilyName: 20477fca-282d-49fb-b03e-371dca074f0f_8wekyb3d8bbwe\r\nManifestVersion: 0.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/UpdateFlowTest_Msix_LicenseAgreement.yaml",
    "content": "# Similar content to UpdateFlowTest_Msix.yaml but with Agreements\r\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.1.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestMsixInstaller\r\nPackageVersion: 2.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test MSIX Installer\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestExe\r\nLicense: Test\r\nAgreements:\r\n  - AgreementLabel: Agreement for MSIX\r\n    Agreement: This is the agreement for the MSIX installer.\r\nShortDescription: AppInstaller Test MSIX Installer\r\nInstallers:\r\n  - Architecture: x64\r\n    InstallerUrl: https://github.com/microsoft/msix-packaging/blob/master/src/test/testData/unpack/TestAppxPackage_x64.appx?raw=true\r\n    InstallerType: msix\r\n    InstallerSha256: 6a2d3683fa19bf00e58e07d1313d20a5f5735ebbd6a999d33381d28740ee07ea\r\n    SignatureSha256: 138781c3e6f635240353f3d14d1d57bdcb89413e49be63b375e6a5d7b93b0d07\r\n    PackageFamilyName: 20477fca-282d-49fb-b03e-371dca074f0f_8wekyb3d8bbwe\r\nManifestType: singleton\r\nManifestVersion: 1.1.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/UpdateFlowTest_Portable.yaml",
    "content": "# Same content with InstallFlowTest_Portable.yaml but with higher version\r\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.2.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestPortableInstaller\r\nPackageVersion: 2.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Portable Exe\r\nPublisher: Microsoft Corporation\r\nAppMoniker: AICLITestPortable\r\nProductCode: AppInstallerCliTest.TestPortableInstaller__TestSource\r\nLicense: Test\r\nShortDescription: AppInstaller Test Portable Exe\r\nInstallers:\r\n    - Architecture: x64\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: portable\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\nManifestType: singleton\r\nManifestVersion: 1.2.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestData/UpdateFlowTest_Zip_Exe.yaml",
    "content": "# Same content with InstallFlowTest_ZipWithExe.yaml but with higher version\r\n# yaml-language-server: $schema=https://aka.ms/winget-manifest.singleton.1.4.0.schema.json\r\n\r\nPackageIdentifier: AppInstallerCliTest.TestZipInstaller\r\nPackageVersion: 2.0.0.0\r\nPackageLocale: en-US\r\nPackageName: AppInstaller Test Zip Installer\r\nShortDescription: AppInstaller Test Zip Installer with exe\r\nPublisher: Microsoft Corporation\r\nMoniker: AICLITestZip\r\nLicense: Test\r\nInstallers:\r\n    - Architecture: x86\r\n      InstallerUrl: https://ThisIsNotUsed\r\n      InstallerType: zip\r\n      InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B\r\n      NestedInstallerType: exe\r\n      NestedInstallerFiles:\r\n        - RelativeFilePath: relativeFilePath\r\n      InstallerSwitches:\r\n        Custom: /custom /ver2.0.0.0\r\n        SilentWithProgress: /silentwithprogress\r\n        Silent: /silence\r\n        Update: /update\r\nManifestType: singleton\r\nManifestVersion: 1.4.0\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestHooks.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"TestSettings.h\"\r\n\r\n#include <SourceFactory.h>\r\n#include <filesystem>\r\n#include <functional>\r\n#include <memory>\r\n#include <string>\r\n\r\n#include <AppInstallerTelemetry.h>\r\n#include <AppInstallerRuntime.h>\r\n#include <AppInstallerDownloader.h>\r\n#include <winget/UserSettings.h>\r\n#include <winget/ExperimentalFeature.h>\r\n#include <winget/Filesystem.h>\r\n#include <winget/IconExtraction.h>\r\n#include <winget/Authentication.h>\r\n#include <winget/HttpClientHelper.h>\r\n#include <sfsclient/SFSClient.h>\r\n\r\n#ifdef AICLI_DISABLE_TEST_HOOKS\r\nstatic_assert(false, \"Test hooks have been disabled\");\r\n#endif\r\n\r\nnamespace AppInstaller\r\n{\r\n    // Don't forget to clear the overrides after use!\r\n    // A good way is to create a helper struct that cleans when destroyed\r\n\r\n    namespace Runtime\r\n    {\r\n        void TestHook_SetPathOverride(PathName target, const std::filesystem::path& path);\r\n        void TestHook_SetPathOverride(PathName target, const Filesystem::PathDetails& details);\r\n        void TestHook_ClearPathOverrides();\r\n    }\r\n\r\n    namespace Repository\r\n    {\r\n        void TestHook_SetSourceFactoryOverride(const std::string& type, std::function<std::unique_ptr<ISourceFactory>()>&& factory);\r\n        void TestHook_ClearSourceFactoryOverrides();\r\n        void TestHook_SetExtractIconFromArpEntryResult_Override(std::vector<AppInstaller::Repository::ExtractedIconInfo>* result);\r\n    }\r\n\r\n    namespace Repository::Microsoft\r\n    {\r\n        void TestHook_SetPinningIndex_Override(std::optional<std::filesystem::path>&& indexPath);\r\n\r\n        using GetARPKeyFunc = std::function<Registry::Key(Manifest::ScopeEnum, Utility::Architecture)>;\r\n        void SetGetARPKeyOverride(GetARPKeyFunc value);\r\n\r\n        using GetFontRegistryRootFunc = std::function<Registry::Key(Manifest::ScopeEnum)>;\r\n        void TestHook_SetGetFontRegistryRootFunc(GetFontRegistryRootFunc value);\r\n    }\r\n\r\n    namespace Logging\r\n    {\r\n        void TestHook_SetTelemetryOverride(std::shared_ptr<TelemetryTraceLogger> ttl);\r\n    }\r\n\r\n    namespace Settings\r\n    {\r\n        void SetUserSettingsOverride(UserSettings* value);\r\n        void SetExperimentalFeatureOverride(const std::map<ExperimentalFeature::Feature, bool>* override);\r\n    }\r\n\r\n    namespace Filesystem\r\n    {\r\n        void TestHook_SetCreateSymlinkResult_Override(bool* status);\r\n    }\r\n\r\n    namespace Archive\r\n    {\r\n        void TestHook_SetScanArchiveResult_Override(bool* status);\r\n    }\r\n\r\n    namespace CLI::Workflow\r\n    {\r\n        void TestHook_SetEnableWindowsFeatureResult_Override(std::optional<DWORD>&& result);\r\n        void TestHook_SetDoesWindowsFeatureExistResult_Override(std::optional<DWORD>&& result);\r\n        void TestHook_SetExtractArchiveWithTarResult_Override(std::optional<DWORD>&& result);\r\n    }\r\n\r\n    namespace Reboot\r\n    {\r\n        void TestHook_SetInitiateRebootResult_Override(bool* status);\r\n        void TestHook_SetRegisterForRestartResult_Override(bool* status);\r\n    }\r\n\r\n    namespace Authentication\r\n    {\r\n        void TestHook_SetAuthenticationResult_Override(Authentication::AuthenticationResult* authResult);\r\n    }\r\n\r\n    namespace MSStore::TestHooks\r\n    {\r\n        void SetDisplayCatalogHttpPipelineStage_Override(std::shared_ptr<web::http::http_pipeline_stage> value);\r\n\r\n        void SetSfsClientAppContents_Override(std::function<std::vector<SFS::AppContent>(std::string_view)>* value);\r\n\r\n        void SetLicensingHttpPipelineStage_Override(std::shared_ptr<web::http::http_pipeline_stage> value);\r\n    }\r\n\r\n    namespace Utility::TestHooks\r\n    {\r\n        void SetDownloadResult_Function_Override(std::function<DownloadResult(\r\n            const std::string& url,\r\n            const std::filesystem::path& dest,\r\n            DownloadType type,\r\n            IProgressCallback& progress,\r\n            std::optional<DownloadInfo> info)>* value);\r\n    }\r\n}\r\n\r\nnamespace TestHook\r\n{\r\n    struct SetCreateSymlinkResult_Override\r\n    {\r\n        SetCreateSymlinkResult_Override(bool status) : m_status(status)\r\n        {\r\n            AppInstaller::Filesystem::TestHook_SetCreateSymlinkResult_Override(&m_status);\r\n        }\r\n\r\n        ~SetCreateSymlinkResult_Override()\r\n        {\r\n            AppInstaller::Filesystem::TestHook_SetCreateSymlinkResult_Override(nullptr);\r\n        }\r\n\r\n    private:\r\n        bool m_status;\r\n    };\r\n\r\n    struct SetScanArchiveResult_Override\r\n    {\r\n        SetScanArchiveResult_Override(bool status) : m_status(status)\r\n        {\r\n            AppInstaller::Archive::TestHook_SetScanArchiveResult_Override(&m_status);\r\n        }\r\n\r\n        ~SetScanArchiveResult_Override()\r\n        {\r\n            AppInstaller::Archive::TestHook_SetScanArchiveResult_Override(nullptr);\r\n        }\r\n\r\n    private:\r\n        bool m_status;\r\n    };\r\n\r\n    struct SetPinningIndex_Override\r\n    {\r\n        SetPinningIndex_Override(const std::filesystem::path& indexPath)\r\n        {\r\n            AppInstaller::Repository::Microsoft::TestHook_SetPinningIndex_Override(indexPath);\r\n        }\r\n\r\n        ~SetPinningIndex_Override()\r\n        {\r\n            AppInstaller::Repository::Microsoft::TestHook_SetPinningIndex_Override({});\r\n        }\r\n    };\r\n\r\n    struct SetExtractIconFromArpEntryResult_Override\r\n    {\r\n        SetExtractIconFromArpEntryResult_Override(std::vector<AppInstaller::Repository::ExtractedIconInfo> extractedIcons) : m_extractedIcons(std::move(extractedIcons))\r\n        {\r\n            AppInstaller::Repository::TestHook_SetExtractIconFromArpEntryResult_Override(&m_extractedIcons);\r\n        }\r\n\r\n        ~SetExtractIconFromArpEntryResult_Override()\r\n        {\r\n            AppInstaller::Repository::TestHook_SetExtractIconFromArpEntryResult_Override(nullptr);\r\n        }\r\n\r\n    private:\r\n        std::vector<AppInstaller::Repository::ExtractedIconInfo> m_extractedIcons;\r\n    };\r\n\r\n    struct SetEnableWindowsFeatureResult_Override\r\n    {\r\n        SetEnableWindowsFeatureResult_Override(DWORD result)\r\n        {\r\n            AppInstaller::CLI::Workflow::TestHook_SetEnableWindowsFeatureResult_Override(result);\r\n        }\r\n\r\n        ~SetEnableWindowsFeatureResult_Override()\r\n        {\r\n            AppInstaller::CLI::Workflow::TestHook_SetEnableWindowsFeatureResult_Override({});\r\n        }\r\n    };\r\n\r\n    struct SetDoesWindowsFeatureExistResult_Override\r\n    {\r\n        SetDoesWindowsFeatureExistResult_Override(DWORD result)\r\n        {\r\n            AppInstaller::CLI::Workflow::TestHook_SetDoesWindowsFeatureExistResult_Override(result);\r\n        }\r\n\r\n        ~SetDoesWindowsFeatureExistResult_Override()\r\n        {\r\n            AppInstaller::CLI::Workflow::TestHook_SetDoesWindowsFeatureExistResult_Override({});\r\n        }\r\n    };\r\n\r\n    struct SetExtractArchiveWithTarResult_Override\r\n    {\r\n        SetExtractArchiveWithTarResult_Override(DWORD result)\r\n        {\r\n            AppInstaller::CLI::Workflow::TestHook_SetExtractArchiveWithTarResult_Override(result);\r\n        }\r\n\r\n        ~SetExtractArchiveWithTarResult_Override()\r\n        {\r\n            AppInstaller::CLI::Workflow::TestHook_SetExtractArchiveWithTarResult_Override({});\r\n        }\r\n    };\r\n\r\n    struct SetInitiateRebootResult_Override\r\n    {\r\n        SetInitiateRebootResult_Override(bool status) : m_status(status)\r\n        {\r\n            AppInstaller::Reboot::TestHook_SetInitiateRebootResult_Override(&m_status);\r\n        }\r\n\r\n        ~SetInitiateRebootResult_Override()\r\n        {\r\n            AppInstaller::Reboot::TestHook_SetInitiateRebootResult_Override(nullptr);\r\n        }\r\n\r\n    private:\r\n        bool m_status;\r\n    };\r\n\r\n    struct SetGetARPKey_Override\r\n    {\r\n        SetGetARPKey_Override(std::function<AppInstaller::Registry::Key(AppInstaller::Manifest::ScopeEnum, AppInstaller::Utility::Architecture)> function)\r\n        {\r\n            AppInstaller::Repository::Microsoft::SetGetARPKeyOverride(function);\r\n        }\r\n\r\n        ~SetGetARPKey_Override()\r\n        {\r\n            AppInstaller::Repository::Microsoft::SetGetARPKeyOverride({});\r\n        }\r\n\r\n    private:\r\n    };\r\n\r\n    struct SetRegisterForRestartResult_Override\r\n    {\r\n        SetRegisterForRestartResult_Override(bool status) : m_status(status)\r\n        {\r\n            AppInstaller::Reboot::TestHook_SetRegisterForRestartResult_Override(&m_status);\r\n        }\r\n\r\n        ~SetRegisterForRestartResult_Override()\r\n        {\r\n            AppInstaller::Reboot::TestHook_SetRegisterForRestartResult_Override(nullptr);\r\n        }\r\n\r\n    private:\r\n        bool m_status;\r\n    };\r\n\r\n    struct SetAuthenticationResult_Override\r\n    {\r\n        SetAuthenticationResult_Override(AppInstaller::Authentication::AuthenticationResult authResult) : m_authResult(authResult)\r\n        {\r\n            AppInstaller::Authentication::TestHook_SetAuthenticationResult_Override(&m_authResult);\r\n        }\r\n\r\n        ~SetAuthenticationResult_Override()\r\n        {\r\n            AppInstaller::Authentication::TestHook_SetAuthenticationResult_Override(nullptr);\r\n        }\r\n\r\n    private:\r\n        AppInstaller::Authentication::AuthenticationResult m_authResult;\r\n    };\r\n\r\n    struct SetDisplayCatalogHttpPipelineStage_Override\r\n    {\r\n        SetDisplayCatalogHttpPipelineStage_Override(std::shared_ptr<web::http::http_pipeline_stage> value)\r\n        {\r\n            AppInstaller::MSStore::TestHooks::SetDisplayCatalogHttpPipelineStage_Override(value);\r\n        }\r\n\r\n        ~SetDisplayCatalogHttpPipelineStage_Override()\r\n        {\r\n            AppInstaller::MSStore::TestHooks::SetDisplayCatalogHttpPipelineStage_Override(nullptr);\r\n        }\r\n    };\r\n\r\n    struct SetSfsClientAppContents_Override\r\n    {\r\n        SetSfsClientAppContents_Override(std::function<std::vector<SFS::AppContent>(std::string_view)> value) : m_appContentsFunction(std::move(value))\r\n        {\r\n            AppInstaller::MSStore::TestHooks::SetSfsClientAppContents_Override(&m_appContentsFunction);\r\n        }\r\n\r\n        ~SetSfsClientAppContents_Override()\r\n        {\r\n            AppInstaller::MSStore::TestHooks::SetSfsClientAppContents_Override(nullptr);\r\n        }\r\n\r\n    private:\r\n        std::function<std::vector<SFS::AppContent>(std::string_view)> m_appContentsFunction;\r\n    };\r\n\r\n    struct SetLicensingHttpPipelineStage_Override\r\n    {\r\n        SetLicensingHttpPipelineStage_Override(std::shared_ptr<web::http::http_pipeline_stage> value)\r\n        {\r\n            AppInstaller::MSStore::TestHooks::SetLicensingHttpPipelineStage_Override(value);\r\n        }\r\n\r\n        ~SetLicensingHttpPipelineStage_Override()\r\n        {\r\n            AppInstaller::MSStore::TestHooks::SetLicensingHttpPipelineStage_Override(nullptr);\r\n        }\r\n    };\r\n\r\n    struct SetDownloadResult_Function_Override\r\n    {\r\n        SetDownloadResult_Function_Override(std::function<AppInstaller::Utility::DownloadResult(\r\n            const std::string& url,\r\n            const std::filesystem::path& dest,\r\n            AppInstaller::Utility::DownloadType type,\r\n            AppInstaller::IProgressCallback& progress,\r\n            std::optional<AppInstaller::Utility::DownloadInfo> info)> value) : m_downloadFunction(std::move(value))\r\n        {\r\n            AppInstaller::Utility::TestHooks::SetDownloadResult_Function_Override(&m_downloadFunction);\r\n        }\r\n\r\n        ~SetDownloadResult_Function_Override()\r\n        {\r\n            AppInstaller::Utility::TestHooks::SetDownloadResult_Function_Override(nullptr);\r\n        }\r\n\r\n    private:\r\n        std::function<AppInstaller::Utility::DownloadResult(\r\n            const std::string& url,\r\n            const std::filesystem::path& dest,\r\n            AppInstaller::Utility::DownloadType type,\r\n            AppInstaller::IProgressCallback& progress,\r\n            std::optional<AppInstaller::Utility::DownloadInfo> info)> m_downloadFunction;\r\n    };\r\n\r\n    struct SetGetFontRegistryRoot_Override\r\n    {\r\n        SetGetFontRegistryRoot_Override(std::function<AppInstaller::Registry::Key(AppInstaller::Manifest::ScopeEnum)> function)\r\n        {\r\n            AppInstaller::Repository::Microsoft::TestHook_SetGetFontRegistryRootFunc(function);\r\n        }\r\n\r\n        ~SetGetFontRegistryRoot_Override()\r\n        {\r\n            AppInstaller::Repository::Microsoft::TestHook_SetGetFontRegistryRootFunc({});\r\n        }\r\n\r\n    private:\r\n    };\r\n\r\n    struct SetUserSettings_Override\r\n    {\r\n        SetUserSettings_Override(AppInstaller::Settings::UserSettings& settings)\r\n        {\r\n            AppInstaller::Settings::SetUserSettingsOverride(&settings);\r\n        }\r\n\r\n        ~SetUserSettings_Override()\r\n        {\r\n            AppInstaller::Settings::SetUserSettingsOverride(nullptr);\r\n        }\r\n    };\r\n\r\n    struct SetSingleExperimentalFeature_Override\r\n    {\r\n        SetSingleExperimentalFeature_Override(AppInstaller::Settings::ExperimentalFeature::Feature feature)\r\n        {\r\n            m_overrides[feature] = true;\r\n            AppInstaller::Settings::SetExperimentalFeatureOverride(&m_overrides);\r\n        }\r\n\r\n        ~SetSingleExperimentalFeature_Override()\r\n        {\r\n            AppInstaller::Settings::SetExperimentalFeatureOverride(nullptr);\r\n        }\r\n\r\n    private:\r\n        std::map<AppInstaller::Settings::ExperimentalFeature::Feature, bool> m_overrides;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestRestRequestHandler.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestRestRequestHandler.h\"\r\n#include <Rest/Schema/1_0/Interface.h>\r\n#include <Rest/Schema/IRestClient.h>\r\n\r\nstd::shared_ptr<TestRestRequestHandler> GetTestRestRequestHandler(\r\n    const web::http::status_code statusCode, const utility::string_t& sampleResponseString, const utility::string_t& mimeType)\r\n{\r\n    return std::make_shared<TestRestRequestHandler>([statusCode, sampleResponseString, mimeType](web::http::http_request) ->\r\n        pplx::task<web::http::http_response>\r\n        {\r\n            web::http::http_response response;\r\n            if (sampleResponseString.empty())\r\n            {\r\n                response.set_body(utf16string{});\r\n            }\r\n            else\r\n            {\r\n                response.set_body(web::json::value::parse(sampleResponseString));\r\n            }\r\n\r\n            response.headers().set_content_type(mimeType);\r\n            response.headers().set_cache_control(L\"no-store\");\r\n            response.set_status_code(statusCode);\r\n            return pplx::task_from_result(response);\r\n        });\r\n}\r\n\r\nstd::shared_ptr<TestRestRequestHandler> GetTestRestRequestHandler(\r\n    std::function<web::http::status_code(const web::http::http_request& request)> handler)\r\n{\r\n    return std::make_shared<TestRestRequestHandler>([handler = std::move(handler)](web::http::http_request request) ->\r\n        pplx::task<web::http::http_response>\r\n        {\r\n            web::http::http_response response;\r\n            response.set_body(utf16string{});\r\n\r\n            response.headers().set_content_type(web::http::details::mime_types::application_json);\r\n            response.headers().set_cache_control(L\"no-store\");\r\n            response.set_status_code(handler(request));\r\n            return pplx::task_from_result(response);\r\n        });\r\n}\r\n\r\nstd::shared_ptr<TestRestRequestHandler> GetHeaderVerificationHandler(\r\n    const web::http::status_code statusCode, const utility::string_t& sampleResponseString, const std::pair<utility::string_t, utility::string_t>& header, web::http::status_code statusCodeOnFailure)\r\n{\r\n    return std::make_shared<TestRestRequestHandler>([statusCode, sampleResponseString, header, statusCodeOnFailure](web::http::http_request request) ->\r\n        pplx::task<web::http::http_response>\r\n        {\r\n            web::http::http_response response;\r\n            auto& headers = request.headers();\r\n            if (!headers.has(header.first) ||\r\n                (utility::conversions::to_utf8string(header.second).compare(utility::conversions::to_utf8string(headers[header.first]))) != 0)\r\n            {\r\n                response.set_body(utf16string{ L\"Expected header not found\" });\r\n                response.set_status_code(statusCodeOnFailure);\r\n                return pplx::task_from_result(response);\r\n            }\r\n\r\n            if (!sampleResponseString.empty())\r\n            {\r\n                response.set_body(web::json::value::parse(sampleResponseString));\r\n            }\r\n\r\n            response.headers().set_content_type(web::http::details::mime_types::application_json);\r\n            response.headers().set_cache_control(L\"no-store\");\r\n            response.set_status_code(statusCode);\r\n            return pplx::task_from_result(response);\r\n        });\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestRestRequestHandler.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <cpprest/http_client.h>\r\n\r\nclass TestRestRequestHandler : public web::http::http_pipeline_stage\r\n{\r\npublic:\r\n    TestRestRequestHandler(const std::function<pplx::task<web::http::http_response>(web::http::http_request request)>& handler) : m_handler(handler) {}\r\n\r\n    virtual pplx::task<web::http::http_response> propagate(web::http::http_request request)\r\n    {\r\n        return m_handler(request);\r\n    }\r\n\r\nprivate:\r\n    std::function<pplx::task<web::http::http_response>(web::http::http_request request)> m_handler;\r\n};\r\n\r\nstd::shared_ptr<TestRestRequestHandler> GetTestRestRequestHandler(\r\n    const web::http::status_code statusCode, const utility::string_t& sampleResponseString = {}, const utility::string_t& mimeType = web::http::details::mime_types::application_json);\r\n\r\nstd::shared_ptr<TestRestRequestHandler> GetTestRestRequestHandler(\r\n    std::function<web::http::status_code(const web::http::http_request& request)> handler);\r\n\r\nstd::shared_ptr<TestRestRequestHandler> GetHeaderVerificationHandler(\r\n    const web::http::status_code statusCode, const utility::string_t& sampleResponseString, const std::pair<utility::string_t, utility::string_t>& header, web::http::status_code statusCodeOnFailure = web::http::status_codes::BadRequest);\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestSettings.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestSettings.h\"\r\n#include <winget/Settings.h>\r\n\r\nusing namespace AppInstaller::Settings;\r\n\r\nnamespace TestCommon\r\n{\r\n    namespace\r\n    {\r\n        void DeleteUserSettingsFilesInternal()\r\n        {\r\n            auto settingsPath = UserSettings::SettingsFilePath();\r\n            if (std::filesystem::exists(settingsPath))\r\n            {\r\n                std::filesystem::remove(settingsPath);\r\n            }\r\n\r\n            auto settingsBackupPath = GetPathTo(Stream::BackupUserSettings);\r\n            if (std::filesystem::exists(settingsBackupPath))\r\n            {\r\n                std::filesystem::remove(settingsBackupPath);\r\n            }\r\n        }\r\n    }\r\n\r\n    void SetSetting(const AppInstaller::Settings::StreamDefinition& stream, std::string_view value)\r\n    {\r\n        REQUIRE(Stream{ stream }.Set(value));\r\n    }\r\n\r\n    void RemoveSetting(const AppInstaller::Settings::StreamDefinition& stream)\r\n    {\r\n        Stream{ stream }.Remove();\r\n    }\r\n\r\n    std::filesystem::path GetPathTo(const AppInstaller::Settings::StreamDefinition& stream)\r\n    {\r\n        return Stream{ stream }.GetPath();\r\n    }\r\n\r\n    UserSettingsFileGuard::UserSettingsFileGuard()\r\n    {\r\n        DeleteUserSettingsFilesInternal();\r\n    }\r\n\r\n    UserSettingsFileGuard::~UserSettingsFileGuard()\r\n    {\r\n        DeleteUserSettingsFilesInternal();\r\n    }\r\n\r\n    [[nodiscard]] UserSettingsFileGuard DeleteUserSettingsFiles()\r\n    {\r\n        return {};\r\n    }\r\n\r\n    GroupPolicyTestOverride::GroupPolicyTestOverride(const AppInstaller::Registry::Key& key) : GroupPolicy(key)\r\n    {\r\n        GroupPolicy::OverrideInstance(this);\r\n    }\r\n\r\n    GroupPolicyTestOverride::~GroupPolicyTestOverride()\r\n    {\r\n        GroupPolicy::ResetInstance();\r\n    }\r\n\r\n    void GroupPolicyTestOverride::SetState(TogglePolicy::Policy policy, PolicyState state)\r\n    {\r\n        m_toggles[policy] = state;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestSettings.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"TestCommon.h\"\r\n#include <winget/Settings.h>\r\n#include <winget/UserSettings.h>\r\n#include <wil/resource.h>\r\n#include <string>\r\n\r\nnamespace TestCommon\r\n{\r\n    // Repeat the policy values here so we can catch unintended changes in the source.\r\n    const std::wstring WinGetPolicyValueName = L\"EnableAppInstaller\";\r\n    const std::wstring WinGetSettingsPolicyValueName = L\"EnableSettings\";\r\n    const std::wstring ExperimentalFeaturesPolicyValueName = L\"EnableExperimentalFeatures\";\r\n    const std::wstring LocalManifestsPolicyValueName = L\"EnableLocalManifestFiles\";\r\n    const std::wstring EnableHashOverridePolicyValueName = L\"EnableHashOverride\";\r\n    const std::wstring EnableLocalArchiveMalwareScanOverridePolicyValueName = L\"EnableLocalArchiveMalwareScanOverride\";\r\n    const std::wstring DefaultSourcePolicyValueName = L\"EnableDefaultSource\";\r\n    const std::wstring MSStoreSourcePolicyValueName = L\"EnableMicrosoftStoreSource\";\r\n    const std::wstring FontSourcePolicyValueName = L\"EnableFontSource\";\r\n    const std::wstring AdditionalSourcesPolicyValueName = L\"EnableAdditionalSources\";\r\n    const std::wstring AllowedSourcesPolicyValueName = L\"EnableAllowedSources\";\r\n    const std::wstring BypassCertificatePinningForMicrosoftStoreValueName = L\"EnableBypassCertificatePinningForMicrosoftStore\";\r\n    const std::wstring EnableWindowsPackageManagerCommandLineInterfaces = L\"EnableWindowsPackageManagerCommandLineInterfaces\";\r\n    const std::wstring ConfigurationPolicyValueName = L\"EnableWindowsPackageManagerConfiguration\";\r\n    const std::wstring ProxyCommandLineOptionsPolicyValueName = L\"EnableWindowsPackageManagerProxyCommandLineOptions\";\r\n    const std::wstring McpServerValueName = L\"EnableWindowsPackageManagerMcpServer\";\r\n\r\n    const std::wstring SourceUpdateIntervalPolicyValueName = L\"SourceAutoUpdateInterval\";\r\n    const std::wstring SourceUpdateIntervalPolicyOldValueName = L\"SourceAutoUpdateIntervalInMinutes\";\r\n\r\n    const std::wstring AdditionalSourcesPolicyKeyName = L\"AdditionalSources\";\r\n    const std::wstring AllowedSourcesPolicyKeyName = L\"AllowedSources\";\r\n\r\n    void SetSetting(const AppInstaller::Settings::StreamDefinition& stream, std::string_view value);\r\n    void RemoveSetting(const AppInstaller::Settings::StreamDefinition& stream);\r\n    std::filesystem::path GetPathTo(const AppInstaller::Settings::StreamDefinition& stream);\r\n\r\n    // This type removes the settings file on creation and destruction to ensure that a test that modifies them can do so cleanly.\r\n    struct UserSettingsFileGuard\r\n    {\r\n        UserSettingsFileGuard();\r\n        ~UserSettingsFileGuard();\r\n    };\r\n\r\n    [[nodiscard]] UserSettingsFileGuard DeleteUserSettingsFiles();\r\n\r\n    struct UserSettingsTest : AppInstaller::Settings::UserSettings\r\n    {\r\n    };\r\n\r\n    struct GroupPolicyTestOverride : AppInstaller::Settings::GroupPolicy\r\n    {\r\n        GroupPolicyTestOverride() : GroupPolicyTestOverride(RegCreateVolatileTestRoot().get()) {}\r\n        GroupPolicyTestOverride(const AppInstaller::Registry::Key& key);\r\n        ~GroupPolicyTestOverride();\r\n\r\n        template<AppInstaller::Settings::ValuePolicy P>\r\n        void SetValue(const ValueType<P>& value)\r\n        {\r\n            m_values.Add<P>(value);\r\n        }\r\n\r\n        template<AppInstaller::Settings::ValuePolicy P>\r\n        void SetValue(ValueType<P> &&value)\r\n        {\r\n            m_values.Add<P>(std::move(value));\r\n        }\r\n\r\n        void SetState(AppInstaller::Settings::TogglePolicy::Policy policy, AppInstaller::Settings::PolicyState state);\r\n    };\r\n\r\n    // Matcher that lets us verify GroupPolicyExceptions.\r\n    struct GroupPolicyExceptionMatcher : public Catch::Matchers::MatcherBase<AppInstaller::Settings::GroupPolicyException>\r\n    {\r\n        GroupPolicyExceptionMatcher(AppInstaller::Settings::TogglePolicy::Policy policy) : m_expectedPolicy(policy) {}\r\n\r\n        bool match(const AppInstaller::Settings::GroupPolicyException& e) const override\r\n        {\r\n            return e.Policy() == m_expectedPolicy;\r\n        }\r\n\r\n        std::string describe() const override\r\n        {\r\n            std::ostringstream result;\r\n            result << \"has policy == \" << m_expectedPolicy;\r\n            return result.str();\r\n        }\r\n\r\n    private:\r\n        AppInstaller::Settings::TogglePolicy::Policy m_expectedPolicy;\r\n    };\r\n\r\n#define REQUIRE_POLICY_EXCEPTION(_expr_, _policy_)     REQUIRE_THROWS_MATCHES(_expr_, AppInstaller::Settings::GroupPolicyException, TestCommon::GroupPolicyExceptionMatcher(_policy_))\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestSource.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestSource.h\"\r\n\r\nusing namespace AppInstaller;\r\nusing namespace AppInstaller::Repository;\r\n\r\nnamespace TestCommon\r\n{\r\n    namespace\r\n    {\r\n        size_t GetNextTestPackageId()\r\n        {\r\n            static std::atomic_size_t packageId(0);\r\n            return ++packageId;\r\n        }\r\n\r\n        TestSource* GetTestSourceFromWeakPtr(const std::weak_ptr<const ISource>& weakSource)\r\n        {\r\n            if (auto source = weakSource.lock())\r\n            {\r\n                if (auto testSource = const_cast<ISource*>(source.get())->CastTo(TestSource::SourceType))\r\n                {\r\n                    return reinterpret_cast<TestSource*>(testSource);\r\n                }\r\n            }\r\n\r\n            return nullptr;\r\n        }\r\n    }\r\n\r\n    TestPackageVersion::TestPackageVersion(const Manifest& manifest, MetadataMap installationMetadata, std::weak_ptr<const ISource> source) :\r\n        VersionManifest(manifest), Metadata(std::move(installationMetadata)), Source(source) {}\r\n\r\n    TestPackageVersion::TestPackageVersion(const Manifest& manifest, std::weak_ptr<const ISource> source, bool hideSystemReferenceStrings) :\r\n        VersionManifest(manifest), Source(source), HideSystemReferenceStrings(hideSystemReferenceStrings) {}\r\n\r\n    TestPackageVersion::LocIndString TestPackageVersion::GetProperty(PackageVersionProperty property) const\r\n    {\r\n        switch (property)\r\n        {\r\n        case PackageVersionProperty::Id:\r\n            return LocIndString{ VersionManifest.Id };\r\n        case PackageVersionProperty::Name:\r\n            return LocIndString{ VersionManifest.DefaultLocalization.Get<AppInstaller::Manifest::Localization::PackageName>() };\r\n        case PackageVersionProperty::Version:\r\n            return LocIndString{ VersionManifest.Version };\r\n        case PackageVersionProperty::Channel:\r\n            return LocIndString{ VersionManifest.Channel };\r\n        case PackageVersionProperty::SourceIdentifier:\r\n            return LocIndString{ Source.lock()->GetIdentifier() };\r\n        case PackageVersionProperty::Publisher:\r\n            return LocIndString{ VersionManifest.DefaultLocalization.Get<AppInstaller::Manifest::Localization::Publisher>() };\r\n        case PackageVersionProperty::ArpMinVersion:\r\n            return LocIndString{ VersionManifest.GetArpVersionRange().IsEmpty() ? \"\" : VersionManifest.GetArpVersionRange().GetMinVersion().ToString() };\r\n        case PackageVersionProperty::ArpMaxVersion:\r\n            return LocIndString{ VersionManifest.GetArpVersionRange().IsEmpty() ? \"\" : VersionManifest.GetArpVersionRange().GetMaxVersion().ToString() };\r\n        case PackageVersionProperty::Moniker:\r\n            return LocIndString{ VersionManifest.Moniker };\r\n        default:\r\n            return {};\r\n        }\r\n    }\r\n\r\n    std::vector<TestPackageVersion::LocIndString> TestPackageVersion::GetMultiProperty(PackageVersionMultiProperty property) const\r\n    {\r\n        std::vector<LocIndString> result;\r\n\r\n        switch (property)\r\n        {\r\n        case PackageVersionMultiProperty::PackageFamilyName:\r\n            if (!HideSystemReferenceStrings)\r\n            {\r\n                for (const auto& installer : VersionManifest.Installers)\r\n                {\r\n                    AddIfHasValueAndNotPresent(installer.PackageFamilyName, result, true);\r\n                }\r\n            }\r\n            break;\r\n        case PackageVersionMultiProperty::ProductCode:\r\n            if (!HideSystemReferenceStrings)\r\n            {\r\n                for (const auto& installer : VersionManifest.Installers)\r\n                {\r\n                    bool shouldFoldCaseForNonPortable = installer.EffectiveInstallerType() != AppInstaller::Manifest::InstallerTypeEnum::Portable;\r\n                    AddIfHasValueAndNotPresent(installer.ProductCode, result, shouldFoldCaseForNonPortable);\r\n                }\r\n            }\r\n            break;\r\n        case PackageVersionMultiProperty::Name:\r\n            for (auto name : VersionManifest.GetPackageNames())\r\n            {\r\n                result.emplace_back(std::move(name));\r\n            }\r\n            break;\r\n        case PackageVersionMultiProperty::Publisher:\r\n            for (auto publisher : VersionManifest.GetPublishers())\r\n            {\r\n                result.emplace_back(std::move(publisher));\r\n            }\r\n            break;\r\n        case PackageVersionMultiProperty::Locale:\r\n            result.emplace_back(VersionManifest.DefaultLocalization.Locale);\r\n            for (const auto& loc : VersionManifest.Localizations)\r\n            {\r\n                result.emplace_back(loc.Locale);\r\n            }\r\n            break;\r\n        case PackageVersionMultiProperty::Command:\r\n            for (auto value : VersionManifest.GetAggregatedCommands())\r\n            {\r\n                result.emplace_back(std::move(value));\r\n            }\r\n            break;\r\n        case PackageVersionMultiProperty::Tag:\r\n            for (auto value : VersionManifest.GetAggregatedTags())\r\n            {\r\n                result.emplace_back(std::move(value));\r\n            }\r\n            break;\r\n        case PackageVersionMultiProperty::UpgradeCode:\r\n            if (!HideSystemReferenceStrings)\r\n            {\r\n                for (const auto& installer : VersionManifest.Installers)\r\n                {\r\n                    bool shouldFoldCaseForNonPortable = installer.EffectiveInstallerType() != AppInstaller::Manifest::InstallerTypeEnum::Portable;\r\n                    for (const auto& entry : installer.AppsAndFeaturesEntries)\r\n                    {\r\n                        AddIfHasValueAndNotPresent(entry.UpgradeCode, result, shouldFoldCaseForNonPortable);\r\n                    }\r\n                }\r\n            }\r\n            break;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    TestPackageVersion::Manifest TestPackageVersion::GetManifest()\r\n    {\r\n        if (auto source = GetTestSource())\r\n        {\r\n            source->IncrementCountOfCallsRequiringManifestData();\r\n        }\r\n\r\n        return VersionManifest;\r\n    }\r\n\r\n    Repository::Source TestPackageVersion::GetSource() const\r\n    {\r\n        return std::const_pointer_cast<TestPackageVersion::ISource>(Source.lock());\r\n    }\r\n\r\n    TestPackageVersion::MetadataMap TestPackageVersion::GetMetadata() const\r\n    {\r\n        return Metadata;\r\n    }\r\n\r\n    void TestPackageVersion::AddIfHasValueAndNotPresent(const Utility::NormalizedString& value, std::vector<LocIndString>& target, bool folded)\r\n    {\r\n        if (!value.empty())\r\n        {\r\n            std::string valueString = folded ? FoldCase(value) : value;\r\n            auto itr = std::find(target.begin(), target.end(), valueString);\r\n            if (itr == target.end())\r\n            {\r\n                target.emplace_back(std::move(valueString));\r\n            }\r\n        }\r\n    }\r\n\r\n    TestSource* TestPackageVersion::GetTestSource() const\r\n    {\r\n        return GetTestSourceFromWeakPtr(Source);\r\n    }\r\n\r\n    TestPackage::TestPackage(const std::vector<Manifest>& available, std::weak_ptr<const ISource> source, bool hideSystemReferenceStringsOnVersion) :\r\n        Source(source)\r\n    {\r\n        DefaultIsSameIdentity = GetNextTestPackageId();\r\n        for (const auto& manifest : available)\r\n        {\r\n            Versions.emplace_back(TestPackageVersion::Make(manifest, source, hideSystemReferenceStringsOnVersion));\r\n        }\r\n    }\r\n\r\n    TestPackage::TestPackage(const Manifest& installed, MetadataMap installationMetadata, std::weak_ptr<const ISource> source) :\r\n        Source(source)\r\n    {\r\n        DefaultIsSameIdentity = GetNextTestPackageId();\r\n        Versions.emplace_back(TestPackageVersion::Make(installed, std::move(installationMetadata), source));\r\n    }\r\n\r\n    TestPackage::LocIndString TestPackage::GetProperty(PackageProperty property) const\r\n    {\r\n        std::shared_ptr<IPackageVersion> truth;\r\n\r\n        if (!Versions.empty())\r\n        {\r\n            truth = Versions[0];\r\n        }\r\n\r\n        if (!truth)\r\n        {\r\n            THROW_HR(E_NOT_VALID_STATE);\r\n        }\r\n\r\n        switch (property)\r\n        {\r\n        case PackageProperty::Id:\r\n            return truth->GetProperty(PackageVersionProperty::Id);\r\n        case PackageProperty::Name:\r\n            return truth->GetProperty(PackageVersionProperty::Name);\r\n        default:\r\n            return {};\r\n        }\r\n    }\r\n\r\n    std::vector<TestPackage::LocIndString> TestPackage::GetMultiProperty(PackageMultiProperty property) const\r\n    {\r\n        std::vector<LocIndString> result;\r\n        PackageVersionMultiProperty mappedProperty = PackageMultiPropertyToPackageVersionMultiProperty(property);\r\n\r\n        for (const auto& version : Versions)\r\n        {\r\n            for (auto&& string : version->GetMultiProperty(mappedProperty))\r\n            {\r\n                auto itr = std::lower_bound(result.begin(), result.end(), string);\r\n\r\n                if (itr == result.end() || *itr != string)\r\n                {\r\n                    result.emplace(itr, std::move(string));\r\n                }\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<PackageVersionKey> TestPackage::GetVersionKeys() const\r\n    {\r\n        if (auto source = GetTestSource())\r\n        {\r\n            source->IncrementCountOfCallsRequiringVersionData();\r\n        }\r\n\r\n        std::vector<PackageVersionKey> result;\r\n        for (const auto& version : Versions)\r\n        {\r\n            result.emplace_back(PackageVersionKey(version->GetSource().GetIdentifier(), version->GetProperty(PackageVersionProperty::Version).get(), version->GetProperty(PackageVersionProperty::Channel).get()));\r\n        }\r\n        return result;\r\n    }\r\n\r\n    std::shared_ptr<IPackageVersion> TestPackage::GetLatestVersion() const\r\n    {\r\n        if (Versions.empty())\r\n        {\r\n            return {};\r\n        }\r\n\r\n        return Versions[0];\r\n    }\r\n\r\n    std::shared_ptr<IPackageVersion> TestPackage::GetVersion(const PackageVersionKey& versionKey) const\r\n    {\r\n        if (!versionKey.IsDefaultLatest())\r\n        {\r\n            if (auto source = GetTestSource())\r\n            {\r\n                source->IncrementCountOfCallsRequiringVersionData();\r\n            }\r\n        }\r\n\r\n        for (const auto& version : Versions)\r\n        {\r\n            if ((versionKey.Version.empty() || versionKey.Version == version->GetProperty(PackageVersionProperty::Version).get()) && \r\n                (versionKey.Channel.empty() || versionKey.Channel == version->GetProperty(PackageVersionProperty::Channel).get()))\r\n            {\r\n                return version;\r\n            }\r\n        }\r\n\r\n        return {};\r\n    }\r\n\r\n    Repository::Source TestPackage::GetSource() const\r\n    {\r\n        return std::const_pointer_cast<TestPackage::ISource>(Source.lock());\r\n    }\r\n\r\n    bool TestPackage::IsSame(const IPackage* other) const\r\n    {\r\n        if (IsSameOverride)\r\n        {\r\n            return IsSameOverride(this, other);\r\n        }\r\n\r\n        const TestPackage* otherPackage = PackageCast<const TestPackage*>(other);\r\n\r\n        if (otherPackage && DefaultIsSameIdentity == otherPackage->DefaultIsSameIdentity)\r\n        {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    const void* TestPackage::CastTo(IPackageType type) const\r\n    {\r\n        if (type == PackageType)\r\n        {\r\n            return this;\r\n        }\r\n\r\n        return nullptr;\r\n    }\r\n\r\n    TestSource* TestPackage::GetTestSource() const\r\n    {\r\n        return GetTestSourceFromWeakPtr(Source);\r\n    }\r\n\r\n    TestCompositePackage::TestCompositePackage(const std::vector<Manifest>& available, std::weak_ptr<const ISource> source, bool hideSystemReferenceStringsOnVersion)\r\n    {\r\n        if (!available.empty())\r\n        {\r\n            Available.emplace_back(TestPackage::Make(available, source, hideSystemReferenceStringsOnVersion));\r\n        }\r\n    }\r\n\r\n    TestCompositePackage::TestCompositePackage(const Manifest& installed, MetadataMap installationMetadata, const std::vector<Manifest>& available, std::weak_ptr<const ISource> source) :\r\n        Installed(TestPackage::Make(installed, std::move(installationMetadata), source))\r\n    {\r\n        if (!available.empty())\r\n        {\r\n            Available.emplace_back(TestPackage::Make(available, source));\r\n        }\r\n    }\r\n\r\n    TestCompositePackage::LocIndString TestCompositePackage::GetProperty(PackageProperty property) const\r\n    {\r\n        std::shared_ptr<IPackage> truth;\r\n\r\n        if (!Available.empty())\r\n        {\r\n            truth = Available[0];\r\n        }\r\n        else\r\n        {\r\n            truth = Installed;\r\n        }\r\n\r\n        if (!truth)\r\n        {\r\n            THROW_HR(E_NOT_VALID_STATE);\r\n        }\r\n\r\n        switch (property)\r\n        {\r\n        case PackageProperty::Id:\r\n            return truth->GetProperty(PackageProperty::Id);\r\n        case PackageProperty::Name:\r\n            return truth->GetProperty(PackageProperty::Name);\r\n        default:\r\n            return {};\r\n        }\r\n    }\r\n\r\n    std::shared_ptr<AppInstaller::Repository::IPackage> TestCompositePackage::GetInstalled()\r\n    {\r\n        return Installed;\r\n    }\r\n\r\n    std::vector<std::shared_ptr<AppInstaller::Repository::IPackage>> TestCompositePackage::GetAvailable()\r\n    {\r\n        return { Available.begin(), Available.end() };\r\n    }\r\n\r\n    const SourceDetails& TestSource::GetDetails() const\r\n    {\r\n        return Details;\r\n    }\r\n\r\n    const std::string& TestSource::GetIdentifier() const\r\n    {\r\n        return Details.Identifier;\r\n    }\r\n\r\n    SourceInformation TestSource::GetInformation() const\r\n    {\r\n        return Information;\r\n    }\r\n\r\n    bool TestSource::QueryFeatureFlag(SourceFeatureFlag flag) const\r\n    {\r\n        return (QueryFeatureFlagFunction ? QueryFeatureFlagFunction(flag) : false);\r\n    }\r\n\r\n    SearchResult TestSource::Search(const SearchRequest& request) const\r\n    {\r\n        if (SearchFunction)\r\n        {\r\n            return SearchFunction(request);\r\n        }\r\n        else\r\n        {\r\n            return {};\r\n        }\r\n    }\r\n\r\n    void* TestSource::CastTo(AppInstaller::Repository::ISourceType type)\r\n    {\r\n        if (type == SourceType)\r\n        {\r\n            return this;\r\n        }\r\n\r\n        return nullptr;\r\n    }\r\n\r\n    void TestSource::IncrementCountOfCallsRequiringVersionData()\r\n    {\r\n        ++CountOfCallsRequiringVersionData;\r\n    }\r\n\r\n    void TestSource::IncrementCountOfCallsRequiringManifestData()\r\n    {\r\n        ++CountOfCallsRequiringManifestData;\r\n    }\r\n\r\n    std::string_view TestSourceFactory::TypeName() const\r\n    {\r\n        return \"*TestSource\"sv;\r\n    }\r\n\r\n    std::shared_ptr<ISourceReference> TestSourceFactory::Create(const SourceDetails& details)\r\n    {\r\n        std::shared_ptr<TestSourceReference> result;\r\n\r\n        if (OnOpenWithCustomHeader)\r\n        {\r\n            result = std::make_shared<TestSourceReference>(details, OnOpenWithCustomHeader);\r\n        }\r\n        else\r\n        {\r\n            result = std::make_shared<TestSourceReference>(details, OnOpen);\r\n        }\r\n\r\n        result->ShouldUpdateBeforeOpenResult = ShouldUpdateBeforeOpenResult;\r\n\r\n        return result;\r\n    }\r\n\r\n    bool TestSourceFactory::Add(SourceDetails& details, IProgressCallback&)\r\n    {\r\n        if (OnAdd)\r\n        {\r\n            OnAdd(details);\r\n        }\r\n        return true;\r\n    }\r\n\r\n    bool TestSourceFactory::Update(const SourceDetails& details, IProgressCallback&)\r\n    {\r\n        if (OnUpdate)\r\n        {\r\n            OnUpdate(details);\r\n        }\r\n        return true;\r\n    }\r\n\r\n    bool TestSourceFactory::Remove(const SourceDetails& details, IProgressCallback&)\r\n    {\r\n        if (OnRemove)\r\n        {\r\n            OnRemove(details);\r\n        }\r\n        return true;\r\n    }\r\n\r\n    // Make copies of self when requested.\r\n    TestSourceFactory::operator std::function<std::unique_ptr<ISourceFactory>()>()\r\n    {\r\n        return [this]() { return std::make_unique<TestSourceFactory>(*this); };\r\n    }\r\n\r\n    bool AddSource(const AppInstaller::Repository::SourceDetails& details, AppInstaller::IProgressCallback& progress)\r\n    {\r\n        Repository::SourceEdit additionalProperties;\r\n        additionalProperties.Explicit = details.Explicit;\r\n        additionalProperties.Priority = details.Priority;\r\n        Repository::Source source{ details.Name, details.Arg, details.Type, Repository::SourceTrustLevel::None, additionalProperties };\r\n        return source.Add(progress);\r\n    }\r\n\r\n    bool UpdateSource(std::string_view name, AppInstaller::IProgressCallback& progress)\r\n    {\r\n        Repository::Source source{ name };\r\n        return source.Update(progress).empty();\r\n    }\r\n\r\n    bool RemoveSource(std::string_view name, AppInstaller::IProgressCallback& progress)\r\n    {\r\n        Repository::Source source{ name };\r\n        return source.Remove(progress);\r\n    }\r\n\r\n    std::vector<AppInstaller::Repository::SourceDetails> GetSources()\r\n    {\r\n        return Repository::Source::GetCurrentSources();\r\n    }\r\n\r\n    AppInstaller::Repository::Source OpenSource(std::string_view name, AppInstaller::IProgressCallback& progress)\r\n    {\r\n        Repository::Source source{ name };\r\n        source.Open(progress);\r\n        return source;\r\n    }\r\n\r\n    void DropSource(std::string_view name)\r\n    {\r\n        Source::DropSource(name);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/TestSource.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <ISource.h>\r\n#include <winget/Manifest.h>\r\n#include <SourceFactory.h>\r\n\r\n#include <functional>\r\n#include <utility>\r\n\r\nnamespace TestCommon\r\n{\r\n    struct TestSource;\r\n\r\n    // IPackageVersion for TestSource\r\n    struct TestPackageVersion : public AppInstaller::Repository::IPackageVersion\r\n    {\r\n        using Manifest = AppInstaller::Manifest::Manifest;\r\n        using ISource = AppInstaller::Repository::ISource;\r\n        using LocIndString = AppInstaller::Utility::LocIndString;\r\n        using MetadataMap = AppInstaller::Repository::IPackageVersion::Metadata;\r\n\r\n        TestPackageVersion(const Manifest& manifest, std::weak_ptr<const ISource> source = {}, bool hideSystemReferenceStrings = false);\r\n        TestPackageVersion(const Manifest& manifest, MetadataMap installationMetadata, std::weak_ptr<const ISource> source = {});\r\n\r\n        template <typename... Args>\r\n        static std::shared_ptr<TestPackageVersion> Make(Args&&... args)\r\n        {\r\n            return std::make_shared<TestPackageVersion>(std::forward<Args>(args)...);\r\n        }\r\n\r\n        LocIndString GetProperty(AppInstaller::Repository::PackageVersionProperty property) const override;\r\n        std::vector<LocIndString> GetMultiProperty(AppInstaller::Repository::PackageVersionMultiProperty property) const override;\r\n        Manifest GetManifest() override;\r\n        AppInstaller::Repository::Source GetSource() const override;\r\n        MetadataMap GetMetadata() const override;\r\n\r\n        Manifest VersionManifest;\r\n        MetadataMap Metadata;\r\n        std::weak_ptr<const ISource> Source;\r\n        bool HideSystemReferenceStrings = false;\r\n\r\n    protected:\r\n        static void AddIfHasValueAndNotPresent(const AppInstaller::Utility::NormalizedString& value, std::vector<LocIndString>& target, bool folded = false);\r\n        TestSource* GetTestSource() const;\r\n    };\r\n\r\n    // IPackage for TestSource\r\n    struct TestPackage : public AppInstaller::Repository::IPackage\r\n    {\r\n        static constexpr AppInstaller::Repository::IPackageType PackageType = AppInstaller::Repository::IPackageType::TestPackage;\r\n\r\n        using Manifest = AppInstaller::Manifest::Manifest;\r\n        using ISource = AppInstaller::Repository::ISource;\r\n        using LocIndString = AppInstaller::Utility::LocIndString;\r\n        using MetadataMap = TestPackageVersion::MetadataMap;\r\n\r\n        // Create a package with only available versions using these manifests.\r\n        TestPackage(const std::vector<Manifest>& available, std::weak_ptr<const ISource> source = {}, bool hideSystemReferenceStringsOnVersion = false);\r\n\r\n        // Create a package with an installed version, metadata, and optionally available versions.\r\n        TestPackage(const Manifest& installed, MetadataMap installationMetadata, std::weak_ptr<const ISource> source = {});\r\n\r\n        template <typename... Args>\r\n        static std::shared_ptr<TestPackage> Make(Args&&... args)\r\n        {\r\n            return std::make_shared<TestPackage>(std::forward<Args>(args)...);\r\n        }\r\n\r\n        AppInstaller::Utility::LocIndString GetProperty(AppInstaller::Repository::PackageProperty property) const override;\r\n        std::vector<AppInstaller::Utility::LocIndString> GetMultiProperty(AppInstaller::Repository::PackageMultiProperty property) const override;\r\n        std::vector<AppInstaller::Repository::PackageVersionKey> GetVersionKeys() const override;\r\n        std::shared_ptr<AppInstaller::Repository::IPackageVersion> GetLatestVersion() const override;\r\n        std::shared_ptr<AppInstaller::Repository::IPackageVersion> GetVersion(const AppInstaller::Repository::PackageVersionKey& versionKey) const override;\r\n        AppInstaller::Repository::Source GetSource() const override;\r\n        bool IsSame(const IPackage* other) const override;\r\n        const void* CastTo(AppInstaller::Repository::IPackageType type) const override;\r\n\r\n        std::vector<std::shared_ptr<AppInstaller::Repository::IPackageVersion>> Versions;\r\n        std::weak_ptr<const ISource> Source;\r\n        size_t DefaultIsSameIdentity = 0;\r\n        std::function<bool(const IPackage*, const IPackage*)> IsSameOverride;\r\n\r\n    protected:\r\n        TestSource* GetTestSource() const;\r\n    };\r\n\r\n    // ICompositePackage for TestSource\r\n    struct TestCompositePackage : public AppInstaller::Repository::ICompositePackage\r\n    {\r\n        using Manifest = AppInstaller::Manifest::Manifest;\r\n        using ISource = AppInstaller::Repository::ISource;\r\n        using LocIndString = AppInstaller::Utility::LocIndString;\r\n        using MetadataMap = TestPackageVersion::MetadataMap;\r\n\r\n        // Create a package with only available versions using these manifests.\r\n        TestCompositePackage(const std::vector<Manifest>& available, std::weak_ptr<const ISource> source = {}, bool hideSystemReferenceStringsOnVersion = false);\r\n\r\n        // Create a package with an installed version, metadata, and optionally available versions.\r\n        TestCompositePackage(const Manifest& installed, MetadataMap installationMetadata, const std::vector<Manifest>& available = {}, std::weak_ptr<const ISource> source = {});\r\n\r\n        template <typename... Args>\r\n        static std::shared_ptr<TestCompositePackage> Make(Args&&... args)\r\n        {\r\n            return std::make_shared<TestCompositePackage>(std::forward<Args>(args)...);\r\n        }\r\n\r\n        AppInstaller::Utility::LocIndString GetProperty(AppInstaller::Repository::PackageProperty property) const override;\r\n        std::shared_ptr<AppInstaller::Repository::IPackage> GetInstalled() override;\r\n        std::vector<std::shared_ptr<AppInstaller::Repository::IPackage>> GetAvailable() override;\r\n\r\n        std::shared_ptr<TestPackage> Installed;\r\n        std::vector<std::shared_ptr<TestPackage>> Available;\r\n    };\r\n\r\n    // An ISource implementation for use across the test code.\r\n    struct TestSource : public AppInstaller::Repository::ISource, public std::enable_shared_from_this<TestSource>\r\n    {\r\n        static constexpr AppInstaller::Repository::ISourceType SourceType = AppInstaller::Repository::ISourceType::TestSource;\r\n\r\n        const AppInstaller::Repository::SourceDetails& GetDetails() const override;\r\n        const std::string& GetIdentifier() const override;\r\n        AppInstaller::Repository::SourceInformation GetInformation() const override;\r\n\r\n        bool QueryFeatureFlag(AppInstaller::Repository::SourceFeatureFlag flag) const override;\r\n        std::function<bool(AppInstaller::Repository::SourceFeatureFlag)> QueryFeatureFlagFunction;\r\n\r\n        AppInstaller::Repository::SearchResult Search(const AppInstaller::Repository::SearchRequest& request) const override;\r\n        void* CastTo(AppInstaller::Repository::ISourceType type) override;\r\n\r\n        AppInstaller::Repository::SourceDetails Details = { \"TestSource\", \"Microsoft.TestSource\", \"//arg\", \"\", \"*TestSource\" };\r\n        AppInstaller::Repository::SourceInformation Information;\r\n        std::function<AppInstaller::Repository::SearchResult(const AppInstaller::Repository::SearchRequest& request)> SearchFunction;\r\n\r\n        TestSource() = default;\r\n        TestSource(const AppInstaller::Repository::SourceDetails& details) : Details(details) {}\r\n\r\n        // Tracking for potential network impacts\r\n        void IncrementCountOfCallsRequiringVersionData();\r\n        size_t CountOfCallsRequiringVersionData = 0;\r\n\r\n        void IncrementCountOfCallsRequiringManifestData();\r\n        size_t CountOfCallsRequiringManifestData = 0;\r\n    };\r\n\r\n    struct TestSourceReference : public AppInstaller::Repository::ISourceReference\r\n    {\r\n        using OpenFunctor = std::function<std::shared_ptr<AppInstaller::Repository::ISource>(const AppInstaller::Repository::SourceDetails&)>;\r\n        using OpenFunctorWithCustomHeader = std::function<std::shared_ptr<AppInstaller::Repository::ISource>(const AppInstaller::Repository::SourceDetails&, std::optional<std::string>)>;\r\n\r\n        TestSourceReference(const AppInstaller::Repository::SourceDetails& details, OpenFunctor open) : m_details(details), m_onOpen(open) {}\r\n        TestSourceReference(const AppInstaller::Repository::SourceDetails& details, OpenFunctorWithCustomHeader open) : m_details(details), m_onOpenWithCustomHeader(open) {}\r\n\r\n        std::string GetIdentifier() override { return m_details.Identifier; }\r\n\r\n        AppInstaller::Repository::SourceDetails& GetDetails() override { return m_details; };\r\n\r\n        bool SetCustomHeader(std::optional<std::string> header) override { m_header = header; return true; }\r\n\r\n        bool ShouldUpdateBeforeOpenResult = false;\r\n        bool ShouldUpdateBeforeOpen(const std::optional<AppInstaller::Repository::TimeSpan>&) override { return ShouldUpdateBeforeOpenResult; }\r\n\r\n        std::shared_ptr<AppInstaller::Repository::ISource> Open(AppInstaller::IProgressCallback&) override\r\n        {\r\n            if (m_onOpenWithCustomHeader)\r\n            {\r\n                return m_onOpenWithCustomHeader(m_details, m_header);\r\n            }\r\n            else\r\n            {\r\n                return m_onOpen(m_details);\r\n            }\r\n        }\r\n\r\n    private:\r\n        AppInstaller::Repository::SourceDetails m_details;\r\n        OpenFunctor m_onOpen;\r\n        OpenFunctorWithCustomHeader m_onOpenWithCustomHeader;\r\n        std::optional<std::string> m_header;\r\n    };\r\n\r\n    // An ISourceFactory implementation for use across the test code.\r\n    struct TestSourceFactory : public AppInstaller::Repository::ISourceFactory\r\n    {\r\n        using OpenFunctor = std::function<std::shared_ptr<AppInstaller::Repository::ISource>(const AppInstaller::Repository::SourceDetails&)>;\r\n        using OpenFunctorWithCustomHeader = std::function<std::shared_ptr<AppInstaller::Repository::ISource>(const AppInstaller::Repository::SourceDetails&, std::optional<std::string>)>;\r\n        using AddFunctor = std::function<void(AppInstaller::Repository::SourceDetails&)>;\r\n        using UpdateFunctor = std::function<void(const AppInstaller::Repository::SourceDetails&)>;\r\n        using RemoveFunctor = std::function<void(const AppInstaller::Repository::SourceDetails&)>;\r\n\r\n        TestSourceFactory(OpenFunctor open) : OnOpen(std::move(open)) {}\r\n        TestSourceFactory(OpenFunctorWithCustomHeader open) : OnOpenWithCustomHeader(std::move(open)) {}\r\n\r\n        // ISourceFactory\r\n        std::string_view TypeName() const override;\r\n        std::shared_ptr<AppInstaller::Repository::ISourceReference> Create(const AppInstaller::Repository::SourceDetails& details) override;\r\n        bool Add(AppInstaller::Repository::SourceDetails& details, AppInstaller::IProgressCallback&) override;\r\n        bool Update(const AppInstaller::Repository::SourceDetails& details, AppInstaller::IProgressCallback&) override;\r\n        bool Remove(const AppInstaller::Repository::SourceDetails& details, AppInstaller::IProgressCallback&) override;\r\n\r\n        // Make copies of self when requested.\r\n        operator std::function<std::unique_ptr<AppInstaller::Repository::ISourceFactory>()>();\r\n\r\n        bool ShouldUpdateBeforeOpenResult = false;\r\n        OpenFunctor OnOpen;\r\n        OpenFunctorWithCustomHeader OnOpenWithCustomHeader;\r\n        AddFunctor OnAdd;\r\n        UpdateFunctor OnUpdate;\r\n        RemoveFunctor OnRemove;\r\n    };\r\n\r\n    bool AddSource(const AppInstaller::Repository::SourceDetails& details, AppInstaller::IProgressCallback& progress);\r\n    bool UpdateSource(std::string_view name, AppInstaller::IProgressCallback& progress);\r\n    bool RemoveSource(std::string_view name, AppInstaller::IProgressCallback& progress);\r\n    AppInstaller::Repository::Source OpenSource(std::string_view name, AppInstaller::IProgressCallback& progress);\r\n    void DropSource(std::string_view name);\r\n    std::vector<AppInstaller::Repository::SourceDetails> GetSources();\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/UninstallFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"WorkflowCommon.h\"\r\n#include <Commands/UninstallCommand.h>\r\n#include <Workflows/PortableFlow.h>\r\n#include <Workflows/ShellExecuteInstallerHandler.h>\r\n#include <Workflows/UninstallFlow.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::CLI;\r\nusing namespace AppInstaller::CLI::Workflow;\r\n\r\nvoid OverrideForPortableUninstall(TestContext& context)\r\n{\r\n    context.Override({ GetUninstallInfo, [](TestContext&)\r\n    {\r\n    } });\r\n\r\n    context.Override({ PortableUninstallImpl, [](TestContext& context)\r\n    {\r\n        std::filesystem::path temp = std::filesystem::temp_directory_path();\r\n        temp /= \"TestPortableUninstalled.txt\";\r\n        std::ofstream file(temp, std::ofstream::out);\r\n        file.close();\r\n\r\n        context.Add<Execution::Data::OperationReturnCode>(0);\r\n    } });\r\n}\r\n\r\nvoid OverrideForExeUninstall(TestContext& context)\r\n{\r\n    context.Override({ ShellExecuteUninstallImpl, [](TestContext& context)\r\n    {\r\n            // Write out the uninstall command\r\n            std::filesystem::path temp = std::filesystem::temp_directory_path();\r\n            temp /= \"TestExeUninstalled.txt\";\r\n            std::ofstream file(temp, std::ofstream::out);\r\n            file << context.Get<Execution::Data::UninstallString>();\r\n            file.close();\r\n\r\n            context.Add<Execution::Data::OperationReturnCode>(0);\r\n        } });\r\n}\r\n\r\nvoid OverrideForMSIXUninstall(TestContext& context)\r\n{\r\n    context.Override({ MsixUninstall, [](TestContext& context)\r\n    {\r\n            // Write out the package full name\r\n            std::filesystem::path temp = std::filesystem::temp_directory_path();\r\n            temp /= \"TestMsixUninstalled.txt\";\r\n            std::ofstream file(temp, std::ofstream::out);\r\n            for (const auto& packageFamilyName : context.Get<Execution::Data::PackageFamilyNames>())\r\n            {\r\n                file << packageFamilyName << std::endl;\r\n            }\r\n\r\n            file.close();\r\n        } });\r\n}\r\n\r\nTEST_CASE(\"UninstallFlow_UninstallPortable\", \"[UninstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile uninstallResultPath(\"TestPortableUninstalled.txt\");\r\n\r\n    std::ostringstream uninstallOutput;\r\n    TestContext context{ uninstallOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Portable }));\r\n    OverrideForPortableUninstall(context);\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Portable.Query);\r\n\r\n    UninstallCommand uninstall({});\r\n    uninstall.Execute(context);\r\n    INFO(uninstallOutput.str());\r\n    REQUIRE(std::filesystem::exists(uninstallResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"UninstallFlow_UninstallExe\", \"[UninstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile uninstallResultPath(\"TestExeUninstalled.txt\");\r\n\r\n    std::ostringstream uninstallOutput;\r\n    TestContext context{ uninstallOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Exe }));\r\n    OverrideForExeUninstall(context);\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe.Query);\r\n    context.Args.AddArg(Execution::Args::Type::Silent);\r\n\r\n    UninstallCommand uninstall({});\r\n    uninstall.Execute(context);\r\n    INFO(uninstallOutput.str());\r\n\r\n    // Verify Uninstaller is called and parameters are passed in.\r\n    REQUIRE(std::filesystem::exists(uninstallResultPath.GetPath()));\r\n    std::ifstream uninstallResultFile(uninstallResultPath.GetPath());\r\n    REQUIRE(uninstallResultFile.is_open());\r\n    std::string uninstallResultStr;\r\n    std::getline(uninstallResultFile, uninstallResultStr);\r\n    REQUIRE(uninstallResultStr.find(\"uninstall.exe\") != std::string::npos);\r\n    REQUIRE(uninstallResultStr.find(\"/silence\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"UninstallFlow_UninstallMsix\", \"[UninstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile uninstallResultPath(\"TestMsixUninstalled.txt\");\r\n\r\n    std::ostringstream uninstallOutput;\r\n    TestContext context{ uninstallOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Msix }));\r\n    OverrideForMSIXUninstall(context);\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Msix.Query);\r\n\r\n    UninstallCommand uninstall({});\r\n    uninstall.Execute(context);\r\n    INFO(uninstallOutput.str());\r\n\r\n    // Verify Uninstaller is called with the package full name.\r\n    REQUIRE(std::filesystem::exists(uninstallResultPath.GetPath()));\r\n    std::ifstream uninstallResultFile(uninstallResultPath.GetPath());\r\n    REQUIRE(uninstallResultFile.is_open());\r\n    std::string uninstallResultStr;\r\n    std::getline(uninstallResultFile, uninstallResultStr);\r\n    REQUIRE(uninstallResultStr.find(\"20477fca-282d-49fb-b03e-371dca074f0f_8wekyb3d8bbwe\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"UninstallFlow_UninstallMSStore\", \"[UninstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile uninstallResultPath(\"TestMsixUninstalled.txt\");\r\n\r\n    std::ostringstream uninstallOutput;\r\n    TestContext context{ uninstallOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_MSStore }));\r\n    OverrideForMSIXUninstall(context);\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_MSStore.Query);\r\n\r\n    UninstallCommand uninstall({});\r\n    uninstall.Execute(context);\r\n    INFO(uninstallOutput.str());\r\n\r\n    // Verify Uninstaller is called with the package full name\r\n    REQUIRE(std::filesystem::exists(uninstallResultPath.GetPath()));\r\n    std::ifstream uninstallResultFile(uninstallResultPath.GetPath());\r\n    REQUIRE(uninstallResultFile.is_open());\r\n    std::string uninstallResultStr;\r\n    std::getline(uninstallResultFile, uninstallResultStr);\r\n    REQUIRE(uninstallResultStr.find(\"microsoft.skypeapp_kzf8qxf38zg5c\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"UninstallFlow_UninstallExeNotFound\", \"[UninstallFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile uninstallResultPath(\"TestExeUninstalled.txt\");\r\n\r\n    std::ostringstream uninstallOutput;\r\n    TestContext context{ uninstallOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({}));\r\n    context.Args.AddArg(Execution::Args::Type::Query, \"AppInstallerCliTest.MissingApp\"sv);\r\n    context.Args.AddArg(Execution::Args::Type::Silent);\r\n\r\n    UninstallCommand uninstall({});\r\n    uninstall.Execute(context);\r\n    INFO(uninstallOutput.str());\r\n\r\n    // Verify Uninstaller is not called.\r\n    REQUIRE(!std::filesystem::exists(uninstallResultPath.GetPath()));\r\n    REQUIRE(uninstallOutput.str().find(Resource::LocString(Resource::String::NoInstalledPackageFound).get()) != std::string::npos);\r\n    REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_NO_APPLICATIONS_FOUND);\r\n}\r\n\r\nTEST_CASE(\"UninstallFlow_UninstallMultiple\", \"[UninstallFlow][workflow][MultiQuery]\")\r\n{\r\n    TestCommon::TempFile exeUninstallResultPath(\"TestExeUninstalled.txt\");\r\n    TestCommon::TempFile msixUninstallResultPath(\"TestMsixUninstalled.txt\");\r\n\r\n    std::ostringstream uninstallOutput;\r\n    TestContext context{ uninstallOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Exe, TSR::TestInstaller_Msix }));\r\n    OverrideForExeUninstall(context);\r\n    OverrideForMSIXUninstall(context);\r\n    context.Args.AddArg(Execution::Args::Type::MultiQuery, TSR::TestInstaller_Exe.Query);\r\n    context.Args.AddArg(Execution::Args::Type::MultiQuery, TSR::TestInstaller_Msix.Query);\r\n\r\n    UninstallCommand uninstall({});\r\n    uninstall.Execute(context);\r\n    INFO(uninstallOutput.str());\r\n\r\n    // Verify Uninstallers are called\r\n    REQUIRE(std::filesystem::exists(exeUninstallResultPath.GetPath()));\r\n    REQUIRE(std::filesystem::exists(msixUninstallResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"UninstallFlow_UninstallMultiple_NotAllInstalled\", \"[UninstallFlow][workflow][MultiQuery]\")\r\n{\r\n    std::ostringstream uninstallOutput;\r\n    TestContext context{ uninstallOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Exe }));\r\n    context.Args.AddArg(Execution::Args::Type::MultiQuery, TSR::TestInstaller_Exe.Query);\r\n    context.Args.AddArg(Execution::Args::Type::MultiQuery, TSR::TestInstaller_Msix.Query);\r\n\r\n    UninstallCommand uninstall({});\r\n    uninstall.Execute(context);\r\n    INFO(uninstallOutput.str());\r\n\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_NOT_ALL_QUERIES_FOUND_SINGLE);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/UpdateFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"WorkflowCommon.h\"\r\n#include \"TestHooks.h\"\r\n#include <Commands/InstallCommand.h>\r\n#include <Commands/UninstallCommand.h>\r\n#include <Commands/UpgradeCommand.h>\r\n#include <winget/PathVariable.h>\r\n#include <Workflows/ShellExecuteInstallerHandler.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::CLI;\r\nusing namespace AppInstaller::CLI::Execution;\r\nusing namespace AppInstaller::Settings;\r\nusing namespace AppInstaller::Utility::literals;\r\n\r\nTEST_CASE(\"UpdateFlow_UpdateWithManifest\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Exe }));\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"UpdateFlowTest_Exe.yaml\").GetPath().u8string());\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify Installer is called and parameters are passed in.\r\n    REQUIRE(std::filesystem::exists(updateResultPath.GetPath()));\r\n    std::ifstream updateResultFile(updateResultPath.GetPath());\r\n    REQUIRE(updateResultFile.is_open());\r\n    std::string updateResultStr;\r\n    std::getline(updateResultFile, updateResultStr);\r\n    REQUIRE(updateResultStr.find(\"/update\") != std::string::npos);\r\n    REQUIRE(updateResultStr.find(\"/silentwithprogress\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_UpdateWithManifestMSStore\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateResultPath(\"TestMSStoreUpdated.txt\");\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_MSStore }));\r\n    OverrideForMSStore(context, true);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_MSStore.yaml\").GetPath().u8string());\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify Installer is called and parameters are passed in.\r\n    REQUIRE(std::filesystem::exists(updateResultPath.GetPath()));\r\n    std::ifstream updateResultFile(updateResultPath.GetPath());\r\n    REQUIRE(updateResultFile.is_open());\r\n    std::string updateResultStr;\r\n    std::getline(updateResultFile, updateResultStr);\r\n    REQUIRE(updateResultStr.find(\"9WZDNCRFJ364\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_UpdateWithManifestAppNotInstalled\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({}));\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallerArgTest_Inno_NoSwitches.yaml\").GetPath().u8string());\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify Installer is not called.\r\n    REQUIRE(!std::filesystem::exists(updateResultPath.GetPath()));\r\n    REQUIRE(updateOutput.str().find(Resource::LocString(Resource::String::NoInstalledPackageFound).get()) != std::string::npos);\r\n    REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_NO_APPLICATIONS_FOUND);\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_UpdateWithManifestVersionAlreadyInstalled\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Exe }));\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_Exe.yaml\").GetPath().u8string());\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify Installer is not called.\r\n    REQUIRE(!std::filesystem::exists(updateResultPath.GetPath()));\r\n    REQUIRE(updateOutput.str().find(Resource::LocString(Resource::String::UpdateNoPackagesFound).get()) != std::string::npos);\r\n    REQUIRE(updateOutput.str().find(Resource::LocString(Resource::String::UpdateNoPackagesFoundReason).get()) != std::string::npos);\r\n    REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE);\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_UpdateExe\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Exe }));\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe.Query);\r\n    context.Args.AddArg(Execution::Args::Type::Silent);\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify Installer is called and parameters are passed in.\r\n    REQUIRE(std::filesystem::exists(updateResultPath.GetPath()));\r\n    std::ifstream updateResultFile(updateResultPath.GetPath());\r\n    REQUIRE(updateResultFile.is_open());\r\n    std::string updateResultStr;\r\n    std::getline(updateResultFile, updateResultStr);\r\n    REQUIRE(updateResultStr.find(\"/update\") != std::string::npos);\r\n    REQUIRE(updateResultStr.find(\"/silence\") != std::string::npos);\r\n    REQUIRE(updateResultStr.find(\"/ver3.0.0.0\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_UpdateZip_Exe\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Zip }));\r\n    OverrideForShellExecute(context);\r\n    OverrideForExtractInstallerFromArchive(context);\r\n    OverrideForVerifyAndSetNestedInstaller(context);\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Zip.Query);\r\n    context.Args.AddArg(Execution::Args::Type::Silent);\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify Installer is called and parameters are passed in.\r\n    REQUIRE(std::filesystem::exists(updateResultPath.GetPath()));\r\n    std::ifstream updateResultFile(updateResultPath.GetPath());\r\n    REQUIRE(updateResultFile.is_open());\r\n    std::string updateResultStr;\r\n    std::getline(updateResultFile, updateResultStr);\r\n    REQUIRE(updateResultStr.find(\"/custom\") != std::string::npos);\r\n    REQUIRE(updateResultStr.find(\"/silence\") != std::string::npos);\r\n    REQUIRE(updateResultStr.find(\"/ver2.0.0.0\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_UpdatePortable\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateResultPath(\"TestPortableInstalled.txt\");\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Portable }));\r\n    OverrideForPortableInstallFlow(context);\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Portable.Query);\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n    REQUIRE(std::filesystem::exists(updateResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_Portable_SymlinkCreationFail\", \"[UpdateFlow][workflow]\")\r\n{\r\n    // Update portable with symlink creation failure verify that it succeeds.\r\n    TestCommon::TempDirectory tempDirectory(\"TestPortableInstallRoot\", false);\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto PreviousThreadGlobals = context.SetForCurrentThread();\r\n    bool overrideCreateSymlinkStatus = false;\r\n    AppInstaller::Filesystem::TestHook_SetCreateSymlinkResult_Override(&overrideCreateSymlinkStatus);\r\n    OverridePortableInstaller(context);\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Portable }));\r\n    const auto& targetDirectory = tempDirectory.GetPath();\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Portable.Query);\r\n    context.Args.AddArg(Execution::Args::Type::InstallLocation, targetDirectory.u8string());\r\n    context.Args.AddArg(Execution::Args::Type::InstallScope, \"user\"sv);\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n    const auto& portableTargetPath = targetDirectory / \"AppInstallerTestExeInstaller.exe\";\r\n    REQUIRE(std::filesystem::exists(portableTargetPath));\r\n    REQUIRE(AppInstaller::Registry::Environment::PathVariable(AppInstaller::Manifest::ScopeEnum::User).Contains(targetDirectory));\r\n\r\n    // Perform uninstall\r\n    std::ostringstream uninstallOutput;\r\n    TestContext uninstallContext{ uninstallOutput, std::cin };\r\n    auto previousThreadGlobals = uninstallContext.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(uninstallContext, CreateTestSource({ TSR::TestInstaller_Portable }));\r\n    uninstallContext.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Portable.Query);\r\n\r\n    UninstallCommand uninstall({});\r\n    uninstall.Execute(uninstallContext);\r\n    INFO(uninstallOutput.str());\r\n\r\n    REQUIRE_FALSE(std::filesystem::exists(portableTargetPath));\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_UpdateExeWithUnsupportedArgs\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateResultPath(\"TestExeInstalled.txt\");\r\n    TestCommon::TempDirectory tempDirectory(\"TempDirectory\", false);\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Exe_UnsupportedArguments }));\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe_UnsupportedArguments.Query);\r\n    context.Args.AddArg(Execution::Args::Type::InstallLocation, tempDirectory);\r\n\r\n    UpgradeCommand update({});\r\n    context.SetExecutingCommand(&update);\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify unsupported arguments error message is shown \r\n    REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_UNSUPPORTED_ARGUMENT);\r\n    REQUIRE(!std::filesystem::exists(updateResultPath.GetPath()));\r\n    REQUIRE(updateOutput.str().find(Resource::LocString(Resource::String::UnsupportedArgument).get()) != std::string::npos);\r\n    REQUIRE(updateOutput.str().find(\"-l,--location\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_UnknownVersion\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateResultPath(\"TestExeInstalled.txt\");\r\n    TestCommon::TempDirectory tempDirectory(\"TempDirectory\", false);\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Exe_UnknownVersion }));\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe_UnknownVersion.Query);\r\n    context.Args.AddArg(Execution::Args::Type::InstallLocation, tempDirectory);\r\n\r\n    UpgradeCommand update({});\r\n    context.SetExecutingCommand(&update);\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify help message is shown the user to use --include-unknown\r\n    REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE);\r\n    REQUIRE(!std::filesystem::exists(updateResultPath.GetPath()));\r\n    REQUIRE(updateOutput.str().find(Resource::LocString(Resource::String::UpgradeUnknownVersionExplanation).get()) != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_UnknownVersion_IncludeUnknownArg\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateResultPath(\"TestExeInstalled.txt\");\r\n    TestCommon::TempDirectory tempDirectory(\"TempDirectory\", false);\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Exe_UnknownVersion }));\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe_UnknownVersion.Query);\r\n    context.Args.AddArg(Execution::Args::Type::InstallLocation, tempDirectory);\r\n    context.Args.AddArg(Execution::Args::Type::IncludeUnknown);\r\n\r\n    UpgradeCommand update({});\r\n    context.SetExecutingCommand(&update);\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n    REQUIRE(std::filesystem::exists(updateResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_NoArgs_UnknownVersion\", \"[UpdateFlow][workflow]\")\r\n{\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({\r\n        TSR::TestInstaller_Exe,\r\n        TSR::TestInstaller_Exe_UnknownVersion,\r\n        TSR::TestInstaller_Msix,\r\n        TSR::TestInstaller_MSStore,\r\n        TSR::TestInstaller_Portable,\r\n        TSR::TestInstaller_Zip,\r\n        }));\r\n\r\n    UpgradeCommand update({});\r\n    context.SetExecutingCommand(&update);\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify --include-unknown help text is displayed if update is executed with no args and an unknown version package is available for upgrade.\r\n    REQUIRE(updateOutput.str().find(Resource::String::UpgradeUnknownVersionCount(1)) != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_IncludeUnknown\", \"[UpdateFlow][workflow]\")\r\n{\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({\r\n        TSR::TestInstaller_Exe,\r\n        TSR::TestInstaller_Exe_UnknownVersion,\r\n        TSR::TestInstaller_Msix,\r\n        TSR::TestInstaller_MSStore,\r\n        TSR::TestInstaller_Portable,\r\n        TSR::TestInstaller_Zip,\r\n        }));\r\n    context.Args.AddArg(Execution::Args::Type::IncludeUnknown);\r\n\r\n    UpgradeCommand update({});\r\n    context.SetExecutingCommand(&update);\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify unknown version package is displayed available for upgrade.\r\n    REQUIRE(updateOutput.str().find(Resource::String::UpgradeUnknownVersionCount(1)) == std::string::npos);\r\n    REQUIRE(updateOutput.str().find(\"unknown\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_UpdatePortableWithManifest\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateResultPath(\"TestPortableInstalled.txt\");\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Portable }));\r\n    OverrideForPortableInstallFlow(context);\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"UpdateFlowTest_Portable.yaml\").GetPath().u8string());\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n    REQUIRE(std::filesystem::exists(updateResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_UpdateMsix\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateResultPath(\"TestMsixInstalled.txt\");\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Msix }));\r\n    OverrideForMSIX(context);\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Msix.Query);\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify Installer is called.\r\n    REQUIRE(std::filesystem::exists(updateResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_UpdateMSStore\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateResultPath(\"TestMSStoreUpdated.txt\");\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_MSStore }));\r\n    OverrideForMSStore(context, true);\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_MSStore.Query);\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify Installer is called.\r\n    REQUIRE(std::filesystem::exists(updateResultPath.GetPath()));\r\n    std::ifstream updateResultFile(updateResultPath.GetPath());\r\n    REQUIRE(updateResultFile.is_open());\r\n    std::string updateResultStr;\r\n    std::getline(updateResultFile, updateResultStr);\r\n    REQUIRE(updateResultStr.find(\"9WZDNCRFJ364\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_UpdateExeLatestAlreadyInstalled\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Exe_LatestInstalled }));\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe_LatestInstalled.Query);\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify Installer is not called.\r\n    REQUIRE(!std::filesystem::exists(updateResultPath.GetPath()));\r\n    REQUIRE(updateOutput.str().find(Resource::LocString(Resource::String::UpdateNoPackagesFound).get()) != std::string::npos);\r\n    REQUIRE(updateOutput.str().find(Resource::LocString(Resource::String::UpdateNoPackagesFoundReason).get()) != std::string::npos);\r\n    REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE);\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_UpdateExeInstallerTypeNotApplicable\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Exe_IncompatibleInstallerType }));\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe_IncompatibleInstallerType.Query);\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify Installer is not called.\r\n    REQUIRE(!std::filesystem::exists(updateResultPath.GetPath()));\r\n    REQUIRE(updateOutput.str().find(Resource::LocString(Resource::String::UpgradeDifferentInstallTechnologyInNewerVersions).get()) != std::string::npos);\r\n    REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE);\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_UpdateExeInstallerTypeNotApplicableSpecificVersion\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Exe_IncompatibleInstallerType }));\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe_IncompatibleInstallerType.Query);\r\n    context.Args.AddArg(Execution::Args::Type::Version, \"2.0.0.0\"sv);\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify Installer is not called.\r\n    REQUIRE(!std::filesystem::exists(updateResultPath.GetPath()));\r\n    REQUIRE(updateOutput.str().find(Resource::LocString(Resource::String::UpgradeDifferentInstallTechnology).get()) != std::string::npos);\r\n    REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE);\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_UpdateExeWithDifferentInstalledType\", \"[UpdateFlow][workflow]\")\r\n{\r\n    // Tests installer applicability when installed type is different but listed in the manifest\r\n    TestCommon::TempFile updateResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Exe_DifferentInstallerType }));\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe_DifferentInstallerType.Query);\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify Installer is called.\r\n    REQUIRE(context.GetTerminationHR() == S_OK);\r\n    REQUIRE(std::filesystem::exists(updateResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_UpdateExeSpecificVersionNotFound\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Exe }));\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe.Query);\r\n    context.Args.AddArg(Execution::Args::Type::Version, \"1.2.3.4\"sv);\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify Installer is not called.\r\n    REQUIRE(!std::filesystem::exists(updateResultPath.GetPath()));\r\n    REQUIRE(updateOutput.str().find(Resource::LocString(Resource::String::GetManifestResultVersionNotFound(\"1.2.3.4\"_liv)).get()) != std::string::npos);\r\n    REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_NO_MANIFEST_FOUND);\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_UpdateExeSpecificVersionNotApplicable\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Exe_IncompatibleInstallerType }));\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe_IncompatibleInstallerType.Query);\r\n    // This must be 2.0.0.0 since the version would not be an upgrade otherwise\r\n    context.Args.AddArg(Execution::Args::Type::Version, \"2.0.0.0\"sv);\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify Installer is not called.\r\n    REQUIRE(!std::filesystem::exists(updateResultPath.GetPath()));\r\n    REQUIRE(updateOutput.str().find(Resource::LocString(Resource::String::UpgradeDifferentInstallTechnology).get()) != std::string::npos);\r\n    REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE);\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_UpdateAllApplicable\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateExeResultPath(\"TestExeInstalled.txt\");\r\n    TestCommon::TempFile updateMsixResultPath(\"TestMsixInstalled.txt\");\r\n    TestCommon::TempFile updateMSStoreResultPath(\"TestMSStoreUpdated.txt\");\r\n    TestCommon::TempFile updatePortableResultPath(\"TestPortableInstalled.txt\");\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({\r\n        TSR::TestInstaller_Exe,\r\n        TSR::TestInstaller_Exe_UnknownVersion,\r\n        TSR::TestInstaller_Msix,\r\n        TSR::TestInstaller_MSStore,\r\n        TSR::TestInstaller_Portable,\r\n        TSR::TestInstaller_Zip,\r\n        }));\r\n    OverrideForShellExecute(context);\r\n    OverrideForMSIX(context);\r\n    OverrideForMSStore(context, true);\r\n    OverrideForPortableInstall(context);\r\n    context.Args.AddArg(Execution::Args::Type::All);\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify that --include-unknown help message is displayed.\r\n    REQUIRE(updateOutput.str().find(Resource::String::UpgradeUnknownVersionCount(1)) != std::string::npos);\r\n    REQUIRE(updateOutput.str().find(\"AppInstallerCliTest.TestExeUnknownVersion\") == std::string::npos);\r\n\r\n    // Verify installers are called.\r\n    REQUIRE(std::filesystem::exists(updateExeResultPath.GetPath()));\r\n    REQUIRE(std::filesystem::exists(updateMsixResultPath.GetPath()));\r\n    REQUIRE(std::filesystem::exists(updateMSStoreResultPath.GetPath()));\r\n    REQUIRE(std::filesystem::exists(updatePortableResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_UpdateAll_IncludeUnknown\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateExeResultPath(\"TestExeInstalled.txt\");\r\n    TestCommon::TempFile updateMsixResultPath(\"TestMsixInstalled.txt\");\r\n    TestCommon::TempFile updateMSStoreResultPath(\"TestMSStoreUpdated.txt\");\r\n    TestCommon::TempFile updatePortableResultPath(\"TestPortableInstalled.txt\");\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({\r\n        TSR::TestInstaller_Exe,\r\n        TSR::TestInstaller_Exe_UnknownVersion,\r\n        TSR::TestInstaller_Msix,\r\n        TSR::TestInstaller_MSStore,\r\n        TSR::TestInstaller_Portable,\r\n        TSR::TestInstaller_Zip,\r\n        }));\r\n    OverrideForShellExecute(context);\r\n    OverrideForMSIX(context);\r\n    OverrideForMSStore(context, true);\r\n    OverrideForPortableInstall(context);\r\n    context.Args.AddArg(Execution::Args::Type::All);\r\n    context.Args.AddArg(Execution::Args::Type::IncludeUnknown);\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify that --include-unknown help message is NOT displayed and unknown version package is upgraded.\r\n    REQUIRE(updateOutput.str().find(Resource::LocString(Resource::String::UpgradeUnknownVersionCount).get()) == std::string::npos);\r\n    REQUIRE(updateOutput.str().find(\"AppInstallerCliTest.TestExeUnknownVersion\") != std::string::npos);\r\n\r\n    // Verify installers are called.\r\n    REQUIRE(std::filesystem::exists(updateExeResultPath.GetPath()));\r\n    REQUIRE(std::filesystem::exists(updateMsixResultPath.GetPath()));\r\n    REQUIRE(std::filesystem::exists(updateMSStoreResultPath.GetPath()));\r\n    REQUIRE(std::filesystem::exists(updatePortableResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_UpgradeWithDuplicateUpgradeItemsFound\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateExeResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Exe_UpgradeAllWithDuplicateUpgradeItems }));\r\n    // Installer should only be run once since the 2 upgrade items are same.\r\n    OverrideForShellExecute(context, 1);\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe_UpgradeAllWithDuplicateUpgradeItems.Query);\r\n    context.Args.AddArg(Execution::Args::Type::All);\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify installers are called.\r\n    REQUIRE(std::filesystem::exists(updateExeResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_Dependencies\", \"[UpdateFlow][workflow][dependencies]\")\r\n{\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Exe_Dependencies }));\r\n    OverrideForShellExecute(context);\r\n    OverrideEnableWindowsFeaturesDependencies(context);\r\n\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe_Dependencies.Query);;\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    std::string updateResultStr = updateOutput.str();\r\n\r\n    // Verify dependencies are informed\r\n    REQUIRE(updateResultStr.find(Resource::LocString(Resource::String::PackageRequiresDependencies).get()) != std::string::npos);\r\n    REQUIRE(updateResultStr.find(\"PreviewIIS\") != std::string::npos);\r\n    REQUIRE(updateResultStr.find(\"Preview VC Runtime\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_LicenseAgreement\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Exe_LicenseAgreement }));\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe_LicenseAgreement.Query);\r\n    context.Args.AddArg(Execution::Args::Type::AcceptPackageAgreements);\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify agreements are shown\r\n    REQUIRE(updateOutput.str().find(\"Agreement for EXE\") != std::string::npos);\r\n    REQUIRE(updateOutput.str().find(\"This is the agreement for the EXE\") != std::string::npos);\r\n\r\n    // Verify Installer is called.\r\n    REQUIRE(std::filesystem::exists(updateResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_LicenseAgreement_NotAccepted\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateResultPath(\"TestExeInstalled.txt\");\r\n\r\n    // Say \"No\" at the agreements prompt\r\n    std::istringstream updateInput{ \"n\" };\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, updateInput };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Exe_LicenseAgreement }));\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe_LicenseAgreement.Query);\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify agreements are shown\r\n    REQUIRE(updateOutput.str().find(\"Agreement for EXE\") != std::string::npos);\r\n    REQUIRE(updateOutput.str().find(\"This is the agreement for the EXE\") != std::string::npos);\r\n\r\n    // Verify Installer is not called.\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED);\r\n    REQUIRE_FALSE(std::filesystem::exists(updateResultPath.GetPath()));\r\n    REQUIRE(updateOutput.str().find(Resource::LocString(Resource::String::PackageAgreementsNotAgreedTo).get()) != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_All_LicenseAgreement\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateExeResultPath(\"TestExeInstalled.txt\");\r\n    TestCommon::TempFile updateMsixResultPath(\"TestMsixInstalled.txt\");\r\n    TestCommon::TempFile updateMSStoreResultPath(\"TestMSStoreUpdated.txt\");\r\n    TestCommon::TempFile updatePortableResultPath(\"TestPortableInstalled.txt\");\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({\r\n        TSR::TestInstaller_Exe_UpgradeUsesAgreements,\r\n        TSR::TestInstaller_Exe_UnknownVersion,\r\n        TSR::TestInstaller_Msix_UpgradeUsesAgreements,\r\n        TSR::TestInstaller_MSStore,\r\n        TSR::TestInstaller_Portable,\r\n        TSR::TestInstaller_Zip,\r\n        }));\r\n    OverrideForShellExecute(context);\r\n    OverrideForMSIX(context);\r\n    OverrideForMSStore(context, true);\r\n    OverrideForPortableInstall(context);\r\n    context.Args.AddArg(Execution::Args::Type::All);\r\n    context.Args.AddArg(Execution::Args::Type::AcceptPackageAgreements);\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify agreements are shown\r\n    REQUIRE(updateOutput.str().find(\"Agreement for EXE\") != std::string::npos);\r\n    REQUIRE(updateOutput.str().find(\"This is the agreement for the EXE\") != std::string::npos);\r\n    REQUIRE(updateOutput.str().find(\"Agreement for MSIX\") != std::string::npos);\r\n    REQUIRE(updateOutput.str().find(\"This is the agreement for the MSIX\") != std::string::npos);\r\n\r\n    // Verify installers are called.\r\n    REQUIRE(std::filesystem::exists(updateExeResultPath.GetPath()));\r\n    REQUIRE(std::filesystem::exists(updateMsixResultPath.GetPath()));\r\n    REQUIRE(std::filesystem::exists(updateMSStoreResultPath.GetPath()));\r\n    REQUIRE(std::filesystem::exists(updatePortableResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_All_LicenseAgreement_NotAccepted\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateExeResultPath(\"TestExeInstalled.txt\");\r\n    TestCommon::TempFile updateMsixResultPath(\"TestMsixInstalled.txt\");\r\n    TestCommon::TempFile updateMSStoreResultPath(\"TestMSStoreUpdated.txt\");\r\n\r\n    // Say \"No\" at the agreements prompt\r\n    std::istringstream updateInput{ \"n\" };\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, updateInput };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({\r\n        TSR::TestInstaller_Exe_UpgradeUsesAgreements,\r\n        TSR::TestInstaller_Exe_UnknownVersion,\r\n        TSR::TestInstaller_Msix_UpgradeUsesAgreements,\r\n        TSR::TestInstaller_MSStore,\r\n        TSR::TestInstaller_Portable,\r\n        TSR::TestInstaller_Zip,\r\n        }));\r\n    context.Args.AddArg(Execution::Args::Type::All);\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify agreements are shown\r\n    REQUIRE(updateOutput.str().find(\"Agreement for EXE\") != std::string::npos);\r\n    REQUIRE(updateOutput.str().find(\"This is the agreement for the EXE\") != std::string::npos);\r\n    REQUIRE(updateOutput.str().find(\"Agreement for MSIX\") != std::string::npos);\r\n    REQUIRE(updateOutput.str().find(\"This is the agreement for the MSIX\") != std::string::npos);\r\n\r\n    // Verify installers are not called.\r\n    REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED);\r\n    REQUIRE_FALSE(std::filesystem::exists(updateExeResultPath.GetPath()));\r\n    REQUIRE_FALSE(std::filesystem::exists(updateMsixResultPath.GetPath()));\r\n    REQUIRE_FALSE(std::filesystem::exists(updateMSStoreResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_RequireExplicit\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateExeResultPath(\"TestExeInstalled.txt\");\r\n    TestCommon::TempFile updateMsixResultPath(\"TestMsixInstalled.txt\");\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n\r\n    // Msix package has an update that requires explicit upgrade.\r\n    // Exe, Portable, MSStore, Zip are also listed with an available upgrade.\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({\r\n        TSR::TestInstaller_Exe,\r\n        TSR::TestInstaller_Exe_UnknownVersion,\r\n        TSR::TestInstaller_Msix_UpgradeRequiresExplicit,\r\n        TSR::TestInstaller_MSStore,\r\n        TSR::TestInstaller_Portable,\r\n        TSR::TestInstaller_Zip,\r\n        }));\r\n\r\n    SECTION(\"List available upgrades\")\r\n    {\r\n        UpgradeCommand update({});\r\n        update.Execute(context);\r\n        INFO(updateOutput.str());\r\n\r\n        // The package that requires explicit upgrade is listed below the header for pinned packages\r\n        REQUIRE(updateOutput.str().find(\"AppInstallerCliTest.TestExeInstaller\") != std::string::npos);\r\n\r\n        auto pinnedPackagesHeaderPosition = updateOutput.str().find(Resource::LocString(Resource::String::UpgradeAvailableForPinned));\r\n        auto pinnedPackageLinePosition = updateOutput.str().find(\"AppInstallerCliTest.TestMsixInstaller\");\r\n        REQUIRE(pinnedPackagesHeaderPosition != std::string::npos);\r\n        REQUIRE(pinnedPackageLinePosition != std::string::npos);\r\n        REQUIRE(pinnedPackagesHeaderPosition < pinnedPackageLinePosition);\r\n        REQUIRE(updateOutput.str().find(Resource::String::UpgradeRequireExplicitCount(1)) == std::string::npos);\r\n    }\r\n\r\n    SECTION(\"Upgrade all except pinned\")\r\n    {\r\n        context.Args.AddArg(Args::Type::All);\r\n        OverrideForMSStore(context, true);\r\n        OverrideForPortableInstall(context);\r\n        OverrideForShellExecute(context);\r\n        OverrideForExtractInstallerFromArchive(context);\r\n        OverrideForVerifyAndSetNestedInstaller(context);\r\n\r\n        UpgradeCommand update({});\r\n        update.Execute(context);\r\n        INFO(updateOutput.str());\r\n\r\n        auto s = updateOutput.str();\r\n\r\n        // Verify message is printed for skipped package\r\n        REQUIRE(updateOutput.str().find(Resource::String::UpgradeRequireExplicitCount(1)) != std::string::npos);\r\n\r\n        // Verify package is not installed, but all others are\r\n        REQUIRE(std::filesystem::exists(updateExeResultPath.GetPath()));\r\n        REQUIRE(!std::filesystem::exists(updateMsixResultPath.GetPath()));\r\n    }\r\n\r\n    SECTION(\"Upgrade explicitly\")\r\n    {\r\n        context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Msix.Query);\r\n        OverrideForMSIX(context);\r\n\r\n        UpgradeCommand update({});\r\n        update.Execute(context);\r\n        INFO(updateOutput.str());\r\n\r\n        REQUIRE(std::filesystem::exists(updateMsixResultPath.GetPath()));\r\n    }\r\n\r\n    // Command should always succeed\r\n    REQUIRE(context.GetTerminationHR() == S_OK);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_FoundInstalledAndUpgradeAvailable\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Exe }));\r\n    OverrideForShellExecute(context);\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe.Query);\r\n    context.Args.AddArg(Execution::Args::Type::Silent);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify Installer is called and parameters are passed in.\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n    std::ifstream installResultFile(installResultPath.GetPath());\r\n    REQUIRE(installResultFile.is_open());\r\n    std::string installResultStr;\r\n    std::getline(installResultFile, installResultStr);\r\n    REQUIRE(installResultStr.find(\"/update\") != std::string::npos);\r\n    REQUIRE(installResultStr.find(\"/ver3.0.0.0\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_FoundInstalledAndUpgradeAvailable_WithNoUpgrade\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Exe }));\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe.Query);\r\n    context.Args.AddArg(Execution::Args::Type::NoUpgrade);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify Installer is not called.\r\n    REQUIRE(!std::filesystem::exists(installResultPath.GetPath()));\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::PackageAlreadyInstalled).get()) != std::string::npos);\r\n    REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_PACKAGE_ALREADY_INSTALLED);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_FoundInstalledAndUpgradeNotAvailable\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Exe_LatestInstalled }));\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe_LatestInstalled.Query);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify Installer is not called.\r\n    REQUIRE(!std::filesystem::exists(installResultPath.GetPath()));\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::UpdateNoPackagesFound).get()) != std::string::npos);\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::UpdateNoPackagesFoundReason).get()) != std::string::npos);\r\n    REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE);\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_UpdateAll_ForwardArgs\", \"[UpdateFlow][workflow]\")\r\n{\r\n    TestCommon::TempFile updateExeResultPath(\"TestExeInstalled.txt\");\r\n    TestCommon::TempFile updateMsixResultPath(\"TestMsixInstalled.txt\");\r\n    TestCommon::TempFile updateMSStoreResultPath(\"TestMSStoreUpdated.txt\");\r\n    TestCommon::TempFile updatePortableResultPath(\"TestPortableInstalled.txt\");\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({\r\n        TSR::TestInstaller_Exe,\r\n        TSR::TestInstaller_Msix,\r\n        TSR::TestInstaller_MSStore,\r\n        TSR::TestInstaller_Portable,\r\n        }));\r\n    OverrideForShellExecute(context);\r\n    OverrideForMSIX(context);\r\n    OverrideForMSStore(context, true);\r\n    OverrideForPortableInstall(context);\r\n    context.Args.AddArg(Execution::Args::Type::All);\r\n    context.Args.AddArg(Execution::Args::Type::Silent);\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify installers are called with the silent flags\r\n    REQUIRE(std::filesystem::exists(updateExeResultPath.GetPath()));\r\n    std::ifstream updateExeResultFile(updateExeResultPath.GetPath());\r\n    std::string updateExeResultStr;\r\n    std::getline(updateExeResultFile, updateExeResultStr);\r\n    REQUIRE(updateExeResultStr.find(\"/silence\") != std::string::npos);\r\n\r\n    REQUIRE(std::filesystem::exists(updateMsixResultPath.GetPath()));\r\n    REQUIRE(std::filesystem::exists(updateMSStoreResultPath.GetPath()));\r\n    REQUIRE(std::filesystem::exists(updatePortableResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_UpdateMultiple\", \"[UpdateFlow][workflow][MultiQuery]\")\r\n{\r\n    TestCommon::TempFile exeUpdateResultPath(\"TestExeInstalled.txt\");\r\n    TestCommon::TempFile msixUpdateResultPath(\"TestMsixInstalled.txt\");\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Exe, TSR::TestInstaller_Msix }));\r\n    OverrideForShellExecute(context);\r\n    OverrideForMSIX(context);\r\n    context.Args.AddArg(Execution::Args::Type::MultiQuery, TSR::TestInstaller_Exe.Query);\r\n    context.Args.AddArg(Execution::Args::Type::MultiQuery, TSR::TestInstaller_Msix.Query);\r\n\r\n    UpgradeCommand update({});\r\n    update.Execute(context);\r\n    INFO(updateOutput.str());\r\n\r\n    // Verify Installers are called called.\r\n    REQUIRE(std::filesystem::exists(exeUpdateResultPath.GetPath()));\r\n    REQUIRE(std::filesystem::exists(exeUpdateResultPath.GetPath()));\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_UpdateMultiple_NotAllFound\", \"[UpdateFlow][workflow][MultiQuery]\")\r\n{\r\n    TestCommon::TempFile exeUpdateResultPath(\"TestExeInstalled.txt\");\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Exe }));\r\n    context.Args.AddArg(Execution::Args::Type::MultiQuery, TSR::TestInstaller_Exe.Query);\r\n    context.Args.AddArg(Execution::Args::Type::MultiQuery, TSR::TestInstaller_Msix.Query);\r\n\r\n    SECTION(\"Ignore unavailable\")\r\n    {\r\n        OverrideForShellExecute(context);\r\n        context.Args.AddArg(Execution::Args::Type::IgnoreUnavailable);\r\n\r\n        UpgradeCommand update({});\r\n        update.Execute(context);\r\n        INFO(updateOutput.str());\r\n\r\n        REQUIRE(!context.IsTerminated());\r\n        REQUIRE(std::filesystem::exists(exeUpdateResultPath.GetPath()));\r\n    }\r\n    SECTION(\"Don't ignore unavailable\")\r\n    {\r\n        UpgradeCommand update({});\r\n        update.Execute(context);\r\n        INFO(updateOutput.str());\r\n\r\n        REQUIRE_TERMINATED_WITH(context, APPINSTALLER_CLI_ERROR_NOT_ALL_QUERIES_FOUND_SINGLE);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"UpdateFlow_UpdateWithReboot\", \"[UpdateFlow][workflow][reboot]\")\r\n{\r\n    TestCommon::TestUserSettings testSettings;\r\n\r\n    std::ostringstream updateOutput;\r\n    TestContext context{ updateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n    OverrideForCompositeInstalledSource(context, CreateTestSource({ TSR::TestInstaller_Exe_ExpectedReturnCodes }));\r\n\r\n    context.Args.AddArg(Execution::Args::Type::Query, TSR::TestInstaller_Exe_ExpectedReturnCodes.Query);\r\n    context.Args.AddArg(Execution::Args::Type::AllowReboot);\r\n\r\n    context.Override({ AppInstaller::CLI::Workflow::ShellExecuteInstallImpl, [&](TestContext& context)\r\n    {\r\n        // APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_TO_FINISH (not treated as an installer error)\r\n        context.Add<Data::OperationReturnCode>(9);\r\n    } });\r\n\r\n    SECTION(\"Reboot success\")\r\n    {\r\n        TestHook::SetInitiateRebootResult_Override initiateRebootResultOverride(true);\r\n\r\n        UpgradeCommand update({});\r\n        update.Execute(context);\r\n        INFO(updateOutput.str());\r\n\r\n        REQUIRE_FALSE(context.IsTerminated());\r\n        REQUIRE(updateOutput.str().find(Resource::LocString(Resource::String::InitiatingReboot).get()) != std::string::npos);\r\n        REQUIRE_FALSE(updateOutput.str().find(Resource::LocString(Resource::String::FailedToInitiateReboot).get()) != std::string::npos);\r\n    }\r\n    SECTION(\"Reboot failed\")\r\n    {\r\n        TestHook::SetInitiateRebootResult_Override initiateRebootResultOverride(false);\r\n\r\n        UpgradeCommand update({});\r\n        update.Execute(context);\r\n        INFO(updateOutput.str());\r\n\r\n        REQUIRE_FALSE(context.IsTerminated());\r\n        REQUIRE(updateOutput.str().find(Resource::LocString(Resource::String::InitiatingReboot).get()) != std::string::npos);\r\n        REQUIRE(updateOutput.str().find(Resource::LocString(Resource::String::FailedToInitiateReboot).get()) != std::string::npos);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/UserSettings.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"TestCommon.h\"\n#include \"TestSettings.h\"\n#include <AppInstallerRuntime.h>\n#include <winget/Settings.h>\n#include \"AppInstallerLogging.h\"\n\n#include <AppInstallerErrors.h>\n\n#include <filesystem>\n#include <string>\n#include <chrono>\n\nusing namespace AppInstaller::Settings;\nusing namespace AppInstaller::Logging;\nusing namespace AppInstaller::Runtime;\nusing namespace TestCommon;\nusing namespace std::string_literals;\nusing namespace std::string_view_literals;\nusing namespace std::chrono_literals;\n\nnamespace\n{\n    static constexpr std::string_view s_goodJson = \"{}\";\n    static constexpr std::string_view s_badJson = \"{\";\n    static constexpr std::string_view s_settings = \"settings.json\"sv;\n    static constexpr std::string_view s_settingsBackup = \"settings.json.backup\"sv;\n}\n\nTEST_CASE(\"UserSettingsFilePaths\", \"[settings]\")\n{\n    auto settingsPath = UserSettings::SettingsFilePath();\n    auto expectedPath = GetPathTo(PathName::UserFileSettings) / \"settings.json\";\n    REQUIRE(settingsPath == expectedPath);\n}\n\nTEST_CASE(\"UserSettingsType\", \"[settings]\")\n{\n    // These are all the possible combinations between (7 of them are impossible):\n    // 1 - No settings.json file exists\n    // 2 - Bad settings.json file\n    // 3 - No settings.json.backup file exists\n    // 4 - Bad settings.json.backup file exists.\n    auto again = DeleteUserSettingsFiles();\n\n    SECTION(\"No setting.json No setting.json.backup\")\n    {\n        UserSettingsTest userSettingTest;\n        REQUIRE(userSettingTest.GetType() == UserSettingsType::Default);\n    }\n    SECTION(\"No setting.json Bad setting.json.backup\")\n    {\n        SetSetting(Stream::BackupUserSettings, s_badJson);\n\n        UserSettingsTest userSettingTest;\n        REQUIRE(userSettingTest.GetType() == UserSettingsType::Default);\n    }\n    SECTION(\"No setting.json Good setting.json.backup\")\n    {\n        SetSetting(Stream::BackupUserSettings, s_goodJson);\n\n        UserSettingsTest userSettingTest;\n        REQUIRE(userSettingTest.GetType() == UserSettingsType::Backup);\n    }\n    SECTION(\"Bad setting.json No setting.json.backup\")\n    {\n        SetSetting(Stream::PrimaryUserSettings, s_badJson);\n\n        UserSettingsTest userSettingTest;\n        REQUIRE(userSettingTest.GetType() == UserSettingsType::Default);\n    }\n    SECTION(\"Bad setting.json Bad setting.json.backup\")\n    {\n        SetSetting(Stream::PrimaryUserSettings, s_badJson);\n        SetSetting(Stream::BackupUserSettings, s_badJson);\n\n        UserSettingsTest userSettingTest;\n        REQUIRE(userSettingTest.GetType() == UserSettingsType::Default);\n    }\n    SECTION(\"Bad setting.json Good setting.json.backup\")\n    {\n        SetSetting(Stream::PrimaryUserSettings, s_badJson);\n        SetSetting(Stream::BackupUserSettings, s_goodJson);\n\n        UserSettingsTest userSettingTest;\n        REQUIRE(userSettingTest.GetType() == UserSettingsType::Backup);\n    }\n    SECTION(\"Good setting.json No setting.json.backup\")\n    {\n        SetSetting(Stream::PrimaryUserSettings, s_goodJson);\n\n        UserSettingsTest userSettingTest;\n        REQUIRE(userSettingTest.GetType() == UserSettingsType::Standard);\n    }\n    SECTION(\"Good setting.json Bad setting.json.backup\")\n    {\n        SetSetting(Stream::PrimaryUserSettings, s_goodJson);\n        SetSetting(Stream::BackupUserSettings, s_badJson);\n\n        UserSettingsTest userSettingTest;\n        REQUIRE(userSettingTest.GetType() == UserSettingsType::Standard);\n    }\n    SECTION(\"Good setting.json Good setting.json.backup\")\n    {\n        SetSetting(Stream::PrimaryUserSettings, s_goodJson);\n        SetSetting(Stream::BackupUserSettings, s_goodJson);\n\n        UserSettingsTest userSettingTest;\n        REQUIRE(userSettingTest.GetType() == UserSettingsType::Standard);\n    }\n}\n\nTEST_CASE(\"UserSettingsCreateFiles\", \"[settings]\")\n{\n    auto again = DeleteUserSettingsFiles();\n\n    auto settingsPath = UserSettings::SettingsFilePath();\n    auto settingsBackupPath = GetPathTo(Stream::BackupUserSettings);\n\n    SECTION(\"No settings.json create new\")\n    {\n        REQUIRE(!std::filesystem::exists(settingsPath));\n        REQUIRE(!std::filesystem::exists(settingsBackupPath));\n\n        UserSettingsTest userSettingTest;\n        REQUIRE(userSettingTest.GetType() == UserSettingsType::Default);\n        userSettingTest.PrepareToShellExecuteFile();\n\n        REQUIRE(std::filesystem::exists(settingsPath));\n        REQUIRE(!std::filesystem::exists(settingsBackupPath));\n    }\n    SECTION(\"Good settings.json create new backup\")\n    {\n        SetSetting(Stream::PrimaryUserSettings, s_goodJson);\n        REQUIRE(std::filesystem::exists(settingsPath));\n        REQUIRE(!std::filesystem::exists(settingsBackupPath));\n\n        UserSettingsTest userSettingTest;\n        REQUIRE(userSettingTest.GetType() == UserSettingsType::Standard);\n        userSettingTest.PrepareToShellExecuteFile();\n\n        REQUIRE(std::filesystem::exists(settingsPath));\n        REQUIRE(std::filesystem::exists(settingsBackupPath));\n    }\n}\n\nTEST_CASE(\"SettingProgressBar\", \"[settings]\")\n{\n    auto again = DeleteUserSettingsFiles();\n\n    SECTION(\"Default value\")\n    {\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::ProgressBarVisualStyle>() == VisualStyle::Accent);\n        REQUIRE(userSettingTest.GetWarnings().size() == 0);\n    }\n    SECTION(\"Accent\")\n    {\n        std::string_view json = R\"({ \"visual\": { \"progressBar\": \"accent\" } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::ProgressBarVisualStyle>() == VisualStyle::Accent);\n        REQUIRE(userSettingTest.GetWarnings().size() == 0);\n    }\n    SECTION(\"Rainbow\")\n    {\n        std::string_view json = R\"({ \"visual\": { \"progressBar\": \"rainbow\" } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::ProgressBarVisualStyle>() == VisualStyle::Rainbow);\n        REQUIRE(userSettingTest.GetWarnings().size() == 0);\n    }\n    SECTION(\"retro\")\n    {\n        std::string_view json = R\"({ \"visual\": { \"progressBar\": \"retro\" } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::ProgressBarVisualStyle>() == VisualStyle::Retro);\n        REQUIRE(userSettingTest.GetWarnings().size() == 0);\n    }\n    SECTION(\"Bad value\")\n    {\n        std::string_view json = R\"({ \"visual\": { \"progressBar\": \"fake\" } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::ProgressBarVisualStyle>() == VisualStyle::Accent);\n        REQUIRE(userSettingTest.GetWarnings().size() == 1);\n    }\n    SECTION(\"Bad value type\")\n    {\n        std::string_view json = R\"({ \"visual\": { \"progressBar\": 5 } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::ProgressBarVisualStyle>() == VisualStyle::Accent);\n        REQUIRE(userSettingTest.GetWarnings().size() == 1);\n    }\n}\n\nTEST_CASE(\"SettingsAnonymizePathForDisplay\", \"[settings]\")\n{\n    auto again = DeleteUserSettingsFiles();\n\n    SECTION(\"Default\")\n    {\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::AnonymizePathForDisplay>() == true);\n        REQUIRE(userSettingTest.GetWarnings().size() == 0);\n    }\n    SECTION(\"True\")\n    {\n        std::string_view json = R\"({ \"visual\": { \"anonymizeDisplayedPaths\": true } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::AnonymizePathForDisplay>() == true);\n        REQUIRE(userSettingTest.GetWarnings().size() == 0);\n    }\n    SECTION(\"False\")\n    {\n        std::string_view json = R\"({ \"visual\": { \"anonymizeDisplayedPaths\": false } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::AnonymizePathForDisplay>() == false);\n        REQUIRE(userSettingTest.GetWarnings().size() == 0);\n    }\n    SECTION(\"Invalid Value\")\n    {\n        std::string_view json = R\"({ \"visual\": { \"anonymizeDisplayedPaths\": \"notBoolean\" } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::AnonymizePathForDisplay>() == true);\n        REQUIRE(userSettingTest.GetWarnings().size() == 1);\n    }\n}\n\nTEST_CASE(\"SettingLoggingLevelPreference\", \"[settings]\")\n{\n    auto again = DeleteUserSettingsFiles();\n\n    SECTION(\"Default value\")\n    {\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::LoggingLevelPreference>() == Level::Info);\n        REQUIRE(userSettingTest.GetWarnings().size() == 0);\n    }\n    SECTION(\"Info\")\n    {\n        std::string_view json = R\"({ \"logging\": { \"level\": \"info\" } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::LoggingLevelPreference>() == Level::Info);\n        REQUIRE(userSettingTest.GetWarnings().size() == 0);\n    }\n    SECTION(\"Verbose\")\n    {\n        std::string_view json = R\"({ \"logging\": { \"level\": \"verbose\" } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::LoggingLevelPreference>() == Level::Verbose);\n        REQUIRE(userSettingTest.GetWarnings().size() == 0);\n    }\n    SECTION(\"Warning\")\n    {\n        std::string_view json = R\"({ \"logging\": { \"level\": \"warning\" } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::LoggingLevelPreference>() == Level::Warning);\n        REQUIRE(userSettingTest.GetWarnings().size() == 0);\n    }\n    SECTION(\"Error\")\n    {\n        std::string_view json = R\"({ \"logging\": { \"level\": \"error\" } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::LoggingLevelPreference>() == Level::Error);\n        REQUIRE(userSettingTest.GetWarnings().size() == 0);\n    }\n    SECTION(\"Critical\")\n    {\n        std::string_view json = R\"({ \"logging\": { \"level\": \"critical\" } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::LoggingLevelPreference>() == Level::Crit);\n        REQUIRE(userSettingTest.GetWarnings().size() == 0);\n    }\n    SECTION(\"Bad value\")\n    {\n        std::string_view json = R\"({ \"logging\": { \"level\": \"fake\" } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::LoggingLevelPreference>() == Level::Info);\n        REQUIRE(userSettingTest.GetWarnings().size() == 1);\n    }\n    SECTION(\"Bad value type\")\n    {\n        std::string_view json = R\"({ \"logging\": { \"level\": 5 } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::LoggingLevelPreference>() == Level::Info);\n        REQUIRE(userSettingTest.GetWarnings().size() == 1);\n    }\n}\n\nTEST_CASE(\"SettingAutoUpdateIntervalInMinutes\", \"[settings]\")\n{\n    auto again = DeleteUserSettingsFiles();\n\n    constexpr static auto cinq = 5min;\n    constexpr static auto cero = 0min;\n    constexpr static auto threehundred = 300min;\r\n\r\n    std::chrono::minutes defaultAutoUpdateTime{};\r\n\r\n    {\n        SetSetting(Stream::PrimaryUserSettings, \"\");\n        UserSettingsTest userSettingTest;\n        defaultAutoUpdateTime = userSettingTest.Get<Setting::AutoUpdateTimeInMinutes>();\r\n    }\n\n    SECTION(\"Valid value 0\")\n    {\n        std::string_view json = R\"({ \"source\": { \"autoUpdateIntervalInMinutes\": 0 } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::AutoUpdateTimeInMinutes>() == cero);\n        REQUIRE(userSettingTest.GetWarnings().size() == 0);\n    }\n    SECTION(\"Valid value 300\")\n    {\n        std::string_view json = R\"({ \"source\": { \"autoUpdateIntervalInMinutes\": 300 } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::AutoUpdateTimeInMinutes>() == threehundred);\n        REQUIRE(userSettingTest.GetWarnings().size() == 0);\n    }\n    SECTION(\"Invalid type negative integer\")\n    {\n        std::string_view json = R\"({ \"source\": { \"autoUpdateIntervalInMinutes\": -20 } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::AutoUpdateTimeInMinutes>() == defaultAutoUpdateTime);\n        REQUIRE(userSettingTest.GetWarnings().size() == 1);\n    }\n    SECTION(\"Invalid type string\")\n    {\n        std::string_view json = R\"({ \"source\": { \"autoUpdateIntervalInMinutes\": \"not a number\" } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::AutoUpdateTimeInMinutes>() == defaultAutoUpdateTime);\n        REQUIRE(userSettingTest.GetWarnings().size() == 1);\n    }\n    SECTION(\"Overridden by Group Policy\")\n    {\n        auto policiesKey = RegCreateVolatileTestRoot();\n        SetRegistryValue(policiesKey.get(), SourceUpdateIntervalPolicyValueName, (DWORD)threehundred.count());\n        GroupPolicyTestOverride policies{ policiesKey.get() };\n\n        std::string_view json = R\"({ \"source\": { \"autoUpdateIntervalInMinutes\": 5 } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::AutoUpdateTimeInMinutes>() == threehundred);\n        REQUIRE(userSettingTest.GetWarnings().size() == 0);\n    }\n    SECTION(\"Invalid Group Policy\")\n    {\n        auto policiesKey = RegCreateVolatileTestRoot();\n        SetRegistryValue(policiesKey.get(), SourceUpdateIntervalPolicyValueName, L\"Not a number\"s);\n        GroupPolicyTestOverride policies{ policiesKey.get() };\n\n        std::string_view json = R\"({ \"source\": { \"autoUpdateIntervalInMinutes\": 5 } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::AutoUpdateTimeInMinutes>() == cinq);\n        REQUIRE(userSettingTest.GetWarnings().size() == 0);\n    }\n}\n\nTEST_CASE(\"SettingsExperimentalCmd\", \"[settings]\")\n{\n    auto again = DeleteUserSettingsFiles();\n\n    SECTION(\"Feature off default\")\n    {\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(!userSettingTest.Get<Setting::EFExperimentalCmd>());\n        REQUIRE(userSettingTest.GetWarnings().size() == 0);\n    }\n    SECTION(\"Feature on\")\n    {\n        std::string_view json = R\"({ \"experimentalFeatures\": { \"experimentalCmd\": true } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::EFExperimentalCmd>());\n        REQUIRE(userSettingTest.GetWarnings().size() == 0);\n    }\n    SECTION(\"Feature off\")\n    {\n        std::string_view json = R\"({ \"experimentalFeatures\": { \"experimentalCmd\": false } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(!userSettingTest.Get<Setting::EFExperimentalCmd>());\n        REQUIRE(userSettingTest.GetWarnings().size() == 0);\n    }\n    SECTION(\"Invalid value\")\n    {\n        std::string_view json = R\"({ \"experimentalFeatures\": { \"experimentalCmd\": \"string\" } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(!userSettingTest.Get<Setting::EFExperimentalCmd>());\n        REQUIRE(userSettingTest.GetWarnings().size() == 1);\n    }\n    SECTION(\"Disabled by group policy\")\n    {\n        auto policiesKey = RegCreateVolatileTestRoot();\n        SetRegistryValue(policiesKey.get(), SourceUpdateIntervalPolicyValueName, L\"Not a number\"s);\n        GroupPolicyTestOverride policies{ policiesKey.get() };\n\n        std::string_view json = R\"({ \"experimentalFeatures\": { \"experimentalCmd\": true } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        // Experimental features group policy is applied at the ExperimentalFeature level,\n        // so it doesn't affect the settings.\n        REQUIRE(userSettingTest.Get<Setting::EFExperimentalCmd>());\n        REQUIRE(userSettingTest.GetWarnings().size() == 0);\n    }\n}\n\nTEST_CASE(\"SettingsPortablePackageUserRoot\", \"[settings]\")\n{\n    auto again = DeleteUserSettingsFiles();\n\n    SECTION(\"Relative path\")\n    {\n        std::string_view json = R\"({ \"installBehavior\": { \"portablePackageUserRoot\": \"%LOCALAPPDATA%/Portable/Root\" } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n        \n        REQUIRE(userSettingTest.Get<Setting::PortablePackageUserRoot>().empty());\n\n        auto warnings = userSettingTest.GetWarnings();\n        REQUIRE(warnings.size() == 1);\n        REQUIRE(warnings[0].Message == AppInstaller::StringResource::String::SettingsWarningInvalidFieldValue);\n        REQUIRE(warnings[0].Path == \".installBehavior.portablePackageUserRoot\");\n    }\n    SECTION(\"Valid path\")\n    {\n        std::string_view json = R\"({ \"installBehavior\": { \"portablePackageUserRoot\": \"C:/Foo/Bar\" } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::PortablePackageUserRoot>() == \"C:/Foo/Bar\");\n        REQUIRE(userSettingTest.GetWarnings().size() == 0);\n    }\n}\n\nTEST_CASE(\"SettingsPortablePackageMachineRoot\", \"[settings]\")\n{\n    auto again = DeleteUserSettingsFiles();\n\n    SECTION(\"Relative path\")\n    {\n        std::string_view json = R\"({ \"installBehavior\": { \"portablePackageMachineRoot\": \"%LOCALAPPDATA%/Portable/Root\" } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::PortablePackageMachineRoot>().empty());\n\n        auto warnings = userSettingTest.GetWarnings();\n        REQUIRE(warnings.size() == 1);\n        REQUIRE(warnings[0].Message == AppInstaller::StringResource::String::SettingsWarningInvalidFieldValue);\n        REQUIRE(warnings[0].Path == \".installBehavior.portablePackageMachineRoot\");\n    }\n    SECTION(\"Valid path\")\n    {\n        std::string_view json = R\"({ \"installBehavior\": { \"portablePackageMachineRoot\": \"C:/Foo/Bar\" } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::PortablePackageMachineRoot>() == \"C:/Foo/Bar\");\n        REQUIRE(userSettingTest.GetWarnings().size() == 0);\n    }\n}\n\nTEST_CASE(\"SettingsDownloadDefaultDirectory\", \"[settings]\")\n{\n    auto again = DeleteUserSettingsFiles();\n\n    SECTION(\"Valid path\")\n    {\n        std::string_view json = R\"({ \"downloadBehavior\": { \"defaultDownloadDirectory\": \"C:/Foo/Bar\" } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::DownloadDefaultDirectory>() == \"C:/Foo/Bar\");\n        REQUIRE(userSettingTest.GetWarnings().size() == 0);\n    }\n}\r\n\r\nTEST_CASE(\"SettingsConfigureDefaultModuleRoot\", \"[settings]\")\r\n{\r\n    auto again = DeleteUserSettingsFiles();\n\n    SECTION(\"Valid path\")\n    {\n        std::string_view json = R\"({ \"configureBehavior\": { \"defaultModuleRoot\": \"C:/Foo/Bar\" } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::ConfigureDefaultModuleRoot>() == \"C:/Foo/Bar\");\n        REQUIRE(userSettingTest.GetWarnings().size() == 0);\n    }\r\n}\r\n\r\nTEST_CASE(\"SettingsArchiveExtractionMethod\", \"[settings]\")\r\n{\n    auto again = DeleteUserSettingsFiles();\r\n\r\n    SECTION(\"Shell api\")\r\n    {\n        std::string_view json = R\"({ \"installBehavior\": { \"archiveExtractionMethod\": \"shellApi\" } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::ArchiveExtractionMethod>() == AppInstaller::Archive::ExtractionMethod::ShellApi);\n    }\r\n    SECTION(\"Shell api\")\r\n    {\n        std::string_view json = R\"({ \"installBehavior\": { \"archiveExtractionMethod\": \"tar\" } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::ArchiveExtractionMethod>() == AppInstaller::Archive::ExtractionMethod::Tar);\n    }\n}\n\nTEST_CASE(\"SettingsInstallScope\", \"[settings]\")\n{\n    auto again = DeleteUserSettingsFiles();\n\n    SECTION(\"User scope preference\")\n    {\n        std::string_view json = R\"({ \"installBehavior\": { \"preferences\": { \"scope\": \"user\" } } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::InstallScopePreference>() == AppInstaller::Manifest::ScopeEnum::User);\n    }\n    SECTION(\"Machine scope preference\")\n    {\n        std::string_view json = R\"({ \"installBehavior\": { \"preferences\": { \"scope\": \"machine\" } } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::InstallScopePreference>() == AppInstaller::Manifest::ScopeEnum::Machine);\n    }\n    SECTION(\"User scope requirement\")\n    {\n        std::string_view json = R\"({ \"installBehavior\": { \"requirements\": { \"scope\": \"user\" } } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::InstallScopeRequirement>() == AppInstaller::Manifest::ScopeEnum::User);\n    }\n    SECTION(\"Machine scope requirement\")\n    {\n        std::string_view json = R\"({ \"installBehavior\": { \"requirements\": { \"scope\": \"machine\" } } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::InstallScopeRequirement>() == AppInstaller::Manifest::ScopeEnum::Machine);\n    }\n}\n\nTEST_CASE(\"SettingsMaxResumes\", \"[settings]\")\n{\n    auto again = DeleteUserSettingsFiles();\n\n    SECTION(\"Modify max number of resumes\")\n    {\n        std::string_view json = R\"({ \"installBehavior\": { \"maxResumes\": 5 } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::MaxResumes>() == 5);\n    }\n}\n\nTEST_CASE(\"LoggingChannels\", \"[settings]\")\n{\n    auto again = DeleteUserSettingsFiles();\n\n    SECTION(\"Not provided\")\n    {\n        std::string_view json = R\"({ })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::LoggingChannelPreference>() == Channel::Defaults);\n    }\n    SECTION(\"No channels\")\n    {\n        std::string_view json = R\"({ \"logging\": { \"channels\": [] } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::LoggingChannelPreference>() == Channel::None);\n    }\n    SECTION(\"Default\")\n    {\n        std::string_view json = R\"({ \"logging\": { \"channels\": [\"default\"] } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::LoggingChannelPreference>() == Channel::Defaults);\n    }\n    SECTION(\"Multiple\")\n    {\n        std::string_view json = R\"({ \"logging\": { \"channels\": [\"core\",\"Repo\",\"YAML\"] } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::LoggingChannelPreference>() == (Channel::Core | Channel::Repo | Channel::YAML));\n    }\n    SECTION(\"Some invalid\")\n    {\n        std::string_view json = R\"({ \"logging\": { \"channels\": [\"cli\",\"sql\",\"INVALID\"] } })\";\n        SetSetting(Stream::PrimaryUserSettings, json);\n        UserSettingsTest userSettingTest;\n\n        REQUIRE(userSettingTest.Get<Setting::LoggingChannelPreference>() == (Channel::CLI | Channel::SQL));\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCLITests/Versions.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <AppInstallerRuntime.h>\r\n#include <AppInstallerVersions.h>\r\n\r\nusing namespace AppInstaller;\r\nusing namespace AppInstaller::Utility;\r\n\r\n\r\nTEST_CASE(\"VersionParse\", \"[versions]\")\r\n{\r\n    Version version(\"1.2.3.4-alpha\");\r\n    const auto& parts = version.GetParts();\r\n    REQUIRE(parts.size() == 4);\r\n    for (size_t i = 0; i < parts.size(); ++i)\r\n    {\r\n        INFO(i);\r\n        REQUIRE(parts[i].Integer == static_cast<uint64_t>(i + 1));\r\n        if (i != 3)\r\n        {\r\n            REQUIRE(parts[i].Other == \"\");\r\n        }\r\n        else\r\n        {\r\n            REQUIRE(parts[i].Other == \"-alpha\");\r\n        }\r\n    }\r\n}\r\n\r\nTEST_CASE(\"VersionParsePlusDash\", \"[versions]\")\r\n{\r\n    Version version(\"1.2.3.4-alpha\", \".-\");\r\n    const auto& parts = version.GetParts();\r\n    REQUIRE(parts.size() == 5);\r\n    for (size_t i = 0; i < 4; ++i)\r\n    {\r\n        INFO(i);\r\n        REQUIRE(parts[i].Integer == static_cast<uint64_t>(i + 1));\r\n        REQUIRE(parts[i].Other == \"\");\r\n    }\r\n    REQUIRE(parts[4].Other == \"alpha\");\r\n}\r\n\r\nTEST_CASE(\"VersionParseWithWhitespace\", \"[versions]\")\r\n{\r\n    Version version(\"1. 2.3 . 4 \");\r\n    const auto& parts = version.GetParts();\r\n    REQUIRE(parts.size() == 4);\r\n    for (size_t i = 0; i < parts.size(); ++i)\r\n    {\r\n        INFO(i);\r\n        REQUIRE(parts[i].Integer == static_cast<uint64_t>(i + 1));\r\n        REQUIRE(parts[i].Other == \"\");\r\n    }\r\n}\r\n\r\nTEST_CASE(\"VersionParseWithPreamble\", \"[versions]\")\r\n{\r\n    Version version(\"v1.2.3.4\");\r\n    const auto& parts = version.GetParts();\r\n    REQUIRE(parts.size() == 4);\r\n    for (size_t i = 0; i < parts.size(); ++i)\r\n    {\r\n        INFO(i);\r\n        REQUIRE(parts[i].Integer == static_cast<uint64_t>(i + 1));\r\n        REQUIRE(parts[i].Other == \"\");\r\n    }\r\n}\r\n\r\nTEST_CASE(\"VersionParseCorner\", \"[versions]\")\r\n{\r\n    Version version1(\"\");\r\n    auto parts = version1.GetParts();\r\n    REQUIRE(parts.size() == 0);\r\n\r\n    Version version2(\".\");\r\n    parts = version2.GetParts();\r\n    REQUIRE(parts.size() == 0);\r\n\r\n    Version version3(\".0\");\r\n    parts = version3.GetParts();\r\n    REQUIRE(parts.size() == 0);\r\n\r\n    Version version4(\".1\");\r\n    parts = version4.GetParts();\r\n    REQUIRE(parts.size() == 2);\r\n    REQUIRE(parts[0].Integer == 0);\r\n    REQUIRE(parts[0].Other == \"\");\r\n    REQUIRE(parts[1].Integer == 1);\r\n    REQUIRE(parts[1].Other == \"\");\r\n\r\n    Version version5(\"version\");\r\n    parts = version5.GetParts();\r\n    REQUIRE(parts.size() == 1);\r\n    REQUIRE(parts[0].Integer == 0);\r\n    REQUIRE(parts[0].Other == \"version\");\r\n\r\n    Version version6(\". 1 \");\r\n    parts = version6.GetParts();\r\n    REQUIRE(parts.size() == 2);\r\n    REQUIRE(parts[0].Integer == 0);\r\n    REQUIRE(parts[0].Other == \"\");\r\n    REQUIRE(parts[1].Integer == 1);\r\n    REQUIRE(parts[1].Other == \"\");\r\n\r\n    Version version7(\"v1.2a\");\r\n    parts = version7.GetParts();\r\n    REQUIRE(parts.size() == 2);\r\n    REQUIRE(parts[0].Integer == 1);\r\n    REQUIRE(parts[0].Other == \"\");\r\n    REQUIRE(parts[1].Integer == 2);\r\n    REQUIRE(parts[1].Other == \"a\");\r\n}\r\n\r\nvoid RequireLessThan(std::string_view a, std::string_view b)\r\n{\r\n    Version vA{ std::string(a) };\r\n    Version vB{ std::string(b) };\r\n\r\n    REQUIRE(vA < vB);\r\n    REQUIRE_FALSE(vB < vA);\r\n    REQUIRE(vA <= vB);\r\n    REQUIRE_FALSE(vB <= vA);\r\n    REQUIRE(vB > vA);\r\n    REQUIRE_FALSE(vA > vB);\r\n    REQUIRE(vB >= vA);\r\n    REQUIRE_FALSE(vA >= vB);\r\n    REQUIRE_FALSE(vA == vB);\r\n    REQUIRE(vA != vB);\r\n}\r\n\r\nvoid RequireEqual(std::string_view a, std::string_view b)\r\n{\r\n    Version vA{ std::string(a) };\r\n    Version vB{ std::string(b) };\r\n\r\n    REQUIRE(vA == vB);\r\n    REQUIRE_FALSE(vA != vB);\r\n    REQUIRE(vA <= vB);\r\n    REQUIRE(vA >= vB);\r\n    REQUIRE_FALSE(vA < vB);\r\n    REQUIRE_FALSE(vA > vB);\r\n}\r\n\r\nTEST_CASE(\"VersionCompare\", \"[versions]\")\r\n{\r\n    RequireLessThan(\"1\", \"2\");\r\n    RequireLessThan(\"1.0.0\", \"2.0.0\");\r\n    RequireLessThan(\"0.0.1\", \"0.0.2\");\r\n    RequireLessThan(\"0.0.1-alpha\", \"0.0.2-alpha\");\r\n    RequireLessThan(\"0.0.1-beta\", \"0.0.2-alpha\");\r\n    RequireLessThan(\"0.0.1-beta\", \"0.0.2-alpha\");\r\n    RequireLessThan(\"13.9.8\", \"14.1\");\r\n\r\n    // Ensure that versions with non-digit characters in their parts are sorted correctly\r\n    RequireLessThan(\"1-rc\", \"1\");\r\n    RequireLessThan(\"1.2-rc\", \"1.2\");\r\n    RequireLessThan(\"1.0-rc\", \"1.0\");\r\n    RequireLessThan(\"1.0.0-rc\", \"1\");\r\n    RequireLessThan(\"22.0.0-rc.1\", \"22.0.0\");\r\n    RequireLessThan(\"22.0.0-rc.1\", \"22.0.0.1\");\r\n    RequireLessThan(\"22.0.0-rc.1\", \"22.0.0.1-rc\");\r\n\r\n    // Ensure that Sub-RC versions are sorted correctly\r\n    RequireLessThan(\"22.0.0-rc.1\", \"22.0.0-rc.1.1\");\r\n    RequireLessThan(\"22.0.0-rc.1.1\", \"22.0.0-rc.1.2\");\r\n    RequireLessThan(\"22.0.0-rc.1.2\", \"22.0.0-rc.2\");\r\n\r\n    RequireEqual(\"1.0\", \"1.0.0\");\r\n\r\n    // Ensure that integers are parsed correctly when there is a leading zero\r\n    RequireEqual(\"1.2.00.3\", \"1.2.0.3\");\r\n    RequireEqual(\"1.2.003.4\", \"1.2.3.4\");\r\n    RequireEqual(\"01.02.03.04\", \"1.2.3.4\");\r\n    RequireEqual(\"1.2.03-beta\", \"1.2.3-beta\");\r\n\r\n    // Ensure whitespace doesn't affect equality\r\n    RequireEqual(\"1.0\", \"1.0 \");\r\n    RequireEqual(\"1.0\", \"1. 0\");\r\n    RequireEqual(\"1.0\", \"1.0.\");\r\n\r\n    // Ensure versions with preambles are sorted correctly\r\n    RequireEqual(\"1.0\", \"Version 1.0\");\r\n    RequireEqual(\"foo1\", \"bar1\");\r\n    RequireLessThan(\"v0.0.1\", \"0.0.2\");\r\n    RequireLessThan(\"v0.0.1\", \"v0.0.2\");\r\n    RequireLessThan(\"1.a2\", \"1.b1\");\r\n    RequireLessThan(\"alpha\", \"beta\");\r\n}\r\n\r\nTEST_CASE(\"VersionAndChannelSort\", \"[versions]\")\r\n{\r\n    std::vector<VersionAndChannel> sortedList =\r\n    {\r\n        { Version(\"15.0.0\"), Channel(\"\") },\r\n        { Version(\"14.0.0\"), Channel(\"\") },\r\n        { Version(\"13.2.1-bugfix\"), Channel(\"\") },\r\n        { Version(\"13.2.0\"), Channel(\"\") },\r\n        { Version(\"13.2.0-rc\"), Channel(\"\") },\r\n        { Version(\"13.0.0\"), Channel(\"\") },\r\n        { Version(\"16.0.0\"), Channel(\"alpha\") },\r\n        { Version(\"15.8.0\"), Channel(\"alpha\") },\r\n        { Version(\"15.1.0\"), Channel(\"beta\") },\r\n    };\r\n\r\n    std::vector<size_t> reorderList = { 4, 2, 1, 7, 6, 3, 8, 5, 0 };\r\n    REQUIRE(sortedList.size() == reorderList.size());\r\n\r\n    std::vector<VersionAndChannel> jumbledList;\r\n    for (auto i : reorderList)\r\n    {\r\n        jumbledList.emplace_back(sortedList[i]);\r\n    }\r\n\r\n    std::sort(jumbledList.begin(), jumbledList.end());\r\n\r\n    for (size_t i = 0; i < jumbledList.size(); ++i)\r\n    {\r\n        const VersionAndChannel& sortedVAC = sortedList[i];\r\n        const VersionAndChannel& jumbledVAC = jumbledList[i];\r\n\r\n        INFO(i);\r\n        REQUIRE(sortedVAC.GetVersion().ToString() == jumbledVAC.GetVersion().ToString());\r\n        REQUIRE(sortedVAC.GetChannel().ToString() == jumbledVAC.GetChannel().ToString());\r\n    }\r\n}\r\n\r\nTEST_CASE(\"MinOsVersion_Check\", \"[versions]\")\r\n{\r\n    // Just verify that we are greater than Win 7 and less than far future Win 10.\r\n    // Unfortunately, an unmanifested process will also pass these validations,\r\n    // but an unmanifested process also can't use Windows APIs to determine the actual version.\r\n    REQUIRE(Runtime::IsCurrentOSVersionGreaterThanOrEqual(Version(\"6.1\")));\r\n    REQUIRE(!Runtime::IsCurrentOSVersionGreaterThanOrEqual(Version(\"10.0.65535\")));\r\n}\r\n\r\nTEST_CASE(\"VersionLatest\", \"[versions]\")\r\n{\r\n    REQUIRE(Version::CreateLatest().IsLatest());\r\n    REQUIRE(Version(\"latest\").IsLatest());\r\n    REQUIRE(Version(\"LATEST\").IsLatest());\r\n    REQUIRE(!Version(\"1.0\").IsLatest());\r\n\r\n    RequireLessThan(\"1.0\", \"latest\");\r\n    RequireLessThan(\"100\", \"latest\");\r\n    RequireLessThan(\"943849587389754876.1\", \"latest\");\r\n\r\n    RequireEqual(\"latest\", \"LATEST\");\r\n}\r\n\r\nTEST_CASE(\"VersionUnknown\", \"[versions]\")\r\n{\r\n    REQUIRE(Version::CreateUnknown().IsUnknown());\r\n    REQUIRE(Version(\"unknown\").IsUnknown());\r\n    REQUIRE(Version(\"UNKNOWN\").IsUnknown());\r\n    REQUIRE(!Version(\"1.0\").IsUnknown());\r\n\r\n    RequireLessThan(\"unknown\", \"1.0\");\r\n    RequireLessThan(\"unknown\", \"1.fork\");\r\n\r\n    RequireEqual(\"unknown\", \"UNKNOWN\");\r\n}\r\n\r\nTEST_CASE(\"VersionUnknownLessThanLatest\", \"[versions]\")\r\n{\r\n    REQUIRE(Version::CreateUnknown() < Version::CreateLatest());\r\n}\r\n\r\nTEST_CASE(\"VersionIsEmpty\", \"[versions]\")\r\n{\r\n    REQUIRE(Version{}.IsEmpty());\r\n    REQUIRE(Version{\"\"}.IsEmpty());\r\n    REQUIRE(!Version{\"1\"}.IsEmpty());\r\n    REQUIRE(!Version{\"0\"}.IsEmpty());\r\n\r\n    Version v{ \"1\" };\r\n    REQUIRE(!v.IsEmpty());\r\n    v.Assign(\"\");\r\n    REQUIRE(v.IsEmpty());\r\n}\r\n\r\nTEST_CASE(\"VersionPartAt\", \"[versions]\")\r\n{\r\n    REQUIRE(Version{}.PartAt(0).Integer == 0);\r\n    REQUIRE(Version{\"1\"}.PartAt(0).Integer == 1);\r\n    REQUIRE(Version{\"1\"}.PartAt(1).Integer == 0);\r\n    REQUIRE(Version{\"1\"}.PartAt(9999).Integer == 0);\r\n}\r\n\r\nTEST_CASE(\"UInt64Version_Success_FourParts\", \"[versions]\")\r\n{\r\n    Version expectedVersion(\"1.2.3.4\");\r\n    UInt64Version versionNumberFromNumber(0x0001000200030004);\r\n    UInt64Version versionNumberFromString(\"1.2.3.4\");\r\n    REQUIRE(expectedVersion == versionNumberFromNumber);\r\n    REQUIRE(expectedVersion == versionNumberFromString);\r\n    REQUIRE(expectedVersion.ToString() == versionNumberFromNumber.ToString());\r\n    REQUIRE(expectedVersion.ToString() == versionNumberFromString.ToString());\r\n}\r\n\r\nTEST_CASE(\"UInt64Version_Success_LessThanFourParts\", \"[versions]\")\r\n{\r\n    UInt64Version versionNumberFromNumber(0x0001000200030000);\r\n    UInt64Version versionNumberFromString(\"1.2.3\");\r\n    REQUIRE(versionNumberFromNumber == versionNumberFromString);\r\n}\r\n\r\nTEST_CASE(\"UInt64Version_Success_NoOverflow\", \"[versions]\")\r\n{\r\n    REQUIRE_NOTHROW(UInt64Version(\"65535.65535.65535.65535\")); // 65535 => 0xffff\r\n    REQUIRE_NOTHROW(UInt64Version(0xffffffffffffffff));\r\n}\r\n\r\nTEST_CASE(\"UInt64Version_Fail_Overflow\", \"[versions]\")\r\n{\r\n    REQUIRE_THROWS(UInt64Version(\"1.0.0.65536\")); // 65536 => 0x10000\r\n}\r\n\r\nTEST_CASE(\"UInt64Version_Fail_MoreThanFourParts\", \"[versions]\")\r\n{\r\n    REQUIRE_THROWS(UInt64Version(\"1.0.0.0.1\"));\r\n}\r\n\r\nTEST_CASE(\"UInt64Version_Fail_NonNumeric\", \"[versions]\")\r\n{\r\n    REQUIRE_THROWS(UInt64Version(\"1.0.0.a\"));\r\n}\r\n\r\nTEST_CASE(\"ApproximateVersionParse\", \"[versions]\")\r\n{\r\n    Version v1_0{ \"1.0\" };\r\n    Version v1_0_LessThan{ v1_0, Version::ApproximateComparator::LessThan };\r\n    Version v1_0_GreaterThan{ v1_0, Version::ApproximateComparator::GreaterThan };\r\n\r\n    Version v1_0_LessThanFromString = Version{ \"< 1.0\" };\r\n    Version v1_0_GreaterThanFromString = Version{ \"> 1.0\" };\r\n\r\n    REQUIRE_FALSE(v1_0.IsApproximate());\r\n    REQUIRE(v1_0_LessThanFromString.IsApproximate());\r\n    REQUIRE(v1_0_GreaterThanFromString.IsApproximate());\r\n\r\n    REQUIRE(v1_0_LessThan == v1_0_LessThanFromString);\r\n    REQUIRE(v1_0_GreaterThan == v1_0_GreaterThanFromString);\r\n\r\n    REQUIRE_THROWS(Version{ \"< Unknown\" });\r\n    REQUIRE_THROWS(Version{ v1_0_LessThan, Version::ApproximateComparator::LessThan });\r\n    REQUIRE_THROWS(Version{ Version::CreateUnknown(), Version::ApproximateComparator::LessThan });\r\n}\r\n\r\nTEST_CASE(\"ApproximateVersionCompare\", \"[versions]\")\r\n{\r\n    RequireEqual(\"< 1.0\", \"< 1.0\");\r\n    RequireEqual(\"< 1.0\", \"< 1.0.0\");\r\n    RequireEqual(\"> 1.0\", \"> 1.0\");\r\n    RequireEqual(\"> 1.0\", \"> 1.0.0\");\r\n\r\n    RequireLessThan(\"< 1.0\", \"1.0\");\r\n    RequireLessThan(\"< 1.0\", \"> 1.0\");\r\n    RequireLessThan(\"1.0\", \"> 1.0\");\r\n    RequireLessThan(\"0.9\", \"< 1.0\");\r\n    RequireLessThan(\"> 1.0\", \"1.1\");\r\n\r\n    // With latest\r\n    RequireLessThan(\"< latest\", \"latest\");\r\n    RequireLessThan(\"latest\", \"> latest\");\r\n    RequireLessThan(\"9999\", \"< latest\");\r\n}\r\n\r\nTEST_CASE(\"VersionRange\", \"[versions]\")\r\n{\r\n    // Create\r\n    REQUIRE_NOTHROW(VersionRange{ Version{ \"1.0\" }, Version{ \"2.0\" } });\r\n    REQUIRE_NOTHROW(VersionRange{ Version{ \"1.0\" }, Version{ \"1.0\" } });\r\n    REQUIRE_NOTHROW(VersionRange{ Version{ \"2.0\" }, Version{ \"1.0\" } });\r\n\r\n    // Overlaps\r\n    REQUIRE(VersionRange{ Version{ \"1.0\" }, Version{ \"2.0\" } }.Overlaps(VersionRange{ Version{ \"2.0\" }, Version{ \"3.0\" } }));\r\n    REQUIRE(VersionRange{ Version{ \"1.0\" }, Version{ \"2.0\" } }.Overlaps(VersionRange{ Version{ \"1.0\" }, Version{ \"1.0\" } }));\r\n    REQUIRE(VersionRange{ Version{ \"1.0\" }, Version{ \"2.0\" } }.Overlaps(VersionRange{ Version{ \"0.5\" }, Version{ \"1.5\" } }));\r\n    REQUIRE_FALSE(VersionRange{ Version{ \"1.0\" }, Version{ \"2.0\" } }.Overlaps(VersionRange{ Version{ \"2.1\" }, Version{ \"3.0\" } }));\r\n    REQUIRE_FALSE(VersionRange{ Version{ \"1.0\" }, Version{ \"2.0\" } }.Overlaps(VersionRange{}));\r\n\r\n    // Empty\r\n    REQUIRE(VersionRange{}.IsEmpty());\r\n    REQUIRE_THROWS(VersionRange{}.GetMinVersion());\r\n    REQUIRE_THROWS(VersionRange{}.GetMaxVersion());\r\n\r\n    // Less than compare\r\n    REQUIRE_THROWS(VersionRange{ Version{ \"0.5\" }, Version{ \"1.0\" } } < VersionRange{ Version{ \"1.0\" }, Version{ \"2.0\" } });\r\n    REQUIRE_THROWS(VersionRange{} < VersionRange{ Version{ \"1.0\" }, Version{ \"2.0\" } });\r\n    REQUIRE(VersionRange{ Version{ \"0.5\" }, Version{ \"1.0\" } } < VersionRange{ Version{ \"1.5\" }, Version{ \"2.0\" } });\r\n    REQUIRE_FALSE(VersionRange{ Version{ \"1.5\" }, Version{ \"2.0\" } } < VersionRange{ Version{ \"0.5\" }, Version{ \"1.0\" } });\r\n}\r\n\r\nTEST_CASE(\"GatedVersion\", \"[versions]\")\r\n{\r\n    REQUIRE(GatedVersion(\"1.0.*\"sv).IsValidVersion({ \"1.0.1\" }));\r\n    REQUIRE(GatedVersion(\"1.0.*\"sv).IsValidVersion({ \"1.0\" }));\r\n    REQUIRE(GatedVersion(\"1.0.*\"sv).IsValidVersion({ \"1\" }));\r\n    REQUIRE(GatedVersion(\"1.0.*\"sv).IsValidVersion({ \"1.0.alpha\" }));\r\n    REQUIRE(GatedVersion(\"1.0.*\"sv).IsValidVersion({ \"1.0.1.2.3\" }));\r\n    REQUIRE(GatedVersion(\"1.0.*\"sv).IsValidVersion({ \"1.0.*\" }));\r\n    REQUIRE_FALSE(GatedVersion(\"1.0.*\"sv).IsValidVersion({ \"1.1.1\" }));\r\n\r\n    REQUIRE(GatedVersion(\"1.*.*\"sv).IsValidVersion({ \"1.*.1\" }));\r\n    REQUIRE(GatedVersion(\"1.*.*\"sv).IsValidVersion({ \"1.*.*\" }));\r\n    REQUIRE_FALSE(GatedVersion(\"1.*.*\"sv).IsValidVersion({ \"1.1.1\" }));\r\n\r\n    REQUIRE(GatedVersion(\"1.0.1\"sv).IsValidVersion({ \"1.0.1\" }));\r\n    REQUIRE_FALSE(GatedVersion(\"1.0.1\"sv).IsValidVersion({ \"1.1.1\" }));\r\n}\r\n\r\nTEST_CASE(\"SemanticVersion\", \"[versions]\")\r\n{\r\n    REQUIRE_THROWS_HR(SemanticVersion(\"1.2.3.4\"), E_INVALIDARG);\r\n    REQUIRE_THROWS_HR(SemanticVersion(\"1.2abc.3\"), E_INVALIDARG);\r\n\r\n    SemanticVersion version = SemanticVersion(\"1.2.3-alpha\");\r\n    REQUIRE(version.IsPrerelease());\r\n    REQUIRE(version.PrereleaseVersion() == Version(\"alpha\"));\r\n    REQUIRE(!version.HasBuildMetadata());\r\n    REQUIRE(version.PartAt(2).Other == \"-alpha\");\r\n\r\n    version = SemanticVersion(\"1.2.3-4.5.6\");\r\n    REQUIRE(version.IsPrerelease());\r\n    REQUIRE(version.PrereleaseVersion() == Version(\"4.5.6\"));\r\n    REQUIRE(!version.HasBuildMetadata());\r\n    REQUIRE(version.PartAt(2).Other == \"-4.5.6\");\r\n\r\n    // Really shouldn't be allowed, but we are loose here\r\n    version = SemanticVersion(\"1.2+build\");\r\n    REQUIRE(!version.IsPrerelease());\r\n    REQUIRE(version.HasBuildMetadata());\r\n    REQUIRE(version.BuildMetadata() == Version(\"build\"));\r\n    REQUIRE(version.PartAt(2).Other == \"+build\");\r\n\r\n    version = SemanticVersion(\"1.2.3-beta+4.5.6\");\r\n    REQUIRE(version.IsPrerelease());\r\n    REQUIRE(version.PrereleaseVersion() == Version(\"beta\"));\r\n    REQUIRE(version.HasBuildMetadata());\r\n    REQUIRE(version.BuildMetadata() == Version(\"4.5.6\"));\r\n    REQUIRE(version.PartAt(2).Other == \"-beta+4.5.6\");\r\n}\r\n\r\nTEST_CASE(\"OpenTypeFontVersion\", \"[versions]\")\r\n{\r\n    // Valid font version.\r\n    OpenTypeFontVersion version = OpenTypeFontVersion(\"Version 1.234\");\r\n    REQUIRE(version.ToString() == \"1.234\");\r\n    REQUIRE(version.GetParts().size() == 2);\r\n    REQUIRE(version.PartAt(0).Integer == 1);\r\n    REQUIRE(version.PartAt(1).Integer == 234);\r\n\r\n    // Font version with additional metadata.\r\n    version = OpenTypeFontVersion(\"Version 9.876.54 ;2024\");\r\n    REQUIRE(version.ToString() == \"9.876\");\r\n    REQUIRE(version.GetParts().size() == 2);\r\n    REQUIRE(version.PartAt(0).Integer == 9);\r\n    REQUIRE(version.PartAt(1).Integer == 876);\r\n\r\n    // Invalid version. Font version must have at least 2 parts.\r\n    REQUIRE_NOTHROW(version = OpenTypeFontVersion(\"1234567\"));\r\n    REQUIRE(version.IsUnknown());\r\n    REQUIRE(version.ToString() == \"Unknown\");\r\n\r\n    // Major and minor parts must have digits.\r\n    REQUIRE_NOTHROW(version = OpenTypeFontVersion(\" abc.def \"));\r\n    REQUIRE(version.IsUnknown());\r\n    REQUIRE(version.ToString() == \"Unknown\");\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/WindowsFeature.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"WorkflowCommon.h\"\r\n#include <AppInstallerRuntime.h>\r\n#include <Commands/InstallCommand.h>\r\n#include \"TestHooks.h\"\r\n\r\nusing namespace AppInstaller::CLI;\r\nusing namespace AppInstaller::Settings;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace TestCommon;\r\n\r\nTEST_CASE(\"InstallFlow_WindowsFeatureDoesNotExist\", \"[windowsFeature]\")\r\n{\r\n    if (!AppInstaller::Runtime::IsRunningAsAdmin())\r\n    {\r\n        WARN(\"Test requires admin privilege. Skipped.\");\r\n        return;\r\n    }\r\n\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n    TestCommon::TestUserSettings testSettings;\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideOpenDependencySource(context);\r\n\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_WindowsFeatures.yaml\").GetPath().u8string());\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_INSTALL_DEPENDENCIES);\r\n    REQUIRE(!std::filesystem::exists(installResultPath.GetPath()));\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::WindowsFeatureNotFound(LocIndView{ \"testFeature1\" })).get()) != std::string::npos);\r\n\r\n    // \"badFeature\" should not be displayed as the flow should terminate after failing to find the first feature.\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::WindowsFeatureNotFound(LocIndView{ \"testFeature2\" })).get()) == std::string::npos);\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::FailedToEnableWindowsFeatureOverrideRequired).get()) != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_FailedToEnableWindowsFeature\", \"[windowsFeature]\")\r\n{\r\n    if (!AppInstaller::Runtime::IsRunningAsAdmin())\r\n    {\r\n        WARN(\"Test requires admin privilege. Skipped.\");\r\n        return;\r\n    }\r\n\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n    TestCommon::TestUserSettings testSettings;\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideOpenDependencySource(context);\r\n\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_WindowsFeatures.yaml\").GetPath().u8string());\r\n\r\n    auto setDoesFeatureExistOverride = TestHook::SetDoesWindowsFeatureExistResult_Override(ERROR_SUCCESS);\r\n    auto setEnableFeatureOverride = TestHook::SetEnableWindowsFeatureResult_Override(0xc0040001); // DISMAPI_E_DISMAPI_NOT_INITIALIZED\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_INSTALL_DEPENDENCIES);\r\n    REQUIRE(!std::filesystem::exists(installResultPath.GetPath()));\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::FailedToEnableWindowsFeatureOverrideRequired).get()) != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_FailedToEnableWindowsFeature_Force\", \"[windowsFeature]\")\r\n{\r\n    if (!AppInstaller::Runtime::IsRunningAsAdmin())\r\n    {\r\n        WARN(\"Test requires admin privilege. Skipped.\");\r\n        return;\r\n    }\r\n\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n    TestCommon::TestUserSettings testSettings;\r\n\r\n    auto doesFeatureExistOverride = TestHook::SetDoesWindowsFeatureExistResult_Override(ERROR_SUCCESS);\r\n    auto expectedErrorCode = 0xc0040001; // DISMAPI_E_DISMAPI_NOT_INITIALIZED\r\n    auto setEnableFeatureOverride = TestHook::SetEnableWindowsFeatureResult_Override(expectedErrorCode);\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n    OverrideOpenDependencySource(context);\r\n\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_WindowsFeatures.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::Force);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify Installer is called and parameters are passed in.\r\n    REQUIRE(context.GetTerminationHR() == ERROR_SUCCESS);\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::FailedToEnableWindowsFeature(LocIndView{ \"testFeature1\" }, expectedErrorCode)).get()) != std::string::npos);\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::FailedToEnableWindowsFeature(LocIndView{ \"testFeature2\" }, expectedErrorCode)).get()) != std::string::npos);\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::FailedToEnableWindowsFeatureOverridden).get()) != std::string::npos);\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n    std::ifstream installResultFile(installResultPath.GetPath());\r\n    REQUIRE(installResultFile.is_open());\r\n    std::string installResultStr;\r\n    std::getline(installResultFile, installResultStr);\r\n    REQUIRE(installResultStr.find(\"/custom\") != std::string::npos);\r\n    REQUIRE(installResultStr.find(\"/silentwithprogress\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_RebootRequired\", \"[windowsFeature]\")\r\n{\r\n    if (!AppInstaller::Runtime::IsRunningAsAdmin())\r\n    {\r\n        WARN(\"Test requires admin privilege. Skipped.\");\r\n        return;\r\n    }\r\n\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n    TestCommon::TestUserSettings testSettings;\r\n\r\n    // Override with reboot required HRESULT.\r\n    auto doesFeatureExistOverride = TestHook::SetDoesWindowsFeatureExistResult_Override(ERROR_SUCCESS);\r\n    auto setEnableFeatureOverride = TestHook::SetEnableWindowsFeatureResult_Override(ERROR_SUCCESS_REBOOT_REQUIRED);\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideOpenDependencySource(context);\r\n\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_WindowsFeatures.yaml\").GetPath().u8string());\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_FOR_INSTALL);\r\n    REQUIRE(!std::filesystem::exists(installResultPath.GetPath()));\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::RebootRequiredToEnableWindowsFeatureOverrideRequired).get()) != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"InstallFlow_RebootRequired_Force\", \"[windowsFeature]\")\r\n{\r\n    if (!AppInstaller::Runtime::IsRunningAsAdmin())\r\n    {\r\n        WARN(\"Test requires admin privilege. Skipped.\");\r\n        return;\r\n    }\r\n\r\n    TestCommon::TempFile installResultPath(\"TestExeInstalled.txt\");\r\n    TestCommon::TestUserSettings testSettings;\r\n\r\n    // Override with reboot required HRESULT.\r\n    auto doesFeatureExistOverride = TestHook::SetDoesWindowsFeatureExistResult_Override(ERROR_SUCCESS);\r\n    auto setEnableFeatureOverride = TestHook::SetEnableWindowsFeatureResult_Override(ERROR_SUCCESS_REBOOT_REQUIRED);\r\n\r\n    std::ostringstream installOutput;\r\n    TestContext context{ installOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    OverrideForShellExecute(context);\r\n    OverrideOpenDependencySource(context);\r\n\r\n    context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_WindowsFeatures.yaml\").GetPath().u8string());\r\n    context.Args.AddArg(Execution::Args::Type::Force);\r\n\r\n    InstallCommand install({});\r\n    install.Execute(context);\r\n    INFO(installOutput.str());\r\n\r\n    // Verify Installer is called and parameters are passed in.\r\n    REQUIRE(context.GetTerminationHR() == ERROR_SUCCESS);\r\n    REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::RebootRequiredToEnableWindowsFeatureOverridden).get()) != std::string::npos);\r\n    REQUIRE(std::filesystem::exists(installResultPath.GetPath()));\r\n    std::ifstream installResultFile(installResultPath.GetPath());\r\n    REQUIRE(installResultFile.is_open());\r\n    std::string installResultStr;\r\n    std::getline(installResultFile, installResultStr);\r\n    REQUIRE(installResultStr.find(\"/custom\") != std::string::npos);\r\n    REQUIRE(installResultStr.find(\"/silentwithprogress\") != std::string::npos);\r\n}"
  },
  {
    "path": "src/AppInstallerCLITests/WorkFlow.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"WorkflowCommon.h\"\r\n#include \"TestSettings.h\"\r\n#include <AppInstallerDownloader.h>\r\n#include <winget/Settings.h>\r\n#include <Workflows/DownloadFlow.h>\r\n#include <Commands/InstallCommand.h>\r\n#include <Commands/SettingsCommand.h>\r\n#include <Commands/ValidateCommand.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::CLI;\r\nusing namespace AppInstaller::CLI::Execution;\r\nusing namespace AppInstaller::CLI::Workflow;\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Settings;\r\nusing namespace AppInstaller::Utility;\r\n\r\nvoid VerifyMotw(const std::filesystem::path& testFile, DWORD zone)\r\n{\r\n    std::filesystem::path motwFile(testFile);\r\n    motwFile += \":Zone.Identifier:$data\";\r\n    std::ifstream motwStream(motwFile);\r\n    std::stringstream motwContent;\r\n    motwContent << motwStream.rdbuf();\r\n    std::string motwContentStr = motwContent.str();\r\n    motwStream.close();\r\n    REQUIRE(motwContentStr.find(\"ZoneId=\" + std::to_string(zone)) != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"VerifyInstallerTrustLevelAndUpdateInstallerFileMotw\", \"[DownloadInstaller][workflow]\")\r\n{\r\n    TestCommon::TempFile testInstallerPath(\"TestInstaller.txt\");\r\n\r\n    std::ofstream ofile(testInstallerPath, std::ofstream::out);\r\n    ofile << \"test\";\r\n    ofile.close();\r\n\r\n    ApplyMotwIfApplicable(testInstallerPath, URLZONE_INTERNET);\r\n    VerifyMotw(testInstallerPath, 3);\r\n\r\n    std::ostringstream updateMotwOutput;\r\n    TestContext context{ updateMotwOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    context.Add<Data::DownloadHashInfo>({ {}, {} });\r\n    context.Add<Data::InstallerPath>(testInstallerPath);\r\n    auto packageVersion = std::make_shared<TestPackageVersion>(Manifest{});\r\n    auto testSource = std::make_shared<TestSource>();\r\n    testSource->Details.TrustLevel = SourceTrustLevel::Trusted;\r\n    packageVersion->Source = testSource;\r\n    context.Add<Data::PackageVersion>(packageVersion);\r\n    ManifestInstaller installer;\r\n    installer.Url = \"http://NotTrusted.com\";\r\n    context.Add<Data::Installer>(std::move(installer));\r\n\r\n    context << VerifyInstallerHash << UpdateInstallerFileMotwIfApplicable;\r\n    REQUIRE(WI_IsFlagSet(context.GetFlags(), ContextFlag::InstallerTrusted));\r\n    VerifyMotw(testInstallerPath, 2);\r\n\r\n    testSource->Details.TrustLevel = SourceTrustLevel::None;\r\n    context.ClearFlags(ContextFlag::InstallerTrusted);\r\n    context << VerifyInstallerHash << UpdateInstallerFileMotwIfApplicable;\r\n    REQUIRE_FALSE(WI_IsFlagSet(context.GetFlags(), ContextFlag::InstallerTrusted));\r\n    VerifyMotw(testInstallerPath, 3);\r\n\r\n    INFO(updateMotwOutput.str());\r\n}\r\n\r\nTEST_CASE(\"ValidateCommand_Dependencies\", \"[workflow][dependencies]\")\r\n{\r\n    std::ostringstream validateOutput;\r\n    TestContext context{ validateOutput, std::cin };\r\n    auto previousThreadGlobals = context.SetForCurrentThread();\r\n    context.Args.AddArg(Args::Type::ValidateManifest, TestDataFile(\"Manifest-Good-AllDependencyTypes.yaml\").GetPath().u8string());\r\n\r\n    ValidateCommand validate({});\r\n    validate.Execute(context);\r\n    INFO(validateOutput.str());\r\n\r\n    // Verify all types of dependencies are printed\r\n    REQUIRE(validateOutput.str().find(Resource::LocString(Resource::String::ValidateCommandReportDependencies).get()) != std::string::npos);\r\n    REQUIRE(validateOutput.str().find(\"WindowsFeaturesDep\") != std::string::npos);\r\n    REQUIRE(validateOutput.str().find(\"WindowsLibrariesDep\") != std::string::npos);\r\n    // PackageDep1 has minimum version (1.0), PackageDep2 doesn't (shouldn't show [>=...])\r\n    REQUIRE(validateOutput.str().find(\"Package.Dep1-x64 [>= 1.0]\") != std::string::npos);\r\n    REQUIRE(validateOutput.str().find(\"Package.Dep2-x64\") != std::string::npos);\r\n    REQUIRE(validateOutput.str().find(\"Package.Dep2-x64 [\") == std::string::npos);\r\n    REQUIRE(validateOutput.str().find(\"ExternalDep\") != std::string::npos);\r\n}\r\n\r\nTEST_CASE(\"AdminSetting_LocalManifestFiles\", \"[LocalManifests][workflow]\")\r\n{\r\n    RemoveSetting(Stream::AdminSettings);\r\n\r\n    {\r\n        // If there's no admin setting, using local manifest should fail.\r\n        Execution::Args args;\r\n        args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_Exe.yaml\").GetPath().u8string());\r\n        InstallCommand installCommand({});\r\n        REQUIRE_THROWS(installCommand.ValidateArguments(args));\r\n    }\r\n\r\n    {\r\n        // Using settings command to enable local manifests\r\n        std::ostringstream settingsOutput;\r\n        TestContext context{ settingsOutput, std::cin };\r\n        auto previousThreadGlobals = context.SetForCurrentThread();\r\n        context.Args.AddArg(Execution::Args::Type::AdminSettingEnable, \"LocalManifestFiles\"sv);\r\n        context.Override({ EnsureRunningAsAdmin, [](TestContext&) {} });\r\n        SettingsCommand settings({});\r\n        settings.Execute(context);\r\n        INFO(settingsOutput.str());\r\n    }\r\n\r\n    {\r\n        // Now using local manifests should succeed\r\n        Execution::Args args2;\r\n        args2.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_Exe.yaml\").GetPath().u8string());\r\n        InstallCommand installCommand2({});\r\n        REQUIRE_NOTHROW(installCommand2.ValidateArguments(args2));\r\n    }\r\n\r\n    {\r\n        // Using settings command to disable local manifests\r\n        std::ostringstream settingsOutput2;\r\n        TestContext context2{ settingsOutput2, std::cin };\r\n        auto previousThreadGlobals = context2.SetForCurrentThread();\r\n        context2.Args.AddArg(Execution::Args::Type::AdminSettingDisable, \"LocalManifestFiles\"sv);\r\n        context2.Override({ EnsureRunningAsAdmin, [](TestContext&) {} });\r\n        SettingsCommand settings2({});\r\n        settings2.Execute(context2);\r\n        INFO(settingsOutput2.str());\r\n    }\r\n\r\n    {\r\n        // Now using local manifests should fail\r\n        Execution::Args args3;\r\n        args3.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_Exe.yaml\").GetPath().u8string());\r\n        InstallCommand installCommand3({});\r\n        REQUIRE_THROWS(installCommand3.ValidateArguments(args3));\r\n    }\r\n}\r\n\r\nTEST_CASE(\"Export_Settings\", \"[Settings][workflow]\")\r\n{\r\n    RemoveSetting(Stream::AdminSettings);\r\n\r\n    {\r\n        // No admin settings, local manifest should be false.\r\n        std::ostringstream exportOutput;\r\n        TestContext context{ exportOutput, std::cin };\r\n        auto previousThreadGlobals = context.SetForCurrentThread();\r\n        SettingsExportCommand settingsExportCommand({});\r\n        settingsExportCommand.Execute(context);\r\n\r\n        auto json = ConvertToJson(exportOutput.str());\r\n        REQUIRE(!json.isNull());\r\n        REQUIRE_FALSE(json[\"adminSettings\"][\"LocalManifestFiles\"].asBool());\r\n\r\n        auto userSettingsFileValue = std::string(json[\"userSettingsFile\"].asCString());\r\n        REQUIRE(userSettingsFileValue.find(\"settings.json\") != std::string::npos);\r\n    }\r\n\r\n    {\r\n        // Enable local manifest and verify export works.\r\n        std::ostringstream settingsOutput;\r\n        TestContext context{ settingsOutput, std::cin };\r\n        auto previousThreadGlobals = context.SetForCurrentThread();\r\n        context.Args.AddArg(Execution::Args::Type::AdminSettingEnable, \"LocalManifestFiles\"sv);\r\n        context.Override({ EnsureRunningAsAdmin, [](TestContext&) {} });\r\n        SettingsCommand settings({});\r\n        settings.Execute(context);\r\n\r\n        std::ostringstream exportOutput;\r\n        TestContext context2{ exportOutput, std::cin };\r\n        auto previousThreadGlobals2 = context2.SetForCurrentThread();\r\n        SettingsExportCommand settingsExportCommand({});\r\n        settingsExportCommand.Execute(context2);\r\n        auto json = ConvertToJson(exportOutput.str());\r\n        REQUIRE(!json.isNull());\r\n        REQUIRE(json[\"adminSettings\"][\"LocalManifestFiles\"].asBool());\r\n\r\n        auto userSettingsFileValue = std::string(json[\"userSettingsFile\"].asCString());\r\n        REQUIRE(userSettingsFileValue.find(\"settings.json\") != std::string::npos);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/WorkflowCommon.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"DependenciesTestSource.h\"\r\n#include \"WorkflowCommon.h\"\r\n#include <winget/ManifestYamlParser.h>\r\n#include <Workflows/ArchiveFlow.h>\r\n#include <Workflows/DownloadFlow.h>\r\n#include <Workflows/InstallFlow.h>\r\n#include <Workflows/MSStoreInstallerHandler.h>\r\n#include <Workflows/DependenciesFlow.h>\r\n\r\nusing namespace AppInstaller::CLI;\r\nusing namespace AppInstaller::CLI::Execution;\r\nusing namespace AppInstaller::CLI::Workflow;\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Utility;\r\n\r\nnamespace TestCommon\r\n{\r\n    namespace TSR\r\n    {\r\n        const TestSourceResult TestQuery_ReturnOne(\r\n            \"TestQueryReturnOne\"sv,\r\n            [](std::vector<ResultMatch>& matches, std::weak_ptr<const ISource> source) {\r\n                auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallFlowTest_Exe.yaml\"));\r\n                matches.emplace_back(\r\n                    ResultMatch(\r\n                        TestCompositePackage::Make(std::vector<Manifest>{ manifest }, source),\r\n                        PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, \"TestQueryReturnOne\")));\r\n            });\r\n\r\n        const TestSourceResult TestQuery_ReturnTwo(\r\n            \"TestQueryReturnTwo\"sv,\r\n            [](std::vector<ResultMatch>& matches, std::weak_ptr<const ISource> source) {\r\n                auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallFlowTest_Exe.yaml\"));\r\n                matches.emplace_back(\r\n                    ResultMatch(\r\n                        TestCompositePackage::Make(std::vector<Manifest>{ manifest }, source),\r\n                        PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, \"TestQueryReturnTwo\")));\r\n\r\n                auto manifest2 = YamlParser::CreateFromPath(TestDataFile(\"Manifest-Good.yaml\"));\r\n                matches.emplace_back(\r\n                    ResultMatch(\r\n                        TestCompositePackage::Make(std::vector<Manifest>{ manifest2 }, source),\r\n                        PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, \"TestQueryReturnTwo\")));\r\n            });\r\n\r\n        const TestSourceResult TestInstaller_Exe(\r\n            \"AppInstallerCliTest.TestExeInstaller\"sv,\r\n            [](std::vector<ResultMatch>& matches, std::weak_ptr<const ISource> source) {\r\n                auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallFlowTest_Exe.yaml\"));\r\n                auto manifest2 = YamlParser::CreateFromPath(TestDataFile(\"UpdateFlowTest_Exe.yaml\"));\r\n                auto manifest3 = YamlParser::CreateFromPath(TestDataFile(\"UpdateFlowTest_Exe_2.yaml\"));\r\n\r\n                auto testPackage =\r\n                    TestCompositePackage::Make(\r\n                        manifest,\r\n                        TestCompositePackage::MetadataMap\r\n                        {\r\n                            { PackageVersionMetadata::InstalledType, \"Exe\" },\r\n                            { PackageVersionMetadata::StandardUninstallCommand, \"C:\\\\uninstall.exe\" },\r\n                            { PackageVersionMetadata::SilentUninstallCommand, \"C:\\\\uninstall.exe /silence\" },\r\n                        },\r\n                        std::vector<Manifest>{ manifest3, manifest2, manifest },\r\n                        source\r\n                        );\r\n                for (auto& availablePackage : testPackage->Available)\r\n                {\r\n                    availablePackage->IsSameOverride = [](const IPackage*, const IPackage*) { return true; };\r\n                }\r\n                matches.emplace_back(\r\n                    ResultMatch(\r\n                        testPackage,\r\n                        PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, \"AppInstallerCliTest.TestExeInstaller\")));\r\n            });\r\n\r\n        const TestSourceResult TestInstaller_Exe_UpgradeUsesAgreements(\r\n            \"AppInstallerCliTest.TestExeInstaller\"sv,\r\n            [](std::vector<ResultMatch>& matches, std::weak_ptr<const ISource> source) {\r\n                auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallFlowTest_Exe.yaml\"));\r\n                auto manifest2 = YamlParser::CreateFromPath(TestDataFile(\"UpdateFlowTest_Exe.yaml\"));\r\n                auto manifest3 = YamlParser::CreateFromPath(TestDataFile(\"UpdateFlowTest_Exe_2_LicenseAgreement.yaml\"));\r\n\r\n                auto testPackage =\r\n                    TestCompositePackage::Make(\r\n                        manifest,\r\n                        TestCompositePackage::MetadataMap\r\n                        {\r\n                            { PackageVersionMetadata::InstalledType, \"Exe\" },\r\n                            { PackageVersionMetadata::StandardUninstallCommand, \"C:\\\\uninstall.exe\" },\r\n                            { PackageVersionMetadata::SilentUninstallCommand, \"C:\\\\uninstall.exe /silence\" },\r\n                        },\r\n                        std::vector<Manifest>{ manifest3, manifest2, manifest },\r\n                        source\r\n                        );\r\n                for (auto& availablePackage : testPackage->Available)\r\n                {\r\n                    availablePackage->IsSameOverride = [](const IPackage*, const IPackage*) { return true; };\r\n                }\r\n                matches.emplace_back(\r\n                    ResultMatch(\r\n                        testPackage,\r\n                        PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, \"AppInstallerCliTest.TestExeInstaller\")));\r\n            });\r\n\r\n        const TestSourceResult TestInstaller_Portable(\r\n            \"AppInstallerCliTest.TestPortableInstaller\"sv,\r\n            [](std::vector<ResultMatch>& matches, std::weak_ptr<const ISource> source) {\r\n                auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallFlowTest_Portable.yaml\"));\r\n                auto manifest2 = YamlParser::CreateFromPath(TestDataFile(\"UpdateFlowTest_Portable.yaml\"));\r\n                matches.emplace_back(\r\n                    ResultMatch(\r\n                        TestCompositePackage::Make(\r\n                            manifest,\r\n                            TestCompositePackage::MetadataMap{ { PackageVersionMetadata::InstalledType, \"Portable\" } },\r\n                            std::vector<Manifest>{ manifest2, manifest },\r\n                            source\r\n                        ),\r\n                        PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, \"AppInstallerCliTest.TestPortableInstaller\")));\r\n            });\r\n\r\n        const TestSourceResult TestInstaller_Msix(\r\n            \"AppInstallerCliTest.TestMsixInstaller\"sv,\r\n            [](std::vector<ResultMatch>& matches, std::weak_ptr<const ISource> source) {\r\n                auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallFlowTest_Msix_StreamingFlow.yaml\"));\r\n                auto manifest2 = YamlParser::CreateFromPath(TestDataFile(\"UpdateFlowTest_Msix.yaml\"));\r\n\r\n                matches.emplace_back(\r\n                    ResultMatch(\r\n                        TestCompositePackage::Make(\r\n                            manifest,\r\n                            TestCompositePackage::MetadataMap{ { PackageVersionMetadata::InstalledType, \"Msix\" } },\r\n                            std::vector<Manifest>{ manifest2, manifest },\r\n                            source\r\n                        ),\r\n                        PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, \"AppInstallerCliTest.TestMsixInstaller\")));\r\n            });\r\n\r\n        const TestSourceResult TestInstaller_Msix_UpgradeUsesAgreements(\r\n            \"AppInstallerCliTest.TestMsixInstaller\"sv,\r\n            [](std::vector<ResultMatch>& matches, std::weak_ptr<const ISource> source) {\r\n                auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallFlowTest_Msix_StreamingFlow.yaml\"));\r\n                auto manifest2 = YamlParser::CreateFromPath(TestDataFile(\"UpdateFlowTest_Msix_LicenseAgreement.yaml\"));\r\n\r\n                matches.emplace_back(\r\n                    ResultMatch(\r\n                        TestCompositePackage::Make(\r\n                            manifest,\r\n                            TestCompositePackage::MetadataMap{ { PackageVersionMetadata::InstalledType, \"Msix\" } },\r\n                            std::vector<Manifest>{ manifest2, manifest },\r\n                            source\r\n                        ),\r\n                        PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, \"AppInstallerCliTest.TestMsixInstaller\")));\r\n            });\r\n\r\n        const TestSourceResult TestInstaller_Msix_UpgradeRequiresExplicit(\r\n            \"AppInstallerCliTest.TestMsixInstaller\"sv,\r\n            [](std::vector<ResultMatch>& matches, std::weak_ptr<const ISource> source) {\r\n                auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallFlowTest_Msix_StreamingFlow.yaml\"));\r\n                auto manifest2 = YamlParser::CreateFromPath(TestDataFile(\"UpdateFlowTest_Msix.yaml\"));\r\n\r\n                matches.emplace_back(\r\n                    ResultMatch(\r\n                        TestCompositePackage::Make(\r\n                            manifest,\r\n                            TestCompositePackage::MetadataMap\r\n                            {\r\n                                { PackageVersionMetadata::InstalledType, \"Msix\" },\r\n                                { PackageVersionMetadata::PinnedState, \"PinnedByManifest\" },\r\n                            },\r\n                            std::vector<Manifest>{ manifest2, manifest },\r\n                            source\r\n                            ),\r\n                        PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, \"AppInstallerCliTest.TestMsixInstaller\")));\r\n            });\r\n\r\n        const TestSourceResult TestInstaller_Zip(\r\n            \"AppInstallerCliTest.TestZipInstaller\"sv,\r\n            [](std::vector<ResultMatch>& matches, std::weak_ptr<const ISource> source) {\r\n                auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallFlowTest_Zip_Exe.yaml\"));\r\n                auto manifest2 = YamlParser::CreateFromPath(TestDataFile(\"UpdateFlowTest_Zip_Exe.yaml\"));\r\n                matches.emplace_back(\r\n                    ResultMatch(\r\n                        TestCompositePackage::Make(\r\n                            manifest,\r\n                            TestCompositePackage::MetadataMap{ { PackageVersionMetadata::InstalledType, \"Exe\" } },\r\n                            std::vector<Manifest>{ manifest2, manifest },\r\n                            source\r\n                        ),\r\n                        PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, \"AppInstallerCliTest.TestZipInstaller\")));\r\n            });\r\n\r\n        const TestSourceResult TestInstaller_MSStore(\r\n            \"AppInstallerCliTest.TestMSStoreInstaller\"sv,\r\n            [](std::vector<ResultMatch>& matches, std::weak_ptr<const ISource> source) {\r\n                auto installed = YamlParser::CreateFromPath(TestDataFile(\"InstallFlowTest_MSStore.yaml\"));\r\n                auto available = installed;\r\n                // Override the installed version to not be Latest\r\n                installed.Version = \"1.0.0.0\";\r\n                matches.emplace_back(\r\n                    ResultMatch(\r\n                        TestCompositePackage::Make(\r\n                            installed,\r\n                            TestCompositePackage::MetadataMap{ { PackageVersionMetadata::InstalledType, \"MSStore\" } },\r\n                            std::vector<Manifest>{ available },\r\n                            source\r\n                        ),\r\n                        PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, \"AppInstallerCliTest.TestMSStoreInstaller\")));\r\n            });\r\n\r\n        const TestSourceResult TestInstaller_Exe_ExpectedReturnCodes(\r\n            \"AppInstallerCliTest.ExpectedReturnCodes\"sv,\r\n            [](std::vector<ResultMatch>& matches, std::weak_ptr<const ISource> source) {\r\n                auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallFlowTest_ExpectedReturnCodes.yaml\"));\r\n                auto manifest2 = YamlParser::CreateFromPath(TestDataFile(\"UpdateFlowTest_ExpectedReturnCodes.yaml\"));\r\n                matches.emplace_back(\r\n                    ResultMatch(\r\n                        TestCompositePackage::Make(\r\n                            manifest,\r\n                            TestCompositePackage::MetadataMap{ { PackageVersionMetadata::InstalledType, \"Exe\" } },\r\n                            std::vector<Manifest>{ manifest2, manifest },\r\n                            source\r\n                        ),\r\n                        PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, \"AppInstallerCliTest.ExpectedReturnCodes\")));\r\n            });\r\n\r\n        const TestSourceResult TestInstaller_Exe_UnknownVersion(\r\n            \"TestExeInstallerWithUnknownVersion\"sv,\r\n            [](std::vector<ResultMatch>& matches, std::weak_ptr<const ISource> source) {\r\n                auto installed = YamlParser::CreateFromPath(TestDataFile(\"InstallFlowTest_UnknownVersion.yaml\"));\r\n                auto available = installed;\r\n                // Override the installed version to be unknown.\r\n                installed.Version = \"unknown\";\r\n                matches.emplace_back(\r\n                    ResultMatch(\r\n                        TestCompositePackage::Make(\r\n                            installed,\r\n                            TestCompositePackage::MetadataMap{ { PackageVersionMetadata::InstalledType, \"Exe\" } },\r\n                            std::vector<Manifest>{ available },\r\n                            source\r\n                        ),\r\n                        PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, \"AppInstallerCliTest.TestExeUnknownVersion\")));\r\n            });\r\n\r\n        const TestSourceResult TestInstaller_Exe_LatestInstalled(\r\n            \"TestExeInstallerWithLatestInstalled\"sv,\r\n            [](std::vector<ResultMatch>& matches, std::weak_ptr<const ISource> source) {\r\n                auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallFlowTest_Exe.yaml\"));\r\n                auto manifest2 = YamlParser::CreateFromPath(TestDataFile(\"UpdateFlowTest_Exe.yaml\"));\r\n                matches.emplace_back(\r\n                    ResultMatch(\r\n                        TestCompositePackage::Make(\r\n                            manifest2,\r\n                            TestCompositePackage::MetadataMap{ { PackageVersionMetadata::InstalledType, \"Exe\" } },\r\n                            std::vector<Manifest>{ manifest2, manifest },\r\n                            source\r\n                        ),\r\n                        PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, \"AppInstallerCliTest.TestExeInstaller\")));\r\n            });\r\n\r\n        const TestSourceResult TestInstaller_Exe_IncompatibleInstallerType(\r\n            \"TestExeInstallerWithIncompatibleInstallerType\"sv,\r\n            [](std::vector<ResultMatch>& matches, std::weak_ptr<const ISource> source) {\r\n                auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallFlowTest_Exe.yaml\"));\r\n                auto manifest2 = YamlParser::CreateFromPath(TestDataFile(\"UpdateFlowTest_Exe.yaml\"));\r\n                matches.emplace_back(\r\n                    ResultMatch(\r\n                        TestCompositePackage::Make(\r\n                            manifest,\r\n                            TestCompositePackage::MetadataMap{ { PackageVersionMetadata::InstalledType, \"Msix\" } },\r\n                            std::vector<Manifest>{ manifest2, manifest },\r\n                            source\r\n                        ),\r\n                        PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, \"AppInstallerCliTest.TestExeInstaller\")));\r\n            });\r\n\r\n        const TestSourceResult TestInstaller_Exe_DifferentInstallerType(\r\n            \"TestExeInstallerWithDifferentInstalledType\"sv,\r\n            [](std::vector<ResultMatch>& matches, std::weak_ptr<const ISource> source) {\r\n                auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallFlowTest_Exe.yaml\"));\r\n                auto manifest2 = YamlParser::CreateFromPath(TestDataFile(\"UpdateFlowTest_Exe_ARPInstallerType.yaml\"));\r\n                matches.emplace_back(\r\n                    ResultMatch(\r\n                        TestCompositePackage::Make(\r\n                            manifest,\r\n                            TestCompositePackage::MetadataMap{ { PackageVersionMetadata::InstalledType, \"Msix\" } },\r\n                            std::vector<Manifest>{ manifest2, manifest },\r\n                            source\r\n                        ),\r\n                        PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, \"AppInstallerCliTest.TestExeInstaller\")));\r\n            });\r\n\r\n        const TestSourceResult TestInstaller_Exe_UnsupportedArguments(\r\n            \"TestExeInstallerWithUnsupportedArguments\"sv,\r\n            [](std::vector<ResultMatch>& matches, std::weak_ptr<const ISource> source) {\r\n                auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallFlowTest_Exe.yaml\"));\r\n                auto manifest2 = YamlParser::CreateFromPath(TestDataFile(\"UpdateFlowTest_Exe_UnsupportedArgs.yaml\"));\r\n                matches.emplace_back(\r\n                    ResultMatch(\r\n                        TestCompositePackage::Make(\r\n                            manifest,\r\n                            TestCompositePackage::MetadataMap{ { PackageVersionMetadata::InstalledType, \"Exe\" } },\r\n                            std::vector<Manifest>{ manifest2, manifest },\r\n                            source\r\n                        ),\r\n                        PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, \"AppInstallerCliTest.TestExeInstaller\")));\r\n            });\r\n\r\n        const TestSourceResult TestInstaller_Exe_NothingInstalled(\r\n            \"TestExeInstallerWithNothingInstalled\"sv,\r\n            [](std::vector<ResultMatch>& matches, std::weak_ptr<const ISource> source) {\r\n                auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallFlowTest_Exe.yaml\"));\r\n                matches.emplace_back(\r\n                    ResultMatch(\r\n                        TestCompositePackage::Make(\r\n                            std::vector<Manifest>{ manifest },\r\n                            source\r\n                        ),\r\n                        PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, \"AppInstallerCliTest.TestExeInstaller\")));\r\n            });\r\n\r\n        const TestSourceResult TestInstaller_Exe_Dependencies(\r\n            \"AppInstallerCliTest.TestExeInstaller.Dependencies\"sv,\r\n            [](std::vector<ResultMatch>& matches, std::weak_ptr<const ISource> source) {\r\n                auto manifest = YamlParser::CreateFromPath(TestDataFile(\"Installer_Exe_Dependencies.yaml\"));\r\n                auto manifest2 = YamlParser::CreateFromPath(TestDataFile(\"UpdateFlowTest_ExeDependencies.yaml\"));\r\n                matches.emplace_back(\r\n                    ResultMatch(\r\n                        TestCompositePackage::Make(\r\n                            manifest,\r\n                            TestCompositePackage::MetadataMap\r\n                            {\r\n                                { PackageVersionMetadata::InstalledType, \"Exe\" },\r\n                                { PackageVersionMetadata::StandardUninstallCommand, \"C:\\\\uninstall.exe\" },\r\n                                { PackageVersionMetadata::SilentUninstallCommand, \"C:\\\\uninstall.exe /silence\" },\r\n                            },\r\n                            std::vector<Manifest>{ manifest2, manifest },\r\n                            source\r\n                            ),\r\n                        PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, \"AppInstallerCliTest.TestExeInstaller.Dependencies\")));\r\n            });\r\n\r\n        const TestSourceResult TestInstaller_Msix_WFDependency(\r\n            \"AppInstallerCliTest.TestMsixInstaller.WFDep\"sv,\r\n            [](std::vector<ResultMatch>& matches, std::weak_ptr<const ISource> source) {\r\n                auto manifest = YamlParser::CreateFromPath(TestDataFile(\"Installer_Msix_WFDependency.yaml\"));\r\n                matches.emplace_back(\r\n                    ResultMatch(\r\n                        TestCompositePackage::Make(\r\n                            std::vector<Manifest>{ manifest },\r\n                            source\r\n                        ),\r\n                        PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, \"AppInstallerCliTest.TestMsixInstaller.WFDep\")));\r\n            });\r\n\r\n        const TestSourceResult TestInstaller_Exe_LicenseAgreement(\r\n            \"TestInstallerWithLicenseAgreement\"sv,\r\n            [](std::vector<ResultMatch>& matches, std::weak_ptr<const ISource> source) {\r\n                auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallFlowTest_LicenseAgreement.yaml\"));\r\n                auto manifest2 = YamlParser::CreateFromPath(TestDataFile(\"UpdateFlowTest_Exe_2_LicenseAgreement.yaml\"));\r\n                matches.emplace_back(\r\n                    ResultMatch(\r\n                        TestCompositePackage::Make(\r\n                            manifest,\r\n                            TestCompositePackage::MetadataMap{ { PackageVersionMetadata::InstalledType, \"Exe\" } },\r\n                            std::vector<Manifest>{ manifest2, manifest },\r\n                            source\r\n                        ),\r\n                        PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, \"TestInstallerWithLicenseAgreement\")));\r\n            });\r\n\r\n        const TestSourceResult TestInstaller_Exe_UpgradeAllWithDuplicateUpgradeItems(\r\n            \"TestUpgradeAllWithDuplicateUpgradeItems\"sv,\r\n            [](std::vector<ResultMatch>& matches, std::weak_ptr<const ISource> source) {\r\n                auto manifest = YamlParser::CreateFromPath(TestDataFile(\"InstallFlowTest_Exe.yaml\"));\r\n                auto manifest2 = YamlParser::CreateFromPath(TestDataFile(\"UpdateFlowTest_Exe.yaml\"));\r\n                auto manifest3 = YamlParser::CreateFromPath(TestDataFile(\"UpdateFlowTest_Exe_2.yaml\"));\r\n                matches.emplace_back(\r\n                    ResultMatch(\r\n                        TestCompositePackage::Make(\r\n                            manifest,\r\n                            TestCompositePackage::MetadataMap\r\n                            {\r\n                                { PackageVersionMetadata::InstalledType, \"Exe\" },\r\n                                { PackageVersionMetadata::StandardUninstallCommand, \"C:\\\\uninstall.exe\" },\r\n                                { PackageVersionMetadata::SilentUninstallCommand, \"C:\\\\uninstall.exe /silence\" },\r\n                            },\r\n                            std::vector<Manifest>{ manifest3, manifest2, manifest },\r\n                            source\r\n                            ),\r\n                        PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, \"AppInstallerCliTest.TestExeInstaller\")));\r\n                matches.emplace_back(\r\n                    ResultMatch(\r\n                        TestCompositePackage::Make(\r\n                            manifest2,\r\n                            TestCompositePackage::MetadataMap\r\n                            {\r\n                                { PackageVersionMetadata::InstalledType, \"Exe\" },\r\n                                { PackageVersionMetadata::StandardUninstallCommand, \"C:\\\\uninstall.exe\" },\r\n                                { PackageVersionMetadata::SilentUninstallCommand, \"C:\\\\uninstall.exe /silence\" },\r\n                            },\r\n                            std::vector<Manifest>{ manifest3, manifest2, manifest },\r\n                            source\r\n                            ),\r\n                        PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, \"AppInstallerCliTest.TestExeInstaller\")));\r\n            });\r\n    }\r\n\r\n    SearchResult WorkflowTestSource::Search(const SearchRequest& request) const\r\n    {\r\n        std::string input;\r\n        if (request.Query)\r\n        {\r\n            input = request.Query->Value;\r\n        }\r\n        else if (!request.Inclusions.empty())\r\n        {\r\n            input = request.Inclusions[0].Value;\r\n        }\r\n        else if (!request.Filters.empty())\r\n        {\r\n            input = request.Filters[0].Value;\r\n        }\r\n\r\n        SearchResult result;\r\n        for (const auto& testSourceResult : m_testSourceResults)\r\n        {\r\n            if (input.empty() || CaseInsensitiveEquals(input, testSourceResult.Query))\r\n            {\r\n                testSourceResult.AddResults(result.Matches, shared_from_this());\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    void WorkflowTestSource::AddResult(const TestSourceResult& testSourceResult)\r\n    {\r\n        m_testSourceResults.push_back(testSourceResult);\r\n    }\r\n\r\n    std::shared_ptr<WorkflowTestSource> CreateTestSource(std::vector<TestSourceResult>&& testSourceResults)\r\n    {\r\n        return std::make_shared<WorkflowTestSource>(std::move(testSourceResults));\r\n    }\r\n\r\n    TestContext::TestContext(std::ostream& out, std::istream& in) : TestContext(out, in, false, std::make_shared<std::vector<WorkflowTaskOverride>>())\r\n    {\r\n        WorkflowTaskOverride wto\r\n        { RemoveInstaller, [](TestContext&)\r\n            {\r\n                // Do nothing; we never want to remove the test files.\r\n        } };\r\n\r\n        // Mark this one as used so that it doesn't anger the destructor.\r\n        wto.UseCount++;\r\n\r\n        Override(wto);\r\n    }\r\n\r\n    TestContext::TestContext(std::ostream& out, std::istream& in, bool isClone, std::shared_ptr<std::vector<WorkflowTaskOverride>> overrides) :\r\n        m_out(out), m_in(in), m_overrides(overrides), m_isClone(isClone), Context(out, in)\r\n    {\r\n        m_shouldExecuteWorkflowTask = [this](const Workflow::WorkflowTask& task)\r\n        {\r\n            auto itr = std::find_if(m_overrides->begin(), m_overrides->end(), [&](const WorkflowTaskOverride& wto) { return wto.Target == task; });\r\n\r\n            if (itr == m_overrides->end())\r\n            {\r\n                return true;\r\n            }\r\n            else\r\n            {\r\n                itr->UseCount++;\r\n                itr->Override(*this);\r\n                return false;\r\n            }\r\n        };\r\n    }\r\n\r\n    TestContext::~TestContext()\r\n    {\r\n        if (!m_isClone)\r\n        {\r\n            for (const auto& wto : *m_overrides)\r\n            {\r\n                if (wto.UseCount == 0)\r\n                {\r\n                    FAIL_CHECK(\"Unused override \" + wto.Target.GetName());\r\n                }\r\n                else if (wto.ExpectedUseCount != -1 && wto.ExpectedUseCount != wto.UseCount)\r\n                {\r\n                    FAIL_CHECK(\"Used override count does not match expected \" + wto.Target.GetName());\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    void TestContext::Override(const WorkflowTaskOverride& wto)\r\n    {\r\n        m_overrides->emplace_back(wto);\r\n    }\r\n\r\n    std::unique_ptr<Context> TestContext::CreateSubContext()\r\n    {\r\n        auto clone = std::make_unique<TestContext>(m_out, m_in, true, m_overrides);\r\n        clone->SetFlags(this->GetFlags());\r\n        CopyArgsToSubContext(clone.get());\r\n        return clone;\r\n    }\r\n\r\n    void OverrideForOpenSource(TestContext& context, std::shared_ptr<WorkflowTestSource> testSource, bool overrideOpenCompositeSource)\r\n    {\r\n        context.Override({ \"OpenSource\", [=](TestContext& context)\r\n        {\r\n            context.Add<Execution::Data::Source>(Source{ testSource });\r\n        } });\r\n\r\n        if (overrideOpenCompositeSource)\r\n        {\r\n            context.Override({ \"OpenCompositeSource\", [](TestContext&)\r\n            {\r\n            } });\r\n        }\r\n    }\r\n\r\n    void OverrideForCompositeInstalledSource(TestContext& context, std::shared_ptr<WorkflowTestSource> testSource)\r\n    {\r\n        context.Override({ \"OpenSource\", [](TestContext&)\r\n        {\r\n        } });\r\n\r\n        context.Override({ \"OpenCompositeSource\", [=](TestContext& context)\r\n        {\r\n            context.Add<Execution::Data::Source>(Source{ testSource });\r\n        } });\r\n    }\r\n\r\n    void OverrideForUpdateInstallerMotw(TestContext& context)\r\n    {\r\n        context.Override({ UpdateInstallerFileMotwIfApplicable, [](TestContext&)\r\n        {\r\n        } });\r\n    }\r\n\r\n    void OverrideForCheckExistingInstaller(TestContext& context)\r\n    {\r\n        context.Override({ CheckForExistingInstaller, [](TestContext&)\r\n        {\r\n        } });\r\n    }\r\n\r\n    void OverrideForShellExecute(TestContext& context, int expectedUseCount)\r\n    {\r\n        OverrideForCheckExistingInstaller(context);\r\n\r\n        context.Override({ DownloadInstallerFile, [](TestContext& context)\r\n        {\r\n            context.Add<Data::DownloadHashInfo>({ {}, {} });\r\n            context.Add<Data::InstallerPath>(TestDataFile(\"AppInstallerTestExeInstaller.exe\"));\r\n        }, expectedUseCount });\r\n\r\n        context.Override({ RenameDownloadedInstaller, [](TestContext&)\r\n        {\r\n        }, expectedUseCount });\r\n\r\n        OverrideForUpdateInstallerMotw(context);\r\n    }\r\n\r\n    void OverrideForShellExecute(TestContext& context, std::vector<Dependency>& installationLog)\r\n    {\r\n        context.Override({ DownloadInstallerFile, [&installationLog](TestContext& context)\r\n        {\r\n            context.Add<Data::DownloadHashInfo>({ {}, {} });\r\n            context.Add<Data::InstallerPath>(TestDataFile(\"AppInstallerTestExeInstaller.exe\"));\r\n\r\n            auto dependency = Dependency(DependencyType::Package, context.Get<Execution::Data::Manifest>().Id, context.Get<Execution::Data::Manifest>().Version);\r\n            installationLog.push_back(dependency);\r\n        } });\r\n\r\n        context.Override({ RenameDownloadedInstaller, [](TestContext&)\r\n        {\r\n        } });\r\n\r\n        OverrideForUpdateInstallerMotw(context);\r\n    }\r\n\r\n    void OverrideForPortableInstall(TestContext& context)\r\n    {\r\n        context.Override({ Workflow::details::PortableInstall, [](TestContext&)\r\n        {\r\n            std::filesystem::path temp = std::filesystem::temp_directory_path();\r\n            temp /= \"TestPortableInstalled.txt\";\r\n            std::ofstream file(temp, std::ofstream::out);\r\n            file.close();\r\n        } });\r\n    }\r\n\r\n    void OverrideForPortableInstallFlow(TestContext& context)\r\n    {\r\n        context.Override({ DownloadInstallerFile, [](TestContext& context)\r\n        {\r\n            context.Add<Data::DownloadHashInfo>({ {}, {} });\r\n            context.Add<Data::InstallerPath>(TestDataFile(\"AppInstallerTestExeInstaller.exe\"));\r\n        } });\r\n\r\n        context.Override({ RenameDownloadedInstaller, [](TestContext&)\r\n        {\r\n        } });\r\n\r\n        OverrideForUpdateInstallerMotw(context);\r\n        OverrideForPortableInstall(context);\r\n    }\r\n\r\n    void OverridePortableInstaller(TestContext& context)\r\n    {\r\n        context.Override({ DownloadInstallerFile, [](TestContext& context)\r\n        {\r\n            std::filesystem::path tempDirectory = std::filesystem::temp_directory_path();\r\n            const auto& installerPath = TestDataFile(\"AppInstallerTestExeInstaller.exe\").GetPath();\r\n            const auto& tempInstallerPath = tempDirectory / \"AppInstallerTestExeInstaller.exe\";\r\n            std::filesystem::copy(installerPath, tempInstallerPath, std::filesystem::copy_options::overwrite_existing);\r\n            context.Add<Data::InstallerPath>(tempInstallerPath);\r\n\r\n            std::ifstream inStream{ tempInstallerPath, std::ifstream::binary };\r\n            SHA256::HashBuffer fileHash = SHA256::ComputeHash(inStream);\r\n            context.Add<Data::DownloadHashInfo>({ fileHash, DownloadResult{ fileHash } });\r\n        } });\r\n\r\n        context.Override({ RenameDownloadedInstaller, [](TestContext&)\r\n        {\r\n        } });\r\n\r\n        OverrideForUpdateInstallerMotw(context);\r\n    }\r\n\r\n    void OverrideForExtractInstallerFromArchive(TestContext& context)\r\n    {\r\n        context.Override({ ExtractFilesFromArchive, [](TestContext&)\r\n        {\r\n        } });\r\n    }\r\n\r\n    void OverrideForVerifyAndSetNestedInstaller(TestContext& context)\r\n    {\r\n        context.Override({ VerifyAndSetNestedInstaller, [](TestContext&)\r\n        {\r\n        } });\r\n    }\r\n\r\n    void OverrideForMSIX(TestContext& context)\r\n    {\r\n        context.Override({ Workflow::details::MsixInstall, [](TestContext& context)\r\n        {\r\n            std::filesystem::path temp = std::filesystem::temp_directory_path();\r\n            temp /= \"TestMsixInstalled.txt\";\r\n            std::ofstream file(temp, std::ofstream::out);\r\n\r\n            if (context.Contains(Execution::Data::InstallerPath))\r\n            {\r\n                file << context.Get<Execution::Data::InstallerPath>().u8string();\r\n            }\r\n            else\r\n            {\r\n                file << context.Get<Execution::Data::Installer>()->Url;\r\n            }\r\n\r\n            file.close();\r\n        } });\r\n    }\r\n\r\n    void OverrideForMSStore(TestContext& context, bool isUpdate)\r\n    {\r\n        if (isUpdate)\r\n        {\r\n            context.Override({ MSStoreUpdate, [](TestContext& context)\r\n            {\r\n                std::filesystem::path temp = std::filesystem::temp_directory_path();\r\n                temp /= \"TestMSStoreUpdated.txt\";\r\n                std::ofstream file(temp, std::ofstream::out);\r\n                file << context.Get<Execution::Data::Installer>()->ProductId;\r\n                file.close();\r\n            } });\r\n        }\r\n        else\r\n        {\r\n            context.Override({ MSStoreInstall, [](TestContext& context)\r\n            {\r\n                std::filesystem::path temp = std::filesystem::temp_directory_path();\r\n                temp /= \"TestMSStoreInstalled.txt\";\r\n                std::ofstream file(temp, std::ofstream::out);\r\n                file << context.Get<Execution::Data::Installer>()->ProductId;\r\n                file.close();\r\n            } });\r\n        }\r\n\r\n        context.Override({ Workflow::EnsureStorePolicySatisfied, [](TestContext&)\r\n        {\r\n        } });\r\n    }\r\n\r\n    void OverrideOpenDependencySource(TestContext& context)\r\n    {\r\n        context.Override({ Workflow::OpenDependencySource, [](TestContext& context)\r\n        {\r\n            context.Add<Execution::Data::DependencySource>(Source{ std::make_shared<DependenciesTestSource>() });\r\n        } });\r\n    }\r\n\r\n    void OverrideEnableWindowsFeaturesDependencies(TestContext& context)\r\n    {\r\n        context.Override({ Workflow::EnableWindowsFeaturesDependencies, [](TestContext&)\r\n        {\r\n        } });\r\n    }\r\n\r\n    void OverrideRegisterStartupAfterReboot(TestContext& context)\r\n    {\r\n        context.Override({ \"RegisterStartupAfterReboot\", [](TestContext&)\r\n        {\r\n        } });\r\n    }\r\n\r\n    void OverrideDownloadInstallerFileForMSStoreDownload(TestContext& context)\r\n    {\r\n        context.Override({ DownloadInstallerFile, [](TestContext& context)\r\n        {\r\n            const auto& installer = context.Get<Data::Installer>().value();\r\n            const auto& installerPath = context.Get<Data::InstallerPath>();\r\n            std::ofstream file(installerPath, std::ofstream::out | std::ofstream::trunc);\r\n            file << installer.Url;\r\n            file.close();\r\n            context.Add<Data::DownloadHashInfo>({ {}, {} });\r\n        } });\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/WorkflowCommon.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include \"TestSource.h\"\r\n#include <winget/ManifestCommon.h>\r\n#include <ExecutionContext.h>\r\n#include <Workflows/WorkflowBase.h>\r\n#include <Public/winget/RepositorySearch.h>\r\n#include <Public/winget/RepositorySource.h>\r\n\r\n#define REQUIRE_TERMINATED_WITH(_context_,_hr_) \\\r\n    REQUIRE(_context_.IsTerminated()); \\\r\n    REQUIRE(_hr_ == _context_.GetTerminationHR())\r\n\r\nnamespace TestCommon\r\n{\r\n    using namespace std::string_view_literals;\r\n\r\n    // Possible results returned when searching the WorkflowTestSource.\r\n    // If the search query matches with this object or is empty, it adds to the search results.\r\n    struct TestSourceResult\r\n    {\r\n        using AddResultsFunction = std::function<void(std::vector<AppInstaller::Repository::ResultMatch>&, std::weak_ptr<const AppInstaller::Repository::ISource>)>;\r\n        TestSourceResult(std::string_view query, AddResultsFunction addResults) : Query(query), AddResults(addResults) {}\r\n\r\n        std::string Query;\r\n        AddResultsFunction AddResults;\r\n    };\r\n\r\n    namespace TSR\r\n    {\r\n        const extern TestSourceResult TestQuery_ReturnOne;\r\n        const extern TestSourceResult TestQuery_ReturnTwo;\r\n        const extern TestSourceResult TestInstaller_Exe;\r\n        const extern TestSourceResult TestInstaller_Exe_Dependencies;\r\n        const extern TestSourceResult TestInstaller_Exe_DifferentInstallerType;\r\n        const extern TestSourceResult TestInstaller_Exe_ExpectedReturnCodes;\r\n        const extern TestSourceResult TestInstaller_Exe_IncompatibleInstallerType;\r\n        const extern TestSourceResult TestInstaller_Exe_LatestInstalled;\r\n        const extern TestSourceResult TestInstaller_Exe_LicenseAgreement;\r\n        const extern TestSourceResult TestInstaller_Exe_NothingInstalled;\r\n        const extern TestSourceResult TestInstaller_Exe_UnknownVersion;\r\n        const extern TestSourceResult TestInstaller_Exe_UnsupportedArguments;\r\n        const extern TestSourceResult TestInstaller_Exe_UpgradeAllWithDuplicateUpgradeItems;\r\n        const extern TestSourceResult TestInstaller_Exe_UpgradeUsesAgreements;\r\n        const extern TestSourceResult TestInstaller_Msix;\r\n        const extern TestSourceResult TestInstaller_Msix_UpgradeRequiresExplicit;\r\n        const extern TestSourceResult TestInstaller_Msix_UpgradeUsesAgreements;\r\n        const extern TestSourceResult TestInstaller_Msix_WFDependency;\r\n        const extern TestSourceResult TestInstaller_MSStore;\r\n        const extern TestSourceResult TestInstaller_Zip;\r\n        const extern TestSourceResult TestInstaller_Portable;\r\n    }\r\n\r\n    struct WorkflowTestSource : public TestSource\r\n    {\r\n        WorkflowTestSource() {}\r\n        WorkflowTestSource(std::vector<TestSourceResult>&& testSourceResults) : m_testSourceResults(std::move(testSourceResults)) {}\r\n\r\n        AppInstaller::Repository::SearchResult Search(const AppInstaller::Repository::SearchRequest& request) const override;\r\n\r\n        void AddResult(const TestSourceResult& testSourceResult);\r\n\r\n    private:\r\n        std::vector<TestSourceResult> m_testSourceResults;\r\n    };\r\n\r\n    std::shared_ptr<WorkflowTestSource> CreateTestSource(std::vector<TestSourceResult>&& testSourceResults);\r\n\r\n    struct TestContext;\r\n\r\n    struct WorkflowTaskOverride\r\n    {\r\n        WorkflowTaskOverride(AppInstaller::CLI::Workflow::WorkflowTask::Func f, const std::function<void(TestContext&)>& o, int expectedUseCount = -1) :\r\n            Target(f), Override(o), ExpectedUseCount(expectedUseCount) {}\r\n\r\n        WorkflowTaskOverride(std::string_view n, const std::function<void(TestContext&)>& o, int expectedUseCount = -1) :\r\n            Target(n), Override(o), ExpectedUseCount(expectedUseCount) {}\r\n\r\n        WorkflowTaskOverride(const AppInstaller::CLI::Workflow::WorkflowTask& t, const std::function<void(TestContext&)>& o, int expectedUseCount = -1) :\r\n            Target(t), Override(o), ExpectedUseCount(expectedUseCount) {}\r\n\r\n        // -1 means no check on actual use count, as long as it's used.\r\n        int ExpectedUseCount = -1;\r\n        int UseCount = 0;\r\n        AppInstaller::CLI::Workflow::WorkflowTask Target;\r\n        std::function<void(TestContext&)> Override;\r\n    };\r\n\r\n    // Enables overriding the behavior of specific workflow tasks.\r\n    struct TestContext : public AppInstaller::CLI::Execution::Context\r\n    {\r\n        TestContext(std::ostream& out, std::istream& in);\r\n\r\n        TestContext(std::ostream& out, std::istream& in, bool isClone, std::shared_ptr<std::vector<WorkflowTaskOverride>> overrides);\r\n\r\n        ~TestContext();\r\n\r\n        void Override(const WorkflowTaskOverride& wto);\r\n\r\n        std::unique_ptr<AppInstaller::CLI::Execution::Context> CreateSubContext() override;\r\n\r\n    private:\r\n        std::shared_ptr<std::vector<WorkflowTaskOverride>> m_overrides;\r\n        std::ostream& m_out;\r\n        std::istream& m_in;\r\n        bool m_isClone = false;\r\n    };\r\n\r\n    void OverrideForOpenSource(TestContext& context, std::shared_ptr<WorkflowTestSource> testSource, bool overrideOpenCompositeSource = false);\r\n\r\n    void OverrideForCompositeInstalledSource(TestContext& context, std::shared_ptr<WorkflowTestSource> testSource);\r\n\r\n    void OverrideForUpdateInstallerMotw(TestContext& context);\r\n\r\n    void OverrideForCheckExistingInstaller(TestContext& context);\r\n\r\n    void OverrideForShellExecute(TestContext& context, int expectedUseCount = -1);\r\n\r\n    void OverrideForShellExecute(TestContext& context, std::vector<AppInstaller::Manifest::Dependency>& installationLog);\r\n\r\n    void OverrideForPortableInstall(TestContext& context);\r\n\r\n    void OverrideForPortableInstallFlow(TestContext& context);\r\n\r\n    void OverridePortableInstaller(TestContext& context);\r\n\r\n    void OverrideForExtractInstallerFromArchive(TestContext& context);\r\n\r\n    void OverrideForVerifyAndSetNestedInstaller(TestContext& context);\r\n\r\n    void OverrideForMSIX(TestContext& context);\r\n\r\n    void OverrideForMSStore(TestContext& context, bool isUpdate);\r\n\r\n    void OverrideOpenDependencySource(TestContext& context);\r\n\r\n    void OverrideEnableWindowsFeaturesDependencies(TestContext& context);\r\n\r\n    void OverrideRegisterStartupAfterReboot(TestContext& context);\r\n\r\n    void OverrideDownloadInstallerFileForMSStoreDownload(TestContext& context);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/WorkflowGroupPolicy.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"TestCommon.h\"\n#include \"TestSettings.h\"\n#include \"AppInstallerErrors.h\"\n#include \"Commands/InstallCommand.h\"\n#include \"Commands/RootCommand.h\"\n#include \"Commands/ShowCommand.h\"\n#include \"Commands/UpgradeCommand.h\"\n#include \"Commands/ValidateCommand.h\"\n\nusing namespace TestCommon;\nusing namespace AppInstaller::CLI;\nusing namespace AppInstaller::Settings;\nusing namespace std::string_view_literals;\n\n\nTEST_CASE(\"GroupPolicy_WinGet\", \"[groupPolicy]\")\n{\n    GroupPolicyTestOverride policies;\n    policies.SetState(TogglePolicy::Policy::WinGet, PolicyState::Disabled);\n\n    SECTION(\"Install is blocked\")\n    {\n        std::ostringstream output;\n        Execution::Context context{ output, std::cin };\n        context.Args.AddArg(Execution::Args::Type::Query, \"Fake.Package\"sv);\n        InstallCommand installCommand({});\n\n        REQUIRE_POLICY_EXCEPTION(\n            installCommand.Execute(context),\n            TogglePolicy::Policy::WinGet);\n    }\n    SECTION(\"Info is not blocked\")\n    {\n        std::ostringstream output;\n        Execution::Context context{ output, std::cin };\n        context.Args.AddArg(Execution::Args::Type::Info);\n        RootCommand rootCommand({});\n\n        rootCommand.Execute(context);\n\n        REQUIRE_FALSE(context.IsTerminated());\n    }\n}\n\nTEST_CASE(\"GroupPolicy_SettingsCommand\", \"[groupPolicy]\")\n{\n    GroupPolicyTestOverride policies;\n    policies.SetState(TogglePolicy::Policy::Settings, PolicyState::Disabled);\n\n    Invocation inv{ std::vector<std::string>{ \"settings\" } };\n    RootCommand rootCommand;\n    REQUIRE_THROWS(rootCommand.FindSubCommand(inv));\n}\n\nTEST_CASE(\"GroupPolicy_LocalManifests\", \"[groupPolicy]\")\n{\n    GroupPolicyTestOverride policies;\n    policies.SetState(TogglePolicy::Policy::LocalManifestFiles, PolicyState::Disabled);\n\n    SECTION(\"Blocked on install\")\n    {\n        Execution::Args args;\n        args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_Exe.yaml\").GetPath().u8string());\n        InstallCommand installCommand({});\n        REQUIRE_THROWS(installCommand.ValidateArguments(args));\n    }\n    SECTION(\"Blocked on upgrade\")\n    {\n        Execution::Args args;\n        args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_Exe.yaml\").GetPath().u8string());\n        UpgradeCommand upgradeCommand({});\n        REQUIRE_THROWS(upgradeCommand.ValidateArguments(args));\n    }\n    SECTION(\"Allowed on show\")\n    {\n        Execution::Args args;\n        args.AddArg(Execution::Args::Type::Manifest, TestDataFile(\"InstallFlowTest_Exe.yaml\").GetPath().u8string());\n        ShowCommand showCommand({});\n        REQUIRE_NOTHROW(showCommand.ValidateArguments(args));\n    }\n    SECTION(\"Allowed on validate\")\n    {\n        Execution::Args args;\n        args.AddArg(Execution::Args::Type::ValidateManifest, TestDataFile(\"InstallFlowTest_Exe.yaml\").GetPath().u8string());\n        ValidateCommand validateCommand({});\n        REQUIRE_NOTHROW(validateCommand.ValidateArguments(args));\n    }\n}\n\nTEST_CASE(\"GroupPolicy_Info\", \"[groupPolicy]\")\n{\n    GroupPolicyTestOverride policies;\n\n    std::ostringstream output;\n    Execution::Context context{ output, std::cin };\n    context.Args.AddArg(Execution::Args::Type::Info);\n    RootCommand rootCommand({});\n\n    SECTION(\"Does not list not configured\")\n    {\n        rootCommand.Execute(context);\n        INFO(output.str());\n\n        REQUIRE_FALSE(context.IsTerminated());\n        REQUIRE(output.str().find(\"Group Policy\") == std::string::npos);\n    }\n    SECTION(\"Shows enabled policies\")\n    {\n        policies.SetState(TogglePolicy::Policy::HashOverride, PolicyState::Enabled);\n\n        rootCommand.Execute(context);\n        INFO(output.str());\n\n        REQUIRE_FALSE(context.IsTerminated());\n        REQUIRE(output.str().find(\"Group Policy\") != std::string::npos);\n        REQUIRE(output.str().find(\"Hash Override Enabled\") != std::string::npos);\n    }\n    SECTION(\"Shows disabled policies\")\n    {\n        policies.SetState(TogglePolicy::Policy::LocalManifestFiles, PolicyState::Disabled);\n\n        rootCommand.Execute(context);\n        INFO(output.str());\n\n        REQUIRE_FALSE(context.IsTerminated());\n        REQUIRE(output.str().find(\"Group Policy\") != std::string::npos);\n        REQUIRE(output.str().find(\"Local Manifest Files Disabled\") != std::string::npos);\n    }\n    SECTION(\"Shows auto update interval\")\n    {\n        policies.SetValue<ValuePolicy::SourceAutoUpdateIntervalInMinutes>(60);\n\n        rootCommand.Execute(context);\n        INFO(output.str());\n\n        REQUIRE_FALSE(context.IsTerminated());\n        REQUIRE(output.str().find(\"Group Policy\") != std::string::npos);\n        REQUIRE(output.str().find(\"Source Auto Update Interval In Minutes 60\") != std::string::npos);\n    }\n    SECTION(\"Shows additional sources list\")\n    {\n        SourceFromPolicy source;\n        source.Name = \"policy-source\";\n        source.Type = \"Test.Type\";\n        source.Arg = \"test-arg\";\n        policies.SetState(TogglePolicy::Policy::AdditionalSources, PolicyState::Enabled);\n        policies.SetValue<ValuePolicy::AdditionalSources>({ source });\n\n        rootCommand.Execute(context);\n        INFO(output.str());\n\n        REQUIRE_FALSE(context.IsTerminated());\n        REQUIRE(output.str().find(\"Group Policy\") != std::string::npos);\n        REQUIRE(output.str().find(\"Sources Enabled\") != std::string::npos);\n        REQUIRE(output.str().find(\"Additional source\") != std::string::npos);\n        REQUIRE(output.str().find(source.Name) != std::string::npos);\n        REQUIRE(output.str().find(source.Type) != std::string::npos);\n        REQUIRE(output.str().find(source.Arg) != std::string::npos);\n    }\n    SECTION(\"Shows allowed sources list\")\n    {\n        SourceFromPolicy source;\n        source.Name = \"allowed-source\";\n        source.Type = \"Test.Type\";\n        source.Arg = \"test-arg\";\n        policies.SetState(TogglePolicy::Policy::AllowedSources, PolicyState::Enabled);\n        policies.SetValue<ValuePolicy::AllowedSources>({ source });\n\n        rootCommand.Execute(context);\n        INFO(output.str());\n\n        REQUIRE_FALSE(context.IsTerminated());\n        REQUIRE(output.str().find(\"Group Policy\") != std::string::npos);\n        REQUIRE(output.str().find(\"Allowed Sources Enabled\") != std::string::npos);\n        REQUIRE(output.str().find(\"Allowed source\") != std::string::npos);\n        REQUIRE(output.str().find(source.Name) != std::string::npos);\n        REQUIRE(output.str().find(source.Type) != std::string::npos);\n        REQUIRE(output.str().find(source.Arg) != std::string::npos);\n    }\n}"
  },
  {
    "path": "src/AppInstallerCLITests/Yaml.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <AppInstallerErrors.h>\r\n#include <winget/Yaml.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::YAML;\r\n\r\n\r\nTEST_CASE(\"YamlParserTypes\", \"[YAML]\")\r\n{\r\n    auto document = AppInstaller::YAML::Load(TestDataFile(\"Node-Types.yaml\"));\r\n\r\n    auto intUnquoted = document[\"IntegerUnquoted\"];\r\n    CHECK(intUnquoted.GetTagType() == Node::TagType::Int);\r\n\r\n    auto intSingleQuoted = document[\"IntegerSingleQuoted\"];\r\n    CHECK(intSingleQuoted.GetTagType() == Node::TagType::Str);\r\n\r\n    auto intDoubleQuoted = document[\"IntegerDoubleQuoted\"];\r\n    CHECK(intDoubleQuoted.GetTagType() == Node::TagType::Str);\r\n\r\n    auto boolTrue = document[\"BooleanTrue\"];\r\n    CHECK(boolTrue.GetTagType() == Node::TagType::Bool);\r\n\r\n    auto strTrue = document[\"StringTrue\"];\r\n    CHECK(strTrue.GetTagType() == Node::TagType::Str);\r\n\r\n    auto boolFalse = document[\"BooleanFalse\"];\r\n    CHECK(boolFalse.GetTagType() == Node::TagType::Bool);\r\n\r\n    auto strFalse = document[\"StringFalse\"];\r\n    CHECK(strFalse.GetTagType() == Node::TagType::Str);\r\n\r\n    auto localTag = document[\"LocalTag\"];\r\n    CHECK(localTag.GetTagType() == Node::TagType::Unknown);\r\n}\r\n\r\nTEST_CASE(\"YamlMergeMappingNode\", \"[YAML]\")\r\n{\r\n    auto document = Load(TestDataFile(\"Node-Mapping.yaml\"));\r\n\r\n    auto mergeNode = document[\"MergeNode\"];\r\n    auto mergeNode2 = document[\"MergeNode2\"];\r\n\r\n    REQUIRE(3 == mergeNode.size());\r\n    REQUIRE(2 == mergeNode2.size());\r\n\r\n    mergeNode.MergeMappingNode(mergeNode2);\r\n\r\n    REQUIRE(5 == mergeNode.size());\r\n}\r\n\r\nTEST_CASE(\"YamlMergeMappingNode_CaseInsensitive\", \"[YAML]\")\r\n{\r\n    auto document = Load(TestDataFile(\"Node-Mapping.yaml\"));\r\n\r\n    auto mergeNode = document[\"MergeNode\"];\r\n    auto mergeNode2 = document[\"MergeNode2\"];\r\n\r\n    REQUIRE(3 == mergeNode.size());\r\n    REQUIRE(2 == mergeNode2.size());\r\n\r\n    mergeNode.MergeMappingNode(mergeNode2, true);\r\n\r\n    REQUIRE(4 == mergeNode.size());\r\n}\r\n\r\nTEST_CASE(\"YamlMergeSequenceNode\", \"[YAML]\")\r\n{\r\n    auto document = Load(TestDataFile(\"Node-Merge.yaml\"));\r\n    auto document2 = Load(TestDataFile(\"Node-Merge2.yaml\"));\r\n\r\n    REQUIRE(3 == document[\"StrawHats\"].size());\r\n    REQUIRE(2 == document2[\"StrawHats\"].size());\r\n\r\n    // Internally will call MergeMappingNode.\r\n    document[\"StrawHats\"].MergeSequenceNode(document2[\"StrawHats\"], \"Bounty\");\r\n    REQUIRE(5 == document[\"StrawHats\"].size());\r\n}\r\n\r\nTEST_CASE(\"YamlMergeSequenceNode_CaseInsensitive\", \"[YAML]\")\r\n{\r\n    auto document = Load(TestDataFile(\"Node-Merge.yaml\"));\r\n    auto document2 = Load(TestDataFile(\"Node-Merge2.yaml\"));\r\n\r\n    REQUIRE(3 == document[\"StrawHats\"].size());\r\n    REQUIRE(2 == document2[\"StrawHats\"].size());\r\n\r\n    // Internally will call MergeMappingNode.\r\n    document[\"StrawHats\"].MergeSequenceNode(document2[\"StrawHats\"], \"Name\", true);\r\n    REQUIRE(4 == document[\"StrawHats\"].size());\r\n\r\n    auto luffy = std::find_if(\r\n        document[\"StrawHats\"].Sequence().begin(),\r\n        document[\"StrawHats\"].Sequence().end(),\r\n        [](Node const& n) { return n[\"Name\"].as<std::string>() == \"Monkey D Luffy\"; });\r\n    REQUIRE(luffy != document[\"StrawHats\"].Sequence().end());\r\n\r\n    // From original node\r\n    REQUIRE((*luffy)[\"Bounty\"].as<std::string>() == \"3,000,000,000\");\r\n\r\n    // From merged node\r\n    REQUIRE((*luffy)[\"Fruit\"].as<std::string>() == \"Gomu Gomu no Mi\");\r\n}\r\n\r\nTEST_CASE(\"YamlMergeNode_MergeSequenceNoKey\", \"[YAML]\")\r\n{\r\n    auto document = Load(TestDataFile(\"Node-Merge.yaml\"));\r\n    auto document2 = Load(TestDataFile(\"Node-Merge2.yaml\"));\r\n\r\n    REQUIRE_THROWS_HR(document[\"StrawHats\"].MergeSequenceNode(document2[\"StrawHats\"], \"Power\"), APPINSTALLER_CLI_ERROR_YAML_INVALID_DATA);\r\n}\r\n\r\nTEST_CASE(\"YamlMappingNode\", \"[YAML]\")\r\n{\r\n    auto document = Load(TestDataFile(\"Node-Mapping.yaml\"));\r\n\r\n    auto node = document[\"key\"];\r\n    REQUIRE(node.as<std::string>() == \"value\");\r\n\r\n    auto node2 = document.GetChildNode(\"KEY\");\r\n    REQUIRE(node2.as<std::string>() == \"value\");\r\n\r\n    auto node3 = document.GetChildNode(\"key\");\r\n    REQUIRE(node3.as<std::string>() == \"value\");\r\n\r\n    auto node4 = document.GetChildNode(\"kEy\");\r\n    REQUIRE(node4.as<std::string>() == \"value\");\r\n\r\n    auto node5 = document.GetChildNode(\"fake\");\r\n    REQUIRE(node5.IsNull());\r\n\r\n    auto node6 = document[\"repeatedkey\"];\r\n    REQUIRE(node6.as<std::string>() == \"repeated value\");\r\n    REQUIRE_THROWS_HR(document.GetChildNode(\"repeatedkey\"), APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY);\r\n\r\n    REQUIRE_THROWS_HR(document.GetChildNode(\"RepeatedKey\"), APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY);\r\n    REQUIRE_THROWS_HR(document[\"RepeatedKey\"], APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY);\r\n}\r\n\r\nTEST_CASE(\"YamlMappingNode_const\", \"[YAML]\")\r\n{\r\n    const auto document = Load(TestDataFile(\"Node-Mapping.yaml\"));\r\n\r\n    auto node = document[\"key\"];\r\n    REQUIRE(node.as<std::string>() == \"value\");\r\n\r\n    auto node2 = document.GetChildNode(\"KEY\");\r\n    REQUIRE(node2.as<std::string>() == \"value\");\r\n\r\n    auto node3 = document.GetChildNode(\"key\");\r\n    REQUIRE(node3.as<std::string>() == \"value\");\r\n\r\n    auto node4 = document.GetChildNode(\"kEy\");\r\n    REQUIRE(node4.as<std::string>() == \"value\");\r\n\r\n    auto node5 = document.GetChildNode(\"fake\");\r\n    REQUIRE(node5.IsNull());\r\n\r\n    auto node6 = document[\"repeatedkey\"];\r\n    REQUIRE(node6.as<std::string>() == \"repeated value\");\r\n    REQUIRE_THROWS_HR(document.GetChildNode(\"repeatedkey\"), APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY);\r\n\r\n    REQUIRE_THROWS_HR(document.GetChildNode(\"RepeatedKey\"), APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY);\r\n    REQUIRE_THROWS_HR(document[\"RepeatedKey\"], APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY);\r\n}\r\n\r\nTEST_CASE(\"YamlContainsEscapeControlCode\", \"[YAML]\")\r\n{\r\n    REQUIRE_THROWS_HR(Load(TestDataFile(\"ContainsEscapeControlCode.yaml\")), APPINSTALLER_CLI_ERROR_LIBYAML_ERROR);\r\n}\r\n\r\nTEST_CASE(\"YamlContainsTooManyNestedLayers\", \"[YAML]\")\r\n{\r\n    REQUIRE_THROWS_HR(Load(TestDataFile(\"ContainsTooManyNestedLayers.yaml\")), APPINSTALLER_CLI_ERROR_YAML_DOC_BUILD_FAILED);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/YamlManifest.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestCommon.h\"\r\n#include <AppInstallerSHA256.h>\r\n#include <AppInstallerLanguageUtilities.h>\r\n#include <winget/ManifestYamlParser.h>\r\n#include <winget/ManifestYamlWriter.h>\r\n#include <winget/Yaml.h>\r\n\r\nusing namespace TestCommon;\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Manifest::YamlParser;\r\nusing namespace AppInstaller::Manifest::YamlWriter;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::YAML;\r\n\r\nnamespace\r\n{\r\n    using MultiValue = std::vector<NormalizedString>;\r\n    bool operator==(const MultiValue& a, const MultiValue& b)\r\n    {\r\n        if (a.size() != b.size())\r\n        {\r\n            return false;\r\n        }\r\n\r\n        for (size_t i = 0; i < a.size(); ++i)\r\n        {\r\n            if (a[i] != b[i])\r\n            {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    void ValidateError(\r\n        const ValidationError& error,\r\n        ValidationError::Level level,\r\n        AppInstaller::StringResource::StringId message,\r\n        std::string field,\r\n        std::string value)\r\n    {\r\n        REQUIRE(level == error.ErrorLevel);\r\n        REQUIRE(message == error.Message);\r\n        REQUIRE(field == error.Context);\r\n        REQUIRE(value == error.Value);\r\n    }\r\n\r\n    void ValidateError(const ValidationError& error, ValidationError::Level level, AppInstaller::StringResource::StringId message)\r\n    {\r\n        ValidateError(error, level, message, std::string(), std::string());\r\n    }\r\n\r\n    struct ManifestExceptionMatcher : public Catch::Matchers::MatcherBase<ManifestException>\r\n    {\r\n        ManifestExceptionMatcher(std::string expectedMessage, bool expectedWarningOnly = false) :\r\n            m_expectedMessage(expectedMessage), m_expectedWarningOnly(expectedWarningOnly) {}\r\n\r\n        // Performs the test for this matcher\r\n        bool match(ManifestException const& e) const override\r\n        {\r\n            return e.GetManifestErrorMessage().find(m_expectedMessage) != std::string::npos &&\r\n                e.IsWarningOnly() == m_expectedWarningOnly;\r\n        }\r\n\r\n        virtual std::string describe() const override {\r\n            std::ostringstream ss;\r\n            ss << std::boolalpha << \"Expected exception message: \" << m_expectedMessage << \" Expected IsWarningOnly: \" << m_expectedWarningOnly;\r\n            return ss.str();\r\n        }\r\n\r\n    private:\r\n        std::string m_expectedMessage;\r\n        bool m_expectedWarningOnly;\r\n    };\r\n\r\n    ManifestValidateOption GetTestManifestValidateOption(\r\n        bool schemaValidationOnly = false,\r\n        bool errorOnVerifiedPublisher = false)\r\n    {\r\n        ManifestValidateOption validateOption;\r\n        validateOption.FullValidation = true;\r\n        validateOption.ThrowOnWarning = true;\r\n        validateOption.SchemaValidationOnly = schemaValidationOnly;\r\n        validateOption.ErrorOnVerifiedPublisherFields = errorOnVerifiedPublisher;\r\n        return validateOption;\r\n    }\r\n\r\n    void TestManifest(\r\n        const std::filesystem::path& manifestPath,\r\n        const std::string& expectedMessage = {},\r\n        bool expectedWarningOnly = false,\r\n        ManifestValidateOption validateOption = GetTestManifestValidateOption())\r\n    {\r\n        INFO(manifestPath.u8string());\r\n\r\n        if (expectedMessage.empty())\r\n        {\r\n            CHECK_NOTHROW(YamlParser::CreateFromPath(TestDataFile(manifestPath), validateOption));\r\n        }\r\n        else\r\n        {\r\n            CHECK_THROWS_MATCHES(YamlParser::CreateFromPath(TestDataFile(manifestPath), validateOption), ManifestException, ManifestExceptionMatcher(expectedMessage, expectedWarningOnly));\r\n        }\r\n    }\r\n\r\n    struct ManifestTestCase\r\n    {\r\n        std::string TestFile;\r\n        std::string ExpectedMessage = {};\r\n        bool IsWarningOnly = false;\r\n        ManifestValidateOption ValidateOption = GetTestManifestValidateOption();\r\n    };\r\n\r\n    void CopyTestDataFilesToFolder(const std::vector<std::string>& testDataFiles, const std::filesystem::path& dest)\r\n    {\r\n        for (const auto& fileName : testDataFiles)\r\n        {\r\n            std::filesystem::copy(TestDataFile(fileName), dest);\r\n        }\r\n    }\r\n\r\n    void RequireContainerInfoPresent(const std::vector<DesiredStateConfigurationContainerInfo>& containers, const DesiredStateConfigurationContainerInfo& info)\r\n    {\r\n        INFO(\"Looking for container info: \" << AppInstaller::ToIntegral(info.Type) << \" - \" << info.RepositoryURL << \" - \" << info.ModuleName);\r\n\r\n        for (const auto& container : containers)\r\n        {\r\n            if (container.Type == info.Type && container.RepositoryURL == info.RepositoryURL && container.ModuleName == info.ModuleName)\r\n            {\r\n                REQUIRE(container.Resources.size() == info.Resources.size());\r\n                for (const auto& resource : info.Resources)\r\n                {\r\n                    INFO(\"Looking for resource: \" << resource.Name);\r\n                    bool foundResource = std::any_of(container.Resources.begin(), container.Resources.end(), [&](const auto& a) { return a.Name == resource.Name; });\r\n                    REQUIRE(foundResource);\r\n                }\r\n\r\n                return;\r\n            }\r\n        }\r\n\r\n        FAIL(\"Did not find a matching container.\");\r\n    }\r\n\r\n    void VerifyV1ManifestContent(const Manifest& manifest, bool isSingleton, ManifestVer manifestVer = { s_ManifestVersionV1 }, bool isExported = false)\r\n    {\r\n        REQUIRE(manifest.Id == \"microsoft.msixsdk\");\r\n        REQUIRE(manifest.Version == \"1.7.32\");\r\n        REQUIRE(manifest.DefaultLocalization.Locale == \"en-US\");\r\n        REQUIRE(manifest.DefaultLocalization.Get<Localization::Publisher>() == \"Microsoft\");\r\n        REQUIRE(manifest.DefaultLocalization.Get<Localization::PublisherUrl>() == \"https://www.microsoft.com\");\r\n        REQUIRE(manifest.DefaultLocalization.Get<Localization::PublisherSupportUrl>() == \"https://www.microsoft.com/support\");\r\n        REQUIRE(manifest.DefaultLocalization.Get<Localization::PrivacyUrl>() == \"https://www.microsoft.com/privacy\");\r\n        REQUIRE(manifest.DefaultLocalization.Get<Localization::Author>() == \"Microsoft\");\r\n        REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageName>() == \"MSIX SDK\");\r\n        REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageUrl>() == \"https://www.microsoft.com/msixsdk/home\");\r\n        REQUIRE(manifest.DefaultLocalization.Get<Localization::License>() == \"MIT License\");\r\n        REQUIRE(manifest.DefaultLocalization.Get<Localization::LicenseUrl>() == \"https://www.microsoft.com/msixsdk/license\");\r\n        REQUIRE(manifest.DefaultLocalization.Get<Localization::Copyright>() == \"Copyright Microsoft Corporation\");\r\n        REQUIRE(manifest.DefaultLocalization.Get<Localization::CopyrightUrl>() == \"https://www.microsoft.com/msixsdk/copyright\");\r\n        REQUIRE(manifest.DefaultLocalization.Get<Localization::ShortDescription>() == \"This is MSIX SDK\");\r\n        REQUIRE(manifest.DefaultLocalization.Get<Localization::Description>() == \"The MSIX SDK project is an effort to enable developers\");\r\n        REQUIRE(manifest.Moniker == \"msixsdk\");\r\n        REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>() == MultiValue{ \"appxsdk\", \"msixsdk\" });\r\n\r\n        if (manifestVer >= ManifestVer{ s_ManifestVersionV1_1 })\r\n        {\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ReleaseNotes>() == \"Default release notes\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::ReleaseNotesUrl>() == \"https://DefaultReleaseNotes.net\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().size() == 1);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).Label == \"DefaultLabel\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).AgreementText == \"DefaultText\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Agreements>().at(0).AgreementUrl == \"https://DefaultAgreementUrl.net\");\r\n        }\r\n\r\n        if (manifestVer >= ManifestVer{ s_ManifestVersionV1_2 })\r\n        {\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::PurchaseUrl>() == \"https://DefaultPurchaseUrl.com\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::InstallationNotes>() == \"Default installation notes\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().size() == 1);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().at(0).DocumentLabel == \"Default document label\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Documentations>().at(0).DocumentUrl == \"https://DefaultDocumentUrl.com\");\r\n        }\r\n\r\n        if (manifestVer >= ManifestVer{ s_ManifestVersionV1_5 })\r\n        {\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().size() == 1);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Url == \"https://testIcon-en-US\");\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).FileType == IconFileTypeEnum::Ico);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Resolution == IconResolutionEnum::Custom);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Theme == IconThemeEnum::Default);\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Sha256 == SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\"));\r\n        }\r\n\r\n        if (!isExported)\r\n        {\r\n            REQUIRE(manifest.DefaultInstallerInfo.Locale == \"en-US\");\r\n            REQUIRE(manifest.DefaultInstallerInfo.Platform == std::vector<PlatformEnum>{ PlatformEnum::Desktop, PlatformEnum::Universal });\r\n            REQUIRE(manifest.DefaultInstallerInfo.MinOSVersion == \"10.0.0.0\");\r\n            REQUIRE(manifest.DefaultInstallerInfo.BaseInstallerType == InstallerTypeEnum::Exe);\r\n            REQUIRE(manifest.DefaultInstallerInfo.Scope == ScopeEnum::Machine);\r\n            REQUIRE(manifest.DefaultInstallerInfo.InstallModes == std::vector<InstallModeEnum>{ InstallModeEnum::Interactive, InstallModeEnum::Silent, InstallModeEnum::SilentWithProgress });\r\n\r\n            const auto& defaultSwitches = manifest.DefaultInstallerInfo.Switches;\r\n            REQUIRE(defaultSwitches.at(InstallerSwitchType::Custom) == \"/custom\");\r\n            REQUIRE(defaultSwitches.at(InstallerSwitchType::SilentWithProgress) == \"/silentwithprogress\");\r\n            REQUIRE(defaultSwitches.at(InstallerSwitchType::Silent) == \"/silence\");\r\n            REQUIRE(defaultSwitches.at(InstallerSwitchType::Interactive) == \"/interactive\");\r\n            REQUIRE(defaultSwitches.at(InstallerSwitchType::Log) == \"/log=<LOGPATH>\");\r\n            REQUIRE(defaultSwitches.at(InstallerSwitchType::InstallLocation) == \"/dir=<INSTALLPATH>\");\r\n            REQUIRE(defaultSwitches.at(InstallerSwitchType::Update) == \"/upgrade\");\r\n\r\n            REQUIRE(manifest.DefaultInstallerInfo.InstallerSuccessCodes == std::vector<DWORD>{ 1, static_cast<DWORD>(0x80070005) });\r\n            REQUIRE(manifest.DefaultInstallerInfo.UpdateBehavior == UpdateBehaviorEnum::UninstallPrevious);\r\n            REQUIRE(manifest.DefaultInstallerInfo.Commands == MultiValue{ \"makemsix\", \"makeappx\" });\r\n            REQUIRE(manifest.DefaultInstallerInfo.Protocols == MultiValue{ \"protocol1\", \"protocol2\" });\r\n            REQUIRE(manifest.DefaultInstallerInfo.FileExtensions == MultiValue{ \"appx\", \"msix\", \"appxbundle\", \"msixbundle\" });\r\n\r\n            const auto& dependencies = manifest.DefaultInstallerInfo.Dependencies;\r\n            REQUIRE(dependencies.HasExactDependency(DependencyType::WindowsFeature, \"IIS\"));\r\n            REQUIRE(dependencies.HasExactDependency(DependencyType::WindowsLibrary, \"VC Runtime\"));\r\n            REQUIRE(dependencies.HasExactDependency(DependencyType::Package, \"Microsoft.MsixSdkDep\", \"1.0.0\"));\r\n            REQUIRE(dependencies.HasExactDependency(DependencyType::External, \"Outside dependencies\"));\r\n            REQUIRE(dependencies.Size() == 4);\r\n\r\n            REQUIRE(manifest.DefaultInstallerInfo.Capabilities == MultiValue{ \"internetClient\" });\r\n            REQUIRE(manifest.DefaultInstallerInfo.RestrictedCapabilities == MultiValue{ \"runFullTrust\" });\r\n            REQUIRE(manifest.DefaultInstallerInfo.PackageFamilyName == \"Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\");\r\n            REQUIRE(manifest.DefaultInstallerInfo.ProductCode == \"{Foo}\");\r\n\r\n            if (manifestVer >= ManifestVer{ s_ManifestVersionV1_1 })\r\n            {\r\n                REQUIRE(manifest.DefaultInstallerInfo.ReleaseDate == \"2021-01-01\");\r\n                REQUIRE(manifest.DefaultInstallerInfo.InstallerAbortsTerminal);\r\n                REQUIRE(manifest.DefaultInstallerInfo.InstallLocationRequired);\r\n                REQUIRE(manifest.DefaultInstallerInfo.RequireExplicitUpgrade);\r\n                REQUIRE(manifest.DefaultInstallerInfo.ElevationRequirement == ElevationRequirementEnum::ElevatesSelf);\r\n                REQUIRE(manifest.DefaultInstallerInfo.UnsupportedOSArchitectures.size() == 1);\r\n                REQUIRE(manifest.DefaultInstallerInfo.UnsupportedOSArchitectures.at(0) == Architecture::Arm);\r\n                REQUIRE(manifest.DefaultInstallerInfo.AppsAndFeaturesEntries.size() == 1);\r\n                REQUIRE(manifest.DefaultInstallerInfo.AppsAndFeaturesEntries.at(0).DisplayName == \"DisplayName\");\r\n                REQUIRE(manifest.DefaultInstallerInfo.AppsAndFeaturesEntries.at(0).DisplayVersion == \"DisplayVersion\");\r\n                REQUIRE(manifest.DefaultInstallerInfo.AppsAndFeaturesEntries.at(0).Publisher == \"Publisher\");\r\n                REQUIRE(manifest.DefaultInstallerInfo.AppsAndFeaturesEntries.at(0).ProductCode == \"ProductCode\");\r\n                REQUIRE(manifest.DefaultInstallerInfo.AppsAndFeaturesEntries.at(0).UpgradeCode == \"UpgradeCode\");\r\n                REQUIRE(manifest.DefaultInstallerInfo.AppsAndFeaturesEntries.at(0).InstallerType == InstallerTypeEnum::Exe);\r\n                REQUIRE(manifest.DefaultInstallerInfo.Markets.AllowedMarkets.size() == 1);\r\n                REQUIRE(manifest.DefaultInstallerInfo.Markets.AllowedMarkets.at(0) == \"US\");\r\n                REQUIRE(manifest.DefaultInstallerInfo.ExpectedReturnCodes.size() == 1);\r\n                REQUIRE(manifest.DefaultInstallerInfo.ExpectedReturnCodes.at(10).ReturnResponseEnum == ExpectedReturnCodeEnum::PackageInUse);\r\n            }\r\n\r\n            if (manifestVer >= ManifestVer{ s_ManifestVersionV1_2 })\r\n            {\r\n                REQUIRE(manifest.DefaultInstallerInfo.DisplayInstallWarnings);\r\n                REQUIRE(manifest.DefaultInstallerInfo.UnsupportedArguments.size() == 1);\r\n                REQUIRE(manifest.DefaultInstallerInfo.UnsupportedArguments.at(0) == UnsupportedArgumentEnum::Log);\r\n            }\r\n\r\n            if (manifestVer >= ManifestVer{ s_ManifestVersionV1_4 })\r\n            {\r\n                REQUIRE(manifest.DefaultInstallerInfo.NestedInstallerType == InstallerTypeEnum::Msi);\r\n                REQUIRE(manifest.DefaultInstallerInfo.NestedInstallerFiles.size() == 1);\r\n                REQUIRE(manifest.DefaultInstallerInfo.NestedInstallerFiles.at(0).RelativeFilePath == \"RelativeFilePath\");\r\n                REQUIRE(manifest.DefaultInstallerInfo.NestedInstallerFiles.at(0).PortableCommandAlias == \"PortableCommandAlias\");\r\n                REQUIRE(manifest.DefaultInstallerInfo.InstallationMetadata.DefaultInstallLocation == \"%ProgramFiles%\\\\TestApp\");\r\n                REQUIRE(manifest.DefaultInstallerInfo.InstallationMetadata.Files.size() == 1);\r\n                REQUIRE(manifest.DefaultInstallerInfo.InstallationMetadata.Files.at(0).RelativeFilePath == \"main.exe\");\r\n                REQUIRE(manifest.DefaultInstallerInfo.InstallationMetadata.Files.at(0).FileType == InstalledFileTypeEnum::Launch);\r\n                REQUIRE(manifest.DefaultInstallerInfo.InstallationMetadata.Files.at(0).FileSha256 == SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\"));\r\n                REQUIRE(manifest.DefaultInstallerInfo.InstallationMetadata.Files.at(0).InvocationParameter == \"/arg\");\r\n            }\r\n\r\n            if (manifestVer >= ManifestVer{ s_ManifestVersionV1_6 })\r\n            {\r\n                REQUIRE(manifest.DefaultInstallerInfo.DownloadCommandProhibited);\r\n            }\r\n\r\n            if (manifestVer >= ManifestVer{ s_ManifestVersionV1_7 })\r\n            {\r\n                REQUIRE(defaultSwitches.at(InstallerSwitchType::Repair) == \"/repair\");\r\n                REQUIRE(manifest.DefaultInstallerInfo.RepairBehavior == RepairBehaviorEnum::Modify);\r\n            }\r\n\r\n            if (manifestVer >= ManifestVer{ s_ManifestVersionV1_9 })\r\n            {\r\n                REQUIRE(manifest.DefaultInstallerInfo.ArchiveBinariesDependOnPath);\r\n            }\r\n        }\r\n\r\n        if (isSingleton || isExported)\r\n        {\r\n            REQUIRE(manifest.Installers.size() == 1);\r\n        }\r\n        else\r\n        {\r\n            if (manifestVer >= ManifestVer{ s_ManifestVersionV1_12 })\r\n            {\r\n                REQUIRE(manifest.Installers.size() == 7);\r\n            }\r\n            else if (manifestVer >= ManifestVer{ s_ManifestVersionV1_7 })\r\n            {\r\n                REQUIRE(manifest.Installers.size() == 5);\r\n            }\r\n            else if (manifestVer >= ManifestVer{ s_ManifestVersionV1_4 })\r\n            {\r\n                REQUIRE(manifest.Installers.size() == 4);\r\n            }\r\n            else if (manifestVer == ManifestVer{ s_ManifestVersionV1_2 })\r\n            {\r\n                REQUIRE(manifest.Installers.size() == 3);\r\n            }\r\n            else\r\n            {\r\n                REQUIRE(manifest.Installers.size() == 2);\r\n            }\r\n        }\r\n\r\n        const ManifestInstaller& installer1 = manifest.Installers.at(0);\r\n        REQUIRE(installer1.Arch == Architecture::X86);\r\n        REQUIRE(installer1.Locale == \"en-GB\");\r\n        REQUIRE(installer1.Platform == std::vector<PlatformEnum>{ PlatformEnum::Desktop });\r\n        REQUIRE(installer1.MinOSVersion == \"10.0.1.0\");\r\n        REQUIRE(installer1.BaseInstallerType == InstallerTypeEnum::Msix);\r\n        REQUIRE(installer1.Url == \"https://www.microsoft.com/msixsdk/msixsdkx86.msix\");\r\n        REQUIRE(installer1.Sha256 == SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\"));\r\n        REQUIRE(installer1.SignatureSha256 == SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\"));\r\n        REQUIRE(installer1.Scope == ScopeEnum::User);\r\n        REQUIRE(installer1.InstallModes == std::vector<InstallModeEnum>{ InstallModeEnum::Interactive });\r\n\r\n        const auto& installer1Switches = installer1.Switches;\r\n        REQUIRE(installer1Switches.at(InstallerSwitchType::Custom) == \"/c\");\r\n        REQUIRE(installer1Switches.at(InstallerSwitchType::SilentWithProgress) == \"/sp\");\r\n        REQUIRE(installer1Switches.at(InstallerSwitchType::Silent) == \"/s\");\r\n        REQUIRE(installer1Switches.at(InstallerSwitchType::Interactive) == \"/i\");\r\n        REQUIRE(installer1Switches.at(InstallerSwitchType::Log) == \"/l=<LOGPATH>\");\r\n        REQUIRE(installer1Switches.at(InstallerSwitchType::InstallLocation) == \"/d=<INSTALLPATH>\");\r\n        REQUIRE(installer1Switches.at(InstallerSwitchType::Update) == \"/u\");\r\n\r\n        REQUIRE(installer1.UpdateBehavior == UpdateBehaviorEnum::Install);\r\n        REQUIRE(installer1.Commands == MultiValue{ \"makemsixPreview\", \"makeappxPreview\" });\r\n        REQUIRE(installer1.Protocols == MultiValue{ \"protocol1preview\", \"protocol2preview\" });\r\n        REQUIRE(installer1.FileExtensions == MultiValue{ \"appxbundle\", \"msixbundle\", \"appx\", \"msix\" });\r\n\r\n        const auto& installer1Dependencies = installer1.Dependencies;\r\n        REQUIRE(installer1Dependencies.HasExactDependency(DependencyType::WindowsFeature, \"PreviewIIS\"));\r\n        REQUIRE(installer1Dependencies.HasExactDependency(DependencyType::WindowsLibrary, \"Preview VC Runtime\"));\r\n        REQUIRE(installer1Dependencies.HasExactDependency(DependencyType::Package, \"Microsoft.MsixSdkDepPreview\", \"1.0.0\"));\r\n        REQUIRE(installer1Dependencies.HasExactDependency(DependencyType::External, \"Preview Outside dependencies\"));\r\n        REQUIRE(installer1Dependencies.Size() == 4);\r\n\r\n        REQUIRE(installer1.Capabilities == MultiValue{ \"internetClientPreview\" });\r\n        REQUIRE(installer1.RestrictedCapabilities == MultiValue{ \"runFullTrustPreview\" });\r\n        REQUIRE(installer1.PackageFamilyName == \"Microsoft.DesktopAppInstallerPreview_8wekyb3d8bbwe\");\r\n\r\n        if (manifestVer >= ManifestVer{ s_ManifestVersionV1_1 })\r\n        {\r\n            REQUIRE(installer1.ReleaseDate == \"2021-02-02\");\r\n            REQUIRE_FALSE(installer1.InstallerAbortsTerminal);\r\n            REQUIRE_FALSE(installer1.InstallLocationRequired);\r\n            REQUIRE_FALSE(installer1.RequireExplicitUpgrade);\r\n            REQUIRE(installer1.ElevationRequirement == ElevationRequirementEnum::ElevationRequired);\r\n            REQUIRE(installer1.UnsupportedOSArchitectures.size() == 1);\r\n            REQUIRE(installer1.UnsupportedOSArchitectures.at(0) == Architecture::Arm64);\r\n            REQUIRE(installer1.AppsAndFeaturesEntries.size() == 0);\r\n            REQUIRE(installer1.Markets.AllowedMarkets.size() == 0);\r\n            REQUIRE(installer1.Markets.ExcludedMarkets.size() == 1);\r\n            REQUIRE(installer1.Markets.ExcludedMarkets.at(0) == \"US\");\r\n            REQUIRE(installer1.ExpectedReturnCodes.at(2).ReturnResponseEnum == ExpectedReturnCodeEnum::ContactSupport);\r\n        }\r\n\r\n        if (manifestVer >= ManifestVer{ s_ManifestVersionV1_2 })\r\n        {\r\n            REQUIRE_FALSE(installer1.DisplayInstallWarnings);\r\n            REQUIRE(installer1.ExpectedReturnCodes.at(3).ReturnResponseEnum == ExpectedReturnCodeEnum::Custom);\r\n            REQUIRE(installer1.ExpectedReturnCodes.at(3).ReturnResponseUrl == \"https://defaultReturnResponseUrl.com\");\r\n            REQUIRE(installer1.UnsupportedArguments.size() == 1);\r\n            REQUIRE(installer1.UnsupportedArguments.at(0) == UnsupportedArgumentEnum::Location);\r\n        }\r\n\r\n        if (manifestVer >= ManifestVer{ s_ManifestVersionV1_4 })\r\n        {\r\n            // NestedInstaller metadata should not be populated unless the InstallerType is zip.\r\n            REQUIRE(installer1.NestedInstallerType == InstallerTypeEnum::Unknown);\r\n            REQUIRE(installer1.NestedInstallerFiles.size() == 0);\r\n\r\n            REQUIRE(installer1.InstallationMetadata.DefaultInstallLocation == \"%ProgramFiles%\\\\TestApp\");\r\n            REQUIRE(installer1.InstallationMetadata.Files.size() == 1);\r\n            REQUIRE(installer1.InstallationMetadata.Files.at(0).RelativeFilePath == \"main.exe\");\r\n            REQUIRE(installer1.InstallationMetadata.Files.at(0).FileType == InstalledFileTypeEnum::Launch);\r\n            REQUIRE(installer1.InstallationMetadata.Files.at(0).FileSha256 == SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\"));\r\n            REQUIRE(installer1.InstallationMetadata.Files.at(0).InvocationParameter == \"/arg\");\r\n            REQUIRE(installer1.InstallationMetadata.Files.at(0).DisplayName == \"DisplayName\");\r\n        }\r\n\r\n        if (manifestVer >= ManifestVer{ s_ManifestVersionV1_6 })\r\n        {\r\n            REQUIRE_FALSE(installer1.DownloadCommandProhibited);\r\n        }\r\n\r\n        if (manifestVer >= ManifestVer{ s_ManifestVersionV1_7 })\r\n        {\r\n            REQUIRE(installer1.Switches.at(InstallerSwitchType::Repair) == \"/r\");\r\n            REQUIRE(installer1.RepairBehavior == RepairBehaviorEnum::Modify);\r\n        }\r\n\r\n        if (manifestVer >= ManifestVer{ s_ManifestVersionV1_9 })\r\n        {\r\n            REQUIRE_FALSE(installer1.ArchiveBinariesDependOnPath);\r\n        }\r\n\r\n        if (manifestVer >= ManifestVer{ s_ManifestVersionV1_28 })\r\n        {\r\n            auto containers = &manifest.DefaultInstallerInfo.DesiredStateConfiguration;\r\n            if (isExported)\r\n            {\r\n                containers = &manifest.Installers[0].DesiredStateConfiguration;\r\n            }\r\n\r\n            RequireContainerInfoPresent(*containers, { { { \"Microsoft.WinGet/AdminSettings\" }, { \"Microsoft.WinGet/Package\" }, { \"Microsoft.WinGet/Source\" }, { \"Microsoft.WinGet/UserSettingsFile\" } } });\r\n        }\r\n\r\n        if (!isSingleton)\r\n        {\r\n            if (!isExported)\r\n            {\r\n                const ManifestInstaller& installer2 = manifest.Installers.at(1);\r\n                REQUIRE(installer2.BaseInstallerType == InstallerTypeEnum::Exe);\r\n                REQUIRE(installer2.Arch == Architecture::X64);\r\n                REQUIRE(installer2.Url == \"https://www.microsoft.com/msixsdk/msixsdkx64.exe\");\r\n                REQUIRE(installer2.Sha256 == SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\"));\r\n                REQUIRE(installer2.ProductCode == \"{Bar}\");\r\n\r\n                if (manifestVer >= ManifestVer{ s_ManifestVersionV1_1 })\r\n                {\r\n                    REQUIRE(installer2.ReleaseDate == \"2021-01-01\");\r\n                    REQUIRE(installer2.InstallerAbortsTerminal);\r\n                    REQUIRE(installer2.InstallLocationRequired);\r\n                    REQUIRE(installer2.RequireExplicitUpgrade);\r\n                    REQUIRE(installer2.ElevationRequirement == ElevationRequirementEnum::ElevatesSelf);\r\n                    REQUIRE(installer2.UnsupportedOSArchitectures.size() == 1);\r\n                    REQUIRE(installer2.UnsupportedOSArchitectures.at(0) == Architecture::Arm);\r\n                    REQUIRE(installer2.AppsAndFeaturesEntries.size() == 1);\r\n                    REQUIRE(installer2.AppsAndFeaturesEntries.at(0).DisplayName == \"DisplayName\");\r\n                    REQUIRE(installer2.AppsAndFeaturesEntries.at(0).DisplayVersion == \"DisplayVersion\");\r\n                    REQUIRE(installer2.AppsAndFeaturesEntries.at(0).Publisher == \"Publisher\");\r\n                    REQUIRE(installer2.AppsAndFeaturesEntries.at(0).ProductCode == \"ProductCode\");\r\n                    REQUIRE(installer2.AppsAndFeaturesEntries.at(0).UpgradeCode == \"UpgradeCode\");\r\n                    REQUIRE(installer2.AppsAndFeaturesEntries.at(0).InstallerType == InstallerTypeEnum::Exe);\r\n                    REQUIRE(installer2.Markets.AllowedMarkets.size() == 1);\r\n                    REQUIRE(installer2.Markets.AllowedMarkets.at(0) == \"US\");\r\n                    REQUIRE(installer2.ExpectedReturnCodes.size() == 1);\r\n                    REQUIRE(installer2.ExpectedReturnCodes.at(10).ReturnResponseEnum == ExpectedReturnCodeEnum::PackageInUse);\r\n                }\r\n\r\n                if (manifestVer >= ManifestVer{ s_ManifestVersionV1_2 })\r\n                {\r\n                    const ManifestInstaller& installer3 = manifest.Installers.at(2);\r\n                    REQUIRE(installer3.BaseInstallerType == InstallerTypeEnum::Portable);\r\n                    REQUIRE(installer3.Arch == Architecture::X86);\r\n                    REQUIRE(installer3.Url == \"https://www.microsoft.com/msixsdk/msixsdkx86.exe\");\r\n                    REQUIRE(installer3.Sha256 == SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\"));\r\n                    REQUIRE(installer3.Commands == MultiValue{ \"standalone\" });\r\n                    REQUIRE(installer3.ExpectedReturnCodes.size() == 1);\r\n                    REQUIRE(installer3.ExpectedReturnCodes.at(11).ReturnResponseEnum == ExpectedReturnCodeEnum::Custom);\r\n                    REQUIRE(installer3.ExpectedReturnCodes.at(11).ReturnResponseUrl == \"https://defaultReturnResponseUrl.com\");\r\n                    REQUIRE_FALSE(installer3.DisplayInstallWarnings);\r\n                    REQUIRE(installer3.UnsupportedArguments.size() == 1);\r\n                    REQUIRE(installer3.UnsupportedArguments.at(0) == UnsupportedArgumentEnum::Log);\r\n                }\r\n\r\n                if (manifestVer >= ManifestVer{ s_ManifestVersionV1_4 })\r\n                {\r\n                    const ManifestInstaller& installer4 = manifest.Installers.at(3);\r\n                    REQUIRE(installer4.BaseInstallerType == InstallerTypeEnum::Zip);\r\n                    REQUIRE(installer4.Arch == Architecture::X64);\r\n                    REQUIRE(installer4.Url == \"https://www.microsoft.com/msixsdk/msixsdkx64.exe\");\r\n                    REQUIRE(installer4.Sha256 == SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\"));\r\n                    REQUIRE(installer4.ProductCode == \"{Foo}\");\r\n                    REQUIRE(installer4.NestedInstallerType == InstallerTypeEnum::Portable);\r\n                    REQUIRE(installer4.NestedInstallerFiles.size() == 2);\r\n                    REQUIRE(installer4.NestedInstallerFiles.at(0).RelativeFilePath == \"relativeFilePath1\");\r\n                    REQUIRE(installer4.NestedInstallerFiles.at(0).PortableCommandAlias == \"portableAlias1\");\r\n                    REQUIRE(installer4.NestedInstallerFiles.at(1).RelativeFilePath == \"relativeFilePath2\");\r\n                    REQUIRE(installer4.NestedInstallerFiles.at(1).PortableCommandAlias == \"portableAlias2\");\r\n                    REQUIRE(installer4.InstallationMetadata.DefaultInstallLocation == \"%ProgramFiles%\\\\TestApp2\");\r\n                    REQUIRE(installer4.InstallationMetadata.Files.size() == 1);\r\n                    REQUIRE(installer4.InstallationMetadata.Files.at(0).RelativeFilePath == \"main2.exe\");\r\n                    REQUIRE(installer4.InstallationMetadata.Files.at(0).FileType == InstalledFileTypeEnum::Other);\r\n                    REQUIRE(installer4.InstallationMetadata.Files.at(0).FileSha256 == SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\"));\r\n                    REQUIRE(installer4.InstallationMetadata.Files.at(0).InvocationParameter == \"/arg2\");\r\n                    REQUIRE(installer4.InstallationMetadata.Files.at(0).DisplayName == \"DisplayName2\");\r\n                }\r\n\r\n                if (manifestVer >= ManifestVer{ s_ManifestVersionV1_6 })\r\n                {\r\n                    REQUIRE(installer2.DownloadCommandProhibited);\r\n                    REQUIRE(installer2.UpdateBehavior == UpdateBehaviorEnum::Deny);\r\n                }\r\n\r\n                if (manifestVer >= ManifestVer{ s_ManifestVersionV1_7 })\r\n                {\r\n                    REQUIRE(installer2.RepairBehavior == RepairBehaviorEnum::Uninstaller);\r\n                    REQUIRE(installer2.Switches.at(InstallerSwitchType::Repair) == \"/r\");\r\n\r\n                    const ManifestInstaller& installer5 = manifest.Installers.at(4);\r\n                    REQUIRE(installer5.BaseInstallerType == InstallerTypeEnum::Burn);\r\n                    REQUIRE(installer5.Arch == Architecture::X64);\r\n                    REQUIRE(installer5.Url == \"https://www.microsoft.com/msixsdk/msixsdkx64.exe\");\r\n                    REQUIRE(installer5.Sha256 == SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\"));\r\n                    REQUIRE(installer5.ProductCode == \"{Bar}\");\r\n                    REQUIRE(installer5.Switches.at(InstallerSwitchType::Repair) == \"/repair\");\r\n                    REQUIRE(installer5.RepairBehavior == RepairBehaviorEnum::Modify);\r\n                }\r\n\r\n                if (manifestVer >= ManifestVer{ s_ManifestVersionV1_9 })\r\n                {\r\n                    const ManifestInstaller& installer4 = manifest.Installers.at(3);\r\n                    REQUIRE(installer4.ArchiveBinariesDependOnPath);\r\n                }\r\n\r\n                if (manifestVer >= ManifestVer{ s_ManifestVersionV1_12 })\r\n                {\r\n                    const ManifestInstaller& installer6 = manifest.Installers.at(5);\r\n                    REQUIRE(installer6.BaseInstallerType == InstallerTypeEnum::Zip);\r\n                    REQUIRE(installer6.Arch == Architecture::Neutral);\r\n                    REQUIRE(installer6.Url == \"https://www.microsoft.com/msixsdk/msixsdkx64.exe\");\r\n                    REQUIRE(installer6.Sha256 == SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\"));\r\n                    REQUIRE(installer6.NestedInstallerType == InstallerTypeEnum::Font);\r\n                    REQUIRE(installer6.NestedInstallerFiles.size() == 5);\r\n                    REQUIRE(installer6.NestedInstallerFiles.at(0).RelativeFilePath == \"relativeFilePath1.otf\");\r\n                    REQUIRE(installer6.NestedInstallerFiles.at(1).RelativeFilePath == \"relativeFilePath2.ttf\");\r\n                    REQUIRE(installer6.NestedInstallerFiles.at(2).RelativeFilePath == \"relativeFilePath3.fnt\");\r\n                    REQUIRE(installer6.NestedInstallerFiles.at(3).RelativeFilePath == \"relativeFilePath4.ttc\");\r\n                    REQUIRE(installer6.NestedInstallerFiles.at(4).RelativeFilePath == \"relativeFilePath5.otc\");\r\n\r\n                    const ManifestInstaller& installer7 = manifest.Installers.at(6);\r\n                    REQUIRE(installer7.BaseInstallerType == InstallerTypeEnum::Font);\r\n                    REQUIRE(installer7.Arch == Architecture::Neutral);\r\n                    REQUIRE(installer7.Url == \"https://www.microsoft.com/msixsdk/msixsdkx64.exe\");\r\n                    REQUIRE(installer7.Sha256 == SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\"));\r\n                }\r\n\r\n                if (manifestVer >= ManifestVer{ s_ManifestVersionV1_28 })\r\n                {\r\n                    RequireContainerInfoPresent(manifest.Installers[1].DesiredStateConfiguration, { { { \"None/None\" } } });\r\n                    REQUIRE(manifest.Installers[2].DesiredStateConfiguration.size() == 0);\r\n                }\r\n            }\r\n\r\n            // Localization\r\n            REQUIRE(manifest.Localizations.size() == 1);\r\n            const ManifestLocalization& localization1 = manifest.Localizations.at(0);\r\n            REQUIRE(localization1.Locale == \"en-GB\");\r\n            REQUIRE(localization1.Get<Localization::Publisher>() == \"Microsoft UK\");\r\n            REQUIRE(localization1.Get<Localization::PublisherUrl>() == \"https://www.microsoft.com/UK\");\r\n            REQUIRE(localization1.Get<Localization::PublisherSupportUrl>() == \"https://www.microsoft.com/support/UK\");\r\n            REQUIRE(localization1.Get<Localization::PrivacyUrl>() == \"https://www.microsoft.com/privacy/UK\");\r\n            REQUIRE(localization1.Get<Localization::Author>() == \"Microsoft UK\");\r\n            REQUIRE(localization1.Get<Localization::PackageName>() == \"MSIX SDK UK\");\r\n            REQUIRE(localization1.Get<Localization::PackageUrl>() == \"https://www.microsoft.com/msixsdk/home/UK\");\r\n            REQUIRE(localization1.Get<Localization::License>() == \"MIT License UK\");\r\n            REQUIRE(localization1.Get<Localization::LicenseUrl>() == \"https://www.microsoft.com/msixsdk/license/UK\");\r\n            REQUIRE(localization1.Get<Localization::Copyright>() == \"Copyright Microsoft Corporation UK\");\r\n            REQUIRE(localization1.Get<Localization::CopyrightUrl>() == \"https://www.microsoft.com/msixsdk/copyright/UK\");\r\n            REQUIRE(localization1.Get<Localization::ShortDescription>() == \"This is MSIX SDK UK\");\r\n            REQUIRE(localization1.Get<Localization::Description>() == \"The MSIX SDK project is an effort to enable developers UK\");\r\n            REQUIRE(localization1.Get<Localization::Tags>() == MultiValue{ \"appxsdkUK\", \"msixsdkUK\" });\r\n\r\n            if (manifestVer >= ManifestVer{ s_ManifestVersionV1_1 })\r\n            {\r\n                REQUIRE(localization1.Get<Localization::ReleaseNotes>() == \"Release notes\");\r\n                REQUIRE(localization1.Get<Localization::ReleaseNotesUrl>() == \"https://ReleaseNotes.net\");\r\n                REQUIRE(localization1.Get<Localization::Agreements>().size() == 1);\r\n                REQUIRE(localization1.Get<Localization::Agreements>().at(0).Label == \"Label\");\r\n                REQUIRE(localization1.Get<Localization::Agreements>().at(0).AgreementText == \"Text\");\r\n                REQUIRE(localization1.Get<Localization::Agreements>().at(0).AgreementUrl == \"https://AgreementUrl.net\");\r\n            }\r\n\r\n            if (manifestVer >= ManifestVer{ s_ManifestVersionV1_2 })\r\n            {\r\n                REQUIRE(localization1.Get<Localization::PurchaseUrl>() == \"https://DefaultPurchaseUrl.com\");\r\n                REQUIRE(localization1.Get<Localization::InstallationNotes>() == \"Default installation notes\");\r\n                REQUIRE(localization1.Get<Localization::Documentations>().size() == 1);\r\n                REQUIRE(localization1.Get<Localization::Documentations>().at(0).DocumentLabel == \"Default document label\");\r\n                REQUIRE(localization1.Get<Localization::Documentations>().at(0).DocumentUrl == \"https://DefaultDocumentUrl.com\");\r\n            }\r\n\r\n            if (manifestVer >= ManifestVer{ s_ManifestVersionV1_5 })\r\n            {\r\n                REQUIRE(localization1.Get<Localization::Icons>().size() == 1);\r\n                REQUIRE(localization1.Get<Localization::Icons>().at(0).Url == \"https://localeTestIcon-en-GB\");\r\n                REQUIRE(localization1.Get<Localization::Icons>().at(0).FileType == IconFileTypeEnum::Png);\r\n                REQUIRE(localization1.Get<Localization::Icons>().at(0).Resolution == IconResolutionEnum::Square32);\r\n                REQUIRE(localization1.Get<Localization::Icons>().at(0).Theme == IconThemeEnum::Light);\r\n                REQUIRE(localization1.Get<Localization::Icons>().at(0).Sha256 == SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321\"));\r\n            }\r\n        }\r\n    }\r\n\r\n    struct ManifestShadowTestInfo\r\n    {\r\n        bool shadowDefaultLocale;\r\n        bool shadowEnGbLocale;\r\n    };\r\n\r\n    void VerifyV1ManifestContentCreatedWithShadow(const Manifest& manifest, ManifestShadowTestInfo shadowInfo, ManifestVer manifestVer = { s_ManifestVersionV1_5 })\r\n    {\r\n        REQUIRE(manifest.Id == \"microsoft.msixsdk\");\r\n        REQUIRE(manifest.Version == \"1.7.32\");\r\n        REQUIRE(manifest.Installers.size() == 1);\r\n\r\n        // Default localization\r\n        REQUIRE(manifest.DefaultLocalization.Locale == \"en-US\");\r\n        REQUIRE(manifest.DefaultLocalization.Get<Localization::Publisher>() == \"Microsoft\");\r\n        REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageName>() == \"MSIX SDK\");\r\n        REQUIRE(manifest.DefaultLocalization.Get<Localization::License>() == \"MIT License\");\r\n        REQUIRE(manifest.DefaultLocalization.Get<Localization::Description>() == \"The MSIX SDK project is an effort to enable developers\");\r\n        REQUIRE(manifest.DefaultLocalization.Get<Localization::ShortDescription>() == \"This is MSIX SDK\");\r\n        if (manifestVer >= ManifestVer{ s_ManifestVersionV1_5 })\r\n        {\r\n            REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().size() == 1);\r\n\r\n            if (shadowInfo.shadowDefaultLocale)\r\n            {\r\n                REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Url == \"https://shadowIcon-default\");\r\n                REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).FileType == IconFileTypeEnum::Ico);\r\n                REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Resolution == IconResolutionEnum::Custom);\r\n                REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Theme == IconThemeEnum::Default);\r\n                REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Sha256 == SHA256::ConvertToBytes(\"1111111111111111111111111111111111111111111111111111111111111111\"));\r\n            }\r\n            else\r\n            {\r\n                REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().size() == 1);\r\n                REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Url == \"https://testIcon-en-US\");\r\n                REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).FileType == IconFileTypeEnum::Ico);\r\n                REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Resolution == IconResolutionEnum::Custom);\r\n                REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Theme == IconThemeEnum::Default);\r\n                REQUIRE(manifest.DefaultLocalization.Get<Localization::Icons>().at(0).Sha256 == SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8123\"));\r\n            }\r\n        }\r\n\r\n        // Localization\r\n        if (manifestVer >= ManifestVer{ s_ManifestVersionV1_5 })\r\n        {\r\n            REQUIRE(manifest.Localizations.size() == 3);\r\n\r\n            bool foundEnGbLocale = false;\r\n            bool foundfrFrLocale = false;\r\n            for (auto const& localization : manifest.Localizations)\r\n            {\r\n                if (localization.Locale == \"en-GB\")\r\n                {\r\n                    REQUIRE(localization.Get<Localization::Description>() == \"The MSIX SDK project is an effort to enable developers UK\");\r\n                    if (shadowInfo.shadowEnGbLocale)\r\n                    {\r\n                        REQUIRE(localization.Get<Localization::Icons>().size() == 1);\r\n                        REQUIRE(localization.Get<Localization::Icons>().at(0).Url == \"https://shadowIcon-en-GB\");\r\n                        REQUIRE(localization.Get<Localization::Icons>().at(0).FileType == IconFileTypeEnum::Png);\r\n                        REQUIRE(localization.Get<Localization::Icons>().at(0).Resolution == IconResolutionEnum::Square32);\r\n                        REQUIRE(localization.Get<Localization::Icons>().at(0).Theme == IconThemeEnum::Light);\r\n                        REQUIRE(localization.Get<Localization::Icons>().at(0).Sha256 == SHA256::ConvertToBytes(\"2222222222222222222222222222222222222222222222222222222222222222\"));\r\n                    }\r\n                    else\r\n                    {\r\n                        REQUIRE(localization.Get<Localization::Icons>().size() == 1);\r\n                        REQUIRE(localization.Get<Localization::Icons>().at(0).Url == \"https://localeTestIcon-en-GB\");\r\n                        REQUIRE(localization.Get<Localization::Icons>().at(0).FileType == IconFileTypeEnum::Png);\r\n                        REQUIRE(localization.Get<Localization::Icons>().at(0).Resolution == IconResolutionEnum::Square32);\r\n                        REQUIRE(localization.Get<Localization::Icons>().at(0).Theme == IconThemeEnum::Light);\r\n                        REQUIRE(localization.Get<Localization::Icons>().at(0).Sha256 == SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8321\"));\r\n                    }\r\n\r\n                    foundEnGbLocale = true;\r\n                }\r\n                else if (localization.Locale == \"fr-FR\")\r\n                {\r\n                    REQUIRE(localization.Get<Localization::Icons>().size() == 1);\r\n                    REQUIRE(localization.Get<Localization::Icons>().at(0).Url == \"https://shadowIcon-fr-FR\");\r\n                    REQUIRE(localization.Get<Localization::Icons>().at(0).FileType == IconFileTypeEnum::Jpeg);\r\n                    REQUIRE(localization.Get<Localization::Icons>().at(0).Resolution == IconResolutionEnum::Square20);\r\n                    REQUIRE(localization.Get<Localization::Icons>().at(0).Theme == IconThemeEnum::Dark);\r\n                    REQUIRE(localization.Get<Localization::Icons>().at(0).Sha256 == SHA256::ConvertToBytes(\"3333333333333333333333333333333333333333333333333333333333333333\"));\r\n                    foundfrFrLocale = true;\r\n                }\r\n                else\r\n                {\r\n                    REQUIRE(localization.Locale == \"es-MX\");\r\n                    REQUIRE(localization.Get<Localization::Description>() == \"The MSIX SDK project is an effort to enable developers MX\");\r\n                    REQUIRE(localization.Get<Localization::Icons>().size() == 1);\r\n                    REQUIRE(localization.Get<Localization::Icons>().at(0).Url == \"https://localeTestIcon-es-MX\");\r\n                    REQUIRE(localization.Get<Localization::Icons>().at(0).FileType == IconFileTypeEnum::Png);\r\n                    REQUIRE(localization.Get<Localization::Icons>().at(0).Resolution == IconResolutionEnum::Square32);\r\n                    REQUIRE(localization.Get<Localization::Icons>().at(0).Theme == IconThemeEnum::Light);\r\n                    REQUIRE(localization.Get<Localization::Icons>().at(0).Sha256 == SHA256::ConvertToBytes(\"4444444444444444444444444444444444444444444444444444444444444444\"));\r\n                }\r\n            }\r\n\r\n            REQUIRE(foundEnGbLocale);\r\n            REQUIRE(foundfrFrLocale);\r\n        }\r\n    }\r\n}\r\n\r\nTEST_CASE(\"ReadPreviewGoodManifestAndVerifyContents\", \"[ManifestValidation]\")\r\n{\r\n    auto manifestFile = TestDataFile(\"Manifest-Good.yaml\");\r\n    Manifest manifest = YamlParser::CreateFromPath(manifestFile);\r\n\r\n    REQUIRE(manifest.Id == \"microsoft.msixsdk\");\r\n    REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageName>() == \"MSIX SDK\");\r\n    REQUIRE(manifest.Moniker == \"msixsdk\");\r\n    REQUIRE(manifest.Version == \"1.7.32\");\r\n    REQUIRE(manifest.DefaultLocalization.Get<Localization::Publisher>() == \"Microsoft\");\r\n    REQUIRE(manifest.Channel == \"release\");\r\n    REQUIRE(manifest.DefaultLocalization.Get<Localization::Author>() == \"Microsoft\");\r\n    REQUIRE(manifest.DefaultLocalization.Get<Localization::License>() == \"MIT License\");\r\n    REQUIRE(manifest.DefaultLocalization.Get<Localization::LicenseUrl>() == \"https://github.com/microsoft/msix-packaging/blob/master/LICENSE\");\r\n    REQUIRE(manifest.DefaultInstallerInfo.MinOSVersion == \"0.0.0.0\");\r\n    REQUIRE(manifest.DefaultLocalization.Get<Localization::Description>() == \"The MSIX SDK project is an effort to enable developers\");\r\n    REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageUrl>() == \"https://github.com/microsoft/msix-packaging\");\r\n    REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>() == MultiValue{ \"msix\", \"appx\" });\r\n    REQUIRE(manifest.DefaultInstallerInfo.Commands == MultiValue{ \"makemsix\", \"makeappx\" });\r\n    REQUIRE(manifest.DefaultInstallerInfo.Protocols == MultiValue{ \"protocol1\", \"protocol2\" });\r\n    REQUIRE(manifest.DefaultInstallerInfo.FileExtensions == MultiValue{ \"appx\", \"appxbundle\", \"msix\", \"msixbundle\" });\r\n    REQUIRE(manifest.DefaultInstallerInfo.BaseInstallerType == InstallerTypeEnum::Exe);\r\n    REQUIRE(manifest.DefaultInstallerInfo.PackageFamilyName == \"Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\");\r\n    REQUIRE(manifest.DefaultInstallerInfo.ProductCode == \"{Foo}\");\r\n    REQUIRE(manifest.DefaultInstallerInfo.UpdateBehavior == UpdateBehaviorEnum::UninstallPrevious);\r\n\r\n    // default switches\r\n    auto switches = manifest.DefaultInstallerInfo.Switches;\r\n    REQUIRE(switches.at(InstallerSwitchType::Custom) == \"/custom\");\r\n    REQUIRE(switches.at(InstallerSwitchType::SilentWithProgress) == \"/silentwithprogress\");\r\n    REQUIRE(switches.at(InstallerSwitchType::Silent) == \"/silence\");\r\n    REQUIRE(switches.at(InstallerSwitchType::Interactive) == \"/interactive\");\r\n    REQUIRE(switches.at(InstallerSwitchType::Language) == \"/en-us\");\r\n    REQUIRE(switches.at(InstallerSwitchType::Log) == \"/log=<LOGPATH>\");\r\n    REQUIRE(switches.at(InstallerSwitchType::InstallLocation) == \"/dir=<INSTALLPATH>\");\r\n    REQUIRE(switches.at(InstallerSwitchType::Update) == \"/update\");\r\n\r\n    // installers\r\n    REQUIRE(manifest.Installers.size() == 2);\r\n    ManifestInstaller installer1 = manifest.Installers.at(0);\r\n    REQUIRE(installer1.Arch == Architecture::X86);\r\n    REQUIRE(installer1.Url == \"https://rubengustorage.blob.core.windows.net/publiccontainer/msixsdkx86.zip\");\r\n    REQUIRE(installer1.Sha256 == SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF8C82\"));\r\n    REQUIRE(installer1.Locale == \"en-US\");\r\n    REQUIRE(installer1.BaseInstallerType == InstallerTypeEnum::Exe);\r\n    REQUIRE(installer1.Scope == ScopeEnum::User);\r\n    REQUIRE(installer1.PackageFamilyName == \"\");\r\n    REQUIRE(installer1.ProductCode == \"{Foo}\");\r\n    REQUIRE(installer1.UpdateBehavior == UpdateBehaviorEnum::Install);\r\n\r\n    auto installer1Switches = installer1.Switches;\r\n    REQUIRE(installer1Switches.at(InstallerSwitchType::Custom) == \"/c\");\r\n    REQUIRE(installer1Switches.at(InstallerSwitchType::SilentWithProgress) == \"/sp\");\r\n    REQUIRE(installer1Switches.at(InstallerSwitchType::Silent) == \"/s\");\r\n    REQUIRE(installer1Switches.at(InstallerSwitchType::Interactive) == \"/i\");\r\n    REQUIRE(installer1Switches.at(InstallerSwitchType::Language) == \"/en\");\r\n    REQUIRE(installer1Switches.at(InstallerSwitchType::Log) == \"/l=<LOGPATH>\");\r\n    REQUIRE(installer1Switches.at(InstallerSwitchType::InstallLocation) == \"/d=<INSTALLPATH>\");\r\n    REQUIRE(installer1Switches.at(InstallerSwitchType::Update) == \"/u\");\r\n\r\n    ManifestInstaller installer2 = manifest.Installers.at(1);\r\n    REQUIRE(installer2.Arch == Architecture::X64);\r\n    REQUIRE(installer2.Url == \"https://rubengustorage.blob.core.windows.net/publiccontainer/msixsdkx64.zip\");\r\n    REQUIRE(installer2.Sha256 == SHA256::ConvertToBytes(\"69D84CA8899800A5575CE31798293CD4FEBAB1D734A07C2E51E56A28E0DF0000\"));\r\n    REQUIRE(installer2.Locale == \"en-US\");\r\n    REQUIRE(installer2.BaseInstallerType == InstallerTypeEnum::Exe);\r\n    REQUIRE(installer2.Scope == ScopeEnum::User);\r\n    REQUIRE(installer2.PackageFamilyName == \"\");\r\n    REQUIRE(installer2.ProductCode == \"{Foo}\");\r\n    REQUIRE(installer2.UpdateBehavior == UpdateBehaviorEnum::UninstallPrevious);\r\n\r\n    // Installer2 does not declare switches, it inherits switches from package default.\r\n    auto installer2Switches = installer2.Switches;\r\n    REQUIRE(installer2Switches.at(InstallerSwitchType::Custom) == \"/custom\");\r\n    REQUIRE(installer2Switches.at(InstallerSwitchType::SilentWithProgress) == \"/silentwithprogress\");\r\n    REQUIRE(installer2Switches.at(InstallerSwitchType::Silent) == \"/silence\");\r\n    REQUIRE(installer2Switches.at(InstallerSwitchType::Interactive) == \"/interactive\");\r\n    REQUIRE(installer2Switches.at(InstallerSwitchType::Language) == \"/en-us\");\r\n    REQUIRE(installer2Switches.at(InstallerSwitchType::Log) == \"/log=<LOGPATH>\");\r\n    REQUIRE(installer2Switches.at(InstallerSwitchType::InstallLocation) == \"/dir=<INSTALLPATH>\");\r\n    REQUIRE(installer2Switches.at(InstallerSwitchType::Update) == \"/update\");\r\n\r\n    // Localization\r\n    REQUIRE(manifest.Localizations.size() == 1);\r\n    ManifestLocalization localization1 = manifest.Localizations.at(0);\r\n    REQUIRE(localization1.Locale == \"es-MX\");\r\n    REQUIRE(localization1.Get<Localization::Description>() == \"El proyecto MSIX SDK es habilita desarrolladores de diferentes\");\r\n    REQUIRE(localization1.Get<Localization::PackageUrl>() == \"https://github.com/microsoft/msix-packaging/es-MX\");\r\n    REQUIRE(localization1.Get<Localization::LicenseUrl>() == \"https://github.com/microsoft/msix-packaging/blob/master/LICENSE-es-MX\");\r\n\r\n    // Stream hash\r\n    std::ifstream stream(manifestFile.GetPath(), std::ios_base::in | std::ios_base::binary);\r\n    REQUIRE(!stream.fail());\r\n    auto manifestHash = SHA256::ComputeHash(stream);\r\n    REQUIRE(manifestHash.size() == manifest.StreamSha256.size());\r\n    REQUIRE(std::equal(manifestHash.begin(), manifestHash.end(), manifest.StreamSha256.begin()));\r\n}\r\n\r\nTEST_CASE(\"ReadGoodManifestWithSpaces\", \"[ManifestValidation]\")\r\n{\r\n    Manifest manifest = YamlParser::CreateFromPath(TestDataFile(\"Manifest-Good-Spaces.yaml\"));\r\n\r\n    REQUIRE(manifest.Id == \"microsoft.msixsdk\");\r\n    REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageName>() == \"MSIX SDK\");\r\n    REQUIRE(manifest.Moniker == \"msixsdk\");\r\n    REQUIRE(manifest.Version == \"1.7.32\");\r\n    REQUIRE(manifest.Channel == \"release\");\r\n    REQUIRE(manifest.DefaultInstallerInfo.MinOSVersion == \"0.0.0.0\");\r\n    REQUIRE(manifest.DefaultLocalization.Get<Localization::Tags>() == MultiValue{ \"msix\", \"appx\" });\r\n    REQUIRE(manifest.DefaultInstallerInfo.Commands == MultiValue{ \"makemsix\", \"makeappx\" });\r\n    REQUIRE(manifest.DefaultInstallerInfo.Protocols == MultiValue{ \"protocol1\", \"protocol2\" });\r\n    REQUIRE(manifest.DefaultInstallerInfo.FileExtensions == MultiValue{ \"appx\", \"appxbundle\", \"msix\", \"msixbundle\" });\r\n}\r\n\r\nTEST_CASE(\"ReadGoodManifests\", \"[ManifestValidation]\")\r\n{\r\n    ManifestTestCase TestCases[] =\r\n    {\r\n        { \"Manifest-Good-InstallerTypeExeRoot-Silent.yaml\" },\r\n        { \"Manifest-Good-InstallerTypeExeRoot-SilentRoot.yaml\" },\r\n        { \"Manifest-Good-InstallerTypeExe-Silent.yaml\" },\r\n        { \"Manifest-Good-InstallerTypeExe-SilentRoot.yaml\" },\r\n        { \"Manifest-Good-InstallerUniqueness-DefaultLang.yaml\" },\r\n        { \"Manifest-Good-InstallerUniqueness-DiffLangs.yaml\" },\r\n        { \"Manifest-Good-InstallerUniqueness-DiffScope.yaml\" },\r\n        { \"Manifest-Good-Minimum.yaml\" },\r\n        { \"Manifest-Good-Minimum-InstallerType.yaml\" },\r\n        { \"Manifest-Good-Switches.yaml\" },\r\n        { \"Manifest-Good-DefaultExpectedReturnCodeInInstallerSuccessCodes.yaml\" },\r\n        { \"Manifest-Good-InstallerTypeZip-PortableExe.yaml\" },\r\n    };\r\n\r\n    for (auto const& testCase : TestCases)\r\n    {\r\n        TestManifest(testCase.TestFile);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"ReadBadManifests\", \"[ManifestValidation]\")\r\n{\r\n    ManifestTestCase TestCases[] =\r\n    {\r\n        { \"Manifest-Bad-ArchInvalid.yaml\", \"Invalid field value. [Architecture]\" },\r\n        { \"Manifest-Bad-ArchMissing.yaml\", \"Missing required property 'Arch'\" },\r\n        { \"Manifest-Bad-Channel-NotSupported.yaml\", \"Field is not supported. [Channel]\" },\r\n        { \"Manifest-Bad-DifferentCase-camelCase.yaml\", \"All field names should be PascalCased. [installerType]\" },\r\n        { \"Manifest-Bad-DifferentCase-lower.yaml\", \"All field names should be PascalCased. [installertype]\" },\r\n        { \"Manifest-Bad-DifferentCase-UPPER.yaml\", \"All field names should be PascalCased. [INSTALLERTYPE]\" },\r\n        { \"Manifest-Bad-DuplicateKey.yaml\", \"Duplicate field found in the manifest.\" },\r\n        { \"Manifest-Bad-DuplicateKey-DifferentCase.yaml\", \"Duplicate field found in the manifest.\" },\r\n        { \"Manifest-Bad-DuplicateKey-DifferentCase-lower.yaml\", \"Duplicate field found in the manifest.\" },\r\n        { \"Manifest-Bad-DuplicateReturnCode-ExpectedCodes.yaml\", \"Duplicate installer return code found.\" },\r\n        { \"Manifest-Bad-DuplicateReturnCode-SuccessCodes.yaml\", \"Duplicate installer return code found.\" },\r\n        { \"Manifest-Bad-DuplicateSha256.yaml\", \"Multiple Installer URLs found with the same InstallerSha256. Please ensure the accuracy of the URLs.\", true },\r\n        { \"Manifest-Bad-IdInvalid.yaml\", \"Failed to validate against schema associated with property name 'Id'\" },\r\n        { \"Manifest-Bad-IdMissing.yaml\", \"Missing required property 'Id'\" },\r\n        { \"Manifest-Bad-InconsistentSha256.yaml\", \"The values of InstallerSha256 do not match for all instances of the same InstallerUrl.\" },\r\n        { \"Manifest-Bad-InstallersMissing.yaml\", \"Missing required property 'Installers'\" },\r\n        { \"Manifest-Bad-InstallerTypeExe-NoSilent.yaml\", \"Silent and SilentWithProgress switches are not specified for InstallerType exe.\", true },\r\n        { \"Manifest-Bad-InstallerTypeExe-NoSilentRoot.yaml\", \"Silent and SilentWithProgress switches are not specified for InstallerType exe.\", true },\r\n        { \"Manifest-Bad-InstallerTypeExeRoot-NoSilent.yaml\", \"Silent and SilentWithProgress switches are not specified for InstallerType exe.\", true },\r\n        { \"Manifest-Bad-InstallerTypeExeRoot-NoSilentRoot.yaml\", \"Silent and SilentWithProgress switches are not specified for InstallerType exe.\", true },\r\n        { \"Manifest-Bad-InstallerTypeInvalid.yaml\", \"Invalid field value. [InstallerType]\" },\r\n        { \"Manifest-Bad-InstallerTypeMissing.yaml\", \"Invalid field value. [InstallerType]\" },\r\n        { \"Manifest-Bad-InstallerTypePortable-InvalidAppsAndFeatures.yaml\", \"Only zero or one entry for Apps and Features may be specified for InstallerType portable.\" },\r\n        { \"Manifest-Bad-InstallerTypePortable-InvalidCommands.yaml\", \"Only zero or one value for Commands may be specified for InstallerType portable.\" },\r\n        { \"Manifest-Bad-InstallerTypePortable-InvalidScope.yaml\", \"Scope is not supported for InstallerType portable.\" },\r\n        { \"Manifest-Bad-InstallerTypeZip-DuplicateCommandAlias.yaml\", \"Duplicate portable command alias found.\" },\r\n        { \"Manifest-Bad-InstallerTypeZip-DuplicateRelativeFilePath.yaml\", \"Duplicate relative file path found.\" },\r\n        { \"Manifest-Bad-InstallerTypeZip-InvalidRelativeFilePath.yaml\", \"Relative file path must not point to a location outside of archive directory\" },\r\n        { \"Manifest-Bad-InstallerTypeZip-MissingRelativeFilePath.yaml\", \"Required field missing. [RelativeFilePath]\" },\r\n        { \"Manifest-Bad-InstallerTypeZip-MultipleNestedInstallers.yaml\", \"Only one entry for NestedInstallerFiles can be specified for non-portable InstallerTypes.\" },\r\n        { \"Manifest-Bad-InstallerTypeZip-NoNestedInstallerFile.yaml\", \"Required field missing. [NestedInstallerFiles]\" },\r\n        { \"Manifest-Bad-InstallerTypeZip-NoNestedInstallerType.yaml\", \"Required field missing. [NestedInstallerType]\" },\r\n        { \"Manifest-Bad-InstallerUniqueness.yaml\", \"Duplicate installer entry found.\" },\r\n        { \"Manifest-Bad-InstallerUniqueness-DefaultScope.yaml\", \"Duplicate installer entry found.\" },\r\n        { \"Manifest-Bad-InstallerUniqueness-DefaultValues.yaml\", \"Duplicate installer entry found.\" },\r\n        { \"Manifest-Bad-InstallerUniqueness-SameLang.yaml\", \"Duplicate installer entry found.\" },\r\n        { \"Manifest-Bad-LicenseMissing.yaml\", \"Missing required property 'License'\" },\r\n        { \"Manifest-Bad-NameMissing.yaml\", \"Missing required property 'Name'\" },\r\n        { \"Manifest-Bad-PublisherMissing.yaml\", \"Missing required property 'Publisher'\" },\r\n        { \"Manifest-Bad-Sha256Invalid.yaml\", \"Failed to validate against schema associated with property name 'Sha256'\" },\r\n        { \"Manifest-Bad-Sha256Missing.yaml\", \"Required field missing. [InstallerSha256]\" },\r\n        { \"Manifest-Bad-SwitchInvalid.yaml\", \"Unknown field. [NotASwitch]\", true },\r\n        { \"Manifest-Bad-UnknownProperty.yaml\", \"Unknown field. [Fake]\", true },\r\n        { \"Manifest-Bad-UnsupportedVersion.yaml\", \"Unsupported ManifestVersion\" },\r\n        { \"Manifest-Bad-UrlInvalid.yaml\", \"Invalid field value. [InstallerUrl]\" },\r\n        { \"Manifest-Bad-UrlMissing.yaml\", \"Required field missing. [InstallerUrl]\" },\r\n        { \"Manifest-Bad-VersionInvalid.yaml\", \"Failed to validate against schema associated with property name 'Version'\" },\r\n        { \"Manifest-Bad-VersionMissing.yaml\", \"Missing required property 'Version'\" },\r\n        { \"Manifest-Bad-InvalidManifestVersionValue.yaml\", \"Failed to validate against schema associated with property name 'ManifestVersion'\" },\r\n        { \"InstallFlowTest_MSStore.yaml\", \"Field value is not supported. [InstallerType] Value: msstore\" },\r\n        { \"Manifest-Bad-PackageFamilyNameOnMSI.yaml\", \"The specified installer type does not support PackageFamilyName. [InstallerType] Value: msi\", true },\r\n        { \"Manifest-Bad-ProductCodeOnMSIX.yaml\", \"The specified installer type does not support ProductCode. [InstallerType] Value: msix\" },\r\n        { \"Manifest-Bad-InvalidUpdateBehavior.yaml\", \"Invalid field value. [UpgradeBehavior]\" },\r\n        { \"Manifest-Bad-InvalidLocale.yaml\", \"The locale value is not a well formed bcp47 language tag.\" },\r\n        { \"Manifest-Bad-AppsAndFeaturesEntriesOnMSIX.yaml\", \"The specified installer type does not write to Apps and Features entry.\" },\r\n        { \"InstallFlowTest_LicenseAgreement.yaml\", \"Field usage requires verified publishers. [Agreement]\", true },\r\n        { \"InstallFlowTest_LicenseAgreement.yaml\", \"Field usage requires verified publishers. [Agreement]\", false, GetTestManifestValidateOption(false, true) },\r\n        { \"Manifest-Bad-ApproximateVersionInPackageVersion.yaml\", \"Approximate version not allowed. [PackageVersion]\" },\r\n        { \"Manifest-Bad-ApproximateVersionInArpVersion.yaml\", \"Approximate version not allowed. [DisplayVersion]\" },\r\n        { \"Manifest-Bad-InstallerTypeZip-PortableNotExe.yaml\", \"The file type of the referenced file is not allowed. [RelativeFilePath] Value: ScriptedApplication.bat\" },\r\n        { \"Manifest-Bad-InstallerTypeZip-PortableNotExe_Root.yaml\", \"The file type of the referenced file is not allowed. [RelativeFilePath] Value: ScriptedApplication.bat\" },\r\n    };\r\n\r\n    for (auto const& testCase : TestCases)\r\n    {\r\n        TestManifest(testCase.TestFile, testCase.ExpectedMessage, testCase.IsWarningOnly, testCase.ValidateOption);\r\n    }\r\n}\r\n\r\nTEST_CASE(\"ManifestEncoding\", \"[ManifestValidation]\")\r\n{\r\n    ManifestTestCase TestCases[] =\r\n    {\r\n        { \"Manifest-Encoding-ANSI.yaml\" },\r\n        { \"Manifest-Encoding-UTF8.yaml\" },\r\n        { \"Manifest-Encoding-UTF8-BOM.yaml\" },\r\n        { \"Manifest-Encoding-UTF16BE.yaml\" },\r\n        { \"Manifest-Encoding-UTF16BE-BOM.yaml\" },\r\n        { \"Manifest-Encoding-UTF16LE.yaml\" },\r\n        { \"Manifest-Encoding-UTF16LE-BOM.yaml\" },\r\n    };\r\n\r\n    for (auto const& testCase : TestCases)\r\n    {\r\n        INFO(testCase.TestFile);\r\n        Manifest manifest = YamlParser::CreateFromPath(TestDataFile(testCase.TestFile), GetTestManifestValidateOption());\r\n        REQUIRE(manifest.DefaultLocalization.Get<Localization::PackageName>() == u8\"MSIX SDK\\xA9\");\r\n    }\r\n}\r\n\r\nTEST_CASE(\"ComplexSystemReference\", \"[ManifestValidation]\")\r\n{\r\n    Manifest manifest = YamlParser::CreateFromPath(TestDataFile(\"Manifest-Good-SystemReferenceComplex.yaml\"));\r\n\r\n    REQUIRE(manifest.Installers.size() == 4);\r\n\r\n    // MSIX installer does inherit\r\n    auto& installer = manifest.Installers[0];\r\n    REQUIRE(installer.BaseInstallerType == InstallerTypeEnum::Msix);\r\n    REQUIRE(installer.Arch == Architecture::X86);\r\n    REQUIRE(installer.PackageFamilyName == \"Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\");\r\n    REQUIRE(installer.ProductCode == \"\");\r\n\r\n    // MSI installer does inherit\r\n    auto& installer1 = manifest.Installers[1];\r\n    REQUIRE(installer1.BaseInstallerType == InstallerTypeEnum::Msi);\r\n    REQUIRE(installer1.Arch == Architecture::X86);\r\n    REQUIRE(installer1.PackageFamilyName == \"\");\r\n    REQUIRE(installer1.ProductCode == \"{Foo}\");\r\n\r\n    // MSIX installer with override\r\n    auto& installer2 = manifest.Installers[2];\r\n    REQUIRE(installer2.BaseInstallerType == InstallerTypeEnum::Msix);\r\n    REQUIRE(installer2.Arch == Architecture::X64);\r\n    REQUIRE(installer2.PackageFamilyName == \"Override_8wekyb3d8bbwe\");\r\n    REQUIRE(installer2.ProductCode == \"\");\r\n\r\n    // MSI installer with override\r\n    auto& installer3 = manifest.Installers[3];\r\n    REQUIRE(installer3.BaseInstallerType == InstallerTypeEnum::Msi);\r\n    REQUIRE(installer3.Arch == Architecture::X64);\r\n    REQUIRE(installer3.PackageFamilyName == \"\");\r\n    REQUIRE(installer3.ProductCode == \"Override\");\r\n}\r\n\r\nTEST_CASE(\"ManifestVersionExtensions\", \"[ManifestValidation]\")\r\n{\r\n    REQUIRE(!ManifestVer(\"1.0.0\"sv).HasExtension(\"msstore\"));\r\n    REQUIRE(!ManifestVer(\"1.0.0-other\"sv).HasExtension(\"msstore\"));\r\n    REQUIRE(!ManifestVer(\"1.0.0-other-other2\"sv).HasExtension(\"msstore\"));\r\n\r\n    REQUIRE(ManifestVer(\"1.0.0-msstore\"sv).HasExtension(\"msstore\"));\r\n    REQUIRE(ManifestVer(\"1.0.0-msstore.2\"sv).HasExtension(\"msstore\"));\r\n    REQUIRE(ManifestVer(\"1.0.0-other-msstore.2\"sv).HasExtension(\"msstore\"));\r\n    REQUIRE(ManifestVer(\"1.0.0-msstore.2-other\"sv).HasExtension(\"msstore\"));\r\n}\r\n\r\nvoid ValidateGoodManifestAndVerifyContents(const std::vector<std::string>& singleton, const std::vector<std::string>& multiFiles, std::string_view version)\r\n{\r\n    ManifestValidateOption validateOption;\r\n    validateOption.FullValidation = true;\r\n    TempDirectory singletonDirectory{ \"SingletonManifest\" };\r\n    CopyTestDataFilesToFolder(singleton, singletonDirectory);\r\n    Manifest singletonManifest = YamlParser::CreateFromPath(singletonDirectory, validateOption);\r\n    VerifyV1ManifestContent(singletonManifest, true, ManifestVer{ version });\r\n\r\n    TempDirectory multiFileDirectory{ \"MultiFileManifest\" };\r\n    CopyTestDataFilesToFolder(multiFiles, multiFileDirectory);\r\n\r\n    TempFile mergedManifestFile{ \"merged.yaml\" };\r\n    Manifest multiFileManifest = YamlParser::CreateFromPath(multiFileDirectory, validateOption, mergedManifestFile);\r\n    VerifyV1ManifestContent(multiFileManifest, false, ManifestVer{ version });\r\n\r\n    // Read from merged manifest should have the same content as multi file manifest\r\n    Manifest mergedManifest = YamlParser::CreateFromPath(mergedManifestFile);\r\n    VerifyV1ManifestContent(mergedManifest, false, ManifestVer{ version });\r\n}\r\n\r\n#define WINGET_VALIDATE_GOOD_MANIFEST_VERSION(_version_) TEST_CASE(\"ValidateGoodManifestAndVerifyContents_\" #_version_ , \"[ManifestValidation][ManifestVersionValidation]\") \\\r\n{ \\\r\n    ValidateGoodManifestAndVerifyContents( \\\r\n        { \"ManifestV\" #_version_ \"-Singleton.yaml\" }, \\\r\n        { \\\r\n            \"ManifestV\" #_version_ \"-MultiFile-Version.yaml\", \\\r\n            \"ManifestV\" #_version_ \"-MultiFile-Installer.yaml\", \\\r\n            \"ManifestV\" #_version_ \"-MultiFile-DefaultLocale.yaml\", \\\r\n            \"ManifestV\" #_version_ \"-MultiFile-Locale.yaml\" \\\r\n        }, \\\r\n        s_ManifestVersionV ## _version_); \\\r\n}\r\n\r\nWINGET_VALIDATE_GOOD_MANIFEST_VERSION(1)\r\nWINGET_VALIDATE_GOOD_MANIFEST_VERSION(1_1)\r\nWINGET_VALIDATE_GOOD_MANIFEST_VERSION(1_2)\r\nWINGET_VALIDATE_GOOD_MANIFEST_VERSION(1_4)\r\nWINGET_VALIDATE_GOOD_MANIFEST_VERSION(1_5)\r\nWINGET_VALIDATE_GOOD_MANIFEST_VERSION(1_6)\r\nWINGET_VALIDATE_GOOD_MANIFEST_VERSION(1_7)\r\nWINGET_VALIDATE_GOOD_MANIFEST_VERSION(1_9)\r\nWINGET_VALIDATE_GOOD_MANIFEST_VERSION(1_10)\r\nWINGET_VALIDATE_GOOD_MANIFEST_VERSION(1_12)\r\nWINGET_VALIDATE_GOOD_MANIFEST_VERSION(1_28)\r\n\r\nvoid WriteSingletonManifestAndVerifyContents(const std::vector<std::string>& singleton, const std::vector<std::string>& multiFiles, std::string_view version)\r\n{\r\n    TempDirectory singletonDirectory{ \"SingletonManifest\" };\r\n    CopyTestDataFilesToFolder(singleton, singletonDirectory);\r\n    Manifest singletonManifest = YamlParser::CreateFromPath(singletonDirectory);\r\n\r\n    TempDirectory exportedSingletonDirectory{ \"exportedSingleton\" };\r\n    std::filesystem::path generatedSingletonManifestPath = exportedSingletonDirectory.GetPath() / \"testSingletonManifest.yaml\";\r\n    YamlWriter::OutputYamlFile(singletonManifest, singletonManifest.Installers[0], generatedSingletonManifestPath);\r\n\r\n    REQUIRE(std::filesystem::exists(generatedSingletonManifestPath));\r\n    Manifest generatedSingletonManifest = YamlParser::CreateFromPath(exportedSingletonDirectory);\r\n    VerifyV1ManifestContent(generatedSingletonManifest, true, ManifestVer{ version }, true);\r\n\r\n    TempDirectory multiFileDirectory{ \"MultiFileManifest\" };\r\n    CopyTestDataFilesToFolder(multiFiles, multiFileDirectory);\r\n\r\n    Manifest multiFileManifest = YamlParser::CreateFromPath(multiFileDirectory);\r\n    TempDirectory exportedMultiFileDirectory{ \"exportedMultiFile\" };\r\n    std::filesystem::path generatedMultiFileManifestPath = exportedMultiFileDirectory.GetPath() / \"testMultiFileManifest.yaml\";\r\n    YamlWriter::OutputYamlFile(multiFileManifest, multiFileManifest.Installers[0], generatedMultiFileManifestPath);\r\n\r\n    REQUIRE(std::filesystem::exists(generatedMultiFileManifestPath));\r\n    Manifest generatedMultiFileManifest = YamlParser::CreateFromPath(exportedMultiFileDirectory);\r\n    VerifyV1ManifestContent(generatedMultiFileManifest, false, ManifestVer{ version }, true);\r\n}\r\n\r\n#define WINGET_WRITE_VERIFY_MANIFEST_VERSION(_version_) TEST_CASE(\"WriteSingletonManifestAndVerifyContents_\" #_version_ , \"[ManifestCreation][ManifestVersionCreation]\") \\\r\n{ \\\r\n    WriteSingletonManifestAndVerifyContents( \\\r\n        { \"ManifestV\" #_version_ \"-Singleton.yaml\" }, \\\r\n        { \\\r\n            \"ManifestV\" #_version_ \"-MultiFile-Version.yaml\", \\\r\n            \"ManifestV\" #_version_ \"-MultiFile-Installer.yaml\", \\\r\n            \"ManifestV\" #_version_ \"-MultiFile-DefaultLocale.yaml\", \\\r\n            \"ManifestV\" #_version_ \"-MultiFile-Locale.yaml\" \\\r\n        }, \\\r\n        s_ManifestVersionV ## _version_); \\\r\n}\r\n\r\nWINGET_WRITE_VERIFY_MANIFEST_VERSION(1)\r\nWINGET_WRITE_VERIFY_MANIFEST_VERSION(1_1)\r\nWINGET_WRITE_VERIFY_MANIFEST_VERSION(1_2)\r\nWINGET_WRITE_VERIFY_MANIFEST_VERSION(1_4)\r\nWINGET_WRITE_VERIFY_MANIFEST_VERSION(1_5)\r\nWINGET_WRITE_VERIFY_MANIFEST_VERSION(1_6)\r\nWINGET_WRITE_VERIFY_MANIFEST_VERSION(1_7)\r\nWINGET_WRITE_VERIFY_MANIFEST_VERSION(1_9)\r\nWINGET_WRITE_VERIFY_MANIFEST_VERSION(1_10)\r\nWINGET_WRITE_VERIFY_MANIFEST_VERSION(1_12)\r\nWINGET_WRITE_VERIFY_MANIFEST_VERSION(1_28)\r\n\r\n// Since Authentication is not supported in community repo and will cause manifest validation failure,\r\n// we are not adding Authentication in v1_10 manifests. Instead a separate test is created for Authentication.\r\nTEST_CASE(\"ReadWriteValidateV1_10ManifestWithInstallerAuthentication\", \"[ManifestCreation][ManifestVersionCreation]\")\r\n{\r\n    // Read manifest\r\n    TempDirectory testDirectory{ \"TestManifest\" };\r\n    CopyTestDataFilesToFolder({ \"ManifestV1_10-InstallerAuthentication.yaml\" }, testDirectory);\r\n    Manifest testManifest = YamlParser::CreateFromPath(testDirectory);\r\n\r\n    // Validate schema\r\n    ManifestValidateOption validateOption;\r\n    validateOption.SchemaValidationOnly = true;\r\n    validateOption.ThrowOnWarning = true;\r\n    YamlParser::CreateFromPath(testDirectory, validateOption);\r\n\r\n    // Verify content\r\n    REQUIRE(testManifest.ManifestVersion == AppInstaller::Manifest::ManifestVer{ s_ManifestVersionV1_10 });\r\n    REQUIRE(testManifest.DefaultInstallerInfo.AuthInfo.Type == AppInstaller::Authentication::AuthenticationType::MicrosoftEntraId);\r\n    REQUIRE(testManifest.DefaultInstallerInfo.AuthInfo.MicrosoftEntraIdInfo);\r\n    REQUIRE(testManifest.DefaultInstallerInfo.AuthInfo.MicrosoftEntraIdInfo->Resource == \"TestResource\");\r\n    REQUIRE(testManifest.DefaultInstallerInfo.AuthInfo.MicrosoftEntraIdInfo->Scope == \"TestScope\");\r\n    REQUIRE(testManifest.Installers.size() == 1);\r\n    REQUIRE(testManifest.Installers[0].AuthInfo.Type == AppInstaller::Authentication::AuthenticationType::MicrosoftEntraIdForAzureBlobStorage);\r\n    REQUIRE(testManifest.Installers[0].AuthInfo.MicrosoftEntraIdInfo);\r\n    REQUIRE(testManifest.Installers[0].AuthInfo.MicrosoftEntraIdInfo->Resource == \"https://storage.azure.com/\");\r\n    REQUIRE(testManifest.Installers[0].AuthInfo.MicrosoftEntraIdInfo->Scope.empty());\r\n\r\n    // Manifest Validation. Only error is \"Authentication not supported\".\r\n    auto errors = ValidateManifest(testManifest, true);\r\n    REQUIRE(errors.size() == 1);\r\n    REQUIRE(errors[0].GetErrorMessage() == \"Field is not supported.\");\r\n    REQUIRE(errors[0].Context == \"Authentication\");\r\n\r\n    // Write manifest\r\n    TempDirectory exportedDirectory{ \"ExportedManifest\" };\r\n    std::filesystem::path exportedManifestPath = exportedDirectory.GetPath() / \"ExportedManifest.yaml\";\r\n    YamlWriter::OutputYamlFile(testManifest, testManifest.Installers[0], exportedManifestPath);\r\n\r\n    // Read back and validate content\r\n    REQUIRE(std::filesystem::exists(exportedManifestPath));\r\n    Manifest exportedManifest = YamlParser::CreateFromPath(exportedDirectory);\r\n    REQUIRE(exportedManifest.ManifestVersion == AppInstaller::Manifest::ManifestVer{ s_ManifestVersionV1_10 });\r\n    REQUIRE(exportedManifest.Installers.size() == 1);\r\n    REQUIRE(exportedManifest.Installers[0].AuthInfo.Type == AppInstaller::Authentication::AuthenticationType::MicrosoftEntraIdForAzureBlobStorage);\r\n    REQUIRE(exportedManifest.Installers[0].AuthInfo.MicrosoftEntraIdInfo);\r\n    REQUIRE(exportedManifest.Installers[0].AuthInfo.MicrosoftEntraIdInfo->Resource == \"https://storage.azure.com/\");\r\n    REQUIRE(exportedManifest.Installers[0].AuthInfo.MicrosoftEntraIdInfo->Scope.empty());\r\n}\r\n\r\n// PowerShell DSC is not supported in the community repo and will cause manifest validation failure.\r\nTEST_CASE(\"ReadWriteValidateV1_28ManifestWithPowerShellDSC\", \"[ManifestCreation][ManifestVersionCreation]\")\r\n{\r\n    // Read manifest\r\n    TempDirectory testDirectory{ \"TestManifest\" };\r\n    CopyTestDataFilesToFolder({ \"ManifestV1_28-PowerShellDSC.yaml\" }, testDirectory);\r\n    Manifest testManifest = YamlParser::CreateFromPath(testDirectory);\r\n\r\n    // Validate schema\r\n    ManifestValidateOption validateOption;\r\n    validateOption.SchemaValidationOnly = true;\r\n    validateOption.ThrowOnWarning = true;\r\n    YamlParser::CreateFromPath(testDirectory, validateOption);\r\n\r\n    // TODO: Update ValidateManifest\r\n    // TODO: Update this test with similar validations\r\n\r\n    // Verify content\r\n    REQUIRE(testManifest.ManifestVersion == AppInstaller::Manifest::ManifestVer{ s_ManifestVersionV1_28 });\r\n    REQUIRE(testManifest.Installers.size() == 1);\r\n    REQUIRE(testManifest.Installers[0].DesiredStateConfiguration.size() == 3);\r\n\r\n    RequireContainerInfoPresent(testManifest.Installers[0].DesiredStateConfiguration, { \"https://www.powershellgallery.com/api/v2\", \"Microsoft.WinGet.DSC\", { { \"WinGetUserSettings\" }, { \"WinGetAdminSettings\" }, { \"WinGetSource\" }, { \"WinGetPackageManager\" }, { \"WinGetPackage\" } } });\r\n    RequireContainerInfoPresent(testManifest.Installers[0].DesiredStateConfiguration, { \"https://mcr.microsoft.com/\", \"Microsoft.WinGet.DSC\", { { \"WinGetUserSettings\" }, { \"WinGetAdminSettings\" }, { \"WinGetSource\" }, { \"WinGetPackageManager\" }, { \"WinGetPackage\" } } });\r\n    RequireContainerInfoPresent(testManifest.Installers[0].DesiredStateConfiguration, { { { \"Microsoft.WinGet/AdminSettings\" }, { \"Microsoft.WinGet/Package\" }, { \"Microsoft.WinGet/Source\" }, { \"Microsoft.WinGet/UserSettingsFile\" } } });\r\n\r\n    // Manifest Validation. Only error is \"PowerShell not supported\".\r\n    auto errors = ValidateManifest(testManifest, true);\r\n    REQUIRE(errors.size() == 1);\r\n    REQUIRE(errors[0].GetErrorMessage() == \"Field is not supported.\");\r\n    REQUIRE(errors[0].Context == \"DesiredStateConfiguration.PowerShell\");\r\n\r\n    // Write manifest\r\n    TempDirectory exportedDirectory{ \"ExportedManifest\" };\r\n    std::filesystem::path exportedManifestPath = exportedDirectory.GetPath() / \"ExportedManifest.yaml\";\r\n    YamlWriter::OutputYamlFile(testManifest, testManifest.Installers[0], exportedManifestPath);\r\n\r\n    // Read back and validate content\r\n    REQUIRE(std::filesystem::exists(exportedManifestPath));\r\n    Manifest exportedManifest = YamlParser::CreateFromPath(exportedDirectory);\r\n    REQUIRE(exportedManifest.ManifestVersion == AppInstaller::Manifest::ManifestVer{ s_ManifestVersionV1_28 });\r\n    REQUIRE(exportedManifest.Installers.size() == 1);\r\n    REQUIRE(exportedManifest.Installers[0].DesiredStateConfiguration.size() == 3);\r\n\r\n    RequireContainerInfoPresent(exportedManifest.Installers[0].DesiredStateConfiguration, { \"https://www.powershellgallery.com/api/v2\", \"Microsoft.WinGet.DSC\", { { \"WinGetUserSettings\" }, { \"WinGetAdminSettings\" }, { \"WinGetSource\" }, { \"WinGetPackageManager\" }, { \"WinGetPackage\" } } });\r\n    RequireContainerInfoPresent(exportedManifest.Installers[0].DesiredStateConfiguration, { \"https://mcr.microsoft.com/\", \"Microsoft.WinGet.DSC\", { { \"WinGetUserSettings\" }, { \"WinGetAdminSettings\" }, { \"WinGetSource\" }, { \"WinGetPackageManager\" }, { \"WinGetPackage\" } } });\r\n    RequireContainerInfoPresent(exportedManifest.Installers[0].DesiredStateConfiguration, { { { \"Microsoft.WinGet/AdminSettings\" }, { \"Microsoft.WinGet/Package\" }, { \"Microsoft.WinGet/Source\" }, { \"Microsoft.WinGet/UserSettingsFile\" } } });\r\n}\r\n\r\nTEST_CASE(\"WriteManifestWithMultipleLocale\", \"[ManifestCreation]\")\r\n{\r\n    Manifest multiLocaleManifest = YamlParser::CreateFromPath(TestDataFile(\"Manifest-Good-MultiLocale.yaml\"));\r\n    TempDirectory exportedDirectory{ \"exported\" };\r\n    std::filesystem::path generatedManifestPath = exportedDirectory.GetPath() / \"testManifestWithMultipleLocale.yaml\";\r\n    YamlWriter::OutputYamlFile(multiLocaleManifest, multiLocaleManifest.Installers[0], generatedManifestPath);\r\n\r\n    REQUIRE(std::filesystem::exists(generatedManifestPath));\r\n    Manifest generatedManifest = YamlParser::CreateFromPath(generatedManifestPath);\r\n    REQUIRE(generatedManifest.Localizations.size() == 2);\r\n}\r\n\r\nTEST_CASE(\"WriteManifestWithMSStoreInstaller\", \"[ManifestCreation]\")\r\n{\r\n    Manifest msstoreManifest = YamlParser::CreateFromPath(TestDataFile(\"DownloadFlowTest_MSStore.yaml\"));\r\n    TempDirectory exportedDirectory{ \"exported\" };\r\n    std::filesystem::path generatedManifestPath = exportedDirectory.GetPath() / \"testManifestWithMultipleLocale.yaml\";\r\n    msstoreManifest.ManifestVersion = ManifestVer{ \"1.1.0\" };\r\n    YamlWriter::OutputYamlFile(msstoreManifest, msstoreManifest.Installers[0], generatedManifestPath);\r\n\r\n    REQUIRE(std::filesystem::exists(generatedManifestPath));\r\n    Manifest generatedManifest = YamlParser::CreateFromPath(generatedManifestPath);\r\n    REQUIRE(generatedManifest.Installers[0].BaseInstallerType == InstallerTypeEnum::MSStore);\r\n    REQUIRE(!generatedManifest.Installers[0].ProductId.empty());\r\n}\r\n\r\nYamlManifestInfo CreateYamlManifestInfo(std::string testDataFile)\r\n{\r\n    YamlManifestInfo result;\r\n    result.Root = AppInstaller::YAML::Load(TestDataFile(testDataFile));\r\n    result.FileName = testDataFile;\r\n    return result;\r\n}\r\n\r\nTEST_CASE(\"MultifileManifestInputValidation\", \"[ManifestValidation]\")\r\n{\r\n    auto previewManifest = CreateYamlManifestInfo(\"Manifest-Good.yaml\");\r\n    auto v1SingletonManifest = CreateYamlManifestInfo(\"ManifestV1-Singleton.yaml\");\r\n    auto v1VersionManifest = CreateYamlManifestInfo(\"ManifestV1-MultiFile-Version.yaml\");\r\n    auto v1InstallerManifest = CreateYamlManifestInfo(\"ManifestV1-MultiFile-Installer.yaml\");\r\n    auto v1DefaultLocaleManifest = CreateYamlManifestInfo(\"ManifestV1-MultiFile-DefaultLocale.yaml\");\r\n    auto v1LocaleManifest = CreateYamlManifestInfo(\"ManifestV1-MultiFile-Locale.yaml\");\r\n\r\n    {\r\n        // Preview and multi file manifest together\r\n        std::vector<YamlManifestInfo> input = { previewManifest, v1VersionManifest, v1InstallerManifest, v1DefaultLocaleManifest };\r\n        REQUIRE_THROWS_MATCHES(YamlParser::ParseManifest(input), ManifestException, ManifestExceptionMatcher(\"Preview manifest does not support multi file manifest format\"));\r\n    }\r\n\r\n    {\r\n        // Singleton and multi file manifest together\r\n        std::vector<YamlManifestInfo> input = { v1SingletonManifest, v1VersionManifest, v1InstallerManifest, v1DefaultLocaleManifest };\r\n        REQUIRE_THROWS_MATCHES(YamlParser::ParseManifest(input), ManifestException, ManifestExceptionMatcher(\"The multi file manifest should not contain file with the particular ManifestType. [ManifestType] Value: singleton\"));\r\n    }\r\n\r\n    {\r\n        // More than 1 version manifest\r\n        std::vector<YamlManifestInfo> input = { v1VersionManifest, v1VersionManifest, v1InstallerManifest, v1DefaultLocaleManifest };\r\n        REQUIRE_THROWS_MATCHES(YamlParser::ParseManifest(input), ManifestException, ManifestExceptionMatcher(\"The multi file manifest should contain only one file with the particular ManifestType. [ManifestType] Value: version\"));\r\n    }\r\n\r\n    {\r\n        // More than 1 installer manifest\r\n        std::vector<YamlManifestInfo> input = { v1VersionManifest, v1InstallerManifest, v1InstallerManifest, v1DefaultLocaleManifest };\r\n        REQUIRE_THROWS_MATCHES(YamlParser::ParseManifest(input), ManifestException, ManifestExceptionMatcher(\"The multi file manifest should contain only one file with the particular ManifestType. [ManifestType] Value: installer\"));\r\n    }\r\n\r\n    {\r\n        // More than 1 default locale manifest\r\n        std::vector<YamlManifestInfo> input = { v1VersionManifest, v1InstallerManifest, v1DefaultLocaleManifest, v1DefaultLocaleManifest };\r\n        REQUIRE_THROWS_MATCHES(YamlParser::ParseManifest(input), ManifestException, ManifestExceptionMatcher(\"The multi file manifest should contain only one file with the particular ManifestType. [ManifestType] Value: defaultLocale\"));\r\n    }\r\n\r\n    {\r\n        // Duplicate locales\r\n        std::vector<YamlManifestInfo> input = { v1VersionManifest, v1InstallerManifest, v1DefaultLocaleManifest, v1LocaleManifest, v1LocaleManifest };\r\n        REQUIRE_THROWS_MATCHES(YamlParser::ParseManifest(input), ManifestException, ManifestExceptionMatcher(\"The multi file manifest contains duplicate PackageLocale. [PackageLocale] Value: en-GB\"));\r\n    }\r\n\r\n    {\r\n        // default locale not match\r\n        auto defaultLocaleManifestCopy = v1DefaultLocaleManifest;\r\n        defaultLocaleManifestCopy.Root[\"PackageLocale\"].SetScalar(\"fr-fr\");\r\n        std::vector<YamlManifestInfo> input = { v1VersionManifest, v1InstallerManifest, defaultLocaleManifestCopy, v1LocaleManifest };\r\n        REQUIRE_THROWS_MATCHES(YamlParser::ParseManifest(input), ManifestException, ManifestExceptionMatcher(\"DefaultLocale value in version manifest does not match PackageLocale value in defaultLocale manifest\"));\r\n    }\r\n\r\n    {\r\n        // Package Id does not match\r\n        auto installerManifestCopy = v1InstallerManifest;\r\n        installerManifestCopy.Root[\"PackageIdentifier\"].SetScalar(\"Another.Identifier\");\r\n        std::vector<YamlManifestInfo> input = { v1VersionManifest, installerManifestCopy, v1DefaultLocaleManifest, v1LocaleManifest };\r\n        REQUIRE_THROWS_MATCHES(YamlParser::ParseManifest(input), ManifestException, ManifestExceptionMatcher(\"The multi file manifest has inconsistent field values. [PackageIdentifier] Value: Another.Identifier\"));\r\n    }\r\n\r\n    {\r\n        // Package Version does not match\r\n        auto installerManifestCopy = v1InstallerManifest;\r\n        installerManifestCopy.Root[\"PackageVersion\"].SetScalar(\"Another.Version\");\r\n        std::vector<YamlManifestInfo> input = { v1VersionManifest, installerManifestCopy, v1DefaultLocaleManifest, v1LocaleManifest };\r\n        REQUIRE_THROWS_MATCHES(YamlParser::ParseManifest(input), ManifestException, ManifestExceptionMatcher(\"The multi file manifest has inconsistent field values. [PackageVersion] Value: Another.Version\"));\r\n    }\r\n\r\n    {\r\n        // Incomplete multi file manifest, missing installer\r\n        std::vector<YamlManifestInfo> input = { v1VersionManifest, v1DefaultLocaleManifest };\r\n        REQUIRE_THROWS_MATCHES(YamlParser::ParseManifest(input), ManifestException, ManifestExceptionMatcher(\"The multi file manifest is incomplete\"));\r\n    }\r\n\r\n    {\r\n        // Incomplete multi file manifest, missing default locale\r\n        std::vector<YamlManifestInfo> input = { v1VersionManifest, v1InstallerManifest };\r\n        REQUIRE_THROWS_MATCHES(YamlParser::ParseManifest(input), ManifestException, ManifestExceptionMatcher(\"The multi file manifest is incomplete\"));\r\n    }\r\n}\r\n\r\nTEST_CASE(\"ManifestApplyLocale\", \"[ManifestValidation]\")\r\n{\r\n    Manifest manifest = YamlParser::CreateFromPath(TestDataFile(\"Manifest-Good-MultiLocale.yaml\"));\r\n\r\n    // No better alternative locale, default is used.\r\n    manifest.ApplyLocale(\"zh-CN\");\r\n    REQUIRE(manifest.CurrentLocalization.Locale == \"es-MX\");\r\n    REQUIRE(manifest.CurrentLocalization.Get<Localization::PackageName>() == \"es-MX package name\");\r\n    REQUIRE(manifest.CurrentLocalization.Get<Localization::Publisher>() == \"es-MX publisher\");\r\n\r\n    // en-US results in en-GB, which is better than default.\r\n    manifest.ApplyLocale(\"en-US\");\r\n    REQUIRE(manifest.CurrentLocalization.Locale == \"en-GB\");\r\n    REQUIRE(manifest.CurrentLocalization.Get<Localization::PackageName>() == \"en-GB package name\");\r\n    REQUIRE(manifest.CurrentLocalization.Get<Localization::Publisher>() == \"en-GB publisher\");\r\n\r\n    // fr-FR results in fr-FR, but only package name is localized.\r\n    manifest.ApplyLocale(\"fr-FR\");\r\n    REQUIRE(manifest.CurrentLocalization.Locale == \"fr-FR\");\r\n    REQUIRE(manifest.CurrentLocalization.Get<Localization::PackageName>() == \"fr-FR package name\");\r\n    REQUIRE(manifest.CurrentLocalization.Get<Localization::Publisher>() == \"es-MX publisher\");\r\n}\r\n\r\nTEST_CASE(\"ManifestLocalizationValidation\", \"[ManifestValidation]\")\r\n{\r\n    Manifest manifest = YamlParser::CreateFromPath(TestDataFile(\"Manifest-Good-MultiLocale.yaml\"));\r\n\r\n    // Set 1 locale to bad value\r\n    manifest.Localizations.at(0).Locale = \"Invalid\";\r\n\r\n    // Full validation should detect as error\r\n    auto errors = ValidateManifest(manifest, true);\r\n    REQUIRE(errors.size() == 1);\r\n    REQUIRE(errors.at(0).ErrorLevel == ValidationError::Level::Error);\r\n\r\n    // Not full validation should detect as warning\r\n    errors = ValidateManifest(manifest, false);\r\n    REQUIRE(errors.size() == 1);\r\n    REQUIRE(errors.at(0).ErrorLevel == ValidationError::Level::Warning);\r\n}\r\n\r\nTEST_CASE(\"PortableFileTypeValidation\", \"[ManifestValidation]\")\r\n{\r\n    Manifest installerManifest = YamlParser::CreateFromPath(TestDataFile(\"Manifest-Bad-InstallerTypeZip-PortableNotExe.yaml\"));\r\n    Manifest rootManifest = YamlParser::CreateFromPath(TestDataFile(\"Manifest-Bad-InstallerTypeZip-PortableNotExe_Root.yaml\"));\r\n\r\n    // Regular validation should detect as error\r\n    auto errors = ValidateManifest(installerManifest, true);\r\n    REQUIRE(errors.size() == 1);\r\n    REQUIRE(errors.at(0).ErrorLevel == ValidationError::Level::Error);\r\n\r\n    errors = ValidateManifest(rootManifest, true);\r\n    REQUIRE(errors.size() == 1);\r\n    REQUIRE(errors.at(0).ErrorLevel == ValidationError::Level::Error);\r\n\r\n    // Should not error when full validation is set to false\r\n    errors = ValidateManifest(installerManifest, false);\r\n    REQUIRE(errors.size() == 0);\r\n\r\n    errors = ValidateManifest(rootManifest, false);\r\n    REQUIRE(errors.size() == 0);\r\n}\r\n\r\nTEST_CASE(\"ReadManifestAndValidateMsixInstallers_Success\", \"[ManifestValidation]\")\r\n{\r\n    TestDataFile testFile(\"Manifest-Good-MsixInstaller.yaml\");\r\n    Manifest manifest = YamlParser::CreateFromPath(testFile);\r\n\r\n    // Update the installer path for testing\r\n    REQUIRE(1 == manifest.Installers.size());\r\n    TestDataFile msixFile(manifest.Installers[0].Url.c_str());\r\n    manifest.Installers[0].Url = msixFile.GetPath().u8string();\r\n\r\n    auto errors = ValidateManifestInstallers(manifest);\r\n    REQUIRE(0 == errors.size());\r\n}\r\n\r\nTEST_CASE(\"ReadManifestAndValidateMsixInstallers_InconsistentFields\", \"[ManifestValidation]\")\r\n{\r\n    TestDataFile testFile(\"Manifest-Bad-InconsistentMsixInstallerFields.yaml\");\r\n    Manifest manifest = YamlParser::CreateFromPath(testFile);\r\n\r\n    // Update the installer path for testing\r\n    REQUIRE(1 == manifest.Installers.size());\r\n    TestDataFile msixFile(manifest.Installers[0].Url.c_str());\r\n    manifest.Installers[0].Url = msixFile.GetPath().u8string();\r\n\r\n    auto errors = ValidateManifestInstallers(manifest);\r\n    REQUIRE(4 == errors.size());\r\n\r\n    ValidateError(errors[0], ValidationError::Level::Error, ManifestError::MsixSignatureHashFailed);\r\n    ValidateError(errors[1], ValidationError::Level::Error, ManifestError::InstallerMsixInconsistencies, \"PackageFamilyName\", \"FakeInstallerForTesting_125rzkzqaqjwj\");\r\n    ValidateError(errors[2], ValidationError::Level::Error, ManifestError::InstallerMsixInconsistencies, \"PackageVersion\", \"43690.48059.52428.56797\");\r\n    ValidateError(errors[3], ValidationError::Level::Error, ManifestError::InstallerMsixInconsistencies, \"MinimumOSVersion\", \"10.0.0.0\");\r\n}\r\n\r\nTEST_CASE(\"ReadManifestAndValidateMsixInstallers_NoSupportedPlatforms\", \"[ManifestValidation]\")\r\n{\r\n    auto testFileName = \"Manifest-Bad-NoSupportedPlatforms.yaml\";\r\n    TestDataFile testFile(testFileName);\r\n    Manifest manifest = YamlParser::CreateFromPath(testFile);\r\n\r\n    // Update the installer path for testing\r\n    REQUIRE(1 == manifest.Installers.size());\r\n    TestDataFile msixFile(manifest.Installers[0].Url.c_str());\r\n    manifest.Installers[0].Url = msixFile.GetPath().u8string();\r\n\r\n    auto errors = ValidateManifestInstallers(manifest);\r\n    REQUIRE(1 == errors.size());\r\n\r\n    ValidateError(errors[0], ValidationError::Level::Error, ManifestError::NoSupportedPlatforms, \"InstallerUrl\", manifest.Installers.front().Url);\r\n}\r\n\r\nTEST_CASE(\"ReadManifestAndValidateMsixInstallers_PackageVersionNotUINT64\", \"[ManifestValidation]\")\r\n{\r\n    Manifest manifest = YamlParser::CreateFromPath(TestDataFile(\"Manifest-Bad-MsixInstaller-PackageVersion.yaml\"));\r\n\r\n    // Update the installer path for testing\r\n    REQUIRE(1 == manifest.Installers.size());\r\n    TestDataFile msixFile(manifest.Installers[0].Url.c_str());\r\n    manifest.Installers[0].Url = msixFile.GetPath().u8string();\r\n\r\n    auto errors = ValidateManifestInstallers(manifest);\r\n    REQUIRE(1 == errors.size());\r\n\r\n    ValidateError(errors[0], ValidationError::Level::Error, ManifestError::InstallerMsixInconsistencies, \"PackageVersion\", \"43690.48059.52428.56797\");\r\n}\r\n\r\nTEST_CASE(\"ReadManifestAndValidateMsixInstallers_MissingFields\", \"[ManifestValidation]\")\r\n{\r\n    TestDataFile testFile(\"Manifest-Bad-MissingMsixInstallerFields.yaml\");\r\n    Manifest manifest = YamlParser::CreateFromPath(testFile);\r\n\r\n    // Update the installer path for testing\r\n    REQUIRE(1 == manifest.Installers.size());\r\n    TestDataFile msixFile(manifest.Installers[0].Url.c_str());\r\n    manifest.Installers[0].Url = msixFile.GetPath().u8string();\r\n\r\n    for (bool treatErrorAsWarning : { false, true })\r\n    {\r\n        auto errors = ValidateManifestInstallers(manifest, treatErrorAsWarning);\r\n        auto expectedLevel = treatErrorAsWarning ? ValidationError::Level::Warning : ValidationError::Level::Error;\r\n        REQUIRE(2 == errors.size());\r\n\r\n        ValidateError(errors[0], expectedLevel, ManifestError::OptionalFieldMissing, \"PackageFamilyName\", \"FakeInstallerForTesting_125rzkzqaqjwj\");\r\n        ValidateError(errors[1], expectedLevel, ManifestError::OptionalFieldMissing, \"MinimumOSVersion\", \"10.0.0.0\");\r\n    }\r\n}\r\n\r\nTEST_CASE(\"ReadManifestAndValidateMsixInstallers_Signed_Success\", \"[ManifestValidation]\")\r\n{\r\n    TestDataFile testFile(\"Manifest-Good-SignedMsixInstaller.yaml\");\r\n    Manifest manifest = YamlParser::CreateFromPath(testFile);\r\n\r\n    // Update the installer path for testing\r\n    REQUIRE(1 == manifest.Installers.size());\r\n    TestDataFile msixFile(manifest.Installers[0].Url.c_str());\r\n    manifest.Installers[0].Url = msixFile.GetPath().u8string();\r\n\r\n    auto errors = ValidateManifestInstallers(manifest);\r\n    REQUIRE(0 == errors.size());\r\n}\r\n\r\nTEST_CASE(\"ReadManifestAndValidateMsixInstallers_Signed_InconsistentFields\", \"[ManifestValidation]\")\r\n{\r\n    TestDataFile testFile(\"Manifest-Bad-InconsistentSignedMsixInstallerFields.yaml\");\r\n    Manifest manifest = YamlParser::CreateFromPath(testFile);\r\n\r\n    // Update the installer path for testing\r\n    REQUIRE(1 == manifest.Installers.size());\r\n    TestDataFile msixFile(manifest.Installers[0].Url.c_str());\r\n    manifest.Installers[0].Url = msixFile.GetPath().u8string();\r\n\r\n    auto errors = ValidateManifestInstallers(manifest);\r\n    REQUIRE(4 == errors.size());\r\n\r\n    ValidateError(errors[0], ValidationError::Level::Error, ManifestError::InstallerMsixInconsistencies, \"SignatureSha256\", \"50562001202c8dad456474d3f20903138d0a15c44ee497c3d4f82e85edbf2f97\");\r\n    ValidateError(errors[1], ValidationError::Level::Error, ManifestError::InstallerMsixInconsistencies, \"PackageFamilyName\", \"FakeInstallerForTesting_125rzkzqaqjwj\");\r\n    ValidateError(errors[2], ValidationError::Level::Error, ManifestError::InstallerMsixInconsistencies, \"PackageVersion\", \"43690.48059.52428.56797\");\r\n    ValidateError(errors[3], ValidationError::Level::Error, ManifestError::InstallerMsixInconsistencies, \"MinimumOSVersion\", \"10.0.0.0\");\r\n}\r\n\r\nTEST_CASE(\"ReadManifestAndValidateMsixBundleInstallers_Success\", \"[ManifestValidation]\")\r\n{\r\n    TestDataFile testFile(\"Manifest-Good-MsixBundleInstaller.yaml\");\r\n    Manifest manifest = YamlParser::CreateFromPath(testFile);\r\n\r\n    // Update the installer path for testing\r\n    REQUIRE(1 == manifest.Installers.size());\r\n    TestDataFile msixFile(manifest.Installers[0].Url.c_str());\r\n    manifest.Installers[0].Url = msixFile.GetPath().u8string();\r\n\r\n    auto errors = ValidateManifestInstallers(manifest);\r\n    REQUIRE(0 == errors.size());\r\n}\r\n\r\nTEST_CASE(\"ReadManifestAndValidateMsixBundleInstallers_WithStub_Success\", \"[ManifestValidation]\")\r\n{\r\n    TestDataFile testFile(\"Manifest-Good-MsixBundleInstaller-WithStub.yaml\");\r\n    Manifest manifest = YamlParser::CreateFromPath(testFile);\r\n\r\n    // Update the installer path for testing\r\n    REQUIRE(1 == manifest.Installers.size());\r\n    TestDataFile msixFile(manifest.Installers[0].Url.c_str());\r\n    manifest.Installers[0].Url = msixFile.GetPath().u8string();\r\n\r\n    auto errors = ValidateManifestInstallers(manifest);\r\n    REQUIRE(0 == errors.size());\r\n}\r\n\r\nTEST_CASE(\"ReadManifestAndValidateMsixBundleInstallers_InconsistentFields\", \"[ManifestValidation]\")\r\n{\r\n    TestDataFile testFile(\"Manifest-Bad-InconsistentMsixBundleInstallerFields.yaml\");\r\n    Manifest manifest = YamlParser::CreateFromPath(testFile);\r\n\r\n    // Update the installer path for testing\r\n    REQUIRE(1 == manifest.Installers.size());\r\n    TestDataFile msixFile(manifest.Installers[0].Url.c_str());\r\n    manifest.Installers[0].Url = msixFile.GetPath().u8string();\r\n\r\n    auto errors = ValidateManifestInstallers(manifest);\r\n    REQUIRE(7 == errors.size());\r\n\r\n    ValidateError(errors[0], ValidationError::Level::Error, ManifestError::MsixSignatureHashFailed);\r\n\r\n    // Validate errors for the first msix package in the msix bundle\r\n    ValidateError(errors[1], ValidationError::Level::Error, ManifestError::InstallerMsixInconsistencies, \"PackageFamilyName\", \"FakeInstallerForTesting_125rzkzqaqjwj\");\r\n    ValidateError(errors[2], ValidationError::Level::Error, ManifestError::InstallerMsixInconsistencies, \"PackageVersion\", \"43690.48059.52428.56797\");\r\n    ValidateError(errors[3], ValidationError::Level::Error, ManifestError::InstallerMsixInconsistencies, \"MinimumOSVersion\", \"10.0.16299.0\");\r\n\r\n    // Validate errors for the second msix package in the msix bundle\r\n    ValidateError(errors[4], ValidationError::Level::Error, ManifestError::InstallerMsixInconsistencies, \"PackageFamilyName\", \"FakeInstallerForTesting_125rzkzqaqjwj\");\r\n    ValidateError(errors[5], ValidationError::Level::Error, ManifestError::InstallerMsixInconsistencies, \"PackageVersion\", \"43690.48059.52428.56797\");\r\n    ValidateError(errors[6], ValidationError::Level::Error, ManifestError::InstallerMsixInconsistencies, \"MinimumOSVersion\", \"10.0.16299.0\");\r\n}\r\n\r\nTEST_CASE(\"ReadManifestAndValidateMsixBundleInstallers_Signed_Success\", \"[ManifestValidation]\")\r\n{\r\n    TestDataFile testFile(\"Manifest-Good-SignedMsixBundleInstaller.yaml\");\r\n    Manifest manifest = YamlParser::CreateFromPath(testFile);\r\n\r\n    // Update the installer path for testing\r\n    REQUIRE(1 == manifest.Installers.size());\r\n    TestDataFile msixFile(manifest.Installers[0].Url.c_str());\r\n    manifest.Installers[0].Url = msixFile.GetPath().u8string();\r\n\r\n    auto errors = ValidateManifestInstallers(manifest);\r\n    REQUIRE(0 == errors.size());\r\n}\r\n\r\nTEST_CASE(\"ReadManifestAndValidateMsixBundleInstallers_Signed_InconsistentFields\", \"[ManifestValidation]\")\r\n{\r\n    TestDataFile testFile(\"Manifest-Bad-InconsistentSignedMsixBundleInstallerFields.yaml\");\r\n    Manifest manifest = YamlParser::CreateFromPath(testFile);\r\n\r\n    // Update the installer path for testing\r\n    REQUIRE(1 == manifest.Installers.size());\r\n    TestDataFile msixFile(manifest.Installers[0].Url.c_str());\r\n    manifest.Installers[0].Url = msixFile.GetPath().u8string();\r\n\r\n    auto errors = ValidateManifestInstallers(manifest);\r\n    REQUIRE(7 == errors.size());\r\n\r\n    ValidateError(errors[0], ValidationError::Level::Error, ManifestError::InstallerMsixInconsistencies, \"SignatureSha256\", \"d70bd623f87b6ce4ddba4506c6000cf43ef3af4ab1207f5579ec43400de1623f\");\r\n\r\n    // Validate errors for the first msix package in the msix bundle\r\n    ValidateError(errors[1], ValidationError::Level::Error, ManifestError::InstallerMsixInconsistencies, \"PackageFamilyName\", \"FakeInstallerForTesting_125rzkzqaqjwj\");\r\n    ValidateError(errors[2], ValidationError::Level::Error, ManifestError::InstallerMsixInconsistencies, \"PackageVersion\", \"43690.48059.52428.56797\");\r\n    ValidateError(errors[3], ValidationError::Level::Error, ManifestError::InstallerMsixInconsistencies, \"MinimumOSVersion\", \"10.0.16299.0\");\r\n\r\n    // Validate errors for the second msix package in the msix bundle\r\n    ValidateError(errors[4], ValidationError::Level::Error, ManifestError::InstallerMsixInconsistencies, \"PackageFamilyName\", \"FakeInstallerForTesting_125rzkzqaqjwj\");\r\n    ValidateError(errors[5], ValidationError::Level::Error, ManifestError::InstallerMsixInconsistencies, \"PackageVersion\", \"43690.48059.52428.56797\");\r\n    ValidateError(errors[6], ValidationError::Level::Error, ManifestError::InstallerMsixInconsistencies, \"MinimumOSVersion\", \"10.0.16299.0\");\r\n}\r\n\r\nTEST_CASE(\"ManifestArpVersionRange\", \"[ManifestValidation]\")\r\n{\r\n    Manifest manifestNoArp = YamlParser::CreateFromPath(TestDataFile(\"Manifest-Good-NoArpVersionDeclared.yaml\"));\r\n    REQUIRE(manifestNoArp.GetArpVersionRange().IsEmpty());\r\n\r\n    Manifest manifestSingleArp = YamlParser::CreateFromPath(TestDataFile(\"Manifest-Good-SingleArpVersionDeclared.yaml\"));\r\n    auto arpRangeSingleArp = manifestSingleArp.GetArpVersionRange();\r\n    REQUIRE(arpRangeSingleArp.GetMinVersion().ToString() == \"11.0\");\r\n    REQUIRE(arpRangeSingleArp.GetMaxVersion().ToString() == \"11.0\");\r\n\r\n    Manifest manifestMultiArp = YamlParser::CreateFromPath(TestDataFile(\"Manifest-Good-MultipleArpVersionDeclared.yaml\"));\r\n    auto arpRangeMultiArp = manifestMultiArp.GetArpVersionRange();\r\n    REQUIRE(arpRangeMultiArp.GetMinVersion().ToString() == \"12.0\");\r\n    REQUIRE(arpRangeMultiArp.GetMaxVersion().ToString() == \"13.0\");\r\n}\r\n\r\nTEST_CASE(\"ManifestV1_10_SchemaHeaderValidations\", \"[ManifestValidation]\")\r\n{\r\n    ManifestValidateOption validateOption;\r\n    validateOption.FullValidation = true;\r\n\r\n    // Schema header not found\r\n    REQUIRE_THROWS_MATCHES(YamlParser::CreateFromPath(TestDataFile(\"ManifestV1_10-Bad-SchemaHeaderNotFound.yaml\"),validateOption), ManifestException, ManifestExceptionMatcher(\"Schema header not found\"));\r\n\r\n    // Schema header not valid\r\n    REQUIRE_THROWS_MATCHES(YamlParser::CreateFromPath(TestDataFile(\"ManifestV1_10-Bad-SchemaHeaderInvalid.yaml\"), validateOption), ManifestException, ManifestExceptionMatcher(\"The schema header is invalid. Please verify that the schema header is present and formatted correctly.\"));\r\n\r\n    // Schema header URL does not match the expected schema URL\r\n    REQUIRE_THROWS_MATCHES(YamlParser::CreateFromPath(TestDataFile(\"ManifestV1_10-Bad-SchemaHeaderURLPatternMismatch.yaml\"), validateOption), ManifestException, ManifestExceptionMatcher(\"The schema header URL does not match the expected pattern.\"));\r\n\r\n    // Schema header ManifestType does not match the expected value\r\n    REQUIRE_THROWS_MATCHES(YamlParser::CreateFromPath(TestDataFile(\"ManifestV1_10-Bad-SchemaHeaderManifestTypeMismatch.yaml\"), validateOption), ManifestException, ManifestExceptionMatcher(\"The manifest type in the schema header does not match the ManifestType property value in the manifest.\"));\r\n\r\n    // Schema header version does not match the expected version\r\n    REQUIRE_THROWS_MATCHES(YamlParser::CreateFromPath(TestDataFile(\"ManifestV1_10-Bad-SchemaHeaderManifestVersionMismatch.yaml\"), validateOption), ManifestException, ManifestExceptionMatcher(\"The manifest version in the schema header does not match the ManifestVersion property value in the manifest.\"));\r\n}\r\n\r\nTEST_CASE(\"ShadowManifest\", \"[ShadowManifest]\")\r\n{\r\n    ManifestValidateOption validateOption;\r\n    validateOption.FullValidation = true;\r\n    validateOption.AllowShadowManifest = true;\r\n\r\n    TempDirectory multiFileDirectory{ \"MultiFileManifest\" };\r\n    CopyTestDataFilesToFolder({\r\n        \"ManifestV1_5-MultiFile-Version.yaml\",\r\n        \"ManifestV1_5-Shadow-Installer.yaml\",\r\n        \"ManifestV1_5-Shadow-DefaultLocale.yaml\",\r\n        \"ManifestV1_5-Shadow-Locale.yaml\",\r\n        \"ManifestV1_5-Shadow-Locale2.yaml\",\r\n        \"ManifestV1_5-Shadow-Shadow.yaml\" }, multiFileDirectory);\r\n\r\n    auto shadowInfo = ManifestShadowTestInfo{};\r\n    shadowInfo.shadowDefaultLocale = true;\r\n    shadowInfo.shadowEnGbLocale = true;\r\n\r\n    TempFile mergedManifestFile{ \"merged.yaml\" };\r\n    Manifest multiFileManifest = YamlParser::CreateFromPath(multiFileDirectory, validateOption, mergedManifestFile);\r\n    VerifyV1ManifestContentCreatedWithShadow(multiFileManifest, shadowInfo);\r\n\r\n    // Read from merged manifest should have the same content as multi file manifest\r\n    Manifest mergedManifest = YamlParser::CreateFromPath(mergedManifestFile);\r\n    VerifyV1ManifestContentCreatedWithShadow(mergedManifest, shadowInfo);\r\n}\r\n\r\nTEST_CASE(\"ShadowManifest_SkipShadowDefaultLocale\", \"[ShadowManifest]\")\r\n{\r\n    ManifestValidateOption validateOption;\r\n    validateOption.FullValidation = true;\r\n    validateOption.AllowShadowManifest = true;\r\n\r\n    TempDirectory multiFileDirectory{ \"MultiFileManifest\" };\r\n    CopyTestDataFilesToFolder({\r\n        \"ManifestV1_5-MultiFile-Version.yaml\",\r\n        \"ManifestV1_5-Shadow-Installer.yaml\",\r\n        \"ManifestV1_5-MultiFile-DefaultLocale.yaml\",\r\n        \"ManifestV1_5-Shadow-Locale.yaml\",\r\n        \"ManifestV1_5-Shadow-Locale2.yaml\",\r\n        \"ManifestV1_5-Shadow-Shadow.yaml\" }, multiFileDirectory);\r\n\r\n    auto shadowInfo = ManifestShadowTestInfo{};\r\n    shadowInfo.shadowDefaultLocale = false;\r\n    shadowInfo.shadowEnGbLocale = true;\r\n\r\n    TempFile mergedManifestFile{ \"merged.yaml\" };\r\n    Manifest multiFileManifest = YamlParser::CreateFromPath(multiFileDirectory, validateOption, mergedManifestFile);\r\n    VerifyV1ManifestContentCreatedWithShadow(multiFileManifest, shadowInfo);\r\n\r\n    // Read from merged manifest should have the same content as multi file manifest\r\n    Manifest mergedManifest = YamlParser::CreateFromPath(mergedManifestFile);\r\n    VerifyV1ManifestContentCreatedWithShadow(mergedManifest, shadowInfo);\r\n}\r\n\r\nTEST_CASE(\"ShadowManifest_SkipShadowLocalizationLocale\", \"[ShadowManifest]\")\r\n{\r\n    ManifestValidateOption validateOption;\r\n    validateOption.FullValidation = true;\r\n    validateOption.AllowShadowManifest = true;\r\n\r\n    TempDirectory multiFileDirectory{ \"MultiFileManifest\" };\r\n    CopyTestDataFilesToFolder({\r\n        \"ManifestV1_5-MultiFile-Version.yaml\",\r\n        \"ManifestV1_5-Shadow-Installer.yaml\",\r\n        \"ManifestV1_5-Shadow-DefaultLocale.yaml\",\r\n        \"ManifestV1_5-MultiFile-Locale.yaml\",\r\n        \"ManifestV1_5-Shadow-Locale2.yaml\",\r\n        \"ManifestV1_5-Shadow-Shadow.yaml\" }, multiFileDirectory);\r\n\r\n    auto shadowInfo = ManifestShadowTestInfo{};\r\n    shadowInfo.shadowDefaultLocale = true;\r\n    shadowInfo.shadowEnGbLocale = false;\r\n\r\n    TempFile mergedManifestFile{ \"merged.yaml\" };\r\n    Manifest multiFileManifest = YamlParser::CreateFromPath(multiFileDirectory, validateOption, mergedManifestFile);\r\n    VerifyV1ManifestContentCreatedWithShadow(multiFileManifest, shadowInfo);\r\n\r\n    // Read from merged manifest should have the same content as multi file manifest\r\n    Manifest mergedManifest = YamlParser::CreateFromPath(mergedManifestFile);\r\n    VerifyV1ManifestContentCreatedWithShadow(mergedManifest, shadowInfo);\r\n}\r\n\r\nTEST_CASE(\"ShadowManifest_ShadowNotAllowed\", \"[ShadowManifest]\")\r\n{\r\n    ManifestValidateOption validateOption;\r\n    validateOption.FullValidation = true;\r\n    validateOption.AllowShadowManifest = false;\r\n\r\n    TempDirectory multiFileDirectory{ \"MultiFileManifest\" };\r\n    CopyTestDataFilesToFolder({\r\n        \"ManifestV1_5-MultiFile-Version.yaml\",\r\n        \"ManifestV1_5-Shadow-Installer.yaml\",\r\n        \"ManifestV1_5-Shadow-DefaultLocale.yaml\",\r\n        \"ManifestV1_5-Shadow-Locale.yaml\",\r\n        \"ManifestV1_5-Shadow-Locale2.yaml\",\r\n        \"ManifestV1_5-Shadow-Shadow.yaml\" }, multiFileDirectory);\r\n\r\n    TempFile mergedManifestFile{ \"merged.yaml\" };\r\n    REQUIRE_THROWS_MATCHES(YamlParser::CreateFromPath(multiFileDirectory, validateOption, mergedManifestFile), ManifestException, ManifestExceptionMatcher(\"Shadow manifest is not allowed. [ManifestType] Value: shadow File: ManifestV1_5-Shadow-Shadow.yaml\"));\r\n}\r\n\r\nTEST_CASE(\"ShadowManifest_TwoShadowFiles\", \"[ShadowManifest]\")\r\n{\r\n    ManifestValidateOption validateOption;\r\n    validateOption.FullValidation = true;\r\n    validateOption.AllowShadowManifest = true;\r\n\r\n    TempDirectory multiFileDirectory{ \"MultiFileManifest\" };\r\n    CopyTestDataFilesToFolder({\r\n        \"ManifestV1_5-MultiFile-Version.yaml\",\r\n        \"ManifestV1_5-Shadow-Installer.yaml\",\r\n        \"ManifestV1_5-Shadow-DefaultLocale.yaml\",\r\n        \"ManifestV1_5-Shadow-Shadow.yaml\",\r\n        \"ManifestV1_5-Shadow-Shadow2.yaml\" }, multiFileDirectory);\r\n\r\n    TempFile mergedManifestFile{ \"merged.yaml\" };\r\n    REQUIRE_THROWS_MATCHES(YamlParser::CreateFromPath(multiFileDirectory, validateOption, mergedManifestFile), ManifestException, ManifestExceptionMatcher(\"The multi file manifest should contain only one file with the particular ManifestType. [ManifestType] Value: shadow File: ManifestV1_5-Shadow-Shadow2.yaml\"));\r\n}\r\n\r\nTEST_CASE(\"ShadowManifest_NotVerifiedPublisher\", \"[ShadowManifest]\")\r\n{\r\n    ManifestValidateOption validateOption;\r\n    validateOption.FullValidation = true;\r\n    validateOption.AllowShadowManifest = true;\r\n    validateOption.ErrorOnVerifiedPublisherFields = true;\r\n\r\n    TempDirectory multiFileDirectory{ \"MultiFileManifest\" };\r\n    CopyTestDataFilesToFolder({\r\n        \"ManifestV1_5-MultiFile-Version.yaml\",\r\n        \"ManifestV1_5-Shadow-Installer.yaml\",\r\n        \"ManifestV1_5-Shadow-DefaultLocale.yaml\",\r\n        \"ManifestV1_5-Shadow-Locale.yaml\",\r\n        \"ManifestV1_5-Shadow-Locale2.yaml\",\r\n        \"ManifestV1_5-Shadow-Shadow.yaml\" }, multiFileDirectory);\r\n\r\n    TempFile mergedManifestFile{ \"merged.yaml\" };\r\n    REQUIRE_THROWS_MATCHES(YamlParser::CreateFromPath(multiFileDirectory, validateOption, mergedManifestFile), ManifestException, ManifestExceptionMatcher(\"Field usage requires verified publishers. [Icons]\"));\r\n}\r\n\r\nTEST_CASE(\"Manifest_PackageFamilyNameInheritance\", \"[ManifestValidation]\")\r\n{\r\n    std::filesystem::path testManifest;\r\n\r\n    SECTION(\"MSIX inside Archive\")\r\n    {\r\n        testManifest = \"Manifest-MSIX-in-Archive.yaml\";\r\n    }\r\n    SECTION(\"MSIX in AppsAndFeatures\")\r\n    {\r\n        testManifest = \"Manifest-MSIX-in-AppsAndFeatures.yaml\";\r\n    }\r\n\r\n    auto manifest = YamlParser::CreateFromPath(TestDataFile(testManifest), GetTestManifestValidateOption());\r\n\r\n    REQUIRE(!manifest.Installers.empty());\r\n    REQUIRE(!manifest.Installers[0].PackageFamilyName.empty());\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCLITests/main.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include <AppInstallerLogging.h>\n#include <AppInstallerFileLogger.h>\n#include <Public/AppInstallerTelemetry.h>\n#include <Telemetry/TraceLogging.h>\n#include <winget/Debugging.h>\n#include \"TestCommon.h\"\n#include \"TestSettings.h\"\n\nusing namespace winrt;\nusing namespace winrt::Windows::Foundation;\nusing namespace std::string_literals;\nusing namespace AppInstaller;\n\n\n// Logs the AppInstaller log target to break up individual tests\nstruct LoggingBreakListener : public Catch::EventListenerBase\n{\n    using EventListenerBase::EventListenerBase;\n\n    void testCaseStarting(const Catch::TestCaseInfo& info) override\n    {\n        Catch::EventListenerBase::testCaseStarting(info);\n        AICLI_LOG(Test, Info, << \"========== Test Case Begins :: \" << info.name << \" ==========\");\n        TestCommon::TempFile::SetTestFailed(false);\n    }\n\n    void testCaseEnded(const Catch::TestCaseStats& testCaseStats) override\n    {\n        AICLI_LOG(Test, Info, << \"========== Test Case Ends ==========\");\n        if (!testCaseStats.totals.delta(lastTotals).testCases.allOk())\n        {\n            TestCommon::TempFile::SetTestFailed(true);\n        }\n        lastTotals = testCaseStats.totals;\n        Catch::EventListenerBase::testCaseEnded(testCaseStats);\n    }\n\n    Catch::Totals lastTotals{};\n};\nCATCH_REGISTER_LISTENER(LoggingBreakListener);\n\n// Map CATCH exceptions so that WIL doesn't fail fast the tests\nHRESULT __stdcall CatchResultFromCaughtException() WI_PFN_NOEXCEPT\n{\n    try\n    {\n        throw;\n    }\n    catch (const Catch::TestFailureException&)\n    {\n        // REC_E_TEST_FAILURE :: Test failure.\n        // Not sure what could generate this, but it is unlikely that we use it.\n        // Since the message is aligned with the issue it should help diagnosis.\n        return 0x8b051032;\n    }\n    catch (...)\n    {\n        // Means we couldn't map the exception\n        return S_OK;\n    }\n}\n\nint main(int argc, char** argv)\n{\n    init_apartment();\n\n    bool hasSetTestDataBasePath = false;\n    bool waitBeforeReturn = false;\n    bool keepSQLLogging = false;\n\n    std::vector<char*> args;\n    for (int i = 0; i < argc; ++i)\n    {\n        if (\"-ktf\"s == argv[i])\n        {\n            TestCommon::TempFile::SetDestructorBehavior(TestCommon::TempFileDestructionBehavior::Keep);\n        }\n        else if (\"-seof\"s == argv[i])\n        {\n            TestCommon::TempFile::SetDestructorBehavior(TestCommon::TempFileDestructionBehavior::ShellExecuteOnFailure);\n        }\n        else if (\"-log\"s == argv[i])\n        {\n            auto logger = std::make_unique<Logging::FileLogger>();\n            logger->SetMaximumSize(0);\n            Logging::Log().AddLogger(std::move(logger));\n        }\n        else if (\"-logto\"s == argv[i])\n        {\n            if (++i < argc)\n            {\n                auto logger = std::make_unique<Logging::FileLogger>(std::filesystem::path{ argv[i] });\n                logger->SetMaximumSize(0);\n                Logging::Log().AddLogger(std::move(logger));\n            }\n        }\n        else if (\"-tdd\"s == argv[i])\n        {\n            if (++i < argc)\n            {\n                TestCommon::TestDataFile::SetTestDataBasePath(argv[i]);\n                hasSetTestDataBasePath = true;\n            }\n        }\n        else if (\"-wait\"s == argv[i])\n        {\n            waitBeforeReturn = true;\n        }\n        else if (\"-logsql\"s == argv[i])\n        {\n            keepSQLLogging = true;\n        }\n        else if (\"-mdmp\"s == argv[i])\n        {\n            Debugging::EnableSelfInitiatedMinidump();\n        }\n        else if (\"-mdmpto\"s == argv[i])\n        {\n            if (++i < argc)\n            {\n                Debugging::EnableSelfInitiatedMinidump(std::filesystem::path{ argv[i] });\n            }\n        }\n        else\n        {\n            args.push_back(argv[i]);\n        }\n    }\n\n    // If not set, use the current executables path\n    if (!hasSetTestDataBasePath)\n    {\n        wchar_t fullFileName[1024];\n        DWORD chars = ARRAYSIZE(fullFileName);\n        if (QueryFullProcessImageNameW(GetCurrentProcess(), 0, fullFileName, &chars))\n        {\n            std::filesystem::path filepath{ fullFileName };\n            filepath.remove_filename();\n            TestCommon::TestDataFile::SetTestDataBasePath(filepath);\n        }\n    }\n\n    // Enable logging, to force log string building to run.\n    // Disable SQL by default, as it generates 10s of MBs of log file and\n    // increases the full test run time by 60% or more.\n    // By not creating a log target, it will all be thrown away.\n    Logging::Log().SetEnabledChannels(Logging::Channel::All);\n    if (!keepSQLLogging)\n    {\n        Logging::Log().DisableChannel(Logging::Channel::SQL);\n    }\n    Logging::Log().SetLevel(Logging::Level::Verbose);\n    Logging::EnableWilFailureTelemetry();\n\n    wil::SetResultFromCaughtExceptionCallback(CatchResultFromCaughtException);\n\n    // Forcibly enable event writing to catch bugs in that code\n    g_IsTelemetryProviderEnabled = true;\n\n    TestCommon::SetTestPathOverrides();\n\n    // Remove any existing settings files in the new tests path\n    TestCommon::UserSettingsFileGuard settingsGuard;\n\n    int result = Catch::Session().run(static_cast<int>(args.size()), args.data());\n\n    if (waitBeforeReturn)\n    {\n        // Wait for some input before returning\n        std::cin.get();\n    }\n\n    return result;\n}\n"
  },
  {
    "path": "src/AppInstallerCLITests/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<packages>\r\n  <package id=\"Microsoft.Windows.CppWinRT\" version=\"2.0.250303.1\" targetFramework=\"native\" />\r\n  <package id=\"Microsoft.Windows.ImplementationLibrary\" version=\"1.0.250325.1\" targetFramework=\"native\" />\r\n</packages>"
  },
  {
    "path": "src/AppInstallerCLITests/pch.cpp",
    "content": "﻿#include \"pch.h\"\n"
  },
  {
    "path": "src/AppInstallerCLITests/pch.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#define NOMINMAX\n#include <Windows.h>\n#include <AclAPI.h>\n#include <WinInet.h>\n#include <shellapi.h>\n#include <objbase.h>\n#include <urlmon.h>\n#include <Msi.h>\n#include <KnownFolders.h>\n\n#include <catch2/catch_session.hpp>\n#include <catch2/catch_template_test_macros.hpp>\n#include <catch2/catch_test_case_info.hpp>\n#include <catch2/catch_test_macros.hpp>\n#include <catch2/generators/catch_generators.hpp>\n#include <catch2/matchers/catch_matchers.hpp>\n#include <catch2/reporters/catch_reporter_event_listener.hpp>\n#include <catch2/reporters/catch_reporter_registrars.hpp>\n\n#include <json/json.h>\n\n#include <winrt/Windows.Foundation.h>\n#include <winrt/Windows.Foundation.Collections.h>\n#include <winrt/Windows.Globalization.h>\n#include <winrt/Windows.Management.Deployment.h>\n#include <winrt/Windows.Web.Http.h>\n#include <wrl/client.h>\n\n#include <wil/filesystem.h>\n#include <wil/resource.h>\n#include <wil/result_macros.h>\r\n#include <wil/safecast.h>\n#include <wil/token_helpers.h>\n\n#include <algorithm>\n#include <atomic>\n#include <filesystem>\n#include <fstream>\n#include <functional>\n#include <future>\n#include <iostream>\n#include <memory>\n#include <random>\n#include <set>\n#include <sstream>\n#include <string>\n#include <string_view>\n#include <unordered_set>\n#include <utility>\n#include <vector>\n"
  },
  {
    "path": "src/AppInstallerCommonCore/AdminSettings.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"AppInstallerLogging.h\"\r\n#include \"AppInstallerStrings.h\"\r\n#include \"winget/Settings.h\"\r\n#include \"winget/AdminSettings.h\"\r\n#include \"winget/GroupPolicy.h\"\r\n#include \"winget/Yaml.h\"\r\n\r\nnamespace AppInstaller::Settings\r\n{\r\n    using namespace std::string_view_literals;\r\n    using namespace Utility::literals;\r\n\r\n    namespace\r\n    {\r\n        constexpr Utility::LocIndView s_AdminSettingsYaml_LocalManifestFiles = \"LocalManifestFiles\"_liv;\r\n        constexpr Utility::LocIndView s_AdminSettingsYaml_BypassCertificatePinningForMicrosoftStore = \"BypassCertificatePinningForMicrosoftStore\"_liv;\r\n        constexpr Utility::LocIndView s_AdminSettingsYaml_InstallerHashOverride = \"InstallerHashOverride\"_liv;\r\n        constexpr Utility::LocIndView s_AdminSettingsYaml_LocalArchiveMalwareScanOverride = \"LocalArchiveMalwareScanOverride\"_liv;\r\n        constexpr Utility::LocIndView s_AdminSettingsYaml_ProxyCommandLineOptions = \"ProxyCommandLineOptions\"_liv;\r\n\r\n        constexpr Utility::LocIndView s_AdminSettingsYaml_DefaultProxy = \"DefaultProxy\"_liv;\r\n\r\n        // Attempts to read a single scalar value from the node.\r\n        template<typename Value>\r\n        bool TryReadScalar(const YAML::Node& rootNode, std::string_view name, Value& value)\r\n        {\r\n            YAML::Node valueNode = rootNode[std::string{ name }];\r\n\r\n            if (!valueNode || !valueNode.IsScalar())\r\n            {\r\n                AICLI_LOG(Core, Verbose, << \"Admin setting '\" << name << \"' was not found or did not contain the expected format\");\r\n                return false;\r\n            }\r\n\r\n            value = valueNode.as<Value>();\r\n            return true;\r\n        }\r\n\r\n        struct AdminSettingValues\r\n        {\r\n            bool LocalManifestFiles = false;\r\n            bool BypassCertificatePinningForMicrosoftStore = false;\r\n            bool InstallerHashOverride = false;\r\n            bool LocalArchiveMalwareScanOverride = false;\r\n            bool ProxyCommandLineOptions = false;\r\n\r\n            std::optional<std::string> DefaultProxy;\r\n        };\r\n\r\n        struct AdminSettingsInternal\r\n        {\r\n            AdminSettingsInternal();\r\n\r\n            void SetAdminSetting(BoolAdminSetting setting, bool enabled);\r\n            void SetAdminSetting(StringAdminSetting setting, const std::optional<std::string>& value);\r\n\r\n            bool GetAdminSettingValue(BoolAdminSetting setting) const;\r\n            std::optional<std::string> GetAdminSettingValue(StringAdminSetting setting) const;\r\n\r\n            void Reset();\r\n\r\n        private:\r\n            void LoadAdminSettings();\r\n            [[nodiscard]] bool SaveAdminSettings();\r\n\r\n            // Sets the value of an admin setting using the given function and then saves the changes.\r\n            // Encapsulates the retry and reload logic.\r\n            // Stops if the value cannot be set, as indicated by the return value of setValue()\r\n            void SetAdminSettingAndSave(std::function<bool()> setValue);\r\n\r\n            Stream m_settingStream;\r\n            AdminSettingValues m_settingValues;\r\n        };\r\n\r\n        AdminSettingsInternal::AdminSettingsInternal() : m_settingStream(Stream::AdminSettings)\r\n        {\r\n            LoadAdminSettings();\r\n        }\r\n\r\n        void AdminSettingsInternal::SetAdminSettingAndSave(std::function<bool()> setValue)\r\n        {\r\n            for (size_t i = 0; i < 10; ++i)\r\n            {\r\n                if (!setValue())\r\n                {\r\n                    return;\r\n                }\r\n\r\n                if (SaveAdminSettings())\r\n                {\r\n                    return;\r\n                }\r\n\r\n                // We need to reload the settings as they have changed\r\n                LoadAdminSettings();\r\n            }\r\n\r\n            THROW_HR_MSG(E_UNEXPECTED, \"Too many attempts at SaveAdminSettings\");\r\n        }\r\n\r\n        void AdminSettingsInternal::SetAdminSetting(BoolAdminSetting setting, bool enabled)\r\n        {\r\n            SetAdminSettingAndSave([&]()\r\n                {\r\n                    switch (setting)\r\n                    {\r\n                    case BoolAdminSetting::LocalManifestFiles:\r\n                        m_settingValues.LocalManifestFiles = enabled;\r\n                        return true;\r\n                    case BoolAdminSetting::BypassCertificatePinningForMicrosoftStore:\r\n                        m_settingValues.BypassCertificatePinningForMicrosoftStore = enabled;\r\n                        return true;\r\n                    case BoolAdminSetting::InstallerHashOverride:\r\n                        m_settingValues.InstallerHashOverride = enabled;\r\n                        return true;\r\n                    case BoolAdminSetting::LocalArchiveMalwareScanOverride:\r\n                        m_settingValues.LocalArchiveMalwareScanOverride = enabled;\r\n                        return true;\r\n                    case BoolAdminSetting::ProxyCommandLineOptions:\r\n                        m_settingValues.ProxyCommandLineOptions = enabled;\r\n                        return true;\r\n                    default:\r\n                        return false;\r\n                    }\r\n                });\r\n        }\r\n\r\n        void AdminSettingsInternal::SetAdminSetting(StringAdminSetting setting, const std::optional<std::string>& value)\r\n        {\r\n            SetAdminSettingAndSave([&]()\r\n                {\r\n                    switch (setting)\r\n                    {\r\n                    case StringAdminSetting::DefaultProxy:\r\n                        m_settingValues.DefaultProxy = value;\r\n                        return true;\r\n                    default:\r\n                        return false;\r\n                    }\r\n                });\r\n        }\r\n\r\n        bool AdminSettingsInternal::GetAdminSettingValue(BoolAdminSetting setting) const\r\n        {\r\n            switch (setting)\r\n            {\r\n            case BoolAdminSetting::LocalManifestFiles:\r\n                return m_settingValues.LocalManifestFiles;\r\n            case BoolAdminSetting::BypassCertificatePinningForMicrosoftStore:\r\n                return m_settingValues.BypassCertificatePinningForMicrosoftStore;\r\n            case BoolAdminSetting::InstallerHashOverride:\r\n                return m_settingValues.InstallerHashOverride;\r\n            case BoolAdminSetting::LocalArchiveMalwareScanOverride:\r\n                return m_settingValues.LocalArchiveMalwareScanOverride;\r\n            case BoolAdminSetting::ProxyCommandLineOptions:\r\n                return m_settingValues.ProxyCommandLineOptions;\r\n            default:\r\n                return false;\r\n            }\r\n        }\r\n\r\n        std::optional<std::string> AdminSettingsInternal::GetAdminSettingValue(StringAdminSetting setting) const\r\n        {\r\n            switch (setting)\r\n            {\r\n            case StringAdminSetting::DefaultProxy:\r\n                return m_settingValues.DefaultProxy;\r\n            default:\r\n                return std::nullopt;\r\n            }\r\n        }\r\n\r\n        void AdminSettingsInternal::Reset()\r\n        {\r\n            m_settingStream.Remove();\r\n        }\r\n\r\n        void AdminSettingsInternal::LoadAdminSettings()\r\n        {\r\n            auto stream = m_settingStream.Get();\r\n            if (!stream)\r\n            {\r\n                AICLI_LOG(Core, Verbose, << \"Admin settings was not found\");\r\n                return;\r\n            }\r\n\r\n            std::string adminSettingsYaml = Utility::ReadEntireStream(*stream);\r\n\r\n            YAML::Node document;\r\n            try\r\n            {\r\n                document = YAML::Load(adminSettingsYaml);\r\n            }\r\n            catch (const std::exception& e)\r\n            {\r\n                AICLI_LOG(YAML, Error, << \"Admin settings contained invalid YAML (\" << e.what() << \")\");\r\n                return;\r\n            }\r\n\r\n            if (document.IsNull())\r\n            {\r\n                AICLI_LOG(Core, Info, << \"Admin settings is empty\");\r\n                return;\r\n            }\r\n\r\n            if (!document.IsMap())\r\n            {\r\n                AICLI_LOG(Core, Error, << \"Admin settings did not contain the expected format\");\r\n                return;\r\n            }\r\n\r\n            TryReadScalar<bool>(document, s_AdminSettingsYaml_LocalManifestFiles, m_settingValues.LocalManifestFiles);\r\n            TryReadScalar<bool>(document, s_AdminSettingsYaml_BypassCertificatePinningForMicrosoftStore, m_settingValues.BypassCertificatePinningForMicrosoftStore);\r\n            TryReadScalar<bool>(document, s_AdminSettingsYaml_InstallerHashOverride, m_settingValues.InstallerHashOverride);\r\n            TryReadScalar<bool>(document, s_AdminSettingsYaml_LocalArchiveMalwareScanOverride, m_settingValues.LocalArchiveMalwareScanOverride);\r\n            TryReadScalar<bool>(document, s_AdminSettingsYaml_ProxyCommandLineOptions, m_settingValues.ProxyCommandLineOptions);\r\n\r\n            std::string defaultProxy;\r\n            if (TryReadScalar<std::string>(document, s_AdminSettingsYaml_DefaultProxy, defaultProxy))\r\n            {\r\n                m_settingValues.DefaultProxy.emplace(std::move(defaultProxy));\r\n            }\r\n        }\r\n\r\n        bool AdminSettingsInternal::SaveAdminSettings()\r\n        {\r\n            YAML::Emitter out;\r\n            out << YAML::BeginMap;\r\n            out << YAML::Key << s_AdminSettingsYaml_LocalManifestFiles << YAML::Value << m_settingValues.LocalManifestFiles;\r\n            out << YAML::Key << s_AdminSettingsYaml_BypassCertificatePinningForMicrosoftStore << YAML::Value << m_settingValues.BypassCertificatePinningForMicrosoftStore;\r\n            out << YAML::Key << s_AdminSettingsYaml_InstallerHashOverride << YAML::Value << m_settingValues.InstallerHashOverride;\r\n            out << YAML::Key << s_AdminSettingsYaml_LocalArchiveMalwareScanOverride << YAML::Value << m_settingValues.LocalArchiveMalwareScanOverride;\r\n            out << YAML::Key << s_AdminSettingsYaml_ProxyCommandLineOptions << YAML::Value << m_settingValues.ProxyCommandLineOptions;\r\n\r\n            if (m_settingValues.DefaultProxy)\r\n            {\r\n                out << YAML::Key << s_AdminSettingsYaml_DefaultProxy << YAML::Value << m_settingValues.DefaultProxy.value();\r\n            }\r\n\r\n            out << YAML::EndMap;\r\n\r\n            return m_settingStream.Set(out.str());\r\n        }\r\n\r\n        auto GetPolicyStateForSetting(BoolAdminSetting setting)\r\n        {\r\n            auto policy = GetAdminSettingPolicy(setting);\r\n            return GroupPolicies().GetState(policy);\r\n        }\r\n\r\n        std::optional<std::reference_wrapper<const std::string>> GetPolicyStateForSetting(StringAdminSetting setting)\r\n        {\r\n            switch (setting)\r\n            {\r\n            case AppInstaller::Settings::StringAdminSetting::DefaultProxy:\r\n                return GroupPolicies().GetValueRef<ValuePolicy::DefaultProxy>();\r\n            default:\r\n                return std::nullopt;\r\n            }\r\n        }\r\n    }\r\n\r\n    BoolAdminSetting StringToBoolAdminSetting(std::string_view in)\r\n    {\r\n        BoolAdminSetting result = BoolAdminSetting::Unknown;\r\n\r\n        if (Utility::CaseInsensitiveEquals(s_AdminSettingsYaml_LocalManifestFiles, in))\r\n        {\r\n            result = BoolAdminSetting::LocalManifestFiles;\r\n        }\r\n        else if (Utility::CaseInsensitiveEquals(s_AdminSettingsYaml_BypassCertificatePinningForMicrosoftStore, in))\r\n        {\r\n            result = BoolAdminSetting::BypassCertificatePinningForMicrosoftStore;\r\n        }\r\n        else if (Utility::CaseInsensitiveEquals(s_AdminSettingsYaml_InstallerHashOverride, in))\r\n        {\r\n            result = BoolAdminSetting::InstallerHashOverride;\r\n        }\r\n        else if (Utility::CaseInsensitiveEquals(s_AdminSettingsYaml_LocalArchiveMalwareScanOverride, in))\r\n        {\r\n            result = BoolAdminSetting::LocalArchiveMalwareScanOverride;\r\n        }\r\n        else if (Utility::CaseInsensitiveEquals(s_AdminSettingsYaml_ProxyCommandLineOptions, in))\r\n        {\r\n            result = BoolAdminSetting::ProxyCommandLineOptions;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    StringAdminSetting StringToStringAdminSetting(std::string_view in)\r\n    {\r\n        StringAdminSetting result = StringAdminSetting::Unknown;\r\n\r\n        if (Utility::CaseInsensitiveEquals(s_AdminSettingsYaml_DefaultProxy, in))\r\n        {\r\n            result = StringAdminSetting::DefaultProxy;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    Utility::LocIndView AdminSettingToString(BoolAdminSetting setting)\r\n    {\r\n        switch (setting)\r\n        {\r\n        case BoolAdminSetting::LocalManifestFiles:\r\n            return s_AdminSettingsYaml_LocalManifestFiles;\r\n        case BoolAdminSetting::BypassCertificatePinningForMicrosoftStore:\r\n            return s_AdminSettingsYaml_BypassCertificatePinningForMicrosoftStore;\r\n        case BoolAdminSetting::InstallerHashOverride:\r\n            return s_AdminSettingsYaml_InstallerHashOverride;\r\n        case BoolAdminSetting::LocalArchiveMalwareScanOverride:\r\n            return s_AdminSettingsYaml_LocalArchiveMalwareScanOverride;\r\n        case BoolAdminSetting::ProxyCommandLineOptions:\r\n            return s_AdminSettingsYaml_ProxyCommandLineOptions;\r\n        default:\r\n            return \"Unknown\"_liv;\r\n        }\r\n    }\r\n\r\n    Utility::LocIndView AdminSettingToString(StringAdminSetting setting)\r\n    {\r\n        switch (setting)\r\n        {\r\n        case StringAdminSetting::DefaultProxy:\r\n            return s_AdminSettingsYaml_DefaultProxy;\r\n        default:\r\n            return \"Unknown\"_liv;\r\n        }\r\n    }\r\n\r\n    TogglePolicy::Policy GetAdminSettingPolicy(BoolAdminSetting setting)\r\n    {\r\n        switch (setting)\r\n        {\r\n        case BoolAdminSetting::LocalManifestFiles:\r\n            return TogglePolicy::Policy::LocalManifestFiles;\r\n        case BoolAdminSetting::BypassCertificatePinningForMicrosoftStore:\r\n            return TogglePolicy::Policy::BypassCertificatePinningForMicrosoftStore;\r\n        case BoolAdminSetting::InstallerHashOverride:\r\n            return TogglePolicy::Policy::HashOverride;\r\n        case BoolAdminSetting::LocalArchiveMalwareScanOverride:\r\n            return TogglePolicy::Policy::LocalArchiveMalwareScanOverride;\r\n        case BoolAdminSetting::ProxyCommandLineOptions:\r\n            return TogglePolicy::Policy::ProxyCommandLineOptions;\r\n        default:\r\n            return TogglePolicy::Policy::None;\r\n        }\r\n    }\r\n\r\n    bool EnableAdminSetting(BoolAdminSetting setting)\r\n    {\r\n        if (GetPolicyStateForSetting(setting) == PolicyState::Disabled)\r\n        {\r\n            return false;\r\n        }\r\n\r\n        AdminSettingsInternal adminSettingsInternal;\r\n        adminSettingsInternal.SetAdminSetting(setting, true);\r\n        return true;\r\n    }\r\n\r\n    bool DisableAdminSetting(BoolAdminSetting setting)\r\n    {\r\n        if (GetPolicyStateForSetting(setting) == PolicyState::Enabled)\r\n        {\r\n            return false;\r\n        }\r\n\r\n        AdminSettingsInternal adminSettingsInternal;\r\n        adminSettingsInternal.SetAdminSetting(setting, false);\r\n        return true;\r\n    }\r\n\r\n    bool IsAdminSettingEnabled(BoolAdminSetting setting)\r\n    {\r\n        // Check for a policy that overrides this setting.\r\n        auto policyState = GetPolicyStateForSetting(setting);\r\n        if (policyState != PolicyState::NotConfigured)\r\n        {\r\n            return policyState == PolicyState::Enabled;\r\n        }\r\n\r\n        AdminSettingsInternal adminSettingsInternal;\r\n        return adminSettingsInternal.GetAdminSettingValue(setting);\r\n    }\r\n\r\n    bool SetAdminSetting(StringAdminSetting setting, std::string_view value)\r\n    {\r\n        if (GetPolicyStateForSetting(setting))\r\n        {\r\n            return false;\r\n        }\r\n\r\n        AdminSettingsInternal adminSettingsInternal;\r\n        adminSettingsInternal.SetAdminSetting(setting, std::string{ value });\r\n        return true;\r\n    }\r\n\r\n    bool ResetAdminSetting(StringAdminSetting setting)\r\n    {\r\n        if (GetPolicyStateForSetting(setting))\r\n        {\r\n            return false;\r\n        }\r\n\r\n        AdminSettingsInternal adminSettingsInternal;\r\n        adminSettingsInternal.SetAdminSetting(setting, std::nullopt);\r\n        return true;\r\n    }\r\n\r\n    void ResetAllAdminSettings()\r\n    {\r\n        AdminSettingsInternal{}.Reset();\r\n    }\r\n\r\n    std::optional<std::string> GetAdminSetting(StringAdminSetting setting)\r\n    {\r\n        // Check for a policy that overrides this setting.\r\n        auto policyState = GetPolicyStateForSetting(setting);\r\n        if (policyState)\r\n        {\r\n            return policyState.value();\r\n        }\r\n\r\n        AdminSettingsInternal adminSettingsInternal;\r\n        return adminSettingsInternal.GetAdminSettingValue(setting);\r\n    }\r\n\r\n    std::vector<BoolAdminSetting> GetAllBoolAdminSettings()\r\n    {\r\n        return GetAllSequentialEnumValues(BoolAdminSetting::Unknown);\r\n    }\r\n\r\n    std::vector<StringAdminSetting> GetAllStringAdminSettings()\r\n    {\r\n        return GetAllSequentialEnumValues(StringAdminSetting::Unknown);\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" />\r\n  <PropertyGroup Label=\"Globals\">\r\n    <CppWinRTOptimized>true</CppWinRTOptimized>\r\n    <CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>\r\n    <CppWinRTGenerateWindowsMetadata>false</CppWinRTGenerateWindowsMetadata>\r\n    <MinimalCoreWin>true</MinimalCoreWin>\r\n    <VCProjectVersion>15.0</VCProjectVersion>\r\n    <ProjectGuid>{5890d6ed-7c3b-40f3-b436-b54f640d9e65}</ProjectGuid>\r\n    <Keyword>Win32Proj</Keyword>\r\n    <RootNamespace>AppInstallerLoggingCore</RootNamespace>\r\n    <WindowsTargetPlatformVersion>10.0.26100.0</WindowsTargetPlatformVersion>\r\n    <WindowsTargetPlatformMinVersion>10.0.17763.0</WindowsTargetPlatformMinVersion>\r\n    <WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|ARM64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|Win32\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Fuzzing|x64\">\r\n      <Configuration>Fuzzing</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Fuzzing|Win32\">\r\n      <Configuration>Fuzzing</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|ARM64\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|Win32\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|x64\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|ARM64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|Win32\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <PropertyGroup Label=\"Configuration\">\r\n    <ConfigurationType>StaticLibrary</ConfigurationType>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Debug'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n    <LinkIncremental>true</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Release'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <LinkIncremental>false</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='ReleaseStatic'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <LinkIncremental>false</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Fuzzing'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>false</WholeProgramOptimization>\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <EnableASAN>true</EnableASAN>\r\n  </PropertyGroup>\r\n  <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\" Label=\"Configuration\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\" Label=\"Configuration\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\" Label=\"Configuration\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\r\n  <ImportGroup Label=\"ExtensionSettings\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"Shared\">\r\n    <Import Project=\"..\\ManifestSchema\\ManifestSchema.vcxitems\" Label=\"Shared\" />\r\n    <Import Project=\"..\\COMServer\\COMServer.vcxitems\" Label=\"Shared\" />\r\n    <Import Project=\"..\\CertificateResources\\CertificateResources.vcxitems\" Label=\"Shared\" />\r\n    <Import Project=\"..\\PureLib\\PureLib.vcxitems\" Label=\"Shared\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"PropertySheet.props\" />\r\n  </ImportGroup>\r\n  <PropertyGroup Label=\"UserMacros\" />\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>true</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>true</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>true</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Fuzzing|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Fuzzing|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(ProjectDir)\\..\\vcpkg.props\" />\r\n  <ItemDefinitionGroup>\r\n    <ClCompile>\r\n      <PrecompiledHeader>Use</PrecompiledHeader>\r\n      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>\r\n      <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>\r\n      <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <AdditionalOptions>%(AdditionalOptions) /permissive- /D _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING</AdditionalOptions>\r\n    </ClCompile>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Debug'\">\r\n    <ClCompile>\r\n      <Optimization>Disabled</Optimization>\r\n      <PreprocessorDefinitions>_NO_ASYNCRTIMP;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;_DEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">$(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\\AppInstallerSharedLib;$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\binver;$(ProjectDir)..\\SfsClient\\sfs-client\\client\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">$(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\\AppInstallerSharedLib;$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\binver;$(ProjectDir)..\\SfsClient\\sfs-client\\client\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</TreatWarningAsError>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</EnablePREfast>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">Windows</SubSystem>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Platform)'=='Win32'\">\r\n    <ClCompile>\r\n      <PreprocessorDefinitions>_NO_ASYNCRTIMP;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;WIN32;%(PreprocessorDefinitions);CLICOREDLLBUILD</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">$(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\\AppInstallerSharedLib;$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\binver;$(ProjectDir)..\\SfsClient\\sfs-client\\client\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</TreatWarningAsError>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</EnablePREfast>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Windows</SubSystem>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Release'\">\r\n    <ClCompile>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>_NO_ASYNCRTIMP;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;NDEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">$(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\\AppInstallerSharedLib;$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\binver;$(ProjectDir)..\\SfsClient\\sfs-client\\client\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">$(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\\AppInstallerSharedLib;$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\binver;$(ProjectDir)..\\SfsClient\\sfs-client\\client\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">$(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\\AppInstallerSharedLib;$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\binver;$(ProjectDir)..\\SfsClient\\sfs-client\\client\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">true</TreatWarningAsError>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</EnablePREfast>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Windows</SubSystem>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='ReleaseStatic'\">\r\n    <ClCompile>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>_NO_ASYNCRTIMP;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;NDEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">$(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\\AppInstallerSharedLib;$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\binver;$(ProjectDir)..\\SfsClient\\sfs-client\\client\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">$(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\\AppInstallerSharedLib;$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\binver;$(ProjectDir)..\\SfsClient\\sfs-client\\client\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">$(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\\AppInstallerSharedLib;$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\binver;$(ProjectDir)..\\SfsClient\\sfs-client\\client\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">true</TreatWarningAsError>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">false</EnablePREfast>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">MultiThreaded</RuntimeLibrary>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">MultiThreaded</RuntimeLibrary>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">MultiThreaded</RuntimeLibrary>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">Windows</SubSystem>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Fuzzing'\">\r\n    <ClCompile>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>_NO_ASYNCRTIMP;NDEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD;WINGET_DISABLE_FOR_FUZZING;_DISABLE_VECTOR_ANNOTATION;_DISABLE_STRING_ANNOTATION</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories>$(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\\AppInstallerSharedLib;$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\binver;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError>true</TreatWarningAsError>\r\n      <LanguageStandard>stdcpp17</LanguageStandard>\r\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r\n      <AdditionalOptions>%(AdditionalOptions) /fsanitize=address /fsanitize-coverage=inline-8bit-counters /fsanitize-coverage=edge /fsanitize-coverage=trace-cmp /fsanitize-coverage=trace-div</AdditionalOptions>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Fuzzing|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <SubSystem>Windows</SubSystem>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"Authentication\\WebAccountManagerAuthenticator.h\" />\r\n    <ClInclude Include=\"DODownloader.h\" />\r\n    <ClInclude Include=\"Public\\winget\\Authentication.h\" />\r\n    <ClInclude Include=\"Public\\winget\\FileCache.h\" />\r\n    <ClInclude Include=\"Public\\winget\\FolderFileWatcher.h\" />\r\n    <ClInclude Include=\"Public\\winget\\ManifestComparator.h\" />\r\n    <ClInclude Include=\"Public\\winget\\MsixManifest.h\" />\r\n    <ClInclude Include=\"Public\\winget\\AdminSettings.h\" />\r\n    <ClInclude Include=\"Public\\winget\\Debugging.h\" />\r\n    <ClInclude Include=\"Public\\winget\\DependenciesGraph.h\" />\r\n    <ClInclude Include=\"HttpStream\\HttpClientWrapper.h\" />\r\n    <ClInclude Include=\"HttpStream\\HttpLocalCache.h\" />\r\n    <ClInclude Include=\"HttpStream\\HttpRandomAccessStream.h\" />\r\n    <ClInclude Include=\"pch.h\" />\r\n    <ClInclude Include=\"Public\\AppInstallerDeployment.h\" />\r\n    <ClInclude Include=\"Public\\AppInstallerDownloader.h\" />\r\n    <ClInclude Include=\"Public\\AppInstallerFileLogger.h\" />\r\n    <ClInclude Include=\"Public\\AppInstallerProgress.h\" />\r\n    <ClInclude Include=\"Public\\AppInstallerMsixInfo.h\" />\r\n    <ClInclude Include=\"Public\\AppInstallerRuntime.h\" />\r\n    <ClInclude Include=\"Public\\AppInstallerSynchronization.h\" />\r\n    <ClInclude Include=\"Public\\AppInstallerTelemetry.h\" />\r\n    <ClInclude Include=\"Public\\AppInstallerArchitecture.h\" />\r\n    <ClInclude Include=\"Public\\winget\\Archive.h\" />\r\n    <ClInclude Include=\"Public\\winget\\ExperimentalFeature.h\" />\r\n    <ClInclude Include=\"Public\\winget\\ExtensionCatalog.h\" />\r\n    <ClInclude Include=\"Public\\winget\\Fonts.h\" />\r\n    <ClInclude Include=\"Public\\winget\\HttpClientHelper.h\">\r\n      <ExcludedFromBuild Condition=\"'$(Configuration)'=='Fuzzing'\">true</ExcludedFromBuild>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\Locale.h\" />\r\n    <ClInclude Include=\"Public\\winget\\Manifest.h\" />\r\n    <ClInclude Include=\"Public\\winget\\ManifestInstaller.h\" />\r\n    <ClInclude Include=\"Public\\winget\\ManifestLocalization.h\" />\r\n    <ClInclude Include=\"Public\\winget\\ManifestCommon.h\" />\r\n    <ClInclude Include=\"Public\\winget\\ManifestValidation.h\" />\r\n    <ClInclude Include=\"Public\\winget\\ManifestYamlParser.h\" />\r\n    <ClInclude Include=\"Public\\winget\\ManifestYamlPopulator.h\" />\r\n    <ClInclude Include=\"Public\\winget\\ManifestYamlWriter.h\" />\r\n    <ClInclude Include=\"Public\\winget\\MsiExecArguments.h\" />\r\n    <ClInclude Include=\"Public\\winget\\MsixManifestValidation.h\" />\r\n    <ClInclude Include=\"Public\\winget\\MSStore.h\" />\r\n    <ClInclude Include=\"Public\\winget\\MSStoreDownload.h\">\r\n      <ExcludedFromBuild Condition=\"'$(Configuration)'=='Fuzzing'\">true</ExcludedFromBuild>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\NameNormalization.h\" />\r\n    <ClInclude Include=\"Public\\winget\\NetworkSettings.h\" />\r\n    <ClInclude Include=\"Public\\winget\\OutputDebugStringLogger.h\" />\r\n    <ClInclude Include=\"Public\\winget\\PackageDependenciesValidationUtil.h\" />\r\n    <ClInclude Include=\"Public\\winget\\PackageVersionDataManifest.h\" />\r\n    <ClInclude Include=\"Public\\winget\\Pin.h\" />\r\n    <ClInclude Include=\"Public\\winget\\Reboot.h\" />\r\n    <ClInclude Include=\"Public\\winget\\Regex.h\" />\r\n    <ClInclude Include=\"Public\\winget\\Rest.h\" />\r\n    <ClInclude Include=\"Public\\winget\\PathVariable.h\" />\r\n    <ClInclude Include=\"Public\\winget\\PortableARPEntry.h\" />\r\n    <ClInclude Include=\"Public\\winget\\PortableFileEntry.h\" />\r\n    <ClInclude Include=\"Public\\winget\\ManifestSchemaValidation.h\" />\r\n    <ClInclude Include=\"Public\\winget\\SelfManagement.h\" />\r\n    <ClInclude Include=\"Public\\winget\\Settings.h\" />\r\n    <ClInclude Include=\"Public\\winget\\StdErrLogger.h\" />\r\n    <ClInclude Include=\"Public\\winget\\ThreadGlobals.h\" />\r\n    <ClInclude Include=\"Public\\winget\\TraceLogger.h\" />\r\n    <ClInclude Include=\"Public\\winget\\UserSettings.h\" />\r\n    <ClInclude Include=\"Telemetry\\TraceLogging.h\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"AdminSettings.cpp\" />\r\n    <ClCompile Include=\"Authentication\\Authentication.cpp\" />\r\n    <ClCompile Include=\"Authentication\\WebAccountManagerAuthenticator.cpp\" />\r\n    <ClCompile Include=\"Debugging.cpp\" />\r\n    <ClCompile Include=\"DependenciesGraph.cpp\" />\r\n    <ClCompile Include=\"DODownloader.cpp\" />\r\n    <ClCompile Include=\"FileCache.cpp\" />\r\n    <ClCompile Include=\"FolderFileWatcher.cpp\" />\r\n    <ClCompile Include=\"Deployment.cpp\" />\r\n    <ClCompile Include=\"Downloader.cpp\" />\r\n    <ClCompile Include=\"ExperimentalFeature.cpp\" />\r\n    <ClCompile Include=\"ExtensionCatalog.cpp\" />\r\n    <ClCompile Include=\"FileLogger.cpp\" />\r\n    <ClCompile Include=\"Fonts.cpp\" />\r\n    <ClCompile Include=\"HttpClientHelper.cpp\">\r\n      <ExcludedFromBuild Condition=\"'$(Configuration)'=='Fuzzing'\">true</ExcludedFromBuild>\r\n    </ClCompile>\r\n    <ClCompile Include=\"HttpStream\\HttpClientWrapper.cpp\" />\r\n    <ClCompile Include=\"HttpStream\\HttpLocalCache.cpp\" />\r\n    <ClCompile Include=\"HttpStream\\HttpRandomAccessStream.cpp\" />\r\n    <ClCompile Include=\"Locale.cpp\" />\r\n    <ClCompile Include=\"Manifest\\Manifest.cpp\" />\r\n    <ClCompile Include=\"Manifest\\ManifestCommon.cpp\" />\r\n    <ClCompile Include=\"Manifest\\ManifestComparator.cpp\" />\r\n    <ClCompile Include=\"Manifest\\ManifestValidation.cpp\" />\r\n    <ClCompile Include=\"Manifest\\ManifestSchemaValidation.cpp\" />\r\n    <ClCompile Include=\"Manifest\\ManifestYamlPopulator.cpp\" />\r\n    <ClCompile Include=\"Manifest\\MsixManifestValidation.cpp\" />\r\n    <ClCompile Include=\"Manifest\\YamlParser.cpp\" />\r\n    <ClCompile Include=\"Manifest\\YamlWriter.cpp\" />\r\n    <ClCompile Include=\"MsiExecArguments.cpp\" />\r\n    <ClCompile Include=\"MsixInfo.cpp\" />\r\n    <ClCompile Include=\"MsixManifest.cpp\" />\r\n    <ClCompile Include=\"MSStore.cpp\" />\r\n    <ClCompile Include=\"MSStoreDownload.cpp\">\r\n      <ExcludedFromBuild Condition=\"'$(Configuration)'=='Fuzzing'\">true</ExcludedFromBuild>\r\n    </ClCompile>\r\n    <ClCompile Include=\"NameNormalization.cpp\" />\r\n    <ClCompile Include=\"NetworkSettings.cpp\" />\r\n    <ClCompile Include=\"OutputDebugStringLogger.cpp\" />\r\n    <ClCompile Include=\"PackageDependenciesValidationUtil.cpp\" />\r\n    <ClCompile Include=\"PackageVersionDataManifest.cpp\" />\r\n    <ClCompile Include=\"Pin.cpp\" />\r\n    <ClCompile Include=\"Progress.cpp\" />\r\n    <ClCompile Include=\"Reboot.cpp\" />\r\n    <ClCompile Include=\"Regex.cpp\" />\r\n    <ClCompile Include=\"Rest.cpp\">\r\n      <ExcludedFromBuild Condition=\"'$(Configuration)'=='Fuzzing'\">true</ExcludedFromBuild>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Runtime.cpp\" />\r\n    <ClCompile Include=\"pch.cpp\">\r\n      <PrecompiledHeader>Create</PrecompiledHeader>\r\n    </ClCompile>\r\n    <ClCompile Include=\"AppInstallerTelemetry.cpp\" />\r\n    <ClCompile Include=\"Archive.cpp\" />\r\n    <ClCompile Include=\"SelfManagement.cpp\" />\r\n    <ClCompile Include=\"Settings.cpp\" />\r\n    <ClCompile Include=\"PathVariable.cpp\" />\r\n    <ClCompile Include=\"PortableARPEntry.cpp\" />\r\n    <ClCompile Include=\"StdErrLogger.cpp\" />\r\n    <ClCompile Include=\"Synchronization.cpp\" />\r\n    <ClCompile Include=\"Telemetry\\TraceLogging.cpp\" />\r\n    <ClCompile Include=\"Architecture.cpp\" />\r\n    <ClCompile Include=\"ThreadGlobals.cpp\" />\r\n    <ClCompile Include=\"TraceLogger.cpp\" />\r\n    <ClCompile Include=\"UserSettings.cpp\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"packages.config\" />\r\n    <None Include=\"PropertySheet.props\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\AppInstallerSharedLib\\AppInstallerSharedLib.vcxproj\">\r\n      <Project>{f3f6e699-bc5d-4950-8a05-e49dd9eb0d51}</Project>\r\n    </ProjectReference>\r\n  </ItemGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\r\n  <ImportGroup Label=\"ExtensionTargets\">\r\n    <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets')\" />\r\n    <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" />\r\n  </ImportGroup>\r\n  <Target Name=\"EnsureNuGetPackageBuildImports\" BeforeTargets=\"PrepareForBuild\">\r\n    <PropertyGroup>\r\n      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>\r\n    </PropertyGroup>\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets'))\" />\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props'))\" />\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets'))\" />\r\n  </Target>\r\n</Project>\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup>\r\n    <Filter Include=\"Source Files\">\r\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Header Files\">\r\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r\n      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Resource Files\">\r\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Public\">\r\n      <UniqueIdentifier>{5cdf3fa3-e657-4d84-81bb-f740aa476143}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"HttpStream\">\r\n      <UniqueIdentifier>{a9c14af9-ca74-4945-a19c-9e99df23a5ae}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Public\\winget\">\r\n      <UniqueIdentifier>{41035fd6-dc74-4464-b9b1-4ffe95d6789c}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Manifest\">\r\n      <UniqueIdentifier>{9b8e2682-3eb7-4530-bc9a-a57fafc44177}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Telemetry\">\r\n      <UniqueIdentifier>{552a58eb-8d07-41b2-87b5-3e71b9fb3cfd}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Authentication\">\r\n      <UniqueIdentifier>{9dd9ab66-00f0-4b18-90ca-6c5da3dc01c4}</UniqueIdentifier>\r\n    </Filter>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"pch.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Telemetry\\TraceLogging.h\">\r\n      <Filter>Telemetry</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\AppInstallerTelemetry.h\">\r\n      <Filter>Public</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\AppInstallerRuntime.h\">\r\n      <Filter>Public</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\AppInstallerDownloader.h\">\r\n      <Filter>Public</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\AppInstallerArchitecture.h\">\r\n      <Filter>Public</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"HttpStream\\HttpClientWrapper.h\">\r\n      <Filter>HttpStream</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"HttpStream\\HttpLocalCache.h\">\r\n      <Filter>HttpStream</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"HttpStream\\HttpRandomAccessStream.h\">\r\n      <Filter>HttpStream</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\AppInstallerMsixInfo.h\">\r\n      <Filter>Public</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\AppInstallerFileLogger.h\">\r\n      <Filter>Public</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\AppInstallerSynchronization.h\">\r\n      <Filter>Public</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\AppInstallerDeployment.h\">\r\n      <Filter>Public</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\AppInstallerProgress.h\">\r\n      <Filter>Public</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\ExtensionCatalog.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\Settings.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\UserSettings.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\ExperimentalFeature.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\ManifestInstaller.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\ManifestLocalization.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\ManifestValidation.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\ManifestYamlParser.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\ManifestYamlWriter.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\NameNormalization.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\Regex.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\ManifestSchemaValidation.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\Manifest.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\ManifestYamlPopulator.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\ManifestCommon.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\Locale.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"DODownloader.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\TraceLogger.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\ThreadGlobals.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\AdminSettings.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\MsiExecArguments.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\DependenciesGraph.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\Debugging.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\PortableARPEntry.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\PortableFileEntry.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\MsixManifest.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\FolderFileWatcher.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\Archive.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\MsixManifestValidation.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\PathVariable.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\PackageDependenciesValidationUtil.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\Pin.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\SelfManagement.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\MSStore.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\Reboot.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Authentication\\WebAccountManagerAuthenticator.h\">\r\n      <Filter>Authentication</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\Authentication.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\NetworkSettings.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\PackageVersionDataManifest.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\HttpClientHelper.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\Rest.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\MSStoreDownload.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\FileCache.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\Fonts.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\OutputDebugStringLogger.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\ManifestComparator.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\StdErrLogger.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"pch.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Telemetry\\TraceLogging.cpp\">\r\n      <Filter>Telemetry</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"AppInstallerTelemetry.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"FileLogger.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Runtime.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Downloader.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Architecture.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"HttpStream\\HttpClientWrapper.cpp\">\r\n      <Filter>HttpStream</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"HttpStream\\HttpLocalCache.cpp\">\r\n      <Filter>HttpStream</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"HttpStream\\HttpRandomAccessStream.cpp\">\r\n      <Filter>HttpStream</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"MsixInfo.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Synchronization.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Deployment.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ExtensionCatalog.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Settings.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"UserSettings.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ExperimentalFeature.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Manifest\\ManifestValidation.cpp\">\r\n      <Filter>Manifest</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Manifest\\YamlParser.cpp\">\r\n      <Filter>Manifest</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Manifest\\YamlWriter.cpp\">\r\n      <Filter>Manifest</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"NameNormalization.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Regex.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Manifest\\ManifestSchemaValidation.cpp\">\r\n      <Filter>Manifest</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Manifest\\ManifestCommon.cpp\">\r\n      <Filter>Manifest</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Manifest\\ManifestYamlPopulator.cpp\">\r\n      <Filter>Manifest</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Manifest\\Manifest.cpp\">\r\n      <Filter>Manifest</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Locale.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"DODownloader.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"TraceLogger.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ThreadGlobals.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"MsiExecArguments.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"AdminSettings.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"DependenciesGraph.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Debugging.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PortableARPEntry.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"MsixManifest.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"FolderFileWatcher.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Archive.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Manifest\\MsixManifestValidation.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PathVariable.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PackageDependenciesValidationUtil.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Progress.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Pin.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"SelfManagement.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"MSStore.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Reboot.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Authentication\\Authentication.cpp\">\r\n      <Filter>Authentication</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Authentication\\WebAccountManagerAuthenticator.cpp\">\r\n      <Filter>Authentication</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"NetworkSettings.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PackageVersionDataManifest.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"HttpClientHelper.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"MSStoreDownload.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"FileCache.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Fonts.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"OutputDebugStringLogger.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Manifest\\ManifestComparator.cpp\">\r\n      <Filter>Manifest</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"StdErrLogger.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"PropertySheet.props\" />\r\n    <None Include=\"packages.config\" />\r\n  </ItemGroup>\r\n</Project>"
  },
  {
    "path": "src/AppInstallerCommonCore/AppInstallerTelemetry.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/AppInstallerTelemetry.h\"\r\n#include \"Public/AppInstallerLogging.h\"\r\n#include \"Public/AppInstallerRuntime.h\"\r\n#include \"Public/AppInstallerSHA256.h\"\r\n#include \"Public/AppInstallerStrings.h\"\r\n#include \"Public/winget/ThreadGlobals.h\"\r\n#include \"winget/Filesystem.h\"\r\n#include \"winget/UserSettings.h\"\r\n\r\n#define AICLI_TraceLoggingStringView(_sv_,_name_) TraceLoggingCountedUtf8String(_sv_.data(), static_cast<ULONG>(_sv_.size()), _name_)\r\n#define AICLI_TraceLoggingWStringView(_sv_,_name_) TraceLoggingCountedWideString(_sv_.data(), static_cast<ULONG>(_sv_.size()), _name_)\r\n\r\n#define AICLI_TraceLoggingWriteActivity(_eventName_,...) TraceLoggingWriteActivity(\\\r\ng_hTraceProvider,\\\r\n_eventName_,\\\r\ns_useGlobalTelemetryActivityId ? &s_globalTelemetryLoggerActivityId : GetActivityId(),\\\r\ns_useGlobalTelemetryActivityId ? nullptr : GetParentActivityId(),\\\r\nTraceLoggingCountedUtf8String(m_caller.c_str(),  static_cast<ULONG>(m_caller.size()), \"Caller\"),\\\r\nTraceLoggingPackedFieldEx(m_telemetryCorrelationJsonW.c_str(), static_cast<ULONG>((m_telemetryCorrelationJsonW.size() + 1) * sizeof(wchar_t)), TlgInUNICODESTRING, TlgOutJSON, \"CvJson\"),\\\r\n__VA_ARGS__)\r\n\r\nnamespace AppInstaller::Logging\r\n{\r\n    using namespace Utility;\r\n\r\n    namespace\r\n    {\r\n        // TODO: This and all usages should be removed after transition to summary event in back end.\r\n        static const uint32_t s_RootExecutionId = 0;\r\n        static std::atomic_uint32_t s_subExecutionId{ s_RootExecutionId };\r\n\r\n        // Data that is needed by AnonymizeString\r\n        constexpr std::wstring_view s_UserProfileReplacement = L\"%USERPROFILE%\"sv;\r\n\r\n        // TODO: Temporary code to keep existing telemetry behavior\r\n        static bool s_useGlobalTelemetryActivityId = false;\r\n        static GUID s_globalTelemetryLoggerActivityId = GUID_NULL;\r\n\r\n        void __stdcall wilResultLoggingCallback(const wil::FailureInfo& info) noexcept\r\n        {\r\n            Telemetry().LogFailure(info);\r\n        }\r\n\r\n        FailureTypeEnum ConvertWilFailureTypeToFailureType(wil::FailureType failureType)\r\n        {\r\n            switch (failureType)\r\n            {\r\n            case wil::FailureType::Exception:\r\n                return FailureTypeEnum::ResultException;\r\n            case wil::FailureType::Return:\r\n                return FailureTypeEnum::ResultReturn;\r\n            case wil::FailureType::Log:\r\n                return FailureTypeEnum::ResultLog;\r\n            case wil::FailureType::FailFast:\r\n                return FailureTypeEnum::ResultFailFast;\r\n            default:\r\n                return FailureTypeEnum::Unknown;\r\n            }\r\n        }\r\n\r\n        std::string_view LogExceptionTypeToString(FailureTypeEnum exceptionType)\r\n        {\r\n            switch (exceptionType)\r\n            {\r\n            case FailureTypeEnum::ResultException:\r\n                return \"wil::ResultException\"sv;\r\n            case FailureTypeEnum::WinrtHResultError:\r\n                return \"winrt::hresult_error\"sv;\r\n            case FailureTypeEnum::ResourceOpen:\r\n                return \"ResourceOpenException\"sv;\r\n            case FailureTypeEnum::StdException:\r\n                return \"std::exception\"sv;\r\n            case FailureTypeEnum::Unknown:\r\n            default:\r\n                return \"unknown\"sv;\r\n            }\r\n        }\r\n    }\r\n\r\n    TelemetrySummary::TelemetrySummary(const TelemetrySummary& other)\r\n    {\r\n        this->IsCOMCall = other.IsCOMCall;\r\n    }\r\n\r\n    TelemetryTraceLogger::TelemetryTraceLogger(bool useSummary) : m_useSummary(useSummary)\r\n    {\r\n        std::ignore = CoCreateGuid(&m_activityId);\r\n        m_subExecutionId = s_RootExecutionId;\r\n    }\r\n\r\n    const GUID* TelemetryTraceLogger::GetActivityId() const\r\n    {\r\n        return &m_activityId;\r\n    }\r\n\r\n    const GUID* TelemetryTraceLogger::GetParentActivityId() const\r\n    {\r\n        return &m_parentActivityId;\r\n    }\r\n\r\n    bool TelemetryTraceLogger::DisableRuntime()\r\n    {\r\n        return m_isRuntimeEnabled.exchange(false);\r\n    }\r\n\r\n    void TelemetryTraceLogger::EnableRuntime()\r\n    {\r\n        m_isRuntimeEnabled = true;\r\n    }\r\n\r\n    void TelemetryTraceLogger::Initialize()\r\n    {\r\n        if (!m_isInitialized)\r\n        {\r\n            InitializeInternal(Settings::User());\r\n        }\r\n    }\r\n\r\n    bool TelemetryTraceLogger::TryInitialize()\r\n    {\r\n        if (!m_isInitialized)\r\n        {\r\n            // Only initialize if we already have the user settings, so that we can respect the telemetry setting.\r\n            // We may not yet have the user settings if we are trying to report an error while reading them.\r\n            auto userSettings = Settings::TryGetUser();\r\n            if (userSettings)\r\n            {\r\n                InitializeInternal(*userSettings);\r\n            }\r\n        }\r\n\r\n        return m_isInitialized;\r\n    }\r\n\r\n    void TelemetryTraceLogger::SetTelemetryCorrelationJson(const std::wstring_view jsonStr_view) noexcept\r\n    {\r\n        // Check if passed in string is a valid Json formatted before returning the value\r\n        // If invalid, return empty Json\r\n        Json::CharReaderBuilder jsonBuilder;\r\n        std::unique_ptr<Json::CharReader> jsonReader(jsonBuilder.newCharReader());\r\n        std::unique_ptr<Json::Value> pJsonValue = std::make_unique<Json::Value>();\r\n        std::string errors;\r\n        std::wstring jsonStrW{ jsonStr_view };\r\n        std::string jsonStr = ConvertToUTF8(jsonStrW.c_str());\r\n\r\n        bool result = jsonReader->parse(jsonStr.c_str(),\r\n            jsonStr.c_str() + jsonStr.size(),\r\n            pJsonValue.get(),\r\n            &errors);\r\n\r\n        if (result)\r\n        {\r\n            m_telemetryCorrelationJsonW = jsonStrW;\r\n            AICLI_LOG(Core, Info, << \"Passed in Correlation Vector Json is valid: \" << jsonStr);\r\n        }\r\n        else\r\n        {\r\n            AICLI_LOG(Core, Error, << \"Passed in Correlation Vector Json is invalid: \" << jsonStr << \"; Error: \" << errors);\r\n        }\r\n    }\r\n\r\n    void TelemetryTraceLogger::SetCaller(const std::string& caller)\r\n    {\r\n        auto callerUTF16 = Utility::ConvertToUTF16(caller);\r\n        auto anonCaller = AnonymizeString(callerUTF16);\r\n        m_caller = Utility::ConvertToUTF8(anonCaller);\r\n    }\r\n\r\n    void TelemetryTraceLogger::SetExecutionStage(uint32_t stage) noexcept\r\n    {\r\n        m_executionStage = stage;\r\n    }\r\n\r\n    std::unique_ptr<TelemetryTraceLogger> TelemetryTraceLogger::CreateSubTraceLogger() const\r\n    {\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !this->m_isInitialized);\r\n\r\n        auto subTraceLogger = std::make_unique<TelemetryTraceLogger>(*this);\r\n\r\n        std::ignore = CoCreateGuid(&subTraceLogger->m_activityId);\r\n        subTraceLogger->m_parentActivityId = this->m_activityId;\r\n        subTraceLogger->m_subExecutionId = s_subExecutionId++;\r\n\r\n        return subTraceLogger;\r\n    }\r\n\r\n    void TelemetryTraceLogger::LogFailure(const wil::FailureInfo& failure) const noexcept\r\n    {\r\n        if (IsTelemetryEnabled())\r\n        {\r\n            auto anonMessage = AnonymizeString(failure.pszMessage);\r\n\r\n            AICLI_TraceLoggingWriteActivity(\r\n                \"FailureInfo\",\r\n                TraceLoggingUInt32(m_subExecutionId, \"SubExecutionId\"),\r\n                TraceLoggingHResult(failure.hr, \"HResult\"),\r\n                AICLI_TraceLoggingWStringView(anonMessage, \"Message\"),\r\n                TraceLoggingString(failure.pszModule, \"Module\"),\r\n                TraceLoggingUInt32(failure.threadId, \"ThreadId\"),\r\n                TraceLoggingUInt32(static_cast<uint32_t>(failure.type), \"Type\"),\r\n                TraceLoggingString(failure.pszFile, \"File\"),\r\n                TraceLoggingUInt32(failure.uLineNumber, \"Line\"),\r\n                TraceLoggingUInt32(m_executionStage, \"ExecutionStage\"),\r\n                TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance),\r\n                TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));\r\n\r\n            if (m_useSummary)\r\n            {\r\n                m_summary.FailureHResult = failure.hr;\r\n                m_summary.FailureMessage = anonMessage;\r\n                m_summary.FailureModule = StringOrEmptyIfNull(failure.pszModule);\r\n                m_summary.FailureThreadId = failure.threadId;\r\n                m_summary.FailureType = ConvertWilFailureTypeToFailureType(failure.type);\r\n                m_summary.FailureFile = StringOrEmptyIfNull(failure.pszFile);\r\n                m_summary.FailureLine = failure.uLineNumber;\r\n            }\r\n        }\r\n\r\n        // Also send failure to the log\r\n        AICLI_LOG(Fail, Error, << [&]() {\r\n            wchar_t message[2048];\r\n            GetFailureLogString(message, ARRAYSIZE(message), failure);\r\n            return Utility::ConvertToUTF8(message);\r\n            }());\r\n    }\r\n\r\n    void TelemetryTraceLogger::LogStartup(bool isCOMCall) const noexcept\r\n    {\r\n        LocIndString version = Runtime::GetClientVersion();\r\n        LocIndString packageVersion;\r\n        if (Runtime::IsRunningInPackagedContext())\r\n        {\r\n            packageVersion = Runtime::GetPackageVersion();\r\n        }\r\n\r\n        if (IsTelemetryEnabled())\r\n        {\r\n            AICLI_TraceLoggingWriteActivity(\r\n                \"ClientVersion\",\r\n                TraceLoggingBool(isCOMCall, \"IsCOMCall\"),\r\n                TraceLoggingCountedString(version->c_str(), static_cast<ULONG>(version->size()), \"Version\"),\r\n                TraceLoggingCountedString(packageVersion->c_str(), static_cast<ULONG>(packageVersion->size()), \"PackageVersion\"),\r\n                TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance),\r\n                TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));\r\n\r\n            if (m_useSummary)\r\n            {\r\n                m_summary.IsCOMCall = isCOMCall;\r\n            }\r\n        }\r\n\r\n        AICLI_LOG(Core, Info, << \"WinGet, version [\" << version << \"], activity [\" << *GetActivityId() << ']');\r\n        AICLI_LOG(Core, Info, << \"Process: \" << Filesystem::GetExecutablePathForProcess(GetCurrentProcess()).filename() << \"[\" << GetCurrentProcessId() << \"], Offset: \" << &__ImageBase);\r\n        AICLI_LOG(Core, Info, << \"OS: \" << Runtime::GetOSVersion());\r\n        AICLI_LOG(Core, Info, << \"Command line Args: \" << Utility::ConvertToUTF8(GetCommandLineW()));\r\n        if (Runtime::IsRunningInPackagedContext())\r\n        {\r\n            AICLI_LOG(Core, Info, << \"Package: \" << packageVersion);\r\n        }\r\n        AICLI_LOG(Core, Info, << \"IsCOMCall:\" << isCOMCall << \"; Caller: \" << m_caller);\r\n\r\n        Log().SetTag(Tag::HeadersComplete);\r\n    }\r\n\r\n    void TelemetryTraceLogger::LogCommand(std::string_view commandName) const noexcept\r\n    {\r\n        if (IsTelemetryEnabled())\r\n        {\r\n            AICLI_TraceLoggingWriteActivity(\r\n                \"CommandFound\",\r\n                AICLI_TraceLoggingStringView(commandName, \"Command\"),\r\n                TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance | PDT_ProductAndServiceUsage),\r\n                TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));\r\n\r\n            if (m_useSummary)\r\n            {\r\n                m_summary.Command = commandName;\r\n            }\r\n        }\r\n\r\n        AICLI_LOG(CLI, Info, << \"Leaf command to execute: \" << commandName);\r\n    }\r\n\r\n    void TelemetryTraceLogger::LogCommandSuccess(std::string_view commandName) const noexcept\r\n    {\r\n        if (IsTelemetryEnabled())\r\n        {\r\n            AICLI_TraceLoggingWriteActivity(\r\n                \"CommandSuccess\",\r\n                AICLI_TraceLoggingStringView(commandName, \"Command\"),\r\n                TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance),\r\n                TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));\r\n\r\n            if (m_useSummary)\r\n            {\r\n                m_summary.CommandSuccess = true;\r\n            }\r\n        }\r\n\r\n        AICLI_LOG(CLI, Info, << \"Leaf command succeeded: \" << commandName);\r\n    }\r\n\r\n    void TelemetryTraceLogger::LogCommandTermination(HRESULT hr, std::string_view file, size_t line) const noexcept\r\n    {\r\n        if (IsTelemetryEnabled())\r\n        {\r\n            AICLI_TraceLoggingWriteActivity(\r\n                \"CommandTermination\",\r\n                TraceLoggingUInt32(m_subExecutionId, \"SubExecutionId\"),\r\n                TraceLoggingHResult(hr, \"HResult\"),\r\n                AICLI_TraceLoggingStringView(file, \"File\"),\r\n                TraceLoggingUInt64(static_cast<UINT64>(line), \"Line\"),\r\n                TraceLoggingUInt32(m_executionStage, \"ExecutionStage\"),\r\n                TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance),\r\n                TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));\r\n\r\n            if (m_useSummary)\r\n            {\r\n                m_summary.FailureHResult = hr;\r\n                m_summary.FailureType = FailureTypeEnum::CommandTermination;\r\n                m_summary.FailureFile = file;\r\n                m_summary.FailureLine = static_cast<UINT32>(line);\r\n            }\r\n        }\r\n\r\n        AICLI_LOG(CLI, Error, << \"Terminating context: 0x\" << SetHRFormat << hr << \" at \" << file << \":\" << line);\r\n    }\r\n\r\n    void TelemetryTraceLogger::LogException(FailureTypeEnum type, std::string_view message) const noexcept\r\n    {\r\n        auto exceptionTypeString = LogExceptionTypeToString(type);\r\n\r\n        if (IsTelemetryEnabled())\r\n        {\r\n            auto anonMessage = AnonymizeString(Utility::ConvertToUTF16(message));\r\n\r\n            AICLI_TraceLoggingWriteActivity(\r\n                \"Exception\",\r\n                TraceLoggingUInt32(m_subExecutionId, \"SubExecutionId\"),\r\n                AICLI_TraceLoggingStringView(exceptionTypeString, \"Type\"),\r\n                AICLI_TraceLoggingWStringView(anonMessage, \"Message\"),\r\n                TraceLoggingUInt32(m_executionStage, \"ExecutionStage\"),\r\n                TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance),\r\n                TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));\r\n\r\n            if (m_useSummary)\r\n            {\r\n                m_summary.FailureType = type;\r\n                m_summary.FailureMessage = anonMessage;\r\n            }\r\n        }\r\n\r\n        AICLI_LOG(CLI, Error, << \"Caught \" << exceptionTypeString << \": \" << message);\r\n    }\r\n\r\n    void TelemetryTraceLogger::LogIsManifestLocal(bool isLocalManifest) const noexcept\r\n    {\r\n        if (IsTelemetryEnabled())\r\n        {\r\n            AICLI_TraceLoggingWriteActivity(\r\n                \"GetManifest\",\r\n                TraceLoggingUInt32(m_subExecutionId, \"SubExecutionId\"),\r\n                TraceLoggingBool(isLocalManifest, \"IsManifestLocal\"),\r\n                TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance),\r\n                TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));\r\n\r\n            if (m_useSummary)\r\n            {\r\n                m_summary.IsManifestLocal = isLocalManifest;\r\n            }\r\n        }\r\n    }\r\n\r\n    void TelemetryTraceLogger::LogManifestFields(std::string_view id, std::string_view name, std::string_view version) const noexcept\r\n    {\r\n        if (IsTelemetryEnabled())\r\n        {\r\n            AICLI_TraceLoggingWriteActivity(\r\n                \"ManifestFields\",\r\n                TraceLoggingUInt32(m_subExecutionId, \"SubExecutionId\"),\r\n                AICLI_TraceLoggingStringView(id, \"Id\"),\r\n                AICLI_TraceLoggingStringView(name, \"Name\"),\r\n                AICLI_TraceLoggingStringView(version, \"Version\"),\r\n                TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance),\r\n                TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));\r\n\r\n            if (m_useSummary)\r\n            {\r\n                m_summary.PackageIdentifier = id;\r\n                m_summary.PackageName = name;\r\n                m_summary.PackageVersion = version;\r\n            }\r\n        }\r\n\r\n        AICLI_LOG(CLI, Info, << \"Manifest fields: Name [\" << name << \"], Version [\" << version << ']');\r\n    }\r\n\r\n    void TelemetryTraceLogger::LogNoAppMatch() const noexcept\r\n    {\r\n        if (IsTelemetryEnabled())\r\n        {\r\n            AICLI_TraceLoggingWriteActivity(\r\n                \"NoAppMatch\",\r\n                TraceLoggingUInt32(m_subExecutionId, \"SubExecutionId\"),\r\n                TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance),\r\n                TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));\r\n        }\r\n\r\n        AICLI_LOG(CLI, Info, << \"No app found matching input criteria\");\r\n    }\r\n\r\n    void TelemetryTraceLogger::LogMultiAppMatch() const noexcept\r\n    {\r\n        if (IsTelemetryEnabled())\r\n        {\r\n            AICLI_TraceLoggingWriteActivity(\r\n                \"MultiAppMatch\",\r\n                TraceLoggingUInt32(m_subExecutionId, \"SubExecutionId\"),\r\n                TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance),\r\n                TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));\r\n        }\r\n\r\n        AICLI_LOG(CLI, Info, << \"Multiple apps found matching input criteria\");\r\n    }\r\n\r\n    void TelemetryTraceLogger::LogAppFound(std::string_view name, std::string_view id) const noexcept\r\n    {\r\n        if (IsTelemetryEnabled())\r\n        {\r\n            AICLI_TraceLoggingWriteActivity(\r\n                \"AppFound\",\r\n                TraceLoggingUInt32(m_subExecutionId, \"SubExecutionId\"),\r\n                AICLI_TraceLoggingStringView(name, \"Name\"),\r\n                AICLI_TraceLoggingStringView(id, \"Id\"),\r\n                TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance),\r\n                TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));\r\n\r\n            if (m_useSummary)\r\n            {\r\n                m_summary.PackageIdentifier = id;\r\n                m_summary.PackageName = name;\r\n            }\r\n        }\r\n\r\n        AICLI_LOG(CLI, Info, << \"Found one app. App id: \" << id << \" App name: \" << name);\r\n    }\r\n\r\n    void TelemetryTraceLogger::LogSelectedInstaller(int arch, std::string_view url, std::string_view installerType, std::string_view scope, std::string_view language) const noexcept\r\n    {\r\n        if (IsTelemetryEnabled())\r\n        {\r\n            AICLI_TraceLoggingWriteActivity(\r\n                \"SelectedInstaller\",\r\n                TraceLoggingUInt32(m_subExecutionId, \"SubExecutionId\"),\r\n                TraceLoggingInt32(arch, \"Arch\"),\r\n                AICLI_TraceLoggingStringView(url, \"Url\"),\r\n                AICLI_TraceLoggingStringView(installerType, \"InstallerType\"),\r\n                AICLI_TraceLoggingStringView(scope, \"Scope\"),\r\n                AICLI_TraceLoggingStringView(language, \"Language\"),\r\n                TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance),\r\n                TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));\r\n\r\n            if (m_useSummary)\r\n            {\r\n                m_summary.InstallerArchitecture = arch;\r\n                m_summary.InstallerUrl = url;\r\n                m_summary.InstallerType = installerType;\r\n                m_summary.InstallerScope = scope;\r\n                m_summary.InstallerLocale = language;\r\n            }\r\n        }\r\n\r\n        AICLI_LOG(CLI, Verbose, << \"Completed installer selection.\");\r\n        AICLI_LOG(CLI, Verbose, << \"Selected installer Architecture: \" << arch);\r\n        AICLI_LOG(CLI, Verbose, << \"Selected installer URL: \" << url);\r\n        AICLI_LOG(CLI, Verbose, << \"Selected installer InstallerType: \" << installerType);\r\n        AICLI_LOG(CLI, Verbose, << \"Selected installer Scope: \" << scope);\r\n        AICLI_LOG(CLI, Verbose, << \"Selected installer Language: \" << language);\r\n    }\r\n\r\n    void TelemetryTraceLogger::LogSearchRequest(\r\n        std::string_view type,\r\n        std::string_view query,\r\n        std::string_view id,\r\n        std::string_view name,\r\n        std::string_view moniker,\r\n        std::string_view tag,\r\n        std::string_view command,\r\n        size_t maximum,\r\n        std::string_view request) const noexcept\r\n    {\r\n        if (IsTelemetryEnabled())\r\n        {\r\n            AICLI_TraceLoggingWriteActivity(\r\n                \"SearchRequest\",\r\n                TraceLoggingUInt32(m_subExecutionId, \"SubExecutionId\"),\r\n                AICLI_TraceLoggingStringView(type, \"Type\"),\r\n                AICLI_TraceLoggingStringView(query, \"Query\"),\r\n                AICLI_TraceLoggingStringView(id, \"Id\"),\r\n                AICLI_TraceLoggingStringView(name, \"Name\"),\r\n                AICLI_TraceLoggingStringView(moniker, \"Moniker\"),\r\n                AICLI_TraceLoggingStringView(tag, \"Tag\"),\r\n                AICLI_TraceLoggingStringView(command, \"Command\"),\r\n                TraceLoggingUInt64(static_cast<UINT64>(maximum), \"Maximum\"),\r\n                AICLI_TraceLoggingStringView(request, \"Request\"),\r\n                TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance),\r\n                TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));\r\n\r\n            if (m_useSummary)\r\n            {\r\n                m_summary.SearchType = type;\r\n                m_summary.SearchQuery = query;\r\n                m_summary.SearchId = id;\r\n                m_summary.SearchName = name;\r\n                m_summary.SearchMoniker = moniker;\r\n                m_summary.SearchTag = tag;\r\n                m_summary.SearchCommand = command;\r\n                m_summary.SearchMaximum = static_cast<UINT64>(maximum);\r\n                m_summary.SearchRequest = request;\r\n            }\r\n        }\r\n    }\r\n\r\n    void TelemetryTraceLogger::LogSearchResultCount(uint64_t resultCount) const noexcept\r\n    {\r\n        if (IsTelemetryEnabled())\r\n        {\r\n            AICLI_TraceLoggingWriteActivity(\r\n                \"SearchResultCount\",\r\n                TraceLoggingUInt32(m_subExecutionId, \"SubExecutionId\"),\r\n                TraceLoggingUInt64(resultCount, \"ResultCount\"),\r\n                TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance),\r\n                TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));\r\n\r\n            if (m_useSummary)\r\n            {\r\n                m_summary.SearchResultCount = resultCount;\r\n            }\r\n        }\r\n\r\n        AICLI_LOG(CLI, Verbose, << \"Search result size: \" << resultCount);\r\n    }\r\n\r\n    void TelemetryTraceLogger::LogInstallerHashMismatch(\r\n        std::string_view id,\r\n        std::string_view version,\r\n        std::string_view channel,\r\n        const std::vector<uint8_t>& expected,\r\n        const std::vector<uint8_t>& actual,\r\n        bool overrideHashMismatch,\r\n        uint64_t downloadSizeInBytes,\r\n        const std::optional<std::string>& contentType) const noexcept\r\n    {\r\n        std::string actualContentType = contentType.value_or(std::string{});\r\n\r\n        if (IsTelemetryEnabled())\r\n        {\r\n            AICLI_TraceLoggingWriteActivity(\r\n                \"HashMismatch\",\r\n                TraceLoggingUInt32(m_subExecutionId, \"SubExecutionId\"),\r\n                AICLI_TraceLoggingStringView(id, \"Id\"),\r\n                AICLI_TraceLoggingStringView(version, \"Version\"),\r\n                AICLI_TraceLoggingStringView(channel, \"Channel\"),\r\n                TraceLoggingBinary(expected.data(), static_cast<ULONG>(expected.size()), \"Expected\"),\r\n                TraceLoggingBinary(actual.data(), static_cast<ULONG>(actual.size()), \"Actual\"),\r\n                TraceLoggingBool(overrideHashMismatch, \"Override\"),\r\n                TraceLoggingUInt64(downloadSizeInBytes, \"ActualSize\"),\r\n                AICLI_TraceLoggingStringView(actualContentType, \"ContentType\"),\r\n                TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance),\r\n                TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));\r\n\r\n            if (m_useSummary)\r\n            {\r\n                m_summary.PackageIdentifier = id;\r\n                m_summary.PackageVersion = version;\r\n                m_summary.Channel = channel;\r\n                m_summary.HashMismatchExpected = expected;\r\n                m_summary.HashMismatchActual = actual;\r\n                m_summary.HashMismatchOverride = overrideHashMismatch;\r\n                m_summary.HashMismatchActualSize = downloadSizeInBytes;\r\n                m_summary.HashMismatchContentType = actualContentType;\r\n            }\r\n        }\r\n\r\n        AICLI_LOG(CLI, Error,\r\n            << \"Package hash verification failed. SHA256 in manifest [\"\r\n            << Utility::SHA256::ConvertToString(expected)\r\n            << \"] does not match download [\"\r\n            << Utility::SHA256::ConvertToString(actual)\r\n            << \"] with file size [\" << downloadSizeInBytes << \"] and content type [\" << actualContentType << \"]\");\r\n    }\r\n\r\n    void TelemetryTraceLogger::LogInstallerFailure(std::string_view id, std::string_view version, std::string_view channel, std::string_view type, uint32_t errorCode) const noexcept\r\n    {\r\n        if (IsTelemetryEnabled())\r\n        {\r\n            AICLI_TraceLoggingWriteActivity(\r\n                \"InstallerFailure\",\r\n                TraceLoggingUInt32(m_subExecutionId, \"SubExecutionId\"),\r\n                AICLI_TraceLoggingStringView(id, \"Id\"),\r\n                AICLI_TraceLoggingStringView(version, \"Version\"),\r\n                AICLI_TraceLoggingStringView(channel, \"Channel\"),\r\n                AICLI_TraceLoggingStringView(type, \"Type\"),\r\n                TraceLoggingUInt32(errorCode, \"ErrorCode\"),\r\n                TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance),\r\n                TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));\r\n\r\n            if (m_useSummary)\r\n            {\r\n                m_summary.PackageIdentifier = id;\r\n                m_summary.PackageVersion = version;\r\n                m_summary.Channel = channel;\r\n                m_summary.InstallerExecutionType = type;\r\n                m_summary.InstallerErrorCode = errorCode;\r\n            }\r\n        }\r\n\r\n        AICLI_LOG(CLI, Error, << type << \" installer failed: \" << errorCode);\r\n    }\r\n\r\n    void TelemetryTraceLogger::LogUninstallerFailure(std::string_view id, std::string_view version, std::string_view type, uint32_t errorCode) const noexcept\r\n    {\r\n        if (IsTelemetryEnabled())\r\n        {\r\n            AICLI_TraceLoggingWriteActivity(\r\n                \"UninstallerFailure\",\r\n                TraceLoggingUInt32(m_subExecutionId, \"SubExecutionId\"),\r\n                AICLI_TraceLoggingStringView(id, \"Id\"),\r\n                AICLI_TraceLoggingStringView(version, \"Version\"),\r\n                AICLI_TraceLoggingStringView(type, \"Type\"),\r\n                TraceLoggingUInt32(errorCode, \"ErrorCode\"),\r\n                TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance),\r\n                TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));\r\n\r\n            if (m_useSummary)\r\n            {\r\n                m_summary.PackageIdentifier = id;\r\n                m_summary.PackageVersion = version;\r\n                m_summary.UninstallerExecutionType = type;\r\n                m_summary.UninstallerErrorCode = errorCode;\r\n            }\r\n        }\r\n\r\n        AICLI_LOG(CLI, Error, << type << \" uninstaller failed: \" << errorCode);\r\n    }\r\n\r\n    void TelemetryTraceLogger::LogSuccessfulInstallARPChange(\r\n        std::string_view sourceIdentifier,\r\n        std::string_view packageIdentifier,\r\n        std::string_view packageVersion,\r\n        std::string_view packageChannel,\r\n        size_t changesToARP,\r\n        size_t matchesInARP,\r\n        size_t countOfIntersectionOfChangesAndMatches,\r\n        std::string_view arpName,\r\n        std::string_view arpVersion,\r\n        std::string_view arpPublisher,\r\n        std::string_view arpLanguage) const noexcept\r\n    {\r\n        if (IsTelemetryEnabled())\r\n        {\r\n            size_t languageNumber = 0xFFFF;\r\n\r\n            try\r\n            {\r\n                std::istringstream languageConversion{ std::string{ arpLanguage } };\r\n                languageConversion >> languageNumber;\r\n            }\r\n            catch (...) {}\r\n\r\n            AICLI_TraceLoggingWriteActivity(\r\n                \"InstallARPChange\",\r\n                TraceLoggingUInt32(m_subExecutionId, \"SubExecutionId\"),\r\n                AICLI_TraceLoggingStringView(sourceIdentifier, \"SourceIdentifier\"),\r\n                AICLI_TraceLoggingStringView(packageIdentifier, \"PackageIdentifier\"),\r\n                AICLI_TraceLoggingStringView(packageVersion, \"PackageVersion\"),\r\n                AICLI_TraceLoggingStringView(packageChannel, \"PackageChannel\"),\r\n                TraceLoggingUInt64(static_cast<UINT64>(changesToARP), \"ChangesToARP\"),\r\n                TraceLoggingUInt64(static_cast<UINT64>(matchesInARP), \"MatchesInARP\"),\r\n                TraceLoggingUInt64(static_cast<UINT64>(countOfIntersectionOfChangesAndMatches), \"ChangesThatMatch\"),\r\n                AICLI_TraceLoggingStringView(arpName, \"ARPName\"),\r\n                AICLI_TraceLoggingStringView(arpVersion, \"ARPVersion\"),\r\n                AICLI_TraceLoggingStringView(arpPublisher, \"ARPPublisher\"),\r\n                TraceLoggingUInt64(static_cast<UINT64>(languageNumber), \"ARPLanguage\"),\r\n                TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance | PDT_ProductAndServiceUsage | PDT_SoftwareSetupAndInventory),\r\n                TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));\r\n\r\n            if (m_useSummary)\r\n            {\r\n                m_summary.SourceIdentifier = sourceIdentifier;\r\n                m_summary.PackageIdentifier = packageIdentifier;\r\n                m_summary.PackageVersion = packageVersion;\r\n                m_summary.Channel = packageChannel;\r\n                m_summary.ChangesToARP = static_cast<UINT64>(changesToARP);\r\n                m_summary.MatchesInARP = static_cast<UINT64>(matchesInARP);\r\n                m_summary.ChangesThatMatch = static_cast<UINT64>(countOfIntersectionOfChangesAndMatches);\r\n                m_summary.ARPName = arpName;\r\n                m_summary.ARPVersion = arpVersion;\r\n                m_summary.ARPPublisher = arpPublisher;\r\n                m_summary.ARPLanguage = static_cast<UINT64>(languageNumber);\r\n            }\r\n        }\r\n\r\n        AICLI_LOG(CLI, Info, << \"During package install, \" << changesToARP << \" changes to ARP were observed, \"\r\n            << matchesInARP << \" matches were found for the package, and \" << countOfIntersectionOfChangesAndMatches << \" packages were in both\");\r\n\r\n        if (arpName.empty())\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"No single entry was determined to be associated with the package\");\r\n        }\r\n        else\r\n        {\r\n            AICLI_LOG(CLI, Info, << \"The entry determined to be associated with the package is '\" << arpName << \"', with publisher '\" << arpPublisher << \"'\");\r\n        }\r\n    }\r\n\r\n    void TelemetryTraceLogger::LogNonFatalDOError(std::string_view url, HRESULT hr) const noexcept\r\n    {\r\n        if (IsTelemetryEnabled())\r\n        {\r\n            AICLI_TraceLoggingWriteActivity(\r\n                \"NonFatalDOError\",\r\n                TraceLoggingUInt32(m_subExecutionId, \"SubExecutionId\"),\r\n                AICLI_TraceLoggingStringView(url, \"Url\"),\r\n                TraceLoggingHResult(hr, \"HResult\"),\r\n                TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance),\r\n                TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES));\r\n\r\n            if (m_useSummary)\r\n            {\r\n                m_summary.DOUrl = url;\r\n                m_summary.DOHResult = hr;\r\n            }\r\n        }\r\n    }\r\n\r\n    void TelemetryTraceLogger::LogRepairFailure(std::string_view id, std::string_view version, std::string_view type, uint32_t errorCode) const noexcept\r\n    {\r\n        if (IsTelemetryEnabled())\r\n        {\r\n            AICLI_TraceLoggingWriteActivity(\r\n                \"RepairFailure\",\r\n                TraceLoggingUInt32(m_subExecutionId, \"SubExecutionId\"),\r\n                AICLI_TraceLoggingStringView(id, \"Id\"),\r\n                AICLI_TraceLoggingStringView(version, \"Version\"),\r\n                AICLI_TraceLoggingStringView(type, \"Type\"),\r\n                TraceLoggingUInt32(errorCode, \"ErrorCode\"),\r\n                TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance),\r\n                TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES));\r\n\r\n            if (m_useSummary)\r\n            {\r\n                m_summary.PackageIdentifier = id;\r\n                m_summary.PackageVersion = version;\r\n                m_summary.RepairExecutionType = type;\r\n                m_summary.RepairErrorCode = errorCode;\r\n            \r\n            }\r\n        }\r\n\r\n        AICLI_LOG(CLI, Error, << type << \" repair failed: \" << errorCode);\r\n    }\r\n\r\n    TelemetryTraceLogger::~TelemetryTraceLogger()\r\n    {\r\n        if (IsTelemetryEnabled())\r\n        {\r\n            LocIndString version = Runtime::GetClientVersion();\r\n            LocIndString packageVersion;\r\n            if (Runtime::IsRunningInPackagedContext())\r\n            {\r\n                packageVersion = Runtime::GetPackageVersion();\r\n            }\r\n\r\n            if (m_useSummary)\r\n            {\r\n                TraceLoggingWriteActivity(\r\n                    g_hTraceProvider,\r\n                    \"SummaryV2\",\r\n                    GetActivityId(),\r\n                    GetParentActivityId(),\r\n                    // From member fields or program info.\r\n                    AICLI_TraceLoggingStringView(m_caller, \"Caller\"),\r\n                    TraceLoggingPackedFieldEx(m_telemetryCorrelationJsonW.c_str(), static_cast<ULONG>((m_telemetryCorrelationJsonW.size() + 1) * sizeof(wchar_t)), TlgInUNICODESTRING, TlgOutJSON, \"CvJson\"),\r\n                    TraceLoggingCountedString(version->c_str(), static_cast<ULONG>(version->size()), \"ClientVersion\"),\r\n                    TraceLoggingCountedString(packageVersion->c_str(), static_cast<ULONG>(packageVersion->size()), \"ClientPackageVersion\"),\r\n                    TraceLoggingBool(Runtime::IsReleaseBuild(), \"IsReleaseBuild\"),\r\n                    TraceLoggingUInt32(m_executionStage, \"ExecutionStage\"),\r\n                    // From TelemetrySummary\r\n                    TraceLoggingHResult(m_summary.FailureHResult, \"FailureHResult\"),\r\n                    AICLI_TraceLoggingWStringView(m_summary.FailureMessage, \"FailureMessage\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.FailureModule, \"FailureModule\"),\r\n                    TraceLoggingUInt32(m_summary.FailureThreadId, \"FailureThreadId\"),\r\n                    TraceLoggingUInt32(static_cast<UINT32>(m_summary.FailureType), \"FailureType\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.FailureFile, \"FailureFile\"),\r\n                    TraceLoggingUInt32(m_summary.FailureLine, \"FailureLine\"),\r\n                    TraceLoggingBool(m_summary.IsCOMCall, \"IsCOMCall\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.Command, \"Command\"),\r\n                    TraceLoggingBool(m_summary.CommandSuccess, \"CommandSuccess\"),\r\n                    TraceLoggingBool(m_summary.IsManifestLocal, \"IsManifestLocal\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.PackageIdentifier, \"PackageIdentifier\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.PackageName, \"PackageName\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.PackageVersion, \"PackageVersion\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.Channel, \"Channel\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.SourceIdentifier, \"SourceIdentifier\"),\r\n                    TraceLoggingInt32(m_summary.InstallerArchitecture, \"InstallerArchitecture\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.InstallerUrl, \"InstallerUrl\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.InstallerType, \"InstallerType\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.InstallerScope, \"InstallerScope\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.InstallerLocale, \"InstallerLocale\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.SearchType, \"SearchType\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.SearchQuery, \"SearchQuery\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.SearchId, \"SearchId\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.SearchName, \"SearchName\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.SearchMoniker, \"SearchMoniker\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.SearchTag, \"SearchTag\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.SearchCommand, \"SearchCommand\"),\r\n                    TraceLoggingUInt64(m_summary.SearchMaximum, \"SearchMaximum\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.SearchRequest, \"SearchRequest\"),\r\n                    TraceLoggingUInt64(m_summary.SearchResultCount, \"SearchResultCount\"),\r\n                    TraceLoggingBinary(m_summary.HashMismatchExpected.data(), static_cast<ULONG>(m_summary.HashMismatchExpected.size()), \"HashMismatchExpected\"),\r\n                    TraceLoggingBinary(m_summary.HashMismatchActual.data(), static_cast<ULONG>(m_summary.HashMismatchActual.size()), \"HashMismatchActual\"),\r\n                    TraceLoggingBool(m_summary.HashMismatchOverride, \"HashMismatchOverride\"),\r\n                    TraceLoggingUInt64(m_summary.HashMismatchActualSize, \"HashMismatchActualSize\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.HashMismatchContentType, \"HashMismatchContentType\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.InstallerExecutionType, \"InstallerExecutionType\"),\r\n                    TraceLoggingUInt32(m_summary.InstallerErrorCode, \"InstallerErrorCode\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.UninstallerExecutionType, \"UninstallerExecutionType\"),\r\n                    TraceLoggingUInt32(m_summary.UninstallerErrorCode, \"UninstallerErrorCode\"),\r\n                    TraceLoggingUInt64(m_summary.ChangesToARP, \"ChangesToARP\"),\r\n                    TraceLoggingUInt64(m_summary.MatchesInARP, \"MatchesInARP\"),\r\n                    TraceLoggingUInt64(m_summary.ChangesThatMatch, \"ChangesThatMatch\"),\r\n                    TraceLoggingUInt64(m_summary.ARPLanguage, \"ARPLanguage\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.ARPName, \"ARPName\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.ARPVersion, \"ARPVersion\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.ARPPublisher, \"ARPPublisher\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.DOUrl, \"DOUrl\"),\r\n                    TraceLoggingHResult(m_summary.DOHResult, \"DOHResult\"),\r\n                    AICLI_TraceLoggingStringView(m_summary.RepairExecutionType, \"RepairExecutionType\"),\r\n                    TraceLoggingUInt32(m_summary.RepairErrorCode, \"RepairErrorCode\"),\r\n                    TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance | PDT_ProductAndServiceUsage | PDT_SoftwareSetupAndInventory),\r\n                    TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES));\r\n            }\r\n        }\r\n    }\r\n\r\n    bool TelemetryTraceLogger::IsTelemetryEnabled() const noexcept\r\n    {\r\n        return g_IsTelemetryProviderEnabled && m_isInitialized && m_isSettingEnabled && m_isRuntimeEnabled;\r\n    }\r\n\r\n    void TelemetryTraceLogger::InitializeInternal(const AppInstaller::Settings::UserSettings& userSettings)\r\n    {\r\n        m_isSettingEnabled = !userSettings.Get<Settings::Setting::TelemetryDisable>();\r\n        m_isInitialized = true;\r\n    }\r\n\r\n    std::wstring TelemetryTraceLogger::AnonymizeString(const wchar_t* input) const noexcept\r\n    {\r\n        return input ? AnonymizeString(std::wstring_view{ input }) : std::wstring{};\r\n    }\r\n\r\n    std::wstring TelemetryTraceLogger::AnonymizeString(std::wstring_view input) const noexcept try\r\n    {\r\n        // GetPathTo() may need to read the settings, so this function should only be called after settings are initialized.\r\n        // To ensure that, this function is only called when emitting an event, and we disable the telemetry until settings are ready.\r\n        static const std::wstring s_UserProfile = Runtime::GetPathTo(Runtime::PathName::UserProfile).wstring();\r\n\r\n        return Utility::ReplaceWhileCopying(input, s_UserProfile, s_UserProfileReplacement);\r\n    }\r\n    catch (...) { return std::wstring{ input }; }\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n    static std::shared_ptr<TelemetryTraceLogger> s_TelemetryTraceLogger_TestOverride;\r\n#endif\r\n\r\n    TelemetryTraceLogger& Telemetry()\r\n    {\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        if (s_TelemetryTraceLogger_TestOverride)\r\n        {\r\n            return *s_TelemetryTraceLogger_TestOverride.get();\r\n        }\r\n#endif\r\n        ThreadLocalStorage::ThreadGlobals* pThreadGlobals = ThreadLocalStorage::ThreadGlobals::GetForCurrentThread();\r\n        if (pThreadGlobals)\r\n        {\r\n            return *reinterpret_cast<TelemetryTraceLogger*>(pThreadGlobals->GetTelemetryObject());\r\n        }\r\n        else\r\n        {\r\n            // For the global telemetry object, we may not have yet read the settings file.\r\n            // In that case, we will not be able to initialize it, so we need to try it\r\n            // each time we get the object.\r\n            static TelemetryTraceLogger processGlobalTelemetry(/* useSummary */ false);\r\n            processGlobalTelemetry.TryInitialize();\r\n            return processGlobalTelemetry;\r\n        }\r\n    }\r\n\r\n    void EnableWilFailureTelemetry()\r\n    {\r\n        wil::SetResultLoggingCallback(wilResultLoggingCallback);\r\n    }\r\n\r\n    void UseGlobalTelemetryLoggerActivityIdOnly()\r\n    {\r\n        s_useGlobalTelemetryActivityId = true;\r\n        std::ignore = CoCreateGuid(&s_globalTelemetryLoggerActivityId);\r\n    }\r\n\r\n    DisableTelemetryScope::DisableTelemetryScope()\r\n    {\r\n        m_token = Telemetry().DisableRuntime();\r\n    }\r\n\r\n    DisableTelemetryScope::~DisableTelemetryScope()\r\n    {\r\n        if (m_token)\r\n        {\r\n            Telemetry().EnableRuntime();\r\n        }\r\n    }\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n    // Replace this test hook with context telemetry when it gets moved over\r\n    void TestHook_SetTelemetryOverride(std::shared_ptr<TelemetryTraceLogger> ttl)\r\n    {\r\n        s_TelemetryTraceLogger_TestOverride = std::move(ttl);\r\n    }\r\n#endif\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Architecture.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/AppInstallerArchitecture.h\"\r\n#include \"Public/AppInstallerLogging.h\"\r\n#include \"Public/AppInstallerRuntime.h\"\r\n#include \"Public/AppInstallerStrings.h\"\r\n\r\nnamespace AppInstaller::Utility\r\n{\r\n    using namespace literals;\r\n    namespace\r\n    {\r\n        // IsWow64GuestMachineSupported() is available starting on Windows 10, version 1709 (RS3).\r\n        // We generally target a later version (version 1809, RS5), but the WinGetUtil is used in\r\n        // Azure Functions that run on version 1607 (RS1) where it is not available. So, we load and\r\n        // call this function only if available.\r\n        using IsWow64GuestMachineSupportedPtr = decltype(&IsWow64GuestMachineSupported);\r\n\r\n        struct IsWow64GuestMachineSupportedHelper\r\n        {\r\n            IsWow64GuestMachineSupportedHelper()\r\n            {\r\n                m_module.reset(LoadLibraryEx(L\"api-ms-win-core-wow64-l1-1-2.dll\", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32));\r\n                if (!m_module)\r\n                {\r\n                    AICLI_LOG(Core, Verbose, << \"Could not load api-ms-win-core-wow64-l1-1-2.dll\");\r\n                    return;\r\n                }\r\n\r\n                m_isWow64GuestMachineSupported =\r\n                    reinterpret_cast<IsWow64GuestMachineSupportedPtr>(GetProcAddress(m_module.get(), \"IsWow64GuestMachineSupported\"));\r\n                if (!m_isWow64GuestMachineSupported)\r\n                {\r\n                    AICLI_LOG(Core, Verbose, << \"Could not get proc address of IsWow64GuestMachineSupported\");\r\n                    return;\r\n                }\r\n            }\r\n\r\n            void AddArchitectureIfGuestMachineSupported(std::vector<Architecture>& target, Architecture architecture, USHORT guestMachine)\r\n            {\r\n                if (m_isWow64GuestMachineSupported)\r\n                {\r\n                    BOOL supported = FALSE;\r\n                    LOG_IF_FAILED(m_isWow64GuestMachineSupported(guestMachine, &supported));\r\n\r\n                    if (supported)\r\n                    {\r\n                        target.push_back(architecture);\r\n                    }\r\n                }\r\n            }\r\n\r\n        private:\r\n            wil::unique_hmodule m_module;\r\n            IsWow64GuestMachineSupportedPtr m_isWow64GuestMachineSupported = nullptr;\r\n        };\r\n\r\n        void AddArchitectureIfGuestMachineSupported(std::vector<Architecture>& target, Architecture architecture, USHORT guestMachine)\r\n        {\r\n            IsWow64GuestMachineSupportedHelper helper;\r\n            helper.AddArchitectureIfGuestMachineSupported(target, architecture, guestMachine);\r\n        }\r\n\r\n        // These types are defined in a future SDK and can be removed when we actually have them available.\r\n        // The exception is that None was added (and this is an enum class).\r\n        enum class MACHINE_ATTRIBUTES {\r\n            None = 0,\r\n            UserEnabled = 0x00000001,\r\n            KernelEnabled = 0x00000002,\r\n            Wow64Container = 0x00000004\r\n        };\r\n\r\n        DEFINE_ENUM_FLAG_OPERATORS(MACHINE_ATTRIBUTES);\r\n\r\n        using GetMachineTypeAttributesPtr = HRESULT(WINAPI*)(USHORT Machine, MACHINE_ATTRIBUTES* MachineTypeAttributes);\r\n\r\n        // GetMachineTypeAttributes can apparently replace IsWow64GuestMachineSupported, but no reason to do so right now.\r\n        struct GetMachineTypeAttributesHelper\r\n        {\r\n            GetMachineTypeAttributesHelper()\r\n            {\r\n                m_module.reset(LoadLibraryEx(L\"api-ms-win-core-processthreads-l1-1-7.dll\", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32));\r\n                if (!m_module)\r\n                {\r\n                    AICLI_LOG(Core, Verbose, << \"Could not load api-ms-win-core-processthreads-l1-1-7.dll\");\r\n                    return;\r\n                }\r\n\r\n                m_getMachineTypeAttributes =\r\n                    reinterpret_cast<GetMachineTypeAttributesPtr>(GetProcAddress(m_module.get(), \"GetMachineTypeAttributes\"));\r\n                if (!m_getMachineTypeAttributes)\r\n                {\r\n                    AICLI_LOG(Core, Verbose, << \"Could not get proc address of GetMachineTypeAttributes\");\r\n                    return;\r\n                }\r\n            }\r\n\r\n            void AddArchitectureIfMachineTypeAttributesUserEnabled(std::vector<Architecture>& target, Architecture architecture, USHORT guestMachine)\r\n            {\r\n                if (m_getMachineTypeAttributes)\r\n                {\r\n                    MACHINE_ATTRIBUTES attributes = MACHINE_ATTRIBUTES::None;\r\n                    if (SUCCEEDED_LOG(m_getMachineTypeAttributes(guestMachine, &attributes)))\r\n                    {\r\n                        if (WI_IsFlagSet(attributes, MACHINE_ATTRIBUTES::UserEnabled))\r\n                        {\r\n                            target.push_back(architecture);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n        private:\r\n            wil::unique_hmodule m_module;\r\n            GetMachineTypeAttributesPtr m_getMachineTypeAttributes = nullptr;\r\n        };\r\n\r\n        void AddArchitectureIfMachineTypeAttributesUserEnabled(std::vector<Architecture>& target, Architecture architecture, USHORT guestMachine)\r\n        {\r\n            GetMachineTypeAttributesHelper helper;\r\n            helper.AddArchitectureIfMachineTypeAttributesUserEnabled(target, architecture, guestMachine);\r\n        }\r\n\r\n        // Gets the applicable architectures for the current machine.\r\n        std::vector<Architecture> CreateApplicableArchitecturesVector()\r\n        {\r\n            std::vector<Architecture> applicableArchs;\r\n\r\n            switch (GetSystemArchitecture())\r\n            {\r\n            case Architecture::Arm64:\r\n            {\r\n                applicableArchs.push_back(Architecture::Arm64);\r\n                AddArchitectureIfGuestMachineSupported(applicableArchs, Architecture::Arm, IMAGE_FILE_MACHINE_ARMNT);\r\n                AddArchitectureIfMachineTypeAttributesUserEnabled(applicableArchs, Architecture::X64, IMAGE_FILE_MACHINE_AMD64);\r\n                AddArchitectureIfGuestMachineSupported(applicableArchs, Architecture::X86, IMAGE_FILE_MACHINE_I386);\r\n                applicableArchs.push_back(Architecture::Neutral);\r\n            }\r\n                break;\r\n            case Architecture::Arm:\r\n                applicableArchs.push_back(Architecture::Arm);\r\n                applicableArchs.push_back(Architecture::Neutral);\r\n                break;\r\n            case Architecture::X86:\r\n                applicableArchs.push_back(Architecture::X86);\r\n                applicableArchs.push_back(Architecture::Neutral);\r\n                break;\r\n            case Architecture::X64:\r\n                applicableArchs.push_back(Architecture::X64);\r\n                AddArchitectureIfGuestMachineSupported(applicableArchs, Architecture::X86, IMAGE_FILE_MACHINE_I386);\r\n                applicableArchs.push_back(Architecture::Neutral);\r\n                break;\r\n            default:\r\n                applicableArchs.push_back(Architecture::Neutral);\r\n            }\r\n\r\n            return applicableArchs;\r\n        }\r\n    }\r\n\r\n    Architecture ConvertToArchitectureEnum(std::string_view archStr)\r\n    {\r\n        std::string arch = ToLower(archStr);\r\n        if (arch == \"x86\")\r\n        {\r\n            return Architecture::X86;\r\n        }\r\n        else if (arch == \"x64\")\r\n        {\r\n            return Architecture::X64;\r\n        }\r\n        else if (arch == \"arm\")\r\n        {\r\n            return Architecture::Arm;\r\n        }\r\n        else if (arch == \"arm64\")\r\n        {\r\n            return Architecture::Arm64;\r\n        }\r\n        else if (arch == \"neutral\")\r\n        {\r\n            return Architecture::Neutral;\r\n        }\r\n\r\n        AICLI_LOG(Core, Info, << \"ConvertToArchitectureEnum: Unknown architecture: \" << archStr);\r\n        return Architecture::Unknown;\r\n    }\r\n\r\n    std::optional<::AppInstaller::Utility::Architecture> ConvertToArchitectureEnum(winrt::Windows::System::ProcessorArchitecture architecture)\r\n    {\r\n        switch (architecture)\r\n        {\r\n        case winrt::Windows::System::ProcessorArchitecture::X86:\r\n            return ::AppInstaller::Utility::Architecture::X86;\r\n        case winrt::Windows::System::ProcessorArchitecture::Arm:\r\n            return ::AppInstaller::Utility::Architecture::Arm;\r\n        case winrt::Windows::System::ProcessorArchitecture::X64:\r\n            return ::AppInstaller::Utility::Architecture::X64;\r\n        case winrt::Windows::System::ProcessorArchitecture::Neutral:\r\n            return ::AppInstaller::Utility::Architecture::Neutral;\r\n        case winrt::Windows::System::ProcessorArchitecture::Arm64:\r\n            return ::AppInstaller::Utility::Architecture::Arm64;\r\n        }\r\n\r\n        return {};\r\n    }\r\n\r\n    LocIndView ToString(Architecture architecture)\r\n    {\r\n        switch (architecture)\r\n        {\r\n        case Architecture::Neutral:\r\n            return \"Neutral\"_liv;\r\n        case Architecture::X86:\r\n            return \"X86\"_liv;\r\n        case Architecture::X64:\r\n            return \"X64\"_liv;\r\n        case Architecture::Arm:\r\n            return \"Arm\"_liv;\r\n        case Architecture::Arm64:\r\n            return \"Arm64\"_liv;\r\n        }\r\n\r\n        return \"Unknown\"_liv;\r\n    }\r\n\r\n    Architecture GetSystemArchitecture()\r\n    {\r\n        Architecture systemArchitecture = Architecture::Unknown;\r\n\r\n        USHORT processArchitecture = IMAGE_FILE_MACHINE_UNKNOWN;\r\n        USHORT machineArchitecture = IMAGE_FILE_MACHINE_UNKNOWN;\r\n        // Just log the error if failed and return architecture Unknown.\r\n        LOG_IF_WIN32_BOOL_FALSE(IsWow64Process2(GetCurrentProcess(), &processArchitecture, &machineArchitecture));\r\n\r\n        switch (machineArchitecture)\r\n        {\r\n        case IMAGE_FILE_MACHINE_AMD64:\r\n            systemArchitecture = Architecture::X64;\r\n            break;\r\n        case IMAGE_FILE_MACHINE_ARM:\r\n            systemArchitecture = Architecture::Arm;\r\n            break;\r\n        case IMAGE_FILE_MACHINE_ARM64:\r\n            systemArchitecture = Architecture::Arm64;\r\n            break;\r\n        case IMAGE_FILE_MACHINE_I386:\r\n            systemArchitecture = Architecture::X86;\r\n            break;\r\n        }\r\n\r\n        return systemArchitecture;\r\n    }\r\n\r\n    const std::vector<Architecture>& GetApplicableArchitectures()\r\n    {\r\n        static std::vector<Architecture> applicableArchs = CreateApplicableArchitecturesVector();\r\n        return applicableArchs;\r\n    }\r\n\r\n    const std::vector<Architecture>& GetAllArchitectures()\r\n    {\r\n        static std::vector<Architecture> allArchs = { Architecture::Neutral, Architecture::X86, Architecture::X64, Architecture::Arm, Architecture::Arm64 };\r\n        return allArchs;\r\n    }\r\n\r\n    int IsApplicableArchitecture(Architecture arch)\r\n    {\r\n        return IsApplicableArchitecture(arch, GetApplicableArchitectures());\r\n    }\r\n\r\n    int IsApplicableArchitecture(Architecture arch, const std::vector<Architecture>& allowedArchitectures)\r\n    {\r\n        auto it = std::find(allowedArchitectures.begin(), allowedArchitectures.end(), arch);\r\n\r\n        if (it != allowedArchitectures.end())\r\n        {\r\n            return static_cast<int>(std::distance(it, allowedArchitectures.end()));\r\n        }\r\n        else\r\n        {\r\n            return InapplicableArchitecture;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Archive.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/Archive.h\"\r\n\r\n// TODO: Move include statement to pch.h and resolve build errors\r\n#pragma warning( push )\r\n#pragma warning ( disable : 4189 4244 26451 )\r\n#include <pure.h>\r\n#pragma warning ( pop )\r\n\r\nnamespace AppInstaller::Archive\r\n{\r\n    using unique_pidlist_absolute = wil::unique_any<PIDLIST_ABSOLUTE, decltype(&::CoTaskMemFree), ::CoTaskMemFree>;\r\n    using unique_lpitemidlist = wil::unique_any<LPITEMIDLIST, decltype(&::CoTaskMemFree), ::CoTaskMemFree>;\r\n\r\n    HRESULT TryExtractArchive(const std::filesystem::path& archivePath, const std::filesystem::path& destPath)\r\n    {\r\n        wil::com_ptr<IFileOperation> pFileOperation;\r\n        RETURN_IF_FAILED(CoCreateInstance(CLSID_FileOperation, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pFileOperation)));\r\n        RETURN_IF_FAILED(pFileOperation->SetOperationFlags(FOF_NO_UI));\r\n\r\n        wil::com_ptr<IShellItem> pShellItemTo;\r\n        RETURN_IF_FAILED(SHCreateItemFromParsingName(destPath.c_str(), NULL, IID_PPV_ARGS(&pShellItemTo)));\r\n\r\n        unique_pidlist_absolute pidlFull;\r\n        RETURN_IF_FAILED(SHParseDisplayName(archivePath.c_str(), NULL, &pidlFull, 0, NULL));\r\n\r\n        wil::com_ptr<IShellFolder> pArchiveShellFolder;\r\n        RETURN_IF_FAILED(SHBindToObject(NULL, pidlFull.get(), NULL, IID_PPV_ARGS(&pArchiveShellFolder)));\r\n\r\n        wil::com_ptr<IEnumIDList> pEnumIdList;\r\n        RETURN_IF_FAILED(pArchiveShellFolder->EnumObjects(nullptr, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &pEnumIdList));\r\n\r\n        unique_lpitemidlist pidlChild;\r\n        ULONG nFetched;\r\n        while (pEnumIdList->Next(1, wil::out_param_ptr<LPITEMIDLIST*>(pidlChild), &nFetched) == S_OK && nFetched == 1)\r\n        {\r\n            wil::com_ptr<IShellItem> pShellItemFrom;\r\n            STRRET strFolderName;\r\n            WCHAR szFolderName[MAX_PATH];\r\n            RETURN_IF_FAILED(pArchiveShellFolder->GetDisplayNameOf(pidlChild.get(), SHGDN_INFOLDER | SHGDN_FORPARSING, &strFolderName));\r\n            RETURN_IF_FAILED(StrRetToBuf(&strFolderName, pidlChild.get(), szFolderName, MAX_PATH));\r\n            RETURN_IF_FAILED(SHCreateItemWithParent(pidlFull.get(), pArchiveShellFolder.get(), pidlChild.get(), IID_PPV_ARGS(&pShellItemFrom)));\r\n            RETURN_IF_FAILED(pFileOperation->CopyItem(pShellItemFrom.get(), pShellItemTo.get(), NULL, NULL));\r\n        }\r\n\r\n        RETURN_IF_FAILED(pFileOperation->PerformOperations());\r\n        return S_OK;\r\n    }\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n    static bool* s_ScanArchiveResult_TestHook_Override = nullptr;\r\n\r\n    void TestHook_SetScanArchiveResult_Override(bool* status)\r\n    {\r\n        s_ScanArchiveResult_TestHook_Override = status;\r\n    }\r\n#endif\r\n\r\n    bool ScanZipFile(const std::filesystem::path& zipPath)\r\n    {\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        if (s_ScanArchiveResult_TestHook_Override)\r\n        {\r\n            return *s_ScanArchiveResult_TestHook_Override;\r\n        }\r\n#endif\r\n\r\n        std::ifstream instream{ zipPath, std::ios::in | std::ios::binary };\r\n        std::vector<uint8_t> data{ { std::istreambuf_iterator<char>{ instream } }, std::istreambuf_iterator<char>{} };\r\n\r\n        uint8_t* buffer = &data[0];\r\n        uint64_t flag = 0;\r\n        int scanResult = pure_zip(buffer, data.size(), flag);\r\n\r\n        return scanResult == 0;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Authentication/Authentication.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"Public/winget/Authentication.h\"\n#include \"WebAccountManagerAuthenticator.h\"\n#include <AppInstallerStrings.h>\n#include <AppInstallerLogging.h>\n\nusing namespace std::string_view_literals;\n\nnamespace AppInstaller::Authentication\n{\n    namespace\n    {\n        constexpr std::string_view s_BearerTokenPrefix = \"Bearer \"sv;\r\n        // Default Azure Blob Storage resource value. Used when manifest author did not provide specific blob resource.\r\n        constexpr std::string_view s_DefaultAzureBlobStorageResource = \"https://storage.azure.com/\"sv;\n    }\n\n    Authenticator::Authenticator(AuthenticationInfo info, AuthenticationArguments args)\n    {\n        THROW_HR_IF(E_UNEXPECTED, args.Mode == AuthenticationMode::Unknown);\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED, info.Type == AuthenticationType::Unknown);\n        THROW_HR_IF(E_UNEXPECTED, info.Type == AuthenticationType::None);\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_AUTHENTICATION_INFO, !info.ValidateIntegrity());\n\n        AICLI_LOG(Core, Info, << \"AuthenticationArguments values. Mode: \" << AuthenticationModeToString(args.Mode) << \", Account: \" << args.AuthenticationAccount);\n\n        if (info.Type == AuthenticationType::MicrosoftEntraId || info.Type == AuthenticationType::MicrosoftEntraIdForAzureBlobStorage)\n        {\n            AICLI_LOG(Core, Info, << \"Creating WebAccountManagerAuthenticator for \" << AuthenticationTypeToString(info.Type));\n            m_authProvider = std::make_unique<WebAccountManagerAuthenticator>(std::move(info), std::move(args));\n        }\n    }\n\n#ifndef AICLI_DISABLE_TEST_HOOKS\n    static AuthenticationResult* s_AuthenticationResult_TestHook_Override = nullptr;\n\n    void TestHook_SetAuthenticationResult_Override(Authentication::AuthenticationResult* authResult)\n    {\n        s_AuthenticationResult_TestHook_Override = authResult;\n    }\n#endif\n\n    // Each authentication provider uses its own mechanism for caching.\n    // Here we directly call authentication provider to authenticate.\n    AuthenticationResult Authenticator::AuthenticateForToken()\n    {\n#ifndef AICLI_DISABLE_TEST_HOOKS\n        if (s_AuthenticationResult_TestHook_Override)\n        {\n            return *s_AuthenticationResult_TestHook_Override;\n        }\n#endif\n\n        THROW_HR_IF(E_UNEXPECTED, !m_authProvider);\n\n        return m_authProvider->AuthenticateForToken();\n    }\r\n\r\n    bool MicrosoftEntraIdAuthenticationInfo::operator<(const MicrosoftEntraIdAuthenticationInfo& other) const\r\n    {\r\n        // std::tie implements tuple comparison, wherein it checks the first item in the tuple,\r\n        // iff the first elements are equal, then the second element is used for comparison, and so on\r\n        return std::tie(Resource, Scope) < std::tie(other.Resource, other.Scope);\r\n    }\r\n\r\n    bool AuthenticationInfo::operator<(const AuthenticationInfo& other) const\n    {\n        // std::tie implements tuple comparison, wherein it checks the first item in the tuple,\r\n        // iff the first elements are equal, then the second element is used for comparison, and so on\r\n        return std::tie(Type, MicrosoftEntraIdInfo) < std::tie(other.Type, other.MicrosoftEntraIdInfo);\n    }\n\n    void AuthenticationInfo::UpdateRequiredFieldsIfNecessary()\n    {\r\n        // If MicrosoftEntraIdForAzureBlobStorage, populate default resource value if missing.\r\n        if (Type == AuthenticationType::MicrosoftEntraIdForAzureBlobStorage)\r\n        {\r\n            if (MicrosoftEntraIdInfo.has_value())\r\n            {\r\n                if (MicrosoftEntraIdInfo->Resource.empty())\r\n                {\r\n                    MicrosoftEntraIdInfo->Resource = s_DefaultAzureBlobStorageResource;\r\n                    MicrosoftEntraIdInfo->Scope = \"\";\n                }\n            }\r\n            else\r\n            {\r\n                MicrosoftEntraIdAuthenticationInfo authInfo;\r\n                authInfo.Resource = s_DefaultAzureBlobStorageResource;\r\n                MicrosoftEntraIdInfo = std::move(authInfo);\n            }\n        }\n    }\n\n    bool AuthenticationInfo::ValidateIntegrity() const\n    {\n        // For MicrosoftEntraId, Resource is required.\n        if (Type == AuthenticationType::MicrosoftEntraId || Type == AuthenticationType::MicrosoftEntraIdForAzureBlobStorage)\n        {\n            return MicrosoftEntraIdInfo.has_value() && !MicrosoftEntraIdInfo->Resource.empty();\n        }\n\n        return true;\n    }\n\n    AuthenticationWindowBase::AuthenticationWindowBase()\n    {\n        InitializeWindowThread();\n    }\n\n    HWND AuthenticationWindowBase::GetHandle()\n    {\n        return m_windowHandle;\n    }\n\n    AuthenticationWindowBase::~AuthenticationWindowBase()\n    {\n        if (!PostMessageW(m_windowHandle, WM_CLOSE, 0, 0))\n        {\n            m_terminateWindowThread = true;\n        }\n\n        if (m_windowThread.joinable())\n        {\n            m_windowThread.join();\n        }\n    }\n\n    void AuthenticationWindowBase::InitializeWindowThread()\n    {\n        static std::once_flag s_registerWindowClassOnce;\n        static LPCWSTR s_windowsClassName = L\"WingetAuthenticationParentWindowClass\";\n        static HMODULE hModule = GetModuleHandle(NULL);\n        THROW_LAST_ERROR_IF_NULL_MSG(hModule, \"Failed to get resource module for authentication window\");\n\n        std::call_once(s_registerWindowClassOnce,\n            [&]()\n            {\n                WNDCLASS wc = {};\n                wc.lpfnWndProc = AuthenticationWindowBase::WindowProcessFunction;\n                wc.hInstance = hModule;\n                wc.lpszClassName = s_windowsClassName;\n                THROW_LAST_ERROR_IF_MSG(!RegisterClassW(&wc), \"Failed to get resource module for authentication window\");\n            });\n\n        wil::unique_event waitForWindowReady;\n        waitForWindowReady.create();\n\n        m_windowThread = std::thread(\n            [&]()\n            {\n                m_windowHandle = CreateWindowW(\n                    s_windowsClassName,\n                    L\"WingetAuthenticationParentWindow\",\n                    WS_OVERLAPPEDWINDOW,\n                    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, /* size and position */\n                    NULL, /* hWndParent */\n                    NULL, /* hMenu */\n                    hModule,\n                    NULL); /* lpParam */\n                THROW_LAST_ERROR_IF_NULL_MSG(hModule, \"Failed to create authentication parent window\");\n\n                // Best effort only\n                SetForegroundWindow(m_windowHandle);\n\n                m_windowThreadId = GetCurrentThreadId();\n\n                // Set window ready event\n                waitForWindowReady.SetEvent();\n\n                // Message loop\n                MSG msg;\n                BOOL getMsgResult;\n                while ((getMsgResult = GetMessage(&msg, NULL, 0, 0)) != 0)\n                {\n                    if (m_terminateWindowThread || getMsgResult == -1)\n                    {\n                        return;\n                    }\n                    else\n                    {\n                        TranslateMessage(&msg);\n                        DispatchMessage(&msg);\n                    }\n                }\n            });\n\n        THROW_HR_IF_MSG(APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED, !waitForWindowReady.wait(10000), \"Creating authentication parent window timed out\");\n    }\n\n    LRESULT __stdcall AuthenticationWindowBase::WindowProcessFunction(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)\n    {\n        switch (uMsg)\n        {\n        case WM_ENDSESSION:\n        case WM_CLOSE:\n            DestroyWindow(hWnd);\n            break;\n        case WM_DESTROY:\n            PostQuitMessage(0);\n            break;\n        default:\n            return DefWindowProc(hWnd, uMsg, wParam, lParam);\n        }\n\n        return 0;\n    }\n\n    std::string_view AuthenticationTypeToString(AuthenticationType in)\n    {\n        switch (in)\n        {\n        case AuthenticationType::None:\n            return \"none\"sv;\n        case AuthenticationType::MicrosoftEntraId:\n            return \"microsoftEntraId\"sv;\r\n        case AuthenticationType::MicrosoftEntraIdForAzureBlobStorage:\n            return \"microsoftEntraIdForAzureBlobStorage\"sv;\n        }\n\n        return \"unknown\"sv;\n    }\n\n    AuthenticationType ConvertToAuthenticationType(std::string_view in)\n    {\n        std::string inStrLower = Utility::ToLower(in);\n        AuthenticationType result = AuthenticationType::Unknown;\n\n        if (inStrLower == \"none\")\n        {\n            result = AuthenticationType::None;\n        }\n        else if (inStrLower == \"microsoftentraid\")\n        {\n            result = AuthenticationType::MicrosoftEntraId;\n        }\r\n        else if (inStrLower == \"microsoftentraidforazureblobstorage\")\n        {\n            result = AuthenticationType::MicrosoftEntraIdForAzureBlobStorage;\n        }\n\n        return result;\n    }\n\n    std::string_view AuthenticationModeToString(AuthenticationMode in)\n    {\n        switch (in)\n        {\n        case AuthenticationMode::Silent:\n            return \"silent\"sv;\n        case AuthenticationMode::SilentPreferred:\n            return \"silentPreferred\"sv;\n        case AuthenticationMode::Interactive:\n            return \"interactive\"sv;\n        }\n\n        return \"unknown\"sv;\n    }\n\n    AuthenticationMode ConvertToAuthenticationMode(std::string_view in)\n    {\n        std::string inStrLower = Utility::ToLower(in);\n        AuthenticationMode result = AuthenticationMode::Unknown;\n\n        if (inStrLower == \"silent\")\n        {\n            result = AuthenticationMode::Silent;\n        }\n        else if (inStrLower == \"silentpreferred\")\n        {\n            result = AuthenticationMode::SilentPreferred;\n        }\n        else if (inStrLower == \"interactive\")\n        {\n            result = AuthenticationMode::Interactive;\n        }\n\n        return result;\n    }\n\n    std::string AppInstaller::Authentication::CreateBearerToken(std::string rawToken)\n    {\n        return std::string{ s_BearerTokenPrefix } + rawToken;\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Authentication/WebAccountManagerAuthenticator.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include <AppInstallerErrors.h>\n#include <AppInstallerStrings.h>\n#include <AppInstallerLogging.h>\n#include <AppInstallerRuntime.h>\n#include \"WebAccountManagerAuthenticator.h\"\n\nusing namespace std::string_view_literals;\nusing namespace winrt::Windows::Foundation;\nusing namespace winrt::Windows::Security::Authentication::Web::Core;\nusing namespace winrt::Windows::Security::Credentials;\n\nnamespace AppInstaller::Authentication\n{\n    namespace\n    {\n        constexpr std::wstring_view s_MicrosoftEntraIdProviderId = L\"https://login.microsoft.com\"sv;\n        constexpr std::wstring_view s_MicrosoftEntraIdAuthority = L\"organizations\"sv;\n        constexpr std::wstring_view s_MicrosoftEntraIdClientId = L\"7b8ea11a-7f45-4b3a-ab51-794d5863af15\"sv;\n        constexpr std::wstring_view s_MicrosoftEntraIdResourceHeader = L\"resource\"sv;\n        constexpr std::wstring_view s_MicrosoftEntraIdLoginHintHeader = L\"LoginHint\"sv;\n    }\n\n    WebAccountManagerAuthenticator::WebAccountManagerAuthenticator(AuthenticationInfo info, AuthenticationArguments args) : m_authInfo(std::move(info)), m_authArgs(std::move(args))\n    {\n        // WebAccountManager manages accounts as user. When running as system, it can only retrieve domain joined device token.\n        // This is very rare scenario for rest source to require a device token. And it needs approval to provision winget client registration.\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), Runtime::IsRunningAsSystem());\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_AUTHENTICATION_INFO, !m_authInfo.ValidateIntegrity());\n        THROW_HR_IF(E_UNEXPECTED, m_authArgs.Mode == AuthenticationMode::Unknown);\n\n        if (IsMicrosoftEntraIdAuthenticationType())\n        {\n            m_webAccountProvider = WebAuthenticationCoreManager::FindAccountProviderAsync(s_MicrosoftEntraIdProviderId, s_MicrosoftEntraIdAuthority).get();\n            THROW_HR_IF_MSG(E_UNEXPECTED, !m_webAccountProvider, \"Authentication Provider not found for Microsoft Entra Id\");\n            AICLI_LOG(Core, Info, << \"WebAccountManagerAuthenticator created for MicrosoftEntraId. Resource: \" << m_authInfo.MicrosoftEntraIdInfo->Resource << \", Scope: \" << m_authInfo.MicrosoftEntraIdInfo->Scope);\n        }\n        else if (m_authInfo.Type == AuthenticationType::None)\n        {\n            THROW_HR_MSG(E_UNEXPECTED, \"WebAccountManagerAuthenticator initialized with authentication type none\");\n        }\n        else\n        {\n            THROW_HR(APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED);\n        }\n    }\n\n    // WebAccountManager manages token and cache at OS level.\n    // So for each authentication request, we call WebAccountManager api to retrieve token.\n    // We do not need to implement own cache logic.\n    AuthenticationResult WebAccountManagerAuthenticator::AuthenticateForToken()\n    {\n        std::lock_guard<std::mutex> lock{ m_authLock };\n\n        AICLI_LOG(Core, Info, << \"Started WebAccountManagerAuthenticator::AuthenticateForToken.\");\n\n        AuthenticationResult result;\n\n        if (!m_authenticatedAccount)\n        {\n            // This is the first time invocation or previous authentication failed\n\n            // Find the account to use if user provided account name and the account is signed in before. Best effort only.\n            WebAccount webAccount = nullptr;\n            if (!m_authArgs.AuthenticationAccount.empty())\n            {\n                webAccount = FindWebAccount(m_authArgs.AuthenticationAccount);\n            }\n\n            if (m_authArgs.Mode == AuthenticationMode::Interactive)\n            {\n                result = GetToken(webAccount, true);\n            }\n            else if (m_authArgs.Mode == AuthenticationMode::SilentPreferred)\n            {\n                result = GetTokenSilent(webAccount);\n                if (FAILED(result.Status))\n                {\n                    result = GetToken(webAccount);\n                }\n            }\n            else if (m_authArgs.Mode == AuthenticationMode::Silent)\n            {\n                result = GetTokenSilent(webAccount);\n            }\n        }\n        else\n        {\n            // Previous authentication successful. Just retrieve the token with the authenticated account.\n            // In rare cases silent flow fails, use interactive flow.\n            result = GetTokenSilent(m_authenticatedAccount);\n            if (FAILED(result.Status) && m_authArgs.Mode != AuthenticationMode::Silent)\n            {\n                result = GetToken(m_authenticatedAccount);\n            }\n        }\n\n        AICLI_LOG(Core, Info, << \"Finished WebAccountManagerAuthenticator::AuthenticateForToken. Result: \" << result.Status);\n\n        return result;\n    }\n\n    WebAccount WebAccountManagerAuthenticator::FindWebAccount(std::string_view accountName)\n    {\n        AICLI_LOG(Core, Info, << \"FindWebAccount called. Desired Account: \" << accountName);\n\n        WebAccount result = nullptr;\n\n        if (IsMicrosoftEntraIdAuthenticationType())\n        {\n            auto findAccountsResult = WebAuthenticationCoreManager::FindAllAccountsAsync(m_webAccountProvider, s_MicrosoftEntraIdClientId).get();\n            if (findAccountsResult.Status() == FindAllWebAccountsStatus::Success)\n            {\n                for (auto const& account : findAccountsResult.Accounts())\n                {\n                    if (Utility::CaseInsensitiveEquals(accountName, Utility::ConvertToUTF8(account.UserName())))\n                    {\n                        result = account;\n                        break;\n                    }\n                }\n            }\n            else\n            {\n                AICLI_LOG(Core, Warning, << \"FindAllAccountsAsync failed. Status: \" << findAccountsResult.Status());\n                auto providerError = findAccountsResult.ProviderError();\n                if (providerError)\n                {\n                    AICLI_LOG(Core, Warning,\n                        << \"FindAllAccountsAsync Provider Error. ErrorCode: \" << providerError.ErrorCode()\n                        << \", Message: \" << Utility::ConvertToUTF8(providerError.ErrorMessage()));\n                }\n            }\n        }\n\n        AICLI_LOG(Core, Info, << \"FindWebAccount result: \" << ((result != nullptr) ? \"found\" : \"not found\"));\n\n        return result;\n    }\n\n    WebTokenRequest WebAccountManagerAuthenticator::CreateTokenRequest(bool forceInteractive)\n    {\n        WebTokenRequest request = nullptr;\n\n        if (IsMicrosoftEntraIdAuthenticationType())\n        {\n            request = WebTokenRequest\n            {\n                m_webAccountProvider,\n                Utility::ConvertToUTF16(m_authInfo.MicrosoftEntraIdInfo->Scope),\n                s_MicrosoftEntraIdClientId,\n                forceInteractive ? WebTokenRequestPromptType::ForceAuthentication : WebTokenRequestPromptType::Default\n            };\n\n            request.Properties().Insert(s_MicrosoftEntraIdResourceHeader, Utility::ConvertToUTF16(m_authInfo.MicrosoftEntraIdInfo->Resource));\n            if (!m_authArgs.AuthenticationAccount.empty())\n            {\n                request.Properties().Insert(s_MicrosoftEntraIdLoginHintHeader, Utility::ConvertToUTF16(m_authArgs.AuthenticationAccount));\n            }\n        }\n\n        return request;\n    }\n\n    AuthenticationResult WebAccountManagerAuthenticator::GetToken(WebAccount webAccount, bool forceInteractive)\n    {\n        AICLI_LOG(Core, Info, << \"Started GetToken. ForceInteractive: \" << forceInteractive);\n\n        auto request = CreateTokenRequest(forceInteractive);\n        if (!request)\n        {\n            AICLI_LOG(Core, Error, << \"CreateTokenRequest returned empty request\");\n            return {};\n        }\n\n        IAsyncOperation<WebTokenRequestResult> requestOperation;\n        constexpr winrt::guid iidAsyncRequestResult{ winrt::guid_of<IAsyncOperation<WebTokenRequestResult>>() };\n        auto authManagerFactory = winrt::get_activation_factory<WebAuthenticationCoreManager>();\n        winrt::com_ptr<IWebAuthenticationCoreManagerInterop> authManagerInterop{ authManagerFactory.as<IWebAuthenticationCoreManagerInterop>() };\n\n        HRESULT requestOperationResult = APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED;\n        AuthenticationWindowBase parentWindow;\n        if (webAccount)\n        {\n            requestOperationResult = authManagerInterop->RequestTokenWithWebAccountForWindowAsync(\n                parentWindow.GetHandle(),\n                request.as<::IInspectable>().get(),\n                webAccount.as<::IInspectable>().get(),\n                iidAsyncRequestResult,\n                reinterpret_cast<void**>(&requestOperation));\n        }\n        else\n        {\n            requestOperationResult = authManagerInterop->RequestTokenForWindowAsync(\n                parentWindow.GetHandle(),\n                request.as<::IInspectable>().get(),\n                iidAsyncRequestResult,\n                reinterpret_cast<void**>(&requestOperation));\n        }\n\n        if (FAILED(requestOperationResult))\n        {\n            AICLI_LOG(Core, Error, << \"RequestTokenForWindowAsync failed. Result: \" << requestOperationResult);\n            return {};\n        }\n\n        return HandleGetTokenResult(requestOperation.get());\n    }\n\n    AuthenticationResult WebAccountManagerAuthenticator::GetTokenSilent(WebAccount webAccount)\n    {\n        AICLI_LOG(Core, Info, << \"Started GetTokenSilent.\");\n\n        auto request = CreateTokenRequest(false);\n        if (!request)\n        {\n            AICLI_LOG(Core, Error, << \"CreateTokenRequest returned empty request\");\n            return {};\n        }\n\r\n        if (webAccount)\r\n        {\r\n            return HandleGetTokenResult(WebAuthenticationCoreManager::GetTokenSilentlyAsync(request, webAccount).get());\n        }\r\n        else\r\n        {\r\n            return HandleGetTokenResult(WebAuthenticationCoreManager::GetTokenSilentlyAsync(request).get());\n        }\n    }\n\n    AuthenticationResult WebAccountManagerAuthenticator::HandleGetTokenResult(WebTokenRequestResult requestResult)\n    {\n        AuthenticationResult result;\n\n        if (!requestResult)\n        {\n            AICLI_LOG(Core, Error, << \"WebTokenRequestResult is null\");\n            return result;\n        }\n\n        if (requestResult.ResponseStatus() == WebTokenRequestStatus::Success)\n        {\n            auto responseData = requestResult.ResponseData().GetAt(0);\n            auto authenticatedAccount = responseData.WebAccount();\n\n            // Check token's corresponding account matches user input if applicable.\n            if (m_authArgs.AuthenticationAccount.empty() || Utility::CaseInsensitiveEquals(m_authArgs.AuthenticationAccount, Utility::ConvertToUTF8(authenticatedAccount.UserName())))\n            {\n                result.Status = S_OK;\n                result.Token = Utility::ConvertToUTF8(responseData.Token());\n                // Assign authenticated account for future token retrieval.\n                m_authenticatedAccount = authenticatedAccount;\n                AICLI_LOG(Core, Info, << \"Authentication success\");\n            }\n            else\n            {\n                AICLI_LOG(Core, Error, << \"Authentication success. But the authenticated account is not the desired one.\");\n                result.Status = APPINSTALLER_CLI_ERROR_AUTHENTICATION_INCORRECT_ACCOUNT;\n            }\n        }\n        else if (requestResult.ResponseStatus() == WebTokenRequestStatus::AccountSwitch)\n        {\n            AICLI_LOG(Core, Error, << \"Authentication failed. The authenticated account is not the desired one.\");\n            result.Status = APPINSTALLER_CLI_ERROR_AUTHENTICATION_INCORRECT_ACCOUNT;\n        }\n        else if (requestResult.ResponseStatus() == WebTokenRequestStatus::ProviderError ||\n            requestResult.ResponseStatus() == WebTokenRequestStatus::AccountProviderNotAvailable)\n        {\n            AICLI_LOG(Core, Error, << \"Authentication failed. Provider failed.\");\n            auto responseError = requestResult.ResponseError();\n            if (responseError)\n            {\n                AICLI_LOG(Core, Error, << \"Provider Error. Code: \" << responseError.ErrorCode() << \", Message: \" << Utility::ConvertToUTF8(responseError.ErrorMessage()));\n            }\n            result.Status = APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED;\n        }\n        else if (requestResult.ResponseStatus() == WebTokenRequestStatus::UserCancel)\n        {\n            AICLI_LOG(Core, Error, << \"Authentication failed. User cancelled.\");\n            result.Status = APPINSTALLER_CLI_ERROR_AUTHENTICATION_CANCELLED_BY_USER;\n        }\n        else if (requestResult.ResponseStatus() == WebTokenRequestStatus::UserInteractionRequired)\n        {\n            AICLI_LOG(Core, Error, << \"Authentication failed. Interactive authentication required.\");\n            result.Status = APPINSTALLER_CLI_ERROR_AUTHENTICATION_INTERACTIVE_REQUIRED;\n        }\n\n        AICLI_LOG(Core, Info, << \"HandleGetTokenResult Result: \" << result.Status);\n\n        return result;\n    }\r\n\n    bool WebAccountManagerAuthenticator::IsMicrosoftEntraIdAuthenticationType()\n    {\n        return m_authInfo.Type == AuthenticationType::MicrosoftEntraId || m_authInfo.Type == AuthenticationType::MicrosoftEntraIdForAzureBlobStorage;\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Authentication/WebAccountManagerAuthenticator.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <atomic>\r\n#include \"Public/winget/Authentication.h\"\r\n#include <winrt/Windows.Security.Authentication.Web.Core.h>\r\n#include <winrt/Windows.Security.Credentials.h>\r\n\r\nnamespace AppInstaller::Authentication\r\n{\r\n    struct WebAccountManagerAuthenticator : public IAuthenticationProvider\r\n    {\r\n        WebAccountManagerAuthenticator(AuthenticationInfo info, AuthenticationArguments args);\r\n\r\n        AuthenticationResult AuthenticateForToken();\r\n\r\n    private:\r\n        AuthenticationInfo m_authInfo;\r\n        AuthenticationArguments m_authArgs;\r\n        winrt::Windows::Security::Credentials::WebAccountProvider m_webAccountProvider = nullptr;\r\n        winrt::Windows::Security::Credentials::WebAccount m_authenticatedAccount = nullptr;\r\n        std::mutex m_authLock;\r\n\r\n        winrt::Windows::Security::Credentials::WebAccount FindWebAccount(std::string_view accountName);\r\n        winrt::Windows::Security::Authentication::Web::Core::WebTokenRequest CreateTokenRequest(bool forceInteractive);\r\n        AuthenticationResult GetToken(winrt::Windows::Security::Credentials::WebAccount webAccount, bool forceInteractive = false);\r\n        AuthenticationResult GetTokenSilent(winrt::Windows::Security::Credentials::WebAccount webAccount);\r\n        AuthenticationResult HandleGetTokenResult(winrt::Windows::Security::Authentication::Web::Core::WebTokenRequestResult requestResult);\r\n\r\n        bool IsMicrosoftEntraIdAuthenticationType();\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/DODownloader.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"DODownloader.h\"\r\n#include \"Public/AppInstallerLogging.h\"\r\n#include \"Public/AppInstallerSHA256.h\"\r\n#include \"Public/AppInstallerStrings.h\"\r\n#include \"winget/UserSettings.h\"\r\n\r\n// TODO: Get this from the Windows SDK when available\r\n#define DODownloadProperty_HttpRedirectionTarget static_cast<DODownloadProperty>(DODownloadProperty_NonVolatile + 1)\r\n#define DODownloadProperty_HttpResponseHeaders static_cast<DODownloadProperty>(DODownloadProperty_HttpRedirectionTarget + 1)\r\n#define DODownloadProperty_HttpServerIPAddress static_cast<DODownloadProperty>(DODownloadProperty_HttpResponseHeaders + 1)\r\n#define DODownloadProperty_HttpStatusCode static_cast<DODownloadProperty>(DODownloadProperty_HttpServerIPAddress + 1)\r\n\r\nnamespace AppInstaller::Utility\r\n{\r\n    namespace\r\n    {\r\n        std::optional<std::string> ExtractContentType(const std::optional<std::string>& headers)\r\n        {\r\n            if (!headers)\r\n            {\r\n                return std::nullopt;\r\n            }\r\n\r\n            static constexpr std::string_view s_ContentType = \"content-type:\"sv;\r\n            auto headerLines = Utility::SplitIntoLines(headers.value());\r\n\r\n            for (const auto& header : headerLines)\r\n            {\r\n                std::string_view headerView = header;\r\n                if (header.length() >= s_ContentType.length())\r\n                {\r\n                    std::string lowerFragment = ToLower(headerView.substr(0, s_ContentType.length()));\r\n                    if (s_ContentType == lowerFragment)\r\n                    {\r\n                        return Trim(header.substr(s_ContentType.length()));\r\n                    }\r\n                }\r\n            }\r\n\r\n            return std::nullopt;\r\n        }\r\n    }\r\n\r\n    namespace DeliveryOptimization\r\n    {\r\n        // Represents a download work item for Delivery Optimization.\r\n        struct Download\r\n        {\r\n            Download(IDOManager* manager)\r\n            {\r\n                THROW_IF_FAILED(manager->CreateDownload(&m_download));\r\n\r\n                // Cloaking - sets the authentication information that will be used to make calls on the DO interface proxy.\r\n                // This will make sure DO server impersonates the correct client identity.\r\n                THROW_IF_FAILED(CoSetProxyBlanket(\r\n                    m_download.get(),\r\n                    RPC_C_AUTHN_DEFAULT,\r\n                    RPC_C_AUTHZ_DEFAULT,\r\n                    COLE_DEFAULT_PRINCIPAL,\r\n                    RPC_C_AUTHN_LEVEL_DEFAULT,\r\n                    RPC_C_IMP_LEVEL_IMPERSONATE,\r\n                    NULL,\r\n                    EOAC_DEFAULT));\r\n            }\r\n\r\n            ~Download()\r\n            {\r\n                DO_DOWNLOAD_STATUS downloadStatus;\r\n                if (SUCCEEDED_LOG(m_download->GetStatus(&downloadStatus)))\r\n                {\r\n                    if (downloadStatus.State == DODownloadState_Transferred)\r\n                    {\r\n                        // Calling IDODownload::Finalize() to inform DO that the DO job can be cleaned up.\r\n                        // Otherwise, the resources associated with the job can be kept for a number of days\r\n                        // until expiration set by DO.\r\n                        (void)LOG_IF_FAILED(m_download->Finalize());\r\n                    }\r\n                    else if (downloadStatus.State != DODownloadState_Finalized)\r\n                    {\r\n                        // For any other state, abort the download since it's no longer in use.\r\n                        // This will allow DO to clean up the cache for the associated content ID.\r\n                        (void)LOG_IF_FAILED(m_download->Abort());\r\n                    }\r\n                }\r\n            }\r\n\r\n            void SetProperty(DODownloadProperty prop, const std::wstring& value)\r\n            {\r\n                wil::unique_variant var;\r\n                var.bstrVal = ::SysAllocString(value.c_str());\r\n                THROW_IF_NULL_ALLOC(var.bstrVal);\r\n                var.vt = VT_BSTR;\r\n                THROW_IF_FAILED(m_download->SetProperty(prop, &var));\r\n            }\r\n\r\n            void SetProperty(DODownloadProperty prop, std::string_view value)\r\n            {\r\n                SetProperty(prop, Utility::ConvertToUTF16(value));\r\n            }\r\n\r\n            void SetProperty(DODownloadProperty prop, uint32_t value)\r\n            {\r\n                wil::unique_variant var;\r\n                var.ulVal = value;\r\n                var.vt = VT_UI4;\r\n                THROW_IF_FAILED(m_download->SetProperty(prop, &var));\r\n            }\r\n\r\n            void SetProperty(DODownloadProperty prop, bool value)\r\n            {\r\n                wil::unique_variant var;\r\n                var.boolVal = value ? VARIANT_TRUE : VARIANT_FALSE;\r\n                var.vt = VT_BOOL;\r\n                THROW_IF_FAILED(m_download->SetProperty(prop, &var));\r\n            }\r\n\r\n            template<typename T>\r\n            void SetUnknownProperty(DODownloadProperty prop, T&& value)\r\n            {\r\n                wil::unique_variant var;\r\n                var.punkVal = nullptr;\r\n                var.vt = VT_UNKNOWN;\r\n                if (value)\r\n                {\r\n                    THROW_IF_FAILED(value->QueryInterface(IID_PPV_ARGS(&var.punkVal)));\r\n                }\r\n                THROW_IF_FAILED(m_download->SetProperty(prop, &var));\r\n            }\r\n\r\n            template<typename T>\r\n            std::optional<T> TryGetProperty(DODownloadProperty prop)\r\n            {\r\n                std::optional<T> result;\r\n                wil::unique_variant var;\r\n                HRESULT hr = m_download->GetProperty(prop, &var);\r\n                if (SUCCEEDED(hr))\r\n                {\r\n                    T value;\r\n                    if (ExtractFromVariant(var, value))\r\n                    {\r\n                        result = std::move(value);\r\n                    }\r\n                }\r\n                return result;\r\n            }\r\n\r\n            void Uri(std::string_view uri)\r\n            {\r\n                SetProperty(DODownloadProperty_Uri, uri);\r\n            }\r\n\r\n            void ContentId(std::string_view contentId)\r\n            {\r\n                SetProperty(DODownloadProperty_ContentId, contentId);\r\n            }\r\n\r\n            void DisplayName(std::string_view displayName)\r\n            {\r\n                SetProperty(DODownloadProperty_DisplayName, displayName);\r\n            }\r\n\r\n            void LocalPath(const std::filesystem::path& localPath)\r\n            {\r\n                SetProperty(DODownloadProperty_LocalPath, localPath.wstring());\r\n            }\r\n\r\n            void CorrelationVector(std::string_view correlationVector)\r\n            {\r\n                SetProperty(DODownloadProperty_CorrelationVector, correlationVector);\r\n            }\r\n\r\n            void NoProgressTimeoutSeconds(uint32_t noProgressTimeoutSeconds)\r\n            {\r\n                SetProperty(DODownloadProperty_NoProgressTimeoutSeconds, noProgressTimeoutSeconds);\r\n            }\r\n\r\n            void ForegroundPriority(bool foregroundPriority)\r\n            {\r\n                SetProperty(DODownloadProperty_ForegroundPriority, foregroundPriority);\r\n            }\r\n\r\n            void BlockingMode(bool blockingMode)\r\n            {\r\n                SetProperty(DODownloadProperty_BlockingMode, blockingMode);\r\n            }\r\n\r\n            void CallbackInterface(IDODownloadStatusCallback* callbackInterface)\r\n            {\r\n                SetUnknownProperty(DODownloadProperty_CallbackInterface, callbackInterface);\r\n            }\r\n\r\n            void StreamInterface(IStream* streamInterface)\r\n            {\r\n                SetUnknownProperty(DODownloadProperty_StreamInterface, streamInterface);\r\n            }\r\n\r\n            void CustomHeaders(const std::vector<DownloadRequestHeader>& headers)\r\n            {\r\n                // DODownloadProperty_HttpCustomAuthHeaders is not used (does not work in our auth scenario). It is only used when challenged.\r\n                std::string customHeaders;\r\n                for (const auto& header : headers)\r\n                {\r\n                    customHeaders += header.Name + \": \" + header.Value + \"\\r\\n\";\r\n                }\r\n\r\n                if (!customHeaders.empty())\r\n                {\r\n                    SetProperty(DODownloadProperty_HttpCustomHeaders, customHeaders);\r\n                }\r\n            }\r\n\r\n            // Properties that may be interesting for future use:\r\n            // https://docs.microsoft.com/en-us/windows/win32/delivery_optimization/deliveryoptimizationdownloadtypes/ne-deliveryoptimizationdownloadtypes-dodownloadproperty\r\n            //  - DODownloadProperty_CostPolicy :: Allow user to specify how to behave on metered networks\r\n\r\n            void Start()\r\n            {\r\n                DO_DOWNLOAD_RANGES_INFO emptyRanges{};\r\n                emptyRanges.RangeCount = 0;\r\n                THROW_IF_FAILED(m_download->Start(&emptyRanges));\r\n            }\r\n\r\n            // Returns true if Abort was successful; false if not.\r\n            bool Cancel()\r\n            {\r\n                return SUCCEEDED_LOG(m_download->Abort());\r\n            }\r\n\r\n            void Finalize()\r\n            {\r\n                THROW_IF_FAILED(m_download->Finalize());\r\n            }\r\n\r\n            DO_DOWNLOAD_STATUS Status()\r\n            {\r\n                DO_DOWNLOAD_STATUS result{};\r\n                THROW_IF_FAILED(m_download->GetStatus(&result));\r\n                return result;\r\n            }\r\n\r\n        private:\r\n            bool ExtractFromVariant(const VARIANT& var, std::string& value)\r\n            {\r\n                if (var.vt == VT_BSTR && var.bstrVal != nullptr)\r\n                {\r\n                    value = Utility::ConvertToUTF8(var.bstrVal);\r\n                    return true;\r\n                }\r\n                else if (var.vt == (VT_BSTR | VT_BYREF) && var.pbstrVal != nullptr && *var.pbstrVal != nullptr)\r\n                {\r\n                    value = Utility::ConvertToUTF8(*var.pbstrVal);\r\n                    return true;\r\n                }\r\n\r\n                return false;\r\n            }\r\n\r\n            wil::com_ptr<IDODownload> m_download;\r\n        };\r\n\r\n        // The top level Delivery Optimization manager object.\r\n        struct Manager\r\n        {\r\n            Manager()\r\n            {\r\n                THROW_IF_FAILED(CoCreateInstance(\r\n                    __uuidof(::DeliveryOptimization),\r\n                    nullptr,\r\n                    CLSCTX_LOCAL_SERVER,\r\n                    IID_PPV_ARGS(&m_manager)));\r\n            }\r\n\r\n            Download CreateDownload()\r\n            {\r\n                return { m_manager.get() };\r\n            }\r\n\r\n        private:\r\n            wil::com_ptr<IDOManager> m_manager;\r\n        };\r\n\r\n        // Status callback handler\r\n        class DODownloadStatusCallback : public Microsoft::WRL::RuntimeClass<\r\n            Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>,\r\n            IDODownloadStatusCallback>\r\n        {\r\n        public:\r\n            DODownloadStatusCallback(IProgressCallback& progress) :\r\n                m_progress(progress)\r\n            {\r\n            }\r\n\r\n            IFACEMETHOD(OnStatusChange)(IDODownload*, const DO_DOWNLOAD_STATUS* status)\r\n            {\r\n                {\r\n                    std::lock_guard<std::mutex> guard(m_statusMutex);\r\n                    m_currentStatus = *status;\r\n                }\r\n                m_statusCV.notify_all();\r\n                return S_OK;\r\n            }\r\n\r\n            static HRESULT Create(\r\n                IProgressCallback& progress,\r\n                DODownloadStatusCallback** result)\r\n            {\r\n                Microsoft::WRL::ComPtr<DODownloadStatusCallback> localResult = Microsoft::WRL::Make<DODownloadStatusCallback>(progress);\r\n                RETURN_IF_NULL_ALLOC(localResult);\r\n\r\n                *result = localResult.Detach();\r\n                return S_OK;\r\n            }\r\n\r\n            // Simply breaks the wait in Wait; the progress object must already be cancelled to force it out.\r\n            void Cancel()\r\n            {\r\n                m_statusCV.notify_all();\r\n            }\r\n\r\n            // Returns true on successful completion, false on cancellation, and throws on an error.\r\n            bool Wait()\r\n            {\r\n                std::unique_lock<std::mutex> lock(m_statusMutex);\r\n\r\n                // If there is no transfer status update for m_doNoProgressTimeout, we will fail.\r\n                auto timeoutTime = std::chrono::steady_clock::now() + Settings::User().Get<Settings::Setting::NetworkDOProgressTimeoutInSeconds>();\r\n                std::optional<UINT64> initialTransferAmount;\r\n                bool transferChange = false;\r\n\r\n                while (!m_progress.IsCancelledBy(CancelReason::Any))\r\n                {\r\n                    if (!transferChange)\r\n                    {\r\n                        if (m_statusCV.wait_until(lock, timeoutTime) == std::cv_status::timeout)\r\n                        {\r\n                            THROW_HR(DO_E_DOWNLOAD_NO_PROGRESS);\r\n                        }\r\n                    }\r\n                    else\r\n                    {\r\n                        m_statusCV.wait(lock);\r\n                    }\r\n\r\n                    // Since we just finished a wait, check for cancellation before handling anything else\r\n                    if (m_progress.IsCancelledBy(CancelReason::Any))\r\n                    {\r\n                        return false;\r\n                    }\r\n\r\n                    AICLI_LOG(Core, Verbose, << \"DO State \" << m_currentStatus.State << \", \" << m_currentStatus.BytesTransferred << \" / \" << m_currentStatus.BytesTotal <<\r\n                        \", Error 0x\" << Logging::SetHRFormat << m_currentStatus.Error << \", extended error 0x\" << Logging::SetHRFormat << m_currentStatus.ExtendedError);\r\n\r\n                    // No matter the state, we are considering any error set to be a failure\r\n                    if (FAILED(m_currentStatus.Error))\r\n                    {\r\n                        AICLI_LOG(Core, Error, << \"DeliveryOptimization error: 0x\" << Logging::SetHRFormat << m_currentStatus.Error <<\r\n                            \", extended error: 0x\" << Logging::SetHRFormat << m_currentStatus.ExtendedError);\r\n                        THROW_HR(m_currentStatus.Error);\r\n                    }\r\n\r\n                    switch (m_currentStatus.State)\r\n                    {\r\n                        // These states are ignored.\r\n                    case DODownloadState_Created:\r\n                    case DODownloadState_Paused:\r\n                        break;\r\n\r\n                    case DODownloadState_Transferring:\r\n                        if (m_currentStatus.BytesTransferred || m_currentStatus.BytesTotal)\r\n                        {\r\n                            m_progress.OnProgress(m_currentStatus.BytesTransferred, m_currentStatus.BytesTotal, ProgressType::Bytes);\r\n                        }\r\n\r\n                        if (!initialTransferAmount)\r\n                        {\r\n                            initialTransferAmount = m_currentStatus.BytesTransferred;\r\n                        }\r\n                        else if (m_currentStatus.BytesTransferred != initialTransferAmount.value())\r\n                        {\r\n                            transferChange = true;\r\n                        }\r\n                        break;\r\n\r\n                        // These are considered to be 'done'\r\n                    case DODownloadState_Transferred:\r\n                    case DODownloadState_Finalized:\r\n                        if (m_currentStatus.BytesTransferred || m_currentStatus.BytesTotal)\r\n                        {\r\n                            m_progress.OnProgress(m_currentStatus.BytesTransferred, m_currentStatus.BytesTotal, ProgressType::Bytes);\r\n                        }\r\n                        return true;\r\n\r\n                        // This is the cancelled state\r\n                    case DODownloadState_Aborted:\r\n                        return false;\r\n                    }\r\n                }\r\n\r\n                return false;\r\n            }\r\n\r\n        private:\r\n            IProgressCallback& m_progress;\r\n            std::mutex m_statusMutex;\r\n            std::condition_variable m_statusCV;\r\n            DO_DOWNLOAD_STATUS m_currentStatus = {};\r\n        };\r\n    }\r\n\r\n    // Debugging tip:\r\n    // From an elevated PowerShell, run:\r\n    // > Get-DeliveryOptimizationLog | Set-Content doLogs.txt\r\n    DownloadResult DODownload(\r\n        const std::string& url,\r\n        const std::filesystem::path& dest,\r\n        IProgressCallback& progress,\r\n        std::optional<DownloadInfo> info)\r\n    {\r\n        AICLI_LOG(Core, Info, << \"DeliveryOptimization downloading from url: \" << url);\r\n\r\n        // Remove the target file since DO will not overwrite\r\n        std::filesystem::remove(dest);\r\n\r\n        DeliveryOptimization::Manager manager;\r\n        DeliveryOptimization::Download download = manager.CreateDownload();\r\n\r\n        wil::com_ptr<DeliveryOptimization::DODownloadStatusCallback> callback;\r\n        THROW_IF_FAILED(DeliveryOptimization::DODownloadStatusCallback::Create(progress, &callback));\r\n\r\n        download.Uri(url);\r\n        download.ForegroundPriority(true);\r\n        download.LocalPath(dest);\r\n        download.CallbackInterface(callback.get());\r\n\r\n        if (info)\r\n        {\r\n            if (!info->DisplayName.empty())\r\n            {\r\n                download.DisplayName(info->DisplayName);\r\n            }\r\n\r\n            if (!info->ContentId.empty())\r\n            {\r\n                download.ContentId(info->ContentId);\r\n            }\r\n\r\n            if (!info->RequestHeaders.empty())\r\n            {\r\n                download.CustomHeaders(info->RequestHeaders);\r\n            }\r\n        }\r\n\r\n        download.Start();\r\n\r\n        auto cancelLifetime = progress.SetCancellationFunction([&download, &callback]()\r\n            {\r\n                AICLI_LOG(Core, Info, << \"Download cancelled.\");\r\n                download.Cancel();\r\n                callback->Cancel();\r\n            });\r\n\r\n        // Check to handle cancellation between Start and SetCancellationFunction\r\n        if (progress.IsCancelledBy(CancelReason::Any))\r\n        {\r\n            AICLI_LOG(Core, Info, << \"Download cancelled.\");\r\n            download.Cancel();\r\n            return {};\r\n        }\r\n\r\n        // Wait returns true for success, false for cancellation, and throws on error.\r\n        if (callback->Wait())\r\n        {\r\n            // Grab the headers so that we can use them later\r\n            std::optional<std::string> responseHeaders = download.TryGetProperty<std::string>(DODownloadProperty_HttpResponseHeaders);\r\n\r\n            // Finalize is required to flush the data and change the file name.\r\n            download.Finalize();\r\n            AICLI_LOG(Core, Info, << \"Download completed.\");\r\n\r\n            std::ifstream inStream{ dest, std::ifstream::binary };\r\n            auto hashDetails = SHA256::ComputeHashDetails(inStream);\r\n\r\n            DownloadResult result;\r\n            result.Sha256Hash = std::move(hashDetails.Hash);\r\n            result.SizeInBytes = hashDetails.SizeInBytes;\r\n            result.ContentType = ExtractContentType(responseHeaders);\r\n\r\n            return result;\r\n        }\r\n\r\n        return {};\r\n    }\r\n\r\n    bool IsDOErrorFatal(HRESULT error)\r\n    {\r\n        // If this gets to be large, store in a sorted array and binary search on it.\r\n        // There will be more to update here, which we should be able to discover through telemetry.\r\n        return\r\n            error == DO_E_BLOCKED_BY_COST_TRANSFER_POLICY ||\r\n            error == DO_E_BLOCKED_BY_CELLULAR_POLICY ||\r\n            error == DO_E_BLOCKED_BY_POWER_STATE ||\r\n            error == DO_E_BLOCKED_BY_NO_NETWORK;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/DODownloader.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerDownloader.h>\r\n#include <AppInstallerProgress.h>\r\n\r\n#include <optional>\r\n#include <ostream>\r\n#include <string>\r\n#include <vector>\r\n\r\nnamespace AppInstaller::Utility\r\n{\r\n    // Downloads a file from the given URL and places it in the given location.\r\n    //   url: The url to be downloaded from. http->https redirection is allowed.\r\n    //   dest: The stream to be downloaded to.\r\n    //   computeHash: Optional. Indicates if SHA256 hash should be calculated when downloading.\r\n    DownloadResult DODownload(\r\n        const std::string& url,\r\n        const std::filesystem::path& dest,\r\n        IProgressCallback& progress,\r\n        std::optional<DownloadInfo> info);\r\n\r\n    // Returns true if the error from DODownload should be treated as fatal;\r\n    // false if we should be able to fall back to other download methods.\r\n    bool IsDOErrorFatal(HRESULT error);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Debugging.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/Debugging.h\"\r\n#include \"Public/AppInstallerRuntime.h\"\r\n#include \"Public/AppInstallerDateTime.h\"\r\n\r\nnamespace AppInstaller::Debugging\r\n{\r\n    namespace\r\n    {\r\n        constexpr std::string_view c_minidumpPrefix = \"Minidump\";\r\n        constexpr std::string_view c_minidumpExtension = \".mdmp\";\r\n\r\n        struct SelfInitiatedMinidumpHelper\r\n        {\r\n            SelfInitiatedMinidumpHelper() = default;\r\n\r\n            ~SelfInitiatedMinidumpHelper()\r\n            {\r\n                if (!m_keepFile)\r\n                {\r\n                    m_file.reset();\r\n                    DeleteFile(m_filePath.wstring().c_str());\r\n                }\r\n            }\r\n\r\n            static SelfInitiatedMinidumpHelper& Instance()\r\n            {\r\n                static SelfInitiatedMinidumpHelper instance;\r\n                return instance;\r\n            }\r\n\r\n            static LONG WINAPI UnhandledExceptionCallback(EXCEPTION_POINTERS* ExceptionInfo)\r\n            {\r\n                MINIDUMP_EXCEPTION_INFORMATION exceptionInformation{};\r\n                // The unhandled exception filter is executed in the context of the failing thread.\r\n                exceptionInformation.ThreadId = GetCurrentThreadId();\r\n                exceptionInformation.ExceptionPointers = ExceptionInfo;\r\n                exceptionInformation.ClientPointers = FALSE;\r\n\r\n                std::thread([&]() {\r\n                    MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), Instance().m_file.get(), MiniDumpNormal, &exceptionInformation, nullptr, nullptr);\r\n                    Instance().m_keepFile = true;\r\n                }).join();\r\n\r\n                return EXCEPTION_CONTINUE_SEARCH;\r\n            }\r\n\r\n            SelfInitiatedMinidumpHelper& Enable(const std::filesystem::path& filePath = {})\r\n            {\r\n                std::call_once(m_enableFlag, [&]()\r\n                    {\r\n                        if (filePath.empty())\r\n                        {\r\n                            m_filePath = Runtime::GetPathTo(Runtime::PathName::DefaultLogLocation);\r\n                            m_filePath /= c_minidumpPrefix.data() + ('-' + Utility::GetCurrentTimeForFilename() + c_minidumpExtension.data());\r\n                        }\r\n                        else\r\n                        {\r\n                            m_filePath = filePath;\r\n                        }\r\n\r\n                        m_file.reset(CreateFile(m_filePath.wstring().c_str(), GENERIC_READ | GENERIC_WRITE,\r\n                            FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr));\r\n                        THROW_LAST_ERROR_IF(!m_file);\r\n\r\n                        SetUnhandledExceptionFilter(UnhandledExceptionCallback);\r\n                    });\r\n\r\n                return *this;\r\n            }\r\n\r\n            void WriteMinidump()\r\n            {\r\n                std::thread([&]() {\r\n                    MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), Instance().m_file.get(), MiniDumpNormal, nullptr, nullptr, nullptr);\r\n                    Instance().m_keepFile = true;\r\n                    }).join();\r\n            }\r\n\r\n        private:\r\n            std::once_flag m_enableFlag;\r\n            std::filesystem::path m_filePath;\r\n            wil::unique_handle m_file;\r\n            std::atomic_bool m_keepFile{ false };\r\n        };\r\n    }\r\n\r\n    void EnableSelfInitiatedMinidump()\r\n    {\r\n        SelfInitiatedMinidumpHelper::Instance().Enable();\r\n    }\r\n\r\n    void EnableSelfInitiatedMinidump(const std::filesystem::path& filePath)\r\n    {\r\n        SelfInitiatedMinidumpHelper::Instance().Enable(filePath);\r\n    }\r\n\r\n    void WriteMinidump()\r\n    {\r\n        SelfInitiatedMinidumpHelper::Instance().Enable().WriteMinidump();\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/DependenciesGraph.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"winget\\DependenciesGraph.h\"\n\nnamespace AppInstaller::Manifest\n{\n    // this constructor was intented for use during installation flow (we already have installer dependencies and there's no need to search the source again)\n    DependencyGraph::DependencyGraph(const Dependency& root, const DependencyList& rootDependencies,\n        std::function<const DependencyList(const Dependency&)> infoFunction) : m_root(root), getDependencies(infoFunction)\n    {\n        m_adjacents[m_root] = std::set<Dependency>();\n        m_toCheck = std::vector<Dependency>();\n        rootDependencies.ApplyToType(DependencyType::Package, [&](Dependency dependency)\n            {\n                m_toCheck.push_back(dependency);\n                AddNode(dependency);\n                AddAdjacent(root, dependency);\n            });\n        m_rootDependencyEvaluated = true;\n    }\n\n    DependencyGraph::DependencyGraph(const Dependency& root, std::function<const DependencyList(const Dependency&)> infoFunction) : m_root(root), getDependencies(infoFunction)\n    {\n        m_adjacents[m_root] = std::set<Dependency>();\n        m_toCheck = std::vector<Dependency>();\n    }\n\n    void DependencyGraph::BuildGraph()\n    {\n        if (!m_rootDependencyEvaluated) \n        {\n            const DependencyList& rootDependencies = getDependencies(m_root);\n            rootDependencies.ApplyToType(DependencyType::Package, [&](Dependency dependency)\n                {\n                    m_toCheck.push_back(dependency);\n                    AddNode(dependency);\n                    AddAdjacent(m_root, dependency);\n                });\n            m_rootDependencyEvaluated = true;\n        }\n\n        if (m_toCheck.empty())\n        {\n            return;\n        }\n\n        for (unsigned int i = 0; i < m_toCheck.size(); ++i)\n        {\n            auto node = m_toCheck.at(i);\n\n            const auto& nodeDependencies = getDependencies(node);\n            nodeDependencies.ApplyToType(DependencyType::Package, [&](Dependency dependency)\n                {\n                    if (!HasNode(dependency))\n                    {\n                        m_toCheck.push_back(dependency);\n                        AddNode(dependency);\n                    }\n\n                    AddAdjacent(node, dependency);\n                });\n        }\n\n        CheckForLoopsAndGetOrder();\n    }\n\n    void DependencyGraph::AddNode(const Dependency& node)\n    {\n        m_adjacents[node] = std::set<Dependency>();\n    }\n\n    void DependencyGraph::AddAdjacent(const Dependency& node, const Dependency& adjacent)\n    {\n        m_adjacents[node].emplace(adjacent);\n    }\n\n    bool DependencyGraph::HasNode(const Dependency& dependency)\n    {\n        auto search = m_adjacents.find(dependency);\n        return search != m_adjacents.end();\n    }\n\n    bool DependencyGraph::HasLoop()\n    {\n        return m_HasLoop;\n    }\n\n    void DependencyGraph::CheckForLoopsAndGetOrder()\n    {\n        m_installationOrder = std::vector<Dependency>();\n        std::set<Dependency> visited;\n        m_HasLoop = HasLoopDFS(visited, m_root);\n    }\n\n    std::vector<Dependency> DependencyGraph::GetInstallationOrder()\n    {\n        return m_installationOrder;\n    }\n\n    // TODO make this function iterative\n    bool DependencyGraph::HasLoopDFS(std::set<Dependency> visited, const Dependency& node)\n    {\n        bool loop = false;\n\n        visited.insert(node);\n        auto lAdjacents = m_adjacents.at(node);\n        for (const auto& adjacent : m_adjacents.at(node))\n        {\n            auto search = visited.find(adjacent);\n            if (search == visited.end()) // if not found\n            {\n                if (HasLoopDFS(visited, adjacent))\n                {\n                    loop = true;\n                    // didn't break the loop to have a complete order at the end (even if a loop exists)\n                }\n            }\n            else\n            {\n                loop = true;\n                // didn't break the loop to have a complete order at the end (even if a loop exists)\n            }\n        }\n\n        // Adding to have an order even if a loop is present\n        if (std::find(m_installationOrder.begin(), m_installationOrder.end(), node) == m_installationOrder.end())\n        {\n            m_installationOrder.push_back(node);\n        }\n\n        return loop;\n    }\n}"
  },
  {
    "path": "src/AppInstallerCommonCore/Deployment.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/AppInstallerDeployment.h\"\r\n#include \"Public/AppInstallerLogging.h\"\r\n#include \"Public/AppInstallerMsixInfo.h\"\r\n#include \"Public/AppInstallerRuntime.h\"\r\n#include \"Public/AppInstallerStrings.h\"\r\n\r\nnamespace AppInstaller::Deployment\r\n{\r\n    using namespace winrt::Windows::Foundation;\r\n    using namespace winrt::Windows::Management::Deployment;\r\n\r\n    namespace\r\n    {\r\n        size_t GetDeploymentOperationId()\r\n        {\r\n            static std::atomic_size_t s_deploymentId = 0;\r\n            return s_deploymentId.fetch_add(1);\r\n        }\r\n\r\n        HRESULT WaitForDeployment(\r\n            IAsyncOperationWithProgress<DeploymentResult, DeploymentProgress>& deployOperation,\r\n            size_t id,\r\n            IProgressCallback& callback,\r\n            bool throwOnError = true)\r\n        {\r\n            AICLI_LOG(Core, Info, << \"Begin waiting for operation #\" << id);\r\n\r\n            AsyncOperationProgressHandler<DeploymentResult, DeploymentProgress> progressCallback(\r\n                [&callback](const IAsyncOperationWithProgress<DeploymentResult, DeploymentProgress>&, DeploymentProgress progress)\r\n                {\r\n                    callback.OnProgress(progress.percentage, 100, ProgressType::Percent);\r\n                }\r\n            );\r\n\r\n            // Set progress callback.\r\n            deployOperation.Progress(progressCallback);\r\n\r\n            auto removeCancel = callback.SetCancellationFunction([&]() { deployOperation.Cancel(); });\r\n\r\n            AICLI_LOG(Core, Info, << \"Begin blocking for operation #\" << id);\r\n\r\n            auto deployResult = deployOperation.get();\r\n\r\n            if (!SUCCEEDED(deployResult.ExtendedErrorCode()))\r\n            {\r\n                AICLI_LOG(Core, Error, << \"Deployment operation #\" << id << \": \" << Utility::ConvertToUTF8(deployResult.ErrorText()));\r\n\r\n                // Note that while the format string is char*, it gets converted to wchar before being used.\r\n                if (throwOnError)\r\n                {\r\n                    THROW_HR_MSG(deployResult.ExtendedErrorCode(), \"Operation failed: %ws\", deployResult.ErrorText().c_str());\r\n                }\r\n                else\r\n                {\r\n                    // Simple return because this path is generally used for recovery cases\r\n                    return deployResult.ExtendedErrorCode();\r\n                }\r\n            }\r\n            else\r\n            {\r\n                AICLI_LOG(Core, Info, << \"Successfully completed #\" << id);\r\n            }\r\n\r\n            return S_OK;\r\n        }\r\n\r\n        bool ShouldUseReputationCheck(const Options& options)\r\n        {\r\n            return options.ExpectedDigests.empty() && !options.SkipReputationCheck;\r\n        }\r\n\r\n        IAsyncOperationWithProgress<DeploymentResult, DeploymentProgress> StartAddPackage(PackageManager& packageManager, const winrt::Windows::Foundation::Uri& uri, const Options& options)\r\n        {\r\n            if (!options.ExpectedDigests.empty())\r\n            {\r\n                // Must use API that supports digests\r\n                THROW_WIN32_IF(ERROR_NOT_SUPPORTED, !IsExpectedDigestsSupported());\r\n\r\n                AddPackageOptions addPackageOptions;\r\n\r\n                for (const auto& digest : options.ExpectedDigests)\r\n                {\r\n                    addPackageOptions.ExpectedDigests().Insert(Uri{ Utility::ConvertToUTF16(digest.first) }, digest.second);\r\n                }\r\n\r\n                return packageManager.AddPackageByUriAsync(uri, addPackageOptions);\r\n            }\r\n            else if (options.SkipReputationCheck)\r\n            {\r\n                return packageManager.AddPackageAsync(\r\n                    uri,\r\n                    nullptr, /*dependencyPackageUris*/\r\n                    DeploymentOptions::None,\r\n                    nullptr, /*targetVolume*/\r\n                    nullptr, /*optionalAndRelatedPackageFamilyNames*/\r\n                    nullptr, /*optionalPackageUris*/\r\n                    nullptr /*relatedPackageUris*/);\r\n            }\r\n            else\r\n            {\r\n                return packageManager.RequestAddPackageAsync(\r\n                    uri,\r\n                    nullptr, /*dependencyPackageUris*/\r\n                    DeploymentOptions::None,\r\n                    nullptr, /*targetVolume*/\r\n                    nullptr, /*optionalAndRelatedPackageFamilyNames*/\r\n                    nullptr /*relatedPackageUris*/);\r\n            }\r\n        }\r\n\r\n        IAsyncOperationWithProgress<DeploymentResult, DeploymentProgress> StartStagePackage(PackageManager& packageManager, const winrt::Windows::Foundation::Uri& uri, const Options& options)\r\n        {\r\n            if (!options.ExpectedDigests.empty())\r\n            {\r\n                // Must use API that supports digests\r\n                THROW_WIN32_IF(ERROR_NOT_SUPPORTED, !IsExpectedDigestsSupported());\r\n\r\n                StagePackageOptions stagePackageOptions;\r\n\r\n                for (const auto& digest : options.ExpectedDigests)\r\n                {\r\n                    stagePackageOptions.ExpectedDigests().Insert(Uri{ Utility::ConvertToUTF16(digest.first) }, digest.second);\r\n                }\r\n\r\n                return packageManager.StagePackageByUriAsync(uri, stagePackageOptions);\r\n            }\r\n            else\r\n            {\r\n                return packageManager.StagePackageAsync(\r\n                    uri,\r\n                    nullptr /*dependencyPackageUris*/);\r\n            }\r\n        }\r\n    }\r\n\r\n    std::ostream& operator<<(std::ostream& out, const Options& options)\r\n    {\r\n        out << \" { SkipReputationCheck = \" << options.SkipReputationCheck << \", ExpectedDigests = {\";\r\n\r\n        for (const auto& digest : options.ExpectedDigests)\r\n        {\r\n            out << \" { URI = \" << digest.first << \", Digest = \" << Utility::ConvertToUTF8(digest.second) << \" } \";\r\n        }\r\n\r\n        out << \"} }\";\r\n\r\n        return out;\r\n    }\r\n\r\n    void AddPackage(\r\n        const winrt::Windows::Foundation::Uri& uri,\r\n        const Options& options,\r\n        IProgressCallback& callback)\r\n    {\r\n        size_t id = GetDeploymentOperationId();\r\n        AICLI_LOG(Core, Info, << \"Starting AddPackage operation #\" << id << \": \" << Utility::ConvertToUTF8(uri.AbsoluteUri().c_str()) << \" Options: \" << options);\r\n\r\n        PackageManager packageManager;\r\n\r\n        IAsyncOperationWithProgress<DeploymentResult, DeploymentProgress> deployOperation = StartAddPackage(packageManager, uri, options);\r\n\r\n        WaitForDeployment(deployOperation, id, callback);\r\n    }\r\n\r\n    bool AddPackageWithDeferredFallback(\r\n        std::string_view uri,\r\n        const Options& options,\r\n        IProgressCallback& callback)\r\n    {\r\n        PackageManager packageManager;\r\n\r\n        // In the event of a failure we want to ensure that the package is not left on the system.\r\n        // No need for proxy as Deployment won't use it anyways.\r\n        Msix::MsixInfo packageInfo{ uri };\r\n        std::wstring packageFullNameWide = packageInfo.GetPackageFullNameWide();\r\n        std::string packageFullName = Utility::ConvertToUTF8(packageFullNameWide);\r\n        auto removePackage = wil::scope_exit([&]() {\r\n            try\r\n            {\r\n                ProgressCallback cb;\r\n                RemovePackage(packageFullName, RemovalOptions::None, cb);\r\n            }\r\n            CATCH_LOG();\r\n            });\r\n\r\n        Uri uriObject(Utility::ConvertToUTF16(uri));\r\n\r\n        if (ShouldUseReputationCheck(options))\r\n        {\r\n            // The only way to get SmartScreen is to use RequestAddPackageAsync, so we will have to start with that.\r\n            size_t id = GetDeploymentOperationId();\r\n            AICLI_LOG(Core, Info, << \"Starting RequestAddPackageAsync operation #\" << id << \": \" << uri);\r\n\r\n            DeploymentOptions deploymentOptions = DeploymentOptions::None;\r\n            // Optimization to keep files if the package is in use. Only available in a newer OS per:\r\n            // https://docs.microsoft.com/en-us/uwp/api/Windows.Management.Deployment.DeploymentOptions\r\n            if (Runtime::IsCurrentOSVersionGreaterThanOrEqual(Utility::Version{ \"10.0.18362.0\" }))\r\n            {\r\n                deploymentOptions = DeploymentOptions::RetainFilesOnFailure;\r\n            }\r\n\r\n            IAsyncOperationWithProgress<DeploymentResult, DeploymentProgress> deployOperation = packageManager.RequestAddPackageAsync(\r\n                uriObject,\r\n                nullptr, /*dependencyPackageUris*/\r\n                deploymentOptions,\r\n                nullptr, /*targetVolume*/\r\n                nullptr, /*optionalAndRelatedPackageFamilyNames*/\r\n                nullptr /*relatedPackageUris*/);\r\n\r\n            HRESULT hr = WaitForDeployment(deployOperation, id, callback, false);\r\n\r\n            if (SUCCEEDED(hr))\r\n            {\r\n                removePackage.release();\r\n                return false;\r\n            }\r\n\r\n            THROW_HR_IF(hr, FAILED(hr) && hr != HRESULT_FROM_WIN32(ERROR_PACKAGES_IN_USE));\r\n        }\r\n\r\n        // If we are skipping SmartScreen or the package was in use, stage then register the package.\r\n        PartialPercentProgressCallback progress{ callback, 100 };\r\n        progress.SetRange(0, 95);\r\n        {\r\n            size_t id = GetDeploymentOperationId();\r\n            AICLI_LOG(Core, Info, << \"Starting StagePackageAsync operation #\" << id << \": \" << uri << \" Options: \" << options);\r\n\r\n            IAsyncOperationWithProgress<DeploymentResult, DeploymentProgress> stageOperation = StartStagePackage(packageManager, uriObject, options);\r\n            WaitForDeployment(stageOperation, id, progress);\r\n        }\r\n\r\n        bool registrationDeferred = false;\r\n        progress.SetRange(95, 100);\r\n        {\r\n            size_t id = GetDeploymentOperationId();\r\n            AICLI_LOG(Core, Info, << \"Starting RegisterPackageByFullNameAsync operation #\" << id << \": \" << packageFullName);\r\n\r\n            IAsyncOperationWithProgress<DeploymentResult, DeploymentProgress> registerOperation =\r\n                packageManager.RegisterPackageByFullNameAsync(packageFullNameWide, nullptr, DeploymentOptions::None);\r\n            HRESULT hr = WaitForDeployment(registerOperation, id, progress, false);\r\n\r\n            if (hr == HRESULT_FROM_WIN32(ERROR_PACKAGES_IN_USE))\r\n            {\r\n                registrationDeferred = true;\r\n            }\r\n            else\r\n            {\r\n                THROW_IF_FAILED(hr);\r\n            }\r\n        }\r\n\r\n        removePackage.release();\r\n        return registrationDeferred;\r\n    }\r\n\r\n    void RemovePackage(\r\n        std::string_view packageFullName,\r\n        RemovalOptions options,\r\n        IProgressCallback& callback)\r\n    {\r\n        size_t id = GetDeploymentOperationId();\r\n        AICLI_LOG(Core, Info, << \"Starting RemovePackage operation #\" << id << \": \" << packageFullName);\r\n\r\n        PackageManager packageManager;\r\n        winrt::hstring fullName = Utility::ConvertToUTF16(packageFullName).c_str();\r\n        auto deployOperation = packageManager.RemovePackageAsync(fullName, options);\r\n\r\n        WaitForDeployment(deployOperation, id, callback);\r\n    }\r\n\r\n    bool AddPackageMachineScope(\r\n        std::string_view uri,\r\n        const Options& options,\r\n        IProgressCallback& callback)\r\n    {\r\n        PackageManager packageManager;\r\n\r\n        // In the event of a failure we want to ensure that the package is not left on the system.\r\n        // No need for proxy as Deployment won't use it anyways.\r\n        Msix::MsixInfo packageInfo{ uri };\r\n        std::wstring packageFullNameWide = packageInfo.GetPackageFullNameWide();\r\n        std::string packageFullName = Utility::ConvertToUTF8(packageFullNameWide);\r\n        std::string packageFamilyName = Msix::GetPackageFamilyNameFromFullName(packageFullName);\r\n        auto removePackage = wil::scope_exit([&]() {\r\n            try\r\n            {\r\n                ProgressCallback cb;\r\n                RemovePackage(packageFullName, RemovalOptions::RemoveForAllUsers, cb);\r\n            }\r\n            CATCH_LOG();\r\n            });\r\n\r\n        Uri uriObject(Utility::ConvertToUTF16(uri));\r\n        PartialPercentProgressCallback progress{ callback, 100 };\r\n\r\n        // First stage package contents\r\n        progress.SetRange(0, 90);\r\n        {\r\n            size_t id = GetDeploymentOperationId();\r\n            AICLI_LOG(Core, Info, << \"Starting StagePackageAsync operation #\" << id << \": \" << uri << \" Options: \" << options);\r\n\r\n            IAsyncOperationWithProgress<DeploymentResult, DeploymentProgress> stageOperation = StartStagePackage(packageManager, uriObject, options);\r\n            WaitForDeployment(stageOperation, id, progress);\r\n        }\r\n\r\n        // Provision for all users\r\n        progress.SetRange(90, 95);\r\n        {\r\n            size_t id = GetDeploymentOperationId();\r\n            AICLI_LOG(Core, Info, << \"Starting ProvisionPackage operation #\" << id << \": \" << packageFamilyName);\r\n\r\n            winrt::hstring familyName = Utility::ConvertToUTF16(packageFamilyName).c_str();\r\n            auto deployOperation = packageManager.ProvisionPackageForAllUsersAsync(familyName);\r\n\r\n            WaitForDeployment(deployOperation, id, progress);\r\n        }\r\n\r\n        // Try registration as best effort, operation is considered successful as long as provisioning is successful.\r\n        progress.SetRange(95, 100);\r\n        bool registrationDeferred = false;\r\n        if (Runtime::IsRunningAsSystem())\r\n        {\r\n            // Packages cannot be registered under local system, just return registration deferred\r\n            registrationDeferred = true;\r\n        }\r\n        else\r\n        {\r\n            try\r\n            {\r\n                size_t id = GetDeploymentOperationId();\r\n                AICLI_LOG(Core, Info, << \"Starting RegisterPackageByFullNameAsync operation #\" << id << \": \" << packageFullName);\r\n\r\n                IAsyncOperationWithProgress<DeploymentResult, DeploymentProgress> registerOperation =\r\n                    packageManager.RegisterPackageByFullNameAsync(packageFullNameWide, nullptr, DeploymentOptions::None);\r\n                WaitForDeployment(registerOperation, id, progress);\r\n            }\r\n            catch (...)\r\n            {\r\n                registrationDeferred = true;\r\n            }\r\n        }\r\n\r\n        progress.OnProgress(100, 100, ProgressType::Percent);\r\n        removePackage.release();\r\n        return registrationDeferred;\r\n    }\r\n\r\n    void RemovePackageMachineScope(\r\n        std::string_view packageFamilyName,\r\n        std::string_view packageFullName,\r\n        IProgressCallback& callback)\r\n    {\r\n        PartialPercentProgressCallback progress{ callback, 100 };\r\n\r\n        // Deprovision first\r\n        progress.SetRange(0, 5);\r\n        {\r\n            size_t id = GetDeploymentOperationId();\r\n            AICLI_LOG(Core, Info, << \"Starting DeprovisionPackage operation #\" << id << \": \" << packageFamilyName);\r\n\r\n            PackageManager packageManager;\r\n            winrt::hstring familyName = Utility::ConvertToUTF16(packageFamilyName).c_str();\r\n            auto deployOperation = packageManager.DeprovisionPackageForAllUsersAsync(familyName);\r\n\r\n            WaitForDeployment(deployOperation, id, progress);\r\n        }\r\n\r\n        // Remove for all users\r\n        progress.SetRange(5, 100);\r\n        {\r\n            RemovePackage(packageFullName, RemovalOptions::RemoveForAllUsers, progress);\r\n        }\r\n    }\r\n\r\n    bool IsRegistered(std::string_view packageFamilyName)\r\n    {\r\n        std::wstring wideFamilyName = Utility::ConvertToUTF16(packageFamilyName);\r\n\r\n        PackageManager packageManager;\r\n        auto packages = packageManager.FindPackagesForUser({}, wideFamilyName);\r\n\r\n        return packages.begin() != packages.end();\r\n    }\r\n\r\n    void RegisterPackage(\r\n        std::string_view packageFamilyName,\r\n        IProgressCallback& callback)\r\n    {\r\n        size_t id = GetDeploymentOperationId();\r\n        AICLI_LOG(Core, Info, << \"Starting RegisterPackageByFullNameAsync operation #\" << id << \": \" << packageFamilyName);\r\n\r\n        PackageManager packageManager;\r\n        winrt::hstring packageFamilyNameWide = Utility::ConvertToUTF16(packageFamilyName).c_str();\r\n        auto deployOperation = packageManager.RegisterPackageByFamilyNameAsync(packageFamilyNameWide, nullptr, DeploymentOptions::None, nullptr, nullptr);\r\n\r\n        WaitForDeployment(deployOperation, id, callback);\r\n    }\r\n\r\n    bool IsExpectedDigestsSupported()\r\n    {\r\n        static bool s_IsExpectedDigestsSupported = Metadata::ApiInformation::IsPropertyPresent(winrt::name_of<AddPackageOptions>(), L\"ExpectedDigests\");\r\n        return s_IsExpectedDigestsSupported;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Downloader.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include <wininet.h>\r\n#include \"Public/AppInstallerErrors.h\"\r\n#include \"Public/AppInstallerRuntime.h\"\r\n#include \"Public/AppInstallerDownloader.h\"\r\n#include \"Public/AppInstallerSHA256.h\"\r\n#include \"Public/AppInstallerStrings.h\"\r\n#include \"Public/AppInstallerLogging.h\"\r\n#include \"Public/AppInstallerTelemetry.h\"\r\n#include \"Public/winget/UserSettings.h\"\r\n#include \"Public/winget/NetworkSettings.h\"\r\n#include \"Public/winget/Filesystem.h\"\r\n#include \"DODownloader.h\"\r\n#include \"HttpStream/HttpRandomAccessStream.h\"\r\n\r\nusing namespace AppInstaller::Runtime;\r\nusing namespace AppInstaller::Settings;\r\nusing namespace AppInstaller::Filesystem;\r\nusing namespace AppInstaller::Utility::HttpStream;\r\nusing namespace winrt::Windows::Web::Http;\r\nusing namespace winrt::Windows::Web::Http::Headers;\r\nusing namespace winrt::Windows::Web::Http::Filters;\r\n\r\nnamespace AppInstaller::Utility\r\n{\r\n    namespace\r\n    {\r\n        std::wstring GetHttpQueryString(const wil::unique_hinternet& urlFile, DWORD queryProperty)\r\n        {\r\n            std::wstring result = {};\r\n            DWORD length = 0;\r\n            if (!HttpQueryInfoW(urlFile.get(),\r\n                queryProperty,\r\n                &result[0],\r\n                &length,\r\n                nullptr))\r\n            {\r\n                auto lastError = GetLastError();\r\n                if (lastError == ERROR_INSUFFICIENT_BUFFER)\r\n                {\r\n                    // lpdwBufferLength contains the size, in bytes, of a buffer large enough to receive the requested information\r\n                    // without the nul char. not the exact buffer size.\r\n                    auto size = static_cast<size_t>(length) / sizeof(wchar_t);\r\n                    result.resize(size + 1);\r\n                    if (HttpQueryInfoW(urlFile.get(),\r\n                        queryProperty,\r\n                        &result[0],\r\n                        &length,\r\n                        nullptr))\r\n                    {\r\n                        // because the buffer can be bigger remove possible null chars\r\n                        result.erase(result.find(L'\\0'));\r\n                    }\r\n                    else\r\n                    {\r\n                        AICLI_LOG(Core, Error, << \"Error retrieving header value [\" << queryProperty << \"]: \" << GetLastError());\r\n                        result.clear();\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(Core, Error, << \"Error retrieving header [\" << queryProperty << \"]: \" << GetLastError());\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        // Gets the retry after value in terms of a delay in seconds\r\n        std::chrono::seconds GetRetryAfter(const HttpDateOrDeltaHeaderValue& retryAfter)\r\n        {\r\n            if (retryAfter)\r\n            {\r\n                auto delta = retryAfter.Delta();\r\n                if (delta)\r\n                {\r\n                    return  std::chrono::duration_cast<std::chrono::seconds>(delta.GetTimeSpan());\r\n                }\r\n\r\n                auto dateTimeRef = retryAfter.Date();\r\n                if (dateTimeRef)\r\n                {\r\n                    auto dateTime = dateTimeRef.GetDateTime();\r\n                    auto now = winrt::clock::now();\r\n\r\n                    if (dateTime > now)\r\n                    {\r\n                        return std::chrono::duration_cast<std::chrono::seconds>(dateTime - now);\r\n                    }\r\n                }\r\n            }\r\n\r\n            return 0s;\r\n        }\r\n\r\n        std::chrono::seconds GetRetryAfter(const wil::unique_hinternet& urlFile)\r\n        {\r\n            std::wstring retryAfter = GetHttpQueryString(urlFile, HTTP_QUERY_RETRY_AFTER);\r\n            return retryAfter.empty() ? 0s : AppInstaller::Utility::GetRetryAfter(retryAfter);\r\n        }\r\n    }\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n    namespace TestHooks\r\n    {\r\n        static std::function<DownloadResult(\r\n            const std::string& url,\r\n            const std::filesystem::path& dest,\r\n            DownloadType type,\r\n            IProgressCallback& progress,\r\n            std::optional<DownloadInfo> info)>* s_Download_Function_Override = nullptr;\r\n\r\n        void SetDownloadResult_Function_Override(std::function<DownloadResult(\r\n            const std::string& url,\r\n            const std::filesystem::path& dest,\r\n            DownloadType type,\r\n            IProgressCallback& progress,\r\n            std::optional<DownloadInfo> info)>* value)\r\n        {\r\n            s_Download_Function_Override = value;\r\n        }\r\n    }\r\n#endif\r\n\r\n    DownloadResult WinINetDownloadToStream(\r\n        const std::string& url,\r\n        std::ostream& dest,\r\n        IProgressCallback& progress,\r\n        std::optional<DownloadInfo> info)\r\n    {\r\n        // For AICLI_LOG usages with string literals.\r\n        #pragma warning(push)\r\n        #pragma warning(disable:26449)\r\n\r\n        AICLI_LOG(Core, Info, << \"WinINet downloading from url: \" << url);\r\n\r\n        auto agentWide = Utility::ConvertToUTF16(Runtime::GetDefaultUserAgent().get());\r\n        wil::unique_hinternet session;\r\n\r\n        const auto& proxyUri = Network().GetProxyUri();\r\n        if (proxyUri)\r\n        {\r\n            AICLI_LOG(Core, Info, << \"Using proxy \" << proxyUri.value());\r\n            session.reset(InternetOpen(\r\n                agentWide.c_str(),\r\n                INTERNET_OPEN_TYPE_PROXY,\r\n                Utility::ConvertToUTF16(proxyUri.value()).c_str(),\r\n                NULL,\r\n                0));\r\n        }\r\n        else\r\n        {\r\n            session.reset(InternetOpen(\r\n                agentWide.c_str(),\r\n                INTERNET_OPEN_TYPE_PRECONFIG,\r\n                NULL,\r\n                NULL,\r\n                0));\r\n        }\r\n\r\n        THROW_LAST_ERROR_IF_NULL_MSG(session, \"InternetOpen() failed.\");\r\n\r\n        std::string customHeaders;\r\n        if (info && info->RequestHeaders.size() > 0)\r\n        {\r\n            for (const auto& header : info->RequestHeaders)\r\n            {\r\n                customHeaders += header.Name + \": \" + header.Value + \"\\r\\n\";\r\n            }\r\n        }\r\n        std::wstring customHeadersWide = Utility::ConvertToUTF16(customHeaders);\r\n\r\n        auto urlWide = Utility::ConvertToUTF16(url);\r\n        wil::unique_hinternet urlFile(InternetOpenUrl(\r\n            session.get(),\r\n            urlWide.c_str(),\r\n            customHeadersWide.empty() ? NULL : customHeadersWide.c_str(),\r\n            customHeadersWide.empty() ? 0 : (DWORD)(customHeadersWide.size()),\r\n            INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS, // This allows http->https redirection\r\n            0));\r\n        THROW_LAST_ERROR_IF_NULL_MSG(urlFile, \"InternetOpenUrl() failed.\");\r\n\r\n        // Check http return status\r\n        DWORD requestStatus = 0;\r\n        DWORD cbRequestStatus = sizeof(requestStatus);\r\n\r\n        THROW_LAST_ERROR_IF_MSG(!HttpQueryInfoW(urlFile.get(),\r\n            HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER,\r\n            &requestStatus,\r\n            &cbRequestStatus,\r\n            nullptr), \"Query download request status failed.\");\r\n\r\n        constexpr DWORD TooManyRequest = 429;\r\n\r\n        switch (requestStatus)\r\n        {\r\n        case HTTP_STATUS_OK:\r\n            // All good\r\n            break;\r\n        case TooManyRequest:\r\n        case HTTP_STATUS_SERVICE_UNAVAIL:\r\n        {\r\n            THROW_EXCEPTION(ServiceUnavailableException(GetRetryAfter(urlFile)));\r\n        }\r\n        default:\r\n            AICLI_LOG(Core, Error, << \"Download request failed. Returned status: \" << requestStatus);\r\n            THROW_HR_MSG(MAKE_HRESULT(SEVERITY_ERROR, FACILITY_HTTP, requestStatus), \"Download request status is not success.\");\r\n        }\r\n\r\n        AICLI_LOG(Core, Verbose, << \"Download request status success.\");\r\n\r\n        // Get content length. Don't fail the download if failed.\r\n        LONGLONG contentLength = 0;\r\n        DWORD cbContentLength = sizeof(contentLength);\r\n\r\n        HttpQueryInfoW(\r\n            urlFile.get(),\r\n            HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER64,\r\n            &contentLength,\r\n            &cbContentLength,\r\n            nullptr);\r\n        AICLI_LOG(Core, Verbose, << \"Download size: \" << contentLength);\r\n\r\n        std::string contentType = Utility::ConvertToUTF8(GetHttpQueryString(urlFile, HTTP_QUERY_CONTENT_TYPE));\r\n        AICLI_LOG(Core, Verbose, << \"Content Type: \" << contentType);\r\n\r\n        // Setup hash engine\r\n        SHA256 hashEngine;\r\n\r\n        const int bufferSize = 1024 * 1024; // 1MB\r\n        auto buffer = std::make_unique<BYTE[]>(bufferSize);\r\n\r\n        BOOL readSuccess = true;\r\n        DWORD bytesRead = 0;\r\n        LONGLONG bytesDownloaded = 0;\r\n\r\n        do\r\n        {\r\n            if (progress.IsCancelledBy(CancelReason::Any))\r\n            {\r\n                AICLI_LOG(Core, Info, << \"Download cancelled.\");\r\n                return {};\r\n            }\r\n\r\n            readSuccess = InternetReadFile(urlFile.get(), buffer.get(), bufferSize, &bytesRead);\r\n\r\n            THROW_LAST_ERROR_IF_MSG(!readSuccess, \"InternetReadFile() failed.\");\r\n\r\n            hashEngine.Add(buffer.get(), bytesRead);\r\n\r\n            dest.write((char*)buffer.get(), bytesRead);\r\n\r\n            bytesDownloaded += bytesRead;\r\n\r\n            if (bytesRead != 0)\r\n            {\r\n                progress.OnProgress(bytesDownloaded, contentLength, ProgressType::Bytes);\r\n            }\r\n\r\n        } while (bytesRead != 0);\r\n\r\n        dest.flush();\r\n\r\n        // Check download size matches if content length is provided in response header\r\n        if (contentLength > 0)\r\n        {\r\n            THROW_HR_IF(APPINSTALLER_CLI_ERROR_DOWNLOAD_SIZE_MISMATCH, bytesDownloaded != contentLength);\r\n        }\r\n\r\n        DownloadResult result;\r\n        result.SizeInBytes = static_cast<uint64_t>(bytesDownloaded);\r\n        result.ContentType = std::move(contentType);\r\n        result.Sha256Hash = hashEngine.Get();\r\n        AICLI_LOG(Core, Info, << \"Download hash: \" << SHA256::ConvertToString(result.Sha256Hash));\r\n\r\n        AICLI_LOG(Core, Info, << \"Download completed.\");\r\n\r\n        #pragma warning(pop)\r\n\r\n        return result;\r\n    }\r\n\r\n    std::map<std::string, std::string> GetHeaders(std::string_view url)\r\n    {\r\n        // TODO: Use proxy info. HttpClient does not support using a custom proxy, only using the system-wide one.\r\n        AICLI_LOG(Core, Verbose, << \"Retrieving headers from url: \" << url);\r\n\r\n        HttpBaseProtocolFilter filter;\r\n        filter.CacheControl().ReadBehavior(HttpCacheReadBehavior::MostRecent);\r\n\r\n        HttpClient client(filter);\r\n        client.DefaultRequestHeaders().Connection().Clear();\r\n        client.DefaultRequestHeaders().Append(L\"Connection\", L\"close\");\r\n        client.DefaultRequestHeaders().UserAgent().ParseAdd(Utility::ConvertToUTF16(Runtime::GetDefaultUserAgent().get()));\r\n\r\n        winrt::Windows::Foundation::Uri uri{ Utility::ConvertToUTF16(url) };\r\n        HttpRequestMessage request(HttpMethod::Head(), uri);\r\n\r\n        HttpResponseMessage response = client.SendRequestAsync(request, HttpCompletionOption::ResponseHeadersRead).get();\r\n\r\n        switch (response.StatusCode())\r\n        {\r\n        case HttpStatusCode::Ok:\r\n            // All good\r\n            break;\r\n        case HttpStatusCode::TooManyRequests:\r\n        case HttpStatusCode::ServiceUnavailable:\r\n        {\r\n            THROW_EXCEPTION(ServiceUnavailableException(GetRetryAfter(response.Headers().RetryAfter())));\r\n        }\r\n        default:\r\n            THROW_HR(MAKE_HRESULT(SEVERITY_ERROR, FACILITY_HTTP, response.StatusCode()));\r\n        }\r\n\r\n        std::map<std::string, std::string> result;\r\n\r\n        for (const auto& header : response.Headers())\r\n        {\r\n            result.emplace(Utility::FoldCase(static_cast<std::string_view>(Utility::ConvertToUTF8(header.Key()))), Utility::ConvertToUTF8(header.Value()));\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    DownloadResult DownloadToStream(\r\n        const std::string& url,\r\n        std::ostream& dest,\r\n        DownloadType,\r\n        IProgressCallback& progress,\r\n        std::optional<DownloadInfo> info)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, url.empty());\r\n        return WinINetDownloadToStream(url, dest, progress, info);\r\n    }\r\n\r\n    DownloadResult Download(\r\n        const std::string& url,\r\n        const std::filesystem::path& dest,\r\n        DownloadType type,\r\n        IProgressCallback& progress,\r\n        std::optional<DownloadInfo> info)\r\n    {\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        if (TestHooks::s_Download_Function_Override)\r\n        {\r\n            return (*TestHooks::s_Download_Function_Override)(url, dest, type, progress, info);\r\n        }\r\n#endif\r\n\r\n        THROW_HR_IF(E_INVALIDARG, url.empty());\r\n        THROW_HR_IF(E_INVALIDARG, dest.empty());\r\n\r\n        AICLI_LOG(Core, Info, << \"Downloading to path: \" << dest);\r\n\r\n        std::filesystem::create_directories(dest.parent_path());\r\n\r\n        // Only Installers should be downloaded with DO currently, as:\r\n        //  - Index :: Constantly changing blob at same location is not what DO is for\r\n        //  - Manifest / InstallerMetadataCollectionInput :: DO overhead is not needed for small files\r\n        //  - WinGetUtil :: Intentionally not using DO at this time\r\n        if (type == DownloadType::Installer)\r\n        {\r\n            if (Network().GetInstallerDownloader() == InstallerDownloader::DeliveryOptimization)\r\n            {\r\n                try\r\n                {\r\n                    auto result = DODownload(url, dest, progress, info);\r\n                    // Since we cannot pre-apply to the file with DO, post-apply the MotW to the file.\r\n                    // Only do so if the file exists, because cancellation will not throw here.\r\n                    if (std::filesystem::exists(dest))\r\n                    {\r\n                        ApplyMotwIfApplicable(dest, URLZONE_INTERNET);\r\n                    }\r\n                    return result;\r\n                }\r\n                catch (const wil::ResultException& re)\r\n                {\r\n                    // Fall back to WinINet below unless the specific error is not one that should be ignored.\r\n                    // We need to be careful not to bypass metered networks or other reasons that might\r\n                    // intentionally cause the download to be blocked.\r\n                    HRESULT hr = re.GetErrorCode();\r\n                    if (IsDOErrorFatal(hr))\r\n                    {\r\n                        throw;\r\n                    }\r\n                    else\r\n                    {\r\n                        // Send telemetry so that we can understand the reasons for DO failing\r\n                        Logging::Telemetry().LogNonFatalDOError(url, hr);\r\n                    }\r\n                }\r\n\r\n                // If we reach this point, we are intending to fall through to WinINet.\r\n                // Remove any file that may have been placed in the target location.\r\n                if (std::filesystem::exists(dest))\r\n                {\r\n                    std::filesystem::remove(dest);\r\n                }\r\n            }\r\n        }\r\n\r\n        std::ofstream emptyDestFile(dest);\r\n        emptyDestFile.close();\r\n        ApplyMotwIfApplicable(dest, URLZONE_INTERNET);\r\n\r\n        // Use std::ofstream::app to append to previous empty file so that it will not\r\n        // create a new file and clear motw.\r\n        std::ofstream outfile(dest, std::ofstream::binary | std::ofstream::app);\r\n        return WinINetDownloadToStream(url, outfile, progress, info);\r\n    }\r\n\r\n    using namespace std::string_view_literals;\r\n    constexpr std::string_view s_http_start = \"http://\"sv;\r\n    constexpr std::string_view s_https_start = \"https://\"sv;\r\n\r\n    bool IsUrlRemote(std::string_view url)\r\n    {\r\n        // Very simple choice right now: \"does it start with http:// or https://\"?\r\n        if (CaseInsensitiveStartsWith(url, s_http_start) ||\r\n            CaseInsensitiveStartsWith(url, s_https_start))\r\n        {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    bool IsUrlSecure(std::string_view url)\r\n    {\r\n        // Very simple choice right now: \"does it start with https://\"?\r\n        if (CaseInsensitiveStartsWith(url, s_https_start))\r\n        {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n    \r\n    static inline bool FileSupportsMotw(const std::filesystem::path& path)\r\n    {\r\n        return SupportsNamedStreams(path);\r\n    }\r\n\r\n    void ApplyMotwIfApplicable(const std::filesystem::path& filePath, URLZONE zone)\r\n    {\r\n        AICLI_LOG(Core, Info, << \"Started applying motw to \" << filePath << \" with zone: \" << zone);\r\n\r\n        if (!FileSupportsMotw(filePath))\r\n        {\r\n            AICLI_LOG(Core, Info, << \"File system does not support ADS. Skipped applying motw\");\r\n            return;\r\n        }\r\n\r\n        Microsoft::WRL::ComPtr<IZoneIdentifier> zoneIdentifier;\r\n        THROW_IF_FAILED(CoCreateInstance(CLSID_PersistentZoneIdentifier, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&zoneIdentifier)));\r\n        THROW_IF_FAILED(zoneIdentifier->SetId(zone));\r\n\r\n        Microsoft::WRL::ComPtr<IPersistFile> persistFile;\r\n        THROW_IF_FAILED(zoneIdentifier.As(&persistFile));\r\n        THROW_IF_FAILED(persistFile->Save(filePath.c_str(), TRUE));\r\n\r\n        AICLI_LOG(Core, Info, << \"Finished applying motw\");\r\n    }\r\n\r\n    void RemoveMotwIfApplicable(const std::filesystem::path& filePath)\r\n    {\r\n        AICLI_LOG(Core, Info, << \"Started removing motw to \" << filePath);\r\n\r\n        if (!FileSupportsMotw(filePath))\r\n        {\r\n            AICLI_LOG(Core, Info, << \"File system does not support ADS. Skipped removing motw\");\r\n            return;\r\n        }\r\n\r\n        Microsoft::WRL::ComPtr<IZoneIdentifier> zoneIdentifier;\r\n        THROW_IF_FAILED(CoCreateInstance(CLSID_PersistentZoneIdentifier, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&zoneIdentifier)));\r\n\r\n        Microsoft::WRL::ComPtr<IPersistFile> persistFile;\r\n        THROW_IF_FAILED(zoneIdentifier.As(&persistFile));\r\n\r\n        auto hr = persistFile->Load(filePath.c_str(), STGM_READ);\r\n        if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))\r\n        {\r\n            // IPersistFile::Load returns same error for \"file not found\" and \"motw not found\".\r\n            // Check if the file exists to be sure we are on the \"motw not found\" case.\r\n            THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), !std::filesystem::exists(filePath));\r\n\r\n            AICLI_LOG(Core, Info, << \"File does not contain motw. Skipped removing motw\");\r\n            return;\r\n        }\r\n\r\n        THROW_IF_FAILED(zoneIdentifier->Remove());\r\n        THROW_IF_FAILED(persistFile->Save(NULL, TRUE));\r\n\r\n        AICLI_LOG(Core, Info, << \"Finished removing motw\");\r\n    }\r\n\r\n    HRESULT ApplyMotwUsingIAttachmentExecuteIfApplicable(const std::filesystem::path& filePath, const std::string& source, URLZONE zoneIfScanFailure)\r\n    {\r\n        AICLI_LOG(Core, Info, << \"Started applying motw using IAttachmentExecute to \" << filePath);\r\n\r\n        if (!FileSupportsMotw(filePath))\r\n        {\r\n            AICLI_LOG(Core, Info, << \"File system does not support ADS. Skipped applying motw\");\r\n            return S_OK;\r\n        }\r\n\r\n        // Attachment execution service needs STA to succeed, so we'll create a new thread and CoInitialize with STA.\r\n        HRESULT aesSaveResult = S_OK;\r\n        auto updateMotw = [&]() -> HRESULT\r\n        {\r\n            Microsoft::WRL::ComPtr<IAttachmentExecute> attachmentExecute;\r\n            RETURN_IF_FAILED(CoCreateInstance(CLSID_AttachmentServices, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&attachmentExecute)));\r\n            RETURN_IF_FAILED(attachmentExecute->SetLocalPath(filePath.c_str()));\r\n            RETURN_IF_FAILED(attachmentExecute->SetSource(Utility::ConvertToUTF16(source).c_str()));\r\n\r\n            // IAttachmentExecute::Save() expects the local file to be clean(i.e. it won't clear existing motw if it thinks the source url is trusted)\r\n            RemoveMotwIfApplicable(filePath);\r\n\r\n            aesSaveResult = attachmentExecute->Save();\r\n\r\n            // Reapply desired zone upon scan failure.\r\n            // Not using SUCCEEDED(hr) to check since there are cases file is missing after a successful scan\r\n            if (aesSaveResult != S_OK && std::filesystem::exists(filePath))\r\n            {\r\n                ApplyMotwIfApplicable(filePath, zoneIfScanFailure);\r\n            }\r\n\r\n            RETURN_IF_FAILED(aesSaveResult);\r\n            return S_OK;\r\n        };\r\n\r\n        HRESULT hr = S_OK;\r\n\r\n        std::thread aesThread([&]()\r\n            {\r\n                hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);\r\n                if (FAILED(hr))\r\n                {\r\n                    return;\r\n                }\r\n\r\n                hr = updateMotw();\r\n                CoUninitialize();\r\n            });\r\n\r\n        aesThread.join();\r\n\r\n        AICLI_LOG(Core, Info, << \"Finished applying motw using IAttachmentExecute. Result: \" << hr << \" IAttachmentExecute::Save() result: \" << aesSaveResult);\r\n\r\n        return aesSaveResult;\r\n    }\r\n\r\n    Microsoft::WRL::ComPtr<IStream> GetReadOnlyStreamFromURI(std::string_view uriStr)\r\n    {\r\n        Microsoft::WRL::ComPtr<IStream> inputStream;\r\n        if (Utility::IsUrlRemote(uriStr))\r\n        {\r\n            // Get an IStream from the input uri and try to create package or bundler reader.\r\n            winrt::Windows::Foundation::Uri uri(Utility::ConvertToUTF16(uriStr));\r\n\r\n            winrt::com_ptr<HttpRandomAccessStream> httpRandomAccessStream = winrt::make_self<HttpRandomAccessStream>();\r\n\r\n            try\r\n            {\r\n                auto randomAccessStream = httpRandomAccessStream->InitializeAsync(uri).get();\r\n\r\n                ::IUnknown* rasAsIUnknown = (::IUnknown*)winrt::get_abi(randomAccessStream);\r\n                THROW_IF_FAILED(CreateStreamOverRandomAccessStream(\r\n                    rasAsIUnknown,\r\n                    IID_PPV_ARGS(inputStream.ReleaseAndGetAddressOf())));\r\n            }\r\n            catch (const winrt::hresult_error& hre)\r\n            {\r\n                if (hre.code() == APPINSTALLER_CLI_ERROR_SERVICE_UNAVAILABLE)\r\n                {\r\n                    THROW_EXCEPTION(AppInstaller::Utility::ServiceUnavailableException(httpRandomAccessStream->RetryAfter()));\r\n                }\r\n\r\n                throw;\r\n            }\r\n        }\r\n        else\r\n        {\r\n            std::filesystem::path path(Utility::ConvertToUTF16(uriStr));\r\n            THROW_IF_FAILED(SHCreateStreamOnFileEx(path.c_str(),\r\n                STGM_READ | STGM_SHARE_DENY_WRITE | STGM_FAILIFTHERE, 0, FALSE, nullptr, &inputStream));\r\n        }\r\n\r\n        return inputStream;\r\n    }\r\n\r\n    std::chrono::seconds GetRetryAfter(const std::wstring& retryAfter)\r\n    {\r\n        try\r\n        {\r\n            winrt::hstring hstringValue{ retryAfter };\r\n            HttpDateOrDeltaHeaderValue headerValue = nullptr;\r\n            HttpDateOrDeltaHeaderValue::TryParse(hstringValue, headerValue);\r\n            return GetRetryAfter(headerValue);\r\n        }\r\n        catch (...)\r\n        {\r\n            AICLI_LOG(Core, Error, << \"Retry-After value not supported: \" << Utility::ConvertToUTF8(retryAfter));\r\n        }\r\n\r\n        return 0s;\r\n    }\r\n\r\n    std::chrono::seconds GetRetryAfter(const HttpResponseMessage& response)\r\n    {\r\n        return GetRetryAfter(response.Headers().RetryAfter());\r\n    }\r\n\r\n    CacheControlPolicy::CacheControlPolicy(std::wstring_view header)\r\n    {\r\n        static constexpr std::wstring_view s_MaxAge = L\"max-age\"sv;\r\n\r\n        if (header.empty())\r\n        {\r\n            return;\r\n        }\r\n\r\n        std::vector<std::wstring_view> directives = Utility::Split(header, L',', true);\r\n\r\n        for (std::wstring_view directive : directives)\r\n        {\r\n            if (!directive.empty())\r\n            {\r\n                // Even if we don't understand the directive, the value was not empty\r\n                Present = true;\r\n            }\r\n\r\n            std::wstring lowerDirective = ToLower(directive);\r\n\r\n            if (lowerDirective == L\"public\"sv)\r\n            {\r\n                Public = true;\r\n            }\r\n            else if (lowerDirective == L\"no-cache\"sv)\r\n            {\r\n                NoCache = true;\r\n            }\r\n            else if (lowerDirective == L\"no-store\"sv)\r\n            {\r\n                NoStore = true;\r\n            }\r\n            else if (StartsWith(lowerDirective, s_MaxAge))\r\n            {\r\n                std::vector<std::wstring_view> parts = Utility::SplitView(lowerDirective, L'=', true);\r\n                if (parts.size() == 2)\r\n                {\r\n                    try\r\n                    {\r\n                        MaxAge = std::min(std::stoull(std::wstring{ parts[1] }), MaximumMaxAge);\r\n                    }\r\n                    CATCH_LOG();\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/ExperimentalFeature.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"AppInstallerLogging.h\"\n#include \"winget/ExperimentalFeature.h\"\n#include \"winget/GroupPolicy.h\"\n#include \"winget/UserSettings.h\"\n\nnamespace AppInstaller::Settings\n{\n#ifndef AICLI_DISABLE_TEST_HOOKS\n    const std::map<ExperimentalFeature::Feature, bool>* s_ExperimentalFeature_Override = nullptr;\n\n    void SetExperimentalFeatureOverride(const std::map<ExperimentalFeature::Feature, bool>* override)\n    {\n        s_ExperimentalFeature_Override = override;\n    }\n#endif\n\n    namespace\n    {\n\n        bool IsEnabledInternal(ExperimentalFeature::Feature feature, const UserSettings& userSettings)\n        {\n            if (feature == ExperimentalFeature::Feature::None)\n            {\n                return true;\n            }\n\n#ifdef WINGET_DISABLE_EXPERIMENTAL_FEATURES\n            UNREFERENCED_PARAMETER(userSettings);\n            return false;\n#else\n\n#ifndef AICLI_DISABLE_TEST_HOOKS\n            if (s_ExperimentalFeature_Override)\n            {\n                auto itr = s_ExperimentalFeature_Override->find(feature);\n                if (itr != s_ExperimentalFeature_Override->end())\n                {\n                    return itr->second;\n                }\n            }\n#endif\n\n            if (!GroupPolicies().IsEnabled(TogglePolicy::Policy::ExperimentalFeatures))\n            {\n                AICLI_LOG(Core, Info, <<\n                    \"Experimental feature '\" << ExperimentalFeature::GetFeature(feature).Name() <<\n                    \"' is disabled due to group policy: \" << TogglePolicy::GetPolicy(TogglePolicy::Policy::ExperimentalFeatures).RegValueName());\n                return false;\n            }\n\n            switch (feature)\n            {\n            case ExperimentalFeature::Feature::ExperimentalCmd:\n                // ExperimentalArg depends on ExperimentalCmd, so instead of failing we could\n                // assume that if ExperimentalArg is enabled then ExperimentalCmd is as well.\n                return userSettings.Get<Setting::EFExperimentalCmd>() || userSettings.Get<Setting::EFExperimentalArg>();\n            case ExperimentalFeature::Feature::ExperimentalArg:\n                return userSettings.Get<Setting::EFExperimentalArg>();\n            case ExperimentalFeature::Feature::DirectMSI:\n                return userSettings.Get<Setting::EFDirectMSI>();\n            case ExperimentalFeature::Feature::Resume:\n                return userSettings.Get<Setting::EFResume>();\n            case ExperimentalFeature::Feature::Font:\n                return userSettings.Get<Setting::EFFonts>();\n            case ExperimentalFeature::Feature::SourcePriority:\n                return userSettings.Get<Setting::EFSourcePriority>();\n            default:\n                THROW_HR(E_UNEXPECTED);\n            }\n#endif\n        }\n    }\n\n    bool ExperimentalFeature::IsEnabled(Feature feature)\n    {\n        return IsEnabledInternal(feature, User());\n    }\n\n#ifndef AICLI_DISABLE_TEST_HOOKS\n    bool ExperimentalFeature::IsEnabled(Feature feature, const UserSettings& userSettings)\n    {\n        return IsEnabledInternal(feature, userSettings);\n    }\n#endif\n\n    ExperimentalFeature ExperimentalFeature::GetFeature(ExperimentalFeature::Feature feature)\n    {\n        switch (feature)\n        {\n        case Feature::ExperimentalCmd:\n            return ExperimentalFeature{ \"Command Sample\", \"experimentalCmd\", \"https://aka.ms/winget-settings\", Feature::ExperimentalCmd };\n        case Feature::ExperimentalArg:\n            return ExperimentalFeature{ \"Argument Sample\", \"experimentalArg\", \"https://aka.ms/winget-settings\", Feature::ExperimentalArg };\n        case Feature::DirectMSI:\n            return ExperimentalFeature{ \"Direct MSI Installation\", \"directMSI\", \"https://aka.ms/winget-settings\", Feature::DirectMSI };\n        case Feature::Resume:\n            return ExperimentalFeature{ \"Resume\", \"resume\", \"https://aka.ms/winget-settings\", Feature::Resume };\n        case Feature::Font:\n            return ExperimentalFeature{ \"Font\", \"fonts\", \"https://aka.ms/winget-settings\", Feature::Font };\n        case Feature::SourcePriority:\n            return ExperimentalFeature{ \"Source Priority\", \"sourcePriority\", \"https://aka.ms/winget-settings\", Feature::SourcePriority };\n        default:\n            THROW_HR(E_UNEXPECTED);\n        }\n    }\n\n    std::vector<ExperimentalFeature> ExperimentalFeature::GetAllFeatures()\n    {\n        std::vector<ExperimentalFeature> result;\n\n        for (Feature_t i = 0x1; i < static_cast<Feature_t>(Feature::Max); i = i << 1)\n        {\n            result.emplace_back(GetFeature(static_cast<Feature>(i)));\n        }\n\n        return result;\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCommonCore/ExtensionCatalog.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"winget/ExtensionCatalog.h\"\r\n#include \"AppInstallerErrors.h\"\r\n#include \"AppInstallerLogging.h\"\r\n#include \"AppInstallerStrings.h\"\r\n\r\nnamespace AppInstaller::Deployment\r\n{\r\n    namespace AppExt = winrt::Windows::ApplicationModel::AppExtensions;\r\n\r\n    Extension::Extension(AppExt::AppExtension extension) : m_extension(extension) {}\r\n\r\n    std::filesystem::path Extension::GetPackagePath() const\r\n    {\r\n        return m_extension.Package().InstalledLocation().Path().c_str();\r\n    }\r\n\r\n    std::filesystem::path Extension::GetPublicFolderPath() const\r\n    {\r\n        auto folder = m_extension.GetPublicFolderAsync().get();\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_EXTENSION_PUBLIC_FAILED, !folder);\r\n        return folder.Path().c_str();\r\n    }\r\n\r\n    winrt::Windows::ApplicationModel::PackageVersion Extension::GetPackageVersion() const\r\n    {\r\n        return m_extension.Package().Id().Version();\r\n    }\r\n\r\n    bool Extension::VerifyContentIntegrity(IProgressCallback& progress)\r\n    {\r\n        auto operation = m_extension.Package().VerifyContentIntegrityAsync();\r\n        auto removeCancel = progress.SetCancellationFunction([&]() { operation.Cancel(); });\r\n        return operation.get();\r\n    }\r\n\r\n    ExtensionCatalog::ExtensionCatalog(std::wstring_view extensionName)\r\n    {\r\n        m_catalog = AppExt::AppExtensionCatalog::Open(winrt::hstring(extensionName));\r\n    }\r\n\r\n    std::optional<Extension> ExtensionCatalog::FindByPackageFamilyAndId(std::string_view packageFamilyName, std::wstring_view id) const\r\n    {\r\n        std::wstring wpfn = Utility::ConvertToUTF16(packageFamilyName);\r\n        std::optional<Extension> result;\r\n\r\n        auto extensions = m_catalog.FindAllAsync().get();\r\n        for (const auto& extension : extensions)\r\n        {\r\n            auto info = extension.AppInfo();\r\n\r\n            AICLI_LOG(Core, Info, << \"Examining extension: PFN = \" << Utility::ConvertToUTF8(info.PackageFamilyName()) << \", ID = \" << Utility::ConvertToUTF8(extension.Id()));\r\n\r\n            if (info.PackageFamilyName() == wpfn && extension.Id() == id)\r\n            {\r\n                AICLI_LOG(Core, Info, << \"Found matching extension.\");\r\n                result = Extension{ extension };\r\n                break;\r\n            }\r\n        }\r\n\r\n        if (!result)\r\n        {\r\n            AICLI_LOG(Core, Info, << \"Did not find extension: PFN = \" << packageFamilyName << \", ID = \" << Utility::ConvertToUTF8(id));\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/FileCache.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/FileCache.h\"\r\n#include <AppInstallerDownloader.h>\r\n#include <AppInstallerLogging.h>\r\n#include <AppInstallerStrings.h>\r\n\r\nnamespace AppInstaller::Caching\r\n{\r\n    namespace anon\r\n    {\r\n        std::string_view GetNameForType(FileCache::Type type)\r\n        {\r\n            switch (type)\r\n            {\r\n            case FileCache::Type::IndexV1_Manifest: return \"V1_M\";\r\n            case FileCache::Type::IndexV2_PackageVersionData: return \"V2_PVD\";\r\n            case FileCache::Type::IndexV2_Manifest: return \"V2_M\";\r\n            case FileCache::Type::Icon: return \"Icon\";\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n            case FileCache::Type::Tests: return \"Tests\";\r\n#endif\r\n            }\r\n\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n\r\n        std::unique_ptr<std::stringstream> GetUpstreamFile(const std::string& basePath, const std::string& relativePath, const Utility::SHA256::HashBuffer& expectedHash)\r\n        {\r\n            // Until signed files are implemented, fail on an empty hash\r\n            THROW_HR_IF(APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE, expectedHash.empty());\r\n\r\n            std::string fullPath = basePath;\r\n            if (fullPath.back() != '/')\r\n            {\r\n                fullPath += '/';\r\n            }\r\n            fullPath += relativePath;\r\n\r\n            if (Utility::IsUrlRemote(fullPath))\r\n            {\r\n                auto result = std::make_unique<std::stringstream>();\r\n\r\n                AICLI_LOG(Core, Verbose, << \"Getting upstream file from remote: \" << fullPath);\r\n                ProgressCallback emptyCallback;\r\n\r\n                constexpr int MaxRetryCount = 2;\r\n                constexpr std::chrono::seconds maximumWaitTimeAllowed = 10s;\r\n                for (int retryCount = 0; retryCount < MaxRetryCount; ++retryCount)\r\n                {\r\n                    try\r\n                    {\r\n                        auto downloadResult = Utility::DownloadToStream(fullPath, *result, Utility::DownloadType::Manifest, emptyCallback);\r\n\r\n                        if (!expectedHash.empty() &&\r\n                            !Utility::SHA256::AreEqual(expectedHash, downloadResult.Sha256Hash))\r\n                        {\r\n                            AICLI_LOG(Core, Verbose, << \"Invalid hash from [\" << fullPath << \"]: expected [\" << Utility::SHA256::ConvertToString(expectedHash) << \"], got [\" << Utility::SHA256::ConvertToString(downloadResult.Sha256Hash) << \"]\");\r\n                            THROW_HR(APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE);\r\n                        }\r\n\r\n                        break;\r\n                    }\r\n                    catch (const Utility::ServiceUnavailableException& sue)\r\n                    {\r\n                        if (retryCount < MaxRetryCount - 1)\r\n                        {\r\n                            auto waitSecondsForRetry = sue.RetryAfter();\r\n                            if (waitSecondsForRetry > maximumWaitTimeAllowed)\r\n                            {\r\n                                throw;\r\n                            }\r\n\r\n                            // TODO: Get real progress callback to allow cancelation.\r\n                            auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(waitSecondsForRetry);\r\n                            Sleep(static_cast<DWORD>(ms.count()));\r\n                        }\r\n                        else\r\n                        {\r\n                            throw;\r\n                        }\r\n                    }\r\n                    catch (...)\r\n                    {\r\n                        if (retryCount < MaxRetryCount - 1)\r\n                        {\r\n                            AICLI_LOG(Core, Verbose, << \"Getting upstream file failed, waiting a bit and retrying: \" << fullPath);\r\n                            Sleep(500);\r\n                        }\r\n                        else\r\n                        {\r\n                            throw;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                return result;\r\n            }\r\n            else\r\n            {\r\n                AICLI_LOG(Core, Verbose, << \"Getting upstream file from local: \" << fullPath);\r\n                std::ifstream fileStream{ fullPath, std::ios_base::in | std::ios_base::binary };\r\n                std::string fileContents = Utility::ReadEntireStream(fileStream);\r\n\r\n                auto fileContentsHash = Utility::SHA256::ComputeHash(fileContents);\r\n\r\n                if (expectedHash.empty() || Utility::SHA256::AreEqual(expectedHash, fileContentsHash))\r\n                {\r\n                    return std::make_unique<std::stringstream>(std::move(fileContents));\r\n                }\r\n                else\r\n                {\r\n                    THROW_HR(APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    FileCache::Details::Details(FileCache::Type type, std::string identifier) :\r\n        Type(type), Identifier(std::move(identifier))\r\n    {\r\n        switch (type)\r\n        {\r\n        case Type::IndexV1_Manifest:\r\n        case Type::IndexV2_PackageVersionData:\r\n        case Type::IndexV2_Manifest:\r\n        case Type::Icon:\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        case Type::Tests:\r\n#endif\r\n            BasePath = Runtime::PathName::Temp;\r\n            break;\r\n        default:\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n    }\r\n\r\n    std::filesystem::path FileCache::Details::GetCachePath() const\r\n    {\r\n        std::filesystem::path result = Runtime::GetPathTo(BasePath);\r\n        result /= \"cache\";\r\n        result /= anon::GetNameForType(Type);\r\n        result /= Utility::ConvertToUTF16(Identifier);\r\n        return result;\r\n    }\r\n\r\n    FileCache::FileCache(Type type, std::string identifier, std::vector<std::string> sources) :\r\n        m_details(type, std::move(identifier)), m_sources(std::move(sources))\r\n    {\r\n        m_cacheBase = m_details.GetCachePath();\r\n    }\r\n\r\n    const FileCache::Details& FileCache::GetDetails() const\r\n    {\r\n        return m_details;\r\n    }\r\n\r\n    std::unique_ptr<std::istream> FileCache::GetFile(const std::filesystem::path& relativePath, const Utility::SHA256::HashBuffer& expectedHash) const\r\n    {\r\n        std::filesystem::path cachedFilePath = m_cacheBase / relativePath;\r\n\r\n        // Check cache for matching file\r\n        try\r\n        {\r\n            if (std::filesystem::is_regular_file(cachedFilePath))\r\n            {\r\n                AICLI_LOG(Core, Verbose, << \"Reading cached file [\" << cachedFilePath << \"]\");\r\n\r\n                std::ifstream fileStream{ cachedFilePath, std::ios_base::in | std::ios_base::binary };\r\n                std::string fileContents = Utility::ReadEntireStream(fileStream);\r\n\r\n                auto fileContentsHash = Utility::SHA256::ComputeHash(fileContents);\r\n\r\n                if (Utility::SHA256::AreEqual(expectedHash, fileContentsHash))\r\n                {\r\n                    return std::make_unique<std::istringstream>(std::move(fileContents));\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(Core, Verbose, << \"Removing cached file [\" << cachedFilePath << \"] due to hash mismatch; expected [\" <<\r\n                        Utility::SHA256::ConvertToString(expectedHash) << \"] but was [\" << Utility::SHA256::ConvertToString(fileContentsHash) << \"]\");\r\n                }\r\n            }\r\n\r\n            std::filesystem::remove_all(cachedFilePath);\r\n        }\r\n        catch (...)\r\n        {\r\n            LOG_CAUGHT_EXCEPTION_MSG(\"Error while attempting to read cached file\");\r\n        }\r\n\r\n        // Making it here means that we do not have a cached file or it needed to be updated and was removed.\r\n        auto result = GetUpstreamFile(relativePath.u8string(), expectedHash);\r\n\r\n        // GetUpstreamFile only returns with a successfully verified hash, we just need to write the file out.\r\n        // Only log failures as caching is an optimization.\r\n        try\r\n        {\r\n            std::filesystem::create_directories(cachedFilePath.parent_path());\r\n\r\n            AICLI_LOG(Core, Verbose, << \"Writing cached file [\" << cachedFilePath << \"]\");\r\n            std::ofstream fileStream{ cachedFilePath, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc };\r\n            LOG_LAST_ERROR_IF(fileStream.fail());\r\n            fileStream << result->str() << std::flush;\r\n            LOG_LAST_ERROR_IF(fileStream.fail());\r\n        }\r\n        catch (...)\r\n        {\r\n            LOG_CAUGHT_EXCEPTION_MSG(\"Error while attempting to write cached file\");\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::unique_ptr<std::stringstream> FileCache::GetUpstreamFile(std::string relativePath, const Utility::SHA256::HashBuffer& expectedHash) const\r\n    {\r\n        // Replace backslashes with forward slashes for HTTP requests (since local can handle them).\r\n        Utility::FindAndReplace(relativePath, \"\\\\\", \"/\");\r\n\r\n        std::exception_ptr firstException;\r\n\r\n        for (const auto& upstream : m_sources)\r\n        {\r\n            try\r\n            {\r\n                return anon::GetUpstreamFile(upstream, relativePath, expectedHash);\r\n            }\r\n            catch(...)\r\n            {\r\n                LOG_CAUGHT_EXCEPTION_MSG(\"GetUpstreamFile failed on source: %hs\", upstream.c_str());\r\n                if (!firstException)\r\n                {\r\n                    firstException = std::current_exception();\r\n                }\r\n            }\r\n        }\r\n\r\n        if (firstException)\r\n        {\r\n            std::rethrow_exception(firstException);\r\n        }\r\n\r\n        // Somewhat arbitrary error that should only happen if no upstream sources provided.\r\n        THROW_HR(E_NOT_SET);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/FileLogger.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/AppInstallerFileLogger.h\"\r\n\r\n#include \"Public/AppInstallerRuntime.h\"\r\n#include \"Public/AppInstallerStrings.h\"\r\n#include \"Public/AppInstallerDateTime.h\"\r\n#include \"Public/winget/UserSettings.h\"\r\n#include <winget/Filesystem.h>\r\n#include <corecrt_io.h>\r\n\r\n\r\nnamespace AppInstaller::Logging\r\n{\r\n    using namespace std::string_view_literals;\r\n    using namespace std::chrono_literals;\r\n\r\n    namespace\r\n    {\r\n        static constexpr std::string_view s_fileLoggerDefaultFilePrefix = \"WinGet\"sv;\r\n        static constexpr std::string_view s_fileLoggerDefaultFileExt = \".log\"sv;\r\n\r\n        // Send to a string first to create a single block to write to a file.\r\n        std::string ToLogLine(Channel channel, std::string_view message)\r\n        {\r\n            std::stringstream strstr;\r\n            strstr << std::chrono::system_clock::now() << \" [\" << std::setw(GetMaxChannelNameLength()) << std::left << std::setfill(' ') << GetChannelName(channel) << \"] \" << message;\r\n            return std::move(strstr).str();\r\n        }\r\n\r\n        // Determines the difference between the given position and the maximum as an offset.\r\n        std::ofstream::off_type CalculateDiff(const std::ofstream::pos_type& position, std::ofstream::off_type maximum)\r\n        {\r\n            auto offsetPosition = static_cast<std::ofstream::off_type>(position);\r\n            return maximum > offsetPosition ? maximum - offsetPosition : 0;\r\n        }\r\n    }\r\n\r\n    FileLogger::FileLogger() : FileLogger(s_fileLoggerDefaultFilePrefix) {}\r\n\r\n    FileLogger::FileLogger(const std::filesystem::path& filePath)\r\n    {\r\n        m_name = GetNameForPath(filePath);\r\n        m_filePath = filePath;\r\n        InitializeDefaultMaximumFileSize();\r\n        OpenFileLoggerStream();\r\n    }\r\n\r\n    FileLogger::FileLogger(const std::string_view fileNamePrefix)\r\n    {\r\n        m_name = \"file\";\r\n        m_filePath = Runtime::GetPathTo(Runtime::PathName::DefaultLogLocation);\r\n        m_filePath /= fileNamePrefix.data() + ('-' + Utility::GetCurrentTimeForFilename() + s_fileLoggerDefaultFileExt.data());\r\n        InitializeDefaultMaximumFileSize();\r\n        OpenFileLoggerStream();\r\n    }\r\n\r\n    FileLogger::~FileLogger()\r\n    {\r\n        m_stream.flush();\r\n        // When std::ofstream is constructed from an existing File handle, it does not call fclose on destruction\r\n        // Only calling close() explicitly will close the file handle.\r\n        m_stream.close();\r\n    }\r\n\r\n    FileLogger& FileLogger::SetMaximumSize(std::ofstream::off_type maximumSize)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, maximumSize < 0);\r\n        m_maximumSize = maximumSize;\r\n        return *this;\r\n    }\r\n\r\n    std::string FileLogger::GetNameForPath(const std::filesystem::path& filePath)\r\n    {\r\n        using namespace std::string_literals;\r\n        return \"file :: \"s + filePath.u8string();\r\n    }\r\n\r\n    std::string_view FileLogger::DefaultPrefix()\r\n    {\r\n        return s_fileLoggerDefaultFilePrefix;\r\n    }\r\n\r\n    std::string_view FileLogger::DefaultExt()\r\n    {\r\n        return s_fileLoggerDefaultFileExt;\r\n    }\r\n\r\n    std::string FileLogger::GetName() const\r\n    {\r\n        return m_name;\r\n    }\r\n\r\n    void FileLogger::Write(Channel channel, Level level, std::string_view message) noexcept try\r\n    {\r\n        std::string log = ToLogLine(channel, message);\r\n        WriteDirect(channel, level, log);\r\n    }\r\n    catch (...) {}\r\n\r\n    void FileLogger::WriteDirect(Channel, Level, std::string_view message) noexcept try\r\n    {\r\n        HandleMaximumFileSize(message);\r\n        m_stream << message << std::endl;\r\n    }\r\n    catch (...) {}\r\n\r\n    void FileLogger::SetTag(Tag tag) noexcept try\r\n    {\r\n        if (tag == Tag::HeadersComplete)\r\n        {\r\n            auto currentPosition = m_stream.tellp();\r\n            if (currentPosition != std::ofstream::pos_type{ -1 })\r\n            {\r\n                m_headersEnd = currentPosition;\r\n            }\r\n        }\r\n    }\r\n    catch (...) {}\r\n\r\n    void FileLogger::Add()\r\n    {\r\n        Log().AddLogger(std::make_unique<FileLogger>());\r\n    }\r\n\r\n    void FileLogger::Add(const std::filesystem::path& filePath)\r\n    {\r\n        Log().AddLogger(std::make_unique<FileLogger>(filePath));\r\n    }\r\n\r\n    void FileLogger::Add(std::string_view fileNamePrefix)\r\n    {\r\n        Log().AddLogger(std::make_unique<FileLogger>(fileNamePrefix));\r\n    }\r\n\r\n    void FileLogger::BeginCleanup()\r\n    {\r\n        BeginCleanup(Runtime::GetPathTo(Runtime::PathName::DefaultLogLocation));\r\n    }\r\n\r\n    void FileLogger::BeginCleanup(const std::filesystem::path& filePath)\r\n    {\r\n        std::thread([filePath]()\r\n            {\r\n                try\r\n                {\r\n                    const auto& settings = Settings::User();\r\n\r\n                    Filesystem::FileLimits fileLimits;\r\n                    fileLimits.Age = settings.Get<Settings::Setting::LoggingFileAgeLimitInDays>();\r\n                    fileLimits.TotalSizeInMB = settings.Get<Settings::Setting::LoggingFileTotalSizeLimitInMB>();\r\n                    fileLimits.Count = settings.Get<Settings::Setting::LoggingFileCountLimit>();\r\n\r\n                    auto filesInPath = Filesystem::GetFileInfoFor(filePath);\r\n                    Filesystem::FilterToFilesExceedingLimits(filesInPath, fileLimits);\r\n\r\n                    for (const auto& file : filesInPath)\r\n                    {\r\n                        std::filesystem::remove(file.Path);\r\n                    }\r\n                }\r\n                // Just throw out everything\r\n                catch (...) {}\r\n            }).detach();\r\n    }\r\n\r\n    void FileLogger::OpenFileLoggerStream() \r\n    {\r\n        // Prevent other writers to our log file, but allow readers\r\n        FILE* filePtr = _wfsopen(m_filePath.wstring().c_str(), L\"w\", _SH_DENYWR);\r\n\r\n        if (filePtr)\r\n        {\r\n            auto closeFile = wil::scope_exit([&]() { fclose(filePtr); });\r\n\r\n            // Prevent inheritance to ensure log file handle is not opened by other processes\r\n            THROW_IF_WIN32_BOOL_FALSE(SetHandleInformation(reinterpret_cast<HANDLE>(_get_osfhandle(_fileno(filePtr))), HANDLE_FLAG_INHERIT, 0));\r\n\r\n            m_stream = std::ofstream{ filePtr };\r\n            closeFile.release();\r\n        }\r\n        else\r\n        {\r\n            AICLI_LOG(Core, Error, << \"Failed to open log file \" << m_filePath.u8string());\r\n            throw std::system_error(errno, std::generic_category());\r\n        }\r\n    }\r\n\r\n    void FileLogger::InitializeDefaultMaximumFileSize()\r\n    {\r\n        m_maximumSize = static_cast<std::ofstream::off_type>(Settings::User().Get<Settings::Setting::LoggingFileIndividualSizeLimitInMB>()) << 20;\r\n    }\r\n\r\n    void FileLogger::HandleMaximumFileSize(std::string_view& currentLog)\r\n    {\r\n        if (m_maximumSize == 0)\r\n        {\r\n            return;\r\n        }\r\n\r\n        auto maximumLogSize = static_cast<size_t>(CalculateDiff(m_headersEnd, m_maximumSize));\r\n\r\n        // In the event that a single log is larger than the maximum\r\n        if (currentLog.size() > maximumLogSize)\r\n        {\r\n            currentLog = currentLog.substr(0, maximumLogSize);\r\n            WrapLogFile();\r\n            return;\r\n        }\r\n\r\n        auto currentPosition = m_stream.tellp();\r\n        if (currentPosition == std::ofstream::pos_type{ -1 })\r\n        {\r\n            // The expectation is that if the stream is in an error state the write won't actually happen.\r\n            return;\r\n        }\r\n\r\n        auto availableSpace = static_cast<size_t>(CalculateDiff(currentPosition, m_maximumSize));\r\n\r\n        if (currentLog.size() > availableSpace)\r\n        {\r\n            WrapLogFile();\r\n            return;\r\n        }\r\n    }\r\n\r\n    void FileLogger::WrapLogFile()\r\n    {\r\n        m_stream.seekp(m_headersEnd);\r\n        // Yes, we may go over the size limit slightly due to this and the unaccounted for newlines\r\n        m_stream << ToLogLine(Channel::Core, \"--- log file has wrapped ---\") << std::endl;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/FolderFileWatcher.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"winget/FolderFileWatcher.h\"\r\n#include \"AppInstallerStrings.h\"\r\n\r\nnamespace AppInstaller::Utility\r\n{\r\n    FolderFileWatcher::FolderFileWatcher(const std::filesystem::path& path, const std::optional<std::string>& ext) :\r\n        m_path(path), m_ext(ext), m_changeReader{}\r\n    {\r\n    }\r\n\r\n    void FolderFileWatcher::Start()\r\n    {\r\n        m_files.clear();\r\n        m_changeReader = wil::make_folder_change_reader(m_path.c_str(),\r\n            true,\r\n            wil::FolderChangeEvents::FileName,\r\n            [this](wil::FolderChangeEvent changeEvent, PCWSTR filePath)\r\n            {\r\n                switch (changeEvent)\r\n                {\r\n                // The file was added to the directory.\r\n                case wil::FolderChangeEvent::Added:\r\n                // The file was renamed and this is the new name.\r\n                case wil::FolderChangeEvent::RenameNewName:\r\n                {\r\n                    std::filesystem::path path(filePath);\r\n                    if (!m_ext.has_value() || Utility::CaseInsensitiveEquals(path.extension().u8string(), *m_ext))\r\n                    {\r\n                        m_files.emplace(path);\r\n                    }\r\n                    break;\r\n                }\r\n\r\n                // The file was removed from the directory.\r\n                case wil::FolderChangeEvent::Removed:\r\n                // The file was renamed and this is the old name.\r\n                case wil::FolderChangeEvent::RenameOldName:\r\n                {\r\n                    std::filesystem::path path(filePath);\r\n                    if (!m_ext.has_value() || Utility::CaseInsensitiveEquals(path.extension().u8string(), *m_ext))\r\n                    {\r\n                        auto it = m_files.find(path);\r\n                        if (it != m_files.cend())\r\n                        {\r\n                            m_files.erase(it);\r\n                        }\r\n                    }\r\n                    break;\r\n                }\r\n\r\n                // The file was modified. This can be a change in the time stamp or attributes.\r\n                case wil::FolderChangeEvent::Modified:\r\n                // A change happens but it got lost. The result of the IoCompletionCallback is ERROR_NOTIFY_ENUM_DIR.\r\n                case wil::FolderChangeEvent::ChangesLost:\r\n                default:\r\n                    break;\r\n                }\r\n            });\r\n    }\r\n\r\n    void FolderFileWatcher::Stop()\r\n    {\r\n        m_changeReader.reset();\r\n    }\r\n}"
  },
  {
    "path": "src/AppInstallerCommonCore/Fonts.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include <AppInstallerErrors.h>\n#include <AppInstallerLogging.h>\n#include <AppInstallerRuntime.h>\n#include <AppInstallerStrings.h>\n#include <winget/Filesystem.h>\n#include <winget/Fonts.h>\n#include <winget/Locale.h>\n#include <winget/Manifest.h>\n#include <winget/ManifestCommon.h>\n#include <winget/Registry.h>\n#include <ShObjIdl_core.h>\n#include <propkey.h>\n#include <wingdi.h>\n\nusing namespace AppInstaller::Utility;\n\nnamespace AppInstaller::Fonts\n{\n    namespace\n    {\n        constexpr std::wstring_view s_FontsPathSubkey = L\"SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\Fonts\";\n        constexpr std::wstring_view s_FontsUserInstallFolder = L\"Microsoft\\\\Windows\\\\Fonts\";\n        constexpr std::wstring_view s_TrueType = L\" (TrueType)\";\n        constexpr std::wstring_view s_IdentifierPrefix = L\"FONT\";\n        constexpr std::wstring_view s_Separator = L\"\\\\\";\n        constexpr std::wstring_view s_FontsWinGetPrefix = L\"Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\";\n        const int s_RemoveFontResourceMaxTries = 1000;\n\n        std::wstring GetFontFileTitle(const std::filesystem::path& fontFilePath)\n        {\n            // This code can fail in a number of ways, including if the file isn't actually\n            // a font file or does not have a title.\n            wil::com_ptr<IPropertyStore> pPropertyStore;\n            THROW_IF_FAILED(SHGetPropertyStoreFromParsingName(fontFilePath.c_str(), nullptr, GPS_DEFAULT, IID_PPV_ARGS(&pPropertyStore)));\n            PROPVARIANT prop;\n            PropVariantInit(&prop);\n            THROW_IF_FAILED(pPropertyStore->GetValue(PKEY_Title, &prop));\n            std::wstring title;\n            if (prop.pwszVal)\n            {\n                title = prop.pwszVal;\n            }\n            THROW_IF_FAILED(PropVariantClear(&prop));\n            return title;\n        }\n\n        void AssertPackageInformation(const FontContext& context)\n        {\n            if (!context.PackageId.empty() && !context.PackageVersion.empty())\n            {\n                return;\n            }\n\n            // This is a programming error if we reach this point where the package identifer cannot be created or derived.\n            THROW_HR_MSG(E_UNEXPECTED, \"Package Id and Version must be provided and non-empty.\");\n        }\n\n        std::wstring GetFontRegistryPath(const FontContext& context)\n        {\n            // Registry path for a font is well-defined based on installer source and package information.\n            auto path = std::wstringstream();\n            path << s_FontsPathSubkey;\n\n            switch (context.InstallerSource)\n            {\n            case InstallerSource::Unknown:\n                // Unknown installer could be anywhere, assume it is in the default fonts location.\n                break;\n            case InstallerSource::WinGet:\n                // WinGet path adds the WinGet prefix + package id + version.\n                path << s_Separator << s_FontsWinGetPrefix << s_Separator << context.PackageId <<\n                    s_Separator << context.PackageVersion;\n                break;\n            default:\n                THROW_HR_MSG(E_UNEXPECTED, \"Undefined InstallerSource.\");\n            }\n\n            return path.str();\n        }\n\n        std::filesystem::path GetRootFontPath(Manifest::ScopeEnum scope)\n        {\n            if (scope == Manifest::ScopeEnum::Machine)\n            {\n                return Runtime::GetPathTo(Runtime::PathName::FontsMachineInstallLocation);\n            }\n            else\n            {\n                return Runtime::GetPathTo(Runtime::PathName::FontsUserInstallLocation);\n            }\n        }\n\n        std::filesystem::path GetFontFileInstallPath(const FontContext& context)\n        {\n            auto path = GetRootFontPath(context.Scope);\n\n            switch (context.InstallerSource)\n            {\n            case InstallerSource::Unknown:\n                // Unknown installer is assumed to be installed in the default location for machine.\n                // For a user installed font it could be anywhere.\n                break;\n            case InstallerSource::WinGet:\n                // WinGet installed packages have two formats depending on the scope.\n                // For Per-user we use subfolders for better robustness and cleaner format.\n                // For Per-machine we must use a single folder due to a system requirement,\n                // so the root path is the machine install path.\n                if (context.Scope == Manifest::ScopeEnum::User)\n                {\n                    AssertPackageInformation(context);\n                    path /= s_FontsWinGetPrefix;\n                    path /= context.PackageId;\n                    path /= context.PackageVersion;\n                }\n\n                break;\n            default:\n                THROW_HR_MSG(E_UNEXPECTED, \"Undefined InstallerSource.\");\n            }\n\n            return path;\n        }\n\n        // For machine-installed fonts the files all reside in the same folder. We need a unique name that is reasonably human\n        // readable. The way system fonts normally do this is by appending a number to the end of the file stem. We will follow\n        // the same pattern by using the original file and adding a number until we arrive at a unique filename.\n        std::filesystem::path GetUniquePathForDestination(const std::filesystem::path& source, const std::filesystem::path& destination)\n        {\n            const auto stem = source.stem();\n            const auto ext = source.extension();\n            auto uniqueName = source.filename();\n            auto candidatePath = destination / uniqueName;\n            int index = 0;\n            while (std::filesystem::exists(candidatePath))\n            {\n                std::filesystem::path appendId = { std::to_string(index) };\n                uniqueName = stem;\n                uniqueName += appendId;\n                uniqueName += ext;\n                candidatePath = destination / uniqueName;\n                index++;\n            }\n\n            return candidatePath;\n        }\n\n        std::vector<std::filesystem::path> GetFontFilePaths(const wil::com_ptr<IDWriteFontFace>& fontFace)\n        {\n            UINT32 fileCount = 0;\n            THROW_IF_FAILED(fontFace->GetFiles(&fileCount, nullptr));\n\n            static_assert(sizeof(wil::com_ptr<IDWriteFontFile>) == sizeof(IDWriteFontFile*));\n            std::vector<wil::com_ptr<IDWriteFontFile>> fontFiles;\n            fontFiles.resize(fileCount);\n\n            THROW_IF_FAILED(fontFace->GetFiles(&fileCount, fontFiles[0].addressof()));\n\n            std::vector<std::filesystem::path> filePaths;\n            for (UINT32 i = 0; i < fileCount; ++i) {\n                wil::com_ptr<IDWriteFontFileLoader> loader;\n                THROW_IF_FAILED(fontFiles[i]->GetLoader(loader.addressof()));\n\n                const void* fontFileReferenceKey;\n                UINT32 fontFileReferenceKeySize;\n                THROW_IF_FAILED(fontFiles[i]->GetReferenceKey(&fontFileReferenceKey, &fontFileReferenceKeySize));\n\n                if (const auto localLoader = loader.try_query<IDWriteLocalFontFileLoader>()) {\n                    UINT32 pathLength;\n                    THROW_IF_FAILED(localLoader->GetFilePathLengthFromKey(fontFileReferenceKey, fontFileReferenceKeySize, &pathLength));\n                    pathLength += 1; // Account for the trailing null terminator during allocation.\n\n                    std::wstring path;\n                    path.resize(pathLength);\n                    THROW_IF_FAILED(localLoader->GetFilePathFromKey(fontFileReferenceKey, fontFileReferenceKeySize, &path[0], pathLength));\n                    path.resize(pathLength - 1); // Remove the null char.\n                    filePaths.emplace_back(std::move(path));\n                }\n            }\n\n            return filePaths;\n        }\n\n        void RemoveAllFontResources(const std::filesystem::path& filePath)\n        {\n            // The recommended uninstall method of a font is to call RemoveFontResource until it fails,\n            // This is not guaranteed to remove the file from use, but it is the best we have.\n            // https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-removefontresourcea\n            int i = 0;\n            while (::RemoveFontResource(filePath.c_str()))\n            {\n                // Let us not loop endlessly.\n                if (++i >= s_RemoveFontResourceMaxTries)\n                {\n                    break;\n                }\n            }\n        }\n\n        void NotifyFontChange()\n        {\n            // Send the WM_FONTCHANGE message so the system and apps know that there has been a font change.\n            // Sometimes this does not have an error when it returns non-zero. To avoid random assert failures\n            // we will not try to log failures for this call. If it fails it does not affect install state.\n            auto sendResult = ::SendNotifyMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);\n            AICLI_LOG(Core, Info, << \"Notified system of font change: \" << sendResult);\n        }\n\n        // Checks the registry path for the file specified, and returns the key value if it finds one.\n        std::optional<std::wstring> CheckRegistryForFontFileReference(const std::wstring& registryPath, const std::filesystem::path& filePath, Manifest::ScopeEnum scope)\n        {\n            try\n            {\n                const auto& hive = scope == Manifest::ScopeEnum::Machine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;\n                const auto& key = Registry::Key::OpenIfExists(hive, registryPath, 0UL, KEY_READ);\n                if (key)\n                {\n                    // Check for the file being present in this key.\n                    for (const auto& valueRef : key.Values())\n                    {\n                        const auto& value = valueRef.Value();\n                        if (!value.has_value() || (value.value().GetType() != Registry::Value::Type::String))\n                        {\n                            continue;\n                        }\n                        const auto& valueName = ConvertToUTF16(valueRef.Name());\n                        const std::filesystem::path& valuePath = { value->GetValue<Registry::Value::Type::String>() };\n                        if (valuePath.is_relative())\n                        {\n                            // Relative value is OK, just compare the filenames.\n                            // We will assume this is in the standard font paths.\n                            if (valuePath.filename() == filePath.filename())\n                            {\n                                return valueName;\n                            }\n                        }\n                        else\n                        {\n                            if (valuePath == filePath)\n                            {\n                                return valueName;\n                            }\n                        }\n                    }\n                }\n            }\n            CATCH_LOG();\n\n            return std::nullopt;\n        }\n\n        // The package registry for machine installed fonts stores the package filename as a registry value.\n        // This is so we can map the original package filename to the installed filename since they may be different.\n        std::optional<std::filesystem::path> GetRegisteredMachineFontInstallPath(const std::wstring& registryPath, const std::filesystem::path& filePath)\n        {\n            try\n            {\n                const auto& key = Registry::Key::OpenIfExists(HKEY_LOCAL_MACHINE, registryPath, 0UL, KEY_READ);\n                if (key)\n                {\n                    for (const auto& valueRef : key.Values())\n                    {\n                        const auto& value = valueRef.Value();\n                        if (!value.has_value() || (value.value().GetType() != Registry::Value::Type::String))\n                        {\n                            continue;\n                        }\n\n                        const auto& valueName = ConvertToUTF16(valueRef.Name());\n                        if (valueName == filePath.filename())\n                        {\n                            const std::filesystem::path& valuePath = { value->GetValue<Registry::Value::Type::String>() };\n                            return valuePath;\n                        }\n                    }\n                }\n            }\n            CATCH_LOG();\n\n            return std::nullopt;\n        }\n    }\n\n    FontResult FontOperationResult::Result() const\n    {\n        if (FAILED(HResult))\n        {\n            return FontResult::Error;\n        }\n        else\n        {\n            return FontResult::Success;\n        }\n    }\n\n    void FontContext::AddPackageFile(const std::filesystem::path& filePath)\n    {\n        PackageFiles.push_back(filePath);\n    }\n\n    Manifest::AppsAndFeaturesEntry FontContext::GetAppsAndFeaturesEntry() const\n    {\n        Manifest::AppsAndFeaturesEntry entry;\n        entry.DisplayName = ConvertToUTF8(PackageId);\n        entry.DisplayVersion = ConvertToUTF8(PackageVersion);\n        entry.InstallerType = Manifest::InstallerTypeEnum::Font;\n\n        // Product Code is the PackageId\n        entry.ProductCode = ConvertToUTF8(PackageId);\n        return entry;\n    }\n\n    std::wstring FontContext::GetPackageIdentifier() const\n    {\n        auto stream = std::wstringstream();\n        stream << s_IdentifierPrefix << s_Separator << ConvertToUTF16(Manifest::ScopeToString(Scope)) << s_Separator << PackageId;\n        return stream.str();\n    }\n\n    // Creates font file info used for install, validation, and enumeration.\n    FontFileInfo CreateFontFileInfo(const FontContext& context, const std::filesystem::path& filePath, const std::wstring& title)\n    {\n        auto fileInfo = FontFileInfo();\n        fileInfo.FilePath = filePath;\n        fileInfo.PackageIdentifier = context.GetPackageIdentifier();\n        fileInfo.PackageId = context.PackageId;\n        fileInfo.PackageVersion = context.PackageVersion;\n        fileInfo.InstallerSource = context.InstallerSource;\n        fileInfo.Scope = context.Scope;\n        fileInfo.Title = title;\n\n        // For font file paths in the registry, we may have a relative filename (because the path is assumed).\n        if (fileInfo.FilePath.is_relative())\n        {\n            // Relative path is assumed to be relative to the default location for the scope.\n            // We are assuming that a relative file path input refers to an already-installed file.\n            auto fullPath = GetRootFontPath(fileInfo.Scope);\n            fullPath /= fileInfo.FilePath;\n            fileInfo.FilePath = std::move(fullPath);\n        }\n\n        // Get information about the font file itself.\n        auto fontCatalog = FontCatalog();\n        fileInfo.WinGetSupported = fontCatalog.IsFontFileSupported(fileInfo.FilePath, fileInfo.FileType);\n        if (fileInfo.WinGetSupported && fileInfo.Title.empty())\n        {\n            try\n            {\n                fileInfo.Title = GetFontFileTitle(fileInfo.FilePath);\n            }\n            CATCH_LOG();\n        }\n\n        if (fileInfo.Title.empty())\n        {\n            // If the title is still empty (such as failure to set it from the File), use the Filename\n            fileInfo.Title = fileInfo.FilePath.filename().wstring();\n        }\n\n        fileInfo.RegistryPackagePath = GetFontRegistryPath(context);\n        if (fileInfo.Scope == Manifest::ScopeEnum::Machine && fileInfo.InstallerSource == InstallerSource::WinGet)\n        {\n            // Machine fonts from WinGet still install into the Font folder but we track package source separately\n            // due to limited information in the Font registry and all font files being in the same key and folder.\n            fileInfo.RegistryInstallPath = s_FontsPathSubkey;\n        }\n        else\n        {\n            // User-installed and non-Winget fonts have same registry package path and install path.\n            fileInfo.RegistryInstallPath = fileInfo.RegistryPackagePath;\n        }\n\n        // Check if the file is already in the install path, in which case this is a query.\n        auto const& installPath = GetFontFileInstallPath(context);\n        if (installPath == fileInfo.FilePath.parent_path())\n        {\n            fileInfo.InstallPath = fileInfo.FilePath;\n        }\n        else\n        {\n            if (fileInfo.InstallerSource == InstallerSource::WinGet && fileInfo.Scope == Manifest::ScopeEnum::Machine)\n            {\n                // Machine installed WinGet fonts must have a non-conflicting filename in the root font folder.\n                // To ensure a unique font name and allow different versions to exist side by side, the install file\n                // name may be a different name from the original package install. To account for this, the Package\n                // registry location uses the original filename as the registry value name and the value as the\n                // resulting path. If we are installing a machine font that already exists, we must check to see\n                // if this file already has a mapping defined.\n                const auto& installedFilePath = GetRegisteredMachineFontInstallPath(fileInfo.RegistryPackagePath, fileInfo.FilePath.filename());\n                if (installedFilePath.has_value())\n                {\n                    fileInfo.InstallPath = installedFilePath.value();\n                }\n                else\n                {\n                    // File not already defined, we need to create a non-conflicting filename.\n                    // Machine-installed WinGet must provide a non-conflicting filename to the root install location.\n                    fileInfo.InstallPath = GetUniquePathForDestination(fileInfo.FilePath, installPath);\n                }\n            }\n            else\n            {\n                fileInfo.InstallPath = installPath / fileInfo.FilePath.filename();\n            }\n        }\n\n        // If our font file is registered it will exist in the install path and have a registry value.\n        const auto& registryTitle = CheckRegistryForFontFileReference(fileInfo.RegistryInstallPath, fileInfo.InstallPath, fileInfo.Scope);\n\n        if (fileInfo.Title.empty())\n        {\n            // Use the registry title or filename if we still dont' know.\n            if (registryTitle.has_value())\n            {\n                fileInfo.Title = registryTitle.value();\n            }\n            else\n            {\n                fileInfo.Title = fileInfo.FilePath.filename().wstring();\n            }\n        }\n\n        fileInfo.IsFontFileInstalled = std::filesystem::exists(fileInfo.InstallPath) ? true : false;\n        fileInfo.IsFontFileRegistered = registryTitle.has_value() ? true : false;\n        if (fileInfo.IsFontFileInstalled && fileInfo.IsFontFileRegistered)\n        {\n            fileInfo.Status = FontStatus::OK;\n        }\n        else if (fileInfo.IsFontFileInstalled || fileInfo.IsFontFileRegistered)\n        {\n            fileInfo.Status = FontStatus::Corrupt;\n        }\n        else\n        {\n            fileInfo.Status = FontStatus::Absent;\n        }\n\n        return fileInfo;\n    }\n\n    FontValidationResult ValidateFontPackage(FontContext& context)\n    {\n        AssertPackageInformation(context);\n\n        auto result = FontValidationResult();\n\n        AICLI_LOG(Core, Info, << \"Validating font package: \" << context.PackageId.c_str() << \" \" << context.PackageVersion.c_str());\n\n        try\n        {\n            // Create font file info for each package file\n            for (const auto& file : context.PackageFiles)\n            {\n                result.FontFileInfos.push_back(CreateFontFileInfo(context, file));\n            }\n\n            // We create an overall status for the validation with the following determination:\n            // If ALL of the files are OK, the package is OK.\n            // If ALL of the files are Absent, the package is Absent.\n            // If there is any combination, the package is Corrupt.\n            // We must check each file info to see if the package is supported by WinGet.\n            // If any file is unsupported then there are unsupported fonts in the package.\n            for (const auto& fontFileInfo : result.FontFileInfos)\n            {\n                if (!fontFileInfo.WinGetSupported)\n                {\n                    result.HasUnsupportedFonts = true;\n                }\n\n                if (fontFileInfo.Status != result.Status)\n                {\n                    if (result.Status == FontStatus::Unknown)\n                    {\n                        // This is the first status we've seen, make it the default.\n                        result.Status = fontFileInfo.Status;\n                    }\n                    else\n                    {\n                        // Previous status now differs from current status, package is corrupt.\n                        result.Status = FontStatus::Corrupt;\n                    }\n                }\n            }\n\n            result.Result = FontResult::Success;\n        }\n        catch (...)\n        {\n            LOG_CAUGHT_EXCEPTION();\n            result.HResult = APPINSTALLER_CLI_ERROR_FONT_VALIDATION_FAILED;\n            result.Result = FontResult::Error;\n        }\n\n        return result;\n    }\n\n    FontOperationResult InstallFontPackage(FontContext& context)\n    {\n        AssertPackageInformation(context);\n\n        FontOperationResult result;\n\n        if (context.InstallerSource != InstallerSource::WinGet)\n        {\n            throw std::logic_error(\"Only WinGet format of font install is supported.\");\n        }\n\n        if (context.PackageFiles.size() == 0)\n        {\n            result.HResult = winrt::hresult(APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_FOUND);\n            AICLI_LOG(Core, Error, << \"Font package has no files: \" << context.PackageId.c_str() << \" - \" << AppInstaller::Logging::SetHRFormat << result.HResult);\n            return result;\n        }\n\n        // Validate the package data was all processed successfully.\n        const auto& validationResult = ValidateFontPackage(context);\n        if (validationResult.Result != FontResult::Success)\n        {\n            result.HResult = winrt::hresult(APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_SUPPORTED);\n            AICLI_LOG(Core, Error, << \"Font package validation failed: \" << context.PackageId.c_str() << \" - \" << AppInstaller::Logging::SetHRFormat << validationResult.HResult);\n            return result;\n        }\n\n        // Check for unsupported font files.\n        if (validationResult.HasUnsupportedFonts)\n        {\n            result.HResult = winrt::hresult(APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_SUPPORTED);\n            AICLI_LOG(Core, Error, << \"Font package has unsupported fonts: \" << context.PackageId.c_str() << \" - \" << result.HResult);\n            return result;\n        }\n\n        // Check for package already installed and correct unless this is a force install.\n        if (validationResult.Status == FontStatus::OK && !context.Force)\n        {\n            result.HResult = winrt::hresult(APPINSTALLER_CLI_ERROR_FONT_ALREADY_INSTALLED);\n            AICLI_LOG(Core, Info, << \"Font package is already installed and in a good state.: \" << context.PackageId.c_str() << \" - \" << AppInstaller::Logging::SetHRFormat << result.HResult);\n            return result;\n        }\n\n        // We will attempt a cleanup / force install if either this is a forced install or the package was not in a good state.\n        if (validationResult.Status == FontStatus::Corrupt || context.Force)\n        {\n            // Force install of a font can have problems because if the font is already there then it\n            // may be in use. The scenarios for using force is if a prior install attempt failed, so\n            // we will try to clean up the existing font registration so it may be successful this time.\n            AICLI_LOG(Core, Info, << \"Package is corrupt or forced install, attempting to remove any existing registration.\");\n            auto uninstallResult = UninstallFontPackage(context);\n            if (uninstallResult.Result() != FontResult::Success)\n            {\n                result.HResult = uninstallResult.HResult;\n                AICLI_LOG(Core, Error, << \"Font cleanup uninstall failed: \" << context.PackageId.c_str() << \" - \" << AppInstaller::Logging::SetHRFormat << uninstallResult.HResult);\n                return result;\n            }\n        }\n\n        AICLI_LOG(Core, Info, << \"Starting install of \" << context.PackageId.c_str());\n\n        try\n        {\n            // Install each file from the file info.\n            for (const auto& fontFileInfo : validationResult.FontFileInfos)\n            {\n                // Font install step 1: Copy file to winget package identifiable location.\n                AICLI_LOG(Core, Info, << \"Moving \" << fontFileInfo.FilePath << \" to \" << fontFileInfo.InstallPath);\n                if (!std::filesystem::exists(fontFileInfo.InstallPath.parent_path()))\n                {\n                    std::filesystem::create_directories(fontFileInfo.InstallPath.parent_path());\n                }\n\n                // The file should not be present, but if it is, do another attempt to remove it.\n                if (std::filesystem::exists(fontFileInfo.InstallPath))\n                {\n                    // Try to remove font resource to avoid file-in-use.\n                    RemoveAllFontResources(fontFileInfo.InstallPath);\n                    if (!std::filesystem::remove(fontFileInfo.InstallPath))\n                    {\n                        AICLI_LOG(Core, Error, << \"Font file already exists and was unable to be removed.\");\n                        THROW_HR(APPINSTALLER_CLI_ERROR_FONT_INSTALL_FAILED);\n                    }\n                }\n\n                if (context.Scope == Manifest::ScopeEnum::Machine)\n                {\n                    // Using std::filesystem::rename does not work when installing into the system Fonts\n                    // folder; the system does not recognize the font files. std::filesystem::copy_file does work.\n                    std::filesystem::copy_file(fontFileInfo.FilePath, fontFileInfo.InstallPath);\n                    std::filesystem::remove(fontFileInfo.FilePath);\n                }\n                else\n                {\n                    // We prefer to use rename where it works.\n                    AppInstaller::Filesystem::RenameFile(fontFileInfo.FilePath, fontFileInfo.InstallPath);\n                }\n\n                AICLI_LOG(Core, Info, << \"Adding \" << fontFileInfo.Title.c_str() << \" to \" << fontFileInfo.InstallPath);\n                if (context.Scope == Manifest::ScopeEnum::User)\n                {\n                    auto key = Registry::Key::Create(HKEY_CURRENT_USER, fontFileInfo.RegistryInstallPath);\n                    key.SetValue(fontFileInfo.Title, fontFileInfo.InstallPath, REG_SZ);\n                }\n                else\n                {\n                    // Machine install we set two keys, one for source information, and one for the actual install.\n                    // The value name is the source filename so we can map this later for validation.\n                    auto sourceKey = Registry::Key::Create(HKEY_LOCAL_MACHINE, fontFileInfo.RegistryPackagePath, 0UL, KEY_ALL_ACCESS);\n                    sourceKey.SetValue(fontFileInfo.FilePath.filename(), fontFileInfo.InstallPath, REG_SZ);\n\n                    // Machine font install uses relative filename. Use filename as value to avoid collisions in the key.\n                    auto installKey = Registry::Key::OpenIfExists(HKEY_LOCAL_MACHINE, fontFileInfo.RegistryInstallPath, 0UL, KEY_ALL_ACCESS);\n                    installKey.SetValue(fontFileInfo.InstallPath.filename(), fontFileInfo.InstallPath.filename(), REG_SZ);\n                }\n\n                // Add Font Resource to the session.\n                const auto& fontsAdded = ::AddFontResource(fontFileInfo.InstallPath.c_str());\n                if (fontsAdded == 0)\n                {\n                    // AddFontResource does not add additional information for us, so we dont know why they were not added,\n                    // only that they were not added. At this point the \"install\" is successful, but we were not able to\n                    // add the font to the system, which means subsequent adds on session start may also fail, but is not\n                    // guaranteed to fail. We will note it in the log and carry on.\n                    AICLI_LOG(Core, Warning, << \"Failed to add font resource: \" << fontFileInfo.InstallPath);\n                }\n                else\n                {\n                    AICLI_LOG(Core, Info, << \"Added \" << fontsAdded << \" fonts to the session.\");\n                }\n            }\n\n            result.HResult = S_OK;\n        }\n        catch (...)\n        {\n            LOG_CAUGHT_EXCEPTION();\n            AICLI_LOG(Core, Error, << \"Install failed for \" << context.PackageId.c_str() << \", attempting rollback.\");\n\n            try\n            {\n                // Rollback. In this case, rollback is uninstall, which should remove any partial installation.\n                // This is best-effort.\n                auto rollbackResult = UninstallFontPackage(context);\n                if (rollbackResult.Result() == FontResult::Success)\n                {\n                    AICLI_LOG(Core, Info, << \"Rollback for \" << context.PackageId.c_str() << \" successful.\");\n                }\n                else\n                {\n                    AICLI_LOG(Core, Error, << \"Rollback for \" << context.PackageId.c_str() << \" failed: \" << AppInstaller::Logging::SetHRFormat << rollbackResult.HResult);\n                }\n            }\n            CATCH_LOG();\n\n            result.HResult = APPINSTALLER_CLI_ERROR_FONT_INSTALL_FAILED;\n        }\n\n        // Regardless of the result there's likely some changes that occurred.\n        NotifyFontChange();\n        return result;\n    }\n\n    FontOperationResult UninstallFontPackage(FontContext& context)\n    {\n        FontOperationResult result;\n\n        if (context.InstallerSource != InstallerSource::WinGet)\n        {\n            throw std::logic_error(\"Only WinGet format of font package uninstall is supported.\");\n        }\n\n        AssertPackageInformation(context);\n\n        const auto& installFolderPath = GetFontFileInstallPath(context);\n        const auto& installPackagePath = GetFontRegistryPath(context);\n        std::vector<std::filesystem::path> filesToRemove;\n\n        try\n        {\n            auto hive = context.Scope == Manifest::ScopeEnum::Machine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;\n            auto key = Registry::Key::OpenIfExists(hive, installPackagePath, 0ul, KEY_ALL_ACCESS);\n\n            if (key)\n            {\n                // Assume all values in this key are fonts related to this package.\n                for (const auto& fontEntry : key.Values())\n                {\n                    auto value = fontEntry.Value();\n                    if (!value.has_value() || (value.value().GetType() != Registry::Value::Type::String))\n                    {\n                        // Not a valid entry, nothing to do here.\n                        continue;\n                    }\n\n                    std::filesystem::path filePath = { value->GetValue<Registry::Value::Type::String>() };\n                    if (!std::filesystem::exists(filePath))\n                    {\n                        // File doesn't exist, nothing to do here.\n                        continue;\n                    }\n\n                    // The font may be in use by the system or other apps, it needs to be removed from\n                    // from use or at least attempted to be removed from use.\n                    RemoveAllFontResources(filePath);\n                    filesToRemove.push_back(filePath);\n                }\n\n                // Delete the key\n                if (!Registry::Key::DeleteTree(hive, installPackagePath))\n                {\n                    AICLI_LOG(Core, Warning, << \"Failed removing registry tree \" << installPackagePath.c_str());\n                }\n\n                if (context.Scope == Manifest::ScopeEnum::Machine)\n                {\n                    // Machine installed fonts also have an entry in the System font registry.\n                    // We have to find the values that have the filename as data.\n                    auto machineFontRoot = Registry::Key::OpenIfExists(HKEY_LOCAL_MACHINE, s_FontsPathSubkey.data(), 0ul, KEY_ALL_ACCESS);\n\n                    for (const auto& file : filesToRemove)\n                    {\n                        machineFontRoot.DeleteValue(file.filename());\n                    }\n                }\n            }\n        }\n        catch (...)\n        {\n            LOG_CAUGHT_EXCEPTION();\n\n            // For uninstall we will log the error and continue trying to remove it, since we have partial remove and are in an unknown state.\n            AICLI_LOG(Core, Error, << \"Failed removing fonts in the registry.\");\n        }\n\n        // Remove any font files.\n        for (const auto& file : filesToRemove)\n        {\n            try\n            {\n                if (std::filesystem::exists(file))\n                {\n                    // TODO: Add robustness for files-in-use scenarios.\n                    std::filesystem::remove(file);\n                }\n            }\n            catch (...)\n            {\n                LOG_CAUGHT_EXCEPTION();\n                AICLI_LOG(Core, Error, << \"Failed removing font files.\");\n                result.HResult = winrt::hresult(APPINSTALLER_CLI_ERROR_FONT_UNINSTALL_FAILED);\n            }\n        }\n\n        if (context.Scope == Manifest::ScopeEnum::User)\n        {\n            // User installed fonts also have an install folder, we will clean that up as well.\n            if (std::filesystem::exists(installFolderPath))\n            {\n                try\n                {\n                    const auto& parent = installFolderPath.parent_path();\n                    std::filesystem::remove_all(installFolderPath);\n\n                    // This may have been the only version installed, so remove parent if empty.\n                    if (std::filesystem::is_empty(parent))\n                    {\n                        std::filesystem::remove(parent);\n                    }\n                }\n                catch (...)\n                {\n                    // Font files have already been removed at this point, so failure to delete\n                    // this folder is not a failure of removing the fonts.\n                    LOG_CAUGHT_EXCEPTION();\n                    AICLI_LOG(Core, Error, << \"Failed removing font folders.\");\n                }\n            }\n        }\n\n        // Notify system of font changes.\n        NotifyFontChange();\n        return result;\n    }\n\n    std::wstring GetFontRegistryRoot()\n    {\n        return s_FontsPathSubkey.data();\n    }\n\n    FontCatalog::FontCatalog()\n    {\n        m_preferredLocales = AppInstaller::Locale::GetUserPreferredLanguagesUTF16();\n        THROW_IF_FAILED(DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(m_factory), m_factory.put_unknown()));\n    }\n\n    std::vector<FontFamily> FontCatalog::GetInstalledFontFamilies(std::optional<std::wstring> familyName)\n    {\n        wil::com_ptr<IDWriteFontCollection> collection;\n        THROW_IF_FAILED(m_factory->GetSystemFontCollection(collection.addressof(), FALSE));\n\n        std::vector<FontFamily> installedFontFamilies;\n\n        if (familyName.has_value())\n        {\n            UINT32 index;\n            BOOL exists;\n            THROW_IF_FAILED(collection->FindFamilyName(familyName.value().c_str(), &index, &exists));\n\n            if (exists)\n            {\n                installedFontFamilies.emplace_back(GetFontFamilyByIndex(collection, index));\n            }\n        }\n        else\n        {\n            UINT32 familyCount = collection->GetFontFamilyCount();\n\n            for (UINT32 index = 0; index < familyCount; index++)\n            {\n                installedFontFamilies.emplace_back(GetFontFamilyByIndex(collection, index));\n            }\n        }\n\n        return installedFontFamilies;\n    }\n\n    bool FontCatalog::IsFontFileSupported(const std::filesystem::path& filePath, DWRITE_FONT_FILE_TYPE& fileType)\n    {\n        if (!std::filesystem::exists(filePath))\n        {\n            fileType = DWRITE_FONT_FILE_TYPE_UNKNOWN;\n            return false;\n        }\n\n        wil::com_ptr<IDWriteFontFile> fontFile;\n        THROW_IF_FAILED(m_factory->CreateFontFileReference(filePath.c_str(), NULL, &fontFile));\n\n        BOOL isSupported;\n        DWRITE_FONT_FACE_TYPE faceType;\n        UINT32 numOfFaces;\n        THROW_IF_FAILED(fontFile->Analyze(&isSupported, &fileType, &faceType, &numOfFaces));\n        return isSupported;\n    }\n\n    std::wstring FontCatalog::GetLocalizedStringFromFont(const wil::com_ptr<IDWriteLocalizedStrings>& localizedStringCollection)\n    {\n        UINT32 index = 0;\n        BOOL exists = false;\n\n        for (const auto& locale : m_preferredLocales)\n        {\n            if (SUCCEEDED_LOG(localizedStringCollection->FindLocaleName(locale.c_str(), &index, &exists)) && exists)\n            {\n                break;\n            }\n        }\n\n        // If the locale does not exist, resort to the default value at the 0 index.\n        if (!exists)\n        {\n            index = 0;\n        }\n\n        UINT32 length = 0;\n        THROW_IF_FAILED(localizedStringCollection->GetStringLength(index, &length));\n        length += 1; // Account for the trailing null terminator during allocation.\n\n        std::wstring localizedString;\n        localizedString.resize(length);\n        THROW_IF_FAILED(localizedStringCollection->GetString(index, &localizedString[0], length));\n        localizedString.resize(length - 1); // Remove the null char.\n        return localizedString;\n    }\n\n    std::wstring FontCatalog::GetFontFaceName(const wil::com_ptr<IDWriteFont>& font)\n    {\n        wil::com_ptr<IDWriteLocalizedStrings> faceNames;\n        THROW_IF_FAILED(font->GetFaceNames(faceNames.addressof()));\n        return GetLocalizedStringFromFont(faceNames);\n    }\n\n    std::wstring FontCatalog::GetFontFamilyName(const wil::com_ptr<IDWriteFontFamily>& fontFamily)\n    {\n        wil::com_ptr<IDWriteLocalizedStrings> familyNames;\n        THROW_IF_FAILED(fontFamily->GetFamilyNames(familyNames.addressof()));\n        return GetLocalizedStringFromFont(familyNames);\n    }\n\n    Utility::OpenTypeFontVersion FontCatalog::GetFontFaceVersion(const wil::com_ptr<IDWriteFont>& font)\n    {\n        wil::com_ptr<IDWriteLocalizedStrings> fontVersion;\n        BOOL exists;\n        THROW_IF_FAILED(font->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_VERSION_STRINGS, fontVersion.addressof(), &exists));\n        if (!exists)\n        {\n            return {};\n        }\n\n        std::string value = ConvertToUTF8(GetLocalizedStringFromFont(fontVersion));\n        Utility::OpenTypeFontVersion openTypeFontVersion{ value };\n        return openTypeFontVersion;\n    }\n\n    FontFamily FontCatalog::GetFontFamilyByIndex(const wil::com_ptr<IDWriteFontCollection>& collection, UINT32 index)\n    {\n        wil::com_ptr<IDWriteFontFamily> family;\n        THROW_IF_FAILED(collection->GetFontFamily(index, family.addressof()));\n        std::wstring familyName = GetFontFamilyName(family);\n\n        std::vector<FontFace> fontFaces;\n        UINT32 fontCount = family->GetFontCount();\n        for (UINT32 fontIndex = 0; fontIndex < fontCount; fontIndex++)\n        {\n            wil::com_ptr<IDWriteFont> font;\n            THROW_IF_FAILED(family->GetFont(fontIndex, font.addressof()));\n\n            wil::com_ptr<IDWriteFontFace> fontFace;\n            THROW_IF_FAILED(font->CreateFontFace(fontFace.addressof()));\n\n            FontFace fontFaceEntry;\n            fontFaceEntry.Name = GetFontFaceName(font);\n            fontFaceEntry.Version = GetFontFaceVersion(font);\n            fontFaceEntry.FilePaths = GetFontFilePaths(fontFace);\n            fontFaces.emplace_back(std::move(fontFaceEntry));\n        }\n\n        FontFamily fontFamily;\n        fontFamily.Name = std::move(familyName);\n        fontFamily.Faces = std::move(fontFaces);\n        return fontFamily;\n    }\n\n    // This will create an inventory of all known permanently installed fonts to the user.\n    // A font is \"permanently installed\" if it is present in the Font registry for the machine or the user.\n    // This will not include fonts that are temporarily installed for the session.\n    std::vector<FontFileInfo> GetInstalledFontFiles()\n    {\n        auto fontFiles = std::vector<FontFileInfo>();\n\n        try\n        {\n            auto wingetMachineFonts = std::unordered_map<std::filesystem::path, bool>();\n\n            // Iterate through scopes for machine and user\n            for (const auto& scope : { Manifest::ScopeEnum::Machine, Manifest::ScopeEnum::User })\n            {\n                auto hive = scope == Manifest::ScopeEnum::Machine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;\n                auto root = Registry::Key::OpenIfExists(hive, std::wstring{ s_FontsPathSubkey });\n\n                // There are two supported scenarios for tracking sub-keys.\n                // 1) We created the subkey, therefore it is a winget installed font.\n                // 2) A package created the subkey for a package-deployed font\n                // We assume that all sub-keys not the WinGet key are packaged keys. It is not guaranteed that\n                // a package created the font, but we will assume that it is to be safe in how we handle them.\n                for (const auto& subkey : root)\n                {\n                    auto subkeyName = ConvertToUTF16(subkey.Name());\n                    auto subkeyKey = subkey.Open();\n                    if (subkeyName == s_FontsWinGetPrefix)\n                    {\n                        // Assume all sub-keys are WinGet Packages\n                        for (const auto& packageSubKey : subkeyKey)\n                        {\n                            // All sub-keys should be versions of the package.\n                            auto wingetPackageSubKey = packageSubKey.Open();\n                            for (const auto& versionSubKey : wingetPackageSubKey)\n                            {\n                                auto packageId = ConvertToUTF16(packageSubKey.Name());\n                                auto version = ConvertToUTF16(versionSubKey.Name());\n                                auto packageVersionSubKey = versionSubKey.Open();\n                                for (const auto& versionValue : packageVersionSubKey.Values())\n                                {\n                                    // Values are the files.\n                                    auto value = versionValue.Value();\n                                    if (!value.has_value() || (value.value().GetType() != Registry::Value::Type::String))\n                                    {\n                                        continue;\n                                    }\n\n                                    std::filesystem::path filePath = { value->GetValue<Registry::Value::Type::String>() };\n                                    if (scope == Manifest::ScopeEnum::Machine)\n                                    {\n                                        // Capture the filename for winget machine fonts so we can avoid duplicates.\n                                        wingetMachineFonts[filePath.filename()] = true;\n                                    }\n\n                                    auto context = FontContext();\n                                    context.Scope = scope;\n                                    context.InstallerSource = InstallerSource::WinGet;\n                                    context.PackageId = packageId;\n                                    context.PackageVersion = version;\n                                    auto fontFile = CreateFontFileInfo(context, filePath, ConvertToUTF16(versionValue.Name()));\n                                    fontFiles.push_back(std::move(fontFile));\n                                }\n                            }\n                        }\n                    }\n                }\n\n                // All remaining values in the root are externally installed fonts.\n                for (const auto& rootValue : root.Values())\n                {\n                    auto value = rootValue.Value();\n                    if (!value.has_value() || (value.value().GetType() != Registry::Value::Type::String))\n                    {\n                        continue;\n                    }\n\n                    std::filesystem::path filePath = { value->GetValue<Registry::Value::Type::String>() };\n                    if (scope == Manifest::ScopeEnum::Machine)\n                    {\n                        // Skip it if this is already identified in the WinGet machine fonts.\n                        if (wingetMachineFonts[filePath.filename()])\n                        {\n                            continue;\n                        }\n                    }\n\n                    auto context = FontContext();\n                    context.Scope = scope;\n                    context.InstallerSource = InstallerSource::Unknown;\n                    context.PackageId = filePath.filename();\n                    auto fontFile = CreateFontFileInfo(context, filePath, ConvertToUTF16(rootValue.Name()));\n                    fontFiles.push_back(std::move(fontFile));\n                }\n            }\n        }\n        catch (...)\n        {\n            LOG_CAUGHT_EXCEPTION();\n            AICLI_LOG(Core, Error, << \"Failed getting font file information.\");\n        }\n\n        return fontFiles;\n    }\n\n    std::vector<FontPackageInfo> GetInstalledFontPackages(Manifest::ScopeEnum scope)\n    {\n        auto fontPackages = std::vector<FontPackageInfo>();\n\n        try\n        {\n            auto hive = scope == Manifest::ScopeEnum::Machine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;\n            auto root = Registry::Key::OpenIfExists(hive, s_FontsPathSubkey.data(), 0UL, KEY_READ);\n\n            for (const auto& subkey : root)\n            {\n                auto subkeyName = ConvertToUTF16(subkey.Name());\n                auto subkeyKey = subkey.Open();\n                if (subkeyName == s_FontsWinGetPrefix)\n                {\n                    // Assume all sub-keys are WinGet Packages\n                    for (const auto& packageSubKey : subkeyKey)\n                    {\n                        try\n                        {\n                            // All sub-keys should be versions of the package.\n                            auto wingetPackageSubKey = packageSubKey.Open();\n                            for (const auto& versionSubKey : wingetPackageSubKey)\n                            {\n                                auto packageId = ConvertToUTF16(packageSubKey.Name());\n                                auto version = ConvertToUTF16(versionSubKey.Name());\n                                auto context = FontContext();\n                                context.Scope = scope;\n                                context.InstallerSource = InstallerSource::WinGet;\n                                context.PackageId = packageId;\n                                context.PackageVersion = version;\n\n                                auto packageVersionSubKey = versionSubKey.Open();\n                                for (const auto& versionValue : packageVersionSubKey.Values())\n                                {\n                                    auto value = versionValue.Value();\n                                    if (!value.has_value() || (value.value().GetType() != Registry::Value::Type::String))\n                                    {\n                                        continue;\n                                    }\n\n                                    std::filesystem::path filePath = { value->GetValue<Registry::Value::Type::String>() };\n                                    context.AddPackageFile(filePath);\n                                }\n\n                                auto validationResult = ValidateFontPackage(context);\n                                if (validationResult.Status != FontStatus::Absent)\n                                {\n                                    auto packageInfo = FontPackageInfo();\n                                    packageInfo.Scope = scope;\n                                    packageInfo.Status = validationResult.Status;\n                                    packageInfo.PackageId = packageId;\n                                    packageInfo.PackageVersion = version;\n                                    packageInfo.PackageIdentifier = context.GetPackageIdentifier();\n                                    fontPackages.push_back(std::move(packageInfo));\n                                }\n                            }\n                        }\n                        catch (...)\n                        {\n                            // If we have bad data in the registry for this entry, log it and skip.\n                            LOG_CAUGHT_EXCEPTION();\n                            AICLI_LOG(Core, Error, << \"Failed getting font package information for: \" << packageSubKey.Name().c_str());\n                            continue;\n                        }\n                    }\n                }\n            }\n        }\n        catch (...)\n        {\n            LOG_CAUGHT_EXCEPTION();\n            AICLI_LOG(Core, Error, << \"Failed getting font package information.\");\n        }\n\n        return fontPackages;\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCommonCore/HttpClientHelper.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include <AppInstallerDownloader.h>\r\n#include <AppInstallerRuntime.h>\r\n#include <winget/HttpClientHelper.h>\r\n#include <winget/NetworkSettings.h>\r\n#include <winhttp.h>\r\n\r\nnamespace AppInstaller::Http\r\n{\r\n    namespace\r\n    {\r\n        // If the caller does not pass in a user agent header, put the default one on the request.\r\n        void EnsureDefaultUserAgent(web::http::http_request& request)\r\n        {\r\n            static utility::string_t c_defaultUserAgent = Utility::ConvertToUTF16(AppInstaller::Runtime::GetDefaultUserAgent());\r\n\r\n            if (!request.headers().has(web::http::header_names::user_agent))\r\n            {\r\n                request.headers().add(web::http::header_names::user_agent, c_defaultUserAgent);\r\n            }\r\n        }\r\n\r\n        void NativeHandleServerCertificateValidation(web::http::client::native_handle handle, const Certificates::PinningConfiguration& pinningConfiguration, ThreadLocalStorage::ThreadGlobals* threadGlobals)\r\n        {\r\n            decltype(threadGlobals->SetForCurrentThread()) previousThreadGlobals;\r\n            if (threadGlobals)\r\n            {\r\n                previousThreadGlobals = threadGlobals->SetForCurrentThread();\r\n            }\r\n\r\n            HINTERNET requestHandle = reinterpret_cast<HINTERNET>(handle);\r\n\r\n            // Get certificate and pass along to pinning config\r\n            wil::unique_cert_context certContext;\r\n            DWORD bufferSize = sizeof(&certContext);\r\n            THROW_IF_WIN32_BOOL_FALSE(WinHttpQueryOption(requestHandle, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &certContext, &bufferSize));\r\n\r\n            THROW_HR_IF(APPINSTALLER_CLI_ERROR_PINNED_CERTIFICATE_MISMATCH, !pinningConfiguration.Validate(certContext.get()));\r\n        }\r\n\r\n        std::chrono::seconds GetRetryAfter(const web::http::http_headers& headers)\r\n        {\r\n            auto retryAfterHeader = headers.find(web::http::header_names::retry_after);\r\n            if (retryAfterHeader != headers.end())\r\n            {\r\n                return AppInstaller::Utility::GetRetryAfter(retryAfterHeader->second.c_str());\r\n            }\r\n\r\n            return 0s;\r\n        }\r\n    }\r\n\r\n    HttpClientHelper::HttpClientHelper(std::shared_ptr<web::http::http_pipeline_stage> stage)\r\n        : m_defaultRequestHandlerStage(std::move(stage))\r\n    {\r\n        const auto& proxyUri = Settings::Network().GetProxyUri();\r\n        if (proxyUri)\r\n        {\r\n            AICLI_LOG(Repo, Info, << \"Setting proxy for REST HTTP Client helper to \" << proxyUri.value());\r\n            m_clientConfig.set_proxy(web::web_proxy{ Utility::ConvertToUTF16(proxyUri.value()) });\r\n        }\r\n        else\r\n        {\r\n            AICLI_LOG(Repo, Info, << \"REST HTTP Client helper does not use proxy\");\r\n        }\r\n    }\r\n\r\n    pplx::task<web::http::http_response> HttpClientHelper::Post(\r\n        const utility::string_t& uri,\r\n        const web::json::value& body,\r\n        const HttpClientHelper::HttpRequestHeaders& headers,\r\n        const HttpClientHelper::HttpRequestHeaders& authHeaders) const\r\n    {\r\n        AICLI_LOG(Repo, Info, << \"Sending http POST request to: \" << utility::conversions::to_utf8string(uri));\r\n        web::http::client::http_client client = GetClient(uri);\r\n        web::http::http_request request{ web::http::methods::POST };\r\n        request.headers().set_content_type(web::http::details::mime_types::application_json);\r\n        request.set_body(body.serialize());\r\n\r\n        // Add headers\r\n        for (auto& pair : headers)\r\n        {\r\n            request.headers().add(pair.first, pair.second);\r\n        }\r\n        EnsureDefaultUserAgent(request);\r\n\r\n        AICLI_LOG(Repo, Verbose, << \"Http POST request details:\\n\" << utility::conversions::to_utf8string(request.to_string()));\r\n\r\n        // Add auth headers after logging\r\n        for (auto& pair : authHeaders)\r\n        {\r\n            request.headers().add(pair.first, pair.second);\r\n        }\r\n\r\n        return client.request(request);\r\n    }\r\n\r\n    std::optional<web::json::value> HttpClientHelper::HandlePost(\r\n        const utility::string_t& uri,\r\n        const web::json::value& body,\r\n        const HttpClientHelper::HttpRequestHeaders& headers,\r\n        const HttpClientHelper::HttpRequestHeaders& authHeaders,\r\n        const HttpResponseHandler& customHandler) const try\r\n    {\r\n        web::http::http_response httpResponse;\r\n        Post(uri, body, headers, authHeaders).then([&httpResponse](const web::http::http_response& response)\r\n            {\r\n                httpResponse = response;\r\n            }).wait();\r\n\r\n        if (customHandler)\r\n        {\r\n            auto handlerResult = customHandler(httpResponse);\r\n            if (!handlerResult.UseDefaultHandling)\r\n            {\r\n                return std::move(handlerResult.Result);\r\n            }\r\n        }\r\n\r\n        return ValidateAndExtractResponse(httpResponse);\r\n    }\r\n    catch (web::http::http_exception& exception)\r\n    {\r\n        RethrowAsWilException(exception);\r\n    }\r\n\r\n    pplx::task<web::http::http_response> HttpClientHelper::Get(\r\n        const utility::string_t& uri,\r\n        const HttpClientHelper::HttpRequestHeaders& headers,\r\n        const HttpClientHelper::HttpRequestHeaders& authHeaders) const\r\n    {\r\n        AICLI_LOG(Repo, Info, << \"Sending http GET request to: \" << utility::conversions::to_utf8string(uri));\r\n        web::http::client::http_client client = GetClient(uri);\r\n        web::http::http_request request{ web::http::methods::GET };\r\n        request.headers().set_content_type(web::http::details::mime_types::application_json);\r\n\r\n        // Add headers\r\n        for (auto& pair : headers)\r\n        {\r\n            request.headers().add(pair.first, pair.second);\r\n        }\r\n        EnsureDefaultUserAgent(request);\r\n\r\n        AICLI_LOG(Repo, Verbose, << \"Http GET request details:\\n\" << utility::conversions::to_utf8string(request.to_string()));\r\n\r\n        // Add auth headers after logging\r\n        for (auto& pair : authHeaders)\r\n        {\r\n            request.headers().add(pair.first, pair.second);\r\n        }\r\n\r\n        return client.request(request);\r\n    }\r\n\r\n    std::optional<web::json::value> HttpClientHelper::HandleGet(\r\n        const utility::string_t& uri,\r\n        const HttpClientHelper::HttpRequestHeaders& headers,\r\n        const HttpClientHelper::HttpRequestHeaders& authHeaders,\r\n        const HttpResponseHandler& customHandler) const try\r\n    {\r\n        web::http::http_response httpResponse;\r\n        Get(uri, headers, authHeaders).then([&httpResponse](const web::http::http_response& response)\r\n            {\r\n                httpResponse = response;\r\n            }).wait();\r\n\r\n        if (customHandler)\r\n        {\r\n            auto handlerResult = customHandler(httpResponse);\r\n            if (!handlerResult.UseDefaultHandling)\r\n            {\r\n                return std::move(handlerResult.Result);\r\n            }\r\n        }\r\n\r\n        return ValidateAndExtractResponse(httpResponse);\r\n    }\r\n    catch (web::http::http_exception& exception)\r\n    {\r\n        RethrowAsWilException(exception);\r\n    }\r\n\r\n    void HttpClientHelper::SetPinningConfiguration(const Certificates::PinningConfiguration& configuration, std::shared_ptr<ThreadLocalStorage::ThreadGlobals> threadGlobals)\r\n    {\r\n        m_clientConfig.set_nativehandle_servercertificate_validation([pinConfig = configuration, globals = std::move(threadGlobals)](web::http::client::native_handle handle)\r\n            {\r\n                NativeHandleServerCertificateValidation(handle, pinConfig, globals.get());\r\n            });\r\n    }\r\n\r\n    web::http::client::http_client HttpClientHelper::GetClient(const utility::string_t& uri) const\r\n    {\r\n        web::http::client::http_client client{ uri, m_clientConfig };\r\n\r\n        // Add default custom handlers if any.\r\n        if (m_defaultRequestHandlerStage)\r\n        {\r\n            client.add_handler(m_defaultRequestHandlerStage);\r\n        }\r\n\r\n        return client;\r\n    }\r\n\r\n    std::optional<web::json::value> HttpClientHelper::ValidateAndExtractResponse(const web::http::http_response& response) const\r\n    {\r\n        AICLI_LOG(Repo, Info, << \"Response status: \" << response.status_code());\r\n        // Ensure that we wait for the content to be ready before we log it; otherwise it will be truncated.\r\n        AICLI_LOG_LARGE_STRING(Repo, Verbose, << \"Response details:\",\r\n            response.content_ready().then([&](const web::http::http_response&) { return utility::conversions::to_utf8string(response.to_string()); }).get());\r\n\r\n        std::optional<web::json::value> result;\r\n        switch (response.status_code())\r\n        {\r\n        case web::http::status_codes::OK:\r\n            result = ExtractJsonResponse(response);\r\n            break;\r\n\r\n        case web::http::status_codes::NotFound:\r\n            THROW_HR(APPINSTALLER_CLI_ERROR_RESTAPI_ENDPOINT_NOT_FOUND);\r\n\r\n        case web::http::status_codes::NoContent:\r\n            result = {};\r\n            break;\r\n\r\n        case web::http::status_codes::BadRequest:\r\n            THROW_HR(APPINSTALLER_CLI_ERROR_RESTAPI_INTERNAL_ERROR);\r\n\r\n        case web::http::status_codes::TooManyRequests:\r\n        case web::http::status_codes::ServiceUnavailable:\r\n            THROW_EXCEPTION(AppInstaller::Utility::ServiceUnavailableException(GetRetryAfter(response.headers())));\r\n\r\n        default:\r\n            THROW_HR(MAKE_HRESULT(SEVERITY_ERROR, FACILITY_HTTP, response.status_code()));\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::optional<web::json::value> HttpClientHelper::ExtractJsonResponse(const web::http::http_response& response) const\r\n    {\r\n        utility::string_t contentType = response.headers().content_type();\r\n\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_RESTAPI_UNSUPPORTED_MIME_TYPE,\r\n            !contentType._Starts_with(web::http::details::mime_types::application_json));\r\n\r\n        return response.extract_json().get();\r\n    }\r\n\r\n    [[noreturn]] void HttpClientHelper::RethrowAsWilException(const web::http::http_exception& exception)\r\n    {\r\n        // Some http_exceptions have no error code; default to REST internal error.\r\n        HRESULT toThrow = APPINSTALLER_CLI_ERROR_RESTAPI_INTERNAL_ERROR;\r\n\r\n        // 99% of the time this code comes from GetLastError.\r\n        // In a few cases it will be 400; as in the HTTP status code.\r\n        // Since that is the one case that http_client_winhttp.cpp uses, we map it specifically.\r\n        // In the event that this makes no sense, ERROR_THREAD_MODE_ALREADY_BACKGROUND is Win32 error 400.\r\n        int errorValue = exception.error_code().value();\r\n        if (errorValue == web::http::status_codes::BadRequest)\r\n        {\r\n            toThrow = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_HTTP, web::http::status_codes::BadRequest);\r\n        }\r\n        else if (errorValue)\r\n        {\r\n            toThrow = HRESULT_FROM_WIN32(errorValue);\r\n        }\r\n\r\n        THROW_HR_MSG(toThrow, \"%hs\", exception.what());\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/HttpStream/HttpClientWrapper.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n\r\n#include \"pch.h\"\r\n#include \"Public/AppInstallerStrings.h\"\r\n#include \"HttpClientWrapper.h\"\r\n#include \"Public/AppInstallerRuntime.h\"\r\n#include \"Public/AppInstallerDownloader.h\"\r\n\r\nusing namespace winrt::Windows::Foundation;\r\nusing namespace winrt::Windows::Security::Cryptography;\r\nusing namespace winrt::Windows::Storage;\r\nusing namespace winrt::Windows::Storage::Streams;\r\nusing namespace winrt::Windows::Web::Http;\r\nusing namespace winrt::Windows::Web::Http::Headers;\r\nusing namespace winrt::Windows::Web::Http::Filters;\r\n\r\n// Note: this class is used by the HttpRandomAccessStream which is passed to the AppxPackaging COM API\r\n// All exceptions thrown across dll boundaries should be WinRT exception not custom exceptions.\r\n// The HRESULTs will be mapped to UI error code by the appropriate component\r\nnamespace AppInstaller::Utility::HttpStream\r\n{\r\n    std::future<std::shared_ptr<HttpClientWrapper>> HttpClientWrapper::CreateAsync(const Uri& uri)\r\n    {\r\n        // TODO: Use proxy info. HttpClient does not support using a custom proxy, only using the system-wide one.\r\n        std::shared_ptr<HttpClientWrapper> instance = std::make_shared<HttpClientWrapper>();\r\n\r\n        // Use an HTTP filter to disable the default caching behavior and use the Most Recent caching behavior instead\r\n        // so we don't use a stale cached resource. Note: this wrapper object is used in the custom HTTP stream implementation\r\n        // so this affects the parsing of HTTP-based packages/bundles.\r\n        HttpBaseProtocolFilter filter;\r\n        filter.CacheControl().ReadBehavior(HttpCacheReadBehavior::MostRecent);\r\n        instance->m_httpClient = HttpClient(filter);\r\n        instance->m_requestUri = uri;\r\n\r\n        instance->m_httpClient.DefaultRequestHeaders().Connection().Clear();\r\n        instance->m_httpClient.DefaultRequestHeaders().Append(L\"Connection\", L\"Keep-Alive\");\r\n        instance->m_httpClient.DefaultRequestHeaders().UserAgent().ParseAdd(Utility::ConvertToUTF16(Runtime::GetDefaultUserAgent().get()));\r\n\r\n        co_await instance->PopulateInfoAsync();\r\n\r\n        co_return instance;\r\n    }\r\n\r\n    // this function will issue a HEAD request to determine the size of the file and the redirect URI\r\n    std::future<void> HttpClientWrapper::PopulateInfoAsync()\r\n    {\r\n        HttpRequestMessage request(HttpMethod::Head(), m_requestUri);\r\n\r\n        HttpResponseMessage response = co_await m_httpClient.SendRequestAsync(request, HttpCompletionOption::ResponseHeadersRead);\r\n\r\n        switch (response.StatusCode())\r\n        {\r\n        case HttpStatusCode::Ok:\r\n            // All good\r\n            break;\r\n        case HttpStatusCode::TooManyRequests:\r\n        case HttpStatusCode::ServiceUnavailable:\r\n        {\r\n            THROW_EXCEPTION(ServiceUnavailableException(GetRetryAfter(response)));\r\n        }\r\n        default:\r\n            THROW_HR(MAKE_HRESULT(SEVERITY_ERROR, FACILITY_HTTP, response.StatusCode()));\r\n        }\r\n\r\n        // Get the length from the response\r\n        if (response.Content().Headers().HasKey(L\"Content-Length\"))\r\n        {\r\n            std::wstring contentLength(response.Content().Headers().Lookup(L\"Content-Length\"));\r\n            m_sizeInBytes = std::stoll(contentLength);\r\n        }\r\n        else\r\n        {\r\n            m_sizeInBytes = 0;\r\n        }\r\n\r\n        // Get the extension from the redirect URI\r\n        m_redirectUri = response.RequestMessage().RequestUri();\r\n\r\n        m_contentType = response.Content().Headers().HasKey(L\"Content-Type\") ?\r\n            response.Content().Headers().Lookup(L\"Content-Type\")\r\n            : L\"\";\r\n\r\n        // If the size wasn't resolved try with a GET 0-0 request\r\n        if (m_sizeInBytes == 0)\r\n        {\r\n            co_await SendHttpRequestAsync(0, 1);\r\n        }\r\n    }\r\n\r\n#ifdef WINGET_DISABLE_FOR_FUZZING\r\n#pragma warning( push )\r\n#pragma warning( disable : 4714) // HRESULT_FROM_WIN32 marked as forceinline not inlined\r\n#endif\r\n\r\n    std::future<IBuffer> HttpClientWrapper::SendHttpRequestAsync(\r\n        _In_ ULONG64 startPosition,\r\n        _In_ UINT32 requestedSizeInBytes)\r\n    {\r\n        unsigned long long endPosition = 0;\r\n\r\n        winrt::check_hresult(ULong64Add(startPosition, requestedSizeInBytes, &endPosition));\r\n\r\n        // Subtracting one should be safe, as the consumer of the stream should not request\r\n        // an empty range, so this number can't go negative.\r\n        endPosition -= 1;\r\n\r\n        std::wstring rangeHeaderValue = L\"bytes=\" + std::to_wstring(startPosition) + L\"-\" + std::to_wstring(endPosition);\r\n\r\n        HttpRequestMessage request(HttpMethod::Get(), m_requestUri);\r\n        request.Headers().Append(L\"Range\", rangeHeaderValue);\r\n\r\n        if (!Utility::IsEmptyOrWhitespace(m_etagHeader))\r\n        {\r\n            request.Headers().Append(L\"If-Match\", m_etagHeader);\r\n        }\r\n\r\n        if (!Utility::IsEmptyOrWhitespace(m_lastModifiedHeader))\r\n        {\r\n            request.Headers().Append(L\"If-Unmodified-Since\", m_lastModifiedHeader);\r\n        }\r\n\r\n        HttpResponseMessage response = co_await m_httpClient.SendRequestAsync(request, HttpCompletionOption::ResponseHeadersRead);\r\n        HttpContentHeaderCollection contentHeaders = response.Content().Headers();\r\n\r\n        switch (response.StatusCode())\r\n        {\r\n        case HttpStatusCode::Ok:\r\n        case HttpStatusCode::PartialContent:\r\n            // All good\r\n            break;\r\n        case HttpStatusCode::TooManyRequests:\r\n        case HttpStatusCode::ServiceUnavailable:\r\n        {\r\n            THROW_EXCEPTION(ServiceUnavailableException(GetRetryAfter(response)));\r\n        }\r\n        default:\r\n            THROW_HR(MAKE_HRESULT(SEVERITY_ERROR, FACILITY_HTTP, response.StatusCode()));\r\n        }\r\n\r\n        if (response.StatusCode() != HttpStatusCode::PartialContent && startPosition != 0)\r\n        {\r\n            // throw HRESULT used for range-request error\r\n            THROW_HR(HRESULT_FROM_WIN32(ERROR_NO_RANGES_PROCESSED));\r\n        }\r\n\r\n        if (response.Headers().HasKey(L\"Accept-Ranges\") &&\r\n            Utility::ToLower(std::wstring(response.Headers().Lookup(L\"Accept-Ranges\"))) == L\"none\")\r\n        {\r\n            // throw HRESULT used for range-request error\r\n            THROW_HR(HRESULT_FROM_WIN32(ERROR_NO_RANGES_PROCESSED));\r\n        }\r\n\r\n        if (Utility::IsEmptyOrWhitespace(m_etagHeader) && response.Headers().HasKey(L\"ETag\"))\r\n        {\r\n            m_etagHeader = response.Headers().Lookup(L\"ETag\");\r\n        }\r\n\r\n        if (Utility::IsEmptyOrWhitespace(m_lastModifiedHeader) && contentHeaders.HasKey(L\"Last-Modified\"))\r\n        {\r\n            m_lastModifiedHeader = contentHeaders.Lookup(L\"Last-Modified\");\r\n        }\r\n\r\n        // If we don't know the size, parse it from the Content-Range field.\r\n        if (m_sizeInBytes == 0 && contentHeaders.HasKey(L\"Content-Range\"))\r\n        {\r\n            // format: a-b/x where x is either a number or *\r\n            std::wstring contentRange(contentHeaders.Lookup(L\"Content-Range\"));\r\n            std::wstring length = contentRange.substr(contentRange.find(L\"/\") + 1);\r\n            m_sizeInBytes = (length == L\"*\") ? 0 : std::stoll(length);\r\n        }\r\n\r\n        co_return co_await response.Content().ReadAsBufferAsync();\r\n    }\r\n\r\n#ifdef WINGET_DISABLE_FOR_FUZZING\r\n#pragma warning( pop ) \r\n#endif\r\n\r\n    std::future<IBuffer> HttpClientWrapper::DownloadRangeAsync(\r\n        const ULONG64 startPosition,\r\n        const UINT32 requestedSizeInBytes,\r\n        const InputStreamOptions& options)\r\n    {\r\n        std::vector<byte> byteArray(requestedSizeInBytes);\r\n        IBuffer buffer = CryptographicBuffer::CreateFromByteArray(byteArray);\r\n\r\n        co_return co_await SendHttpRequestAsync(startPosition, requestedSizeInBytes);\r\n    }\r\n}"
  },
  {
    "path": "src/AppInstallerCommonCore/HttpStream/HttpClientWrapper.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winrt/Windows.Foundation.h>\r\n#include <winrt/Windows.Web.Http.h>\r\n\r\nnamespace AppInstaller::Utility::HttpStream\r\n{\r\n    // Wrapper around HTTP client. When created, an object of this class will send a HTTP \r\n    // head request to determine the size of the data source.\r\n    class HttpClientWrapper\r\n    {\r\n    public:\r\n        static std::future<std::shared_ptr<HttpClientWrapper>> CreateAsync(const winrt::Windows::Foundation::Uri& uri);\r\n\r\n        std::future<winrt::Windows::Storage::Streams::IBuffer> DownloadRangeAsync(\r\n            const ULONG64 startPosition,\r\n            const UINT32 requestedSizeInBytes,\r\n            const winrt::Windows::Storage::Streams::InputStreamOptions& options);\r\n\r\n        unsigned long long GetFullFileSize()\r\n        {\r\n            return m_sizeInBytes;\r\n        }\r\n\r\n        winrt::Windows::Foundation::Uri GetRedirectUri()\r\n        {\r\n            return m_redirectUri;\r\n        }\r\n\r\n        std::wstring GetContentType()\r\n        {\r\n            return m_contentType;\r\n        }\r\n\r\n    private:\r\n        winrt::Windows::Web::Http::HttpClient m_httpClient;\r\n        winrt::Windows::Foundation::Uri m_requestUri = nullptr;\r\n        winrt::Windows::Foundation::Uri m_redirectUri = nullptr;\r\n        std::wstring m_contentType;\r\n        unsigned long long m_sizeInBytes = 0;\r\n        std::wstring m_etagHeader;\r\n        std::wstring m_lastModifiedHeader;\r\n\r\n        std::future<void> PopulateInfoAsync();\r\n\r\n        std::future<winrt::Windows::Storage::Streams::IBuffer> SendHttpRequestAsync(\r\n            _In_ ULONG64 startPosition,\r\n            _In_ UINT32 requestedSizeInBytes);\r\n    };\r\n}"
  },
  {
    "path": "src/AppInstallerCommonCore/HttpStream/HttpLocalCache.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n\r\n#include \"pch.h\"\r\n#include \"HttpLocalCache.h\"\r\n\r\nusing namespace Windows::Storage::Streams;\r\nusing namespace winrt::Windows::Storage::Streams;\r\nusing namespace winrt::Windows::Security::Cryptography;\r\n\r\n// Note: this class is used by the HttpRandomAccessStream which is passed to the AppxPackaging COM API\r\n// All exceptions thrown across dll boundaries should be WinRT exception not custom exceptions.\r\n// The HRESULTs will be mapped to UI error code by the appropriate component\r\nnamespace AppInstaller::Utility::HttpStream\r\n{\r\n    std::future<IBuffer> HttpLocalCache::ReadFromCacheAndDownloadIfNecessaryAsync(\r\n        const ULONG64 requestedPosition,\r\n        const UINT32 requestedSize,\r\n        HttpClientWrapper* httpClientWrapper,\r\n        InputStreamOptions httpInputStreamOptions)\r\n    {\r\n        // Increment cache access counter user for implementing LRU replacement\r\n        m_accessCounter++;\r\n\r\n        // Find all the pages for the given request, and the pages that are missing\r\n        std::vector<ULONG64> allPages;\r\n        std::vector<ULONG64> unsatisfiablePages;\r\n        FindCachePages(requestedPosition, requestedSize, allPages, unsatisfiablePages);\r\n\r\n        // download the missing pages\r\n        co_await DownloadAndSaveToCacheAsync(\r\n            unsatisfiablePages,\r\n            httpClientWrapper,\r\n            httpInputStreamOptions);\r\n\r\n        // At this point, everything should be in the cache\r\n        IBuffer constructedBuffer = {};\r\n\r\n        for (UINT32 i = 0; i < allPages.size(); i++)\r\n        {\r\n            UINT64 pageOffset = allPages[i];\r\n            IBuffer cachedPageBuffer = ReadPageFromCache(pageOffset);\r\n            constructedBuffer = ConcatenateBuffers(constructedBuffer, cachedPageBuffer);\r\n        }\r\n\r\n        // trim buffer to match requested range\r\n        IBuffer requestedBuffer = TrimBufferToSatisfyRequest(\r\n            constructedBuffer,\r\n            requestedPosition,\r\n            requestedSize,\r\n            allPages);\r\n\r\n        VacateStaleEntriesFromCache();\r\n\r\n        co_return requestedBuffer;\r\n    }\r\n\r\n    void HttpLocalCache::FindCachePages(\r\n        ULONG64 requestedPosition,\r\n        UINT32 requestedSize,\r\n        std::vector<ULONG64>& allPages,\r\n        std::vector<ULONG64>& unsatisfiablePages)\r\n    {\r\n        ULONG64 requestedEndPosition;\r\n        ULONG64 currentPageOffset;\r\n        winrt::check_hresult(ULong64Add(requestedPosition, requestedSize, &requestedEndPosition));\r\n        winrt::check_hresult(ULong64Mult((requestedPosition / PAGE_SIZE), PAGE_SIZE, &currentPageOffset));\r\n\r\n        // There's always at least one page for the range\r\n        do\r\n        {\r\n            allPages.push_back(currentPageOffset);\r\n\r\n            if (m_localCache.find(currentPageOffset) == m_localCache.end())\r\n            {\r\n                unsatisfiablePages.push_back(currentPageOffset);\r\n            }\r\n\r\n            winrt::check_hresult(ULong64Add(currentPageOffset, PAGE_SIZE, &currentPageOffset));\r\n\r\n        } while (currentPageOffset < requestedEndPosition);\r\n    }\r\n\r\n    // Breaks the provided buffer into smaller buffers and saves them to the cache at the corresponding \r\n    // page offset position, starting at firstPageOffset. The smaller buffers are all PAGE_SIZE bytes,\r\n    // except for the one corresponding to the last page in the file\r\n    void HttpLocalCache::SaveBufferToCache(const IBuffer& buffer, const ULONG64 firstPageOffset)\r\n    {\r\n        UINT32 remainingBufferSize = buffer.Length();\r\n        UINT32 currentBufferIndex = 0;\r\n        ULONG64 currentPageOffset = firstPageOffset;\r\n\r\n        while (remainingBufferSize > 0)\r\n        {\r\n            // Extract the sub-buffer\r\n            UINT32 currentPageSize = std::min(remainingBufferSize, PAGE_SIZE);\r\n            IBuffer currentPageBuffer = CreateTrimmedBuffer(buffer, currentBufferIndex, currentPageSize);\r\n\r\n            // Add it to the cache\r\n            CachedPage currentPage;\r\n            currentPage.lastAccessCounter = m_accessCounter;\r\n            currentPage.buffer = currentPageBuffer;\r\n            m_localCache[currentPageOffset] = currentPage;\r\n\r\n            // update loop vars\r\n            winrt::check_hresult(UInt32Sub(remainingBufferSize, currentPageSize, &remainingBufferSize));\r\n            winrt::check_hresult(UInt32Add(currentBufferIndex, currentPageSize, &currentBufferIndex));\r\n            winrt::check_hresult(ULong64Add(currentPageOffset, PAGE_SIZE, &currentPageOffset));\r\n        }\r\n    }\r\n\r\n    IBuffer HttpLocalCache::ReadPageFromCache(const ULONG64 pageOffset)\r\n    {\r\n        if (!(m_localCache.find(pageOffset) != m_localCache.end()))\r\n        {\r\n            THROW_HR(E_INVALIDARG);\r\n        }\r\n\r\n        CachedPage& page = m_localCache[pageOffset];\r\n        page.lastAccessCounter = m_accessCounter;\r\n\r\n        return page.buffer;\r\n    }\r\n\r\n    // Trims a buffer that was constructed (by fetching pages from cache and downloading missing pages)\r\n    // in order to satisfy a request and return the exact buffer the consumer asked for.\r\n    IBuffer HttpLocalCache::TrimBufferToSatisfyRequest(\r\n        const IBuffer& constructedBuffer,\r\n        const ULONG64 requestedPosition,\r\n        const UINT32 requestedSize,\r\n        const std::vector<ULONG64> allPages)\r\n    {\r\n        ULONG64 fullBufferStartOffset = allPages[0];\r\n\r\n        ULONG64 trimmedBufferStartRelativeIndex;\r\n        winrt::check_hresult(ULong64Sub(requestedPosition, fullBufferStartOffset, &trimmedBufferStartRelativeIndex));\r\n\r\n        IBuffer requestedBuffer = CreateTrimmedBuffer(\r\n            constructedBuffer,\r\n            (UINT32)trimmedBufferStartRelativeIndex, // Conversion is safe as buffer size is a UINT32.\r\n            requestedSize);\r\n\r\n        return requestedBuffer;\r\n    }\r\n\r\n    // Downloads a chunk of the file, saves it to the cache, and returns the corresponding buffer\r\n    // If the requested size is 0, this method returns an empty buffer without making HTTP calls\r\n    std::future<void> HttpLocalCache::DownloadAndSaveToCacheAsync(\r\n        const std::vector<ULONG64> unsatisfiablePages,\r\n        HttpClientWrapper* httpClientWrapper,\r\n        InputStreamOptions httpInputStreamOptions)\r\n    {\r\n        // Determine the download job\r\n        // To make things easy, we will download the contiguous range that includes all the unsatisfiable ranges.\r\n        // Note that in theory, this may include cached pages. However, this situation is rarely expected to happen,\r\n        // if at all. The package reader usually reads things in chunks of 64 KB or less, so, we should expect to \r\n        // always have up to two satisfiable and unsatisfiable pages in total.\r\n        UINT64 fileSize = httpClientWrapper->GetFullFileSize();\r\n        ULONG64 downloadJobStartPosition = 0U;\r\n        ULONG64 downloadJobEndPosition = 0U;\r\n        ULONG64 downloadJobSize = 0U;\r\n        if (unsatisfiablePages.size() > 0U)\r\n        {\r\n            downloadJobStartPosition = unsatisfiablePages[0];\r\n            ULONG64 lastUnsatisfiableJob = unsatisfiablePages[unsatisfiablePages.size() - 1];\r\n            winrt::check_hresult(ULong64Add(lastUnsatisfiableJob, PAGE_SIZE, &downloadJobEndPosition));\r\n\r\n            // make sure to not overflow file size\r\n            downloadJobEndPosition = std::min(downloadJobEndPosition, fileSize);\r\n            winrt::check_hresult(ULong64Sub(downloadJobEndPosition, downloadJobStartPosition, &downloadJobSize));\r\n        }\r\n\r\n        if (downloadJobSize != 0U)\r\n        {\r\n            // start download job\r\n            IBuffer downloadedBuffer = co_await httpClientWrapper->DownloadRangeAsync(\r\n                downloadJobStartPosition,\r\n                (UINT32)downloadJobSize,\r\n                httpInputStreamOptions);\r\n\r\n            SaveBufferToCache(downloadedBuffer, downloadJobStartPosition);\r\n        }\r\n    }\r\n\r\n    void HttpLocalCache::VacateStaleEntriesFromCache()\r\n    {\r\n        // Copy page offsets into vector and sort by the access counter\r\n        std::vector<std::pair<UINT64, int>> orderedPageOffsets;\r\n        for (auto pageIter = m_localCache.begin(); pageIter != m_localCache.end(); pageIter++)\r\n        {\r\n            orderedPageOffsets.push_back(std::pair<UINT64, int>(pageIter->first, pageIter->second.lastAccessCounter));\r\n        }\r\n\r\n        // Compare function to sort by access counter\r\n        auto cmp = [](std::pair<UINT64, int> const & a, std::pair<UINT64, int> const & b)\r\n        {\r\n            return a.second != b.second ? a.second < b.second : a.first < b.first;\r\n        };\r\n\r\n        std::sort(orderedPageOffsets.begin(), orderedPageOffsets.end(), cmp);\r\n\r\n        for (auto pageIter = orderedPageOffsets.begin(); pageIter != orderedPageOffsets.end(); pageIter++)\r\n        {\r\n            if (m_localCache.size() > MAX_PAGES)\r\n            {\r\n                m_localCache.erase(pageIter->first);\r\n            }\r\n            else\r\n            {\r\n                break;\r\n            }\r\n        }\r\n    }\r\n\r\n    IBuffer HttpLocalCache::CreateTrimmedBuffer(\r\n        const IBuffer& originalBuffer,\r\n        UINT32 trimStartIndex,\r\n        UINT32 size)\r\n    {\r\n        uint32_t bufferLength = originalBuffer.Length();\r\n        THROW_HR_IF(E_INVALIDARG, trimStartIndex > bufferLength);\r\n\r\n        originalBuffer.as<::IInspectable>();\r\n\r\n        // Get the byte array from the IBuffer object\r\n        Microsoft::WRL::ComPtr<IBufferByteAccess> bufferByteAccess;\r\n        ::IInspectable* bufferAbi = (::IInspectable*)winrt::get_abi(originalBuffer);\r\n        bufferAbi->QueryInterface(IID_PPV_ARGS(&bufferByteAccess));\r\n        byte* byteBuffer = nullptr;\r\n        bufferByteAccess->Buffer(&byteBuffer);\r\n\r\n        // Create the array of bytes holding the trimmed bytes\r\n        IBuffer trimmedBuffer = CryptographicBuffer::CreateFromByteArray(\r\n            { byteBuffer + trimStartIndex, std::min(size, bufferLength - trimStartIndex) });\r\n\r\n        return trimmedBuffer;\r\n    }\r\n\r\n    IBuffer HttpLocalCache::ConcatenateBuffers(const IBuffer& buffer1, const IBuffer& buffer2)\r\n    {\r\n        DataWriter writer;\r\n        writer.WriteBuffer(buffer1);\r\n        writer.WriteBuffer(buffer2);\r\n        return writer.DetachBuffer();\r\n    }\r\n}"
  },
  {
    "path": "src/AppInstallerCommonCore/HttpStream/HttpLocalCache.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n\r\n#pragma once\r\n\r\n#include \"HttpClientWrapper.h\"\r\n\r\nnamespace AppInstaller::Utility::HttpStream\r\n{\r\n    // Represents an entry in the cache.\r\n    struct CachedPage\r\n    {\r\n        int lastAccessCounter = 0;\r\n        winrt::Windows::Storage::Streams::IBuffer buffer;\r\n    };\r\n\r\n    // A cache used internally by the custom HttpRandomAccessStream to reduce round-trips\r\n    class HttpLocalCache\r\n    {\r\n    public:\r\n        static constexpr UINT32 PAGE_SIZE = 2 << 16;   // each entry in the cache is 64 KB\r\n        static constexpr UINT32 MAX_PAGES = 200;       // cache size capped at 12.5 MB (200 * 64KB)\r\n\r\n        // Returns a buffer matching the requested range by reading the parts of the range that are cached\r\n        // and downloading the rest using the provided httpClientWrapper object\r\n        std::future<winrt::Windows::Storage::Streams::IBuffer> ReadFromCacheAndDownloadIfNecessaryAsync(\r\n            const ULONG64 requestedPosition,\r\n            const UINT32 requestedSize,\r\n            HttpClientWrapper* httpClientWrapper,\r\n            winrt::Windows::Storage::Streams::InputStreamOptions httpInputStreamOptions);\r\n\r\n    private:\r\n        std::map<ULONG64, CachedPage> m_localCache;\r\n        UINT32 m_accessCounter = 0U;\r\n\r\n        // Returns a vector of all pages corresponding to a range, and another (subset)\r\n        // vector of the pages missing from the cache.\r\n        void FindCachePages(\r\n            const ULONG64 requestedPosition,\r\n            const UINT32 requestedSize,\r\n            std::vector<ULONG64>& allPages,\r\n            std::vector<ULONG64>& unsatisfiablePages);\r\n\r\n        void SaveBufferToCache(const winrt::Windows::Storage::Streams::IBuffer& buffer, const ULONG64 firstPageOffset);\r\n\r\n        winrt::Windows::Storage::Streams::IBuffer ReadPageFromCache(const ULONG64 pageOffset);\r\n\r\n        void VacateStaleEntriesFromCache();\r\n\r\n        std::future<void> DownloadAndSaveToCacheAsync(\r\n            const std::vector<ULONG64> unsatisfiablePages,\r\n            HttpClientWrapper* httpClientWrapper,\r\n            const winrt::Windows::Storage::Streams::InputStreamOptions httpInputStreamOptions);\r\n\r\n        winrt::Windows::Storage::Streams::IBuffer TrimBufferToSatisfyRequest(\r\n            const winrt::Windows::Storage::Streams::IBuffer& constructedBuffer,\r\n            const ULONG64 requestedPosition,\r\n            const UINT32 requestedSize,\r\n            const std::vector<ULONG64> allPages);\r\n\r\n        winrt::Windows::Storage::Streams::IBuffer CreateTrimmedBuffer(\r\n            const winrt::Windows::Storage::Streams::IBuffer& originalBuffer,\r\n            UINT32 trimStartIndex,\r\n            UINT32 size);\r\n\r\n        winrt::Windows::Storage::Streams::IBuffer ConcatenateBuffers(\r\n            const winrt::Windows::Storage::Streams::IBuffer& buffer1,\r\n            const winrt::Windows::Storage::Streams::IBuffer& buffer2);\r\n    };\r\n}"
  },
  {
    "path": "src/AppInstallerCommonCore/HttpStream/HttpRandomAccessStream.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n\r\n#include \"pch.h\"\r\n#include \"HttpRandomAccessStream.h\"\r\n#include \"Public/AppInstallerDownloader.h\"\r\n\r\nusing namespace winrt::Windows::Foundation;\r\nusing namespace winrt::Windows::Storage::Streams;\r\n\r\n// Note: the HttpRandomAccessStream is passed to the AppxPackaging COM API\r\n// All exceptions thrown across dll boundaries should be WinRT exception not custom exceptions.\r\n// The HRESULTs will be mapped to UI error code by the appropriate component\r\nnamespace AppInstaller::Utility::HttpStream\r\n{\r\n    IAsyncOperation<IRandomAccessStream> HttpRandomAccessStream::InitializeAsync(const Uri& uri)\r\n    {\r\n        auto strong_this{ get_strong() };\r\n\r\n        try\r\n        {\r\n            strong_this->m_httpHelper = co_await HttpClientWrapper::CreateAsync(uri);\r\n            strong_this->m_size = strong_this->m_httpHelper->GetFullFileSize();\r\n            strong_this->m_httpLocalCache = std::make_unique<HttpLocalCache>();\r\n        }\r\n        catch (const ServiceUnavailableException& e)\r\n        {\r\n            strong_this->m_retryAfter = e.RetryAfter();\r\n            throw;\r\n        }\r\n\r\n        co_return strong_this.as<IRandomAccessStream>();\r\n    }\r\n\r\n    uint64_t HttpRandomAccessStream::Size() const\r\n    {\r\n        return m_size;\r\n    }\r\n\r\n    void HttpRandomAccessStream::Size(uint64_t value)\r\n    {\r\n        UNREFERENCED_PARAMETER(value);\r\n        THROW_HR(E_NOTIMPL);\r\n    }\r\n\r\n    uint64_t HttpRandomAccessStream::Position() const\r\n    {\r\n        return m_requestedPosition;\r\n    }\r\n\r\n    bool HttpRandomAccessStream::CanRead() const\r\n    {\r\n        return true;\r\n    }\r\n\r\n    bool HttpRandomAccessStream::CanWrite() const\r\n    {\r\n        return false;\r\n    }\r\n\r\n    IInputStream HttpRandomAccessStream::GetInputStreamAt(uint64_t position) const\r\n    {\r\n        UNREFERENCED_PARAMETER(position);\r\n        THROW_HR(E_NOTIMPL);\r\n    }\r\n\r\n    IOutputStream HttpRandomAccessStream::GetOutputStreamAt(uint64_t position) const\r\n    {\r\n        UNREFERENCED_PARAMETER(position);\r\n        THROW_HR(E_NOTIMPL);\r\n    }\r\n\r\n    IRandomAccessStream HttpRandomAccessStream::CloneStream() const\r\n    {\r\n        THROW_HR(E_NOTIMPL);\r\n    }\r\n\r\n    void HttpRandomAccessStream::Seek(uint64_t position)\r\n    {\r\n        m_requestedPosition = position;\r\n    }\r\n\r\n    IAsyncOperationWithProgress<IBuffer, uint32_t> HttpRandomAccessStream::ReadAsync(\r\n        IBuffer buffer,\r\n        uint32_t count,\r\n        InputStreamOptions options)\r\n    {\r\n        IBuffer result = co_await m_httpLocalCache->ReadFromCacheAndDownloadIfNecessaryAsync(\r\n            m_requestedPosition,\r\n            count,\r\n            m_httpHelper.get(),\r\n            options);\r\n        winrt::check_hresult(ULong64Add(m_requestedPosition, result.Length(), &m_requestedPosition));\r\n\r\n        co_return result;\r\n    }\r\n\r\n    std::chrono::seconds HttpRandomAccessStream::RetryAfter() const\r\n    {\r\n        return m_retryAfter;\r\n    }\r\n}"
  },
  {
    "path": "src/AppInstallerCommonCore/HttpStream/HttpRandomAccessStream.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n\r\n#pragma once\r\n#include \"HttpClientWrapper.h\"\r\n#include \"HttpLocalCache.h\"\r\n\r\nusing namespace std::chrono_literals;\r\n\r\nnamespace AppInstaller::Utility::HttpStream\r\n{\r\n    // Provides an implementation of a random access stream over HTTP that supports\r\n    // range-based fetching. This is intended to be used by AppxPackageReader.\r\n    //\r\n    // Note: If the server doesn't support HTTP ranges, this implementation will throw an exception.\r\n    class HttpRandomAccessStream : public winrt::implements<\r\n        HttpRandomAccessStream,\r\n        winrt::Windows::Storage::Streams::IRandomAccessStream,\r\n        winrt::Windows::Storage::Streams::IInputStream>\r\n    {\r\n    public:\r\n        winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::Streams::IRandomAccessStream> InitializeAsync(const winrt::Windows::Foundation::Uri& uri);\r\n        uint64_t Size() const;\r\n        void Size(uint64_t value);\r\n        uint64_t Position() const;\r\n        bool CanRead() const;\r\n        bool CanWrite() const;\r\n        winrt::Windows::Storage::Streams::IInputStream GetInputStreamAt(uint64_t position) const;\r\n        winrt::Windows::Storage::Streams::IOutputStream GetOutputStreamAt(uint64_t position) const;\r\n        winrt::Windows::Storage::Streams::IRandomAccessStream CloneStream() const;\r\n        void Seek(uint64_t position);\r\n        winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Windows::Storage::Streams::IBuffer, uint32_t> ReadAsync(\r\n            winrt::Windows::Storage::Streams::IBuffer buffer,\r\n            uint32_t count,\r\n            winrt::Windows::Storage::Streams::InputStreamOptions options);\r\n        std::chrono::seconds RetryAfter() const;\r\n\r\n    private:\r\n        std::shared_ptr<HttpClientWrapper> m_httpHelper;\r\n        std::unique_ptr<HttpLocalCache> m_httpLocalCache;\r\n        unsigned long long m_size = 0;\r\n        unsigned long long m_requestedPosition = 0;\r\n        std::chrono::seconds m_retryAfter = 0s;\r\n    };\r\n}"
  },
  {
    "path": "src/AppInstallerCommonCore/Locale.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"winget/Locale.h\"\r\n#include \"AppInstallerStrings.h\"\r\n#include \"AppInstallerLogging.h\"\r\n\r\nnamespace AppInstaller::Locale\r\n{\r\n    namespace\r\n    {\r\n        constexpr int MAX_LOCALE_SNAME_LEN = 85;\r\n\r\n        // We will just leak this. The module is shared as both functions will always be together.\r\n        HMODULE g_bcp47 = (HMODULE)(-1);\r\n        typedef bool(WINAPI* IsWellFormedTagFunc)(PCWSTR);\r\n        typedef HRESULT(WINAPI* GetDistanceOfClosestLanguageInListFunc)(PCWSTR, PCWSTR, wchar_t, double*);\r\n\r\n        HMODULE LoadBcp47ModuleFrom(_In_ PCWSTR moduleName)\r\n        {\r\n            HMODULE module = LoadLibraryExW(moduleName, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);\r\n            if (module != nullptr)\r\n            {\r\n                // All BCP47 APIs we are interested are always exported from the same dll together. So we just pick anyone for probe.\r\n                IsWellFormedTagFunc func = (IsWellFormedTagFunc)(GetProcAddress(module, \"IsWellFormedTag\"));\r\n                if (func != nullptr)\r\n                {\r\n                    return module;\r\n                }\r\n                FreeLibrary(module);\r\n            }\r\n\r\n            return nullptr;\r\n        }\r\n\r\n        HMODULE LoadBcp47Module()\r\n        {\r\n            HMODULE module = LoadBcp47ModuleFrom(L\"bcp47mrm.dll\");\r\n            if (module == nullptr)\r\n            {\r\n                // In downlevel OS, the API is exposed by bcp47langs.dll.\r\n                module = LoadBcp47ModuleFrom(L\"bcp47langs.dll\");\r\n            }\r\n\r\n            return module;\r\n        }\r\n\r\n        void InitializeBcp47Module()\r\n        {\r\n            HMODULE comparand = (HMODULE)(-1);\r\n            if (InterlockedCompareExchangePointer(reinterpret_cast<PVOID*>(&g_bcp47), comparand, comparand) == comparand)\r\n            {\r\n                HMODULE module = LoadBcp47Module();\r\n                InterlockedExchangePointer(reinterpret_cast<PVOID*>(&g_bcp47), module);\r\n            }\r\n        }\r\n    }\r\n\r\n    bool IsWellFormedBcp47Tag(std::string_view bcp47Tag)\r\n    {\r\n        // Before new SDK is released, we need to use LoadLibrary/GetProcAddress\r\n        InitializeBcp47Module();\r\n\r\n        if (g_bcp47 == nullptr)\r\n        {\r\n            // Didn't find an implementation. Just return true.\r\n            AICLI_LOG(Core, Warning, << \"bcp47 module not found.\");\r\n            return true;\r\n        }\r\n\r\n        IsWellFormedTagFunc func = (IsWellFormedTagFunc)(GetProcAddress(g_bcp47, \"IsWellFormedTag\"));\r\n        if (func != nullptr)\r\n        {\r\n            auto wBcp47Tag = Utility::ConvertToUTF16(bcp47Tag);\r\n            return func(wBcp47Tag.c_str());\r\n        }\r\n\r\n        // Should not reach here.\r\n        return TRUE;\r\n    }\r\n\r\n    double GetDistanceOfLanguage(std::string_view target, std::string_view available)\r\n    {\r\n        // Before new SDK is released, we need to use LoadLibrary/GetProcAddress\r\n        InitializeBcp47Module();\r\n\r\n        if (g_bcp47 == nullptr)\r\n        {\r\n            // Didn't find an implementation. Just return 0 as no match.\r\n            AICLI_LOG(Core, Warning, << \"bcp47 module not found.\");\r\n            return 0;\r\n        }\r\n\r\n        GetDistanceOfClosestLanguageInListFunc func =\r\n            (GetDistanceOfClosestLanguageInListFunc)(GetProcAddress(g_bcp47, \"GetDistanceOfClosestLanguageInList\"));\r\n        if (func != nullptr)\r\n        {\r\n            double distance = 0;\r\n            auto wTarget = Utility::ConvertToUTF16(target);\r\n            auto wAvailable = Utility::ConvertToUTF16(available);\r\n\r\n            // Do not check HRESULT because the method returns ERROR_NO_MATCH on no match, which is a valid case.\r\n            (void)func(wTarget.c_str(), wAvailable.c_str(), L';' /* Not used, we compare one at a time */, &distance);\r\n            return distance;\r\n        }\r\n\r\n        // Should not reach here.\r\n        return 0;\r\n    }\r\n\r\n    std::vector<std::string> GetUserPreferredLanguages()\r\n    {\r\n        std::vector<std::string> result;\r\n\r\n        for (const auto& lang : winrt::Windows::System::UserProfile::GlobalizationPreferences::Languages())\r\n        {\r\n            result.emplace_back(Utility::ConvertToUTF8(lang));\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<std::wstring> GetUserPreferredLanguagesUTF16()\r\n    {\r\n        std::vector<std::wstring> result;\r\n\r\n        for (const auto& lang : winrt::Windows::System::UserProfile::GlobalizationPreferences::Languages())\r\n        {\r\n            result.emplace_back(std::wstring(lang));\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::string LocaleIdToBcp47Tag(LCID localeId)\r\n    {\r\n        WCHAR localeName[MAX_LOCALE_SNAME_LEN] = {0};\r\n        int ret = LCIDToLocaleName(\r\n            localeId,\r\n            localeName,\r\n            MAX_LOCALE_SNAME_LEN,\r\n            LOCALE_ALLOW_NEUTRAL_NAMES);\r\n\r\n        if (ret <= 0)\r\n        {\r\n            return {};\r\n        }\r\n\r\n        return Utility::ConvertToUTF8(std::wstring(localeName));\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/MSStore.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include <winget/MSStore.h>\r\n#include <winget/ManifestCommon.h>\r\n#include <winget/Runtime.h>\r\n#include <AppInstallerFileLogger.h>\r\n#include <AppInstallerErrors.h>\r\n#include <winrt/Windows.ApplicationModel.h>\r\n\r\nnamespace AppInstaller::MSStore\r\n{\r\n    using namespace std::string_view_literals;\r\n    using namespace winrt::Windows::Foundation;\r\n    using namespace winrt::Windows::Foundation::Collections;\r\n    using namespace winrt::Windows::ApplicationModel::Store::Preview::InstallControl;\r\n\r\n    namespace\r\n    {\r\n        // The type of entitlement we were able to acquire/ensure.\r\n        enum class EntitlementType\r\n        {\r\n            None,\r\n            User,\r\n            Device,\r\n        };\r\n\r\n        EntitlementType EnsureFreeEntitlement(const std::wstring& productId, Manifest::ScopeEnum scope)\r\n        {\r\n            AppInstallManager installManager;\r\n\r\n            AICLI_LOG(Core, Info, << \"Getting entitlement for ProductId: \" << Utility::ConvertToUTF8(productId));\r\n\r\n            // Verifying/Acquiring product ownership\r\n            GetEntitlementResult entitlementResult{ nullptr };\r\n            EntitlementType result = EntitlementType::None;\r\n\r\n            if (scope == Manifest::ScopeEnum::Machine)\r\n            {\r\n                AICLI_LOG(Core, Info, << \"Get device entitlement (machine scope install).\");\r\n                result = EntitlementType::Device;\r\n                try\r\n                {\r\n                    entitlementResult = installManager.GetFreeDeviceEntitlementAsync(productId, winrt::hstring(), winrt::hstring()).get();\r\n                }\r\n                CATCH_LOG();\r\n            }\r\n            else\r\n            {\r\n                AICLI_LOG(Core, Info, << \"Get user entitlement.\");\r\n                result = EntitlementType::User;\r\n                try\r\n                {\r\n                    entitlementResult = installManager.GetFreeUserEntitlementAsync(productId, winrt::hstring(), winrt::hstring()).get();\r\n                }\r\n                CATCH_LOG();\r\n\r\n                if (!entitlementResult || entitlementResult.Status() == GetEntitlementStatus::NoStoreAccount)\r\n                {\r\n                    AICLI_LOG(Core, Info, << \"Get device entitlement (no store account).\");\r\n                    result = EntitlementType::Device;\r\n                    try\r\n                    {\r\n                        entitlementResult = installManager.GetFreeDeviceEntitlementAsync(productId, winrt::hstring(), winrt::hstring()).get();\r\n                    }\r\n                    CATCH_LOG();\r\n                }\r\n            }\r\n\r\n            if (entitlementResult && entitlementResult.Status() == GetEntitlementStatus::Succeeded)\r\n            {\r\n                AICLI_LOG(Core, Info, << \"Get entitlement succeeded.\");\r\n            }\r\n            else if (entitlementResult)\r\n            {\r\n                result = EntitlementType::None;\r\n\r\n                if (entitlementResult.Status() == GetEntitlementStatus::NetworkError)\r\n                {\r\n                    AICLI_LOG(Core, Error, << \"Get entitlement failed. Network error.\");\r\n                }\r\n                else if (entitlementResult.Status() == GetEntitlementStatus::ServerError)\r\n                {\r\n                    AICLI_LOG(Core, Error, << \"Get entitlement failed. Server error.\");\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(Core, Error, << \"Get entitlement failed. Unknown status: \" << static_cast<int32_t>(entitlementResult.Status()));\r\n                }\r\n            }\r\n            else\r\n            {\r\n                result = EntitlementType::None;\r\n                AICLI_LOG(Core, Error, << \"Get entitlement failed. Exception.\");\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        enum class CheckExistingItemResult\r\n        {\r\n            None,\r\n            Restart,\r\n            Cancel,\r\n        };\r\n\r\n        CheckExistingItemResult CheckRestartOrCancelForPossibleExistingOperation(const IVectorView<AppInstallItem>& installItems)\r\n        {\r\n            CheckExistingItemResult result = CheckExistingItemResult::None;\r\n\r\n            for (auto const& installItem : installItems)\r\n            {\r\n                const auto& status = installItem.GetCurrentStatus();\r\n                switch (status.InstallState())\r\n                {\r\n                case AppInstallState::Canceled:\r\n                case AppInstallState::Error:\r\n                    // For these states, always do a cancel;\r\n                    result = CheckExistingItemResult::Cancel;\r\n                    return result;\r\n                case AppInstallState::Paused:\r\n                case AppInstallState::PausedLowBattery:\r\n                case AppInstallState::PausedWiFiRecommended:\r\n                case AppInstallState::PausedWiFiRequired:\r\n                case AppInstallState::ReadyToDownload:\r\n                    // For these states, set result to restart and continue the loop to see if future items need cancel.\r\n                    result = CheckExistingItemResult::Restart;\r\n                    break;\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        bool DoesInstallItemsContainProduct(const IVectorView<AppInstallItem>& installItems, std::wstring_view productId)\r\n        {\r\n            for (auto const& installItem : installItems)\r\n            {\r\n                if (Utility::CaseInsensitiveEquals(installItem.ProductId(), productId))\r\n                {\r\n                    return true;\r\n                }\r\n            }\r\n\r\n            return false;\r\n        }\r\n\r\n        // Returns true if Restart or Cancel happened. False otherwise.\r\n        HRESULT RestartOrCancelExistingOperationIfNecessary(const IVectorView<AppInstallItem>& installItems, AppInstallManager& installManager, std::wstring_view productId)\r\n        {\r\n            auto existingItemResult = CheckRestartOrCancelForPossibleExistingOperation(installItems);\r\n\r\n            if (existingItemResult == CheckExistingItemResult::Cancel || existingItemResult == CheckExistingItemResult::Restart)\r\n            {\r\n                if (existingItemResult == CheckExistingItemResult::Cancel)\r\n                {\r\n                    installManager.Cancel(productId);\r\n\r\n                    // Wait for at most 10 seconds for install item to be removed from queue.\r\n                    for (int i = 0; i < 50; ++i)\r\n                    {\r\n                        Sleep(200);\r\n                        if (!DoesInstallItemsContainProduct(installManager.AppInstallItems(), productId))\r\n                        {\r\n                            return S_OK;\r\n                        }\r\n                    }\r\n\r\n                    RETURN_HR(HRESULT_FROM_WIN32(ERROR_TIMEOUT));\r\n                }\r\n                else\r\n                {\r\n                    installManager.Restart(productId);\r\n                    return S_OK;\r\n                }\r\n            }\r\n\r\n            return S_FALSE;\r\n        }\r\n\r\n        // Used to detect a signal that a package update is being requested so that we can early out\r\n        // on an attempt to update ourself. This is only needed for elevated processes because the\r\n        // standard shutdown signals are not sent to elevated processes in the same manner.\r\n        struct PackageUpdateMonitor\r\n        {\r\n            PackageUpdateMonitor()\r\n            {\r\n                if (Runtime::IsRunningAsAdmin() && Runtime::IsRunningInPackagedContext())\r\n                {\r\n                    m_catalog = winrt::Windows::ApplicationModel::PackageCatalog::OpenForCurrentPackage();\r\n                    m_updatingEvent = m_catalog.PackageUpdating(\r\n                        winrt::auto_revoke, [this](winrt::Windows::ApplicationModel::PackageCatalog, winrt::Windows::ApplicationModel::PackageUpdatingEventArgs args)\r\n                        {\r\n                            // Deployment always sends a value of 0 before doing any work and a value of 100 when completely done.\r\n                            constexpr double minProgress = 0;\r\n                            auto progress = args.Progress();\r\n                            if (progress > minProgress)\r\n                            {\r\n                                m_isUpdating = true;\r\n                            }\r\n                        });\r\n                }\r\n            }\r\n\r\n            bool IsUpdating() const\r\n            {\r\n                return m_isUpdating;\r\n            }\r\n\r\n        private:\r\n            winrt::Windows::ApplicationModel::PackageCatalog m_catalog = nullptr;\r\n            decltype(winrt::Windows::ApplicationModel::PackageCatalog{ nullptr }.PackageUpdating(winrt::auto_revoke, nullptr)) m_updatingEvent;\r\n            std::atomic_bool m_isUpdating = false;\r\n        };\r\n\r\n        HRESULT WaitForOperation(const std::wstring& productId, bool isSilentMode, IVectorView<AppInstallItem>& installItems, IProgressCallback& progress, const PackageUpdateMonitor& monitor)\r\n        {\r\n            auto cancelIfOperationFailed = wil::scope_exit(\r\n                [&]()\r\n                {\r\n                    try\r\n                    {\r\n                        AppInstallManager installManager;\r\n                        installManager.Cancel(productId);\r\n                    }\r\n                    CATCH_LOG();\r\n                });\r\n\r\n            for (auto const& installItem : installItems)\r\n            {\r\n                AICLI_LOG(Core, Info, <<\r\n                    \"Started MSStore package execution. ProductId: \" << Utility::ConvertToUTF8(installItem.ProductId()) <<\r\n                    \" PackageFamilyName: \" << Utility::ConvertToUTF8(installItem.PackageFamilyName()));\r\n\r\n                if (isSilentMode)\r\n                {\r\n                    installItem.InstallInProgressToastNotificationMode(AppInstallationToastNotificationMode::NoToast);\r\n                    installItem.CompletedInstallToastNotificationMode(AppInstallationToastNotificationMode::NoToast);\r\n                }\r\n            }\r\n\r\n            HRESULT errorCode = S_OK;\r\n\r\n            // We are aggregating all AppInstallItem progresses into one.\r\n            // Averaging every progress for now until we have a better way to find overall progress.\r\n            uint64_t overallProgressMax = 100 * static_cast<uint64_t>(installItems.Size());\r\n            uint64_t currentProgress = 0;\r\n\r\n            while (currentProgress < overallProgressMax)\r\n            {\r\n                currentProgress = 0;\r\n\r\n                for (auto const& installItem : installItems)\r\n                {\r\n                    const auto& status = installItem.GetCurrentStatus();\r\n                    currentProgress += static_cast<uint64_t>(status.PercentComplete());\r\n\r\n                    errorCode = status.ErrorCode();\r\n\r\n                    if (!SUCCEEDED(errorCode))\r\n                    {\r\n                        return errorCode;\r\n                    }\r\n                }\r\n\r\n                // It may take a while for Store client to pick up the install request.\r\n                // So we show indefinite progress here to avoid a progress bar stuck at 0.\r\n                if (currentProgress > 0)\r\n                {\r\n                    progress.OnProgress(currentProgress, overallProgressMax, ProgressType::Percent);\r\n                }\r\n\r\n                if (progress.IsCancelledBy(CancelReason::User))\r\n                {\r\n                    for (auto const& installItem : installItems)\r\n                    {\r\n                        installItem.Cancel();\r\n                    }\r\n                }\r\n\r\n                // If app shutdown then we have 30s to keep installing, keep going and hope for the best.\r\n                else if (progress.IsCancelledBy(CancelReason::AppShutdown) || monitor.IsUpdating())\r\n                {\r\n                    for (auto const& installItem : installItems)\r\n                    {\r\n                        // Insert spiderman meme.\r\n                        if (installItem.ProductId() == std::wstring{ s_AppInstallerProductId })\r\n                        {\r\n                            AICLI_LOG(Core, Info, << \"Asked to shutdown while installing AppInstaller.\");\r\n                            progress.OnProgress(overallProgressMax, overallProgressMax, ProgressType::Percent);\r\n                            cancelIfOperationFailed.release();\r\n                            return S_OK;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                Sleep(100);\r\n            }\r\n\r\n            if (SUCCEEDED(errorCode))\r\n            {\r\n                cancelIfOperationFailed.release();\r\n            }\r\n\r\n            return errorCode;\r\n        }\r\n    }\r\n\r\n    HRESULT MSStoreOperation::StartAndWaitForOperation(IProgressCallback& progress)\r\n    {\r\n        // Best effort verifying/acquiring product ownership.\r\n        std::ignore = EnsureFreeEntitlement(m_productId, m_scope);\r\n\r\n        if (m_type == MSStoreOperationType::Update)\r\n        {\r\n            return UpdatePackage(progress);\r\n        }\r\n        else\r\n        {\r\n            return InstallPackage(progress);\r\n        }\r\n    }\r\n\r\n    HRESULT MSStoreOperation::InstallPackage(IProgressCallback& progress)\r\n    {\r\n        PackageUpdateMonitor monitor;\r\n\r\n        AppInstallManager installManager;\r\n        AppInstallOptions installOptions;\r\n\r\n        installOptions.AllowForcedAppRestart(m_force);\r\n        if (m_isSilentMode)\r\n        {\r\n            installOptions.InstallInProgressToastNotificationMode(AppInstallationToastNotificationMode::NoToast);\r\n            installOptions.CompletedInstallToastNotificationMode(AppInstallationToastNotificationMode::NoToast);\r\n        }\r\n\r\n        if (m_type == MSStoreOperationType::Repair)\r\n        {\r\n            // Attempt to repair the installation of an app that is already installed.\r\n            installOptions.Repair(true);\r\n        }\r\n\r\n        if (m_scope == Manifest::ScopeEnum::Machine)\r\n        {\r\n            // TODO: There was a bug in InstallService where admin user is incorrectly identified as not admin,\r\n            // causing false access denied on many OS versions.\r\n            // Remove this check when the OS bug is fixed and back ported.\r\n            if (!Runtime::IsRunningAsSystem())\r\n            {\r\n                AICLI_LOG(Core, Error, << \"Device wide install for msstore type is not supported under admin context.\");\r\n                return APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED;\r\n            }\r\n\r\n            installOptions.InstallForAllUsers(true);\r\n        }\r\n\r\n        IVectorView<AppInstallItem> installItems = installManager.StartProductInstallAsync(\r\n            m_productId,            // ProductId\r\n            winrt::hstring(),       // FlightId\r\n            L\"WinGetCli\",           // ClientId\r\n            winrt::hstring(),\r\n            installOptions).get();\r\n\r\n        // Check if we need to restart or cancel existing items.\r\n        auto restartOrCancelResult = RestartOrCancelExistingOperationIfNecessary(installItems, installManager, m_productId);\r\n        RETURN_IF_FAILED(restartOrCancelResult);\r\n\r\n        // If restart or cancel happened, try again.\r\n        if (restartOrCancelResult == S_OK)\r\n        {\r\n            // Try again\r\n            installItems = installManager.StartProductInstallAsync(\r\n                m_productId,            // ProductId\r\n                winrt::hstring(),       // FlightId\r\n                L\"WinGetCli\",           // ClientId\r\n                winrt::hstring(),\r\n                installOptions).get();\r\n        }\r\n\r\n        return WaitForOperation(m_productId, m_isSilentMode, installItems, progress, monitor);\r\n    }\r\n\r\n    HRESULT MSStoreOperation::UpdatePackage(IProgressCallback& progress)\r\n    {\r\n        PackageUpdateMonitor monitor;\r\n\r\n        AppInstallManager installManager;\r\n        AppUpdateOptions updateOptions;\r\n        updateOptions.AllowForcedAppRestart(m_force);\r\n\r\n        // SearchForUpdateAsync will automatically trigger update if found.\r\n        AppInstallItem installItem = installManager.SearchForUpdatesAsync(\r\n            m_productId,          // ProductId\r\n            winrt::hstring(),   // SkuId\r\n            winrt::hstring(),\r\n            winrt::hstring(),   // ClientId\r\n            updateOptions\r\n        ).get();\r\n\r\n        if (!installItem)\r\n        {\r\n            return APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE;\r\n        }\r\n\r\n        std::vector<AppInstallItem> installItemVector{ installItem };\r\n        IVectorView<AppInstallItem> installItems = winrt::single_threaded_vector(std::move(installItemVector)).GetView();\r\n\r\n        // Check if we need to restart or cancel existing items.\r\n        auto restartOrCancelResult = RestartOrCancelExistingOperationIfNecessary(installItems, installManager, m_productId);\r\n        RETURN_IF_FAILED(restartOrCancelResult);\r\n\r\n        // If restart or cancel happened, try again.\r\n        if (restartOrCancelResult == S_OK)\r\n        {\r\n            // Try again\r\n            installItem = installManager.SearchForUpdatesAsync(\r\n                m_productId,          // ProductId\r\n                winrt::hstring(),   // SkuId\r\n                winrt::hstring(),\r\n                winrt::hstring(),   // ClientId\r\n                updateOptions\r\n            ).get();\r\n\r\n            if (!installItem)\r\n            {\r\n                return APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE;\r\n            }\r\n\r\n            installItemVector.clear();\r\n            installItemVector.emplace_back(installItem);\r\n            installItems = winrt::single_threaded_vector(std::move(installItemVector)).GetView();\r\n        }\r\n\r\n        return WaitForOperation(m_productId, m_isSilentMode, installItems, progress, monitor);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/MSStoreDownload.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include <AppInstallerStrings.h>\r\n#include <AppInstallerErrors.h>\r\n#include <AppinstallerLogging.h>\r\n#include \"AppInstallerMsixInfo.h\"\r\n#include \"AppInstallerRuntime.h\"\r\n#include \"winget/HttpClientHelper.h\"\r\n#include \"winget/JsonUtil.h\"\r\n#include \"winget/Locale.h\"\r\n#include \"winget/MSStoreDownload.h\"\r\n#include \"winget/NetworkSettings.h\"\r\n#include \"winget/Rest.h\"\r\n#include \"winget/UserSettings.h\"\r\n#ifndef WINGET_DISABLE_FOR_FUZZING\r\n#include <sfsclient/SFSClient.h>\r\n#endif\r\n\r\nnamespace AppInstaller::MSStore\r\n{\r\n    using namespace std::string_view_literals;\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n    namespace TestHooks\r\n    {\r\n        static std::shared_ptr<web::http::http_pipeline_stage> s_DisplayCatalog_HttpPipelineStage_Override = nullptr;\r\n\r\n        void SetDisplayCatalogHttpPipelineStage_Override(std::shared_ptr<web::http::http_pipeline_stage> value)\r\n        {\r\n            s_DisplayCatalog_HttpPipelineStage_Override = value;\r\n        }\r\n\r\n        static std::function<std::vector<SFS::AppContent>(std::string_view)>* s_SfsClient_AppContents_Override = nullptr;\r\n\r\n        void SetSfsClientAppContents_Override(std::function<std::vector<SFS::AppContent>(std::string_view)>* value)\r\n        {\r\n            s_SfsClient_AppContents_Override = value;\r\n        }\r\n\r\n        static std::shared_ptr<web::http::http_pipeline_stage> s_Licensing_HttpPipelineStage_Override = nullptr;\r\n\r\n        void SetLicensingHttpPipelineStage_Override(std::shared_ptr<web::http::http_pipeline_stage> value)\r\n        {\r\n            s_Licensing_HttpPipelineStage_Override = value;\r\n        }\r\n    }\r\n#endif\r\n\r\n    namespace DisplayCatalogDetails\r\n    {\r\n        // Default preferred sku to use\r\n        constexpr std::string_view TargetSkuIdValue = \"0015\"sv;\r\n\r\n        // Json response fields\r\n        constexpr std::string_view Product = \"Product\"sv;\r\n        constexpr std::string_view DisplaySkuAvailabilities = \"DisplaySkuAvailabilities\"sv;\r\n        constexpr std::string_view Sku = \"Sku\"sv;\r\n        constexpr std::string_view SkuId = \"SkuId\"sv;\r\n        constexpr std::string_view Properties = \"Properties\"sv;\r\n        constexpr std::string_view Packages = \"Packages\"sv;\r\n        constexpr std::string_view Languages = \"Languages\"sv;\r\n        constexpr std::string_view PackageFormat = \"PackageFormat\"sv;\r\n        constexpr std::string_view PackageId = \"PackageId\"sv;\r\n        constexpr std::string_view Architectures = \"Architectures\"sv;\r\n        constexpr std::string_view ContentId = \"ContentId\"sv;\r\n        constexpr std::string_view FulfillmentData = \"FulfillmentData\"sv;\r\n        constexpr std::string_view WuCategoryId = \"WuCategoryId\"sv;\r\n\r\n        // Display catalog rest endpoint\r\n        constexpr std::string_view DisplayCatalogRestApi = R\"(https://displaycatalog.mp.microsoft.com/v7.0/products/{0}?fieldsTemplate={1}&market={2}&languages={3}&catalogIds={4})\";\r\n        constexpr std::string_view Details = \"Details\"sv;\r\n        constexpr std::string_view Neutral = \"Neutral\"sv;\r\n        constexpr std::string_view TargetCatalogId = \"4\"sv;\r\n\r\n        enum class DisplayCatalogPackageFormatEnum\r\n        {\r\n            Unknown,\r\n            AppxBundle,\r\n            MsixBundle,\r\n            Appx,\r\n            Msix,\r\n        };\r\n\r\n        DisplayCatalogPackageFormatEnum ConvertToPackageFormatEnum(std::string_view packageFormatStr)\r\n        {\r\n            std::string packageFormat = Utility::ToLower(packageFormatStr);\r\n            if (packageFormat == \"appxbundle\")\r\n            {\r\n                return DisplayCatalogPackageFormatEnum::AppxBundle;\r\n            }\r\n            else if (packageFormat == \"msixbundle\")\r\n            {\r\n                return DisplayCatalogPackageFormatEnum::MsixBundle;\r\n            }\r\n            else if (packageFormat == \"appx\")\r\n            {\r\n                return DisplayCatalogPackageFormatEnum::Appx;\r\n            }\r\n            else if (packageFormat == \"msix\")\r\n            {\r\n                return DisplayCatalogPackageFormatEnum::Msix;\r\n            }\r\n\r\n            AICLI_LOG(Core, Info, << \"ConvertToPackageFormatEnum: Unknown package format: \" << packageFormatStr);\r\n            return DisplayCatalogPackageFormatEnum::Unknown;\r\n        }\r\n\r\n        struct DisplayCatalogPackage\r\n        {\r\n            std::string PackageId;\r\n\r\n            std::vector<AppInstaller::Utility::Architecture> Architectures;\r\n\r\n            std::vector<std::string> Languages;\r\n\r\n            DisplayCatalogPackageFormatEnum PackageFormat = DisplayCatalogPackageFormatEnum::Unknown;\r\n\r\n            // To be used later in sfs-client\r\n            std::string WuCategoryId;\r\n\r\n            // To be used later in licensing\r\n            std::string ContentId;\r\n        };\r\n\r\n        // Display catalog package comparison logic.\r\n        // The comparator follows similar logic as ManifestComparator.\r\n        namespace DisplayCatalogPackageComparison\r\n        {\r\n            struct DisplayCatalogPackageComparisonField\r\n            {\r\n                DisplayCatalogPackageComparisonField(std::string_view name) : m_name(name) {}\r\n\r\n                virtual ~DisplayCatalogPackageComparisonField() = default;\r\n\r\n                std::string_view Name() const { return m_name; }\r\n\r\n                virtual bool IsApplicable(const DisplayCatalogPackage& package) = 0;\r\n\r\n                virtual bool IsFirstBetter(const DisplayCatalogPackage& first, const DisplayCatalogPackage& second) = 0;\r\n\r\n            private:\r\n                std::string_view m_name;\r\n            };\r\n\r\n            struct PackageFormatComparator : public DisplayCatalogPackageComparisonField\r\n            {\r\n                PackageFormatComparator() : DisplayCatalogPackageComparisonField(\"Package Format\") {}\r\n\r\n                bool IsApplicable(const DisplayCatalogPackage& package) override\r\n                {\r\n                    return package.PackageFormat != DisplayCatalogPackageFormatEnum::Unknown;\r\n                }\r\n\r\n                bool IsFirstBetter(const DisplayCatalogPackage& first, const DisplayCatalogPackage& second) override\r\n                {\r\n                    return IsPackageFormatBundle(first) && !IsPackageFormatBundle(second);\r\n                }\r\n\r\n            private:\r\n                bool IsPackageFormatBundle(const DisplayCatalogPackage& package)\r\n                {\r\n                    return\r\n                        package.PackageFormat == DisplayCatalogPackageFormatEnum::AppxBundle ||\r\n                        package.PackageFormat == DisplayCatalogPackageFormatEnum::MsixBundle;\r\n                }\r\n            };\r\n\r\n            struct LocaleComparator : public DisplayCatalogPackageComparisonField\r\n            {\r\n                LocaleComparator(std::string locale) : DisplayCatalogPackageComparisonField(\"Locale\")\r\n                {\r\n                    if (!locale.empty())\r\n                    {\r\n                        m_locales.emplace_back(std::move(locale));\r\n                        m_isRequirement = true;\r\n                    }\r\n                    else\r\n                    {\r\n                        m_locales = Locale::GetUserPreferredLanguages();\r\n                    }\r\n\r\n                    AICLI_LOG(Core, Verbose,\r\n                        << \"Locale Comparator created with locales: \" << Utility::ConvertContainerToString(m_locales)\r\n                        << \" , Is requirement: \" << m_isRequirement);\r\n                }\r\n\r\n                bool IsApplicable(const DisplayCatalogPackage& package) override\r\n                {\r\n                    if (m_isRequirement)\r\n                    {\r\n                        for (auto const& locale : m_locales)\r\n                        {\r\n                            double distanceScore = GetBestDistanceScoreFromList(locale, package.Languages);\r\n                            if (distanceScore >= Locale::MinimumDistanceScoreAsCompatibleMatch)\r\n                            {\r\n                                return true;\r\n                            }\r\n                        }\r\n\r\n                        return false;\r\n                    }\r\n                    else\r\n                    {\r\n                        return true;\r\n                    }\r\n                }\r\n\r\n                bool IsFirstBetter(const DisplayCatalogPackage& first, const DisplayCatalogPackage& second)\r\n                {\r\n                    for (auto const& locale : m_locales)\r\n                    {\r\n                        double firstScore = GetBestDistanceScoreFromList(locale, first.Languages);\r\n                        double secondScore = GetBestDistanceScoreFromList(locale, second.Languages);\r\n\r\n                        if (firstScore >= Locale::MinimumDistanceScoreAsCompatibleMatch || secondScore >= Locale::MinimumDistanceScoreAsCompatibleMatch)\r\n                        {\r\n                            return firstScore > secondScore;\r\n                        }\r\n                    }\r\n\r\n                    return false;\r\n                }\r\n\r\n            private:\r\n                double GetBestDistanceScoreFromList(std::string_view targetLocale, const std::vector<std::string>& locales)\r\n                {\r\n                    double finalScore = 0;\r\n                    for (auto const& locale : locales)\r\n                    {\r\n                        double currentScore = Locale::GetDistanceOfLanguage(targetLocale, locale);\r\n                        if (currentScore > finalScore)\r\n                        {\r\n                            finalScore = currentScore;\r\n                        }\r\n                    }\r\n\r\n                    return finalScore;\r\n                }\r\n\r\n                std::vector<std::string> m_locales;\r\n                bool m_isRequirement = false;\r\n            };\r\n\r\n            struct ArchitectureComparator : public DisplayCatalogPackageComparisonField\r\n            {\r\n                ArchitectureComparator(Utility::Architecture architecture) : DisplayCatalogPackageComparisonField(\"Architecture\")\r\n                {\r\n                    if (architecture != Utility::Architecture::Unknown)\r\n                    {\r\n                        m_architectures.emplace_back(architecture);\r\n                        m_isRequirement = true;\r\n                    }\r\n                    else\r\n                    {\r\n                        m_architectures = Utility::GetApplicableArchitectures();\r\n                    }\r\n\r\n                    AICLI_LOG(Core, Verbose,\r\n                        << \"Architecture Comparator created with archs: \" << Utility::ConvertContainerToString(m_architectures, Utility::ToString)\r\n                        << \" , Is requirement: \" << m_isRequirement);\r\n                }\r\n\r\n                bool IsApplicable(const DisplayCatalogPackage& package) override\r\n                {\r\n                    if (m_isRequirement)\r\n                    {\r\n                        for (auto arch : package.Architectures)\r\n                        {\r\n                            if (Utility::IsApplicableArchitecture(arch, m_architectures) > Utility::InapplicableArchitecture)\r\n                            {\r\n                                return true;\r\n                            }\r\n                        }\r\n\r\n                        return false;\r\n                    }\r\n                    else\r\n                    {\r\n                        return true;\r\n                    }\r\n                }\r\n\r\n                bool IsFirstBetter(const DisplayCatalogPackage& first, const DisplayCatalogPackage& second) override\r\n                {\r\n                    for (auto arch : m_architectures)\r\n                    {\r\n                        auto firstItr = std::find(first.Architectures.begin(), first.Architectures.end(), arch);\r\n                        auto secondItr = std::find(second.Architectures.begin(), second.Architectures.end(), arch);\r\n\r\n                        if (firstItr != first.Architectures.end() && secondItr == second.Architectures.end())\r\n                        {\r\n                            true;\r\n                        }\r\n                        else if (secondItr != second.Architectures.end())\r\n                        {\r\n                            return false;\r\n                        }\r\n                    }\r\n\r\n                    return false;\r\n                }\r\n\r\n            private:\r\n                std::vector<Utility::Architecture> m_architectures;\r\n                bool m_isRequirement = false;\r\n            };\r\n\r\n            struct DisplayCatalogPackageComparator\r\n            {\r\n                DisplayCatalogPackageComparator(std::string requiredLocale, Utility::Architecture requiredArch)\r\n                {\r\n                    // Order of comparators matters.\r\n                    AddComparator(std::make_unique<LocaleComparator>(requiredLocale));\r\n                    AddComparator(std::make_unique<ArchitectureComparator>(requiredArch));\r\n                    AddComparator(std::make_unique<PackageFormatComparator>());\r\n                }\r\n\r\n                // Gets the best installer from the manifest, if at least one is applicable.\r\n                std::optional<DisplayCatalogPackage> GetPreferredPackage(const std::vector<DisplayCatalogPackage>& packages)\r\n                {\r\n                    AICLI_LOG(Core, Verbose, << \"Starting display catalog package selection.\");\r\n\r\n                    const DisplayCatalogPackage* result = nullptr;\r\n                    for (const auto& package : packages)\r\n                    {\r\n                        if (IsApplicable(package) && (!result || IsFirstBetter(package, *result)))\r\n                        {\r\n                            result = &package;\r\n                        }\r\n                    }\r\n\r\n                    if (result)\r\n                    {\r\n                        return *result;\r\n                    }\r\n                    else\r\n                    {\r\n                        return {};\r\n                    }\r\n                }\r\n\r\n                // Determines if the package is applicable.\r\n                bool IsApplicable(const DisplayCatalogPackage& package)\r\n                {\r\n                    for (const auto& comparator : m_comparators)\r\n                    {\r\n                        if (!comparator->IsApplicable(package))\r\n                        {\r\n                            return false;\r\n                        }\r\n                    }\r\n\r\n                    return true;\r\n                }\r\n\r\n                // Determines if the first package is a better choice.\r\n                bool IsFirstBetter(const DisplayCatalogPackage& first, const DisplayCatalogPackage& second)\r\n                {\r\n                    for (const auto& comparator : m_comparators)\r\n                    {\r\n                        bool forwardCompare = comparator->IsFirstBetter(first, second);\r\n                        bool reverseCompare = comparator->IsFirstBetter(second, first);\r\n\r\n                        if (forwardCompare && reverseCompare)\r\n                        {\r\n                            AICLI_LOG(Core, Error, << \"Packages are both better than each other?\");\r\n                            THROW_HR(E_UNEXPECTED);\r\n                        }\r\n\r\n                        if (forwardCompare && !reverseCompare)\r\n                        {\r\n                            AICLI_LOG(Core, Verbose, << \"Package \" << first.PackageId << \" is better than \" << second.PackageId);\r\n                            return true;\r\n                        }\r\n                    }\r\n\r\n                    AICLI_LOG(Core, Verbose, << \"Package \" << first.PackageId << \" is equivalent in priority to \" << second.PackageId);\r\n                    return false;\r\n                }\r\n\r\n            private:\r\n                void AddComparator(std::unique_ptr<DisplayCatalogPackageComparisonField>&& comparator)\r\n                {\r\n                    if (comparator)\r\n                    {\r\n                        m_comparators.emplace_back(std::move(comparator));\r\n                    }\r\n                }\r\n\r\n                std::vector<std::unique_ptr<DisplayCatalogPackageComparisonField>> m_comparators;\r\n            };\r\n        }\r\n\r\n        // Display catalog API invocation and handling\r\n\r\n        utility::string_t GetDisplayCatalogRestApi(std::string_view productId, std::string_view locale)\r\n        {\r\n            std::vector<Utility::LocIndString> locales;\r\n            if (!locale.empty())\r\n            {\r\n                locales.emplace_back(locale);\r\n            }\r\n            else\r\n            {\r\n                for (auto const& localeEntry : Locale::GetUserPreferredLanguages())\r\n                {\r\n                    locales.emplace_back(localeEntry);\r\n                }\r\n            }\r\n\r\n            // Neutral is always added\r\n            locales.emplace_back(Neutral);\r\n\r\n            auto restEndpoint = AppInstaller::Utility::Format(std::string{ DisplayCatalogRestApi },\r\n                productId, Details, AppInstaller::Runtime::GetOSRegion(), Utility::Join(Utility::LocIndView(\",\"), locales), TargetCatalogId);\r\n\r\n            return JSON::GetUtilityString(restEndpoint);\r\n        }\r\n\r\n        // Response format:\r\n        // {\r\n        //   \"Product\": {\r\n        //     \"DisplaySkuAvailabilities\": [\r\n        //       {\r\n        //         \"Sku\": {\r\n        //           \"SkuId\": \"0015\",\r\n        //           ... Sku Contents ...\r\n        //         }\r\n        //       }\r\n        //     ]\r\n        //   }\r\n        // }\r\n        std::reference_wrapper<const web::json::value> GetSkuNodeFromDisplayCatalogResponse(const web::json::value& responseObject)\r\n        {\r\n            AICLI_LOG(Core, Info, << \"Started parsing display catalog response. Try to find target sku: \" << TargetSkuIdValue);\r\n\r\n            if (responseObject.is_null())\r\n            {\r\n                AICLI_LOG(Core, Error, << \"Missing DisplayCatalog Response json object.\");\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_DISPLAYCATALOG_API_FAILED);\r\n            }\r\n\r\n            std::optional<std::reference_wrapper<const web::json::value>> product = JSON::GetJsonValueFromNode(responseObject, JSON::GetUtilityString(Product));\r\n            if (!product)\r\n            {\r\n                AICLI_LOG(Core, Error, << \"Missing Product node\");\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_DISPLAYCATALOG_API_FAILED);\r\n            }\r\n\r\n            auto skuEntries = JSON::GetRawJsonArrayFromJsonNode(product.value().get(), JSON::GetUtilityString(DisplaySkuAvailabilities));\r\n            if (!skuEntries)\r\n            {\r\n                AICLI_LOG(Core, Error, << \"Missing DisplaySkuAvailabilities\");\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_DISPLAYCATALOG_API_FAILED);\r\n            }\r\n\r\n            for (const auto& skuEntry : skuEntries.value().get())\r\n            {\r\n                std::optional<std::reference_wrapper<const web::json::value>> sku = JSON::GetJsonValueFromNode(skuEntry, JSON::GetUtilityString(Sku));\r\n                if (!sku)\r\n                {\r\n                    AICLI_LOG(Core, Error, << \"Missing Sku\");\r\n                    THROW_HR(APPINSTALLER_CLI_ERROR_DISPLAYCATALOG_API_FAILED);\r\n                }\r\n\r\n                const auto& skuValue = sku.value().get();\r\n                auto skuId = JSON::GetRawStringValueFromJsonNode(skuValue, JSON::GetUtilityString(SkuId)).value_or(\"\");\r\n                if (TargetSkuIdValue == skuId)\r\n                {\r\n                    AICLI_LOG(Core, Info, << \"Target Sku (\" << TargetSkuIdValue << \") found\");\r\n                    return skuValue;\r\n                }\r\n            }\r\n\r\n            AICLI_LOG(Core, Error, << \"Target Sku (\" << TargetSkuIdValue << \") not found\");\r\n            THROW_HR(APPINSTALLER_CLI_ERROR_NO_APPLICABLE_DISPLAYCATALOG_PACKAGE);\r\n        }\r\n\r\n        // Response format:\r\n        // {\r\n        //   \"Sku\": {\r\n        //     \"Properties\": {\r\n        //       \"Packages\": [\r\n        //         {\r\n        //           \"PackageId\": \"package id\",\r\n        //           \"Architectures\": [ \"x86\", \"x64\" ],\r\n        //           \"Languages\": [ \"en\", \"fr\" ],\r\n        //           \"PackageFormat\": \"AppxBundle\",\r\n        //           \"ContentId\": \"guid\",\r\n        //           \"FulfillmentData\": {\r\n        //             \"WuCategoryId\": \"guid\",\r\n        //           }\r\n        //         }\r\n        //       ]\r\n        //     }\r\n        //   }\r\n        // }\r\n        std::vector<DisplayCatalogPackage> GetDisplayCatalogPackagesFromSkuNode(const web::json::value& jsonObject)\r\n        {\r\n            AICLI_LOG(Core, Info, << \"Started extracting display catalog packages from sku.\");\r\n\r\n            std::optional<std::reference_wrapper<const web::json::value>> properties = JSON::GetJsonValueFromNode(jsonObject, JSON::GetUtilityString(Properties));\r\n            if (!properties)\r\n            {\r\n                AICLI_LOG(Core, Error, << \"Missing Properties\");\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_DISPLAYCATALOG_API_FAILED);\r\n            }\r\n\r\n            const auto& propertiesValue = properties.value().get();\r\n            auto packages = JSON::GetRawJsonArrayFromJsonNode(propertiesValue, JSON::GetUtilityString(Packages));\r\n            if (!packages)\r\n            {\r\n                AICLI_LOG(Core, Error, << \"Missing Packages\");\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_DISPLAYCATALOG_API_FAILED);\r\n            }\r\n\r\n            std::vector<DisplayCatalogPackage> displayCatalogPackages;\r\n\r\n            for (const auto& packageEntry : packages.value().get())\r\n            {\r\n                DisplayCatalogPackage catalogPackage;\r\n\r\n                // Package Id\r\n                catalogPackage.PackageId = JSON::GetRawStringValueFromJsonNode(packageEntry, JSON::GetUtilityString(PackageId)).value_or(\"\");\r\n                // Architectures\r\n                auto architectures = JSON::GetRawStringArrayFromJsonNode(packageEntry, JSON::GetUtilityString(Architectures));\r\n                for (const auto& arch : architectures)\r\n                {\r\n                    auto archEnum = Utility::ConvertToArchitectureEnum(arch);\r\n                    if (archEnum != Utility::Architecture::Unknown)\r\n                    {\r\n                        catalogPackage.Architectures.emplace_back(archEnum);\r\n                    }\r\n                }\r\n                // Languages\r\n                auto languages = JSON::GetRawStringArrayFromJsonNode(packageEntry, JSON::GetUtilityString(Languages));\r\n                for (const auto& language : languages)\r\n                {\r\n                    catalogPackage.Languages.emplace_back(language);\r\n                }\r\n                // Package Format\r\n                auto packageFormat = JSON::GetRawStringValueFromJsonNode(packageEntry, JSON::GetUtilityString(PackageFormat)).value_or(\"\");\r\n                catalogPackage.PackageFormat = ConvertToPackageFormatEnum(packageFormat);\r\n                // Content Id\r\n                catalogPackage.ContentId = JSON::GetRawStringValueFromJsonNode(packageEntry, JSON::GetUtilityString(ContentId)).value_or(\"\");\r\n                if (catalogPackage.ContentId.empty())\r\n                {\r\n                    AICLI_LOG(Core, Warning, << \"Missing ContentId\");\r\n                    // ContentId is required for licensing. Skip this package if missing.\r\n                    continue;\r\n                }\r\n                // WuCategoryId\r\n                std::optional<std::reference_wrapper<const web::json::value>> fulfillmentData = JSON::GetJsonValueFromNode(packageEntry, JSON::GetUtilityString(FulfillmentData));\r\n                if (!fulfillmentData)\r\n                {\r\n                    AICLI_LOG(Core, Warning, << \"Missing FulfillmentData\");\r\n                    // WuCategoryId is required for sfs-client. Skip this package if missing.\r\n                    continue;\r\n                }\r\n                catalogPackage.WuCategoryId = JSON::GetRawStringValueFromJsonNode(fulfillmentData.value().get(), JSON::GetUtilityString(WuCategoryId)).value_or(\"\");\r\n                if (catalogPackage.WuCategoryId.empty())\r\n                {\r\n                    AICLI_LOG(Core, Warning, << \"Missing WuCategoryId\");\r\n                    // WuCategoryId is required for sfs-client. Skip this package if missing.\r\n                    continue;\r\n                }\r\n\r\n                displayCatalogPackages.emplace_back(std::move(catalogPackage));\r\n            }\r\n\r\n            return displayCatalogPackages;\r\n        }\r\n\r\n        DisplayCatalogPackage CallDisplayCatalogAndGetPreferredPackage(std::string_view productId, std::string_view locale, Utility::Architecture architecture, const Http::HttpClientHelper::HttpRequestHeaders& authHeaders)\r\n        {\r\n            AICLI_LOG(Core, Info, << \"CallDisplayCatalogAndGetPreferredPackage with ProductId: \" << productId << \" Locale: \" << locale << \" Architecture: \" << Utility::ToString(architecture));\r\n\r\n            auto displayCatalogApi = GetDisplayCatalogRestApi(productId, locale);\r\n\r\n            AppInstaller::Http::HttpClientHelper httpClientHelper;\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n            if (TestHooks::s_DisplayCatalog_HttpPipelineStage_Override)\r\n            {\r\n                httpClientHelper = AppInstaller::Http::HttpClientHelper{ TestHooks::s_DisplayCatalog_HttpPipelineStage_Override };\r\n            }\r\n#endif\r\n\r\n            std::optional<web::json::value> displayCatalogResponseObject = httpClientHelper.HandleGet(displayCatalogApi, {}, authHeaders);\r\n\r\n            if (!displayCatalogResponseObject)\r\n            {\r\n                AICLI_LOG(Core, Error, << \"No display catalog json object found\");\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_DISPLAYCATALOG_API_FAILED);\r\n            }\r\n\r\n            const auto& sku = GetSkuNodeFromDisplayCatalogResponse(displayCatalogResponseObject.value());\r\n            auto displayCatalogPackages = GetDisplayCatalogPackagesFromSkuNode(sku.get());\r\n\r\n            DisplayCatalogPackageComparison::DisplayCatalogPackageComparator packageComparator{ std::string{ locale }, architecture };\r\n            auto preferredPackageResult = packageComparator.GetPreferredPackage(displayCatalogPackages);\r\n\r\n            if (!preferredPackageResult)\r\n            {\r\n                AICLI_LOG(Core, Error,\r\n                    << \"No applicable display catalog package found for ProductId: \" << productId\r\n                    << \" , Locale: \" << locale << \" , Architecture: \" << Utility::ToString(architecture));\r\n\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_NO_APPLICABLE_DISPLAYCATALOG_PACKAGE);\r\n            }\r\n\r\n            auto preferredPackage = preferredPackageResult.value();\r\n\r\n            AICLI_LOG(Core, Info,\r\n                << \"DisplayCatalog package selected. WuCategoryId: \" << preferredPackage.WuCategoryId\r\n                << \" , ContentId: \" << preferredPackage.ContentId);\r\n\r\n            return preferredPackage;\r\n        }\r\n    }\r\n\r\n#ifndef WINGET_DISABLE_FOR_FUZZING\r\n    namespace SfsClientDetails\r\n    {\r\n        const std::string SupportedFileTypes[] = { \".msix\", \".msixbundle\", \".appx\", \".appxbundle\" };\r\n\r\n        Manifest::PlatformEnum ConvertFromSfsPlatform(std::string_view applicability)\r\n        {\r\n            if (Utility::CaseInsensitiveStartsWith(applicability, \"universal\"))\r\n            {\r\n                return Manifest::PlatformEnum::Universal;\r\n            }\r\n            else if (Utility::CaseInsensitiveStartsWith(applicability, \"desktop\"))\r\n            {\r\n                return Manifest::PlatformEnum::Desktop;\r\n            }\r\n            else if (Utility::CaseInsensitiveStartsWith(applicability, \"iot\"))\r\n            {\r\n                return Manifest::PlatformEnum::IoT;\r\n            }\r\n            else if (Utility::CaseInsensitiveStartsWith(applicability, \"analog\"))\r\n            {\r\n                return Manifest::PlatformEnum::Holographic;\r\n            }\r\n            else if (Utility::CaseInsensitiveStartsWith(applicability, \"ppi\"))\r\n            {\r\n                return Manifest::PlatformEnum::Team;\r\n            }\r\n\r\n            return Manifest::PlatformEnum::Unknown;\r\n        }\r\n\r\n        // Parses a string of the form `<PLATFORM>=<MINIMUM REQUIRED VERSION>{,}?`.\r\n        struct PlatformApplicability\r\n        {\r\n            explicit PlatformApplicability(std::string_view input, bool extractVersion = true) :\r\n                Platform(ConvertFromSfsPlatform(input))\r\n            {\r\n                if (extractVersion)\r\n                {\r\n                    THROW_HR_IF(E_INVALIDARG, input.empty());\r\n\r\n                    size_t position = input.find('=');\r\n                    THROW_HR_IF(E_INVALIDARG, std::string_view::npos == position);\r\n\r\n                    position += 1;\r\n                    size_t length = input.size() - position;\r\n                    if (length > 0 && input.back() == ',')\r\n                    {\r\n                        length -= 1;\r\n                    }\r\n\r\n                    MinimumVersion = Utility::UInt64Version{ std::string{ input.substr(position, length) } };\r\n                }\r\n            }\r\n\r\n            Manifest::PlatformEnum Platform;\r\n            std::optional<Utility::UInt64Version> MinimumVersion;\r\n        };\r\n\r\n        Utility::Architecture ConvertFromSfsArchitecture(SFS::Architecture sfsArchitecture)\r\n        {\r\n            switch (sfsArchitecture)\r\n            {\r\n            case SFS::Architecture::Amd64:\r\n                return Utility::Architecture::X64;\r\n            case SFS::Architecture::x86:\r\n                return Utility::Architecture::X86;\r\n            case SFS::Architecture::Arm64:\r\n                return Utility::Architecture::Arm64;\r\n            case SFS::Architecture::Arm:\r\n                return Utility::Architecture::Arm;\r\n            case SFS::Architecture::None:\r\n                return Utility::Architecture::Neutral;\r\n            }\r\n\r\n            return Utility::Architecture::Unknown;\r\n        }\r\n\r\n        std::vector<Manifest::PlatformEnum> GetSfsPackageFileSupportedPlatforms(\r\n            const SFS::AppFile& appFile,\r\n            Manifest::PlatformEnum requiredPlatform,\r\n            const std::optional<Utility::UInt64Version>& targetOSVersion)\r\n        {\r\n            std::vector<Manifest::PlatformEnum> supportedPlatforms;\r\n\r\n            for (auto const& applicability : appFile.GetApplicabilityDetails().GetPlatformApplicabilityForPackage())\r\n            {\r\n                AICLI_LOG(Core, Verbose, << \"  examining platform [\" << applicability << \"] for applicability...\");\r\n                PlatformApplicability platform(applicability, targetOSVersion.has_value());\r\n\r\n                if (platform.Platform == Manifest::PlatformEnum::Unknown)\r\n                {\r\n                    AICLI_LOG(Core, Verbose, << \"    not applicable due to unknown platform\");\r\n                    continue;\r\n                }\r\n\r\n                if (platform.MinimumVersion && targetOSVersion)\r\n                {\r\n                    if (targetOSVersion.value() < platform.MinimumVersion.value())\r\n                    {\r\n                        AICLI_LOG(Core, Verbose, << \"    not applicable due to OS version; target [\"\r\n                            << targetOSVersion.value().ToString() << \"] is lower than minimum [\"\r\n                            << platform.MinimumVersion.value().ToString() << \"]\");\r\n                        continue;\r\n                    }\r\n                }\r\n\r\n                if (platform.Platform == requiredPlatform || requiredPlatform == Manifest::PlatformEnum::Unknown)\r\n                {\r\n                    AICLI_LOG(Core, Verbose, << \"    applicable\");\r\n                    supportedPlatforms.emplace_back(platform.Platform);\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(Core, Verbose, << \"    not applicable due to platform requirement\");\r\n                }\r\n            }\r\n\r\n            return supportedPlatforms;\r\n        }\r\n\r\n        std::vector<Utility::Architecture> GetSfsPackageFileSupportedArchitectures(const SFS::AppFile& appFile, Utility::Architecture requiredArchitecture)\r\n        {\r\n            std::vector<Utility::Architecture> supportedArchitectures;\r\n\r\n            for (auto const& sfsArchitecture : appFile.GetApplicabilityDetails().GetArchitectures())\r\n            {\r\n                auto convertedArchitecture = ConvertFromSfsArchitecture(sfsArchitecture);\r\n                if (convertedArchitecture == Utility::Architecture::Unknown)\r\n                {\r\n                    continue;\r\n                }\r\n\r\n                if (requiredArchitecture == Utility::Architecture::Unknown || // No required architecture\r\n                    convertedArchitecture == requiredArchitecture)\r\n                {\r\n                    supportedArchitectures.emplace_back(convertedArchitecture);\r\n                }\r\n            }\r\n\r\n            return supportedArchitectures;\r\n        }\r\n\r\n        std::string GetSfsPackageFileExtension(const SFS::AppFile& appFile)\r\n        {\r\n            return std::filesystem::path{ appFile.GetFileId() }.extension().u8string();\r\n        }\r\n\r\n        bool IsFileExtensionSupported(std::string_view fileExtension)\r\n        {\r\n            for (auto const& supportedFileType : SupportedFileTypes)\r\n            {\r\n                if (Utility::CaseInsensitiveEquals(supportedFileType, fileExtension))\r\n                {\r\n                    return true;\r\n                }\r\n            }\r\n\r\n            return false;\r\n        }\r\n\r\n        // The file name will be {Name}_{Version}_{Platform list}_{Arch list}.{File Extension}\r\n        // If the file name is longer than 256, file moniker will be used.\r\n        std::string GetSfsPackageFileNameForDownload(\r\n            const std::string& packageName,\r\n            const Utility::UInt64Version& packageVersion,\r\n            const std::vector<Manifest::PlatformEnum>& supportedPlatforms,\r\n            const std::vector<Utility::Architecture>& supportedArchitectures,\r\n            const std::string& fileExtension,\r\n            const std::string& fileMoniker)\r\n        {\r\n            std::string platformString;\r\n            for (auto platform : supportedPlatforms)\r\n            {\r\n                platformString += std::string{ Manifest::PlatformToString(platform, true) } + '.';\r\n            }\r\n            platformString.resize(platformString.size() - 1);\r\n\r\n            std::string architectureString;\r\n            for (auto architecture : supportedArchitectures)\r\n            {\r\n                architectureString += std::string{ Utility::ToString(architecture) } + '.';\r\n            }\r\n            architectureString.resize(architectureString.size() - 1);\r\n\r\n            std::string fileName =\r\n                packageName + '_' +\r\n                packageVersion.ToString() + '_' +\r\n                platformString + '_' +\r\n                architectureString +\r\n                fileExtension;\r\n\r\n            if (fileName.length() < 256)\r\n            {\r\n                return fileName;\r\n            }\r\n            else\r\n            {\r\n                return fileMoniker + fileExtension;\r\n            }\r\n        }\r\n\r\n        void SfsClientLoggingCallback(const SFS::LogData& logData)\r\n        {\r\n            std::string message = \"Message: \" + std::string{ logData.message };\r\n            message += \" File: \" + std::string{ logData.file };\r\n            message += \" Line: \" + std::to_string(logData.line);\r\n            message += \" Function: \" + std::string{ logData.function };\r\n\r\n            switch (logData.severity)\r\n            {\r\n            case SFS::LogSeverity::Verbose:\r\n                AICLI_LOG(Core, Verbose, << message);\r\n                break;\r\n            case SFS::LogSeverity::Info:\r\n                AICLI_LOG(Core, Info, << message);\r\n                break;\r\n            case SFS::LogSeverity::Warning:\r\n                AICLI_LOG(Core, Warning, << message);\r\n                break;\r\n            case SFS::LogSeverity::Error:\r\n                AICLI_LOG(Core, Error, << message);\r\n                break;\r\n            }\r\n        }\r\n\r\n        const std::unique_ptr<SFS::SFSClient>& GetSfsClientInstance()\r\n        {\r\n            static std::unique_ptr<SFS::SFSClient> s_sfsClient;\r\n            static std::once_flag s_sfsClientInitializeOnce;\r\n\r\n            std::call_once(s_sfsClientInitializeOnce,\r\n                [&]()\r\n                {\r\n                    SFS::ClientConfig config;\r\n                    config.accountId = \"storeapps\";\r\n                    config.instanceId = \"storeapps\";\r\n                    config.logCallbackFn = SfsClientLoggingCallback;\r\n\r\n                    auto result = SFS::SFSClient::Make(config, s_sfsClient);\r\n                    if (!result)\r\n                    {\r\n                        AICLI_LOG(Core, Error, << \"Failed to initialize SfsClient. Error code: \" << result.GetCode() << \" Message: \" << result.GetMsg());\r\n                        THROW_HR_MSG(APPINSTALLER_CLI_ERROR_SFSCLIENT_API_FAILED, \"Failed to initialize SfsClient. ErrorCode: %lu Message: %hs\", result.GetCode(), result.GetMsg().c_str());\r\n                    }\r\n                });\r\n\r\n            return s_sfsClient;\r\n        }\r\n\r\n        std::vector<MSStoreDownloadFile> PopulateSfsAppFileToMSStoreDownloadFileVector(\r\n            const std::vector<SFS::AppFile>& appFiles,\r\n            Utility::Architecture requiredArchitecture = Utility::Architecture::Unknown,\r\n            Manifest::PlatformEnum requiredPlatform = Manifest::PlatformEnum::Unknown,\r\n            const std::optional<Utility::UInt64Version>& targetOSVersion = std::nullopt)\r\n        {\r\n            using PlatformAndArchitectureKey = std::pair<Manifest::PlatformEnum, Utility::Architecture>;\r\n\r\n            // Since the server may return multiple versions of the same package, we'll use this map to record the one with latest version\r\n            // for each Platform|Architecture pair.\r\n            std::map<PlatformAndArchitectureKey, MSStoreDownloadFile> downloadFilesMap;\r\n\r\n            for (auto const& appFile : appFiles)\r\n            {\r\n                AICLI_LOG(Core, Info, << \"Examining package [\" << appFile.GetFileMoniker() << \" (\" << appFile.GetFileId() << \")] for download...\");\r\n\r\n                // Filter out unsupported packages\r\n                auto supportedPlatforms = GetSfsPackageFileSupportedPlatforms(appFile, requiredPlatform, targetOSVersion);\r\n                if (supportedPlatforms.empty())\r\n                {\r\n                    AICLI_LOG(Core, Verbose, << \"  package has no applicable platform.\");\r\n                    continue;\r\n                }\r\n                auto supportedArchitectures = GetSfsPackageFileSupportedArchitectures(appFile, requiredArchitecture);\r\n                if (supportedArchitectures.empty())\r\n                {\r\n                    AICLI_LOG(Core, Verbose, << \"  package has no applicable architecture.\");\r\n                    continue;\r\n                }\r\n                std::string fileExtension = GetSfsPackageFileExtension(appFile);\r\n                if (!IsFileExtensionSupported(fileExtension))\r\n                {\r\n                    AICLI_LOG(Core, Verbose, << \"  package has unsupported file type [\" << fileExtension << \"].\");\r\n                    continue;\r\n                }\r\n\r\n                MSStoreDownloadFile downloadFile;\r\n                downloadFile.Url = appFile.GetUrl();\r\n                // The sha256 hash was base64 encoded\r\n                downloadFile.Sha256 = JSON::Base64Decode(appFile.GetHashes().at(SFS::HashType::Sha256));\r\n                auto packageInfo = Msix::GetPackageIdInfoFromFullName(appFile.GetFileMoniker());\r\n                downloadFile.Version = packageInfo.Version;\r\n                downloadFile.FileName = GetSfsPackageFileNameForDownload(\r\n                    packageInfo.Name, packageInfo.Version, supportedPlatforms,\r\n                    supportedArchitectures, fileExtension, appFile.GetFileMoniker());\r\n\r\n                // Update the platform architecture map with latest package if applicable\r\n                for (auto supportedPlatform : supportedPlatforms)\r\n                {\r\n                    for (auto supportedArchitecture : supportedArchitectures)\r\n                    {\r\n                        PlatformAndArchitectureKey downloadFileKey{ supportedPlatform, supportedArchitecture };\r\n                        if (downloadFile.Version > downloadFilesMap[downloadFileKey].Version)\r\n                        {\r\n                            downloadFilesMap[downloadFileKey] = downloadFile;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Generate MSStoreDownloadFile vector and remove duplication.\r\n            std::vector<MSStoreDownloadFile> result;\r\n            for (auto& downloadFileEntry : downloadFilesMap)\r\n            {\r\n                if (std::find_if(result.begin(), result.end(),\r\n                    [&](const MSStoreDownloadFile& downloadFile)\r\n                    {\r\n                        return Utility::CaseInsensitiveEquals(downloadFile.FileName, downloadFileEntry.second.FileName);\r\n                    }) == result.end())\r\n                {\r\n                    result.emplace_back(std::move(downloadFileEntry.second));\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        MSStoreDownloadInfo CallSfsClientAndGetMSStoreDownloadInfo(\r\n            std::string_view wuCategoryId,\r\n            Utility::Architecture requiredArchitecture,\r\n            Manifest::PlatformEnum requiredPlatform,\r\n            const std::optional<Utility::UInt64Version>& targetOSVersion)\r\n        {\r\n            AICLI_LOG(Core, Info, << \"CallSfsClientAndGetMSStoreDownloadInfo with WuCategoryId: \" << wuCategoryId\r\n                << \" Architecture: \" << Utility::ToString(requiredArchitecture) << \" Platform: \" << Manifest::PlatformToString(requiredPlatform)\r\n                << \" Target OS Version: \" << (targetOSVersion ? targetOSVersion.value().ToString() : \"any\"));\r\n\r\n            std::vector<SFS::AppContent> appContents;\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n            if (TestHooks::s_SfsClient_AppContents_Override)\r\n            {\r\n                appContents = (*TestHooks::s_SfsClient_AppContents_Override)(wuCategoryId);\r\n            }\r\n            else\r\n#endif\r\n            {\r\n                SFS::RequestParams sfsClientRequest;\r\n                sfsClientRequest.productRequests = { {std::string{ wuCategoryId }, {}} };\r\n                const auto& proxyUri = AppInstaller::Settings::Network().GetProxyUri();\r\n                if (proxyUri)\r\n                {\r\n                    AICLI_LOG(Core, Info, << \"Passing proxy to SFS client \" << *proxyUri);\r\n                    sfsClientRequest.proxy = *proxyUri;\r\n                }\r\n\r\n                auto requestResult = GetSfsClientInstance()->GetLatestAppDownloadInfo(sfsClientRequest, appContents);\r\n                if (!requestResult)\r\n                {\r\n                    if (requestResult.GetCode() == SFS::Result::Code::HttpNotFound)\r\n                    {\r\n                        AICLI_LOG(Core, Error, << \"Failed to call SfsClient GetLatestAppDownloadInfo. Package not found.\");\r\n                        THROW_HR_MSG(APPINSTALLER_CLI_ERROR_SFSCLIENT_PACKAGE_NOT_SUPPORTED, \"Failed to call SfsClient GetLatestAppDownloadInfo. Package download not supported.\");\r\n                    }\r\n                    else\r\n                    {\r\n                        AICLI_LOG(Core, Error, << \"Failed to call SfsClient GetLatestAppDownloadInfo. Error code: \" << requestResult.GetCode() << \" Message: \" << requestResult.GetMsg());\r\n                        THROW_HR_MSG(APPINSTALLER_CLI_ERROR_SFSCLIENT_API_FAILED, \"Failed to call SfsClient GetLatestAppDownloadInfo. ErrorCode: %lu Message: %hs\", requestResult.GetCode(), requestResult.GetMsg().c_str());\r\n                    }\r\n                }\r\n            }\r\n\r\n            THROW_HR_IF(E_UNEXPECTED, appContents.empty());\r\n\r\n            MSStoreDownloadInfo result;\r\n            // Currently for app downloads, the result vector is always size 1.\r\n            const auto& appContent = appContents.at(0);\r\n\r\n            // Populate main packages\r\n            result.MainPackages = PopulateSfsAppFileToMSStoreDownloadFileVector(appContent.GetFiles(), requiredArchitecture, requiredPlatform, targetOSVersion);\r\n\r\n            // Populate dependency packages\r\n            for (auto const& dependencyEntry : appContent.GetPrerequisites())\r\n            {\r\n                // Not passing in required platform for dependencies. Dependencies are mostly Windows.Universal.\r\n                auto dependencyPackages = PopulateSfsAppFileToMSStoreDownloadFileVector(dependencyEntry.GetFiles(), requiredArchitecture, Manifest::PlatformEnum::Unknown, targetOSVersion);\r\n                std::move(dependencyPackages.begin(), dependencyPackages.end(), std::inserter(result.DependencyPackages, result.DependencyPackages.end()));\r\n            }\r\n\r\n            if (result.MainPackages.empty())\r\n            {\r\n                AICLI_LOG(Core, Error, << \"No applicable SFS main package.\");\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_NO_APPLICABLE_SFSCLIENT_PACKAGE);\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n#endif\r\n\r\n    namespace LicensingDetails\r\n    {\r\n        // Json response fields\r\n        constexpr std::string_view License = \"license\"sv;\r\n        constexpr std::string_view Keys = \"keys\"sv;\r\n        constexpr std::string_view Value = \"value\"sv;\r\n\r\n        // Licensing rest endpoint\r\n        constexpr std::string_view LicensingRestEndpoint = \"https://licensing.md.mp.microsoft.com/v9.0/licenses/offlineContent\";\r\n        constexpr std::string_view ContentId = \"contentId\"sv;\r\n        constexpr std::string_view From = \"From\"sv;\r\n\r\n        // Response:\r\n        // {\r\n        //   \"license\": {\r\n        //     \"keys\": [ // returned as array for future, for now only 1 key\r\n        //       {\r\n        //         \"value\": \"base64 encoded string\"\r\n        //       }\r\n        //     ]\r\n        //   }\r\n        // }\r\n        std::vector<BYTE> GetLicensing(std::string_view contentId, const Http::HttpClientHelper::HttpRequestHeaders& authHeaders)\r\n        {\r\n            AICLI_LOG(Core, Error, << \"GetLicensing with ContentId: \" << contentId);\r\n\r\n            AppInstaller::Http::HttpClientHelper httpClientHelper;\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n            if (TestHooks::s_Licensing_HttpPipelineStage_Override)\r\n            {\r\n                httpClientHelper = AppInstaller::Http::HttpClientHelper{ TestHooks::s_Licensing_HttpPipelineStage_Override };\r\n            }\r\n#endif\r\n\r\n            web::json::value requestBody;\r\n            requestBody[JSON::GetUtilityString(ContentId)] = web::json::value::string(JSON::GetUtilityString(contentId));\r\n            Http::HttpClientHelper::HttpRequestHeaders requestHeaders;\r\n            requestHeaders.insert_or_assign(JSON::GetUtilityString(From), L\"winget-cli\");\r\n\r\n            std::optional<web::json::value> licensingResponseObject = std::nullopt;\r\n            try\r\n            {\r\n                licensingResponseObject = httpClientHelper.HandlePost(\r\n                    JSON::GetUtilityString(LicensingRestEndpoint), requestBody, requestHeaders, authHeaders);\r\n            }\r\n            catch (const wil::ResultException& re)\r\n            {\r\n                if (re.GetErrorCode() == HTTP_E_STATUS_FORBIDDEN)\r\n                {\r\n                    AICLI_LOG(CLI, Error, << \"Getting MSStore package license failed. The Microsoft Entra Id account does not have privilege.\");\r\n                    THROW_HR(APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED_FORBIDDEN);\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(CLI, Error, << \"Getting MSStore package license failed. Error code: \" << re.GetErrorCode());\r\n                    THROW_HR(re.GetErrorCode());\r\n                }\r\n            }\r\n\r\n            if (!licensingResponseObject || licensingResponseObject->is_null())\r\n            {\r\n                AICLI_LOG(Core, Error, << \"Empty licensing response\");\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED);\r\n            }\r\n\r\n            std::optional<std::reference_wrapper<const web::json::value>> license = JSON::GetJsonValueFromNode(licensingResponseObject.value(), JSON::GetUtilityString(License));\r\n            if (!license)\r\n            {\r\n                AICLI_LOG(Core, Error, << \"Missing license node\");\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED);\r\n            }\r\n\r\n            auto keys = JSON::GetRawJsonArrayFromJsonNode(license.value().get(), JSON::GetUtilityString(Keys));\r\n            if (!keys || keys->get().size() == 0)\r\n            {\r\n                AICLI_LOG(Core, Error, << \"Missing keys or empty keys\");\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED);\r\n            }\r\n\r\n            std::string base64LicenseContent = JSON::GetRawStringValueFromJsonNode(keys->get().at(0), JSON::GetUtilityString(Value)).value_or(\"\");\r\n            if (base64LicenseContent.empty())\r\n            {\r\n                AICLI_LOG(Core, Error, << \"Missing license content\");\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED);\r\n            }\r\n\r\n            return JSON::Base64Decode(base64LicenseContent);\r\n        }\r\n    }\r\n\r\n    namespace\r\n    {\r\n        Http::HttpClientHelper::HttpRequestHeaders GetAuthHeaders(std::unique_ptr<Authentication::Authenticator>& authenticator)\r\n        {\r\n            if (!authenticator)\r\n            {\r\n                return {};\r\n            }\r\n\r\n            Http::HttpClientHelper::HttpRequestHeaders result;\r\n\r\n            auto authResult = authenticator->AuthenticateForToken();\r\n            if (FAILED(authResult.Status))\r\n            {\r\n                AICLI_LOG(Repo, Error, << \"Authentication failed. Result: \" << authResult.Status);\r\n                THROW_HR_MSG(authResult.Status, \"Failed to authenticate for MicrosoftEntraId\");\r\n            }\r\n            result.insert_or_assign(web::http::header_names::authorization, JSON::GetUtilityString(Authentication::CreateBearerToken(authResult.Token)));\r\n\r\n            return result;\r\n        }\r\n    }\r\n\r\n    MSStoreDownloadContext::MSStoreDownloadContext(\r\n        std::string productId,\r\n        AppInstaller::Utility::Architecture architecture,\r\n        Manifest::PlatformEnum platform,\r\n        std::string locale,\r\n        AppInstaller::Authentication::AuthenticationArguments authArgs) :\r\n        m_productId(std::move(productId)), m_architecture(architecture), m_platform(platform), m_locale(std::move(locale))\r\n    {\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        if (!TestHooks::s_DisplayCatalog_HttpPipelineStage_Override)\r\n#endif\r\n        {\r\n            Authentication::MicrosoftEntraIdAuthenticationInfo displayCatalogMicrosoftEntraIdAuthInfo;\r\n            displayCatalogMicrosoftEntraIdAuthInfo.Resource = \"https://bigcatalog.commerce.microsoft.com\";\r\n            Authentication::AuthenticationInfo displayCatalogAuthInfo;\r\n            displayCatalogAuthInfo.Type = Authentication::AuthenticationType::MicrosoftEntraId;\r\n            displayCatalogAuthInfo.MicrosoftEntraIdInfo = std::move(displayCatalogMicrosoftEntraIdAuthInfo);\r\n\r\n            m_displayCatalogAuthenticator = std::make_unique<Authentication::Authenticator>(std::move(displayCatalogAuthInfo), authArgs);\r\n        }\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        if (!TestHooks::s_Licensing_HttpPipelineStage_Override)\r\n#endif\r\n        {\r\n            Authentication::MicrosoftEntraIdAuthenticationInfo licensingMicrosoftEntraIdAuthInfo;\r\n            licensingMicrosoftEntraIdAuthInfo.Resource = \"c5e1cb0d-5d24-4b1a-b291-ec684152b2ba\";\r\n            Authentication::AuthenticationInfo licensingAuthInfo;\r\n            licensingAuthInfo.Type = Authentication::AuthenticationType::MicrosoftEntraId;\r\n            licensingAuthInfo.MicrosoftEntraIdInfo = std::move(licensingMicrosoftEntraIdAuthInfo);\r\n\r\n            m_licensingAuthenticator = std::make_unique<Authentication::Authenticator>(std::move(licensingAuthInfo), authArgs);\r\n        }\r\n    }\r\n\r\n    void MSStoreDownloadContext::TargetOSVersion(std::optional<Utility::UInt64Version> targetOSVersion)\r\n    {\r\n        m_targetOSVersion = std::move(targetOSVersion);\r\n    }\r\n\r\n    MSStoreDownloadInfo MSStoreDownloadContext::GetDownloadInfo()\r\n    {\r\n#ifndef WINGET_DISABLE_FOR_FUZZING\r\n        auto displayCatalogPackage = DisplayCatalogDetails::CallDisplayCatalogAndGetPreferredPackage(m_productId, m_locale, m_architecture, GetAuthHeaders(m_displayCatalogAuthenticator));\r\n        auto downloadInfo = SfsClientDetails::CallSfsClientAndGetMSStoreDownloadInfo(displayCatalogPackage.WuCategoryId, m_architecture, m_platform, m_targetOSVersion);\r\n        downloadInfo.ContentId = displayCatalogPackage.ContentId;\r\n        return downloadInfo;\r\n#else\r\n        return {};\r\n#endif\r\n    }\r\n\r\n    std::vector<BYTE> MSStoreDownloadContext::GetLicense(std::string_view contentId)\r\n    {\r\n        return LicensingDetails::GetLicensing(contentId, GetAuthHeaders(m_licensingAuthenticator));\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Manifest/Manifest.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"winget/Manifest.h\"\r\n#include \"winget/Locale.h\"\r\n#include \"winget/UserSettings.h\"\r\n\r\nnamespace AppInstaller::Manifest\r\n{\r\n    namespace\r\n    {\r\n        void AddFoldedStringToSetIfNotEmpty(std::set<string_t>& set, const string_t& value)\r\n        {\r\n            if (!value.empty())\r\n            {\r\n                set.emplace(Utility::FoldCase(value));\r\n            }\r\n        }\r\n    }\r\n\r\n    void Manifest::ApplyLocale(const std::string& locale)\r\n    {\r\n        CurrentLocalization = DefaultLocalization;\r\n\r\n        // Get target locale from Preferred Languages settings if applicable\r\n        std::vector<std::string> targetLocales;\r\n        if (locale.empty())\r\n        {\r\n            targetLocales = Locale::GetUserPreferredLanguages();\r\n        }\r\n        else\r\n        {\r\n            targetLocales.emplace_back(locale);\r\n        }\r\n\r\n        for (auto const& targetLocale : targetLocales)\r\n        {\r\n            const ManifestLocalization* bestLocalization = nullptr;\r\n            double bestScore = Locale::GetDistanceOfLanguage(targetLocale, DefaultLocalization.Locale);\r\n\r\n            for (auto const& localization : Localizations)\r\n            {\r\n                double score = Locale::GetDistanceOfLanguage(targetLocale, localization.Locale);\r\n                if (score > bestScore)\r\n                {\r\n                    bestLocalization = &localization;\r\n                    bestScore = score;\r\n                }\r\n            }\r\n\r\n            // If there's better locale than default And is compatible with target locale, merge and return;\r\n            if (bestScore >= Locale::MinimumDistanceScoreAsCompatibleMatch)\r\n            {\r\n                if (bestLocalization != nullptr)\r\n                {\r\n                    CurrentLocalization.ReplaceOrMergeWith(*bestLocalization);\r\n                }\r\n                break;\r\n            }\r\n        }\r\n    }\r\n\r\n    std::vector<string_t> Manifest::GetAggregatedTags() const\r\n    {\r\n        std::vector<string_t> resultTags = DefaultLocalization.Get<Localization::Tags>();\r\n\r\n        for (const auto& locale : Localizations)\r\n        {\r\n            auto tags = locale.Get<Localization::Tags>();\r\n            for (const auto& tag : tags)\r\n            {\r\n                if (std::find(resultTags.begin(), resultTags.end(), tag) == resultTags.end())\r\n                {\r\n                    resultTags.emplace_back(tag);\r\n                }\r\n            }\r\n        }\r\n\r\n        return resultTags;\r\n    }\r\n\r\n    std::vector<string_t> Manifest::GetAggregatedCommands() const\r\n    {\r\n        std::vector<string_t> resultCommands;\r\n\r\n        for (const auto& installer : Installers)\r\n        {\r\n            for (const auto& command : installer.Commands)\r\n            {\r\n                if (std::find(resultCommands.begin(), resultCommands.end(), command) == resultCommands.end())\r\n                {\r\n                    resultCommands.emplace_back(command);\r\n                }\r\n            }\r\n        }\r\n\r\n        return resultCommands;\r\n    }\r\n\r\n    Utility::VersionRange Manifest::GetArpVersionRange() const\r\n    {\r\n        bool arpVersionFound = false;\r\n        Utility::Version minVersion;\r\n        Utility::Version maxVersion;\r\n\r\n        for (auto const& installer : Installers)\r\n        {\r\n            if (DoesInstallerTypeSupportArpVersionRange(installer.EffectiveInstallerType()))\r\n            {\r\n                for (auto const& entry : installer.AppsAndFeaturesEntries)\r\n                {\r\n                    if (!entry.DisplayVersion.empty())\r\n                    {\r\n                        Utility::Version arpVersion{ entry.DisplayVersion };\r\n\r\n                        if (!arpVersionFound)\r\n                        {\r\n                            // This is the first arp version found, populate both min and max version\r\n                            minVersion = arpVersion;\r\n                            maxVersion = arpVersion;\r\n                            arpVersionFound = true;\r\n                            continue;\r\n                        }\r\n\r\n                        if (arpVersion < minVersion)\r\n                        {\r\n                            minVersion = arpVersion;\r\n                        }\r\n                        else if (arpVersion > maxVersion)\r\n                        {\r\n                            maxVersion = arpVersion;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        return arpVersionFound ? Utility::VersionRange{ minVersion, maxVersion } : Utility::VersionRange{};\r\n    }\r\n\r\n    std::vector<string_t> Manifest::GetPackageFamilyNames() const\r\n    {\r\n        return GetSystemReferenceStrings(\r\n            [](const ManifestInstaller& i) -> const Utility::NormalizedString& { return i.PackageFamilyName; });\r\n    }\r\n\r\n    std::vector<string_t> Manifest::GetProductCodes() const\r\n    {\r\n        return GetSystemReferenceStrings(\r\n            [](const ManifestInstaller& i) -> const Utility::NormalizedString& { return i.ProductCode; },\r\n            [](const AppsAndFeaturesEntry& e) -> const Utility::NormalizedString& { return e.ProductCode; });\r\n    }\r\n\r\n    std::vector<string_t> Manifest::GetUpgradeCodes() const\r\n    {\r\n        return GetSystemReferenceStrings(\r\n            {},\r\n            [](const AppsAndFeaturesEntry& e) -> const Utility::NormalizedString& { return e.UpgradeCode; });\r\n    }\r\n\r\n    std::vector<string_t> Manifest::GetPackageNames() const\r\n    {\r\n        std::set<string_t> set;\r\n\r\n        AddFoldedStringToSetIfNotEmpty(set, DefaultLocalization.Get<Localization::PackageName>());\r\n        for (const auto& loc : Localizations)\r\n        {\r\n            AddFoldedStringToSetIfNotEmpty(set, loc.Get<Localization::PackageName>());\r\n        }\r\n\r\n        // In addition to the names used for our display, add the display names from the ARP entries\r\n        for (const auto& installer : Installers)\r\n        {\r\n            for (const auto& appsAndFeaturesEntry : installer.AppsAndFeaturesEntries)\r\n            {\r\n                AddFoldedStringToSetIfNotEmpty(set, appsAndFeaturesEntry.DisplayName);\r\n            }\r\n        }\r\n\r\n        std::vector<Utility::NormalizedString> result(\r\n            std::make_move_iterator(set.begin()),\r\n            std::make_move_iterator(set.end()));\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<string_t> Manifest::GetPublishers() const\r\n    {\r\n        std::set<string_t> set;\r\n\r\n        AddFoldedStringToSetIfNotEmpty(set, DefaultLocalization.Get<Localization::Publisher>());\r\n        for (const auto& loc : Localizations)\r\n        {\r\n            AddFoldedStringToSetIfNotEmpty(set, loc.Get<Localization::Publisher>());\r\n        }\r\n\r\n        // In addition to the publishers used for our display, add the publisher from the ARP entries\r\n        for (const auto& installer : Installers)\r\n        {\r\n            for (const auto& appsAndFeaturesEntry : installer.AppsAndFeaturesEntries)\r\n            {\r\n                AddFoldedStringToSetIfNotEmpty(set, appsAndFeaturesEntry.Publisher);\r\n            }\r\n        }\r\n\r\n        std::vector<Utility::NormalizedString> result(\r\n            std::make_move_iterator(set.begin()),\r\n            std::make_move_iterator(set.end()));\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<string_t> Manifest::GetSystemReferenceStrings(\r\n        std::function<const string_t& (const ManifestInstaller&)> extractStringFromInstaller,\r\n        std::function<const string_t& (const AppsAndFeaturesEntry&)> extractStringFromAppsAndFeaturesEntry) const\r\n    {\r\n        std::set<string_t> set;\r\n\r\n        for (const auto& installer : Installers)\r\n        {\r\n            if (extractStringFromInstaller)\r\n            {\r\n                const auto& installerString = extractStringFromInstaller(installer);\r\n                AddFoldedStringToSetIfNotEmpty(set, installerString);\r\n            }\r\n\r\n            if (extractStringFromAppsAndFeaturesEntry)\r\n            {\r\n                for (const auto& entry : installer.AppsAndFeaturesEntries)\r\n                {\r\n                    const auto& entryString = extractStringFromAppsAndFeaturesEntry(entry);\r\n                    AddFoldedStringToSetIfNotEmpty(set, entryString);\r\n                }\r\n            }\r\n        }\r\n\r\n        std::vector<Utility::NormalizedString> result(\r\n            std::make_move_iterator(set.begin()),\r\n            std::make_move_iterator(set.end()));\r\n\r\n        return result;\r\n    }\r\n}"
  },
  {
    "path": "src/AppInstallerCommonCore/Manifest/ManifestCommon.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"winget/ManifestCommon.h\"\r\n#include \"winget/ManifestValidation.h\"\r\n\r\nnamespace AppInstaller::Manifest\r\n{\r\n    namespace\r\n    {\r\n        enum class CompatibilitySet\r\n        {\r\n            None,\r\n            Exe,\r\n            Msi,\r\n            Msix,\r\n        };\r\n\r\n        CompatibilitySet GetCompatibilitySet(InstallerTypeEnum type)\r\n        {\r\n            switch (type)\r\n            {\r\n            case InstallerTypeEnum::Inno:\r\n            case InstallerTypeEnum::Nullsoft:\r\n            case InstallerTypeEnum::Exe:\r\n            case InstallerTypeEnum::Burn:\r\n                return CompatibilitySet::Exe;\r\n            case InstallerTypeEnum::Wix:\r\n            case InstallerTypeEnum::Msi:\r\n                return CompatibilitySet::Msi;\r\n            case InstallerTypeEnum::Msix:\r\n            case InstallerTypeEnum::MSStore:\r\n                return CompatibilitySet::Msix;\r\n            default:\r\n                return CompatibilitySet::None;\r\n            }\r\n        }\r\n    }\r\n\r\n    ManifestVer::ManifestVer(std::string_view version)\r\n    {\r\n        bool validationSuccess = true;\r\n\r\n        // Separate the extensions out\r\n        size_t hyphenPos = version.find_first_of('-');\r\n        if (hyphenPos != std::string_view::npos)\r\n        {\r\n            // The first part is the main version\r\n            Assign(std::string{ version.substr(0, hyphenPos) }, \".\");\r\n\r\n            // The second part is the extensions\r\n            hyphenPos += 1;\r\n            while (hyphenPos < version.length())\r\n            {\r\n                size_t newPos = version.find_first_of('-', hyphenPos);\r\n\r\n                size_t length = (newPos == std::string::npos ? version.length() : newPos) - hyphenPos;\r\n                m_extensions.emplace_back(std::string{ version.substr(hyphenPos, length) }, \".\");\r\n\r\n                hyphenPos += length + 1;\r\n            }\r\n        }\r\n        else\r\n        {\r\n            Assign(std::string{ version }, \".\");\r\n        }\r\n\r\n        if (m_parts.size() > 3)\r\n        {\r\n            validationSuccess = false;\r\n        }\r\n        else\r\n        {\r\n            for (size_t i = 0; i < m_parts.size(); i++)\r\n            {\r\n                if (!m_parts[i].Other.empty())\r\n                {\r\n                    validationSuccess = false;\r\n                    break;\r\n                }\r\n            }\r\n\r\n            for (const RawVersion& ext : m_extensions)\r\n            {\r\n                if (ext.GetParts().empty() || ext.GetParts()[0].Integer != 0)\r\n                {\r\n                    validationSuccess = false;\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n\r\n        if (!validationSuccess)\r\n        {\r\n            std::vector<ValidationError> errors;\r\n            errors.emplace_back(ManifestError::InvalidFieldValue, \"ManifestVersion\", std::string{ version });\r\n            THROW_EXCEPTION(ManifestException(std::move(errors)));\r\n        }\r\n    }\r\n\r\n    bool ManifestVer::HasExtension() const\r\n    {\r\n        return !m_extensions.empty();\r\n    }\r\n\r\n    bool ManifestVer::HasExtension(std::string_view extension) const\r\n    {\r\n        for (const RawVersion& ext : m_extensions)\r\n        {\r\n            const auto& parts = ext.GetParts();\r\n            if (!parts.empty() && parts[0].Integer == 0 && parts[0].Other == extension)\r\n            {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    InstallerTypeEnum ConvertToInstallerTypeEnum(const std::string& in)\r\n    {\r\n        std::string inStrLower = Utility::ToLower(in);\r\n        InstallerTypeEnum result = InstallerTypeEnum::Unknown;\r\n\r\n        if (inStrLower == \"inno\")\r\n        {\r\n            result = InstallerTypeEnum::Inno;\r\n        }\r\n        else if (inStrLower == \"wix\")\r\n        {\r\n            result = InstallerTypeEnum::Wix;\r\n        }\r\n        else if (inStrLower == \"msi\")\r\n        {\r\n            result = InstallerTypeEnum::Msi;\r\n        }\r\n        else if (inStrLower == \"nullsoft\")\r\n        {\r\n            result = InstallerTypeEnum::Nullsoft;\r\n        }\r\n        else if (inStrLower == \"zip\")\r\n        {\r\n            result = InstallerTypeEnum::Zip;\r\n        }\r\n        else if (inStrLower == \"appx\" || inStrLower == \"msix\")\r\n        {\r\n            result = InstallerTypeEnum::Msix;\r\n        }\r\n        else if (inStrLower == \"exe\")\r\n        {\r\n            result = InstallerTypeEnum::Exe;\r\n        }\r\n        else if (inStrLower == \"burn\")\r\n        {\r\n            result = InstallerTypeEnum::Burn;\r\n        }\r\n        else if (inStrLower == \"msstore\")\r\n        {\r\n            result = InstallerTypeEnum::MSStore;\r\n        }\r\n        else if (inStrLower == \"portable\") \r\n        {\r\n            result = InstallerTypeEnum::Portable;\r\n        }\r\n        else if (inStrLower == \"font\")\r\n        {\r\n            result = InstallerTypeEnum::Font;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    UpdateBehaviorEnum ConvertToUpdateBehaviorEnum(const std::string& in)\r\n    {\r\n        UpdateBehaviorEnum result = UpdateBehaviorEnum::Unknown;\r\n\r\n        if (Utility::CaseInsensitiveEquals(in, \"install\"))\r\n        {\r\n            result = UpdateBehaviorEnum::Install;\r\n        }\r\n        else if (Utility::CaseInsensitiveEquals(in, \"uninstallprevious\"))\r\n        {\r\n            result = UpdateBehaviorEnum::UninstallPrevious;\r\n        }\r\n        else if (Utility::CaseInsensitiveEquals(in, \"deny\"))\r\n        {\r\n            result = UpdateBehaviorEnum::Deny;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    ScopeEnum ConvertToScopeEnum(std::string_view in)\r\n    {\r\n        ScopeEnum result = ScopeEnum::Unknown;\r\n\r\n        if (Utility::CaseInsensitiveEquals(in, \"user\"))\r\n        {\r\n            result = ScopeEnum::User;\r\n        }\r\n        else if (Utility::CaseInsensitiveEquals(in, \"machine\"))\r\n        {\r\n            result = ScopeEnum::Machine;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    InstallModeEnum ConvertToInstallModeEnum(const std::string& in)\r\n    {\r\n        InstallModeEnum result = InstallModeEnum::Unknown;\r\n\r\n        if (Utility::CaseInsensitiveEquals(in, \"interactive\"))\r\n        {\r\n            result = InstallModeEnum::Interactive;\r\n        }\r\n        else if (Utility::CaseInsensitiveEquals(in, \"silent\"))\r\n        {\r\n            result = InstallModeEnum::Silent;\r\n        }\r\n        else if (Utility::CaseInsensitiveEquals(in, \"silentWithProgress\"))\r\n        {\r\n            result = InstallModeEnum::SilentWithProgress;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    PlatformEnum ConvertToPlatformEnum(std::string_view in)\r\n    {\r\n        std::string inStrLower = Utility::ToLower(in);\r\n\r\n        if (inStrLower == \"windows.desktop\")\r\n        {\r\n            return PlatformEnum::Desktop;\r\n        }\r\n        else if (inStrLower == \"windows.universal\")\r\n        {\r\n            return PlatformEnum::Universal;\r\n        }\r\n\r\n        return PlatformEnum::Unknown;\r\n    }\r\n\r\n    PlatformEnum ConvertToPlatformEnumForMSStoreDownload(std::string_view in)\r\n    {\r\n        std::string inStrLower = Utility::ToLower(in);\r\n\r\n        if (inStrLower == \"windows.desktop\")\r\n        {\r\n            return PlatformEnum::Desktop;\r\n        }\r\n        else if (inStrLower == \"windows.universal\")\r\n        {\r\n            return PlatformEnum::Universal;\r\n        }\r\n        else if (inStrLower == \"windows.iot\")\r\n        {\r\n            return PlatformEnum::IoT;\r\n        }\r\n        else if (inStrLower == \"windows.team\")\r\n        {\r\n            return PlatformEnum::Team;\r\n        }\r\n        else if (inStrLower == \"windows.holographic\")\r\n        {\r\n            return PlatformEnum::Holographic;\r\n        }\r\n\r\n        return PlatformEnum::Unknown;\r\n    }\r\n\r\n    ElevationRequirementEnum ConvertToElevationRequirementEnum(const std::string& in)\r\n    {\r\n        ElevationRequirementEnum result = ElevationRequirementEnum::Unknown;\r\n\r\n        if (Utility::CaseInsensitiveEquals(in, \"elevationRequired\"))\r\n        {\r\n            result = ElevationRequirementEnum::ElevationRequired;\r\n        }\r\n        else if (Utility::CaseInsensitiveEquals(in, \"elevationProhibited\"))\r\n        {\r\n            result = ElevationRequirementEnum::ElevationProhibited;\r\n        }\r\n        else if (Utility::CaseInsensitiveEquals(in, \"elevatesSelf\"))\r\n        {\r\n            result = ElevationRequirementEnum::ElevatesSelf;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    UnsupportedArgumentEnum ConvertToUnsupportedArgumentEnum(const std::string& in)\r\n    {\r\n        UnsupportedArgumentEnum result = UnsupportedArgumentEnum::Unknown;\r\n\r\n        if (Utility::CaseInsensitiveEquals(in, \"log\"))\r\n        {\r\n            result = UnsupportedArgumentEnum::Log;\r\n        }\r\n        else if (Utility::CaseInsensitiveEquals(in, \"location\"))\r\n        {\r\n            result = UnsupportedArgumentEnum::Location;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    ManifestTypeEnum ConvertToManifestTypeEnum(const std::string& in)\r\n    {\r\n        if (in == \"singleton\")\r\n        {\r\n            return ManifestTypeEnum::Singleton;\r\n        }\r\n        else if (in == \"version\")\r\n        {\r\n            return ManifestTypeEnum::Version;\r\n        }\r\n        else if (in == \"installer\")\r\n        {\r\n            return ManifestTypeEnum::Installer;\r\n        }\r\n        else if (in == \"defaultLocale\")\r\n        {\r\n            return ManifestTypeEnum::DefaultLocale;\r\n        }\r\n        else if (in == \"locale\")\r\n        {\r\n            return ManifestTypeEnum::Locale;\r\n        }\r\n        else if (in == \"merged\")\r\n        {\r\n            return ManifestTypeEnum::Merged;\r\n        }\r\n        else if (in == \"shadow\")\r\n        {\r\n            return ManifestTypeEnum::Shadow;\r\n        }\r\n        else\r\n        {\r\n            THROW_HR_MSG(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), \"Unsupported ManifestType: %hs\", in.c_str());\r\n        }\r\n    }\r\n\r\n    ExpectedReturnCodeEnum ConvertToExpectedReturnCodeEnum(const std::string& in)\r\n    {\r\n        std::string inStrLower = Utility::ToLower(in);\r\n        ExpectedReturnCodeEnum result = ExpectedReturnCodeEnum::Unknown;\r\n\r\n        if (inStrLower == \"packageinuse\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::PackageInUse;\r\n        }\r\n        else if (inStrLower == \"packageinusebyapplication\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::PackageInUseByApplication;\r\n        }\r\n        else if (inStrLower == \"installinprogress\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::InstallInProgress;\r\n        }\r\n        else if (inStrLower == \"fileinuse\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::FileInUse;\r\n        }\r\n        else if (inStrLower == \"missingdependency\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::MissingDependency;\r\n        }\r\n        else if (inStrLower == \"diskfull\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::DiskFull;\r\n        }\r\n        else if (inStrLower == \"insufficientmemory\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::InsufficientMemory;\r\n        }\r\n        else if (inStrLower == \"invalidparameter\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::InvalidParameter;\r\n        }\r\n        else if (inStrLower == \"nonetwork\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::NoNetwork;\r\n        }\r\n        else if (inStrLower == \"contactsupport\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::ContactSupport;\r\n        }\r\n        else if (inStrLower == \"rebootrequiredtofinish\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::RebootRequiredToFinish;\r\n        }\r\n        else if (inStrLower == \"rebootrequiredforinstall\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::RebootRequiredForInstall;\r\n        }\r\n        else if (inStrLower == \"rebootinitiated\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::RebootInitiated;\r\n        }\r\n        else if (inStrLower == \"cancelledbyuser\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::CancelledByUser;\r\n        }\r\n        else if (inStrLower == \"alreadyinstalled\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::AlreadyInstalled;\r\n        }\r\n        else if (inStrLower == \"downgrade\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::Downgrade;\r\n        }\r\n        else if (inStrLower == \"blockedbypolicy\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::BlockedByPolicy;\r\n        }\r\n        else if (inStrLower == \"systemnotsupported\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::SystemNotSupported;\r\n        }\r\n        else if (inStrLower == \"custom\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::Custom;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    InstalledFileTypeEnum ConvertToInstalledFileTypeEnum(const std::string& in)\r\n    {\r\n        std::string inStrLower = Utility::ToLower(in);\r\n        InstalledFileTypeEnum result = InstalledFileTypeEnum::Unknown;\r\n\r\n        if (inStrLower == \"launch\")\r\n        {\r\n            result = InstalledFileTypeEnum::Launch;\r\n        }\r\n        else if (inStrLower == \"uninstall\")\r\n        {\r\n            result = InstalledFileTypeEnum::Uninstall;\r\n        }\r\n        else if (inStrLower == \"other\")\r\n        {\r\n            result = InstalledFileTypeEnum::Other;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    IconFileTypeEnum ConvertToIconFileTypeEnum(std::string_view in)\r\n    {\r\n        std::string inStrLower = Utility::ToLower(in);\r\n        IconFileTypeEnum result = IconFileTypeEnum::Unknown;\r\n\r\n        if (inStrLower == \"jpeg\")\r\n        {\r\n            result = IconFileTypeEnum::Jpeg;\r\n        }\r\n        else if (inStrLower == \"png\")\r\n        {\r\n            result = IconFileTypeEnum::Png;\r\n        }\r\n        else if (inStrLower == \"ico\")\r\n        {\r\n            result = IconFileTypeEnum::Ico;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    IconThemeEnum ConvertToIconThemeEnum(std::string_view in)\r\n    {\r\n        std::string inStrLower = Utility::ToLower(in);\r\n        IconThemeEnum result = IconThemeEnum::Unknown;\r\n\r\n        if (inStrLower == \"default\")\r\n        {\r\n            result = IconThemeEnum::Default;\r\n        }\r\n        else if (inStrLower == \"dark\")\r\n        {\r\n            result = IconThemeEnum::Dark;\r\n        }\r\n        else if (inStrLower == \"light\")\r\n        {\r\n            result = IconThemeEnum::Light;\r\n        }\r\n        else if (inStrLower == \"highcontrast\")\r\n        {\r\n            result = IconThemeEnum::HighContrast;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    IconResolutionEnum ConvertToIconResolutionEnum(std::string_view in)\r\n    {\r\n        std::string inStrLower = Utility::ToLower(in);\r\n        IconResolutionEnum result = IconResolutionEnum::Unknown;\r\n\r\n        if (inStrLower == \"custom\")\r\n        {\r\n            result = IconResolutionEnum::Custom;\r\n        }\r\n        else if (inStrLower == \"16x16\")\r\n        {\r\n            result = IconResolutionEnum::Square16;\r\n        }\r\n        else if (inStrLower == \"20x20\")\r\n        {\r\n            result = IconResolutionEnum::Square20;\r\n        }\r\n        else if (inStrLower == \"24x24\")\r\n        {\r\n            result = IconResolutionEnum::Square24;\r\n        }\r\n        else if (inStrLower == \"30x30\")\r\n        {\r\n            result = IconResolutionEnum::Square30;\r\n        }\r\n        else if (inStrLower == \"32x32\")\r\n        {\r\n            result = IconResolutionEnum::Square32;\r\n        }\r\n        else if (inStrLower == \"36x36\")\r\n        {\r\n            result = IconResolutionEnum::Square36;\r\n        }\r\n        else if (inStrLower == \"40x40\")\r\n        {\r\n            result = IconResolutionEnum::Square40;\r\n        }\r\n        else if (inStrLower == \"48x48\")\r\n        {\r\n            result = IconResolutionEnum::Square48;\r\n        }\r\n        else if (inStrLower == \"60x60\")\r\n        {\r\n            result = IconResolutionEnum::Square60;\r\n        }\r\n        else if (inStrLower == \"64x64\")\r\n        {\r\n            result = IconResolutionEnum::Square64;\r\n        }\r\n        else if (inStrLower == \"72x72\")\r\n        {\r\n            result = IconResolutionEnum::Square72;\r\n        }\r\n        else if (inStrLower == \"80x80\")\r\n        {\r\n            result = IconResolutionEnum::Square80;\r\n        }\r\n        else if (inStrLower == \"96x96\")\r\n        {\r\n            result = IconResolutionEnum::Square96;\r\n        }\r\n        else if (inStrLower == \"256x256\")\r\n        {\r\n            result = IconResolutionEnum::Square256;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::string_view InstallerTypeToString(InstallerTypeEnum installerType)\r\n    {\r\n        switch (installerType)\r\n        {\r\n        case InstallerTypeEnum::Exe:\r\n            return \"exe\"sv;\r\n        case InstallerTypeEnum::Inno:\r\n            return \"inno\"sv;\r\n        case InstallerTypeEnum::Msi:\r\n            return \"msi\"sv;\r\n        case InstallerTypeEnum::Msix:\r\n            return \"msix\"sv;\r\n        case InstallerTypeEnum::Nullsoft:\r\n            return \"nullsoft\"sv;\r\n        case InstallerTypeEnum::Wix:\r\n            return \"wix\"sv;\r\n        case InstallerTypeEnum::Zip:\r\n            return \"zip\"sv;\r\n        case InstallerTypeEnum::Burn:\r\n            return \"burn\"sv;\r\n        case InstallerTypeEnum::MSStore:\r\n            return \"msstore\"sv;\r\n        case InstallerTypeEnum::Portable:\r\n            return \"portable\"sv;\r\n        case InstallerTypeEnum::Font:\r\n            return \"font\"sv;\r\n        }\r\n\r\n        return \"unknown\"sv;\r\n    }\r\n\r\n    std::string_view InstallerSwitchTypeToString(InstallerSwitchType installerSwitchType)\r\n    {\r\n        switch (installerSwitchType)\r\n        {\r\n        case InstallerSwitchType::Custom:\r\n            return \"Custom\"sv;\r\n        case InstallerSwitchType::Silent:\r\n            return \"Silent\"sv;\r\n        case InstallerSwitchType::SilentWithProgress:\r\n            return \"SilentWithProgress\"sv;\r\n        case InstallerSwitchType::Interactive:\r\n            return \"Interactive\"sv;\r\n        case InstallerSwitchType::Language:\r\n            return \"Language\"sv;\r\n        case InstallerSwitchType::Log:\r\n            return \"Log\"sv;\r\n        case InstallerSwitchType::InstallLocation:\r\n            return \"InstallLocation\"sv;\r\n        case InstallerSwitchType::Update:\r\n            return \"Upgrade\"sv;\r\n        case InstallerSwitchType::Repair:\r\n            return \"Repair\"sv;\r\n        }\r\n\r\n        return \"Unknown\"sv;\r\n    }\r\n\r\n    std::string_view ElevationRequirementToString(ElevationRequirementEnum elevationRequirement)\r\n    {\r\n        switch (elevationRequirement)\r\n        {\r\n        case ElevationRequirementEnum::ElevationRequired:\r\n            return \"elevationRequired\"sv;\r\n        case ElevationRequirementEnum::ElevationProhibited:\r\n            return \"elevationProhibited\"sv;\r\n        case ElevationRequirementEnum::ElevatesSelf:\r\n            return \"elevatesSelf\"sv;\r\n        }\r\n\r\n        return \"unknown\"sv;\r\n    }\r\n\r\n    std::string_view UnsupportedArgumentToString(UnsupportedArgumentEnum unsupportedArgument)\r\n    {\r\n        switch (unsupportedArgument)\r\n        {\r\n        case UnsupportedArgumentEnum::Log:\r\n            return \"log\"sv;\r\n        case UnsupportedArgumentEnum::Location:\r\n            return \"location\"sv;\r\n        }\r\n\r\n        return \"unknown\"sv;\r\n    }\r\n\r\n    std::string_view InstallModeToString(InstallModeEnum installMode)\r\n    {\r\n        switch (installMode)\r\n        {\r\n        case InstallModeEnum::Interactive:\r\n            return \"interactive\"sv;\r\n        case InstallModeEnum::Silent:\r\n            return \"silent\"sv;\r\n        case InstallModeEnum::SilentWithProgress:\r\n            return \"silentWithProgress\"sv;\r\n        }\r\n\r\n        return \"unknown\"sv;\r\n    }\r\n\r\n    std::string_view PlatformToString(PlatformEnum platform, bool shortString)\r\n    {\r\n        switch (platform)\r\n        {\r\n        case PlatformEnum::Desktop:\r\n            return shortString ? \"Desktop\" : \"Windows.Desktop\"sv;\r\n        case PlatformEnum::Universal:\r\n            return shortString ? \"Universal\" : \"Windows.Universal\"sv;\r\n        case PlatformEnum::IoT:\r\n            return shortString ? \"IoT\" : \"Windows.IoT\"sv;\r\n        case PlatformEnum::Holographic:\r\n            return shortString ? \"Holographic\" : \"Windows.Holographic\"sv;\r\n        case PlatformEnum::Team:\r\n            return shortString ? \"Team\" : \"Windows.Team\"sv;\r\n        }\r\n\r\n        return \"Unknown\"sv;\r\n    }\r\n\r\n    std::string_view UpdateBehaviorToString(UpdateBehaviorEnum updateBehavior)\r\n    {\r\n        switch (updateBehavior)\r\n        {\r\n        case UpdateBehaviorEnum::Install:\r\n            return \"install\"sv;\r\n        case UpdateBehaviorEnum::UninstallPrevious:\r\n            return \"uninstallPrevious\"sv;\r\n        case UpdateBehaviorEnum::Deny:\r\n            return \"deny\"sv;\r\n        }\r\n\r\n        return \"unknown\"sv;\r\n    }\r\n\r\n    std::string_view RepairBehaviorToString(RepairBehaviorEnum repairBehavior)\r\n    {\r\n        switch (repairBehavior)\r\n        {\r\n        case AppInstaller::Manifest::RepairBehaviorEnum::Modify:\r\n            return \"modify\"sv;\r\n        case AppInstaller::Manifest::RepairBehaviorEnum::Installer:\r\n            return \"installer\"sv;\r\n        case AppInstaller::Manifest::RepairBehaviorEnum::Uninstaller:\r\n            return \"uninstaller\"sv;\r\n        }\r\n\r\n        return \"unknown\"sv;\r\n    }\r\n\r\n    std::string_view ScopeToString(ScopeEnum scope)\r\n    {\r\n        switch (scope)\r\n        {\r\n        case ScopeEnum::User:\r\n            return \"User\"sv;\r\n        case ScopeEnum::Machine:\r\n            return \"Machine\"sv;\r\n        }\r\n\r\n        return \"Unknown\"sv;\r\n    }\r\n\r\n    std::string_view InstalledFileTypeToString(InstalledFileTypeEnum installedFileType)\r\n    {\r\n        switch (installedFileType)\r\n        {\r\n        case InstalledFileTypeEnum::Launch:\r\n            return \"launch\"sv;\r\n        case InstalledFileTypeEnum::Uninstall:\r\n            return \"uninstall\"sv;\r\n        case InstalledFileTypeEnum::Other:\r\n            return \"other\"sv;\r\n        }\r\n\r\n        return \"unknown\"sv;\r\n    }\r\n\r\n    std::string_view IconFileTypeToString(IconFileTypeEnum iconFileType)\r\n    {\r\n        switch (iconFileType)\r\n        {\r\n        case IconFileTypeEnum::Ico:\r\n            return \"ico\"sv;\r\n        case IconFileTypeEnum::Jpeg:\r\n            return \"jpeg\"sv;\r\n        case IconFileTypeEnum::Png:\r\n            return \"png\"sv;\r\n        }\r\n\r\n        return \"unknown\"sv;\r\n    }\r\n\r\n    std::string_view IconThemeToString(IconThemeEnum iconTheme)\r\n    {\r\n        switch (iconTheme)\r\n        {\r\n        case IconThemeEnum::Default:\r\n            return \"default\"sv;\r\n        case IconThemeEnum::Dark:\r\n            return \"dark\"sv;\r\n        case IconThemeEnum::Light:\r\n            return \"light\"sv;\r\n        case IconThemeEnum::HighContrast:\r\n            return \"highContrast\"sv;\r\n        }\r\n\r\n        return \"unknown\"sv;\r\n    }\r\n\r\n    std::string_view IconResolutionToString(IconResolutionEnum iconResolution)\r\n    {\r\n        switch (iconResolution)\r\n        {\r\n        case IconResolutionEnum::Custom:\r\n            return \"custom\"sv;\r\n        case IconResolutionEnum::Square16:\r\n            return \"16x16\"sv;\r\n        case IconResolutionEnum::Square20:\r\n            return \"20x20\"sv;\r\n        case IconResolutionEnum::Square24:\r\n            return \"24x24\"sv;\r\n        case IconResolutionEnum::Square30:\r\n            return \"30x30\"sv;\r\n        case IconResolutionEnum::Square32:\r\n            return \"32x32\"sv;\r\n        case IconResolutionEnum::Square36:\r\n            return \"36x36\"sv;\r\n        case IconResolutionEnum::Square40:\r\n            return \"40x40\"sv;\r\n        case IconResolutionEnum::Square48:\r\n            return \"48x48\"sv;\r\n        case IconResolutionEnum::Square60:\r\n            return \"60x60\"sv;\r\n        case IconResolutionEnum::Square64:\r\n            return \"64x64\"sv;\r\n        case IconResolutionEnum::Square72:\r\n            return \"72x72\"sv;\r\n        case IconResolutionEnum::Square80:\r\n            return \"80x80\"sv;\r\n        case IconResolutionEnum::Square96:\r\n            return \"96x96\"sv;\r\n        case IconResolutionEnum::Square256:\r\n            return \"256x256\"sv;\r\n        }\r\n\r\n        return \"unknown\"sv;\r\n    }\r\n\r\n    std::string_view ExpectedReturnCodeToString(ExpectedReturnCodeEnum expectedReturnCode)\r\n    {\r\n        switch (expectedReturnCode)\r\n        {\r\n        case ExpectedReturnCodeEnum::AlreadyInstalled:\r\n            return \"alreadyInstalled\"sv;\r\n        case ExpectedReturnCodeEnum::PackageInUse:\r\n            return \"packageInUse\"sv;\r\n        case ExpectedReturnCodeEnum::PackageInUseByApplication:\r\n            return \"packageInUseByApplication\"sv;\r\n        case ExpectedReturnCodeEnum::InstallInProgress:\r\n            return \"installInProgress\"sv;\r\n        case ExpectedReturnCodeEnum::FileInUse:\r\n            return \"fileInUse\"sv;\r\n        case ExpectedReturnCodeEnum::MissingDependency:\r\n            return \"missingDependency\"sv;\r\n        case ExpectedReturnCodeEnum::DiskFull:\r\n            return \"diskFull\"sv;\r\n        case ExpectedReturnCodeEnum::InsufficientMemory:\r\n            return \"insufficientMemory\"sv;\r\n        case ExpectedReturnCodeEnum::InvalidParameter:\r\n            return \"invalidParameter\"sv;\r\n        case ExpectedReturnCodeEnum::NoNetwork:\r\n            return \"noNetwork\"sv;\r\n        case ExpectedReturnCodeEnum::ContactSupport:\r\n            return \"contactSupport\"sv;\r\n        case ExpectedReturnCodeEnum::RebootRequiredToFinish:\r\n            return \"rebootRequiredToFinish\"sv;\r\n        case ExpectedReturnCodeEnum::RebootRequiredForInstall:\r\n            return \"rebootRequiredForInstall\"sv;\r\n        case ExpectedReturnCodeEnum::RebootInitiated:\r\n            return \"rebootInitiated\"sv;\r\n        case ExpectedReturnCodeEnum::CancelledByUser:\r\n            return \"cancelledByUser\"sv;\r\n        case ExpectedReturnCodeEnum::Downgrade:\r\n            return \"downgrade\"sv;\r\n        case ExpectedReturnCodeEnum::BlockedByPolicy:\r\n            return \"blockedByPolicy\"sv;\r\n        case ExpectedReturnCodeEnum::SystemNotSupported:\r\n            return \"systemNotSupported\"sv;\r\n        case ExpectedReturnCodeEnum::Custom:\r\n            return \"custom\"sv;\r\n        }\r\n\r\n        return \"unknown\"sv;\r\n    }\r\n\r\n    std::string_view ManifestTypeToString(ManifestTypeEnum manifestType)\r\n    {\r\n        switch (manifestType)\r\n        {\r\n        case ManifestTypeEnum::DefaultLocale:\r\n            return \"defaultLocale\"sv;\r\n        case ManifestTypeEnum::Installer:\r\n            return \"installer\"sv;\r\n        case ManifestTypeEnum::Locale:\r\n            return \"locale\"sv;\r\n        case ManifestTypeEnum::Merged:\r\n            return \"merged\"sv;\r\n        case ManifestTypeEnum::Singleton:\r\n            return \"singleton\"sv;\r\n        case ManifestTypeEnum::Version:\r\n            return \"version\"sv;\r\n        }\r\n\r\n        return \"unknown\"sv;\r\n    }\r\n\r\n    bool DoesInstallerTypeUsePackageFamilyName(InstallerTypeEnum installerType)\r\n    {\r\n        return (installerType == InstallerTypeEnum::Msix || installerType == InstallerTypeEnum::MSStore);\r\n    }\r\n\r\n    bool DoAnyAppsAndFeaturesEntriesUsePackageFamilyName(const std::vector<AppsAndFeaturesEntry>& entries)\r\n    {\r\n        for (const AppsAndFeaturesEntry& entry : entries)\r\n        {\r\n            if (DoesInstallerTypeUsePackageFamilyName(entry.InstallerType))\r\n            {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    bool DoesInstallerTypeUseProductCode(InstallerTypeEnum installerType)\r\n    {\r\n        return (\r\n            installerType == InstallerTypeEnum::Exe ||\r\n            installerType == InstallerTypeEnum::Inno ||\r\n            installerType == InstallerTypeEnum::Msi ||\r\n            installerType == InstallerTypeEnum::Nullsoft ||\r\n            installerType == InstallerTypeEnum::Wix ||\r\n            installerType == InstallerTypeEnum::Burn ||\r\n            installerType == InstallerTypeEnum::Portable\r\n            );\r\n    }\r\n\r\n    bool DoesInstallerTypeWriteAppsAndFeaturesEntry(InstallerTypeEnum installerType)\r\n    {\r\n        return (\r\n            installerType == InstallerTypeEnum::Exe ||\r\n            installerType == InstallerTypeEnum::Inno ||\r\n            installerType == InstallerTypeEnum::Msi ||\r\n            installerType == InstallerTypeEnum::Nullsoft ||\r\n            installerType == InstallerTypeEnum::Wix ||\r\n            installerType == InstallerTypeEnum::Burn ||\r\n            installerType == InstallerTypeEnum::Portable\r\n            );\r\n    }\r\n\r\n    bool DoesInstallerTypeSupportArpVersionRange(InstallerTypeEnum installerType)\r\n    {\r\n        return (\r\n            installerType == InstallerTypeEnum::Exe ||\r\n            installerType == InstallerTypeEnum::Inno ||\r\n            installerType == InstallerTypeEnum::Msi ||\r\n            installerType == InstallerTypeEnum::Nullsoft ||\r\n            installerType == InstallerTypeEnum::Wix ||\r\n            installerType == InstallerTypeEnum::Burn ||\r\n            installerType == InstallerTypeEnum::Msix\r\n            );\r\n    }\r\n\r\n    bool DoesInstallerTypeIgnoreScopeFromManifest(InstallerTypeEnum installerType)\r\n    {\r\n        return\r\n            installerType == InstallerTypeEnum::Font ||\r\n            installerType == InstallerTypeEnum::Portable ||\r\n            installerType == InstallerTypeEnum::Msix ||\r\n            installerType == InstallerTypeEnum::MSStore;\r\n    }\r\n\r\n    bool DoesInstallerTypeRequireAdminForMachineScopeInstall(InstallerTypeEnum installerType)\r\n    {\r\n        return\r\n            installerType == InstallerTypeEnum::Font ||\r\n            installerType == InstallerTypeEnum::Portable ||\r\n            installerType == InstallerTypeEnum::MSStore ||\r\n            installerType == InstallerTypeEnum::Msix;\r\n    }\r\n\r\n    bool DoesInstallerTypeRequireRepairBehaviorForRepair(InstallerTypeEnum installerType)\r\n    {\r\n        return\r\n            installerType == InstallerTypeEnum::Burn ||\r\n            installerType == InstallerTypeEnum::Inno ||\r\n            installerType == InstallerTypeEnum::Nullsoft ||\r\n            installerType == InstallerTypeEnum::Exe;\r\n    }\r\n\r\n    bool IsArchiveType(InstallerTypeEnum installerType)\r\n    {\r\n        return (installerType == InstallerTypeEnum::Zip);\r\n    }\r\n\r\n    bool IsPortableType(InstallerTypeEnum installerType)\r\n    {\r\n        return (installerType == InstallerTypeEnum::Portable);\r\n    }\r\n\r\n    bool DoesInstallerTypeSupportMultipleNestedInstallers(InstallerTypeEnum installerType)\r\n    {\r\n        return (\r\n            installerType == InstallerTypeEnum::Portable ||\r\n            installerType == InstallerTypeEnum::Font\r\n            );\r\n    }\r\n\r\n    bool IsNestedInstallerTypeSupported(InstallerTypeEnum nestedInstallerType)\r\n    {\r\n        return (\r\n            nestedInstallerType == InstallerTypeEnum::Exe ||\r\n            nestedInstallerType == InstallerTypeEnum::Inno ||\r\n            nestedInstallerType == InstallerTypeEnum::Msi ||\r\n            nestedInstallerType == InstallerTypeEnum::Nullsoft ||\r\n            nestedInstallerType == InstallerTypeEnum::Wix ||\r\n            nestedInstallerType == InstallerTypeEnum::Burn ||\r\n            nestedInstallerType == InstallerTypeEnum::Portable ||\r\n            nestedInstallerType == InstallerTypeEnum::Msix ||\r\n            nestedInstallerType == InstallerTypeEnum::Font\r\n            );\r\n    }\r\n\r\n    bool IsInstallerTypeCompatible(InstallerTypeEnum type1, InstallerTypeEnum type2)\r\n    {\r\n        // Unknown type cannot be compatible with any other\r\n        if (type1 == InstallerTypeEnum::Unknown || type2 == InstallerTypeEnum::Unknown)\r\n        {\r\n            return false;\r\n        }\r\n\r\n        // Not unknown, so must be compatible\r\n        if (type1 == type2)\r\n        {\r\n            return true;\r\n        }\r\n\r\n        CompatibilitySet set1 = GetCompatibilitySet(type1);\r\n        CompatibilitySet set2 = GetCompatibilitySet(type2);\r\n\r\n        // If either is none, they can't be compatible\r\n        if (set1 == CompatibilitySet::None || set2 == CompatibilitySet::None)\r\n        {\r\n            return false;\r\n        }\r\n\r\n        return set1 == set2;\r\n    }\r\n\r\n    std::map<InstallerSwitchType, Utility::NormalizedString> GetDefaultKnownSwitches(InstallerTypeEnum installerType)\r\n    {\r\n        switch (installerType)\r\n        {\r\n        case InstallerTypeEnum::Burn:\r\n        case InstallerTypeEnum::Wix:\r\n        case InstallerTypeEnum::Msi:\r\n            return\r\n            {\r\n                {InstallerSwitchType::Silent, ManifestInstaller::string_t(\"/quiet /norestart\")},\r\n                {InstallerSwitchType::SilentWithProgress, ManifestInstaller::string_t(\"/passive /norestart\")},\r\n                {InstallerSwitchType::Log, ManifestInstaller::string_t(\"/log \\\"\" + std::string(ARG_TOKEN_LOGPATH) + \"\\\"\")},\r\n                {InstallerSwitchType::InstallLocation, ManifestInstaller::string_t(\"TARGETDIR=\\\"\" + std::string(ARG_TOKEN_INSTALLPATH) + \"\\\"\")}\r\n            };\r\n        case InstallerTypeEnum::Nullsoft:\r\n            return\r\n            {\r\n                {InstallerSwitchType::Silent, ManifestInstaller::string_t(\"/S\")},\r\n                {InstallerSwitchType::SilentWithProgress, ManifestInstaller::string_t(\"/S\")},\r\n                {InstallerSwitchType::InstallLocation, ManifestInstaller::string_t(\"/D=\" + std::string(ARG_TOKEN_INSTALLPATH))}\r\n            };\r\n        case InstallerTypeEnum::Inno:\r\n            return\r\n            {\r\n                {InstallerSwitchType::Silent, ManifestInstaller::string_t(\"/SP- /VERYSILENT /SUPPRESSMSGBOXES /NORESTART\")},\r\n                {InstallerSwitchType::SilentWithProgress, ManifestInstaller::string_t(\"/SP- /SILENT /SUPPRESSMSGBOXES /NORESTART\")},\r\n                {InstallerSwitchType::Log, ManifestInstaller::string_t(\"/LOG=\\\"\" + std::string(ARG_TOKEN_LOGPATH) + \"\\\"\")},\r\n                {InstallerSwitchType::InstallLocation, ManifestInstaller::string_t(\"/DIR=\\\"\" + std::string(ARG_TOKEN_INSTALLPATH) + \"\\\"\")}\r\n            };\r\n        default:\r\n            return {};\r\n        }\r\n    }\r\n\r\n    RepairBehaviorEnum ConvertToRepairBehaviorEnum(std::string_view in)\r\n    {\r\n        std::string inStrLower = Utility::ToLower(in);\r\n        RepairBehaviorEnum result = RepairBehaviorEnum::Unknown;\r\n\r\n        if (inStrLower == \"installer\")\r\n        {\r\n            result = RepairBehaviorEnum::Installer;\r\n        }\r\n        else if (inStrLower == \"uninstaller\")\r\n        {\r\n            result = RepairBehaviorEnum::Uninstaller;\r\n        }\r\n        else if (inStrLower == \"modify\")\r\n        {\r\n            result = RepairBehaviorEnum::Modify;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::map<DWORD, ExpectedReturnCodeEnum> GetDefaultKnownReturnCodes(InstallerTypeEnum installerType)\r\n    {\r\n        switch (installerType)\r\n        {\r\n        case InstallerTypeEnum::Burn:\r\n        case InstallerTypeEnum::Wix:\r\n        case InstallerTypeEnum::Msi:\r\n            // See https://docs.microsoft.com/windows/win32/msi/error-codes\r\n            return\r\n            {\r\n                { ERROR_INSTALL_ALREADY_RUNNING, ExpectedReturnCodeEnum::InstallInProgress },\r\n                { ERROR_DISK_FULL, ExpectedReturnCodeEnum::DiskFull },\r\n                { ERROR_INSTALL_SERVICE_FAILURE, ExpectedReturnCodeEnum::ContactSupport },\r\n                { ERROR_SUCCESS_REBOOT_REQUIRED, ExpectedReturnCodeEnum::RebootRequiredToFinish },\r\n                { ERROR_SUCCESS_REBOOT_INITIATED, ExpectedReturnCodeEnum::RebootInitiated },\r\n                { ERROR_INSTALL_USEREXIT, ExpectedReturnCodeEnum::CancelledByUser },\r\n                { ERROR_PRODUCT_VERSION, ExpectedReturnCodeEnum::AlreadyInstalled },\r\n                { ERROR_INSTALL_REJECTED, ExpectedReturnCodeEnum::SystemNotSupported },\r\n                { ERROR_INSTALL_PACKAGE_REJECTED, ExpectedReturnCodeEnum::BlockedByPolicy },\r\n                { ERROR_INSTALL_TRANSFORM_REJECTED, ExpectedReturnCodeEnum::BlockedByPolicy },\r\n                { ERROR_PATCH_PACKAGE_REJECTED, ExpectedReturnCodeEnum::BlockedByPolicy },\r\n                { ERROR_PATCH_REMOVAL_DISALLOWED, ExpectedReturnCodeEnum::BlockedByPolicy },\r\n                { ERROR_INSTALL_REMOTE_DISALLOWED, ExpectedReturnCodeEnum::BlockedByPolicy },\r\n                { ERROR_INVALID_PARAMETER, ExpectedReturnCodeEnum::InvalidParameter },\r\n                { ERROR_INVALID_TABLE, ExpectedReturnCodeEnum::InvalidParameter },\r\n                { ERROR_INVALID_COMMAND_LINE, ExpectedReturnCodeEnum::InvalidParameter },\r\n                { ERROR_INVALID_PATCH_XML, ExpectedReturnCodeEnum::InvalidParameter },\r\n                { ERROR_INSTALL_LANGUAGE_UNSUPPORTED, ExpectedReturnCodeEnum::SystemNotSupported },\r\n                { ERROR_INSTALL_PLATFORM_UNSUPPORTED, ExpectedReturnCodeEnum::SystemNotSupported },\r\n            };\r\n        case InstallerTypeEnum::Inno:\r\n            // See https://jrsoftware.org/ishelp/index.php?topic=setupexitcodes\r\n            return\r\n            {\r\n                { 2, ExpectedReturnCodeEnum::CancelledByUser },\r\n                { 5, ExpectedReturnCodeEnum::CancelledByUser },\r\n                { 8, ExpectedReturnCodeEnum::RebootRequiredForInstall },\r\n            };\r\n        case InstallerTypeEnum::Msix:\r\n            // See https://docs.microsoft.com/en-us/windows/win32/appxpkg/troubleshooting\r\n            return\r\n            {\r\n                { HRESULT_FROM_WIN32(ERROR_INSTALL_PREREQUISITE_FAILED), ExpectedReturnCodeEnum::MissingDependency },\r\n                { HRESULT_FROM_WIN32(ERROR_INSTALL_RESOLVE_DEPENDENCY_FAILED), ExpectedReturnCodeEnum::MissingDependency },\r\n                { HRESULT_FROM_WIN32(ERROR_INSTALL_OPTIONAL_PACKAGE_REQUIRES_MAIN_PACKAGE), ExpectedReturnCodeEnum::MissingDependency },\r\n                { HRESULT_FROM_WIN32(ERROR_INSTALL_OUT_OF_DISK_SPACE), ExpectedReturnCodeEnum::DiskFull },\r\n                { HRESULT_FROM_WIN32(ERROR_INSTALL_CANCEL), ExpectedReturnCodeEnum::CancelledByUser },\r\n                { HRESULT_FROM_WIN32(ERROR_PACKAGE_ALREADY_EXISTS), ExpectedReturnCodeEnum::AlreadyInstalled },\r\n                { HRESULT_FROM_WIN32(ERROR_INSTALL_PACKAGE_DOWNGRADE), ExpectedReturnCodeEnum::Downgrade },\r\n                { HRESULT_FROM_WIN32(ERROR_DEPLOYMENT_BLOCKED_BY_POLICY), ExpectedReturnCodeEnum::BlockedByPolicy},\r\n                { HRESULT_FROM_WIN32(ERROR_INSTALL_POLICY_FAILURE), ExpectedReturnCodeEnum::BlockedByPolicy},\r\n                { HRESULT_FROM_WIN32(ERROR_PACKAGES_IN_USE), ExpectedReturnCodeEnum::PackageInUse },\r\n                { HRESULT_FROM_WIN32(ERROR_INSTALL_WRONG_PROCESSOR_ARCHITECTURE), ExpectedReturnCodeEnum::SystemNotSupported },\r\n                { HRESULT_FROM_WIN32(ERROR_PACKAGE_NOT_SUPPORTED_ON_FILESYSTEM), ExpectedReturnCodeEnum::SystemNotSupported },\r\n                { HRESULT_FROM_WIN32(ERROR_DEPLOYMENT_OPTION_NOT_SUPPORTED), ExpectedReturnCodeEnum::SystemNotSupported },\r\n                { HRESULT_FROM_WIN32(ERROR_PACKAGE_LACKS_CAPABILITY_TO_DEPLOY_ON_HOST), ExpectedReturnCodeEnum::SystemNotSupported },\r\n            };\r\n        default:\r\n            return {};\r\n        }\r\n    }\r\n\r\n    void DependencyList::Add(const Dependency& newDependency)\r\n    {\r\n        Dependency* existingDependency = this->HasDependency(newDependency);\r\n\r\n        if (existingDependency != NULL)\r\n        {\r\n            if (newDependency.MinVersion > existingDependency->MinVersion)\r\n            {\r\n                existingDependency->MinVersion = newDependency.MinVersion;\r\n            }\r\n        }\r\n        else\r\n        {\r\n            m_dependencies.push_back(newDependency);\r\n        }\r\n    }\r\n\r\n    void DependencyList::Add(const DependencyList& otherDependencyList)\r\n    {\r\n        for (const auto& dependency : otherDependencyList.m_dependencies)\r\n        {\r\n            this->Add(dependency);\r\n        }\r\n    }\r\n\r\n    bool DependencyList::HasAny() const { return !m_dependencies.empty(); }\r\n    bool DependencyList::HasAnyOf(DependencyType type) const\r\n    {\r\n        for (const auto& dependency : m_dependencies)\r\n        {\r\n            if (dependency.Type == type) return true;\r\n        };\r\n        return false;\r\n    }\r\n\r\n    Dependency* DependencyList::HasDependency(const Dependency& dependencyToSearch)\r\n    {\r\n        for (auto& dependency : m_dependencies)\r\n        {\r\n            if (dependency.Type == dependencyToSearch.Type && ICUCaseInsensitiveEquals(dependency.Id(), dependencyToSearch.Id()))\r\n            {\r\n                return &dependency;\r\n            }\r\n        }\r\n        return nullptr;\r\n    }\r\n\r\n    // for testing purposes\r\n    bool DependencyList::HasExactDependency(DependencyType type, const string_t& id, const string_t& minVersion) const\r\n    {\r\n        for (const auto& dependency : m_dependencies)\r\n        {\r\n            if (dependency.Type == type && Utility::ICUCaseInsensitiveEquals(dependency.Id(), id))\r\n            {\r\n                if (!minVersion.empty())\r\n                {\r\n                    return dependency.MinVersion == Utility::Version{ minVersion };\r\n                }\r\n                else\r\n                {\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n        return false;\r\n    }\r\n\r\n    size_t DependencyList::Size() const\r\n    {\r\n        return m_dependencies.size();\r\n    }\r\n\r\n    void DependencyList::ApplyToType(DependencyType type, std::function<void(const Dependency&)> func) const\r\n    {\r\n        for (const auto& dependency : m_dependencies)\r\n        {\r\n            if (dependency.Type == type) func(dependency);\r\n        }\r\n    }\r\n\r\n    void DependencyList::ApplyToAll(std::function<void(const Dependency&)> func) const\r\n    {\r\n        for (const auto& dependency : m_dependencies)\r\n        {\r\n            func(dependency);\r\n        }\r\n    }\r\n\r\n    bool DependencyList::Empty() const\r\n    {\r\n        return m_dependencies.empty();\r\n    }\r\n\r\n    void DependencyList::Clear() { m_dependencies.clear(); }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Manifest/ManifestComparator.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include <winget/ManifestComparator.h>\r\n#include <AppInstallerLogging.h>\r\n#include <winget/UserSettings.h>\r\n#include <winget/Runtime.h>\r\n#include <winget/Locale.h>\r\n\r\nusing namespace AppInstaller::Manifest;\r\n\r\nnamespace AppInstaller::Manifest\r\n{\r\n    std::ostream& operator<<(std::ostream& out, const ManifestInstaller& installer)\r\n    {\r\n        return out << '[' <<\r\n            AppInstaller::Utility::ToString(installer.Arch) << ',' <<\r\n            AppInstaller::Manifest::InstallerTypeToString(installer.EffectiveInstallerType()) << ',' <<\r\n            AppInstaller::Manifest::ScopeToString(installer.Scope) << ',' <<\r\n            installer.Locale << ']';\r\n    }\r\n}\r\n\r\nnamespace AppInstaller::Manifest\r\n{\r\n    namespace\r\n    {\r\n        struct PortableInstallFilter : public details::FilterField\r\n        {\r\n            PortableInstallFilter() : details::FilterField(\"Portable Install\") {}\r\n\r\n            InapplicabilityFlags IsApplicable(const ManifestInstaller& installer) override\r\n            {\r\n                // Unvirtualized resources restricted capability is only supported for >= 10.0.18362\r\n                // TODO: Add support for OS versions that don't support virtualization.\r\n                if (installer.EffectiveInstallerType() == InstallerTypeEnum::Portable && !Runtime::IsCurrentOSVersionGreaterThanOrEqual(Utility::Version(\"10.0.18362\")))\r\n                {\r\n                    return InapplicabilityFlags::OSVersion;\r\n                }\r\n\r\n                return InapplicabilityFlags::None;\r\n            }\r\n\r\n            std::string ExplainInapplicable(const ManifestInstaller&) override\r\n            {\r\n                std::string result = \"Current OS is lower than supported MinOSVersion (10.0.18362) for Portable install\";\r\n                return result;\r\n            }\r\n        };\r\n\r\n        struct OSVersionFilter : public details::FilterField\r\n        {\r\n            OSVersionFilter() : details::FilterField(\"OS Version\") {}\r\n\r\n            InapplicabilityFlags IsApplicable(const ManifestInstaller& installer) override\r\n            {\r\n                if (installer.MinOSVersion.empty() || Runtime::IsCurrentOSVersionGreaterThanOrEqual(Utility::Version(installer.MinOSVersion)))\r\n                {\r\n                    return InapplicabilityFlags::None;\r\n                }\r\n\r\n                return InapplicabilityFlags::OSVersion;\r\n            }\r\n\r\n            std::string ExplainInapplicable(const ManifestInstaller& installer) override\r\n            {\r\n                std::string result = \"Current OS is lower than MinOSVersion \";\r\n                result += installer.MinOSVersion;\r\n                return result;\r\n            }\r\n        };\r\n\r\n        struct MachineArchitectureComparator : public details::ComparisonField\r\n        {\r\n            MachineArchitectureComparator() : details::ComparisonField(\"Machine Architecture\") {}\r\n\r\n            MachineArchitectureComparator(std::vector<Utility::Architecture> allowedArchitectures) :\r\n                details::ComparisonField(\"Machine Architecture\"), m_allowedArchitectures(std::move(allowedArchitectures))\r\n            {\r\n                AICLI_LOG(CLI, Verbose, << \"Architecture Comparator created with allowed architectures: \" << Utility::ConvertContainerToString(m_allowedArchitectures, Utility::ToString));\r\n            }\r\n\r\n            static std::unique_ptr<MachineArchitectureComparator> Create(const ManifestComparator::Options& options)\r\n            {\r\n                if (!options.AllowedArchitectures.empty())\r\n                {\r\n                    // If the incoming data contains elements, we will use them to construct a final allowed list.\r\n                    // The algorithm is to take elements until we find Unknown, which indicates that any architecture is\r\n                    // acceptable at this point. The system supported set of architectures will then be placed at the end.\r\n                    std::vector<Utility::Architecture> result;\r\n                    bool addRemainingApplicableArchitectures = false;\r\n\r\n                    for (Utility::Architecture architecture : options.AllowedArchitectures)\r\n                    {\r\n                        if (architecture == Utility::Architecture::Unknown)\r\n                        {\r\n                            addRemainingApplicableArchitectures = true;\r\n                            break;\r\n                        }\r\n\r\n                        // If the architecture is applicable and not already in our result set...\r\n                        if ((options.SkipApplicabilityCheck || Utility::IsApplicableArchitecture(architecture) != Utility::InapplicableArchitecture) &&\r\n                            Utility::IsApplicableArchitecture(architecture, result) == Utility::InapplicableArchitecture)\r\n                        {\r\n                            result.push_back(architecture);\r\n                        }\r\n                    }\r\n\r\n                    if (addRemainingApplicableArchitectures)\r\n                    {\r\n                        for (Utility::Architecture architecture : Utility::GetApplicableArchitectures())\r\n                        {\r\n                            if (Utility::IsApplicableArchitecture(architecture, result) == Utility::InapplicableArchitecture)\r\n                            {\r\n                                result.push_back(architecture);\r\n                            }\r\n                        }\r\n                    }\r\n\r\n                    return std::make_unique<MachineArchitectureComparator>(std::move(result));\r\n                }\r\n                else\r\n                {\r\n                    return std::make_unique<MachineArchitectureComparator>();\r\n                }\r\n            }\r\n\r\n            InapplicabilityFlags IsApplicable(const ManifestInstaller& installer) override\r\n            {\r\n                if (CheckAllowedArchitecture(installer.Arch) == Utility::InapplicableArchitecture ||\r\n                    IsSystemArchitectureUnsupportedByInstaller(installer))\r\n                {\r\n                    return InapplicabilityFlags::MachineArchitecture;\r\n                }\r\n\r\n                return InapplicabilityFlags::None;\r\n            }\r\n\r\n            std::string ExplainInapplicable(const ManifestInstaller& installer) override\r\n            {\r\n                std::string result;\r\n                if (Utility::IsApplicableArchitecture(installer.Arch) == Utility::InapplicableArchitecture)\r\n                {\r\n                    result = \"Machine is not compatible with \";\r\n                    result += Utility::ToString(installer.Arch);\r\n                }\r\n                else if (IsSystemArchitectureUnsupportedByInstaller(installer))\r\n                {\r\n                    result = \"System architecture is unsupported by installer\";\r\n                }\r\n                else\r\n                {\r\n                    result = \"Architecture was excluded by caller : \";\r\n                    result += Utility::ToString(installer.Arch);\r\n                }\r\n\r\n                return result;\r\n            }\r\n\r\n            details::ComparisonResult IsFirstBetter(const ManifestInstaller& first, const ManifestInstaller& second) override\r\n            {\r\n                auto arch1 = CheckAllowedArchitecture(first.Arch);\r\n                auto arch2 = CheckAllowedArchitecture(second.Arch);\r\n\r\n                if (arch1 > arch2)\r\n                {\r\n                    // A match with the primary architecture is strong\r\n                    return (first.Arch == GetStrongArchitectureMatch() ? details::ComparisonResult::StrongPositive : details::ComparisonResult::WeakPositive);\r\n                }\r\n\r\n                return details::ComparisonResult::Negative;\r\n            }\r\n\r\n        private:\r\n            int CheckAllowedArchitecture(Utility::Architecture architecture)\r\n            {\r\n                if (m_allowedArchitectures.empty())\r\n                {\r\n                    return Utility::IsApplicableArchitecture(architecture);\r\n                }\r\n                else\r\n                {\r\n                    return Utility::IsApplicableArchitecture(architecture, m_allowedArchitectures);\r\n                }\r\n            }\r\n\r\n            bool IsSystemArchitectureUnsupportedByInstaller(const ManifestInstaller& installer)\r\n            {\r\n                auto unsupportedItr = std::find(\r\n                    installer.UnsupportedOSArchitectures.begin(),\r\n                    installer.UnsupportedOSArchitectures.end(),\r\n                    Utility::GetSystemArchitecture());\r\n                return unsupportedItr != installer.UnsupportedOSArchitectures.end();\r\n            }\r\n\r\n            Utility::Architecture GetStrongArchitectureMatch()\r\n            {\r\n                // If we have a preferential order, treat the first entry as strong.\r\n                // Otherwise, treat the system architecture as strong (which is always first in the default order).\r\n                return m_allowedArchitectures.empty() ? Utility::GetSystemArchitecture() : m_allowedArchitectures.front();\r\n            }\r\n\r\n            std::vector<Utility::Architecture> m_allowedArchitectures;\r\n        };\r\n\r\n        struct InstallerTypeComparator : public details::ComparisonField\r\n        {\r\n            InstallerTypeComparator(std::vector<InstallerTypeEnum> preference, std::vector<InstallerTypeEnum> requirement) :\r\n                details::ComparisonField(\"Installer Type\"), m_preference(std::move(preference)), m_requirement(std::move(requirement))\r\n            {\r\n                m_preferenceAsString = Utility::ConvertContainerToString(m_preference, InstallerTypeToString);\r\n                m_requirementAsString = Utility::ConvertContainerToString(m_requirement, InstallerTypeToString);\r\n                AICLI_LOG(CLI, Verbose,\r\n                    << \"InstallerType Comparator created with Required InstallerTypes: \" << m_requirementAsString\r\n                    << \" , Preferred InstallerTypes: \" << m_preferenceAsString);\r\n            }\r\n\r\n            static std::unique_ptr<InstallerTypeComparator> Create(const ManifestComparator::Options& options)\r\n            {\r\n                std::vector<InstallerTypeEnum> preference;\r\n                std::vector<InstallerTypeEnum> requirement;\r\n\r\n                if (options.RequestedInstallerType)\r\n                {\r\n                    requirement.emplace_back(options.RequestedInstallerType.value());\r\n                }\r\n                else\r\n                {\r\n                    preference = Settings::User().Get<Settings::Setting::InstallerTypePreference>();\r\n                    requirement = Settings::User().Get<Settings::Setting::InstallerTypeRequirement>();\r\n                }\r\n\r\n                if (!preference.empty() || !requirement.empty())\r\n                {\r\n                    return std::make_unique<InstallerTypeComparator>(preference, requirement);\r\n                }\r\n                else\r\n                {\r\n                    return {};\r\n                }\r\n            }\r\n\r\n            std::string ExplainInapplicable(const ManifestInstaller& installer) override\r\n            {\r\n                std::string result = \"InstallerType [\";\r\n                result += InstallerTypeToString(installer.EffectiveInstallerType());\r\n                result += \"] does not match required InstallerTypes: \";\r\n                result += m_requirementAsString;\r\n                return result;\r\n            }\r\n\r\n            InapplicabilityFlags IsApplicable(const ManifestInstaller& installer) override\r\n            {\r\n                if (!m_requirement.empty())\r\n                {\r\n                    // The installer is applicable if the effective or base installer type matches.\r\n                    if (ContainsInstallerType(m_requirement, installer.EffectiveInstallerType()) ||\r\n                        ContainsInstallerType(m_requirement, installer.BaseInstallerType))\r\n                    {\r\n                        return InapplicabilityFlags::None;\r\n                    }\r\n\r\n                    return InapplicabilityFlags::InstallerType;\r\n                }\r\n                else\r\n                {\r\n                    return InapplicabilityFlags::None;\r\n                }\r\n            }\r\n\r\n            details::ComparisonResult IsFirstBetter(const ManifestInstaller& first, const ManifestInstaller& second) override\r\n            {\r\n                if (m_preference.empty())\r\n                {\r\n                    return details::ComparisonResult::Negative;\r\n                }\r\n\r\n                for (InstallerTypeEnum installerTypePreference : m_preference)\r\n                {\r\n                    bool isFirstInstallerTypePreferred =\r\n                        first.EffectiveInstallerType() == installerTypePreference ||\r\n                        first.BaseInstallerType == installerTypePreference;\r\n\r\n                    bool isSecondInstallerTypePreferred =\r\n                        second.EffectiveInstallerType() == installerTypePreference ||\r\n                        second.BaseInstallerType == installerTypePreference;\r\n\r\n                    if (isFirstInstallerTypePreferred && isSecondInstallerTypePreferred)\r\n                    {\r\n                        return details::ComparisonResult::Negative;\r\n                    }\r\n                    else if (isFirstInstallerTypePreferred != isSecondInstallerTypePreferred)\r\n                    {\r\n                        // Treating this as a weak positive because one can use requirements to guarantee the installer type if necessary.\r\n                        return (isFirstInstallerTypePreferred ? details::ComparisonResult::WeakPositive : details::ComparisonResult::Negative);\r\n                    }\r\n                }\r\n\r\n                return details::ComparisonResult::Negative;\r\n            }\r\n\r\n        private:\r\n            std::vector<InstallerTypeEnum> m_preference;\r\n            std::vector<InstallerTypeEnum> m_requirement;\r\n            std::string m_preferenceAsString;\r\n            std::string m_requirementAsString;\r\n\r\n            bool ContainsInstallerType(const std::vector<InstallerTypeEnum>& selection, InstallerTypeEnum installerType)\r\n            {\r\n                return std::find(selection.begin(), selection.end(), installerType) != selection.end();\r\n            }\r\n        };\r\n\r\n        struct InstalledTypeFilter : public details::FilterField\r\n        {\r\n            InstalledTypeFilter(InstallerTypeEnum installedType) :\r\n                details::FilterField(\"Installed Type\"), m_installedType(installedType) {}\r\n\r\n            static std::unique_ptr<InstalledTypeFilter> Create(const ManifestComparator::Options& options)\r\n            {\r\n                if (options.CurrentlyInstalledType)\r\n                {\r\n                    InstallerTypeEnum installedType = options.CurrentlyInstalledType.value();\r\n                    if (installedType != InstallerTypeEnum::Unknown)\r\n                    {\r\n                        return std::make_unique<InstalledTypeFilter>(installedType);\r\n                    }\r\n                }\r\n\r\n                return {};\r\n            }\r\n\r\n            InapplicabilityFlags IsApplicable(const ManifestInstaller& installer) override\r\n            {\r\n                return IsInstallerCompatibleWith(installer, m_installedType) ? InapplicabilityFlags::None : InapplicabilityFlags::InstalledType;\r\n            }\r\n\r\n            std::string ExplainInapplicable(const ManifestInstaller& installer) override\r\n            {\r\n                std::string result = \"Installed package type '\" + std::string{ InstallerTypeToString(m_installedType) } +\r\n                    \"' is not compatible with installer type \" + std::string{ InstallerTypeToString(installer.EffectiveInstallerType()) };\r\n\r\n                std::string arpInstallerTypes;\r\n                for (const auto& entry : installer.AppsAndFeaturesEntries)\r\n                {\r\n                    arpInstallerTypes += \" \" + std::string{ InstallerTypeToString(entry.InstallerType) };\r\n                }\r\n\r\n                if (!arpInstallerTypes.empty())\r\n                {\r\n                    result += \", or with accepted type(s)\" + arpInstallerTypes;\r\n                }\r\n\r\n                return result;\r\n            }\r\n\r\n        private:\r\n            // The installer is compatible if it's type or any of its ARP entries' type matches the installed type\r\n            static bool IsInstallerCompatibleWith(const ManifestInstaller& installer, InstallerTypeEnum type)\r\n            {\r\n                if (IsInstallerTypeCompatible(installer.EffectiveInstallerType(), type))\r\n                {\r\n                    return true;\r\n                }\r\n\r\n                auto itr = std::find_if(\r\n                    installer.AppsAndFeaturesEntries.begin(),\r\n                    installer.AppsAndFeaturesEntries.end(),\r\n                    [=](AppsAndFeaturesEntry arpEntry) { return IsInstallerTypeCompatible(arpEntry.InstallerType, type); });\r\n                if (itr != installer.AppsAndFeaturesEntries.end())\r\n                {\r\n                    return true;\r\n                }\r\n\r\n                return false;\r\n            }\r\n\r\n            InstallerTypeEnum m_installedType;\r\n        };\r\n\r\n        struct InstalledScopeFilter : public details::FilterField\r\n        {\r\n            InstalledScopeFilter(ScopeEnum requirement) :\r\n                details::FilterField(\"Installed Scope\"), m_requirement(requirement) {}\r\n\r\n            static std::unique_ptr<InstalledScopeFilter> Create(const ManifestComparator::Options& options)\r\n            {\r\n                // Check for an existing install and require a matching scope.\r\n                if (options.CurrentlyInstalledScope)\r\n                {\r\n                    ScopeEnum installedScope = options.CurrentlyInstalledScope.value();\r\n                    if (installedScope != ScopeEnum::Unknown)\r\n                    {\r\n                        return std::make_unique<InstalledScopeFilter>(installedScope);\r\n                    }\r\n                }\r\n\r\n                return {};\r\n            }\r\n\r\n            InapplicabilityFlags IsApplicable(const ManifestInstaller& installer) override\r\n            {\r\n                // We have to assume the unknown scope will match our required scope, or the entire catalog would stop working for upgrade.\r\n                if (installer.Scope == ScopeEnum::Unknown || installer.Scope == m_requirement || DoesInstallerTypeIgnoreScopeFromManifest(installer.EffectiveInstallerType()))\r\n                {\r\n                    return InapplicabilityFlags::None;\r\n                }\r\n\r\n                return InapplicabilityFlags::InstalledScope;\r\n            }\r\n\r\n            std::string ExplainInapplicable(const ManifestInstaller& installer) override\r\n            {\r\n                std::string result = \"Installer scope does not match currently installed scope: \";\r\n                result += ScopeToString(installer.Scope);\r\n                result += \" != \";\r\n                result += ScopeToString(m_requirement);\r\n                return result;\r\n            }\r\n\r\n        private:\r\n            ScopeEnum m_requirement;\r\n        };\r\n\r\n        struct ScopeComparator : public details::ComparisonField\r\n        {\r\n            ScopeComparator(ScopeEnum preference, ScopeEnum requirement, bool allowUnknownInAdditionToRequired) :\r\n                details::ComparisonField(\"Scope\"), m_preference(preference), m_requirement(requirement), m_allowUnknownInAdditionToRequired(allowUnknownInAdditionToRequired) {}\r\n\r\n            static std::unique_ptr<ScopeComparator> Create(const ManifestComparator::Options& options)\r\n            {\r\n                // Preference will always come from settings\r\n                ScopeEnum preference = Settings::User().Get<Settings::Setting::InstallScopePreference>();\r\n\r\n                // Requirement may come from args or settings; args overrides settings.\r\n                ScopeEnum requirement = ScopeEnum::Unknown;\r\n\r\n                if (options.RequestedInstallerScope)\r\n                {\r\n                    requirement = options.RequestedInstallerScope.value();\r\n                }\r\n                else\r\n                {\r\n                    requirement = Settings::User().Get<Settings::Setting::InstallScopeRequirement>();\r\n                }\r\n\r\n                bool allowUnknownInAdditionToRequired = false;\r\n                if (options.AllowUnknownScope)\r\n                {\r\n                    allowUnknownInAdditionToRequired = options.AllowUnknownScope.value();\r\n\r\n                    // Force the required type to be preferred over Unknown\r\n                    if (requirement != ScopeEnum::Unknown)\r\n                    {\r\n                        preference = requirement;\r\n                    }\r\n                }\r\n\r\n                if (preference != ScopeEnum::Unknown || requirement != ScopeEnum::Unknown)\r\n                {\r\n                    return std::make_unique<ScopeComparator>(preference, requirement, allowUnknownInAdditionToRequired);\r\n                }\r\n                else\r\n                {\r\n                    return {};\r\n                }\r\n            }\r\n\r\n            InapplicabilityFlags IsApplicable(const ManifestInstaller& installer) override\r\n            {\r\n                // Applicable if one of:\r\n                //  1. No requirement (aka is Unknown)\r\n                //  2. Requirement met\r\n                //  3. Installer scope is Unknown and this has been explicitly allowed\r\n                //  4. The installer type is scope agnostic (we can control it)\r\n                if (m_requirement == ScopeEnum::Unknown ||\r\n                    installer.Scope == m_requirement ||\r\n                    (installer.Scope == ScopeEnum::Unknown && m_allowUnknownInAdditionToRequired) ||\r\n                    DoesInstallerTypeIgnoreScopeFromManifest(installer.EffectiveInstallerType()))\r\n                {\r\n                    return InapplicabilityFlags::None;\r\n                }\r\n\r\n                return InapplicabilityFlags::Scope;\r\n            }\r\n\r\n            std::string ExplainInapplicable(const ManifestInstaller& installer) override\r\n            {\r\n                std::string result = \"Installer scope does not match required scope: \";\r\n                result += ScopeToString(installer.Scope);\r\n                result += \" != \";\r\n                result += ScopeToString(m_requirement);\r\n                return result;\r\n            }\r\n\r\n            details::ComparisonResult IsFirstBetter(const ManifestInstaller& first, const ManifestInstaller& second) override\r\n            {\r\n                if (m_preference != ScopeEnum::Unknown && first.Scope == m_preference && second.Scope != m_preference)\r\n                {\r\n                    // When the second input is unknown, this is a weak result. If it is not (and therefore the opposite of the preference), this is strong.\r\n                    return (second.Scope == ScopeEnum::Unknown ? details::ComparisonResult::WeakPositive : details::ComparisonResult::StrongPositive);\r\n                }\r\n\r\n                return details::ComparisonResult::Negative;\r\n            }\r\n\r\n        private:\r\n            ScopeEnum m_preference;\r\n            ScopeEnum m_requirement;\r\n            bool m_allowUnknownInAdditionToRequired;\r\n        };\r\n\r\n        struct LocaleComparator : public details::ComparisonField\r\n        {\r\n            LocaleComparator(std::vector<std::string> preference, std::vector<std::string> requirement, bool isInstalledLocale) :\r\n                details::ComparisonField(\"Locale\"), m_preference(std::move(preference)), m_requirement(std::move(requirement)), m_isInstalledLocale(isInstalledLocale)\r\n            {\r\n                m_requirementAsString = Utility::ConvertContainerToString(m_requirement);\r\n                m_preferenceAsString = Utility::ConvertContainerToString(m_preference);\r\n                AICLI_LOG(CLI, Verbose,\r\n                    << \"Locale Comparator created with Required Locales: \" << m_requirementAsString\r\n                    << \" , Preferred Locales: \" << m_preferenceAsString\r\n                    << \" , IsInstalledLocale: \" << m_isInstalledLocale);\r\n            }\r\n\r\n            static std::unique_ptr<LocaleComparator> Create(const ManifestComparator::Options& options)\r\n            {\r\n                std::vector<std::string> preference;\r\n                std::vector<std::string> requirement;\r\n                // This is for installed locale case, where the locale is a preference but requires at least compatible match.\r\n                bool isInstalledLocale = false;\r\n\r\n                // Requirement may come from args, previous user intent or settings; args overrides previous user intent then settings.\r\n                if (options.RequestedInstallerLocale)\r\n                {\r\n                    requirement.emplace_back(options.RequestedInstallerLocale.value());\r\n                }\r\n                else if (options.PreviousUserIntentLocale)\r\n                {\r\n                    requirement.emplace_back(options.PreviousUserIntentLocale.value());\r\n                    isInstalledLocale = true;\r\n                }\r\n                else\r\n                {\r\n                    if (!options.CurrentlyInstalledLocale)\r\n                    {\r\n                        // If it's an upgrade of previous package, no need to set requirements from settings\r\n                        // as previous installed locale will be used later.\r\n                        requirement = Settings::User().Get<Settings::Setting::InstallLocaleRequirement>();\r\n                    }\r\n                }\r\n\r\n                // Preference will come from previous installed locale, winget settings or Preferred Languages settings.\r\n                // Previous installed locale goes first, then winget settings, then Preferred Languages settings.\r\n                // Previous installed locale also requires at least compatible locale match.\r\n                if (options.CurrentlyInstalledLocale)\r\n                {\r\n                    preference.emplace_back(options.CurrentlyInstalledLocale.value());\r\n                    isInstalledLocale = true;\r\n                }\r\n                else\r\n                {\r\n                    preference = Settings::User().Get<Settings::Setting::InstallLocalePreference>();\r\n                    if (preference.empty())\r\n                    {\r\n                        preference = Locale::GetUserPreferredLanguages();\r\n                    }\r\n                }\r\n\r\n                if (!preference.empty() || !requirement.empty())\r\n                {\r\n                    return std::make_unique<LocaleComparator>(preference, requirement, isInstalledLocale);\r\n                }\r\n                else\r\n                {\r\n                    return {};\r\n                }\r\n            }\r\n\r\n            InapplicabilityFlags IsApplicable(const ManifestInstaller& installer) override\r\n            {\r\n                InapplicabilityFlags inapplicableFlag = m_isInstalledLocale ? InapplicabilityFlags::InstalledLocale : InapplicabilityFlags::Locale;\r\n\r\n                if (!m_requirement.empty())\r\n                {\r\n                    // Check if requirement is satisfied\r\n                    for (auto const& requiredLocale : m_requirement)\r\n                    {\r\n                        if (Locale::GetDistanceOfLanguage(requiredLocale, installer.Locale) >= Locale::MinimumDistanceScoreAsPerfectMatch)\r\n                        {\r\n                            return InapplicabilityFlags::None;\r\n                        }\r\n                    }\r\n\r\n                    return inapplicableFlag;\r\n                }\r\n                else if (m_isInstalledLocale && !m_preference.empty())\r\n                {\r\n                    // For installed locale preference, check at least compatible match for preference\r\n                    for (auto const& preferredLocale : m_preference)\r\n                    {\r\n                        // We have to assume an unknown installer locale will match our installed locale, or the entire catalog would stop working for upgrade.\r\n                        if (installer.Locale.empty() ||\r\n                            Locale::GetDistanceOfLanguage(preferredLocale, installer.Locale) >= Locale::MinimumDistanceScoreAsCompatibleMatch)\r\n                        {\r\n                            return InapplicabilityFlags::None;\r\n                        }\r\n                    }\r\n\r\n                    return inapplicableFlag;\r\n                }\r\n                else\r\n                {\r\n                    return InapplicabilityFlags::None;\r\n                }\r\n            }\r\n\r\n            std::string ExplainInapplicable(const ManifestInstaller& installer) override\r\n            {\r\n                std::string result = \"Installer locale does not match required locale: \";\r\n                result += installer.Locale;\r\n                result += \"Required locales: \";\r\n                result += m_requirementAsString;\r\n                result += \" Or does not satisfy compatible match for Preferred Locales: \";\r\n                result += m_preferenceAsString;\r\n                return result;\r\n            }\r\n\r\n            details::ComparisonResult IsFirstBetter(const ManifestInstaller& first, const ManifestInstaller& second) override\r\n            {\r\n                if (m_preference.empty())\r\n                {\r\n                    return details::ComparisonResult::Negative;\r\n                }\r\n\r\n                for (auto const& preferredLocale : m_preference)\r\n                {\r\n                    double firstScore = first.Locale.empty() ? Locale::UnknownLanguageDistanceScore : Locale::GetDistanceOfLanguage(preferredLocale, first.Locale);\r\n                    double secondScore = second.Locale.empty() ? Locale::UnknownLanguageDistanceScore : Locale::GetDistanceOfLanguage(preferredLocale, second.Locale);\r\n\r\n                    if (firstScore >= Locale::MinimumDistanceScoreAsCompatibleMatch || secondScore >= Locale::MinimumDistanceScoreAsCompatibleMatch)\r\n                    {\r\n                        // This could probably be enriched to always check all locales and determine strong/weak based off of the MinimumDistanceScoreAsCompatibleMatch.\r\n                        return (firstScore > secondScore ? details::ComparisonResult::StrongPositive : details::ComparisonResult::Negative);\r\n                    }\r\n                }\r\n\r\n                // At this point, the installer locale matches no preference.\r\n                // if first is unknown and second is no match for sure, we might prefer unknown one.\r\n                return (first.Locale.empty() && !second.Locale.empty() ? details::ComparisonResult::WeakPositive : details::ComparisonResult::Negative);\r\n            }\r\n\r\n        private:\r\n            std::vector<std::string> m_preference;\r\n            std::vector<std::string> m_requirement;\r\n            std::string m_requirementAsString;\r\n            std::string m_preferenceAsString;\r\n            bool m_isInstalledLocale = false;\r\n        };\r\n\r\n        struct MarketFilter : public details::FilterField\r\n        {\r\n            MarketFilter(Manifest::string_t market) : details::FilterField(\"Market\"), m_market(market)\r\n            {\r\n                AICLI_LOG(CLI, Verbose, << \"Market Filter created with market: \" << m_market);\r\n            }\r\n\r\n            static std::unique_ptr<MarketFilter> Create()\r\n            {\r\n                return std::make_unique<MarketFilter>(Runtime::GetOSRegion());\r\n            }\r\n\r\n            InapplicabilityFlags IsApplicable(const ManifestInstaller& installer) override\r\n            {\r\n                // If both allowed and excluded lists are provided, we only need to check the allowed markets.\r\n                if (!installer.Markets.AllowedMarkets.empty())\r\n                {\r\n                    // Inapplicable if NOT found\r\n                    if (!IsMarketInList(installer.Markets.AllowedMarkets))\r\n                    {\r\n                        return InapplicabilityFlags::Market;\r\n                    }\r\n                }\r\n                else if (!installer.Markets.ExcludedMarkets.empty())\r\n                {\r\n                    // Inapplicable if found\r\n                    if (IsMarketInList(installer.Markets.ExcludedMarkets))\r\n                    {\r\n                        return InapplicabilityFlags::Market;\r\n                    }\r\n                }\r\n\r\n                return InapplicabilityFlags::None;\r\n            }\r\n\r\n            std::string ExplainInapplicable(const ManifestInstaller& installer) override\r\n            {\r\n                std::string result = \"Current market '\" + m_market + \"' does not match installer markets.\" +\r\n                    \" Allowed markets: \" + Utility::ConvertContainerToString(installer.Markets.AllowedMarkets) +\r\n                    \" Excluded markets: \" + Utility::ConvertContainerToString(installer.Markets.ExcludedMarkets);\r\n                return result;\r\n            }\r\n\r\n        private:\r\n            bool IsMarketInList(const std::vector<Manifest::string_t> markets)\r\n            {\r\n                return markets.end() != std::find_if(\r\n                    markets.begin(),\r\n                    markets.end(),\r\n                    [&](const auto& m) { return Utility::CaseInsensitiveEquals(m, m_market); });\r\n            }\r\n\r\n            Manifest::string_t m_market;\r\n        };\r\n    }\r\n\r\n    ManifestComparator::ManifestComparator(const Options& options)\r\n    {\r\n        // Filters based on installer's MinOSVersion\r\n        AddFilter(std::make_unique<OSVersionFilter>());\r\n        // Filters out portable installers if they are not supported by the system\r\n        AddFilter(std::make_unique<PortableInstallFilter>());\r\n        // Filters based on the scope of a currently installed package\r\n        AddFilter(InstalledScopeFilter::Create(options));\r\n        // Filters based on the market region of the system\r\n        AddFilter(MarketFilter::Create());\r\n        // Filters based on the installer type compatability, including with AppsAndFeaturesEntry declarations\r\n        AddFilter(InstalledTypeFilter::Create(options));\r\n\r\n        // Filter order is not important, but comparison order determines priority.\r\n        // Note that all comparators are also filters and their comparison function will only be called on\r\n        // installers that both match the required criteria.\r\n        // \r\n        // The comparators are ordered by the `IsFirstBetter` method, which uses the following algorithm:\r\n        //  - Each comparison between two installers can return one of { Strong, Weak, Negative }\r\n        //  - Installers are compared in both directions, going through the list of comparators as defined here\r\n        //  - The first Strong result in either direction is given priority\r\n        //  - If no Strong results, the first Weak result is used\r\n        //  - If all Negative results, then the two installers are equal in priority (meaning the first one in the list is kept as \"better\")\r\n        // \r\n        // TODO: There are improvements to be made here around ordering, especially in the context of implicit vs explicit vs command line preferences.\r\n\r\n        // Filters based on exact matches for requirements or compatible matches for preferences\r\n        // Only applies when preference exists:\r\n        // Strong if first is compatible and better match than second\r\n        // Weak if first is unknown and second is not\r\n        AddComparator(LocaleComparator::Create(options));\r\n        // Filters only if a requirement is present and it cannot be satisfied by the installer (including installer types that we can control scope in code)\r\n        // Only applies when preference exists:\r\n        // Strong if first matches preference and second does not and is not Unknown\r\n        // Weak if first matches preference and second is Unknown\r\n        AddComparator(ScopeComparator::Create(options));\r\n        // Filters architectures out that are not supported or are not in the preferences/requirements/inputs.\r\n        // Strong if first equals the earliest architecture in the allowed list and second does not [default means the system architecture]\r\n        // Weak if first is better match for system architecture than second\r\n        AddComparator(MachineArchitectureComparator::Create(options));\r\n        // Filters installer types out that are not in preferences or requirements.\r\n        // Only applies when preference exists:\r\n        // Weak if first is in preference list and second is not\r\n        AddComparator(InstallerTypeComparator::Create(options));\r\n    }\r\n\r\n    InstallerAndInapplicabilities ManifestComparator::GetPreferredInstaller(const Manifest& manifest)\r\n    {\r\n        AICLI_LOG(CLI, Verbose, << \"Starting installer selection.\");\r\n\r\n        const ManifestInstaller* result = nullptr;\r\n        std::vector<InapplicabilityFlags> inapplicabilitiesInstallers;\r\n\r\n        for (const auto& installer : manifest.Installers)\r\n        {\r\n            auto inapplicabilityInstaller = IsApplicable(installer);\r\n            if (inapplicabilityInstaller == InapplicabilityFlags::None)\r\n            {\r\n                if (!result || IsFirstBetter(installer, *result))\r\n                {\r\n                    AICLI_LOG(CLI, Verbose, << \"Installer \" << installer << \" is current best choice\");\r\n                    result = &installer;\r\n                }\r\n            }\r\n            else\r\n            {\r\n                inapplicabilitiesInstallers.push_back(inapplicabilityInstaller);\r\n            }\r\n        }\r\n\r\n        if (!result)\r\n        {\r\n            return { {}, std::move(inapplicabilitiesInstallers) };\r\n        }\r\n\r\n        return { *result, std::move(inapplicabilitiesInstallers) };\r\n    }\r\n\r\n    InapplicabilityFlags ManifestComparator::IsApplicable(const ManifestInstaller& installer)\r\n    {\r\n        InapplicabilityFlags inapplicabilityResult = InapplicabilityFlags::None;\r\n\r\n        for (const auto& filter : m_filters)\r\n        {\r\n            auto inapplicability = filter->IsApplicable(installer);\r\n            if (inapplicability != InapplicabilityFlags::None)\r\n            {\r\n                AICLI_LOG(CLI, Verbose, << \"Installer \" << installer << \" not applicable: \" << filter->ExplainInapplicable(installer));\r\n                WI_SetAllFlags(inapplicabilityResult, inapplicability);\r\n            }\r\n        }\r\n\r\n        return inapplicabilityResult;\r\n    }\r\n\r\n    bool ManifestComparator::IsFirstBetter(\r\n        const ManifestInstaller& first,\r\n        const ManifestInstaller& second)\r\n    {\r\n        // The priority will still be used as a tie-break between weak results.\r\n        std::optional<std::string_view> firstWeakComparator;\r\n        bool firstWeakComparatorResult = false;\r\n\r\n        for (auto comparator : m_comparators)\r\n        {\r\n            details::ComparisonResult forwardCompare = comparator->IsFirstBetter(first, second);\r\n            details::ComparisonResult reverseCompare = comparator->IsFirstBetter(second, first);\r\n\r\n            // Should not happen, but if it does it points at a serious bug that should be fixed.\r\n            if (forwardCompare != details::ComparisonResult::Negative && reverseCompare != details::ComparisonResult::Negative)\r\n            {\r\n                AICLI_LOG(CLI, Error, << \"Installer \" << first << \" and \" << second << \" are both better than each other?\");\r\n                THROW_HR(E_UNEXPECTED);\r\n            }\r\n\r\n            if (forwardCompare == details::ComparisonResult::StrongPositive)\r\n            {\r\n                AICLI_LOG(CLI, Verbose, << \"Installer \" << first << \" is better [strong] than \" << second << \" due to: \" << comparator->Name());\r\n                return true;\r\n            }\r\n\r\n            if (reverseCompare == details::ComparisonResult::StrongPositive)\r\n            {\r\n                // Second is better by this comparator, don't allow a lower priority one to override that.\r\n                AICLI_LOG(CLI, Verbose, << \"Installer \" << second << \" is better [strong] than \" << first << \" due to: \" << comparator->Name());\r\n                return false;\r\n            }\r\n\r\n            // Save the first weak result that we get\r\n            if (!firstWeakComparator)\r\n            {\r\n                if (forwardCompare == details::ComparisonResult::WeakPositive)\r\n                {\r\n                    firstWeakComparator = comparator->Name();\r\n                    firstWeakComparatorResult = true;\r\n                }\r\n                else if (reverseCompare == details::ComparisonResult::WeakPositive)\r\n                {\r\n                    firstWeakComparator = comparator->Name();\r\n                    firstWeakComparatorResult = false;\r\n                }\r\n            }\r\n        }\r\n\r\n        // If we found a weak result (and no strong result because we made it here), return it.\r\n        if (firstWeakComparator)\r\n        {\r\n            if (firstWeakComparatorResult)\r\n            {\r\n                AICLI_LOG(CLI, Verbose, << \"Installer \" << first << \" is better [weak] than \" << second << \" due to: \" << *firstWeakComparator);\r\n            }\r\n            else\r\n            {\r\n                AICLI_LOG(CLI, Verbose, << \"Installer \" << second << \" is better [weak] than \" << first << \" due to: \" << *firstWeakComparator);\r\n            }\r\n\r\n            return firstWeakComparatorResult;\r\n        }\r\n\r\n        // Equal, and thus not better\r\n        AICLI_LOG(CLI, Verbose, << \"Installer \" << first << \" and \" << second << \" are equivalent in priority\");\r\n        return false;\r\n    }\r\n\r\n    void ManifestComparator::AddFilter(std::unique_ptr<details::FilterField>&& filter)\r\n    {\r\n        if (filter)\r\n        {\r\n            m_filters.emplace_back(std::move(filter));\r\n        }\r\n    }\r\n\r\n    void ManifestComparator::AddComparator(std::unique_ptr<details::ComparisonField>&& comparator)\r\n    {\r\n        if (comparator)\r\n        {\r\n            m_comparators.push_back(comparator.get());\r\n            m_filters.emplace_back(std::move(comparator));\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Manifest/ManifestSchemaValidation.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"winget/Yaml.h\"\r\n#include \"winget/JsonSchemaValidation.h\"\r\n#include \"winget/ManifestCommon.h\"\r\n#include \"winget/ManifestSchemaValidation.h\"\r\n#include \"winget/ManifestYamlParser.h\"\r\n#include \"winget/Resources.h\"\r\n\r\n#include <ManifestSchema.h>\r\n\r\nnamespace AppInstaller::Manifest::YamlParser\r\n{\r\n    using namespace std::string_view_literals;\r\n\r\n    namespace\r\n    {\r\n        enum class YamlScalarType\r\n        {\r\n            String,\r\n            Int,\r\n            Bool\r\n        };\r\n\r\n        // List of fields that use non string scalar types\r\n        const std::map<std::string_view, YamlScalarType> ManifestFieldTypes =\r\n        {\r\n            { \"InstallerSuccessCodes\"sv, YamlScalarType::Int },\r\n            { \"InstallerAbortsTerminal\"sv, YamlScalarType::Bool },\r\n            { \"InstallLocationRequired\"sv, YamlScalarType::Bool },\r\n            { \"RequireExplicitUpgrade\"sv, YamlScalarType::Bool },\r\n            { \"DisplayInstallWarnings\"sv, YamlScalarType::Bool },\r\n            { \"InstallerReturnCode\"sv, YamlScalarType::Int },\r\n            { \"DownloadCommandProhibited\", YamlScalarType::Bool },\r\n            { \"ArchiveBinariesDependOnPath\", YamlScalarType::Bool }\r\n        };\r\n\r\n        YamlScalarType GetManifestScalarValueType(const std::string& key)\r\n        {\r\n            auto iter = ManifestFieldTypes.find(key);\r\n            if (iter != ManifestFieldTypes.end())\r\n            {\r\n                return iter->second;\r\n            }\r\n\r\n            return YamlScalarType::String;\r\n        }\r\n\r\n        Json::Value YamlScalarNodeToJson(const YAML::Node& scalarNode, YamlScalarType scalarType)\r\n        {\r\n            if (scalarType == YamlScalarType::Int)\r\n            {\r\n                return Json::Value(scalarNode.as<int>());\r\n            }\r\n            else if (scalarType == YamlScalarType::Bool)\r\n            {\r\n                return Json::Value(scalarNode.as<bool>());\r\n            }\r\n            else\r\n            {\r\n                return Json::Value(scalarNode.as<std::string>());\r\n            }\r\n        }\r\n\r\n        Json::Value ManifestYamlNodeToJson(const YAML::Node& rootNode, YamlScalarType scalarType = YamlScalarType::String)\r\n        {\r\n            Json::Value result;\r\n\r\n            if (rootNode.IsNull())\r\n            {\r\n                result = Json::Value::nullSingleton();\r\n            }\r\n            else if (rootNode.IsMap())\r\n            {\r\n                for (auto const& keyValuePair : rootNode.Mapping())\r\n                {\r\n                    // We only support string type as key in our manifest\r\n                    auto key = keyValuePair.first.as<std::string>();\r\n                    result[keyValuePair.first.as<std::string>()] = ManifestYamlNodeToJson(keyValuePair.second, GetManifestScalarValueType(key));\r\n                }\r\n            }\r\n            else if (rootNode.IsSequence())\r\n            {\r\n                for (auto const& value : rootNode.Sequence())\r\n                {\r\n                    result.append(ManifestYamlNodeToJson(value, scalarType));\r\n                }\r\n            }\r\n            else if (rootNode.IsScalar())\r\n            {\r\n                result = YamlScalarNodeToJson(rootNode, scalarType);\r\n            }\r\n            else\r\n            {\r\n                THROW_HR(E_UNEXPECTED);\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        std::vector<ValidationError> ParseSchemaHeaderString(const YamlManifestInfo& manifestInfo, const ValidationError::Level& errorLevel, std::string& schemaHeaderUrlString)\r\n        {\r\n            std::vector<ValidationError> errors;\r\n            std::string schemaHeader = manifestInfo.DocumentSchemaHeader.SchemaHeader;\r\n\r\n            // Remove the leading '#' and any leading/trailing whitespaces\r\n            if (schemaHeader[0] == '#')\r\n            {\r\n                schemaHeader = schemaHeader.substr(1); // Remove the leading '#'\r\n                schemaHeader = Utility::Trim(schemaHeader); // Trim leading/trailing whitespaces\r\n            }\r\n\r\n            // Parse the schema header string as YAML string to get the schema header URL\r\n            try\r\n            {\r\n                auto root = YAML::Load(schemaHeader);\r\n\r\n                if (root.IsNull() || (!root.IsNull() && !root.IsDefined()))\r\n                {\r\n                    errors.emplace_back(ValidationError::MessageContextValueLineLevelWithFile(ManifestError::InvalidSchemaHeader, \"\", schemaHeader, manifestInfo.DocumentSchemaHeader.Mark.line, manifestInfo.DocumentSchemaHeader.Mark.column, errorLevel, manifestInfo.FileName));\r\n                }\r\n                else\r\n                {\r\n                    schemaHeaderUrlString = root[YAML::DocumentSchemaHeader::YamlLanguageServerKey].as<std::string>();\r\n                }\r\n            }\r\n            catch (const YAML::Exception&)\r\n            {\r\n                errors.emplace_back(ValidationError::MessageContextValueLineLevelWithFile(ManifestError::InvalidSchemaHeader, \"\", schemaHeader, manifestInfo.DocumentSchemaHeader.Mark.line, manifestInfo.DocumentSchemaHeader.Mark.column, errorLevel, manifestInfo.FileName));\r\n            }\r\n            catch (const std::exception&)\r\n            {\r\n                errors.emplace_back(ValidationError::MessageContextValueLineLevelWithFile(ManifestError::InvalidSchemaHeader, \"\", schemaHeader, manifestInfo.DocumentSchemaHeader.Mark.line, manifestInfo.DocumentSchemaHeader.Mark.column, errorLevel, manifestInfo.FileName));\r\n            }\r\n\r\n            return errors;\r\n        }\r\n\r\n        bool ParseSchemaHeaderUrl(const std::string& schemaHeaderValue, std::string& schemaType, std::string& schemaVersion)\r\n        {\r\n            // Use regex to match the pattern of @\"winget-manifest\\.(?<type>\\w+)\\.(?<version>[\\d\\.]+)\\.schema\\.json$\"\r\n            std::regex schemaUrlPattern(R\"(winget-manifest\\.(\\w+)\\.([\\d\\.]+)\\.schema\\.json$)\");\r\n            std::smatch match;\r\n\r\n            if (std::regex_search(schemaHeaderValue, match, schemaUrlPattern))\r\n            {\r\n                schemaType = match[1].str();\r\n                schemaVersion = match[2].str();\r\n                return true;\r\n            }\r\n\r\n            return false;\r\n        }\r\n\r\n        std::vector<ValidationError> ValidateSchemaHeaderType(const std::string& headerManifestType, const ManifestTypeEnum& expectedManifestType, const YamlManifestInfo& manifestInfo, ValidationError::Level errorLevel)\r\n        {\r\n            std::vector<ValidationError> errors;\r\n            ManifestTypeEnum actualManifestType = ConvertToManifestTypeEnum(headerManifestType);\r\n            size_t schemaHeaderTypeIndex = manifestInfo.DocumentSchemaHeader.SchemaHeader.find(headerManifestType) + 1;\r\n\r\n            if (actualManifestType != expectedManifestType)\r\n            {\r\n                errors.emplace_back(ValidationError::MessageContextValueLineLevelWithFile(ManifestError::SchemaHeaderManifestTypeMismatch, \"\", headerManifestType, manifestInfo.DocumentSchemaHeader.Mark.line, schemaHeaderTypeIndex, errorLevel, manifestInfo.FileName));\r\n            }\r\n\r\n            return errors;\r\n        }\r\n\r\n        std::vector<ValidationError> ValidateSchemaHeaderVersion(const std::string& headerManifestVersion, const ManifestVer& expectedManifestVersion, const YamlManifestInfo& manifestInfo, ValidationError::Level errorLevel)\r\n        {\r\n            std::vector<ValidationError> errors;\r\n            ManifestVer actualHeaderVersion(headerManifestVersion);\r\n            size_t schemaHeaderVersionIndex = manifestInfo.DocumentSchemaHeader.SchemaHeader.find(headerManifestVersion) + 1;\r\n\r\n            if (actualHeaderVersion != expectedManifestVersion)\r\n            {\r\n                errors.emplace_back(ValidationError::MessageContextValueLineLevelWithFile(ManifestError::SchemaHeaderManifestVersionMismatch, \"\", headerManifestVersion, manifestInfo.DocumentSchemaHeader.Mark.line, schemaHeaderVersionIndex, errorLevel, manifestInfo.FileName));\r\n            }\r\n\r\n            return errors;\r\n        }\r\n\r\n        bool IsValidSchemaHeaderUrl(const std::string& schemaHeaderUrlString, const YamlManifestInfo& manifestInfo, const ManifestVer& manifestVersion)\r\n        {\r\n            // Load the schema file to compare the schema header URL with the schema ID in the schema file\r\n            Json::Value schemaFile = LoadSchemaDoc(manifestVersion, manifestInfo.ManifestType);\r\n\r\n            if (schemaFile.isMember(\"$id\"))\r\n            {\r\n                std::string schemaId = schemaFile[\"$id\"].asString();\r\n\r\n                // Prefix schema ID with \"schema=\" to match the schema header URL pattern and compare it with the schema header URL\r\n                schemaId = \"$schema=\" + schemaId;\r\n\r\n                if (Utility::CaseInsensitiveEquals(schemaId, schemaHeaderUrlString))\r\n                {\r\n                    return true;\r\n                }\r\n            }\r\n\r\n            return false;\r\n        }\r\n\r\n        ValidationError GetSchemaHeaderUrlPatternMismatchError(const std::string& schemaHeaderUrlString, const YamlManifestInfo& manifestInfo, const ValidationError::Level& errorLevel)\r\n        {\r\n            size_t schemaHeaderUrlIndex = manifestInfo.DocumentSchemaHeader.SchemaHeader.find(schemaHeaderUrlString) + 1;\r\n\r\n            return ValidationError::MessageContextValueLineLevelWithFile(ManifestError::SchemaHeaderUrlPatternMismatch, \"\", manifestInfo.DocumentSchemaHeader.SchemaHeader, manifestInfo.DocumentSchemaHeader.Mark.line, schemaHeaderUrlIndex, errorLevel, manifestInfo.FileName);\r\n        }\r\n\r\n        std::vector<ValidationError> ValidateSchemaHeaderUrl(const YamlManifestInfo& manifestInfo, const ManifestVer& manifestVersion, const ValidationError::Level& errorLevel)\r\n        {\r\n            std::vector<ValidationError> errors;\r\n\r\n            std::string schemaHeaderUrlString;\r\n            // Parse the schema header string to get the schema header URL\r\n            auto parserErrors = ParseSchemaHeaderString(manifestInfo, errorLevel, schemaHeaderUrlString);\r\n            std::move(parserErrors.begin(), parserErrors.end(), std::inserter(errors, errors.end()));\r\n\r\n            if (!errors.empty())\r\n            {\r\n                return errors;\r\n            }\r\n\r\n            std::string manifestTypeString;\r\n            std::string manifestVersionString;\r\n\r\n            // Parse the schema header URL to get the manifest type and version\r\n            if (ParseSchemaHeaderUrl(schemaHeaderUrlString, manifestTypeString, manifestVersionString))\r\n            {\r\n                auto headerManifestTypeErrors = ValidateSchemaHeaderType(manifestTypeString, manifestInfo.ManifestType, manifestInfo, errorLevel);\r\n                std::move(headerManifestTypeErrors.begin(), headerManifestTypeErrors.end(), std::inserter(errors, errors.end()));\r\n\r\n                auto headerManifestVersionErrors = ValidateSchemaHeaderVersion(manifestVersionString, manifestVersion, manifestInfo, errorLevel);\r\n                std::move(headerManifestVersionErrors.begin(), headerManifestVersionErrors.end(), std::inserter(errors, errors.end()));\r\n\r\n                // Finally, match the entire schema header URL with the schema ID in the schema file to ensure the URL domain matches the schema definition file.\r\n                if (!IsValidSchemaHeaderUrl(schemaHeaderUrlString, manifestInfo, manifestVersion))\r\n                {\r\n                    errors.emplace_back(GetSchemaHeaderUrlPatternMismatchError(schemaHeaderUrlString, manifestInfo, errorLevel));\r\n                }\r\n            }\r\n            else\r\n            {\r\n                errors.emplace_back(GetSchemaHeaderUrlPatternMismatchError(schemaHeaderUrlString, manifestInfo, errorLevel));\r\n            }\r\n\r\n            return errors;\r\n        }\r\n\r\n        std::vector<ValidationError> ValidateYamlManifestSchemaHeader(const YamlManifestInfo& manifestInfo, const ManifestVer& manifestVersion, ValidationError::Level errorLevel)\r\n        {\r\n            std::vector<ValidationError> errors;\r\n            std::string schemaHeaderString;\r\n\r\n            if (manifestInfo.DocumentSchemaHeader.SchemaHeader.empty())\r\n            {\r\n                errors.emplace_back(ValidationError::MessageLevelWithFile(ManifestError::SchemaHeaderNotFound, errorLevel, manifestInfo.FileName));\r\n                return errors;\r\n            }\r\n\r\n            auto parserErrors = ValidateSchemaHeaderUrl(manifestInfo, manifestVersion, errorLevel);\r\n            std::move(parserErrors.begin(), parserErrors.end(), std::inserter(errors, errors.end()));\r\n\r\n            return errors;\r\n        }\r\n    }\r\n\r\n    Json::Value LoadSchemaDoc(const ManifestVer& manifestVersion, ManifestTypeEnum manifestType)\r\n    {\r\n        int idx = MANIFESTSCHEMA_NO_RESOURCE;\r\n        std::map<ManifestTypeEnum, int> resourceMap;\r\n\r\n        if (manifestVersion >= ManifestVer{ s_ManifestVersionV1_28 })\r\n        {\r\n            resourceMap = {\r\n                { ManifestTypeEnum::Singleton, IDX_MANIFEST_SCHEMA_V1_28_SINGLETON },\r\n                { ManifestTypeEnum::Version, IDX_MANIFEST_SCHEMA_V1_28_VERSION },\r\n                { ManifestTypeEnum::Installer, IDX_MANIFEST_SCHEMA_V1_28_INSTALLER },\r\n                { ManifestTypeEnum::DefaultLocale, IDX_MANIFEST_SCHEMA_V1_28_DEFAULTLOCALE },\r\n                { ManifestTypeEnum::Locale, IDX_MANIFEST_SCHEMA_V1_28_LOCALE },\r\n            };\r\n        }\r\n        else if (manifestVersion >= ManifestVer{ s_ManifestVersionV1_12 })\r\n        {\r\n            resourceMap = {\r\n                { ManifestTypeEnum::Singleton, IDX_MANIFEST_SCHEMA_V1_12_SINGLETON },\r\n                { ManifestTypeEnum::Version, IDX_MANIFEST_SCHEMA_V1_12_VERSION },\r\n                { ManifestTypeEnum::Installer, IDX_MANIFEST_SCHEMA_V1_12_INSTALLER },\r\n                { ManifestTypeEnum::DefaultLocale, IDX_MANIFEST_SCHEMA_V1_12_DEFAULTLOCALE },\r\n                { ManifestTypeEnum::Locale, IDX_MANIFEST_SCHEMA_V1_12_LOCALE },\r\n            };\r\n        }\r\n        else if (manifestVersion >= ManifestVer{ s_ManifestVersionV1_10 })\r\n        {\r\n            resourceMap = {\r\n                { ManifestTypeEnum::Singleton, IDX_MANIFEST_SCHEMA_V1_10_SINGLETON },\r\n                { ManifestTypeEnum::Version, IDX_MANIFEST_SCHEMA_V1_10_VERSION },\r\n                { ManifestTypeEnum::Installer, IDX_MANIFEST_SCHEMA_V1_10_INSTALLER },\r\n                { ManifestTypeEnum::DefaultLocale, IDX_MANIFEST_SCHEMA_V1_10_DEFAULTLOCALE },\r\n                { ManifestTypeEnum::Locale, IDX_MANIFEST_SCHEMA_V1_10_LOCALE },\r\n            };\r\n        }\r\n        else if (manifestVersion >= ManifestVer{ s_ManifestVersionV1_9 })\r\n        {\r\n            resourceMap = {\r\n                { ManifestTypeEnum::Singleton, IDX_MANIFEST_SCHEMA_V1_9_SINGLETON },\r\n                { ManifestTypeEnum::Version, IDX_MANIFEST_SCHEMA_V1_9_VERSION },\r\n                { ManifestTypeEnum::Installer, IDX_MANIFEST_SCHEMA_V1_9_INSTALLER },\r\n                { ManifestTypeEnum::DefaultLocale, IDX_MANIFEST_SCHEMA_V1_9_DEFAULTLOCALE },\r\n                { ManifestTypeEnum::Locale, IDX_MANIFEST_SCHEMA_V1_9_LOCALE },\r\n            };\r\n        }\r\n        else if (manifestVersion >= ManifestVer{ s_ManifestVersionV1_7 })\r\n        {\r\n            resourceMap = {\r\n                { ManifestTypeEnum::Singleton, IDX_MANIFEST_SCHEMA_V1_7_SINGLETON },\r\n                { ManifestTypeEnum::Version, IDX_MANIFEST_SCHEMA_V1_7_VERSION },\r\n                { ManifestTypeEnum::Installer, IDX_MANIFEST_SCHEMA_V1_7_INSTALLER },\r\n                { ManifestTypeEnum::DefaultLocale, IDX_MANIFEST_SCHEMA_V1_7_DEFAULTLOCALE },\r\n                { ManifestTypeEnum::Locale, IDX_MANIFEST_SCHEMA_V1_7_LOCALE },\r\n            };\r\n        }\r\n        else if (manifestVersion >= ManifestVer{ s_ManifestVersionV1_6 })\r\n        {\r\n            resourceMap = {\r\n                { ManifestTypeEnum::Singleton, IDX_MANIFEST_SCHEMA_V1_6_SINGLETON },\r\n                { ManifestTypeEnum::Version, IDX_MANIFEST_SCHEMA_V1_6_VERSION },\r\n                { ManifestTypeEnum::Installer, IDX_MANIFEST_SCHEMA_V1_6_INSTALLER },\r\n                { ManifestTypeEnum::DefaultLocale, IDX_MANIFEST_SCHEMA_V1_6_DEFAULTLOCALE },\r\n                { ManifestTypeEnum::Locale, IDX_MANIFEST_SCHEMA_V1_6_LOCALE },\r\n            };\r\n        }\r\n        else if (manifestVersion >= ManifestVer{ s_ManifestVersionV1_5 })\r\n        {\r\n            resourceMap = {\r\n                { ManifestTypeEnum::Singleton, IDX_MANIFEST_SCHEMA_V1_5_SINGLETON },\r\n                { ManifestTypeEnum::Version, IDX_MANIFEST_SCHEMA_V1_5_VERSION },\r\n                { ManifestTypeEnum::Installer, IDX_MANIFEST_SCHEMA_V1_5_INSTALLER },\r\n                { ManifestTypeEnum::DefaultLocale, IDX_MANIFEST_SCHEMA_V1_5_DEFAULTLOCALE },\r\n                { ManifestTypeEnum::Locale, IDX_MANIFEST_SCHEMA_V1_5_LOCALE },\r\n            };\r\n        }\r\n        else if (manifestVersion >= ManifestVer{ s_ManifestVersionV1_4 })\r\n        {\r\n            resourceMap = {\r\n                { ManifestTypeEnum::Singleton, IDX_MANIFEST_SCHEMA_V1_4_SINGLETON },\r\n                { ManifestTypeEnum::Version, IDX_MANIFEST_SCHEMA_V1_4_VERSION },\r\n                { ManifestTypeEnum::Installer, IDX_MANIFEST_SCHEMA_V1_4_INSTALLER },\r\n                { ManifestTypeEnum::DefaultLocale, IDX_MANIFEST_SCHEMA_V1_4_DEFAULTLOCALE },\r\n                { ManifestTypeEnum::Locale, IDX_MANIFEST_SCHEMA_V1_4_LOCALE },\r\n            };\r\n        }\r\n        else if (manifestVersion >= ManifestVer{ s_ManifestVersionV1_2 })\r\n        {\r\n            resourceMap = {\r\n                { ManifestTypeEnum::Singleton, IDX_MANIFEST_SCHEMA_V1_2_SINGLETON },\r\n                { ManifestTypeEnum::Version, IDX_MANIFEST_SCHEMA_V1_2_VERSION },\r\n                { ManifestTypeEnum::Installer, IDX_MANIFEST_SCHEMA_V1_2_INSTALLER },\r\n                { ManifestTypeEnum::DefaultLocale, IDX_MANIFEST_SCHEMA_V1_2_DEFAULTLOCALE },\r\n                { ManifestTypeEnum::Locale, IDX_MANIFEST_SCHEMA_V1_2_LOCALE },\r\n            };\r\n        }\r\n        else if (manifestVersion >= ManifestVer{ s_ManifestVersionV1_1 })\r\n        {\r\n            resourceMap = {\r\n                { ManifestTypeEnum::Singleton, IDX_MANIFEST_SCHEMA_V1_1_SINGLETON },\r\n                { ManifestTypeEnum::Version, IDX_MANIFEST_SCHEMA_V1_1_VERSION },\r\n                { ManifestTypeEnum::Installer, IDX_MANIFEST_SCHEMA_V1_1_INSTALLER },\r\n                { ManifestTypeEnum::DefaultLocale, IDX_MANIFEST_SCHEMA_V1_1_DEFAULTLOCALE },\r\n                { ManifestTypeEnum::Locale, IDX_MANIFEST_SCHEMA_V1_1_LOCALE },\r\n            };\r\n        }\r\n        else if (manifestVersion >= ManifestVer{ s_ManifestVersionV1 })\r\n        {\r\n            resourceMap = {\r\n                { ManifestTypeEnum::Singleton, IDX_MANIFEST_SCHEMA_V1_SINGLETON },\r\n                { ManifestTypeEnum::Version, IDX_MANIFEST_SCHEMA_V1_VERSION },\r\n                { ManifestTypeEnum::Installer, IDX_MANIFEST_SCHEMA_V1_INSTALLER },\r\n                { ManifestTypeEnum::DefaultLocale, IDX_MANIFEST_SCHEMA_V1_DEFAULTLOCALE },\r\n                { ManifestTypeEnum::Locale, IDX_MANIFEST_SCHEMA_V1_LOCALE },\r\n            };\r\n        }\r\n        else\r\n        {\r\n            resourceMap = {\r\n                { ManifestTypeEnum::Preview, IDX_MANIFEST_SCHEMA_PREVIEW },\r\n            };\r\n        }\r\n\r\n        auto iter = resourceMap.find(manifestType);\r\n        if (iter != resourceMap.end())\r\n        {\r\n            idx = iter->second;\r\n        }\r\n        else\r\n        {\r\n            THROW_HR(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED));\r\n        }\r\n\r\n        std::string_view schemaStr = Resource::GetResourceAsString(idx, MANIFESTSCHEMA_RESOURCE_TYPE);\r\n        return JsonSchema::LoadSchemaDoc(schemaStr);\r\n    }\r\n\r\n    std::vector<ValidationError> ValidateAgainstSchema(const std::vector<YamlManifestInfo>& manifestList, const ManifestVer& manifestVersion)\r\n    {\r\n        std::vector<ValidationError> errors;\r\n        // A list of schema validator to avoid multiple loadings of same schema\r\n        std::map<ManifestTypeEnum, valijson::Schema> schemaList;\r\n\r\n        for (const auto& entry : manifestList)\r\n        {\r\n            if (entry.ManifestType == ManifestTypeEnum::Shadow)\r\n            {\r\n                // There's no schema for a shadow manifest.\r\n                continue;\r\n            }\r\n\r\n            if (schemaList.find(entry.ManifestType) == schemaList.end())\r\n            {\r\n                // Copy constructor of valijson::Schema was private\r\n                valijson::Schema& newSchema = schemaList.emplace(\r\n                    std::piecewise_construct, std::make_tuple(entry.ManifestType), std::make_tuple()).first->second;\r\n                Json::Value schemaJson = LoadSchemaDoc(manifestVersion, entry.ManifestType);\r\n                JsonSchema::PopulateSchema(schemaJson, newSchema);\r\n            }\r\n\r\n            const auto& schema = schemaList.find(entry.ManifestType)->second;\r\n            Json::Value manifestJson = ManifestYamlNodeToJson(entry.Root);\r\n            valijson::ValidationResults results;\r\n\r\n            if (!JsonSchema::Validate(schema, manifestJson, results))\r\n            {\r\n                errors.emplace_back(ValidationError::MessageContextWithFile(ManifestError::SchemaError, JsonSchema::GetErrorStringFromResults(results), entry.FileName));\r\n            }\r\n        }\r\n\r\n        return errors;\r\n    }\r\n\r\n    std::vector<ValidationError> ValidateYamlManifestsSchemaHeader(const std::vector<YamlManifestInfo>& manifestList, const ManifestVer& manifestVersion, bool treatErrorAsWarning)\r\n    {\r\n        std::vector<ValidationError> errors;\r\n        ValidationError::Level errorLevel = treatErrorAsWarning ? ValidationError::Level::Warning : ValidationError::Level::Error;\r\n\r\n        // Read the manifest schema header and ensure it exists\r\n        for (const auto& entry : manifestList)\r\n        {\r\n            if (entry.ManifestType == ManifestTypeEnum::Shadow)\r\n            {\r\n                // There's no schema for a shadow manifest.\r\n                continue;\r\n            }\r\n\r\n            auto schemaHeaderErrors = ValidateYamlManifestSchemaHeader(entry, manifestVersion, errorLevel);\r\n            std::move(schemaHeaderErrors.begin(), schemaHeaderErrors.end(), std::inserter(errors, errors.end()));\r\n        }\r\n\r\n        return errors;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Manifest/ManifestValidation.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"AppInstallerLogging.h\"\r\n#include \"AppInstallerMsixInfo.h\"\r\n#include \"winget/MsixManifest.h\"\r\n#include \"winget/ManifestValidation.h\"\r\n#include \"winget/MsixManifestValidation.h\"\r\n#include \"winget/Locale.h\"\r\n#include \"winget/Filesystem.h\"\r\n\r\nnamespace AppInstaller::Manifest\r\n{\r\n    namespace\r\n    {\r\n        constexpr std::array<std::wstring_view, 1> s_AllowedPortableFiletypes = {\r\n            L\".exe\",\r\n        };\r\n\r\n        constexpr std::array<std::wstring_view, 5> s_AllowedFontFiletypes = {\r\n            L\".otf\",         // OpenType Font\r\n            L\".ttf\",         // TrueType Font\r\n            L\".fnt\",         // Font\r\n            L\".ttc\",         // TrueType Font Collection\r\n            L\".otc\",         // OpenType Font Collection\r\n        };\r\n\r\n        const auto& GetErrorIdToMessageMap()\r\n        {\r\n            static std::map<AppInstaller::StringResource::StringId, std::string_view> ErrorIdToMessageMap = {\r\n                { AppInstaller::Manifest::ManifestError::InvalidRootNode, \"Encountered unexpected root node.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::FieldUnknown, \"Unknown field.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::FieldIsNotPascalCase, \"All field names should be PascalCased.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::FieldDuplicate, \"Duplicate field found in the manifest.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::RequiredFieldEmpty, \"Required field with empty value.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::RequiredFieldMissing,  \"Required field missing.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::InvalidFieldValue, \"Invalid field value.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::ExeInstallerMissingSilentSwitches, \"Silent and SilentWithProgress switches are not specified for InstallerType exe. Please make sure the installer can run unattended.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::FieldNotSupported, \"Field is not supported.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::FieldValueNotSupported, \"Field value is not supported.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::DuplicateInstallerEntry, \"Duplicate installer entry found.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::DuplicateInstallerHash, \"Multiple Installer URLs found with the same InstallerSha256. Please ensure the accuracy of the URLs.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::InstallerTypeDoesNotSupportPackageFamilyName, \"The specified installer type does not support PackageFamilyName.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::InstallerTypeDoesNotSupportProductCode, \"The specified installer type does not support ProductCode.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::InstallerTypeDoesNotWriteAppsAndFeaturesEntry, \"The specified installer type does not write to Apps and Features entry.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::IncompleteMultiFileManifest, \"The multi file manifest is incomplete.A multi file manifest must contain at least version, installer and defaultLocale manifest.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::InconsistentMultiFileManifestFieldValue, \"The multi file manifest has inconsistent field values.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::DuplicatePortableCommandAlias, \"Duplicate portable command alias found.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::DuplicateRelativeFilePath, \"Duplicate relative file path found.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::DuplicateMultiFileManifestType, \"The multi file manifest should contain only one file with the particular ManifestType.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::DuplicateMultiFileManifestLocale, \"The multi file manifest contains duplicate PackageLocale.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::UnsupportedMultiFileManifestType, \"The multi file manifest should not contain file with the particular ManifestType.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::InconsistentInstallerHash, \"The values of InstallerSha256 do not match for all instances of the same InstallerUrl.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::InconsistentMultiFileManifestDefaultLocale, \"DefaultLocale value in version manifest does not match PackageLocale value in defaultLocale manifest.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::FieldFailedToProcess, \"Failed to process field.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::InvalidBcp47Value, \"The locale value is not a well formed bcp47 language tag.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::BothAllowedAndExcludedMarketsDefined, \"Both AllowedMarkets and ExcludedMarkets defined.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::DuplicateReturnCodeEntry, \"Duplicate installer return code found.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::FieldRequireVerifiedPublisher, \"Field usage requires verified publishers.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::SingleManifestPackageHasDependencies, \"Package has a single manifest and is a dependency of other manifests.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::MultiManifestPackageHasDependencies, \"Deleting the manifest will be break the following dependencies.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::MissingManifestDependenciesNode, \"Dependency not found: \"sv },\r\n                { AppInstaller::Manifest::ManifestError::NoSuitableMinVersionDependency,\"No Suitable Minimum Version: \"sv },\r\n                { AppInstaller::Manifest::ManifestError::FoundDependencyLoop, \"Loop found.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::ExceededAppsAndFeaturesEntryLimit, \"Only zero or one entry for Apps and Features may be specified for InstallerType portable.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::ExceededCommandsLimit, \"Only zero or one value for Commands may be specified for InstallerType portable.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::ScopeNotSupported, \"Scope is not supported for InstallerType portable.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::InstallerMsixInconsistencies, \"Inconsistent value in the manifest.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::OptionalFieldMissing, \"Optional field missing.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::InstallerFailedToProcess, \"Failed to process installer.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::NoSupportedPlatforms, \"No supported platforms.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::ApproximateVersionNotAllowed, \"Approximate version not allowed.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::ArpVersionOverlapWithIndex, \"DisplayVersion declared in the manifest has overlap with existing DisplayVersion range in the index. Existing DisplayVersion range in index: \"sv },\r\n                { AppInstaller::Manifest::ManifestError::ArpVersionValidationInternalError, \"Internal error while validating DisplayVersion against index.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::ExceededNestedInstallerFilesLimit, \"Only one entry for NestedInstallerFiles can be specified for non-portable InstallerTypes.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::RelativeFilePathEscapesDirectory, \"Relative file path must not point to a location outside of archive directory.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::ArpValidationError, \"Arp Validation Error.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::SchemaError, \"Schema Error.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::MsixSignatureHashFailed, \"Failed to calculate MSIX signature hash.Please verify that the input file is a valid, signed MSIX.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::ShadowManifestNotAllowed, \"Shadow manifest is not allowed.\" },\r\n                { AppInstaller::Manifest::ManifestError::SchemaHeaderNotFound, \"Schema header not found.\" },\r\n                { AppInstaller::Manifest::ManifestError::InvalidSchemaHeader , \"The schema header is invalid. Please verify that the schema header is present and formatted correctly.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::SchemaHeaderManifestTypeMismatch , \"The manifest type in the schema header does not match the ManifestType property value in the manifest.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::SchemaHeaderManifestVersionMismatch, \"The manifest version in the schema header does not match the ManifestVersion property value in the manifest.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::SchemaHeaderUrlPatternMismatch, \"The schema header URL does not match the expected pattern.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::InvalidPortableFiletype, \"The file type of the referenced file is not allowed.\"sv },\r\n                { AppInstaller::Manifest::ManifestError::InvalidFontFiletype, \"The file type of the referenced file is not a supported font file type.\"sv },\r\n            };\r\n\r\n            return ErrorIdToMessageMap;\r\n        }\r\n    }\r\n\r\n    std::vector<ValidationError> ValidateManifest(const Manifest& manifest, bool fullValidation)\r\n    {\r\n        std::vector<ValidationError> resultErrors;\r\n\r\n        // Channel is not supported currently\r\n        if (!manifest.Channel.empty())\r\n        {\r\n            resultErrors.emplace_back(ManifestError::FieldNotSupported, \"Channel\", manifest.Channel);\r\n        }\r\n\r\n        try\r\n        {\r\n            // Version value should be successfully parsed\r\n            Utility::Version testVersion{ manifest.Version };\r\n            if (testVersion.IsApproximate())\r\n            {\r\n                resultErrors.emplace_back(ManifestError::ApproximateVersionNotAllowed, \"PackageVersion\", manifest.Version);\r\n            }\r\n        }\r\n        catch (const std::exception&)\r\n        {\r\n            resultErrors.emplace_back(ManifestError::InvalidFieldValue, \"PackageVersion\", manifest.Version);\r\n        }\r\n\r\n        auto defaultLocErrors = ValidateManifestLocalization(manifest.DefaultLocalization, !fullValidation);\r\n        std::move(defaultLocErrors.begin(), defaultLocErrors.end(), std::inserter(resultErrors, resultErrors.end()));\r\n\r\n        // Comparison function to check duplicate installer entry. {installerType, arch, language and scope} combination is the key.\r\n        // Todo: use the comparator from ManifestComparator when that one is fully implemented.\r\n        auto installerCmp = [](const ManifestInstaller& in1, const ManifestInstaller& in2)\r\n        {\r\n            if (in1.BaseInstallerType != in2.BaseInstallerType)\r\n            {\r\n                return in1.BaseInstallerType < in2.BaseInstallerType;\r\n            }\r\n            else if (IsArchiveType(in1.BaseInstallerType))\r\n            {\r\n                // Compare nested installer type if base installer type is archive.\r\n                if (in1.NestedInstallerType != in2.NestedInstallerType)\r\n                {\r\n                    return in1.NestedInstallerType < in2.NestedInstallerType;\r\n                }\r\n            }\r\n\r\n            if (in1.Arch != in2.Arch)\r\n            {\r\n                return in1.Arch < in2.Arch;\r\n            }\r\n\r\n            if (in1.Locale != in2.Locale)\r\n            {\r\n                return in1.Locale < in2.Locale;\r\n            }\r\n\r\n            // Unknown is considered equal to all other values for uniqueness.\r\n            // If either value is unknown, don't compare them.\r\n            if (in1.Scope != in2.Scope && in1.Scope != ScopeEnum::Unknown && in2.Scope != ScopeEnum::Unknown)\r\n            {\r\n                return in1.Scope < in2.Scope;\r\n            }\r\n\r\n            return false;\r\n        };\r\n\r\n        std::set<ManifestInstaller, decltype(installerCmp)> installerSet(installerCmp);\r\n        bool duplicateInstallerFound = false;\r\n\r\n        // Set up maps for checking uniqueness across hash <-> url pairs\r\n        std::unordered_map<std::string, std::string> urlToChecksum;\r\n        std::unordered_map<std::string, std::string> checksumToUrl;\r\n\r\n        // Validate installers\r\n        for (auto const& installer : manifest.Installers)\r\n        {\r\n            // If not full validation, for future compatibility, skip validating unknown installers.\r\n            if (installer.EffectiveInstallerType() == InstallerTypeEnum::Unknown && !fullValidation)\r\n            {\r\n                continue;\r\n            }\r\n\r\n            if (!duplicateInstallerFound && !installerSet.insert(installer).second)\r\n            {\r\n                AICLI_LOG(Core, Error, << \"Duplicate installer: Type [\" << InstallerTypeToString(installer.EffectiveInstallerType()) <<\r\n                    \"], Architecture [\" << Utility::ToString(installer.Arch) << \"], Locale [\" << installer.Locale <<\r\n                    \"], Scope [\" << ScopeToString(installer.Scope) << \"]\");\r\n\r\n                resultErrors.emplace_back(ManifestError::DuplicateInstallerEntry);\r\n                duplicateInstallerFound = true;\r\n            }\r\n\r\n            if (installer.Arch == Utility::Architecture::Unknown)\r\n            {\r\n                resultErrors.emplace_back(ManifestError::InvalidFieldValue, \"Architecture\");\r\n            }\r\n\r\n            if (installer.EffectiveInstallerType() == InstallerTypeEnum::Unknown)\r\n            {\r\n                resultErrors.emplace_back(ManifestError::InvalidFieldValue, \"InstallerType\");\r\n            }\r\n\r\n            if (installer.UpdateBehavior == UpdateBehaviorEnum::Unknown)\r\n            {\r\n                resultErrors.emplace_back(ManifestError::InvalidFieldValue, \"UpgradeBehavior\");\r\n            }\r\n\r\n            // Validate system reference strings if they are set at the installer level\r\n            // Allow PackageFamilyName to be declared with non msix installers to support nested installer scenarios. But still report as warning to notify user of this uncommon case.\r\n            if (!installer.PackageFamilyName.empty() && !(DoesInstallerTypeUsePackageFamilyName(installer.EffectiveInstallerType()) || DoAnyAppsAndFeaturesEntriesUsePackageFamilyName(installer.AppsAndFeaturesEntries)))\r\n            {\r\n                resultErrors.emplace_back(ManifestError::InstallerTypeDoesNotSupportPackageFamilyName, \"InstallerType\", std::string{ InstallerTypeToString(installer.EffectiveInstallerType()) }, ValidationError::Level::Warning);\r\n            }\r\n\r\n            if (!installer.ProductCode.empty() && !DoesInstallerTypeUseProductCode(installer.EffectiveInstallerType()))\r\n            {\r\n                resultErrors.emplace_back(ManifestError::InstallerTypeDoesNotSupportProductCode, \"InstallerType\", InstallerTypeToString(installer.EffectiveInstallerType()));\r\n            }\r\n\r\n            if (!installer.AppsAndFeaturesEntries.empty() && !DoesInstallerTypeWriteAppsAndFeaturesEntry(installer.EffectiveInstallerType()))\r\n            {\r\n                resultErrors.emplace_back(ManifestError::InstallerTypeDoesNotWriteAppsAndFeaturesEntry, \"InstallerType\", InstallerTypeToString(installer.EffectiveInstallerType()));\r\n            }\r\n\r\n            if (installer.EffectiveInstallerType() == InstallerTypeEnum::MSStore)\r\n            {\r\n                if (fullValidation)\r\n                {\r\n                    // MSStore type is not supported in community repo\r\n                    resultErrors.emplace_back(\r\n                        ManifestError::FieldValueNotSupported, \"InstallerType\",\r\n                        InstallerTypeToString(installer.EffectiveInstallerType()));\r\n                }\r\n\r\n                if (installer.ProductId.empty())\r\n                {\r\n                    resultErrors.emplace_back(ManifestError::RequiredFieldMissing, \"ProductId\");\r\n                }\r\n            }\r\n            else\r\n            {\r\n                // For other types, Url and Sha256 are required\r\n                if (installer.Url.empty())\r\n                {\r\n                    resultErrors.emplace_back(ManifestError::RequiredFieldMissing, \"InstallerUrl\");\r\n                }\r\n                if (installer.Sha256.empty())\r\n                {\r\n                    resultErrors.emplace_back(ManifestError::RequiredFieldMissing, \"InstallerSha256\");\r\n                }\r\n                // ProductId should not be used\r\n                if (!installer.ProductId.empty())\r\n                {\r\n                    resultErrors.emplace_back(ManifestError::FieldNotSupported, \"ProductId\");\r\n                }\r\n\r\n                // Ensure that each URL has a one to one mapping with a Sha256 and\r\n                // warn if a Sha256 has a one to many mapping with a URL\r\n                if (fullValidation && !installer.Url.empty() && !installer.Sha256.empty())\r\n                {\r\n                    std::string checksum = Utility::SHA256::ConvertToString(installer.Sha256);\r\n                    std::string url = installer.Url;\r\n\r\n                    auto [urlIterator, urlInserted] = urlToChecksum.try_emplace(url, checksum);\r\n                    auto [checksumIterator, checksumInserted] = checksumToUrl.try_emplace(checksum, url);\r\n\r\n                    if (!urlInserted && urlIterator->second != checksum)\r\n                    {\r\n                        // If the URL was not inserted, and the value in the map does not match the current Sha256, then\r\n                        // a single URL corresponds to multiple SHA256 and an error should be thrown\r\n                        resultErrors.emplace_back(ManifestError::InconsistentInstallerHash, \"InstallerUrl\", url);\r\n                    }\r\n\r\n                    if (!checksumInserted && checksumIterator->second != url)\r\n                    {\r\n                        // If the SHA256 was not inserted, and the value in the map does not match the current URL, then\r\n                        // a single SHA256 corresponds to multiple URLS and a warning should be thrown\r\n                        resultErrors.emplace_back(ManifestError::DuplicateInstallerHash, \"InstallerSha256\", checksum, ValidationError::Level::Warning);\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (installer.EffectiveInstallerType() == InstallerTypeEnum::Exe &&\r\n                (installer.Switches.find(InstallerSwitchType::SilentWithProgress) == installer.Switches.end() ||\r\n                 installer.Switches.find(InstallerSwitchType::Silent) == installer.Switches.end()))\r\n            {\r\n                resultErrors.emplace_back(ManifestError::ExeInstallerMissingSilentSwitches, ValidationError::Level::Warning);\r\n            }\r\n\r\n            // The command field restriction only applies if the base installer type is Portable.\r\n            if (installer.BaseInstallerType == InstallerTypeEnum::Portable)\r\n            {\r\n                if (installer.Commands.size() > 1)\r\n                {\r\n                    resultErrors.emplace_back(ManifestError::ExceededCommandsLimit);\r\n                }\r\n            }\r\n\r\n            if (installer.EffectiveInstallerType() == InstallerTypeEnum::Portable)\r\n            {\r\n                if (installer.AppsAndFeaturesEntries.size() > 1)\r\n                {\r\n                    resultErrors.emplace_back(ManifestError::ExceededAppsAndFeaturesEntryLimit);\r\n                }\r\n                if (installer.Scope != ScopeEnum::Unknown)\r\n                {\r\n                    resultErrors.emplace_back(ManifestError::ScopeNotSupported, ValidationError::Level::Warning);\r\n                }\r\n            }\r\n\r\n            if (IsArchiveType(installer.BaseInstallerType))\r\n            {\r\n                bool isPortable = installer.NestedInstallerType == InstallerTypeEnum::Portable;\r\n                bool isFont = installer.NestedInstallerType == InstallerTypeEnum::Font;\r\n\r\n                if (installer.NestedInstallerType == InstallerTypeEnum::Unknown)\r\n                {\r\n                    resultErrors.emplace_back(ManifestError::RequiredFieldMissing, \"NestedInstallerType\");\r\n                }\r\n                if (installer.NestedInstallerFiles.size() == 0)\r\n                {\r\n                    resultErrors.emplace_back(ManifestError::RequiredFieldMissing, \"NestedInstallerFiles\");\r\n                }\r\n                if (!isPortable && !isFont && installer.NestedInstallerFiles.size() != 1)\r\n                {\r\n                    resultErrors.emplace_back(ManifestError::ExceededNestedInstallerFilesLimit, \"NestedInstallerFiles\");\r\n                }\r\n\r\n                std::set<std::string> commandAliasSet;\r\n                std::set<std::string> relativeFilePathSet;\r\n\r\n                for (const auto& nestedInstallerFile : installer.NestedInstallerFiles)\r\n                {\r\n                    if (nestedInstallerFile.RelativeFilePath.empty())\r\n                    {\r\n                        resultErrors.emplace_back(ManifestError::RequiredFieldMissing, \"RelativeFilePath\");\r\n                        break;\r\n                    }\r\n\r\n                    // Check that the relative file path does not escape base directory.\r\n                    const std::filesystem::path& basePath = std::filesystem::current_path();\r\n                    const std::filesystem::path& fullPath = basePath / ConvertToUTF16(nestedInstallerFile.RelativeFilePath);\r\n                    if (AppInstaller::Filesystem::PathEscapesBaseDirectory(fullPath, basePath))\r\n                    {\r\n                        resultErrors.emplace_back(ManifestError::RelativeFilePathEscapesDirectory, \"RelativeFilePath\");\r\n                    }\r\n\r\n                    // Check for duplicate relative filepath values.\r\n                    if (!relativeFilePathSet.insert(Utility::ToLower(nestedInstallerFile.RelativeFilePath)).second)\r\n                    {\r\n                        resultErrors.emplace_back(ManifestError::DuplicateRelativeFilePath, \"RelativeFilePath\");\r\n                    }\r\n\r\n                    // Check for duplicate portable command alias values.\r\n                    const auto& alias = Utility::ToLower(nestedInstallerFile.PortableCommandAlias);\r\n                    if (!alias.empty() && !commandAliasSet.insert(alias).second)\r\n                    {\r\n                        resultErrors.emplace_back(ManifestError::DuplicatePortableCommandAlias, \"PortableCommandAlias\");\r\n                        break;\r\n                    }\r\n\r\n                    // If running full validation, check filetype\r\n                    if (fullValidation)\r\n                    {\r\n                        if (isPortable)\r\n                        {\r\n                            if (fullPath.has_extension() && std::find(s_AllowedPortableFiletypes.begin(), s_AllowedPortableFiletypes.end(), fullPath.extension()) == s_AllowedPortableFiletypes.end())\r\n                            {\r\n                                resultErrors.emplace_back(ManifestError::InvalidPortableFiletype, \"RelativeFilePath\", nestedInstallerFile.RelativeFilePath);\r\n                            }\r\n                        }\r\n\r\n                        if (isFont)\r\n                        {\r\n                            if (fullPath.has_extension() && std::find(s_AllowedFontFiletypes.begin(), s_AllowedFontFiletypes.end(), fullPath.extension()) == s_AllowedFontFiletypes.end())\r\n                            {\r\n                                resultErrors.emplace_back(ManifestError::InvalidFontFiletype, \"RelativeFilePath\", nestedInstallerFile.RelativeFilePath);\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Check empty string before calling IsValidUrl to avoid duplicate error reporting.\r\n            if (!installer.Url.empty() && IsValidURL(NULL, Utility::ConvertToUTF16(installer.Url).c_str(), 0) == S_FALSE)\r\n            {\r\n                resultErrors.emplace_back(ManifestError::InvalidFieldValue, \"InstallerUrl\", installer.Url);\r\n            }\r\n\r\n            if (!installer.Locale.empty() && !Locale::IsWellFormedBcp47Tag(installer.Locale))\r\n            {\r\n                resultErrors.emplace_back(ManifestError::InvalidBcp47Value, \"InstallerLocale\", installer.Locale);\r\n            }\r\n\r\n            if (!installer.Markets.AllowedMarkets.empty() && !installer.Markets.ExcludedMarkets.empty())\r\n            {\r\n                resultErrors.emplace_back(ManifestError::BothAllowedAndExcludedMarketsDefined);\r\n            }\r\n\r\n            // Check expected return codes for duplicates between successful and expected error codes\r\n            std::set<DWORD> returnCodeSet;\r\n            returnCodeSet.insert(installer.InstallerSuccessCodes.begin(), installer.InstallerSuccessCodes.end());\r\n            for (const auto& code : installer.ExpectedReturnCodes)\r\n            {\r\n                if (!returnCodeSet.insert(code.first).second)\r\n                {\r\n                    resultErrors.emplace_back(ManifestError::DuplicateReturnCodeEntry);\r\n\r\n                    // Stop checking to avoid repeated errors\r\n                    break;\r\n                }\r\n            }\r\n\r\n            // Check no approximate version declared for DisplayVersion in AppsAndFeatureEntries\r\n            for (auto const& entry : installer.AppsAndFeaturesEntries)\r\n            {\r\n                if (!entry.DisplayVersion.empty())\r\n                {\r\n                    try\r\n                    {\r\n                        Utility::Version displayVersion{ entry.DisplayVersion };\r\n                        if (displayVersion.IsApproximate())\r\n                        {\r\n                            resultErrors.emplace_back(ManifestError::ApproximateVersionNotAllowed, \"DisplayVersion\", entry.DisplayVersion);\r\n                        }\r\n                    }\r\n                    catch (const std::exception&)\r\n                    {\r\n                        resultErrors.emplace_back(ManifestError::InvalidFieldValue, \"DisplayVersion\", entry.DisplayVersion);\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Check AuthInfo validity. For full validation (community repo), authentication type must be none.\r\n            if (installer.AuthInfo.Type != Authentication::AuthenticationType::None)\r\n            {\r\n                if (fullValidation)\r\n                {\r\n                    // Authentication is not supported (must be none) in community repo.\r\n                    resultErrors.emplace_back(ManifestError::FieldNotSupported, \"Authentication\");\r\n                }\r\n\r\n                if (!installer.AuthInfo.ValidateIntegrity())\r\n                {\r\n                    resultErrors.emplace_back(ManifestError::InvalidFieldValue, \"Authentication\");\r\n                }\r\n            }\r\n\r\n            if (fullValidation)\r\n            {\r\n                for (const auto& container : installer.DesiredStateConfiguration)\r\n                {\r\n                    if (container.Type == DesiredStateConfigurationContainerType::PowerShell)\r\n                    {\r\n                        // PowerShell DSC is not supported in community repo.\r\n                        resultErrors.emplace_back(ManifestError::FieldNotSupported, \"DesiredStateConfiguration.PowerShell\");\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // Validate localizations\r\n        for (auto const& localization : manifest.Localizations)\r\n        {\r\n            auto locErrors = ValidateManifestLocalization(localization, !fullValidation);\r\n            std::move(locErrors.begin(), locErrors.end(), std::inserter(resultErrors, resultErrors.end()));\r\n        }\r\n\r\n        return resultErrors;\r\n    }\r\n\r\n    std::vector<ValidationError> ValidateManifestLocalization(const ManifestLocalization& localization, bool treatErrorAsWarning)\r\n    {\r\n        std::vector<ValidationError> resultErrors;\r\n\r\n        if (!localization.Locale.empty() && !Locale::IsWellFormedBcp47Tag(localization.Locale))\r\n        {\r\n            resultErrors.emplace_back(ManifestError::InvalidBcp47Value, \"PackageLocale\", localization.Locale, treatErrorAsWarning ? ValidationError::Level::Warning : ValidationError::Level::Error);\r\n        }\r\n\r\n        if (localization.Contains(Localization::Agreements))\r\n        {\r\n            const auto& agreements = localization.Get<Localization::Agreements>();\r\n            for (const auto& agreement : agreements)\r\n            {\r\n                // At least one must be present\r\n                if (agreement.Label.empty() && agreement.AgreementText.empty() && agreement.AgreementUrl.empty())\r\n                {\r\n                    resultErrors.emplace_back(ManifestError::InvalidFieldValue, \"Agreements\", treatErrorAsWarning ? ValidationError::Level::Warning : ValidationError::Level::Error);\r\n                }\r\n            }\r\n        }\r\n\r\n        return resultErrors;\r\n    }\r\n\r\n    std::vector<ValidationError> ValidateManifestInstallers(const Manifest& manifest, bool treatErrorAsWarning)\r\n    {\r\n        std::vector<ValidationError> errors;\r\n        auto validationErrorLevel = treatErrorAsWarning ? ValidationError::Level::Warning : ValidationError::Level::Error;\r\n        MsixManifestValidation msixManifestValidation(validationErrorLevel);\r\n        for (const auto& installer : manifest.Installers)\r\n        {\r\n            // Installer msix or msixbundle\r\n            if (installer.EffectiveInstallerType() == InstallerTypeEnum::Msix)\r\n            {\r\n                auto installerErrors = msixManifestValidation.Validate(manifest, installer);\r\n                std::move(installerErrors.begin(), installerErrors.end(), std::inserter(errors, errors.end()));\r\n            }\r\n        }\r\n\r\n        return errors;\r\n    }\r\n\r\n    std::string ValidationError::GetErrorMessage() const\r\n    {\r\n        const auto& ErrorIdToMessageMap = GetErrorIdToMessageMap();\r\n        const auto itr = ErrorIdToMessageMap.find(Message);\r\n\r\n        if (itr != ErrorIdToMessageMap.end())\r\n        {\r\n            return std::string(itr->second);\r\n        }\r\n        \r\n        return Utility::ConvertToUTF8(Message);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Manifest/ManifestYamlPopulator.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"AppInstallerSHA256.h\"\r\n#include \"winget/ManifestYamlPopulator.h\"\r\n\r\nnamespace AppInstaller::Manifest\r\n{\r\n    using ValidationErrors = std::vector<ValidationError>;\r\n    using ExpectedReturnCodeInfo = AppInstaller::Manifest::ManifestInstaller::ExpectedReturnCodeInfo;\r\n\r\n    namespace\r\n    {\r\n        template <typename Ptr>\r\n        Ptr* variant_ptr(const VariantManifestPtr& v) { return std::get<Ptr*>(v); }\r\n\r\n        ManifestInstaller* GetManifestInstallerPtrFromManifest(const VariantManifestPtr& v) { return &(variant_ptr<Manifest>(v)->DefaultInstallerInfo); }\r\n\r\n        ManifestLocalization* GetManifestLocalizationPtrFromManifest(const VariantManifestPtr& v) { return &(variant_ptr<Manifest>(v)->DefaultLocalization); }\r\n\r\n        ManifestInstaller* GetManifestInstallerPtr(const VariantManifestPtr& v)\r\n        {\r\n            if (auto installer = std::get_if<ManifestInstaller*>(&v))\r\n            {\r\n                return *installer;\r\n            }\r\n\r\n            return GetManifestInstallerPtrFromManifest(v);\r\n        }\r\n\r\n        ManifestLocalization* GetManifestLocalizationPtr(const VariantManifestPtr& v)\r\n        {\r\n            if (auto localization = std::get_if<ManifestLocalization*>(&v))\r\n            {\r\n                return *localization;\r\n            }\r\n\r\n            return GetManifestLocalizationPtrFromManifest(v);\r\n        }\r\n\r\n        // Only used in preview manifest\r\n        std::vector<Manifest::string_t> SplitMultiValueField(const std::string& input)\r\n        {\r\n            if (input.empty())\r\n            {\r\n                return {};\r\n            }\r\n\r\n            std::vector<Manifest::string_t> result;\r\n            size_t currentPos = 0;\r\n            while (currentPos < input.size())\r\n            {\r\n                size_t splitPos = input.find(',', currentPos);\r\n                if (splitPos == std::string::npos)\r\n                {\r\n                    splitPos = input.size();\r\n                }\r\n\r\n                std::string splitVal = input.substr(currentPos, splitPos - currentPos);\r\n                Utility::Trim(splitVal);\r\n                if (!splitVal.empty())\r\n                {\r\n                    result.emplace_back(std::move(splitVal));\r\n                }\r\n                currentPos = splitPos + 1;\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        std::vector<Manifest::string_t> ProcessStringSequenceNode(const YAML::Node& node, bool trim = true)\r\n        {\r\n            THROW_HR_IF(E_INVALIDARG, !node.IsSequence());\r\n\r\n            std::vector<Manifest::string_t> result;\r\n\r\n            for (auto const& entry : node.Sequence())\r\n            {\r\n                std::string value = entry.as<std::string>();\r\n                if (trim)\r\n                {\r\n                    Utility::Trim(value);\r\n                }\r\n\r\n                result.emplace_back(std::move(value));\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        std::vector<DWORD> ProcessInstallerSuccessCodeSequenceNode(const YAML::Node& node)\r\n        {\r\n            THROW_HR_IF(E_INVALIDARG, !node.IsSequence());\r\n\r\n            std::vector<DWORD> result;\r\n\r\n            for (auto const& entry : node.Sequence())\r\n            {\r\n                result.emplace_back(static_cast<DWORD>(entry.as<int>()));\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        std::vector<PlatformEnum> ProcessPlatformSequenceNode(const YAML::Node& node)\r\n        {\r\n            THROW_HR_IF(E_INVALIDARG, !node.IsSequence());\r\n\r\n            std::vector<PlatformEnum> result;\r\n\r\n            for (auto const& entry : node.Sequence())\r\n            {\r\n                result.emplace_back(ConvertToPlatformEnum(entry.as<std::string>()));\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        std::vector<InstallModeEnum> ProcessInstallModeSequenceNode(const YAML::Node& node)\r\n        {\r\n            THROW_HR_IF(E_INVALIDARG, !node.IsSequence());\r\n\r\n            std::vector<InstallModeEnum> result;\r\n\r\n            for (auto const& entry : node.Sequence())\r\n            {\r\n                result.emplace_back(ConvertToInstallModeEnum(entry.as<std::string>()));\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        std::vector<AppInstaller::Utility::Architecture> ProcessArchitectureSequenceNode(const YAML::Node& node)\r\n        {\r\n            THROW_HR_IF(E_INVALIDARG, !node.IsSequence());\r\n\r\n            std::vector<AppInstaller::Utility::Architecture> result;\r\n\r\n            for (auto const& entry : node.Sequence())\r\n            {\r\n                result.emplace_back(Utility::ConvertToArchitectureEnum(entry.as<std::string>()));\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        std::vector<UnsupportedArgumentEnum> ProcessUnsupportedArgumentsSequenceNode(const YAML::Node& node)\r\n        {\r\n            THROW_HR_IF(E_INVALIDARG, !node.IsSequence());\r\n\r\n            std::vector<UnsupportedArgumentEnum> result;\r\n\r\n            for (auto const& entry : node.Sequence())\r\n            {\r\n                result.emplace_back(ConvertToUnsupportedArgumentEnum(entry.as<std::string>()));\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        void ProcessDependenciesNode(DependencyType type, const YAML::Node& node, DependencyList* dependencyList)\r\n        {\r\n            const auto& ids = ProcessStringSequenceNode(node);\r\n            for (auto id : ids)\r\n            {\r\n                dependencyList->Add(Dependency(type, id));\r\n            }\r\n        }\r\n    }\r\n\r\n    std::vector<ManifestYamlPopulator::FieldProcessInfo> ManifestYamlPopulator::GetRootFieldProcessInfo()\r\n    {\r\n        // Common fields across versions\r\n        std::vector<FieldProcessInfo> result =\r\n        {\r\n            { \"ManifestVersion\", [](const YAML::Node&, const VariantManifestPtr&)->ValidationErrors { /* ManifestVersion already populated. Field listed here for duplicate and PascalCase check */ return {}; } },\r\n            { \"Installers\", [this](const YAML::Node& value, const VariantManifestPtr&)->ValidationErrors { m_p_installersNode = &value; return {}; } },\r\n            { \"Localization\", [this](const YAML::Node& value, const VariantManifestPtr&)->ValidationErrors { m_p_localizationsNode = &value; return {}; } },\r\n            { \"Channel\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<Manifest>(v)->Channel = Utility::Trim(value.as<std::string>()); return {}; } },\r\n        };\r\n\r\n        // Additional version specific fields\r\n        if (m_manifestVersion.get().Major() == 0)\r\n        {\r\n            std::vector<FieldProcessInfo> previewRootFields\r\n            {\r\n                { \"Id\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<Manifest>(v)->Id = Utility::Trim(value.as<std::string>()); return {}; } },\r\n                { \"Version\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<Manifest>(v)->Version = Utility::Trim(value.as<std::string>()); return {}; } },\r\n                { \"AppMoniker\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<Manifest>(v)->Moniker = Utility::Trim(value.as<std::string>()); return {}; } },\r\n            };\r\n\r\n\r\n            std::move(previewRootFields.begin(), previewRootFields.end(), std::inserter(result, result.end()));\r\n        }\r\n        else if (m_manifestVersion.get().Major() == 1)\r\n        {\r\n            // Starting v1, we should be only adding new fields for each minor version increase\r\n            if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1 })\r\n            {\r\n                std::vector<FieldProcessInfo> v1RootFields\r\n                {\r\n                    { \"PackageIdentifier\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<Manifest>(v)->Id = Utility::Trim(value.as<std::string>()); return {}; } },\r\n                    { \"PackageVersion\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<Manifest>(v)->Version = Utility::Trim(value.as<std::string>()); return {}; } },\r\n                    { \"Moniker\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<Manifest>(v)->Moniker = Utility::Trim(value.as<std::string>()); return {}; } },\r\n                    { \"ManifestType\", [](const YAML::Node&, const VariantManifestPtr&)->ValidationErrors { /* ManifestType already checked. Field listed here for duplicate and PascalCase check */ return {}; } },\r\n                };\r\n\r\n                std::move(v1RootFields.begin(), v1RootFields.end(), std::inserter(result, result.end()));\r\n            }\r\n        }\r\n\r\n        // Root fields mapped as Installer and Localization values\r\n        auto rootInstallerFields = GetInstallerFieldProcessInfo(true);\r\n        std::move(rootInstallerFields.begin(), rootInstallerFields.end(), std::inserter(result, result.end()));\r\n\r\n        auto rootLocalizationFields = GetLocalizationFieldProcessInfo(true);\r\n        std::move(rootLocalizationFields.begin(), rootLocalizationFields.end(), std::inserter(result, result.end()));\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<ManifestYamlPopulator::FieldProcessInfo> ManifestYamlPopulator::GetInstallerFieldProcessInfo(bool forRootFields)\r\n    {\r\n        // Common fields across versions\r\n        std::vector<FieldProcessInfo> result =\r\n        {\r\n            { \"InstallerType\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->BaseInstallerType = ConvertToInstallerTypeEnum(value.as<std::string>()); return {}; } },\r\n            { \"PackageFamilyName\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->PackageFamilyName = value.as<std::string>(); return {}; } },\r\n            { \"ProductCode\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->ProductCode = value.as<std::string>(); return {}; } },\r\n        };\r\n\r\n        // Additional version specific fields\r\n        if (m_manifestVersion.get().Major() == 0)\r\n        {\r\n            // Root level and Localization node level\r\n            std::vector<FieldProcessInfo> previewCommonFields =\r\n            {\r\n                { \"UpdateBehavior\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->UpdateBehavior = ConvertToUpdateBehaviorEnum(value.as<std::string>()); return {}; } },\r\n                { \"Switches\", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ValidateAndProcessFields(value, SwitchesFieldInfos, VariantManifestPtr(&(GetManifestInstallerPtr(v)->Switches))); }},\r\n            };\r\n\r\n            std::move(previewCommonFields.begin(), previewCommonFields.end(), std::inserter(result, result.end()));\r\n\r\n            if (!forRootFields)\r\n            {\r\n                // Installer node only\r\n                std::vector<FieldProcessInfo> installerOnlyFields =\r\n                {\r\n                    { \"Arch\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<ManifestInstaller>(v)->Arch = Utility::ConvertToArchitectureEnum(value.as<std::string>()); return {}; } },\r\n                    { \"Url\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<ManifestInstaller>(v)->Url = value.as<std::string>(); return {}; } },\r\n                    { \"Sha256\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<ManifestInstaller>(v)->Sha256 = Utility::SHA256::ConvertToBytes(value.as<std::string>()); return {}; } },\r\n                    { \"SignatureSha256\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<ManifestInstaller>(v)->SignatureSha256 = Utility::SHA256::ConvertToBytes(value.as<std::string>()); return {}; } },\r\n                    { \"Language\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<ManifestInstaller>(v)->Locale = value.as<std::string>(); return {}; } },\r\n                    { \"Scope\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<ManifestInstaller>(v)->Scope = ConvertToScopeEnum(value.as<std::string>()); return {}; } },\r\n                };\r\n\r\n                if (m_manifestVersion.get().HasExtension(s_MSStoreExtension))\r\n                {\r\n                    installerOnlyFields.emplace_back(\"ProductId\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<ManifestInstaller>(v)->ProductId = value.as<std::string>(); return {}; });\r\n                }\r\n\r\n                std::move(installerOnlyFields.begin(), installerOnlyFields.end(), std::inserter(result, result.end()));\r\n            }\r\n            else\r\n            {\r\n                // Root node only\r\n                std::vector<FieldProcessInfo> rootOnlyFields =\r\n                {\r\n                    { \"MinOSVersion\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtrFromManifest(v)->MinOSVersion = value.as<std::string>(); return {}; } },\r\n                    { \"Commands\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtrFromManifest(v)->Commands = SplitMultiValueField(value.as<std::string>()); return {}; } },\r\n                    { \"Protocols\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtrFromManifest(v)->Protocols = SplitMultiValueField(value.as<std::string>()); return {}; } },\r\n                    { \"FileExtensions\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtrFromManifest(v)->FileExtensions = SplitMultiValueField(value.as<std::string>()); return {}; } },\r\n                };\r\n\r\n                std::move(rootOnlyFields.begin(), rootOnlyFields.end(), std::inserter(result, result.end()));\r\n            }\r\n        }\r\n        else if (m_manifestVersion.get().Major() == 1)\r\n        {\r\n            // Starting v1, we should be only adding new fields for each minor version increase\r\n            if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1 })\r\n            {\r\n                // Root level and Installer node level\r\n                std::vector<FieldProcessInfo> v1CommonFields =\r\n                {\r\n                    { \"InstallerLocale\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->Locale = value.as<std::string>(); return {}; } },\r\n                    { \"Platform\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->Platform = ProcessPlatformSequenceNode(value); return {}; } },\r\n                    { \"MinimumOSVersion\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->MinOSVersion = value.as<std::string>(); return {}; } },\r\n                    { \"Scope\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->Scope = ConvertToScopeEnum(value.as<std::string>()); return {}; } },\r\n                    { \"InstallModes\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->InstallModes = ProcessInstallModeSequenceNode(value); return {}; } },\r\n                    { \"InstallerSwitches\", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ValidateAndProcessFields(value, SwitchesFieldInfos, VariantManifestPtr(&(GetManifestInstallerPtr(v)->Switches))); }},\r\n                    { \"InstallerSuccessCodes\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->InstallerSuccessCodes = ProcessInstallerSuccessCodeSequenceNode(value); return {}; } },\r\n                    { \"UpgradeBehavior\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->UpdateBehavior = ConvertToUpdateBehaviorEnum(value.as<std::string>()); return {}; } },\r\n                    { \"Commands\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->Commands = ProcessStringSequenceNode(value); return {}; } },\r\n                    { \"Protocols\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->Protocols = ProcessStringSequenceNode(value); return {}; } },\r\n                    { \"FileExtensions\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->FileExtensions = ProcessStringSequenceNode(value); return {}; } },\r\n                    { \"Dependencies\", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ValidateAndProcessFields(value, DependenciesFieldInfos, VariantManifestPtr(&(GetManifestInstallerPtr(v)->Dependencies))); }},\r\n                    { \"Capabilities\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->Capabilities = ProcessStringSequenceNode(value); return {}; } },\r\n                    { \"RestrictedCapabilities\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->RestrictedCapabilities = ProcessStringSequenceNode(value); return {}; } },\r\n                };\r\n\r\n                std::move(v1CommonFields.begin(), v1CommonFields.end(), std::inserter(result, result.end()));\r\n\r\n                if (!forRootFields)\r\n                {\r\n                    // Installer level only fields\r\n                    std::vector<FieldProcessInfo> v1InstallerFields =\r\n                    {\r\n                        { \"Architecture\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<ManifestInstaller>(v)->Arch = Utility::ConvertToArchitectureEnum(value.as<std::string>()); return {}; } },\r\n                        { \"InstallerUrl\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<ManifestInstaller>(v)->Url = value.as<std::string>(); return {}; } },\r\n                        { \"InstallerSha256\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<ManifestInstaller>(v)->Sha256 = Utility::SHA256::ConvertToBytes(value.as<std::string>()); return {}; } },\r\n                        { \"SignatureSha256\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<ManifestInstaller>(v)->SignatureSha256 = Utility::SHA256::ConvertToBytes(value.as<std::string>()); return {}; } },\r\n                        // No custom validation needed at field populating time since we have semantic validation later to block msstore and productId from community repo.\r\n                        { \"MSStoreProductIdentifier\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<ManifestInstaller>(v)->ProductId = value.as<std::string>(); return {}; } },\r\n                    };\r\n\r\n                    std::move(v1InstallerFields.begin(), v1InstallerFields.end(), std::inserter(result, result.end()));\r\n                }\r\n            }\r\n\r\n            if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_1 })\r\n            {\r\n                std::vector<FieldProcessInfo> fields_v1_1 =\r\n                {\r\n                    { \"InstallerAbortsTerminal\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->InstallerAbortsTerminal = value.as<bool>(); return {}; } },\r\n                    { \"InstallLocationRequired\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->InstallLocationRequired = value.as<bool>(); return {}; } },\r\n                    { \"RequireExplicitUpgrade\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->RequireExplicitUpgrade = value.as<bool>(); return {}; } },\r\n                    { \"ReleaseDate\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->ReleaseDate = Utility::Trim(value.as<std::string>()); return {}; } },\r\n                    { \"UnsupportedOSArchitectures\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->UnsupportedOSArchitectures = ProcessArchitectureSequenceNode(value); return {}; } },\r\n                    { \"ElevationRequirement\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->ElevationRequirement = ConvertToElevationRequirementEnum(value.as<std::string>()); return {}; } },\r\n                    { \"Markets\", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ProcessMarketsNode(value, GetManifestInstallerPtr(v)); } },\r\n                    { \"AppsAndFeaturesEntries\", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ProcessAppsAndFeaturesEntriesNode(value, GetManifestInstallerPtr(v)); } },\r\n                    { \"ExpectedReturnCodes\", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ProcessExpectedReturnCodesNode(value, GetManifestInstallerPtr(v)); } },\r\n                };\r\n\r\n                std::move(fields_v1_1.begin(), fields_v1_1.end(), std::inserter(result, result.end()));\r\n            }\r\n\r\n            if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_2 })\r\n            {\r\n                std::vector<FieldProcessInfo> fields_v1_2 =\r\n                {\r\n                    { \"UnsupportedArguments\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->UnsupportedArguments = ProcessUnsupportedArgumentsSequenceNode(value); return {}; } },\r\n                    { \"DisplayInstallWarnings\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->DisplayInstallWarnings = value.as<bool>(); return {}; } },\r\n                };\r\n\r\n                std::move(fields_v1_2.begin(), fields_v1_2.end(), std::inserter(result, result.end()));\r\n            }\r\n\r\n            if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_4 })\r\n            {\r\n                std::vector<FieldProcessInfo> fields_v1_4 =\r\n                {\r\n                    { \"NestedInstallerType\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->NestedInstallerType = ConvertToInstallerTypeEnum(value.as<std::string>()); return {}; } },\r\n                    { \"NestedInstallerFiles\", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ProcessNestedInstallerFilesNode(value, GetManifestInstallerPtr(v)); } },\r\n                    { \"InstallationMetadata\", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ValidateAndProcessFields(value, InstallationMetadataFieldInfos, VariantManifestPtr(&(GetManifestInstallerPtr(v)->InstallationMetadata))); }},\r\n                };\r\n\r\n                std::move(fields_v1_4.begin(), fields_v1_4.end(), std::inserter(result, result.end()));\r\n            }\r\n\r\n            if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_6 })\r\n            {\r\n                std::vector<FieldProcessInfo> fields_v1_6 =\r\n                {\r\n                    { \"DownloadCommandProhibited\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->DownloadCommandProhibited = value.as<bool>(); return {}; }, true },\r\n                };\r\n\r\n                std::move(fields_v1_6.begin(), fields_v1_6.end(), std::inserter(result, result.end()));\r\n            }\r\n\r\n            if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_7 })\r\n            {\r\n                std::vector<FieldProcessInfo> fields_v1_7 =\r\n                {\r\n                    { \"RepairBehavior\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->RepairBehavior = ConvertToRepairBehaviorEnum(value.as<std::string>()); return {}; } },\r\n                };\r\n\r\n                std::move(fields_v1_7.begin(), fields_v1_7.end(), std::inserter(result, result.end()));\r\n            }\r\n\r\n            if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_9 })\r\n            {\r\n                std::vector<FieldProcessInfo> fields_v1_9 =\r\n                {\r\n                    { \"ArchiveBinariesDependOnPath\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->ArchiveBinariesDependOnPath = value.as<bool>(); return {}; } },\r\n                };\r\n\r\n                std::move(fields_v1_9.begin(), fields_v1_9.end(), std::inserter(result, result.end()));\r\n            }\r\n\r\n            if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_10 })\r\n            {\r\n                std::vector<FieldProcessInfo> fields_v1_10 =\r\n                {\r\n                    { \"Authentication\", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestInstallerPtr(v)->AuthInfo = {}; auto errors = ValidateAndProcessFields(value, AuthenticationFieldInfos, VariantManifestPtr(&(GetManifestInstallerPtr(v)->AuthInfo))); GetManifestInstallerPtr(v)->AuthInfo.UpdateRequiredFieldsIfNecessary(); return errors; }, true},\r\n                };\r\n\r\n                std::move(fields_v1_10.begin(), fields_v1_10.end(), std::inserter(result, result.end()));\r\n            }\r\n\r\n            if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_28 })\r\n            {\r\n                std::vector<FieldProcessInfo> fields_v1_28 =\r\n                {\r\n                    { \"DesiredStateConfiguration\", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors\r\n                        {\r\n                            auto* installer = GetManifestInstallerPtr(v);\r\n                            installer->DesiredStateConfiguration.clear();\r\n                            return ValidateAndProcessFields(value, DesiredStateConfigurationFieldInfos, VariantManifestPtr(&(installer->DesiredStateConfiguration)));\r\n                        }\r\n                    },\r\n                };\r\n\r\n                std::move(fields_v1_28.begin(), fields_v1_28.end(), std::inserter(result, result.end()));\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<ManifestYamlPopulator::FieldProcessInfo> ManifestYamlPopulator::GetSwitchesFieldProcessInfo()\r\n    {\r\n        // Common fields across versions\r\n        std::vector<FieldProcessInfo> result =\r\n        {\r\n            { \"Custom\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { (*variant_ptr<std::map<InstallerSwitchType, Utility::NormalizedString>>(v))[InstallerSwitchType::Custom] = value.as<std::string>(); return{}; } },\r\n            { \"Silent\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { (*variant_ptr<std::map<InstallerSwitchType, Utility::NormalizedString>>(v))[InstallerSwitchType::Silent] = value.as<std::string>(); return{}; } },\r\n            { \"SilentWithProgress\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { (*variant_ptr<std::map<InstallerSwitchType, Utility::NormalizedString>>(v))[InstallerSwitchType::SilentWithProgress] = value.as<std::string>(); return{}; } },\r\n            { \"Interactive\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { (*variant_ptr<std::map<InstallerSwitchType, Utility::NormalizedString>>(v))[InstallerSwitchType::Interactive] = value.as<std::string>(); return{}; } },\r\n            { \"Log\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { (*variant_ptr<std::map<InstallerSwitchType, Utility::NormalizedString>>(v))[InstallerSwitchType::Log] = value.as<std::string>(); return{}; } },\r\n            { \"InstallLocation\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { (*variant_ptr<std::map<InstallerSwitchType, Utility::NormalizedString>>(v))[InstallerSwitchType::InstallLocation] = value.as<std::string>(); return{}; } },\r\n        };\r\n\r\n        // Additional version specific fields\r\n        if (m_manifestVersion.get().Major() == 0)\r\n        {\r\n            // Language only exists in preview manifests. Though we don't use it in our code yet, keep it here to be consistent with schema.\r\n            result.emplace_back(\"Language\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { (*variant_ptr<std::map<InstallerSwitchType, Utility::NormalizedString>>(v))[InstallerSwitchType::Language] = value.as<std::string>(); return{}; });\r\n            result.emplace_back(\"Update\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { (*variant_ptr<std::map<InstallerSwitchType, Utility::NormalizedString>>(v))[InstallerSwitchType::Update] = value.as<std::string>(); return{}; });\r\n        }\r\n        else if (m_manifestVersion.get().Major() == 1)\r\n        {\r\n            result.emplace_back(\"Upgrade\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { (*variant_ptr<std::map<InstallerSwitchType, Utility::NormalizedString>>(v))[InstallerSwitchType::Update] = value.as<std::string>(); return{}; });\r\n\r\n            if (m_manifestVersion.get() >= ManifestVer{s_ManifestVersionV1_7})\r\n            {\r\n                result.emplace_back(\"Repair\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { (*variant_ptr<std::map<InstallerSwitchType, Utility::NormalizedString>>(v))[InstallerSwitchType::Repair] = value.as<std::string>(); return{}; });\r\n            };\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<ManifestYamlPopulator::FieldProcessInfo> ManifestYamlPopulator::GetExpectedReturnCodesFieldProcessInfo()\r\n    {\r\n        std::vector<FieldProcessInfo> result = {};\r\n\r\n        if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_1 })\r\n        {\r\n            result.emplace_back(\"InstallerReturnCode\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<ExpectedReturnCode>(v)->InstallerReturnCode = static_cast<int>(value.as<int>()); return {}; });\r\n            result.emplace_back(\"ReturnResponse\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<ExpectedReturnCode>(v)->ReturnResponse = ConvertToExpectedReturnCodeEnum(value.as<std::string>()); return {}; });\r\n        }\r\n\r\n        if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_2 })\r\n        {\r\n            result.emplace_back(\"ReturnResponseUrl\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<ExpectedReturnCode>(v)->ReturnResponseUrl = value.as<std::string>(); return {}; });\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<ManifestYamlPopulator::FieldProcessInfo> ManifestYamlPopulator::GetLocalizationFieldProcessInfo(bool forRootFields)\r\n    {\r\n        // Common fields across versions\r\n        std::vector<FieldProcessInfo> result =\r\n        {\r\n            { \"Description\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add<Localization::Description>(Utility::Trim(value.as<std::string>())); return {}; } },\r\n            { \"LicenseUrl\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add<Localization::LicenseUrl>(value.as<std::string>()); return {}; } },\r\n        };\r\n\r\n        // Additional version specific fields\r\n        if (m_manifestVersion.get().Major() == 0)\r\n        {\r\n            // Root level and Localization node level\r\n            result.emplace_back(\"Homepage\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add<Localization::PackageUrl>(value.as<std::string>()); return {}; });\r\n\r\n            if (!forRootFields)\r\n            {\r\n                // Localization node only\r\n                result.emplace_back(\"Language\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<ManifestLocalization>(v)->Locale = value.as<std::string>(); return {}; });\r\n            }\r\n            else\r\n            {\r\n                // Root node only\r\n                std::vector<FieldProcessInfo> rootOnlyFields =\r\n                {\r\n                    { \"Name\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtrFromManifest(v)->Add<Localization::PackageName>(Utility::Trim(value.as<std::string>())); return {}; } },\r\n                    { \"Publisher\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtrFromManifest(v)->Add<Localization::Publisher>(value.as<std::string>()); return {}; } },\r\n                    { \"Author\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtrFromManifest(v)->Add<Localization::Author>(value.as<std::string>()); return {}; } },\r\n                    { \"License\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtrFromManifest(v)->Add<Localization::License>(value.as<std::string>()); return {}; } },\r\n                    { \"Tags\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtrFromManifest(v)->Add<Localization::Tags>(SplitMultiValueField(value.as<std::string>())); return {}; } },\r\n                };\r\n\r\n                std::move(rootOnlyFields.begin(), rootOnlyFields.end(), std::inserter(result, result.end()));\r\n            }\r\n        }\r\n        else if (m_manifestVersion.get().Major() == 1)\r\n        {\r\n            // Starting v1, we should be only adding new fields for each minor version increase\r\n            if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1 })\r\n            {\r\n                // Root level and Localization node level\r\n                std::vector<FieldProcessInfo> v1CommonFields =\r\n                {\r\n                    { \"PackageLocale\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Locale = value.as<std::string>(); return {}; } },\r\n                    { \"Publisher\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add<Localization::Publisher>(value.as<std::string>()); return {}; } },\r\n                    { \"PublisherUrl\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add<Localization::PublisherUrl>(value.as<std::string>()); return {}; } },\r\n                    { \"PublisherSupportUrl\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add<Localization::PublisherSupportUrl>(value.as<std::string>()); return {}; } },\r\n                    { \"PrivacyUrl\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add<Localization::PrivacyUrl>(value.as<std::string>()); return {}; } },\r\n                    { \"Author\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add<Localization::Author>(value.as<std::string>()); return {}; } },\r\n                    { \"PackageName\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add<Localization::PackageName>(Utility::Trim(value.as<std::string>())); return {}; } },\r\n                    { \"PackageUrl\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add<Localization::PackageUrl>(value.as<std::string>()); return {}; } },\r\n                    { \"License\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add<Localization::License>(value.as<std::string>()); return {}; } },\r\n                    { \"Copyright\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add<Localization::Copyright>(value.as<std::string>()); return {}; } },\r\n                    { \"CopyrightUrl\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add<Localization::CopyrightUrl>(value.as<std::string>()); return {}; } },\r\n                    { \"ShortDescription\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add<Localization::ShortDescription>(Utility::Trim(value.as<std::string>())); return {}; } },\r\n                    { \"Tags\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add<Localization::Tags>(ProcessStringSequenceNode(value)); return {}; } },\r\n                };\r\n\r\n                std::move(v1CommonFields.begin(), v1CommonFields.end(), std::inserter(result, result.end()));\r\n            }\r\n\r\n            if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_1 })\r\n            {\r\n                std::vector<FieldProcessInfo> fields_v1_1 =\r\n                {\r\n                    { \"Agreements\", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ProcessAgreementsNode(value, GetManifestLocalizationPtr(v)); } },\r\n                    { \"ReleaseNotes\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add<Localization::ReleaseNotes>(value.as<std::string>()); return {}; } },\r\n                    { \"ReleaseNotesUrl\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add<Localization::ReleaseNotesUrl>(value.as<std::string>()); return {}; } },\r\n                };\r\n\r\n                std::move(fields_v1_1.begin(), fields_v1_1.end(), std::inserter(result, result.end()));\r\n            }\r\n\r\n            if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_2 })\r\n            {\r\n                std::vector<FieldProcessInfo> fields_v1_2 =\r\n                {\r\n                    { \"PurchaseUrl\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add<Localization::PurchaseUrl>(value.as<std::string>()); return {}; } },\r\n                    { \"InstallationNotes\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Add<Localization::InstallationNotes>(value.as<std::string>()); return {}; } },\r\n                    { \"Documentations\", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ProcessDocumentationsNode(value, GetManifestLocalizationPtr(v)); } },\r\n                };\r\n\r\n                std::move(fields_v1_2.begin(), fields_v1_2.end(), std::inserter(result, result.end()));\r\n            }\r\n\r\n            if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_5 })\r\n            {\r\n                std::vector<FieldProcessInfo> fields_v1_5 =\r\n                {\r\n                    { \"Icons\", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ProcessIconsNode(value, GetManifestLocalizationPtr(v)); }, true },\r\n                };\r\n\r\n                std::move(fields_v1_5.begin(), fields_v1_5.end(), std::inserter(result, result.end()));\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<ManifestYamlPopulator::FieldProcessInfo> ManifestYamlPopulator::GetDependenciesFieldProcessInfo()\r\n    {\r\n        std::vector<FieldProcessInfo> result = {};\r\n\r\n        if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1 })\r\n        {\r\n            result =\r\n            {\r\n                { \"WindowsFeatures\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { ProcessDependenciesNode(DependencyType::WindowsFeature, value, variant_ptr<DependencyList>(v)); return {}; } },\r\n                { \"WindowsLibraries\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { ProcessDependenciesNode(DependencyType::WindowsLibrary, value, variant_ptr<DependencyList>(v)); return {}; } },\r\n                { \"PackageDependencies\", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { ProcessPackageDependenciesNode(value, variant_ptr<DependencyList>(v)); return {}; } },\r\n                { \"ExternalDependencies\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { ProcessDependenciesNode(DependencyType::External, value, variant_ptr<DependencyList>(v)); return {}; } },\r\n            };\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<ManifestYamlPopulator::FieldProcessInfo> ManifestYamlPopulator::GetPackageDependenciesFieldProcessInfo()\r\n    {\r\n        std::vector<FieldProcessInfo> result = {};\r\n\r\n        if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1 })\r\n        {\r\n            result =\r\n            {\r\n                { \"PackageIdentifier\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<Dependency>(v)->SetId(Utility::Trim(value.as<std::string>())); return {}; } },\r\n                { \"MinimumVersion\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<Dependency>(v)->MinVersion = Utility::Version(Utility::Trim(value.as<std::string>())); return {}; } },\r\n            };\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<ManifestYamlPopulator::FieldProcessInfo> ManifestYamlPopulator::GetAgreementFieldProcessInfo()\r\n    {\r\n        std::vector<FieldProcessInfo> result = {};\r\n\r\n        if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_1 })\r\n        {\r\n            result =\r\n            {\r\n                { \"AgreementLabel\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<Agreement>(v)->Label = Utility::Trim(value.as<std::string>()); return {}; } },\r\n                { \"Agreement\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<Agreement>(v)->AgreementText = Utility::Trim(value.as<std::string>()); return {}; }, true },\r\n                { \"AgreementUrl\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<Agreement>(v)->AgreementUrl = Utility::Trim(value.as<std::string>()); return {}; } },\r\n            };\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<ManifestYamlPopulator::FieldProcessInfo> ManifestYamlPopulator::GetMarketsFieldProcessInfo()\r\n    {\r\n        std::vector<FieldProcessInfo> result = {};\r\n\r\n        if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_1 })\r\n        {\r\n            result =\r\n            {\r\n                { \"AllowedMarkets\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<MarketsInfo>(v)->AllowedMarkets = ProcessStringSequenceNode(value); return {}; } },\r\n                { \"ExcludedMarkets\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<MarketsInfo>(v)->ExcludedMarkets = ProcessStringSequenceNode(value); return {}; } },\r\n            };\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<ManifestYamlPopulator::FieldProcessInfo> ManifestYamlPopulator::GetAppsAndFeaturesEntryFieldProcessInfo()\r\n    {\r\n        std::vector<FieldProcessInfo> result = {};\r\n\r\n        if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_1 })\r\n        {\r\n            result =\r\n            {\r\n                { \"DisplayName\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<AppsAndFeaturesEntry>(v)->DisplayName = Utility::Trim(value.as<std::string>()); return {}; } },\r\n                { \"Publisher\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<AppsAndFeaturesEntry>(v)->Publisher = Utility::Trim(value.as<std::string>()); return {}; } },\r\n                { \"DisplayVersion\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<AppsAndFeaturesEntry>(v)->DisplayVersion = Utility::Trim(value.as<std::string>()); return {}; } },\r\n                { \"ProductCode\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<AppsAndFeaturesEntry>(v)->ProductCode = Utility::Trim(value.as<std::string>()); return {}; } },\r\n                { \"UpgradeCode\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<AppsAndFeaturesEntry>(v)->UpgradeCode = Utility::Trim(value.as<std::string>()); return {}; } },\r\n                { \"InstallerType\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<AppsAndFeaturesEntry>(v)->InstallerType = ConvertToInstallerTypeEnum(value.as<std::string>()); return {}; } },\r\n            };\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<ManifestYamlPopulator::FieldProcessInfo> ManifestYamlPopulator::GetDocumentationFieldProcessInfo()\r\n    {\r\n        std::vector<FieldProcessInfo> result = {};\r\n\r\n        if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_2 })\r\n        {\r\n            result =\r\n            {\r\n                { \"DocumentLabel\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<Documentation>(v)->DocumentLabel = Utility::Trim(value.as<std::string>()); return {}; } },\r\n                { \"DocumentUrl\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<Documentation>(v)->DocumentUrl = Utility::Trim(value.as<std::string>()); return {}; } },\r\n            };\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<ManifestYamlPopulator::FieldProcessInfo> ManifestYamlPopulator::GetIconFieldProcessInfo()\r\n    {\r\n        std::vector<FieldProcessInfo> result = {};\r\n\r\n        if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_5 })\r\n        {\r\n            result =\r\n            {\r\n                { \"IconUrl\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<Icon>(v)->Url = Utility::Trim(value.as<std::string>()); return {}; } },\r\n                { \"IconFileType\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<Icon>(v)->FileType = ConvertToIconFileTypeEnum(value.as<std::string>()); return {}; } },\r\n                { \"IconResolution\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<Icon>(v)->Resolution = ConvertToIconResolutionEnum(value.as<std::string>()); return {}; } },\r\n                { \"IconTheme\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<Icon>(v)->Theme = ConvertToIconThemeEnum(value.as<std::string>()); return {}; } },\r\n                { \"IconSha256\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<Icon>(v)->Sha256 = Utility::SHA256::ConvertToBytes(value.as<std::string>()); return {}; } },\r\n            };\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<ManifestYamlPopulator::FieldProcessInfo> ManifestYamlPopulator::GetNestedInstallerFileFieldProcessInfo()\r\n    {\r\n        std::vector<FieldProcessInfo> result = {};\r\n\r\n        if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_4 })\r\n        {\r\n            result =\r\n            {\r\n                { \"RelativeFilePath\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<NestedInstallerFile>(v)->RelativeFilePath = Utility::Trim(value.as<std::string>()); return {}; } },\r\n                { \"PortableCommandAlias\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<NestedInstallerFile>(v)->PortableCommandAlias = Utility::Trim(value.as<std::string>()); return {}; } },\r\n            };\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<ManifestYamlPopulator::FieldProcessInfo> ManifestYamlPopulator::GetInstallationMetadataFieldProcessInfo()\r\n    {\r\n        std::vector<FieldProcessInfo> result = {};\r\n\r\n        if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_4 })\r\n        {\r\n            result =\r\n            {\r\n                { \"DefaultInstallLocation\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<InstallationMetadataInfo>(v)->DefaultInstallLocation = Utility::Trim(value.as<std::string>()); return {}; } },\r\n                { \"Files\", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ProcessInstallationMetadataFilesNode(value, variant_ptr<InstallationMetadataInfo>(v)); } },\r\n            };\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<ManifestYamlPopulator::FieldProcessInfo> ManifestYamlPopulator::GetInstallationMetadataFilesFieldProcessInfo()\r\n    {\r\n        std::vector<FieldProcessInfo> result = {};\r\n\r\n        if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_4 })\r\n        {\r\n            result =\r\n            {\r\n                { \"RelativeFilePath\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<InstalledFile>(v)->RelativeFilePath = Utility::Trim(value.as<std::string>()); return {}; } },\r\n                { \"FileSha256\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<InstalledFile>(v)->FileSha256 = Utility::SHA256::ConvertToBytes(value.as<std::string>()); return {}; } },\r\n                { \"FileType\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<InstalledFile>(v)->FileType = ConvertToInstalledFileTypeEnum(value.as<std::string>()); return {}; } },\r\n                { \"InvocationParameter\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<InstalledFile>(v)->InvocationParameter = Utility::Trim(value.as<std::string>()); return {}; } },\r\n                { \"DisplayName\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<InstalledFile>(v)->DisplayName = Utility::Trim(value.as<std::string>()); return {}; } },\r\n            };\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<ManifestYamlPopulator::FieldProcessInfo> ManifestYamlPopulator::GetAuthenticationFieldInfos()\r\n    {\r\n        std::vector<FieldProcessInfo> result = {};\r\n\r\n        if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_10 })\r\n        {\r\n            result =\r\n            {\r\n                { \"AuthenticationType\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<Authentication::AuthenticationInfo>(v)->Type = Authentication::ConvertToAuthenticationType(value.as<std::string>()); return {}; } },\r\n                { \"MicrosoftEntraIdAuthenticationInfo\", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<Authentication::AuthenticationInfo>(v)->MicrosoftEntraIdInfo.emplace(); return ValidateAndProcessFields(value, MicrosoftEntraIdAuthenticationInfoFieldInfos, VariantManifestPtr(&(variant_ptr<Authentication::AuthenticationInfo>(v)->MicrosoftEntraIdInfo.value()))); }},\r\n            };\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<ManifestYamlPopulator::FieldProcessInfo> ManifestYamlPopulator::GetMicrosoftEntraIdAuthenticationInfoFieldInfos()\r\n    {\r\n        std::vector<FieldProcessInfo> result = {};\r\n\r\n        if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_10 })\r\n        {\r\n            result =\r\n            {\r\n                { \"Resource\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<Authentication::MicrosoftEntraIdAuthenticationInfo>(v)->Resource = Utility::Trim(value.as<std::string>()); return {}; } },\r\n                { \"Scope\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<Authentication::MicrosoftEntraIdAuthenticationInfo>(v)->Scope = Utility::Trim(value.as<std::string>()); return {}; } },\r\n            };\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<ManifestYamlPopulator::FieldProcessInfo> ManifestYamlPopulator::GetShadowRootFieldProcessInfo()\r\n    {\r\n        std::vector<FieldProcessInfo> result;\r\n\r\n        if (m_manifestVersion.get().Major() == 1)\r\n        {\r\n            if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_5 })\r\n            {\r\n                std::vector<FieldProcessInfo> fields_v1_5 =\r\n                {\r\n                    {\r\n                        { \"Localization\", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ProcessShadowLocalizationNode(value, variant_ptr<Manifest>(v)); } },\r\n                        { \"ManifestType\", [](const YAML::Node&, const VariantManifestPtr&)->ValidationErrors { return {}; } },\r\n                        { \"PackageIdentifier\", [](const YAML::Node&, const VariantManifestPtr&)->ValidationErrors { return {}; } },\r\n                        { \"PackageVersion\", [](const YAML::Node&, const VariantManifestPtr&)->ValidationErrors { return {}; } },\r\n                        { \"ManifestVersion\", [](const YAML::Node&, const VariantManifestPtr&)->ValidationErrors { return {}; } },\r\n                    },\r\n                };\r\n\r\n                std::move(fields_v1_5.begin(), fields_v1_5.end(), std::inserter(result, result.end()));\r\n            }\r\n        }\r\n\r\n        auto rootLocalizationFields = GetShadowLocalizationFieldProcessInfo();\r\n        std::move(rootLocalizationFields.begin(), rootLocalizationFields.end(), std::inserter(result, result.end()));\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<ManifestYamlPopulator::FieldProcessInfo> ManifestYamlPopulator::GetShadowLocalizationFieldProcessInfo()\r\n    {\r\n        std::vector<FieldProcessInfo> result;\r\n\r\n        if (m_manifestVersion.get().Major() == 1)\r\n        {\r\n            if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_5 })\r\n            {\r\n                std::vector<FieldProcessInfo> fields_v1_5 =\r\n                {\r\n                    { \"PackageLocale\", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { GetManifestLocalizationPtr(v)->Locale = value.as<std::string>(); return {}; } },\r\n                    { \"Icons\", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ProcessIconsNode(value, GetManifestLocalizationPtr(v)); } },\r\n                };\r\n\r\n                std::move(fields_v1_5.begin(), fields_v1_5.end(), std::inserter(result, result.end()));\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<ManifestYamlPopulator::FieldProcessInfo> ManifestYamlPopulator::GetDesiredStateConfigurationFieldInfos()\r\n    {\r\n        std::vector<FieldProcessInfo> result = {};\r\n\r\n        if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_28 })\r\n        {\r\n            result =\r\n            {\r\n                { \"PowerShell\", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ProcessDSC_PowerShellModuleNode(value, variant_ptr<std::vector<DesiredStateConfigurationContainerInfo>>(v)); } },\r\n                { \"DSCv3\", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors\r\n                    {\r\n                        auto* variantValue = variant_ptr<std::vector<DesiredStateConfigurationContainerInfo>>(v);\r\n                        variantValue->emplace_back(DesiredStateConfigurationContainerType::DSCv3);\r\n                        return ValidateAndProcessFields(value, DesiredStateConfigurationDSCv3FieldInfos, VariantManifestPtr(&variantValue->back()));\r\n                    }\r\n                },\r\n            };\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<ManifestYamlPopulator::FieldProcessInfo> ManifestYamlPopulator::GetDesiredStateConfigurationPowerShellModuleFieldInfos()\r\n    {\r\n        std::vector<FieldProcessInfo> result = {};\r\n\r\n        if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_28 })\r\n        {\r\n            result =\r\n            {\r\n                { \"RepositoryUrl\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<DesiredStateConfigurationContainerInfo>(v)->RepositoryURL = Utility::Trim(value.as<std::string>()); return {}; } },\r\n                { \"ModuleName\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<DesiredStateConfigurationContainerInfo>(v)->ModuleName = Utility::Trim(value.as<std::string>()); return {}; } },\r\n                { \"Resources\", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ProcessDSC_PowerShellResourcesNode(value, variant_ptr<DesiredStateConfigurationContainerInfo>(v)); } },\r\n            };\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<ManifestYamlPopulator::FieldProcessInfo> ManifestYamlPopulator::GetDesiredStateConfigurationPowerShellResourceFieldInfos()\r\n    {\r\n        std::vector<FieldProcessInfo> result = {};\r\n\r\n        if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_28 })\r\n        {\r\n            result =\r\n            {\r\n                { \"Name\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<DesiredStateConfigurationResourceInfo>(v)->Name = Utility::Trim(value.as<std::string>()); return {}; } },\r\n            };\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<ManifestYamlPopulator::FieldProcessInfo> ManifestYamlPopulator::GetDesiredStateConfigurationDSCv3FieldInfos()\r\n    {\r\n        std::vector<FieldProcessInfo> result = {};\r\n\r\n        if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_28 })\r\n        {\r\n            result =\r\n            {\r\n                { \"Resources\", [this](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { return ProcessDSCv3ResourcesNode(value, variant_ptr<DesiredStateConfigurationContainerInfo>(v)); } },\r\n            };\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<ManifestYamlPopulator::FieldProcessInfo> ManifestYamlPopulator::GetDesiredStateConfigurationDSCv3ResourceFieldInfos()\r\n    {\r\n        std::vector<FieldProcessInfo> result = {};\r\n\r\n        if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_28 })\r\n        {\r\n            result =\r\n            {\r\n                { \"Type\", [](const YAML::Node& value, const VariantManifestPtr& v)->ValidationErrors { variant_ptr<DesiredStateConfigurationResourceInfo>(v)->Name = Utility::Trim(value.as<std::string>()); return {}; } },\r\n            };\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    ValidationErrors ManifestYamlPopulator::ValidateAndProcessFields(\r\n        const YAML::Node& rootNode,\r\n        const std::vector<FieldProcessInfo>& fieldInfos,\r\n        const VariantManifestPtr& v)\r\n    {\r\n        ValidationErrors resultErrors;\r\n\r\n        if (!rootNode.IsMap() || rootNode.size() == 0)\r\n        {\r\n            resultErrors.emplace_back(ManifestError::InvalidRootNode, \"\", \"\", m_isMergedManifest ? 0 : rootNode.Mark().line, m_isMergedManifest ? 0 : rootNode.Mark().column);\r\n            return resultErrors;\r\n        }\r\n\r\n        // Keeps track of already processed fields. Used to check duplicate fields.\r\n        std::set<std::string> processedFields;\r\n\r\n        for (auto const& keyValuePair : rootNode.Mapping())\r\n        {\r\n            std::string key = keyValuePair.first.as<std::string>();\r\n            const YAML::Node& valueNode = keyValuePair.second;\r\n\r\n            // We'll do case-insensitive search first and validate correct case later.\r\n            auto fieldIter = std::find_if(fieldInfos.begin(), fieldInfos.end(),\r\n                [&](auto const& s)\r\n                {\r\n                    return Utility::CaseInsensitiveEquals(s.Name, key);\r\n                });\r\n\r\n            if (fieldIter != fieldInfos.end())\r\n            {\r\n                const FieldProcessInfo& fieldInfo = *fieldIter;\r\n\r\n                // Make sure the found key is in Pascal Case\r\n                if (key != fieldInfo.Name)\r\n                {\r\n                    resultErrors.emplace_back(ManifestError::FieldIsNotPascalCase, key, \"\", m_isMergedManifest ? 0 : keyValuePair.first.Mark().line, m_isMergedManifest ? 0 : keyValuePair.first.Mark().column);\r\n                }\r\n\r\n                // Make sure it's not a duplicate key\r\n                if (!processedFields.insert(fieldInfo.Name).second)\r\n                {\r\n                    resultErrors.emplace_back(ManifestError::FieldDuplicate, fieldInfo.Name, \"\", m_isMergedManifest ? 0 : keyValuePair.first.Mark().line, m_isMergedManifest ? 0 : keyValuePair.first.Mark().column);\r\n                }\r\n\r\n                if (fieldInfo.RequireVerifiedPublisher)\r\n                {\r\n                    resultErrors.emplace_back(ManifestError::FieldRequireVerifiedPublisher, fieldInfo.Name, \"\",\r\n                        m_isMergedManifest ? 0 : keyValuePair.first.Mark().line, m_isMergedManifest ? 0 : keyValuePair.first.Mark().column,\r\n                        m_validateOption.ErrorOnVerifiedPublisherFields ? ValidationError::Level::Error : ValidationError::Level::Warning);\r\n                }\r\n\r\n                if (!valueNode.IsNull())\r\n                {\r\n                    try\r\n                    {\r\n                        auto errors = fieldInfo.ProcessFunc(valueNode, v);\r\n                        std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end()));\r\n                    }\r\n                    catch (const std::exception&)\r\n                    {\r\n                        resultErrors.emplace_back(ManifestError::FieldFailedToProcess, fieldInfo.Name);\r\n                    }\r\n                }\r\n            }\r\n            else\r\n            {\r\n                // For full validation, also reports unrecognized fields as warning\r\n                if (m_validateOption.FullValidation)\r\n                {\r\n                    resultErrors.emplace_back(ManifestError::FieldUnknown, key, \"\", m_isMergedManifest ? 0 : keyValuePair.first.Mark().line, m_isMergedManifest ? 0 : keyValuePair.first.Mark().column, ValidationError::Level::Warning);\r\n                }\r\n            }\r\n        }\r\n\r\n        return resultErrors;\r\n    }\r\n\r\n    ValidationErrors ManifestYamlPopulator::ProcessPackageDependenciesNode(const YAML::Node& rootNode, DependencyList* dependencyList)\r\n    {\r\n        ValidationErrors resultErrors;\r\n\r\n        for (auto const& entry : rootNode.Sequence())\r\n        {\r\n            Dependency packageDependency = Dependency(DependencyType::Package);\r\n            auto errors = ValidateAndProcessFields(entry, PackageDependenciesFieldInfos, VariantManifestPtr(&packageDependency));\r\n            std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end()));\r\n            dependencyList->Add(std::move(packageDependency));\r\n        }\r\n\r\n        return resultErrors;\r\n    }\r\n\r\n    ValidationErrors ManifestYamlPopulator::ProcessAgreementsNode(const YAML::Node& agreementsNode, ManifestLocalization* localization)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, !agreementsNode.IsSequence());\r\n\r\n        ValidationErrors resultErrors;\r\n        std::vector<Agreement> agreements;\r\n\r\n        for (auto const& entry : agreementsNode.Sequence())\r\n        {\r\n            Agreement agreement;\r\n            auto errors = ValidateAndProcessFields(entry, AgreementFieldInfos, VariantManifestPtr(&agreement));\r\n            std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end()));\r\n            agreements.emplace_back(std::move(agreement));\r\n        }\r\n\r\n        if (!agreements.empty())\r\n        {\r\n            localization->Add<Localization::Agreements>(std::move(agreements));\r\n        }\r\n\r\n        return resultErrors;\r\n    }\r\n\r\n    std::vector<ValidationError> ManifestYamlPopulator::ProcessMarketsNode(const YAML::Node& marketsNode, ManifestInstaller* installer)\r\n    {\r\n        MarketsInfo markets;\r\n        auto errors = ValidateAndProcessFields(marketsNode, MarketsFieldInfos, VariantManifestPtr(&markets));\r\n        installer->Markets = markets;\r\n        return errors;\r\n    }\r\n\r\n    std::vector<ValidationError> ManifestYamlPopulator::ProcessAppsAndFeaturesEntriesNode(const YAML::Node& appsAndFeaturesEntriesNode, ManifestInstaller* installer)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, !appsAndFeaturesEntriesNode.IsSequence());\r\n\r\n        ValidationErrors resultErrors;\r\n        std::vector<AppsAndFeaturesEntry> appsAndFeaturesEntries;\r\n\r\n        for (auto const& entry : appsAndFeaturesEntriesNode.Sequence())\r\n        {\r\n            AppsAndFeaturesEntry appsAndFeaturesEntry;\r\n            auto errors = ValidateAndProcessFields(entry, AppsAndFeaturesEntryFieldInfos, VariantManifestPtr(&appsAndFeaturesEntry));\r\n            std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end()));\r\n            appsAndFeaturesEntries.emplace_back(std::move(appsAndFeaturesEntry));\r\n        }\r\n\r\n        installer->AppsAndFeaturesEntries = appsAndFeaturesEntries;\r\n\r\n        return resultErrors;\r\n    }\r\n\r\n    ValidationErrors ManifestYamlPopulator::ProcessExpectedReturnCodesNode(const YAML::Node& returnCodesNode, ManifestInstaller* installer)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, !returnCodesNode.IsSequence());\r\n\r\n        ValidationErrors resultErrors;\r\n        std::map<DWORD, ExpectedReturnCodeInfo> returnCodes;\r\n\r\n        for (auto const& entry : returnCodesNode.Sequence())\r\n        {\r\n            ExpectedReturnCode returnCode;\r\n            auto errors = ValidateAndProcessFields(entry, ExpectedReturnCodesFieldInfos, VariantManifestPtr(&returnCode));\r\n            std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end()));\r\n            if (!returnCodes.insert({ returnCode.InstallerReturnCode, {returnCode.ReturnResponse, returnCode.ReturnResponseUrl} }).second)\r\n            {\r\n                resultErrors.emplace_back(ManifestError::DuplicateReturnCodeEntry);\r\n            }\r\n        }\r\n\r\n        installer->ExpectedReturnCodes = returnCodes;\r\n\r\n        return resultErrors;\r\n    }\r\n\r\n    ValidationErrors ManifestYamlPopulator::ProcessDocumentationsNode(const YAML::Node& documentationsNode, ManifestLocalization* localization)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, !documentationsNode.IsSequence());\r\n\r\n        ValidationErrors resultErrors;\r\n        std::vector<Documentation> documentations;\r\n\r\n        for (auto const& entry : documentationsNode.Sequence())\r\n        {\r\n            Documentation documentation;\r\n            auto errors = ValidateAndProcessFields(entry, DocumentationFieldInfos, VariantManifestPtr(&documentation));\r\n            std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end()));\r\n            documentations.emplace_back(std::move(documentation));\r\n        }\r\n\r\n        if (!documentations.empty())\r\n        {\r\n            localization->Add<Localization::Documentations>(std::move(documentations));\r\n        }\r\n\r\n        return resultErrors;\r\n    }\r\n\r\n    std::vector<ValidationError> ManifestYamlPopulator::ProcessIconsNode(const YAML::Node& iconsNode, ManifestLocalization* localization)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, !iconsNode.IsSequence());\r\n\r\n        ValidationErrors resultErrors;\r\n        std::vector<Icon> icons;\r\n\r\n        for (auto const& entry : iconsNode.Sequence())\r\n        {\r\n            Icon icon;\r\n            auto errors = ValidateAndProcessFields(entry, IconFieldInfos, VariantManifestPtr(&icon));\r\n            std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end()));\r\n            icons.emplace_back(std::move(icon));\r\n        }\r\n\r\n        if (!icons.empty())\r\n        {\r\n            localization->Add<Localization::Icons>(std::move(icons));\r\n        }\r\n\r\n        return resultErrors;\r\n    }\r\n\r\n    ValidationErrors ManifestYamlPopulator::ProcessNestedInstallerFilesNode(const YAML::Node& nestedInstallerFilesNode, ManifestInstaller* installer)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, !nestedInstallerFilesNode.IsSequence());\r\n\r\n        ValidationErrors resultErrors;\r\n        std::vector<NestedInstallerFile> nestedInstallerFiles;\r\n\r\n        for (auto const& entry : nestedInstallerFilesNode.Sequence())\r\n        {\r\n            NestedInstallerFile nestedInstallerFile;\r\n            auto errors = ValidateAndProcessFields(entry, NestedInstallerFileFieldInfos, VariantManifestPtr(&nestedInstallerFile));\r\n            std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end()));\r\n            nestedInstallerFiles.emplace_back(std::move(nestedInstallerFile));\r\n        }\r\n\r\n        if (!nestedInstallerFiles.empty())\r\n        {\r\n            installer->NestedInstallerFiles = nestedInstallerFiles;\r\n        }\r\n\r\n        return resultErrors;\r\n    }\r\n\r\n    std::vector<ValidationError> ManifestYamlPopulator::ProcessInstallationMetadataFilesNode(const YAML::Node& installedFilesNode, InstallationMetadataInfo* installationMetadata)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, !installedFilesNode.IsSequence());\r\n\r\n        ValidationErrors resultErrors;\r\n        std::vector<InstalledFile> installedFiles;\r\n\r\n        for (auto const& entry : installedFilesNode.Sequence())\r\n        {\r\n            InstalledFile installedFile;\r\n            auto errors = ValidateAndProcessFields(entry, InstallationMetadataFilesFieldInfos, VariantManifestPtr(&installedFile));\r\n            std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end()));\r\n            installedFiles.emplace_back(std::move(installedFile));\r\n        }\r\n\r\n        if (!installedFiles.empty())\r\n        {\r\n            installationMetadata->Files = installedFiles;\r\n        }\r\n\r\n        return resultErrors;\r\n    }\r\n\r\n    std::vector<ValidationError> ManifestYamlPopulator::ProcessShadowLocalizationNode(const YAML::Node& localizationNode, Manifest* manifest)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, !localizationNode.IsSequence());\r\n\r\n        ValidationErrors resultErrors;\r\n        auto shadowLocalizationFields = GetShadowLocalizationFieldProcessInfo();\r\n\r\n        for (auto const& entry : localizationNode.Sequence())\r\n        {\r\n            ManifestLocalization localization;\r\n            auto errors = ValidateAndProcessFields(entry, shadowLocalizationFields, VariantManifestPtr(&localization));\r\n            std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end()));\r\n            manifest->Localizations.emplace_back(std::move(std::move(localization)));\r\n        }\r\n\r\n        return resultErrors;\r\n    }\r\n\r\n    std::vector<ValidationError> ManifestYamlPopulator::ProcessDSC_PowerShellModuleNode(const YAML::Node& node, std::vector<DesiredStateConfigurationContainerInfo>* containers)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, !node.IsSequence());\r\n\r\n        ValidationErrors resultErrors;\r\n\r\n        for (auto const& entry : node.Sequence())\r\n        {\r\n            auto& containerInfo = containers->emplace_back(DesiredStateConfigurationContainerType::PowerShell);\r\n            auto errors = ValidateAndProcessFields(entry, DesiredStateConfigurationPowerShellModuleFieldInfos, VariantManifestPtr(&containerInfo));\r\n            std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end()));\r\n        }\r\n\r\n        return resultErrors;\r\n    }\r\n\r\n    std::vector<ValidationError> ManifestYamlPopulator::ProcessDSC_PowerShellResourcesNode(const YAML::Node& node, DesiredStateConfigurationContainerInfo* container)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, !node.IsSequence());\r\n\r\n        ValidationErrors resultErrors;\r\n\r\n        for (auto const& entry : node.Sequence())\r\n        {\r\n            auto& resourceInfo = container->Resources.emplace_back();\r\n            auto errors = ValidateAndProcessFields(entry, DesiredStateConfigurationPowerShellResourceFieldInfos, VariantManifestPtr(&resourceInfo));\r\n            std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end()));\r\n        }\r\n\r\n        return resultErrors;\r\n    }\r\n\r\n    std::vector<ValidationError> ManifestYamlPopulator::ProcessDSCv3ResourcesNode(const YAML::Node& node, DesiredStateConfigurationContainerInfo* container)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, !node.IsSequence());\r\n\r\n        ValidationErrors resultErrors;\r\n\r\n        for (auto const& entry : node.Sequence())\r\n        {\r\n            auto& resourceInfo = container->Resources.emplace_back();\r\n            auto errors = ValidateAndProcessFields(entry, DesiredStateConfigurationDSCv3ResourceFieldInfos, VariantManifestPtr(&resourceInfo));\r\n            std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end()));\r\n        }\r\n\r\n        return resultErrors;\r\n    }\r\n\r\n\r\n    ManifestYamlPopulator::ManifestYamlPopulator(YAML::Node& rootNode, Manifest& manifest, const ManifestVer& manifestVersion, ManifestValidateOption validateOption) :\r\n        m_rootNode(rootNode), m_manifest(manifest), m_manifestVersion(manifestVersion), m_validateOption(validateOption)\r\n    {\r\n        m_isMergedManifest = !m_rootNode.get()[\"ManifestType\"sv].IsNull() && m_rootNode.get()[\"ManifestType\"sv].as<std::string>() == \"merged\";\r\n        m_manifest.get().ManifestVersion = m_manifestVersion;\r\n    }\r\n\r\n    ValidationErrors ManifestYamlPopulator::PopulateManifestInternal()\r\n    {\r\n        const YAML::Node& rootNode = m_rootNode;\r\n        ValidationErrors resultErrors;\r\n\r\n        // Prepare field infos\r\n        RootFieldInfos = GetRootFieldProcessInfo();\r\n        InstallerFieldInfos = GetInstallerFieldProcessInfo();\r\n        SwitchesFieldInfos = GetSwitchesFieldProcessInfo();\r\n        ExpectedReturnCodesFieldInfos = GetExpectedReturnCodesFieldProcessInfo();\r\n        DependenciesFieldInfos = GetDependenciesFieldProcessInfo();\r\n        PackageDependenciesFieldInfos = GetPackageDependenciesFieldProcessInfo();\r\n        LocalizationFieldInfos = GetLocalizationFieldProcessInfo();\r\n        AgreementFieldInfos = GetAgreementFieldProcessInfo();\r\n        MarketsFieldInfos = GetMarketsFieldProcessInfo();\r\n        AppsAndFeaturesEntryFieldInfos = GetAppsAndFeaturesEntryFieldProcessInfo();\r\n        DocumentationFieldInfos = GetDocumentationFieldProcessInfo();\r\n        IconFieldInfos = GetIconFieldProcessInfo();\r\n        NestedInstallerFileFieldInfos = GetNestedInstallerFileFieldProcessInfo();\r\n        InstallationMetadataFieldInfos = GetInstallationMetadataFieldProcessInfo();\r\n        InstallationMetadataFilesFieldInfos = GetInstallationMetadataFilesFieldProcessInfo();\r\n        AuthenticationFieldInfos = GetAuthenticationFieldInfos();\r\n        MicrosoftEntraIdAuthenticationInfoFieldInfos = GetMicrosoftEntraIdAuthenticationInfoFieldInfos();\r\n        DesiredStateConfigurationFieldInfos = GetDesiredStateConfigurationFieldInfos();\r\n        DesiredStateConfigurationPowerShellModuleFieldInfos = GetDesiredStateConfigurationPowerShellModuleFieldInfos();\r\n        DesiredStateConfigurationPowerShellResourceFieldInfos = GetDesiredStateConfigurationPowerShellResourceFieldInfos();\r\n        DesiredStateConfigurationDSCv3FieldInfos = GetDesiredStateConfigurationDSCv3FieldInfos();\r\n        DesiredStateConfigurationDSCv3ResourceFieldInfos = GetDesiredStateConfigurationDSCv3ResourceFieldInfos();\r\n\r\n        resultErrors = ValidateAndProcessFields(rootNode, RootFieldInfos, VariantManifestPtr(&(m_manifest.get())));\r\n\r\n        if (!m_p_installersNode)\r\n        {\r\n            return resultErrors;\r\n        }\r\n\r\n        // Populate installers\r\n        for (auto const& entry : m_p_installersNode->Sequence())\r\n        {\r\n            ManifestInstaller installer = m_manifest.get().DefaultInstallerInfo;\r\n\r\n#define WINGET_STASH_INSTALLER_PROPERTY(_property_,_clear_) \\\r\n            auto stashed ## _property_ = std::move(installer. _property_); \\\r\n            installer. _property_ . _clear_ ();\r\n\r\n#define WINGET_UNSTASH_INSTALLER_PROPERTY(_property_) \\\r\n            installer. _property_ = std::move(stashed ## _property_);\r\n\r\n            // Clear these defaults as PackageFamilyName, ProductCode, AppsAndFeaturesEntries need to be copied based on InstallerType\r\n            WINGET_STASH_INSTALLER_PROPERTY(PackageFamilyName, clear);\r\n            WINGET_STASH_INSTALLER_PROPERTY(ProductCode, clear);\r\n            WINGET_STASH_INSTALLER_PROPERTY(AppsAndFeaturesEntries, clear);\r\n            // Clear dependencies as installer specific overrides root\r\n            WINGET_STASH_INSTALLER_PROPERTY(Dependencies, Clear);\r\n            // Clear nested installers as it should only be copied for zip installerType.\r\n            installer.NestedInstallerType = InstallerTypeEnum::Unknown;\r\n            WINGET_STASH_INSTALLER_PROPERTY(NestedInstallerFiles, clear);\r\n\r\n            auto errors = ValidateAndProcessFields(entry, InstallerFieldInfos, VariantManifestPtr(&installer));\r\n            std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end()));\r\n\r\n            // Set installer type back before attempting to use it in any of the EffectiveInstallerType calls below\r\n            if (IsArchiveType(installer.BaseInstallerType))\r\n            {\r\n                if (installer.NestedInstallerFiles.empty())\r\n                {\r\n                    WINGET_UNSTASH_INSTALLER_PROPERTY(NestedInstallerFiles);\r\n                }\r\n\r\n                if (installer.NestedInstallerType == InstallerTypeEnum::Unknown)\r\n                {\r\n                    installer.NestedInstallerType = m_manifest.get().DefaultInstallerInfo.NestedInstallerType;\r\n                }\r\n            }\r\n\r\n            // Copy in system reference strings from the root if not set in the installer and appropriate\r\n            if (installer.AppsAndFeaturesEntries.empty() && DoesInstallerTypeWriteAppsAndFeaturesEntry(installer.EffectiveInstallerType()))\r\n            {\r\n                WINGET_UNSTASH_INSTALLER_PROPERTY(AppsAndFeaturesEntries);\r\n            }\r\n\r\n            if (installer.PackageFamilyName.empty() &&\r\n                (DoesInstallerTypeUsePackageFamilyName(installer.EffectiveInstallerType()) ||\r\n                 DoAnyAppsAndFeaturesEntriesUsePackageFamilyName(installer.AppsAndFeaturesEntries)))\r\n            {\r\n                WINGET_UNSTASH_INSTALLER_PROPERTY(PackageFamilyName);\r\n            }\r\n\r\n            if (installer.ProductCode.empty() && DoesInstallerTypeUseProductCode(installer.EffectiveInstallerType()))\r\n            {\r\n                WINGET_UNSTASH_INSTALLER_PROPERTY(ProductCode);\r\n            }\r\n\r\n            // If there are no dependencies on installer use default ones\r\n            if (!installer.Dependencies.HasAny())\r\n            {\r\n                WINGET_UNSTASH_INSTALLER_PROPERTY(Dependencies);\r\n            }\r\n\r\n            // Populate installer default switches if not exists\r\n            auto defaultSwitches = GetDefaultKnownSwitches(installer.EffectiveInstallerType());\r\n            for (auto const& defaultSwitch : defaultSwitches)\r\n            {\r\n                if (installer.Switches.find(defaultSwitch.first) == installer.Switches.end())\r\n                {\r\n                    installer.Switches[defaultSwitch.first] = defaultSwitch.second;\r\n                }\r\n            }\r\n\r\n            // Populate installer default return codes if not present in ExpectedReturnCodes and InstallerSuccessCodes\r\n            auto defaultReturnCodes = GetDefaultKnownReturnCodes(installer.EffectiveInstallerType());\r\n            for (auto const& defaultReturnCode : defaultReturnCodes)\r\n            {\r\n                if (installer.ExpectedReturnCodes.find(defaultReturnCode.first) == installer.ExpectedReturnCodes.end() &&\r\n                    std::find(installer.InstallerSuccessCodes.begin(), installer.InstallerSuccessCodes.end(), defaultReturnCode.first) == installer.InstallerSuccessCodes.end())\r\n                {\r\n                    installer.ExpectedReturnCodes[defaultReturnCode.first].ReturnResponseEnum = defaultReturnCode.second;\r\n                }\r\n            }\r\n\r\n            m_manifest.get().Installers.emplace_back(std::move(installer));\r\n        }\r\n\r\n        // Populate additional localizations\r\n        if (m_p_localizationsNode && m_p_localizationsNode->IsSequence())\r\n        {\r\n            for (auto const& entry : m_p_localizationsNode->Sequence())\r\n            {\r\n                ManifestLocalization localization;\r\n                auto errors = ValidateAndProcessFields(entry, LocalizationFieldInfos, VariantManifestPtr(&localization));\r\n                std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end()));\r\n                m_manifest.get().Localizations.emplace_back(std::move(std::move(localization)));\r\n            }\r\n        }\r\n\r\n        return resultErrors;\r\n    }\r\n\r\n    ValidationErrors ManifestYamlPopulator::InsertShadow(const YAML::Node& shadowNode)\r\n    {\r\n        Manifest shadowManifest;\r\n\r\n        // Process shadow node.\r\n        auto resultErrors = ValidateAndProcessFields(shadowNode, GetShadowRootFieldProcessInfo(), VariantManifestPtr(&shadowManifest));\r\n\r\n        // Merge.\r\n        if (m_manifestVersion.get() >= ManifestVer{ s_ManifestVersionV1_5 })\r\n        {\r\n            // Default localization\r\n            if (Utility::ICUCaseInsensitiveEquals(m_manifest.get().DefaultLocalization.Locale, shadowManifest.DefaultLocalization.Locale))\r\n            {\r\n                // Icons\r\n                if (!m_manifest.get().DefaultLocalization.Contains(Localization::Icons) &&\r\n                    shadowManifest.DefaultLocalization.Contains(Localization::Icons))\r\n                {\r\n                    m_manifest.get().DefaultLocalization.Add<Localization::Icons>(std::move(shadowManifest.DefaultLocalization.Get<Localization::Icons>()));\r\n\r\n                    YAML::Node key{ YAML::Node::Type::Scalar, \"\", YAML::Mark() };\r\n                    key.SetScalar(\"Icons\");\r\n                    YAML::Node value = shadowNode.GetChildNode(\"Icons\");\r\n                    m_rootNode.get().AddMappingNode(std::move(key), std::move(value));\r\n                }\r\n            }\r\n\r\n            // Localizations\r\n            if (!shadowManifest.Localizations.empty())\r\n            {\r\n                // Merge manifest object\r\n                for (auto const& shadowLocalization : shadowManifest.Localizations)\r\n                {\r\n                    // Manifest\r\n                    if (auto iter = std::find_if(m_manifest.get().Localizations.begin(), m_manifest.get().Localizations.end(), [&](auto const& l) { return Utility::ICUCaseInsensitiveEquals(l.Locale, shadowLocalization.Locale); }); iter != m_manifest.get().Localizations.end())\r\n                    {\r\n                        if (!(*iter).Contains(Localization::Icons) &&\r\n                            shadowLocalization.Contains(Localization::Icons))\r\n                        {\r\n                            (*iter).Add<Localization::Icons>(std::move(shadowLocalization.Get<Localization::Icons>()));\r\n                        }\r\n                    }\r\n                    else\r\n                    {\r\n                        ManifestLocalization localization = shadowLocalization;\r\n                        m_manifest.get().Localizations.emplace_back(std::move(std::move(localization)));\r\n                    }\r\n                }\r\n\r\n                // Merge yaml\r\n                auto shadowLocalizationsNode = shadowNode.GetChildNode(\"Localization\");\r\n                if (m_p_localizationsNode)\r\n                {\r\n                    m_rootNode.get().GetChildNode(\"Localization\").MergeSequenceNode(shadowLocalizationsNode, \"PackageLocale\", true);\r\n                }\r\n                else\r\n                {\r\n                    YAML::Node key{ YAML::Node::Type::Scalar, \"\", YAML::Mark() };\r\n                    key.SetScalar(\"Localization\");\r\n                    m_rootNode.get().AddMappingNode(std::move(key), std::move(shadowLocalizationsNode));\r\n                }\r\n            }\r\n        }\r\n\r\n        return resultErrors;\r\n    }\r\n\r\n    ValidationErrors ManifestYamlPopulator::PopulateManifest(\r\n        YAML::Node& rootNode,\r\n        Manifest& manifest,\r\n        const ManifestVer& manifestVersion,\r\n        ManifestValidateOption validateOption,\r\n        const std::optional<YAML::Node>& shadowNode)\r\n    {\r\n        ManifestYamlPopulator manifestPopulator(rootNode, manifest, manifestVersion, validateOption);\r\n        auto errors = manifestPopulator.PopulateManifestInternal();\r\n\r\n        if (shadowNode.has_value())\r\n        {\r\n            auto shadowErrors = manifestPopulator.InsertShadow(shadowNode.value());\r\n            std::move(shadowErrors.begin(), shadowErrors.end(), std::inserter(errors, errors.end()));\r\n        }\r\n\r\n        return errors;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Manifest/MsixManifestValidation.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"AppInstallerLogging.h\"\n#include \"AppInstallerRuntime.h\"\n#include \"AppInstallerDownloader.h\"\n#include \"winget/MsixManifestValidation.h\"\n\nnamespace AppInstaller::Manifest\n{\n    std::vector<ValidationError> MsixManifestValidation::Validate(\n        const Manifest& manifest,\n        const ManifestInstaller& installer)\n    {\n        std::vector<ValidationError> errors;\n        auto msixInfo = GetMsixInfo(installer.Url);\n        if (msixInfo)\n        {\n            ValidateMsixManifestSignatureHash(msixInfo, installer.SignatureSha256, errors);\n            auto msixManifests = msixInfo->GetAppPackageManifests();\n            auto installerMinOSVersion = GetManifestInstallerMinOSVersion(installer.MinOSVersion, errors);\n            for (const auto& msixManifest : msixManifests)\n            {\n                auto msixManifestIdentity = msixManifest.GetIdentity();\n                ValidateMsixManifestPackageFamilyName(msixManifestIdentity.GetPackageFamilyName(), installer.PackageFamilyName, errors);\n                ValidateMsixManifestPackageVersion(msixManifestIdentity.GetVersion(), manifest.Version, errors);\n                ValidateMsixManifestMinOSVersion(msixManifest.GetMinimumOSVersionForSupportedPlatforms(), installerMinOSVersion, installer.Url, errors);\n            }\n        }\n        else\n        {\n            errors.emplace_back(ManifestError::InstallerFailedToProcess, \"InstallerUrl\", installer.Url);\n        }\n\n        return errors;\n    }\n\n    MsixManifestValidation::~MsixManifestValidation()\n    {\n        AICLI_LOG(Core, Info, << \"Removing downloaded installers\");\n        for (const auto& installerPath : m_downloadedInstallers)\n        {\n            try\n            {\n                std::filesystem::remove(installerPath);\n            }\n            catch (...)\n            {\n                AICLI_LOG(Core, Warning, << \"Failed to remove downloaded installer: \" << installerPath);\n            }\n        }\n    }\n\n    std::optional<std::filesystem::path> MsixManifestValidation::DownloadInstaller(std::string installerUrl, int retryCount)\n    {\n        while (retryCount-- > 0)\n        {\n            try\n            {\n                AICLI_LOG(Core, Info, << \"Start downloading installer\");\n                auto tempFile = Runtime::GetNewTempFilePath();\n                ProgressCallback emptyCallback;\n                Utility::Download(installerUrl, tempFile, Utility::DownloadType::Installer, emptyCallback);\n                m_downloadedInstallers.push_back(tempFile);\n                return tempFile;\n            }\n            catch (...)\n            {\n                AICLI_LOG(Core, Error, << \"Downloading installer failed. Remaining attempts: \" << retryCount);\n            }\n        }\n\n        return std::nullopt;\n    }\n\n    std::shared_ptr<Msix::MsixInfo> MsixManifestValidation::GetMsixInfoFromUrl(std::string installerUrl)\n    {\n        try\n        {\n            AICLI_LOG(Core, Info, << \"Fetching Msix info from installer url\");\n            return std::make_shared<Msix::MsixInfo>(installerUrl);\n        }\n        catch (...)\n        {\n            AICLI_LOG(Core, Error, << \"Error fetching Msix info from the installer url.\");\n            return nullptr;\n        }\n    }\n\n    std::shared_ptr<Msix::MsixInfo> MsixManifestValidation::GetMsixInfoFromLocalPath(std::string installerUrl)\n    {\n        int maxRetry = 3;\n        std::shared_ptr<Msix::MsixInfo> msixInfo;\n        auto installerPath = DownloadInstaller(installerUrl, maxRetry);\n        if (installerPath.has_value())\n        {\n            try\n            {\n                AICLI_LOG(Core, Info, << \"Fetching Msix info from installer local path\");\n                msixInfo = std::make_shared<Msix::MsixInfo>(installerPath.value());\n            }\n            catch (...)\n            {\n                AICLI_LOG(Core, Error, << \"Error fetching Msix info from the installer local path.\");\n            }\n        }\n        else\n        {\n            AICLI_LOG(Core, Error, << \"Failed to download installer.\");\n        }\n\n        return msixInfo;\n    }\n\n    std::shared_ptr<Msix::MsixInfo> MsixManifestValidation::GetMsixInfo(std::string installerUrl)\n    {\n        std::shared_ptr<Msix::MsixInfo> msixInfo;\n        // Cache Msix info for new installer url\n        auto findMsixInfo = m_msixInfoCache.find(installerUrl);\n        if (findMsixInfo == m_msixInfoCache.end())\n        {\n            msixInfo = GetMsixInfoFromUrl(installerUrl);\n            if (!msixInfo)\n            {\n                AICLI_LOG(Core, Warning, << \"Failed to get Msix info directly from the installer url. \"\n                    << \"Downloading installer instead.\");\n                msixInfo = GetMsixInfoFromLocalPath(installerUrl);\n            }\n\n            if (msixInfo)\n            {\n                m_msixInfoCache.insert({ installerUrl, msixInfo });\n            }\n            else\n            {\n                AICLI_LOG(Core, Error, << \"Msix info could not be obtained.\");\n            }\n        }\n        else\n        {\n            msixInfo = findMsixInfo->second;\n        }\n\n        return msixInfo;\n    }\n\n    std::optional<Msix::OSVersion> MsixManifestValidation::GetManifestInstallerMinOSVersion(\n        std::string minOSVersion,\n        std::vector<ValidationError>& errors)\n    {\n        try\n        {\n            if (!minOSVersion.empty())\n            {\n                return std::make_optional<Msix::OSVersion>(minOSVersion);\n            }\n        }\n        catch (const std::exception&)\n        {\n            errors.emplace_back(ManifestError::InvalidFieldValue, \"MinimumOSVersion\", minOSVersion);\n        }\n        return std::nullopt;\n    }\n\n    void MsixManifestValidation::ValidateMsixManifestPackageFamilyName(\n        Utility::NormalizedString msixPackageFamilyName,\n        Utility::NormalizedString manifestPackageFamilyName,\n        std::vector<ValidationError>& errors)\n    {\n        if (!manifestPackageFamilyName.empty())\n        {\n            if (manifestPackageFamilyName != msixPackageFamilyName)\n            {\n                errors.emplace_back(ManifestError::InstallerMsixInconsistencies, \"PackageFamilyName\", msixPackageFamilyName);\n            }\n        }\n        else\n        {\n            errors.emplace_back(ManifestError::OptionalFieldMissing, \"PackageFamilyName\", msixPackageFamilyName, m_validationErrorLevel);\n        }\n    }\n\n    void MsixManifestValidation::ValidateMsixManifestPackageVersion(\n        const Msix::PackageVersion& msixPackageVersion,\n        const string_t& manifestPackageVersionStr,\n        std::vector<ValidationError>& errors)\n    {\n        std::optional<Msix::PackageVersion> manifestPackageVersion;\n        try\n        {\n            manifestPackageVersion = { manifestPackageVersionStr };\n        }\n        catch (...)\n        {\n            AICLI_LOG(Core, Error, << \"Failed to parse package version to UINT64\");\n        }\n\n        if (!manifestPackageVersion.has_value() || msixPackageVersion != manifestPackageVersion.value())\n        {\n            errors.emplace_back(ManifestError::InstallerMsixInconsistencies, \"PackageVersion\", msixPackageVersion.ToString());\n        }\n    }\n\n    void MsixManifestValidation::ValidateMsixManifestMinOSVersion(\n        const std::optional<Msix::OSVersion>& msixMinOSVersion,\n        const std::optional<Msix::OSVersion>& manifestMinOSVersion,\n        std::string installerUrl,\n        std::vector<ValidationError>& errors)\n    {\n        if (!msixMinOSVersion.has_value())\n        {\n            errors.emplace_back(ManifestError::NoSupportedPlatforms, \"InstallerUrl\", installerUrl);\n        }\n        else if (manifestMinOSVersion.has_value())\n        {\n            if (msixMinOSVersion.value() != manifestMinOSVersion.value())\n            {\n                errors.emplace_back(ManifestError::InstallerMsixInconsistencies, \"MinimumOSVersion\", msixMinOSVersion.value().ToString());\n            }\n        }\n        else\n        {\n            errors.emplace_back(\n                ManifestError::OptionalFieldMissing,\n                \"MinimumOSVersion\",\n                msixMinOSVersion.value().ToString(),\n                m_validationErrorLevel);\n        }\n    }\n\n    void MsixManifestValidation::ValidateMsixManifestSignatureHash(\n        const std::shared_ptr<Msix::MsixInfo> msixInfo,\n        const Utility::SHA256::HashBuffer& manifestSignatureHash,\n        std::vector<ValidationError>& errors)\n    {\n        try\n        {\n            if (!manifestSignatureHash.empty())\n            {\n                auto msixSignatureHash = msixInfo->GetSignatureHash();\n                if (msixSignatureHash != manifestSignatureHash)\n                {\n                    auto msixSignatureHashString = Utility::SHA256::ConvertToString(msixSignatureHash);\n                    errors.emplace_back(ManifestError::InstallerMsixInconsistencies, \"SignatureSha256\", msixSignatureHashString);\n                }\n            }\n        }\n        catch (const wil::ResultException&)\n        {\n            errors.emplace_back(ManifestError::MsixSignatureHashFailed);\n        }\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Manifest/YamlParser.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"AppInstallerSHA256.h\"\r\n#include \"winget/Yaml.h\"\r\n#include \"winget/ManifestSchemaValidation.h\"\r\n#include \"winget/ManifestYamlPopulator.h\"\r\n#include \"winget/ManifestYamlParser.h\"\r\n\r\nnamespace AppInstaller::Manifest::YamlParser\r\n{\r\n    namespace\r\n    {\r\n        // Basic V1 manifest required fields check for later manifest consistency check\r\n        void ValidateV1ManifestInput(const YamlManifestInfo& entry)\r\n        {\r\n            std::vector<ValidationError> errors;\r\n\r\n            if (!entry.Root.IsMap())\r\n            {\r\n                THROW_EXCEPTION_MSG(ManifestException(APPINSTALLER_CLI_ERROR_INVALID_MANIFEST), \"The manifest does not contain a valid root. File: %hs\", entry.FileName.c_str());\r\n            }\r\n\r\n            if (!entry.Root[\"PackageIdentifier\"])\r\n            {\r\n                errors.emplace_back(ValidationError::MessageContextWithFile(\r\n                    ManifestError::RequiredFieldMissing, \"PackageIdentifier\", entry.FileName));\r\n            }\r\n\r\n            if (!entry.Root[\"PackageVersion\"])\r\n            {\r\n                errors.emplace_back(ValidationError::MessageContextWithFile(\r\n                    ManifestError::RequiredFieldMissing, \"PackageVersion\", entry.FileName));\r\n            }\r\n\r\n            if (!entry.Root[\"ManifestVersion\"])\r\n            {\r\n                errors.emplace_back(ValidationError::MessageContextWithFile(\r\n                    ManifestError::RequiredFieldMissing, \"ManifestVersion\", entry.FileName));\r\n            }\r\n\r\n            if (!entry.Root[\"ManifestType\"])\r\n            {\r\n                errors.emplace_back(ValidationError::MessageContextWithFile(\r\n                    ManifestError::InconsistentMultiFileManifestFieldValue, \"ManifestType\", entry.FileName));\r\n            }\r\n            else\r\n            {\r\n                auto manifestType = ConvertToManifestTypeEnum(entry.Root[\"ManifestType\"].as<std::string>());\r\n\r\n                switch (manifestType)\r\n                {\r\n                case ManifestTypeEnum::Version:\r\n                    if (!entry.Root[\"DefaultLocale\"])\r\n                    {\r\n                        errors.emplace_back(ValidationError::MessageContextWithFile(\r\n                            ManifestError::RequiredFieldMissing, \"DefaultLocale\", entry.FileName));\r\n                    }\r\n                    break;\r\n                case ManifestTypeEnum::Singleton:\r\n                case ManifestTypeEnum::Locale:\r\n                case ManifestTypeEnum::DefaultLocale:\r\n                    if (!entry.Root[\"PackageLocale\"])\r\n                    {\r\n                        errors.emplace_back(ValidationError::MessageContextWithFile(\r\n                            ManifestError::RequiredFieldMissing, \"PackageLocale\", entry.FileName));\r\n                    }\r\n                    break;\r\n                }\r\n            }\r\n\r\n            if (!errors.empty())\r\n            {\r\n                ManifestException ex{ std::move(errors) };\r\n                THROW_EXCEPTION(ex);\r\n            }\r\n        }\r\n\r\n        // Input validations:\r\n        // - Determine manifest version\r\n        // - Check multi file manifest input integrity\r\n        //   - All manifests use same PackageIdentifier, PackageVersion, ManifestVersion\r\n        //   - All required types exist and exist only once. i.e. version, installer, defaultLocale\r\n        //   - No duplicate locales across manifests\r\n        //   - DefaultLocale matches in version manifest and defaultLocale manifest\r\n        // - Validate manifest type correctness\r\n        //   - Allowed file type in multi file manifest: version, installer, defaultLocale, locale\r\n        //   - Allowed file type in single file manifest: preview manifest, merged and singleton\r\n        ManifestVer ValidateInput(std::vector<YamlManifestInfo>& input, ManifestValidateOption validateOption)\r\n        {\r\n            std::vector<ValidationError> errors;\r\n\r\n            std::string manifestVersionStr;\r\n            ManifestVer manifestVersion;\r\n            ManifestVer ManifestVersionV1{ s_ManifestVersionV1 };\r\n            bool isMultifileManifest = input.size() > 1;\r\n\r\n            // Use the first manifest doc to determine ManifestVersion, there'll be checks for manifest version consistency later\r\n            auto& firstYamlManifest = input[0];\r\n            if (!firstYamlManifest.Root.IsMap())\r\n            {\r\n                THROW_EXCEPTION_MSG(ManifestException(APPINSTALLER_CLI_ERROR_INVALID_MANIFEST), \"The manifest does not contain a valid root. File: %hs\", firstYamlManifest.FileName.c_str());\r\n            }\r\n\r\n            if (firstYamlManifest.Root[\"ManifestVersion\"sv])\r\n            {\r\n                manifestVersionStr = firstYamlManifest.Root[\"ManifestVersion\"sv].as<std::string>();\r\n            }\r\n            else\r\n            {\r\n                manifestVersionStr = s_DefaultManifestVersion;\r\n            }\r\n            manifestVersion = ManifestVer{ manifestVersionStr };\r\n\r\n            // Check max supported version\r\n            if (manifestVersion.Major() > s_MaxSupportedMajorVersion)\r\n            {\r\n                THROW_EXCEPTION_MSG(ManifestException(APPINSTALLER_CLI_ERROR_UNSUPPORTED_MANIFESTVERSION), \"Unsupported ManifestVersion: %hs\", manifestVersion.ToString().c_str());\r\n            }\r\n\r\n            // Preview manifest validations\r\n            if (manifestVersion < ManifestVersionV1)\r\n            {\r\n                // multi file manifest is only supported starting ManifestVersion 1.0.0\r\n                if (isMultifileManifest)\r\n                {\r\n                    THROW_EXCEPTION_MSG(ManifestException(APPINSTALLER_CLI_ERROR_INVALID_MANIFEST), \"Preview manifest does not support multi file manifest format.\");\r\n                }\r\n\r\n                firstYamlManifest.ManifestType = ManifestTypeEnum::Preview;\r\n            }\r\n            // V1 manifest validations\r\n            else\r\n            {\r\n                // Check required fields used by later consistency check for better error message instead of\r\n                // Field Type Not Match error.\r\n                for (auto const& entry : input)\r\n                {\r\n                    ValidateV1ManifestInput(entry);\r\n                }\r\n\r\n                if (isMultifileManifest)\r\n                {\r\n                    // Populates the PackageIdentifier and PackageVersion from first doc for later consistency check\r\n                    std::string packageId = firstYamlManifest.Root[\"PackageIdentifier\"].as<std::string>();\r\n                    std::string packageVersion = firstYamlManifest.Root[\"PackageVersion\"].as<std::string>();\r\n\r\n                    std::set<std::string> localesSet;\r\n\r\n                    bool isVersionManifestFound = false;\r\n                    bool isInstallerManifestFound = false;\r\n                    bool isDefaultLocaleManifestFound = false;\r\n                    bool isShadowManifestFound = false;\r\n                    std::string defaultLocaleFromVersionManifest;\r\n                    std::string defaultLocaleFromDefaultLocaleManifest;\r\n\r\n                    for (auto& entry : input)\r\n                    {\r\n                        std::string localPackageId = entry.Root[\"PackageIdentifier\"].as<std::string>();\r\n                        if (localPackageId != packageId)\r\n                        {\r\n                            errors.emplace_back(ValidationError::MessageContextValueWithFile(\r\n                                ManifestError::InconsistentMultiFileManifestFieldValue, \"PackageIdentifier\", localPackageId, entry.FileName));\r\n                        }\r\n\r\n                        std::string localPackageVersion = entry.Root[\"PackageVersion\"].as<std::string>();\r\n                        if (localPackageVersion != packageVersion)\r\n                        {\r\n                            errors.emplace_back(ValidationError::MessageContextValueWithFile(\r\n                                ManifestError::InconsistentMultiFileManifestFieldValue, \"PackageVersion\", localPackageVersion, entry.FileName));\r\n                        }\r\n\r\n                        std::string localManifestVersion = entry.Root[\"ManifestVersion\"].as<std::string>();\r\n                        if (localManifestVersion != manifestVersionStr)\r\n                        {\r\n                            errors.emplace_back(ValidationError::MessageContextValueWithFile(\r\n                                ManifestError::InconsistentMultiFileManifestFieldValue, \"ManifestVersion\", localManifestVersion, entry.FileName));\r\n                        }\r\n\r\n                        std::string manifestTypeStr = entry.Root[\"ManifestType\"sv].as<std::string>();\r\n                        ManifestTypeEnum manifestType = ConvertToManifestTypeEnum(manifestTypeStr);\r\n                        entry.ManifestType = manifestType;\r\n\r\n                        switch (manifestType)\r\n                        {\r\n                        case ManifestTypeEnum::Version:\r\n                            if (isVersionManifestFound)\r\n                            {\r\n                                errors.emplace_back(ValidationError::MessageContextValueWithFile(\r\n                                    ManifestError::DuplicateMultiFileManifestType, \"ManifestType\", manifestTypeStr, entry.FileName));\r\n                            }\r\n                            else\r\n                            {\r\n                                isVersionManifestFound = true;\r\n                                defaultLocaleFromVersionManifest = entry.Root[\"DefaultLocale\"sv].as<std::string>();\r\n                            }\r\n                            break;\r\n                        case ManifestTypeEnum::Installer:\r\n                            if (isInstallerManifestFound)\r\n                            {\r\n                                errors.emplace_back(ValidationError::MessageContextValueWithFile(\r\n                                    ManifestError::DuplicateMultiFileManifestType, \"ManifestType\", manifestTypeStr, entry.FileName));\r\n                            }\r\n                            else\r\n                            {\r\n                                isInstallerManifestFound = true;\r\n                            }\r\n                            break;\r\n                        case ManifestTypeEnum::DefaultLocale:\r\n                            if (isDefaultLocaleManifestFound)\r\n                            {\r\n                                errors.emplace_back(ValidationError::MessageContextValueWithFile(\r\n                                    ManifestError::DuplicateMultiFileManifestType, \"ManifestType\", manifestTypeStr, entry.FileName));\r\n                            }\r\n                            else\r\n                            {\r\n                                isDefaultLocaleManifestFound = true;\r\n                                auto packageLocale = entry.Root[\"PackageLocale\"sv].as<std::string>();\r\n                                defaultLocaleFromDefaultLocaleManifest = packageLocale;\r\n\r\n                                if (localesSet.find(packageLocale) != localesSet.end())\r\n                                {\r\n                                    errors.emplace_back(ValidationError::MessageContextValueWithFile(\r\n                                        ManifestError::DuplicateMultiFileManifestLocale, \"PackageLocale\", packageLocale, entry.FileName));\r\n                                }\r\n                                else\r\n                                {\r\n                                    localesSet.insert(packageLocale);\r\n                                }\r\n                            }\r\n                            break;\r\n                        case ManifestTypeEnum::Locale:\r\n                        {\r\n                            auto packageLocale = entry.Root[\"PackageLocale\"sv].as<std::string>();\r\n                            if (localesSet.find(packageLocale) != localesSet.end())\r\n                            {\r\n                                errors.emplace_back(ValidationError::MessageContextValueWithFile(\r\n                                    ManifestError::DuplicateMultiFileManifestLocale, \"PackageLocale\", packageLocale, entry.FileName));\r\n                            }\r\n                            else\r\n                            {\r\n                                localesSet.insert(packageLocale);\r\n                            }\r\n                            break;\r\n                        }\r\n                        case ManifestTypeEnum::Shadow:\r\n                        {\r\n                            if (!validateOption.AllowShadowManifest)\r\n                            {\r\n                                errors.emplace_back(ValidationError::MessageContextValueWithFile(\r\n                                    ManifestError::ShadowManifestNotAllowed, \"ManifestType\", manifestTypeStr, entry.FileName));\r\n                            }\r\n                            else if (isShadowManifestFound)\r\n                            {\r\n                                errors.emplace_back(ValidationError::MessageContextValueWithFile(\r\n                                    ManifestError::DuplicateMultiFileManifestType, \"ManifestType\", manifestTypeStr, entry.FileName));\r\n                            }\r\n                            else\r\n                            {\r\n                                isShadowManifestFound = true;\r\n                            }\r\n                            break;\r\n                        }\r\n                        default:\r\n                            errors.emplace_back(ValidationError::MessageContextValueWithFile(\r\n                                ManifestError::UnsupportedMultiFileManifestType, \"ManifestType\", manifestTypeStr, entry.FileName));\r\n                        }\r\n                    }\r\n\r\n                    if (isVersionManifestFound && isDefaultLocaleManifestFound && defaultLocaleFromDefaultLocaleManifest != defaultLocaleFromVersionManifest)\r\n                    {\r\n                        errors.emplace_back(ManifestError::InconsistentMultiFileManifestDefaultLocale);\r\n                    }\r\n\r\n                    if (!validateOption.SchemaValidationOnly && !(isVersionManifestFound && isInstallerManifestFound && isDefaultLocaleManifestFound))\r\n                    {\r\n                        errors.emplace_back(ManifestError::IncompleteMultiFileManifest);\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    std::string manifestTypeStr = firstYamlManifest.Root[\"ManifestType\"sv].as<std::string>();\r\n                    ManifestTypeEnum manifestType = ConvertToManifestTypeEnum(manifestTypeStr);\r\n                    firstYamlManifest.ManifestType = manifestType;\r\n\r\n                    if (validateOption.FullValidation && manifestType == ManifestTypeEnum::Merged)\r\n                    {\r\n                        errors.emplace_back(ValidationError::MessageContextValueWithFile(ManifestError::FieldValueNotSupported, \"ManifestType\", manifestTypeStr, firstYamlManifest.FileName));\r\n                    }\r\n\r\n                    if (!validateOption.SchemaValidationOnly && manifestType != ManifestTypeEnum::Merged && manifestType != ManifestTypeEnum::Singleton)\r\n                    {\r\n                        errors.emplace_back(ValidationError::MessageWithFile(ManifestError::IncompleteMultiFileManifest, firstYamlManifest.FileName));\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (!errors.empty())\r\n            {\r\n                ManifestException ex{ std::move(errors) };\r\n                THROW_EXCEPTION(ex);\r\n            }\r\n\r\n            return manifestVersion;\r\n        }\r\n\r\n        // Find a unique required manifest from the input in multi manifest case\r\n        const YAML::Node& FindUniqueRequiredDocFromMultiFileManifest(const std::vector<YamlManifestInfo>& input, ManifestTypeEnum manifestType)\r\n        {\r\n            auto iter = std::find_if(input.begin(), input.end(),\r\n                [=](auto const& s)\r\n                {\r\n                    return s.ManifestType == manifestType;\r\n                });\r\n\r\n            THROW_HR_IF(E_UNEXPECTED, iter == input.end());\r\n\r\n            return iter->Root;\r\n        }\r\n\r\n        std::optional<YAML::Node> FindUniqueOptionalDocFromMultiFileManifest(std::vector<YamlManifestInfo>& input, ManifestTypeEnum manifestType)\r\n        {\r\n            auto iter = std::find_if(input.begin(), input.end(),\r\n                [=](auto const& s)\r\n                {\r\n                    return s.ManifestType == manifestType;\r\n                });\r\n\r\n            if (iter != input.end())\r\n            {\r\n                return iter->Root;\r\n            }\r\n\r\n            return {};\r\n        }\r\n\r\n        // Merge one manifest file to the final merged manifest, basically copying the mapping but excluding certain common fields\r\n        void MergeOneManifestToMultiFileManifest(const YAML::Node& input, YAML::Node& destination)\r\n        {\r\n            THROW_HR_IF(E_UNEXPECTED, !input.IsMap());\r\n            THROW_HR_IF(E_UNEXPECTED, !destination.IsMap());\r\n\r\n            const std::vector<std::string> FieldsToIgnore = { \"PackageIdentifier\", \"PackageVersion\", \"ManifestType\", \"ManifestVersion\" };\r\n\r\n            for (auto const& keyValuePair : input.Mapping())\r\n            {\r\n                // We only support string type as key in our manifest\r\n                if (std::find(FieldsToIgnore.begin(), FieldsToIgnore.end(), keyValuePair.first.as<std::string>()) == FieldsToIgnore.end())\r\n                {\r\n                    YAML::Node key = keyValuePair.first;\r\n                    YAML::Node value = keyValuePair.second;\r\n                    destination.AddMappingNode(std::move(key), std::move(value));\r\n                }\r\n            }\r\n        }\r\n\r\n        YAML::Node MergeMultiFileManifest(const std::vector<YamlManifestInfo>& input)\r\n        {\r\n            // Starts with installer manifest\r\n            YAML::Node result = FindUniqueRequiredDocFromMultiFileManifest(input, ManifestTypeEnum::Installer);\r\n\r\n            // Copy default locale manifest content into manifest root\r\n            YAML::Node defaultLocaleManifest = FindUniqueRequiredDocFromMultiFileManifest(input, ManifestTypeEnum::DefaultLocale);\r\n            MergeOneManifestToMultiFileManifest(defaultLocaleManifest, result);\r\n\r\n            // Copy additional locale manifests\r\n            YAML::Node localizations{ YAML::Node::Type::Sequence, \"\", YAML::Mark() };\r\n            for (const auto& entry : input)\r\n            {\r\n                if (entry.ManifestType == ManifestTypeEnum::Locale)\r\n                {\r\n                    YAML::Node localization{ YAML::Node::Type::Mapping, \"\", YAML::Mark() };\r\n                    MergeOneManifestToMultiFileManifest(entry.Root, localization);\r\n                    localizations.AddSequenceNode(std::move(localization));\r\n                }\r\n            }\r\n\r\n            if (localizations.size() > 0)\r\n            {\r\n                YAML::Node key{ YAML::Node::Type::Scalar, \"\", YAML::Mark() };\r\n                key.SetScalar(\"Localization\");\r\n                result.AddMappingNode(std::move(key), std::move(localizations));\r\n            }\r\n\r\n            result[\"ManifestType\"sv].SetScalar(\"merged\");\r\n\r\n            return result;\r\n        }\r\n\r\n        void EmitYamlNode(const YAML::Node& input, YAML::Emitter& emitter)\r\n        {\r\n            if (input.IsMap())\r\n            {\r\n                emitter << YAML::BeginMap;\r\n                for (auto const& keyValuePair : input.Mapping())\r\n                {\r\n                    emitter << YAML::Key;\r\n                    EmitYamlNode(keyValuePair.first, emitter);\r\n                    emitter << YAML::Value;\r\n                    EmitYamlNode(keyValuePair.second, emitter);\r\n                }\r\n                emitter << YAML::EndMap;\r\n            }\r\n            else if (input.IsSequence())\r\n            {\r\n                emitter << YAML::BeginSeq;\r\n                for (auto const& value : input.Sequence())\r\n                {\r\n                    EmitYamlNode(value, emitter);\r\n                }\r\n                emitter << YAML::EndSeq;\r\n            }\r\n            else if (input.IsScalar())\r\n            {\r\n                emitter << input.as<std::string>();\r\n            }\r\n            else if (input.IsNull())\r\n            {\r\n                emitter << \"\";\r\n            }\r\n            else\r\n            {\r\n                THROW_HR(E_UNEXPECTED);\r\n            }\r\n        }\r\n\r\n        void OutputYamlDoc(const YAML::Node& input, const std::filesystem::path& out)\r\n        {\r\n            THROW_HR_IF(E_UNEXPECTED, !input.IsMap());\r\n\r\n            YAML::Emitter emitter;\r\n            EmitYamlNode(input, emitter);\r\n\r\n            std::filesystem::create_directories(out.parent_path());\r\n            std::ofstream outFileStream(out);\r\n            emitter.Emit(outFileStream);\r\n            outFileStream.close();\r\n        }\r\n\r\n        std::vector<ValidationError> ParseManifestImpl(\r\n            std::vector<YamlManifestInfo>& input,\r\n            Manifest& manifest,\r\n            const std::filesystem::path& mergedManifestPath,\r\n            ManifestValidateOption validateOption)\r\n        {\r\n            THROW_HR_IF_MSG(E_INVALIDARG, input.size() == 0, \"No manifest file found\");\r\n            THROW_HR_IF_MSG(E_INVALIDARG, validateOption.SchemaValidationOnly && !mergedManifestPath.empty(), \"Manifest cannot be merged if only schema validation is performed\");\r\n            THROW_HR_IF_MSG(E_INVALIDARG, input.size() == 1 && !mergedManifestPath.empty(), \"Manifest cannot be merged from a single manifest\");\r\n\r\n            auto manifestVersion = ValidateInput(input, validateOption);\r\n\r\n            std::vector<ValidationError> resultErrors;\r\n\r\n            if (validateOption.FullValidation || validateOption.SchemaValidationOnly)\r\n            {\r\n                resultErrors = ValidateAgainstSchema(input, manifestVersion);\r\n            }\r\n\r\n            if (validateOption.SchemaValidationOnly)\r\n            {\r\n                return resultErrors;\r\n            }\r\n\r\n            // Merge manifests in multi file manifest case\r\n            bool isMultiFile = input.size() > 1;\r\n            YAML::Node& manifestDoc = input[0].Root;\r\n            if (isMultiFile)\r\n            {\r\n                manifestDoc = MergeMultiFileManifest(input);\r\n            }\r\n\r\n            auto shadowNode = isMultiFile ? FindUniqueOptionalDocFromMultiFileManifest(input, ManifestTypeEnum::Shadow) : std::optional<YAML::Node>{};\r\n\r\n            auto errors = ManifestYamlPopulator::PopulateManifest(manifestDoc, manifest, manifestVersion, validateOption, shadowNode);\r\n            std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end()));\r\n\r\n            // Extra semantic validations after basic validation and field population\r\n            if (validateOption.FullValidation)\r\n            {\r\n                errors = ValidateManifest(manifest);\r\n                std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end()));\r\n\r\n                // Validate the schema header for manifest version 1.7 and above\r\n                if (manifestVersion >= ManifestVer{ s_ManifestVersionV1_7 })\r\n                {\r\n                    // Validate the schema header.\r\n                    errors = ValidateYamlManifestsSchemaHeader(input, manifestVersion, validateOption.SchemaHeaderValidationAsWarning);\r\n                    std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end()));\r\n                }\r\n            }\r\n\r\n            if (validateOption.InstallerValidation)\r\n            {\r\n                errors = ValidateManifestInstallers(manifest);\r\n                std::move(errors.begin(), errors.end(), std::inserter(resultErrors, resultErrors.end()));\r\n            }\r\n\r\n            // Output merged manifest if requested\r\n            if (!mergedManifestPath.empty())\r\n            {\r\n                OutputYamlDoc(manifestDoc, mergedManifestPath);\r\n            }\r\n\r\n            // If there is only one input file, use its hash for the stream\r\n            if (input.size() == 1)\r\n            {\r\n                manifest.StreamSha256 = std::move(input[0].StreamSha256);\r\n            }\r\n\r\n            return resultErrors;\r\n        }\r\n    }\r\n\r\n    Manifest CreateFromPath(\r\n        const std::filesystem::path& inputPath,\r\n        ManifestValidateOption validateOption,\r\n        const std::filesystem::path& mergedManifestPath)\r\n    {\r\n        std::vector<YamlManifestInfo> docList;\r\n\r\n        try\r\n        {\r\n            if (std::filesystem::is_directory(inputPath))\r\n            {\r\n                for (const auto& file : std::filesystem::directory_iterator(inputPath))\r\n                {\r\n                    THROW_HR_IF_MSG(HRESULT_FROM_WIN32(ERROR_DIRECTORY_NOT_SUPPORTED), std::filesystem::is_directory(file.path()), \"Subdirectory not supported in manifest path\");\r\n\r\n                    YamlManifestInfo manifestInfo;\r\n                    YAML::Document doc = YAML::LoadDocument(file.path());\r\n                    manifestInfo.DocumentSchemaHeader = doc.GetSchemaHeader();\r\n                    manifestInfo.Root = std::move(doc).GetRoot();\r\n                    manifestInfo.FileName = file.path().filename().u8string();\r\n                    docList.emplace_back(std::move(manifestInfo));\r\n                }\r\n            }\r\n            else\r\n            {\r\n                YamlManifestInfo manifestInfo;\r\n                YAML::Document doc = YAML::LoadDocument(inputPath, manifestInfo.StreamSha256);\r\n                manifestInfo.DocumentSchemaHeader = doc.GetSchemaHeader();\r\n                manifestInfo.Root = std::move(doc).GetRoot();\r\n                manifestInfo.FileName = inputPath.filename().u8string();\r\n                docList.emplace_back(std::move(manifestInfo));\r\n            }\r\n        }\r\n        catch (const std::exception& e)\r\n        {\r\n            THROW_EXCEPTION_MSG(ManifestException(), \"%hs\", e.what());\r\n        }\r\n\r\n        return ParseManifest(docList, validateOption, mergedManifestPath);\r\n    }\r\n\r\n    Manifest Create(\r\n        const std::string& input,\r\n        ManifestValidateOption validateOption,\r\n        const std::filesystem::path& mergedManifestPath)\r\n    {\r\n        std::vector<YamlManifestInfo> docList;\r\n\r\n        try\r\n        {\r\n            YamlManifestInfo manifestInfo;\r\n            YAML::Document doc = YAML::LoadDocument(input);\r\n            manifestInfo.DocumentSchemaHeader = doc.GetSchemaHeader();\r\n            manifestInfo.Root = std::move(doc).GetRoot();\r\n            docList.emplace_back(std::move(manifestInfo));\r\n        }\r\n        catch (const std::exception& e)\r\n        {\r\n            THROW_EXCEPTION_MSG(ManifestException(), \"%hs\", e.what());\r\n        }\r\n\r\n        return ParseManifest(docList, validateOption, mergedManifestPath);\r\n    }\r\n\r\n    Manifest ParseManifest(\r\n        std::vector<YamlManifestInfo>& input,\r\n        ManifestValidateOption validateOption,\r\n        const std::filesystem::path& mergedManifestPath)\r\n    {\r\n        Manifest manifest;\r\n        std::vector<ValidationError> errors;\r\n\r\n        try\r\n        {\r\n            errors = ParseManifestImpl(input, manifest, mergedManifestPath, validateOption);\r\n        }\r\n        catch (const ManifestException&)\r\n        {\r\n            // Prevent ManifestException from being wrapped in another ManifestException\r\n            throw;\r\n        }\r\n        catch (const std::exception& e)\r\n        {\r\n            THROW_EXCEPTION_MSG(ManifestException(), \"%hs\", e.what());\r\n        }\r\n\r\n        if (!errors.empty())\r\n        {\r\n            ManifestException ex{ std::move(errors) };\r\n\r\n            if (validateOption.ThrowOnWarning || !ex.IsWarningOnly())\r\n            {\r\n                THROW_EXCEPTION(ex);\r\n            }\r\n        }\r\n\r\n        return manifest;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Manifest/YamlWriter.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"AppInstallerStrings.h\"\n#include \"AppInstallerSHA256.h\"\n#include \"winget/Yaml.h\"\n#include \"winget/ManifestYamlWriter.h\"\n\nnamespace AppInstaller::Manifest::YamlWriter\n{\n    using namespace Utility::literals;\n\n    namespace\n    {\n        constexpr std::string_view PackageIdentifier = \"PackageIdentifier\"sv;\n        constexpr std::string_view PackageFamilyName = \"PackageFamilyName\"sv;\n        constexpr std::string_view ProductCode = \"ProductCode\"sv;\n        constexpr std::string_view Versions = \"Versions\"sv;\n        constexpr std::string_view PackageVersion = \"PackageVersion\"sv;\n        constexpr std::string_view Channel = \"Channel\"sv;\n        constexpr std::string_view ManifestVersion = \"ManifestVersion\"sv;\n        constexpr std::string_view ManifestType = \"ManifestType\"sv;\n\n        // Installer\n        constexpr std::string_view Installers = \"Installers\"sv;\n        constexpr std::string_view InstallerIdentifier = \"InstallerIdentifier\"sv;\n        constexpr std::string_view InstallerSha256 = \"InstallerSha256\"sv;\n        constexpr std::string_view InstallerUrl = \"InstallerUrl\"sv;\n        constexpr std::string_view Architecture = \"Architecture\"sv;\n        constexpr std::string_view InstallerLocale = \"InstallerLocale\"sv;\n        constexpr std::string_view Platform = \"Platform\"sv;\n        constexpr std::string_view InstallerType = \"InstallerType\"sv;\n        constexpr std::string_view Scope = \"Scope\"sv;\n        constexpr std::string_view SignatureSha256 = \"SignatureSha256\"sv;\n        constexpr std::string_view InstallModes = \"InstallModes\"sv;\n        constexpr std::string_view MSStoreProductIdentifier = \"MSStoreProductIdentifier\"sv;\n        constexpr std::string_view ReleaseDate = \"ReleaseDate\"sv;\n        constexpr std::string_view InstallerAbortsTerminal = \"InstallerAbortsTerminal\"sv;\n        constexpr std::string_view InstallLocationRequired = \"InstallLocationRequired\"sv;\n        constexpr std::string_view RequireExplicitUpgrade = \"RequireExplicitUpgrade\"sv;\n        constexpr std::string_view UnsupportedOSArchitectures = \"UnsupportedOSArchitectures\"sv;\n        constexpr std::string_view AppsAndFeaturesEntries = \"AppsAndFeaturesEntries\"sv;\n        constexpr std::string_view DisplayVersion = \"DisplayVersion\"sv;\n        constexpr std::string_view UpgradeCode = \"UpgradeCode\"sv;\n        constexpr std::string_view Markets = \"Markets\"sv;\n        constexpr std::string_view AllowedMarkets = \"AllowedMarkets\"sv;\n        constexpr std::string_view ExcludedMarkets = \"ExcludedMarkets\"sv;\n        constexpr std::string_view ElevationRequirement = \"ElevationRequirement\"sv;\n        constexpr std::string_view ExpectedReturnCodes = \"ExpectedReturnCodes\"sv;\n        constexpr std::string_view InstallerReturnCode = \"InstallerReturnCode\"sv;\n        constexpr std::string_view ReturnResponse = \"ReturnResponse\"sv;\n        constexpr std::string_view ReturnResponseUrl = \"ReturnResponseUrl\"sv;\n        constexpr std::string_view NestedInstallerType = \"NestedInstallerType\"sv;\n        constexpr std::string_view DisplayInstallWarnings = \"DisplayInstallWarnings\"sv;\n        constexpr std::string_view UnsupportedArguments = \"UnsupportedArguments\"sv;\n        constexpr std::string_view NestedInstallerFiles = \"NestedInstallerFiles\"sv;\n        constexpr std::string_view NestedInstallerFileRelativeFilePath = \"RelativeFilePath\"sv;\n        constexpr std::string_view PortableCommandAlias = \"PortableCommandAlias\"sv;\n        constexpr std::string_view InstallationMetadata = \"InstallationMetadata\"sv;\n        constexpr std::string_view DefaultInstallLocation = \"DefaultInstallLocation\"sv;\n        constexpr std::string_view InstallationMetadataFiles = \"Files\"sv;\n        constexpr std::string_view InstallationMetadataRelativeFilePath = \"RelativeFilePath\"sv;\n        constexpr std::string_view FileSha256 = \"FileSha256\"sv;\n        constexpr std::string_view FileType = \"FileType\"sv;\n        constexpr std::string_view InvocationParameter = \"InvocationParameter\"sv;\n        constexpr std::string_view DisplayName = \"DisplayName\"sv;\n        constexpr std::string_view MinimumOSVersion = \"MinimumOSVersion\"sv;\n        constexpr std::string_view DownloadCommandProhibited = \"DownloadCommandProhibited\"sv;\n        constexpr std::string_view RepairBehavior = \"RepairBehavior\"sv;\r\n        constexpr std::string_view ArchiveBinariesDependOnPath = \"ArchiveBinariesDependOnPath\"sv;\r\n        constexpr std::string_view Authentication = \"Authentication\"sv;\r\n        constexpr std::string_view AuthenticationType = \"AuthenticationType\"sv;\r\n        constexpr std::string_view MicrosoftEntraIdAuthenticationInfo = \"MicrosoftEntraIdAuthenticationInfo\"sv;\r\n        constexpr std::string_view MicrosoftEntraIdResource = \"Resource\"sv;\r\n        constexpr std::string_view MicrosoftEntraIdScope = \"Scope\"sv;\n        constexpr std::string_view DesiredStateConfiguration = \"DesiredStateConfiguration\"sv;\n        constexpr std::string_view DesiredStateConfigurationResources = \"Resources\"sv;\n        constexpr std::string_view DesiredStateConfigurationPowerShell = \"PowerShell\"sv;\n        constexpr std::string_view DesiredStateConfigurationPowerShellRepositoryURL = \"RepositoryUrl\"sv;\n        constexpr std::string_view DesiredStateConfigurationPowerShellModuleName = \"ModuleName\"sv;\n        constexpr std::string_view DesiredStateConfigurationPowerShellResourceName = \"Name\"sv;\n        constexpr std::string_view DesiredStateConfigurationDSCv3 = \"DSCv3\"sv;\n        constexpr std::string_view DesiredStateConfigurationDSCv3ResourceType = \"Type\"sv;\n\n        // Installer switches\n        constexpr std::string_view InstallerSwitches = \"InstallerSwitches\"sv;\n        constexpr std::string_view Silent = \"Silent\"sv;\n        constexpr std::string_view SilentWithProgress = \"SilentWithProgress\"sv;\n        constexpr std::string_view Interactive = \"Interactive\"sv;\n        constexpr std::string_view InstallLocation = \"InstallLocation\"sv;\n        constexpr std::string_view Log = \"Log\"sv;\n        constexpr std::string_view Upgrade = \"Upgrade\"sv;\n        constexpr std::string_view Custom = \"Custom\"sv;\n        constexpr std::string_view Repair = \"Repair\"sv;\n\n        constexpr std::string_view InstallerSuccessCodes = \"InstallerSuccessCodes\"sv;\n        constexpr std::string_view UpgradeBehavior = \"UpgradeBehavior\"sv;\n        constexpr std::string_view Commands = \"Commands\"sv;\n        constexpr std::string_view Protocols = \"Protocols\"sv;\n        constexpr std::string_view FileExtensions = \"FileExtensions\"sv;\n\n        // Dependencies\n        constexpr std::string_view Dependencies = \"Dependencies\"sv;\n        constexpr std::string_view WindowsFeatures = \"WindowsFeatures\"sv;\n        constexpr std::string_view WindowsLibraries = \"WindowsLibraries\"sv;\n        constexpr std::string_view PackageDependencies = \"PackageDependencies\"sv;\n        constexpr std::string_view MinimumVersion = \"MinimumVersion\"sv;\n        constexpr std::string_view ExternalDependencies = \"ExternalDependencies\"sv;\n        constexpr std::string_view Capabilities = \"Capabilities\"sv;\n        constexpr std::string_view RestrictedCapabilities = \"RestrictedCapabilities\"sv;\n\n        // Locale\n        constexpr std::string_view Localization = \"Localization\"sv;\n        constexpr std::string_view InstallationNotes = \"InstallationNotes\"sv;\n        constexpr std::string_view PurchaseUrl = \"PurchaseUrl\"sv;\n        constexpr std::string_view Documentations = \"Documentations\"sv;\n        constexpr std::string_view DocumentLabel = \"DocumentLabel\"sv;\n        constexpr std::string_view DocumentUrl = \"DocumentUrl\"sv;\n        constexpr std::string_view Icons = \"Icons\"sv;\n        constexpr std::string_view IconUrl = \"IconUrl\"sv;\n        constexpr std::string_view IconFileType = \"IconFileType\"sv;\n        constexpr std::string_view IconResolution = \"IconResolution\"sv;\n        constexpr std::string_view IconTheme = \"IconTheme\"sv;\n        constexpr std::string_view IconSha256 = \"IconSha256\"sv;\n        constexpr std::string_view ReleaseNotes = \"ReleaseNotes\"sv;\n        constexpr std::string_view ReleaseNotesUrl = \"ReleaseNotesUrl\"sv;\n        constexpr std::string_view Agreements = \"Agreements\"sv;\n        constexpr std::string_view AgreementLabel = \"AgreementLabel\"sv;\n        constexpr std::string_view Agreement = \"Agreement\"sv;\n        constexpr std::string_view AgreementUrl = \"AgreementUrl\"sv;\n        constexpr std::string_view DefaultLocale = \"DefaultLocale\"sv;\n        constexpr std::string_view Locales = \"Locales\"sv;\n        constexpr std::string_view PackageLocale = \"PackageLocale\"sv;\n        constexpr std::string_view Publisher = \"Publisher\"sv;\n        constexpr std::string_view PublisherUrl = \"PublisherUrl\"sv;\n        constexpr std::string_view PublisherSupportUrl = \"PublisherSupportUrl\"sv;\n        constexpr std::string_view PrivacyUrl = \"PrivacyUrl\"sv;\n        constexpr std::string_view Author = \"Author\"sv;\n        constexpr std::string_view PackageName = \"PackageName\"sv;\n        constexpr std::string_view PackageUrl = \"PackageUrl\"sv;\n        constexpr std::string_view License = \"License\"sv;\n        constexpr std::string_view LicenseUrl = \"LicenseUrl\"sv;\n        constexpr std::string_view Copyright = \"Copyright\"sv;\n        constexpr std::string_view CopyrightUrl = \"CopyrightUrl\"sv;\n        constexpr std::string_view ShortDescription = \"ShortDescription\"sv;\n        constexpr std::string_view Description = \"Description\"sv;\n        constexpr std::string_view Tags = \"Tags\"sv;\n        constexpr std::string_view Moniker = \"Moniker\"sv;\n\n#define WRITE_PROPERTY(emitter, key, value) \\\n        { \\\n            emitter << YAML::Key << key << YAML::Value << value; \\\n        }\n\n#define WRITE_BOOL_PROPERTY(emitter, key, value) \\\n        { \\\n            emitter << YAML::Key << key << YAML::Value << Utility::ConvertBoolToString(value); \\\n        }\n\n#define WRITE_PROPERTY_IF_EXISTS(emitter, key, value) \\\n        { \\\n            if (!value.empty()) \\\n            { \\\n                WRITE_PROPERTY(emitter, key, value) \\\n            } \\\n        }\r\n\r\n#define WRITE_SHA256_PROPERTY_IF_NOT_EMPTY(emitter, key, field) \\\n        { \\\n            if (!field.empty()) \\\n            { \\\n                WRITE_PROPERTY(emitter, key, Utility::SHA256::ConvertToString(field)) \\\n            } \\\n        }\r\n\r\n#define WRITE_ENUM_PROPERTY_IF_NOT_UNKNOWN(emitter, key, value, enumField, enumType) \\\n        { \\\n            if (enumField != enumType::Unknown) \\\n            { \\\n                WRITE_PROPERTY(emitter, key, value) \\\n            } \\\n        }\n\n        void ProcessAgreements(YAML::Emitter& out, const std::vector<AppInstaller::Manifest::Agreement>& agreements)\n        {\n            if (agreements.empty())\n            {\n                return;\n            }\n\n            out << YAML::Key << Agreements;\n            out << YAML::BeginSeq;\n            for (const auto& agreement : agreements)\n            {\n                out << YAML::BeginMap;\n                WRITE_PROPERTY_IF_EXISTS(out, AgreementLabel, agreement.Label);\n                WRITE_PROPERTY_IF_EXISTS(out, AgreementUrl, agreement.AgreementUrl);\n                WRITE_PROPERTY_IF_EXISTS(out, Agreement, agreement.AgreementText);\n                out << YAML::EndMap;\n            }\n            out << YAML::EndSeq;\n        }\n\n        void ProcessDocumentations(YAML::Emitter& out, const std::vector<AppInstaller::Manifest::Documentation>& documentations)\n        {\n            if (documentations.empty())\n            {\n                return;\n            }\n\n            out << YAML::Key << Documentations;\n            out << YAML::BeginSeq;\n            for (const auto& document : documentations)\n            {\n                out << YAML::BeginMap;\n                WRITE_PROPERTY_IF_EXISTS(out, DocumentLabel, document.DocumentLabel);\n                WRITE_PROPERTY_IF_EXISTS(out, DocumentUrl, document.DocumentUrl);\n                out << YAML::EndMap;\n            }\n            out << YAML::EndSeq;\n        }\n\n        void ProcessIcons(YAML::Emitter& out, std::vector<AppInstaller::Manifest::Icon> icons)\n        {\n            if (icons.empty())\n            {\n                return;\n            }\n\n            out << YAML::Key << Icons;\n            out << YAML::BeginSeq;\n            for (const auto& icon : icons)\n            {\n                out << YAML::BeginMap;\n                WRITE_PROPERTY(out, IconUrl, icon.Url);\n                WRITE_PROPERTY(out, IconFileType, IconFileTypeToString(icon.FileType));\n                WRITE_ENUM_PROPERTY_IF_NOT_UNKNOWN(out, IconResolution, IconResolutionToString(icon.Resolution), icon.Resolution, IconResolutionEnum);\n                WRITE_ENUM_PROPERTY_IF_NOT_UNKNOWN(out, IconTheme, IconThemeToString(icon.Theme), icon.Theme, IconThemeEnum);\r\n                WRITE_SHA256_PROPERTY_IF_NOT_EMPTY(out, IconSha256, icon.Sha256);\n                out << YAML::EndMap;\n            }\n            out << YAML::EndSeq;\n        }\n\n        // Generic method for handling a list of strings (i.e. tags)\n        void ProcessStringSequence(YAML::Emitter& out, std::string_view name, std::vector<AppInstaller::Manifest::string_t> items)\n        {\n            if (items.empty())\n            {\n                return;\n            }\n\n            out << YAML::Key << name;\n            out << YAML::BeginSeq;\n            for (const auto& item : items)\n            {\r\n                if (!item.empty())\r\n                {\n                    out << item;\r\n                }\n            }\n            out << YAML::EndSeq;\n        }\n\n        void ProcessLocaleFields(YAML::Emitter& out, const ManifestLocalization& manifest)\n        {\n            ProcessAgreements(out, manifest.Get<Localization::Agreements>());\n            ProcessDocumentations(out, manifest.Get<Localization::Documentations>());\n            ProcessIcons(out, manifest.Get<Localization::Icons>());\n            ProcessStringSequence(out, Tags, manifest.Get<Localization::Tags>());\n\n            WRITE_PROPERTY(out, PackageLocale, manifest.Locale);\n            WRITE_PROPERTY_IF_EXISTS(out, Author, manifest.Get<Localization::Author>());\n            WRITE_PROPERTY_IF_EXISTS(out, Copyright, manifest.Get<Localization::Copyright>());\n            WRITE_PROPERTY_IF_EXISTS(out, CopyrightUrl, manifest.Get<Localization::CopyrightUrl>());\n            WRITE_PROPERTY_IF_EXISTS(out, Description, manifest.Get<Localization::Description>());\n            WRITE_PROPERTY_IF_EXISTS(out, ShortDescription, manifest.Get<Localization::ShortDescription>());\n            WRITE_PROPERTY_IF_EXISTS(out, License, manifest.Get<Localization::License>());\n            WRITE_PROPERTY_IF_EXISTS(out, LicenseUrl, manifest.Get<Localization::LicenseUrl>());\n            WRITE_PROPERTY_IF_EXISTS(out, PackageName, manifest.Get<Localization::PackageName>());\n            WRITE_PROPERTY_IF_EXISTS(out, PackageUrl, manifest.Get<Localization::PackageUrl>());\n            WRITE_PROPERTY_IF_EXISTS(out, PrivacyUrl, manifest.Get<Localization::PrivacyUrl>());\n            WRITE_PROPERTY_IF_EXISTS(out, Publisher, manifest.Get<Localization::Publisher>());\n            WRITE_PROPERTY_IF_EXISTS(out, PublisherSupportUrl, manifest.Get<Localization::PublisherSupportUrl>());\n            WRITE_PROPERTY_IF_EXISTS(out, PublisherUrl, manifest.Get<Localization::PublisherUrl>());\n            WRITE_PROPERTY_IF_EXISTS(out, PurchaseUrl, manifest.Get<Localization::PurchaseUrl>());\n            WRITE_PROPERTY_IF_EXISTS(out, ReleaseNotes, manifest.Get<Localization::ReleaseNotes>());\n            WRITE_PROPERTY_IF_EXISTS(out, ReleaseNotesUrl, manifest.Get<Localization::ReleaseNotesUrl>());\n            WRITE_PROPERTY_IF_EXISTS(out, InstallationNotes, manifest.Get<Localization::InstallationNotes>());\n        }\n\n        void ProcessAppsAndFeaturesEntries(YAML::Emitter& out, const std::vector<AppsAndFeaturesEntry>& appsAndFeaturesEntries)\n        {\n            if (appsAndFeaturesEntries.empty())\n            {\n                return;\n            }\n\n            out << YAML::Key << AppsAndFeaturesEntries;\n            out << YAML::BeginSeq;\n            for (const auto& appsAndFeatureEntry : appsAndFeaturesEntries)\n            {\n                out << YAML::BeginMap;\n                WRITE_PROPERTY_IF_EXISTS(out, DisplayName, appsAndFeatureEntry.DisplayName);\n                WRITE_PROPERTY_IF_EXISTS(out, DisplayVersion, appsAndFeatureEntry.DisplayVersion);\n                WRITE_ENUM_PROPERTY_IF_NOT_UNKNOWN(out, InstallerType, InstallerTypeToString(appsAndFeatureEntry.InstallerType), appsAndFeatureEntry.InstallerType, InstallerTypeEnum);\n                WRITE_PROPERTY_IF_EXISTS(out, ProductCode, appsAndFeatureEntry.ProductCode);\n                WRITE_PROPERTY_IF_EXISTS(out, Publisher, appsAndFeatureEntry.Publisher);\n                WRITE_PROPERTY_IF_EXISTS(out, UpgradeCode, appsAndFeatureEntry.UpgradeCode);\n                out << YAML::EndMap;\n            }\n            out << YAML::EndSeq;\n        }\n\n        void ProcessInstallerSwitches(YAML::Emitter& out, const std::map<InstallerSwitchType, string_t>& installerSwitches)\n        {\n            if (installerSwitches.empty())\n            {\n                return;\n            }\n\n            out << YAML::Key << InstallerSwitches;\n            out << YAML::BeginMap;\n            for (auto const& [type, value] : installerSwitches)\n            {\n                WRITE_PROPERTY_IF_EXISTS(out, InstallerSwitchTypeToString(type), value);\n            }\n            out << YAML::EndMap;\n        }\n\n        void ProcessExpectedReturnCodes(YAML::Emitter& out, const std::map<DWORD, ManifestInstaller::ExpectedReturnCodeInfo>& expectedReturnCodes)\n        {\n            if (expectedReturnCodes.empty())\n            {\n                return;\n            }\n\n            out << YAML::Key << ExpectedReturnCodes;\n            out << YAML::BeginSeq;\n            for (const auto& expectedReturnCode : expectedReturnCodes)\n            {\n                out << YAML::BeginMap;\n                WRITE_PROPERTY(out, InstallerReturnCode, std::to_string(expectedReturnCode.first));\n                WRITE_PROPERTY(out, ReturnResponse, ExpectedReturnCodeToString(expectedReturnCode.second.ReturnResponseEnum));\n                WRITE_PROPERTY_IF_EXISTS(out, ReturnResponseUrl, expectedReturnCode.second.ReturnResponseUrl);\n                out << YAML::EndMap;\n            }\n            out << YAML::EndSeq;\n        }\n\n        void ProcessUnsupportedArguments(YAML::Emitter& out, const std::vector<UnsupportedArgumentEnum>& unsupportedArguments)\n        {\n            if (unsupportedArguments.empty())\n            {\n                return;\n            }\n\n            out << YAML::Key << UnsupportedArguments;\n            out << YAML::BeginSeq;\n            for (auto const& unsupportedArg : unsupportedArguments)\n            {\n                if (unsupportedArg != UnsupportedArgumentEnum::Unknown)\r\n                {\r\n                    out << UnsupportedArgumentToString(unsupportedArg);\r\n                }\n            }\n            out << YAML::EndSeq;\n        }\n\n        void ProcessUnsupportedOSArchitecture(YAML::Emitter& out, const std::vector<AppInstaller::Utility::Architecture>& architectures)\n        {\n            if (architectures.empty())\n            {\n                return;\n            }\n\n            out << YAML::Key << UnsupportedOSArchitectures;\n            out << YAML::BeginSeq;\n            for (auto const& architecture : architectures)\n            {\r\n                if (architecture != AppInstaller::Utility::Architecture::Unknown)\r\n                {\r\n                    out << Utility::ToLower(ToString(architecture));\n                }\n            }\n            out << YAML::EndSeq;\n        }\n\n        void ProcessInstallModes(YAML::Emitter& out, const std::vector<InstallModeEnum>& installModes)\n        {\n            if (installModes.empty())\n            {\n                return;\n            }\n\n            out << YAML::Key << InstallModes;\n            out << YAML::BeginSeq;\n            for (auto const& installMode : installModes)\n            {\r\n                if (installMode != InstallModeEnum::Unknown)\r\n                {\r\n                    out << InstallModeToString(installMode);\n                }\n            }\n            out << YAML::EndSeq;\n        }\n\n        void ProcessPlatforms(YAML::Emitter& out, const std::vector<PlatformEnum>& platforms)\n        {\n            if (platforms.empty())\n            {\n                return;\n            }\n            out << YAML::Key << Platform;\n            out << YAML::BeginSeq;\n            for (auto const& platform : platforms)\n            {\r\n                if (platform != PlatformEnum::Unknown)\r\n                {\r\n                    out << PlatformToString(platform);\n                }\n            }\n            out << YAML::EndSeq;\n        }\n\n        void ProcessInstallerSuccessCodes(YAML::Emitter& out, const std::vector<DWORD>& installerSuccessCodes)\n        {\n            if (installerSuccessCodes.empty())\n            {\n                return;\n            }\n\n            out << YAML::Key << InstallerSuccessCodes;\n            out << YAML::BeginSeq;\n            for (auto const& installerSuccessCode : installerSuccessCodes)\n            {\n                out << std::to_string(installerSuccessCode);\n            }\n            out << YAML::EndSeq;\n        }\n\n        void ProcessMarkets(YAML::Emitter& out, const MarketsInfo& marketsInfo)\n        {\n            if (marketsInfo.AllowedMarkets.empty() && marketsInfo.ExcludedMarkets.empty())\n            {\n                return;\n            }\n\n            out << YAML::Key << Markets;\n            out << YAML::BeginMap;\n            ProcessStringSequence(out, AllowedMarkets, marketsInfo.AllowedMarkets);\n            ProcessStringSequence(out, ExcludedMarkets, marketsInfo.ExcludedMarkets);\n            out << YAML::EndMap;\n        }\n\n        void ProcessNestedInstallerFiles(YAML::Emitter& out, const std::vector<NestedInstallerFile>& nestedInstallerFiles)\n        {\n            if (nestedInstallerFiles.empty())\n            {\n                return;\n            }\n\n            out << YAML::Key << NestedInstallerFiles;\n            out << YAML::BeginSeq;\n            for (const auto& nestedInstallerFile : nestedInstallerFiles)\n            {\n                out << YAML::BeginMap;\n                WRITE_PROPERTY(out, NestedInstallerFileRelativeFilePath, nestedInstallerFile.RelativeFilePath);\n                WRITE_PROPERTY_IF_EXISTS(out, PortableCommandAlias, nestedInstallerFile.PortableCommandAlias);\n                out << YAML::EndMap;\n            }\n            out << YAML::EndSeq;\n        }\n\n        void ProcessInstallationMetadataInstalledFiles(YAML::Emitter& out, const std::vector<InstalledFile>& installedFiles)\n        {\n            if (installedFiles.empty())\n            {\n                return;\n            }\n\n            out << YAML::Key << InstallationMetadataFiles;\n            out << YAML::BeginSeq;\n            for (const auto& installedFile : installedFiles)\n            {\n                out << YAML::BeginMap;\n                WRITE_PROPERTY(out, InstallationMetadataRelativeFilePath, installedFile.RelativeFilePath);\n                WRITE_SHA256_PROPERTY_IF_NOT_EMPTY(out, FileSha256, installedFile.FileSha256);\n                WRITE_ENUM_PROPERTY_IF_NOT_UNKNOWN(out, FileType, InstalledFileTypeToString(installedFile.FileType), installedFile.FileType, InstalledFileTypeEnum);\n                WRITE_PROPERTY_IF_EXISTS(out, InvocationParameter, installedFile.InvocationParameter);\n                WRITE_PROPERTY_IF_EXISTS(out, DisplayName, installedFile.DisplayName);\n\n                out << YAML::EndMap;\n            }\n            out << YAML::EndSeq;\n        }\n\n        void ProcessInstallationMetadata(YAML::Emitter& out, const InstallationMetadataInfo& installationMetadata)\n        {\n            if (installationMetadata.DefaultInstallLocation.empty() && installationMetadata.Files.empty())\n            {\n                return;\n            }\n\n            out << YAML::Key << InstallationMetadata;\n            out << YAML::BeginMap;\n            WRITE_PROPERTY_IF_EXISTS(out, DefaultInstallLocation, installationMetadata.DefaultInstallLocation);\n            ProcessInstallationMetadataInstalledFiles(out, installationMetadata.Files);\n            out << YAML::EndMap;\n        }\r\n\r\n        void ProcessAuthentication(YAML::Emitter& out, const Authentication::AuthenticationInfo& authInfo)\n        {\n            if (authInfo.Type == Authentication::AuthenticationType::None)\n            {\n                return;\n            }\n\n            out << YAML::Key << Authentication;\n            out << YAML::BeginMap;\n            WRITE_PROPERTY(out, AuthenticationType, Authentication::AuthenticationTypeToString(authInfo.Type));\n            if (authInfo.MicrosoftEntraIdInfo)\r\n            {\r\n                out << YAML::Key << MicrosoftEntraIdAuthenticationInfo;\r\n                out << YAML::BeginMap;\r\n                WRITE_PROPERTY_IF_EXISTS(out, MicrosoftEntraIdResource, authInfo.MicrosoftEntraIdInfo->Resource);\r\n                WRITE_PROPERTY_IF_EXISTS(out, MicrosoftEntraIdScope, authInfo.MicrosoftEntraIdInfo->Scope);\r\n                out << YAML::EndMap;\n            }\n            out << YAML::EndMap;\n        }\n\n        void ProcessDependencies(YAML::Emitter& out, const DependencyList& dependencies)\n        {\n            if (!dependencies.HasAny())\n            {\n                return;\n            }\n\n            out << YAML::Key << Dependencies;\n            out << YAML::BeginMap;\n\n            if (dependencies.HasAnyOf(DependencyType::WindowsFeature))\n            {\n                out << YAML::Key << WindowsFeatures;\n                out << YAML::BeginSeq;\n                dependencies.ApplyToType(DependencyType::WindowsFeature, [&out](Dependency dependency)\n                    {\n                        out << dependency.Id();\n                    });\n                out << YAML::EndSeq;\n            }\n\n            if (dependencies.HasAnyOf(DependencyType::WindowsLibrary))\n            {\n                out << YAML::Key << WindowsLibraries;\n                out << YAML::BeginSeq;\n                dependencies.ApplyToType(DependencyType::WindowsLibrary, [&out](Dependency dependency)\n                    {\n                        out << dependency.Id();\n                    });\n                out << YAML::EndSeq;\n            }\n\n            if (dependencies.HasAnyOf(DependencyType::Package))\n            {\n                out << YAML::Key << PackageDependencies;\n                out << YAML::BeginSeq;\n                dependencies.ApplyToType(DependencyType::Package, [&out](Dependency dependency)\n                    {\n                        out << YAML::BeginMap;\n                        WRITE_PROPERTY(out, PackageIdentifier, dependency.Id());\n\n                        if (dependency.MinVersion.has_value())\n                        {\n                            WRITE_PROPERTY_IF_EXISTS(out, MinimumVersion, dependency.MinVersion.value().ToString());\n                        }\n\n                        out << YAML::EndMap;\n                    });\n                out << YAML::EndSeq;\n            }\n\n            if (dependencies.HasAnyOf(DependencyType::External))\n            {\n                out << YAML::Key << ExternalDependencies;\n                out << YAML::BeginSeq;\n                dependencies.ApplyToType(DependencyType::External, [&out](Dependency dependency)\n                    {\n                        out << dependency.Id();\n                    });\n                out << YAML::EndSeq;\n            }\n\n            out << YAML::EndMap;\n        }\r\n\n        void ProcessDesiredStateConfiguration(YAML::Emitter& out, const std::vector<DesiredStateConfigurationContainerInfo>& containers)\r\n        {\r\n            if (containers.empty())\r\n            {\r\n                return;\r\n            }\r\n\r\n            out << YAML::Key << DesiredStateConfiguration;\r\n            out << YAML::BeginMap;\n\r\n            // Process PowerShell containers\r\n            bool firstPowerShellContainer = true;\n            for (const auto& container : containers)\r\n            {\r\n                if (container.Type == DesiredStateConfigurationContainerType::PowerShell)\r\n                {\n                    if (firstPowerShellContainer)\r\n                    {\r\n                        out << YAML::Key << DesiredStateConfigurationPowerShell;\n                        out << YAML::BeginSeq;\n                        firstPowerShellContainer = false;\n                    }\r\n\r\n                    out << YAML::BeginMap;\r\n\r\n                    WRITE_PROPERTY(out, DesiredStateConfigurationPowerShellRepositoryURL, container.RepositoryURL);\r\n                    WRITE_PROPERTY(out, DesiredStateConfigurationPowerShellModuleName, container.ModuleName);\r\n\r\n                    out << YAML::Key << DesiredStateConfigurationResources;\r\n                    out << YAML::BeginSeq;\r\n\r\n                    for (const auto& resource : container.Resources)\r\n                    {\r\n                        out << YAML::BeginMap;\r\n                        WRITE_PROPERTY(out, DesiredStateConfigurationPowerShellResourceName, resource.Name);\r\n                        out << YAML::EndMap;\n                    }\r\n\r\n                    out << YAML::EndSeq;\r\n                    out << YAML::EndMap;\n                }\n            }\r\n\r\n            if (!firstPowerShellContainer)\r\n            {\r\n                out << YAML::EndSeq;\r\n            }\r\n\r\n            // Process DSCv3 container\n            bool firstDSCv3Container = true;\n            for (const auto& container : containers)\r\n            {\r\n                if (container.Type == DesiredStateConfigurationContainerType::DSCv3)\r\n                {\n                    if (firstDSCv3Container)\r\n                    {\r\n                        out << YAML::Key << DesiredStateConfigurationDSCv3;\n                        out << YAML::BeginMap;\n                        firstDSCv3Container = false;\n                    }\r\n                    else\r\n                    {\r\n                        THROW_HR_MSG(E_INVALIDARG, \"Cannot have multiple DSCv3 containers.\");\r\n                    }\r\n\r\n                    out << YAML::Key << DesiredStateConfigurationResources;\r\n                    out << YAML::BeginSeq;\r\n\r\n                    for (const auto& resource : container.Resources)\r\n                    {\r\n                        out << YAML::BeginMap;\r\n                        WRITE_PROPERTY(out, DesiredStateConfigurationDSCv3ResourceType, resource.Name);\r\n                        out << YAML::EndMap;\n                    }\r\n\r\n                    out << YAML::EndSeq;\n                    out << YAML::EndMap;\n                }\n            }\r\n\n            out << YAML::EndMap;\n        }\n\n        void ProcessInstallerFields(YAML::Emitter& out, const ManifestInstaller& installer)\n        {\n            WRITE_PROPERTY(out, Architecture, Utility::ToLower(ToString(installer.Arch)));\n            WRITE_PROPERTY(out, InstallerType, InstallerTypeToString(installer.BaseInstallerType));\n            WRITE_ENUM_PROPERTY_IF_NOT_UNKNOWN(out, NestedInstallerType, InstallerTypeToString(installer.NestedInstallerType), installer.NestedInstallerType, InstallerTypeEnum);\n            WRITE_SHA256_PROPERTY_IF_NOT_EMPTY(out, InstallerSha256, installer.Sha256);\n            WRITE_SHA256_PROPERTY_IF_NOT_EMPTY(out, SignatureSha256, installer.SignatureSha256);\n            WRITE_PROPERTY_IF_EXISTS(out, InstallerUrl, installer.Url);\r\n            WRITE_PROPERTY_IF_EXISTS(out, MSStoreProductIdentifier, installer.ProductId);\r\n\n            WRITE_ENUM_PROPERTY_IF_NOT_UNKNOWN(out, Scope, Utility::ToLower(ScopeToString(installer.Scope)), installer.Scope, ScopeEnum);\n            WRITE_PROPERTY_IF_EXISTS(out, InstallerLocale, installer.Locale);\n            WRITE_ENUM_PROPERTY_IF_NOT_UNKNOWN(out, ElevationRequirement, ElevationRequirementToString(installer.ElevationRequirement), installer.ElevationRequirement, ElevationRequirementEnum);\n            WRITE_PROPERTY_IF_EXISTS(out, PackageFamilyName, installer.PackageFamilyName);\n            WRITE_PROPERTY_IF_EXISTS(out, ReleaseDate, installer.ReleaseDate);\n            WRITE_BOOL_PROPERTY(out, InstallerAbortsTerminal, installer.InstallerAbortsTerminal);\n            WRITE_BOOL_PROPERTY(out, InstallLocationRequired, installer.InstallLocationRequired);\n            WRITE_BOOL_PROPERTY(out, RequireExplicitUpgrade, installer.RequireExplicitUpgrade);\n            WRITE_BOOL_PROPERTY(out, DisplayInstallWarnings, installer.DisplayInstallWarnings);\n            WRITE_BOOL_PROPERTY(out, DownloadCommandProhibited, installer.DownloadCommandProhibited);\r\n            WRITE_BOOL_PROPERTY(out, ArchiveBinariesDependOnPath, installer.ArchiveBinariesDependOnPath);\n            WRITE_PROPERTY_IF_EXISTS(out, MinimumOSVersion, installer.MinOSVersion);\n            WRITE_PROPERTY_IF_EXISTS(out, ProductCode, installer.ProductCode);\n            WRITE_ENUM_PROPERTY_IF_NOT_UNKNOWN(out, UpgradeBehavior, UpdateBehaviorToString(installer.UpdateBehavior), installer.UpdateBehavior, UpdateBehaviorEnum);\r\n            WRITE_ENUM_PROPERTY_IF_NOT_UNKNOWN(out, RepairBehavior, RepairBehaviorToString(installer.RepairBehavior), installer.RepairBehavior, RepairBehaviorEnum);\n\n            ProcessStringSequence(out, Capabilities, installer.Capabilities);\n            ProcessStringSequence(out, Commands, installer.Commands);\n            ProcessStringSequence(out, FileExtensions, installer.FileExtensions);\n            ProcessStringSequence(out, Protocols, installer.Protocols);\n            ProcessStringSequence(out, RestrictedCapabilities, installer.RestrictedCapabilities);\n\n            ProcessAppsAndFeaturesEntries(out, installer.AppsAndFeaturesEntries);\n            ProcessDependencies(out, installer.Dependencies);\n            ProcessExpectedReturnCodes(out, installer.ExpectedReturnCodes);\n            ProcessInstallerSwitches(out, installer.Switches);\n            ProcessInstallationMetadata(out, installer.InstallationMetadata);\n            ProcessInstallerSuccessCodes(out, installer.InstallerSuccessCodes);\n            ProcessInstallModes(out, installer.InstallModes);\n            ProcessMarkets(out, installer.Markets);\n            ProcessNestedInstallerFiles(out, installer.NestedInstallerFiles);\n            ProcessPlatforms(out, installer.Platform);\n            ProcessUnsupportedArguments(out, installer.UnsupportedArguments);\n            ProcessUnsupportedOSArchitecture(out, installer.UnsupportedOSArchitectures);\r\n            ProcessAuthentication(out, installer.AuthInfo);\n            ProcessDesiredStateConfiguration(out, installer.DesiredStateConfiguration);\n        }\n\n        void ProcessInstaller(YAML::Emitter& out, const ManifestInstaller& installer)\n        {\n            out << YAML::Key << Installers;\n            out << YAML::BeginSeq;\n            out << YAML::BeginMap;\n            ProcessInstallerFields(out, installer);\n            out << YAML::EndMap;\n            out << YAML::EndSeq;\n        }\n\n        void ProcessLocalizations(YAML::Emitter& out, const std::vector<ManifestLocalization>& localizations)\n        {\n            if (!localizations.empty())\n            {\n                out << YAML::Key << Localization;\n                out << YAML::BeginSeq;\n\n                for (const auto& localization : localizations)\n                {\r\n                    out << YAML::BeginMap;\n                    ProcessLocaleFields(out, localization);\r\n                    out << YAML::EndMap;\n                }\n\n                out << YAML::EndSeq;\n            }\n        }\n\n        void PopulateManifestYamlEmitter(YAML::Emitter& out, const Manifest& manifest, const ManifestInstaller& installer)\n        {\n            // Currently, exporting the yaml only supports outputting a single installer.\n            // TODO: If no single installer is provided, output all installers.\n            out << YAML::BeginMap;\n            WRITE_PROPERTY(out, PackageIdentifier, manifest.Id);\n            WRITE_PROPERTY(out, PackageVersion, manifest.Version);\n            WRITE_PROPERTY_IF_EXISTS(out, Channel, manifest.Channel);\n            WRITE_PROPERTY_IF_EXISTS(out, Moniker, manifest.Moniker);\n            ProcessLocaleFields(out, manifest.DefaultLocalization);\n            ProcessLocalizations(out, manifest.Localizations);\n            ProcessInstaller(out, installer);\n            WRITE_PROPERTY(out, ManifestVersion, manifest.ManifestVersion.ToString());\n\n            ManifestTypeEnum manifestType = ManifestTypeEnum::Merged;\n            WRITE_PROPERTY(out, ManifestType, ManifestTypeToString(manifestType));\n            out << YAML::EndMap;\n        }\n    }\n\n    std::string YamlWriter::ManifestToYamlString(const Manifest& manifest, const ManifestInstaller& installer)\n    {\n        YAML::Emitter out;\n        PopulateManifestYamlEmitter(out, manifest, installer);\n        return out.str();\n    }\n\n    void YamlWriter::OutputYamlFile(const Manifest& manifest, const ManifestInstaller& installer, const std::filesystem::path& out)\n    {\n        const std::filesystem::path& parentDirectory = out.parent_path();\n\n        if (!std::filesystem::exists(parentDirectory))\n        {\n            std::filesystem::create_directories(parentDirectory);\n        }\n        else\n        {\n            THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_CANNOT_MAKE), !std::filesystem::is_directory(parentDirectory));\n        }\n\n        YAML::Emitter emitter;\n        PopulateManifestYamlEmitter(emitter, manifest, installer);\n\n        std::ofstream outFileStream(out);\n        emitter.Emit(outFileStream);\n        outFileStream.close();\n    }\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/MsiExecArguments.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/MsiExecArguments.h\"\r\n#include \"Public/AppInstallerErrors.h\"\r\n#include \"Public/AppInstallerLogging.h\"\r\n#include \"Public/AppInstallerStrings.h\"\r\n\r\n\r\nnamespace AppInstaller::Msi\r\n{\r\n    using namespace std::string_view_literals;\r\n\r\n    namespace\r\n    {\r\n        const char MsiExecQuietOption = 'q';\r\n        const char MsiExecLogOption = 'l';\r\n\r\n        // Description of how a long option is replaced by a short option.\r\n        struct TokenReplacement\r\n        {\r\n            TokenReplacement(std::string_view longOption, std::string_view shortOption) : LongOption(longOption), ShortOption({ shortOption }) {}\r\n            TokenReplacement(std::string_view longOption, std::vector<std::string_view>&& shortOption) : LongOption(longOption), ShortOption(std::move(shortOption)) {}\r\n            std::string_view LongOption;\r\n            std::vector<std::string_view> ShortOption;\r\n        };\r\n\r\n        // Determines whether an argument token is a switch/option.\r\n        bool IsSwitch(std::string_view token)\r\n        {\r\n            THROW_HR_IF(APPINSTALLER_CLI_ERROR_INTERNAL_ERROR, token.empty());\r\n            return token[0] == '-' || token[0] == '/';\r\n        }\r\n\r\n        // Parses the log mode and log file for the Log (/l) option.\r\n        // The option has a modifier specifying the log mode (what is logged)\r\n        // and a value specifying the log file.\r\n        // E.g. /l* log.txt, /lw warnings.txt\r\n        void ParseLogOption(std::string_view logModeString, std::string_view logFile, MsiParsedArguments& parsedArgs)\r\n        {\r\n            if (Utility::IsEmptyOrWhitespace(logFile))\r\n            {\r\n                AICLI_LOG(Core, Error, << \"MSI log file path cannot be empty\");\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT);\r\n            }\r\n\r\n            INSTALLLOGMODE logMode = {};\r\n            INSTALLLOGATTRIBUTES logAttributes = {};\r\n\r\n            // Note: These flags are mostly consecutive bits in the order given, except where indicated.\r\n            // Skipped flags are not mapped to a command line option.\r\n            std::map<char, INSTALLLOGMODE> ValidLogModes\r\n            {\r\n                { 'm', INSTALLLOGMODE_FATALEXIT },\r\n                { 'e', INSTALLLOGMODE_ERROR },\r\n                { 'w', INSTALLLOGMODE_WARNING },\r\n                { 'u', INSTALLLOGMODE_USER },\r\n                { 'i', INSTALLLOGMODE_INFO },\r\n                // FILESINUSE\r\n                // RESOLVESOURCE\r\n                { 'o', INSTALLLOGMODE_OUTOFDISKSPACE },\r\n                { 'a', INSTALLLOGMODE_ACTIONSTART },\r\n                { 'r', INSTALLLOGMODE_ACTIONDATA },\r\n                { 'p', INSTALLLOGMODE_PROPERTYDUMP },\r\n                { 'c', INSTALLLOGMODE_COMMONDATA },\r\n                { 'v', INSTALLLOGMODE_VERBOSE },\r\n                { 'x', INSTALLLOGMODE_EXTRADEBUG },\r\n                // LOGONLYONERROR\r\n                // LOGPERFORMANCE\r\n            };\r\n\r\n            std::map<char, INSTALLLOGATTRIBUTES> ValidLogAttributes\r\n            {\r\n                { '+', INSTALLLOGATTRIBUTES_APPEND },\r\n                { '!', INSTALLLOGATTRIBUTES_FLUSHEACHLINE },\r\n            };\r\n\r\n            bool isLogModeSet = false;\r\n            for (char c : logModeString)\r\n            {\r\n                // Log-all option\r\n                if (c == '*')\r\n                {\r\n                    logMode |= AllLogMode;\r\n                    isLogModeSet = true;\r\n                    continue;\r\n                }\r\n\r\n                auto modeItr = ValidLogModes.find(c);\r\n                if (modeItr != ValidLogModes.end())\r\n                {\r\n                    logMode |= modeItr->second;\r\n                    isLogModeSet = true;\r\n                    continue;\r\n                }\r\n\r\n                auto attributeItr = ValidLogAttributes.find(c);\r\n                if (attributeItr != ValidLogAttributes.end())\r\n                {\r\n                    logAttributes |= attributeItr->second;\r\n                    continue;\r\n                }\r\n\r\n                AICLI_LOG(Core, Error, << \"Unknown msiexec log modifier: \" << c);\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT);\r\n            }\r\n\r\n            if (!isLogModeSet)\r\n            {\r\n                logMode = DefaultLogMode;\r\n            }\r\n\r\n            parsedArgs.LogMode = logMode;\r\n            parsedArgs.LogAttributes = logAttributes;\r\n            parsedArgs.LogFile = Utility::ConvertToUTF16(logFile);\r\n        }\r\n\r\n        // Parses the modifier for the UI Level option (/q)\r\n        // The modifier starts with a base (b, f, n, r), followed by extra flags (+, -, !).\r\n        // E.g. /qn, /qb-!\r\n        void ParseQuietOption(std::string_view modifier, MsiParsedArguments& parsedArgs)\r\n        {\r\n            if (modifier.empty())\r\n            {\r\n                // /q is treated as equivalent to /qn\r\n                modifier = \"n\"sv;\r\n            }\r\n\r\n            // Lower values in INSTALLUILEVEL work like a base enum (e.g. None=2, Basic=3)\r\n            // with higher values being modifying flags (e.g. HideCancel=0x20, ProgressOnly=0x40).\r\n            // Some steps depend on the base enum, so we keep it separate for easier checking.\r\n            INSTALLUILEVEL uiLevelBase = {};\r\n            INSTALLUILEVEL uiLevelModifiers = {};\r\n\r\n            // Parse the base level\r\n            switch (std::tolower(modifier[0]))\r\n            {\r\n            case 'f':\r\n                uiLevelBase = INSTALLUILEVEL_FULL;\r\n                break;\r\n            case 'r':\r\n                uiLevelBase = INSTALLUILEVEL_REDUCED;\r\n                break;\r\n            case 'b':\r\n                uiLevelBase = INSTALLUILEVEL_BASIC;\r\n                break;\r\n            case '+':\r\n                uiLevelBase = INSTALLUILEVEL_NONE;\r\n                uiLevelModifiers = INSTALLUILEVEL_ENDDIALOG;\r\n                break;\r\n            case 'n':\r\n                uiLevelBase = INSTALLUILEVEL_NONE;\r\n                break;\r\n            default:\r\n                AICLI_LOG(Core, Error, << \"Invalid modifier for msiexec /q argument: \" << modifier);\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT);\r\n            };\r\n\r\n            // Parse the modifiers\r\n            for (size_t i = 1; i < modifier.size(); ++i)\r\n            {\r\n                const char c = modifier[i];\r\n\r\n                if (c == '+')\r\n                {\r\n                    WI_SetFlag(uiLevelModifiers, INSTALLUILEVEL_ENDDIALOG);\r\n                }\r\n                else if (c == '-')\r\n                {\r\n                    if (uiLevelBase == INSTALLUILEVEL_BASIC)\r\n                    {\r\n                        WI_SetFlag(uiLevelModifiers, INSTALLUILEVEL_PROGRESSONLY);\r\n                    }\r\n                    else\r\n                    {\r\n                        AICLI_LOG(Core, Error, << \"msiexec UI option Progress Only (-) is only valid with UI level Basic (b)\");\r\n                        THROW_HR(APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT);\r\n                    }\r\n                }\r\n                else if (c == '!')\r\n                {\r\n                    if (uiLevelBase == INSTALLUILEVEL_BASIC)\r\n                    {\r\n                        WI_SetFlag(uiLevelModifiers, INSTALLUILEVEL_HIDECANCEL);\r\n                    }\r\n                    else\r\n                    {\r\n                        AICLI_LOG(Core, Error, << \"msiexec UI option Hide Cancel (!) is only valid with UI level Basic (b)\");\r\n                        THROW_HR(APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT);\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Only deviation from msiexec:\r\n            // When using UI Level None, allow showing the UAC prompt.\r\n            WI_SetFlagIf(uiLevelModifiers, INSTALLUILEVEL_UACONLY, uiLevelBase == INSTALLUILEVEL_NONE);\r\n\r\n            parsedArgs.UILevel = uiLevelBase | uiLevelModifiers;\r\n        }\r\n\r\n        bool IsWhiteSpace(char c)\r\n        {\r\n            return c == ' ' || c == '\\t';\r\n        }\r\n\r\n        // Gets the next token found in the arguments string, starting the search on the given position.\r\n        // If there are no more tokens, return empty.\r\n        // After finding the token, updates `start` to point to the next place we need to start the next token search.\r\n        std::string_view GetNextToken(std::string_view arguments, size_t& start)\r\n        {\r\n            // Eat leading whitespace\r\n            while (start < arguments.size() && IsWhiteSpace(arguments[start]))\r\n            {\r\n                ++start;\r\n            }\r\n\r\n            if (start >= arguments.size())\r\n            {\r\n                // We reached the end\r\n                return {};\r\n            }\r\n\r\n            size_t pos = start;\r\n            bool seekingSpaceSeparator = ('\"' != arguments[pos]);\r\n            bool withinQuotes = false;\r\n\r\n            // Start looking from the next character\r\n            ++pos;\r\n\r\n            // Advance until we hit the end or the next separator\r\n            while (pos < arguments.size())\r\n            {\r\n                bool isSpace = IsWhiteSpace(arguments[pos]);\r\n                bool isQuote = ('\"' == arguments[pos]);\r\n\r\n                if (isSpace || isQuote)\r\n                {\r\n                    // We've encountered one of the two separators we're interested in\r\n                    if (seekingSpaceSeparator)\r\n                    {\r\n                        if (isQuote)\r\n                        {\r\n                            // We will ignore space characters enclosed between double quotes\r\n                            withinQuotes = !withinQuotes;\r\n                        }\r\n                        else\r\n                        {\r\n                            // This is a space character. If it is between quotes we ignore it;\r\n                            // otherwise it is a separator.\r\n                            if (!withinQuotes)\r\n                            {\r\n                                break;\r\n                            }\r\n                        }\r\n                    }\r\n                    else\r\n                    {\r\n                        if (isQuote)\r\n                        {\r\n                            // we've got what we needed, it is OK to stop\r\n                            break;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                ++pos;\r\n            }\r\n\r\n            if (!seekingSpaceSeparator)\r\n            {\r\n                // We were looking for a terminating \" character.\r\n                if (pos < arguments.size())\r\n                {\r\n                    // We move past the \" character (it is OK for the end of the line\r\n                    // to act as the matching \" character in some cases)\r\n                    ++pos;\r\n                }\r\n            }\r\n\r\n            auto result = arguments.substr(start, pos - start);\r\n            start = pos;\r\n            return result;\r\n        }\r\n\r\n        // Split the arguments string into tokens. Tokens are delimited by whitespace\r\n        // unless quoted. Each token represents an option (like /q), an argument\r\n        // for an option, or a property.\r\n        std::list<std::string> TokenizeMsiArguments(std::string_view arguments)\r\n        {\r\n            size_t start = 0;\r\n            std::list<std::string> result;\r\n            auto token = GetNextToken(arguments, start);\r\n            while (!token.empty())\r\n            {\r\n                result.emplace_back(token);\r\n                token = GetNextToken(arguments, start);\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        // Parses a token that represents an argument to an option.\r\n        // If the value is unquoted, returns it as is.\r\n        // If the value is quoted, removes the quotes and replaces escaped characters.\r\n        std::string ParseValue(std::string_view valueToken)\r\n        {\r\n            if (valueToken.empty() || valueToken[0] != '\"')\r\n            {\r\n                // Nothing to do for empty or unquoted tokens\r\n                return std::string{ valueToken };\r\n            }\r\n\r\n            // Copy the string ignoring the quotes and replacing escaped characters.\r\n            // In quoted tokens, the back quote represents double quotes (` means \")\r\n            // and can be escaped with back slash (\\` means `).\r\n            // Note that we accept quoted values with a missing closing quote (the end\r\n            // of string signals the end).\r\n            std::string result;\r\n            for (size_t i = 1; i < valueToken.size(); ++i)\r\n            {\r\n                if (valueToken[i] == '\"')\r\n                {\r\n                    // The tokenizer can leave several pairs of quotes in the token\r\n                    // but they are not accepted in this case. We only accept the final\r\n                    // closing quotes.\r\n                    if (i + 1 == valueToken.size())\r\n                    {\r\n                        break;\r\n                    }\r\n                    else\r\n                    {\r\n                        AICLI_LOG(Core, Error, << \"Invalid msiexec argument: \" << valueToken);\r\n                        THROW_HR(APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT);\r\n                    }\r\n                }\r\n\r\n                if (i + 1 < valueToken.size() && valueToken[i] == '\\\\' && valueToken[i + 1] == '`')\r\n                {\r\n                    result += '`';\r\n                    ++i;\r\n                }\r\n                else if (valueToken[i] == '`')\r\n                {\r\n                    result += '\"';\r\n                }\r\n                else\r\n                {\r\n                    result += valueToken[i];\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        // Validates that a token represents a property.\r\n        // This checks that the property has the form PropertyName=Value,\r\n        // with the value optionally quoted.\r\n        bool IsValidPropertyToken(std::string_view token)\r\n        {\r\n            THROW_HR_IF(APPINSTALLER_CLI_ERROR_INTERNAL_ERROR, token.empty());\r\n\r\n            if (token[0] != '%' && !IsCharAlphaNumericA(token[0]))\r\n            {\r\n                AICLI_LOG(Core, Error, << \"Bad property for msiexec: \" << token);\r\n                return false;\r\n            }\r\n\r\n            // Find the = separator at the end of the property name\r\n            size_t pos = 0;\r\n            while (pos < token.size() && !IsWhiteSpace(token[pos]) && token[pos] != '=')\r\n            {\r\n                ++pos;\r\n            }\r\n\r\n            if (pos == token.size() || token[pos] != '=')\r\n            {\r\n                AICLI_LOG(Core, Error, << \"Expected property for call to msiexec, but couldn't find separator: \" << token);\r\n                return false;\r\n            }\r\n\r\n            // Validate the property value.\r\n            // It should be completely enclosed in quotes, or not contain white space.\r\n            // If quoted, there can be pairs of consecutive quotes that work as escape sequences.\r\n            // We accept empty property values.\r\n            ++pos;\r\n            if (pos == token.size())\r\n            {\r\n                // Empty value\r\n                return true;\r\n            }\r\n\r\n            // If quoted, we will only inspect the values between the quotes.\r\n            bool quoted = false;\r\n            size_t end = token.size();\r\n            if (token[pos] == '\"')\r\n            {\r\n                ++pos;\r\n\r\n                if (pos >= end || token.back() != '\"')\r\n                {\r\n                    AICLI_LOG(Core, Error, << \"Badly quoted msiexec property: \" << token);\r\n                    THROW_HR(APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT);\r\n                }\r\n\r\n                --end;\r\n                quoted = true;\r\n            }\r\n\r\n            while (pos < end)\r\n            {\r\n                if (quoted)\r\n                {\r\n                    // For quoted values, any internal quote must be followed by another one.\r\n                    if (token[pos] == '\"')\r\n                    {\r\n                        if (pos + 1 < end && token[pos + 1] == '\"')\r\n                        {\r\n                            // Skip the two quotes\r\n                            ++pos;\r\n                        }\r\n                        else\r\n                        {\r\n                            AICLI_LOG(Core, Error, << \"Unexpected quotes in msiexec property arg: \" << token);\r\n                            THROW_HR(APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT);\r\n                        }\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    // For unquoted values, we only check that there is no whitespace\r\n                    if (IsWhiteSpace(token[pos]))\r\n                    {\r\n                        AICLI_LOG(Core, Error, << \"Unexpected space in msiexec property arg: \" << token);\r\n                        THROW_HR(APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT);\r\n                    }\r\n                }\r\n\r\n                ++pos;\r\n            }\r\n\r\n            return true;\r\n        }\r\n\r\n        // Replaces long options in the arguments (e.g. /quiet), by their short equivalents\r\n        // (e.g. /qn). The replacement is done in-place.\r\n        void ReplaceLongOptions(std::list<std::string>& tokens)\r\n        {\r\n            // We don't handle all possible options because we don't need to.\r\n            // Options not handled:\r\n            //   /update\r\n            //   /uninstall\r\n            //   /package\r\n            //   /help\r\n            const std::vector<TokenReplacement> Replacements\r\n            {\r\n                { \"quiet\"sv, \"/qn\"sv },\r\n                { \"passive\"sv, { \"/qb!-\"sv, \"REBOOTPROMPT=S\"sv } },\r\n                { \"norestart\"sv, \"REBOOT=ReallySuppress\"sv },\r\n                { \"forcerestart\"sv, \"REBOOT=Force\"sv },\r\n                { \"promptrestart\"sv, \"REBOOTPROMPT=\\\"\\\"\"sv },\r\n                { \"log\"sv, \"/l*\"sv },\r\n            };\r\n\r\n            auto itr = tokens.begin();\r\n            while (itr != tokens.end())\r\n            {\r\n                if (!IsSwitch(*itr))\r\n                {\r\n                    // We only need to replace switches.\r\n                    ++itr;\r\n                    continue;\r\n                }\r\n\r\n                // Find if there is a replacement for this option.\r\n                // We ignore the leading / or - when comparing.\r\n                auto option = std::string_view(*itr).substr(1);\r\n                auto replacementItr = std::find_if(Replacements.begin(), Replacements.end(), [&](const TokenReplacement& replacement) { return Utility::CaseInsensitiveEquals(replacement.LongOption, option); });\r\n                if (replacementItr == Replacements.end())\r\n                {\r\n                    // There is no replacement for this switch;\r\n                    ++itr;\r\n                    continue;\r\n                }\r\n\r\n                // Add all the replacements tokens needed before this one, then delete the existing token.\r\n                tokens.insert(itr, replacementItr->ShortOption.begin(), replacementItr->ShortOption.end());\r\n\r\n                // Delete the current token an move to the next one.\r\n                // We don't need to do anything more to the newly added tokens.\r\n                itr = tokens.erase(itr);\r\n            }\r\n        }\r\n\r\n        // Consumes the next argument token in the list. If the token is an option\r\n        // that takes an argument, also consumes it. After consuming the token(s),\r\n        // removes it from the list and updates the parsed arguments accordingly.\r\n        void ConsumeNextToken(std::list<std::string>& tokens, MsiParsedArguments& parsedArgs)\r\n        {\r\n            THROW_HR_IF(APPINSTALLER_CLI_ERROR_INTERNAL_ERROR, tokens.empty());\r\n\r\n            auto token = std::move(tokens.front());\r\n            tokens.pop_front();\r\n            if (!IsSwitch(token))\r\n            {\r\n                // Token is a property, i.e. NAME=value. Add it to the parsed args.\r\n                THROW_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT, !IsValidPropertyToken(token));\r\n                parsedArgs.Properties += L\" \" + Utility::ConvertToUTF16(token);\r\n                return;\r\n            }\r\n\r\n            // Token is an option.\r\n            if (token.size() <= 1)\r\n            {\r\n                AICLI_LOG(Core, Error, << \"Invalid command line argument for msiexec: \" << token);\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT);\r\n            }\r\n\r\n            char option = token[1];\r\n            auto optionModifier = ParseValue(std::string_view(token).substr(2));\r\n\r\n            // Options are case-insensitive\r\n            switch (std::tolower(option))\r\n            {\r\n            case MsiExecQuietOption:\r\n            {\r\n                ParseQuietOption(optionModifier, parsedArgs);\r\n                break;\r\n            }\r\n            case MsiExecLogOption:\r\n            {\r\n                if (tokens.empty())\r\n                {\r\n                    // Log option must be followed by an option argument\r\n                    AICLI_LOG(Core, Error, << \"msiexec option \" << token << \" must be followed by a value\");\r\n                    THROW_HR(APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT);\r\n                }\r\n\r\n                const auto optionValue = ParseValue(tokens.front());\r\n                tokens.pop_front();\r\n\r\n                ParseLogOption(optionModifier, optionValue, parsedArgs);\r\n                break;\r\n            }\r\n            default:\r\n            {\r\n                AICLI_LOG(Core, Error, << \"Invalid option for msiexec: \" << token);\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT);\r\n            }\r\n            }\r\n        }\r\n    }\r\n\r\n    MsiParsedArguments ParseMSIArguments(std::string_view arguments)\r\n    {\r\n        // Split the arguments into tokens, which we will process one by one.\r\n        auto argumentTokens = TokenizeMsiArguments(arguments);\r\n\r\n        // Replace long options so we can work only with short ones.\r\n        ReplaceLongOptions(argumentTokens);\r\n\r\n        // Process the arguments.\r\n        MsiParsedArguments result;\r\n        while (!argumentTokens.empty())\r\n        {\r\n            ConsumeNextToken(argumentTokens, result);\r\n        }\r\n\r\n        return result;\r\n    }\r\n}"
  },
  {
    "path": "src/AppInstallerCommonCore/MsixInfo.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/AppInstallerMsixInfo.h\"\r\n#include \"HttpStream/HttpRandomAccessStream.h\"\r\n#include \"Public/AppInstallerDownloader.h\"\r\n#include \"Public/AppInstallerLogging.h\"\r\n#include \"Public/AppInstallerStrings.h\"\r\n#include \"Public/AppInstallerDownloader.h\"\r\n#include \"Public/AppInstallerRuntime.h\"\r\n\r\nusing namespace winrt::Windows::Storage::Streams;\r\nusing namespace Microsoft::WRL;\r\nusing namespace AppInstaller::Utility::HttpStream;\r\nusing namespace winrt::Windows::Management::Deployment;\r\n\r\nnamespace AppInstaller::Msix\r\n{\r\n    namespace\r\n    {\r\n        // MSIX-specific header placed in the P7X file, before the actual signature\r\n        const byte P7xFileId[] = { 0x50, 0x4b, 0x43, 0x58 };\r\n        const DWORD P7xFileIdSize = sizeof(P7xFileId);\r\n\r\n        // Gets the version from the manifest reader.\r\n        UINT64 GetVersionFromManifestReader(IAppxManifestReader* reader)\r\n        {\r\n            ComPtr<IAppxManifestPackageId> packageId;\r\n            THROW_IF_FAILED(reader->GetPackageId(&packageId));\r\n\r\n            UINT64 result = 0;\r\n            THROW_IF_FAILED(packageId->GetVersion(&result));\r\n\r\n            return result;\r\n        }\r\n\r\n        // Gets the UINT64 version from the version struct.\r\n        UINT64 GetVersionFromVersion(const winrt::Windows::ApplicationModel::PackageVersion& version)\r\n        {\r\n            UINT64 result = version.Major;\r\n            result = (result << 16) | version.Minor;\r\n            result = (result << 16) | version.Build;\r\n            result = (result << 16) | version.Revision;\r\n\r\n            return result;\r\n        }\r\n\r\n        // Writes the stream (from current location) to the given file.\r\n        void WriteStreamToFile(IStream* stream, UINT64 expectedSize, const std::filesystem::path& target, IProgressCallback& progress)\r\n        {\r\n            std::filesystem::path tempFile = target;\r\n            tempFile += \".dnld\";\r\n\r\n            {\r\n                std::ofstream file(tempFile, std::ios_base::binary | std::ios_base::out | std::ios_base::trunc);\r\n\r\n                constexpr ULONG bufferSize = 1 << 20;\r\n                std::unique_ptr<char[]> buffer = std::make_unique<char[]>(bufferSize);\r\n\r\n                UINT64 totalBytesRead = 0;\r\n\r\n                while (!progress.IsCancelledBy(CancelReason::Any))\r\n                {\r\n                    ULONG bytesRead = 0;\r\n                    HRESULT hr = stream->Read(buffer.get(), bufferSize, &bytesRead);\r\n\r\n                    if (bytesRead)\r\n                    {\r\n                        // If we got bytes, just accept them and keep going.\r\n                        LOG_IF_FAILED(hr);\r\n\r\n                        THROW_HR_IF_MSG(E_UNEXPECTED, expectedSize && totalBytesRead + bytesRead > expectedSize, \"Read more bytes than expected size\");\r\n\r\n                        file.write(buffer.get(), bytesRead);\r\n                        totalBytesRead += bytesRead;\r\n                        progress.OnProgress(totalBytesRead, expectedSize, ProgressType::Bytes);\r\n                    }\r\n                    else\r\n                    {\r\n                        // If given a size, and we have read it all, quit\r\n                        if (expectedSize && totalBytesRead == expectedSize)\r\n                        {\r\n                            break;\r\n                        }\r\n\r\n                        // If the stream returned an error, throw it\r\n                        THROW_IF_FAILED(hr);\r\n\r\n                        // If we were given a size and didn't reach it, throw our own error;\r\n                        // otherwise assume that this is just normal EOF.\r\n                        if (expectedSize)\r\n                        {\r\n                            THROW_WIN32(ERROR_HANDLE_EOF);\r\n                        }\r\n                        else\r\n                        {\r\n                            break;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            std::filesystem::path backupFile = target;\r\n            backupFile += \".bkup\";\r\n            if (std::filesystem::exists(target))\r\n            {\r\n                if (std::filesystem::exists(backupFile))\r\n                {\r\n                    std::filesystem::remove(backupFile);\r\n                }\r\n                std::filesystem::rename(target, backupFile);\r\n            }\r\n\r\n            std::filesystem::rename(tempFile, target);\r\n        }\r\n\r\n        // Writes the appx file to the given file.\r\n        void WriteAppxFileToFile(IAppxFile* appxFile, const std::filesystem::path& target, IProgressCallback& progress)\r\n        {\r\n            UINT64 size = 0;\r\n            THROW_IF_FAILED(appxFile->GetSize(&size));\r\n\r\n            ComPtr<IStream> stream;\r\n            THROW_IF_FAILED(appxFile->GetStream(&stream));\r\n\r\n            WriteStreamToFile(stream.Get(), size, target, progress);\r\n        }\r\n\r\n        // Writes the stream (from current location) to the given file handle.\r\n        void WriteStreamToFileHandle(IStream* stream, UINT64 expectedSize, HANDLE target, IProgressCallback& progress)\r\n        {\r\n            constexpr ULONG bufferSize = 1 << 20;\r\n            std::unique_ptr<char[]> buffer = std::make_unique<char[]>(bufferSize);\r\n\r\n            UINT64 totalBytesRead = 0;\r\n\r\n            while (!progress.IsCancelledBy(CancelReason::Any))\r\n            {\r\n                ULONG bytesRead = 0;\r\n                HRESULT hr = stream->Read(buffer.get(), bufferSize, &bytesRead);\r\n\r\n                if (bytesRead)\r\n                {\r\n                    // If we got bytes, just accept them and keep going.\r\n                    LOG_IF_FAILED(hr);\r\n\r\n                    THROW_HR_IF_MSG(E_UNEXPECTED, expectedSize && totalBytesRead + bytesRead > expectedSize, \"Read more bytes than expected size\");\r\n\r\n                    DWORD bytesWritten = 0;\r\n                    THROW_LAST_ERROR_IF(!WriteFile(target, buffer.get(), bytesRead, &bytesWritten, nullptr));\r\n                    THROW_HR_IF(E_UNEXPECTED, bytesRead != bytesWritten);\r\n                    totalBytesRead += bytesRead;\r\n                    progress.OnProgress(totalBytesRead, expectedSize, ProgressType::Bytes);\r\n                }\r\n                else\r\n                {\r\n                    // If given a size, and we have read it all, quit\r\n                    if (expectedSize && totalBytesRead == expectedSize)\r\n                    {\r\n                        break;\r\n                    }\r\n\r\n                    // If the stream returned an error, throw it\r\n                    THROW_IF_FAILED(hr);\r\n\r\n                    // If we were given a size and didn't reach it, throw our own error;\r\n                    // otherwise assume that this is just normal EOF.\r\n                    if (expectedSize)\r\n                    {\r\n                        THROW_WIN32(ERROR_HANDLE_EOF);\r\n                    }\r\n                    else\r\n                    {\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // Writes the appx file to the given file handle.\r\n        void WriteAppxFileToFileHandle(IAppxFile* appxFile, HANDLE target, IProgressCallback& progress)\r\n        {\r\n            UINT64 size = 0;\r\n            THROW_IF_FAILED(appxFile->GetSize(&size));\r\n\r\n            ComPtr<IStream> stream;\r\n            THROW_IF_FAILED(appxFile->GetStream(&stream));\r\n\r\n            WriteStreamToFileHandle(stream.Get(), size, target, progress);\r\n        }\r\n\r\n        bool ValidateMsixTrustInfo(const std::filesystem::path& msixPath, bool verifyMicrosoftOrigin)\r\n        {\r\n            bool result = false;\r\n            AICLI_LOG(Core, Info, << \"Started trust validation of msix at: \" << msixPath);\r\n\r\n            try\r\n            {\r\n                bool verifyChainResult = false;\r\n\r\n                // First verify certificate chain if requested.\r\n                if (verifyMicrosoftOrigin)\r\n                {\r\n                    auto [certContext, certStore] = GetCertContextFromMsix(msixPath);\r\n\r\n                    // Get certificate chain context for validation\r\n                    CERT_CHAIN_PARA certChainParameters = { 0 };\r\n                    certChainParameters.cbSize = sizeof(CERT_CHAIN_PARA);\r\n                    certChainParameters.RequestedUsage.dwType = USAGE_MATCH_TYPE_AND;\r\n                    DWORD certChainFlags = CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL;\r\n\r\n                    wil::unique_cert_chain_context certChainContext;\r\n                    THROW_LAST_ERROR_IF(!CertGetCertificateChain(\r\n                        HCCE_LOCAL_MACHINE,\r\n                        certContext.get(),\r\n                        NULL,   // Use the current system time for CRL validation\r\n                        certStore.get(),\r\n                        &certChainParameters,\r\n                        certChainFlags,\r\n                        NULL,   // Reserved parameter; must be NULL\r\n                        &certChainContext));\r\n\r\n                    // Validate that the certificate chain is rooted in one of the well-known Microsoft root certs\r\n                    CERT_CHAIN_POLICY_PARA policyParameters = { 0 };\r\n                    policyParameters.cbSize = sizeof(CERT_CHAIN_POLICY_PARA);\r\n                    policyParameters.dwFlags = MICROSOFT_ROOT_CERT_CHAIN_POLICY_CHECK_APPLICATION_ROOT_FLAG;\r\n                    CERT_CHAIN_POLICY_STATUS policyStatus = { 0 };\r\n                    policyStatus.cbSize = sizeof(CERT_CHAIN_POLICY_STATUS);\r\n                    LPCSTR policyOid = CERT_CHAIN_POLICY_MICROSOFT_ROOT;\r\n                    BOOL certChainVerifySucceeded = CertVerifyCertificateChainPolicy(\r\n                        policyOid,\r\n                        certChainContext.get(),\r\n                        &policyParameters,\r\n                        &policyStatus);\r\n\r\n                    AICLI_LOG(Core, Info, << \"Result for certificate chain validation of Microsoft origin: \" << policyStatus.dwError);\r\n\r\n                    verifyChainResult = certChainVerifySucceeded && policyStatus.dwError == ERROR_SUCCESS;\r\n                }\r\n                else\r\n                {\r\n                    verifyChainResult = true;\r\n                }\r\n\r\n                // If certificate chain origin validation is success or not requested, then validate the trust info of the file.\r\n                if (verifyChainResult)\r\n                {\r\n                    // Set up the structures needed for the WinVerifyTrust call\r\n                    WINTRUST_FILE_INFO fileInfo = { 0 };\r\n                    fileInfo.cbStruct = sizeof(WINTRUST_FILE_INFO);\r\n                    fileInfo.pcwszFilePath = msixPath.c_str();\r\n\r\n                    WINTRUST_DATA trustData = { 0 };\r\n                    trustData.cbStruct = sizeof(WINTRUST_DATA);\r\n                    trustData.dwUIChoice = WTD_UI_NONE;\r\n                    trustData.fdwRevocationChecks = WTD_REVOKE_WHOLECHAIN;\r\n                    trustData.dwUnionChoice = WTD_CHOICE_FILE;\r\n                    trustData.dwStateAction = WTD_STATEACTION_VERIFY;\r\n                    trustData.dwProvFlags = WTD_CACHE_ONLY_URL_RETRIEVAL;\r\n                    trustData.pFile = &fileInfo;\r\n\r\n                    GUID verifyActionId = WINTRUST_ACTION_GENERIC_VERIFY_V2;\r\n\r\n                    HRESULT verifyTrustResult = static_cast<HRESULT>(WinVerifyTrust(static_cast<HWND>(INVALID_HANDLE_VALUE), &verifyActionId, &trustData));\r\n                    AICLI_LOG(Core, Info, << \"Result for trust info validation of the msix: \" << verifyTrustResult);\r\n\r\n                    result = verifyTrustResult == S_OK;\r\n                }\r\n            }\r\n            catch (const wil::ResultException& re)\r\n            {\r\n                AICLI_LOG(Core, Error, << \"Failed during msix trust validation. Error: \" << re.GetErrorCode());\r\n                result = false;\r\n            }\r\n            catch (...)\r\n            {\r\n                AICLI_LOG(Core, Error, << \"Failed during msix trust validation.\");\r\n                result = false;\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n\r\n    bool GetBundleReader(\r\n        IStream* inputStream,\r\n        IAppxBundleReader** reader)\r\n    {\r\n        ComPtr<IAppxBundleFactory> bundleFactory;\r\n\r\n        // Create a new Appxbundle factory\r\n        THROW_IF_FAILED(CoCreateInstance(\r\n            __uuidof(AppxBundleFactory),\r\n            nullptr,\r\n            CLSCTX_INPROC_SERVER,\r\n            __uuidof(IAppxBundleFactory),\r\n            (LPVOID*)(&bundleFactory)));\r\n\r\n        HRESULT hr = bundleFactory->CreateBundleReader(inputStream, reader);\r\n\r\n        if (SUCCEEDED(hr))\r\n        {\r\n            return true;\r\n        }\r\n        else if (hr == APPX_E_MISSING_REQUIRED_FILE)\r\n        {\r\n            // APPX_E_MISSING_REQUIRED_FILE returned when trying to open\r\n            // an *.msix as an *.msixbundle or vice-versa.\r\n            return false;\r\n        }\r\n        else\r\n        {\r\n            THROW_HR(hr);\r\n        }\r\n    }\r\n\r\n    bool GetPackageReader(\r\n        IStream* inputStream,\r\n        IAppxPackageReader** reader)\r\n    {\r\n        ComPtr<IAppxFactory> appxFactory;\r\n\r\n        // Create a new Appx factory\r\n        THROW_IF_FAILED(CoCreateInstance(\r\n            __uuidof(AppxFactory),\r\n            nullptr,\r\n            CLSCTX_INPROC_SERVER,\r\n            __uuidof(IAppxFactory),\r\n            (LPVOID*)(&appxFactory)));\r\n\r\n        // Create a new package reader using the factory.\r\n        HRESULT hr = appxFactory->CreatePackageReader(inputStream, reader);\r\n\r\n        if (SUCCEEDED(hr))\r\n        {\r\n            return true;\r\n        }\r\n        else if (hr == APPX_E_MISSING_REQUIRED_FILE)\r\n        {\r\n            // APPX_E_MISSING_REQUIRED_FILE returned when trying to open\r\n            // an *.msix as an *.msixbundle or vice-versa.\r\n            return false;\r\n        }\r\n        else\r\n        {\r\n            THROW_HR(hr);\r\n        }\r\n    }\r\n\r\n    void GetManifestReader(\r\n        IStream* inputStream,\r\n        IAppxManifestReader** reader)\r\n    {\r\n        ComPtr<IAppxFactory> appxFactory;\r\n\r\n        THROW_IF_FAILED(CoCreateInstance(\r\n            __uuidof(AppxFactory),\r\n            nullptr,\r\n            CLSCTX_INPROC_SERVER,\r\n            __uuidof(IAppxFactory),\r\n            (LPVOID*)(&appxFactory)));\r\n\r\n        THROW_IF_FAILED(appxFactory->CreateManifestReader(inputStream, reader));\r\n    }\r\n\r\n    std::optional<std::string> GetPackageFullNameFromFamilyName(std::string_view familyName)\r\n    {\r\n        PackageManager packageManager;\r\n\r\n        std::wstring pfn = Utility::ConvertToUTF16(familyName);\r\n\r\n        // PackageManager.FindPackages() can find all packages (including provisioned ones) but requires admin.\r\n        // For non admin callers, use FindPackagesByPackageFamily where only packages registered to current user will be found.\r\n        if (Runtime::IsRunningAsAdmin())\r\n        {\r\n            auto packages = packageManager.FindPackages(pfn);\r\n\r\n            std::optional<std::string> result;\r\n            for (const auto& package : packages)\r\n            {\r\n                if (result.has_value())\r\n                {\r\n                    // More than 1 package found. Don't directly error, let caller deal with it.\r\n                    AICLI_LOG(Core, Error, << \"Multiple packages found for family name: \" << familyName);\r\n                    return {};\r\n                }\r\n\r\n                result = Utility::ConvertToUTF8(package.Id().FullName());\r\n            }\r\n\r\n            return result;\r\n        }\r\n        else\r\n        {\r\n            UINT32 fullNameCount = 0;\r\n            UINT32 bufferLength = 0;\r\n            UINT32 properties = 0;\r\n            LONG findResult = FindPackagesByPackageFamily(pfn.c_str(), PACKAGE_FILTER_HEAD, &fullNameCount, nullptr, &bufferLength, nullptr, &properties);\r\n            if (findResult == ERROR_SUCCESS || fullNameCount == 0)\r\n            {\r\n                // No package found\r\n                return {};\r\n            }\r\n            else if (findResult != ERROR_INSUFFICIENT_BUFFER)\r\n            {\r\n                THROW_WIN32(findResult);\r\n            }\r\n            else if (fullNameCount != 1)\r\n            {\r\n                // Don't directly error, let caller deal with it\r\n                AICLI_LOG(Core, Error, << \"Multiple packages found for family name: \" << fullNameCount);\r\n                return {};\r\n            }\r\n\r\n            // fullNameCount == 1 at this point\r\n            PWSTR fullNamePtr;\r\n            std::wstring buffer(static_cast<size_t>(bufferLength) + 1, '\\0');\r\n            THROW_IF_WIN32_ERROR(FindPackagesByPackageFamily(pfn.c_str(), PACKAGE_FILTER_HEAD, &fullNameCount, &fullNamePtr, &bufferLength, &buffer[0], &properties));\r\n            if (fullNameCount != 1 || bufferLength == 0)\r\n            {\r\n                // Something changed in between, abandon\r\n                AICLI_LOG(Core, Error, << \"Packages found for family name: \" << fullNameCount);\r\n                return {};\r\n            }\r\n            buffer.resize(bufferLength - 1);\r\n            return Utility::ConvertToUTF8(buffer);\r\n        }\r\n    }\r\n\r\n    std::string GetPackageFamilyNameFromFullName(std::string_view fullName)\r\n    {\r\n        std::wstring result;\r\n        result.resize(PACKAGE_FAMILY_NAME_MAX_LENGTH + 1);\r\n        UINT32 size = static_cast<UINT32>(result.size());\r\n        THROW_IF_WIN32_ERROR(PackageFamilyNameFromFullName(Utility::ConvertToUTF16(fullName).c_str(), &size, &result[0]));\r\n        result.resize(size - 1);\r\n        return Utility::ConvertToUTF8(result);\r\n    }\r\n\r\n    std::optional<std::filesystem::path> GetPackageLocationFromFullName(std::string_view fullName)\r\n    {\r\n        std::wstring fn = Utility::ConvertToUTF16(fullName);\r\n\r\n        UINT32 length = 0;\r\n        LONG returnVal = GetStagedPackagePathByFullName(fn.c_str(), &length, nullptr);\r\n        if (returnVal != ERROR_INSUFFICIENT_BUFFER)\r\n        {\r\n            LOG_WIN32(returnVal);\r\n            return {};\r\n        }\r\n\r\n        THROW_HR_IF(E_UNEXPECTED, length == 0);\r\n\r\n        std::wstring result;\r\n        result.resize(length);\r\n\r\n        returnVal = GetStagedPackagePathByFullName(fn.c_str(), &length, &result[0]);\r\n        if (returnVal != ERROR_SUCCESS)\r\n        {\r\n            LOG_WIN32(returnVal);\r\n            return {};\r\n        }\r\n\r\n        result.resize(length - 1);\r\n        return { result };\r\n    }\r\n\r\n    Msix::PackageIdInfo GetPackageIdInfoFromFullName(std::string_view fullName)\r\n    {\r\n        std::wstring fullNameWide = Utility::ConvertToUTF16(fullName);\r\n\r\n        UINT32 length = 0;\r\n        LONG returnVal = PackageIdFromFullName(fullNameWide.c_str(), PACKAGE_INFORMATION_BASIC, &length, nullptr);\r\n        if (returnVal != ERROR_INSUFFICIENT_BUFFER)\r\n        {\r\n            LOG_WIN32(returnVal);\r\n            return {};\r\n        }\r\n\r\n        THROW_HR_IF(E_UNEXPECTED, length == 0);\r\n\r\n        std::unique_ptr<BYTE[]> packageIdContent = std::make_unique<BYTE[]>(length);\r\n\r\n        returnVal = PackageIdFromFullName(fullNameWide.c_str(), PACKAGE_INFORMATION_BASIC, &length, packageIdContent.get());\r\n        if (returnVal != ERROR_SUCCESS)\r\n        {\r\n            LOG_WIN32(returnVal);\r\n            return {};\r\n        }\r\n\r\n        PACKAGE_ID* packageId = (PACKAGE_ID*)packageIdContent.get();\r\n\r\n        return { Utility::ConvertToUTF8(packageId->name), packageId->version.Version };\r\n    }\r\n\r\n    GetCertContextResult GetCertContextFromMsix(const std::filesystem::path& msixPath)\r\n    {\r\n        // Retrieve raw signature from msix\r\n        MsixInfo msixInfo{ msixPath };\r\n        auto signature = msixInfo.GetSignature(true);\r\n\r\n        // Get the cert content\r\n        wil::unique_any<HCRYPTMSG, decltype(&::CryptMsgClose), ::CryptMsgClose> signedMessage;\r\n        wil::unique_hcertstore certStore;\r\n        CRYPT_DATA_BLOB signatureBlob = { 0 };\r\n        signatureBlob.cbData = static_cast<DWORD>(signature.size());\r\n        signatureBlob.pbData = signature.data();\r\n        THROW_LAST_ERROR_IF(!CryptQueryObject(\r\n            CERT_QUERY_OBJECT_BLOB,\r\n            &signatureBlob,\r\n            CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED,\r\n            CERT_QUERY_FORMAT_FLAG_BINARY,\r\n            0,      // Reserved parameter\r\n            NULL,   // No encoding info needed\r\n            NULL,\r\n            NULL,\r\n            &certStore,\r\n            &signedMessage,\r\n            NULL));\r\n\r\n        // Get the signer size and information from the signed data message\r\n        // The properties of the signer info will be used to uniquely identify the signing certificate in the certificate store\r\n        DWORD signerInfoSize = 0;\r\n        THROW_LAST_ERROR_IF(!CryptMsgGetParam(\r\n            signedMessage.get(),\r\n            CMSG_SIGNER_INFO_PARAM,\r\n            0,\r\n            NULL,\r\n            &signerInfoSize));\r\n\r\n        // Check that the signer info size is within reasonable bounds; under the max length of a string for the issuer field\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_DATA), !(signerInfoSize > 0 && signerInfoSize < STRSAFE_MAX_CCH));\r\n\r\n        std::vector<byte> signerInfoBuffer;\r\n        signerInfoBuffer.resize(signerInfoSize);\r\n        THROW_LAST_ERROR_IF(!CryptMsgGetParam(\r\n            signedMessage.get(),\r\n            CMSG_SIGNER_INFO_PARAM,\r\n            0,\r\n            signerInfoBuffer.data(),\r\n            &signerInfoSize));\r\n\r\n        // Get the signing certificate from the certificate store based on the issuer and serial number of the signer info\r\n        CMSG_SIGNER_INFO* signerInfo = reinterpret_cast<CMSG_SIGNER_INFO*>(signerInfoBuffer.data());\r\n        CERT_INFO certInfo;\r\n        certInfo.Issuer = signerInfo->Issuer;\r\n        certInfo.SerialNumber = signerInfo->SerialNumber;\r\n\r\n        wil::unique_cert_context certContext;\r\n        certContext.reset(CertGetSubjectCertificateFromStore(\r\n            certStore.get(),\r\n            X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,\r\n            &certInfo));\r\n        THROW_LAST_ERROR_IF(!certContext.get());\r\n\r\n        return { std::move(certContext), std::move(certStore) };\r\n    }\r\n\r\n    MsixInfo::MsixInfo(std::string_view uriStr)\r\n    {\r\n        m_stream = Utility::GetReadOnlyStreamFromURI(uriStr);\r\n\r\n        if (GetBundleReader(m_stream.Get(), &m_bundleReader))\r\n        {\r\n            m_isBundle = true;\r\n        }\r\n        else if (GetPackageReader(m_stream.Get(), &m_packageReader))\r\n        {\r\n            m_isBundle = false;\r\n        }\r\n        else\r\n        {\r\n            THROW_HR_MSG(HRESULT_FROM_WIN32(ERROR_INSTALL_OPEN_PACKAGE_FAILED),\r\n                \"Failed to open uri as msix package or bundle. Uri: %hs\", uriStr.data());\r\n        }\r\n    }\r\n\r\n    std::vector<byte> MsixInfo::GetSignature(bool skipP7xFileId)\r\n    {\r\n        ComPtr<IAppxFile> signatureFile;\r\n        if (m_isBundle)\r\n        {\r\n            THROW_IF_FAILED(m_bundleReader->GetFootprintFile(APPX_BUNDLE_FOOTPRINT_FILE_TYPE_SIGNATURE, &signatureFile));\r\n        }\r\n        else\r\n        {\r\n            THROW_IF_FAILED(m_packageReader->GetFootprintFile(APPX_FOOTPRINT_FILE_TYPE_SIGNATURE, &signatureFile));\r\n        }\r\n\r\n        std::vector<byte> signatureContent;\r\n        DWORD signatureSize;\r\n\r\n        ComPtr<IStream> signatureStream;\r\n        THROW_IF_FAILED(signatureFile->GetStream(&signatureStream));\r\n\r\n        STATSTG stat = { 0 };\r\n        THROW_IF_FAILED(signatureStream->Stat(&stat, STATFLAG_NONAME));\r\n        THROW_HR_IF(E_UNEXPECTED, stat.cbSize.HighPart != 0); // Signature size should be small\r\n        signatureSize = stat.cbSize.LowPart;\r\n        THROW_HR_IF(E_UNEXPECTED, signatureSize <= P7xFileIdSize);\r\n\r\n        if (skipP7xFileId)\r\n        {\r\n            // Validate msix signature header\r\n            byte headerBuffer[P7xFileIdSize];\r\n            DWORD headerRead;\r\n            THROW_IF_FAILED(signatureStream->Read(headerBuffer, P7xFileIdSize, &headerRead));\r\n            THROW_HR_IF_MSG(E_UNEXPECTED, headerRead != P7xFileIdSize, \"Failed to read signature header\");\r\n            THROW_HR_IF_MSG(E_UNEXPECTED, !std::equal(P7xFileId, P7xFileId + P7xFileIdSize, headerBuffer), \"Unexpected msix signature header\");\r\n            signatureSize -= P7xFileIdSize;\r\n        }\r\n\r\n        signatureContent.resize(signatureSize);\r\n\r\n        DWORD signatureRead;\r\n        THROW_IF_FAILED(signatureStream->Read(signatureContent.data(), signatureSize, &signatureRead));\r\n        THROW_HR_IF_MSG(E_UNEXPECTED, signatureRead != signatureSize, \"Failed to read the whole signature stream\");\r\n\r\n        return signatureContent;\r\n    }\r\n\r\n    Utility::SHA256::HashBuffer MsixInfo::GetSignatureHash()\r\n    {\r\n        auto signature = GetSignature();\r\n        return Utility::SHA256::ComputeHash(signature.data(), static_cast<uint32_t>(signature.size()));\r\n    }\r\n\r\n    std::wstring MsixInfo::GetDigest()\r\n    {\r\n        ComPtr<IAppxDigestProvider> digestProvider;\r\n        if (m_isBundle)\r\n        {\r\n            THROW_IF_FAILED(m_bundleReader.As(&digestProvider));\r\n        }\r\n        else\r\n        {\r\n            THROW_IF_FAILED(m_packageReader.As(&digestProvider));\r\n        }\r\n\r\n        wil::unique_cotaskmem_string result;\r\n        THROW_IF_FAILED(digestProvider->GetDigest(&result));\r\n\r\n        return result.get();\r\n    }\r\n\r\n    std::wstring MsixInfo::GetPackageFullNameWide()\r\n    {\r\n        ComPtr<IAppxManifestPackageId> packageId;\r\n        if (m_isBundle)\r\n        {\r\n            ComPtr<IAppxBundleManifestReader> manifestReader;\r\n            THROW_IF_FAILED(m_bundleReader->GetManifest(&manifestReader));\r\n            THROW_IF_FAILED(manifestReader->GetPackageId(&packageId));\r\n        }\r\n        else\r\n        {\r\n            ComPtr<IAppxManifestReader> manifestReader;\r\n            THROW_IF_FAILED(m_packageReader->GetManifest(&manifestReader));\r\n            THROW_IF_FAILED(manifestReader->GetPackageId(&packageId));\r\n        }\r\n\r\n        wil::unique_cotaskmem_string fullName;\r\n        THROW_IF_FAILED(packageId->GetPackageFullName(&fullName));\r\n\r\n        return { fullName.get() };\r\n    }\r\n\r\n    std::string MsixInfo::GetPackageFullName()\r\n    {\r\n        return Utility::ConvertToUTF8(GetPackageFullNameWide());\r\n    }\r\n\r\n    std::vector<ComPtr<IAppxPackageReader>> MsixInfo::GetAppPackages(bool includeStub) const\r\n    {\r\n        if (!m_isBundle)\r\n        {\r\n            return { m_packageReader };\r\n        }\r\n\r\n        std::vector<ComPtr<IAppxPackageReader>> packages;\r\n\r\n        ComPtr<IAppxBundleManifestReader> manifestReader;\r\n        THROW_IF_FAILED(m_bundleReader->GetManifest(&manifestReader));\r\n\r\n        ComPtr<IAppxBundleManifestPackageInfoEnumerator> packageInfoItems;\r\n        THROW_IF_FAILED(manifestReader->GetPackageInfoItems(&packageInfoItems));\r\n\r\n        BOOL hasCurrent = FALSE;\r\n        THROW_IF_FAILED(packageInfoItems->GetHasCurrent(&hasCurrent));\r\n        while (hasCurrent)\r\n        {\r\n            ComPtr<IAppxBundleManifestPackageInfo> packageInfo;\r\n            THROW_IF_FAILED(packageInfoItems->GetCurrent(&packageInfo));\r\n\r\n            APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE packageType;\r\n            THROW_IF_FAILED(packageInfo->GetPackageType(&packageType));\r\n\r\n            // Check flat bundle case.\r\n            UINT64 offset;\r\n            THROW_IF_FAILED(packageInfo->GetOffset(&offset));\r\n            bool isContained = offset != 0;\r\n\r\n            // Check stub package case.\r\n            ComPtr<IAppxBundleManifestPackageInfo4> packageInfo4;\r\n            THROW_IF_FAILED(packageInfo.As(&packageInfo4));\r\n            BOOL isStub = FALSE;\r\n            THROW_IF_FAILED(packageInfo4->GetIsStub(&isStub));\r\n\r\n            if (isContained && (includeStub || !isStub) &&\r\n                packageType == APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE::APPX_BUNDLE_PAYLOAD_PACKAGE_TYPE_APPLICATION)\r\n            {\r\n                wil::unique_cotaskmem_string fileName;\r\n                THROW_IF_FAILED(packageInfo->GetFileName(&fileName));\r\n\r\n                ComPtr<IAppxFile> packageFile;\r\n                THROW_IF_FAILED(m_bundleReader->GetPayloadPackage(fileName.get(), &packageFile));\r\n\r\n                ComPtr<IStream> stream;\r\n                THROW_IF_FAILED(packageFile->GetStream(&stream));\r\n\r\n                ComPtr<IAppxPackageReader> packageReader;\r\n                if (GetPackageReader(stream.Get(), &packageReader))\r\n                {\r\n                    packages.emplace_back(std::move(packageReader));\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(Core, Warning, << \"Could not get package reader for bundle payload.\");\r\n                }\r\n            }\r\n\r\n            THROW_IF_FAILED(packageInfoItems->MoveNext(&hasCurrent));\r\n        }\r\n\r\n        return packages;\r\n    }\r\n\r\n    std::vector<MsixPackageManifest> MsixInfo::GetAppPackageManifests(bool includeStub) const\r\n    {\r\n        std::vector<MsixPackageManifest> manifests;\r\n        auto packages = GetAppPackages(includeStub);\r\n        for (const auto& package : packages)\r\n        {\r\n            ComPtr<IAppxManifestReader> manifestReader;\r\n            THROW_IF_FAILED(package->GetManifest(&manifestReader));\r\n            manifests.emplace_back(std::move(manifestReader));\r\n        }\r\n\r\n        return manifests;\r\n    }\r\n\r\n    bool MsixInfo::IsNewerThan(const std::filesystem::path& otherPackage)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, m_isBundle);\r\n\r\n        MsixInfo other{ otherPackage };\r\n\r\n        THROW_HR_IF(E_INVALIDARG, other.m_isBundle);\r\n\r\n        ComPtr<IAppxManifestReader> otherReader;\r\n        THROW_IF_FAILED(other.m_packageReader->GetManifest(&otherReader));\r\n\r\n        ComPtr<IAppxManifestReader> manifestReader;\r\n        THROW_IF_FAILED(m_packageReader->GetManifest(&manifestReader));\r\n\r\n        return (GetVersionFromManifestReader(manifestReader.Get()) > GetVersionFromManifestReader(otherReader.Get()));\r\n    }\r\n\r\n    bool MsixInfo::IsNewerThan(const winrt::Windows::ApplicationModel::PackageVersion& otherVersion)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, m_isBundle);\r\n\r\n        ComPtr<IAppxManifestReader> manifestReader;\r\n        THROW_IF_FAILED(m_packageReader->GetManifest(&manifestReader));\r\n\r\n        return (GetVersionFromManifestReader(manifestReader.Get()) > GetVersionFromVersion(otherVersion));\r\n    }\r\n\r\n    void MsixInfo::WriteToFile(std::string_view packageFile, const std::filesystem::path& target, IProgressCallback& progress)\r\n    {\r\n        std::wstring fileUTF16 = Utility::ConvertToUTF16(packageFile);\r\n\r\n        ComPtr<IAppxFile> appxFile;\r\n        if (m_isBundle)\r\n        {\r\n            THROW_IF_FAILED(m_bundleReader->GetPayloadPackage(fileUTF16.c_str(), &appxFile));\r\n        }\r\n        else\r\n        {\r\n            THROW_IF_FAILED(m_packageReader->GetPayloadFile(fileUTF16.c_str(), &appxFile));\r\n        }\r\n\r\n        WriteAppxFileToFile(appxFile.Get(), target, progress);\r\n    }\r\n\r\n    void MsixInfo::WriteManifestToFile(const std::filesystem::path& target, IProgressCallback& progress)\r\n    {\r\n        ComPtr<IAppxFile> appxFile;\r\n        if (m_isBundle)\r\n        {\r\n            THROW_IF_FAILED(m_bundleReader->GetFootprintFile(APPX_BUNDLE_FOOTPRINT_FILE_TYPE_MANIFEST, &appxFile));\r\n        }\r\n        else\r\n        {\r\n            THROW_IF_FAILED(m_packageReader->GetFootprintFile(APPX_FOOTPRINT_FILE_TYPE_MANIFEST, &appxFile));\r\n        }\r\n\r\n        WriteAppxFileToFile(appxFile.Get(), target, progress);\r\n    }\r\n\r\n    void MsixInfo::WriteToFileHandle(std::string_view packageFile, HANDLE target, IProgressCallback& progress)\r\n    {\r\n        std::wstring fileUTF16 = Utility::ConvertToUTF16(packageFile);\r\n\r\n        ComPtr<IAppxFile> appxFile;\r\n        if (m_isBundle)\r\n        {\r\n            THROW_IF_FAILED(m_bundleReader->GetPayloadPackage(fileUTF16.c_str(), &appxFile));\r\n        }\r\n        else\r\n        {\r\n            THROW_IF_FAILED(m_packageReader->GetPayloadFile(fileUTF16.c_str(), &appxFile));\r\n        }\r\n\r\n        WriteAppxFileToFileHandle(appxFile.Get(), target, progress);\r\n    }\r\n\r\n    WriteLockedMsixFile::WriteLockedMsixFile(const std::filesystem::path& path)\r\n    {\r\n        m_file = Utility::ManagedFile::OpenWriteLockedFile(path, 0);\r\n    }\r\n\r\n    bool WriteLockedMsixFile::ValidateTrustInfo(bool checkMicrosoftOrigin) const\r\n    {\r\n        return ValidateMsixTrustInfo(m_file.GetFilePath(), checkMicrosoftOrigin);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/MsixManifest.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include <pch.h>\n#include <AppInstallerMsixInfo.h>\n#include <winget/MsixManifest.h>\n\nusing namespace Microsoft::WRL;\n\nnamespace AppInstaller::Msix\n{\n    bool IsSupportedPlatform(MsixPackageManifestTargetDeviceFamily::Platform platform)\n    {\n        return platform == MsixPackageManifestTargetDeviceFamily::Platform::WindowsDesktop\n            || platform == MsixPackageManifestTargetDeviceFamily::Platform::WindowsUniversal;\n    }\n\n    Utility::NormalizedString MsixPackageManifestIdentity::GetPackageFamilyName() const\n    {\n        wil::unique_cotaskmem_string familyName;\n        THROW_IF_FAILED(m_packageId->GetPackageFamilyName(&familyName));\n        return { familyName.get() };\n    }\n\n    PackageVersion MsixPackageManifestIdentity::GetVersion() const\n    {\n        UINT64 version = 0;\n        THROW_IF_FAILED(m_packageId->GetVersion(&version));\n        return PackageVersion{ version };\n    }\n\n    MsixPackageManifestIdentity MsixPackageManifest::GetIdentity() const\n    {\n        ComPtr<IAppxManifestPackageId> manifestPackageId;\n        THROW_IF_FAILED(m_manifestReader->GetPackageId(&manifestPackageId));\n        return MsixPackageManifestIdentity{ std::move(manifestPackageId) };\n    }\n\n    std::optional<OSVersion> MsixPackageManifest::GetMinimumOSVersionForSupportedPlatforms() const\n    {\n        std::optional<OSVersion> minOSVersion;\n        auto targetDeviceFamilies = GetTargetDeviceFamilies();\n\n        for (const auto& targetDeviceFamily : targetDeviceFamilies)\n        {\n            if (IsSupportedPlatform(targetDeviceFamily.GetPlatform()))\n            {\n                auto targetDeviceFamilyMinVersion = targetDeviceFamily.GetMinVersion();\n                if (!minOSVersion.has_value() || targetDeviceFamilyMinVersion < minOSVersion.value())\n                {\n                    minOSVersion = targetDeviceFamilyMinVersion;\n                }\n            }\n        }\n\n        return minOSVersion;\n    }\n\n    std::vector<MsixPackageManifestTargetDeviceFamily> MsixPackageManifest::GetTargetDeviceFamilies() const\n    {\n        std::vector<MsixPackageManifestTargetDeviceFamily> targetDeviceFamilies;\n        ComPtr<IAppxManifestReader3> manifestReader3;\n        THROW_IF_FAILED(m_manifestReader.As(&manifestReader3));\n\n        ComPtr<IAppxManifestTargetDeviceFamiliesEnumerator> targetDeviceFamiliesIter;\n        THROW_IF_FAILED(manifestReader3->GetTargetDeviceFamilies(&targetDeviceFamiliesIter));\n\n        BOOL hasCurrent = FALSE;\n        THROW_IF_FAILED(targetDeviceFamiliesIter->GetHasCurrent(&hasCurrent));\n        while (hasCurrent)\n        {\n            ComPtr<IAppxManifestTargetDeviceFamily> targetDeviceFamily;\n            THROW_IF_FAILED(targetDeviceFamiliesIter->GetCurrent(&targetDeviceFamily));\n\n            targetDeviceFamilies.emplace_back(std::move(targetDeviceFamily));\n\n            THROW_IF_FAILED(targetDeviceFamiliesIter->MoveNext(&hasCurrent));\n        }\n\n        return targetDeviceFamilies;\n    }\n\n    std::string MsixPackageManifestTargetDeviceFamily::GetName() const\n    {\n        wil::unique_cotaskmem_string name;\n        THROW_IF_FAILED(m_targetDeviceFamily->GetName(&name));\n        return Utility::ConvertToUTF8(name.get());\n    }\n\n    OSVersion MsixPackageManifestTargetDeviceFamily::GetMinVersion() const\n    {\n        UINT64 minVersion = 0;\n        THROW_IF_FAILED(m_targetDeviceFamily->GetMinVersion(&minVersion));\n        return OSVersion{ minVersion };\n    }\n\n    MsixPackageManifestTargetDeviceFamily::Platform MsixPackageManifestTargetDeviceFamily::GetPlatform() const\n    {\n        auto name = GetName();\n        if (Utility::CaseInsensitiveEquals(name, WindowsDesktopName))\n        {\n            return WindowsDesktop;\n        }\n\n        if (Utility::CaseInsensitiveEquals(name, WindowsUniversalName))\n        {\n            return WindowsUniversal;\n        }\n\n        return Other;\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCommonCore/NameNormalization.cpp",
    "content": "﻿// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/NameNormalization.h\"\r\n#include \"Public/AppInstallerStrings.h\"\r\n#include \"Public/winget/Regex.h\"\r\n\r\n\r\nnamespace AppInstaller::Utility\r\n{\r\n    namespace\r\n    {\r\n        struct InterimNameNormalizationResult\r\n        {\r\n            std::wstring Name;\r\n            Architecture Architecture = Architecture::Unknown;\r\n            std::wstring Locale;\r\n        };\r\n\r\n        struct InterimPublisherNormalizationResult\r\n        {\r\n            std::wstring Publisher;\r\n        };\r\n\r\n        // To maintain consistency, changes that result in different output must be done in a new version.\r\n        // This can potentially be ignored (if thought through) when the changes will only increase the\r\n        // number of matches being made, with no impact to existing matches. For instance, removing an\r\n        // arbitrary new processor architecture from names would hopefully only affect existing packages\r\n        // that were not matching properly. Fixing a bug that was causing bad strings to be produced would\r\n        // be impactful, and thus should likely result in a new iteration.\r\n        class NormalizationInitial : public details::INameNormalizer\r\n        {\r\n            static std::wstring PrepareForValidation(std::string_view value)\r\n            {\r\n                std::wstring result = Utility::Normalize(ConvertToUTF16(value));\r\n                Trim(result);\r\n                size_t atPos = result.find(L\"@@\", 3);\r\n                if (atPos != std::wstring::npos)\r\n                {\r\n                    result = result.substr(0, atPos);\r\n                }\r\n                return result;\r\n            }\r\n\r\n            // If the string is wrapped with some character groups, remove them.\r\n            // Returns true if string was wrapped; false if not.\r\n            static bool Unwrap(std::wstring& value)\r\n            {\r\n                if (value.length() >= 2)\r\n                {\r\n                    bool unwrap = false;\r\n\r\n                    switch (value[0])\r\n                    {\r\n                    case L'\"':\r\n                        unwrap = value.back() == L'\"';\r\n                        break;\r\n\r\n                    case L'(':\r\n                        unwrap = value.back() == L')';\r\n                        break;\r\n                    }\r\n\r\n                    if (unwrap)\r\n                    {\r\n                        value = value.substr(1, value.length() - 2);\r\n                        return true;\r\n                    }\r\n                }\r\n\r\n                return false;\r\n            }\r\n\r\n            // Removes all matches from the input string.\r\n            static bool Remove(const Regex::Expression& re, std::wstring& input)\r\n            {\r\n                std::wstring output = re.Replace(input, {});\r\n                bool result = (output != input);\r\n                input = std::move(output);\r\n                return result;\r\n            }\r\n\r\n            // Removes the architecture and returns the value, if any\r\n            Architecture RemoveArchitecture(std::wstring& value) const\r\n            {\r\n                Architecture result = Architecture::Unknown;\r\n\r\n                // Must detect this first because \"32/64 bit\" is a superstring of \"64 bit\"\r\n                if (Remove(Architecture32Or64Bit, value))\r\n                {\r\n                    // If the program is 32 and 64 bit in the same installer, leave as unknown.\r\n                }\r\n                // Must detect 64 bit before 32 bit because of \"x86-64\" being a superstring of \"x86\"\r\n                else if (Remove(ArchitectureX64, value) || Remove(Architecture64Bit, value))\r\n                {\r\n                    result = Architecture::X64;\r\n                }\r\n                else if (Remove(ArchitectureX32, value) || Remove(Architecture32Bit, value))\r\n                {\r\n                    result = Architecture::X86;\r\n                }\r\n\r\n                return result;\r\n            }\r\n\r\n            // Removes all matches for the given regular expressions\r\n            static bool RemoveAll(const std::vector<Regex::Expression*>& regexes, std::wstring& value)\r\n            {\r\n                bool result = false;\r\n\r\n                for (const auto& re : regexes)\r\n                {\r\n                    result = Remove(*re, value) || result;\r\n                }\r\n\r\n                return result;\r\n            }\r\n\r\n            // Removes all locales and returns the common value, if any\r\n            std::wstring RemoveLocale(std::wstring& value) const\r\n            {\r\n                bool localeFound = false;\r\n                std::wstring result;\r\n\r\n                std::wstring newValue;\r\n                auto newValueInserter = std::back_inserter(newValue);\r\n\r\n                Locale.ForEach(value,\r\n                    [&](bool isMatch, std::wstring_view text)\r\n                    {\r\n                        bool copy = !isMatch;\r\n\r\n                        if (isMatch)\r\n                        {\r\n                            std::wstring foldedText = ConvertToUTF16(FoldCase(text));\r\n\r\n                            // Ensure that the value is in the locale list\r\n                            auto bound = std::lower_bound(Locales.begin(), Locales.end(), foldedText);\r\n\r\n                            if (bound == Locales.end() || *bound != foldedText)\r\n                            {\r\n                                // Match was not a locale in our list, so copy it out\r\n                                copy = true;\r\n                            }\r\n                            else if (!localeFound)\r\n                            {\r\n                                // First/only match, just extract the value\r\n                                result = foldedText;\r\n                                localeFound = true;\r\n                            }\r\n                            else if (!result.empty())\r\n                            {\r\n                                // For some reason, there are multiple locales listed.\r\n                                // See if they have anything in common.\r\n                                if (result != foldedText)\r\n                                {\r\n                                    // Not completely the same (expected), see if they are at least the same language\r\n                                    result.erase(result.find(L'-'));\r\n                                    foldedText.erase(foldedText.find(L'-'));\r\n\r\n                                    if (result != foldedText)\r\n                                    {\r\n                                        // Not the same language, abandon having a locale and just clean them\r\n                                        result.clear();\r\n                                    }\r\n                                }\r\n                            }\r\n                        }\r\n\r\n                        if (copy)\r\n                        {\r\n                            std::copy(text.begin(), text.end(), newValueInserter);\r\n                        }\r\n\r\n                        return true;\r\n                    });\r\n\r\n                value = std::move(newValue);\r\n\r\n                return result;\r\n            }\r\n\r\n            // Splits the string based on the regex matches, excluding empty/whitespace strings\r\n            // and any values found in the exclusions.\r\n            static std::vector<std::wstring> Split(const Regex::Expression& re, const std::wstring& value, const std::vector<std::wstring>& exclusions, bool stopOnExclusion = false)\r\n            {\r\n                std::vector<std::wstring> result;\r\n\r\n                re.ForEach(value,\r\n                    [&](bool, std::wstring_view text)\r\n                    {\r\n                        if (IsEmptyOrWhitespace(text))\r\n                        {\r\n                            return true;\r\n                        }\r\n\r\n                        // Do not stop for an exclusion if it is the first word found\r\n                        if (!result.empty())\r\n                        {\r\n                            std::wstring foldedText = ConvertToUTF16(FoldCase(text));\r\n\r\n                            auto bound = std::lower_bound(exclusions.begin(), exclusions.end(), foldedText);\r\n\r\n                            if (bound != exclusions.end() && *bound == foldedText)\r\n                            {\r\n                                return !stopOnExclusion;\r\n                            }\r\n                        }\r\n\r\n                        result.emplace_back(std::wstring{ text });\r\n                        return true;\r\n                    });\r\n\r\n                return result;\r\n            }\r\n\r\n            // Joins all of the given strings into a single value\r\n            static std::wstring Join(const std::vector<std::wstring>& values, const std::wstring& separator = {})\r\n            {\r\n                std::wstring result;\r\n\r\n                bool isFirst = true;\r\n                for (const auto& v : values)\r\n                {\r\n                    if (isFirst)\r\n                    {\r\n                        isFirst = false;\r\n                    }\r\n                    else\r\n                    {\r\n                        result += separator;\r\n                    }\r\n\r\n                    result += v;\r\n                }\r\n\r\n                return result;\r\n            }\r\n\r\n            static constexpr Regex::Options reOptions = Regex::Options::CaseInsensitive;\r\n\r\n            // Architecture\r\n            Regex::Expression ArchitectureX32{ R\"((?<=^|[^\\p{L}\\p{Nd}])(X32|X86)(?=\\P{Nd}|$)(?:\\sEDITION)?)\", reOptions };\r\n            Regex::Expression ArchitectureX64{ R\"((?<=^|[^\\p{L}\\p{Nd}])(X64|AMD64|X86([\\p{Pd}\\p{Pc}]64))(?=\\P{Nd}|$)(?:\\sEDITION)?)\", reOptions };\r\n            Regex::Expression Architecture32Bit{ R\"((?<=^|[^\\p{L}\\p{Nd}])(32[\\p{Pd}\\p{Pc}\\p{Z}]?BIT)S?(?:\\sEDITION)?)\", reOptions };\r\n            Regex::Expression Architecture64Bit{ R\"((?<=^|[^\\p{L}\\p{Nd}])(64[\\p{Pd}\\p{Pc}\\p{Z}]?BIT)S?(?:\\sEDITION)?)\", reOptions };\r\n            Regex::Expression Architecture32Or64Bit{ R\"((?<=^|[^\\p{L}\\p{Nd}])((64[\\\\\\/]32|32[\\\\\\/]64)[\\p{Pd}\\p{Pc}\\p{Z}]?BIT)S?(?:\\sEDITION)?)\", reOptions };\r\n\r\n            // Locale\r\n            Regex::Expression Locale{ R\"((?<![A-Z])((?:\\p{Lu}{2,3}(-(CANS|CYRL|LATN|MONG))?-\\p{Lu}{2})(?![A-Z])(?:-VALENCIA)?))\", reOptions };\r\n\r\n            // Specifically for SAP Business Objects programs\r\n            Regex::Expression SAPPackage{ R\"(^(?:[\\p{Lu}\\p{Nd}]+[\\._])+[\\p{Lu}\\p{Nd}]+(?:-(?:\\p{Nd}+\\.)+\\p{Nd}+)(?:-(?:\\p{Lu}{2}(?:_\\p{Lu}{2})?|CORE))(?:-(?:\\p{Lu}{2}|\\p{Nd}{2}))$)\", reOptions };\r\n\r\n            // Extract KB numbers from their parens to preserve them\r\n            Regex::Expression KBNumbers{ R\"(\\((KB\\d+)\\))\", reOptions };\r\n\r\n            Regex::Expression NonLettersAndDigits{ R\"([^\\p{L}\\p{Nd}])\", reOptions };\r\n            Regex::Expression NonLetterDigitOrSpace{ R\"([^\\p{L}\\p{Nd}\\s])\", reOptions };\r\n            Regex::Expression URIProtocol{ R\"((?<!\\p{L})(?:http[s]?|ftp):\\/\\/)\", reOptions }; // remove protocol from URIs\r\n\r\n            Regex::Expression VersionDelimited{ R\"(((?<!\\p{L})(?:V|VER|VERSI(?:O|Ó)N|VERSÃO|VERSIE|WERSJA|BUILD|RELEASE|RC|SP)\\P{L}?)?\\p{Nd}+([\\p{Po}\\p{Pd}\\p{Pc}]\\p{Nd}?(RC|B|A|R|SP|K)?\\p{Nd}+)+([\\p{Po}\\p{Pd}\\p{Pc}]?[\\p{L}\\p{Nd}]+)*)\", reOptions };\r\n            Regex::Expression Version{ R\"((FOR\\s)?(?<!\\p{L})(?:P|V|R|VER|VERSI(?:O|Ó)N|VERSÃO|VERSIE|WERSJA|BUILD|RELEASE|RC|SP)(?:\\P{L}|\\P{L}\\p{L})?(\\p{Nd}|\\.\\p{Nd})+(?:RC|B|A|R|V|SP)?\\p{Nd}?)\", reOptions };\r\n            Regex::Expression VersionLetter{ R\"((?<!\\p{L})(?:(?:V|VER|VERSI(?:O|Ó)N|VERSÃO|VERSIE|WERSJA|BUILD|RELEASE|RC|SP)\\P{L})?\\p{Lu}\\p{Nd}+(?:[\\p{Po}\\p{Pd}\\p{Pc}]\\p{Nd}+)+)\", reOptions };\r\n            Regex::Expression NonNestedBracket{ R\"(\\([^\\(\\)]*\\)|\\[[^\\[\\]]*\\])\", reOptions }; // remove things in parentheses, if there aren't parentheses nested inside\r\n            Regex::Expression BracketEnclosed{ R\"((?:\\p{Ps}.*\\p{Pe}|\".*\"))\", reOptions }; // Impossible to properly handle nested parens with regex\r\n            Regex::Expression LeadingSymbols{ R\"(^[^\\p{L}\\p{Nd}]+)\", reOptions }; // remove symbols at the beginning\r\n            Regex::Expression TrailingNonLetters{ R\"(\\P{L}+$)\", reOptions }; // remove non-letters at the end\r\n            Regex::Expression PrefixParens{ R\"(^\\(.*?\\))\", reOptions }; // remove things in parentheses at the front of program names\r\n            Regex::Expression EmptyParens{ R\"((\\(\\s*\\)|\\[\\s*\\]|\"\\s*\"))\", reOptions }; // remove appearances of (), [], and \"\", with any number of spaces within\r\n            Regex::Expression EN{ R\"(\\sEN\\s*$)\", reOptions }; // remove appearances of EN (represents English language) at the ends of program names\r\n            Regex::Expression TrailingSymbols{ R\"([^\\p{L}\\p{Nd}]+$)\", reOptions }; // remove all non-letter/numbers at the end\r\n            Regex::Expression FilePath{ R\"(((INSTALLED\\sAT|IN)\\s)?[CDEF]:\\\\(.+?\\\\)*[^\\s]*\\\\?)\", reOptions }; // remove file paths\r\n            Regex::Expression FilePathGHS{ R\"(\\(CHANGE #\\d{1,2} TO [CDEF]:\\\\(.+?\\\\)*[^\\s]*\\\\?\\))\", reOptions }; // remove file paths in certain Green Hills Software program names\r\n            Regex::Expression FilePathParens{ R\"(\\([CDEF]:\\\\(.+?\\\\)*[^\\s]*\\\\?\\))\", reOptions }; // remove file paths within parentheses\r\n            Regex::Expression FilePathQuotes{ R\"(\"[CDEF]:\\\\(.+?\\\\)*[^\\s]*\\\\?\")\", reOptions }; // remove file paths within quotes\r\n            Regex::Expression Roblox{ R\"((?<=^ROBLOX\\s(PLAYER|STUDIO))(\\sFOR\\s.*))\", reOptions }; // for Roblox programs\r\n            Regex::Expression Bomgar{ R\"((?<=^BOMGAR\\s(JUMP CLIENT|(ACCESS|REPRESENTATIVE) CONSOLE|BUTTON)|^EMBEDDED CALLBACK)(\\s.*))\", reOptions }; // for Bomgar programs\r\n            Regex::Expression AcronymSeparators{ R\"((?:(?<=^\\p{L})|(?<=\\P{L}\\p{L}))(\\.|\\/)(?=\\p{L}(?:\\P{L}|$)))\", reOptions };\r\n            Regex::Expression NonLetters{ R\"((?<=^|\\s)[^\\p{L}]+(?=\\s|$))\", reOptions }; // remove all non-letters not attached to \r\n            Regex::Expression ProgramNameSplit{ R\"([^\\p{L}\\p{Nd}\\+\\&])\", reOptions }; // used to separate 'words' in program names\r\n            Regex::Expression PublisherNameSplit{ R\"([^\\p{L}\\p{Nd}])\", reOptions }; // used to separate 'words' in publisher names\r\n\r\n            const std::vector<Regex::Expression*> ProgramNameRegexes\r\n            {\r\n                &Roblox,\r\n                &Bomgar,\r\n                &PrefixParens,\r\n                &EmptyParens,\r\n                &FilePathGHS,\r\n                &FilePathParens,\r\n                &FilePathQuotes,\r\n                &FilePath,\r\n                &VersionLetter,\r\n                &VersionDelimited,\r\n                &Version,\r\n                &EN,\r\n                &NonNestedBracket,\r\n                &BracketEnclosed,\r\n                &URIProtocol,\r\n                &LeadingSymbols,\r\n                &TrailingSymbols\r\n            };\r\n\r\n            const std::vector<Regex::Expression*> PublisherNameRegexes\r\n            {\r\n                &VersionDelimited,\r\n                &Version,\r\n                &NonNestedBracket,\r\n                &BracketEnclosed,\r\n                &URIProtocol,\r\n                &NonLetters,\r\n                &TrailingNonLetters,\r\n                &AcronymSeparators\r\n            };\r\n\r\n            // Add values here but use Locales in code.\r\n            const std::vector<std::wstring_view> LocaleViews\r\n            {\r\n                L\"AF-ZA\", L\"AM-ET\", L\"AR-AE\", L\"AR-BH\", L\"AR-DZ\", L\"AR-EG\", L\"AR-IQ\", L\"AR-JO\", L\"AR-KW\", L\"AR-LB\", L\"AR-LY\",\r\n                L\"AR-MA\", L\"ARN-CL\", L\"AR-OM\", L\"AR-QA\", L\"AR-SA\", L\"AR-SY\", L\"AR-TN\", L\"AR-YE\", L\"AS-IN\", L\"BA-RU\", L\"BE-BY\",\r\n                L\"BG-BG\", L\"BN-BD\", L\"BN-IN\", L\"BO-CN\", L\"BR-FR\", L\"CA-ES\", L\"CA-ES-VALENCIA\",\r\n                L\"CO-FR\", L\"CS-CZ\", L\"CY-GB\", L\"DA-DK\", L\"DE-AT\",\r\n                L\"DE-CH\", L\"DE-DE\", L\"DE-LI\", L\"DE-LU\", L\"DSB-DE\", L\"DV-MV\", L\"EL-GR\", L\"EN-AU\", L\"EN-BZ\", L\"EN-CA\", L\"EN-GB\",\r\n                L\"EN-IE\", L\"EN-IN\", L\"EN-JM\", L\"EN-MY\", L\"EN-NZ\", L\"EN-PH\", L\"EN-SG\", L\"EN-TT\", L\"EN-US\", L\"EN-ZA\", L\"EN-ZW\",\r\n                L\"ES-AR\", L\"ES-BO\", L\"ES-CL\", L\"ES-CO\", L\"ES-CR\", L\"ES-DO\", L\"ES-EC\", L\"ES-ES\", L\"ES-GT\", L\"ES-HN\", L\"ES-MX\",\r\n                L\"ES-NI\", L\"ES-PA\", L\"ES-PE\", L\"ES-PR\", L\"ES-PY\", L\"ES-SV\", L\"ES-US\", L\"ES-UY\", L\"ES-VE\", L\"ET-EE\", L\"EU-ES\",\r\n                L\"FA-IR\", L\"FI-FI\", L\"FIL-PH\", L\"FO-FO\", L\"FR-BE\", L\"FR-CA\", L\"FR-CH\", L\"FR-FR\", L\"FR-LU\", L\"FR-MC\", L\"FY-NL\",\r\n                L\"GA-IE\", L\"GD-DB\", L\"GL-ES\", L\"GSW-FR\", L\"GU-IN\", L\"HE-IL\", L\"HI-IN\", L\"HR-BA\", L\"HR-HR\", L\"HSB-DE\", L\"HU-HU\",\r\n                L\"HY-AM\", L\"ID-ID\", L\"IG-NG\", L\"II-CN\", L\"IS-IS\", L\"IT-CH\", L\"IT-IT\", L\"JA-JP\", L\"KA-GE\", L\"KK-KZ\", L\"KL-GL\",\r\n                L\"KM-KH\", L\"KN-IN\", L\"KOK-IN\", L\"KO-KR\", L\"KY-KG\", L\"LB-LU\", L\"LO-LA\", L\"LT-LT\", L\"LV-LV\", L\"MI-NZ\", L\"MK-MK\",\r\n                L\"ML-IN\", L\"MN-MN\", L\"MOH-CA\", L\"MR-IN\", L\"MS-BN\", L\"MS-MY\", L\"MT-MT\", L\"NB-NO\", L\"NE-NP\", L\"NL-BE\", L\"NL-NL\",\r\n                L\"NN-NO\", L\"NSO-ZA\", L\"OC-FR\", L\"OR-IN\", L\"PA-IN\", L\"PL-PL\", L\"PRS-AF\", L\"PS-AF\", L\"PT-BR\", L\"PT-PT\", L\"QUT-GT\",\r\n                L\"QUZ-BO\", L\"QUZ-EC\", L\"QUZ-PE\", L\"RM-CH\", L\"RO-RO\", L\"RU-RU\", L\"RW-RW\", L\"SAH-RU\", L\"SA-IN\", L\"SE-FI\", L\"SE-NO\",\r\n                L\"SE-SE\", L\"SI-LK\", L\"SK-SK\", L\"SL-SI\", L\"SMA-NO\", L\"SMA-SE\", L\"SMJ-NO\", L\"SMJ-SE\", L\"SMN-FI\", L\"SMS-FI\", L\"SQ-AL\",\r\n                L\"SV-FI\", L\"SV-SE\", L\"SW-KE\", L\"SYR-SY\", L\"TA-IN\", L\"TE-IN\", L\"TH-TH\", L\"TK-TM\", L\"TN-ZA\", L\"TR-TR\", L\"TT-RU\",\r\n                L\"UG-CN\", L\"UK-UA\", L\"UR-PK\", L\"VI-VN\", L\"WO-SN\", L\"XH-ZA\", L\"YO-NG\", L\"ZH-CN\", L\"ZH-HK\", L\"ZH-MO\", L\"ZH-SG\",\r\n                L\"ZH-TW\", L\"ZU-ZA\", L\"AZ-CYRL-AZ\", L\"AZ-LATN-AZ\", L\"BS-CYRL-BA\", L\"BS-LATN-BA\", L\"HA-LATN-NG\", L\"IU-CANS-CA\",\r\n                L\"IU-LATN-CA\", L\"MN-MONG-CN\", L\"SR-CYRL-BA\", L\"SR-CYRL-CS\", L\"SR-CYRL-ME\", L\"SR-CYRL-RS\", L\"SR-LATN-BA\",\r\n                L\"SR-LATN-CS\", L\"SR-LATN-ME\", L\"SR-LATN-RS\", L\"TG-CYRL-TJ\", L\"TZM-LATN-DZ\", L\"UZ-CYRL-UZ\", L\"UZ-LATN-UZ\",\r\n            };\r\n\r\n            // The folded and sorted version of LocaleViews.\r\n            const std::vector<std::wstring> Locales;\r\n\r\n            // Add values here but use LegalEntitySuffixes in code.\r\n            const std::vector<std::wstring_view> LegalEntitySuffixViews\r\n            {\r\n                // Acronyms\r\n                L\"AB\", L\"AD\", L\"AG\", L\"APS\", L\"AS\", L\"ASA\", L\"BV\", L\"CO\", L\"CV\", L\"DOO\", L\"eV\", L\"GES\", L\"GESMBH\", L\"GMBH\", L\"INC\", L\"KG\",\r\n                L\"KS\", L\"PS\", L\"LLC\", L\"LP\", L\"LTD\", L\"LTDA\", L\"MBH\", L\"NV\", L\"PLC\", L\"SL\", L\"PTY\", L\"PVT\", L\"SA\", L\"SARL\",\r\n                L\"SC\", L\"SCA\", L\"SL\", L\"SP\", L\"SPA\", L\"SRL\", L\"SRO\",\r\n\r\n                // Words\r\n                L\"COMPANY\", L\"CORP\", L\"CORPORATION\", L\"HOLDING\", L\"HOLDINGS\", L\"INCORPORATED\", L\"LIMITED\", L\"SUBSIDIARY\"\r\n            };\r\n\r\n            // The folded and sorted version of LocaleViews.\r\n            const std::vector<std::wstring> LegalEntitySuffixes;\r\n\r\n            const bool PreserveWhiteSpace;\r\n\r\n            static std::vector<std::wstring> FoldAndSort(const std::vector<std::wstring_view>& input)\r\n            {\r\n                std::vector<std::wstring> result;\r\n                std::transform(input.begin(), input.end(), std::back_inserter(result), [](const std::wstring_view wsv) { return Utility::ConvertToUTF16(Utility::FoldCase(wsv)); });\r\n                std::sort(result.begin(), result.end());\r\n                return result;\r\n            }\r\n\r\n            InterimNameNormalizationResult NormalizeNameInternal(std::string_view name) const\r\n            {\r\n                InterimNameNormalizationResult result;\r\n                result.Name = PrepareForValidation(name);\r\n                while (Unwrap(result.Name)); // remove wrappers\r\n\r\n                // handle (large majority of) SAP Business Object programs\r\n                if (SAPPackage.IsMatch(result.Name))\r\n                {\r\n                    return result;\r\n                }\r\n\r\n                result.Architecture = RemoveArchitecture(result.Name);\r\n                result.Locale = RemoveLocale(result.Name);\r\n\r\n                // Extract KB numbers from their parens and preserve them\r\n                result.Name = KBNumbers.Replace(result.Name, L\"$1\");\r\n\r\n                // Repeatedly remove matches for the regexes to create the minimum name\r\n                while (RemoveAll(ProgramNameRegexes, result.Name));\r\n\r\n                auto tokens = Split(ProgramNameSplit, result.Name, LegalEntitySuffixes);\r\n\r\n                // Re-join the tokens and drop all undesired characters\r\n                if (PreserveWhiteSpace)\r\n                {\r\n                    result.Name = Join(tokens, L\" \");\r\n                    Remove(NonLetterDigitOrSpace, result.Name);\r\n                }\r\n                else\r\n                {\r\n                    result.Name = Join(tokens);\r\n                    Remove(NonLettersAndDigits, result.Name);\r\n                }\r\n\r\n                return result;\r\n            }\r\n\r\n            InterimPublisherNormalizationResult NormalizePublisherInternal(std::string_view publisher) const\r\n            {\r\n                InterimPublisherNormalizationResult result;\r\n\r\n                result.Publisher = PrepareForValidation(publisher);\r\n                while (Unwrap(result.Publisher)); // remove wrappers\r\n\r\n                while (RemoveAll(PublisherNameRegexes, result.Publisher));\r\n\r\n                auto tokens = Split(PublisherNameSplit, result.Publisher, LegalEntitySuffixes, true);\r\n\r\n                // Re-join the tokens and drop all undesired characters\r\n                if (PreserveWhiteSpace)\r\n                {\r\n                    result.Publisher = Join(tokens, L\" \");\r\n                    Remove(NonLetterDigitOrSpace, result.Publisher);\r\n                }\r\n                else\r\n                {\r\n                    result.Publisher = Join(tokens);\r\n                    Remove(NonLettersAndDigits, result.Publisher);\r\n                }\r\n\r\n                return result;\r\n            }\r\n\r\n        public:\r\n            NormalizationInitial(bool preserveWhiteSpace) : Locales(FoldAndSort(LocaleViews)), LegalEntitySuffixes(FoldAndSort(LegalEntitySuffixViews)), PreserveWhiteSpace(preserveWhiteSpace)\r\n            {\r\n            }\r\n\r\n            NormalizedName Normalize(std::string_view name, std::string_view publisher) const override\r\n            {\r\n                InterimNameNormalizationResult nameResult = NormalizeNameInternal(name);\r\n                InterimPublisherNormalizationResult pubResult = NormalizePublisherInternal(publisher);\r\n\r\n                NormalizedName result;\r\n                result.Name(ConvertToUTF8(nameResult.Name));\r\n                result.Architecture(nameResult.Architecture);\r\n                result.Locale(ConvertToUTF8(nameResult.Locale));\r\n                result.Publisher(ConvertToUTF8(pubResult.Publisher));\r\n\r\n                return result;\r\n            }\r\n\r\n            NormalizedName NormalizeName(std::string_view name) const override\r\n            {\r\n                InterimNameNormalizationResult nameResult = NormalizeNameInternal(name);\r\n\r\n                NormalizedName result;\r\n                result.Name(ConvertToUTF8(nameResult.Name));\r\n                result.Architecture(nameResult.Architecture);\r\n                result.Locale(ConvertToUTF8(nameResult.Locale));\r\n\r\n                return result;\r\n            }\r\n\r\n            std::string NormalizePublisher(std::string_view publisher) const override\r\n            {\r\n                InterimPublisherNormalizationResult pubResult = NormalizePublisherInternal(publisher);\r\n\r\n                return ConvertToUTF8(pubResult.Publisher);\r\n            }\r\n        };\r\n    }\r\n\r\n    NameNormalizer::NameNormalizer(NormalizationVersion version)\r\n    {\r\n        switch (version)\r\n        {\r\n        case AppInstaller::Utility::NormalizationVersion::Initial:\r\n            m_normalizer = std::make_unique<NormalizationInitial>(false);\r\n            break;\r\n        case AppInstaller::Utility::NormalizationVersion::InitialPreserveWhiteSpace:\r\n            m_normalizer = std::make_unique<NormalizationInitial>(true);\r\n            break;\r\n        default:\r\n            THROW_HR(E_INVALIDARG);\r\n        }\r\n    }\r\n\r\n    NormalizedName NameNormalizer::Normalize(std::string_view name, std::string_view publisher) const\r\n    {\r\n        return m_normalizer->Normalize(name, publisher);\r\n    }\r\n\r\n    NormalizedName NameNormalizer::NormalizeName(std::string_view name) const\r\n    {\r\n        return m_normalizer->NormalizeName(name);\r\n    }\r\n\r\n    std::string NameNormalizer::NormalizePublisher(std::string_view publisher) const\r\n    {\r\n        return m_normalizer->NormalizePublisher(publisher);\r\n    }\r\n\r\n    std::string NormalizedName::GetNormalizedName(NormalizationField fieldsToInclude) const\r\n    {\r\n        std::string result = Name();\r\n\r\n        if (WI_IsFlagSet(fieldsToInclude, NormalizationField::Architecture) && m_arch != Utility::Architecture::Unknown)\r\n        {\r\n            result += '(' + std::string(Utility::ToString(m_arch)) + ')';\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    NormalizationField NormalizedName::GetNormalizedFields() const\r\n    {\r\n        NormalizationField result = NormalizationField::None;\r\n\r\n        if (m_arch != Utility::Architecture::Unknown)\r\n        {\r\n            result |= NormalizationField::Architecture;\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/NetworkSettings.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"winget/NetworkSettings.h\"\n#include \"winget/AdminSettings.h\"\n#include \"AppInstallerLogging.h\"\n\nnamespace AppInstaller::Settings\n{\n    void NetworkSettings::SetProxyUri(const std::optional<std::string>& proxyUri)\n    {\n        AICLI_LOG(Core, Info, << \"Setting proxy\");\n\n        if (proxyUri)\n        {\n            m_proxyUri = proxyUri.value();\n            AICLI_LOG(Core, Info, << \"New value for proxy is \" << m_proxyUri.value());\n        }\n        else\n        {\n            m_proxyUri.reset();\n            AICLI_LOG(Core, Info, << \"Proxy will not be used\");\n        }\n    }\n\n    InstallerDownloader NetworkSettings::GetInstallerDownloader() const\n    {\n        // The default is DeliveryOptimization.\n        // We use WinINet if specified by settings, or if we want to use proxy (as DO does not support that)\n        InstallerDownloader setting = User().Get<Setting::NetworkDownloader>();\n\n        if (m_proxyUri && setting != InstallerDownloader::WinInet)\n        {\n            AICLI_LOG(Core, Info, << \"Forcing use of wininet for download as DO does not support proxy\");\n            return InstallerDownloader::WinInet;\n        }\n        else if (setting == InstallerDownloader::Default)\n        {\n            return InstallerDownloader::DeliveryOptimization;\n        }\r\n        else\r\n        {\n            return setting;\n        }\n    }\n\n    NetworkSettings::NetworkSettings()\n    {\n        // Get the default proxy\r\n        try\r\n        {\n            m_proxyUri = GetAdminSetting(StringAdminSetting::DefaultProxy);\n        }\r\n        CATCH_LOG()\n        AICLI_LOG(Core, Info, << \"Default proxy is \" << (m_proxyUri ? m_proxyUri.value() : \"not set\"));\n    }\n\n    NetworkSettings& NetworkSettings::Instance()\n    {\n        static NetworkSettings networkSettings;\n        return networkSettings;\n    }\n\n    NetworkSettings& Network()\n    {\n        return NetworkSettings::Instance();\n    }\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/OutputDebugStringLogger.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"winget/OutputDebugStringLogger.h\"\r\n\r\nnamespace AppInstaller::Logging\r\n{\r\n    namespace\r\n    {\r\n        static constexpr std::string_view s_OutputDebugStringLoggerName = \"OutputDebugStringLogger\";\r\n    }\r\n\r\n    std::string OutputDebugStringLogger::GetName() const\r\n    {\r\n        return std::string{ s_OutputDebugStringLoggerName };\r\n    }\r\n\r\n    void OutputDebugStringLogger::Write(Channel channel, Level, std::string_view message) noexcept try\r\n    {\r\n        std::stringstream strstr;\r\n        strstr << \"[\" << std::setw(GetMaxChannelNameLength()) << std::left << std::setfill(' ') << GetChannelName(channel) << \"] \" << message << std::endl;\r\n        std::string formattedMessage = std::move(strstr).str();\r\n\r\n        OutputDebugStringA(formattedMessage.c_str());\r\n    }\r\n    catch (...)\r\n    {\r\n        // Just eat any exceptions here; better than losing logs\r\n    }\r\n\r\n    void OutputDebugStringLogger::WriteDirect(Channel, Level, std::string_view message) noexcept try\r\n    {\r\n        std::string nullTerminatedMessage{ message };\r\n        OutputDebugStringA(nullTerminatedMessage.c_str());\r\n    }\r\n    catch (...)\r\n    {\r\n        // Just eat any exceptions here; better than losing logs\r\n    }\r\n\r\n    void OutputDebugStringLogger::Add()\r\n    {\r\n        Log().AddLogger(std::make_unique<OutputDebugStringLogger>());\r\n    }\r\n\r\n    void OutputDebugStringLogger::Remove()\r\n    {\r\n        Log().RemoveLogger(std::string{ s_OutputDebugStringLoggerName });\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/PackageDependenciesValidationUtil.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include <Public/winget/PackageDependenciesValidationUtil.h>\n#include <winget/ManifestValidation.h>\n\nnamespace AppInstaller::Manifest\n{\n\tWinGetManifestDependenciesErrorResult GetDependenciesValidationResultFromException(const AppInstaller::Manifest::ManifestException& manifestException)\n\t{\n\t\tauto result = WinGetManifestDependenciesErrorResult::None;\n\t\tauto validationErrors = manifestException.Errors();\n\n\t\tfor (const auto& validationError : validationErrors)\n\t\t{\n\t\t\tauto message = validationError.Message;\n\n\t\t\tstd::map<AppInstaller::StringResource::StringId, WinGetManifestDependenciesErrorResult> dependenciesErrorMessageMap =\n\t\t\t{\n\t\t\t\t{ManifestError::SingleManifestPackageHasDependencies, WinGetManifestDependenciesErrorResult::SingleManifestPackageHasDependencies},\n\t\t\t\t{ManifestError::MultiManifestPackageHasDependencies, WinGetManifestDependenciesErrorResult::MultiManifestPackageHasDependencies },\n\t\t\t\t{ManifestError::MissingManifestDependenciesNode, WinGetManifestDependenciesErrorResult::MissingManifestDependenciesNode },\n\t\t\t\t{ManifestError::NoSuitableMinVersionDependency, WinGetManifestDependenciesErrorResult::NoSuitableMinVersionDependency },\n\t\t\t\t{ManifestError::FoundDependencyLoop, WinGetManifestDependenciesErrorResult::FoundDependencyLoop }\n\t\t\t};\n\n\t\t\tauto itr = dependenciesErrorMessageMap.find(message);\n\n\t\t\tif (itr != dependenciesErrorMessageMap.end())\n\t\t\t{\n\t\t\t\tresult |= itr->second;\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n}"
  },
  {
    "path": "src/AppInstallerCommonCore/PackageVersionDataManifest.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/PackageVersionDataManifest.h\"\r\n#include \"Public/winget/Yaml.h\"\r\n#include <AppInstallerErrors.h>\r\n#include <AppInstallerLogging.h>\r\n#include <AppInstallerStrings.h>\r\n\r\nusing namespace std::string_view_literals;\r\n\r\nnamespace AppInstaller::Manifest\r\n{\r\n    // These shortened names save some bytes since humans are neither authoring them nor reading them (except to debug).\r\n    static constexpr std::string_view s_FieldName_SchemaVersion = \"sV\"sv;\r\n    static constexpr std::string_view s_FieldName_VersionData = \"vD\"sv;\r\n    static constexpr std::string_view s_FieldName_Version = \"v\"sv;\r\n    static constexpr std::string_view s_FieldName_ArpMinVersion = \"aMiV\"sv;\r\n    static constexpr std::string_view s_FieldName_ArpMaxVersion = \"aMaV\"sv;\r\n    static constexpr std::string_view s_FieldName_RelativePath = \"rP\"sv;\r\n    static constexpr std::string_view s_FieldName_Sha256Hash = \"s256H\"sv;\r\n\r\n    static constexpr std::string_view s_SchemaVersion_1_0 = \"1.0\"sv;\r\n\r\n    static constexpr DWORD CompressionAlgorithm = COMPRESS_ALGORITHM_MSZIP;\r\n    static constexpr bool CompressionSetLevel1 = false;\r\n\r\n    namespace anon\r\n    {\r\n        std::string GetRequiredChildString(const YAML::Node& node, std::string_view childName)\r\n        {\r\n            const YAML::Node& childNode = node.GetChildNode(childName);\r\n            THROW_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_MANIFEST, !childNode.IsScalar());\r\n            return childNode.as<std::string>();\r\n        }\r\n\r\n        std::optional<std::string> GetOptionalChildString(const YAML::Node& node, std::string_view childName)\r\n        {\r\n            const YAML::Node& childNode = node.GetChildNode(childName);\r\n            return childNode.IsScalar() ? std::make_optional(childNode.as<std::string>()) : std::nullopt;\r\n        }\r\n\r\n        void Deserialize_1_0(const YAML::Node& document, PackageVersionDataManifest& manifest)\r\n        {\r\n            const YAML::Node& versionDataItems = document.GetChildNode(s_FieldName_VersionData);\r\n            THROW_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_MANIFEST, !versionDataItems.IsSequence());\r\n\r\n            for (const YAML::Node& item : versionDataItems.Sequence())\r\n            {\r\n                THROW_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_MANIFEST, !item.IsMap());\r\n\r\n                PackageVersionDataManifest::VersionData versionData;\r\n\r\n                versionData.Version.Assign(GetRequiredChildString(item, s_FieldName_Version));\r\n                versionData.ArpMinVersion = GetOptionalChildString(item, s_FieldName_ArpMinVersion);\r\n                versionData.ArpMaxVersion = GetOptionalChildString(item, s_FieldName_ArpMaxVersion);\r\n                versionData.ManifestRelativePath = GetRequiredChildString(item, s_FieldName_RelativePath);\r\n                versionData.ManifestHash = GetRequiredChildString(item, s_FieldName_Sha256Hash);\r\n\r\n                manifest.AddVersion(std::move(versionData));\r\n            }\r\n        }\r\n    }\r\n\r\n    std::string_view PackageVersionDataManifest::VersionManifestFileName()\r\n    {\r\n        return \"versionData.yml\"sv;\r\n    }\r\n\r\n    std::string_view PackageVersionDataManifest::VersionManifestCompressedFileName()\r\n    {\r\n        return \"versionData.mszyml\"sv;\r\n    }\r\n\r\n    std::filesystem::path PackageVersionDataManifest::GetRelativeDirectoryPath(std::string_view packageIdentifier, std::string_view manifestHash)\r\n    {\r\n        std::filesystem::path result = \"packages\";\r\n        result /= Utility::ConvertToUTF16(packageIdentifier);\r\n        result /= manifestHash.substr(0, 8);\r\n        return result;\r\n    }\r\n\r\n    Compression::Compressor PackageVersionDataManifest::CreateCompressor()\r\n    {\r\n        Compression::Compressor result(CompressionAlgorithm);\r\n        if constexpr (CompressionSetLevel1)\r\n        {\r\n            result.SetInformation(COMPRESS_INFORMATION_CLASS_LEVEL, 1);\r\n        }\r\n        return result;\r\n    }\r\n\r\n    Compression::Decompressor PackageVersionDataManifest::CreateDecompressor()\r\n    {\r\n        return Compression::Decompressor(CompressionAlgorithm);\r\n    }\r\n\r\n    PackageVersionDataManifest::VersionData::VersionData(\r\n        const Utility::VersionAndChannel& versionAndChannel,\r\n        std::optional<std::string> arpMinVersion,\r\n        std::optional<std::string> arpMaxVersion,\r\n        std::optional<std::string> relativePath,\r\n        std::optional<std::string> manifestHash) :\r\n        Version(versionAndChannel.GetVersion()),\r\n        ArpMinVersion(std::move(arpMinVersion)),\r\n        ArpMaxVersion(std::move(arpMaxVersion)),\r\n        ManifestRelativePath(std::move(relativePath).value_or(\"\")),\r\n        ManifestHash(std::move(manifestHash).value_or(\"\"))\r\n    {\r\n        if (ArpMinVersion && ArpMinVersion->empty())\r\n        {\r\n            ArpMinVersion.reset();\r\n        }\r\n\r\n        if (ArpMaxVersion && ArpMaxVersion->empty())\r\n        {\r\n            ArpMaxVersion.reset();\r\n        }\r\n    }\r\n\r\n    void PackageVersionDataManifest::AddVersion(VersionData&& versionData)\r\n    {\r\n        m_versions.emplace_back(std::move(versionData));\r\n    }\r\n\r\n    const std::vector<PackageVersionDataManifest::VersionData>& PackageVersionDataManifest::Versions() const\r\n    {\r\n        return m_versions;\r\n    }\r\n\r\n    std::string PackageVersionDataManifest::Serialize()\r\n    {\r\n        YAML::Emitter out;\r\n        out << YAML::BeginMap;\r\n        out << YAML::Key << s_FieldName_SchemaVersion << YAML::Value << s_SchemaVersion_1_0;\r\n\r\n        out << YAML::Key << s_FieldName_VersionData;\r\n        out << YAML::BeginSeq;\r\n\r\n        for (const auto& version : m_versions)\r\n        {\r\n            out << YAML::BeginMap;\r\n            out << YAML::Key << s_FieldName_Version << YAML::Value << version.Version.ToString();\r\n            if (version.ArpMinVersion)\r\n            {\r\n                out << YAML::Key << s_FieldName_ArpMinVersion << YAML::Value << version.ArpMinVersion.value();\r\n            }\r\n            if (version.ArpMaxVersion)\r\n            {\r\n                out << YAML::Key << s_FieldName_ArpMaxVersion << YAML::Value << version.ArpMaxVersion.value();\r\n            }\r\n            out << YAML::Key << s_FieldName_RelativePath << YAML::Value << version.ManifestRelativePath;\r\n            out << YAML::Key << s_FieldName_Sha256Hash << YAML::Value << version.ManifestHash;\r\n            out << YAML::EndMap;\r\n        }\r\n\r\n        out << YAML::EndSeq;\r\n        out << YAML::EndMap;\r\n\r\n        return out.str();\r\n    }\r\n\r\n    void PackageVersionDataManifest::Deserialize(std::string_view input)\r\n    {\r\n        AICLI_LOG_LARGE_STRING(Core, Verbose, << \"PackageVersionDataManifest deserializing:\", input);\r\n\r\n        YAML::Node document = YAML::Load(input);\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_MANIFEST, !document.IsMap());\r\n\r\n        const YAML::Node& schemaVersionNode = document.GetChildNode(s_FieldName_SchemaVersion);\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_MANIFEST, !schemaVersionNode.IsScalar());\r\n\r\n        Utility::Version schemaVersion{ schemaVersionNode.as<std::string>() };\r\n\r\n        if (schemaVersion.PartAt(0).Integer == 1)\r\n        {\r\n            anon::Deserialize_1_0(document, *this);\r\n        }\r\n        else\r\n        {\r\n            THROW_HR(APPINSTALLER_CLI_ERROR_UNSUPPORTED_MANIFESTVERSION);\r\n        }\r\n    }\r\n\r\n    void PackageVersionDataManifest::Deserialize(const std::vector<uint8_t>& input)\r\n    {\r\n        Deserialize(std::string_view{ reinterpret_cast<const char*>(input.data()), input.size() });\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/PathVariable.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"winget/PathVariable.h\"\r\n#include <winget/Filesystem.h>\r\n\r\nusing namespace AppInstaller::Utility;\r\n\r\nnamespace AppInstaller::Registry::Environment\r\n{\r\n    namespace\r\n    {\r\n        constexpr std::wstring_view s_PathName = L\"Path\";\r\n        constexpr std::wstring_view s_PathSubkey_User = L\"Environment\";\r\n        constexpr std::wstring_view s_PathSubkey_Machine = L\"SYSTEM\\\\CurrentControlSet\\\\Control\\\\Session Manager\\\\Environment\";\r\n\r\n        void EnsurePathValueEndsWithSemicolon(std::string& value)\r\n        {\r\n            if (value.back() != ';')\r\n            {\r\n                value += ';';\r\n            }\r\n        }\r\n\r\n        std::string ExpandPathValue(const std::string& value)\r\n        {\r\n            std::string result;\r\n            std::vector<std::string> pathEntries = Split(value, ';');\r\n            for (std::string& pathEntry : pathEntries)\r\n            {\r\n                if (!pathEntry.empty())\r\n                {\r\n                    result += AppInstaller::Filesystem::GetExpandedPath(pathEntry).u8string();\r\n                    result += ';';\r\n                }\r\n            }\r\n            return result;\r\n        }\r\n    }\r\n\r\n    PathVariable::PathVariable(Manifest::ScopeEnum scope, bool readOnly) : m_scope(scope), m_readOnly(readOnly)\r\n    {\r\n        if (m_readOnly)\r\n        {\r\n            if (m_scope == Manifest::ScopeEnum::Machine)\r\n            {\r\n                m_key = Registry::Key::OpenIfExists(HKEY_LOCAL_MACHINE, std::wstring{ s_PathSubkey_Machine });\r\n            }\r\n            else\r\n            {\r\n                m_key = Registry::Key::OpenIfExists(HKEY_CURRENT_USER, std::wstring{ s_PathSubkey_User });\r\n            }\r\n        }\r\n        else\r\n        {\r\n            if (m_scope == Manifest::ScopeEnum::Machine)\r\n            {\r\n                m_key = Registry::Key::Create(HKEY_LOCAL_MACHINE, std::wstring{ s_PathSubkey_Machine });\r\n            }\r\n            else\r\n            {\r\n                m_key = Registry::Key::Create(HKEY_CURRENT_USER, std::wstring{ s_PathSubkey_User });\r\n            }\r\n        }\r\n    }\r\n\r\n    std::string PathVariable::GetPathValue()\r\n    {\r\n        std::wstring pathName = std::wstring{ s_PathName };\r\n        return Normalize(m_key[pathName]->GetValue<Value::Type::String>());\r\n    }\r\n\r\n    bool PathVariable::Contains(const std::filesystem::path& target)\r\n    {\r\n        std::string targetString = Normalize(target.u8string());\r\n        return (GetPathValue().find(targetString) != std::string::npos);\r\n    }\r\n\r\n    bool PathVariable::Remove(const std::filesystem::path& target)\r\n    {\r\n        THROW_HR_IF(E_ACCESSDENIED, m_readOnly);\r\n\r\n        if (Contains(target))\r\n        {\r\n            std::string targetString = Normalize(target.u8string());\r\n            std::string pathValue = GetPathValue();\r\n            FindAndReplace(pathValue, targetString, \"\");\r\n            FindAndReplace(pathValue, \";;\", \";\");\r\n            SetPathValue(pathValue);\r\n            return true;\r\n        }\r\n        else\r\n        {\r\n            return false;\r\n        }\r\n    }\r\n\r\n    bool PathVariable::Append(const std::filesystem::path& target)\r\n    {\r\n        THROW_HR_IF(E_ACCESSDENIED, m_readOnly);\r\n\r\n        if (!Contains(target))\r\n        {\r\n            std::string targetString = Normalize(target.u8string());\r\n            std::string pathValue = GetPathValue();\r\n            EnsurePathValueEndsWithSemicolon(pathValue);\r\n            pathValue += targetString;\r\n            EnsurePathValueEndsWithSemicolon(pathValue);\r\n            SetPathValue(pathValue);\r\n            return true;\r\n        }\r\n        else\r\n        {\r\n            return false;\r\n        }\r\n    }\r\n\r\n    void PathVariable::SetPathValue(const std::string& value)\r\n    {\r\n        THROW_HR_IF(E_ACCESSDENIED, m_readOnly);\r\n\r\n        std::wstring pathName = std::wstring{ s_PathName };\r\n        m_key.SetValue(pathName, ConvertToUTF16(value), REG_EXPAND_SZ);\r\n        SendNotifyMessageW(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)TEXT(\"Environment\"));\r\n\r\n    }\r\n\r\n    bool RefreshPathVariableForCurrentProcess()\r\n    {\r\n        // Path values must be expanded before assigning to process environment for proper refresh.\r\n        std::string systemPathValue = ExpandPathValue(PathVariable(Manifest::ScopeEnum::Machine, true).GetPathValue());\r\n        std::string userPathValue = ExpandPathValue(PathVariable(Manifest::ScopeEnum::User, true).GetPathValue());\r\n        std::wstring pathValue = ConvertToUTF16(systemPathValue + userPathValue);\r\n        return _wputenv_s(L\"PATH\", pathValue.c_str()) == 0;\r\n    }\r\n}"
  },
  {
    "path": "src/AppInstallerCommonCore/Pin.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"winget/Pin.h\"\r\n\r\nusing namespace AppInstaller::Utility;\r\n\r\nnamespace AppInstaller::Pinning\r\n{\r\n    using namespace std::string_view_literals;\r\n\r\n    namespace\r\n    {\r\n        // Source ID to use for the installed source; it does not match any installed source.\r\n        // This does match with the actual ID of the source, but it doesn't really matter\r\n        // as it is handled specially when we see it.\r\n        constexpr std::string_view s_installedSourceId = \"*PredefinedInstalledSource\"sv;\r\n    }\r\n\r\n    PinType ConvertToPinTypeEnum(std::string_view in)\r\n    {\r\n        if (Utility::CaseInsensitiveEquals(in, \"Blocking\"sv))\r\n        {\r\n            return PinType::Blocking;\r\n        }\r\n        else if (Utility::CaseInsensitiveEquals(in, \"Pinning\"sv))\r\n        {\r\n            return PinType::Pinning;\r\n        }\r\n        else if (Utility::CaseInsensitiveEquals(in, \"Gating\"sv))\r\n        {\r\n            return PinType::Gating;\r\n        }\r\n        else if (Utility::CaseInsensitiveEquals(in, \"PinnedByManifest\"sv))\r\n        {\r\n            return PinType::PinnedByManifest;\r\n        }\r\n        else\r\n        {\r\n            return PinType::Unknown;\r\n        }\r\n    }\r\n\r\n    std::string_view ToString(PinType type)\r\n    {\r\n        switch (type)\r\n        {\r\n        case PinType::Blocking:\r\n            return \"Blocking\"sv;\r\n        case PinType::Pinning:\r\n            return \"Pinning\"sv;\r\n        case PinType::Gating:\r\n            return \"Gating\"sv;\r\n        case PinType::PinnedByManifest:\r\n            return \"PinnedByManifest\"sv;\r\n        case PinType::Unknown:\r\n        default:\r\n            return \"Unknown\";\r\n        }\r\n    }\r\n\r\n    bool IsStricter(PinType first, PinType second)\r\n    {\r\n        return first > second;\r\n    }\r\n\r\n    PinType Stricter(PinType first, PinType second)\r\n    {\r\n        return IsStricter(first, second) ? first : second;\r\n    }\r\n\r\n    std::string PinKey::ToString() const\r\n    {\r\n        std::stringstream ss;\r\n        ss << \"Package=[\" << PackageId << \"] Source=[\" << SourceId << \"]\";\r\n        return ss.str();\r\n    }\r\n\r\n    PinKey PinKey::GetPinKeyForInstalled(std::string_view systemReferenceString)\r\n    {\r\n        return { systemReferenceString, s_installedSourceId };\r\n    }\r\n\r\n    bool PinKey::IsForInstalled() const\r\n    {\r\n        return SourceId == s_installedSourceId;\r\n    }\r\n\r\n    std::string Pin::ToString() const\r\n    {\r\n        std::stringstream ss;\r\n        ss << m_key.ToString() << \" Type=[\" << Pinning::ToString(m_type) << ']';\r\n\r\n        if (m_type == PinType::Gating)\r\n        {\r\n            ss << \" GatedVersion=[\" << m_gatedVersion.ToString() << ']';\r\n        }\r\n\r\n        return ss.str();\r\n    }\r\n\r\n    Pin Pin::CreateBlockingPin(PinKey&& pinKey)\r\n    {\r\n        return { PinType::Blocking, std::move(pinKey) };\r\n    }\r\n\r\n    Pin Pin::CreatePinningPin(PinKey&& pinKey)\r\n    {\r\n        return { PinType::Pinning, std::move(pinKey) };\r\n    }\r\n\r\n    Pin Pin::CreateGatingPin(PinKey&& pinKey, GatedVersion&& gatedVersion)\r\n    {\r\n        return { PinType::Gating, std::move(pinKey), std::move(gatedVersion) };\r\n    }\r\n\r\n    bool Pin::operator==(const Pin& other) const\r\n    {\r\n        return m_type == other.m_type &&\r\n            m_key == other.m_key &&\r\n            m_gatedVersion == other.m_gatedVersion;\r\n    }\r\n}"
  },
  {
    "path": "src/AppInstallerCommonCore/PortableARPEntry.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"winget/PortableARPEntry.h\"\r\n#include \"winget/Manifest.h\"\r\n\r\nusing namespace AppInstaller::Utility;\r\n\r\n#define VALUENAMECASE(valueName) case PortableValueName::valueName: return s_##valueName;\r\n\r\nnamespace AppInstaller::Registry::Portable\r\n{\r\n    namespace\r\n    {\r\n        constexpr std::wstring_view s_UninstallRegistryX64 = L\"Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Uninstall\";\r\n        constexpr std::wstring_view s_UninstallRegistryX86 = L\"Software\\\\Wow6432Node\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Uninstall\";\r\n        constexpr std::wstring_view s_DisplayName = L\"DisplayName\";\r\n        constexpr std::wstring_view s_DisplayVersion = L\"DisplayVersion\";\r\n        constexpr std::wstring_view s_Publisher = L\"Publisher\";\r\n        constexpr std::wstring_view s_InstallDate = L\"InstallDate\";\r\n        constexpr std::wstring_view s_URLInfoAbout = L\"URLInfoAbout\";\r\n        constexpr std::wstring_view s_HelpLink = L\"HelpLink\";\r\n        constexpr std::wstring_view s_UninstallString = L\"UninstallString\";\r\n        constexpr std::wstring_view s_WinGetInstallerType = L\"WinGetInstallerType\";\r\n        constexpr std::wstring_view s_InstallLocation = L\"InstallLocation\";\r\n        constexpr std::wstring_view s_PortableTargetFullPath = L\"TargetFullPath\";\r\n        constexpr std::wstring_view s_PortableSymlinkFullPath = L\"SymlinkFullPath\";\r\n        constexpr std::wstring_view s_SHA256 = L\"SHA256\";\r\n        constexpr std::wstring_view s_WinGetPackageIdentifier = L\"WinGetPackageIdentifier\";\r\n        constexpr std::wstring_view s_WinGetSourceIdentifier = L\"WinGetSourceIdentifier\";\r\n        constexpr std::wstring_view s_InstallDirectoryCreated = L\"InstallDirectoryCreated\";\r\n        constexpr std::wstring_view s_InstallDirectoryAddedToPath = L\"InstallDirectoryAddedToPath\";\r\n    }\r\n\r\n    PortableARPEntry::PortableARPEntry(Manifest::ScopeEnum scope, Utility::Architecture arch, const std::string& productCode)\r\n    {\r\n        m_scope = scope;\r\n        m_arch = arch;\r\n        m_productCode = productCode;\r\n\r\n        if (m_scope == Manifest::ScopeEnum::Machine)\r\n        {\r\n            m_root = HKEY_LOCAL_MACHINE;\r\n            if (m_arch == Utility::Architecture::X64)\r\n            {\r\n                m_subKey = s_UninstallRegistryX64;\r\n                m_samDesired = KEY_WOW64_64KEY;\r\n            }\r\n            else\r\n            {\r\n                m_subKey = s_UninstallRegistryX86;\r\n                m_samDesired = KEY_WOW64_32KEY;\r\n            }\r\n        }\r\n        else\r\n        {\r\n            // HKCU uninstall registry share the x64 registry view.\r\n            m_root = HKEY_CURRENT_USER;\r\n            m_subKey = s_UninstallRegistryX64;\r\n            m_samDesired = KEY_WOW64_64KEY;\r\n        }\r\n\r\n        m_subKey += L\"\\\\\" + ConvertToUTF16(m_productCode);\r\n        m_key = Key::OpenIfExists(m_root, m_subKey, 0, KEY_ALL_ACCESS);\r\n        if (m_key != NULL)\r\n        {\r\n            m_exists = true;\r\n        }\r\n        else\r\n        {\r\n            m_exists = false;\r\n            m_key = Key::Create(m_root, m_subKey);\r\n        }\r\n    }\r\n\r\n    std::wstring_view ToString(PortableValueName valueName)\r\n    {\r\n        switch (valueName)\r\n        {\r\n            VALUENAMECASE(DisplayName);\r\n            VALUENAMECASE(DisplayVersion);\r\n            VALUENAMECASE(Publisher);\r\n            VALUENAMECASE(InstallDate);\r\n            VALUENAMECASE(URLInfoAbout);\r\n            VALUENAMECASE(HelpLink);\r\n            VALUENAMECASE(UninstallString);\r\n            VALUENAMECASE(WinGetInstallerType);\r\n            VALUENAMECASE(InstallLocation);\r\n            VALUENAMECASE(PortableTargetFullPath);\r\n            VALUENAMECASE(PortableSymlinkFullPath);\r\n            VALUENAMECASE(SHA256);\r\n            VALUENAMECASE(WinGetPackageIdentifier);\r\n            VALUENAMECASE(WinGetSourceIdentifier);\r\n            VALUENAMECASE(InstallDirectoryCreated);\r\n            VALUENAMECASE(InstallDirectoryAddedToPath);\r\n            default: return {};\r\n        }\r\n    }\r\n\r\n    std::optional<Value> PortableARPEntry::operator[](PortableValueName valueName) const\r\n    {\r\n        return m_key[std::wstring{ ToString(valueName) }];\r\n    }\r\n\r\n    void PortableARPEntry::SetValue(PortableValueName valueName, const std::wstring& value)\r\n    {\r\n        m_key.SetValue(std::wstring{ ToString(valueName) }, value, REG_SZ);\r\n    }\r\n\r\n    void PortableARPEntry::SetValue(PortableValueName valueName, const std::string_view& value)\r\n    {\r\n        m_key.SetValue(std::wstring{ ToString(valueName) }, ConvertToUTF16(value), REG_SZ);\r\n    }\r\n\r\n    void PortableARPEntry::SetValue(PortableValueName valueName, bool& value)\r\n    {\r\n        m_key.SetValue(std::wstring{ ToString(valueName) }, value);\r\n    }\r\n\r\n    void PortableARPEntry::Delete()\r\n    {\r\n        Registry::Key::Delete(m_root, m_subKey, m_samDesired);\r\n    }\r\n}"
  },
  {
    "path": "src/AppInstallerCommonCore/Progress.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"AppInstallerProgress.h\"\r\n#include <AppInstallerErrors.h>\r\n\r\nnamespace AppInstaller\r\n{\r\n    HRESULT ToHRESULT(CancelReason reason)\r\n    {\r\n        HRESULT hr = E_ABORT;\r\n\r\n        switch (reason)\r\n        {\r\n        case CancelReason::CtrlCSignal:\r\n            hr = APPINSTALLER_CLI_ERROR_CTRL_SIGNAL_RECEIVED;\r\n            break;\r\n        case CancelReason::AppShutdown:\r\n            hr = APPINSTALLER_CLI_ERROR_APPTERMINATION_RECEIVED;\r\n            break;\r\n        }\r\n\r\n        return hr;\r\n    }\r\n\r\n    ProgressCallback::ProgressCallback(IProgressSink* sink) : m_sink(sink)\r\n    {\r\n    }\r\n\r\n    void ProgressCallback::BeginProgress()\r\n    {\r\n        IProgressSink* sink = GetSink();\r\n        if (sink)\r\n        {\r\n            sink->BeginProgress();\r\n        }\r\n    }\r\n\r\n    void ProgressCallback::OnProgress(uint64_t current, uint64_t maximum, ProgressType type)\r\n    {\r\n        IProgressSink* sink = GetSink();\r\n        if (sink)\r\n        {\r\n            sink->OnProgress(current, maximum, type);\r\n        }\r\n    }\r\n\r\n    void ProgressCallback::SetProgressMessage(std::string_view message)\r\n    {\r\n        IProgressSink* sink = GetSink();\r\n        if (sink)\r\n        {\r\n            sink->SetProgressMessage(message);\r\n        }\r\n    }\r\n\r\n    void ProgressCallback::EndProgress(bool hideProgressWhenDone)\r\n    {\r\n        IProgressSink* sink = GetSink();\r\n        if (sink)\r\n        {\r\n            sink->EndProgress(hideProgressWhenDone);\r\n        }\r\n    };\r\n\r\n    bool ProgressCallback::IsCancelledBy(CancelReason cancelReasons)\r\n    {\r\n        THROW_HR_IF(E_UNEXPECTED, cancelReasons == CancelReason::None);\r\n        return WI_IsAnyFlagSet(cancelReasons, m_cancelReason);\r\n    }\r\n\r\n    [[nodiscard]] IProgressCallback::CancelFunctionRemoval ProgressCallback::SetCancellationFunction(std::function<void()>&& f)\r\n    {\r\n        m_cancellationFunction = std::move(f);\r\n        if (m_cancellationFunction)\r\n        {\r\n            return IProgressCallback::CancelFunctionRemoval(this);\r\n        }\r\n        else\r\n        {\r\n            return {};\r\n        }\r\n    }\r\n\r\n    bool ProgressCallback::Wait(IProgressCallback& progress, std::chrono::milliseconds millisecondsToWait)\r\n    {\r\n        wil::unique_event calledEvent;\r\n        calledEvent.create();\r\n\r\n        auto cancellationFunc = progress.SetCancellationFunction([&calledEvent]()\r\n            {\r\n                calledEvent.SetEvent();\r\n            });\r\n\r\n        if (calledEvent.wait(static_cast<DWORD>(millisecondsToWait.count())))\r\n        {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    void ProgressCallback::Cancel(CancelReason reason)\r\n    {\r\n        m_cancelReason = reason;\r\n        if (m_cancellationFunction)\r\n        {\r\n            m_cancellationFunction();\r\n        }\r\n    }\r\n\r\n    IProgressSink* ProgressCallback::GetSink()\r\n    {\r\n        return m_sink.load();\r\n    }\r\n\r\n    PartialPercentProgressCallback::PartialPercentProgressCallback(IProgressCallback& baseCallback, uint64_t globalMax) :\r\n        m_baseCallback(baseCallback), m_globalMax(globalMax)\r\n    {\r\n    }\r\n\r\n    void PartialPercentProgressCallback::BeginProgress()\r\n    {\r\n        THROW_HR(E_NOTIMPL);\r\n    }\r\n\r\n    void PartialPercentProgressCallback::OnProgress(uint64_t current, uint64_t maximum, ProgressType type)\r\n    {\r\n        THROW_HR_IF(E_UNEXPECTED, ProgressType::Percent != type);\r\n\r\n        m_baseCallback.OnProgress(m_rangeMin + (m_rangeMax - m_rangeMin) * current / maximum, m_globalMax, type);\r\n    }\r\n\r\n    void PartialPercentProgressCallback::SetProgressMessage(std::string_view message)\r\n    {\r\n        m_baseCallback.SetProgressMessage(message);\r\n    }\r\n\r\n    void PartialPercentProgressCallback::EndProgress(bool)\r\n    {\r\n        THROW_HR(E_NOTIMPL);\r\n    }\r\n\r\n    IProgressCallback::CancelFunctionRemoval PartialPercentProgressCallback::SetCancellationFunction(std::function<void()>&& f)\r\n    {\r\n        return m_baseCallback.SetCancellationFunction(std::move(f));\r\n    }\r\n\r\n    void PartialPercentProgressCallback::SetRange(uint64_t rangeMin, uint64_t rangeMax)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, rangeMin > rangeMax || rangeMax > m_globalMax);\r\n        m_rangeMin = rangeMin;\r\n        m_rangeMax = rangeMax;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/PropertySheet.props",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ImportGroup Label=\"PropertySheets\" />\n  <PropertyGroup Label=\"UserMacros\" />\n    <!--\n    To customize common C++/WinRT project properties: \n    * right-click the project node\n    * expand the Common Properties item\n    * select the C++/WinRT property page\n\n    For more advanced scenarios, and complete documentation, please see:\n    https://github.com/Microsoft/xlang/tree/master/src/package/cppwinrt/nuget \n    -->\n  <PropertyGroup />\n  <ItemDefinitionGroup />\n</Project>"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/AppInstallerArchitecture.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <optional>\r\n#include <vector>\r\n#include <winget/LocIndependent.h>\r\n#include <winrt/Windows.System.h>\r\n\r\nnamespace AppInstaller::Utility\r\n{\r\n    static const int InapplicableArchitecture = -1;\r\n\r\n    enum class Architecture\r\n    {\r\n        Unknown = -1,\r\n        Neutral,\r\n        X86,\r\n        X64,\r\n        Arm,\r\n        Arm64\r\n    };\r\n\r\n    // Converts a string to corresponding enum\r\n    Architecture ConvertToArchitectureEnum(std::string_view archStr);\r\n\r\n    // Converts an ProcessorArchitecture to an Architecture\r\n    std::optional<Architecture> ConvertToArchitectureEnum(winrt::Windows::System::ProcessorArchitecture architecture);\r\n\r\n    // Converts an Architecture to a string_view\r\n    LocIndView ToString(Architecture architecture);\r\n\r\n    // Gets the system's architecture as Architecture enum\r\n    AppInstaller::Utility::Architecture GetSystemArchitecture();\r\n\r\n    // Gets the set of architectures that are applicable to the current system\r\n    const std::vector<Architecture>& GetApplicableArchitectures();\r\n\r\n    // Gets the set of architectures that are supported by winget\r\n    const std::vector<Architecture>& GetAllArchitectures();\r\n\r\n    // Gets if an architecture is applicable to the system\r\n    // Returns the priority in the applicable architecture list if the architecture is applicable. 0 has lowest priority.\r\n    // Returns -1 if the architecture is not applicable.\r\n    int IsApplicableArchitecture(Architecture arch);\r\n\r\n    // Gets if an architecture is applicable to the given list\r\n    // Returns the priority in the applicable architecture list if the architecture is applicable. 0 has lowest priority.\r\n    // Returns -1 if the architecture is not applicable.\r\n    int IsApplicableArchitecture(Architecture arch, const std::vector<Architecture>& allowedArchitectures);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/AppInstallerDeployment.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerProgress.h>\r\n#include <winrt/Windows.Foundation.h>\r\n#include <winrt/Windows.Management.Deployment.h>\r\n\r\nnamespace AppInstaller::Deployment\r\n{\r\n    // A set of optional values useful across many of the deployment functions.\r\n    struct Options\r\n    {\r\n        Options() = default;\r\n        explicit Options(bool skipReputationCheck) : SkipReputationCheck(skipReputationCheck) {}\r\n\r\n        // Avoid using APIs that make a reputation check.\r\n        bool SkipReputationCheck = false;\r\n\r\n        // The pairs of URI+Digest to enforce.\r\n        std::vector<std::pair<std::string, std::wstring>> ExpectedDigests;\r\n    };\r\n\r\n    // Calls winrt::Windows::Management::Deployment::PackageManager::AddPackageAsync if skipSmartScreen is true,\r\n    // Otherwise, calls winrt::Windows::Management::Deployment::PackageManager::RequestAddPackageAsync\r\n    void AddPackage(\r\n        const winrt::Windows::Foundation::Uri& uri,\r\n        const Options& options,\r\n        IProgressCallback& callback);\r\n\r\n    // Calls winrt::Windows::Management::Deployment::PackageManager::AddPackageAsync if skipSmartScreen is true,\r\n    // Otherwise, calls winrt::Windows::Management::Deployment::PackageManager::RequestAddPackageAsync.\r\n    // If the Add function fails due to the package being in use, we fall back to stage and register, which allows\r\n    // a deferred registration.\r\n    // Returns true if the registration was deferred; false if not.\r\n    bool AddPackageWithDeferredFallback(\r\n        std::string_view uri,\r\n        const Options& options,\r\n        IProgressCallback& callback);\r\n\r\n    // Calls winrt::Windows::Management::Deployment::PackageManager::RemovePackageAsync\r\n    void RemovePackage(\r\n        std::string_view packageFullName,\r\n        winrt::Windows::Management::Deployment::RemovalOptions options,\r\n        IProgressCallback& callback);\r\n\r\n    // Calls winrt::Windows::Management::Deployment::PackageManager::StagePackageAsync\r\n    //       winrt::Windows::Management::Deployment::PackageManager::ProvisionPackageForAllUsersAsync\r\n    //       winrt::Windows::Management::Deployment::PackageManager::RegisterPackageByFullNameAsync if not running as system\r\n    bool AddPackageMachineScope(\r\n        std::string_view uri,\r\n        const Options& options,\r\n        IProgressCallback& callback);\r\n\r\n    // Calls winrt::Windows::Management::Deployment::PackageManager::DeprovisionPackageForAllUsersAsync\r\n    //       winrt::Windows::Management::Deployment::PackageManager::RemovePackageAsync with RemoveForAllUsers\r\n    void RemovePackageMachineScope(\r\n        std::string_view packageFamilyName,\r\n        std::string_view packageFullName,\r\n        IProgressCallback& callback);\r\n\r\n    // Calls winrt::Windows::Management::Deployment::PackageManager::FindPackagesForUser\r\n    bool IsRegistered(std::string_view packageFamilyName);\r\n\r\n    // Calls winrt::Windows::Management::Deployment::PackageManager::RegisterPackageByFamilyNameAsync\r\n    void RegisterPackage(\r\n        std::string_view packageFamilyName,\r\n        IProgressCallback& callback);\r\n\r\n    // Determines if the ExpectedDigests property (and thus feture) is supported on the current version of Windows.\r\n    bool IsExpectedDigestsSupported();\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/AppInstallerDownloader.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerErrors.h>\r\n#include <AppInstallerProgress.h>\r\n\r\n#include <chrono>\r\n#include <filesystem>\r\n#include <map>\r\n#include <optional>\r\n#include <ostream>\r\n#include <string>\r\n#include <string_view>\r\n#include <vector>\r\n\r\nusing namespace std::chrono_literals;\r\n\r\nnamespace AppInstaller::Utility\r\n{\r\n    // The type of data being downloaded; determines what code should\r\n    // be used when downloading.\r\n    enum class DownloadType\r\n    {\r\n        Index,\r\n        Manifest,\r\n        WinGetUtil,\r\n        Installer,\r\n        InstallerMetadataCollectionInput,\r\n        ConfigurationFile,\r\n    };\r\n\r\n    struct DownloadRequestHeader\r\n    {\r\n        std::string Name;\r\n        std::string Value;\r\n        bool IsAuth = false;\r\n    };\r\n\r\n    // Extra metadata about a download for use by certain downloaders (Delivery Optimization for instance).\r\n    // Extra download request headers.\r\n    struct DownloadInfo\r\n    {\r\n        std::string DisplayName;\r\n        std::string ContentId;\r\n        std::vector<DownloadRequestHeader> RequestHeaders;\r\n    };\r\n\r\n    // Properties about the downloaded file.\r\n    struct DownloadResult\r\n    {\r\n        std::vector<BYTE> Sha256Hash;\r\n        uint64_t SizeInBytes = 0;\r\n        std::optional<std::string> ContentType;\r\n    };\r\n\r\n    // An exception that indicates that a remote service is too busy/unavailable and may contain data on when to try again.\r\n    struct ServiceUnavailableException : public wil::ResultException\r\n    {\r\n        ServiceUnavailableException(std::chrono::seconds retryAfter = 0s) : wil::ResultException(APPINSTALLER_CLI_ERROR_SERVICE_UNAVAILABLE), m_retryAfter(retryAfter) {}\r\n\r\n        std::chrono::seconds RetryAfter() const { return m_retryAfter; }\r\n\r\n    private:\r\n        std::chrono::seconds m_retryAfter;\r\n    };\r\n\r\n    // Downloads a file from the given URL and places it in the given location.\r\n    //   url: The url to be downloaded from. http->https redirection is allowed.\r\n    //   dest: The stream to be downloaded to.\r\n    //   computeHash: Optional. Indicates if SHA256 hash should be calculated when downloading.\r\n    //   downloadInfo: Optional. Currently only used by DO to identify the download.\r\n    DownloadResult DownloadToStream(\r\n        const std::string& url,\r\n        std::ostream& dest,\r\n        DownloadType type,\r\n        IProgressCallback& progress,\r\n        std::optional<DownloadInfo> downloadInfo = {});\r\n\r\n    // Downloads a file from the given URL and places it in the given location.\r\n    //   url: The url to be downloaded from. http->https redirection is allowed.\r\n    //   dest: The path to local file to be downloaded to.\r\n    //   computeHash: Optional. Indicates if SHA256 hash should be calculated when downloading.\r\n    //   downloadInfo: Optional. Currently only used by DO to identify the download.\r\n    DownloadResult Download(\r\n        const std::string& url,\r\n        const std::filesystem::path& dest,\r\n        DownloadType type,\r\n        IProgressCallback& progress,\r\n        std::optional<DownloadInfo> downloadInfo = {});\r\n\r\n    // Gets the headers for the given URL.\r\n    std::map<std::string, std::string> GetHeaders(std::string_view url);\r\n\r\n    // Determines if the given url is a remote location.\r\n    bool IsUrlRemote(std::string_view url);\r\n\r\n    // Determines if the given url is secured.\r\n    bool IsUrlSecure(std::string_view url);\r\n\r\n    // Apply Mark of the web if the target file is on NTFS, otherwise does nothing.\r\n    void ApplyMotwIfApplicable(const std::filesystem::path& filePath, URLZONE zone);\r\n\r\n    // Remove Mark of the web if the target file is on NTFS, otherwise does nothing.\r\n    void RemoveMotwIfApplicable(const std::filesystem::path& filePath);\r\n\r\n    // Apply Mark of the web using IAttachmentExecute::Save if the target file is on NTFS, otherwise does nothing.\r\n    // This method only does a best effort since Attachment Execution Service may be disabled.\r\n    // If IAttachmentExecute::Save is successfully invoked and the scan failed, the failure HRESULT is returned.\r\n    // zoneIfScanFailure: URLZONE to apply if IAttachmentExecute::Save scan failed.\r\n    HRESULT ApplyMotwUsingIAttachmentExecuteIfApplicable(const std::filesystem::path& filePath, const std::string& source, URLZONE zoneIfScanFailure);\r\n\r\n    // Function to read-only create a stream from a uri string (url address or file system path)\r\n    ::Microsoft::WRL::ComPtr<IStream> GetReadOnlyStreamFromURI(std::string_view uriStr);\r\n\r\n    // Gets the retry after value in terms of a delay in seconds.\r\n    std::chrono::seconds GetRetryAfter(const std::wstring& retryAfter);\r\n\r\n    // Gets the retry after value in terms of a delay in seconds.\r\n    std::chrono::seconds GetRetryAfter(const winrt::Windows::Web::Http::HttpResponseMessage& response);\r\n\r\n    // Data about the cache-control header.\r\n    struct CacheControlPolicy\r\n    {\r\n        // Limit max age to a year\r\n        static constexpr unsigned long long MaximumMaxAge = 60 * 60 * 24 * 365;\r\n\r\n        CacheControlPolicy() = default;\r\n        CacheControlPolicy(std::wstring_view header);\r\n\r\n        // True only if the cache-control header was present and contained at least one directive.\r\n        bool Present = false;\r\n\r\n        // The max-age directive; in seconds.\r\n        unsigned long long MaxAge = 0;\r\n\r\n        // The no-cache directive; indicates that the cache should always revalidate.\r\n        bool NoCache = false;\r\n\r\n        // The no-store directive; indicates that the data should not be cached.\r\n        bool NoStore = false;\r\n\r\n        // The public directive; indicates that the data is not user specific.\r\n        bool Public = false;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/AppInstallerFileLogger.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerLogging.h>\r\n\r\n#include <filesystem>\r\n#include <fstream>\r\n#include <string>\r\n#include <string_view>\r\n\r\nnamespace AppInstaller::Logging\r\n{\r\n    // Logs to a file.\r\n    struct FileLogger : public ILogger\r\n    {\r\n        FileLogger();\r\n        explicit FileLogger(const std::filesystem::path& filePath);\r\n        explicit FileLogger(const std::string_view fileNamePrefix);\r\n\r\n        ~FileLogger();\r\n\r\n        FileLogger(const FileLogger&) = delete;\r\n        FileLogger& operator=(const FileLogger&) = delete;\r\n\r\n        FileLogger(FileLogger&&) = default;\r\n        FileLogger& operator=(FileLogger&&) = default;\r\n\r\n        // The default value for the maximum size comes from settings.\r\n        // Setting the maximum size to 0 will disable the maximum.\r\n        FileLogger& SetMaximumSize(std::ofstream::off_type maximumSize);\r\n\r\n        static std::string GetNameForPath(const std::filesystem::path& filePath);\r\n\r\n        static std::string_view DefaultPrefix();\r\n        static std::string_view DefaultExt();\r\n\r\n        // ILogger\r\n        std::string GetName() const override;\r\n\r\n        void Write(Channel channel, Level level, std::string_view message) noexcept override;\r\n\r\n        void WriteDirect(Channel channel, Level level, std::string_view message) noexcept override;\r\n\r\n        void SetTag(Tag tag) noexcept override;\r\n\r\n        // Adds a FileLogger to the current Log\r\n        static void Add();\r\n        static void Add(const std::filesystem::path& filePath);\r\n        static void Add(std::string_view fileNamePrefix);\r\n\r\n        // Starts a background task to clean up old log files.\r\n        static void BeginCleanup();\r\n        static void BeginCleanup(const std::filesystem::path& filePath);\r\n\r\n    private:\r\n        std::string m_name;\r\n        std::filesystem::path m_filePath;\r\n        std::ofstream m_stream;\r\n        std::ofstream::pos_type m_headersEnd = 0;\r\n        std::ofstream::off_type m_maximumSize = 0;\r\n\r\n        void OpenFileLoggerStream();\r\n\r\n        // Initializes the default maximum file size.\r\n        void InitializeDefaultMaximumFileSize();\r\n\r\n        // Determines if the logger needs to wrap back to the beginning, doing so when needed.\r\n        // May also shrink the given view if it exceeds the overall maximum.\r\n        void HandleMaximumFileSize(std::string_view& currentLog);\r\n\r\n        // Resets the log file state so that it will overwrite the data portion.\r\n        void WrapLogFile();\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/AppInstallerMsixInfo.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"AppInstallerProgress.h\"\r\n#include \"winget/ManagedFile.h\"\r\n#include \"winget/Manifest.h\"\r\n#include \"winget/MsixManifest.h\"\r\n#include <AppInstallerVersions.h>\r\n\r\n#include <AppxPackaging.h>\r\n\r\n#include <wrl/client.h>\r\n#include <winrt/Windows.ApplicationModel.h>\r\n\r\n#include <filesystem>\r\n#include <optional>\r\n#include <string>\r\n#include <string_view>\r\n#include <vector>\r\n\r\nnamespace AppInstaller::Msix\r\n{\r\n    // Function to create an AppxBundle package reader given the input file name.\r\n    // Returns true if success, false if the input stream is of wrong type.\r\n    bool GetBundleReader(\r\n        IStream* inputStream,\r\n        IAppxBundleReader** reader);\r\n\r\n    // Function to create an Appx package reader given the input file name.\r\n    // Returns true if success, false if the input stream is of wrong type.\r\n    bool GetPackageReader(\r\n        IStream* inputStream,\r\n        IAppxPackageReader** reader);\r\n\r\n    // Function to create an Appx manifest reader given the input file name.\r\n    void GetManifestReader(\r\n        IStream* inputStream,\r\n        IAppxManifestReader** reader);\r\n\r\n    // Gets the package full name from the family name.\r\n    // This will be the one registered for the current user, if any.\r\n    std::optional<std::string> GetPackageFullNameFromFamilyName(std::string_view familyName);\r\n\r\n    // Gets the package family name from the given full name.\r\n    std::string GetPackageFamilyNameFromFullName(std::string_view fullName);\r\n\r\n    // Gets the package location from the given full name.\r\n    std::optional<std::filesystem::path> GetPackageLocationFromFullName(std::string_view fullName);\r\n\r\n    struct PackageIdInfo\r\n    {\r\n        std::string Name;\r\n        AppInstaller::Utility::UInt64Version Version;\r\n    };\r\n\r\n    // Gets the package id info from the given full name.\r\n    PackageIdInfo GetPackageIdInfoFromFullName(std::string_view fullName);\r\n\r\n    // MsixInfo class handles all appx/msix related query.\r\n    struct MsixInfo\r\n    {\r\n        MsixInfo(std::string_view uriStr);\r\n\r\n        template<typename T, std::enable_if_t<std::is_same_v<T, std::filesystem::path>, int> = 0>\r\n        MsixInfo(const T& path) : MsixInfo(path.u8string()) {}\r\n\r\n        MsixInfo(const MsixInfo&) = default;\r\n        MsixInfo& operator=(const MsixInfo&) = default;\r\n\r\n        MsixInfo(MsixInfo&&) = default;\r\n        MsixInfo& operator=(MsixInfo&&) = default;\r\n\r\n        inline bool GetIsBundle()\r\n        {\r\n            return m_isBundle;\r\n        }\r\n\r\n        // Full content of AppxSignature.p7x\r\n        // If skipP7xFileId is true, returns content of converted .p7s\r\n        std::vector<byte> GetSignature(bool skipP7xFileId = false);\r\n\r\n        // Gets the signature sha256 hash.\r\n        Utility::SHA256::HashBuffer GetSignatureHash();\r\n\r\n        // Gets the digest of the package.\r\n        std::wstring GetDigest();\r\n\r\n        // Gets the package full name.\r\n        std::wstring GetPackageFullNameWide();\r\n        std::string GetPackageFullName();\r\n\r\n        // Gets a value indicating whether the referenced info is newer than the given package.\r\n        bool IsNewerThan(const std::filesystem::path& otherPackage);\r\n\r\n        bool IsNewerThan(const winrt::Windows::ApplicationModel::PackageVersion& otherVersion);\r\n\r\n        // Writes the package file to the given path.\r\n        void WriteToFile(std::string_view packageFile, const std::filesystem::path& target, IProgressCallback& progress);\r\n\r\n        // Writes the package's manifest to the given path.\r\n        void WriteManifestToFile(const std::filesystem::path& target, IProgressCallback& progress);\r\n\r\n        // Writes the package file to the given file handle.\r\n        void WriteToFileHandle(std::string_view packageFile, HANDLE target, IProgressCallback& progress);\r\n\r\n        // Get application package manifests from msix and msixbundle.\r\n        std::vector<MsixPackageManifest> GetAppPackageManifests(bool includeStub = false) const;\r\n\r\n    private:\r\n        bool m_isBundle;\r\n        Microsoft::WRL::ComPtr<IStream> m_stream;\r\n        Microsoft::WRL::ComPtr<IAppxBundleReader> m_bundleReader;\r\n        Microsoft::WRL::ComPtr<IAppxPackageReader> m_packageReader;\r\n\r\n        // Get application packages. Ignore stub packages if any.\r\n        std::vector<Microsoft::WRL::ComPtr<IAppxPackageReader>> GetAppPackages(bool includeStub = false) const;\r\n    };\r\n\r\n    struct GetCertContextResult\r\n    {\r\n        wil::unique_cert_context CertContext;\r\n        wil::unique_hcertstore CertStore;\r\n    };\r\n\r\n    // Get cert context from a signed msix/msixbundle file.\r\n    GetCertContextResult GetCertContextFromMsix(const std::filesystem::path& msixPath);\r\n\r\n    struct WriteLockedMsixFile\r\n    {\r\n        WriteLockedMsixFile(const std::filesystem::path& path);\r\n\r\n        bool ValidateTrustInfo(bool checkMicrosoftOrigin) const;\r\n\r\n    private:\r\n        Utility::ManagedFile m_file;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/AppInstallerProgress.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <wil/resource.h>\r\n#include <atomic>\r\n#include <functional>\r\n#include <string_view>\r\n\r\nnamespace AppInstaller\r\n{\r\n    // Forward declaration\r\n    struct ProgressCallback;\r\n    struct IProgressCallback;\r\n\r\n    namespace details\r\n    {\r\n        // For SetCancellationFunction return.\r\n        inline void RemoveCancellationFunction(IProgressCallback* callback);\r\n    }\r\n\r\n    // The semantic meaning of the progress values.\r\n    enum class ProgressType : uint32_t\r\n    {\r\n        // Progress will not be sent.\r\n        None,\r\n        Bytes,\r\n        Percent,\r\n    };\r\n\r\n    // The reason why progress is cancelled.\r\n    enum class CancelReason : uint32_t\r\n    {\r\n        None = 0x0,\r\n        Abort = 0x1,\r\n        CtrlCSignal = 0x2,\r\n        User = Abort | CtrlCSignal,\r\n        AppShutdown = 0x4,\r\n        Any = 0xFFFFFFFF\r\n    };\r\n\r\n    DEFINE_ENUM_FLAG_OPERATORS(CancelReason);\r\n\r\n    // Gets the HRESULT associated with the given reason.\r\n    HRESULT ToHRESULT(CancelReason reason);\r\n\r\n    // Interface that provides a callback to inform of cancellation.\r\n    struct ICancellable\r\n    {\r\n        // Inform of cancellation with provided reason.\r\n        // When `force` is true, it is expected to happen regardless of user intent.\r\n        virtual void Cancel(CancelReason reason, bool force) = 0;\r\n    };\r\n\r\n    // Interface that only receives progress, and does not participate in cancellation.\r\n    // This allows a sink be simple, and let ProgressCallback handle the complications\r\n    // of cancel state.\r\n    struct IProgressSink\r\n    {\r\n        // Called as progress is made.\r\n        // If maximum is 0, the maximum is unknown.\r\n        virtual void OnProgress(uint64_t current, uint64_t maximum, ProgressType type) = 0;\r\n\r\n        // Sets a message for the current progress state.\r\n        virtual void SetProgressMessage(std::string_view message) = 0;\r\n\r\n        // Called as progress begins.\r\n        virtual void BeginProgress() = 0;\r\n\r\n        // Called as progress ends.\r\n        virtual void EndProgress(bool hideProgressWhenDone) = 0;\r\n    };\r\n\r\n    // Callback interface given to the worker to report to.\r\n    // Also enables the caller to request cancellation.\r\n    struct IProgressCallback : public IProgressSink\r\n    {\r\n        using CancelFunctionRemoval = wil::unique_any<IProgressCallback*, decltype(&details::RemoveCancellationFunction), details::RemoveCancellationFunction>;\r\n\r\n        // Returns a value indicating if the future has been cancelled.\r\n        virtual bool IsCancelledBy(CancelReason cancelReasons) = 0;\r\n\r\n        // Sets a cancellation function that will be called when the operation is to be cancelled.\r\n        [[nodiscard]] virtual CancelFunctionRemoval SetCancellationFunction(std::function<void()>&& f) = 0;\r\n    };\r\n\r\n    // Implementation of IProgressCallback.\r\n    struct ProgressCallback : public IProgressCallback\r\n    {\r\n        ProgressCallback() = default;\r\n        ProgressCallback(IProgressSink* sink);\r\n\r\n        static bool Wait(IProgressCallback& progress, std::chrono::milliseconds ms);\r\n\r\n        void BeginProgress() override;\r\n\r\n        void OnProgress(uint64_t current, uint64_t maximum, ProgressType type) override;\r\n\r\n        void SetProgressMessage(std::string_view message) override;\r\n\r\n        void EndProgress(bool hideProgressWhenDone) override;\r\n\r\n        bool IsCancelledBy(CancelReason cancelReasons) override;\r\n\r\n        [[nodiscard]] IProgressCallback::CancelFunctionRemoval SetCancellationFunction(std::function<void()>&& f) override;\r\n\r\n        void Cancel(CancelReason reason = CancelReason::Abort);\r\n\r\n        IProgressSink* GetSink();\r\n\r\n    private:\r\n        std::atomic<IProgressSink*> m_sink = nullptr;\r\n        std::function<void()> m_cancellationFunction;\r\n        CancelReason m_cancelReason = CancelReason::None;\r\n    };\r\n\r\n    // A progress callback that reports its progress as a partial range of percentage to its base progress callback\r\n    struct PartialPercentProgressCallback : public ProgressCallback\r\n    {\r\n        PartialPercentProgressCallback(IProgressCallback& baseCallback, uint64_t globalMax);\r\n\r\n        void BeginProgress() override;\r\n\r\n        void OnProgress(uint64_t current, uint64_t maximum, ProgressType type) override;\r\n\r\n        void SetProgressMessage(std::string_view message) override;\r\n\r\n        void EndProgress(bool hideProgressWhenDone) override;\r\n\r\n        [[nodiscard]] IProgressCallback::CancelFunctionRemoval SetCancellationFunction(std::function<void()>&& f) override;\r\n\r\n        void SetRange(uint64_t rangeMin, uint64_t rangeMax);\r\n\r\n    private:\r\n        IProgressCallback& m_baseCallback;\r\n        uint64_t m_rangeMin = 0;\r\n        uint64_t m_rangeMax = 0;\r\n        uint64_t m_globalMax = 0;\r\n    };\r\n\r\n    namespace details\r\n    {\r\n        inline void RemoveCancellationFunction(IProgressCallback* callback)\r\n        {\r\n            (void)callback->SetCancellationFunction(nullptr);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/AppInstallerRuntime.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerVersions.h>\r\n#include <winget/LocIndependent.h>\r\n#include <winget/Filesystem.h>\r\n#include <winget/Runtime.h>\r\n\r\n#include <filesystem>\r\n#include <memory>\r\n#include <string>\r\n#include <string_view>\r\n\r\nnamespace AppInstaller::Runtime\r\n{\r\n    // Sets the runtime path state name globally.\r\n    void SetRuntimePathStateName(std::string name);\r\n\r\n    // A path to be retrieved based on the runtime.\r\n    enum class PathName\r\n    {\r\n        // The temporary file location.\r\n        Temp,\r\n        // The local state (file) storage location.\r\n        LocalState,\r\n        // The default location where log files are located.\r\n        DefaultLogLocation,\r\n        // The location that standard type settings are stored.\r\n        // In a packaged context, this returns a prepend value for the container name.\r\n        StandardSettings,\r\n        // The location that user file type settings are stored.\r\n        UserFileSettings,\r\n        // The location where secure settings data is stored (for reading).\r\n        SecureSettingsForRead,\r\n        // The location where secure settings data is stored (for writing).\r\n        SecureSettingsForWrite,\r\n        // The value of %USERPROFILE%.\r\n        UserProfile,\r\n        // The location where portable packages are installed to with user scope.\r\n        PortablePackageUserRoot,\r\n        // The location where portable packages are installed to with machine scope.\r\n        PortablePackageMachineRoot,\r\n        // The location where portable packages are installed to with machine scope (x86).\r\n        PortablePackageMachineRootX86,\r\n        // The location where symlinks to portable packages are stored under user scope.\r\n        PortableLinksUserLocation,\r\n        // The location where symlinks to portable packages are stored under machine scope.\r\n        PortableLinksMachineLocation,\r\n        // The root location for the package containing the winget application.\r\n        SelfPackageRoot,\r\n        // The location where user downloads are stored.\r\n        UserProfileDownloads,\r\n        // The location where configuration modules are stored.\r\n        ConfigurationModules,\r\n        // The location where checkpoints are stored.\r\n        CheckpointsLocation,\r\n        // The location of the CLI executable file.\r\n        CLIExecutable,\r\n        // The directory containing the CLI executable file.\r\n        MCPExecutable,\r\n        // The location of the image assets, if it exists.\r\n        ImageAssets,\r\n        // The location where fonts are installed with user scope.\r\n        FontsUserInstallLocation,\r\n        // The location where fonts are installed with machine scope.\r\n        FontsMachineInstallLocation,\r\n        // The location that standard type settings are stored in files.\r\n        StandardFileSettings,\r\n        // Always one more than the last path; for being able to iterate paths in tests.\r\n        Max\r\n    };\r\n\r\n    // Gets the PathDetails used for the given path.\r\n    // This is exposed primarily to allow for testing, GetPathTo should be preferred.\r\n    Filesystem::PathDetails GetPathDetailsFor(PathName path, bool forDisplay = false);\r\n\r\n    // Gets the path to the requested location.\r\n    inline std::filesystem::path GetPathTo(PathName path, bool forDisplay = false)\r\n    {\r\n        return Filesystem::GetPathTo(path, forDisplay);\r\n    }\r\n\r\n    // Replaces the substring in the path with the user profile environment variable.\r\n    void ReplaceProfilePathsWithEnvironmentVariable(std::filesystem::path& path);\r\n\r\n    // Gets a new temp file path.\r\n    std::filesystem::path GetNewTempFilePath();\r\n\r\n    // Determines whether developer mode is enabled.\r\n    bool IsDevModeEnabled();\r\n\r\n    // Gets the default user agent string for the Windows Package Manager.\r\n    Utility::LocIndString GetDefaultUserAgent();\r\n\r\n    // Gets the user agent string from passed in caller for the Windows Package Manager.\r\n    Utility::LocIndString GetUserAgent(std::string_view caller);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/AppInstallerSynchronization.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerLanguageUtilities.h>\r\n#include <AppInstallerProgress.h>\r\n#include <wil/resource.h>\r\n\r\n#include <chrono>\r\n#include <functional>\r\n#include <string_view>\r\n#include <vector>\r\n\r\nusing namespace std::chrono_literals;\r\n\r\n\r\nnamespace AppInstaller::Synchronization\r\n{\r\n    // This is a standard named mutex.\r\n    // It must be acquired and released (or destroyed) on the same thread, just as all Windows mutexes must be.\r\n    struct CrossProcessLock\r\n    {\r\n        CrossProcessLock(std::string_view name);\r\n        CrossProcessLock(const std::wstring& name);\r\n\r\n        ~CrossProcessLock();\r\n\r\n        CrossProcessLock(const CrossProcessLock&) = delete;\r\n        CrossProcessLock& operator=(const CrossProcessLock&) = delete;\r\n\r\n        CrossProcessLock(CrossProcessLock&&) = default;\r\n        CrossProcessLock& operator=(CrossProcessLock&&) = default;\r\n\r\n        // Acquires the lock; cancellation is enabled via the progress object.\r\n        // Returns true when the lock is acquired and false if the wait is cancelled.\r\n        bool Acquire(IProgressCallback& progress);\r\n\r\n        // Optionally release the lock before destroying the object.\r\n        void Release();\r\n\r\n        // Attempts to acquire the mutex without a wait.\r\n        // Returns true if it was able, false if not.\r\n        bool TryAcquireNoWait();\r\n\r\n        // Indicates whether the lock is held.\r\n        operator bool() const;\r\n\r\n    private:\r\n        wil::unique_mutex m_mutex;\r\n        wil::mutex_release_scope_exit m_lock;\r\n        DWORD m_lockThreadId = 0;\r\n    };\r\n\r\n    // This lock is used to prevent multiple winget related processes from attempting to install (or uninstall) at the same time.\r\n    // It must be acquired and released (or destroyed) on the same thread, just as all Windows mutexes must be.\r\n    struct CrossProcessInstallLock : public CrossProcessLock\r\n    {\r\n        CrossProcessInstallLock() : CrossProcessLock(L\"WinGetCrossProcessInstallLock\") {}\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/AppInstallerTelemetry.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerLanguageUtilities.h>\r\n#include <wil/result_macros.h>\r\n\r\n#include <string_view>\r\n#include <vector>\r\n#include <cguid.h>\r\n\r\nnamespace AppInstaller::Settings\r\n{\r\n    struct UserSettings;\r\n}\r\n\r\nnamespace AppInstaller::Logging\r\n{\r\n    enum class FailureTypeEnum : UINT32\r\n    {\r\n        None = 0x0,\r\n\r\n        // Failure type from FailureInfo in result_macros.h\r\n        ResultException = 0x1, // THROW_...\r\n        ResultReturn = 0x2, // RETURN_..._LOG or RETURN_..._MSG\r\n        ResultLog = 0x3, // LOG_...\r\n        ResultFailFast = 0x4, // FAIL_FAST_...\r\n\r\n        // Other failure types from LogException()\r\n        Unknown = 0x10000,\r\n        WinrtHResultError = 0x10001,\r\n        ResourceOpen = 0x10002,\r\n        StdException = 0x10003,\r\n\r\n        // Command termination\r\n        CommandTermination = 0x20000,\r\n    };\r\n\r\n    // Contains all fields logged through the TelemetryTraceLogger. Last write wins.\r\n    // This will be used to report a summary event upon destruction of the TelemetryTraceLogger.\r\n    struct TelemetrySummary\r\n    {\r\n        TelemetrySummary() = default;\r\n\r\n        // Selectively copy member fields for copy constructor;\r\n        TelemetrySummary(const TelemetrySummary& other);\r\n        TelemetrySummary& operator=(const TelemetrySummary&) = default;\r\n\r\n        TelemetrySummary(TelemetrySummary&&) = default;\r\n        TelemetrySummary& operator=(TelemetrySummary&&) = default;\r\n\r\n        // Log wil failure, exception, command termination\r\n        HRESULT FailureHResult = S_OK;\r\n        std::wstring FailureMessage;\r\n        std::string FailureModule;\r\n        UINT32 FailureThreadId = 0;\r\n        FailureTypeEnum FailureType = FailureTypeEnum::None;\r\n        std::string FailureFile;\r\n        UINT32 FailureLine = 0;\r\n\r\n        // LogStartup\r\n        bool IsCOMCall = false;\r\n\r\n        // LogCommand\r\n        std::string Command;\r\n\r\n        // LogCommandSuccess\r\n        bool CommandSuccess = false;\r\n\r\n        // LogIsManifestLocal\r\n        bool IsManifestLocal = false;\r\n\r\n        // LogManifestFields, LogAppFound\r\n        std::string PackageIdentifier;\r\n        std::string PackageName;\r\n        std::string PackageVersion;\r\n        std::string Channel;\r\n        std::string SourceIdentifier;\r\n\r\n        // LogSelectedInstaller\r\n        INT32 InstallerArchitecture = -1;\r\n        std::string InstallerUrl;\r\n        std::string InstallerType;\r\n        std::string InstallerScope;\r\n        std::string InstallerLocale;\r\n\r\n        // LogSearchRequest\r\n        std::string SearchType;\r\n        std::string SearchQuery;\r\n        std::string SearchId;\r\n        std::string SearchName;\r\n        std::string SearchMoniker;\r\n        std::string SearchTag;\r\n        std::string SearchCommand;\r\n        UINT64 SearchMaximum = 0;\r\n        std::string SearchRequest;\r\n\r\n        // LogSearchResultCount\r\n        UINT64 SearchResultCount = 0;\r\n\r\n        // LogInstallerHashMismatch\r\n        std::vector<uint8_t> HashMismatchExpected;\r\n        std::vector<uint8_t> HashMismatchActual;\r\n        bool HashMismatchOverride = false;\r\n        uint64_t HashMismatchActualSize = 0;\r\n        std::string HashMismatchContentType;\r\n\r\n        // LogInstallerFailure\r\n        std::string InstallerExecutionType;\r\n        UINT32 InstallerErrorCode = 0;\r\n\r\n        // LogUninstallerFailure\r\n        std::string UninstallerExecutionType;\r\n        UINT32 UninstallerErrorCode = 0;\r\n\r\n        // LogRepairFailure\r\n        std::string RepairExecutionType;\r\n        UINT32 RepairErrorCode = 0;\r\n\r\n        // LogSuccessfulInstallARPChange\r\n        UINT64 ChangesToARP = 0;\r\n        UINT64 MatchesInARP = 0;\r\n        UINT64 ChangesThatMatch = 0;\r\n        UINT64 ARPLanguage = 0;\r\n        std::string ARPName;\r\n        std::string ARPVersion;\r\n        std::string ARPPublisher;\r\n\r\n        // LogNonFatalDOError\r\n        std::string DOUrl;\r\n        HRESULT DOHResult = S_OK;\r\n    };\r\n\r\n    // This type contains the registration lifetime of the telemetry trace logging provider.\r\n    // Due to the nature of trace logging, specific methods should be added per desired trace.\r\n    // As there should not be a significantly large number of individual telemetry events,\r\n    // this should not become a burden.\r\n    struct TelemetryTraceLogger\r\n    {\r\n        TelemetryTraceLogger(bool useSummary = true);\r\n\r\n        ~TelemetryTraceLogger();\r\n\r\n        TelemetryTraceLogger(const TelemetryTraceLogger&) = default;\r\n        TelemetryTraceLogger& operator=(const TelemetryTraceLogger&) = default;\r\n\r\n        TelemetryTraceLogger(TelemetryTraceLogger&&) = default;\r\n        TelemetryTraceLogger& operator=(TelemetryTraceLogger&&) = default;\r\n\r\n        // Control whether this trace logger is enabled at runtime.\r\n        bool DisableRuntime();\r\n        void EnableRuntime();\r\n\r\n        // Return address of m_activityId\r\n        const GUID* GetActivityId() const;\r\n\r\n        // Return address of m_parentActivityId\r\n        const GUID* GetParentActivityId() const;\r\n\r\n        // Capture if UserSettings is enabled and set user profile path\r\n        void Initialize();\r\n\r\n        // Try to capture if UserSettings is enabled and set user profile path, returns whether the action is successfully completed.\r\n        // There is a possible circular dependency with the user settings. When initializing the telemetry, we need to read the settings\r\n        // to make sure it's not disabled, but a failure when reading the settings would trigger a telemetry event. We work around that\r\n        // by avoiding initialization (and thus disabling telemetry) until we have successfully read the settings. Subsequent calls to\r\n        // TryInitialize() would finish the initialization.\r\n        bool TryInitialize();\r\n\r\n        // Store the passed in name of the Caller for COM calls\r\n        void SetCaller(const std::string& caller);\r\n\r\n        // Store the passed in Telemetry Correlation Json for COM calls\r\n        void SetTelemetryCorrelationJson(const std::wstring_view jsonStr_view) noexcept;\r\n\r\n        void SetExecutionStage(uint32_t stage) noexcept;\r\n\r\n        std::unique_ptr<TelemetryTraceLogger> CreateSubTraceLogger() const;\r\n\r\n        // Logs the failure info.\r\n        void LogFailure(const wil::FailureInfo& failure) const noexcept;\r\n\r\n        // Logs the initial process startup.\r\n        void LogStartup(bool isCOMCall = false) const noexcept;\r\n\r\n        // Logs the invoked command.\r\n        void LogCommand(std::string_view commandName) const noexcept;\r\n\r\n        // Logs the invoked command success.\r\n        void LogCommandSuccess(std::string_view commandName) const noexcept;\r\n\r\n        // Logs the invoked command termination.\r\n        void LogCommandTermination(HRESULT hr, std::string_view file, size_t line) const noexcept;\r\n\r\n        // Logs the invoked command termination.\r\n        void LogException(FailureTypeEnum type, std::string_view message) const noexcept;\r\n\r\n        // Logs whether the manifest used in workflow is local\r\n        void LogIsManifestLocal(bool isLocalManifest) const noexcept;\r\n\r\n        // Logs the Manifest fields.\r\n        void LogManifestFields(std::string_view id, std::string_view name, std::string_view version) const noexcept;\r\n\r\n        // Logs when there is no matching App found for search\r\n        void LogNoAppMatch() const noexcept;\r\n\r\n        // Logs when there is multiple matching Apps found for search\r\n        void LogMultiAppMatch() const noexcept;\r\n\r\n        // Logs the name and Id of app found\r\n        void LogAppFound(std::string_view name, std::string_view id) const noexcept;\r\n\r\n        // Logs the selected installer details\r\n        void LogSelectedInstaller(int arch, std::string_view url, std::string_view installerType, std::string_view scope, std::string_view language) const noexcept;\r\n\r\n        // Logs details of a search request.\r\n        void LogSearchRequest(\r\n            std::string_view type,\r\n            std::string_view query,\r\n            std::string_view id,\r\n            std::string_view name,\r\n            std::string_view moniker,\r\n            std::string_view tag,\r\n            std::string_view command,\r\n            size_t maximum,\r\n            std::string_view request) const noexcept;\r\n\r\n        // Logs the Search Result\r\n        void LogSearchResultCount(uint64_t resultCount) const noexcept;\r\n\r\n        // Logs a mismatch between the expected and actual hash values.\r\n        void LogInstallerHashMismatch(\r\n            std::string_view id,\r\n            std::string_view version,\r\n            std::string_view channel,\r\n            const std::vector<uint8_t>& expected,\r\n            const std::vector<uint8_t>& actual,\r\n            bool overrideHashMismatch,\r\n            uint64_t downloadSizeInBytes,\r\n            const std::optional<std::string>& contentType) const noexcept;\r\n\r\n        // Logs a failed installation attempt.\r\n        void LogInstallerFailure(std::string_view id, std::string_view version, std::string_view channel, std::string_view type, uint32_t errorCode) const noexcept;\r\n\r\n        // Logs a failed uninstallation attempt.\r\n        void LogUninstallerFailure(std::string_view id, std::string_view version, std::string_view type, uint32_t errorCode) const noexcept;\r\n\r\n        // Logs a failed repair attempt.\r\n        void LogRepairFailure(std::string_view id, std::string_view version, std::string_view type, uint32_t errorCode) const noexcept;\r\n\r\n        // Logs data about the changes that ocurred in the ARP entries based on an install.\r\n        // First 4 arguments are well known values for the package that we installed.\r\n        // The next 3 are counts of the number of packages in each category.\r\n        // The last 4 are the fields directly from the ARP entry that has been determined to be related to the package that\r\n        // was installed, or they will be empty if there is no data or ambiguity about which entry should be logged.\r\n        virtual void LogSuccessfulInstallARPChange(\r\n            std::string_view sourceIdentifier,\r\n            std::string_view packageIdentifier,\r\n            std::string_view packageVersion,\r\n            std::string_view packageChannel,\r\n            size_t changesToARP,\r\n            size_t matchesInARP,\r\n            size_t countOfIntersectionOfChangesAndMatches,\r\n            std::string_view arpName,\r\n            std::string_view arpVersion,\r\n            std::string_view arpPublisher,\r\n            std::string_view arpLanguage) const noexcept;\r\n\r\n        void LogNonFatalDOError(std::string_view url, HRESULT hr) const noexcept;\r\n\r\n    protected:\r\n        bool IsTelemetryEnabled() const noexcept;\r\n\r\n        // Initializes flags that determine whether telemetry is enabled.\r\n        void InitializeInternal(const AppInstaller::Settings::UserSettings& userSettings);\r\n\r\n        // Used to anonymize a string to the best of our ability.\r\n        // Should primarily be used on failure messages or paths if needed.\r\n        std::wstring AnonymizeString(const wchar_t* input) const noexcept;\r\n        std::wstring AnonymizeString(std::wstring_view input) const noexcept;\r\n\r\n        // Flags used to determine whether to send telemetry. All of them are set during initialization and\r\n        // are CopyConstructibleAtomic to minimize the impact of multiple simultaneous initialization attempts.\r\n        // m_isSettingEnabled starts as false so we can don't send telemetry until we have read the\r\n        // settings and confirmed that it is enabled.\r\n        CopyConstructibleAtomic<bool> m_isSettingEnabled{ false };\r\n\r\n        // We may decide to disable telemetry at runtime, for example, for command line completion.\r\n        CopyConstructibleAtomic<bool> m_isRuntimeEnabled{ true };\r\n\r\n        // We wait for initialization of the other flags before sending any events.\r\n        CopyConstructibleAtomic<bool> m_isInitialized{ false };\r\n\r\n        CopyConstructibleAtomic<uint32_t> m_executionStage{ 0 };\r\n\r\n        GUID m_activityId = GUID_NULL;\r\n        GUID m_parentActivityId = GUID_NULL;\r\n        std::wstring m_telemetryCorrelationJsonW = L\"{}\";\r\n        std::string m_caller;\r\n\r\n        bool m_useSummary = true;\r\n        mutable TelemetrySummary m_summary;\r\n\r\n        // TODO: This and all related code could be removed after transition to summary event in back end.\r\n        uint32_t m_subExecutionId;\r\n    };\r\n\r\n    // Helper to make the call sites look clean.\r\n    TelemetryTraceLogger& Telemetry();\r\n\r\n    // Turns on wil failure telemetry and logging.\r\n    void EnableWilFailureTelemetry();\r\n\r\n    // TODO: Temporary code to keep existing telemetry behavior for command execution cases.\r\n    void UseGlobalTelemetryLoggerActivityIdOnly();\r\n\r\n    // An RAII object to disable telemetry during its lifetime.\r\n    // Primarily used by the complete command to prevent messy input from spamming us.\r\n    struct DisableTelemetryScope\r\n    {\r\n        DisableTelemetryScope();\r\n\r\n        DisableTelemetryScope(const DisableTelemetryScope&) = delete;\r\n        DisableTelemetryScope& operator=(const DisableTelemetryScope&) = delete;\r\n\r\n        DisableTelemetryScope(DisableTelemetryScope&&) = default;\r\n        DisableTelemetryScope& operator=(DisableTelemetryScope&&) = default;\r\n\r\n        ~DisableTelemetryScope();\r\n\r\n    private:\r\n        DestructionToken m_token;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/AdminSettings.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n\r\n#include <string>\r\n#include \"winget/GroupPolicy.h\"\r\n\r\nnamespace AppInstaller::Settings\r\n{\r\n    // Enum of admin settings.\r\n    enum class BoolAdminSetting : size_t\r\n    {\r\n        Unknown = 0,\r\n        LocalManifestFiles,\r\n        BypassCertificatePinningForMicrosoftStore,\r\n        InstallerHashOverride,\r\n        LocalArchiveMalwareScanOverride,\r\n        ProxyCommandLineOptions,\r\n        Max,\r\n    };\r\n\r\n    enum class StringAdminSetting : size_t\r\n    {\r\n        Unknown = 0,\r\n        DefaultProxy,\r\n        Max,\r\n    };\r\n\r\n    BoolAdminSetting StringToBoolAdminSetting(std::string_view in);\r\n    StringAdminSetting StringToStringAdminSetting(std::string_view in);\r\n\r\n    Utility::LocIndView AdminSettingToString(BoolAdminSetting setting);\r\n    Utility::LocIndView AdminSettingToString(StringAdminSetting setting);\r\n\r\n    // Returns true if the value is set.\r\n    // Group policy overriding the setting can prevent the value from being set\r\n    bool EnableAdminSetting(BoolAdminSetting setting);\r\n    bool DisableAdminSetting(BoolAdminSetting setting);\r\n    bool SetAdminSetting(StringAdminSetting setting, std::string_view value);\r\n    bool ResetAdminSetting(StringAdminSetting setting);\r\n    void ResetAllAdminSettings();\r\n\r\n    bool IsAdminSettingEnabled(BoolAdminSetting setting);\r\n    std::optional<std::string> GetAdminSetting(StringAdminSetting setting);\r\n\r\n    std::vector<BoolAdminSetting> GetAllBoolAdminSettings();\r\n    std::vector<StringAdminSetting> GetAllStringAdminSettings();\r\n\r\n    TogglePolicy::Policy GetAdminSettingPolicy(BoolAdminSetting setting);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/Archive.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <filesystem>\r\n\r\nnamespace AppInstaller::Archive\r\n{\r\n    enum class ExtractionMethod\r\n    {\r\n        // Default archive extraction method is ShellApi.\r\n        ShellApi,\r\n        Tar,\r\n    };\r\n\r\n    HRESULT TryExtractArchive(const std::filesystem::path& archivePath, const std::filesystem::path& destPath);\r\n\r\n    bool ScanZipFile(const std::filesystem::path& zipPath);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/Authentication.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <string>\r\n#include <string_view>\r\n#include <optional>\r\n#include \"AppInstallerErrors.h\"\r\n\r\nnamespace AppInstaller::Authentication\r\n{\r\n    // The authentication type supported\r\n    enum class AuthenticationType\r\n    {\r\n        Unknown,\r\n        None,\r\n        MicrosoftEntraId,\r\n        MicrosoftEntraIdForAzureBlobStorage,\r\n    };\r\n\r\n    std::string_view AuthenticationTypeToString(AuthenticationType in);\r\n    AuthenticationType ConvertToAuthenticationType(std::string_view in);\r\n\r\n    // The authentication modes\r\n    enum class AuthenticationMode\r\n    {\r\n        Unknown,\r\n\r\n        // Always do interactive authentication on first request, following requests may use cached result.\r\n        Interactive,\r\n\r\n        // Try silent flow first. If failed, use interactive flow.\r\n        SilentPreferred,\r\n\r\n        // Only do silent flow. If failed, the authentication failed.\r\n        Silent,\r\n    };\r\n\r\n    std::string_view AuthenticationModeToString(AuthenticationMode in);\r\n    AuthenticationMode ConvertToAuthenticationMode(std::string_view in);\r\n\r\n    // Authentication info for Microsoft Entra Id authentication;\r\n    struct MicrosoftEntraIdAuthenticationInfo\r\n    {\r\n        // Resource is required\r\n        std::string Resource;\r\n\r\n        // Scope is optional\r\n        std::string Scope;\r\n\r\n        bool operator<(const MicrosoftEntraIdAuthenticationInfo& other) const;\r\n    };\r\n\r\n    // Authentication info struct used to initialize Authenticator, this is from source information.\r\n    struct AuthenticationInfo\r\n    {\r\n        AuthenticationType Type = AuthenticationType::None;\r\n        std::optional<MicrosoftEntraIdAuthenticationInfo> MicrosoftEntraIdInfo;\r\n\r\n        bool operator<(const AuthenticationInfo& other) const;\r\n\r\n        // Update default values for missing required fields for known authentication type.\r\n        void UpdateRequiredFieldsIfNecessary();\r\n\r\n        // Validates data integrity against known authentication type.\r\n        bool ValidateIntegrity() const;\r\n    };\r\n\r\n    // Authentication arguments struct used to initialize Authenticator, this is from user input.\r\n    struct AuthenticationArguments\r\n    {\r\n        AuthenticationMode Mode = AuthenticationMode::Unknown;\r\n\r\n        // Optional. If set, the value will be used to acquire the specific account and also be validated with authentication result.\r\n        std::string AuthenticationAccount;\r\n    };\r\n\r\n    // The authentication result\r\n    struct AuthenticationResult\r\n    {\r\n        // Default to failed. S_OK on authentication success.\r\n        HRESULT Status = APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED;\r\n\r\n        // The token result on authentication success.\r\n        std::string Token;\r\n    };\r\n\r\n    // Individual authentication provider interface. Authenticator will delegate authentication to authentication provider.\r\n    struct IAuthenticationProvider\r\n    {\r\n        virtual ~IAuthenticationProvider() = default;\r\n\r\n        // Authenticate and return string result.\r\n        virtual AuthenticationResult AuthenticateForToken() = 0;\r\n    };\r\n\r\n    // The public facing authenticator\r\n    struct Authenticator\r\n    {\r\n        Authenticator(AuthenticationInfo info, AuthenticationArguments args);\r\n\r\n        // Authenticate and return string result.\r\n        AuthenticationResult AuthenticateForToken();\r\n\r\n    private:\r\n        std::unique_ptr<IAuthenticationProvider> m_authProvider;\r\n    };\r\n\r\n    // This is the class for authentication window parent window.\r\n    // When authenticating interactively, some api needs handle to a parent window.\r\n    // This class will initiate a new thread and create a hidden window but with foreground priority (best effort).\r\n    // This class handles terminating the window thread on destruction\r\n    struct AuthenticationWindowBase\r\n    {\r\n        // The constructor will initiate the authentication parent window and thread\r\n        AuthenticationWindowBase();\r\n\r\n        AuthenticationWindowBase(const AuthenticationWindowBase&) = delete;\r\n        AuthenticationWindowBase& operator=(const AuthenticationWindowBase&) = delete;\r\n\r\n        AuthenticationWindowBase(AuthenticationWindowBase&&) = delete;\r\n        AuthenticationWindowBase& operator=(AuthenticationWindowBase&&) = delete;\r\n\r\n        // Get the native window handle\r\n        HWND GetHandle();\r\n\r\n        // The destructor will terminate the authentication parent window and thread\r\n        ~AuthenticationWindowBase();\r\n\r\n    private:\r\n        HWND m_windowHandle;\r\n        DWORD m_windowThreadId;\r\n        std::thread m_windowThread;\r\n        // In case PostThreadMessage() fails, let window thread exit immediately.\r\n        std::atomic<bool> m_terminateWindowThread = false;\r\n\r\n        void InitializeWindowThread();\r\n        static LRESULT WINAPI WindowProcessFunction(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);\r\n    };\r\n\r\n    // Create bearer token from a raw token\r\n    std::string CreateBearerToken(std::string rawToken);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/Debugging.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <filesystem>\r\n\r\nnamespace AppInstaller::Debugging\r\n{\r\n    // Enables a self initiated minidump on certain process level failures.\r\n    // Only the first call to EnableSelfInitiatedMinidump has any effect.\r\n    void EnableSelfInitiatedMinidump();\r\n\r\n    // Enables a self initiated minidump on certain process level failures.\r\n    // Creates the minidump in the given location.\r\n    // Only the first call to EnableSelfInitiatedMinidump has any effect.\r\n    void EnableSelfInitiatedMinidump(const std::filesystem::path& filePath);\r\n\r\n    // Forces the minidump to be written.\r\n    void WriteMinidump();\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/DependenciesGraph.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"winget/ManifestCommon.h\"\n\nnamespace AppInstaller::Manifest \n{\n    struct DependencyGraph\n    {\n        // this constructor was intended for use during installation flow (we already have installer dependencies and there's no need to search the source again)\n        DependencyGraph(const Dependency& root, const DependencyList& rootDependencies,\n            std::function<const DependencyList(const Dependency&)> infoFunction);\n\n        DependencyGraph(const Dependency& root, std::function<const DependencyList(const Dependency&)> infoFunction);\n\n        void BuildGraph();\n\n        void AddNode(const Dependency& node);\n\n        void AddAdjacent(const Dependency& node, const Dependency& adjacent);\n\n        bool HasNode(const Dependency& dependency);\n\n        bool HasLoop();\n\n        void CheckForLoopsAndGetOrder();\n\n        std::vector<Dependency> GetInstallationOrder();\n\n    private:\n        // TODO make this function iterative\n        bool HasLoopDFS(std::set<Dependency> visited, const Dependency& node);\n\n        const Dependency& m_root;\n        std::map<Dependency, std::set<Dependency>> m_adjacents;\n        std::function<const DependencyList(const Dependency&)> getDependencies;\n        bool m_HasLoop = false;\n        bool m_rootDependencyEvaluated = false;\n        std::vector<Dependency> m_installationOrder;\n        std::vector<Dependency> m_toCheck;\n    };\n}\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/ExperimentalFeature.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include <vector>\n#include <string>\n#include <type_traits>\n#include \"AppInstallerStrings.h\"\n\nnamespace AppInstaller::Settings\n{\n    using namespace std::string_view_literals;\n    struct UserSettings;\n\n    struct ExperimentalFeature\n    {\n        // To add an experimental feature\n        // 1 - add a flag in this enum, before Max\n        // 2 - add a setting in Setting enum in UserSettings.h\n        // 3 - follow how to add setting instructions\n        // 4 - provide implementation in ExperimentalFeature.cpp\n        enum class Feature : unsigned\n        {\n            None = 0x0,\n            // Before making DirectMSI non-experimental, it should be part of manifest validation.\n            DirectMSI = 0x1,\n            Resume = 0x2,\n            Font = 0x4,\n            SourcePriority = 0x8,\n            Max, // This MUST always be after all experimental features\n\n            // Features listed after Max will not be shown with the features command\n            // This can be used to hide highly experimental features (or these example ones)\n            ExperimentalCmd = 0x10000,\n            ExperimentalArg = 0x20000,\n        };\n\n        using Feature_t = std::underlying_type_t<ExperimentalFeature::Feature>;\n\n        ExperimentalFeature(std::string_view name, std::string_view jsonName, std::string_view link, Feature feature) :\n            m_name(name), m_jsonName(jsonName), m_link(link), m_feature(feature) {}\n\n        ~ExperimentalFeature() = default;\n\n        ExperimentalFeature(const ExperimentalFeature&) = default;\n        ExperimentalFeature& operator=(const ExperimentalFeature&) = default;\n\n        ExperimentalFeature(ExperimentalFeature&&) = default;\n        ExperimentalFeature& operator=(ExperimentalFeature&&) = default;\n\n        static bool IsEnabled(Feature feature);\n\n#ifndef AICLI_DISABLE_TEST_HOOKS\n        static bool IsEnabled(Feature feature, const UserSettings& userSettings);\n#endif\n\n        static ExperimentalFeature GetFeature(ExperimentalFeature::Feature feature);\n        static std::vector<ExperimentalFeature> GetAllFeatures();\n\n        std::string_view Name() const { return m_name; }\n        Utility::LocIndView JsonName() const { return m_jsonName; }\n        std::string_view Link() const { return m_link; }\n        Feature GetFeature() const { return m_feature; }\n\n    private:\n        std::string_view m_name;\n        Utility::LocIndView m_jsonName;\n        std::string_view m_link;\n        Feature m_feature;\n    };\n\n    inline ExperimentalFeature::Feature operator|(ExperimentalFeature::Feature lhs, ExperimentalFeature::Feature rhs)\n    {\n        return static_cast<ExperimentalFeature::Feature> (\n            static_cast<ExperimentalFeature::Feature_t>(lhs) |\n            static_cast<ExperimentalFeature::Feature_t>(rhs));\n    }\n\n    inline ExperimentalFeature::Feature& operator|=(ExperimentalFeature::Feature& lhs, ExperimentalFeature::Feature rhs)\n    {\n        lhs = lhs | rhs;\n        return lhs;\n    }\n\n    inline ExperimentalFeature::Feature operator&(ExperimentalFeature::Feature lhs, ExperimentalFeature::Feature rhs)\n    {\n        return static_cast<ExperimentalFeature::Feature>(\n            static_cast<ExperimentalFeature::Feature_t>(lhs) &\n            static_cast<ExperimentalFeature::Feature_t>(rhs));\n    }\n\n    inline ExperimentalFeature::Feature& operator&=(ExperimentalFeature::Feature& lhs, ExperimentalFeature::Feature rhs)\n    {\n        lhs = lhs & rhs;\n        return lhs;\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/ExtensionCatalog.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerProgress.h>\r\n\r\n#include <winrt/Windows.ApplicationModel.h>\r\n#include <winrt/Windows.ApplicationModel.AppExtensions.h>\r\n\r\n#include <filesystem>\r\n#include <string_view>\r\n#include <optional>\r\n\r\nnamespace AppInstaller::Deployment\r\n{\r\n    using namespace std::string_view_literals;\r\n    constexpr std::wstring_view SourceExtensionName = L\"com.microsoft.winget.source\"sv;\r\n\r\n    constexpr std::wstring_view IndexDBId = L\"IndexDB\"sv;\r\n\r\n    // Wraps an AppExtension.\r\n    struct Extension\r\n    {\r\n        Extension(winrt::Windows::ApplicationModel::AppExtensions::AppExtension extension);\r\n\r\n        // Gets the location of the package root.\r\n        std::filesystem::path GetPackagePath() const;\r\n\r\n        // Gets the location of the directory shared by the extension.\r\n        std::filesystem::path GetPublicFolderPath() const;\r\n\r\n        // Get the version of the package.\r\n        winrt::Windows::ApplicationModel::PackageVersion GetPackageVersion() const;\r\n\r\n        // Verifies the integrity of the extension.\r\n        bool VerifyContentIntegrity(IProgressCallback& progress);\r\n\r\n    private:\r\n        winrt::Windows::ApplicationModel::AppExtensions::AppExtension m_extension;\r\n    };\r\n\r\n    // Wraps an AppExtensionCatalog.\r\n    struct ExtensionCatalog\r\n    {\r\n        ExtensionCatalog(std::wstring_view extensionName);\r\n\r\n        // Finds an extension by its package family name and id.\r\n        std::optional<Extension> FindByPackageFamilyAndId(std::string_view packageFamilyName, std::wstring_view id) const;\r\n\r\n    private:\r\n        winrt::Windows::ApplicationModel::AppExtensions::AppExtensionCatalog m_catalog = nullptr;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/FileCache.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerRuntime.h>\r\n#include <AppInstallerSHA256.h>\r\n#include <filesystem>\r\n#include <istream>\r\n#include <sstream>\r\n\r\nnamespace AppInstaller::Caching\r\n{\r\n    // A file cache for relatively small files (they are always full loaded into memory due to the hash enforcement).\r\n    struct FileCache\r\n    {\r\n        // The supported file cache types.\r\n        enum class Type\r\n        {\r\n            // Manifests for index V1.\r\n            IndexV1_Manifest,\r\n            // Package version data files for index V2.\r\n            IndexV2_PackageVersionData,\r\n            // Manifests for index V2.\r\n            IndexV2_Manifest,\r\n            // Icon for use during show command when sixel rendering is enabled.\r\n            Icon,\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n            // The test type.\r\n            Tests,\r\n#endif\r\n        };\r\n\r\n        // Contains information about a specific file cache instance.\r\n        struct Details\r\n        {\r\n            Details(Type type, std::string identifier);\r\n\r\n            Runtime::PathName BasePath;\r\n            Type Type;\r\n            std::string Identifier;\r\n\r\n            // Gets the full path to the cache directory.\r\n            std::filesystem::path GetCachePath() const;\r\n        };\r\n\r\n        // Construct a file cache for the given instance.\r\n        FileCache(Type type, std::string identifier, std::vector<std::string> sources);\r\n\r\n        // Gets the details for this file cache.\r\n        const Details& GetDetails() const;\r\n\r\n        // Gets a stream containing the contents of the requested file.\r\n        // The hash must match for this function to return successfully.\r\n        std::unique_ptr<std::istream> GetFile(const std::filesystem::path& relativePath, const Utility::SHA256::HashBuffer& expectedHash) const;\r\n\r\n    private:\r\n        // Gets a stream containing the contents of the requested file from an upstream source.\r\n        // The hash must match for this function to return successfully.\r\n        std::unique_ptr<std::stringstream> GetUpstreamFile(std::string relativePath, const Utility::SHA256::HashBuffer& expectedHash) const;\r\n\r\n        Details m_details;\r\n        std::vector<std::string> m_sources;\r\n        std::filesystem::path m_cacheBase;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/FolderFileWatcher.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <unordered_set>\r\n#pragma warning( push )\r\n#pragma warning ( disable : 6387 28196 )\r\n#include <wil/filesystem.h>\r\n#pragma warning( pop )\r\n\r\nnamespace AppInstaller::Utility\r\n{\r\n    // Watch for new/renamed files recursively in a given directory with an optional extension.\r\n    struct FolderFileWatcher\r\n    {\r\n        FolderFileWatcher(const std::filesystem::path& path, const std::optional<std::string>& ext = std::nullopt);\r\n        ~FolderFileWatcher() {};\r\n\r\n        FolderFileWatcher(const FolderFileWatcher&) = delete;\r\n        FolderFileWatcher& operator=(const FolderFileWatcher&) = delete;\r\n\r\n        FolderFileWatcher(FolderFileWatcher&&) = default;\r\n        FolderFileWatcher& operator=(FolderFileWatcher&&) = default;\r\n\r\n        void Start();\r\n        void Stop();\r\n\r\n        const std::unordered_set<std::filesystem::path>& Files() { return m_files; }\r\n        const std::filesystem::path& FolderPath() { return m_path; }\r\n\r\n    private:\r\n        std::filesystem::path m_path;\r\n        std::optional<std::string> m_ext;\r\n        std::unordered_set<std::filesystem::path> m_files;\r\n        wil::unique_folder_change_reader m_changeReader;\r\n    };\r\n}"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/Fonts.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include <AppInstallerVersions.h>\n#include <dwrite_3.h>\n#include <wil/com.h>\n#include <wil/registry.h>\n#include <winget/Manifest.h>\n#include <winget/ManifestCommon.h>\n\nnamespace AppInstaller::Fonts\n{\n    enum class InstallerSource\n    {\n        // Installer source is not guaranteed to be absolutely correct, as it is just\n        // filesystem and registry. We make assumptions based on the structure of how\n        // the font is installed to make a best-effort determination.\n        Unknown,    // Can be any external font installer\n        WinGet,     // Font installed by WinGet\n    };\n\n    enum class FontStatus\n    {\n        // The current status of a particular font file / package.\n        Unknown,\n        Absent,     // Font is not present at all.\n        OK,         // Font is present and in a good state.\n        Corrupt,    // Font is partially installed (has a file, but no registry, or vice-versa)\n    };\n\n    enum class FontResult\n    {\n        Unknown,\n        Success,\n        Error,\n    };\n\n    struct FontFace\n    {\n        std::wstring Name;\n        std::vector<std::filesystem::path> FilePaths;\n        Utility::OpenTypeFontVersion Version;\n    };\n\n    struct FontFamily\n    {\n        std::wstring Name;\n        std::vector<FontFace> Faces;\n    };\n\n    // Represents information about a font file used for its installation, query, and removal.\n    struct FontFileInfo\n    {\n        std::filesystem::path FilePath;         // Where the file currently is\n        std::filesystem::path InstallPath;      // Where the file should be if installed.\n        std::wstring Title;\n        Manifest::ScopeEnum Scope = Manifest::ScopeEnum::Unknown;\n        DWRITE_FONT_FILE_TYPE FileType = DWRITE_FONT_FILE_TYPE_UNKNOWN;\n        InstallerSource InstallerSource = InstallerSource::Unknown;\n        FontStatus Status = FontStatus::Unknown;\n        bool WinGetSupported = false;\n        bool IsFontFileInstalled = false;\n        bool IsFontFileRegistered = false;\n        std::wstring PackageId;\n        std::wstring PackageVersion;\n\n        // Fonts that are not winget-packaged will use this for an identifier.\n        std::wstring PackageIdentifier;\n\n        // Registry Install path is where the installation with the system is located.\n        std::wstring RegistryInstallPath;\n\n        // Registry Source path is where package mapping of the package is.\n        std::wstring RegistryPackagePath;\n    };\n\n    // Represents information about a WinGet-installed font package.\n    struct FontPackageInfo\n    {\n        Manifest::ScopeEnum Scope = Manifest::ScopeEnum::Unknown;\n        FontStatus Status = FontStatus::Unknown;\n        std::wstring PackageId;\n        std::wstring PackageVersion;\n        std::wstring PackageIdentifier;\n    };\n\n    struct FontContext\n    {\n        InstallerSource InstallerSource = InstallerSource::Unknown;\n        Manifest::ScopeEnum Scope = Manifest::ScopeEnum::Unknown;\n        std::vector<std::filesystem::path> PackageFiles = std::vector<std::filesystem::path>();\n        std::wstring PackageId;\n        std::wstring PackageVersion;\n        bool Force = false;\n\n        void AddPackageFile(const std::filesystem::path& filePath);\n        Manifest::AppsAndFeaturesEntry GetAppsAndFeaturesEntry() const;\n        std::wstring GetPackageIdentifier() const;\n    };\n\n    struct FontValidationResult\n    {\n        FontResult Result = FontResult::Unknown;\n        FontStatus Status = FontStatus::Unknown;\n        bool HasUnsupportedFonts = false;\n        winrt::hresult HResult = winrt::hresult(S_OK);\n        std::vector<FontFileInfo> FontFileInfos = std::vector<FontFileInfo>();\n    };\n\n    struct FontOperationResult\n    {\n        winrt::hresult HResult = winrt::hresult(S_OK);\n        FontResult Result() const;\n\n        // TODO: Add optional rollback context to unwind installs if one operation succeeded but a subsequent one failed.\n    };\n\n    std::vector<FontFileInfo> GetInstalledFontFiles();\n\n    std::vector<FontPackageInfo> GetInstalledFontPackages(Manifest::ScopeEnum scope);\n\n    FontFileInfo CreateFontFileInfo(const FontContext& context, const std::filesystem::path& filePath, const std::wstring& title = std::wstring());\n\n    FontValidationResult ValidateFontPackage(FontContext& context);\n\n    FontOperationResult InstallFontPackage(FontContext& context);\n\n    FontOperationResult UninstallFontPackage(FontContext& context);\n\n    std::wstring GetFontRegistryRoot();\n\n    struct FontCatalog\n    {\n        FontCatalog();\n\n        // Gets all installed font families on the system. If an exact family name is provided and found, returns the installed font family.\n        std::vector<FontFamily> GetInstalledFontFamilies(std::optional<std::wstring> familyName = {});\n\n        // Returns a boolean value indicating whether the specified file path is a valid font file.\n        bool IsFontFileSupported(const std::filesystem::path& filePath, DWRITE_FONT_FILE_TYPE& fileType);\n\n        std::filesystem::path GetRootFontPath(Manifest::ScopeEnum scope);\n\n    private:\n        FontFamily GetFontFamilyByIndex(const wil::com_ptr<IDWriteFontCollection>& collection, UINT32 index);\n        std::wstring GetLocalizedStringFromFont(const wil::com_ptr<IDWriteLocalizedStrings>& localizedStringCollection);\n        std::wstring GetFontFamilyName(const wil::com_ptr<IDWriteFontFamily>& fontFamily);\n        std::wstring GetFontFaceName(const wil::com_ptr<IDWriteFont>& font);\n        Utility::OpenTypeFontVersion GetFontFaceVersion(const wil::com_ptr<IDWriteFont>& font);\n\n        wil::com_ptr<IDWriteFactory7> m_factory;\n        std::vector<std::wstring> m_preferredLocales;\n    };\n}\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/HttpClientHelper.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/Certificates.h>\r\n#include <winget/SharedThreadGlobals.h>\r\n#include <cpprest/http_client.h>\r\n#include <cpprest/json.h>\r\n#include <memory>\r\n#include <optional>\r\n#include <vector>\r\n\r\nnamespace AppInstaller::Http\r\n{\r\n    struct HttpClientHelper\r\n    {\r\n        using HttpRequestHeaders = std::unordered_map<utility::string_t, utility::string_t>;\r\n\r\n        struct HttpResponseHandlerResult\r\n        {\r\n            // The custom response handler result. Default is empty.\r\n            std::optional<web::json::value> Result = std::nullopt;\r\n\r\n            // Indicates whether to use default handling logic by HttpClientHelper instead (i.e. the custom response handler does not handle the specific response).\r\n            bool UseDefaultHandling = false;\r\n        };\r\n\r\n        using HttpResponseHandler = std::function<HttpResponseHandlerResult(const web::http::http_response&)>;\r\n\r\n        HttpClientHelper(std::shared_ptr<web::http::http_pipeline_stage> = {});\r\n\r\n        pplx::task<web::http::http_response> Post(const utility::string_t& uri, const web::json::value& body, const HttpRequestHeaders& headers = {}, const HttpRequestHeaders& authHeaders = {}) const;\r\n\r\n        std::optional<web::json::value> HandlePost(const utility::string_t& uri, const web::json::value& body, const HttpRequestHeaders& headers = {}, const HttpRequestHeaders& authHeaders = {}, const HttpResponseHandler& customHandler = {}) const;\r\n\r\n        pplx::task<web::http::http_response> Get(const utility::string_t& uri, const HttpRequestHeaders& headers = {}, const HttpRequestHeaders& authHeaders = {}) const;\r\n\r\n        std::optional<web::json::value> HandleGet(const utility::string_t& uri, const HttpRequestHeaders& headers = {}, const HttpRequestHeaders& authHeaders = {}, const HttpResponseHandler& customHandler = {}) const;\r\n\r\n        void SetPinningConfiguration(const Certificates::PinningConfiguration& configuration, std::shared_ptr<ThreadLocalStorage::ThreadGlobals> threadGlobals = {});\r\n\r\n    protected:\r\n        std::optional<web::json::value> ValidateAndExtractResponse(const web::http::http_response& response) const;\r\n\r\n        std::optional<web::json::value> ExtractJsonResponse(const web::http::http_response& response) const;\r\n\r\n    private:\r\n        web::http::client::http_client GetClient(const utility::string_t& uri) const;\r\n\r\n        // Translates a cpprestsdk http_exception to a WIL exception.\r\n        static void RethrowAsWilException(const web::http::http_exception& exception);\r\n\r\n        std::shared_ptr<web::http::http_pipeline_stage> m_defaultRequestHandlerStage;\r\n        web::http::client::http_client_config m_clientConfig;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/Locale.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <string>\r\n#include <vector>\r\n\r\nnamespace AppInstaller::Locale\r\n{\r\n    static constexpr double MinimumDistanceScoreAsPerfectMatch = 1.0;\r\n    static constexpr double MinimumDistanceScoreAsCompatibleMatch = 0.9;\r\n    static constexpr double UnknownLanguageDistanceScore = 0.0;\r\n\r\n    // Check if a bcp47 language tag is well formed\r\n    bool IsWellFormedBcp47Tag(std::string_view bcp47Tag);\r\n\r\n    // Get a score of language distance between target and available. The return value range is 0 to 1.\r\n    // With 1 meaning perfect match and 0 meaning no match.\r\n    double GetDistanceOfLanguage(std::string_view target, std::string_view available);\r\n\r\n    // Get the list of user Preferred Languages from settings. Returns an empty vector in rare cases of failure.\r\n    std::vector<std::string> GetUserPreferredLanguages();\r\n\r\n    // Get the list of user Preferred Languages from settings. Returns an empty vector in rare cases of failure.\r\n    std::vector<std::wstring> GetUserPreferredLanguagesUTF16();\r\n\r\n    // Get the bcp47 tag from a locale id. Returns empty string if conversion cannot be performed.\r\n    std::string LocaleIdToBcp47Tag(LCID localeId);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/MSStore.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Manifest.h\"\r\n#include <AppInstallerProgress.h>\r\n\r\n#include <winrt/Windows.Foundation.Collections.h>\r\n#include <winrt/Windows.ApplicationModel.Store.Preview.InstallControl.h>\r\n\r\n#include <string>\r\n\r\nnamespace AppInstaller::MSStore\r\n{\r\n    using namespace std::string_view_literals;\r\n    static constexpr std::wstring_view s_AppInstallerProductId = L\"9NBLGGH4NNS1\"sv;\r\n\r\n    enum class MSStoreOperationType\r\n    {\r\n        Install,\r\n        Update,\r\n        Repair,\r\n    };\r\n\r\n    struct MSStoreOperation\r\n    {\r\n        MSStoreOperation(MSStoreOperationType type, const std::wstring& productId, Manifest::ScopeEnum scope, bool isSilentMode, bool force) :\r\n            m_type(type), m_productId(productId), m_scope(scope), m_isSilentMode(isSilentMode), m_force(force)\r\n        {\r\n        }\r\n\r\n        MSStoreOperation(const MSStoreOperation&) = delete;\r\n        MSStoreOperation& operator=(const MSStoreOperation&) = delete;\r\n\r\n        MSStoreOperation(MSStoreOperation&&) = delete;\r\n        MSStoreOperation& operator=(MSStoreOperation&&) = delete;\r\n\r\n        HRESULT StartAndWaitForOperation(IProgressCallback& progress);\r\n\r\n    private:\r\n        HRESULT InstallPackage(IProgressCallback& progress);\r\n        HRESULT UpdatePackage(IProgressCallback& progress);\r\n\r\n        MSStoreOperationType m_type;\r\n        std::wstring m_productId;\r\n        Manifest::ScopeEnum m_scope;\r\n        bool m_isSilentMode;\r\n        bool m_force;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/MSStoreDownload.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerArchitecture.h>\r\n#include <AppInstallerSHA256.h>\r\n#include <AppInstallerVersions.h>\r\n#include \"winget/Authentication.h\"\r\n#include \"winget/ManifestCommon.h\"\r\n\r\n#include <string>\r\n#include <optional>\r\n#include <string_view>\r\n#include <memory>\r\n#include <vector>\r\n\r\nnamespace AppInstaller::MSStore\r\n{\r\n    // Struct representing 1 MSStore package file download info\r\n    struct MSStoreDownloadFile\r\n    {\r\n        std::string Url;\r\n        AppInstaller::Utility::SHA256::HashBuffer Sha256;\r\n        std::string FileName;\r\n        AppInstaller::Utility::UInt64Version Version = 0;\r\n    };\r\n\r\n    struct MSStoreDownloadInfo\r\n    {\r\n        std::vector<MSStoreDownloadFile> MainPackages;\r\n        std::vector<MSStoreDownloadFile> DependencyPackages;\r\n\r\n        std::string ContentId;\r\n    };\r\n\r\n    struct MSStoreDownloadContext\r\n    {\r\n        MSStoreDownloadContext(\r\n            std::string productId,\r\n            AppInstaller::Utility::Architecture architecture,\r\n            AppInstaller::Manifest::PlatformEnum platform,\r\n            std::string locale,\r\n            AppInstaller::Authentication::AuthenticationArguments authArgs);\r\n\r\n        void TargetOSVersion(std::optional<Utility::UInt64Version> targetOSVersion);\r\n\r\n        // Calls display catalog API and sfs-client to get download info.\r\n        MSStoreDownloadInfo GetDownloadInfo();\r\n\r\n        // Gets license for the corresponding packages\r\n        std::vector<BYTE> GetLicense(std::string_view contentId);\r\n\r\n    private:\r\n        std::string m_productId;\r\n        AppInstaller::Utility::Architecture m_architecture = AppInstaller::Utility::Architecture::Unknown;\r\n        AppInstaller::Manifest::PlatformEnum m_platform = AppInstaller::Manifest::PlatformEnum::Unknown;\r\n        std::optional<Utility::UInt64Version> m_targetOSVersion = std::nullopt;\r\n        std::string m_locale;\r\n        std::unique_ptr<AppInstaller::Authentication::Authenticator> m_displayCatalogAuthenticator;\r\n        std::unique_ptr<AppInstaller::Authentication::Authenticator> m_licensingAuthenticator;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/Manifest.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerStrings.h>\r\n#include <AppInstallerSHA256.h>\r\n#include <AppInstallerVersions.h>\r\n#include <winget/ManifestInstaller.h>\r\n#include <winget/ManifestLocalization.h>\r\n\r\n#include <vector>\r\n\r\nnamespace AppInstaller::Manifest\r\n{\r\n    // Representation of the parsed manifest file.\r\n    struct Manifest\r\n    {\r\n        using string_t = Utility::NormalizedString;\r\n\r\n        string_t Id;\r\n\r\n        string_t Version;\r\n\r\n        string_t Channel;\r\n\r\n        string_t Moniker;\r\n\r\n        ManifestVer ManifestVersion;\r\n\r\n        ManifestInstaller DefaultInstallerInfo;\r\n\r\n        std::vector<ManifestInstaller> Installers;\r\n\r\n        ManifestLocalization DefaultLocalization;\r\n\r\n        std::vector<ManifestLocalization> Localizations;\r\n\r\n        ManifestLocalization CurrentLocalization;\r\n\r\n        // ApplyLocale will update the CurrentLocalization according to the specified locale\r\n        // If locale is empty, user setting locale will be used\r\n        void ApplyLocale(const std::string& locale = {});\r\n\r\n        // Get all tags across localizations\r\n        std::vector<string_t> GetAggregatedTags() const;\r\n\r\n        // Get all commands across installers\r\n        std::vector<string_t> GetAggregatedCommands() const;\r\n\r\n        // Gets ARP version range if declared, otherwise an empty range is returned\r\n        Utility::VersionRange GetArpVersionRange() const;\r\n\r\n        // Get package family names across installers, Case folded.\r\n        std::vector<string_t> GetPackageFamilyNames() const;\r\n\r\n        // Get product codes across installers, Case folded.\r\n        std::vector<string_t> GetProductCodes() const;\r\n\r\n        // Get upgrade codes across installers, Case folded.\r\n        std::vector<string_t> GetUpgradeCodes() const;\r\n\r\n        // Get package names across localizations and installers, Case folded.\r\n        std::vector<string_t> GetPackageNames() const;\r\n\r\n        // Get publishers across localizations and installers, Case folded.\r\n        std::vector<string_t> GetPublishers() const;\r\n\r\n        // If not empty, the SHA256 hash of the manifest stream itself.\r\n        Utility::SHA256::HashBuffer StreamSha256;\r\n\r\n    private:\r\n        std::vector<string_t> GetSystemReferenceStrings(\r\n            std::function<const string_t& (const ManifestInstaller&)> extractStringFromInstaller = {},\r\n            std::function<const string_t& (const AppsAndFeaturesEntry&)> extractStringFromAppsAndFeaturesEntry = {}) const;\r\n    };\r\n}"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/ManifestCommon.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerStrings.h>\r\n#include <AppInstallerVersions.h>\r\n#include <functional>\r\n#include <map>\r\n#include <set>\r\n#include <string_view>\r\n#include <vector>\r\n\r\nnamespace AppInstaller::Manifest\r\n{\r\n    // Forward declaration\r\n    struct ManifestInstaller;\r\n\r\n    using string_t = Utility::NormalizedString;\r\n    using namespace std::string_view_literals;\r\n    using Utility::RawVersion;\r\n\r\n    // The maximum supported major version known about by this code.\r\n    constexpr uint64_t s_MaxSupportedMajorVersion = 1;\r\n\r\n    // The default manifest version assigned to manifests without a ManifestVersion field.\r\n    constexpr std::string_view s_DefaultManifestVersion = \"0.1.0\"sv;\r\n\r\n    // V1 manifest version for GA\r\n    constexpr std::string_view s_ManifestVersionV1 = \"1.0.0\"sv;\r\n\r\n    // V1.1 manifest version\r\n    constexpr std::string_view s_ManifestVersionV1_1 = \"1.1.0\"sv;\r\n\r\n    // V1.2 manifest version\r\n    constexpr std::string_view s_ManifestVersionV1_2 = \"1.2.0\"sv;\r\n\r\n    // V1.4 manifest version\r\n    constexpr std::string_view s_ManifestVersionV1_4 = \"1.4.0\"sv;\r\n\r\n    // V1.5 manifest version\r\n    constexpr std::string_view s_ManifestVersionV1_5 = \"1.5.0\"sv;\r\n\r\n    // V1.6 manifest version\r\n    constexpr std::string_view s_ManifestVersionV1_6 = \"1.6.0\"sv;\r\n\r\n    // V1.7 manifest version\r\n    constexpr std::string_view s_ManifestVersionV1_7 = \"1.7.0\"sv;\r\n\r\n    // V1.9 manifest version\r\n    constexpr std::string_view s_ManifestVersionV1_9 = \"1.9.0\"sv;\r\n\r\n    // V1.10 manifest version\r\n    constexpr std::string_view s_ManifestVersionV1_10 = \"1.10.0\"sv;\r\n\r\n    // V1.12 manifest version\r\n    constexpr std::string_view s_ManifestVersionV1_12 = \"1.12.0\"sv;\r\n\r\n    // V1.28 manifest version\r\n    constexpr std::string_view s_ManifestVersionV1_28 = \"1.28.0\"sv;\r\n\r\n    // Any new manifest version must also be added to src\\WinGetUtilInterop\\Manifest\\ManifestVersion.cs.\r\n\r\n    // The manifest extension for the MS Store\r\n    constexpr std::string_view s_MSStoreExtension = \"msstore\"sv;\r\n\r\n    struct ManifestValidateOption\r\n    {\r\n        bool SchemaValidationOnly = false;\r\n        bool ErrorOnVerifiedPublisherFields = false;\r\n        bool InstallerValidation = false;\r\n\r\n        // Options not exposed in winget util\r\n        bool FullValidation = false;\r\n        bool ThrowOnWarning = false;\r\n        bool AllowShadowManifest = false;\r\n        bool SchemaHeaderValidationAsWarning = false;\r\n    };\r\n\r\n    // ManifestVer is inherited from Utility::Version and is a more restricted version.\r\n    // ManifestVer is used to specify the version of app manifest itself.\r\n    // ManifestVer is a 3 part version in the format of [0-65535].[0-65535].[0-65535]\r\n    // and optionally a following tag in the format of -[SomeString] for experimental purpose.\r\n    struct ManifestVer : public Utility::Version\r\n    {\r\n        ManifestVer() = default;\r\n\r\n        ManifestVer(std::string_view version);\r\n\r\n        uint64_t Major() const { return m_parts.size() > 0 ? m_parts[0].Integer : 0; }\r\n        uint64_t Minor() const { return m_parts.size() > 1 ? m_parts[1].Integer : 0; }\r\n        uint64_t Patch() const { return m_parts.size() > 2 ? m_parts[2].Integer : 0; }\r\n\r\n        bool HasExtension() const;\r\n\r\n        bool HasExtension(std::string_view extension) const;\r\n\r\n    private:\r\n        std::vector<RawVersion> m_extensions;\r\n    };\r\n\r\n    enum class InstallerTypeEnum\r\n    {\r\n        Unknown,\r\n        Inno,\r\n        Wix,\r\n        Msi,\r\n        Nullsoft,\r\n        Zip,\r\n        Msix,\r\n        Exe,\r\n        Burn,\r\n        MSStore,\r\n        Portable,\r\n        Font,\r\n    };\r\n\r\n    enum class UpdateBehaviorEnum\r\n    {\r\n        Unknown,\r\n        Install,\r\n        UninstallPrevious,\r\n        Deny,\r\n    };\r\n\r\n    enum class InstallerSwitchType\r\n    {\r\n        Custom,\r\n        Silent,\r\n        SilentWithProgress,\r\n        Interactive,\r\n        Language,\r\n        Log,\r\n        InstallLocation,\r\n        Update,\r\n        Repair,\r\n    };\r\n\r\n    enum class RepairBehaviorEnum\r\n    {\r\n        Unknown,\r\n        Modify,\r\n        Installer,\r\n        Uninstaller,\r\n    };\r\n\r\n    enum class ScopeEnum\r\n    {\r\n        Unknown,\r\n        User,\r\n        Machine,\r\n    };\r\n\r\n    enum class InstallModeEnum\r\n    {\r\n        Unknown,\r\n        Interactive,\r\n        Silent,\r\n        SilentWithProgress,\r\n    };\r\n\r\n    enum class ExpectedReturnCodeEnum\r\n    {\r\n        Unknown,\r\n        PackageInUse,\r\n        PackageInUseByApplication,\r\n        InstallInProgress,\r\n        FileInUse,\r\n        MissingDependency,\r\n        DiskFull,\r\n        InsufficientMemory,\r\n        InvalidParameter,\r\n        NoNetwork,\r\n        ContactSupport,\r\n        RebootRequiredToFinish,\r\n        RebootRequiredForInstall,\r\n        RebootInitiated,\r\n        CancelledByUser,\r\n        AlreadyInstalled,\r\n        Downgrade,\r\n        BlockedByPolicy,\r\n        SystemNotSupported,\r\n        Custom,\r\n    };\r\n\r\n    enum class PlatformEnum\r\n    {\r\n        Unknown,\r\n        Universal,\r\n        Desktop,\r\n        IoT,\r\n        Team,\r\n        Holographic,\r\n    };\r\n\r\n    enum class ElevationRequirementEnum\r\n    {\r\n        Unknown,\r\n        ElevationRequired,\r\n        ElevationProhibited,\r\n        ElevatesSelf,\r\n    };\r\n\r\n    enum class UnsupportedArgumentEnum\r\n    {\r\n        Unknown,\r\n        Log,\r\n        Location\r\n    };\r\n\r\n    enum class InstalledFileTypeEnum\r\n    {\r\n        Unknown,\r\n        Launch,\r\n        Uninstall,\r\n        Other,\r\n    };\r\n\r\n    enum class ManifestTypeEnum\r\n    {\r\n        Singleton,\r\n        Version,\r\n        Installer,\r\n        DefaultLocale,\r\n        Locale,\r\n        Merged,\r\n        Preview,\r\n        Shadow,\r\n    };\r\n\r\n    enum class DependencyType\r\n    {\r\n        WindowsFeature,\r\n        WindowsLibrary,\r\n        Package,\r\n        External\r\n    };\r\n\r\n    enum class IconFileTypeEnum\r\n    {\r\n        Unknown,\r\n        Jpeg,\r\n        Png,\r\n        Ico,\r\n    };\r\n\r\n    enum class IconThemeEnum\r\n    {\r\n        Unknown,\r\n        Default,\r\n        Light,\r\n        Dark,\r\n        HighContrast,\r\n    };\r\n\r\n    // Icon resolutions from https://learn.microsoft.com/en-us/windows/apps/design/style/iconography/app-icon-construction#app-icon\r\n    enum class IconResolutionEnum\r\n    {\r\n        Unknown,\r\n        Custom,\r\n        Square16,\r\n        Square20,\r\n        Square24,\r\n        Square30,\r\n        Square32,\r\n        Square36,\r\n        Square40,\r\n        Square48,\r\n        Square60,\r\n        Square64,\r\n        Square72,\r\n        Square80,\r\n        Square96,\r\n        Square256,\r\n    };\r\n\r\n    struct ExpectedReturnCode\r\n    {\r\n        DWORD InstallerReturnCode = 0;\r\n        ExpectedReturnCodeEnum ReturnResponse = ExpectedReturnCodeEnum::Unknown;\r\n        string_t ReturnResponseUrl;\r\n    };\r\n\r\n    struct Dependency\r\n    {\r\n        DependencyType Type;\r\n        const string_t& Id() const { return m_id; };\r\n        std::optional<Utility::Version> MinVersion;\r\n\r\n        Dependency(DependencyType type, string_t id, string_t minVersion) : Type(type), m_id(std::move(id)), MinVersion(Utility::Version(std::move(minVersion))), m_foldedId(FoldCase(m_id)) {}\r\n        Dependency(DependencyType type, string_t id) : Type(type), m_id(std::move(id)), m_foldedId(FoldCase(m_id)){}\r\n        Dependency(DependencyType type) : Type(type) {}\r\n\r\n        bool operator ==(const Dependency& rhs) const\r\n        {\r\n            return Type == rhs.Type && m_foldedId == rhs.m_foldedId && MinVersion == rhs.MinVersion;\r\n        }\r\n\r\n        bool operator <(const Dependency& rhs) const\r\n        {\r\n            return m_foldedId < rhs.m_foldedId;\r\n        }\r\n\r\n        bool IsVersionOk(const Utility::Version& version)\r\n        {\r\n            return MinVersion <= version;\r\n        }\r\n\r\n        // m_foldedId should be set whenever Id is set\r\n        void SetId(string_t id)\r\n        {\r\n            m_id = std::move(id);\r\n            m_foldedId = FoldCase(m_id);\r\n        }\r\n\r\n    private:\r\n        string_t m_id;\r\n        std::string m_foldedId;\r\n    };\r\n\r\n    struct DependencyList\r\n    {\r\n        void Add(const Dependency& newDependency);\r\n        void Add(const DependencyList& otherDependencyList);\r\n        bool HasAny() const;\r\n        bool HasAnyOf(DependencyType type) const;\r\n        Dependency* HasDependency(const Dependency& dependencyToSearch);\r\n        void ApplyToType(DependencyType type, std::function<void(const Dependency&)> func) const;\r\n        void ApplyToAll(std::function<void(const Dependency&)> func) const;\r\n        bool Empty() const;\r\n        void Clear();\r\n        bool HasExactDependency(DependencyType type, const string_t& id, const string_t& minVersion = \"\") const;\r\n        size_t Size() const;\r\n\r\n    private:\r\n        std::vector<Dependency> m_dependencies;\r\n    };\r\n\r\n    struct AppsAndFeaturesEntry\r\n    {\r\n        string_t DisplayName;\r\n        string_t Publisher;\r\n        string_t DisplayVersion;\r\n        string_t ProductCode;\r\n        string_t UpgradeCode;\r\n        InstallerTypeEnum InstallerType = InstallerTypeEnum::Unknown;\r\n    };\r\n\r\n    struct MarketsInfo\r\n    {\r\n        std::vector<string_t> AllowedMarkets;\r\n        std::vector<string_t> ExcludedMarkets;\r\n    };\r\n\r\n    struct NestedInstallerFile\r\n    {\r\n        string_t RelativeFilePath;\r\n        string_t PortableCommandAlias;\r\n    };\r\n\r\n    struct InstalledFile\r\n    {\r\n        string_t RelativeFilePath;\r\n        std::vector<BYTE> FileSha256;\r\n        InstalledFileTypeEnum FileType = InstalledFileTypeEnum::Other;\r\n        string_t InvocationParameter;\r\n        string_t DisplayName;\r\n    };\r\n\r\n    struct InstallationMetadataInfo\r\n    {\r\n        string_t DefaultInstallLocation;\r\n        std::vector<InstalledFile> Files;\r\n\r\n        // Checks if there are any installation metadata available.\r\n        bool HasData() const { return !DefaultInstallLocation.empty() || !Files.empty(); }\r\n\r\n        void Clear() { DefaultInstallLocation.clear(); Files.clear(); }\r\n    };\r\n\r\n    // Information about a specific DSC resource.\r\n    struct DesiredStateConfigurationResourceInfo\r\n    {\r\n        string_t Name;\r\n    };\r\n\r\n    // The type of resource container.\r\n    enum class DesiredStateConfigurationContainerType\r\n    {\r\n        PowerShell,\r\n        DSCv3,\r\n    };\r\n\r\n    // Information about a DSC container.\r\n    // Contains the union of properties relevant to all container types.\r\n    struct DesiredStateConfigurationContainerInfo\r\n    {\r\n        DesiredStateConfigurationContainerInfo(DesiredStateConfigurationContainerType type) : Type(type) {}\r\n\r\n        DesiredStateConfigurationContainerInfo(const string_t& repositoryUrl, const string_t& moduleName, std::vector<DesiredStateConfigurationResourceInfo> resources) :\r\n            Type(DesiredStateConfigurationContainerType::PowerShell), RepositoryURL(repositoryUrl), ModuleName(moduleName), Resources(std::move(resources)) {}\r\n\r\n        DesiredStateConfigurationContainerInfo(std::vector<DesiredStateConfigurationResourceInfo> resources) :\r\n            Type(DesiredStateConfigurationContainerType::DSCv3), Resources(std::move(resources)) {}\r\n\r\n        DesiredStateConfigurationContainerType Type;\r\n\r\n        // For Type == PowerShell\r\n        string_t RepositoryURL;\r\n        string_t ModuleName;\r\n\r\n        // For all types\r\n        std::vector<DesiredStateConfigurationResourceInfo> Resources;\r\n    };\r\n\r\n    InstallerTypeEnum ConvertToInstallerTypeEnum(const std::string& in);\r\n\r\n    UpdateBehaviorEnum ConvertToUpdateBehaviorEnum(const std::string& in);\r\n\r\n    ScopeEnum ConvertToScopeEnum(std::string_view in);\r\n\r\n    InstallModeEnum ConvertToInstallModeEnum(const std::string& in);\r\n\r\n    PlatformEnum ConvertToPlatformEnum(std::string_view in);\r\n\r\n    PlatformEnum ConvertToPlatformEnumForMSStoreDownload(std::string_view in);\r\n\r\n    ElevationRequirementEnum ConvertToElevationRequirementEnum(const std::string& in);\r\n\r\n    UnsupportedArgumentEnum ConvertToUnsupportedArgumentEnum(const std::string& in);\r\n\r\n    ManifestTypeEnum ConvertToManifestTypeEnum(const std::string& in);\r\n\r\n    ExpectedReturnCodeEnum ConvertToExpectedReturnCodeEnum(const std::string& in);\r\n\r\n    InstalledFileTypeEnum ConvertToInstalledFileTypeEnum(const std::string& in);\r\n\r\n    IconFileTypeEnum ConvertToIconFileTypeEnum(std::string_view in);\r\n\r\n    IconThemeEnum ConvertToIconThemeEnum(std::string_view in);\r\n\r\n    IconResolutionEnum ConvertToIconResolutionEnum(std::string_view in);\r\n\r\n    RepairBehaviorEnum ConvertToRepairBehaviorEnum(std::string_view in);\r\n\r\n    std::string_view InstallerTypeToString(InstallerTypeEnum installerType);\r\n\r\n    std::string_view InstallerSwitchTypeToString(InstallerSwitchType installerSwitchType);\r\n\r\n    std::string_view ElevationRequirementToString(ElevationRequirementEnum elevationRequirement);\r\n\r\n    std::string_view InstallModeToString(InstallModeEnum installMode);\r\n\r\n    std::string_view UnsupportedArgumentToString(UnsupportedArgumentEnum unsupportedArgument);\r\n\r\n    std::string_view UpdateBehaviorToString(UpdateBehaviorEnum updateBehavior);\r\n\r\n    std::string_view RepairBehaviorToString(RepairBehaviorEnum repairBehavior);\r\n\r\n    // Short string representation does not contain \"Windows.\"\r\n    std::string_view PlatformToString(PlatformEnum platform, bool shortString = false);\r\n\r\n    std::string_view ScopeToString(ScopeEnum scope);\r\n\r\n    std::string_view InstalledFileTypeToString(InstalledFileTypeEnum installedFileType);\r\n\r\n    std::string_view IconFileTypeToString(IconFileTypeEnum iconFileType);\r\n\r\n    std::string_view IconThemeToString(IconThemeEnum iconTheme);\r\n\r\n    std::string_view IconResolutionToString(IconResolutionEnum iconResolution);\r\n\r\n    std::string_view ManifestTypeToString(ManifestTypeEnum manifestType);\r\n\r\n    std::string_view ExpectedReturnCodeToString(ExpectedReturnCodeEnum expectedReturnCode);\r\n\r\n    // Gets a value indicating whether the given installer uses the PackageFamilyName system reference.\r\n    bool DoesInstallerTypeUsePackageFamilyName(InstallerTypeEnum installerType);\r\n\r\n    // Gets a value indicating whether any of the ARP entries uses the PackageFamilyName system reference.\r\n    bool DoAnyAppsAndFeaturesEntriesUsePackageFamilyName(const std::vector<AppsAndFeaturesEntry>& entries);\r\n\r\n    // Gets a value indicating whether the given installer uses the ProductCode system reference.\r\n    bool DoesInstallerTypeUseProductCode(InstallerTypeEnum installerType);\r\n\r\n    // Gets a value indicating whether the given installer writes ARP entry.\r\n    bool DoesInstallerTypeWriteAppsAndFeaturesEntry(InstallerTypeEnum installerType);\r\n\r\n    // Gets a value indicating whether the given installer type supports ARP version range.\r\n    bool DoesInstallerTypeSupportArpVersionRange(InstallerTypeEnum installer);\r\n\r\n    // Gets a value indicating whether the given installer ignores the Scope value from the manifest.\r\n    bool DoesInstallerTypeIgnoreScopeFromManifest(InstallerTypeEnum installerType);\r\n\r\n    // Gets a value indicating whether the given installer requires admin for install.\r\n    bool DoesInstallerTypeRequireAdminForMachineScopeInstall(InstallerTypeEnum installerType);\r\n\r\n    // Gets a value indicating whether the given installer requires RepairBehavior for repair.\r\n    bool DoesInstallerTypeRequireRepairBehaviorForRepair(InstallerTypeEnum installerType);\r\n\r\n    // Gets a value indicating whether the given installer type is an archive.\r\n    bool IsArchiveType(InstallerTypeEnum installerType);\r\n\r\n    // Gets a value indicating whether the given installer type is a portable.\r\n    bool IsPortableType(InstallerTypeEnum installerType);\r\n\r\n    // Gets a value indicating whether the given installer type supports multiple nested installers.\r\n    bool DoesInstallerTypeSupportMultipleNestedInstallers(InstallerTypeEnum installerType);\r\n\r\n    // Gets a value indicating whether the given nested installer type is supported.\r\n    bool IsNestedInstallerTypeSupported(InstallerTypeEnum nestedInstallerType);\r\n\r\n    // Checks whether 2 installer types are compatible. E.g. inno and exe are update compatible\r\n    bool IsInstallerTypeCompatible(InstallerTypeEnum type1, InstallerTypeEnum type2);\r\n\r\n    // Get a list of default switches for known installer types\r\n    std::map<InstallerSwitchType, Utility::NormalizedString> GetDefaultKnownSwitches(InstallerTypeEnum installerType);\r\n\r\n    // Get a list of default return codes for known installer types\r\n    std::map<DWORD, ExpectedReturnCodeEnum> GetDefaultKnownReturnCodes(InstallerTypeEnum installerType);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/ManifestComparator.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/Manifest.h>\r\n#include <memory>\r\n#include <optional>\r\n#include <string>\r\n#include <string_view>\r\n#include <utility>\r\n#include <vector>\r\n\r\n\r\nnamespace AppInstaller::Manifest\r\n{\r\n    // Flags to indicate why an installer was not applicable\r\n    enum class InapplicabilityFlags : int\r\n    {\r\n        None = 0x0,\r\n        OSVersion = 0x1,\r\n        InstalledScope = 0x2,\r\n        InstalledType = 0x4,\r\n        InstalledLocale = 0x8,\r\n        Locale = 0x10,\r\n        Scope = 0x20,\r\n        MachineArchitecture = 0x40,\r\n        Market = 0x80,\r\n        InstallerType = 0x100,\r\n    };\r\n\r\n    DEFINE_ENUM_FLAG_OPERATORS(InapplicabilityFlags);\r\n\r\n    namespace details\r\n    {\r\n        // An interface for defining new filters based on user inputs.\r\n        struct FilterField\r\n        {\r\n            FilterField(std::string_view name) : m_name(name) {}\r\n\r\n            virtual ~FilterField() = default;\r\n\r\n            std::string_view Name() const { return m_name; }\r\n\r\n            // Determines if the installer is applicable based on this field alone.\r\n            virtual InapplicabilityFlags IsApplicable(const AppInstaller::Manifest::ManifestInstaller& installer) = 0;\r\n\r\n            // Explains why the filter regarded this installer as inapplicable.\r\n            // Will only be called when IsApplicable returns false.\r\n            virtual std::string ExplainInapplicable(const AppInstaller::Manifest::ManifestInstaller& installer) = 0;\r\n\r\n        private:\r\n            std::string_view m_name;\r\n        };\r\n\r\n        // The result of ComparisonField::IsFirstBetter\r\n        enum class ComparisonResult\r\n        {\r\n            // The first input is not better than the second input.\r\n            Negative,\r\n            // The first input is somewhat better than the second input.\r\n            // If another comparison has a strong positive result, it will override a weak result.\r\n            WeakPositive,\r\n            // The first input is definitely better than the second input.\r\n            StrongPositive,\r\n        };\r\n\r\n        // An interface for defining new comparisons based on user inputs.\r\n        struct ComparisonField : public FilterField\r\n        {\r\n            using FilterField::FilterField;\r\n\r\n            virtual ~ComparisonField() = default;\r\n\r\n            // Determines if the first installer is a better choice based on this field alone.\r\n            virtual ComparisonResult IsFirstBetter(const AppInstaller::Manifest::ManifestInstaller& first, const AppInstaller::Manifest::ManifestInstaller& second) = 0;\r\n        };\r\n    }\r\n\r\n    struct InstallerAndInapplicabilities\r\n    {\r\n        std::optional<AppInstaller::Manifest::ManifestInstaller> installer;\r\n        std::vector<InapplicabilityFlags> inapplicabilitiesInstaller;\r\n    };\r\n\r\n    // Class in charge of comparing manifest entries\r\n    struct ManifestComparator\r\n    {\r\n        // Options that affect the comparisons.\r\n        struct Options\r\n        {\r\n            // The allowed architectures and a value indicating whether to perform applicability checks.\r\n            std::vector<Utility::Architecture> AllowedArchitectures;\r\n            bool SkipApplicabilityCheck = false;\r\n\r\n            // The requested installer type.\r\n            std::optional<InstallerTypeEnum> RequestedInstallerType;\r\n\r\n            // The currently installed type.\r\n            std::optional<InstallerTypeEnum> CurrentlyInstalledType;\r\n\r\n            // The requested installer scope and a value indicating whether and unknown scope is acceptable.\r\n            std::optional<ScopeEnum> RequestedInstallerScope;\r\n            std::optional<bool> AllowUnknownScope;\r\n\r\n            // The currently installed scope.\r\n            std::optional<ScopeEnum> CurrentlyInstalledScope;\r\n\r\n            // The requested installer locale.\r\n            std::optional<std::string> RequestedInstallerLocale;\r\n\r\n            // Get the currently installed locale intent and value.\r\n            std::optional<std::string> PreviousUserIntentLocale;\r\n            std::optional<std::string> CurrentlyInstalledLocale;\r\n        };\r\n\r\n        ManifestComparator(const Options& options);\r\n\r\n        // Gets the best installer from the manifest, if at least one is applicable.\r\n        InstallerAndInapplicabilities GetPreferredInstaller(const AppInstaller::Manifest::Manifest& manifest);\r\n\r\n        // Determines if an installer is applicable.\r\n        InapplicabilityFlags IsApplicable(const AppInstaller::Manifest::ManifestInstaller& installer);\r\n\r\n        // Determines if the first installer is a better choice.\r\n        bool IsFirstBetter(\r\n            const AppInstaller::Manifest::ManifestInstaller& first,\r\n            const AppInstaller::Manifest::ManifestInstaller& second);\r\n\r\n    private:\r\n        void AddFilter(std::unique_ptr<details::FilterField>&& filter);\r\n        void AddComparator(std::unique_ptr<details::ComparisonField>&& comparator);\r\n\r\n        std::vector<std::unique_ptr<details::FilterField>> m_filters;\r\n        // Non-owning pointers to values in m_filters.\r\n        std::vector<details::ComparisonField*> m_comparators;\r\n    };\r\n\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/ManifestInstaller.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerArchitecture.h>\r\n#include <AppInstallerStrings.h>\r\n#include <winget/Authentication.h>\r\n#include <winget/ManifestCommon.h>\r\n\r\n#include <map>\r\n#include <string>\r\n\r\nnamespace AppInstaller::Manifest\r\n{\r\n    using namespace std::string_view_literals;\r\n\r\n    // Token specified in installer args will be replaced by proper value.\r\n    static constexpr std::string_view ARG_TOKEN_LOGPATH = \"<LOGPATH>\"sv;\r\n    static constexpr std::string_view ARG_TOKEN_INSTALLPATH = \"<INSTALLPATH>\"sv;\r\n\r\n    struct ManifestInstaller\r\n    {\r\n        using string_t = Utility::NormalizedString;\r\n\r\n        AppInstaller::Utility::Architecture Arch = AppInstaller::Utility::Architecture::Unknown;\r\n\r\n        string_t Url;\r\n\r\n        std::vector<BYTE> Sha256;\r\n\r\n        // Optional. Only used by appx/msix type. If provided, Appinstaller will\r\n        // validate appx/msix signature and perform streaming install.\r\n        std::vector<BYTE> SignatureSha256;\r\n\r\n        // Store Product Id\r\n        string_t ProductId;\r\n\r\n        string_t Locale;\r\n\r\n        std::vector<PlatformEnum> Platform;\r\n\r\n        string_t MinOSVersion;\r\n\r\n        // If present, has more precedence than root\r\n        InstallerTypeEnum BaseInstallerType = InstallerTypeEnum::Unknown;\r\n\r\n        InstallerTypeEnum NestedInstallerType = InstallerTypeEnum::Unknown;\r\n\r\n        InstallerTypeEnum EffectiveInstallerType() const\r\n        {\r\n            return IsArchiveType(BaseInstallerType) ? NestedInstallerType : BaseInstallerType;\r\n        }\r\n\r\n        std::vector<NestedInstallerFile> NestedInstallerFiles;\r\n\r\n        ScopeEnum Scope = ScopeEnum::Unknown;\r\n\r\n        std::vector<InstallModeEnum> InstallModes;\r\n\r\n        // If present, has more precedence than root\r\n        std::map<InstallerSwitchType, string_t> Switches;\r\n\r\n        std::vector<DWORD> InstallerSuccessCodes;\r\n\r\n        struct ExpectedReturnCodeInfo\r\n        {\r\n            ExpectedReturnCodeEnum ReturnResponseEnum = ExpectedReturnCodeEnum::Unknown;\r\n            string_t ReturnResponseUrl;\r\n        };\r\n\r\n        std::map<DWORD, ExpectedReturnCodeInfo> ExpectedReturnCodes;\r\n\r\n        UpdateBehaviorEnum UpdateBehavior = UpdateBehaviorEnum::Install;\r\n\r\n        RepairBehaviorEnum RepairBehavior = RepairBehaviorEnum::Unknown;\r\n\r\n        std::vector<string_t> Commands;\r\n\r\n        std::vector<string_t> Protocols;\r\n\r\n        std::vector<string_t> FileExtensions;\r\n\r\n        // Package family name for MSIX packaged installers.\r\n        string_t PackageFamilyName;\r\n\r\n        // Product code for ARP (Add/Remove Programs) installers.\r\n        string_t ProductCode;\r\n\r\n        // For msix only\r\n        std::vector<string_t> Capabilities;\r\n\r\n        // For msix only\r\n        std::vector<string_t> RestrictedCapabilities;\r\n\r\n        DependencyList Dependencies;\r\n\r\n        bool InstallerAbortsTerminal = false;\r\n\r\n        string_t ReleaseDate;\r\n\r\n        bool InstallLocationRequired = false;\r\n\r\n        bool RequireExplicitUpgrade = false;\r\n\r\n        bool DisplayInstallWarnings = false;\r\n\r\n        std::vector<UnsupportedArgumentEnum> UnsupportedArguments;\r\n\r\n        std::vector<AppInstaller::Utility::Architecture> UnsupportedOSArchitectures;\r\n\r\n        std::vector<AppsAndFeaturesEntry> AppsAndFeaturesEntries;\r\n\r\n        ElevationRequirementEnum ElevationRequirement = ElevationRequirementEnum::Unknown;\r\n\r\n        MarketsInfo Markets;\r\n\r\n        InstallationMetadataInfo InstallationMetadata;\r\n\r\n        bool DownloadCommandProhibited = false;\r\n\r\n        bool ArchiveBinariesDependOnPath = false;\r\n\r\n        Authentication::AuthenticationInfo AuthInfo;\r\n\r\n        std::vector<DesiredStateConfigurationContainerInfo> DesiredStateConfiguration;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/ManifestLocalization.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/ManifestCommon.h>\r\n#include <AppInstallerStrings.h>\r\n\r\n#include <variant>\r\n\r\nnamespace AppInstaller::Manifest\r\n{\r\n    using string_t = Utility::NormalizedString;\r\n\r\n    enum class Localization : size_t\r\n    {\r\n        Publisher,\r\n        PublisherUrl,\r\n        PublisherSupportUrl,\r\n        PrivacyUrl,\r\n        Author,\r\n        PackageName,\r\n        PackageUrl,\r\n        License,\r\n        LicenseUrl,\r\n        Copyright,\r\n        CopyrightUrl,\r\n        ShortDescription,\r\n        Description,\r\n        Tags,\r\n        Agreements,\r\n        Documentations,\r\n        ReleaseNotes,\r\n        ReleaseNotesUrl,\r\n        PurchaseUrl,\r\n        InstallationNotes,\r\n        Icons,\r\n        Max\r\n    };\r\n\r\n    struct Agreement\r\n    {\r\n        string_t Label;\r\n        string_t AgreementText;\r\n        string_t AgreementUrl;\r\n    };\r\n\r\n    struct Documentation\r\n    {\r\n        string_t DocumentLabel;\r\n        string_t DocumentUrl;\r\n    };\r\n\r\n    struct Icon\r\n    {\r\n        string_t Url;\r\n        IconFileTypeEnum FileType = IconFileTypeEnum::Unknown;\r\n        IconResolutionEnum Resolution = IconResolutionEnum::Unknown;\r\n        IconThemeEnum Theme = IconThemeEnum::Unknown;\r\n        std::vector<BYTE> Sha256;\r\n    };\r\n\r\n    namespace details\r\n    {\r\n        template <Localization L>\r\n        struct LocalizationMapping\r\n        {\r\n            using value_t = string_t;\r\n        };\r\n\r\n        template <>\r\n        struct LocalizationMapping<Localization::Tags>\r\n        {\r\n            using value_t = std::vector<string_t>;\r\n        };\r\n\r\n        template <>\r\n        struct LocalizationMapping<Localization::Agreements>\r\n        {\r\n            using value_t = std::vector<Agreement>;\r\n        };\r\n\r\n        template <>\r\n        struct LocalizationMapping<Localization::Documentations>\r\n        {\r\n            using value_t = std::vector<Documentation>;\r\n        };\r\n\r\n        template <>\r\n        struct LocalizationMapping<Localization::Icons>\r\n        {\r\n            using value_t = std::vector<Icon>;\r\n        };\r\n\r\n        // Used to deduce the LocalizationVariant type; making a variant that includes std::monostate and all LocalizationMapping types.\r\n        template <size_t... I>\r\n        inline auto Deduce(std::index_sequence<I...>) { return std::variant<std::monostate, typename LocalizationMapping<static_cast<Localization>(I)>::value_t...>{}; }\r\n\r\n        // Holds data of any type listed in a LocalizationMapping.\r\n        using LocalizationVariant = decltype(Deduce(std::make_index_sequence<static_cast<size_t>(Localization::Max)>()));\r\n\r\n        // Gets the index into the variant for the given Localization.\r\n        constexpr inline size_t LocalizationIndex(Localization l) { return static_cast<size_t>(l) + 1; }\r\n    }\r\n\r\n    struct ManifestLocalization\r\n    {\r\n        string_t Locale;\r\n\r\n        // Adds a value to the Localization data, or overwrites an existing entry.\r\n        template <Localization L>\r\n        void Add(typename details::LocalizationMapping<L>::value_t&& v)\r\n        {\r\n            m_data[L].emplace<details::LocalizationIndex(L)>(std::forward<typename details::LocalizationMapping<L>::value_t>(v));\r\n        }\r\n        template <Localization L>\r\n        void Add(const typename details::LocalizationMapping<L>::value_t& v)\r\n        {\r\n            m_data[L].emplace<details::LocalizationIndex(L)>(v);\r\n        }\r\n\r\n        // Return a value indicating whether the given localization type exists.\r\n        bool Contains(Localization l) const { return (m_data.find(l) != m_data.end()); }\r\n\r\n        // Gets the localization value if exists, otherwise empty for easier access\r\n        template <Localization L>\r\n        typename details::LocalizationMapping<L>::value_t Get() const\r\n        {\r\n            auto itr = m_data.find(L);\r\n            if (itr == m_data.end())\r\n            {\r\n                return {};\r\n            }\r\n            else\r\n            {\r\n                return std::get<details::LocalizationIndex(L)>(itr->second);\r\n            }\r\n        }\r\n\r\n        void ReplaceOrMergeWith(const ManifestLocalization& other)\r\n        {\r\n            for (auto const& entry : other.m_data)\r\n            {\r\n                this->m_data[entry.first] = entry.second;\r\n            }\r\n\r\n            this->Locale = other.Locale;\r\n        }\r\n\r\n    private:\r\n        std::map<Localization, details::LocalizationVariant> m_data;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/ManifestSchemaValidation.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ManifestCommon.h\"\r\n#include \"ManifestValidation.h\"\r\n\r\n#include <json/json.h>\r\n\r\nnamespace AppInstaller::Manifest::YamlParser\r\n{\r\n    // Forward declarations\r\n    struct YamlManifestInfo;\r\n\r\n    // Load manifest schema as parsed json doc\r\n    Json::Value LoadSchemaDoc(const ManifestVer& manifestVersion, ManifestTypeEnum manifestType);\r\n\r\n    // Validate a list of individual manifests against schema\r\n    std::vector<ValidationError> ValidateAgainstSchema(\r\n        const std::vector<YamlManifestInfo>& manifestList,\r\n        const ManifestVer& manifestVersion);\r\n\r\n    // Validate the schema header of a list of manifests\r\n    std::vector<ValidationError> ValidateYamlManifestsSchemaHeader(\r\n        const std::vector<YamlManifestInfo>& manifestList,\r\n        const ManifestVer& manifestVersion,\r\n        bool treatErrorAsWarning = true);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/ManifestValidation.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerErrors.h>\r\n#include <winget/Manifest.h>\r\n#include <winget/Resources.h>\r\n\r\n#include <wil/result.h>\r\n#include <functional>\r\n#include <unordered_set>\r\n\r\nnamespace YAML { class Node; }\r\n\r\nnamespace AppInstaller::Manifest\r\n{\r\n    namespace ManifestError\r\n    {\r\n\r\n        const char* const ErrorMessagePrefix = \"Manifest Error: \";\r\n        const char* const WarningMessagePrefix = \"Manifest Warning: \";\r\n\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ApproximateVersionNotAllowed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ArpValidationError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ArpVersionOverlapWithIndex);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ArpVersionValidationInternalError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(BothAllowedAndExcludedMarketsDefined);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DuplicatePortableCommandAlias);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DuplicateRelativeFilePath);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DuplicateMultiFileManifestLocale);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DuplicateMultiFileManifestType);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DuplicateInstallerEntry);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DuplicateInstallerHash);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(DuplicateReturnCodeEntry);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExceededAppsAndFeaturesEntryLimit);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExceededCommandsLimit);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExceededNestedInstallerFilesLimit);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ExeInstallerMissingSilentSwitches);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FieldDuplicate);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FieldFailedToProcess);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FieldIsNotPascalCase);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FieldNotSupported);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FieldRequireVerifiedPublisher);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FieldUnknown);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FieldValueNotSupported);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(FoundDependencyLoop);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(IncompleteMultiFileManifest);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InconsistentInstallerHash);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InconsistentMultiFileManifestDefaultLocale);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InconsistentMultiFileManifestFieldValue);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerFailedToProcess);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerMsixInconsistencies);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerTypeDoesNotSupportPackageFamilyName);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerTypeDoesNotSupportProductCode);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InstallerTypeDoesNotWriteAppsAndFeaturesEntry);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InvalidBcp47Value);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InvalidFieldValue);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InvalidRootNode);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MissingManifestDependenciesNode);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MsixSignatureHashFailed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(MultiManifestPackageHasDependencies);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(NoSuitableMinVersionDependency);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(NoSupportedPlatforms);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(OptionalFieldMissing);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(RelativeFilePathEscapesDirectory);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(RequiredFieldEmpty);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(RequiredFieldMissing);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SchemaError);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ScopeNotSupported);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(ShadowManifestNotAllowed);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SingleManifestPackageHasDependencies);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(UnsupportedMultiFileManifestType);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SchemaHeaderNotFound);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InvalidSchemaHeader);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SchemaHeaderManifestTypeMismatch);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SchemaHeaderManifestVersionMismatch);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(SchemaHeaderUrlPatternMismatch);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InvalidPortableFiletype);\r\n        WINGET_DEFINE_RESOURCE_STRINGID(InvalidFontFiletype);\r\n    }\r\n\r\n    struct ValidationError\r\n    {\r\n        enum class Level\r\n        {\r\n            Warning,\r\n            Error\r\n        };\r\n\r\n        AppInstaller::StringResource::StringId Message;\r\n        std::string Context = {};\r\n        std::string Value = {};\r\n        // line and column are 1 based\r\n        size_t Line = 0;\r\n        size_t Column = 0;\r\n        Level ErrorLevel = Level::Error;\r\n        std::string FileName;\r\n\r\n        ValidationError(AppInstaller::StringResource::StringId message) :\r\n            Message(std::move(message)) {}\r\n\r\n        ValidationError(AppInstaller::StringResource::StringId message, Level level) :\r\n            Message(std::move(message)), ErrorLevel(level) {}\r\n\r\n        ValidationError(AppInstaller::StringResource::StringId message, std::string context) :\r\n            Message(std::move(message)), Context(std::move(context)) {}\r\n\r\n        ValidationError(AppInstaller::StringResource::StringId message, std::string context, Level level) :\r\n            Message(std::move(message)), Context(std::move(context)), ErrorLevel(level) {}\r\n\r\n        ValidationError(AppInstaller::StringResource::StringId message, std::string context, std::string_view value) :\r\n            Message(std::move(message)), Context(std::move(context)), Value(value) {}\r\n\r\n        ValidationError(AppInstaller::StringResource::StringId message, std::string context, std::string value) :\r\n            Message(std::move(message)), Context(std::move(context)), Value(std::move(value)) {}\r\n\r\n        ValidationError(AppInstaller::StringResource::StringId message, std::string context, std::string value, Level level) :\r\n            Message(std::move(message)), Context(std::move(context)), Value(std::move(value)), ErrorLevel(level) {}\r\n\r\n        ValidationError(AppInstaller::StringResource::StringId message, std::string context, std::string value, size_t line, size_t column) :\r\n            Message(std::move(message)), Context(std::move(context)), Value(std::move(value)), Line(line), Column(column) {}\r\n\r\n        ValidationError(AppInstaller::StringResource::StringId message, std::string context, std::string value, size_t line, size_t column, Level level) :\r\n            Message(std::move(message)), Context(std::move(context)), Value(std::move(value)), Line(line), Column(column), ErrorLevel(level) {}\r\n\r\n        std::string GetErrorMessage() const;\r\n\r\n        static ValidationError MessageWithFile(AppInstaller::StringResource::StringId message, std::string file)\r\n        {\r\n            ValidationError error{ message };\r\n            error.FileName = file;\r\n            return error;\r\n        }\r\n\r\n        static ValidationError MessageContextWithFile(AppInstaller::StringResource::StringId message, std::string context, std::string file)\r\n        {\r\n            ValidationError error{ message, context };\r\n            error.FileName = file;\r\n            return error;\r\n        }\r\n\r\n        static ValidationError MessageContextValueWithFile(AppInstaller::StringResource::StringId message, std::string context, std::string value, std::string file)\r\n        {\r\n            ValidationError error{ message, context, value };\r\n            error.FileName = file;\r\n            return error;\r\n        }\r\n\r\n        static ValidationError MessageLevelWithFile(AppInstaller::StringResource::StringId message, Level level, std::string file)\r\n        {\r\n            ValidationError error{ message, level };\r\n            error.FileName = file;\r\n            return error;\r\n        }\r\n\r\n        static ValidationError MessageContextValueLineLevelWithFile(AppInstaller::StringResource::StringId message, std::string context, std::string value, size_t line, size_t column , Level level , std::string file)\r\n        {\r\n            ValidationError error{ message, context, value, line, column, level };\r\n            error.FileName = file;\r\n            return error;\r\n        }\r\n    };\r\n\r\n    struct ManifestException : public wil::ResultException\r\n    {\r\n        ManifestException(std::vector<ValidationError>&& errors = {}, HRESULT hr = APPINSTALLER_CLI_ERROR_MANIFEST_FAILED) :\r\n            wil::ResultException(hr), m_errors(std::move(errors))\r\n        {\r\n            auto p = [&](ValidationError const& e) {\r\n                return e.ErrorLevel == ValidationError::Level::Error;\r\n            };\r\n\r\n            m_warningOnly = !m_errors.empty() && std::find_if(m_errors.begin(), m_errors.end(), p) == m_errors.end();\r\n        }\r\n\r\n        ManifestException(HRESULT hr) : ManifestException({}, hr) {}\r\n\r\n        // Error message without wil diagnostic info\r\n        const std::string& GetManifestErrorMessage() const noexcept\r\n        {\r\n            if (m_manifestErrorMessage.empty())\r\n            {\r\n                if (m_errors.empty())\r\n                {\r\n                    // Syntax error, yaml parser error is stored in FailureInfo\r\n                    if (GetFailureInfo().pszMessage)\r\n                    {\r\n                        m_manifestErrorMessage = Utility::ConvertToUTF8(GetFailureInfo().pszMessage);\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    for (auto const& error : m_errors)\r\n                    {\r\n                        if (error.ErrorLevel == ValidationError::Level::Error)\r\n                        {\r\n                            m_manifestErrorMessage += ManifestError::ErrorMessagePrefix;\r\n                        }\r\n                        else if (error.ErrorLevel == ValidationError::Level::Warning)\r\n                        {\r\n                            m_manifestErrorMessage += ManifestError::WarningMessagePrefix;\r\n                        }\r\n                        m_manifestErrorMessage += error.GetErrorMessage();\r\n\r\n                        if (!error.Context.empty())\r\n                        {\r\n                            m_manifestErrorMessage += \" [\" + error.Context + \"]\";\r\n                        }\r\n                        if (!error.Value.empty())\r\n                        {\r\n                            m_manifestErrorMessage += \" Value: \" + error.Value;\r\n                        }\r\n                        if (error.Line > 0 && error.Column > 0)\r\n                        {\r\n                            m_manifestErrorMessage += \" Line: \" + std::to_string(error.Line) + \", Column: \" + std::to_string(error.Column);\r\n                        }\r\n                        if (!error.FileName.empty())\r\n                        {\r\n                            m_manifestErrorMessage += \" File: \" + error.FileName;\r\n                        }\r\n                        m_manifestErrorMessage += '\\n';\r\n                    }\r\n                }\r\n            }\r\n            return m_manifestErrorMessage;\r\n        }\r\n\r\n        bool IsWarningOnly() const noexcept\r\n        {\r\n            return m_warningOnly;\r\n        }\r\n\r\n        const char* what() const noexcept override\r\n        {\r\n            if (m_whatMessage.empty())\r\n            {\r\n                m_whatMessage = ResultException::what();\r\n\r\n                if (!m_errors.empty())\r\n                {\r\n                    m_whatMessage += GetManifestErrorMessage();\r\n                }\r\n            }\r\n            return m_whatMessage.c_str();\r\n        }\r\n\r\n        const std::vector<ValidationError>& Errors() const { return m_errors; }\r\n\r\n    private:\r\n        std::vector<ValidationError> m_errors;\r\n        mutable std::string m_whatMessage;\r\n        mutable std::string m_manifestErrorMessage;\r\n        bool m_warningOnly;\r\n    };\r\n\r\n    // fullValidation: bool to set if manifest validation should perform extra validation that is not required for reading a manifest.\r\n    std::vector<ValidationError> ValidateManifest(const Manifest& manifest, bool fullValidation = true);\r\n    std::vector<ValidationError> ValidateManifestLocalization(const ManifestLocalization& localization, bool treatErrorAsWarning = false);\r\n    std::vector<ValidationError> ValidateManifestInstallers(const Manifest& manifest, bool treatErrorAsWarning = false);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/ManifestYamlParser.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/ManifestValidation.h>\r\n#include <winget/Manifest.h>\r\n#include <winget/Yaml.h>\r\n#include <AppInstallerSHA256.h>\r\n#include <filesystem>\r\n\r\nnamespace AppInstaller::Manifest::YamlParser\r\n{\r\n    struct YamlManifestInfo\r\n    {\r\n        // Root node of a yaml manifest file\r\n        YAML::Node Root;\r\n\r\n        // File name of the manifest file if applicable for error reporting\r\n        std::string FileName;\r\n\r\n        // Schema header string found in the manifest file\r\n        YAML::DocumentSchemaHeader DocumentSchemaHeader;\r\n\r\n        // The SHA256 hash of the stream\r\n        Utility::SHA256::HashBuffer StreamSha256;\r\n\r\n        ManifestTypeEnum ManifestType = ManifestTypeEnum::Preview;\r\n    };\r\n\r\n    Manifest CreateFromPath(\r\n        const std::filesystem::path& inputPath,\r\n        ManifestValidateOption validateOption = {},\r\n        const std::filesystem::path& mergedManifestPath = {});\r\n\r\n    Manifest Create(\r\n        const std::string& input,\r\n        ManifestValidateOption validateOption = {},\r\n        const std::filesystem::path& mergedManifestPath = {});\r\n\r\n    Manifest ParseManifest(\r\n        std::vector<YamlManifestInfo>& input,\r\n        ManifestValidateOption validateOption = {},\r\n        const std::filesystem::path& mergedManifestPath = {});\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/ManifestYamlPopulator.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/Manifest.h>\r\n#include <winget/ManifestValidation.h>\r\n#include <winget/Yaml.h>\r\n\r\nnamespace AppInstaller::Manifest\r\n{\r\n    // Add here new manifest pointer types.\r\n    using VariantManifestPtr = std::variant<\r\n        Agreement*,\r\n        AppsAndFeaturesEntry*,\r\n        Dependency*,\r\n        DependencyList*,\r\n        DesiredStateConfigurationContainerInfo*,\r\n        DesiredStateConfigurationResourceInfo*,\r\n        Documentation*,\r\n        ExpectedReturnCode*,\r\n        Icon*,\r\n        InstallationMetadataInfo*,\r\n        InstalledFile*,\r\n        Manifest*,\r\n        ManifestInstaller*,\r\n        ManifestLocalization*,\r\n        MarketsInfo*,\r\n        NestedInstallerFile*,\r\n        AppInstaller::Authentication::AuthenticationInfo*,\r\n        AppInstaller::Authentication::MicrosoftEntraIdAuthenticationInfo*,\r\n        std::map<InstallerSwitchType, Utility::NormalizedString>*,\r\n        std::vector<DesiredStateConfigurationContainerInfo>*\r\n    >;\r\n\r\n    struct ManifestYamlPopulator\r\n    {\r\n        static std::vector<ValidationError> PopulateManifest(\r\n            YAML::Node& rootNode,\r\n            Manifest& manifest,\r\n            const ManifestVer& manifestVersion,\r\n            ManifestValidateOption validateOption,\r\n            const std::optional<YAML::Node>& shadowNode);\r\n\r\n    private:\r\n\r\n        ManifestYamlPopulator(YAML::Node& rootNode, Manifest& manifest, const ManifestVer& manifestVersion, ManifestValidateOption validateOption);\r\n\r\n        std::reference_wrapper<YAML::Node> m_rootNode;\r\n        std::reference_wrapper<Manifest> m_manifest;\r\n        std::reference_wrapper<const ManifestVer> m_manifestVersion;\r\n        bool m_isMergedManifest = false;\r\n        ManifestValidateOption m_validateOption;\r\n\r\n        // Struct mapping a manifest field to its population logic\r\n        struct FieldProcessInfo\r\n        {\r\n            FieldProcessInfo(std::string name, std::function<std::vector<ValidationError>(const YAML::Node&, const VariantManifestPtr& v)> func, bool requireVerifiedPublisher = false) :\r\n                Name(std::move(name)), ProcessFunc(func), RequireVerifiedPublisher(requireVerifiedPublisher) {}\r\n\r\n            std::string Name;\r\n            std::function<std::vector<ValidationError>(const YAML::Node&, const VariantManifestPtr& v)> ProcessFunc;\r\n            bool RequireVerifiedPublisher = false;\r\n        };\r\n\r\n        std::vector<FieldProcessInfo> RootFieldInfos;\r\n        std::vector<FieldProcessInfo> InstallerFieldInfos;\r\n        std::vector<FieldProcessInfo> SwitchesFieldInfos;\r\n        std::vector<FieldProcessInfo> ExpectedReturnCodesFieldInfos;\r\n        std::vector<FieldProcessInfo> DependenciesFieldInfos;\r\n        std::vector<FieldProcessInfo> PackageDependenciesFieldInfos;\r\n        std::vector<FieldProcessInfo> LocalizationFieldInfos;\r\n        std::vector<FieldProcessInfo> AgreementFieldInfos;\r\n        std::vector<FieldProcessInfo> MarketsFieldInfos;\r\n        std::vector<FieldProcessInfo> AppsAndFeaturesEntryFieldInfos;\r\n        std::vector<FieldProcessInfo> DocumentationFieldInfos;\r\n        std::vector<FieldProcessInfo> IconFieldInfos;\r\n        std::vector<FieldProcessInfo> NestedInstallerFileFieldInfos;\r\n        std::vector<FieldProcessInfo> InstallationMetadataFieldInfos;\r\n        std::vector<FieldProcessInfo> InstallationMetadataFilesFieldInfos;\r\n        std::vector<FieldProcessInfo> AuthenticationFieldInfos;\r\n        std::vector<FieldProcessInfo> MicrosoftEntraIdAuthenticationInfoFieldInfos;\r\n        std::vector<FieldProcessInfo> DesiredStateConfigurationFieldInfos;\r\n        std::vector<FieldProcessInfo> DesiredStateConfigurationPowerShellModuleFieldInfos;\r\n        std::vector<FieldProcessInfo> DesiredStateConfigurationPowerShellResourceFieldInfos;\r\n        std::vector<FieldProcessInfo> DesiredStateConfigurationDSCv3FieldInfos;\r\n        std::vector<FieldProcessInfo> DesiredStateConfigurationDSCv3ResourceFieldInfos;\r\n\r\n        // Cache of Installers node and Localization node\r\n        YAML::Node const* m_p_installersNode = nullptr;\r\n        YAML::Node const* m_p_localizationsNode = nullptr;\r\n\r\n        std::vector<FieldProcessInfo> GetRootFieldProcessInfo();\r\n        std::vector<FieldProcessInfo> GetInstallerFieldProcessInfo(bool forRootFields = false);\r\n        std::vector<FieldProcessInfo> GetSwitchesFieldProcessInfo();\r\n        std::vector<FieldProcessInfo> GetExpectedReturnCodesFieldProcessInfo();\r\n        std::vector<FieldProcessInfo> GetDependenciesFieldProcessInfo();\r\n        std::vector<FieldProcessInfo> GetPackageDependenciesFieldProcessInfo();\r\n        std::vector<FieldProcessInfo> GetLocalizationFieldProcessInfo(bool forRootFields = false);\r\n        std::vector<FieldProcessInfo> GetAgreementFieldProcessInfo();\r\n        std::vector<FieldProcessInfo> GetMarketsFieldProcessInfo();\r\n        std::vector<FieldProcessInfo> GetAppsAndFeaturesEntryFieldProcessInfo();\r\n        std::vector<FieldProcessInfo> GetDocumentationFieldProcessInfo();\r\n        std::vector<FieldProcessInfo> GetIconFieldProcessInfo();\r\n        std::vector<FieldProcessInfo> GetNestedInstallerFileFieldProcessInfo();\r\n        std::vector<FieldProcessInfo> GetInstallationMetadataFieldProcessInfo();\r\n        std::vector<FieldProcessInfo> GetInstallationMetadataFilesFieldProcessInfo();\r\n        std::vector<FieldProcessInfo> GetAuthenticationFieldInfos();\r\n        std::vector<FieldProcessInfo> GetMicrosoftEntraIdAuthenticationInfoFieldInfos();\r\n        std::vector<FieldProcessInfo> GetDesiredStateConfigurationFieldInfos();\r\n        std::vector<FieldProcessInfo> GetDesiredStateConfigurationPowerShellModuleFieldInfos();\r\n        std::vector<FieldProcessInfo> GetDesiredStateConfigurationPowerShellResourceFieldInfos();\r\n        std::vector<FieldProcessInfo> GetDesiredStateConfigurationDSCv3FieldInfos();\r\n        std::vector<FieldProcessInfo> GetDesiredStateConfigurationDSCv3ResourceFieldInfos();\r\n\r\n        // Shadow\r\n        std::vector<FieldProcessInfo> GetShadowRootFieldProcessInfo();\r\n        std::vector<FieldProcessInfo> GetShadowLocalizationFieldProcessInfo();\r\n\r\n        // This method takes YAML root node and list of manifest field info.\r\n        // Yaml lib does not support case-insensitive search and it allows duplicate keys. If duplicate keys exist,\r\n        // the value is undefined. So in this method, we will iterate through the node map and process each individual\r\n        // pair ourselves. This also helps with generating aggregated error rather than throwing on first failure.\r\n        std::vector<ValidationError> ValidateAndProcessFields(\r\n            const YAML::Node& rootNode,\r\n            const std::vector<FieldProcessInfo>& fieldInfos,\r\n            const VariantManifestPtr& v);\r\n\r\n        std::vector<ValidationError> ProcessPackageDependenciesNode(const YAML::Node& rootNode, DependencyList* dependencyList);\r\n        std::vector<ValidationError> ProcessAgreementsNode(const YAML::Node& agreementsNode, ManifestLocalization* localization);\r\n        std::vector<ValidationError> ProcessMarketsNode(const YAML::Node& marketsNode, AppInstaller::Manifest::ManifestInstaller* installer);\r\n        std::vector<ValidationError> ProcessAppsAndFeaturesEntriesNode(const YAML::Node& appsAndFeaturesEntriesNode, AppInstaller::Manifest::ManifestInstaller* installer);\r\n        std::vector<ValidationError> ProcessExpectedReturnCodesNode(const YAML::Node& returnCodesNode, AppInstaller::Manifest::ManifestInstaller* installer);\r\n        std::vector<ValidationError> ProcessDocumentationsNode(const YAML::Node& documentationsNode, ManifestLocalization* localization);\r\n        std::vector<ValidationError> ProcessIconsNode(const YAML::Node& iconsNode, ManifestLocalization* localization);\r\n        std::vector<ValidationError> ProcessNestedInstallerFilesNode(const YAML::Node& nestedInstallerFilesNode, AppInstaller::Manifest::ManifestInstaller* installer);\r\n        std::vector<ValidationError> ProcessInstallationMetadataFilesNode(const YAML::Node& installedFilesNode, InstallationMetadataInfo* installationMetadata);\r\n        std::vector<ValidationError> ProcessShadowLocalizationNode(const YAML::Node& localizationNode, Manifest* manifest);\r\n        std::vector<ValidationError> ProcessDSC_PowerShellModuleNode(const YAML::Node& node, std::vector<DesiredStateConfigurationContainerInfo>* containers);\r\n        std::vector<ValidationError> ProcessDSC_PowerShellResourcesNode(const YAML::Node& node, DesiredStateConfigurationContainerInfo* container);\r\n        std::vector<ValidationError> ProcessDSCv3ResourcesNode(const YAML::Node& node, DesiredStateConfigurationContainerInfo* container);\r\n\r\n        std::vector<ValidationError> PopulateManifestInternal();\r\n        std::vector<ValidationError> InsertShadow(const YAML::Node& shadowNode);\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/ManifestYamlWriter.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include <winget/Manifest.h>\n#include <winget/Yaml.h>\n\nnamespace AppInstaller::Manifest::YamlWriter\n{\n    /// <summary>\n    /// Converts the manifest and a single installer to a yaml string.\n    /// </summary>\n    /// <param name=\"manifest\">Manifest object.</param>\n    /// <param name=\"installer\">Manifest installer object.</param>\n    /// <returns>Yaml string.</returns>\n    std::string ManifestToYamlString(const Manifest& manifest, const ManifestInstaller& installer);\n\n    /// <summary>\n    /// Exports the manifest and single manifest installer to a yaml file.\n    /// </summary>\n    /// <param name=\"manifest\">Manifest object.</param>\n    /// <param name=\"installer\">Manifest installer object.</param>\n    /// <param name=\"out\">Path of the yaml file.</param>\n    void OutputYamlFile(const Manifest& manifest, const ManifestInstaller& installer, const std::filesystem::path& out);\n}"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/MsiExecArguments.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <list>\r\n#include <string_view>\r\n#include <vector>\r\n\r\n\r\n// This file defines parsing of the command line arguments passed to msiexec.exe.\r\n//\r\n// Some packages require the UAC prompt for installing even on silent installs. This\r\n// can be done with the MSI API using the INSTALLUILEVEL_UACONLY flag, but msiexec.exe\r\n// does not provide a way to use it. So, we use the MSI API directly instead of\r\n// through msiexec.exe. Since msiexec.exe does some parsing of command line arguments\r\n// before handing off to the API, we replicate that parsing here.\r\n//\r\n// Since we care only about installation, we simplify the parsing by assuming that\r\n// the command line has the form\r\n//   msiexec.exe /i (MSI file) [Other args...]\r\n\r\nnamespace AppInstaller::Msi\r\n{\r\n    DEFINE_ENUM_FLAG_OPERATORS(INSTALLUILEVEL);\r\n    DEFINE_ENUM_FLAG_OPERATORS(INSTALLLOGMODE);\r\n    DEFINE_ENUM_FLAG_OPERATORS(INSTALLLOGATTRIBUTES);\r\n\r\n    constexpr INSTALLLOGMODE DefaultLogMode =\r\n        INSTALLLOGMODE_FATALEXIT | INSTALLLOGMODE_ERROR | INSTALLLOGMODE_WARNING | INSTALLLOGMODE_INFO |\r\n        INSTALLLOGMODE_OUTOFDISKSPACE | INSTALLLOGMODE_ACTIONSTART | INSTALLLOGMODE_ACTIONDATA;\r\n\r\n    // All but the four flags that always have to be set explicitly (Verbose, ExtraDebug, LogOnlyOnError, LogPerformance)\r\n    constexpr INSTALLLOGMODE AllLogMode =\r\n        INSTALLLOGMODE_FATALEXIT | INSTALLLOGMODE_ERROR | INSTALLLOGMODE_WARNING | INSTALLLOGMODE_USER | INSTALLLOGMODE_INFO |\r\n        INSTALLLOGMODE_OUTOFDISKSPACE | INSTALLLOGMODE_ACTIONSTART | INSTALLLOGMODE_ACTIONDATA |\r\n        INSTALLLOGMODE_PROPERTYDUMP | INSTALLLOGMODE_COMMONDATA;\r\n\r\n    // Arguments parsed from a command line string.\r\n    // Arguments currently supported are:\r\n    //   - Logging options (/l)\r\n    //   - Quiet options (/q)\r\n    //   - Properties (PROPERTY=Value)\r\n    struct MsiParsedArguments\r\n    {\r\n        // Logging options. See: MsiEnableLog()\r\n        INSTALLLOGMODE LogMode = {};\r\n        std::optional<std::wstring> LogFile;\r\n        INSTALLLOGATTRIBUTES LogAttributes = {};\r\n\r\n        // UI options. See: MsiSetInternalUI()\r\n        INSTALLUILEVEL UILevel = INSTALLUILEVEL_DEFAULT;\r\n\r\n        // Properties string\r\n        std::wstring Properties;\r\n    };\r\n\r\n    // Parses a command line string for msiexec.\r\n    // This function assumes that the full command line will have the form\r\n    //   msiexec.exe /i package.msi [arguments]\r\n    // and that it is only parsing the [arguments] part.\r\n    //\r\n    // Note: This does not match msiexec exactly. It does not support options\r\n    // unrelated to install, nor all options for install (e.g. /n).\r\n    MsiParsedArguments ParseMSIArguments(std::string_view arguments);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/MsixManifest.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"AppInstallerStrings.h\"\n#include \"AppInstallerVersions.h\"\n\n#include <AppxPackaging.h>\n#include <wrl/client.h>\n\nnamespace AppInstaller::Msix\n{\n    using PackageVersion = Utility::UInt64Version;\n    using OSVersion = Utility::UInt64Version;\n\n    // Package identity for an MSIX manifest\n    struct MsixPackageManifestIdentity\n    {\n        MsixPackageManifestIdentity(Microsoft::WRL::ComPtr<IAppxManifestPackageId> packageId)\n            : m_packageId(packageId) {}\n\n        Utility::NormalizedString GetPackageFamilyName() const;\n        PackageVersion GetVersion() const;\n    private:\n        Microsoft::WRL::ComPtr<IAppxManifestPackageId> m_packageId;\n    };\n\n    // Target device family for an MSIX manifest\n    struct MsixPackageManifestTargetDeviceFamily\n    {\n        // Target device family names\n        static constexpr std::string_view WindowsDesktopName = \"Windows.Desktop\";\n        static constexpr std::string_view WindowsUniversalName = \"Windows.Universal\";\n\n        enum Platform\n        {\n            WindowsDesktop,\n            WindowsUniversal,\n            Other,\n        };\n\n        MsixPackageManifestTargetDeviceFamily(Microsoft::WRL::ComPtr<IAppxManifestTargetDeviceFamily> targetDeviceFamily)\n            : m_targetDeviceFamily(targetDeviceFamily) {}\n\n        std::string GetName() const;\n        OSVersion GetMinVersion() const;\n        Platform GetPlatform() const;\n    private:\n        Microsoft::WRL::ComPtr<IAppxManifestTargetDeviceFamily> m_targetDeviceFamily;\n    };\n\n    // MSIX manifest\n    struct MsixPackageManifest\n    {\n        MsixPackageManifest(Microsoft::WRL::ComPtr<IAppxManifestReader> manifestReader)\n            : m_manifestReader(manifestReader) {}\n\n        std::vector<MsixPackageManifestTargetDeviceFamily> GetTargetDeviceFamilies() const;\n        MsixPackageManifestIdentity GetIdentity() const;\n        std::optional<OSVersion> GetMinimumOSVersionForSupportedPlatforms() const;\n    private:\n        Microsoft::WRL::ComPtr<IAppxManifestReader> m_manifestReader;\n    };\n}"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/MsixManifestValidation.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"AppInstallerErrors.h\"\n#include \"AppInstallerMsixInfo.h\"\n#include \"winget/Manifest.h\"\n#include \"winget/ManifestValidation.h\"\n\nnamespace AppInstaller::Manifest\n{\n    struct MsixManifestValidation\n    {\n        MsixManifestValidation(ValidationError::Level validationErrorLevel) : m_validationErrorLevel(validationErrorLevel) {}\n\n        ~MsixManifestValidation();\n\n        // Validate manifest for Msix packages and Msix bundles.\n        std::vector<ValidationError> Validate(\n            const Manifest& manifest,\n            const ManifestInstaller& installer);\n    private:\n        std::map<std::string, std::shared_ptr<Msix::MsixInfo>> m_msixInfoCache;\n        std::vector<std::filesystem::path> m_downloadedInstallers;\n        ValidationError::Level m_validationErrorLevel;\n\n        // Get Msix info from url/local path, or load it from cache.\n        // Return null pointer if operation failed.\n        std::shared_ptr<Msix::MsixInfo> GetMsixInfo(std::string installerUrl);\n\n        // Get Msix info from installer url.\n        // Return null pointer if operation failed.\n        std::shared_ptr<Msix::MsixInfo> GetMsixInfoFromUrl(std::string installerUrl);\n\n        // Download and get msix info from installer local path.\n        // Return null pointer if operation failed.\n        std::shared_ptr<Msix::MsixInfo> GetMsixInfoFromLocalPath(std::string installerUrl);\n\n        // Download the installer.\n        // If the download was successful, return the destination path.\n        std::optional<std::filesystem::path> DownloadInstaller(std::string installerUrl, int retryCount);\n\n        // Get manifest installer minimum OS version or nullopt if failed to\n        // parse input.\n        std::optional<Msix::OSVersion> GetManifestInstallerMinOSVersion(\n            std::string minOSVersion,\n            std::vector<ValidationError>& errors);\n\n        // Validate Msix package family name.\n        void ValidateMsixManifestPackageFamilyName(\n            Utility::NormalizedString msixPackageFamilyName,\n            Utility::NormalizedString manifestPackageFamilyName,\n            std::vector<ValidationError>& errors);\n\n        // Validate Msix package version.\n        void ValidateMsixManifestPackageVersion(\n            const Msix::PackageVersion& msixPackageVersion,\n            const string_t& manifestPackageVersionStr,\n            std::vector<ValidationError>& errors);\n\n        // Validate Msix minimum OS version for supported platforms.\n        void ValidateMsixManifestMinOSVersion(\n            const std::optional<Msix::OSVersion>& msixMinOSVersion,\n            const std::optional<Msix::OSVersion>& manifestMinOSVersion,\n            std::string installerUrl,\n            std::vector<ValidationError>& errors);\n\n        // Validate Msix signature hash.\n        void ValidateMsixManifestSignatureHash(\n            const std::shared_ptr<Msix::MsixInfo> msixInfo,\n            const Utility::SHA256::HashBuffer& manifestSignatureHash,\n            std::vector<ValidationError>& errors);\n    };\n}\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/NameNormalization.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerArchitecture.h>\r\n\r\n#include <string>\r\n#include <string_view>\r\n\r\n\r\nnamespace AppInstaller::Utility\r\n{\r\n    // The specific version of normalization being used.\r\n    enum class NormalizationVersion\r\n    {\r\n        Initial,\r\n        InitialPreserveWhiteSpace,\r\n    };\r\n\r\n    // List of name normalization fields. Architecture, locale, etc.\r\n    // Currently only architecture is used.\r\n    enum class NormalizationField : uint32_t\r\n    {\r\n        None = 0x0,\r\n        Architecture = 0x1,\r\n    };\r\n\r\n    DEFINE_ENUM_FLAG_OPERATORS(NormalizationField);\r\n\r\n    struct NameNormalizer;\r\n\r\n    // A package publisher and name that has been normalized, allowing direct\r\n    // comparison across versions and many other facet. Also allows use in\r\n    // generating and Id for local packages.\r\n    struct NormalizedName\r\n    {\r\n        NormalizedName() = default;\r\n\r\n        const std::string& Name() const { return m_name; }\r\n        void Name(std::string&& name) { m_name = std::move(name); }\r\n        void Name(std::string_view name) { m_name = name; }\r\n\r\n        Utility::Architecture Architecture() const { return m_arch; }\r\n        void Architecture(Utility::Architecture arch) { m_arch = arch; }\r\n\r\n        const std::string& Locale() const { return m_locale; }\r\n        void Locale(std::string&& locale) { m_locale = std::move(locale); }\r\n\r\n        const std::string& Publisher() const { return m_publisher; }\r\n        void Publisher(std::string&& publisher) { m_publisher = std::move(publisher); }\r\n        void Publisher(std::string_view publisher) { m_publisher = publisher; }\r\n\r\n        // Gets normalized name with additional normalization fields included.\r\n        std::string GetNormalizedName(NormalizationField fieldsToInclude) const;\r\n        // Gets a flag indicating the list of fields detected in normalization.\r\n        NormalizationField GetNormalizedFields() const;\r\n\r\n    private:\r\n        std::string m_name;\r\n        Utility::Architecture m_arch = Utility::Architecture::Unknown;\r\n        std::string m_locale;\r\n        std::string m_publisher;\r\n    };\r\n\r\n    namespace details\r\n    {\r\n        // NameNormalizer interface to allow different versions.\r\n        struct INameNormalizer\r\n        {\r\n            virtual ~INameNormalizer() = default;\r\n\r\n            // Normalize both the name and publisher at the same time.\r\n            virtual NormalizedName Normalize(std::string_view name, std::string_view publisher) const = 0;\r\n\r\n            // Normalize only the name.\r\n            virtual NormalizedName NormalizeName(std::string_view name) const = 0;\r\n\r\n            // Normalize only the publisher.\r\n            virtual std::string NormalizePublisher(std::string_view publisher) const = 0;\r\n        };\r\n    }\r\n\r\n    // Helper that manages the lifetime of the internals required to\r\n    // execute the name normalization.\r\n    struct NameNormalizer\r\n    {\r\n        NameNormalizer(NormalizationVersion version);\r\n\r\n        NormalizedName Normalize(std::string_view name, std::string_view publisher) const;\r\n        NormalizedName NormalizeName(std::string_view name) const;\r\n        std::string NormalizePublisher(std::string_view publisher) const;\r\n\r\n    private:\r\n        std::unique_ptr<details::INameNormalizer> m_normalizer;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/NetworkSettings.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n\n#include <optional>\n#include <string>\n#include \"winget/UserSettings.h\"\n\nnamespace AppInstaller::Settings\n{\n    // Network related settings.\n    // Merges information from user settings, admin settings, command line, and group policy.\n    // TODO: This is currently a process global. It should be converted to a thread local\n    //       (like telemetry) once we expose configuring a proxy through the COM API\n    struct NetworkSettings\n    {\n        static NetworkSettings& Instance();\n\n        const std::optional<std::string>& GetProxyUri() const { return m_proxyUri; }\n        // Sets the proxy URI; may do nothing depending on admin settings and group policy\n        void SetProxyUri(const std::optional<std::string>& proxyUri);\n\n        InstallerDownloader GetInstallerDownloader() const;\n\n    protected:\n        NetworkSettings();\n        ~NetworkSettings() = default;\n\n        std::optional<std::string> m_proxyUri;\n    };\n\n    NetworkSettings& Network();\n}\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/OutputDebugStringLogger.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerLogging.h>\r\n\r\nnamespace AppInstaller::Logging\r\n{\r\n    // Sends logs to the OutputDebugString function.\r\n    // Intended for use during initialization debugging.\r\n    struct OutputDebugStringLogger : ILogger\r\n    {\r\n        OutputDebugStringLogger() = default;\r\n\r\n        ~OutputDebugStringLogger() = default;\r\n\r\n        // ILogger\r\n        std::string GetName() const override;\r\n\r\n        void Write(Channel channel, Level, std::string_view message) noexcept override;\r\n\r\n        void WriteDirect(Channel channel, Level level, std::string_view message) noexcept override;\r\n\r\n        // Adds OutputDebugStringLogger to the current Log\r\n        static void Add();\r\n\r\n        // Removes OutputDebugStringLogger from the current Log\r\n        static void Remove();\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/PackageDependenciesValidationUtil.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include <winget/ManifestValidation.h>\n\nnamespace AppInstaller::Manifest\n{\n    enum WinGetManifestDependenciesErrorResult : uint32_t\n    {\n        None = 0x0,\n\n        // Each validation step should have an enum for corresponding failure.\n        SingleManifestPackageHasDependencies = 0x10000,\n        MultiManifestPackageHasDependencies = 0x20000,\n        MissingManifestDependenciesNode = 0x40000,\n        NoSuitableMinVersionDependency = 0x80000,\n        FoundDependencyLoop = 0x100000,\n    };\n\n    DEFINE_ENUM_FLAG_OPERATORS(WinGetManifestDependenciesErrorResult);\n\n    WinGetManifestDependenciesErrorResult GetDependenciesValidationResultFromException(const ManifestException& manifestException);\n}"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/PackageVersionDataManifest.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerVersions.h>\r\n#include <winget/Compression.h>\r\n#include <filesystem>\r\n\r\n\r\nnamespace AppInstaller::Manifest\r\n{\r\n    // Contains the manifest that stores package version data for index v2\r\n    struct PackageVersionDataManifest\r\n    {\r\n        // The file name to use for the package version data manifest.\r\n        static std::string_view VersionManifestFileName();\r\n\r\n        // The file name to use for the compressed package version data manifest.\r\n        static std::string_view VersionManifestCompressedFileName();\r\n\r\n        // Gets the relative path to the package version manifest from the inputs.\r\n        static std::filesystem::path GetRelativeDirectoryPath(std::string_view packageIdentifier, std::string_view manifestHash);\r\n\r\n        // Creates the compressor used by the PackageVersionDataManifest.\r\n        static Compression::Compressor CreateCompressor();\r\n\r\n        // Creates the decompressor used by the PackageVersionDataManifest.\r\n        static Compression::Decompressor CreateDecompressor();\r\n\r\n        // Data on an individual version.\r\n        struct VersionData\r\n        {\r\n            VersionData() = default;\r\n\r\n            VersionData(\r\n                const Utility::VersionAndChannel& versionAndChannel,\r\n                std::optional<std::string> arpMinVersion,\r\n                std::optional<std::string> arpMaxVersion,\r\n                std::optional<std::string> relativePath,\r\n                std::optional<std::string> manifestHash);\r\n\r\n            Utility::Version Version;\r\n            std::optional<std::string> ArpMinVersion;\r\n            std::optional<std::string> ArpMaxVersion;\r\n            std::string ManifestRelativePath;\r\n            std::string ManifestHash;\r\n        };\r\n\r\n        // Adds the given version data to the manifest.\r\n        void AddVersion(VersionData&& versionData);\r\n\r\n        // Gets the version data in this object.\r\n        const std::vector<VersionData>& Versions() const;\r\n\r\n        // Returns a serialized version of the current manifest data.\r\n        std::string Serialize();\r\n\r\n        // Parses the input into this objects data.\r\n        void Deserialize(std::string_view input);\r\n\r\n        // Parses the input into this objects data.\r\n        void Deserialize(const std::vector<uint8_t>& input);\r\n\r\n    private:\r\n        std::vector<VersionData> m_versions;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/PathVariable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"winget/Manifest.h\"\r\n#include \"winget/Registry.h\"\r\n\r\nnamespace AppInstaller::Registry::Environment\r\n{\r\n    bool RefreshPathVariableForCurrentProcess();\r\n\r\n    struct PathVariable\r\n    {\r\n        PathVariable(Manifest::ScopeEnum scope, bool readOnly = false);\r\n\r\n        // Returns the PATH variable as a string.\r\n        std::string GetPathValue();\r\n\r\n        // Checks if the PATH variable contains the target path.\r\n        bool Contains(const std::filesystem::path& target);\r\n\r\n        // Returns a value indicating whether the target path was removed from the PATH variable.\r\n        bool Remove(const std::filesystem::path& target);\r\n\r\n        // Returns a value indicating whether the target path was appended to the PATH variable.\r\n        bool Append(const std::filesystem::path& target);\r\n\r\n    private:\r\n        void SetPathValue(const std::string& value);\r\n        Registry::Key m_key;\r\n        Manifest::ScopeEnum m_scope;\r\n        bool m_readOnly;\r\n    };\r\n}"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/Pin.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"winget/Manifest.h\"\r\n#include \"AppInstallerVersions.h\"\r\n\r\nnamespace AppInstaller::Pinning\r\n{\r\n    // The pin types are ordered by how \"strict\" they are.\r\n    // Meaning, the one that is more restrictive goes later.\r\n    // This is used to decide which pin to report if there are multiple pins.\r\n    enum class PinType : int64_t\r\n    {\r\n        // Unknown pin type or not pinned\r\n        Unknown,\r\n        // Pinned by the manifest using the RequiresExplicitUpgrade field.\r\n        // Behaves the same as Pinning pins\r\n        PinnedByManifest,\r\n        // The package is excluded from 'upgrade --all', unless '--include-pinned' is added.\r\n        // 'upgrade <package>' is not blocked.\r\n        Pinning,\r\n        // The package is pinned to a specific version range.\r\n        Gating,\r\n        // The package is blocked from 'upgrade --all' and 'upgrade <package>'.\r\n        // User has to unblock to allow update.\r\n        Blocking,\r\n    };\r\n\r\n    std::string_view ToString(PinType type);\r\n    PinType ConvertToPinTypeEnum(std::string_view in);\r\n\r\n    // Determines which of two pin types is more strict.\r\n    bool IsStricter(PinType first, PinType second);\r\n\r\n    // Returns the stricter of two pin types.\r\n    PinType Stricter(PinType first, PinType second);\r\n\r\n    // The set of values needed to uniquely identify a Pin.\r\n    // A Pin can apply to an installed package or to an available package.\r\n    // Pins on available packages can persist when an app is updated outside of winget,\r\n    // but it's hard to have them work when there are multiple installed packages for the same available package.\r\n    // Pins on installed packages work fine when there are multiple installed packages for the same available,\r\n    // but they break when the package is updated outside of winget.\r\n    struct PinKey\r\n    {\r\n        PinKey() = default;\r\n        PinKey(const Manifest::Manifest::string_t& packageId, std::string_view sourceId)\r\n            : PackageId(packageId), SourceId(sourceId) {}\r\n\r\n        // Gets a pin key that refers to an installed package by its ProductCode or PackageFamilyName.\r\n        // The sourceId used is a special string to distinguish from available packages.\r\n        static PinKey GetPinKeyForInstalled(std::string_view systemReferenceString);\r\n\r\n        bool IsForInstalled() const;\r\n\r\n        bool operator==(const PinKey& other) const\r\n        {\r\n            return PackageId == other.PackageId\r\n                && SourceId == other.SourceId;\r\n        }\r\n\r\n        bool operator!=(const PinKey& other) const\r\n        {\r\n            return !(*this == other);\r\n        }\r\n\r\n        bool operator<(const PinKey& other) const\r\n        {\r\n            // std::tie implements tuple comparison, wherein it checks the first item in the tuple,\r\n            // iff the first elements are equal, then the second element is used for comparison, and so on\r\n            return std::tie(PackageId, SourceId) < std::tie(other.PackageId, other.SourceId);\r\n        }\r\n\r\n        // Used for logging\r\n        std::string ToString() const;\r\n\r\n        std::string PackageId;\r\n        std::string SourceId;\r\n    };\r\n\r\n    struct Pin\r\n    {\r\n        Pin(const Pin&) = default;\r\n        Pin& operator=(const Pin& other) = default;\r\n\r\n        Pin(Pin&&) = default;\r\n        Pin& operator=(Pin&&) = default;\r\n\r\n        static Pin CreateBlockingPin(PinKey&& pinKey);\r\n        static Pin CreatePinningPin(PinKey&& pinKey);\r\n        static Pin CreateGatingPin(PinKey&& pinKey, Utility::GatedVersion&& gatedVersion);\r\n\r\n        static Pin CreateBlockingPin(const PinKey& pinKey) { return CreateBlockingPin(PinKey{ pinKey }); }\r\n        static Pin CreatePinningPin(const PinKey& pinKey) { return CreatePinningPin(PinKey{ pinKey }); }\r\n        static Pin CreateGatingPin(const PinKey& pinKey, const Utility::GatedVersion& gatedVersion) { return CreateGatingPin(PinKey{ pinKey }, Utility::GatedVersion{ gatedVersion }); }\r\n\r\n        PinType GetType() const { return m_type; }\r\n        const PinKey& GetKey() const { return m_key; }\r\n        const Utility::GatedVersion& GetGatedVersion() const { return m_gatedVersion; }\r\n\r\n        bool operator==(const Pin& other) const;\r\n        bool operator<(const Pin& other) const\r\n        {\r\n            return std::make_pair(m_type, m_key) < std::make_pair(other.m_type, other.m_key);\r\n        }\r\n\r\n        // Used for logging\r\n        std::string ToString() const;\r\n\r\n    private:\r\n        Pin(PinType type, PinKey&& pinKey, Utility::GatedVersion&& gatedVersion = {})\r\n            : m_type(type), m_key(std::move(pinKey)), m_gatedVersion(std::move(gatedVersion)) {}\r\n\r\n        PinType m_type = PinType::Unknown;\r\n        PinKey m_key;\r\n        Utility::GatedVersion m_gatedVersion;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/PortableARPEntry.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/Registry.h>\r\n#include \"Manifest.h\"\r\n\r\nnamespace AppInstaller::Registry::Portable\r\n{\r\n    enum class PortableValueName\r\n    {\r\n        DisplayName,\r\n        DisplayVersion,\r\n        HelpLink,\r\n        InstallDate,\r\n        InstallDirectoryCreated,\r\n        InstallLocation,\r\n        PortableSymlinkFullPath,\r\n        PortableTargetFullPath,\r\n        Publisher,\r\n        SHA256,\r\n        URLInfoAbout,\r\n        UninstallString,\r\n        WinGetInstallerType,\r\n        WinGetPackageIdentifier,\r\n        WinGetSourceIdentifier,\r\n        InstallDirectoryAddedToPath,\r\n    };\r\n\r\n    std::wstring_view ToString(PortableValueName valueName);\r\n\r\n    struct PortableARPEntry : Registry::Key\r\n    {\r\n        PortableARPEntry(Manifest::ScopeEnum scope, Utility::Architecture arch, const std::string& productCode);\r\n\r\n        std::optional<Value> operator[](PortableValueName valueName) const;\r\n\r\n        bool Exists() { return m_exists; }\r\n\r\n        void SetValue(PortableValueName valueName, const std::wstring& value);\r\n        void SetValue(PortableValueName valueName, const std::string_view& value);\r\n        void SetValue(PortableValueName valueName, bool& value);\r\n\r\n        void Delete();\r\n\r\n        Registry::Key GetKey() { return m_key; };\r\n        Manifest::ScopeEnum GetScope() { return m_scope; };\r\n        Utility::Architecture GetArchitecture() { return m_arch; };\r\n        std::string GetProductCode() { return m_productCode; };\r\n\r\n    private:\r\n        bool m_exists = false;\r\n        std::string m_productCode;\r\n        Key m_key;\r\n        HKEY m_root;\r\n        std::wstring m_subKey;\r\n        DWORD m_samDesired;\r\n        Manifest::ScopeEnum m_scope;\r\n        Utility::Architecture m_arch;\r\n    };\r\n\r\n}"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/PortableFileEntry.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"AppInstallerSHA256.h\"\r\n#include <string>\r\n#include <filesystem>\r\n\r\nnamespace AppInstaller::Portable\r\n{\r\n    // File type enum of the portable file\r\n    enum class PortableFileType\r\n    {\r\n        Unknown,\r\n        File,\r\n        Directory,\r\n        Symlink\r\n    };\r\n\r\n    // Metadata representation of a portable file placed down during installation\r\n    struct PortableFileEntry\r\n    {\r\n        // Version 1.0\r\n        PortableFileType FileType = PortableFileType::Unknown;\r\n        std::string SHA256;\r\n        std::string SymlinkTarget;\r\n        std::filesystem::path CurrentPath;\r\n\r\n        void SetFilePath(const std::filesystem::path& path)\r\n        {\r\n            if (FileType != PortableFileType::Symlink)\r\n            {\r\n                m_filePath = std::filesystem::weakly_canonical(path);\r\n            }\r\n            else\r\n            {\r\n                m_filePath = path;\r\n            }\r\n        };\r\n\r\n        std::filesystem::path GetFilePath() const { return m_filePath; };\r\n\r\n        static PortableFileEntry CreateFileEntry(const std::filesystem::path& currentPath, const std::filesystem::path& targetPath, const std::string& sha256)\r\n        {\r\n            PortableFileEntry fileEntry;\r\n            fileEntry.FileType = PortableFileType::File;\r\n            fileEntry.CurrentPath = currentPath;\r\n            fileEntry.SetFilePath(targetPath);\r\n\r\n            if (sha256.empty())\r\n            {\r\n                fileEntry.SHA256 = Utility::SHA256::ConvertToString(Utility::SHA256::ComputeHashFromFile(currentPath));\r\n            }\r\n            else\r\n            {\r\n                fileEntry.SHA256 = sha256;\r\n            }\r\n            return fileEntry;\r\n        }\r\n\r\n        static PortableFileEntry CreateSymlinkEntry(const std::filesystem::path& symlinkPath, const std::filesystem::path& targetPath)\r\n        {\r\n            PortableFileEntry symlinkEntry;\r\n            symlinkEntry.FileType = PortableFileType::Symlink;\r\n            symlinkEntry.SetFilePath(symlinkPath);\r\n            symlinkEntry.SymlinkTarget = targetPath.u8string();\r\n            return symlinkEntry;\r\n        }\r\n\r\n        static PortableFileEntry CreateDirectoryEntry(const std::filesystem::path& currentPath, const std::filesystem::path& directoryPath)\r\n        {\r\n            PortableFileEntry directoryEntry;\r\n            directoryEntry.FileType = PortableFileType::Directory;\r\n            directoryEntry.CurrentPath = currentPath;\r\n            directoryEntry.SetFilePath(directoryPath);\r\n            return directoryEntry;\r\n        }\r\n\r\n    private:\r\n        std::filesystem::path m_filePath;\r\n    };\r\n}"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/Reboot.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n\nnamespace AppInstaller::Reboot\n{\n    bool InitiateReboot();\n\n    // Registers the application to be restarted by Windows Error Reporting (WER) in case of an unexpected shutdown.\n    bool RegisterRestartForWER(const std::string& commandLineArgs);\n\n    // Unregisters the application from being restarted by Windows Error Reporting (WER).\n    bool UnregisterRestartForWER();\n\n    // Runs a program when a user logs on.\n    void WriteToRunOnceRegistry(const std::string& resumeId, const std::string& commandLine);\n}"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/Regex.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <functional>\r\n#include <memory>\r\n#include <string_view>\r\n\r\n\r\nnamespace AppInstaller::Regex\r\n{\r\n    // Options for regular expression use.\r\n    enum class Options\r\n    {\r\n        None = 0,\r\n        CaseInsensitive,\r\n    };\r\n\r\n    // Stores the compiled regular expression.\r\n    // All pattern strings are considered UTF-8.\r\n    // All input strings are considered UTF-16, as this is what ICU operates on internally.\r\n    struct Expression\r\n    {\r\n        Expression();\r\n        Expression(std::string_view pattern, Options options = Options::None);\r\n\r\n        Expression(const Expression&);\r\n        Expression& operator=(const Expression&);\r\n\r\n        Expression(Expression&&) noexcept;\r\n        Expression& operator=(Expression&&) noexcept;\r\n\r\n        ~Expression();\r\n\r\n        // Determines if the expression contains a value.\r\n        operator bool() const;\r\n\r\n        // Returns a value indicating whether the *entire* input matches the expression.\r\n        bool IsMatch(std::wstring_view input) const;\r\n\r\n        // Replaces all matches in the input with the replacement.\r\n        std::wstring Replace(std::wstring_view input, std::wstring_view replacement) const;\r\n\r\n        // For each section of the input, invoke the given functor. This allows the caller\r\n        // to iterate over the entire string, taking action as appropriate for each part.\r\n        // The parameters are:\r\n        //      bool :: indicates whether this section was a match\r\n        //      string_view :: the text for the section\r\n        // The functor should return true to continue the loop, or false to break it.\r\n        void ForEach(std::wstring_view input, const std::function<bool(bool,std::wstring_view)>& f) const;\r\n\r\n    private:\r\n        struct impl;\r\n        std::unique_ptr<impl> pImpl;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/Rest.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <cpprest/json.h>\r\n\r\nnamespace AppInstaller::Rest\r\n{\r\n    utility::string_t GetRestAPIBaseUri(std::string restApiUri);\r\n\r\n    bool IsValidUri(const utility::string_t& restApiUri);\r\n\r\n    utility::string_t AppendPathToUri(const utility::string_t& restApiUri, const utility::string_t& path);\r\n\r\n    utility::string_t MakeQueryParam(std::string_view queryName, const std::string& queryValue);\r\n\r\n    utility::string_t AppendQueryParamsToUri(const utility::string_t& uri, const std::map<std::string_view, std::string>& queryParameters);\r\n\r\n    std::vector<std::string> GetUniqueItems(const std::vector<std::string>& list);\r\n}\r\n\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/SelfManagement.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerProgress.h>\r\n\r\nnamespace AppInstaller::SelfManagement\r\n{\r\n    // Gets the stub preference for the current package.\r\n    // Returns true if the package is set to prefer stubs.\r\n    // Returns false if the package is set to prefer the full package,\r\n    // or the current process is not packaged.\r\n    bool IsStubPreferred();\r\n\r\n    // Sets the stub preference for the current package.\r\n    // It is an error to set the preference if the process is not packaged,\r\n    // or the preference can otherwise not be set (older version of Windows).\r\n    void SetStubPreferred(bool preferStub);\r\n\r\n    // Gets a value indicating whether the current package is the stub package.\r\n    bool IsStubPackage();\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/Settings.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <filesystem>\r\n#include <memory>\r\n#include <string>\r\n#include <string_view>\r\n\r\nnamespace AppInstaller::Settings\r\n{\r\n    using namespace std::string_view_literals;\r\n\r\n    namespace details\r\n    {\r\n        // A settings container.\r\n        struct ISettingsContainer\r\n        {\r\n            virtual ~ISettingsContainer() = default;\r\n\r\n            // Gets a stream containing the setting's value, if present.\r\n            // If the setting does not exist, returns an empty value.\r\n            virtual std::unique_ptr<std::istream> Get() = 0;\r\n\r\n            // Sets the setting to the given value.\r\n            virtual bool Set(std::string_view value) = 0;\r\n\r\n            // Deletes the setting.\r\n            virtual void Remove() = 0;\r\n\r\n            // Gets the path to the setting, if reasonable.\r\n            virtual std::filesystem::path PathTo() = 0;\r\n        };\r\n    }\r\n\r\n    // Allows settings to be classified and treated differently base on any number of factors.\r\n    // Names should still be unique, as there is no guarantee made about types mapping to unique roots.\r\n    enum class Type\r\n    {\r\n        // A Standard setting stream has no special requirements (limited to 8K contents and no embedded null characters).\r\n        Standard,\r\n        // A UserFile setting stream should be located in a file that is easily editable by the user.\r\n        UserFile,\r\n        // A settings stream that should not be modified except by admin privileges.\r\n        Secure,\r\n        // A settings stream that is encrypted. It does not require admin privileges to write to.\r\n        Encrypted,\r\n        // A setting stream has should be stored in a file, removing the limitations of the Standard type.\r\n        StandardFile,\r\n    };\r\n\r\n    // Converts the Type enum to a string.\r\n    std::string_view ToString(Type type);\r\n\r\n    // A stream definition, combining both type and path.\r\n    // The well known values in Streams should be used by product code, while tests may directly create them.\r\n    struct StreamDefinition\r\n    {\r\n        constexpr StreamDefinition(Type type, std::string_view name) : Type(type), Name(name) {}\r\n\r\n        // The type of stream.\r\n        Type Type;\r\n\r\n        // The name is used as a file name in some situations.\r\n        std::string_view Name;\r\n    };\r\n\r\n    // A setting stream; provides access to functionality on the stream.\r\n    struct Stream\r\n    {\r\n        // The set of well known settings streams.\r\n        // Changing these values can result in data loss.\r\n\r\n        // The set of sources as defined by the user.\r\n        constexpr static StreamDefinition UserSources{ Type::Secure, \"user_sources\"sv };\r\n        // The metadata about all sources.\r\n        constexpr static StreamDefinition SourcesMetadata{ Type::Standard, \"sources_metadata\"sv };\r\n        // The primary user settings file.\r\n        constexpr static StreamDefinition PrimaryUserSettings{ Type::UserFile, \"settings.json\"sv };\r\n        // The backup user settings file.\r\n        constexpr static StreamDefinition BackupUserSettings{ Type::UserFile, \"settings.json.backup\"sv };\r\n        // The admin settings.\r\n        constexpr static StreamDefinition AdminSettings{ Type::Secure, \"admin_settings\"sv };\r\n        // The REST information cache.\r\n        constexpr static StreamDefinition RestInformationCache{ Type::Encrypted, \"rest_information\"sv };\r\n\r\n        // Gets a Stream for the StreamDefinition.\r\n        // If the stream is synchronized, attempts to Set the value can fail due to another writer\r\n        // having changed the underlying stream.\r\n        Stream(const StreamDefinition& streamDefinition);\r\n\r\n        const StreamDefinition& Definition() const { return m_streamDefinition; }\r\n\r\n        // Gets the stream if present.\r\n        // If the setting stream does not exist, returns an empty value (see operator bool).\r\n        std::unique_ptr<std::istream> Get();\r\n\r\n        // Sets the stream to the given value.\r\n        // Returns true if successful; false if the underlying stream has changed.\r\n        [[nodiscard]] bool Set(std::string_view value);\r\n\r\n        // Deletes the setting stream.\r\n        void Remove();\r\n\r\n        // Gets the name of the stream.\r\n        std::string_view GetName() const;\r\n\r\n        // Gets the path to the stream.\r\n        std::filesystem::path GetPath() const;\r\n\r\n    private:\r\n        const StreamDefinition m_streamDefinition;\r\n        std::unique_ptr<details::ISettingsContainer> m_container;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/StdErrLogger.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerLogging.h>\r\n\r\nnamespace AppInstaller::Logging\r\n{\r\n    // Sends logs to the stderr stream.\r\n    struct StdErrLogger : ILogger\r\n    {\r\n        StdErrLogger() = default;\r\n\r\n        ~StdErrLogger() = default;\r\n\r\n        // ILogger\r\n        std::string GetName() const override;\r\n\r\n        void Write(Channel channel, Level level, std::string_view message) noexcept override;\r\n\r\n        void WriteDirect(Channel channel, Level level, std::string_view message) noexcept override;\r\n\r\n        // Adds OutputDebugStringLogger to the current Log\r\n        static void Add();\r\n\r\n        // Removes OutputDebugStringLogger from the current Log\r\n        static void Remove();\r\n\r\n    private:\r\n        Level m_level = Level::Error;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/ThreadGlobals.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include <AppInstallerLogging.h>\n#include <winget/SharedThreadGlobals.h>\n#include <AppInstallerTelemetry.h>\n#include <mutex>\n\nnamespace AppInstaller::ThreadLocalStorage\n{\n    struct WingetThreadGlobals : public ThreadGlobals\n    {\n        WingetThreadGlobals() = default;\n        virtual ~WingetThreadGlobals() = default;\n\n        // Request that a sub ThreadGlobals be constructed from the given parent.\n        struct create_sub_thread_globals_t {};\n        WingetThreadGlobals(WingetThreadGlobals& parent, create_sub_thread_globals_t);\n\n        AppInstaller::Logging::DiagnosticLogger& GetDiagnosticLogger() override;\n\n        void* GetTelemetryObject() override;\n\n        AppInstaller::Logging::TelemetryTraceLogger& GetTelemetryLogger();\n\n        // Set Globals for Current Thread\n        // Return RAII object with its ownership to set the AppInstaller ThreadLocalStorage back to previous state\n        std::unique_ptr<AppInstaller::ThreadLocalStorage::PreviousThreadGlobals> SetForCurrentThread() override;\n\n    private:\n\n        void Initialize();\n\n        std::shared_ptr<AppInstaller::Logging::DiagnosticLogger> m_pDiagnosticLogger;\n        std::unique_ptr<AppInstaller::Logging::TelemetryTraceLogger> m_pTelemetryLogger;\n        std::once_flag m_loggerInitOnceFlag;\n    };\n}\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/TraceLogger.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerLogging.h>\r\n#include <AppInstallerTelemetry.h>\r\n\r\n#include <string>\r\n#include <string_view>\r\n\r\nnamespace AppInstaller::Logging\r\n{\r\n    // Log ETW events for tracing.\r\n    // Doesn't save events to a file on disk.\r\n    struct TraceLogger : ILogger\r\n    {\r\n        TraceLogger() = default;\r\n\r\n        ~TraceLogger() = default;\r\n\r\n        // ILogger\r\n        std::string GetName() const override;\r\n\r\n        void Write(Channel channel, Level, std::string_view message) noexcept override;\r\n\r\n        void WriteDirect(Channel channel, Level level, std::string_view message) noexcept override;\r\n\r\n        // Adds a TraceLogger to the current Log\r\n        static void Add();\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Public/winget/UserSettings.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"AppInstallerStrings.h\"\r\n#include \"AppInstallerLogging.h\"\r\n#include \"winget/Archive.h\"\r\n#include \"winget/GroupPolicy.h\"\r\n#include \"winget/Resources.h\"\r\n#include \"winget/ManifestCommon.h\"\r\n\r\n#include <filesystem>\r\n#include <map>\r\n#include <optional>\r\n#include <string>\r\n#include <type_traits>\r\n#include <variant>\r\n#include <vector>\r\n\r\n#include \"AppInstallerArchitecture.h\"\r\n\r\nusing namespace std::chrono_literals;\r\nusing namespace std::string_view_literals;\r\n\r\nnamespace AppInstaller::Settings\r\n{\r\n    // The type of argument.\r\n    enum class UserSettingsType\r\n    {\r\n        // Settings files don't exist. A file is created on the first call to the settings command.\r\n        Default,\r\n        // Loaded settings.json\r\n        Standard,\r\n        // Loaded settings.json.backup\r\n        Backup,\r\n        // Loaded from custom settings content\r\n        Custom,\r\n    };\r\n\r\n    // The visual style of the progress bar.\r\n    enum class VisualStyle\r\n    {\r\n        NoVT,\r\n        Retro,\r\n        Accent,\r\n        Rainbow,\r\n        Sixel,\r\n        Disabled,\r\n    };\r\n\r\n    // The download code to use for *installers*.\r\n    enum class InstallerDownloader\r\n    {\r\n        Default,\r\n        WinInet,\r\n        DeliveryOptimization,\r\n    };\r\n\r\n    // Enum of settings.\r\n    // Must start at 0 to enable direct access to variant in UserSettings.\r\n    // Max must be last and unused.\r\n    // How to add a setting\r\n    // 1 - Add to enum.\r\n    // 2 - Implement SettingMap specialization via SETTINGMAPPING_SPECIALIZATION\r\n    // Validate will be called by ValidateAll without any more changes.\r\n    enum class Setting : size_t\r\n    {\r\n        // Visual\r\n        ProgressBarVisualStyle,\r\n        AnonymizePathForDisplay,\r\n        EnableSixelDisplay,\r\n        // Source\r\n        AutoUpdateTimeInMinutes,\r\n        // Experimental\r\n        EFExperimentalCmd,\r\n        EFExperimentalArg,\r\n        EFDirectMSI,\r\n        EFResume,\r\n        EFFonts,\r\n        EFSourcePriority,\r\n        // Telemetry\r\n        TelemetryDisable,\r\n        // Install behavior\r\n        InstallScopePreference,\r\n        InstallScopeRequirement,\r\n        InstallArchitecturePreference,\r\n        InstallArchitectureRequirement,\r\n        InstallLocalePreference,\r\n        InstallLocaleRequirement,\r\n        InstallerTypePreference,\r\n        InstallerTypeRequirement,\r\n        InstallDefaultRoot,\r\n        InstallSkipDependencies,\r\n        ArchiveExtractionMethod,\r\n        DisableInstallNotes,\r\n        PortablePackageUserRoot,\r\n        PortablePackageMachineRoot,\r\n        MaxResumes,\r\n        // Network\r\n        NetworkDownloader,\r\n        NetworkDOProgressTimeoutInSeconds,\r\n        NetworkWingetAlternateSourceURL,\r\n        // Logging\r\n        LoggingLevelPreference,\r\n        LoggingChannelPreference,\r\n        LoggingFileAgeLimitInDays,\r\n        LoggingFileTotalSizeLimitInMB,\r\n        LoggingFileIndividualSizeLimitInMB,\r\n        LoggingFileCountLimit,\r\n        // Uninstall behavior\r\n        UninstallPurgePortablePackage,\r\n        // Download behavior\r\n        DownloadDefaultDirectory,\r\n        // Configure behavior\r\n        ConfigureDefaultModuleRoot,\r\n        // Interactivity\r\n        InteractivityDisable,\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        // Debug\r\n        EnableSelfInitiatedMinidump,\r\n        KeepAllLogFiles,\r\n#endif\r\n        Max\r\n    };\r\n\r\n    namespace details\r\n    {\r\n        template <Setting S>\r\n        struct SettingMapping\r\n        {\r\n            // json_t - type the setting in json.\r\n            // value_t - the type of this setting.\r\n            // DefaultValue - the value_t default value when setting is absent or semantically wrong.\r\n            // Path - json path to the property. See Json::Path in json.h for syntax. So far, this is sufficient\r\n            //        but since is \"brief\" and \"untested\" we might implement our own if needed.\r\n            // Validate - Function that does semantic validation.\r\n        };\r\n\r\n#define SETTINGMAPPING_SPECIALIZATION_POLICY(_setting_, _json_, _value_, _default_, _path_, _valuePolicy_) \\\r\n        template <> \\\r\n        struct SettingMapping<_setting_> \\\r\n        { \\\r\n            using json_t = _json_; \\\r\n            using value_t = _value_; \\\r\n            inline static const value_t DefaultValue = _default_; \\\r\n            static constexpr std::string_view Path = _path_; \\\r\n            static std::optional<value_t> Validate(const json_t& value); \\\r\n            static constexpr ValuePolicy Policy = _valuePolicy_; \\\r\n            using policy_t = GroupPolicy::ValueType<Policy>; \\\r\n            static_assert(Policy == ValuePolicy::None || std::is_same<json_t, policy_t>::value); \\\r\n        }\r\n\r\n#define SETTINGMAPPING_SPECIALIZATION(_setting_, _json_, _value_, _default_, _path_) \\\r\n        SETTINGMAPPING_SPECIALIZATION_POLICY(_setting_, _json_, _value_, _default_, _path_, ValuePolicy::None)\r\n\r\n        // Visual\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::ProgressBarVisualStyle, std::string, VisualStyle, VisualStyle::Accent, \".visual.progressBar\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::AnonymizePathForDisplay, bool, bool, true, \".visual.anonymizeDisplayedPaths\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::EnableSixelDisplay, bool, bool, false, \".visual.enableSixels\"sv);\r\n        // Source\r\n        SETTINGMAPPING_SPECIALIZATION_POLICY(Setting::AutoUpdateTimeInMinutes, uint32_t, std::chrono::minutes, 15min, \".source.autoUpdateIntervalInMinutes\"sv, ValuePolicy::SourceAutoUpdateIntervalInMinutes);\r\n        // Experimental\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::EFExperimentalCmd, bool, bool, false, \".experimentalFeatures.experimentalCmd\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::EFExperimentalArg, bool, bool, false, \".experimentalFeatures.experimentalArg\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::EFDirectMSI, bool, bool, false, \".experimentalFeatures.directMSI\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::EFResume, bool, bool, false, \".experimentalFeatures.resume\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::EFFonts, bool, bool, false, \".experimentalFeatures.fonts\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::EFSourcePriority, bool, bool, false, \".experimentalFeatures.sourcePriority\"sv);\r\n        // Telemetry\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::TelemetryDisable, bool, bool, false, \".telemetry.disable\"sv);\r\n        // Install behavior\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::InstallArchitecturePreference, std::vector<std::string>, std::vector<Utility::Architecture>, {}, \".installBehavior.preferences.architectures\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::InstallArchitectureRequirement, std::vector<std::string>, std::vector<Utility::Architecture>, {}, \".installBehavior.requirements.architectures\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::InstallScopePreference, std::string, Manifest::ScopeEnum, Manifest::ScopeEnum::User, \".installBehavior.preferences.scope\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::InstallScopeRequirement, std::string, Manifest::ScopeEnum, Manifest::ScopeEnum::Unknown, \".installBehavior.requirements.scope\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::InstallLocalePreference, std::vector<std::string>, std::vector<std::string>, {}, \".installBehavior.preferences.locale\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::InstallLocaleRequirement, std::vector<std::string>, std::vector<std::string>, {}, \".installBehavior.requirements.locale\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::InstallerTypePreference, std::vector<std::string>, std::vector<Manifest::InstallerTypeEnum>, {}, \".installBehavior.preferences.installerTypes\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::InstallerTypeRequirement, std::vector<std::string>, std::vector<Manifest::InstallerTypeEnum>, {}, \".installBehavior.requirements.installerTypes\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::InstallSkipDependencies, bool, bool, false, \".installBehavior.skipDependencies\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::ArchiveExtractionMethod, std::string, Archive::ExtractionMethod, Archive::ExtractionMethod::ShellApi, \".installBehavior.archiveExtractionMethod\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::DisableInstallNotes, bool, bool, false, \".installBehavior.disableInstallNotes\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::PortablePackageUserRoot, std::string, std::filesystem::path, {}, \".installBehavior.portablePackageUserRoot\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::PortablePackageMachineRoot, std::string, std::filesystem::path, {}, \".installBehavior.portablePackageMachineRoot\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::InstallDefaultRoot, std::string, std::filesystem::path, {}, \".installBehavior.defaultInstallRoot\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::MaxResumes, uint32_t, int, 3, \".installBehavior.maxResumes\"sv);\r\n        // Uninstall behavior\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::UninstallPurgePortablePackage, bool, bool, false, \".uninstallBehavior.purgePortablePackage\"sv);\r\n        // Download behavior\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::DownloadDefaultDirectory, std::string, std::filesystem::path, {}, \".downloadBehavior.defaultDownloadDirectory\"sv);\r\n        // Configure behavior\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::ConfigureDefaultModuleRoot, std::string, std::filesystem::path, {}, \".configureBehavior.defaultModuleRoot\"sv);\r\n\r\n        // Network\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::NetworkDownloader, std::string, InstallerDownloader, InstallerDownloader::Default, \".network.downloader\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::NetworkDOProgressTimeoutInSeconds, uint32_t, std::chrono::seconds, 60s, \".network.doProgressTimeoutInSeconds\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::NetworkWingetAlternateSourceURL, bool, bool, true, \".network.enableWingetAlternateSourceURL\"sv);\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        // Debug\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::EnableSelfInitiatedMinidump, bool, bool, false, \".debugging.enableSelfInitiatedMinidump\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::KeepAllLogFiles, bool, bool, false, \".debugging.keepAllLogFiles\"sv);\r\n#endif\r\n        // Logging\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::LoggingLevelPreference, std::string, Logging::Level, Logging::Level::Info, \".logging.level\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::LoggingChannelPreference, std::vector<std::string>, Logging::Channel, Logging::Channel::Defaults, \".logging.channels\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::LoggingFileAgeLimitInDays, uint32_t, std::chrono::hours, (7 * 24h), \".logging.file.ageLimitInDays\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::LoggingFileTotalSizeLimitInMB, uint32_t, uint32_t, 128, \".logging.file.totalSizeLimitInMB\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::LoggingFileIndividualSizeLimitInMB, uint32_t, uint32_t, 16, \".logging.file.individualSizeLimitInMB\"sv);\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::LoggingFileCountLimit, uint32_t, uint32_t, 0, \".logging.file.countLimit\"sv);\r\n        // Interactivity\r\n        SETTINGMAPPING_SPECIALIZATION(Setting::InteractivityDisable, bool, bool, false, \".interactivity.disable\"sv);\r\n        \r\n        // Used to deduce the SettingVariant type; making a variant that includes std::monostate and all SettingMapping types.\r\n        template <size_t... I>\r\n        inline auto Deduce(std::index_sequence<I...>) { return std::variant<std::monostate, typename SettingMapping<static_cast<Setting>(I)>::value_t...>{}; }\r\n\r\n        // Holds data of any type listed in a SettingMapping.\r\n        using SettingVariant = decltype(Deduce(std::make_index_sequence<static_cast<size_t>(Setting::Max)>()));\r\n\r\n        // Gets the index into the variant for the given Setting.\r\n        constexpr inline size_t SettingIndex(Setting s) { return static_cast<size_t>(s) + 1; }\r\n    }\r\n\r\n    // Representation of the parsed settings file.\r\n    struct UserSettings\r\n    {\r\n        // Jsoncpp doesn't provide line number and column for an individual Json::Value node.\r\n        struct Warning\r\n        {\r\n            Warning(StringResource::StringId message) : Message(message) {}\r\n            Warning(StringResource::StringId message, std::string_view settingPath) : Message(message), Path(settingPath) {}\r\n            Warning(StringResource::StringId message, std::string_view settingPath, std::string_view settingValue, bool isField = true) :\r\n                Message(message), Path(settingPath), Data(settingValue), IsFieldWarning(isField) {}\r\n\r\n            StringResource::StringId Message;\r\n            Utility::LocIndString Path;\r\n            Utility::LocIndString Data;\r\n            bool IsFieldWarning = true;\r\n        };\r\n\r\n        static UserSettings const& Instance(const std::optional<std::string>& content = std::nullopt);\r\n\r\n        static std::filesystem::path SettingsFilePath(bool forDisplay = false);\r\n\r\n        UserSettings(const UserSettings&) = delete;\r\n        UserSettings& operator=(const UserSettings&) = delete;\r\n\r\n        UserSettings(UserSettings&&) = delete;\r\n        UserSettings& operator=(UserSettings&&) = delete;\r\n\r\n        UserSettingsType GetType() const { return m_type; }\r\n        std::vector<Warning> const& GetWarnings() const { return m_warnings; }\r\n\r\n        void PrepareToShellExecuteFile() const;\r\n\r\n        // Gets setting value, if its not in the map it returns the default value.\r\n        template <Setting S>\r\n        typename details::SettingMapping<S>::value_t Get() const\r\n        {\r\n            auto itr = m_settings.find(S);\r\n            if (itr == m_settings.end())\r\n            {\r\n                return details::SettingMapping<S>::DefaultValue;\r\n            }\r\n\r\n            return std::get<details::SettingIndex(S)>(itr->second);\r\n        }\r\n\r\n    protected:\r\n        UserSettingsType m_type = UserSettingsType::Default;\r\n        std::vector<Warning> m_warnings;\r\n        std::map<Setting, details::SettingVariant> m_settings;\r\n\r\n        UserSettings(const std::optional<std::string>& content = std::nullopt);\r\n        ~UserSettings() = default;\r\n    };\r\n\r\n    const UserSettings* TryGetUser();\r\n    UserSettings const& User();\r\n    bool TryInitializeCustomUserSettings(std::string content);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Reboot.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"AppInstallerLogging.h\"\n#include \"AppInstallerStrings.h\"\n#include \"Public/winget/Reboot.h\"\n#include \"Public/winget/Registry.h\"\n#include <AppInstallerRuntime.h>\n#include <Windows.h>\n\nusing namespace AppInstaller::Registry;\n\nnamespace AppInstaller::Reboot\n{\n    namespace\n    {\n        constexpr std::wstring_view s_RunOnceRegistry = L\"Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\RunOnce\";\n    }\n\n#ifndef AICLI_DISABLE_TEST_HOOKS\n    static bool* s_InitiateRebootResult_TestHook_Override = nullptr;\n\n    void TestHook_SetInitiateRebootResult_Override(bool* status)\n    {\n        s_InitiateRebootResult_TestHook_Override = status;\n    }\n\n    static bool* s_RegisterForRestartResult_TestHook_Override = nullptr;\n\n    void TestHook_SetRegisterForRestartResult_Override(bool* status)\n    {\n        s_RegisterForRestartResult_TestHook_Override = status;\n    }\n#endif\n\n    bool InitiateReboot()\n    {\n#ifndef AICLI_DISABLE_TEST_HOOKS\n        if (s_InitiateRebootResult_TestHook_Override)\n        {\n            return *s_InitiateRebootResult_TestHook_Override;\n        }\n#endif\n\n        wil::unique_handle hToken;\n        TOKEN_PRIVILEGES pTokenPrivileges;\n\n        // Get a token for this process.\n        if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))\n        {\n            AICLI_LOG(Core, Error, << \"OpenProcessToken error: \" << GetLastError());\n            return false;\n        }\n\n        // Shutdown privilege must be enabled for this process. \n        if (!LookupPrivilegeValueW(NULL, SE_SHUTDOWN_NAME, &pTokenPrivileges.Privileges[0].Luid))\n        {\n            AICLI_LOG(Core, Error, << \"LookupPrivilegeValue error: \" << GetLastError());\n            return false;\n        }\n\n        pTokenPrivileges.PrivilegeCount = 1;\n        pTokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;\n\n        if (!AdjustTokenPrivileges(hToken.get(), FALSE, &pTokenPrivileges, 0, (PTOKEN_PRIVILEGES)NULL, 0))\n        {\n            AICLI_LOG(Core, Error, << \"AdjustTokenPrivilege error: \" << GetLastError());\n            return false;\n        }\n\n        AICLI_LOG(Core, Info, << \"Initiating reboot.\");\n        return ExitWindowsEx(EWX_RESTARTAPPS, SHTDN_REASON_MINOR_INSTALLATION);\n    }\n\n    bool RegisterRestartForWER(const std::string& commandLineArgs)\n    {\n#ifndef AICLI_DISABLE_TEST_HOOKS\n        if (s_RegisterForRestartResult_TestHook_Override)\n        {\n            return *s_RegisterForRestartResult_TestHook_Override;\n        }\n#endif\n\n        HRESULT result = RegisterApplicationRestart(AppInstaller::Utility::ConvertToUTF16(commandLineArgs).c_str(), 0 /* Always restart process */);\n\n        if (FAILED(result))\n        {\n            AICLI_LOG(Core, Error, << \"RegisterApplicationRestart failed with hr: \" << result);\n            return false;\n        }\n        else\n        {\n            AICLI_LOG(CLI, Info, << \"Register for restart with command line args: \" << commandLineArgs);\n            return true;\n        }\n    }\n\n    bool UnregisterRestartForWER()\n    {\n        HRESULT result = UnregisterApplicationRestart();\n        AICLI_LOG(CLI, Info, << \"Application unregistered for restart.\");\n\n        if (FAILED(result))\n        {\n            AICLI_LOG(Core, Error, << \"RegisterApplicationRestart failed with hr: \" << result);\n            return false;\n        }\n        else\n        {\n            return true;\n        }\n    }\n\n    void WriteToRunOnceRegistry(const std::string& resumeId, const std::string& commandLine)\n    {\n        THROW_HR_IF(E_UNEXPECTED, commandLine.size() > MAX_PATH);\n\n        HKEY root = AppInstaller::Runtime::IsRunningAsAdmin() ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;\n        std::wstring subKey = std::wstring{ s_RunOnceRegistry };\n        Key key = Key::OpenIfExists(root, subKey, 0, KEY_ALL_ACCESS);\n\n        if (!key)\n        {\n            key = Key::Create(root, subKey);\n        }\n\n        key.SetValue(Utility::ConvertToUTF16(\"WingetResume-\" + resumeId), Utility::ConvertToUTF16(commandLine), REG_SZ);\n        AICLI_LOG(CLI, Info, << \"Set RunOnce registry with value: \" << commandLine);\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Regex.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/Regex.h\"\r\n#include \"Public/AppInstallerErrors.h\"\r\n#include \"Public/AppInstallerLogging.h\"\r\n#include \"Public/AppInstallerLanguageUtilities.h\"\r\n\r\n#define WINGET_THROW_REGEX_ERROR_IF_FAILED(_err_,_func_) \\\r\n    if (U_FAILURE(_err_)) \\\r\n    { \\\r\n        AICLI_LOG(Core, Error, << #_func_ \" returned \" << _err_); \\\r\n        THROW_HR(APPINSTALLER_CLI_ERROR_ICU_REGEX_ERROR); \\\r\n    }\r\n\r\n\r\nnamespace AppInstaller::Regex\r\n{\r\n    struct Expression::impl\r\n    {\r\n        using uregex_ptr = wil::unique_any<URegularExpression*, decltype(uregex_close), uregex_close>;\r\n        using utext_ptr = wil::unique_any<UText*, decltype(utext_close), utext_close>;\r\n\r\n        // Create caches the original ICU regex objects in a static map and hands out copies of them\r\n        // when requested. Since we have a limited set, this is a very simple cache-all-forever pattern.\r\n        static std::unique_ptr<impl> Create(std::string_view pattern, Options options)\r\n        {\r\n            struct key\r\n            {\r\n                std::string pattern;\r\n                Options options = Options::None;\r\n\r\n                bool operator<(const key& other) const\r\n                {\r\n                    if (pattern < other.pattern)\r\n                    {\r\n                        return true;\r\n                    }\r\n                    else if (pattern == other.pattern)\r\n                    {\r\n                        return ToIntegral(options) < ToIntegral(other.options);\r\n                    }\r\n                    else\r\n                    {\r\n                        return false;\r\n                    }\r\n                }\r\n            };\r\n\r\n            struct statics\r\n            {\r\n                std::map<key, impl> map;\r\n                wil::srwlock lock;\r\n            };\r\n\r\n            static statics s_regex_cache;\r\n\r\n            key requested;\r\n            requested.pattern = pattern;\r\n            requested.options = options;\r\n\r\n            {\r\n                // Attempt to find in the cache\r\n                auto sharedLock = s_regex_cache.lock.lock_shared();\r\n\r\n                auto itr = s_regex_cache.map.find(requested);\r\n                if (itr != s_regex_cache.map.end())\r\n                {\r\n                    return std::make_unique<impl>(itr->second);\r\n                }\r\n            }\r\n\r\n            auto exclusiveLock = s_regex_cache.lock.lock_exclusive();\r\n\r\n            // Check if another thread created it while we waited for the lock.\r\n            auto itr = s_regex_cache.map.find(requested);\r\n            if (itr != s_regex_cache.map.end())\r\n            {\r\n                return std::make_unique<impl>(itr->second);\r\n            }\r\n            else\r\n            {\r\n                return std::make_unique<impl>(s_regex_cache.map.emplace(std::move(requested), impl{ pattern, options }).first->second);\r\n            }\r\n        }\r\n\r\n        impl(std::string_view pattern, Options options)\r\n        {\r\n            UErrorCode uec = U_ZERO_ERROR;\r\n\r\n            utext_ptr patternUtext{ utext_openUTF8(nullptr, pattern.data(), pattern.length(), &uec) };\r\n            WINGET_THROW_REGEX_ERROR_IF_FAILED(uec, utext_openUTF8);\r\n\r\n            // For now, just handle the one option\r\n            uint32_t flags = 0;\r\n\r\n            if (options == Options::CaseInsensitive)\r\n            {\r\n                flags = UREGEX_CASE_INSENSITIVE;\r\n            }\r\n\r\n            UParseError parseError{};\r\n\r\n            m_regex.reset(uregex_openUText(patternUtext.get(), flags, &parseError, &uec));\r\n\r\n            if (U_FAILURE(uec))\r\n            {\r\n                AICLI_LOG(Core, Error, << \"uregex_openUText failed with error [\" << uec << \"] at line \" << parseError.line << \", position \" << parseError.offset << '\\n' << pattern);\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_ICU_REGEX_ERROR);\r\n            }\r\n        }\r\n\r\n        impl(const impl& other)\r\n        {\r\n            UErrorCode uec = U_ZERO_ERROR;\r\n\r\n            m_regex.reset(uregex_clone(other.m_regex.get(), &uec));\r\n            WINGET_THROW_REGEX_ERROR_IF_FAILED(uec, uregex_clone);\r\n        }\r\n\r\n        impl& operator=(const impl& other)\r\n        {\r\n            *this = impl{ other };\r\n            return *this;\r\n        }\r\n\r\n        impl(impl&&) = default;\r\n        impl& operator=(impl&&) = default;\r\n\r\n        ~impl() = default;\r\n\r\n        bool IsMatch(std::wstring_view input) const\r\n        {\r\n            UErrorCode uec = U_ZERO_ERROR;\r\n\r\n            SetText(input);\r\n\r\n            UBool result = uregex_matches(m_regex.get(), -1, &uec);\r\n            WINGET_THROW_REGEX_ERROR_IF_FAILED(uec, uregex_matches);\r\n\r\n            return !!result;\r\n        }\r\n\r\n        std::wstring Replace(std::wstring_view input, std::wstring_view replacement) const\r\n        {\r\n            UErrorCode uec = U_ZERO_ERROR;\r\n\r\n            SetText(input);\r\n\r\n            std::u16string_view u16replacement = Convert(replacement);\r\n            utext_ptr replacementUtext{ utext_openUChars(nullptr, u16replacement.data(), u16replacement.length(), &uec) };\r\n            WINGET_THROW_REGEX_ERROR_IF_FAILED(uec, utext_openUTF8);\r\n\r\n            utext_ptr resultUText{ uregex_replaceAllUText(m_regex.get(), replacementUtext.get(), nullptr, &uec) };\r\n            WINGET_THROW_REGEX_ERROR_IF_FAILED(uec, uregex_replaceAllUText);\r\n\r\n            int64_t cch = utext_nativeLength(resultUText.get());\r\n            std::wstring result(static_cast<size_t>(cch), '\\0');\r\n\r\n            utext_extract(resultUText.get(), 0, std::numeric_limits<int64_t>::max(), reinterpret_cast<char16_t*>(&result[0]), static_cast<int32_t>(result.size()), &uec);\r\n            WINGET_THROW_REGEX_ERROR_IF_FAILED(uec, utext_extract);\r\n\r\n            return result;\r\n        }\r\n\r\n        void ForEach(std::wstring_view input, const std::function<bool(bool, std::wstring_view)>&f) const\r\n        {\r\n            UErrorCode uec = U_ZERO_ERROR;\r\n\r\n            SetText(input);\r\n            int32_t startPos = 0;\r\n\r\n            while (uregex_findNext(m_regex.get(), &uec))\r\n            {\r\n                WINGET_THROW_REGEX_ERROR_IF_FAILED(uec, uregex_findNext);\r\n\r\n                int32_t pos = uregex_start(m_regex.get(), 0, &uec);\r\n                WINGET_THROW_REGEX_ERROR_IF_FAILED(uec, uregex_start);\r\n                THROW_HR_IF(E_UNEXPECTED, pos == -1);\r\n\r\n                // First, send off the unmatched part before the match\r\n                if (pos > startPos)\r\n                {\r\n                    if (!f(false, input.substr(startPos, static_cast<size_t>(pos) - startPos)))\r\n                    {\r\n                        return;\r\n                    }\r\n                }\r\n\r\n                // Now send the matched part\r\n                int32_t end = uregex_end(m_regex.get(), 0, &uec);\r\n                WINGET_THROW_REGEX_ERROR_IF_FAILED(uec, uregex_end);\r\n                THROW_HR_IF(E_UNEXPECTED, end == -1);\r\n\r\n                if (!f(true, input.substr(pos, static_cast<size_t>(end) - pos)))\r\n                {\r\n                    return;\r\n                }\r\n\r\n                startPos = end;\r\n            }\r\n\r\n            WINGET_THROW_REGEX_ERROR_IF_FAILED(uec, uregex_findNext);\r\n\r\n            // Finally, send any remaining part\r\n            if (input.length() > static_cast<size_t>(startPos))\r\n            {\r\n                f(false, input.substr(startPos));\r\n            }\r\n        }\r\n\r\n    private:\r\n        static std::u16string_view Convert(std::wstring_view input)\r\n        {\r\n            static_assert(sizeof(wchar_t) == sizeof(char16_t), \"wchar_t and char16_t must be the same size\");\r\n            return { reinterpret_cast<const char16_t*>(input.data()), input.size() };\r\n        }\r\n\r\n        void SetText(std::wstring_view input) const\r\n        {\r\n            UErrorCode uec = U_ZERO_ERROR;\r\n\r\n            std::u16string_view u16 = Convert(input);\r\n\r\n            uregex_setText(m_regex.get(), u16.data(), static_cast<int32_t>(u16.length()), &uec);\r\n            WINGET_THROW_REGEX_ERROR_IF_FAILED(uec, uregex_setText);\r\n        }\r\n\r\n        uregex_ptr m_regex;\r\n    };\r\n\r\n    Expression::Expression() = default;\r\n\r\n    Expression::Expression(std::string_view pattern, Options options) : pImpl(impl::Create(pattern, options)) {}\r\n\r\n    Expression::Expression(const Expression& other)\r\n    {\r\n        if (other.pImpl)\r\n        {\r\n            pImpl = std::make_unique<impl>(*other.pImpl);\r\n        }\r\n    }\r\n\r\n    Expression& Expression::operator=(const Expression& other)\r\n    {\r\n        return *this = Expression{ other };\r\n    }\r\n\r\n    Expression::Expression(Expression&&) noexcept = default;\r\n    Expression& Expression::operator=(Expression&&) noexcept = default;\r\n\r\n    Expression::~Expression() = default;\r\n\r\n    Expression::operator bool() const\r\n    {\r\n        return static_cast<bool>(pImpl);\r\n    }\r\n\r\n    bool Expression::IsMatch(std::wstring_view input) const\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !pImpl);\r\n        return pImpl->IsMatch(input);\r\n    }\r\n\r\n    std::wstring Expression::Replace(std::wstring_view input, std::wstring_view replacement) const\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !pImpl);\r\n        return pImpl->Replace(input, replacement);\r\n    }\r\n\r\n    void Expression::ForEach(std::wstring_view input, const std::function<bool(bool, std::wstring_view)>& f) const\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !pImpl);\r\n        return pImpl->ForEach(input, f);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Rest.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"AppInstallerStrings.h\"\r\n#include \"winget/Rest.h\"\r\n#include <winget/JsonUtil.h>\r\n\r\nnamespace AppInstaller::Rest\r\n{\r\n    utility::string_t GetRestAPIBaseUri(std::string uri)\r\n    {\r\n        // Trim\r\n        if (!uri.empty())\r\n        {\r\n            uri = AppInstaller::Utility::Trim(uri);\r\n\r\n            // Remove trailing forward slash\r\n            if (uri.back() == '/')\r\n            {\r\n                uri.pop_back();\r\n            }\r\n        }\r\n\r\n        // Encode the Uri\r\n        return web::uri::encode_uri(JSON::GetUtilityString(uri));\r\n    }\r\n\r\n    bool IsValidUri(const utility::string_t& restApiUri)\r\n    {\r\n        return web::uri::validate(restApiUri);\r\n    }\r\n\r\n    utility::string_t AppendPathToUri(const utility::string_t& restApiUri, const utility::string_t& path)\r\n    {\r\n        web::uri_builder builder(restApiUri);\r\n        builder.append_path(path, true);\r\n        return builder.to_string();\r\n    }\r\n\r\n    utility::string_t MakeQueryParam(std::string_view queryName, const std::string& queryValue)\r\n    {\r\n        std::string queryParam;\r\n        queryParam.append(queryName).append(\"=\").append(queryValue);\r\n\r\n        return utility::conversions::to_string_t(queryParam);\r\n    }\r\n\r\n    utility::string_t AppendQueryParamsToUri(const utility::string_t& uri, const std::map<std::string_view, std::string>& queryParameters)\r\n    {\r\n        web::http::uri_builder builder{ uri };\r\n\r\n        for (auto& pair : queryParameters)\r\n        {\r\n            builder.append_query(MakeQueryParam(pair.first, pair.second), true);\r\n        }\r\n\r\n        return builder.to_string();\r\n    }\r\n\r\n    std::vector<std::string> GetUniqueItems(const std::vector<std::string>& list)\r\n    {\r\n        std::set<std::string> set;\r\n        for (const auto& item : list)\r\n        {\r\n            set.emplace(item);\r\n        }\r\n\r\n        std::vector<std::string> result{ set.begin(), set.end() };\r\n        return result;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Runtime.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include <binver/version.h>\r\n#include \"Public/AppInstallerLogging.h\"\r\n#include \"Public/AppInstallerRuntime.h\"\r\n#include \"Public/AppInstallerStrings.h\"\r\n#include \"Public/winget/UserSettings.h\"\r\n#include \"Public/winget/Registry.h\"\r\n#include <winget/Filesystem.h>\r\n\r\n\r\n#define WINGET_DEFAULT_LOG_DIRECTORY \"DiagOutputDir\"\r\n\r\nnamespace AppInstaller::Runtime\r\n{\r\n    using namespace Utility;\r\n    using namespace Settings;\r\n    using namespace Filesystem;\r\n\r\n    namespace\r\n    {\r\n        using namespace std::string_view_literals;\r\n        constexpr std::string_view s_DefaultTempDirectory = \"WinGet\"sv;\r\n        constexpr std::string_view s_SettingsFile_Relative = \"Settings\"sv;\r\n        constexpr std::string_view s_SecureSettings_Base = \"Microsoft\\\\WinGet\"sv;\r\n        constexpr std::string_view s_SecureSettings_UserRelative = \"settings\"sv;\r\n        constexpr std::string_view s_SecureSettings_Relative_Unpackaged = \"win\"sv;\r\n        constexpr std::string_view s_PortablePackageUserRoot_Base = \"Microsoft\"sv;\r\n        constexpr std::string_view s_PortablePackageRoot = \"WinGet\"sv;\r\n        constexpr std::string_view s_PortablePackagesDirectory = \"Packages\"sv;\r\n        constexpr std::string_view s_LinksDirectory = \"Links\"sv;\r\n        constexpr std::string_view s_FontsInstallDirectory = \"Microsoft\\\\Windows\\\\Fonts\"sv;\r\n        constexpr std::string_view s_ConfigurationModulesDirectory = \"Configuration\\\\Modules\"sv;\r\n// Use production CLSIDs as a surrogate for repository location.\r\n#if USE_PROD_CLSIDS\r\n        constexpr std::string_view s_ImageAssetsDirectoryRelative = \"Assets\\\\WinGet\"sv;\r\n#else\r\n        constexpr std::string_view s_ImageAssetsDirectoryRelative = \"Images\"sv;\r\n#endif\r\n        constexpr std::string_view s_CheckpointsDirectory = \"Checkpoints\"sv;\r\n        constexpr std::string_view s_DevModeSubkey = \"SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\AppModelUnlock\"sv;\r\n        constexpr std::string_view s_AllowDevelopmentWithoutDevLicense = \"AllowDevelopmentWithoutDevLicense\"sv;\r\n#ifndef WINGET_DISABLE_FOR_FUZZING\r\n        constexpr std::string_view s_SecureSettings_Relative_Packaged = \"pkg\"sv;\r\n#endif\r\n        constexpr std::string_view s_RuntimePath_Unpackaged_DefaultState = \"defaultState\"sv;\r\n\r\n        constexpr std::string_view s_UserProfileEnvironmentVariable = \"%USERPROFILE%\";\r\n        constexpr std::string_view s_LocalAppDataEnvironmentVariable = \"%LOCALAPPDATA%\";\r\n        constexpr std::string_view s_WindowsApps_Base = \"Microsoft\\\\WindowsApps\"sv;\r\n        constexpr std::string_view s_WinGetDev_Exe = \"wingetdev.exe\";\r\n        constexpr std::string_view s_WinGet_Exe = \"winget.exe\";\r\n        constexpr std::string_view s_WinGetMCPDev_Exe = \"WindowsPackageManagerMCPServerDev.exe\";\r\n        constexpr std::string_view s_WinGetMCP_Exe = \"WindowsPackageManagerMCPServer.exe\";\r\n\r\n        static std::optional<std::string> s_runtimePathStateName;\r\n        static wil::srwlock s_runtimePathStateNameLock;\r\n\r\n        // Gets the path to the root of the package containing the current process.\r\n        std::filesystem::path GetPackagePath()\r\n        {\r\n            wchar_t packageFullName[PACKAGE_FULL_NAME_MAX_LENGTH + 1];\r\n            UINT32 nameLength = ARRAYSIZE(packageFullName);\r\n            THROW_IF_WIN32_ERROR(GetPackageFullName(GetCurrentProcess(), &nameLength, packageFullName));\r\n\r\n            UINT32 pathLength = 0;\r\n            LONG result = GetPackagePathByFullName(packageFullName, &pathLength, nullptr);\r\n            THROW_HR_IF(HRESULT_FROM_WIN32(result), result != ERROR_INSUFFICIENT_BUFFER);\r\n\r\n            std::unique_ptr<wchar_t[]> buffer = std::make_unique<wchar_t[]>(pathLength);\r\n            THROW_IF_WIN32_ERROR(GetPackagePathByFullName(packageFullName, &pathLength, buffer.get()));\r\n\r\n            return { buffer.get() };\r\n        }\r\n\r\n        // Gets the path to the directory containing the currently executing binary file.\r\n        std::filesystem::path GetBinaryDirectoryPath()\r\n        {\r\n            HMODULE moduleHandle = NULL;\r\n            THROW_IF_WIN32_BOOL_FALSE(GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,\r\n                (LPCWSTR)&GetBinaryDirectoryPath, &moduleHandle));\r\n\r\n            // Get the path for this module.\r\n            wil::unique_process_heap_string binaryPath;\r\n            THROW_IF_FAILED(wil::GetModuleFileNameW(moduleHandle, binaryPath));\r\n\r\n            std::filesystem::path resultFilePath{ binaryPath.get() };\r\n            return resultFilePath.parent_path();\r\n        }\r\n\r\n        std::unique_ptr<byte[]> GetPACKAGE_ID()\r\n        {\r\n            UINT32 bufferLength = 0;\r\n            LONG gcpiResult = GetCurrentPackageId(&bufferLength, nullptr);\r\n            THROW_HR_IF(E_UNEXPECTED, gcpiResult != ERROR_INSUFFICIENT_BUFFER);\r\n\r\n            std::unique_ptr<byte[]> buffer = std::make_unique<byte[]>(bufferLength);\r\n\r\n            gcpiResult = GetCurrentPackageId(&bufferLength, buffer.get());\r\n            if (FAILED_WIN32_LOG(gcpiResult))\r\n            {\r\n                return {};\r\n            }\r\n\r\n            return buffer;\r\n        }\r\n\r\n        // Gets the package name; only succeeds if running in a packaged context.\r\n        std::string GetPackageName()\r\n        {\r\n            std::unique_ptr<byte[]> buffer = GetPACKAGE_ID();\r\n            if (!buffer)\r\n            {\r\n                return {};\r\n            }\r\n\r\n            PACKAGE_ID* packageId = reinterpret_cast<PACKAGE_ID*>(buffer.get());\r\n            return Utility::ConvertToUTF8(packageId->name);\r\n        }\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        static std::map<PathName, PathDetails> s_Path_TestHook_Overrides;\r\n#endif\r\n\r\n        // Gets the user's temp path\r\n        std::filesystem::path GetPathToUserTemp(bool forDisplay)\r\n        {\r\n            if (forDisplay && Settings::User().Get<Setting::AnonymizePathForDisplay>())\r\n            {\r\n                return \"%TEMP%\";\r\n            }\r\n            else\r\n            {\r\n                wchar_t tempPath[MAX_PATH + 1];\r\n                DWORD tempChars = GetTempPathW(ARRAYSIZE(tempPath), tempPath);\r\n                THROW_LAST_ERROR_IF(!tempChars);\r\n                THROW_HR_IF(E_UNEXPECTED, tempChars > ARRAYSIZE(tempPath));\r\n                return { std::wstring_view{ tempPath, static_cast<size_t>(tempChars) } };\r\n            }\r\n        }\r\n\r\n        // Gets the current user's SID for use in paths.\r\n        std::filesystem::path GetUserSID()\r\n        {\r\n            auto userToken = wil::get_token_information<TOKEN_USER>();\r\n\r\n            wil::unique_hlocal_string sidString;\r\n            THROW_IF_WIN32_BOOL_FALSE(ConvertSidToStringSidW(userToken->User.Sid, &sidString));\r\n            return { sidString.get() };\r\n        }\r\n\r\n        std::string GetRuntimePathStateName()\r\n        {\r\n            std::string result;\r\n            auto lock = s_runtimePathStateNameLock.lock_shared();\r\n\r\n            if (s_runtimePathStateName.has_value())\r\n            {\r\n                result = s_runtimePathStateName.value();\r\n            }\r\n\r\n            if (Utility::IsEmptyOrWhitespace(result))\r\n            {\r\n                result = s_RuntimePath_Unpackaged_DefaultState;\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n\r\n    void SetRuntimePathStateName(std::string name)\r\n    {\r\n        auto suitablePathPart = MakeSuitablePathPart(name);\r\n        auto lock = s_runtimePathStateNameLock.lock_exclusive();\r\n        s_runtimePathStateName.emplace(std::move(suitablePathPart));\r\n    }\r\n\r\n    // Contains all of the paths that are common between the runtime contexts.\r\n    PathDetails GetPathDetailsCommon(PathName path, bool forDisplay)\r\n    {\r\n        PathDetails result;\r\n        // We should not create directories by default when they are retrieved for display purposes.\r\n        result.Create = !forDisplay;\r\n\r\n        bool mayBeInProfilePath = false;\r\n\r\n        switch (path)\r\n        {\r\n        case PathName::UserProfile:\r\n            result.Path = (forDisplay && Settings::User().Get<Setting::AnonymizePathForDisplay>()) ? s_UserProfileEnvironmentVariable : GetKnownFolderPath(FOLDERID_Profile);\r\n            result.Create = false;\r\n            break;\r\n        case PathName::PortablePackageUserRoot:\r\n            result.Path = Settings::User().Get<Setting::PortablePackageUserRoot>();\r\n            if (result.Path.empty())\r\n            {\r\n                result.Path = GetKnownFolderPath(FOLDERID_LocalAppData);\r\n                result.Path /= s_PortablePackageUserRoot_Base;\r\n                result.Path /= s_PortablePackageRoot;\r\n                result.Path /= s_PortablePackagesDirectory;\r\n            }\r\n            mayBeInProfilePath = true;\r\n            break;\r\n        case PathName::PortablePackageMachineRoot:\r\n            result.Path = Settings::User().Get<Setting::PortablePackageMachineRoot>();\r\n            if (result.Path.empty())\r\n            {\r\n                result.Path = GetKnownFolderPath(FOLDERID_ProgramFiles);\r\n                result.Path /= s_PortablePackageRoot;\r\n                result.Path /= s_PortablePackagesDirectory;\r\n            }\r\n            break;\r\n        case PathName::PortablePackageMachineRootX86:\r\n            result.Path = Settings::User().Get<Setting::PortablePackageMachineRoot>();\r\n            if (result.Path.empty())\r\n            {\r\n                result.Path = GetKnownFolderPath(FOLDERID_ProgramFilesX86);\r\n                result.Path /= s_PortablePackageRoot;\r\n                result.Path /= s_PortablePackagesDirectory;\r\n            }\r\n            break;\r\n        case PathName::PortableLinksUserLocation:\r\n            result.Path = GetKnownFolderPath(FOLDERID_LocalAppData);\r\n            result.Path /= s_PortablePackageUserRoot_Base;\r\n            result.Path /= s_PortablePackageRoot;\r\n            result.Path /= s_LinksDirectory;\r\n            mayBeInProfilePath = true;\r\n            break;\r\n        case PathName::PortableLinksMachineLocation:\r\n            result.Path = GetKnownFolderPath(FOLDERID_ProgramFiles);\r\n            result.Path /= s_PortablePackageRoot;\r\n            result.Path /= s_LinksDirectory;\r\n            break;\r\n        case PathName::UserProfileDownloads:\r\n            result.Path = GetKnownFolderPath(FOLDERID_Downloads);\r\n            mayBeInProfilePath = true;\r\n            break;\r\n        case PathName::FontsUserInstallLocation:\r\n            result.Path = GetKnownFolderPath(FOLDERID_LocalAppData);\r\n            result.Path /= s_FontsInstallDirectory;\r\n            mayBeInProfilePath = true;\r\n            break;\r\n        case PathName::FontsMachineInstallLocation:\r\n            result.Path = GetKnownFolderPath(FOLDERID_Fonts);\r\n            break;\r\n        case PathName::ConfigurationModules:\r\n            result.Path = Settings::User().Get<Setting::ConfigureDefaultModuleRoot>();\r\n            if (result.Path.empty())\r\n            {\r\n                result.Path = GetKnownFolderPath(FOLDERID_LocalAppData);\r\n                result.Path /= s_SecureSettings_Base;\r\n                result.Path /= s_ConfigurationModulesDirectory;\r\n            }\r\n            mayBeInProfilePath = true;\r\n            break;\r\n        default:\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n\r\n        if (mayBeInProfilePath && forDisplay && Settings::User().Get<Setting::AnonymizePathForDisplay>())\r\n        {\r\n            ReplaceProfilePathsWithEnvironmentVariable(result.Path);\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n#ifndef WINGET_DISABLE_FOR_FUZZING\r\n    PathDetails GetPathDetailsForPackagedContext(PathName path, bool forDisplay)\r\n    {\r\n        PathDetails result;\r\n        // We should not create directories by default when they are retrieved for display purposes.\r\n        result.Create = !forDisplay;\r\n\r\n        auto appStorage = winrt::Windows::Storage::ApplicationData::Current();\r\n        bool mayBeInProfilePath = false;\r\n\r\n        switch (path)\r\n        {\r\n        case PathName::Temp:\r\n            result.Path = GetPathToUserTemp(forDisplay) / s_DefaultTempDirectory;\r\n            result.SetOwner(ACEPrincipal::CurrentUser);\r\n            result.ACL[ACEPrincipal::System] = ACEPermissions::All;\r\n            result.ACL[ACEPrincipal::Admins] = ACEPermissions::All;\r\n            break;\r\n        case PathName::LocalState:\r\n        case PathName::UserFileSettings:\r\n            result.Path.assign(appStorage.LocalFolder().Path().c_str());\r\n            mayBeInProfilePath = true;\r\n            break;\r\n        case PathName::StandardFileSettings:\r\n            result.Path.assign(appStorage.LocalFolder().Path().c_str());\r\n            result.Path /= s_SettingsFile_Relative;\r\n            mayBeInProfilePath = true;\r\n            break;\r\n        case PathName::DefaultLogLocation:\r\n            // To enable UIF collection through Feedback hub, we must put our logs here.\r\n            result.Path.assign(appStorage.LocalFolder().Path().c_str());\r\n            result.Path /= WINGET_DEFAULT_LOG_DIRECTORY;\r\n            mayBeInProfilePath = true;\r\n            break;\r\n        case PathName::StandardSettings:\r\n            result.Create = false;\r\n            break;\r\n        case PathName::SecureSettingsForRead:\r\n        case PathName::SecureSettingsForWrite:\r\n            result.Path = GetKnownFolderPath(FOLDERID_ProgramData);\r\n            result.Path /= s_SecureSettings_Base;\r\n            result.Path /= GetUserSID();\r\n            result.Path /= s_SecureSettings_UserRelative;\r\n            result.Path /= s_SecureSettings_Relative_Packaged;\r\n            result.Path /= GetPackageName();\r\n            if (path == PathName::SecureSettingsForWrite)\r\n            {\r\n                result.SetOwner(ACEPrincipal::Admins);\r\n                // When running as system, we do not set current user permissions to avoid permission conflicts.\r\n                if (!IsRunningAsSystem())\r\n                {\r\n                    result.ACL[ACEPrincipal::CurrentUser] = ACEPermissions::ReadExecute;\r\n                }\r\n                result.ACL[ACEPrincipal::System] = ACEPermissions::All;\r\n            }\r\n            else\r\n            {\r\n                result.Create = false;\r\n            }\r\n            break;\r\n        case PathName::UserProfile:\r\n        case PathName::PortablePackageMachineRoot:\r\n        case PathName::PortablePackageMachineRootX86:\r\n        case PathName::PortableLinksMachineLocation:\r\n        case PathName::PortableLinksUserLocation:\r\n        case PathName::PortablePackageUserRoot:\r\n        case PathName::UserProfileDownloads:\r\n        case PathName::FontsUserInstallLocation:\r\n        case PathName::FontsMachineInstallLocation:\r\n        case PathName::ConfigurationModules:\r\n            result = GetPathDetailsCommon(path, forDisplay);\r\n            break;\r\n        case PathName::SelfPackageRoot:\r\n        case PathName::ImageAssets:\r\n            result.Path = GetPackagePath();\r\n            result.Create = false;\r\n            if (path == PathName::ImageAssets)\r\n            {\r\n                result.Path /= s_ImageAssetsDirectoryRelative;\r\n            }\r\n            break;\r\n        case PathName::CheckpointsLocation:\r\n            result = GetPathDetailsForPackagedContext(PathName::LocalState, forDisplay);\r\n            result.Path /= s_CheckpointsDirectory;\r\n            break;\r\n        case PathName::CLIExecutable:\r\n        case PathName::MCPExecutable:\r\n            result.Path = GetKnownFolderPath(FOLDERID_LocalAppData);\r\n            result.Path /= s_WindowsApps_Base;\r\n            result.Path /= GetPackageFamilyName();\r\n\r\n            if (path == PathName::CLIExecutable)\r\n            {\r\n#if USE_PROD_CLSIDS\r\n                result.Path /= s_WinGet_Exe;\r\n#else\r\n                result.Path /= s_WinGetDev_Exe;\r\n#endif\r\n            }\r\n            else if (path == PathName::MCPExecutable)\r\n            {\r\n#if USE_PROD_CLSIDS\r\n                result.Path /= s_WinGetMCP_Exe;\r\n#else\r\n                result.Path /= s_WinGetMCPDev_Exe;\r\n#endif\r\n            }\r\n\r\n            result.Create = false;\r\n            mayBeInProfilePath = true;\r\n            break;\r\n        default:\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n\r\n        if (mayBeInProfilePath && forDisplay && Settings::User().Get<Setting::AnonymizePathForDisplay>())\r\n        {\r\n            ReplaceProfilePathsWithEnvironmentVariable(result.Path);\r\n        }\r\n\r\n        return result;\r\n    }\r\n#endif\r\n\r\n    PathDetails GetPathDetailsForUnpackagedContext(PathName path, bool forDisplay)\r\n    {\r\n        PathDetails result;\r\n        // We should not create directories by default when they are retrieved for display purposes.\r\n        result.Create = !forDisplay;\r\n        bool anonymize = forDisplay && Settings::User().Get<Setting::AnonymizePathForDisplay>();\r\n\r\n        switch (path)\r\n        {\r\n        case PathName::Temp:\r\n        case PathName::DefaultLogLocation:\r\n        {\r\n            result.Path = GetPathToUserTemp(forDisplay);\r\n            result.Path /= s_DefaultTempDirectory;\r\n            result.Path /= GetRuntimePathStateName();\r\n            if (path == PathName::Temp)\r\n            {\r\n                result.SetOwner(ACEPrincipal::CurrentUser);\r\n                result.ACL[ACEPrincipal::System] = ACEPermissions::All;\r\n                result.ACL[ACEPrincipal::Admins] = ACEPermissions::All;\r\n            }\r\n        }\r\n        break;\r\n        case PathName::LocalState:\r\n            result = Filesystem::GetPathDetailsFor(Filesystem::PathName::UnpackagedLocalStateRoot, anonymize);\r\n            result.Create = !forDisplay;\r\n            result.Path /= GetRuntimePathStateName();\r\n            break;\r\n        case PathName::StandardSettings:\r\n        case PathName::StandardFileSettings:\r\n        case PathName::UserFileSettings:\r\n            result = Filesystem::GetPathDetailsFor(Filesystem::PathName::UnpackagedSettingsRoot, anonymize);\r\n            result.Create = !forDisplay;\r\n            result.Path /= GetRuntimePathStateName();\r\n            break;\r\n        case PathName::SecureSettingsForRead:\r\n        case PathName::SecureSettingsForWrite:\r\n            result.Path = GetKnownFolderPath(FOLDERID_ProgramData);\r\n            result.Path /= s_SecureSettings_Base;\r\n            result.Path /= GetUserSID();\r\n            result.Path /= s_SecureSettings_UserRelative;\r\n            result.Path /= s_SecureSettings_Relative_Unpackaged;\r\n            result.Path /= GetRuntimePathStateName();\r\n            if (path == PathName::SecureSettingsForWrite)\r\n            {\r\n                result.SetOwner(ACEPrincipal::Admins);\r\n                // When running as system, we do not set current user permissions to avoid permission conflicts.\r\n                if (!IsRunningAsSystem())\r\n                {\r\n                    result.ACL[ACEPrincipal::CurrentUser] = ACEPermissions::ReadExecute;\r\n                }\r\n                result.ACL[ACEPrincipal::System] = ACEPermissions::All;\r\n            }\r\n            else\r\n            {\r\n                result.Create = false;\r\n            }\r\n            break;\r\n        case PathName::UserProfile:\r\n        case PathName::PortablePackageMachineRoot:\r\n        case PathName::PortablePackageMachineRootX86:\r\n        case PathName::PortableLinksMachineLocation:\r\n        case PathName::PortableLinksUserLocation:\r\n        case PathName::PortablePackageUserRoot:\r\n        case PathName::UserProfileDownloads:\r\n        case PathName::FontsUserInstallLocation:\r\n        case PathName::FontsMachineInstallLocation:\r\n        case PathName::ConfigurationModules:\r\n            result = GetPathDetailsCommon(path, forDisplay);\r\n            break;\r\n        case PathName::SelfPackageRoot:\r\n        case PathName::CLIExecutable:\r\n        case PathName::MCPExecutable:\r\n        case PathName::ImageAssets:\r\n            result.Path = GetBinaryDirectoryPath();\r\n            result.Create = false;\r\n            if (path == PathName::CLIExecutable)\r\n            {\r\n                result.Path /= s_WinGet_Exe;\r\n            }\r\n            else if (path == PathName::MCPExecutable)\r\n            {\r\n                result.Path /= s_WinGetMCP_Exe;\r\n            }\r\n            else if (path == PathName::ImageAssets)\r\n            {\r\n                result.Path /= s_ImageAssetsDirectoryRelative;\r\n                if (!std::filesystem::is_directory(result.Path))\r\n                {\r\n                    result.Path.clear();\r\n                }\r\n            }\r\n            break;\r\n        case PathName::CheckpointsLocation:\r\n            result = GetPathDetailsForUnpackagedContext(PathName::LocalState, forDisplay);\r\n            result.Path /= s_CheckpointsDirectory;\r\n            break;\r\n        default:\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    PathDetails GetPathDetailsFor(PathName path, bool forDisplay)\r\n    {\r\n        PathDetails result;\r\n\r\n#ifndef WINGET_DISABLE_FOR_FUZZING\r\n        if (IsRunningInPackagedContext())\r\n        {\r\n            result = GetPathDetailsForPackagedContext(path, forDisplay);\r\n        }\r\n        else\r\n#endif\r\n        {\r\n            result = GetPathDetailsForUnpackagedContext(path, forDisplay);\r\n        }\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        // Override the value after letting the normal code path run\r\n        auto itr = s_Path_TestHook_Overrides.find(path);\r\n        if (itr != s_Path_TestHook_Overrides.end())\r\n        {\r\n            result = itr->second;\r\n        }\r\n#endif\r\n\r\n        return result;\r\n    }\r\n\r\n    // Try to replace LOCALAPPDATA first as it is the likely location, fall back to trying USERPROFILE.\r\n    void ReplaceProfilePathsWithEnvironmentVariable(std::filesystem::path& path)\r\n    {\r\n        if (!ReplaceCommonPathPrefix(path, GetKnownFolderPath(FOLDERID_LocalAppData), s_LocalAppDataEnvironmentVariable))\r\n        {\r\n            ReplaceCommonPathPrefix(path, GetKnownFolderPath(FOLDERID_Profile), s_UserProfileEnvironmentVariable);\r\n        }\r\n    }\r\n\r\n    std::filesystem::path GetNewTempFilePath()\r\n    {\r\n        GUID guid;\r\n        THROW_IF_FAILED(CoCreateGuid(&guid));\r\n        WCHAR tempFileName[256];\r\n        THROW_HR_IF(E_UNEXPECTED, StringFromGUID2(guid, tempFileName, ARRAYSIZE(tempFileName)) == 0);\r\n        auto tempFilePath = Runtime::GetPathTo(Runtime::PathName::Temp);\r\n        tempFilePath /= tempFileName;\r\n\r\n        return tempFilePath;\r\n    }\r\n\r\n    // Determines whether developer mode is enabled.\r\n    // Does not account for the group policy value which takes precedence over this registry value.\r\n    bool IsDevModeEnabled()\r\n    {\r\n        const auto& devModeSubKey = Registry::Key::OpenIfExists(HKEY_LOCAL_MACHINE, s_DevModeSubkey, 0, KEY_READ|KEY_WOW64_64KEY);\r\n        const auto& devModeEnabled = devModeSubKey[s_AllowDevelopmentWithoutDevLicense];\r\n        if (devModeEnabled.has_value())\r\n        {\r\n            return devModeEnabled->GetValue<Registry::Value::Type::DWord>() == 1;\r\n        }\r\n        else\r\n        {\r\n            return false;\r\n        }\r\n    }\r\n\r\n    // Using \"standard\" user agent format\r\n    // Keeping `winget-cli` for historical reasons\r\n    Utility::LocIndString GetDefaultUserAgent()\r\n    {\r\n        std::ostringstream strstr;\r\n        strstr <<\r\n            \"winget-cli\" <<\r\n            \" WindowsPackageManager/\" << GetClientVersion() <<\r\n            \" DesktopAppInstaller/\" << GetPackageVersion();\r\n        return Utility::LocIndString{ strstr.str() };\r\n    }\r\n\r\n    Utility::LocIndString GetUserAgent(std::string_view caller)\r\n    {\r\n        auto escapedCaller = winrt::Windows::Foundation::Uri::EscapeComponent(Utility::ConvertToUTF16(caller));\r\n\r\n        std::ostringstream strstr;\r\n        strstr <<\r\n            Utility::ConvertToUTF8(escapedCaller) <<\r\n            \" WindowsPackageManager/\" << GetClientVersion() <<\r\n            \" DesktopAppInstaller/\" << GetPackageVersion();\r\n        return Utility::LocIndString{ strstr.str() };\r\n    }\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n    void TestHook_SetPathOverride(PathName target, const std::filesystem::path& path)\r\n    {\r\n        if (s_Path_TestHook_Overrides.count(target))\r\n        {\r\n            s_Path_TestHook_Overrides[target].Path = path;\r\n        }\r\n        else\r\n        {\r\n            PathDetails details = GetPathDetailsFor(target);\r\n            details.Path = path;\r\n            s_Path_TestHook_Overrides[target] = std::move(details);\r\n        }\r\n    }\r\n\r\n    void TestHook_SetPathOverride(PathName target, const PathDetails& details)\r\n    {\r\n        s_Path_TestHook_Overrides[target] = details;\r\n    }\r\n\r\n    void TestHook_ClearPathOverrides()\r\n    {\r\n        s_Path_TestHook_Overrides.clear();\r\n    }\r\n#endif\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/SelfManagement.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"winget/ExperimentalFeature.h\"\r\n#include \"winget/SelfManagement.h\"\r\n#include \"AppInstallerRuntime.h\"\r\n\r\nnamespace AppInstaller::SelfManagement\r\n{\r\n    using namespace AppInstaller::Settings;\r\n    using namespace std::string_view_literals;\r\n    using namespace winrt::Windows::ApplicationModel;\r\n    using namespace winrt::Windows::Management::Deployment;\r\n    using namespace winrt::Windows::Services::Store;\r\n\r\n    // Always use AppInstaller's package family name for wingetdev\r\n    static constexpr std::wstring_view s_AppInstallerPfn = L\"Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\"sv;\r\n    constexpr std::wstring_view s_RemoteServerFileName = L\"DotNet\\\\ConfigurationRemotingServer.exe\";\r\n\r\n    bool IsStubPreferred()\r\n    {\r\n        winrt::hstring packageFamilyName{ s_AppInstallerPfn };\r\n\r\n        PackageManager packageManager;\r\n        auto packageManager9 = packageManager.try_as<IPackageManager9>();\r\n\r\n        if (!packageManager9)\r\n        {\r\n            // If the API isn't present, then the only option is full package.\r\n            return false;\r\n        }\r\n\r\n        auto preference = packageManager9.GetPackageStubPreference(packageFamilyName);\r\n\r\n        return preference == PackageStubPreference::Stub;\r\n    }\r\n\r\n    void SetStubPreferred(bool preferStub)\r\n    {\r\n        winrt::hstring packageFamilyName{ s_AppInstallerPfn };\r\n\r\n        PackageManager packageManager;\r\n        auto packageManager9 = packageManager.try_as<IPackageManager9>();\r\n\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_OLD_WIN_VERSION), !packageManager9);\r\n\r\n        packageManager9.SetPackageStubPreference(packageFamilyName, preferStub ? PackageStubPreference::Stub : PackageStubPreference::Full);\r\n    }\r\n\r\n    bool IsStubPackage()\r\n    {\r\n        // The right way to do it is to call FindPackage APIs from PackageManager, but that requires admin.\r\n        std::filesystem::path serverPath = Runtime::GetPathTo(Runtime::PathName::SelfPackageRoot) / s_RemoteServerFileName;\r\n        return !std::filesystem::exists(serverPath);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Settings.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/Settings.h\"\r\n#include \"Public/AppInstallerLogging.h\"\r\n#include \"Public/AppInstallerRuntime.h\"\r\n#include \"Public/AppInstallerStrings.h\"\r\n#include \"Public/AppInstallerSHA256.h\"\r\n#include \"Public/winget/Yaml.h\"\r\n\r\nnamespace AppInstaller::Settings\r\n{\r\n    using namespace std::string_view_literals;\r\n    using namespace Runtime;\r\n    using namespace Utility;\r\n\r\n    namespace\r\n    {\r\n        void ValidateSettingNamePath(const std::filesystem::path& name)\r\n        {\r\n            THROW_HR_IF(E_INVALIDARG, !name.has_relative_path());\r\n            THROW_HR_IF(E_INVALIDARG, name.has_root_path());\r\n            THROW_HR_IF(E_INVALIDARG, !name.has_filename());\r\n        }\r\n\r\n        void LogSettingAction(std::string_view action, const StreamDefinition& def)\r\n        {\r\n            AICLI_LOG(Core, Verbose, << \"Setting action: \" << action << \", Type: \" << ToString(def.Type) << \", Name: \" << def.Name);\r\n        }\r\n\r\n#ifndef WINGET_DISABLE_FOR_FUZZING\r\n        // A settings container backed by the ApplicationDataContainer functionality.\r\n        struct ApplicationDataSettingsContainer : public details::ISettingsContainer\r\n        {\r\n            using Container = winrt::Windows::Storage::ApplicationDataContainer;\r\n\r\n            ApplicationDataSettingsContainer(const Container& container, const std::filesystem::path& name)\r\n            {\r\n                m_parentContainer = GetRelativeContainer(container, name.parent_path());\r\n                m_settingName = winrt::to_hstring(name.filename().c_str());\r\n            }\r\n\r\n            static Container GetRelativeContainer(const Container& container, const std::filesystem::path& offset)\r\n            {\r\n                auto result = container;\r\n\r\n                for (const auto& part : offset)\r\n                {\r\n                    auto partHstring = winrt::to_hstring(part.c_str());\r\n                    result = result.CreateContainer(partHstring, winrt::Windows::Storage::ApplicationDataCreateDisposition::Always);\r\n                }\r\n\r\n                return result;\r\n            }\r\n\r\n            std::unique_ptr<std::istream> Get() override\r\n            {\r\n                auto settingsValues = m_parentContainer.Values();\r\n                if (settingsValues.HasKey(m_settingName))\r\n                {\r\n                    auto value = winrt::unbox_value<winrt::hstring>(settingsValues.Lookup(m_settingName));\r\n                    return std::make_unique<std::istringstream>(Utility::ConvertToUTF8(value.c_str()));\r\n                }\r\n                else\r\n                {\r\n                    return {};\r\n                }\r\n            }\r\n\r\n            bool Set(std::string_view value) override\r\n            {\r\n                m_parentContainer.Values().Insert(m_settingName, winrt::box_value(winrt::to_hstring(value)));\r\n                return true;\r\n            }\r\n\r\n            void Remove() override\r\n            {\r\n                m_parentContainer.Values().Remove(m_settingName);\r\n            }\r\n\r\n            std::filesystem::path PathTo() override\r\n            {\r\n                THROW_HR(E_UNEXPECTED);\r\n            }\r\n\r\n        private:\r\n            Container m_parentContainer = nullptr;\r\n            winrt::hstring m_settingName;\r\n        };\r\n#endif\r\n\r\n        // A settings container backed by the filesystem.\r\n        struct FileSettingsContainer : public details::ISettingsContainer\r\n        {\r\n            FileSettingsContainer(std::filesystem::path root, const std::filesystem::path& name) : m_settingFile(std::move(root))\r\n            {\r\n                m_settingFile /= name;\r\n            }\r\n\r\n            std::unique_ptr<std::istream> Get() override\r\n            {\r\n                if (std::filesystem::exists(m_settingFile))\r\n                {\r\n                    auto result = std::make_unique<std::ifstream>(m_settingFile, std::ios_base::in | std::ios_base::binary);\r\n                    THROW_LAST_ERROR_IF(result->fail());\r\n                    return result;\r\n                }\r\n                else\r\n                {\r\n                    return {};\r\n                }\r\n            }\r\n\r\n            bool Set(std::string_view value) override\r\n            {\r\n                EnsureParentPath();\r\n\r\n                std::ofstream stream(m_settingFile, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);\r\n                THROW_LAST_ERROR_IF(stream.fail());\r\n                stream << value << std::flush;\r\n                THROW_LAST_ERROR_IF(stream.fail());\r\n\r\n                return true;\r\n            }\r\n\r\n            void Remove() override\r\n            {\r\n                std::filesystem::remove(m_settingFile);\r\n            }\r\n\r\n            std::filesystem::path PathTo() override\r\n            {\r\n                return m_settingFile;\r\n            }\r\n\r\n        private:\r\n            void EnsureParentPath()\r\n            {\r\n                std::filesystem::create_directories(m_settingFile.parent_path());\r\n            }\r\n\r\n            std::filesystem::path m_settingFile;\r\n        };\r\n\r\n        // A settings container that manages safely writing to its value with exchange semantics.\r\n        // Only allows Set to succeed if the hash value of the setting is the same as the last time it was read.\r\n        struct ExchangeSettingsContainer : public details::ISettingsContainer\r\n        {\r\n            ExchangeSettingsContainer(std::unique_ptr<ISettingsContainer>&& container, const std::string_view& name) :\r\n                m_container(std::move(container)), m_name(name) {}\r\n\r\n            std::unique_ptr<std::istream> Get() override\r\n            {\r\n                return GetInternal(m_hash);\r\n            }\r\n\r\n            bool Set(std::string_view value) override\r\n            {\r\n                THROW_HR_IF(E_UNEXPECTED, value.size() > std::numeric_limits<uint32_t>::max());\r\n\r\n                // If Set is called without ever reading the value, then we can assume that caller wants\r\n                // to overwrite it regardless. Also, we don't have any previous value to compare against\r\n                // anyway so the only other option would be to always reject it.\r\n                if (m_hash)\r\n                {\r\n                    std::optional<SHA256::HashBuffer> currentHash;\r\n                    std::ignore = GetInternal(currentHash);\r\n\r\n                    if (currentHash && !SHA256::AreEqual(m_hash.value(), currentHash.value()))\r\n                    {\r\n                        AICLI_LOG(Core, Verbose, << \"Setting value for '\" << m_name << \"' has changed since last read; rejecting Set\");\r\n                        return false;\r\n                    }\r\n                }\r\n\r\n                SHA256::HashBuffer newHash = SHA256::ComputeHash(reinterpret_cast<const uint8_t*>(value.data()), static_cast<uint32_t>(value.size()));\r\n                if (m_container->Set(value))\r\n                {\r\n                    m_hash = std::move(newHash);\r\n                    return true;\r\n                }\r\n                else\r\n                {\r\n                    return false;\r\n                }\r\n            }\r\n\r\n            void Remove() override\r\n            {\r\n                m_container->Remove();\r\n                m_hash.reset();\r\n            }\r\n\r\n            std::filesystem::path PathTo() override\r\n            {\r\n                return m_container->PathTo();\r\n            }\r\n\r\n        protected:\r\n            std::optional<std::string> GetAsString()\r\n            {\r\n                return GetAsStringInternal(m_hash);\r\n            }\r\n\r\n            std::string_view m_name;\r\n            std::optional<SHA256::HashBuffer> m_hash;\r\n\r\n        private:\r\n            std::optional<std::string> GetAsStringInternal(std::optional<SHA256::HashBuffer>& hashStorage)\r\n            {\r\n                std::unique_ptr<std::istream> stream = m_container->Get();\r\n\r\n                if (!stream)\r\n                {\r\n                    // If no stream exists, then no hashing needs to be done.\r\n                    // Return an empty hash vector to indicate the attempted read but no result.\r\n                    hashStorage.emplace();\r\n                    return std::nullopt;\r\n                }\r\n\r\n                std::string streamContents = Utility::ReadEntireStream(*stream);\r\n                THROW_HR_IF(E_UNEXPECTED, streamContents.size() > std::numeric_limits<uint32_t>::max());\r\n\r\n                hashStorage = SHA256::ComputeHash(reinterpret_cast<const uint8_t*>(streamContents.c_str()), static_cast<uint32_t>(streamContents.size()));\r\n\r\n                return streamContents;\r\n            }\r\n\r\n            std::unique_ptr<std::istream> GetInternal(std::optional<SHA256::HashBuffer>& hashStorage)\r\n            {\r\n                auto string = GetAsStringInternal(hashStorage);\r\n\r\n                // Return a stream over the contents that we read in and hashed, to prevent a race.\r\n                return string ? std::make_unique<std::istringstream>(string.value()) : nullptr;\r\n            }\r\n\r\n            std::unique_ptr<ISettingsContainer> m_container;\r\n        };\r\n\r\n        // A settings container wrapper that enforces security.\r\n        struct SecureSettingsContainer : public ExchangeSettingsContainer\r\n        {\r\n            constexpr static std::string_view NodeName_Sha256 = \"SHA256\"sv;\r\n\r\n            SecureSettingsContainer(std::unique_ptr<ISettingsContainer>&& container, const std::string_view& name) :\r\n                ExchangeSettingsContainer(std::move(container), name), m_secure(GetPathTo(PathName::SecureSettingsForRead), name) {}\r\n\r\n        private:\r\n            struct VerificationData\r\n            {\r\n                bool Found = false;\r\n                SHA256::HashBuffer Hash;\r\n            };\r\n\r\n            VerificationData GetVerificationData()\r\n            {\r\n                std::unique_ptr<std::istream> stream = m_secure.Get();\r\n\r\n                if (!stream)\r\n                {\r\n                    return {};\r\n                }\r\n\r\n                std::string streamContents = Utility::ReadEntireStream(*stream);\r\n\r\n                YAML::Node document;\r\n                try\r\n                {\r\n                    document = YAML::Load(streamContents);\r\n                }\r\n                catch (const std::runtime_error& e)\r\n                {\r\n                    AICLI_LOG(Core, Error, << \"Secure setting metadata for '\" << m_name << \"' contained invalid YAML (\" << e.what() << \"):\\n\" << streamContents);\r\n                    return {};\r\n                }\r\n\r\n                std::string hashString;\r\n\r\n                try\r\n                {\r\n                    hashString = document[NodeName_Sha256].as<std::string>();\r\n                }\r\n                catch (const std::runtime_error& e)\r\n                {\r\n                    AICLI_LOG(Core, Error, << \"Secure setting metadata for '\" << m_name << \"' contained invalid YAML (\" << e.what() << \"):\\n\" << streamContents);\r\n                    return {};\r\n                }\r\n\r\n                VerificationData result;\r\n                result.Found = true;\r\n                result.Hash = SHA256::ConvertToBytes(hashString);\r\n\r\n                return result;\r\n            }\r\n\r\n            void SetVerificationData(VerificationData data)\r\n            {\r\n                YAML::Emitter out;\r\n                out << YAML::BeginMap;\r\n                out << YAML::Key << NodeName_Sha256 << YAML::Value << SHA256::ConvertToString(data.Hash);\r\n                out << YAML::EndMap;\r\n\r\n                m_secure.Set(out.str());\r\n            }\r\n\r\n        public:\r\n            std::unique_ptr<std::istream> Get() override\r\n            {\r\n                std::unique_ptr<std::istream> stream = ExchangeSettingsContainer::Get();\r\n\r\n                if (!stream)\r\n                {\r\n                    // If no stream exists, then no verification needs to be done.\r\n                    return stream;\r\n                }\r\n\r\n                VerificationData verData = GetVerificationData();\r\n\r\n                // This case should be very rare, so a very identifiable error is helpful.\r\n                // Plus the text for this one is fairly on point for what has happened.\r\n                THROW_HR_IF(SPAPI_E_FILE_HASH_NOT_IN_CATALOG, !verData.Found);\r\n\r\n                THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_DATA_CHECKSUM_ERROR), !SHA256::AreEqual(m_hash.value(), verData.Hash));\r\n\r\n                // ExchangeSettingsContainer already produces an in memory stream that we can use.\r\n                return stream;\r\n            }\r\n\r\n            bool Set(std::string_view value) override\r\n            {\r\n                // Force the creation of the secure settings location with appropriate ACLs\r\n                GetPathTo(PathName::SecureSettingsForWrite);\r\n\r\n                bool exchangeResult = ExchangeSettingsContainer::Set(value);\r\n\r\n                if (exchangeResult)\r\n                {\r\n                    VerificationData verData;\r\n                    verData.Hash = m_hash.value();\r\n\r\n                    SetVerificationData(verData);\r\n                }\r\n\r\n                return exchangeResult;\r\n            }\r\n\r\n            void Remove() override\r\n            {\r\n                ExchangeSettingsContainer::Remove();\r\n                m_secure.Remove();\r\n            }\r\n\r\n            std::filesystem::path PathTo() override\r\n            {\r\n                THROW_HR(E_UNEXPECTED);\r\n            }\r\n\r\n        private:\r\n            FileSettingsContainer m_secure;\r\n        };\r\n\r\n        // A settings container wrapper that enforces privacy.\r\n        struct EncryptedSettingsContainer : public ExchangeSettingsContainer\r\n        {\r\n            EncryptedSettingsContainer(std::unique_ptr<ISettingsContainer>&& container, const std::string_view& name) :\r\n                ExchangeSettingsContainer(std::move(container), name) {\r\n            }\r\n\r\n            std::unique_ptr<std::istream> Get() override\r\n            {\r\n                std::optional<std::string> stream = ExchangeSettingsContainer::GetAsString();\r\n\r\n                if (!stream)\r\n                {\r\n                    // If no stream exists, then nothing needs to be done.\r\n                    return nullptr;\r\n                }\r\n\r\n                DATA_BLOB data{};\r\n                data.pbData = reinterpret_cast<BYTE*>(stream->data());\r\n                data.cbData = static_cast<DWORD>(stream->size());\r\n\r\n                DATA_BLOB out{};\r\n                auto freeOut = wil::scope_exit([&]() { LocalFree(out.pbData); });\r\n\r\n                THROW_IF_WIN32_BOOL_FALSE(CryptUnprotectData(&data, NULL, NULL, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN, &out));\r\n\r\n                return std::make_unique<std::istringstream>(std::string{ reinterpret_cast<char*>(out.pbData), out.cbData });\r\n            }\r\n\r\n            bool Set(std::string_view value) override\r\n            {\r\n                DATA_BLOB data{};\r\n                data.pbData = reinterpret_cast<BYTE*>(const_cast<char*>(value.data()));\r\n                data.cbData = static_cast<DWORD>(value.size());\r\n\r\n                DATA_BLOB out{};\r\n                auto freeOut = wil::scope_exit([&]() { LocalFree(out.pbData); });\r\n\r\n                THROW_IF_WIN32_BOOL_FALSE(CryptProtectData(&data, NULL, NULL, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN, &out));\r\n\r\n                return ExchangeSettingsContainer::Set(std::string_view{ reinterpret_cast<char*>(out.pbData), out.cbData });\r\n            }\r\n\r\n            std::filesystem::path PathTo() override\r\n            {\r\n                THROW_HR(E_UNEXPECTED);\r\n            }\r\n        };\r\n\r\n        std::unique_ptr<details::ISettingsContainer> GetRawSettingsContainer(Type type, const std::string_view& name)\r\n        {\r\n#ifndef WINGET_DISABLE_FOR_FUZZING\r\n            if (IsRunningInPackagedContext())\r\n            {\r\n                switch (type)\r\n                {\r\n                case Type::Standard:\r\n                    return std::make_unique<ApplicationDataSettingsContainer>(\r\n                        ApplicationDataSettingsContainer::GetRelativeContainer(\r\n                            winrt::Windows::Storage::ApplicationData::Current().LocalSettings(), GetPathTo(PathName::StandardSettings)),\r\n                        name);\r\n                case Type::StandardFile:\r\n                    return std::make_unique<FileSettingsContainer>(GetPathTo(PathName::StandardFileSettings), name);\r\n                default:\r\n                    THROW_HR(E_UNEXPECTED);\r\n                }\r\n            }\r\n            else\r\n#endif\r\n            {\r\n                switch (type)\r\n                {\r\n                case Type::Standard:\r\n                case Type::StandardFile:\r\n                    return std::make_unique<FileSettingsContainer>(GetPathTo(PathName::StandardSettings), name);\r\n                default:\r\n                    THROW_HR(E_UNEXPECTED);\r\n                }\r\n            }\r\n        }\r\n\r\n        // The default is not a raw container, so we wrap some of the underlying containers to enable higher order behaviors.\r\n        std::unique_ptr<details::ISettingsContainer> GetSettingsContainer(Type type, const std::string_view& name)\r\n        {\r\n            switch (type)\r\n            {\r\n            case Type::Standard:\r\n                // Standard settings should use exchange semantics to prevent overwrites\r\n                return std::make_unique<ExchangeSettingsContainer>(GetRawSettingsContainer(type, name), name);\r\n\r\n            case Type::UserFile:\r\n                // User file settings are not typically modified by us, so there is no need for exchange\r\n                return std::make_unique<FileSettingsContainer>(GetPathTo(PathName::UserFileSettings), name);\r\n\r\n            case Type::Secure:\r\n                // Secure settings add hash verification on reads on top of exchange semantics\r\n                return std::make_unique<SecureSettingsContainer>(GetRawSettingsContainer(Type::Standard, name), name);\r\n\r\n            case Type::Encrypted:\r\n                // Encrypted settings add encryption on top of exchange semantics\r\n                return std::make_unique<EncryptedSettingsContainer>(GetRawSettingsContainer(Type::StandardFile, name), name);\r\n\r\n            case Type::StandardFile:\r\n                // Standard settings should use exchange semantics to prevent overwrites\r\n                return std::make_unique<ExchangeSettingsContainer>(GetRawSettingsContainer(type, name), name);\r\n\r\n            default:\r\n                THROW_HR(E_UNEXPECTED);\r\n            }\r\n        }\r\n\r\n        std::unique_ptr<details::ISettingsContainer> GetSettingsContainer(const StreamDefinition& streamDefinition)\r\n        {\r\n            return GetSettingsContainer(streamDefinition.Type, streamDefinition.Name);\r\n        }\r\n    }\r\n\r\n    std::string_view ToString(Type type)\r\n    {\r\n        switch (type)\r\n        {\r\n        case Type::Standard:\r\n            return \"Standard\"sv;\r\n        case Type::UserFile:\r\n            return \"UserFile\"sv;\r\n        case Type::Secure:\r\n            return \"Secure\"sv;\r\n        case Type::Encrypted:\r\n            return \"Encrypted\"sv;\r\n        case Type::StandardFile:\r\n            return \"StandardFile\"sv;\r\n        default:\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n    }\r\n\r\n    Stream::Stream(const StreamDefinition& streamDefinition) :\r\n        m_streamDefinition(streamDefinition), m_container(GetSettingsContainer(streamDefinition))\r\n    {\r\n        ValidateSettingNamePath(m_streamDefinition.Name);\r\n    }\r\n\r\n    std::unique_ptr<std::istream> Stream::Get()\r\n    {\r\n        LogSettingAction(\"Get\", m_streamDefinition);\r\n        return m_container->Get();\r\n    }\r\n\r\n    [[nodiscard]] bool Stream::Set(std::string_view value)\r\n    {\r\n        LogSettingAction(\"Set\", m_streamDefinition);\r\n        return m_container->Set(value);\r\n    }\r\n\r\n    void Stream::Remove()\r\n    {\r\n        LogSettingAction(\"Remove\", m_streamDefinition);\r\n        m_container->Remove();\r\n    }\r\n\r\n    std::string_view Stream::GetName() const\r\n    {\r\n        return m_streamDefinition.Name;\r\n    }\r\n\r\n    std::filesystem::path Stream::GetPath() const\r\n    {\r\n        return m_container->PathTo();\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/StdErrLogger.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"winget/StdErrLogger.h\"\r\n\r\nnamespace AppInstaller::Logging\r\n{\r\n    namespace\r\n    {\r\n        static constexpr std::string_view s_StdErrLoggerName = \"StdErrLogger\";\r\n    }\r\n\r\n    std::string StdErrLogger::GetName() const\r\n    {\r\n        return std::string{ s_StdErrLoggerName };\r\n    }\r\n\r\n    void StdErrLogger::Write(Channel channel, Level level, std::string_view message) noexcept try\r\n    {\r\n        if (level >= m_level)\r\n        {\r\n            std::cerr << \"[\" << std::setw(GetMaxChannelNameLength()) << std::left << std::setfill(' ') << GetChannelName(channel) << \"] \" << message << std::endl;\r\n        }\r\n    }\r\n    catch (...)\r\n    {\r\n        // Just eat any exceptions here; better than losing logs\r\n    }\r\n\r\n    void StdErrLogger::WriteDirect(Channel, Level level, std::string_view message) noexcept try\r\n    {\r\n        if (level >= m_level)\r\n        {\r\n            std::cerr.write(message.data(), static_cast<std::streamsize>(message.size()));\r\n        }\r\n    }\r\n    catch (...)\r\n    {\r\n        // Just eat any exceptions here; better than losing logs\r\n    }\r\n\r\n    void StdErrLogger::Add()\r\n    {\r\n        Log().AddLogger(std::make_unique<StdErrLogger>());\r\n    }\r\n\r\n    void StdErrLogger::Remove()\r\n    {\r\n        Log().RemoveLogger(std::string{ s_StdErrLoggerName });\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Synchronization.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include <AppInstallerSynchronization.h>\r\n#include <AppInstallerStrings.h>\r\n\r\n\r\nnamespace AppInstaller::Synchronization\r\n{\r\n    // The amount of time that we wait in between checking for cancellation\r\n    constexpr std::chrono::milliseconds s_CrossProcessInstallLock_WaitLoopTime = 250ms;\r\n\r\n    CrossProcessLock::CrossProcessLock(std::string_view name) : CrossProcessLock(Utility::ConvertToUTF16(name))\r\n    {\r\n    }\r\n\r\n    CrossProcessLock::CrossProcessLock(const std::wstring& name)\r\n    {\r\n        m_mutex.create(name.c_str(), 0, SYNCHRONIZE);\r\n    }\r\n\r\n    CrossProcessLock::~CrossProcessLock()\r\n    {\r\n        Release();\r\n    }\r\n\r\n    bool CrossProcessLock::Acquire(IProgressCallback& progress)\r\n    {\r\n        while (!progress.IsCancelledBy(CancelReason::Any))\r\n        {\r\n            auto lock = m_mutex.acquire(nullptr, static_cast<DWORD>(std::chrono::duration_cast<std::chrono::milliseconds>(s_CrossProcessInstallLock_WaitLoopTime).count()));\r\n\r\n            if (lock)\r\n            {\r\n                m_lockThreadId = GetCurrentThreadId();\r\n                m_lock = std::move(lock);\r\n                return true;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    void CrossProcessLock::Release()\r\n    {\r\n        if (m_lock)\r\n        {\r\n            // Ensure that we are in fact always releasing on the same thread that acquired the lock.\r\n            // This is to force crashes rather than deadlocks in the event that we make a design error that leads to that.\r\n            FAIL_FAST_IF(m_lockThreadId != GetCurrentThreadId());\r\n            m_lock.reset();\r\n        }\r\n    }\r\n\r\n    bool CrossProcessLock::TryAcquireNoWait()\r\n    {\r\n        auto lock = m_mutex.acquire(nullptr, 0);\r\n\r\n        if (lock)\r\n        {\r\n            m_lockThreadId = GetCurrentThreadId();\r\n            m_lock = std::move(lock);\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    CrossProcessLock::operator bool() const\r\n    {\r\n        return static_cast<bool>(m_lock);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Telemetry/TraceLogging.cpp",
    "content": "﻿// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project root for license information.\n\n#include \"pch.h\"\n#include \"TraceLogging.h\"\n\n// GUID for Microsoft.PackageManager.Client : {c0cf606f-569b-5c20-27d9-88a745fa2175}\nTRACELOGGING_DEFINE_PROVIDER(\n    g_hTraceProvider,\n    \"Microsoft.PackageManager.Client\",\n    (0xc0cf606f, 0x569b, 0x5c20, 0x27, 0xd9, 0x88, 0xa7, 0x45, 0xfa, 0x21, 0x75),\n    TraceLoggingOptionMicrosoftTelemetry());\n\nbool g_IsTelemetryProviderEnabled{};\nUCHAR g_TelemetryProviderLevel{};\nULONGLONG g_TelemetryProviderMatchAnyKeyword{};\n\nstruct TraceProvider\n{\n    TraceProvider();\n\n    ~TraceProvider();\n};\n\nTraceProvider g_TraceProvider{};\n\nvoid WINAPI TelemetryProviderEnabledCallback(\n    _In_      LPCGUID /*sourceId*/,\n    _In_      ULONG isEnabled,\n    _In_      UCHAR level,\n    _In_      ULONGLONG matchAnyKeyword,\n    _In_      ULONGLONG /*matchAllKeywords*/,\n    _In_opt_  PEVENT_FILTER_DESCRIPTOR /*filterData*/,\n    _In_opt_  PVOID /*callbackContext*/)\n{\n    g_IsTelemetryProviderEnabled = !!isEnabled;\n    g_TelemetryProviderLevel = level;\n    g_TelemetryProviderMatchAnyKeyword = matchAnyKeyword;\n}\n\nTraceProvider::TraceProvider()\n{\n    TraceLoggingRegisterEx(g_hTraceProvider, TelemetryProviderEnabledCallback, nullptr);\n}\n\nTraceProvider::~TraceProvider()\n{\n    TraceLoggingUnregister(g_hTraceProvider);\n}\n"
  },
  {
    "path": "src/AppInstallerCommonCore/Telemetry/TraceLogging.h",
    "content": "﻿// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project root for license information.\n\n#pragma once\n\n#include <Telemetry/WinEventLogLevels.h>\n#include <TraceLoggingProvider.h>\n\n#include <Telemetry/MicrosoftTelemetry.h>\n\n// Keywords\n#define KEYWORD_REPEATER         0x0000000000000001\n#define KEYWORD_SCROLLER         0x0000000000000002\n#define KEYWORD_PTR              0x0000000000000004\n#define KEYWORD_SCROLLVIEWER     0x0000000000000008\n#define KEYWORD_SWIPECONTROL     0x0000000000000010\n#define KEYWORD_COMMANDBARFLYOUT 0x0000000000000020\n\n// Common output formats\n#define TRACE_MSG_METH L\"%s[0x%p]()\\n\"\n#define TRACE_MSG_METH_DBL L\"%s[0x%p](%lf)\\n\"\n#define TRACE_MSG_METH_DBL_DBL L\"%s[0x%p](%lf, %lf)\\n\"\n#define TRACE_MSG_METH_DBL_INT L\"%s[0x%p](%lf, %d)\\n\"\n#define TRACE_MSG_METH_DBL_DBL_INT L\"%s[0x%p](%lf, %lf, %d)\\n\"\n#define TRACE_MSG_METH_DBL_DBL_FLT L\"%s[0x%p](%lf, %lf, %f)\\n\"\n#define TRACE_MSG_METH_DBL_DBL_STR L\"%s[0x%p](%lf, %lf, %s)\\n\"\n#define TRACE_MSG_METH_FLT L\"%s[0x%p](%f)\\n\"\n#define TRACE_MSG_METH_FLT_FLT L\"%s[0x%p](%f, %f)\\n\"\n#define TRACE_MSG_METH_FLT_FLT_FLT L\"%s[0x%p](%f, %f, %f)\\n\"\n#define TRACE_MSG_METH_FLT_FLT_FLT_FLT L\"%s[0x%p](%f, %f, %f, %f)\\n\"\n#define TRACE_MSG_METH_FLT_FLT_STR_INT L\"%s[0x%p](%f, %f, %s, %d)\\n\"\n#define TRACE_MSG_METH_INT L\"%s[0x%p](%d)\\n\"\n#define TRACE_MSG_METH_INT_INT L\"%s[0x%p](%d, %d)\\n\"\n#define TRACE_MSG_METH_PTR L\"%s[0x%p](0x%p)\\n\"\n#define TRACE_MSG_METH_PTR_PTR L\"%s[0x%p](0x%p, 0x%p)\\n\"\n#define TRACE_MSG_METH_PTR_DBL L\"%s[0x%p](0x%p, %lf)\\n\"\n#define TRACE_MSG_METH_PTR_INT L\"%s[0x%p](0x%p, %d)\\n\"\n#define TRACE_MSG_METH_PTR_STR L\"%s[0x%p](0x%p, %s)\\n\"\n#define TRACE_MSG_METH_STR L\"%s[0x%p](%s)\\n\"\n#define TRACE_MSG_METH_STR_STR L\"%s[0x%p](%s, %s)\\n\"\n#define TRACE_MSG_METH_STR_DBL L\"%s[0x%p](%s, %lf)\\n\"\n#define TRACE_MSG_METH_STR_FLT L\"%s[0x%p](%s, %f)\\n\"\n#define TRACE_MSG_METH_STR_INT L\"%s[0x%p](%s, %d)\\n\"\n#define TRACE_MSG_METH_STR_STR_STR L\"%s[0x%p](%s, %s, %s)\\n\"\n#define TRACE_MSG_METH_STR_INT_INT L\"%s[0x%p](%s, %d, %d)\\n\"\n#define TRACE_MSG_METH_STR_FLT_FLT L\"%s[0x%p](%s, %f, %f)\\n\"\n#define TRACE_MSG_METH_STR_STR_FLT L\"%s[0x%p](%s, %s, %f)\\n\"\n#define TRACE_MSG_METH_STR_STR_INT_INT L\"%s[0x%p](%s, %s, %d, %d)\\n\"\n\n#define TRACE_MSG_METH_METH L\"%s[0x%p] - calls %s()\\n\"\n#define TRACE_MSG_METH_METH_INT L\"%s[0x%p] - calls %s(%d)\\n\"\n#define TRACE_MSG_METH_METH_STR L\"%s[0x%p] - calls %s(%s)\\n\"\n#define TRACE_MSG_METH_METH_STR_STR L\"%s[0x%p] - calls %s(%s, %s)\\n\"\n#define TRACE_MSG_METH_METH_FLT_STR L\"%s[0x%p] - calls %s(%f, %s)\\n\"\n#define TRACE_MSG_METH_METH_FLT_FLT_FLT L\"%s[0x%p] - calls %s(%f, %f, %f)\\n\"\n\n// Current method name\n#define METH_NAME StringUtil::Utf8ToUtf16(__FUNCTION__).c_str()\n\n// TraceLogging provider name for telemetry.\n#define TELEMETRY_PROVIDER_NAME \"Microsoft.PackageManager.Client\"\n\nTRACELOGGING_DECLARE_PROVIDER(g_hTraceProvider);\nextern bool g_IsTelemetryProviderEnabled;\nextern UCHAR g_TelemetryProviderLevel;\nextern ULONGLONG g_TelemetryProviderMatchAnyKeyword;"
  },
  {
    "path": "src/AppInstallerCommonCore/ThreadGlobals.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/ThreadGlobals.h\"\r\n\r\nnamespace AppInstaller::ThreadLocalStorage\r\n{\r\n    using namespace AppInstaller::Logging;\r\n\r\n    WingetThreadGlobals::WingetThreadGlobals(WingetThreadGlobals& parent, create_sub_thread_globals_t)\r\n    {\r\n        parent.Initialize();\r\n        m_pDiagnosticLogger = parent.m_pDiagnosticLogger;\r\n        m_pTelemetryLogger = parent.m_pTelemetryLogger->CreateSubTraceLogger();\r\n        // Flip the initialization flag\r\n        std::call_once(m_loggerInitOnceFlag, []() {});\r\n    }\r\n\r\n    DiagnosticLogger& WingetThreadGlobals::GetDiagnosticLogger()\r\n    {\r\n        return *(m_pDiagnosticLogger);\r\n    }\r\n\r\n    void* WingetThreadGlobals::GetTelemetryObject()\r\n    {\r\n        return m_pTelemetryLogger.get();\r\n    }\r\n\r\n    TelemetryTraceLogger& WingetThreadGlobals::GetTelemetryLogger()\r\n    {\r\n        return *(m_pTelemetryLogger);\r\n    }\r\n\r\n    std::unique_ptr<PreviousThreadGlobals> WingetThreadGlobals::SetForCurrentThread()\r\n    {\r\n        Initialize();\r\n        return ThreadGlobals::SetForCurrentThread();\r\n    }\r\n\r\n    void WingetThreadGlobals::Initialize()\r\n    {\r\n        try\r\n        {\r\n            std::call_once(m_loggerInitOnceFlag, [this]()\r\n                {\r\n                    m_pDiagnosticLogger = std::make_unique<DiagnosticLogger>();\r\n                    m_pTelemetryLogger = std::make_unique<TelemetryTraceLogger>();\r\n\r\n                    // The above make_unique for TelemetryTraceLogger will either create an object or will throw which is caught below.\r\n                    m_pTelemetryLogger->Initialize();\r\n                });\r\n        }\r\n        catch (...)\r\n        {\r\n            // May throw std::system_error if any condition prevents calls to call_once from executing as specified\r\n            // May throw std::bad_alloc or any exception thrown by the constructor of TelemetryTraceLogger\r\n            // Loggers are best effort and shouldn't block core functionality. So eat up the exceptions here\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/TraceLogger.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/TraceLogger.h\"\r\n#include \"Public/AppInstallerTelemetry.h\"\r\n#include \"Public/winget/ThreadGlobals.h\"\r\n\r\nnamespace AppInstaller::Logging\r\n{\r\n    void TraceLogger::Write(Channel channel, Level, std::string_view message) noexcept try\r\n    {\r\n        // Send to a string first to create a single block to log to a trace.\r\n        std::stringstream strstr;\r\n        strstr << std::chrono::system_clock::now() << \" [\" << std::setw(GetMaxChannelNameLength()) << std::left << std::setfill(' ') << GetChannelName(channel) << \"] \" << message << std::endl;\r\n\r\n        TraceLoggingWriteActivity(g_hTraceProvider,\r\n            \"Diagnostics\",\r\n            Telemetry().GetActivityId(),\r\n            Telemetry().GetParentActivityId(),\r\n            TraceLoggingString(strstr.str().c_str(), \"LogMessage\"));\r\n    }\r\n    catch (...)\r\n    {\r\n        // Just eat any exceptions here; better to lose logs than functionality\r\n    }\r\n\r\n    void TraceLogger::WriteDirect(Channel, Level, std::string_view message) noexcept try\r\n    {\r\n        TraceLoggingWriteActivity(g_hTraceProvider,\r\n            \"Diagnostics\",\r\n            Telemetry().GetActivityId(),\r\n            Telemetry().GetParentActivityId(),\r\n            TraceLoggingCountedUtf8String(message.data(), static_cast<ULONG>(message.size()), \"LogMessage\"));\r\n    }\r\n    catch (...)\r\n    {\r\n        // Just eat any exceptions here; better to lose logs than functionality\r\n    }\r\n\r\n    std::string TraceLogger::GetName() const\r\n    {\r\n        return \"Trace\";\r\n    }\r\n\r\n    void TraceLogger::Add()\r\n    {\r\n        Log().AddLogger(std::make_unique<TraceLogger>());\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/UserSettings.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"AppInstallerRuntime.h\"\r\n#include \"AppInstallerLanguageUtilities.h\"\r\n#include \"AppInstallerLogging.h\"\r\n#include \"winget/JsonUtil.h\"\r\n#include \"winget/Settings.h\"\r\n#include \"winget/UserSettings.h\"\r\n#include \"winget/filesystem.h\"\r\n\r\n#include \"AppInstallerArchitecture.h\"\r\n#include \"winget/Locale.h\"\r\n\r\nnamespace AppInstaller::Settings\r\n{\r\n    using namespace std::string_view_literals;\r\n    using namespace Runtime;\r\n    using namespace Utility;\r\n    using namespace Logging;\r\n    using namespace JSON;\r\n    using namespace Filesystem;\r\n\r\n    static constexpr std::string_view s_SettingEmpty =\r\n        R\"({\r\n    \"$schema\": \"https://aka.ms/winget-settings.schema.json\",\r\n\r\n    // For documentation on these settings, see: https://aka.ms/winget-settings\r\n    // \"source\": {\r\n    //    \"autoUpdateIntervalInMinutes\": 5\r\n    // },\r\n})\"sv;\r\n\r\n    namespace\r\n    {\r\n        template<class T>\r\n        inline std::string GetValueString(T value)\r\n        {\r\n            std::string convertedValue;\r\n\r\n            if constexpr (std::is_arithmetic_v<T>)\r\n            {\r\n                convertedValue = std::to_string(value);\r\n            }\r\n            else\r\n            {\r\n                convertedValue = value;\r\n            }\r\n\r\n            return convertedValue;\r\n        }\r\n\r\n        template<>\r\n        inline std::string GetValueString(std::vector<std::string> value)\r\n        {\r\n            std::string convertedValue = \"[\";\r\n\r\n            bool first = true;\r\n            for (auto const& entry : value)\r\n            {\r\n                if (first)\r\n                {\r\n                    first = false;\r\n                }\r\n                else\r\n                {\r\n                    convertedValue += \", \";\r\n                }\r\n\r\n                convertedValue += entry;\r\n            }\r\n\r\n            convertedValue += ']';\r\n\r\n            return convertedValue;\r\n        }\r\n\r\n        std::optional<Json::Value> ParseSettingsContent(const std::string& content, std::string_view settingName, std::vector<UserSettings::Warning>& warnings)\r\n        {\r\n            Json::Value root;\r\n            Json::CharReaderBuilder builder;\r\n            const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());\r\n            std::string error;\r\n\r\n            if (reader->parse(content.c_str(), content.c_str() + content.size(), &root, &error))\r\n            {\r\n                return root;\r\n            }\r\n\r\n            AICLI_LOG(Core, Error, << \"Error parsing \" << settingName << \": \" << error);\r\n            warnings.emplace_back(StringResource::String::SettingsWarningParseError, settingName, error, false);\r\n\r\n            return {};\r\n        }\r\n\r\n        std::optional<Json::Value> ParseFile(const StreamDefinition& setting, std::vector<UserSettings::Warning>& warnings)\r\n        {\r\n            try\r\n            {\r\n                auto stream = Stream{ setting }.Get();\r\n                if (stream)\r\n                {\r\n                    std::string settingsContentStr = Utility::ReadEntireStream(*stream);\r\n                    return ParseSettingsContent(settingsContentStr, setting.Name, warnings);\r\n                }\r\n            }\r\n            catch (const std::exception& e)\r\n            {\r\n                AICLI_LOG(Core, Error, << \"Failed to read \" << setting.Name << \"; Reason: \" << e.what());\r\n            }\r\n            catch (...)\r\n            {\r\n                AICLI_LOG(Core, Error, << \"Failed to read \" << setting.Name << \"; Reason unknown.\");\r\n            }\r\n\r\n            return {};\r\n        }\r\n\r\n        template <Setting S>\r\n        std::optional<typename details::SettingMapping<S>::json_t> GetValueFromPolicy()\r\n        {\r\n            return GroupPolicies().GetValue<details::SettingMapping<S>::Policy>();\r\n        }\r\n\r\n        template <Setting S>\r\n        void Validate(\r\n            Json::Value& root,\r\n            std::map<Setting, details::SettingVariant>& settings,\r\n            std::vector<UserSettings::Warning>& warnings)\r\n        {\r\n            // jsoncpp doesn't support std::string_view yet.\r\n            auto path = std::string(details::SettingMapping<S>::Path);\r\n\r\n            // Settings set by Group Policy override anything else. See if there is one.\r\n            auto policyValue = GetValueFromPolicy<S>();\r\n            if (policyValue.has_value())\r\n            {\r\n                // If the value is valid, use it.\r\n                // Otherwise, fall back to default.\r\n                // In any case, we do not need to read the setting from the JSON.\r\n                auto validatedValue = details::SettingMapping<S>::Validate(policyValue.value());\r\n                if (validatedValue.has_value())\r\n                {\r\n                    // Add it to the map\r\n                    settings[S].emplace<details::SettingIndex(S)>(\r\n                        std::forward<typename details::SettingMapping<S>::value_t>(validatedValue.value()));\r\n                    AICLI_LOG(Core, Verbose, << \"Valid setting from Group Policy. Field: \" << path << \" Value: \" << GetValueString(policyValue.value()));\r\n                }\r\n                else\r\n                {\r\n                    auto valueAsString = GetValueString(policyValue.value());\r\n                    AICLI_LOG(Core, Error, << \"Invalid setting from Group Policy. Field: \" << path << \" Value: \" << valueAsString);\r\n                    warnings.emplace_back(StringResource::String::SettingsWarningInvalidValueFromPolicy, path, valueAsString);\r\n                }\r\n\r\n                return;\r\n            }\r\n\r\n            const Json::Path jsonPath(path);\r\n            Json::Value result = jsonPath.resolve(root);\r\n            if (!result.isNull())\r\n            {\r\n                auto jsonValue = GetValue<typename details::SettingMapping<S>::json_t>(result);\r\n\r\n                if (jsonValue.has_value())\r\n                {\r\n                    auto validatedValue = details::SettingMapping<S>::Validate(jsonValue.value());\r\n\r\n                    if (validatedValue.has_value())\r\n                    {\r\n                        // Finally add it to the map\r\n                        settings[S].emplace<details::SettingIndex(S)>(\r\n                            std::forward<typename details::SettingMapping<S>::value_t>(validatedValue.value()));\r\n                        AICLI_LOG(Core, Verbose, << \"Valid setting. Field: \" << path << \" Value: \" << GetValueString(jsonValue.value()));\r\n                    }\r\n                    else\r\n                    {\r\n                        auto valueAsString = GetValueString(jsonValue.value());\r\n                        AICLI_LOG(Core, Error, << \"Invalid field value. Field: \" << path << \" Value: \" << valueAsString);\r\n                        warnings.emplace_back(StringResource::String::SettingsWarningInvalidFieldValue, path, valueAsString);\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(Core, Error, << \"Invalid field format. Field: \" << path << \" Using default\");\r\n                    warnings.emplace_back(StringResource::String::SettingsWarningInvalidFieldFormat, path);\r\n                }\r\n            }\r\n            else\r\n            {\r\n                AICLI_LOG(Core, Verbose, << \"Setting \" << path << \" not found. Using default\");\r\n            }\r\n        }\r\n\r\n        template <size_t... S>\r\n        void ValidateAll(\r\n            Json::Value& root,\r\n            std::map<Setting, details::SettingVariant>& settings,\r\n            std::vector<UserSettings::Warning>& warnings,\r\n            std::index_sequence<S...>)\r\n        {\r\n            // Use folding to call each setting validate function.\r\n            (FoldHelper{}, ..., Validate<static_cast<Setting>(S)>(root, settings, warnings));\r\n        }\r\n\r\n        std::optional<std::filesystem::path> ValidatePathValue(std::string_view value)\r\n        {\r\n            std::filesystem::path path = ConvertToUTF16(value);\r\n            if (!path.is_absolute())\r\n            {\r\n                return {};\r\n            }\r\n\r\n            return path;\r\n        }\r\n    }\r\n\r\n    namespace details\r\n    {\r\n#define WINGET_VALIDATE_SIGNATURE(_setting_) \\\r\n        std::optional<SettingMapping<Setting::_setting_>::value_t> \\\r\n        SettingMapping<Setting::_setting_>::Validate(const SettingMapping<Setting::_setting_>::json_t& value)\r\n\r\n        // Stamps out a validate function that simply returns the input value.\r\n#define WINGET_VALIDATE_PASS_THROUGH(_setting_) \\\r\n        WINGET_VALIDATE_SIGNATURE(_setting_) \\\r\n        { \\\r\n            return value; \\\r\n        }\r\n\r\n        WINGET_VALIDATE_SIGNATURE(AutoUpdateTimeInMinutes)\r\n        {\r\n            return std::chrono::minutes(value);\r\n        }\r\n\r\n        WINGET_VALIDATE_SIGNATURE(ProgressBarVisualStyle)\r\n        {\r\n            std::string lowerValue = ToLower(value);\r\n\r\n            if (value == \"accent\")\r\n            {\r\n                return VisualStyle::Accent;\r\n            }\r\n            else if (value == \"rainbow\")\r\n            {\r\n                return VisualStyle::Rainbow;\r\n            }\r\n            else if (value == \"retro\")\r\n            {\r\n                return VisualStyle::Retro;\r\n            }\r\n            else if (value == \"sixel\")\r\n            {\r\n                return VisualStyle::Sixel;\r\n            }\r\n            else if (value == \"disabled\")\r\n            {\r\n                return VisualStyle::Disabled;\r\n            }\r\n\r\n            return {};\r\n        }\r\n\r\n        WINGET_VALIDATE_PASS_THROUGH(EnableSixelDisplay)\r\n        WINGET_VALIDATE_PASS_THROUGH(EFExperimentalCmd)\r\n        WINGET_VALIDATE_PASS_THROUGH(EFExperimentalArg)\r\n        WINGET_VALIDATE_PASS_THROUGH(EFDirectMSI)\r\n        WINGET_VALIDATE_PASS_THROUGH(EFResume)\r\n        WINGET_VALIDATE_PASS_THROUGH(EFFonts)\r\n        WINGET_VALIDATE_PASS_THROUGH(EFSourcePriority)\r\n        WINGET_VALIDATE_PASS_THROUGH(AnonymizePathForDisplay)\r\n        WINGET_VALIDATE_PASS_THROUGH(TelemetryDisable)\r\n        WINGET_VALIDATE_PASS_THROUGH(InteractivityDisable)\r\n        WINGET_VALIDATE_PASS_THROUGH(InstallSkipDependencies)\r\n        WINGET_VALIDATE_PASS_THROUGH(DisableInstallNotes)\r\n        WINGET_VALIDATE_PASS_THROUGH(UninstallPurgePortablePackage)\r\n        WINGET_VALIDATE_PASS_THROUGH(NetworkWingetAlternateSourceURL)\r\n        WINGET_VALIDATE_PASS_THROUGH(MaxResumes)\r\n        WINGET_VALIDATE_PASS_THROUGH(LoggingFileTotalSizeLimitInMB)\r\n        WINGET_VALIDATE_PASS_THROUGH(LoggingFileIndividualSizeLimitInMB)\r\n        WINGET_VALIDATE_PASS_THROUGH(LoggingFileCountLimit)\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        WINGET_VALIDATE_PASS_THROUGH(EnableSelfInitiatedMinidump)\r\n        WINGET_VALIDATE_PASS_THROUGH(KeepAllLogFiles)\r\n#endif\r\n\r\n        WINGET_VALIDATE_SIGNATURE(PortablePackageUserRoot)\r\n        {\r\n            return ValidatePathValue(value);\r\n        }\r\n\r\n        WINGET_VALIDATE_SIGNATURE(PortablePackageMachineRoot)\r\n        {\r\n            return ValidatePathValue(value);\r\n        }\r\n\r\n        WINGET_VALIDATE_SIGNATURE(ArchiveExtractionMethod)\r\n        {\r\n            static constexpr std::string_view s_archiveExtractionMethod_shellApi = \"shellApi\";\r\n            static constexpr std::string_view s_archiveExtractionMethod_tar = \"tar\";\r\n\r\n            if (Utility::CaseInsensitiveEquals(value, s_archiveExtractionMethod_tar))\r\n            {\r\n                return Archive::ExtractionMethod::Tar;\r\n            }\r\n            else if (Utility::CaseInsensitiveEquals(value, s_archiveExtractionMethod_shellApi))\r\n            {\r\n                return Archive::ExtractionMethod::ShellApi;\r\n            }\r\n\r\n            return {};\r\n        }\r\n\r\n        WINGET_VALIDATE_SIGNATURE(InstallArchitecturePreference)\r\n        {\r\n            std::vector<Utility::Architecture> archs;\r\n            for (auto const& i : value)\r\n            {\r\n                Utility::Architecture arch = Utility::ConvertToArchitectureEnum(i);\r\n                if (Utility::IsApplicableArchitecture(arch) == Utility::InapplicableArchitecture)\r\n                {\r\n                    return {};\r\n                }\r\n                archs.emplace_back(arch);\r\n            }\r\n            return archs;\r\n        }\r\n\r\n        WINGET_VALIDATE_SIGNATURE(InstallArchitectureRequirement)\r\n        {\r\n            return SettingMapping<Setting::InstallArchitecturePreference>::Validate(value);\r\n        }\r\n\r\n        WINGET_VALIDATE_SIGNATURE(InstallScopePreference)\r\n        {\r\n            static constexpr std::string_view s_scope_user = \"user\";\r\n            static constexpr std::string_view s_scope_machine = \"machine\";\r\n\r\n            if (Utility::CaseInsensitiveEquals(value, s_scope_user))\r\n            {\r\n                return Manifest::ScopeEnum::User;\r\n            }\r\n            else if (Utility::CaseInsensitiveEquals(value, s_scope_machine))\r\n            {\r\n                return Manifest::ScopeEnum::Machine;\r\n            }\r\n\r\n            return {};\r\n        }\r\n\r\n        WINGET_VALIDATE_SIGNATURE(InstallScopeRequirement)\r\n        {\r\n            return SettingMapping<Setting::InstallScopePreference>::Validate(value);\r\n        }\r\n\r\n        WINGET_VALIDATE_SIGNATURE(InstallLocalePreference)\r\n        {\r\n            for (auto const& entry : value)\r\n            {\r\n                if (!Locale::IsWellFormedBcp47Tag(entry))\r\n                {\r\n                    return {};\r\n                }\r\n            }\r\n\r\n            return value;\r\n        }\r\n\r\n        WINGET_VALIDATE_SIGNATURE(InstallLocaleRequirement)\r\n        {\r\n            return SettingMapping<Setting::InstallLocalePreference>::Validate(value);\r\n        }\r\n\r\n        WINGET_VALIDATE_SIGNATURE(InstallerTypePreference)\r\n        {\r\n            std::vector<Manifest::InstallerTypeEnum> installerTypes;\r\n            for (auto const& i : value)\r\n            {\r\n                Manifest::InstallerTypeEnum installerType = Manifest::ConvertToInstallerTypeEnum(i);\r\n                if (installerType == Manifest::InstallerTypeEnum::Unknown)\r\n                {\r\n                    return {};\r\n                }\r\n                installerTypes.emplace_back(installerType);\r\n            }\r\n            return installerTypes;\r\n        }\r\n\r\n        WINGET_VALIDATE_SIGNATURE(InstallerTypeRequirement)\r\n        {\r\n            return SettingMapping<Setting::InstallerTypePreference>::Validate(value);\r\n        }\r\n\r\n        WINGET_VALIDATE_SIGNATURE(InstallDefaultRoot)\r\n        {\r\n            return ValidatePathValue(value);\r\n        }\r\n\r\n        WINGET_VALIDATE_SIGNATURE(DownloadDefaultDirectory)\r\n        {\r\n            return ValidatePathValue(value);\r\n        }\r\n\r\n        WINGET_VALIDATE_SIGNATURE(ConfigureDefaultModuleRoot)\r\n        {\r\n            return ValidatePathValue(value);\r\n        }\r\n\r\n        WINGET_VALIDATE_SIGNATURE(NetworkDownloader)\r\n        {\r\n            static constexpr std::string_view s_downloader_default = \"default\";\r\n            static constexpr std::string_view s_downloader_wininet = \"wininet\";\r\n            static constexpr std::string_view s_downloader_do = \"do\";\r\n\r\n            if (Utility::CaseInsensitiveEquals(value, s_downloader_default))\r\n            {\r\n                return InstallerDownloader::Default;\r\n            }\r\n            else if (Utility::CaseInsensitiveEquals(value, s_downloader_wininet))\r\n            {\r\n                return InstallerDownloader::WinInet;\r\n            }\r\n            else if (Utility::CaseInsensitiveEquals(value, s_downloader_do))\r\n            {\r\n                return InstallerDownloader::DeliveryOptimization;\r\n            }\r\n\r\n            return {};\r\n        }\r\n\r\n        WINGET_VALIDATE_SIGNATURE(NetworkDOProgressTimeoutInSeconds)\r\n        {\r\n            return std::chrono::seconds(value);\r\n        }\r\n\r\n        WINGET_VALIDATE_SIGNATURE(LoggingLevelPreference)\r\n        {\r\n            // logging preference possible values\r\n            static constexpr std::string_view s_logging_verbose = \"verbose\";\r\n            static constexpr std::string_view s_logging_info = \"info\";\r\n            static constexpr std::string_view s_logging_warning = \"warning\";\r\n            static constexpr std::string_view s_logging_error = \"error\";\r\n            static constexpr std::string_view s_logging_critical = \"critical\";\r\n\r\n            if (Utility::CaseInsensitiveEquals(value, s_logging_verbose))\r\n            {\r\n                return Level::Verbose;\r\n            }\r\n            else if (Utility::CaseInsensitiveEquals(value, s_logging_info))\r\n            {\r\n                return Level::Info;\r\n            }\r\n            else if (Utility::CaseInsensitiveEquals(value, s_logging_warning))\r\n            {\r\n                return Level::Warning;\r\n            }\r\n            else if (Utility::CaseInsensitiveEquals(value, s_logging_error))\r\n            {\r\n                return Level::Error;\r\n            }\r\n            else if (Utility::CaseInsensitiveEquals(value, s_logging_critical))\r\n            {\r\n                return Level::Crit;\r\n            }\r\n            return {};\r\n        }\r\n\r\n        WINGET_VALIDATE_SIGNATURE(LoggingChannelPreference)\r\n        {\r\n            Logging::Channel result = Logging::Channel::None;\r\n\r\n            for (auto const& entry : value)\r\n            {\r\n                result |= GetChannelFromName(entry);\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        WINGET_VALIDATE_SIGNATURE(LoggingFileAgeLimitInDays)\r\n        {\r\n            return value * 24h;\r\n        }\r\n    }\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n    static UserSettings* s_UserSettings_Override = nullptr;\r\n\r\n    void SetUserSettingsOverride(UserSettings* value)\r\n    {\r\n        s_UserSettings_Override = value;\r\n    }\r\n#endif\r\n\r\n    static std::atomic_bool s_userSettingsInitialized{ false };\r\n    static std::atomic_bool s_userSettingsInInitialization{ false };\r\n\r\n    UserSettings const& UserSettings::Instance(const std::optional<std::string>& content)\r\n    {\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        if (s_UserSettings_Override)\r\n        {\r\n            return *s_UserSettings_Override;\r\n        }\r\n#endif\r\n        if (!s_userSettingsInitialized)\r\n        {\r\n            s_userSettingsInInitialization = true;\r\n        }\r\n\r\n        static UserSettings userSettings(content);\r\n        s_userSettingsInitialized = true;\r\n        s_userSettingsInInitialization = false;\r\n\r\n        return userSettings;\r\n    }\r\n\r\n    const UserSettings* TryGetUser()\r\n    {\r\n        if (s_userSettingsInitialized)\r\n        {\r\n            return &UserSettings::Instance();\r\n        }\r\n\r\n        // Try to initialize UserSettings, return nullptr if it's already in initialization.\r\n        if (s_userSettingsInInitialization)\r\n        {\r\n            return nullptr;\r\n        }\r\n\r\n        return &UserSettings::Instance();\r\n    }\r\n\r\n    UserSettings const& User()\r\n    {\r\n        return UserSettings::Instance();\r\n    }\r\n\r\n    bool TryInitializeCustomUserSettings(std::string content)\r\n    {\r\n        if (s_userSettingsInitialized || s_userSettingsInInitialization)\r\n        {\r\n            return false;\r\n        }\r\n\r\n        return UserSettings::Instance(std::move(content)).GetType() == UserSettingsType::Custom;\r\n    }\r\n\r\n    UserSettings::UserSettings(const std::optional<std::string>& content) : m_type(UserSettingsType::Default)\r\n    {\r\n        Json::Value settingsRoot = Json::Value::nullSingleton();\r\n\r\n        // Settings can be loaded from settings.json or settings.json.backup files.\r\n        // 0 - Use default (empty) settings if disabled by group policy.\r\n        // if\r\n        // 1 - Use passed in settings content if available.\r\n        // else\r\n        // 2 - Use settings.json if exists and passes parsing.\r\n        // 3 - Use settings.backup.json if settings.json fails to parse.\r\n        // finally\r\n        // 4 - Use default (empty) if both settings files fail to load.\r\n\r\n        if (!GroupPolicies().IsEnabled(TogglePolicy::Policy::Settings))\r\n        {\r\n            AICLI_LOG(Core, Info, << \"Ignoring settings file due to group policy. Using default values.\");\r\n            return;\r\n        }\r\n\r\n        if (content.has_value())\r\n        {\r\n            auto settingsJson = ParseSettingsContent(content.value(), \"CustomSettings\", m_warnings);\r\n            if (settingsJson.has_value())\r\n            {\r\n                AICLI_LOG(Core, Info, << \"Settings loaded from custom settings\");\r\n                m_type = UserSettingsType::Custom;\r\n                settingsRoot = settingsJson.value();\r\n            }\r\n        }\r\n        else\r\n        {\r\n            auto settingsJson = ParseFile(Stream::PrimaryUserSettings, m_warnings);\r\n            if (settingsJson.has_value())\r\n            {\r\n                AICLI_LOG(Core, Info, << \"Settings loaded from \" << Stream::PrimaryUserSettings.Name);\r\n                m_type = UserSettingsType::Standard;\r\n                settingsRoot = settingsJson.value();\r\n            }\r\n\r\n            // Settings didn't parse or doesn't exist, try with backup.\r\n            if (settingsRoot.isNull())\r\n            {\r\n                auto settingsBackupJson = ParseFile(Stream::BackupUserSettings, m_warnings);\r\n                if (settingsBackupJson.has_value())\r\n                {\r\n                    AICLI_LOG(Core, Info, << \"Settings loaded from \" << Stream::BackupUserSettings.Name);\r\n                    m_warnings.emplace_back(StringResource::String::SettingsWarningLoadedBackupSettings);\r\n                    m_type = UserSettingsType::Backup;\r\n                    settingsRoot = settingsBackupJson.value();\r\n                }\r\n                else\r\n                {\r\n                    // Settings and back up didn't parse or exist. If they exist then warn the user.\r\n                    auto settingsPath = Stream{ Stream::PrimaryUserSettings }.GetPath();\r\n                    auto backupPath = Stream{ Stream::BackupUserSettings }.GetPath();\r\n                    if (std::filesystem::exists(settingsPath) || std::filesystem::exists(backupPath))\r\n                    {\r\n                        m_warnings.emplace_back(StringResource::String::SettingsWarningUsingDefault);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        if (!settingsRoot.isNull())\r\n        {\r\n            ValidateAll(settingsRoot, m_settings, m_warnings, std::make_index_sequence<static_cast<size_t>(Setting::Max)>());\r\n        }\r\n        else\r\n        {\r\n            AICLI_LOG(Core, Info, << \"Valid settings file not found. Using default values.\");\r\n        }\r\n    }\r\n\r\n    void UserSettings::PrepareToShellExecuteFile() const\r\n    {\r\n        UserSettingsType userSettingType = GetType();\r\n\r\n        if (userSettingType == UserSettingsType::Default)\r\n        {\r\n            Stream primarySettings{ Stream::PrimaryUserSettings };\r\n\r\n            // Create settings file if it doesn't exist.\r\n            if (!std::filesystem::exists(primarySettings.GetPath()))\r\n            {\r\n                std::ignore = primarySettings.Set(s_SettingEmpty);\r\n                AICLI_LOG(Core, Info, << \"Created new settings file\");\r\n            }\r\n        }\r\n        else if (userSettingType == UserSettingsType::Standard)\r\n        {\r\n            // Settings file was loaded correctly, create backup.\r\n            auto from = SettingsFilePath();\r\n            auto to = Stream{ Stream::BackupUserSettings }.GetPath();\r\n            std::filesystem::copy_file(from, to, std::filesystem::copy_options::overwrite_existing);\r\n            AICLI_LOG(Core, Info, << \"Copied settings to backup file\");\r\n        }\r\n    }\r\n\r\n    std::filesystem::path UserSettings::SettingsFilePath(bool forDisplay)\r\n    {\r\n        auto path = Stream{ Stream::PrimaryUserSettings }.GetPath();\r\n\r\n        if (forDisplay && Settings::User().Get<Setting::AnonymizePathForDisplay>())\r\n        {\r\n            ReplaceCommonPathPrefix(path, GetKnownFolderPath(FOLDERID_LocalAppData), \"%LOCALAPPDATA%\");\r\n        }\r\n\r\n        return path;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerCommonCore/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<packages>\r\n  <package id=\"Microsoft.Windows.CppWinRT\" version=\"2.0.250303.1\" targetFramework=\"native\" />\r\n  <package id=\"Microsoft.Windows.ImplementationLibrary\" version=\"1.0.250325.1\" targetFramework=\"native\" />\r\n</packages>"
  },
  {
    "path": "src/AppInstallerCommonCore/pch.cpp",
    "content": "﻿// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n"
  },
  {
    "path": "src/AppInstallerCommonCore/pch.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n\r\n#define NOMINMAX\r\n#include <Windows.h>\r\n#include <AclAPI.h>\r\n#include <appmodel.h>\r\n#include <sddl.h>\r\n#include <Shlobj.h>\r\n#include <Shlwapi.h>\r\n#include <wow64apiset.h>\r\n#include <icu.h>\r\n#include <msi.h>\r\n#include <DbgHelp.h>\r\n#include <SoftPub.h>\r\n#include <WinTrust.h>\r\n#include <wincrypt.h>\r\n#include <deliveryoptimization.h>\r\n#include <deliveryoptimizationerrors.h>\r\n\r\n#include \"TraceLogging.h\"\r\n\r\n#define YAML_DECLARE_STATIC\r\n#include <yaml.h>\r\n\r\n// TODO: See if we can get down to having just one JSON parser...\r\n#include <json/json.h>\r\n\r\n#pragma warning( push )\r\n#pragma warning ( disable : 4458 4100 4702 6031 26439 )\r\n#include <valijson/schema.hpp>\r\n#include <valijson/schema_parser.hpp>\r\n#include <valijson/validator.hpp>\r\n#include <valijson/adapters/jsoncpp_adapter.hpp>\r\n#pragma warning( pop )\r\n\r\n#include <algorithm>\r\n#include <chrono>\r\n#include <condition_variable>\r\n#include <cwctype>\r\n#include <filesystem>\r\n#include <fstream>\r\n#include <functional>\r\n#include <future>\r\n#include <iomanip>\r\n#include <iterator>\r\n#include <limits>\r\n#include <memory>\r\n#include <mutex>\r\n#include <optional>\r\n#include <ostream>\r\n#include <regex>\r\n#include <set>\r\n#include <string>\r\n#include <sstream>\r\n#include <stack>\r\n#include <string_view>\r\n#include <type_traits>\r\n#include <unordered_set>\r\n#include <vector>\r\n#include <variant>\r\n\r\n#ifndef WINGET_DISABLE_FOR_FUZZING\r\n#pragma warning( push )\r\n#pragma warning ( disable : 26495 26439 )\r\n#include <cpprest/http_client.h>\r\n#include <cpprest/json.h>\r\n#include <cpprest/uri_builder.h>\r\n#pragma warning( pop )\r\n#endif\r\n\r\n#pragma warning( push )\r\n#pragma warning ( disable : 6001 6285 6287 6340 6387 6388 26451 26495 28196 )\r\n#include <wil/resource.h>\r\n#include <wil/result.h>\r\n#include <wil/result_macros.h>\r\n#include <wil/safecast.h>\r\n#include <wil/token_helpers.h>\r\n#include <wil/com.h>\r\n#include <wil/filesystem.h>\r\n#include <wil/win32_helpers.h>\r\n#include <wil/registry_helpers.h>\r\n#pragma warning( pop )\r\n\r\n#include <wil/cppwinrt.h>\r\n\r\n#include <winrt/Windows.ApplicationModel.h>\r\n#include <winrt/Windows.ApplicationModel.AppExtensions.h>\r\n#include <winrt/Windows.Foundation.h>\r\n#include <winrt/Windows.Foundation.Collections.h>\r\n#include <winrt/Windows.Foundation.Metadata.h>\r\n#include <winrt/Windows.Management.Deployment.h>\r\n#include <winrt/Windows.Security.Cryptography.h>\r\n#include <winrt/Windows.Services.Store.h>\r\n#include <winrt/Windows.Storage.h>\r\n#include <winrt/Windows.Storage.Streams.h>\r\n#include <winrt/Windows.System.Profile.h>\r\n#include <winrt/Windows.System.UserProfile.h>\r\n#include <winrt/Windows.Web.Http.h>\r\n#include <winrt/Windows.Web.Http.Headers.h>\r\n#include <winrt/Windows.Web.Http.Filters.h>\r\n#include <winrt/Windows.Globalization.h>\r\n#include <winrt/Windows.ApplicationModel.Store.Preview.InstallControl.h>\r\n#include <winrt/Windows.Security.Authentication.Web.Core.h>\r\n#include <winrt/Windows.Security.Credentials.h>\r\n\r\n#include <wrl/client.h>\r\n#include <wrl/implements.h>\r\n\r\n// Stream/buffer helper APIs\r\n#include <robuffer.h>\r\n#include <shcore.h>\r\n\r\n#include <AppxPackaging.h>\r\n#include <WebAuthenticationCoreManagerInterop.h>\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/ARPCorrelation.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"winget/ARPCorrelation.h\"\r\n#include \"winget/ARPCorrelationAlgorithms.h\"\r\n#include \"winget/Manifest.h\"\r\n#include \"winget/NameNormalization.h\"\r\n#include \"winget/RepositorySearch.h\"\r\n#include \"winget/RepositorySource.h\"\r\n\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Utility;\r\n\r\nnamespace AppInstaller::Repository::Correlation\r\n{\r\n    namespace\r\n    {\r\n        constexpr double MatchingThreshold = 0.5;\r\n        constexpr double MinimumDifferentiationThreshold = 0.05;\r\n\r\n        IARPMatchConfidenceAlgorithm& InstanceInternal(std::optional<IARPMatchConfidenceAlgorithm*> algorithmOverride = {})\r\n        {\r\n            static WordsEditDistanceMatchConfidenceAlgorithm s_algorithm;\r\n            static IARPMatchConfidenceAlgorithm* s_override = nullptr;\r\n\r\n            if (algorithmOverride.has_value())\r\n            {\r\n                s_override = algorithmOverride.value();\r\n            }\r\n\r\n            if (s_override)\r\n            {\r\n                return *s_override;\r\n            }\r\n            else\r\n            {\r\n                return s_algorithm;\r\n            }\r\n        }\r\n    }\r\n\r\n    IARPMatchConfidenceAlgorithm& IARPMatchConfidenceAlgorithm::Instance()\r\n    {\r\n        return InstanceInternal();\r\n    }\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n    void IARPMatchConfidenceAlgorithm::OverrideInstance(IARPMatchConfidenceAlgorithm* algorithmOverride)\r\n    {\r\n        InstanceInternal(algorithmOverride);\r\n    }\r\n\r\n    void IARPMatchConfidenceAlgorithm::ResetInstance()\r\n    {\r\n        InstanceInternal(nullptr);\r\n    }\r\n#endif\r\n\r\n    // Find the best match using heuristics\r\n    ARPHeuristicsCorrelationResult FindARPEntryForNewlyInstalledPackageWithHeuristics(\r\n        const Manifest::Manifest& manifest,\r\n        const std::vector<ARPEntry>& arpEntries)\r\n    {\r\n        // TODO: In the future we can make different passes with different algorithms until we find a match\r\n        return FindARPEntryForNewlyInstalledPackageWithHeuristics(manifest, arpEntries, IARPMatchConfidenceAlgorithm::Instance());\r\n    }\r\n\r\n    ARPHeuristicsCorrelationResult FindARPEntryForNewlyInstalledPackageWithHeuristics(\r\n        const AppInstaller::Manifest::Manifest& manifest,\r\n        const std::vector<ARPEntry>& arpEntries,\r\n        IARPMatchConfidenceAlgorithm& algorithm)\r\n    {\r\n        if (arpEntries.empty())\r\n        {\r\n            AICLI_LOG(Repo, Warning, << \"Empty ARP entries given\");\r\n            return {};\r\n        }\r\n\r\n        AICLI_LOG(Repo, Verbose, << \"Looking for best match in ARP for manifest \" << manifest.Id);\r\n\r\n        algorithm.Init(manifest);\r\n\r\n        ARPHeuristicsCorrelationResult result;\r\n        result.Measures.reserve(arpEntries.size());\r\n\r\n        for (const auto& arpEntry : arpEntries)\r\n        {\r\n            auto score = algorithm.ComputeConfidence(arpEntry);\r\n            AICLI_LOG(Repo, Verbose, << \"Match confidence for \" << arpEntry.Entry->GetProperty(PackageProperty::Id) << \": \" << score);\r\n\r\n            result.Measures.emplace_back(CorrelationMeasure{ score, arpEntry.Entry->GetLatestVersion() });\r\n        }\r\n\r\n        std::sort(result.Measures.begin(), result.Measures.end(), [](const CorrelationMeasure& a, const CorrelationMeasure& b) { return a.Measure > b.Measure; });\r\n\r\n        if (result.Measures[0].Measure < MatchingThreshold)\r\n        {\r\n            AICLI_LOG(Repo, Verbose, << \"Maximum score [\" << result.Measures[0].Measure << \"] is lower than threshold [\" << MatchingThreshold << \"]\");\r\n            result.Reason = \"maximum score below threshold\";\r\n        }\r\n        else if (result.Measures.size() >= 2 && (result.Measures[0].Measure - result.Measures[1].Measure) < MinimumDifferentiationThreshold)\r\n        {\r\n            AICLI_LOG(Repo, Verbose, << \"Top two scores, [\" << result.Measures[0].Measure << \"] and [\" << result.Measures[1].Measure << \"] are not significantly different [\" << MinimumDifferentiationThreshold << \"]\");\r\n            result.Reason = \"top two scores are not significantly different\";\r\n        }\r\n        else\r\n        {\r\n            AICLI_LOG(Repo, Verbose, << \"Best match is \" << result.Measures[0].Package->GetProperty(PackageVersionProperty::Id));\r\n            result.Package = result.Measures[0].Package;\r\n            result.Reason = \"heuristics match\";\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    void ARPCorrelationData::CapturePreInstallSnapshot()\r\n    {\r\n        ProgressCallback empty;\r\n        Repository::Source preInstallARP = Repository::Source(PredefinedSource::ARP);\r\n        preInstallARP.Open(empty);\r\n\r\n        for (const auto& entry : preInstallARP.Search({}).Matches)\r\n        {\r\n            auto installed = entry.Package->GetInstalled()->GetLatestVersion();\r\n            if (installed)\r\n            {\r\n                m_preInstallSnapshot.emplace_back(std::make_tuple(\r\n                    installed->GetProperty(PackageVersionProperty::Id),\r\n                    installed->GetProperty(PackageVersionProperty::Version),\r\n                    installed->GetProperty(PackageVersionProperty::Channel)));\r\n            }\r\n        }\r\n\r\n        std::sort(m_preInstallSnapshot.begin(), m_preInstallSnapshot.end());\r\n    }\r\n\r\n    void ARPCorrelationData::CapturePostInstallSnapshot()\r\n    {\r\n        ProgressCallback empty;\r\n        m_postInstallSnapshotSource = Repository::Source(PredefinedSource::ARP);\r\n        m_postInstallSnapshotSource.Open(empty);\r\n\r\n        for (auto& entry : m_postInstallSnapshotSource.Search({}).Matches)\r\n        {\r\n            auto installed = entry.Package->GetInstalled()->GetLatestVersion();\r\n\r\n            if (installed)\r\n            {\r\n                auto entryKey = std::make_tuple(\r\n                    installed->GetProperty(PackageVersionProperty::Id),\r\n                    installed->GetProperty(PackageVersionProperty::Version),\r\n                    installed->GetProperty(PackageVersionProperty::Channel));\r\n\r\n                auto itr = std::lower_bound(m_preInstallSnapshot.begin(), m_preInstallSnapshot.end(), entryKey);\r\n                m_postInstallSnapshot.emplace_back(entry.Package->GetInstalled(), itr == m_preInstallSnapshot.end() || *itr != entryKey);\r\n            }\r\n        }\r\n    }\r\n\r\n    ARPCorrelationResult ARPCorrelationData::CorrelateForNewlyInstalled(const Manifest::Manifest& manifest, const ARPCorrelationSettings& settings)\r\n    {\r\n        AICLI_LOG(Repo, Verbose, << \"Finding ARP entry matching newly installed package\");\r\n\r\n        // Also attempt to find the entry based on the manifest data\r\n\r\n        SearchRequest manifestSearchRequest;\r\n        AppInstaller::Manifest::Manifest::string_t defaultPublisher;\r\n        if (manifest.DefaultLocalization.Contains(Localization::Publisher))\r\n        {\r\n            defaultPublisher = manifest.DefaultLocalization.Get<Localization::Publisher>();\r\n        }\r\n\r\n        // The default localization must contain the name or we cannot do this lookup\r\n        if (manifest.DefaultLocalization.Contains(Localization::PackageName))\r\n        {\r\n            AppInstaller::Manifest::Manifest::string_t defaultName = manifest.DefaultLocalization.Get<Localization::PackageName>();\r\n            manifestSearchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::NormalizedNameAndPublisher, MatchType::Exact, defaultName, defaultPublisher));\r\n\r\n            for (const auto& loc : manifest.Localizations)\r\n            {\r\n                if (loc.Contains(Localization::PackageName) || loc.Contains(Localization::Publisher))\r\n                {\r\n                    manifestSearchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::NormalizedNameAndPublisher, MatchType::Exact,\r\n                        loc.Contains(Localization::PackageName) ? loc.Get<Localization::PackageName>() : defaultName,\r\n                        loc.Contains(Localization::Publisher) ? loc.Get<Localization::Publisher>() : defaultPublisher));\r\n                }\r\n            }\r\n        }\r\n\r\n        std::set<std::string> productCodes;\r\n        std::set<std::string> upgradeCodes;\r\n        for (const auto& installer : manifest.Installers)\r\n        {\r\n            if (!installer.ProductCode.empty())\r\n            {\r\n                // Add each ProductCode only once\r\n                if (productCodes.insert(installer.ProductCode).second)\r\n                {\r\n                    manifestSearchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::ProductCode, MatchType::Exact, installer.ProductCode));\r\n                }\r\n            }\r\n\r\n            for (const auto& appsAndFeaturesEntry : installer.AppsAndFeaturesEntries)\r\n            {\r\n                if (!appsAndFeaturesEntry.DisplayName.empty())\r\n                {\r\n                    manifestSearchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::NormalizedNameAndPublisher, MatchType::Exact,\r\n                        appsAndFeaturesEntry.DisplayName,\r\n                        appsAndFeaturesEntry.Publisher.empty() ? defaultPublisher : appsAndFeaturesEntry.Publisher));\r\n                }\r\n\r\n                // Add each ProductCode and UpgradeCode only once;\r\n                if (!appsAndFeaturesEntry.ProductCode.empty() && productCodes.insert(appsAndFeaturesEntry.ProductCode).second)\r\n                {\r\n                    manifestSearchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::ProductCode, MatchType::Exact, appsAndFeaturesEntry.ProductCode));\r\n                }\r\n                if (!appsAndFeaturesEntry.UpgradeCode.empty() && upgradeCodes.insert(appsAndFeaturesEntry.UpgradeCode).second)\r\n                {\r\n                    manifestSearchRequest.Inclusions.emplace_back(PackageMatchFilter(PackageMatchField::UpgradeCode, MatchType::Exact, appsAndFeaturesEntry.UpgradeCode));\r\n                }\r\n            }\r\n        }\r\n\r\n        SearchResult findByManifest;\r\n\r\n        // Don't execute this search if it would just find everything\r\n        if (!manifestSearchRequest.IsForEverything())\r\n        {\r\n            findByManifest = m_postInstallSnapshotSource.Search(manifestSearchRequest);\r\n        }\r\n\r\n        // Cross reference the changes with the search results\r\n        std::vector<std::shared_ptr<IPackage>> packagesInBoth;\r\n\r\n        for (const auto& change : m_postInstallSnapshot)\r\n        {\r\n            if (change.IsNewOrUpdated)\r\n            {\r\n                for (const auto& byManifest : findByManifest.Matches)\r\n                {\r\n                    if (change.Entry->IsSame(byManifest.Package->GetInstalled().get()))\r\n                    {\r\n                        packagesInBoth.emplace_back(change.Entry);\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // We now have all of the package changes; time to report them.\r\n        //\r\n        // The set of cases we could have for finding packages based on the manifest:\r\n        //  0 packages  ::  The manifest data does not match the ARP information.\r\n        //  1 package   ::  Golden path; this should be what we installed.\r\n        //  2+ packages ::  The data in the manifest is either too broad or we have\r\n        //                  a problem with our name normalization.\r\n\r\n        // Find the package that we are going to log\r\n        ARPCorrelationResult result;\r\n        // TODO: Find a good way to consider the other heuristics in these stats.\r\n        result.ChangesToARP = std::count_if(m_postInstallSnapshot.begin(), m_postInstallSnapshot.end(), [](const ARPEntry& e) { return e.IsNewOrUpdated; });\r\n        result.MatchesInARP = findByManifest.Matches.size();\r\n        result.CountOfIntersectionOfChangesAndMatches = packagesInBoth.size();\r\n\r\n        // If there is only a single common package (changed and matches), it is almost certainly the correct one.\r\n        if (settings.AllowNormalization && packagesInBoth.size() == 1)\r\n        {\r\n            result.Package = packagesInBoth[0]->GetLatestVersion();\r\n            result.Reason = \"normalization match and new/changed\";\r\n        }\r\n        // If it wasn't changed but we still find a match, that is the best thing to report.\r\n        else if (settings.AllowNormalization && findByManifest.Matches.size() == 1)\r\n        {\r\n            result.Package = findByManifest.Matches[0].Package->GetInstalled()->GetLatestVersion();\r\n            result.Reason = \"normalization match (not new/changed)\";\r\n        }\r\n        else if (settings.AllowSingleChange && result.ChangesToARP == 1)\r\n        {\r\n            result.Package = std::find_if(m_postInstallSnapshot.begin(), m_postInstallSnapshot.end(), [](const ARPEntry& e) { return e.IsNewOrUpdated; })->Entry->GetLatestVersion();\r\n            result.Reason = \"only new/changed value\";\r\n        }\r\n        else\r\n        {\r\n            // We were not able to find an exact match, so we now run some heuristics\r\n            // to try and match the package with some ARP entry by assigning them scores.\r\n            AICLI_LOG(Repo, Verbose, << \"No exact ARP match found. Trying to find one with heuristics\");\r\n\r\n            result = FindARPEntryForNewlyInstalledPackageWithHeuristics(manifest, m_postInstallSnapshot);\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/ARPCorrelationAlgorithms.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"winget/ARPCorrelationAlgorithms.h\"\r\n\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Utility;\r\n\r\nnamespace AppInstaller::Repository::Correlation\r\n{\r\n    using WordSequence = WordsEditDistanceMatchConfidenceAlgorithm::WordSequence;\r\n\r\n    namespace\r\n    {\r\n        // A simple matrix class to hold score tables without having to allocate multiple arrays.\r\n        struct Matrix\r\n        {\r\n            Matrix(size_t rows, size_t columns) : m_rows(rows), m_columns(columns), m_data(rows* columns) {}\r\n\r\n            double& At(size_t i, size_t j)\r\n            {\r\n                return m_data[i * m_columns + j];\r\n            }\r\n\r\n        private:\r\n            size_t m_rows;\r\n            size_t m_columns;\r\n            std::vector<double> m_data;\r\n        };\r\n\r\n        double EditDistanceScore(const std::vector<std::string>& s1, const std::vector<std::string>& s2)\r\n        {\r\n            // Naive implementation of edit distance (scaled over the sequence size).\r\n            // This considers only the operations of adding and removing elements.\r\n\r\n            if (s1.empty() || s2.empty())\r\n            {\r\n                return 0;\r\n            }\r\n\r\n            // distance[i, j] = distance between s1[0:i] and s2[0:j]\r\n            // We don't need to hold more than two rows at a time, but it's simpler to keep the whole table.\r\n            Matrix distance(s1.size() + 1, s2.size() + 1);\r\n\r\n            for (size_t i = 0; i < s1.size(); ++i)\r\n            {\r\n                for (size_t j = 0; j < s2.size(); ++j)\r\n                {\r\n                    double& d = distance.At(i, j);\r\n                    if (s1[i] == s2[j])\r\n                    {\r\n                        // If the two elements are equal, the distance is the same as from one element before.\r\n                        // In case we are on the first element of one of the two sequences, the distance is\r\n                        // equal to the cost of adding all the previous elements in the other\r\n                        if (i == 0)\r\n                        {\r\n                            d = static_cast<double>(j);\r\n                        }\r\n                        else if (j == 0)\r\n                        {\r\n                            d = static_cast<double>(i);\r\n                        }\r\n                        else\r\n                        {\r\n                            d = distance.At(i - 1, j - 1);\r\n                        }\r\n                    }\r\n                    else\r\n                    {\r\n                        // If the two elements are distinct, the score is the cost of removing the last element\r\n                        // in one sequence plus the cost of editing the remainder of both.\r\n                        if (i > 0 && j > 0)\r\n                        {\r\n                            d = 1 + std::min(distance.At(i - 1, j), distance.At(i, j - 1));\r\n                        }\r\n                        else if (i > 0)\r\n                        {\r\n                            d = 1 + distance.At(i - 1, j);\r\n                        }\r\n                        else if (j > 0)\r\n                        {\r\n                            d = 1 + distance.At(i, j - 1);\r\n                        }\r\n                        else\r\n                        {\r\n                            // Remove one and add the other\r\n                            d = 2;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Maximum distance is equal to the sum of both lengths (removing all elements from one and adding all the elements from the other).\r\n            // We use that to scale to [0,1].\r\n            // A smaller distance represents a higher match, so we subtract from 1 for the final score\r\n            double editDistance = distance.At(s1.size() - 1, s2.size() - 1);\r\n            return 1 - editDistance / (static_cast<uint64_t>(s1.size()) + static_cast<uint64_t>(s2.size()));\r\n        }\r\n    }\r\n\r\n    WordsEditDistanceMatchConfidenceAlgorithm::NameAndPublisher::NameAndPublisher(const WordSequence& name, const WordSequence& publisher) : Name(name), Publisher(publisher)\r\n    {\r\n        NamePublisher.insert(NamePublisher.end(), publisher.begin(), publisher.end());\r\n        NamePublisher.insert(NamePublisher.end(), name.begin(), name.end());\r\n    }\r\n\r\n    WordsEditDistanceMatchConfidenceAlgorithm::NameAndPublisher::NameAndPublisher(WordSequence&& name, WordSequence&& publisher) : Name(std::move(name)), Publisher(std::move(publisher))\r\n    {\r\n        NamePublisher.insert(NamePublisher.end(), publisher.begin(), publisher.end());\r\n        NamePublisher.insert(NamePublisher.end(), name.begin(), name.end());\r\n\r\n    }\r\n\r\n    void WordsEditDistanceMatchConfidenceAlgorithm::Init(const AppInstaller::Manifest::Manifest& manifest)\r\n    {\r\n        // We will use the name and publisher from each localization.\r\n        m_namesAndPublishers.clear();\r\n\r\n        WordSequence defaultPublisher;\r\n        if (manifest.DefaultLocalization.Contains(Manifest::Localization::Publisher))\r\n        {\r\n            defaultPublisher = NormalizeAndPreparePublisher(manifest.DefaultLocalization.Get<Manifest::Localization::Publisher>());\r\n        }\r\n\r\n        if (manifest.DefaultLocalization.Contains(Manifest::Localization::PackageName))\r\n        {\r\n            WordSequence defaultName = NormalizeAndPrepareName(manifest.DefaultLocalization.Get<Manifest::Localization::PackageName>());\r\n            m_namesAndPublishers.emplace_back(defaultName, defaultPublisher);\r\n\r\n            for (const auto& loc : manifest.Localizations)\r\n            {\r\n                if (loc.Contains(Manifest::Localization::PackageName) || loc.Contains(Manifest::Localization::Publisher))\r\n                {\r\n                    auto name = loc.Contains(Manifest::Localization::PackageName) ? NormalizeAndPrepareName(loc.Get<Manifest::Localization::PackageName>()) : defaultName;\r\n                    auto publisher = loc.Contains(Manifest::Localization::Publisher) ? NormalizeAndPreparePublisher(loc.Get<Manifest::Localization::Publisher>()) : defaultPublisher;\r\n\r\n                    m_namesAndPublishers.emplace_back(std::move(name), std::move(publisher));\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    double WordsEditDistanceMatchConfidenceAlgorithm::ComputeConfidence(const ARPEntry& arpEntry) const\r\n    {\r\n        // Name and Publisher are available as multi properties, but for ARP entries there will only be 0 or 1 values.\r\n        NameAndPublisher arpNameAndPublisher(\r\n            NormalizeAndPrepareName(arpEntry.Entry->GetLatestVersion()->GetProperty(PackageVersionProperty::Name).get()),\r\n            NormalizeAndPreparePublisher(arpEntry.Entry->GetLatestVersion()->GetProperty(PackageVersionProperty::Publisher).get()));\r\n\r\n        // Get the best score across all localizations\r\n        double bestMatchingScore = 0;\r\n        for (const auto& manifestNameAndPublisher : m_namesAndPublishers)\r\n        {\r\n            // Sometimes the publisher may be included in the name, for example Microsoft PowerToys as opposed to simply PowerToys.\r\n            // This may happen both in the ARP entry and the manifest. We try adding it in case it is in one but not in both.\r\n            auto nameScore = EditDistanceScore(manifestNameAndPublisher.Name, arpNameAndPublisher.Name);\r\n\r\n            // Ignore cases where the name is not at all similar to avoid matching due to publisher only\r\n            if (nameScore < m_nameMatchingScoreMinThreshold)\r\n            {\r\n                continue;\r\n            }\r\n\r\n            auto publisherScore = EditDistanceScore(manifestNameAndPublisher.Publisher, arpNameAndPublisher.Publisher);\r\n            auto namePublisherScore = std::max(\r\n                EditDistanceScore(manifestNameAndPublisher.NamePublisher, arpNameAndPublisher.Name),\r\n                EditDistanceScore(manifestNameAndPublisher.Name, arpNameAndPublisher.NamePublisher));\r\n\r\n            // Use the best between considering name and publisher as a single string or separately.\r\n            auto score = std::max(\r\n                nameScore * m_nameMatchingScoreWeight + publisherScore * (1 - m_nameMatchingScoreWeight),\r\n                namePublisherScore);\r\n            bestMatchingScore = std::max(bestMatchingScore, score);\r\n        }\r\n\r\n        // Factor in whether this entry is new\r\n        auto result = bestMatchingScore * m_stringMatchingWeight + (arpEntry.IsNewOrUpdated ? 1 : 0) * (1 - m_stringMatchingWeight);\r\n\r\n        return result;\r\n    }\r\n\r\n    WordSequence WordsEditDistanceMatchConfidenceAlgorithm::PrepareString(std::string_view s) const\r\n    {\r\n        return Utility::SplitIntoWords(Utility::FoldCase(s));\r\n    }\r\n\r\n    WordSequence WordsEditDistanceMatchConfidenceAlgorithm::NormalizeAndPrepareName(std::string_view name) const\r\n    {\r\n        return PrepareString(m_normalizer.NormalizeName(name).Name());\r\n    }\r\n\r\n    WordSequence WordsEditDistanceMatchConfidenceAlgorithm::NormalizeAndPreparePublisher(std::string_view publisher) const\r\n    {\r\n        return PrepareString(m_normalizer.NormalizePublisher(publisher));\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" />\r\n  <PropertyGroup Label=\"Globals\">\r\n    <CppWinRTOptimized>true</CppWinRTOptimized>\r\n    <CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>\r\n    <MinimalCoreWin>true</MinimalCoreWin>\r\n    <VCProjectVersion>15.0</VCProjectVersion>\r\n    <ProjectGuid>{5eb88068-5fb9-4e69-89b2-72dbc5e068f9}</ProjectGuid>\r\n    <Keyword>Win32Proj</Keyword>\r\n    <RootNamespace>AppInstallerRepositoryCore</RootNamespace>\r\n    <WindowsTargetPlatformVersion>10.0.26100.0</WindowsTargetPlatformVersion>\r\n    <WindowsTargetPlatformMinVersion>10.0.17763.0</WindowsTargetPlatformMinVersion>\r\n    <WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|ARM64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|Win32\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|ARM64\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|Win32\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|x64\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|ARM64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|Win32\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <PropertyGroup Label=\"Configuration\">\r\n    <ConfigurationType>StaticLibrary</ConfigurationType>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Debug'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n    <LinkIncremental>true</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Release'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <LinkIncremental>false</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='ReleaseStatic'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <LinkIncremental>false</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\" Label=\"Configuration\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\" Label=\"Configuration\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\" Label=\"Configuration\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\r\n  <ImportGroup Label=\"ExtensionSettings\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"Shared\">\r\n    <Import Project=\"..\\CertificateResources\\CertificateResources.vcxitems\" Label=\"Shared\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"PropertySheet.props\" />\r\n  </ImportGroup>\r\n  <PropertyGroup Label=\"UserMacros\" />\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>true</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>true</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>true</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(ProjectDir)\\..\\vcpkg.props\" />\r\n  <ItemDefinitionGroup>\r\n    <ClCompile>\r\n      <PrecompiledHeader>Use</PrecompiledHeader>\r\n      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>\r\n      <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>\r\n      <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <AdditionalOptions>%(AdditionalOptions) /permissive- /bigobj /D _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING</AdditionalOptions>\r\n    </ClCompile>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Debug'\">\r\n    <ClCompile>\r\n      <Optimization>Disabled</Optimization>\r\n      <PreprocessorDefinitions>_NO_ASYNCRTIMP;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;_DEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">$(ProjectDir);$(ProjectDir)\\Public;$(ProjectDir)..\\AppInstallerCommonCore\\Public;$(ProjectDir)..\\AppInstallerSharedLib\\Public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">$(ProjectDir);$(ProjectDir)\\Public;$(ProjectDir)..\\AppInstallerCommonCore\\Public;$(ProjectDir)..\\AppInstallerSharedLib\\Public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</TreatWarningAsError>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</EnablePREfast>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">Windows</SubSystem>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Platform)'=='Win32'\">\r\n    <ClCompile>\r\n      <PreprocessorDefinitions>_NO_ASYNCRTIMP;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;WIN32;%(PreprocessorDefinitions);CLICOREDLLBUILD</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">$(ProjectDir);$(ProjectDir)\\Public;$(ProjectDir)..\\AppInstallerCommonCore\\Public;$(ProjectDir)..\\AppInstallerSharedLib\\Public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</TreatWarningAsError>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</EnablePREfast>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Windows</SubSystem>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Release'\">\r\n    <ClCompile>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>_NO_ASYNCRTIMP;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;NDEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">$(ProjectDir);$(ProjectDir)\\Public;$(ProjectDir)..\\AppInstallerCommonCore\\Public;$(ProjectDir)..\\AppInstallerSharedLib\\Public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">$(ProjectDir);$(ProjectDir)\\Public;$(ProjectDir)..\\AppInstallerCommonCore\\Public;$(ProjectDir)..\\AppInstallerSharedLib\\Public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">$(ProjectDir);$(ProjectDir)\\Public;$(ProjectDir)..\\AppInstallerCommonCore\\Public;$(ProjectDir)..\\AppInstallerSharedLib\\Public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">true</TreatWarningAsError>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</EnablePREfast>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Windows</SubSystem>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='ReleaseStatic'\">\r\n    <ClCompile>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>_NO_ASYNCRTIMP;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;NDEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">$(ProjectDir);$(ProjectDir)\\Public;$(ProjectDir)..\\AppInstallerCommonCore\\Public;$(ProjectDir)..\\AppInstallerSharedLib\\Public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">$(ProjectDir);$(ProjectDir)\\Public;$(ProjectDir)..\\AppInstallerCommonCore\\Public;$(ProjectDir)..\\AppInstallerSharedLib\\Public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">$(ProjectDir);$(ProjectDir)\\Public;$(ProjectDir)..\\AppInstallerCommonCore\\Public;$(ProjectDir)..\\AppInstallerSharedLib\\Public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">true</TreatWarningAsError>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">false</EnablePREfast>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">MultiThreaded</RuntimeLibrary>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">MultiThreaded</RuntimeLibrary>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">MultiThreaded</RuntimeLibrary>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">Windows</SubSystem>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"ArpVersionValidation.h\" />\r\n    <ClInclude Include=\"CompositeSource.h\" />\r\n    <ClInclude Include=\"IconDefs.h\" />\r\n    <ClInclude Include=\"ISource.h\" />\r\n    <ClInclude Include=\"MatchCriteriaResolver.h\" />\r\n    <ClInclude Include=\"Microsoft\\ARPHelper.h\" />\r\n    <ClInclude Include=\"Microsoft\\FontHelper.h\" />\r\n    <ClInclude Include=\"Microsoft\\PinningIndex.h\" />\r\n    <ClInclude Include=\"Microsoft\\PredefinedInstalledSourceFactory.h\" />\r\n    <ClInclude Include=\"Microsoft\\PredefinedWriteableSourceFactory.h\" />\r\n    <ClInclude Include=\"Microsoft\\PreIndexedPackageSourceFactory.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\ChannelTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\CommandsTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\IdTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\Interface.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\ManifestTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\MonikerTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\NameTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\OneToManyTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\OneToOneTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\PathPartTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\SearchResultsTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\TagsTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\VersionTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\VirtualTableBase.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_1\\Interface.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_1\\ManifestMetadataTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_1\\PackageFamilyNameTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_1\\ProductCodeTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_1\\SearchResultsTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_2\\Interface.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_2\\NormalizedPackageNameTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_2\\NormalizedPackagePublisherTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_2\\SearchResultsTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_3\\HashVirtualTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_3\\Interface.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_4\\DependenciesTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_4\\Interface.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_5\\ArpVersionVirtualTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_5\\Interface.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_6\\Interface.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_6\\SearchResultsTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_6\\UpgradeCodeTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_7\\Interface.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\CommandsTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\Interface.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\NormalizedPackageNameTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\NormalizedPackagePublisherTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\PackageFamilyNameTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\PackagesTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\OneToManyTableWithMap.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\PackageUpdateTrackingTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\ProductCodeTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\SearchResultsTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\SystemReferenceStringTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\TagsTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\UpgradeCodeTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\IPinningIndex.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\IPortableIndex.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\ICheckpointDatabase.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\ISQLiteIndex.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\SQLiteIndexContextData.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\Pinning_1_0\\PinningIndexInterface.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\Pinning_1_0\\PinTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\Portable_1_0\\PortableIndexInterface.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\Portable_1_0\\PortableTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\Checkpoint_1_0\\CheckpointDataTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\Checkpoint_1_0\\CheckpointDatabaseInterface.h\" />\r\n    <ClInclude Include=\"Microsoft\\Schema\\Checkpoint_1_0\\CheckpointTable.h\" />\r\n    <ClInclude Include=\"Microsoft\\SQLiteIndex.h\" />\r\n    <ClInclude Include=\"Microsoft\\SQLiteIndexSource.h\" />\r\n    <ClInclude Include=\"Microsoft\\ConfigurableTestSourceFactory.h\" />\r\n    <ClInclude Include=\"Microsoft\\SQLiteIndexSourceV1.h\" />\r\n    <ClInclude Include=\"Microsoft\\SQLiteIndexSourceV2.h\" />\r\n    <ClInclude Include=\"PackageDependenciesValidation.h\" />\r\n    <ClInclude Include=\"PackageTrackingCatalogSourceFactory.h\" />\r\n    <ClInclude Include=\"pch.h\" />\r\n    <ClInclude Include=\"Public\\winget\\ARPCorrelation.h\" />\r\n    <ClInclude Include=\"Public\\winget\\Checkpoint.h\" />\r\n    <ClInclude Include=\"Public\\winget\\CheckpointDatabase.h\" />\r\n    <ClInclude Include=\"Public\\winget\\IconExtraction.h\" />\r\n    <ClInclude Include=\"Public\\winget\\InstalledFilesCorrelation.h\" />\r\n    <ClInclude Include=\"Public\\winget\\InstalledStatus.h\" />\r\n    <ClInclude Include=\"Public\\winget\\InstallerMetadataCollectionContext.h\" />\r\n    <ClInclude Include=\"Public\\winget\\ManifestJSONParser.h\" />\r\n    <ClInclude Include=\"Public\\winget\\ARPCorrelationAlgorithms.h\" />\r\n    <ClInclude Include=\"Public\\winget\\PackageTrackingCatalog.h\" />\r\n    <ClInclude Include=\"Public\\winget\\PackageVersionSelection.h\" />\r\n    <ClInclude Include=\"Public\\winget\\PinningData.h\" />\r\n    <ClInclude Include=\"Public\\winget\\PortableIndex.h\" />\r\n    <ClInclude Include=\"Public\\winget\\RepositorySearch.h\" />\r\n    <ClInclude Include=\"Public\\winget\\RepositorySource.h\" />\r\n    <ClInclude Include=\"Rest\\RestClient.h\" />\r\n    <ClInclude Include=\"Rest\\RestInformationCache.h\" />\r\n    <ClInclude Include=\"Rest\\RestSource.h\" />\r\n    <ClInclude Include=\"Rest\\RestSourceFactory.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\1_0\\Interface.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\1_0\\Json\\ManifestDeserializer.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\1_0\\Json\\SearchRequestSerializer.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\1_0\\Json\\SearchResponseDeserializer.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\1_10\\Interface.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\1_10\\Json\\ManifestDeserializer.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\1_12\\Interface.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\1_12\\Json\\ManifestDeserializer.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\1_1\\Interface.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\1_1\\Json\\ManifestDeserializer.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\1_1\\Json\\SearchRequestSerializer.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\1_4\\Interface.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\1_4\\Json\\ManifestDeserializer.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\1_4\\Json\\SearchResponseDeserializer.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\1_5\\Interface.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\1_5\\Json\\ManifestDeserializer.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\1_6\\Interface.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\1_6\\Json\\ManifestDeserializer.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\1_7\\Interface.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\1_7\\Json\\ManifestDeserializer.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\1_9\\Interface.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\1_9\\Json\\ManifestDeserializer.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\AuthenticationInfoParser.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\CommonRestConstants.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\InformationResponseDeserializer.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\IRestClient.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\SearchRequestComposer.h\" />\r\n    <ClInclude Include=\"Rest\\Schema\\SearchResponseParser.h\" />\r\n    <ClInclude Include=\"SourceFactory.h\" />\r\n    <ClInclude Include=\"SourceList.h\" />\r\n    <ClInclude Include=\"SourcePolicy.h\" />\r\n    <ClInclude Include=\"SourceUpdateChecks.h\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"ARPCorrelation.cpp\" />\r\n    <ClCompile Include=\"ARPCorrelationAlgorithms.cpp\" />\r\n    <ClCompile Include=\"IconExtraction.cpp\" />\r\n    <ClCompile Include=\"ArpVersionValidation.cpp\" />\r\n    <ClCompile Include=\"CompositeSource.cpp\" />\r\n    <ClCompile Include=\"InstalledFilesCorrelation.cpp\" />\r\n    <ClCompile Include=\"InstallerMetadataCollectionContext.cpp\" />\r\n    <ClCompile Include=\"ManifestJSONParser.cpp\" />\r\n    <ClCompile Include=\"MatchCriteriaResolver.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\ARPHelper.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\FontHelper.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\ConfigurableTestSourceFactory.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\PinningIndex.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\PortableIndex.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\PredefinedInstalledSourceFactory.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\PredefinedWriteableSourceFactory.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\PreIndexedPackageSourceFactory.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\CheckpointDatabase.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_0\\Interface_1_0.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_0\\ManifestTable.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_0\\OneToManyTable.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_0\\OneToOneTable.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_0\\PathPartTable.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_0\\SearchResultsTable_1_0.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_1\\Interface_1_1.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_1\\ManifestMetadataTable.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_1\\SearchResultsTable_1_1.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_2\\Interface_1_2.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_2\\SearchResultsTable_1_2.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_3\\Interface_1_3.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_4\\DependenciesTable.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_4\\Interface_1_4.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_5\\Interface_1_5.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_6\\Interface_1_6.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_6\\SearchResultsTable_1_6.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_7\\Interface_1_7.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\2_0\\Interface_2_0.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\2_0\\PackagesTable.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\2_0\\OneToManyTableWithMap.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\2_0\\PackageUpdateTrackingTable.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\2_0\\SearchResultsTable_2_0.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\2_0\\SystemReferenceStringTable.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\ISQLiteIndex.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\Pinning_1_0\\PinningIndexInterface_1_0.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\Pinning_1_0\\PinTable.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\Portable_1_0\\PortableIndexInterface_1_0.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\Portable_1_0\\PortableTable.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\Checkpoint_1_0\\CheckpointDataTable.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\Checkpoint_1_0\\CheckpointDatabaseInterface_1_0.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\Schema\\Checkpoint_1_0\\CheckpointTable.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\SQLiteIndex.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\SQLiteIndexSource.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\SQLiteIndexSourceV1.cpp\" />\r\n    <ClCompile Include=\"Microsoft\\SQLiteIndexSourceV2.cpp\" />\r\n    <ClCompile Include=\"PackageDependenciesValidation.cpp\" />\r\n    <ClCompile Include=\"PackageInstalledStatus.cpp\" />\r\n    <ClCompile Include=\"PackageTrackingCatalog.cpp\" />\r\n    <ClCompile Include=\"PackageVersionSelection.cpp\" />\r\n    <ClCompile Include=\"pch.cpp\">\r\n      <PrecompiledHeader>Create</PrecompiledHeader>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PinningData.cpp\" />\r\n    <ClCompile Include=\"RepositorySearch.cpp\" />\r\n    <ClCompile Include=\"RepositorySource.cpp\" />\r\n    <ClCompile Include=\"Rest\\RestClient.cpp\" />\r\n    <ClCompile Include=\"Rest\\RestInformationCache.cpp\" />\r\n    <ClCompile Include=\"Rest\\RestSource.cpp\" />\r\n    <ClCompile Include=\"Rest\\RestSourceFactory.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\1_0\\RestInterface_1_0.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\1_0\\Json\\ManifestDeserializer_1_0.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\1_0\\Json\\SearchRequestSerializer_1_0.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\1_0\\Json\\SearchResponseDeserializer_1_0.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\1_10\\Json\\ManifestDeserializer_1_10.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\1_10\\RestInterface_1_10.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\1_12\\Json\\ManifestDeserializer_1_12.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\1_12\\RestInterface_1_12.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\1_1\\Json\\ManifestDeserializer_1_1.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\1_1\\Json\\SearchRequestSerializer_1_1.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\1_1\\RestInterface_1_1.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\1_4\\Json\\ManifestDeserializer_1_4.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\1_4\\Json\\SearchResponseDeserializer_1_4.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\1_4\\RestInterface_1_4.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\1_5\\Json\\ManifestDeserializer_1_5.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\1_5\\RestInterface_1_5.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\1_6\\Json\\ManifestDeserializer_1_6.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\1_6\\RestInterface_1_6.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\1_7\\Json\\ManifestDeserializer_1_7.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\1_7\\RestInterface_1_7.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\1_9\\Json\\ManifestDeserializer_1_9.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\1_9\\RestInterface_1_9.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\AuthenticationInfoParser.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\InformationResponseDeserializer.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\SearchRequestComposer.cpp\" />\r\n    <ClCompile Include=\"Rest\\Schema\\SearchResponseParser.cpp\" />\r\n    <ClCompile Include=\"SourceList.cpp\" />\r\n    <ClCompile Include=\"SourcePolicy.cpp\" />\r\n    <ClCompile Include=\"SourceUpdateChecks.cpp\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"Microsoft\\README.md\" />\r\n    <None Include=\"packages.config\" />\r\n    <None Include=\"PropertySheet.props\" />\r\n  </ItemGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\r\n  <ImportGroup Label=\"ExtensionTargets\">\r\n    <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets')\" />\r\n    <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" />\r\n  </ImportGroup>\r\n  <Target Name=\"EnsureNuGetPackageBuildImports\" BeforeTargets=\"PrepareForBuild\">\r\n    <PropertyGroup>\r\n      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>\r\n    </PropertyGroup>\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets'))\" />\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props'))\" />\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets'))\" />\r\n  </Target>\r\n</Project>"
  },
  {
    "path": "src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj.filters",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup>\r\n    <Filter Include=\"Source Files\">\r\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Header Files\">\r\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r\n      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Resource Files\">\r\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Microsoft\">\r\n      <UniqueIdentifier>{2d97761a-4967-4ece-b5fd-d96f346731ed}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Microsoft\\Schema\">\r\n      <UniqueIdentifier>{7996cf09-4e36-4009-b48d-53ffc3bfa956}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Microsoft\\Schema\\1_0\">\r\n      <UniqueIdentifier>{cff561cd-211b-4cab-87f5-39359eef1e8d}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Public\">\r\n      <UniqueIdentifier>{69ce2e35-fe7f-41af-bd47-91a70131d167}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Microsoft\\Schema\\1_1\">\r\n      <UniqueIdentifier>{aef8989c-44fd-4848-ae2c-c81d3f2e2c72}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Microsoft\\Schema\\1_2\">\r\n      <UniqueIdentifier>{dc8b6163-e9b5-4d05-87bc-d6098afe0f92}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Rest\">\r\n      <UniqueIdentifier>{7f16f6e0-12c6-4bb9-885e-3f8b666d5f74}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Rest\\Schema\">\r\n      <UniqueIdentifier>{15a1ee83-4118-40fe-ba43-c54d7185d505}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Rest\\Schema\\1_0\">\r\n      <UniqueIdentifier>{8a93b62f-d065-4048-b43a-a2b14b70c330}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Rest\\Schema\\1_0\\Json\">\r\n      <UniqueIdentifier>{6bcbaf7a-289f-4d0b-b128-67bef903745c}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Microsoft\\Schema\\1_3\">\r\n      <UniqueIdentifier>{15639b2c-ce61-4a18-995a-a73cf1a5817e}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Rest\\Schema\\1_1\">\r\n      <UniqueIdentifier>{9d8095ed-07de-4bc9-bfe7-630b781586d0}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Rest\\Schema\\1_1\\Json\">\r\n      <UniqueIdentifier>{2cc20cdb-dcb2-4e0e-b04f-e2d838146100}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Public\\winget\">\r\n      <UniqueIdentifier>{aa7315bc-4eb0-4280-9572-f5a25f6e73ad}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Microsoft\\Schema\\1_4\">\r\n      <UniqueIdentifier>{dcae9c55-cdd7-4381-8acd-3554896608a5}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Microsoft\\Schema\\1_5\">\r\n      <UniqueIdentifier>{e31c8e5b-ed2c-43c8-b91b-db8ec4c52f71}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Microsoft\\Schema\\1_6\">\r\n      <UniqueIdentifier>{84a55def-9fb8-4c90-8d5a-2cedc171940b}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Microsoft\\Schema\\Portable_1_0\">\r\n      <UniqueIdentifier>{edef5ff7-9bfe-48f8-a179-e343d1a8b57f}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Rest\\Schema\\1_4\">\r\n      <UniqueIdentifier>{4f5950e2-1713-4c1e-84ce-f868cfcb3a68}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Rest\\Schema\\1_4\\Json\">\r\n      <UniqueIdentifier>{d9d70cf5-ce04-4db2-a0ec-970dd0ad22b6}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Rest\\Schema\\1_5\">\r\n      <UniqueIdentifier>{f131c993-1136-4f4c-85a9-8606c6d297a8}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Rest\\Schema\\1_5\\Json\">\r\n      <UniqueIdentifier>{78cf34a8-b868-4393-ad9c-630940569186}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Microsoft\\Schema\\Pinning_1_0\">\r\n      <UniqueIdentifier>{f05e19bb-2161-4ab0-9d04-2dfa2d3eb3c6}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Rest\\Schema\\1_6\">\r\n      <UniqueIdentifier>{21da32f5-b918-436e-96a9-465525f90259}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Rest\\Schema\\1_6\\Json\">\r\n      <UniqueIdentifier>{b2e78f3d-931e-432c-8485-255b1dbc9db7}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Microsoft\\Schema\\1_7\">\r\n      <UniqueIdentifier>{f610927a-6f1d-42c5-9ad9-b59790091944}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Microsoft\\Schema\\Checkpoint_1_0\">\r\n      <UniqueIdentifier>{a3f9c7ed-f487-40d6-9ee7-e9a052e55c29}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Rest\\Schema\\1_7\">\r\n      <UniqueIdentifier>{f42acfce-4fc0-435b-a9a2-bf5528aecbcc}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Rest\\Schema\\1_7\\Json\">\r\n      <UniqueIdentifier>{7fd6c265-81c0-4c6e-87b2-24bef117e21d}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Microsoft\\Schema\\2_0\">\r\n      <UniqueIdentifier>{34442899-29e5-4183-96ba-a1e8740146be}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Rest\\Schema\\1_9\">\r\n      <UniqueIdentifier>{8edd7018-8836-4b15-84c1-998391e19038}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Rest\\Schema\\1_9\\Json\">\r\n      <UniqueIdentifier>{7464e3ff-7a60-4bb6-8806-70562382043b}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Rest\\Schema\\1_10\">\r\n      <UniqueIdentifier>{da801426-6d3b-40ca-b204-152e7e18067b}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Rest\\Schema\\1_10\\Json\">\r\n      <UniqueIdentifier>{1a1efb9f-7332-4094-bb98-a4c51ea68b24}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Rest\\Schema\\1_12\">\r\n      <UniqueIdentifier>{c29ae113-5eb6-41af-b64d-fac925dcf2c2}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Rest\\Schema\\1_12\\Json\">\r\n      <UniqueIdentifier>{2075b51e-aa11-473a-bae0-e0d4366f926b}</UniqueIdentifier>\r\n    </Filter>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"pch.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\SQLiteIndex.h\">\r\n      <Filter>Microsoft</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\ISQLiteIndex.h\">\r\n      <Filter>Microsoft\\Schema</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\Interface.h\">\r\n      <Filter>Microsoft\\Schema\\1_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\OneToOneTable.h\">\r\n      <Filter>Microsoft\\Schema\\1_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\IdTable.h\">\r\n      <Filter>Microsoft\\Schema\\1_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\ChannelTable.h\">\r\n      <Filter>Microsoft\\Schema\\1_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\MonikerTable.h\">\r\n      <Filter>Microsoft\\Schema\\1_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\NameTable.h\">\r\n      <Filter>Microsoft\\Schema\\1_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\VersionTable.h\">\r\n      <Filter>Microsoft\\Schema\\1_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\OneToManyTable.h\">\r\n      <Filter>Microsoft\\Schema\\1_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\TagsTable.h\">\r\n      <Filter>Microsoft\\Schema\\1_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\CommandsTable.h\">\r\n      <Filter>Microsoft\\Schema\\1_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\ManifestTable.h\">\r\n      <Filter>Microsoft\\Schema\\1_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\PathPartTable.h\">\r\n      <Filter>Microsoft\\Schema\\1_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"SourceFactory.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\PreIndexedPackageSourceFactory.h\">\r\n      <Filter>Microsoft</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\SQLiteIndexSource.h\">\r\n      <Filter>Microsoft</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\SearchResultsTable.h\">\r\n      <Filter>Microsoft\\Schema\\1_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_1\\Interface.h\">\r\n      <Filter>Microsoft\\Schema\\1_1</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_1\\PackageFamilyNameTable.h\">\r\n      <Filter>Microsoft\\Schema\\1_1</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_1\\ProductCodeTable.h\">\r\n      <Filter>Microsoft\\Schema\\1_1</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_1\\SearchResultsTable.h\">\r\n      <Filter>Microsoft\\Schema\\1_1</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\PredefinedInstalledSourceFactory.h\">\r\n      <Filter>Microsoft</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"CompositeSource.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_1\\ManifestMetadataTable.h\">\r\n      <Filter>Microsoft\\Schema\\1_1</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\ARPHelper.h\">\r\n      <Filter>Microsoft</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\FontHelper.h\">\r\n      <Filter>Microsoft</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_2\\Interface.h\">\r\n      <Filter>Microsoft\\Schema\\1_2</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_2\\SearchResultsTable.h\">\r\n      <Filter>Microsoft\\Schema\\1_2</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_2\\NormalizedPackageNameTable.h\">\r\n      <Filter>Microsoft\\Schema\\1_2</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_2\\NormalizedPackagePublisherTable.h\">\r\n      <Filter>Microsoft\\Schema\\1_2</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\1_0\\Interface.h\">\r\n      <Filter>Rest\\Schema\\1_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\IRestClient.h\">\r\n      <Filter>Rest\\Schema</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\RestClient.h\">\r\n      <Filter>Rest</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\RestSource.h\">\r\n      <Filter>Rest</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\RestSourceFactory.h\">\r\n      <Filter>Rest</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\1_0\\Json\\ManifestDeserializer.h\">\r\n      <Filter>Rest\\Schema\\1_0\\Json</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\1_0\\Json\\SearchRequestSerializer.h\">\r\n      <Filter>Rest\\Schema\\1_0\\Json</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\1_0\\Json\\SearchResponseDeserializer.h\">\r\n      <Filter>Rest\\Schema\\1_0\\Json</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\CommonRestConstants.h\">\r\n      <Filter>Rest\\Schema</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_3\\Interface.h\">\r\n      <Filter>Microsoft\\Schema\\1_3</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_3\\HashVirtualTable.h\">\r\n      <Filter>Microsoft\\Schema\\1_3</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"SourceList.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"SourcePolicy.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\PredefinedWriteableSourceFactory.h\">\r\n      <Filter>Microsoft</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\InformationResponseDeserializer.h\">\r\n      <Filter>Rest\\Schema</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\1_1\\Interface.h\">\r\n      <Filter>Rest\\Schema\\1_1</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\1_1\\Json\\ManifestDeserializer.h\">\r\n      <Filter>Rest\\Schema\\1_1\\Json</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\1_1\\Json\\SearchRequestSerializer.h\">\r\n      <Filter>Rest\\Schema\\1_1\\Json</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\ConfigurableTestSourceFactory.h\">\r\n      <Filter>Microsoft</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\PackageTrackingCatalog.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\RepositorySearch.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\RepositorySource.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ISource.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_4\\DependenciesTable.h\">\r\n      <Filter>Microsoft\\Schema\\1_4</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_4\\Interface.h\">\r\n      <Filter>Microsoft\\Schema\\1_4</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"PackageTrackingCatalogSourceFactory.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"PackageDependenciesValidation.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\ARPCorrelation.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\ManifestJSONParser.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\InstallerMetadataCollectionContext.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\ARPCorrelationAlgorithms.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_5\\ArpVersionVirtualTable.h\">\r\n      <Filter>Microsoft\\Schema\\1_5</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_5\\Interface.h\">\r\n      <Filter>Microsoft\\Schema\\1_5</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ArpVersionValidation.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_0\\VirtualTableBase.h\">\r\n      <Filter>Microsoft\\Schema\\1_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_6\\Interface.h\">\r\n      <Filter>Microsoft\\Schema\\1_6</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_6\\UpgradeCodeTable.h\">\r\n      <Filter>Microsoft\\Schema\\1_6</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_6\\SearchResultsTable.h\">\r\n      <Filter>Microsoft\\Schema\\1_6</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\Portable_1_0\\PortableIndexInterface.h\">\r\n      <Filter>Microsoft\\Schema\\Portable_1_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\Portable_1_0\\PortableTable.h\">\r\n      <Filter>Microsoft\\Schema\\Portable_1_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\IPortableIndex.h\">\r\n      <Filter>Microsoft\\Schema</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\1_4\\Json\\ManifestDeserializer.h\">\r\n      <Filter>Rest\\Schema\\1_4\\Json</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\1_4\\Interface.h\">\r\n      <Filter>Rest\\Schema\\1_4</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\1_4\\Json\\SearchResponseDeserializer.h\">\r\n      <Filter>Rest\\Schema\\1_4\\Json</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\1_5\\Json\\ManifestDeserializer.h\">\r\n      <Filter>Rest\\Schema\\1_5\\Json</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\1_5\\Interface.h\">\r\n      <Filter>Rest\\Schema\\1_5</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\SearchRequestComposer.h\">\r\n      <Filter>Rest\\Schema</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\SearchResponseParser.h\">\r\n      <Filter>Rest\\Schema</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\IPinningIndex.h\">\r\n      <Filter>Microsoft\\Schema</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\PinningIndex.h\">\r\n      <Filter>Microsoft</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\Pinning_1_0\\PinningIndexInterface.h\">\r\n      <Filter>Microsoft\\Schema\\Pinning_1_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\Pinning_1_0\\PinTable.h\">\r\n      <Filter>Microsoft\\Schema\\Pinning_1_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\InstalledFilesCorrelation.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"IconDefs.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\IconExtraction.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\1_6\\Json\\ManifestDeserializer.h\">\r\n      <Filter>Rest\\Schema\\1_6\\Json</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\1_6\\Interface.h\">\r\n      <Filter>Rest\\Schema\\1_6</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\1_7\\Interface.h\">\r\n      <Filter>Microsoft\\Schema\\1_7</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\ICheckpointDatabase.h\">\r\n      <Filter>Microsoft\\Schema</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\Checkpoint_1_0\\CheckpointDataTable.h\">\r\n      <Filter>Microsoft\\Schema\\Checkpoint_1_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\Checkpoint_1_0\\CheckpointDatabaseInterface.h\">\r\n      <Filter>Microsoft\\Schema\\Checkpoint_1_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\Checkpoint_1_0\\CheckpointTable.h\">\r\n      <Filter>Microsoft\\Schema\\Checkpoint_1_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\Checkpoint.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"SourceUpdateChecks.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\1_7\\Interface.h\">\r\n      <Filter>Rest\\Schema\\1_7</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\AuthenticationInfoParser.h\">\r\n      <Filter>Rest\\Schema</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\PinningData.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\PortableIndex.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\CheckpointDatabase.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\InstalledStatus.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\PackageVersionSelection.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\1_7\\Json\\ManifestDeserializer.h\">\r\n      <Filter>Rest\\Schema\\1_7\\Json</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\CommandsTable.h\">\r\n      <Filter>Microsoft\\Schema\\2_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\Interface.h\">\r\n      <Filter>Microsoft\\Schema\\2_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\PackagesTable.h\">\r\n      <Filter>Microsoft\\Schema\\2_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\OneToManyTableWithMap.h\">\r\n      <Filter>Microsoft\\Schema\\2_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\SearchResultsTable.h\">\r\n      <Filter>Microsoft\\Schema\\2_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\TagsTable.h\">\r\n      <Filter>Microsoft\\Schema\\2_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\SystemReferenceStringTable.h\">\r\n      <Filter>Microsoft\\Schema\\2_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\PackageFamilyNameTable.h\">\r\n      <Filter>Microsoft\\Schema\\2_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\NormalizedPackageNameTable.h\">\r\n      <Filter>Microsoft\\Schema\\2_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\NormalizedPackagePublisherTable.h\">\r\n      <Filter>Microsoft\\Schema\\2_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\ProductCodeTable.h\">\r\n      <Filter>Microsoft\\Schema\\2_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\UpgradeCodeTable.h\">\r\n      <Filter>Microsoft\\Schema\\2_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\2_0\\PackageUpdateTrackingTable.h\">\r\n      <Filter>Microsoft\\Schema\\2_0</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\Schema\\SQLiteIndexContextData.h\">\r\n      <Filter>Microsoft\\Schema</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\SQLiteIndexSourceV1.h\">\r\n      <Filter>Microsoft</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Microsoft\\SQLiteIndexSourceV2.h\">\r\n      <Filter>Microsoft</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\1_9\\Json\\ManifestDeserializer.h\">\r\n      <Filter>Rest\\Schema\\1_9\\Json</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\1_9\\Interface.h\">\r\n      <Filter>Rest\\Schema\\1_9</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\1_10\\Interface.h\">\r\n      <Filter>Rest\\Schema\\1_10</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\1_10\\Json\\ManifestDeserializer.h\">\r\n      <Filter>Rest\\Schema\\1_10\\Json</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\1_12\\Interface.h\">\r\n      <Filter>Rest\\Schema\\1_12</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\Schema\\1_12\\Json\\ManifestDeserializer.h\">\r\n      <Filter>Rest\\Schema\\1_12\\Json</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Rest\\RestInformationCache.h\">\r\n      <Filter>Rest</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"MatchCriteriaResolver.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"pch.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\SQLiteIndex.cpp\">\r\n      <Filter>Microsoft</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_0\\OneToOneTable.cpp\">\r\n      <Filter>Microsoft\\Schema\\1_0</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_0\\OneToManyTable.cpp\">\r\n      <Filter>Microsoft\\Schema\\1_0</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_0\\ManifestTable.cpp\">\r\n      <Filter>Microsoft\\Schema\\1_0</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_0\\PathPartTable.cpp\">\r\n      <Filter>Microsoft\\Schema\\1_0</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"RepositorySource.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\PreIndexedPackageSourceFactory.cpp\">\r\n      <Filter>Microsoft</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\SQLiteIndexSource.cpp\">\r\n      <Filter>Microsoft</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_0\\Interface_1_0.cpp\">\r\n      <Filter>Microsoft\\Schema\\1_0</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_1\\Interface_1_1.cpp\">\r\n      <Filter>Microsoft\\Schema\\1_1</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_0\\SearchResultsTable_1_0.cpp\">\r\n      <Filter>Microsoft\\Schema\\1_0</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_1\\SearchResultsTable_1_1.cpp\">\r\n      <Filter>Microsoft\\Schema\\1_1</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\PredefinedInstalledSourceFactory.cpp\">\r\n      <Filter>Microsoft</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"CompositeSource.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_1\\ManifestMetadataTable.cpp\">\r\n      <Filter>Microsoft\\Schema\\1_1</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\ARPHelper.cpp\">\r\n      <Filter>Microsoft</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\FontHelper.cpp\">\r\n      <Filter>Microsoft</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_2\\Interface_1_2.cpp\">\r\n      <Filter>Microsoft\\Schema\\1_2</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_2\\SearchResultsTable_1_2.cpp\">\r\n      <Filter>Microsoft\\Schema\\1_2</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\1_0\\RestInterface_1_0.cpp\">\r\n      <Filter>Rest\\Schema\\1_0</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\RestClient.cpp\">\r\n      <Filter>Rest</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\RestSource.cpp\">\r\n      <Filter>Rest</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\RestSourceFactory.cpp\">\r\n      <Filter>Rest</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\1_0\\Json\\ManifestDeserializer_1_0.cpp\">\r\n      <Filter>Rest\\Schema\\1_0\\Json</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\1_0\\Json\\SearchRequestSerializer_1_0.cpp\">\r\n      <Filter>Rest\\Schema\\1_0\\Json</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\1_0\\Json\\SearchResponseDeserializer_1_0.cpp\">\r\n      <Filter>Rest\\Schema\\1_0\\Json</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_3\\Interface_1_3.cpp\">\r\n      <Filter>Microsoft\\Schema\\1_3</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"SourceList.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"SourcePolicy.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\InformationResponseDeserializer.cpp\">\r\n      <Filter>Rest\\Schema</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\PredefinedWriteableSourceFactory.cpp\">\r\n      <Filter>Microsoft</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\1_1\\RestInterface_1_1.cpp\">\r\n      <Filter>Rest\\Schema\\1_1</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\1_1\\Json\\ManifestDeserializer_1_1.cpp\">\r\n      <Filter>Rest\\Schema\\1_1\\Json</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\1_1\\Json\\SearchRequestSerializer_1_1.cpp\">\r\n      <Filter>Rest\\Schema\\1_1\\Json</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\ConfigurableTestSourceFactory.cpp\">\r\n      <Filter>Microsoft</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PackageTrackingCatalog.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"RepositorySearch.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_4\\DependenciesTable.cpp\">\r\n      <Filter>Microsoft\\Schema\\1_4</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_4\\Interface_1_4.cpp\">\r\n      <Filter>Microsoft\\Schema\\1_4</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PackageDependenciesValidation.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ARPCorrelation.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ManifestJSONParser.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"InstallerMetadataCollectionContext.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ARPCorrelationAlgorithms.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_5\\Interface_1_5.cpp\">\r\n      <Filter>Microsoft\\Schema\\1_5</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ArpVersionValidation.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_6\\Interface_1_6.cpp\">\r\n      <Filter>Microsoft\\Schema\\1_6</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_6\\SearchResultsTable_1_6.cpp\">\r\n      <Filter>Microsoft\\Schema\\1_6</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\PortableIndex.cpp\">\r\n      <Filter>Microsoft</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\Portable_1_0\\PortableIndexInterface_1_0.cpp\">\r\n      <Filter>Microsoft\\Schema\\Portable_1_0</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\Portable_1_0\\PortableTable.cpp\">\r\n      <Filter>Microsoft\\Schema\\Portable_1_0</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\1_4\\Json\\ManifestDeserializer_1_4.cpp\">\r\n      <Filter>Rest\\Schema\\1_4\\Json</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\1_4\\RestInterface_1_4.cpp\">\r\n      <Filter>Rest\\Schema\\1_4</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\1_4\\Json\\SearchResponseDeserializer_1_4.cpp\">\r\n      <Filter>Rest\\Schema\\1_4\\Json</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\1_5\\Json\\ManifestDeserializer_1_5.cpp\">\r\n      <Filter>Rest\\Schema\\1_5\\Json</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\1_5\\RestInterface_1_5.cpp\">\r\n      <Filter>Rest\\Schema\\1_5</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\SearchRequestComposer.cpp\">\r\n      <Filter>Rest\\Schema</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\SearchResponseParser.cpp\">\r\n      <Filter>Rest\\Schema</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PackageInstalledStatus.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\PinningIndex.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\Pinning_1_0\\PinTable.cpp\">\r\n      <Filter>Microsoft\\Schema\\Pinning_1_0</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"InstalledFilesCorrelation.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"IconExtraction.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\1_6\\Json\\ManifestDeserializer_1_6.cpp\">\r\n      <Filter>Rest\\Schema\\1_6\\Json</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\1_6\\RestInterface_1_6.cpp\">\r\n      <Filter>Rest\\Schema\\1_6</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\1_7\\Interface_1_7.cpp\">\r\n      <Filter>Microsoft\\Schema\\1_7</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\CheckpointDatabase.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\Checkpoint_1_0\\CheckpointDataTable.cpp\">\r\n      <Filter>Microsoft\\Schema\\Checkpoint_1_0</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\Checkpoint_1_0\\CheckpointTable.cpp\">\r\n      <Filter>Microsoft\\Schema\\Checkpoint_1_0</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"SourceUpdateChecks.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\Checkpoint_1_0\\CheckpointDatabaseInterface_1_0.cpp\">\r\n      <Filter>Microsoft\\Schema\\Checkpoint_1_0</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\Pinning_1_0\\PinningIndexInterface_1_0.cpp\">\r\n      <Filter>Microsoft\\Schema\\Pinning_1_0</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\1_7\\RestInterface_1_7.cpp\">\r\n      <Filter>Rest\\Schema\\1_7</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\AuthenticationInfoParser.cpp\">\r\n      <Filter>Rest\\Schema</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PinningData.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PackageVersionSelection.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\1_7\\Json\\ManifestDeserializer_1_7.cpp\">\r\n      <Filter>Rest\\Schema\\1_7\\Json</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\2_0\\Interface_2_0.cpp\">\r\n      <Filter>Microsoft\\Schema\\2_0</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\2_0\\PackagesTable.cpp\">\r\n      <Filter>Microsoft\\Schema\\2_0</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\2_0\\OneToManyTableWithMap.cpp\">\r\n      <Filter>Microsoft\\Schema\\2_0</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\2_0\\SearchResultsTable_2_0.cpp\">\r\n      <Filter>Microsoft\\Schema\\2_0</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\ISQLiteIndex.cpp\">\r\n      <Filter>Microsoft\\Schema</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\2_0\\SystemReferenceStringTable.cpp\">\r\n      <Filter>Microsoft\\Schema\\2_0</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\Schema\\2_0\\PackageUpdateTrackingTable.cpp\">\r\n      <Filter>Microsoft\\Schema\\2_0</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\SQLiteIndexSourceV1.cpp\">\r\n      <Filter>Microsoft</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Microsoft\\SQLiteIndexSourceV2.cpp\">\r\n      <Filter>Microsoft</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\1_9\\Json\\ManifestDeserializer_1_9.cpp\">\r\n      <Filter>Rest\\Schema\\1_9\\Json</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\1_9\\RestInterface_1_9.cpp\">\r\n      <Filter>Rest\\Schema\\1_9</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\1_10\\RestInterface_1_10.cpp\">\r\n      <Filter>Rest\\Schema\\1_10</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\1_10\\Json\\ManifestDeserializer_1_10.cpp\">\r\n      <Filter>Rest\\Schema\\1_10\\Json</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\1_12\\RestInterface_1_12.cpp\">\r\n      <Filter>Rest\\Schema\\1_12</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\Schema\\1_12\\Json\\ManifestDeserializer_1_12.cpp\">\r\n      <Filter>Rest\\Schema\\1_12\\Json</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Rest\\RestInformationCache.cpp\">\r\n      <Filter>Rest</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"MatchCriteriaResolver.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"PropertySheet.props\" />\r\n    <None Include=\"packages.config\" />\r\n    <None Include=\"Microsoft\\README.md\">\r\n      <Filter>Microsoft</Filter>\r\n    </None>\r\n  </ItemGroup>\r\n</Project>"
  },
  {
    "path": "src/AppInstallerRepositoryCore/ArpVersionValidation.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"pch.h\"\r\n#include \"ArpVersionValidation.h\"\r\n#include <winget/ManifestValidation.h>\r\n\r\nnamespace AppInstaller::Repository\r\n{\r\n    namespace\r\n    {\r\n        std::vector<Utility::VersionRange> GetArpVersionRangesByPackageRowId(const Microsoft::SQLiteIndex* index, Microsoft::SQLiteIndex::IdType packageRowId, const Utility::VersionAndChannel& excludeVersionAndChannel = {})\r\n        {\r\n            std::vector<Utility::VersionRange> result;\r\n\r\n            auto versionKeys = index->GetVersionKeysById(packageRowId);\r\n            for (auto const& versionKey : versionKeys)\r\n            {\r\n                // For manifest update, the manifest to be updated does not need to be checked.\r\n                // In unlikely cases if both version 1.0.0 and 1.0 of the same package exist, we compare raw values here as what sqlite index does.\r\n                if (versionKey.VersionAndChannel.GetVersion().ToString() == excludeVersionAndChannel.GetVersion().ToString() &&\r\n                    versionKey.VersionAndChannel.GetChannel().ToString() == excludeVersionAndChannel.GetChannel().ToString())\r\n                {\r\n                    continue;\r\n                }\r\n\r\n                auto arpMinVersion = index->GetPropertyByPrimaryId(versionKey.ManifestId, PackageVersionProperty::ArpMinVersion).value_or(\"\");\r\n                auto arpMaxVersion = index->GetPropertyByPrimaryId(versionKey.ManifestId, PackageVersionProperty::ArpMaxVersion).value_or(\"\");\r\n\r\n                // Either both empty or both not empty\r\n                THROW_HR_IF(E_UNEXPECTED, arpMinVersion.empty() != arpMaxVersion.empty());\r\n\r\n                if (!arpMinVersion.empty() && !arpMaxVersion.empty())\r\n                {\r\n                    result.emplace_back(Utility::VersionRange{ Utility::Version{ std::move(arpMinVersion) }, Utility::Version{ std::move(arpMaxVersion) } });\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n\r\n    void ValidateManifestArpVersion(const Microsoft::SQLiteIndex* index, const Manifest::Manifest& manifest)\r\n    {\r\n        try\r\n        {\r\n            auto manifestArpVersionRange = manifest.GetArpVersionRange();\r\n            if (manifestArpVersionRange.IsEmpty())\r\n            {\r\n                return;\r\n            }\r\n\r\n            SearchRequest request;\r\n            request.Filters.emplace_back(PackageMatchField::Id, MatchType::CaseInsensitive, manifest.Id);\r\n            auto searchResult = index->Search(request);\r\n            if (searchResult.Matches.empty())\r\n            {\r\n                return;\r\n            }\r\n\r\n            auto arpVersionRangesInIndex = GetArpVersionRangesByPackageRowId(index, searchResult.Matches[0].first, { Utility::Version{ manifest.Version }, Utility::Channel{ manifest.Channel } });\r\n            for (auto const& arpInIndex : arpVersionRangesInIndex)\r\n            {\r\n                if (manifestArpVersionRange.Overlaps(arpInIndex))\r\n                {\r\n                    std::string context = (\" [\" + arpInIndex.GetMinVersion().ToString() + \", \" + arpInIndex.GetMaxVersion().ToString() + \"]\");\r\n                    auto validationError = Manifest::ValidationError(Manifest::ManifestError::ArpVersionOverlapWithIndex, context);\r\n                    \r\n                    AICLI_LOG(Repo, Error, << validationError.GetErrorMessage() << context);\r\n                    THROW_EXCEPTION(Manifest::ManifestException(\r\n                        { validationError },\r\n                        APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED));\r\n                }\r\n            }\r\n        }\r\n        catch (const Manifest::ManifestException&)\r\n        {\r\n            // Prevent ManifestException from being wrapped in another ManifestException\r\n            throw;\r\n        }\r\n        catch (...)\r\n        {\r\n            AICLI_LOG(Repo, Error, << \"ValidateManifestArpVersion() encountered internal error.\");\r\n            THROW_EXCEPTION(Manifest::ManifestException(\r\n                { Manifest::ValidationError(Manifest::ManifestError::ArpVersionValidationInternalError) },\r\n                APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED));\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/ArpVersionValidation.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"Microsoft/SQLiteIndex.h\"\n#include <winget/Manifest.h>\n\nnamespace AppInstaller::Repository\n{\n    // Validate the manifest arp version range against index. Any validation failures will be thrown as ManifestException for better message back to caller.\n    void ValidateManifestArpVersion(const Microsoft::SQLiteIndex* index, const Manifest::Manifest& manifest);\n}\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/CompositeSource.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"CompositeSource.h\"\r\n#include <winget/ExperimentalFeature.h>\r\n\r\nusing namespace AppInstaller::Settings;\r\n\r\nnamespace AppInstaller::Repository\r\n{\r\n    using namespace std::string_view_literals;\r\n\r\n    namespace anon\r\n    {\r\n        Utility::VersionAndChannel GetVACFromVersion(IPackageVersion* packageVersion)\r\n        {\r\n            return {\r\n                Utility::Version(packageVersion->GetProperty(PackageVersionProperty::Version)),\r\n                Utility::Channel(packageVersion->GetProperty(PackageVersionProperty::Channel))\r\n            };\r\n        }\r\n\r\n        // Returns true for fields that provide a strong match; one that is not based on a heuristic.\r\n        bool IsStrongMatchField(PackageMatchField field)\r\n        {\r\n            switch (field)\r\n            {\r\n            case AppInstaller::Repository::PackageMatchField::PackageFamilyName:\r\n            case AppInstaller::Repository::PackageMatchField::ProductCode:\r\n            case AppInstaller::Repository::PackageMatchField::UpgradeCode:\r\n                return true;\r\n            }\r\n\r\n            return false;\r\n        }\r\n\r\n        // Gets the only available package from the composite, ensuring this fact in test contexts.\r\n        std::shared_ptr<IPackage> OnlyAvailable(const std::shared_ptr<ICompositePackage>& composite)\r\n        {\r\n            std::vector<std::shared_ptr<IPackage>> availablePackages = composite->GetAvailable();\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n            THROW_HR_IF(E_UNEXPECTED, availablePackages.size() != 1);\r\n#endif\r\n\r\n            return std::move(availablePackages.front());\r\n        }\r\n\r\n        // Move returns if there is only one package in the matches that is strong; otherwise returns an empty value.\r\n        std::shared_ptr<ICompositePackage> FindOnlyStrongMatchFieldResult(std::vector<ResultMatch>& matches)\r\n        {\r\n            std::shared_ptr<ICompositePackage> result;\r\n\r\n            for (auto&& match : matches)\r\n            {\r\n                AICLI_LOG(Repo, Info, << \"  Checking match with package id: \" << match.Package->GetProperty(PackageProperty::Id));\r\n\r\n                if (IsStrongMatchField(match.MatchCriteria.Field))\r\n                {\r\n                    if (!result)\r\n                    {\r\n                        result = std::move(match.Package);\r\n                    }\r\n                    else\r\n                    {\r\n                        AICLI_LOG(Repo, Info, << \"  Found multiple packages with strong match fields\");\r\n                        result.reset();\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        // Gets a single matching package from the results\r\n        template <typename MultipleIntro, typename Indeterminate>\r\n        std::shared_ptr<ICompositePackage> GetMatchingPackage(std::vector<ResultMatch>& matches, MultipleIntro&& multipleIntro, Indeterminate&& indeterminate)\r\n        {\r\n            if (matches.empty())\r\n            {\r\n                return {};\r\n            }\r\n            else if (matches.size() == 1)\r\n            {\r\n                return std::move(matches[0].Package);\r\n            }\r\n            else\r\n            {\r\n                multipleIntro();\r\n\r\n                auto result = FindOnlyStrongMatchFieldResult(matches);\r\n\r\n                if (!result)\r\n                {\r\n                    indeterminate();\r\n                }\r\n\r\n                return result;\r\n            }\r\n        }\r\n\r\n        // For a given package from a tracking catalog, get the latest write time.\r\n        // Look at all versions rather than just the latest to account for the potential of downgrading.\r\n        std::chrono::system_clock::time_point GetLatestTrackingWriteTime(\r\n            const std::shared_ptr<IPackage>& trackingPackage)\r\n        {\r\n            std::chrono::system_clock::time_point result{};\r\n\r\n            for (const auto& key : trackingPackage->GetVersionKeys())\r\n            {\r\n                auto version = trackingPackage->GetVersion(key);\r\n                if (version)\r\n                {\r\n                    auto metadata = version->GetMetadata();\r\n                    auto itr = metadata.find(PackageVersionMetadata::TrackingWriteTime);\r\n                    if (itr != metadata.end())\r\n                    {\r\n                        std::int64_t unixEpoch = 0;\r\n                        try\r\n                        {\r\n                            unixEpoch = std::stoll(itr->second);\r\n                        }\r\n                        CATCH_LOG();\r\n\r\n                        std::chrono::system_clock::time_point versionTime = Utility::ConvertUnixEpochToSystemClock(unixEpoch);\r\n\r\n                        if (versionTime > result)\r\n                        {\r\n                            result = versionTime;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        // An installed package's version reported in ARP does not necessarily match the versions used for the manifest.\r\n        // This function uses the data in the manifest to map the installed version string to the version used by the manifest.\r\n        //\r\n        // TODO: Note: Currently this function assumes the all versions in the available package is from one source.\r\n        // Even though a composite package can have available packages from multiple sources, we only call this function\r\n        // for the default (first) available package. If we ever need to consider other sources, this function needs to be revisited.\r\n        std::string GetMappedInstalledVersion(const std::string& installedVersion, const std::shared_ptr<IPackage>& availablePackage)\r\n        {\r\n            // Perform an initial check to see if the latest version has a mapping; if it does not, do not attempt any more.\r\n            auto latestVersion = availablePackage->GetLatestVersion();\r\n            if (latestVersion)\r\n            {\r\n                auto version = latestVersion->GetProperty(PackageVersionProperty::Version);\r\n                auto arpMinVersion = latestVersion->GetProperty(PackageVersionProperty::ArpMinVersion);\r\n                auto arpMaxVersion = latestVersion->GetProperty(PackageVersionProperty::ArpMaxVersion);\r\n\r\n                if ((arpMinVersion.empty() || arpMinVersion == version) && (arpMaxVersion.empty() || arpMaxVersion == version))\r\n                {\r\n                    return installedVersion;\r\n                }\r\n            }\r\n\r\n            // Stores raw versions value strings to run a preliminary check whether version mapping is needed.\r\n            std::vector<std::tuple<std::string, std::string, std::string>> rawVersionValues;\r\n            auto versionKeys = availablePackage->GetVersionKeys();\r\n            bool shouldTryPerformMapping = false;\r\n\r\n            for (auto const& versionKey : versionKeys)\r\n            {\r\n                auto availableVersion = availablePackage->GetVersion(versionKey);\r\n                std::string arpMinVersion = availableVersion->GetProperty(PackageVersionProperty::ArpMinVersion);\r\n                std::string arpMaxVersion = availableVersion->GetProperty(PackageVersionProperty::ArpMaxVersion);\r\n\r\n                if (!arpMinVersion.empty() && !arpMaxVersion.empty())\r\n                {\r\n                    std::string manifestVersion = versionKey.Version;\r\n\r\n                    if (!shouldTryPerformMapping && (arpMinVersion != manifestVersion || arpMaxVersion != manifestVersion))\r\n                    {\r\n                        shouldTryPerformMapping = true;\r\n                    }\r\n\r\n                    rawVersionValues.emplace_back(std::make_tuple(std::move(manifestVersion), std::move(arpMinVersion), std::move(arpMaxVersion)));\r\n                }\r\n            }\r\n\r\n            if (!shouldTryPerformMapping)\r\n            {\r\n                return installedVersion;\r\n            }\r\n\r\n            // Construct a map between manifest version and arp version range. The map is ordered in descending by package version.\r\n            std::vector<std::pair<Utility::Version, Utility::VersionRange>> arpVersionMap;\r\n\r\n            for (auto& tuple : rawVersionValues)\r\n            {\r\n                auto&& [manifestVersion, arpMinVersion, arpMaxVersion] = std::move(tuple);\r\n                Utility::VersionRange arpVersionRange{ Utility::Version(std::move(arpMinVersion)), Utility::Version(std::move(arpMaxVersion)) };\r\n                Utility::Version manifestVer{ std::move(manifestVersion) };\r\n                // Skip mapping to unknown version\r\n                if (!manifestVer.IsUnknown())\r\n                {\r\n                    arpVersionMap.emplace_back(std::make_pair(std::move(manifestVer), std::move(arpVersionRange)));\r\n                }\r\n            }\r\n\r\n            // Go through the arp version map and determine what mapping should be performed.\r\n            // shouldPerformMapping is true when at least 1 arp version range is different from the package version.\r\n            bool shouldPerformMapping = false;\r\n            bool isArpVersionRangeInDescendingOrder = true;\r\n            const Utility::VersionRange* previousVersionRange = nullptr;\r\n\r\n            for (auto const& pair : arpVersionMap)\r\n            {\r\n                // If arp version range is not same as package version, should perform mapping\r\n                // This check is still needed to account for 1.0 == 1.0.0 cases\r\n                if (!shouldPerformMapping && !pair.second.IsSameAsSingleVersion(pair.first))\r\n                {\r\n                    shouldPerformMapping = true;\r\n                }\r\n\r\n                if (!previousVersionRange)\r\n                {\r\n                    // This is the first non empty arp version range\r\n                    previousVersionRange = &pair.second;\r\n                }\r\n                else if (isArpVersionRangeInDescendingOrder)\r\n                {\r\n                    // The arp version range should be less than previous range\r\n                    if (pair.second < *previousVersionRange)\r\n                    {\r\n                        previousVersionRange = &pair.second;\r\n                    }\r\n                    else\r\n                    {\r\n                        isArpVersionRangeInDescendingOrder = false;\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Now perform arp version mapping\r\n            if (shouldPerformMapping)\r\n            {\r\n                Utility::Version installed{ installedVersion };\r\n                for (auto const& pair : arpVersionMap)\r\n                {\r\n                    // If the installed version is in the arp version range\r\n                    if (pair.second.ContainsVersion(installed))\r\n                    {\r\n                        return pair.first.ToString();\r\n                    }\r\n                }\r\n\r\n                // At this point, no mapping found. Perform approximate mapping if applicable.\r\n                // We'll start from end of the vector because we try to find closest less than version if possible.\r\n                if (isArpVersionRangeInDescendingOrder)\r\n                {\r\n                    const Utility::Version* lastGreaterThanVersion = nullptr;\r\n                    auto it = arpVersionMap.rbegin();\r\n                    while (it != arpVersionMap.rend())\r\n                    {\r\n                        const auto& pair = *it;\r\n                        if (installed < pair.second.GetMinVersion())\r\n                        {\r\n                            return Utility::Version{ pair.first, Utility::Version::ApproximateComparator::LessThan }.ToString();\r\n                        }\r\n                        else\r\n                        {\r\n                            lastGreaterThanVersion = &pair.first;\r\n                        }\r\n                        \r\n                        it++;\r\n                    }\r\n\r\n                    // No approximate less than version found, approximate greater than version will be returned.\r\n                    if (lastGreaterThanVersion)\r\n                    {\r\n                        return Utility::Version{ *lastGreaterThanVersion, Utility::Version::ApproximateComparator::GreaterThan }.ToString();\r\n                    }\r\n                }\r\n            }\r\n\r\n            // return the input installed version if no mapping is performed or found.\r\n            return installedVersion;\r\n        }\r\n\r\n        // A composite package installed version that allows us to override the source or the version.\r\n        struct CompositeInstalledVersion : public IPackageVersion\r\n        {\r\n            CompositeInstalledVersion(std::shared_ptr<IPackageVersion> baseInstalledVersion, Source trackingSource, std::shared_ptr<IPackageVersion> trackingPackageVersion, std::string overrideVersion = {}) :\r\n                m_baseInstalledVersion(std::move(baseInstalledVersion)), m_trackingSource(std::move(trackingSource)), m_trackingPackageVersion(std::move(trackingPackageVersion)), m_overrideVersion(std::move(overrideVersion))\r\n            {}\r\n\r\n            Utility::LocIndString GetProperty(PackageVersionProperty property) const override\r\n            {\r\n                // If there is an override version, use it.\r\n                if (property == PackageVersionProperty::Version && !m_overrideVersion.empty())\r\n                {\r\n                    return Utility::LocIndString{ m_overrideVersion };\r\n                }\r\n\r\n                return m_baseInstalledVersion->GetProperty(property);\r\n            }\r\n\r\n            std::vector<Utility::LocIndString> GetMultiProperty(PackageVersionMultiProperty property) const override\r\n            {\r\n                return m_baseInstalledVersion->GetMultiProperty(property);\r\n            }\r\n\r\n            Manifest::Manifest GetManifest() override\r\n            {\r\n                return m_baseInstalledVersion->GetManifest();\r\n            }\r\n\r\n            Source GetSource() const override\r\n            {\r\n                // If there is a tracking source, use it instead to indicate that it came from there.\r\n                if (m_trackingSource)\r\n                {\r\n                    return m_trackingSource;\r\n                }\r\n\r\n                return m_baseInstalledVersion->GetSource();\r\n            }\r\n\r\n            Metadata GetMetadata() const override\r\n            {\r\n                auto result = m_baseInstalledVersion->GetMetadata();\r\n\r\n                // Populate metadata from tracking package version if not present in base installed version.\r\n                if (m_trackingPackageVersion)\r\n                {\r\n                    auto trackingMetadata = m_trackingPackageVersion->GetMetadata();\r\n                    for (auto metadataItem : { PackageVersionMetadata::InstalledArchitecture, PackageVersionMetadata::InstalledLocale,\r\n                        PackageVersionMetadata::UserIntentArchitecture, PackageVersionMetadata::UserIntentLocale, PackageVersionMetadata::PinnedState })\r\n                    {\r\n                        auto itr = trackingMetadata.find(metadataItem);\r\n                        auto existingItr = result.find(metadataItem);\r\n                        if (itr != trackingMetadata.end() && existingItr == result.end())\r\n                        {\r\n                            result[metadataItem] = itr->second;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                return result;\r\n            }\r\n\r\n        private:\r\n            std::shared_ptr<IPackageVersion> m_baseInstalledVersion;\r\n            Source m_trackingSource;\r\n            std::string m_overrideVersion;\r\n            std::shared_ptr<IPackageVersion> m_trackingPackageVersion;\r\n        };\r\n\r\n        // An IPackage for the installed package of a CompositePackage.\r\n        struct CompositeInstalledPackage : public IPackage\r\n        {\r\n            static constexpr IPackageType PackageType = IPackageType::CompositeInstalledPackage;\r\n\r\n            CompositeInstalledPackage(std::shared_ptr<IPackage> package)\r\n            {\r\n                AddPackageAndVersionKeyData(std::move(package));\r\n            }\r\n\r\n            Utility::LocIndString GetProperty(PackageProperty property) const override\r\n            {\r\n                THROW_HR_IF(E_UNEXPECTED, m_packages.empty() || m_versionKeyData.empty());\r\n\r\n                // Use the highest version for package properties\r\n                return m_packages[m_versionKeyData[0].PackageIndex]->GetProperty(property);\r\n            }\r\n\r\n            std::vector<Utility::LocIndString> GetMultiProperty(PackageMultiProperty property) const override\r\n            {\r\n                std::vector<Utility::LocIndString> result;\r\n\r\n                for (const auto& package : m_packages)\r\n                {\r\n                    for (auto&& string : package->GetMultiProperty(property))\r\n                    {\r\n                        auto itr = std::lower_bound(result.begin(), result.end(), string);\r\n\r\n                        if (itr == result.end() || *itr != string)\r\n                        {\r\n                            result.emplace(itr, std::move(string));\r\n                        }\r\n                    }\r\n                }\r\n\r\n                return result;\r\n            }\r\n\r\n            std::vector<PackageVersionKey> GetVersionKeys() const override\r\n            {\r\n                return { m_versionKeyData.begin(), m_versionKeyData.end() };\r\n            }\r\n\r\n            std::shared_ptr<IPackageVersion> GetVersion(const PackageVersionKey& versionKey) const override\r\n            {\r\n                std::shared_ptr<IPackageVersion> installedVersion;\r\n                std::string overrideVersion;\r\n\r\n                for (const VersionKeyData& key : m_versionKeyData)\r\n                {\r\n                    if (key.IsMatch(versionKey))\r\n                    {\r\n                        installedVersion = key.InstalledVersion;\r\n                        overrideVersion = key.Version;\r\n                        break;\r\n                    }\r\n                }\r\n\r\n                if (installedVersion)\r\n                {\r\n                    // Get the appropriate tracking version or latest if it is not found.\r\n                    // The tracking package uses the mapped version.\r\n                    std::shared_ptr<IPackageVersion> trackingPackageVersion;\r\n                    if (m_trackingPackage)\r\n                    {\r\n                        // Remove our use of the package id as source\r\n                        PackageVersionKey versionKey_NoSource = versionKey;\r\n                        versionKey_NoSource.SourceId.clear();\r\n\r\n                        trackingPackageVersion = m_trackingPackage->GetVersion(versionKey_NoSource);\r\n\r\n                        if (!trackingPackageVersion)\r\n                        {\r\n                            trackingPackageVersion = m_trackingPackage->GetLatestVersion();\r\n                        }\r\n                    }\r\n\r\n                    return std::make_shared<CompositeInstalledVersion>(std::move(installedVersion), m_trackingSource, std::move(trackingPackageVersion), std::move(overrideVersion));\r\n                }\r\n\r\n                return nullptr;\r\n            }\r\n\r\n            std::shared_ptr<IPackageVersion> GetLatestVersion() const override\r\n            {\r\n                return GetVersion({});\r\n            }\r\n\r\n            Source GetSource() const override\r\n            {\r\n                // If there is a tracking source, use it instead to indicate that it came from there.\r\n                // Otherwise, all of the installed packages should be from the same source.\r\n                return m_trackingSource ? m_trackingSource : m_packages[0]->GetSource();\r\n            }\r\n\r\n            bool IsSame(const IPackage* other) const override\r\n            {\r\n                const CompositeInstalledPackage* otherPackage = PackageCast<const CompositeInstalledPackage*>(other);\r\n\r\n                if (otherPackage)\r\n                {\r\n                    if (m_packages.size() != otherPackage->m_packages.size())\r\n                    {\r\n                        return false;\r\n                    }\r\n\r\n                    for (const auto& subPackage : m_packages)\r\n                    {\r\n                        bool foundSame = false;\r\n\r\n                        for (const auto& otherSubPackage : otherPackage->m_packages)\r\n                        {\r\n                            if (subPackage->IsSame(otherSubPackage.get()))\r\n                            {\r\n                                foundSame = true;\r\n                                break;\r\n                            }\r\n                        }\r\n\r\n                        if (!foundSame)\r\n                        {\r\n                            return false;\r\n                        }\r\n                    }\r\n\r\n                    return true;\r\n                }\r\n\r\n                return false;\r\n            }\r\n\r\n            const void* CastTo(IPackageType type) const override\r\n            {\r\n                if (type == PackageType)\r\n                {\r\n                    return this;\r\n                }\r\n\r\n                return nullptr;\r\n            }\r\n\r\n            void SetTracking(\r\n                Source trackingSource,\r\n                std::shared_ptr<IPackage> trackingPackage,\r\n                std::chrono::system_clock::time_point trackingWriteTime)\r\n            {\r\n                m_trackingSource = std::move(trackingSource);\r\n                m_trackingPackage = std::move(trackingPackage);\r\n                m_trackingWriteTime = trackingWriteTime;\r\n            }\r\n\r\n            Source GetTrackingSource() const\r\n            {\r\n                return m_trackingSource;\r\n            }\r\n\r\n            const std::shared_ptr<IPackage>& GetTrackingPackage() const\r\n            {\r\n                return m_trackingPackage;\r\n            }\r\n\r\n            std::chrono::system_clock::time_point GetTrackingPackageWriteTime() const\r\n            {\r\n                return m_trackingWriteTime;\r\n            }\r\n\r\n            bool ContainsInstalledPackage(const IPackage* installedPackage) const\r\n            {\r\n                for (const auto& package : m_packages)\r\n                {\r\n                    if (package->IsSame(installedPackage))\r\n                    {\r\n                        return true;\r\n                    }\r\n                }\r\n\r\n                return false;\r\n            }\r\n\r\n            void FoldInstalledIn(const std::shared_ptr<CompositeInstalledPackage>& other)\r\n            {\r\n                for (const auto& package : other->m_packages)\r\n                {\r\n                    AddPackageAndVersionKeyData(package);\r\n                }\r\n            }\r\n\r\n            // Set a version that will override the version string from the installed package\r\n            void SetOverrideInstalledVersion(const std::shared_ptr<IPackage>& availablePackage)\r\n            {\r\n                if (availablePackage)\r\n                {\r\n                    m_availablePackageVersionOverride = availablePackage;\r\n\r\n                    for (auto& key : m_versionKeyData)\r\n                    {\r\n                        if (Manifest::DoesInstallerTypeSupportArpVersionRange(key.InstalledType))\r\n                        {\r\n                            key.Version = GetMappedInstalledVersion(key.InstalledVersion->GetProperty(PackageVersionProperty::Version), availablePackage);\r\n                            key.VersionAndChannel = Utility::VersionAndChannel{ key.Version, key.Channel };\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            bool IsEmpty() const\r\n            {\r\n                return m_versionKeyData.empty();\r\n            }\r\n\r\n        private:\r\n            // Contains information about all of the version keys.\r\n            // We use the `SourceId` field to store the installed package identifier so that we can disambiguate keys is they have the same version.\r\n            struct VersionKeyData : public PackageVersionKey\r\n            {\r\n                size_t PackageIndex;\r\n                std::shared_ptr<IPackageVersion> InstalledVersion;\r\n                Manifest::InstallerTypeEnum InstalledType;\r\n                Utility::VersionAndChannel VersionAndChannel;\r\n\r\n                bool operator<(const VersionKeyData& other) const\r\n                {\r\n                    return VersionAndChannel < other.VersionAndChannel;\r\n                }\r\n            };\r\n\r\n            // Adds the package and version key data to the composite.\r\n            // The version keys are then sorted so that the first (index 0) in the vector has the highest version.\r\n            // Note that it may tied for highest version if, for instance, the same version is installed for different architectures.\r\n            void AddPackageAndVersionKeyData(std::shared_ptr<IPackage> package)\r\n            {\r\n                // We don't want this to happen, but it could. Rather than a crash, we will log it and move on.\r\n                if (!package)\r\n                {\r\n                    AICLI_LOG(Repo, Verbose, << \"AddPackageAndVersionKeyData called with an empty package\");\r\n                    return;\r\n                }\r\n\r\n                size_t packageIndex = m_packages.size();\r\n                std::string packageIdentifier = package->GetProperty(PackageProperty::Id);\r\n                bool versionAdded = false;\r\n\r\n                for (const auto& versionKey : package->GetVersionKeys())\r\n                {\r\n                    VersionKeyData keyData{ versionKey };\r\n\r\n                    keyData.PackageIndex = packageIndex;\r\n                    keyData.InstalledVersion = package->GetVersion(versionKey);\r\n\r\n                    if (!keyData.InstalledVersion)\r\n                    {\r\n                        AICLI_LOG(Repo, Verbose, << \"AddPackageAndVersionKeyData: Package [\" << packageIdentifier << \"] did not return a version for [\" << versionKey.Version << \"]\");\r\n                        continue;\r\n                    }\r\n\r\n                    // We use the `SourceId` field to store the installed package identifier so that we can disambiguate keys if they have the same version.\r\n                    keyData.SourceId = packageIdentifier;\r\n\r\n                    keyData.InstalledType = Manifest::ConvertToInstallerTypeEnum(keyData.InstalledVersion->GetMetadata()[PackageVersionMetadata::InstalledType]);\r\n                    if (m_availablePackageVersionOverride && Manifest::DoesInstallerTypeSupportArpVersionRange(keyData.InstalledType))\r\n                    {\r\n                        keyData.Version = GetMappedInstalledVersion(keyData.InstalledVersion->GetProperty(PackageVersionProperty::Version), m_availablePackageVersionOverride);\r\n                    }\r\n\r\n                    keyData.VersionAndChannel = Utility::VersionAndChannel{ keyData.Version, keyData.Channel };\r\n\r\n                    m_versionKeyData.emplace_back(std::move(keyData));\r\n                    versionAdded = true;\r\n                }\r\n\r\n                if (versionAdded)\r\n                {\r\n                    m_packages.emplace_back(std::move(package));\r\n\r\n                    std::sort(m_versionKeyData.begin(), m_versionKeyData.end());\r\n                }\r\n            }\r\n\r\n            std::vector<std::shared_ptr<IPackage>> m_packages;\r\n            std::vector<VersionKeyData> m_versionKeyData;\r\n            Source m_trackingSource;\r\n            std::shared_ptr<IPackage> m_trackingPackage;\r\n            std::chrono::system_clock::time_point m_trackingWriteTime = std::chrono::system_clock::time_point::min();\r\n            std::shared_ptr<IPackage> m_availablePackageVersionOverride;\r\n        };\r\n\r\n        // An ICompositePackage for the CompositeSource.\r\n        struct CompositePackage : public ICompositePackage\r\n        {\r\n            // The availablePackage may only contain one available package within it, as it is expected to be the output of a search on a single source.\r\n            CompositePackage(const std::shared_ptr<ICompositePackage>& installedPackage, const std::shared_ptr<ICompositePackage>& availablePackage = {}, bool setPrimary = false)\r\n            {\r\n                if (installedPackage)\r\n                {\r\n                    m_installedPackage = std::make_shared<CompositeInstalledPackage>(installedPackage->GetInstalled());\r\n\r\n                    // If the installed package result existed, but didn't actually create any installed versions, drop it.\r\n                    if (m_installedPackage->IsEmpty())\r\n                    {\r\n                        m_installedPackage.reset();\r\n                    }\r\n                }\r\n\r\n                AddAvailablePackage(availablePackage, setPrimary);\r\n            }\r\n\r\n            Utility::LocIndString GetProperty(PackageProperty property) const override\r\n            {\r\n                IPackage* truth = nullptr;\r\n                if (m_primaryAvailablePackage)\r\n                {\r\n                    truth = m_primaryAvailablePackage.get();\r\n                }\r\n                if (!truth && !m_availablePackages.empty())\r\n                {\r\n                    truth = m_availablePackages[0].get();\r\n                }\r\n                if (!truth)\r\n                {\r\n                    truth = m_installedPackage.get();\r\n                }\r\n\r\n                THROW_HR_IF(E_UNEXPECTED, !truth);\r\n\r\n                return truth->GetProperty(property);\r\n            }\r\n\r\n            std::shared_ptr<IPackage> GetInstalled() override\r\n            {\r\n                return m_installedPackage;\r\n            }\r\n\r\n            std::vector<std::shared_ptr<IPackage>> GetAvailable() override\r\n            {\r\n                return m_availablePackages;\r\n            }\r\n\r\n            const std::vector<std::shared_ptr<IPackage>>& GetAvailablePackages()\r\n            {\r\n                return m_availablePackages;\r\n            }\r\n\r\n            bool IsSameAsAnyAvailable(const IPackage* other) const\r\n            {\r\n                if (other)\r\n                {\r\n                    for (const auto& availablePackage : m_availablePackages)\r\n                    {\r\n                        if (other->IsSame(availablePackage.get()))\r\n                        {\r\n                            return true;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                return false;\r\n            }\r\n\r\n            const std::shared_ptr<CompositeInstalledPackage>& GetInstalledPackage() const\r\n            {\r\n                return m_installedPackage;\r\n            }\r\n\r\n            bool ContainsInstalledPackage(const IPackage* installedPackage) const\r\n            {\r\n                return m_installedPackage ? m_installedPackage->ContainsInstalledPackage(installedPackage) : false;\r\n            }\r\n\r\n            void AddAvailablePackage(const std::shared_ptr<ICompositePackage>& availablePackage, bool setPrimary = false)\r\n            {\r\n                if (availablePackage)\r\n                {\r\n                    m_availablePackages.emplace_back(OnlyAvailable(availablePackage));\r\n\r\n                    if (setPrimary)\r\n                    {\r\n                        m_primaryAvailablePackage = m_availablePackages.back();\r\n                    }\r\n\r\n                    // Set override for primary or with the first available version found\r\n                    if (setPrimary || m_availablePackages.size() == 1)\r\n                    {\r\n                        TrySetOverrideInstalledVersion(m_availablePackages.back());\r\n                    }\r\n                }\r\n            }\r\n\r\n            std::shared_ptr<IPackage>& GetPrimaryAvailablePackage()\r\n            {\r\n                return m_primaryAvailablePackage;\r\n            }\r\n\r\n            Source GetTrackingSource() const\r\n            {\r\n                return m_installedPackage ? m_installedPackage->GetTrackingSource() : Source{};\r\n            }\r\n\r\n            std::shared_ptr<IPackage> GetTrackingPackage() const\r\n            {\r\n                return m_installedPackage ? m_installedPackage->GetTrackingPackage() : std::shared_ptr<IPackage>{};\r\n            }\r\n\r\n            std::chrono::system_clock::time_point GetTrackingPackageWriteTime() const\r\n            {\r\n                return m_installedPackage ? m_installedPackage->GetTrackingPackageWriteTime() : std::chrono::system_clock::time_point::min();\r\n            }\r\n\r\n            void SetTracking(\r\n                Source trackingSource,\r\n                std::shared_ptr<IPackage> trackingPackage,\r\n                std::chrono::system_clock::time_point trackingWriteTime)\r\n            {\r\n                if (m_installedPackage)\r\n                {\r\n                    m_installedPackage->SetTracking(std::move(trackingSource), std::move(trackingPackage), trackingWriteTime);\r\n                }\r\n            }\r\n\r\n            void FoldInstalledIn(const std::shared_ptr<CompositePackage>& other)\r\n            {\r\n                if (other->m_installedPackage)\r\n                {\r\n                    if (m_installedPackage)\r\n                    {\r\n                        m_installedPackage->FoldInstalledIn(other->m_installedPackage);\r\n                    }\r\n                    else\r\n                    {\r\n                        m_installedPackage = other->m_installedPackage;\r\n                    }\r\n                }\r\n            }\r\n\r\n        private:\r\n            // Try to set a version that will override the version string from the installed package\r\n            void TrySetOverrideInstalledVersion(const std::shared_ptr<IPackage>& availablePackage)\r\n            {\r\n                if (m_installedPackage && availablePackage)\r\n                {\r\n                    m_installedPackage->SetOverrideInstalledVersion(availablePackage);\r\n                }\r\n            }\r\n\r\n            std::shared_ptr<CompositeInstalledPackage> m_installedPackage;\r\n            std::shared_ptr<IPackage> m_primaryAvailablePackage;\r\n            std::vector<std::shared_ptr<IPackage>> m_availablePackages;\r\n        };\r\n\r\n        // The comparator compares the ResultMatch by MatchType first, then Field in a predefined order.\r\n        struct ResultMatchComparator\r\n        {\r\n            template <typename U, typename V>\r\n            bool operator() (\r\n                const U& match1,\r\n                const V& match2)\r\n            {\r\n                if (match1.MatchCriteria.Type != match2.MatchCriteria.Type)\r\n                {\r\n                    return match1.MatchCriteria.Type < match2.MatchCriteria.Type;\r\n                }\r\n\r\n                if (match1.MatchCriteria.Field != match2.MatchCriteria.Field)\r\n                {\r\n                    return match1.MatchCriteria.Field < match2.MatchCriteria.Field;\r\n                }\r\n\r\n                return false;\r\n            }\r\n        };\r\n\r\n        template <typename T>\r\n        void SortResultMatches(std::vector<T>& matches)\r\n        {\r\n            std::stable_sort(matches.begin(), matches.end(), ResultMatchComparator());\r\n        }\r\n\r\n        // A copy of the standard match that holds a CompositePackage instead.\r\n        struct CompositeResultMatch\r\n        {\r\n            std::shared_ptr<CompositePackage> Package;\r\n            PackageMatchFilter MatchCriteria;\r\n\r\n            CompositeResultMatch(std::shared_ptr<CompositePackage> p, PackageMatchFilter f) : Package(std::move(p)), MatchCriteria(std::move(f)) {}\r\n        };\r\n\r\n        // Stores data to enable correlation between installed and available packages.\r\n        struct CompositeResult\r\n        {\r\n            // A system reference string.\r\n            struct SystemReferenceString\r\n            {\r\n                SystemReferenceString(PackageMatchField field, Utility::LocIndString string) :\r\n                    Field(field), String1(Utility::FoldCase(string)) {}\r\n\r\n                SystemReferenceString(PackageMatchField field, Utility::LocIndString string1, Utility::LocIndString string2) :\r\n                    Field(field), String1(Utility::FoldCase(string1)), String2(Utility::FoldCase(string2)) {}\r\n\r\n                bool operator<(const SystemReferenceString& other) const\r\n                {\r\n                    if (Field != other.Field)\r\n                    {\r\n                        return Field < other.Field;\r\n                    }\r\n\r\n                    if (String1 != other.String1)\r\n                    {\r\n                        return String1 < other.String1;\r\n                    }\r\n\r\n                    return String2 < other.String2;\r\n                }\r\n\r\n                bool operator==(const SystemReferenceString& other) const\r\n                {\r\n                    return Field == other.Field && String1 == other.String1 && String2 == other.String2;\r\n                }\r\n\r\n                void AddToFilters(\r\n                    std::vector<PackageMatchFilter>& filters) const\r\n                {\r\n                    switch (Field)\r\n                    {\r\n                    case PackageMatchField::NormalizedNameAndPublisher:\r\n                        filters.emplace_back(PackageMatchFilter(Field, MatchType::Exact, String1.get(), String2.get()));\r\n                        break;\r\n\r\n                    default:\r\n                        filters.emplace_back(PackageMatchFilter(Field, MatchType::Exact, String1.get()));\r\n                    }\r\n                }\r\n\r\n            private:\r\n                PackageMatchField Field;\r\n                Utility::LocIndString String1;\r\n                Utility::LocIndString String2;\r\n            };\r\n\r\n            // Data relevant to correlation for a package.\r\n            struct PackageData\r\n            {\r\n                std::set<SystemReferenceString> SystemReferenceStrings;\r\n\r\n                void AddIfNotPresent(SystemReferenceString&& srs)\r\n                {\r\n                    if (SystemReferenceStrings.find(srs) == SystemReferenceStrings.end())\r\n                    {\r\n                        SystemReferenceStrings.emplace(std::move(srs));\r\n                    }\r\n                }\r\n\r\n                SearchRequest CreateInclusionsSearchRequest(SearchPurpose searchPurpose) const\r\n                {\r\n                    SearchRequest result;\r\n                    for (const auto& srs : SystemReferenceStrings)\r\n                    {\r\n                        srs.AddToFilters(result.Inclusions);\r\n                    }\r\n                    result.Purpose = searchPurpose;\r\n                    return result;\r\n                }\r\n\r\n                std::shared_ptr<IPackage> AddSystemReferenceStringsFromTrackingPackage(const PackageTrackingCatalog& trackingCatalog, const Utility::LocIndString& identifier, std::string_view sourceIdentifier)\r\n                {\r\n                    SearchRequest trackingRequest;\r\n                    trackingRequest.Filters.emplace_back(PackageMatchField::Id, MatchType::CaseInsensitive, identifier.get());\r\n\r\n                    SearchResult trackingResult = trackingCatalog.Search(trackingRequest);\r\n                    std::shared_ptr<IPackage> result;\r\n\r\n                    if (trackingResult.Matches.size() == 1)\r\n                    {\r\n                        result = OnlyAvailable(trackingResult.Matches[0].Package);\r\n                        AddSystemReferenceStrings(result.get());\r\n                    }\r\n                    else if (trackingResult.Matches.size() > 1)\r\n                    {\r\n                        AICLI_LOG(Repo, Warning, << \"Found \" << trackingResult.Matches.size() << \" results for Id [\" << identifier << \"] in tracking catalog for: \" << sourceIdentifier);\r\n                    }\r\n\r\n                    return result;\r\n                }\r\n\r\n                void AddSystemReferenceStrings(IPackage* package)\r\n                {\r\n                    GetSystemReferenceStrings(\r\n                        package,\r\n                        PackageMultiProperty::PackageFamilyName,\r\n                        PackageMatchField::PackageFamilyName);\r\n\r\n                    GetSystemReferenceStrings(\r\n                        package,\r\n                        PackageMultiProperty::ProductCode,\r\n                        PackageMatchField::ProductCode);\r\n\r\n                    GetSystemReferenceStrings(\r\n                        package,\r\n                        PackageMultiProperty::UpgradeCode,\r\n                        PackageMatchField::UpgradeCode);\r\n\r\n                    GetNameAndPublisher(\r\n                        package);\r\n                }\r\n\r\n                void AddSystemReferenceStringsFromManifest(const Manifest::Manifest& manifest)\r\n                {\r\n                    for (const auto& pfn : manifest.GetPackageFamilyNames())\r\n                    {\r\n                        AddIfNotPresent(SystemReferenceString{ PackageMatchField::PackageFamilyName, Utility::LocIndString{ pfn } });\r\n                    }\r\n                    for (const auto& productCode : manifest.GetProductCodes())\r\n                    {\r\n                        AddIfNotPresent(SystemReferenceString{ PackageMatchField::ProductCode, Utility::LocIndString{ productCode } });\r\n                    }\r\n                    for (const auto& upgradeCode : manifest.GetUpgradeCodes())\r\n                    {\r\n                        AddIfNotPresent(SystemReferenceString{ PackageMatchField::UpgradeCode, Utility::LocIndString{ upgradeCode } });\r\n                    }\r\n                    for (const auto& name : manifest.GetPackageNames())\r\n                    {\r\n                        for (const auto& publisher : manifest.GetPublishers())\r\n                        {\r\n                            AddIfNotPresent(SystemReferenceString{\r\n                                PackageMatchField::NormalizedNameAndPublisher,\r\n                                Utility::LocIndString{ name },\r\n                                Utility::LocIndString{ publisher } });\r\n                        }\r\n                    }\r\n                }\r\n\r\n            private:\r\n                void GetSystemReferenceStrings(\r\n                    IPackage* package,\r\n                    PackageMultiProperty prop,\r\n                    PackageMatchField field)\r\n                {\r\n                    for (auto&& string : package->GetMultiProperty(prop))\r\n                    {\r\n                        AddIfNotPresent(SystemReferenceString{ field, std::move(string) });\r\n                    }\r\n                }\r\n\r\n                void GetNameAndPublisher(\r\n                    IPackage* package)\r\n                {\r\n                    // Unfortunately the names and publishers are unique and not tied to each other strictly, so we need\r\n                    // to go broad on the matches. Future work can hopefully make name and publisher operate more as a unit,\r\n                    // but for now we have to search for the cartesian of these...\r\n                    auto names = package->GetMultiProperty(PackageMultiProperty::NormalizedName);\r\n                    auto publishers = package->GetMultiProperty(PackageMultiProperty::NormalizedPublisher);\r\n\r\n                    for (const auto& name : names)\r\n                    {\r\n                        for (const auto& publisher : publishers)\r\n                        {\r\n                            AddIfNotPresent(SystemReferenceString{\r\n                                PackageMatchField::NormalizedNameAndPublisher,\r\n                                name,\r\n                                publisher });\r\n                        }\r\n                    }\r\n                }\r\n            };\r\n\r\n            // For a given package, prepares the results for it.\r\n            PackageData GetSystemReferenceStrings(IPackage* package)\r\n            {\r\n                PackageData result;\r\n                result.AddSystemReferenceStrings(package);\r\n                return result;\r\n            }\r\n\r\n            // Check for a package already in the result that should have been correlated already.\r\n            // If we find one, see if we should upgrade it's match criteria.\r\n            // If we don't, return package data for further use.\r\n            //     downloadManifests: when creating system reference strings, also download manifests to get more data.\r\n            std::optional<PackageData> CheckForExistingResultFromAvailablePackageMatch(const ResultMatch& availableMatch, bool downloadManifests)\r\n            {\r\n                std::shared_ptr<IPackage> availablePackage = OnlyAvailable(availableMatch.Package);\r\n\r\n                for (auto& match : Matches)\r\n                {\r\n                    if (match.Package->IsSameAsAnyAvailable(availablePackage.get()))\r\n                    {\r\n                        if (ResultMatchComparator{}(availableMatch, match))\r\n                        {\r\n                            match.MatchCriteria = availableMatch.MatchCriteria;\r\n                        }\r\n\r\n                        return {};\r\n                    }\r\n                }\r\n\r\n                PackageData result;\r\n                result.AddSystemReferenceStrings(availablePackage.get());\r\n\r\n                if (downloadManifests)\r\n                {\r\n                    constexpr int c_downloadManifestsLimit = 3;\r\n                    int manifestsDownloaded = 0;\r\n                    for (auto const& versionKey : availablePackage->GetVersionKeys())\r\n                    {\r\n                        auto packageVersion = availablePackage->GetVersion(versionKey);\r\n\r\n                        auto manifest = packageVersion->GetManifest();\r\n                        result.AddSystemReferenceStringsFromManifest(manifest);\r\n                        manifestsDownloaded++;\r\n\r\n                        if (manifestsDownloaded >= c_downloadManifestsLimit)\r\n                        {\r\n                            break;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                return result;\r\n            }\r\n\r\n            // Determines if the results contain the given installed package.\r\n            bool ContainsInstalledPackage(const IPackage* installedPackage) const \r\n            {\r\n                for (auto& match : Matches)\r\n                {\r\n                    if (match.Package->ContainsInstalledPackage(installedPackage))\r\n                    {\r\n                        return true;\r\n                    }\r\n                }\r\n\r\n                return false;\r\n            }\r\n\r\n            // Determines if the results contain the given installed package.\r\n            std::shared_ptr<CompositePackage> FindInstalledPackage(const IPackage* installedPackage) const\r\n            {\r\n                for (auto& match : Matches)\r\n                {\r\n                    if (match.Package->ContainsInstalledPackage(installedPackage))\r\n                    {\r\n                        return match.Package;\r\n                    }\r\n                }\r\n\r\n                return {};\r\n            }\r\n\r\n            // *Destructively* converts the result to the standard variant.\r\n            SearchResult ConvertToSearchResult()\r\n            {\r\n                FoldResults();\r\n\r\n                SearchResult result;\r\n\r\n                result.Matches.reserve(Matches.size());\r\n                for (auto& match : Matches)\r\n                {\r\n                    result.Matches.emplace_back(std::move(match.Package), std::move(match.MatchCriteria));\r\n                }\r\n\r\n                result.Truncated = Truncated;\r\n\r\n                result.Failures = std::move(Failures);\r\n\r\n                return result;\r\n            }\r\n\r\n            bool AddFailureIfSourceNotPresent(SearchResult::Failure&& failure)\r\n            {\r\n                auto itr = std::find_if(Failures.begin(), Failures.end(),\r\n                    [&failure](const SearchResult::Failure& present) {\r\n                        return present.SourceName == failure.SourceName;\r\n                    });\r\n\r\n                if (itr == Failures.end())\r\n                {\r\n                    Failures.emplace_back(std::move(failure));\r\n                    return true;\r\n                }\r\n\r\n                return false;\r\n            }\r\n\r\n            SearchResult SearchAndHandleFailures(const Source& source, const SearchRequest& request)\r\n            {\r\n                SearchResult result;\r\n\r\n                try\r\n                {\r\n                    result = source.Search(request);\r\n                }\r\n                catch (...)\r\n                {\r\n                    if (AddFailureIfSourceNotPresent({ source.GetDetails().Name, std::current_exception() }))\r\n                    {\r\n                        LOG_CAUGHT_EXCEPTION();\r\n                        AICLI_LOG(Repo, Warning, << \"Failed to search source for correlation: \" << source.GetDetails().Name);\r\n                    }\r\n                }\r\n\r\n                // Move failures into the result\r\n                for (SearchResult::Failure& failure : result.Failures)\r\n                {\r\n                    AddFailureIfSourceNotPresent(std::move(failure));\r\n                }\r\n\r\n                return result;\r\n            }\r\n\r\n            // Group results in an attempt to have a single result that covers all installed versions.\r\n            // This is expected to be called immediately after the installed search portion,\r\n            // when each result will contain a single installed version and some number of available packages.\r\n            // \r\n            // The folds that happen are:\r\n            //  1. When results have the same primary available package (the primary available package is set due to tracking data)\r\n            //  2. When a result has no primary available package, but another result does have a primary that matches one of the available\r\n            //      a. Choose the latest primary if there are multiple\r\n            //  3. When multiple results have no primary available package and share the same available package set\r\n            //      a. There are many potential additional rules that could be made here, but we will start with the simplest version.\r\n            //\r\n            // Potential improvements:\r\n            //  1. Attempting correlation of non-primary available packages to allow folding in more complex cases\r\n            //      a. For example, if installed A has {source1:package1, source2:package2} and installed B has {source1:package1}, can we\r\n            //          make sure that source1:package1 and source2:package2 are in fact \"the same\" to confidently say that installed A and B\r\n            //          are side by side versions.\r\n            //  2. Attempt correlation by installed data only\r\n            //      a. We can potentially detect multiple instances of the same installed item with the same correlation logic turned back on\r\n            //          the installed source.  This would allow for folding even when the package is not in any available source.\r\n            void FoldResults()\r\n            {\r\n                // The key to uniquely identify the package in the map\r\n                struct InstalledResultFoldKey\r\n                {\r\n                    InstalledResultFoldKey() = default;\r\n\r\n                    InstalledResultFoldKey(const std::shared_ptr<IPackage>& package)\r\n                    {\r\n                        std::shared_ptr<IPackageVersion> latestAvailable = package->GetLatestVersion();\r\n                        if (latestAvailable)\r\n                        {\r\n                            SourceIdentifier = latestAvailable->GetSource().GetIdentifier();\r\n                            PackageIdentifier = latestAvailable->GetProperty(PackageVersionProperty::Id);\r\n                        }\r\n                    }\r\n\r\n                    // Hash operation\r\n                    size_t operator()(const InstalledResultFoldKey& value) const noexcept\r\n                    {\r\n                        std::hash<std::string> hashString;\r\n                        return hashString(value.SourceIdentifier) ^ (hashString(value.PackageIdentifier) << 1);\r\n                    }\r\n\r\n                    bool operator==(const InstalledResultFoldKey& other) const noexcept\r\n                    {\r\n                        // Treat both empty as invalid and never equal\r\n                        if (SourceIdentifier.empty() && PackageIdentifier.empty())\r\n                        {\r\n                            return false;\r\n                        }\r\n\r\n                        return SourceIdentifier == other.SourceIdentifier && PackageIdentifier == other.PackageIdentifier;\r\n                    }\r\n\r\n                    std::string SourceIdentifier;\r\n                    std::string PackageIdentifier;\r\n                };\r\n\r\n                // The data for a package in the map\r\n                struct InstalledResultFoldData\r\n                {\r\n                    InstalledResultFoldData() = default;\r\n                    explicit InstalledResultFoldData(size_t primaryPackageIndex) : PrimaryPackageIndex(primaryPackageIndex) {}\r\n\r\n                    std::optional<size_t> PrimaryPackageIndex;\r\n                    std::vector<size_t> NonPrimaryPackageIndices;\r\n                };\r\n\r\n                std::unordered_map<InstalledResultFoldKey, InstalledResultFoldData, InstalledResultFoldKey> foldData;\r\n\r\n                // Attempt to fold all primary package matches first.\r\n                // Packages without primaries will still be indexed into the hash table.\r\n                for (size_t i = 0; i < Matches.size(); ++i)\r\n                {\r\n                    CompositeResultMatch& currentMatch = Matches[i];\r\n\r\n                    // Check current match for fold target\r\n                    if (currentMatch.Package->GetPrimaryAvailablePackage())\r\n                    {\r\n                        InstalledResultFoldKey key{ currentMatch.Package->GetPrimaryAvailablePackage() };\r\n\r\n                        auto itr = foldData.find(key);\r\n                        if (itr != foldData.end())\r\n                        {\r\n                            if (itr->second.PrimaryPackageIndex)\r\n                            {\r\n                                Matches[itr->second.PrimaryPackageIndex.value()].Package->FoldInstalledIn(currentMatch.Package);\r\n                                currentMatch.Package.reset();\r\n                            }\r\n                            else\r\n                            {\r\n                                itr->second.PrimaryPackageIndex = i;\r\n                            }\r\n                        }\r\n                        else\r\n                        {\r\n                            foldData[key] = InstalledResultFoldData{ i };\r\n                        }\r\n                    }\r\n                    else\r\n                    {\r\n                        for (const auto& availablePackage : currentMatch.Package->GetAvailablePackages())\r\n                        {\r\n                            InstalledResultFoldKey key{ availablePackage };\r\n\r\n                            auto itr = foldData.find(key);\r\n                            if (itr == foldData.end())\r\n                            {\r\n                                itr = foldData.insert({ key, {} }).first;\r\n                            }\r\n\r\n                            itr->second.NonPrimaryPackageIndices.emplace_back(i);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                // After primary matches are folded, attempt to fold results without primary matches.\r\n                // The latest primary match will be preferred.\r\n                for (size_t i = 0; i < Matches.size(); ++i)\r\n                {\r\n                    CompositeResultMatch& currentMatch = Matches[i];\r\n\r\n                    // Skip any matches that we have already folded\r\n                    if (!currentMatch.Package)\r\n                    {\r\n                        continue;\r\n                    }\r\n\r\n                    if (!currentMatch.Package->GetPrimaryAvailablePackage())\r\n                    {\r\n                        InstalledResultFoldData* latestPrimaryAvailable = nullptr;\r\n                        std::vector<InstalledResultFoldData*> availableFoldData;\r\n\r\n                        for (const auto& availablePackage : currentMatch.Package->GetAvailablePackages())\r\n                        {\r\n                            auto& packageFoldData = foldData.at(availablePackage);\r\n\r\n                            if (packageFoldData.PrimaryPackageIndex)\r\n                            {\r\n                                if (!latestPrimaryAvailable ||\r\n                                    Matches[latestPrimaryAvailable->PrimaryPackageIndex.value()].Package->GetTrackingPackageWriteTime() < Matches[packageFoldData.PrimaryPackageIndex.value()].Package->GetTrackingPackageWriteTime())\r\n                                {\r\n                                    latestPrimaryAvailable = &packageFoldData;\r\n                                }\r\n                            }\r\n                            else\r\n                            {\r\n                                availableFoldData.emplace_back(&packageFoldData);\r\n                            }\r\n                        }\r\n\r\n                        if (latestPrimaryAvailable)\r\n                        {\r\n                            Matches[latestPrimaryAvailable->PrimaryPackageIndex.value()].Package->FoldInstalledIn(currentMatch.Package);\r\n                            currentMatch.Package.reset();\r\n\r\n                            // If the result with the primary is later, move it forward\r\n                            if (latestPrimaryAvailable->PrimaryPackageIndex.value() > i)\r\n                            {\r\n                                currentMatch.Package = std::move(Matches[latestPrimaryAvailable->PrimaryPackageIndex.value()].Package);\r\n                                Matches[latestPrimaryAvailable->PrimaryPackageIndex.value()].Package.reset();\r\n                                latestPrimaryAvailable->PrimaryPackageIndex = i;\r\n                            }\r\n                            continue;\r\n                        }\r\n\r\n                        // First, find the intersection of all results that contain all of the packages from this result.\r\n                        std::vector<size_t> candidateMatches;\r\n                        for (size_t j = 0; j < availableFoldData.size(); ++j)\r\n                        {\r\n                            InstalledResultFoldData* packageFoldData = availableFoldData[j];\r\n\r\n                            if (j == 0)\r\n                            {\r\n                                candidateMatches = packageFoldData->NonPrimaryPackageIndices;\r\n                            }\r\n                            else\r\n                            {\r\n                                std::vector<size_t> temp;\r\n                                std::set_intersection(\r\n                                    candidateMatches.begin(), candidateMatches.end(),\r\n                                    packageFoldData->NonPrimaryPackageIndices.begin(), packageFoldData->NonPrimaryPackageIndices.end(),\r\n                                    std::back_inserter(temp));\r\n                                candidateMatches = std::move(temp);\r\n                            }\r\n                        }\r\n\r\n                        // Now exclude both our own result and any that have a different (larger) number of available packages\r\n                        candidateMatches.erase(std::remove_if(candidateMatches.begin(), candidateMatches.end(),\r\n                            [&](size_t index) { return index == i || Matches[index].Package->GetAvailablePackages().size() != currentMatch.Package->GetAvailablePackages().size(); }),\r\n                            candidateMatches.end());\r\n\r\n                        // All of these remaining values should be folded in to our result\r\n                        for (size_t foldTarget : candidateMatches)\r\n                        {\r\n                            currentMatch.Package->FoldInstalledIn(Matches[foldTarget].Package);\r\n                            Matches[foldTarget].Package.reset();\r\n                        }\r\n                    }\r\n                }\r\n\r\n                // Get rid of the folded results; we reset the Package to indicate that it is no longer valid\r\n                Matches.erase(std::remove_if(Matches.begin(), Matches.end(), [&](const CompositeResultMatch& match) { return !match.Package; }), Matches.end());\r\n            }\r\n\r\n            std::vector<CompositeResultMatch> Matches;\r\n            bool Truncated = false;\r\n            std::vector<SearchResult::Failure> Failures;\r\n        };\r\n\r\n        std::shared_ptr<ICompositePackage> GetTrackedPackageFromAvailableSource(CompositeResult& result, const Source& source, const Utility::LocIndString& identifier)\r\n        {\r\n            SearchRequest directRequest;\r\n            directRequest.Filters.emplace_back(PackageMatchField::Id, MatchType::CaseInsensitive, identifier.get());\r\n\r\n            SearchResult directResult = result.SearchAndHandleFailures(source, directRequest);\r\n\r\n            if (directResult.Matches.empty())\r\n            {\r\n                AICLI_LOG(Repo, Warning, << \"Did not find Id [\" << identifier << \"] in tracked source: \" << source.GetDetails().Name);\r\n            }\r\n            else if (directResult.Matches.size() == 1)\r\n            {\r\n                return directResult.Matches[0].Package;\r\n            }\r\n            else\r\n            {\r\n                AICLI_LOG(Repo, Warning, << \"Found multiple results for Id [\" << identifier << \"] in tracked source: \" << source.GetDetails().Name);\r\n            }\r\n\r\n            return {};\r\n        }\r\n    }\r\n\r\n    using namespace anon;\r\n\r\n    CompositeSource::CompositeSource(std::string identifier)\r\n    {\r\n        m_details.Identifier = std::move(identifier);\r\n    }\r\n\r\n    const SourceDetails& CompositeSource::GetDetails() const\r\n    {\r\n        return m_details;\r\n    }\r\n\r\n    const std::string& CompositeSource::GetIdentifier() const\r\n    {\r\n        return m_details.Identifier;\r\n    }\r\n\r\n    // The composite search needs to take several steps to get results, and due to the\r\n    // potential for different information spread across multiple sources, base searches\r\n    // need to be performed in both installed and available.\r\n    //\r\n    // If an installed source is present, then the searches should only return packages\r\n    // that are installed. This means that the base searches against available sources\r\n    // will only return results where a match is found in the installed source.\r\n    SearchResult CompositeSource::Search(const SearchRequest& request) const\r\n    {\r\n        if (m_installedSource)\r\n        {\r\n            return SearchInstalled(request);\r\n        }\r\n        else\r\n        {\r\n            return SearchAvailable(request);\r\n        }\r\n    }\r\n\r\n    void* CompositeSource::CastTo(ISourceType type)\r\n    {\r\n        if (type == SourceType)\r\n        {\r\n            return this;\r\n        }\r\n\r\n        return nullptr;\r\n    }\r\n\r\n    void CompositeSource::AddAvailableSource(const Source& source)\r\n    {\r\n        m_availableSources.emplace_back(source);\r\n    }\r\n\r\n    void CompositeSource::SetInstalledSource(Source source, CompositeSearchBehavior searchBehavior)\r\n    {\r\n        m_installedSource = std::move(source);\r\n        m_searchBehavior = searchBehavior;\r\n    }\r\n\r\n    // An installed search first finds all installed packages that match the request, then correlates with available sources.\r\n    // Next the search is performed against the available sources and correlated with the installed source. A result will only\r\n    // be added if there exists an installed package that was not found by the initial search.\r\n    // This allows for search terms to find installed packages by their available metadata, as well as the local values.\r\n    //\r\n    // Search flow:\r\n    //  Installed :: Search incoming request\r\n    //  For each result\r\n    //      For each available source\r\n    //          Tracking :: Search system references\r\n    //      If tracking found\r\n    //          Available :: Search tracking ID\r\n    //      If no available, for each available source\r\n    //          Available :: Search system references\r\n    // \r\n    //  For each available source\r\n    //      Tracking :: Search incoming request\r\n    //      For each result\r\n    //          Installed :: Search system references\r\n    //          If found\r\n    //              Available :: Search tracking ID\r\n    //      Available :: Search incoming request\r\n    //      For each result\r\n    //          Installed :: Search system references\r\n    SearchResult CompositeSource::SearchInstalled(const SearchRequest& request) const\r\n    {\r\n        CompositeResult result;\r\n\r\n        // If the search behavior is for AllPackages or Installed then the result can contain packages that are\r\n        // only in the Installed source, but do not have an AvailableVersion.\r\n        if (m_searchBehavior == CompositeSearchBehavior::AllPackages || m_searchBehavior == CompositeSearchBehavior::Installed)\r\n        {\r\n            // Search installed source (allow exceptions out as we own the installed source)\r\n            SearchResult installedResult = m_installedSource.Search(request);\r\n            result.Truncated = installedResult.Truncated;\r\n\r\n            for (auto&& match : installedResult.Matches)\r\n            {\r\n                if (!match.Package)\r\n                {\r\n                    // Ensure that the crash from installedVersion below is not from the actual package being null.\r\n                    AICLI_LOG(Repo, Warning, << \"CompositeSource: The match of the package (matched on \" <<\r\n                        ToString(match.MatchCriteria.Field) << \" => '\" << match.MatchCriteria.Value <<\r\n                        \"') was null and is being dropped from the results.\");\r\n                    continue;\r\n                }\r\n\r\n                std::shared_ptr<CompositePackage> compositePackage = std::make_shared<CompositePackage>(match.Package);\r\n                auto installedPackage = compositePackage->GetInstalled();\r\n\r\n                if (!installedPackage)\r\n                {\r\n                    // One would think that the installed package coming directly from our own installed source\r\n                    // would never be null, but it is sometimes. Rather than making users suffer through crashes\r\n                    // that break their entire experience, lets log a few things and then ignore this match.\r\n                    AICLI_LOG(Repo, Warning, << \"CompositeSource: The installed version of the package '\" <<\r\n                        match.Package->GetProperty(PackageProperty::Id) << \"' was null and is being dropped from the results.\");\r\n                    continue;\r\n                }\r\n\r\n                auto installedPackageData = result.GetSystemReferenceStrings(installedPackage.get());\r\n\r\n                // Create a search request to run against all available sources\r\n                if (!installedPackageData.SystemReferenceStrings.empty())\r\n                {\r\n                    SearchRequest systemReferenceSearch = installedPackageData.CreateInclusionsSearchRequest(SearchPurpose::CorrelationToAvailable);\r\n                    AICLI_LOG(Repo, Verbose, << \"Finding available package from installed package using system reference search: \" << systemReferenceSearch.ToString());\r\n\r\n                    // Search sources and add to result\r\n                    for (const auto& source : m_availableSources)\r\n                    {\r\n                        AICLI_LOG(Repo, Verbose, << \" ... searching source: \" << source.GetDetails().Name << \" [\" << source.GetIdentifier() << ']');\r\n\r\n                        // Find the tracking result with the latest timestamp.\r\n                        auto trackingCatalog = source.GetTrackingCatalog();\r\n                        SearchResult trackingResult = trackingCatalog.Search(systemReferenceSearch);\r\n\r\n                        std::shared_ptr<IPackage> trackingPackage;\r\n                        std::chrono::system_clock::time_point trackingPackageTime;\r\n                        bool trackingSet = false;\r\n\r\n                        for (const auto& trackingMatch : trackingResult.Matches)\r\n                        {\r\n                            auto candidateTime = GetLatestTrackingWriteTime(OnlyAvailable(trackingMatch.Package));\r\n\r\n                            if (!trackingPackage || candidateTime > trackingPackageTime)\r\n                            {\r\n                                trackingPackage = OnlyAvailable(trackingMatch.Package);\r\n                                trackingPackageTime = candidateTime;\r\n                            }\r\n                        }\r\n\r\n                        if (trackingPackage && trackingPackageTime > compositePackage->GetTrackingPackageWriteTime())\r\n                        {\r\n                            AICLI_LOG(Repo, Verbose, << \" ... setting latest tracking package to: \" << trackingPackage->GetProperty(PackageProperty::Id));\r\n                            compositePackage->SetTracking(source, trackingPackage, trackingPackageTime);\r\n                            trackingSet = true;\r\n                        }\r\n\r\n                        // Attempt to correlate local packages against this source if supported.\r\n                        SearchResult availableResult;\r\n                        if (source.GetDetails().SupportInstalledSearchCorrelation)\r\n                        {\r\n                            availableResult = result.SearchAndHandleFailures(source, systemReferenceSearch);\r\n                        }\r\n\r\n                        auto availablePackage = GetMatchingPackage(availableResult.Matches,\r\n                            [&]() {\r\n                                AICLI_LOG(Repo, Info,\r\n                                << \"Found multiple matches for installed package [\" << installedPackage->GetProperty(PackageProperty::Id) <<\r\n                                \"] in source [\" << source.GetIdentifier() << \"] when searching for [\" << systemReferenceSearch.ToString() << \"]\");\r\n                            }, [&] {\r\n                                AICLI_LOG(Repo, Warning, << \"  Appropriate available package could not be determined\");\r\n                            });\r\n\r\n                        if (trackingPackage)\r\n                        {\r\n                            auto trackingIdentifier = trackingPackage->GetProperty(PackageProperty::Id);\r\n\r\n                            // We always want to take the available search result if it exists as the package may have been updated.\r\n                            if (availablePackage)\r\n                            {\r\n                                auto availableIdentifier = availablePackage->GetProperty(PackageProperty::Id);\r\n                                if (!Utility::ICUCaseInsensitiveEquals(availableIdentifier, trackingIdentifier))\r\n                                {\r\n                                    AICLI_LOG(Repo, Verbose, << \" ... overriding tracking package (\" << trackingIdentifier << \") with available package (\" << availableIdentifier << \")\");\r\n                                }\r\n                            }\r\n                            else\r\n                            {\r\n                                AICLI_LOG(Repo, Verbose, << \" ... using tracking package: \" << trackingIdentifier);\r\n                                availablePackage = GetTrackedPackageFromAvailableSource(result, source, trackingIdentifier);\r\n                            }\r\n                        }\r\n\r\n                        if (availablePackage)\r\n                        {\r\n                            AICLI_LOG(Repo, Verbose, << \" ... adding available package: \" << availablePackage->GetProperty(PackageProperty::Id));\r\n                            compositePackage->AddAvailablePackage(availablePackage, trackingSet);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                // Move the installed result into the composite result\r\n                result.Matches.emplace_back(std::move(compositePackage), std::move(match.MatchCriteria));\r\n            }\r\n\r\n            // Optimization for the \"everything installed\" case, no need to allow for reverse correlations\r\n            if (request.IsForEverything() && m_searchBehavior == CompositeSearchBehavior::Installed)\r\n            {\r\n                return result.ConvertToSearchResult();\r\n            }\r\n        }\r\n\r\n        // Search available sources\r\n        for (const auto& source : m_availableSources)\r\n        {\r\n            auto trackingCatalog = source.GetTrackingCatalog();\r\n\r\n            SearchResult availableResult = result.SearchAndHandleFailures(source, request);\r\n            bool downloadManifests = source.QueryFeatureFlag(SourceFeatureFlag::ManifestMayContainAdditionalSystemReferenceStrings);\r\n\r\n            for (auto&& match : availableResult.Matches)\r\n            {\r\n                // Check for the package already in the result.\r\n                // In cases that PackageData will be created, also download manifests for system reference strings\r\n                // when search result is small (currently limiting to 1).\r\n                auto packageData = result.CheckForExistingResultFromAvailablePackageMatch(match, downloadManifests && availableResult.Matches.size() == 1);\r\n\r\n                // If found existing package in the result, continue\r\n                if (!packageData)\r\n                {\r\n                    continue;\r\n                }\r\n\r\n                // Use data from the tracking catalog as it can potentially get better correlations\r\n                auto trackingPackage = packageData->AddSystemReferenceStringsFromTrackingPackage(trackingCatalog, match.Package->GetProperty(PackageProperty::Id), source.GetDetails().Name);\r\n\r\n                // If no package was found that was already in the results, do a correlation lookup with the installed\r\n                // source to create a new composite package entry if we find any packages there.\r\n                bool foundInstalledMatch = false;\r\n                if (!packageData->SystemReferenceStrings.empty())\r\n                {\r\n                    // Create a search request to run against the installed source\r\n                    SearchRequest systemReferenceSearch = packageData->CreateInclusionsSearchRequest(SearchPurpose::CorrelationToInstalled);\r\n\r\n                    AICLI_LOG(Repo, Verbose, << \"Finding installed package from available package using system reference search: \" << systemReferenceSearch.ToString());\r\n                    // Correlate against installed (allow exceptions out as we own the installed source)\r\n                    SearchResult installedCrossRef = m_installedSource.Search(systemReferenceSearch);\r\n\r\n                    for (const auto& installedMatch : installedCrossRef.Matches)\r\n                    {\r\n                        if (!IsStrongMatchField(installedMatch.MatchCriteria.Field))\r\n                        {\r\n                            // For weak correlations, do an installed -> available check to ensure that there are no other strong correlations.\r\n                            SearchResult correlationConfirmation;\r\n                            if (source.GetDetails().SupportInstalledSearchCorrelation)\r\n                            {\r\n                                correlationConfirmation = result.SearchAndHandleFailures(source, result.GetSystemReferenceStrings(installedMatch.Package->GetInstalled().get()).CreateInclusionsSearchRequest(SearchPurpose::CorrelationToAvailable));\r\n                            }\r\n\r\n                            if (correlationConfirmation.Matches.empty())\r\n                            {\r\n                                // We probably made the correlation due to tracking data, keep it.\r\n                            }\r\n                            else if (correlationConfirmation.Matches.size() > 1)\r\n                            {\r\n                                // There is contention for the correlation.\r\n                                AICLI_LOG(Repo, Verbose, << \" ... installed package [\" << installedMatch.Package->GetProperty(PackageProperty::Id) <<\r\n                                    \"] had multiple correlations and is being ignored as a match for [\" << match.Package->GetProperty(PackageProperty::Id) << \"]\");\r\n                                continue;\r\n                            }\r\n                            else if (!OnlyAvailable(correlationConfirmation.Matches[0].Package)->IsSame(OnlyAvailable(match.Package).get()))\r\n                            {\r\n                                // The only correlation is not to the current package.\r\n                                AICLI_LOG(Repo, Verbose, << \" ... installed package [\" << installedMatch.Package->GetProperty(PackageProperty::Id) <<\r\n                                    \"] was found through available package [\" << match.Package->GetProperty(PackageProperty::Id) << \"], but only correlated to [\" <<\r\n                                    correlationConfirmation.Matches[0].Package->GetProperty(PackageProperty::Id) << \"] and is being ignored\");\r\n                                continue;\r\n                            }\r\n                        }\r\n\r\n                        // Now that we know we need to add this available package, determine how exactly\r\n                        std::shared_ptr<CompositePackage> resultPackage = result.FindInstalledPackage(installedMatch.Package->GetInstalled().get());\r\n\r\n                        if (resultPackage)\r\n                        {\r\n                            // Check for a package from the same source already present on the result package.\r\n                            bool foundSameSource = false;\r\n\r\n                            for (const auto& availablePackage : resultPackage->GetAvailablePackages())\r\n                            {\r\n                                if (availablePackage->GetSource() == source)\r\n                                {\r\n                                    // TODO: May need to add more data so that we can choose the proper correlation, but it may also be very difficult to get through\r\n                                    //       the gauntlet of other checks and arrive in this situation.\r\n                                    AICLI_LOG(Repo, Verbose, << \" ... found [\" << availablePackage->GetProperty(PackageProperty::Id) <<\r\n                                        \"] already correlated to [\" << installedMatch.Package->GetProperty(PackageProperty::Id) << \"] from the same source [\" <<\r\n                                        source.GetDetails().Name << \"] as [\" << match.Package->GetProperty(PackageProperty::Id) << \"]; ignoring the second correlation\");\r\n                                    foundSameSource = true;\r\n                                }\r\n                            }\r\n\r\n                            if (foundSameSource)\r\n                            {\r\n                                continue;\r\n                            }\r\n                        }\r\n                        else\r\n                        {\r\n                            result.Matches.emplace_back(std::make_shared<CompositePackage>(installedMatch.Package), match.MatchCriteria);\r\n                            resultPackage = result.Matches.back().Package;\r\n                        }\r\n\r\n                        bool setPrimary = false;\r\n                        if (trackingPackage)\r\n                        {\r\n                            auto trackingPackageTime = GetLatestTrackingWriteTime(trackingPackage);\r\n\r\n                            if (trackingPackageTime > resultPackage->GetTrackingPackageWriteTime())\r\n                            {\r\n                                resultPackage->SetTracking(source, std::move(trackingPackage), trackingPackageTime);\r\n                                setPrimary = true;\r\n                            }\r\n                        }\r\n\r\n                        resultPackage->AddAvailablePackage(std::move(match.Package), setPrimary);\r\n\r\n                        foundInstalledMatch = true;\r\n                    }\r\n                }\r\n\r\n                // If there was no correlation for this package, add it without one.\r\n                if ((m_searchBehavior == CompositeSearchBehavior::AllPackages || m_searchBehavior == CompositeSearchBehavior::AvailablePackages) && !foundInstalledMatch)\r\n                {\r\n                    result.Matches.emplace_back(std::make_shared<CompositePackage>(std::shared_ptr<ICompositePackage>{}, std::move(match.Package)), match.MatchCriteria);\r\n                }\r\n            }\r\n        }\r\n\r\n        SortResultMatches(result.Matches);\r\n\r\n        if (request.MaximumResults > 0 && result.Matches.size() > request.MaximumResults)\r\n        {\r\n            result.Truncated = true;\r\n            result.Matches.erase(result.Matches.begin() + request.MaximumResults, result.Matches.end());\r\n        }\r\n\r\n        return result.ConvertToSearchResult();\r\n    }\r\n\r\n    // An available search goes through each source, searching individually and then sorting the full result set.\r\n    SearchResult CompositeSource::SearchAvailable(const SearchRequest& request) const\r\n    {\r\n        SearchResult result;\r\n\r\n        // Search available sources\r\n        for (const auto& source : m_availableSources)\r\n        {\r\n            SearchResult oneSourceResult;\r\n\r\n            try\r\n            {\r\n                oneSourceResult = source.Search(request);\r\n            }\r\n            catch (...)\r\n            {\r\n                LOG_CAUGHT_EXCEPTION();\r\n                AICLI_LOG(Repo, Warning, << \"Failed to search source: \" << source.GetDetails().Name);\r\n                result.Failures.emplace_back(SearchResult::Failure{ source.GetDetails().Name, std::current_exception() });\r\n            }\r\n\r\n            // Move into the single result\r\n            std::move(oneSourceResult.Matches.begin(), oneSourceResult.Matches.end(), std::back_inserter(result.Matches));\r\n            std::move(oneSourceResult.Failures.begin(), oneSourceResult.Failures.end(), std::back_inserter(result.Failures));\r\n        }\r\n\r\n        SortResultMatches(result.Matches);\r\n\r\n        if (request.MaximumResults > 0 && result.Matches.size() > request.MaximumResults)\r\n        {\r\n            result.Truncated = true;\r\n            result.Matches.erase(result.Matches.begin() + request.MaximumResults, result.Matches.end());\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/CompositeSource.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ISource.h\"\r\n\r\nnamespace AppInstaller::Repository\r\n{\r\n    struct CompositeSource : public ISource\r\n    {\r\n        static constexpr ISourceType SourceType = ISourceType::CompositeSource;\r\n\r\n        explicit CompositeSource(std::string identifier);\r\n\r\n        CompositeSource(const CompositeSource&) = delete;\r\n        CompositeSource& operator=(const CompositeSource&) = delete;\r\n\r\n        CompositeSource(CompositeSource&&) = default;\r\n        CompositeSource& operator=(CompositeSource&&) = default;\r\n\r\n        ~CompositeSource() = default;\r\n\r\n        // ISource\r\n\r\n        // Get the source's details.\r\n        const SourceDetails& GetDetails() const override;\r\n\r\n        // Gets the source's identifier; a unique identifier independent of the name\r\n        // that will not change between a remove/add or between additional adds.\r\n        // Must be suitable for filesystem names.\r\n        const std::string& GetIdentifier() const override;\r\n\r\n        // Execute a search on the source.\r\n        SearchResult Search(const SearchRequest& request) const override;\r\n\r\n        // Casts to the requested type.\r\n        void* CastTo(ISourceType type) override;\r\n\r\n        // ~ISource\r\n\r\n        // Adds an available source to be aggregated.\r\n        void AddAvailableSource(const Source& source);\r\n\r\n        // Gets the available sources if the source is composite.\r\n        std::vector<Source> GetAvailableSources() const { return m_availableSources; }\r\n\r\n        // Checks if any available sources are present\r\n        bool HasAvailableSource() const { return !m_availableSources.empty(); }\r\n\r\n        // Sets the installed source to be composited.\r\n        void SetInstalledSource(Source source, CompositeSearchBehavior searchBehavior = CompositeSearchBehavior::Installed);\r\n\r\n    private:\r\n        // Performs a search when an installed source is present.\r\n        SearchResult SearchInstalled(const SearchRequest& request) const;\r\n\r\n        // Performs a search when no installed source is present.\r\n        SearchResult SearchAvailable(const SearchRequest& request) const;\r\n\r\n        Source m_installedSource;\r\n        std::vector<Source> m_availableSources;\r\n        SourceDetails m_details;\r\n        CompositeSearchBehavior m_searchBehavior = CompositeSearchBehavior::Installed;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/ISource.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Public/winget/RepositorySource.h\"\r\n#include <winget/SharedThreadGlobals.h>\r\n#include <memory>\r\n\r\nnamespace AppInstaller::Repository\r\n{\r\n    // To allow for runtime casting from ISource to the specific types, this enum contains all of the ISource implementations.\r\n    enum class ISourceType\r\n    {\r\n        TestSource,\r\n        ConfigurableTestSource,\r\n        RestSource,\r\n        SQLiteIndexSource,\r\n        CompositeSource,\r\n        IMutablePackageSource,\r\n        OpenExceptionProxy,\r\n    };\r\n\r\n    // Internal interface for interacting with a source from outside of the repository lib.\r\n    struct ISource\r\n    {\r\n        virtual ~ISource() = default;\r\n\r\n        // Gets the source's identifier; a unique identifier independent of the name\r\n        // that will not change between a remove/add or between additional adds.\r\n        // Must be suitable for filesystem names unless the source is internal to winget,\r\n        // in which case the identifier should begin with a '*' character.\r\n        virtual const std::string& GetIdentifier() const = 0;\r\n\r\n        // Get the source's configuration from settings. Source details can be used during opening the source.\r\n        virtual const SourceDetails& GetDetails() const = 0;\r\n\r\n        // Get the source's information after the source is opened.\r\n        virtual SourceInformation GetInformation() const { return {}; };\r\n\r\n        // Query the value of the given feature flag.\r\n        // The default state of any new flag is false.\r\n        virtual bool QueryFeatureFlag(SourceFeatureFlag) const { return false; }\r\n\r\n        // Execute a search on the source.\r\n        virtual SearchResult Search(const SearchRequest& request) const = 0;\r\n\r\n        // Gets this object as the requested type, or null if it is not the requested type.\r\n        virtual void* CastTo(ISourceType type) = 0;\r\n    };\r\n\r\n    // Does the equivalent of a dynamic_pointer_cast, but without it to allow RTTI to be disabled.\r\n    template <typename SourceType>\r\n    std::shared_ptr<SourceType> SourceCast(const std::shared_ptr<ISource>& source)\r\n    {\r\n        if (!source)\r\n        {\r\n            return {};\r\n        }\r\n\r\n        void* castResult = source->CastTo(SourceType::SourceType);\r\n\r\n        if (!castResult)\r\n        {\r\n            return {};\r\n        }\r\n\r\n        return std::shared_ptr<SourceType>(source, reinterpret_cast<SourceType*>(castResult));\r\n    }\r\n\r\n    // Internal interface to represent source information; basically SourceDetails but with methods to enable differential behaviors.\r\n    struct ISourceReference\r\n    {\r\n        virtual ~ISourceReference() = default;\r\n\r\n        // Gets the source's identifier; a unique identifier independent of the name\r\n        // that will not change between a remove/add or between additional adds.\r\n        // Must be suitable for filesystem names unless the source is internal to winget,\r\n        // in which case the identifier should begin with a '*' character.\r\n        virtual std::string GetIdentifier() = 0;\r\n\r\n        // Get the source's configuration details from settings.\r\n        virtual SourceDetails& GetDetails() = 0;\r\n\r\n        // Get the source's information.\r\n        virtual SourceInformation GetInformation() { return {}; }\r\n\r\n        // Set custom header. Returns false if custom header is not supported.\r\n        virtual bool SetCustomHeader(std::optional<std::string>) { return false; }\r\n\r\n        // Set caller.\r\n        virtual void SetCaller(std::string) {}\r\n\r\n        // Set authentication arguments.\r\n        virtual void SetAuthenticationArguments(Authentication::AuthenticationArguments) {}\r\n\r\n        // Determine if the source needs to be updated before being opened.\r\n        virtual bool ShouldUpdateBeforeOpen(const std::optional<TimeSpan>&) { return false; }\r\n\r\n        // Opens the source. This function should throw upon open failure rather than returning an empty pointer.\r\n        virtual std::shared_ptr<ISource> Open(IProgressCallback& progress) = 0;\r\n\r\n        // Sets thread globals for the source. This allows the option for sources that operate on other threads to log properly.\r\n        virtual void SetThreadGlobals(const std::shared_ptr<ThreadLocalStorage::ThreadGlobals>&) {}\r\n    };\r\n\r\n    // Internal interface extension to ISource for databases that can be updated after creation, like InstallingPackages\r\n    struct IMutablePackageSource\r\n    {\r\n        static constexpr AppInstaller::Repository::ISourceType SourceType = AppInstaller::Repository::ISourceType::IMutablePackageSource;\r\n\r\n        virtual ~IMutablePackageSource() = default;\r\n\r\n        // Adds a package version to the source.\r\n        virtual void AddPackageVersion(const Manifest::Manifest& manifest, const std::filesystem::path& relativePath) = 0;\r\n\r\n        // Removes a package version from the source.\r\n        virtual void RemovePackageVersion(const Manifest::Manifest& manifest, const std::filesystem::path& relativePath) = 0;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/IconDefs.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n\r\n#pragma once\r\n\r\n// Icon file structure and definitions:\r\n// https://msdn.microsoft.com/en-us/library/ms997538.aspx\r\n\r\n// .ico icon structures\r\n\r\n// Icon entry struct\r\ntypedef struct\r\n{\r\n    BYTE        bWidth;         // Width, in pixels, of the image\r\n    BYTE        bHeight;        // Height, in pixels, of the image\r\n    BYTE        bColorCount;    // Number of colors in image (0 if >=8bpp)\r\n    BYTE        bReserved;      // Reserved ( must be 0)\r\n    WORD        wPlanes;        // Color Planes\r\n    WORD        wBitCount;      // Bits per pixel\r\n    DWORD       dwBytesInRes;    // How many bytes in this resource?\r\n    DWORD       dwImageOffset;  // Where in the file is this image?\r\n} ICONDIRENTRY, *LPICONDIRENTRY;\r\n\r\n\r\n// Icon directory struct\r\ntypedef struct\r\n{\r\n    WORD            idReserved;   // Reserved (must be 0)\r\n    WORD            idType;       // Resource Type (1 for icons)\r\n    WORD            idCount;      // How many images?\r\n    ICONDIRENTRY    idEntries[1]; // An entry for each image (idCount of 'em)\r\n} ICONDIR, *LPICONDIR;\r\n\r\n\r\n// Image struct\r\ntypedef struct\r\n{\r\n    BITMAPINFOHEADER    icHeader;      // DIB header\r\n    RGBQUAD             icColors[1];   // Color table\r\n    BYTE                icXOR[1];      // DIB bits for XOR mask\r\n    BYTE                icAND[1];      // DIB bits for AND mask\r\n} ICONIMAGE, * LPICONIMAGE;\r\n\r\n\r\n// .exe and .dll icon structures\r\n\r\n// #pragmas are used here to insure that the structure's\r\n// packing in memory matches the packing of the EXE or DLL.\r\n#pragma pack( push )\r\n#pragma pack( 2 )\r\n\r\ntypedef struct\r\n{\r\n    BYTE   bWidth;               // Width, in pixels, of the image\r\n    BYTE   bHeight;              // Height, in pixels, of the image\r\n    BYTE   bColorCount;          // Number of colors in image (0 if >=8bpp)\r\n    BYTE   bReserved;            // Reserved\r\n    WORD   wPlanes;              // Color Planes\r\n    WORD   wBitCount;            // Bits per pixel\r\n    DWORD  dwBytesInRes;         // how many bytes in this resource?\r\n    WORD   nID;                  // the ID\r\n} GRPICONDIRENTRY, *LPGRPICONDIRENTRY;\r\n\r\n\r\ntypedef struct\r\n{\r\n    WORD            idReserved;   // Reserved (must be 0)\r\n    WORD            idType;       // Resource type (1 for icons)\r\n    WORD            idCount;      // How many images?\r\n    GRPICONDIRENTRY idEntries[1]; // The entries for each image\r\n} GRPICONDIR, *LPGRPICONDIR;\r\n\r\n#pragma pack( pop )\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/IconExtraction.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"IconDefs.h\"\n#include \"winget/IconExtraction.h\"\n#include \"Microsoft/ARPHelper.h\"\n#include <AppInstallerSHA256.h>\n#include <winget/Filesystem.h>\n\nnamespace AppInstaller::Repository\n{\n    using namespace AppInstaller::Repository::Microsoft;\n\n    namespace\n    {\n        // Struct used as data object passed to Enumerate callback function of EnumResourceNamesEx\n        struct EnumGroupIconProcParameter\n        {\n            // Input to specify icon index\n            int IconIndex = 0;\n            // The result Resource handle of the group icon\n            HRSRC ResourceHandle = nullptr;\n            // How many icons were already found\n            int IconsFound = 0;\n        };\n\n        BOOL CALLBACK EnumGroupIconProc(HMODULE hModule, LPCWSTR lpType, LPWSTR lpName, LONG_PTR lParam)\n        {\n            EnumGroupIconProcParameter* parameter = reinterpret_cast<EnumGroupIconProcParameter*>(lParam);\n            bool foundRequestedIcon = false;\n\n            // Find icon by resource name\n            if (parameter->IconIndex < 0)\n            {\n                if (IS_INTRESOURCE(lpName))\n                {\n                    if (-parameter->IconIndex == LOWORD(lpName))\n                    {\n                        // Found icon by MAKEINTRESOURCE name\n                        foundRequestedIcon = true;\n                    }\n                }\n                else if (lpName[0] == TEXT('#'))\n                {\n                    std::wstring resourceIdString = lpName + 1; // skip the #\n                    try\n                    {\n                        auto resourceId = std::stoi(resourceIdString.c_str(), nullptr, 0);\n                        if (-parameter->IconIndex == resourceId)\n                        {\n                            // Found icon by number as string #12\n                            foundRequestedIcon = true;\n                        }\n                    }\n                    catch (...)\n                    {\n                        // Error occurred, stop enumerating\n                        return FALSE;\n                    }\n                }\n            }\n            else if (parameter->IconIndex == parameter->IconsFound)\n            {\n                // Found icon by index\n                foundRequestedIcon = TRUE;\n            }\n\n            if (foundRequestedIcon)\n            {\n                parameter->ResourceHandle = FindResourceExW(hModule, lpType, lpName, 0);\n                return FALSE;\n            }\n\n            // Continue enumerating\n            parameter->IconsFound++;\n            return TRUE;\n        };\n\n        void WriteIconDirHeaderToByteArray(std::vector<BYTE>& data, const ICONDIR& iconDir)\n        {\n            data.clear();\n            BYTE const* toBeWritten = reinterpret_cast<BYTE const*>(&(iconDir.idReserved));\n            data.insert(data.end(), toBeWritten, toBeWritten + sizeof(iconDir.idReserved));\n            toBeWritten = reinterpret_cast<BYTE const*>(&(iconDir.idType));\n            data.insert(data.end(), toBeWritten, toBeWritten + sizeof(iconDir.idType));\n            toBeWritten = reinterpret_cast<BYTE const*>(&(iconDir.idCount));\n            data.insert(data.end(), toBeWritten, toBeWritten + sizeof(iconDir.idCount));\n        }\n\n        void AppendIconDirEntryToByteArray(std::vector<BYTE>& data, const ICONDIRENTRY& iconDirEntry)\n        {\n            data.insert(data.end(), iconDirEntry.bWidth);\n            data.insert(data.end(), iconDirEntry.bHeight);\n            data.insert(data.end(), iconDirEntry.bColorCount);\n            data.insert(data.end(), iconDirEntry.bReserved);\n            BYTE const* toBeWritten = reinterpret_cast<BYTE const*>(&(iconDirEntry.wPlanes));\n            data.insert(data.end(), toBeWritten, toBeWritten + sizeof(iconDirEntry.wPlanes));\n            toBeWritten = reinterpret_cast<BYTE const*>(&(iconDirEntry.wBitCount));\n            data.insert(data.end(), toBeWritten, toBeWritten + sizeof(iconDirEntry.wBitCount));\n            toBeWritten = reinterpret_cast<BYTE const*>(&(iconDirEntry.dwBytesInRes));\n            data.insert(data.end(), toBeWritten, toBeWritten + sizeof(iconDirEntry.dwBytesInRes));\n            toBeWritten = reinterpret_cast<BYTE const*>(&(iconDirEntry.dwImageOffset));\n            data.insert(data.end(), toBeWritten, toBeWritten + sizeof(iconDirEntry.dwImageOffset));\n        }\n    }\n\n    std::vector<BYTE> ExtractIconFromBinaryFile(const std::filesystem::path binaryPath, int iconIndex)\n    {\n        try\n        {\n            wil::unique_hmodule module;\n            module.reset(LoadLibraryEx(binaryPath.c_str(), nullptr, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE));\n            THROW_LAST_ERROR_IF_NULL(module);\n\n            EnumGroupIconProcParameter param;\n            param.IconIndex = iconIndex;\n\n#pragma warning( push )\n#pragma warning ( disable : 4302 )\n            // First find the requested group icon\n            EnumResourceNamesExW(\n                module.get(),\n                MAKEINTRESOURCE(RT_GROUP_ICON),\n                EnumGroupIconProc,\n                reinterpret_cast<LONG_PTR>(&param),\n                (RESOURCE_ENUM_MUI | RESOURCE_ENUM_LN | RESOURCE_ENUM_VALIDATE),\n                0);\n#pragma warning( pop )\n\n            if (param.ResourceHandle)\n            {\n                // Load and Lock to get a pointer to a GRPICONDIR\n                HGLOBAL groupIconResourceHandle = LoadResource(module.get(), param.ResourceHandle);\n                THROW_LAST_ERROR_IF_NULL(groupIconResourceHandle);\n                LPGRPICONDIR groupIconDir = reinterpret_cast<LPGRPICONDIR>(LockResource(groupIconResourceHandle));\n                THROW_LAST_ERROR_IF_NULL(groupIconDir);\n\n                // Basic validation\n                if (groupIconDir->idReserved != 0 || groupIconDir->idType != 1 || groupIconDir->idCount == 0)\n                {\n                    return {};\n                }\n\n                struct SingleIconImage\n                {\n                    ICONDIRENTRY DirEntry = { 0 };\n                    // pointer to byte contents with size\n                    std::pair<const BYTE*, DWORD> Content;\n                };\n\n                // Read all individual icon image contents\n                std::vector<SingleIconImage> iconContents;\n                // The first image's offset.\n                DWORD imageOffset = 6 /* ICONDIR size */ + groupIconDir->idCount * 16 /* each ICONDIRENTRY size */;\n\n                for (int i = 0; i < groupIconDir->idCount; i++)\n                {\n                    SingleIconImage iconEntry;\n\n                    // Populate ICONDIRENTRY\n                    iconEntry.DirEntry.bWidth = groupIconDir->idEntries[i].bWidth;\n                    iconEntry.DirEntry.bHeight = groupIconDir->idEntries[i].bHeight;\n                    iconEntry.DirEntry.bColorCount = groupIconDir->idEntries[i].bColorCount;\n                    iconEntry.DirEntry.bReserved = groupIconDir->idEntries[i].bReserved;\n                    iconEntry.DirEntry.wPlanes = groupIconDir->idEntries[i].wPlanes;\n                    iconEntry.DirEntry.wBitCount = groupIconDir->idEntries[i].wBitCount;\n                    iconEntry.DirEntry.dwBytesInRes = groupIconDir->idEntries[i].dwBytesInRes;\n                    iconEntry.DirEntry.dwImageOffset = imageOffset;\n\n                    // Load individual icon content\n                    HRSRC iconResourceHandle = FindResourceExW(module.get(), RT_ICON, MAKEINTRESOURCE(groupIconDir->idEntries[i].nID), 0);\n                    THROW_LAST_ERROR_IF_NULL(iconResourceHandle);\n                    HGLOBAL iconResourceContentHandle = LoadResource(module.get(), iconResourceHandle);\n                    THROW_LAST_ERROR_IF_NULL(iconResourceContentHandle);\n                    iconEntry.Content.second = SizeofResource(module.get(), iconResourceHandle);\n                    THROW_LAST_ERROR_IF(iconEntry.Content.second == 0);\n                    iconEntry.Content.first = reinterpret_cast<BYTE*>(LockResource(iconResourceContentHandle));\n                    THROW_LAST_ERROR_IF_NULL(iconEntry.Content.first);\n\n                    // This will be the next image offset.\n                    imageOffset += iconEntry.Content.second;\n\n                    iconContents.emplace_back(std::move(iconEntry));\n                }\n\n                // Construct ico file icon dir header\n                ICONDIR iconDir;\n                iconDir.idReserved = groupIconDir->idReserved;\n                iconDir.idType = groupIconDir->idType;\n                iconDir.idCount = groupIconDir->idCount;\n\n                std::vector<BYTE> result;\n\n                // Write Icon Dir header\n                WriteIconDirHeaderToByteArray(result, iconDir);\n\n                // Write Icon Dir entries\n                for (auto const& singleIconEntry : iconContents)\n                {\n                    AppendIconDirEntryToByteArray(result, singleIconEntry.DirEntry);\n                }\n\n                // Write Icon contents\n                for (auto const& singleIconEntry : iconContents)\n                {\n                    result.insert(result.end(), singleIconEntry.Content.first, singleIconEntry.Content.first + singleIconEntry.Content.second);\n                }\n\n                return result;\n            }\n        }\n        CATCH_LOG();\n\n        return {};\n    }\n\n#ifndef AICLI_DISABLE_TEST_HOOKS\n    static std::vector<ExtractedIconInfo>* s_ExtractIconFromArpEntry_TestHook_Override = nullptr;\n\n    void TestHook_SetExtractIconFromArpEntryResult_Override(std::vector<ExtractedIconInfo>* result)\n    {\n        s_ExtractIconFromArpEntry_TestHook_Override = result;\n    }\n#endif\n\n    std::vector<ExtractedIconInfo> ExtractIconFromArpEntry(const std::string& productCode, Manifest::ScopeEnum scope)\n    {\n#ifndef AICLI_DISABLE_TEST_HOOKS\n        if (s_ExtractIconFromArpEntry_TestHook_Override)\n        {\n            return *s_ExtractIconFromArpEntry_TestHook_Override;\n        }\n#endif\n\n        ARPHelper arpHelper;\n        Registry::Key arpEntry = arpHelper.FindARPEntry(productCode, scope);\n\n        if (arpEntry)\n        {\n            std::wstring iconPathRaw;\n            if (arpHelper.GetBoolValue(arpEntry, arpHelper.WindowsInstaller))\n            {\n                // For msi, get icon from ProductInfo\n                auto productCodeWide = Utility::ConvertToUTF16(productCode);\n                DWORD iconPathSize = 0;\n                if (ERROR_MORE_DATA == MsiGetProductInfoW(productCodeWide.c_str(), INSTALLPROPERTY_PRODUCTICON, nullptr, &iconPathSize))\n                {\n                    std::wstring iconPathBuffer;\n                    // The iconPathSize returned in previous call does not count the null terminator.\n                    iconPathSize++;\n                    iconPathBuffer.resize(iconPathSize);\n                    if (ERROR_SUCCESS == MsiGetProductInfoW(productCodeWide.c_str(), INSTALLPROPERTY_PRODUCTICON, iconPathBuffer.data(), &iconPathSize))\n                    {\n                        iconPathBuffer.resize(iconPathSize);\n                        iconPathRaw = iconPathBuffer;\n                    }\n                }\n            }\n            else\n            {\n                // For other win32 apps, try DisplayIcon.\n                iconPathRaw = Utility::ConvertToUTF16(arpHelper.GetStringValue(arpEntry, arpHelper.DisplayIcon));\n            }\n\n            if (!iconPathRaw.empty())\n            {\n                PathUnquoteSpacesW(iconPathRaw.data());\n                // For paths like C:\\test\\test.exe,-3\n                int iconIndex = 0;\n                iconIndex = PathParseIconLocationW(iconPathRaw.data());\n                // Above operations will modify the input string with null terminator in the middle.\n                iconPathRaw = iconPathRaw.c_str();\n                auto iconPath = Filesystem::GetExpandedPath(Utility::ConvertToUTF8(iconPathRaw));\n\n                if (std::filesystem::exists(iconPath))\n                {\n                    auto extension = iconPath.extension().u8string();\n                    std::vector<BYTE> iconContent;\n                    if (Utility::CaseInsensitiveEquals(extension, \".ico\"))\n                    {\n                        std::ifstream iconFile{ iconPath, std::ios::in | std::ios::binary };\n                        iconContent = Utility::ReadEntireStreamAsByteArray(iconFile);\n                    }\n                    else if (Utility::CaseInsensitiveEquals(extension, \".exe\") || Utility::CaseInsensitiveEquals(extension, \".dll\"))\n                    {\n                        iconContent = ExtractIconFromBinaryFile(iconPath, iconIndex);\n                    }\n\n                    // Construct ExtractedIconInfo return result\n                    if (!iconContent.empty())\n                    {\n                        ExtractedIconInfo iconInfo;\n                        iconInfo.IconFileType = Manifest::IconFileTypeEnum::Ico;\n                        iconInfo.IconTheme = Manifest::IconThemeEnum::Default;\n                        iconInfo.IconResolution = Manifest::IconResolutionEnum::Custom;\n                        iconInfo.IconSha256 = Utility::SHA256::ComputeHash(iconContent.data(), static_cast<uint32_t>(iconContent.size()));\n                        iconInfo.IconContent = std::move(iconContent);\n\n                        return { std::move(iconInfo) };\n                    }\n                }\n            }\n        }\n\n        return {};\n    }\n}"
  },
  {
    "path": "src/AppInstallerRepositoryCore/InstalledFilesCorrelation.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"winget/InstalledFilesCorrelation.h\"\r\n#include <winget/FolderFileWatcher.h>\r\n#include <winget/Filesystem.h>\r\n\r\nusing namespace AppInstaller::Manifest;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Utility;\r\n\r\nnamespace AppInstaller::Repository::Correlation\r\n{\r\n    namespace\r\n    {\r\n        constexpr std::string_view s_ShellLinkFileExtension = \".lnk\"sv;\r\n        const std::vector<std::pair<std::filesystem::path, std::string>> s_CandidateInstallLocationRoots =\r\n        {\r\n            { Filesystem::GetKnownFolderPath(FOLDERID_LocalAppData), \"%LOCALAPPDATA%\" },\r\n            { Filesystem::GetKnownFolderPath(FOLDERID_ProgramFiles), \"%PROGRAMFILES%\" },\r\n            { Filesystem::GetKnownFolderPath(FOLDERID_ProgramFilesX86), \"%PROGRAMFILES(X86)%\" },\r\n        };\r\n\r\n        // Contains shell link info\r\n        struct ShellLinkFileInfo\r\n        {\r\n            std::filesystem::path Path;\r\n            std::string Args;\r\n            std::string DisplayName;\r\n        };\r\n\r\n        std::optional<ShellLinkFileInfo> ParseShellLinkFile(const std::filesystem::path& linkFile)\r\n        {\r\n            try\r\n            {\r\n                AICLI_LOG(Repo, Info, << \"Parsing link file at \" << linkFile);\r\n\r\n                ShellLinkFileInfo result;\r\n\r\n                Microsoft::WRL::ComPtr<IShellLink> shellLink;\r\n                THROW_IF_FAILED(CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&shellLink)));\r\n                Microsoft::WRL::ComPtr<IPersistFile> persistFile;\r\n                THROW_IF_FAILED(shellLink.As(&persistFile));\r\n                THROW_IF_FAILED(persistFile->Load(linkFile.wstring().c_str(), STGM_READ));\r\n                THROW_IF_FAILED(shellLink->Resolve(nullptr, SLR_NO_UI | SLR_NOUPDATE | SLR_NOSEARCH | SLR_NOTRACK | SLR_NOLINKINFO));\r\n\r\n                {\r\n                    // Parse Path from shell link\r\n                    std::wstring buffer;\r\n                    buffer.resize(MAX_PATH);\r\n                    HRESULT hr = S_OK;\r\n                    for (int retry = 0; retry < 5; retry++)\r\n                    {\r\n                        hr = shellLink->GetPath(\r\n                            &buffer[0],\r\n                            static_cast<int>(buffer.size()),\r\n                            nullptr,\r\n                            0\r\n                        );\r\n\r\n                        if (SUCCEEDED(hr))\r\n                        {\r\n                            buffer.erase(std::find(buffer.begin(), buffer.end(), L'\\0'), buffer.end());\r\n                            result.Path = buffer;\r\n                            break;\r\n                        }\r\n                        else if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))\r\n                        {\r\n                            buffer.resize(buffer.size() * 2);\r\n                        }\r\n                        else\r\n                        {\r\n                            THROW_IF_FAILED(hr);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                {\r\n                    // Parse arguments from shell link\r\n                    std::wstring buffer;\r\n                    buffer.resize(MAX_PATH);\r\n                    HRESULT hr = S_OK;\r\n                    for (int retry = 0; retry < 5; retry++)\r\n                    {\r\n                        hr = shellLink->GetArguments(\r\n                            &buffer[0],\r\n                            static_cast<int>(buffer.size()));\r\n\r\n                        if (SUCCEEDED(hr))\r\n                        {\r\n                            buffer.erase(std::find(buffer.begin(), buffer.end(), L'\\0'), buffer.end());\r\n                            result.Args = Utility::ConvertToUTF8(buffer);\r\n                            break;\r\n                        }\r\n                        else if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))\r\n                        {\r\n                            buffer.resize(buffer.size() * 2);\r\n                        }\r\n                        else\r\n                        {\r\n                            THROW_IF_FAILED(hr);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                // Use shell link file name (minus extension) as display name.\r\n                result.DisplayName = linkFile.stem().u8string();\r\n\r\n                AICLI_LOG(Repo, Info, << \"Link file parsed. Path: \" << result.Path << \" Args: \" << result.Args << \" DisplayName: \" << result.DisplayName);\r\n\r\n                return result;\r\n            }\r\n            catch (...)\r\n            {\r\n                AICLI_LOG(Repo, Error, << \"Failed to parse link file at \" << linkFile);\r\n                return {};\r\n            }\r\n        }\r\n\r\n        // Returns nullopt if path is not under base.\r\n        std::optional<std::filesystem::path> GetRelativePath(const std::filesystem::path& path, const std::filesystem::path& base)\r\n        {\r\n            auto canonicalPath = std::filesystem::weakly_canonical(path);\r\n            auto canonicalBase = std::filesystem::weakly_canonical(base);\r\n\r\n            auto relativePath = std::filesystem::relative(canonicalPath, canonicalBase);\r\n            if (!relativePath.empty() && *relativePath.begin() != \".\" && *relativePath.begin() != \"..\")\r\n            {\r\n                return relativePath;\r\n            }\r\n            else\r\n            {\r\n                return {};\r\n            }\r\n        }\r\n\r\n        std::optional<std::filesystem::path> CheckOneInstallLocation(const std::filesystem::path& childFile, const std::filesystem::path& baseFolder)\r\n        {\r\n            auto relativePath = GetRelativePath(childFile, baseFolder);\r\n            if (relativePath)\r\n            {\r\n                // TODO: Here we assume the install location is the top directory of relative path.\r\n                auto installLocation = baseFolder / *relativePath->begin();\r\n                if (std::filesystem::exists(installLocation) && std::filesystem::is_directory(installLocation))\r\n                {\r\n                    return installLocation;\r\n                }\r\n            }\r\n\r\n            return {};\r\n        }\r\n\r\n        // If install location is not provided in arp entry, try LocalAppData folder and Program Files folders.\r\n        std::optional<std::filesystem::path> CheckInstallLocation(const std::filesystem::path& path)\r\n        {\r\n            for (auto const& entry : s_CandidateInstallLocationRoots)\r\n            {\r\n                auto installLocation = CheckOneInstallLocation(path, entry.first);\r\n                if (installLocation)\r\n                {\r\n                    return installLocation;\r\n                }\r\n            }\r\n\r\n            return {};\r\n        }\r\n\r\n        // TODO: basic heuristics to determine file type.\r\n        AppInstaller::Manifest::InstalledFileTypeEnum GetInstalledFileType(const ShellLinkFileInfo& linkInfo)\r\n        {\r\n            Manifest::InstalledFileTypeEnum result = Manifest::InstalledFileTypeEnum::Other;\r\n\r\n            if (Utility::CaseInsensitiveContainsSubstring(linkInfo.Path.u8string(), \"uninstall\") ||\r\n                Utility::CaseInsensitiveContainsSubstring(linkInfo.Path.u8string(), \"unins000\") ||\r\n                Utility::CaseInsensitiveContainsSubstring(linkInfo.Args, \"uninstall\") ||\r\n                Utility::CaseInsensitiveContainsSubstring(linkInfo.DisplayName, \"uninstall\"))\r\n            {\r\n                result = Manifest::InstalledFileTypeEnum::Uninstall;\r\n            }\r\n            else if (Utility::CaseInsensitiveEquals(linkInfo.Path.extension().u8string(), \".exe\"))\r\n            {\r\n                result = Manifest::InstalledFileTypeEnum::Launch;\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        std::string GetUnexpandedInstallLocation(const std::filesystem::path& installLocation)\r\n        {\r\n            // Try to match the candidate install location roots first.\r\n            std::filesystem::path resultInstallLocation = installLocation;\r\n            for (auto const& entry : s_CandidateInstallLocationRoots)\r\n            {\r\n                if (Filesystem::ReplaceCommonPathPrefix(resultInstallLocation, entry.first, entry.second))\r\n                {\r\n                    return resultInstallLocation.u8string();\r\n                }\r\n            }\r\n\r\n            // Then try PathUnExpandEnvStrings OS api\r\n            std::wstring installLocationWString = installLocation.wstring();\r\n            std::wstring buffer;\r\n            buffer.resize(installLocationWString.size() + 20);\r\n            if (PathUnExpandEnvStrings(\r\n                installLocationWString.c_str(),\r\n                &buffer[0],\r\n                static_cast<int>(buffer.size())))\r\n            {\r\n                buffer.resize(buffer.find(L'\\0'));\r\n                return Utility::ConvertToUTF8(buffer);\r\n            }\r\n\r\n            return resultInstallLocation.u8string();\r\n        }\r\n    }\r\n\r\n    InstalledFilesCorrelation::InstalledFilesCorrelation()\r\n    {\r\n        m_fileWatchers.emplace_back(Filesystem::GetKnownFolderPath(FOLDERID_CommonStartMenu), std::string{ s_ShellLinkFileExtension });\r\n        m_fileWatchers.emplace_back(Filesystem::GetKnownFolderPath(FOLDERID_StartMenu), std::string{ s_ShellLinkFileExtension });\r\n    }\r\n\r\n    void InstalledFilesCorrelation::StartFileWatcher()\r\n    {\r\n        m_files.clear();\r\n\r\n        for (auto& watcher : m_fileWatchers)\r\n        {\r\n            watcher.Start();\r\n        }\r\n    }\r\n\r\n    void InstalledFilesCorrelation::StopFileWatcher()\r\n    {\r\n        for (auto& watcher : m_fileWatchers)\r\n        {\r\n            watcher.Stop();\r\n        }\r\n\r\n        for (auto& watcher : m_fileWatchers)\r\n        {\r\n            FileWatcherFiles files;\r\n            files.Folder = watcher.FolderPath();\r\n\r\n            for (auto const& file : watcher.Files())\r\n            {\r\n                files.Files.emplace_back(file);\r\n            }\r\n\r\n            m_files.emplace_back(std::move(files));\r\n        }\r\n    }\r\n\r\n    InstallationMetadata InstalledFilesCorrelation::CorrelateForNewlyInstalled(\r\n        const Manifest::Manifest&,\r\n        const std::string& arpInstallLocation)\r\n    {\r\n        InstallationMetadata result;\r\n\r\n        std::filesystem::path installLocation;\r\n        // Use arp install location if provided\r\n        if (!arpInstallLocation.empty())\r\n        {\r\n            installLocation = Filesystem::GetExpandedPath(arpInstallLocation);\r\n        }\r\n\r\n        for (auto const& files : m_files)\r\n        {\r\n            for (auto const& file : files.Files)\r\n            {\r\n                // TODO: we only watch shell link files at the moment.\r\n                auto linkInfo = ParseShellLinkFile(files.Folder / file);\r\n                if (linkInfo)\r\n                {\r\n                    auto installedFileType = GetInstalledFileType(linkInfo.value());\r\n\r\n                    // Collect installed files metadata if exist\r\n                    if (std::filesystem::exists(linkInfo->Path) && std::filesystem::is_regular_file(linkInfo->Path))\r\n                    {\r\n                        if (installLocation.empty())\r\n                        {\r\n                            // TODO: In most cases, installed files are under same folder, so use the first file to determine install location at the moment.\r\n                            auto location = CheckInstallLocation(linkInfo->Path);\r\n                            if (!location)\r\n                            {\r\n                                continue;\r\n                            }\r\n\r\n                            installLocation = location.value();\r\n                        }\r\n\r\n                        auto relativePath = GetRelativePath(linkInfo->Path, installLocation);\r\n                        if (relativePath)\r\n                        {\r\n                            AppInstaller::Manifest::InstalledFile fileEntry;\r\n                            fileEntry.RelativeFilePath = relativePath->string();\r\n                            std::ifstream in{ linkInfo->Path, std::ifstream::binary };\r\n                            fileEntry.FileSha256 = Utility::SHA256::ComputeHash(in);\r\n                            fileEntry.InvocationParameter = linkInfo->Args;\r\n                            fileEntry.DisplayName = linkInfo->DisplayName;\r\n                            fileEntry.FileType = installedFileType;\r\n                            result.InstalledFiles.Files.emplace_back(std::move(fileEntry));\r\n                        }\r\n                    }\r\n\r\n                    // Collect short cut paths\r\n                    InstalledStartupLinkFile linkFile;\r\n                    linkFile.RelativeFilePath = file.u8string();\r\n                    linkFile.FileType = installedFileType;\r\n                    result.StartupLinkFiles.emplace_back(linkFile);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (!installLocation.empty())\r\n        {\r\n            result.InstalledFiles.DefaultInstallLocation = GetUnexpandedInstallLocation(installLocation);\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/InstallerMetadataCollectionContext.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"winget/InstallerMetadataCollectionContext.h\"\r\n\r\n#include <AppInstallerDownloader.h>\r\n#include <AppInstallerErrors.h>\r\n#include <AppInstallerLogging.h>\r\n#include <AppInstallerFileLogger.h>\r\n#include <winget/TraceLogger.h>\r\n#include <AppInstallerStrings.h>\r\n#include <winget/JsonUtil.h>\r\n#include <winget/ManifestJSONParser.h>\r\n\r\nusing namespace AppInstaller::Utility;\r\n\r\nnamespace AppInstaller::Repository::Metadata\r\n{\r\n    namespace\r\n    {\r\n        struct ProductMetadataFields_1_N\r\n        {\r\n            ProductMetadataFields_1_N(const Version& version)\r\n            {\r\n                if (::AppInstaller::Utility::Version{ \"1.1\" } <= version)\r\n                {\r\n                    SchemaVersion = L\"1.1\";\r\n                    Scope = L\"scope\";\r\n                }\r\n\r\n                if (::AppInstaller::Utility::Version{ \"1.2\" } <= version)\r\n                {\r\n                    SchemaVersion = L\"1.2\";\r\n                    InstalledFiles = L\"installedFiles\";\r\n                    DefaultInstallLocation = L\"DefaultInstallLocation\";\r\n                    InstallationMetadataFiles = L\"Files\";\r\n                    InstalledFileRelativeFilePath = L\"RelativeFilePath\";\r\n                    InstalledFileSha256 = L\"FileSha256\";\r\n                    InstalledFileType = L\"FileType\";\r\n                    InstalledFileInvocationParameter = L\"InvocationParameter\";\r\n                    InstalledFileDisplayName = L\"DisplayName\";\r\n                    InstalledStartupLinks = L\"startupLinks\";\r\n                    InstalledStartupLinkPath = L\"RelativeFilePath\";\r\n                    InstalledStartupLinkType = L\"FileType\";\r\n                    Icons = L\"icons\";\r\n                    IconContent = L\"IconContent\";\r\n                    IconSha256 = L\"IconSha256\";\r\n                    IconFileType = L\"IconFileType\";\r\n                    IconResolution = L\"IconResolution\";\r\n                    IconTheme = L\"IconTheme\";\r\n                }\r\n            }\r\n\r\n            utility::string_t SchemaVersion = L\"1.0\";\r\n\r\n            // 1.0\r\n            utility::string_t ProductVersionMin = L\"productVersionMin\";\r\n            utility::string_t ProductVersionMax = L\"productVersionMax\";\r\n            utility::string_t Metadata = L\"metadata\";\r\n            utility::string_t InstallerHash = L\"installerHash\";\r\n            utility::string_t SubmissionIdentifier = L\"submissionIdentifier\";\r\n            utility::string_t Version = L\"version\";\r\n            utility::string_t AppsAndFeaturesEntries = L\"AppsAndFeaturesEntries\";\r\n            utility::string_t Historical = L\"historical\";\r\n\r\n            // AppsAndFeaturesEntry fields.\r\n            utility::string_t DisplayName = L\"DisplayName\";\r\n            utility::string_t Publisher = L\"Publisher\";\r\n            utility::string_t DisplayVersion = L\"DisplayVersion\";\r\n            utility::string_t ProductCode = L\"ProductCode\";\r\n            utility::string_t UpgradeCode = L\"UpgradeCode\";\r\n            utility::string_t InstallerType = L\"InstallerType\";\r\n\r\n            utility::string_t VersionMin = L\"versionMin\";\r\n            utility::string_t VersionMax = L\"versionMax\";\r\n            utility::string_t Names = L\"names\";\r\n            utility::string_t Publishers = L\"publishers\";\r\n            utility::string_t ProductCodes = L\"productCodes\";\r\n            utility::string_t UpgradeCodes = L\"upgradeCodes\";\r\n\r\n            // 1.1\r\n            utility::string_t Scope;\r\n\r\n            // 1.2\r\n\r\n            // Installed files\r\n            utility::string_t InstalledFiles;\r\n            utility::string_t DefaultInstallLocation;\r\n            utility::string_t InstallationMetadataFiles;\r\n            utility::string_t InstalledFileRelativeFilePath;\r\n            utility::string_t InstalledFileSha256;\r\n            utility::string_t InstalledFileType;\r\n            utility::string_t InstalledFileInvocationParameter;\r\n            utility::string_t InstalledFileDisplayName;\r\n            // Startup links\r\n            utility::string_t InstalledStartupLinks;\r\n            utility::string_t InstalledStartupLinkPath;\r\n            utility::string_t InstalledStartupLinkType;\r\n            // Icons\r\n            utility::string_t Icons;\r\n            utility::string_t IconContent;\r\n            utility::string_t IconSha256;\r\n            utility::string_t IconFileType;\r\n            utility::string_t IconResolution;\r\n            utility::string_t IconTheme;\r\n        };\r\n\r\n        struct OutputFields_1_0\r\n        {\r\n            utility::string_t Version = L\"version\";\r\n            utility::string_t SubmissionData = L\"submissionData\";\r\n            utility::string_t InstallerHash = L\"installerHash\";\r\n            utility::string_t Status = L\"status\";\r\n            utility::string_t Metadata = L\"metadata\";\r\n            utility::string_t Diagnostics = L\"diagnostics\";\r\n        };\r\n        \r\n        struct DiagnosticFields\r\n        {\r\n            // Error case\r\n            utility::string_t ErrorHR = L\"errorHR\";\r\n            utility::string_t ErrorText = L\"errorText\";\r\n\r\n            // Non-error case\r\n            utility::string_t Reason = L\"reason\";\r\n            utility::string_t ChangedEntryCount = L\"changedEntryCount\";\r\n            utility::string_t MatchedEntryCount = L\"matchedEntryCount\";\r\n            utility::string_t IntersectionCount = L\"intersectionCount\";\r\n            utility::string_t CorrelationMeasures = L\"correlationMeasures\";\r\n            utility::string_t Value = L\"value\";\r\n            utility::string_t Name = L\"name\";\r\n            utility::string_t Publisher = L\"publisher\";\r\n        };\r\n\r\n        std::string GetRequiredString(const web::json::value& value, const utility::string_t& field)\r\n        {\r\n            auto optString = AppInstaller::JSON::GetRawStringValueFromJsonNode(value, field);\r\n            if (!optString)\r\n            {\r\n                AICLI_LOG(Repo, Error, << \"Required field '\" << Utility::ConvertToUTF8(field) << \"' was not present\");\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE);\r\n            }\r\n            return std::move(optString).value();\r\n        }\r\n\r\n        void AddFieldIfNotEmpty(web::json::value& value, const utility::string_t& field, std::string_view string)\r\n        {\r\n            if (!string.empty())\r\n            {\r\n                value[field] = AppInstaller::JSON::GetStringValue(string);\r\n            }\r\n        }\r\n\r\n        web::json::value CreateStringArray(const std::set<std::string>& values)\r\n        {\r\n            web::json::value result;\r\n            size_t index = 0;\r\n\r\n            for (const std::string& value : values)\r\n            {\r\n                result[index++] = AppInstaller::JSON::GetStringValue(value);\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        bool AddIfNotPresentAndNotEmpty(std::set<std::string>& strings, const std::set<std::string>& filter, const std::string& string)\r\n        {\r\n            if (string.empty() || filter.find(string) != filter.end())\r\n            {\r\n                return false;\r\n            }\r\n\r\n            strings.emplace(string);\r\n            return true;\r\n        }\r\n\r\n        bool AddIfNotPresentAndNotEmpty(std::set<std::string>& strings, const std::string& string)\r\n        {\r\n            return AddIfNotPresentAndNotEmpty(strings, strings, string);\r\n        }\r\n\r\n        void AddIfNotPresent(std::set<std::string>& strings, std::set<std::string>& filter, const std::set<std::string>& inputs)\r\n        {\r\n            for (const std::string& input : inputs)\r\n            {\r\n                if (AddIfNotPresentAndNotEmpty(strings, filter, input))\r\n                {\r\n                    filter.emplace(input);\r\n                }\r\n            }\r\n        }\r\n\r\n        void FilterAndAddToEntries(Manifest::AppsAndFeaturesEntry&& newEntry, std::vector<Manifest::AppsAndFeaturesEntry>& entries)\r\n        {\r\n            // Erase all duplicated data from the new entry\r\n            for (const auto& entry : entries)\r\n            {\r\n#define WINGET_ERASE_IF_SAME(_value_) if (entry._value_ == newEntry._value_) { newEntry._value_.clear(); }\r\n                WINGET_ERASE_IF_SAME(DisplayName);\r\n                WINGET_ERASE_IF_SAME(DisplayVersion);\r\n                WINGET_ERASE_IF_SAME(ProductCode);\r\n                WINGET_ERASE_IF_SAME(Publisher);\r\n                WINGET_ERASE_IF_SAME(UpgradeCode);\r\n#undef WINGET_ERASE_IF_SAME\r\n\r\n                if (entry.InstallerType == newEntry.InstallerType)\r\n                {\r\n                    newEntry.InstallerType = Manifest::InstallerTypeEnum::Unknown;\r\n                }\r\n            }\r\n\r\n            // If anything remains, add it\r\n            if (!newEntry.DisplayName.empty() || !newEntry.DisplayVersion.empty() || !newEntry.ProductCode.empty() ||\r\n                !newEntry.Publisher.empty() || !newEntry.UpgradeCode.empty() || newEntry.InstallerType != Manifest::InstallerTypeEnum::Unknown)\r\n            {\r\n                entries.emplace_back(std::move(newEntry));\r\n            }\r\n        }\r\n\r\n        std::optional<std::string> GetStringFromFutureSchema(const web::json::value& value, const utility::string_t& field)\r\n        {\r\n            if (field.empty())\r\n            {\r\n                return {};\r\n            }\r\n\r\n            return AppInstaller::JSON::GetRawStringValueFromJsonNode(value, field);\r\n        }\r\n\r\n        void SetStringFromFutureSchema(web::json::value& json, const utility::string_t& field, std::string_view value)\r\n        {\r\n            if (!field.empty())\r\n            {\r\n                json[field] = AppInstaller::JSON::GetStringValue(value);\r\n            }\r\n        }\r\n\r\n        // For installed files merging, we remove conflicting entries, like scope. Indicating we are not certain some files will always be installed.\r\n        void MergeInstalledFilesMetadata(Manifest::InstallationMetadataInfo& existing, const Manifest::InstallationMetadataInfo& incoming)\r\n        {\r\n            if (!Utility::CaseInsensitiveEquals(existing.DefaultInstallLocation, incoming.DefaultInstallLocation))\r\n            {\r\n                existing.Clear();\r\n                return;\r\n            }\r\n\r\n            auto existingItr = existing.Files.begin();\r\n            while (existingItr != existing.Files.end())\r\n            {\r\n                auto itr = std::find_if(incoming.Files.begin(), incoming.Files.end(), [&](const Manifest::InstalledFile& entry)\r\n                    {\r\n                        return Utility::CaseInsensitiveEquals(existingItr->RelativeFilePath, entry.RelativeFilePath);\r\n                    });\r\n\r\n                if (itr == incoming.Files.end())\r\n                {\r\n                    existingItr = existing.Files.erase(existingItr);\r\n                }\r\n                else\r\n                {\r\n                    if (existingItr->InvocationParameter != itr->InvocationParameter)\r\n                    {\r\n                        existingItr->InvocationParameter.clear();\r\n                    }\r\n                    if (!Utility::CaseInsensitiveEquals(existingItr->DisplayName, itr->DisplayName))\r\n                    {\r\n                        existingItr->DisplayName.clear();\r\n                    }\r\n                    if (!Utility::SHA256::AreEqual(existingItr->FileSha256, itr->FileSha256))\r\n                    {\r\n                        existingItr->FileSha256.clear();\r\n                    }\r\n                    if (existingItr->FileType != itr->FileType)\r\n                    {\r\n                        existingItr->FileType = Manifest::InstalledFileTypeEnum::Unknown;\r\n                    }\r\n\r\n                    ++existingItr;\r\n                }\r\n            }\r\n        }\r\n\r\n        // For startup link files merging, we add non duplicate entries, like ProductCodes. Indicating possible startup links an installer could potentially add.\r\n        void MergeStartupLinkFilesMetadata(std::vector<Correlation::InstalledStartupLinkFile>& existing, const std::vector<Correlation::InstalledStartupLinkFile>& incoming)\r\n        {\r\n            for (auto const& incomingEntry : incoming)\r\n            {\r\n                auto itr = std::find_if(existing.begin(), existing.end(), [&](const Correlation::InstalledStartupLinkFile& entry)\r\n                    {\r\n                        return Utility::CaseInsensitiveEquals(incomingEntry.RelativeFilePath, entry.RelativeFilePath);\r\n                    });\r\n\r\n                if (itr == existing.end())\r\n                {\r\n                    existing.emplace_back(incomingEntry);\r\n                }\r\n                else if (itr->FileType != incomingEntry.FileType)\r\n                {\r\n                    // Set conflicting file type to Unknown.\r\n                    itr->FileType = AppInstaller::Manifest::InstalledFileTypeEnum::Unknown;\r\n                }\r\n            }\r\n        }\r\n\r\n        // TODO: This method could be moved to rest response parser and reused when winget supports launch\r\n        // scenarios (i.e. when startup links info are exposed in winget manifest).\r\n        std::optional<std::vector<Correlation::InstalledStartupLinkFile>> DeserializeInstalledStartupLinks(\r\n            const web::json::value& startupLinkFiles,\r\n            const ProductMetadataFields_1_N& fields)\r\n        {\r\n            if (startupLinkFiles.is_null() || !startupLinkFiles.is_array())\r\n            {\r\n                return {};\r\n            }\r\n\r\n            std::vector<Correlation::InstalledStartupLinkFile> startupLinks;\r\n            for (auto const& startupLink : startupLinkFiles.as_array())\r\n            {\r\n                Correlation::InstalledStartupLinkFile fileEntry;\r\n\r\n                std::optional<std::string> relativeFilePath = AppInstaller::JSON::GetRawStringValueFromJsonNode(startupLink, fields.InstalledStartupLinkPath);\r\n                if (!AppInstaller::JSON::IsValidNonEmptyStringValue(relativeFilePath))\r\n                {\r\n                    AICLI_LOG(Repo, Error, << \"Missing RelativeFilePath in Installed Startup Link Files.\");\r\n                    return {};\r\n                }\r\n\r\n                fileEntry.RelativeFilePath = std::move(*relativeFilePath);\r\n\r\n                std::optional<std::string> fileType = AppInstaller::JSON::GetRawStringValueFromJsonNode(startupLink, fields.InstalledStartupLinkType);\r\n                if (AppInstaller::JSON::IsValidNonEmptyStringValue(fileType))\r\n                {\r\n                    fileEntry.FileType = Manifest::ConvertToInstalledFileTypeEnum(*fileType);\r\n                }\r\n\r\n                startupLinks.emplace_back(std::move(fileEntry));\r\n            }\r\n\r\n            return startupLinks;\r\n        }\r\n\r\n        std::vector<ExtractedIconInfo> DeserializeExtractedIcons(\r\n            const web::json::value& icons,\r\n            const ProductMetadataFields_1_N& fields)\r\n        {\r\n            if (icons.is_null() || !icons.is_array())\r\n            {\r\n                return {};\r\n            }\r\n\r\n            std::vector<ExtractedIconInfo> result;\r\n            for (auto const& iconInfo : icons.as_array())\r\n            {\r\n                ExtractedIconInfo iconInfoEntry;\r\n\r\n                auto content = AppInstaller::JSON::GetRawStringValueFromJsonNode(iconInfo, fields.IconContent);\r\n                if (!AppInstaller::JSON::IsValidNonEmptyStringValue(content))\r\n                {\r\n                    AICLI_LOG(Repo, Error, << \"Missing IconContent in Extracted Icons.\");\r\n                    return {};\r\n                }\r\n\r\n                iconInfoEntry.IconContent = AppInstaller::JSON::Base64Decode(*content);\r\n\r\n                std::optional<std::string> sha256 = AppInstaller::JSON::GetRawStringValueFromJsonNode(iconInfo, fields.IconSha256);\r\n                if (AppInstaller::JSON::IsValidNonEmptyStringValue(sha256))\r\n                {\r\n                    iconInfoEntry.IconSha256 = Utility::SHA256::ConvertToBytes(*sha256);\r\n                }\r\n\r\n                std::optional<std::string> fileType = AppInstaller::JSON::GetRawStringValueFromJsonNode(iconInfo, fields.IconFileType);\r\n                if (AppInstaller::JSON::IsValidNonEmptyStringValue(fileType))\r\n                {\r\n                    iconInfoEntry.IconFileType = Manifest::ConvertToIconFileTypeEnum(*fileType);\r\n                }\r\n\r\n                std::optional<std::string> theme = AppInstaller::JSON::GetRawStringValueFromJsonNode(iconInfo, fields.IconTheme);\r\n                if (AppInstaller::JSON::IsValidNonEmptyStringValue(theme))\r\n                {\r\n                    iconInfoEntry.IconTheme = Manifest::ConvertToIconThemeEnum(*theme);\r\n                }\r\n\r\n                std::optional<std::string> resolution = AppInstaller::JSON::GetRawStringValueFromJsonNode(iconInfo, fields.IconResolution);\r\n                if (AppInstaller::JSON::IsValidNonEmptyStringValue(resolution))\r\n                {\r\n                    iconInfoEntry.IconResolution = Manifest::ConvertToIconResolutionEnum(*resolution);\r\n                }\r\n\r\n                result.emplace_back(std::move(iconInfoEntry));\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n\r\n    void ProductMetadata::Clear()\r\n    {\r\n        SchemaVersion = {};\r\n        ProductVersionMin = {};\r\n        ProductVersionMax = {};\r\n        InstallerMetadataMap.clear();\r\n        HistoricalMetadataList.clear();\r\n    }\r\n\r\n    void ProductMetadata::FromJson(const web::json::value& json)\r\n    {\r\n        Clear();\r\n\r\n        utility::string_t versionFieldName = L\"version\";\r\n\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE, json.is_null());\r\n\r\n        SchemaVersion = Version{ GetRequiredString(json, versionFieldName) };\r\n        AICLI_LOG(Repo, Info, << \"Parsing metadata JSON version \" << SchemaVersion.ToString());\r\n\r\n        if (SchemaVersion.PartAt(0).Integer == 1)\r\n        {\r\n            FromJson_1_N(json);\r\n        }\r\n        else\r\n        {\r\n            AICLI_LOG(Repo, Error, << \"Don't know how to handle metadata version \" << SchemaVersion.ToString());\r\n            THROW_HR(HRESULT_FROM_WIN32(ERROR_UNSUPPORTED_TYPE));\r\n        }\r\n\r\n        // Sort the historical data with oldest last (thus b < a)\r\n        std::sort(HistoricalMetadataList.begin(), HistoricalMetadataList.end(),\r\n            [](const HistoricalMetadata& a, const HistoricalMetadata& b) {\r\n                return b.ProductVersionMin < a.ProductVersionMin;\r\n            });\r\n    }\r\n\r\n    web::json::value ProductMetadata::ToJson(const Utility::Version& schemaVersion, size_t maximumSizeInBytes)\r\n    {\r\n        SchemaVersion = schemaVersion;\r\n        AICLI_LOG(Repo, Info, << \"Creating metadata JSON version \" << SchemaVersion.ToString());\r\n\r\n        using ToJsonFunctionPointer = web::json::value(ProductMetadata::*)();\r\n        ToJsonFunctionPointer toJsonFunction = nullptr;\r\n\r\n        if (SchemaVersion.PartAt(0).Integer == 1)\r\n        {\r\n            toJsonFunction = &ProductMetadata::ToJson_1_N;\r\n        }\r\n        else\r\n        {\r\n            AICLI_LOG(Repo, Error, << \"Don't know how to handle metadata version \" << SchemaVersion.ToString());\r\n            THROW_HR(HRESULT_FROM_WIN32(ERROR_UNSUPPORTED_TYPE));\r\n        }\r\n\r\n        // Constrain the result based on maximum size given\r\n        web::json::value result = (this->*toJsonFunction)();\r\n\r\n        while (maximumSizeInBytes)\r\n        {\r\n            // Determine current size\r\n            std::ostringstream temp;\r\n            result.serialize(temp);\r\n\r\n            std::string tempStr = temp.str();\r\n            if (tempStr.length() > maximumSizeInBytes)\r\n            {\r\n                if (!DropOldestHistoricalData())\r\n                {\r\n                    AICLI_LOG(Repo, Error, << \"Could not remove any more historical data to get under \" << maximumSizeInBytes << \" bytes\");\r\n                    AICLI_LOG(Repo, Info, << \"  Smallest size was \" << tempStr.length() << \" bytes with value:\\n\" << tempStr);\r\n                    THROW_HR(HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE));\r\n                }\r\n                result = (this->*toJsonFunction)();\r\n            }\r\n            else\r\n            {\r\n                break;\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    void ProductMetadata::CopyFrom(const ProductMetadata& source, std::string_view submissionIdentifier)\r\n    {\r\n        // If the source has no installer metadata, consider it empty\r\n        if (source.InstallerMetadataMap.empty())\r\n        {\r\n            return;\r\n        }\r\n\r\n        // With the same submission, just copy over all of the data\r\n        if (source.InstallerMetadataMap.begin()->second.SubmissionIdentifier == submissionIdentifier)\r\n        {\r\n            *this = source;\r\n            return;\r\n        }\r\n\r\n        // This is a new submission, so we must move all of the data to historical and update the older historical data\r\n        // First, create a new historical entry for the current metadata\r\n        HistoricalMetadata currentHistory;\r\n\r\n        currentHistory.ProductVersionMin = source.ProductVersionMin;\r\n        currentHistory.ProductVersionMax = source.ProductVersionMax;\r\n\r\n        for (const auto& metadataItem : source.InstallerMetadataMap)\r\n        {\r\n            for (const auto& entry : metadataItem.second.AppsAndFeaturesEntries)\r\n            {\r\n                AddIfNotPresentAndNotEmpty(currentHistory.Names, entry.DisplayName);\r\n                AddIfNotPresentAndNotEmpty(currentHistory.Publishers, entry.Publisher);\r\n                AddIfNotPresentAndNotEmpty(currentHistory.ProductCodes, entry.ProductCode);\r\n                AddIfNotPresentAndNotEmpty(currentHistory.UpgradeCodes, entry.UpgradeCode);\r\n            }\r\n        }\r\n\r\n        // Copy the data in so that we can continue using currentHistory to track all strings\r\n        HistoricalMetadataList.emplace_back(currentHistory);\r\n\r\n        // Now, copy over the other historical data, filtering out anything we have seen\r\n        for (const auto& historical : source.HistoricalMetadataList)\r\n        {\r\n            HistoricalMetadata copied;\r\n            copied.ProductVersionMin = historical.ProductVersionMin;\r\n            copied.ProductVersionMax = historical.ProductVersionMax;\r\n            AddIfNotPresent(copied.Names, currentHistory.Names, historical.Names);\r\n            AddIfNotPresent(copied.Publishers, currentHistory.Publishers, historical.Publishers);\r\n            AddIfNotPresent(copied.ProductCodes, currentHistory.ProductCodes, historical.ProductCodes);\r\n            AddIfNotPresent(copied.UpgradeCodes, currentHistory.UpgradeCodes, historical.UpgradeCodes);\r\n\r\n            if (!copied.Names.empty() || !copied.Publishers.empty() || !copied.ProductCodes.empty() || !copied.UpgradeCodes.empty())\r\n            {\r\n                HistoricalMetadataList.emplace_back(std::move(copied));\r\n            }\r\n        }\r\n    }\r\n\r\n    void ProductMetadata::FromJson_1_N(const web::json::value& json)\r\n    {\r\n        AICLI_LOG(Repo, Info, << \"Parsing metadata JSON \" << SchemaVersion.ToString() << \" fields\");\r\n\r\n        ProductMetadataFields_1_N fields{ SchemaVersion };\r\n\r\n        auto productVersionMinString = AppInstaller::JSON::GetRawStringValueFromJsonNode(json, fields.ProductVersionMin);\r\n        if (productVersionMinString)\r\n        {\r\n            ProductVersionMin = Version{ std::move(productVersionMinString).value() };\r\n        }\r\n\r\n        auto productVersionMaxString = AppInstaller::JSON::GetRawStringValueFromJsonNode(json, fields.ProductVersionMax);\r\n        if (productVersionMaxString)\r\n        {\r\n            ProductVersionMax = Version{ std::move(productVersionMaxString).value() };\r\n        }\r\n\r\n        // The 1.0 version of metadata uses the 1.5 version of REST\r\n        JSON::ManifestJSONParser parser{ Version{ \"1.5\" } };\r\n\r\n        std::string submissionIdentifierVerification;\r\n\r\n        auto metadataArray = AppInstaller::JSON::GetRawJsonArrayFromJsonNode(json, fields.Metadata);\r\n        if (metadataArray)\r\n        {\r\n            for (const auto& item : metadataArray->get())\r\n            {\r\n                std::string installerHashString = GetRequiredString(item, fields.InstallerHash);\r\n                THROW_HR_IF(APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE, InstallerMetadataMap.find(installerHashString) != InstallerMetadataMap.end());\r\n\r\n                InstallerMetadata installerMetadata;\r\n\r\n                installerMetadata.SubmissionIdentifier = GetRequiredString(item, fields.SubmissionIdentifier);\r\n                if (submissionIdentifierVerification.empty())\r\n                {\r\n                    submissionIdentifierVerification = installerMetadata.SubmissionIdentifier;\r\n                }\r\n                else if (submissionIdentifierVerification != installerMetadata.SubmissionIdentifier)\r\n                {\r\n                    AICLI_LOG(Repo, Error, << \"Different submission identifiers found in metadata: '\" <<\r\n                        submissionIdentifierVerification << \"' and '\" << installerMetadata.SubmissionIdentifier << \"'\");\r\n                    THROW_HR(APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE);\r\n                }\r\n\r\n                auto appsAndFeatures = AppInstaller::JSON::GetRawJsonArrayFromJsonNode(item, fields.AppsAndFeaturesEntries);\r\n                THROW_HR_IF(APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE, !appsAndFeatures);\r\n                installerMetadata.AppsAndFeaturesEntries = parser.DeserializeAppsAndFeaturesEntries(appsAndFeatures.value());\r\n\r\n                installerMetadata.Scope = GetStringFromFutureSchema(item, fields.Scope).value_or(std::string{});\r\n\r\n                if (!fields.InstalledFiles.empty())\r\n                {\r\n                    auto installedFiles = AppInstaller::JSON::GetJsonValueFromNode(item, fields.InstalledFiles);\r\n                    if (installedFiles)\r\n                    {\r\n                        installerMetadata.InstalledFiles = parser.DeserializeInstallationMetadata(installedFiles->get());\r\n                    }\r\n                }\r\n\r\n                if (!fields.InstalledStartupLinks.empty())\r\n                {\r\n                    auto startupLinks = AppInstaller::JSON::GetJsonValueFromNode(item, fields.InstalledStartupLinks);\r\n                    if (startupLinks)\r\n                    {\r\n                        installerMetadata.StartupLinkFiles = DeserializeInstalledStartupLinks(startupLinks->get(), fields);\r\n                    }\r\n                }\r\n\r\n                if (!fields.Icons.empty())\r\n                {\r\n                    auto icons = AppInstaller::JSON::GetJsonValueFromNode(item, fields.Icons);\r\n                    if (icons)\r\n                    {\r\n                        installerMetadata.Icons = DeserializeExtractedIcons(icons->get(), fields);\r\n                    }\r\n                }\r\n\r\n                InstallerMetadataMap[installerHashString] = std::move(installerMetadata);\r\n            }\r\n        }\r\n\r\n        auto historicalArray = AppInstaller::JSON::GetRawJsonArrayFromJsonNode(json, fields.Historical);\r\n        if (historicalArray)\r\n        {\r\n            for (const auto& item : historicalArray->get())\r\n            {\r\n                HistoricalMetadata historicalMetadata;\r\n\r\n                historicalMetadata.ProductVersionMin = Version{ GetRequiredString(item, fields.VersionMin) };\r\n                historicalMetadata.ProductVersionMax = Version{ GetRequiredString(item, fields.VersionMax) };\r\n                historicalMetadata.Names = AppInstaller::JSON::GetRawStringSetFromJsonNode(item, fields.Names);\r\n                historicalMetadata.Publishers = AppInstaller::JSON::GetRawStringSetFromJsonNode(item, fields.Publishers);\r\n                historicalMetadata.ProductCodes = AppInstaller::JSON::GetRawStringSetFromJsonNode(item, fields.ProductCodes);\r\n                historicalMetadata.UpgradeCodes = AppInstaller::JSON::GetRawStringSetFromJsonNode(item, fields.UpgradeCodes);\r\n\r\n                HistoricalMetadataList.emplace_back(std::move(historicalMetadata));\r\n            }\r\n        }\r\n    }\r\n\r\n    web::json::value ProductMetadata::ToJson_1_N()\r\n    {\r\n        AICLI_LOG(Repo, Info, << \"Creating metadata JSON \" << SchemaVersion.ToString() << \" fields\");\r\n\r\n        ProductMetadataFields_1_N fields{ SchemaVersion };\r\n\r\n        web::json::value result;\r\n\r\n        result[fields.Version] = web::json::value::string(fields.SchemaVersion);\r\n        result[fields.ProductVersionMin] = AppInstaller::JSON::GetStringValue(ProductVersionMin.ToString());\r\n        result[fields.ProductVersionMax] = AppInstaller::JSON::GetStringValue(ProductVersionMax.ToString());\r\n\r\n        web::json::value metadataArray = web::json::value::array();\r\n        size_t metadataItemIndex = 0;\r\n        for (const auto& item : InstallerMetadataMap)\r\n        {\r\n            web::json::value itemValue;\r\n\r\n            itemValue[fields.InstallerHash] = AppInstaller::JSON::GetStringValue(item.first);\r\n            itemValue[fields.SubmissionIdentifier] = AppInstaller::JSON::GetStringValue(item.second.SubmissionIdentifier);\r\n            SetStringFromFutureSchema(itemValue, fields.Scope, item.second.Scope);\r\n            if (!fields.InstalledFiles.empty() && item.second.InstalledFiles.has_value())\r\n            {\r\n                web::json::value installationMetadata;\r\n\r\n                installationMetadata[fields.DefaultInstallLocation] = AppInstaller::JSON::GetStringValue(item.second.InstalledFiles->DefaultInstallLocation);\r\n\r\n                web::json::value installedFilesArray = web::json::value::array();\r\n                size_t installedFileIndex = 0;\r\n                for (const auto& entry : item.second.InstalledFiles->Files)\r\n                {\r\n                    web::json::value entryValue;\r\n                    AddFieldIfNotEmpty(entryValue, fields.InstalledFileRelativeFilePath, entry.RelativeFilePath);\r\n                    AddFieldIfNotEmpty(entryValue, fields.InstalledFileInvocationParameter, entry.InvocationParameter);\r\n                    AddFieldIfNotEmpty(entryValue, fields.InstalledFileDisplayName, entry.DisplayName);\r\n                    entryValue[fields.InstalledFileType] = AppInstaller::JSON::GetStringValue(Manifest::InstalledFileTypeToString(entry.FileType));\r\n                    if (!entry.FileSha256.empty())\r\n                    {\r\n                        entryValue[fields.InstalledFileSha256] = AppInstaller::JSON::GetStringValue(SHA256::ConvertToString(entry.FileSha256));\r\n                    }\r\n                    installedFilesArray[installedFileIndex++] = std::move(entryValue);\r\n                }\r\n                installationMetadata[fields.InstallationMetadataFiles] = std::move(installedFilesArray);\r\n\r\n                itemValue[fields.InstalledFiles] = std::move(installationMetadata);\r\n            }\r\n\r\n            if (!fields.InstalledStartupLinks.empty() && item.second.StartupLinkFiles.has_value())\r\n            {\r\n                web::json::value startupLinkFilesArray = web::json::value::array();\r\n                size_t startupLinkFileIndex = 0;\r\n                for (const auto& entry : item.second.StartupLinkFiles.value())\r\n                {\r\n                    web::json::value entryValue;\r\n                    entryValue[fields.InstalledStartupLinkPath] = AppInstaller::JSON::GetStringValue(entry.RelativeFilePath);\r\n                    entryValue[fields.InstalledStartupLinkType] = AppInstaller::JSON::GetStringValue(Manifest::InstalledFileTypeToString(entry.FileType));\r\n\r\n                    startupLinkFilesArray[startupLinkFileIndex++] = std::move(entryValue);\r\n                }\r\n\r\n                itemValue[fields.InstalledStartupLinks] = std::move(startupLinkFilesArray);\r\n            }\r\n\r\n            if (!fields.Icons.empty() && !item.second.Icons.empty())\r\n            {\r\n                web::json::value iconsArray = web::json::value::array();\r\n                size_t iconIndex = 0;\r\n                for (const auto& entry : item.second.Icons)\r\n                {\r\n                    web::json::value entryValue;\r\n                    entryValue[fields.IconContent] = AppInstaller::JSON::GetStringValue(AppInstaller::JSON::Base64Encode(entry.IconContent));\r\n                    if (!entry.IconSha256.empty())\r\n                    {\r\n                        entryValue[fields.IconSha256] = AppInstaller::JSON::GetStringValue(SHA256::ConvertToString(entry.IconSha256));\r\n                    }\r\n                    entryValue[fields.IconFileType] = AppInstaller::JSON::GetStringValue(Manifest::IconFileTypeToString(entry.IconFileType));\r\n                    entryValue[fields.IconTheme] = AppInstaller::JSON::GetStringValue(Manifest::IconThemeToString(entry.IconTheme));\r\n                    entryValue[fields.IconResolution] = AppInstaller::JSON::GetStringValue(Manifest::IconResolutionToString(entry.IconResolution));\r\n\r\n                    iconsArray[iconIndex++] = std::move(entryValue);\r\n                }\r\n\r\n                itemValue[fields.Icons] = std::move(iconsArray);\r\n            }\r\n\r\n            web::json::value appsAndFeaturesArray = web::json::value::array();\r\n            size_t appsAndFeaturesEntryIndex = 0;\r\n            for (const auto& entry : item.second.AppsAndFeaturesEntries)\r\n            {\r\n                web::json::value entryValue;\r\n\r\n                AddFieldIfNotEmpty(entryValue, fields.DisplayName, entry.DisplayName);\r\n                AddFieldIfNotEmpty(entryValue, fields.Publisher, entry.Publisher);\r\n                AddFieldIfNotEmpty(entryValue, fields.DisplayVersion, entry.DisplayVersion);\r\n                AddFieldIfNotEmpty(entryValue, fields.ProductCode, entry.ProductCode);\r\n                AddFieldIfNotEmpty(entryValue, fields.UpgradeCode, entry.UpgradeCode);\r\n                if (entry.InstallerType != Manifest::InstallerTypeEnum::Unknown)\r\n                {\r\n                    entryValue[fields.InstallerType] = AppInstaller::JSON::GetStringValue(Manifest::InstallerTypeToString(entry.InstallerType));\r\n                }\r\n\r\n                appsAndFeaturesArray[appsAndFeaturesEntryIndex++] = std::move(entryValue);\r\n            }\r\n\r\n            itemValue[fields.AppsAndFeaturesEntries] = std::move(appsAndFeaturesArray);\r\n\r\n            metadataArray[metadataItemIndex++] = std::move(itemValue);\r\n        }\r\n\r\n        result[fields.Metadata] = std::move(metadataArray);\r\n\r\n        web::json::value historicalArray = web::json::value::array();\r\n        size_t historicalItemIndex = 0;\r\n        for (const auto& item : HistoricalMetadataList)\r\n        {\r\n            web::json::value itemValue;\r\n\r\n            itemValue[fields.VersionMin] = AppInstaller::JSON::GetStringValue(item.ProductVersionMin.ToString());\r\n            itemValue[fields.VersionMax] = AppInstaller::JSON::GetStringValue(item.ProductVersionMax.ToString());\r\n            itemValue[fields.Names] = CreateStringArray(item.Names);\r\n            itemValue[fields.Publishers] = CreateStringArray(item.Publishers);\r\n            itemValue[fields.ProductCodes] = CreateStringArray(item.ProductCodes);\r\n            itemValue[fields.UpgradeCodes] = CreateStringArray(item.UpgradeCodes);\r\n\r\n            historicalArray[historicalItemIndex++] = std::move(itemValue);\r\n        }\r\n\r\n        result[fields.Historical] = std::move(historicalArray);\r\n\r\n        return result;\r\n    }\r\n\r\n    bool ProductMetadata::DropOldestHistoricalData()\r\n    {\r\n        if (HistoricalMetadataList.empty())\r\n        {\r\n            return false;\r\n        }\r\n\r\n        HistoricalMetadataList.pop_back();\r\n        return true;\r\n    }\r\n\r\n    InstallerMetadataCollectionContext::InstallerMetadataCollectionContext() :\r\n        m_correlationData(std::make_unique<Correlation::ARPCorrelationData>()),\r\n        m_installedFilesCorrelation(std::make_unique<Correlation::InstalledFilesCorrelation>())\r\n    {}\r\n\r\n    InstallerMetadataCollectionContext::InstallerMetadataCollectionContext(\r\n        std::unique_ptr<Correlation::ARPCorrelationData> correlationData,\r\n        std::unique_ptr<Correlation::InstalledFilesCorrelation> installedFilesCorrelation,\r\n        const std::wstring& json) :\r\n        m_correlationData(std::move(correlationData)), m_installedFilesCorrelation(std::move(installedFilesCorrelation))\r\n    {\r\n        auto threadGlobalsLifetime = InitializeLogging({});\r\n        InitializePreinstallState(json);\r\n    }\r\n\r\n    std::unique_ptr<InstallerMetadataCollectionContext> InstallerMetadataCollectionContext::FromFile(const std::filesystem::path& file, const std::filesystem::path& logFile)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, file.empty());\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), !std::filesystem::exists(file));\r\n\r\n        std::unique_ptr<InstallerMetadataCollectionContext> result = std::make_unique<InstallerMetadataCollectionContext>();\r\n        auto threadGlobalsLifetime = result->InitializeLogging(logFile);\r\n\r\n        AICLI_LOG(Repo, Info, << \"Opening InstallerMetadataCollectionContext input file: \" << file);\r\n        std::ifstream fileStream{ file };\r\n\r\n        auto content = ReadEntireStream(fileStream);\r\n        // CppRestSdk's implementation of json parsing does not work with '\\0', so trimming them here\r\n        content.erase(std::find(content.begin(), content.end(), '\\0'), content.end());\r\n\r\n        result->InitializePreinstallState(ConvertToUTF16(content));\r\n\r\n        return result;\r\n    }\r\n\r\n    std::unique_ptr<InstallerMetadataCollectionContext> InstallerMetadataCollectionContext::FromURI(std::wstring_view uri, const std::filesystem::path& logFile)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, uri.empty());\r\n\r\n        std::unique_ptr<InstallerMetadataCollectionContext> result = std::make_unique<InstallerMetadataCollectionContext>();\r\n        auto threadGlobalsLifetime = result->InitializeLogging(logFile);\r\n\r\n        std::string utf8Uri = ConvertToUTF8(uri);\r\n        THROW_HR_IF(E_INVALIDARG, !IsUrlRemote(utf8Uri));\r\n\r\n        AICLI_LOG(Repo, Info, << \"Downloading InstallerMetadataCollectionContext input file: \" << utf8Uri);\r\n\r\n        std::ostringstream jsonStream;\r\n        ProgressCallback emptyCallback;\r\n\r\n        const int MaxRetryCount = 2;\r\n        for (int retryCount = 0; retryCount < MaxRetryCount; ++retryCount)\r\n        {\r\n            try\r\n            {\r\n                auto downloadHash = DownloadToStream(utf8Uri, jsonStream, DownloadType::InstallerMetadataCollectionInput, emptyCallback);\r\n                break;\r\n            }\r\n            catch (...)\r\n            {\r\n                if (retryCount < MaxRetryCount - 1)\r\n                {\r\n                    AICLI_LOG(Repo, Info, << \"  Downloading InstallerMetadataCollectionContext input failed, waiting a bit and retrying...\");\r\n                    Sleep(500);\r\n                }\r\n                else\r\n                {\r\n                    throw;\r\n                }\r\n            }\r\n        }\r\n\r\n        result->InitializePreinstallState(ConvertToUTF16(jsonStream.str()));\r\n\r\n        return result;\r\n    }\r\n\r\n    std::unique_ptr<InstallerMetadataCollectionContext> InstallerMetadataCollectionContext::FromJSON(const std::wstring& json, const std::filesystem::path& logFile)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, json.empty());\r\n\r\n        std::unique_ptr<InstallerMetadataCollectionContext> result = std::make_unique<InstallerMetadataCollectionContext>();\r\n        auto threadGlobalsLifetime = result->InitializeLogging(logFile);\r\n        result->InitializePreinstallState(json);\r\n\r\n        return result;\r\n    }\r\n\r\n    void InstallerMetadataCollectionContext::Complete(const std::filesystem::path& output)\r\n    {\r\n        auto threadGlobalsLifetime = m_threadGlobals.SetForCurrentThread();\r\n\r\n        THROW_HR_IF(E_INVALIDARG, !output.has_filename());\r\n\r\n        if (output.has_parent_path())\r\n        {\r\n            std::filesystem::create_directories(output.parent_path());\r\n        }\r\n\r\n        std::ofstream outputStream{ output };\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_OPEN_FAILED), !outputStream);\r\n\r\n        CompleteWithThreadGlobalsSet(outputStream);\r\n    }\r\n\r\n    void InstallerMetadataCollectionContext::Complete(std::ostream& output)\r\n    {\r\n        auto threadGlobalsLifetime = m_threadGlobals.SetForCurrentThread();\r\n        CompleteWithThreadGlobalsSet(output);\r\n    }\r\n\r\n    std::wstring InstallerMetadataCollectionContext::Merge(const std::wstring& json, size_t maximumSizeInBytes, const std::filesystem::path& logFile)\r\n    {\r\n        ThreadLocalStorage::WingetThreadGlobals threadGlobals;\r\n        auto globalsLifetime = InitializeLogging(threadGlobals, logFile);\r\n\r\n        AICLI_LOG(Repo, Info, << \"Parsing input JSON:\\n\" << ConvertToUTF8(json));\r\n\r\n        // Parse and validate JSON\r\n        try\r\n        {\r\n            utility::string_t versionFieldName = L\"version\";\r\n\r\n            web::json::value inputValue = web::json::value::parse(json);\r\n\r\n            THROW_HR_IF(APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE, inputValue.is_null());\r\n\r\n            Version inputVersion = Version{ GetRequiredString(inputValue, versionFieldName) };\r\n            AICLI_LOG(Repo, Info, << \"Parsing input JSON version \" << inputVersion.ToString());\r\n\r\n            web::json::value mergedResult;\r\n\r\n            if (inputVersion.PartAt(0).Integer == 1)\r\n            {\r\n                mergedResult = Merge_1_0(inputValue, maximumSizeInBytes);\r\n            }\r\n            else\r\n            {\r\n                AICLI_LOG(Repo, Error, << \"Don't know how to handle version \" << inputVersion.ToString());\r\n                THROW_HR(HRESULT_FROM_WIN32(ERROR_UNSUPPORTED_TYPE));\r\n            }\r\n\r\n            std::wostringstream outputStream;\r\n            mergedResult.serialize(outputStream);\r\n\r\n            return std::move(outputStream).str();\r\n        }\r\n        catch (const web::json::json_exception& exc)\r\n        {\r\n            AICLI_LOG(Repo, Error, << \"Exception parsing input JSON: \" << exc.what());\r\n        }\r\n\r\n        // We will return within the try or throw a non-json exception, so if we get here it was a json exception.\r\n        THROW_HR(APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE);\r\n    }\r\n\r\n    void InstallerMetadataCollectionContext::CompleteWithThreadGlobalsSet(std::ostream& output)\r\n    {\r\n        web::json::value outputJSON;\r\n\r\n        if (!ContainsError())\r\n        {\r\n            try\r\n            {\r\n                // Collect post-install system state\r\n                m_correlationData->CapturePostInstallSnapshot();\r\n                m_installedFilesCorrelation->StopFileWatcher();\r\n\r\n                ComputeOutputData();\r\n\r\n                // Construct output JSON\r\n                AICLI_LOG(Repo, Info, << \"Creating output JSON version for input version \" << m_inputVersion.ToString());\r\n\r\n                if (m_inputVersion.PartAt(0).Integer == 1)\r\n                {\r\n                    // We only have one version currently, so use that as long as the major version is 1\r\n                    outputJSON = CreateOutputJson_1_0();\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(Repo, Error, << \"Don't know how to output for version \" << m_inputVersion.ToString());\r\n                    THROW_HR(HRESULT_FROM_WIN32(ERROR_UNSUPPORTED_TYPE));\r\n                }\r\n            }\r\n            catch (...)\r\n            {\r\n                CollectErrorDataFromException(std::current_exception());\r\n            }\r\n        }\r\n\r\n        if (ContainsError())\r\n        {\r\n            // We only have one version currently\r\n            outputJSON = CreateErrorJson_1_0();\r\n        }\r\n\r\n        // Write output\r\n        outputJSON.serialize(output);\r\n    }\r\n\r\n    std::unique_ptr<ThreadLocalStorage::PreviousThreadGlobals> InstallerMetadataCollectionContext::InitializeLogging(ThreadLocalStorage::WingetThreadGlobals& threadGlobals, const std::filesystem::path& logFile)\r\n    {\r\n        auto threadGlobalsLifetime = threadGlobals.SetForCurrentThread();\r\n\r\n        Logging::Log().SetLevel(Logging::Level::Info);\r\n        Logging::Log().SetEnabledChannels(Logging::Channel::All);\r\n        Logging::EnableWilFailureTelemetry();\r\n        Logging::TraceLogger::Add();\r\n\r\n        if (!logFile.empty())\r\n        {\r\n            Logging::FileLogger::Add(logFile);\r\n        }\r\n\r\n        Logging::Telemetry().SetCaller(\"installer-metadata-collection\");\r\n        Logging::Telemetry().LogStartup();\r\n\r\n        return threadGlobalsLifetime;\r\n    }\r\n\r\n    std::unique_ptr<ThreadLocalStorage::PreviousThreadGlobals> InstallerMetadataCollectionContext::InitializeLogging(const std::filesystem::path& logFile)\r\n    {\r\n        return InitializeLogging(m_threadGlobals, logFile);\r\n    }\r\n\r\n    void InstallerMetadataCollectionContext::InitializePreinstallState(const std::wstring& json)\r\n    {\r\n        try\r\n        {\r\n            AICLI_LOG(Repo, Info, << \"Parsing input JSON:\\n\" << ConvertToUTF8(json));\r\n\r\n            // Parse and validate JSON\r\n            try\r\n            {\r\n                utility::string_t versionFieldName = L\"version\";\r\n\r\n                web::json::value inputValue = web::json::value::parse(json);\r\n\r\n                THROW_HR_IF(APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE, inputValue.is_null());\r\n\r\n                m_inputVersion = Version{ GetRequiredString(inputValue, versionFieldName) };\r\n                AICLI_LOG(Repo, Info, << \"Parsing input JSON version \" << m_inputVersion.ToString());\r\n\r\n                if (m_inputVersion.PartAt(0).Integer == 1)\r\n                {\r\n                    // We only have one version currently, so use that as long as the major version is 1\r\n                    ParseInputJson_1_0(inputValue);\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(Repo, Error, << \"Don't know how to handle version \" << m_inputVersion.ToString());\r\n                    THROW_HR(HRESULT_FROM_WIN32(ERROR_UNSUPPORTED_TYPE));\r\n                }\r\n            }\r\n            catch (const web::json::json_exception& exc)\r\n            {\r\n                AICLI_LOG(Repo, Error, << \"Exception parsing input JSON: \" << exc.what());\r\n                throw;\r\n            }\r\n\r\n            // Collect pre-install system state\r\n            m_correlationData->CapturePreInstallSnapshot();\r\n            m_installedFilesCorrelation->StartFileWatcher();\r\n        }\r\n        catch (...)\r\n        {\r\n            CollectErrorDataFromException(std::current_exception());\r\n        }\r\n    }\r\n\r\n    void InstallerMetadataCollectionContext::ComputeOutputData()\r\n    {\r\n        // Copy the metadata from the current; this function takes care of moving data to historical if the submission is new.\r\n        m_outputMetadata.CopyFrom(m_currentMetadata, m_submissionIdentifier);\r\n\r\n        Correlation::ARPCorrelationSettings settings;\r\n        std::string arpInstallLocation;\r\n        // As this code is typically run in a controlled environment, we can assume that a single value change is very likely the correct value.\r\n        settings.AllowSingleChange = true;\r\n\r\n        // ARP entry correlation\r\n        Correlation::ARPCorrelationResult correlationResult = m_correlationData->CorrelateForNewlyInstalled(m_incomingManifest, settings);\r\n\r\n        if (correlationResult.Package)\r\n        {\r\n            auto& package = correlationResult.Package;\r\n\r\n            // Update min and max versions based on the version of the correlated package\r\n            Version packageVersion{ package->GetProperty(PackageVersionProperty::Version) };\r\n\r\n            if (m_outputMetadata.ProductVersionMin.IsEmpty() || packageVersion < m_outputMetadata.ProductVersionMin)\r\n            {\r\n                m_outputMetadata.ProductVersionMin = packageVersion;\r\n            }\r\n\r\n            if (m_outputMetadata.ProductVersionMax.IsEmpty() || m_outputMetadata.ProductVersionMax < packageVersion)\r\n            {\r\n                m_outputMetadata.ProductVersionMax = packageVersion;\r\n            }\r\n\r\n            // Create the AppsAndFeaturesEntry that we need to add\r\n            Manifest::AppsAndFeaturesEntry newEntry;\r\n            auto packageMetadata = package->GetMetadata();\r\n\r\n            // Arp installed location will be used in later installed files correlation.\r\n            arpInstallLocation = packageMetadata[PackageVersionMetadata::InstalledLocation];\r\n\r\n            // TODO: Use some amount of normalization here to prevent things like versions being in the name from bloating the data\r\n            newEntry.DisplayName = package->GetProperty(PackageVersionProperty::Name).get();\r\n            newEntry.DisplayVersion = packageVersion.ToString();\r\n            if (packageMetadata.count(PackageVersionMetadata::InstalledType))\r\n            {\r\n                newEntry.InstallerType = Manifest::ConvertToInstallerTypeEnum(packageMetadata[PackageVersionMetadata::InstalledType]);\r\n            }\r\n            auto productCodes = package->GetMultiProperty(PackageVersionMultiProperty::ProductCode);\r\n            if (!productCodes.empty())\r\n            {\r\n                newEntry.ProductCode = std::move(productCodes[0]).get();\r\n            }\r\n            newEntry.Publisher = package->GetProperty(PackageVersionProperty::Publisher).get();\r\n            // TODO: Support upgrade code throughout the code base...\r\n\r\n            Manifest::ScopeEnum scope = Manifest::ConvertToScopeEnum(packageMetadata[PackageVersionMetadata::InstalledScope]);\r\n\r\n            // ARP entry icon extraction upon ARP correlation success\r\n            auto icons = ExtractIconFromArpEntry(newEntry.ProductCode, scope);\r\n\r\n            // Add or update the metadata for the installer hash\r\n            auto itr = m_outputMetadata.InstallerMetadataMap.find(m_installerHash);\r\n\r\n            if (itr == m_outputMetadata.InstallerMetadataMap.end())\r\n            {\r\n                // New entry needed\r\n                ProductMetadata::InstallerMetadata newMetadata;\r\n\r\n                newMetadata.SubmissionIdentifier = m_submissionIdentifier;\r\n                newMetadata.AppsAndFeaturesEntries.emplace_back(std::move(newEntry));\r\n\r\n                if (scope != Manifest::ScopeEnum::Unknown)\r\n                {\r\n                    newMetadata.Scope = Manifest::ScopeToString(scope);\r\n                }\r\n\r\n                if (!icons.empty())\r\n                {\r\n                    newMetadata.Icons = std::move(icons);\r\n                }\r\n\r\n                m_outputMetadata.InstallerMetadataMap[m_installerHash] = std::move(newMetadata);\r\n            }\r\n            else\r\n            {\r\n                if (itr->second.Scope.empty())\r\n                {\r\n                    itr->second.Scope = Manifest::ScopeToString(scope);\r\n                }\r\n                // If there is a conflicting scope already present, force it to Unknown\r\n                else if (scope != Manifest::ScopeEnum::Unknown && Manifest::ConvertToScopeEnum(itr->second.Scope) != scope)\r\n                {\r\n                    itr->second.Scope = Manifest::ScopeToString(Manifest::ScopeEnum::Unknown);\r\n                }\r\n\r\n                // We will always use the latest extracted icons upon confliction.\r\n                if (!icons.empty())\r\n                {\r\n                    itr->second.Icons = std::move(icons);\r\n                }\r\n\r\n                // Existing entry for installer hash, add/update the entry\r\n                FilterAndAddToEntries(std::move(newEntry), itr->second.AppsAndFeaturesEntries);\r\n            }\r\n        }\r\n\r\n        // Installation files correlation\r\n        auto installationMetadata = m_installedFilesCorrelation->CorrelateForNewlyInstalled(m_incomingManifest, arpInstallLocation);\r\n\r\n        if (installationMetadata.InstalledFiles.HasData() || !installationMetadata.StartupLinkFiles.empty())\r\n        {\r\n            // Add or update the metadata for the installer hash\r\n            auto itr = m_outputMetadata.InstallerMetadataMap.find(m_installerHash);\r\n\r\n            if (itr == m_outputMetadata.InstallerMetadataMap.end())\r\n            {\r\n                // New entry needed\r\n                ProductMetadata::InstallerMetadata newMetadata;\r\n\r\n                newMetadata.SubmissionIdentifier = m_submissionIdentifier;\r\n\r\n                if (installationMetadata.InstalledFiles.HasData())\r\n                {\r\n                    newMetadata.InstalledFiles = std::move(installationMetadata.InstalledFiles);\r\n                }\r\n                if (!installationMetadata.StartupLinkFiles.empty())\r\n                {\r\n                    newMetadata.StartupLinkFiles = std::move(installationMetadata.StartupLinkFiles);\r\n                }\r\n\r\n                m_outputMetadata.InstallerMetadataMap[m_installerHash] = std::move(newMetadata);\r\n            }\r\n            else\r\n            {\r\n                // Add new or merge with existing entry\r\n                if (installationMetadata.InstalledFiles.HasData())\r\n                {\r\n                    if (!itr->second.InstalledFiles.has_value())\r\n                    {\r\n                        itr->second.InstalledFiles = std::move(installationMetadata.InstalledFiles);\r\n                    }\r\n                    else\r\n                    {\r\n                        MergeInstalledFilesMetadata(*(itr->second.InstalledFiles), installationMetadata.InstalledFiles);\r\n                    }\r\n                }\r\n\r\n                if (!installationMetadata.StartupLinkFiles.empty())\r\n                {\r\n                    if (!itr->second.StartupLinkFiles.has_value())\r\n                    {\r\n                        itr->second.StartupLinkFiles = std::move(installationMetadata.StartupLinkFiles);\r\n                    }\r\n                    else\r\n                    {\r\n                        MergeStartupLinkFilesMetadata(*(itr->second.StartupLinkFiles), installationMetadata.StartupLinkFiles);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        if (correlationResult.Package)\r\n        {\r\n            m_outputStatus = OutputStatus::Success;\r\n        }\r\n        else\r\n        {\r\n            m_outputStatus = OutputStatus::LowConfidence;\r\n        }\r\n\r\n        // Create the diagnostics data, based on the other values from the correlation result.\r\n        DiagnosticFields fields;\r\n\r\n        m_outputDiagnostics[fields.Reason] = AppInstaller::JSON::GetStringValue(correlationResult.Reason);\r\n        m_outputDiagnostics[fields.ChangedEntryCount] = web::json::value::number(static_cast<int64_t>(correlationResult.ChangesToARP));\r\n        m_outputDiagnostics[fields.MatchedEntryCount] = web::json::value::number(static_cast<int64_t>(correlationResult.MatchesInARP));\r\n        m_outputDiagnostics[fields.IntersectionCount] = web::json::value::number(static_cast<int64_t>(correlationResult.CountOfIntersectionOfChangesAndMatches));\r\n\r\n        constexpr size_t MaximumDiagnosticMeasures = 10;\r\n        web::json::value measuresArray = web::json::value::array();\r\n        for (size_t i = 0; i < correlationResult.Measures.size() && i < MaximumDiagnosticMeasures; ++i)\r\n        {\r\n            web::json::value measureValue;\r\n            const auto& measure = correlationResult.Measures[i];\r\n\r\n            measureValue[fields.Value] = web::json::value::number(measure.Measure);\r\n            measureValue[fields.Name] = AppInstaller::JSON::GetStringValue(measure.Package->GetProperty(PackageVersionProperty::Name));\r\n            measureValue[fields.Publisher] = AppInstaller::JSON::GetStringValue(measure.Package->GetProperty(PackageVersionProperty::Publisher));\r\n\r\n            measuresArray[i] = std::move(measureValue);\r\n        }\r\n\r\n        m_outputDiagnostics[fields.CorrelationMeasures] = std::move(measuresArray);\r\n    }\r\n\r\n    void InstallerMetadataCollectionContext::ParseInputJson_1_0(web::json::value& input)\r\n    {\r\n        AICLI_LOG(Repo, Info, << \"Parsing input JSON 1.0 fields\");\r\n\r\n        // Field names\r\n        utility::string_t metadataVersionFieldName = L\"supportedMetadataVersion\";\r\n        utility::string_t metadataFieldName = L\"currentMetadata\";\r\n        utility::string_t submissionDataFieldName = L\"submissionData\";\r\n        utility::string_t submissionIdentifierFieldName = L\"submissionIdentifier\";\r\n        utility::string_t packageDataFieldName = L\"packageData\";\r\n        utility::string_t installerHashFieldName = L\"installerHash\";\r\n        utility::string_t defaultLocaleFieldName = L\"DefaultLocale\";\r\n        utility::string_t localesFieldName = L\"Locales\";\r\n\r\n        // root fields\r\n        m_supportedMetadataVersion = Version{ GetRequiredString(input, metadataVersionFieldName) };\r\n\r\n        auto currentMetadataValue = AppInstaller::JSON::GetJsonValueFromNode(input, metadataFieldName);\r\n        if (currentMetadataValue)\r\n        {\r\n            m_currentMetadata.FromJson(currentMetadataValue.value());\r\n        }\r\n\r\n        // submissionData fields\r\n        auto submissionDataValue = AppInstaller::JSON::GetJsonValueFromNode(input, submissionDataFieldName);\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE, !submissionDataValue);\r\n        m_submissionData = submissionDataValue.value();\r\n\r\n        m_submissionIdentifier = GetRequiredString(m_submissionData, submissionIdentifierFieldName);\r\n\r\n        // packageData fields\r\n        auto packageDataValue = AppInstaller::JSON::GetJsonValueFromNode(input, packageDataFieldName);\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE, !packageDataValue);\r\n\r\n        m_installerHash = GetRequiredString(packageDataValue.value(), installerHashFieldName);\r\n\r\n        // The 1.0 version of input uses the 1.5 version of REST\r\n        JSON::ManifestJSONParser parser{ Version{ \"1.5\" }};\r\n\r\n        {\r\n            auto defaultLocaleValue = AppInstaller::JSON::GetJsonValueFromNode(packageDataValue.value(), defaultLocaleFieldName);\r\n            THROW_HR_IF(APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE, !defaultLocaleValue);\r\n\r\n            auto defaultLocale = parser.DeserializeLocale(defaultLocaleValue.value());\r\n            THROW_HR_IF(APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE,\r\n                !defaultLocale ||\r\n                !defaultLocale->Contains(Manifest::Localization::PackageName) ||\r\n                !defaultLocale->Contains(Manifest::Localization::Publisher));\r\n\r\n            m_incomingManifest.DefaultLocalization = std::move(defaultLocale).value();\r\n\r\n            auto localesArray = AppInstaller::JSON::GetRawJsonArrayFromJsonNode(packageDataValue.value(), localesFieldName);\r\n            if (localesArray)\r\n            {\r\n                for (const auto& locale : localesArray->get())\r\n                {\r\n                    auto localization = parser.DeserializeLocale(locale);\r\n                    if (localization)\r\n                    {\r\n                        m_incomingManifest.Localizations.emplace_back(std::move(localization).value());\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    web::json::value InstallerMetadataCollectionContext::CreateOutputJson_1_0()\r\n    {\r\n        AICLI_LOG(Repo, Info, << \"Setting output JSON 1.0 fields\");\r\n\r\n        OutputFields_1_0 fields;\r\n\r\n        web::json::value result;\r\n\r\n        result[fields.Version] = web::json::value::string(L\"1.0\");\r\n        result[fields.SubmissionData] = m_submissionData;\r\n        result[fields.InstallerHash] = AppInstaller::JSON::GetStringValue(m_installerHash);\r\n\r\n        // Limit output status to 1.0 known values\r\n        OutputStatus statusToUse = OutputStatus::Unknown;\r\n        if (m_outputStatus == OutputStatus::Success || m_outputStatus == OutputStatus::Error || m_outputStatus == OutputStatus::LowConfidence)\r\n        {\r\n            statusToUse = m_outputStatus;\r\n        }\r\n        result[fields.Status] = web::json::value::string(ToString(statusToUse));\r\n\r\n        if (m_outputStatus == OutputStatus::Success)\r\n        {\r\n            result[fields.Metadata] = m_outputMetadata.ToJson(m_supportedMetadataVersion, 0);\r\n        }\r\n\r\n        result[fields.Diagnostics] = m_outputDiagnostics;\r\n\r\n        return result;\r\n    }\r\n\r\n    utility::string_t InstallerMetadataCollectionContext::ToString(OutputStatus status)\r\n    {\r\n        switch (status)\r\n        {\r\n        case OutputStatus::Success: return L\"Success\";\r\n        case OutputStatus::Error: return L\"Error\";\r\n        case OutputStatus::LowConfidence: return L\"LowConfidence\";\r\n        }\r\n\r\n        // For both the status value of Unknown and anything else\r\n        return L\"Unknown\";\r\n    }\r\n\r\n    bool InstallerMetadataCollectionContext::ContainsError() const\r\n    {\r\n        return m_outputStatus == OutputStatus::Error;\r\n    }\r\n\r\n    void InstallerMetadataCollectionContext::CollectErrorDataFromException(std::exception_ptr exception)\r\n    {\r\n        m_outputStatus = OutputStatus::Error;\r\n\r\n        try\r\n        {\r\n            std::rethrow_exception(exception);\r\n        }\r\n        catch (const wil::ResultException& re)\r\n        {\r\n            m_errorHR = re.GetErrorCode();\r\n            m_errorText = GetUserPresentableMessage(re);\r\n        }\r\n        catch (const winrt::hresult_error& hre)\r\n        {\r\n            m_errorHR = hre.code();\r\n            m_errorText = GetUserPresentableMessage(hre);\r\n        }\r\n        catch (const std::exception& e)\r\n        {\r\n            m_errorHR = E_FAIL;\r\n            m_errorText = GetUserPresentableMessage(e);\r\n        }\r\n        catch (...)\r\n        {\r\n            m_errorHR = E_UNEXPECTED;\r\n            m_errorText = \"An unexpected exception type was thrown.\";\r\n        }\r\n    }\r\n\r\n    web::json::value InstallerMetadataCollectionContext::CreateErrorJson_1_0()\r\n    {\r\n        AICLI_LOG(Repo, Info, << \"Setting error JSON 1.0 fields\");\r\n\r\n        OutputFields_1_0 fields;\r\n        DiagnosticFields diagnosticFields;\r\n\r\n        web::json::value result;\r\n\r\n        result[fields.Version] = web::json::value::string(L\"1.0\");\r\n        result[fields.SubmissionData] = m_submissionData;\r\n        result[fields.InstallerHash] = AppInstaller::JSON::GetStringValue(m_installerHash);\r\n        result[fields.Status] = web::json::value::string(ToString(OutputStatus::Error));\r\n        result[fields.Metadata] = web::json::value::null();\r\n\r\n        web::json::value error;\r\n\r\n        error[diagnosticFields.ErrorHR] = web::json::value::number(static_cast<int64_t>(m_errorHR));\r\n        error[diagnosticFields.ErrorText] = AppInstaller::JSON::GetStringValue(m_errorText);\r\n\r\n        result[fields.Diagnostics] = std::move(error);\r\n\r\n        return result;\r\n    }\r\n\r\n    web::json::value InstallerMetadataCollectionContext::Merge_1_0(web::json::value& input, size_t maximumSizeInBytes)\r\n    {\r\n        AICLI_LOG(Repo, Info, << \"Merging 1.0 input metadatas\");\r\n\r\n        utility::string_t metadatasFieldName = L\"metadatas\";\r\n\r\n        auto metadatasValue = AppInstaller::JSON::GetRawJsonArrayFromJsonNode(input, metadatasFieldName);\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE, !metadatasValue);\r\n\r\n        std::vector<ProductMetadata> metadatas;\r\n        for (const auto& value : metadatasValue->get())\r\n        {\r\n            ProductMetadata current;\r\n            current.FromJson(value);\r\n            metadatas.emplace_back(std::move(current));\r\n        }\r\n\r\n        THROW_HR_IF(E_NOT_SET, metadatas.empty());\r\n\r\n        // Require that all merging values use the same submission\r\n        for (const ProductMetadata& metadata : metadatas)\r\n        {\r\n            const std::string& firstSubmission = metadatas[0].InstallerMetadataMap.begin()->second.SubmissionIdentifier;\r\n            const std::string& metadataSubmission = metadata.InstallerMetadataMap.begin()->second.SubmissionIdentifier;\r\n            if (firstSubmission != metadataSubmission)\r\n            {\r\n                AICLI_LOG(Repo, Info, << \"Found submission identifier mismatch: \" << firstSubmission << \" != \" << metadataSubmission);\r\n                THROW_HR(E_NOT_VALID_STATE);\r\n            }\r\n        }\r\n\r\n        // Do the actual merging\r\n        ProductMetadata resultMetadata;\r\n\r\n        // The historical data should be the same across the board, so we can just copy the first one.\r\n        resultMetadata.HistoricalMetadataList = metadatas[0].HistoricalMetadataList;\r\n\r\n        for (const ProductMetadata& metadata : metadatas)\r\n        {\r\n            // Get the minimum and maximum versions from the individual values\r\n            if (resultMetadata.ProductVersionMin.IsEmpty() || metadata.ProductVersionMin < resultMetadata.ProductVersionMin)\r\n            {\r\n                resultMetadata.ProductVersionMin = metadata.ProductVersionMin;\r\n            }\r\n\r\n            if (resultMetadata.ProductVersionMax < metadata.ProductVersionMax)\r\n            {\r\n                resultMetadata.ProductVersionMax = metadata.ProductVersionMax;\r\n            }\r\n\r\n            if (resultMetadata.SchemaVersion < metadata.SchemaVersion)\r\n            {\r\n                resultMetadata.SchemaVersion = metadata.SchemaVersion;\r\n            }\r\n\r\n            for (const auto& installerMetadata : metadata.InstallerMetadataMap)\r\n            {\r\n                auto itr = resultMetadata.InstallerMetadataMap.find(installerMetadata.first);\r\n                if (itr == resultMetadata.InstallerMetadataMap.end())\r\n                {\r\n                    // Installer hash not in the result, so just copy it\r\n                    resultMetadata.InstallerMetadataMap.emplace(installerMetadata);\r\n                }\r\n                else\r\n                {\r\n                    if (itr->second.Scope.empty())\r\n                    {\r\n                        itr->second.Scope = installerMetadata.second.Scope;\r\n                    }\r\n                    else if (!installerMetadata.second.Scope.empty())\r\n                    {\r\n                        // If there is a conflicting scope already present, force it to Unknown\r\n                        if (Manifest::ConvertToScopeEnum(itr->second.Scope) != Manifest::ConvertToScopeEnum(installerMetadata.second.Scope))\r\n                        {\r\n                            itr->second.Scope = Manifest::ScopeToString(Manifest::ScopeEnum::Unknown);\r\n                        }\r\n                    }\r\n\r\n                    // We will always use the latest extracted icons upon confliction.\r\n                    if (!installerMetadata.second.Icons.empty())\r\n                    {\r\n                        itr->second.Icons = installerMetadata.second.Icons;\r\n                    }\r\n\r\n                    if (!itr->second.InstalledFiles.has_value())\r\n                    {\r\n                        itr->second.InstalledFiles = installerMetadata.second.InstalledFiles;\r\n                    }\r\n                    else if (installerMetadata.second.InstalledFiles.has_value())\r\n                    {\r\n                        MergeInstalledFilesMetadata(*(itr->second.InstalledFiles), *(installerMetadata.second.InstalledFiles));\r\n                    }\r\n\r\n                    if (!itr->second.StartupLinkFiles.has_value())\r\n                    {\r\n                        itr->second.StartupLinkFiles = installerMetadata.second.StartupLinkFiles;\r\n                    }\r\n                    else if (installerMetadata.second.StartupLinkFiles.has_value())\r\n                    {\r\n                        MergeStartupLinkFilesMetadata(*(itr->second.StartupLinkFiles), *(installerMetadata.second.StartupLinkFiles));\r\n                    }\r\n\r\n                    // Merge into existing installer data\r\n                    for (const auto& targetEntry : installerMetadata.second.AppsAndFeaturesEntries)\r\n                    {\r\n                        FilterAndAddToEntries(Manifest::AppsAndFeaturesEntry{ targetEntry }, itr->second.AppsAndFeaturesEntries);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        // Convert to JSON\r\n        return resultMetadata.ToJson(resultMetadata.SchemaVersion, maximumSizeInBytes);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/ManifestJSONParser.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/ManifestJSONParser.h\"\r\n#include \"Rest/Schema/1_0/Json/ManifestDeserializer.h\"\r\n#include \"Rest/Schema/1_1/Json/ManifestDeserializer.h\"\r\n#include \"Rest/Schema/1_4/Json/ManifestDeserializer.h\"\r\n#include \"Rest/Schema/1_5/Json/ManifestDeserializer.h\"\r\n#include \"Rest/Schema/1_6/Json/ManifestDeserializer.h\"\r\n#include \"Rest/Schema/1_7/Json/ManifestDeserializer.h\"\r\n#include \"Rest/Schema/1_9/Json/ManifestDeserializer.h\"\r\n#include \"Rest/Schema/1_10/Json/ManifestDeserializer.h\"\r\n#include \"Rest/Schema/1_12/Json/ManifestDeserializer.h\"\r\n\r\nnamespace AppInstaller::Repository::JSON\r\n{\r\n    struct ManifestJSONParser::impl\r\n    {\r\n        // The deserializer.  We only have one lineage (1.0+) right now.\r\n        std::unique_ptr<Rest::Schema::V1_0::Json::ManifestDeserializer> m_deserializer;\r\n    };\r\n\r\n    ManifestJSONParser::ManifestJSONParser(const Utility::Version& responseSchemaVersion)\r\n    {\r\n        const auto& parts = responseSchemaVersion.GetParts();\r\n        THROW_HR_IF(E_INVALIDARG, parts.empty());\r\n\r\n        m_pImpl = std::make_unique<impl>();\r\n\r\n        if (parts[0].Integer == 1)\r\n        {\r\n            if (parts.size() == 1 || parts[1].Integer == 0)\r\n            {\r\n                m_pImpl->m_deserializer = std::make_unique<Rest::Schema::V1_0::Json::ManifestDeserializer>();\r\n            }\r\n            else if (parts.size() > 1 && parts[1].Integer < 4)\r\n            {\r\n                m_pImpl->m_deserializer = std::make_unique<Rest::Schema::V1_1::Json::ManifestDeserializer>();\r\n            }\r\n            else if (parts.size() > 1 && parts[1].Integer < 5)\r\n            {\r\n                m_pImpl->m_deserializer = std::make_unique<Rest::Schema::V1_4::Json::ManifestDeserializer>();\r\n            }\r\n            else if (parts.size() > 1 && parts[1].Integer < 6)\r\n            {\r\n                m_pImpl->m_deserializer = std::make_unique<Rest::Schema::V1_5::Json::ManifestDeserializer>();\r\n            }\r\n            else if (parts.size() > 1 && parts[1].Integer < 7)\r\n            {\r\n                m_pImpl->m_deserializer = std::make_unique<Rest::Schema::V1_6::Json::ManifestDeserializer>();\r\n            }\r\n            else if (parts.size() > 1 && parts[1].Integer < 9)\r\n            {\r\n                m_pImpl->m_deserializer = std::make_unique<Rest::Schema::V1_7::Json::ManifestDeserializer>();\r\n            }\r\n            else if (parts.size() > 1 && parts[1].Integer < 10)\r\n            {\r\n                m_pImpl->m_deserializer = std::make_unique<Rest::Schema::V1_9::Json::ManifestDeserializer>();\r\n            }\r\n            else if (parts.size() > 1 && parts[1].Integer < 12)\r\n            {\r\n                m_pImpl->m_deserializer = std::make_unique<Rest::Schema::V1_10::Json::ManifestDeserializer>();\r\n            }\r\n            else\r\n            {\r\n                m_pImpl->m_deserializer = std::make_unique<Rest::Schema::V1_12::Json::ManifestDeserializer>();\r\n            }\r\n        }\r\n        else\r\n        {\r\n            THROW_HR(HRESULT_FROM_WIN32(ERROR_UNSUPPORTED_TYPE));\r\n        }\r\n    }\r\n\r\n    ManifestJSONParser::ManifestJSONParser(ManifestJSONParser&&) noexcept = default;\r\n    ManifestJSONParser& ManifestJSONParser::operator=(ManifestJSONParser&&) noexcept = default;\r\n\r\n    ManifestJSONParser::~ManifestJSONParser() = default;\r\n\r\n    std::vector<Manifest::Manifest> ManifestJSONParser::Deserialize(const web::json::value& response) const\r\n    {\r\n        return m_pImpl->m_deserializer->Deserialize(response);\r\n    }\r\n\r\n    std::vector<Manifest::Manifest> ManifestJSONParser::DeserializeData(const web::json::value& data) const\r\n    {\r\n        return m_pImpl->m_deserializer->DeserializeData(data);\r\n    }\r\n\r\n    std::vector<Manifest::AppsAndFeaturesEntry> ManifestJSONParser::DeserializeAppsAndFeaturesEntries(const web::json::array& data) const\r\n    {\r\n        return m_pImpl->m_deserializer->DeserializeAppsAndFeaturesEntries(data);\r\n    }\r\n\r\n    std::optional<Manifest::ManifestLocalization> ManifestJSONParser::DeserializeLocale(const web::json::value& locale) const\r\n    {\r\n        return m_pImpl->m_deserializer->DeserializeLocale(locale);\r\n    }\r\n\r\n    std::optional<Manifest::InstallationMetadataInfo> ManifestJSONParser::DeserializeInstallationMetadata(const web::json::value& installationMetadata) const\r\n    {\r\n        return m_pImpl->m_deserializer->DeserializeInstallationMetadata(installationMetadata);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/MatchCriteriaResolver.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n#include \"pch.h\"\n#include \"MatchCriteriaResolver.h\"\n#include <AppInstallerStrings.h>\n\nnamespace AppInstaller::Repository\n{\n    namespace\n    {\n        using ValueMatchFunction = bool (*)(const Utility::NormalizedString&, const Utility::NormalizedString&);\n\n        bool ValueMatchFunction_AlwaysFalse(const Utility::NormalizedString&, const Utility::NormalizedString&)\n        {\n            return false;\n        }\n\n        bool ValueMatchFunction_Exact(const Utility::NormalizedString& a, const Utility::NormalizedString& b)\n        {\n            return a == b;\n        }\n\n        bool ValueMatchFunction_CaseInsensitive(const Utility::NormalizedString& a, const Utility::NormalizedString& b)\n        {\n            return Utility::ICUCaseInsensitiveEquals(a, b);\n        }\n\n        bool ValueMatchFunction_StartsWith(const Utility::NormalizedString& a, const Utility::NormalizedString& b)\n        {\n            return Utility::ICUCaseInsensitiveStartsWith(a, b);\n        }\n\n        bool ValueMatchFunction_Substring(const Utility::NormalizedString& a, const Utility::NormalizedString& b)\n        {\n            return Utility::ContainsSubstring(FoldCase(a), FoldCase(b));\n        }\n\n        ValueMatchFunction GetMatchTypeFunction(MatchType matchType)\n        {\n            switch (matchType)\n            {\n            case MatchType::Exact:\n                return ValueMatchFunction_Exact;\n            case MatchType::CaseInsensitive:\n                return ValueMatchFunction_CaseInsensitive;\n            case MatchType::StartsWith:\n                return ValueMatchFunction_StartsWith;\n            case MatchType::Substring:\n                return ValueMatchFunction_Substring;\n            case MatchType::Fuzzy:\n            case MatchType::FuzzySubstring:\n            case MatchType::Wildcard:\n            default:\n                return ValueMatchFunction_AlwaysFalse;\n            }\n        }\n\n        PackageVersionProperty GetPackageVersionPropertyFor(PackageMatchField field)\n        {\n            switch (field)\n            {\n            case PackageMatchField::Id:\n                return PackageVersionProperty::Id;\n            case PackageMatchField::Name:\n                return PackageVersionProperty::Name;\n            case PackageMatchField::Moniker:\n                return PackageVersionProperty::Moniker;\n            default:\n                THROW_HR(E_UNEXPECTED);\n            }\n        }\n\n        PackageVersionMultiProperty GetPackageVersionMultiPropertyFor(PackageMatchField field)\n        {\n            switch (field)\n            {\n            case PackageMatchField::Command:\n                return PackageVersionMultiProperty::Command;\n            case PackageMatchField::Tag:\n                return PackageVersionMultiProperty::Tag;\n            case PackageMatchField::PackageFamilyName:\n                return PackageVersionMultiProperty::PackageFamilyName;\n            case PackageMatchField::ProductCode:\n                return PackageVersionMultiProperty::ProductCode;\n            case PackageMatchField::UpgradeCode:\n                return PackageVersionMultiProperty::UpgradeCode;\n            default:\n                THROW_HR(E_UNEXPECTED);\n            }\n        }\n\r\n        // Gets the best match type for the given field value and required minimum match type.\n        std::optional<MatchType> GetBestMatchType(const RequestMatch& request, MatchType mustBeBetterThanMatchType, const Utility::NormalizedString& value)\n        {\r\n            if (request.Value.empty())\r\n            {\n                return std::nullopt;\n            }\r\n\r\n            for (auto matchType : { MatchType::Exact, MatchType::CaseInsensitive, MatchType::StartsWith, MatchType::Substring })\r\n            {\n                if (matchType >= mustBeBetterThanMatchType)\r\n                {\r\n                    break;\n                }\r\n\n                auto matchFunction = GetMatchTypeFunction(matchType);\n\n                if (matchFunction(value, request.Value))\r\n                {\n                    return matchType;\n                }\n            }\r\n\n            return std::nullopt;\n        }\n\r\n        // Gets the best match type for the given field value and required minimum match type.\n        std::optional<MatchType> GetBestMatchType(const SearchRequest& request, PackageMatchField field, MatchType mustBeBetterThanMatchType, const Utility::NormalizedString& value)\n        {\r\n            std::optional<MatchType> result;\r\n\r\n            if (request.Query)\r\n            {\n                result = GetBestMatchType(request.Query.value(), mustBeBetterThanMatchType, value);\r\n\r\n                if (result)\r\n                {\n                    mustBeBetterThanMatchType = result.value();\n                }\n            }\r\n\r\n            for (const auto& filter : request.Filters)\r\n            {\n                if (result.value_or(MatchType::Wildcard) == MatchType::Exact)\r\n                {\n                    break;\n                }\r\n\r\n                if (filter.Field == field)\r\n                {\r\n                    std::optional<MatchType> filterResult = GetBestMatchType(filter, mustBeBetterThanMatchType, value);\r\n\r\n                    if (filterResult)\r\n                    {\r\n                        result = std::move(filterResult);\n                        mustBeBetterThanMatchType = result.value();\n                    }\r\n                }\n            }\r\n\r\n            return result;\n        }\r\n\r\n        // Gets the best match and updates the result if it should be updated.\r\n        // Returns true to indicate that an exact match has been found.\r\n        bool UpdatePackageMatchFilterCheck(const SearchRequest& request, PackageMatchField field, PackageMatchFilter& result, const Utility::LocIndString& propertyValue)\r\n        {\r\n            Utility::NormalizedString normalizedValue = propertyValue.get();\r\n            auto bestMatch = GetBestMatchType(request, field, result.Type, normalizedValue);\r\n\r\n            if (bestMatch && bestMatch.value() < result.Type)\r\n            {\n                result.Type = bestMatch.value();\r\n                result.Field = field;\r\n                result.Value = std::move(normalizedValue);\n            }\r\n\r\n            return MatchType::Exact == result.Type;\n        }\n    }\n\n    PackageMatchFilter FindBestMatchCriteria(const SearchRequest& request, const IPackageVersion* packageVersion)\n    {\n        PackageMatchFilter result{ PackageMatchField::Unknown, MatchType::Wildcard };\n\n        // Single value fields\n        for (auto field : { PackageMatchField::Id, PackageMatchField::Name, PackageMatchField::Moniker })\n        {\n            auto propertyValue = packageVersion->GetProperty(GetPackageVersionPropertyFor(field));\n            if (propertyValue.empty())\n            {\n                continue;\n            }\r\n\r\n            if (UpdatePackageMatchFilterCheck(request, field, result, propertyValue))\r\n            {\n                break;\n            }\n        }\n\n        // Multi-value fields\n        for (auto field : { PackageMatchField::Command, PackageMatchField::Tag, PackageMatchField::PackageFamilyName,\n            PackageMatchField::ProductCode, PackageMatchField::UpgradeCode })\n        {\n            if (MatchType::Exact == result.Type)\r\n            {\n                break;\n            }\r\n\n            auto propertyValues = packageVersion->GetMultiProperty(GetPackageVersionMultiPropertyFor(field));\n            if (propertyValues.empty())\n            {\n                continue;\n            }\r\n\r\n            for (const auto& propertyValue : propertyValues)\r\n            {\r\n                if (UpdatePackageMatchFilterCheck(request, field, result, propertyValue))\r\n                {\n                    break;\n                }\r\n            }\n        }\r\n\r\n        return result;\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/MatchCriteriaResolver.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"Public/winget/RepositorySearch.h\"\n\nnamespace AppInstaller::Repository\n{\n    // Finds the highest rated match criteria for the package based on the search request,\n    PackageMatchFilter FindBestMatchCriteria(const SearchRequest& request, const IPackageVersion* packageVersion);\n}\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/ARPHelper.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ARPHelper.h\"\r\n#include \"winget/PortableARPEntry.h\"\r\n\r\nnamespace AppInstaller::Repository::Microsoft\r\n{\r\n    using namespace AppInstaller::Registry::Portable;\r\n\r\n    namespace\r\n    {\r\n        // \"Unpacks\" a GUID in the format used by the UpgradesCode registry key into the usual format.\r\n        // Returns empty if it is not a valid GUID\r\n        std::optional<std::string> TryUnpackUpgradeCodeGuid(std::string_view packed)\r\n        {\r\n            // A GUID is made up of 4 parts:\r\n            //   - Part 1 is made up of one 4 byte block\r\n            //   - Parts 2 and 3 are made up of one 2 byte block\r\n            //   - Part 4 is made up of eight 1 byte blocks\r\n            //\r\n            // The GUID strings we have in the manifests represent all of this in hex in order,\r\n            // with dashes between each part, and after the second byte of Part 4.\r\n            // The \"packed\" GUIDs in the registry place the blocks in the same order,\r\n            // without dashes and with opposite endian-ness.\r\n            //\r\n            // For example\r\n            //   ARP:          {FECAFEB5-8D0E-4AE4-8FA0-745BAA835C35}\r\n            //                FECAFEB5 8D0E 4AE4 8F A0 74 5B AA 83 5C 35\r\n            //                 Part 1   P2   P3  <------ Part 4 ------->\r\n            //                5BEFACEF E0D8 4EA4 F8 0A 47 B5 AA 38 C5 53\r\n            //   UpgradeCode:     5BEFACEFE0D84EA4F80A47B5AA38C553\r\n            //\r\n            // The conversion can be done by mapping each location in the packed string\r\n            // to the appropriate location in the unpacked string.\r\n            constexpr size_t PackedLength = 32;\r\n            if (packed.length() != PackedLength || !std::all_of(packed.begin(), packed.end(), isxdigit))\r\n            {\r\n                return {};\r\n            }\r\n\r\n            // PositionMapping[i] is the position to which the i-th char is mapped\r\n            // I.e., unpacked[ PositionMapping[i] ] = packed[i]\r\n            constexpr size_t PositionMapping[PackedLength] =\r\n            {\r\n                8,7,6,5,4,3,2,1,\r\n                13,12,11,10,\r\n                18,17,16,15,\r\n                21,20, 23,22,\r\n                26,25, 28,27, 30,29, 32,31, 34,33, 36,35,\r\n            };\r\n\r\n            std::string unpacked(\"{00000000-0000-0000-0000-000000000000}\");\r\n            for (size_t i = 0; i < PackedLength; ++i)\r\n            {\r\n                unpacked[PositionMapping[i]] = packed[i];\r\n            }\r\n\r\n            return unpacked;\r\n        }\r\n\r\n        // Gets a mapping from ProductCode to UpgradeCode for MSI packages.\r\n        std::map<std::string, std::string> GetUpgradeCodes()\r\n        {\r\n            // The UpgradeCode is not stored in the ARP registry keys, so we have to get it separately.\r\n            // We could use MsiGetProductProperty or MsiGetProperty from the MSI API to query it,\r\n            // but it is very slow.\r\n            //\r\n            // The UpgradeCode is also stored in the registry under\r\n            //   HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UpgradeCodes\r\n            // (Note that this key is not documented, so it is possible that it will change but very unlikely...)\r\n            //\r\n            // Under 'UpgradeCodes' there is one key for each upgrade code, and each upgrade code key\r\n            // contains the product code as a value. All the upgrade codes and product codes are GUIDs,\r\n            // but represented in an unusual way - see TryUnpackUpgradeCodeGuid()\r\n\r\n            AICLI_LOG(Repo, Info, << \"Reading MSI UpgradeCodes\");\r\n            std::map<std::string, std::string> upgradeCodes;\r\n\r\n            try\r\n            {\r\n                // There is no UpgradeCodes key on the x86 view of the registry\r\n                Registry::Key upgradeCodesKey = Registry::Key::OpenIfExists(HKEY_LOCAL_MACHINE, \"SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Installer\\\\UpgradeCodes\", 0, KEY_READ | KEY_WOW64_64KEY);\r\n\r\n                if (upgradeCodesKey)\r\n                {\r\n                    for (const auto& upgradeCodeKeyRef : upgradeCodesKey)\r\n                    {\r\n                        std::string keyName;\r\n\r\n                        try\r\n                        {\r\n                            keyName = upgradeCodeKeyRef.Name();\r\n                            auto upgradeCode = TryUnpackUpgradeCodeGuid(keyName);\r\n                            if (upgradeCode)\r\n                            {\r\n                                auto upgradeCodeKey = upgradeCodeKeyRef.Open();\r\n                                for (const auto& productCodeValue : upgradeCodeKey.Values())\r\n                                {\r\n                                    auto productCode = TryUnpackUpgradeCodeGuid(productCodeValue.Name());\r\n                                    if (productCode)\r\n                                    {\r\n                                        upgradeCodes[*productCode] = *upgradeCode;\r\n                                    }\r\n                                }\r\n                            }\r\n                        }\r\n                        CATCH_LOG_MSG(\"Failed to read upgrade code: %hs\", keyName.c_str());\r\n                    }\r\n                }\r\n            }\r\n            CATCH_LOG_MSG(\"Failed to read upgrade codes.\");\r\n\r\n            return upgradeCodes;\r\n        }\r\n    }\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n    using GetARPKeyFunc = std::function<Registry::Key(Manifest::ScopeEnum, Utility::Architecture)>;\r\n    static GetARPKeyFunc s_GetARPKey_Override;\r\n\r\n    void SetGetARPKeyOverride(GetARPKeyFunc value)\r\n    {\r\n        s_GetARPKey_Override = value;\r\n    }\r\n#endif\r\n\r\n    Registry::Key ARPHelper::GetARPKey(Manifest::ScopeEnum scope, Utility::Architecture architecture) const\r\n    {\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        if (s_GetARPKey_Override)\r\n        {\r\n            return s_GetARPKey_Override(scope, architecture);\r\n        }\r\n#endif\r\n\r\n        HKEY rootKey = NULL;\r\n\r\n        switch (scope)\r\n        {\r\n        case Manifest::ScopeEnum::User:\r\n            rootKey = HKEY_CURRENT_USER;\r\n            break;\r\n        case Manifest::ScopeEnum::Machine:\r\n            rootKey = HKEY_LOCAL_MACHINE;\r\n            break;\r\n        default:\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n\r\n        bool isValid = false;\r\n        REGSAM access = KEY_READ;\r\n\r\n        switch (Utility::GetSystemArchitecture())\r\n        {\r\n        case Utility::Architecture::X86:\r\n            switch (architecture)\r\n            {\r\n            case Utility::Architecture::X86:\r\n                isValid = true;\r\n                break;\r\n            }\r\n            break;\r\n        case Utility::Architecture::X64:\r\n            switch (architecture)\r\n            {\r\n            case Utility::Architecture::X86:\r\n                if (scope == Manifest::ScopeEnum::Machine)\r\n                {\r\n                    access |= KEY_WOW64_32KEY;\r\n                    isValid = true;\r\n                }\r\n                break;\r\n            case Utility::Architecture::X64:\r\n                access |= KEY_WOW64_64KEY;\r\n                isValid = true;\r\n                break;\r\n            }\r\n            break;\r\n        case Utility::Architecture::Arm:\r\n            switch (architecture)\r\n            {\r\n            case Utility::Architecture::Arm:\r\n                isValid = true;\r\n                break;\r\n            }\r\n            break;\r\n        case Utility::Architecture::Arm64:\r\n            switch (architecture)\r\n            {\r\n            case Utility::Architecture::X86:\r\n                if (scope == Manifest::ScopeEnum::Machine)\r\n                {\r\n#ifdef _ARM_\r\n                    // Not accessible if this is an ARM process\r\n                    AICLI_LOG(Repo, Warning, << \"Cannot enumerate x86 machine ARP entries when current process is ARM\");\r\n#else\r\n                    access |= KEY_WOW64_32KEY;\r\n                    isValid = true;\r\n#endif\r\n                }\r\n                break;\r\n            case Utility::Architecture::Arm64:\r\n                access |= KEY_WOW64_64KEY;\r\n                isValid = true;\r\n                break;\r\n            }\r\n            break;\r\n        }\r\n\r\n        if (isValid)\r\n        {\r\n            return Registry::Key::OpenIfExists(rootKey, SubKeyPath, 0, access);\r\n        }\r\n        else\r\n        {\r\n            return {};\r\n        }\r\n    }\r\n\r\n    Registry::Key ARPHelper::FindARPEntry(const std::string& productCode, Manifest::ScopeEnum scope) const\r\n    {\r\n        if (productCode.empty())\r\n        {\r\n            return {};\r\n        }\r\n\r\n        std::vector<Manifest::ScopeEnum> scopesToSearch;\r\n        if (scope == Manifest::ScopeEnum::Unknown)\r\n        {\r\n            scopesToSearch = { Manifest::ScopeEnum::User, Manifest::ScopeEnum::Machine };\r\n        }\r\n        else\r\n        {\r\n            scopesToSearch = { scope };\r\n        }\r\n\r\n        for (auto scopeToSearch : scopesToSearch)\r\n        {\r\n            for (auto architecture : Utility::GetApplicableArchitectures())\r\n            {\r\n                Registry::Key arpRootKey = GetARPKey(scopeToSearch, architecture);\r\n                if (arpRootKey)\r\n                {\r\n                    for (const auto& entry : arpRootKey)\r\n                    {\r\n                        if (Utility::CaseInsensitiveEquals(productCode, entry.Name()))\r\n                        {\r\n                            return entry.Open();\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        return {};\r\n    }\r\n\r\n    bool ARPHelper::GetBoolValue(const Registry::Key& arpKey, const std::wstring& name)\r\n    {\r\n        auto value = arpKey[name];\r\n        return (value && value->GetType() == Registry::Value::Type::DWord && value->GetValue<Registry::Value::Type::DWord>());\r\n    }\r\n\r\n    std::string ARPHelper::GetStringValue(const Registry::Key& arpKey, const std::wstring& name)\r\n    {\r\n        auto value = arpKey[name];\r\n        if (value && value->GetType() == Registry::Value::Type::String)\r\n        {\r\n            return value->GetValue<Registry::Value::Type::String>();\r\n        }\r\n\r\n        return {};\r\n    }\r\n\r\n    std::string ARPHelper::DetermineVersion(const Registry::Key& arpKey) const\r\n    {\r\n        // First check DisplayVersion for a complete version string\r\n        auto displayVersion = arpKey[DisplayVersion];\r\n        if (displayVersion && displayVersion->GetType() == Registry::Value::Type::String)\r\n        {\r\n            std::string result = displayVersion->GetValue<Registry::Value::Type::String>();\r\n            if (!result.empty())\r\n            {\r\n                return result;\r\n            }\r\n        }\r\n\r\n        // Next attempt VersionMajor.VersionMinor, then MajorVersion.MinorVersion\r\n        for (const auto& names : { std::make_pair(std::ref(VersionMajor), std::ref(VersionMinor)), std::make_pair(std::ref(MajorVersion), std::ref(MinorVersion)) })\r\n        {\r\n            auto majorVersion = arpKey[names.first];\r\n            auto minorVersion = arpKey[names.second];\r\n            if (majorVersion || minorVersion)\r\n            {\r\n                uint32_t majorVersionInt = 0;\r\n                uint32_t minorVersionInt = 0;\r\n\r\n                if (majorVersion && majorVersion->GetType() == Registry::Value::Type::DWord)\r\n                {\r\n                    majorVersionInt = majorVersion->GetValue<Registry::Value::Type::DWord>();\r\n                }\r\n\r\n                if (minorVersion && minorVersion->GetType() == Registry::Value::Type::DWord)\r\n                {\r\n                    minorVersionInt = minorVersion->GetValue<Registry::Value::Type::DWord>();\r\n                }\r\n\r\n                if (majorVersionInt || minorVersionInt)\r\n                {\r\n                    std::ostringstream strstr;\r\n                    strstr << majorVersionInt << '.' << minorVersionInt;\r\n                    return strstr.str();\r\n                }\r\n            }\r\n        }\r\n\r\n        // Finally attempt to turn the Version DWORD into a version string\r\n        auto version = arpKey[Version];\r\n        if (version && version->GetType() == Registry::Value::Type::DWord)\r\n        {\r\n            uint32_t versionInt = version->GetValue<Registry::Value::Type::DWord>();\r\n            if (versionInt)\r\n            {\r\n                std::ostringstream strstr;\r\n                strstr << ((versionInt & 0xFF000000) >> 24) << '.' << ((versionInt & 0x00FF0000) >> 16) << '.' << (versionInt & 0x0000FFFF);\r\n                return strstr.str();\r\n            }\r\n        }\r\n\r\n        return Utility::Version::CreateUnknown().ToString();\r\n    }\r\n\r\n    void ARPHelper::AddMetadataIfPresent(const Registry::Key& key, const std::wstring& name, SQLiteIndex& index, SQLiteIndex::IdType manifestId, PackageVersionMetadata metadata) const\r\n    {\r\n        auto value = key[name];\r\n        if (value)\r\n        {\r\n            std::string valueString;\r\n\r\n            if (value->GetType() == Registry::Value::Type::String)\r\n            {\r\n                valueString = value->GetValue<Registry::Value::Type::String>();\r\n            }\r\n            else if (value->GetType() == Registry::Value::Type::ExpandString)\r\n            {\r\n                valueString = value->GetValue<Registry::Value::Type::ExpandString>();\r\n            }\r\n            else if (value->GetType() == Registry::Value::Type::DWord)\r\n            {\r\n                DWORD dwordValue = value->GetValue<Registry::Value::Type::DWord>();\r\n                if (name == Language)\r\n                {\r\n                    valueString = Locale::LocaleIdToBcp47Tag(dwordValue);\r\n                }\r\n                else\r\n                {\r\n                    std::ostringstream strstr;\r\n                    strstr << dwordValue;\r\n                    valueString = strstr.str();\r\n                }\r\n            }\r\n\r\n            if (!valueString.empty())\r\n            {\r\n                index.SetMetadataByManifestId(manifestId, metadata, valueString);\r\n            }\r\n        }\r\n    }\r\n\r\n    void ARPHelper::PopulateIndexFromARP(SQLiteIndex& index, Manifest::ScopeEnum scope) const\r\n    {\r\n        auto upgradeCodes = GetUpgradeCodes();\r\n\r\n        for (auto architecture : Utility::GetApplicableArchitectures())\r\n        {\r\n            Registry::Key arpRootKey = GetARPKey(scope, architecture);\r\n\r\n            if (arpRootKey)\r\n            {\r\n                PopulateIndexFromKey(index, arpRootKey, Manifest::ScopeToString(scope), Utility::ToString(architecture), upgradeCodes);\r\n            }\r\n        }\r\n    }\r\n\r\n    void ARPHelper::PopulateIndexFromKey(SQLiteIndex& index, const Registry::Key& key, std::string_view scope, std::string_view architecture, const std::map<std::string, std::string>& upgradeCodes) const\r\n    {\r\n        AICLI_LOG(Repo, Verbose, << \"Examining ARP entries for \" << scope << \" | \" << architecture);\r\n\r\n        for (const auto& arpEntry : key)\r\n        {\r\n            std::string productCode;\r\n\r\n            try\r\n            {\r\n                productCode = arpEntry.Name();\r\n\r\n                Manifest::Manifest manifest;\r\n                manifest.DefaultLocalization.Add<Manifest::Localization::Tags>({ \"ARP\" });\r\n\r\n                // Construct a unique name for this entry\r\n                const char separator = '\\\\';\r\n\r\n                std::ostringstream stream;\r\n                stream << \"ARP\" << separator << scope << separator << architecture << separator << productCode;\r\n\r\n                manifest.Id = stream.str();\r\n\r\n                manifest.Installers.emplace_back();\r\n                // TODO: This likely needs some cleanup applied, as it looks like INNO tends to append an \"_is#\"\r\n                //       that might vary across machines/installs. There may be other things we want to clean up as well,\r\n                //       like trimming spaces at the ends, or removing the version string from the product code\r\n                //       if it is present.\r\n                manifest.Installers[0].ProductCode = productCode;\r\n\r\n                Registry::Key arpKey = arpEntry.Open();\r\n\r\n                // Ignore entries that are listed as SystemComponent\r\n                if (GetBoolValue(arpKey, SystemComponent))\r\n                {\r\n                    AICLI_LOG(Repo, Verbose, << \"Skipping \" << productCode << \" because it is a SystemComponent\");\r\n                    continue;\r\n                }\r\n\r\n                // If no name is provided, ignore this entry\r\n                auto displayName = arpKey[DisplayName];\r\n                if (!displayName || displayName->GetType() != Registry::Value::Type::String)\r\n                {\r\n                    AICLI_LOG(Repo, Verbose, << \"Skipping \" << productCode << \" because DisplayName is not a REG_SZ value\");\r\n                    continue;\r\n                }\r\n                auto displayNameValue = displayName->GetValue<Registry::Value::Type::String>();\r\n                if (displayNameValue.empty())\r\n                {\r\n                    AICLI_LOG(Repo, Verbose, << \"Skipping \" << productCode << \" because DisplayName is empty\");\r\n                    continue;\r\n                }\r\n\r\n                manifest.DefaultLocalization.Add<Manifest::Localization::PackageName>(displayNameValue);\r\n                // Add DisplayName to ARP entries too\r\n                // This is to help normalized publisher and name correlation where ARP DisplayName matching\r\n                // will be getting improved in future iterations.\r\n                manifest.Installers[0].AppsAndFeaturesEntries.emplace_back();\r\n                manifest.Installers[0].AppsAndFeaturesEntries[0].DisplayName = displayNameValue;\r\n\r\n                // If no version can be determined, ignore this entry\r\n                manifest.Version = DetermineVersion(arpKey);\r\n                if (manifest.Version.empty())\r\n                {\r\n                    AICLI_LOG(Repo, Verbose, << \"Skipping \" << productCode << \" because a version could not be determined\");\r\n                    continue;\r\n                }\r\n\r\n                auto publisher = arpKey[Publisher];\r\n                if (publisher && publisher->GetType() == Registry::Value::Type::String)\r\n                {\r\n                    manifest.DefaultLocalization.Add<Manifest::Localization::Publisher>(publisher->GetValue<Registry::Value::Type::String>());\r\n\r\n                    // If Publisher is set, change the Id using name normalization\r\n                    // TODO: Figure out how to actually make this work since there are often instances of the same\r\n                    // data in x64 and x86 entries that will collide.\r\n                    //auto normalizedName = index.NormalizeName(\r\n                    //    manifest.DefaultLocalization.Get<Manifest::Localization::PackageName>(),\r\n                    //    manifest.DefaultLocalization.Get<Manifest::Localization::Publisher>());\r\n                    //manifest.Id = normalizedName.Publisher() + '.' + normalizedName.Name();\r\n                }\r\n\r\n                // Pick up WindowsInstaller to determine if this is an MSI install.\r\n                // TODO: Could also determine Inno (and maybe other types) through detecting other keys here.\r\n                auto installedType = Manifest::InstallerTypeEnum::Exe;\r\n\r\n                if (GetBoolValue(arpKey, WindowsInstaller))\r\n                {\r\n                    installedType = Manifest::InstallerTypeEnum::Msi;\r\n\r\n                    // If this is an MSI, look up the UpgradeCode\r\n                    auto upgradeCodeItr = upgradeCodes.find(productCode);\r\n                    if (upgradeCodeItr != upgradeCodes.end())\r\n                    {\r\n                        manifest.Installers[0].AppsAndFeaturesEntries[0].UpgradeCode = upgradeCodeItr->second;\r\n                    }\r\n                }\r\n\r\n                // TODO: If we want to keep the constructed manifest around to allow for `show` type commands\r\n                //       against installed packages, we should use URLInfoAbout/HelpLink for the Homepage.\r\n\r\n                // TODO: Determine the best way to handle duplicates; sometimes the same package will be listed under\r\n                //       both x64 and x86 locations for ARP.\r\n                //       For now, we will attempt to insert and catch.\r\n                std::optional<SQLiteIndex::IdType> manifestIdOpt;\r\n\r\n                try\r\n                {\r\n                    // Use the ProductCode as a unique key for the path\r\n                    manifestIdOpt = index.AddManifest(manifest);\r\n                }\r\n                catch (...)\r\n                {\r\n                    // Ignore errors if they occur, they are most likely a duplicate value\r\n                }\r\n\r\n                if (!manifestIdOpt)\r\n                {\r\n                    AICLI_LOG(Repo, Warning,\r\n                        << \"Ignoring duplicate ARP entry \" << scope << '|' << architecture << '|' << productCode << \" [\" << manifest.DefaultLocalization.Get<Manifest::Localization::PackageName>() << \"]\");\r\n                    continue;\r\n                }\r\n\r\n                SQLiteIndex::IdType manifestId = manifestIdOpt.value();\r\n\r\n                // Pass scope along to metadata.\r\n                index.SetMetadataByManifestId(manifestId, PackageVersionMetadata::InstalledScope, scope);\r\n\r\n                // TODO: Pass along architecture, although there are cases where it is not clear what architecture the package\r\n                //       is from it's ARP location, despite it very clearly being a specific architecture. And note that user\r\n                //       scope does not have separate ARP locations, so every architecture would appear as native.\r\n\r\n                // Publisher is needed for certain scenarios but we don't store it from the manifest\r\n                if (manifest.DefaultLocalization.Contains(Manifest::Localization::Publisher))\r\n                {\r\n                    index.SetMetadataByManifestId(\r\n                        manifestId, PackageVersionMetadata::Publisher,\r\n                        manifest.DefaultLocalization.Get<Manifest::Localization::Publisher>());\r\n                }\r\n\r\n                // Pick up InstallLocation when upgrade supports remove/install to enable this location\r\n                // to survive across the removal.\r\n                AddMetadataIfPresent(arpKey, InstallLocation, index, manifestId, PackageVersionMetadata::InstalledLocation);\r\n\r\n                // Pick up UninstallString and QuietUninstallString for uninstall.\r\n                AddMetadataIfPresent(arpKey, UninstallString, index, manifestId, PackageVersionMetadata::StandardUninstallCommand);\r\n                AddMetadataIfPresent(arpKey, QuietUninstallString, index, manifestId, PackageVersionMetadata::SilentUninstallCommand);\r\n\r\n                // Pick up ModifyPath for repair.\r\n                AddMetadataIfPresent(arpKey, ModifyPath, index, manifestId, PackageVersionMetadata::StandardModifyCommand);\r\n                AddMetadataIfPresent(arpKey, NoModify, index, manifestId, PackageVersionMetadata::NoModify);\r\n                AddMetadataIfPresent(arpKey, NoRepair, index, manifestId, PackageVersionMetadata::NoRepair);\r\n\r\n                // Pick up Language to enable proper selection of language for upgrade.\r\n                AddMetadataIfPresent(arpKey, Language, index, manifestId, PackageVersionMetadata::InstalledLocale);\r\n\r\n                if (Manifest::ConvertToInstallerTypeEnum(GetStringValue(arpKey, std::wstring{ ToString(PortableValueName::WinGetInstallerType) })) == Manifest::InstallerTypeEnum::Portable)\r\n                {\r\n                    // Portable uninstall requires the installed architecture for locating the entry in the registry.\r\n                    index.SetMetadataByManifestId(manifestId, PackageVersionMetadata::InstalledArchitecture, architecture);\r\n                    installedType = Manifest::InstallerTypeEnum::Portable;\r\n                }\r\n\r\n                index.SetMetadataByManifestId(manifestId, PackageVersionMetadata::InstalledType, Manifest::InstallerTypeToString(installedType));\r\n            }\r\n            catch (...)\r\n            {\r\n                AICLI_LOG(Repo, Warning, << \"Failed to read ARP entry, ignoring it: \" << scope << '|' << architecture << '|' << productCode);\r\n                LOG_CAUGHT_EXCEPTION();\r\n            }\r\n        }\r\n    }\r\n\r\n    std::vector<wil::unique_registry_watcher> ARPHelper::CreateRegistryWatchers(Manifest::ScopeEnum scope, std::function<void(Manifest::ScopeEnum, Utility::Architecture, wil::RegistryChangeKind)> callback)\r\n    {\r\n        std::vector<wil::unique_registry_watcher> result;\r\n\r\n        auto addToResult = [&](Manifest::ScopeEnum scopeToUse)\r\n            {\r\n                for (auto architecture : Utility::GetApplicableArchitectures())\r\n                {\r\n                    Registry::Key arpRootKey = GetARPKey(scopeToUse, architecture);\r\n\r\n                    if (arpRootKey)\r\n                    {\r\n                        result.emplace_back(wil::make_registry_watcher(arpRootKey, L\"\", true, [scopeToUse, architecture, callback](wil::RegistryChangeKind change) { callback(scopeToUse, architecture, change); }));\r\n                    }\r\n                }\r\n            };\r\n\r\n        if (scope == Manifest::ScopeEnum::Unknown)\r\n        {\r\n            addToResult(Manifest::ScopeEnum::User);\r\n            addToResult(Manifest::ScopeEnum::Machine);\r\n        }\r\n        else\r\n        {\r\n            addToResult(scope);\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/ARPHelper.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/SQLiteIndex.h\"\r\n#include <AppInstallerArchitecture.h>\r\n#include <winget/Registry.h>\r\n#include <winget/ManifestInstaller.h>\r\n#include <wil/registry.h>\r\n#include <wil/resource.h>\r\n\r\n#include <string>\r\n#include <vector>\r\n\r\nnamespace AppInstaller::Repository::Microsoft\r\n{\r\n    // A helper to find the various locations that contain ARP (Add/Remove Programs) entries.\r\n    struct ARPHelper\r\n    {\r\n        // See https://docs.microsoft.com/en-us/windows/win32/msi/uninstall-registry-key for details.\r\n        const std::wstring SubKeyPath{ L\"SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Uninstall\" };\r\n\r\n        // REG_SZ\r\n        const std::wstring DisplayName{ L\"DisplayName\" };\r\n        // REG_SZ\r\n        const std::wstring Publisher{ L\"Publisher\" };\r\n        // REG_SZ\r\n        const std::wstring DisplayVersion{ L\"DisplayVersion\" };\r\n        // REG_DWORD (ex. 0xMMmmbbbb, M[ajor], m[inor], b[uild])\r\n        const std::wstring Version{ L\"Version\" };\r\n        // REG_DWORD\r\n        const std::wstring VersionMajor{ L\"VersionMajor\" };\r\n        // REG_DWORD\r\n        const std::wstring VersionMinor{ L\"VersionMinor\" };\r\n        // REG_DWORD\r\n        const std::wstring MajorVersion{ L\"MajorVersion\" };\r\n        // REG_DWORD\r\n        const std::wstring MinorVersion{ L\"MinorVersion\" };\r\n        // REG_SZ\r\n        const std::wstring URLInfoAbout{ L\"URLInfoAbout\" };\r\n        // REG_SZ\r\n        const std::wstring HelpLink{ L\"HelpLink\" };\r\n        // REG_SZ\r\n        const std::wstring InstallLocation{ L\"InstallLocation\" };\r\n        // REG_DWORD (ex. 1033 [en-us])\r\n        const std::wstring Language{ L\"Language\" };\r\n        // REG_SZ (ex. \"english\")\r\n        const std::wstring InnoSetupLanguage{ L\"Inno Setup: Language\" };\r\n        // REG_EXPAND_SZ\r\n        const std::wstring UninstallString{ L\"UninstallString\" };\r\n        // REG_EXPAND_SZ\r\n        const std::wstring QuietUninstallString{ L\"QuietUninstallString\" };\r\n        // REG_DWORD (bool, true indicates MSI)\r\n        const std::wstring WindowsInstaller{ L\"WindowsInstaller\" };\r\n        // REG_DWORD (bool)\r\n        const std::wstring SystemComponent{ L\"SystemComponent\" };\r\n        // REG_SZ\r\n        const std::wstring DisplayIcon{ L\"DisplayIcon\" };\r\n        // REG_DWORD\r\n        const std::wstring NoModify{ L\"NoModify\" };\r\n        // REG_DWORD\r\n        const std::wstring NoRepair{ L\"NoRepair\" };\r\n        // REG_SZ\r\n        const std::wstring ModifyPath{ L\"ModifyPath\" };\r\n\r\n        // Gets the registry key associated with the given scope and architecture on this platform.\r\n        // May return an empty key if there is no valid location (bad combination or not found).\r\n        Registry::Key GetARPKey(Manifest::ScopeEnum scope, Utility::Architecture architecture) const;\r\n\r\n        // Gets the arp registry key associated with the given scope and product code.\r\n        // May return an empty key if not found.\r\n        Registry::Key FindARPEntry(const std::string& productCode, AppInstaller::Manifest::ScopeEnum scope = AppInstaller::Manifest::ScopeEnum::Unknown) const;\r\n\r\n        // Returns true IFF the value exists and contains a non-zero DWORD.\r\n        static bool GetBoolValue(const Registry::Key& arpKey, const std::wstring& name);\r\n\r\n        // Returns the string value if it exists.\r\n        static std::string GetStringValue(const Registry::Key& arpKey, const std::wstring& name);\r\n\r\n        // Determines the version from an ARP entry.\r\n        // The priority is:\r\n        //  DisplayVersion\r\n        //  Version\r\n        //  MajorVersion, MinorVersion\r\n        std::string DetermineVersion(const Registry::Key& arpKey) const;\r\n\r\n        // Reads a value and adds it to the metadata if it exists.\r\n        void AddMetadataIfPresent(const Registry::Key& key, const std::wstring& name, SQLiteIndex& index, SQLiteIndex::IdType manifestId, PackageVersionMetadata metadata) const;\r\n\r\n        // Populates the index with the ARP entries from the given scope (machine/user).\r\n        // Handles all of the architectures for the given scope.\r\n        void PopulateIndexFromARP(SQLiteIndex& index, Manifest::ScopeEnum scope) const;\r\n\r\n        // Populates the index with the ARP entries from the given key.\r\n        // This entry point is primarily to allow unit tests to operate of arbitrary keys;\r\n        // product code should use PopulateIndexFromARP.\r\n        void PopulateIndexFromKey(SQLiteIndex& index, const Registry::Key& key, std::string_view scope, std::string_view architecture, const std::map<std::string, std::string>& upgradeCodes = {}) const;\r\n\r\n        // Creates registry watchers for the given scope\r\n        std::vector<wil::unique_registry_watcher> CreateRegistryWatchers(Manifest::ScopeEnum scope, std::function<void(Manifest::ScopeEnum, Utility::Architecture, wil::RegistryChangeKind)> callback);\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/CheckpointDatabase.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"Public/winget/CheckpointDatabase.h\"\n#include \"Microsoft/Schema/ICheckpointDatabase.h\"\n#include \"Microsoft/Schema/Checkpoint_1_0/CheckpointDatabaseInterface.h\"\n\nnamespace AppInstaller::Repository::Microsoft\n{\n    namespace\n    {\n        // Creates the ICheckpointDatabase interface object for the given version.\n        std::unique_ptr<Schema::ICheckpointDatabase> CreateICheckpointDatabase(const SQLite::Version& version)\n        {\n            if (version == SQLite::Version{ 1, 0 } ||\n                version.MajorVersion == 1 ||\n                version.IsLatest())\n            {\n                return std::make_unique<Schema::Checkpoint_V1_0::CheckpointDatabaseInterface>();\n            }\n\n            THROW_HR(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED));\n        }\n    }\n\n    CheckpointDatabase::CheckpointDatabase(CheckpointDatabase&&) = default;\n    CheckpointDatabase& CheckpointDatabase::operator=(CheckpointDatabase&&) = default;\n\n    std::shared_ptr<CheckpointDatabase> CheckpointDatabase::CreateNew(const std::string& filePath, SQLite::Version version)\n    {\n        AICLI_LOG(Repo, Info, << \"Creating new Checkpoint database with version [\" << version << \"] at '\" << filePath << \"'\");\n        CheckpointDatabase result{ filePath, version };\n\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(result.m_dbconn, \"CheckpointDatabase_CreateNew\");\n\n        // Use calculated version, as incoming version could be 'latest'\n        result.m_version.SetSchemaVersion(result.m_dbconn);\n\n        result.m_interface->CreateTables(result.m_dbconn);\n\n        result.SetLastWriteTime();\n\n        savepoint.Commit();\n\n        return std::make_shared<CheckpointDatabase>(std::move(result));\n    }\n\n    std::shared_ptr<CheckpointDatabase> CheckpointDatabase::Open(const std::string& filePath, SQLite::SQLiteStorageBase::OpenDisposition disposition, Utility::ManagedFile&& indexFile)\n    {\n        return std::make_shared<CheckpointDatabase>(CheckpointDatabase{ filePath, disposition, std::move(indexFile) });\n    }\n\n    bool CheckpointDatabase::IsEmpty()\n    {\n        return m_interface->IsEmpty(m_dbconn);\n    }\n\n    CheckpointDatabase::IdType CheckpointDatabase::AddCheckpoint(std::string_view checkpointName)\n    {\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\n        AICLI_LOG(Repo, Verbose, << \"Adding checkpoint [\" << checkpointName << \"]\");\n\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(m_dbconn, \"CheckpointDatabase_addCheckpoint\");\n\n        IdType result = m_interface->AddCheckpoint(m_dbconn, checkpointName);\n\n        SetLastWriteTime();\n        savepoint.Commit();\n        return result;\n    }\n\n    std::vector<CheckpointDatabase::IdType> CheckpointDatabase::GetCheckpointIds()\n    {\n        return m_interface->GetCheckpointIds(m_dbconn);\n    }\n\n    bool CheckpointDatabase::HasDataField(IdType checkpointId, int type, const std::string& name)\n    {\n        return m_interface->GetCheckpointDataFieldValues(m_dbconn, checkpointId, type, name).has_value();\n    }\n\n    std::vector<int> CheckpointDatabase::GetDataTypes(IdType checkpointId)\n    {\n        return m_interface->GetCheckpointDataTypes(m_dbconn, checkpointId);\n    }\n\n    std::vector<std::string> CheckpointDatabase::GetDataFieldNames(IdType checkpointId, int dataType)\n    {\n        return m_interface->GetCheckpointDataFields(m_dbconn, checkpointId, dataType);\n    }\n\n    void CheckpointDatabase::SetDataValue(IdType checkpointId, int dataType, const std::string& field, const std::vector<std::string>& values)\n    {\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\n        AICLI_LOG(Repo, Verbose, << \"Setting checkpoint data [\" << dataType << \"]\");\n\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(m_dbconn, \"CheckpointDatabase_setDataValue\");\n\n        m_interface->SetCheckpointDataValues(m_dbconn, checkpointId, dataType, field, values);\n\n        SetLastWriteTime();\n        savepoint.Commit();\n    }\n\n    void CheckpointDatabase::UpdateDataValue(IdType checkpointId, int dataType, const std::string& field, const std::vector<std::string>& values)\n    {\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\n        AICLI_LOG(Repo, Verbose, << \"Updating checkpoint data [\" << dataType << \"]\");\n\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(m_dbconn, \"CheckpointDatabase_updateDataValue\");\n\n        m_interface->RemoveCheckpointDataType(m_dbconn, checkpointId, dataType);\n        m_interface->SetCheckpointDataValues(m_dbconn, checkpointId, dataType, field, values);\n\n        SetLastWriteTime();\n        savepoint.Commit();\n    }\n\n    void CheckpointDatabase::RemoveDataType(IdType checkpointId, int dataType)\n    {\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\n        AICLI_LOG(Repo, Verbose, << \"Removing checkpoint data [\" << dataType << \"]\");\n\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(m_dbconn, \"CheckpointDatabase_removeDataValue\");\n\n        m_interface->RemoveCheckpointDataType(m_dbconn, checkpointId, dataType);\n\n        SetLastWriteTime();\n        savepoint.Commit();\n    }\n\n    std::string CheckpointDatabase::GetDataFieldSingleValue(IdType checkpointId, int dataType, const std::string& field)\n    {\n        const auto& values = m_interface->GetCheckpointDataFieldValues(m_dbconn, checkpointId, dataType, field);\n\n        if (!values.has_value())\n        {\n            THROW_HR(E_UNEXPECTED);\n        }\n\n        return values.value()[0];\n    }\n\n    std::vector<std::string> CheckpointDatabase::GetDataFieldMultiValue(IdType checkpointId, int dataType, const std::string& field)\n    {\n        const auto& values = m_interface->GetCheckpointDataFieldValues(m_dbconn, checkpointId, dataType, field);\n\n        if (!values.has_value())\n        {\n            THROW_HR(E_UNEXPECTED);\n        }\n\n        return values.value();\n    }\n\n\n    CheckpointDatabase::CheckpointDatabase(const std::string& target, SQLiteStorageBase::OpenDisposition disposition, Utility::ManagedFile&& indexFile) :\n        SQLiteStorageBase(target, disposition, std::move(indexFile))\n    {\n        AICLI_LOG(Repo, Info, << \"Opened Checkpoint Index with version [\" << m_version << \"], last write [\" << GetLastWriteTime() << \"]\");\n        m_interface = CreateICheckpointDatabase(m_version);\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX, disposition == SQLiteStorageBase::OpenDisposition::ReadWrite && m_version != m_interface->GetVersion());\n    }\n\n    CheckpointDatabase::CheckpointDatabase(const std::string& target, SQLite::Version version) : SQLiteStorageBase(target, version)\n    {\n        m_interface = CreateICheckpointDatabase(m_version);\n        m_version = m_interface->GetVersion();\n    }\n}"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/ConfigurableTestSourceFactory.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Microsoft/ConfigurableTestSourceFactory.h\"\r\n\r\n#include <json/json.h>\r\n\r\nusing namespace std::string_literals;\r\nusing namespace std::string_view_literals;\r\nusing namespace AppInstaller::Utility::literals;\r\n\r\nnamespace AppInstaller::Repository::Microsoft\r\n{\r\n    namespace\r\n    {\r\n        // The configuration defined for a source.\r\n        // This can be added to as new scenarios are needed for testing.\r\n        struct TestSourceConfiguration\r\n        {\r\n            TestSourceConfiguration(const std::string& config)\r\n            {\r\n                Json::Value root;\r\n                Json::CharReaderBuilder builder;\r\n                const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());\r\n\r\n                std::string error;\r\n\r\n                if (reader->parse(config.c_str(), config.c_str() + config.size(), &root, &error))\r\n                {\r\n                    // TODO: If this becomes more dynamic, refactor the UserSettings code to make it easier to leverage here\r\n                    ParseHR(root, \".OpenHR\", OpenHR);\r\n                    ParseHR(root, \".SearchHR\", SearchHR);\r\n                    ParseBool(root, \".ContainsPackage\", ContainsPackage);\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(Repo, Error, << \"Error parsing test source config: \" << error);\r\n                    THROW_HR_MSG(E_INVALIDARG, \"%hs\", error.c_str());\r\n                }\r\n            }\r\n\r\n            // The HR to throw on Factory::Create (if FAILED)\r\n            HRESULT OpenHR = S_OK;\r\n\r\n            // The HR to throw on Source::Search (if FAILED)\r\n            HRESULT SearchHR = S_OK;\r\n\r\n            // If a result should be returned by search.\r\n            bool ContainsPackage = false;\r\n\r\n        private:\r\n            static void ParseHR(const Json::Value& root, const std::string& path, HRESULT& hr)\r\n            {\r\n                const Json::Path jsonPath(path);\r\n                Json::Value node = jsonPath.resolve(root);\r\n                if (!node.isNull())\r\n                {\r\n                    if (node.isIntegral())\r\n                    {\r\n                        hr = node.asInt();\r\n                    }\r\n                    else if (node.isString())\r\n                    {\r\n                        hr = static_cast<HRESULT>(std::strtoll(node.asString().c_str(), nullptr, 0));\r\n                    }\r\n                }\r\n            }\r\n\r\n            static void ParseBool(const Json::Value& root, const std::string& path, bool& value)\r\n            {\r\n                const Json::Path jsonPath(path);\r\n                Json::Value node = jsonPath.resolve(root);\r\n                if (!node.isNull())\r\n                {\r\n                    if (node.isBool())\r\n                    {\r\n                        value = node.asBool();\r\n                    }\r\n                }\r\n            }\r\n        };\r\n\r\n        // A test package that contains test data.\r\n        struct TestPackage : public std::enable_shared_from_this<TestPackage>, public ICompositePackage, public IPackage, public IPackageVersion\r\n        {\r\n            TestPackage(std::shared_ptr<ISource> source) : m_source(std::move(source)) {}\r\n\r\n            Utility::LocIndString GetProperty(PackageProperty property) const override\r\n            {\r\n                switch (property)\r\n                {\r\n                case PackageProperty::Id:\r\n                    return \"ConfigurableTestSource Package Identifier\"_lis;\r\n                case PackageProperty::Name:\r\n                    return \"ConfigurableTestSource Package Name\"_lis;\r\n                }\r\n\r\n                return {};\r\n            }\r\n\r\n            std::shared_ptr<IPackage> GetInstalled() override\r\n            {\r\n                return nullptr;\r\n            }\r\n\r\n            std::vector<std::shared_ptr<IPackage>> GetAvailable() override\r\n            {\r\n                return { shared_from_this() };\r\n            }\r\n\r\n            std::vector<Utility::LocIndString> GetMultiProperty(PackageMultiProperty) const override\r\n            {\r\n                return {};\r\n            }\r\n\r\n            Source GetSource() const override\r\n            {\r\n                return { m_source };\r\n            }\r\n\r\n            bool IsSame(const IPackage*) const override\r\n            {\r\n                return false;\r\n            }\r\n\r\n            const void* CastTo(IPackageType) const override\r\n            {\r\n                return nullptr;\r\n            }\r\n\r\n            std::vector<PackageVersionKey> GetVersionKeys() const override\r\n            {\r\n                return { {} };\r\n            }\r\n\r\n            std::shared_ptr<IPackageVersion> GetVersion(const PackageVersionKey&) const override\r\n            {\r\n                return std::static_pointer_cast<IPackageVersion>(NonConstSharedFromThis());\r\n            }\r\n\r\n            std::shared_ptr<IPackageVersion> GetLatestVersion() const override\r\n            {\r\n                return std::static_pointer_cast<IPackageVersion>(NonConstSharedFromThis());\r\n            }\r\n\r\n            Utility::LocIndString GetProperty(PackageVersionProperty property) const override\r\n            {\r\n                switch (property)\r\n                {\r\n                case PackageVersionProperty::Id:\r\n                    return \"ConfigurableTestSource Package Version Identifier\"_lis;\r\n                case PackageVersionProperty::Name:\r\n                    return \"ConfigurableTestSource Package Version Name\"_lis;\r\n                case PackageVersionProperty::SourceIdentifier:\r\n                    return \"ConfigurableTestSource Package Version Source Identifier\"_lis;\r\n                case PackageVersionProperty::SourceName:\r\n                    return \"ConfigurableTestSource Package Version Source Name\"_lis;\r\n                case PackageVersionProperty::Version:\r\n                    return \"ConfigurableTestSource Package Version Version\"_lis;\r\n                case PackageVersionProperty::Channel:\r\n                    return \"ConfigurableTestSource Package Version Channel\"_lis;\r\n                case PackageVersionProperty::RelativePath:\r\n                    return \"ConfigurableTestSource Package Version Relative Path\"_lis;\r\n                case PackageVersionProperty::ManifestSHA256Hash:\r\n                    return \"ConfigurableTestSource Package Version Manifest SHA 256 Hash\"_lis;\r\n                case PackageVersionProperty::Publisher:\r\n                    return \"ConfigurableTestSource Package Version Publisher\"_lis;\r\n                case PackageVersionProperty::ArpMinVersion:\r\n                    return \"ConfigurableTestSource Package Version Arp Min Version\"_lis;\r\n                case PackageVersionProperty::ArpMaxVersion:\r\n                    return \"ConfigurableTestSource Package Version Arp Max Version\"_lis;\r\n                case PackageVersionProperty::Moniker:\r\n                    return \"ConfigurableTestSource Package Version Moniker\"_lis;\r\n                }\r\n\r\n                return {};\r\n            }\r\n\r\n            std::vector<Utility::LocIndString> GetMultiProperty(PackageVersionMultiProperty) const override\r\n            {\r\n                return {};\r\n            }\r\n\r\n            Manifest::Manifest GetManifest() override\r\n            {\r\n                Manifest::Manifest result;\r\n\r\n                result.Id = \"ConfigurableTestSource Manifest Identifier\";\r\n                result.CurrentLocalization.Add<Manifest::Localization::PackageName>(\"ConfigurableTestSource Manifest Name\");\r\n\r\n                return result;\r\n            }\r\n\r\n            Metadata GetMetadata() const override\r\n            {\r\n                return {};\r\n            }\r\n\r\n        private:\r\n            std::shared_ptr<TestPackage> NonConstSharedFromThis() const\r\n            {\r\n                return const_cast<TestPackage*>(this)->shared_from_this();\r\n            }\r\n\r\n            std::shared_ptr<ISource> m_source;\r\n        };\r\n\r\n        // The configurable source itself.\r\n        struct ConfigurableTestSource : public std::enable_shared_from_this<ConfigurableTestSource>, public ISource\r\n        {\r\n            static constexpr ISourceType SourceType = ISourceType::ConfigurableTestSource;\r\n\r\n            ConfigurableTestSource(const SourceDetails& details, const TestSourceConfiguration& config) :\r\n                m_details(details), m_config(config) {}\r\n\r\n            const SourceDetails& GetDetails() const override { return m_details; }\r\n\r\n            const std::string& GetIdentifier() const override { return m_details.Identifier; }\r\n\r\n            SearchResult Search(const SearchRequest&) const override\r\n            {\r\n                THROW_IF_FAILED(m_config.SearchHR);\r\n\r\n                SearchResult result;\r\n\r\n                if (m_config.ContainsPackage)\r\n                {\r\n                    std::shared_ptr<TestPackage> package = std::make_shared<TestPackage>(NonConstSharedFromThis());\r\n                    PackageMatchFilter packageFilter{ {}, {} };\r\n\r\n                    result.Matches.emplace_back(std::move(package), std::move(packageFilter));\r\n                }\r\n\r\n                return result;\r\n            }\r\n\r\n            void* CastTo(ISourceType type) override\r\n            {\r\n                if (type == SourceType)\r\n                {\r\n                    return this;\r\n                }\r\n\r\n                return nullptr;\r\n            }\r\n\r\n        private:\r\n            std::shared_ptr<ConfigurableTestSource> NonConstSharedFromThis() const\r\n            {\r\n                return const_cast<ConfigurableTestSource*>(this)->shared_from_this();\r\n            }\r\n\r\n            SourceDetails m_details;\r\n            TestSourceConfiguration m_config;\r\n        };\r\n\r\n        struct ConfigurableTestSourceReference : public ISourceReference\r\n        {\r\n            ConfigurableTestSourceReference(const SourceDetails& details) : m_details(details)\r\n            {\r\n                m_details.Identifier = \"*ConfigurableTestSource\";\r\n            }\r\n\r\n            std::string GetIdentifier() override { return m_details.Identifier; }\r\n\r\n            SourceDetails& GetDetails() override { return m_details; };\r\n\r\n            bool SetCustomHeader(std::optional<std::string>) override { return true; }\r\n\r\n            std::shared_ptr<ISource> Open(IProgressCallback&) override\r\n            {\r\n                // enables `source add` with FAILED(OpenHR)\r\n                TestSourceConfiguration config{ m_details.Arg };\r\n                THROW_IF_FAILED(config.OpenHR);\r\n                return std::make_shared<ConfigurableTestSource>(m_details, config);\r\n            }\r\n\r\n        private:\r\n            SourceDetails m_details;\r\n        };\r\n\r\n        // The actual factory implementation.\r\n        struct ConfigurableTestSourceFactoryImpl : public ISourceFactory\r\n        {\r\n            std::string_view TypeName() const override final\r\n            {\r\n                return ConfigurableTestSourceFactory::Type();\r\n            }\r\n\r\n            std::shared_ptr<ISourceReference> Create(const SourceDetails& details) override final\r\n            {\r\n                return std::make_shared<ConfigurableTestSourceReference>(details);\r\n            }\r\n\r\n            bool Add(SourceDetails& details, IProgressCallback&) override final\r\n            {\r\n                // Attempt to parse the configuration so that we can fail at the appropriate point\r\n                TestSourceConfiguration config{ details.Arg };\r\n                return true;\r\n            }\r\n\r\n            bool Update(const SourceDetails&, IProgressCallback&) override final\r\n            {\r\n                return true;\r\n            }\r\n\r\n            bool BackgroundUpdate(const SourceDetails&, IProgressCallback&) override final\r\n            {\r\n                return true;\r\n            }\r\n\r\n            bool Remove(const SourceDetails&, IProgressCallback&) override final\r\n            {\r\n                return true;\r\n            }\r\n        };\r\n    }\r\n\r\n    std::unique_ptr<ISourceFactory> ConfigurableTestSourceFactory::Create()\r\n    {\r\n        return std::make_unique<ConfigurableTestSourceFactoryImpl>();\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/ConfigurableTestSourceFactory.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ISource.h\"\r\n#include \"SourceFactory.h\"\r\n\r\n#include <string_view>\r\n\r\nnamespace AppInstaller::Repository::Microsoft\r\n{\r\n    using namespace std::string_view_literals;\r\n\r\n    // A source for use in manual or E2E tests that can be configured to fail as needed.\r\n    struct ConfigurableTestSourceFactory\r\n    {\r\n        // Get the type string for this source.\r\n        static constexpr std::string_view Type()\r\n        {\r\n            using namespace std::string_view_literals;\r\n            return \"Microsoft.Test.Configurable\"sv;\r\n        }\r\n\r\n        // Creates a source factory for this type.\r\n        static std::unique_ptr<ISourceFactory> Create();\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/FontHelper.cpp",
    "content": "\n// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"FontHelper.h\"\n#include <winget/Fonts.h>\nusing namespace AppInstaller::Utility;\n\nnamespace AppInstaller::Repository::Microsoft\n{\n#ifndef AICLI_DISABLE_TEST_HOOKS\n    using GetFontRegistryRootFunc = std::function<Registry::Key(Manifest::ScopeEnum)>;\n    static GetFontRegistryRootFunc s_FontRegistryRoot_Override;\n\n    void TestHook_SetGetFontRegistryRootFunc(GetFontRegistryRootFunc value)\n    {\n        s_FontRegistryRoot_Override = value;\n    }\n#endif\n\n    void FontHelper::PopulateIndex(SQLiteIndex& index, Manifest::ScopeEnum scope) const\n    {\n        const auto& fontPackages = AppInstaller::Fonts::GetInstalledFontPackages(scope);\n        for (const auto& fontPackage : fontPackages)\n        {\n            try\n            {\n                // Font packages are collections of fonts; the PackageId is treated as the productCode.\n                std::string productCode = ConvertToUTF8(fontPackage.PackageId);\n\n                Manifest::Manifest manifest;\n                manifest.DefaultLocalization.Add<Manifest::Localization::Tags>({ \"Font\" });\n                manifest.Id = ConvertToUTF8(fontPackage.PackageIdentifier);\n                manifest.Version = ConvertToUTF8(fontPackage.PackageVersion);\n                manifest.Moniker = productCode;\n                manifest.Installers.emplace_back();\n                manifest.Installers[0].ProductCode = productCode;\n\n                // We don't know the package name from the install information. The best we can do is reuse the id.\n                manifest.DefaultLocalization.Add<Manifest::Localization::PackageName>(productCode);\n\n                std::optional<SQLiteIndex::IdType> manifestIdOpt;\n                try\n                {\n                    // Use the ProductCode as a unique key for the path\n                    manifestIdOpt = index.AddManifest(manifest);\n                }\n                catch (...)\n                {\n                    // Same package may show up under User and Machine install.\n                    // Ignore errors if they occur, they are most likely a duplicate value\n                }\n\n                if (!manifestIdOpt)\n                {\n                    AICLI_LOG(Repo, Warning,\n                        << \"Ignoring duplicate font entry \" << scope << '|' << manifest.Id << '|' << manifest.Version);\n                    continue;\n                }\n\n                SQLiteIndex::IdType manifestId = manifestIdOpt.value();\n\n                index.SetMetadataByManifestId(manifestId, PackageVersionMetadata::InstalledScope, Manifest::ScopeToString(scope));\n                index.SetMetadataByManifestId(manifestId, PackageVersionMetadata::InstalledType, Manifest::InstallerTypeToString(Manifest::InstallerTypeEnum::Font));                \n            }\n            catch (...)\n            {\n                AICLI_LOG(Repo, Warning, << \"Failed to process font package entry, ignoring it: \" << scope << '|' << ConvertToUTF8(fontPackage.PackageId));\n                LOG_CAUGHT_EXCEPTION();\n            }\n        }\n    }\n\n    void FontHelper::AddRegistryWatchers(Manifest::ScopeEnum scope, std::function<void(Manifest::ScopeEnum, wil::RegistryChangeKind)> callback, std::vector<wil::unique_registry_watcher>& watchers)\n    {\n        auto addToWatchers = [&](Manifest::ScopeEnum scopeToUse)\n            {\n                auto hive = scopeToUse == Manifest::ScopeEnum::Machine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;\n                auto root = Registry::Key::OpenIfExists(hive, AppInstaller::Fonts::GetFontRegistryRoot(), 0UL, KEY_READ);\n\n#ifndef AICLI_DISABLE_TEST_HOOKS\n                if (s_FontRegistryRoot_Override)\n                {\n                    root = s_FontRegistryRoot_Override(scopeToUse);\n                }\n#endif\n                if (root)\n                {\n                    watchers.emplace_back(wil::make_registry_watcher(root, L\"\", true, [scopeToUse, callback](wil::RegistryChangeKind change) { callback(scopeToUse, change); }));\n                }\n            };\n\n        if (scope == Manifest::ScopeEnum::Unknown)\n        {\n            addToWatchers(Manifest::ScopeEnum::User);\n            addToWatchers(Manifest::ScopeEnum::Machine);\n        }\n        else\n        {\n            addToWatchers(scope);\n        }\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/FontHelper.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"Microsoft/SQLiteIndex.h\"\n#include <winget/Registry.h>\n#include <winget/ManifestInstaller.h>\n#include <winget/Fonts.h>\n#include <wil/registry.h>\n#include <wil/resource.h>\n\n#include <string>\n#include <vector>\n\nnamespace AppInstaller::Repository::Microsoft\n{\n    // A helper to find the various locations that find installed font information.\n    struct FontHelper\n    {\n        void PopulateIndex(SQLiteIndex& index, Manifest::ScopeEnum scope) const;\n\n        void AddRegistryWatchers(Manifest::ScopeEnum scope, std::function<void(Manifest::ScopeEnum, wil::RegistryChangeKind)> callback, std::vector<wil::unique_registry_watcher>& watchers);\n    };\n}\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/PinningIndex.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"PinningIndex.h\"\r\n#include <winget/SQLiteStorageBase.h>\r\n#include \"Schema/Pinning_1_0/PinningIndexInterface.h\"\r\n\r\nnamespace AppInstaller::Repository::Microsoft\r\n{\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n    std::optional<std::filesystem::path> s_PinningIndexOverride{};\r\n    void TestHook_SetPinningIndex_Override(std::optional<std::filesystem::path>&& indexPath)\r\n    {\r\n        s_PinningIndexOverride = std::move(indexPath);\r\n    }\r\n#endif\r\n\r\n    namespace\r\n    {\r\n        std::filesystem::path GetPinningDatabasePath()\r\n        {\r\n            const auto DefaultPath = Runtime::GetPathTo(Runtime::PathName::LocalState) / \"pinning.db\";\r\n\r\n            return\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n                s_PinningIndexOverride.has_value() ? s_PinningIndexOverride.value() :\r\n#endif\r\n                DefaultPath;\r\n        }\r\n\r\n        std::shared_ptr<PinningIndex> OpenDatabaseIfExists(const std::filesystem::path& path, SQLite::SQLiteStorageBase::OpenDisposition openDisposition)\r\n        {\r\n            AICLI_LOG(Repo, Info, << \"Attempting to open pinning database: \" << path);\r\n\r\n            try\r\n            {\r\n                if (std::filesystem::exists(path))\r\n                {\r\n                    if (std::filesystem::is_regular_file(path))\r\n                    {\r\n                        try\r\n                        {\r\n                            AICLI_LOG(Repo, Info, << \"... opening existing pinning database\");\r\n                            return std::make_shared<PinningIndex>(PinningIndex::Open(path.u8string(), openDisposition));\r\n                        }\r\n                        CATCH_LOG();\r\n\r\n                        AICLI_LOG(Repo, Info, << \"... deleting bad pinning database file\");\r\n                        std::filesystem::remove_all(path);\r\n                    }\r\n                    else\r\n                    {\r\n                        AICLI_LOG(Repo, Info, << \"... deleting pinning database path that is a directory\");\r\n                        std::filesystem::remove_all(path);\r\n                    }\r\n                }\r\n            }\r\n            CATCH_LOG();\r\n\r\n            return {};\r\n        }\r\n    }\r\n\r\n    PinningIndex PinningIndex::CreateNew(const std::string& filePath, SQLite::Version version)\r\n    {\r\n        AICLI_LOG(Repo, Info, << \"Creating new Pinning Index with version [\" << version << \"] at '\" << filePath << \"'\");\r\n        PinningIndex result{ filePath, version };\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(result.m_dbconn, \"pinningindex_createnew\");\r\n\r\n        // Use calculated version, as incoming version could be 'latest'\r\n        result.m_version.SetSchemaVersion(result.m_dbconn);\r\n\r\n        result.m_interface->CreateTables(result.m_dbconn);\r\n\r\n        result.SetLastWriteTime();\r\n\r\n        savepoint.Commit();\r\n\r\n        return result;\r\n    }\r\n\r\n    std::shared_ptr<PinningIndex> PinningIndex::OpenIfExists(OpenDisposition openDisposition)\r\n    {\r\n        return OpenDatabaseIfExists(GetPinningDatabasePath(), openDisposition);\r\n    }\r\n\r\n    std::shared_ptr<PinningIndex> PinningIndex::OpenOrCreateDefault(OpenDisposition openDisposition)\r\n    {\r\n        const auto databasePath = GetPinningDatabasePath();\r\n\r\n        std::shared_ptr<PinningIndex> result = OpenDatabaseIfExists(databasePath, openDisposition);\r\n\r\n        if (!result)\r\n        {\r\n            AICLI_LOG(Repo, Info, << \"... creating pinning database\");\r\n\r\n            try\r\n            {\r\n                result = std::make_shared<PinningIndex>(PinningIndex::CreateNew(databasePath.u8string()));\r\n            }\r\n            CATCH_LOG();\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    PinningIndex::IdType PinningIndex::AddPin(const Pinning::Pin& pin)\r\n    {\r\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\r\n        AICLI_LOG(Repo, Verbose, << \"Adding Pin \" << pin.ToString());\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(m_dbconn, \"pinningindex_addpin\");\r\n\r\n        IdType result = m_interface->AddPin(m_dbconn, pin);\r\n\r\n        SetLastWriteTime();\r\n\r\n        savepoint.Commit();\r\n\r\n        return result;\r\n    }\r\n\r\n    bool PinningIndex::UpdatePin(const Pinning::Pin& pin)\r\n    {\r\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\r\n        AICLI_LOG(Repo, Verbose, << \"Updating Pin \" << pin.ToString());\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(m_dbconn, \"pinningindex_updatepin\");\r\n\r\n        bool result = m_interface->UpdatePin(m_dbconn, pin).first;\r\n\r\n        if (result)\r\n        {\r\n            SetLastWriteTime();\r\n            savepoint.Commit();\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    void PinningIndex::AddOrUpdatePin(const Pinning::Pin& pin)\r\n    {\r\n        auto existingPin = GetPin(pin.GetKey());\r\n        if (existingPin.has_value())\r\n        {\r\n            UpdatePin(pin);\r\n        }\r\n        else\r\n        {\r\n            AddPin(pin);\r\n        }\r\n    }\r\n\r\n    void PinningIndex::RemovePin(const Pinning::PinKey& pinKey)\r\n    {\r\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\r\n        AICLI_LOG(Repo, Verbose, << \"Removing Pin \" << pinKey.ToString());\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(m_dbconn, \"pinningIndex_removePin\");\r\n\r\n        m_interface->RemovePin(m_dbconn, pinKey);\r\n\r\n        SetLastWriteTime();\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    std::optional<Pinning::Pin> PinningIndex::GetPin(const Pinning::PinKey& pinKey)\r\n    {\r\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\r\n        return m_interface->GetPin(m_dbconn, pinKey);\r\n    }\r\n\r\n    std::vector<Pinning::Pin> PinningIndex::GetAllPins()\r\n    {\r\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\r\n        return m_interface->GetAllPins(m_dbconn);\r\n    }\r\n\r\n    bool PinningIndex::ResetAllPins(std::string_view sourceId)\r\n    {\r\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\r\n        return m_interface->ResetAllPins(m_dbconn, sourceId);\r\n    }\r\n\r\n    std::unique_ptr<Schema::IPinningIndex> PinningIndex::CreateIPinningIndex() const\r\n    {\r\n        if (m_version == SQLite::Version{ 1, 0 } ||\r\n            m_version.MajorVersion == 1 ||\r\n            m_version.IsLatest())\r\n        {\r\n            return std::make_unique<Schema::Pinning_V1_0::PinningIndexInterface>();\r\n        }\r\n\r\n        THROW_HR(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED));\r\n    }\r\n\r\n    PinningIndex::PinningIndex(const std::string& target, SQLiteStorageBase::OpenDisposition disposition, Utility::ManagedFile&& indexFile) :\r\n        SQLiteStorageBase(target, disposition, std::move(indexFile))\r\n    {\r\n        AICLI_LOG(Repo, Info, << \"Opened Pinning Index with version [\" << m_version << \"], last write [\" << GetLastWriteTime() << \"]\");\r\n        m_interface = CreateIPinningIndex();\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX, disposition == SQLiteStorageBase::OpenDisposition::ReadWrite && m_version != m_interface->GetVersion());\r\n    }\r\n\r\n    PinningIndex::PinningIndex(const std::string& target, SQLite::Version version) : SQLiteStorageBase(target, version)\r\n    {\r\n        m_interface = CreateIPinningIndex();\r\n        m_version = m_interface->GetVersion();\r\n    }\r\n}"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/PinningIndex.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteWrapper.h>\r\n#include \"Microsoft/Schema/IPinningIndex.h\"\r\n#include <winget/SQLiteStorageBase.h>\r\n#include <winget/Pin.h>\r\n#include <winget/ManagedFile.h>\r\n\r\nnamespace AppInstaller::Repository::Microsoft\r\n{\r\n    struct PinningIndex : SQLite::SQLiteStorageBase\r\n    {\r\n        // An id that refers to a specific Pinning file.\r\n        using IdType = SQLite::rowid_t;\r\n\r\n        PinningIndex(const PinningIndex&) = delete;\r\n        PinningIndex& operator=(const PinningIndex&) = delete;\r\n\r\n        PinningIndex(PinningIndex&&) = default;\r\n        PinningIndex& operator=(PinningIndex&&) = default;\r\n\r\n        // Creates a new PinningIndex database of the given version.\r\n        static PinningIndex CreateNew(const std::string& filePath, SQLite::Version version = SQLite::Version::Latest());\r\n\r\n        // Opens an existing PinningIndex database.\r\n        static PinningIndex Open(const std::string& filePath, OpenDisposition disposition, Utility::ManagedFile&& indexFile = {})\r\n        {\r\n            return { filePath, disposition, std::move(indexFile) };\r\n        }\r\n\r\n        // Opens the PinningIndex database on the default path if it exists.\r\n        // Returns nullptr in case of error.\r\n        static std::shared_ptr<PinningIndex> OpenIfExists(OpenDisposition openDisposition = OpenDisposition::Read);\r\n\r\n        // Opens or creates a PinningIndex database on the default path.\r\n        // openDisposition is only used when opening an existing database.\r\n        // Returns nullptr in case of error.\r\n        static std::shared_ptr<PinningIndex> OpenOrCreateDefault(OpenDisposition openDisposition = OpenDisposition::ReadWrite);\r\n\r\n        // Adds a pin to the index.\r\n        IdType AddPin(const Pinning::Pin& pin);\r\n\r\n        // Updates a pin type, and gated version if needed.\r\n        // Return value indicates whether there were any changes.\r\n        bool UpdatePin(const Pinning::Pin& pin);\r\n\r\n        // Adds a pin or updates it if it already exists.\r\n        void AddOrUpdatePin(const Pinning::Pin& pin);\r\n\r\n        // Removes a pin from the index.\r\n        void RemovePin(const Pinning::PinKey& pinKey);\r\n\r\n        // Returns the current pin for a given package if it exists.\r\n        std::optional<Pinning::Pin> GetPin(const Pinning::PinKey& pinKey);\r\n\r\n        // Returns a vector containing all the existing pins.\r\n        std::vector<Pinning::Pin> GetAllPins();\r\n\r\n        // Deletes all pins from a given source, or from all sources if none is specified\r\n        bool ResetAllPins(std::string_view sourceId = {});\r\n\r\n    private:\r\n        // Constructor used to open an existing index.\r\n        PinningIndex(const std::string& target, SQLiteStorageBase::OpenDisposition disposition, Utility::ManagedFile&& indexFile);\r\n\r\n        // Constructor used to create a new index.\r\n        PinningIndex(const std::string& target, SQLite::Version version);\r\n\r\n        // Creates the IPinningIndex interface object for this version.\r\n        std::unique_ptr<Schema::IPinningIndex> CreateIPinningIndex() const;\r\n\r\n        std::unique_ptr<Schema::IPinningIndex> m_interface;\r\n    };\r\n}"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/PortableIndex.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/PortableIndex.h\"\r\n#include \"Microsoft/Schema/IPortableIndex.h\"\r\n#include \"Microsoft/Schema/Portable_1_0/PortableTable.h\"\r\n#include <winget/SQLiteStorageBase.h>\r\n#include \"Schema/Portable_1_0/PortableIndexInterface.h\"\r\n#include <winget/Filesystem.h>\r\n\r\nnamespace AppInstaller::Repository::Microsoft\r\n{\r\n    PortableIndex::PortableIndex(PortableIndex&&) = default;\r\n    PortableIndex& PortableIndex::operator=(PortableIndex&&) = default;\r\n\r\n    PortableIndex::~PortableIndex() = default;\r\n\r\n    PortableIndex PortableIndex::CreateNew(const std::string& filePath, SQLite::Version version)\r\n    {\r\n        AICLI_LOG(Repo, Info, << \"Creating new Portable Index with version [\" << version << \"] at '\" << filePath << \"'\");\r\n        PortableIndex result{ filePath, version };\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(result.m_dbconn, \"portableindex_createnew\");\r\n\r\n        // Use calculated version, as incoming version could be 'latest'\r\n        result.m_version.SetSchemaVersion(result.m_dbconn);\r\n\r\n        result.m_interface->CreateTable(result.m_dbconn);\r\n\r\n        const auto& filePathUTF16 = Utility::ConvertToUTF16(filePath);\r\n        SetFileAttributes(filePathUTF16.c_str(), GetFileAttributes(filePathUTF16.c_str()) | FILE_ATTRIBUTE_HIDDEN);\r\n\r\n        result.SetLastWriteTime();\r\n\r\n        savepoint.Commit();\r\n\r\n        return result;\r\n    }\r\n\r\n    PortableIndex PortableIndex::Open(const std::string& filePath, OpenDisposition disposition, Utility::ManagedFile&& indexFile)\r\n    {\r\n        return { filePath, disposition, std::move(indexFile) };\r\n    }\r\n\r\n    PortableIndex::IdType PortableIndex::AddPortableFile(const Portable::PortableFileEntry& file)\r\n    {\r\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\r\n        AICLI_LOG(Repo, Verbose, << \"Adding portable file for [\" << file.GetFilePath() << \"]\");\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(m_dbconn, \"portableindex_addfile\");\r\n\r\n        IdType result = m_interface->AddPortableFile(m_dbconn, file);\r\n\r\n        SetLastWriteTime();\r\n\r\n        savepoint.Commit();\r\n\r\n        return result;\r\n    }\r\n\r\n    void PortableIndex::RemovePortableFile(const Portable::PortableFileEntry& file)\r\n    {\r\n        AICLI_LOG(Repo, Verbose, << \"Removing portable file [\" << file.GetFilePath() << \"]\");\r\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(m_dbconn, \"portableindex_removefile\");\r\n\r\n        m_interface->RemovePortableFile(m_dbconn, file);\r\n\r\n        SetLastWriteTime();\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    bool PortableIndex::UpdatePortableFile(const Portable::PortableFileEntry& file)\r\n    {\r\n        AICLI_LOG(Repo, Verbose, << \"Updating portable file [\" << file.GetFilePath() << \"]\");\r\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(m_dbconn, \"portableindex_updatefile\");\r\n\r\n        bool result = m_interface->UpdatePortableFile(m_dbconn, file).first;\r\n        \r\n        if (result)\r\n        {\r\n            SetLastWriteTime();\r\n            savepoint.Commit();\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    bool PortableIndex::Exists(const Portable::PortableFileEntry& file)\r\n    {\r\n        AICLI_LOG(Repo, Verbose, << \"Checking if portable file exists [\" << file.GetFilePath() << \"]\");\r\n        return m_interface->Exists(m_dbconn, file);\r\n    }\r\n\r\n    bool PortableIndex::IsEmpty()\r\n    {\r\n        return m_interface->IsEmpty(m_dbconn);\r\n    }\r\n\r\n    void PortableIndex::AddOrUpdatePortableFile(const Portable::PortableFileEntry& file)\r\n    {\r\n        if (Exists(file))\r\n        {\r\n            UpdatePortableFile(file);\r\n        }\r\n        else\r\n        {\r\n            AddPortableFile(file);\r\n        }\r\n    }\r\n\r\n    std::vector<Portable::PortableFileEntry> PortableIndex::GetAllPortableFiles()\r\n    {\r\n        return m_interface->GetAllPortableFiles(m_dbconn);\r\n    }\r\n\r\n    std::unique_ptr<Schema::IPortableIndex> PortableIndex::CreateIPortableIndex() const\r\n    {\r\n        if (m_version == SQLite::Version{ 1, 0 } ||\r\n            m_version.MajorVersion == 1 ||\r\n            m_version.IsLatest())\r\n        {\r\n            return std::make_unique<Schema::Portable_V1_0::PortableIndexInterface>();\r\n        }\r\n\r\n        THROW_HR(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED));\r\n    }\r\n\r\n    PortableIndex::PortableIndex(const std::string& target, SQLiteStorageBase::OpenDisposition disposition, Utility::ManagedFile&& indexFile) :\r\n        SQLiteStorageBase(target, disposition, std::move(indexFile))\r\n    {\r\n        AICLI_LOG(Repo, Info, << \"Opened Portable Index with version [\" << m_version << \"], last write [\" << GetLastWriteTime() << \"]\");\r\n        m_interface = CreateIPortableIndex();\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX, disposition == SQLiteStorageBase::OpenDisposition::ReadWrite && m_version != m_interface->GetVersion());\r\n    }\r\n\r\n    PortableIndex::PortableIndex(const std::string& target, SQLite::Version version) : SQLiteStorageBase(target, version)\r\n    {\r\n        m_interface = CreateIPortableIndex();\r\n        m_version = m_interface->GetVersion();\r\n    }\r\n}"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/PreIndexedPackageSourceFactory.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Microsoft/PreIndexedPackageSourceFactory.h\"\r\n#include \"Microsoft/SQLiteIndex.h\"\r\n#include \"Microsoft/SQLiteIndexSource.h\"\r\n#include \"SourceUpdateChecks.h\"\r\n\r\n#include <AppInstallerDateTime.h>\r\n#include <AppInstallerDeployment.h>\r\n#include <AppInstallerDownloader.h>\r\n#include <AppInstallerMsixInfo.h>\r\n#include <winget/ManagedFile.h>\r\n#include <winget/ExperimentalFeature.h>\r\n\r\nusing namespace std::string_literals;\r\nusing namespace std::string_view_literals;\r\n\r\nnamespace AppInstaller::Repository::Microsoft\r\n{\r\n    namespace\r\n    {\r\n        static constexpr std::string_view s_PreIndexedPackageSourceFactory_PackageFileName = \"source.msix\"sv;\r\n        static constexpr std::string_view s_PreIndexedPackageSourceFactory_V2_PackageFileName = \"source2.msix\"sv;\r\n        static constexpr std::string_view s_PreIndexedPackageSourceFactory_PackageVersionHeader = \"x-ms-meta-sourceversion\"sv;\r\n        static constexpr std::string_view s_PreIndexedPackageSourceFactory_IndexFileName = \"index.db\"sv;\r\n        // TODO: This being hard coded to force using the Public directory name is not ideal.\r\n        static constexpr std::string_view s_PreIndexedPackageSourceFactory_IndexFilePath = \"Public\\\\index.db\"sv;\r\n\r\n        // Construct the package location from the given details.\r\n        // Currently expects that the arg is an https uri pointing to the root of the data.\r\n        std::string GetPackageLocation(const std::string& basePath, std::string_view fileName)\r\n        {\r\n            std::string result = basePath;\r\n            if (result.back() != '/')\r\n            {\r\n                result += '/';\r\n            }\r\n            result += fileName;\r\n            return result;\r\n        }\r\n\r\n        // Gets the set of package locations that should be tried, in order.\r\n        std::vector<std::string> GetPackageLocations(const SourceDetails& details)\r\n        {\r\n            THROW_HR_IF(E_INVALIDARG, details.Arg.empty());\r\n\r\n            std::vector<std::string> result;\r\n\r\n            result.emplace_back(GetPackageLocation(details.Arg, s_PreIndexedPackageSourceFactory_V2_PackageFileName));\r\n            result.emplace_back(GetPackageLocation(details.Arg, s_PreIndexedPackageSourceFactory_PackageFileName));\r\n\r\n            if (!details.AlternateArg.empty())\r\n            {\r\n                result.emplace_back(GetPackageLocation(details.AlternateArg, s_PreIndexedPackageSourceFactory_V2_PackageFileName));\r\n                result.emplace_back(GetPackageLocation(details.AlternateArg, s_PreIndexedPackageSourceFactory_PackageFileName));\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        // Abstracts the fallback for package location when the MsixInfo is needed.\r\n        struct PreIndexedPackageInfo\r\n        {\r\n            template <typename LocationCheck>\r\n            PreIndexedPackageInfo(const SourceDetails& details, LocationCheck&& locationCheck)\r\n            {\r\n                std::vector<std::string> potentialLocations = GetPackageLocations(details);\r\n\r\n                for (const auto& location : potentialLocations)\r\n                {\r\n                    locationCheck(location);\r\n                }\r\n\r\n                std::exception_ptr primaryException;\r\n\r\n                for (const auto& location : potentialLocations)\r\n                {\r\n                    try\r\n                    {\r\n                        m_msixInfo = std::make_unique<Msix::MsixInfo>(location);\r\n                        m_packageLocation = location;\r\n                        return;\r\n                    }\r\n                    catch (...)\r\n                    {\r\n                        LOG_CAUGHT_EXCEPTION_MSG(\"PreIndexedPackageInfo failed on location: %hs\", location.c_str());\r\n                        if (!primaryException)\r\n                        {\r\n                            primaryException = std::current_exception();\r\n                        }\r\n                    }\r\n                }\r\n\r\n                std::rethrow_exception(primaryException);\r\n            }\r\n\r\n            const std::string& PackageLocation() const { return m_packageLocation; }\r\n            Msix::MsixInfo& MsixInfo() { return *m_msixInfo; }\r\n\r\n        private:\r\n            std::string m_packageLocation;\r\n            std::unique_ptr<Msix::MsixInfo> m_msixInfo;\r\n        };\r\n\r\n        // Abstracts the fallback for package location when an update is being done.\r\n        struct PreIndexedPackageUpdateCheck\r\n        {\r\n            PreIndexedPackageUpdateCheck(const SourceDetails& details)\r\n            {\r\n                std::vector<std::string> potentialLocations = GetPackageLocations(details);\r\n\r\n                std::exception_ptr primaryException;\r\n\r\n                for (const auto& location : potentialLocations)\r\n                {\r\n                    try\r\n                    {\r\n                        m_availableVersion = GetAvailableVersionFrom(location);\r\n                        m_packageLocation = location;\r\n                        return;\r\n                    }\r\n                    catch (...)\r\n                    {\r\n                        LOG_CAUGHT_EXCEPTION_MSG(\"PreIndexedPackageUpdateCheck failed on location: %hs\", location.c_str());\r\n                        if (!primaryException)\r\n                        {\r\n                            primaryException = std::current_exception();\r\n                        }\r\n                    }\r\n                }\r\n\r\n                std::rethrow_exception(primaryException);\r\n            }\r\n\r\n            const std::string& PackageLocation() const { return m_packageLocation; }\r\n            const Msix::PackageVersion& AvailableVersion() const { return m_availableVersion; }\r\n\r\n        private:\r\n            std::string m_packageLocation;\r\n            Msix::PackageVersion m_availableVersion;\r\n\r\n            Msix::PackageVersion GetAvailableVersionFrom(const std::string& packageLocation)\r\n            {\r\n                if (Utility::IsUrlRemote(packageLocation))\r\n                {\r\n                    std::map<std::string, std::string> headers = Utility::GetHeaders(packageLocation);\r\n                    auto itr = headers.find(std::string{ s_PreIndexedPackageSourceFactory_PackageVersionHeader });\r\n                    if (itr != headers.end())\r\n                    {\r\n                        AICLI_LOG(Repo, Verbose, << \"Header indicates version is: \" << itr->second);\r\n                        return { itr->second };\r\n                    }\r\n\r\n                    // We did not find the header we were looking for, log the ones we did find\r\n                    AICLI_LOG(Repo, Verbose, << \"Did not find \" << s_PreIndexedPackageSourceFactory_PackageVersionHeader << \" in:\\n\" << [&]()\r\n                        {\r\n                            std::ostringstream headerLog;\r\n                            for (const auto& header : headers)\r\n                            {\r\n                                headerLog << \"  \" << header.first << \" : \" << header.second << '\\n';\r\n                            }\r\n                            return std::move(headerLog).str();\r\n                        }());\r\n                }\r\n\r\n                AICLI_LOG(Repo, Verbose, << \"Reading package data to determine version\");\r\n                Msix::MsixInfo info{ packageLocation };\r\n                auto manifest = info.GetAppPackageManifests();\r\n\r\n                THROW_HR_IF(APPINSTALLER_CLI_ERROR_PACKAGE_IS_BUNDLE, manifest.size() > 1);\r\n                THROW_HR_IF(E_UNEXPECTED, manifest.size() == 0);\r\n\r\n                return manifest[0].GetIdentity().GetVersion();\r\n            }\r\n        };\r\n\r\n        // Gets the package family name from the details.\r\n        std::string GetPackageFamilyNameFromDetails(const SourceDetails& details)\r\n        {\r\n            THROW_HR_IF(E_UNEXPECTED, details.Data.empty());\r\n            return details.Data;\r\n        }\r\n\r\n        // Creates a name for the cross process reader-writer lock given the details.\r\n        std::string CreateNameForCPL(const SourceDetails& details)\r\n        {\r\n            // The only relevant data is the package family name\r\n            return \"PreIndexedSourceCPL_\"s + GetPackageFamilyNameFromDetails(details);\r\n        }\r\n\r\n        // The base class for a package that comes from a preindexed packaged source.\r\n        struct PreIndexedFactoryBase : public ISourceFactory\r\n        {\r\n            std::string_view TypeName() const override final\r\n            {\r\n                return PreIndexedPackageSourceFactory::Type();\r\n            }\r\n\r\n            std::shared_ptr<ISourceReference> Create(const SourceDetails& details) override final\r\n            {\r\n                // With more than one source implementation, we will probably need to probe first\r\n                THROW_HR_IF(E_INVALIDARG, !details.Type.empty() && details.Type != PreIndexedPackageSourceFactory::Type());\r\n\r\n                return CreateInternal(details);\r\n            }\r\n\r\n            virtual std::shared_ptr<ISourceReference> CreateInternal(const SourceDetails& details) = 0;\r\n\r\n            bool Add(SourceDetails& details, IProgressCallback& progress) override final\r\n            {\r\n                if (details.Type.empty())\r\n                {\r\n                    // With more than one source implementation, we will probably need to probe first\r\n                    details.Type = PreIndexedPackageSourceFactory::Type();\r\n                    AICLI_LOG(Repo, Info, << \"Initializing source type: \" << details.Name << \" => \" << details.Type);\r\n                }\r\n                else\r\n                {\r\n                    THROW_HR_IF(E_INVALIDARG, details.Type != PreIndexedPackageSourceFactory::Type());\r\n                }\r\n\r\n                PreIndexedPackageInfo packageInfo(details, [](const std::string& packageLocation)\r\n                    {\r\n                        THROW_HR_IF(APPINSTALLER_CLI_ERROR_SOURCE_NOT_SECURE, Utility::IsUrlRemote(packageLocation) && !Utility::IsUrlSecure(packageLocation));\r\n                    });\r\n\r\n                AICLI_LOG(Repo, Info, << \"Initializing source from: \" << details.Name << \" => \" << packageInfo.PackageLocation());\r\n\r\n                THROW_HR_IF(APPINSTALLER_CLI_ERROR_PACKAGE_IS_BUNDLE, packageInfo.MsixInfo().GetIsBundle());\r\n\r\n                auto fullName = packageInfo.MsixInfo().GetPackageFullName();\r\n                AICLI_LOG(Repo, Info, << \"Found package full name: \" << details.Name << \" => \" << fullName);\r\n\r\n                details.Data = Msix::GetPackageFamilyNameFromFullName(fullName);\r\n                details.Identifier = Msix::GetPackageFamilyNameFromFullName(fullName);\r\n\r\n                auto lock = LockExclusive(details, progress);\r\n                if (!lock)\r\n                {\r\n                    return false;\r\n                }\r\n\r\n                return UpdateInternal(packageInfo.PackageLocation(), details, progress);\r\n            }\r\n\r\n            bool Update(const SourceDetails& details, IProgressCallback& progress) override final\r\n            {\r\n                return UpdateBase(details, false, progress);\r\n            }\r\n\r\n            bool BackgroundUpdate(const SourceDetails& details, IProgressCallback& progress) override final\r\n            {\r\n                return UpdateBase(details, true, progress);\r\n            }\r\n\r\n            // Retrieves the currently cached version of the package.\r\n            virtual std::optional<Msix::PackageVersion> GetCurrentVersion(const SourceDetails& details) = 0;\r\n\r\n            virtual bool UpdateInternal(const std::string& packageLocation, const SourceDetails& details, IProgressCallback& progress) = 0;\r\n\r\n            bool Remove(const SourceDetails& details, IProgressCallback& progress) override final\r\n            {\r\n                THROW_HR_IF(E_INVALIDARG, details.Type != PreIndexedPackageSourceFactory::Type());\r\n                auto lock = LockExclusive(details, progress);\r\n                if (!lock)\r\n                {\r\n                    return false;\r\n                }\r\n\r\n                return RemoveInternal(details, progress);\r\n            }\r\n\r\n            virtual bool RemoveInternal(const SourceDetails& details, IProgressCallback&) = 0;\r\n\r\n        private:\r\n            Synchronization::CrossProcessLock LockExclusive(const SourceDetails& details, IProgressCallback& progress, bool isBackground = false)\r\n            {\r\n                Synchronization::CrossProcessLock result(CreateNameForCPL(details));\r\n\r\n                if (isBackground)\r\n                {\r\n                    // If this is a background update, don't wait on the lock.\r\n                    result.TryAcquireNoWait();\r\n                }\r\n                else\r\n                {\r\n                    result.Acquire(progress);\r\n                }\r\n\r\n                return result;\r\n            }\r\n\r\n            bool UpdateBase(const SourceDetails& details, bool isBackground, IProgressCallback& progress)\r\n            {\r\n                THROW_HR_IF(E_INVALIDARG, details.Type != PreIndexedPackageSourceFactory::Type());\r\n\r\n                std::optional<Msix::PackageVersion> currentVersion = GetCurrentVersion(details);\r\n                PreIndexedPackageUpdateCheck updateCheck(details);\r\n\r\n                if (currentVersion)\r\n                {\r\n                    if (currentVersion.value() >= updateCheck.AvailableVersion())\r\n                    {\r\n                        AICLI_LOG(Repo, Verbose, << \"Remote source data (\" << updateCheck.AvailableVersion().ToString() <<\r\n                            \") was not newer than existing (\" << currentVersion.value().ToString() << \"), no update needed\");\r\n                        return true;\r\n                    }\r\n                    else\r\n                    {\r\n                        AICLI_LOG(Repo, Verbose, << \"Remote source data (\" << updateCheck.AvailableVersion().ToString() <<\r\n                            \") was newer than existing (\" << currentVersion.value().ToString() << \"), updating\");\r\n                    }\r\n                }\r\n\r\n                if (progress.IsCancelledBy(CancelReason::Any))\r\n                {\r\n                    AICLI_LOG(Repo, Info, << \"Cancelling update upon request\");\r\n                    return false;\r\n                }\r\n\r\n                auto lock = LockExclusive(details, progress, isBackground);\r\n                if (!lock)\r\n                {\r\n                    return false;\r\n                }\r\n\r\n                return UpdateInternal(updateCheck.PackageLocation(), details, progress);\r\n            }\r\n        };\r\n\r\n        // *Should only be called when under a CrossProcessReaderWriteLock*\r\n        std::optional<Deployment::Extension> GetExtensionFromDetails(const SourceDetails& details)\r\n        {\r\n            Deployment::ExtensionCatalog catalog(Deployment::SourceExtensionName);\r\n            return catalog.FindByPackageFamilyAndId(GetPackageFamilyNameFromDetails(details), Deployment::IndexDBId);\r\n        }\r\n\r\n        std::optional<Msix::PackageVersion> PackagedContextGetCurrentVersion(const SourceDetails& details)\r\n        {\r\n            auto extension = GetExtensionFromDetails(details);\r\n\r\n            if (extension)\r\n            {\r\n                auto version = extension->GetPackageVersion();\r\n                return Msix::PackageVersion{ version.Major, version.Minor, version.Build, version.Revision };\r\n            }\r\n            else\r\n            {\r\n                return std::nullopt;\r\n            }\r\n        }\r\n\r\n        // Constructs the location that we will write files to.\r\n        std::filesystem::path GetStatePathFromDetails(const SourceDetails& details)\r\n        {\r\n            std::filesystem::path result = Runtime::GetPathTo(Runtime::PathName::LocalState);\r\n            result /= PreIndexedPackageSourceFactory::Type();\r\n            result /= GetPackageFamilyNameFromDetails(details);\r\n            return result;\r\n        }\r\n\r\n        std::optional<Msix::PackageVersion> DesktopContextGetCurrentVersion(const SourceDetails& details)\r\n        {\r\n            std::filesystem::path packageState = GetStatePathFromDetails(details);\r\n            std::filesystem::path packagePath = packageState / s_PreIndexedPackageSourceFactory_PackageFileName;\r\n\r\n            if (std::filesystem::exists(packagePath))\r\n            {\r\n                // If we already have a trusted index package, use it to determine if we need to update or not.\r\n                Msix::WriteLockedMsixFile indexPackage{ packagePath };\r\n                if (indexPackage.ValidateTrustInfo(WI_IsFlagSet(details.TrustLevel, SourceTrustLevel::StoreOrigin)))\r\n                {\r\n                    Msix::MsixInfo msixInfo{ packagePath };\r\n                    auto manifest = msixInfo.GetAppPackageManifests();\r\n\r\n                    if (manifest.size() == 1)\r\n                    {\r\n                        return manifest[0].GetIdentity().GetVersion();\r\n                    }\r\n                }\r\n            }\r\n\r\n            return std::nullopt;\r\n        }\r\n\r\n        bool CheckForUpdateBeforeOpen(const SourceDetails& details, std::optional<Msix::PackageVersion> currentVersion, const std::optional<TimeSpan>& requestedUpdateInterval)\r\n        {\r\n            // If we can't find a good package, then we have to update to operate\r\n            if (!currentVersion)\r\n            {\r\n                AICLI_LOG(Repo, Verbose, << \"Source `\" << details.Name << \"` has no data\");\r\n                return true;\r\n            }\r\n\r\n            using namespace std::chrono_literals;\r\n            using clock = std::chrono::system_clock;\r\n\r\n            // Attempt to convert the package version to a time_point\r\n            clock::time_point versionTime = Utility::GetTimePointFromVersion(currentVersion.value());\r\n\r\n            // Since we expect that the version time indicates creation time, don't let it be far in the future.\r\n            auto now = clock::now();\r\n            if (versionTime > now && versionTime - now > 24h)\r\n            {\r\n                versionTime = clock::time_point::min();\r\n            }\r\n\r\n            // Use the later of the version and last update times\r\n            clock::time_point timeToCheck = (versionTime > details.LastUpdateTime ? versionTime : details.LastUpdateTime);\r\n\r\n            return IsAfterUpdateCheckTime(details.Name, timeToCheck, requestedUpdateInterval);\r\n        }\r\n\r\n        struct PackagedContextSourceReference : public ISourceReference\r\n        {\r\n            PackagedContextSourceReference(const SourceDetails& details) : m_details(details)\r\n            {\r\n                if (!m_details.Data.empty())\r\n                {\r\n                    m_details.Identifier = GetPackageFamilyNameFromDetails(details);\r\n                }\r\n            }\r\n\r\n            std::string GetIdentifier() override { return m_details.Identifier; }\r\n\r\n            SourceDetails& GetDetails() override { return m_details; };\r\n\r\n            bool ShouldUpdateBeforeOpen(const std::optional<TimeSpan>& requestedUpdateInterval) override\r\n            {\r\n                return CheckForUpdateBeforeOpen(m_details, PackagedContextGetCurrentVersion(m_details), requestedUpdateInterval);\r\n            }\r\n\r\n            std::shared_ptr<ISource> Open(IProgressCallback& progress) override\r\n            {\r\n                Synchronization::CrossProcessLock lock(CreateNameForCPL(m_details));\r\n                if (!lock.Acquire(progress))\r\n                {\r\n                    return {};\r\n                }\r\n\r\n                auto extension = GetExtensionFromDetails(m_details);\r\n                if (!extension)\r\n                {\r\n                    AICLI_LOG(Repo, Info, << \"Package not found \" << m_details.Data);\r\n                    THROW_HR(APPINSTALLER_CLI_ERROR_SOURCE_DATA_MISSING);\r\n                }\r\n\r\n                THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_NEEDS_REMEDIATION), !extension->VerifyContentIntegrity(progress));\r\n\r\n                // To work around an issue with accessing the public folder, we are temporarily\r\n                // constructing the location ourself.  This was already the case for the non-packaged\r\n                // runtime, and we can fix both in the future.  The only problem with this is that\r\n                // the directory in the extension *must* be Public, rather than one set by the creator.\r\n                std::filesystem::path indexLocation = extension->GetPackagePath();\r\n                indexLocation /= s_PreIndexedPackageSourceFactory_IndexFilePath;\r\n\r\n                SQLiteIndex index = SQLiteIndex::Open(indexLocation.u8string(), SQLiteIndex::OpenDisposition::Immutable);\r\n\r\n                // We didn't use to store the source identifier, so we compute it here in case it's\r\n                // missing from the details.\r\n                m_details.Identifier = GetPackageFamilyNameFromDetails(m_details);\r\n                return std::make_shared<SQLiteIndexSource>(m_details, std::move(index), false, true);\r\n            }\r\n\r\n        private:\r\n            SourceDetails m_details;\r\n        };\r\n\r\n        // Source factory for running within a packaged context\r\n        struct PackagedContextFactory : public PreIndexedFactoryBase\r\n        {\r\n            std::shared_ptr<ISourceReference> CreateInternal(const SourceDetails& details) override\r\n            {\r\n                return std::make_shared<PackagedContextSourceReference>(details);\r\n            }\r\n\r\n            std::optional<Msix::PackageVersion> GetCurrentVersion(const SourceDetails& details) override\r\n            {\r\n                return PackagedContextGetCurrentVersion(details);\r\n            }\r\n\r\n            bool UpdateInternal(const std::string& packageLocation, const SourceDetails& details, IProgressCallback& progress) override\r\n            {\r\n                // Due to complications with deployment, download the file and deploy from\r\n                // a local source while we investigate further.\r\n                bool download = Utility::IsUrlRemote(packageLocation);\r\n                std::filesystem::path localFile;\r\n\r\n                if (download)\r\n                {\r\n                    localFile = Runtime::GetPathTo(Runtime::PathName::Temp);\r\n                    localFile /= GetPackageFamilyNameFromDetails(details) + \".msix\";\r\n\r\n                    Utility::Download(packageLocation, localFile, Utility::DownloadType::Index, progress);\r\n                }\r\n                else\r\n                {\r\n                    localFile = Utility::ConvertToUTF16(packageLocation);\r\n                }\r\n\r\n                // Verify the local file\r\n                Msix::WriteLockedMsixFile fileLock{ localFile };\r\n                Msix::MsixInfo localMsixInfo{ localFile };\r\n\r\n                // The package should not be a bundle\r\n                THROW_HR_IF(APPINSTALLER_CLI_ERROR_PACKAGE_IS_BUNDLE, localMsixInfo.GetIsBundle());\r\n\r\n                // Ensure that family name has not changed\r\n                THROW_HR_IF(APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE,\r\n                    GetPackageFamilyNameFromDetails(details) != Msix::GetPackageFamilyNameFromFullName(localMsixInfo.GetPackageFullName()));\r\n\r\n                if (!fileLock.ValidateTrustInfo(WI_IsFlagSet(details.TrustLevel, SourceTrustLevel::StoreOrigin)))\r\n                {\r\n                    AICLI_LOG(Repo, Error, << \"Source update failed. Source package failed trust validation.\");\r\n                    THROW_HR(APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE);\r\n                }\r\n\r\n                winrt::Windows::Foundation::Uri uri = winrt::Windows::Foundation::Uri(localFile.c_str());\r\n                Deployment::AddPackage(\r\n                    uri,\r\n                    Deployment::Options{ WI_IsFlagSet(details.TrustLevel, SourceTrustLevel::Trusted) },\r\n                    progress);\r\n\r\n                if (download)\r\n                {\r\n                    try\r\n                    {\r\n                        // If successful, delete the file\r\n                        std::filesystem::remove(localFile);\r\n                    }\r\n                    CATCH_LOG();\r\n                }\r\n\r\n                return true;\r\n            }\r\n\r\n            bool RemoveInternal(const SourceDetails& details, IProgressCallback& callback) override\r\n            {\r\n                auto fullName = Msix::GetPackageFullNameFromFamilyName(GetPackageFamilyNameFromDetails(details));\r\n\r\n                if (!fullName)\r\n                {\r\n                    AICLI_LOG(Repo, Info, << \"No full name found for family name: \" << GetPackageFamilyNameFromDetails(details));\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(Repo, Info, << \"Removing package: \" << *fullName);\r\n                    Deployment::RemovePackage(*fullName, winrt::Windows::Management::Deployment::RemovalOptions::None, callback);\r\n                }\r\n\r\n                return true;\r\n            }\r\n        };\r\n\r\n        struct DesktopContextSourceReference : public ISourceReference\r\n        {\r\n            DesktopContextSourceReference(const SourceDetails& details) : m_details(details)\r\n            {\r\n                if (!m_details.Data.empty())\r\n                {\r\n                    m_details.Identifier = GetPackageFamilyNameFromDetails(details);\r\n                }\r\n            }\r\n\r\n            std::string GetIdentifier() override { return m_details.Identifier; }\r\n\r\n            SourceDetails& GetDetails() override { return m_details; };\r\n\r\n            bool ShouldUpdateBeforeOpen(const std::optional<TimeSpan>& requestedUpdateInterval) override\r\n            {\r\n                return CheckForUpdateBeforeOpen(m_details, DesktopContextGetCurrentVersion(m_details), requestedUpdateInterval);\r\n            }\r\n\r\n            std::shared_ptr<ISource> Open(IProgressCallback& progress) override\r\n            {\r\n                Synchronization::CrossProcessLock lock(CreateNameForCPL(m_details));\r\n                if (!lock.Acquire(progress))\r\n                {\r\n                    return {};\r\n                }\r\n\r\n                std::filesystem::path packageLocation = GetStatePathFromDetails(m_details);\r\n                packageLocation /= s_PreIndexedPackageSourceFactory_PackageFileName;\r\n\r\n                if (!std::filesystem::exists(packageLocation))\r\n                {\r\n                    AICLI_LOG(Repo, Info, << \"Data not found at \" << packageLocation);\r\n                    THROW_HR(APPINSTALLER_CLI_ERROR_SOURCE_DATA_MISSING);\r\n                }\r\n\r\n                // Put a write exclusive lock on the index package.\r\n                Msix::WriteLockedMsixFile indexPackage{ packageLocation };\r\n\r\n                // Validate index package trust info.\r\n                THROW_HR_IF(APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE, !indexPackage.ValidateTrustInfo(WI_IsFlagSet(m_details.TrustLevel, SourceTrustLevel::StoreOrigin)));\r\n\r\n                // Create a temp lock exclusive index file.\r\n                auto tempIndexFilePath = Runtime::GetNewTempFilePath();\r\n                auto tempIndexFile = Utility::ManagedFile::CreateWriteLockedFile(tempIndexFilePath, GENERIC_WRITE, true);\r\n\r\n                // Populate temp index file.\r\n                Msix::MsixInfo packageInfo(packageLocation);\r\n                packageInfo.WriteToFileHandle(s_PreIndexedPackageSourceFactory_IndexFilePath, tempIndexFile.GetFileHandle(), progress);\r\n\r\n                if (progress.IsCancelledBy(CancelReason::Any))\r\n                {\r\n                    AICLI_LOG(Repo, Info, << \"Cancelling open upon request\");\r\n                    return {};\r\n                }\r\n\r\n                SQLiteIndex index = SQLiteIndex::Open(tempIndexFile.GetFilePath().u8string(), SQLiteIndex::OpenDisposition::Immutable, std::move(tempIndexFile));\r\n\r\n                // We didn't use to store the source identifier, so we compute it here in case it's\r\n                // missing from the details.\r\n                m_details.Identifier = GetPackageFamilyNameFromDetails(m_details);\r\n                return std::make_shared<SQLiteIndexSource>(m_details, std::move(index), false, true);\r\n            }\r\n\r\n        private:\r\n            SourceDetails m_details;\r\n        };\r\n\r\n        // Source factory for running outside of a package.\r\n        struct DesktopContextFactory : public PreIndexedFactoryBase\r\n        {\r\n            std::shared_ptr<ISourceReference> CreateInternal(const SourceDetails& details) override\r\n            {\r\n                return std::make_shared<DesktopContextSourceReference>(details);\r\n            }\r\n\r\n            std::optional<Msix::PackageVersion> GetCurrentVersion(const SourceDetails& details) override\r\n            {\r\n                return DesktopContextGetCurrentVersion(details);\r\n            }\r\n\r\n            bool UpdateInternal(const std::string& packageLocation, const SourceDetails& details, IProgressCallback& progress) override\r\n            {\r\n                // We will extract the manifest and index files directly to this location\r\n                std::filesystem::path packageState = GetStatePathFromDetails(details);\r\n                std::filesystem::create_directories(packageState);\r\n\r\n                std::filesystem::path packagePath = packageState / s_PreIndexedPackageSourceFactory_PackageFileName;\r\n\r\n                std::filesystem::path tempPackagePath = packagePath.u8string() + \".dnld.msix\";\r\n                auto removeTempFileOnExit = wil::scope_exit([&]()\r\n                    {\r\n                        try\r\n                        {\r\n                            std::filesystem::remove(tempPackagePath);\r\n                        }\r\n                        catch (...)\r\n                        {\r\n                            AICLI_LOG(Repo, Info, << \"Failed to remove temp index file at: \" << tempPackagePath);\r\n                        }\r\n                    });\r\n\r\n                if (Utility::IsUrlRemote(packageLocation))\r\n                {\r\n                    AppInstaller::Utility::Download(packageLocation, tempPackagePath, AppInstaller::Utility::DownloadType::Index, progress);\r\n                }\r\n                else\r\n                {\r\n                    std::filesystem::copy(packageLocation, tempPackagePath);\r\n                    progress.OnProgress(100, 100, ProgressType::Percent);\r\n                }\r\n\r\n                if (progress.IsCancelledBy(CancelReason::Any))\r\n                {\r\n                    AICLI_LOG(Repo, Info, << \"Cancelling update upon request\");\r\n                    return false;\r\n                }\r\n\r\n                {\r\n                    // Extra scope to release the file lock right after trust validation.\r\n                    Msix::WriteLockedMsixFile tempIndexPackage{ tempPackagePath };\r\n                    Msix::MsixInfo tempMsixInfo{ tempPackagePath };\r\n\r\n                    // The package should not be a bundle\r\n                    THROW_HR_IF(APPINSTALLER_CLI_ERROR_PACKAGE_IS_BUNDLE, tempMsixInfo.GetIsBundle());\r\n\r\n                    // Ensure that family name has not changed\r\n                    THROW_HR_IF(APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE,\r\n                        GetPackageFamilyNameFromDetails(details) != Msix::GetPackageFamilyNameFromFullName(tempMsixInfo.GetPackageFullName()));\r\n\r\n                    if (!tempIndexPackage.ValidateTrustInfo(WI_IsFlagSet(details.TrustLevel, SourceTrustLevel::StoreOrigin)))\r\n                    {\r\n                        AICLI_LOG(Repo, Error, << \"Source update failed. Source package failed trust validation.\");\r\n                        THROW_HR(APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE);\r\n                    }\r\n                }\r\n\r\n                std::filesystem::rename(tempPackagePath, packagePath);\r\n                AICLI_LOG(Repo, Info, << \"Source update success.\");\r\n\r\n                removeTempFileOnExit.release();\r\n\r\n                return true;\r\n            }\r\n\r\n            bool RemoveInternal(const SourceDetails& details, IProgressCallback&) override\r\n            {\r\n                std::filesystem::path packageState = GetStatePathFromDetails(details);\r\n\r\n                if (!std::filesystem::exists(packageState))\r\n                {\r\n                    AICLI_LOG(Repo, Info, << \"No state found for source: \" << packageState.u8string());\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(Repo, Info, << \"Removing state found for source: \" << packageState.u8string());\r\n                    std::filesystem::remove_all(packageState);\r\n                }\r\n\r\n                return true;\r\n            }\r\n        };\r\n    }\r\n\r\n    std::unique_ptr<ISourceFactory> PreIndexedPackageSourceFactory::Create()\r\n    {\r\n        if (Runtime::IsRunningInPackagedContext())\r\n        {\r\n            return std::make_unique<PackagedContextFactory>();\r\n        }\r\n        else\r\n        {\r\n            return std::make_unique<DesktopContextFactory>();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/PreIndexedPackageSourceFactory.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ISource.h\"\r\n#include \"SourceFactory.h\"\r\n\r\n#include <string_view>\r\n\r\nnamespace AppInstaller::Repository::Microsoft\r\n{\r\n    using namespace std::string_view_literals;\r\n\r\n    // A source where the index is precomputed and stored on a server within an optional MSIX package.\r\n    // In addition, the manifest files are also individually available on the server.\r\n    // Arg  ::  Expected to be a fully qualified path to the root of the data.\r\n    //          This can be a web location such as https://somewhere/ or a local file share \\\\somewhere\\\r\n    //          Under this path there must exist an MSIX package called \"index.msix\".\r\n    //          This must have a file called \"index.db\" contained within, which is a SQLiteIndex.\r\n    //          The index's paths refer to relative locations under the Arg value.\r\n    // Data ::  The package family name of the package at Arg + /index.msix.\r\n    struct PreIndexedPackageSourceFactory\r\n    {\r\n        // Get the type string for this source.\r\n        static constexpr std::string_view Type()\r\n        {\r\n            using namespace std::string_view_literals;\r\n            return \"Microsoft.PreIndexed.Package\"sv;\r\n        }\r\n\r\n        // Creates a source factory for this type.\r\n        static std::unique_ptr<ISourceFactory> Create();\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/PredefinedInstalledSourceFactory.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Microsoft/ARPHelper.h\"\r\n#include \"Microsoft/FontHelper.h\"\r\n#include \"Microsoft/PredefinedInstalledSourceFactory.h\"\r\n#include \"Microsoft/SQLiteIndex.h\"\r\n#include \"Microsoft/SQLiteIndexSource.h\"\r\n#include <winget/ManifestInstaller.h>\r\n#include <winget/COMStaticStorage.h>\r\n#include <winget/Registry.h>\r\n#include <AppInstallerArchitecture.h>\r\n#include <winget/ExperimentalFeature.h>\r\n\r\nusing namespace std::string_literals;\r\nusing namespace std::string_view_literals;\r\n\r\nnamespace AppInstaller::Repository::Microsoft\r\n{\r\n    namespace\r\n    {\r\n        std::optional<std::string> GetCachedMSIXName(const Utility::NormalizedString& id, const Utility::Version& version, SQLiteIndex& cacheData)\r\n        {\r\n            SearchRequest searchRequest;\r\n            searchRequest.Inclusions.emplace_back(PackageMatchField::Id, MatchType::Exact, id);\r\n\r\n            SQLiteIndex::SearchResult searchResult = cacheData.Search(searchRequest);\r\n\r\n            if (searchResult.Matches.empty())\r\n            {\r\n                return std::nullopt;\r\n            }\r\n\r\n            if (searchResult.Matches.size() != 1)\r\n            {\r\n                // This is very unexpected, but just log it and carry on\r\n                AICLI_LOG(Repo, Warning, << \"Found multiple (\" << searchResult.Matches.size() << \") cache entries for: \" << id);\r\n                return std::nullopt;\r\n            }\r\n\r\n            auto versionKeys = cacheData.GetVersionKeysById(searchResult.Matches[0].first);\r\n            const SQLiteIndex::VersionKey* versionKey = nullptr;\r\n\r\n            for (const auto& key : versionKeys)\r\n            {\r\n                if (key.VersionAndChannel.GetVersion() == version)\r\n                {\r\n                    versionKey = &key;\r\n                    break;\r\n                }\r\n            }\r\n\r\n            if (!versionKey)\r\n            {\r\n                return std::nullopt;\r\n            }\r\n\r\n            return cacheData.GetPropertyByPrimaryId(versionKey->ManifestId, PackageVersionProperty::Name);\r\n        }\r\n\r\n        // Populates the index with the entries from MSIX.\r\n        void PopulateIndexFromMSIX(SQLiteIndex& index, Manifest::ScopeEnum scope, SQLiteIndex* cacheData = nullptr)\r\n        {\r\n            using namespace winrt::Windows::ApplicationModel;\r\n            using namespace winrt::Windows::Management::Deployment;\r\n            using namespace winrt::Windows::Foundation::Collections;\r\n\r\n            AICLI_LOG(Repo, Verbose, << \"Examining MSIX entries for \" << ScopeToString(scope));\r\n\r\n            IIterable<Package> packages;\r\n            PackageManager packageManager;\r\n\r\n            if (scope == Manifest::ScopeEnum::Machine)\r\n            {\r\n                // May not be present on our oldest supported systems; simply ignore for the time being.\r\n                IPackageManager9 packageManager9 = packageManager.try_as<IPackageManager9>();\r\n                if (packageManager9)\r\n                {\r\n                    try\r\n                    {\r\n                        packages = packageManager.FindProvisionedPackages();\r\n                    }\r\n                    catch (const winrt::hresult_error& hre)\r\n                    {\r\n                        // Historically this API has not been accessible unelevated; if it fails, try to carry on\r\n                        AICLI_LOG(Repo, Warning, << \"FindProvisionedPackages failed, bypassing provisioned packages: 0x\" << Logging::SetHRFormat << hre.code());\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(Repo, Warning, << \"FindProvisionedPackages is not available on this version of Windows\");\r\n                }\r\n            }\r\n            else\r\n            {\r\n                // TODO: Consider if Optional packages should also be enumerated\r\n                for (PackageTypes types : { PackageTypes::Main | PackageTypes::Framework, PackageTypes::Main, PackageTypes::Framework })\r\n                {\r\n                    try\r\n                    {\r\n                        packages = packageManager.FindPackagesForUserWithPackageTypes({}, types);\r\n                        break;\r\n                    }\r\n                    catch (const winrt::hresult_error& hre)\r\n                    {\r\n                        if (hre.code() == E_NOT_SET)\r\n                        {\r\n                            // This OS issue occurs frequently enough that we will attempt to work around it by enumerating progressively fewer packages\r\n                            AICLI_LOG(Repo, Warning, << \"FindPackagesForUserWithPackageTypes returned E_NOT_SET for types: \" << ToIntegral(types));\r\n                        }\r\n                        else\r\n                        {\r\n                            throw;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Failed to retrieve even an empty package list; make sure that these cases have a log to indicate why.\r\n            if (!packages)\r\n            {\r\n                AICLI_LOG(Repo, Warning, << \"MSIX package list not populated\");\r\n                return;\r\n            }\r\n\r\n            // Reuse the same manifest object, as we will be setting the same values every time.\r\n            Manifest::Manifest manifest;\r\n            // Add one installer for storing the package family name.\r\n            manifest.Installers.emplace_back();\r\n            // Every package will have the same tags currently.\r\n            manifest.DefaultLocalization.Add<Manifest::Localization::Tags>({ \"msix\" });\r\n\r\n            // Fields in the index but not populated:\r\n            //  AppMoniker - Not sure what we would put.\r\n            //  Channel - We don't know this information here.\r\n            //  Commands - We could open the manifest and look for these eventually.\r\n            //  Tags - Not sure what else we could put in here.\r\n            for (const auto& package : packages)\r\n            {\r\n                // System packages are part of the OS, and cannot be managed by the user.\r\n                // Filter them out as there is no point in showing them in a package manager.\r\n                auto signatureKind = package.SignatureKind();\r\n                if (signatureKind == PackageSignatureKind::System)\r\n                {\r\n                    continue;\r\n                }\r\n\r\n                auto packageId = package.Id();\r\n                Utility::NormalizedString fullName = Utility::ConvertToUTF8(packageId.FullName());\r\n                Utility::NormalizedString familyName = Utility::ConvertToUTF8(packageId.FamilyName());\r\n\r\n                manifest.Id = \"MSIX\\\\\" + fullName;\r\n\r\n                // Get version\r\n                std::ostringstream strstr;\r\n                auto packageVersion = packageId.Version();\r\n                strstr << packageVersion.Major << '.' << packageVersion.Minor << '.' << packageVersion.Build << '.' << packageVersion.Revision;\r\n\r\n                manifest.Version = strstr.str();\r\n\r\n                // Determine package name\r\n                bool isPackageNameSet = false;\r\n\r\n                // Look for the name in the cache data first\r\n                if (cacheData)\r\n                {\r\n                    std::optional<std::string> cachedName = GetCachedMSIXName(manifest.Id, manifest.Version, *cacheData);\r\n\r\n                    if (cachedName)\r\n                    {\r\n                        manifest.DefaultLocalization.Add<Manifest::Localization::PackageName>(cachedName.value());\r\n                        isPackageNameSet = true;\r\n                    }\r\n                }\r\n\r\n                // Attempt to get the DisplayName. Since this will retrieve the localized value, it has a chance to fail.\r\n                // Rather than completely skip this package in that case, we will simply fall back to using the package name below.\r\n                if (!isPackageNameSet && !Runtime::IsRunningAsSystem())\r\n                {\r\n                    try\r\n                    {\r\n                        auto displayName = Utility::ConvertToUTF8(package.DisplayName());\r\n                        if (!displayName.empty())\r\n                        {\r\n                            manifest.DefaultLocalization.Add<Manifest::Localization::PackageName>(displayName);\r\n                            isPackageNameSet = true;\r\n                        }\r\n                    }\r\n                    catch (const winrt::hresult_error& hre)\r\n                    {\r\n                        AICLI_LOG(Repo, Warning, << \"winrt::hresult_error[0x\" << Logging::SetHRFormat << hre.code() << \": \" <<\r\n                            Utility::ConvertToUTF8(hre.message()) << \"] exception thrown when getting DisplayName for \" << fullName);\r\n                    }\r\n                    catch (...)\r\n                    {\r\n                        AICLI_LOG(Repo, Warning, << \"Unknown exception thrown when getting DisplayName for \" << fullName);\r\n                    }\r\n                }\r\n\r\n                if (!isPackageNameSet)\r\n                {\r\n                    manifest.DefaultLocalization.Add<Manifest::Localization::PackageName>(Utility::ConvertToUTF8(packageId.Name()));\r\n                }\r\n\r\n                manifest.Installers[0].PackageFamilyName = familyName;\r\n\r\n                // Use the full name as a unique key for the path\r\n                auto manifestId = index.AddManifest(manifest);\r\n\r\n                index.SetMetadataByManifestId(manifestId, PackageVersionMetadata::InstalledType,\r\n                    Manifest::InstallerTypeToString(Manifest::InstallerTypeEnum::Msix));\r\n\r\n                auto architecture = Utility::ConvertToArchitectureEnum(packageId.Architecture());\r\n                if (architecture)\r\n                {\r\n                    index.SetMetadataByManifestId(manifestId, PackageVersionMetadata::InstalledArchitecture,\r\n                        ToString(architecture.value()));\r\n                }\r\n\r\n                // May not be present on our oldest supported systems; simply ignore for the time being.\r\n                IPackage8 package8 = package.try_as<IPackage8>();\r\n                if (package8)\r\n                {\r\n                    index.SetMetadataByManifestId(manifestId, PackageVersionMetadata::InstalledLocation,\r\n                        Utility::ConvertToUTF8(package8.InstalledPath()));\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(Repo, Warning, << \"Windows::ApplicationModel::Package::InstalledPath is not available on this version of Windows\");\r\n                }\r\n            }\r\n        }\r\n\r\n        SQLiteIndex CreateAndPopulateIndex(PredefinedInstalledSourceFactory::Filter filter)\r\n        {\r\n            AICLI_LOG(Repo, Verbose, << \"Creating PredefinedInstalledSource with filter [\" << PredefinedInstalledSourceFactory::FilterToString(filter) << ']');\r\n\r\n            // Create an in memory index\r\n            SQLiteIndex index = SQLiteIndex::CreateNew(SQLITE_MEMORY_DB_CONNECTION_TARGET, SQLite::Version::Latest(), SQLiteIndex::CreateOptions::SupportPathless);\r\n\r\n            // Put installed packages into the index\r\n            if (filter == PredefinedInstalledSourceFactory::Filter::None || filter == PredefinedInstalledSourceFactory::Filter::ARP ||\r\n                filter == PredefinedInstalledSourceFactory::Filter::User || filter == PredefinedInstalledSourceFactory::Filter::Machine)\r\n            {\r\n                ARPHelper arpHelper;\r\n                if (filter != PredefinedInstalledSourceFactory::Filter::User)\r\n                {\r\n                    arpHelper.PopulateIndexFromARP(index, Manifest::ScopeEnum::Machine);\r\n                }\r\n                if (filter != PredefinedInstalledSourceFactory::Filter::Machine)\r\n                {\r\n                    arpHelper.PopulateIndexFromARP(index, Manifest::ScopeEnum::User);\r\n                }\r\n            }\r\n\r\n            if (filter == PredefinedInstalledSourceFactory::Filter::None ||\r\n                filter == PredefinedInstalledSourceFactory::Filter::MSIX ||\r\n                filter == PredefinedInstalledSourceFactory::Filter::User)\r\n            {\r\n                PopulateIndexFromMSIX(index, Manifest::ScopeEnum::User);\r\n            }\r\n            else if (filter == PredefinedInstalledSourceFactory::Filter::Machine)\r\n            {\r\n                PopulateIndexFromMSIX(index, Manifest::ScopeEnum::Machine);\r\n            }\r\n\r\n            // Put Installed Fonts into the index.\r\n            if (filter == PredefinedInstalledSourceFactory::Filter::None || filter == PredefinedInstalledSourceFactory::Filter::ARP ||\r\n                filter == PredefinedInstalledSourceFactory::Filter::User || filter == PredefinedInstalledSourceFactory::Filter::Machine)\r\n            {\r\n                FontHelper fontHelper;\r\n                if (filter != PredefinedInstalledSourceFactory::Filter::User)\r\n                {\r\n                    fontHelper.PopulateIndex(index, Manifest::ScopeEnum::Machine);\r\n                }\r\n\r\n                if (filter != PredefinedInstalledSourceFactory::Filter::Machine)\r\n                {\r\n                    fontHelper.PopulateIndex(index, Manifest::ScopeEnum::User);\r\n                }\r\n            }\r\n\r\n            AICLI_LOG(Repo, Verbose, << \" ... finished creating PredefinedInstalledSource\");\r\n\r\n            return index;\r\n        }\r\n\r\n        struct CachedInstalledIndex\r\n        {\r\n            struct Singleton : public WinRT::COMStaticStorageBase<CachedInstalledIndex>\r\n            {\r\n                Singleton() : COMStaticStorageBase(L\"WindowsPackageManager.CachedInstalledIndex\") {}\r\n            };\r\n\r\n            CachedInstalledIndex()\r\n            {\r\n                ARPHelper arpHelper;\r\n                m_registryWatchers = arpHelper.CreateRegistryWatchers(Manifest::ScopeEnum::Unknown,\r\n                    [this](Manifest::ScopeEnum, Utility::Architecture, wil::RegistryChangeKind) { ForceNextUpdate(); });\r\n\r\n                FontHelper fontHelper;\r\n                fontHelper.AddRegistryWatchers(Manifest::ScopeEnum::Unknown,\r\n                    [this](Manifest::ScopeEnum, wil::RegistryChangeKind) { ForceNextUpdate(); }, m_registryWatchers);\r\n\r\n                m_catalog = winrt::Windows::ApplicationModel::PackageCatalog::OpenForCurrentUser();\r\n                m_eventRevoker = m_catalog.PackageStatusChanged(winrt::auto_revoke, [this](auto...) { ForceNextUpdate(); });\r\n            }\r\n\r\n            void UpdateIndexIfNeeded()\r\n            {\r\n                auto sharedLock = m_lock.lock_shared();\r\n                if (CheckForUpdate())\r\n                {\r\n                    // Upgrade to exclusive\r\n                    sharedLock.reset();\r\n                    auto exclusiveLock = m_lock.lock_exclusive();\r\n\r\n                    if (CheckForUpdate())\r\n                    {\r\n                        // TODO: To support servicing, the initial implementation of update will simply leverage\r\n                        //       some data from the existing index to speed up the MSIX populate function.\r\n                        //       In a larger update, we may want to make it possible to actually update the cache directly.\r\n                        //       We may even persist the cache to disk to speed things up further.\r\n\r\n                        // Set the update indicator to false before we start reading so that an external change can\r\n                        // reindicate a need to update in the middle. But in the event that we error here, set it back to true\r\n                        // to prevent an error from blocking further attempts.\r\n                        m_forceNextUpdate = false;\r\n                        auto scopeExit = wil::scope_exit([&]() { m_forceNextUpdate = true; });\r\n\r\n                        // Populate from ARP using standard mechanism.\r\n                        SQLiteIndex update = CreateAndPopulateIndex(PredefinedInstalledSourceFactory::Filter::ARP);\r\n\r\n                        // Populate from MSIX, using localization data from the existing index if applicable.\r\n                        PopulateIndexFromMSIX(update, Manifest::ScopeEnum::User, m_index.get());\r\n\r\n                        m_index = std::make_unique<SQLiteIndex>(std::move(update));\r\n                        scopeExit.release();\r\n                    }\r\n                }\r\n            }\r\n\r\n            SQLiteIndex GetCopy()\r\n            {\r\n                auto lock = m_lock.lock_shared();\r\n                THROW_HR_IF(E_POINTER, !m_index);\r\n                return SQLiteIndex::CopyFrom(SQLITE_MEMORY_DB_CONNECTION_TARGET, *m_index);\r\n            }\r\n\r\n            void ForceNextUpdate()\r\n            {\r\n                m_forceNextUpdate = true;\r\n            }\r\n\r\n        private:\r\n            bool CheckForUpdate()\r\n            {\r\n                return (!m_index || m_forceNextUpdate.load());\r\n            }\r\n\r\n            wil::srwlock m_lock;\r\n            std::atomic_bool m_forceNextUpdate{ false };\r\n            std::unique_ptr<SQLiteIndex> m_index;\r\n            std::vector<wil::unique_registry_watcher> m_registryWatchers;\r\n            winrt::Windows::ApplicationModel::PackageCatalog m_catalog = nullptr;\r\n            decltype(winrt::Windows::ApplicationModel::PackageCatalog{ nullptr }.PackageStatusChanged(winrt::auto_revoke, nullptr)) m_eventRevoker;\r\n        };\r\n\r\n        struct PredefinedInstalledSourceReference : public ISourceReference\r\n        {\r\n            PredefinedInstalledSourceReference(const SourceDetails& details) : m_details(details)\r\n            {\r\n                m_details.Identifier = \"*PredefinedInstalledSource\";\r\n\r\n                if (PredefinedInstalledSourceFactory::StringToFilter(m_details.Arg) == PredefinedInstalledSourceFactory::Filter::NoneWithForcedCacheUpdate)\r\n                {\r\n                    GetCachedInstalledIndex()->ForceNextUpdate();\r\n                }\r\n            }\r\n\r\n            std::string GetIdentifier() override { return m_details.Identifier; }\r\n\r\n            SourceDetails& GetDetails() override { return m_details; };\r\n\r\n            std::shared_ptr<ISource> Open(IProgressCallback& progress) override\r\n            {\r\n                // TODO: Maybe we do need to use it?\r\n                UNREFERENCED_PARAMETER(progress);\r\n\r\n                // Determine the filter\r\n                PredefinedInstalledSourceFactory::Filter filter = PredefinedInstalledSourceFactory::StringToFilter(m_details.Arg);\r\n\r\n                // Only cache for the unfiltered install data\r\n                if (filter == PredefinedInstalledSourceFactory::Filter::None || filter == PredefinedInstalledSourceFactory::Filter::NoneWithForcedCacheUpdate)\r\n                {\r\n                    std::shared_ptr<CachedInstalledIndex> cachedIndex = GetCachedInstalledIndex();\r\n                    cachedIndex->UpdateIndexIfNeeded();\r\n                    return std::make_shared<SQLiteIndexSource>(m_details, cachedIndex->GetCopy(), true);\r\n                }\r\n                else\r\n                {\r\n                    return std::make_shared<SQLiteIndexSource>(m_details, CreateAndPopulateIndex(filter), true);\r\n                }\r\n            }\r\n\r\n        private:\r\n            std::shared_ptr<CachedInstalledIndex> GetCachedInstalledIndex()\r\n            {\r\n                static CachedInstalledIndex::Singleton s_installedIndex;\r\n                return s_installedIndex.Get();\r\n            }\r\n\r\n            SourceDetails m_details;\r\n        };\r\n\r\n        // The factory for the predefined installed source.\r\n        struct Factory : public ISourceFactory\r\n        {\r\n            std::string_view TypeName() const override final\r\n            {\r\n                return PredefinedInstalledSourceFactory::Type();\r\n            }\r\n\r\n            std::shared_ptr<ISourceReference> Create(const SourceDetails& details) override final\r\n            {\r\n                THROW_HR_IF(E_INVALIDARG, details.Type != PredefinedInstalledSourceFactory::Type());\r\n\r\n                return std::make_shared<PredefinedInstalledSourceReference>(details);\r\n            }\r\n\r\n            bool Add(SourceDetails&, IProgressCallback&) override final\r\n            {\r\n                // Add should never be needed, as this is predefined.\r\n                THROW_HR(E_NOTIMPL);\r\n            }\r\n\r\n            bool Update(const SourceDetails&, IProgressCallback&) override final\r\n            {\r\n                // Update could be used later, but not for now.\r\n                THROW_HR(E_NOTIMPL);\r\n            }\r\n\r\n            bool Remove(const SourceDetails&, IProgressCallback&) override final\r\n            {\r\n                // Similar to add, remove should never be needed.\r\n                THROW_HR(E_NOTIMPL);\r\n            }\r\n        };\r\n    }\r\n\r\n    std::string_view PredefinedInstalledSourceFactory::FilterToString(Filter filter)\r\n    {\r\n        switch (filter)\r\n        {\r\n        case AppInstaller::Repository::Microsoft::PredefinedInstalledSourceFactory::Filter::None:\r\n            return \"None\"sv;\r\n        case AppInstaller::Repository::Microsoft::PredefinedInstalledSourceFactory::Filter::ARP:\r\n            return \"ARP\"sv;\r\n        case AppInstaller::Repository::Microsoft::PredefinedInstalledSourceFactory::Filter::MSIX:\r\n            return \"MSIX\"sv;\r\n        case AppInstaller::Repository::Microsoft::PredefinedInstalledSourceFactory::Filter::User:\r\n            return \"User\"sv;\r\n        case AppInstaller::Repository::Microsoft::PredefinedInstalledSourceFactory::Filter::Machine:\r\n            return \"Machine\"sv;\r\n        case AppInstaller::Repository::Microsoft::PredefinedInstalledSourceFactory::Filter::NoneWithForcedCacheUpdate:\r\n            return \"NoneWithForcedCacheUpdate\"sv;\r\n        default:\r\n            return \"Unknown\"sv;\r\n        }\r\n    }\r\n\r\n    PredefinedInstalledSourceFactory::Filter PredefinedInstalledSourceFactory::StringToFilter(std::string_view filter)\r\n    {\r\n        if (filter == FilterToString(Filter::ARP))\r\n        {\r\n            return Filter::ARP;\r\n        }\r\n        else if (filter == FilterToString(Filter::MSIX))\r\n        {\r\n            return Filter::MSIX;\r\n        }\r\n        else if (filter == FilterToString(Filter::User))\r\n        {\r\n            return Filter::User;\r\n        }\r\n        else if (filter == FilterToString(Filter::Machine))\r\n        {\r\n            return Filter::Machine;\r\n        }\r\n        else if (filter == FilterToString(Filter::NoneWithForcedCacheUpdate))\r\n        {\r\n            return Filter::NoneWithForcedCacheUpdate;\r\n        }\r\n        else\r\n        {\r\n            return Filter::None;\r\n        }\r\n    }\r\n\r\n    std::unique_ptr<ISourceFactory> PredefinedInstalledSourceFactory::Create()\r\n    {\r\n        return std::make_unique<Factory>();\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/PredefinedInstalledSourceFactory.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ISource.h\"\r\n#include \"SourceFactory.h\"\r\n\r\n#include <string_view>\r\n\r\nnamespace AppInstaller::Repository::Microsoft\r\n{\r\n    using namespace std::string_view_literals;\r\n\r\n    // A source of installed packages on the local system.\r\n    // Arg  ::  A value indicating how the list is to be filtered.\r\n    // Data ::  Not used.\r\n    struct PredefinedInstalledSourceFactory\r\n    {\r\n        // Get the type string for this source.\r\n        static constexpr std::string_view Type()\r\n        {\r\n            return \"Microsoft.Predefined.Installed\"sv;\r\n        }\r\n\r\n        // The filtering level for the source.\r\n        enum class Filter\r\n        {\r\n            // Contains user ARP, machine ARP, user MSIX, user Fonts and machine Fonts\r\n            None,\r\n            // Contains user ARP and machine ARP\r\n            ARP,\r\n            // Contains user MSIX\r\n            MSIX,\r\n            // Contains user ARP and user MSIX and user Fonts\r\n            User,\r\n            // Contains machine ARP and machine MSIX and machine Fonts\r\n            Machine,\r\n            // Same as None but creating the source reference causes the next Open to always update the cache\r\n            NoneWithForcedCacheUpdate,\r\n        };\r\n\r\n        // Converts a filter to its string.\r\n        static std::string_view FilterToString(Filter filter);\r\n\r\n        // Converts a string to its filter value.\r\n        static Filter StringToFilter(std::string_view filter);\r\n\r\n        // Creates a source factory for this type.\r\n        static std::unique_ptr<ISourceFactory> Create();\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/PredefinedWriteableSourceFactory.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Microsoft/ARPHelper.h\"\r\n#include \"Microsoft/PredefinedWriteableSourceFactory.h\"\r\n#include \"Microsoft/SQLiteIndex.h\"\r\n#include \"Microsoft/SQLiteIndexSource.h\"\r\n#include <winget/ManifestInstaller.h>\r\n\r\n#include <winget/Registry.h>\r\n#include <AppInstallerArchitecture.h>\r\n\r\nusing namespace std::string_literals;\r\nusing namespace std::string_view_literals;\r\n\r\nnamespace AppInstaller::Repository::Microsoft\r\n{\r\n    namespace\r\n    {\r\n        // The factory for the predefined installing source.\r\n        struct PredefinedWriteableSourceFactoryImpl : public ISourceFactory\r\n        {\r\n            std::string_view TypeName() const override final\r\n            {\r\n                return PredefinedWriteableSourceFactory::Type();\r\n            }\r\n\r\n            std::shared_ptr<ISourceReference> Create(const SourceDetails& details) override final;\r\n\r\n            bool Add(SourceDetails&, IProgressCallback&) override final\r\n            {\r\n                // Add should never be needed, as this is predefined.\r\n                THROW_HR(E_NOTIMPL);\r\n            }\r\n\r\n            bool Update(const SourceDetails&, IProgressCallback&) override final\r\n            {\r\n                // Update could be used later, but not for now.\r\n                THROW_HR(E_NOTIMPL);\r\n            }\r\n\r\n            bool Remove(const SourceDetails&, IProgressCallback&) override final\r\n            {\r\n                // Similar to add, remove should never be needed.\r\n                THROW_HR(E_NOTIMPL);\r\n            }\r\n        };\r\n\r\n        struct PredefinedWriteableSourceReference : public ISourceReference\r\n        {\r\n            PredefinedWriteableSourceReference(const SourceDetails& details) : m_details(details)\r\n            {\r\n                m_details.Identifier = \"*PredefinedWriteableSource\";\r\n            }\r\n\r\n            std::string GetIdentifier() override { return m_details.Identifier; }\r\n\r\n            SourceDetails& GetDetails() override { return m_details; };\r\n\r\n            std::shared_ptr<ISource> Open(IProgressCallback&) override\r\n            {\r\n                // Installing is the only type right now so just return the Installing source to all callers.\r\n                // Since the source is writeable, it must be shared by all callers that try to open it\r\n                // since queries on one instance would not see what was written on another instance.\r\n                std::call_once(g_InstallingSourceOnceFlag,\r\n                    [&]()\r\n                    {\r\n                        // Create an in memory index without paths or dependencies\r\n                        SQLiteIndex index = SQLiteIndex::CreateNew(SQLITE_MEMORY_DB_CONNECTION_TARGET, SQLite::Version::Latest(), SQLiteIndex::CreateOptions::SupportPathless | SQLiteIndex::CreateOptions::DisableDependenciesSupport);\r\n\r\n                        g_sharedSource = std::make_shared<SQLiteIndexWriteableSource>(m_details, std::move(index), true);\r\n                    });\r\n\r\n                return g_sharedSource;\r\n            }\r\n\r\n        private:\r\n            SourceDetails m_details;\r\n            static std::shared_ptr<ISource> g_sharedSource;\r\n            static std::once_flag g_InstallingSourceOnceFlag;\r\n        };\r\n\r\n        std::shared_ptr<ISource> PredefinedWriteableSourceReference::g_sharedSource = nullptr;\r\n        std::once_flag PredefinedWriteableSourceReference::g_InstallingSourceOnceFlag;\r\n\r\n        std::shared_ptr<ISourceReference> PredefinedWriteableSourceFactoryImpl::Create(const SourceDetails& details)\r\n        {\r\n            THROW_HR_IF(E_INVALIDARG, details.Type != PredefinedWriteableSourceFactory::Type());\r\n\r\n            return std::make_shared<PredefinedWriteableSourceReference>(details);\r\n        }\r\n    }\r\n\r\n    std::string_view PredefinedWriteableSourceFactory::TypeToString(WriteableType type)\r\n    {\r\n        switch (type)\r\n        {\r\n        case AppInstaller::Repository::Microsoft::PredefinedWriteableSourceFactory::WriteableType::Installing:\r\n            return \"Installing\"sv;\r\n        default:\r\n            return \"Unknown\"sv;\r\n        }\r\n    }\r\n\r\n    std::unique_ptr<ISourceFactory> PredefinedWriteableSourceFactory::Create()\r\n    {\r\n        return std::make_unique<PredefinedWriteableSourceFactoryImpl>();\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/PredefinedWriteableSourceFactory.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ISource.h\"\r\n#include \"SourceFactory.h\"\r\n\r\n#include <string_view>\r\n\r\nnamespace AppInstaller::Repository::Microsoft\r\n{\r\n    using namespace std::string_view_literals;\r\n    \r\n    // A source of installing packages on the local system.\r\n    // Arg  ::  A value indicating the type of writeable source\r\n    // Data ::  Not used.\r\n    struct PredefinedWriteableSourceFactory\r\n    {\r\n        // Get the type string for this source.\r\n        static constexpr std::string_view Type()\r\n        {\r\n            return \"Microsoft.Predefined.Writeable\"sv;\r\n        }\r\n\r\n        // The type for the source.\r\n        enum class WriteableType\r\n        {\r\n            Installing\r\n        };\r\n\r\n        // Converts a type to its string.\r\n        static std::string_view TypeToString(WriteableType type);\r\n\r\n        // Creates a source factory for this type.\r\n        static std::unique_ptr<ISourceFactory> Create();\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/README.md",
    "content": "### Design\r\nThe object stack is as such:\r\n- SQLiteIndex :: Houses the database connection and the proper interface with which to interact with it\r\n- ISQLiteIndex :: Interface that creates a uniform model to use against all schemas\r\n- Schema::V*::Interface :: Actual implementation of ISQLiteIndex for specific schema version\r\n\r\nThe code that needs to interact with an index will create a SQLiteIndex object.  That in turn will open the database, determine the schema version, then create the appropriate ISQLiteIndex providing object.  All queries and changes to the index will go through the SQLiteIndex object.\r\n\r\nWhen a change to the schema is needed, a new schema directory should be created.  This can pull code from the schemas before it, only updating the specific table(s) that are needed.  Then Version code should be updated to create the new Interface as appropriate.  Any new methods needed on ISQLiteIndex should be added, and SQLiteIndexBase to implement them in terms of the older functions.  Only the new schema should need to implement the new functions.   **Once shipped, one should never need to update code within an existing schema, save for bug fixes.**\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/SQLiteIndex.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"SQLiteIndex.h\"\r\n#include <winget/SQLiteStorageBase.h>\r\n#include \"ArpVersionValidation.h\"\r\n#include <winget/ManifestYamlParser.h>\r\n\r\nnamespace AppInstaller::Repository::Microsoft\r\n{\r\n    namespace\r\n    {\r\n        size_t GetPageSizeFromOptions(SQLiteIndex::CreateOptions options)\r\n        {\r\n            return WI_IsFlagSet(options, SQLiteIndex::CreateOptions::LargePageSize) ? 65536 : 0;\r\n        }\r\n    }\r\n\r\n    SQLiteIndex SQLiteIndex::CreateNew(const std::string& filePath, SQLite::Version version, CreateOptions options)\r\n    {\r\n        AICLI_LOG(Repo, Info, << \"Creating new SQLite Index with version [\" << version << \"] at '\" << filePath << \"'\");\r\n        SQLiteIndex result{ filePath, version, options };\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(result.m_dbconn, \"sqliteindex_createnew\");\r\n\r\n        // Use calculated version, as incoming version could be 'latest'\r\n        result.m_version.SetSchemaVersion(result.m_dbconn);\r\n\r\n        result.m_interface->CreateTables(result.m_dbconn, options);\r\n\r\n        result.SetLastWriteTime();\r\n\r\n        savepoint.Commit();\r\n\r\n        return result;\r\n    }\r\n\r\n    SQLiteIndex SQLiteIndex::Open(const std::string& filePath, OpenDisposition disposition, Utility::ManagedFile&& indexFile)\r\n    {\r\n        return { filePath, disposition, std::move(indexFile) };\r\n    }\r\n\r\n    SQLiteIndex SQLiteIndex::CopyFrom(const std::string& filePath, SQLiteIndex& source)\r\n    {\r\n        return { filePath, source };\r\n    }\r\n\r\n    SQLiteIndex::SQLiteIndex(const std::string& target, const SQLite::Version& version, CreateOptions options) : SQLiteStorageBase(target, version, GetPageSizeFromOptions(options))\r\n    {\r\n        m_dbconn.EnableICU();\r\n        m_interface = Schema::CreateISQLiteIndex(version);\r\n        m_version = m_interface->GetVersion();\r\n        SetDatabaseFilePath(target);\r\n    }\r\n\r\n    SQLiteIndex::SQLiteIndex(const std::string& target, SQLiteStorageBase::OpenDisposition disposition, Utility::ManagedFile&& indexFile) :\r\n        SQLiteStorageBase(target, disposition, std::move(indexFile))\r\n    {\r\n        m_dbconn.EnableICU();\r\n        AICLI_LOG(Repo, Info, << \"Opened SQLite Index with version [\" << m_version << \"], last write [\" << GetLastWriteTime() << \"]\");\r\n        m_interface = Schema::CreateISQLiteIndex(m_version);\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX, disposition == SQLiteStorageBase::OpenDisposition::ReadWrite && m_version != m_interface->GetVersion());\r\n        SetDatabaseFilePath(target);\r\n    }\r\n\r\n    SQLiteIndex::SQLiteIndex(const std::string& target, SQLiteIndex& source) :\r\n        SQLiteStorageBase(target, source)\r\n    {\r\n        m_dbconn.EnableICU();\r\n        m_interface = Schema::CreateISQLiteIndex(m_version);\r\n        SetDatabaseFilePath(target);\r\n    }\r\n\r\n    void SQLiteIndex::SetDatabaseFilePath(const std::string& target)\r\n    {\r\n        if (target != SQLITE_MEMORY_DB_CONNECTION_TARGET)\r\n        {\r\n            m_contextData.Add<Schema::Property::DatabaseFilePath>(Utility::ConvertToUTF16(target));\r\n        }\r\n    }\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n    void SQLiteIndex::ForceVersion(const SQLite::Version& version)\r\n    {\r\n        m_interface = Schema::CreateISQLiteIndex(version);\r\n    }\r\n\r\n    SQLite::Version SQLiteIndex::GetLatestVersion()\r\n    {\r\n        return Schema::CreateISQLiteIndex(SQLite::Version::Latest())->GetVersion();\r\n    }\r\n\r\n    const Schema::SQLiteIndexContextData& SQLiteIndex::GetContextData() const\r\n    {\r\n        return m_contextData;\r\n    }\r\n#endif\r\n\r\n    SQLiteIndex::IdType SQLiteIndex::AddManifest(const std::filesystem::path& manifestPath, const std::filesystem::path& relativePath)\r\n    {\r\n        AICLI_LOG(Repo, Verbose, << \"Adding manifest from file [\" << manifestPath << \"]\");\r\n\r\n        Manifest::Manifest manifest = Manifest::YamlParser::CreateFromPath(manifestPath);\r\n        return AddManifestInternal(manifest, relativePath);\r\n    }\r\n\r\n    SQLiteIndex::IdType SQLiteIndex::AddManifest(const Manifest::Manifest& manifest, const std::filesystem::path& relativePath)\r\n    {\r\n        return AddManifestInternal(manifest, relativePath);\r\n    }\r\n\r\n    SQLiteIndex::IdType SQLiteIndex::AddManifest(const Manifest::Manifest& manifest)\r\n    {\r\n        return AddManifestInternal(manifest, {});\r\n    }\r\n\r\n    SQLiteIndex::IdType SQLiteIndex::AddManifestInternal(const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath)\r\n    {\r\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\r\n        return AddManifestInternalHoldingLock(manifest, relativePath);\r\n    }\r\n\r\n    SQLiteIndex::IdType SQLiteIndex::AddManifestInternalHoldingLock(const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath)\r\n    {\r\n        AICLI_LOG(Repo, Verbose, << \"Adding manifest for [\" << manifest.Id << \", \" << manifest.Version << \"] at relative path [\" << relativePath.value_or(\"\") << \"]\");\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(m_dbconn, \"sqliteindex_addmanifest\");\r\n\r\n        IdType result = m_interface->AddManifest(m_dbconn, manifest, relativePath);\r\n\r\n        SetLastWriteTime();\r\n\r\n        savepoint.Commit();\r\n\r\n        return result;\r\n    }\r\n\r\n    bool SQLiteIndex::UpdateManifest(const std::filesystem::path& manifestPath, const std::filesystem::path& relativePath)\r\n    {\r\n        AICLI_LOG(Repo, Verbose, << \"Updating manifest from file [\" << manifestPath << \"]\");\r\n\r\n        Manifest::Manifest manifest = Manifest::YamlParser::CreateFromPath(manifestPath);\r\n        return UpdateManifestInternal(manifest, relativePath);\r\n    }\r\n\r\n    bool SQLiteIndex::UpdateManifest(const Manifest::Manifest& manifest, const std::filesystem::path& relativePath)\r\n    {\r\n        return UpdateManifestInternal(manifest, relativePath);\r\n    }\r\n\r\n    bool SQLiteIndex::UpdateManifest(const Manifest::Manifest& manifest)\r\n    {\r\n        return UpdateManifestInternal(manifest, {});\r\n    }\r\n\r\n    bool SQLiteIndex::UpdateManifestInternal(const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath)\r\n    {\r\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\r\n        return UpdateManifestInternalHoldingLock(manifest, relativePath);\r\n    }\r\n\r\n    bool SQLiteIndex::UpdateManifestInternalHoldingLock(const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath)\r\n    {\r\n        AICLI_LOG(Repo, Verbose, << \"Updating manifest for [\" << manifest.Id << \", \" << manifest.Version << \"] at relative path [\" << relativePath.value_or(\"\") << \"]\");\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(m_dbconn, \"sqliteindex_updatemanifest\");\r\n\r\n        bool result = m_interface->UpdateManifest(m_dbconn, manifest, relativePath).first;\r\n\r\n        if (result)\r\n        {\r\n            SetLastWriteTime();\r\n\r\n            savepoint.Commit();\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    bool SQLiteIndex::AddOrUpdateManifest(const std::filesystem::path& manifestPath, const std::filesystem::path& relativePath)\r\n    {\r\n        AICLI_LOG(Repo, Verbose, << \"Adding or Updating manifest from file [\" << manifestPath << \"]\");\r\n\r\n        Manifest::Manifest manifest = Manifest::YamlParser::CreateFromPath(manifestPath);\r\n        return AddOrUpdateManifestInternal(manifest, relativePath);\r\n    }\r\n\r\n    bool SQLiteIndex::AddOrUpdateManifest(const Manifest::Manifest& manifest, const std::filesystem::path& relativePath)\r\n    {\r\n        return AddOrUpdateManifestInternal(manifest, relativePath);\r\n    }\r\n\r\n    bool SQLiteIndex::AddOrUpdateManifest(const Manifest::Manifest& manifest)\r\n    {\r\n        return AddOrUpdateManifestInternal(manifest, {});\r\n    }\r\n\r\n    bool SQLiteIndex::AddOrUpdateManifestInternal(const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath)\r\n    {\r\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\r\n        AICLI_LOG(Repo, Verbose, << \"Adding or Updating manifest for [\" << manifest.Id << \", \" << manifest.Version << \"] at relative path [\" << relativePath.value_or(\"\") << \"]\");\r\n\r\n        if (m_interface->GetManifestIdByManifest(m_dbconn, manifest))\r\n        {\r\n            UpdateManifestInternalHoldingLock(manifest, relativePath);\r\n            return false;\r\n        }\r\n        else\r\n        {\r\n            AddManifestInternalHoldingLock(manifest, relativePath);\r\n            return true;\r\n        }\r\n    }\r\n\r\n    void SQLiteIndex::RemoveManifest(const std::filesystem::path& manifestPath, const std::filesystem::path& relativePath)\r\n    {\r\n        AICLI_LOG(Repo, Verbose, << \"Removing manifest from file [\" << manifestPath << \"]\");\r\n\r\n        Manifest::Manifest manifest = Manifest::YamlParser::CreateFromPath(manifestPath);\r\n        RemoveManifest(manifest, relativePath);\r\n    }\r\n\r\n    void SQLiteIndex::RemoveManifest(const Manifest::Manifest& manifest, const std::filesystem::path& relativePath)\r\n    {\r\n        AICLI_LOG(Repo, Verbose, << \"Removing manifest for [\" << manifest.Id << \", \" << manifest.Version << \"] at relative path [\" << relativePath << \"]\");\r\n        RemoveManifest(manifest);\r\n    }\r\n\r\n    void SQLiteIndex::RemoveManifest(const Manifest::Manifest& manifest)\r\n    {\r\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(m_dbconn, \"sqliteindex_removemanifest\");\r\n\r\n        m_interface->RemoveManifest(m_dbconn, manifest);\r\n\r\n        SetLastWriteTime();\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    void SQLiteIndex::RemoveManifestById(IdType manifestId)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(m_dbconn, \"SQLiteIndex_RemoveManifestById\");\r\n\r\n        m_interface->RemoveManifestById(m_dbconn, manifestId);\r\n\r\n        SetLastWriteTime();\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    void SQLiteIndex::PrepareForPackaging()\r\n    {\r\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\r\n        AICLI_LOG(Repo, Info, << \"Preparing index for packaging\");\r\n\r\n        m_interface->PrepareForPackaging(Schema::SQLiteIndexContext{ m_dbconn, m_contextData });\r\n    }\r\n\r\n    bool SQLiteIndex::CheckConsistency(bool log) const\r\n    {\r\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\r\n        AICLI_LOG(Repo, Info, << \"Checking index consistency...\");\r\n\r\n        bool result = m_interface->CheckConsistency(m_dbconn, log);\r\n\r\n        AICLI_LOG(Repo, Info, << \"...index *WAS\" << (result ? \"*\" : \" NOT*\") << \" consistent.\");\r\n\r\n        return result;\r\n    }\r\n\r\n    Schema::ISQLiteIndex::SearchResult SQLiteIndex::Search(const SearchRequest& request) const\r\n    {\r\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\r\n        AICLI_LOG(Repo, Verbose, << \"Performing search: \" << request.ToString());\r\n\r\n        return m_interface->Search(m_dbconn, request);\r\n    }\r\n\r\n    std::optional<std::string> SQLiteIndex::GetPropertyByPrimaryId(IdType primaryId, PackageVersionProperty property) const\r\n    {\r\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\r\n        return m_interface->GetPropertyByPrimaryId(m_dbconn, primaryId, property);\r\n    }\r\n\r\n    std::vector<std::string> SQLiteIndex::GetMultiPropertyByPrimaryId(IdType primaryId, PackageVersionMultiProperty property) const\r\n    {\r\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\r\n        return m_interface->GetMultiPropertyByPrimaryId(m_dbconn, primaryId, property);\r\n    }\r\n\r\n    std::optional<SQLiteIndex::IdType> SQLiteIndex::GetManifestIdByKey(IdType id, std::string_view version, std::string_view channel) const\r\n    {\r\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\r\n        return m_interface->GetManifestIdByKey(m_dbconn, id, version, channel);\r\n    }\r\n\r\n    std::optional<SQLiteIndex::IdType> SQLiteIndex::GetManifestIdByManifest(const Manifest::Manifest& manifest) const\r\n    {\r\n        return m_interface->GetManifestIdByManifest(m_dbconn, manifest);\r\n    }\r\n\r\n    std::vector<SQLiteIndex::VersionKey> SQLiteIndex::GetVersionKeysById(IdType id) const\r\n    {\r\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\r\n        return m_interface->GetVersionKeysById(m_dbconn, id);\r\n    }\r\n\r\n    SQLiteIndex::MetadataResult SQLiteIndex::GetMetadataByManifestId(SQLite::rowid_t manifestId) const\r\n    {\r\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\r\n        return m_interface->GetMetadataByManifestId(m_dbconn, manifestId);\r\n    }\r\n\r\n    void SQLiteIndex::SetMetadataByManifestId(IdType manifestId, PackageVersionMetadata metadata, std::string_view value)\r\n    {\r\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\r\n        m_interface->SetMetadataByManifestId(m_dbconn, manifestId, metadata, value);\r\n    }\r\n\r\n    Utility::NormalizedName SQLiteIndex::NormalizeName(std::string_view name, std::string_view publisher) const\r\n    {\r\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\r\n        return m_interface->NormalizeName(name, publisher);\r\n    }\r\n\r\n    std::set<std::pair<SQLite::rowid_t, Utility::NormalizedString>> SQLiteIndex::GetDependenciesByManifestRowId(SQLite::rowid_t manifestRowId) const\r\n    {\r\n        return m_interface->GetDependenciesByManifestRowId(m_dbconn, manifestRowId);\r\n    }\r\n\r\n    std::vector<std::pair<SQLite::rowid_t, Utility::NormalizedString>> SQLiteIndex::GetDependentsById(AppInstaller::Manifest::string_t packageId) const\r\n    {\r\n        return m_interface->GetDependentsById(m_dbconn, packageId);\r\n    }\r\n\r\n    bool SQLiteIndex::MigrateTo(SQLite::Version version)\r\n    {\r\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(m_dbconn, \"sqliteindex_migrate_to\");\r\n\r\n        AICLI_LOG(Repo, Info, << \"Attempting to migrate index from [\" << m_interface->GetVersion() << \"] to [\" << version << \"]...\");\r\n        std::unique_ptr<Schema::ISQLiteIndex> newInterface = Schema::CreateISQLiteIndex(version);\r\n\r\n        bool result = newInterface->MigrateFrom(m_dbconn, m_interface.get());\r\n\r\n        AICLI_LOG(Repo, Info, << \"...migration was \" << (result ? \"\" : \"NOT \") << \"successful\");\r\n        if (result)\r\n        {\r\n            version.SetSchemaVersion(m_dbconn);\r\n            SetLastWriteTime();\r\n            savepoint.Commit();\r\n\r\n            m_version = version;\r\n            m_interface = std::move(newInterface);\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    void SQLiteIndex::SetProperty(Property property, const std::string& value)\r\n    {\r\n        std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };\r\n\r\n        switch (property)\r\n        {\r\n        case Property::PackageUpdateTrackingBaseTime:\r\n            m_interface->SetProperty(m_dbconn, Schema::Property::PackageUpdateTrackingBaseTime, value);\r\n            break;\r\n        case Property::IntermediateFileOutputPath:\r\n        {\r\n            std::filesystem::path pathValue{ Utility::ConvertToUTF16(value) };\r\n            THROW_HR_IF(E_INVALIDARG, pathValue.empty() || pathValue.is_relative());\r\n            m_contextData.Add<Schema::Property::IntermediateFileOutputPath>(std::move(pathValue));\r\n        }\r\n            break;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/SQLiteIndex.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteWrapper.h>\r\n#include \"Microsoft/Schema/ISQLiteIndex.h\"\r\n#include <winget/SQLiteVersion.h>\r\n#include <winget/SQLiteStorageBase.h>\r\n#include \"ISource.h\"\r\n#include <AppInstallerLanguageUtilities.h>\r\n#include <AppInstallerVersions.h>\r\n#include <winget/Manifest.h>\r\n#include <winget/NameNormalization.h>\r\n#include <winget/ManagedFile.h>\r\n\r\n#include <filesystem>\r\n#include <limits>\r\n#include <memory>\r\n#include <optional>\r\n#include <string>\r\n#include <utility>\r\n#include <vector>\r\n\r\nnamespace AppInstaller::Repository::Microsoft\r\n{\r\n    // Holds the connection to the database, as well as the appropriate functionality to interface with it.\r\n    struct SQLiteIndex : SQLite::SQLiteStorageBase\r\n    {\r\n        // An id that refers to a specific application.\r\n        using IdType = SQLite::rowid_t;\r\n\r\n        // The return type of Search\r\n        using SearchResult = Schema::ISQLiteIndex::SearchResult;\r\n\r\n        // The return type of GetMetadataByManifestId\r\n        using MetadataResult = Schema::ISQLiteIndex::MetadataResult;\r\n\r\n        // Options for creating a new index.\r\n        using CreateOptions = Schema::ISQLiteIndex::CreateOptions;\r\n\r\n        // The type of version keys.\r\n        using VersionKey = Schema::ISQLiteIndex::VersionKey;\r\n\r\n        SQLiteIndex(const SQLiteIndex&) = delete;\r\n        SQLiteIndex& operator=(const SQLiteIndex&) = delete;\r\n\r\n        SQLiteIndex(SQLiteIndex&&) = default;\r\n        SQLiteIndex& operator=(SQLiteIndex&&) = default;\r\n\r\n        // Creates a new index database of the given version.\r\n        static SQLiteIndex CreateNew(const std::string& filePath, SQLite::Version version = SQLite::Version::Latest(), CreateOptions options = CreateOptions::None);\r\n\r\n        // Opens an existing SQLiteIndex database.\r\n        static SQLiteIndex Open(const std::string& filePath, OpenDisposition disposition, Utility::ManagedFile&& indexFile = {});\r\n\r\n        // Creates a copy of the given index.\r\n        static SQLiteIndex CopyFrom(const std::string& filePath, SQLiteIndex& source);\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        // Changes the version of the interface being used to operate on the database.\r\n        // Should only be used for testing.\r\n        void ForceVersion(const SQLite::Version& version);\r\n\r\n        // Gets the latest version of the index schema (the actual numbers, not just the latest sentinel values).\r\n        static SQLite::Version GetLatestVersion();\r\n\r\n        // Gets the context data for testing.\r\n        const Schema::SQLiteIndexContextData& GetContextData() const;\r\n#endif\r\n\r\n        // Adds the manifest at the repository relative path to the index.\r\n        // If the function succeeds, the manifest has been added.\r\n        // Returns the manifest id.\r\n        IdType AddManifest(const std::filesystem::path& manifestPath, const std::filesystem::path& relativePath);\r\n\r\n        // Adds the manifest at the repository relative path to the index.\r\n        // If the function succeeds, the manifest has been added.\r\n        // Returns the manifest id.\r\n        IdType AddManifest(const Manifest::Manifest& manifest, const std::filesystem::path& relativePath);\r\n\r\n        // Adds the manifest to the index.\r\n        // If the function succeeds, the manifest has been added.\r\n        // Returns the manifest id.\r\n        IdType AddManifest(const Manifest::Manifest& manifest);\r\n\r\n        // Updates the manifest with matching { Id, Version, Channel } in the index.\r\n        // The return value indicates whether the index was modified by the function.\r\n        bool UpdateManifest(const std::filesystem::path& manifestPath, const std::filesystem::path& relativePath);\r\n\r\n        // Updates the manifest with matching { Id, Version, Channel } in the index.\r\n        // The return value indicates whether the index was modified by the function.\r\n        bool UpdateManifest(const Manifest::Manifest& manifest, const std::filesystem::path& relativePath);\r\n\r\n        // Updates the manifest with matching { Id, Version, Channel } in the index.\r\n        // The return value indicates whether the index was modified by the function.\r\n        bool UpdateManifest(const Manifest::Manifest& manifest);\r\n\r\n        // Adds or updates the manifest with matching { Id, Version, Channel } in the index.\r\n        // The return value indicates whether the manifest was added (true) or updated (false).\r\n        bool AddOrUpdateManifest(const std::filesystem::path& manifestPath, const std::filesystem::path& relativePath);\r\n\r\n        // Updates the manifest with matching { Id, Version, Channel } in the index.\r\n        // The return value indicates whether the manifest was added (true) or updated (false).\r\n        bool AddOrUpdateManifest(const Manifest::Manifest& manifest, const std::filesystem::path& relativePath);\r\n\r\n        // Updates the manifest with matching { Id, Version, Channel } in the index.\r\n        // The return value indicates whether the manifest was added (true) or updated (false).\r\n        bool AddOrUpdateManifest(const Manifest::Manifest& manifest);\r\n\r\n        // Removes the manifest with matching { Id, Version, Channel } from the index.\r\n        void RemoveManifest(const std::filesystem::path& manifestPath, const std::filesystem::path& relativePath);\r\n\r\n        // Removes the manifest with matching { Id, Version, Channel } from the index.\r\n        void RemoveManifest(const Manifest::Manifest& manifest, const std::filesystem::path& relativePath);\r\n        \r\n        // Removes the manifest with matching { Id, Version, Channel } from the index.\r\n        void RemoveManifest(const Manifest::Manifest& manifest);\r\n\r\n        // Removes the manifest with the given id.\r\n        void RemoveManifestById(IdType manifestId);\r\n\r\n        // Removes data that is no longer needed for an index that is to be published.\r\n        void PrepareForPackaging();\r\n\r\n        // Checks the consistency of the index to ensure that every referenced row exists.\r\n        // Returns true if index is consistent; false if it is not.\r\n        bool CheckConsistency(bool log = false) const;\r\n\r\n        // Performs a search based on the given criteria.\r\n        SearchResult Search(const SearchRequest& request) const;\r\n\r\n        // Gets the string for the given property and primary id, if present.\r\n        std::optional<std::string> GetPropertyByPrimaryId(IdType primaryId, PackageVersionProperty property) const;\r\n\r\n        // Gets the string values for the given property and primary id, if present.\r\n        std::vector<std::string> GetMultiPropertyByPrimaryId(IdType primaryId, PackageVersionMultiProperty property) const;\r\n\r\n        // Gets the manifest id for the given { id, version, channel }, if present.\r\n        // If version is empty, gets the value for the 'latest' version.\r\n        std::optional<IdType> GetManifestIdByKey(IdType id, std::string_view version, std::string_view channel) const;\r\n\r\n        // Gets the manifest id for the given manifest, if present.\r\n        std::optional<IdType> GetManifestIdByManifest(const Manifest::Manifest& manifest) const;\r\n\r\n        // Gets all versions and channels for the given id.\r\n        std::vector<VersionKey> GetVersionKeysById(IdType id) const;\r\n\r\n        // Gets the string for the given metadata and manifest id, if present.\r\n        MetadataResult GetMetadataByManifestId(SQLite::rowid_t manifestId) const;\r\n\r\n        // Sets the string for the given metadata and manifest id.\r\n        void SetMetadataByManifestId(IdType manifestId, PackageVersionMetadata metadata, std::string_view value);\r\n\r\n        // Normalizes a name using the internal rules used by the index.\r\n        // Largely a utility function; should not be used to do work on behalf of the index by the caller.\r\n        Utility::NormalizedName NormalizeName(std::string_view name, std::string_view publisher) const;\r\n\r\n        // Get all the dependencies for a specific manifest.\r\n        std::set<std::pair<SQLite::rowid_t, Utility::NormalizedString>> GetDependenciesByManifestRowId(SQLite::rowid_t manifestRowId) const;\r\n        std::vector<std::pair<SQLite::rowid_t, Utility::NormalizedString>> GetDependentsById(AppInstaller::Manifest::string_t packageId) const;\r\n\r\n        // Migrates the index to the target version.\r\n        // Returns false to indicate that the requested migration is not supported.\r\n        bool MigrateTo(SQLite::Version version);\r\n\r\n        // The property values that can be set.\r\n        enum class Property\r\n        {\r\n            PackageUpdateTrackingBaseTime,\r\n            IntermediateFileOutputPath,\r\n        };\r\n\r\n        // Sets the given property.\r\n        // Some properties will persist into the database.\r\n        void SetProperty(Property property, const std::string& value);\r\n\r\n    private:\r\n        // Constructor used to create a new index.\r\n        SQLiteIndex(const std::string& target, const SQLite::Version& version, CreateOptions options);\r\n\r\n        // Constructor used to open an existing index.\r\n        SQLiteIndex(const std::string& target, SQLiteStorageBase::OpenDisposition disposition, Utility::ManagedFile&& indexFile);\r\n\r\n        // Constructor used to copy the given index.\r\n        SQLiteIndex(const std::string& target, SQLiteIndex& source);\r\n\r\n        // Sets the database file path in the context data if appropriate.\r\n        void SetDatabaseFilePath(const std::string& target);\r\n\r\n        // Internal functions to normalize on the relativePath being present.\r\n        IdType AddManifestInternal(const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath);\r\n        IdType AddManifestInternalHoldingLock(const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath);\r\n        bool UpdateManifestInternal(const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath);\r\n        bool UpdateManifestInternalHoldingLock(const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath);\r\n        bool AddOrUpdateManifestInternal(const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath);\r\n\r\n        std::unique_ptr<Schema::ISQLiteIndex> m_interface;\r\n        Schema::SQLiteIndexContextData m_contextData;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/SQLiteIndexSource.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Microsoft/SQLiteIndexSource.h\"\r\n#include \"Microsoft/SQLiteIndexSourceV1.h\"\r\n#include \"Microsoft/SQLiteIndexSourceV2.h\"\r\n#include \"Microsoft/PreIndexedPackageSourceFactory.h\"\r\n#include <winget/ManifestYamlParser.h>\r\n#include <winget/PackageVersionDataManifest.h>\r\n\r\nusing namespace AppInstaller::Utility;\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft\r\n{\r\n    namespace details\r\n    {\r\n        SourceReference::SourceReference(const std::shared_ptr<SQLiteIndexSource>& source) :\r\n            m_source(source) {}\r\n\r\n        std::shared_ptr<SQLiteIndexSource> SourceReference::GetReferenceSource() const\r\n        {\r\n            std::shared_ptr<SQLiteIndexSource> source = m_source.lock();\r\n            THROW_HR_IF(E_NOT_VALID_STATE, !source);\r\n            return source;\r\n        }\r\n    }\r\n\r\n    SQLiteIndexSource::SQLiteIndexSource(\r\n        const SourceDetails& details,\r\n        SQLiteIndex&& index,\r\n        bool isInstalledSource,\r\n        bool requireManifestHash) :\r\n        m_details(details), m_isInstalled(isInstalledSource), m_index(std::move(index)), m_requireManifestHash(requireManifestHash)\r\n    {\r\n        std::vector<std::string> cacheSources;\r\n        cacheSources.push_back(m_details.Arg);\r\n        if (!m_details.AlternateArg.empty())\r\n        {\r\n            cacheSources.push_back(m_details.AlternateArg);\r\n        }\r\n\r\n        switch (m_index.GetVersion().MajorVersion)\r\n        {\r\n        case 1:\r\n            m_manifestCache = std::make_shared<Caching::FileCache>(Caching::FileCache::Type::IndexV1_Manifest, m_details.Identifier, std::move(cacheSources));\r\n            break;\r\n        case 2:\r\n            m_manifestCache = std::make_shared<Caching::FileCache>(Caching::FileCache::Type::IndexV2_Manifest, m_details.Identifier, cacheSources);\r\n            m_packageVersionDataCache = std::make_shared<Caching::FileCache>(Caching::FileCache::Type::IndexV2_PackageVersionData, m_details.Identifier, std::move(cacheSources));\r\n            break;\r\n        default:\r\n            THROW_WIN32(ERROR_NOT_SUPPORTED);\r\n        }\r\n    }\r\n\r\n    const SourceDetails& SQLiteIndexSource::GetDetails() const\r\n    {\r\n        return m_details;\r\n    }\r\n\r\n    const std::string& SQLiteIndexSource::GetIdentifier() const\r\n    {\r\n        return m_details.Identifier;\r\n    }\r\n\r\n    SearchResult SQLiteIndexSource::Search(const SearchRequest& request) const\r\n    {\r\n        auto indexResults = m_index.Search(request);\r\n\r\n        SearchResult result;\r\n        std::shared_ptr<SQLiteIndexSource> sharedThis = NonConstSharedFromThis();\r\n        uint32_t majorVersion = m_index.GetVersion().MajorVersion;\r\n\r\n        for (auto& indexResult : indexResults.Matches)\r\n        {\r\n            std::shared_ptr<ICompositePackage> package;\r\n\r\n            switch (majorVersion)\r\n            {\r\n            case 1:\r\n                package = std::make_shared<details::V1::SQLitePackage>(sharedThis, indexResult.first, m_manifestCache, m_isInstalled);\r\n                break;\r\n            case 2:\r\n                package = std::make_shared<details::V2::SQLitePackage>(sharedThis, indexResult.first, m_manifestCache, m_packageVersionDataCache, m_isInstalled);\r\n                break;\r\n            default:\r\n                THROW_WIN32(ERROR_NOT_SUPPORTED);\r\n            }\r\n\r\n            result.Matches.emplace_back(\r\n                std::move(package),\r\n                std::move(indexResult.second));\r\n        }\r\n\r\n        result.Truncated = indexResults.Truncated;\r\n        return result;\r\n    }\r\n\r\n    void* SQLiteIndexSource::CastTo(ISourceType type)\r\n    {\r\n        if (type == SourceType)\r\n        {\r\n            return this;\r\n        }\r\n\r\n        return nullptr;\r\n    }\r\n\r\n    bool SQLiteIndexSource::IsSame(const SQLiteIndexSource* other) const\r\n    {\r\n        return (other && GetIdentifier() == other->GetIdentifier());\r\n    }\r\n\r\n    std::shared_ptr<SQLiteIndexSource> SQLiteIndexSource::NonConstSharedFromThis() const\r\n    {\r\n        return const_cast<SQLiteIndexSource*>(this)->shared_from_this();\r\n    }\r\n\r\n    SQLiteIndexWriteableSource::SQLiteIndexWriteableSource(const SourceDetails& details, SQLiteIndex&& index, bool isInstalledSource) :\r\n        SQLiteIndexSource(details, std::move(index), isInstalledSource)\r\n    {\r\n    }\r\n\r\n    void* SQLiteIndexWriteableSource::CastTo(ISourceType type)\r\n    {\r\n        if (type == ISourceType::IMutablePackageSource)\r\n        {\r\n            return static_cast<IMutablePackageSource*>(this);\r\n        }\r\n\r\n        return SQLiteIndexSource::CastTo(type);\r\n    }\r\n\r\n    void SQLiteIndexWriteableSource::AddPackageVersion(const Manifest::Manifest& manifest, const std::filesystem::path& relativePath)\r\n    {\r\n        m_index.AddManifest(manifest, relativePath);\r\n    }\r\n    \r\n    void SQLiteIndexWriteableSource::RemovePackageVersion(const Manifest::Manifest& manifest, const std::filesystem::path& relativePath)\r\n    {\r\n        m_index.RemoveManifest(manifest, relativePath);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/SQLiteIndexSource.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/SQLiteIndex.h\"\r\n#include \"ISource.h\"\r\n#include <winget/FileCache.h>\r\n#include <memory>\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft\r\n{\r\n    // A source that holds a SQLiteIndex and lock.\r\n    struct SQLiteIndexSource : public std::enable_shared_from_this<SQLiteIndexSource>, public ISource\r\n    {\r\n        static constexpr ISourceType SourceType = ISourceType::SQLiteIndexSource;\r\n\r\n        SQLiteIndexSource(\r\n            const SourceDetails& details,\r\n            SQLiteIndex&& index,\r\n            bool isInstalledSource = false, \r\n            bool requireManifestHash = false);\r\n\r\n        SQLiteIndexSource(const SQLiteIndexSource&) = delete;\r\n        SQLiteIndexSource& operator=(const SQLiteIndexSource&) = delete;\r\n\r\n        SQLiteIndexSource(SQLiteIndexSource&&) = default;\r\n        SQLiteIndexSource& operator=(SQLiteIndexSource&&) = default;\r\n\r\n        ~SQLiteIndexSource() = default;\r\n\r\n        // Get the source's details.\r\n        const SourceDetails& GetDetails() const override;\r\n\r\n        // Gets the source's identifier; a unique identifier independent of the name\r\n        // that will not change between a remove/add or between additional adds.\r\n        // Must be suitable for filesystem names.\r\n        const std::string& GetIdentifier() const override;\r\n\r\n        // Execute a search on the source.\r\n        SearchResult Search(const SearchRequest& request) const override;\r\n\r\n        // Casts to the requested type.\r\n        void* CastTo(ISourceType type) override;\r\n\r\n        // Gets the index.\r\n        SQLiteIndex& GetIndex() { return m_index; }\r\n        const SQLiteIndex& GetIndex() const { return m_index; }\r\n\r\n        // Determines if the other source refers to the same as this.\r\n        bool IsSame(const SQLiteIndexSource* other) const;\r\n\r\n        bool RequireManifestHash() const { return m_requireManifestHash; }\r\n\r\n    private:\r\n        std::shared_ptr<SQLiteIndexSource> NonConstSharedFromThis() const;\r\n\r\n        SourceDetails m_details;\r\n        bool m_requireManifestHash;\r\n        bool m_isInstalled;\r\n        std::shared_ptr<Caching::FileCache> m_manifestCache;\r\n        std::shared_ptr<Caching::FileCache> m_packageVersionDataCache;\r\n\r\n    protected:\r\n        SQLiteIndex m_index;\r\n    };\r\n\r\n    // A source that holds a SQLiteIndex and lock.\r\n    struct SQLiteIndexWriteableSource : public SQLiteIndexSource, public IMutablePackageSource\r\n    {\r\n        SQLiteIndexWriteableSource(\r\n            const SourceDetails& details,\r\n            SQLiteIndex&& index,\r\n            bool isInstalledSource = false);\r\n\r\n        // Casts to the requested type.\r\n        void* CastTo(ISourceType type) override;\r\n\r\n        // Adds a package version to the source.\r\n        void AddPackageVersion(const Manifest::Manifest& manifest, const std::filesystem::path& relativePath);\r\n\r\n        // Removes a package version from the source.\r\n        void RemovePackageVersion(const Manifest::Manifest& manifest, const std::filesystem::path& relativePath);\r\n    };\r\n\r\n    namespace details\r\n    {\r\n        // For the IPackage(Version) implementations that need to hold a weak reference to a SQLiteIndexSource.\r\n        struct SourceReference\r\n        {\r\n            SourceReference(const std::shared_ptr<SQLiteIndexSource>& source);\r\n\r\n        protected:\r\n            std::shared_ptr<SQLiteIndexSource> GetReferenceSource() const;\r\n\r\n        private:\r\n            std::weak_ptr<SQLiteIndexSource> m_source;\r\n        };\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/SQLiteIndexSourceV1.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Microsoft/SQLiteIndexSourceV1.h\"\r\n#include <winget/ManifestYamlParser.h>\r\n\r\nusing namespace AppInstaller::Utility;\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::details::V1\r\n{\r\n    // The IPackageVersion implementation for V1 index.\r\n    struct PackageVersion : public SourceReference, public IPackageVersion\r\n    {\r\n        PackageVersion(const std::shared_ptr<SQLiteIndexSource>& source, SQLiteIndex::IdType manifestId, const std::shared_ptr<Caching::FileCache>& manifestCache) :\r\n            SourceReference(source), m_manifestId(manifestId), m_manifestCache(manifestCache) {}\r\n\r\n        // Inherited via IPackageVersion\r\n        LocIndString GetProperty(PackageVersionProperty property) const override\r\n        {\r\n            switch (property)\r\n            {\r\n            case PackageVersionProperty::SourceIdentifier:\r\n                return LocIndString{ GetReferenceSource()->GetIdentifier() };\r\n            case PackageVersionProperty::SourceName:\r\n                return LocIndString{ GetReferenceSource()->GetDetails().Name };\r\n            default:\r\n                // Values coming from the index will always be localized/independent.\r\n                std::optional<std::string> optValue = GetReferenceSource()->GetIndex().GetPropertyByPrimaryId(m_manifestId, property);\r\n                return LocIndString{ optValue ? optValue.value() : std::string{} };\r\n            }\r\n        }\r\n\r\n        std::vector<LocIndString> GetMultiProperty(PackageVersionMultiProperty property) const override\r\n        {\r\n            std::vector<LocIndString> result;\r\n\r\n            for (auto&& value : GetReferenceSource()->GetIndex().GetMultiPropertyByPrimaryId(m_manifestId, property))\r\n            {\r\n                // Values coming from the index will always be localized/independent.\r\n                result.emplace_back(std::move(value));\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        Manifest::Manifest GetManifest() override\r\n        {\r\n            std::shared_ptr<SQLiteIndexSource> source = GetReferenceSource();\r\n\r\n            std::optional<std::string> relativePathOpt = source->GetIndex().GetPropertyByPrimaryId(m_manifestId, PackageVersionProperty::RelativePath);\r\n            THROW_HR_IF(E_NOT_SET, !relativePathOpt);\r\n\r\n            std::optional<std::string> manifestHashString = source->GetIndex().GetPropertyByPrimaryId(m_manifestId, PackageVersionProperty::ManifestSHA256Hash);\r\n            THROW_HR_IF(APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE, source->RequireManifestHash() && !manifestHashString);\r\n\r\n            SHA256::HashBuffer manifestSHA256;\r\n            if (manifestHashString)\r\n            {\r\n                manifestSHA256 = SHA256::ConvertToBytes(manifestHashString.value());\r\n            }\r\n\r\n            std::unique_ptr<std::istream> manifestStream = m_manifestCache->GetFile(ConvertToUTF16(relativePathOpt.value()), manifestSHA256);\r\n            return Manifest::YamlParser::Create(ReadEntireStream(*manifestStream));\r\n        }\r\n\r\n        Source GetSource() const override\r\n        {\r\n            return Source{ GetReferenceSource() };\r\n        }\r\n\r\n        IPackageVersion::Metadata GetMetadata() const override\r\n        {\r\n            auto metadata = GetReferenceSource()->GetIndex().GetMetadataByManifestId(m_manifestId);\r\n\r\n            IPackageVersion::Metadata result;\r\n            for (auto&& data : metadata)\r\n            {\r\n                result.emplace(std::move(data));\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n    private:\r\n        SQLiteIndex::IdType m_manifestId;\r\n        std::shared_ptr<Caching::FileCache> m_manifestCache;\r\n    };\r\n\r\n    SQLitePackage::SQLitePackage(const std::shared_ptr<SQLiteIndexSource>& source, SQLiteIndex::IdType idId, const std::shared_ptr<Caching::FileCache>& manifestCache, bool isInstalled) :\r\n        SourceReference(source), m_idId(idId), m_manifestCache(manifestCache), m_isInstalled(isInstalled) {}\r\n\r\n    LocIndString SQLitePackage::GetProperty(PackageProperty property) const\r\n    {\r\n        LocIndString result;\r\n\r\n        std::shared_ptr<IPackageVersion> truth = GetLatestVersion();\r\n        if (truth)\r\n        {\r\n            switch (property)\r\n            {\r\n            case PackageProperty::Id:\r\n                return truth->GetProperty(PackageVersionProperty::Id);\r\n            case PackageProperty::Name:\r\n                return truth->GetProperty(PackageVersionProperty::Name);\r\n            default:\r\n                THROW_HR(E_UNEXPECTED);\r\n            }\r\n        }\r\n        else\r\n        {\r\n            AICLI_LOG(Repo, Verbose, << \"SQLitePackage: No manifest was found for the package with id# '\" << m_idId << \"'\");\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<Utility::LocIndString> SQLitePackage::GetMultiProperty(PackageMultiProperty property) const\r\n    {\r\n        std::shared_ptr<SQLiteIndexSource> source = GetReferenceSource();\r\n        std::vector<Utility::LocIndString> result;\r\n        PackageVersionMultiProperty mappedProperty = PackageMultiPropertyToPackageVersionMultiProperty(property);\r\n\r\n        for (const auto& version : source->GetIndex().GetVersionKeysById(m_idId))\r\n        {\r\n            for (auto&& string : source->GetIndex().GetMultiPropertyByPrimaryId(version.ManifestId, mappedProperty))\r\n            {\r\n                auto itr = std::lower_bound(result.begin(), result.end(), string);\r\n\r\n                if (itr == result.end() || itr->get() != string)\r\n                {\r\n                    result.emplace(itr, std::move(string));\r\n                }\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<PackageVersionKey> SQLitePackage::GetVersionKeys() const\r\n    {\r\n        std::shared_ptr<SQLiteIndexSource> source = GetReferenceSource();\r\n\r\n        {\r\n            auto sharedLock = m_versionKeysLock.lock_shared();\r\n\r\n            if (!m_versionKeys.empty())\r\n            {\r\n                return m_versionKeys;\r\n            }\r\n        }\r\n\r\n        auto exclusiveLock = m_versionKeysLock.lock_exclusive();\r\n\r\n        if (!m_versionKeys.empty())\r\n        {\r\n            return m_versionKeys;\r\n        }\r\n\r\n        std::vector<SQLiteIndex::VersionKey> versions = source->GetIndex().GetVersionKeysById(m_idId);\r\n\r\n        for (const auto& vk : versions)\r\n        {\r\n            std::string version = vk.VersionAndChannel.GetVersion().ToString();\r\n            std::string channel = vk.VersionAndChannel.GetChannel().ToString();\r\n            m_versionKeys.emplace_back(source->GetIdentifier(), version, channel);\r\n            m_versionKeysMap.emplace(MapKey{ std::move(version), std::move(channel) }, vk.ManifestId);\r\n        }\r\n\r\n        return m_versionKeys;\r\n    }\r\n\r\n    std::shared_ptr<IPackageVersion> SQLitePackage::GetLatestVersion() const\r\n    {\r\n        std::shared_ptr<SQLiteIndexSource> source = GetReferenceSource();\r\n        std::optional<SQLiteIndex::IdType> manifestId = source->GetIndex().GetManifestIdByKey(m_idId, {}, {});\r\n\r\n        if (manifestId)\r\n        {\r\n            return std::make_shared<PackageVersion>(source, manifestId.value(), m_manifestCache);\r\n        }\r\n\r\n        return {};\r\n    }\r\n\r\n    std::shared_ptr<IPackageVersion> SQLitePackage::GetVersion(const PackageVersionKey& versionKey) const\r\n    {\r\n        std::shared_ptr<SQLiteIndexSource> source = GetReferenceSource();\r\n\r\n        // Ensure that this key targets this (or any) source\r\n        if (!versionKey.SourceId.empty() && versionKey.SourceId != source->GetIdentifier())\r\n        {\r\n            return {};\r\n        }\r\n\r\n        std::optional<SQLiteIndex::IdType> manifestId;\r\n\r\n        {\r\n            MapKey requested{ versionKey.Version, versionKey.Channel };\r\n            auto sharedLock = m_versionKeysLock.lock_shared();\r\n\r\n            auto itr = m_versionKeysMap.find(requested);\r\n            if (itr != m_versionKeysMap.end())\r\n            {\r\n                manifestId = itr->second;\r\n            }\r\n        }\r\n\r\n        if (!manifestId)\r\n        {\r\n            manifestId = source->GetIndex().GetManifestIdByKey(m_idId, versionKey.Version, versionKey.Channel);\r\n        }\r\n\r\n        if (manifestId)\r\n        {\r\n            return std::make_shared<PackageVersion>(source, manifestId.value(), m_manifestCache);\r\n        }\r\n\r\n        return {};\r\n    }\r\n\r\n    Source SQLitePackage::GetSource() const\r\n    {\r\n        return Source{ GetReferenceSource() };\r\n    }\r\n\r\n    bool SQLitePackage::IsSame(const IPackage* other) const\r\n    {\r\n        const SQLitePackage* otherSQLite = PackageCast<const SQLitePackage*>(other);\r\n\r\n        if (otherSQLite)\r\n        {\r\n            return GetReferenceSource()->IsSame(otherSQLite->GetReferenceSource().get()) && m_idId == otherSQLite->m_idId;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    const void* SQLitePackage::CastTo(IPackageType type) const\r\n    {\r\n        if (type == PackageType)\r\n        {\r\n            return this;\r\n        }\r\n\r\n        return nullptr;\r\n    }\r\n\r\n    std::shared_ptr<IPackage> SQLitePackage::GetInstalled()\r\n    {\r\n        return m_isInstalled ? shared_from_this() : std::shared_ptr<IPackage>{};\r\n    }\r\n\r\n    std::vector<std::shared_ptr<IPackage>> SQLitePackage::GetAvailable()\r\n    {\r\n        return m_isInstalled ? std::vector<std::shared_ptr<IPackage>>{} : std::vector<std::shared_ptr<IPackage>>{ shared_from_this() };\r\n    }\r\n\r\n    bool SQLitePackage::MapKey::operator<(const MapKey& other) const\r\n    {\r\n        if (Version < other.Version)\r\n        {\r\n            return true;\r\n        }\r\n        else if (Version == other.Version)\r\n        {\r\n            return Channel < other.Channel;\r\n        }\r\n        else\r\n        {\r\n            return false;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/SQLiteIndexSourceV1.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/SQLiteIndexSource.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::details::V1\r\n{\r\n    // The IPackage implementation for V1 index.\r\n    struct SQLitePackage : public std::enable_shared_from_this<SQLitePackage>, public SourceReference, public IPackage, public ICompositePackage\r\n    {\r\n        static constexpr IPackageType PackageType = IPackageType::SQLitePackage1;\r\n\r\n        SQLitePackage(const std::shared_ptr<SQLiteIndexSource>& source, SQLiteIndex::IdType idId, const std::shared_ptr<Caching::FileCache>& manifestCache, bool isInstalled);\r\n\r\n        // Inherited via IPackage\r\n        Utility::LocIndString GetProperty(PackageProperty property) const;\r\n\r\n        std::vector<Utility::LocIndString> GetMultiProperty(PackageMultiProperty property) const override;\r\n\r\n        std::vector<PackageVersionKey> GetVersionKeys() const override;\r\n\r\n        std::shared_ptr<IPackageVersion> GetLatestVersion() const override;\r\n\r\n        std::shared_ptr<IPackageVersion> GetVersion(const PackageVersionKey& versionKey) const override;\r\n\r\n        Source GetSource() const override;\r\n\r\n        bool IsSame(const IPackage* other) const override;\r\n\r\n        const void* CastTo(IPackageType type) const override;\r\n\r\n        // Inherited via ICompositePackage\r\n        std::shared_ptr<IPackage> GetInstalled() override;\r\n\r\n        std::vector<std::shared_ptr<IPackage>> GetAvailable() override;\r\n\r\n    private:\r\n        // Contains the information needed to map a version key to it's rows.\r\n        struct MapKey\r\n        {\r\n            Utility::NormalizedString Version;\r\n            Utility::NormalizedString Channel;\r\n\r\n            bool operator<(const MapKey& other) const;\r\n        };\r\n\r\n        SQLiteIndex::IdType m_idId;\r\n        std::shared_ptr<Caching::FileCache> m_manifestCache;\r\n        bool m_isInstalled;\r\n\r\n        // To avoid removing const from the interface\r\n        mutable wil::srwlock m_versionKeysLock;\r\n        mutable std::vector<PackageVersionKey> m_versionKeys;\r\n        mutable std::map<MapKey, SQLiteIndex::IdType> m_versionKeysMap;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/SQLiteIndexSourceV2.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Microsoft/SQLiteIndexSourceV2.h\"\r\n#include <winget/ManifestYamlParser.h>\r\n\r\nusing namespace AppInstaller::Utility;\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::details::V2\r\n{\r\n    // Get the relative path and hash for the package version data manifest.\r\n    std::pair<std::filesystem::path, std::string> CreatePackageVersionDataRelativePath(const std::shared_ptr<SQLiteIndexSource>& source, SQLiteIndex::IdType packageRowId)\r\n    {\r\n        const SQLiteIndex& index = source->GetIndex();\r\n\r\n        std::string identifier = index.GetPropertyByPrimaryId(packageRowId, PackageVersionProperty::Id).value();\r\n        std::string hash = index.GetPropertyByPrimaryId(packageRowId, PackageVersionProperty::ManifestSHA256Hash).value();\r\n        std::filesystem::path relativePath = Manifest::PackageVersionDataManifest::GetRelativeDirectoryPath(identifier, hash) / Manifest::PackageVersionDataManifest::VersionManifestCompressedFileName();\r\n\r\n        return std::make_pair(std::move(relativePath), std::move(hash));\r\n    }\r\n\r\n    // Gets package version data for the given package in the index.\r\n    Manifest::PackageVersionDataManifest GetPackageVersionData(const std::shared_ptr<SQLiteIndexSource>& source, SQLiteIndex::IdType packageRowId, const Caching::FileCache& fileCache)\r\n    {\r\n        auto pathAndHash = CreatePackageVersionDataRelativePath(source, packageRowId);\r\n        auto fileStream = fileCache.GetFile(pathAndHash.first, SHA256::ConvertToBytes(pathAndHash.second));\r\n        auto fileBytes = ReadEntireStreamAsByteArray(*fileStream);\r\n\r\n        Manifest::PackageVersionDataManifest result;\r\n        result.Deserialize(Manifest::PackageVersionDataManifest::CreateDecompressor().Decompress(fileBytes));\r\n\r\n        return result;\r\n    }\r\n\r\n    // The IPackageVersion implementation for V2 index.\r\n    struct PackageVersion : public SourceReference, public IPackageVersion\r\n    {\r\n        PackageVersion(\r\n            const std::shared_ptr<SQLiteIndexSource>& source,\r\n            SQLiteIndex::IdType packageRowId,\r\n            std::optional<Manifest::PackageVersionDataManifest::VersionData> packageVersionData,\r\n            const std::shared_ptr<Caching::FileCache>& manifestCache,\r\n            const std::shared_ptr<Caching::FileCache>& packageVersionDataCache) :\r\n                SourceReference(source),\r\n                m_packageRowId(packageRowId),\r\n                m_packageVersionData(std::move(packageVersionData)),\r\n                m_manifestCache(manifestCache),\r\n                m_packageVersionDataCache(packageVersionDataCache)\r\n        {}\r\n\r\n        // Inherited via IPackageVersion\r\n        LocIndString GetProperty(PackageVersionProperty property) const override\r\n        {\r\n            switch (property)\r\n            {\r\n            case PackageVersionProperty::SourceIdentifier:\r\n                return LocIndString{ GetReferenceSource()->GetIdentifier() };\r\n            case PackageVersionProperty::SourceName:\r\n                return LocIndString{ GetReferenceSource()->GetDetails().Name };\r\n            case PackageVersionProperty::RelativePath:\r\n            case PackageVersionProperty::ManifestSHA256Hash:\r\n            {\r\n                // These values can only come from the version data.\r\n                EnsurePackageVersionData();\r\n                return GetPropertyFromVersionData(property);\r\n            }\r\n                break;\r\n            case PackageVersionProperty::Publisher:\r\n            {\r\n                // These values can only come from the manifest.\r\n                EnsureManifest();\r\n                return GetPropertyFromManifest(property);\r\n            }\r\n                break;\r\n            case PackageVersionProperty::Id:\r\n            case PackageVersionProperty::Name:\r\n            case PackageVersionProperty::Moniker:\r\n            {\r\n                // These properties can come from the manifest or the index.\r\n                // The index values will be for the latest version rather than this specific one though.\r\n                auto sharedLock = m_versionAndManifestLock.lock_shared();\r\n\r\n                if (m_manifest)\r\n                {\r\n                    return GetPropertyFromManifestWithLock(property);\r\n                }\r\n                else\r\n                {\r\n                    return GetPropertyFromIndex(property);\r\n                }\r\n            }\r\n                break;\r\n            case PackageVersionProperty::Version:\r\n            case PackageVersionProperty::Channel:\r\n            case PackageVersionProperty::ArpMinVersion:\r\n            case PackageVersionProperty::ArpMaxVersion:\r\n            {\r\n                // These properties can come from the manifest, version data, or the index.\r\n                // The index values are only for the latest version, but we should always already have the version data\r\n                // for any version that is not the latest.\r\n                auto sharedLock = m_versionAndManifestLock.lock_shared();\r\n\r\n                if (m_manifest)\r\n                {\r\n                    return GetPropertyFromManifestWithLock(property);\r\n                }\r\n                else if (m_packageVersionData)\r\n                {\r\n                    return GetPropertyFromVersionDataWithLock(property);\r\n                }\r\n                else\r\n                {\r\n                    return GetPropertyFromIndex(property);\r\n                }\r\n            }\r\n                break;\r\n            default:\r\n                THROW_HR(E_UNEXPECTED);\r\n            }\r\n        }\r\n\r\n        std::vector<LocIndString> GetMultiProperty(PackageVersionMultiProperty property) const override\r\n        {\r\n            switch (property)\r\n            {\r\n            case PackageVersionMultiProperty::Locale:\r\n            {\r\n                // These values can only come from the manifest.\r\n                EnsureManifest();\r\n                return GetMultiPropertyFromManifest(property);\r\n            }\r\n                break;\r\n            case PackageVersionMultiProperty::PackageFamilyName:\r\n            case PackageVersionMultiProperty::ProductCode:\r\n            case PackageVersionMultiProperty::UpgradeCode:\r\n            case PackageVersionMultiProperty::Name:\r\n            case PackageVersionMultiProperty::Publisher:\r\n            case PackageVersionMultiProperty::Tag:\r\n            case PackageVersionMultiProperty::Command:\r\n            {\r\n                // These properties can come from the manifest or the index.\r\n                // The index values will be for all versions rather than this specific one though.\r\n                auto sharedLock = m_versionAndManifestLock.lock_shared();\r\n\r\n                if (m_manifest)\r\n                {\r\n                    return GetMultiPropertyFromManifestWithLock(property);\r\n                }\r\n                else\r\n                {\r\n                    return GetMultiPropertyFromIndex(property);\r\n                }\r\n            }\r\n            break;\r\n            default:\r\n                THROW_HR(E_UNEXPECTED);\r\n            }\r\n        }\r\n\r\n        Manifest::Manifest GetManifest() override\r\n        {\r\n            EnsureManifest();\r\n            auto sharedLock = m_versionAndManifestLock.lock_shared();\r\n            return m_manifest.value();\r\n        }\r\n\r\n        Source GetSource() const override\r\n        {\r\n            return Source{ GetReferenceSource() };\r\n        }\r\n\r\n        IPackageVersion::Metadata GetMetadata() const override\r\n        {\r\n            return {};\r\n        }\r\n\r\n    private:\r\n        // Ensures that the package version data is present.\r\n        void EnsurePackageVersionData() const\r\n        {\r\n            {\r\n                auto sharedLock = m_versionAndManifestLock.lock_shared();\r\n                if (m_packageVersionData)\r\n                {\r\n                    return;\r\n                }\r\n            }\r\n\r\n            auto exclusiveLock = m_versionAndManifestLock.lock_exclusive();\r\n            if (m_packageVersionData)\r\n            {\r\n                return;\r\n            }\r\n\r\n            Manifest::PackageVersionDataManifest packageVersionDataManifest = GetPackageVersionData(GetReferenceSource(), m_packageRowId, *m_packageVersionDataCache);\r\n\r\n            for (const auto& versionData : packageVersionDataManifest.Versions())\r\n            {\r\n                // We should only ever be looking for the latest version here.\r\n                if (!m_packageVersionData || m_packageVersionData->Version < versionData.Version)\r\n                {\r\n                    m_packageVersionData = versionData;\r\n                }\r\n            }\r\n        }\r\n\r\n        // Ensures that the manifest is present.\r\n        void EnsureManifest() const\r\n        {\r\n            {\r\n                auto sharedLock = m_versionAndManifestLock.lock_shared();\r\n                if (m_manifest)\r\n                {\r\n                    return;\r\n                }\r\n            }\r\n\r\n            // We will need the package version data to get the manifest.\r\n            EnsurePackageVersionData();\r\n\r\n            auto exclusiveLock = m_versionAndManifestLock.lock_exclusive();\r\n            if (m_manifest)\r\n            {\r\n                return;\r\n            }\r\n\r\n            std::unique_ptr<std::istream> manifestStream =\r\n                m_manifestCache->GetFile(ConvertToUTF16(m_packageVersionData->ManifestRelativePath), SHA256::ConvertToBytes(m_packageVersionData->ManifestHash));\r\n            m_manifest = Manifest::YamlParser::Create(ReadEntireStream(*manifestStream));\r\n            m_manifest->ApplyLocale();\r\n        }\r\n\r\n        LocIndString GetPropertyFromIndex(PackageVersionProperty property) const\r\n        {\r\n            switch (property)\r\n            {\r\n            case PackageVersionProperty::Id:\r\n            case PackageVersionProperty::Name:\r\n            case PackageVersionProperty::Moniker:\r\n            case PackageVersionProperty::Version:\r\n            case PackageVersionProperty::ArpMinVersion:\r\n            case PackageVersionProperty::ArpMaxVersion:\r\n            {\r\n                // Values coming from the index will always be localized/independent.\r\n                std::optional<std::string> optValue = GetReferenceSource()->GetIndex().GetPropertyByPrimaryId(m_packageRowId, property);\r\n                return LocIndString{ optValue ? optValue.value() : std::string{} };\r\n            }\r\n            default:\r\n                return {};\r\n            }\r\n        }\r\n\r\n        LocIndString GetPropertyFromVersionData(PackageVersionProperty property) const\r\n        {\r\n            auto sharedLock = m_versionAndManifestLock.lock_shared();\r\n            return GetPropertyFromVersionDataWithLock(property);\r\n        }\r\n\r\n        LocIndString GetPropertyFromVersionDataWithLock(PackageVersionProperty property) const\r\n        {\r\n            std::string result;\r\n\r\n            switch (property)\r\n            {\r\n            case PackageVersionProperty::RelativePath:\r\n                result = m_packageVersionData->ManifestRelativePath;\r\n                break;\r\n            case PackageVersionProperty::ManifestSHA256Hash:\r\n                result = m_packageVersionData->ManifestHash;\r\n                break;\r\n            case PackageVersionProperty::Version:\r\n                result = m_packageVersionData->Version.ToString();\r\n                break;\r\n            case PackageVersionProperty::ArpMinVersion:\r\n                result = m_packageVersionData->ArpMinVersion.value_or(\"\");\r\n                break;\r\n            case PackageVersionProperty::ArpMaxVersion:\r\n                result = m_packageVersionData->ArpMaxVersion.value_or(\"\");\r\n                break;\r\n            }\r\n\r\n            return LocIndString{ std::move(result) };\r\n        }\r\n\r\n        LocIndString GetPropertyFromManifest(PackageVersionProperty property) const\r\n        {\r\n            auto sharedLock = m_versionAndManifestLock.lock_shared();\r\n            return GetPropertyFromManifestWithLock(property);\r\n        }\r\n\r\n        LocIndString GetPropertyFromManifestWithLock(PackageVersionProperty property) const\r\n        {\r\n            std::string result;\r\n\r\n            switch (property)\r\n            {\r\n            case PackageVersionProperty::Publisher:\r\n                result = m_manifest->CurrentLocalization.Get<Manifest::Localization::Publisher>();\r\n                break;\r\n            case PackageVersionProperty::Id:\r\n                result = m_manifest->Id;\r\n                break;\r\n            case PackageVersionProperty::Name:\r\n                result = m_manifest->CurrentLocalization.Get<Manifest::Localization::PackageName>();\r\n                break;\r\n            case PackageVersionProperty::Moniker:\r\n                result = m_manifest->Moniker;\r\n                break;\r\n            case PackageVersionProperty::Version:\r\n                result = m_manifest->Version;\r\n                break;\r\n            case PackageVersionProperty::Channel:\r\n                result = m_manifest->Channel;\r\n                break;\r\n            case PackageVersionProperty::ArpMinVersion:\r\n            {\r\n                auto versionRange = m_manifest->GetArpVersionRange();\r\n                if (!versionRange.IsEmpty())\r\n                {\r\n                    result = versionRange.GetMinVersion().ToString();\r\n                }\r\n            }\r\n                break;\r\n            case PackageVersionProperty::ArpMaxVersion:\r\n            {\r\n                auto versionRange = m_manifest->GetArpVersionRange();\r\n                if (!versionRange.IsEmpty())\r\n                {\r\n                    result = versionRange.GetMaxVersion().ToString();\r\n                }\r\n            }\r\n                break;\r\n            }\r\n\r\n            return LocIndString{ std::move(result) };\r\n        }\r\n\r\n        std::vector<LocIndString> GetMultiPropertyFromIndex(PackageVersionMultiProperty property) const\r\n        {\r\n            std::vector<LocIndString> result;\r\n\r\n            for (auto&& value : GetReferenceSource()->GetIndex().GetMultiPropertyByPrimaryId(m_packageRowId, property))\r\n            {\r\n                // Values coming from the index will always be localized/independent.\r\n                result.emplace_back(std::move(value));\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        std::vector<LocIndString> GetMultiPropertyFromManifest(PackageVersionMultiProperty property) const\r\n        {\r\n            auto sharedLock = m_versionAndManifestLock.lock_shared();\r\n            return GetMultiPropertyFromManifestWithLock(property);\r\n        }\r\n\r\n        std::vector<LocIndString> GetMultiPropertyFromManifestWithLock(PackageVersionMultiProperty property) const\r\n        {\r\n            std::vector<Manifest::string_t> intermediate;\r\n\r\n            switch (property)\r\n            {\r\n            case PackageVersionMultiProperty::PackageFamilyName:\r\n                intermediate = m_manifest->GetPackageFamilyNames();\r\n                break;\r\n            case PackageVersionMultiProperty::ProductCode:\r\n                intermediate = m_manifest->GetProductCodes();\r\n                break;\r\n            case PackageVersionMultiProperty::UpgradeCode:\r\n                intermediate = m_manifest->GetUpgradeCodes();\r\n                break;\r\n            case PackageVersionMultiProperty::Name:\r\n                intermediate = m_manifest->GetPackageNames();\r\n                break;\r\n            case PackageVersionMultiProperty::Publisher:\r\n                intermediate = m_manifest->GetPublishers();\r\n                break;\r\n            case PackageVersionMultiProperty::Locale:\r\n                for (const auto& localization : m_manifest->Localizations)\r\n                {\r\n                    intermediate.emplace_back(localization.Locale);\r\n                }\r\n                break;\r\n            case PackageVersionMultiProperty::Tag:\r\n                intermediate = m_manifest->GetAggregatedTags();\r\n                break;\r\n            case PackageVersionMultiProperty::Command:\r\n                intermediate = m_manifest->GetAggregatedCommands();\r\n                break;\r\n            }\r\n\r\n            std::vector<LocIndString> result;\r\n\r\n            for (auto&& value : intermediate)\r\n            {\r\n                // Values coming from the manifest will always be localized/independent.\r\n                result.emplace_back(std::move(value));\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        SQLiteIndex::IdType m_packageRowId;\r\n\r\n        mutable wil::srwlock m_versionAndManifestLock;\r\n        mutable std::optional<Manifest::PackageVersionDataManifest::VersionData> m_packageVersionData;\r\n        mutable std::optional<Manifest::Manifest> m_manifest;\r\n\r\n        std::shared_ptr<Caching::FileCache> m_manifestCache;\r\n        std::shared_ptr<Caching::FileCache> m_packageVersionDataCache;\r\n    };\r\n\r\n    SQLitePackage::SQLitePackage(\r\n        const std::shared_ptr<SQLiteIndexSource>& source,\r\n        SQLiteIndex::IdType packageRowId,\r\n        const std::shared_ptr<Caching::FileCache>& manifestCache,\r\n        const std::shared_ptr<Caching::FileCache>& packageVersionDataCache,\r\n        bool isInstalled) :\r\n        SourceReference(source),\r\n        m_packageRowId(packageRowId),\r\n        m_manifestCache(manifestCache),\r\n        m_packageVersionDataCache(packageVersionDataCache),\r\n        m_isInstalled(isInstalled)\r\n    {}\r\n\r\n    LocIndString SQLitePackage::GetProperty(PackageProperty property) const\r\n    {\r\n        std::optional<std::string> result;\r\n        std::shared_ptr<SQLiteIndexSource> source = GetReferenceSource();\r\n\r\n        switch (property)\r\n        {\r\n        case PackageProperty::Id:\r\n            result = source->GetIndex().GetPropertyByPrimaryId(m_packageRowId, PackageVersionProperty::Id);\r\n            break;\r\n        case PackageProperty::Name:\r\n            result = source->GetIndex().GetPropertyByPrimaryId(m_packageRowId, PackageVersionProperty::Name);\r\n            break;\r\n        default:\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n\r\n        return LocIndString{ result ? std::move(result).value() : std::string{} };\r\n    }\r\n\r\n    std::vector<Utility::LocIndString> SQLitePackage::GetMultiProperty(PackageMultiProperty property) const\r\n    {\r\n        std::vector<LocIndString> result;\r\n\r\n        for (auto&& value : GetReferenceSource()->GetIndex().GetMultiPropertyByPrimaryId(m_packageRowId, PackageMultiPropertyToPackageVersionMultiProperty(property)))\r\n        {\r\n            // Values coming from the index will always be localized/independent.\r\n            result.emplace_back(std::move(value));\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<PackageVersionKey> SQLitePackage::GetVersionKeys() const\r\n    {\r\n        std::shared_ptr<SQLiteIndexSource> source = GetReferenceSource();\r\n\r\n        {\r\n            auto sharedLock = m_versionKeysLock.lock_shared();\r\n\r\n            if (!m_versionKeys.empty())\r\n            {\r\n                return m_versionKeys;\r\n            }\r\n        }\r\n\r\n        EnsurePackageVersionData(source);\r\n\r\n        auto sharedLock = m_versionKeysLock.lock_shared();\r\n        return m_versionKeys;\r\n    }\r\n\r\n    std::shared_ptr<IPackageVersion> SQLitePackage::GetLatestVersion() const\r\n    {\r\n        std::shared_ptr<SQLiteIndexSource> source = GetReferenceSource();\r\n        auto sharedLock = m_versionKeysLock.lock_shared();\r\n        return std::make_shared<PackageVersion>(source, m_packageRowId, m_latestVersionData, m_manifestCache, m_packageVersionDataCache);\r\n    }\r\n\r\n    std::shared_ptr<IPackageVersion> SQLitePackage::GetVersion(const PackageVersionKey& versionKey) const\r\n    {\r\n        std::shared_ptr<SQLiteIndexSource> source = GetReferenceSource();\r\n\r\n        // Ensure that this key targets this (or any) source\r\n        if (!versionKey.SourceId.empty() && versionKey.SourceId != source->GetIdentifier())\r\n        {\r\n            return {};\r\n        }\r\n\r\n        std::optional<Manifest::PackageVersionDataManifest::VersionData> versionData;\r\n\r\n        // Check for a latest version request.\r\n        if (versionKey.IsDefaultLatest())\r\n        {\r\n            auto sharedLock = m_versionKeysLock.lock_shared();\r\n            return std::make_shared<PackageVersion>(source, m_packageRowId, m_latestVersionData, m_manifestCache, m_packageVersionDataCache);\r\n        }\r\n\r\n        EnsurePackageVersionData(source);\r\n\r\n        {\r\n            MapKey requested{ versionKey.Version, versionKey.Channel };\r\n            auto sharedLock = m_versionKeysLock.lock_shared();\r\n\r\n            auto itr = m_versionKeysMap.find(requested);\r\n            if (itr != m_versionKeysMap.end())\r\n            {\r\n                versionData = itr->second;\r\n            }\r\n        }\r\n\r\n        if (versionData)\r\n        {\r\n            return std::make_shared<PackageVersion>(source, m_packageRowId, std::move(versionData), m_manifestCache, m_packageVersionDataCache);\r\n        }\r\n\r\n        return {};\r\n    }\r\n\r\n    Source SQLitePackage::GetSource() const\r\n    {\r\n        return Source{ GetReferenceSource() };\r\n    }\r\n\r\n    bool SQLitePackage::IsSame(const IPackage* other) const\r\n    {\r\n        const SQLitePackage* otherSQLite = PackageCast<const SQLitePackage*>(other);\r\n\r\n        if (otherSQLite)\r\n        {\r\n            return GetReferenceSource()->IsSame(otherSQLite->GetReferenceSource().get()) && m_packageRowId == otherSQLite->m_packageRowId;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    const void* SQLitePackage::CastTo(IPackageType type) const\r\n    {\r\n        if (type == PackageType)\r\n        {\r\n            return this;\r\n        }\r\n\r\n        return nullptr;\r\n    }\r\n\r\n    std::shared_ptr<IPackage> SQLitePackage::GetInstalled()\r\n    {\r\n        return m_isInstalled ? shared_from_this() : std::shared_ptr<IPackage>{};\r\n    }\r\n\r\n    std::vector<std::shared_ptr<IPackage>> SQLitePackage::GetAvailable()\r\n    {\r\n        return m_isInstalled ? std::vector<std::shared_ptr<IPackage>>{} : std::vector<std::shared_ptr<IPackage>>{ shared_from_this() };\r\n    }\r\n\r\n    bool SQLitePackage::MapKey::operator<(const MapKey& other) const\r\n    {\r\n        if (Version < other.Version)\r\n        {\r\n            return true;\r\n        }\r\n        else if (Version == other.Version)\r\n        {\r\n            return Channel < other.Channel;\r\n        }\r\n        else\r\n        {\r\n            return false;\r\n        }\r\n    }\r\n\r\n    // Ensures that we have the package version data present.\r\n    void SQLitePackage::EnsurePackageVersionData(const std::shared_ptr<SQLiteIndexSource>& source) const\r\n    {\r\n        {\r\n            auto sharedLock = m_versionKeysLock.lock_shared();\r\n\r\n            if (!m_versionKeys.empty())\r\n            {\r\n                return;\r\n            }\r\n        }\r\n\r\n        auto exclusiveLock = m_versionKeysLock.lock_exclusive();\r\n\r\n        if (!m_versionKeys.empty())\r\n        {\r\n            return;\r\n        }\r\n\r\n        Manifest::PackageVersionDataManifest packageVersionDataManifest = GetPackageVersionData(source, m_packageRowId, *m_packageVersionDataCache);\r\n\r\n        for (const auto& versionData : packageVersionDataManifest.Versions())\r\n        {\r\n            std::string version = versionData.Version.ToString();\r\n            std::string channel;\r\n            m_versionKeys.emplace_back(source->GetIdentifier(), version, channel);\r\n            m_versionKeysMap.emplace(MapKey{ std::move(version), std::move(channel) }, versionData);\r\n\r\n            if (!m_latestVersionData || m_latestVersionData->Version < versionData.Version)\r\n            {\r\n                m_latestVersionData = versionData;\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/SQLiteIndexSourceV2.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/SQLiteIndexSource.h\"\r\n#include <winget/PackageVersionDataManifest.h>\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::details::V2\r\n{\r\n    // The IPackage implementation for V2 index.\r\n    struct SQLitePackage : public std::enable_shared_from_this<SQLitePackage>, public SourceReference, public IPackage, public ICompositePackage\r\n    {\r\n        static constexpr IPackageType PackageType = IPackageType::SQLitePackage2;\r\n\r\n        SQLitePackage(\r\n            const std::shared_ptr<SQLiteIndexSource>& source,\r\n            SQLiteIndex::IdType packageRowId,\r\n            const std::shared_ptr<Caching::FileCache>& manifestCache,\r\n            const std::shared_ptr<Caching::FileCache>& packageVersionDataCache,\r\n            bool isInstalled);\r\n\r\n        // Inherited via IPackage\r\n        Utility::LocIndString GetProperty(PackageProperty property) const;\r\n\r\n        std::vector<Utility::LocIndString> GetMultiProperty(PackageMultiProperty property) const override;\r\n\r\n        std::vector<PackageVersionKey> GetVersionKeys() const override;\r\n\r\n        std::shared_ptr<IPackageVersion> GetLatestVersion() const override;\r\n\r\n        std::shared_ptr<IPackageVersion> GetVersion(const PackageVersionKey& versionKey) const override;\r\n\r\n        Source GetSource() const override;\r\n\r\n        bool IsSame(const IPackage* other) const override;\r\n\r\n        const void* CastTo(IPackageType type) const override;\r\n\r\n        // Inherited via ICompositePackage\r\n        std::shared_ptr<IPackage> GetInstalled() override;\r\n\r\n        std::vector<std::shared_ptr<IPackage>> GetAvailable() override;\r\n\r\n    private:\r\n        // Contains the information needed to map a version key to it's rows.\r\n        struct MapKey\r\n        {\r\n            Utility::Version Version;\r\n            Utility::NormalizedString Channel;\r\n\r\n            bool operator<(const MapKey& other) const;\r\n        };\r\n\r\n        // Ensures that we have the package version data present.\r\n        void EnsurePackageVersionData(const std::shared_ptr<SQLiteIndexSource>& source) const;\r\n\r\n        SQLiteIndex::IdType m_packageRowId;\r\n        std::shared_ptr<Caching::FileCache> m_manifestCache;\r\n        std::shared_ptr<Caching::FileCache> m_packageVersionDataCache;\r\n        bool m_isInstalled;\r\n\r\n        // To avoid removing const from the interface\r\n        mutable wil::srwlock m_versionKeysLock;\r\n        mutable std::vector<PackageVersionKey> m_versionKeys;\r\n        mutable std::map<MapKey, Manifest::PackageVersionDataManifest::VersionData> m_versionKeysMap;\r\n        mutable std::optional<Manifest::PackageVersionDataManifest::VersionData> m_latestVersionData;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_0/ChannelTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/1_0/OneToOneTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_0\r\n{\r\n    namespace details\r\n    {\r\n        using namespace std::string_view_literals;\r\n\r\n        struct ChannelTableInfo\r\n        {\r\n            inline static constexpr std::string_view TableName() { return \"channels\"sv; }\r\n            inline static constexpr std::string_view ValueName() { return \"channel\"sv; }\r\n        };\r\n    }\r\n\r\n    // The table for Channel.\r\n    using ChannelTable = OneToOneTable<details::ChannelTableInfo>;\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_0/CommandsTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/1_0/OneToManyTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_0\r\n{\r\n    namespace details\r\n    {\r\n        using namespace std::string_view_literals;\r\n\r\n        struct CommandsTableInfo\r\n        {\r\n            inline static constexpr std::string_view TableName() { return \"commands\"sv; }\r\n            inline static constexpr std::string_view ValueName() { return \"command\"sv; }\r\n        };\r\n    }\r\n\r\n    // The table for Commands.\r\n    using CommandsTable = OneToManyTable<details::CommandsTableInfo>;\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_0/IdTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/1_0/OneToOneTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_0\r\n{\r\n    namespace details\r\n    {\r\n        using namespace std::string_view_literals;\r\n\r\n        struct IdTableInfo\r\n        {\r\n            inline static constexpr std::string_view TableName() { return \"ids\"sv; }\r\n            inline static constexpr std::string_view ValueName() { return \"id\"sv; }\r\n        };\r\n    }\r\n\r\n    // The table for Id.\r\n    using IdTable = OneToOneTable<details::IdTableInfo>;\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_0/Interface.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/ISQLiteIndex.h\"\r\n#include \"Microsoft/Schema/1_0/SearchResultsTable.h\"\r\n#include \"Microsoft/Schema/1_0/OneToManyTable.h\"\r\n\r\n#include <memory>\r\n#include <vector>\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_0\r\n{\r\n    // Interface to this schema version exposed through ISQLiteIndex.\r\n    struct Interface : public ISQLiteIndex\r\n    {\r\n        // Version 1.0\r\n        SQLite::Version GetVersion() const override;\r\n        void CreateTables(SQLite::Connection& connection, CreateOptions options) override;\r\n        SQLite::rowid_t AddManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath) override;\r\n        std::pair<bool, SQLite::rowid_t> UpdateManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath) override;\r\n        SQLite::rowid_t RemoveManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest) override;\r\n        void RemoveManifestById(SQLite::Connection& connection, SQLite::rowid_t manifestId) override;\r\n        void PrepareForPackaging(SQLite::Connection& connection) override;\r\n        bool CheckConsistency(const SQLite::Connection& connection, bool log) const override;\r\n        SearchResult Search(const SQLite::Connection& connection, const SearchRequest& request) const override;\r\n        std::optional<std::string> GetPropertyByPrimaryId(const SQLite::Connection& connection, SQLite::rowid_t primaryId, PackageVersionProperty property) const override;\r\n        std::vector<std::string> GetMultiPropertyByPrimaryId(const SQLite::Connection& connection, SQLite::rowid_t primaryId, PackageVersionMultiProperty property) const override;\r\n        std::optional<SQLite::rowid_t> GetManifestIdByKey(const SQLite::Connection& connection, SQLite::rowid_t id, std::string_view version, std::string_view channel) const override;\r\n        std::optional<SQLite::rowid_t> GetManifestIdByManifest(const SQLite::Connection& connection, const Manifest::Manifest& manifest) const override;\r\n        std::vector<VersionKey> GetVersionKeysById(const SQLite::Connection& connection, SQLite::rowid_t id) const override;\r\n\r\n        // Version 1.1\r\n        MetadataResult GetMetadataByManifestId(const SQLite::Connection& connection, SQLite::rowid_t manifestId) const override;\r\n        void SetMetadataByManifestId(SQLite::Connection& connection, SQLite::rowid_t manifestId, PackageVersionMetadata metadata, std::string_view value) override;\r\n\r\n        // Version 1.2\r\n        Utility::NormalizedName NormalizeName(std::string_view name, std::string_view publisher) const override;\r\n\r\n        // Version 1.4 Get all the dependencies for a specific manifest.\r\n        std::set<std::pair<SQLite::rowid_t, Utility::NormalizedString>> GetDependenciesByManifestRowId(const SQLite::Connection& connection, SQLite::rowid_t manifestRowId) const override;\r\n        std::vector<std::pair<SQLite::rowid_t, Utility::NormalizedString>> GetDependentsById(const SQLite::Connection& connection, AppInstaller::Manifest::string_t packageId) const override;\r\n\r\n        // Version 1.7\r\n        void DropTables(SQLite::Connection& connection) override;\r\n\r\n        // Version 2.0\r\n        bool MigrateFrom(SQLite::Connection& connection, const ISQLiteIndex* current) override;\r\n\r\n    protected:\r\n        virtual bool NotNeeded(const SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, SQLite::rowid_t id) const;\r\n\r\n        // Creates the search results table.\r\n        virtual std::unique_ptr<SearchResultsTable> CreateSearchResultsTable(const SQLite::Connection& connection) const;\r\n\r\n        // Executes all relevant searches for the query.\r\n        virtual void PerformQuerySearch(SearchResultsTable& resultsTable, const RequestMatch& query) const;\r\n\r\n        // Gets a property already knowing that the manifest id is valid.\r\n        virtual std::optional<std::string> GetPropertyByManifestIdInternal(const SQLite::Connection& connection, SQLite::rowid_t manifestId, PackageVersionProperty property) const;\r\n\r\n        // Gets the one to many table schema to use.\r\n        virtual OneToManyTableSchema GetOneToManyTableSchema() const;\r\n\r\n        // Force the database to shrink the file size.\r\n        // This *must* be done outside of an active transaction.\r\n        void Vacuum(const SQLite::Connection& connection);\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_0/Interface_1_0.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Microsoft/Schema/1_0/Interface.h\"\r\n\r\n#include \"Microsoft/Schema/1_0/IdTable.h\"\r\n#include \"Microsoft/Schema/1_0/NameTable.h\"\r\n#include \"Microsoft/Schema/1_0/MonikerTable.h\"\r\n#include \"Microsoft/Schema/1_0/VersionTable.h\"\r\n#include \"Microsoft/Schema/1_0/ChannelTable.h\"\r\n\r\n#include \"Microsoft/Schema/1_0/PathPartTable.h\"\r\n\r\n#include \"Microsoft/Schema/1_0/ManifestTable.h\"\r\n\r\n#include \"Microsoft/Schema/1_0/TagsTable.h\"\r\n#include \"Microsoft/Schema/1_0/CommandsTable.h\"\r\n\r\n#include \"Microsoft/Schema/1_0/SearchResultsTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_0\r\n{\r\n    namespace\r\n    {\r\n        // Gets an existing manifest by its rowid., if it exists.\r\n        std::optional<SQLite::rowid_t> GetExistingManifestId(const SQLite::Connection& connection, const Manifest::Manifest& manifest)\r\n        {\r\n            std::optional<SQLite::rowid_t> idId = IdTable::SelectIdByValue(connection, manifest.Id, true);\r\n            if (!idId)\r\n            {\r\n                AICLI_LOG(Repo, Verbose, << \"Did not find an Id { \" << manifest.Id << \" }\");\r\n                return {};\r\n            }\r\n\r\n            std::optional<SQLite::rowid_t> versionId = VersionTable::SelectIdByValue(connection, manifest.Version, true);\r\n            if (!versionId)\r\n            {\r\n                AICLI_LOG(Repo, Verbose, << \"Did not find a Version { \" << manifest.Version << \" }\");\r\n                return {};\r\n            }\r\n\r\n            std::optional<SQLite::rowid_t> channelId = ChannelTable::SelectIdByValue(connection, manifest.Channel, true);\r\n            if (!channelId)\r\n            {\r\n                AICLI_LOG(Repo, Verbose, << \"Did not find a Channel { \" << manifest.Channel << \" }\");\r\n                return {};\r\n            }\r\n\r\n            auto result = ManifestTable::SelectByValueIds<IdTable, VersionTable, ChannelTable>(connection, { idId.value(), versionId.value(), channelId.value() });\r\n\r\n            if (!result)\r\n            {\r\n                AICLI_LOG(Repo, Verbose, << \"Did not find a manifest row for { \" << manifest.Id << \", \" << manifest.Version << \", \" << manifest.Channel << \" }\");\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        // Gets a manifest id by the given key values.\r\n        std::optional<SQLite::rowid_t> StaticGetManifestIdByKey(const SQLite::Connection& connection, SQLite::rowid_t id, std::string_view version = \"\", std::string_view channel = \"\")\r\n        {\r\n            std::optional<SQLite::rowid_t> channelIdOpt = ChannelTable::SelectIdByValue(connection, channel, true);\r\n            if (!channelIdOpt && !channel.empty())\r\n            {\r\n                AICLI_LOG(Repo, Info, << \"Did not find a Channel { \" << channel << \" }\");\r\n                return {};\r\n            }\r\n\r\n            std::optional<SQLite::rowid_t> versionIdOpt;\r\n            std::vector<std::pair<SQLite::rowid_t, std::string>> versionStrings;\r\n\r\n            if (channelIdOpt)\r\n            {\r\n                versionStrings = ManifestTable::GetAllValuesByIds<VersionTable, IdTable, ChannelTable>(connection, { id, channelIdOpt.value() });\r\n            }\r\n            else\r\n            {\r\n                versionStrings = ManifestTable::GetAllValuesByIds<VersionTable, IdTable>(connection, { id });\r\n            }\r\n\r\n            if (versionStrings.empty())\r\n            {\r\n                AICLI_LOG(Repo, Info, << \"Did not find any Versions { \" << id << \", \" << channel << \" }\");\r\n                return {};\r\n            }\r\n\r\n            // Convert the strings to Versions and sort them\r\n            struct VersionAndRow\r\n            {\r\n                SQLite::rowid_t Row = 0;\r\n                Utility::Version Version;\r\n\r\n                bool operator<(const VersionAndRow& other) const { return Version < other.Version; }\r\n            };\r\n\r\n            std::vector<VersionAndRow> versions;\r\n            for (auto& v : versionStrings)\r\n            {\r\n                versions.emplace_back(VersionAndRow{ v.first, std::move(v.second) });\r\n            }\r\n\r\n            std::sort(versions.begin(), versions.end());\r\n\r\n            if (version.empty())\r\n            {\r\n                // Get the last version in the list (the highest version)\r\n                versionIdOpt = versions.back().Row;\r\n            }\r\n            else\r\n            {\r\n                VersionAndRow requested;\r\n                requested.Version = Utility::Version{ std::string(version) };\r\n\r\n                auto itr = std::lower_bound(versions.begin(), versions.end(), requested);\r\n                if (itr != versions.end() && itr->Version == requested.Version)\r\n                {\r\n                    versionIdOpt = itr->Row;\r\n                }\r\n            }\r\n\r\n            if (!versionIdOpt)\r\n            {\r\n                AICLI_LOG(Repo, Info, << \"Did not find a Version for { \" << version << \" }\");\r\n                return {};\r\n            }\r\n\r\n            if (channelIdOpt)\r\n            {\r\n                return ManifestTable::SelectByValueIds<IdTable, VersionTable, ChannelTable>(connection, { id, versionIdOpt.value(), channelIdOpt.value() });\r\n            }\r\n            else\r\n            {\r\n                return ManifestTable::SelectByValueIds<IdTable, VersionTable>(connection, { id, versionIdOpt.value() });\r\n            }\r\n        }\r\n\r\n        bool NotNeededInternal(const SQLite::Connection& connection, std::string_view, std::string_view valueName, SQLite::rowid_t id)\r\n        {\r\n            return !ManifestTable::IsValueReferenced(connection, valueName, id);\r\n        }\r\n\r\n        // Updates the manifest column and related table based on the given value.\r\n        template <typename Table>\r\n        void UpdateManifestValueById(SQLite::Connection& connection, const typename Table::value_t& value, SQLite::rowid_t manifestId, bool overwriteLikeMatch = false)\r\n        {\r\n            auto [oldValueId] = ManifestTable::GetIdsById<Table>(connection, manifestId);\r\n\r\n            SQLite::rowid_t newValueId = Table::EnsureExists(connection, value, overwriteLikeMatch);\r\n\r\n            ManifestTable::UpdateValueIdById<Table>(connection, manifestId, newValueId);\r\n\r\n            if (NotNeededInternal(connection, Table::TableName(), Table::ValueName(), oldValueId))\r\n            {\r\n                Table::DeleteById(connection, oldValueId);\r\n            }\r\n        }\r\n    }\r\n\r\n    SQLite::Version Interface::GetVersion() const\r\n    {\r\n        return { 1, 0 };\r\n    }\r\n\r\n    void Interface::CreateTables(SQLite::Connection& connection, CreateOptions options)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"createtables_v1_0\");\r\n\r\n        IdTable::Create_deprecated(connection);\r\n        NameTable::Create_deprecated(connection);\r\n        MonikerTable::Create_deprecated(connection);\r\n        VersionTable::Create_deprecated(connection);\r\n        ChannelTable::Create_deprecated(connection);\r\n\r\n        PathPartTable::Create_deprecated(connection);\r\n\r\n        ManifestTable::Create_deprecated(connection, {\r\n            { IdTable::ValueName(), true, false }, \r\n            { NameTable::ValueName(), false, false },\r\n            { MonikerTable::ValueName(), false, false },\r\n            { VersionTable::ValueName(), true, false },\r\n            { ChannelTable::ValueName(), true, false },\r\n            { PathPartTable::ValueName(), false, WI_IsFlagClear(options, CreateOptions::SupportPathless) }\r\n            });\r\n\r\n        TagsTable::Create(connection, GetOneToManyTableSchema());\r\n        CommandsTable::Create(connection, GetOneToManyTableSchema());\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    SQLite::rowid_t Interface::AddManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath)\r\n    {\r\n        auto manifestResult = GetExistingManifestId(connection, manifest);\r\n\r\n        // If this manifest is already present, we can't add it.\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), manifestResult.has_value());\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"addmanifest_v1_0\");\r\n\r\n        auto [pathAdded, pathLeafId] = PathPartTable::EnsurePathExists(connection, relativePath, true);\r\n\r\n        // If we get false from the function, this manifest path already exists in the index.\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), relativePath && !pathAdded);\r\n\r\n        // Ensure that all of the 1:1 data exists.\r\n        SQLite::rowid_t idId = IdTable::EnsureExists(connection, manifest.Id, true);\r\n        SQLite::rowid_t nameId = NameTable::EnsureExists(connection, manifest.DefaultLocalization.Get<Manifest::Localization::PackageName>());\r\n        SQLite::rowid_t monikerId = MonikerTable::EnsureExists(connection, manifest.Moniker);\r\n        SQLite::rowid_t versionId = VersionTable::EnsureExists(connection, manifest.Version);\r\n        SQLite::rowid_t channelId = ChannelTable::EnsureExists(connection, manifest.Channel);\r\n\r\n        // Insert the manifest entry.\r\n        SQLite::rowid_t manifestId = ManifestTable::Insert(connection, {\r\n            { IdTable::ValueName(), idId},\r\n            { NameTable::ValueName(), nameId },\r\n            { MonikerTable::ValueName(), monikerId },\r\n            { VersionTable::ValueName(), versionId },\r\n            { ChannelTable::ValueName(), channelId },\r\n            { PathPartTable::ValueName(), pathLeafId }\r\n            });\r\n\r\n        // Add all of the 1:N data.\r\n        TagsTable::EnsureExistsAndInsert(connection, manifest.GetAggregatedTags(), manifestId);\r\n        CommandsTable::EnsureExistsAndInsert(connection, manifest.GetAggregatedCommands(), manifestId);\r\n\r\n        savepoint.Commit();\r\n\r\n        return manifestId;\r\n    }\r\n\r\n    std::pair<bool, SQLite::rowid_t> Interface::UpdateManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath)\r\n    {\r\n        auto manifestResult = GetExistingManifestId(connection, manifest);\r\n\r\n        // If the manifest doesn't actually exist, fail the update.\r\n        THROW_HR_IF(E_NOT_SET, !manifestResult);\r\n\r\n        SQLite::rowid_t manifestId = manifestResult.value();\r\n\r\n        auto [idInIndex, nameInIndex, monikerInIndex, versionInIndex, channelInIndex] =\r\n            ManifestTable::GetValuesById<IdTable, NameTable, MonikerTable, VersionTable, ChannelTable>(connection, manifestId);\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"updatemanifest_v1_0\");\r\n        bool indexModified = false;\r\n\r\n        // Id, Version, and Channel may have changed casing. If so, they too need to be updated.\r\n        if (idInIndex != manifest.Id)\r\n        {\r\n            UpdateManifestValueById<IdTable>(connection, manifest.Id, manifestId, true);\r\n            indexModified = true;\r\n        }\r\n\r\n        if (versionInIndex != manifest.Version)\r\n        {\r\n            UpdateManifestValueById<VersionTable>(connection, manifest.Version, manifestId);\r\n            indexModified = true;\r\n        }\r\n\r\n        if (channelInIndex != manifest.Channel)\r\n        {\r\n            UpdateManifestValueById<ChannelTable>(connection, manifest.Channel, manifestId);\r\n            indexModified = true;\r\n        }\r\n\r\n        auto packageName = manifest.DefaultLocalization.Get<Manifest::Localization::PackageName>();\r\n        if (nameInIndex != packageName)\r\n        {\r\n            UpdateManifestValueById<NameTable>(connection, packageName, manifestId);\r\n            indexModified = true;\r\n        }\r\n\r\n        if (monikerInIndex != manifest.Moniker)\r\n        {\r\n            UpdateManifestValueById<MonikerTable>(connection, manifest.Moniker, manifestId);\r\n            indexModified = true;\r\n        }\r\n\r\n        // Update path table if necessary\r\n        auto [existingPathLeafId] = ManifestTable::GetIdsById<PathPartTable>(connection, manifestId);\r\n        auto [pathAdded, newPathLeafId] = PathPartTable::EnsurePathExists(connection, relativePath, true);\r\n\r\n        if (relativePath && pathAdded)\r\n        {\r\n            // Path was added, so we need to update the manifest table and delete the old path\r\n            ManifestTable::UpdateValueIdById<PathPartTable>(connection, manifestId, newPathLeafId);\r\n            PathPartTable::RemovePathById(connection, existingPathLeafId);\r\n            indexModified = true;\r\n        }\r\n        else\r\n        {\r\n            // The path already existed, so it must either match the existing manifest path or it is an error\r\n            THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), existingPathLeafId != newPathLeafId);\r\n        }\r\n\r\n        // Update all 1:N tables as necessary\r\n        indexModified = TagsTable::UpdateIfNeededByManifestId(connection, manifest.GetAggregatedTags(), manifestId) || indexModified;\r\n        indexModified = CommandsTable::UpdateIfNeededByManifestId(connection, manifest.GetAggregatedCommands(), manifestId) || indexModified;\r\n\r\n        savepoint.Commit();\r\n\r\n        return { indexModified, manifestId };\r\n    }\r\n\r\n    SQLite::rowid_t Interface::RemoveManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest)\r\n    {\r\n        auto manifestResult = GetExistingManifestId(connection, manifest);\r\n\r\n        // If the manifest doesn't actually exist, fail the remove.\r\n        THROW_HR_IF(E_NOT_SET, !manifestResult);\r\n\r\n        RemoveManifestById(connection, manifestResult.value());\r\n\r\n        return manifestResult.value();\r\n    }\r\n\r\n    void Interface::RemoveManifestById(SQLite::Connection& connection, SQLite::rowid_t manifestId)\r\n    {\r\n        // Get the ids of the values from the manifest table\r\n        auto [idId, nameId, monikerId, versionId, channelId, pathLeafId] = \r\n            ManifestTable::GetIdsById<IdTable, NameTable, MonikerTable, VersionTable, ChannelTable, PathPartTable>(connection, manifestId);\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"RemoveManifestById_v1_0\");\r\n\r\n        // Remove the manifest row\r\n        ManifestTable::DeleteById(connection, manifestId);\r\n\r\n        // Remove all of the 1:1 data that is no longer referenced.\r\n        if (NotNeeded(connection, IdTable::TableName(), IdTable::ValueName(), idId))\r\n        {\r\n            IdTable::DeleteById(connection, idId);\r\n        }\r\n        \r\n        if (NotNeeded(connection, NameTable::TableName(), NameTable::ValueName(), nameId))\r\n        {\r\n            NameTable::DeleteById(connection, nameId);\r\n        }\r\n\r\n        if (NotNeeded(connection, MonikerTable::TableName(), MonikerTable::ValueName(), monikerId))\r\n        {\r\n            MonikerTable::DeleteById(connection, monikerId);\r\n        }\r\n        \r\n        if (NotNeeded(connection, VersionTable::TableName(), VersionTable::ValueName(), versionId))\r\n        {\r\n            VersionTable::DeleteById(connection, versionId);\r\n        }\r\n        \r\n        if (NotNeeded(connection, ChannelTable::TableName(), ChannelTable::ValueName(), channelId))\r\n        {\r\n            ChannelTable::DeleteById(connection, channelId);\r\n        }\r\n\r\n        // Remove the path\r\n        PathPartTable::RemovePathById(connection, pathLeafId);\r\n\r\n        // Remove all of the 1:N data that is no longer referenced.\r\n        TagsTable::DeleteIfNotNeededByManifestId(connection, manifestId);\r\n        CommandsTable::DeleteIfNotNeededByManifestId(connection, manifestId);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    bool Interface::NotNeeded(const SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, SQLite::rowid_t id) const\r\n    {\r\n        return NotNeededInternal(connection, tableName, valueName, id);\r\n    }\r\n\r\n    void Interface::PrepareForPackaging(SQLite::Connection& connection)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"prepareforpackaging_v1_0\");\r\n\r\n        IdTable::PrepareForPackaging_deprecated(connection);\r\n        NameTable::PrepareForPackaging_deprecated(connection);\r\n        MonikerTable::PrepareForPackaging_deprecated(connection);\r\n        VersionTable::PrepareForPackaging_deprecated(connection);\r\n        ChannelTable::PrepareForPackaging_deprecated(connection);\r\n\r\n        PathPartTable::PrepareForPackaging_deprecated(connection);\r\n\r\n        ManifestTable::PrepareForPackaging_deprecated(connection, {\r\n            VersionTable::ValueName(),\r\n            ChannelTable::ValueName(),\r\n            PathPartTable::ValueName(),\r\n            });\r\n\r\n        TagsTable::PrepareForPackaging(connection, GetOneToManyTableSchema(), false, false);\r\n        CommandsTable::PrepareForPackaging(connection, GetOneToManyTableSchema(), false, false);\r\n\r\n        savepoint.Commit();\r\n\r\n        Vacuum(connection);\r\n    }\r\n\r\n    bool Interface::CheckConsistency(const SQLite::Connection& connection, bool log) const\r\n    {\r\n        bool result = true;\r\n\r\n#define AICLI_CHECK_CONSISTENCY(_check_) \\\r\n        if (result || log) \\\r\n        { \\\r\n            result = _check_ && result; \\\r\n        }\r\n\r\n        // Check the manifest table references to it's 1:1 tables\r\n        AICLI_CHECK_CONSISTENCY(ManifestTable::CheckConsistency<IdTable>(connection, log));\r\n        AICLI_CHECK_CONSISTENCY(ManifestTable::CheckConsistency<NameTable>(connection, log));\r\n        AICLI_CHECK_CONSISTENCY(ManifestTable::CheckConsistency<MonikerTable>(connection, log));\r\n        AICLI_CHECK_CONSISTENCY(ManifestTable::CheckConsistency<VersionTable>(connection, log));\r\n        AICLI_CHECK_CONSISTENCY(ManifestTable::CheckConsistency<ChannelTable>(connection, log));\r\n        AICLI_CHECK_CONSISTENCY(ManifestTable::CheckConsistency<PathPartTable>(connection, log));\r\n\r\n        // Check the 1:1 tables' consistency\r\n        AICLI_CHECK_CONSISTENCY(IdTable::CheckConsistency(connection, log));\r\n        AICLI_CHECK_CONSISTENCY(NameTable::CheckConsistency(connection, log));\r\n        AICLI_CHECK_CONSISTENCY(MonikerTable::CheckConsistency(connection, log));\r\n        AICLI_CHECK_CONSISTENCY(VersionTable::CheckConsistency(connection, log));\r\n        AICLI_CHECK_CONSISTENCY(ChannelTable::CheckConsistency(connection, log));\r\n\r\n        // Check the pathparts table for consistency\r\n        AICLI_CHECK_CONSISTENCY(PathPartTable::CheckConsistency(connection, log));\r\n\r\n        // Check the 1:N map tables for consistency\r\n        AICLI_CHECK_CONSISTENCY(TagsTable::CheckConsistency(connection, log));\r\n        AICLI_CHECK_CONSISTENCY(CommandsTable::CheckConsistency(connection, log));\r\n\r\n#undef AICLI_CHECK_CONSISTENCY\r\n\r\n        return result;\r\n    }\r\n\r\n    ISQLiteIndex::SearchResult Interface::Search(const SQLite::Connection& connection, const SearchRequest& request) const\r\n    {\r\n        if (request.IsForEverything())\r\n        {\r\n            std::vector<SQLite::rowid_t> ids = IdTable::GetAllRowIds(connection, request.MaximumResults);\r\n\r\n            SearchResult result;\r\n            for (SQLite::rowid_t id : ids)\r\n            {\r\n                result.Matches.emplace_back(std::make_pair(id, PackageMatchFilter(PackageMatchField::Id, MatchType::Wildcard)));\r\n            }\r\n\r\n            result.Truncated = (request.MaximumResults && IdTable::GetCount(connection) > request.MaximumResults);\r\n\r\n            return result;\r\n        }\r\n\r\n        // First phase, create the search results table and populate it with the initial results.\r\n        // If the Query is provided, we search across many fields and put results in together.\r\n        // If Inclusions has fields, we add these to the data.\r\n        // If neither is defined, we take the first filter and use it as the initial results search.\r\n        std::unique_ptr<SearchResultsTable> resultsTable = CreateSearchResultsTable(connection);\r\n        bool inclusionsAttempted = false;\r\n\r\n        if (request.Query)\r\n        {\r\n            // Perform searches across multiple tables to populate the initial results.\r\n            PerformQuerySearch(*resultsTable.get(), request.Query.value());\r\n\r\n            inclusionsAttempted = true;\r\n        }\r\n\r\n        if (!request.Inclusions.empty())\r\n        {\r\n            for (auto include : request.Inclusions)\r\n            {\r\n                for (MatchType match : GetDefaultMatchTypeOrder(include.Type))\r\n                {\r\n                    include.Type = match;\r\n                    resultsTable->SearchOnField(include);\r\n                }\r\n            }\r\n\r\n            inclusionsAttempted = true;\r\n        }\r\n\r\n        size_t filterIndex = 0;\r\n        if (!inclusionsAttempted)\r\n        {\r\n            THROW_HR_IF(E_UNEXPECTED, request.Filters.empty());\r\n\r\n            // Perform search for just the field matching the first filter\r\n            PackageMatchFilter filter = request.Filters[0];\r\n\r\n            for (MatchType match : GetDefaultMatchTypeOrder(filter.Type))\r\n            {\r\n                filter.Type = match;\r\n                resultsTable->SearchOnField(filter);\r\n            }\r\n\r\n            // Skip the filter as we already know everything matches\r\n            filterIndex = 1;\r\n        }\r\n\r\n        // Remove any duplicate manifest entries\r\n        resultsTable->RemoveDuplicateManifestRows();\r\n\r\n        // Second phase, for remaining filters, flag matching search results, then remove unflagged values.\r\n        for (size_t i = filterIndex; i < request.Filters.size(); ++i)\r\n        {\r\n            PackageMatchFilter filter = request.Filters[i];\r\n\r\n            resultsTable->PrepareToFilter();\r\n\r\n            for (MatchType match : GetDefaultMatchTypeOrder(filter.Type))\r\n            {\r\n                filter.Type = match;\r\n                resultsTable->FilterOnField(filter);\r\n            }\r\n\r\n            resultsTable->CompleteFilter();\r\n        }\r\n\r\n        return resultsTable->GetSearchResults(request.MaximumResults);\r\n    }\r\n\r\n    std::optional<std::string> Interface::GetPropertyByPrimaryId(const SQLite::Connection& connection, SQLite::rowid_t primaryId, PackageVersionProperty property) const\r\n    {\r\n        return GetPropertyByManifestIdInternal(connection, primaryId, property);\r\n    }\r\n\r\n    std::vector<std::string> Interface::GetMultiPropertyByPrimaryId(const SQLite::Connection& connection, SQLite::rowid_t primaryId, PackageVersionMultiProperty property) const\r\n    {\r\n        switch (property)\r\n        {\r\n        case PackageVersionMultiProperty::Tag:\r\n            return TagsTable::GetValuesByManifestId(connection, primaryId);\r\n        case PackageVersionMultiProperty::Command:\r\n            return CommandsTable::GetValuesByManifestId(connection, primaryId);\r\n        default:\r\n            return {};\r\n        }\r\n    }\r\n\r\n    std::optional<SQLite::rowid_t> Interface::GetManifestIdByKey(const SQLite::Connection& connection, SQLite::rowid_t id, std::string_view version, std::string_view channel) const\r\n    {\r\n        return StaticGetManifestIdByKey(connection, id, version, channel);\r\n    }\r\n\r\n    std::optional<SQLite::rowid_t> Interface::GetManifestIdByManifest(const SQLite::Connection& connection, const Manifest::Manifest& manifest) const\r\n    {\r\n        return GetExistingManifestId(connection, manifest);\r\n    }\r\n\r\n    std::set<std::pair<SQLite::rowid_t, Utility::NormalizedString>> Interface::GetDependenciesByManifestRowId(const SQLite::Connection&, SQLite::rowid_t) const\r\n    {\r\n        return {};\r\n    }\r\n\r\n    std::vector<std::pair<SQLite::rowid_t, Utility::NormalizedString>> Interface::GetDependentsById(const SQLite::Connection&, AppInstaller::Manifest::string_t) const\r\n    {\r\n        return {};\r\n    }\r\n\r\n    void Interface::DropTables(SQLite::Connection& connection)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"drop_tables_v1_0\");\r\n\r\n        IdTable::Drop(connection);\r\n        NameTable::Drop(connection);\r\n        MonikerTable::Drop(connection);\r\n        VersionTable::Drop(connection);\r\n        ChannelTable::Drop(connection);\r\n\r\n        PathPartTable::Drop(connection);\r\n\r\n        ManifestTable::Drop(connection);\r\n\r\n        TagsTable::Drop(connection);\r\n        CommandsTable::Drop(connection);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    bool Interface::MigrateFrom(SQLite::Connection&, const ISQLiteIndex*)\r\n    {\r\n        return false;\r\n    }\r\n\r\n    std::vector<ISQLiteIndex::VersionKey> Interface::GetVersionKeysById(const SQLite::Connection& connection, SQLite::rowid_t id) const\r\n    {\r\n        auto versionsAndChannels = ManifestTable::GetAllValuesById<IdTable, VersionTable, ChannelTable>(connection, id);\r\n\r\n        std::vector<ISQLiteIndex::VersionKey> result;\r\n        result.reserve(versionsAndChannels.size());\r\n        for (auto&& vac : versionsAndChannels)\r\n        {\r\n            result.emplace_back(ISQLiteIndex::VersionKey{ Utility::VersionAndChannel{ Utility::Version{ std::move(std::get<1>(vac)) }, Utility::Channel{ std::move(std::get<2>(vac)) } }, std::get<0>(vac) });\r\n        }\r\n\r\n        std::sort(result.begin(), result.end());\r\n\r\n        return result;\r\n    }\r\n\r\n    ISQLiteIndex::MetadataResult Interface::GetMetadataByManifestId(const SQLite::Connection&, SQLite::rowid_t) const\r\n    {\r\n        return {};\r\n    }\r\n\r\n    void Interface::SetMetadataByManifestId(SQLite::Connection&, SQLite::rowid_t, PackageVersionMetadata, std::string_view)\r\n    {\r\n    }\r\n\r\n    Utility::NormalizedName Interface::NormalizeName(std::string_view name, std::string_view publisher) const\r\n    {\r\n        Utility::NormalizedName result;\r\n        result.Name(name);\r\n        result.Publisher(publisher);\r\n        return result;\r\n    }\r\n\r\n    std::unique_ptr<SearchResultsTable> Interface::CreateSearchResultsTable(const SQLite::Connection& connection) const\r\n    {\r\n        return std::make_unique<SearchResultsTable>(connection);\r\n    }\r\n\r\n    void Interface::PerformQuerySearch(SearchResultsTable& resultsTable, const RequestMatch& query) const\r\n    {\r\n        // Arbitrary values to create a reusable filter with the given value.\r\n        PackageMatchFilter filter(PackageMatchField::Id, MatchType::Exact, query.Value);\r\n\r\n        for (MatchType match : GetDefaultMatchTypeOrder(query.Type))\r\n        {\r\n            filter.Type = match;\r\n\r\n            for (auto field : { PackageMatchField::Id, PackageMatchField::Name, PackageMatchField::Moniker, PackageMatchField::Command, PackageMatchField::Tag })\r\n            {\r\n                filter.Field = field;\r\n                resultsTable.SearchOnField(filter);\r\n            }\r\n        }\r\n    }\r\n\r\n    std::optional<std::string> Interface::GetPropertyByManifestIdInternal(const SQLite::Connection& connection, SQLite::rowid_t manifestId, PackageVersionProperty property) const\r\n    {\r\n        switch (property)\r\n        {\r\n        case AppInstaller::Repository::PackageVersionProperty::Id:\r\n            return ManifestTable::GetValueById<IdTable>(connection, manifestId);\r\n        case AppInstaller::Repository::PackageVersionProperty::Name:\r\n            return ManifestTable::GetValueById<NameTable>(connection, manifestId);\r\n        case AppInstaller::Repository::PackageVersionProperty::Version:\r\n            return ManifestTable::GetValueById<VersionTable>(connection, manifestId);\r\n        case AppInstaller::Repository::PackageVersionProperty::Channel:\r\n            return ManifestTable::GetValueById<ChannelTable>(connection, manifestId);\r\n        case AppInstaller::Repository::PackageVersionProperty::RelativePath:\r\n            return PathPartTable::GetPathById(connection, std::get<0>(ManifestTable::GetIdsById<PathPartTable>(connection, manifestId)));\r\n        case AppInstaller::Repository::PackageVersionProperty::Moniker:\r\n            return ManifestTable::GetValueById<MonikerTable>(connection, manifestId);\r\n        default:\r\n            return {};\r\n        }\r\n    }\r\n\r\n    OneToManyTableSchema Interface::GetOneToManyTableSchema() const\r\n    {\r\n        return OneToManyTableSchema::Version_1_0;\r\n    }\r\n\r\n    void Interface::Vacuum(const SQLite::Connection& connection)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.Vacuum();\r\n        builder.Execute(connection);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_0/ManifestTable.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ManifestTable.h\"\r\n#include <winget/SQLiteStatementBuilder.h>\r\n#include \"OneToManyTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_0\r\n{\r\n    using namespace std::string_view_literals;\r\n    static constexpr std::string_view s_ManifestTable_Table_Name = \"manifest\"sv;\r\n    static constexpr std::string_view s_ManifestTable_Index_Separator = \"_\"sv;\r\n    static constexpr std::string_view s_ManifestTable_Index_Suffix = \"_index\"sv;\r\n\r\n    namespace details\r\n    {\r\n        std::optional<SQLite::rowid_t> ManifestTableSelectByValueIds(\r\n            const SQLite::Connection& connection,\r\n            std::initializer_list<std::string_view> values,\r\n            std::initializer_list<SQLite::rowid_t> ids)\r\n        {\r\n            THROW_HR_IF(E_INVALIDARG, values.size() != ids.size());\r\n\r\n            SQLite::Builder::StatementBuilder builder;\r\n            builder.Select(SQLite::RowIDName).From(s_ManifestTable_Table_Name);\r\n            \r\n            bool isFirst = true;\r\n\r\n            for (const auto& value : values)\r\n            {\r\n                if (isFirst)\r\n                {\r\n                    builder.Where(value).Equals(SQLite::Builder::Unbound);\r\n                    isFirst = false;\r\n                }\r\n                else\r\n                {\r\n                    builder.And(value).Equals(SQLite::Builder::Unbound);\r\n                }\r\n            }\r\n\r\n            builder.Limit(1);\r\n\r\n            SQLite::Statement select = builder.Prepare(connection);\r\n\r\n            int bindIndex = 0;\r\n            for (const auto& id : ids)\r\n            {\r\n                select.Bind(++bindIndex, id);\r\n            }\r\n\r\n            if (select.Step())\r\n            {\r\n                return select.GetColumn<SQLite::rowid_t>(0);\r\n            }\r\n            else\r\n            {\r\n                return {};\r\n            }\r\n        }\r\n\r\n        SQLite::Statement ManifestTableGetIdsById_Statement(\r\n            const SQLite::Connection& connection,\r\n            SQLite::rowid_t id,\r\n            std::initializer_list<std::string_view> values,\r\n            bool stepAndVerify)\r\n        {\r\n            SQLite::Builder::StatementBuilder builder;\r\n            builder.Select(values).From(s_ManifestTable_Table_Name).Where(SQLite::RowIDName).Equals(id);\r\n\r\n            SQLite::Statement result = builder.Prepare(connection);\r\n\r\n            if (stepAndVerify)\r\n            {\r\n                THROW_HR_IF(E_NOT_SET, !result.Step());\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        // Creates a statement and executes it, select the actual values for a given manifest id.\r\n        // Ex.\r\n        // SELECT [ids].[id] FROM [manifest]\r\n        // JOIN [ids] ON [manifest].[id] = [ids].[rowid]\r\n        // WHERE [manifest].[rowid] = 1\r\n        SQLite::Statement ManifestTableGetValuesById_Statement(\r\n            const SQLite::Connection& connection,\r\n            SQLite::rowid_t id,\r\n            std::initializer_list<SQLite::Builder::QualifiedColumn> columns,\r\n            std::initializer_list<std::string_view> manifestColumnNames,\r\n            bool stepAndVerify)\r\n        {\r\n            THROW_HR_IF(E_UNEXPECTED, manifestColumnNames.size() != columns.size());\r\n\r\n            using QCol = SQLite::Builder::QualifiedColumn;\r\n\r\n            SQLite::Builder::StatementBuilder builder;\r\n            builder.Select(columns).From(s_ManifestTable_Table_Name);\r\n\r\n            // join tables\r\n            auto columnItr = columns.begin();\r\n            auto manifestColumnNameItr = manifestColumnNames.begin();\r\n            while (columnItr != columns.end())\r\n            {\r\n                builder.Join(columnItr->Table).On(QCol{ s_ManifestTable_Table_Name, *manifestColumnNameItr }, QCol{ columnItr->Table, SQLite::RowIDName });\r\n\r\n                columnItr++;\r\n                manifestColumnNameItr++;\r\n            }\r\n\r\n            builder.Where(QCol{ s_ManifestTable_Table_Name, SQLite::RowIDName }).Equals(id);\r\n\r\n            SQLite::Statement result = builder.Prepare(connection);\r\n\r\n            if (stepAndVerify)\r\n            {\r\n                THROW_HR_IF(E_NOT_SET, !result.Step());\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        SQLite::Statement ManifestTableGetAllValuesByIds_Statement(\r\n            const SQLite::Connection& connection,\r\n            std::initializer_list<SQLite::Builder::QualifiedColumn> valueColumns,\r\n            std::initializer_list<SQLite::Builder::QualifiedColumn> joinColumns,\r\n            std::initializer_list<std::string_view> idColumns,\r\n            std::initializer_list<SQLite::rowid_t> ids)\r\n        {\r\n            using QCol = SQLite::Builder::QualifiedColumn;\r\n\r\n            THROW_HR_IF(E_INVALIDARG, idColumns.size() != ids.size());\r\n\r\n            SQLite::Builder::StatementBuilder builder;\r\n            builder.Select(valueColumns).From(s_ManifestTable_Table_Name);\r\n\r\n            for (const auto& joinColumn : joinColumns)\r\n            {\r\n                builder.Join(joinColumn.Table).On(QCol{ s_ManifestTable_Table_Name, joinColumn.Column }, QCol{ joinColumn.Table, SQLite::RowIDName });\r\n            }\r\n\r\n            bool isFirst = true;\r\n\r\n            for (const auto& idColumn : idColumns)\r\n            {\r\n                if (isFirst)\r\n                {\r\n                    builder.Where(idColumn).Equals(SQLite::Builder::Unbound);\r\n                    isFirst = false;\r\n                }\r\n                else\r\n                {\r\n                    builder.And(idColumn).Equals(SQLite::Builder::Unbound);\r\n                }\r\n            }\r\n\r\n            SQLite::Statement select = builder.Prepare(connection);\r\n\r\n            int bindIndex = 0;\r\n            for (const auto& id : ids)\r\n            {\r\n                select.Bind(++bindIndex, id);\r\n            }\r\n\r\n            return select;\r\n        }\r\n\r\n        std::vector<std::pair<SQLite::rowid_t, std::string>> ManifestTableGetAllValuesByIds(\r\n            const SQLite::Connection& connection,\r\n            std::initializer_list<SQLite::Builder::QualifiedColumn> valueColumns,\r\n            std::initializer_list<SQLite::Builder::QualifiedColumn> joinColumns,\r\n            std::initializer_list<std::string_view> idColumns,\r\n            std::initializer_list<SQLite::rowid_t> ids)\r\n        {\r\n            auto select = ManifestTableGetAllValuesByIds_Statement(connection, valueColumns, joinColumns, idColumns, ids);\r\n\r\n            std::vector<std::pair<SQLite::rowid_t, std::string>> result;\r\n            while (select.Step())\r\n            {\r\n                result.emplace_back(select.GetColumn<SQLite::rowid_t>(0), select.GetColumn<std::string>(1));\r\n            }\r\n            return result;\r\n        }\r\n\r\n        std::vector<int> ManifestTableBuildSearchStatement(\r\n            SQLite::Builder::StatementBuilder& builder,\r\n            std::initializer_list<SQLite::Builder::QualifiedColumn> columns,\r\n            std::initializer_list<bool> isOneToOnes,\r\n            std::string_view manifestAlias,\r\n            std::string_view valueAlias,\r\n            bool useLike)\r\n        {\r\n            using QCol = SQLite::Builder::QualifiedColumn;\r\n\r\n            // Build a statement like:\r\n            //      SELECT manifest.rowid as m, ids.id as v from manifest\r\n            //      join ids on manifest.id = ids.rowid\r\n            //      where ids.id = <value>\r\n            // OR\r\n            //      SELECT manifest.rowid as m, tags.tag as v from manifest\r\n            //      join tags_map on manifest.rowid = tags_map.manifest\r\n            //      join tags on tags_map.tag = tags.rowid\r\n            //      where tags.tag = <value>\r\n            // Where the joins and where portions are repeated for each table in question.\r\n            builder.Select().\r\n                Column(QCol(s_ManifestTable_Table_Name, SQLite::RowIDName)).As(manifestAlias);\r\n\r\n            // Value will be captured for single tables references, and left empty for multi-tables\r\n            if (columns.size() == 1)\r\n            {\r\n                builder.Column(*columns.begin());\r\n            }\r\n            else\r\n            {\r\n                builder.Value(std::string_view{});\r\n            }\r\n\r\n            builder.As(valueAlias).From(s_ManifestTable_Table_Name);\r\n\r\n            // Create join clauses\r\n            THROW_HR_IF(E_INVALIDARG, columns.size() != isOneToOnes.size());\r\n            auto columnItr = columns.begin();\r\n            auto isOneToOneItr = isOneToOnes.begin();\r\n\r\n            for (; columnItr != columns.end(); ++columnItr, ++isOneToOneItr)\r\n            {\r\n                const SQLite::Builder::QualifiedColumn& column = *columnItr;\r\n\r\n                if (*isOneToOneItr)\r\n                {\r\n                    builder.\r\n                        Join(column.Table).On(QCol(s_ManifestTable_Table_Name, column.Column), QCol(column.Table, SQLite::RowIDName));\r\n                }\r\n                else\r\n                {\r\n                    std::string mapTableName = details::OneToManyTableGetMapTableName(column.Table);\r\n                    builder.\r\n                        Join(mapTableName).On(QCol(s_ManifestTable_Table_Name, SQLite::RowIDName), QCol(mapTableName, details::OneToManyTableGetManifestColumnName())).\r\n                        Join(column.Table).On(QCol(mapTableName, column.Column), QCol(column.Table, SQLite::RowIDName));\r\n                }\r\n            }\r\n\r\n            std::vector<int> result;\r\n\r\n            // Create where clause\r\n            for (const SQLite::Builder::QualifiedColumn& column : columns)\r\n            {\r\n                if (result.empty())\r\n                {\r\n                    builder.Where(column);\r\n                }\r\n                else\r\n                {\r\n                    builder.And(column);\r\n                }\r\n\r\n                if (useLike)\r\n                {\r\n                    builder.Like(SQLite::Builder::Unbound);\r\n                    result.push_back(builder.GetLastBindIndex());\r\n                    builder.Escape(SQLite::EscapeCharForLike);\r\n                }\r\n                else\r\n                {\r\n                    builder.Equals(SQLite::Builder::Unbound);\r\n                    result.push_back(builder.GetLastBindIndex());\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        SQLite::Statement ManifestTableUpdateValueIdById_Statement(SQLite::Connection& connection, std::string_view valueName)\r\n        {\r\n            SQLite::Builder::StatementBuilder builder;\r\n            builder.Update(s_ManifestTable_Table_Name).Set().Column(valueName).Equals(SQLite::Builder::Unbound).Where(SQLite::RowIDName).Equals(SQLite::Builder::Unbound);\r\n\r\n            return builder.Prepare(connection);\r\n        }\r\n\r\n        bool ManifestTableCheckConsistency(const SQLite::Connection& connection, const SQLite::Builder::QualifiedColumn& target, std::string_view manifestColumnName, bool log)\r\n        {\r\n            using QCol = SQLite::Builder::QualifiedColumn;\r\n\r\n            // Build a select statement to find manifest rows containing references to 1:1 tables with nonexistent rowids\r\n            // Such as:\r\n            // Select manifest.rowid, manifest.id, ids.id from manifest left outer join ids on manifest.id = ids.rowid where ids.id is NULL\r\n            SQLite::Builder::StatementBuilder builder;\r\n            builder.\r\n                Select({ QCol(s_ManifestTable_Table_Name, SQLite::RowIDName), QCol(s_ManifestTable_Table_Name, manifestColumnName) }).\r\n                From(s_ManifestTable_Table_Name).\r\n                LeftOuterJoin(target.Table).On(QCol(s_ManifestTable_Table_Name, manifestColumnName), QCol(target.Table, SQLite::RowIDName)).\r\n                Where(target).IsNull();\r\n\r\n            SQLite::Statement select = builder.Prepare(connection);\r\n            bool result = true;\r\n\r\n            while (select.Step())\r\n            {\r\n                result = false;\r\n\r\n                if (!log)\r\n                {\r\n                    break;\r\n                }\r\n\r\n                AICLI_LOG(Repo, Info, << \"  [INVALID] manifest [\" << select.GetColumn<SQLite::rowid_t>(0) << \"] refers to \" << target.Table << \" [\" << select.GetColumn<SQLite::rowid_t>(1) << \"]\");\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n\r\n    std::string_view ManifestTable::TableName()\r\n    {\r\n        return s_ManifestTable_Table_Name;\r\n    }\r\n\r\n    // Starting in V1.1, all code should be going this route of creating named indices rather than using primary or unique keys on columns.\r\n    // The resulting database will function the same, but give us control to drop the indices to reduce space.\r\n    void ManifestTable::Create(SQLite::Connection& connection, std::initializer_list<ManifestColumnInfo> values)\r\n    {\r\n        using namespace SQLite::Builder;\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"createManifestTable_v1_1\");\r\n\r\n        StatementBuilder createTableBuilder;\r\n        createTableBuilder.CreateTable(s_ManifestTable_Table_Name).BeginColumns();\r\n\r\n        // Add an integer primary key to keep the manifest rowid consistent\r\n        createTableBuilder.Column(IntegerPrimaryKey());\r\n\r\n        for (const ManifestColumnInfo& value : values)\r\n        {\r\n            createTableBuilder.Column(ColumnBuilder(value.Name, Type::Int64).NotNull());\r\n        }\r\n\r\n        createTableBuilder.EndColumns();\r\n\r\n        createTableBuilder.Execute(connection);\r\n\r\n        // Create a unique index with the primary key values\r\n        StatementBuilder pkIndexBuilder;\r\n\r\n        pkIndexBuilder.CreateUniqueIndex({ s_ManifestTable_Table_Name, s_ManifestTable_Index_Suffix }).On(s_ManifestTable_Table_Name).BeginColumns();\r\n\r\n        for (const ManifestColumnInfo& value : values)\r\n        {\r\n            if (value.PrimaryKey)\r\n            {\r\n                pkIndexBuilder.Column(value.Name);\r\n            }\r\n        }\r\n\r\n        pkIndexBuilder.EndColumns();\r\n\r\n        pkIndexBuilder.Execute(connection);\r\n\r\n        // Create an index on every value to improve performance\r\n        for (const ManifestColumnInfo& value : values)\r\n        {\r\n            StatementBuilder createIndexBuilder;\r\n\r\n            if (value.Unique)\r\n            {\r\n                createIndexBuilder.CreateUniqueIndex({ s_ManifestTable_Table_Name, s_ManifestTable_Index_Separator, value.Name, s_ManifestTable_Index_Suffix });\r\n            }\r\n            else\r\n            {\r\n                createIndexBuilder.CreateIndex({ s_ManifestTable_Table_Name, s_ManifestTable_Index_Separator, value.Name, s_ManifestTable_Index_Suffix });\r\n            }\r\n\r\n            createIndexBuilder.On(s_ManifestTable_Table_Name).Columns(value.Name);\r\n\r\n            createIndexBuilder.Execute(connection);\r\n        }\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    void ManifestTable::AddColumn(SQLite::Connection& connection, AddedColumnInfo value)\r\n    {\r\n        using namespace SQLite::Builder;\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"addColumnManifestTable_v1_3\");\r\n\r\n        StatementBuilder alterTableBuilder;\r\n        alterTableBuilder.AlterTable(s_ManifestTable_Table_Name).Add(value.Name, value.Type);\r\n\r\n        alterTableBuilder.Execute(connection);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    void ManifestTable::Create_deprecated(SQLite::Connection& connection, std::initializer_list<ManifestColumnInfo> values)\r\n    {\r\n        using namespace SQLite::Builder;\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"createManifestTable_v1_0\");\r\n\r\n        StatementBuilder createTableBuilder;\r\n        createTableBuilder.CreateTable(s_ManifestTable_Table_Name).BeginColumns();\r\n\r\n        for (const ManifestColumnInfo& value : values)\r\n        {\r\n            createTableBuilder.Column(ColumnBuilder(value.Name, Type::Int64).NotNull().Unique(value.Unique));\r\n        }\r\n\r\n        PrimaryKeyBuilder pkBuilder;\r\n        for (const ManifestColumnInfo& value : values)\r\n        {\r\n            if (value.PrimaryKey)\r\n            {\r\n                pkBuilder.Column(value.Name);\r\n            }\r\n        }\r\n\r\n        createTableBuilder.Column(pkBuilder).EndColumns();\r\n\r\n        createTableBuilder.Execute(connection);\r\n\r\n        // Create an index on every value to improve performance\r\n        for (const ManifestColumnInfo& value : values)\r\n        {\r\n            StatementBuilder createIndexBuilder;\r\n            createIndexBuilder.CreateIndex({ s_ManifestTable_Table_Name, s_ManifestTable_Index_Separator, value.Name, s_ManifestTable_Index_Suffix }).\r\n                On(s_ManifestTable_Table_Name).Columns(value.Name);\r\n\r\n            createIndexBuilder.Execute(connection);\r\n        }\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    void ManifestTable::Drop(SQLite::Connection& connection)\r\n    {\r\n        SQLite::Builder::StatementBuilder dropTableBuilder;\r\n        dropTableBuilder.DropTable(s_ManifestTable_Table_Name);\r\n\r\n        dropTableBuilder.Execute(connection);\r\n    }\r\n\r\n    SQLite::rowid_t ManifestTable::Insert(SQLite::Connection& connection, std::initializer_list<ManifestOneToOneValue> values)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.InsertInto(s_ManifestTable_Table_Name).BeginColumns();\r\n\r\n        for (const ManifestOneToOneValue& value : values)\r\n        {\r\n            builder.Column(value.Name);\r\n        }\r\n\r\n        builder.EndColumns().BeginValues();\r\n\r\n        for (const ManifestOneToOneValue& value : values)\r\n        {\r\n            builder.Value(value.Value);\r\n        }\r\n\r\n        builder.EndValues();\r\n\r\n        builder.Execute(connection);\r\n\r\n        return connection.GetLastInsertRowID();\r\n    }\r\n\r\n    bool ManifestTable::ExistsById(const SQLite::Connection& connection, SQLite::rowid_t id)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.Select(SQLite::Builder::RowCount).From(s_ManifestTable_Table_Name).Where(SQLite::RowIDName).Equals(id);\r\n\r\n        SQLite::Statement countStatement = builder.Prepare(connection);\r\n\r\n        THROW_HR_IF(E_UNEXPECTED, !countStatement.Step());\r\n\r\n        return (countStatement.GetColumn<int>(0) != 0);\r\n    }\r\n\r\n    void ManifestTable::DeleteById(SQLite::Connection& connection, SQLite::rowid_t id)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.DeleteFrom(s_ManifestTable_Table_Name).Where(SQLite::RowIDName).Equals(id);\r\n\r\n        builder.Execute(connection);\r\n    }\r\n\r\n    void ManifestTable::PrepareForPackaging(SQLite::Connection& connection, std::initializer_list<std::string_view> values)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"pfpManifestTable_v1_1\");\r\n\r\n        PrepareForPackaging_deprecated(connection, values);\r\n\r\n        SQLite::Builder::StatementBuilder dropPKIndexBuilder;\r\n        dropPKIndexBuilder.DropIndex({ s_ManifestTable_Table_Name, s_ManifestTable_Index_Suffix });\r\n        dropPKIndexBuilder.Execute(connection);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    void ManifestTable::PrepareForPackaging_deprecated(SQLite::Connection& connection, std::initializer_list<std::string_view> values)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"pfpManifestTable_v1_0\");\r\n\r\n        // Drop the index on the requested values\r\n        for (std::string_view value : values)\r\n        {\r\n            SQLite::Builder::StatementBuilder dropIndexBuilder;\r\n            dropIndexBuilder.DropIndex({ s_ManifestTable_Table_Name, s_ManifestTable_Index_Separator, value, s_ManifestTable_Index_Suffix });\r\n\r\n            dropIndexBuilder.Execute(connection);\r\n        }\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    bool ManifestTable::IsValueReferenced(const SQLite::Connection& connection, std::string_view valueName, SQLite::rowid_t valueRowId)\r\n    {\r\n        return details::ManifestTableSelectByValueIds(connection, { valueName }, { valueRowId }).has_value();\r\n    }\r\n\r\n    bool ManifestTable::IsEmpty(SQLite::Connection& connection)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.Select(SQLite::Builder::RowCount).From(s_ManifestTable_Table_Name);\r\n\r\n        SQLite::Statement countStatement = builder.Prepare(connection);\r\n\r\n        THROW_HR_IF(E_UNEXPECTED, !countStatement.Step());\r\n\r\n        return (countStatement.GetColumn<int>(0) == 0);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_0/ManifestTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteWrapper.h>\r\n#include <winget/SQLiteStatementBuilder.h>\r\n#include \"Microsoft/Schema/1_0/VirtualTableBase.h\"\r\n#include <initializer_list>\r\n#include <optional>\r\n#include <string_view>\r\n#include <utility>\r\n#include <vector>\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_0\r\n{\r\n    namespace details\r\n    {\r\n        template<typename Table>\r\n        std::string_view GetManifestTableColumnName()\r\n        {\r\n            if constexpr (std::is_base_of<VirtualTableBase, Table>())\r\n            {\r\n                return Table::ManifestColumnName();\r\n            }\r\n            else\r\n            {\r\n                return Table::ValueName();\r\n            }\r\n        }\r\n\r\n        // Selects a manifest by the given value id.\r\n        std::optional<SQLite::rowid_t> ManifestTableSelectByValueIds(\r\n            const SQLite::Connection& connection,\r\n            std::initializer_list<std::string_view> values,\r\n            std::initializer_list<SQLite::rowid_t> ids);\r\n\r\n        // Gets the requested ids for the manifest with the given rowid.\r\n        SQLite::Statement ManifestTableGetIdsById_Statement(\r\n            const SQLite::Connection& connection,\r\n            SQLite::rowid_t id,\r\n            std::initializer_list<std::string_view> values,\r\n            bool stepAndVerify = true);\r\n\r\n        // Gets the requested values for the manifest with the given rowid.\r\n        SQLite::Statement ManifestTableGetValuesById_Statement(\r\n            const SQLite::Connection& connection,\r\n            SQLite::rowid_t id,\r\n            std::initializer_list<SQLite::Builder::QualifiedColumn> columns,\r\n            std::initializer_list<std::string_view> manifestColumnNames,\r\n            bool stepAndVerify = true);\r\n\r\n        // Gets all values for rows that match the given ids.\r\n        SQLite::Statement ManifestTableGetAllValuesByIds_Statement(\r\n            const SQLite::Connection& connection,\r\n            std::initializer_list<SQLite::Builder::QualifiedColumn> valueColumns,\r\n            std::initializer_list<SQLite::Builder::QualifiedColumn> joinColumns,\r\n            std::initializer_list<std::string_view> idColumns,\r\n            std::initializer_list<SQLite::rowid_t> ids);\r\n\r\n        // Gets all values for rows that match the given ids.\r\n        std::vector<std::pair<SQLite::rowid_t, std::string>> ManifestTableGetAllValuesByIds(\r\n            const SQLite::Connection& connection,\r\n            std::initializer_list<SQLite::Builder::QualifiedColumn> valueColumns,\r\n            std::initializer_list<SQLite::Builder::QualifiedColumn> joinColumns,\r\n            std::initializer_list<std::string_view> idColumns,\r\n            std::initializer_list<SQLite::rowid_t> ids);\r\n\r\n        // Builds the search select statement base on the given values.\r\n        std::vector<int> ManifestTableBuildSearchStatement(\r\n            SQLite::Builder::StatementBuilder& builder,\r\n            std::initializer_list<SQLite::Builder::QualifiedColumn> columns,\r\n            std::initializer_list<bool> isOneToOnes,\r\n            std::string_view manifestAlias,\r\n            std::string_view valueAlias,\r\n            bool useLike);\r\n\r\n        // Prepares a statement to update the value of a single column for the manifest with the given rowid.\r\n        // The first bind value will be the value to set.\r\n        // The second bind value will be the manifest rowid to modify.\r\n        SQLite::Statement ManifestTableUpdateValueIdById_Statement(SQLite::Connection& connection, std::string_view valueName);\r\n\r\n        // Checks the consistency of the index to ensure that every referenced row exists.\r\n        // Returns true if index is consistent; false if it is not.\r\n        bool ManifestTableCheckConsistency(const SQLite::Connection& connection, const SQLite::Builder::QualifiedColumn& target, std::string_view manifestColumnName, bool log);\r\n    }\r\n\r\n    // Info on the manifest columns.\r\n    struct ManifestColumnInfo\r\n    {\r\n        std::string_view Name;\r\n        bool PrimaryKey;\r\n        bool Unique;\r\n    };\r\n\r\n    // Information on a column being added via ALTER TABLE\r\n    struct AddedColumnInfo\r\n    {\r\n        std::string_view Name;\r\n        SQLite::Builder::Type Type;\r\n    };\r\n\r\n    // A value that is 1:1 with the manifest.\r\n    struct ManifestOneToOneValue\r\n    {\r\n        std::string_view Name;\r\n        SQLite::rowid_t Value;\r\n    };\r\n\r\n    // A table that represents a single manifest\r\n    struct ManifestTable\r\n    {\r\n        // Get the table name.\r\n        static std::string_view TableName();\r\n\r\n        // Creates the table with named indices.\r\n        static void Create(SQLite::Connection& connection, std::initializer_list<ManifestColumnInfo> values);\r\n\r\n        // Alters the table, adding the columns provided.\r\n        static void AddColumn(SQLite::Connection& connection, AddedColumnInfo value);\r\n\r\n        // Creates the table with standard primary keys.\r\n        static void Create_deprecated(SQLite::Connection& connection, std::initializer_list<ManifestColumnInfo> values);\r\n\r\n        // Drops the table.\r\n        static void Drop(SQLite::Connection& connection);\r\n\r\n        // Insert the given values into the table.\r\n        static SQLite::rowid_t Insert(SQLite::Connection& connection, std::initializer_list<ManifestOneToOneValue> values);\r\n\r\n        // Gets a value indicating whether the manifest with rowid id exists.\r\n        static bool ExistsById(const SQLite::Connection& connection, SQLite::rowid_t id);\r\n\r\n        // Select the first rowid of the manifest with the given value.\r\n        template <typename... Tables>\r\n        static std::optional<SQLite::rowid_t> SelectByValueIds(const SQLite::Connection& connection, std::initializer_list<SQLite::rowid_t> ids)\r\n        {\r\n            static_assert(sizeof...(Tables) >= 1);\r\n            return details::ManifestTableSelectByValueIds(connection, { Tables::ValueName()... }, ids);\r\n        }\r\n\r\n        // Gets the ids requested for the manifest with the given rowid.\r\n        template <typename... Tables>\r\n        static auto GetIdsById(const SQLite::Connection& connection, SQLite::rowid_t id)\r\n        {\r\n            return details::ManifestTableGetIdsById_Statement(connection, id, { details::GetManifestTableColumnName<Tables>()...}).GetRow<typename Tables::id_t...>();\r\n        }\r\n\r\n        // Gets the id requested for the manifest with the given rowid, if it exists.\r\n        template <typename Table>\r\n        static std::optional<typename Table::id_t> GetIdById(const SQLite::Connection& connection, SQLite::rowid_t id)\r\n        {\r\n            auto statement = details::ManifestTableGetIdsById_Statement(connection, id, { details::GetManifestTableColumnName<Table>() }, false);\r\n            if (statement.Step()) { return statement.GetColumn<typename Table::id_t>(0); }\r\n            else { return std::nullopt; }\r\n        }\r\n\r\n        // Gets the values requested for the manifest with the given rowid.\r\n        template <typename... Tables>\r\n        static auto GetValuesById(const SQLite::Connection& connection, SQLite::rowid_t id)\r\n        {\r\n            return details::ManifestTableGetValuesById_Statement(connection, id, { SQLite::Builder::QualifiedColumn{ Tables::TableName(), Tables::ValueName() }... }, { details::GetManifestTableColumnName<Tables>()... }).GetRow<typename Tables::value_t...>();\r\n        }\r\n\r\n        // Gets the value requested for the manifest with the given rowid, if it exists.\r\n        template <typename Table>\r\n        static std::optional<typename Table::value_t> GetValueById(const SQLite::Connection& connection, SQLite::rowid_t id)\r\n        {\r\n            auto statement = details::ManifestTableGetValuesById_Statement(connection, id, { SQLite::Builder::QualifiedColumn{ Table::TableName(), Table::ValueName() } }, { details::GetManifestTableColumnName<Table>() }, false);\r\n            if (statement.Step()) { return statement.GetColumn<typename Table::value_t>(0); }\r\n            else { return std::nullopt; }\r\n        }\r\n\r\n        // Gets the row ids and values for rows that match the given ids.\r\n        template <typename ValueTable, typename... IdTables>\r\n        static std::vector<std::pair<SQLite::rowid_t, typename ValueTable::value_t>> GetAllValuesByIds(const SQLite::Connection& connection, std::initializer_list<SQLite::rowid_t> ids)\r\n        {\r\n            return details::ManifestTableGetAllValuesByIds(connection,\r\n                { SQLite::Builder::QualifiedColumn{ ValueTable::TableName(), SQLite::RowIDName }, SQLite::Builder::QualifiedColumn{ ValueTable::TableName(), ValueTable::ValueName() } },\r\n                { SQLite::Builder::QualifiedColumn{ ValueTable::TableName(), ValueTable::ValueName() } },\r\n                { IdTables::ValueName()... }, ids);\r\n        }\r\n\r\n        // Gets all values for rows that match the given id.\r\n        template <typename IdTable, typename... ValueTables>\r\n        static std::vector<std::tuple<SQLite::rowid_t, typename ValueTables::value_t...>> GetAllValuesById(const SQLite::Connection& connection, SQLite::rowid_t id)\r\n        {\r\n            auto stmt = details::ManifestTableGetAllValuesByIds_Statement(connection,\r\n                { SQLite::Builder::QualifiedColumn{ TableName(), SQLite::RowIDName }, SQLite::Builder::QualifiedColumn{ ValueTables::TableName(), ValueTables::ValueName() }... },\r\n                { SQLite::Builder::QualifiedColumn{ ValueTables::TableName(), ValueTables::ValueName() }... },\r\n                { IdTable::ValueName() }, { id });\r\n            std::vector<std::tuple<SQLite::rowid_t, typename ValueTables::value_t...>> result;\r\n            while (stmt.Step())\r\n            {\r\n                result.emplace_back(stmt.GetRow<SQLite::rowid_t, typename ValueTables::value_t...>());\r\n            }\r\n            return result;\r\n        }\r\n\r\n        // Builds the search select statement base on the given values.\r\n        // If more than one table is provided, no value will be captured.\r\n        // The return value is the bind indices of the values to match against.\r\n        template <typename... Table>\r\n        static std::vector<int> BuildSearchStatement(SQLite::Builder::StatementBuilder& builder, std::string_view manifestAlias, std::string_view valueAlias, bool useLike)\r\n        {\r\n            return details::ManifestTableBuildSearchStatement(builder, { SQLite::Builder::QualifiedColumn{ Table::TableName(), Table::ValueName() }... }, { Table::IsOneToOne()... }, manifestAlias, valueAlias, useLike);\r\n        }\r\n\r\n        // Update the value of a single column for the manifest with the given rowid.\r\n        template <typename Table>\r\n        static void UpdateValueIdById(SQLite::Connection& connection, SQLite::rowid_t id, const typename Table::id_t& value)\r\n        {\r\n            auto stmt = details::ManifestTableUpdateValueIdById_Statement(connection, details::GetManifestTableColumnName<Table>());\r\n            stmt.Bind(1, value);\r\n            stmt.Bind(2, id);\r\n            stmt.Execute();\r\n        }\r\n\r\n        // Deletes the manifest row with the given rowid.\r\n        static void DeleteById(SQLite::Connection& connection, SQLite::rowid_t id);\r\n\r\n        // Removes data that is no longer needed for an index that is to be published.\r\n        static void PrepareForPackaging(SQLite::Connection& connection, std::initializer_list<std::string_view> values);\r\n\r\n        // Removes data that is no longer needed for an index that is to be published.\r\n        static void PrepareForPackaging_deprecated(SQLite::Connection& connection, std::initializer_list<std::string_view> values);\r\n\r\n        // Checks if the row id is present in the column denoted by the value supplied.\r\n        static bool IsValueReferenced(const SQLite::Connection& connection, std::string_view valueName, SQLite::rowid_t valueRowId);\r\n\r\n        // Checks the consistency of the index to ensure that every referenced row exists.\r\n        // Returns true if index is consistent; false if it is not.\r\n        template <typename Table>\r\n        static bool CheckConsistency(const SQLite::Connection& connection, bool log)\r\n        {\r\n            return details::ManifestTableCheckConsistency(\r\n                connection, SQLite::Builder::QualifiedColumn{ Table::TableName(), Table::ValueName() }, details::GetManifestTableColumnName<Table>(), log);\r\n        }\r\n\r\n        // Determines if the table is empty.\r\n        static bool IsEmpty(SQLite::Connection& connection);\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_0/MonikerTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/1_0/OneToOneTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_0\r\n{\r\n    namespace details\r\n    {\r\n        using namespace std::string_view_literals;\r\n\r\n        struct MonikerTableInfo\r\n        {\r\n            inline static constexpr std::string_view TableName() { return \"monikers\"sv; }\r\n            inline static constexpr std::string_view ValueName() { return \"moniker\"sv; }\r\n        };\r\n    }\r\n\r\n    // The table for Moniker.\r\n    using MonikerTable = OneToOneTable<details::MonikerTableInfo>;\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_0/NameTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/1_0/OneToOneTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_0\r\n{\r\n    namespace details\r\n    {\r\n        using namespace std::string_view_literals;\r\n\r\n        struct NameTableInfo\r\n        {\r\n            inline static constexpr std::string_view TableName() { return \"names\"sv; }\r\n            inline static constexpr std::string_view ValueName() { return \"name\"sv; }\r\n        };\r\n    }\r\n\r\n    // The table for Name.\r\n    // TODO: Currently only indexing name from default locale, might need to be OneToMany table\r\n    using NameTable = OneToOneTable<details::NameTableInfo>;\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_0/OneToManyTable.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Microsoft/Schema/1_0/OneToManyTable.h\"\r\n#include \"Microsoft/Schema/1_0/OneToOneTable.h\"\r\n#include \"Microsoft/Schema/1_0/ManifestTable.h\"\r\n#include \"Microsoft/Schema/1_0/IdTable.h\"\r\n#include <winget/SQLiteStatementBuilder.h>\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_0\r\n{\r\n    namespace details\r\n    {\r\n        using namespace std::string_view_literals;\r\n        static constexpr std::string_view s_OneToManyTable_MapTable_ManifestName = \"manifest\"sv;\r\n        static constexpr std::string_view s_OneToManyTable_MapTable_Suffix = \"_map\"sv;\r\n        static constexpr std::string_view s_OneToManyTable_MapTable_PrimaryKeyIndexSuffix = \"_pkindex\"sv;\r\n        static constexpr std::string_view s_OneToManyTable_MapTable_IndexSuffix = \"_index\"sv;\r\n\r\n        namespace\r\n        {\r\n            // Create the mapping table insert statement for multiple use.\r\n            // Bind the rowid of the value to 2.\r\n            SQLite::Statement CreateMappingInsertStatementForManifestId(SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, SQLite::rowid_t manifestId)\r\n            {\r\n                SQLite::Builder::StatementBuilder insertMappingBuilder;\r\n                insertMappingBuilder.InsertInto({ tableName, s_OneToManyTable_MapTable_Suffix }).\r\n                    Columns({ s_OneToManyTable_MapTable_ManifestName, valueName }).Values(manifestId, SQLite::Builder::Unbound);\r\n\r\n                return insertMappingBuilder.Prepare(connection);\r\n            }\r\n\r\n            // Get a collection of the value ids associated with the given manifest id.\r\n            std::vector<SQLite::rowid_t> GetValueIdsByManifestId(SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, SQLite::rowid_t manifestId)\r\n            {\r\n                std::vector<SQLite::rowid_t> result;\r\n\r\n                SQLite::Builder::StatementBuilder selectMappingBuilder;\r\n                selectMappingBuilder.Select(valueName).From({ tableName, s_OneToManyTable_MapTable_Suffix }).Where(s_OneToManyTable_MapTable_ManifestName).Equals(manifestId);\r\n\r\n                SQLite::Statement selectMappingStatement = selectMappingBuilder.Prepare(connection);\r\n\r\n                while (selectMappingStatement.Step())\r\n                {\r\n                    result.push_back(selectMappingStatement.GetColumn<SQLite::rowid_t>(0));\r\n                }\r\n\r\n                return result;\r\n            }\r\n\r\n            struct DeleteValueIfNotNeededStatements\r\n            {\r\n                DeleteValueIfNotNeededStatements(SQLite::Connection& connection, std::string_view tableName, std::string_view valueName)\r\n                {\r\n                    SQLite::Builder::StatementBuilder selectValueMappingBuilder;\r\n                    selectValueMappingBuilder.Select(s_OneToManyTable_MapTable_ManifestName).From({ tableName, s_OneToManyTable_MapTable_Suffix }).Where(valueName).Equals(SQLite::Builder::Unbound).Limit(1);\r\n\r\n                    SelectIfAnyMappingsByValueId = selectValueMappingBuilder.Prepare(connection);\r\n\r\n                    SQLite::Builder::StatementBuilder deleteValueBuilder;\r\n                    deleteValueBuilder.DeleteFrom(tableName).Where(SQLite::RowIDName).Equals(SQLite::Builder::Unbound);\r\n\r\n                    DeleteValueById = deleteValueBuilder.Prepare(connection);\r\n                }\r\n\r\n                void Execute(SQLite::rowid_t valueId)\r\n                {\r\n                    SelectIfAnyMappingsByValueId.Reset();\r\n                    SelectIfAnyMappingsByValueId.Bind(1, valueId);\r\n\r\n                    // If no rows are found, we can delete the data.\r\n                    if (!SelectIfAnyMappingsByValueId.Step())\r\n                    {\r\n                        DeleteValueById.Reset();\r\n                        DeleteValueById.Bind(1, valueId);\r\n\r\n                        DeleteValueById.Execute();\r\n                    }\r\n                }\r\n\r\n            private:\r\n                // Bind valid rowid to 1.\r\n                SQLite::Statement SelectIfAnyMappingsByValueId;\r\n                // Bind valid rowid to 1.\r\n                SQLite::Statement DeleteValueById;\r\n            };\r\n\r\n            bool SchemaVersionUsesNamedIndices(OneToManyTableSchema schemaVersion)\r\n            {\r\n                return schemaVersion != OneToManyTableSchema::Version_1_0;\r\n            }\r\n        }\r\n\r\n        std::string OneToManyTableGetMapTableName(std::string_view tableName)\r\n        {\r\n            std::string result(tableName);\r\n            result += s_OneToManyTable_MapTable_Suffix;\r\n            return result;\r\n        }\r\n\r\n        std::string_view OneToManyTableGetManifestColumnName()\r\n        {\r\n            return s_OneToManyTable_MapTable_ManifestName;\r\n        }\r\n\r\n        void CreateOneToManyTable(SQLite::Connection& connection, OneToManyTableSchema schemaVersion, std::string_view tableName, std::string_view valueName)\r\n        {\r\n            using namespace SQLite::Builder;\r\n\r\n            SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, std::string{ tableName } + \"_create_v1_0\");\r\n\r\n            // Create the data table as a 1:1\r\n            CreateOneToOneTable(connection, tableName, valueName, SchemaVersionUsesNamedIndices(schemaVersion));\r\n\r\n            switch (schemaVersion)\r\n            {\r\n            case OneToManyTableSchema::Version_1_0:\r\n            {\r\n                // Create the mapping table\r\n                StatementBuilder createMapTableBuilder;\r\n                createMapTableBuilder.CreateTable({ tableName, s_OneToManyTable_MapTable_Suffix }).Columns({\r\n                    ColumnBuilder(s_OneToManyTable_MapTable_ManifestName, Type::Int64).NotNull(),\r\n                    ColumnBuilder(valueName, Type::Int64).NotNull(),\r\n                    PrimaryKeyBuilder({ valueName, s_OneToManyTable_MapTable_ManifestName })\r\n                    });\r\n\r\n                createMapTableBuilder.Execute(connection);\r\n            }\r\n                break;\r\n            case OneToManyTableSchema::Version_1_1:\r\n            {\r\n                // Create the mapping table\r\n                StatementBuilder createMapTableBuilder;\r\n                createMapTableBuilder.CreateTable({ tableName, s_OneToManyTable_MapTable_Suffix }).Columns({\r\n                    ColumnBuilder(s_OneToManyTable_MapTable_ManifestName, Type::Int64).NotNull(),\r\n                    ColumnBuilder(valueName, Type::Int64).NotNull()\r\n                    });\r\n\r\n                createMapTableBuilder.Execute(connection);\r\n\r\n                StatementBuilder pkIndexBuilder;\r\n                pkIndexBuilder.CreateUniqueIndex({ tableName, s_OneToManyTable_MapTable_Suffix, s_OneToManyTable_MapTable_PrimaryKeyIndexSuffix }).\r\n                    On({ tableName, s_OneToManyTable_MapTable_Suffix }).Columns({ valueName, s_OneToManyTable_MapTable_ManifestName });\r\n                pkIndexBuilder.Execute(connection);\r\n            }\r\n                break;\r\n            case OneToManyTableSchema::Version_1_7:\r\n            {\r\n                // Create the mapping table\r\n                StatementBuilder createMapTableBuilder;\r\n                createMapTableBuilder.CreateTable({ tableName, s_OneToManyTable_MapTable_Suffix }).Columns({\r\n                    ColumnBuilder(s_OneToManyTable_MapTable_ManifestName, Type::Int64).NotNull(),\r\n                    ColumnBuilder(valueName, Type::Int64).NotNull(),\r\n                    PrimaryKeyBuilder({ valueName, s_OneToManyTable_MapTable_ManifestName })\r\n                    }).WithoutRowID();\r\n\r\n                createMapTableBuilder.Execute(connection);\r\n            }\r\n                break;\r\n            default:\r\n                THROW_HR(E_UNEXPECTED);\r\n            }\r\n\r\n            StatementBuilder createMapTableIndexBuilder;\r\n            createMapTableIndexBuilder.CreateIndex({ tableName, s_OneToManyTable_MapTable_Suffix, s_OneToManyTable_MapTable_IndexSuffix }).\r\n                On({ tableName, s_OneToManyTable_MapTable_Suffix }).Columns({ s_OneToManyTable_MapTable_ManifestName, valueName });\r\n\r\n            createMapTableIndexBuilder.Execute(connection);\r\n\r\n            savepoint.Commit();\r\n        }\r\n\r\n        void DropOneToManyTable(SQLite::Connection& connection, std::string_view tableName)\r\n        {\r\n            SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, std::string{ tableName } + \"_drop_v1_0\");\r\n\r\n            DropOneToOneTable(connection, tableName);\r\n\r\n            SQLite::Builder::StatementBuilder dropTableBuilder;\r\n            dropTableBuilder.DropTable({ tableName, s_OneToManyTable_MapTable_Suffix });\r\n\r\n            dropTableBuilder.Execute(connection);\r\n\r\n            savepoint.Commit();\r\n        }\r\n\r\n        std::vector<std::string> OneToManyTableGetValuesByManifestId(\r\n            const SQLite::Connection& connection,\r\n            std::string_view tableName,\r\n            std::string_view valueName,\r\n            SQLite::rowid_t manifestId)\r\n        {\r\n            using QCol = SQLite::Builder::QualifiedColumn;\r\n\r\n            std::vector<std::string> result;\r\n\r\n            SQLite::Builder::StatementBuilder builder;\r\n            builder.Select(QCol(tableName, valueName)).\r\n                From({ tableName, s_OneToManyTable_MapTable_Suffix }).As(\"map\").Join(tableName).\r\n                On(QCol(\"map\", valueName), QCol(tableName, SQLite::RowIDName)).Where(QCol(\"map\", s_OneToManyTable_MapTable_ManifestName)).Equals(manifestId);\r\n\r\n            SQLite::Statement statement = builder.Prepare(connection);\r\n\r\n            while (statement.Step())\r\n            {\r\n                result.emplace_back(statement.GetColumn<std::string>(0));\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        void OneToManyTableEnsureExistsAndInsert(SQLite::Connection& connection,\r\n            std::string_view tableName, std::string_view valueName,\r\n            const std::vector<Utility::NormalizedString>& values, SQLite::rowid_t manifestId)\r\n        {\r\n            SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, std::string{ tableName } + \"_ensureandinsert_v1_0\");\r\n\r\n            SQLite::Statement insertMapping = CreateMappingInsertStatementForManifestId(connection, tableName, valueName, manifestId);\r\n\r\n            for (const std::string& value : values)\r\n            {\r\n                // First, ensure that the data exists\r\n                SQLite::rowid_t dataId = OneToOneTableEnsureExists(connection, tableName, valueName, value);\r\n\r\n                // Second, insert into the mapping table\r\n                insertMapping.Reset();\r\n                insertMapping.Bind(2, dataId);\r\n\r\n                insertMapping.Execute();\r\n            }\r\n\r\n            savepoint.Commit();\r\n        }\r\n\r\n        bool OneToManyTableUpdateIfNeededByManifestId(SQLite::Connection& connection,\r\n            std::string_view tableName, std::string_view valueName,\r\n            const std::vector<Utility::NormalizedString>& values, SQLite::rowid_t manifestId)\r\n        {\r\n            std::vector<SQLite::rowid_t> oldValueIds = GetValueIdsByManifestId(connection, tableName, valueName, manifestId);\r\n            bool modificationNeeded = false;\r\n\r\n            SQLite::Statement insertMapping = CreateMappingInsertStatementForManifestId(connection, tableName, valueName, manifestId);\r\n\r\n            for (const std::string& value : values)\r\n            {\r\n                SQLite::rowid_t valueId = OneToOneTableEnsureExists(connection, tableName, valueName, value);\r\n\r\n                auto itr = std::find(oldValueIds.begin(), oldValueIds.end(), valueId);\r\n                if (itr != oldValueIds.end())\r\n                {\r\n                    oldValueIds.erase(itr);\r\n                }\r\n                else\r\n                {\r\n                    modificationNeeded = true;\r\n\r\n                    insertMapping.Reset();\r\n                    insertMapping.Bind(2, valueId);\r\n\r\n                    insertMapping.Execute();\r\n                }\r\n            }\r\n\r\n            // All incoming values are now present, we just need to delete the remaining old ones.\r\n            SQLite::Builder::StatementBuilder deleteBuilder;\r\n            deleteBuilder.DeleteFrom({ tableName, s_OneToManyTable_MapTable_Suffix }).\r\n                Where(s_OneToManyTable_MapTable_ManifestName).Equals(manifestId).And(valueName).Equals(SQLite::Builder::Unbound);\r\n\r\n            SQLite::Statement deleteStatement = deleteBuilder.Prepare(connection);\r\n\r\n            DeleteValueIfNotNeededStatements dvinns(connection, tableName, valueName);\r\n\r\n            for (SQLite::rowid_t valueId : oldValueIds)\r\n            {\r\n                modificationNeeded = true;\r\n\r\n                // First, delete the mapping\r\n                deleteStatement.Reset();\r\n                deleteStatement.Bind(2, valueId);\r\n\r\n                deleteStatement.Execute();\r\n\r\n                // Second, delete the value itself if not needed\r\n                dvinns.Execute(valueId);\r\n            }\r\n\r\n            return modificationNeeded;\r\n        }\r\n\r\n        void OneToManyTableDeleteIfNotNeededByManifestId(SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, SQLite::rowid_t manifestId)\r\n        {\r\n            SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, std::string{ tableName } + \"_deleteifnotneeded_v1_0\");\r\n\r\n            // Get values referenced by the manifest id.\r\n            std::vector<SQLite::rowid_t> values = GetValueIdsByManifestId(connection, tableName, valueName, manifestId);\r\n\r\n            // Delete the mapping table rows with the manifest id.\r\n            SQLite::Builder::StatementBuilder deleteBuilder;\r\n            deleteBuilder.DeleteFrom({ tableName, s_OneToManyTable_MapTable_Suffix }).Where(s_OneToManyTable_MapTable_ManifestName).Equals(manifestId);\r\n\r\n            deleteBuilder.Execute(connection);\r\n\r\n            // For each value, see if any references exist\r\n            DeleteValueIfNotNeededStatements dvinns(connection, tableName, valueName);\r\n\r\n            for (SQLite::rowid_t value : values)\r\n            {\r\n                dvinns.Execute(value);\r\n            }\r\n\r\n            savepoint.Commit();\r\n        }\r\n\r\n        void OneToManyTablePrepareForPackaging(SQLite::Connection& connection, std::string_view tableName, OneToManyTableSchema schemaVersion, bool preserveManifestIndex, bool preserveValuesIndex)\r\n        {\r\n            if (!preserveManifestIndex)\r\n            {\r\n                SQLite::Builder::StatementBuilder dropMapTableIndexBuilder;\r\n                dropMapTableIndexBuilder.DropIndex({ tableName, s_OneToManyTable_MapTable_Suffix, s_OneToManyTable_MapTable_IndexSuffix });\r\n\r\n                dropMapTableIndexBuilder.Execute(connection);\r\n            }\r\n\r\n            OneToOneTablePrepareForPackaging(connection, tableName, SchemaVersionUsesNamedIndices(schemaVersion), preserveValuesIndex);\r\n        }\r\n\r\n        bool OneToManyTableCheckConsistency(const SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, bool log)\r\n        {\r\n            using QCol = SQLite::Builder::QualifiedColumn;\r\n            constexpr std::string_view s_map = \"map\"sv;\r\n\r\n            bool result = true;\r\n\r\n            {\r\n                // Build a select statement to find map rows containing references to manifests with nonexistent rowids\r\n                // Such as:\r\n                // Select map.rowid, map.manifest from tags_map as map left outer join manifest on map.manifest = manifest.rowid where manifest.id is null\r\n\r\n                SQLite::Builder::StatementBuilder builder;\r\n                builder.\r\n                    Select({ QCol(s_map, s_OneToManyTable_MapTable_ManifestName), QCol(s_map, valueName) }).\r\n                    From({ tableName, s_OneToManyTable_MapTable_Suffix }).As(s_map).\r\n                    LeftOuterJoin(ManifestTable::TableName()).On(QCol(s_map, s_OneToManyTable_MapTable_ManifestName), QCol(ManifestTable::TableName(), SQLite::RowIDName)).\r\n                    Where(QCol(ManifestTable::TableName(), SQLite::RowIDName)).IsNull();\r\n\r\n                SQLite::Statement select = builder.Prepare(connection);\r\n\r\n                while (select.Step())\r\n                {\r\n                    result = false;\r\n\r\n                    if (!log)\r\n                    {\r\n                        break;\r\n                    }\r\n\r\n                    AICLI_LOG(Repo, Info, << \"  [INVALID] \" << tableName << s_OneToManyTable_MapTable_Suffix << \" [\" << select.GetColumn<SQLite::rowid_t>(0) <<\r\n                        \", \" << select.GetColumn<SQLite::rowid_t>(1) << \"] refers to invalid \" << ManifestTable::TableName());\r\n                }\r\n            }\r\n\r\n            if (!result && !log)\r\n            {\r\n                return result;\r\n            }\r\n\r\n            {\r\n                // Build a select statement to find map rows containing references to 1:1 tables with nonexistent rowids\r\n                // Such as:\r\n                // Select map.rowid, map.tag from tags_map as map left outer join tags on map.tag = tags.rowid where tags.tag is null\r\n                SQLite::Builder::StatementBuilder builder;\r\n                builder.\r\n                    Select({ QCol(s_map, s_OneToManyTable_MapTable_ManifestName), QCol(s_map, valueName) }).\r\n                    From({ tableName, s_OneToManyTable_MapTable_Suffix }).As(s_map).\r\n                    LeftOuterJoin(tableName).On(QCol(s_map, valueName), QCol(tableName, SQLite::RowIDName)).\r\n                    Where(QCol(tableName, valueName)).IsNull();\r\n\r\n                SQLite::Statement select = builder.Prepare(connection);\r\n                bool secondaryResult = true;\r\n\r\n                while (select.Step())\r\n                {\r\n                    secondaryResult = false;\r\n\r\n                    if (!log)\r\n                    {\r\n                        break;\r\n                    }\r\n\r\n                    AICLI_LOG(Repo, Info, << \"  [INVALID] \" << tableName << s_OneToManyTable_MapTable_Suffix << \" [\" << select.GetColumn<SQLite::rowid_t>(0) <<\r\n                        \", \" << select.GetColumn<SQLite::rowid_t>(1) << \"] refers to invalid \" << tableName);\r\n                }\r\n\r\n                result = result && secondaryResult;\r\n            }\r\n\r\n            if (!result && !log)\r\n            {\r\n                return result;\r\n            }\r\n\r\n            result = OneToOneTableCheckConsistency(connection, tableName, valueName, log) && result;\r\n\r\n            return result;\r\n        }\r\n\r\n        bool OneToManyTableIsEmpty(SQLite::Connection& connection, std::string_view tableName)\r\n        {\r\n            SQLite::Builder::StatementBuilder countBuilder;\r\n            countBuilder.Select(SQLite::Builder::RowCount).From(tableName);\r\n\r\n            SQLite::Statement countStatement = countBuilder.Prepare(connection);\r\n\r\n            THROW_HR_IF(E_UNEXPECTED, !countStatement.Step());\r\n\r\n            SQLite::Builder::StatementBuilder countMapBuilder;\r\n            countMapBuilder.Select(SQLite::Builder::RowCount).From({ tableName, s_OneToManyTable_MapTable_Suffix });\r\n\r\n            SQLite::Statement countMapStatement = countMapBuilder.Prepare(connection);\r\n\r\n            THROW_HR_IF(E_UNEXPECTED, !countMapStatement.Step());\r\n\r\n            return ((countStatement.GetColumn<int>(0) == 0) && (countMapStatement.GetColumn<int>(0) == 0));\r\n        }\r\n\r\n        SQLite::Statement OneToManyTablePrepareMapDataFoldingStatement(const SQLite::Connection& connection, std::string_view tableName)\r\n        {\r\n            using namespace SQLite::Builder;\r\n            StatementBuilder builder;\r\n\r\n            // Create a statement that will collapse (and dedupe) all rows in the map to the latest (max) manifest for a given id, like:\r\n            // UPDATE OR REPLACE map SET manifest = (SELECT MAX(rowid) FROM manifest_table WHERE id = ?1) WHERE manifest IN (SELECT rowid FROM manifest_table WHERE id = ?1)\r\n            builder.UpdateOrReplace({ tableName, s_OneToManyTable_MapTable_Suffix }).Set().Column(s_OneToManyTable_MapTable_ManifestName).Equals()\r\n                .BeginParenthetical()\r\n                    .Select().Column(Aggregate::Max, SQLite::RowIDName).From(ManifestTable::TableName()).Where(IdTable::ValueName()).Equals(Unbound, 1)\r\n                .EndParenthetical()\r\n                .Where(s_OneToManyTable_MapTable_ManifestName).In()\r\n                .BeginParenthetical()\r\n                    .Select(SQLite::RowIDName).From(ManifestTable::TableName()).Where(IdTable::ValueName()).Equals(Unbound, 1)\r\n                .EndParenthetical();\r\n\r\n            return builder.Prepare(connection);\r\n        }\r\n    }\r\n\r\n    std::optional<SQLite::rowid_t> OneToManyTableGetMapDataFoldingManifestTargetId(const SQLite::Connection& connection, SQLite::rowid_t manifestId)\r\n    {\r\n        using namespace SQLite::Builder;\r\n        StatementBuilder builder;\r\n\r\n        // Select the maximum manifest rowid from the manifests whose id is the same as the row with the given manifest rowid, like:\r\n        // SELECT MAX(rowid) FROM manifest_table WHERE id = (SELECT id FROM manifest_table WHERE rowid = ?)\r\n        builder.Select().Column(Aggregate::Max, SQLite::RowIDName).From(ManifestTable::TableName()).Where(IdTable::ValueName()).Equals()\r\n            .BeginParenthetical()\r\n                .Select(IdTable::ValueName()).From(ManifestTable::TableName()).Where(SQLite::RowIDName).Equals(manifestId)\r\n            .EndParenthetical();\r\n\r\n        SQLite::Statement statement = builder.Prepare(connection);\r\n\r\n        if (statement.Step() && !statement.GetColumnIsNull(0))\r\n        {\r\n            return statement.GetColumn<SQLite::rowid_t>(0);\r\n        }\r\n\r\n        return std::nullopt;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_0/OneToManyTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteWrapper.h>\r\n#include <string>\r\n#include <string_view>\r\n#include <vector>\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_0\r\n{\r\n    // Allow the different schema version to indicate which they are.\r\n    enum class OneToManyTableSchema\r\n    {\r\n        // Does not used a named unique index for either table.\r\n        // Map table has primary key and rowid.\r\n        Version_1_0,\r\n        // Uses a named unique index for both tables.\r\n        // Map table has rowid.\r\n        Version_1_1,\r\n        // Uses a named unique index for data table. (No change from 1.1)\r\n        // Map table has primary key and no rowid.\r\n        Version_1_7,\r\n    };\r\n\r\n    namespace details\r\n    {\r\n        // Returns the map table name for a given table.\r\n        std::string OneToManyTableGetMapTableName(std::string_view tableName);\r\n\r\n        // Returns the manifest column name.\r\n        std::string_view OneToManyTableGetManifestColumnName();\r\n\r\n        // Create the tables.\r\n        void CreateOneToManyTable(SQLite::Connection& connection, OneToManyTableSchema schemaVersion, std::string_view tableName, std::string_view valueName);\r\n\r\n        // Drop the tables.\r\n        void DropOneToManyTable(SQLite::Connection& connection, std::string_view tableName);\r\n\r\n        // Gets all values associated with the given manifest id.\r\n        std::vector<std::string> OneToManyTableGetValuesByManifestId(\r\n            const SQLite::Connection& connection,\r\n            std::string_view tableName,\r\n            std::string_view valueName,\r\n            SQLite::rowid_t manifestId);\r\n\r\n        // Ensures that the value exists and inserts mapping entries.\r\n        void OneToManyTableEnsureExistsAndInsert(SQLite::Connection& connection,\r\n            std::string_view tableName, std::string_view valueName, \r\n            const std::vector<Utility::NormalizedString>& values, SQLite::rowid_t manifestId);\r\n\r\n        // Updates the mapping table to represent the given values for the manifest.\r\n        bool OneToManyTableUpdateIfNeededByManifestId(SQLite::Connection& connection,\r\n            std::string_view tableName, std::string_view valueName,\r\n            const std::vector<Utility::NormalizedString>& values, SQLite::rowid_t manifestId);\r\n\r\n        // Deletes the mapping rows for the given manifest, then removes any unused data rows.\r\n        void OneToManyTableDeleteIfNotNeededByManifestId(SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, SQLite::rowid_t manifestId);\r\n\r\n        // Removes data that is no longer needed for an index that is to be published.\r\n        void OneToManyTablePrepareForPackaging(SQLite::Connection& connection, std::string_view tableName, OneToManyTableSchema schemaVersion, bool preserveManifestIndex, bool preserveValuesIndex);\r\n\r\n        // Checks the consistency of the index to ensure that every referenced row exists.\r\n        // Returns true if index is consistent; false if it is not.\r\n         bool OneToManyTableCheckConsistency(const SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, bool log);\r\n\r\n        // Determines if the table is empty.\r\n        bool OneToManyTableIsEmpty(SQLite::Connection& connection, std::string_view tableName);\r\n\r\n        // Prepares a statement for replacing all of the map data to point to a single manifest for a given id.\r\n        SQLite::Statement OneToManyTablePrepareMapDataFoldingStatement(const SQLite::Connection& connection, std::string_view tableName);\r\n    }\r\n\r\n    // Gets the manifest id that the PrepareMapDataFoldingStatement will fold to for the given manifest id.\r\n    std::optional<SQLite::rowid_t> OneToManyTableGetMapDataFoldingManifestTargetId(const SQLite::Connection& connection, SQLite::rowid_t manifestId);\r\n\r\n    // A table that represents a value that is 1:N with a primary entry.\r\n    template <typename TableInfo>\r\n    struct OneToManyTable\r\n    {\r\n        // The name of the table.\r\n        static constexpr std::string_view TableName()\r\n        {\r\n            return TableInfo::TableName();\r\n        }\r\n\r\n        // The value name of the table.\r\n        static constexpr std::string_view ValueName()\r\n        {\r\n            return TableInfo::ValueName();\r\n        }\r\n\r\n        // Value indicating type.\r\n        static constexpr bool IsOneToOne()\r\n        {\r\n            return false;\r\n        }\r\n\r\n        // Creates the table with named indices.\r\n        static void Create(SQLite::Connection& connection, OneToManyTableSchema schemaVersion)\r\n        {\r\n            details::CreateOneToManyTable(connection, schemaVersion, TableInfo::TableName(), TableInfo::ValueName());\r\n        }\r\n\r\n        // Drops the table.\r\n        static void Drop(SQLite::Connection& connection)\r\n        {\r\n            details::DropOneToManyTable(connection, TableInfo::TableName());\r\n        }\r\n\r\n        // Gets all values associated with the given manifest id.\r\n        static std::vector<std::string> GetValuesByManifestId(const SQLite::Connection& connection, SQLite::rowid_t manifestId)\r\n        {\r\n            return details::OneToManyTableGetValuesByManifestId(connection, TableInfo::TableName(), TableInfo::ValueName(), manifestId);\r\n        }\r\n\r\n        // Ensures that all values exist in the data table, and inserts into the mapping table for the given manifest id.\r\n        static void EnsureExistsAndInsert(SQLite::Connection& connection, const std::vector<Utility::NormalizedString>& values, SQLite::rowid_t manifestId)\r\n        {\r\n            details::OneToManyTableEnsureExistsAndInsert(connection, TableInfo::TableName(), TableInfo::ValueName(), values, manifestId);\r\n        }\r\n\r\n        // Updates the mapping table to represent the given values for the manifest.\r\n        static bool UpdateIfNeededByManifestId(SQLite::Connection& connection, const std::vector<Utility::NormalizedString>& values, SQLite::rowid_t manifestId)\r\n        {\r\n            return details::OneToManyTableUpdateIfNeededByManifestId(connection, TableInfo::TableName(), TableInfo::ValueName(), values, manifestId);\r\n        }\r\n\r\n        // Deletes the mapping rows for the given manifest, then removes any unused data rows.\r\n        static void DeleteIfNotNeededByManifestId(SQLite::Connection& connection, SQLite::rowid_t manifestId)\r\n        {\r\n            details::OneToManyTableDeleteIfNotNeededByManifestId(connection, TableInfo::TableName(), TableInfo::ValueName(), manifestId);\r\n        }\r\n\r\n        // Removes data that is no longer needed for an index that is to be published.\r\n        // Preserving the manifest index will improve the efficiency of finding the values associated with a manifest.\r\n        // Preserving the values index will improve searching when it is primarily done by equality.\r\n        static void PrepareForPackaging(SQLite::Connection& connection, OneToManyTableSchema schemaVersion, bool preserveManifestIndex, bool preserveValuesIndex)\r\n        {\r\n            details::OneToManyTablePrepareForPackaging(connection, TableInfo::TableName(), schemaVersion, preserveManifestIndex, preserveValuesIndex);\r\n        }\r\n\r\n        // Checks the consistency of the index to ensure that every referenced row exists.\r\n        // Returns true if index is consistent; false if it is not.\r\n        static bool CheckConsistency(const SQLite::Connection& connection, bool log)\r\n        {\r\n            return details::OneToManyTableCheckConsistency(connection, TableInfo::TableName(), TableInfo::ValueName(), log);\r\n        }\r\n\r\n        // Determines if the table is empty.\r\n        static bool IsEmpty(SQLite::Connection& connection)\r\n        {\r\n            return details::OneToManyTableIsEmpty(connection, TableInfo::TableName());\r\n        }\r\n\r\n        // Prepares a statement for replacing all of the map data to point to a single manifest for a given id.\r\n        static SQLite::Statement PrepareMapDataFoldingStatement(const SQLite::Connection& connection)\r\n        {\r\n            return details::OneToManyTablePrepareMapDataFoldingStatement(connection, TableInfo::TableName());\r\n        }\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_0/OneToOneTable.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Microsoft/Schema/1_0/OneToOneTable.h\"\r\n#include \"Microsoft/Schema/1_0/ManifestTable.h\"\r\n#include <winget/SQLiteStatementBuilder.h>\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_0\r\n{\r\n    namespace details\r\n    {\r\n        using namespace std::string_view_literals;\r\n        static constexpr std::string_view s_OneToOneTable_IndexSuffix = \"_pkindex\"sv;\r\n\r\n        void CreateOneToOneTable(SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, bool useNamedIndices)\r\n        {\r\n            using namespace SQLite::Builder;\r\n\r\n            // Starting in V1.1, all code should be going this route of creating named indices rather than using primary or unique keys on columns.\r\n            // The resulting database will function the same, but give us control to drop the indices to reduce space.\r\n            if (useNamedIndices)\r\n            {\r\n                SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, std::string{ tableName } + \"_create_v1_1\");\r\n\r\n                StatementBuilder createTableBuilder;\r\n\r\n                createTableBuilder.CreateTable(tableName).Columns({\r\n                    IntegerPrimaryKey(),\r\n                    ColumnBuilder(valueName, Type::Text).NotNull()\r\n                    });\r\n\r\n                createTableBuilder.Execute(connection);\r\n\r\n                StatementBuilder indexBuilder;\r\n                indexBuilder.CreateUniqueIndex({ tableName, s_OneToOneTable_IndexSuffix }).On(tableName).Columns(valueName);\r\n                indexBuilder.Execute(connection);\r\n\r\n                savepoint.Commit();\r\n            }\r\n            else\r\n            {\r\n                StatementBuilder createTableBuilder;\r\n\r\n                createTableBuilder.CreateTable(tableName).Columns({\r\n                    ColumnBuilder(valueName, Type::Text).NotNull().PrimaryKey()\r\n                    });\r\n\r\n                createTableBuilder.Execute(connection);\r\n            }\r\n        }\r\n\r\n        void DropOneToOneTable(SQLite::Connection& connection, std::string_view tableName)\r\n        {\r\n            SQLite::Builder::StatementBuilder dropTableBuilder;\r\n            dropTableBuilder.DropTable(tableName);\r\n\r\n            dropTableBuilder.Execute(connection);\r\n        }\r\n\r\n        std::optional<SQLite::rowid_t> OneToOneTableSelectIdByValue(const SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, std::string_view value, bool useLike)\r\n        {\r\n            SQLite::Builder::StatementBuilder selectBuilder;\r\n            selectBuilder.Select(SQLite::RowIDName).From(tableName).Where(valueName);\r\n\r\n            if (useLike)\r\n            {\r\n                selectBuilder.LikeWithEscape(value);\r\n            }\r\n            else\r\n            {\r\n                selectBuilder.Equals(value);\r\n            }\r\n\r\n            SQLite::Statement select = selectBuilder.Prepare(connection);\r\n\r\n            if (select.Step())\r\n            {\r\n                return select.GetColumn<SQLite::rowid_t>(0);\r\n            }\r\n            else\r\n            {\r\n                return {};\r\n            }\r\n        }\r\n\r\n        std::optional<std::string> OneToOneTableSelectValueById(SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, SQLite::rowid_t id)\r\n        {\r\n            SQLite::Builder::StatementBuilder selectBuilder;\r\n            selectBuilder.Select(valueName).From(tableName).Where(SQLite::RowIDName).Equals(id);\r\n\r\n            SQLite::Statement select = selectBuilder.Prepare(connection);\r\n\r\n            if (select.Step())\r\n            {\r\n                return select.GetColumn<std::string>(0);\r\n            }\r\n            else\r\n            {\r\n                return {};\r\n            }\r\n        }\r\n\r\n        std::vector<SQLite::rowid_t> OneToOneTableGetAllRowIds(const SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, size_t limit)\r\n        {\r\n            SQLite::Builder::StatementBuilder selectBuilder;\r\n            selectBuilder.Select(SQLite::RowIDName).From(tableName).OrderBy(valueName);\r\n\r\n            if (limit)\r\n            {\r\n                selectBuilder.Limit(limit);\r\n            }\r\n\r\n            SQLite::Statement select = selectBuilder.Prepare(connection);\r\n\r\n            std::vector<SQLite::rowid_t> result;\r\n            while (select.Step())\r\n            {\r\n                result.emplace_back(select.GetColumn<SQLite::rowid_t>(0));\r\n            }\r\n            return result;\r\n        }\r\n\r\n        SQLite::rowid_t OneToOneTableEnsureExists(SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, std::string_view value, bool overwriteLikeMatch)\r\n        {\r\n            auto selectResult = OneToOneTableSelectIdByValue(connection, tableName, valueName, value, overwriteLikeMatch);\r\n            if (selectResult)\r\n            {\r\n                if (overwriteLikeMatch)\r\n                {\r\n                    // If the value in the table is not an exact match, overwrite it with the incoming value\r\n                    auto tableValue = OneToOneTableSelectValueById(connection, tableName, valueName, selectResult.value());\r\n                    if (tableValue.value() != value)\r\n                    {\r\n                        SQLite::Builder::StatementBuilder updateBuilder;\r\n                        updateBuilder.Update(tableName).Set().Column(valueName).Equals(value).Where(SQLite::RowIDName).Equals(selectResult);\r\n\r\n                        updateBuilder.Execute(connection);\r\n                    }\r\n                }\r\n\r\n                return selectResult.value();\r\n            }\r\n\r\n            SQLite::Builder::StatementBuilder insertBuilder;\r\n            insertBuilder.InsertInto(tableName).Columns(valueName).Values(value);\r\n\r\n            insertBuilder.Execute(connection);\r\n\r\n            return connection.GetLastInsertRowID();\r\n        }\r\n\r\n        void OneToOneTablePrepareForPackaging(SQLite::Connection& connection, std::string_view tableName, bool useNamedIndices, bool preserveValuesIndex)\r\n        {\r\n            if (useNamedIndices && !preserveValuesIndex)\r\n            {\r\n                SQLite::Builder::StatementBuilder dropIndexBuilder;\r\n                dropIndexBuilder.DropIndex({ tableName, s_OneToOneTable_IndexSuffix });\r\n                dropIndexBuilder.Execute(connection);\r\n            }\r\n        }\r\n\r\n        uint64_t OneToOneTableGetCount(const SQLite::Connection& connection, std::string_view tableName)\r\n        {\r\n            SQLite::Builder::StatementBuilder builder;\r\n            builder.Select(SQLite::Builder::RowCount).From(tableName);\r\n\r\n            SQLite::Statement countStatement = builder.Prepare(connection);\r\n\r\n            THROW_HR_IF(E_UNEXPECTED, !countStatement.Step());\r\n\r\n            return static_cast<uint64_t>(countStatement.GetColumn<SQLite::rowid_t>(0));\r\n        }\r\n\r\n        bool OneToOneTableIsEmpty(SQLite::Connection& connection, std::string_view tableName)\r\n        {\r\n            return (OneToOneTableGetCount(connection, tableName) == 0);\r\n        }\r\n\r\n        void OneToOneTableDeleteById(SQLite::Connection& connection, std::string_view tableName, SQLite::rowid_t id)\r\n        {\r\n            SQLite::Builder::StatementBuilder builder;\r\n            builder.DeleteFrom(tableName).Where(SQLite::RowIDName).Equals(id);\r\n\r\n            builder.Execute(connection);\r\n        }\r\n\r\n        bool OneToOneTableCheckConsistency(const SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, bool log)\r\n        {\r\n            // Build a select statement to find values that contain an embedded null character\r\n            // Such as:\r\n            // Select count(*) from table where instr(value,char(0))>0\r\n            SQLite::Builder::StatementBuilder builder;\r\n            builder.\r\n                Select({ SQLite::RowIDName, valueName }).\r\n                From(tableName).\r\n                WhereValueContainsEmbeddedNullCharacter(valueName);\r\n\r\n            SQLite::Statement select = builder.Prepare(connection);\r\n            bool result = true;\r\n\r\n            while (select.Step())\r\n            {\r\n                result = false;\r\n\r\n                if (!log)\r\n                {\r\n                    break;\r\n                }\r\n\r\n                AICLI_LOG(Repo, Info, << \"  [INVALID] value in table [\" << tableName << \"] at row [\" << select.GetColumn<SQLite::rowid_t>(0) << \"] contains an embedded null character and starts with [\" << select.GetColumn<std::string>(1) << \"]\");\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_0/OneToOneTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteWrapper.h>\r\n#include <optional>\r\n#include <string>\r\n#include <string_view>\r\n#include <vector>\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_0\r\n{\r\n    namespace details\r\n    {\r\n        // Creates the table.\r\n        void CreateOneToOneTable(SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, bool useNamedIndices);\r\n\r\n        // Drops the table.\r\n        void DropOneToOneTable(SQLite::Connection& connection, std::string_view tableName);\r\n\r\n        // Selects the value from the table, returning the rowid if it exists.\r\n        std::optional<SQLite::rowid_t> OneToOneTableSelectIdByValue(const SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, std::string_view value, bool useLike = false);\r\n\r\n        // Selects the value from the table, returning the rowid if it exists.\r\n        std::optional<std::string> OneToOneTableSelectValueById(SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, SQLite::rowid_t id);\r\n\r\n        // Gets all row ids from the table.\r\n        std::vector<SQLite::rowid_t> OneToOneTableGetAllRowIds(const SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, size_t limit);\r\n\r\n        // Ensures that the values exists in the table.\r\n        SQLite::rowid_t OneToOneTableEnsureExists(SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, std::string_view value, bool overwriteLikeMatch = false);\r\n\r\n        // Removes data that is no longer needed for an index that is to be published.\r\n        void OneToOneTablePrepareForPackaging(SQLite::Connection& connection, std::string_view tableName, bool useNamedIndices, bool preserveValuesIndex);\r\n\r\n        // Gets the total number of rows in the table.\r\n        uint64_t OneToOneTableGetCount(const SQLite::Connection& connection, std::string_view tableName);\r\n\r\n        // Determines if the table is empty.\r\n        bool OneToOneTableIsEmpty(SQLite::Connection& connection, std::string_view tableName);\r\n\r\n        // Removes the given row by its rowid if it is no longer referenced.\r\n        void OneToOneTableDeleteById(SQLite::Connection& connection, std::string_view tableName, SQLite::rowid_t id);\r\n\r\n        // Checks the consistency of the table.\r\n        bool OneToOneTableCheckConsistency(const SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, bool log);\r\n    }\r\n\r\n    // A table that represents a value that is 1:1 with a primary entry.\r\n    template <typename TableInfo>\r\n    struct OneToOneTable\r\n    {\r\n        // The value type.\r\n        using value_t = std::string;\r\n\r\n        // The id type\r\n        using id_t = SQLite::rowid_t;\r\n\r\n        // Creates the table with named indices.\r\n        static void Create(SQLite::Connection& connection)\r\n        {\r\n            details::CreateOneToOneTable(connection, TableInfo::TableName(), TableInfo::ValueName(), true);\r\n        }\r\n\r\n        // Creates the table with standard primary keys.\r\n        static void Create_deprecated(SQLite::Connection& connection)\r\n        {\r\n            details::CreateOneToOneTable(connection, TableInfo::TableName(), TableInfo::ValueName(), false);\r\n        }\r\n\r\n        // Drops the table.\r\n        static void Drop(SQLite::Connection& connection)\r\n        {\r\n            details::DropOneToOneTable(connection, TableInfo::TableName());\r\n        }\r\n\r\n        // The name of the table.\r\n        static constexpr std::string_view TableName()\r\n        {\r\n            return TableInfo::TableName();\r\n        }\r\n\r\n        // The value name of the table.\r\n        static constexpr std::string_view ValueName()\r\n        {\r\n            return TableInfo::ValueName();\r\n        }\r\n\r\n        // Value indicating type.\r\n        static constexpr bool IsOneToOne()\r\n        {\r\n            return true;\r\n        }\r\n\r\n        // Selects the value from the table, returning the rowid if it exists.\r\n        static std::optional<SQLite::rowid_t> SelectIdByValue(const SQLite::Connection& connection, std::string_view value, bool useLike = false)\r\n        {\r\n            return details::OneToOneTableSelectIdByValue(connection, TableInfo::TableName(), TableInfo::ValueName(), value, useLike);\r\n        }\r\n\r\n        // Selects the value from the table, returning it if it exists.\r\n        static std::optional<value_t> SelectValueById(SQLite::Connection& connection, id_t id)\r\n        {\r\n            return details::OneToOneTableSelectValueById(connection, TableInfo::TableName(), TableInfo::ValueName(), id);\r\n        }\r\n\r\n        // Gets all row ids from the table.\r\n        static std::vector<SQLite::rowid_t> GetAllRowIds(const SQLite::Connection& connection, size_t limit = 0)\r\n        {\r\n            return details::OneToOneTableGetAllRowIds(connection, TableInfo::TableName(), TableInfo::ValueName(), limit);\r\n        }\r\n\r\n        // Ensures that the given value exists in the table, returning the rowid.\r\n        static SQLite::rowid_t EnsureExists(SQLite::Connection& connection, std::string_view value, bool overwriteLikeMatch = false)\r\n        {\r\n            return details::OneToOneTableEnsureExists(connection, TableInfo::TableName(), TableInfo::ValueName(), value, overwriteLikeMatch);\r\n        }\r\n\r\n        // Removes the given row by its rowid if it is no longer referenced.\r\n        static void DeleteById(SQLite::Connection& connection, SQLite::rowid_t id)\r\n        {\r\n            return details::OneToOneTableDeleteById(connection, TableInfo::TableName(), id);\r\n        }\r\n\r\n        // Removes data that is no longer needed for an index that is to be published.\r\n        // Preserving the values index will improve searching when it is primarily done by equality.\r\n        static void PrepareForPackaging(SQLite::Connection& connection, bool preserveValuesIndex = false)\r\n        {\r\n            details::OneToOneTablePrepareForPackaging(connection, TableInfo::TableName(), true, preserveValuesIndex);\r\n        }\r\n\r\n        // Removes data that is no longer needed for an index that is to be published.\r\n        static void PrepareForPackaging_deprecated(SQLite::Connection& connection)\r\n        {\r\n            details::OneToOneTablePrepareForPackaging(connection, TableInfo::TableName(), false, false);\r\n        }\r\n\r\n        // Gets the total number of rows in the table.\r\n        static uint64_t GetCount(const SQLite::Connection& connection)\r\n        {\r\n            return details::OneToOneTableGetCount(connection, TableInfo::TableName());\r\n        }\r\n\r\n        // Determines if the table is empty.\r\n        static bool IsEmpty(SQLite::Connection& connection)\r\n        {\r\n            return details::OneToOneTableIsEmpty(connection, TableInfo::TableName());\r\n        }\r\n\r\n        // Checks the consistency of the table.\r\n        static bool CheckConsistency(const SQLite::Connection& connection, bool log)\r\n        {\r\n            return details::OneToOneTableCheckConsistency(connection, TableInfo::TableName(), TableInfo::ValueName(), log);\r\n        }\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_0/PathPartTable.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"PathPartTable.h\"\r\n#include <winget/SQLiteStatementBuilder.h>\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_0\r\n{\r\n    using namespace std::string_view_literals;\r\n    static constexpr std::string_view s_PathPartTable_Table_Name = \"pathparts\"sv;\r\n    static constexpr std::string_view s_PathPartTable_PrimaryKeyIndex_Name = \"pathparts_pkindex\"sv;\r\n    static constexpr std::string_view s_PathPartTable_ParentIndex_Name = \"pathparts_parentidx\"sv;\r\n    static constexpr std::string_view s_PathPartTable_ParentValue_Name = \"parent\"sv;\r\n    static constexpr std::string_view s_PathPartTable_PartValue_Name = \"pathpart\"sv;\r\n\r\n    namespace\r\n    {\r\n        // Attempts to select a path part given the input.\r\n        // Returns an no value if none exists, or the rowid of the part if it is found.\r\n        std::optional<SQLite::rowid_t> SelectPathPart(SQLite::Connection& connection, std::optional<SQLite::rowid_t> parent, std::string_view part)\r\n        {\r\n            SQLite::Builder::StatementBuilder builder;\r\n            builder.Select(SQLite::RowIDName).From(s_PathPartTable_Table_Name).\r\n                Where(s_PathPartTable_ParentValue_Name).Equals(parent).And(s_PathPartTable_PartValue_Name).Equals(part);\r\n\r\n            SQLite::Statement select = builder.Prepare(connection);\r\n\r\n            if (select.Step())\r\n            {\r\n                return select.GetColumn<SQLite::rowid_t>(0);\r\n            }\r\n            else\r\n            {\r\n                return {};\r\n            }\r\n        }\r\n\r\n        // Inserts the given path part into the table, returning the rowid of the inserted row.\r\n        SQLite::rowid_t InsertPathPart(SQLite::Connection& connection, std::optional<SQLite::rowid_t> parent, std::string_view part)\r\n        {\r\n            THROW_HR_IF(E_INVALIDARG, part.empty());\r\n\r\n            SQLite::Builder::StatementBuilder builder;\r\n            builder.InsertInto(s_PathPartTable_Table_Name).Columns({ s_PathPartTable_ParentValue_Name, s_PathPartTable_PartValue_Name }).Values(parent, part);\r\n\r\n            builder.Execute(connection);\r\n\r\n            return connection.GetLastInsertRowID();\r\n        }\r\n\r\n        // Inserts the no path part into the table.\r\n        SQLite::rowid_t InsertNoPathPart(SQLite::Connection& connection)\r\n        {\r\n            SQLite::Builder::StatementBuilder builder;\r\n            builder.\r\n                InsertInto(s_PathPartTable_Table_Name).\r\n                Columns({ SQLite::RowIDName, s_PathPartTable_ParentValue_Name, s_PathPartTable_PartValue_Name }).\r\n                Values(PathPartTable::NoPathId, std::optional<SQLite::rowid_t>{}, std::string_view{});\r\n\r\n            builder.Execute(connection);\r\n\r\n            return connection.GetLastInsertRowID();\r\n        }\r\n\r\n        // Gets the parent of a given part by id.\r\n        // This should only be called when the part must exist, as it will throw if not found.\r\n        std::optional<SQLite::rowid_t> GetParentById(SQLite::Connection& connection, SQLite::rowid_t id)\r\n        {\r\n            SQLite::Builder::StatementBuilder builder;\r\n            builder.Select(s_PathPartTable_ParentValue_Name).From(s_PathPartTable_Table_Name).Where(SQLite::RowIDName).Equals(id);\r\n\r\n            SQLite::Statement select = builder.Prepare(connection);\r\n\r\n            THROW_HR_IF(APPINSTALLER_CLI_ERROR_INDEX_INTEGRITY_COMPROMISED, !select.Step());\r\n\r\n            if (!select.GetColumnIsNull(0))\r\n            {\r\n                return select.GetColumn<SQLite::rowid_t>(0);\r\n            }\r\n            else\r\n            {\r\n                return {};\r\n            }\r\n        }\r\n\r\n        // Determines if any part references this one as their parent.\r\n        bool IsLeafPart(SQLite::Connection& connection, SQLite::rowid_t id)\r\n        {\r\n            SQLite::Builder::StatementBuilder builder;\r\n            builder.Select(SQLite::Builder::RowCount).From(s_PathPartTable_Table_Name).Where(s_PathPartTable_ParentValue_Name).Equals(id);\r\n\r\n            SQLite::Statement select = builder.Prepare(connection);\r\n\r\n            THROW_HR_IF(E_UNEXPECTED, !select.Step());\r\n\r\n            // No rows with this as a parent means it is a leaf.\r\n            return (select.GetColumn<int>(0) == 0);\r\n        }\r\n\r\n        // Removes the given part by id.\r\n        void RemovePartById(SQLite::Connection& connection, SQLite::rowid_t id)\r\n        {\r\n            SQLite::Builder::StatementBuilder builder;\r\n            builder.DeleteFrom(s_PathPartTable_Table_Name).Where(SQLite::RowIDName).Equals(id);\r\n\r\n            builder.Execute(connection);\r\n        }\r\n    }\r\n\r\n    // Starting in V1.1, all code should be going this route of creating named indices rather than using primary or unique keys on columns.\r\n    // The resulting database will function the same, but give us control to drop the indices to reduce space.\r\n    void PathPartTable::Create(SQLite::Connection& connection)\r\n    {\r\n        using namespace SQLite::Builder;\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"createPathParts_v1_1\");\r\n\r\n        StatementBuilder createTableBuilder;\r\n        createTableBuilder.CreateTable(s_PathPartTable_Table_Name).Columns({\r\n            IntegerPrimaryKey(),\r\n            ColumnBuilder(s_PathPartTable_ParentValue_Name, Type::Int64),\r\n            ColumnBuilder(s_PathPartTable_PartValue_Name, Type::Text).NotNull()\r\n            });\r\n\r\n        createTableBuilder.Execute(connection);\r\n\r\n        StatementBuilder createPKIndexBuilder;\r\n        createPKIndexBuilder.CreateUniqueIndex(s_PathPartTable_PrimaryKeyIndex_Name).On(s_PathPartTable_Table_Name).Columns({ s_PathPartTable_PartValue_Name, s_PathPartTable_ParentValue_Name });\r\n        createPKIndexBuilder.Execute(connection);\r\n\r\n        StatementBuilder createIndexBuilder;\r\n        createIndexBuilder.CreateIndex(s_PathPartTable_ParentIndex_Name).On(s_PathPartTable_Table_Name).Columns(s_PathPartTable_ParentValue_Name);\r\n        createIndexBuilder.Execute(connection);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    void PathPartTable::Create_deprecated(SQLite::Connection& connection)\r\n    {\r\n        using namespace SQLite::Builder;\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"createPathParts_v1_0\");\r\n\r\n        StatementBuilder createTableBuilder;\r\n        createTableBuilder.CreateTable(s_PathPartTable_Table_Name).Columns({\r\n            ColumnBuilder(s_PathPartTable_ParentValue_Name, Type::Int64),\r\n            ColumnBuilder(s_PathPartTable_PartValue_Name, Type::Text).NotNull(),\r\n            PrimaryKeyBuilder({ s_PathPartTable_PartValue_Name, s_PathPartTable_ParentValue_Name })\r\n            });\r\n\r\n        createTableBuilder.Execute(connection);\r\n\r\n        StatementBuilder createIndexBuilder;\r\n        createIndexBuilder.CreateIndex(s_PathPartTable_ParentIndex_Name).On(s_PathPartTable_Table_Name).Columns(s_PathPartTable_ParentValue_Name);\r\n\r\n        createIndexBuilder.Execute(connection);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    void PathPartTable::Drop(SQLite::Connection& connection)\r\n    {\r\n        SQLite::Builder::StatementBuilder dropTableBuilder;\r\n        dropTableBuilder.DropTable(s_PathPartTable_Table_Name);\r\n\r\n        dropTableBuilder.Execute(connection);\r\n    }\r\n\r\n    std::string_view PathPartTable::TableName()\r\n    {\r\n        return s_PathPartTable_Table_Name;\r\n    }\r\n\r\n    std::string_view PathPartTable::ValueName()\r\n    {\r\n        return s_PathPartTable_PartValue_Name;\r\n    }\r\n\r\n    std::tuple<bool, SQLite::rowid_t> EnsurePathExistsInternal(SQLite::Connection& connection, const std::filesystem::path& relativePath, bool createIfNotFound)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, !relativePath.has_relative_path());\r\n        THROW_HR_IF(E_INVALIDARG, relativePath.has_root_path());\r\n        THROW_HR_IF(E_INVALIDARG, !relativePath.has_filename());\r\n\r\n        std::unique_ptr<SQLite::Savepoint> savepoint;\r\n        if (createIfNotFound)\r\n        {\r\n            savepoint = std::make_unique<SQLite::Savepoint>(SQLite::Savepoint::Create(connection, \"ensurepathexists_v1_0\"));\r\n        }\r\n\r\n        bool partsAdded = false;\r\n\r\n        std::optional<SQLite::rowid_t> parent;\r\n        for (const auto& part : relativePath)\r\n        {\r\n            std::string utf8part = part.u8string();\r\n            std::optional<SQLite::rowid_t> current = SelectPathPart(connection, parent, utf8part);\r\n\r\n            if (!current)\r\n            {\r\n                if (createIfNotFound)\r\n                {\r\n                    partsAdded = true;\r\n                    current = InsertPathPart(connection, parent, utf8part);\r\n                }\r\n                else\r\n                {\r\n                    // Current part was not found, and we were told not to create.\r\n                    // Return false to indicate that the path does not exist.\r\n                    return {};\r\n                }\r\n            }\r\n\r\n            parent = current;\r\n        }\r\n\r\n        if (savepoint)\r\n        {\r\n            savepoint->Commit();\r\n        }\r\n\r\n        // If we get this far, the path exists.\r\n        // If we were asked to create it, return whether we needed to or it was already present.\r\n        // If not, then true indicates that it exists.\r\n        return { (createIfNotFound ? partsAdded : true), parent.value() };\r\n    }\r\n\r\n    std::tuple<bool, SQLite::rowid_t> PathPartTable::EnsurePathExists(SQLite::Connection& connection, const std::optional<std::filesystem::path>& relativePath, bool createIfNotFound)\r\n    {\r\n        if (relativePath)\r\n        {\r\n            return EnsurePathExistsInternal(connection, relativePath.value(), createIfNotFound);\r\n        }\r\n\r\n        std::unique_ptr<SQLite::Savepoint> savepoint;\r\n        if (createIfNotFound)\r\n        {\r\n            savepoint = std::make_unique<SQLite::Savepoint>(SQLite::Savepoint::Create(connection, \"ensurepathexists_v1_0\"));\r\n        }\r\n\r\n        bool partsAdded = false;\r\n\r\n        std::optional<SQLite::rowid_t> noPathPart = SelectPathPart(connection, {}, {});\r\n\r\n        if (!noPathPart)\r\n        {\r\n            if (createIfNotFound)\r\n            {\r\n                partsAdded = true;\r\n                noPathPart = InsertNoPathPart(connection);\r\n            }\r\n            else\r\n            {\r\n                // Not found, and we were told not to create.\r\n                // Return false to indicate that the path does not exist.\r\n                return {};\r\n            }\r\n        }\r\n\r\n        if (savepoint)\r\n        {\r\n            savepoint->Commit();\r\n        }\r\n\r\n        // If we get this far, the path exists.\r\n        // If we were asked to create it, return whether we needed to or it was already present.\r\n        // If not, then true indicates that it exists.\r\n        return { (createIfNotFound ? partsAdded : true), noPathPart.value() };\r\n    }\r\n\r\n    std::optional<std::string> PathPartTable::GetPathById(const SQLite::Connection& connection, SQLite::rowid_t id)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.Select({ s_PathPartTable_ParentValue_Name, s_PathPartTable_PartValue_Name }).\r\n            From(s_PathPartTable_Table_Name).Where(SQLite::RowIDName).Equals(SQLite::Builder::Unbound);\r\n\r\n        SQLite::Statement select = builder.Prepare(connection);\r\n\r\n        SQLite::rowid_t currentPart = id;\r\n        std::string result;\r\n\r\n        while (true)\r\n        {\r\n            select.Reset();\r\n            select.Bind(1, currentPart);\r\n\r\n            if (select.Step())\r\n            {\r\n                std::string partValue = select.GetColumn<std::string>(1);\r\n                if (result.empty())\r\n                {\r\n                    result = partValue;\r\n                }\r\n                else\r\n                {\r\n                    result = partValue + '/' + result;\r\n                }\r\n\r\n                if (select.GetColumnIsNull(0))\r\n                {\r\n                    // If the parent of this column is null, then we have reached the relative root\r\n                    break;\r\n                }\r\n                else\r\n                {\r\n                    currentPart = select.GetColumn<SQLite::rowid_t>(0);\r\n                }\r\n            }\r\n            else\r\n            {\r\n                if (currentPart == id)\r\n                {\r\n                    // The given id did not reference an actual path\r\n                    return {};\r\n                }\r\n                else\r\n                {\r\n                    // We found a broken path\r\n                    AICLI_LOG(Repo, Error, << \"Path part references an invalid parent: \" << currentPart);\r\n                    THROW_HR(APPINSTALLER_CLI_ERROR_INDEX_INTEGRITY_COMPROMISED);\r\n                }\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    void PathPartTable::RemovePathById(SQLite::Connection& connection, SQLite::rowid_t id)\r\n    {\r\n        // Don't bother removing the pathless id\r\n        if (id == NoPathId)\r\n        {\r\n            return;\r\n        }\r\n\r\n        SQLite::rowid_t currentPartToRemove = id;\r\n        while (IsLeafPart(connection, currentPartToRemove))\r\n        {\r\n            std::optional<SQLite::rowid_t> parent = GetParentById(connection, currentPartToRemove);\r\n            RemovePartById(connection, currentPartToRemove);\r\n\r\n            // If parent was NULL, this was a root part and we can stop\r\n            if (!parent)\r\n            {\r\n                break;\r\n            }\r\n            else\r\n            {\r\n                currentPartToRemove = parent.value();\r\n            }\r\n        }\r\n    }\r\n\r\n    void PathPartTable::PrepareForPackaging(SQLite::Connection& connection)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"pfpPathParts_v1_1\");\r\n\r\n        PrepareForPackaging_deprecated(connection);\r\n\r\n        SQLite::Builder::StatementBuilder dropPKIndexBuilder;\r\n        dropPKIndexBuilder.DropIndex(s_PathPartTable_PrimaryKeyIndex_Name);\r\n        dropPKIndexBuilder.Execute(connection);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    void PathPartTable::PrepareForPackaging_deprecated(SQLite::Connection& connection)\r\n    {\r\n        SQLite::Builder::StatementBuilder dropIndexBuilder;\r\n        dropIndexBuilder.DropIndex(s_PathPartTable_ParentIndex_Name);\r\n        dropIndexBuilder.Execute(connection);\r\n    }\r\n\r\n    bool PathPartTable::CheckConsistency(const SQLite::Connection& connection, bool log)\r\n    {\r\n        using QCol = SQLite::Builder::QualifiedColumn;\r\n\r\n        // Build a select statement to find pathpart rows containing references to parents with nonexistent rowids\r\n        // Such as:\r\n        // Select l.rowid, l.parent from pathparts as l left outer join pathparts as r on l.parent = r.rowid where l.parent is not null and r.pathpart is null\r\n        constexpr std::string_view s_left = \"left\"sv;\r\n        constexpr std::string_view s_right = \"right\"sv;\r\n        bool result = true;\r\n\r\n        {\r\n            SQLite::Builder::StatementBuilder builder;\r\n            builder.\r\n                Select({ QCol(s_left, SQLite::RowIDName), QCol(s_left, s_PathPartTable_ParentValue_Name) }).\r\n                From(s_PathPartTable_Table_Name).As(s_left).\r\n                LeftOuterJoin(s_PathPartTable_Table_Name).As(s_right).On(QCol(s_left, s_PathPartTable_ParentValue_Name), QCol(s_right, SQLite::RowIDName)).\r\n                Where(QCol(s_left, s_PathPartTable_ParentValue_Name)).IsNotNull().And(QCol(s_right, s_PathPartTable_PartValue_Name)).IsNull();\r\n\r\n            SQLite::Statement select = builder.Prepare(connection);\r\n\r\n            while (select.Step())\r\n            {\r\n                result = false;\r\n\r\n                if (!log)\r\n                {\r\n                    break;\r\n                }\r\n\r\n                AICLI_LOG(Repo, Info, << \"  [INVALID] pathparts [\" << select.GetColumn<SQLite::rowid_t>(0) << \"] refers to \" << s_PathPartTable_ParentValue_Name << \" [\" << select.GetColumn<SQLite::rowid_t>(1) << \"]\");\r\n            }\r\n        }\r\n\r\n        if (!result && !log)\r\n        {\r\n            return result;\r\n        }\r\n\r\n        {\r\n            // Build a select statement to find values that contain an embedded null character\r\n            // Such as:\r\n            // Select count(*) from table where instr(value,char(0))>0\r\n            SQLite::Builder::StatementBuilder builder;\r\n            builder.\r\n                Select({ SQLite::RowIDName, s_PathPartTable_PartValue_Name }).\r\n                From(s_PathPartTable_Table_Name).\r\n                WhereValueContainsEmbeddedNullCharacter(s_PathPartTable_PartValue_Name);\r\n\r\n            SQLite::Statement select = builder.Prepare(connection);\r\n\r\n            while (select.Step())\r\n            {\r\n                result = false;\r\n\r\n                if (!log)\r\n                {\r\n                    break;\r\n                }\r\n\r\n                AICLI_LOG(Repo, Info, << \"  [INVALID] value in table [\" << s_PathPartTable_Table_Name << \"] at row [\" << select.GetColumn<SQLite::rowid_t>(0) << \"] contains an embedded null character and starts with [\" << select.GetColumn<std::string>(1) << \"]\");\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    bool PathPartTable::IsEmpty(SQLite::Connection& connection)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.Select(SQLite::Builder::RowCount).From(s_PathPartTable_Table_Name);\r\n\r\n        SQLite::Statement countStatement = builder.Prepare(connection);\r\n\r\n        THROW_HR_IF(E_UNEXPECTED, !countStatement.Step());\r\n\r\n        return (countStatement.GetColumn<int>(0) == 0);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_0/PathPartTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteWrapper.h>\r\n#include <filesystem>\r\n#include <optional>\r\n#include <string>\r\n#include <string_view>\r\n#include <tuple>\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_0\r\n{\r\n    // A table that represents the parts of a path\r\n    struct PathPartTable\r\n    {\r\n        // The id type\r\n        using id_t = SQLite::rowid_t;\r\n\r\n        // The id used when no path is present.\r\n        constexpr static id_t NoPathId = -1;\r\n\r\n        // Creates the table with named indices.\r\n        static void Create(SQLite::Connection& connection);\r\n\r\n        // Creates the table with standard primary keys.\r\n        static void Create_deprecated(SQLite::Connection& connection);\r\n\r\n        // Drops the table.\r\n        static void Drop(SQLite::Connection& connection);\r\n\r\n        // Gets the table name.\r\n        static std::string_view TableName();\r\n\r\n        // Gets the value name.\r\n        static std::string_view ValueName();\r\n\r\n        // Ensure that the given relative path exists within the path parts table.\r\n        // If createIfNotFound is true, the function will add the parts as needed.\r\n        //      The result bool will indicate whether it was necessary to add the path (true),\r\n        //      or it was already present (false).\r\n        // If createIfNotFound is false, the function will simply determine if the path is present.\r\n        //      The result bool will indicate whether the path was found (true), or not (false).\r\n        // In all cases except createIfNotFound == false and result bool == false, the int64_t value\r\n        // will be valid and the rowid of the final path part in the path.\r\n        // If relativePath is not provided, will always map to an entry with NoPathId.\r\n        static std::tuple<bool, SQLite::rowid_t> EnsurePathExists(SQLite::Connection& connection, const std::optional<std::filesystem::path>& relativePath, bool createIfNotFound);\r\n\r\n        // Gets the path string using the given id as the leaf.\r\n        static std::optional<std::string> GetPathById(const SQLite::Connection& connection, SQLite::rowid_t id);\r\n\r\n        // Removes the path that terminates at the given id.\r\n        // Will not remove a path part if it is referenced.\r\n        static void RemovePathById(SQLite::Connection& connection, SQLite::rowid_t id);\r\n\r\n        // Removes data that is no longer needed for an index that is to be published.\r\n        static void PrepareForPackaging(SQLite::Connection& connection);\r\n\r\n        // Removes data that is no longer needed for an index that is to be published.\r\n        static void PrepareForPackaging_deprecated(SQLite::Connection& connection);\r\n\r\n        // Checks the consistency of the index to ensure that every referenced row exists.\r\n        // Returns true if index is consistent; false if it is not.\r\n        static bool CheckConsistency(const SQLite::Connection& connection, bool log);\r\n\r\n        // Determines if the table is empty.\r\n        static bool IsEmpty(SQLite::Connection& connection);\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_0/SearchResultsTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteWrapper.h>\r\n#include <winget/SQLiteTempTable.h>\r\n#include \"Microsoft/Schema/ISQLiteIndex.h\"\r\n#include \"Public/winget/RepositorySearch.h\"\r\n\r\n#include <optional>\r\n#include <utility>\r\n#include <vector>\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_0\r\n{\r\n    // Table for holding temporary search results.\r\n    struct SearchResultsTable : public SQLite::TempTable\r\n    {\r\n        SearchResultsTable(const SQLite::Connection& connection);\r\n\r\n        SearchResultsTable(const SearchResultsTable&) = delete;\r\n        SearchResultsTable& operator=(const SearchResultsTable&) = delete;\r\n\r\n        SearchResultsTable(SearchResultsTable&&) = default;\r\n        SearchResultsTable& operator=(SearchResultsTable&&) = default;\r\n\r\n        // Performs the requested search type on the requested field.\r\n        void SearchOnField(const PackageMatchFilter& filter);\r\n\r\n        // Removes rows with manifest ids whose sort order is below the highest one.\r\n        void RemoveDuplicateManifestRows();\r\n\r\n        // Prepares the table for a filtering pass.\r\n        void PrepareToFilter();\r\n\r\n        // Performs the requested filter type on the requested field.\r\n        void FilterOnField(const PackageMatchFilter& filter);\r\n\r\n        // Completes a filtering pass, removing filtered rows.\r\n        void CompleteFilter();\r\n\r\n        // Gets the results from the table.\r\n        ISQLiteIndex::SearchResult GetSearchResults(size_t limit = 0);\r\n\r\n    protected:\r\n        // Builds the search statement for the specified field and match type.\r\n        std::vector<int> BuildSearchStatement(SQLite::Builder::StatementBuilder& builder, PackageMatchField field, MatchType match) const;\r\n\r\n        virtual std::vector<int> BuildSearchStatement(\r\n            SQLite::Builder::StatementBuilder& builder,\r\n            PackageMatchField field,\r\n            std::string_view manifestAlias,\r\n            std::string_view valueAlias,\r\n            bool useLike) const;\r\n\r\n        static bool MatchUsesLike(MatchType match);\r\n        void BindStatementForMatchType(SQLite::Statement& statement, MatchType match, int bindIndex, std::string_view value);\r\n\r\n        virtual void BindStatementForMatchType(SQLite::Statement& statement, const PackageMatchFilter& filter, const std::vector<int>& bindIndex);\r\n\r\n    private:\r\n        const SQLite::Connection& m_connection;\r\n        int m_sortOrdinalValue = 0;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_0/SearchResultsTable_1_0.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"SearchResultsTable.h\"\r\n#include <winget/SQLiteStatementBuilder.h>\r\n\r\n#include \"Microsoft/Schema/1_0/IdTable.h\"\r\n#include \"Microsoft/Schema/1_0/NameTable.h\"\r\n#include \"Microsoft/Schema/1_0/MonikerTable.h\"\r\n#include \"Microsoft/Schema/1_0/ManifestTable.h\"\r\n#include \"Microsoft/Schema/1_0/TagsTable.h\"\r\n#include \"Microsoft/Schema/1_0/CommandsTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_0\r\n{\r\n    namespace\r\n    {\r\n        using namespace std::string_literals;\r\n        using namespace std::string_view_literals;\r\n\r\n        constexpr std::string_view s_SearchResultsTable_Manifest = \"manifest\"sv;\r\n        constexpr std::string_view s_SearchResultsTable_MatchField = \"field\"sv;\r\n        constexpr std::string_view s_SearchResultsTable_MatchType = \"match\"sv;\r\n        constexpr std::string_view s_SearchResultsTable_MatchValue = \"value\"sv;\r\n        constexpr std::string_view s_SearchResultsTable_SortValue = \"sort\"sv;\r\n        constexpr std::string_view s_SearchResultsTable_Filter = \"filter\"sv;\r\n\r\n        constexpr std::string_view s_SearchResultsTable_Index_Suffix = \"_i_m\"sv;\r\n\r\n        constexpr std::string_view s_SearchResultsTable_SubSelect_TableAlias = \"valueTable\"sv;\r\n        constexpr std::string_view s_SearchResultsTable_SubSelect_ManifestAlias = \"m\"sv;\r\n        constexpr std::string_view s_SearchResultsTable_SubSelect_ValueAlias = \"v\"sv;\r\n    }\r\n\r\n    SearchResultsTable::SearchResultsTable(const SQLite::Connection& connection) :\r\n        m_connection(connection)\r\n    {\r\n        using namespace SQLite::Builder;\r\n\r\n        {\r\n            StatementBuilder builder;\r\n            builder.CreateTable(GetQualifiedName()).BeginColumns();\r\n\r\n            builder.Column(ColumnBuilder(s_SearchResultsTable_Manifest, Type::RowId).NotNull());\r\n            builder.Column(ColumnBuilder(s_SearchResultsTable_MatchField, Type::Int).NotNull());\r\n            builder.Column(ColumnBuilder(s_SearchResultsTable_MatchType, Type::Int).NotNull());\r\n            builder.Column(ColumnBuilder(s_SearchResultsTable_MatchValue, Type::Text).NotNull());\r\n            builder.Column(ColumnBuilder(s_SearchResultsTable_SortValue, Type::Int).NotNull());\r\n            builder.Column(ColumnBuilder(s_SearchResultsTable_Filter, Type::Bool).NotNull());\r\n\r\n            builder.EndColumns();\r\n\r\n            builder.Execute(m_connection);\r\n        }\r\n\r\n        InitDropStatement(m_connection);\r\n\r\n        {\r\n            SQLite::Builder::QualifiedTable index = GetQualifiedName();\r\n            std::string indexName(index.Table);\r\n            indexName += s_SearchResultsTable_Index_Suffix;\r\n            index.Table = indexName;\r\n\r\n            StatementBuilder builder;\r\n            builder.CreateIndex(indexName).On(GetQualifiedName().Table).Columns(s_SearchResultsTable_Manifest);\r\n\r\n            builder.Execute(m_connection);\r\n        }\r\n    }\r\n\r\n    void SearchResultsTable::SearchOnField(const PackageMatchFilter& filter)\r\n    {\r\n        using namespace SQLite::Builder;\r\n\r\n        int sortOrdinal = m_sortOrdinalValue++;\r\n\r\n        // Create an insert statement to select values into the table as requested.\r\n        // The goal is a statement like this:\r\n        //      INSERT INTO <tempTable>\r\n        //      SELECT valueTable.m, <field>, <match>, valueTable.v, <sort>, <filter> FROM\r\n        //      (SELECT manifest.rowid as m, manifest.id as v from manifest join ids on manifest.id = ids.rowid where ids.id = <value>) AS valueTable\r\n        // Where the subselect is built by the owning table.\r\n        StatementBuilder builder;\r\n        builder.InsertInto(GetQualifiedName()).Select().\r\n            Column(QualifiedColumn(s_SearchResultsTable_SubSelect_TableAlias, s_SearchResultsTable_SubSelect_ManifestAlias)).\r\n            Value(filter.Field).\r\n            Value(filter.Type).\r\n            Column(QualifiedColumn(s_SearchResultsTable_SubSelect_TableAlias, s_SearchResultsTable_SubSelect_ValueAlias)).\r\n            Value(sortOrdinal).\r\n            Value(false).\r\n        From().BeginParenthetical();\r\n\r\n        // Add the field specific portion\r\n        std::vector<int> bindIndex = BuildSearchStatement(builder, filter.Field, filter.Type);\r\n\r\n        if (bindIndex.empty())\r\n        {\r\n            AICLI_LOG(Repo, Verbose, << \"PackageMatchField not supported in this version: \" << ToString(filter.Field));\r\n            return;\r\n        }\r\n\r\n        builder.EndParenthetical().As(s_SearchResultsTable_SubSelect_TableAlias);\r\n\r\n        SQLite::Statement statement = builder.Prepare(m_connection);\r\n        BindStatementForMatchType(statement, filter, bindIndex);\r\n        statement.Execute();\r\n        AICLI_LOG(SQL, Verbose, << \"Search found \" << m_connection.GetChanges() << \" rows\");\r\n    }\r\n\r\n    void SearchResultsTable::RemoveDuplicateManifestRows()\r\n    {\r\n        using namespace SQLite::Builder;\r\n\r\n        // Create a delete statement to leave only one row with a given manifest.\r\n        // This will arbitrarily choose one of the rows if multiple have the same lowest sort order.\r\n        // The goal is a statement like this:\r\n        //      DELETE from <temp> where rowid not in (\r\n        //          SELECT rowid from (\r\n        //              SELECT rowid, min(sort) from <temp> group by manifest\r\n        //          )\r\n        //      )\r\n        StatementBuilder builder;\r\n        builder.DeleteFrom(GetQualifiedName()).Where(SQLite::RowIDName).Not().In().BeginParenthetical().\r\n            Select(SQLite::RowIDName).From().BeginParenthetical().\r\n                Select().Column(SQLite::RowIDName).Column(Aggregate::Min, s_SearchResultsTable_SortValue).From(GetQualifiedName()).GroupBy(s_SearchResultsTable_Manifest).\r\n            EndParenthetical().\r\n        EndParenthetical();\r\n\r\n        builder.Execute(m_connection);\r\n        AICLI_LOG(SQL, Verbose, << \"Removed \" << m_connection.GetChanges() << \" duplicate rows\");\r\n    }\r\n\r\n    void SearchResultsTable::PrepareToFilter()\r\n    {\r\n        // Reset all filter values to unselected\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.Update(GetQualifiedName()).Set().Column(s_SearchResultsTable_Filter).Equals(false);\r\n\r\n        builder.Execute(m_connection);\r\n    }\r\n\r\n    void SearchResultsTable::FilterOnField(const PackageMatchFilter& filter)\r\n    {\r\n        using namespace SQLite::Builder;\r\n\r\n        // Create an update statement to mark rows that are found by the search.\r\n        // This will arbitrarily choose one of the rows if multiple have the same lowest sort order.\r\n        // The goal is a statement like this:\r\n        //      UPDATE <temp> set filter = 1 where manifest in (\r\n        //          SELECT m from (\r\n        //              SELECT manifest.rowid as m, manifest.id as v from manifest join ids on manifest.id = ids.rowid where ids.id = <value>\r\n        //          )\r\n        //      )\r\n        StatementBuilder builder;\r\n        builder.Update(GetQualifiedName()).Set().Column(s_SearchResultsTable_Filter).Equals(true).Where(s_SearchResultsTable_Manifest).In().BeginParenthetical().\r\n            Select(s_SearchResultsTable_SubSelect_ManifestAlias).From().BeginParenthetical();\r\n\r\n        // Add the field specific portion\r\n        std::vector<int> bindIndex = BuildSearchStatement(builder, filter.Field, filter.Type);\r\n\r\n        if (bindIndex.empty())\r\n        {\r\n            AICLI_LOG(Repo, Verbose, << \"PackageMatchField not supported in this version: \" << ToString(filter.Field));\r\n            return;\r\n        }\r\n\r\n        builder.EndParenthetical().EndParenthetical();\r\n\r\n        SQLite::Statement statement = builder.Prepare(m_connection);\r\n        BindStatementForMatchType(statement, filter, bindIndex);\r\n        statement.Execute();\r\n        AICLI_LOG(SQL, Verbose, << \"Filter kept \" << m_connection.GetChanges() << \" rows\");\r\n    }\r\n\r\n    void SearchResultsTable::CompleteFilter()\r\n    {\r\n        // Delete all unselected values\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.DeleteFrom(GetQualifiedName()).Where(s_SearchResultsTable_Filter).Equals(false);\r\n\r\n        builder.Execute(m_connection);\r\n        AICLI_LOG(SQL, Verbose, << \"Filter deleted \" << m_connection.GetChanges() << \" rows\");\r\n    }\r\n\r\n    ISQLiteIndex::SearchResult SearchResultsTable::GetSearchResults(size_t limit)\r\n    {\r\n        constexpr std::string_view tempTableAlias = \"t\"sv;\r\n\r\n        using namespace SQLite::Builder;\r\n        using QCol = QualifiedColumn;\r\n\r\n        // Select all unique ids from the results table, and their highest ordered match.\r\n        // The goal is a statement like this:\r\n        //  SELECT m.id, field, match, value, min(sort) from <temp> join manifest on rowid = manifest group by m.id order by t.sort\r\n        // Through the \"group by m.id\", we will only ever have one row per id, and the \"min(sort)\" returns us one of the rows that matched\r\n        // through the earliest search.  We also order by the sort value to have the earliest search matches first in the list\r\n        StatementBuilder builder;\r\n        builder.Select().\r\n            Column(QCol(ManifestTable::TableName(), IdTable::ValueName())).\r\n            Column(QCol(tempTableAlias, s_SearchResultsTable_MatchField)).\r\n            Column(QCol(tempTableAlias, s_SearchResultsTable_MatchType)).\r\n            Column(QCol(tempTableAlias, s_SearchResultsTable_MatchValue)).\r\n            Column(Aggregate::Min, QCol(tempTableAlias, s_SearchResultsTable_SortValue)).\r\n        From(GetQualifiedName()).As(tempTableAlias).\r\n            Join(ManifestTable::TableName()).On(QCol(tempTableAlias, s_SearchResultsTable_Manifest), QCol(ManifestTable::TableName(), SQLite::RowIDName)).\r\n            GroupBy(QCol(ManifestTable::TableName(), IdTable::ValueName())).OrderBy(QCol(tempTableAlias, s_SearchResultsTable_SortValue));\r\n\r\n        SQLite::Statement select = builder.Prepare(m_connection);\r\n\r\n        ISQLiteIndex::SearchResult result;\r\n        while (select.Step())\r\n        {\r\n            if (limit && result.Matches.size() >= limit)\r\n            {\r\n                break;\r\n            }\r\n\r\n            result.Matches.emplace_back(select.GetColumn<SQLite::rowid_t>(0), \r\n                PackageMatchFilter(select.GetColumn<PackageMatchField>(1), select.GetColumn<MatchType>(2), select.GetColumn<std::string>(3)));\r\n        }\r\n\r\n        result.Truncated = (select.GetState() != SQLite::Statement::State::Completed);\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<int> SearchResultsTable::BuildSearchStatement(SQLite::Builder::StatementBuilder& builder, PackageMatchField field, MatchType match) const\r\n    {\r\n        return BuildSearchStatement(builder, field, s_SearchResultsTable_SubSelect_ManifestAlias, s_SearchResultsTable_SubSelect_ValueAlias, MatchUsesLike(match));\r\n    }\r\n\r\n    std::vector<int> SearchResultsTable::BuildSearchStatement(\r\n        SQLite::Builder::StatementBuilder& builder,\r\n        PackageMatchField field,\r\n        std::string_view manifestAlias,\r\n        std::string_view valueAlias,\r\n        bool useLike) const\r\n    {\r\n        switch (field)\r\n        {\r\n        case PackageMatchField::Id:\r\n            return ManifestTable::BuildSearchStatement<IdTable>(builder, manifestAlias, valueAlias, useLike);\r\n        case PackageMatchField::Name:\r\n            return ManifestTable::BuildSearchStatement<NameTable>(builder, manifestAlias, valueAlias, useLike);\r\n        case PackageMatchField::Moniker:\r\n            return ManifestTable::BuildSearchStatement<MonikerTable>(builder, manifestAlias, valueAlias, useLike);\r\n        case PackageMatchField::Tag:\r\n            return ManifestTable::BuildSearchStatement<TagsTable>(builder, manifestAlias, valueAlias, useLike);\r\n        case PackageMatchField::Command:\r\n            return ManifestTable::BuildSearchStatement<CommandsTable>(builder, manifestAlias, valueAlias, useLike);\r\n        default:\r\n            return {};\r\n        }\r\n    }\r\n\r\n    bool SearchResultsTable::MatchUsesLike(MatchType match)\r\n    {\r\n        return (match != MatchType::Exact);\r\n    }\r\n\r\n    void SearchResultsTable::BindStatementForMatchType(SQLite::Statement& statement, MatchType match, int bindIndex, std::string_view value)\r\n    {\r\n        std::string valueToUse;\r\n\r\n        if (MatchUsesLike(match))\r\n        {\r\n            valueToUse = SQLite::EscapeStringForLike(value);\r\n        }\r\n        else\r\n        {\r\n            valueToUse = value;\r\n        }\r\n\r\n        switch (match)\r\n        {\r\n        case AppInstaller::Repository::MatchType::StartsWith:\r\n            valueToUse += '%';\r\n            break;\r\n        case AppInstaller::Repository::MatchType::Substring:\r\n            valueToUse = \"%\"s + valueToUse + '%';\r\n            break;\r\n        default:\r\n            // No changes required for others.\r\n            break;\r\n        }\r\n\r\n        statement.Bind(bindIndex, valueToUse);\r\n    }\r\n\r\n    void SearchResultsTable::BindStatementForMatchType(SQLite::Statement& statement, const PackageMatchFilter& filter, const std::vector<int>& bindIndex)\r\n    {\r\n        // TODO: Implement these more complex match types\r\n        if (filter.Type == MatchType::Wildcard || filter.Type == MatchType::Fuzzy || filter.Type == MatchType::FuzzySubstring)\r\n        {\r\n            AICLI_LOG(Repo, Verbose, << \"Specific match type not implemented, skipping: \" << ToString(filter.Type));\r\n            return;\r\n        }\r\n\r\n        BindStatementForMatchType(statement, filter.Type, bindIndex[0], filter.Value);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_0/TagsTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/1_0/OneToManyTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_0\r\n{\r\n    namespace details\r\n    {\r\n        using namespace std::string_view_literals;\r\n\r\n        struct TagsTableInfo\r\n        {\r\n            inline static constexpr std::string_view TableName() { return \"tags\"sv; }\r\n            inline static constexpr std::string_view ValueName() { return \"tag\"sv; }\r\n        };\r\n    }\r\n\r\n    // The table for Tags.\r\n    using TagsTable = OneToManyTable<details::TagsTableInfo>;\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_0/VersionTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/1_0/OneToOneTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_0\r\n{\r\n    namespace details\r\n    {\r\n        using namespace std::string_view_literals;\r\n\r\n        struct VersionTableInfo\r\n        {\r\n            inline static constexpr std::string_view TableName() { return \"versions\"sv; }\r\n            inline static constexpr std::string_view ValueName() { return \"version\"sv; }\r\n        };\r\n    }\r\n\r\n    // The table for Version.\r\n    using VersionTable = OneToOneTable<details::VersionTableInfo>;\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_0/VirtualTableBase.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_0\r\n{\r\n    // Since we have multiple manifest columns pointing to same table now(i.e. versions table), and previous assumption\r\n    // is manifest table column always has same name as referenced table column (i.e. manifest.version and versions.version),\r\n    // we need to differentiate manifest column name and referenced table column name(i.e. manifest.arp_min_version and versions.version)\r\n    // An optional ManifestColumnName() is added to virtual table for the above purpose, and can be used in the future if needed.\r\n    // To let the template codes better determine virtual tables, the following struct is created.\r\n\r\n    // Struct used as the base for virtual tables.\r\n    // Future virtual tables reusing an existing table should derive from this and implement\r\n    //    static std::string_view ManifestColumnName();\r\n    // in addition to regular table info methods.\r\n    struct VirtualTableBase\r\n    {\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_1/Interface.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/ISQLiteIndex.h\"\r\n#include \"Microsoft/Schema/1_0/Interface.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_1\r\n{\r\n    // Interface to this schema version exposed through ISQLiteIndex.\r\n    struct Interface : public V1_0::Interface\r\n    {\r\n        // Version 1.0\r\n        SQLite::Version GetVersion() const override;\r\n        void CreateTables(SQLite::Connection& connection, CreateOptions options) override;\r\n        SQLite::rowid_t AddManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath) override;\r\n        std::pair<bool, SQLite::rowid_t> UpdateManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath) override;\r\n        void RemoveManifestById(SQLite::Connection& connection, SQLite::rowid_t manifestId) override;\r\n        void PrepareForPackaging(SQLite::Connection& connection) override;\r\n        bool CheckConsistency(const SQLite::Connection& connection, bool log) const override;\r\n        SearchResult Search(const SQLite::Connection& connection, const SearchRequest& request) const override;\r\n        std::vector<std::string> GetMultiPropertyByPrimaryId(const SQLite::Connection& connection, SQLite::rowid_t primaryId, PackageVersionMultiProperty property) const override;\r\n\r\n        // Version 1.1\r\n        MetadataResult GetMetadataByManifestId(const SQLite::Connection& connection, SQLite::rowid_t manifestId) const override;\r\n        void SetMetadataByManifestId(SQLite::Connection& connection, SQLite::rowid_t manifestId, PackageVersionMetadata metadata, std::string_view value) override;\r\n\r\n        // Version 1.7\r\n        void DropTables(SQLite::Connection& connection) override;\r\n\r\n    protected:\r\n        std::unique_ptr<V1_0::SearchResultsTable> CreateSearchResultsTable(const SQLite::Connection& connection) const override;\r\n        void PerformQuerySearch(V1_0::SearchResultsTable& resultsTable, const RequestMatch& query) const override;\r\n        V1_0::OneToManyTableSchema GetOneToManyTableSchema() const override;\r\n\r\n        virtual SearchResult SearchInternal(const SQLite::Connection& connection, SearchRequest& request) const;\r\n        virtual void PrepareForPackaging(SQLite::Connection& connection, bool vacuum);\r\n\r\n        // Gets a property already knowing that the manifest id is valid.\r\n        virtual std::optional<std::string> GetPropertyByManifestIdInternal(const SQLite::Connection& connection, SQLite::rowid_t manifestId, PackageVersionProperty property) const;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_1/Interface_1_1.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Microsoft/Schema/1_1/Interface.h\"\r\n\r\n#include \"Microsoft/Schema/1_0/IdTable.h\"\r\n#include \"Microsoft/Schema/1_0/NameTable.h\"\r\n#include \"Microsoft/Schema/1_0/MonikerTable.h\"\r\n#include \"Microsoft/Schema/1_0/VersionTable.h\"\r\n#include \"Microsoft/Schema/1_0/ChannelTable.h\"\r\n\r\n#include \"Microsoft/Schema/1_0/PathPartTable.h\"\r\n\r\n#include \"Microsoft/Schema/1_0/ManifestTable.h\"\r\n\r\n#include \"Microsoft/Schema/1_0/TagsTable.h\"\r\n#include \"Microsoft/Schema/1_0/CommandsTable.h\"\r\n#include \"Microsoft/Schema/1_1/PackageFamilyNameTable.h\"\r\n#include \"Microsoft/Schema/1_1/ProductCodeTable.h\"\r\n\r\n#include \"Microsoft/Schema/1_1/SearchResultsTable.h\"\r\n\r\n#include \"Microsoft/Schema/1_1/ManifestMetadataTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_1\r\n{\r\n    SQLite::Version Interface::GetVersion() const\r\n    {\r\n        return { 1, 1 };\r\n    }\r\n\r\n    void Interface::CreateTables(SQLite::Connection& connection, CreateOptions options)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"createtables_v1_1\");\r\n\r\n        V1_0::IdTable::Create(connection);\r\n        V1_0::NameTable::Create(connection);\r\n        V1_0::MonikerTable::Create(connection);\r\n        V1_0::VersionTable::Create(connection);\r\n        V1_0::ChannelTable::Create(connection);\r\n\r\n        V1_0::PathPartTable::Create(connection);\r\n\r\n        V1_0::ManifestTable::Create(connection, {\r\n            { V1_0::IdTable::ValueName(), true, false },\r\n            { V1_0::NameTable::ValueName(), false, false },\r\n            { V1_0::MonikerTable::ValueName(), false, false },\r\n            { V1_0::VersionTable::ValueName(), true, false },\r\n            { V1_0::ChannelTable::ValueName(), true, false },\r\n            { V1_0::PathPartTable::ValueName(), false, WI_IsFlagClear(options, CreateOptions::SupportPathless) }\r\n            });\r\n\r\n        V1_0::TagsTable::Create(connection, GetOneToManyTableSchema());\r\n        V1_0::CommandsTable::Create(connection, GetOneToManyTableSchema());\r\n        PackageFamilyNameTable::Create(connection, GetOneToManyTableSchema());\r\n        ProductCodeTable::Create(connection, GetOneToManyTableSchema());\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    SQLite::rowid_t Interface::AddManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"addmanifest_v1_1\");\r\n\r\n        SQLite::rowid_t manifestId = V1_0::Interface::AddManifest(connection, manifest, relativePath);\r\n\r\n        // Add the new 1.1 data\r\n        // These system reference strings are all stored with their cases folded so that they can be\r\n        // looked up ordinally; enabling the index to provide efficient searches.\r\n        PackageFamilyNameTable::EnsureExistsAndInsert(connection, manifest.GetPackageFamilyNames(), manifestId);\r\n        ProductCodeTable::EnsureExistsAndInsert(connection, manifest.GetProductCodes(), manifestId);\r\n\r\n        savepoint.Commit();\r\n\r\n        return manifestId;\r\n    }\r\n\r\n    std::pair<bool, SQLite::rowid_t> Interface::UpdateManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"updatemanifest_v1_1\");\r\n\r\n        auto [indexModified, manifestId] = V1_0::Interface::UpdateManifest(connection, manifest, relativePath);\r\n\r\n        // Update new 1:N tables as necessary\r\n        indexModified = PackageFamilyNameTable::UpdateIfNeededByManifestId(connection, manifest.GetPackageFamilyNames(), manifestId) || indexModified;\r\n        indexModified = ProductCodeTable::UpdateIfNeededByManifestId(connection, manifest.GetProductCodes(), manifestId) || indexModified;\r\n\r\n        savepoint.Commit();\r\n\r\n        return { indexModified, manifestId };\r\n    }\r\n\r\n    void Interface::RemoveManifestById(SQLite::Connection& connection, SQLite::rowid_t manifestId)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"RemoveManifestById_v1_1\");\r\n\r\n        V1_0::Interface::RemoveManifestById(connection, manifestId);\r\n\r\n        // Remove all of the new 1:N data that is no longer referenced.\r\n        PackageFamilyNameTable::DeleteIfNotNeededByManifestId(connection, manifestId);\r\n        ProductCodeTable::DeleteIfNotNeededByManifestId(connection, manifestId);\r\n\r\n        if (ManifestMetadataTable::Exists(connection))\r\n        {\r\n            ManifestMetadataTable::DeleteByManifestId(connection, manifestId);\r\n        }\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    void Interface::PrepareForPackaging(SQLite::Connection& connection)\r\n    {\r\n        PrepareForPackaging(connection, true);\r\n    }\r\n\r\n    bool Interface::CheckConsistency(const SQLite::Connection& connection, bool log) const\r\n    {\r\n        bool result = V1_0::Interface::CheckConsistency(connection, log);\r\n\r\n        // If the v1.0 index was consistent, or if full logging of inconsistency was requested, check the v1.1 data.\r\n        if (result || log)\r\n        {\r\n            result = PackageFamilyNameTable::CheckConsistency(connection, log) && result;\r\n        }\r\n\r\n        if (result || log)\r\n        {\r\n            result = ProductCodeTable::CheckConsistency(connection, log) && result;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    ISQLiteIndex::SearchResult Interface::Search(const SQLite::Connection& connection, const SearchRequest& request) const\r\n    {\r\n        SearchRequest updatedRequest = request;\r\n        return SearchInternal(connection, updatedRequest);\r\n    }\r\n\r\n    std::vector<std::string> Interface::GetMultiPropertyByPrimaryId(const SQLite::Connection& connection, SQLite::rowid_t primaryId, PackageVersionMultiProperty property) const\r\n    {\r\n        switch (property)\r\n        {\r\n        case PackageVersionMultiProperty::PackageFamilyName:\r\n            return PackageFamilyNameTable::GetValuesByManifestId(connection, primaryId);\r\n        case PackageVersionMultiProperty::ProductCode:\r\n            return ProductCodeTable::GetValuesByManifestId(connection, primaryId);\r\n        default:\r\n            return V1_0::Interface::GetMultiPropertyByPrimaryId(connection, primaryId, property);\r\n        }\r\n    }\r\n\r\n    ISQLiteIndex::MetadataResult Interface::GetMetadataByManifestId(const SQLite::Connection& connection, SQLite::rowid_t manifestId) const\r\n    {\r\n        ISQLiteIndex::MetadataResult result;\r\n\r\n        if (ManifestMetadataTable::Exists(connection))\r\n        {\r\n            result = ManifestMetadataTable::GetMetadataByManifestId(connection, manifestId);\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    void Interface::SetMetadataByManifestId(SQLite::Connection& connection, SQLite::rowid_t manifestId, PackageVersionMetadata metadata, std::string_view value)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"setmetadatabymanifestid_v1_1\");\r\n\r\n        if (!ManifestMetadataTable::Exists(connection))\r\n        {\r\n            ManifestMetadataTable::Create(connection);\r\n        }\r\n\r\n        ManifestMetadataTable::SetMetadataByManifestId(connection, manifestId, metadata, value);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    void Interface::DropTables(SQLite::Connection& connection)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"drop_tables_v1_1\");\r\n\r\n        V1_0::Interface::DropTables(connection);\r\n\r\n        PackageFamilyNameTable::Drop(connection);\r\n        ProductCodeTable::Drop(connection);\r\n\r\n        ManifestMetadataTable::Drop(connection);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    std::unique_ptr<V1_0::SearchResultsTable> Interface::CreateSearchResultsTable(const SQLite::Connection& connection) const\r\n    {\r\n        return std::make_unique<V1_1::SearchResultsTable>(connection);\r\n    }\r\n\r\n    void Interface::PerformQuerySearch(V1_0::SearchResultsTable& resultsTable, const RequestMatch& query) const\r\n    {\r\n        // First, do an exact match search for the folded system reference strings\r\n        // We do this first because it is exact, and likely won't match anything else if it matches this.\r\n        PackageMatchFilter filter(PackageMatchField::PackageFamilyName, MatchType::Exact, Utility::FoldCase(query.Value));\r\n        resultsTable.SearchOnField(filter);\r\n\r\n        filter.Field = PackageMatchField::ProductCode;\r\n        resultsTable.SearchOnField(filter);\r\n\r\n        // Then do the 1.0 search\r\n        V1_0::Interface::PerformQuerySearch(resultsTable, query);\r\n    }\r\n\r\n    V1_0::OneToManyTableSchema Interface::GetOneToManyTableSchema() const\r\n    {\r\n        return V1_0::OneToManyTableSchema::Version_1_1;\r\n    }\r\n\r\n    ISQLiteIndex::SearchResult Interface::SearchInternal(const SQLite::Connection& connection, SearchRequest& request) const\r\n    {\r\n        // Update any system reference strings to be folded\r\n        auto foldIfNeeded = [](PackageMatchFilter& filter)\r\n        {\r\n            if ((filter.Field == PackageMatchField::PackageFamilyName || filter.Field == PackageMatchField::ProductCode) &&\r\n                filter.Type == MatchType::Exact)\r\n            {\r\n                filter.Value = Utility::FoldCase(filter.Value);\r\n            }\r\n        };\r\n\r\n        for (auto& inclusion : request.Inclusions)\r\n        {\r\n            foldIfNeeded(inclusion);\r\n        }\r\n\r\n        for (auto& filter : request.Filters)\r\n        {\r\n            foldIfNeeded(filter);\r\n        }\r\n\r\n        return V1_0::Interface::Search(connection, request);\r\n    }\r\n\r\n    void Interface::PrepareForPackaging(SQLite::Connection& connection, bool vacuum)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"prepareforpackaging_v1_1\");\r\n\r\n        V1_0::IdTable::PrepareForPackaging(connection);\r\n        V1_0::NameTable::PrepareForPackaging(connection);\r\n        V1_0::MonikerTable::PrepareForPackaging(connection);\r\n        V1_0::VersionTable::PrepareForPackaging(connection);\r\n        V1_0::ChannelTable::PrepareForPackaging(connection);\r\n\r\n        V1_0::PathPartTable::PrepareForPackaging(connection);\r\n\r\n        V1_0::ManifestTable::PrepareForPackaging(connection, {\r\n            V1_0::VersionTable::ValueName(),\r\n            V1_0::ChannelTable::ValueName(),\r\n            V1_0::PathPartTable::ValueName(),\r\n            });\r\n\r\n        V1_0::TagsTable::PrepareForPackaging(connection, GetOneToManyTableSchema(), false, false);\r\n        V1_0::CommandsTable::PrepareForPackaging(connection, GetOneToManyTableSchema(), false, false);\r\n        PackageFamilyNameTable::PrepareForPackaging(connection, GetOneToManyTableSchema(), true, true);\r\n        ProductCodeTable::PrepareForPackaging(connection, GetOneToManyTableSchema(), true, true);\r\n\r\n        savepoint.Commit();\r\n\r\n        if (vacuum)\r\n        {\r\n            Vacuum(connection);\r\n        }\r\n    }\r\n\r\n    std::optional<std::string> Interface::GetPropertyByManifestIdInternal(const SQLite::Connection& connection, SQLite::rowid_t manifestId, PackageVersionProperty property) const\r\n    {\r\n        switch (property)\r\n        {\r\n        case AppInstaller::Repository::PackageVersionProperty::Publisher:\r\n        {\r\n            // Publisher is not a primary data member in this version, but it may be stored in the metadata\r\n            if (ManifestMetadataTable::Exists(connection))\r\n            {\r\n                return ManifestMetadataTable::GetMetadataByManifestIdAndMetadata(connection, manifestId, PackageVersionMetadata::Publisher);\r\n            }\r\n\r\n            // No metadata, so no publisher\r\n            return {};\r\n        }\r\n        default:\r\n            return V1_0::Interface::GetPropertyByManifestIdInternal(connection, manifestId, property);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_1/ManifestMetadataTable.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ManifestMetadataTable.h\"\r\n#include <winget/SQLiteStatementBuilder.h>\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_1\r\n{\r\n    using namespace SQLite;\r\n\r\n    static constexpr std::string_view s_ManifestMetadataTable_Table_Name = \"manifest_metadata\"sv;\r\n    static constexpr std::string_view s_ManifestMetadataTable_PrimaryKeyIndex_Name = \"manifest_metadata_pk\"sv;\r\n    static constexpr std::string_view s_ManifestMetadataTable_Manifest_Column = \"manifest\"sv;\r\n    static constexpr std::string_view s_ManifestMetadataTable_Metadata_Column = \"metadata\"sv;\r\n    static constexpr std::string_view s_ManifestMetadataTable_Value_Column = \"value\"sv;\r\n\r\n    bool ManifestMetadataTable::Exists(const SQLite::Connection& connection)\r\n    {\r\n        Builder::StatementBuilder builder;\r\n        builder.Select(Builder::RowCount).From(Builder::Schema::MainTable).\r\n            Where(Builder::Schema::TypeColumn).Equals(Builder::Schema::Type_Table).And(Builder::Schema::NameColumn).Equals(s_ManifestMetadataTable_Table_Name);\r\n\r\n        Statement statement = builder.Prepare(connection);\r\n        THROW_HR_IF(E_UNEXPECTED, !statement.Step());\r\n        return statement.GetColumn<int64_t>(0) != 0;\r\n    }\r\n\r\n    void ManifestMetadataTable::Create(SQLite::Connection& connection)\r\n    {\r\n        using namespace Builder;\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"createmanifestmetadata_v1_1\");\r\n\r\n        StatementBuilder createTableBuilder;\r\n        createTableBuilder.CreateTable(s_ManifestMetadataTable_Table_Name).Columns({\r\n            ColumnBuilder(s_ManifestMetadataTable_Manifest_Column, Type::Int64).NotNull(),\r\n            ColumnBuilder(s_ManifestMetadataTable_Metadata_Column, Type::Int64).NotNull(),\r\n            ColumnBuilder(s_ManifestMetadataTable_Value_Column, Type::Text)\r\n            });\r\n\r\n        createTableBuilder.Execute(connection);\r\n\r\n        StatementBuilder createPKIndexBuilder;\r\n        createPKIndexBuilder.CreateUniqueIndex(s_ManifestMetadataTable_PrimaryKeyIndex_Name).On(s_ManifestMetadataTable_Table_Name).\r\n            Columns({ s_ManifestMetadataTable_Manifest_Column, s_ManifestMetadataTable_Metadata_Column });\r\n        createPKIndexBuilder.Execute(connection);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    void ManifestMetadataTable::Drop(SQLite::Connection& connection)\r\n    {\r\n        SQLite::Builder::StatementBuilder dropTableBuilder;\r\n        dropTableBuilder.DropTableIfExists(s_ManifestMetadataTable_Table_Name);\r\n\r\n        dropTableBuilder.Execute(connection);\r\n    }\r\n\r\n    ISQLiteIndex::MetadataResult ManifestMetadataTable::GetMetadataByManifestId(const SQLite::Connection& connection, SQLite::rowid_t manifestId)\r\n    {\r\n        using namespace Builder;\r\n\r\n        StatementBuilder builder;\r\n        builder.Select({ s_ManifestMetadataTable_Metadata_Column, s_ManifestMetadataTable_Value_Column }).From(s_ManifestMetadataTable_Table_Name).\r\n            Where(s_ManifestMetadataTable_Manifest_Column).Equals(manifestId);\r\n\r\n        Statement statement = builder.Prepare(connection);\r\n\r\n        ISQLiteIndex::MetadataResult result;\r\n        while (statement.Step())\r\n        {\r\n            result.emplace_back(std::make_pair(statement.GetColumn<PackageVersionMetadata>(0), statement.GetColumn<std::string>(1)));\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::optional<std::string> ManifestMetadataTable::GetMetadataByManifestIdAndMetadata(const SQLite::Connection& connection, SQLite::rowid_t manifestId, PackageVersionMetadata metadata)\r\n    {\r\n        using namespace Builder;\r\n\r\n        StatementBuilder builder;\r\n        builder.Select(s_ManifestMetadataTable_Value_Column).From(s_ManifestMetadataTable_Table_Name).\r\n            Where(s_ManifestMetadataTable_Manifest_Column).Equals(manifestId).\r\n            And(s_ManifestMetadataTable_Metadata_Column).Equals(metadata);\r\n\r\n        Statement statement = builder.Prepare(connection);\r\n\r\n        if (statement.Step())\r\n        {\r\n            return statement.GetColumn<std::string>(0);\r\n        }\r\n\r\n        return {};\r\n    }\r\n\r\n    void ManifestMetadataTable::SetMetadataByManifestId(SQLite::Connection& connection, SQLite::rowid_t manifestId, PackageVersionMetadata metadata, std::string_view value)\r\n    {\r\n        using namespace Builder;\r\n\r\n        // First, we attempt to update an existing row. If not changes occurred, we then insert the new value.\r\n        // UPSERT (aka ON CONFLICT) is not available to us, as it was only introduced in 3.24.0 (2018-06-04),\r\n        // and we need to support Windows 10 (17763) which was released in 2017.\r\n        StatementBuilder updateBuilder;\r\n        updateBuilder.Update(s_ManifestMetadataTable_Table_Name).Set().Column(s_ManifestMetadataTable_Value_Column).Equals(value).\r\n            Where(s_ManifestMetadataTable_Manifest_Column).Equals(manifestId).And(s_ManifestMetadataTable_Metadata_Column).Equals(metadata);\r\n\r\n        updateBuilder.Execute(connection);\r\n\r\n        // No changes means we need to insert the row\r\n        if (connection.GetChanges() == 0)\r\n        {\r\n            StatementBuilder insertBuilder;\r\n            insertBuilder.InsertInto(s_ManifestMetadataTable_Table_Name).\r\n                Columns({ s_ManifestMetadataTable_Manifest_Column, s_ManifestMetadataTable_Metadata_Column, s_ManifestMetadataTable_Value_Column })\r\n                .Values(manifestId, metadata, value);\r\n\r\n            insertBuilder.Execute(connection);\r\n        }\r\n    }\r\n\r\n    void ManifestMetadataTable::DeleteByManifestId(SQLite::Connection & connection, SQLite::rowid_t manifestId)\r\n    {\r\n        using namespace Builder;\r\n\r\n        StatementBuilder builder;\r\n        builder.DeleteFrom(s_ManifestMetadataTable_Table_Name).Where(s_ManifestMetadataTable_Manifest_Column).Equals(manifestId);\r\n        builder.Execute(connection);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_1/ManifestMetadataTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteWrapper.h>\r\n#include \"Microsoft/Schema/ISQLiteIndex.h\"\r\n#include \"Public/winget/RepositorySearch.h\"\r\n\r\n#include <string>\r\n#include <string_view>\r\n#include <vector>\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_1\r\n{\r\n    // A table for storing arbitrary metadata on individual manifests.\r\n    // The table and all metadata are optional.\r\n    struct ManifestMetadataTable\r\n    {\r\n        // Determine if the table currently exists in the database.\r\n        static bool Exists(const SQLite::Connection& connection);\r\n\r\n        // Creates the table in the database.\r\n        static void Create(SQLite::Connection& connection);\r\n\r\n        // Drops the table.\r\n        static void Drop(SQLite::Connection& connection);\r\n\r\n        // Gets all metadata associated with the given manifest.\r\n        // The table must exist.\r\n        static ISQLiteIndex::MetadataResult GetMetadataByManifestId(const SQLite::Connection& connection, SQLite::rowid_t manifestId);\r\n\r\n        // Gets the specific metadata value for the manifest, if it exists.\r\n        // The table must exist.\r\n        static std::optional<std::string> GetMetadataByManifestIdAndMetadata(const SQLite::Connection& connection, SQLite::rowid_t manifestId, PackageVersionMetadata metadata);\r\n\r\n        // Sets the metadata value for the given manifest.\r\n        // The table must exist.\r\n        static void SetMetadataByManifestId(SQLite::Connection& connection, SQLite::rowid_t manifestId, PackageVersionMetadata metadata, std::string_view value);\r\n\r\n        // Removes all metadata values for the given manifest.\r\n        // The table must exist.\r\n        static void DeleteByManifestId(SQLite::Connection& connection, SQLite::rowid_t manifestId);\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_1/PackageFamilyNameTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/1_0/OneToManyTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_1\r\n{\r\n    namespace details\r\n    {\r\n        using namespace std::string_view_literals;\r\n\r\n        struct PackageFamilyNameTableInfo\r\n        {\r\n            inline static constexpr std::string_view TableName() { return \"pfns\"sv; }\r\n            inline static constexpr std::string_view ValueName() { return \"pfn\"sv; }\r\n        };\r\n    }\r\n\r\n    // The table for PackageFamilyName.\r\n    using PackageFamilyNameTable = V1_0::OneToManyTable<details::PackageFamilyNameTableInfo>;\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_1/ProductCodeTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/1_0/OneToManyTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_1\r\n{\r\n    namespace details\r\n    {\r\n        using namespace std::string_view_literals;\r\n\r\n        struct ProductCodeTableInfo\r\n        {\r\n            inline static constexpr std::string_view TableName() { return \"productcodes\"sv; }\r\n            inline static constexpr std::string_view ValueName() { return \"productcode\"sv; }\r\n        };\r\n    }\r\n\r\n    // The table for ProductCode.\r\n    using ProductCodeTable = V1_0::OneToManyTable<details::ProductCodeTableInfo>;\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_1/SearchResultsTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/1_0/SearchResultsTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_1\r\n{\r\n    // Table for holding temporary search results.\r\n    struct SearchResultsTable : public V1_0::SearchResultsTable\r\n    {\r\n        SearchResultsTable(const SQLite::Connection& connection) : V1_0::SearchResultsTable(connection) {}\r\n\r\n        SearchResultsTable(const SearchResultsTable&) = delete;\r\n        SearchResultsTable& operator=(const SearchResultsTable&) = delete;\r\n\r\n        SearchResultsTable(SearchResultsTable&&) = default;\r\n        SearchResultsTable& operator=(SearchResultsTable&&) = default;\r\n\r\n    protected:\r\n        std::vector<int> BuildSearchStatement(\r\n            SQLite::Builder::StatementBuilder& builder,\r\n            PackageMatchField field,\r\n            std::string_view manifestAlias,\r\n            std::string_view valueAlias,\r\n            bool useLike) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_1/SearchResultsTable_1_1.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"SearchResultsTable.h\"\r\n\r\n#include \"Microsoft/Schema/1_0/ManifestTable.h\"\r\n#include \"Microsoft/Schema/1_1/PackageFamilyNameTable.h\"\r\n#include \"Microsoft/Schema/1_1/ProductCodeTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_1\r\n{\r\n    std::vector<int> SearchResultsTable::BuildSearchStatement(\r\n        SQLite::Builder::StatementBuilder& builder,\r\n        PackageMatchField field,\r\n        std::string_view manifestAlias,\r\n        std::string_view valueAlias,\r\n        bool useLike) const\r\n    {\r\n        switch (field)\r\n        {\r\n        case PackageMatchField::PackageFamilyName:\r\n            return V1_0::ManifestTable::BuildSearchStatement<PackageFamilyNameTable>(builder, manifestAlias, valueAlias, useLike);\r\n        case PackageMatchField::ProductCode:\r\n            return V1_0::ManifestTable::BuildSearchStatement<ProductCodeTable>(builder, manifestAlias, valueAlias, useLike);\r\n        default:\r\n            return V1_0::SearchResultsTable::BuildSearchStatement(builder, field, manifestAlias, valueAlias, useLike);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_2/Interface.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/ISQLiteIndex.h\"\r\n#include \"Microsoft/Schema/1_1/Interface.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_2\r\n{\r\n    // Interface to this schema version exposed through ISQLiteIndex.\r\n    struct Interface : public V1_1::Interface\r\n    {\r\n        Interface(Utility::NormalizationVersion normVersion = Utility::NormalizationVersion::Initial);\r\n\r\n        // Version 1.0\r\n        SQLite::Version GetVersion() const override;\r\n        void CreateTables(SQLite::Connection& connection, CreateOptions options) override;\r\n        SQLite::rowid_t AddManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath) override;\r\n        std::pair<bool, SQLite::rowid_t> UpdateManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath) override;\r\n        void RemoveManifestById(SQLite::Connection& connection, SQLite::rowid_t manifestId) override;\r\n        bool CheckConsistency(const SQLite::Connection& connection, bool log) const override;\r\n        std::vector<std::string> GetMultiPropertyByPrimaryId(const SQLite::Connection& connection, SQLite::rowid_t primaryId, PackageVersionMultiProperty property) const override;\r\n\r\n        // Version 1.2\r\n        Utility::NormalizedName NormalizeName(std::string_view name, std::string_view publisher) const override;\r\n\r\n        // Version 1.7\r\n        void DropTables(SQLite::Connection& connection) override;\r\n\r\n    protected:\r\n        std::unique_ptr<V1_0::SearchResultsTable> CreateSearchResultsTable(const SQLite::Connection& connection) const override;\r\n        SearchResult SearchInternal(const SQLite::Connection& connection, SearchRequest& request) const override;\r\n        void PrepareForPackaging(SQLite::Connection& connection, bool vacuum) override;\r\n\r\n        // The name normalization utility\r\n        Utility::NameNormalizer m_normalizer;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_2/Interface_1_2.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Microsoft/Schema/1_2/Interface.h\"\r\n\r\n#include \"Microsoft/Schema/1_2/NormalizedPackageNameTable.h\"\r\n#include \"Microsoft/Schema/1_2/NormalizedPackagePublisherTable.h\"\r\n\r\n#include \"Microsoft/Schema/1_2/SearchResultsTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_2\r\n{\r\n    namespace anon\r\n    {\r\n        void AddNormalizedName(\r\n            const Utility::NameNormalizer& normalizer,\r\n            const Manifest::string_t& name,\r\n            std::vector<Utility::NormalizedString>& out,\r\n            Utility::NormalizationField fieldsToInclude = Utility::NormalizationField::None)\r\n        {\r\n            Utility::NormalizedString value = normalizer.NormalizeName(Utility::FoldCase(name)).GetNormalizedName(fieldsToInclude);\r\n            if (std::find(out.begin(), out.end(), value) == out.end())\r\n            {\r\n                out.emplace_back(std::move(value));\r\n            }\r\n        }\r\n\r\n        void AddLocalizationNormalizedName(const Utility::NameNormalizer& normalizer, const Manifest::ManifestLocalization& localization, std::vector<Utility::NormalizedString>& out)\r\n        {\r\n            if (localization.Contains(Manifest::Localization::PackageName))\r\n            {\r\n                AddNormalizedName(normalizer, localization.Get<Manifest::Localization::PackageName>(), out);\r\n            }\r\n        }\r\n\r\n        void AddNormalizedPublisher(const Utility::NameNormalizer& normalizer, const Manifest::string_t& publisher, std::vector<Utility::NormalizedString>& out)\r\n        {\r\n            Utility::NormalizedString value = normalizer.NormalizePublisher(Utility::FoldCase(publisher));\r\n            if (std::find(out.begin(), out.end(), value) == out.end())\r\n            {\r\n                out.emplace_back(std::move(value));\r\n            }\r\n        }\r\n\r\n        void AddLocalizationNormalizedPublisher(const Utility::NameNormalizer& normalizer, const Manifest::ManifestLocalization& localization, std::vector<Utility::NormalizedString>& out)\r\n        {\r\n            if (localization.Contains(Manifest::Localization::Publisher))\r\n            {\r\n                AddNormalizedPublisher(normalizer, localization.Get<Manifest::Localization::Publisher>(), out);\r\n            }\r\n        }\r\n\r\n        std::vector<Utility::NormalizedString> GetNormalizedNames(const Utility::NameNormalizer& normalizer, const Manifest::Manifest& manifest)\r\n        {\r\n            std::vector<Utility::NormalizedString> result;\r\n\r\n            AddLocalizationNormalizedName(normalizer, manifest.DefaultLocalization, result);\r\n            for (const auto& loc : manifest.Localizations)\r\n            {\r\n                AddLocalizationNormalizedName(normalizer, loc, result);\r\n            }\r\n\r\n            // In addition to the names used for our display, add the display names from the ARP entries\r\n            for (const auto& installer : manifest.Installers)\r\n            {\r\n                for (const auto& appsAndFeaturesEntry : installer.AppsAndFeaturesEntries)\r\n                {\r\n                    if (!appsAndFeaturesEntry.DisplayName.empty())\r\n                    {\r\n                        AddNormalizedName(normalizer, appsAndFeaturesEntry.DisplayName, result);\r\n                        // For arp display name, also add a copy with architecture info for more accurate correlation.\r\n                        AddNormalizedName(normalizer, appsAndFeaturesEntry.DisplayName, result, Utility::NormalizationField::Architecture);\r\n                    }\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        std::vector<Utility::NormalizedString> GetNormalizedPublishers(const Utility::NameNormalizer& normalizer, const Manifest::Manifest& manifest)\r\n        {\r\n            std::vector<Utility::NormalizedString> result;\r\n\r\n            AddLocalizationNormalizedPublisher(normalizer, manifest.DefaultLocalization, result);\r\n            for (const auto& loc : manifest.Localizations)\r\n            {\r\n                AddLocalizationNormalizedPublisher(normalizer, loc, result);\r\n            }\r\n\r\n            // In addition to the publishers used for our display, add the publishers from the ARP entries\r\n            for (const auto& installer : manifest.Installers)\r\n            {\r\n                for (const auto& appsAndFeaturesEntry : installer.AppsAndFeaturesEntries)\r\n                {\r\n                    if (!appsAndFeaturesEntry.Publisher.empty())\r\n                    {\r\n                        AddNormalizedPublisher(normalizer, appsAndFeaturesEntry.Publisher, result);\r\n                    }\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        // Update NormalizedNameAndPublisher with normalization and folding\r\n        // Returns true if the normalized name contains normalization field of fieldsToInclude\r\n        bool UpdateNormalizedNameAndPublisher(\r\n            PackageMatchFilter& filter,\r\n            const Utility::NameNormalizer& normalizer,\r\n            Utility::NormalizationField fieldsToInclude)\r\n        {\r\n            Utility::NormalizedName normalized = normalizer.Normalize(Utility::FoldCase(filter.Value), Utility::FoldCase(filter.Additional.value()));\r\n            filter.Value = normalized.GetNormalizedName(fieldsToInclude);\r\n            filter.Additional = normalized.Publisher();\r\n            return WI_AreAllFlagsSet(normalized.GetNormalizedFields(), fieldsToInclude);\r\n        }\r\n\r\n        // Update NormalizedNameAndPublisher with normalization and folding\r\n        // Returns true if any of normalized name contains normalization field of fieldsToInclude\r\n        bool UpdatePackageMatchFilters(\r\n            std::vector<PackageMatchFilter>& filters,\r\n            const Utility::NameNormalizer& normalizer,\r\n            Utility::NormalizationField normalizedNameFieldsToFilter = Utility::NormalizationField::None)\r\n        {\r\n            bool normalizedNameFieldsFound = false;\r\n            for (auto itr = filters.begin(); itr != filters.end();)\r\n            {\r\n                if (itr->Field == PackageMatchField::NormalizedNameAndPublisher && itr->Type == MatchType::Exact)\r\n                {\r\n                    if (!UpdateNormalizedNameAndPublisher(*itr, normalizer, normalizedNameFieldsToFilter))\r\n                    {\r\n                        // If not matched, this package match filter will be removed.\r\n                        // For example, if caller is trying to search with arch info only, values without arch will be removed from search.\r\n                        itr = filters.erase(itr);\r\n                        continue;\r\n                    }\r\n\r\n                    normalizedNameFieldsFound = true;\r\n                }\r\n\r\n                ++itr;\r\n            }\r\n\r\n            return normalizedNameFieldsFound;\r\n        }\r\n    }\r\n\r\n    Interface::Interface(Utility::NormalizationVersion normVersion) : m_normalizer(normVersion)\r\n    {\r\n    }\r\n\r\n    SQLite::Version Interface::GetVersion() const\r\n    {\r\n        return { 1, 2 };\r\n    }\r\n\r\n    void Interface::CreateTables(SQLite::Connection& connection, CreateOptions options)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"createtables_v1_2\");\r\n\r\n        V1_1::Interface::CreateTables(connection, options);\r\n\r\n        // While the name and publisher should be linked per-locale, we are not implementing that here.\r\n        // This will mean that one can match cross locale name and publisher, but the chance that this\r\n        // leads to a confusion between packages is very small. More likely would be intentional attempts\r\n        // to confuse the correlation, which could be fairly easily carried out even with linked values.\r\n        NormalizedPackageNameTable::Create(connection, GetOneToManyTableSchema());\r\n        NormalizedPackagePublisherTable::Create(connection, GetOneToManyTableSchema());\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    SQLite::rowid_t Interface::AddManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"addmanifest_v1_2\");\r\n\r\n        SQLite::rowid_t manifestId = V1_1::Interface::AddManifest(connection, manifest, relativePath);\r\n\r\n        // Add the new 1.2 data\r\n        // These normalized strings are all stored with their cases folded so that they can be\r\n        // looked up ordinally; enabling the index to provide efficient searches.\r\n        NormalizedPackageNameTable::EnsureExistsAndInsert(connection, anon::GetNormalizedNames(m_normalizer, manifest), manifestId);\r\n        NormalizedPackagePublisherTable::EnsureExistsAndInsert(connection, anon::GetNormalizedPublishers(m_normalizer, manifest), manifestId);\r\n\r\n        savepoint.Commit();\r\n\r\n        return manifestId;\r\n    }\r\n\r\n    std::pair<bool, SQLite::rowid_t> Interface::UpdateManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"updatemanifest_v1_2\");\r\n\r\n        auto [indexModified, manifestId] = V1_1::Interface::UpdateManifest(connection, manifest, relativePath);\r\n\r\n        // Update new 1.2 tables as necessary\r\n        indexModified = NormalizedPackageNameTable::UpdateIfNeededByManifestId(connection, anon::GetNormalizedNames(m_normalizer, manifest), manifestId) || indexModified;\r\n        indexModified = NormalizedPackagePublisherTable::UpdateIfNeededByManifestId(connection, anon::GetNormalizedPublishers(m_normalizer, manifest), manifestId) || indexModified;\r\n\r\n        savepoint.Commit();\r\n\r\n        return { indexModified, manifestId };\r\n    }\r\n\r\n    void Interface::RemoveManifestById(SQLite::Connection& connection, SQLite::rowid_t manifestId)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"RemoveManifestById_v1_2\");\r\n\r\n        V1_1::Interface::RemoveManifestById(connection, manifestId);\r\n\r\n        // Remove all of the new 1.2 data that is no longer referenced.\r\n        NormalizedPackageNameTable::DeleteIfNotNeededByManifestId(connection, manifestId);\r\n        NormalizedPackagePublisherTable::DeleteIfNotNeededByManifestId(connection, manifestId);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    bool Interface::CheckConsistency(const SQLite::Connection& connection, bool log) const\r\n    {\r\n        bool result = V1_1::Interface::CheckConsistency(connection, log);\r\n\r\n        // If the v1.1 index was consistent, or if full logging of inconsistency was requested, check the v1.2 data.\r\n        if (result || log)\r\n        {\r\n            result = NormalizedPackageNameTable::CheckConsistency(connection, log) && result;\r\n        }\r\n\r\n        if (result || log)\r\n        {\r\n            result = NormalizedPackagePublisherTable::CheckConsistency(connection, log) && result;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<std::string> Interface::GetMultiPropertyByPrimaryId(const SQLite::Connection& connection, SQLite::rowid_t primaryId, PackageVersionMultiProperty property) const\r\n    {\r\n        switch (property)\r\n        {\r\n            // These values are not right, as they are normalized.  But they are good enough for now and all we have.\r\n        case PackageVersionMultiProperty::Name:\r\n            return NormalizedPackageNameTable::GetValuesByManifestId(connection, primaryId);\r\n        case PackageVersionMultiProperty::Publisher:\r\n            return NormalizedPackagePublisherTable::GetValuesByManifestId(connection, primaryId);\r\n        default:\r\n            return V1_1::Interface::GetMultiPropertyByPrimaryId(connection, primaryId, property);\r\n        }\r\n    }\r\n\r\n    Utility::NormalizedName Interface::NormalizeName(std::string_view name, std::string_view publisher) const\r\n    {\r\n        return m_normalizer.Normalize(name, publisher);\r\n    }\r\n\r\n    void Interface::DropTables(SQLite::Connection& connection)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"drop_tables_v1_2\");\r\n\r\n        V1_1::Interface::DropTables(connection);\r\n\r\n        NormalizedPackageNameTable::Drop(connection);\r\n        NormalizedPackagePublisherTable::Drop(connection);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    std::unique_ptr<V1_0::SearchResultsTable> Interface::CreateSearchResultsTable(const SQLite::Connection& connection) const\r\n    {\r\n        return std::make_unique<V1_2::SearchResultsTable>(connection);\r\n    }\r\n\r\n    ISQLiteIndex::SearchResult Interface::SearchInternal(const SQLite::Connection& connection, SearchRequest& request) const\r\n    {\r\n        if (request.Purpose == SearchPurpose::CorrelationToInstalled)\r\n        {\r\n            // Correlate from available package to installed package\r\n            // For available package to installed package mapping, only one try is needed.\r\n            // For example, if ARP DisplayName contains arch, then the installed package's ARP DisplayName should also include arch.\r\n            auto candidateInclusionsWithArch = request.Inclusions;\r\n            if (anon::UpdatePackageMatchFilters(candidateInclusionsWithArch, m_normalizer, Utility::NormalizationField::Architecture))\r\n            {\r\n                // If DisplayNames contain arch, only use Inclusions with arch for search\r\n                request.Inclusions = candidateInclusionsWithArch;\r\n            }\r\n            else\r\n            {\r\n                // Otherwise, just update the Inclusions with normalization\r\n                anon::UpdatePackageMatchFilters(request.Inclusions, m_normalizer);\r\n            }\r\n\r\n            return V1_1::Interface::SearchInternal(connection, request);\r\n        }\r\n        else if (request.Purpose == SearchPurpose::CorrelationToAvailable)\r\n        {\r\n            // For installed package to available package correlation,\r\n            // try the search with NormalizedName with Arch first, if not found, try with all values.\r\n            // This can be extended in the future for more granular search requests.\r\n            std::vector<SearchRequest> candidateSearches;\r\n            auto candidateSearchWithArch = request;\r\n            if (anon::UpdatePackageMatchFilters(candidateSearchWithArch.Inclusions, m_normalizer, Utility::NormalizationField::Architecture))\r\n            {\r\n                candidateSearches.emplace_back(std::move(candidateSearchWithArch));\r\n            }\r\n            anon::UpdatePackageMatchFilters(request.Inclusions, m_normalizer);\r\n            candidateSearches.emplace_back(request);\r\n\r\n            SearchResult result;\r\n            for (auto& candidateSearch : candidateSearches)\r\n            {\r\n                result = V1_1::Interface::SearchInternal(connection, candidateSearch);\r\n                if (!result.Matches.empty())\r\n                {\r\n                    break;\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n        else\r\n        {\r\n            anon::UpdatePackageMatchFilters(request.Inclusions, m_normalizer);\r\n            anon::UpdatePackageMatchFilters(request.Filters, m_normalizer);\r\n\r\n            return V1_1::Interface::SearchInternal(connection, request);\r\n        }\r\n    }\r\n\r\n    void Interface::PrepareForPackaging(SQLite::Connection& connection, bool vacuum)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"prepareforpackaging_v1_2\");\r\n\r\n        V1_1::Interface::PrepareForPackaging(connection, false);\r\n\r\n        NormalizedPackageNameTable::PrepareForPackaging(connection, GetOneToManyTableSchema(), true, true);\r\n        NormalizedPackagePublisherTable::PrepareForPackaging(connection, GetOneToManyTableSchema(), true, true);\r\n\r\n        savepoint.Commit();\r\n\r\n        if (vacuum)\r\n        {\r\n            Vacuum(connection);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_2/NormalizedPackageNameTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/1_0/OneToManyTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_2\r\n{\r\n    namespace details\r\n    {\r\n        using namespace std::string_view_literals;\r\n\r\n        struct NormalizedPackageNameTableInfo\r\n        {\r\n            inline static constexpr std::string_view TableName() { return \"norm_names\"sv; }\r\n            inline static constexpr std::string_view ValueName() { return \"norm_name\"sv; }\r\n        };\r\n    }\r\n\r\n    // The table for NormalizedPackageName.\r\n    using NormalizedPackageNameTable = V1_0::OneToManyTable<details::NormalizedPackageNameTableInfo>;\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_2/NormalizedPackagePublisherTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/1_0/OneToManyTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_2\r\n{\r\n    namespace details\r\n    {\r\n        using namespace std::string_view_literals;\r\n\r\n        struct NormalizedPackagePublisherTableInfo\r\n        {\r\n            inline static constexpr std::string_view TableName() { return \"norm_publishers\"sv; }\r\n            inline static constexpr std::string_view ValueName() { return \"norm_publisher\"sv; }\r\n        };\r\n    }\r\n\r\n    // The table for NormalizedPackagePublisher.\r\n    using NormalizedPackagePublisherTable = V1_0::OneToManyTable<details::NormalizedPackagePublisherTableInfo>;\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_2/SearchResultsTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/1_1/SearchResultsTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_2\r\n{\r\n    // Table for holding temporary search results.\r\n    struct SearchResultsTable : public V1_1::SearchResultsTable\r\n    {\r\n        SearchResultsTable(const SQLite::Connection& connection) : V1_1::SearchResultsTable(connection) {}\r\n\r\n        SearchResultsTable(const SearchResultsTable&) = delete;\r\n        SearchResultsTable& operator=(const SearchResultsTable&) = delete;\r\n\r\n        SearchResultsTable(SearchResultsTable&&) = default;\r\n        SearchResultsTable& operator=(SearchResultsTable&&) = default;\r\n\r\n    protected:\r\n        std::vector<int> BuildSearchStatement(\r\n            SQLite::Builder::StatementBuilder& builder,\r\n            PackageMatchField field,\r\n            std::string_view manifestAlias,\r\n            std::string_view valueAlias,\r\n            bool useLike) const override;\r\n\r\n        // Import all overrides of this function\r\n        using V1_0::SearchResultsTable::BindStatementForMatchType;\r\n\r\n        void BindStatementForMatchType(SQLite::Statement& statement, const PackageMatchFilter& filter, const std::vector<int>& bindIndex) override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_2/SearchResultsTable_1_2.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"SearchResultsTable.h\"\r\n\r\n#include \"Microsoft/Schema/1_0/ManifestTable.h\"\r\n#include \"Microsoft/Schema/1_2/NormalizedPackageNameTable.h\"\r\n#include \"Microsoft/Schema/1_2/NormalizedPackagePublisherTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_2\r\n{\r\n    std::vector<int> SearchResultsTable::BuildSearchStatement(\r\n        SQLite::Builder::StatementBuilder& builder,\r\n        PackageMatchField field,\r\n        std::string_view manifestAlias,\r\n        std::string_view valueAlias,\r\n        bool useLike) const\r\n    {\r\n        switch (field)\r\n        {\r\n        case PackageMatchField::NormalizedNameAndPublisher:\r\n            return V1_0::ManifestTable::BuildSearchStatement<NormalizedPackageNameTable, NormalizedPackagePublisherTable>(builder, manifestAlias, valueAlias, useLike);\r\n        default:\r\n            return V1_1::SearchResultsTable::BuildSearchStatement(builder, field, manifestAlias, valueAlias, useLike);\r\n        }\r\n    }\r\n\r\n    void SearchResultsTable::BindStatementForMatchType(SQLite::Statement& statement, const PackageMatchFilter& filter, const std::vector<int>& bindIndex)\r\n    {\r\n        V1_0::SearchResultsTable::BindStatementForMatchType(statement, filter, bindIndex);\r\n\r\n        if (filter.Field == PackageMatchField::NormalizedNameAndPublisher)\r\n        {\r\n            BindStatementForMatchType(statement, filter.Type, bindIndex[1], filter.Additional.value());\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_3/HashVirtualTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteStatementBuilder.h>\r\n\r\n#include <string_view>\r\n\r\nusing namespace std::string_view_literals;\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_3\r\n{\r\n    // A virtual table used to add a direct column onto the manifest table.\r\n    struct HashVirtualTable\r\n    {\r\n        // The id type (which is actually the value for this virtual table)\r\n        using id_t = SQLite::blob_t;\r\n\r\n        // The name of the column.\r\n        static constexpr std::string_view ValueName()\r\n        {\r\n            return \"hash\"sv;\r\n        }\r\n\r\n        // The value type of the column.\r\n        static constexpr SQLite::Builder::Type SQLiteType()\r\n        {\r\n            return SQLite::Builder::Type::Blob;\r\n        }\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_3/Interface.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/ISQLiteIndex.h\"\r\n#include \"Microsoft/Schema/1_2/Interface.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_3\r\n{\r\n    // Interface to this schema version exposed through ISQLiteIndex.\r\n    struct Interface : public V1_2::Interface\r\n    {\r\n        Interface(Utility::NormalizationVersion normVersion = Utility::NormalizationVersion::Initial);\r\n\r\n        // Version 1.0\r\n        SQLite::Version GetVersion() const override;\r\n        void CreateTables(SQLite::Connection& connection, CreateOptions options) override;\r\n        SQLite::rowid_t AddManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath) override;\r\n        std::pair<bool, SQLite::rowid_t> UpdateManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath) override;\r\n\r\n    protected:\r\n        // Gets a property already knowing that the manifest id is valid.\r\n        std::optional<std::string> GetPropertyByManifestIdInternal(const SQLite::Connection& connection, SQLite::rowid_t manifestId, PackageVersionProperty property) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_3/Interface_1_3.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Microsoft/Schema/1_3/Interface.h\"\r\n#include <AppInstallerSHA256.h>\r\n\r\n#include \"Microsoft/Schema/1_0/ManifestTable.h\"\r\n#include \"Microsoft/Schema/1_3/HashVirtualTable.h\"\r\n#include <winget/ManifestValidation.h>\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_3\r\n{\r\n    Interface::Interface(Utility::NormalizationVersion normVersion) : V1_2::Interface(normVersion)\r\n    {\r\n    }\r\n\r\n    SQLite::Version Interface::GetVersion() const\r\n    {\r\n        return { 1, 3 };\r\n    }\r\n\r\n    void Interface::CreateTables(SQLite::Connection& connection, CreateOptions options)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"createtables_v1_3\");\r\n\r\n        V1_2::Interface::CreateTables(connection, options);\r\n\r\n        V1_0::ManifestTable::AddColumn(connection, { HashVirtualTable::ValueName(), HashVirtualTable::SQLiteType() });\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    SQLite::rowid_t Interface::AddManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"addmanifest_v1_3\");\r\n\r\n        SQLite::rowid_t manifestId = V1_2::Interface::AddManifest(connection, manifest, relativePath);\r\n\r\n        // Set the hash value if provided\r\n        if (!manifest.StreamSha256.empty())\r\n        {\r\n            THROW_HR_IF(E_INVALIDARG, manifest.StreamSha256.size() != Utility::SHA256::HashBufferSizeInBytes);\r\n            V1_0::ManifestTable::UpdateValueIdById<HashVirtualTable>(connection, manifestId, manifest.StreamSha256);\r\n        }\r\n\r\n        savepoint.Commit();\r\n\r\n        return manifestId;\r\n    }\r\n\r\n    std::pair<bool, SQLite::rowid_t> Interface::UpdateManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"updatemanifest_v1_3\");\r\n\r\n        auto [indexModified, manifestId] = V1_2::Interface::UpdateManifest(connection, manifest, relativePath);\r\n\r\n        // Set the hash value if provided\r\n        if (!manifest.StreamSha256.empty())\r\n        {\r\n            THROW_HR_IF(E_INVALIDARG, manifest.StreamSha256.size() != Utility::SHA256::HashBufferSizeInBytes);\r\n\r\n            auto currentHash = std::get<0>(V1_0::ManifestTable::GetIdsById<HashVirtualTable>(connection, manifestId));\r\n\r\n            if (currentHash.size() != Utility::SHA256::HashBufferSizeInBytes ||\r\n                !std::equal(currentHash.begin(), currentHash.end(), manifest.StreamSha256.begin()))\r\n            {\r\n                V1_0::ManifestTable::UpdateValueIdById<HashVirtualTable>(connection, manifestId, manifest.StreamSha256);\r\n                indexModified = true;\r\n            }\r\n        }\r\n\r\n        savepoint.Commit();\r\n\r\n        return { indexModified, manifestId };\r\n    }\r\n\r\n    std::optional<std::string> Interface::GetPropertyByManifestIdInternal(const SQLite::Connection& connection, SQLite::rowid_t manifestId, PackageVersionProperty property) const\r\n    {\r\n        switch (property)\r\n        {\r\n        case AppInstaller::Repository::PackageVersionProperty::ManifestSHA256Hash:\r\n        {\r\n            std::optional<SQLite::blob_t> hash = V1_0::ManifestTable::GetIdById<HashVirtualTable>(connection, manifestId);\r\n            return (!hash || hash->empty()) ? std::optional<std::string>{} : Utility::SHA256::ConvertToString(hash.value());\r\n        }\r\n        default:\r\n            return V1_2::Interface::GetPropertyByManifestIdInternal(connection, manifestId, property);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_4/DependenciesTable.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"DependenciesTable.h\"\r\n#include <winget/SQLiteStatementBuilder.h>\r\n#include \"winget\\DependenciesGraph.h\"\r\n#include \"Microsoft/Schema/1_0/OneToOneTable.h\"\r\n#include \"Microsoft/Schema/1_0/IdTable.h\"\r\n#include \"Microsoft/Schema/1_0/ManifestTable.h\"\r\n#include \"Microsoft/Schema/1_0/VersionTable.h\"\r\n#include \"Microsoft/Schema/1_0/Interface.h\"\r\n#include \"Microsoft/Schema/1_0/ChannelTable.h\"\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_4\r\n{\r\n    using namespace AppInstaller;\r\n    using namespace std::string_view_literals;\r\n    using namespace SQLite::Builder;\r\n    using namespace Schema::V1_0;\r\n    using QCol = SQLite::Builder::QualifiedColumn;\r\n\r\n    static constexpr std::string_view s_DependenciesTable_Table_Name = \"dependencies\"sv;\r\n    static constexpr std::string_view s_DependenciesTable_Index_Name = \"dependencies_pkindex\"sv;\r\n    static constexpr std::string_view s_DependenciesTable_Manifest_Column_Name = \"manifest\"sv;\r\n    static constexpr std::string_view s_DependenciesTable_MinVersion_Column_Name = \"min_version\"sv;\r\n    static constexpr std::string_view s_DependenciesTable_PackageId_Column_Name = \"package_id\";\r\n\r\n    namespace\r\n    {\r\n        struct DependencyTableRow \r\n        {\r\n            SQLite::rowid_t m_packageRowId;\r\n            SQLite::rowid_t m_manifestRowId;\r\n\r\n            // Ideally this should be version row id, the version string is more needed than row id,\r\n            // this prevents converting back and forth between version row id and version string.\r\n            std::optional<Utility::NormalizedString> m_version; \r\n\r\n            bool operator <(const DependencyTableRow& rhs) const\r\n            {\r\n                auto lhsVersion = m_version.has_value() ? m_version.value() : \"\";\r\n                auto rhsVersion = rhs.m_version.has_value() ? rhs.m_version.value() : \"\";\r\n                return std::tie(m_packageRowId, m_manifestRowId, lhsVersion) < std::tie(rhs.m_packageRowId, rhs.m_manifestRowId, rhsVersion);\r\n            }\r\n        };\r\n\r\n        void ThrowOnMissingPackageNodes(std::vector<Manifest::Dependency>& missingPackageNodes)\r\n        {\r\n            if (!missingPackageNodes.empty())\r\n            {\r\n                std::string missingPackages{ missingPackageNodes.begin()->Id()};\r\n                std::for_each(\r\n                    missingPackageNodes.begin() + 1,\r\n                    missingPackageNodes.end(),\r\n                    [&](auto& dep) { missingPackages.append(\", \" + dep.Id()); });\r\n                THROW_HR_MSG(APPINSTALLER_CLI_ERROR_MISSING_PACKAGE, \"Missing packages: %hs\", missingPackages.c_str());\r\n            }\r\n        }\r\n\r\n        std::set<DependencyTableRow> GetAndLinkDependencies(\r\n            SQLite::Connection& connection,\r\n            const Manifest::Manifest& manifest,\r\n            SQLite::rowid_t manifestRowId,\r\n            Manifest::DependencyType dependencyType)\r\n        {\r\n            std::set<DependencyTableRow>  dependencies;\r\n            std::vector<Manifest::Dependency> missingPackageNodes;\r\n\r\n            for (const auto& installer : manifest.Installers)\r\n            {\r\n                installer.Dependencies.ApplyToType(dependencyType, [&](Manifest::Dependency dependency)\r\n                {\r\n                    auto packageRowId = IdTable::SelectIdByValue(connection, dependency.Id(), true);\r\n                    std::optional<Utility::NormalizedString> version;\r\n\r\n                    if (!packageRowId.has_value())\r\n                    {\r\n                        missingPackageNodes.emplace_back(dependency);\r\n                        return;\r\n                    }\r\n\r\n                    if (dependency.MinVersion.has_value())\r\n                    {\r\n                        version = dependency.MinVersion.value().ToString();\r\n                    }\r\n\r\n                    dependencies.emplace(DependencyTableRow{ packageRowId.value(), manifestRowId, version });\r\n                });\r\n            }\r\n\r\n            ThrowOnMissingPackageNodes(missingPackageNodes);\r\n\r\n            return dependencies;\r\n        }\r\n\r\n        bool RemoveDependenciesByRowIds(SQLite::Connection& connection, std::vector<DependencyTableRow> dependencyTableRows)\r\n        {\r\n            using namespace SQLite::Builder;\r\n            bool tableUpdated = false;\r\n            if (dependencyTableRows.empty())\r\n            {\r\n                return tableUpdated;\r\n            }\r\n            SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, std::string{ s_DependenciesTable_Table_Name } + \"remove_dependencies_by_rowid\");\r\n\r\n            SQLite::Builder::StatementBuilder builder;\r\n            builder\r\n                .DeleteFrom(s_DependenciesTable_Table_Name)\r\n                .Where(s_DependenciesTable_PackageId_Column_Name).Equals(Unbound)\r\n                .And(s_DependenciesTable_Manifest_Column_Name).Equals(Unbound);\r\n\r\n            \r\n            SQLite::Statement deleteStmt = builder.Prepare(connection);\r\n            for (auto row : dependencyTableRows)\r\n            {\r\n                deleteStmt.Reset();\r\n                deleteStmt.Bind(1, row.m_packageRowId);\r\n                deleteStmt.Bind(2, row.m_manifestRowId);\r\n                deleteStmt.Execute();\r\n                tableUpdated = true;\r\n            }\r\n\r\n            savepoint.Commit();\r\n            return tableUpdated;\r\n        }\r\n\r\n        bool InsertManifestDependencies(\r\n            SQLite::Connection& connection,\r\n            std::set<DependencyTableRow>& dependenciesTableRows)\r\n        {\r\n            using namespace SQLite::Builder;\r\n            using namespace Schema::V1_0;\r\n            bool tableUpdated = false;\r\n\r\n            StatementBuilder insertBuilder;\r\n            insertBuilder.InsertInto(s_DependenciesTable_Table_Name)\r\n                .Columns({ s_DependenciesTable_Manifest_Column_Name, s_DependenciesTable_MinVersion_Column_Name, s_DependenciesTable_PackageId_Column_Name })\r\n                .Values(Unbound, Unbound, Unbound);\r\n            SQLite::Statement insert = insertBuilder.Prepare(connection);\r\n\r\n            for (const auto& dep : dependenciesTableRows)\r\n            {\r\n                insert.Reset();\r\n                insert.Bind(1, dep.m_manifestRowId);\r\n\r\n                if (dep.m_version.has_value())\r\n                {\r\n                    insert.Bind(2, VersionTable::EnsureExists(connection, dep.m_version.value()));\r\n                }\r\n                else\r\n                {\r\n                    insert.Bind(2, nullptr);\r\n                }\r\n                \r\n                insert.Bind(3, dep.m_packageRowId);\r\n\r\n                insert.Execute();\r\n                tableUpdated = true;\r\n            }\r\n\r\n            return tableUpdated;\r\n        }\r\n    }\r\n\r\n    bool DependenciesTable::Exists(const SQLite::Connection& connection)\r\n    {\r\n        using namespace SQLite;\r\n\r\n        Builder::StatementBuilder builder;\r\n        builder.Select(Builder::RowCount).From(Builder::Schema::MainTable).\r\n            Where(Builder::Schema::TypeColumn).Equals(Builder::Schema::Type_Table).And(Builder::Schema::NameColumn).Equals(s_DependenciesTable_Table_Name);\r\n\r\n        Statement statement = builder.Prepare(connection);\r\n        THROW_HR_IF(E_UNEXPECTED, !statement.Step());\r\n        return statement.GetColumn<int64_t>(0) != 0;\r\n    }\r\n\r\n    std::string_view DependenciesTable::TableName()\r\n    {\r\n        return s_DependenciesTable_Table_Name;\r\n    }\r\n\r\n    void DependenciesTable::Create(SQLite::Connection& connection)\r\n    {\r\n        using namespace SQLite::Builder;\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"createDependencyTable_v1_4\");\r\n        constexpr std::string_view dependencyIndexByVersionId = \"dependencies_version_id_index\";\r\n        constexpr std::string_view dependencyIndexByPackageId = \"dependencies_package_id_index\";\r\n\r\n        StatementBuilder createTableBuilder;\r\n        createTableBuilder.CreateTable(TableName()).BeginColumns();\r\n        createTableBuilder.Column(IntegerPrimaryKey());\r\n\r\n        std::array<DependenciesTableColumnInfo, 2> notNullableDependenciesColumns\r\n        {\r\n            DependenciesTableColumnInfo{ s_DependenciesTable_Manifest_Column_Name },\r\n            DependenciesTableColumnInfo{ s_DependenciesTable_PackageId_Column_Name }\r\n        };\r\n\r\n        std::array<DependenciesTableColumnInfo, 1> nullableDependenciesColumns\r\n        {\r\n            DependenciesTableColumnInfo{ s_DependenciesTable_MinVersion_Column_Name }\r\n        };\r\n\r\n        // Add dependencies column tables not null columns.\r\n        for (const DependenciesTableColumnInfo& value : notNullableDependenciesColumns)\r\n        {\r\n            createTableBuilder.Column(ColumnBuilder(value.Name, Type::RowId).NotNull());\r\n        }\r\n\r\n        // Add dependencies column tables null columns.\r\n        for (const DependenciesTableColumnInfo& value : nullableDependenciesColumns)\r\n        {\r\n            createTableBuilder.Column(ColumnBuilder(value.Name, Type::RowId));\r\n        }\r\n\r\n        createTableBuilder.EndColumns();\r\n\r\n        createTableBuilder.Execute(connection);\r\n\r\n        // Primary key index by package rowid and manifest rowid.\r\n        StatementBuilder createPKIndexBuilder;\r\n        createPKIndexBuilder.CreateUniqueIndex(s_DependenciesTable_Index_Name).On(s_DependenciesTable_Table_Name).Columns({ s_DependenciesTable_Manifest_Column_Name, s_DependenciesTable_PackageId_Column_Name });\r\n        createPKIndexBuilder.Execute(connection);\r\n\r\n        // Index of dependency by Manifest id. \r\n        StatementBuilder createIndexByManifestIdBuilder;\r\n        createIndexByManifestIdBuilder.CreateIndex(dependencyIndexByVersionId).On(s_DependenciesTable_Table_Name).Columns({ s_DependenciesTable_MinVersion_Column_Name });\r\n        createIndexByManifestIdBuilder.Execute(connection);\r\n\r\n        // Index of dependency by package id.\r\n        StatementBuilder createIndexByPackageIdBuilder;\r\n        createIndexByPackageIdBuilder.CreateIndex(dependencyIndexByPackageId).On(s_DependenciesTable_Table_Name).Columns({ s_DependenciesTable_PackageId_Column_Name });\r\n        createIndexByPackageIdBuilder.Execute(connection);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    void DependenciesTable::Drop(SQLite::Connection& connection)\r\n    {\r\n        SQLite::Builder::StatementBuilder dropTableBuilder;\r\n        dropTableBuilder.DropTableIfExists(s_DependenciesTable_Table_Name);\r\n\r\n        dropTableBuilder.Execute(connection);\r\n    }\r\n\r\n    void DependenciesTable::AddDependencies(SQLite::Connection& connection, const Manifest::Manifest& manifest, SQLite::rowid_t manifestRowId)\r\n    {\r\n        if (!Exists(connection))\r\n        {\r\n            return;\r\n        }\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, std::string{ s_DependenciesTable_Table_Name } + \"add_dependencies_v1_4\");\r\n\r\n        auto dependencies = GetAndLinkDependencies(connection, manifest, manifestRowId, Manifest::DependencyType::Package);\r\n        if (!dependencies.size())\r\n        {\r\n            return;\r\n        }\r\n\r\n        InsertManifestDependencies(connection, dependencies);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    bool DependenciesTable::UpdateDependencies(SQLite::Connection& connection, const Manifest::Manifest& manifest, SQLite::rowid_t manifestRowId)\r\n    {\r\n        if (!Exists(connection))\r\n        {\r\n            return false;\r\n        }\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, std::string{ s_DependenciesTable_Table_Name } + \"update_dependencies_v1_4\");\r\n\r\n        const auto dependencies = GetAndLinkDependencies(connection, manifest, manifestRowId, Manifest::DependencyType::Package);\r\n        auto existingDependencies = GetDependenciesByManifestRowId(connection, manifestRowId);\r\n\r\n        // Get dependencies to add.\r\n        std::set<DependencyTableRow> toAddDependencies;\r\n        std::copy_if(\r\n            dependencies.begin(),\r\n            dependencies.end(),\r\n            std::inserter(toAddDependencies, toAddDependencies.begin()),\r\n            [&](DependencyTableRow dep)\r\n            {\r\n                Utility::NormalizedString version = dep.m_version.has_value() ? dep.m_version.value() : \"\";\r\n                return existingDependencies.find(std::make_pair(dep.m_packageRowId, version)) == existingDependencies.end();\r\n            }\r\n        );\r\n\r\n        // Get dependencies to remove.\r\n        std::vector<DependencyTableRow> toRemoveDependencies;\r\n        std::for_each(\r\n            existingDependencies.begin(),\r\n            existingDependencies.end(),\r\n            [&](std::pair<SQLite::rowid_t, Utility::NormalizedString> row)\r\n            {\r\n                if (dependencies.find(DependencyTableRow{row.first, manifestRowId, row.second}) == dependencies.end())\r\n                {\r\n                    toRemoveDependencies.emplace_back(DependencyTableRow{ row.first, manifestRowId });\r\n                }\r\n            }\r\n        );\r\n\r\n        bool tableUpdated = RemoveDependenciesByRowIds(connection, toRemoveDependencies);\r\n        tableUpdated = InsertManifestDependencies(connection, toAddDependencies) || tableUpdated;\r\n        savepoint.Commit();\r\n\r\n        return tableUpdated;\r\n    }\r\n\r\n    void DependenciesTable::RemoveDependencies(SQLite::Connection& connection, SQLite::rowid_t manifestRowId)\r\n    {\r\n        if (!Exists(connection))\r\n        {\r\n            return;\r\n        }\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, std::string{ s_DependenciesTable_Table_Name } + \"remove_dependencies_by_manifest_v1_4\");\r\n\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.DeleteFrom(s_DependenciesTable_Table_Name).Where(s_DependenciesTable_Manifest_Column_Name).Equals(manifestRowId);\r\n\r\n        builder.Execute(connection);\r\n        savepoint.Commit();\r\n    }\r\n\r\n    std::vector<std::pair<SQLite::rowid_t, Utility::NormalizedString>> DependenciesTable::GetDependentsById(const SQLite::Connection& connection, Manifest::string_t packageId)\r\n    {\r\n        constexpr std::string_view depTableAlias = \"dep\";\r\n        constexpr std::string_view minVersionAlias = \"minV\";\r\n        constexpr std::string_view packageIdAlias = \"pId\";\r\n\r\n\r\n        StatementBuilder builder;\r\n        // Find all manifest that depend on this package. Use outer join for joining version table as min_version may be NULL.\r\n        // SELECT [dep].[manifest], [dep].[min_version], [pId].[id], [minV].[version] FROM [dependencies] AS [dep] \r\n        // LEFT OUTER JOIN [versions] AS [minV] ON [dep].[min_version] = [minV].[rowid] \r\n        // JOIN [ids] AS [pId] ON [pId].[rowid] = [dep].[package_id] \r\n        // WHERE [pId].[id] = ?\r\n        builder.Select()\r\n            .Column(QCol(depTableAlias, s_DependenciesTable_Manifest_Column_Name))\r\n            .Column(QCol(depTableAlias, s_DependenciesTable_MinVersion_Column_Name))\r\n            .Column(QCol(packageIdAlias, IdTable::ValueName()))\r\n            .Column(QCol(minVersionAlias, VersionTable::ValueName()))\r\n            .From({ s_DependenciesTable_Table_Name }).As(depTableAlias)\r\n            .LeftOuterJoin({ VersionTable::TableName() }).As(minVersionAlias)\r\n            .On(QCol(depTableAlias, s_DependenciesTable_MinVersion_Column_Name), QCol(minVersionAlias, SQLite::RowIDName))\r\n            .Join({ IdTable::TableName() }).As(packageIdAlias)\r\n            .On(QCol(packageIdAlias, SQLite::RowIDName), QCol(depTableAlias, s_DependenciesTable_PackageId_Column_Name))\r\n            .Where(QCol(packageIdAlias, IdTable::ValueName())).Equals(Unbound);\r\n\r\n        SQLite::Statement stmt = builder.Prepare(connection);\r\n        stmt.Bind(1, std::string{ packageId });\r\n\r\n        std::vector<std::pair<SQLite::rowid_t, Utility::NormalizedString>> resultSet;\r\n\r\n        while (stmt.Step())\r\n        {\r\n            Utility::NormalizedString version = \"\";\r\n            if (!stmt.GetColumnIsNull(1))\r\n            {\r\n                // If min_version is not NULL, use the corresponding value from Version table.\r\n                version = stmt.GetColumn<std::string>(3);\r\n            }\r\n            resultSet.emplace_back(\r\n                std::make_pair(stmt.GetColumn<SQLite::rowid_t>(0), std::move(version)));\r\n        }\r\n\r\n        return resultSet;\r\n    }\r\n\r\n    std::set<std::pair<SQLite::rowid_t, Utility::NormalizedString>> DependenciesTable::GetDependenciesByManifestRowId(const SQLite::Connection& connection, SQLite::rowid_t manifestRowId)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n\r\n        constexpr std::string_view depTableAlias = \"dep\";\r\n        constexpr std::string_view minVersionAlias = \"minV\";\r\n\r\n        std::set<std::pair<SQLite::rowid_t, Utility::NormalizedString>> resultSet;\r\n\r\n        // Use Outer join since min_version could have NULL value. \r\n        // SELECT [dep].[package_id], [dep].[min_version], [minV].[version] FROM [dependencies] AS [dep] \r\n        // LEFT OUTER JOIN [versions] AS [minV] ON [minV].[rowid] = [dep].[min_version]\r\n        // WHERE [dep].[manifest] = ?\r\n        builder.Select()\r\n            .Column(QCol(depTableAlias, s_DependenciesTable_PackageId_Column_Name))\r\n            .Column(QCol(depTableAlias, s_DependenciesTable_MinVersion_Column_Name))\r\n            .Column(QCol(minVersionAlias, VersionTable::ValueName()))\r\n            .From({ s_DependenciesTable_Table_Name }).As(depTableAlias)\r\n            .LeftOuterJoin({ VersionTable::TableName() }).As(minVersionAlias)\r\n            .On(QCol(minVersionAlias, SQLite::RowIDName), QCol(depTableAlias, s_DependenciesTable_MinVersion_Column_Name))\r\n            .Where(QCol(depTableAlias, s_DependenciesTable_Manifest_Column_Name)).Equals(Unbound);\r\n\r\n        SQLite::Statement select = builder.Prepare(connection);\r\n\r\n        select.Bind(1, manifestRowId);\r\n        while (select.Step())\r\n        {\r\n            Utility::NormalizedString version = \"\";\r\n            if (!select.GetColumnIsNull(1))\r\n            {\r\n                // If min_version is not NULL, use the corresponding value from Version table.\r\n                version = select.GetColumn<std::string>(2);\r\n            }\r\n            resultSet.emplace(std::make_pair(select.GetColumn<SQLite::rowid_t>(0), std::move(version)));\r\n        }\r\n\r\n        return resultSet;\r\n    }\r\n\r\n    void DependenciesTable::PrepareForPackaging(SQLite::Connection& connection)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"prepareForPacking_V1_4\");\r\n\r\n        StatementBuilder dropIndexBuilder;\r\n        dropIndexBuilder.DropIndex({ s_DependenciesTable_Index_Name });\r\n        dropIndexBuilder.Execute(connection);\r\n\r\n        StatementBuilder dropTableBuilder;\r\n        dropTableBuilder.DropTable({ s_DependenciesTable_Table_Name });\r\n        dropTableBuilder.Execute(connection);\r\n\r\n        savepoint.Commit();\r\n    }\r\n    \r\n    bool DependenciesTable::CheckConsistency(const SQLite::Connection& connection, bool log)\r\n    {\r\n        StatementBuilder builder;\r\n\r\n        if (!Exists(connection))\r\n        {\r\n            return true;\r\n        }\r\n\r\n        builder.Select(QCol(s_DependenciesTable_Table_Name, SQLite::RowIDName))\r\n            .From(s_DependenciesTable_Table_Name)\r\n            .LeftOuterJoin(IdTable::TableName())\r\n            .On(QCol(s_DependenciesTable_Table_Name, s_DependenciesTable_PackageId_Column_Name), QCol(IdTable::TableName(), SQLite::RowIDName))\r\n            .LeftOuterJoin(ManifestTable::TableName())\r\n            .On(QCol(s_DependenciesTable_Table_Name, s_DependenciesTable_Manifest_Column_Name), QCol(ManifestTable::TableName(), SQLite::RowIDName))\r\n            .LeftOuterJoin(VersionTable::TableName())\r\n            .On(QCol(s_DependenciesTable_Table_Name, s_DependenciesTable_MinVersion_Column_Name), QCol(VersionTable::TableName(), SQLite::RowIDName))\r\n            .Where(QCol(ManifestTable::TableName(), SQLite::RowIDName)).IsNull()\r\n            .Or(QCol(VersionTable::TableName(), SQLite::RowIDName)).IsNull().And(QCol(s_DependenciesTable_Table_Name, s_DependenciesTable_MinVersion_Column_Name)).IsNotNull()\r\n            .Or(QCol(IdTable::TableName(), SQLite::RowIDName)).IsNull();\r\n\r\n        SQLite::Statement select = builder.Prepare(connection);\r\n        \r\n        bool result = true;\r\n\r\n        while (select.Step())\r\n        {\r\n            result = false;\r\n\r\n            if (!log)\r\n            {\r\n                break;\r\n            }\r\n\r\n            AICLI_LOG(Repo, Info, << \"  [INVALID] row in [\" << s_DependenciesTable_Table_Name << \"] rowid [\" << select.GetColumn<SQLite::rowid_t>(0) << \"]\");\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    bool DependenciesTable::IsValueReferenced(const SQLite::Connection& connection, std::string_view tableName, SQLite::rowid_t valueRowId)\r\n    {\r\n        if (!Exists(connection))\r\n        {\r\n            return false;\r\n        }\r\n\r\n        StatementBuilder builder;\r\n\r\n        if (tableName != V1_0::VersionTable::TableName())\r\n        {\r\n            return false;\r\n        }\r\n\r\n        std::array<std::string_view, 1> columns = { s_DependenciesTable_MinVersion_Column_Name };\r\n        bool referenced = false;\r\n\r\n        for(auto column: columns)\r\n        {\r\n            builder.Select(SQLite::RowIDName).From(s_DependenciesTable_Table_Name).Where(column).Equals(Unbound).Limit(1);\r\n\r\n            SQLite::Statement select = builder.Prepare(connection);\r\n\r\n            select.Bind(1, valueRowId);\r\n            if (select.Step())\r\n            {\r\n                referenced = true;\r\n                break;\r\n            }\r\n        }\r\n\r\n        return referenced;\r\n    }\r\n\r\n    std::vector<SQLite::rowid_t> DependenciesTable::GetDependenciesMinVersionsRowIdByManifestId(const SQLite::Connection& connection, SQLite::rowid_t manifestRowId)\r\n    {\r\n        if (!Exists(connection))\r\n        {\r\n            return {};\r\n        }\r\n\r\n        StatementBuilder builder;\r\n\r\n        std::vector<SQLite::rowid_t> result;\r\n\r\n        // Find all versions for manifest row.\r\n        // SELECT [min_version] FROM [dependencies]  \r\n        // WHERE [manifest] = ?\r\n        builder.Select()\r\n            .Column(s_DependenciesTable_MinVersion_Column_Name)\r\n            .From({ s_DependenciesTable_Table_Name })\r\n            .Where(s_DependenciesTable_Manifest_Column_Name).Equals(Unbound);\r\n\r\n        auto select = builder.Prepare(connection);\r\n\r\n        select.Bind(1, manifestRowId);\r\n\r\n        while (select.Step())\r\n        {\r\n            if (!select.GetColumnIsNull(0))\r\n            {\r\n                result.emplace_back(select.GetColumn<SQLite::rowid_t>(0));\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<std::pair<SQLite::rowid_t, Utility::NormalizedString>> DependenciesTable::GetAllDependenciesWithMinVersions(const SQLite::Connection& connection)\r\n    {\r\n        if (!Exists(connection))\r\n        {\r\n            return {};\r\n        }\r\n\r\n        std::vector<std::pair<SQLite::rowid_t, Utility::NormalizedString>> result;\r\n\r\n        constexpr std::string_view depTableAlias = \"dep\";\r\n        constexpr std::string_view minVersionAlias = \"minV\";\r\n\r\n        StatementBuilder builder;\r\n\r\n        // SELECT [dep].[package_id], [minV].[version] FROM [dependencies] AS [dep] \r\n        // JOIN [versions] AS [minV] ON [minV].[rowid] = [dep].[min_version]\r\n        builder.Select()\r\n            .Column(QCol(depTableAlias, s_DependenciesTable_PackageId_Column_Name))\r\n            .Column(QCol(minVersionAlias, VersionTable::ValueName()))\r\n            .From({ s_DependenciesTable_Table_Name }).As(depTableAlias)\r\n            .Join({ VersionTable::TableName() }).As(minVersionAlias)\r\n            .On(QCol(minVersionAlias, SQLite::RowIDName), QCol(depTableAlias, s_DependenciesTable_MinVersion_Column_Name));\r\n\r\n        SQLite::Statement select = builder.Prepare(connection);\r\n\r\n        while (select.Step())\r\n        {\r\n            Utility::NormalizedString version = \"\";\r\n            if (!select.GetColumnIsNull(1))\r\n            {\r\n                version = select.GetColumn<std::string>(1);\r\n            }\r\n\r\n            if (!version.empty())\r\n            {\r\n                result.emplace_back(std::make_pair(select.GetColumn<SQLite::rowid_t>(0), version));\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_4/DependenciesTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"pch.h\"\n#include <winget/SQLiteWrapper.h>\n#include <winget/SQLiteStatementBuilder.h>\n#include <winget/Manifest.h>\n\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_4\n{\n    using namespace AppInstaller;\n\n    struct DependenciesTableColumnInfo\n    {\n        std::string_view Name;\n    };\n\n    struct DependenciesTable\n    {\n        // Get the table name.\n        static std::string_view TableName();\n\n        // Creates the table with named indices.\n        static void Create(SQLite::Connection& connection);\r\n\r\n        // Drops the table.\n        static void Drop(SQLite::Connection& connection);\n\n        static bool Exists(const SQLite::Connection& connection);\n\n        // Add the dependencies for the specific manifest.\n        static void AddDependencies(SQLite::Connection& connection, const Manifest::Manifest& manifest, SQLite::rowid_t manifestRowId);\n\n        // update the dependencies for the specific manifest.\n        static bool UpdateDependencies(SQLite::Connection& connection, const Manifest::Manifest& manifest, SQLite::rowid_t manifestRowId);\n\n        // Remove the dependencies by manifest id\n        static void RemoveDependencies(SQLite::Connection& connection, SQLite::rowid_t manifestRowId);\n\n        // Get dependencies the dependencies\n        static std::set<std::pair<SQLite::rowid_t, Utility::NormalizedString>> GetDependenciesByManifestRowId(const SQLite::Connection& connection, SQLite::rowid_t manifestRowId);\n\n        // Get dependencies by package id.\n        static std::vector<std::pair<SQLite::rowid_t, Utility::NormalizedString>> GetDependentsById(const SQLite::Connection& connection, AppInstaller::Manifest::string_t packageId);\n\n        // Check dependencies table consistency.\n        static bool CheckConsistency(const SQLite::Connection& connection, bool log);\n\n        // Checks if the row id is present in the column denoted by the value supplied.\n        static bool IsValueReferenced(const SQLite::Connection& connection, std::string_view valueName, SQLite::rowid_t valueRowId);\n\n        // The dependencies table and corresponding index are dropped.\n        static void PrepareForPackaging(SQLite::Connection& connection);\n\n        // Get all min version values of the given manifest's dependencies, used for VersionTable cleanup when updating or removing a manifest.\n        static std::vector<SQLite::rowid_t> GetDependenciesMinVersionsRowIdByManifestId(const SQLite::Connection& connection, SQLite::rowid_t manifestRowId);\n\n        // Get all dependencies with min versions in the dependencies table, used during consistency check. Returning a list of <PackageRowId, VersionString> pair.\n        static std::vector<std::pair<SQLite::rowid_t, Utility::NormalizedString>> GetAllDependenciesWithMinVersions(const SQLite::Connection& connection);\n    };\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_4/Interface.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"Microsoft/Schema/ISQLiteIndex.h\"\n#include \"Microsoft/Schema/1_3/Interface.h\"\n\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_4\n{\n    // Interface to this schema version exposed through ISQLiteIndex.\n    struct Interface : public V1_3::Interface\n    {\n        Interface(Utility::NormalizationVersion normVersion = Utility::NormalizationVersion::Initial);\n\n        // Version 1.0\n        SQLite::Version GetVersion() const override;\n        void CreateTables(SQLite::Connection& connection, CreateOptions options) override;\n        SQLite::rowid_t AddManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath) override;\n        std::pair<bool, SQLite::rowid_t> UpdateManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath) override;\n        void RemoveManifestById(SQLite::Connection& connection, SQLite::rowid_t manifestId) override;\n        bool CheckConsistency(const SQLite::Connection& connection, bool log) const override;\n        void PrepareForPackaging(SQLite::Connection& connection, bool vacuum) override;\n\n        std::set<std::pair<SQLite::rowid_t, Utility::NormalizedString>> GetDependenciesByManifestRowId(const SQLite::Connection& connection, SQLite::rowid_t manifestRowId) const override;\n        std::vector<std::pair<SQLite::rowid_t, Utility::NormalizedString>> GetDependentsById(const SQLite::Connection& connection, AppInstaller::Manifest::string_t packageId) const override;\n\n        // Version 1.7\n        void DropTables(SQLite::Connection& connection) override;\n\n    protected:\n        bool NotNeeded(const SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, SQLite::rowid_t id) const override;\n\n    private:\n        // Semantic check to validate dependencies with min versions are satisfied.\n        bool ValidateDependenciesWithMinVersions(const SQLite::Connection& connection, bool log) const;\n    };\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_4/Interface_1_4.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Microsoft/Schema/1_4/Interface.h\"\r\n#include \"Microsoft/Schema/1_0/VersionTable.h\"\r\n\r\n#include \"Microsoft/Schema/1_4/DependenciesTable.h\"\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_4\r\n{\r\n    Interface::Interface(Utility::NormalizationVersion normVersion) : V1_3::Interface(normVersion)\r\n    {\r\n    }\r\n\r\n    SQLite::Version Interface::GetVersion() const\r\n    {\r\n        return { 1, 4 };\r\n    }\r\n\r\n    void Interface::CreateTables(SQLite::Connection& connection, CreateOptions options)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"createtables_v1_4\");\r\n\r\n        V1_3::Interface::CreateTables(connection, options);\r\n\r\n        if (WI_IsFlagClear(options, CreateOptions::DisableDependenciesSupport))\r\n        {\r\n            DependenciesTable::Create(connection);\r\n        }\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    SQLite::rowid_t Interface::AddManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"addmanifest_v1_4\");\r\n\r\n        SQLite::rowid_t manifestId = V1_3::Interface::AddManifest(connection, manifest, relativePath);\r\n\r\n        DependenciesTable::AddDependencies(connection, manifest, manifestId);\r\n\r\n        savepoint.Commit();\r\n\r\n        return manifestId;\r\n    }\r\n\r\n    std::pair<bool, SQLite::rowid_t> Interface::UpdateManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"updatemanifest_v1_4\");\r\n\r\n        auto [indexModified, manifestId] = V1_3::Interface::UpdateManifest(connection, manifest, relativePath);\r\n\r\n        bool dependenciesModified = DependenciesTable::UpdateDependencies(connection, manifest, manifestId);\r\n        indexModified = indexModified || dependenciesModified;\r\n\r\n        savepoint.Commit();\r\n\r\n        return { indexModified, manifestId };\r\n     }\r\n\r\n    void Interface::RemoveManifestById(SQLite::Connection& connection, SQLite::rowid_t manifestId)\r\n    {\r\n        // Get all versions that need cleaning from the version table.\r\n        auto minVersions = DependenciesTable::GetDependenciesMinVersionsRowIdByManifestId(connection, manifestId);\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"removemanifest_v1_4\");\r\n\r\n        // Removes dependences for the manifest id.\r\n        DependenciesTable::RemoveDependencies(connection, manifestId);\r\n\r\n        // Removes the manifest.\r\n        V1_3::Interface::RemoveManifestById(connection, manifestId);\r\n\r\n        // Remove the versions that are not needed.\r\n        for (auto minVersion : minVersions)\r\n        {\r\n            if (NotNeeded(connection, Schema::V1_0::VersionTable::TableName(), Schema::V1_0::VersionTable::ValueName(), minVersion))\r\n            {\r\n                Schema::V1_0::VersionTable::DeleteById(connection, minVersion);\r\n            }\r\n        }\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    bool Interface::NotNeeded(const SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, SQLite::rowid_t id) const\r\n    {\r\n        bool result = V1_0::Interface::NotNeeded(connection, tableName, valueName, id);\r\n\r\n        return !DependenciesTable::IsValueReferenced(connection, tableName, id) && result;\r\n    }\r\n\r\n    void Interface::PrepareForPackaging(SQLite::Connection& connection, bool vacuum)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"prepareforpackaging_v1_4\");\r\n\r\n        V1_3::Interface::PrepareForPackaging(connection, false);\r\n\r\n        DependenciesTable::PrepareForPackaging(connection);\r\n\r\n        savepoint.Commit();\r\n\r\n        if (vacuum)\r\n        {\r\n            Vacuum(connection);\r\n        }\r\n    }\r\n\r\n    bool Interface::CheckConsistency(const SQLite::Connection& connection, bool log) const\r\n    {\r\n        bool result = V1_3::Interface::CheckConsistency(connection, log);\r\n\r\n        // If the v1.3 index was consistent, or if full logging of inconsistency was requested, check the v1.4 data.\r\n        if (result || log)\r\n        {\r\n            result = DependenciesTable::CheckConsistency(connection, log) && result;\r\n        }\r\n\r\n        if (result || log)\r\n        {\r\n            result = ValidateDependenciesWithMinVersions(connection, log) && result;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::set<std::pair<SQLite::rowid_t, Utility::NormalizedString>> Interface::GetDependenciesByManifestRowId(const SQLite::Connection& connection, SQLite::rowid_t manifestRowId) const\r\n    {\r\n        return DependenciesTable::GetDependenciesByManifestRowId(connection, manifestRowId);\r\n    }\r\n\r\n    std::vector<std::pair<SQLite::rowid_t, Utility::NormalizedString>> Interface::GetDependentsById(const SQLite::Connection& connection, AppInstaller::Manifest::string_t packageId) const\r\n    {\r\n        return DependenciesTable::GetDependentsById(connection, packageId);\r\n    }\r\n\r\n    void Interface::DropTables(SQLite::Connection& connection)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"drop_tables_v1_4\");\r\n\r\n        V1_2::Interface::DropTables(connection);\r\n\r\n        DependenciesTable::Drop(connection);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    bool Interface::ValidateDependenciesWithMinVersions(const SQLite::Connection& connection, bool log) const\r\n    {\r\n        try\r\n        {\r\n            bool result = true;\r\n            // A map to store already checked dependency package latest versions.\r\n            std::map<SQLite::rowid_t, Utility::Version> checkedVersions;\r\n\r\n            auto dependencies = DependenciesTable::GetAllDependenciesWithMinVersions(connection);\r\n            for (auto const& dependency : dependencies)\r\n            {\r\n                // If the dependency package has not been checked yet, add to the map.\r\n                if (checkedVersions.find(dependency.first) == checkedVersions.end())\r\n                {\r\n                    auto versionKeys = GetVersionKeysById(connection, dependency.first);\r\n                    THROW_HR_IF(E_UNEXPECTED, versionKeys.empty());\r\n                    checkedVersions.emplace(dependency.first, versionKeys[0].VersionAndChannel.GetVersion());\r\n                }\r\n\r\n                // If the latest version is less than min version required, fail the validation.\r\n                if (checkedVersions[dependency.first] < Utility::Version{ dependency.second })\r\n                {\r\n                    AICLI_LOG(Repo, Error, << \"Dependency with min version not satisfied. Dependency package row id: \" << dependency.first << \" min version: \" << dependency.second);\r\n                    result = false;\r\n\r\n                    if (!log)\r\n                    {\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n        catch (...)\r\n        {\r\n            AICLI_LOG(Repo, Error, << \"ValidateDependenciesWithMinVersions() encountered internal error. Returning false.\");\r\n            return false;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_5/ArpVersionVirtualTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteStatementBuilder.h>\r\n#include \"Microsoft/Schema/1_0/VersionTable.h\"\r\n#include \"Microsoft/Schema/1_0/VirtualTableBase.h\"\r\n#include <string_view>\r\n\r\nusing namespace std::string_view_literals;\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_5\r\n{\r\n    // A virtual table used to add Arp min version to ManifestTable, the values are stored in VersionTable.\r\n    struct ArpMinVersionVirtualTable : public V1_0::VirtualTableBase\r\n    {\r\n        // The id type\r\n        using id_t = V1_0::VersionTable::id_t;\r\n\r\n        // The value type\r\n        using value_t = V1_0::VersionTable::value_t;\r\n\r\n        // The name of the table.\r\n        static constexpr std::string_view TableName()\r\n        {\r\n            return V1_0::VersionTable::TableName();\r\n        }\r\n\r\n        // The value name of the column.\r\n        static constexpr std::string_view ValueName()\r\n        {\r\n            return V1_0::VersionTable::ValueName();\r\n        }\r\n\r\n        // The value name of the manifest table column.\r\n        static constexpr std::string_view ManifestColumnName()\r\n        {\r\n            return \"arp_min_version\"sv;\r\n        }\r\n    };\r\n\r\n    // A virtual table used to add Arp max version to ManifestTable, the values are stored in VersionTable.\r\n    struct ArpMaxVersionVirtualTable : public V1_0::VirtualTableBase\r\n    {\r\n        // The id type\r\n        using id_t = V1_0::VersionTable::id_t;\r\n\r\n        // The value type\r\n        using value_t = V1_0::VersionTable::value_t;\r\n\r\n        // The name of the table.\r\n        static constexpr std::string_view TableName()\r\n        {\r\n            return V1_0::VersionTable::TableName();\r\n        }\r\n\r\n        // The value name of the column.\r\n        static constexpr std::string_view ValueName()\r\n        {\r\n            return V1_0::VersionTable::ValueName();\r\n        }\r\n\r\n        // The value name of the manifest table column.\r\n        static constexpr std::string_view ManifestColumnName()\r\n        {\r\n            return \"arp_max_version\"sv;\r\n        }\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_5/Interface.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"Microsoft/Schema/ISQLiteIndex.h\"\n#include \"Microsoft/Schema/1_4/Interface.h\"\n\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_5\n{\n    // Interface to this schema version exposed through ISQLiteIndex.\n    struct Interface : public V1_4::Interface\n    {\n        Interface(Utility::NormalizationVersion normVersion = Utility::NormalizationVersion::Initial);\n\n        // Version 1.0\n        SQLite::Version GetVersion() const override;\n        void CreateTables(SQLite::Connection& connection, CreateOptions options) override;\n        SQLite::rowid_t AddManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath) override;\n        std::pair<bool, SQLite::rowid_t> UpdateManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath) override;\n        void RemoveManifestById(SQLite::Connection& connection, SQLite::rowid_t manifestId) override;\n        bool CheckConsistency(const SQLite::Connection& connection, bool log) const override;\n\n    protected:\n\n        bool NotNeeded(const SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, SQLite::rowid_t id) const override;\n\n        // Gets a property already knowing that the manifest id is valid.\n        std::optional<std::string> GetPropertyByManifestIdInternal(const SQLite::Connection& connection, SQLite::rowid_t manifestId, PackageVersionProperty property) const override;\n\n    private:\r\n        // Gets the ARP version ranges for the given package identifier.\r\n        std::vector<Utility::VersionRange> GetArpVersionRanges(const SQLite::Connection& connection, SQLite::rowid_t packageIdentifier) const;\r\n\n        // Semantic check to validate all arp version ranges within the index\n        bool ValidateArpVersionConsistency(const SQLite::Connection& connection, bool log) const;\n    };\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_5/Interface_1_5.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Microsoft/Schema/1_5/Interface.h\"\r\n#include \"Microsoft/Schema/1_5/ArpVersionVirtualTable.h\"\r\n#include \"Microsoft/Schema/1_0/ManifestTable.h\"\r\n#include \"Microsoft/Schema/1_0/IdTable.h\"\r\n#include \"Microsoft/Schema/1_0/VersionTable.h\"\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_5\r\n{\r\n    Interface::Interface(Utility::NormalizationVersion normVersion) : V1_4::Interface(normVersion)\r\n    {\r\n    }\r\n\r\n    SQLite::Version Interface::GetVersion() const\r\n    {\r\n        return { 1, 5 };\r\n    }\r\n\r\n    void Interface::CreateTables(SQLite::Connection& connection, CreateOptions options)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"createtables_v1_5\");\r\n\r\n        V1_4::Interface::CreateTables(connection, options);\r\n\r\n        V1_0::ManifestTable::AddColumn(connection, { ArpMinVersionVirtualTable::ManifestColumnName(), SQLite::Builder::Type::RowId });\r\n        V1_0::ManifestTable::AddColumn(connection, { ArpMaxVersionVirtualTable::ManifestColumnName(), SQLite::Builder::Type::RowId });\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    SQLite::rowid_t Interface::AddManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"addmanifest_v1_5\");\r\n\r\n        SQLite::rowid_t manifestId = V1_4::Interface::AddManifest(connection, manifest, relativePath);\r\n\r\n        auto arpVersionRange = manifest.GetArpVersionRange();\r\n        Manifest::string_t arpMinVersion, arpMaxVersion;\r\n\r\n        if (!arpVersionRange.IsEmpty())\r\n        {\r\n            // Check to see if adding this version range will create a conflict\r\n            SQLite::rowid_t packageIdentifier = V1_0::ManifestTable::GetIdById<V1_0::IdTable>(connection, manifestId).value();\r\n            std::vector<Utility::VersionRange> ranges = GetArpVersionRanges(connection, packageIdentifier);\r\n            ranges.push_back(arpVersionRange);\r\n\r\n            if (Utility::HasOverlapInVersionRanges(ranges))\r\n            {\r\n                AICLI_LOG(Repo, Error, << \"Overlapped Arp version ranges found for package. All ranges currently in index followed by new range:\\n\" << [&]() {\r\n                        std::stringstream stream;\r\n                        for (const auto& range : ranges)\r\n                        {\r\n                            stream << '[' << range.GetMinVersion().ToString() << \"] - [\" << range.GetMaxVersion().ToString() << \"]\\n\";\r\n                        }\r\n                        return std::move(stream).str();\r\n                    }());\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_ARP_VERSION_VALIDATION_FAILED);\r\n            }\r\n\r\n            arpMinVersion = arpVersionRange.GetMinVersion().ToString();\r\n            arpMaxVersion = arpVersionRange.GetMaxVersion().ToString();\r\n        }\r\n\r\n        SQLite::rowid_t arpMinVersionId = V1_0::VersionTable::EnsureExists(connection, arpMinVersion);\r\n        SQLite::rowid_t arpMaxVersionId = V1_0::VersionTable::EnsureExists(connection, arpMaxVersion);\r\n        V1_0::ManifestTable::UpdateValueIdById<ArpMinVersionVirtualTable>(connection, manifestId, arpMinVersionId);\r\n        V1_0::ManifestTable::UpdateValueIdById<ArpMaxVersionVirtualTable>(connection, manifestId, arpMaxVersionId);\r\n\r\n        savepoint.Commit();\r\n\r\n        return manifestId;\r\n    }\r\n\r\n    std::pair<bool, SQLite::rowid_t> Interface::UpdateManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"updatemanifest_v1_5\");\r\n\r\n        auto [indexModified, manifestId] = V1_4::Interface::UpdateManifest(connection, manifest, relativePath);\r\n\r\n        auto [oldMinVersionId, oldMaxVersionId] =\r\n            V1_0::ManifestTable::GetIdsById<ArpMinVersionVirtualTable, ArpMaxVersionVirtualTable>(connection, manifestId);\r\n\r\n        auto arpVersionRange = manifest.GetArpVersionRange();\r\n        Manifest::string_t arpMinVersion = arpVersionRange.IsEmpty() ? \"\" : arpVersionRange.GetMinVersion().ToString();\r\n        Manifest::string_t arpMaxVersion = arpVersionRange.IsEmpty() ? \"\" : arpVersionRange.GetMaxVersion().ToString();\r\n\r\n        SQLite::rowid_t arpMinVersionId = V1_0::VersionTable::EnsureExists(connection, arpMinVersion);\r\n        SQLite::rowid_t arpMaxVersionId = V1_0::VersionTable::EnsureExists(connection, arpMaxVersion);\r\n\r\n        // For cleaning up the old entries after update if applicable\r\n        bool cleanOldMinVersionId = false;\r\n        bool cleanOldMaxVersionId = false;\r\n\r\n        if (arpMinVersionId != oldMinVersionId)\r\n        {\r\n            V1_0::ManifestTable::UpdateValueIdById<ArpMinVersionVirtualTable>(connection, manifestId, arpMinVersionId);\r\n            cleanOldMinVersionId = true;\r\n            indexModified = true;\r\n        }\r\n\r\n        if (arpMaxVersionId != oldMaxVersionId)\r\n        {\r\n            V1_0::ManifestTable::UpdateValueIdById<ArpMaxVersionVirtualTable>(connection, manifestId, arpMaxVersionId);\r\n            cleanOldMaxVersionId = true;\r\n            indexModified = true;\r\n        }\r\n\r\n        if (!arpVersionRange.IsEmpty())\r\n        {\r\n            // Check to see if the new set of version ranges created a conflict.\r\n            // We could have done this before attempting the update but it would be more complex and SQLite gives us easy rollback.\r\n            SQLite::rowid_t packageIdentifier = V1_0::ManifestTable::GetIdById<V1_0::IdTable>(connection, manifestId).value();\r\n            std::vector<Utility::VersionRange> ranges = GetArpVersionRanges(connection, packageIdentifier);\r\n\r\n            if (Utility::HasOverlapInVersionRanges(ranges))\r\n            {\r\n                AICLI_LOG(Repo, Error, << \"Overlapped Arp version ranges found for package. Ranges that would be present with attempted upgrade:\\n\" << [&]() {\r\n                        std::stringstream stream;\r\n                        for (const auto& range : ranges)\r\n                        {\r\n                            stream << '[' << range.GetMinVersion().ToString() << \"] - [\" << range.GetMaxVersion().ToString() << \"]\\n\";\r\n                        }\r\n                        return std::move(stream).str();\r\n                    }());\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_ARP_VERSION_VALIDATION_FAILED);\r\n            }\r\n        }\r\n\r\n        if (cleanOldMinVersionId && NotNeeded(connection, V1_0::VersionTable::TableName(), V1_0::VersionTable::ValueName(), oldMinVersionId))\r\n        {\r\n            V1_0::VersionTable::DeleteById(connection, oldMinVersionId);\r\n        }\r\n\r\n        if (cleanOldMaxVersionId && oldMaxVersionId != oldMinVersionId && NotNeeded(connection, V1_0::VersionTable::TableName(), V1_0::VersionTable::ValueName(), oldMaxVersionId))\r\n        {\r\n            V1_0::VersionTable::DeleteById(connection, oldMaxVersionId);\r\n        }\r\n\r\n        savepoint.Commit();\r\n\r\n        return { indexModified, manifestId };\r\n     }\r\n\r\n    void Interface::RemoveManifestById(SQLite::Connection& connection, SQLite::rowid_t manifestId)\r\n    {\r\n        // Get the old arp version ids of the values from the manifest table\r\n        auto [arpMinVersionId, arpMaxVersionId] =\r\n            V1_0::ManifestTable::GetIdsById<ArpMinVersionVirtualTable, ArpMaxVersionVirtualTable>(connection, manifestId);\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"RemoveManifestById_v1_5\");\r\n\r\n        // Removes the manifest.\r\n        V1_4::Interface::RemoveManifestById(connection, manifestId);\r\n\r\n        // Remove the versions that are not needed.\r\n        if (NotNeeded(connection, V1_0::VersionTable::TableName(), V1_0::VersionTable::ValueName(), arpMinVersionId))\r\n        {\r\n            V1_0::VersionTable::DeleteById(connection, arpMinVersionId);\r\n        }\r\n\r\n        if (arpMaxVersionId != arpMinVersionId && NotNeeded(connection, V1_0::VersionTable::TableName(), V1_0::VersionTable::ValueName(), arpMaxVersionId))\r\n        {\r\n            V1_0::VersionTable::DeleteById(connection, arpMaxVersionId);\r\n        }\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    bool Interface::NotNeeded(const SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, SQLite::rowid_t id) const\r\n    {\r\n        bool result = V1_4::Interface::NotNeeded(connection, tableName, valueName, id);\r\n\r\n        if (result && tableName == V1_0::VersionTable::TableName())\r\n        {\r\n            if (valueName != V1_0::VersionTable::ValueName())\r\n            {\r\n                result = !V1_0::ManifestTable::IsValueReferenced(connection, V1_0::VersionTable::ValueName(), id) && result;\r\n            }\r\n            if (valueName != ArpMinVersionVirtualTable::ManifestColumnName())\r\n            {\r\n                result = !V1_0::ManifestTable::IsValueReferenced(connection, ArpMinVersionVirtualTable::ManifestColumnName(), id) && result;\r\n            }\r\n            if (valueName != ArpMaxVersionVirtualTable::ManifestColumnName())\r\n            {\r\n                result = !V1_0::ManifestTable::IsValueReferenced(connection, ArpMaxVersionVirtualTable::ManifestColumnName(), id) && result;\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    bool Interface::CheckConsistency(const SQLite::Connection& connection, bool log) const\r\n    {\r\n        bool result = V1_4::Interface::CheckConsistency(connection, log);\r\n\r\n        // If the v1.4 index was consistent, or if full logging of inconsistency was requested, check the v1.5 data.\r\n        if (result || log)\r\n        {\r\n            result = V1_0::ManifestTable::CheckConsistency<ArpMinVersionVirtualTable>(connection, log) && result;\r\n        }\r\n\r\n        if (result || log)\r\n        {\r\n            result = V1_0::ManifestTable::CheckConsistency<ArpMaxVersionVirtualTable>(connection, log) && result;\r\n        }\r\n\r\n        if (result || log)\r\n        {\r\n            result = ValidateArpVersionConsistency(connection, log) && result;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::optional<std::string> Interface::GetPropertyByManifestIdInternal(const SQLite::Connection& connection, SQLite::rowid_t manifestId, PackageVersionProperty property) const\r\n    {\r\n        switch (property)\r\n        {\r\n        case AppInstaller::Repository::PackageVersionProperty::ArpMinVersion:\r\n            return V1_0::ManifestTable::GetValueById<ArpMinVersionVirtualTable>(connection, manifestId);\r\n        case AppInstaller::Repository::PackageVersionProperty::ArpMaxVersion:\r\n            return V1_0::ManifestTable::GetValueById<ArpMaxVersionVirtualTable>(connection, manifestId);\r\n        default:\r\n            return V1_4::Interface::GetPropertyByManifestIdInternal(connection, manifestId, property);\r\n        }\r\n    }\r\n\r\n    std::vector<Utility::VersionRange> Interface::GetArpVersionRanges(const SQLite::Connection& connection, SQLite::rowid_t packageIdentifier) const\r\n    {\r\n        std::vector<Utility::VersionRange> ranges;\r\n        auto versionKeys = GetVersionKeysById(connection, packageIdentifier);\r\n        for (auto const& versionKey : versionKeys)\r\n        {\r\n            auto arpMinVersion = GetPropertyByPrimaryId(connection, versionKey.ManifestId, PackageVersionProperty::ArpMinVersion).value_or(\"\");\r\n            auto arpMaxVersion = GetPropertyByPrimaryId(connection, versionKey.ManifestId, PackageVersionProperty::ArpMaxVersion).value_or(\"\");\r\n\r\n            // Either both empty or both not empty\r\n            THROW_HR_IF(E_UNEXPECTED, arpMinVersion.empty() != arpMaxVersion.empty());\r\n\r\n            if (!arpMinVersion.empty() && !arpMaxVersion.empty())\r\n            {\r\n                ranges.emplace_back(Utility::VersionRange{ Utility::Version{ std::move(arpMinVersion) }, Utility::Version{ std::move(arpMaxVersion) } });\r\n            }\r\n        }\r\n        return ranges;\r\n    }\r\n\r\n    bool Interface::ValidateArpVersionConsistency(const SQLite::Connection& connection, bool log) const\r\n    {\r\n        try\r\n        {\r\n            bool result = true;\r\n\r\n            // Search everything\r\n            SearchRequest request;\r\n            auto searchResult = Search(connection, request);\r\n            for (auto const& match : searchResult.Matches)\r\n            {\r\n                // Get arp version ranges for each package to check\r\n                std::vector<Utility::VersionRange> ranges = GetArpVersionRanges(connection, match.first);\r\n\r\n                // Check overlap\r\n                if (Utility::HasOverlapInVersionRanges(ranges))\r\n                {\r\n                    AICLI_LOG(Repo, Error, << \"Overlapped Arp version ranges found for package. PackageRowId: \" << match.first);\r\n                    result = false;\r\n\r\n                    if (!log)\r\n                    {\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n        catch (...)\r\n        {\r\n            AICLI_LOG(Repo, Error, << \"ValidateArpVersionConsistency() encountered internal error. Returning false.\");\r\n            return false;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_6/Interface.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/ISQLiteIndex.h\"\r\n#include \"Microsoft/Schema/1_5/Interface.h\"\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_6\r\n{\r\n    // Interface to this schema version exposed through ISQLiteIndex.\r\n    struct Interface : public V1_5::Interface\r\n    {\r\n        Interface(Utility::NormalizationVersion normVersion = Utility::NormalizationVersion::Initial);\r\n\r\n        // Version 1.0\r\n        SQLite::Version GetVersion() const override;\r\n        void CreateTables(SQLite::Connection& connection, CreateOptions options) override;\r\n        SQLite::rowid_t AddManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath) override;\r\n        std::pair<bool, SQLite::rowid_t> UpdateManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath) override;\r\n        void RemoveManifestById(SQLite::Connection& connection, SQLite::rowid_t manifestId) override;\r\n        bool CheckConsistency(const SQLite::Connection& connection, bool log) const override;\r\n        std::vector<std::string> GetMultiPropertyByPrimaryId(const SQLite::Connection& connection, SQLite::rowid_t primaryId, PackageVersionMultiProperty property) const override;\r\n\r\n        // Version 1.7\r\n        void DropTables(SQLite::Connection& connection) override;\r\n\r\n    protected:\r\n        std::unique_ptr<V1_0::SearchResultsTable> CreateSearchResultsTable(const SQLite::Connection& connection) const override;\r\n        void PerformQuerySearch(V1_0::SearchResultsTable& resultsTable, const RequestMatch& query) const override;\r\n        ISQLiteIndex::SearchResult SearchInternal(const SQLite::Connection& connection, SearchRequest& request) const;\r\n        void PrepareForPackaging(SQLite::Connection& connection, bool vacuum) override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_6/Interface_1_6.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Microsoft/Schema/1_6/Interface.h\"\r\n#include \"Microsoft/Schema/1_6/UpgradeCodeTable.h\"\r\n#include \"Microsoft/Schema/1_6/SearchResultsTable.h\"\r\n#include \"Microsoft/Schema/1_0/ManifestTable.h\"\r\n#include \"Microsoft/Schema/1_0/VersionTable.h\"\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_6\r\n{\r\n    Interface::Interface(Utility::NormalizationVersion normVersion) : V1_5::Interface(normVersion)\r\n    {\r\n    }\r\n\r\n    SQLite::Version Interface::GetVersion() const\r\n    {\r\n        return { 1, 6 };\r\n    }\r\n\r\n    void Interface::CreateTables(SQLite::Connection& connection, CreateOptions options)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"createtables_v1_6\");\r\n\r\n        V1_5::Interface::CreateTables(connection, options);\r\n\r\n        UpgradeCodeTable::Create(connection, GetOneToManyTableSchema());\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    SQLite::rowid_t Interface::AddManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"addmanifest_v1_6\");\r\n\r\n        SQLite::rowid_t manifestId = V1_5::Interface::AddManifest(connection, manifest, relativePath);\r\n\r\n        // Add the new 1.6 data\r\n        // These system reference strings are all stored with their cases folded so that they can be\r\n        // looked up ordinally; enabling the index to provide efficient searches.\r\n        UpgradeCodeTable::EnsureExistsAndInsert(connection, manifest.GetUpgradeCodes(), manifestId);\r\n\r\n        savepoint.Commit();\r\n\r\n        return manifestId;\r\n    }\r\n\r\n    std::pair<bool, SQLite::rowid_t> Interface::UpdateManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"updatemanifest_v1_6\");\r\n\r\n        auto [indexModified, manifestId] = V1_5::Interface::UpdateManifest(connection, manifest, relativePath);\r\n\r\n        // Update new 1:N tables as necessary\r\n        indexModified = UpgradeCodeTable::UpdateIfNeededByManifestId(connection, manifest.GetUpgradeCodes(), manifestId) || indexModified;\r\n\r\n        savepoint.Commit();\r\n\r\n        return { indexModified, manifestId };\r\n    }\r\n\r\n    void Interface::RemoveManifestById(SQLite::Connection& connection, SQLite::rowid_t manifestId)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"RemoveManifestById_v1_6\");\r\n\r\n        // Removes the manifest.\r\n        V1_5::Interface::RemoveManifestById(connection, manifestId);\r\n\r\n        // Remove all of the new 1:N data that is no longer referenced.\r\n        UpgradeCodeTable::DeleteIfNotNeededByManifestId(connection, manifestId);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    bool Interface::CheckConsistency(const SQLite::Connection& connection, bool log) const\r\n    {\r\n        bool result = V1_5::Interface::CheckConsistency(connection, log);\r\n\r\n        // If the v1.5 index was consistent, or if full logging of inconsistency was requested, check the v1.6 data.\r\n        if (result || log)\r\n        {\r\n            result = UpgradeCodeTable::CheckConsistency(connection, log) && result;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<std::string> Interface::GetMultiPropertyByPrimaryId(const SQLite::Connection& connection, SQLite::rowid_t primaryId, PackageVersionMultiProperty property) const\r\n    {\r\n        switch (property)\r\n        {\r\n        case PackageVersionMultiProperty::UpgradeCode:\r\n            return UpgradeCodeTable::GetValuesByManifestId(connection, primaryId);\r\n        default:\r\n            return V1_5::Interface::GetMultiPropertyByPrimaryId(connection, primaryId, property);\r\n        }\r\n    }\r\n\r\n    void Interface::DropTables(SQLite::Connection& connection)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"drop_tables_v1_6\");\r\n\r\n        V1_4::Interface::DropTables(connection);\r\n\r\n        UpgradeCodeTable::Drop(connection);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    std::unique_ptr<V1_0::SearchResultsTable> Interface::CreateSearchResultsTable(const SQLite::Connection& connection) const\r\n    {\r\n        return std::make_unique<V1_6::SearchResultsTable>(connection);\r\n    }\r\n\r\n    void Interface::PerformQuerySearch(V1_0::SearchResultsTable& resultsTable, const RequestMatch& query) const\r\n    {\r\n        // First, do an exact match search for the folded system reference strings\r\n        // We do this first because it is exact, and likely won't match anything else if it matches this.\r\n        PackageMatchFilter filter(PackageMatchField::UpgradeCode, MatchType::Exact, Utility::FoldCase(query.Value));\r\n        resultsTable.SearchOnField(filter);\r\n\r\n        // Then do the 1.5 search\r\n        V1_5::Interface::PerformQuerySearch(resultsTable, query);\r\n    }\r\n\r\n    ISQLiteIndex::SearchResult Interface::SearchInternal(const SQLite::Connection& connection, SearchRequest& request) const\r\n    {\r\n        // Update any system reference strings to be folded\r\n        auto foldIfNeeded = [](PackageMatchFilter& filter)\r\n        {\r\n            if (filter.Field == PackageMatchField::UpgradeCode && filter.Type == MatchType::Exact)\r\n            {\r\n                filter.Value = Utility::FoldCase(filter.Value);\r\n            }\r\n        };\r\n\r\n        for (auto& inclusion : request.Inclusions)\r\n        {\r\n            foldIfNeeded(inclusion);\r\n        }\r\n\r\n        for (auto& filter : request.Filters)\r\n        {\r\n            foldIfNeeded(filter);\r\n        }\r\n\r\n        return V1_5::Interface::SearchInternal(connection, request);\r\n    }\r\n\r\n    void Interface::PrepareForPackaging(SQLite::Connection& connection, bool vacuum)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"prepareforpackaging_v1_6\");\r\n\r\n        V1_5::Interface::PrepareForPackaging(connection, false);\r\n\r\n        UpgradeCodeTable::PrepareForPackaging(connection, GetOneToManyTableSchema(), true, true);\r\n\r\n        savepoint.Commit();\r\n\r\n        if (vacuum)\r\n        {\r\n            Vacuum(connection);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_6/SearchResultsTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/1_2/SearchResultsTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_6\r\n{\r\n    // Table for holding temporary search results.\r\n    struct SearchResultsTable : public V1_2::SearchResultsTable\r\n    {\r\n        SearchResultsTable(const SQLite::Connection& connection) : V1_2::SearchResultsTable(connection) {}\r\n\r\n        SearchResultsTable(const SearchResultsTable&) = delete;\r\n        SearchResultsTable& operator=(const SearchResultsTable&) = delete;\r\n\r\n        SearchResultsTable(SearchResultsTable&&) = default;\r\n        SearchResultsTable& operator=(SearchResultsTable&&) = default;\r\n\r\n    protected:\r\n        std::vector<int> BuildSearchStatement(\r\n            SQLite::Builder::StatementBuilder& builder,\r\n            PackageMatchField field,\r\n            std::string_view manifestAlias,\r\n            std::string_view valueAlias,\r\n            bool useLike) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_6/SearchResultsTable_1_6.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"SearchResultsTable.h\"\r\n\r\n#include \"Microsoft/Schema/1_0/ManifestTable.h\"\r\n#include \"Microsoft/Schema/1_6/UpgradeCodeTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_6\r\n{\r\n    std::vector<int> SearchResultsTable::BuildSearchStatement(\r\n        SQLite::Builder::StatementBuilder& builder,\r\n        PackageMatchField field,\r\n        std::string_view manifestAlias,\r\n        std::string_view valueAlias,\r\n        bool useLike) const\r\n    {\r\n        switch (field)\r\n        {\r\n        case PackageMatchField::UpgradeCode:\r\n            return V1_0::ManifestTable::BuildSearchStatement<UpgradeCodeTable>(builder, manifestAlias, valueAlias, useLike);\r\n        default:\r\n            return V1_2::SearchResultsTable::BuildSearchStatement(builder, field, manifestAlias, valueAlias, useLike);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_6/UpgradeCodeTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/1_0/OneToManyTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_6\r\n{\r\n    namespace details\r\n    {\r\n        using namespace std::string_view_literals;\r\n\r\n        struct UpgradeCodeTableInfo\r\n        {\r\n            inline static constexpr std::string_view TableName() { return \"upgradecodes\"sv; }\r\n            inline static constexpr std::string_view ValueName() { return \"upgradecode\"sv; }\r\n        };\r\n    }\r\n\r\n    // The table for UpgradeCode.\r\n    using UpgradeCodeTable = V1_0::OneToManyTable<details::UpgradeCodeTableInfo>;\r\n}\r\n\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_7/Interface.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/ISQLiteIndex.h\"\r\n#include \"Microsoft/Schema/1_6/Interface.h\"\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_7\r\n{\r\n    using namespace std::string_view_literals;\r\n\r\n    // Version 1.7\r\n    static constexpr std::string_view s_MetadataValueName_MapDataFolded = \"mapDataFolded\"sv;\r\n    static constexpr char s_MetadataValue_MapDataFolded_Separator = ';';\r\n\r\n    // Interface to this schema version exposed through ISQLiteIndex.\r\n    struct Interface : public V1_6::Interface\r\n    {\r\n        static constexpr std::string_view MapDataFolded_VersionSpecifier = \"1.7\"sv;\r\n\r\n        Interface(Utility::NormalizationVersion normVersion = Utility::NormalizationVersion::Initial);\r\n\r\n        // Version 1.0\r\n        SQLite::Version GetVersion() const override;\r\n        std::vector<std::string> GetMultiPropertyByPrimaryId(const SQLite::Connection& connection, SQLite::rowid_t primaryId, PackageVersionMultiProperty property) const override;\r\n\r\n    protected:\r\n        void PrepareForPackaging(SQLite::Connection& connection, bool vacuum) override;\r\n        V1_0::OneToManyTableSchema GetOneToManyTableSchema() const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/1_7/Interface_1_7.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Microsoft/Schema/1_7/Interface.h\"\r\n#include <winget/SQLiteMetadataTable.h>\r\n#include \"Microsoft/Schema/1_0/CommandsTable.h\"\r\n#include \"Microsoft/Schema/1_0/IdTable.h\"\r\n#include \"Microsoft/Schema/1_0/TagsTable.h\"\r\n#include \"Microsoft/Schema/1_1/PackageFamilyNameTable.h\"\r\n#include \"Microsoft/Schema/1_2/NormalizedPackageNameTable.h\"\r\n#include \"Microsoft/Schema/1_2/NormalizedPackagePublisherTable.h\"\r\n#include \"Microsoft/Schema/1_6/UpgradeCodeTable.h\"\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V1_7\r\n{\r\n    namespace\r\n    {\r\n        bool ShouldFoldPropertyLookup(const SQLite::Connection& connection)\r\n        {\r\n            // Get the metadata indicator that we folded these multi properties.\r\n            // If it contains the value for folding these properties in the 1.7 manner, also fold the incoming manifest\r\n            // to the same value that it would have been folded to so that all manifest entries will have all of these properties.\r\n            std::optional<std::string> mapDataFolded = SQLite::MetadataTable::TryGetNamedValue<std::string>(connection, s_MetadataValueName_MapDataFolded);\r\n\r\n            if (mapDataFolded)\r\n            {\r\n                std::vector<std::string> foldedSplit = Utility::Split(mapDataFolded.value(), s_MetadataValue_MapDataFolded_Separator);\r\n\r\n                for (const std::string& splitValue : foldedSplit)\r\n                {\r\n                    if (splitValue == Interface::MapDataFolded_VersionSpecifier)\r\n                    {\r\n                        return true;\r\n                    }\r\n                }\r\n            }\r\n\r\n            return false;\r\n        }\r\n    }\r\n\r\n    Interface::Interface(Utility::NormalizationVersion normVersion) : V1_6::Interface(normVersion)\r\n    {\r\n    }\r\n\r\n    SQLite::Version Interface::GetVersion() const\r\n    {\r\n        return { 1, 7 };\r\n    }\r\n\r\n    std::vector<std::string> Interface::GetMultiPropertyByPrimaryId(const SQLite::Connection& connection, SQLite::rowid_t primaryId, PackageVersionMultiProperty property) const\r\n    {\r\n        if (property == PackageVersionMultiProperty::PackageFamilyName ||\r\n            property == PackageVersionMultiProperty::Name ||\r\n            property == PackageVersionMultiProperty::Publisher ||\r\n            property == PackageVersionMultiProperty::UpgradeCode)\r\n        {\r\n            if (ShouldFoldPropertyLookup(connection))\r\n            {\r\n                std::optional<SQLite::rowid_t> maximumManifestId = V1_0::OneToManyTableGetMapDataFoldingManifestTargetId(connection, primaryId);\r\n                if (maximumManifestId)\r\n                {\r\n                    primaryId = maximumManifestId.value();\r\n                }\r\n            }\r\n        }\r\n\r\n        return V1_6::Interface::GetMultiPropertyByPrimaryId(connection, primaryId, property);\r\n    }\r\n\r\n    void Interface::PrepareForPackaging(SQLite::Connection& connection, bool vacuum)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"prepareforpackaging_v1_7\");\r\n\r\n        // Remove data that is not particularly interesting per-manifest\r\n        std::array<SQLite::Statement, 6> dataRemovalStatements{\r\n            V1_0::CommandsTable::PrepareMapDataFoldingStatement(connection),\r\n            V1_0::TagsTable::PrepareMapDataFoldingStatement(connection),\r\n            V1_1::PackageFamilyNameTable::PrepareMapDataFoldingStatement(connection),\r\n            V1_2::NormalizedPackageNameTable::PrepareMapDataFoldingStatement(connection),\r\n            V1_2::NormalizedPackagePublisherTable::PrepareMapDataFoldingStatement(connection),\r\n            V1_6::UpgradeCodeTable::PrepareMapDataFoldingStatement(connection),\r\n        };\r\n\r\n        std::vector<SQLite::rowid_t> allIdentifiers = V1_0::IdTable::GetAllRowIds(connection);\r\n\r\n        for (SQLite::rowid_t id : allIdentifiers)\r\n        {\r\n            for (SQLite::Statement& statement : dataRemovalStatements)\r\n            {\r\n                statement.Reset();\r\n                statement.Bind(1, id);\r\n\r\n                statement.Execute();\r\n            }\r\n        }\r\n\r\n        SQLite::MetadataTable::SetNamedValue(connection, s_MetadataValueName_MapDataFolded, MapDataFolded_VersionSpecifier);\r\n\r\n        V1_6::Interface::PrepareForPackaging(connection, false);\r\n\r\n        savepoint.Commit();\r\n\r\n        if (vacuum)\r\n        {\r\n            Vacuum(connection);\r\n        }\r\n    }\r\n\r\n    V1_0::OneToManyTableSchema Interface::GetOneToManyTableSchema() const\r\n    {\r\n        return V1_0::OneToManyTableSchema::Version_1_7;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/2_0/CommandsTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/2_0/OneToManyTableWithMap.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V2_0\r\n{\r\n    namespace details\r\n    {\r\n        using namespace std::string_view_literals;\r\n\r\n        struct CommandsTableInfo\r\n        {\r\n            inline static constexpr std::string_view TableName() { return \"commands2\"sv; }\r\n            inline static constexpr std::string_view ValueName() { return \"command\"sv; }\r\n        };\r\n    }\r\n\r\n    using CommandsTable = OneToManyTableWithMap<details::CommandsTableInfo>;\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/2_0/Interface.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/ISQLiteIndex.h\"\r\n#include \"Microsoft/Schema/2_0/SearchResultsTable.h\"\r\n#include \"Microsoft/Schema/2_0/OneToManyTableWithMap.h\"\r\n\r\n#include <memory>\r\n#include <vector>\r\n\r\nusing namespace std::string_view_literals;\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V2_0\r\n{\r\n    // Version 2.0\r\n    static constexpr std::string_view s_MetadataValueName_PackageUpdateTrackingBaseTime = \"updateTrackingBase\"sv;\r\n\r\n    // Interface to this schema version exposed through ISQLiteIndex.\r\n    struct Interface : public ISQLiteIndex\r\n    {\r\n        Interface(Utility::NormalizationVersion normVersion = Utility::NormalizationVersion::Initial);\r\n\r\n        // Version 1.0\r\n        SQLite::Version GetVersion() const override;\r\n        void CreateTables(SQLite::Connection& connection, CreateOptions options) override;\r\n        SQLite::rowid_t AddManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath) override;\r\n        std::pair<bool, SQLite::rowid_t> UpdateManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath) override;\r\n        SQLite::rowid_t RemoveManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest) override;\r\n        void RemoveManifestById(SQLite::Connection& connection, SQLite::rowid_t manifestId) override;\r\n        void PrepareForPackaging(SQLite::Connection& connection) override;\r\n        void PrepareForPackaging(const SQLiteIndexContext& context) override;\r\n        bool CheckConsistency(const SQLite::Connection& connection, bool log) const override;\r\n        SearchResult Search(const SQLite::Connection& connection, const SearchRequest& request) const override;\r\n        std::optional<std::string> GetPropertyByPrimaryId(const SQLite::Connection& connection, SQLite::rowid_t primaryId, PackageVersionProperty property) const override;\r\n        std::vector<std::string> GetMultiPropertyByPrimaryId(const SQLite::Connection& connection, SQLite::rowid_t primaryId, PackageVersionMultiProperty property) const override;\r\n        std::optional<SQLite::rowid_t> GetManifestIdByKey(const SQLite::Connection& connection, SQLite::rowid_t id, std::string_view version, std::string_view channel) const override;\r\n        std::optional<SQLite::rowid_t> GetManifestIdByManifest(const SQLite::Connection& connection, const Manifest::Manifest& manifest) const override;\r\n        std::vector<VersionKey> GetVersionKeysById(const SQLite::Connection& connection, SQLite::rowid_t id) const override;\r\n\r\n        // Version 1.1\r\n        MetadataResult GetMetadataByManifestId(const SQLite::Connection& connection, SQLite::rowid_t manifestId) const override;\r\n        void SetMetadataByManifestId(SQLite::Connection& connection, SQLite::rowid_t manifestId, PackageVersionMetadata metadata, std::string_view value) override;\r\n\r\n        // Version 1.2\r\n        Utility::NormalizedName NormalizeName(std::string_view name, std::string_view publisher) const override;\r\n\r\n        // Version 1.4 Get all the dependencies for a specific manifest.\r\n        std::set<std::pair<SQLite::rowid_t, Utility::NormalizedString>> GetDependenciesByManifestRowId(const SQLite::Connection& connection, SQLite::rowid_t manifestRowId) const override;\r\n        std::vector<std::pair<SQLite::rowid_t, Utility::NormalizedString>> GetDependentsById(const SQLite::Connection& connection, AppInstaller::Manifest::string_t packageId) const override;\r\n\r\n        // Version 1.7\r\n        void DropTables(SQLite::Connection& connection) override;\r\n\r\n        // Version 2.0\r\n        bool MigrateFrom(SQLite::Connection& connection, const ISQLiteIndex* current) override;\r\n        void SetProperty(SQLite::Connection& connection, Property property, const std::string& value) override;\r\n\r\n    protected:\r\n        // Creates the search results table.\r\n        virtual std::unique_ptr<SearchResultsTable> CreateSearchResultsTable(const SQLite::Connection& connection) const;\r\n\r\n        // Executes all relevant searches for the query.\r\n        virtual void PerformQuerySearch(SearchResultsTable& resultsTable, const RequestMatch& query) const;\r\n\r\n        // Gets the one to many table schema to use.\r\n        virtual OneToManyTableSchema GetOneToManyTableSchema() const;\r\n\r\n        // Executes search on a request that can be modified.\r\n        virtual SearchResult SearchInternal(const SQLite::Connection& connection, SearchRequest& request) const;\r\n\r\n        // Executes search on the given request.\r\n        SearchResult BasicSearchInternal(const SQLite::Connection& connection, const SearchRequest& request) const;\r\n\r\n        // Prepares for packaging, optionally vacuuming the database.\r\n        virtual void PrepareForPackaging(const SQLiteIndexContext& context, bool vacuum);\r\n\r\n        // Force the database to shrink the file size.\r\n        // This *must* be done outside of an active transaction.\r\n        void Vacuum(const SQLite::Connection& connection);\r\n\r\n        // If before PrepareForPackaging is called, this should find the internal interface schema version and create the object.\r\n        // If after PrepareForPackaging is called, this should not find the internal interface schema version and allow the code to fall through.\r\n        // requireInternalInterface should be set to true for modifying functions.\r\n        void EnsureInternalInterface(const SQLite::Connection& connection, bool requireInternalInterface = false) const;\r\n\r\n        // Allows derived types to move to a different internal schema version.\r\n        virtual std::unique_ptr<Schema::ISQLiteIndex> CreateInternalInterface() const;\r\n\r\n        // If EnsureInternalInterface has been called.\r\n        mutable bool m_internalInterfaceChecked = false;\r\n\r\n        // Interface to the data before PrepareForPackaging is called.\r\n        mutable std::unique_ptr<Schema::ISQLiteIndex> m_internalInterface;\r\n\r\n        // The name normalization utility\r\n        Utility::NameNormalizer m_normalizer;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/2_0/Interface_2_0.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include <winget/SQLiteMetadataTable.h>\r\n#include \"Microsoft/Schema/2_0/Interface.h\"\r\n\r\n#include \"Microsoft/Schema/2_0/PackagesTable.h\"\r\n\r\n#include \"Microsoft/Schema/2_0/TagsTable.h\"\r\n#include \"Microsoft/Schema/2_0/CommandsTable.h\"\r\n#include \"Microsoft/Schema/2_0/PackageFamilyNameTable.h\"\r\n#include \"Microsoft/Schema/2_0/ProductCodeTable.h\"\r\n#include \"Microsoft/Schema/2_0/NormalizedPackageNameTable.h\"\r\n#include \"Microsoft/Schema/2_0/NormalizedPackagePublisherTable.h\"\r\n#include \"Microsoft/Schema/2_0/UpgradeCodeTable.h\"\r\n\r\n#include \"Microsoft/Schema/2_0/SearchResultsTable.h\"\r\n#include \"Microsoft/Schema/2_0/PackageUpdateTrackingTable.h\"\r\n\r\n#include <winget/PackageVersionDataManifest.h>\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V2_0\r\n{\r\n    namespace anon\r\n    {\r\n        // Folds the values of the fields that are stored folded.\r\n        void FoldPackageMatchFilters(std::vector<PackageMatchFilter>& filters)\r\n        {\r\n            for (auto& filter : filters)\r\n            {\r\n                if ((filter.Field == PackageMatchField::PackageFamilyName || filter.Field == PackageMatchField::ProductCode || filter.Field == PackageMatchField::UpgradeCode) &&\r\n                    filter.Type == MatchType::Exact)\r\n                {\r\n                    filter.Value = Utility::FoldCase(filter.Value);\r\n                }\r\n            }\r\n        }\r\n\r\n        // Update NormalizedNameAndPublisher with normalization and folding\r\n        // Returns true if the normalized name contains normalization field of fieldsToInclude\r\n        bool UpdateNormalizedNameAndPublisher(\r\n            PackageMatchFilter& filter,\r\n            const Utility::NameNormalizer& normalizer,\r\n            Utility::NormalizationField fieldsToInclude)\r\n        {\r\n            Utility::NormalizedName normalized = normalizer.Normalize(Utility::FoldCase(filter.Value), Utility::FoldCase(filter.Additional.value()));\r\n            filter.Value = normalized.GetNormalizedName(fieldsToInclude);\r\n            filter.Additional = normalized.Publisher();\r\n            return WI_AreAllFlagsSet(normalized.GetNormalizedFields(), fieldsToInclude);\r\n        }\r\n\r\n        bool UpdatePackageMatchFilters(\r\n            std::vector<PackageMatchFilter>& filters,\r\n            const Utility::NameNormalizer& normalizer,\r\n            Utility::NormalizationField normalizedNameFieldsToFilter = Utility::NormalizationField::None)\r\n        {\r\n            bool normalizedNameFieldsFound = false;\r\n            for (auto itr = filters.begin(); itr != filters.end();)\r\n            {\r\n                if (itr->Field == PackageMatchField::NormalizedNameAndPublisher && itr->Type == MatchType::Exact)\r\n                {\r\n                    if (!UpdateNormalizedNameAndPublisher(*itr, normalizer, normalizedNameFieldsToFilter))\r\n                    {\r\n                        // If not matched, this package match filter will be removed.\r\n                        // For example, if caller is trying to search with arch info only, values without arch will be removed from search.\r\n                        itr = filters.erase(itr);\r\n                        continue;\r\n                    }\r\n\r\n                    normalizedNameFieldsFound = true;\r\n                }\r\n\r\n                ++itr;\r\n            }\r\n\r\n            return normalizedNameFieldsFound;\r\n        }\r\n    }\r\n\r\n    Interface::Interface(Utility::NormalizationVersion normVersion) : m_normalizer(normVersion)\r\n    {\r\n    }\r\n\r\n    SQLite::Version Interface::GetVersion() const\r\n    {\r\n        return { 2, 0 };\r\n    }\r\n\r\n    void Interface::CreateTables(SQLite::Connection& connection, CreateOptions options)\r\n    {\r\n        m_internalInterface = CreateInternalInterface();\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"createtables_v2_0\");\r\n\r\n        // We only create the internal tables at this point, the actual 2.0 tables are created in PrepareForPackaging\r\n        m_internalInterface->CreateTables(connection, options);\r\n\r\n        savepoint.Commit();\r\n\r\n        m_internalInterfaceChecked = true;\r\n    }\r\n\r\n    SQLite::rowid_t Interface::AddManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath)\r\n    {\r\n        EnsureInternalInterface(connection, true);\r\n        SQLite::rowid_t manifestId = m_internalInterface->AddManifest(connection, manifest, relativePath);\r\n        PackageUpdateTrackingTable::Update(connection, m_internalInterface.get(), m_internalInterface->GetPropertyByPrimaryId(connection, manifestId, PackageVersionProperty::Id).value());\r\n        return manifestId;\r\n    }\r\n\r\n    std::pair<bool, SQLite::rowid_t> Interface::UpdateManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath)\r\n    {\r\n        EnsureInternalInterface(connection, true);\r\n        std::pair<bool, SQLite::rowid_t> result = m_internalInterface->UpdateManifest(connection, manifest, relativePath);\r\n        if (result.first)\r\n        {\r\n            PackageUpdateTrackingTable::Update(connection, m_internalInterface.get(), m_internalInterface->GetPropertyByPrimaryId(connection, result.second, PackageVersionProperty::Id).value());\r\n        }\r\n        return result;\r\n    }\r\n\r\n    SQLite::rowid_t Interface::RemoveManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest)\r\n    {\r\n        EnsureInternalInterface(connection, true);\r\n        std::optional<SQLite::rowid_t> result = m_internalInterface->GetManifestIdByManifest(connection, manifest);\r\n\r\n        // If the manifest doesn't actually exist, fail the remove.\r\n        THROW_HR_IF(E_NOT_SET, !result);\r\n\r\n        SQLite::rowid_t manifestId = result.value();\r\n        RemoveManifestById(connection, manifestId);\r\n\r\n        return manifestId;\r\n    }\r\n\r\n    void Interface::RemoveManifestById(SQLite::Connection& connection, SQLite::rowid_t manifestId)\r\n    {\r\n        EnsureInternalInterface(connection, true);\r\n        std::optional<std::string> identifier = m_internalInterface->GetPropertyByPrimaryId(connection, manifestId, PackageVersionProperty::Id);\r\n        m_internalInterface->RemoveManifestById(connection, manifestId);\r\n        if (identifier)\r\n        {\r\n            PackageUpdateTrackingTable::Update(connection, m_internalInterface.get(), identifier.value());\r\n        }\r\n    }\r\n\r\n    void Interface::PrepareForPackaging(SQLite::Connection&)\r\n    {\r\n        // We implement the context version\r\n        THROW_HR(E_NOTIMPL);\r\n    }\r\n\r\n    void Interface::PrepareForPackaging(const SQLiteIndexContext& context)\r\n    {\r\n        EnsureInternalInterface(context.Connection, true);\r\n        PrepareForPackaging(context, true);\r\n    }\r\n\r\n    bool Interface::CheckConsistency(const SQLite::Connection& connection, bool log) const\r\n    {\r\n        EnsureInternalInterface(connection);\r\n\r\n        bool result = true;\r\n\r\n#define AICLI_CHECK_CONSISTENCY(_check_) \\\r\n        if (result || log) \\\r\n        { \\\r\n            result = _check_ && result; \\\r\n        }\r\n\r\n        if (m_internalInterface)\r\n        {\r\n            AICLI_CHECK_CONSISTENCY(m_internalInterface->CheckConsistency(connection, log));\r\n            AICLI_CHECK_CONSISTENCY(PackageUpdateTrackingTable::CheckConsistency(connection, m_internalInterface.get(), log));\r\n\r\n            return result;\r\n        }\r\n\r\n        AICLI_CHECK_CONSISTENCY((PackagesTable::CheckConsistency<\r\n            PackagesTable::IdColumn,\r\n            PackagesTable::NameColumn,\r\n            PackagesTable::MonikerColumn,\r\n            PackagesTable::LatestVersionColumn,\r\n            PackagesTable::ARPMinVersionColumn,\r\n            PackagesTable::ARPMaxVersionColumn>(connection, log)));\r\n\r\n        // Check the 1:N map tables for consistency\r\n        AICLI_CHECK_CONSISTENCY(TagsTable::CheckConsistency(connection, log));\r\n        AICLI_CHECK_CONSISTENCY(CommandsTable::CheckConsistency(connection, log));\r\n\r\n        AICLI_CHECK_CONSISTENCY(PackageFamilyNameTable::CheckConsistency(connection, log));\r\n        AICLI_CHECK_CONSISTENCY(ProductCodeTable::CheckConsistency(connection, log));\r\n        AICLI_CHECK_CONSISTENCY(NormalizedPackageNameTable::CheckConsistency(connection, log));\r\n        AICLI_CHECK_CONSISTENCY(NormalizedPackagePublisherTable::CheckConsistency(connection, log));\r\n        AICLI_CHECK_CONSISTENCY(UpgradeCodeTable::CheckConsistency(connection, log));\r\n\r\n#undef AICLI_CHECK_CONSISTENCY\r\n\r\n        return result;\r\n    }\r\n\r\n    ISQLiteIndex::SearchResult Interface::Search(const SQLite::Connection& connection, const SearchRequest& request) const\r\n    {\r\n        EnsureInternalInterface(connection);\r\n\r\n        if (m_internalInterface)\r\n        {\r\n            return m_internalInterface->Search(connection, request);\r\n        }\r\n\r\n        SearchRequest requestCopy = request;\r\n        return SearchInternal(connection, requestCopy);\r\n    }\r\n\r\n    std::optional<std::string> Interface::GetPropertyByPrimaryId(const SQLite::Connection& connection, SQLite::rowid_t primaryId, PackageVersionProperty property) const\r\n    {\r\n        EnsureInternalInterface(connection);\r\n\r\n        if (m_internalInterface)\r\n        {\r\n            return m_internalInterface->GetPropertyByPrimaryId(connection, primaryId, property);\r\n        }\r\n\r\n        switch (property)\r\n        {\r\n        case PackageVersionProperty::Id:\r\n            return PackagesTable::GetValueById<PackagesTable::IdColumn>(connection, primaryId);\r\n        case PackageVersionProperty::Name:\r\n            return PackagesTable::GetValueById<PackagesTable::NameColumn>(connection, primaryId);\r\n        case PackageVersionProperty::Version:\r\n            return PackagesTable::GetValueById<PackagesTable::LatestVersionColumn>(connection, primaryId);\r\n        case PackageVersionProperty::Channel:\r\n            return \"\";\r\n        case PackageVersionProperty::ManifestSHA256Hash:\r\n        {\r\n            std::optional<SQLite::blob_t> hash = PackagesTable::GetValueById<PackagesTable::HashColumn>(connection, primaryId);\r\n            return (!hash || hash->empty()) ? std::optional<std::string>{} : Utility::SHA256::ConvertToString(hash.value());\r\n        }\r\n        case PackageVersionProperty::ArpMinVersion:\r\n            return PackagesTable::GetValueById<PackagesTable::ARPMinVersionColumn>(connection, primaryId);\r\n        case PackageVersionProperty::ArpMaxVersion:\r\n            return PackagesTable::GetValueById<PackagesTable::ARPMaxVersionColumn>(connection, primaryId);\r\n        case PackageVersionProperty::Moniker:\r\n            return PackagesTable::GetValueById<PackagesTable::MonikerColumn>(connection, primaryId);\r\n        default:\r\n            return {};\r\n        }\r\n    }\r\n\r\n    std::vector<std::string> Interface::GetMultiPropertyByPrimaryId(const SQLite::Connection& connection, SQLite::rowid_t primaryId, PackageVersionMultiProperty property) const\r\n    {\r\n        EnsureInternalInterface(connection);\r\n\r\n        if (m_internalInterface)\r\n        {\r\n            return m_internalInterface->GetMultiPropertyByPrimaryId(connection, primaryId, property);\r\n        }\r\n\r\n        switch (property)\r\n        {\r\n        case PackageVersionMultiProperty::PackageFamilyName:\r\n            return PackageFamilyNameTable::GetValuesByPrimaryId(connection, primaryId);\r\n        case PackageVersionMultiProperty::ProductCode:\r\n            return ProductCodeTable::GetValuesByPrimaryId(connection, primaryId);\r\n            // These values are not right, as they are normalized.  But they are good enough for now and all we have.\r\n        case PackageVersionMultiProperty::Name:\r\n            return NormalizedPackageNameTable::GetValuesByPrimaryId(connection, primaryId);\r\n        case PackageVersionMultiProperty::Publisher:\r\n            return NormalizedPackagePublisherTable::GetValuesByPrimaryId(connection, primaryId);\r\n        case PackageVersionMultiProperty::UpgradeCode:\r\n            return UpgradeCodeTable::GetValuesByPrimaryId(connection, primaryId);\r\n        case PackageVersionMultiProperty::Tag:\r\n            return TagsTable::GetValuesByPrimaryId(connection, primaryId);\r\n        case PackageVersionMultiProperty::Command:\r\n            return CommandsTable::GetValuesByPrimaryId(connection, primaryId);\r\n        default:\r\n            return {};\r\n        }\r\n    }\r\n\r\n    std::optional<SQLite::rowid_t> Interface::GetManifestIdByKey(const SQLite::Connection& connection, SQLite::rowid_t id, std::string_view version, std::string_view channel) const\r\n    {\r\n        EnsureInternalInterface(connection);\r\n\r\n        if (m_internalInterface)\r\n        {\r\n            return m_internalInterface->GetManifestIdByKey(connection, id, version, channel);\r\n        }\r\n\r\n        THROW_HR(E_NOT_VALID_STATE);\r\n    }\r\n\r\n    std::optional<SQLite::rowid_t> Interface::GetManifestIdByManifest(const SQLite::Connection& connection, const Manifest::Manifest& manifest) const\r\n    {\r\n        EnsureInternalInterface(connection);\r\n\r\n        if (m_internalInterface)\r\n        {\r\n            return m_internalInterface->GetManifestIdByManifest(connection, manifest);\r\n        }\r\n\r\n        THROW_HR(E_NOT_VALID_STATE);\r\n    }\r\n\r\n    std::vector<ISQLiteIndex::VersionKey> Interface::GetVersionKeysById(const SQLite::Connection& connection, SQLite::rowid_t id) const\r\n    {\r\n        EnsureInternalInterface(connection);\r\n\r\n        if (m_internalInterface)\r\n        {\r\n            return m_internalInterface->GetVersionKeysById(connection, id);\r\n        }\r\n\r\n        THROW_HR(E_NOT_VALID_STATE);\r\n    }\r\n\r\n    ISQLiteIndex::MetadataResult Interface::GetMetadataByManifestId(const SQLite::Connection&, SQLite::rowid_t) const\r\n    {\r\n        return {};\r\n    }\r\n\r\n    void Interface::SetMetadataByManifestId(SQLite::Connection&, SQLite::rowid_t, PackageVersionMetadata, std::string_view)\r\n    {\r\n    }\r\n\r\n    Utility::NormalizedName Interface::NormalizeName(std::string_view name, std::string_view publisher) const\r\n    {\r\n        if (m_internalInterface)\r\n        {\r\n            return m_internalInterface->NormalizeName(name, publisher);\r\n        }\r\n\r\n        return m_normalizer.Normalize(name, publisher);\r\n    }\r\n\r\n    std::set<std::pair<SQLite::rowid_t, Utility::NormalizedString>> Interface::GetDependenciesByManifestRowId(const SQLite::Connection& connection, SQLite::rowid_t rowid) const\r\n    {\r\n        EnsureInternalInterface(connection);\r\n\r\n        if (m_internalInterface)\r\n        {\r\n            return m_internalInterface->GetDependenciesByManifestRowId(connection, rowid);\r\n        }\r\n\r\n        THROW_HR(E_NOT_VALID_STATE);\r\n    }\r\n\r\n    std::vector<std::pair<SQLite::rowid_t, Utility::NormalizedString>> Interface::GetDependentsById(const SQLite::Connection& connection, AppInstaller::Manifest::string_t id) const\r\n    {\r\n        EnsureInternalInterface(connection);\r\n\r\n        if (m_internalInterface)\r\n        {\r\n            return m_internalInterface->GetDependentsById(connection, id);\r\n        }\r\n\r\n        THROW_HR(E_NOT_VALID_STATE);\r\n    }\r\n\r\n    void Interface::DropTables(SQLite::Connection& connection)\r\n    {\r\n        EnsureInternalInterface(connection);\r\n\r\n        if (m_internalInterface)\r\n        {\r\n            return m_internalInterface->DropTables(connection);\r\n        }\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"drop_tables_v2_0\");\r\n\r\n        PackagesTable::Drop(connection);\r\n\r\n        TagsTable::Drop(connection);\r\n        CommandsTable::Drop(connection);\r\n\r\n        PackageFamilyNameTable::Drop(connection);\r\n        ProductCodeTable::Drop(connection);\r\n        NormalizedPackageNameTable::Drop(connection);\r\n        NormalizedPackagePublisherTable::Drop(connection);\r\n        UpgradeCodeTable::Drop(connection);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    bool Interface::MigrateFrom(SQLite::Connection& connection, const ISQLiteIndex* current)\r\n    {\r\n        THROW_HR_IF_NULL(E_POINTER, current);\r\n\r\n        auto currentVersion = current->GetVersion();\r\n        if (currentVersion.MajorVersion != 1 || currentVersion.MinorVersion != 7)\r\n        {\r\n            return false;\r\n        }\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"migrate_from_v2_0\");\r\n\r\n        // We only need to insert all of the existing packages into the update tracking table.\r\n        PackageUpdateTrackingTable::EnsureExists(connection);\r\n        SearchResult allPackages = current->Search(connection, {});\r\n\r\n        for (const auto& packageMatch : allPackages.Matches)\r\n        {\r\n            std::vector<ISQLiteIndex::VersionKey> versionKeys = current->GetVersionKeysById(connection, packageMatch.first);\r\n            ISQLiteIndex::VersionKey& latestVersionKey = versionKeys[0];\r\n            PackageUpdateTrackingTable::Update(connection, current, current->GetPropertyByPrimaryId(connection, latestVersionKey.ManifestId, PackageVersionProperty::Id).value(), false);\r\n        }\r\n\r\n        savepoint.Commit();\r\n        return true;\r\n    }\r\n\r\n    void Interface::SetProperty(SQLite::Connection& connection, Property property, const std::string& value)\r\n    {\r\n        switch (property)\r\n        {\r\n        case Property::PackageUpdateTrackingBaseTime:\r\n        {\r\n            int64_t baseTime = 0;\r\n            if (value.empty())\r\n            {\r\n                baseTime = Utility::GetCurrentUnixEpoch();\r\n            }\r\n            else\r\n            {\r\n                baseTime = std::stoll(value);\r\n            }\r\n            SQLite::MetadataTable::SetNamedValue(connection, s_MetadataValueName_PackageUpdateTrackingBaseTime, std::to_string(baseTime));\r\n        }\r\n            break;\r\n\r\n        default:\r\n            THROW_WIN32(ERROR_NOT_SUPPORTED);\r\n        }\r\n    }\r\n\r\n    std::unique_ptr<SearchResultsTable> Interface::CreateSearchResultsTable(const SQLite::Connection& connection) const\r\n    {\r\n        return std::make_unique<SearchResultsTable>(connection);\r\n    }\r\n\r\n    void Interface::PerformQuerySearch(SearchResultsTable& resultsTable, const RequestMatch& query) const\r\n    {\r\n        // First, do an exact match search for the folded system reference strings\r\n        // We do this first because it is exact, and likely won't match anything else if it matches this.\r\n        PackageMatchFilter filter(PackageMatchField::Unknown, MatchType::Exact, Utility::FoldCase(query.Value));\r\n\r\n        for (PackageMatchField field : { PackageMatchField::PackageFamilyName, PackageMatchField::ProductCode, PackageMatchField::UpgradeCode })\r\n        {\r\n            filter.Field = field;\r\n            resultsTable.SearchOnField(filter);\r\n        }\r\n\r\n        // Now search on the unfolded value\r\n        filter.Value = query.Value;\r\n\r\n        for (MatchType match : GetDefaultMatchTypeOrder(query.Type))\r\n        {\r\n            filter.Type = match;\r\n\r\n            for (auto field : { PackageMatchField::Id, PackageMatchField::Name, PackageMatchField::Moniker, PackageMatchField::Command, PackageMatchField::Tag })\r\n            {\r\n                filter.Field = field;\r\n                resultsTable.SearchOnField(filter);\r\n            }\r\n        }\r\n    }\r\n\r\n    OneToManyTableSchema Interface::GetOneToManyTableSchema() const\r\n    {\r\n        return OneToManyTableSchema::Version_2_0;\r\n    }\r\n\r\n    ISQLiteIndex::SearchResult Interface::SearchInternal(const SQLite::Connection& connection, SearchRequest& request) const\r\n    {\r\n        anon::FoldPackageMatchFilters(request.Inclusions);\r\n        anon::FoldPackageMatchFilters(request.Filters);\r\n\r\n        if (request.Purpose == SearchPurpose::CorrelationToInstalled)\r\n        {\r\n            // Correlate from available package to installed package\r\n            // For available package to installed package mapping, only one try is needed.\r\n            // For example, if ARP DisplayName contains arch, then the installed package's ARP DisplayName should also include arch.\r\n            auto candidateInclusionsWithArch = request.Inclusions;\r\n            if (anon::UpdatePackageMatchFilters(candidateInclusionsWithArch, m_normalizer, Utility::NormalizationField::Architecture))\r\n            {\r\n                // If DisplayNames contain arch, only use Inclusions with arch for search\r\n                request.Inclusions = candidateInclusionsWithArch;\r\n            }\r\n            else\r\n            {\r\n                // Otherwise, just update the Inclusions with normalization\r\n                anon::UpdatePackageMatchFilters(request.Inclusions, m_normalizer);\r\n            }\r\n\r\n            return BasicSearchInternal(connection, request);\r\n        }\r\n        else if (request.Purpose == SearchPurpose::CorrelationToAvailable)\r\n        {\r\n            // For installed package to available package correlation,\r\n            // try the search with NormalizedName with Arch first, if not found, try with all values.\r\n            // This can be extended in the future for more granular search requests.\r\n            std::vector<SearchRequest> candidateSearches;\r\n            auto candidateSearchWithArch = request;\r\n            if (anon::UpdatePackageMatchFilters(candidateSearchWithArch.Inclusions, m_normalizer, Utility::NormalizationField::Architecture))\r\n            {\r\n                candidateSearches.emplace_back(std::move(candidateSearchWithArch));\r\n            }\r\n            anon::UpdatePackageMatchFilters(request.Inclusions, m_normalizer);\r\n            candidateSearches.emplace_back(request);\r\n\r\n            SearchResult result;\r\n            for (auto& candidateSearch : candidateSearches)\r\n            {\r\n                result = BasicSearchInternal(connection, candidateSearch);\r\n                if (!result.Matches.empty())\r\n                {\r\n                    break;\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n        else\r\n        {\r\n            anon::UpdatePackageMatchFilters(request.Inclusions, m_normalizer);\r\n            anon::UpdatePackageMatchFilters(request.Filters, m_normalizer);\r\n\r\n            return BasicSearchInternal(connection, request);\r\n        }\r\n    }\r\n\r\n    ISQLiteIndex::SearchResult Interface::BasicSearchInternal(const SQLite::Connection& connection, const SearchRequest& request) const\r\n    {\r\n        if (request.IsForEverything())\r\n        {\r\n            std::vector<SQLite::rowid_t> ids = PackagesTable::GetAllRowIds(connection, PackagesTable::IdColumn::Name, request.MaximumResults);\r\n\r\n            SearchResult result;\r\n            for (SQLite::rowid_t id : ids)\r\n            {\r\n                result.Matches.emplace_back(std::make_pair(id, PackageMatchFilter(PackageMatchField::Id, MatchType::Wildcard)));\r\n            }\r\n\r\n            result.Truncated = (request.MaximumResults && PackagesTable::GetCount(connection) > request.MaximumResults);\r\n\r\n            return result;\r\n        }\r\n\r\n        // First phase, create the search results table and populate it with the initial results.\r\n        // If the Query is provided, we search across many fields and put results in together.\r\n        // If Inclusions has fields, we add these to the data.\r\n        // If neither is defined, we take the first filter and use it as the initial results search.\r\n        std::unique_ptr<SearchResultsTable> resultsTable = CreateSearchResultsTable(connection);\r\n        bool inclusionsAttempted = false;\r\n\r\n        if (request.Query)\r\n        {\r\n            // Perform searches across multiple tables to populate the initial results.\r\n            PerformQuerySearch(*resultsTable.get(), request.Query.value());\r\n\r\n            inclusionsAttempted = true;\r\n        }\r\n\r\n        if (!request.Inclusions.empty())\r\n        {\r\n            for (auto include : request.Inclusions)\r\n            {\r\n                for (MatchType match : GetDefaultMatchTypeOrder(include.Type))\r\n                {\r\n                    include.Type = match;\r\n                    resultsTable->SearchOnField(include);\r\n                }\r\n            }\r\n\r\n            inclusionsAttempted = true;\r\n        }\r\n\r\n        size_t filterIndex = 0;\r\n        if (!inclusionsAttempted)\r\n        {\r\n            THROW_HR_IF(E_UNEXPECTED, request.Filters.empty());\r\n\r\n            // Perform search for just the field matching the first filter\r\n            PackageMatchFilter filter = request.Filters[0];\r\n\r\n            for (MatchType match : GetDefaultMatchTypeOrder(filter.Type))\r\n            {\r\n                filter.Type = match;\r\n                resultsTable->SearchOnField(filter);\r\n            }\r\n\r\n            // Skip the filter as we already know everything matches\r\n            filterIndex = 1;\r\n        }\r\n\r\n        // Remove any duplicate manifest entries\r\n        resultsTable->RemoveDuplicatePackageRows();\r\n\r\n        // Second phase, for remaining filters, flag matching search results, then remove unflagged values.\r\n        for (size_t i = filterIndex; i < request.Filters.size(); ++i)\r\n        {\r\n            PackageMatchFilter filter = request.Filters[i];\r\n\r\n            resultsTable->PrepareToFilter();\r\n\r\n            for (MatchType match : GetDefaultMatchTypeOrder(filter.Type))\r\n            {\r\n                filter.Type = match;\r\n                resultsTable->FilterOnField(filter);\r\n            }\r\n\r\n            resultsTable->CompleteFilter();\r\n        }\r\n\r\n        return resultsTable->GetSearchResults(request.MaximumResults);\r\n    }\r\n\r\n    void Interface::PrepareForPackaging(const SQLiteIndexContext& context, bool vacuum)\r\n    {\r\n        SQLite::Connection& connection = context.Connection;\r\n\r\n        // Get the base time from metadata\r\n        int64_t updateBaseTime = 0;\r\n        std::optional<std::string> updateBaseTimeString = SQLite::MetadataTable::TryGetNamedValue<std::string>(connection, s_MetadataValueName_PackageUpdateTrackingBaseTime);\r\n        if (updateBaseTimeString && !updateBaseTimeString->empty())\r\n        {\r\n            updateBaseTime = std::stoll(updateBaseTimeString.value());\r\n        }\r\n\r\n        // Get the output directory or use the file path\r\n        std::filesystem::path baseOutputDirectory;\r\n\r\n        if (context.Data.Contains(Property::IntermediateFileOutputPath))\r\n        {\r\n            baseOutputDirectory = context.Data.Get<Property::IntermediateFileOutputPath>();\r\n        }\r\n        else if (context.Data.Contains(Property::DatabaseFilePath))\r\n        {\r\n            baseOutputDirectory = context.Data.Get<Property::DatabaseFilePath>();\r\n            baseOutputDirectory = baseOutputDirectory.parent_path();\r\n        }\r\n\r\n        THROW_WIN32_IF(ERROR_INVALID_STATE, baseOutputDirectory.empty() || baseOutputDirectory.is_relative());\r\n\r\n        // Output all of the changed package version manifests since the base time to the target location\r\n        for (const auto& packageData : PackageUpdateTrackingTable::GetUpdatesSince(connection, updateBaseTime))\r\n        {\r\n            std::filesystem::path packageDirectory = baseOutputDirectory /\r\n                Manifest::PackageVersionDataManifest::GetRelativeDirectoryPath(packageData.PackageIdentifier, Utility::SHA256::ConvertToString(packageData.Hash));\r\n\r\n            std::filesystem::create_directories(packageDirectory);\r\n\r\n            std::filesystem::path manifestPath = packageDirectory / Manifest::PackageVersionDataManifest::VersionManifestCompressedFileName();\r\n\r\n            AICLI_LOG(Repo, Info, << \"Writing PackageVersionDataManifest for [\" << packageData.PackageIdentifier << \"] to [\" << manifestPath << \"]\");\r\n\r\n            std::ofstream stream(manifestPath, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);\r\n            THROW_LAST_ERROR_IF(stream.fail());\r\n            stream.write(reinterpret_cast<const char*>(packageData.Manifest.data()), packageData.Manifest.size());\r\n            THROW_LAST_ERROR_IF(stream.fail());\r\n            stream.flush();\r\n        }\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"prepareforpackaging_v2_0\");\r\n\r\n        // Create the 2.0 data tables\r\n        PackagesTable::Create<\r\n            PackagesTable::IdColumn,\r\n            PackagesTable::NameColumn,\r\n            PackagesTable::MonikerColumn,\r\n            PackagesTable::LatestVersionColumn,\r\n            PackagesTable::ARPMinVersionColumn,\r\n            PackagesTable::ARPMaxVersionColumn,\r\n            PackagesTable::HashColumn\r\n        >(connection);\r\n\r\n        TagsTable::Create(connection, GetOneToManyTableSchema());\r\n        CommandsTable::Create(connection, GetOneToManyTableSchema());\r\n\r\n        PackageFamilyNameTable::Create(connection);\r\n        ProductCodeTable::Create(connection);\r\n        NormalizedPackageNameTable::Create(connection);\r\n        NormalizedPackagePublisherTable::Create(connection);\r\n        UpgradeCodeTable::Create(connection);\r\n\r\n        // Copy data from 1.7 tables to 2.0 tables\r\n        SearchResult allPackages = m_internalInterface->Search(connection, {});\r\n\r\n        for (const auto& packageMatch : allPackages.Matches)\r\n        {\r\n            std::vector<ISQLiteIndex::VersionKey> versionKeys = m_internalInterface->GetVersionKeysById(connection, packageMatch.first);\r\n            ISQLiteIndex::VersionKey& latestVersionKey = versionKeys[0];\r\n\r\n            std::string packageIdentifier = m_internalInterface->GetPropertyByPrimaryId(connection, latestVersionKey.ManifestId, PackageVersionProperty::Id).value();\r\n\r\n            std::vector<PackagesTable::NameValuePair> packageData{\r\n                { PackagesTable::IdColumn::Name, packageIdentifier },\r\n                { PackagesTable::NameColumn::Name, m_internalInterface->GetPropertyByPrimaryId(connection, latestVersionKey.ManifestId, PackageVersionProperty::Name).value() },\r\n                { PackagesTable::LatestVersionColumn::Name, latestVersionKey.VersionAndChannel.GetVersion().ToString() },\r\n            };\r\n\r\n            auto addIfPresent = [&](std::string_view name, std::optional<std::string>&& value)\r\n                {\r\n                    if (value && !value->empty())\r\n                    {\r\n                        packageData.emplace_back(PackagesTable::NameValuePair{ name, std::move(value).value() });\r\n                    }\r\n                };\r\n\r\n            addIfPresent(PackagesTable::MonikerColumn::Name, m_internalInterface->GetPropertyByPrimaryId(connection, latestVersionKey.ManifestId, PackageVersionProperty::Moniker).value());\r\n            addIfPresent(PackagesTable::ARPMinVersionColumn::Name, m_internalInterface->GetPropertyByPrimaryId(connection, latestVersionKey.ManifestId, PackageVersionProperty::ArpMinVersion).value());\r\n            addIfPresent(PackagesTable::ARPMaxVersionColumn::Name, m_internalInterface->GetPropertyByPrimaryId(connection, latestVersionKey.ManifestId, PackageVersionProperty::ArpMaxVersion).value());\r\n\r\n            SQLite::rowid_t packageId = PackagesTable::Insert(connection, packageData);\r\n\r\n            PackagesTable::UpdateValueIdById<PackagesTable::HashColumn>(connection, packageId, PackageUpdateTrackingTable::GetDataHash(connection, packageIdentifier));\r\n\r\n            for (const auto& versionKey : versionKeys)\r\n            {\r\n                TagsTable::EnsureExistsAndInsert(connection, m_internalInterface->GetMultiPropertyByPrimaryId(connection, versionKey.ManifestId, PackageVersionMultiProperty::Tag), packageId);\r\n                CommandsTable::EnsureExistsAndInsert(connection, m_internalInterface->GetMultiPropertyByPrimaryId(connection, versionKey.ManifestId, PackageVersionMultiProperty::Command), packageId);\r\n\r\n                PackageFamilyNameTable::EnsureExists(connection, m_internalInterface->GetMultiPropertyByPrimaryId(connection, versionKey.ManifestId, PackageVersionMultiProperty::PackageFamilyName), packageId);\r\n                ProductCodeTable::EnsureExists(connection, m_internalInterface->GetMultiPropertyByPrimaryId(connection, versionKey.ManifestId, PackageVersionMultiProperty::ProductCode), packageId);\r\n                NormalizedPackageNameTable::EnsureExists(connection, m_internalInterface->GetMultiPropertyByPrimaryId(connection, versionKey.ManifestId, PackageVersionMultiProperty::Name), packageId);\r\n                NormalizedPackagePublisherTable::EnsureExists(connection, m_internalInterface->GetMultiPropertyByPrimaryId(connection, versionKey.ManifestId, PackageVersionMultiProperty::Publisher), packageId);\r\n                UpgradeCodeTable::EnsureExists(connection, m_internalInterface->GetMultiPropertyByPrimaryId(connection, versionKey.ManifestId, PackageVersionMultiProperty::UpgradeCode), packageId);\r\n            }\r\n        }\r\n\r\n        PackagesTable::PrepareForPackaging<\r\n            PackagesTable::IdColumn,\r\n            PackagesTable::NameColumn,\r\n            PackagesTable::MonikerColumn,\r\n            PackagesTable::LatestVersionColumn,\r\n            PackagesTable::ARPMinVersionColumn,\r\n            PackagesTable::ARPMaxVersionColumn,\r\n            PackagesTable::HashColumn\r\n        >(connection);\r\n\r\n        TagsTable::PrepareForPackaging(connection);\r\n        CommandsTable::PrepareForPackaging(connection);\r\n\r\n        PackageUpdateTrackingTable::Drop(connection);\r\n\r\n        // The tables based on SystemReferenceStringTable don't need a prepare currently\r\n\r\n        // Drop 1.7 tables\r\n        m_internalInterface->DropTables(connection);\r\n\r\n        savepoint.Commit();\r\n\r\n        m_internalInterface.reset();\r\n\r\n        if (vacuum)\r\n        {\r\n            Vacuum(connection);\r\n        }\r\n    }\r\n\r\n    void Interface::Vacuum(const SQLite::Connection& connection)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.Vacuum();\r\n        builder.Execute(connection);\r\n    }\r\n\r\n    void Interface::EnsureInternalInterface(const SQLite::Connection& connection, bool requireInternalInterface) const\r\n    {\r\n        if (!m_internalInterfaceChecked)\r\n        {\r\n            if (!PackagesTable::Exists(connection))\r\n            {\r\n                m_internalInterface = CreateInternalInterface();\r\n            }\r\n\r\n            m_internalInterfaceChecked = true;\r\n        }\r\n\r\n        THROW_HR_IF(E_NOT_VALID_STATE, requireInternalInterface && !m_internalInterface);\r\n    }\r\n\r\n    std::unique_ptr<Schema::ISQLiteIndex> Interface::CreateInternalInterface() const\r\n    {\r\n        return CreateISQLiteIndex({ 1, 7 });\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/2_0/NormalizedPackageNameTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/2_0/SystemReferenceStringTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V2_0\r\n{\r\n    namespace details\r\n    {\r\n        using namespace std::string_view_literals;\r\n\r\n        struct NormalizedPackageNameTableInfo\r\n        {\r\n            inline static constexpr std::string_view TableName() { return \"norm_names2\"sv; }\r\n            inline static constexpr std::string_view ValueName() { return \"norm_name\"sv; }\r\n        };\r\n    }\r\n\r\n    // The table for Commands.\r\n    using NormalizedPackageNameTable = SystemReferenceStringTable<details::NormalizedPackageNameTableInfo>;\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/2_0/NormalizedPackagePublisherTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/2_0/SystemReferenceStringTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V2_0\r\n{\r\n    namespace details\r\n    {\r\n        using namespace std::string_view_literals;\r\n\r\n        struct NormalizedPackagePublisherTableInfo\r\n        {\r\n            inline static constexpr std::string_view TableName() { return \"norm_publishers2\"sv; }\r\n            inline static constexpr std::string_view ValueName() { return \"norm_publisher\"sv; }\r\n        };\r\n    }\r\n\r\n    using NormalizedPackagePublisherTable = SystemReferenceStringTable<details::NormalizedPackagePublisherTableInfo>;\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/2_0/OneToManyTableWithMap.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Microsoft/Schema/2_0/OneToManyTableWithMap.h\"\r\n#include \"Microsoft/Schema/2_0/PackagesTable.h\"\r\n#include <winget/SQLiteStatementBuilder.h>\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V2_0\r\n{\r\n    namespace details\r\n    {\r\n        using PrimaryTable = PackagesTable;\r\n\r\n        using namespace std::string_view_literals;\r\n        static constexpr std::string_view s_OneToManyTableWithMap_MapTable_PrimaryName = \"package\"sv;\r\n        static constexpr std::string_view s_OneToManyTableWithMap_MapTable_Suffix = \"_map\"sv;\r\n        static constexpr std::string_view s_OneToManyTableWithMap_MapTable_IndexSuffix = \"_index\"sv;\r\n        static constexpr std::string_view s_OneToManyTableWithMap_PrimaryKeyIndexSuffix = \"_pkindex\"sv;\r\n\r\n        namespace anon\r\n        {\r\n            // Create the mapping table insert statement for multiple use.\r\n            // Bind the rowid of the value to 2.\r\n            SQLite::Statement CreateMappingInsertStatementForPrimaryId(SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, SQLite::rowid_t manifestId)\r\n            {\r\n                SQLite::Builder::StatementBuilder insertMappingBuilder;\r\n                insertMappingBuilder.InsertOrIgnore({ tableName, s_OneToManyTableWithMap_MapTable_Suffix }).\r\n                    Columns({ s_OneToManyTableWithMap_MapTable_PrimaryName, valueName }).Values(manifestId, SQLite::Builder::Unbound);\r\n\r\n                return insertMappingBuilder.Prepare(connection);\r\n            }\r\n\r\n            // Get a collection of the value ids associated with the given primary id.\r\n            std::vector<SQLite::rowid_t> GetValueIdsByPrimaryId(SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, SQLite::rowid_t manifestId)\r\n            {\r\n                std::vector<SQLite::rowid_t> result;\r\n\r\n                SQLite::Builder::StatementBuilder selectMappingBuilder;\r\n                selectMappingBuilder.Select(valueName).From({ tableName, s_OneToManyTableWithMap_MapTable_Suffix }).Where(s_OneToManyTableWithMap_MapTable_PrimaryName).Equals(manifestId);\r\n\r\n                SQLite::Statement selectMappingStatement = selectMappingBuilder.Prepare(connection);\r\n\r\n                while (selectMappingStatement.Step())\r\n                {\r\n                    result.push_back(selectMappingStatement.GetColumn<SQLite::rowid_t>(0));\r\n                }\r\n\r\n                return result;\r\n            }\r\n\r\n            void CreateDataTable(SQLite::Connection& connection, std::string_view tableName, std::string_view valueName)\r\n            {\r\n                using namespace SQLite::Builder;\r\n\r\n                SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, std::string{ tableName } + \"_create_v2_0\");\r\n\r\n                StatementBuilder createTableBuilder;\r\n\r\n                createTableBuilder.CreateTable(tableName).Columns({\r\n                    IntegerPrimaryKey(),\r\n                    ColumnBuilder(valueName, Type::Text).NotNull()\r\n                    });\r\n\r\n                createTableBuilder.Execute(connection);\r\n\r\n                StatementBuilder indexBuilder;\r\n                indexBuilder.CreateUniqueIndex({ tableName, s_OneToManyTableWithMap_PrimaryKeyIndexSuffix }).On(tableName).Columns(valueName);\r\n                indexBuilder.Execute(connection);\r\n\r\n                savepoint.Commit();\r\n            }\r\n\r\n            void DropDataTable(SQLite::Connection& connection, std::string_view tableName)\r\n            {\r\n                SQLite::Builder::StatementBuilder dropTableBuilder;\r\n                dropTableBuilder.DropTable(tableName);\r\n\r\n                dropTableBuilder.Execute(connection);\r\n            }\r\n\r\n            std::optional<SQLite::rowid_t> DataTableSelectIdByValue(const SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, std::string_view value, bool useLike)\r\n            {\r\n                SQLite::Builder::StatementBuilder selectBuilder;\r\n                selectBuilder.Select(SQLite::RowIDName).From(tableName).Where(valueName);\r\n\r\n                if (useLike)\r\n                {\r\n                    selectBuilder.LikeWithEscape(value);\r\n                }\r\n                else\r\n                {\r\n                    selectBuilder.Equals(value);\r\n                }\r\n\r\n                SQLite::Statement select = selectBuilder.Prepare(connection);\r\n\r\n                if (select.Step())\r\n                {\r\n                    return select.GetColumn<SQLite::rowid_t>(0);\r\n                }\r\n                else\r\n                {\r\n                    return {};\r\n                }\r\n            }\r\n\r\n            std::optional<std::string> DataTableSelectValueById(SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, SQLite::rowid_t rowid)\r\n            {\r\n                SQLite::Builder::StatementBuilder selectBuilder;\r\n                selectBuilder.Select(valueName).From(tableName).Where(SQLite::RowIDName).Equals(rowid);\r\n\r\n                SQLite::Statement select = selectBuilder.Prepare(connection);\r\n\r\n                if (select.Step())\r\n                {\r\n                    return select.GetColumn<std::string>(0);\r\n                }\r\n                else\r\n                {\r\n                    return {};\r\n                }\r\n            }\r\n\r\n            SQLite::rowid_t DataTableEnsureExists(SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, std::string_view value, bool overwriteLikeMatch = false)\r\n            {\r\n                auto selectResult = DataTableSelectIdByValue(connection, tableName, valueName, value, overwriteLikeMatch);\r\n                if (selectResult)\r\n                {\r\n                    if (overwriteLikeMatch)\r\n                    {\r\n                        // If the value in the table is not an exact match, overwrite it with the incoming value\r\n                        auto tableValue = DataTableSelectValueById(connection, tableName, valueName, selectResult.value());\r\n                        if (tableValue.value() != value)\r\n                        {\r\n                            SQLite::Builder::StatementBuilder updateBuilder;\r\n                            updateBuilder.Update(tableName).Set().Column(valueName).Equals(value).Where(SQLite::RowIDName).Equals(selectResult);\r\n\r\n                            updateBuilder.Execute(connection);\r\n                        }\r\n                    }\r\n\r\n                    return selectResult.value();\r\n                }\r\n\r\n                SQLite::Builder::StatementBuilder insertBuilder;\r\n                insertBuilder.InsertInto(tableName).Columns(valueName).Values(value);\r\n\r\n                insertBuilder.Execute(connection);\r\n\r\n                return connection.GetLastInsertRowID();\r\n            }\r\n\r\n            void DataTablePrepareForPackaging(SQLite::Connection& connection, std::string_view tableName)\r\n            {\r\n                SQLite::Builder::StatementBuilder dropIndexBuilder;\r\n                dropIndexBuilder.DropIndex({ tableName, s_OneToManyTableWithMap_PrimaryKeyIndexSuffix });\r\n                dropIndexBuilder.Execute(connection);\r\n            }\r\n\r\n            bool DataTableCheckConsistency(const SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, bool log)\r\n            {\r\n                // Build a select statement to find values that contain an embedded null character\r\n                // Such as:\r\n                // Select count(*) from table where instr(value,char(0))>0\r\n                SQLite::Builder::StatementBuilder builder;\r\n                builder.\r\n                    Select({ SQLite::RowIDName, valueName }).\r\n                    From(tableName).\r\n                    WhereValueContainsEmbeddedNullCharacter(valueName);\r\n\r\n                SQLite::Statement select = builder.Prepare(connection);\r\n                bool result = true;\r\n\r\n                while (select.Step())\r\n                {\r\n                    result = false;\r\n\r\n                    if (!log)\r\n                    {\r\n                        break;\r\n                    }\r\n\r\n                    AICLI_LOG(Repo, Info, << \"  [INVALID] value in table [\" << tableName << \"] at row [\" << select.GetColumn<SQLite::rowid_t>(0) << \"] contains an embedded null character and starts with [\" << select.GetColumn<std::string>(1) << \"]\");\r\n                }\r\n\r\n                return result;\r\n            }\r\n        }\r\n\r\n        std::string OneToManyTableWithMapGetMapTableName(std::string_view tableName)\r\n        {\r\n            std::string result(tableName);\r\n            result += s_OneToManyTableWithMap_MapTable_Suffix;\r\n            return result;\r\n        }\r\n\r\n        std::string_view OneToManyTableWithMapGetManifestColumnName()\r\n        {\r\n            return s_OneToManyTableWithMap_MapTable_PrimaryName;\r\n        }\r\n\r\n        void CreateOneToManyTableWithMap(SQLite::Connection& connection, OneToManyTableSchema schemaVersion, std::string_view tableName, std::string_view valueName)\r\n        {\r\n            using namespace SQLite::Builder;\r\n\r\n            SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, std::string{ tableName } + \"_create_v2_0\");\r\n\r\n            // Create the data table as a 1:1\r\n            anon::CreateDataTable(connection, tableName, valueName);\r\n\r\n            switch (schemaVersion)\r\n            {\r\n            case OneToManyTableSchema::Version_2_0:\r\n            {\r\n                // Create the mapping table\r\n                StatementBuilder createMapTableBuilder;\r\n                createMapTableBuilder.CreateTable({ tableName, s_OneToManyTableWithMap_MapTable_Suffix }).Columns({\r\n                    ColumnBuilder(valueName, Type::Int64).NotNull(),\r\n                    ColumnBuilder(s_OneToManyTableWithMap_MapTable_PrimaryName, Type::Int64).NotNull(),\r\n                    PrimaryKeyBuilder({ valueName, s_OneToManyTableWithMap_MapTable_PrimaryName })\r\n                    }).WithoutRowID();\r\n\r\n                createMapTableBuilder.Execute(connection);\r\n            }\r\n                break;\r\n            default:\r\n                THROW_HR(E_UNEXPECTED);\r\n            }\r\n\r\n            StatementBuilder createMapTableIndexBuilder;\r\n            createMapTableIndexBuilder.CreateIndex({ tableName, s_OneToManyTableWithMap_MapTable_Suffix, s_OneToManyTableWithMap_MapTable_IndexSuffix }).\r\n                On({ tableName, s_OneToManyTableWithMap_MapTable_Suffix }).Columns({ s_OneToManyTableWithMap_MapTable_PrimaryName, valueName });\r\n\r\n            createMapTableIndexBuilder.Execute(connection);\r\n\r\n            savepoint.Commit();\r\n        }\r\n\r\n        void DropOneToManyTableWithMap(SQLite::Connection& connection, std::string_view tableName)\r\n        {\r\n            SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, std::string{ tableName } + \"_drop_v2_0\");\r\n\r\n            anon::DropDataTable(connection, tableName);\r\n\r\n            SQLite::Builder::StatementBuilder dropTableBuilder;\r\n            dropTableBuilder.DropTable({ tableName, s_OneToManyTableWithMap_MapTable_Suffix });\r\n\r\n            dropTableBuilder.Execute(connection);\r\n\r\n            savepoint.Commit();\r\n        }\r\n\r\n        std::vector<std::string> OneToManyTableWithMapGetValuesByPrimaryId(\r\n            const SQLite::Connection& connection,\r\n            std::string_view tableName,\r\n            std::string_view valueName,\r\n            SQLite::rowid_t manifestId)\r\n        {\r\n            using QCol = SQLite::Builder::QualifiedColumn;\r\n\r\n            std::vector<std::string> result;\r\n\r\n            SQLite::Builder::StatementBuilder builder;\r\n            builder.Select(QCol(tableName, valueName)).\r\n                From({ tableName, s_OneToManyTableWithMap_MapTable_Suffix }).As(\"map\").Join(tableName).\r\n                On(QCol(\"map\", valueName), QCol(tableName, SQLite::RowIDName)).Where(QCol(\"map\", s_OneToManyTableWithMap_MapTable_PrimaryName)).Equals(manifestId);\r\n\r\n            SQLite::Statement statement = builder.Prepare(connection);\r\n\r\n            while (statement.Step())\r\n            {\r\n                result.emplace_back(statement.GetColumn<std::string>(0));\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        void OneToManyTableWithMapEnsureExistsAndInsert(SQLite::Connection& connection,\r\n            std::string_view tableName, std::string_view valueName,\r\n            const std::vector<std::string>& values, SQLite::rowid_t manifestId)\r\n        {\r\n            SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, std::string{ tableName } + \"_ensureandinsert_v2_0\");\r\n\r\n            SQLite::Statement insertMapping = anon::CreateMappingInsertStatementForPrimaryId(connection, tableName, valueName, manifestId);\r\n\r\n            for (const std::string& value : values)\r\n            {\r\n                // First, ensure that the data exists\r\n                SQLite::rowid_t dataId = anon::DataTableEnsureExists(connection, tableName, valueName, value);\r\n\r\n                // Second, insert into the mapping table\r\n                insertMapping.Reset();\r\n                insertMapping.Bind(2, dataId);\r\n\r\n                insertMapping.Execute();\r\n            }\r\n\r\n            savepoint.Commit();\r\n        }\r\n\r\n        void OneToManyTableWithMapPrepareForPackaging(SQLite::Connection& connection, std::string_view tableName)\r\n        {\r\n            SQLite::Builder::StatementBuilder dropMapTableIndexBuilder;\r\n            dropMapTableIndexBuilder.DropIndex({ tableName, s_OneToManyTableWithMap_MapTable_Suffix, s_OneToManyTableWithMap_MapTable_IndexSuffix });\r\n\r\n            dropMapTableIndexBuilder.Execute(connection);\r\n\r\n            anon::DataTablePrepareForPackaging(connection, tableName);\r\n        }\r\n\r\n        bool OneToManyTableWithMapCheckConsistency(const SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, bool log)\r\n        {\r\n            using QCol = SQLite::Builder::QualifiedColumn;\r\n            constexpr std::string_view s_map = \"map\"sv;\r\n\r\n            bool result = true;\r\n\r\n            {\r\n                // Build a select statement to find map rows containing references to primaries with nonexistent rowids\r\n                // Such as:\r\n                // Select map.rowid, map.primary from tags_map as map left outer join primary on map.primary = primary.rowid where primary.id is null\r\n\r\n                SQLite::Builder::StatementBuilder builder;\r\n                builder.\r\n                    Select({ QCol(s_map, s_OneToManyTableWithMap_MapTable_PrimaryName), QCol(s_map, valueName) }).\r\n                    From({ tableName, s_OneToManyTableWithMap_MapTable_Suffix }).As(s_map).\r\n                    LeftOuterJoin(details::PrimaryTable::TableName()).On(QCol(s_map, s_OneToManyTableWithMap_MapTable_PrimaryName), QCol(details::PrimaryTable::TableName(), SQLite::RowIDName)).\r\n                    Where(QCol(details::PrimaryTable::TableName(), SQLite::RowIDName)).IsNull();\r\n\r\n                SQLite::Statement select = builder.Prepare(connection);\r\n\r\n                while (select.Step())\r\n                {\r\n                    result = false;\r\n\r\n                    if (!log)\r\n                    {\r\n                        break;\r\n                    }\r\n\r\n                    AICLI_LOG(Repo, Info, << \"  [INVALID] \" << tableName << s_OneToManyTableWithMap_MapTable_Suffix << \" [\" << select.GetColumn<SQLite::rowid_t>(0) <<\r\n                        \", \" << select.GetColumn<SQLite::rowid_t>(1) << \"] refers to invalid \" << details::PrimaryTable::TableName());\r\n                }\r\n            }\r\n\r\n            if (!result && !log)\r\n            {\r\n                return result;\r\n            }\r\n\r\n            {\r\n                // Build a select statement to find map rows containing references to 1:1 tables with nonexistent rowids\r\n                // Such as:\r\n                // Select map.rowid, map.tag from tags_map as map left outer join tags on map.tag = tags.rowid where tags.tag is null\r\n                SQLite::Builder::StatementBuilder builder;\r\n                builder.\r\n                    Select({ QCol(s_map, s_OneToManyTableWithMap_MapTable_PrimaryName), QCol(s_map, valueName) }).\r\n                    From({ tableName, s_OneToManyTableWithMap_MapTable_Suffix }).As(s_map).\r\n                    LeftOuterJoin(tableName).On(QCol(s_map, valueName), QCol(tableName, SQLite::RowIDName)).\r\n                    Where(QCol(tableName, valueName)).IsNull();\r\n\r\n                SQLite::Statement select = builder.Prepare(connection);\r\n                bool secondaryResult = true;\r\n\r\n                while (select.Step())\r\n                {\r\n                    secondaryResult = false;\r\n\r\n                    if (!log)\r\n                    {\r\n                        break;\r\n                    }\r\n\r\n                    AICLI_LOG(Repo, Info, << \"  [INVALID] \" << tableName << s_OneToManyTableWithMap_MapTable_Suffix << \" [\" << select.GetColumn<SQLite::rowid_t>(0) <<\r\n                        \", \" << select.GetColumn<SQLite::rowid_t>(1) << \"] refers to invalid \" << tableName);\r\n                }\r\n\r\n                result = result && secondaryResult;\r\n            }\r\n\r\n            if (!result && !log)\r\n            {\r\n                return result;\r\n            }\r\n\r\n            result = anon::DataTableCheckConsistency(connection, tableName, valueName, log) && result;\r\n\r\n            return result;\r\n        }\r\n\r\n        bool OneToManyTableWithMapIsEmpty(SQLite::Connection& connection, std::string_view tableName)\r\n        {\r\n            SQLite::Builder::StatementBuilder countBuilder;\r\n            countBuilder.Select(SQLite::Builder::RowCount).From(tableName);\r\n\r\n            SQLite::Statement countStatement = countBuilder.Prepare(connection);\r\n\r\n            THROW_HR_IF(E_UNEXPECTED, !countStatement.Step());\r\n\r\n            SQLite::Builder::StatementBuilder countMapBuilder;\r\n            countMapBuilder.Select(SQLite::Builder::RowCount).From({ tableName, s_OneToManyTableWithMap_MapTable_Suffix });\r\n\r\n            SQLite::Statement countMapStatement = countMapBuilder.Prepare(connection);\r\n\r\n            THROW_HR_IF(E_UNEXPECTED, !countMapStatement.Step());\r\n\r\n            return ((countStatement.GetColumn<int>(0) == 0) && (countMapStatement.GetColumn<int>(0) == 0));\r\n        }\r\n\r\n        int OneToManyTableWithMapBuildSearchStatement(\r\n            SQLite::Builder::StatementBuilder& builder,\r\n            std::string_view tableName,\r\n            std::string_view valueName,\r\n            std::string_view primaryAlias,\r\n            std::string_view valueAlias,\r\n            bool useLike)\r\n        {\r\n            using QCol = SQLite::Builder::QualifiedColumn;\r\n            constexpr std::string_view s_map = \"map\"sv;\r\n\r\n            // Build a statement like:\r\n            //      SELECT map.package as p, table.value as v from table\r\n            //      join map on table.rowid = map.value\r\n            //      where table.value = <value>\r\n            builder.Select().\r\n                Column(QCol(s_map, s_OneToManyTableWithMap_MapTable_PrimaryName)).As(primaryAlias).\r\n                Column(QCol(tableName, valueName)).As(valueAlias).\r\n                From(tableName).\r\n                Join({ tableName, s_OneToManyTableWithMap_MapTable_Suffix }).As(s_map).On(QCol(tableName, SQLite::RowIDName), QCol(s_map, valueName)).\r\n                Where(QCol(tableName, valueName));\r\n\r\n            int result = -1;\r\n\r\n            if (useLike)\r\n            {\r\n                builder.Like(SQLite::Builder::Unbound);\r\n                result = builder.GetLastBindIndex();\r\n                builder.Escape(SQLite::EscapeCharForLike);\r\n            }\r\n            else\r\n            {\r\n                builder.Equals(SQLite::Builder::Unbound);\r\n                result = builder.GetLastBindIndex();\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/2_0/OneToManyTableWithMap.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteWrapper.h>\r\n#include <winget/SQLiteStatementBuilder.h>\r\n#include <string>\r\n#include <string_view>\r\n#include <vector>\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V2_0\r\n{\r\n    // Allow the different schema version to indicate which they are.\r\n    enum class OneToManyTableSchema\r\n    {\r\n        // Uses a named unique index for data table.\r\n        // Map table has primary key and no rowid.\r\n        // Column order is consistent with primary key order.\r\n        Version_2_0,\r\n    };\r\n\r\n    namespace details\r\n    {\r\n        // Returns the map table name for a given table.\r\n        std::string OneToManyTableGetMapTableName(std::string_view tableName);\r\n\r\n        // Returns the primary column name.\r\n        std::string_view OneToManyTableGetManifestColumnName();\r\n\r\n        // Create the tables.\r\n        void CreateOneToManyTableWithMap(SQLite::Connection& connection, OneToManyTableSchema schemaVersion, std::string_view tableName, std::string_view valueName);\r\n\r\n        // Drops the tables.\r\n        void DropOneToManyTableWithMap(SQLite::Connection& connection, std::string_view tableName);\r\n\r\n        // Gets all values associated with the given primary id.\r\n        std::vector<std::string> OneToManyTableWithMapGetValuesByPrimaryId(\r\n            const SQLite::Connection& connection,\r\n            std::string_view tableName,\r\n            std::string_view valueName,\r\n            SQLite::rowid_t primaryId);\r\n\r\n        // Ensures that the value exists and inserts mapping entries.\r\n        void OneToManyTableWithMapEnsureExistsAndInsert(SQLite::Connection& connection,\r\n            std::string_view tableName, std::string_view valueName, \r\n            const std::vector<std::string>& values, SQLite::rowid_t primaryId);\r\n\r\n        // Removes data that is no longer needed for an index that is to be published.\r\n        void OneToManyTableWithMapPrepareForPackaging(SQLite::Connection& connection, std::string_view tableName);\r\n\r\n        // Checks the consistency of the index to ensure that every referenced row exists.\r\n        // Returns true if index is consistent; false if it is not.\r\n         bool OneToManyTableWithMapCheckConsistency(const SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, bool log);\r\n\r\n        // Determines if the table is empty.\r\n        bool OneToManyTableWithMapIsEmpty(SQLite::Connection& connection, std::string_view tableName);\r\n\r\n        // Builds the search select statement base on the given value.\r\n        // The return value is the bind index of the value to match against.\r\n        int OneToManyTableWithMapBuildSearchStatement(\r\n            SQLite::Builder::StatementBuilder& builder,\r\n            std::string_view tableName,\r\n            std::string_view valueName,\r\n            std::string_view primaryAlias,\r\n            std::string_view valueAlias,\r\n            bool useLike);\r\n    }\r\n\r\n    // A table that represents a value that is 1:N with a primary entry.\r\n    template <typename TableInfo>\r\n    struct OneToManyTableWithMap\r\n    {\r\n        // The name of the table.\r\n        static constexpr std::string_view TableName()\r\n        {\r\n            return TableInfo::TableName();\r\n        }\r\n\r\n        // The value name of the table.\r\n        static constexpr std::string_view ValueName()\r\n        {\r\n            return TableInfo::ValueName();\r\n        }\r\n\r\n        // Creates the table with named indices.\r\n        static void Create(SQLite::Connection& connection, OneToManyTableSchema schemaVersion)\r\n        {\r\n            details::CreateOneToManyTableWithMap(connection, schemaVersion, TableInfo::TableName(), TableInfo::ValueName());\r\n        }\r\n\r\n        // Drops the tables.\r\n        static void Drop(SQLite::Connection& connection)\r\n        {\r\n            details::DropOneToManyTableWithMap(connection, TableInfo::TableName());\r\n        }\r\n\r\n        // Gets all values associated with the given primary id.\r\n        static std::vector<std::string> GetValuesByPrimaryId(const SQLite::Connection& connection, SQLite::rowid_t primaryId)\r\n        {\r\n            return details::OneToManyTableWithMapGetValuesByPrimaryId(connection, TableInfo::TableName(), TableInfo::ValueName(), primaryId);\r\n        }\r\n\r\n        // Ensures that all values exist in the data table, and inserts into the mapping table for the given primary id.\r\n        static void EnsureExistsAndInsert(SQLite::Connection& connection, const std::vector<std::string>& values, SQLite::rowid_t primaryId)\r\n        {\r\n            details::OneToManyTableWithMapEnsureExistsAndInsert(connection, TableInfo::TableName(), TableInfo::ValueName(), values, primaryId);\r\n        }\r\n\r\n        // Removes data that is no longer needed for an index that is to be published.\r\n        // Preserving the primary index will improve the efficiency of finding the values associated with a primary.\r\n        // Preserving the values index will improve searching when it is primarily done by equality.\r\n        static void PrepareForPackaging(SQLite::Connection& connection)\r\n        {\r\n            details::OneToManyTableWithMapPrepareForPackaging(connection, TableInfo::TableName());\r\n        }\r\n\r\n        // Checks the consistency of the index to ensure that every referenced row exists.\r\n        // Returns true if index is consistent; false if it is not.\r\n        static bool CheckConsistency(const SQLite::Connection& connection, bool log)\r\n        {\r\n            return details::OneToManyTableWithMapCheckConsistency(connection, TableInfo::TableName(), TableInfo::ValueName(), log);\r\n        }\r\n\r\n        // Determines if the table is empty.\r\n        static bool IsEmpty(SQLite::Connection& connection)\r\n        {\r\n            return details::OneToManyTableWithMapIsEmpty(connection, TableInfo::TableName());\r\n        }\r\n\r\n        // Builds the search select statement base on the given value.\r\n        // The return value is the bind index of the value to match against.\r\n        static int BuildSearchStatement(SQLite::Builder::StatementBuilder& builder, std::string_view primaryAlias, std::string_view valueAlias, bool useLike)\r\n        {\r\n            return details::OneToManyTableWithMapBuildSearchStatement(builder, TableInfo::TableName(), TableInfo::ValueName(), primaryAlias, valueAlias, useLike);\r\n        }\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/2_0/PackageFamilyNameTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/2_0/SystemReferenceStringTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V2_0\r\n{\r\n    namespace details\r\n    {\r\n        using namespace std::string_view_literals;\r\n\r\n        struct PackageFamilyNameTableInfo\r\n        {\r\n            inline static constexpr std::string_view TableName() { return \"pfns2\"sv; }\r\n            inline static constexpr std::string_view ValueName() { return \"pfn\"sv; }\r\n        };\r\n    }\r\n\r\n    using PackageFamilyNameTable = SystemReferenceStringTable<details::PackageFamilyNameTableInfo>;\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/2_0/PackageUpdateTrackingTable.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"PackageUpdateTrackingTable.h\"\r\n#include <winget/PackageVersionDataManifest.h>\r\n#include <winget/SQLiteStatementBuilder.h>\r\n\r\nusing namespace AppInstaller::SQLite;\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V2_0\r\n{\r\n    using namespace std::string_view_literals;\r\n    static constexpr std::string_view s_PUTT_Table_Name = \"update_tracking\"sv;\r\n    static constexpr std::string_view s_PUTT_WriteTimeIndex_Name = \"update_tracking_write_idx\"sv;\r\n    static constexpr std::string_view s_PUTT_Package = \"package\"sv;\r\n    static constexpr std::string_view s_PUTT_WriteTime = \"write_time\"sv;\r\n    static constexpr std::string_view s_PUTT_Manifest = \"manifest\"sv;\r\n    static constexpr std::string_view s_PUTT_Hash = \"hash\"sv;\r\n\r\n    std::string_view PackageUpdateTrackingTable::TableName()\r\n    {\r\n        return s_PUTT_Table_Name;\r\n    }\r\n\r\n    void PackageUpdateTrackingTable::Create(SQLite::Connection& connection)\r\n    {\r\n        using namespace Builder;\r\n\r\n        StatementBuilder builder;\r\n        builder.CreateTable(s_PUTT_Table_Name).BeginColumns();\r\n\r\n        builder.Column(IntegerPrimaryKey());\r\n        builder.Column(ColumnBuilder(s_PUTT_Package, Type::Text).NotNull());\r\n        builder.Column(ColumnBuilder(s_PUTT_WriteTime, Type::Int64).NotNull());\r\n        builder.Column(ColumnBuilder(s_PUTT_Manifest, Type::Blob).NotNull());\r\n        builder.Column(ColumnBuilder(s_PUTT_Hash, Type::Blob).NotNull());\r\n\r\n        builder.EndColumns();\r\n\r\n        builder.Execute(connection);\r\n\r\n        StatementBuilder indexBuilder;\r\n        indexBuilder.CreateIndex(s_PUTT_WriteTimeIndex_Name).On(s_PUTT_Table_Name).Columns(s_PUTT_WriteTime);\r\n        indexBuilder.Execute(connection);\r\n    }\r\n\r\n    void PackageUpdateTrackingTable::EnsureExists(SQLite::Connection& connection)\r\n    {\r\n        if (!Exists(connection))\r\n        {\r\n            Create(connection);\r\n        }\r\n    }\r\n\r\n    void PackageUpdateTrackingTable::Drop(SQLite::Connection& connection)\r\n    {\r\n        Builder::StatementBuilder dropTableBuilder;\r\n        dropTableBuilder.DropTable(s_PUTT_Table_Name);\r\n\r\n        dropTableBuilder.Execute(connection);\r\n    }\r\n\r\n    bool PackageUpdateTrackingTable::Exists(const SQLite::Connection& connection)\r\n    {\r\n        Builder::StatementBuilder builder;\r\n        builder.Select(Builder::RowCount).From(Builder::Schema::MainTable).\r\n            Where(Builder::Schema::TypeColumn).Equals(Builder::Schema::Type_Table).And(Builder::Schema::NameColumn).Equals(s_PUTT_Table_Name);\r\n\r\n        Statement statement = builder.Prepare(connection);\r\n        THROW_HR_IF(E_UNEXPECTED, !statement.Step());\r\n        return statement.GetColumn<int64_t>(0) != 0;\r\n    }\r\n\r\n    void PackageUpdateTrackingTable::Update(SQLite::Connection& connection, const ISQLiteIndex* internalIndex, const std::string& packageIdentifier, bool ensureTable)\r\n    {\r\n        if (ensureTable)\r\n        {\r\n            EnsureExists(connection);\r\n        }\r\n\r\n        SearchRequest request;\r\n        request.Inclusions.emplace_back(PackageMatchField::Id, MatchType::CaseInsensitive, packageIdentifier);\r\n        auto result = internalIndex->Search(connection, request);\r\n\r\n        if (result.Matches.empty())\r\n        {\r\n            // Remove any existing package update row\r\n            Builder::StatementBuilder deleteBuilder;\r\n            deleteBuilder.DeleteFrom(s_PUTT_Table_Name).Where(s_PUTT_Package).LikeWithEscape(packageIdentifier);\r\n\r\n            deleteBuilder.Execute(connection);\r\n        }\r\n        else\r\n        {\r\n            THROW_HR_IF(E_UNEXPECTED, result.Matches.size() != 1);\r\n\r\n            // Insert or update the package row\r\n            std::vector<ISQLiteIndex::VersionKey> versionKeys = internalIndex->GetVersionKeysById(connection, result.Matches[0].first);\r\n\r\n            Manifest::PackageVersionDataManifest manifest;\r\n\r\n            for (const auto& key : versionKeys)\r\n            {\r\n                Manifest::PackageVersionDataManifest::VersionData versionData{\r\n                    key.VersionAndChannel,\r\n                    internalIndex->GetPropertyByPrimaryId(connection, key.ManifestId, PackageVersionProperty::ArpMinVersion),\r\n                    internalIndex->GetPropertyByPrimaryId(connection, key.ManifestId, PackageVersionProperty::ArpMaxVersion),\r\n                    internalIndex->GetPropertyByPrimaryId(connection, key.ManifestId, PackageVersionProperty::RelativePath),\r\n                    internalIndex->GetPropertyByPrimaryId(connection, key.ManifestId, PackageVersionProperty::ManifestSHA256Hash)\r\n                };\r\n\r\n                manifest.AddVersion(std::move(versionData));\r\n            }\r\n\r\n            std::string manifestString = manifest.Serialize();\r\n\r\n            auto compressor = Manifest::PackageVersionDataManifest::CreateCompressor();\r\n            std::vector<uint8_t> compressedManifest = compressor.Compress(manifestString);\r\n\r\n            Utility::SHA256::HashBuffer manifestHash = Utility::SHA256::ComputeHash(compressedManifest);\r\n            int64_t currentTime = Utility::GetCurrentUnixEpoch();\r\n\r\n            // First attempt to update the row and then insert it if no modification occurred.\r\n            Builder::StatementBuilder updateBuilder;\r\n            updateBuilder.Update(s_PUTT_Table_Name).Set().\r\n                Column(s_PUTT_WriteTime).Equals(currentTime).\r\n                Column(s_PUTT_Manifest).Equals(compressedManifest).\r\n                Column(s_PUTT_Hash).Equals(manifestHash).\r\n                Where(s_PUTT_Package).LikeWithEscape(packageIdentifier);\r\n\r\n            updateBuilder.Execute(connection);\r\n\r\n            if (connection.GetChanges() == 0)\r\n            {\r\n                Builder::StatementBuilder insertBuilder;\r\n                insertBuilder.InsertInto(s_PUTT_Table_Name).\r\n                    Columns({ s_PUTT_Package, s_PUTT_WriteTime, s_PUTT_Manifest, s_PUTT_Hash }).\r\n                    Values(packageIdentifier, currentTime, compressedManifest, manifestHash);\r\n\r\n                insertBuilder.Execute(connection);\r\n            }\r\n        }\r\n    }\r\n\r\n    bool PackageUpdateTrackingTable::CheckConsistency(const SQLite::Connection& connection, ISQLiteIndex* internalIndex, bool log)\r\n    {\r\n        bool result = true;\r\n\r\n        // Ensure that all data in the update table matches the internal index\r\n        for (const PackageData& packageData : GetUpdatesSince(connection, 0))\r\n        {\r\n            auto manifestHash = Utility::SHA256::ComputeHash(packageData.Manifest);\r\n            if (!Utility::SHA256::AreEqual(packageData.Hash, manifestHash))\r\n            {\r\n                if (!log)\r\n                {\r\n                    return false;\r\n                }\r\n\r\n                result = false;\r\n                AICLI_LOG(Repo, Info, << \"  [INVALID] value [\" << s_PUTT_Hash << \"] in table [\" << s_PUTT_Table_Name <<\r\n                    \"] at row [\" << packageData.RowID << \"]; the hash of the manifest value does not match the hash in the row\");\r\n            }\r\n\r\n            SearchRequest request;\r\n            request.Inclusions.emplace_back(PackageMatchField::Id, MatchType::CaseInsensitive, packageData.PackageIdentifier);\r\n\r\n            if (internalIndex->Search(connection, request).Matches.empty())\r\n            {\r\n                if (!log)\r\n                {\r\n                    return false;\r\n                }\r\n\r\n                result = false;\r\n                AICLI_LOG(Repo, Info, << \"  [INVALID] value [\" << s_PUTT_Package << \"] in table [\" << s_PUTT_Table_Name <<\r\n                    \"] at row [\" << packageData.RowID << \"]; the package [\" << packageData.PackageIdentifier << \"] was not found in the internal index\");\r\n            }\r\n        }\r\n\r\n        // Ensure that all packages in the internal index are present in the update table\r\n        Builder::StatementBuilder builder;\r\n        builder.Select(Builder::RowCount).From(s_PUTT_Table_Name).Where(s_PUTT_Package).Like(Builder::Unbound).Escape(EscapeCharForLike);\r\n\r\n        Statement select = builder.Prepare(connection);\r\n\r\n        for (const auto& packageMatch : internalIndex->Search(connection, {}).Matches)\r\n        {\r\n            std::vector<ISQLiteIndex::VersionKey> versionKeys = internalIndex->GetVersionKeysById(connection, packageMatch.first);\r\n            ISQLiteIndex::VersionKey& latestVersionKey = versionKeys[0];\r\n\r\n            std::string packageIdentifier = internalIndex->GetPropertyByPrimaryId(connection, latestVersionKey.ManifestId, PackageVersionProperty::Id).value();\r\n\r\n            select.Reset();\r\n            select.Bind(1, packageIdentifier);\r\n            select.Step();\r\n\r\n            if (select.GetColumn<int64_t>(0) != 1)\r\n            {\r\n                if (!log)\r\n                {\r\n                    return false;\r\n                }\r\n\r\n                result = false;\r\n                AICLI_LOG(Repo, Info, << \"  [INVALID] value [\" << packageIdentifier << \"] in the internal index was not found in [\" << s_PUTT_Table_Name << \"]\");\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<PackageUpdateTrackingTable::PackageData> PackageUpdateTrackingTable::GetUpdatesSince(const SQLite::Connection& connection, int64_t updateBaseTime)\r\n    {\r\n        Builder::StatementBuilder builder;\r\n        builder.Select({ RowIDName, s_PUTT_Package, s_PUTT_WriteTime, s_PUTT_Manifest, s_PUTT_Hash }).\r\n            From(s_PUTT_Table_Name).Where(s_PUTT_WriteTime).IsGreaterThanOrEqualTo(updateBaseTime);\r\n\r\n        Statement select = builder.Prepare(connection);\r\n\r\n        std::vector<PackageData> result;\r\n\r\n        while (select.Step())\r\n        {\r\n            PackageData item;\r\n            item.RowID = select.GetColumn<rowid_t>(0);\r\n            item.PackageIdentifier = select.GetColumn<std::string>(1);\r\n            item.WriteTime = select.GetColumn<int64_t>(2);\r\n            item.Manifest = select.GetColumn<blob_t>(3);\r\n            item.Hash = select.GetColumn<blob_t>(4);\r\n\r\n            result.emplace_back(std::move(item));\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    SQLite::blob_t PackageUpdateTrackingTable::GetDataHash(const SQLite::Connection& connection, const std::string& packageIdentifier)\r\n    {\r\n        Builder::StatementBuilder builder;\r\n        builder.Select(s_PUTT_Hash).From(s_PUTT_Table_Name).Where(s_PUTT_Package).LikeWithEscape(packageIdentifier);\r\n\r\n        Statement select = builder.Prepare(connection);\r\n\r\n        THROW_HR_IF(E_NOT_SET, !select.Step());\r\n\r\n        return select.GetColumn<SQLite::blob_t>(0);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/2_0/PackageUpdateTrackingTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/ISQLiteIndex.h\"\r\n#include <winget/SQLiteWrapper.h>\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V2_0\r\n{\r\n    // Table for tracking the updates to the internal table so that prepare can output\r\n    // only the necessary package manifests.\r\n    struct PackageUpdateTrackingTable\r\n    {\r\n        // Get the table name.\r\n        static std::string_view TableName();\r\n\r\n        // Creates the table.\r\n        static void Create(SQLite::Connection& connection);\r\n\r\n        // Creates the table if it does not exist.\r\n        static void EnsureExists(SQLite::Connection& connection);\r\n\r\n        // Drops the table.\r\n        static void Drop(SQLite::Connection& connection);\r\n\r\n        // Determine if the table currently exists in the database.\r\n        static bool Exists(const SQLite::Connection& connection);\r\n\r\n        // Updates the tracking table for the given package identifier in the internal index.\r\n        static void Update(SQLite::Connection& connection, const ISQLiteIndex* internalIndex, const std::string& packageIdentifier, bool ensureTable = true);\r\n\r\n        // Checks the consistency of the index to ensure that every referenced row exists.\r\n        // Returns true if index is consistent; false if it is not.\r\n        static bool CheckConsistency(const SQLite::Connection& connection, ISQLiteIndex* internalIndex, bool log);\r\n\r\n        // Data on a single row in the table.\r\n        struct PackageData\r\n        {\r\n            SQLite::rowid_t RowID = 0;\r\n            std::string PackageIdentifier;\r\n            int64_t WriteTime = 0;\r\n            SQLite::blob_t Manifest;\r\n            SQLite::blob_t Hash;\r\n        };\r\n\r\n        // Gets the data on updates that have been written since the given base time.\r\n        static std::vector<PackageData> GetUpdatesSince(const SQLite::Connection& connection, int64_t updateBaseTime);\r\n\r\n        // Gets the data hash for the given package identifier.\r\n        static SQLite::blob_t GetDataHash(const SQLite::Connection& connection, const std::string& packageIdentifier);\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/2_0/PackagesTable.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"PackagesTable.h\"\r\n#include <winget/SQLiteStatementBuilder.h>\r\n#include \"OneToManyTableWithMap.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V2_0\r\n{\r\n    using namespace std::string_view_literals;\r\n    static constexpr std::string_view s_PackagesTable_Table_Name = \"packages\"sv;\r\n    static constexpr std::string_view s_PackagesTable_Index_Separator = \"_\"sv;\r\n    static constexpr std::string_view s_PackagesTable_Index_Suffix = \"_index\"sv;\r\n\r\n    namespace details\r\n    {\r\n        void PackagesTableCreate(SQLite::Connection& connection, std::initializer_list<ColumnInfo> values)\r\n        {\r\n            using namespace SQLite::Builder;\r\n\r\n            SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"createPackagesTable_v2_0\");\r\n\r\n            StatementBuilder createTableBuilder;\r\n            createTableBuilder.CreateTable(s_PackagesTable_Table_Name).BeginColumns();\r\n\r\n            // Add an integer primary key to keep the manifest rowid consistent\r\n            createTableBuilder.Column(IntegerPrimaryKey());\r\n\r\n            for (const ColumnInfo& value : values)\r\n            {\r\n                ColumnBuilder columnBuilder(value.Name, value.Type);\r\n\r\n                if (!value.AllowNull)\r\n                {\r\n                    columnBuilder.NotNull();\r\n                }\r\n\r\n                createTableBuilder.Column(columnBuilder);\r\n            }\r\n\r\n            createTableBuilder.EndColumns();\r\n\r\n            createTableBuilder.Execute(connection);\r\n\r\n            // Create a unique index with the primary key values\r\n            StatementBuilder pkIndexBuilder;\r\n\r\n            pkIndexBuilder.CreateUniqueIndex({ s_PackagesTable_Table_Name, s_PackagesTable_Index_Suffix }).On(s_PackagesTable_Table_Name).BeginColumns();\r\n\r\n            for (const ColumnInfo& value : values)\r\n            {\r\n                if (value.PrimaryKey)\r\n                {\r\n                    pkIndexBuilder.Column(value.Name);\r\n                }\r\n            }\r\n\r\n            pkIndexBuilder.EndColumns();\r\n\r\n            pkIndexBuilder.Execute(connection);\r\n\r\n            // Create an index on every value to improve performance\r\n            for (const ColumnInfo& value : values)\r\n            {\r\n                StatementBuilder createIndexBuilder;\r\n\r\n                createIndexBuilder.CreateIndex({ s_PackagesTable_Table_Name, s_PackagesTable_Index_Separator, value.Name, s_PackagesTable_Index_Suffix });\r\n                createIndexBuilder.On(s_PackagesTable_Table_Name).Columns(value.Name);\r\n\r\n                createIndexBuilder.Execute(connection);\r\n            }\r\n\r\n            savepoint.Commit();\r\n        }\r\n\r\n        // Creates a statement and executes it, select the actual values for a given manifest id.\r\n        // Ex.\r\n        // SELECT [ids].[id] FROM [manifest]\r\n        // JOIN [ids] ON [manifest].[id] = [ids].[rowid]\r\n        // WHERE [manifest].[rowid] = 1\r\n        SQLite::Statement PackagesTableGetValuesById_Statement(\r\n            const SQLite::Connection& connection,\r\n            SQLite::rowid_t id,\r\n            std::initializer_list<std::string_view> columns,\r\n            bool stepAndVerify)\r\n        {\r\n            SQLite::Builder::StatementBuilder builder;\r\n            builder.Select(columns).From(s_PackagesTable_Table_Name).Where(SQLite::RowIDName).Equals(id);\r\n\r\n            SQLite::Statement result = builder.Prepare(connection);\r\n\r\n            if (stepAndVerify)\r\n            {\r\n                THROW_HR_IF(E_NOT_SET, !result.Step());\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        SQLite::Statement PackagesTableUpdateValueIdById_Statement(SQLite::Connection& connection, std::string_view valueName)\r\n        {\r\n            SQLite::Builder::StatementBuilder builder;\r\n            builder.Update(s_PackagesTable_Table_Name).Set().Column(valueName).Equals(SQLite::Builder::Unbound).Where(SQLite::RowIDName).Equals(SQLite::Builder::Unbound);\r\n\r\n            return builder.Prepare(connection);\r\n        }\r\n\r\n        void PackagesTablePrepareForPackaging(SQLite::Connection& connection, std::initializer_list<ColumnInfo> values)\r\n        {\r\n            SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"pfpPackagesTable_v2_0\");\r\n\r\n            // Drop the index on the requested values\r\n            for (const auto& value : values)\r\n            {\r\n                SQLite::Builder::StatementBuilder dropIndexBuilder;\r\n                dropIndexBuilder.DropIndex({ s_PackagesTable_Table_Name, s_PackagesTable_Index_Separator, value.Name, s_PackagesTable_Index_Suffix });\r\n\r\n                dropIndexBuilder.Execute(connection);\r\n            }\r\n\r\n            SQLite::Builder::StatementBuilder dropPKIndexBuilder;\r\n            dropPKIndexBuilder.DropIndex({ s_PackagesTable_Table_Name, s_PackagesTable_Index_Suffix });\r\n            dropPKIndexBuilder.Execute(connection);\r\n\r\n            savepoint.Commit();\r\n        }\r\n\r\n        bool PackagesTableCheckColumnForNulls(const SQLite::Connection& connection, std::string_view valueName, bool log)\r\n        {\r\n            // Build a select statement to find values that contain an embedded null character\r\n            // Such as:\r\n            // Select count(*) from table where instr(value,char(0))>0\r\n            SQLite::Builder::StatementBuilder builder;\r\n            builder.\r\n                Select({ SQLite::RowIDName, valueName }).\r\n                From(s_PackagesTable_Table_Name).\r\n                WhereValueContainsEmbeddedNullCharacter(valueName);\r\n\r\n            SQLite::Statement select = builder.Prepare(connection);\r\n            bool result = true;\r\n\r\n            while (select.Step())\r\n            {\r\n                result = false;\r\n\r\n                if (!log)\r\n                {\r\n                    break;\r\n                }\r\n\r\n                AICLI_LOG(Repo, Info, << \"  [INVALID] value [\" << valueName << \"] in table [\" << s_PackagesTable_Table_Name <<\r\n                    \"] at row [\" << select.GetColumn<SQLite::rowid_t>(0) << \"] contains an embedded null character and starts with [\" <<\r\n                    select.GetColumn<std::string>(1) << \"]\");\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        bool PackagesTableCheckConsistency(const SQLite::Connection& connection, std::initializer_list<std::string_view> values, bool log)\r\n        {\r\n            bool result = true;\r\n\r\n            for (const auto& value : values)\r\n            {\r\n                if (result || log)\r\n                {\r\n                    result = details::PackagesTableCheckColumnForNulls(connection, value, log) && result;\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n\r\n    std::string_view PackagesTable::TableName()\r\n    {\r\n        return s_PackagesTable_Table_Name;\r\n    }\r\n\r\n    void PackagesTable::Drop(SQLite::Connection& connection)\r\n    {\r\n        SQLite::Builder::StatementBuilder dropTableBuilder;\r\n        dropTableBuilder.DropTable(s_PackagesTable_Table_Name);\r\n\r\n        dropTableBuilder.Execute(connection);\r\n    }\r\n\r\n    bool PackagesTable::Exists(const SQLite::Connection& connection)\r\n    {\r\n        using namespace SQLite;\r\n\r\n        Builder::StatementBuilder builder;\r\n        builder.Select(Builder::RowCount).From(Builder::Schema::MainTable).\r\n            Where(Builder::Schema::TypeColumn).Equals(Builder::Schema::Type_Table).And(Builder::Schema::NameColumn).Equals(s_PackagesTable_Table_Name);\r\n\r\n        Statement statement = builder.Prepare(connection);\r\n        THROW_HR_IF(E_UNEXPECTED, !statement.Step());\r\n        return statement.GetColumn<int64_t>(0) != 0;\r\n    }\r\n\r\n    void PackagesTable::AddColumn(SQLite::Connection& connection, const ColumnInfo& value)\r\n    {\r\n        using namespace SQLite::Builder;\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"addColumnPackagesTable_v2_0\");\r\n\r\n        StatementBuilder alterTableBuilder;\r\n        alterTableBuilder.AlterTable(s_PackagesTable_Table_Name).Add(value.Name, value.Type);\r\n\r\n        alterTableBuilder.Execute(connection);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    SQLite::rowid_t PackagesTable::Insert(SQLite::Connection& connection, const std::vector<NameValuePair>& values)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.InsertInto(s_PackagesTable_Table_Name).BeginColumns();\r\n\r\n        for (const NameValuePair& value : values)\r\n        {\r\n            builder.Column(value.Name);\r\n        }\r\n\r\n        builder.EndColumns().BeginValues();\r\n\r\n        for (const NameValuePair& value : values)\r\n        {\r\n            builder.Value(value.Value);\r\n        }\r\n\r\n        builder.EndValues();\r\n\r\n        builder.Execute(connection);\r\n\r\n        return connection.GetLastInsertRowID();\r\n    }\r\n\r\n    bool PackagesTable::ExistsById(const SQLite::Connection& connection, SQLite::rowid_t id)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.Select(SQLite::Builder::RowCount).From(s_PackagesTable_Table_Name).Where(SQLite::RowIDName).Equals(id);\r\n\r\n        SQLite::Statement countStatement = builder.Prepare(connection);\r\n\r\n        THROW_HR_IF(E_UNEXPECTED, !countStatement.Step());\r\n\r\n        return (countStatement.GetColumn<int>(0) != 0);\r\n    }\r\n\r\n    std::vector<SQLite::rowid_t> PackagesTable::GetAllRowIds(const SQLite::Connection& connection, std::string_view orderByColumn, size_t limit)\r\n    {\r\n        SQLite::Builder::StatementBuilder selectBuilder;\r\n        selectBuilder.Select(SQLite::RowIDName).From(s_PackagesTable_Table_Name).OrderBy(orderByColumn);\r\n\r\n        if (limit)\r\n        {\r\n            selectBuilder.Limit(limit);\r\n        }\r\n\r\n        SQLite::Statement select = selectBuilder.Prepare(connection);\r\n\r\n        std::vector<SQLite::rowid_t> result;\r\n        while (select.Step())\r\n        {\r\n            result.emplace_back(select.GetColumn<SQLite::rowid_t>(0));\r\n        }\r\n        return result;\r\n    }\r\n\r\n    uint64_t PackagesTable::GetCount(const SQLite::Connection& connection)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.Select(SQLite::Builder::RowCount).From(s_PackagesTable_Table_Name);\r\n\r\n        SQLite::Statement countStatement = builder.Prepare(connection);\r\n\r\n        THROW_HR_IF(E_UNEXPECTED, !countStatement.Step());\r\n\r\n        return static_cast<uint64_t>(countStatement.GetColumn<SQLite::rowid_t>(0));\r\n    }\r\n\r\n    int PackagesTable::BuildSearchStatement(\r\n        SQLite::Builder::StatementBuilder& builder,\r\n        std::string_view valueName,\r\n        std::string_view primaryAlias,\r\n        std::string_view valueAlias,\r\n        bool useLike)\r\n    {\r\n        using QCol = SQLite::Builder::QualifiedColumn;\r\n\r\n        // Build a statement like:\r\n        //      SELECT packages.rowid as p, packages.id as v from packages\r\n        //      where packages.id = <value>\r\n        builder.Select().\r\n            Column(QCol(s_PackagesTable_Table_Name, SQLite::RowIDName)).As(primaryAlias).\r\n            Column(QCol(s_PackagesTable_Table_Name, valueName)).As(valueAlias).\r\n        From(s_PackagesTable_Table_Name).Where(QCol(s_PackagesTable_Table_Name, valueName));\r\n\r\n        int result = -1;\r\n\r\n        if (useLike)\r\n        {\r\n            builder.Like(SQLite::Builder::Unbound);\r\n            result = builder.GetLastBindIndex();\r\n            builder.Escape(SQLite::EscapeCharForLike);\r\n        }\r\n        else\r\n        {\r\n            builder.Equals(SQLite::Builder::Unbound);\r\n            result = builder.GetLastBindIndex();\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    bool PackagesTable::IsEmpty(SQLite::Connection& connection)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.Select(SQLite::Builder::RowCount).From(s_PackagesTable_Table_Name);\r\n\r\n        SQLite::Statement countStatement = builder.Prepare(connection);\r\n\r\n        THROW_HR_IF(E_UNEXPECTED, !countStatement.Step());\r\n\r\n        return (countStatement.GetColumn<int>(0) == 0);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/2_0/PackagesTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteWrapper.h>\r\n#include <winget/SQLiteStatementBuilder.h>\r\n#include <initializer_list>\r\n#include <optional>\r\n#include <string_view>\r\n#include <utility>\r\n#include <vector>\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V2_0\r\n{\r\n    namespace details\r\n    {\r\n        // Info on the columns.\r\n        struct ColumnInfo\r\n        {\r\n            template<typename Column>\r\n            static constexpr ColumnInfo Create()\r\n            {\r\n                ColumnInfo result;\r\n                result.Name = Column::Name;\r\n                result.Type = Column::Type;\r\n                result.PrimaryKey = Column::PrimaryKey;\r\n                result.AllowNull = Column::AllowNull;\r\n                return result;\r\n            }\r\n\r\n            std::string_view Name;\r\n            SQLite::Builder::Type Type = {};\r\n            bool PrimaryKey = false;\r\n            bool AllowNull = false;\r\n        };\r\n\r\n        // Creates the table.\r\n        void PackagesTableCreate(SQLite::Connection& connection, std::initializer_list<ColumnInfo> values);\r\n\r\n        // Gets the requested values for the manifest with the given rowid.\r\n        SQLite::Statement PackagesTableGetValuesById_Statement(\r\n            const SQLite::Connection& connection,\r\n            SQLite::rowid_t id,\r\n            std::initializer_list<std::string_view> columns,\r\n            bool stepAndVerify = true);\r\n\r\n        // Prepares a statement to update the value of a single column for the manifest with the given rowid.\r\n        // The first bind value will be the value to set.\r\n        // The second bind value will be the manifest rowid to modify.\r\n        SQLite::Statement PackagesTableUpdateValueIdById_Statement(SQLite::Connection& connection, std::string_view valueName);\r\n\r\n        // Removes data that is no longer needed for an index that is to be published.\r\n        void PackagesTablePrepareForPackaging(SQLite::Connection& connection, std::initializer_list<ColumnInfo> values);\r\n\r\n        // Checks for embedded nulls in the database.\r\n        bool PackagesTableCheckConsistency(const SQLite::Connection& connection, std::initializer_list<std::string_view> values, bool log);\r\n    }\r\n\r\n    // A table in which each row represents a single package.\r\n    struct PackagesTable\r\n    {\r\n        // Get the table name.\r\n        static std::string_view TableName();\r\n\r\n        struct IdColumn\r\n        {\r\n            static constexpr std::string_view Name = \"id\"sv;\r\n            static constexpr SQLite::Builder::Type Type = SQLite::Builder::Type::Text;\r\n            static constexpr bool PrimaryKey = true;\r\n            static constexpr bool AllowNull = false;\r\n        };\r\n\r\n        struct NameColumn\r\n        {\r\n            static constexpr std::string_view Name = \"name\"sv;\r\n            static constexpr SQLite::Builder::Type Type = SQLite::Builder::Type::Text;\r\n            static constexpr bool PrimaryKey = false;\r\n            static constexpr bool AllowNull = false;\r\n        };\r\n\r\n        struct MonikerColumn\r\n        {\r\n            static constexpr std::string_view Name = \"moniker\"sv;\r\n            static constexpr SQLite::Builder::Type Type = SQLite::Builder::Type::Text;\r\n            static constexpr bool PrimaryKey = false;\r\n            static constexpr bool AllowNull = true;\r\n        };\r\n\r\n        struct LatestVersionColumn\r\n        {\r\n            static constexpr std::string_view Name = \"latest_version\"sv;\r\n            static constexpr SQLite::Builder::Type Type = SQLite::Builder::Type::Text;\r\n            static constexpr bool PrimaryKey = false;\r\n            static constexpr bool AllowNull = false;\r\n        };\r\n\r\n        struct ARPMinVersionColumn\r\n        {\r\n            static constexpr std::string_view Name = \"arp_min_version\"sv;\r\n            static constexpr SQLite::Builder::Type Type = SQLite::Builder::Type::Text;\r\n            static constexpr bool PrimaryKey = false;\r\n            static constexpr bool AllowNull = true;\r\n        };\r\n\r\n        struct ARPMaxVersionColumn\r\n        {\r\n            static constexpr std::string_view Name = \"arp_max_version\"sv;\r\n            static constexpr SQLite::Builder::Type Type = SQLite::Builder::Type::Text;\r\n            static constexpr bool PrimaryKey = false;\r\n            static constexpr bool AllowNull = true;\r\n        };\r\n\r\n        struct HashColumn\r\n        {\r\n            static constexpr std::string_view Name = \"hash\"sv;\r\n            static constexpr SQLite::Builder::Type Type = SQLite::Builder::Type::Blob;\r\n            static constexpr bool PrimaryKey = false;\r\n            static constexpr bool AllowNull = true;\r\n        };\r\n\r\n        using ColumnInfo = details::ColumnInfo;\r\n\r\n        // Creates the table.\r\n        template <typename... Columns>\r\n        static void Create(SQLite::Connection& connection)\r\n        {\r\n            details::PackagesTableCreate(connection, { ColumnInfo::Create<Columns>()... });\r\n        }\r\n\r\n        // Drops the table.\r\n        static void Drop(SQLite::Connection& connection);\r\n\r\n        // Determine if the table currently exists in the database.\r\n        static bool Exists(const SQLite::Connection& connection);\r\n\r\n        // Alters the table, adding the column provided.\r\n        static void AddColumn(SQLite::Connection& connection, const ColumnInfo& value);\r\n\r\n        // A string value for the package.\r\n        struct NameValuePair\r\n        {\r\n            std::string_view Name;\r\n            std::string Value;\r\n        };\r\n\r\n        // Insert the given values into the table.\r\n        static SQLite::rowid_t Insert(SQLite::Connection& connection, const std::vector<NameValuePair>& values);\r\n\r\n        // Gets a value indicating whether the package with rowid exists.\r\n        static bool ExistsById(const SQLite::Connection& connection, SQLite::rowid_t rowid);\r\n\r\n        // Gets all row ids from the table.\r\n        static std::vector<SQLite::rowid_t> GetAllRowIds(const SQLite::Connection& connection, std::string_view orderByColumn, size_t limit = 0);\r\n\r\n        // Gets the total number of rows in the table.\r\n        static uint64_t GetCount(const SQLite::Connection& connection);\r\n\r\n        // Gets the values requested for the package with the given rowid.\r\n        template <typename... Columns>\r\n        static auto GetValuesById(const SQLite::Connection& connection, SQLite::rowid_t rowid)\r\n        {\r\n            return details::PackagesTableGetValuesById_Statement(connection, rowid, { Columns::Name... }).GetRow<typename SQLite::Builder::TypeInfo<Columns::Type, Columns::AllowNull>::value_t...>();\r\n        }\r\n\r\n        // Gets the value requested for the package with the given rowid, if it exists.\r\n        template <typename Column>\r\n        static std::optional<typename SQLite::Builder::TypeInfo<Column::Type, false>::value_t> GetValueById(const SQLite::Connection& connection, SQLite::rowid_t rowid)\r\n        {\r\n            auto statement = details::PackagesTableGetValuesById_Statement(connection, rowid, { Column::Name }, false);\r\n            if (statement.Step()) { return statement.GetColumn<typename SQLite::Builder::TypeInfo<Column::Type, Column::AllowNull>::value_t>(0); }\r\n            else { return std::nullopt; }\r\n        }\r\n\r\n        // Builds the search select statement base on the given value.\r\n        // The return value is the bind index of the value to match against.\r\n        static int BuildSearchStatement(SQLite::Builder::StatementBuilder& builder, std::string_view valueName, std::string_view primaryAlias, std::string_view valueAlias, bool useLike);\r\n\r\n        // Update the value of a single column for the package with the given rowid.\r\n        template <typename Column>\r\n        static void UpdateValueIdById(SQLite::Connection& connection, SQLite::rowid_t id, const typename SQLite::Builder::TypeInfo<Column::Type, Column::AllowNull>::value_t& value)\r\n        {\r\n            auto stmt = details::PackagesTableUpdateValueIdById_Statement(connection, Column::Name);\r\n            stmt.Bind(1, value);\r\n            stmt.Bind(2, id);\r\n            stmt.Execute();\r\n        }\r\n\r\n        // Removes data that is no longer needed for an index that is to be published.\r\n        template <typename... Columns>\r\n        static void PrepareForPackaging(SQLite::Connection& connection)\r\n        {\r\n            details::PackagesTablePrepareForPackaging(connection, { ColumnInfo::Create<Columns>()... });\r\n        }\r\n\r\n        // Checks the consistency of the index to ensure that every referenced row exists.\r\n        // Returns true if index is consistent; false if it is not.\r\n        template <typename... Columns>\r\n        static bool CheckConsistency(const SQLite::Connection& connection, bool log)\r\n        {\r\n            return details::PackagesTableCheckConsistency(connection, { Columns::Name... }, log);\r\n        }\r\n\r\n        // Determines if the table is empty.\r\n        static bool IsEmpty(SQLite::Connection& connection);\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/2_0/ProductCodeTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/2_0/SystemReferenceStringTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V2_0\r\n{\r\n    namespace details\r\n    {\r\n        using namespace std::string_view_literals;\r\n\r\n        struct ProductCodeTableInfo\r\n        {\r\n            inline static constexpr std::string_view TableName() { return \"productcodes2\"sv; }\r\n            inline static constexpr std::string_view ValueName() { return \"productcode\"sv; }\r\n        };\r\n    }\r\n\r\n    using ProductCodeTable = SystemReferenceStringTable<details::ProductCodeTableInfo>;\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/2_0/SearchResultsTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteWrapper.h>\r\n#include <winget/SQLiteTempTable.h>\r\n#include \"Microsoft/Schema/ISQLiteIndex.h\"\r\n#include \"Public/winget/RepositorySearch.h\"\r\n\r\n#include <optional>\r\n#include <utility>\r\n#include <vector>\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V2_0\r\n{\r\n    // Table for holding temporary search results.\r\n    struct SearchResultsTable : public SQLite::TempTable\r\n    {\r\n        SearchResultsTable(const SQLite::Connection& connection);\r\n\r\n        SearchResultsTable(const SearchResultsTable&) = delete;\r\n        SearchResultsTable& operator=(const SearchResultsTable&) = delete;\r\n\r\n        SearchResultsTable(SearchResultsTable&&) = default;\r\n        SearchResultsTable& operator=(SearchResultsTable&&) = default;\r\n\r\n        // Performs the requested search type on the requested field.\r\n        void SearchOnField(const PackageMatchFilter& filter);\r\n\r\n        // Removes rows with package ids whose sort order is below the highest one.\r\n        void RemoveDuplicatePackageRows();\r\n\r\n        // Prepares the table for a filtering pass.\r\n        void PrepareToFilter();\r\n\r\n        // Performs the requested filter type on the requested field.\r\n        void FilterOnField(const PackageMatchFilter& filter);\r\n\r\n        // Completes a filtering pass, removing filtered rows.\r\n        void CompleteFilter();\r\n\r\n        // Gets the results from the table.\r\n        ISQLiteIndex::SearchResult GetSearchResults(size_t limit = 0);\r\n\r\n    protected:\r\n        // Builds the search statement for the specified field and match type.\r\n        std::vector<int> BuildSearchStatement(SQLite::Builder::StatementBuilder& builder, PackageMatchField field, MatchType match) const;\r\n\r\n        virtual std::vector<int> BuildSearchStatement(\r\n            SQLite::Builder::StatementBuilder& builder,\r\n            PackageMatchField field,\r\n            std::string_view manifestAlias,\r\n            std::string_view valueAlias,\r\n            bool useLike) const;\r\n\r\n        static bool MatchUsesLike(MatchType match);\r\n        void BindStatementForMatchType(SQLite::Statement& statement, MatchType match, int bindIndex, std::string_view value);\r\n\r\n        virtual void BindStatementForMatchType(SQLite::Statement& statement, const PackageMatchFilter& filter, const std::vector<int>& bindIndex);\r\n\r\n    private:\r\n        const SQLite::Connection& m_connection;\r\n        int m_sortOrdinalValue = 0;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/2_0/SearchResultsTable_2_0.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"SearchResultsTable.h\"\r\n#include <winget/SQLiteStatementBuilder.h>\r\n\r\n#include \"Microsoft/Schema/2_0/PackagesTable.h\"\r\n#include \"Microsoft/Schema/2_0/TagsTable.h\"\r\n#include \"Microsoft/Schema/2_0/CommandsTable.h\"\r\n#include \"Microsoft/Schema/2_0/PackageFamilyNameTable.h\"\r\n#include \"Microsoft/Schema/2_0/ProductCodeTable.h\"\r\n#include \"Microsoft/Schema/2_0/UpgradeCodeTable.h\"\r\n#include \"Microsoft/Schema/2_0/NormalizedPackageNameTable.h\"\r\n#include \"Microsoft/Schema/2_0/NormalizedPackagePublisherTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V2_0\r\n{\r\n    namespace\r\n    {\r\n        using namespace std::string_literals;\r\n        using namespace std::string_view_literals;\r\n\r\n        constexpr std::string_view s_SearchResultsTable_Package = \"package\"sv;\r\n        constexpr std::string_view s_SearchResultsTable_MatchField = \"field\"sv;\r\n        constexpr std::string_view s_SearchResultsTable_MatchType = \"match\"sv;\r\n        constexpr std::string_view s_SearchResultsTable_MatchValue = \"value\"sv;\r\n        constexpr std::string_view s_SearchResultsTable_SortValue = \"sort\"sv;\r\n        constexpr std::string_view s_SearchResultsTable_Filter = \"filter\"sv;\r\n\r\n        constexpr std::string_view s_SearchResultsTable_Index_Suffix = \"_i_m\"sv;\r\n\r\n        constexpr std::string_view s_SearchResultsTable_SubSelect_TableAlias = \"valueTable\"sv;\r\n        constexpr std::string_view s_SearchResultsTable_SubSelect_PackageAlias = \"p\"sv;\r\n        constexpr std::string_view s_SearchResultsTable_SubSelect_ValueAlias = \"v\"sv;\r\n    }\r\n\r\n    SearchResultsTable::SearchResultsTable(const SQLite::Connection& connection) :\r\n        m_connection(connection)\r\n    {\r\n        using namespace SQLite::Builder;\r\n\r\n        {\r\n            StatementBuilder builder;\r\n            builder.CreateTable(GetQualifiedName()).BeginColumns();\r\n\r\n            builder.Column(ColumnBuilder(s_SearchResultsTable_Package, Type::RowId).NotNull());\r\n            builder.Column(ColumnBuilder(s_SearchResultsTable_MatchField, Type::Int).NotNull());\r\n            builder.Column(ColumnBuilder(s_SearchResultsTable_MatchType, Type::Int).NotNull());\r\n            builder.Column(ColumnBuilder(s_SearchResultsTable_MatchValue, Type::Text).NotNull());\r\n            builder.Column(ColumnBuilder(s_SearchResultsTable_SortValue, Type::Int).NotNull());\r\n            builder.Column(ColumnBuilder(s_SearchResultsTable_Filter, Type::Bool).NotNull());\r\n\r\n            builder.EndColumns();\r\n\r\n            builder.Execute(m_connection);\r\n        }\r\n\r\n        InitDropStatement(m_connection);\r\n\r\n        {\r\n            SQLite::Builder::QualifiedTable index = GetQualifiedName();\r\n            std::string indexName(index.Table);\r\n            indexName += s_SearchResultsTable_Index_Suffix;\r\n            index.Table = indexName;\r\n\r\n            StatementBuilder builder;\r\n            builder.CreateIndex(indexName).On(GetQualifiedName().Table).Columns(s_SearchResultsTable_Package);\r\n\r\n            builder.Execute(m_connection);\r\n        }\r\n    }\r\n\r\n    void SearchResultsTable::SearchOnField(const PackageMatchFilter& filter)\r\n    {\r\n        using namespace SQLite::Builder;\r\n\r\n        int sortOrdinal = m_sortOrdinalValue++;\r\n\r\n        // Create an insert statement to select values into the table as requested.\r\n        // The goal is a statement like this:\r\n        //      INSERT INTO <tempTable>\r\n        //      SELECT valueTable.p, <field>, <match>, valueTable.v, <sort>, <filter> FROM\r\n        //      (SELECT packages.rowid as p, packages.id as v from packages where packages.id = <value>) AS valueTable\r\n        // Where the subselect is built by the owning table.\r\n        StatementBuilder builder;\r\n        builder.InsertInto(GetQualifiedName()).Select().\r\n            Column(QualifiedColumn(s_SearchResultsTable_SubSelect_TableAlias, s_SearchResultsTable_SubSelect_PackageAlias)).\r\n            Value(filter.Field).\r\n            Value(filter.Type).\r\n            Column(QualifiedColumn(s_SearchResultsTable_SubSelect_TableAlias, s_SearchResultsTable_SubSelect_ValueAlias)).\r\n            Value(sortOrdinal).\r\n            Value(false).\r\n        From().BeginParenthetical();\r\n\r\n        // Add the field specific portion\r\n        std::vector<int> bindIndex = BuildSearchStatement(builder, filter.Field, filter.Type);\r\n\r\n        if (bindIndex.empty())\r\n        {\r\n            AICLI_LOG(Repo, Verbose, << \"PackageMatchField not supported in this version: \" << ToString(filter.Field));\r\n            return;\r\n        }\r\n\r\n        builder.EndParenthetical().As(s_SearchResultsTable_SubSelect_TableAlias);\r\n\r\n        SQLite::Statement statement = builder.Prepare(m_connection);\r\n        BindStatementForMatchType(statement, filter, bindIndex);\r\n        statement.Execute();\r\n        AICLI_LOG(SQL, Verbose, << \"Search found \" << m_connection.GetChanges() << \" rows\");\r\n    }\r\n\r\n    void SearchResultsTable::RemoveDuplicatePackageRows()\r\n    {\r\n        using namespace SQLite::Builder;\r\n\r\n        // Create a delete statement to leave only one row with a given package.\r\n        // This will arbitrarily choose one of the rows if multiple have the same lowest sort order.\r\n        // The goal is a statement like this:\r\n        //      DELETE from <temp> where rowid not in (\r\n        //          SELECT rowid from (\r\n        //              SELECT rowid, min(sort) from <temp> group by package\r\n        //          )\r\n        //      )\r\n        StatementBuilder builder;\r\n        builder.DeleteFrom(GetQualifiedName()).Where(SQLite::RowIDName).Not().In().BeginParenthetical().\r\n            Select(SQLite::RowIDName).From().BeginParenthetical().\r\n                Select().Column(SQLite::RowIDName).Column(Aggregate::Min, s_SearchResultsTable_SortValue).From(GetQualifiedName()).GroupBy(s_SearchResultsTable_Package).\r\n            EndParenthetical().\r\n        EndParenthetical();\r\n\r\n        builder.Execute(m_connection);\r\n        AICLI_LOG(SQL, Verbose, << \"Removed \" << m_connection.GetChanges() << \" duplicate rows\");\r\n    }\r\n\r\n    void SearchResultsTable::PrepareToFilter()\r\n    {\r\n        // Reset all filter values to unselected\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.Update(GetQualifiedName()).Set().Column(s_SearchResultsTable_Filter).Equals(false);\r\n\r\n        builder.Execute(m_connection);\r\n    }\r\n\r\n    void SearchResultsTable::FilterOnField(const PackageMatchFilter& filter)\r\n    {\r\n        using namespace SQLite::Builder;\r\n\r\n        // Create an update statement to mark rows that are found by the search.\r\n        // This will arbitrarily choose one of the rows if multiple have the same lowest sort order.\r\n        // The goal is a statement like this:\r\n        //      UPDATE <temp> set filter = 1 where package in (\r\n        //          SELECT p from (\r\n        //              SELECT packages.rowid as p, packages.id as v from packages where packages.id = <value>\r\n        //          )\r\n        //      )\r\n        StatementBuilder builder;\r\n        builder.Update(GetQualifiedName()).Set().Column(s_SearchResultsTable_Filter).Equals(true).Where(s_SearchResultsTable_Package).In().BeginParenthetical().\r\n            Select(s_SearchResultsTable_SubSelect_PackageAlias).From().BeginParenthetical();\r\n\r\n        // Add the field specific portion\r\n        std::vector<int> bindIndex = BuildSearchStatement(builder, filter.Field, filter.Type);\r\n\r\n        if (bindIndex.empty())\r\n        {\r\n            AICLI_LOG(Repo, Verbose, << \"PackageMatchField not supported in this version: \" << ToString(filter.Field));\r\n            return;\r\n        }\r\n\r\n        builder.EndParenthetical().EndParenthetical();\r\n\r\n        SQLite::Statement statement = builder.Prepare(m_connection);\r\n        BindStatementForMatchType(statement, filter, bindIndex);\r\n        statement.Execute();\r\n        AICLI_LOG(SQL, Verbose, << \"Filter kept \" << m_connection.GetChanges() << \" rows\");\r\n    }\r\n\r\n    void SearchResultsTable::CompleteFilter()\r\n    {\r\n        // Delete all unselected values\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.DeleteFrom(GetQualifiedName()).Where(s_SearchResultsTable_Filter).Equals(false);\r\n\r\n        builder.Execute(m_connection);\r\n        AICLI_LOG(SQL, Verbose, << \"Filter deleted \" << m_connection.GetChanges() << \" rows\");\r\n    }\r\n\r\n    ISQLiteIndex::SearchResult SearchResultsTable::GetSearchResults(size_t limit)\r\n    {\r\n        using namespace SQLite::Builder;\r\n        using QCol = QualifiedColumn;\r\n\r\n        // Select all of the results from the table; it is expected that RemoveDuplicatePackageRows has been called.\r\n        StatementBuilder builder;\r\n        builder.Select({\r\n            s_SearchResultsTable_Package,\r\n            s_SearchResultsTable_MatchField,\r\n            s_SearchResultsTable_MatchType,\r\n            s_SearchResultsTable_MatchValue,\r\n        }).\r\n        From(GetQualifiedName()).OrderBy(s_SearchResultsTable_SortValue);\r\n\r\n        SQLite::Statement select = builder.Prepare(m_connection);\r\n\r\n        ISQLiteIndex::SearchResult result;\r\n        while (select.Step())\r\n        {\r\n            if (limit && result.Matches.size() >= limit)\r\n            {\r\n                break;\r\n            }\r\n\r\n            result.Matches.emplace_back(select.GetColumn<SQLite::rowid_t>(0), \r\n                PackageMatchFilter(select.GetColumn<PackageMatchField>(1), select.GetColumn<MatchType>(2), select.GetColumn<std::string>(3)));\r\n        }\r\n\r\n        result.Truncated = (select.GetState() != SQLite::Statement::State::Completed);\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<int> SearchResultsTable::BuildSearchStatement(SQLite::Builder::StatementBuilder& builder, PackageMatchField field, MatchType match) const\r\n    {\r\n        return BuildSearchStatement(builder, field, s_SearchResultsTable_SubSelect_PackageAlias, s_SearchResultsTable_SubSelect_ValueAlias, MatchUsesLike(match));\r\n    }\r\n\r\n    std::vector<int> SearchResultsTable::BuildSearchStatement(\r\n        SQLite::Builder::StatementBuilder& builder,\r\n        PackageMatchField field,\r\n        std::string_view manifestAlias,\r\n        std::string_view valueAlias,\r\n        bool useLike) const\r\n    {\r\n        std::vector<int> result;\r\n\r\n        switch (field)\r\n        {\r\n        case PackageMatchField::Id:\r\n            result.push_back(PackagesTable::BuildSearchStatement(builder, PackagesTable::IdColumn::Name, manifestAlias, valueAlias, useLike));\r\n            break;\r\n        case PackageMatchField::Name:\r\n            result.push_back(PackagesTable::BuildSearchStatement(builder, PackagesTable::NameColumn::Name, manifestAlias, valueAlias, useLike));\r\n            break;\r\n        case PackageMatchField::Moniker:\r\n            result.push_back(PackagesTable::BuildSearchStatement(builder, PackagesTable::MonikerColumn::Name, manifestAlias, valueAlias, useLike));\r\n            break;\r\n        case PackageMatchField::Tag:\r\n            result.push_back(TagsTable::BuildSearchStatement(builder, manifestAlias, valueAlias, useLike));\r\n            break;\r\n        case PackageMatchField::Command:\r\n            result.push_back(CommandsTable::BuildSearchStatement(builder, manifestAlias, valueAlias, useLike));\r\n            break;\r\n        case PackageMatchField::PackageFamilyName:\r\n            result.push_back(PackageFamilyNameTable::BuildSearchStatement(builder, manifestAlias, valueAlias, useLike));\r\n            break;\r\n        case PackageMatchField::ProductCode:\r\n            result.push_back(ProductCodeTable::BuildSearchStatement(builder, manifestAlias, valueAlias, useLike));\r\n            break;\r\n        case PackageMatchField::UpgradeCode:\r\n            result.push_back(UpgradeCodeTable::BuildSearchStatement(builder, manifestAlias, valueAlias, useLike));\r\n            break;\r\n        case PackageMatchField::NormalizedNameAndPublisher:\r\n            result = NormalizedPackageNameTable::BuildPairedSearchStatement<NormalizedPackagePublisherTable>(builder, manifestAlias, valueAlias, useLike);\r\n            break;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    bool SearchResultsTable::MatchUsesLike(MatchType match)\r\n    {\r\n        return (match != MatchType::Exact);\r\n    }\r\n\r\n    void SearchResultsTable::BindStatementForMatchType(SQLite::Statement& statement, MatchType match, int bindIndex, std::string_view value)\r\n    {\r\n        std::string valueToUse;\r\n\r\n        if (MatchUsesLike(match))\r\n        {\r\n            valueToUse = SQLite::EscapeStringForLike(value);\r\n        }\r\n        else\r\n        {\r\n            valueToUse = value;\r\n        }\r\n\r\n        switch (match)\r\n        {\r\n        case AppInstaller::Repository::MatchType::StartsWith:\r\n            valueToUse += '%';\r\n            break;\r\n        case AppInstaller::Repository::MatchType::Substring:\r\n            valueToUse = \"%\"s + valueToUse + '%';\r\n            break;\r\n        default:\r\n            // No changes required for others.\r\n            break;\r\n        }\r\n\r\n        statement.Bind(bindIndex, valueToUse);\r\n    }\r\n\r\n    void SearchResultsTable::BindStatementForMatchType(SQLite::Statement& statement, const PackageMatchFilter& filter, const std::vector<int>& bindIndex)\r\n    {\r\n        // TODO: Implement these more complex match types\r\n        if (filter.Type == MatchType::Wildcard || filter.Type == MatchType::Fuzzy || filter.Type == MatchType::FuzzySubstring)\r\n        {\r\n            AICLI_LOG(Repo, Verbose, << \"Specific match type not implemented, skipping: \" << ToString(filter.Type));\r\n            return;\r\n        }\r\n\r\n        BindStatementForMatchType(statement, filter.Type, bindIndex[0], filter.Value);\r\n\r\n        if (filter.Field == PackageMatchField::NormalizedNameAndPublisher)\r\n        {\r\n            BindStatementForMatchType(statement, filter.Type, bindIndex[1], filter.Additional.value());\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/2_0/SystemReferenceStringTable.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Microsoft/Schema/2_0/SystemReferenceStringTable.h\"\r\n#include \"Microsoft/Schema/2_0/PackagesTable.h\"\r\n#include <winget/SQLiteStatementBuilder.h>\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V2_0\r\n{\r\n    namespace details\r\n    {\r\n        using PrimaryTable = PackagesTable;\r\n\r\n        using namespace std::string_view_literals;\r\n        static constexpr std::string_view s_SystemReferenceStringTable_PrimaryName = \"package\"sv;\r\n\r\n        std::string_view SystemReferenceStringTableGetPrimaryColumnName()\r\n        {\r\n            return s_SystemReferenceStringTable_PrimaryName;\r\n        }\r\n\r\n        void SystemReferenceStringTableCreate(SQLite::Connection& connection, std::string_view tableName, std::string_view valueName)\r\n        {\r\n            using namespace SQLite::Builder;\r\n\r\n            SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, std::string{ tableName } + \"_create_v2_0\");\r\n\r\n            StatementBuilder createTableBuilder;\r\n            createTableBuilder.CreateTable(tableName).Columns({\r\n                ColumnBuilder(valueName, Type::Text).NotNull(),\r\n                ColumnBuilder(s_SystemReferenceStringTable_PrimaryName, Type::RowId).NotNull(),\r\n                PrimaryKeyBuilder({ valueName, s_SystemReferenceStringTable_PrimaryName })\r\n                }).WithoutRowID();\r\n\r\n            createTableBuilder.Execute(connection);\r\n\r\n            savepoint.Commit();\r\n        }\r\n\r\n        void SystemReferenceStringTableDrop(SQLite::Connection& connection, std::string_view tableName)\r\n        {\r\n            SQLite::Builder::StatementBuilder dropTableBuilder;\r\n            dropTableBuilder.DropTable(tableName);\r\n\r\n            dropTableBuilder.Execute(connection);\r\n        }\r\n\r\n        std::vector<std::string> SystemReferenceStringTableGetValuesByPrimaryId(\r\n            const SQLite::Connection& connection,\r\n            std::string_view tableName,\r\n            std::string_view valueName,\r\n            SQLite::rowid_t primaryId)\r\n        {\r\n            std::vector<std::string> result;\r\n\r\n            SQLite::Builder::StatementBuilder builder;\r\n            builder.Select(valueName).\r\n                From(tableName).Where(s_SystemReferenceStringTable_PrimaryName).Equals(primaryId);\r\n\r\n            SQLite::Statement statement = builder.Prepare(connection);\r\n\r\n            while (statement.Step())\r\n            {\r\n                result.emplace_back(statement.GetColumn<std::string>(0));\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        void SystemReferenceStringTableEnsureExists(\r\n            SQLite::Connection& connection,\r\n            std::string_view tableName,\r\n            std::string_view valueName,\r\n            const std::vector<std::string>& values,\r\n            SQLite::rowid_t primaryId)\r\n        {\r\n            SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, std::string{ tableName } + \"_ensure_v2_0\");\r\n\r\n            SQLite::Builder::StatementBuilder builder;\r\n\r\n            builder.InsertOrIgnore(tableName).\r\n                Columns({ valueName, s_SystemReferenceStringTable_PrimaryName }).Values(SQLite::Builder::Unbound, primaryId);\r\n\r\n            SQLite::Statement insertStatement = builder.Prepare(connection);\r\n\r\n            for (const std::string& value : values)\r\n            {\r\n                // Second, insert into the mapping table\r\n                insertStatement.Reset();\r\n                insertStatement.Bind(1, value);\r\n\r\n                insertStatement.Execute();\r\n            }\r\n\r\n            savepoint.Commit();\r\n        }\r\n\r\n        bool SystemReferenceStringTableCheckConsistency(const SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, bool log)\r\n        {\r\n            using QCol = SQLite::Builder::QualifiedColumn;\r\n\r\n            bool result = true;\r\n\r\n            {\r\n                // Build a select statement to find rows containing references to primaries with nonexistent rowids\r\n                // Such as:\r\n                // Select data.data, data.primary from data left outer join primary on data.primary = primary.rowid where primary.id is null\r\n\r\n                SQLite::Builder::StatementBuilder builder;\r\n                builder.\r\n                    Select({ QCol(tableName, valueName), QCol(tableName, s_SystemReferenceStringTable_PrimaryName) }).\r\n                    From(tableName).\r\n                    LeftOuterJoin(details::PrimaryTable::TableName()).On(QCol(tableName, s_SystemReferenceStringTable_PrimaryName), QCol(details::PrimaryTable::TableName(), SQLite::RowIDName)).\r\n                    Where(QCol(details::PrimaryTable::TableName(), SQLite::RowIDName)).IsNull();\r\n\r\n                SQLite::Statement select = builder.Prepare(connection);\r\n\r\n                while (select.Step())\r\n                {\r\n                    result = false;\r\n\r\n                    if (!log)\r\n                    {\r\n                        break;\r\n                    }\r\n\r\n                    AICLI_LOG(Repo, Info, << \"  [INVALID] \" << tableName << \" [\" << select.GetColumn<std::string>(0) <<\r\n                        \", \" << select.GetColumn<SQLite::rowid_t>(1) << \"] refers to invalid \" << details::PrimaryTable::TableName());\r\n                }\r\n            }\r\n\r\n            if (!result && !log)\r\n            {\r\n                return result;\r\n            }\r\n\r\n            // Build a select statement to find values that contain an embedded null character\r\n            // Such as:\r\n            // Select count(*) from table where instr(value,char(0))>0\r\n            SQLite::Builder::StatementBuilder builder;\r\n            builder.\r\n                Select({ valueName, s_SystemReferenceStringTable_PrimaryName }).\r\n                From(tableName).\r\n                WhereValueContainsEmbeddedNullCharacter(valueName);\r\n\r\n            SQLite::Statement select = builder.Prepare(connection);\r\n\r\n            while (select.Step())\r\n            {\r\n                result = false;\r\n\r\n                if (!log)\r\n                {\r\n                    break;\r\n                }\r\n\r\n                AICLI_LOG(Repo, Info, << \"  [INVALID] value in table [\" << tableName << \"] for primary [\" << select.GetColumn<SQLite::rowid_t>(1) << \"] contains an embedded null character and starts with [\" << select.GetColumn<std::string>(0) << \"]\");\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        bool SystemReferenceStringTableIsEmpty(SQLite::Connection& connection, std::string_view tableName)\r\n        {\r\n            SQLite::Builder::StatementBuilder countBuilder;\r\n            countBuilder.Select(SQLite::Builder::RowCount).From(tableName);\r\n\r\n            SQLite::Statement countStatement = countBuilder.Prepare(connection);\r\n\r\n            THROW_HR_IF(E_UNEXPECTED, !countStatement.Step());\r\n\r\n            return countStatement.GetColumn<int>(0) == 0;\r\n        }\r\n\r\n        int SystemReferenceStringTableBuildSearchStatement(\r\n            SQLite::Builder::StatementBuilder& builder,\r\n            std::string_view tableName,\r\n            std::string_view valueName,\r\n            std::string_view primaryAlias,\r\n            std::string_view valueAlias,\r\n            bool useLike)\r\n        {\r\n            using QCol = SQLite::Builder::QualifiedColumn;\r\n\r\n            // Build a statement like:\r\n            //      SELECT table.package as p, table.value as v from table\r\n            //      where table.value = <value>\r\n            builder.Select().\r\n                Column(s_SystemReferenceStringTable_PrimaryName).As(primaryAlias).\r\n                Column(valueName).As(valueAlias).\r\n                From(tableName).\r\n                Where(valueName);\r\n\r\n            int result = -1;\r\n\r\n            if (useLike)\r\n            {\r\n                builder.Like(SQLite::Builder::Unbound);\r\n                result = builder.GetLastBindIndex();\r\n                builder.Escape(SQLite::EscapeCharForLike);\r\n            }\r\n            else\r\n            {\r\n                builder.Equals(SQLite::Builder::Unbound);\r\n                result = builder.GetLastBindIndex();\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        std::vector<int> SystemReferenceStringTableBuildPairedSearchStatement(\r\n            SQLite::Builder::StatementBuilder& builder,\r\n            std::string_view tableName,\r\n            std::string_view valueName,\r\n            std::string_view pairedTableName,\r\n            std::string_view pairedValueName,\r\n            std::string_view primaryAlias,\r\n            std::string_view valueAlias,\r\n            bool useLike)\r\n        {\r\n            using QCol = SQLite::Builder::QualifiedColumn;\r\n\r\n            // Build a statement like:\r\n            //      SELECT table.package as p, '' as v from table\r\n            //      join paired on table.package = paired.package\r\n            //      where table.value = <value1> and paired.pairedValue = <value2>\r\n            builder.Select().\r\n                Column(QCol(tableName, s_SystemReferenceStringTable_PrimaryName)).As(primaryAlias).\r\n                Value(std::string_view{}).As(valueAlias).\r\n                From(tableName).\r\n                Join(pairedTableName).On(QCol(tableName, s_SystemReferenceStringTable_PrimaryName), QCol(pairedTableName, s_SystemReferenceStringTable_PrimaryName)).\r\n                Where(QCol(tableName, valueName));\r\n\r\n            std::vector<int> result;\r\n\r\n            if (useLike)\r\n            {\r\n                builder.Like(SQLite::Builder::Unbound);\r\n                result.push_back(builder.GetLastBindIndex());\r\n                builder.Escape(SQLite::EscapeCharForLike);\r\n            }\r\n            else\r\n            {\r\n                builder.Equals(SQLite::Builder::Unbound);\r\n                result.push_back(builder.GetLastBindIndex());\r\n            }\r\n\r\n            builder.And(QCol(pairedTableName, pairedValueName));\r\n\r\n            if (useLike)\r\n            {\r\n                builder.Like(SQLite::Builder::Unbound);\r\n                result.push_back(builder.GetLastBindIndex());\r\n                builder.Escape(SQLite::EscapeCharForLike);\r\n            }\r\n            else\r\n            {\r\n                builder.Equals(SQLite::Builder::Unbound);\r\n                result.push_back(builder.GetLastBindIndex());\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/2_0/SystemReferenceStringTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteWrapper.h>\r\n#include <winget/SQLiteStatementBuilder.h>\r\n#include <AppInstallerStrings.h>\r\n#include <string>\r\n#include <string_view>\r\n#include <vector>\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V2_0\r\n{\r\n    namespace details\r\n    {\r\n        // Returns the primary column name.\r\n        std::string_view SystemReferenceStringTableGetPrimaryColumnName();\r\n\r\n        // Create the table.\r\n        void SystemReferenceStringTableCreate(SQLite::Connection& connection, std::string_view tableName, std::string_view valueName);\r\n\r\n        // Drops the table.\r\n        void SystemReferenceStringTableDrop(SQLite::Connection& connection, std::string_view tableName);\r\n\r\n        // Gets all values associated with the given primary id.\r\n        std::vector<std::string> SystemReferenceStringTableGetValuesByPrimaryId(\r\n            const SQLite::Connection& connection,\r\n            std::string_view tableName,\r\n            std::string_view valueName,\r\n            SQLite::rowid_t primaryId);\r\n\r\n        // Ensures that the value exists and inserts mapping entries.\r\n        void SystemReferenceStringTableEnsureExists(\r\n            SQLite::Connection& connection,\r\n            std::string_view tableName,\r\n            std::string_view valueName, \r\n            const std::vector<std::string>& values,\r\n            SQLite::rowid_t primaryId);\r\n\r\n        // Checks the consistency of the index to ensure that every referenced row exists.\r\n        // Returns true if index is consistent; false if it is not.\r\n         bool SystemReferenceStringTableCheckConsistency(const SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, bool log);\r\n\r\n        // Determines if the table is empty.\r\n        bool SystemReferenceStringTableIsEmpty(SQLite::Connection& connection, std::string_view tableName);\r\n\r\n        // Builds the search select statement base on the given value.\r\n        // The return value is the bind index of the value to match against.\r\n        int SystemReferenceStringTableBuildSearchStatement(\r\n            SQLite::Builder::StatementBuilder& builder,\r\n            std::string_view tableName,\r\n            std::string_view valueName,\r\n            std::string_view primaryAlias,\r\n            std::string_view valueAlias,\r\n            bool useLike);\r\n\r\n        // Builds the search select statement base on the given value.\r\n        // The return value is the bind index of the value to match against.\r\n        std::vector<int> SystemReferenceStringTableBuildPairedSearchStatement(\r\n            SQLite::Builder::StatementBuilder& builder,\r\n            std::string_view tableName,\r\n            std::string_view valueName,\r\n            std::string_view pairedTableName,\r\n            std::string_view pairedValueName,\r\n            std::string_view primaryAlias,\r\n            std::string_view valueAlias,\r\n            bool useLike);\r\n    }\r\n\r\n    // A table that represents a value that is 1:N with a primary entry.\r\n    template <typename TableInfo>\r\n    struct SystemReferenceStringTable\r\n    {\r\n        // The name of the table.\r\n        static constexpr std::string_view TableName()\r\n        {\r\n            return TableInfo::TableName();\r\n        }\r\n\r\n        // The value name of the table.\r\n        static constexpr std::string_view ValueName()\r\n        {\r\n            return TableInfo::ValueName();\r\n        }\r\n\r\n        // Creates the table.\r\n        static void Create(SQLite::Connection& connection)\r\n        {\r\n            details::SystemReferenceStringTableCreate(connection, TableInfo::TableName(), TableInfo::ValueName());\r\n        }\r\n\r\n        // Drops the table.\r\n        static void Drop(SQLite::Connection& connection)\r\n        {\r\n            details::SystemReferenceStringTableDrop(connection, TableInfo::TableName());\r\n        }\r\n\r\n        // Gets all values associated with the given primary id.\r\n        static std::vector<std::string> GetValuesByPrimaryId(const SQLite::Connection& connection, SQLite::rowid_t primaryId)\r\n        {\r\n            return details::SystemReferenceStringTableGetValuesByPrimaryId(connection, TableInfo::TableName(), TableInfo::ValueName(), primaryId);\r\n        }\r\n\r\n        // Ensures that all values exist in the data table, and inserts into the mapping table for the given primary id.\r\n        static void EnsureExists(SQLite::Connection& connection, const std::vector<std::string>& values, SQLite::rowid_t primaryId)\r\n        {\r\n            details::SystemReferenceStringTableEnsureExists(connection, TableInfo::TableName(), TableInfo::ValueName(), values, primaryId);\r\n        }\r\n\r\n        // Checks the consistency of the index to ensure that every referenced row exists.\r\n        // Returns true if index is consistent; false if it is not.\r\n        static bool CheckConsistency(const SQLite::Connection& connection, bool log)\r\n        {\r\n            return details::SystemReferenceStringTableCheckConsistency(connection, TableInfo::TableName(), TableInfo::ValueName(), log);\r\n        }\r\n\r\n        // Determines if the table is empty.\r\n        static bool IsEmpty(SQLite::Connection& connection)\r\n        {\r\n            return details::SystemReferenceStringTableIsEmpty(connection, TableInfo::TableName());\r\n        }\r\n\r\n        // Builds the search select statement base on the given value.\r\n        // The return value is the bind index of the value to match against.\r\n        static int BuildSearchStatement(SQLite::Builder::StatementBuilder& builder, std::string_view primaryAlias, std::string_view valueAlias, bool useLike)\r\n        {\r\n            return details::SystemReferenceStringTableBuildSearchStatement(builder, TableInfo::TableName(), TableInfo::ValueName(), primaryAlias, valueAlias, useLike);\r\n        }\r\n\r\n        // Builds the search select statement base on the given value.\r\n        // The return value is the bind index of the value to match against.\r\n        template<typename PairedTable>\r\n        static std::vector<int> BuildPairedSearchStatement(SQLite::Builder::StatementBuilder& builder, std::string_view primaryAlias, std::string_view valueAlias, bool useLike)\r\n        {\r\n            return details::SystemReferenceStringTableBuildPairedSearchStatement(builder, TableInfo::TableName(), TableInfo::ValueName(), PairedTable::TableName(), PairedTable::ValueName(), primaryAlias, valueAlias, useLike);\r\n        }\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/2_0/TagsTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/2_0/OneToManyTableWithMap.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V2_0\r\n{\r\n    namespace details\r\n    {\r\n        using namespace std::string_view_literals;\r\n\r\n        struct TagsTableInfo\r\n        {\r\n            inline static constexpr std::string_view TableName() { return \"tags2\"sv; }\r\n            inline static constexpr std::string_view ValueName() { return \"tag\"sv; }\r\n        };\r\n    }\r\n\r\n    using TagsTable = OneToManyTableWithMap<details::TagsTableInfo>;\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/2_0/UpgradeCodeTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/2_0/SystemReferenceStringTable.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::V2_0\r\n{\r\n    namespace details\r\n    {\r\n        using namespace std::string_view_literals;\r\n\r\n        struct UpgradeCodeTableInfo\r\n        {\r\n            inline static constexpr std::string_view TableName() { return \"upgradecodes2\"sv; }\r\n            inline static constexpr std::string_view ValueName() { return \"upgradecode\"sv; }\r\n        };\r\n    }\r\n\r\n    using UpgradeCodeTable = SystemReferenceStringTable<details::UpgradeCodeTableInfo>;\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/Checkpoint_1_0/CheckpointDataTable.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"CheckpointDataTable.h\"\n#include <winget/SQLiteStatementBuilder.h>\n\nnamespace AppInstaller::Repository::Microsoft::Schema::Checkpoint_V1_0\n{\n    using namespace SQLite;\n    using namespace std::string_view_literals;\n    static constexpr std::string_view s_CheckpointDataTable_Table_Name = \"CheckpointData\"sv;\n    static constexpr std::string_view s_CheckpointDataTable_CheckpointId_Column = \"CheckpointId\"sv;\n    static constexpr std::string_view s_CheckpointDataTable_ContextData_Column = \"ContextData\"sv;\n    static constexpr std::string_view s_CheckpointDataTable_Name_Column = \"Name\"sv;\n    static constexpr std::string_view s_CheckpointDataTable_Value_Column = \"Value\"sv;\n    static constexpr std::string_view s_CheckpointDataTable_Index_Column = \"Index\"sv;\n\n    namespace\n    {\n        SQLite::rowid_t SetNamedValue(SQLite::Connection& connection, std::string_view name, std::string_view value)\n        {\n            SQLite::Builder::StatementBuilder builder;\n            builder.InsertInto(s_CheckpointDataTable_Table_Name)\n                .Columns({ s_CheckpointDataTable_CheckpointId_Column,\n                    s_CheckpointDataTable_ContextData_Column,\n                    s_CheckpointDataTable_Name_Column,\n                    s_CheckpointDataTable_Value_Column,\n                    s_CheckpointDataTable_Index_Column})\n                .Values(name, value);\n\n            builder.Execute(connection);\n            return connection.GetLastInsertRowID();\n        }\n\n        std::string GetNamedValue(SQLite::Connection& connection, std::string_view name)\n        {\n            SQLite::Builder::StatementBuilder builder;\n            builder.Select({ s_CheckpointDataTable_Value_Column })\n                .From(s_CheckpointDataTable_Table_Name).Where(s_CheckpointDataTable_Name_Column).Equals(name);\n\n            SQLite::Statement statement = builder.Prepare(connection);\n            THROW_HR_IF(E_NOT_SET, !statement.Step());\n            return statement.GetColumn<std::string>(0);\n        }\n    }\n\n    std::string_view CheckpointDataTable::TableName()\n    {\n        return s_CheckpointDataTable_Table_Name;\n    }\n\n    void CheckpointDataTable::Create(SQLite::Connection& connection)\n    {\n        using namespace SQLite::Builder;\n\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"createCheckpointDataTable_v1_0\");\n\n        StatementBuilder createTableBuilder;\n        createTableBuilder.CreateTable(s_CheckpointDataTable_Table_Name).BeginColumns();\n        createTableBuilder.Column(ColumnBuilder(s_CheckpointDataTable_CheckpointId_Column, Type::Int).NotNull());\n        createTableBuilder.Column(ColumnBuilder(s_CheckpointDataTable_ContextData_Column, Type::Int).NotNull());\n        createTableBuilder.Column(ColumnBuilder(s_CheckpointDataTable_Name_Column, Type::Text).NotNull());\n        createTableBuilder.Column(ColumnBuilder(s_CheckpointDataTable_Value_Column, Type::Text));\n        createTableBuilder.Column(ColumnBuilder(s_CheckpointDataTable_Index_Column, Type::Int).NotNull());\n\n        PrimaryKeyBuilder pkBuilder;\n        pkBuilder.Column(s_CheckpointDataTable_CheckpointId_Column);\n        pkBuilder.Column(s_CheckpointDataTable_ContextData_Column);\n        pkBuilder.Column(s_CheckpointDataTable_Name_Column);\n        pkBuilder.Column(s_CheckpointDataTable_Index_Column);\n\n        createTableBuilder.Column(pkBuilder).EndColumns();\n        createTableBuilder.Execute(connection);\n        savepoint.Commit();\n    }\n\n    bool CheckpointDataTable::IsEmpty(SQLite::Connection& connection)\n    {\n        SQLite::Builder::StatementBuilder builder;\n        builder.Select(SQLite::Builder::RowCount).From(s_CheckpointDataTable_Table_Name);\n\n        SQLite::Statement countStatement = builder.Prepare(connection);\n\n        THROW_HR_IF(E_UNEXPECTED, !countStatement.Step());\n\n        return (countStatement.GetColumn<int>(0) == 0);\n    }\n\n    std::vector<int> CheckpointDataTable::GetAvailableData(SQLite::Connection& connection, SQLite::rowid_t checkpointId)\n    {\n        SQLite::Builder::StatementBuilder builder;\n        builder.Select(s_CheckpointDataTable_ContextData_Column).From(s_CheckpointDataTable_Table_Name).Where(s_CheckpointDataTable_CheckpointId_Column);\n        builder.Equals(checkpointId);\n\n        SQLite::Statement select = builder.Prepare(connection);\n\n        std::vector<int> availableData;\n\n        while (select.Step())\n        {\n            availableData.emplace_back(select.GetColumn<int>(0));\n        }\n\n        return availableData;\n    }\n\n    SQLite::rowid_t CheckpointDataTable::AddCheckpointData(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int contextData, std::string_view name, std::string_view value, int index)\n    {\n        SQLite::Builder::StatementBuilder builder;\n\n        if (value.empty())\n        {\n            builder.InsertInto(s_CheckpointDataTable_Table_Name)\n                .Columns({ s_CheckpointDataTable_CheckpointId_Column,\n                    s_CheckpointDataTable_ContextData_Column,\n                    s_CheckpointDataTable_Name_Column,\n                    s_CheckpointDataTable_Index_Column })\n                .Values(checkpointId, contextData, name, index);\n        }\n        else\n        {\n            builder.InsertInto(s_CheckpointDataTable_Table_Name)\n                .Columns({ s_CheckpointDataTable_CheckpointId_Column,\n                    s_CheckpointDataTable_ContextData_Column,\n                    s_CheckpointDataTable_Name_Column,\n                    s_CheckpointDataTable_Value_Column,\n                    s_CheckpointDataTable_Index_Column })\n                .Values(checkpointId, contextData, name, value, index);\n        }\n\n        builder.Execute(connection);\n        return connection.GetLastInsertRowID();\n    }\n\n    bool CheckpointDataTable::HasDataField(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int type, std::string_view name)\n    {\n        SQLite::Builder::StatementBuilder builder;\n        builder.Select(SQLite::Builder::RowCount).From(s_CheckpointDataTable_Table_Name).Where(s_CheckpointDataTable_CheckpointId_Column);\n        builder.Equals(checkpointId).And(s_CheckpointDataTable_ContextData_Column).Equals(type).And(s_CheckpointDataTable_Name_Column).Equals(name);\n\n        SQLite::Statement countStatement = builder.Prepare(connection);\n\n        THROW_HR_IF(E_UNEXPECTED, !countStatement.Step());\n\n        return (countStatement.GetColumn<int>(0) == 0);\n    }\n\n    std::vector<std::string> CheckpointDataTable::GetDataFields(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int type)\n    {\n        SQLite::Builder::StatementBuilder builder;\n        builder.Select(s_CheckpointDataTable_Name_Column).From(s_CheckpointDataTable_Table_Name).Where(s_CheckpointDataTable_CheckpointId_Column);\n        builder.Equals(checkpointId).And(s_CheckpointDataTable_ContextData_Column).Equals(type);\n\n        SQLite::Statement select = builder.Prepare(connection);\n\n        std::vector<std::string> fields;\n\n        while (select.Step())\n        {\n            fields.emplace_back(select.GetColumn<std::string>(0));\n        }\n\n        return fields;\n    }\n\n    std::vector<std::string> CheckpointDataTable::GetDataValuesByFieldName(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int contextData, std::string_view name)\n    {\n        SQLite::Builder::StatementBuilder builder;\n        builder.Select(s_CheckpointDataTable_Value_Column).From(s_CheckpointDataTable_Table_Name).Where(s_CheckpointDataTable_CheckpointId_Column);\n        builder.Equals(checkpointId).And(s_CheckpointDataTable_ContextData_Column).Equals(contextData).And(s_CheckpointDataTable_Name_Column).Equals(name);\n\n        SQLite::Statement select = builder.Prepare(connection);\n\n        std::vector<std::string> values;\n\n        while (select.Step())\n        {\n            values.emplace_back(select.GetColumn<std::string>(0));\n        }\n\n        return values;\n    }\n\n    std::string CheckpointDataTable::GetDataValue(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int type)\n    {\n        SQLite::Builder::StatementBuilder builder;\n        builder.Select(s_CheckpointDataTable_Value_Column).From(s_CheckpointDataTable_Table_Name).Where(s_CheckpointDataTable_CheckpointId_Column);\n        builder.Equals(checkpointId).And(s_CheckpointDataTable_ContextData_Column).Equals(type);\n\n        SQLite::Statement select = builder.Prepare(connection);\n\n        if (select.Step())\n        {\n            return select.GetColumn<std::string>(0);\n        }\n        else\n        {\n            return {};\n        }\n    }\n\n    void CheckpointDataTable::RemoveDataType(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int contextData)\n    {\n        SQLite::Builder::StatementBuilder builder;\n        builder.DeleteFrom(s_CheckpointDataTable_Table_Name).Where(s_CheckpointDataTable_CheckpointId_Column).Equals(checkpointId)\n            .And(s_CheckpointDataTable_ContextData_Column).Equals(contextData);\n        builder.Execute(connection);\n    }\n}"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/Checkpoint_1_0/CheckpointDataTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include <winget/SQLiteWrapper.h>\n#include <string_view>\n#include <vector>\n\nnamespace AppInstaller::Repository::Microsoft::Schema::Checkpoint_V1_0\n{\n    struct CheckpointDataTable\n    {\n        // Get the table name.\n        static std::string_view TableName();\n\n        // Creates the table with named indices.\n        static void Create(SQLite::Connection& connection);\n\n        // Gets a value indicating whether the table is empty.\n        static bool IsEmpty(SQLite::Connection& connection);\n\n        // Get all available context data.\n        static std::vector<int> GetAvailableData(SQLite::Connection& connection, SQLite::rowid_t checkpointId);\n\n        // Adds a context data for a checkpoint. Index is used to represent the item number if the context data has more than one value.\n        static SQLite::rowid_t AddCheckpointData(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int contextData, std::string_view name, std::string_view value, int index = 1);\n\n        // Gets all fields for a context data.\n        static std::vector<std::string> GetDataFields(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int type);\n\n        // Gets the context data values by property name from a checkpoint id.\n        static std::vector<std::string> GetDataValuesByFieldName(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int contextData, std::string_view name);\n\n        // Returns a boolean value indicating whether a field exists for a context data.\n        static bool HasDataField(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int type, std::string_view name);\n\n        // Removes the context data by checkpoint id.\n        static void RemoveDataType(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int contextData);\n\n        // Gets a single data value for a context data.\n        static std::string GetDataValue(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int type);\n    };\n}"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/Checkpoint_1_0/CheckpointDatabaseInterface.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"Microsoft/Schema/ICheckpointDatabase.h\"\n\nnamespace AppInstaller::Repository::Microsoft::Schema::Checkpoint_V1_0\n{\n    struct CheckpointDatabaseInterface : public ICheckpointDatabase\n    {\n        // Version 1.0\n        SQLite::Version GetVersion() const override;\n        void CreateTables(SQLite::Connection& connection) override;\n\n    private:\n        bool IsEmpty(SQLite::Connection& connection) override;\n        SQLite::rowid_t AddCheckpoint(SQLite::Connection& connection, std::string_view checkpointName) override;\n        std::vector<SQLite::rowid_t> GetCheckpointIds(SQLite::Connection& connection) override;\n        std::vector<int> GetCheckpointDataTypes(SQLite::Connection& connection, SQLite::rowid_t checkpointId) override;\n        std::vector<std::string> GetCheckpointDataFields(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int dataType) override;\n        void SetCheckpointDataValues(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int dataType, std::string_view name, const std::vector<std::string>& values) override;\n        std::optional<std::vector<std::string>> GetCheckpointDataFieldValues(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int dataType, std::string_view name) override;\n        void RemoveCheckpointDataType(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int dataType) override;\n    };\n}"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/Checkpoint_1_0/CheckpointDatabaseInterface_1_0.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"Microsoft/Schema/Checkpoint_1_0/CheckpointDatabaseInterface.h\"\n#include \"Microsoft/Schema/Checkpoint_1_0/CheckpointDataTable.h\"\n#include \"Microsoft/Schema/Checkpoint_1_0/CheckpointTable.h\"\n\nnamespace AppInstaller::Repository::Microsoft::Schema::Checkpoint_V1_0\n{\n    SQLite::Version CheckpointDatabaseInterface::GetVersion() const\n    {\n        return { 1, 0 };\n    }\n\n    void CheckpointDatabaseInterface::CreateTables(SQLite::Connection& connection)\n    {\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"createCheckpointTables_v1_0\");\n        Checkpoint_V1_0::CheckpointTable::Create(connection);\n        Checkpoint_V1_0::CheckpointDataTable::Create(connection);\n        savepoint.Commit();\n    }\n\n    bool CheckpointDatabaseInterface::IsEmpty(SQLite::Connection& connection)\n    {\n        return CheckpointDataTable::IsEmpty(connection);\n    }\n\n    SQLite::rowid_t CheckpointDatabaseInterface::AddCheckpoint(SQLite::Connection& connection, std::string_view checkpointName)\n    {\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"addCheckpoint_v1_0\");\n        SQLite::rowid_t checkpointId = CheckpointTable::AddCheckpoint(connection, checkpointName);\n        savepoint.Commit();\n        return checkpointId;\n    }\n\n    std::vector<SQLite::rowid_t> CheckpointDatabaseInterface::GetCheckpointIds(SQLite::Connection& connection)\n    {\n        return CheckpointTable::GetCheckpointIds(connection);\n    }\n\n    std::vector<int> CheckpointDatabaseInterface::GetCheckpointDataTypes(SQLite::Connection& connection, SQLite::rowid_t checkpointId)\n    {\n        return CheckpointDataTable::GetAvailableData(connection, checkpointId);\n    }\n\n    std::vector<std::string> CheckpointDatabaseInterface::GetCheckpointDataFields(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int dataType)\n    {\n        return CheckpointDataTable::GetDataFields(connection, checkpointId, dataType);\n    }\n\n    void CheckpointDatabaseInterface::SetCheckpointDataValues(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int dataType, std::string_view name, const std::vector<std::string>& values)\n    {\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"setCheckpointData_v1_0\");\n\n        if (values.empty())\n        {\n            CheckpointDataTable::AddCheckpointData(connection, checkpointId, dataType, name, {}, 0);\n        }\n        else\n        {\n            int index = 0;\n\n            for (const auto& value : values)\n            {\n                CheckpointDataTable::AddCheckpointData(connection, checkpointId, dataType, name, value, index);\n                index++;\n            }\n        }\n\n        savepoint.Commit();\n    }\n\n    std::optional<std::vector<std::string>> CheckpointDatabaseInterface::GetCheckpointDataFieldValues(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int dataType, std::string_view name)\n    {\n        return CheckpointDataTable::GetDataValuesByFieldName(connection, checkpointId, dataType, name);\n    }\n\n    void CheckpointDatabaseInterface::RemoveCheckpointDataType(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int dataType)\n    {\n        CheckpointDataTable::RemoveDataType(connection, checkpointId, dataType);\n    }\n}"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/Checkpoint_1_0/CheckpointTable.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"CheckpointTable.h\"\n#include <winget/SQLiteStatementBuilder.h>\n\nnamespace AppInstaller::Repository::Microsoft::Schema::Checkpoint_V1_0\n{\n    using namespace std::string_view_literals;\n    static constexpr std::string_view s_CheckpointTable_Table_Name = \"Checkpoints\"sv;\n    static constexpr std::string_view s_CheckpointTable_Index_Name = \"Checkpoints_pkindex\"sv;\n    static constexpr std::string_view s_CheckpointTable_Name_Column = \"Name\";\n    static constexpr std::string_view s_CheckpointTable_CreationTime_Column = \"CreationTime\";\n\n    std::string_view CheckpointTable::TableName()\n    {\n        return s_CheckpointTable_Table_Name;\n    }\n    \n    void CheckpointTable::Create(SQLite::Connection& connection)\n    {\n        using namespace SQLite::Builder;\n\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"createCheckpointTable_v1_0\");\n\n        StatementBuilder createTableBuilder;\n        createTableBuilder.CreateTable(s_CheckpointTable_Table_Name).Columns({\n            ColumnBuilder(s_CheckpointTable_Index_Name, Type::Integer).PrimaryKey(),\n            ColumnBuilder(s_CheckpointTable_Name_Column, Type::Text).NotNull(),\n            ColumnBuilder(s_CheckpointTable_CreationTime_Column, Type::Int64).NotNull()\n            });\n\n        createTableBuilder.Execute(connection);\n\n        savepoint.Commit();\n    }\n\n    std::vector<SQLite::rowid_t> CheckpointTable::GetCheckpointIds(SQLite::Connection& connection)\n    {\n        SQLite::Builder::StatementBuilder builder;\n        builder.Select(SQLite::RowIDName).From(s_CheckpointTable_Table_Name).OrderBy(SQLite::RowIDName).Descending();\n\n        SQLite::Statement select = builder.Prepare(connection);\n\n        std::vector<SQLite::rowid_t> checkpoints;\n\n        while (select.Step())\n        {\n            checkpoints.emplace_back(select.GetColumn<SQLite::rowid_t>(0));\n        }\n\n        return checkpoints;\n    }\n\n    SQLite::rowid_t CheckpointTable::AddCheckpoint(SQLite::Connection& connection, std::string_view checkpointName)\n    {\n        SQLite::Builder::StatementBuilder builder;\n        builder.InsertInto(s_CheckpointTable_Table_Name)\n            .Columns({ s_CheckpointTable_Name_Column,\n                s_CheckpointTable_CreationTime_Column })\n            .Values(checkpointName, Utility::GetCurrentUnixEpoch());\n\n        builder.Execute(connection);\n        return connection.GetLastInsertRowID();\n    }\n}"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/Checkpoint_1_0/CheckpointTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include <winget/SQLiteWrapper.h>\n#include <vector>\n#include <optional>\n\nnamespace AppInstaller::Repository::Microsoft::Schema::Checkpoint_V1_0\n{\n    struct CheckpointTable\n    {\n        // Get the table name.\n        static std::string_view TableName();\n\n        // Creates the table with named indices.\n        static void Create(SQLite::Connection& connection);\n\n        // Returns all checkpoint ids in descending (newest at the front) order.\n        static std::vector<SQLite::rowid_t> GetCheckpointIds(SQLite::Connection& connection);\n\n        // Adds a checkpoint.\n        static SQLite::rowid_t AddCheckpoint(SQLite::Connection& connection, std::string_view checkpointName);\n    };\n}"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/ICheckpointDatabase.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include <winget/SQLiteWrapper.h>\n#include <winget/SQLiteVersion.h>\n\nnamespace AppInstaller::Repository::Microsoft::Schema\n{\n    struct ICheckpointDatabase\n    {\n        virtual ~ICheckpointDatabase() = default;\n\n        // Gets the schema version that this index interface is built for.\n        virtual SQLite::Version GetVersion() const = 0;\n\n        // Creates all of the version dependent tables within the database.\n        virtual void CreateTables(SQLite::Connection& connection) = 0;\n\n        // Version 1.0\n        // Returns a bool value indicating whether all checkpoint tables are empty.\n        virtual bool IsEmpty(SQLite::Connection& connection) = 0;\n\n        // Returns all checkpoint ids in descending (newest at the front) order.\n        virtual std::vector<SQLite::rowid_t> GetCheckpointIds(SQLite::Connection& connection) = 0;\n         \n        // Adds a new checkpoint to the Checkpoint table.\n        virtual SQLite::rowid_t AddCheckpoint(SQLite::Connection& connection, std::string_view checkpointName) = 0;\n\n        // Gets the data types associated with a checkpoint id.\n        virtual std::vector<int> GetCheckpointDataTypes(SQLite::Connection& connection, SQLite::rowid_t checkpointId) = 0;\n\n        // Sets the field values for a checkpoint data type.\n        virtual void SetCheckpointDataValues(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int dataType, std::string_view name, const std::vector<std::string>& values) = 0;\n\n        // Gets all field names for a checkpoint data type.\n        virtual std::vector<std::string> GetCheckpointDataFields(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int dataType) = 0;\n\n        // Gets all field values for a checkpoint data type.\n        virtual std::optional<std::vector<std::string>> GetCheckpointDataFieldValues(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int dataType, std::string_view name) = 0;\n    \n        // Removes all values for a checkpoint data type.\n        virtual void RemoveCheckpointDataType(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int dataType) = 0;\n    };\n}"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/IPinningIndex.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteWrapper.h>\r\n#include <winget/SQLiteVersion.h>\r\n#include \"winget/Pin.h\"\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema\r\n{\r\n    struct IPinningIndex\r\n    {\r\n        virtual ~IPinningIndex() = default;\r\n\r\n        // Gets the schema version that this index interface is built for.\r\n        virtual SQLite::Version GetVersion() const = 0;\r\n\r\n        // Creates all of the version dependent tables within the database.\r\n        virtual void CreateTables(SQLite::Connection& connection) = 0;\r\n\r\n        // Version 1.0\r\n        // Adds a pin to the index.\r\n        virtual SQLite::rowid_t AddPin(SQLite::Connection& connection, const Pinning::Pin& pin) = 0;\r\n\r\n        // Updates an existing pin in the index.\r\n        // The return value indicates whether the index was modified by the function.\r\n        virtual std::pair<bool, SQLite::rowid_t> UpdatePin(SQLite::Connection& connection, const Pinning::Pin& pin) = 0;\r\n\r\n        // Removes a pin from the index.\r\n        virtual SQLite::rowid_t RemovePin(SQLite::Connection& connection, const Pinning::PinKey& pinKey) = 0;\r\n\r\n        // Returns the current pin for a given package if it exists.\r\n        virtual std::optional<Pinning::Pin> GetPin(SQLite::Connection& connection, const Pinning::PinKey& pinKey) = 0;\r\n\r\n        // Returns a vector containing all the existing pins.\r\n        virtual std::vector<Pinning::Pin> GetAllPins(SQLite::Connection& connection) = 0;\r\n\r\n        // Removes all the pins from a given source, or from all sources if none is specified.\r\n        // Returns a value indicating whether any pin was deleted.\r\n        virtual bool ResetAllPins(SQLite::Connection& connection, std::string_view sourceId) = 0;\r\n    };\r\n}"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/IPortableIndex.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteWrapper.h>\r\n#include <winget/SQLiteVersion.h>\r\n#include \"winget/PortableFileEntry.h\"\r\n#include <filesystem>\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema\r\n{\r\n    struct IPortableIndex\r\n    {\r\n        virtual ~IPortableIndex() = default;\r\n\r\n        // Gets the schema version that this index interface is built for.\r\n        virtual SQLite::Version GetVersion() const = 0;\r\n\r\n        // Creates all of the version dependent tables within the database.\r\n        virtual void CreateTable(SQLite::Connection& connection) = 0;\r\n\r\n        // Version 1.0\r\n        // Adds a portable file to the index.\r\n        virtual SQLite::rowid_t AddPortableFile(SQLite::Connection& connection, const Portable::PortableFileEntry& file) = 0;\r\n\r\n        // Removes a portable file from the index.\r\n        virtual SQLite::rowid_t RemovePortableFile(SQLite::Connection& connection, const Portable::PortableFileEntry& file) = 0;\r\n\r\n        // Updates the file with matching FilePath in the index.\r\n        // The return value indicates whether the index was modified by the function.\r\n        virtual std::pair<bool, SQLite::rowid_t> UpdatePortableFile(SQLite::Connection& connection, const Portable::PortableFileEntry& file) = 0;\r\n\r\n        // Returns a bool value indicating whether the PortableFile already exists in the index.\r\n        virtual bool Exists(SQLite::Connection& connection, const Portable::PortableFileEntry& file) = 0;\r\n\r\n        // Returns a bool value indicating whether the index is empty.\r\n        virtual bool IsEmpty(SQLite::Connection& connection) = 0;\r\n\r\n        // Returns a vector including all the portable files recorded in the index.\r\n        virtual std::vector<Portable::PortableFileEntry> GetAllPortableFiles(SQLite::Connection& connection) = 0;\r\n    };\r\n}"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/ISQLiteIndex.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Microsoft/Schema/ISQLiteIndex.h\"\r\n\r\n#include \"Microsoft/Schema/1_0/Interface.h\"\r\n#include \"Microsoft/Schema/1_1/Interface.h\"\r\n#include \"Microsoft/Schema/1_2/Interface.h\"\r\n#include \"Microsoft/Schema/1_3/Interface.h\"\r\n#include \"Microsoft/Schema/1_4/Interface.h\"\r\n#include \"Microsoft/Schema/1_5/Interface.h\"\r\n#include \"Microsoft/Schema/1_6/Interface.h\"\r\n#include \"Microsoft/Schema/1_7/Interface.h\"\r\n#include \"Microsoft/Schema/2_0/Interface.h\"\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema\r\n{\r\n    void ISQLiteIndex::PrepareForPackaging(const SQLiteIndexContext& context)\r\n    {\r\n        PrepareForPackaging(context.Connection);\r\n    }\r\n\r\n    void ISQLiteIndex::SetProperty(SQLite::Connection&, Property, const std::string&)\r\n    {\r\n        THROW_WIN32(ERROR_NOT_SUPPORTED);\r\n    }\r\n\r\n    std::unique_ptr<ISQLiteIndex> CreateISQLiteIndex(const SQLite::Version& version)\r\n    {\r\n        if (version.MajorVersion == 1 ||\r\n            version.IsLatest())\r\n        {\r\n            constexpr std::array<std::unique_ptr<ISQLiteIndex>(*)(), 8> versionCreatorMap =\r\n            {\r\n                []() { return std::unique_ptr<ISQLiteIndex>(std::make_unique<V1_0::Interface>()); },\r\n                []() { return std::unique_ptr<ISQLiteIndex>(std::make_unique<V1_1::Interface>()); },\r\n                []() { return std::unique_ptr<ISQLiteIndex>(std::make_unique<V1_2::Interface>()); },\r\n                []() { return std::unique_ptr<ISQLiteIndex>(std::make_unique<V1_3::Interface>()); },\r\n                []() { return std::unique_ptr<ISQLiteIndex>(std::make_unique<V1_4::Interface>()); },\r\n                []() { return std::unique_ptr<ISQLiteIndex>(std::make_unique<V1_5::Interface>()); },\r\n                []() { return std::unique_ptr<ISQLiteIndex>(std::make_unique<V1_6::Interface>()); },\r\n                []() { return std::unique_ptr<ISQLiteIndex>(std::make_unique<V1_7::Interface>()); },\r\n            };\r\n\r\n            return versionCreatorMap[std::min(static_cast<size_t>(version.MinorVersion), versionCreatorMap.size() - 1)]();\r\n        }\r\n\r\n        // Version 2.0 is designed solely for minimizing the size of the index for transport.\r\n        // Unless it is prepared for packaging, it will be identical to a 1.N index.\r\n        if (version.MajorVersion == 2)\r\n        {\r\n            constexpr std::array<std::unique_ptr<ISQLiteIndex>(*)(), 1> versionCreatorMap =\r\n            {\r\n                []() { return std::unique_ptr<ISQLiteIndex>(std::make_unique<V2_0::Interface>()); },\r\n            };\r\n\r\n            return versionCreatorMap[std::min(static_cast<size_t>(version.MinorVersion), versionCreatorMap.size() - 1)]();\r\n        }\r\n\r\n        // We do not have the capacity to operate on this schema version\r\n        THROW_WIN32(ERROR_NOT_SUPPORTED);\r\n    }\r\n\r\n    std::vector<MatchType> GetDefaultMatchTypeOrder(MatchType type)\r\n    {\r\n        switch (type)\r\n        {\r\n        case MatchType::Exact:\r\n            return { MatchType::Exact };\r\n        case MatchType::CaseInsensitive:\r\n            return { MatchType::CaseInsensitive };\r\n        case MatchType::StartsWith:\r\n            return { MatchType::CaseInsensitive, MatchType::StartsWith };\r\n        case MatchType::Substring:\r\n            return { MatchType::CaseInsensitive, MatchType::Substring };\r\n        case MatchType::Wildcard:\r\n            return { MatchType::Wildcard };\r\n        case MatchType::Fuzzy:\r\n            return { MatchType::CaseInsensitive, MatchType::Fuzzy };\r\n        case MatchType::FuzzySubstring:\r\n            return { MatchType::CaseInsensitive, MatchType::Fuzzy, MatchType::Substring, MatchType::FuzzySubstring };\r\n        default:\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/ISQLiteIndex.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteWrapper.h>\r\n#include <winget/SQLiteVersion.h>\r\n#include \"ISource.h\"\r\n#include \"Microsoft/Schema/SQLiteIndexContextData.h\"\r\n#include <AppInstallerVersions.h>\r\n#include <winget/Manifest.h>\r\n#include <winget/NameNormalization.h>\r\n\r\n#include <filesystem>\r\n#include <optional>\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema\r\n{\r\n    // Contains the database connection and any other data that the owning index might need to pass in.\r\n    struct SQLiteIndexContext\r\n    {\r\n        SQLite::Connection& Connection;\r\n        SQLiteIndexContextData& Data;\r\n    };\r\n\r\n    // The common interface used to interact with all schema versions of the index.\r\n    struct ISQLiteIndex\r\n    {\r\n        virtual ~ISQLiteIndex() = default;\r\n\r\n        // The non-version specific return value of Search.\r\n        // New fields must have initializers to their down-schema defaults.\r\n        struct SearchResult\r\n        {\r\n            std::vector<std::pair<SQLite::rowid_t, PackageMatchFilter>> Matches;\r\n            bool Truncated = false;\r\n        };\r\n\r\n        // The non-version specific return value of GetMetadataByManifestId.\r\n        using MetadataResult = std::vector<std::pair<PackageVersionMetadata, std::string>>;\r\n\r\n        // Version 1.0\r\n\r\n        // Gets the schema version that this index interface is built for.\r\n        virtual SQLite::Version GetVersion() const = 0;\r\n\r\n        // Options for creating the index.\r\n        enum class CreateOptions\r\n        {\r\n            // Standard\r\n            None = 0x0,\r\n            // Enable support for passing in nullopt values to Add/UpdateManifest\r\n            SupportPathless = 0x1,\r\n            // Disable support for dependencies\r\n            DisableDependenciesSupport = 0x2,\r\n            // Use maximum page size in SQLite.\r\n            // This was part of an exploration of ways to reduce file size but ultimately led to a larger\r\n            // compressed file with a worse ratio (limited testing but was significant enough to warrant abandonment).\r\n            // Leaving this here as a valid null result to prevent future maintainers from needing to investigate.\r\n            LargePageSize = 0x4,\r\n        };\r\n\r\n        // Contains both the object representation of the version key and the rows.\r\n        struct VersionKey\r\n        {\r\n            Utility::VersionAndChannel VersionAndChannel;\r\n            SQLite::rowid_t ManifestId;\r\n\r\n            bool operator<(const VersionKey& other) const { return VersionAndChannel < other.VersionAndChannel; }\r\n        };\r\n\r\n        // Creates all of the version dependent tables within the database.\r\n        virtual void CreateTables(SQLite::Connection& connection, CreateOptions options) = 0;\r\n\r\n        // Adds the manifest at the repository relative path to the index.\r\n        virtual SQLite::rowid_t AddManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest, const std::optional<std::filesystem::path>& relativePath) = 0;\r\n\r\n        // Updates the manifest with matching { Id, Version, Channel } in the index.\r\n        // The return value indicates whether the index was modified by the function.\r\n        virtual std::pair<bool, SQLite::rowid_t> UpdateManifest(\r\n            SQLite::Connection& connection,\r\n            const Manifest::Manifest& manifest,\r\n            const std::optional<std::filesystem::path>& relativePath) = 0;\r\n\r\n        // Removes the manifest with matching { Id, Version, Channel } from the index.\r\n        virtual SQLite::rowid_t RemoveManifest(SQLite::Connection& connection, const Manifest::Manifest& manifest) = 0;\r\n\r\n        // Removes the manifest with the given id.\r\n        virtual void RemoveManifestById(SQLite::Connection& connection, SQLite::rowid_t manifestId) = 0;\r\n\r\n        // Removes data that is no longer needed for an index that is to be published.\r\n        virtual void PrepareForPackaging(SQLite::Connection& connection) = 0;\r\n\r\n        // Removes data that is no longer needed for an index that is to be published.\r\n        virtual void PrepareForPackaging(const SQLiteIndexContext& context);\r\n\r\n        // Checks the consistency of the index to ensure that every referenced row exists.\r\n        // Returns true if index is consistent; false if it is not.\r\n        virtual bool CheckConsistency(const SQLite::Connection& connection, bool log) const = 0;\r\n\r\n        // Performs a search based on the given criteria.\r\n        virtual SearchResult Search(const SQLite::Connection& connection, const SearchRequest& request) const = 0;\r\n\r\n        // Gets the string for the given property and primary id, if present.\r\n        virtual std::optional<std::string> GetPropertyByPrimaryId(const SQLite::Connection& connection, SQLite::rowid_t primaryId, PackageVersionProperty property) const = 0;\r\n\r\n        // Gets the string values for the given property and primary id, if present.\r\n        virtual std::vector<std::string> GetMultiPropertyByPrimaryId(const SQLite::Connection& connection, SQLite::rowid_t primaryId, PackageVersionMultiProperty property) const = 0;\r\n\r\n        // Gets the manifest id for the given { id, version, channel }, if present.\r\n        // If version is empty, gets the value for the 'latest' version.\r\n        virtual std::optional<SQLite::rowid_t> GetManifestIdByKey(const SQLite::Connection& connection, SQLite::rowid_t id, std::string_view version, std::string_view channel) const = 0;\r\n\r\n        // Gets the manifest id for the given manifest, if present.\r\n        virtual std::optional<SQLite::rowid_t> GetManifestIdByManifest(const SQLite::Connection& connection, const Manifest::Manifest& manifest) const = 0;\r\n\r\n        // Gets all versions and channels for the given id.\r\n        virtual std::vector<VersionKey> GetVersionKeysById(const SQLite::Connection& connection, SQLite::rowid_t id) const = 0;\r\n\r\n        // Version 1.1\r\n\r\n        // Gets the string for the given metadata and manifest id, if present.\r\n        virtual MetadataResult GetMetadataByManifestId(const SQLite::Connection& connection, SQLite::rowid_t manifestId) const = 0;\r\n\r\n        // Sets the string for the given metadata and manifest id.\r\n        virtual void SetMetadataByManifestId(SQLite::Connection& connection, SQLite::rowid_t manifestId, PackageVersionMetadata metadata, std::string_view value) = 0;\r\n\r\n        // Version 1.2\r\n\r\n        // Normalizes a name using the internal rules used by the index.\r\n        // Largely a utility function; should not be used to do work on behalf of the index by the caller.\r\n        virtual Utility::NormalizedName NormalizeName(std::string_view name, std::string_view publisher) const = 0;\r\n\r\n        // Version 1.4\r\n\r\n        // Get all the dependencies for a specific manifest.\r\n        virtual std::set<std::pair<SQLite::rowid_t, Utility::NormalizedString>> GetDependenciesByManifestRowId(const SQLite::Connection& connection, SQLite::rowid_t manifestRowId) const = 0;\r\n\r\n        virtual std::vector<std::pair<SQLite::rowid_t, Utility::NormalizedString>> GetDependentsById(const SQLite::Connection& connection, AppInstaller::Manifest::string_t packageId) const = 0;\r\n\r\n        // Version 1.7\r\n\r\n        // Drops all tables that would have been created.\r\n        virtual void DropTables(SQLite::Connection& connection) = 0;\r\n\r\n        // Version 2.0\r\n\r\n        // Migrates from the current interface given.\r\n        // Returns true if supported; false if not.\r\n        // Throws on errors that occur during an attempted migration.\r\n        virtual bool MigrateFrom(SQLite::Connection& connection, const ISQLiteIndex* current) = 0;\r\n\r\n        // Set the property value.\r\n        virtual void SetProperty(SQLite::Connection& connection, Property property, const std::string& value);\r\n    };\r\n\r\n    DEFINE_ENUM_FLAG_OPERATORS(ISQLiteIndex::CreateOptions);\r\n\r\n    // Creates the ISQLiteIndex interface object for the given version.\r\n    std::unique_ptr<ISQLiteIndex> CreateISQLiteIndex(const SQLite::Version& version);\r\n\r\n    // For a given match type, gets the set of match types that are more specific subsets of it.\r\n    std::vector<MatchType> GetDefaultMatchTypeOrder(MatchType type);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/Pinning_1_0/PinTable.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"PinTable.h\"\r\n#include <winget/SQLiteStatementBuilder.h>\r\n#include \"Microsoft/Schema/IPinningIndex.h\"\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::Pinning_V1_0\r\n{\r\n    namespace\r\n    {\r\n        std::optional<Pinning::Pin> GetPinFromRow(\r\n            std::string_view packageId,\r\n            std::string_view sourceId,\r\n            Pinning::PinType type,\r\n            std::string_view version)\r\n\r\n        {\r\n            switch (type)\r\n            {\r\n            case Pinning::PinType::Blocking:\r\n                return Pinning::Pin::CreateBlockingPin({ packageId, sourceId });\r\n            case Pinning::PinType::Pinning:\r\n                return Pinning::Pin::CreatePinningPin({ packageId, sourceId });\r\n            case Pinning::PinType::Gating:\r\n                return Pinning::Pin::CreateGatingPin({ packageId, sourceId }, Utility::GatedVersion{ version });\r\n            default:\r\n                return {};\r\n            }\r\n        }\r\n    }\r\n\r\n    using namespace std::string_view_literals;\r\n    static constexpr std::string_view s_PinTable_Table_Name = \"pin\"sv;\r\n    static constexpr std::string_view s_PinTable_PackageId_Column = \"package_id\"sv;\r\n    static constexpr std::string_view s_PinTable_SourceId_Column = \"source_id\"sv;\r\n    static constexpr std::string_view s_PinTable_Type_Column = \"type\"sv;\r\n    static constexpr std::string_view s_PinTable_Version_Column = \"version\"sv;\r\n    static constexpr std::string_view s_PinTable_Index = \"pin_index\"sv;\r\n\r\n    std::string_view PinTable::TableName()\r\n    {\r\n        return s_PinTable_Table_Name;\r\n    }\r\n\r\n    void PinTable::Create(SQLite::Connection& connection)\r\n    {\r\n        using namespace SQLite::Builder;\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"createpintable_v1_0\");\r\n\r\n        StatementBuilder createTableBuilder;\r\n        createTableBuilder.CreateTable(s_PinTable_Table_Name).BeginColumns();\r\n\r\n        createTableBuilder.Column(ColumnBuilder(s_PinTable_PackageId_Column, Type::Text).NotNull());\r\n        createTableBuilder.Column(ColumnBuilder(s_PinTable_SourceId_Column, Type::Text).NotNull());\r\n        createTableBuilder.Column(ColumnBuilder(s_PinTable_Type_Column, Type::Int64).NotNull());\r\n        createTableBuilder.Column(ColumnBuilder(s_PinTable_Version_Column, Type::Text).NotNull());\r\n\r\n        createTableBuilder.EndColumns();\r\n        createTableBuilder.Execute(connection);\r\n\r\n        // Create an index over the pairs package,source\r\n        StatementBuilder createIndexBuilder;\r\n        createIndexBuilder.CreateUniqueIndex(s_PinTable_Index).On(s_PinTable_Table_Name)\r\n            .Columns({ s_PinTable_PackageId_Column, s_PinTable_SourceId_Column });\r\n        createIndexBuilder.Execute(connection);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    std::optional<SQLite::rowid_t> PinTable::GetIdByPinKey(SQLite::Connection& connection, const Pinning::PinKey& pinKey)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.Select(SQLite::RowIDName).From(s_PinTable_Table_Name)\r\n            .Where(s_PinTable_PackageId_Column).Equals((std::string_view)pinKey.PackageId)\r\n            .And(s_PinTable_SourceId_Column).Equals((std::string_view)pinKey.SourceId);\r\n\r\n        SQLite::Statement select = builder.Prepare(connection);\r\n\r\n        if (select.Step())\r\n        {\r\n            return select.GetColumn<SQLite::rowid_t>(0);\r\n        }\r\n        else\r\n        {\r\n            return {};\r\n        }\r\n    }\r\n\r\n    SQLite::rowid_t PinTable::AddPin(SQLite::Connection& connection, const Pinning::Pin& pin)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        const auto& pinKey = pin.GetKey();\r\n        builder.InsertInto(s_PinTable_Table_Name)\r\n            .Columns({\r\n                s_PinTable_PackageId_Column,\r\n                s_PinTable_SourceId_Column,\r\n                s_PinTable_Type_Column,\r\n                s_PinTable_Version_Column })\r\n            .Values(\r\n                (std::string_view)pinKey.PackageId,\r\n                pinKey.SourceId,\r\n                pin.GetType(),\r\n                pin.GetGatedVersion().ToString());\r\n\r\n        builder.Execute(connection);\r\n        return connection.GetLastInsertRowID();\r\n    }\r\n\r\n    bool PinTable::UpdatePinById(SQLite::Connection& connection, SQLite::rowid_t pinId, const Pinning::Pin& pin)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        const auto& pinKey = pin.GetKey();\r\n        builder.Update(s_PinTable_Table_Name).Set()\r\n            .Column(s_PinTable_PackageId_Column).Equals((std::string_view)pinKey.PackageId)\r\n            .Column(s_PinTable_SourceId_Column).Equals(pinKey.SourceId)\r\n            .Column(s_PinTable_Type_Column).Equals(pin.GetType())\r\n            .Column(s_PinTable_Version_Column).Equals(pin.GetGatedVersion().ToString())\r\n            .Where(SQLite::RowIDName).Equals(pinId);\r\n\r\n        builder.Execute(connection);\r\n        return connection.GetChanges() != 0;\r\n    }\r\n\r\n    void PinTable::RemovePinById(SQLite::Connection& connection, SQLite::rowid_t pinId)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.DeleteFrom(s_PinTable_Table_Name).Where(SQLite::RowIDName).Equals(pinId);\r\n        builder.Execute(connection);\r\n    }\r\n\r\n    std::optional<Pinning::Pin> PinTable::GetPinById(SQLite::Connection& connection, const SQLite::rowid_t pinId)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.Select({\r\n            s_PinTable_PackageId_Column,\r\n            s_PinTable_SourceId_Column,\r\n            s_PinTable_Type_Column,\r\n            s_PinTable_Version_Column })\r\n            .From(s_PinTable_Table_Name).Where(SQLite::RowIDName).Equals(pinId);\r\n\r\n        SQLite::Statement select = builder.Prepare(connection);\r\n\r\n        if (!select.Step())\r\n        {\r\n            return {};\r\n        }\r\n\r\n        auto [packageId, sourceId, pinType, gatedVersion] =\r\n            select.GetRow<std::string, std::string, Pinning::PinType, std::string>();\r\n        return GetPinFromRow(packageId, sourceId, pinType, gatedVersion);\r\n    }\r\n\r\n    std::vector<Pinning::Pin> PinTable::GetAllPins(SQLite::Connection& connection)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.Select({\r\n            s_PinTable_PackageId_Column,\r\n            s_PinTable_SourceId_Column,\r\n            s_PinTable_Type_Column,\r\n            s_PinTable_Version_Column })\r\n            .From(s_PinTable_Table_Name);\r\n\r\n        SQLite::Statement select = builder.Prepare(connection);\r\n\r\n        std::vector<Pinning::Pin> pins;\r\n        while (select.Step())\r\n        {\r\n            auto [packageId, sourceId, pinType, gatedVersion] =\r\n                select.GetRow<std::string, std::string, Pinning::PinType, std::string>();\r\n            auto pin = GetPinFromRow(packageId, sourceId, pinType, gatedVersion);\r\n            if (pin)\r\n            {\r\n                pins.push_back(std::move(pin.value()));\r\n            }\r\n        }\r\n\r\n        return pins;\r\n    }\r\n\r\n    bool PinTable::ResetAllPins(SQLite::Connection& connection, std::string_view sourceId)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.DeleteFrom(s_PinTable_Table_Name);\r\n\r\n        if (!sourceId.empty())\r\n        {\r\n            builder.Where(s_PinTable_SourceId_Column).Equals(sourceId);\r\n        }\r\n\r\n        builder.Execute(connection);\r\n\r\n        return connection.GetChanges() != 0;\r\n    }\r\n}"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/Pinning_1_0/PinTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteWrapper.h>\r\n#include <winget/SQLiteStatementBuilder.h>\r\n#include \"Microsoft/Schema/IPinningIndex.h\"\r\n#include <string_view>\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::Pinning_V1_0\r\n{\r\n    struct PinTable\r\n    {\r\n        // Get the table name.\r\n        static std::string_view TableName();\r\n\r\n        // Creates the table with named indices.\r\n        static void Create(SQLite::Connection& connection);\r\n\r\n        // Gets the row ID for the pin, if it exists.\r\n        static std::optional<SQLite::rowid_t> GetIdByPinKey(SQLite::Connection& connection, const Pinning::PinKey& pinKey);\r\n\r\n        // Adds a new pin. Returns the row ID of the added pin.\r\n        static SQLite::rowid_t AddPin(SQLite::Connection& connection, const Pinning::Pin& pin);\r\n\r\n        // Updates an existing pin.\r\n        // Returns a value indicating whether there were any changes.\r\n        static bool UpdatePinById(SQLite::Connection& connection, SQLite::rowid_t pinId, const Pinning::Pin& pin);\r\n\r\n        // Removes a pin given its row ID.\r\n        static void RemovePinById(SQLite::Connection& connection, SQLite::rowid_t pinId);\r\n\r\n        // Gets a pin by its row ID if it exists.\r\n        // Used for testing\r\n        static std::optional<Pinning::Pin> GetPinById(SQLite::Connection& connection, const SQLite::rowid_t pinId);\r\n\r\n        // Gets all the currently existing pins.\r\n        static std::vector<Pinning::Pin> GetAllPins(SQLite::Connection& connection);\r\n\r\n        // Resets all pins from a given source, or from all sources if none is specified.\r\n        // Returns a value indicating whether there were any changes.\r\n        static bool ResetAllPins(SQLite::Connection& connection, std::string_view sourceId = {});\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/Pinning_1_0/PinningIndexInterface.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Microsoft/Schema/IPinningIndex.h\"\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::Pinning_V1_0\r\n{\r\n    struct PinningIndexInterface : public IPinningIndex\r\n    {\r\n        // Version 1.0\r\n        SQLite::Version GetVersion() const override;\r\n        void CreateTables(SQLite::Connection& connection) override;\r\n\r\n    private:\r\n        SQLite::rowid_t AddPin(SQLite::Connection& connection, const Pinning::Pin& pin) override;\r\n        std::pair<bool, SQLite::rowid_t> UpdatePin(SQLite::Connection& connection, const Pinning::Pin& pin) override;\r\n        SQLite::rowid_t RemovePin(SQLite::Connection& connection, const Pinning::PinKey& pinKey) override;\r\n        std::optional<Pinning::Pin> GetPin(SQLite::Connection& connection, const Pinning::PinKey& pinKey) override;\r\n        std::vector<Pinning::Pin> GetAllPins(SQLite::Connection& connection) override;\r\n        bool ResetAllPins(SQLite::Connection& connection, std::string_view sourceId) override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/Pinning_1_0/PinningIndexInterface_1_0.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Microsoft/Schema/Pinning_1_0/PinningIndexInterface.h\"\r\n#include \"Microsoft/Schema/Pinning_1_0/PinTable.h\"\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::Pinning_V1_0\r\n{\r\n    namespace\r\n    {\r\n        std::optional<SQLite::rowid_t> GetExistingPinId(SQLite::Connection& connection, const Pinning::PinKey& pinKey)\r\n        {\r\n            auto result = PinTable::GetIdByPinKey(connection, pinKey);\r\n\r\n            if (!result)\r\n            {\r\n                AICLI_LOG(Repo, Verbose, << \"Did not find pin \" << pinKey.ToString());\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n    }\r\n\r\n    // Version 1.0\r\n    SQLite::Version PinningIndexInterface::GetVersion() const\r\n    {\r\n        return { 1, 0 };\r\n    }\r\n\r\n    void PinningIndexInterface::CreateTables(SQLite::Connection& connection)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"createpintable_v1_0\");\r\n        Pinning_V1_0::PinTable::Create(connection);\r\n        savepoint.Commit();\r\n    }\r\n\r\n    SQLite::rowid_t PinningIndexInterface::AddPin(SQLite::Connection& connection, const Pinning::Pin& pin)\r\n    {\r\n        auto existingPin = GetExistingPinId(connection, pin.GetKey());\r\n\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), existingPin.has_value());\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"addpin_v1_0\");\r\n        SQLite::rowid_t pinId = PinTable::AddPin(connection, pin);\r\n\r\n        savepoint.Commit();\r\n        return pinId;\r\n    }\r\n\r\n    std::pair<bool, SQLite::rowid_t> PinningIndexInterface::UpdatePin(SQLite::Connection& connection, const Pinning::Pin& pin)\r\n    {\r\n        auto existingPinId = GetExistingPinId(connection, pin.GetKey());\r\n\r\n        // If the pin doesn't exist, fail the update\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), !existingPinId);\r\n\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"updatepin_v1_0\");\r\n        bool status = PinTable::UpdatePinById(connection, existingPinId.value(), pin);\r\n\r\n        savepoint.Commit();\r\n        return { status, existingPinId.value() };\r\n    }\r\n\r\n    SQLite::rowid_t PinningIndexInterface::RemovePin(SQLite::Connection& connection, const Pinning::PinKey& pinKey)\r\n    {\r\n        auto existingPinId = GetExistingPinId(connection, pinKey);\r\n\r\n        // If the pin doesn't exist, fail the remove\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), !existingPinId);\r\n\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"removepin_v1_0\");\r\n        PinTable::RemovePinById(connection, existingPinId.value());\r\n\r\n        savepoint.Commit();\r\n        return existingPinId.value();\r\n    }\r\n\r\n    std::optional<Pinning::Pin> PinningIndexInterface::GetPin(SQLite::Connection& connection, const Pinning::PinKey& pinKey)\r\n    {\r\n        auto existingPinId = GetExistingPinId(connection, pinKey);\r\n\r\n        if (!existingPinId)\r\n        {\r\n            return {};\r\n        }\r\n\r\n        return PinTable::GetPinById(connection, existingPinId.value());\r\n    }\r\n\r\n    std::vector<Pinning::Pin> PinningIndexInterface::GetAllPins(SQLite::Connection& connection)\r\n    {\r\n        return PinTable::GetAllPins(connection);\r\n    }\r\n\r\n    bool PinningIndexInterface::ResetAllPins(SQLite::Connection& connection, std::string_view sourceId)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"resetpins_v1_0\");\r\n        bool result = PinTable::ResetAllPins(connection, sourceId);\r\n        savepoint.Commit();\r\n\r\n        return result;\r\n    }\r\n}"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/Portable_1_0/PortableIndexInterface.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"Microsoft/Schema/IPortableIndex.h\"\n#include \"Microsoft/Schema/Portable_1_0/PortableTable.h\"\n\nnamespace AppInstaller::Repository::Microsoft::Schema::Portable_V1_0\n{\n    struct PortableIndexInterface : public IPortableIndex\n    {\n        // Version 1.0\n        SQLite::Version GetVersion() const override;\n        void CreateTable(SQLite::Connection& connection) override;\n\n    private:\n        SQLite::rowid_t AddPortableFile(SQLite::Connection& connection, const Portable::PortableFileEntry& file) override;\n        SQLite::rowid_t RemovePortableFile(SQLite::Connection& connection, const Portable::PortableFileEntry& file) override;\n        std::pair<bool, SQLite::rowid_t> UpdatePortableFile(SQLite::Connection& connection, const Portable::PortableFileEntry& file) override;\n        bool Exists(SQLite::Connection& connection, const Portable::PortableFileEntry& file) override;\n        bool IsEmpty(SQLite::Connection& connection) override;\n        std::vector<Portable::PortableFileEntry> GetAllPortableFiles(SQLite::Connection& connection) override;\n    };\n}"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/Portable_1_0/PortableIndexInterface_1_0.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Microsoft/Schema/Portable_1_0/PortableIndexInterface.h\"\r\n#include \"Microsoft/Schema/Portable_1_0/PortableTable.h\"\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::Portable_V1_0\r\n{\r\n    namespace\r\n    {\r\n        std::optional<SQLite::rowid_t> GetExistingPortableFileId(const SQLite::Connection& connection, const Portable::PortableFileEntry& file)\r\n        {\r\n            auto result = PortableTable::SelectByFilePath(connection, file.GetFilePath());\r\n\r\n            if (!result)\r\n            {\r\n                AICLI_LOG(Repo, Verbose, << \"Did not find a portable file with the path  { \" << file.GetFilePath() << \" }\");\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n\r\n    SQLite::Version PortableIndexInterface::GetVersion() const\r\n    {\r\n        return { 1, 0 };\r\n    }\r\n\r\n    void PortableIndexInterface::CreateTable(SQLite::Connection& connection)\r\n    {\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"createportabletable_v1_0\");\r\n        Portable_V1_0::PortableTable::Create(connection);\r\n        savepoint.Commit();\r\n    }\r\n\r\n    SQLite::rowid_t PortableIndexInterface::AddPortableFile(SQLite::Connection& connection, const Portable::PortableFileEntry& file)\r\n    {\r\n        auto portableEntryResult = GetExistingPortableFileId(connection, file);\r\n\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), portableEntryResult.has_value());\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"addportablefile_v1_0\");\r\n        SQLite::rowid_t portableFileId = PortableTable::AddPortableFile(connection, file);\r\n\r\n        savepoint.Commit();\r\n        return portableFileId;\r\n    }\r\n\r\n    SQLite::rowid_t PortableIndexInterface::RemovePortableFile(SQLite::Connection& connection, const Portable::PortableFileEntry& file)\r\n    {\r\n        auto portableEntryResult = GetExistingPortableFileId(connection, file);\r\n\r\n        // If the portable file doesn't actually exist, fail the remove.\r\n        THROW_HR_IF(E_NOT_SET, !portableEntryResult);\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"removeportablefile_v1_0\");\r\n        PortableTable::RemovePortableFileById(connection, portableEntryResult.value());\r\n\r\n        savepoint.Commit();\r\n        return portableEntryResult.value();\r\n    }\r\n\r\n    std::pair<bool, SQLite::rowid_t> PortableIndexInterface::UpdatePortableFile(SQLite::Connection& connection, const Portable::PortableFileEntry& file)\r\n    {\r\n        auto portableEntryResult = GetExistingPortableFileId(connection, file);\r\n\r\n        // If the portable file doesn't actually exist, fail the update.\r\n        THROW_HR_IF(E_NOT_SET, !portableEntryResult);\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"updateportablefile_v1_0\");\r\n        bool status = PortableTable::UpdatePortableFileById(connection, portableEntryResult.value(), file);\r\n\r\n        savepoint.Commit();\r\n        return { status, portableEntryResult.value() };\r\n    }\r\n\r\n    bool PortableIndexInterface::Exists(SQLite::Connection& connection, const Portable::PortableFileEntry& file)\r\n    {\r\n        return GetExistingPortableFileId(connection, file).has_value();\r\n    }\r\n\r\n    bool PortableIndexInterface::IsEmpty(SQLite::Connection& connection)\r\n    {\r\n        return PortableTable::IsEmpty(connection);\r\n    }\r\n\r\n    std::vector<Portable::PortableFileEntry> PortableIndexInterface::GetAllPortableFiles(SQLite::Connection& connection)\r\n    {\r\n        return PortableTable::GetAllPortableFiles(connection);\r\n    }\r\n}"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/Portable_1_0/PortableTable.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"PortableTable.h\"\r\n#include <winget/SQLiteStatementBuilder.h>\r\n#include \"Microsoft/Schema/IPortableIndex.h\"\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::Portable_V1_0\r\n{\r\n    using namespace std::string_view_literals;\r\n    static constexpr std::string_view s_PortableTable_Table_Name = \"portable\"sv;\r\n    static constexpr std::string_view s_PortableTable_FilePath_Column = \"filepath\"sv;\r\n    static constexpr std::string_view s_PortableTable_FileType_Column = \"filetype\"sv;\r\n    static constexpr std::string_view s_PortableTable_SHA256_Column = \"sha256\"sv;\r\n    static constexpr std::string_view s_PortableTable_SymlinkTarget_Column = \"symlinktarget\"sv;\r\n\r\n    std::string_view PortableTable::TableName()\r\n    {\r\n        return s_PortableTable_Table_Name;\r\n    }\r\n    \r\n    void PortableTable::Create(SQLite::Connection& connection)\r\n    {\r\n        using namespace SQLite::Builder;\r\n\r\n        SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, \"createPortableTable_v1_0\");\r\n\r\n        StatementBuilder createTableBuilder;\r\n        createTableBuilder.CreateTable(s_PortableTable_Table_Name).BeginColumns();\r\n\r\n        createTableBuilder.Column(ColumnBuilder(s_PortableTable_FilePath_Column, Type::Text).NotNull().Unique().CollateNoCase());\r\n        createTableBuilder.Column(ColumnBuilder(s_PortableTable_FileType_Column, Type::Int64).NotNull());\r\n        createTableBuilder.Column(ColumnBuilder(s_PortableTable_SHA256_Column, Type::Blob));\r\n        createTableBuilder.Column(ColumnBuilder(s_PortableTable_SymlinkTarget_Column, Type::Text));\r\n\r\n        createTableBuilder.EndColumns();\r\n        createTableBuilder.Execute(connection);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    std::optional<SQLite::rowid_t> PortableTable::SelectByFilePath(const SQLite::Connection& connection, const std::filesystem::path& path)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.Select(SQLite::RowIDName).From(s_PortableTable_Table_Name).Where(s_PortableTable_FilePath_Column);\r\n        builder.Equals(path.u8string());\r\n\r\n        SQLite::Statement select = builder.Prepare(connection);\r\n\r\n        if (select.Step())\r\n        {\r\n            return select.GetColumn<SQLite::rowid_t>(0);\r\n        }\r\n        else\r\n        {\r\n            return {};\r\n        }\r\n    }\r\n\r\n    void PortableTable::RemovePortableFileById(SQLite::Connection& connection, SQLite::rowid_t id)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.DeleteFrom(s_PortableTable_Table_Name).Where(SQLite::RowIDName).Equals(id);\r\n        builder.Execute(connection);\r\n    }\r\n\r\n    SQLite::rowid_t PortableTable::AddPortableFile(SQLite::Connection& connection, const Portable::PortableFileEntry& file)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.InsertInto(s_PortableTable_Table_Name)\r\n            .Columns({ s_PortableTable_FilePath_Column,\r\n                s_PortableTable_FileType_Column,\r\n                s_PortableTable_SHA256_Column,\r\n                s_PortableTable_SymlinkTarget_Column })\r\n            .Values(file.GetFilePath().u8string(), file.FileType, file.SHA256, file.SymlinkTarget);\r\n\r\n        builder.Execute(connection);\r\n        return connection.GetLastInsertRowID();\r\n    }\r\n\r\n    bool PortableTable::UpdatePortableFileById(SQLite::Connection& connection, SQLite::rowid_t id, const Portable::PortableFileEntry& file)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.Update(s_PortableTable_Table_Name).Set()\r\n            .Column(s_PortableTable_FilePath_Column).Equals(file.GetFilePath().u8string())\r\n            .Column(s_PortableTable_FileType_Column).Equals(file.FileType)\r\n            .Column(s_PortableTable_SHA256_Column).Equals(file.SHA256)\r\n            .Column(s_PortableTable_SymlinkTarget_Column).Equals(file.SymlinkTarget)\r\n            .Where(SQLite::RowIDName).Equals(id);\r\n\r\n        builder.Execute(connection);\r\n        return connection.GetChanges() != 0;\r\n    }\r\n\r\n    std::optional<Portable::PortableFileEntry> PortableTable::GetPortableFileById(const SQLite::Connection& connection, SQLite::rowid_t id)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.Select({ s_PortableTable_FilePath_Column,\r\n            s_PortableTable_FileType_Column,\r\n            s_PortableTable_SHA256_Column,\r\n            s_PortableTable_SymlinkTarget_Column})\r\n            .From(s_PortableTable_Table_Name).Where(SQLite::RowIDName).Equals(id);\r\n\r\n        SQLite::Statement select = builder.Prepare(connection);\r\n\r\n        Portable::PortableFileEntry portableFile;\r\n        if (select.Step())\r\n        {\r\n            auto [filePath, fileType, sha256, symlinkTarget] = select.GetRow<std::string, Portable::PortableFileType, std::string, std::string>();\r\n            portableFile.FileType = fileType;\r\n            portableFile.SetFilePath(Utility::ConvertToUTF16(filePath));\r\n            portableFile.SHA256 = std::move(sha256);\r\n            portableFile.SymlinkTarget = std::move(symlinkTarget);\r\n            return portableFile;\r\n        }\r\n        else\r\n        {\r\n            return {};\r\n        }\r\n    }\r\n\r\n    bool PortableTable::ExistsById(const SQLite::Connection& connection, SQLite::rowid_t id)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.Select(SQLite::Builder::RowCount).From(s_PortableTable_Table_Name).Where(SQLite::RowIDName).Equals(id);\r\n\r\n        SQLite::Statement countStatement = builder.Prepare(connection);\r\n\r\n        THROW_HR_IF(E_UNEXPECTED, !countStatement.Step());\r\n\r\n        return (countStatement.GetColumn<int>(0) != 0);\r\n    }\r\n\r\n    void PortableTable::DeleteById(SQLite::Connection& connection, SQLite::rowid_t id)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.DeleteFrom(s_PortableTable_Table_Name).Where(SQLite::RowIDName).Equals(id);\r\n\r\n        builder.Execute(connection);\r\n    }\r\n\r\n    bool PortableTable::IsEmpty(SQLite::Connection& connection)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.Select(SQLite::Builder::RowCount).From(s_PortableTable_Table_Name);\r\n\r\n        SQLite::Statement countStatement = builder.Prepare(connection);\r\n\r\n        THROW_HR_IF(E_UNEXPECTED, !countStatement.Step());\r\n\r\n        return (countStatement.GetColumn<int>(0) == 0);\r\n    }\r\n\r\n    std::vector<Portable::PortableFileEntry> PortableTable::GetAllPortableFiles(SQLite::Connection& connection)\r\n    {\r\n        SQLite::Builder::StatementBuilder builder;\r\n        builder.Select({ s_PortableTable_FilePath_Column,\r\n            s_PortableTable_FileType_Column,\r\n            s_PortableTable_SHA256_Column,\r\n            s_PortableTable_SymlinkTarget_Column })\r\n            .From(s_PortableTable_Table_Name);\r\n\r\n        SQLite::Statement select = builder.Prepare(connection);\r\n        std::vector<Portable::PortableFileEntry> result;\r\n        while (select.Step())\r\n        {\r\n            Portable::PortableFileEntry portableFile;\r\n            auto [filePath, fileType, sha256, symlinkTarget] = select.GetRow<std::string, Portable::PortableFileType, std::string, std::string>();\r\n            portableFile.FileType = fileType;\r\n            portableFile.SetFilePath(Utility::ConvertToUTF16(filePath));\r\n            portableFile.SHA256 = std::move(sha256);\r\n            portableFile.SymlinkTarget = std::move(symlinkTarget);\r\n            result.emplace_back(std::move(portableFile));\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/Portable_1_0/PortableTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteWrapper.h>\r\n#include <winget/SQLiteStatementBuilder.h>\r\n#include \"Microsoft/Schema/IPortableIndex.h\"\r\n#include <string_view>\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema::Portable_V1_0\r\n{\r\n    // A table the represents a single portable file\r\n    struct PortableTable\r\n    {\r\n        // Get the table name.\r\n        static std::string_view TableName();\r\n\r\n        // Creates the table with named indices.\r\n        static void Create(SQLite::Connection& connection);\r\n\r\n        // Gets a value indicating whether the portable file with rowid id exists.\r\n        static bool ExistsById(const SQLite::Connection& connection, SQLite::rowid_t id);\r\n\r\n        // Deletes the portable file row with the given rowid\r\n        static void DeleteById(SQLite::Connection& connection, SQLite::rowid_t id);\r\n\r\n        // Gets a value indicating whether the table is empty.\r\n        static bool IsEmpty(SQLite::Connection& connection);\r\n\r\n        // Selects the portable file by filepath from the table, returning the rowid if it exists.\r\n        static std::optional<SQLite::rowid_t> SelectByFilePath(const SQLite::Connection& connection, const std::filesystem::path& path);\r\n\r\n        // Selects the portable file by rowid from the table, returning the portable file object if it exists.\r\n        static std::optional<Portable::PortableFileEntry> GetPortableFileById(const SQLite::Connection& connection, SQLite::rowid_t id);\r\n        \r\n        // Adds the portable file into the table.\r\n        static SQLite::rowid_t AddPortableFile(SQLite::Connection& connection, const Portable::PortableFileEntry& file);\r\n\r\n        // Removes the portable file from the table by id.\r\n        static void RemovePortableFileById(SQLite::Connection& connection, SQLite::rowid_t id);\r\n\r\n        // Updates the portable file in the table by id.\r\n        static bool UpdatePortableFileById(SQLite::Connection& connection, SQLite::rowid_t id, const Portable::PortableFileEntry& file);\r\n\r\n        // Gets all portable files recorded in the index.\r\n        static std::vector<Portable::PortableFileEntry> GetAllPortableFiles(SQLite::Connection& connection);\r\n    };\r\n}"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Microsoft/Schema/SQLiteIndexContextData.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerLanguageUtilities.h>\r\n#include <filesystem>\r\n\r\n\r\nnamespace AppInstaller::Repository::Microsoft::Schema\r\n{\r\n    // Names a property\r\n    enum class Property : size_t\r\n    {\r\n        PackageUpdateTrackingBaseTime,\r\n        IntermediateFileOutputPath,\r\n        DatabaseFilePath,\r\n        Max\r\n    };\r\n\r\n    namespace details\r\n    {\r\n        template <Property D>\r\n        struct PropertyMapping\r\n        {\r\n            // value_t type specifies the type of this property\r\n        };\r\n\r\n        template <>\r\n        struct PropertyMapping<Property::PackageUpdateTrackingBaseTime>\r\n        {\r\n            using value_t = int64_t;\r\n            static constexpr bool SetThroughInterface = true;\r\n        };\r\n\r\n        template <>\r\n        struct PropertyMapping<Property::IntermediateFileOutputPath>\r\n        {\r\n            using value_t = std::filesystem::path;\r\n            static constexpr bool SetThroughInterface = false;\r\n        };\r\n\r\n        template <>\r\n        struct PropertyMapping<Property::DatabaseFilePath>\r\n        {\r\n            using value_t = std::filesystem::path;\r\n            static constexpr bool SetThroughInterface = false;\r\n        };\r\n    }\r\n\r\n    using SQLiteIndexContextData = EnumBasedVariantMap<Property, details::PropertyMapping>;\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/PackageDependenciesValidation.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"pch.h\"\n#include \"PackageDependenciesValidation.h\"\n#include <winget/ManifestValidation.h>\n#include <winget/DependenciesGraph.h>\n\nnamespace AppInstaller::Repository\n{\n    namespace\n    {\n        struct DependentManifestInfo\n        {\n            Utility::NormalizedString Id;\n            Utility::NormalizedString Version;\n        };\n\n        Manifest::DependencyList GetDependencies(\n            const Manifest::Manifest& manifest, AppInstaller::Manifest::DependencyType dependencyType)\n        {\n            Manifest::DependencyList depList;\n            std::vector<AppInstaller::Manifest::Dependency>  dependencies;\n\n            for (const auto& installer : manifest.Installers)\n            {\n                installer.Dependencies.ApplyToType(dependencyType, [&](AppInstaller::Manifest::Dependency dependency)\n                {\n                    depList.Add(dependency);\n                });\n            }\n\n            return depList;\n        }\n\n        std::optional<SQLiteIndex::VersionKey> GetPackageLatestVersion(\n            SQLiteIndex* index, Manifest::string_t packageId, std::set<Utility::Version> exclusions = {})\n        {\n            SearchRequest request;\n            request.Filters.emplace_back(PackageMatchField::Id, MatchType::CaseInsensitive, packageId);\n\n            auto results = index->Search(request);\n\n            if (results.Matches.empty())\n            {\n                return {};\n            }\n\n            auto packageRowId = results.Matches[0].first;\n            auto vac = index->GetVersionKeysById(packageRowId);\n\n            if (vac.empty())\n            {\n                return {};\n            }\n\n            SQLiteIndex::VersionKey maxVersion{ Utility::VersionAndChannel{ Utility::Version::CreateUnknown(), Utility::Channel(\"\") } };\n\n            for (auto& v : vac)\n            {\n                auto currentVersion = v.VersionAndChannel.GetVersion();\n                if (exclusions.find(currentVersion) != exclusions.end())\n                {\n                    continue;\n                }\n\n                if (currentVersion > maxVersion.VersionAndChannel.GetVersion())\n                {\n                    maxVersion = v;\n                }\n            }\n\n            if (maxVersion.VersionAndChannel.GetVersion().IsUnknown())\n            {\n                return {};\n            }\n\n            return maxVersion;\n        }\n    \n        void ThrowOnManifestValidationFailed(\n            std::vector<std::pair<DependentManifestInfo, Utility::Version>> failedManifests, AppInstaller::StringResource::StringId error)\n        {\n            auto itrStart = failedManifests.begin();\n            std::vector<Manifest::ValidationError> validationErrors;\n            validationErrors.emplace_back(error, \"PackageIdentifier.PackageVersion\", itrStart->first.Id + '.' + itrStart->first.Version );\n\n            std::for_each(\n                itrStart + 1,\n                failedManifests.end(),\n                [&](std::pair<DependentManifestInfo, Utility::Version> current)\n                {\n                    validationErrors.emplace_back(error, \"PackageIdentifier.PackageVersion\", current.first.Id + '.' + current.first.Version);\n                });\n\n            THROW_EXCEPTION(\n                Manifest::ManifestException(\n                    std::move(validationErrors), APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED));\n        }\n    };\n\n    bool PackageDependenciesValidation::ValidateManifestDependencies(SQLiteIndex* index, const Manifest::Manifest& manifest)\n    {\n        using namespace Manifest;\n\n        Dependency rootId(DependencyType::Package, manifest.Id, manifest.Version);\n        std::vector<ValidationError> dependenciesError;\n        bool foundErrors = false;\n\n        DependencyGraph graph\n        {\n            rootId,\n            [&](const Dependency& node)\n            {\n                DependencyList depList;\n                if (node.Id() == rootId.Id())\n                {\n                    return GetDependencies(manifest, DependencyType::Package);\n                }\n\n                auto packageLatest = GetPackageLatestVersion(index, node.Id());\n                if (!packageLatest.has_value())\n                {\n                    dependenciesError.emplace_back(\n                        ManifestError::MissingManifestDependenciesNode, \"PackageIdentifier\", node.Id());\n                    foundErrors = true;\n                    return depList;\n                }\n\n                if (node.MinVersion > packageLatest->VersionAndChannel.GetVersion())\n                {\n                    dependenciesError.emplace_back(ManifestError::NoSuitableMinVersionDependency, \"PackageIdentifier\", node.Id());\n                    foundErrors = true;\n                    return depList;\n                }\n\n                auto packageLatestDependencies = index->GetDependenciesByManifestRowId(packageLatest->ManifestId);\n                std::for_each(\n                    packageLatestDependencies.begin(),\n                    packageLatestDependencies.end(),\n                    [&](std::pair<SQLite::rowid_t, Utility::NormalizedString> row)\n                    {\n                        auto manifestRowId = index->GetManifestIdByKey(row.first, \"\", \"\");\n                        auto packageId = index->GetPropertyByPrimaryId(manifestRowId.value(), PackageVersionProperty::Id);\n                        Dependency dep(DependencyType::Package, packageId.value(), row.second);\n                        depList.Add(dep);\n                    });\n\n                return depList;\n            }\n        };\n\n        graph.BuildGraph();\n\n        if (foundErrors)\n        {\n            THROW_EXCEPTION(ManifestException(std::move(dependenciesError), APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED));\n        }\n\n        if (graph.HasLoop())\n        {\n            dependenciesError.emplace_back(ManifestError::FoundDependencyLoop);\n            THROW_EXCEPTION(ManifestException(std::move(dependenciesError), APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED));\n        }\n\n        return true;\n    }\n\n    bool PackageDependenciesValidation::VerifyDependenciesStructureForManifestDelete(SQLiteIndex* index, const Manifest::Manifest& manifest)\n    {\n        auto dependentsSet = index->GetDependentsById(manifest.Id);\n\n        if (!dependentsSet.size())\n        {\n            // all good this manifest is not a dependency of any manifest.\n            return true;\n        }\n\n        std::vector<std::pair<DependentManifestInfo, Utility::Version>> dependentManifestInfoToVersionPair;\n        std::for_each(\n            dependentsSet.begin(),\n            dependentsSet.end(),\n            [&](std::pair<SQLite::rowid_t, Utility::Version> current)\n            {\n                DependentManifestInfo dependentManifestInfo;\n                dependentManifestInfo.Id = index->GetPropertyByPrimaryId(current.first, PackageVersionProperty::Id).value();\n                dependentManifestInfo.Version = index->GetPropertyByPrimaryId(current.first, PackageVersionProperty::Version).value();\n\n                dependentManifestInfoToVersionPair.emplace_back(std::make_pair(dependentManifestInfo, current.second));\n            });\n\n        auto packageLatest = GetPackageLatestVersion(index, manifest.Id);\n\n        if (!packageLatest.has_value())\n        {\n            // this is a fatal error, a manifest should exists in the very least(including the current manifest being deleted),\n            // since this is a delete operation. \n            THROW_HR(APPINSTALLER_CLI_ERROR_MISSING_PACKAGE);\n        }\n\n        if (Utility::Version(manifest.Version) < packageLatest->VersionAndChannel.GetVersion())\n        {\n            // all good, since it's min version the criteria is still satisfied.\n            return true;\n        }\n\n        auto nextLatestAfterDelete = GetPackageLatestVersion(index, manifest.Id, { packageLatest->VersionAndChannel.GetVersion() });\n\n        if (!nextLatestAfterDelete.has_value())\n        {\n            ThrowOnManifestValidationFailed(\n                dependentManifestInfoToVersionPair, Manifest::ManifestError::SingleManifestPackageHasDependencies);\n        }\n\n        std::vector<std::pair<DependentManifestInfo, Utility::Version>> breakingManifests;\n\n        // Gets breaking manifests.\n        std::copy_if(\n            dependentManifestInfoToVersionPair.begin(),\n            dependentManifestInfoToVersionPair.end(),\n            std::back_inserter(breakingManifests),\n            [&](std::pair<DependentManifestInfo, Utility::Version> current)\n            {\n                return current.second > nextLatestAfterDelete->VersionAndChannel.GetVersion();\n            }\n        );\n\n        if (!breakingManifests.empty())\n        {\n            ThrowOnManifestValidationFailed(\n                breakingManifests, Manifest::ManifestError::MultiManifestPackageHasDependencies);\n        }\n\n        return true;\n    }\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/PackageDependenciesValidation.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"Microsoft/SQLiteIndex.h\"\n#include <winget/Manifest.h>\n\nnamespace AppInstaller::Repository\n{\n    using namespace AppInstaller::Repository::Microsoft;\n\n    struct PackageDependenciesValidation\n    {\n        // Validate the dependencies of the given manifest.\n        static bool ValidateManifestDependencies(SQLiteIndex* index, const Manifest::Manifest& manifest);\n\n        static bool VerifyDependenciesStructureForManifestDelete(SQLiteIndex* index, const Manifest::Manifest& manifest);\n    };\n}\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/PackageInstalledStatus.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/InstalledStatus.h\"\r\n#include \"Public/winget/PackageVersionSelection.h\"\r\n#include <winget/Filesystem.h>\r\n\r\nusing namespace AppInstaller::Settings;\r\nusing namespace std::chrono_literals;\r\n\r\nnamespace AppInstaller::Repository\r\n{\r\n    namespace\r\n    {\r\n        HRESULT CheckInstalledLocationStatus(const std::filesystem::path& installedLocation)\r\n        {\r\n            HRESULT installLocationStatus = WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_APPLICABLE;\r\n            if (!installedLocation.empty())\r\n            {\r\n                // Use the none throw version, if the directory cannot be reached, it's treated as not found and later file checks are not performed.\r\n                std::error_code error;\r\n                installLocationStatus =\r\n                    std::filesystem::exists(installedLocation, error) && std::filesystem::is_directory(installedLocation, error) ?\r\n                    WINGET_INSTALLED_STATUS_INSTALL_LOCATION_FOUND :\r\n                    WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_FOUND;\r\n            }\r\n\r\n            return installLocationStatus;\r\n        }\r\n\r\n        // Map to cache already calculated file hashes.\r\n        struct FilePathComparator\r\n        {\r\n            bool operator()(const std::filesystem::path& a, const std::filesystem::path& b) const\r\n            {\r\n                if (std::filesystem::equivalent(a, b))\r\n                {\r\n                    return false;\r\n                }\r\n\r\n                return a < b;\r\n            }\r\n        };\r\n        using FileHashMap = std::map<std::filesystem::path, Utility::SHA256::HashBuffer, FilePathComparator>;\r\n\r\n        HRESULT CheckInstalledFileStatus(\r\n            const std::filesystem::path& filePath,\r\n            const Utility::SHA256::HashBuffer& expectedHash,\r\n            FileHashMap& fileHashes)\r\n        {\r\n            HRESULT fileStatus = WINGET_INSTALLED_STATUS_FILE_NOT_FOUND;\r\n            try\r\n            {\r\n                if (std::filesystem::exists(filePath) && std::filesystem::is_regular_file(filePath))\r\n                {\r\n                    fileStatus = WINGET_INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK;\r\n                    if (!expectedHash.empty())\r\n                    {\r\n                        auto itr = fileHashes.find(filePath);\r\n                        if (itr == fileHashes.end())\r\n                        {\r\n                            // If not found in cache, compute the hash.\r\n                            std::ifstream in{ filePath, std::ifstream::binary };\r\n                            itr = fileHashes.emplace(filePath, Utility::SHA256::ComputeHash(in)).first;\r\n                        }\r\n\r\n                        fileStatus = Utility::SHA256::AreEqual(expectedHash, itr->second) ?\r\n                            WINGET_INSTALLED_STATUS_FILE_HASH_MATCH : WINGET_INSTALLED_STATUS_FILE_HASH_MISMATCH;\r\n                    }\r\n                }\r\n            }\r\n            catch (...)\r\n            {\r\n                fileStatus = WINGET_INSTALLED_STATUS_FILE_ACCESS_ERROR;\r\n            }\r\n\r\n            return fileStatus;\r\n        }\r\n\r\n        std::vector<InstallerInstalledStatus> CheckInstalledStatusInternal(\r\n            const std::shared_ptr<ICompositePackage>& package,\r\n            InstalledStatusType checkTypes)\r\n        {\r\n            using namespace AppInstaller::Manifest;\r\n\r\n            std::vector<InstallerInstalledStatus> result;\r\n            bool checkFileHash = false;\r\n            std::shared_ptr<IPackageVersion> installedVersion = GetInstalledVersion(package);\r\n            std::shared_ptr<IPackageVersion> availableVersion;\r\n            FileHashMap fileHashes;\r\n\r\n            // Variables for metadata from installed version.\r\n            InstallerTypeEnum installedType = InstallerTypeEnum::Unknown;\r\n            ScopeEnum installedScope = ScopeEnum::Unknown;\r\n            std::filesystem::path installedLocation;\r\n            std::string installedLocale;\r\n            Utility::Architecture installedArchitecture = Utility::Architecture::Unknown;\r\n            HRESULT installedLocationStatus = WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_APPLICABLE;\r\n\r\n            std::shared_ptr<IPackageVersionCollection> availableVersions = GetAvailableVersionsForInstalledVersion(package);\r\n\r\n            // Prepare installed metadata from installed version.\r\n            // Determine the available package version to be used for installed status checking.\r\n            // Only perform file hash check if we find an available version that matches installed version.\r\n            if (installedVersion)\r\n            {\r\n                // Installed metadata.\r\n                auto installedMetadata = installedVersion->GetMetadata();\r\n                installedType = ConvertToInstallerTypeEnum(installedMetadata[PackageVersionMetadata::InstalledType]);\r\n                installedScope = ConvertToScopeEnum(installedMetadata[PackageVersionMetadata::InstalledScope]);\r\n                installedLocation = Filesystem::GetExpandedPath(installedMetadata[PackageVersionMetadata::InstalledLocation]);\r\n                installedLocale = installedMetadata[PackageVersionMetadata::InstalledLocale];\r\n                installedArchitecture = Utility::ConvertToArchitectureEnum(installedMetadata[PackageVersionMetadata::InstalledArchitecture]);\r\n                installedLocationStatus = CheckInstalledLocationStatus(installedLocation);\r\n\r\n                // Determine available version.\r\n                Utility::Version installedVersionAsVersion{ installedVersion->GetProperty(PackageVersionProperty::Version) };\r\n                auto installedChannel = installedVersion->GetProperty(PackageVersionProperty::Channel);\r\n                PackageVersionKey versionKey;\r\n                versionKey.Channel = installedChannel.get();\r\n\r\n                if (installedVersionAsVersion.IsApproximate())\r\n                {\r\n                    // Use the base version as available version if installed version is mapped to be an approximate.\r\n                    versionKey.Version = installedVersionAsVersion.GetBaseVersion().ToString();\r\n                    availableVersion = availableVersions->GetVersion(versionKey);\r\n                    // It's unexpected if the installed version is already mapped to some version.\r\n                    THROW_HR_IF(E_UNEXPECTED, !availableVersion);\r\n                }\r\n                else\r\n                {\r\n                    versionKey.Version = installedVersionAsVersion.ToString();\r\n                    availableVersion = availableVersions->GetVersion(versionKey);\r\n                    if (availableVersion)\r\n                    {\r\n                        checkFileHash = true;\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (!availableVersion)\r\n            {\r\n                // No installed version, or installed version not found in available versions,\r\n                // then attempt to check installed status using latest version.\r\n                availableVersion = availableVersions->GetLatestVersion();\r\n                THROW_HR_IF(E_UNEXPECTED, !availableVersion);\r\n            }\r\n\r\n            auto manifest = availableVersion->GetManifest();\r\n            for (auto const& installer : manifest.Installers)\r\n            {\r\n                InstallerInstalledStatus installerStatus;\r\n                installerStatus.Installer = installer;\r\n\r\n                // ARP related checks\r\n                if (WI_IsAnyFlagSet(checkTypes, InstalledStatusType::AllAppsAndFeaturesEntryChecks))\r\n                {\r\n                    bool isMatchingInstaller =\r\n                        installedVersion &&\r\n                        IsInstallerTypeCompatible(installedType, installer.EffectiveInstallerType()) &&\r\n                        (installedScope == ScopeEnum::Unknown || installer.Scope == ScopeEnum::Unknown || installedScope == installer.Scope) &&  // Treat unknown scope as compatible\r\n                        (installedArchitecture == Utility::Architecture::Unknown || installer.Arch == Utility::Architecture::Neutral || installedArchitecture == installer.Arch) &&  // Treat unknown installed architecture as compatible\r\n                        (installedLocale.empty() || installer.Locale.empty() || !Locale::IsWellFormedBcp47Tag(installedLocale) || Locale::GetDistanceOfLanguage(installedLocale, installer.Locale) >= Locale::MinimumDistanceScoreAsCompatibleMatch);  // Treat invalid locale as compatible\r\n\r\n                    // ARP entry status\r\n                    if (WI_IsFlagSet(checkTypes, InstalledStatusType::AppsAndFeaturesEntry))\r\n                    {\r\n                        installerStatus.Status.emplace_back(\r\n                            InstalledStatusType::AppsAndFeaturesEntry,\r\n                            \"\",\r\n                            isMatchingInstaller ? WINGET_INSTALLED_STATUS_ARP_ENTRY_FOUND : WINGET_INSTALLED_STATUS_ARP_ENTRY_NOT_FOUND);\r\n                    }\r\n\r\n                    // ARP install location status\r\n                    if (isMatchingInstaller && WI_IsFlagSet(checkTypes, InstalledStatusType::AppsAndFeaturesEntryInstallLocation))\r\n                    {\r\n                        installerStatus.Status.emplace_back(\r\n                            InstalledStatusType::AppsAndFeaturesEntryInstallLocation,\r\n                            installedLocation.u8string(),\r\n                            installedLocationStatus);\r\n                    }\r\n\r\n                    // ARP install location files\r\n                    if (isMatchingInstaller &&\r\n                        installedLocationStatus == WINGET_INSTALLED_STATUS_INSTALL_LOCATION_FOUND &&\r\n                        WI_IsFlagSet(checkTypes, InstalledStatusType::AppsAndFeaturesEntryInstallLocationFile))\r\n                    {\r\n                        for (auto const& file : installer.InstallationMetadata.Files)\r\n                        {\r\n                            std::filesystem::path filePath = installedLocation / Utility::ConvertToUTF16(file.RelativeFilePath);\r\n                            auto fileStatus = CheckInstalledFileStatus(filePath, checkFileHash ? file.FileSha256 : Utility::SHA256::HashBuffer{}, fileHashes);\r\n\r\n                            installerStatus.Status.emplace_back(\r\n                                InstalledStatusType::AppsAndFeaturesEntryInstallLocationFile,\r\n                                filePath.u8string(),\r\n                                fileStatus);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                // Default install location related checks\r\n                if (WI_IsAnyFlagSet(checkTypes, InstalledStatusType::AllDefaultInstallLocationChecks) && installer.InstallationMetadata.HasData())\r\n                {\r\n                    auto defaultInstalledLocation = Filesystem::GetExpandedPath(installer.InstallationMetadata.DefaultInstallLocation);\r\n                    HRESULT defaultInstalledLocationStatus = CheckInstalledLocationStatus(defaultInstalledLocation);\r\n\r\n                    // Default install location status\r\n                    if (WI_IsFlagSet(checkTypes, InstalledStatusType::DefaultInstallLocation))\r\n                    {\r\n                        installerStatus.Status.emplace_back(\r\n                            InstalledStatusType::DefaultInstallLocation,\r\n                            defaultInstalledLocation.u8string(),\r\n                            defaultInstalledLocationStatus);\r\n                    }\r\n\r\n                    // Default install location files\r\n                    if (defaultInstalledLocationStatus == WINGET_INSTALLED_STATUS_INSTALL_LOCATION_FOUND &&\r\n                        WI_IsFlagSet(checkTypes, InstalledStatusType::DefaultInstallLocationFile))\r\n                    {\r\n                        for (auto const& file : installer.InstallationMetadata.Files)\r\n                        {\r\n                            std::filesystem::path filePath = defaultInstalledLocation / Utility::ConvertToUTF16(file.RelativeFilePath);\r\n                            auto fileStatus = CheckInstalledFileStatus(filePath, checkFileHash ? file.FileSha256 : Utility::SHA256::HashBuffer{}, fileHashes);\r\n\r\n                            installerStatus.Status.emplace_back(\r\n                                InstalledStatusType::DefaultInstallLocationFile,\r\n                                filePath.u8string(),\r\n                                fileStatus);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if (!installerStatus.Status.empty())\r\n                {\r\n                    result.emplace_back(std::move(installerStatus));\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n\r\n    std::vector<InstallerInstalledStatus> CheckPackageInstalledStatus(const std::shared_ptr<ICompositePackage>& package, InstalledStatusType checkTypes)\r\n    {\r\n        return CheckInstalledStatusInternal(package, checkTypes);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/PackageTrackingCatalog.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"winget/PackageTrackingCatalog.h\"\r\n#include \"PackageTrackingCatalogSourceFactory.h\"\r\n#include \"winget/Pin.h\"\r\n#include \"winget/RepositorySource.h\"\r\n#include \"Microsoft/SQLiteIndexSource.h\"\r\n#include \"AppInstallerDateTime.h\"\r\n\r\nusing namespace std::string_literals;\r\nusing namespace AppInstaller::Repository::Microsoft;\r\n\r\n\r\nnamespace AppInstaller::Repository\r\n{\r\n    namespace\r\n    {\r\n        constexpr std::string_view c_PackageTrackingFileName = \"installed.db\";\r\n        constexpr std::string_view c_PackageTrackingCorruptedFileName = \"installed-corrupted.db\";\r\n\r\n        std::string CreateNameForCPL(const std::string& pathName)\r\n        {\r\n            return \"PackageTrackingCPL_\"s + pathName;\r\n        }\r\n\r\n        std::filesystem::path GetPackageTrackingFilePath(const std::string& pathName)\r\n        {\r\n            std::filesystem::path result = Runtime::GetPathTo(Runtime::PathName::LocalState);\r\n            result /= pathName;\r\n            result /= c_PackageTrackingFileName;\r\n            return result;\r\n        }\r\n\r\n        // Call while holding the CrossProcessLock\r\n        SQLiteIndex CreateOnlyTrackingIndex(const std::filesystem::path& trackingDB)\r\n        {\r\n            return SQLiteIndex::CreateNew(trackingDB.u8string(), SQLite::Version::Latest(), SQLiteIndex::CreateOptions::SupportPathless | SQLiteIndex::CreateOptions::DisableDependenciesSupport);\r\n        }\r\n\r\n        // Call while holding the CrossProcessLock\r\n        SQLiteIndex CreateOrOpenTrackingIndex(const std::filesystem::path& trackingDB)\r\n        {\r\n            if (!std::filesystem::exists(trackingDB))\r\n            {\r\n                std::filesystem::create_directories(trackingDB.parent_path());\r\n                return CreateOnlyTrackingIndex(trackingDB);\r\n            }\r\n            else\r\n            {\r\n                try\r\n                {\r\n                    // TODO: Check schema version and upgrade as necessary when there is a relevant new schema.\r\n                    //       Could write this all now but it will be better tested when there is a new schema.\r\n                    return SQLiteIndex::Open(trackingDB.u8string(), SQLiteIndex::OpenDisposition::ReadWrite);\r\n                }\r\n                catch(...)\r\n                {\r\n                    LOG_CAUGHT_EXCEPTION_MSG(\"Exception opening tracking catalog\");\r\n                }\r\n\r\n                // Move existing database and create a new one\r\n                std::filesystem::path destination{ trackingDB };\r\n                destination.replace_filename(c_PackageTrackingCorruptedFileName);\r\n                SQLite::SQLiteStorageBase::RenameSQLiteDatabase(trackingDB, destination, true);\r\n\r\n                return CreateOnlyTrackingIndex(trackingDB);\r\n            }\r\n        }\r\n\r\n        struct PackageTrackingCatalogSourceReference : public ISourceReference\r\n        {\r\n            PackageTrackingCatalogSourceReference(const SourceDetails& details) : m_details(details) {}\r\n\r\n            SourceDetails& GetDetails() override\r\n            {\r\n                return m_details;\r\n            }\r\n\r\n            std::string GetIdentifier() override\r\n            {\r\n                return m_details.Identifier;\r\n            }\r\n\r\n            std::shared_ptr<ISource> Open(IProgressCallback& callback) override\r\n            {\r\n                m_details.Arg = Utility::MakeSuitablePathPart(m_details.Data);\r\n                std::filesystem::path trackingDB = GetPackageTrackingFilePath(m_details.Arg);\r\n\r\n                Synchronization::CrossProcessLock lock(CreateNameForCPL(m_details.Arg));\r\n                if (!lock.Acquire(callback))\r\n                {\r\n                    return {};\r\n                }\r\n\r\n                return std::make_shared<SQLiteIndexSource>(m_details, CreateOrOpenTrackingIndex(trackingDB));\r\n            }\r\n\r\n        private:\r\n            // Store the identifier of the source in the Data field.\r\n            SourceDetails m_details;\r\n        };\r\n\r\n        struct PackageTrackingCatalogSourceFactoryImpl : public ISourceFactory\r\n        {\r\n            std::string_view TypeName() const override final\r\n            {\r\n                return PackageTrackingCatalogSourceFactory::Type();\r\n            }\r\n\r\n            std::shared_ptr<ISourceReference> Create(const SourceDetails& details) override final\r\n            {\r\n                THROW_HR_IF(E_INVALIDARG, !Utility::CaseInsensitiveEquals(details.Type, PackageTrackingCatalogSourceFactory::Type()));\r\n\r\n                return std::make_shared<PackageTrackingCatalogSourceReference>(details);\r\n            }\r\n\r\n            bool Add(SourceDetails&, IProgressCallback&) override final\r\n            {\r\n                THROW_HR(E_NOTIMPL);\r\n            }\r\n\r\n            bool Update(const SourceDetails&, IProgressCallback&) override final\r\n            {\r\n                THROW_HR(E_NOTIMPL);\r\n            }\r\n\r\n            bool Remove(const SourceDetails& details, IProgressCallback& progress) override final\r\n            {\r\n                THROW_HR_IF(E_INVALIDARG, !Utility::CaseInsensitiveEquals(details.Type, PackageTrackingCatalogSourceFactory::Type()));\r\n\r\n                std::string pathName = Utility::MakeSuitablePathPart(details.Data);\r\n\r\n                Synchronization::CrossProcessLock lock(CreateNameForCPL(pathName));\r\n                if (!lock.Acquire(progress))\r\n                {\r\n                    return false;\r\n                }\r\n\r\n                std::filesystem::path trackingDB = GetPackageTrackingFilePath(pathName);\r\n\r\n                if (std::filesystem::exists(trackingDB))\r\n                {\r\n                    std::filesystem::remove(trackingDB);\r\n                }\r\n\r\n                return true;\r\n            }\r\n        };\r\n    }\r\n\r\n    struct PackageTrackingCatalog::implementation\r\n    {\r\n        std::shared_ptr<Microsoft::SQLiteIndexSource> Source;\r\n    };\r\n\r\n    PackageTrackingCatalog::PackageTrackingCatalog() = default;\r\n    PackageTrackingCatalog::PackageTrackingCatalog(const PackageTrackingCatalog&) = default;\r\n    PackageTrackingCatalog& PackageTrackingCatalog::operator=(const PackageTrackingCatalog&) = default;\r\n    PackageTrackingCatalog::PackageTrackingCatalog(PackageTrackingCatalog&&) noexcept = default;\r\n    PackageTrackingCatalog& PackageTrackingCatalog::operator=(PackageTrackingCatalog&&) noexcept = default;\r\n    PackageTrackingCatalog::~PackageTrackingCatalog() = default;\r\n\r\n    PackageTrackingCatalog PackageTrackingCatalog::CreateForSource(const Source& source)\r\n    {\r\n        // Not a valid source for tracking\r\n        const std::string sourceIdentifier = source.GetIdentifier();\r\n        if (sourceIdentifier.empty() || !source.ContainsAvailablePackages())\r\n        {\r\n            THROW_HR(E_INVALIDARG);\r\n        }\r\n\r\n        // Create fake details for the source while stashing some information that might be helpful for debugging\r\n        SourceDetails details;\r\n        details.Type = PackageTrackingCatalogSourceFactory::Type();\r\n        details.Identifier = \"*Tracking\";\r\n        details.Name = \"Tracking for \"s + source.GetDetails().Name;\r\n        details.Origin = SourceOrigin::PackageTracking;\r\n        details.Data = sourceIdentifier;\r\n\r\n        ProgressCallback dummyProgress;\r\n\r\n        PackageTrackingCatalog result;\r\n        result.m_implementation = std::make_shared<PackageTrackingCatalog::implementation>();\r\n        result.m_implementation->Source = SourceCast<SQLiteIndexSource>(ISourceFactory::GetForType(details.Type)->Create(details)->Open(dummyProgress));\r\n\r\n        return result;\r\n    }\r\n\r\n    void PackageTrackingCatalog::RemoveForSource(const std::string& identifier)\r\n    {\r\n        if (identifier.empty())\r\n        {\r\n            THROW_HR(E_INVALIDARG);\r\n        }\r\n\r\n        // Create details to pass to the factory; the identifier of the source is passed in the Data field.\r\n        SourceDetails dummyDetails;\r\n        dummyDetails.Type = PackageTrackingCatalogSourceFactory::Type();\r\n        dummyDetails.Data = identifier;\r\n\r\n        ProgressCallback dummyProgress;\r\n\r\n        ISourceFactory::GetForType(dummyDetails.Type)->Remove(dummyDetails, dummyProgress);\r\n    }\r\n\r\n    PackageTrackingCatalog::operator bool() const\r\n    {\r\n        return static_cast<bool>(m_implementation);\r\n    }\r\n\r\n    SearchResult PackageTrackingCatalog::Search(const SearchRequest& request) const\r\n    {\r\n        return m_implementation->Source->Search(request);\r\n    }\r\n\r\n    struct PackageTrackingCatalog::Version::implementation\r\n    {\r\n        SQLiteIndex::IdType Id;\r\n    };\r\n\r\n    PackageTrackingCatalog::Version::Version(const Version&) = default;\r\n    PackageTrackingCatalog::Version& PackageTrackingCatalog::Version::operator=(const Version&) = default;\r\n    PackageTrackingCatalog::Version::Version(Version&&) noexcept = default;\r\n    PackageTrackingCatalog::Version& PackageTrackingCatalog::Version::operator=(Version&&) noexcept = default;\r\n    PackageTrackingCatalog::Version::~Version() = default;\r\n\r\n    PackageTrackingCatalog::Version::Version(PackageTrackingCatalog& catalog, std::shared_ptr<implementation>&& value) :\r\n        m_catalog(&catalog), m_implementation(std::move(value)) {}\r\n\r\n    void PackageTrackingCatalog::Version::SetMetadata(PackageVersionMetadata metadata, const Utility::NormalizedString& value)\r\n    {\r\n        auto& index = m_catalog->m_implementation->Source->GetIndex();\r\n        index.SetMetadataByManifestId(m_implementation->Id, metadata, value);\r\n    }\r\n\r\n    PackageTrackingCatalog::Version PackageTrackingCatalog::RecordInstall(\r\n        Manifest::Manifest& manifest,\r\n        const Manifest::ManifestInstaller& installer,\r\n        bool isUpgrade)\r\n    {\r\n        // TODO: Store additional information from these if needed\r\n        UNREFERENCED_PARAMETER(isUpgrade);\r\n\r\n        auto& index = m_implementation->Source->GetIndex();\r\n\r\n        // Strip ARP version information from the manifest if it is present\r\n        for (auto& arpRangeRemovedInstaller : manifest.Installers)\r\n        {\r\n            for (auto& arpRangeRemovedEntry : arpRangeRemovedInstaller.AppsAndFeaturesEntries)\r\n            {\r\n                arpRangeRemovedEntry.DisplayVersion.clear();\r\n            }\r\n        }\r\n\r\n        // Check for an existing manifest that matches this one (could be reinstalling)\r\n        auto manifestIdOpt = index.GetManifestIdByManifest(manifest);\r\n\r\n        if (manifestIdOpt)\r\n        {\r\n            index.UpdateManifest(manifest);\r\n        }\r\n        else\r\n        {\r\n            manifestIdOpt = index.AddManifest(manifest);\r\n        }\r\n\r\n        SQLiteIndex::IdType manifestId = manifestIdOpt.value();\r\n\r\n        // Write additional metadata for package tracking\r\n        std::ostringstream strstr;\r\n        strstr << Utility::GetCurrentUnixEpoch();\r\n        index.SetMetadataByManifestId(manifestId, PackageVersionMetadata::TrackingWriteTime, strstr.str());\r\n\r\n        if (installer.RequireExplicitUpgrade)\r\n        {\r\n            index.SetMetadataByManifestId(manifestId, PackageVersionMetadata::PinnedState, ToString(Pinning::PinType::PinnedByManifest));\r\n        }\r\n\r\n        // Record installed architecture and locale if applicable\r\n        index.SetMetadataByManifestId(manifestId, PackageVersionMetadata::InstalledArchitecture, ToString(installer.Arch));\r\n        if (!installer.Locale.empty())\r\n        {\r\n            index.SetMetadataByManifestId(manifestId, PackageVersionMetadata::InstalledLocale, installer.Locale);\r\n        }\r\n\r\n        std::shared_ptr<Version::implementation> result = std::make_shared<Version::implementation>();\r\n        result->Id = manifestId;\r\n        return { *this, std::move(result) };\r\n    }\r\n\r\n    void PackageTrackingCatalog::RecordUninstall(const Utility::LocIndString& packageIdentifier)\r\n    {\r\n        auto& index = m_implementation->Source->GetIndex();\r\n\r\n        SearchRequest idSearch;\r\n        idSearch.Filters.emplace_back(PackageMatchField::Id, MatchType::CaseInsensitive, packageIdentifier.get());\r\n        auto searchResult = index.Search(idSearch);\r\n\r\n        for (const auto& match : searchResult.Matches)\r\n        {\r\n            auto versions = index.GetVersionKeysById(match.first);\r\n\r\n            for (const auto& version : versions)\r\n            {\r\n                index.RemoveManifestById(version.ManifestId);\r\n            }\r\n        }\r\n    }\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n    std::filesystem::path PackageTrackingCatalog::GetFilePath() const\r\n    {\r\n        return m_implementation->Source->GetIndex().GetContextData().Get<Schema::Property::DatabaseFilePath>();\r\n    }\r\n#endif\r\n\r\n    std::unique_ptr<ISourceFactory> PackageTrackingCatalogSourceFactory::Create()\r\n    {\r\n        return std::make_unique<PackageTrackingCatalogSourceFactoryImpl>();\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/PackageTrackingCatalogSourceFactory.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"SourceFactory.h\"\r\n\r\nusing namespace std::string_view_literals;\r\n\r\n\r\nnamespace AppInstaller::Repository\r\n{\r\n    // Enable test to inject a custom tracking source by integrating the internal source creation into the standard flows.\r\n    // If overriding, the opened ISource must be a SQLiteIndexSource or the code will fail.\r\n    struct PackageTrackingCatalogSourceFactory\r\n    {\r\n        // Get the type string for this source.\r\n        static constexpr std::string_view Type()\r\n        {\r\n            using namespace std::string_view_literals;\r\n            return \"Microsoft.PackageTracking\"sv;\r\n        }\r\n\r\n        // Creates a source factory for this type.\r\n        static std::unique_ptr<ISourceFactory> Create();\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/PackageVersionSelection.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/PackageVersionSelection.h\"\r\n#include \"Public/winget/RepositorySource.h\"\r\n#include \"Public/winget/PinningData.h\"\r\n\r\n\r\nnamespace AppInstaller::Repository\r\n{\r\n    namespace\r\n    {\r\n        std::shared_ptr<IPackage> GetAvailablePackageFromSource(const std::vector<std::shared_ptr<IPackage>>& packages, const std::string_view sourceIdentifier)\r\n        {\r\n            for (const std::shared_ptr<IPackage>& package : packages)\r\n            {\r\n                if (sourceIdentifier == package->GetSource().GetIdentifier())\r\n                {\r\n                    return package;\r\n                }\r\n            }\r\n\r\n            return {};\r\n        }\r\n\r\n        struct AvailablePackageVersionCollection : public IPackageVersionCollection\r\n        {\r\n            AvailablePackageVersionCollection(const std::shared_ptr<ICompositePackage>& composite, const std::shared_ptr<IPackageVersion>& installedVersion) :\r\n                m_packages(composite->GetAvailable())\r\n            {\r\n                if (!installedVersion)\r\n                {\r\n                    return;\r\n                }\r\n\r\n                m_channel = installedVersion->GetProperty(PackageVersionProperty::Channel);\r\n\r\n                // Remove the packages that are not from the installed source.\r\n                Source installedVersionSource = installedVersion->GetSource();\r\n                if (installedVersionSource && installedVersionSource.ContainsAvailablePackages())\r\n                {\r\n                    m_packages.erase(std::remove_if(m_packages.begin(), m_packages.end(), [&](const std::shared_ptr<IPackage>& p) { return installedVersionSource != p->GetSource(); }), m_packages.end());\r\n                }\r\n            }\r\n\r\n            std::vector<PackageVersionKey> GetVersionKeys() const override\r\n            {\r\n                std::vector<PackageVersionKey> result;\r\n\r\n                for (const std::shared_ptr<IPackage>& package : m_packages)\r\n                {\r\n                    std::vector<PackageVersionKey> versionKeys = package->GetVersionKeys();\r\n                    std::copy(versionKeys.begin(), versionKeys.end(), std::back_inserter(result));\r\n                }\r\n\r\n                // Remove all elements whose channel does not match the installed package.\r\n                if (m_channel)\r\n                {\r\n                    result.erase(\r\n                        std::remove_if(result.begin(), result.end(), [&](const PackageVersionKey& pvk) { return !Utility::ICUCaseInsensitiveEquals(pvk.Channel, m_channel.value()); }),\r\n                        result.end());\r\n                }\r\n\r\n                // Put latest versions at the front; for versions available from multiple sources maintain the order they were added in\r\n                std::stable_sort(result.begin(), result.end());\r\n\r\n                return result;\r\n            }\r\n\r\n            std::shared_ptr<IPackageVersion> GetVersion(const PackageVersionKey& versionKey) const override\r\n            {\r\n                // If there is a specific source, just use that package's result\r\n                std::shared_ptr<IPackage> package;\r\n\r\n                if (!versionKey.SourceId.empty())\r\n                {\r\n                    package = GetAvailablePackageFromSource(m_packages, versionKey.SourceId);\r\n                }\r\n                else if (m_packages.size() == 1)\r\n                {\r\n                    package = m_packages[0];\r\n                }\r\n                else if (versionKey.IsDefaultLatest())\r\n                {\r\n                    std::shared_ptr<IPackageVersion> result;\r\n                    Utility::Version resultVersion;\r\n\r\n                    for (const auto& p : m_packages)\r\n                    {\r\n                        std::shared_ptr<IPackageVersion> latest = p->GetLatestVersion();\r\n                        Utility::Version version { latest->GetProperty(PackageVersionProperty::Version) };\r\n\r\n                        if (!result || resultVersion < version)\r\n                        {\r\n                            result = std::move(latest);\r\n                            resultVersion = std::move(version);\r\n                        }\r\n                    }\r\n\r\n                    return result;\r\n                }\r\n                else\r\n                {\r\n                    // Otherwise, find the first version that matches\r\n                    std::vector<PackageVersionKey> versions = GetVersionKeys();\r\n\r\n                    for (const PackageVersionKey& key : versions)\r\n                    {\r\n                        if (key.IsMatch(versionKey))\r\n                        {\r\n                            package = GetAvailablePackageFromSource(m_packages, key.SourceId);\r\n                            break;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                return package ? package->GetVersion(versionKey) : nullptr;\r\n            }\r\n\r\n            std::shared_ptr<IPackageVersion> GetLatestVersion() const override\r\n            {\r\n                return GetVersion({ \"\", \"\", m_channel.value_or(\"\") });\r\n            }\r\n\r\n        private:\r\n            std::optional<std::string> m_channel;\r\n            std::vector<std::shared_ptr<IPackage>> m_packages;\r\n        };\r\n    }\r\n\r\n    std::shared_ptr<IPackageVersionCollection> GetAvailableVersionsForInstalledVersion(const std::shared_ptr<ICompositePackage>& composite)\r\n    {\r\n        return std::make_shared<AvailablePackageVersionCollection>(composite, GetInstalledVersion(composite));\r\n    }\r\n\r\n    std::shared_ptr<IPackageVersionCollection> GetAvailableVersionsForInstalledVersion(\r\n        const std::shared_ptr<ICompositePackage>& composite,\r\n        const std::shared_ptr<IPackageVersion>& installedVersion)\r\n    {\r\n        return std::make_shared<AvailablePackageVersionCollection>(composite, installedVersion);\r\n    }\r\n\r\n    std::shared_ptr<IPackageVersionCollection> GetAllAvailableVersions(const std::shared_ptr<ICompositePackage>& composite)\r\n    {\r\n        return GetAvailableVersionsForInstalledVersion(composite, nullptr);\r\n    }\r\n\r\n    std::shared_ptr<IPackageVersion> GetInstalledVersion(const std::shared_ptr<ICompositePackage>& composite)\r\n    {\r\n        auto installedPackage = composite->GetInstalled();\r\n        return installedPackage ? installedPackage->GetLatestVersion() : nullptr;\r\n    }\r\n\r\n    std::shared_ptr<IPackage> GetAvailablePackageFromSource(const std::shared_ptr<ICompositePackage>& composite, const std::string_view sourceIdentifier)\r\n    {\r\n        return GetAvailablePackageFromSource(composite->GetAvailable(), sourceIdentifier);\r\n    }\r\n\r\n    LatestApplicableVersionData GetLatestApplicableVersion(const std::shared_ptr<ICompositePackage>& composite)\r\n    {\r\n        using namespace AppInstaller::Pinning;\r\n\r\n        LatestApplicableVersionData result;\r\n\r\n        auto installedVersion = AppInstaller::Repository::GetInstalledVersion(composite);\r\n        auto availableVersions = AppInstaller::Repository::GetAvailableVersionsForInstalledVersion(composite, installedVersion);\r\n\r\n        PinningData pinningData{ PinningData::Disposition::ReadOnly };\r\n        auto evaluator = pinningData.CreatePinStateEvaluator(PinBehavior::ConsiderPins, installedVersion);\r\n\r\n        AppInstaller::Manifest::ManifestComparator::Options options;\r\n        if (installedVersion)\r\n        {\r\n            GetManifestComparatorOptionsFromMetadata(options, installedVersion->GetMetadata());\r\n        }\r\n        AppInstaller::Manifest::ManifestComparator manifestComparator{ options };\r\n\r\n        auto availableVersionKeys = availableVersions->GetVersionKeys();\r\n        for (const auto& availableVersionKey : availableVersionKeys)\r\n        {\r\n            auto availableVersion = availableVersions->GetVersion(availableVersionKey);\r\n\r\n            if (installedVersion && !evaluator.IsUpdate(availableVersion))\r\n            {\r\n                // Version too low or different channel for upgrade\r\n                continue;\r\n            }\r\n\r\n            if (evaluator.EvaluatePinType(availableVersion) != AppInstaller::Pinning::PinType::Unknown)\r\n            {\r\n                // Pinned\r\n                continue;\r\n            }\r\n\r\n            auto manifestComparatorResult = manifestComparator.GetPreferredInstaller(availableVersion->GetManifest());\r\n            if (!manifestComparatorResult.installer.has_value())\r\n            {\r\n                // No applicable installer\r\n                continue;\r\n            }\r\n\r\n            result.LatestApplicableVersion = availableVersion;\r\n            if (installedVersion)\r\n            {\r\n                result.UpdateAvailable = true;\r\n            }\r\n\r\n            break;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    void GetManifestComparatorOptionsFromMetadata(AppInstaller::Manifest::ManifestComparator::Options& options, const IPackageVersion::Metadata& metadata, bool includeAllowedArchitectures)\r\n    {\r\n        auto installedTypeItr = metadata.find(Repository::PackageVersionMetadata::InstalledType);\r\n        if (installedTypeItr != metadata.end())\r\n        {\r\n            options.CurrentlyInstalledType = Manifest::ConvertToInstallerTypeEnum(installedTypeItr->second);\r\n        }\r\n\r\n        auto installedScopeItr = metadata.find(Repository::PackageVersionMetadata::InstalledScope);\r\n        if (installedScopeItr != metadata.end())\r\n        {\r\n            options.CurrentlyInstalledScope = Manifest::ConvertToScopeEnum(installedScopeItr->second);\r\n        }\r\n\r\n        auto userIntentLocaleItr = metadata.find(Repository::PackageVersionMetadata::UserIntentLocale);\r\n        if (userIntentLocaleItr != metadata.end())\r\n        {\r\n            options.PreviousUserIntentLocale = userIntentLocaleItr->second;\r\n        }\r\n\r\n        auto installedLocaleItr = metadata.find(Repository::PackageVersionMetadata::InstalledLocale);\r\n        if (installedLocaleItr != metadata.end())\r\n        {\r\n            options.CurrentlyInstalledLocale = installedLocaleItr->second;\r\n        }\r\n\r\n        if (includeAllowedArchitectures)\r\n        {\r\n            auto userIntentItr = metadata.find(Repository::PackageVersionMetadata::UserIntentArchitecture);\r\n            if (userIntentItr != metadata.end())\r\n            {\r\n                // For upgrade, user intent from previous install is considered requirement\r\n                options.AllowedArchitectures.emplace_back(Utility::ConvertToArchitectureEnum(userIntentItr->second));\r\n            }\r\n            else\r\n            {\r\n                auto installedItr = metadata.find(Repository::PackageVersionMetadata::InstalledArchitecture);\r\n                if (installedItr != metadata.end())\r\n                {\r\n                    // For upgrade, previous installed architecture should be considered first preference and is always allowed.\r\n                    // Then check settings requirements and preferences.\r\n                    options.AllowedArchitectures.emplace_back(Utility::ConvertToArchitectureEnum(installedItr->second));\r\n                }\r\n\r\n                std::vector<Utility::Architecture> requiredArchitectures = Settings::User().Get<Settings::Setting::InstallArchitectureRequirement>();\r\n                std::vector<Utility::Architecture> optionalArchitectures = Settings::User().Get<Settings::Setting::InstallArchitecturePreference>();\r\n\r\n                if (!requiredArchitectures.empty())\r\n                {\r\n                    // Required architecture list from settings if applicable\r\n                    options.AllowedArchitectures.insert(options.AllowedArchitectures.end(), requiredArchitectures.begin(), requiredArchitectures.end());\r\n                }\r\n                else\r\n                {\r\n                    // Preferred architecture list from settings if applicable, add Unknown to indicate allowing remaining applicable\r\n                    if (!optionalArchitectures.empty())\r\n                    {\r\n                        options.AllowedArchitectures.insert(options.AllowedArchitectures.end(), optionalArchitectures.begin(), optionalArchitectures.end());\r\n                    }\r\n\r\n                    options.AllowedArchitectures.emplace_back(Utility::Architecture::Unknown);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    std::optional<int32_t> GetSourcePriority(const std::shared_ptr<ICompositePackage>& composite)\r\n    {\r\n        auto installed = composite->GetInstalled();\r\n\r\n        if (installed)\r\n        {\r\n            auto installedVersion = installed->GetLatestVersion();\r\n\r\n            if (installedVersion)\r\n            {\r\n                auto installedSource = installedVersion->GetSource();\r\n\r\n                if (installedSource.ContainsAvailablePackages())\r\n                {\r\n                    return installedSource.GetDetails().Priority;\r\n                }\r\n            }\r\n        }\r\n\r\n        auto available = composite->GetAvailable();\r\n\r\n        if (!available.empty())\r\n        {\r\n            return available.front()->GetSource().GetDetails().Priority;\r\n        }\r\n\r\n        return std::nullopt;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/PinningData.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/PinningData.h\"\r\n#include \"Microsoft/PinningIndex.h\"\r\n#include \"Public/winget/RepositorySource.h\"\r\n\r\nusing namespace AppInstaller::SQLite;\r\nusing namespace AppInstaller::Repository;\r\nusing namespace AppInstaller::Repository::Microsoft;\r\n\r\nnamespace AppInstaller::Pinning\r\n{\r\n    namespace\r\n    {\r\n        // Evaluates the pinning state of a version for a single pin.\r\n        PinType EvaluatePinnedStateForVersion(\r\n            const Utility::Version& version,\r\n            const std::optional<Pin>& pin,\r\n            PinBehavior behavior)\r\n        {\r\n            if (pin)\r\n            {\r\n                if (pin->GetType() == PinType::Blocking\r\n                    || (pin->GetType() == PinType::Pinning && behavior != PinBehavior::IncludePinned)\r\n                    || (pin->GetType() == PinType::Gating && !pin->GetGatedVersion().IsValidVersion(version)))\r\n                {\r\n                    return pin->GetType();\r\n                }\r\n            }\r\n\r\n            return PinType::Unknown;\r\n        }\r\n\r\n        // Gets the pinned state for an available version that may have a pin,\r\n        // and optionally an additional pin that could come from the installed version.\r\n        // If both pins are present, we return the one that is the most strict.\r\n        Pinning::PinType GetPinnedStateForVersion(\r\n            const Utility::Version& version,\r\n            const std::optional<Pinning::Pin>& availablePin,\r\n            const std::optional<Pinning::Pin>& installedPin,\r\n            PinBehavior behavior)\r\n        {\r\n            if (behavior == PinBehavior::IgnorePins)\r\n            {\r\n                return Pinning::PinType::Unknown;\r\n            }\r\n\r\n            return Stricter(\r\n                EvaluatePinnedStateForVersion(version, availablePin, behavior),\r\n                EvaluatePinnedStateForVersion(version, installedPin, behavior));\r\n        }\r\n    }\r\n\r\n    PinningData::PinningData() = default;\r\n    PinningData::PinningData(const PinningData&) = default;\r\n    PinningData& PinningData::operator=(const PinningData&) = default;\r\n    PinningData::PinningData(PinningData&&) noexcept = default;\r\n    PinningData& PinningData::operator=(PinningData&&) noexcept = default;\r\n    PinningData::~PinningData() = default;\r\n\r\n    PinningData::PinningData(Disposition disposition)\r\n    {\r\n        if (disposition == Disposition::ReadOnly)\r\n        {\r\n            m_database = PinningIndex::OpenIfExists(SQLiteStorageBase::OpenDisposition::Read);\r\n        }\r\n        else\r\n        {\r\n            m_database = PinningIndex::OpenOrCreateDefault(SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n        }\r\n    }\r\n\r\n    PinningData::operator bool() const\r\n    {\r\n        return IsDatabaseConnected();\r\n    }\r\n\r\n    bool PinningData::IsDatabaseConnected() const\r\n    {\r\n        return static_cast<bool>(m_database);\r\n    }\r\n\r\n    void PinningData::AddOrUpdatePin(const Pin& pin)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !IsDatabaseConnected());\r\n        m_database->AddOrUpdatePin(pin);\r\n    }\r\n\r\n    void PinningData::RemovePin(const PinKey& pinKey)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !IsDatabaseConnected());\r\n        m_database->RemovePin(pinKey);\r\n    }\r\n\r\n    std::optional<Pin> PinningData::GetPin(const PinKey& pinKey)\r\n    {\r\n        return IsDatabaseConnected() ? m_database->GetPin(pinKey) : std::nullopt;\r\n    }\r\n\r\n    std::vector<Pin> PinningData::GetAllPins()\r\n    {\r\n        return IsDatabaseConnected() ? m_database->GetAllPins() : std::vector<Pin>{};\r\n    }\r\n\r\n    bool PinningData::ResetAllPins(std::string_view sourceId)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !IsDatabaseConnected());\r\n        return m_database->ResetAllPins(sourceId);\r\n    }\r\n\r\n    PinningData::PinStateEvaluator::PinStateEvaluator(\r\n        PinBehavior behavior,\r\n        std::shared_ptr<PinningIndex> database,\r\n        const std::shared_ptr<IPackageVersion>& installedVersion) :\r\n        m_behavior(behavior), m_database(std::move(database))\r\n    {\r\n        if (m_behavior == PinBehavior::IgnorePins || !installedVersion)\r\n        {\r\n            // Because the database isn't guaranteed to be present, align ignoring pins with there being no pins to ignore.\r\n            // Also do not consider pins when there is no installed version. This is to remain consistent with the previous\r\n            // implementation. If this is to be changed, more install paths will need to be do pinning checks to ensure\r\n            // that one could, for instance, block the install of a package.\r\n            m_database.reset();\r\n        }\r\n        else if (m_database)\r\n        {\r\n            PinKey key = PinKey::GetPinKeyForInstalled(installedVersion->GetProperty(PackageVersionProperty::Id));\r\n            m_installedPin = m_database->GetPin(key);\r\n        }\r\n\r\n        if (installedVersion)\r\n        {\r\n            m_installedVersion = Utility::VersionAndChannel{\r\n                Utility::Version{ installedVersion->GetProperty(PackageVersionProperty::Version) },\r\n                Utility::Channel{ installedVersion->GetProperty(PackageVersionProperty::Channel) }\r\n            };\r\n        }\r\n    }\r\n\r\n    PinningData::PinStateEvaluator::PinStateEvaluator(const PinStateEvaluator&) = default;\r\n    PinningData::PinStateEvaluator& PinningData::PinStateEvaluator::operator=(const PinStateEvaluator&) = default;\r\n    PinningData::PinStateEvaluator::PinStateEvaluator(PinStateEvaluator&&) noexcept = default;\r\n    PinningData::PinStateEvaluator& PinningData::PinStateEvaluator::operator=(PinStateEvaluator&&) noexcept = default;\r\n\r\n    PinningData::PinStateEvaluator::~PinStateEvaluator() = default;\r\n\r\n    std::shared_ptr<IPackageVersion> PinningData::PinStateEvaluator::GetLatestAvailableVersionForPins(const std::shared_ptr<IPackageVersionCollection>& package)\r\n    {\r\n        if (!m_database)\r\n        {\r\n            return package->GetLatestVersion();\r\n        }\r\n\r\n        auto availableVersionKeys = package->GetVersionKeys();\r\n\r\n        // Skip until we find a version that isn't pinned\r\n        for (const auto& availableVersion : availableVersionKeys)\r\n        {\r\n            std::shared_ptr<IPackageVersion> packageVersion = package->GetVersion(availableVersion);\r\n            if (EvaluatePinType(packageVersion) == Pinning::PinType::Unknown)\r\n            {\r\n                return packageVersion;\r\n            }\r\n        }\r\n\r\n        return {};\r\n    }\r\n\r\n    bool PinningData::PinStateEvaluator::IsUpdate(const std::shared_ptr<IPackageVersion>& availableVersion)\r\n    {\r\n        if (m_installedVersion && availableVersion)\r\n        {\r\n            Utility::VersionAndChannel availableVersionAndChannel{\r\n                Utility::Version{ availableVersion->GetProperty(PackageVersionProperty::Version) },\r\n                Utility::Channel{ availableVersion->GetProperty(PackageVersionProperty::Channel) }\r\n            };\r\n\r\n            return m_installedVersion->IsUpdatedBy(availableVersionAndChannel);\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    PinType PinningData::PinStateEvaluator::EvaluatePinType(const std::shared_ptr<AppInstaller::Repository::IPackageVersion>& packageVersion)\r\n    {\r\n        if (!m_database || !packageVersion)\r\n        {\r\n            return PinType::Unknown;\r\n        }\r\n\r\n        std::optional<Pin> incomingPin;\r\n\r\n        PinKey pinKey{ packageVersion->GetProperty(PackageVersionProperty::Id).get(), packageVersion->GetSource().GetIdentifier()};\r\n        auto itr = m_availablePins.find(pinKey);\r\n        if (itr == m_availablePins.end())\r\n        {\r\n            incomingPin = m_database->GetPin(pinKey);\r\n            m_availablePins[pinKey] = incomingPin;\r\n        }\r\n        else\r\n        {\r\n            incomingPin = itr->second;\r\n        }\r\n\r\n        return GetPinnedStateForVersion(packageVersion->GetProperty(PackageVersionProperty::Version).get(), incomingPin, m_installedPin, m_behavior);\r\n    }\r\n\r\n    // Creates an object for use in evaluating pinning data for a given package\r\n    PinningData::PinStateEvaluator PinningData::CreatePinStateEvaluator(\r\n        PinBehavior behavior,\r\n        const std::shared_ptr<IPackageVersion>& installedVersion)\r\n    {\r\n        return { behavior, m_database, installedVersion };\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/PropertySheet.props",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ImportGroup Label=\"PropertySheets\" />\n  <PropertyGroup Label=\"UserMacros\" />\n    <!--\n    To customize common C++/WinRT project properties: \n    * right-click the project node\n    * expand the Common Properties item\n    * select the C++/WinRT property page\n\n    For more advanced scenarios, and complete documentation, please see:\n    https://github.com/Microsoft/xlang/tree/master/src/package/cppwinrt/nuget \n    -->\n  <PropertyGroup />\n  <ItemDefinitionGroup />\n</Project>"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Public/winget/ARPCorrelation.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n\r\n#include <winget/LocIndependent.h>\r\n#include <winget/RepositorySource.h>\r\n\r\n#include <memory>\r\n#include <utility>\r\n#include <vector>\r\n\r\nnamespace AppInstaller\r\n{\r\n    namespace Manifest\r\n    {\r\n        struct Manifest;\r\n        struct ManifestLocalization;\r\n    }\r\n\r\n    namespace Repository\r\n    {\r\n        struct IPackage;\r\n        struct IPackageVersion;\r\n        struct Source;\r\n    }\r\n}\r\n\r\nnamespace AppInstaller::Repository::Correlation\r\n{\r\n    // Contains the { Id, Version, Channel }\r\n    using ARPEntrySnapshot = std::tuple<Utility::LocIndString, Utility::LocIndString, Utility::LocIndString>;\r\n\r\n    // Struct holding all the data from an ARP entry we use for the correlation\r\n    struct ARPEntry\r\n    {\r\n        ARPEntry(std::shared_ptr<AppInstaller::Repository::IPackage> entry, bool isNewOrUpdated) : Entry(std::move(entry)), IsNewOrUpdated(isNewOrUpdated) {}\r\n\r\n        // Data found in the ARP entry\r\n        std::shared_ptr<AppInstaller::Repository::IPackage> Entry;\r\n\r\n        // Whether this entry changed with the current installation\r\n        bool IsNewOrUpdated;\r\n    };\r\n\r\n    // One of the possible options that could be chosen for correlation.\r\n    struct CorrelationMeasure\r\n    {\r\n        // The value that the correlation algorithm assigned to the match with the package.\r\n        double Measure{};\r\n\r\n        // The package that was measured.\r\n        std::shared_ptr<AppInstaller::Repository::IPackageVersion> Package{};\r\n    };\r\n\r\n    // The result of a heuristics correlation attempt.\r\n    struct ARPHeuristicsCorrelationResult\r\n    {\r\n        // Correlated package from ARP\r\n        std::shared_ptr<AppInstaller::Repository::IPackageVersion> Package{};\r\n\r\n        // The reason for the correlation (for diagnostics).\r\n        std::string Reason;\r\n\r\n        // The correlation metrics and their associated ARP package information (for diagnostics).\r\n        std::vector<CorrelationMeasure> Measures;\r\n    };\r\n\r\n    // The result of a correlation attempt.\r\n    struct ARPCorrelationResult : public ARPHeuristicsCorrelationResult\r\n    {\r\n        // Number of ARP entries that are new or updated\r\n        size_t ChangesToARP{};\r\n\r\n        // Number of ARP entries that match with the installed package\r\n        size_t MatchesInARP{};\r\n\r\n        // Number of changed ARP entries that match the installed package\r\n        size_t CountOfIntersectionOfChangesAndMatches{};\r\n\r\n        ARPCorrelationResult& operator=(ARPHeuristicsCorrelationResult&& other)\r\n        {\r\n            *static_cast<ARPHeuristicsCorrelationResult*>(this) = std::move(other);\r\n            return *this;\r\n        }\r\n    };\r\n\r\n    // Allows callers finer control over how the correlation result will be chosen.\r\n    // The values appear in order of their application in the correlation algorithm, meaning that a later\r\n    // setting that is set to true can be preempted by an earlier setting, if a correlation occurs with the\r\n    // earlier setting.\r\n    // The default values are chosen to reflect what is used after an install on a consumer system.\r\n    struct ARPCorrelationSettings\r\n    {\r\n        // This setting controls whether the name and publisher normalization algorithm will be used for correlation.\r\n        // When true, normalization will be the first choice for correlation. This means that a normalized name+publisher\r\n        // match will result in correlation (unless there are multiple matches).\r\n        // When false, normalization will only be used for the statistics (MatchesInARP), but the correlation result package\r\n        // will not be based on normalization.\r\n        bool AllowNormalization = true;\r\n\r\n        // This settings controls whether a single changed ARP entry is sufficient to result in correlation.\r\n        // When true, if only a single ARP entry is detected as new or changed, it will be chosen as the correlated result.\r\n        bool AllowSingleChange = false;\r\n    };\r\n\r\n    struct IARPMatchConfidenceAlgorithm\r\n    {\r\n        virtual ~IARPMatchConfidenceAlgorithm() = default;\r\n        virtual void Init(const AppInstaller::Manifest::Manifest& manifest) = 0;\r\n        virtual double ComputeConfidence(const ARPEntry& arpEntry) const = 0;\r\n\r\n        // Returns an instance of the algorithm we will actually use.\r\n        // We may use multiple instances/specializations for testing and experimentation.\r\n        static IARPMatchConfidenceAlgorithm& Instance();\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        static void OverrideInstance(IARPMatchConfidenceAlgorithm* algorithmOverride);\r\n        static void ResetInstance();\r\n#endif\r\n    };\r\n\r\n    ARPHeuristicsCorrelationResult FindARPEntryForNewlyInstalledPackageWithHeuristics(\r\n        const AppInstaller::Manifest::Manifest& manifest,\r\n        const std::vector<ARPEntry>& arpEntries);\r\n\r\n    ARPHeuristicsCorrelationResult FindARPEntryForNewlyInstalledPackageWithHeuristics(\r\n        const AppInstaller::Manifest::Manifest& manifest,\r\n        const std::vector<ARPEntry>& arpEntries,\r\n        IARPMatchConfidenceAlgorithm& algorithm);\r\n\r\n    // Holds data needed for ARP correlation, as well as functions to run correlation on the collected data.\r\n    struct ARPCorrelationData\r\n    {\r\n        ARPCorrelationData() = default;\r\n        virtual ~ARPCorrelationData() = default;\r\n\r\n        // Captures the ARP state before the package installation.\r\n        void CapturePreInstallSnapshot();\r\n\r\n        // Captures the ARP state differences after the package installation.\r\n        void CapturePostInstallSnapshot();\r\n\r\n        // Correlates the given manifest against the data previously collected with capture calls.\r\n        virtual ARPCorrelationResult CorrelateForNewlyInstalled(const Manifest::Manifest& manifest, const ARPCorrelationSettings& settings = {});\r\n\r\n        const std::vector<ARPEntrySnapshot>& GetPreInstallSnapshot() const { return m_preInstallSnapshot; }\r\n\r\n    private:\r\n        std::vector<ARPEntrySnapshot> m_preInstallSnapshot;\r\n\r\n        Source m_postInstallSnapshotSource;\r\n        std::vector<Correlation::ARPEntry> m_postInstallSnapshot;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Public/winget/ARPCorrelationAlgorithms.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n\r\n#include <winget/ARPCorrelation.h>\r\n#include <winget/Manifest.h>\r\n#include <winget/NameNormalization.h>\r\n#include <winget/RepositorySearch.h>\r\n#include <winget/RepositorySource.h>\r\n\r\nnamespace AppInstaller::Repository::Correlation\r\n{\r\n    struct EmptyMatchConfidenceAlgorithm : public IARPMatchConfidenceAlgorithm\r\n    {\r\n        void Init(const AppInstaller::Manifest::Manifest&) override {}\r\n        double ComputeConfidence(const ARPEntry&) const override { return 0; }\r\n    };\r\n\r\n    // Algorithm that computes the match confidence by looking at the edit distance between\r\n    // the sequences of words in the name and publisher.\r\n    // The edit distance for this allows only adding or removing words, not editing them,\r\n    // as that would make any two names too similar.\r\n    struct WordsEditDistanceMatchConfidenceAlgorithm : public IARPMatchConfidenceAlgorithm\r\n    {\r\n        using WordSequence = std::vector<std::string>;\r\n\r\n        struct NameAndPublisher\r\n        {\r\n            NameAndPublisher(const WordSequence& name, const WordSequence& publisher);\r\n            NameAndPublisher(WordSequence&& name, WordSequence&& publisher);\r\n\r\n            WordSequence Name;\r\n            WordSequence Publisher;\r\n            WordSequence NamePublisher;\r\n        };\r\n\r\n        void Init(const AppInstaller::Manifest::Manifest& manifest) override;\r\n        double ComputeConfidence(const ARPEntry& arpEntry) const override;\r\n\r\n    private:\r\n        WordSequence PrepareString(std::string_view s) const;\r\n        WordSequence NormalizeAndPrepareName(std::string_view name) const;\r\n        WordSequence NormalizeAndPreparePublisher(std::string_view publisher) const;\r\n\r\n        AppInstaller::Utility::NameNormalizer m_normalizer{ AppInstaller::Utility::NormalizationVersion::InitialPreserveWhiteSpace };\r\n        std::vector<NameAndPublisher> m_namesAndPublishers;\r\n\r\n        // Parameters for the algorithm\r\n\r\n        // How much weight to give to the string matching score.\r\n        // The rest is assigned by whether the entry is new.\r\n        const double m_stringMatchingWeight = 0.8;\r\n\r\n        // How much weight to give to the matching score of the package name;\r\n        // the rest is assigned to the publisher score.\r\n        const double m_nameMatchingScoreWeight = 2. / 3.;\r\n\r\n        // Minimum score needed in the name for us to accept a match.\r\n        // This prevents us from being misled by a long match in the publisher.\r\n        const double m_nameMatchingScoreMinThreshold = 0.2;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Public/winget/Checkpoint.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include <winget/CheckpointDatabase.h>\n#include <guiddef.h>\n\nusing namespace AppInstaller::Repository::Microsoft;\n\nnamespace AppInstaller::Checkpoints\n{\n    enum AutomaticCheckpointData\n    {\n        ClientVersion,\n        Command,\n        Arguments,\n        ResumeCount\n    };\n\n    struct CheckpointManager;\n\n    // A representation of a row in the Checkpoint table.\n    template <typename T>\n    struct Checkpoint\n    {\n        static_assert(std::is_enum<T>::value);\n        friend CheckpointManager;\n\n        std::vector<T> GetCheckpointDataTypes()\n        {\n            return m_checkpointDatabase->GetDataTypes(m_checkpointId);\n        }\n\n        // Returns a boolean value indicating whether the field name exists.\n        bool Has(T dataType, const std::string& fieldName)\n        {\n            return m_checkpointDatabase->HasDataField(m_checkpointId, dataType, fieldName);\n        }\n\n        // Gets all available field names.\n        std::vector<std::string> GetFieldNames(T dataType)\n        {\n            return m_checkpointDatabase->GetDataFieldNames(m_checkpointId, dataType);\n        }\n\n        // Sets a single field value for a data type.\n        void Set(T dataType, const std::string& fieldName, const std::string& value)\n        {\n            m_checkpointDatabase->SetDataValue(m_checkpointId, dataType, fieldName, { value });\n        }\n\n        // Sets multiple field values for a data type.\n        void SetMany(T dataType, const std::string& fieldName, const std::vector<std::string>& values)\n        {\n            m_checkpointDatabase->SetDataValue(m_checkpointId, dataType, fieldName, values);\n        }\n\n        // Update a single existing field value for a data type.\n        void Update(T dataType, const std::string& fieldName, const std::string& value)\n        {\n            m_checkpointDatabase->UpdateDataValue(m_checkpointId, dataType, fieldName, { value });\n        }\n\n        // Gets a single field value for a data type.\n        std::string Get(T dataType, const std::string& fieldName)\n        {\n            return m_checkpointDatabase->GetDataFieldSingleValue(m_checkpointId, dataType, fieldName);\n        }\n\n        // Gets multiple field values for a data type.\n        std::vector<std::string> GetMany(T dataType, const std::string& fieldName)\n        {\n            return m_checkpointDatabase->GetDataFieldMultiValue(m_checkpointId, dataType, fieldName);\n        }\n\n    private: \n        Checkpoint(std::shared_ptr<AppInstaller::Repository::Microsoft::CheckpointDatabase> checkpointDatabase, AppInstaller::Repository::Microsoft::CheckpointDatabase::IdType checkpointId) :\n            m_checkpointDatabase(checkpointDatabase), m_checkpointId(checkpointId){};\n\n        AppInstaller::Repository::Microsoft::CheckpointDatabase::IdType m_checkpointId;\n        std::shared_ptr<CheckpointDatabase> m_checkpointDatabase;\n    };\n}"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Public/winget/CheckpointDatabase.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include <winget/SQLiteWrapper.h>\n#include <winget/SQLiteStorageBase.h>\n#include <winget/ManagedFile.h>\n\nnamespace AppInstaller::Repository::Microsoft\n{\n    namespace Schema\n    {\n        struct ICheckpointDatabase;\n    }\n\n    struct CheckpointDatabase : SQLite::SQLiteStorageBase\n    {\n        // An id that refers to a specific Checkpoint.\n        using IdType = SQLite::rowid_t;\n\n        CheckpointDatabase(const CheckpointDatabase&) = delete;\n        CheckpointDatabase& operator=(const CheckpointDatabase&) = delete;\n\n        CheckpointDatabase(CheckpointDatabase&&);\n        CheckpointDatabase& operator=(CheckpointDatabase&&);\n\n        // Create a new checkpoint database.\n        static std::shared_ptr<CheckpointDatabase> CreateNew(const std::string& filePath, SQLite::Version version = SQLite::Version::Latest());\n\n        // Opens an existing checkpoint database.\n        static std::shared_ptr<CheckpointDatabase> Open(const std::string& filePath, OpenDisposition disposition = OpenDisposition::ReadWrite, Utility::ManagedFile&& indexFile = {});\n\n        // Returns a value indicating whether the database is empty.\n        bool IsEmpty();\n\n        // Adds a new checkpoint name to the checkpoint table.\n        IdType AddCheckpoint(std::string_view checkpointName);\n\n        // Returns all checkpoint ids in descending (newest at the front) order.\n        std::vector<IdType> GetCheckpointIds();\n\n        // Returns a boolean value indicating a field exists for a checkpoint data type.\n        bool HasDataField(IdType checkpointId, int type, const std::string& name);\n\n        // Returns the available data types for a checkpoint id.\n        std::vector<int> GetDataTypes(IdType checkpointId);\n\n        // Returns the available field names for a checkpoint data.\n        std::vector<std::string> GetDataFieldNames(IdType checkpointId, int dataType);\n\n        // Sets the value(s) for a data type and field.\n        void SetDataValue(IdType checkpointId, int dataType, const std::string& field, const std::vector<std::string>& values);\n\n        // Updates the value(s) for a data type and field.\n        void UpdateDataValue(IdType checkpointId, int dataType, const std::string& field, const std::vector<std::string>& values);\n\n        // Gets a single value for a data type field.\n        std::string GetDataFieldSingleValue(IdType checkpointId, int dataType, const std::string& field);\n\n        // Gets multiple values for a data type field.\n        std::vector<std::string> GetDataFieldMultiValue(IdType checkpointId, int dataType, const std::string& field);\n\n        // Removes the value(s) for a data type.\n        void RemoveDataType(IdType checkpointId, int dataType);\n\n    private:\n        // Constructor used to open an existing index.\n        CheckpointDatabase(const std::string& target, SQLiteStorageBase::OpenDisposition disposition, Utility::ManagedFile&& indexFile);\n\n        // Constructor used to create a new index.\n        CheckpointDatabase(const std::string& target, SQLite::Version version);\n\n        std::unique_ptr<Schema::ICheckpointDatabase> m_interface;\n    };\n}"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Public/winget/IconExtraction.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include <vector>\n#include <winget/Manifest.h>\n\nnamespace AppInstaller::Repository\n{\n    struct ExtractedIconInfo\n    {\n        std::vector<BYTE> IconContent;\n        std::vector<BYTE> IconSha256;\n        AppInstaller::Manifest::IconFileTypeEnum IconFileType = AppInstaller::Manifest::IconFileTypeEnum::Unknown;\n        AppInstaller::Manifest::IconThemeEnum IconTheme = AppInstaller::Manifest::IconThemeEnum::Unknown;\n        AppInstaller::Manifest::IconResolutionEnum IconResolution = AppInstaller::Manifest::IconResolutionEnum::Unknown;\n    };\n\n    // The usage of iconIndex is same as usage in ExtractIconEx at\n    // https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-extracticonexw\n    // The icon index usage is basically:\n    //     0, 1, 2        means zero-based index of the first icon to extract.\n    //     -1, -2, -3     means extract icon whose resource name is 1, 2, 3 etc\n    std::vector<BYTE> ExtractIconFromBinaryFile(const std::filesystem::path binaryPath, int iconIndex = 0);\n\n    // Extracts the app icon given the app's product code.\n    // This method uses similar logic for retrieving icon as app list in settings page.\n    // This method returns empty if only default icons would be picked.\n    // This method returns contents of .ico icons.\n    std::vector<ExtractedIconInfo> ExtractIconFromArpEntry(const std::string& productCode, AppInstaller::Manifest::ScopeEnum scope = AppInstaller::Manifest::ScopeEnum::Unknown);\n}\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Public/winget/InstalledFilesCorrelation.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/Manifest.h>\r\n#include <winget/FolderFileWatcher.h>\r\n#include <optional>\r\n\r\nnamespace AppInstaller::Repository::Correlation\r\n{\r\n    // TODO: This definition could be moved to Manifest when winget supports launch scenarios.\r\n    struct InstalledStartupLinkFile\r\n    {\r\n        // Relative file path to the startup menu folder.\r\n        // Same installers write the links to user startup folder or machine startup folder depending on the scope\r\n        // the installers were running for. So only relative file paths were collected. And seems enough.\r\n        AppInstaller::Manifest::string_t RelativeFilePath;\r\n        // Heuristic startup link type.\r\n        AppInstaller::Manifest::InstalledFileTypeEnum FileType = AppInstaller::Manifest::InstalledFileTypeEnum::Unknown;\r\n    };\r\n\r\n    struct InstallationMetadata\r\n    {\r\n        // Installed files metadata. Currently only capturing files pointed by a startup link.\r\n        AppInstaller::Manifest::InstallationMetadataInfo InstalledFiles;\r\n        // Startup links metadata.\r\n        std::vector<InstalledStartupLinkFile> StartupLinkFiles;\r\n    };\r\n\r\n    struct InstalledFilesCorrelation\r\n    {\r\n        // Constructor initializes the file watchers.\r\n        InstalledFilesCorrelation();\r\n        virtual ~InstalledFilesCorrelation() = default;\r\n\r\n        // Start the file watcher before the package installation.\r\n        virtual void StartFileWatcher();\r\n\r\n        // Stop the file watcher after the package installation.\r\n        virtual void StopFileWatcher();\r\n\r\n        // Correlates the given manifest against the data previously collected with capture calls.\r\n        virtual InstallationMetadata CorrelateForNewlyInstalled(\r\n            const Manifest::Manifest& manifest,\r\n            const std::string& arpInstallLocation);\r\n\r\n    private:\r\n        struct FileWatcherFiles\r\n        {\r\n            // FileWatcher folder base.\r\n            std::filesystem::path Folder;\r\n            // List of files represented as relative file path to the base folder.\r\n            std::vector<std::filesystem::path> Files;\r\n        };\r\n\r\n        std::vector<AppInstaller::Utility::FolderFileWatcher> m_fileWatchers;\r\n        std::vector<FileWatcherFiles> m_files;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Public/winget/InstalledStatus.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerStrings.h>\r\n#include <winget/Manifest.h>\r\n#include <winget/RepositorySearch.h>\r\n\r\n#include <memory>\r\n#include <vector>\r\n\r\n\r\nnamespace AppInstaller::Repository\r\n{\r\n    // Defines the installed status check type.\r\n    enum class InstalledStatusType : uint32_t\r\n    {\r\n        // None is checked.\r\n        None = 0x0,\r\n        // Check Apps and Features entry.\r\n        AppsAndFeaturesEntry = 0x0001,\r\n        // Check Apps and Features entry install location if applicable.\r\n        AppsAndFeaturesEntryInstallLocation = 0x0002,\r\n        // Check Apps and Features entry install location with installed files if applicable.\r\n        AppsAndFeaturesEntryInstallLocationFile = 0x0004,\r\n        // Check default install location if applicable.\r\n        DefaultInstallLocation = 0x0008,\r\n        // Check default install location with installed files if applicable.\r\n        DefaultInstallLocationFile = 0x0010,\r\n\r\n        // Below are helper values for calling CheckInstalledStatus as input.\r\n        // AppsAndFeaturesEntry related checks\r\n        AllAppsAndFeaturesEntryChecks = AppsAndFeaturesEntry | AppsAndFeaturesEntryInstallLocation | AppsAndFeaturesEntryInstallLocationFile,\r\n        // DefaultInstallLocation related checks\r\n        AllDefaultInstallLocationChecks = DefaultInstallLocation | DefaultInstallLocationFile,\r\n        // All checks\r\n        AllChecks = AllAppsAndFeaturesEntryChecks | AllDefaultInstallLocationChecks,\r\n    };\r\n\r\n    DEFINE_ENUM_FLAG_OPERATORS(InstalledStatusType);\r\n\r\n    // Struct representing an individual installed status.\r\n    struct InstalledStatus\r\n    {\r\n        // The installed status type.\r\n        InstalledStatusType Type = InstalledStatusType::None;\r\n        // The installed status path.\r\n        Utility::NormalizedString Path;\r\n        // The installed status result.\r\n        HRESULT Status;\r\n\r\n        InstalledStatus(InstalledStatusType type, Utility::NormalizedString path, HRESULT status) :\r\n            Type(type), Path(std::move(path)), Status(status) {}\r\n    };\r\n\r\n    // Struct representing installed status from an installer.\r\n    struct InstallerInstalledStatus\r\n    {\r\n        Manifest::ManifestInstaller Installer;\r\n        std::vector<InstalledStatus> Status;\r\n    };\r\n\r\n    // Checks installed status of a package.\r\n    std::vector<InstallerInstalledStatus> CheckPackageInstalledStatus(const std::shared_ptr<ICompositePackage>& package, InstalledStatusType checkTypes = InstalledStatusType::AllChecks);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Public/winget/InstallerMetadataCollectionContext.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n\r\n#include <AppInstallerVersions.h>\r\n#include <winget/Manifest.h>\r\n#include <winget/JsonUtil.h>\r\n#include <winget/ThreadGlobals.h>\r\n#include <winget/ARPCorrelation.h>\r\n#include <winget/InstalledFilesCorrelation.h>\r\n#include <winget/IconExtraction.h>\r\n\r\n#include <filesystem>\r\n#include <map>\r\n#include <memory>\r\n#include <optional>\r\n#include <ostream>\r\n#include <string>\r\n#include <string_view>\r\n\r\nnamespace AppInstaller::Repository::Metadata\r\n{\r\n    // The overall metadata that we collect.\r\n    struct ProductMetadata\r\n    {\r\n        ProductMetadata() = default;\r\n\r\n        // Removes all stored data.\r\n        void Clear();\r\n\r\n        // Load the metadata from an existing JSON blob.\r\n        void FromJson(const web::json::value& json);\r\n\r\n        // Create a JSON value for the metadata using the given schema version.\r\n        web::json::value ToJson(const Utility::Version& schemaVersion, size_t maximumSizeInBytes);\r\n\r\n        // Copies the metadata from the source. If the given submission identifier does not match\r\n        // the source, it's data is moved to historical.\r\n        void CopyFrom(const ProductMetadata& source, std::string_view submissionIdentifier);\r\n\r\n        // The installer specific metadata that we collect.\r\n        struct InstallerMetadata\r\n        {\r\n            friend ProductMetadata;\r\n\r\n            // 1.0\r\n            std::string SubmissionIdentifier;\r\n            std::vector<Manifest::AppsAndFeaturesEntry> AppsAndFeaturesEntries;\r\n\r\n            // 1.1\r\n            // If Scope value is empty, the value is not set before. If the value is Unknown, a conflicting value is encountered.\r\n            std::string Scope;\r\n\r\n            // 1.2\r\n            // If std::nullopt, the value is not set before. If the value is empty(i.e. !HasData()), a conflicting value is encountered.\r\n            std::optional<Manifest::InstallationMetadataInfo> InstalledFiles;\r\n            // If std::nullopt, the value is not set before. If the vector is empty, conflicting values are encountered.\r\n            std::optional<std::vector<Correlation::InstalledStartupLinkFile>> StartupLinkFiles;\r\n            // Extracted icons\r\n            std::vector<ExtractedIconInfo> Icons;\r\n        };\r\n\r\n        // Metadata from previous product revisions.\r\n        struct HistoricalMetadata\r\n        {\r\n            // 1.0\r\n            Utility::Version ProductVersionMin;\r\n            Utility::Version ProductVersionMax;\r\n            std::set<std::string> Names;\r\n            std::set<std::string> Publishers;\r\n            std::set<std::string> ProductCodes;\r\n            std::set<std::string> UpgradeCodes;\r\n        };\r\n\r\n        // 1.0\r\n        Utility::Version SchemaVersion;\r\n        Utility::Version ProductVersionMin;\r\n        Utility::Version ProductVersionMax;\r\n        // Map from installer hash to metadata\r\n        std::map<std::string, InstallerMetadata> InstallerMetadataMap;\r\n        std::vector<HistoricalMetadata> HistoricalMetadataList;\r\n\r\n    private:\r\n        void FromJson_1_N(const web::json::value& json);\r\n        web::json::value ToJson_1_N();\r\n\r\n        // Removes the historical data with the oldest version.\r\n        // Returns true if something was removed; false it not.\r\n        bool DropOldestHistoricalData();\r\n    };\r\n\r\n    // Contains the functions and data used for collecting metadata from installers.\r\n    struct InstallerMetadataCollectionContext\r\n    {\r\n        InstallerMetadataCollectionContext();\r\n        InstallerMetadataCollectionContext(\r\n            std::unique_ptr<Correlation::ARPCorrelationData> correlationData,\r\n            std::unique_ptr<Correlation::InstalledFilesCorrelation> installedFilesCorrelation,\r\n            const std::wstring& json);\r\n\r\n        InstallerMetadataCollectionContext(const InstallerMetadataCollectionContext&) = delete;\r\n        InstallerMetadataCollectionContext& operator=(const InstallerMetadataCollectionContext&) = delete;\r\n\r\n        InstallerMetadataCollectionContext(InstallerMetadataCollectionContext&&) = default;\r\n        InstallerMetadataCollectionContext& operator=(InstallerMetadataCollectionContext&&) = default;\r\n\r\n        // Create from various forms of JSON input to prevent type collisions on constructor.\r\n        static std::unique_ptr<InstallerMetadataCollectionContext> FromFile(const std::filesystem::path& file, const std::filesystem::path& logFile);\r\n        static std::unique_ptr<InstallerMetadataCollectionContext> FromURI(std::wstring_view uri, const std::filesystem::path& logFile);\r\n        static std::unique_ptr<InstallerMetadataCollectionContext> FromJSON(const std::wstring& json, const std::filesystem::path& logFile);\r\n\r\n        // Completes the collection, writing to the given location.\r\n        void Complete(const std::filesystem::path& output);\r\n\r\n        // Completes the collection, writing to the given location.\r\n        void Complete(std::ostream& output);\r\n\r\n        static std::wstring Merge(const std::wstring& json, size_t maximumSizeInBytes, const std::filesystem::path& logFile);\r\n\r\n    private:\r\n        // Initializes the context runtime, including the log file if provided.\r\n        static std::unique_ptr<ThreadLocalStorage::PreviousThreadGlobals> InitializeLogging(ThreadLocalStorage::WingetThreadGlobals& threadGlobals, const std::filesystem::path& logFile);\r\n        std::unique_ptr<ThreadLocalStorage::PreviousThreadGlobals> InitializeLogging(const std::filesystem::path& logFile);\r\n\r\n        // Sets the collection context input and the preinstall state.\r\n        void InitializePreinstallState(const std::wstring& json);\r\n\r\n        // Creates the output ProductMetadata and diagnostics objects for output\r\n        void ComputeOutputData();\r\n\r\n        // Callers should set the thread globals before calling this.\r\n        void CompleteWithThreadGlobalsSet(std::ostream& output);\r\n\r\n        // Parse version 1.0 of input JSON\r\n        void ParseInputJson_1_0(web::json::value& input);\r\n\r\n        // Create version 1.0 of output JSON\r\n        web::json::value CreateOutputJson_1_0();\r\n\r\n        // Determines whether an error has occurred in the context.\r\n        bool ContainsError() const;\r\n\r\n        // Collects information from the exception for error reporting.\r\n        void CollectErrorDataFromException(std::exception_ptr exception);\r\n\r\n        // Create version 1.0 of error JSON\r\n        web::json::value CreateErrorJson_1_0();\r\n\r\n        // Merge using merge input version 1.0\r\n        static web::json::value Merge_1_0(web::json::value& input, size_t maximumSizeInBytes);\r\n\r\n        ThreadLocalStorage::WingetThreadGlobals m_threadGlobals;\r\n\r\n        // Parsed input\r\n        Utility::Version m_inputVersion;\r\n        Utility::Version m_supportedMetadataVersion;\r\n        ProductMetadata m_currentMetadata;\r\n        web::json::value m_submissionData;\r\n        std::string m_submissionIdentifier;\r\n        std::string m_installerHash;\r\n        Manifest::Manifest m_incomingManifest;\r\n\r\n        std::unique_ptr<Correlation::ARPCorrelationData> m_correlationData;\r\n        std::unique_ptr<Correlation::InstalledFilesCorrelation> m_installedFilesCorrelation;\r\n\r\n        // Output data\r\n        enum class OutputStatus\r\n        {\r\n            // Version 1.0 status values\r\n            Unknown,\r\n            Success,\r\n            Error,\r\n            LowConfidence,\r\n        };\r\n\r\n        // Convert status to a JSON string value\r\n        static utility::string_t ToString(OutputStatus status);\r\n\r\n        OutputStatus m_outputStatus = OutputStatus::Unknown;\r\n        ProductMetadata m_outputMetadata;\r\n        web::json::value m_outputDiagnostics;\r\n\r\n        // Error data storage\r\n        HRESULT m_errorHR = S_OK;\r\n        std::string m_errorText;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Public/winget/ManifestJSONParser.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerVersions.h>\r\n#include <winget/JsonUtil.h>\r\n#include <winget/Manifest.h>\r\n\r\n#include <memory>\r\n#include <vector>\r\n\r\nnamespace AppInstaller::Repository::JSON\r\n{\r\n    // Exposes functions for parsing JSON REST responses to manifest requests.\r\n    struct ManifestJSONParser\r\n    {\r\n        ManifestJSONParser(const Utility::Version& responseSchemaVersion);\r\n\r\n        ManifestJSONParser(const ManifestJSONParser&) = delete;\r\n        ManifestJSONParser& operator=(const ManifestJSONParser&) = delete;\r\n\r\n        ManifestJSONParser(ManifestJSONParser&&) noexcept;\r\n        ManifestJSONParser& operator=(ManifestJSONParser&&) noexcept;\r\n\r\n        ~ManifestJSONParser();\r\n\r\n        // Deserializes the manifests from the REST response object root.\r\n        // May potentially contain multiple versions of the same package.\r\n        std::vector<Manifest::Manifest> Deserialize(const web::json::value& response) const;\r\n\r\n        // Deserializes the manifests from the Data field of the REST response object.\r\n        // May potentially contain multiple versions of the same package.\r\n        std::vector<Manifest::Manifest> DeserializeData(const web::json::value& data) const;\r\n\r\n        // Deserializes the AppsAndFeaturesEntries node, returning the set of values below it.\r\n        std::vector<Manifest::AppsAndFeaturesEntry> DeserializeAppsAndFeaturesEntries(const web::json::array& data) const;\r\n\r\n        // Deserializes the locale node; returning an object if a proper locale was found.\r\n        std::optional<Manifest::ManifestLocalization> DeserializeLocale(const web::json::value& locale) const;\r\n\r\n        // Deserializes the InstallationMetadata node; returning an object if a proper InstallationMetadata was found.\r\n        std::optional<Manifest::InstallationMetadataInfo> DeserializeInstallationMetadata(const web::json::value& installationMetadata) const;\r\n\r\n    private:\r\n        struct impl;\r\n        std::unique_ptr<impl> m_pImpl;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Public/winget/PackageTrackingCatalog.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerStrings.h>\r\n#include <winget/Manifest.h>\r\n\r\n#include <memory>\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n#include <filesystem>\r\n#endif\r\n\r\nnamespace AppInstaller::Repository\r\n{\r\n    struct Source;\r\n    struct SearchRequest;\r\n    struct SearchResult;\r\n    enum class PackageVersionMetadata;\r\n\r\n    // A catalog for tracking package actions from a given source.\r\n    struct PackageTrackingCatalog\r\n    {\r\n        friend Source;\r\n\r\n        PackageTrackingCatalog();\r\n        PackageTrackingCatalog(const PackageTrackingCatalog&);\r\n        PackageTrackingCatalog& operator=(const PackageTrackingCatalog&);\r\n        PackageTrackingCatalog(PackageTrackingCatalog&&) noexcept;\r\n        PackageTrackingCatalog& operator=(PackageTrackingCatalog&&) noexcept;\r\n        ~PackageTrackingCatalog();\r\n\r\n        // Removes the package tracking catalog for a given source identifier.\r\n        static void RemoveForSource(const std::string& identifier);\r\n\r\n        // Determines if the current object holds anything.\r\n        operator bool() const;\r\n\r\n        // Execute a search against the catalog.\r\n        // Note that the packages in the results have the versions under \"available\" in order to\r\n        // expose all versions contained therein (in the event that this is deemed useful at some point).\r\n        SearchResult Search(const SearchRequest& request) const;\r\n\r\n        // Enables more granular control over the metadata in the tracking catalog if necessary.\r\n        struct Version\r\n        {\r\n            friend PackageTrackingCatalog;\r\n\r\n            Version(const Version&);\r\n            Version& operator=(const Version&);\r\n            Version(Version&&) noexcept;\r\n            Version& operator=(Version&&) noexcept;\r\n            ~Version();\r\n\r\n            // Set the given metadata value.\r\n            void SetMetadata(PackageVersionMetadata metadata, const Utility::NormalizedString& value);\r\n\r\n        private:\r\n            struct implementation;\r\n            Version(PackageTrackingCatalog& catalog, std::shared_ptr<implementation>&& value);\r\n            std::shared_ptr<implementation> m_implementation;\r\n            PackageTrackingCatalog* m_catalog;\r\n        };\r\n\r\n        // Records an installation of the given package.\r\n        Version RecordInstall(Manifest::Manifest& manifest, const Manifest::ManifestInstaller& installer, bool isUpgrade);\r\n\r\n        // Records an uninstall of the given package.\r\n        void RecordUninstall(const Utility::LocIndString& packageIdentifier);\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        // Gets the path to the database file.\r\n        std::filesystem::path GetFilePath() const;\r\n#endif\r\n\r\n    protected:\r\n        // Creates or opens the tracking catalog for the given source.\r\n        static PackageTrackingCatalog CreateForSource(const Source& source);\r\n\r\n    private:\r\n        struct implementation;\r\n        std::shared_ptr<implementation> m_implementation;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Public/winget/PackageVersionSelection.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/RepositorySearch.h>\r\n#include <winget/ManifestComparator.h>\r\n\r\n\r\nnamespace AppInstaller::Repository\r\n{\r\n    // Gets an IPackageVersionCollection that represents the available package versions for the installed version.\r\n    // If we have tracking data, will remove packages not from the tracked source. Will also remove versions that do not correspond to the tracked channel.\r\n    // This function uses the latest installed version as a temporary convenience until side-by-side is implemented.\r\n    std::shared_ptr<IPackageVersionCollection> GetAvailableVersionsForInstalledVersion(const std::shared_ptr<ICompositePackage>& composite);\r\n\r\n    // Gets an IPackageVersionCollection that represents the available package versions for the given installed version.\r\n    std::shared_ptr<IPackageVersionCollection> GetAvailableVersionsForInstalledVersion(\r\n        const std::shared_ptr<ICompositePackage>& composite,\r\n        const std::shared_ptr<IPackageVersion>& installedVersion);\r\n\r\n    // Equivalent to `GetAvailableVersionsForInstalledVersion(composite, nullptr)` to make the intent more clear that the caller wants to ignore any installed\r\n    // package information.\r\n    std::shared_ptr<IPackageVersionCollection> GetAllAvailableVersions(const std::shared_ptr<ICompositePackage>& composite);\r\n\r\n    // Gets the installed version, or a null if there isn't one.\r\n    std::shared_ptr<IPackageVersion> GetInstalledVersion(const std::shared_ptr<ICompositePackage>& composite);\r\n\r\n    // Gets the available IPackage corresponding to the given source identifier.\r\n    std::shared_ptr<IPackage> GetAvailablePackageFromSource(const std::shared_ptr<ICompositePackage>& composite, const std::string_view sourceIdentifier);\r\n\r\n    struct LatestApplicableVersionData\r\n    {\r\n        std::shared_ptr<AppInstaller::Repository::IPackageVersion> LatestApplicableVersion;\r\n        bool UpdateAvailable = false;\r\n    };\r\n\r\n    // Determines the default install version and whether an update is available.\r\n    LatestApplicableVersionData GetLatestApplicableVersion(const std::shared_ptr<ICompositePackage>& composite);\r\n\r\n    // Fills the options from the given metadata, optionally including the allowed architectures.\r\n    void GetManifestComparatorOptionsFromMetadata(AppInstaller::Manifest::ManifestComparator::Options& options, const IPackageVersion::Metadata& metadata, bool includeAllowedArchitectures = true);\r\n\r\n    // Gets the source priority for a given composite package, taking into account installed relationships.\r\n    std::optional<int32_t> GetSourcePriority(const std::shared_ptr<ICompositePackage>& composite);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Public/winget/PinningData.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/Pin.h>\r\n#include <winget/RepositorySearch.h>\r\n#include <map>\r\n#include <memory>\r\n#include <optional>\r\n#include <vector>\r\n\r\nnamespace AppInstaller::Repository::Microsoft\r\n{\r\n    struct PinningIndex;\r\n}\r\n\r\nnamespace AppInstaller::Pinning\r\n{\r\n    // Possible ways to consider pins when getting a package's available versions\r\n    enum class PinBehavior\r\n    {\r\n        // Ignore pins, returns all available versions.\r\n        IgnorePins,\r\n        // Include available versions for packages with a Pinning pin.\r\n        // Blocking pins and Gating pins still respected.\r\n        IncludePinned,\r\n        // Respect all the types of pins.\r\n        ConsiderPins,\r\n    };\r\n\r\n    // The public representation of the pinning database.\r\n    struct PinningData\r\n    {\r\n        // Creates an empty pinning data.\r\n        PinningData();\r\n\r\n        // Enum to make the pinning data disposition clear in the caller.\r\n        enum class Disposition\r\n        {\r\n            // The data can only be read.\r\n            ReadOnly,\r\n            // The data can be read and written.\r\n            ReadWrite,\r\n        };\r\n\r\n        // Creates a usable pinning data with the given read/write capability.\r\n        PinningData(Disposition disposition);\r\n\r\n        PinningData(const PinningData&);\r\n        PinningData& operator=(const PinningData&);\r\n        PinningData(PinningData&&) noexcept;\r\n        PinningData& operator=(PinningData&&) noexcept;\r\n        ~PinningData();\r\n\r\n        // Determines if the pinning database is opened\r\n        operator bool() const;\r\n        bool IsDatabaseConnected() const;\r\n\r\n        // Pass through functions to the index itself\r\n        void AddOrUpdatePin(const Pin& pin);\r\n        void RemovePin(const PinKey& pinKey);\r\n        std::optional<Pin> GetPin(const PinKey& pinKey);\r\n        std::vector<Pin> GetAllPins();\r\n        bool ResetAllPins(std::string_view sourceId = {});\r\n\r\n        // A type used for evaluating the pinning state for a given package.\r\n        struct PinStateEvaluator\r\n        {\r\n            PinStateEvaluator(\r\n                PinBehavior behavior,\r\n                std::shared_ptr<AppInstaller::Repository::Microsoft::PinningIndex> database,\r\n                const std::shared_ptr<AppInstaller::Repository::IPackageVersion>& installedVersion);\r\n\r\n            PinStateEvaluator(const PinStateEvaluator&);\r\n            PinStateEvaluator& operator=(const PinStateEvaluator&);\r\n            PinStateEvaluator(PinStateEvaluator&&) noexcept;\r\n            PinStateEvaluator& operator=(PinStateEvaluator&&) noexcept;\r\n\r\n            ~PinStateEvaluator();\r\n\r\n            // Gets the latest available package version that fits within the pinning restrictions.\r\n            // This should be the package object that contains available versions associated with the installed version for which this evaluator was created.\r\n            std::shared_ptr<AppInstaller::Repository::IPackageVersion> GetLatestAvailableVersionForPins(const std::shared_ptr<AppInstaller::Repository::IPackageVersionCollection>& package);\r\n\r\n            // Determines if the given version is an update to the installed version that this object was created with.\r\n            // This should be a version associated with the installed version for which this evaluator was created.\r\n            bool IsUpdate(const std::shared_ptr<AppInstaller::Repository::IPackageVersion>& availableVersion);\r\n\r\n            // Determines the pin type to apply to the given version.\r\n            PinType EvaluatePinType(const std::shared_ptr<AppInstaller::Repository::IPackageVersion>& packageVersion);\r\n\r\n        private:\r\n            PinBehavior m_behavior;\r\n            std::shared_ptr<AppInstaller::Repository::Microsoft::PinningIndex> m_database;\r\n            std::optional<Pin> m_installedPin;\r\n            std::optional<Utility::VersionAndChannel> m_installedVersion;\r\n            // Cache pins for available version to reduce database lookups.\r\n            std::map<PinKey, std::optional<Pin>> m_availablePins;\r\n        };\r\n\r\n        // Creates an object for use in evaluating pinning data for a given package\r\n        PinStateEvaluator CreatePinStateEvaluator(\r\n            PinBehavior behavior,\r\n            const std::shared_ptr<AppInstaller::Repository::IPackageVersion>& installedVersion);\r\n\r\n    private:\r\n        std::shared_ptr<AppInstaller::Repository::Microsoft::PinningIndex> m_database;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Public/winget/PortableIndex.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteWrapper.h>\r\n#include <winget/SQLiteStorageBase.h>\r\n#include <winget/PortableFileEntry.h>\r\n#include <winget/ManagedFile.h>\r\n\r\nusing namespace AppInstaller::Portable;\r\n\r\nnamespace AppInstaller::Repository::Microsoft\r\n{\r\n    namespace Schema\r\n    {\r\n        struct IPortableIndex;\r\n    }\r\n\r\n    struct PortableIndex : SQLite::SQLiteStorageBase\r\n    {\r\n        // An id that refers to a specific portable file.\r\n        using IdType = SQLite::rowid_t;\r\n\r\n        PortableIndex(const PortableIndex&) = delete;\r\n        PortableIndex& operator=(const PortableIndex&) = delete;\r\n\r\n        PortableIndex(PortableIndex&&);\r\n        PortableIndex& operator=(PortableIndex&&);\r\n\r\n        ~PortableIndex();\r\n\r\n        // Creates a new PortableIndex database of the given version.\r\n        static PortableIndex CreateNew(const std::string& filePath, SQLite::Version version = SQLite::Version::Latest());\r\n\r\n        // Opens an existing PortableIndex database.\r\n        static PortableIndex Open(const std::string& filePath, OpenDisposition disposition, Utility::ManagedFile&& indexFile = {});\r\n\r\n        IdType AddPortableFile(const Portable::PortableFileEntry& file);\r\n\r\n        void RemovePortableFile(const Portable::PortableFileEntry& file);\r\n\r\n        bool UpdatePortableFile(const Portable::PortableFileEntry& file);\r\n\r\n        void AddOrUpdatePortableFile(const Portable::PortableFileEntry& file);\r\n\r\n        std::vector<Portable::PortableFileEntry> GetAllPortableFiles();\r\n\r\n        bool Exists(const Portable::PortableFileEntry& file);\r\n\r\n        bool IsEmpty();\r\n\r\n    private:\r\n        // Constructor used to open an existing index.\r\n        PortableIndex(const std::string& target, SQLiteStorageBase::OpenDisposition disposition, Utility::ManagedFile&& indexFile);\r\n\r\n        // Constructor used to create a new index.\r\n        PortableIndex(const std::string& target, SQLite::Version version);\r\n\r\n        // Creates the IPortableIndex interface object for this version.\r\n        std::unique_ptr<Schema::IPortableIndex> CreateIPortableIndex() const;\r\n\r\n        std::unique_ptr<Schema::IPortableIndex> m_interface;\r\n    };\r\n}"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Public/winget/RepositorySearch.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerErrors.h>\r\n#include <AppInstallerStrings.h>\r\n#include <AppInstallerVersions.h>\r\n#include <winget/LocIndependent.h>\r\n#include <winget/Manifest.h>\r\n\r\n#include <map>\r\n#include <memory>\r\n#include <optional>\r\n#include <string>\r\n#include <string_view>\r\n#include <vector>\r\n\r\n\r\nnamespace AppInstaller::Repository\r\n{\r\n    struct Source;\r\n\r\n    // The type of matching to perform during a search.\r\n    // The values must be declared in order of preference in search results.\r\n    enum class MatchType\r\n    {\r\n        Exact = 0,\r\n        CaseInsensitive,\r\n        StartsWith,\r\n        Fuzzy,\r\n        Substring,\r\n        FuzzySubstring,\r\n        Wildcard,\r\n    };\r\n\r\n    // Convert a MatchType to a string.\r\n    std::string_view ToString(MatchType type);\r\n\r\n    // The field to match on.\r\n    // The values must be declared in order of preference in search results.\r\n    enum class PackageMatchField\r\n    {\r\n        Id = 0,\r\n        Name,\r\n        Moniker,\r\n        Command,\r\n        Tag,\r\n        PackageFamilyName,\r\n        ProductCode,\r\n        UpgradeCode,\r\n        NormalizedNameAndPublisher,\r\n        Market,\r\n        Unknown = 9999\r\n    };\r\n\r\n    // Convert a PackageMatchField to a string.\r\n    std::string_view ToString(PackageMatchField matchField);\r\n\r\n    // Parse a string to PackageMatchField.\r\n    PackageMatchField StringToPackageMatchField(std::string_view field);\r\n\r\n    // A single match to be performed during a search.\r\n    struct RequestMatch\r\n    {\r\n        MatchType Type;\r\n        Utility::NormalizedString Value;\r\n        std::optional<Utility::NormalizedString> Additional;\r\n\r\n        RequestMatch(MatchType t) : Type(t) {}\r\n        RequestMatch(MatchType t, Utility::NormalizedString& v) : Type(t), Value(v) {}\r\n        RequestMatch(MatchType t, const Utility::NormalizedString& v) : Type(t), Value(v) {}\r\n        RequestMatch(MatchType t, Utility::NormalizedString&& v) : Type(t), Value(std::move(v)) {}\r\n        RequestMatch(MatchType t, std::string_view v1, std::string_view v2) : Type(t), Value(v1), Additional(Utility::NormalizedString{ v2 }) {}\r\n    };\r\n\r\n    // A match on a specific field to be performed during a search.\r\n    struct PackageMatchFilter : public RequestMatch\r\n    {\r\n        PackageMatchField Field;\r\n\r\n        PackageMatchFilter(PackageMatchField f, MatchType t) : RequestMatch(t), Field(f) { EnsureRequiredValues(); }\r\n        PackageMatchFilter(PackageMatchField f, MatchType t, Utility::NormalizedString& v) : RequestMatch(t, v), Field(f) { EnsureRequiredValues(); }\r\n        PackageMatchFilter(PackageMatchField f, MatchType t, const Utility::NormalizedString& v) : RequestMatch(t, v), Field(f) { EnsureRequiredValues(); }\r\n        PackageMatchFilter(PackageMatchField f, MatchType t, Utility::NormalizedString&& v) : RequestMatch(t, std::move(v)), Field(f) { EnsureRequiredValues(); }\r\n        PackageMatchFilter(PackageMatchField f, MatchType t, std::string_view v1, std::string_view v2) : RequestMatch(t, v1, v2), Field(f) { EnsureRequiredValues(); }\r\n\r\n    protected:\r\n        void EnsureRequiredValues()\r\n        {\r\n            // Ensure that the second value always exists when it should\r\n            if (Field == PackageMatchField::NormalizedNameAndPublisher && !Additional)\r\n            {\r\n                Additional = Utility::NormalizedString{};\r\n            }\r\n        }\r\n    };\r\n\r\n    // The search purpose of the search request.\r\n    enum class SearchPurpose\r\n    {\r\n        // Default search purpose.\r\n        Default,\r\n        // The result is used for correlation to an installed package.\r\n        CorrelationToInstalled,\r\n        // The result is used for correlation to an available package.\r\n        CorrelationToAvailable,\r\n    };\r\n\r\n    // Container for data used to filter the available manifests in a source.\r\n    // It can be thought of as:\r\n    //  (Query || Inclusions...) && Filters...\r\n    // If Query and Inclusions are both empty, the starting data set will be the entire database.\r\n    //  Everything && Filters...\r\n    struct SearchRequest\r\n    {\r\n        // The generic query matches against a source defined set of fields.\r\n        std::optional<RequestMatch> Query;\r\n\r\n        // Specific fields used to include more data.\r\n        // If Query is defined, this can add more rows afterward.\r\n        // If Query is not defined, this is the only set of data included.\r\n        std::vector<PackageMatchFilter> Inclusions;\r\n\r\n        // Specific fields used to filter the data further.\r\n        std::vector<PackageMatchFilter> Filters;\r\n\r\n        // The search purpose of the search request.\r\n        SearchPurpose Purpose = SearchPurpose::Default;\r\n\r\n        // The maximum number of results to return.\r\n        // The default of 0 will place no limit.\r\n        size_t MaximumResults{};\r\n\r\n        // Returns a value indicating whether this request is for all available data.\r\n        bool IsForEverything() const;\r\n\r\n        // Returns a string summarizing the search request.\r\n        std::string ToString() const;\r\n    };\r\n\r\n    // A property of a package version.\r\n    enum class PackageVersionProperty\r\n    {\r\n        Id,\r\n        Name,\r\n        SourceIdentifier,\r\n        SourceName,\r\n        Version,\r\n        Channel,\r\n        RelativePath,\r\n        // Returned in hexadecimal format\r\n        ManifestSHA256Hash,\r\n        Publisher,\r\n        ArpMinVersion,\r\n        ArpMaxVersion,\r\n        Moniker,\r\n    };\r\n\r\n    // A property of a package version that can have multiple values.\r\n    enum class PackageVersionMultiProperty\r\n    {\r\n        // The package family names (PFN) associated with the package version\r\n        PackageFamilyName,\r\n        // The product codes associated with the package version.\r\n        ProductCode,\r\n        // The upgrade codes associated with the package version.\r\n        UpgradeCode,\r\n        // TODO: Fully implement these 3; the data is not yet in the index source (name and publisher are hacks and locale is not present)\r\n        //       For future usage of these, be aware of the limitations.\r\n        // The package names for the version; ideally these would match in number and order with both Publisher and Locale.\r\n        Name,\r\n        // The publisher values for the version; ideally these would match in number and order with both Name and Locale.\r\n        Publisher,\r\n        // The locale of the matching Name and Publisher values; ideally these would match in number and order with both Name and Publisher.\r\n        // May be empty if there is only a single value for Name and Publisher.\r\n        Locale,\r\n        // The tags associated with a package version.\r\n        Tag,\r\n        // The commands associated with a package version.\r\n        Command,\r\n    };\r\n\r\n    // A metadata item of a package version. These values are persisted and cannot be changed.\r\n    enum class PackageVersionMetadata : int32_t\r\n    {\r\n        // The InstallerType of an installed package\r\n        InstalledType,\r\n        // The Scope of an installed package\r\n        InstalledScope,\r\n        // The system path where the package is installed\r\n        InstalledLocation,\r\n        // The standard uninstall command; which may be interactive\r\n        StandardUninstallCommand,\r\n        // An uninstall command that should be non-interactive\r\n        SilentUninstallCommand,\r\n        // The publisher of the package\r\n        Publisher,\r\n        // The locale of the package\r\n        InstalledLocale,\r\n        // The write time for the given version\r\n        TrackingWriteTime,\r\n        // The Architecture of an installed package\r\n        InstalledArchitecture,\r\n        // The pinned state of the installed package\r\n        // As a package can have multiple pins for multiple sources, this is the strictest pin\r\n        PinnedState,\r\n        // The Architecture of user intent\r\n        UserIntentArchitecture,\r\n        // The locale of user intent\r\n        UserIntentLocale,\r\n        // The standard modify command; which may be interactive\r\n        StandardModifyCommand,\r\n        // No Modify flag\r\n        NoModify,\r\n        // No Repair flag\r\n        NoRepair,\r\n    };\r\n\r\n    // Convert a PackageVersionMetadata to a string.\r\n    std::string_view ToString(PackageVersionMetadata pvm);\r\n\r\n    // A single package version.\r\n    struct IPackageVersion\r\n    {\r\n        using Metadata = std::map<PackageVersionMetadata, std::string>;\r\n\r\n        virtual ~IPackageVersion() = default;\r\n\r\n        // Gets a property of this package version.\r\n        virtual Utility::LocIndString GetProperty(PackageVersionProperty property) const = 0;\r\n\r\n        // Gets a property of this package version that can have multiple values.\r\n        virtual std::vector<Utility::LocIndString> GetMultiProperty(PackageVersionMultiProperty property) const = 0;\r\n\r\n        // Gets the manifest of this package version.\r\n        virtual Manifest::Manifest GetManifest() = 0;\r\n\r\n        // Gets the source where this package version is from.\r\n        virtual Source GetSource() const = 0;\r\n\r\n        // Gets any metadata associated with this package version.\r\n        // Primarily stores data on installed packages.\r\n        virtual Metadata GetMetadata() const = 0;\r\n    };\r\n\r\n    // A key to identify a package version within a package.\r\n    struct PackageVersionKey\r\n    {\r\n        PackageVersionKey() = default;\r\n\r\n        PackageVersionKey(std::string sourceId, Utility::NormalizedString version, Utility::NormalizedString channel) :\r\n            SourceId(std::move(sourceId)), Version(std::move(version)), Channel(std::move(channel)) {}\r\n\r\n        // The source id that this version came from.\r\n        std::string SourceId;\r\n\r\n        // The version.\r\n        Utility::NormalizedString Version;\r\n\r\n        // The channel.\r\n        Utility::NormalizedString Channel;\r\n\r\n        bool operator<(const PackageVersionKey& other) const\r\n        {\r\n            // Sort using only the version and channel.\r\n            // The order for the sources depends on the context.\r\n            return Utility::VersionAndChannel({ Version }, { Channel }) < Utility::VersionAndChannel({ other.Version }, { other.Channel });\r\n        }\r\n\r\n        // Determines if a well defined key (this one) is matched by the provided key.\r\n        // The provided key may use empty values to indicate no specific matching requirements.\r\n        bool IsMatch(const PackageVersionKey& other) const;\r\n\r\n        // Determines if this version is the simple \"latest\" targeting version (version and channel are both empty).\r\n        bool IsDefaultLatest() const;\r\n    };\r\n\r\n    // A property of a package.\r\n    enum class PackageProperty\r\n    {\r\n        Id,\r\n        Name,\r\n    };\r\n\r\n    // A property of a package that can have multiple values.\r\n    enum class PackageMultiProperty\r\n    {\r\n        // The package family names (PFN) associated with the package.\r\n        PackageFamilyName,\r\n        // The product codes associated with the package.\r\n        ProductCode,\r\n        // The upgrade codes associated with the package.\r\n        UpgradeCode,\r\n        // The normalized names for the package.\r\n        NormalizedName,\r\n        // The normalized publisher names for the package.\r\n        NormalizedPublisher,\r\n        // The tags associated with the package.\r\n        Tag,\r\n        // The commands associated with the package.\r\n        Command,\r\n    };\r\n\r\n    // Maps the package multi-property value to its package version multi-property value for internal use.\r\n    PackageVersionMultiProperty PackageMultiPropertyToPackageVersionMultiProperty(PackageMultiProperty property);\r\n\r\n    // To allow for runtime casting from IPackage to the specific types, this enum contains all of the IPackage implementations.\r\n    enum class IPackageType\r\n    {\r\n        TestPackage,\r\n        RestPackage,\r\n        SQLitePackage1,\r\n        SQLitePackage2,\r\n        PinnablePackage,\r\n        CompositeInstalledPackage,\r\n    };\r\n\r\n    // Contains a collection of package versions.\r\n    struct IPackageVersionCollection\r\n    {\r\n        virtual ~IPackageVersionCollection() = default;\r\n\r\n        // Gets all versions of this package.\r\n        // The versions will be returned in sorted, descending order.\r\n        //  Ex. { 4, 3, 2, 1 }\r\n        virtual std::vector<PackageVersionKey> GetVersionKeys() const = 0;\r\n\r\n        // Gets a specific version of this package.\r\n        virtual std::shared_ptr<IPackageVersion> GetVersion(const PackageVersionKey& versionKey) const = 0;\r\n\r\n        // A convenience method to effectively call `GetVersion(GetVersionKeys[0])`.\r\n        virtual std::shared_ptr<IPackageVersion> GetLatestVersion() const = 0;\r\n    };\r\n\r\n    // Contains information about a package and its versions from a single source.\r\n    struct IPackage : public IPackageVersionCollection\r\n    {\r\n        virtual ~IPackage() = default;\r\n\r\n        // Gets a property of this package.\r\n        virtual Utility::LocIndString GetProperty(PackageProperty property) const = 0;\r\n\r\n        // Gets a property of this package that can have multiple values.\r\n        virtual std::vector<Utility::LocIndString> GetMultiProperty(PackageMultiProperty property) const = 0;\r\n\r\n        // Gets the source that this package is from.\r\n        virtual Source GetSource() const = 0;\r\n\r\n        // Determines if the given IPackage refers to the same package as this one.\r\n        virtual bool IsSame(const IPackage*) const = 0;\r\n\r\n        // Gets this object as the requested type, or null if it is not the requested type.\r\n        virtual const void* CastTo(IPackageType type) const = 0;\r\n    };\r\n\r\n    // Contains information about the graph of packages related to a search.\r\n    struct ICompositePackage\r\n    {\r\n        virtual ~ICompositePackage() = default;\r\n\r\n        // Gets a property of this package result.\r\n        virtual Utility::LocIndString GetProperty(PackageProperty property) const = 0;\r\n\r\n        // Gets the installed package information.\r\n        virtual std::shared_ptr<IPackage> GetInstalled() = 0;\r\n\r\n        // Gets all of the available packages for this result.\r\n        // There will be at most one package per source in this list.\r\n        virtual std::vector<std::shared_ptr<IPackage>> GetAvailable() = 0;\r\n    };\r\n\r\n    // Does the equivalent of a dynamic_cast, but without it to allow RTTI to be disabled.\r\n    // Example usage:\r\n    //  bool IsSame(const IPackage* other) const override\r\n    //  {\r\n    //      const MyPackage* otherAsMyType = PackageCast<const MyPackage*>(other);\r\n    //      ...\r\n    //  }\r\n    template <typename PackageType>\r\n    PackageType PackageCast(const IPackage* package)\r\n    {\r\n        static_assert(std::is_pointer_v<PackageType>, \"The target type of the PackageCast must be a pointer; use the same type as if this were a dynamic_cast.\");\r\n        if (!package)\r\n        {\r\n            return nullptr;\r\n        }\r\n        using ActualPackageType = std::remove_pointer_t<std::remove_cv_t<PackageType>>;\r\n        return reinterpret_cast<PackageType>(package->CastTo(ActualPackageType::PackageType));\r\n    }\r\n\r\n    // A single result from the search.\r\n    struct ResultMatch\r\n    {\r\n        // The package found by the search request.\r\n        std::shared_ptr<ICompositePackage> Package;\r\n\r\n        // The highest order field on which the package matched the search.\r\n        PackageMatchFilter MatchCriteria;\r\n\r\n        ResultMatch(std::shared_ptr<ICompositePackage> p, PackageMatchFilter f) : Package(std::move(p)), MatchCriteria(std::move(f)) {}\r\n    };\r\n\r\n    // Search result data.\r\n    struct SearchResult\r\n    {\r\n        // Contains a failure from the Search.\r\n        struct Failure\r\n        {\r\n            std::string SourceName;\r\n            std::exception_ptr Exception;\r\n        };\r\n\r\n        // The full set of results from the search.\r\n        std::vector<ResultMatch> Matches;\r\n\r\n        // If true, the results were truncated by the given SearchRequest::MaximumResults.\r\n        bool Truncated = false;\r\n\r\n        // Present if the Search was against a composite source and one failed, but not limited to that scenario.\r\n        std::vector<Failure> Failures;\r\n    };\r\n\r\n    struct UnsupportedRequestException : public wil::ResultException\r\n    {\r\n        UnsupportedRequestException() : wil::ResultException(APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST) {}\r\n\r\n        UnsupportedRequestException(\r\n            std::vector<std::string> unsupportedPackageMatchFields,\r\n            std::vector<std::string> requiredPackageMatchFields,\r\n            std::vector<std::string> unsupportedQueryParameters,\r\n            std::vector<std::string> requiredQueryParameters) :\r\n            wil::ResultException(APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST),\r\n            UnsupportedPackageMatchFields(std::move(unsupportedPackageMatchFields)), RequiredPackageMatchFields(std::move(requiredPackageMatchFields)),\r\n            UnsupportedQueryParameters(std::move(unsupportedQueryParameters)), RequiredQueryParameters(std::move(requiredQueryParameters)) {}\r\n\r\n        std::vector<std::string> UnsupportedPackageMatchFields;\r\n        std::vector<std::string> RequiredPackageMatchFields;\r\n        std::vector<std::string> UnsupportedQueryParameters;\r\n        std::vector<std::string> RequiredQueryParameters;\r\n\r\n        const char* what() const noexcept override;\r\n\r\n    private:\r\n        mutable std::string m_whatMessage;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Public/winget/RepositorySource.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/RepositorySearch.h>\r\n#include <winget/PackageTrackingCatalog.h>\r\n#include <AppInstallerProgress.h>\r\n#include <winget/Certificates.h>\r\n#include <winget/Authentication.h>\r\n#include <winget/SharedThreadGlobals.h>\r\n\r\n#include <chrono>\r\n#include <filesystem>\r\n#include <memory>\r\n#include <optional>\r\n#include <string>\r\n#include <string_view>\r\n#include <vector>\r\n\r\n\r\nnamespace AppInstaller::Repository\r\n{\r\n    // The interval is of 100 nano seconds precision.This is used by file date period and the Windows::Foundation::TimeSpan exposed in COM api.\r\n    using TimeSpan = std::chrono::duration<int64_t, std::ratio_multiply<std::ratio<100>, std::nano>>;\r\n\r\n    struct ISourceReference;\r\n    struct ISource;\r\n\r\n    // Defines the origin of the source details.\r\n    enum class SourceOrigin\r\n    {\r\n        Default,\r\n        User,\r\n        Predefined,\r\n        GroupPolicy,\r\n        Metadata,\r\n        PackageTracking,\r\n    };\r\n\r\n    // Defines the trust level of the source.\r\n    enum class SourceTrustLevel : uint32_t\r\n    {\r\n        None        = 0x00000000,\r\n        Trusted     = 0x00000001,\r\n        StoreOrigin = 0x00000002,\r\n    };\r\n\r\n    DEFINE_ENUM_FLAG_OPERATORS(SourceTrustLevel);\r\n\r\n    // Converts a string_view to the corresponding SourceTrustLevel enum.\r\n    SourceTrustLevel ConvertToSourceTrustLevelEnum(std::string_view trustLevel);\r\n\r\n    // Converts a vector of trust level strings to the corresponding SourceTrustLevel enum flag.\r\n    SourceTrustLevel ConvertToSourceTrustLevelFlag(std::vector<std::string> values);\r\n\r\n    // Converts a SourceTrustLevel flag to a list of trust level strings.\r\n    std::vector<std::string_view> SourceTrustLevelFlagToList(SourceTrustLevel trustLevel);\r\n\r\n    // Converts a SourceTrustLevel enum to the corresponding string.\r\n    std::string_view SourceTrustLevelEnumToString(SourceTrustLevel trustLevel);\r\n\r\n    // Gets the full trust level string name for display.\r\n    std::string GetSourceTrustLevelForDisplay(SourceTrustLevel trustLevel);\r\n\r\n    std::string_view ToString(SourceOrigin origin);\r\n\r\n    // Fields that require user agreements.\r\n    enum class ImplicitAgreementFieldEnum : int\r\n    {\r\n        None = 0x0,\r\n        Market = 0x1,\r\n    };\r\n\r\n    DEFINE_ENUM_FLAG_OPERATORS(ImplicitAgreementFieldEnum);\r\n\r\n    // A predefined source.\r\n    // These sources are not under the direct control of the user, such as packages installed on the system.\r\n    enum class PredefinedSource\r\n    {\r\n        // Default behavior. Contains ARP packages installed as for user and for machine, MSIX packages for current user.\r\n        Installed,\r\n        // Only contains packages installed as for user\r\n        InstalledUser,\r\n        // Only contains packages installed as for machine\r\n        InstalledMachine,\r\n        ARP,\r\n        MSIX,\r\n        Installing,\r\n        // Same as `Installed`, but creating the source reference for this is sufficient to cause the cache to be updated\r\n        // on next Open of any `Installed` or `InstalledForceCacheUpdate`.\r\n        InstalledForceCacheUpdate,\r\n    };\r\n\r\n    // A well known source.\r\n    // These come with the app and can be disabled but not removed.\r\n    enum class WellKnownSource\r\n    {\r\n        WinGet,\r\n        MicrosoftStore,\r\n        DesktopFrameworks,\r\n        WinGetFont,\r\n    };\r\n\r\n    // Search behavior for composite sources.\r\n    // Only relevant for composite sources with an installed source, not for aggregates of multiple available sources.\r\n    // Installed and available packages in the result are always correlated when possible.\r\n    enum class CompositeSearchBehavior\r\n    {\r\n        // Search only installed packages.\r\n        Installed,\r\n        // Search both installed and available packages.\r\n        AllPackages,\r\n        // Search only available packages.\r\n        AvailablePackages,\r\n    };\r\n\r\n    // Interface for source configurations. Source configurations are used to get a source reference without opening the source.\r\n    struct SourceDetails\r\n    {\r\n        // The name of the source.\r\n        std::string Name;\r\n\r\n        // The type of the source.\r\n        std::string Type;\r\n\r\n        // The argument used when adding the source.\r\n        std::string Arg;\r\n\r\n        // The source's extra data string.\r\n        std::string Data;\r\n\r\n        // The source's unique identifier.\r\n        std::string Identifier;\r\n\r\n        // The origin of the source.\r\n        SourceOrigin Origin = SourceOrigin::Default;\r\n\r\n        // The trust level of the source\r\n        SourceTrustLevel TrustLevel = SourceTrustLevel::None;\r\n\r\n        // The last time that this source was updated.\r\n        std::chrono::system_clock::time_point LastUpdateTime = {};\r\n\r\n        // Stores the earliest time that a background update should be attempted.\r\n        std::chrono::system_clock::time_point DoNotUpdateBefore = {};\r\n\r\n        // Whether the source supports InstalledSource correlation.\r\n        bool SupportInstalledSearchCorrelation = true;\r\n\r\n        // The configuration of how the server certificate will be validated.\r\n        Certificates::PinningConfiguration CertificatePinningConfiguration;\r\n\r\n        // This value is used as an alternative to the `Arg` value if it is failing to function properly.\r\n        // The alternate location must point to identical data or inconsistencies may arise.\r\n        std::string AlternateArg;\r\n\r\n        // Whether the source should be hidden by default unless explicitly declared.\r\n        bool Explicit = false;\r\n\r\n        // Value used for sorting the sources and making decisions\r\n        // (like preferring one source over the other if both have a package to install).\r\n        // Higher values come first in priority order.\r\n        int32_t Priority = 0;\r\n    };\r\n\r\n    // Check if a source matches a well known source\r\n    std::optional<WellKnownSource> CheckForWellKnownSource(const SourceDetails& sourceDetails);\r\n\r\n    // Individual source agreement entry. Label will be highlighted in the display as the key of the agreement entry.\r\n    struct SourceAgreement\r\n    {\r\n        SourceAgreement() = default;\r\n\r\n        SourceAgreement(std::string label, std::string text, std::string url) :\r\n            Label(std::move(label)), Text(std::move(text)), Url(std::move(url)) {}\r\n\r\n        std::string Label;\r\n        std::string Text;\r\n        std::string Url;\r\n    };\r\n\r\n    // Interface for retrieving information about a source after opening the source.\r\n    struct SourceInformation\r\n    {\r\n        // Identifier of the source agreements. This is used to identify if source agreements have changed.\r\n        std::string SourceAgreementsIdentifier;\r\n\r\n        // List of source agreements that require user to accept.\r\n        std::vector<SourceAgreement> SourceAgreements;\r\n\r\n        // Unsupported match fields in search request. If this field is in the filters, the request may fail.\r\n        std::vector<std::string> UnsupportedPackageMatchFields;\r\n\r\n        // Required match fields in search request. If this field is not found in the filters, the request may fail(except Market).\r\n        std::vector<std::string> RequiredPackageMatchFields;\r\n\r\n        // Unsupported query parameters in get manifest request.\r\n        std::vector<std::string> UnsupportedQueryParameters;\r\n\r\n        // Required query parameters in get manifest request.\r\n        std::vector<std::string> RequiredQueryParameters;\r\n\r\n        // Source authentication info.\r\n        Authentication::AuthenticationInfo Authentication;\r\n    };\r\n\r\n    // Contains information about edits to a source.\r\n    struct SourceEdit\r\n    {\r\n        SourceEdit() = default;\r\n\r\n        // The Explicit property of a source.\r\n        std::optional<bool> Explicit;\r\n\r\n        // The Priority property of a source.\r\n        std::optional<int32_t> Priority;\r\n    };\r\n\r\n    // Allows calling code to inquire about specific features of an ISource implementation.\r\n    // The default state of any new flag is false.\r\n    enum class SourceFeatureFlag\r\n    {\r\n        // If true, the manifests for this source may contain more data than is available from just the\r\n        // version information found from a search.\r\n        ManifestMayContainAdditionalSystemReferenceStrings,\r\n    };\r\n\r\n    // Represents a source which would be interacted from outside of repository lib.\r\n    struct Source\r\n    {\r\n        // Default constructor with an empty source.\r\n        Source();\r\n\r\n        // Constructor to get a named source, passing empty string will get all available sources.\r\n        Source(std::string_view name);\r\n\r\n        // Constructor to get a PredefinedSource. Like installed source, etc.\r\n        Source(PredefinedSource source);\r\n\r\n        // Constructor to get a source coming with winget. Like winget community source, etc.\r\n        Source(WellKnownSource source);\r\n\r\n        // Constructor for a source to be added.\r\n        Source(std::string_view name, std::string_view arg, std::string_view type, SourceTrustLevel trustLevel, const SourceEdit& additionalProperties);\r\n\r\n        // Constructor for creating a composite source from a list of available sources.\r\n        Source(const std::vector<Source>& availableSources);\r\n\r\n        // Constructor for creating a composite source from an installed source and available source(may be composite already).\r\n        Source(\r\n            const Source& installedSource,\r\n            const Source& availableSource,\r\n            CompositeSearchBehavior searchBehavior = CompositeSearchBehavior::Installed);\r\n\r\n        // Constructor for creating a Source object from an existing ISource.\r\n        // Should only be used internally by ISource implementations to return the value from IPackageVersion::GetSource.\r\n        Source(std::shared_ptr<ISource> source);\r\n\r\n        // Bool operator to check if a source reference is successfully acquired.\r\n        // Theoretically, the constructor could just throw when CreateSource returns empty.\r\n        // To avoid putting try catch everywhere, we use bool operator here.\r\n        operator bool() const;\r\n\r\n        // Determines if the sources are equivalent.\r\n        // Currently only works for individual sources, not composites.\r\n        bool operator==(const Source& other) const;\r\n        bool operator!=(const Source& other) const;\r\n\r\n        // Gets the source's identifier; a unique identifier independent of the name\r\n        // that will not change between a remove/add or between additional adds.\r\n        // Must be suitable for filesystem names unless the source is internal to winget,\r\n        // in which case the identifier should begin with a '*' character.\r\n        std::string GetIdentifier() const;\r\n\r\n        // Get the source's configuration details from settings.\r\n        SourceDetails GetDetails() const;\r\n\r\n        // Get the source's information.\r\n        SourceInformation GetInformation() const;\r\n\r\n        // Query the value of the given feature flag.\r\n        // The default state of any new flag is false.\r\n        bool QueryFeatureFlag(SourceFeatureFlag flag) const;\r\n\r\n        // Returns true if the origin type can contain available packages.\r\n        bool ContainsAvailablePackages() const;\r\n\r\n        // Set custom header. Must be set before Open to have effect.\r\n        bool SetCustomHeader(std::optional<std::string> header);\r\n\r\n        // Set caller. Must be set before Open to have effect.\r\n        void SetCaller(std::string caller);\r\n\r\n        // Set authentication arguments. Must be set before Open to have effect.\r\n        void SetAuthenticationArguments(Authentication::AuthenticationArguments args);\r\n\r\n        // Set thread globals. Must be set before Open to have effect.\r\n        void SetThreadGlobals(const std::shared_ptr<ThreadLocalStorage::ThreadGlobals>& threadGlobals);\r\n\r\n        // Set background update check interval.\r\n        void SetBackgroundUpdateInterval(TimeSpan interval);\r\n\r\n        // Indicates that we are only interested in the PackageTrackingCatalog for the source.\r\n        // Must be set before Open to have effect, and will prevent the underlying source from being updated or opened.\r\n        void InstalledPackageInformationOnly(bool value);\r\n\r\n        // Determines if this source refers to the given well known source.\r\n        bool IsWellKnownSource(WellKnownSource wellKnownSource);\r\n\r\n        // Execute a search on the source.\r\n        SearchResult Search(const SearchRequest& request) const;\r\n\r\n        /* Source agreements */\r\n\r\n        // Get required agreement fields info.\r\n        ImplicitAgreementFieldEnum GetAgreementFieldsFromSourceInformation() const;\r\n\r\n        // Checks the source agreements and returns if agreements are satisfied.\r\n        bool CheckSourceAgreements() const;\r\n\r\n        // Saves the accepted source agreements in metadata.\r\n        void SaveAcceptedSourceAgreements() const;\r\n\r\n        /* Composite sources */\r\n\r\n        // Gets a value indicating whether this source is a composite of other sources,\r\n        // and thus the packages may come from disparate sources as well.\r\n        bool IsComposite() const;\r\n\r\n        // Gets the available sources if the source is composite.\r\n        std::vector<Source> GetAvailableSources() const;\r\n\r\n        /* Writable sources */\r\n\r\n        // Adds a package version to the source.\r\n        void AddPackageVersion(const Manifest::Manifest& manifest, const std::filesystem::path& relativePath);\r\n\r\n        // Removes a package version from the source.\r\n        void RemovePackageVersion(const Manifest::Manifest& manifest, const std::filesystem::path& relativePath);\r\n\r\n        /* Source operations */\r\n\r\n        // Opens the source. This function should throw upon open failure rather than returning an empty pointer.\r\n        std::vector<SourceDetails> Open(IProgressCallback& progress);\r\n\r\n        // Add source. Source add command.\r\n        bool Add(IProgressCallback& progress);\r\n\r\n        // Update Source. Source update command.\r\n        std::vector<SourceDetails> Update(IProgressCallback& progress);\r\n\r\n        // Remove source. Source remove command.\r\n        bool Remove(IProgressCallback& progress);\r\n\r\n        // Edit source. Source edit command.\r\n        void Edit(const SourceEdit& edits);\r\n\r\n        // Determines if this source is a valid edit of otherSource.\r\n        // Returns true if this source qualifies as an edit of the other source.\r\n        bool RequiresChanges(const SourceEdit& edits);\r\n\r\n        // Gets the tracking catalog for the current source.\r\n        PackageTrackingCatalog GetTrackingCatalog() const;\r\n\r\n        // Drop source. Source reset command.\r\n        static bool DropSource(std::string_view name);\r\n\r\n        // Get a list of all available SourceDetails.\r\n        static std::vector<SourceDetails> GetCurrentSources();\r\n\r\n        // Get a default source type is the source type used when adding a source without specifying a type.\r\n        static std::string_view GetDefaultSourceType();\r\n\r\n    private:\r\n        void InitializeSourceReference(std::string_view name);\r\n\r\n        std::vector<std::shared_ptr<ISourceReference>> m_sourceReferences;\r\n        std::shared_ptr<ISource> m_source;\r\n        bool m_isSourceToBeAdded = false;\r\n        bool m_isComposite = false;\r\n        std::optional<TimeSpan> m_backgroundUpdateInterval;\r\n        bool m_installedPackageInformationOnly = false;\r\n        mutable std::shared_ptr<PackageTrackingCatalog> m_trackingCatalog;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/RepositorySearch.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/RepositorySearch.h\"\r\n\r\nusing namespace AppInstaller::Settings;\r\nusing namespace std::chrono_literals;\r\n\r\nnamespace AppInstaller::Repository\r\n{\r\n    namespace\r\n    {\r\n        std::string GetStringVectorMessage(const std::vector<std::string>& input)\r\n        {\r\n            std::string result;\r\n            bool first = true;\r\n            for (auto const& field : input)\r\n            {\r\n                if (first)\r\n                {\r\n                    result += field;\r\n                    first = false;\r\n                }\r\n                else\r\n                {\r\n                    result += \", \" + field;\r\n                }\r\n            }\r\n            return result;\r\n        }\r\n    }\r\n\r\n    bool SearchRequest::IsForEverything() const\r\n    {\r\n        return (!Query.has_value() && Inclusions.empty() && Filters.empty());\r\n    }\r\n\r\n    std::string SearchRequest::ToString() const\r\n    {\r\n        std::ostringstream result;\r\n\r\n        result << \"Query:\";\r\n        if (Query)\r\n        {\r\n            result << '\\'' << Query.value().Value << \"'[\" << Repository::ToString(Query.value().Type) << ']';\r\n        }\r\n        else\r\n        {\r\n            result << \"[none]\";\r\n        }\r\n\r\n        for (const auto& include : Inclusions)\r\n        {\r\n            result << \" Include:\" << Repository::ToString(include.Field) << \"='\" << include.Value << \"'\";\r\n            if (include.Additional)\r\n            {\r\n                result << \"+'\" << include.Additional.value() << \"'\";\r\n            }\r\n            result << \"[\" << Repository::ToString(include.Type) << \"]\";\r\n        }\r\n\r\n        for (const auto& filter : Filters)\r\n        {\r\n            result << \" Filter:\" << Repository::ToString(filter.Field) << \"='\" << filter.Value << \"'[\" << Repository::ToString(filter.Type) << \"]\";\r\n        }\r\n\r\n        if (MaximumResults)\r\n        {\r\n            result << \" Limit:\" << MaximumResults;\r\n        }\r\n\r\n        return result.str();\r\n    }\r\n\r\n    std::string_view ToString(PackageVersionMetadata pvm)\r\n    {\r\n        switch (pvm)\r\n        {\r\n        case PackageVersionMetadata::InstalledType: return \"InstalledType\"sv;\r\n        case PackageVersionMetadata::InstalledScope: return \"InstalledScope\"sv;\r\n        case PackageVersionMetadata::InstalledLocation: return \"InstalledLocation\"sv;\r\n        case PackageVersionMetadata::StandardUninstallCommand: return \"StandardUninstallCommand\"sv;\r\n        case PackageVersionMetadata::SilentUninstallCommand: return \"SilentUninstallCommand\"sv;\r\n        case PackageVersionMetadata::Publisher: return \"Publisher\"sv;\r\n        case PackageVersionMetadata::InstalledLocale: return \"InstalledLocale\"sv;\r\n        case PackageVersionMetadata::TrackingWriteTime: return \"TrackingWriteTime\"sv;\r\n        case PackageVersionMetadata::InstalledArchitecture: return \"InstalledArchitecture\"sv;\r\n        case PackageVersionMetadata::PinnedState: return \"PinnedState\"sv;\r\n        case PackageVersionMetadata::UserIntentArchitecture: return \"UserIntentArchitecture\"sv;\r\n        case PackageVersionMetadata::UserIntentLocale: return \"UserIntentLocale\"sv;\r\n        default: return \"Unknown\"sv;\r\n        }\r\n    }\r\n\r\n    bool PackageVersionKey::IsMatch(const PackageVersionKey& other) const\r\n    {\r\n        return\r\n            ((other.SourceId.empty() || other.SourceId == SourceId) &&\r\n             (other.Version.empty() || Utility::Version{ other.Version } == Utility::Version{ Version }) &&\r\n             (other.Channel.empty() || Utility::ICUCaseInsensitiveEquals(other.Channel, Channel)));\r\n    }\r\n\r\n    bool PackageVersionKey::IsDefaultLatest() const\r\n    {\r\n        return Version.empty() && Channel.empty();\r\n    }\r\n\r\n    PackageVersionMultiProperty PackageMultiPropertyToPackageVersionMultiProperty(PackageMultiProperty property)\r\n    {\r\n        switch (property)\r\n        {\r\n        case PackageMultiProperty::PackageFamilyName: return PackageVersionMultiProperty::PackageFamilyName;\r\n        case PackageMultiProperty::ProductCode: return PackageVersionMultiProperty::ProductCode;\r\n        case PackageMultiProperty::UpgradeCode: return PackageVersionMultiProperty::UpgradeCode;\r\n        case PackageMultiProperty::NormalizedName: return PackageVersionMultiProperty::Name;\r\n        case PackageMultiProperty::NormalizedPublisher: return PackageVersionMultiProperty::Publisher;\r\n        case PackageMultiProperty::Tag: return PackageVersionMultiProperty::Tag;\r\n        case PackageMultiProperty::Command: return PackageVersionMultiProperty::Command;\r\n        default:\r\n            THROW_HR_MSG(E_UNEXPECTED, \"PackageMultiProperty must map to a PackageVersionMultiProperty\");\r\n        }\r\n    }\r\n\r\n    const char* UnsupportedRequestException::what() const noexcept\r\n    {\r\n        if (m_whatMessage.empty())\r\n        {\r\n            m_whatMessage = \"The request is not supported.\";\r\n\r\n            if (!UnsupportedPackageMatchFields.empty())\r\n            {\r\n                m_whatMessage += \"Unsupported Package Match Fields: \" + GetStringVectorMessage(UnsupportedPackageMatchFields);\r\n            }\r\n            if (!RequiredPackageMatchFields.empty())\r\n            {\r\n                m_whatMessage += \"Required Package Match Fields: \" + GetStringVectorMessage(RequiredPackageMatchFields);\r\n            }\r\n            if (!UnsupportedQueryParameters.empty())\r\n            {\r\n                m_whatMessage += \"Unsupported Query Parameters: \" + GetStringVectorMessage(UnsupportedQueryParameters);\r\n            }\r\n            if (!RequiredQueryParameters.empty())\r\n            {\r\n                m_whatMessage += \"Required Query Parameters: \" + GetStringVectorMessage(RequiredQueryParameters);\r\n            }\r\n        }\r\n        return m_whatMessage.c_str();\r\n    }\r\n\r\n    std::string_view ToString(MatchType type)\r\n    {\r\n        using namespace std::string_view_literals;\r\n\r\n        switch (type)\r\n        {\r\n        case MatchType::Exact:\r\n            return \"Exact\"sv;\r\n        case MatchType::CaseInsensitive:\r\n            return \"CaseInsensitive\"sv;\r\n        case MatchType::StartsWith:\r\n            return \"StartsWith\"sv;\r\n        case MatchType::Substring:\r\n            return \"Substring\"sv;\r\n        case MatchType::Wildcard:\r\n            return \"Wildcard\"sv;\r\n        case MatchType::Fuzzy:\r\n            return \"Fuzzy\"sv;\r\n        case MatchType::FuzzySubstring:\r\n            return \"FuzzySubstring\"sv;\r\n        }\r\n\r\n        return \"UnknownMatchType\"sv;\r\n    }\r\n\r\n    std::string_view ToString(PackageMatchField matchField)\r\n    {\r\n        using namespace std::string_view_literals;\r\n\r\n        switch (matchField)\r\n        {\r\n        case PackageMatchField::Command:\r\n            return \"Command\"sv;\r\n        case PackageMatchField::Id:\r\n            return \"Id\"sv;\r\n        case PackageMatchField::Moniker:\r\n            return \"Moniker\"sv;\r\n        case PackageMatchField::Name:\r\n            return \"Name\"sv;\r\n        case PackageMatchField::Tag:\r\n            return \"Tag\"sv;\r\n        case PackageMatchField::PackageFamilyName:\r\n            return \"PackageFamilyName\"sv;\r\n        case PackageMatchField::ProductCode:\r\n            return \"ProductCode\"sv;\r\n        case PackageMatchField::UpgradeCode:\r\n            return \"UpgradeCode\"sv;\r\n        case PackageMatchField::NormalizedNameAndPublisher:\r\n            return \"NormalizedNameAndPublisher\"sv;\r\n        case PackageMatchField::Market:\r\n            return \"Market\"sv;\r\n        }\r\n\r\n        return \"UnknownMatchField\"sv;\r\n    }\r\n\r\n    PackageMatchField StringToPackageMatchField(std::string_view field)\r\n    {\r\n        std::string toLower = Utility::ToLower(field);\r\n\r\n        if (toLower == \"command\")\r\n        {\r\n            return PackageMatchField::Command;\r\n        }\r\n        else if (toLower == \"id\")\r\n        {\r\n            return PackageMatchField::Id;\r\n        }\r\n        else if (toLower == \"moniker\")\r\n        {\r\n            return PackageMatchField::Moniker;\r\n        }\r\n        else if (toLower == \"name\")\r\n        {\r\n            return PackageMatchField::Name;\r\n        }\r\n        else if (toLower == \"tag\")\r\n        {\r\n            return PackageMatchField::Tag;\r\n        }\r\n        else if (toLower == \"packagefamilyname\")\r\n        {\r\n            return PackageMatchField::PackageFamilyName;\r\n        }\r\n        else if (toLower == \"productcode\")\r\n        {\r\n            return PackageMatchField::ProductCode;\r\n        }\r\n        else if (toLower == \"upgradecode\")\r\n        {\r\n            return PackageMatchField::UpgradeCode;\r\n        }\r\n        else if (toLower == \"normalizednameandpublisher\")\r\n        {\r\n            return PackageMatchField::NormalizedNameAndPublisher;\r\n        }\r\n        else if (toLower == \"market\")\r\n        {\r\n            return PackageMatchField::Market;\r\n        }\r\n\r\n        return PackageMatchField::Unknown;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/RepositorySource.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ISource.h\"\r\n#include \"CompositeSource.h\"\r\n#include \"SourceFactory.h\"\r\n#include \"SourceList.h\"\r\n#include \"SourcePolicy.h\"\r\n#include \"Microsoft/PredefinedInstalledSourceFactory.h\"\r\n#include \"Microsoft/PredefinedWriteableSourceFactory.h\"\r\n#include \"Microsoft/PreIndexedPackageSourceFactory.h\"\r\n#include \"Rest/RestSourceFactory.h\"\r\n#include \"PackageTrackingCatalogSourceFactory.h\"\r\n#include \"SourceUpdateChecks.h\"\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n#include \"Microsoft/ConfigurableTestSourceFactory.h\"\r\n#endif\r\n\r\n#include <winget/GroupPolicy.h>\r\n\r\nusing namespace AppInstaller::Settings;\r\nusing namespace std::chrono_literals;\r\nusing namespace AppInstaller::Utility::literals;\r\n\r\nnamespace AppInstaller::Repository\r\n{\r\n    namespace\r\n    {\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        static std::map<std::string, std::function<std::unique_ptr<ISourceFactory>()>> s_Sources_TestHook_SourceFactories;\r\n#endif\r\n\r\n        std::shared_ptr<ISourceReference> CreateSourceFromDetails(const SourceDetails& details)\r\n        {\r\n            return ISourceFactory::GetForType(details.Type)->Create(details);\r\n        }\r\n\r\n        std::chrono::milliseconds GetMillisecondsToWait(std::chrono::seconds retryAfter, size_t randomMultiplier = 1)\r\n        {\r\n            if (retryAfter != 0s)\r\n            {\r\n                return std::chrono::duration_cast<std::chrono::milliseconds>(retryAfter);\r\n            }\r\n            else\r\n            {\r\n                // Add a bit of randomness to the retry wait time\r\n                std::default_random_engine randomEngine(std::random_device{}());\r\n                std::uniform_int_distribution<long long> distribution(2000, 10000);\r\n\r\n                return std::chrono::milliseconds(distribution(randomEngine) * randomMultiplier);\r\n            }\r\n        }\r\n\r\n        struct AddOrUpdateResult\r\n        {\r\n            bool UpdateChecked = false;\r\n            bool MetadataWritten = false;\r\n        };\r\n\r\n        template <typename MemberFunc>\r\n        AddOrUpdateResult AddOrUpdateFromDetails(SourceDetails& details, MemberFunc member, IProgressCallback& progress)\r\n        {\r\n            AddOrUpdateResult result;\r\n\r\n            auto factory = ISourceFactory::GetForType(details.Type);\r\n\r\n            // If we are instructed to wait longer than this, just fail rather than retrying.\r\n            constexpr std::chrono::seconds maximumWaitTimeAllowed = 60s;\r\n            std::chrono::seconds waitSecondsForRetry = 0s;\r\n\r\n            // Attempt; if it fails, wait a short time and retry.\r\n            try\r\n            {\r\n                result.UpdateChecked = (factory.get()->*member)(details, progress);\r\n                if (result.UpdateChecked)\r\n                {\r\n                    details.LastUpdateTime = std::chrono::system_clock::now();\r\n                    result.MetadataWritten = true;\r\n                }\r\n                return result;\r\n            }\r\n            catch (const Utility::ServiceUnavailableException& sue)\r\n            {\r\n                waitSecondsForRetry = sue.RetryAfter();\r\n\r\n                // Do not retry if the server tell us to wait more than the max time allowed.\r\n                if (waitSecondsForRetry > maximumWaitTimeAllowed)\r\n                {\r\n                    details.DoNotUpdateBefore = std::chrono::system_clock::now() + waitSecondsForRetry;\r\n                    AICLI_LOG(Repo, Info, << \"Source `\" << details.Name << \"` unavailable first try, setting DoNotUpdateBefore to \" << details.DoNotUpdateBefore);\r\n                    result.MetadataWritten = true;\r\n                    return result;\r\n                }\r\n            }\r\n            CATCH_LOG();\r\n\r\n            std::chrono::milliseconds millisecondsToWait = GetMillisecondsToWait(waitSecondsForRetry);\r\n\r\n            AICLI_LOG(Repo, Info, << \"Source add/update failed, waiting \" << millisecondsToWait.count() << \" milliseconds and retrying: \" << details.Name);\r\n\r\n            if (!ProgressCallback::Wait(progress, millisecondsToWait))\r\n            {\r\n                AICLI_LOG(Repo, Info, << \"Source second try cancelled.\");\r\n                return {};\r\n            }\r\n\r\n            try\r\n            {\r\n                // If this one fails, maybe the problem is persistent.\r\n                result.UpdateChecked = (factory.get()->*member)(details, progress);\r\n                if (result.UpdateChecked)\r\n                {\r\n                    details.LastUpdateTime = std::chrono::system_clock::now();\r\n                    result.MetadataWritten = true;\r\n                }\r\n            }\r\n            catch (const Utility::ServiceUnavailableException& sue)\r\n            {\r\n                details.DoNotUpdateBefore = std::chrono::system_clock::now() + GetMillisecondsToWait(sue.RetryAfter(), 3);\r\n                AICLI_LOG(Repo, Info, << \"Source `\" << details.Name << \"` unavailable second try, setting DoNotUpdateBefore to \" << details.DoNotUpdateBefore);\r\n                result.MetadataWritten = true;\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        AddOrUpdateResult AddSourceFromDetails(SourceDetails& details, IProgressCallback& progress)\r\n        {\r\n            return AddOrUpdateFromDetails(details, &ISourceFactory::Add, progress);\r\n        }\r\n\r\n        AddOrUpdateResult UpdateSourceFromDetails(SourceDetails& details, IProgressCallback& progress)\r\n        {\r\n            return AddOrUpdateFromDetails(details, &ISourceFactory::Update, progress);\r\n        }\r\n\r\n        AddOrUpdateResult BackgroundUpdateSourceFromDetails(SourceDetails& details, IProgressCallback& progress)\r\n        {\r\n            return AddOrUpdateFromDetails(details, &ISourceFactory::BackgroundUpdate, progress);\r\n        }\r\n\r\n        bool RemoveSourceFromDetails(const SourceDetails& details, IProgressCallback& progress)\r\n        {\r\n            auto factory = ISourceFactory::GetForType(details.Type);\r\n\r\n            return factory->Remove(details, progress);\r\n        }\r\n\r\n        bool ContainsAvailablePackagesInternal(SourceOrigin origin)\r\n        {\r\n            return (origin == SourceOrigin::Default || origin == SourceOrigin::GroupPolicy || origin == SourceOrigin::User);\r\n        }\r\n\r\n        SourceDetails GetPredefinedSourceDetails(PredefinedSource source)\r\n        {\r\n            SourceDetails details;\r\n            details.Origin = SourceOrigin::Predefined;\r\n\r\n            switch (source)\r\n            {\r\n            case PredefinedSource::Installed:\r\n                details.Type = Microsoft::PredefinedInstalledSourceFactory::Type();\r\n                details.Arg = Microsoft::PredefinedInstalledSourceFactory::FilterToString(Microsoft::PredefinedInstalledSourceFactory::Filter::None);\r\n                return details;\r\n            case PredefinedSource::InstalledForceCacheUpdate:\r\n                details.Type = Microsoft::PredefinedInstalledSourceFactory::Type();\r\n                details.Arg = Microsoft::PredefinedInstalledSourceFactory::FilterToString(Microsoft::PredefinedInstalledSourceFactory::Filter::NoneWithForcedCacheUpdate);\r\n                return details;\r\n            case PredefinedSource::InstalledUser:\r\n                details.Type = Microsoft::PredefinedInstalledSourceFactory::Type();\r\n                details.Arg = Microsoft::PredefinedInstalledSourceFactory::FilterToString(Microsoft::PredefinedInstalledSourceFactory::Filter::User);\r\n                return details;\r\n            case PredefinedSource::InstalledMachine:\r\n                details.Type = Microsoft::PredefinedInstalledSourceFactory::Type();\r\n                details.Arg = Microsoft::PredefinedInstalledSourceFactory::FilterToString(Microsoft::PredefinedInstalledSourceFactory::Filter::Machine);\r\n                return details;\r\n            case PredefinedSource::ARP:\r\n                details.Type = Microsoft::PredefinedInstalledSourceFactory::Type();\r\n                details.Arg = Microsoft::PredefinedInstalledSourceFactory::FilterToString(Microsoft::PredefinedInstalledSourceFactory::Filter::ARP);\r\n                return details;\r\n            case PredefinedSource::MSIX:\r\n                details.Type = Microsoft::PredefinedInstalledSourceFactory::Type();\r\n                details.Arg = Microsoft::PredefinedInstalledSourceFactory::FilterToString(Microsoft::PredefinedInstalledSourceFactory::Filter::MSIX);\r\n                return details;\r\n            case PredefinedSource::Installing:\r\n                details.Type = Microsoft::PredefinedWriteableSourceFactory::Type();\r\n                // As long as there is only one type this is not particularly needed, but Arg is exposed publicly\r\n                // so this is used here for consistency with other predefined sources.\r\n                details.Arg = Microsoft::PredefinedWriteableSourceFactory::TypeToString(Microsoft::PredefinedWriteableSourceFactory::WriteableType::Installing);\r\n                return details;\r\n            }\r\n\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n\r\n        // Carries the exception from an OpenSource call and presents it back at search time.\r\n        struct OpenExceptionProxy : public ISource, std::enable_shared_from_this<OpenExceptionProxy>\r\n        {\r\n            static constexpr ISourceType SourceType = ISourceType::OpenExceptionProxy;\r\n\r\n            OpenExceptionProxy(const SourceDetails& details, std::exception_ptr exception) :\r\n                m_details(details), m_exception(std::move(exception)) {}\r\n\r\n            const SourceDetails& GetDetails() const override { return m_details; }\r\n\r\n            const std::string& GetIdentifier() const override { return m_details.Identifier; }\r\n\r\n            SearchResult Search(const SearchRequest&) const override\r\n            {\r\n                SearchResult result;\r\n                result.Failures.emplace_back(SearchResult::Failure{ GetDetails().Name, m_exception });\r\n                return result;\r\n            }\r\n\r\n            void* CastTo(ISourceType type) override\r\n            {\r\n                if (type == SourceType)\r\n                {\r\n                    return this;\r\n                }\r\n\r\n                return nullptr;\r\n            }\r\n\r\n        private:\r\n            SourceDetails m_details;\r\n            std::exception_ptr m_exception;\r\n        };\r\n\r\n        // A wrapper that doesn't actually forward the search requests.\r\n        struct TrackingOnlySourceWrapper : public ISource\r\n        {\r\n            TrackingOnlySourceWrapper(std::shared_ptr<ISourceReference> wrapped) : m_wrapped(std::move(wrapped))\r\n            {\r\n                m_identifier = m_wrapped->GetIdentifier();\r\n            }\r\n\r\n            const std::string& GetIdentifier() const override { return m_identifier; }\r\n\r\n            SourceDetails& GetDetails() const override { return m_wrapped->GetDetails(); }\r\n\r\n            SourceInformation GetInformation() const override { return m_wrapped->GetInformation(); }\r\n\r\n            SearchResult Search(const SearchRequest&) const override { return {}; }\r\n\r\n            void* CastTo(ISourceType) override { return nullptr; }\r\n\r\n        private:\r\n            std::shared_ptr<ISourceReference> m_wrapped;\r\n            std::string m_identifier;\r\n        };\r\n\r\n        // A wrapper to create another wrapper.\r\n        struct TrackingOnlyReferenceWrapper : public ISourceReference\r\n        {\r\n            TrackingOnlyReferenceWrapper(std::shared_ptr<ISourceReference> wrapped) : m_wrapped(std::move(wrapped)) {}\r\n\r\n            std::string GetIdentifier() override { return m_wrapped->GetIdentifier(); }\r\n\r\n            SourceDetails& GetDetails() override { return m_wrapped->GetDetails(); }\r\n\r\n            SourceInformation GetInformation() override { return m_wrapped->GetInformation(); }\r\n\r\n            bool SetCustomHeader(std::optional<std::string>) override { return false; }\r\n\r\n            void SetCaller(std::string caller) override { m_wrapped->SetCaller(std::move(caller)); }\r\n\r\n            std::shared_ptr<ISource> Open(IProgressCallback&) override\r\n            {\r\n                return std::make_shared<TrackingOnlySourceWrapper>(m_wrapped);\r\n            }\r\n\r\n        private:\r\n            std::shared_ptr<ISourceReference> m_wrapped;\r\n        };\r\n    }\r\n\r\n    std::unique_ptr<ISourceFactory> ISourceFactory::GetForType(std::string_view type)\r\n    {\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        // Tests can ensure case matching\r\n        auto itr = s_Sources_TestHook_SourceFactories.find(std::string(type));\r\n        if (itr != s_Sources_TestHook_SourceFactories.end())\r\n        {\r\n            return itr->second();\r\n        }\r\n\r\n        if (Utility::CaseInsensitiveEquals(Microsoft::ConfigurableTestSourceFactory::Type(), type))\r\n        {\r\n            return Microsoft::ConfigurableTestSourceFactory::Create();\r\n        }\r\n#endif\r\n\r\n        // For now, enable an empty type to represent the only one we have.\r\n        if (type.empty() ||\r\n            Utility::CaseInsensitiveEquals(Microsoft::PreIndexedPackageSourceFactory::Type(), type))\r\n        {\r\n            return Microsoft::PreIndexedPackageSourceFactory::Create();\r\n        }\r\n        // Should always come from code, so no need for case insensitivity\r\n        else if (Microsoft::PredefinedInstalledSourceFactory::Type() == type)\r\n        {\r\n            return Microsoft::PredefinedInstalledSourceFactory::Create();\r\n        }\r\n        // Should always come from code, so no need for case insensitivity\r\n        else if (Microsoft::PredefinedWriteableSourceFactory::Type() == type)\r\n        {\r\n            return Microsoft::PredefinedWriteableSourceFactory::Create();\r\n        }\r\n        // Should always come from code, so no need for case insensitivity\r\n        else if (PackageTrackingCatalogSourceFactory::Type() == type)\r\n        {\r\n            return PackageTrackingCatalogSourceFactory::Create();\r\n        }\r\n        else if (Utility::CaseInsensitiveEquals(Rest::RestSourceFactory::Type(), type))\r\n        {\r\n            return Rest::RestSourceFactory::Create();\r\n        }\r\n\r\n        THROW_HR(APPINSTALLER_CLI_ERROR_INVALID_SOURCE_TYPE);\r\n    }\r\n\r\n    SourceTrustLevel ConvertToSourceTrustLevelEnum(std::string_view trustLevel)\r\n    {\r\n        std::string lowerTrustLevel = Utility::ToLower(trustLevel);\r\n\r\n        if (lowerTrustLevel == \"storeorigin\")\r\n        {\r\n            return SourceTrustLevel::StoreOrigin;\r\n        }\r\n        else if (lowerTrustLevel == \"trusted\")\r\n        {\r\n            return SourceTrustLevel::Trusted;\r\n        }\r\n        else if (lowerTrustLevel == \"none\")\r\n        {\r\n            return SourceTrustLevel::None;\r\n        }\r\n        else\r\n        {\r\n            THROW_HR(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED));\r\n        }\r\n    }\r\n\r\n    std::string_view SourceTrustLevelEnumToString(SourceTrustLevel trustLevel)\r\n    {\r\n        switch (trustLevel)\r\n        {\r\n        case SourceTrustLevel::StoreOrigin:\r\n            return \"StoreOrigin\"sv;\r\n        case SourceTrustLevel::Trusted:\r\n            return \"Trusted\"sv;\r\n        case SourceTrustLevel::None:\r\n            return \"None\"sv;\r\n        }\r\n\r\n        return \"Unknown\"sv;\r\n    }\r\n\r\n    SourceTrustLevel ConvertToSourceTrustLevelFlag(std::vector<std::string> trustLevels)\r\n    {\r\n        Repository::SourceTrustLevel result = Repository::SourceTrustLevel::None;\r\n        for (auto& trustLevel : trustLevels)\r\n        {\r\n            Repository::SourceTrustLevel trustLevelEnum = ConvertToSourceTrustLevelEnum(trustLevel);\r\n            if (trustLevelEnum == Repository::SourceTrustLevel::None)\r\n            {\r\n                return Repository::SourceTrustLevel::None;\r\n            }\r\n            else if (trustLevelEnum == Repository::SourceTrustLevel::Trusted)\r\n            {\r\n                WI_SetFlag(result, Repository::SourceTrustLevel::Trusted);\r\n            }\r\n            else if (trustLevelEnum == Repository::SourceTrustLevel::StoreOrigin)\r\n            {\r\n                WI_SetFlag(result, Repository::SourceTrustLevel::StoreOrigin);\r\n            }\r\n            else\r\n            {\r\n                THROW_HR_MSG(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), \"Invalid source trust level.\");\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<std::string_view> SourceTrustLevelFlagToList(SourceTrustLevel trustLevel)\r\n    {\r\n        std::vector<std::string_view> result;\r\n\r\n        if (WI_IsFlagSet(trustLevel, Repository::SourceTrustLevel::Trusted))\r\n        {\r\n            result.emplace_back(Repository::SourceTrustLevelEnumToString(Repository::SourceTrustLevel::Trusted));\r\n        }\r\n        if (WI_IsFlagSet(trustLevel, Repository::SourceTrustLevel::StoreOrigin))\r\n        {\r\n            result.emplace_back(Repository::SourceTrustLevelEnumToString(Repository::SourceTrustLevel::StoreOrigin));\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::string GetSourceTrustLevelForDisplay(SourceTrustLevel trustLevel)\r\n    {\r\n        std::vector<std::string_view> trustLevelList = Repository::SourceTrustLevelFlagToList(trustLevel);\r\n        std::vector<Utility::LocIndString> locIndList(trustLevelList.begin(), trustLevelList.end());\r\n        return Utility::Join(\"|\"_liv, locIndList);\r\n    }\r\n\r\n    std::string_view ToString(SourceOrigin origin)\r\n    {\r\n        switch (origin)\r\n        {\r\n        case SourceOrigin::Default:\r\n            return \"Default\"sv;\r\n        case SourceOrigin::User:\r\n            return \"User\"sv;\r\n        case SourceOrigin::Predefined:\r\n            return \"Predefined\"sv;\r\n        case SourceOrigin::GroupPolicy:\r\n            return \"GroupPolicy\"sv;\r\n        case SourceOrigin::Metadata:\r\n            return \"Metadata\"sv;\r\n        default:\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n    }\r\n\r\n    std::optional<WellKnownSource> CheckForWellKnownSource(const SourceDetails& sourceDetails)\r\n    {\r\n        return CheckForWellKnownSourceMatch(sourceDetails.Name, sourceDetails.Arg, sourceDetails.Type);\r\n    }\r\n\r\n    Source::Source() {}\r\n\r\n    Source::Source(std::string_view name)\r\n    {\r\n        InitializeSourceReference(name);\r\n    }\r\n\r\n    Source::Source(PredefinedSource source)\r\n    {\r\n        SourceDetails details = GetPredefinedSourceDetails(source);\r\n        m_sourceReferences.emplace_back(CreateSourceFromDetails(details));\r\n    }\r\n\r\n    Source::Source(WellKnownSource source)\r\n    {\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY, !IsWellKnownSourceEnabled(source));\r\n\r\n        auto details = GetWellKnownSourceDetailsInternal(source);\r\n\r\n        // Populate metadata\r\n        SourceList sourceList;\r\n        auto sourceDetailsWithMetadata = sourceList.GetSource(details.Name);\r\n        if (sourceDetailsWithMetadata)\r\n        {\r\n            sourceDetailsWithMetadata->CopyMetadataFieldsTo(details);\r\n        }\r\n\r\n        m_sourceReferences.emplace_back(CreateSourceFromDetails(details));\r\n    }\r\n\r\n    Source::Source(std::string_view name, std::string_view arg, std::string_view type, SourceTrustLevel trustLevel, const SourceEdit& additionalProperties)\r\n    {\r\n        m_isSourceToBeAdded = true;\r\n        SourceDetails details;\r\n\r\n        std::optional<WellKnownSource> wellKnownSourceCheck = CheckForWellKnownSourceMatch(name, arg, type);\r\n\r\n        if (wellKnownSourceCheck)\r\n        {\r\n            details = GetWellKnownSourceDetailsInternal(wellKnownSourceCheck.value());\r\n        }\r\n        else\r\n        {\r\n            details.Name = name;\r\n            details.Arg = arg;\r\n            details.Type = type;\r\n            details.TrustLevel = trustLevel;\r\n            if (additionalProperties.Explicit)\r\n            {\r\n                details.Explicit = additionalProperties.Explicit.value();\r\n            }\r\n            if (additionalProperties.Priority)\r\n            {\r\n                details.Priority = additionalProperties.Priority.value();\r\n            }\r\n        }\r\n\r\n        m_sourceReferences.emplace_back(CreateSourceFromDetails(details));\r\n    }\r\n\r\n    Source::Source(const std::vector<Source>& availableSources)\r\n    {\r\n        std::shared_ptr<CompositeSource> compositeSource = std::make_shared<CompositeSource>(\"*CompositeSource\");\r\n\r\n        for (const auto& availableSource : availableSources)\r\n        {\r\n            THROW_HR_IF(E_INVALIDARG, !availableSource.m_source || availableSource.IsComposite());\r\n            compositeSource->AddAvailableSource(availableSource.m_source);\r\n        }\r\n\r\n        m_source = compositeSource;\r\n        m_isComposite = true;\r\n    }\r\n\r\n    Source::Source(const Source& installedSource, const Source& availableSource, CompositeSearchBehavior searchBehavior)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, !installedSource.m_source || installedSource.m_isComposite || !availableSource.m_source);\r\n\r\n        std::shared_ptr<CompositeSource> compositeSource = SourceCast<CompositeSource>(availableSource.m_source);\r\n\r\n        if (!compositeSource)\r\n        {\r\n            compositeSource = std::make_shared<CompositeSource>(\"*CompositeSource\");\r\n            compositeSource->AddAvailableSource(availableSource.m_source);\r\n        }\r\n\r\n        compositeSource->SetInstalledSource(installedSource, searchBehavior);\r\n\r\n        m_source = compositeSource;\r\n        m_isComposite = true;\r\n    }\r\n\r\n    Source::Source(std::shared_ptr<ISource> source) : m_source(std::move(source)) {}\r\n\r\n    Source::operator bool() const\r\n    {\r\n        return !m_sourceReferences.empty() || m_source != nullptr;\r\n    }\r\n\r\n    void Source::InitializeSourceReference(std::string_view name)\r\n    {\r\n        SourceList sourceList;\r\n\r\n        if (name.empty())\r\n        {\r\n            auto currentSources = sourceList.GetCurrentSourceRefs();\r\n            if (currentSources.empty())\r\n            {\r\n                AICLI_LOG(Repo, Info, << \"Default source requested, but no sources configured\");\r\n            }\r\n            else if (currentSources.size() == 1)\r\n            {\r\n                if (!currentSources[0].get().Explicit)\r\n                {\r\n                    AICLI_LOG(Repo, Info, << \"Default source requested, only 1 source available, using the only source: \" << currentSources[0].get().Name);\r\n                    InitializeSourceReference(currentSources[0].get().Name);\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(Repo, Info, << \"Skipping explicit source reference \" << currentSources[0].get().Name);\r\n                }\r\n            }\r\n            else\r\n            {\r\n                AICLI_LOG(Repo, Info, << \"Default source requested, multiple sources available, adding all to source references.\");\r\n\r\n                for (auto& source : currentSources)\r\n                {\r\n                    if (!source.get().Explicit)\r\n                    {\r\n                        AICLI_LOG(Repo, Info, << \"Adding to source references \" << source.get().Name);\r\n                        m_sourceReferences.emplace_back(CreateSourceFromDetails(source));\r\n                    }\r\n                    else\r\n                    {\r\n                        AICLI_LOG(Repo, Info, << \"Skipping explicit source reference \" << source.get().Name);\r\n                    }\r\n                }\r\n\r\n                if (m_sourceReferences.size() > 1)\r\n                {\r\n                    m_isComposite = true;\r\n                }\r\n            }\r\n        }\r\n        else\r\n        {\r\n            auto source = sourceList.GetCurrentSource(name);\r\n            if (!source)\r\n            {\r\n                AICLI_LOG(Repo, Info, << \"Named source requested, but not found: \" << name);\r\n            }\r\n            else\r\n            {\r\n                AICLI_LOG(Repo, Info, << \"Named source requested, found: \" << source->Name);\r\n                m_sourceReferences.emplace_back(CreateSourceFromDetails(*source));\r\n            }\r\n        }\r\n    }\r\n\r\n    bool Source::operator==(const Source& other) const\r\n    {\r\n        SourceDetails thisDetails = GetDetails();\r\n        SourceDetails otherDetails = other.GetDetails();\r\n\r\n        return (thisDetails.Type == otherDetails.Type && thisDetails.Identifier == otherDetails.Identifier);\r\n    }\r\n\r\n    bool Source::operator!=(const Source& other) const\r\n    {\r\n        return !operator==(other);\r\n    }\r\n\r\n    std::string Source::GetIdentifier() const\r\n    {\r\n        if (m_source)\r\n        {\r\n            return m_source->GetIdentifier();\r\n        }\r\n        else if (m_sourceReferences.size() == 1)\r\n        {\r\n            return m_sourceReferences[0]->GetIdentifier();\r\n        }\r\n        else\r\n        {\r\n            THROW_HR(HRESULT_FROM_WIN32(ERROR_INVALID_STATE));\r\n        }\r\n    }\r\n\r\n    SourceDetails Source::GetDetails() const\r\n    {\r\n        if (m_source)\r\n        {\r\n            return m_source->GetDetails();\r\n        }\r\n        else if (m_sourceReferences.size() == 1)\r\n        {\r\n            return m_sourceReferences[0]->GetDetails();\r\n        }\r\n        else\r\n        {\r\n            THROW_HR(HRESULT_FROM_WIN32(ERROR_INVALID_STATE));\r\n        }\r\n    }\r\n\r\n    SourceInformation Source::GetInformation() const\r\n    {\r\n        if (m_source && !m_isComposite)\r\n        {\r\n            return m_source->GetInformation();\r\n        }\r\n        else if (m_sourceReferences.size() == 1)\r\n        {\r\n            return m_sourceReferences[0]->GetInformation();\r\n        }\r\n        else\r\n        {\r\n            THROW_HR(HRESULT_FROM_WIN32(ERROR_INVALID_STATE));\r\n        }\r\n    }\r\n\r\n    bool Source::QueryFeatureFlag(SourceFeatureFlag flag) const\r\n    {\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !m_source);\r\n        return m_source->QueryFeatureFlag(flag);\r\n    }\r\n\r\n    bool Source::ContainsAvailablePackages() const\r\n    {\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), IsComposite());\r\n        return ContainsAvailablePackagesInternal(GetDetails().Origin);\r\n    }\r\n\r\n    bool Source::SetCustomHeader(std::optional<std::string> header)\r\n    {\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), m_sourceReferences.size() != 1);\r\n        return m_sourceReferences[0]->SetCustomHeader(header);\r\n    }\r\n\r\n    void Source::SetCaller(std::string caller)\r\n    {\r\n        for (auto& sourceReference : m_sourceReferences)\r\n        {\r\n            sourceReference->SetCaller(caller);\r\n        }\r\n    }\r\n\r\n    void Source::SetAuthenticationArguments(Authentication::AuthenticationArguments args)\r\n    {\r\n        for (auto& sourceReference : m_sourceReferences)\r\n        {\r\n            sourceReference->SetAuthenticationArguments(args);\r\n        }\r\n    }\r\n\r\n    void Source::SetThreadGlobals(const std::shared_ptr<ThreadLocalStorage::ThreadGlobals>& threadGlobals)\r\n    {\r\n        for (auto& sourceReference : m_sourceReferences)\r\n        {\r\n            sourceReference->SetThreadGlobals(threadGlobals);\r\n        }\r\n    }\r\n\r\n    void Source::SetBackgroundUpdateInterval(TimeSpan interval)\r\n    {\r\n        m_backgroundUpdateInterval = interval;\r\n    }\r\n\r\n    void Source::InstalledPackageInformationOnly(bool value)\r\n    {\r\n        m_installedPackageInformationOnly = value;\r\n    }\r\n\r\n    bool Source::IsWellKnownSource(WellKnownSource wellKnownSource)\r\n    {\r\n        SourceDetails details = GetDetails();\r\n        auto wellKnown = CheckForWellKnownSourceMatch(details.Name, details.Arg, details.Type);\r\n        return wellKnown && wellKnown.value() == wellKnownSource;\r\n    }\r\n\r\n    SearchResult Source::Search(const SearchRequest& request) const\r\n    {\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !m_source);\r\n        return m_source->Search(request);\r\n    }\r\n\r\n    ImplicitAgreementFieldEnum Source::GetAgreementFieldsFromSourceInformation() const\r\n    {\r\n        ImplicitAgreementFieldEnum result = ImplicitAgreementFieldEnum::None;\r\n\r\n        auto info = GetInformation();\r\n        if (info.RequiredPackageMatchFields.end() != std::find_if(info.RequiredPackageMatchFields.begin(), info.RequiredPackageMatchFields.end(), [&](const auto& field) { return Utility::CaseInsensitiveEquals(field, \"market\"); }) ||\r\n            info.RequiredQueryParameters.end() != std::find_if(info.RequiredQueryParameters.begin(), info.RequiredQueryParameters.end(), [&](const auto& param) { return Utility::CaseInsensitiveEquals(param, \"market\"); }))\r\n        {\r\n            WI_SetFlag(result, ImplicitAgreementFieldEnum::Market);\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    bool Source::CheckSourceAgreements() const\r\n    {\r\n        auto sourceName = GetDetails().Name;\r\n        auto agreementFields = GetAgreementFieldsFromSourceInformation();\r\n        auto agreementsIdentifier = GetInformation().SourceAgreementsIdentifier;\r\n\r\n        SourceList sourceList;\r\n        return sourceList.CheckSourceAgreements(sourceName, agreementsIdentifier, agreementFields);\r\n    }\r\n\r\n    void Source::SaveAcceptedSourceAgreements() const\r\n    {\r\n        auto sourceName = GetDetails().Name;\r\n        auto agreementFields = GetAgreementFieldsFromSourceInformation();\r\n        auto agreementsIdentifier = GetInformation().SourceAgreementsIdentifier;\r\n\r\n        SourceList sourceList;\r\n        return sourceList.SaveAcceptedSourceAgreements(sourceName, agreementsIdentifier, agreementFields);\r\n    }\r\n\r\n    bool Source::IsComposite() const\r\n    {\r\n        return m_isComposite;\r\n    }\r\n\r\n    std::vector<Source> Source::GetAvailableSources() const\r\n    {\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !m_source || !m_isComposite);\r\n\r\n        auto compositeSource = SourceCast<CompositeSource>(m_source);\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !compositeSource);\r\n\r\n        return compositeSource->GetAvailableSources();\r\n    }\r\n\r\n    void Source::AddPackageVersion(const Manifest::Manifest& manifest, const std::filesystem::path& relativePath)\r\n    {\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !m_source);\r\n        auto writableSource = SourceCast<IMutablePackageSource>(m_source);\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !writableSource);\r\n        writableSource->AddPackageVersion(manifest, relativePath);\r\n    }\r\n\r\n    void Source::RemovePackageVersion(const Manifest::Manifest& manifest, const std::filesystem::path& relativePath)\r\n    {\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !m_source);\r\n        auto writableSource = SourceCast<IMutablePackageSource>(m_source);\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !writableSource);\r\n        writableSource->RemovePackageVersion(manifest, relativePath);\r\n    }\r\n\r\n    std::vector<SourceDetails> Source::Open(IProgressCallback& progress)\r\n    {\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), m_isSourceToBeAdded || m_sourceReferences.empty());\r\n\r\n        std::vector<SourceDetails> result;\r\n\r\n        if (!m_source)\r\n        {\r\n            std::vector<std::shared_ptr<ISourceReference>>* sourceReferencesToOpen = nullptr;\r\n            std::vector<std::shared_ptr<ISourceReference>> sourceReferencesForTrackingOnly;\r\n            std::unique_ptr<SourceList> sourceList;\r\n\r\n            if (m_installedPackageInformationOnly)\r\n            {\r\n                sourceReferencesToOpen = &sourceReferencesForTrackingOnly;\r\n\r\n                // Create a wrapper for each reference\r\n                for (auto& sourceReference : m_sourceReferences)\r\n                {\r\n                    sourceReferencesForTrackingOnly.emplace_back(std::make_shared<TrackingOnlyReferenceWrapper>(sourceReference));\r\n                }\r\n            }\r\n            else\r\n            {\r\n                // Check for updates before opening.\r\n                for (auto& sourceReference : m_sourceReferences)\r\n                {\r\n                    if (ShouldUpdateBeforeOpen(sourceReference.get(), m_backgroundUpdateInterval))\r\n                    {\r\n                        auto& details = sourceReference->GetDetails();\r\n\r\n                        try\r\n                        {\r\n                            // TODO: Consider adding a context callback to indicate we are doing the same action\r\n                            // to avoid the progress bar fill up multiple times.\r\n                            AddOrUpdateResult updateResult = BackgroundUpdateSourceFromDetails(details, progress);\r\n\r\n                            if (updateResult.MetadataWritten)\r\n                            {\r\n                                if (sourceList == nullptr)\r\n                                {\r\n                                    sourceList = std::make_unique<SourceList>();\r\n                                }\r\n\r\n                                auto detailsInternal = sourceList->GetSource(details.Name);\r\n                                detailsInternal->CopyMetadataFieldsFrom(details);\r\n                                sourceList->SaveMetadata(*detailsInternal);\r\n                            }\r\n\r\n                            if (!updateResult.UpdateChecked)\r\n                            {\r\n                                AICLI_LOG(Repo, Error, << \"Failed to update source: \" << details.Name);\r\n                                result.emplace_back(details);\r\n                            }\r\n                        }\r\n                        catch (...)\r\n                        {\r\n                            LOG_CAUGHT_EXCEPTION();\r\n                            AICLI_LOG(Repo, Warning, << \"Failed to update source: \" << details.Name);\r\n                            result.emplace_back(details);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                sourceReferencesToOpen = &m_sourceReferences;\r\n            }\r\n\r\n            if (sourceReferencesToOpen->size() > 1)\r\n            {\r\n                AICLI_LOG(Repo, Info, << \"Multiple sources available, creating aggregated source.\");\r\n                auto aggregatedSource = std::make_shared<CompositeSource>(\"*DefaultSource\");\r\n                std::vector<std::shared_ptr<OpenExceptionProxy>> openExceptionProxies;\r\n\r\n                for (auto& sourceReference : *sourceReferencesToOpen)\r\n                {\r\n                    AICLI_LOG(Repo, Info, << \"Adding to aggregated source: \" << sourceReference->GetDetails().Name);\r\n\r\n                    try\r\n\r\n                    {\r\n                        aggregatedSource->AddAvailableSource(sourceReference->Open(progress));\r\n                    }\r\n                    catch (...)\r\n                    {\r\n                        LOG_CAUGHT_EXCEPTION();\r\n                        AICLI_LOG(Repo, Warning, << \"Failed to open available source: \" << sourceReference->GetDetails().Name);\r\n                        openExceptionProxies.emplace_back(std::make_shared<OpenExceptionProxy>(sourceReference->GetDetails(), std::current_exception()));\r\n                    }\r\n                }\r\n\r\n                // If all sources failed to open, then throw an exception that is specific to this case.\r\n                THROW_HR_IF(APPINSTALLER_CLI_ERROR_FAILED_TO_OPEN_ALL_SOURCES, !aggregatedSource->HasAvailableSource());\r\n\r\n                // Place all of the proxies into the source to be searched later\r\n                for (auto& proxy : openExceptionProxies)\r\n                {\r\n                    aggregatedSource->AddAvailableSource(Source{ std::move(proxy) });\r\n                }\r\n\r\n                m_source = aggregatedSource;\r\n            }\r\n            else\r\n            {\r\n                m_source = (*sourceReferencesToOpen)[0]->Open(progress);\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    bool Source::Add(IProgressCallback& progress)\r\n    {\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !m_isSourceToBeAdded || m_sourceReferences.size() != 1);\r\n\r\n        auto& sourceDetails = m_sourceReferences[0]->GetDetails();\r\n\r\n        // If the source type is empty, use a default.\r\n        // AddSourceForDetails will also check for empty, but we need the actual type before that for validation.\r\n        if (sourceDetails.Type.empty())\r\n        {\r\n            sourceDetails.Type = GetDefaultSourceType();\r\n        }\r\n\r\n        AICLI_LOG(Repo, Info, << \"Adding source: Name[\" << sourceDetails.Name << \"], Type[\" << sourceDetails.Type << \"], Arg[\" << sourceDetails.Arg << \"]\");\r\n\r\n        // Check all sources for the given name.\r\n        SourceList sourceList;\r\n\r\n        auto source = sourceList.GetSource(sourceDetails.Name);\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_SOURCE_NAME_ALREADY_EXISTS, source != nullptr && source->Origin != SourceOrigin::Metadata && !source->IsTombstone);\r\n\r\n        // Check sources allowed by group policy\r\n        auto blockingPolicy = GetPolicyBlockingUserSource(sourceDetails.Name, sourceDetails.Type, sourceDetails.Arg, false);\r\n        if (blockingPolicy != TogglePolicy::Policy::None)\r\n        {\r\n            throw GroupPolicyException(blockingPolicy);\r\n        }\r\n\r\n        sourceDetails.LastUpdateTime = Utility::ConvertUnixEpochToSystemClock(0);\r\n\r\n        // Allow the origin to stay as Default if the incoming details match a well known value\r\n        if (!(sourceDetails.Origin == SourceOrigin::Default && CheckForWellKnownSourceMatch(sourceDetails.Name, sourceDetails.Arg, sourceDetails.Type)))\r\n        {\r\n            sourceDetails.Origin = SourceOrigin::User;\r\n        }\r\n\r\n        bool result = AddSourceFromDetails(sourceDetails, progress).UpdateChecked;\r\n        if (result)\r\n        {\r\n            sourceList.AddSource(sourceDetails);\r\n            SaveAcceptedSourceAgreements();\r\n            m_isSourceToBeAdded = false;\r\n            AICLI_LOG(Repo, Info, << \"Source created with extra data: \" << sourceDetails.Data);\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<SourceDetails> Source::Update(IProgressCallback& progress)\r\n    {\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), m_isSourceToBeAdded || m_source || m_sourceReferences.empty());\r\n\r\n        SourceList sourceList;\r\n        std::vector<SourceDetails> result;\r\n\r\n        for (auto& sourceReference : m_sourceReferences)\r\n        {\r\n            THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !ContainsAvailablePackagesInternal(sourceReference->GetDetails().Origin));\r\n\r\n            auto& details = sourceReference->GetDetails();\r\n            AICLI_LOG(Repo, Info, << \"Named source to be updated, found: \" << details.Name);\r\n\r\n            try\r\n            {\r\n                // TODO: Consider adding a context callback to indicate we are doing the same action\r\n                // to avoid the progress bar fill up multiple times.\r\n                AddOrUpdateResult updateResult = UpdateSourceFromDetails(details, progress);\r\n\r\n                if (updateResult.MetadataWritten)\r\n                {\r\n                    auto detailsInternal = sourceList.GetSource(details.Name);\r\n                    detailsInternal->CopyMetadataFieldsFrom(details);\r\n                    sourceList.SaveMetadata(*detailsInternal);\r\n                }\r\n\r\n                if (!updateResult.UpdateChecked)\r\n                {\r\n                    AICLI_LOG(Repo, Error, << \"Failed to update source: \" << details.Name);\r\n                    result.emplace_back(details);\r\n                }\r\n            }\r\n            catch (...)\r\n            {\r\n                LOG_CAUGHT_EXCEPTION();\r\n                AICLI_LOG(Repo, Error, << \"Failed to update source: \" << details.Name);\r\n                result.emplace_back(details);\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    bool Source::Remove(IProgressCallback& progress)\r\n    {\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), m_isSourceToBeAdded || m_sourceReferences.size() != 1 || m_source);\r\n\r\n        const auto& details = m_sourceReferences[0]->GetDetails();\r\n        AICLI_LOG(Repo, Info, << \"Named source to be removed, found: \" << details.Name << \" [\" << ToString(details.Origin) << ']');\r\n\r\n        EnsureSourceIsRemovable(details);\r\n\r\n        bool result = RemoveSourceFromDetails(details, progress);\r\n        if (result)\r\n        {\r\n            SourceList sourceList;\r\n            sourceList.RemoveSource(details);\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    void Source::Edit(const SourceEdit& edits)\r\n    {\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), m_isSourceToBeAdded || m_sourceReferences.size() != 1 || m_source);\r\n\r\n        auto& details = m_sourceReferences[0]->GetDetails();\r\n        AICLI_LOG(Repo, Info, << \"Named source to be edited, found: \" << details.Name << \" [\" << ToString(details.Origin) << ']');\r\n\r\n        // This is intentionally the same policy checks as Remove. If the source cannot be removed then it cannot be edited.\r\n        EnsureSourceIsRemovable(details);\r\n\r\n        if (RequiresChanges(edits))\r\n        {\r\n            if (edits.Explicit.has_value())\r\n            {\r\n                details.Explicit = edits.Explicit.value();\r\n            }\r\n\r\n            if (edits.Priority.has_value())\r\n            {\r\n                details.Priority = edits.Priority.value();\r\n            }\r\n\r\n            // Apply the edits and update source list.\r\n            SourceList sourceList;\r\n            sourceList.EditSource(details);\r\n        }\r\n    }\r\n\r\n    bool Source::RequiresChanges(const SourceEdit& edits)\r\n    {\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), m_sourceReferences.size() != 1);\r\n\r\n        const auto& details = m_sourceReferences[0]->GetDetails();\r\n\r\n        bool isChanged = false;\r\n\r\n        if (edits.Explicit.has_value() && edits.Explicit.value() != details.Explicit)\r\n        {\r\n            isChanged = true;\r\n        }\r\n\r\n        if (edits.Priority.has_value() && edits.Priority.value() != details.Priority)\r\n        {\r\n            isChanged = true;\r\n        }\r\n\r\n        return isChanged;\r\n    }\r\n\r\n    PackageTrackingCatalog Source::GetTrackingCatalog() const\r\n    {\r\n        // With C++20, consider removing the shared_ptr here and making the one inside PackageTrackingCatalog atomic.\r\n        std::shared_ptr<PackageTrackingCatalog> currentTrackingCatalog = std::atomic_load(&m_trackingCatalog);\r\n        if (!currentTrackingCatalog)\r\n        {\r\n            std::shared_ptr<PackageTrackingCatalog> newTrackingCatalog = std::make_shared<PackageTrackingCatalog>(PackageTrackingCatalog::CreateForSource(*this));\r\n\r\n            if (std::atomic_compare_exchange_strong(&m_trackingCatalog, &currentTrackingCatalog, newTrackingCatalog))\r\n            {\r\n                currentTrackingCatalog = newTrackingCatalog;\r\n            }\r\n        }\r\n\r\n        return *currentTrackingCatalog;\r\n    }\r\n\r\n    std::vector<SourceDetails> Source::GetCurrentSources()\r\n    {\r\n        SourceList sourceList;\r\n\r\n        std::vector<SourceDetails> result;\r\n        for (auto&& source : sourceList.GetCurrentSourceRefs())\r\n        {\r\n            result.emplace_back(std::move(source));\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    bool Source::DropSource(std::string_view name)\r\n    {\r\n        if (name.empty())\r\n        {\r\n            SourceList::RemoveSettingsStreams();\r\n            return true;\r\n        }\r\n        else\r\n        {\r\n            SourceList sourceList;\r\n\r\n            auto source = sourceList.GetCurrentSource(name);\r\n            if (!source)\r\n            {\r\n                AICLI_LOG(Repo, Info, << \"Named source to be dropped, but not found: \" << name);\r\n                return false;\r\n            }\r\n            else\r\n            {\r\n                AICLI_LOG(Repo, Info, << \"Named source to be dropped, found: \" << source->Name);\r\n\r\n                EnsureSourceIsRemovable(*source);\r\n                sourceList.RemoveSource(*source);\r\n\r\n                return true;\r\n            }\r\n        }\r\n    }\r\n\r\n    std::string_view Source::GetDefaultSourceType()\r\n    {\r\n        return ISourceFactory::GetForType(\"\")->TypeName();\r\n    }\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n    void TestHook_SetSourceFactoryOverride(const std::string& type, std::function<std::unique_ptr<ISourceFactory>()>&& factory)\r\n    {\r\n        s_Sources_TestHook_SourceFactories[type] = std::move(factory);\r\n    }\r\n\r\n    void TestHook_ClearSourceFactoryOverrides()\r\n    {\r\n        s_Sources_TestHook_SourceFactories.clear();\r\n    }\r\n#endif\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/RestClient.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"RestClient.h\"\r\n#include \"RestInformationCache.h\"\r\n#include \"Rest/Schema/1_0/Interface.h\"\r\n#include \"Rest/Schema/1_1/Interface.h\"\r\n#include \"Rest/Schema/1_4/Interface.h\"\r\n#include \"Rest/Schema/1_5/Interface.h\"\r\n#include \"Rest/Schema/1_6/Interface.h\"\r\n#include \"Rest/Schema/1_7/Interface.h\"\r\n#include \"Rest/Schema/1_9/Interface.h\"\r\n#include \"Rest/Schema/1_10/Interface.h\"\r\n#include \"Rest/Schema/1_12/Interface.h\"\r\n#include \"Rest/Schema/InformationResponseDeserializer.h\"\r\n#include \"Rest/Schema/CommonRestConstants.h\"\r\n#include <AppInstallerDownloader.h>\r\n#include <winget/HttpClientHelper.h>\r\n#include <winget/Rest.h>\r\n#include <winget/JsonUtil.h>\r\n\r\nusing namespace AppInstaller::Repository::Rest::Schema;\r\nusing namespace AppInstaller::Repository::Rest::Schema::V1_0;\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::Http;\r\n\r\nnamespace AppInstaller::Repository::Rest\r\n{\r\n    // Supported versions\r\n    std::set<Version> WingetSupportedContracts = {\r\n        Version_1_0_0,\r\n        Version_1_1_0,\r\n        Version_1_4_0,\r\n        Version_1_5_0,\r\n        Version_1_6_0,\r\n        Version_1_7_0,\r\n        Version_1_9_0,\r\n        Version_1_10_0,\r\n        Version_1_12_0,\r\n    };\r\n\r\n    constexpr std::string_view WindowsPackageManagerHeader = \"Windows-Package-Manager\"sv;\r\n    constexpr size_t WindowsPackageManagerHeaderMaxLength = 1024;\r\n\r\n    namespace\r\n    {\r\n        HttpClientHelper::HttpRequestHeaders GetHeaders(const std::optional<std::string>& customHeader, std::string_view caller)\r\n        {\r\n            HttpClientHelper::HttpRequestHeaders headers;\r\n\r\n            if (customHeader)\r\n            {\r\n                AICLI_LOG(Repo, Verbose, << \"Custom header found: \" << customHeader.value());\r\n                THROW_HR_IF(APPINSTALLER_CLI_ERROR_CUSTOMHEADER_EXCEEDS_MAXLENGTH, customHeader.value().size() > WindowsPackageManagerHeaderMaxLength);\r\n                headers.emplace(JSON::GetUtilityString(WindowsPackageManagerHeader), JSON::GetUtilityString(customHeader.value()));\r\n            }\r\n\r\n            if (!caller.empty())\r\n            {\r\n                AICLI_LOG(Repo, Verbose, << \"User agent caller found: \" << caller);\r\n                std::wstring userAgentWide = JSON::GetUtilityString(Runtime::GetUserAgent(caller));\r\n                try\r\n                {\r\n                    // Replace user profile if the caller binary is under user profile.\r\n                    userAgentWide = Utility::ReplaceWhileCopying(userAgentWide, Runtime::GetPathTo(Runtime::PathName::UserProfile).wstring(), L\"%USERPROFILE%\");\r\n                }\r\n                CATCH_LOG();\r\n                headers.emplace(web::http::header_names::user_agent, userAgentWide);\r\n            }\r\n\r\n            return headers;\r\n        }\r\n    }\r\n\r\n    RestClient::RestClient(std::unique_ptr<Schema::IRestClient> supportedInterface, std::string sourceIdentifier)\r\n        : m_interface(std::move(supportedInterface)), m_sourceIdentifier(std::move(sourceIdentifier))\r\n    {\r\n    }\r\n\r\n    std::optional<Manifest::Manifest> RestClient::GetManifestByVersion(const std::string& packageId, const std::string& version, const std::string& channel) const\r\n    {\r\n        return m_interface->GetManifestByVersion(packageId, version, channel);\r\n    }\r\n\r\n    IRestClient::SearchResult RestClient::Search(const SearchRequest& request) const\r\n    {\r\n        return m_interface->Search(request);\r\n    }\r\n\r\n    std::string RestClient::GetSourceIdentifier() const\r\n    {\r\n        return m_sourceIdentifier;\r\n    }\r\n\r\n    IRestClient::Information RestClient::GetSourceInformation() const\r\n    {\r\n        return m_interface->GetSourceInformation();\r\n    }\r\n\r\n    std::optional<Version> RestClient::GetLatestCommonVersion(\r\n        const std::vector<std::string>& serverSupportedVersions,\r\n        const std::set<Version>& wingetSupportedVersions)\r\n    {\r\n        std::set<Version> commonVersions;\r\n        for (auto& version : serverSupportedVersions)\r\n        {\r\n            Version versionInfo(version);\r\n            auto itr = std::find_if(wingetSupportedVersions.begin(), wingetSupportedVersions.end(),\r\n                [&](const Version& v)\r\n                {\r\n                    // Only check major and minor version match if applicable\r\n                    if (v.GetParts().size() >= 2)\r\n                    {\r\n                        return versionInfo.GetParts().size() >= 2 &&\r\n                            versionInfo.GetParts().at(0) == v.GetParts().at(0) &&\r\n                            versionInfo.GetParts().at(1) == v.GetParts().at(1);\r\n                    }\r\n                    else\r\n                    {\r\n                        return versionInfo == v;\r\n                    }\r\n                });\r\n            if (itr != wingetSupportedVersions.end())\r\n            {\r\n                commonVersions.insert(*itr);\r\n            }\r\n        }\r\n\r\n        if (commonVersions.empty())\r\n        {\r\n            return {};\r\n        }\r\n\r\n        return *commonVersions.rbegin();\r\n    }\r\n\r\n    Schema::IRestClient::Information RestClient::GetInformation(const std::string& restApi, const std::optional<std::string>& customHeader, std::string_view caller, const HttpClientHelper& helper)\r\n    {\r\n        utility::string_t restEndpoint = AppInstaller::Rest::GetRestAPIBaseUri(restApi);\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_URL, !AppInstaller::Rest::IsValidUri(restEndpoint));\r\n        utility::string_t endpoint = AppInstaller::Rest::AppendPathToUri(restEndpoint, JSON::GetUtilityString(InformationGetEndpoint));\r\n\r\n        // Check the cache for a valid information entry\r\n        RestInformationCache informationCache;\r\n        std::optional<Schema::IRestClient::Information> cachedInformation = informationCache.Get(endpoint, customHeader, caller);\r\n\r\n        if (cachedInformation)\r\n        {\r\n            return std::move(cachedInformation).value();\r\n        }\r\n\r\n        // Not in cache, make REST call to retrieve it\r\n        auto headers = GetHeaders(customHeader, caller);\r\n        CacheControlPolicy cacheControl;\r\n\r\n        std::optional<web::json::value> response = helper.HandleGet(\r\n            endpoint,\r\n            headers,\r\n            {},\r\n            [&](const web::http::http_response& httpResponse)\r\n            {\r\n                cacheControl = CacheControlPolicy{ httpResponse.headers().cache_control() };\r\n                return Http::HttpClientHelper::HttpResponseHandlerResult{ std::nullopt, true };\r\n            });\r\n\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE, !response);\r\n\r\n        InformationResponseDeserializer responseDeserializer;\r\n        auto result = responseDeserializer.Deserialize(response.value());\r\n\r\n        // Cache the information value as requested\r\n        informationCache.Cache(endpoint, customHeader, caller, cacheControl, std::move(response).value());\r\n\r\n        return result;\r\n    }\r\n\r\n    std::unique_ptr<Schema::IRestClient> RestClient::GetSupportedInterface(\r\n        const std::string& api,\r\n        const HttpClientHelper::HttpRequestHeaders& additionalHeaders,\r\n        const IRestClient::Information& information,\r\n        const Authentication::AuthenticationArguments& authArgs,\r\n        const Version& version,\r\n        const HttpClientHelper& helper)\r\n    {\r\n        if (version == Version_1_0_0)\r\n        {\r\n            return std::make_unique<Schema::V1_0::Interface>(api, helper);\r\n        }\r\n        else if (version == Version_1_1_0)\r\n        {\r\n            return std::make_unique<Schema::V1_1::Interface>(api, helper, information, additionalHeaders);\r\n        }\r\n        else if (version == Version_1_4_0)\r\n        {\r\n            return std::make_unique<Schema::V1_4::Interface>(api, helper, information, additionalHeaders);\r\n        }\r\n        else if (version == Version_1_5_0)\r\n        {\r\n            return std::make_unique<Schema::V1_5::Interface>(api, helper, information, additionalHeaders);\r\n        }\r\n        else if (version == Version_1_6_0)\r\n        {\r\n            return std::make_unique<Schema::V1_6::Interface>(api, helper, information, additionalHeaders);\r\n        }\r\n        else if (version == Version_1_7_0)\r\n        {\r\n            return std::make_unique<Schema::V1_7::Interface>(api, helper, information, additionalHeaders, authArgs);\r\n        }\r\n        else if (version == Version_1_9_0)\r\n        {\r\n            return std::make_unique<Schema::V1_9::Interface>(api, helper, information, additionalHeaders, authArgs);\r\n        }\r\n        else if (version == Version_1_10_0)\r\n        {\r\n            return std::make_unique<Schema::V1_10::Interface>(api, helper, information, additionalHeaders, authArgs);\r\n        }\r\n        else if (version == Version_1_12_0)\r\n        {\r\n            return std::make_unique<Schema::V1_12::Interface>(api, helper, information, additionalHeaders, authArgs);\r\n        }\r\n\r\n        THROW_HR(APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_VERSION);\r\n    }\r\n\r\n    RestClient RestClient::Create(\r\n        const std::string& restApi,\r\n        const std::optional<std::string>& customHeader,\r\n        std::string_view caller,\r\n        const HttpClientHelper& helper,\r\n        const Schema::IRestClient::Information& information,\r\n        const Authentication::AuthenticationArguments& authArgs)\r\n    {\r\n        utility::string_t restEndpoint = AppInstaller::Rest::GetRestAPIBaseUri(restApi);\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_URL, !AppInstaller::Rest::IsValidUri(restEndpoint));\r\n\r\n        auto headers = GetHeaders(customHeader, caller);\r\n\r\n        std::optional<Version> latestCommonVersion = GetLatestCommonVersion(information.ServerSupportedVersions, WingetSupportedContracts);\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE, !latestCommonVersion);\r\n\r\n        std::unique_ptr<Schema::IRestClient> supportedInterface = GetSupportedInterface(utility::conversions::to_utf8string(restEndpoint), headers, information, authArgs, latestCommonVersion.value(), helper);\r\n        return RestClient{ std::move(supportedInterface), information.SourceIdentifier };\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/RestClient.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <set>\r\n#include \"Rest/Schema/IRestClient.h\"\r\n#include \"ISource.h\"\r\n#include <winget/HttpClientHelper.h>\r\n\r\nnamespace AppInstaller::Repository::Rest\r\n{\r\n    struct RestClient\r\n    {\r\n        RestClient(const RestClient&) = delete;\r\n        RestClient& operator=(const RestClient&) = delete;\r\n\r\n        RestClient(RestClient&&) = default;\r\n        RestClient& operator=(RestClient&&) = default;\r\n\r\n        // Performs a search based on the given criteria.\r\n        Schema::IRestClient::SearchResult Search(const SearchRequest& request) const;\r\n\r\n        std::optional<Manifest::Manifest> GetManifestByVersion(const std::string& packageId, const std::string& version, const std::string& channel) const;\r\n\r\n        std::string GetSourceIdentifier() const;\r\n\r\n        Schema::IRestClient::Information GetSourceInformation() const;\r\n\r\n        static std::optional<AppInstaller::Utility::Version> GetLatestCommonVersion(const std::vector<std::string>& serverSupportedVersions, const std::set<AppInstaller::Utility::Version>& wingetSupportedVersions);\r\n\r\n        // Responsible for getting the source information contracts with minimal validation. Does not try to create a rest interface out of it.\r\n        static Schema::IRestClient::Information GetInformation(const std::string& restApi, const std::optional<std::string>& customHeader, std::string_view caller, const Http::HttpClientHelper& helper);\r\n\r\n        static std::unique_ptr<Schema::IRestClient> GetSupportedInterface(\r\n            const std::string& restApi,\r\n            const Http::HttpClientHelper::HttpRequestHeaders& additionalHeaders,\r\n            const Schema::IRestClient::Information& information,\r\n            const Authentication::AuthenticationArguments& authArgs,\r\n            const AppInstaller::Utility::Version& version,\r\n            const Http::HttpClientHelper& helper);\r\n\r\n        // Creates the rest client. Full validation performed (just as opening the source)\r\n        static RestClient Create(\r\n            const std::string& restApi,\r\n            const std::optional<std::string>& customHeader,\r\n            std::string_view caller,\r\n            const Http::HttpClientHelper& helper,\r\n            const Schema::IRestClient::Information& information,\r\n            const Authentication::AuthenticationArguments& authArgs = {});\r\n    private:\r\n        RestClient(std::unique_ptr<Schema::IRestClient> supportedInterface, std::string sourceIdentifier);\r\n\r\n        std::unique_ptr<Schema::IRestClient> m_interface;\r\n        std::string m_sourceIdentifier;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/RestInformationCache.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"RestInformationCache.h\"\r\n#include \"Rest/Schema/InformationResponseDeserializer.h\"\r\n#include <winget/JsonUtil.h>\r\n\r\nnamespace AppInstaller::Repository::Rest\r\n{\r\n    namespace\r\n    {\r\n        constexpr std::wstring_view s_EndpointName = L\"endpoint\"sv;\r\n        constexpr std::wstring_view s_HashName = L\"hash\"sv;\r\n        constexpr std::wstring_view s_ExpirationName = L\"expiration\"sv;\r\n        constexpr std::wstring_view s_DataName = L\"data\"sv;\r\n\r\n        // Calculates the hash of values that might change per-call.\r\n        Utility::SHA256::HashBuffer GetHash(const std::optional<std::string>& customHeader, std::string_view caller)\r\n        {\r\n            std::stringstream stream;\r\n            if (customHeader)\r\n            {\r\n                stream << customHeader.value();\r\n            }\r\n            stream << '|' << caller;\r\n\r\n            return Utility::SHA256::ComputeHash(stream);\r\n        }\r\n\r\n        uint64_t CalculateExpiration(std::chrono::seconds duration)\r\n        {\r\n            // If no expiration information is provided, use 1 minute\r\n            if (!duration.count())\r\n            {\r\n                duration = 60s;\r\n            }\r\n\r\n            return Utility::ConvertSystemClockToUnixEpoch(std::chrono::system_clock::now() + duration);\r\n        }\r\n    }\r\n\r\n    std::optional<Schema::IRestClient::Information> RestInformationCache::Get(const std::wstring& endpoint, const std::optional<std::string>& customHeader, std::string_view caller)\r\n#ifdef AICLI_DISABLE_TEST_HOOKS\r\n        try\r\n#endif\r\n    {\r\n        LoadCacheView();\r\n\r\n        Utility::SHA256::HashBuffer hashValue = GetHash(customHeader, caller);\r\n        CacheItem* item = FindCacheItem(endpoint, hashValue);\r\n\r\n        // If we don't find a private match, see if there is a public one.\r\n        if (!item)\r\n        {\r\n            item = FindCacheItem(endpoint, {});\r\n        }\r\n\r\n        if (!item)\r\n        {\r\n            return std::nullopt;\r\n        }\r\n\r\n        Schema::InformationResponseDeserializer responseDeserializer;\r\n        return responseDeserializer.Deserialize(item->Data);\r\n    }\r\n#ifdef AICLI_DISABLE_TEST_HOOKS\r\n    catch (...)\r\n    {\r\n        LOG_CAUGHT_EXCEPTION_MSG(\"RestInformationCache::Get exception\");\r\n        return std::nullopt;\r\n    }\r\n#endif\r\n\r\n    void RestInformationCache::Cache(const std::wstring& endpoint, const std::optional<std::string>& customHeader, std::string_view caller, const Utility::CacheControlPolicy& cacheControl, web::json::value response)\r\n#ifdef AICLI_DISABLE_TEST_HOOKS\r\n        try\r\n#endif\r\n    {\r\n        // If requested, do not cache this response.\r\n        // Since this data is small, treat no-cache as no-store.\r\n        if (cacheControl.NoStore || cacheControl.NoCache)\r\n        {\r\n            return;\r\n        }\r\n\r\n        // If not public, we use the header values to differentiate the cache items.\r\n        Utility::SHA256::HashBuffer hashValue;\r\n        if (!cacheControl.Public)\r\n        {\r\n            hashValue = GetHash(customHeader, caller);\r\n        }\r\n\r\n        uint64_t expirationEpoch = CalculateExpiration(std::chrono::seconds{ cacheControl.MaxAge });\r\n\r\n        // Due to the exchange semantics on the setting stream, we may have to retry storing the value.\r\n        for (int i = 0; i < 10; ++i)\r\n        {\r\n            CacheItem* item = FindCacheItem(endpoint, hashValue);\r\n\r\n            if (!item)\r\n            {\r\n                item = &m_cacheView.emplace_back();\r\n\r\n                item->Endpoint = endpoint;\r\n                item->Hash = hashValue;\r\n            }\r\n\r\n            item->UnixEpochExpiration = expirationEpoch;\r\n            item->Data = std::move(response);\r\n\r\n            if (StoreCacheView())\r\n            {\r\n                AICLI_LOG(Repo, Verbose, << \"RestInformationCache stored information for: \" << Utility::ConvertToUTF8(endpoint));\r\n                return;\r\n            }\r\n            else\r\n            {\r\n                // Extract the response back from the item for the next iteration\r\n                response = std::move(item->Data);\r\n\r\n                // Failed to store due to the cache changing, reload and try again.\r\n                LoadCacheView();\r\n            }\r\n        }\r\n\r\n        AICLI_LOG(Repo, Warning, << \"RestInformationCache failed to store information cache after 10 attempts.\");\r\n    }\r\n#ifdef AICLI_DISABLE_TEST_HOOKS\r\n    CATCH_LOG();\r\n#endif\r\n\r\n    void RestInformationCache::LoadCacheView()\r\n    {\r\n        using namespace web::json;\r\n\r\n        std::unique_ptr<std::istream> stream = m_settingsStream.Get();\r\n        m_cacheView.clear();\r\n\r\n        if (!stream)\r\n        {\r\n            return;\r\n        }\r\n\r\n        value cacheValue = value::parse(*stream);\r\n\r\n        if (!cacheValue.is_array())\r\n        {\r\n            AICLI_LOG(Repo, Warning, << \"RestInformationCache value was not an array.\");\r\n            return;\r\n        }\r\n\r\n        array& cacheArray = cacheValue.as_array();\r\n\r\n        for (const value& cacheItemValue : cacheArray)\r\n        {\r\n            if (!cacheItemValue.is_object())\r\n            {\r\n                AICLI_LOG(Repo, Warning, << \"RestInformationCache cache item was not an object.\");\r\n                continue;\r\n            }\r\n\r\n            std::optional<uint64_t> expiration = JSON::GetRawUInt64ValueFromJsonNode(cacheItemValue, std::wstring{ s_ExpirationName });\r\n            if (!expiration)\r\n            {\r\n                AICLI_LOG(Repo, Warning, << \"RestInformationCache cache item missing expiration.\");\r\n                continue;\r\n            }\r\n\r\n            if (std::chrono::system_clock::now() > Utility::ConvertUnixEpochToSystemClock(expiration.value()))\r\n            {\r\n                AICLI_LOG(Repo, Verbose, << \"RestInformationCache cache item has expired.\");\r\n                continue;\r\n            }\r\n\r\n            std::optional<std::wstring> endpoint = JSON::GetWideStringValueFromJsonNode(cacheItemValue, std::wstring{ s_EndpointName });\r\n            if (!JSON::IsValidNonEmptyStringValue(endpoint))\r\n            {\r\n                AICLI_LOG(Repo, Warning, << \"RestInformationCache cache item missing endpoint.\");\r\n                continue;\r\n            }\r\n\r\n            CacheItem cacheItem;\r\n            cacheItem.Endpoint = endpoint.value();\r\n            cacheItem.UnixEpochExpiration = expiration.value();\r\n\r\n            std::optional<std::wstring> hash = JSON::GetWideStringValueFromJsonNode(cacheItemValue, std::wstring{ s_HashName });\r\n            if (JSON::IsValidNonEmptyStringValue(hash))\r\n            {\r\n                cacheItem.Hash = Utility::SHA256::ConvertToBytes(hash.value());\r\n            }\r\n\r\n            auto dataValue = JSON::GetJsonValueFromNode(cacheItemValue, std::wstring{ s_DataName });\r\n            if (!dataValue)\r\n            {\r\n                AICLI_LOG(Repo, Warning, << \"RestInformationCache cache item missing data.\");\r\n                continue;\r\n            }\r\n\r\n            cacheItem.Data = dataValue.value().get();\r\n            if (cacheItem.Data.is_null())\r\n            {\r\n                AICLI_LOG(Repo, Warning, << \"RestInformationCache cache item data value null.\");\r\n                continue;\r\n            }\r\n\r\n            m_cacheView.emplace_back(std::move(cacheItem));\r\n        }\r\n    }\r\n\r\n    RestInformationCache::CacheItem* RestInformationCache::FindCacheItem(const std::wstring& endpoint, const Utility::SHA256::HashBuffer& hash)\r\n    {\r\n        for (CacheItem& item : m_cacheView)\r\n        {\r\n            if (item.Endpoint == endpoint &&\r\n                Utility::SHA256::AreEqual(item.Hash, hash))\r\n            {\r\n                return &item;\r\n            }\r\n        }\r\n\r\n        return nullptr;\r\n    }\r\n\r\n    [[nodiscard]] bool RestInformationCache::StoreCacheView()\r\n    {\r\n        using namespace web::json;\r\n\r\n        value cacheValue = value::array();\r\n        array& cacheArray = cacheValue.as_array();\r\n\r\n        for (const CacheItem& item : m_cacheView)\r\n        {\r\n            value cacheItemValue = value::object();\r\n            object& cacheItemObject = cacheItemValue.as_object();\r\n\r\n            cacheItemObject[std::wstring{ s_EndpointName }] = value::value(item.Endpoint);\r\n            cacheItemObject[std::wstring{ s_HashName }] = value::value(Utility::ConvertToUTF16(Utility::ConvertToHexString(item.Hash)));\r\n            cacheItemObject[std::wstring{ s_ExpirationName }] = value::value(item.UnixEpochExpiration);\r\n            cacheItemObject[std::wstring{ s_DataName }] = item.Data;\r\n\r\n            cacheArray[cacheArray.size()] = std::move(cacheItemValue);\r\n        }\r\n\r\n        std::stringstream stream;\r\n        cacheValue.serialize(stream);\r\n\r\n        return m_settingsStream.Set(std::move(stream).str());\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/RestInformationCache.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Rest/Schema/IRestClient.h\"\r\n#include <AppInstallerDownloader.h>\r\n#include <AppInstallerSHA256.h>\r\n#include <winget/Settings.h>\r\n#include <cpprest/json.h>\r\n#include <optional>\r\n#include <string>\r\n#include <string_view>\r\n\r\nnamespace AppInstaller::Repository::Rest\r\n{\r\n    // Provides access to cached responses to the /information request.\r\n    struct RestInformationCache\r\n    {\r\n        // Attempts to get a cached information response for the provided inputs.\r\n        std::optional<Schema::IRestClient::Information> Get(const std::wstring& endpoint, const std::optional<std::string>& customHeader, std::string_view caller);\r\n\r\n        // Stores the information response as appropriate.\r\n        void Cache(const std::wstring& endpoint, const std::optional<std::string>& customHeader, std::string_view caller, const Utility::CacheControlPolicy& cacheControl, web::json::value response);\r\n\r\n    private:\r\n        struct CacheItem\r\n        {\r\n            std::wstring Endpoint;\r\n            Utility::SHA256::HashBuffer Hash;\r\n            uint64_t UnixEpochExpiration = 0;\r\n            web::json::value Data;\r\n        };\r\n\r\n        // Reads from the cache, constructing our view of the items it contains.\r\n        // Discards any expired items while reading the cache.\r\n        void LoadCacheView();\r\n\r\n        // Finds the cache item for the given inputs, or nullptr if it is not found.\r\n        CacheItem* FindCacheItem(const std::wstring& endpoint, const Utility::SHA256::HashBuffer& hash);\r\n\r\n        // Attempts to store the current cache view back to the cache.\r\n        // Returns true if successful; false if the cache was updated since our last read and a retry is necessary.\r\n        [[nodiscard]] bool StoreCacheView();\r\n\r\n        Settings::Stream m_settingsStream{ Settings::Stream::RestInformationCache };\r\n        std::vector<CacheItem> m_cacheView;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/RestSource.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"RestSource.h\"\r\n#include \"MatchCriteriaResolver.h\"\r\n\r\nusing namespace AppInstaller::Utility;\r\n\r\nnamespace AppInstaller::Repository::Rest\r\n{\r\n    namespace\r\n    {\r\n        using namespace AppInstaller::Repository::Rest::Schema;\r\n\r\n        // The source reference used by package objects.\r\n        struct SourceReference\r\n        {\r\n            SourceReference(const std::shared_ptr<RestSource>& source) :\r\n                m_source(source) {}\r\n\r\n        protected:\r\n            std::shared_ptr<RestSource> GetReferenceSource() const\r\n            {\r\n                std::shared_ptr<RestSource> source = m_source.lock();\r\n                THROW_HR_IF(E_NOT_VALID_STATE, !source);\r\n                return source;\r\n            }\r\n\r\n        private:\r\n            std::weak_ptr<RestSource> m_source;\r\n        };\r\n\r\n        // The IPackage implementation for Available packages from RestSource.\r\n        struct RestPackage : public std::enable_shared_from_this<RestPackage>, public SourceReference, public IPackage, public ICompositePackage\r\n        {\r\n            static constexpr IPackageType PackageType = IPackageType::RestPackage;\r\n\r\n            RestPackage(const std::shared_ptr<RestSource>& source, IRestClient::Package&& package) :\r\n                SourceReference(source), m_package(std::move(package))\r\n            {\r\n                SortVersionsInternal();\r\n            }\r\n\r\n            // Inherited via IPackage\r\n            Utility::LocIndString GetProperty(PackageProperty property) const override\r\n            {\r\n                switch (property)\r\n                {\r\n                case PackageProperty::Id:\r\n                    return Utility::LocIndString{ m_package.PackageInformation.PackageIdentifier };\r\n                case PackageProperty::Name:\r\n                    return Utility::LocIndString{ m_package.PackageInformation.PackageName };\r\n                default:\r\n                    THROW_HR(E_UNEXPECTED);\r\n                }\r\n            }\r\n\r\n            std::vector<Utility::LocIndString> GetMultiProperty(PackageMultiProperty property) const override;\r\n\r\n            std::vector<PackageVersionKey> GetVersionKeys() const override\r\n            {\r\n                std::shared_ptr<const RestSource> source = GetReferenceSource();\r\n                std::scoped_lock versionsLock{ m_packageVersionsLock };\r\n\r\n                std::vector<PackageVersionKey> result;\r\n                for (const auto& versionInfo : m_package.Versions)\r\n                {\r\n                    result.emplace_back(\r\n                        source->GetIdentifier(), versionInfo.VersionAndChannel.GetVersion().ToString(), versionInfo.VersionAndChannel.GetChannel().ToString());\r\n                }\r\n\r\n                return result;\r\n            }\r\n\r\n            std::shared_ptr<IPackageVersion> GetLatestVersion() const override\r\n            {\r\n                std::scoped_lock versionsLock{ m_packageVersionsLock };\r\n                return GetLatestVersionInternal();\r\n            }\r\n\r\n            std::shared_ptr<IPackageVersion> GetVersion(const PackageVersionKey& versionKey) const override;\r\n\r\n            Source GetSource() const override\r\n            {\r\n                return Source{ GetReferenceSource() };\r\n            }\r\n\r\n            bool IsSame(const IPackage* other) const override\r\n            {\r\n                const RestPackage* otherPackage = PackageCast<const RestPackage*>(other);\r\n\r\n                if (otherPackage)\r\n                {\r\n                    return GetReferenceSource()->IsSame(otherPackage->GetReferenceSource().get()) &&\r\n                        Utility::CaseInsensitiveEquals(m_package.PackageInformation.PackageIdentifier, otherPackage->m_package.PackageInformation.PackageIdentifier);\r\n                }\r\n\r\n                return false;\r\n            }\r\n\r\n            const void* CastTo(IPackageType type) const override\r\n            {\r\n                if (type == PackageType)\r\n                {\r\n                    return this;\r\n                }\r\n\r\n                return nullptr;\r\n            }\r\n\r\n            // Inherited via ICompositePackage\r\n            std::shared_ptr<IPackage> GetInstalled() override\r\n            {\r\n                return {};\r\n            }\r\n\r\n            std::vector<std::shared_ptr<IPackage>> GetAvailable() override\r\n            {\r\n                return std::vector<std::shared_ptr<IPackage>>{ shared_from_this() };\r\n            }\r\n\r\n            // Helpers for PackageVersion interop\r\n            const IRestClient::PackageInfo& PackageInfo() const\r\n            {\r\n                return m_package.PackageInformation;\r\n            }\r\n\r\n            // This function is designed to handle the case where the only version that is returned by the\r\n            // initial search is Unknown. In that case, we perform a search intended to trigger the optimized\r\n            // path and directly get all manifests.\r\n            bool HandleSingleUnknownVersion(IRestClient::VersionInfo& versionInfo)\r\n            {\r\n                // If the calling version is unknown then we want to update it if we already\r\n                // have the results in the package.\r\n                if (versionInfo.VersionAndChannel.GetVersion().IsUnknown() && !versionInfo.Manifest)\r\n                {\r\n                    std::scoped_lock versionsLock{ m_packageVersionsLock };\r\n                    if (m_package.Versions.size() == 1 && m_package.Versions[0].VersionAndChannel.GetVersion().IsUnknown() && !m_package.Versions[0].Manifest)\r\n                    {\r\n                        SearchRequest request;\r\n                        request.Filters.emplace_back(PackageMatchField::Id, MatchType::CaseInsensitive, m_package.PackageInformation.PackageIdentifier);\r\n\r\n                        IRestClient::SearchResult result = GetReferenceSource()->GetRestClient().Search(request);\r\n\r\n                        if (result.Matches.size() == 1)\r\n                        {\r\n                            m_package.Versions = std::move(result.Matches[0].Versions);\r\n                            SortVersionsInternal();\r\n                        }\r\n                        else\r\n                        {\r\n                            // Unexpected, but just leave things as they are\r\n                            AICLI_LOG(Repo, Warning, << \"Found \" << result.Matches.size() << \" matches for optimized search of \" << m_package.PackageInformation.PackageIdentifier);\r\n                        }\r\n                    }\r\n\r\n                    if (!m_package.Versions.empty())\r\n                    {\r\n                        // The results are now sorted; either take the last one if it is unknown\r\n                        // or the first one if it is not (aka latest).\r\n                        if (m_package.Versions.back().VersionAndChannel.GetVersion().IsUnknown())\r\n                        {\r\n                            versionInfo = m_package.Versions.back();\r\n                        }\r\n                        else\r\n                        {\r\n                            versionInfo = m_package.Versions.front();\r\n                        }\r\n                    }\r\n\r\n                    return true;\r\n                }\r\n\r\n                return false;\r\n            }\r\n\r\n        private:\r\n            std::shared_ptr<RestPackage> NonConstSharedFromThis() const\r\n            {\r\n                return const_cast<RestPackage*>(this)->shared_from_this();\r\n            }\r\n\r\n            // Must hold m_packageVersionsLock while calling this\r\n            std::shared_ptr<IPackageVersion> GetLatestVersionInternal() const;\r\n\r\n            // Must hold m_packageVersionsLock while calling this\r\n            void SortVersionsInternal()\r\n            {\r\n                std::sort(m_package.Versions.begin(), m_package.Versions.end(),\r\n                    [](const IRestClient::VersionInfo& a, const IRestClient::VersionInfo& b)\r\n                    {\r\n                        return a.VersionAndChannel < b.VersionAndChannel;\r\n                    });\r\n            }\r\n\r\n            IRestClient::Package m_package;\r\n            // Protects access to m_package.Versions\r\n            mutable std::mutex m_packageVersionsLock;\r\n        };\r\n\r\n        void GetMultiPropertyValues(\r\n            const RestPackage* package,\r\n            const IRestClient::VersionInfo& versionInfo,\r\n            PackageVersionMultiProperty property,\r\n            std::vector<Utility::LocIndString>& result,\r\n            void (*Action)(std::vector<Utility::LocIndString>&, Utility::LocIndString&&))\r\n        {\r\n            switch (property)\r\n            {\r\n            case PackageVersionMultiProperty::PackageFamilyName:\r\n                for (const std::string& pfn : versionInfo.PackageFamilyNames)\r\n                {\r\n                    Action(result, Utility::LocIndString{ pfn });\r\n                }\r\n                break;\r\n            case PackageVersionMultiProperty::ProductCode:\r\n                for (const std::string& productCode : versionInfo.ProductCodes)\r\n                {\r\n                    Action(result, Utility::LocIndString{ productCode });\r\n                }\r\n                break;\r\n            case PackageVersionMultiProperty::UpgradeCode:\r\n                for (const std::string& upgradeCode : versionInfo.UpgradeCodes)\r\n                {\r\n                    Action(result, Utility::LocIndString{ upgradeCode });\r\n                }\r\n                break;\r\n            case PackageVersionMultiProperty::Name:\r\n                if (versionInfo.Manifest)\r\n                {\r\n                    for (auto&& name : versionInfo.Manifest->GetPackageNames())\r\n                    {\r\n                        Action(result, Utility::LocIndString{ std::move(name) });\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    Action(result, Utility::LocIndString{ package->PackageInfo().PackageName });\r\n                }\r\n                break;\r\n            case PackageVersionMultiProperty::Publisher:\r\n                if (versionInfo.Manifest)\r\n                {\r\n                    for (auto&& publisher : versionInfo.Manifest->GetPublishers())\r\n                    {\r\n                        Action(result, Utility::LocIndString{ std::move(publisher) });\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    Action(result, Utility::LocIndString{ package->PackageInfo().Publisher });\r\n                }\r\n                break;\r\n            case PackageVersionMultiProperty::Locale:\r\n                if (versionInfo.Manifest)\r\n                {\r\n                    Action(result, Utility::LocIndString{ versionInfo.Manifest->DefaultLocalization.Locale });\r\n                    for (const auto& loc : versionInfo.Manifest->Localizations)\r\n                    {\r\n                        Action(result, Utility::LocIndString{ loc.Locale });\r\n                    }\r\n                }\r\n                break;\r\n            }\r\n        }\r\n\r\n        std::vector<Utility::LocIndString> RestPackage::GetMultiProperty(PackageMultiProperty property) const\r\n        {\r\n            std::scoped_lock versionsLock{ m_packageVersionsLock };\r\n            std::vector<Utility::LocIndString> result;\r\n            PackageVersionMultiProperty mappedProperty = PackageMultiPropertyToPackageVersionMultiProperty(property);\r\n\r\n            for (const auto& versionInfo : m_package.Versions)\r\n            {\r\n                GetMultiPropertyValues(\r\n                    this,\r\n                    versionInfo,\r\n                    mappedProperty,\r\n                    result,\r\n                    [](std::vector<Utility::LocIndString>& result, Utility::LocIndString&& string)\r\n                    {\r\n                        auto itr = std::lower_bound(result.begin(), result.end(), string);\r\n\r\n                        if (itr == result.end() || *itr != string)\r\n                        {\r\n                            result.emplace(itr, std::move(string));\r\n                        }\r\n                    });\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        // The IPackageVersion impl for RestSource.\r\n        struct PackageVersion : public SourceReference, public IPackageVersion\r\n        {\r\n            PackageVersion(\r\n                const std::shared_ptr<RestSource>& source, std::shared_ptr<RestPackage>&& package, IRestClient::VersionInfo versionInfo)\r\n                : SourceReference(source), m_package(std::move(package)), m_versionInfo(std::move(versionInfo)) {}\r\n\r\n            // Inherited via IPackageVersion\r\n            Utility::LocIndString GetProperty(PackageVersionProperty property) const override\r\n            {\r\n                switch (property)\r\n                {\r\n                case PackageVersionProperty::SourceIdentifier:\r\n                    return Utility::LocIndString{ GetReferenceSource()->GetIdentifier() };\r\n                case PackageVersionProperty::SourceName:\r\n                    return Utility::LocIndString{ GetReferenceSource()->GetDetails().Name };\r\n                case PackageVersionProperty::Id:\r\n                    return Utility::LocIndString{ m_package->PackageInfo().PackageIdentifier };\r\n                case PackageVersionProperty::Name:\r\n                    return Utility::LocIndString{ m_package->PackageInfo().PackageName };\r\n                case PackageVersionProperty::Version:\r\n                    return Utility::LocIndString{ m_versionInfo.VersionAndChannel.GetVersion().ToString() };\r\n                case PackageVersionProperty::Channel:\r\n                    return Utility::LocIndString{ m_versionInfo.VersionAndChannel.GetChannel().ToString() };\r\n                case PackageVersionProperty::Publisher:\r\n                    return Utility::LocIndString{ m_package->PackageInfo().Publisher };\r\n                case PackageVersionProperty::ArpMinVersion:\r\n                    if (!m_versionInfo.ArpVersions.empty())\r\n                    {\r\n                        return Utility::LocIndString{ m_versionInfo.ArpVersions.front().ToString() };\r\n                    }\r\n                    else if (m_versionInfo.Manifest)\r\n                    {\r\n                        auto arpVersionRange = m_versionInfo.Manifest->GetArpVersionRange();\r\n                        return arpVersionRange.IsEmpty() ? Utility::LocIndString{} : Utility::LocIndString{ arpVersionRange.GetMinVersion().ToString() };\r\n                    }\r\n                    else\r\n                    {\r\n                        return {};\r\n                    }\r\n                case PackageVersionProperty::ArpMaxVersion:\r\n                    if (!m_versionInfo.ArpVersions.empty())\r\n                    {\r\n                        return Utility::LocIndString{ m_versionInfo.ArpVersions.back().ToString() };\r\n                    }\r\n                    else if (m_versionInfo.Manifest)\r\n                    {\r\n                        auto arpVersionRange = m_versionInfo.Manifest->GetArpVersionRange();\r\n                        return arpVersionRange.IsEmpty() ? Utility::LocIndString{} : Utility::LocIndString{ arpVersionRange.GetMaxVersion().ToString() };\r\n                    }\r\n                    else\r\n                    {\r\n                        return {};\r\n                    }\r\n                default:\r\n                    return {};\r\n                }\r\n            }\r\n\r\n            std::vector<Utility::LocIndString> GetMultiProperty(PackageVersionMultiProperty property) const override\r\n            {\r\n                std::vector<Utility::LocIndString> result;\r\n\r\n                GetMultiPropertyValues(\r\n                    m_package.get(),\r\n                    m_versionInfo,\r\n                    property,\r\n                    result,\r\n                    [](std::vector<Utility::LocIndString>& result, Utility::LocIndString&& string)\r\n                    {\r\n                        result.emplace_back(std::move(string));\r\n                    });\r\n\r\n                return result;\r\n            }\r\n\r\n            Manifest::Manifest GetManifest() override\r\n            {\r\n                AICLI_LOG(Repo, Verbose, << \"Getting manifest\");\r\n\r\n                if (m_versionInfo.Manifest)\r\n                {\r\n                    return m_versionInfo.Manifest.value();\r\n                }\r\n\r\n                if (m_package->HandleSingleUnknownVersion(m_versionInfo) &&\r\n                    m_versionInfo.Manifest)\r\n                {\r\n                    return m_versionInfo.Manifest.value();\r\n                }\r\n\r\n                std::optional<Manifest::Manifest> manifest = GetReferenceSource()->GetRestClient().GetManifestByVersion(\r\n                    m_package->PackageInfo().PackageIdentifier, m_versionInfo.VersionAndChannel.GetVersion().ToString(), m_versionInfo.VersionAndChannel.GetChannel().ToString());\r\n\r\n                if (!manifest)\r\n                {\r\n                    AICLI_LOG(Repo, Verbose, << \"Valid manifest not found for package: \" << m_package->PackageInfo().PackageIdentifier);\r\n                    return {};\r\n                }\r\n                \r\n                m_versionInfo.Manifest = std::move(manifest.value());\r\n                return m_versionInfo.Manifest.value();\r\n            }\r\n\r\n            Source GetSource() const override\r\n            {\r\n                return Source{ GetReferenceSource() };\r\n            }\r\n\r\n            IPackageVersion::Metadata GetMetadata() const override\r\n            {\r\n                IPackageVersion::Metadata result;\r\n                return result;\r\n            }\r\n\r\n        private:\r\n            std::shared_ptr<RestPackage> m_package;\r\n            IRestClient::VersionInfo m_versionInfo;\r\n        };\r\n\r\n        std::shared_ptr<IPackageVersion> RestPackage::GetVersion(const PackageVersionKey& versionKey) const\r\n        {\r\n            std::shared_ptr<RestSource> source = GetReferenceSource();\r\n            std::scoped_lock versionsLock{ m_packageVersionsLock };\r\n\r\n            // Ensure that this key targets this (or any) source\r\n            if (!versionKey.SourceId.empty() && versionKey.SourceId != source->GetIdentifier())\r\n            {\r\n                return {};\r\n            }\r\n\r\n            std::shared_ptr<IPackageVersion> packageVersion;\r\n            if (!versionKey.Version.empty() && !versionKey.Channel.empty())\r\n            {\r\n                for (const auto& versionInfo : m_package.Versions)\r\n                {\r\n                    if (CaseInsensitiveEquals(versionInfo.VersionAndChannel.GetVersion().ToString(), versionKey.Version)\r\n                        && CaseInsensitiveEquals(versionInfo.VersionAndChannel.GetChannel().ToString(), versionKey.Channel))\r\n                    {\r\n                        packageVersion = std::make_shared<PackageVersion>(source, NonConstSharedFromThis(), versionInfo);\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n            else if (versionKey.Version.empty() && versionKey.Channel.empty())\r\n            {\r\n                packageVersion = GetLatestVersionInternal();\r\n            }\r\n            else if (versionKey.Version.empty())\r\n            {\r\n                for (const auto& versionInfo : m_package.Versions)\r\n                {\r\n                    if (CaseInsensitiveEquals(versionInfo.VersionAndChannel.GetChannel().ToString(), versionKey.Channel))\r\n                    {\r\n                        packageVersion = std::make_shared<PackageVersion>(source, NonConstSharedFromThis(), versionInfo);\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n            else if (versionKey.Channel.empty())\r\n            {\r\n                for (const auto& versionInfo : m_package.Versions)\r\n                {\r\n                    if (CaseInsensitiveEquals(versionInfo.VersionAndChannel.GetVersion().ToString(), versionKey.Version))\r\n                    {\r\n                        packageVersion = std::make_shared<PackageVersion>(source, NonConstSharedFromThis(), versionInfo);\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n\r\n            return packageVersion;\r\n        }\r\n\r\n        std::shared_ptr<IPackageVersion> RestPackage::GetLatestVersionInternal() const\r\n        {\r\n            return std::make_shared<PackageVersion>(GetReferenceSource(), NonConstSharedFromThis(), m_package.Versions.front());\r\n        }\r\n    }\r\n\r\n    RestSource::RestSource(const SourceDetails& details, SourceInformation information, RestClient&& restClient)\r\n        : m_details(details), m_information(std::move(information)), m_restClient(std::move(restClient))\r\n    {\r\n    }\r\n\r\n    const std::string& RestSource::GetIdentifier() const\r\n    {\r\n        return m_details.Identifier;\r\n    }\r\n\r\n    const SourceDetails& RestSource::GetDetails() const\r\n    {\r\n        return m_details;\r\n    }\r\n\r\n    SourceInformation RestSource::GetInformation() const\r\n    {\r\n        return m_information;\r\n    }\r\n\r\n    bool RestSource::QueryFeatureFlag(SourceFeatureFlag flag) const\r\n    {\r\n        switch (flag)\r\n        {\r\n        case SourceFeatureFlag::ManifestMayContainAdditionalSystemReferenceStrings:\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    SearchResult RestSource::Search(const SearchRequest& request) const\r\n    {\r\n        IRestClient::SearchResult results = m_restClient.Search(request);\r\n        SearchResult searchResult;\r\n\r\n        std::shared_ptr<RestSource> sharedThis = NonConstSharedFromThis();\r\n        for (auto& result : results.Matches)\r\n        {\r\n            std::shared_ptr<RestPackage> package = std::make_shared<RestPackage>(sharedThis, std::move(result));\r\n            PackageMatchFilter packageFilter{ FindBestMatchCriteria(request, package->GetLatestVersion().get()) };\r\n\r\n            searchResult.Matches.emplace_back(std::move(package), std::move(packageFilter));\r\n        }\r\n\r\n        searchResult.Truncated = results.Truncated;\r\n\r\n        return searchResult;\r\n    }\r\n\r\n    void* RestSource::CastTo(ISourceType type)\r\n    {\r\n        if (type == SourceType)\r\n        {\r\n            return this;\r\n        }\r\n\r\n        return nullptr;\r\n    }\r\n\r\n    const RestClient& RestSource::GetRestClient() const\r\n    {\r\n        return m_restClient;\r\n    }\r\n\r\n    bool RestSource::IsSame(const RestSource* other) const\r\n    {\r\n        return (other && GetIdentifier() == other->GetIdentifier());\r\n    }\r\n\r\n    std::shared_ptr<RestSource> RestSource::NonConstSharedFromThis() const\r\n    {\r\n        return const_cast<RestSource*>(this)->shared_from_this();\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/RestSource.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ISource.h\"\r\n#include \"RestClient.h\"\r\n\r\nnamespace AppInstaller::Repository::Rest\r\n{\r\n    // A source that holds a RestSource.\r\n    struct RestSource : public std::enable_shared_from_this<RestSource>, public ISource\r\n    {\r\n        static constexpr ISourceType SourceType = ISourceType::RestSource;\r\n\r\n        RestSource(const SourceDetails& details, SourceInformation information, RestClient&& restClient);\r\n\r\n        RestSource(const RestSource&) = delete;\r\n        RestSource& operator=(const RestSource&) = delete;\r\n\r\n        RestSource(RestSource&&) = default;\r\n        RestSource& operator=(RestSource&&) = default;\r\n\r\n        ~RestSource() = default;\r\n\r\n        // Gets the source's identifier; a unique identifier independent of the name\r\n        // that will not change between a remove/add or between additional adds.\r\n        // Must be suitable for filesystem names.\r\n        const std::string& GetIdentifier() const override;\r\n\r\n        // Get the source's details.\r\n        const SourceDetails& GetDetails() const override;\r\n\r\n        SourceInformation GetInformation() const override;\r\n\r\n        bool QueryFeatureFlag(SourceFeatureFlag flag) const override;\r\n\r\n        // Execute a search on the source.\r\n        SearchResult Search(const SearchRequest& request) const override;\r\n\r\n        // Casts to the requested type.\r\n        void* CastTo(ISourceType type) override;\r\n\r\n        // Gets the rest client.\r\n        const RestClient& GetRestClient() const;\r\n\r\n        // Determines if the other source refers to the same as this.\r\n        bool IsSame(const RestSource* other) const;\r\n\r\n    private:\r\n        std::shared_ptr<RestSource> NonConstSharedFromThis() const;\r\n\r\n        SourceDetails m_details;\r\n        SourceInformation m_information;\r\n        RestClient m_restClient;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/RestSourceFactory.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"RestSourceFactory.h\"\r\n#include \"RestClient.h\"\r\n#include \"RestSource.h\"\r\n\r\nusing namespace std::string_literals;\r\nusing namespace std::string_view_literals;\r\n\r\nnamespace AppInstaller::Repository::Rest\r\n{\r\n    namespace\r\n    {\r\n        struct RestSourceReference : public ISourceReference\r\n        {\r\n            RestSourceReference(const SourceDetails& details) : m_details(details) {}\r\n\r\n            SourceDetails& GetDetails() override { return m_details; };\r\n\r\n            std::string GetIdentifier() override\r\n            {\r\n                Initialize();\r\n                return m_details.Identifier;\r\n            }\r\n\r\n            SourceInformation GetInformation() override\r\n            {\r\n                Initialize();\r\n                return m_information;\r\n            }\r\n\r\n            // Set custom header. Returns false if custom header is not supported.\r\n            bool SetCustomHeader(std::optional<std::string> header) override\r\n            {\r\n                m_customHeader = header;\r\n                return true;\r\n            }\r\n\r\n            void SetCaller(std::string caller) override\r\n            {\r\n                m_caller = std::move(caller);\r\n            }\r\n\r\n            void SetAuthenticationArguments(Authentication::AuthenticationArguments authArgs) override\r\n            {\r\n                m_authArgs = std::move(authArgs);\r\n            }\r\n\r\n            std::shared_ptr<ISource> Open(IProgressCallback&) override\r\n            {\r\n                Initialize();\r\n                RestClient restClient = RestClient::Create(m_details.Arg, m_customHeader, m_caller, m_httpClientHelper, m_restClientInformation, m_authArgs);\r\n                return std::make_shared<RestSource>(m_details, m_information, std::move(restClient));\r\n            }\r\n\r\n            void SetThreadGlobals(const std::shared_ptr<ThreadLocalStorage::ThreadGlobals>& threadGlobals) override\r\n            {\r\n                m_threadGlobals = threadGlobals;\r\n            }\r\n\r\n        private:\r\n            void Initialize()\r\n            {\r\n                std::call_once(m_initializeFlag,\r\n                    [&]()\r\n                    {\r\n                        m_httpClientHelper.SetPinningConfiguration(m_details.CertificatePinningConfiguration, m_threadGlobals);\r\n                        m_restClientInformation = RestClient::GetInformation(m_details.Arg, m_customHeader, m_caller, m_httpClientHelper);\r\n\r\n                        m_details.Identifier = m_restClientInformation.SourceIdentifier;\r\n\r\n                        m_information.UnsupportedPackageMatchFields = m_restClientInformation.UnsupportedPackageMatchFields;\r\n                        m_information.RequiredPackageMatchFields = m_restClientInformation.RequiredPackageMatchFields;\r\n                        m_information.UnsupportedQueryParameters = m_restClientInformation.UnsupportedQueryParameters;\r\n                        m_information.RequiredQueryParameters = m_restClientInformation.RequiredQueryParameters;\r\n\r\n                        m_information.SourceAgreementsIdentifier = m_restClientInformation.SourceAgreementsIdentifier;\r\n                        for (auto const& agreement : m_restClientInformation.SourceAgreements)\r\n                        {\r\n                            m_information.SourceAgreements.emplace_back(agreement.Label, agreement.Text, agreement.Url);\r\n                        }\r\n\r\n                        m_information.Authentication = m_restClientInformation.Authentication;\r\n                    });\r\n            }\r\n\r\n            SourceDetails m_details;\r\n            Http::HttpClientHelper m_httpClientHelper;\r\n            SourceInformation m_information;\r\n            Schema::IRestClient::Information m_restClientInformation;\r\n            std::optional<std::string> m_customHeader;\r\n            std::string m_caller;\r\n            Authentication::AuthenticationArguments m_authArgs;\r\n            std::once_flag m_initializeFlag;\r\n            std::shared_ptr<ThreadLocalStorage::ThreadGlobals> m_threadGlobals;\r\n        };\r\n\r\n        // The base class for data that comes from a rest based source.\r\n        struct RestSourceFactoryImpl : public ISourceFactory\r\n        {\r\n            std::string_view TypeName() const override final\r\n            {\r\n                return RestSourceFactory::Type();\r\n            }\r\n\r\n            std::shared_ptr<ISourceReference> Create(const SourceDetails& details) override final\r\n            {\r\n                THROW_HR_IF(E_INVALIDARG, !Utility::CaseInsensitiveEquals(details.Type, RestSourceFactory::Type()));\r\n\r\n                return std::make_shared<RestSourceReference>(details);\r\n            }\r\n\r\n            bool Add(SourceDetails& details, IProgressCallback&) override final\r\n            {\r\n                if (details.Type.empty())\r\n                {\r\n                    details.Type = RestSourceFactory::Type();\r\n                }\r\n                else\r\n                {\r\n                    THROW_HR_IF(E_INVALIDARG, !Utility::CaseInsensitiveEquals(details.Type, RestSourceFactory::Type()));\r\n                }\r\n\r\n                // Check if URL is remote and secure\r\n                THROW_HR_IF(APPINSTALLER_CLI_ERROR_SOURCE_NOT_REMOTE, !Utility::IsUrlRemote(details.Arg));\r\n                THROW_HR_IF(APPINSTALLER_CLI_ERROR_SOURCE_NOT_SECURE, !Utility::IsUrlSecure(details.Arg));\r\n\r\n                return true;\r\n            }\r\n\r\n            bool Update(const SourceDetails& details, IProgressCallback&) override final\r\n            {\r\n                THROW_HR_IF(E_INVALIDARG, !Utility::CaseInsensitiveEquals(details.Type, RestSourceFactory::Type()));\r\n                return true;\r\n            }\r\n\r\n            bool Remove(const SourceDetails& details, IProgressCallback&) override final\r\n            {\r\n                THROW_HR_IF(E_INVALIDARG, !Utility::CaseInsensitiveEquals(details.Type, RestSourceFactory::Type()));\r\n                return true;\r\n            }\r\n        };\r\n    }\r\n\r\n    std::unique_ptr<ISourceFactory> RestSourceFactory::Create()\r\n    {\r\n        return std::make_unique<RestSourceFactoryImpl>();\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/RestSourceFactory.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ISource.h\"\r\n#include \"SourceFactory.h\"\r\n#include <string_view>\r\n\r\nnamespace AppInstaller::Repository::Rest\r\n{\r\n    using namespace std::string_view_literals;\r\n\r\n    // A source where the information is stored on a REST based server.\r\n    // In addition, the manifest information is also available on the server.\r\n    // Arg  ::  Expected to be a API which supports querying functionality.\r\n    struct RestSourceFactory\r\n    {\r\n        // Get the type string for this source.\r\n        static constexpr std::string_view Type()\r\n        {\r\n            using namespace std::string_view_literals;\r\n            return \"Microsoft.Rest\"sv;\r\n        }\r\n\r\n        // Creates a source factory for this type.\r\n        static std::unique_ptr<ISourceFactory> Create();\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_0/Interface.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Rest/Schema/IRestClient.h\"\r\n#include <winget/HttpClientHelper.h>\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_0\r\n{\r\n    // Interface to this schema version exposed through IRestClient.\r\n    struct Interface : public IRestClient\r\n    {\r\n        Interface(const std::string& restApi, const Http::HttpClientHelper& helper);\r\n\r\n        Interface(const Interface&) = delete;\r\n        Interface& operator=(const Interface&) = delete;\r\n\r\n        Interface(Interface&&) = default;\r\n        Interface& operator=(Interface&&) = default;\r\n\r\n        Utility::Version GetVersion() const override;\r\n        IRestClient::Information GetSourceInformation() const override;\r\n        IRestClient::SearchResult Search(const SearchRequest& request) const override;\r\n        std::optional<Manifest::Manifest> GetManifestByVersion(const std::string& packageId, const std::string& version, const std::string& channel) const override;\r\n        std::vector<Manifest::Manifest> GetManifests(const std::string& packageId, const std::map<std::string_view, std::string>& params = {}) const override;\r\n\r\n    protected:\r\n        bool MeetsOptimizedSearchCriteria(const SearchRequest& request) const;\r\n        IRestClient::SearchResult OptimizedSearch(const SearchRequest& request) const;\r\n        IRestClient::SearchResult SearchInternal(const SearchRequest& request) const;\r\n\r\n        // Check query params against source information and update if necessary.\r\n        virtual std::map<std::string_view, std::string> GetValidatedQueryParams(const std::map<std::string_view, std::string>& params) const;\r\n\r\n        // Check search request against source information and get json search body.\r\n        virtual web::json::value GetValidatedSearchBody(const SearchRequest& searchRequest) const;\r\n\r\n        virtual SearchResult GetSearchResult(const web::json::value& searchResponseObject) const;\r\n        virtual std::vector<Manifest::Manifest> GetParsedManifests(const web::json::value& manifestsResponseObject) const;\r\n\r\n        // Gets auth headers if source requires authentication for access.\r\n        virtual Http::HttpClientHelper::HttpRequestHeaders GetAuthHeaders() const;\r\n\r\n        Http::HttpClientHelper::HttpRequestHeaders m_requiredRestApiHeaders;\r\n\r\n    private:\r\n        std::string m_restApiUri;\r\n        utility::string_t m_searchEndpoint;\r\n        Http::HttpClientHelper m_httpClientHelper;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/ManifestDeserializer.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/Manifest.h>\r\n#include <cpprest/json.h>\r\n#include <winget/JsonUtil.h>\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_0::Json\r\n{\r\n    // Manifest Deserializer.\r\n    struct ManifestDeserializer\r\n    {\r\n        // Gets the manifest from the given json object received from a REST request\r\n        std::vector<Manifest::Manifest> Deserialize(const web::json::value& responseJsonObject) const;\r\n\r\n        // Gets the manifest from the given json Data field\r\n        std::vector<Manifest::Manifest> DeserializeData(const web::json::value& dataJsonObject) const;\r\n\r\n        // Deserializes the AppsAndFeaturesEntries node, returning the set of values below it.\r\n        virtual std::vector<Manifest::AppsAndFeaturesEntry> DeserializeAppsAndFeaturesEntries(const web::json::array& entries) const;\r\n\r\n        // Deserializes the locale; requires that the PackageLocale be set to return an object.\r\n        virtual std::optional<Manifest::ManifestLocalization> DeserializeLocale(const web::json::value& localeJsonObject) const;\r\n\r\n        // Deserializes the locale; requires that the PackageLocale be set to return an object.\r\n        virtual std::optional<Manifest::InstallationMetadataInfo> DeserializeInstallationMetadata(const web::json::value& installationMetadataJsonObject) const;\r\n\r\n    protected:\r\n\r\n        template <Manifest::Localization L>\r\n        inline void TryParseStringLocaleField(Manifest::ManifestLocalization& manifestLocale, const web::json::value& localeJsonObject, std::string_view localeJsonFieldName) const\r\n        {\r\n            auto value = AppInstaller::JSON::GetRawStringValueFromJsonNode(localeJsonObject, AppInstaller::JSON::GetUtilityString(localeJsonFieldName));\r\n\r\n            if (AppInstaller::JSON::IsValidNonEmptyStringValue(value))\r\n            {\r\n                manifestLocale.Add<L>(value.value());\r\n            }\r\n        }\r\n\r\n        virtual std::optional<Manifest::ManifestInstaller> DeserializeInstaller(const web::json::value& installerJsonObject) const;\r\n\r\n        virtual std::map<Manifest::InstallerSwitchType, Manifest::string_t> DeserializeInstallerSwitches(const web::json::value& installerSwitchesJsonObject) const;\r\n\r\n        std::optional<Manifest::DependencyList> DeserializeDependency(const web::json::value& dependenciesJsonObject) const;\r\n\r\n        virtual Manifest::InstallerTypeEnum ConvertToInstallerType(std::string_view in) const;\r\n\r\n        virtual Manifest::UpdateBehaviorEnum ConvertToUpdateBehavior(std::string_view in) const;\r\n\r\n        std::vector<Manifest::string_t> ConvertToManifestStringArray(const std::vector<std::string>& values) const;\r\n\r\n        virtual Manifest::ManifestVer GetManifestVersion() const;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/ManifestDeserializer_1_0.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Rest/Schema/1_0/Interface.h\"\r\n#include \"Rest/Schema/CommonRestConstants.h\"\r\n#include \"Rest/Schema/IRestClient.h\"\r\n#include \"ManifestDeserializer.h\"\r\n#include <winget/HttpClientHelper.h>\r\n#include <winget/JsonUtil.h>\r\n\r\nusing namespace AppInstaller::Manifest;\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_0::Json\r\n{\r\n    namespace\r\n    {\r\n        // Manifest response constants specific to this deserializer\r\n        constexpr std::string_view PackageIdentifier = \"PackageIdentifier\"sv;\r\n        constexpr std::string_view PackageFamilyName = \"PackageFamilyName\"sv;\r\n        constexpr std::string_view ProductCode = \"ProductCode\"sv;\r\n        constexpr std::string_view Versions = \"Versions\"sv;\r\n        constexpr std::string_view PackageVersion = \"PackageVersion\"sv;\r\n        constexpr std::string_view Channel = \"Channel\"sv;\r\n\r\n        // Locale\r\n        constexpr std::string_view DefaultLocale = \"DefaultLocale\"sv;\r\n        constexpr std::string_view Locales = \"Locales\"sv;\r\n        constexpr std::string_view PackageLocale = \"PackageLocale\"sv;\r\n        constexpr std::string_view Publisher = \"Publisher\"sv;\r\n        constexpr std::string_view PublisherUrl = \"PublisherUrl\"sv;\r\n        constexpr std::string_view PublisherSupportUrl = \"PublisherSupportUrl\"sv;\r\n        constexpr std::string_view PrivacyUrl = \"PrivacyUrl\"sv;\r\n        constexpr std::string_view Author = \"Author\"sv;\r\n        constexpr std::string_view PackageName = \"PackageName\"sv;\r\n        constexpr std::string_view PackageUrl = \"PackageUrl\"sv;\r\n        constexpr std::string_view License = \"License\"sv;\r\n        constexpr std::string_view LicenseUrl = \"LicenseUrl\"sv;\r\n        constexpr std::string_view Copyright = \"Copyright\"sv;\r\n        constexpr std::string_view CopyrightUrl = \"CopyrightUrl\"sv;\r\n        constexpr std::string_view ShortDescription = \"ShortDescription\"sv;\r\n        constexpr std::string_view Description = \"Description\"sv;\r\n        constexpr std::string_view Tags = \"Tags\"sv;\r\n        constexpr std::string_view Moniker = \"Moniker\"sv;\r\n\r\n        // Installer\r\n        constexpr std::string_view Installers = \"Installers\"sv;\r\n        constexpr std::string_view InstallerIdentifier = \"InstallerIdentifier\"sv;\r\n        constexpr std::string_view InstallerSha256 = \"InstallerSha256\"sv;\r\n        constexpr std::string_view InstallerUrl = \"InstallerUrl\"sv;\r\n        constexpr std::string_view Architecture = \"Architecture\"sv;\r\n        constexpr std::string_view InstallerLocale = \"InstallerLocale\"sv;\r\n        constexpr std::string_view Platform = \"Platform\"sv;\r\n        constexpr std::string_view MinimumOSVersion = \"MinimumOSVersion\"sv;\r\n        constexpr std::string_view InstallerType = \"InstallerType\"sv;\r\n        constexpr std::string_view Scope = \"Scope\"sv;\r\n        constexpr std::string_view SignatureSha256 = \"SignatureSha256\"sv;\r\n        constexpr std::string_view InstallModes = \"InstallModes\"sv;\r\n\r\n        // Installer switches\r\n        constexpr std::string_view InstallerSwitches = \"InstallerSwitches\"sv;\r\n        constexpr std::string_view Silent = \"Silent\"sv;\r\n        constexpr std::string_view SilentWithProgress = \"SilentWithProgress\"sv;\r\n        constexpr std::string_view Interactive = \"Interactive\"sv;\r\n        constexpr std::string_view InstallLocation = \"InstallLocation\"sv;\r\n        constexpr std::string_view Log = \"Log\"sv;\r\n        constexpr std::string_view Upgrade = \"Upgrade\"sv;\r\n        constexpr std::string_view Custom = \"Custom\"sv;\r\n\r\n        constexpr std::string_view InstallerSuccessCodes = \"InstallerSuccessCodes\"sv;\r\n        constexpr std::string_view UpgradeBehavior = \"UpgradeBehavior\"sv;\r\n        constexpr std::string_view Commands = \"Commands\"sv;\r\n        constexpr std::string_view Protocols = \"Protocols\"sv;\r\n        constexpr std::string_view FileExtensions = \"FileExtensions\"sv;\r\n\r\n        // Dependencies\r\n        constexpr std::string_view Dependencies = \"Dependencies\"sv;\r\n        constexpr std::string_view WindowsFeatures = \"WindowsFeatures\"sv;\r\n        constexpr std::string_view WindowsLibraries = \"WindowsLibraries\"sv;\r\n        constexpr std::string_view PackageDependencies = \"PackageDependencies\"sv;\r\n        constexpr std::string_view MinimumVersion = \"MinimumVersion\"sv;\r\n        constexpr std::string_view ExternalDependencies = \"ExternalDependencies\"sv;\r\n\r\n        constexpr std::string_view Capabilities = \"Capabilities\"sv;\r\n        constexpr std::string_view RestrictedCapabilities = \"RestrictedCapabilities\"sv;\r\n\r\n        void TryParseInstallerSwitchField(\r\n            std::map<InstallerSwitchType, Utility::NormalizedString>& installerSwitches,\r\n            InstallerSwitchType switchType,\r\n            const web::json::value& switchesJsonObject,\r\n            std::string_view switchJsonFieldName)\r\n        {\r\n            auto value = JSON::GetRawStringValueFromJsonNode(switchesJsonObject, JSON::GetUtilityString(switchJsonFieldName));\r\n\r\n            if (JSON::IsValidNonEmptyStringValue(value))\r\n            {\r\n                installerSwitches[switchType] = value.value();\r\n            }\r\n        }\r\n    }\r\n\r\n    std::vector<Manifest::Manifest> ManifestDeserializer::Deserialize(const web::json::value& responseJsonObject) const\r\n    {\r\n        if (responseJsonObject.is_null())\r\n        {\r\n            AICLI_LOG(Repo, Error, << \"Missing json object.\");\r\n            THROW_HR(APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA);\r\n        }\r\n\r\n        try\r\n        {\r\n            std::optional<std::reference_wrapper<const web::json::value>> manifestObject =\r\n                JSON::GetJsonValueFromNode(responseJsonObject, JSON::GetUtilityString(Data));\r\n\r\n            if (!manifestObject || manifestObject.value().get().is_null())\r\n            {\r\n                AICLI_LOG(Repo, Verbose, << \"No manifest results returned.\");\r\n                return {};\r\n            }\r\n\r\n            return DeserializeData(manifestObject.value());\r\n        }\r\n        catch (const wil::ResultException&)\r\n        {\r\n            throw;\r\n        }\r\n        catch (const std::exception& e)\r\n        {\r\n            AICLI_LOG(Repo, Error, << \"Error encountered while deserializing manifest. Reason: \" << e.what());\r\n        }\r\n        catch (...)\r\n        {\r\n            AICLI_LOG(Repo, Error, << \"Error encountered while deserializing manifest...\");\r\n        }\r\n\r\n        // If we make it here, there was an exception above that we didn't throw.\r\n        // This will convert it into our standard error.\r\n        THROW_HR(APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA);\r\n    }\r\n\r\n    std::vector<Manifest::Manifest> ManifestDeserializer::DeserializeData(const web::json::value& dataJsonObject) const\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, dataJsonObject.is_null());\r\n\r\n        std::vector<Manifest::Manifest> manifests;\r\n\r\n        std::optional<std::string> id = JSON::GetRawStringValueFromJsonNode(dataJsonObject, JSON::GetUtilityString(PackageIdentifier));\r\n        if (!JSON::IsValidNonEmptyStringValue(id))\r\n        {\r\n            AICLI_LOG(Repo, Error, << \"Missing package identifier.\");\r\n            THROW_HR(APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA);\r\n        }\r\n\r\n        std::optional<std::reference_wrapper<const web::json::array>> versions = JSON::GetRawJsonArrayFromJsonNode(dataJsonObject, JSON::GetUtilityString(Versions));\r\n        if (!versions || versions.value().get().size() == 0)\r\n        {\r\n            AICLI_LOG(Repo, Error, << \"Missing versions in package: \" << id.value());\r\n            THROW_HR(APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA);\r\n        }\r\n\r\n        for (auto& versionItem : versions.value().get())\r\n        {\r\n            Manifest::Manifest manifest;\r\n\r\n            manifest.ManifestVersion = GetManifestVersion();\r\n\r\n            manifest.Id = id.value();\r\n\r\n            std::optional<std::string> packageVersion = JSON::GetRawStringValueFromJsonNode(versionItem, JSON::GetUtilityString(PackageVersion));\r\n            if (!JSON::IsValidNonEmptyStringValue(packageVersion))\r\n            {\r\n                AICLI_LOG(Repo, Error, << \"Missing package version in package: \" << manifest.Id);\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA);\r\n            }\r\n            manifest.Version = std::move(packageVersion.value());\r\n\r\n            manifest.Channel = JSON::GetRawStringValueFromJsonNode(versionItem, JSON::GetUtilityString(Channel)).value_or(\"\");\r\n\r\n            // Default locale\r\n            std::optional<std::reference_wrapper<const web::json::value>> defaultLocale =\r\n                JSON::GetJsonValueFromNode(versionItem, JSON::GetUtilityString(DefaultLocale));\r\n            if (!defaultLocale)\r\n            {\r\n                AICLI_LOG(Repo, Error, << \"Missing default locale in package: \" << manifest.Id);\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA);\r\n            }\r\n            else\r\n            {\r\n                std::optional<Manifest::ManifestLocalization> defaultLocaleObject = DeserializeLocale(defaultLocale.value().get());\r\n                if (!defaultLocaleObject)\r\n                {\r\n                    AICLI_LOG(Repo, Error, << \"Missing default locale in package: \" << manifest.Id);\r\n                    THROW_HR(APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA);\r\n                }\r\n\r\n                if (!defaultLocaleObject.value().Contains(Manifest::Localization::PackageName) ||\r\n                    !defaultLocaleObject.value().Contains(Manifest::Localization::Publisher) ||\r\n                    !defaultLocaleObject.value().Contains(Manifest::Localization::ShortDescription))\r\n                {\r\n                    AICLI_LOG(Repo, Error, << \"Missing PackageName, Publisher or ShortDescription in default locale: \" << manifest.Id);\r\n                    THROW_HR(APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA);\r\n                }\r\n\r\n                manifest.DefaultLocalization = std::move(defaultLocaleObject.value());\r\n\r\n                // Moniker is in Default locale\r\n                manifest.Moniker = JSON::GetRawStringValueFromJsonNode(defaultLocale.value().get(), JSON::GetUtilityString(Moniker)).value_or(\"\");\r\n            }\r\n\r\n            // Installers\r\n            std::optional<std::reference_wrapper<const web::json::array>> installers = JSON::GetRawJsonArrayFromJsonNode(versionItem, JSON::GetUtilityString(Installers));\r\n            if (!installers || installers.value().get().size() == 0)\r\n            {\r\n                AICLI_LOG(Repo, Error, << \"Missing installers in package: \" << manifest.Id);\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA);\r\n            }\r\n\r\n            for (auto& installer : installers.value().get())\r\n            {\r\n                std::optional<Manifest::ManifestInstaller> installerObject = DeserializeInstaller(installer);\r\n                if (installerObject)\r\n                {\r\n                    // Merge default switches after parsing.\r\n                    auto defaultSwitches = Manifest::GetDefaultKnownSwitches(installerObject->EffectiveInstallerType());\r\n                    for (auto const& defaultSwitch : defaultSwitches)\r\n                    {\r\n                        if (installerObject->Switches.find(defaultSwitch.first) == installerObject->Switches.end())\r\n                        {\r\n                            installerObject->Switches[defaultSwitch.first] = defaultSwitch.second;\r\n                        }\r\n                    }\r\n\r\n                    manifest.Installers.emplace_back(std::move(installerObject.value()));\r\n                }\r\n            }\r\n\r\n            if (manifest.Installers.size() == 0)\r\n            {\r\n                AICLI_LOG(Repo, Error, << \"Missing valid installers in package: \" << manifest.Id);\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA);\r\n            }\r\n\r\n            // Other locales\r\n            std::optional<std::reference_wrapper<const web::json::array>> locales = JSON::GetRawJsonArrayFromJsonNode(versionItem, JSON::GetUtilityString(Locales));\r\n            if (locales)\r\n            {\r\n                for (auto& locale : locales.value().get())\r\n                {\r\n                    std::optional<Manifest::ManifestLocalization> localeObject = DeserializeLocale(locale);\r\n                    if (localeObject)\r\n                    {\r\n                        manifest.Localizations.emplace_back(std::move(localeObject.value()));\r\n                    }\r\n                }\r\n            }\r\n\r\n            manifests.emplace_back(std::move(manifest));\r\n        }\r\n\r\n        return manifests;\r\n    }\r\n\r\n    std::vector<Manifest::AppsAndFeaturesEntry> ManifestDeserializer::DeserializeAppsAndFeaturesEntries(const web::json::array&) const\r\n    {\r\n        return {};\r\n    }\r\n\r\n    std::optional<Manifest::InstallationMetadataInfo> ManifestDeserializer::DeserializeInstallationMetadata(const web::json::value&) const\r\n    {\r\n        return {};\r\n    }\r\n\r\n    std::optional<Manifest::ManifestLocalization> ManifestDeserializer::DeserializeLocale(const web::json::value& localeJsonObject) const\r\n    {\r\n        if (localeJsonObject.is_null())\r\n        {\r\n            return {};\r\n        }\r\n\r\n        Manifest::ManifestLocalization locale;\r\n        std::optional<std::string> packageLocale = JSON::GetRawStringValueFromJsonNode(localeJsonObject, JSON::GetUtilityString(PackageLocale));\r\n        if (!JSON::IsValidNonEmptyStringValue(packageLocale))\r\n        {\r\n            AICLI_LOG(Repo, Error, << \"Missing package locale.\");\r\n            return {};\r\n        }\r\n        locale.Locale = std::move(packageLocale.value());\r\n\r\n        TryParseStringLocaleField<Manifest::Localization::PackageName>(locale, localeJsonObject, PackageName);\r\n        TryParseStringLocaleField<Manifest::Localization::Publisher>(locale, localeJsonObject, Publisher);\r\n        TryParseStringLocaleField<Manifest::Localization::ShortDescription>(locale, localeJsonObject, ShortDescription);\r\n        TryParseStringLocaleField<Manifest::Localization::PublisherUrl>(locale, localeJsonObject, PublisherUrl);\r\n        TryParseStringLocaleField<Manifest::Localization::PublisherSupportUrl>(locale, localeJsonObject, PublisherSupportUrl);\r\n        TryParseStringLocaleField<Manifest::Localization::PrivacyUrl>(locale, localeJsonObject, PrivacyUrl);\r\n        TryParseStringLocaleField<Manifest::Localization::Author>(locale, localeJsonObject, Author);\r\n        TryParseStringLocaleField<Manifest::Localization::PackageUrl>(locale, localeJsonObject, PackageUrl);\r\n        TryParseStringLocaleField<Manifest::Localization::License>(locale, localeJsonObject, License);\r\n        TryParseStringLocaleField<Manifest::Localization::LicenseUrl>(locale, localeJsonObject, LicenseUrl);\r\n        TryParseStringLocaleField<Manifest::Localization::Copyright>(locale, localeJsonObject, Copyright);\r\n        TryParseStringLocaleField<Manifest::Localization::CopyrightUrl>(locale, localeJsonObject, CopyrightUrl);\r\n        TryParseStringLocaleField<Manifest::Localization::Description>(locale, localeJsonObject, Description);\r\n\r\n        auto tags = ConvertToManifestStringArray(JSON::GetRawStringArrayFromJsonNode(localeJsonObject, JSON::GetUtilityString(Tags)));\r\n        if (!tags.empty())\r\n        {\r\n            locale.Add<AppInstaller::Manifest::Localization::Tags>(tags);\r\n        }\r\n\r\n        return locale;\r\n    }\r\n\r\n    std::optional<Manifest::ManifestInstaller> ManifestDeserializer::DeserializeInstaller(const web::json::value& installerJsonObject) const\r\n    {\r\n        if (installerJsonObject.is_null())\r\n        {\r\n            return {};\r\n        }\r\n\r\n        Manifest::ManifestInstaller installer;\r\n\r\n        installer.Url = JSON::GetRawStringValueFromJsonNode(installerJsonObject, JSON::GetUtilityString(InstallerUrl)).value_or(\"\");\r\n\r\n        std::optional<std::string> sha256 = JSON::GetRawStringValueFromJsonNode(installerJsonObject, JSON::GetUtilityString(InstallerSha256));\r\n        if (JSON::IsValidNonEmptyStringValue(sha256))\r\n        {\r\n            installer.Sha256 = Utility::SHA256::ConvertToBytes(sha256.value());\r\n        }\r\n\r\n        std::optional<std::string> arch = JSON::GetRawStringValueFromJsonNode(installerJsonObject, JSON::GetUtilityString(Architecture));\r\n        if (!JSON::IsValidNonEmptyStringValue(arch))\r\n        {\r\n            AICLI_LOG(Repo, Error, << \"Missing installer architecture.\");\r\n            return {};\r\n        }\r\n        installer.Arch = Utility::ConvertToArchitectureEnum(arch.value());\r\n\r\n        std::optional<std::string> installerType = JSON::GetRawStringValueFromJsonNode(installerJsonObject, JSON::GetUtilityString(InstallerType));\r\n        if (!JSON::IsValidNonEmptyStringValue(installerType))\r\n        {\r\n            AICLI_LOG(Repo, Error, << \"Missing installer type.\");\r\n            return {};\r\n        }\r\n        installer.BaseInstallerType = ConvertToInstallerType(installerType.value());\r\n        installer.Locale = JSON::GetRawStringValueFromJsonNode(installerJsonObject, JSON::GetUtilityString(InstallerLocale)).value_or(\"\");\r\n\r\n        // platform\r\n        std::optional<std::reference_wrapper<const web::json::array>> platforms = JSON::GetRawJsonArrayFromJsonNode(installerJsonObject, JSON::GetUtilityString(Platform));\r\n        if (platforms)\r\n        {\r\n            for (auto& platform : platforms.value().get())\r\n            {\r\n                std::optional<std::string> platformValue = JSON::GetRawStringValueFromJsonValue(platform);\r\n                if (platformValue)\r\n                {\r\n                    installer.Platform.emplace_back(Manifest::ConvertToPlatformEnum(platformValue.value()));\r\n                }\r\n            }\r\n        }\r\n\r\n        installer.MinOSVersion = JSON::GetRawStringValueFromJsonNode(installerJsonObject, JSON::GetUtilityString(MinimumOSVersion)).value_or(\"\");\r\n        std::optional<std::string> scope = JSON::GetRawStringValueFromJsonNode(installerJsonObject, JSON::GetUtilityString(Scope));\r\n        if (scope)\r\n        {\r\n            installer.Scope = Manifest::ConvertToScopeEnum(scope.value());\r\n        }\r\n\r\n        std::optional<std::string> signatureSha256 = JSON::GetRawStringValueFromJsonNode(installerJsonObject, JSON::GetUtilityString(SignatureSha256));\r\n        if (signatureSha256)\r\n        {\r\n            installer.SignatureSha256 = Utility::SHA256::ConvertToBytes(signatureSha256.value());\r\n        }\r\n\r\n        // Install modes\r\n        std::optional<std::reference_wrapper<const web::json::array>> installModes = JSON::GetRawJsonArrayFromJsonNode(installerJsonObject, JSON::GetUtilityString(InstallModes));\r\n        if (installModes)\r\n        {\r\n            for (auto& mode : installModes.value().get())\r\n            {\r\n                std::optional<std::string> modeObject = JSON::GetRawStringValueFromJsonValue(mode);\r\n                if (modeObject)\r\n                {\r\n                    installer.InstallModes.emplace_back(Manifest::ConvertToInstallModeEnum(modeObject.value()));\r\n                }\r\n            }\r\n        }\r\n\r\n        // Installer Switches\r\n        std::optional<std::reference_wrapper<const web::json::value>> switches =\r\n            JSON::GetJsonValueFromNode(installerJsonObject, JSON::GetUtilityString(InstallerSwitches));\r\n        if (switches)\r\n        {\r\n            installer.Switches = DeserializeInstallerSwitches(switches.value().get());\r\n        }\r\n\r\n        // Installer SuccessCodes\r\n        std::optional<std::reference_wrapper<const web::json::array>> installSuccessCodes = JSON::GetRawJsonArrayFromJsonNode(installerJsonObject, JSON::GetUtilityString(InstallerSuccessCodes));\r\n        if (installSuccessCodes)\r\n        {\r\n            for (auto& code : installSuccessCodes.value().get())\r\n            {\r\n                std::optional<int> codeValue = JSON::GetRawIntValueFromJsonValue(code);\r\n                if (codeValue)\r\n                {\r\n                    installer.InstallerSuccessCodes.emplace_back(std::move(codeValue.value()));\r\n                }\r\n            }\r\n        }\r\n\r\n        std::optional<std::string> updateBehavior = JSON::GetRawStringValueFromJsonNode(installerJsonObject, JSON::GetUtilityString(UpgradeBehavior));\r\n        if (updateBehavior)\r\n        {\r\n            installer.UpdateBehavior = ConvertToUpdateBehavior(updateBehavior.value());\r\n        }\r\n\r\n        installer.Commands = ConvertToManifestStringArray(JSON::GetRawStringArrayFromJsonNode(installerJsonObject, JSON::GetUtilityString(Commands)));\r\n        installer.Protocols = ConvertToManifestStringArray(JSON::GetRawStringArrayFromJsonNode(installerJsonObject, JSON::GetUtilityString(Protocols)));\r\n        installer.FileExtensions = ConvertToManifestStringArray(JSON::GetRawStringArrayFromJsonNode(installerJsonObject, JSON::GetUtilityString(FileExtensions)));\r\n\r\n        // Dependencies\r\n        std::optional<std::reference_wrapper<const web::json::value>> dependenciesObject =\r\n            JSON::GetJsonValueFromNode(installerJsonObject, JSON::GetUtilityString(Dependencies));\r\n        if (dependenciesObject)\r\n        {\r\n            std::optional<Manifest::DependencyList> dependencyList = DeserializeDependency(dependenciesObject.value().get());\r\n            if (dependencyList)\r\n            {\r\n                installer.Dependencies = std::move(dependencyList.value());\r\n            }\r\n        }\r\n\r\n        installer.PackageFamilyName = JSON::GetRawStringValueFromJsonNode(installerJsonObject, JSON::GetUtilityString(PackageFamilyName)).value_or(\"\");\r\n        installer.ProductCode = JSON::GetRawStringValueFromJsonNode(installerJsonObject, JSON::GetUtilityString(ProductCode)).value_or(\"\");\r\n        installer.Capabilities = ConvertToManifestStringArray(JSON::GetRawStringArrayFromJsonNode(installerJsonObject, JSON::GetUtilityString(Capabilities)));\r\n        installer.RestrictedCapabilities = ConvertToManifestStringArray(JSON::GetRawStringArrayFromJsonNode(installerJsonObject, JSON::GetUtilityString(RestrictedCapabilities)));\r\n\r\n        return installer;\r\n    }\r\n\r\n    std::map<Manifest::InstallerSwitchType, Manifest::string_t> ManifestDeserializer::DeserializeInstallerSwitches(const web::json::value& installerSwitchesJsonObject) const\r\n    {\r\n        std::map<Manifest::InstallerSwitchType, Manifest::string_t> installerSwitches;\r\n\r\n        TryParseInstallerSwitchField(installerSwitches, InstallerSwitchType::Silent, installerSwitchesJsonObject, Silent);\r\n        TryParseInstallerSwitchField(installerSwitches, InstallerSwitchType::SilentWithProgress, installerSwitchesJsonObject, SilentWithProgress);\r\n        TryParseInstallerSwitchField(installerSwitches, InstallerSwitchType::Interactive, installerSwitchesJsonObject, Interactive);\r\n        TryParseInstallerSwitchField(installerSwitches, InstallerSwitchType::InstallLocation, installerSwitchesJsonObject, InstallLocation);\r\n        TryParseInstallerSwitchField(installerSwitches, InstallerSwitchType::Log, installerSwitchesJsonObject, Log);\r\n        TryParseInstallerSwitchField(installerSwitches, InstallerSwitchType::Update, installerSwitchesJsonObject, Upgrade);\r\n        TryParseInstallerSwitchField(installerSwitches, InstallerSwitchType::Custom, installerSwitchesJsonObject, Custom);\r\n\r\n        return installerSwitches;\r\n    }\r\n\r\n    std::optional<Manifest::DependencyList> ManifestDeserializer::DeserializeDependency(const web::json::value& dependenciesObject) const\r\n    {\r\n        if (dependenciesObject.is_null())\r\n        {\r\n            return {};\r\n        }\r\n\r\n        Manifest::DependencyList dependencyList;\r\n\r\n        auto wfIds = ConvertToManifestStringArray(JSON::GetRawStringArrayFromJsonNode(dependenciesObject, JSON::GetUtilityString(WindowsFeatures)));\r\n        for (auto&& id : wfIds)\r\n        {\r\n            dependencyList.Add(Dependency(DependencyType::WindowsFeature, std::move(id)));\r\n        };\r\n\r\n        const auto& wlIds = ConvertToManifestStringArray(JSON::GetRawStringArrayFromJsonNode(dependenciesObject, JSON::GetUtilityString(WindowsLibraries)));\r\n        for (auto id : wlIds)\r\n        {\r\n            dependencyList.Add(Dependency(DependencyType::WindowsLibrary, id));\r\n        };\r\n\r\n        const auto& extIds = ConvertToManifestStringArray(JSON::GetRawStringArrayFromJsonNode(dependenciesObject, JSON::GetUtilityString(ExternalDependencies)));\r\n        for (auto id : extIds)\r\n        {\r\n            dependencyList.Add(Dependency(DependencyType::External, id));\r\n        };\r\n\r\n        // Package Dependencies\r\n        std::optional<std::reference_wrapper<const web::json::array>> packageDependencies = JSON::GetRawJsonArrayFromJsonNode(dependenciesObject, JSON::GetUtilityString(PackageDependencies));\r\n        if (packageDependencies)\r\n        {\r\n            for (auto& packageDependency : packageDependencies.value().get())\r\n            {\r\n                std::optional<std::string> id = JSON::GetRawStringValueFromJsonNode(packageDependency, JSON::GetUtilityString(PackageIdentifier));\r\n                if (id)\r\n                {\r\n                    Dependency pkg{ DependencyType::Package, std::move(id.value()) ,  JSON::GetRawStringValueFromJsonNode(packageDependency, JSON::GetUtilityString(MinimumVersion)).value_or(\"\") };\r\n                    dependencyList.Add(std::move(pkg));\r\n                }\r\n            }\r\n        }\r\n\r\n        return dependencyList;\r\n    }\r\n\r\n    Manifest::InstallerTypeEnum ManifestDeserializer::ConvertToInstallerType(std::string_view in) const\r\n    {\r\n        std::string inStrLower = Utility::ToLower(in);\r\n\r\n        if (inStrLower == \"inno\")\r\n        {\r\n            return InstallerTypeEnum::Inno;\r\n        }\r\n        else if (inStrLower == \"wix\")\r\n        {\r\n            return InstallerTypeEnum::Wix;\r\n        }\r\n        else if (inStrLower == \"msi\")\r\n        {\r\n            return InstallerTypeEnum::Msi;\r\n        }\r\n        else if (inStrLower == \"nullsoft\")\r\n        {\r\n            return InstallerTypeEnum::Nullsoft;\r\n        }\r\n        else if (inStrLower == \"zip\")\r\n        {\r\n            return InstallerTypeEnum::Zip;\r\n        }\r\n        else if (inStrLower == \"appx\" || inStrLower == \"msix\")\r\n        {\r\n            return InstallerTypeEnum::Msix;\r\n        }\r\n        else if (inStrLower == \"exe\")\r\n        {\r\n            return InstallerTypeEnum::Exe;\r\n        }\r\n        else if (inStrLower == \"burn\")\r\n        {\r\n            return InstallerTypeEnum::Burn;\r\n        }\r\n\r\n        return InstallerTypeEnum::Unknown;\r\n    }\r\n\r\n    Manifest::UpdateBehaviorEnum ManifestDeserializer::ConvertToUpdateBehavior(std::string_view in) const\r\n    {\r\n        std::string inStrLower = Utility::ToLower(in);\r\n\r\n        if (inStrLower == \"install\")\r\n        {\r\n            return UpdateBehaviorEnum::Install;\r\n        }\r\n        else if (inStrLower == \"uninstallprevious\")\r\n        {\r\n            return UpdateBehaviorEnum::UninstallPrevious;\r\n        }\r\n\r\n        return UpdateBehaviorEnum::Unknown;\r\n    }\r\n\r\n    std::vector<Manifest::string_t> ManifestDeserializer::ConvertToManifestStringArray(const std::vector<std::string>& values) const\r\n    {\r\n        std::vector<Manifest::string_t> result;\r\n        for (const auto& value : values)\r\n        {\r\n            result.emplace_back(value);\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    Manifest::ManifestVer ManifestDeserializer::GetManifestVersion() const\r\n    {\r\n        return Manifest::s_ManifestVersionV1;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/SearchRequestSerializer.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <cpprest/json.h>\r\n#include \"Rest/Schema/IRestClient.h\"\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_0::Json\r\n{\r\n    // Search Result Serializer.\r\n    struct SearchRequestSerializer\r\n    {\r\n        web::json::value Serialize(const SearchRequest& searchRequest) const;\r\n\r\n    protected:\r\n        std::optional<web::json::value> SerializeSearchRequest(const SearchRequest& searchRequest) const;\r\n\r\n        std::optional<web::json::value> GetRequestMatchJsonObject(const AppInstaller::Repository::RequestMatch& requestMatch) const;\r\n\r\n        std::optional<web::json::value> GetPackageMatchFilterJsonObject(const PackageMatchFilter& packageMatchFilter) const;\r\n\r\n        virtual std::optional<std::string_view> ConvertPackageMatchFieldToString(AppInstaller::Repository::PackageMatchField field) const;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/SearchRequestSerializer_1_0.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Rest/Schema/IRestClient.h\"\r\n#include \"SearchRequestSerializer.h\"\r\n#include <winget/JsonUtil.h>\r\n#include \"Rest/Schema/CommonRestConstants.h\"\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_0::Json\r\n{\r\n    namespace\r\n    {\r\n        // Search request constants\r\n        constexpr std::string_view Query = \"Query\"sv;\r\n        constexpr std::string_view Filters = \"Filters\"sv;\r\n        constexpr std::string_view Inclusions = \"Inclusions\"sv;\r\n        constexpr std::string_view MaximumResults = \"MaximumResults\"sv;\r\n        constexpr std::string_view RequestMatch = \"RequestMatch\"sv;\r\n        constexpr std::string_view KeyWord = \"KeyWord\"sv;\r\n        constexpr std::string_view MatchType = \"MatchType\"sv;\r\n        constexpr std::string_view PackageMatchField = \"PackageMatchField\"sv;\r\n        constexpr std::string_view FetchAllManifests = \"FetchAllManifests\"sv;\r\n\r\n        std::optional<std::string_view> ConvertMatchTypeToString(AppInstaller::Repository::MatchType type)\r\n        {\r\n            // Match types supported by Rest API schema.\r\n            switch (type)\r\n            {\r\n            case MatchType::Exact:\r\n                return \"Exact\"sv;\r\n            case MatchType::CaseInsensitive:\r\n                return \"CaseInsensitive\"sv;\r\n            case MatchType::StartsWith:\r\n                return \"StartsWith\"sv;\r\n            case MatchType::Substring:\r\n                return \"Substring\"sv;\r\n            case MatchType::Wildcard:\r\n                return \"Wildcard\"sv;\r\n            case MatchType::Fuzzy:\r\n                return \"Fuzzy\"sv;\r\n            case MatchType::FuzzySubstring:\r\n                return \"FuzzySubstring\"sv;\r\n            }\r\n\r\n            return {};\r\n        }\r\n    }\r\n\r\n    web::json::value SearchRequestSerializer::Serialize(const SearchRequest& searchRequest) const\r\n    {\r\n        std::optional<web::json::value> result = SerializeSearchRequest(searchRequest);\r\n\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_RESTAPI_INTERNAL_ERROR, !result);\r\n\r\n        return result.value();\r\n    }\r\n\r\n    std::optional<web::json::value> SearchRequestSerializer::SerializeSearchRequest(const SearchRequest& searchRequest) const\r\n    {\r\n        try\r\n        {\r\n            web::json::value json_body;\r\n            if (searchRequest.MaximumResults > 0)\r\n            {\r\n                json_body[JSON::GetUtilityString(MaximumResults)] = searchRequest.MaximumResults;\r\n            }\r\n\r\n            if (searchRequest.IsForEverything())\r\n            {\r\n                json_body[JSON::GetUtilityString(FetchAllManifests)] = web::json::value::boolean(true);\r\n                return json_body;\r\n            }\r\n\r\n            if (searchRequest.Query)\r\n            {\r\n                auto& requestMatch = searchRequest.Query.value();\r\n                web::json::value requestMatchObject = web::json::value::object();\r\n                std::optional<web::json::value> requestMatchJson = GetRequestMatchJsonObject(requestMatch);\r\n                if (requestMatchJson)\r\n                {\r\n                    json_body[JSON::GetUtilityString(Query)] = std::move(requestMatchJson.value());\r\n                }\r\n            }\r\n\r\n            if (!searchRequest.Filters.empty())\r\n            {\r\n                web::json::value filters = web::json::value::array();\r\n\r\n                int i = 0;\r\n                for (auto& filter : searchRequest.Filters)\r\n                {\r\n                    std::optional<web::json::value> jsonObject = GetPackageMatchFilterJsonObject(filter);\r\n\r\n                    if (jsonObject)\r\n                    {\r\n                        filters[i++] = std::move(jsonObject.value());\r\n                    }\r\n                }\r\n\r\n                json_body[JSON::GetUtilityString(Filters)] = filters;\r\n            }\r\n\r\n            if (!searchRequest.Inclusions.empty())\r\n            {\r\n                web::json::value inclusions = web::json::value::array();\r\n\r\n                int i = 0;\r\n                for (auto& inclusion : searchRequest.Inclusions)\r\n                {\r\n                    std::optional<web::json::value> jsonObject = GetPackageMatchFilterJsonObject(inclusion);\r\n\r\n                    if (jsonObject)\r\n                    {\r\n                        inclusions[i++] = std::move(jsonObject.value());\r\n                    }\r\n                }\r\n\r\n                json_body[JSON::GetUtilityString(Inclusions)] = inclusions;\r\n            }\r\n\r\n            return json_body;\r\n        }\r\n        catch (const std::exception& e)\r\n        {\r\n            AICLI_LOG(Repo, Error, << \"Error occurred while serializing search request. Reason: \" << e.what());\r\n        }\r\n        catch (...)\r\n        {\r\n            AICLI_LOG(Repo, Error, << \"Error occurred while serializing search request\");\r\n        }\r\n\r\n        return {};\r\n    }\r\n\r\n    std::optional<web::json::value> SearchRequestSerializer::GetPackageMatchFilterJsonObject(const PackageMatchFilter& packageMatchFilter) const\r\n    {\r\n        web::json::value filter = web::json::value::object();\r\n        std::optional<std::string_view> matchField = ConvertPackageMatchFieldToString(packageMatchFilter.Field);\r\n\r\n        if (!matchField)\r\n        {\r\n            AICLI_LOG(Repo, Warning, << \"Skipping unsupported package match field: \" << packageMatchFilter.Field);\r\n            return {};\r\n        }\r\n\r\n        filter[JSON::GetUtilityString(PackageMatchField)] = web::json::value::string(JSON::GetUtilityString(matchField.value()));\r\n        std::optional<web::json::value> requestMatchJson = GetRequestMatchJsonObject(packageMatchFilter);\r\n\r\n        if (!requestMatchJson)\r\n        {\r\n            AICLI_LOG(Repo, Warning, << \"Skipping unsupported request match object.\");\r\n            return {};\r\n        }\r\n\r\n        filter[JSON::GetUtilityString(RequestMatch)] = std::move(requestMatchJson.value());\r\n        return filter;\r\n    }\r\n\r\n    std::optional<web::json::value> SearchRequestSerializer::GetRequestMatchJsonObject(const AppInstaller::Repository::RequestMatch& requestMatch) const\r\n    {\r\n        web::json::value match = web::json::value::object();\r\n        match[JSON::GetUtilityString(KeyWord)] = web::json::value::string(JSON::GetUtilityString(requestMatch.Value));\r\n\r\n        std::optional<std::string_view> matchType = ConvertMatchTypeToString(requestMatch.Type);\r\n        if (!matchType)\r\n        {\r\n            AICLI_LOG(Repo, Warning, << \"Skipping unsupported match type: \" << requestMatch.Type);\r\n            return {};\r\n        }\r\n\r\n        match[JSON::GetUtilityString(MatchType)] = web::json::value::string(JSON::GetUtilityString(matchType.value()));\r\n        return match;\r\n    }\r\n\r\n    std::optional<std::string_view> SearchRequestSerializer::ConvertPackageMatchFieldToString(AppInstaller::Repository::PackageMatchField field) const\r\n    {\r\n        // Match fields supported by Rest API schema.\r\n        switch (field)\r\n        {\r\n        case PackageMatchField::Command:\r\n            return \"Command\"sv;\r\n        case PackageMatchField::Id:\r\n            return \"PackageIdentifier\"sv;\r\n        case PackageMatchField::Moniker:\r\n            return \"Moniker\"sv;\r\n        case PackageMatchField::Name:\r\n            return \"PackageName\"sv;\r\n        case PackageMatchField::Tag:\r\n            return \"Tag\"sv;\r\n        case PackageMatchField::PackageFamilyName:\r\n            return \"PackageFamilyName\"sv;\r\n        case PackageMatchField::ProductCode:\r\n            return \"ProductCode\"sv;\r\n        case PackageMatchField::NormalizedNameAndPublisher:\r\n            return \"NormalizedPackageNameAndPublisher\"sv;\r\n        }\r\n\r\n        return {};\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/SearchResponseDeserializer.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <cpprest/json.h>\r\n#include \"Rest/Schema/IRestClient.h\"\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_0::Json\r\n{\r\n    // Search Result Deserializer.\r\n    struct SearchResponseDeserializer\r\n    {\r\n        // Gets the search result for given version\r\n        IRestClient::SearchResult Deserialize(const web::json::value& searchResultJsonObject) const;\r\n\r\n    protected:\r\n        virtual std::optional<IRestClient::SearchResult> DeserializeSearchResult(const web::json::value& searchResultJsonObject) const;\r\n        virtual std::optional<IRestClient::VersionInfo> DeserializeVersionInfo(const web::json::value& versionInfoJsonObject) const;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_0/Json/SearchResponseDeserializer_1_0.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Rest/Schema/CommonRestConstants.h\"\r\n#include \"Rest/Schema/IRestClient.h\"\r\n#include \"SearchResponseDeserializer.h\"\r\n#include <winget/JsonUtil.h>\r\n#include <winget/Rest.h>\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_0::Json\r\n{\r\n    namespace\r\n    {\r\n        // Search response constants\r\n        constexpr std::string_view PackageIdentifier = \"PackageIdentifier\"sv;\r\n        constexpr std::string_view PackageName = \"PackageName\"sv;\r\n        constexpr std::string_view Publisher = \"Publisher\"sv;\r\n        constexpr std::string_view PackageFamilyNames = \"PackageFamilyNames\"sv;\r\n        constexpr std::string_view ProductCodes = \"ProductCodes\"sv;\r\n        constexpr std::string_view Versions = \"Versions\"sv;\r\n        constexpr std::string_view PackageVersion = \"PackageVersion\"sv;\r\n        constexpr std::string_view Channel = \"Channel\"sv;\r\n    }\r\n\r\n    IRestClient::SearchResult SearchResponseDeserializer::Deserialize(const web::json::value& searchResponseObject) const\r\n    {\r\n        std::optional<IRestClient::SearchResult> response = DeserializeSearchResult(searchResponseObject);\r\n\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA, !response);\r\n\r\n        return response.value();\r\n    }\r\n\r\n    std::optional<IRestClient::SearchResult> SearchResponseDeserializer::DeserializeSearchResult(const web::json::value& searchResponseObject) const\r\n    {\r\n        // Make search result from json output.\r\n        if (searchResponseObject.is_null())\r\n        {\r\n            AICLI_LOG(Repo, Error, << \"Missing json object.\");\r\n            return {};\r\n        }\r\n\r\n        IRestClient::SearchResult result;\r\n        try\r\n        {\r\n            std::optional<std::reference_wrapper<const web::json::array>> dataArray = JSON::GetRawJsonArrayFromJsonNode(searchResponseObject, JSON::GetUtilityString(Data));\r\n            if (!dataArray || dataArray.value().get().size() == 0)\r\n            {\r\n                AICLI_LOG(Repo, Verbose, << \"No search results returned.\");\r\n                return result;\r\n            }\r\n\r\n            for (auto& manifestItem : dataArray.value().get())\r\n            {\r\n                std::optional<std::string> packageId = JSON::GetRawStringValueFromJsonNode(manifestItem, JSON::GetUtilityString(PackageIdentifier));\r\n                std::optional<std::string> packageName = JSON::GetRawStringValueFromJsonNode(manifestItem, JSON::GetUtilityString(PackageName));\r\n                std::optional<std::string> publisher = JSON::GetRawStringValueFromJsonNode(manifestItem, JSON::GetUtilityString(Publisher));\r\n\r\n                if (!JSON::IsValidNonEmptyStringValue(packageId) || !JSON::IsValidNonEmptyStringValue(packageName) || !JSON::IsValidNonEmptyStringValue(publisher))\r\n                {\r\n                    AICLI_LOG(Repo, Error, << \"Missing required package fields in manifest search results.\");\r\n                    return {};\r\n                }\r\n\r\n                std::optional<std::reference_wrapper<const web::json::array>> versionValue = JSON::GetRawJsonArrayFromJsonNode(manifestItem, JSON::GetUtilityString(Versions));\r\n                std::vector<IRestClient::VersionInfo> versionList;\r\n\r\n                if (versionValue)\r\n                {\r\n                    for (auto& versionItem : versionValue.value().get())\r\n                    {\r\n                        auto versionInfo = DeserializeVersionInfo(versionItem);\r\n                        if (!versionInfo.has_value())\r\n                        {\r\n                            AICLI_LOG(Repo, Error, << \"Received incomplete package version in package: \" << packageId.value());\r\n                            return {};\r\n                        }\r\n\r\n                        versionList.emplace_back(std::move(*versionInfo));\r\n                    }\r\n                }\r\n\r\n                if (versionList.size() == 0)\r\n                {\r\n                    AICLI_LOG(Repo, Error, << \"Received no versions in package: \" << packageId.value());\r\n                    return {};\r\n                }\r\n\r\n                IRestClient::PackageInfo packageInfo{\r\n                        std::move(packageId.value()), std::move(packageName.value()), std::move(publisher.value()) };\r\n                IRestClient::Package package{ std::move(packageInfo), std::move(versionList) };\r\n                result.Matches.emplace_back(std::move(package));\r\n            }\r\n\r\n            return result;\r\n        }\r\n        catch (const std::exception& e)\r\n        {\r\n            AICLI_LOG(Repo, Error, << \"Error encountered while deserializing search result. Reason: \" << e.what());\r\n        }\r\n        catch (...)\r\n        {\r\n            AICLI_LOG(Repo, Error, << \"Error encountered while deserializing search result...\");\r\n        }\r\n\r\n        return {};\r\n    }\r\n\r\n    std::optional<IRestClient::VersionInfo> SearchResponseDeserializer::DeserializeVersionInfo(const web::json::value& versionInfoJsonObject) const\r\n    {\r\n        std::optional<std::string> version = JSON::GetRawStringValueFromJsonNode(versionInfoJsonObject, JSON::GetUtilityString(PackageVersion));\r\n        if (!JSON::IsValidNonEmptyStringValue(version))\r\n        {\r\n            AICLI_LOG(Repo, Error, << \"Received incomplete package version\");\r\n            return {};\r\n        }\r\n\r\n        std::string channel = JSON::GetRawStringValueFromJsonNode(versionInfoJsonObject, JSON::GetUtilityString(Channel)).value_or(\"\");\r\n        std::vector<std::string> packageFamilyNames = AppInstaller::Rest::GetUniqueItems(JSON::GetRawStringArrayFromJsonNode(versionInfoJsonObject, JSON::GetUtilityString(PackageFamilyNames)));\r\n        std::vector<std::string> productCodes = AppInstaller::Rest::GetUniqueItems(JSON::GetRawStringArrayFromJsonNode(versionInfoJsonObject, JSON::GetUtilityString(ProductCodes)));\r\n\r\n        return IRestClient::VersionInfo{\r\n            AppInstaller::Utility::VersionAndChannel{std::move(version.value()), std::move(channel)},\r\n            {},\r\n            std::move(packageFamilyNames),\r\n            std::move(productCodes) };\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_0/RestInterface_1_0.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Rest/Schema/1_0/Interface.h\"\r\n#include \"Rest/Schema/IRestClient.h\"\r\n#include <winget/HttpClientHelper.h>\r\n#include <winget/JsonUtil.h>\r\n#include <winget/ManifestJSONParser.h>\r\n#include <winget/ManifestValidation.h>\r\n#include <winget/Rest.h>\r\n#include \"Rest/Schema/CommonRestConstants.h\"\r\n#include \"Rest/Schema/SearchResponseParser.h\"\r\n#include \"Rest/Schema/SearchRequestComposer.h\"\r\n\r\nusing namespace std::string_view_literals;\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_0\r\n{\r\n    namespace\r\n    {\r\n        // Query params\r\n        constexpr std::string_view VersionQueryParam = \"Version\"sv;\r\n        constexpr std::string_view ChannelQueryParam = \"Channel\"sv;\r\n\r\n        utility::string_t GetSearchEndpoint(const std::string& restApiUri)\r\n        {\r\n            return AppInstaller::Rest::AppendPathToUri(AppInstaller::JSON::GetUtilityString(restApiUri), AppInstaller::JSON::GetUtilityString(ManifestSearchPostEndpoint));\r\n        }\r\n\r\n        utility::string_t GetManifestByVersionEndpoint(\r\n            const std::string& restApiUri, const std::string& packageId, const std::map<std::string_view, std::string>& queryParameters)\r\n        {\r\n            utility::string_t getManifestEndpoint = AppInstaller::Rest::AppendPathToUri(\r\n                AppInstaller::JSON::GetUtilityString(restApiUri), AppInstaller::JSON::GetUtilityString(ManifestByVersionAndChannelGetEndpoint));\r\n\r\n            utility::string_t getManifestWithPackageIdPath = AppInstaller::Rest::AppendPathToUri(getManifestEndpoint, AppInstaller::JSON::GetUtilityString(packageId));\r\n\r\n            // Create the endpoint with query parameters\r\n            return AppInstaller::Rest::AppendQueryParamsToUri(getManifestWithPackageIdPath, queryParameters);\r\n        }\r\n\r\n        std::optional<utility::string_t> GetContinuationToken(const web::json::value& jsonObject)\r\n        {\r\n            std::optional<std::string> continuationToken = AppInstaller::JSON::GetRawStringValueFromJsonNode(jsonObject, AppInstaller::JSON::GetUtilityString(ContinuationToken));\r\n\r\n            if (continuationToken)\r\n            {\r\n                return utility::conversions::to_string_t(continuationToken.value());\r\n            }\r\n\r\n            return {};\r\n        }\r\n\r\n        AppInstaller::Http::HttpClientHelper::HttpResponseHandlerResult CustomRestCallResponseHandler(const web::http::http_response& response)\r\n        {\r\n            AppInstaller::Http::HttpClientHelper::HttpResponseHandlerResult result;\r\n            result.UseDefaultHandling = true;\r\n\r\n            if (response.status_code() == web::http::status_codes::NotFound &&\r\n                response.headers().content_type()._Starts_with(web::http::details::mime_types::application_json))\r\n            {\r\n                auto responseJson = response.extract_json().get();\r\n                if (responseJson.is_object() && responseJson.has_field(L\"code\") && responseJson.has_field(L\"message\"))\r\n                {\r\n                    // We'll treat 404 with json response containing code and message fields as empty result.\r\n                    // Leave the HttpResponseHandlerResult result empty and disable default HttpClientHelper handling.\r\n                    result.UseDefaultHandling = false;\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n\r\n    Interface::Interface(const std::string& restApi, const Http::HttpClientHelper& httpClientHelper) : m_restApiUri(restApi), m_httpClientHelper(httpClientHelper)\r\n    {\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_URL, !AppInstaller::Rest::IsValidUri(AppInstaller::JSON::GetUtilityString(restApi)));\r\n\r\n        m_searchEndpoint = GetSearchEndpoint(m_restApiUri);\r\n        m_requiredRestApiHeaders.emplace(AppInstaller::JSON::GetUtilityString(ContractVersion), AppInstaller::JSON::GetUtilityString(Version_1_0_0.ToString()));\r\n    }\r\n\r\n    Utility::Version Interface::GetVersion() const\r\n    {\r\n        return Version_1_0_0;\r\n    }\r\n\r\n    IRestClient::Information Interface::GetSourceInformation() const\r\n    {\r\n        return {};\r\n    }\r\n\r\n    IRestClient::SearchResult Interface::Search(const SearchRequest& request) const\r\n    {\r\n        // Optimization\r\n        if (MeetsOptimizedSearchCriteria(request))\r\n        {\r\n            return OptimizedSearch(request);\r\n        }\r\n\r\n        return SearchInternal(request);\r\n    }\r\n\r\n    IRestClient::SearchResult Interface::SearchInternal(const SearchRequest& request) const\r\n    {\r\n        SearchResult results;\r\n        utility::string_t continuationToken;\r\n        Http::HttpClientHelper::HttpRequestHeaders searchHeaders = m_requiredRestApiHeaders;\r\n        do\r\n        {\r\n            if (!continuationToken.empty())\r\n            {\r\n                AICLI_LOG(Repo, Verbose, << \"Received continuation token. Retrieving more results.\");\r\n                searchHeaders.insert_or_assign(AppInstaller::JSON::GetUtilityString(ContinuationToken), continuationToken);\r\n            }\r\n\r\n            std::optional<web::json::value> jsonObject = m_httpClientHelper.HandlePost(m_searchEndpoint, GetValidatedSearchBody(request), searchHeaders, GetAuthHeaders(), CustomRestCallResponseHandler);\r\n\r\n            utility::string_t ct;\r\n            if (jsonObject)\r\n            {\r\n                SearchResult currentResult = GetSearchResult(jsonObject.value());\r\n\r\n                size_t insertElements = !request.MaximumResults ? currentResult.Matches.size() :\r\n                    std::min(currentResult.Matches.size(), request.MaximumResults - results.Matches.size());\r\n\r\n                if (insertElements < currentResult.Matches.size())\r\n                {\r\n                    results.Truncated = true;\r\n                }\r\n\r\n                std::move(currentResult.Matches.begin(), std::next(currentResult.Matches.begin(), insertElements), std::inserter(results.Matches, results.Matches.end()));\r\n                ct = GetContinuationToken(jsonObject.value()).value_or(L\"\");\r\n            }\r\n\r\n            continuationToken = ct;\r\n\r\n        } while (!continuationToken.empty() && (!request.MaximumResults || results.Matches.size() < request.MaximumResults));\r\n\r\n        if (!continuationToken.empty())\r\n        {\r\n            results.Truncated = true;\r\n        }\r\n\r\n        if (results.Matches.empty())\r\n        {\r\n            AICLI_LOG(Repo, Verbose, << \"No search results returned by rest source\");\r\n        }\r\n\r\n        return results;\r\n    }\r\n\r\n    std::optional<Manifest::Manifest> Interface::GetManifestByVersion(const std::string& packageId, const std::string& version, const std::string& channel) const\r\n    {\r\n        std::map<std::string_view, std::string> queryParams;\r\n        if (!version.empty())\r\n        {\r\n            queryParams.emplace(VersionQueryParam, version);\r\n        }\r\n\r\n        if (!channel.empty())\r\n        {\r\n            queryParams.emplace(ChannelQueryParam, channel);\r\n        }\r\n\r\n        std::vector<Manifest::Manifest> manifests = GetManifests(packageId, queryParams);\r\n\r\n        if (!manifests.empty())\r\n        {\r\n            for (Manifest::Manifest manifest : manifests)\r\n            {\r\n                if (Utility::CaseInsensitiveEquals(manifest.Version, version) &&\r\n                    Utility::CaseInsensitiveEquals(manifest.Channel, channel))\r\n                {\r\n                    return manifest;\r\n                }\r\n            }\r\n        }\r\n\r\n        return {};\r\n    }\r\n\r\n    bool Interface::MeetsOptimizedSearchCriteria(const SearchRequest& request) const\r\n    {\r\n        // Optimization: If the user wants to install a certain package with an exact match on package id and a particular rest source, we will\r\n        // call the package manifest endpoint to get the manifest directly instead of running a search for it.\r\n        if (!request.Query && request.Inclusions.size() == 0 &&\r\n            request.Filters.size() == 1 && request.Filters[0].Field == PackageMatchField::Id &&\r\n            (request.Filters[0].Type == MatchType::Exact || request.Filters[0].Type == MatchType::CaseInsensitive))\r\n        {\r\n            AICLI_LOG(Repo, Verbose, << \"Search request meets optimized search criteria.\");\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    IRestClient::SearchResult Interface::OptimizedSearch(const SearchRequest& request) const\r\n    {\r\n        SearchResult searchResult;\r\n        std::vector<Manifest::Manifest> manifests = GetManifests(request.Filters[0].Value);\r\n\r\n        if (!manifests.empty())\r\n        {\r\n            auto& manifest = manifests.at(0);\r\n            PackageInfo packageInfo = PackageInfo{\r\n                manifest.Id,\r\n                manifest.DefaultLocalization.Get<AppInstaller::Manifest::Localization::PackageName>(),\r\n                manifest.DefaultLocalization.Get<AppInstaller::Manifest::Localization::Publisher>() };\r\n\r\n            // Add all the versions to the package info object\r\n            std::vector<VersionInfo> versions;\r\n            for (auto& manifestVersion : manifests)\r\n            {\r\n                auto packageFamilyNames = manifestVersion.GetPackageFamilyNames();\r\n                auto productCodes = manifestVersion.GetProductCodes();\r\n                auto arpVersionRange = manifestVersion.GetArpVersionRange();\r\n                auto upgradeCodes = manifestVersion.GetUpgradeCodes();\r\n\r\n                versions.emplace_back(\r\n                    VersionInfo{\r\n                        AppInstaller::Utility::VersionAndChannel {manifestVersion.Version, manifestVersion.Channel},\r\n                        manifestVersion,\r\n                        std::vector<std::string>{ packageFamilyNames.begin(), packageFamilyNames.end()},\r\n                        std::vector<std::string>{ productCodes.begin(), productCodes.end()},\r\n                        arpVersionRange.IsEmpty() ? std::vector<Utility::Version>{} : std::vector<Utility::Version>{ arpVersionRange.GetMinVersion(), arpVersionRange.GetMaxVersion() },\r\n                        std::vector<std::string>{ upgradeCodes.begin(), upgradeCodes.end()} });\r\n            }\r\n\r\n            Package package = Package{ std::move(packageInfo), std::move(versions) };\r\n            searchResult.Matches.emplace_back(std::move(package));\r\n        }\r\n\r\n        return searchResult;\r\n    }\r\n\r\n    std::vector<Manifest::Manifest> Interface::GetManifests(const std::string& packageId, const std::map<std::string_view, std::string>& params) const\r\n    {\r\n        auto validatedParams = GetValidatedQueryParams(params);\r\n\r\n        std::vector<Manifest::Manifest> results;\r\n        utility::string_t continuationToken;\r\n        Http::HttpClientHelper::HttpRequestHeaders searchHeaders = m_requiredRestApiHeaders;\r\n        std::optional<web::json::value> jsonObject = m_httpClientHelper.HandleGet(GetManifestByVersionEndpoint(m_restApiUri, packageId, validatedParams), searchHeaders, GetAuthHeaders(), CustomRestCallResponseHandler);\r\n\r\n        if (!jsonObject)\r\n        {\r\n            AICLI_LOG(Repo, Verbose, << \"No results were returned by the rest source for package id: \" << packageId);\r\n            return results;\r\n        }\r\n\r\n        // Parse json and return Manifests\r\n        std::vector<Manifest::Manifest> manifests = GetParsedManifests(jsonObject.value());\r\n\r\n        // Manifest validation\r\n        for (auto& manifestItem : manifests)\r\n        {\r\n            std::vector<AppInstaller::Manifest::ValidationError> validationErrors =\r\n                AppInstaller::Manifest::ValidateManifest(manifestItem, false);\r\n\r\n            int errors = 0;\r\n            for (auto& error : validationErrors)\r\n            {\r\n                if (error.ErrorLevel == Manifest::ValidationError::Level::Error)\r\n                {\r\n                    AICLI_LOG(Repo, Error, << \"Received manifest contains validation error: \" << error.GetErrorMessage());\r\n                    errors++;\r\n                }\r\n            }\r\n\r\n            THROW_HR_IF(APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA, errors > 0);\r\n\r\n            results.emplace_back(manifestItem);\r\n        }\r\n\r\n        return results;\r\n    }\r\n\r\n    std::map<std::string_view, std::string> Interface::GetValidatedQueryParams(const std::map<std::string_view, std::string>& params) const\r\n    {\r\n        return params;\r\n    }\r\n\r\n    web::json::value Interface::GetValidatedSearchBody(const SearchRequest& searchRequest) const\r\n    {\r\n        SearchRequestComposer searchRequestComposer{ GetVersion() };\r\n        return searchRequestComposer.Serialize(searchRequest);\r\n    }\r\n\r\n    IRestClient::SearchResult Interface::GetSearchResult(const web::json::value& searchResponseObject) const\r\n    {\r\n        SearchResponseParser searchResponseParser{ GetVersion() };\r\n        return searchResponseParser.Deserialize(searchResponseObject);\r\n    }\r\n\r\n    std::vector<Manifest::Manifest> Interface::GetParsedManifests(const web::json::value& manifestsResponseObject) const\r\n    {\r\n        JSON::ManifestJSONParser manifestParser{ GetVersion() };\r\n        return manifestParser.Deserialize(manifestsResponseObject);\r\n    }\r\n\r\n    Http::HttpClientHelper::HttpRequestHeaders Interface::GetAuthHeaders() const\r\n    {\r\n        return {};\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_1/Interface.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Rest/Schema/1_0/Interface.h\"\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_1\r\n{\r\n    // Interface to this schema version exposed through IRestClient.\r\n    struct Interface : public V1_0::Interface\r\n    {\r\n        Interface(const std::string& restApi, const Http::HttpClientHelper& helper, IRestClient::Information information, const Http::HttpClientHelper::HttpRequestHeaders& additionalHeaders = {});\r\n\r\n        Interface(const Interface&) = delete;\r\n        Interface& operator=(const Interface&) = delete;\r\n\r\n        Interface(Interface&&) = default;\r\n        Interface& operator=(Interface&&) = default;\r\n\r\n        Utility::Version GetVersion() const override;\r\n        IRestClient::Information GetSourceInformation() const override;\r\n\r\n    protected:\r\n        // Check query params against source information and update if necessary.\r\n        std::map<std::string_view, std::string> GetValidatedQueryParams(const std::map<std::string_view, std::string>& params) const override;\r\n\r\n        // Check search request against source information and get json search body.\r\n        web::json::value GetValidatedSearchBody(const SearchRequest& searchRequest) const override;\r\n\r\n        SearchResult GetSearchResult(const web::json::value& searchResponseObject) const override;\r\n        std::vector<Manifest::Manifest> GetParsedManifests(const web::json::value& manifestsResponseObject) const override;\r\n\r\n        PackageMatchField ConvertStringToPackageMatchField(std::string_view field) const;\r\n\r\n        IRestClient::Information m_information;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_1/Json/ManifestDeserializer.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Rest/Schema/1_0/Json/ManifestDeserializer.h\"\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_1::Json\r\n{\r\n    // Manifest Deserializer.\r\n    struct ManifestDeserializer : public V1_0::Json::ManifestDeserializer\r\n    {\r\n        std::vector<Manifest::AppsAndFeaturesEntry> DeserializeAppsAndFeaturesEntries(const web::json::array& entries) const override;\r\n\r\n        std::optional<Manifest::ManifestLocalization> DeserializeLocale(const web::json::value& localeJsonObject) const override;\r\n\r\n    protected:\r\n        std::optional<Manifest::ManifestInstaller> DeserializeInstaller(const web::json::value& installerJsonObject) const override;\r\n\r\n        Manifest::InstallerTypeEnum ConvertToInstallerType(std::string_view in) const override;\r\n\r\n        virtual Manifest::ExpectedReturnCodeEnum ConvertToExpectedReturnCodeEnum(std::string_view in) const;\r\n\r\n        virtual Manifest::ManifestInstaller::ExpectedReturnCodeInfo DeserializeExpectedReturnCodeInfo(const web::json::value& expectedReturnCodeJsonObject) const;\r\n\r\n        Manifest::ManifestVer GetManifestVersion() const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_1/Json/ManifestDeserializer_1_1.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ManifestDeserializer.h\"\r\n#include <winget/JsonUtil.h>\r\n\r\nusing namespace AppInstaller::Manifest;\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_1::Json\r\n{\r\n    namespace\r\n    {\r\n        // Installer\r\n        constexpr std::string_view MSStoreProductIdentifier = \"MSStoreProductIdentifier\"sv;\r\n        constexpr std::string_view ReleaseDate = \"ReleaseDate\"sv;\r\n        constexpr std::string_view InstallerAbortsTerminal = \"InstallerAbortsTerminal\"sv;\r\n        constexpr std::string_view InstallLocationRequired = \"InstallLocationRequired\"sv;\r\n        constexpr std::string_view RequireExplicitUpgrade = \"RequireExplicitUpgrade\"sv;\r\n        constexpr std::string_view UnsupportedOSArchitectures = \"UnsupportedOSArchitectures\"sv;\r\n        constexpr std::string_view AppsAndFeaturesEntries = \"AppsAndFeaturesEntries\"sv;\r\n        constexpr std::string_view DisplayName = \"DisplayName\"sv;\r\n        constexpr std::string_view Publisher = \"Publisher\"sv;\r\n        constexpr std::string_view DisplayVersion = \"DisplayVersion\"sv;\r\n        constexpr std::string_view ProductCode = \"ProductCode\"sv;\r\n        constexpr std::string_view UpgradeCode = \"UpgradeCode\"sv;\r\n        constexpr std::string_view InstallerType = \"InstallerType\"sv;\r\n        constexpr std::string_view Markets = \"Markets\"sv;\r\n        constexpr std::string_view AllowedMarkets = \"AllowedMarkets\"sv;\r\n        constexpr std::string_view ExcludedMarkets = \"ExcludedMarkets\"sv;\r\n        constexpr std::string_view ElevationRequirement = \"ElevationRequirement\"sv;\r\n        constexpr std::string_view ExpectedReturnCodes = \"ExpectedReturnCodes\"sv;\r\n        constexpr std::string_view InstallerReturnCode = \"InstallerReturnCode\"sv;\r\n        constexpr std::string_view ReturnResponse = \"ReturnResponse\"sv;\r\n\r\n        // Locale\r\n        constexpr std::string_view ReleaseNotes = \"ReleaseNotes\"sv;\r\n        constexpr std::string_view ReleaseNotesUrl = \"ReleaseNotesUrl\"sv;\r\n        constexpr std::string_view Agreements = \"Agreements\"sv;\r\n        constexpr std::string_view AgreementLabel = \"AgreementLabel\"sv;\r\n        constexpr std::string_view Agreement = \"Agreement\"sv;\r\n        constexpr std::string_view AgreementUrl = \"AgreementUrl\"sv;\r\n    }\r\n\r\n    std::vector<Manifest::AppsAndFeaturesEntry> ManifestDeserializer::DeserializeAppsAndFeaturesEntries(const web::json::array& entries) const\r\n    {\r\n        std::vector<Manifest::AppsAndFeaturesEntry> result;\r\n\r\n        for (auto& arpEntryNode : entries)\r\n        {\r\n            AppsAndFeaturesEntry arpEntry;\r\n            arpEntry.DisplayName = JSON::GetRawStringValueFromJsonNode(arpEntryNode, JSON::GetUtilityString(DisplayName)).value_or(\"\");\r\n            arpEntry.Publisher = JSON::GetRawStringValueFromJsonNode(arpEntryNode, JSON::GetUtilityString(Publisher)).value_or(\"\");\r\n            arpEntry.DisplayVersion = JSON::GetRawStringValueFromJsonNode(arpEntryNode, JSON::GetUtilityString(DisplayVersion)).value_or(\"\");\r\n            arpEntry.ProductCode = JSON::GetRawStringValueFromJsonNode(arpEntryNode, JSON::GetUtilityString(ProductCode)).value_or(\"\");\r\n            arpEntry.UpgradeCode = JSON::GetRawStringValueFromJsonNode(arpEntryNode, JSON::GetUtilityString(UpgradeCode)).value_or(\"\");\r\n            arpEntry.InstallerType = ConvertToInstallerType(JSON::GetRawStringValueFromJsonNode(arpEntryNode, JSON::GetUtilityString(InstallerType)).value_or(\"\"));\r\n\r\n            // Only add when at least one field is valid\r\n            if (!arpEntry.DisplayName.empty() || !arpEntry.Publisher.empty() || !arpEntry.DisplayVersion.empty() ||\r\n                !arpEntry.ProductCode.empty() || !arpEntry.UpgradeCode.empty() || arpEntry.InstallerType != InstallerTypeEnum::Unknown)\r\n            {\r\n                result.emplace_back(std::move(arpEntry));\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    Manifest::InstallerTypeEnum ManifestDeserializer::ConvertToInstallerType(std::string_view in) const\r\n    {\r\n        std::string inStrLower = Utility::ToLower(in);\r\n\r\n        if (inStrLower == \"msstore\")\r\n        {\r\n            return InstallerTypeEnum::MSStore;\r\n        }\r\n\r\n        return V1_0::Json::ManifestDeserializer::ConvertToInstallerType(inStrLower);\r\n    }\r\n\r\n    Manifest::ExpectedReturnCodeEnum ManifestDeserializer::ConvertToExpectedReturnCodeEnum(std::string_view in) const\r\n    {\r\n        std::string inStrLower = Utility::ToLower(in);\r\n        ExpectedReturnCodeEnum result = ExpectedReturnCodeEnum::Unknown;\r\n\r\n        if (inStrLower == \"packageinuse\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::PackageInUse;\r\n        }\r\n        else if (inStrLower == \"installinprogress\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::InstallInProgress;\r\n        }\r\n        else if (inStrLower == \"fileinuse\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::FileInUse;\r\n        }\r\n        else if (inStrLower == \"missingdependency\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::MissingDependency;\r\n        }\r\n        else if (inStrLower == \"diskfull\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::DiskFull;\r\n        }\r\n        else if (inStrLower == \"insufficientmemory\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::InsufficientMemory;\r\n        }\r\n        else if (inStrLower == \"nonetwork\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::NoNetwork;\r\n        }\r\n        else if (inStrLower == \"contactsupport\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::ContactSupport;\r\n        }\r\n        else if (inStrLower == \"rebootrequiredtofinish\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::RebootRequiredToFinish;\r\n        }\r\n        else if (inStrLower == \"rebootrequiredforinstall\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::RebootRequiredForInstall;\r\n        }\r\n        else if (inStrLower == \"rebootinitiated\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::RebootInitiated;\r\n        }\r\n        else if (inStrLower == \"cancelledbyuser\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::CancelledByUser;\r\n        }\r\n        else if (inStrLower == \"alreadyinstalled\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::AlreadyInstalled;\r\n        }\r\n        else if (inStrLower == \"downgrade\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::Downgrade;\r\n        }\r\n        else if (inStrLower == \"blockedbypolicy\")\r\n        {\r\n            result = ExpectedReturnCodeEnum::BlockedByPolicy;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    Manifest::ManifestInstaller::ExpectedReturnCodeInfo ManifestDeserializer::DeserializeExpectedReturnCodeInfo(const web::json::value& expectedReturnCodeJsonObject) const\r\n    {\r\n        ExpectedReturnCodeEnum returnResponse = ConvertToExpectedReturnCodeEnum(JSON::GetRawStringValueFromJsonNode(expectedReturnCodeJsonObject, JSON::GetUtilityString(ReturnResponse)).value_or(\"\"));\r\n        \r\n        return { returnResponse, \"\" };\r\n    }\r\n\r\n    std::optional<Manifest::ManifestInstaller> ManifestDeserializer::DeserializeInstaller(const web::json::value& installerJsonObject) const\r\n    {\r\n        auto result = V1_0::Json::ManifestDeserializer::DeserializeInstaller(installerJsonObject);\r\n\r\n        if (result)\r\n        {\r\n            auto& installer = result.value();\r\n\r\n            installer.ProductId = JSON::GetRawStringValueFromJsonNode(installerJsonObject, JSON::GetUtilityString(MSStoreProductIdentifier)).value_or(\"\");\r\n            installer.ReleaseDate = JSON::GetRawStringValueFromJsonNode(installerJsonObject, JSON::GetUtilityString(ReleaseDate)).value_or(\"\");\r\n            installer.InstallerAbortsTerminal = JSON::GetRawBoolValueFromJsonNode(installerJsonObject, JSON::GetUtilityString(InstallerAbortsTerminal)).value_or(false);\r\n            installer.InstallLocationRequired = JSON::GetRawBoolValueFromJsonNode(installerJsonObject, JSON::GetUtilityString(InstallLocationRequired)).value_or(false);\r\n            installer.RequireExplicitUpgrade = JSON::GetRawBoolValueFromJsonNode(installerJsonObject, JSON::GetUtilityString(RequireExplicitUpgrade)).value_or(false);\r\n            installer.ElevationRequirement = Manifest::ConvertToElevationRequirementEnum(\r\n                JSON::GetRawStringValueFromJsonNode(installerJsonObject, JSON::GetUtilityString(ElevationRequirement)).value_or(\"\"));\r\n\r\n            // list of unsupported OS architectures\r\n            std::optional<std::reference_wrapper<const web::json::array>> unsupportedOSArchitectures = JSON::GetRawJsonArrayFromJsonNode(installerJsonObject, JSON::GetUtilityString(UnsupportedOSArchitectures));\r\n            if (unsupportedOSArchitectures)\r\n            {\r\n                for (auto& archValue : unsupportedOSArchitectures.value().get())\r\n                {\r\n                    std::optional<std::string> arch = JSON::GetRawStringValueFromJsonValue(archValue);\r\n                    if (JSON::IsValidNonEmptyStringValue(arch))\r\n                    {\r\n                        auto archEnum = Utility::ConvertToArchitectureEnum(arch.value());\r\n\r\n                        if (archEnum == Utility::Architecture::Neutral)\r\n                        {\r\n                            AICLI_LOG(Repo, Error, << \"Unsupported OS architectures cannot contain neutral value.\");\r\n                            return {};\r\n                        }\r\n\r\n                        if (archEnum != Utility::Architecture::Unknown)\r\n                        {\r\n                            installer.UnsupportedOSArchitectures.emplace_back(archEnum);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Apps and Features Entries\r\n            std::optional<std::reference_wrapper<const web::json::array>> arpEntriesNode = JSON::GetRawJsonArrayFromJsonNode(installerJsonObject, JSON::GetUtilityString(AppsAndFeaturesEntries));\r\n            if (arpEntriesNode)\r\n            {\r\n                installer.AppsAndFeaturesEntries = DeserializeAppsAndFeaturesEntries(arpEntriesNode.value());\r\n            }\r\n\r\n            // Markets\r\n            std::optional<std::reference_wrapper<const web::json::value>> marketsNode = JSON::GetJsonValueFromNode(installerJsonObject, JSON::GetUtilityString(Markets));\r\n            if (marketsNode && !marketsNode.value().get().is_null())\r\n            {\r\n                installer.Markets.ExcludedMarkets = V1_0::Json::ManifestDeserializer::ConvertToManifestStringArray(\r\n                    JSON::GetRawStringArrayFromJsonNode(marketsNode.value().get(), JSON::GetUtilityString(ExcludedMarkets)));\r\n                installer.Markets.AllowedMarkets = V1_0::Json::ManifestDeserializer::ConvertToManifestStringArray(\r\n                    JSON::GetRawStringArrayFromJsonNode(marketsNode.value().get(), JSON::GetUtilityString(AllowedMarkets)));\r\n            }\r\n\r\n            // Expected return codes\r\n            std::optional<std::reference_wrapper<const web::json::array>> expectedReturnCodesNode = JSON::GetRawJsonArrayFromJsonNode(installerJsonObject, JSON::GetUtilityString(ExpectedReturnCodes));\r\n            if (expectedReturnCodesNode)\r\n            {\r\n                for (auto& returnCodeNode : expectedReturnCodesNode.value().get())\r\n                {\r\n                    DWORD installerReturnCode = static_cast<DWORD>(JSON::GetRawIntValueFromJsonNode(returnCodeNode, JSON::GetUtilityString(InstallerReturnCode)).value_or(0));\r\n                    auto returnCodeInfo = DeserializeExpectedReturnCodeInfo(returnCodeNode);\r\n\r\n                    // Only add when it is valid\r\n                    if (installerReturnCode != 0 && returnCodeInfo.ReturnResponseEnum != ExpectedReturnCodeEnum::Unknown)\r\n                    {\r\n                        if (!installer.ExpectedReturnCodes.insert({ installerReturnCode, std::move(returnCodeInfo) }).second)\r\n                        {\r\n                            AICLI_LOG(Repo, Error, << \"Expected return codes cannot have repeated value.\");\r\n                            return {};\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Populate installer default return codes if not present in ExpectedReturnCodes and InstallerSuccessCodes\r\n            auto defaultReturnCodes = GetDefaultKnownReturnCodes(installer.EffectiveInstallerType());\r\n            for (auto const& defaultReturnCode : defaultReturnCodes)\r\n            {\r\n                if (installer.ExpectedReturnCodes.find(defaultReturnCode.first) == installer.ExpectedReturnCodes.end() &&\r\n                    std::find(installer.InstallerSuccessCodes.begin(), installer.InstallerSuccessCodes.end(), defaultReturnCode.first) == installer.InstallerSuccessCodes.end())\r\n                {\r\n                    installer.ExpectedReturnCodes[defaultReturnCode.first].ReturnResponseEnum = defaultReturnCode.second;\r\n                }\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::optional<Manifest::ManifestLocalization> ManifestDeserializer::DeserializeLocale(const web::json::value& localeJsonObject) const\r\n    {\r\n        auto result = V1_0::Json::ManifestDeserializer::DeserializeLocale(localeJsonObject);\r\n\r\n        if (result)\r\n        {\r\n            auto& locale = result.value();\r\n\r\n            TryParseStringLocaleField<Manifest::Localization::ReleaseNotes>(locale, localeJsonObject, ReleaseNotes);\r\n            TryParseStringLocaleField<Manifest::Localization::ReleaseNotesUrl>(locale, localeJsonObject, ReleaseNotesUrl);\r\n\r\n            // Agreements\r\n            auto agreementsNode = JSON::GetRawJsonArrayFromJsonNode(localeJsonObject, JSON::GetUtilityString(Agreements));\r\n            if (agreementsNode)\r\n            {\r\n                std::vector<Manifest::Agreement> agreements;\r\n                for (auto const& agreementNode : agreementsNode.value().get())\r\n                {\r\n                    Manifest::Agreement agreementEntry;\r\n\r\n                    agreementEntry.Label = JSON::GetRawStringValueFromJsonNode(agreementNode, JSON::GetUtilityString(AgreementLabel)).value_or(\"\");\r\n                    agreementEntry.AgreementText = JSON::GetRawStringValueFromJsonNode(agreementNode, JSON::GetUtilityString(Agreement)).value_or(\"\");\r\n                    agreementEntry.AgreementUrl = JSON::GetRawStringValueFromJsonNode(agreementNode, JSON::GetUtilityString(AgreementUrl)).value_or(\"\");\r\n\r\n                    if (!agreementEntry.Label.empty() || !agreementEntry.AgreementText.empty() || !agreementEntry.AgreementUrl.empty())\r\n                    {\r\n                        agreements.emplace_back(std::move(agreementEntry));\r\n                    }\r\n                }\r\n\r\n                if (!agreements.empty())\r\n                {\r\n                    locale.Add<Manifest::Localization::Agreements>(std::move(agreements));\r\n                }\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    Manifest::ManifestVer ManifestDeserializer::GetManifestVersion() const\r\n    {\r\n        return Manifest::s_ManifestVersionV1_1;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_1/Json/SearchRequestSerializer.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <cpprest/json.h>\r\n#include \"Rest/Schema/1_0/Json/SearchRequestSerializer.h\"\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_1::Json\r\n{\r\n    // Search Result Serializer.\r\n    struct SearchRequestSerializer : public V1_0::Json::SearchRequestSerializer\r\n    {\r\n    protected:\r\n        std::optional<std::string_view> ConvertPackageMatchFieldToString(AppInstaller::Repository::PackageMatchField field) const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_1/Json/SearchRequestSerializer_1_1.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"SearchRequestSerializer.h\"\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_1::Json\r\n{\r\n    std::optional<std::string_view> SearchRequestSerializer::ConvertPackageMatchFieldToString(AppInstaller::Repository::PackageMatchField field) const\r\n    {\r\n        if (field == PackageMatchField::Market)\r\n        {\r\n            return \"Market\"sv;\r\n        }\r\n\r\n        return V1_0::Json::SearchRequestSerializer::ConvertPackageMatchFieldToString(field);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_1/RestInterface_1_1.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Rest/Schema/1_1/Interface.h\"\r\n#include \"Rest/Schema/CommonRestConstants.h\"\r\n#include \"Rest/Schema/IRestClient.h\"\r\n#include <winget/HttpClientHelper.h>\r\n#include <winget/JsonUtil.h>\r\n\r\nusing namespace std::string_view_literals;\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_1\r\n{\r\n    namespace\r\n    {\r\n        // Query params\r\n        constexpr std::string_view MarketQueryParam = \"Market\"sv;\r\n\r\n        // Response constants\r\n        constexpr std::string_view UnsupportedPackageMatchFields = \"UnsupportedPackageMatchFields\"sv;\r\n        constexpr std::string_view RequiredPackageMatchFields = \"RequiredPackageMatchFields\"sv;\r\n        constexpr std::string_view UnsupportedQueryParameters = \"UnsupportedQueryParameters\"sv;\r\n        constexpr std::string_view RequiredQueryParameters = \"RequiredQueryParameters\"sv;\r\n    }\r\n\r\n    Interface::Interface(\r\n        const std::string& restApi,\r\n        const Http::HttpClientHelper& httpClientHelper,\r\n        IRestClient::Information information,\r\n        const Http::HttpClientHelper::HttpRequestHeaders& additionalHeaders) : V1_0::Interface(restApi, httpClientHelper), m_information(std::move(information))\r\n    {\r\n        m_requiredRestApiHeaders[JSON::GetUtilityString(ContractVersion)] = JSON::GetUtilityString(Version_1_1_0.ToString());\r\n\r\n        if (!additionalHeaders.empty())\r\n        {\r\n            m_requiredRestApiHeaders.insert(additionalHeaders.begin(), additionalHeaders.end());\r\n        }\r\n    }\r\n\r\n    Utility::Version Interface::GetVersion() const\r\n    {\r\n        return Version_1_1_0;\r\n    }\r\n\r\n    IRestClient::Information Interface::GetSourceInformation() const\r\n    {\r\n        return m_information;\r\n    }\r\n\r\n    std::map<std::string_view, std::string> Interface::GetValidatedQueryParams(const std::map<std::string_view, std::string>& params) const\r\n    {\r\n        std::map<std::string_view, std::string> result = params;\r\n\r\n        for (auto const& param : m_information.RequiredQueryParameters)\r\n        {\r\n            if (params.end() == std::find_if(params.begin(), params.end(), [&](const auto& pair) { return Utility::CaseInsensitiveEquals(pair.first, param); }))\r\n            {\r\n                if (Utility::CaseInsensitiveEquals(param, MarketQueryParam))\r\n                {\r\n                    result.emplace(MarketQueryParam, Runtime::GetOSRegion());\r\n                    continue;\r\n                }\r\n\r\n                AICLI_LOG(Repo, Error, << \"Search request is not supported by the rest source. Required query Parameter: \" << param);\r\n                throw UnsupportedRequestException({}, {}, {}, m_information.RequiredQueryParameters);\r\n            }\r\n        }\r\n\r\n        for (auto const& param : m_information.UnsupportedQueryParameters)\r\n        {\r\n            if (params.end() != std::find_if(params.begin(), params.end(), [&](const auto& pair) { return Utility::CaseInsensitiveEquals(pair.first, param); }))\r\n            {\r\n                AICLI_LOG(Repo, Error, << \"Search request is not supported by the rest source. Unsupported query Parameter: \" << param);\r\n                throw UnsupportedRequestException({}, {}, m_information.UnsupportedQueryParameters, {});\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    web::json::value Interface::GetValidatedSearchBody(const SearchRequest& searchRequest) const\r\n    {\r\n        SearchRequest resultSearchRequest = searchRequest;\r\n\r\n        for (auto const& field : m_information.RequiredPackageMatchFields)\r\n        {\r\n            PackageMatchField matchField = ConvertStringToPackageMatchField(field);\r\n\r\n            if (searchRequest.Filters.end() == std::find_if(searchRequest.Filters.begin(), searchRequest.Filters.end(), [&](const PackageMatchFilter& filter) { return filter.Field == matchField; }))\r\n            {\r\n                if (matchField == PackageMatchField::Market)\r\n                {\r\n                    resultSearchRequest.Filters.emplace_back(PackageMatchFilter(PackageMatchField::Market, MatchType::CaseInsensitive, Runtime::GetOSRegion()));\r\n                    continue;\r\n                }\r\n\r\n                AICLI_LOG(Repo, Error, << \"Search request is not supported by the rest source. Required package match field: \" << field);\r\n                throw UnsupportedRequestException({}, m_information.RequiredPackageMatchFields, {}, {});\r\n            }\r\n        }\r\n\r\n        for (auto const& field : m_information.UnsupportedPackageMatchFields)\r\n        {\r\n            PackageMatchField matchField = ConvertStringToPackageMatchField(field);\r\n\r\n            if (matchField == PackageMatchField::Unknown)\r\n            {\r\n                continue;\r\n            }\r\n\r\n            if (searchRequest.Inclusions.end() != std::find_if(searchRequest.Inclusions.begin(), searchRequest.Inclusions.end(), [&](const PackageMatchFilter& inclusion) { return inclusion.Field == matchField; }))\r\n            {\r\n                AICLI_LOG(Repo, Info, << \"Search request Inclusions contains package match field not supported by the rest source. Ignoring the field. Unsupported package match field: \" << field);\r\n\r\n                resultSearchRequest.Inclusions.erase(\r\n                    std::remove_if(\r\n                        resultSearchRequest.Inclusions.begin(), resultSearchRequest.Inclusions.end(),\r\n                        [&](const PackageMatchFilter& inclusion) { return inclusion.Field == matchField; }),\r\n                    resultSearchRequest.Inclusions.end());\r\n            }\r\n\r\n            if (searchRequest.Filters.end() != std::find_if(searchRequest.Filters.begin(), searchRequest.Filters.end(), [&](const PackageMatchFilter& filter) { return filter.Field == matchField; }))\r\n            {\r\n                AICLI_LOG(Repo, Error, << \"Search request is not supported by the rest source. Unsupported package match field: \" << field);\r\n                throw UnsupportedRequestException(m_information.UnsupportedPackageMatchFields, {}, {}, {});\r\n            }\r\n        }\r\n\r\n        return V1_0::Interface::GetValidatedSearchBody(resultSearchRequest);\r\n    }\r\n\r\n    IRestClient::SearchResult Interface::GetSearchResult(const web::json::value& searchResponseObject) const\r\n    {\r\n        IRestClient::SearchResult result = V1_0::Interface::GetSearchResult(searchResponseObject);\r\n\r\n        if (result.Matches.size() == 0)\r\n        {\r\n            auto requiredPackageMatchFields = JSON::GetRawStringArrayFromJsonNode(searchResponseObject, JSON::GetUtilityString(RequiredPackageMatchFields));\r\n            auto unsupportedPackageMatchFields = JSON::GetRawStringArrayFromJsonNode(searchResponseObject, JSON::GetUtilityString(UnsupportedPackageMatchFields));\r\n\r\n            if (requiredPackageMatchFields.size() != 0 || unsupportedPackageMatchFields.size() != 0)\r\n            {\r\n                AICLI_LOG(Repo, Error, << \"Search request is not supported by the rest source\");\r\n                throw UnsupportedRequestException(std::move(unsupportedPackageMatchFields), std::move(requiredPackageMatchFields), {}, {});\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<Manifest::Manifest> Interface::GetParsedManifests(const web::json::value& manifestsResponseObject) const\r\n    {\r\n        auto result = V1_0::Interface::GetParsedManifests(manifestsResponseObject);\r\n\r\n        if (result.size() == 0)\r\n        {\r\n            auto requiredQueryParameters = JSON::GetRawStringArrayFromJsonNode(manifestsResponseObject, JSON::GetUtilityString(RequiredQueryParameters));\r\n            auto unsupportedQueryParameters = JSON::GetRawStringArrayFromJsonNode(manifestsResponseObject, JSON::GetUtilityString(UnsupportedQueryParameters));\r\n\r\n            if (requiredQueryParameters.size() != 0 || unsupportedQueryParameters.size() != 0)\r\n            {\r\n                AICLI_LOG(Repo, Error, << \"Search request is not supported by the rest source\");\r\n                throw UnsupportedRequestException({}, {}, std::move(unsupportedQueryParameters), std::move(requiredQueryParameters));\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    PackageMatchField Interface::ConvertStringToPackageMatchField(std::string_view field) const\r\n    {\r\n        std::string toLower = Utility::ToLower(field);\r\n\r\n        if (toLower == \"command\")\r\n        {\r\n            return PackageMatchField::Command;\r\n        }\r\n        else if (toLower == \"packageidentifier\")\r\n        {\r\n            return PackageMatchField::Id;\r\n        }\r\n        else if (toLower == \"moniker\")\r\n        {\r\n            return PackageMatchField::Moniker;\r\n        }\r\n        else if (toLower == \"packagename\")\r\n        {\r\n            return PackageMatchField::Name;\r\n        }\r\n        else if (toLower == \"tag\")\r\n        {\r\n            return PackageMatchField::Tag;\r\n        }\r\n        else if (toLower == \"packagefamilyname\")\r\n        {\r\n            return PackageMatchField::PackageFamilyName;\r\n        }\r\n        else if (toLower == \"productcode\")\r\n        {\r\n            return PackageMatchField::ProductCode;\r\n        }\r\n        else if (toLower == \"normalizedpackagenameandpublisher\")\r\n        {\r\n            return PackageMatchField::NormalizedNameAndPublisher;\r\n        }\r\n        else if (toLower == \"market\")\r\n        {\r\n            return PackageMatchField::Market;\r\n        }\r\n\r\n        return PackageMatchField::Unknown;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_10/Interface.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Rest/Schema/1_9/Interface.h\"\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_10\r\n{\r\n    // Interface to this schema version exposed through IRestClient.\r\n    struct Interface : public V1_9::Interface\r\n    {\r\n        Interface(const std::string& restApi, const Http::HttpClientHelper& helper, IRestClient::Information information, const Http::HttpClientHelper::HttpRequestHeaders& additionalHeaders = {}, Authentication::AuthenticationArguments authArgs = {});\r\n\r\n        Interface(const Interface&) = delete;\r\n        Interface& operator=(const Interface&) = delete;\r\n\r\n        Interface(Interface&&) = default;\r\n        Interface& operator=(Interface&&) = default;\r\n\r\n        Utility::Version GetVersion() const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_10/Json/ManifestDeserializer.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Rest/Schema/1_9/Json/ManifestDeserializer.h\"\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_10::Json\r\n{\r\n    // Manifest Deserializer.\r\n    struct ManifestDeserializer : public V1_9::Json::ManifestDeserializer\r\n    {\r\n    protected:\r\n\r\n        std::optional<Manifest::ManifestInstaller> DeserializeInstaller(const web::json::value& installerJsonObject) const override;\r\n\r\n        Manifest::ManifestVer GetManifestVersion() const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_10/Json/ManifestDeserializer_1_10.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ManifestDeserializer.h\"\r\n#include \"Rest/Schema/AuthenticationInfoParser.h\"\r\n#include <winget/JsonUtil.h>\r\n\r\nusing namespace AppInstaller::Manifest;\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_10::Json\r\n{\r\n    std::optional<Manifest::ManifestInstaller> ManifestDeserializer::DeserializeInstaller(const web::json::value& installerJsonObject) const\r\n    {\r\n        auto result = V1_9::Json::ManifestDeserializer::DeserializeInstaller(installerJsonObject);\r\n\r\n        if (result)\r\n        {\r\n            auto& installer = result.value();\r\n\r\n            installer.AuthInfo = ParseAuthenticationInfo(installerJsonObject, ParseAuthenticationInfoType::Installer, GetManifestVersion());\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    Manifest::ManifestVer ManifestDeserializer::GetManifestVersion() const\r\n    {\r\n        return Manifest::s_ManifestVersionV1_10;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_10/RestInterface_1_10.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Rest/Schema/1_10/Interface.h\"\r\n#include \"Rest/Schema/CommonRestConstants.h\"\r\n#include \"Rest/Schema/IRestClient.h\"\r\n#include <winget/HttpClientHelper.h>\r\n#include <winget/JsonUtil.h>\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_10\r\n{\r\n    Interface::Interface(\r\n        const std::string& restApi,\r\n        const Http::HttpClientHelper& httpClientHelper,\r\n        IRestClient::Information information,\r\n        const Http::HttpClientHelper::HttpRequestHeaders& additionalHeaders,\r\n        Authentication::AuthenticationArguments authArgs) : V1_9::Interface(restApi, httpClientHelper, std::move(information), additionalHeaders, std::move(authArgs))\r\n    {\r\n        m_requiredRestApiHeaders[JSON::GetUtilityString(ContractVersion)] = JSON::GetUtilityString(Version_1_10_0.ToString());\r\n    }\r\n\r\n    Utility::Version Interface::GetVersion() const\r\n    {\r\n        return Version_1_10_0;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_12/Interface.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"Rest/Schema/1_10/Interface.h\"\n\nnamespace AppInstaller::Repository::Rest::Schema::V1_12\n{\n    // Interface to this schema version exposed through IRestClient.\n    struct Interface : public V1_10::Interface\n    {\n        Interface(const std::string& restApi, const Http::HttpClientHelper& helper, IRestClient::Information information, const Http::HttpClientHelper::HttpRequestHeaders& additionalHeaders = {}, Authentication::AuthenticationArguments authArgs = {});\n\n        Interface(const Interface&) = delete;\n        Interface& operator=(const Interface&) = delete;\n\n        Interface(Interface&&) = default;\n        Interface& operator=(Interface&&) = default;\n\n        Utility::Version GetVersion() const override;\n    };\n}\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_12/Json/ManifestDeserializer.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"Rest/Schema/1_10/Json/ManifestDeserializer.h\"\n\nnamespace AppInstaller::Repository::Rest::Schema::V1_12::Json\n{\n    // Manifest Deserializer.\n    struct ManifestDeserializer : public V1_10::Json::ManifestDeserializer\n    {\n    protected:\n\n        Manifest::InstallerTypeEnum ConvertToInstallerType(std::string_view in) const override;\n\n        Manifest::ManifestVer GetManifestVersion() const override;\n    };\n}\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_12/Json/ManifestDeserializer_1_12.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"ManifestDeserializer.h\"\n#include \"Rest/Schema/AuthenticationInfoParser.h\"\n#include <winget/JsonUtil.h>\n\nusing namespace AppInstaller::Manifest;\n\nnamespace AppInstaller::Repository::Rest::Schema::V1_12::Json\n{\n    Manifest::InstallerTypeEnum ManifestDeserializer::ConvertToInstallerType(std::string_view in) const\n    {\n        std::string inStrLower = Utility::ToLower(in);\n\n        if (inStrLower == \"font\")\n        {\n            return InstallerTypeEnum::Font;\n        }\n\n        return V1_10::Json::ManifestDeserializer::ConvertToInstallerType(inStrLower);\n    }\n\n    Manifest::ManifestVer ManifestDeserializer::GetManifestVersion() const\n    {\n        return Manifest::s_ManifestVersionV1_12;\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_12/RestInterface_1_12.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"Rest/Schema/1_12/Interface.h\"\n#include \"Rest/Schema/CommonRestConstants.h\"\n#include \"Rest/Schema/IRestClient.h\"\n#include <winget/HttpClientHelper.h>\n#include <winget/JsonUtil.h>\n\nnamespace AppInstaller::Repository::Rest::Schema::V1_12\n{\n    Interface::Interface(\n        const std::string& restApi,\n        const Http::HttpClientHelper& httpClientHelper,\n        IRestClient::Information information,\n        const Http::HttpClientHelper::HttpRequestHeaders& additionalHeaders,\n        Authentication::AuthenticationArguments authArgs) : V1_10::Interface(restApi, httpClientHelper, std::move(information), additionalHeaders, std::move(authArgs))\n    {\n        m_requiredRestApiHeaders[JSON::GetUtilityString(ContractVersion)] = JSON::GetUtilityString(Version_1_12_0.ToString());\n    }\n\n    Utility::Version Interface::GetVersion() const\n    {\n        return Version_1_12_0;\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_4/Interface.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Rest/Schema/1_1/Interface.h\"\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_4\r\n{\r\n    // Interface to this schema version exposed through IRestClient.\r\n    struct Interface : public V1_1::Interface\r\n    {\r\n        Interface(const std::string& restApi, const Http::HttpClientHelper& helper, IRestClient::Information information, const Http::HttpClientHelper::HttpRequestHeaders& additionalHeaders = {});\r\n\r\n        Interface(const Interface&) = delete;\r\n        Interface& operator=(const Interface&) = delete;\r\n\r\n        Interface(Interface&&) = default;\r\n        Interface& operator=(Interface&&) = default;\r\n\r\n        Utility::Version GetVersion() const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_4/Json/ManifestDeserializer.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Rest/Schema/1_1/Json/ManifestDeserializer.h\"\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_4::Json\r\n{\r\n    // Manifest Deserializer.\r\n    struct ManifestDeserializer : public V1_1::Json::ManifestDeserializer\r\n    {\r\n        std::optional<Manifest::ManifestLocalization> DeserializeLocale(const web::json::value& localeJsonObject) const override;\r\n\r\n        std::optional<Manifest::InstallationMetadataInfo> DeserializeInstallationMetadata(const web::json::value& installationMetadataJsonObject) const override;\r\n\r\n    protected:\r\n        std::optional<Manifest::ManifestInstaller> DeserializeInstaller(const web::json::value& installerJsonObject) const override;\r\n\r\n        Manifest::InstallerTypeEnum ConvertToInstallerType(std::string_view in) const override;\r\n\r\n        Manifest::ExpectedReturnCodeEnum ConvertToExpectedReturnCodeEnum(std::string_view in) const override;\r\n\r\n        Manifest::ManifestInstaller::ExpectedReturnCodeInfo DeserializeExpectedReturnCodeInfo(const web::json::value& expectedReturnCodeJsonObject) const override;\r\n\r\n        Manifest::ManifestVer GetManifestVersion() const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_4/Json/ManifestDeserializer_1_4.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ManifestDeserializer.h\"\r\n#include <winget/JsonUtil.h>\r\n\r\nusing namespace AppInstaller::Manifest;\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_4::Json\r\n{\r\n    namespace\r\n    {\r\n        // Installer\r\n        constexpr std::string_view ReturnResponseUrl = \"ReturnResponseUrl\"sv;\r\n        constexpr std::string_view NestedInstallerType = \"NestedInstallerType\"sv;\r\n        constexpr std::string_view DisplayInstallWarnings = \"DisplayInstallWarnings\"sv;\r\n        constexpr std::string_view UnsupportedArguments = \"UnsupportedArguments\"sv;\r\n        constexpr std::string_view NestedInstallerFiles = \"NestedInstallerFiles\"sv;\r\n        constexpr std::string_view NestedInstallerFileRelativeFilePath = \"RelativeFilePath\"sv;\r\n        constexpr std::string_view PortableCommandAlias = \"PortableCommandAlias\"sv;\r\n        constexpr std::string_view InstallationMetadata = \"InstallationMetadata\"sv;\r\n        constexpr std::string_view DefaultInstallLocation = \"DefaultInstallLocation\"sv;\r\n        constexpr std::string_view InstallationMetadataFiles = \"Files\"sv;\r\n        constexpr std::string_view InstallationMetadataRelativeFilePath = \"RelativeFilePath\"sv;\r\n        constexpr std::string_view FileSha256 = \"FileSha256\"sv;\r\n        constexpr std::string_view FileType = \"FileType\"sv;\r\n        constexpr std::string_view InvocationParameter = \"InvocationParameter\"sv;\r\n        constexpr std::string_view DisplayName = \"DisplayName\"sv;\r\n\r\n        // Locale\r\n        constexpr std::string_view InstallationNotes = \"InstallationNotes\"sv;\r\n        constexpr std::string_view PurchaseUrl = \"PurchaseUrl\"sv;\r\n        constexpr std::string_view Documentations = \"Documentations\"sv;\r\n        constexpr std::string_view DocumentLabel = \"DocumentLabel\"sv;\r\n        constexpr std::string_view DocumentUrl = \"DocumentUrl\"sv;\r\n    }\r\n\r\n    Manifest::InstallerTypeEnum ManifestDeserializer::ConvertToInstallerType(std::string_view in) const\r\n    {\r\n        std::string inStrLower = Utility::ToLower(in);\r\n\r\n        if (inStrLower == \"portable\")\r\n        {\r\n            return InstallerTypeEnum::Portable;\r\n        }\r\n\r\n        return V1_1::Json::ManifestDeserializer::ConvertToInstallerType(inStrLower);\r\n    }\r\n\r\n    Manifest::ExpectedReturnCodeEnum ManifestDeserializer::ConvertToExpectedReturnCodeEnum(std::string_view in) const\r\n    {\r\n        std::string inStrLower = Utility::ToLower(in);\r\n\r\n        if (inStrLower == \"custom\")\r\n        {\r\n            return ExpectedReturnCodeEnum::Custom;\r\n        }\r\n        else if (inStrLower == \"packageinusebyapplication\")\r\n        {\r\n            return ExpectedReturnCodeEnum::PackageInUseByApplication;\r\n        }\r\n        else if (inStrLower == \"invalidparameter\")\r\n        {\r\n            return ExpectedReturnCodeEnum::InvalidParameter;\r\n        }\r\n        else if (inStrLower == \"systemnotsupported\")\r\n        {\r\n            return ExpectedReturnCodeEnum::SystemNotSupported;\r\n        }\r\n\r\n        return V1_1::Json::ManifestDeserializer::ConvertToExpectedReturnCodeEnum(inStrLower);\r\n    }\r\n\r\n    Manifest::ManifestInstaller::ExpectedReturnCodeInfo ManifestDeserializer::DeserializeExpectedReturnCodeInfo(const web::json::value& expectedReturnCodeJsonObject) const\r\n    {\r\n        auto result = V1_1::Json::ManifestDeserializer::DeserializeExpectedReturnCodeInfo(expectedReturnCodeJsonObject);\r\n        result.ReturnResponseUrl = JSON::GetRawStringValueFromJsonNode(expectedReturnCodeJsonObject, JSON::GetUtilityString(ReturnResponseUrl)).value_or(\"\");\r\n        return result;\r\n    }\r\n\r\n    std::optional<Manifest::InstallationMetadataInfo> ManifestDeserializer::DeserializeInstallationMetadata(const web::json::value& installationMetadataJsonObject) const\r\n    {\r\n        if (installationMetadataJsonObject.is_null() || !installationMetadataJsonObject.is_object())\r\n        {\r\n            return {};\r\n        }\r\n\r\n        Manifest::InstallationMetadataInfo installationMetadata;\r\n        installationMetadata.DefaultInstallLocation = JSON::GetRawStringValueFromJsonNode(installationMetadataJsonObject, JSON::GetUtilityString(DefaultInstallLocation)).value_or(\"\");\r\n\r\n        auto filesNode = JSON::GetRawJsonArrayFromJsonNode(installationMetadataJsonObject, JSON::GetUtilityString(InstallationMetadataFiles));\r\n        if (filesNode)\r\n        {\r\n            for (auto const& fileNode : filesNode->get())\r\n            {\r\n                std::optional<std::string> relativeFilePath = JSON::GetRawStringValueFromJsonNode(fileNode, JSON::GetUtilityString(InstallationMetadataRelativeFilePath));\r\n                if (!JSON::IsValidNonEmptyStringValue(relativeFilePath))\r\n                {\r\n                    AICLI_LOG(Repo, Error, << \"Missing RelativeFilePath in InstallationMetadata Files.\");\r\n                    return {};\r\n                }\r\n\r\n                Manifest::InstalledFile installedFile;\r\n                installedFile.RelativeFilePath = std::move(*relativeFilePath);\r\n                installedFile.InvocationParameter = JSON::GetRawStringValueFromJsonNode(fileNode, JSON::GetUtilityString(InvocationParameter)).value_or(\"\");\r\n                installedFile.DisplayName = JSON::GetRawStringValueFromJsonNode(fileNode, JSON::GetUtilityString(DisplayName)).value_or(\"\");\r\n\r\n                std::optional<std::string> sha256 = JSON::GetRawStringValueFromJsonNode(fileNode, JSON::GetUtilityString(FileSha256));\r\n                if (JSON::IsValidNonEmptyStringValue(sha256))\r\n                {\r\n                    installedFile.FileSha256 = Utility::SHA256::ConvertToBytes(*sha256);\r\n                }\r\n\r\n                std::optional<std::string> fileType = JSON::GetRawStringValueFromJsonNode(fileNode, JSON::GetUtilityString(FileType));\r\n                if (JSON::IsValidNonEmptyStringValue(fileType))\r\n                {\r\n                    installedFile.FileType = Manifest::ConvertToInstalledFileTypeEnum(*fileType);\r\n                }\r\n\r\n                installationMetadata.Files.emplace_back(std::move(installedFile));\r\n            }\r\n        }\r\n\r\n        return installationMetadata;\r\n    }\r\n\r\n    std::optional<Manifest::ManifestInstaller> ManifestDeserializer::DeserializeInstaller(const web::json::value& installerJsonObject) const\r\n    {\r\n        auto result = V1_1::Json::ManifestDeserializer::DeserializeInstaller(installerJsonObject);\r\n\r\n        if (result)\r\n        {\r\n            auto& installer = result.value();\r\n\r\n            std::optional<std::string> nestedInstallerType = JSON::GetRawStringValueFromJsonNode(installerJsonObject, JSON::GetUtilityString(NestedInstallerType));\r\n            if (nestedInstallerType)\r\n            {\r\n                installer.NestedInstallerType = ConvertToInstallerType(*nestedInstallerType);\r\n            }\r\n            \r\n            installer.DisplayInstallWarnings = JSON::GetRawBoolValueFromJsonNode(installerJsonObject, JSON::GetUtilityString(DisplayInstallWarnings)).value_or(false);\r\n\r\n            // UnsupportedArguments\r\n            auto unsupportedArguments = JSON::GetRawStringArrayFromJsonNode(installerJsonObject, JSON::GetUtilityString(UnsupportedArguments));\r\n            for (auto const& unsupportedArgument : unsupportedArguments)\r\n            {\r\n                auto unsupportedArgumentEnum = Manifest::ConvertToUnsupportedArgumentEnum(unsupportedArgument);\r\n                if (unsupportedArgumentEnum != Manifest::UnsupportedArgumentEnum::Unknown)\r\n                {\r\n                    installer.UnsupportedArguments.emplace_back(unsupportedArgumentEnum);\r\n                }\r\n            }\r\n\r\n            // NestedInstallerFiles\r\n            auto nestedInstallerFilesNode = JSON::GetRawJsonArrayFromJsonNode(installerJsonObject, JSON::GetUtilityString(NestedInstallerFiles));\r\n            if (nestedInstallerFilesNode)\r\n            {\r\n                for (auto const& nestedInstallerFileNode : nestedInstallerFilesNode->get())\r\n                {\r\n                    std::optional<std::string> relativeFilePath = JSON::GetRawStringValueFromJsonNode(nestedInstallerFileNode, JSON::GetUtilityString(NestedInstallerFileRelativeFilePath));\r\n                    if (!JSON::IsValidNonEmptyStringValue(relativeFilePath))\r\n                    {\r\n                        AICLI_LOG(Repo, Error, << \"Missing RelativeFilePath in NestedInstallerFiles.\");\r\n                        return {};\r\n                    }\r\n\r\n                    Manifest::NestedInstallerFile nestedInstallerFile;\r\n                    nestedInstallerFile.RelativeFilePath = std::move(*relativeFilePath);\r\n                    nestedInstallerFile.PortableCommandAlias = JSON::GetRawStringValueFromJsonNode(nestedInstallerFileNode, JSON::GetUtilityString(PortableCommandAlias)).value_or(\"\");\r\n\r\n                    installer.NestedInstallerFiles.emplace_back(std::move(nestedInstallerFile));\r\n                }\r\n            }\r\n\r\n            // InstallationMetadata\r\n            auto installationMetadataNode = JSON::GetJsonValueFromNode(installerJsonObject, JSON::GetUtilityString(InstallationMetadata));\r\n            if (installationMetadataNode)\r\n            {\r\n                auto installationMetadata = DeserializeInstallationMetadata(installationMetadataNode->get());\r\n                if (installationMetadata)\r\n                {\r\n                    installer.InstallationMetadata = std::move(*installationMetadata);\r\n                }\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::optional<Manifest::ManifestLocalization> ManifestDeserializer::DeserializeLocale(const web::json::value& localeJsonObject) const\r\n    {\r\n        auto result = V1_1::Json::ManifestDeserializer::DeserializeLocale(localeJsonObject);\r\n\r\n        if (result)\r\n        {\r\n            auto& locale = result.value();\r\n\r\n            TryParseStringLocaleField<Manifest::Localization::InstallationNotes>(locale, localeJsonObject, InstallationNotes);\r\n            TryParseStringLocaleField<Manifest::Localization::PurchaseUrl>(locale, localeJsonObject, PurchaseUrl);\r\n\r\n            // Documentations\r\n            auto documentationsNode = JSON::GetRawJsonArrayFromJsonNode(localeJsonObject, JSON::GetUtilityString(Documentations));\r\n            if (documentationsNode)\r\n            {\r\n                std::vector<Manifest::Documentation> documentations;\r\n                for (auto const& documentationNode : documentationsNode->get())\r\n                {\r\n                    Manifest::Documentation documentationEntry;\r\n\r\n                    documentationEntry.DocumentLabel = JSON::GetRawStringValueFromJsonNode(documentationNode, JSON::GetUtilityString(DocumentLabel)).value_or(\"\");\r\n                    documentationEntry.DocumentUrl = JSON::GetRawStringValueFromJsonNode(documentationNode, JSON::GetUtilityString(DocumentUrl)).value_or(\"\");\r\n\r\n                    if (!documentationEntry.DocumentLabel.empty() || !documentationEntry.DocumentUrl.empty())\r\n                    {\r\n                        documentations.emplace_back(std::move(documentationEntry));\r\n                    }\r\n                }\r\n\r\n                if (!documentations.empty())\r\n                {\r\n                    locale.Add<Manifest::Localization::Documentations>(std::move(documentations));\r\n                }\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    Manifest::ManifestVer ManifestDeserializer::GetManifestVersion() const\r\n    {\r\n        return Manifest::s_ManifestVersionV1_4;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_4/Json/SearchResponseDeserializer.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <cpprest/json.h>\r\n#include \"Rest/Schema/1_0/Json/SearchResponseDeserializer.h\"\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_4::Json\r\n{\r\n    // Search Result Deserializer.\r\n    struct SearchResponseDeserializer : public V1_0::Json::SearchResponseDeserializer\r\n    {\r\n    protected:\r\n        std::optional<IRestClient::VersionInfo> DeserializeVersionInfo(const web::json::value& versionInfoJsonObject) const;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_4/Json/SearchResponseDeserializer_1_4.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"SearchResponseDeserializer.h\"\r\n#include <winget/JsonUtil.h>\r\n#include <winget/Rest.h>\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_4::Json\r\n{\r\n    namespace\r\n    {\r\n        // Search response constants\r\n        constexpr std::string_view UpgradeCodes = \"UpgradeCodes\"sv;\r\n        constexpr std::string_view AppsAndFeaturesEntryVersions = \"AppsAndFeaturesEntryVersions\"sv;\r\n    }\r\n\r\n    std::optional<IRestClient::VersionInfo> SearchResponseDeserializer::DeserializeVersionInfo(const web::json::value& versionInfoJsonObject) const\r\n    {\r\n        auto result = V1_0::Json::SearchResponseDeserializer::DeserializeVersionInfo(versionInfoJsonObject);\r\n        if (result.has_value())\r\n        {\r\n            result->UpgradeCodes = AppInstaller::Rest::GetUniqueItems(JSON::GetRawStringArrayFromJsonNode(versionInfoJsonObject, JSON::GetUtilityString(UpgradeCodes)));\r\n            auto arpVersions = AppInstaller::Rest::GetUniqueItems(JSON::GetRawStringArrayFromJsonNode(versionInfoJsonObject, JSON::GetUtilityString(AppsAndFeaturesEntryVersions)));\r\n            for (auto const& version : arpVersions)\r\n            {\r\n                result->ArpVersions.emplace_back(Utility::Version{ version });\r\n            }\r\n            // Sort the arp versions for later querying\r\n            std::sort(result->ArpVersions.begin(), result->ArpVersions.end());\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_4/RestInterface_1_4.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Rest/Schema/1_4/Interface.h\"\r\n#include \"Rest/Schema/CommonRestConstants.h\"\r\n#include \"Rest/Schema/IRestClient.h\"\r\n#include <winget/HttpClientHelper.h>\r\n#include <winget/JsonUtil.h>\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_4\r\n{\r\n    Interface::Interface(\r\n        const std::string& restApi,\r\n        const Http::HttpClientHelper& httpClientHelper,\r\n        IRestClient::Information information,\r\n        const Http::HttpClientHelper::HttpRequestHeaders& additionalHeaders) : V1_1::Interface(restApi, httpClientHelper, std::move(information), additionalHeaders)\r\n    {\r\n        m_requiredRestApiHeaders[JSON::GetUtilityString(ContractVersion)] = JSON::GetUtilityString(Version_1_4_0.ToString());\r\n    }\r\n\r\n    Utility::Version Interface::GetVersion() const\r\n    {\r\n        return Version_1_4_0;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_5/Interface.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Rest/Schema/1_4/Interface.h\"\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_5\r\n{\r\n    // Interface to this schema version exposed through IRestClient.\r\n    struct Interface : public V1_4::Interface\r\n    {\r\n        Interface(const std::string& restApi, const Http::HttpClientHelper& helper, IRestClient::Information information, const Http::HttpClientHelper::HttpRequestHeaders& additionalHeaders = {});\r\n\r\n        Interface(const Interface&) = delete;\r\n        Interface& operator=(const Interface&) = delete;\r\n\r\n        Interface(Interface&&) = default;\r\n        Interface& operator=(Interface&&) = default;\r\n\r\n        Utility::Version GetVersion() const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_5/Json/ManifestDeserializer.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Rest/Schema/1_4/Json/ManifestDeserializer.h\"\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_5::Json\r\n{\r\n    // Manifest Deserializer.\r\n    struct ManifestDeserializer : public V1_4::Json::ManifestDeserializer\r\n    {\r\n        std::optional<Manifest::ManifestLocalization> DeserializeLocale(const web::json::value& localeJsonObject) const override;\r\n\r\n    protected:\r\n\r\n        Manifest::ManifestVer GetManifestVersion() const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_5/Json/ManifestDeserializer_1_5.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ManifestDeserializer.h\"\r\n#include <winget/JsonUtil.h>\r\n\r\nusing namespace AppInstaller::Manifest;\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_5::Json\r\n{\r\n    namespace\r\n    {\r\n        // Locale\r\n        constexpr std::string_view Icons = \"Icons\"sv;\r\n        constexpr std::string_view IconUrl = \"IconUrl\"sv;\r\n        constexpr std::string_view IconFileType = \"IconFileType\"sv;\r\n        constexpr std::string_view IconResolution = \"IconResolution\"sv;\r\n        constexpr std::string_view IconTheme = \"IconTheme\"sv;\r\n        constexpr std::string_view IconSha256 = \"IconSha256\"sv;\r\n    }\r\n\r\n    std::optional<Manifest::ManifestLocalization> ManifestDeserializer::DeserializeLocale(const web::json::value& localeJsonObject) const\r\n    {\r\n        auto result = V1_4::Json::ManifestDeserializer::DeserializeLocale(localeJsonObject);\r\n\r\n        if (result)\r\n        {\r\n            auto& locale = result.value();\r\n\r\n            // Icons\r\n            auto iconsNode = JSON::GetRawJsonArrayFromJsonNode(localeJsonObject, JSON::GetUtilityString(Icons));\r\n            if (iconsNode)\r\n            {\r\n                std::vector<Manifest::Icon> icons;\r\n                for (auto const& iconNode : iconsNode->get())\r\n                {\r\n                    Manifest::Icon iconEntry;\r\n\r\n                    iconEntry.Url = JSON::GetRawStringValueFromJsonNode(iconNode, JSON::GetUtilityString(IconUrl)).value_or(\"\");\r\n                    if (iconEntry.Url.empty())\r\n                    {\r\n                        continue;\r\n                    }\r\n\r\n                    auto fileType = JSON::GetRawStringValueFromJsonNode(iconNode, JSON::GetUtilityString(IconFileType)).value_or(\"\");\r\n                    if (fileType.empty())\r\n                    {\r\n                        continue;\r\n                    }\r\n\r\n                    iconEntry.FileType = Manifest::ConvertToIconFileTypeEnum(fileType);\r\n                    iconEntry.Resolution = Manifest::ConvertToIconResolutionEnum(JSON::GetRawStringValueFromJsonNode(iconNode, JSON::GetUtilityString(IconResolution)).value_or(\"\"));\r\n                    iconEntry.Theme = Manifest::ConvertToIconThemeEnum(JSON::GetRawStringValueFromJsonNode(iconNode, JSON::GetUtilityString(IconTheme)).value_or(\"\"));\r\n\r\n                    std::optional<std::string> sha256 = JSON::GetRawStringValueFromJsonNode(iconNode, JSON::GetUtilityString(IconSha256));\r\n                    if (JSON::IsValidNonEmptyStringValue(sha256))\r\n                    {\r\n                        iconEntry.Sha256 = Utility::SHA256::ConvertToBytes(*sha256);\r\n                    }\r\n\r\n                    icons.emplace_back(std::move(iconEntry));\r\n                }\r\n\r\n                if (!icons.empty())\r\n                {\r\n                    locale.Add<Manifest::Localization::Icons>(std::move(icons));\r\n                }\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    Manifest::ManifestVer ManifestDeserializer::GetManifestVersion() const\r\n    {\r\n        return Manifest::s_ManifestVersionV1_5;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_5/RestInterface_1_5.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Rest/Schema/1_5/Interface.h\"\r\n#include \"Rest/Schema/CommonRestConstants.h\"\r\n#include \"Rest/Schema/IRestClient.h\"\r\n#include <winget/HttpClientHelper.h>\r\n#include <winget/JsonUtil.h>\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_5\r\n{\r\n    Interface::Interface(\r\n        const std::string& restApi,\r\n        const Http::HttpClientHelper& httpClientHelper,\r\n        IRestClient::Information information,\r\n        const Http::HttpClientHelper::HttpRequestHeaders& additionalHeaders) : V1_4::Interface(restApi, httpClientHelper, std::move(information), additionalHeaders)\r\n    {\r\n        m_requiredRestApiHeaders[JSON::GetUtilityString(ContractVersion)] = JSON::GetUtilityString(Version_1_5_0.ToString());\r\n    }\r\n\r\n    Utility::Version Interface::GetVersion() const\r\n    {\r\n        return Version_1_5_0;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_6/Interface.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Rest/Schema/1_5/Interface.h\"\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_6\r\n{\r\n    // Interface to this schema version exposed through IRestClient.\r\n    struct Interface : public V1_5::Interface\r\n    {\r\n        Interface(const std::string& restApi, const Http::HttpClientHelper& helper, IRestClient::Information information, const Http::HttpClientHelper::HttpRequestHeaders& additionalHeaders = {});\r\n\r\n        Interface(const Interface&) = delete;\r\n        Interface& operator=(const Interface&) = delete;\r\n\r\n        Interface(Interface&&) = default;\r\n        Interface& operator=(Interface&&) = default;\r\n\r\n        Utility::Version GetVersion() const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_6/Json/ManifestDeserializer.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Rest/Schema/1_5/Json/ManifestDeserializer.h\"\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_6::Json\r\n{\r\n    // Manifest Deserializer.\r\n    struct ManifestDeserializer : public V1_5::Json::ManifestDeserializer\r\n    {\r\n    protected:\r\n\r\n        std::optional<Manifest::ManifestInstaller> DeserializeInstaller(const web::json::value& installerJsonObject) const override;\r\n\r\n        Manifest::UpdateBehaviorEnum ConvertToUpdateBehavior(std::string_view in) const override;\r\n\r\n        Manifest::ManifestVer GetManifestVersion() const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_6/Json/ManifestDeserializer_1_6.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ManifestDeserializer.h\"\r\n#include <winget/JsonUtil.h>\r\n\r\nusing namespace AppInstaller::Manifest;\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_6::Json\r\n{\r\n    namespace\r\n    {\r\n        // Installer\r\n        constexpr std::string_view DownloadCommandProhibited = \"DownloadCommandProhibited\"sv;\r\n    }\r\n\r\n    std::optional<Manifest::ManifestInstaller> ManifestDeserializer::DeserializeInstaller(const web::json::value& installerJsonObject) const\r\n    {\r\n        auto result = V1_5::Json::ManifestDeserializer::DeserializeInstaller(installerJsonObject);\r\n\r\n        if (result)\r\n        {\r\n            auto& installer = result.value();\r\n\r\n            installer.DownloadCommandProhibited = JSON::GetRawBoolValueFromJsonNode(installerJsonObject, JSON::GetUtilityString(DownloadCommandProhibited)).value_or(false);\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    Manifest::UpdateBehaviorEnum ManifestDeserializer::ConvertToUpdateBehavior(std::string_view in) const\r\n    {\r\n        std::string inStrLower = Utility::ToLower(in);\r\n\r\n        if (inStrLower == \"deny\")\r\n        {\r\n            return UpdateBehaviorEnum::Deny;\r\n        }\r\n\r\n        return V1_5::Json::ManifestDeserializer::ConvertToUpdateBehavior(inStrLower);\r\n    }\r\n\r\n    Manifest::ManifestVer ManifestDeserializer::GetManifestVersion() const\r\n    {\r\n        return Manifest::s_ManifestVersionV1_6;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_6/RestInterface_1_6.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Rest/Schema/1_6/Interface.h\"\r\n#include \"Rest/Schema/CommonRestConstants.h\"\r\n#include \"Rest/Schema/IRestClient.h\"\r\n#include <winget/HttpClientHelper.h>\r\n#include <winget/JsonUtil.h>\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_6\r\n{\r\n    Interface::Interface(\r\n        const std::string& restApi,\r\n        const Http::HttpClientHelper& httpClientHelper,\r\n        IRestClient::Information information,\r\n        const Http::HttpClientHelper::HttpRequestHeaders& additionalHeaders) : V1_5::Interface(restApi, httpClientHelper, std::move(information), additionalHeaders)\r\n    {\r\n        m_requiredRestApiHeaders[JSON::GetUtilityString(ContractVersion)] = JSON::GetUtilityString(Version_1_6_0.ToString());\r\n    }\r\n\r\n    Utility::Version Interface::GetVersion() const\r\n    {\r\n        return Version_1_6_0;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_7/Interface.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Rest/Schema/1_6/Interface.h\"\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_7\r\n{\r\n    // Interface to this schema version exposed through IRestClient.\r\n    struct Interface : public V1_6::Interface\r\n    {\r\n        Interface(const std::string& restApi, const Http::HttpClientHelper& helper, IRestClient::Information information, const Http::HttpClientHelper::HttpRequestHeaders& additionalHeaders = {}, Authentication::AuthenticationArguments authArgs = {});\r\n\r\n        Interface(const Interface&) = delete;\r\n        Interface& operator=(const Interface&) = delete;\r\n\r\n        Interface(Interface&&) = default;\r\n        Interface& operator=(Interface&&) = default;\r\n\r\n        Utility::Version GetVersion() const override;\r\n\r\n        Http::HttpClientHelper::HttpRequestHeaders GetAuthHeaders() const override;\r\n\r\n    protected:\r\n        std::unique_ptr<Authentication::Authenticator> m_authenticator;\r\n        Authentication::AuthenticationArguments m_authArgs;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_7/Json/ManifestDeserializer.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Rest/Schema/1_6/Json/ManifestDeserializer.h\"\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_7::Json\r\n{\r\n    // Manifest Deserializer.\r\n    struct ManifestDeserializer : public V1_6::Json::ManifestDeserializer\r\n    {\r\n    protected:\r\n\r\n        std::optional<Manifest::ManifestInstaller> DeserializeInstaller(const web::json::value& installerJsonObject) const override;\r\n\r\n        std::map<Manifest::InstallerSwitchType, Manifest::string_t> DeserializeInstallerSwitches(const web::json::value& installerSwitchesJsonObject) const override;\r\n\r\n        Manifest::ManifestVer GetManifestVersion() const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_7/Json/ManifestDeserializer_1_7.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ManifestDeserializer.h\"\r\n#include <winget/JsonUtil.h>\r\n\r\nusing namespace AppInstaller::Manifest;\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_7::Json\r\n{\r\n    namespace\r\n    {\r\n        // Installer\r\n        constexpr std::string_view InstallerSwitchRepair = \"Repair\"sv;\r\n        constexpr std::string_view RepairBehavior = \"RepairBehavior\"sv;\r\n    }\r\n\r\n    std::optional<Manifest::ManifestInstaller> ManifestDeserializer::DeserializeInstaller(const web::json::value& installerJsonObject) const\r\n    {\r\n        auto result = V1_6::Json::ManifestDeserializer::DeserializeInstaller(installerJsonObject);\r\n\r\n        if (result)\r\n        {\r\n            auto& installer = result.value();\r\n\r\n            installer.RepairBehavior = Manifest::ConvertToRepairBehaviorEnum(JSON::GetRawStringValueFromJsonNode(installerJsonObject, JSON::GetUtilityString(RepairBehavior)).value_or(\"\"));\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::map<Manifest::InstallerSwitchType, Manifest::string_t> ManifestDeserializer::DeserializeInstallerSwitches(const web::json::value& installerSwitchesJsonObject) const\r\n    {\r\n        auto installerSwitches = V1_6::Json::ManifestDeserializer::DeserializeInstallerSwitches(installerSwitchesJsonObject);\r\n\r\n        auto repairValue = JSON::GetRawStringValueFromJsonNode(installerSwitchesJsonObject, JSON::GetUtilityString(InstallerSwitchRepair));\r\n\r\n        if (JSON::IsValidNonEmptyStringValue(repairValue))\r\n        {\r\n            installerSwitches[Manifest::InstallerSwitchType::Repair] = repairValue.value();\r\n        }\r\n\r\n        return installerSwitches;\r\n    }\r\n\r\n    Manifest::ManifestVer ManifestDeserializer::GetManifestVersion() const\r\n    {\r\n        return Manifest::s_ManifestVersionV1_7;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_7/RestInterface_1_7.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Rest/Schema/1_7/Interface.h\"\r\n#include \"Rest/Schema/CommonRestConstants.h\"\r\n#include \"Rest/Schema/IRestClient.h\"\r\n#include <winget/HttpClientHelper.h>\r\n#include <winget/JsonUtil.h>\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_7\r\n{\r\n    Interface::Interface(\r\n        const std::string& restApi,\r\n        const Http::HttpClientHelper& httpClientHelper,\r\n        IRestClient::Information information,\r\n        const Http::HttpClientHelper::HttpRequestHeaders& additionalHeaders,\r\n        Authentication::AuthenticationArguments authArgs) : V1_6::Interface(restApi, httpClientHelper, std::move(information), additionalHeaders), m_authArgs(std::move(authArgs))\r\n    {\r\n        m_requiredRestApiHeaders[JSON::GetUtilityString(ContractVersion)] = JSON::GetUtilityString(Version_1_7_0.ToString());\r\n\r\n        if (m_information.Authentication.Type == Authentication::AuthenticationType::MicrosoftEntraId)\r\n        {\r\n            AICLI_LOG(Repo, Info, << \"Creating authenticator for MicrosoftEntraId authentication. Source Identifier: \" << m_information.SourceIdentifier);\r\n            m_authenticator = std::make_unique<Authentication::Authenticator>(m_information.Authentication, m_authArgs);\r\n        }\r\n        else if (m_information.Authentication.Type == Authentication::AuthenticationType::Unknown)\r\n        {\r\n            AICLI_LOG(Repo, Error, << \"Authentication type unknown for rest source. Source Identifier: \" << m_information.SourceIdentifier);\r\n            THROW_HR(APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED);\r\n        }\r\n    }\r\n\r\n    Utility::Version Interface::GetVersion() const\r\n    {\r\n        return Version_1_7_0;\r\n    }\r\n\r\n    Http::HttpClientHelper::HttpRequestHeaders Interface::GetAuthHeaders() const\r\n    {\r\n        Http::HttpClientHelper::HttpRequestHeaders result;\r\n\r\n        if (m_information.Authentication.Type == Authentication::AuthenticationType::MicrosoftEntraId)\r\n        {\r\n            auto authResult = m_authenticator->AuthenticateForToken();\r\n            if (FAILED(authResult.Status))\r\n            {\r\n                AICLI_LOG(Repo, Error, << \"Authentication failed. Result: \" << authResult.Status);\r\n                THROW_HR_MSG(authResult.Status, \"Failed to authenticate for MicrosoftEntraId\");\r\n            }\r\n            result.insert_or_assign(web::http::header_names::authorization, JSON::GetUtilityString(Authentication::CreateBearerToken(authResult.Token)));\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_9/Interface.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Rest/Schema/1_7/Interface.h\"\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_9\r\n{\r\n    // Interface to this schema version exposed through IRestClient.\r\n    struct Interface : public V1_7::Interface\r\n    {\r\n        Interface(const std::string& restApi, const Http::HttpClientHelper& helper, IRestClient::Information information, const Http::HttpClientHelper::HttpRequestHeaders& additionalHeaders = {}, Authentication::AuthenticationArguments authArgs = {});\r\n\r\n        Interface(const Interface&) = delete;\r\n        Interface& operator=(const Interface&) = delete;\r\n\r\n        Interface(Interface&&) = default;\r\n        Interface& operator=(Interface&&) = default;\r\n\r\n        Utility::Version GetVersion() const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_9/Json/ManifestDeserializer.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Rest/Schema/1_7/Json/ManifestDeserializer.h\"\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_9::Json\r\n{\r\n    // Manifest Deserializer.\r\n    struct ManifestDeserializer : public V1_7::Json::ManifestDeserializer\r\n    {\r\n    protected:\r\n\r\n        std::optional<Manifest::ManifestInstaller> DeserializeInstaller(const web::json::value& installerJsonObject) const override;\r\n\r\n        Manifest::ManifestVer GetManifestVersion() const override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_9/Json/ManifestDeserializer_1_9.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ManifestDeserializer.h\"\r\n#include <winget/JsonUtil.h>\r\n\r\nusing namespace AppInstaller::Manifest;\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_9::Json\r\n{\r\n    namespace\r\n    {\r\n        // Installer\r\n        constexpr std::string_view ArchiveBinariesDependOnPath = \"ArchiveBinariesDependOnPath\"sv;\r\n    }\r\n\r\n    std::optional<Manifest::ManifestInstaller> ManifestDeserializer::DeserializeInstaller(const web::json::value& installerJsonObject) const\r\n    {\r\n        auto result = V1_7::Json::ManifestDeserializer::DeserializeInstaller(installerJsonObject);\r\n\r\n        if (result)\r\n        {\r\n            auto& installer = result.value();\r\n\r\n            installer.ArchiveBinariesDependOnPath = JSON::GetRawBoolValueFromJsonNode(installerJsonObject, JSON::GetUtilityString(ArchiveBinariesDependOnPath)).value_or(false);\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    Manifest::ManifestVer ManifestDeserializer::GetManifestVersion() const\r\n    {\r\n        return Manifest::s_ManifestVersionV1_9;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/1_9/RestInterface_1_9.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Rest/Schema/1_9/Interface.h\"\r\n#include \"Rest/Schema/CommonRestConstants.h\"\r\n#include \"Rest/Schema/IRestClient.h\"\r\n#include <winget/HttpClientHelper.h>\r\n#include <winget/JsonUtil.h>\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema::V1_9\r\n{\r\n    Interface::Interface(\r\n        const std::string& restApi,\r\n        const Http::HttpClientHelper& httpClientHelper,\r\n        IRestClient::Information information,\r\n        const Http::HttpClientHelper::HttpRequestHeaders& additionalHeaders,\r\n        Authentication::AuthenticationArguments authArgs) : V1_7::Interface(restApi, httpClientHelper, std::move(information), additionalHeaders, std::move(authArgs))\r\n    {\r\n        m_requiredRestApiHeaders[JSON::GetUtilityString(ContractVersion)] = JSON::GetUtilityString(Version_1_9_0.ToString());\r\n    }\r\n\r\n    Utility::Version Interface::GetVersion() const\r\n    {\r\n        return Version_1_9_0;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/AuthenticationInfoParser.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"AuthenticationInfoParser.h\"\r\n#include <winget/JsonUtil.h>\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema\r\n{\r\n    namespace\r\n    {\r\n        // Authentication info constants\r\n        constexpr std::string_view Authentication = \"Authentication\"sv;\r\n        constexpr std::string_view AuthenticationType = \"AuthenticationType\"sv;\r\n        constexpr std::string_view MicrosoftEntraIdAuthenticationInfo = \"MicrosoftEntraIdAuthenticationInfo\"sv;\r\n        constexpr std::string_view MicrosoftEntraId_Resource = \"Resource\"sv;\r\n        constexpr std::string_view MicrosoftEntraId_Scope = \"Scope\"sv;\r\n\r\n        Authentication::AuthenticationType ConvertToAuthenticationTypeForSource(std::string_view in)\r\n        {\r\n            std::string inStrLower = Utility::ToLower(in);\r\n            Authentication::AuthenticationType result = Authentication::AuthenticationType::Unknown;\r\n\r\n            if (inStrLower == \"none\")\r\n            {\r\n                result = Authentication::AuthenticationType::None;\r\n            }\r\n            else if (inStrLower == \"microsoftentraid\")\r\n            {\r\n                result = Authentication::AuthenticationType::MicrosoftEntraId;\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        Authentication::AuthenticationType ConvertToAuthenticationTypeForInstaller(std::string_view in, Manifest::ManifestVer manifestVersion)\r\n        {\r\n            if (manifestVersion >= Manifest::ManifestVer{ Manifest::s_ManifestVersionV1_10 })\r\n            {\r\n                return Authentication::ConvertToAuthenticationType(in);\r\n            }\r\n\r\n            return Authentication::AuthenticationType::Unknown;\r\n        }\r\n    }\r\n\r\n    // The authentication info json looks like below:\r\n    // \"Authentication\": {\r\n    //     \"AuthenticationType\": \"microsoftEntraId\",\r\n    //     \"MicrosoftEntraIdAuthenticationInfo\" : {\r\n    //         \"Resource\": \"GUID\",\r\n    //         \"Scope\" : \"test\"\r\n    //     }\r\n    // }\r\n    Authentication::AuthenticationInfo ParseAuthenticationInfo(const web::json::value& dataObject, ParseAuthenticationInfoType parseType, std::optional<Manifest::ManifestVer> manifestVersion)\r\n    {\r\n        auto authenticationObject = JSON::GetJsonValueFromNode(dataObject, JSON::GetUtilityString(Authentication));\r\n        if (!authenticationObject)\r\n        {\r\n            AICLI_LOG(Repo, Info, << \"Authentication node not found. Assuming authentication type none.\");\r\n            return {};\r\n        }\r\n\r\n        const auto& authenticationObjectNode = authenticationObject.value().get();\r\n        if (authenticationObjectNode.is_null())\r\n        {\r\n            AICLI_LOG(Repo, Info, << \"Authentication node is null. Assuming authentication type none.\");\r\n            return {};\r\n        }\r\n\r\n        Authentication::AuthenticationInfo result;\r\n        result.Type = Authentication::AuthenticationType::Unknown;\r\n\r\n        auto authenticationTypeString = JSON::GetRawStringValueFromJsonNode(authenticationObjectNode, JSON::GetUtilityString(AuthenticationType));\r\n        // AuthenticationType required if Authentication exists and is not null.\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_AUTHENTICATION_INFO, !JSON::IsValidNonEmptyStringValue(authenticationTypeString));\r\n        if (parseType == ParseAuthenticationInfoType::Source)\r\n        {\r\n            result.Type = ConvertToAuthenticationTypeForSource(authenticationTypeString.value());\r\n        }\r\n        else if (parseType == ParseAuthenticationInfoType::Installer)\r\n        {\r\n            THROW_HR_IF(E_INVALIDARG, !manifestVersion);\r\n            result.Type = ConvertToAuthenticationTypeForInstaller(authenticationTypeString.value(), manifestVersion.value());\r\n        }\r\n\r\n        // Parse MicrosoftEntraId info\r\n        auto microsoftEntraIdInfoObject = JSON::GetJsonValueFromNode(authenticationObjectNode, JSON::GetUtilityString(MicrosoftEntraIdAuthenticationInfo));\r\n        if (microsoftEntraIdInfoObject)\r\n        {\r\n            const auto& microsoftEntraIdInfoNode = microsoftEntraIdInfoObject.value().get();\r\n\r\n            Authentication::MicrosoftEntraIdAuthenticationInfo microsoftEntraIdInfo;\r\n\r\n            auto resourceString = JSON::GetRawStringValueFromJsonNode(microsoftEntraIdInfoNode, JSON::GetUtilityString(MicrosoftEntraId_Resource));\r\n            // Resource required if MicrosoftEntraIdAuthenticationInfo exists and is not null.\r\n            THROW_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_AUTHENTICATION_INFO, !JSON::IsValidNonEmptyStringValue(resourceString));\r\n            microsoftEntraIdInfo.Resource = std::move(resourceString.value());\r\n\r\n            auto scopeString = JSON::GetRawStringValueFromJsonNode(microsoftEntraIdInfoNode, JSON::GetUtilityString(MicrosoftEntraId_Scope));\r\n            if (JSON::IsValidNonEmptyStringValue(scopeString))\r\n            {\r\n                microsoftEntraIdInfo.Scope = std::move(scopeString.value());\r\n            }\r\n\r\n            result.MicrosoftEntraIdInfo = std::move(microsoftEntraIdInfo);\r\n        }\r\n\r\n        result.UpdateRequiredFieldsIfNecessary();\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_AUTHENTICATION_INFO, !result.ValidateIntegrity());\r\n\r\n        return result;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/AuthenticationInfoParser.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <cpprest/json.h>\r\n#include <winget/Authentication.h>\r\n#include <winget/ManifestCommon.h>\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema\r\n{\r\n    enum class ParseAuthenticationInfoType\r\n    {\r\n        Source,\r\n        Installer,\r\n    };\r\n\r\n    // Parses AuthenticationInfo from json object.\r\n    // This could be used for installer level parsing as well in manifest deserializer (currently not supported, manifestVersion not used).\r\n    // The authentication info json looks like below:\r\n    // \"Authentication\": {\r\n    //     \"AuthenticationType\": \"microsoftEntraId\",\r\n    //     \"MicrosoftEntraIdAuthenticationInfo\" : {\r\n    //         \"Resource\": \"GUID\",\r\n    //         \"Scope\" : \"test\"\r\n    //     }\r\n    // }\r\n    Authentication::AuthenticationInfo ParseAuthenticationInfo(const web::json::value& dataObject, ParseAuthenticationInfoType parseType, std::optional<Manifest::ManifestVer> manifestVersion = {});\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/CommonRestConstants.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerVersions.h>\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema\r\n{\r\n    // Winget supported contract versions\r\n    const Utility::Version Version_1_0_0{ \"1.0.0\" };\r\n    const Utility::Version Version_1_1_0{ \"1.1.0\" };\r\n    const Utility::Version Version_1_4_0{ \"1.4.0\" };\r\n    const Utility::Version Version_1_5_0{ \"1.5.0\" };\r\n    const Utility::Version Version_1_6_0{ \"1.6.0\" };\r\n    const Utility::Version Version_1_7_0{ \"1.7.0\" };\r\n    const Utility::Version Version_1_9_0{ \"1.9.0\" };\r\n    const Utility::Version Version_1_10_0{ \"1.10.0\" };\r\n    const Utility::Version Version_1_12_0{ \"1.12.0\" };\r\n\r\n    // General API response constants\r\n    constexpr std::string_view Data = \"Data\"sv;\r\n    constexpr std::string_view ContinuationToken = \"ContinuationToken\"sv;\r\n\r\n    // General API Header constant\r\n    constexpr std::string_view ContractVersion = \"Version\"sv;\r\n\r\n    // General endpoint constants\r\n    constexpr std::string_view InformationGetEndpoint = \"/information\"sv;\r\n    constexpr std::string_view ManifestSearchPostEndpoint = \"/manifestSearch\"sv;\r\n    constexpr std::string_view ManifestByVersionAndChannelGetEndpoint = \"/packageManifests/\"sv;\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/IRestClient.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteVersion.h>\r\n#include <winget/Manifest.h>\r\n#include <winget/RepositorySearch.h>\r\n#include <AppInstallerVersions.h>\r\n#include <winget/Authentication.h>\r\n#include <vector>\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema\r\n{\r\n    // The common interface used to interact with RestAPI responses.\r\n    struct IRestClient\r\n    {\r\n    virtual ~IRestClient() = default;\r\n\r\n    struct PackageInfo\r\n    {\r\n        std::string PackageIdentifier;\r\n        std::string PackageName;\r\n        std::string Publisher;\r\n\r\n        PackageInfo(std::string packageIdentifier, std::string packageName, std::string publisher) \r\n        : PackageIdentifier(std::move(packageIdentifier)), PackageName(std::move(packageName)), Publisher(std::move(publisher)) {}\r\n    };\r\n\r\n    // NOTE: When changes are made to VersionInfo struct, remember to update the OptimizedSearch path in RestInterface1_0\r\n    // where VersionInfo struct was directly created from manifest.\r\n    struct VersionInfo\r\n    {\r\n        AppInstaller::Utility::VersionAndChannel VersionAndChannel;\r\n        std::optional<Manifest::Manifest> Manifest;\r\n        std::vector<std::string> PackageFamilyNames;\r\n        std::vector<std::string> ProductCodes;\r\n        std::vector<AppInstaller::Utility::Version> ArpVersions;\r\n        std::vector<std::string> UpgradeCodes;\r\n\r\n        VersionInfo(AppInstaller::Utility::VersionAndChannel versionAndChannel, std::optional<Manifest::Manifest> manifest, std::vector<std::string> packageFamilyNames = {}, std::vector<std::string> productCodes = {}, std::vector<AppInstaller::Utility::Version> arpVersions = {}, std::vector<std::string> upgradeCodes = {})\r\n            : VersionAndChannel(std::move(versionAndChannel)), Manifest(std::move(manifest)), PackageFamilyNames(std::move(packageFamilyNames)), ProductCodes(std::move(productCodes)), ArpVersions(std::move(arpVersions)), UpgradeCodes(std::move(upgradeCodes)) {}\r\n    };\r\n\r\n    // Minimal information retrieved for any search request.\r\n    struct Package\r\n    {\r\n        PackageInfo PackageInformation;\r\n        std::vector<VersionInfo> Versions;\r\n\r\n        Package(PackageInfo packageInfo, std::vector<VersionInfo> versions)\r\n        : PackageInformation(std::move(packageInfo)), Versions(std::move(versions)) {}\r\n    };\r\n\r\n    struct SearchResult\r\n    {\r\n        std::vector<Package> Matches;\r\n        bool Truncated = false;\r\n    };\r\n\r\n    struct SourceAgreementEntry\r\n    {\r\n        std::string Label;\r\n        std::string Text;\r\n        std::string Url;\r\n    };\r\n\r\n    // Information endpoint models\r\n    struct Information\r\n    {\r\n        std::string SourceIdentifier;\r\n        std::vector<std::string> ServerSupportedVersions;\r\n        std::string SourceAgreementsIdentifier;\r\n        std::vector<SourceAgreementEntry> SourceAgreements;\r\n        std::vector<std::string> UnsupportedPackageMatchFields;\r\n        std::vector<std::string> RequiredPackageMatchFields;\r\n        std::vector<std::string> UnsupportedQueryParameters;\r\n        std::vector<std::string> RequiredQueryParameters;\r\n        Authentication::AuthenticationInfo Authentication;\r\n\r\n        Information() {}\r\n        Information(std::string sourceId, std::vector<std::string> versions)\r\n            : SourceIdentifier(std::move(sourceId)), ServerSupportedVersions(std::move(versions)) {}\r\n    };\r\n\r\n    // Get interface version.\r\n    virtual Utility::Version GetVersion() const = 0;\r\n\r\n    // Get source information.\r\n    virtual Information GetSourceInformation() const = 0;\r\n\r\n    // Performs a search based on the given criteria.\r\n    virtual SearchResult Search(const SearchRequest& request) const = 0;\r\n\r\n    // Gets the manifest for given version\r\n    virtual std::optional<Manifest::Manifest> GetManifestByVersion(const std::string& packageId, const std::string& version, const std::string& channel) const = 0;\r\n    \r\n    // Gets the manifests for given query parameters\r\n    virtual std::vector<Manifest::Manifest> GetManifests(const std::string& packageId, const std::map<std::string_view, std::string>& params = {}) const = 0;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/InformationResponseDeserializer.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Rest/Schema/IRestClient.h\"\r\n#include <winget/JsonUtil.h>\r\n#include \"Rest/Schema/CommonRestConstants.h\"\r\n#include \"AuthenticationInfoParser.h\"\r\n#include \"InformationResponseDeserializer.h\"\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema\r\n{\r\n    namespace\r\n    {\r\n        // Information response constants\r\n        constexpr std::string_view SourceIdentifier = \"SourceIdentifier\"sv;\r\n        constexpr std::string_view ServerSupportedVersions = \"ServerSupportedVersions\"sv;\r\n\r\n        constexpr std::string_view SourceAgreements = \"SourceAgreements\"sv;\r\n        constexpr std::string_view SourceAgreementsIdentifier = \"AgreementsIdentifier\"sv;\r\n        constexpr std::string_view SourceAgreementsContent = \"Agreements\"sv;\r\n        constexpr std::string_view SourceAgreementLabel = \"AgreementLabel\"sv;\r\n        constexpr std::string_view SourceAgreementText = \"Agreement\"sv;\r\n        constexpr std::string_view SourceAgreementUrl = \"AgreementUrl\"sv;\r\n\r\n        constexpr std::string_view UnsupportedPackageMatchFields = \"UnsupportedPackageMatchFields\"sv;\r\n        constexpr std::string_view RequiredPackageMatchFields = \"RequiredPackageMatchFields\"sv;\r\n        constexpr std::string_view UnsupportedQueryParameters = \"UnsupportedQueryParameters\"sv;\r\n        constexpr std::string_view RequiredQueryParameters = \"RequiredQueryParameters\"sv;\r\n    }\r\n\r\n    IRestClient::Information InformationResponseDeserializer::Deserialize(const web::json::value& dataObject) const\r\n    {\r\n        // Get information result from json output.\r\n        std::optional<IRestClient::Information> information = DeserializeInformation(dataObject);\r\n\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE, !information);\r\n\r\n        return information.value();\r\n    }\r\n\r\n    std::optional<IRestClient::Information> InformationResponseDeserializer::DeserializeInformation(const web::json::value& dataObject) const\r\n    {\r\n        try\r\n        {\r\n            if (dataObject.is_null())\r\n            {\r\n                AICLI_LOG(Repo, Error, << \"Missing json object.\");\r\n                return {};\r\n            }\r\n\r\n            std::optional<std::reference_wrapper<const web::json::value>> data = JSON::GetJsonValueFromNode(dataObject, JSON::GetUtilityString(Data));\r\n            if (!data)\r\n            {\r\n                AICLI_LOG(Repo, Error, << \"Missing data\");\r\n                return {};\r\n            }\r\n\r\n            const auto& dataValue = data.value().get();\r\n            std::optional<std::string> sourceId = JSON::GetRawStringValueFromJsonNode(dataValue, JSON::GetUtilityString(SourceIdentifier));\r\n            if (!JSON::IsValidNonEmptyStringValue(sourceId))\r\n            {\r\n                AICLI_LOG(Repo, Error, << \"Missing source identifier\");\r\n                return {};\r\n            }\r\n\r\n            std::vector<std::string> allVersions = JSON::GetRawStringArrayFromJsonNode(dataValue, JSON::GetUtilityString(ServerSupportedVersions));\r\n            if (allVersions.size() == 0)\r\n            {\r\n                AICLI_LOG(Repo, Error, << \"Missing supported versions.\");\r\n                return {};\r\n            }\r\n\r\n            IRestClient::Information info{ std::move(sourceId.value()), std::move(allVersions) };\r\n\r\n            auto agreements = JSON::GetJsonValueFromNode(dataValue, JSON::GetUtilityString(SourceAgreements));\r\n            if (agreements)\r\n            {\r\n                const auto& agreementsValue = agreements.value().get();\r\n\r\n                auto agreementsIdentifier = JSON::GetRawStringValueFromJsonNode(agreementsValue, JSON::GetUtilityString(SourceAgreementsIdentifier));\r\n                if (!JSON::IsValidNonEmptyStringValue(agreementsIdentifier))\r\n                {\r\n                    AICLI_LOG(Repo, Error, << \"SourceAgreements node exists but AgreementsIdentifier is missing.\");\r\n                    return {};\r\n                }\r\n\r\n                info.SourceAgreementsIdentifier = std::move(agreementsIdentifier.value());\r\n\r\n                auto agreementsContent = JSON::GetRawJsonArrayFromJsonNode(agreementsValue, JSON::GetUtilityString(SourceAgreementsContent));\r\n                if (agreementsContent)\r\n                {\r\n                    for (auto const& agreementNode : agreementsContent.value().get())\r\n                    {\r\n                        IRestClient::SourceAgreementEntry agreementEntry;\r\n\r\n                        std::optional<std::string> label = JSON::GetRawStringValueFromJsonNode(agreementNode, JSON::GetUtilityString(SourceAgreementLabel));\r\n                        if (JSON::IsValidNonEmptyStringValue(label))\r\n                        {\r\n                            agreementEntry.Label = std::move(label.value());\r\n                        }\r\n\r\n                        std::optional<std::string> text = JSON::GetRawStringValueFromJsonNode(agreementNode, JSON::GetUtilityString(SourceAgreementText));\r\n                        if (JSON::IsValidNonEmptyStringValue(text))\r\n                        {\r\n                            agreementEntry.Text = std::move(text.value());\r\n                        }\r\n\r\n                        std::optional<std::string> url = JSON::GetRawStringValueFromJsonNode(agreementNode, JSON::GetUtilityString(SourceAgreementUrl));\r\n                        if (JSON::IsValidNonEmptyStringValue(url))\r\n                        {\r\n                            agreementEntry.Url = std::move(url.value());\r\n                        }\r\n\r\n                        if (!agreementEntry.Label.empty() || !agreementEntry.Text.empty() || !agreementEntry.Url.empty())\r\n                        {\r\n                            info.SourceAgreements.emplace_back(std::move(agreementEntry));\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            info.RequiredPackageMatchFields = JSON::GetRawStringArrayFromJsonNode(dataValue, JSON::GetUtilityString(RequiredPackageMatchFields));\r\n            info.UnsupportedPackageMatchFields = JSON::GetRawStringArrayFromJsonNode(dataValue, JSON::GetUtilityString(UnsupportedPackageMatchFields));\r\n            info.RequiredQueryParameters = JSON::GetRawStringArrayFromJsonNode(dataValue, JSON::GetUtilityString(RequiredQueryParameters));\r\n            info.UnsupportedQueryParameters = JSON::GetRawStringArrayFromJsonNode(dataValue, JSON::GetUtilityString(UnsupportedQueryParameters));\r\n\r\n            info.Authentication = ParseAuthenticationInfo(dataValue, ParseAuthenticationInfoType::Source);\r\n\r\n            return info;\r\n        }\r\n        catch (const std::exception& e)\r\n        {\r\n            AICLI_LOG(Repo, Error, << \"Error encountered while deserializing Information. Reason: \" << e.what());\r\n        }\r\n        catch (...)\r\n        {\r\n            AICLI_LOG(Repo, Error, << \"Received invalid information.\");\r\n        }\r\n\r\n        return {};\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/InformationResponseDeserializer.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Rest/Schema/IRestClient.h\"\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema\r\n{\r\n    // Information response Deserializer.\r\n    struct InformationResponseDeserializer\r\n    {\r\n        // Gets the information model for given response\r\n        IRestClient::Information Deserialize(const web::json::value& dataObject) const;\r\n\r\n    protected:\r\n        std::optional<IRestClient::Information> DeserializeInformation(const web::json::value& dataObject) const;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/SearchRequestComposer.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"SearchRequestComposer.h\"\r\n#include \"Rest/Schema/1_0/Json/SearchRequestSerializer.h\"\r\n#include \"Rest/Schema/1_1/Json/SearchRequestSerializer.h\"\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema\r\n{\r\n    struct SearchRequestComposer::impl\r\n    {\r\n        // The serializer.  We only have one lineage (1.0+) right now.\r\n        std::unique_ptr<Rest::Schema::V1_0::Json::SearchRequestSerializer> m_serializer;\r\n    };\r\n\r\n    SearchRequestComposer::SearchRequestComposer(SearchRequestComposer&&) noexcept = default;\r\n    SearchRequestComposer& SearchRequestComposer::operator=(SearchRequestComposer&&) noexcept = default;\r\n\r\n    SearchRequestComposer::~SearchRequestComposer() = default;\r\n\r\n    SearchRequestComposer::SearchRequestComposer(const Utility::Version& schemaVersion)\r\n    {\r\n        const auto& parts = schemaVersion.GetParts();\r\n        THROW_HR_IF(E_INVALIDARG, parts.empty());\r\n\r\n        m_pImpl = std::make_unique<impl>();\r\n\r\n        if (parts[0].Integer == 1)\r\n        {\r\n            if (parts.size() == 1 || parts[1].Integer == 0)\r\n            {\r\n                m_pImpl->m_serializer = std::make_unique<Rest::Schema::V1_0::Json::SearchRequestSerializer>();\r\n            }\r\n            else\r\n            {\r\n                m_pImpl->m_serializer = std::make_unique<Rest::Schema::V1_1::Json::SearchRequestSerializer>();\r\n            }\r\n        }\r\n        else\r\n        {\r\n            THROW_HR(HRESULT_FROM_WIN32(ERROR_UNSUPPORTED_TYPE));\r\n        }\r\n    }\r\n\r\n    web::json::value SearchRequestComposer::Serialize(const AppInstaller::Repository::SearchRequest& searchRequest) const\r\n    {\r\n        return m_pImpl->m_serializer->Serialize(searchRequest);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/SearchRequestComposer.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerVersions.h>\r\n#include <winget/JsonUtil.h>\r\n#include <winget/RepositorySearch.h>\r\n\r\n#include <memory>\r\n#include <vector>\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema\r\n{\r\n    // Exposes functions for creating JSON REST request body from search requests.\r\n    struct SearchRequestComposer\r\n    {\r\n        SearchRequestComposer(const Utility::Version& schemaVersion);\r\n\r\n        SearchRequestComposer(const SearchRequestComposer&) = delete;\r\n        SearchRequestComposer& operator=(const SearchRequestComposer&) = delete;\r\n\r\n        SearchRequestComposer(SearchRequestComposer&&) noexcept;\r\n        SearchRequestComposer& operator=(SearchRequestComposer&&) noexcept;\r\n\r\n        ~SearchRequestComposer();\r\n\r\n        // Create search request rest call body from a given SearchRequest\r\n        web::json::value Serialize(const AppInstaller::Repository::SearchRequest& searchRequest) const;\r\n\r\n    private:\r\n        struct impl;\r\n        std::unique_ptr<impl> m_pImpl;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/SearchResponseParser.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"SearchResponseParser.h\"\r\n#include \"Rest/Schema/1_0/Json/SearchResponseDeserializer.h\"\r\n#include \"Rest/Schema/1_4/Json/SearchResponseDeserializer.h\"\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema\r\n{\r\n    struct SearchResponseParser::impl\r\n    {\r\n        // The deserializer.  We only have one lineage (1.0+) right now.\r\n        std::unique_ptr<Rest::Schema::V1_0::Json::SearchResponseDeserializer> m_deserializer;\r\n    };\r\n\r\n    SearchResponseParser::SearchResponseParser(SearchResponseParser&&) noexcept = default;\r\n    SearchResponseParser& SearchResponseParser::operator=(SearchResponseParser&&) noexcept = default;\r\n\r\n    SearchResponseParser::~SearchResponseParser() = default;\r\n\r\n    SearchResponseParser::SearchResponseParser(const Utility::Version& schemaVersion)\r\n    {\r\n        const auto& parts = schemaVersion.GetParts();\r\n        THROW_HR_IF(E_INVALIDARG, parts.empty());\r\n\r\n        m_pImpl = std::make_unique<impl>();\r\n\r\n        if (parts[0].Integer == 1)\r\n        {\r\n            if (parts.size() == 1 || parts[1].Integer < 4)\r\n            {\r\n                m_pImpl->m_deserializer = std::make_unique<Rest::Schema::V1_0::Json::SearchResponseDeserializer>();\r\n            }\r\n            else\r\n            {\r\n                m_pImpl->m_deserializer = std::make_unique<Rest::Schema::V1_4::Json::SearchResponseDeserializer>();\r\n            }\r\n        }\r\n        else\r\n        {\r\n            THROW_HR(HRESULT_FROM_WIN32(ERROR_UNSUPPORTED_TYPE));\r\n        }\r\n    }\r\n\r\n    IRestClient::SearchResult SearchResponseParser::Deserialize(const web::json::value& searchResultJsonObject) const\r\n    {\r\n        return m_pImpl->m_deserializer->Deserialize(searchResultJsonObject);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/Rest/Schema/SearchResponseParser.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerVersions.h>\r\n#include <winget/JsonUtil.h>\r\n#include \"Rest/Schema/IRestClient.h\"\r\n\r\n#include <memory>\r\n#include <vector>\r\n\r\nnamespace AppInstaller::Repository::Rest::Schema\r\n{\r\n    // Exposes functions for parsing JSON REST responses to IRestClient SearchResult.\r\n    struct SearchResponseParser\r\n    {\r\n        SearchResponseParser(const Utility::Version& schemaVersion);\r\n\r\n        SearchResponseParser(const SearchResponseParser&) = delete;\r\n        SearchResponseParser& operator=(const SearchResponseParser&) = delete;\r\n\r\n        SearchResponseParser(SearchResponseParser&&) noexcept;\r\n        SearchResponseParser& operator=(SearchResponseParser&&) noexcept;\r\n\r\n        ~SearchResponseParser();\r\n\r\n        // Gets the search result for response object\r\n        IRestClient::SearchResult Deserialize(const web::json::value& searchResultJsonObject) const;\r\n\r\n    private:\r\n        struct impl;\r\n        std::unique_ptr<impl> m_pImpl;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/SourceFactory.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ISource.h\"\r\n#include <AppInstallerProgress.h>\r\n\r\n#include <memory>\r\n\r\n\r\nnamespace AppInstaller::Repository\r\n{\r\n    // Interface for manipulating a source based on its details.\r\n    struct ISourceFactory\r\n    {\r\n        virtual ~ISourceFactory() = default;\r\n\r\n        // Gets the name of the source type.\r\n        virtual std::string_view TypeName() const = 0;\r\n\r\n        // Creates a source object from the given details.\r\n        virtual std::shared_ptr<ISourceReference> Create(const SourceDetails& details) = 0;\r\n\r\n        // Adds the source from the given details, writing back to the details any changes.\r\n        // Return value indicates whether the action completed.\r\n        virtual bool Add(SourceDetails& details, IProgressCallback& progress) = 0;\r\n\r\n        // Updates the source from the given details (may not change the details).\r\n        // Return value indicates whether the action completed.\r\n        virtual bool Update(const SourceDetails& details, IProgressCallback& progress) = 0;\r\n\r\n        // Updates the source from the given details (may not change the details).\r\n        // This version is for use in automatic, background updates to the source.\r\n        // It is done this way to preserve the signature for use with member function pointers.\r\n        // Return value indicates whether the action completed.\r\n        virtual bool BackgroundUpdate(const SourceDetails& details, IProgressCallback& progress)\r\n        {\r\n            return Update(details, progress);\r\n        }\r\n\r\n        // Removes the source from the given details.\r\n        // Return value indicates whether the action completed.\r\n        virtual bool Remove(const SourceDetails& details, IProgressCallback& progress) = 0;\r\n\r\n        // Gets the factory for the given type.\r\n        static std::unique_ptr<ISourceFactory> GetForType(std::string_view type);\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/SourceList.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"SourceList.h\"\r\n#include \"SourcePolicy.h\"\r\n#include \"Microsoft/PreIndexedPackageSourceFactory.h\"\r\n#include \"Rest/RestSourceFactory.h\"\r\n\r\n#include <winget/AdminSettings.h>\r\n#include <winget/Certificates.h>\r\n#include <CertificateResources.h>\r\n\r\nusing namespace AppInstaller::Settings;\r\nusing namespace std::string_view_literals;\r\n\r\nnamespace AppInstaller::Repository\r\n{\r\n    namespace\r\n    {\r\n        constexpr std::string_view s_SourcesYaml_Sources = \"Sources\"sv;\r\n        constexpr std::string_view s_SourcesYaml_Source_Name = \"Name\"sv;\r\n        constexpr std::string_view s_SourcesYaml_Source_Type = \"Type\"sv;\r\n        constexpr std::string_view s_SourcesYaml_Source_Arg = \"Arg\"sv;\r\n        constexpr std::string_view s_SourcesYaml_Source_Data = \"Data\"sv;\r\n        constexpr std::string_view s_SourcesYaml_Source_Identifier = \"Identifier\"sv;\r\n        constexpr std::string_view s_SourcesYaml_Source_IsTombstone = \"IsTombstone\"sv;\r\n        constexpr std::string_view s_SourcesYaml_Source_IsOverride = \"IsOverride\"sv;\r\n        constexpr std::string_view s_SourcesYaml_Source_Explicit = \"Explicit\"sv;\r\n        constexpr std::string_view s_SourcesYaml_Source_TrustLevel = \"TrustLevel\"sv;\r\n        constexpr std::string_view s_SourcesYaml_Source_Priority = \"Priority\"sv;\r\n\r\n        constexpr std::string_view s_MetadataYaml_Sources = \"Sources\"sv;\r\n        constexpr std::string_view s_MetadataYaml_Source_Name = \"Name\"sv;\r\n        constexpr std::string_view s_MetadataYaml_Source_LastUpdate = \"LastUpdate\"sv;\r\n        constexpr std::string_view s_MetadataYaml_Source_DoNotUpdateBefore = \"DoNotUpdateBefore\"sv;\r\n        constexpr std::string_view s_MetadataYaml_Source_AcceptedAgreementsIdentifier = \"AcceptedAgreementsIdentifier\"sv;\r\n        constexpr std::string_view s_MetadataYaml_Source_AcceptedAgreementFields = \"AcceptedAgreementFields\"sv;\r\n\r\n        constexpr std::string_view s_Source_WingetCommunityDefault_Name = \"winget\"sv;\r\n        constexpr std::string_view s_Source_WingetCommunityDefault_Arg = \"https://cdn.winget.microsoft.com/cache\"sv;\r\n        constexpr std::string_view s_Source_WingetCommunityDefault_Data = \"Microsoft.Winget.Source_8wekyb3d8bbwe\"sv;\r\n        constexpr std::string_view s_Source_WingetCommunityDefault_Identifier = \"Microsoft.Winget.Source_8wekyb3d8bbwe\"sv;\r\n\r\n        constexpr std::string_view s_Source_MSStoreDefault_Name = \"msstore\"sv;\r\n        constexpr std::string_view s_Source_MSStoreDefault_Arg = \"https://storeedgefd.dsx.mp.microsoft.com/v9.0\"sv;\r\n        constexpr std::string_view s_Source_MSStoreDefault_Identifier = \"StoreEdgeFD\"sv;\r\n\r\n        constexpr std::string_view s_Source_DesktopFrameworks_Name = \"microsoft.builtin.desktop.frameworks\"sv;\r\n        constexpr std::string_view s_Source_DesktopFrameworks_Arg = \"https://cdn.winget.microsoft.com/platform\"sv;\r\n        constexpr std::string_view s_Source_DesktopFrameworks_Data = \"Microsoft.Winget.Platform.Source_8wekyb3d8bbwe\"sv;\r\n        constexpr std::string_view s_Source_DesktopFrameworks_Identifier = \"Microsoft.Winget.Platform.Source_8wekyb3d8bbwe\"sv;\r\n\r\n        constexpr std::string_view s_Source_WingetCommunityFont_Name = \"winget-font\"sv;\r\n        constexpr std::string_view s_Source_WingetCommunityFont_Arg = \"https://cdn.winget.microsoft.com/fonts\"sv;\r\n        constexpr std::string_view s_Source_WingetCommunityFont_Data = \"Microsoft.Winget.Fonts.Source_8wekyb3d8bbwe\"sv;\r\n        constexpr std::string_view s_Source_WingetCommunityFont_Identifier = \"Microsoft.Winget.Fonts.Source_8wekyb3d8bbwe\"sv;\r\n\r\n        // Attempts to read a single scalar value from the node.\r\n        template<typename Value>\r\n        bool TryReadScalar(std::string_view settingName, const std::string& settingValue, const YAML::Node& sourceNode, std::string_view name, Value& value, bool required = true)\r\n        {\r\n            YAML::Node valueNode = sourceNode[std::string{ name }];\r\n\r\n            if (!valueNode || !valueNode.IsScalar())\r\n            {\r\n                if (required)\r\n                {\r\n                    AICLI_LOG(Repo, Error, << \"Setting '\" << settingName << \"' did not contain the expected format (\" << name << \" is invalid within a source):\\n\" << settingValue);\r\n                }\r\n                return false;\r\n            }\r\n\r\n            value = valueNode.as<Value>();\r\n            return true;\r\n        }\r\n\r\n        // Attempts to read the source details from the given stream.\r\n        // Results are all or nothing; if any failures occur, no details are returned.\r\n        bool TryReadSourceDetails(\r\n            std::string_view settingName,\r\n            std::istream& stream,\r\n            std::string_view rootName,\r\n            std::function<bool(SourceDetailsInternal&, const std::string&, const YAML::Node&)> parse,\r\n            std::vector<SourceDetailsInternal>& sourceDetails)\r\n        {\r\n            std::vector<SourceDetailsInternal> result;\r\n            std::string settingValue = Utility::ReadEntireStream(stream);\r\n\r\n            YAML::Node document;\r\n            try\r\n            {\r\n                document = YAML::Load(settingValue);\r\n            }\r\n            catch (const std::exception& e)\r\n            {\r\n                AICLI_LOG(YAML, Error, << \"Setting '\" << settingName << \"' contained invalid YAML (\" << e.what() << \"):\\n\" << settingValue);\r\n                return false;\r\n            }\r\n\r\n            try\r\n            {\r\n                YAML::Node sources = document[rootName];\r\n                if (!sources)\r\n                {\r\n                    AICLI_LOG(Repo, Error, << \"Setting '\" << settingName << \"' did not contain the expected format (missing \" << rootName << \"):\\n\" << settingValue);\r\n                    return false;\r\n                }\r\n\r\n                if (sources.IsNull())\r\n                {\r\n                    // An empty sources is an acceptable thing.\r\n                    return true;\r\n                }\r\n\r\n                if (!sources.IsSequence())\r\n                {\r\n                    AICLI_LOG(Repo, Error, << \"Setting '\" << settingName << \"' did not contain the expected format (\" << rootName << \" was not a sequence):\\n\" << settingValue);\r\n                    return false;\r\n                }\r\n\r\n                for (const auto& source : sources.Sequence())\r\n                {\r\n                    SourceDetailsInternal details;\r\n                    if (!parse(details, settingValue, source))\r\n                    {\r\n                        return false;\r\n                    }\r\n\r\n                    result.emplace_back(std::move(details));\r\n                }\r\n            }\r\n            catch (const std::exception& e)\r\n            {\r\n                AICLI_LOG(YAML, Error, << \"Setting '\" << settingName << \"' contained unexpected YAML (\" << e.what() << \"):\\n\" << settingValue);\r\n                return false;\r\n            }\r\n\r\n            sourceDetails = std::move(result);\r\n            return true;\r\n        }\r\n\r\n        // Gets the source details from a particular setting, or an empty optional if no setting exists.\r\n        std::optional<std::vector<SourceDetailsInternal>> TryGetSourcesFromSetting(\r\n            Settings::Stream& setting,\r\n            std::string_view rootName,\r\n            std::function<bool(SourceDetailsInternal&, const std::string&, const YAML::Node&)> parse)\r\n        {\r\n            auto sourcesStream = setting.Get();\r\n            if (!sourcesStream)\r\n            {\r\n                // Note that this case is different than the one in which all sources have been removed.\r\n                return {};\r\n            }\r\n            else\r\n            {\r\n                std::vector<SourceDetailsInternal> result;\r\n                if (!TryReadSourceDetails(setting.GetName(), *sourcesStream, rootName, parse, result))\r\n                {\r\n                    AICLI_LOG(YAML, Error, << \"Ignoring corrupted source data.\");\r\n                }\r\n                return result;\r\n            }\r\n        }\r\n\r\n        // Gets the source details from a particular setting.\r\n        std::vector<SourceDetailsInternal> GetSourcesFromSetting(\r\n            Settings::Stream& setting,\r\n            std::string_view rootName,\r\n            std::function<bool(SourceDetailsInternal&, const std::string&, const YAML::Node&)> parse)\r\n        {\r\n            return TryGetSourcesFromSetting(setting, rootName, parse).value_or(std::vector<SourceDetailsInternal>{});\r\n        }\r\n\r\n        // Sets the sources for a particular setting, from a particular origin.\r\n        [[nodiscard]] bool SetSourcesToSettingWithFilter(Settings::Stream& setting, SourceOrigin origin, const std::vector<SourceDetailsInternal>& sources)\r\n        {\r\n            YAML::Emitter out;\r\n            out << YAML::BeginMap;\r\n            out << YAML::Key << s_SourcesYaml_Sources;\r\n            out << YAML::BeginSeq;\r\n\r\n            for (const auto& details : sources)\r\n            {\r\n                if (details.Origin == origin)\r\n                {\r\n                    out << YAML::BeginMap;\r\n                    out << YAML::Key << s_SourcesYaml_Source_Name << YAML::Value << details.Name;\r\n                    out << YAML::Key << s_SourcesYaml_Source_Type << YAML::Value << details.Type;\r\n                    out << YAML::Key << s_SourcesYaml_Source_Arg << YAML::Value << details.Arg;\r\n                    out << YAML::Key << s_SourcesYaml_Source_Data << YAML::Value << details.Data;\r\n                    out << YAML::Key << s_SourcesYaml_Source_Identifier << YAML::Value << details.Identifier;\r\n                    out << YAML::Key << s_SourcesYaml_Source_IsTombstone << YAML::Value << details.IsTombstone;\r\n                    out << YAML::Key << s_SourcesYaml_Source_IsOverride << YAML::Value << details.IsOverride;\r\n                    out << YAML::Key << s_SourcesYaml_Source_Explicit << YAML::Value << details.Explicit;\r\n                    out << YAML::Key << s_SourcesYaml_Source_TrustLevel << YAML::Value << static_cast<int64_t>(details.TrustLevel);\r\n                    out << YAML::Key << s_SourcesYaml_Source_Priority << YAML::Value << details.Priority;\r\n                    out << YAML::EndMap;\r\n                }\r\n            }\r\n\r\n            out << YAML::EndSeq;\r\n            out << YAML::EndMap;\r\n\r\n            return setting.Set(out.str());\r\n        }\r\n\r\n        // Assumes that names match already\r\n        bool DoSourceDetailsInternalMatch(const SourceDetailsInternal& left, const SourceDetailsInternal& right)\r\n        {\r\n            return left.Arg == right.Arg &&\r\n                left.Identifier == right.Identifier &&\r\n                Utility::CaseInsensitiveEquals(left.Type, right.Type);\r\n        }\r\n\r\n        bool ShouldBeHidden(const SourceDetailsInternal& details)\r\n        {\r\n            return details.IsTombstone || details.Origin == SourceOrigin::Metadata || !details.IsVisible;\r\n        }\r\n    }\r\n\r\n    void SourceDetailsInternal::CopyMetadataFieldsTo(SourceDetailsInternal& target)\r\n    {\r\n        if (LastUpdateTime > target.LastUpdateTime)\r\n        {\r\n            target.LastUpdateTime = LastUpdateTime;\r\n        }\r\n\r\n        if (DoNotUpdateBefore > target.DoNotUpdateBefore)\r\n        {\r\n            target.DoNotUpdateBefore = DoNotUpdateBefore;\r\n        }\r\n\r\n        target.AcceptedAgreementFields = AcceptedAgreementFields;\r\n        target.AcceptedAgreementsIdentifier = AcceptedAgreementsIdentifier;\r\n    }\r\n\r\n    void SourceDetailsInternal::CopyMetadataFieldsFrom(const SourceDetails& source)\r\n    {\r\n        LastUpdateTime = source.LastUpdateTime;\r\n        DoNotUpdateBefore = source.DoNotUpdateBefore;\r\n    }\r\n\r\n    void SourceDetailsInternal::CopyOverrideFieldsFrom(const SourceDetails& overrideSource)\r\n    {\r\n        // These are the supported Override fields.\r\n        Explicit = overrideSource.Explicit;\r\n        Priority = overrideSource.Priority;\r\n    }\r\n\r\n    bool SourceDetailsInternal::operator<(const SourceDetailsInternal& other) const\r\n    {\r\n        // Higher values come first in ordering and must be \"less than\" for standard sorting\r\n        return Priority > other.Priority;\r\n    }\r\n\r\n    std::string_view GetWellKnownSourceName(WellKnownSource source)\r\n    {\r\n        switch (source)\r\n        {\r\n        case WellKnownSource::WinGet:\r\n            return s_Source_WingetCommunityDefault_Name;\r\n        case WellKnownSource::MicrosoftStore:\r\n            return s_Source_MSStoreDefault_Name;\r\n        case WellKnownSource::DesktopFrameworks:\r\n            return s_Source_DesktopFrameworks_Name;\r\n        case WellKnownSource::WinGetFont:\r\n            return s_Source_WingetCommunityFont_Name;\r\n        }\r\n\r\n        return {};\r\n    }\r\n\r\n    std::string_view GetWellKnownSourceArg(WellKnownSource source)\r\n    {\r\n        switch (source)\r\n        {\r\n        case WellKnownSource::WinGet:\r\n            return s_Source_WingetCommunityDefault_Arg;\r\n        case WellKnownSource::MicrosoftStore:\r\n            return s_Source_MSStoreDefault_Arg;\r\n        case WellKnownSource::DesktopFrameworks:\r\n            return s_Source_DesktopFrameworks_Arg;\r\n        case WellKnownSource::WinGetFont:\r\n            return s_Source_WingetCommunityFont_Arg;\r\n        }\r\n\r\n        return {};\r\n    }\r\n\r\n    std::string_view GetWellKnownSourceIdentifier(WellKnownSource source)\r\n    {\r\n        switch (source)\r\n        {\r\n        case WellKnownSource::WinGet:\r\n            return s_Source_WingetCommunityDefault_Identifier;\r\n        case WellKnownSource::MicrosoftStore:\r\n            return s_Source_MSStoreDefault_Identifier;\r\n        case WellKnownSource::DesktopFrameworks:\r\n            return s_Source_DesktopFrameworks_Identifier;\r\n        case WellKnownSource::WinGetFont:\r\n            return s_Source_WingetCommunityFont_Identifier;\r\n        }\r\n\r\n        return {};\r\n    }\r\n\r\n    std::optional<WellKnownSource> CheckForWellKnownSourceMatch(std::string_view name, std::string_view arg, std::string_view type)\r\n    {\r\n        if (name == s_Source_WingetCommunityDefault_Name && arg == s_Source_WingetCommunityDefault_Arg && type == Microsoft::PreIndexedPackageSourceFactory::Type())\r\n        {\r\n            return WellKnownSource::WinGet;\r\n        }\r\n\r\n        if (name == s_Source_MSStoreDefault_Name && arg == s_Source_MSStoreDefault_Arg && type == Rest::RestSourceFactory::Type())\r\n        {\r\n            return WellKnownSource::MicrosoftStore;\r\n        }\r\n\r\n        if (name == s_Source_DesktopFrameworks_Name && arg == s_Source_DesktopFrameworks_Arg && type == Microsoft::PreIndexedPackageSourceFactory::Type())\r\n        {\r\n            return WellKnownSource::DesktopFrameworks;\r\n        }\r\n\r\n        if (name == s_Source_WingetCommunityFont_Name && arg == s_Source_WingetCommunityFont_Arg && type == Rest::RestSourceFactory::Type())\r\n        {\r\n            return WellKnownSource::WinGetFont;\r\n        }\r\n\r\n        return {};\r\n    }\r\n\r\n    SourceDetailsInternal GetWellKnownSourceDetailsInternal(WellKnownSource source)\r\n    {\r\n        switch (source)\r\n        {\r\n        case WellKnownSource::WinGet:\r\n        {\r\n            SourceDetailsInternal details;\r\n            details.Origin = SourceOrigin::Default;\r\n            details.Name = s_Source_WingetCommunityDefault_Name;\r\n            details.Type = Microsoft::PreIndexedPackageSourceFactory::Type();\r\n            details.Arg = s_Source_WingetCommunityDefault_Arg;\r\n            details.Data = s_Source_WingetCommunityDefault_Data;\r\n            details.Identifier = s_Source_WingetCommunityDefault_Identifier;\r\n            details.TrustLevel = SourceTrustLevel::Trusted | SourceTrustLevel::StoreOrigin;\r\n            return details;\r\n        }\r\n        case WellKnownSource::MicrosoftStore:\r\n        {\r\n            SourceDetailsInternal details;\r\n            details.Origin = SourceOrigin::Default;\r\n            details.Name = s_Source_MSStoreDefault_Name;\r\n            details.Type = Rest::RestSourceFactory::Type();\r\n            details.Arg = s_Source_MSStoreDefault_Arg;\r\n            details.Identifier = s_Source_MSStoreDefault_Identifier;\r\n            details.TrustLevel = SourceTrustLevel::Trusted;\r\n            details.SupportInstalledSearchCorrelation = false;\r\n\r\n            if (!Settings::IsAdminSettingEnabled(Settings::BoolAdminSetting::BypassCertificatePinningForMicrosoftStore))\r\n            {\r\n                using namespace AppInstaller::Certificates;\r\n\r\n                PinningChain chain;\r\n                auto chainElement = chain.Root();\r\n                chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_ROOT_1, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::PublicKey);\r\n                chainElement = chainElement.Next();\r\n                chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_INTERMEDIATE_1, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::Subject | PinningVerificationType::Issuer);\r\n                chainElement = chainElement.Next();\r\n                chainElement->LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_1, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::Subject | PinningVerificationType::Issuer);\r\n\r\n                PinningChain chain2;\r\n                auto chainElement2 = chain2.Root();\r\n                chainElement2->LoadCertificate(IDX_CERTIFICATE_STORE_ROOT_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::PublicKey);\r\n                chainElement2 = chainElement2.Next();\r\n                chainElement2->LoadCertificate(IDX_CERTIFICATE_STORE_INTERMEDIATE_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::Subject | PinningVerificationType::Issuer);\r\n                chainElement2 = chainElement2.Next();\r\n                chainElement2->LoadCertificate(IDX_CERTIFICATE_STORE_LEAF_2, CERTIFICATE_RESOURCE_TYPE).SetPinning(PinningVerificationType::Subject | PinningVerificationType::Issuer);\r\n\r\n                // See https://aka.ms/AzureTLSCAs (internal) for the source of these CAs\r\n                PinningChain chain3;\r\n                chain3.PartialChain().Root()->\r\n                    LoadCertificate(IDX_CERTIFICATE_MS_TLS_ECC_ROOT_G2, CERTIFICATE_RESOURCE_TYPE).\r\n                    SetPinning(PinningVerificationType::PublicKey | PinningVerificationType::AnyIssuer | PinningVerificationType::RequireNonLeaf);\r\n\r\n                PinningChain chain4;\r\n                chain4.PartialChain().Root()->\r\n                    LoadCertificate(IDX_CERTIFICATE_MS_TLS_RSA_ROOT_G2, CERTIFICATE_RESOURCE_TYPE).\r\n                    SetPinning(PinningVerificationType::PublicKey | PinningVerificationType::AnyIssuer | PinningVerificationType::RequireNonLeaf);\r\n\r\n                details.CertificatePinningConfiguration = PinningConfiguration(\"Microsoft Store Source\");\r\n                details.CertificatePinningConfiguration.AddChain(std::move(chain));\r\n                details.CertificatePinningConfiguration.AddChain(std::move(chain2));\r\n                details.CertificatePinningConfiguration.AddChain(std::move(chain3));\r\n                details.CertificatePinningConfiguration.AddChain(std::move(chain4));\r\n            }\r\n\r\n            return details;\r\n        }\r\n        case WellKnownSource::DesktopFrameworks:\r\n        {\r\n            SourceDetailsInternal details;\r\n            details.Origin = SourceOrigin::Default;\r\n            details.Name = s_Source_DesktopFrameworks_Name;\r\n            details.Type = Microsoft::PreIndexedPackageSourceFactory::Type();\r\n            details.Arg = s_Source_DesktopFrameworks_Arg;\r\n            details.Data = s_Source_DesktopFrameworks_Data;\r\n            details.Identifier = s_Source_DesktopFrameworks_Identifier;\r\n            details.TrustLevel = SourceTrustLevel::Trusted | SourceTrustLevel::StoreOrigin;\r\n            details.IsVisible = false;\r\n            return details;\r\n        }\r\n        case WellKnownSource::WinGetFont:\r\n        {\r\n            SourceDetailsInternal details;\r\n            details.Origin = SourceOrigin::Default;\r\n            details.Name = s_Source_WingetCommunityFont_Name;\r\n            details.Type = Microsoft::PreIndexedPackageSourceFactory::Type();\r\n            details.Arg = s_Source_WingetCommunityFont_Arg;\r\n            details.Data = s_Source_WingetCommunityFont_Data;\r\n            details.Identifier = s_Source_WingetCommunityFont_Identifier;\r\n            details.TrustLevel = SourceTrustLevel::Trusted | SourceTrustLevel::StoreOrigin;\r\n            details.Explicit = true;\r\n            return details;\r\n        }\r\n        }\r\n\r\n        THROW_HR(E_UNEXPECTED);\r\n    }\r\n\r\n    SourceList::SourceList() : m_userSourcesStream(Stream::UserSources), m_metadataStream(Stream::SourcesMetadata)\r\n    {\r\n        OverwriteSourceList();\r\n        OverwriteMetadata();\r\n    }\r\n\r\n    std::vector<std::reference_wrapper<SourceDetailsInternal>> SourceList::GetCurrentSourceRefs()\r\n    {\r\n        std::vector<std::reference_wrapper<SourceDetailsInternal>> result;\r\n\r\n        for (auto& s : m_sourceList)\r\n        {\r\n            if (!ShouldBeHidden(s))\r\n            {\r\n                result.emplace_back(std::ref(s));\r\n            }\r\n            else\r\n            {\r\n                AICLI_LOG(Repo, Verbose, << \"GetCurrentSourceRefs: Source named '\" << s.Name << \"' from origin \" << ToString(s.Origin) << \" is hidden and is dropped.\");\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    auto SourceList::FindSource(std::string_view name, bool includeHidden)\r\n    {\r\n        return std::find_if(m_sourceList.begin(), m_sourceList.end(),\r\n            [name, includeHidden](const SourceDetailsInternal& sd)\r\n            {\r\n                return Utility::ICUCaseInsensitiveEquals(sd.Name, name) &&\r\n                    (includeHidden || !ShouldBeHidden(sd));\r\n            });\r\n    }\r\n\r\n    bool SourceList::TryFindSourceByOrigin(std::string_view name, SourceOrigin origin, SourceDetailsInternal& targetSourceOut, bool includeHidden)\r\n    {\r\n        auto defaultSources = GetSourcesByOrigin(origin);\r\n        auto iter = std::find_if(defaultSources.begin(), defaultSources.end(),\r\n            [name, includeHidden](const SourceDetailsInternal& sd)\r\n            {\r\n                return Utility::ICUCaseInsensitiveEquals(sd.Name, name) &&\r\n                    (includeHidden || !ShouldBeHidden(sd));\r\n            });\r\n\r\n        if (iter == defaultSources.end())\r\n        {\r\n            return false;\r\n        }\r\n\r\n        targetSourceOut = (*iter);\r\n        return true;\r\n    }\r\n\r\n    SourceDetailsInternal* SourceList::GetCurrentSource(std::string_view name)\r\n    {\r\n        auto itr = FindSource(name);\r\n        return itr == m_sourceList.end() ? nullptr : &(*itr);\r\n    }\r\n\r\n    SourceDetailsInternal* SourceList::GetSource(std::string_view name)\r\n    {\r\n        auto itr = FindSource(name, true);\r\n        return itr == m_sourceList.end() ? nullptr : &(*itr);\r\n    }\r\n\r\n    void SourceList::AddSource(const SourceDetailsInternal& details)\r\n    {\r\n        bool sourcesSet = false;\r\n\r\n        for (size_t i = 0; !sourcesSet && i < 10; ++i)\r\n        {\r\n            auto itr = FindSource(details.Name, true);\r\n            THROW_HR_IF(APPINSTALLER_CLI_ERROR_SOURCE_NAME_ALREADY_EXISTS,\r\n                itr != m_sourceList.end() && itr->Origin != SourceOrigin::Metadata && !itr->IsTombstone);\r\n\r\n            // Erase the source's entry if applicable\r\n            if (itr != m_sourceList.end())\r\n            {\r\n                m_sourceList.erase(itr);\r\n            }\r\n\r\n            m_sourceList.emplace_back(details);\r\n\r\n            sourcesSet = SetSourcesByOrigin(SourceOrigin::User, m_sourceList);\r\n\r\n            if (!sourcesSet)\r\n            {\r\n                OverwriteSourceList();\r\n                OverwriteMetadata();\r\n            }\r\n        }\r\n\r\n        THROW_HR_IF_MSG(E_UNEXPECTED, !sourcesSet, \"Too many attempts at SetSourcesByOrigin\");\r\n\r\n        SaveMetadataInternal(details);\r\n    }\r\n\r\n    void SourceList::RemoveSource(const SourceDetailsInternal& detailsRef)\r\n    {\r\n        // Copy the incoming details because we might destroy the referenced structure\r\n        // when reloading the source details from settings.\r\n        SourceDetailsInternal details = detailsRef;\r\n        bool sourcesSet = false;\r\n\r\n        for (size_t i = 0; !sourcesSet && i < 10; ++i)\r\n        {\r\n            switch (details.Origin)\r\n            {\r\n            case SourceOrigin::Default:\r\n            {\r\n                auto target = FindSource(details.Name, true);\r\n                if (target == m_sourceList.end())\r\n                {\r\n                    THROW_HR_MSG(E_UNEXPECTED, \"Default source not in SourceList\");\r\n                }\r\n\r\n                if (!target->IsTombstone)\r\n                {\r\n                    SourceDetailsInternal tombstone;\r\n                    tombstone.Name = details.Name;\r\n                    tombstone.IsTombstone = true;\r\n                    tombstone.Origin = SourceOrigin::User;\r\n                    m_sourceList.emplace_back(std::move(tombstone));\r\n                }\r\n            }\r\n                break;\r\n            case SourceOrigin::User:\r\n            {\r\n                auto target = FindSource(details.Name);\r\n                if (target == m_sourceList.end())\r\n                {\r\n                    // Assumed that an update to the sources removed it first\r\n                    return;\r\n                }\r\n\r\n                // If this is an override of a default source, turn this into a tombstone instead of removing it.\r\n                if (target->IsOverride)\r\n                {\r\n                    target->IsOverride = false;\r\n                    target->IsTombstone = true;\r\n                    break;\r\n                }\r\n\r\n                m_sourceList.erase(target);\r\n            }\r\n                break;\r\n            case SourceOrigin::GroupPolicy:\r\n                // This should have already been blocked higher up.\r\n                AICLI_LOG(Repo, Error, << \"Attempting to remove Group Policy source: \" << details.Name);\r\n                THROW_HR(E_UNEXPECTED);\r\n            default:\r\n                THROW_HR(E_UNEXPECTED);\r\n            }\r\n\r\n            sourcesSet = SetSourcesByOrigin(SourceOrigin::User, m_sourceList);\r\n\r\n            if (!sourcesSet)\r\n            {\r\n                OverwriteSourceList();\r\n                OverwriteMetadata();\r\n            }\r\n        }\r\n\r\n        THROW_HR_IF_MSG(E_UNEXPECTED, !sourcesSet, \"Too many attempts at SetSourcesByOrigin\");\r\n\r\n        SaveMetadataInternal(details, true);\r\n    }\r\n\r\n    void SourceList::EditSource(const SourceDetailsInternal& detailsRef)\r\n    {\r\n        // Copy the incoming details because we might destroy the referenced structure\r\n        // when reloading the source details from settings.\r\n        SourceDetailsInternal details = detailsRef;\r\n        bool sourcesSet = false;\r\n\r\n        for (size_t i = 0; !sourcesSet && i < 10; ++i)\r\n        {\r\n            switch (details.Origin)\r\n            {\r\n            case SourceOrigin::Default:\r\n            {\r\n                auto target = FindSource(details.Name, true);\r\n                if (target == m_sourceList.end())\r\n                {\r\n                    THROW_HR_MSG(E_UNEXPECTED, \"Default source not in SourceList\");\r\n                }\r\n\r\n                if (!target->IsTombstone)\r\n                {\r\n                    // Copy the original and then apply the override fields.\r\n                    SourceDetailsInternal override = *target;\r\n                    override.Origin = SourceOrigin::User;\r\n                    override.IsOverride = true;\r\n                    override.CopyOverrideFieldsFrom(details);\r\n                    m_sourceList.emplace_back(std::move(override));\r\n                }\r\n            }\r\n            break;\r\n            case SourceOrigin::User:\r\n            {\r\n                auto target = FindSource(details.Name);\r\n                if (target == m_sourceList.end())\r\n                {\r\n                    // Assumed that an update to the sources removed it first\r\n                    return;\r\n                }\r\n\r\n                // Editing a User Source is just replacing the fields that can be edited.\r\n                target->CopyOverrideFieldsFrom(details);\r\n            }\r\n            break;\r\n            case SourceOrigin::GroupPolicy:\r\n                // This should have already been blocked higher up.\r\n                AICLI_LOG(Repo, Error, << \"Attempting to edit a Group Policy source: \" << details.Name);\r\n                THROW_HR(E_UNEXPECTED);\r\n            default:\r\n                THROW_HR(E_UNEXPECTED);\r\n            }\r\n\r\n            sourcesSet = SetSourcesByOrigin(SourceOrigin::User, m_sourceList);\r\n\r\n            if (!sourcesSet)\r\n            {\r\n                OverwriteSourceList();\r\n                OverwriteMetadata();\r\n            }\r\n        }\r\n\r\n        THROW_HR_IF_MSG(E_UNEXPECTED, !sourcesSet, \"Too many attempts at SetSourcesByOrigin\");\r\n\r\n        SaveMetadataInternal(details, true);\r\n    }\r\n\r\n    void SourceList::SaveMetadata(const SourceDetailsInternal& details)\r\n    {\r\n        SaveMetadataInternal(details);\r\n    }\r\n\r\n    bool SourceList::CheckSourceAgreements(std::string_view sourceName, std::string_view agreementsIdentifier, ImplicitAgreementFieldEnum agreementFields)\r\n    {\r\n        if (agreementFields == ImplicitAgreementFieldEnum::None && agreementsIdentifier.empty())\r\n        {\r\n            // No agreements to be accepted.\r\n            return true;\r\n        }\r\n\r\n        auto detailsInternal = GetCurrentSource(sourceName);\r\n        if (!detailsInternal)\r\n        {\r\n            // Source not found.\r\n            return false;\r\n        }\r\n\r\n        return static_cast<int>(agreementFields) == detailsInternal->AcceptedAgreementFields &&\r\n            agreementsIdentifier == detailsInternal->AcceptedAgreementsIdentifier;\r\n    }\r\n\r\n    void SourceList::SaveAcceptedSourceAgreements(std::string_view sourceName, std::string_view agreementsIdentifier, ImplicitAgreementFieldEnum agreementFields)\r\n    {\r\n        if (agreementFields == ImplicitAgreementFieldEnum::None && agreementsIdentifier.empty())\r\n        {\r\n            // No agreements to be accepted.\r\n            return;\r\n        }\r\n\r\n        auto detailsInternal = GetCurrentSource(sourceName);\r\n        if (!detailsInternal)\r\n        {\r\n            // No source to update.\r\n            return;\r\n        }\r\n\r\n        detailsInternal->AcceptedAgreementFields = static_cast<int>(agreementFields);\r\n        detailsInternal->AcceptedAgreementsIdentifier = agreementsIdentifier;\r\n\r\n        SaveMetadataInternal(*detailsInternal);\r\n    }\r\n\r\n    void SourceList::RemoveSettingsStreams()\r\n    {\r\n        Stream{ Stream::UserSources }.Remove();\r\n        Stream{ Stream::SourcesMetadata }.Remove();\r\n    }\r\n\r\n    void SourceList::OverwriteSourceList()\r\n    {\r\n        m_sourceList.clear();\r\n\r\n        for (SourceOrigin origin : { SourceOrigin::GroupPolicy, SourceOrigin::User, SourceOrigin::Default })\r\n        {\r\n            auto forOrigin = GetSourcesByOrigin(origin);\r\n\r\n            for (auto&& source : forOrigin)\r\n            {\r\n                auto foundSource = GetSource(source.Name);\r\n                if (!foundSource)\r\n                {\r\n                    // Name not already defined, add it\r\n                    m_sourceList.emplace_back(std::move(source));\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(Repo, Info, << \"Source named '\" << foundSource->Name << \"' is already defined at origin \" << ToString(foundSource->Origin) <<\r\n                        \". The source from origin \" << ToString(origin) << \" is dropped.\");\r\n                }\r\n            }\r\n        }\r\n\r\n        if (ExperimentalFeature::IsEnabled(ExperimentalFeature::Feature::SourcePriority))\r\n        {\r\n            std::stable_sort(m_sourceList.begin(), m_sourceList.end());\r\n        }\r\n    }\r\n\r\n    void SourceList::OverwriteMetadata()\r\n    {\r\n        auto metadata = GetMetadata();\r\n        for (auto& metaSource : metadata)\r\n        {\r\n            auto source = GetSource(metaSource.Name);\r\n            if (source)\r\n            {\r\n                metaSource.CopyMetadataFieldsTo(*source);\r\n            }\r\n            else\r\n            {\r\n                m_sourceList.emplace_back(std::move(metaSource));\r\n            }\r\n        }\r\n    }\r\n\r\n    // Gets the sources from a particular origin.\r\n    std::vector<SourceDetailsInternal> SourceList::GetSourcesByOrigin(SourceOrigin origin)\r\n    {\r\n        std::vector<SourceDetailsInternal> result;\r\n\r\n        switch (origin)\r\n        {\r\n        case SourceOrigin::Default:\r\n        {\r\n            if (IsWellKnownSourceEnabled(WellKnownSource::MicrosoftStore))\r\n            {\r\n                result.emplace_back(GetWellKnownSourceDetailsInternal(WellKnownSource::MicrosoftStore));\r\n            }\r\n\r\n            if (IsWellKnownSourceEnabled(WellKnownSource::WinGet))\r\n            {\r\n                result.emplace_back(GetWellKnownSourceDetailsInternal(WellKnownSource::WinGet));\r\n            }\r\n\r\n            if (IsWellKnownSourceEnabled(WellKnownSource::WinGetFont))\r\n            {\r\n                result.emplace_back(GetWellKnownSourceDetailsInternal(WellKnownSource::WinGetFont));\r\n            }\r\n\r\n            // Since the source is not visible outside, this is added just to have the source in the internal\r\n            // list for tracking updates.  Thus there is no need to check a policy.\r\n            result.emplace_back(GetWellKnownSourceDetailsInternal(WellKnownSource::DesktopFrameworks));\r\n        }\r\n        break;\r\n        case SourceOrigin::User:\r\n        {\r\n            std::vector<SourceDetailsInternal> userSources = GetSourcesFromSetting(\r\n                m_userSourcesStream,\r\n                s_SourcesYaml_Sources,\r\n                [&](SourceDetailsInternal& details, const std::string& settingValue, const YAML::Node& source)\r\n                {\r\n                    std::string_view name = m_userSourcesStream.GetName();\r\n                    if (!TryReadScalar(name, settingValue, source, s_SourcesYaml_Source_Name, details.Name)) { return false; }\r\n                    if (!TryReadScalar(name, settingValue, source, s_SourcesYaml_Source_Type, details.Type)) { return false; }\r\n                    if (!TryReadScalar(name, settingValue, source, s_SourcesYaml_Source_Arg, details.Arg)) { return false; }\r\n                    if (!TryReadScalar(name, settingValue, source, s_SourcesYaml_Source_Data, details.Data)) { return false; }\r\n                    if (!TryReadScalar(name, settingValue, source, s_SourcesYaml_Source_IsTombstone, details.IsTombstone)) { return false; }\r\n                    TryReadScalar(name, settingValue, source, s_SourcesYaml_Source_Explicit, details.Explicit, false);\r\n                    TryReadScalar(name, settingValue, source, s_SourcesYaml_Source_Identifier, details.Identifier, false);\r\n                    TryReadScalar(name, settingValue, source, s_SourcesYaml_Source_IsOverride, details.IsOverride, false);\r\n                    TryReadScalar(name, settingValue, source, s_SourcesYaml_Source_Priority, details.Priority, false);\r\n\r\n                    int64_t trustLevelValue;\r\n                    if (TryReadScalar(name, settingValue, source, s_SourcesYaml_Source_TrustLevel, trustLevelValue, false))\r\n                    {\r\n                        details.TrustLevel = static_cast<Repository::SourceTrustLevel>(trustLevelValue);\r\n                    }\r\n\r\n                    return true;\r\n                });\r\n\r\n            for (auto& source : userSources)\r\n            {\r\n                // Check source against list of allowed sources and drop tombstones for required sources\r\n                if (!IsUserSourceAllowedByPolicy(source.Name, source.Type, source.Arg, source.IsTombstone))\r\n                {\r\n                    AICLI_LOG(Repo, Warning, << \"User source \" << source.Name << \" dropped because of group policy\");\r\n                    continue;\r\n                }\r\n\r\n                // If this is an override source, we need to get the target of the override and apply the override data on top of it.\r\n                if (source.IsOverride)\r\n                {\r\n                    SourceDetailsInternal override;\r\n                    if (!TryFindSourceByOrigin(source.Name, SourceOrigin::Default, override))\r\n                    {\r\n                        // The default source may be disabled, in which case it may not be returned in the list of default sources.\r\n                        AICLI_LOG(Repo, Warning, << \"User source \" << source.Name << \" is an override for a nonexistent Default Source.\");\r\n                        continue;\r\n                    }\r\n\r\n                    override.CopyOverrideFieldsFrom(source);\r\n                    override.Origin = SourceOrigin::User;\r\n                    override.IsOverride = true;\r\n                    result.emplace_back(std::move(override));\r\n                    AICLI_LOG(Repo, Info, << \"User source \" << source.Name << \" is overriding the Default source of the same name.\");\r\n                    continue;\r\n                }\r\n\r\n                result.emplace_back(std::move(source));\r\n            }\r\n        }\r\n        break;\r\n        case SourceOrigin::GroupPolicy:\r\n        {\r\n            if (GroupPolicies().GetState(TogglePolicy::Policy::AdditionalSources) == PolicyState::Enabled)\r\n            {\r\n                AICLI_LOG(Repo, Verbose, << \"Additional sources GP is enabled...\");\r\n                auto additionalSourcesOpt = GroupPolicies().GetValueRef<ValuePolicy::AdditionalSources>();\r\n                if (additionalSourcesOpt.has_value())\r\n                {\r\n                    const auto& additionalSources = additionalSourcesOpt->get();\r\n                    for (const auto& additionalSource : additionalSources)\r\n                    {\r\n                        AICLI_LOG(Repo, Verbose, << \"... with configured source \" << additionalSource.Name);\r\n                        SourceDetailsInternal details;\r\n                        details.Name = additionalSource.Name;\r\n                        details.Type = additionalSource.Type;\r\n                        details.Arg = additionalSource.Arg;\r\n                        details.Data = additionalSource.Data;\r\n                        details.Identifier = additionalSource.Identifier;\r\n                        details.Origin = SourceOrigin::GroupPolicy;\r\n                        details.Explicit = additionalSource.Explicit;\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n                        details.CertificatePinningConfiguration = additionalSource.PinningConfiguration;\r\n#endif\r\n                        try\r\n                        {\r\n                            details.TrustLevel = Repository::ConvertToSourceTrustLevelFlag(additionalSource.TrustLevel);\r\n                        }\r\n                        catch (...)\r\n                        {\r\n                            details.TrustLevel = Repository::SourceTrustLevel::None;\r\n                            AICLI_LOG(Repo, Verbose, << \"Invalid source trust level from policy. Trust level set to None.\");\r\n                        }\r\n\r\n                        result.emplace_back(std::move(details));\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(Repo, Verbose, << \"... but has no values.\");\r\n                }\r\n            }\r\n            else\r\n            {\r\n                AICLI_LOG(Repo, Verbose, << \"Additional sources GP is not enabled.\");\r\n            }\r\n        }\r\n        break;\r\n        default:\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n\r\n        for (auto& source : result)\r\n        {\r\n            source.Origin = origin;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    bool SourceList::SetSourcesByOrigin(SourceOrigin origin, const std::vector<SourceDetailsInternal>& sources)\r\n    {\r\n        switch (origin)\r\n        {\r\n        case SourceOrigin::User:\r\n            return SetSourcesToSettingWithFilter(m_userSourcesStream, SourceOrigin::User, sources);\r\n        }\r\n\r\n        THROW_HR(E_UNEXPECTED);\r\n    }\r\n\r\n    std::vector<SourceDetailsInternal> SourceList::GetMetadata()\r\n    {\r\n        return GetSourcesFromSetting(\r\n            m_metadataStream,\r\n            s_MetadataYaml_Sources,\r\n            [&](SourceDetailsInternal& details, const std::string& settingValue, const YAML::Node& source)\r\n            {\r\n                details.Origin = SourceOrigin::Metadata;\r\n                std::string_view name = m_metadataStream.GetName();\r\n                if (!TryReadScalar(name, settingValue, source, s_MetadataYaml_Source_Name, details.Name)) { return false; }\r\n\r\n                int64_t lastUpdateInEpoch{};\r\n                if (!TryReadScalar(name, settingValue, source, s_MetadataYaml_Source_LastUpdate, lastUpdateInEpoch)) { return false; }\r\n                details.LastUpdateTime = Utility::ConvertUnixEpochToSystemClock(lastUpdateInEpoch);\r\n\r\n                int64_t doNotUpdateBeforeInEpoch{};\r\n                if (TryReadScalar(name, settingValue, source, s_MetadataYaml_Source_DoNotUpdateBefore, doNotUpdateBeforeInEpoch, false))\r\n                {\r\n                    details.DoNotUpdateBefore = Utility::ConvertUnixEpochToSystemClock(doNotUpdateBeforeInEpoch);\r\n                }\r\n\r\n                TryReadScalar(name, settingValue, source, s_MetadataYaml_Source_AcceptedAgreementsIdentifier, details.AcceptedAgreementsIdentifier, false);\r\n                TryReadScalar(name, settingValue, source, s_MetadataYaml_Source_AcceptedAgreementFields, details.AcceptedAgreementFields, false);\r\n                return true;\r\n            });\r\n    }\r\n\r\n    bool SourceList::SetMetadata(const std::vector<SourceDetailsInternal>& sources)\r\n    {\r\n        YAML::Emitter out;\r\n        out << YAML::BeginMap;\r\n        out << YAML::Key << s_MetadataYaml_Sources;\r\n        out << YAML::BeginSeq;\r\n\r\n        for (const auto& details : sources)\r\n        {\r\n            out << YAML::BeginMap;\r\n            out << YAML::Key << s_MetadataYaml_Source_Name << YAML::Value << details.Name;\r\n            out << YAML::Key << s_MetadataYaml_Source_LastUpdate << YAML::Value << Utility::ConvertSystemClockToUnixEpoch(details.LastUpdateTime);\r\n            out << YAML::Key << s_MetadataYaml_Source_DoNotUpdateBefore << YAML::Value << Utility::ConvertSystemClockToUnixEpoch(details.DoNotUpdateBefore);\r\n            out << YAML::Key << s_MetadataYaml_Source_AcceptedAgreementsIdentifier << YAML::Value << details.AcceptedAgreementsIdentifier;\r\n            out << YAML::Key << s_MetadataYaml_Source_AcceptedAgreementFields << YAML::Value << details.AcceptedAgreementFields;\r\n            out << YAML::EndMap;\r\n        }\r\n\r\n        out << YAML::EndSeq;\r\n        out << YAML::EndMap;\r\n\r\n        return m_metadataStream.Set(out.str());\r\n    }\r\n\r\n    void SourceList::SaveMetadataInternal(const SourceDetailsInternal& detailsRef, bool remove)\r\n    {\r\n        // Copy the incoming details because we might overwrite the metadata\r\n        // when reloading the source details from settings.\r\n        SourceDetailsInternal details = detailsRef;\r\n        bool metadataSet = false;\r\n\r\n        for (size_t i = 0; !metadataSet && i < 10; ++i)\r\n        {\r\n            metadataSet = SetMetadata(m_sourceList);\r\n\r\n            if (!metadataSet)\r\n            {\r\n                OverwriteMetadata();\r\n\r\n                auto target = FindSource(details.Name, true);\r\n                if (target == m_sourceList.end())\r\n                {\r\n                    // Didn't find the metadata, so we consider this a success\r\n                    return;\r\n                }\r\n\r\n                if (remove)\r\n                {\r\n                    // The remove will have removed the source but not the metadata.\r\n                    // Remove it again here.\r\n                    m_sourceList.erase(target);\r\n                }\r\n                else\r\n                {\r\n                    // Update the freshly read metadata with the update that was requested.\r\n                    details.CopyMetadataFieldsTo(*target);\r\n                }\r\n            }\r\n        }\r\n\r\n        THROW_HR_IF_MSG(E_UNEXPECTED, !metadataSet, \"Too many attempts at SetMetadata\");\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/SourceList.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ISource.h\"\r\n#include <winget/Settings.h>\r\n\r\n\r\nnamespace AppInstaller::Repository\r\n{\r\n    // Built-in values for default sources\r\n    std::string_view GetWellKnownSourceName(WellKnownSource source);\r\n    std::string_view GetWellKnownSourceArg(WellKnownSource source);\r\n    std::string_view GetWellKnownSourceIdentifier(WellKnownSource source);\r\n    std::optional<WellKnownSource> CheckForWellKnownSourceMatch(std::string_view name, std::string_view arg, std::string_view type);\r\n\r\n    // SourceDetails with additional data used internally.\r\n    struct SourceDetailsInternal : public SourceDetails\r\n    {\r\n        SourceDetailsInternal() = default;\r\n        SourceDetailsInternal(const SourceDetails& details) : SourceDetails(details) {}\r\n\r\n        // Copies the metadata fields to this target.\r\n        void CopyMetadataFieldsTo(SourceDetailsInternal& target);\r\n\r\n        // Copies the metadata fields from this source. This only include partial metadata.\r\n        void CopyMetadataFieldsFrom(const SourceDetails& source);\r\n\r\n        // Copies the overridden fields from the target source to this source. This is only the supported override fields.\r\n        void CopyOverrideFieldsFrom(const SourceDetails& overrideSource);\r\n\r\n        // Sorts by Priority with higher values coming first in the order.\r\n        bool operator<(const SourceDetailsInternal& other) const;\r\n\r\n        // If true, this is a tombstone, marking the deletion of a source at a lower priority origin.\r\n        bool IsTombstone = false;\r\n\r\n        // If true, this is an override of a source at a lower priority. An override source only defines\r\n        // changes on top of the lower priority source, otherwise uses the same as the lower priority source.\r\n        bool IsOverride = false;\r\n\r\n        // If false, this is not visible in GetCurrentSource or GetAllSources, it's only available when explicitly requested.\r\n        bool IsVisible = true;\r\n\r\n        // Accepted agreements info.\r\n        std::string AcceptedAgreementsIdentifier;\r\n        int AcceptedAgreementFields = 0;\r\n    };\r\n\r\n    // Gets the internal details for a well known source.\r\n    SourceDetailsInternal GetWellKnownSourceDetailsInternal(WellKnownSource source);\r\n\r\n    // Struct containing internal implementation of the source list.\r\n    // This contains all source data; including tombstoned sources.\r\n    struct SourceList\r\n    {\r\n        SourceList();\r\n\r\n        // Get a list of current sources references which can be used to update the contents in place.\r\n        // e.g. update the LastTimeUpdated value of sources.\r\n        std::vector<std::reference_wrapper<SourceDetailsInternal>> GetCurrentSourceRefs();\r\n\r\n        // Current source means source that's not in tombstone\r\n        SourceDetailsInternal* GetCurrentSource(std::string_view name);\r\n\r\n        // Source includes ones in tombstone\r\n        SourceDetailsInternal* GetSource(std::string_view name);\r\n\r\n        // Add/remove/edit a current source\r\n        void AddSource(const SourceDetailsInternal& details);\r\n        void RemoveSource(const SourceDetailsInternal& details);\r\n        void EditSource(const SourceDetailsInternal& details);\r\n\r\n        // Save source metadata; the particular source with the metadata update is given.\r\n        // The given source must already be in the internal source list.\r\n        void SaveMetadata(const SourceDetailsInternal& details);\r\n\r\n        // Checks the source agreements and returns if agreements are satisfied.\r\n        bool CheckSourceAgreements(std::string_view sourceName, std::string_view agreementsIdentifier, ImplicitAgreementFieldEnum agreementFields);\r\n\r\n        // Save agreements information.\r\n        void SaveAcceptedSourceAgreements(std::string_view sourceName, std::string_view agreementsIdentifier, ImplicitAgreementFieldEnum agreementFields);\r\n\r\n        // Removes all settings streams associated with the source list.\r\n        // Implements `winget source reset --force`.\r\n        static void RemoveSettingsStreams();\r\n\r\n    private:\r\n        // Overwrites the source list with all sources.\r\n        void OverwriteSourceList();\r\n\r\n        // Overwrites the source list with the current metadata.\r\n        void OverwriteMetadata();\r\n\r\n        // calls std::find_if and return the iterator.\r\n        auto FindSource(std::string_view name, bool includeHidden = false);\r\n\r\n        // Tries to find a named source from the specified origin.\r\n        [[nodiscard]] bool TryFindSourceByOrigin(std::string_view name, SourceOrigin origin, SourceDetailsInternal& targetSourceOut, bool includeHidden = false);\r\n\r\n        std::vector<SourceDetailsInternal> GetSourcesByOrigin(SourceOrigin origin);\r\n        // Does *NOT* set metadata; call SaveMetadataInternal afterward.\r\n        [[nodiscard]] bool SetSourcesByOrigin(SourceOrigin origin, const std::vector<SourceDetailsInternal>& sources);\r\n\r\n        std::vector<SourceDetailsInternal> GetMetadata();\r\n        [[nodiscard]] bool SetMetadata(const std::vector<SourceDetailsInternal>& sources);\r\n\r\n        // Save source metadata; the particular source with the metadata update is given.\r\n        // If remove is true, the given source is being removed.\r\n        void SaveMetadataInternal(const SourceDetailsInternal& details, bool remove = false);\r\n\r\n        std::vector<SourceDetailsInternal> m_sourceList;\r\n        Settings::Stream m_userSourcesStream;\r\n        Settings::Stream m_metadataStream;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/SourcePolicy.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"SourcePolicy.h\"\r\n#include \"Microsoft/PreIndexedPackageSourceFactory.h\"\r\n#include \"Rest/RestSourceFactory.h\"\r\n\r\nusing namespace AppInstaller::Settings;\r\n\r\n\r\nnamespace AppInstaller::Repository\r\n{\r\n    namespace\r\n    {\r\n        // Checks whether a default source is enabled with the current settings.\r\n        // onlyExplicit determines whether we consider the not-configured state to be enabled or not.\r\n        bool IsDefaultSourceEnabled(WellKnownSource sourceToLog, ExperimentalFeature::Feature feature, bool onlyExplicit, TogglePolicy::Policy policy)\r\n        {\r\n            if (!ExperimentalFeature::IsEnabled(feature))\r\n            {\r\n                // No need to log here\r\n                return false;\r\n            }\r\n\r\n            if (onlyExplicit)\r\n            {\r\n                // No need to log here\r\n                return GroupPolicies().GetState(policy) == PolicyState::Enabled;\r\n            }\r\n\r\n            if (!GroupPolicies().IsEnabled(policy))\r\n            {\r\n                AICLI_LOG(Repo, Info, << \"The default source \" << GetWellKnownSourceName(sourceToLog) << \" is disabled due to Group Policy\");\r\n                return false;\r\n            }\r\n\r\n            return true;\r\n        }\r\n\r\n        template<ValuePolicy P>\r\n        std::optional<SourceFromPolicy> FindSourceInPolicy(std::string_view name, std::string_view type, std::string_view arg)\r\n        {\r\n            auto sourcesOpt = GroupPolicies().GetValueRef<P>();\r\n            if (!sourcesOpt.has_value())\r\n            {\r\n                return std::nullopt;\r\n            }\r\n\r\n            const auto& sources = sourcesOpt->get();\r\n            auto source = std::find_if(\r\n                sources.begin(),\r\n                sources.end(),\r\n                [&](const SourceFromPolicy& policySource)\r\n                {\r\n                    return Utility::ICUCaseInsensitiveEquals(name, policySource.Name) && Utility::ICUCaseInsensitiveEquals(type, policySource.Type) && arg == policySource.Arg;\r\n                });\r\n\r\n            if (source == sources.end())\r\n            {\r\n                return std::nullopt;\r\n            }\r\n\r\n            return *source;\r\n        }\r\n\r\n        template<ValuePolicy P>\r\n        bool IsSourceInPolicy(std::string_view name, std::string_view type, std::string_view arg)\r\n        {\r\n            return FindSourceInPolicy<P>(name, type, arg).has_value();\r\n        }\r\n    }\r\n\r\n    // Checks whether the Group Policy allows this user source.\r\n    // If it does it returns None, otherwise it returns which policy is blocking it.\r\n    // Note that this applies to user sources that are being added as well as user sources\r\n    // that already existed when the Group Policy came into effect.\r\n    TogglePolicy::Policy GetPolicyBlockingUserSource(std::string_view name, std::string_view type, std::string_view arg, bool isTombstone)\r\n    {\r\n        // Reasons for not allowing:\r\n        //  1. The source is a tombstone for default source that is explicitly enabled\r\n        //  2. The source is a default source that is disabled\r\n        //  3. The source has the same name as a default source that is explicitly enabled (to prevent shadowing)\r\n        //  4. Allowed sources are disabled, blocking all user sources\r\n        //  5. There is an explicit list of allowed sources and this source is not in it\r\n        //\r\n        // We don't need to check sources added by policy as those have higher priority.\r\n        //\r\n        // Use the name and arg to match sources as we don't have the identifier before adding.\r\n\r\n        // Case 1:\r\n        // The source is a tombstone and we need the policy to be explicitly enabled.\r\n        if (isTombstone)\r\n        {\r\n            if (name == GetWellKnownSourceName(WellKnownSource::WinGet) && IsWellKnownSourceEnabled(WellKnownSource::WinGet, true))\r\n            {\r\n                return TogglePolicy::Policy::DefaultSource;\r\n            }\r\n\r\n            if (name == GetWellKnownSourceName(WellKnownSource::MicrosoftStore) && IsWellKnownSourceEnabled(WellKnownSource::MicrosoftStore, true))\r\n            {\r\n                return TogglePolicy::Policy::MSStoreSource;\r\n            }\r\n\r\n            if (name == GetWellKnownSourceName(WellKnownSource::WinGetFont) && IsWellKnownSourceEnabled(WellKnownSource::WinGetFont, true))\r\n            {\r\n                return TogglePolicy::Policy::FontSource;\r\n            }\r\n\r\n            // Any other tombstone is allowed\r\n            return TogglePolicy::Policy::None;\r\n        }\r\n\r\n        // Case 2:\r\n        //  - The source is not a tombstone and we don't need the policy to be explicitly enabled.\r\n        //  - Check only against the source argument and type as the user source may have a different name.\r\n        //  - Do a case-insensitive check as the domain portion of the URL is case-insensitive,\r\n        //    and we don't need case sensitivity for the rest as we control the domain.\r\n        if (Utility::CaseInsensitiveEquals(arg, GetWellKnownSourceArg(WellKnownSource::WinGet)) &&\r\n            Utility::CaseInsensitiveEquals(type, Microsoft::PreIndexedPackageSourceFactory::Type()))\r\n        {\r\n            return IsWellKnownSourceEnabled(WellKnownSource::WinGet) ? TogglePolicy::Policy::None : TogglePolicy::Policy::DefaultSource;\r\n        }\r\n\r\n        if (Utility::CaseInsensitiveEquals(arg, GetWellKnownSourceArg(WellKnownSource::MicrosoftStore)) &&\r\n            Utility::CaseInsensitiveEquals(type, Rest::RestSourceFactory::Type()))\r\n        {\r\n            return IsWellKnownSourceEnabled(WellKnownSource::MicrosoftStore) ? TogglePolicy::Policy::None : TogglePolicy::Policy::MSStoreSource;\r\n        }\r\n\r\n        if (Utility::CaseInsensitiveEquals(arg, GetWellKnownSourceArg(WellKnownSource::WinGetFont)) &&\r\n            Utility::CaseInsensitiveEquals(type, Microsoft::PreIndexedPackageSourceFactory::Type()))\r\n        {\r\n            return IsWellKnownSourceEnabled(WellKnownSource::WinGetFont) ? TogglePolicy::Policy::None : TogglePolicy::Policy::FontSource;\r\n        }\r\n\r\n        // Case 3:\r\n        // If the source has the same name as a default source, it is shadowing with a different argument\r\n        // (as it didn't match above). We only care if Group Policy requires the default source.\r\n        if (name == GetWellKnownSourceName(WellKnownSource::WinGet) && IsWellKnownSourceEnabled(WellKnownSource::WinGet, true))\r\n        {\r\n            AICLI_LOG(Repo, Warning, << \"User source is not allowed as it shadows the default source. Name [\" << name << \"]. Arg [\" << arg << \"] Type [\" << type << ']');\r\n            return TogglePolicy::Policy::DefaultSource;\r\n        }\r\n\r\n        if (name == GetWellKnownSourceName(WellKnownSource::MicrosoftStore) && IsWellKnownSourceEnabled(WellKnownSource::MicrosoftStore, true))\r\n        {\r\n            AICLI_LOG(Repo, Warning, << \"User source is not allowed as it shadows a default MS Store source. Name [\" << name << \"]. Arg [\" << arg << \"] Type [\" << type << ']');\r\n            return TogglePolicy::Policy::MSStoreSource;\r\n        }\r\n\r\n        if (name == GetWellKnownSourceName(WellKnownSource::WinGetFont) && IsWellKnownSourceEnabled(WellKnownSource::WinGetFont, true))\r\n        {\r\n            AICLI_LOG(Repo, Warning, << \"User source is not allowed as it shadows a default font source. Name [\" << name << \"]. Arg [\" << arg << \"] Type [\" << type << ']');\r\n            return TogglePolicy::Policy::FontSource;\r\n        }\r\n\r\n        // Case 4:\r\n        // The guard in the source add command should already block adding.\r\n        // This check drops existing user sources.\r\n        auto allowedSourcesPolicy = GroupPolicies().GetState(TogglePolicy::Policy::AllowedSources);\r\n        if (allowedSourcesPolicy == PolicyState::Disabled)\r\n        {\r\n            AICLI_LOG(Repo, Warning, << \"User sources are disabled by Group Policy\");\r\n            return TogglePolicy::Policy::AllowedSources;\r\n        }\r\n\r\n        // Case 5:\r\n        if (allowedSourcesPolicy == PolicyState::Enabled)\r\n        {\r\n            if (!IsSourceInPolicy<ValuePolicy::AllowedSources>(name, type, arg))\r\n            {\r\n                AICLI_LOG(Repo, Warning, << \"Source is not in the Group Policy allowed list. Name [\" << name << \"]. Arg [\" << arg << \"] Type [\" << type << ']');\r\n                return TogglePolicy::Policy::AllowedSources;\r\n            }\r\n        }\r\n\r\n        return TogglePolicy::Policy::None;\r\n    }\r\n\r\n    bool IsUserSourceAllowedByPolicy(std::string_view name, std::string_view type, std::string_view arg, bool isTombstone)\r\n    {\r\n        return GetPolicyBlockingUserSource(name, type, arg, isTombstone) == TogglePolicy::Policy::None;\r\n    }\r\n\r\n    bool IsWellKnownSourceEnabled(WellKnownSource source, bool onlyExplicit)\r\n    {\r\n        switch (source)\r\n        {\r\n        case AppInstaller::Repository::WellKnownSource::WinGet:\r\n            return IsDefaultSourceEnabled(source, ExperimentalFeature::Feature::None, onlyExplicit, TogglePolicy::Policy::DefaultSource);\r\n        case AppInstaller::Repository::WellKnownSource::MicrosoftStore:\r\n            return IsDefaultSourceEnabled(source, ExperimentalFeature::Feature::None, onlyExplicit, TogglePolicy::Policy::MSStoreSource);\r\n        case AppInstaller::Repository::WellKnownSource::WinGetFont:\r\n            return IsDefaultSourceEnabled(source, ExperimentalFeature::Feature::None, onlyExplicit, TogglePolicy::Policy::FontSource);\r\n        case AppInstaller::Repository::WellKnownSource::DesktopFrameworks:\r\n            // No corresponding policy available for this source.\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    void EnsureSourceIsRemovable(const SourceDetailsInternal& source)\r\n    {\r\n        // Block removing sources added by Group Policy\r\n        if (source.Origin == SourceOrigin::GroupPolicy)\r\n        {\r\n            AICLI_LOG(Repo, Error, << \"Cannot remove source added by Group Policy\");\r\n            throw GroupPolicyException(TogglePolicy::Policy::AdditionalSources);\r\n        }\r\n\r\n        // Block removing default sources required by Group Policy.\r\n        if (source.Origin == SourceOrigin::Default)\r\n        {\r\n            if (GroupPolicies().GetState(TogglePolicy::Policy::DefaultSource) == PolicyState::Enabled &&\r\n                source.Identifier == GetWellKnownSourceIdentifier(WellKnownSource::WinGet))\r\n            {\r\n                throw GroupPolicyException(TogglePolicy::Policy::DefaultSource);\r\n            }\r\n\r\n            if (GroupPolicies().GetState(TogglePolicy::Policy::MSStoreSource) == PolicyState::Enabled &&\r\n                source.Identifier == GetWellKnownSourceIdentifier(WellKnownSource::MicrosoftStore))\r\n            {\r\n                throw GroupPolicyException(TogglePolicy::Policy::MSStoreSource);\r\n            }\r\n\r\n            if (GroupPolicies().GetState(TogglePolicy::Policy::FontSource) == PolicyState::Enabled &&\r\n                source.Identifier == GetWellKnownSourceIdentifier(WellKnownSource::WinGetFont))\r\n            {\r\n                throw GroupPolicyException(TogglePolicy::Policy::FontSource);\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/SourcePolicy.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"SourceList.h\"\r\n#include <winget/GroupPolicy.h>\r\n\r\n#include <string_view>\r\n\r\n\r\nnamespace AppInstaller::Repository\r\n{\r\n    // Checks whether the Group Policy allows this user source.\r\n    // If it does it returns None, otherwise it returns which policy is blocking it.\r\n    // Note that this applies to user sources that are being added as well as user sources\r\n    // that already existed when the Group Policy came into effect.\r\n    Settings::TogglePolicy::Policy GetPolicyBlockingUserSource(std::string_view name, std::string_view type, std::string_view arg, bool isTombstone);\r\n\r\n    // Helper that converts the result of GetPolicyBlockingUserSource into a bool.\r\n    bool IsUserSourceAllowedByPolicy(std::string_view name, std::string_view type, std::string_view arg, bool isTombstone);\r\n\r\n    // Determines if a well known source is enabled; if onlyExplicit is true, it must be explicitly enabled by group policy.\r\n    bool IsWellKnownSourceEnabled(WellKnownSource source, bool onlyExplicit = false);\r\n\r\n    // Checks that the specified source is removable per policy; throwing if it is not.\r\n    void EnsureSourceIsRemovable(const SourceDetailsInternal& source);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/SourceUpdateChecks.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"SourceUpdateChecks.h\"\r\n#include \"ISource.h\"\r\n#include <winget/UserSettings.h>\r\n\r\nusing namespace std::chrono_literals;\r\n\r\nnamespace AppInstaller::Repository\r\n{\r\n    bool ShouldUpdateBeforeOpen(ISourceReference* sourceReference, const std::optional<TimeSpan>& requestedUpdateInterval)\r\n    {\r\n        const SourceDetails& details = sourceReference->GetDetails();\r\n\r\n        // Always respect this value to prevent server overloading\r\n        if (IsBeforeDoNotUpdateBeforeTime(details))\r\n        {\r\n            return false;\r\n        }\r\n\r\n        // Allow the source reference to decide beyond this\r\n        return sourceReference->ShouldUpdateBeforeOpen(requestedUpdateInterval);\r\n    }\r\n\r\n    bool IsBeforeDoNotUpdateBeforeTime(const SourceDetails& details)\r\n    {\r\n        if (std::chrono::system_clock::now() < details.DoNotUpdateBefore)\r\n        {\r\n            AICLI_LOG(Repo, Info, << \"Background update for `\" << details.Name << \"` is suppressed until: \" << details.DoNotUpdateBefore);\r\n            return true;\r\n        }\r\n        else\r\n        {\r\n            return false;\r\n        }\r\n    }\r\n\r\n    bool IsAfterUpdateCheckTime(const SourceDetails& details, std::optional<TimeSpan> requestedUpdateInterval)\r\n    {\r\n        return IsAfterUpdateCheckTime(details.Name, details.LastUpdateTime, requestedUpdateInterval);\r\n    }\r\n\r\n    bool IsAfterUpdateCheckTime(std::string_view name, std::chrono::system_clock::time_point lastUpdateTime, std::optional<TimeSpan> requestedUpdateInterval)\r\n    {\r\n        constexpr static TimeSpan s_ZeroMins = 0min;\r\n\r\n        TimeSpan autoUpdateTime;\r\n        if (requestedUpdateInterval)\r\n        {\r\n            autoUpdateTime = requestedUpdateInterval.value();\r\n        }\r\n        else\r\n        {\r\n            autoUpdateTime = Settings::User().Get<Settings::Setting::AutoUpdateTimeInMinutes>();\r\n        }\r\n\r\n        // A value of zero means no auto update, to get update the source run `winget update`\r\n        if (autoUpdateTime != s_ZeroMins)\r\n        {\r\n            auto timeSinceLastUpdate = std::chrono::system_clock::now() - lastUpdateTime;\r\n            if (timeSinceLastUpdate > autoUpdateTime)\r\n            {\r\n                AICLI_LOG(Repo, Info, << \"Source `\" << name << \"` after auto update time [\" <<\r\n                    (requestedUpdateInterval ? \"(override) \" : \"\") <<\r\n                    std::chrono::duration_cast<std::chrono::minutes>(autoUpdateTime).count() << \" mins]; it has been at least \" <<\r\n                    std::chrono::duration_cast<std::chrono::minutes>(timeSinceLastUpdate).count() << \" mins\");\r\n                return true;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/SourceUpdateChecks.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Public/winget/RepositorySource.h\"\r\n#include <chrono>\r\n\r\nnamespace AppInstaller::Repository\r\n{\r\n    // Determines if the given source should update before opening.\r\n    bool ShouldUpdateBeforeOpen(ISourceReference* sourceReference, const std::optional<TimeSpan>& requestedUpdateInterval);\r\n\r\n    // Determines if the current time is before a previously stored \"do note update before\" time.\r\n    bool IsBeforeDoNotUpdateBeforeTime(const SourceDetails& details);\r\n\r\n    // Determines if the given details and desired update interval indicate an update check should occur.\r\n    bool IsAfterUpdateCheckTime(const SourceDetails& details, std::optional<TimeSpan> requestedUpdateInterval);\r\n\r\n    // Determines if the given details and desired update interval indicate an update check should occur.\r\n    bool IsAfterUpdateCheckTime(std::string_view name, std::chrono::system_clock::time_point lastUpdateTime, std::optional<TimeSpan> requestedUpdateInterval);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<packages>\r\n  <package id=\"Microsoft.Windows.CppWinRT\" version=\"2.0.250303.1\" targetFramework=\"native\" />\r\n  <package id=\"Microsoft.Windows.ImplementationLibrary\" version=\"1.0.250325.1\" targetFramework=\"native\" />\r\n</packages>"
  },
  {
    "path": "src/AppInstallerRepositoryCore/pch.cpp",
    "content": "﻿// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n"
  },
  {
    "path": "src/AppInstallerRepositoryCore/pch.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n\n#define NOMINMAX\n#include <windows.h>\n#include <urlmon.h>\n#include <appmodel.h>\r\n#include <Shlwapi.h>\n#include <Shlobj.h>\n#include <msi.h>\n\n#pragma warning( push )\n#pragma warning ( disable : 6001 6340 6387 6388 26451 26495 28196 )\n#include <wil/filesystem.h>\n#include <wil/registry.h>\n#include <wil/resource.h>\n#include <wil/result.h>\n#include <wil/result_macros.h>\r\n#include <wil/registry_helpers.h>\n#pragma warning( pop )\n\n#include <winsqlite/winsqlite3.h>\n\n#include <winrt/Windows.ApplicationModel.h>\r\n#include <winrt/Windows.ApplicationModel.Core.h>\n#include <winrt/Windows.Foundation.h>\n#include <winrt/Windows.Foundation.Collections.h>\n#include <winrt/Windows.Management.Deployment.h>\n#include <winrt/Windows.Storage.h>\n#include <winrt/Windows.Web.Http.h>\n#include <wrl/client.h>\n\n#include <algorithm>\n#include <array>\n#include <chrono>\n#include <filesystem>\n#include <fstream>\n#include <functional>\n#include <initializer_list>\n#include <iomanip>\n#include <map>\n#include <memory>\n#include <optional>\n#include <random>\n#include <set>\r\n#include <shared_mutex>\n#include <string>\n#include <string_view>\n#include <sstream>\n#include <system_error>\n#include <thread>\n#include <tuple>\n#include <type_traits>\n#include <unordered_map>\n#include <unordered_set>\n#include <utility>\n\n#include <json/json.h>\r\n\r\n#pragma warning( push )\n#pragma warning ( disable : 26495 26439 )\n#include <cpprest/http_client.h>\n#include <cpprest/json.h>\n#include <cpprest/uri_builder.h>\n#pragma warning( pop )\r\n\r\n#include <AppInstallerDateTime.h>\n#include <AppInstallerDownloader.h>\n#include <AppInstallerErrors.h>\n#include <AppInstallerLogging.h>\n#include <AppInstallerRuntime.h>\n#include <AppInstallerSHA256.h>\n#include <AppInstallerStrings.h>\n#include <AppInstallerSynchronization.h>\n#include <AppInstallerTelemetry.h>\n#include <AppInstallerVersions.h>\n#include <winget/ExtensionCatalog.h>\n#include <winget/ExperimentalFeature.h>\n#include <winget/Locale.h>\n#include <winget/Settings.h>\n#include <winget/UserSettings.h>\n#include <winget/Yaml.h>\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/AppInstallerLogging.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"Public/AppInstallerLogging.h\"\n#include \"Public/AppInstallerStrings.h\"\n#include \"Public/AppInstallerDateTime.h\"\n#include \"Public/winget/SharedThreadGlobals.h\"\n\nnamespace AppInstaller::Logging\n{\n    std::string_view GetChannelName(Channel channel)\n    {\n        switch(channel)\n        {\n        case Channel::Fail:   return \"FAIL\";\n        case Channel::CLI:    return \"CLI\";\n        case Channel::SQL:    return \"SQL\";\n        case Channel::Repo:   return \"REPO\";\n        case Channel::YAML:   return \"YAML\";\n        case Channel::Core:   return \"CORE\";\n        case Channel::Test:   return \"TEST\";\n        case Channel::Config: return \"CONF\";\n        case Channel::Workflow: return \"WORK\";\n        default:              return \"NONE\";\n        }\n    }\n\n    Channel GetChannelFromName(std::string_view channel)\n    {\n        std::string lowerChannel = Utility::ToLower(channel);\n\n        if (lowerChannel == \"fail\")\n        {\n            return Channel::Fail;\n        }\n        else if (lowerChannel == \"cli\")\n        {\n            return Channel::CLI;\n        }\n        else if (lowerChannel == \"sql\")\n        {\n            return Channel::SQL;\n        }\n        else if (lowerChannel == \"repo\")\n        {\n            return Channel::Repo;\n        }\n        else if (lowerChannel == \"yaml\")\n        {\n            return Channel::YAML;\n        }\n        else if (lowerChannel == \"core\")\n        {\n            return Channel::Core;\n        }\n        else if (lowerChannel == \"test\")\n        {\n            return Channel::Test;\n        }\n        else if (lowerChannel == \"conf\" || lowerChannel == \"config\")\n        {\n            return Channel::Config;\n        }\n        else if (lowerChannel == \"workflow\")\n        {\n            return Channel::Workflow;\n        }\n        else if (lowerChannel == \"default\" || lowerChannel == \"defaults\")\n        {\n            return Channel::Defaults;\n        }\n        else if (lowerChannel == \"all\")\n        {\n            return Channel::All;\n        }\n\n        return Channel::None;\n    }\n\n    size_t GetMaxChannelNameLength() { return 4; }\n\n    void DiagnosticLogger::AddLogger(std::unique_ptr<ILogger>&& logger)\n    {\n        m_loggers.emplace_back(std::move(logger));\n    }\n\n    bool DiagnosticLogger::ContainsLogger(const std::string& name)\n    {\n        for (auto i = m_loggers.begin(); i != m_loggers.end(); ++i)\n        {\n            if ((*i)->GetName() == name)\n            {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    std::unique_ptr<ILogger> DiagnosticLogger::RemoveLogger(const std::string& name)\n    {\n        std::unique_ptr<ILogger> result;\n\n        for (auto i = m_loggers.begin(); i != m_loggers.end(); ++i)\n        {\n            if ((*i)->GetName() == name)\n            {\n                result = std::move(*i);\n                m_loggers.erase(i);\n                break;\n            }\n        }\n\n        return result;\n    }\n\n    void DiagnosticLogger::RemoveAllLoggers()\n    {\n        m_loggers.clear();\n    }\n\n    void DiagnosticLogger::EnableChannel(Channel channel)\n    {\n        WI_SetAllFlags(m_enabledChannels, channel);\n    }\n\n    void DiagnosticLogger::SetEnabledChannels(Channel channel)\n    {\n        m_enabledChannels = channel;\n    }\n\n    void DiagnosticLogger::DisableChannel(Channel channel)\n    {\n        WI_ClearAllFlags(m_enabledChannels, channel);\n    }\n\n    void DiagnosticLogger::SetLevel(Level level)\n    {\n        m_enabledLevel = level;\n    }\n\n    Level DiagnosticLogger::GetLevel() const\n    {\n        return m_enabledLevel;\n    }\n\n    bool DiagnosticLogger::IsEnabled(Channel channel, Level level) const\n    {\n        return (!m_loggers.empty() &&\n                WI_IsAnyFlagSet(m_enabledChannels, channel) &&\n                (ToIntegral(level) >= ToIntegral(m_enabledLevel)));\n    }\n\n    void DiagnosticLogger::Write(Channel channel, Level level, std::string_view message)\n    {\n        THROW_HR_IF_MSG(E_INVALIDARG, channel == Channel::All, \"Cannot write to all channels\");\n\n        if (IsEnabled(channel, level))\n        {\n            for (auto& logger : m_loggers)\n            {\n                logger->Write(channel, level, message);\n            }\n        }\n    }\n\n    void DiagnosticLogger::WriteDirect(Channel channel, Level level, std::string_view message)\n    {\n        THROW_HR_IF_MSG(E_INVALIDARG, channel == Channel::All, \"Cannot write to all channels\");\n\n        if (IsEnabled(channel, level))\n        {\n            for (auto& logger : m_loggers)\n            {\n                logger->WriteDirect(channel, level, message);\n            }\n        }\n    }\n\n    void DiagnosticLogger::SetTag(Tag tag)\n    {\n        for (auto& logger : m_loggers)\n        {\n            logger->SetTag(tag);\n        }\n    }\n\n    DiagnosticLogger& Log()\n    {\n        ThreadLocalStorage::ThreadGlobals* pThreadGlobals = ThreadLocalStorage::ThreadGlobals::GetForCurrentThread();\n        if (pThreadGlobals)\n        {\n            return pThreadGlobals->GetDiagnosticLogger();\n        }\n        else\n        {\n            static DiagnosticLogger processGlobalLogger;\n            return processGlobalLogger;\n        }\n    }\n\n    std::ostream& SetHRFormat(std::ostream& out)\n    {\n        return out << std::hex << std::setw(8) << std::setfill('0');\n    }\n}\n\nnamespace std\n{\n    std::ostream& operator<<(std::ostream& out, const std::chrono::system_clock::time_point& time)\n    {\n        AppInstaller::Utility::OutputTimePoint(out, time);\n        return out;\n    }\n\n    std::ostream& operator<<(std::ostream& out, const GUID& guid)\n    {\n        wchar_t buffer[256];\n\n        if (StringFromGUID2(guid, buffer, ARRAYSIZE(buffer)))\n        {\n            out << AppInstaller::Utility::ConvertToUTF8(buffer);\n        }\n        else\n        {\n            out << \"error\";\n        }\n\n        return out;\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerSharedLib/AppInstallerSharedLib.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" />\r\n  <PropertyGroup Label=\"Globals\">\r\n    <CppWinRTOptimized>true</CppWinRTOptimized>\r\n    <CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>\r\n    <MinimalCoreWin>true</MinimalCoreWin>\r\n    <VCProjectVersion>15.0</VCProjectVersion>\r\n    <ProjectGuid>{F3F6E699-BC5D-4950-8A05-E49DD9EB0D51}</ProjectGuid>\r\n    <Keyword>Win32Proj</Keyword>\r\n    <WindowsTargetPlatformVersion>10.0.26100.0</WindowsTargetPlatformVersion>\r\n    <WindowsTargetPlatformMinVersion>10.0.17763.0</WindowsTargetPlatformMinVersion>\r\n    <WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|ARM64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|Win32\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Fuzzing|x64\">\r\n      <Configuration>Fuzzing</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Fuzzing|Win32\">\r\n      <Configuration>Fuzzing</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|ARM64\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|Win32\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|x64\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|ARM64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|Win32\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <PropertyGroup Label=\"Configuration\">\r\n    <ConfigurationType>StaticLibrary</ConfigurationType>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Debug'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n    <LinkIncremental>true</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Release'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <LinkIncremental>false</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='ReleaseStatic'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <LinkIncremental>false</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Fuzzing'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>false</WholeProgramOptimization>\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <EnableASAN>true</EnableASAN>\r\n  </PropertyGroup>\r\n  <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\" Label=\"Configuration\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\" Label=\"Configuration\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\" Label=\"Configuration\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\r\n  <ImportGroup Label=\"ExtensionSettings\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"Shared\" />\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"PropertySheet.props\" />\r\n  </ImportGroup>\r\n  <PropertyGroup Label=\"UserMacros\" />\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>true</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>true</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>true</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Fuzzing|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Fuzzing|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(ProjectDir)\\..\\vcpkg.props\" />\r\n  <ItemDefinitionGroup>\r\n    <ClCompile>\r\n      <PrecompiledHeader>Use</PrecompiledHeader>\r\n      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>\r\n      <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>\r\n      <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <AdditionalOptions>%(AdditionalOptions) /permissive- /D _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING</AdditionalOptions>\r\n    </ClCompile>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Debug'\">\r\n    <ClCompile>\r\n      <Optimization>Disabled</Optimization>\r\n      <PreprocessorDefinitions>_NO_ASYNCRTIMP;_DEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">$(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\\binver;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">$(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\\binver;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</TreatWarningAsError>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</EnablePREfast>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">Windows</SubSystem>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Platform)'=='Win32'\">\r\n    <ClCompile>\r\n      <PreprocessorDefinitions>_NO_ASYNCRTIMP;WIN32;%(PreprocessorDefinitions);CLICOREDLLBUILD</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">$(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\\binver;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</TreatWarningAsError>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</EnablePREfast>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Windows</SubSystem>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Release'\">\r\n    <ClCompile>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>_NO_ASYNCRTIMP;NDEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">$(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\\binver;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">$(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\\binver;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">$(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\\binver;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">true</TreatWarningAsError>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</EnablePREfast>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Windows</SubSystem>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='ReleaseStatic'\">\r\n    <ClCompile>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>_NO_ASYNCRTIMP;NDEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">$(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\\binver;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">$(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\\binver;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">$(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\\binver;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">true</TreatWarningAsError>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">false</EnablePREfast>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">false</RuntimeTypeInfo>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">MultiThreaded</RuntimeLibrary>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">MultiThreaded</RuntimeLibrary>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">MultiThreaded</RuntimeLibrary>\r\n    </ClCompile>\r\n    <Link>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">Windows</SubSystem>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Fuzzing'\">\r\n    <ClCompile>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>_NO_ASYNCRTIMP;NDEBUG;%(PreprocessorDefinitions);CLICOREDLLBUILD;WINGET_DISABLE_FOR_FUZZING;_DISABLE_VECTOR_ANNOTATION;_DISABLE_STRING_ANNOTATION</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories>$(ProjectDir);$(ProjectDir)Public;$(ProjectDir)Telemetry;$(ProjectDir)..\\binver;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError>true</TreatWarningAsError>\r\n      <LanguageStandard>stdcpp17</LanguageStandard>\r\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r\n      <AdditionalOptions>%(AdditionalOptions) /fsanitize=address /fsanitize-coverage=inline-8bit-counters /fsanitize-coverage=edge /fsanitize-coverage=trace-cmp /fsanitize-coverage=trace-div</AdditionalOptions>\r\n      <RuntimeTypeInfo>false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <SubSystem>Windows</SubSystem>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"ICU\\SQLiteICU.h\" />\r\n    <ClInclude Include=\"pch.h\" />\r\n    <ClInclude Include=\"Public\\AppInstallerDateTime.h\" />\r\n    <ClInclude Include=\"Public\\AppInstallerErrors.h\" />\r\n    <ClInclude Include=\"Public\\AppInstallerLanguageUtilities.h\" />\r\n    <ClInclude Include=\"Public\\AppInstallerSHA256.h\" />\r\n    <ClInclude Include=\"Public\\AppInstallerStrings.h\" />\r\n    <ClInclude Include=\"Public\\AppInstallerLogging.h\" />\r\n    <ClInclude Include=\"Public\\AppInstallerVersions.h\" />\r\n    <ClInclude Include=\"Public\\Telemetry\\MicrosoftTelemetry.h\" />\r\n    <ClInclude Include=\"Public\\Telemetry\\WinEventLogLevels.h\" />\r\n    <ClInclude Include=\"Public\\winget\\AsyncTokens.h\" />\r\n    <ClInclude Include=\"Public\\winget\\Certificates.h\" />\r\n    <ClInclude Include=\"Public\\winget\\Compression.h\" />\r\n    <ClInclude Include=\"Public\\winget\\COMStaticStorage.h\" />\r\n    <ClInclude Include=\"Public\\winget\\ConfigurationSetProcessorHandlers.h\" />\r\n    <ClInclude Include=\"Public\\winget\\DetectMismatch.h\" />\r\n    <ClInclude Include=\"Public\\winget\\Filesystem.h\" />\r\n    <ClInclude Include=\"Public\\winget\\GroupPolicy.h\" />\r\n    <ClInclude Include=\"Public\\winget\\IConfigurationStaticsInternals.h\" />\r\n    <ClInclude Include=\"Public\\winget\\ILifetimeWatcher.h\" />\r\n    <ClInclude Include=\"Public\\winget\\JsonSchemaValidation.h\" />\r\n    <ClInclude Include=\"Public\\winget\\JsonUtil.h\" />\r\n    <ClInclude Include=\"Public\\winget\\LocIndependent.h\" />\r\n    <ClInclude Include=\"Public\\winget\\ManagedFile.h\" />\r\n    <ClInclude Include=\"Public\\winget\\ModuleCountBase.h\" />\r\n    <ClInclude Include=\"Public\\winget\\PathTree.h\" />\r\n    <ClInclude Include=\"Public\\winget\\Registry.h\" />\r\n    <ClInclude Include=\"Public\\winget\\Resources.h\" />\r\n    <ClInclude Include=\"Public\\winget\\Runtime.h\" />\r\n    <ClInclude Include=\"Public\\winget\\Security.h\" />\r\n    <ClInclude Include=\"Public\\winget\\SharedThreadGlobals.h\" />\r\n    <ClInclude Include=\"Public\\winget\\SQLiteDynamicStorage.h\" />\r\n    <ClInclude Include=\"Public\\winget\\SQLiteMetadataTable.h\" />\r\n    <ClInclude Include=\"Public\\winget\\SQLiteStatementBuilder.h\" />\r\n    <ClInclude Include=\"Public\\winget\\SQLiteStorageBase.h\" />\r\n    <ClInclude Include=\"Public\\winget\\SQLiteTempTable.h\" />\r\n    <ClInclude Include=\"Public\\winget\\SQLiteVersion.h\" />\r\n    <ClInclude Include=\"Public\\winget\\SQLiteWrapper.h\" />\r\n    <ClInclude Include=\"Public\\winget\\Yaml.h\" />\r\n    <ClInclude Include=\"YamlWrapper.h\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"AppInstallerLogging.cpp\" />\r\n    <ClCompile Include=\"AppInstallerStrings.cpp\" />\r\n    <ClCompile Include=\"Certificates.cpp\" />\r\n    <ClCompile Include=\"Compression.cpp\" />\r\n    <ClCompile Include=\"COMStaticStorage.cpp\" />\r\n    <ClCompile Include=\"DateTime.cpp\" />\r\n    <ClCompile Include=\"Errors.cpp\" />\r\n    <ClCompile Include=\"Filesystem.cpp\" />\r\n    <ClCompile Include=\"GroupPolicy.cpp\" />\r\n    <ClCompile Include=\"ICU\\SQLiteICU.c\">\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Fuzzing|x64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Fuzzing|Win32'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">NotUsing</PrecompiledHeader>\r\n    </ClCompile>\r\n    <ClCompile Include=\"JsonSchemaValidation.cpp\" />\r\n    <ClCompile Include=\"JsonUtil.cpp\" />\r\n    <ClCompile Include=\"ManagedFile.cpp\" />\r\n    <ClCompile Include=\"SQLiteDynamicStorage.cpp\" />\r\n    <ClCompile Include=\"SQLiteMetadataTable.cpp\" />\r\n    <ClCompile Include=\"Registry.cpp\" />\r\n    <ClCompile Include=\"Resources.cpp\" />\r\n    <ClCompile Include=\"pch.cpp\">\r\n      <PrecompiledHeader>Create</PrecompiledHeader>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Runtime.cpp\" />\r\n    <ClCompile Include=\"Security.cpp\" />\r\n    <ClCompile Include=\"SHA256.cpp\" />\r\n    <ClCompile Include=\"SharedThreadGlobals.cpp\" />\r\n    <ClCompile Include=\"SQLiteStatementBuilder.cpp\" />\r\n    <ClCompile Include=\"SQLiteStorageBase.cpp\" />\r\n    <ClCompile Include=\"SQLiteTempTable.cpp\" />\r\n    <ClCompile Include=\"SQLiteVersion.cpp\" />\r\n    <ClCompile Include=\"SQLiteWrapper.cpp\" />\r\n    <ClCompile Include=\"Versions.cpp\" />\r\n    <ClCompile Include=\"Yaml.cpp\" />\r\n    <ClCompile Include=\"YamlWrapper.cpp\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"packages.config\" />\r\n    <None Include=\"PropertySheet.props\" />\r\n  </ItemGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\r\n  <ImportGroup Label=\"ExtensionTargets\">\r\n    <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets')\" />\r\n    <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" />\r\n  </ImportGroup>\r\n  <Target Name=\"EnsureNuGetPackageBuildImports\" BeforeTargets=\"PrepareForBuild\">\r\n    <PropertyGroup>\r\n      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>\r\n    </PropertyGroup>\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets'))\" />\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props'))\" />\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets'))\" />\r\n  </Target>\r\n</Project>\r\n\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/AppInstallerSharedLib.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup>\r\n    <Filter Include=\"Source Files\">\r\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Header Files\">\r\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r\n      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Public\">\r\n      <UniqueIdentifier>{5cdf3fa3-e657-4d84-81bb-f740aa476143}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Public\\winget\">\r\n      <UniqueIdentifier>{41035fd6-dc74-4464-b9b1-4ffe95d6789c}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Public\\Telemetry - Do Not Modify\">\r\n      <UniqueIdentifier>{3a5b2424-6c80-4edc-85bc-f371f2e93a33}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"SQLite\">\r\n      <UniqueIdentifier>{d5b3a812-cc25-4826-b380-0488cd0944e1}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"ICU\">\r\n      <UniqueIdentifier>{2403870a-5bb9-461f-8558-877c23ec487b}</UniqueIdentifier>\r\n    </Filter>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"pch.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\AppInstallerLogging.h\">\r\n      <Filter>Public</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\AppInstallerStrings.h\">\r\n      <Filter>Public</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\AppInstallerSHA256.h\">\r\n      <Filter>Public</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\AppInstallerErrors.h\">\r\n      <Filter>Public</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\AppInstallerDateTime.h\">\r\n      <Filter>Public</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"YamlWrapper.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\Yaml.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\JsonSchemaValidation.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\Resources.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\SharedThreadGlobals.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\LocIndependent.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\AppInstallerLanguageUtilities.h\">\r\n      <Filter>Public</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\AppInstallerVersions.h\">\r\n      <Filter>Public</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\Telemetry\\MicrosoftTelemetry.h\">\r\n      <Filter>Public\\Telemetry - Do Not Modify</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\Telemetry\\WinEventLogLevels.h\">\r\n      <Filter>Public\\Telemetry - Do Not Modify</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\Runtime.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\AsyncTokens.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\ConfigurationSetProcessorHandlers.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\ILifetimeWatcher.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\Security.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\Certificates.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\GroupPolicy.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\Registry.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\JsonUtil.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\IConfigurationStaticsInternals.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\SQLiteStatementBuilder.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\SQLiteStorageBase.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\SQLiteTempTable.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\SQLiteWrapper.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ICU\\SQLiteICU.h\">\r\n      <Filter>ICU</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\SQLiteVersion.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\ManagedFile.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\SQLiteMetadataTable.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\Compression.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\Filesystem.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\SQLiteDynamicStorage.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\ModuleCountBase.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\COMStaticStorage.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\DetectMismatch.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\winget\\PathTree.h\">\r\n      <Filter>Public\\winget</Filter>\r\n    </ClInclude>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"pch.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"AppInstallerLogging.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"AppInstallerStrings.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"DateTime.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"SHA256.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Errors.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"YamlWrapper.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Yaml.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"JsonSchemaValidation.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"SharedThreadGlobals.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Resources.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Versions.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Runtime.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Security.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Certificates.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"GroupPolicy.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Registry.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"JsonUtil.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"SQLiteStatementBuilder.cpp\">\r\n      <Filter>SQLite</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"SQLiteStorageBase.cpp\">\r\n      <Filter>SQLite</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"SQLiteTempTable.cpp\">\r\n      <Filter>SQLite</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"SQLiteWrapper.cpp\">\r\n      <Filter>SQLite</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"SQLiteMetadataTable.cpp\">\r\n      <Filter>SQLite</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ICU\\SQLiteICU.c\">\r\n      <Filter>ICU</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"SQLiteVersion.cpp\">\r\n      <Filter>SQLite</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ManagedFile.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Compression.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Filesystem.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"SQLiteDynamicStorage.cpp\">\r\n      <Filter>SQLite</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"COMStaticStorage.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"PropertySheet.props\" />\r\n    <None Include=\"packages.config\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Natvis Include=\"$(MSBuildThisFileDirectory)..\\..\\natvis\\wil.natvis\" />\r\n  </ItemGroup>\r\n</Project>"
  },
  {
    "path": "src/AppInstallerSharedLib/AppInstallerStrings.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/AppInstallerStrings.h\"\r\n#include \"Public/AppInstallerErrors.h\"\r\n#include \"Public/AppInstallerLogging.h\"\r\n#include \"Public/AppInstallerSHA256.h\"\r\n\r\nnamespace AppInstaller::Utility\r\n{\r\n    // Same as std::isspace(char)\r\n#define AICLI_SPACE_CHARS \" \\f\\n\\r\\t\\v\"sv\r\n\r\n    using namespace std::string_view_literals;\r\n    constexpr std::string_view s_SpaceChars = AICLI_SPACE_CHARS;\r\n    constexpr std::wstring_view s_WideSpaceChars = L\"\" AICLI_SPACE_CHARS;\r\n\r\n    namespace\r\n    {\r\n        // Contains the ICU objects necessary to do break iteration.\r\n        struct ICUBreakIterator\r\n        {\r\n            ICUBreakIterator(std::string_view input, UBreakIteratorType type)\r\n            {\r\n                UErrorCode err = U_ZERO_ERROR; \r\n\r\n                m_text.reset(utext_openUTF8(nullptr, input.data(), wil::safe_cast<int64_t>(input.length()), &err));\r\n                if (U_FAILURE(err))\r\n                {\r\n                    AICLI_LOG(Core, Error, << \"utext_openUTF8 returned \" << err);\r\n                    THROW_HR(APPINSTALLER_CLI_ERROR_ICU_BREAK_ITERATOR_ERROR);\r\n                }\r\n\r\n                m_brk.reset(ubrk_open(type, nullptr, nullptr, 0, &err));\r\n                if (U_FAILURE(err))\r\n                {\r\n                    AICLI_LOG(Core, Error, << \"ubrk_open returned \" << err);\r\n                    THROW_HR(APPINSTALLER_CLI_ERROR_ICU_BREAK_ITERATOR_ERROR);\r\n                }\r\n\r\n                ubrk_setUText(m_brk.get(), m_text.get(), &err);\r\n                if (U_FAILURE(err))\r\n                {\r\n                    AICLI_LOG(Core, Error, << \"ubrk_setUText returned \" << err);\r\n                    THROW_HR(APPINSTALLER_CLI_ERROR_ICU_BREAK_ITERATOR_ERROR);\r\n                }\r\n\r\n                int32_t i = ubrk_first(m_brk.get());\r\n                if (i != 0)\r\n                {\r\n                    AICLI_LOG(Core, Error, << \"ubrk_first returned \" << i);\r\n                    THROW_HR(APPINSTALLER_CLI_ERROR_ICU_BREAK_ITERATOR_ERROR);\r\n                }\r\n            }\r\n\r\n            // Gets the current break value; the byte offset or UBRK_DONE.\r\n            int32_t CurrentBreak() const { return m_currentBrk; }\r\n\r\n            // Gets the current byte offset, throwing if the value is UBRK_DONE or negative.\r\n            size_t CurrentOffset() const\r\n            {\r\n                THROW_HR_IF(E_NOT_VALID_STATE, m_currentBrk < 0);\r\n                return static_cast<size_t>(m_currentBrk);\r\n            }\r\n\r\n            // Returns the byte offset of the next break in the string\r\n            int32_t Next()\r\n            {\r\n                m_currentBrk = ubrk_next(m_brk.get());\r\n                return m_currentBrk;\r\n            }\r\n\r\n            // Returns the byte offset of the next count'th break in the string\r\n            int32_t Advance(size_t count)\r\n            {\r\n                for (size_t i = 0; i < count && m_currentBrk != UBRK_DONE; ++i)\r\n                {\r\n                    Next();\r\n                }\r\n                return m_currentBrk;\r\n            }\r\n\r\n            // Returns code point of the character at m_currentBrk, or U_SENTINEL if m_currentBrk points to the end.\r\n            UChar32 CurrentCodePoint()\r\n            {\r\n                return utext_char32At(m_text.get(), m_currentBrk);\r\n            }\r\n\r\n            // Returns the status from the break rule that determined the most recently break position.\r\n            int32_t CurrentRuleStatus()\r\n            {\r\n                return ubrk_getRuleStatus(m_brk.get());\r\n            }\r\n\r\n        private:\r\n            wil::unique_any<UText*, decltype(utext_close), &utext_close> m_text;\r\n            wil::unique_any<UBreakIterator*, decltype(ubrk_close), &ubrk_close> m_brk;\r\n            int32_t m_currentBrk = 0;\r\n        };\r\n\r\n        template <typename StringType>\r\n        StringType& TrimTemplate(StringType& input, std::basic_string_view<typename StringType::value_type> spaceChars)\r\n        {\r\n            if (!input.empty())\r\n            {\r\n                size_t begin = input.find_first_not_of(spaceChars);\r\n                size_t end = input.find_last_not_of(spaceChars);\r\n\r\n                if (begin == StringType::npos || end == StringType::npos)\r\n                {\r\n                    input = {};\r\n                }\r\n                else if (begin != 0 || end != input.length() - 1)\r\n                {\r\n                    input = input.substr(begin, (end - begin) + 1);\r\n                }\r\n            }\r\n\r\n            return input;\r\n        }\r\n\r\n        template <typename StringType>\r\n        StringType TrimCopyTemplate(const StringType& input)\r\n        {\r\n            StringType result = input;\r\n            Utility::Trim(result);\r\n            return result;\r\n        }\r\n\r\n        template <typename StringType>\r\n        StringType TrimMoveTemplate(StringType&& input)\r\n        {\r\n            StringType result = std::move(input);\r\n            Utility::Trim(result);\r\n            return result;\r\n        }\r\n\r\n        template <typename StringType>\r\n        std::vector<StringType> SplitTemplate(const StringType& input, typename StringType::value_type separator, bool trim)\r\n        {\r\n            std::vector<StringType> result;\r\n            size_t startIndex = 0;\r\n            size_t endIndex = 0;\r\n\r\n            while ((endIndex = input.find(separator, startIndex)) != StringType::npos)\r\n            {\r\n                StringType substring = input.substr(startIndex, endIndex - startIndex);\r\n\r\n                if (trim)\r\n                {\r\n                    Utility::Trim(substring);\r\n                }\r\n\r\n                result.emplace_back(std::move(substring));\r\n                startIndex = endIndex + 1;\r\n            }\r\n\r\n            result.emplace_back(trim ? Utility::Trim(input.substr(startIndex)) : input.substr(startIndex));\r\n            return result;\r\n        }\r\n    }\r\n\r\n    bool CaseInsensitiveEquals(std::string_view a, std::string_view b)\r\n    {\r\n        return ToLower(a) == ToLower(b);\r\n    }\r\n\r\n    bool CaseInsensitiveEquals(std::wstring_view a, std::wstring_view b)\r\n    {\r\n        return ToLower(a) == ToLower(b);\r\n    }\r\n\r\n    bool CaseInsensitiveContains(const std::vector<std::string_view>& a, std::string_view b)\r\n    {\r\n        auto B = ToLower(b);\r\n        return std::any_of(a.begin(), a.end(), [&](const std::string_view& s) { return ToLower(s) == B; });\r\n    }\r\n\r\n    bool StartsWith(std::wstring_view a, std::wstring_view b)\r\n    {\r\n        return a.length() >= b.length() && a.substr(0, b.length()) == b;\r\n    }\r\n\r\n    bool CaseInsensitiveStartsWith(std::string_view a, std::string_view b)\r\n    {\r\n        return a.length() >= b.length() && CaseInsensitiveEquals(a.substr(0, b.length()), b);\r\n    }\r\n\r\n    bool CaseInsensitiveStartsWith(std::wstring_view a, std::wstring_view b)\r\n    {\r\n        return a.length() >= b.length() && CaseInsensitiveEquals(a.substr(0, b.length()), b);\r\n    }\r\n\r\n    bool CaseInsensitiveContainsSubstring(std::string_view a, std::string_view b)\r\n    {\r\n        auto it = std::search(\r\n            a.begin(), a.end(),\r\n            b.begin(), b.end(),\r\n            [](char ch1, char ch2) { return std::tolower(ch1) == std::tolower(ch2); }\r\n        );\r\n        return (it != a.end());\r\n    }\r\n\r\n    bool ContainsSubstring(std::string_view a, std::string_view b)\r\n    {\r\n        auto it = std::search(\r\n            a.begin(), a.end(),\r\n            b.begin(), b.end()\r\n        );\r\n        return (it != a.end());\r\n    }\r\n\r\n    bool ICUCaseInsensitiveEquals(std::string_view a, std::string_view b)\r\n    {\r\n        return FoldCase(a) == FoldCase(b);\r\n    }\r\n\r\n    bool ICUCaseInsensitiveStartsWith(std::string_view a, std::string_view b)\r\n    {\r\n        return a.length() >= b.length() && ICUCaseInsensitiveEquals(a.substr(0, b.length()), b);\r\n    }\r\n\r\n    std::string ConvertToUTF8(std::wstring_view input)\r\n    {\r\n        if (input.empty())\r\n        {\r\n            return {};\r\n        }\r\n\r\n        int utf8ByteCount = WideCharToMultiByte(CP_UTF8, 0, input.data(), wil::safe_cast<int>(input.length()), nullptr, 0, nullptr, nullptr);\r\n        THROW_LAST_ERROR_IF(utf8ByteCount == 0);\r\n\r\n        // Since the string view should not contain the null char, the result won't either.\r\n        // This allows us to use the resulting size value directly in the string constructor.\r\n        std::string result(wil::safe_cast<size_t>(utf8ByteCount), '\\0');\r\n\r\n        int utf8BytesWritten = WideCharToMultiByte(CP_UTF8, 0, input.data(), wil::safe_cast<int>(input.length()), &result[0], wil::safe_cast<int>(result.size()), nullptr, nullptr);\r\n        FAIL_FAST_HR_IF(E_UNEXPECTED, utf8ByteCount != utf8BytesWritten);\r\n\r\n        return result;\r\n    }\r\n\r\n    std::wstring ConvertToUTF16(std::string_view input, UINT codePage)\r\n    {\r\n        if (input.empty())\r\n        {\r\n            return {};\r\n        }\r\n\r\n        int utf16CharCount = MultiByteToWideChar(codePage, 0, input.data(), wil::safe_cast<int>(input.length()), nullptr, 0);\r\n        THROW_LAST_ERROR_IF(utf16CharCount == 0);\r\n\r\n        // Since the string view should not contain the null char, the result won't either.\r\n        // This allows us to use the resulting size value directly in the string constructor.\r\n        std::wstring result(wil::safe_cast<size_t>(utf16CharCount), L'\\0');\r\n\r\n        int utf16CharsWritten = MultiByteToWideChar(codePage, 0, input.data(), wil::safe_cast<int>(input.length()), &result[0], wil::safe_cast<int>(result.size()));\r\n        FAIL_FAST_HR_IF(E_UNEXPECTED, utf16CharCount != utf16CharsWritten);\r\n\r\n        return result;\r\n    }\r\n\r\n    std::optional<std::wstring> TryConvertToUTF16(std::string_view input, UINT codePage)\r\n    {\r\n        if (input.empty())\r\n        {\r\n            return std::wstring{};\r\n        }\r\n\r\n        int utf16CharCount = MultiByteToWideChar(codePage, 0, input.data(), wil::safe_cast<int>(input.length()), nullptr, 0);\r\n        if (utf16CharCount == 0)\r\n        {\r\n            return {};\r\n        }\r\n\r\n        // Since the string view should not contain the null char, the result won't either.\r\n        // This allows us to use the resulting size value directly in the string constructor.\r\n        std::wstring result(wil::safe_cast<size_t>(utf16CharCount), L'\\0');\r\n\r\n        int utf16CharsWritten = MultiByteToWideChar(codePage, 0, input.data(), wil::safe_cast<int>(input.length()), &result[0], wil::safe_cast<int>(result.size()));\r\n        if (utf16CharCount != utf16CharsWritten)\r\n        {\r\n            return {};\r\n        }\r\n\r\n        return std::optional{ result };\r\n    }\r\n\r\n    std::u32string ConvertToUTF32(std::string_view input)\r\n    {\r\n        if (input.empty())\r\n        {\r\n            return {};\r\n        }\r\n\r\n        UErrorCode errorCode = UErrorCode::U_ZERO_ERROR;\r\n        auto utf32ByteCount= ucnv_convert(\"UTF-32\", \"UTF-8\", nullptr, 0, input.data(), static_cast<int32_t>(input.size()), &errorCode);\r\n\r\n        if (errorCode != U_BUFFER_OVERFLOW_ERROR)\r\n        {\r\n            AICLI_LOG(Core, Error, << \"ucnv_convert returned \" << errorCode);\r\n            THROW_HR(APPINSTALLER_CLI_ERROR_ICU_CONVERSION_ERROR);\r\n        }\r\n\r\n        FAIL_FAST_HR_IF(E_UNEXPECTED, utf32ByteCount % sizeof(char32_t) != 0);\r\n        auto utf32CharCount = utf32ByteCount / sizeof(char32_t);\r\n        std::u32string result(utf32CharCount, U'\\0');\r\n\r\n        errorCode = UErrorCode::U_ZERO_ERROR;\r\n\r\n        auto utf32BytesWritten = ucnv_convert(\"UTF-32\", \"UTF-8\", (char*)(result.data()), utf32ByteCount, input.data(), static_cast<int32_t>(input.size()), &errorCode);\r\n\r\n        // The size we pass to ucnv_convert is not enough for it to put in the null terminator,\r\n        // which wouldn't work anyways as it puts a single byte.\r\n        if (errorCode != U_STRING_NOT_TERMINATED_WARNING)\r\n        {\r\n            AICLI_LOG(Core, Error, << \"ucnv_convert returned \" << errorCode);\r\n            THROW_HR(APPINSTALLER_CLI_ERROR_ICU_CONVERSION_ERROR);\r\n        }\r\n\r\n        FAIL_FAST_HR_IF(E_UNEXPECTED, utf32ByteCount != utf32BytesWritten);\r\n\r\n        return result;\r\n    }\r\n\r\n    size_t UTF8Length(std::string_view input)\r\n    {\r\n        ICUBreakIterator itr{ input, UBRK_CHARACTER };\r\n\r\n        size_t numGraphemeClusters = 0;\r\n\r\n        while (itr.Next() != UBRK_DONE)\r\n        {\r\n            numGraphemeClusters++;\r\n        }\r\n\r\n        return numGraphemeClusters;\r\n    }\r\n\r\n    size_t UTF8ColumnWidth(const NormalizedUTF8<NormalizationC>& input)\r\n    {\r\n        ICUBreakIterator itr{ input, UBRK_CHARACTER };\r\n\r\n        size_t columnWidth = 0;\r\n        UChar32 currentCP = 0;\r\n\r\n        currentCP = itr.CurrentCodePoint();\r\n        while (itr.Next() != UBRK_DONE && currentCP != U_SENTINEL)\r\n        {\r\n            int32_t width = u_getIntPropertyValue(currentCP, UCHAR_EAST_ASIAN_WIDTH);\r\n            columnWidth += width == U_EA_FULLWIDTH || width == U_EA_WIDE ? 2 : 1;\r\n\r\n            currentCP = itr.CurrentCodePoint();\r\n        }\r\n\r\n        return columnWidth;\r\n    }\r\n\r\n    std::string_view UTF8Substring(std::string_view input, size_t offset, size_t count)\r\n    {\r\n        ICUBreakIterator itr{ input, UBRK_CHARACTER };\r\n\r\n        // Offset was past end, throw just like std::string::substr\r\n        if (itr.Advance(offset) == UBRK_DONE)\r\n        {\r\n            throw std::out_of_range(\"UTF8Substring: offset past end of input\");\r\n        }\r\n\r\n        size_t utf8Offset = itr.CurrentOffset();\r\n        size_t utf8Count = 0;\r\n\r\n        // Count past end, convert to npos to get all of string\r\n        if (itr.Advance(count) == UBRK_DONE)\r\n        {\r\n            utf8Count = std::string_view::npos;\r\n        }\r\n        else\r\n        {\r\n            utf8Count = itr.CurrentOffset() - utf8Offset;\r\n        }\r\n\r\n        return input.substr(utf8Offset, utf8Count);\r\n    }\r\n\r\n    std::string UTF8TrimRightToColumnWidth(const NormalizedUTF8<NormalizationC>& input, size_t expectedWidth, size_t& actualWidth)\r\n    {\r\n        ICUBreakIterator itr{ input, UBRK_CHARACTER };\r\n\r\n        size_t columnWidth = 0;\r\n        UChar32 currentCP = 0;\r\n        int32_t currentBrk = 0;\r\n        int32_t nextBrk = 0;\r\n\r\n        currentCP = itr.CurrentCodePoint();\r\n        currentBrk = itr.CurrentBreak();\r\n        nextBrk = itr.Next();\r\n        while (nextBrk != UBRK_DONE && currentCP != U_SENTINEL)\r\n        {\r\n            int32_t width = u_getIntPropertyValue(currentCP, UCHAR_EAST_ASIAN_WIDTH);\r\n            int charWidth = width == U_EA_FULLWIDTH || width == U_EA_WIDE ? 2 : 1;\r\n            columnWidth += charWidth;\r\n\r\n            if (columnWidth > expectedWidth)\r\n            {\r\n                columnWidth -= charWidth;\r\n                break;\r\n            }\r\n\r\n            currentCP = itr.CurrentCodePoint();\r\n            currentBrk = nextBrk;\r\n            nextBrk = itr.Next();\r\n        }\r\n\r\n        actualWidth = columnWidth;\r\n\r\n        return input.substr(0, currentBrk);\r\n    }\r\n\r\n    std::string Normalize(std::string_view input, NORM_FORM form)\r\n    {\r\n        if (input.empty())\r\n        {\r\n            return {};\r\n        }\r\n\r\n        return ConvertToUTF8(Normalize(ConvertToUTF16(input), form));\r\n    }\r\n\r\n    std::wstring Normalize(std::wstring_view input, NORM_FORM form)\r\n    {\r\n        if (input.empty())\r\n        {\r\n            return {};\r\n        }\r\n\r\n        std::wstring result;\r\n\r\n        int cchEstimate = NormalizeString(form, input.data(), static_cast<int>(input.length()), NULL, 0);\r\n        for (;;)\r\n        {\r\n            result.resize(cchEstimate);\r\n            cchEstimate = NormalizeString(form, input.data(), static_cast<int>(input.length()), &result[0], cchEstimate);\r\n\r\n            if (cchEstimate > 0)\r\n            {\r\n                result.resize(cchEstimate);\r\n                return result;\r\n            }\r\n            else\r\n            {\r\n                DWORD dwError = GetLastError();\r\n                THROW_LAST_ERROR_IF(dwError != ERROR_INSUFFICIENT_BUFFER);\r\n\r\n                // New guess is negative of the return value.\r\n                cchEstimate = -cchEstimate;\r\n\r\n                THROW_HR_IF_MSG(E_UNEXPECTED, static_cast<size_t>(cchEstimate) <= result.size(), \"New estimate should never be less than previous value\");\r\n            }\r\n        }\r\n    }\r\n\r\n    void ReplaceEmbeddedNullCharacters(std::string& s, char c)\r\n    {\r\n        for (size_t i = 0; i < s.length(); ++i)\r\n        {\r\n            if (s[i] == '\\0')\r\n            {\r\n                s[i] = c;\r\n            }\r\n        }\r\n    }\r\n\r\n    std::string ToLower(std::string_view in)\r\n    {\r\n        std::string result(in);\r\n        std::transform(result.begin(), result.end(), result.begin(),\r\n            [](unsigned char c) { return static_cast<char>(std::tolower(c)); });\r\n        return result;\r\n    }\r\n\r\n    std::wstring ToLower(std::wstring_view in)\r\n    {\r\n        std::wstring result(in);\r\n        std::transform(result.begin(), result.end(), result.begin(),\r\n            [](unsigned short c) { return std::towlower(c); });\r\n        return result;\r\n    }\r\n\r\n    std::string FoldCase(std::string_view input)\r\n    {\r\n        if (input.empty())\r\n        {\r\n            return {};\r\n        }\r\n\r\n        wil::unique_any<UCaseMap*, decltype(ucasemap_close), &ucasemap_close> caseMap;\r\n        UErrorCode errorCode = UErrorCode::U_ZERO_ERROR;\r\n        caseMap.reset(ucasemap_open(nullptr, U_FOLD_CASE_DEFAULT, &errorCode));\r\n\r\n        if (U_FAILURE(errorCode))\r\n        {\r\n            AICLI_LOG(Core, Error, << \"ucasemap_open returned \" << errorCode);\r\n            THROW_HR(APPINSTALLER_CLI_ERROR_ICU_CASEMAP_ERROR);\r\n        }\r\n\r\n        int32_t cch = ucasemap_utf8FoldCase(caseMap.get(), nullptr, 0, input.data(), static_cast<int32_t>(input.size()), &errorCode);\r\n        if (errorCode != U_BUFFER_OVERFLOW_ERROR)\r\n        {\r\n            AICLI_LOG(Core, Error, << \"ucasemap_utf8FoldCase returned \" << errorCode);\r\n            THROW_HR(APPINSTALLER_CLI_ERROR_ICU_CASEMAP_ERROR);\r\n        }\r\n\r\n        errorCode = UErrorCode::U_ZERO_ERROR;\r\n\r\n        std::string result(cch, '\\0');\r\n        cch = ucasemap_utf8FoldCase(caseMap.get(), &result[0], cch, input.data(), static_cast<int32_t>(input.size()), &errorCode);\r\n        if (U_FAILURE(errorCode))\r\n        {\r\n            AICLI_LOG(Core, Error, << \"ucasemap_utf8FoldCase returned \" << errorCode);\r\n            THROW_HR(APPINSTALLER_CLI_ERROR_ICU_CASEMAP_ERROR);\r\n        }\r\n\r\n        while (result.back() == '\\0')\r\n        {\r\n            result.pop_back();\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    NormalizedString FoldCase(const NormalizedString& input)\r\n    {\r\n        NormalizedString result;\r\n        result.assign(FoldCase(static_cast<std::string_view>(input)));\r\n        return result;\r\n    }\r\n\r\n    bool IsEmptyOrWhitespace(std::string_view str)\r\n    {\r\n        if (str.empty())\r\n        {\r\n            return true;\r\n        }\r\n\r\n        return str.find_last_not_of(s_SpaceChars) == std::string_view::npos;\r\n    }\r\n\r\n    bool IsEmptyOrWhitespace(std::wstring_view str)\r\n    {\r\n        if (str.empty())\r\n        {\r\n            return true;\r\n        }\r\n\r\n        return str.find_last_not_of(s_WideSpaceChars) == std::wstring_view::npos;\r\n    }\r\n\r\n    bool FindAndReplace(std::string& inputStr, std::string_view token, std::string_view value)\r\n    {\r\n        bool result = false;\r\n        std::string::size_type pos = 0u;\r\n        while ((pos = inputStr.find(token, pos)) != std::string::npos)\r\n        {\r\n            result = true;\r\n            inputStr.replace(pos, token.length(), value);\r\n            pos += value.length();\r\n        }\r\n        return result;\r\n    }\r\n\r\n    std::wstring ReplaceWhileCopying(std::wstring_view input, std::wstring_view token, std::wstring_view value)\r\n    {\r\n        if (token.empty())\r\n        {\r\n            return std::wstring{ input };\r\n        }\r\n\r\n        std::wstring result;\r\n        result.reserve(input.size());\r\n\r\n        std::wstring::size_type pos = 0u;\r\n        do\r\n        {\r\n            std::wstring::size_type findPos = input.find(token, pos);\r\n\r\n            if (findPos == std::wstring::npos)\r\n            {\r\n                result.append(input.substr(pos));\r\n            }\r\n            else\r\n            {\r\n                result.append(input.substr(pos, findPos - pos));\r\n                result.append(value);\r\n                findPos += token.length();\r\n            }\r\n\r\n            pos = findPos;\r\n        }\r\n        while (pos != std::wstring::npos);\r\n\r\n        return result;\r\n    }\r\n\r\n    std::string& Trim(std::string& str)\r\n    {\r\n        return TrimTemplate(str, s_SpaceChars);\r\n    }\r\n\r\n    std::string Trim(const std::string& str)\r\n    {\r\n        return TrimCopyTemplate(str);\r\n    }\r\n\r\n    std::string Trim(std::string&& str)\r\n    {\r\n        return TrimMoveTemplate(std::move(str));\r\n    }\r\n\r\n    std::string_view& Trim(std::string_view& str)\r\n    {\r\n        return TrimTemplate(str, s_SpaceChars);\r\n    }\r\n\r\n    std::string_view Trim(std::string_view&& str)\r\n    {\r\n        return TrimCopyTemplate(str);\r\n    }\r\n\r\n    std::wstring& Trim(std::wstring& str)\r\n    {\r\n        return TrimTemplate(str, s_WideSpaceChars);\r\n    }\r\n\r\n    std::wstring Trim(const std::wstring& str)\r\n    {\r\n        return TrimCopyTemplate(str);\r\n    }\r\n\r\n    std::wstring Trim(std::wstring&& str)\r\n    {\r\n        return TrimMoveTemplate(std::move(str));\r\n    }\r\n\r\n    std::wstring_view& Trim(std::wstring_view& str)\r\n    {\r\n        return TrimTemplate(str, s_WideSpaceChars);\r\n    }\r\n\r\n    std::wstring_view Trim(std::wstring_view&& str)\r\n    {\r\n        return TrimCopyTemplate(str);\r\n    }\r\n\r\n    std::string ReadEntireStream(std::istream& stream)\r\n    {\r\n        std::streampos currentPos = stream.tellg();\r\n        stream.seekg(0, std::ios_base::end);\r\n\r\n        auto offset = stream.tellg() - currentPos;\r\n        stream.seekg(currentPos);\r\n\r\n        // Don't allow use of this API for reading very large streams.\r\n        THROW_HR_IF(E_OUTOFMEMORY, offset > static_cast<std::streamoff>(std::numeric_limits<uint32_t>::max()));\r\n        std::string result(static_cast<size_t>(offset), '\\0');\r\n        stream.read(&result[0], offset);\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<std::uint8_t> ReadEntireStreamAsByteArray(std::istream& stream)\r\n    {\r\n        std::streampos currentPos = stream.tellg();\r\n        stream.seekg(0, std::ios_base::end);\r\n\r\n        auto offset = stream.tellg() - currentPos;\r\n        stream.seekg(currentPos);\r\n\r\n        // Don't allow use of this API for reading very large streams.\r\n        THROW_HR_IF(E_OUTOFMEMORY, offset > static_cast<std::streamoff>(std::numeric_limits<uint32_t>::max()));\r\n        std::vector<std::uint8_t> result;\r\n        result.resize(static_cast<size_t>(offset));\r\n        stream.read(reinterpret_cast<char*>(result.data()), offset);\r\n\r\n        return result;\r\n    }\r\n\r\n    std::wstring ExpandEnvironmentVariables(const std::wstring& input)\r\n    {\r\n        if (input.empty())\r\n        {\r\n            return {};\r\n        }\r\n\r\n        DWORD charCount = ExpandEnvironmentStringsW(input.c_str(), nullptr, 0);\r\n        THROW_LAST_ERROR_IF(charCount == 0);\r\n\r\n        std::wstring result(wil::safe_cast<size_t>(charCount), L'\\0');\r\n\r\n        DWORD charCountWritten = ExpandEnvironmentStringsW(input.c_str(), &result[0], charCount);\r\n        THROW_HR_IF(E_UNEXPECTED, charCount != charCountWritten);\r\n\r\n        if (result.back() == L'\\0')\r\n        {\r\n            result.resize(result.size() - 1);\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    // Follow the rules at https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file to replace\r\n    // invalid characters in a candidate path part.\r\n    // Additionally, based on https://docs.microsoft.com/en-us/windows/win32/fileio/filesystem-functionality-comparison#limits\r\n    // limit the number of characters to 255.\r\n    std::string MakeSuitablePathPart(std::string_view candidate)\r\n    {\r\n        constexpr char replaceChar = '_';\r\n        constexpr std::string_view illegalChars = R\"(<>:\"/\\|?*)\";\r\n        constexpr size_t pathLengthLimit = 255;\r\n\r\n        // First, walk the string and replace illegal characters\r\n        std::string result;\r\n        result.reserve(candidate.size());\r\n\r\n        ICUBreakIterator itr{ candidate, UBRK_CHARACTER };\r\n        size_t resultBreakCount = 0;\r\n\r\n        while (itr.CurrentBreak() != UBRK_DONE && itr.CurrentOffset() < candidate.size() && resultBreakCount <= pathLengthLimit)\r\n        {\r\n            UChar32 current = itr.CurrentCodePoint();\r\n            bool isIllegal = current < 32 || (current < 256 && illegalChars.find(static_cast<char>(current)) != std::string::npos);\r\n\r\n            int32_t offset = itr.CurrentBreak();\r\n            int32_t nextOffset = itr.Next();\r\n\r\n            // Don't allow a . at the end of a name\r\n            if (static_cast<size_t>(nextOffset) >= candidate.size())\r\n            {\r\n                if (current == static_cast<UChar32>('.'))\r\n                {\r\n                    isIllegal = true;\r\n                }\r\n            }\r\n\r\n            if (isIllegal)\r\n            {\r\n                result.append(1, replaceChar);\r\n            }\r\n            else\r\n            {\r\n                size_t count = (nextOffset == UBRK_DONE ? std::string::npos : static_cast<size_t>(nextOffset) - static_cast<size_t>(offset));\r\n                result.append(candidate.substr(static_cast<size_t>(offset), count));\r\n            }\r\n\r\n            ++resultBreakCount;\r\n        }\r\n\r\n        // If there are too many characters for a single path; switch to a hash.\r\n        // This should basically never happen, but if it does it will prevent collisions better.\r\n        if (resultBreakCount > pathLengthLimit)\r\n        {\r\n            return SHA256::ConvertToString(SHA256::ComputeHash(candidate));\r\n        }\r\n\r\n        // Second, look for any newly formed illegal names.\r\n        // For now just error on these cases; they should not happen often.\r\n        for (const auto& illegalName : {\r\n            \".\"sv, \"CON\"sv, \"PRN\"sv, \"AUX\"sv, \"NUL\"sv, \"COM1\"sv, \"COM2\"sv, \"COM3\"sv, \"COM4\"sv, \"COM5\"sv, \"COM6\"sv, \"COM7\"sv, \"COM8\"sv, \"COM9\"sv,\r\n            \"LPT1\"sv, \"LPT2\"sv, \"LPT3\"sv, \"LPT4\"sv, \"LPT5\"sv, \"LPT6\"sv, \"LPT7\"sv, \"LPT8\"sv, \"LPT9\"sv })\r\n        {\r\n            // Either equals the illegal name (starts with and same length) or starts with and the first character after is a .\r\n            if (CaseInsensitiveStartsWith(result, illegalName) && (result.size() == illegalName.size() || result[illegalName.size()] == '.'))\r\n            {\r\n                THROW_HR(E_INVALIDARG);\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::pair<std::string, std::filesystem::path> SplitFileNameFromURI(std::string_view uri)\r\n    {\r\n        std::filesystem::path filename = GetFileNameFromURI(uri);\r\n        return { std::string{ uri.substr(0, uri.size() - filename.u8string().size()) }, filename };\r\n    }\r\n\r\n    std::filesystem::path GetFileNameFromURI(std::string_view uri)\r\n    {\r\n        winrt::Windows::Foundation::Uri winrtUri{ winrt::hstring{ ConvertToUTF16(uri) } };\r\n        std::filesystem::path path{ static_cast<std::wstring_view>(winrtUri.Path()) };\r\n\r\n        return path.filename();\r\n    }\r\n\r\n    std::vector<std::string> SplitIntoWords(std::string_view input)\r\n    {\r\n        ICUBreakIterator itr{ input, UBRK_WORD };\r\n        std::size_t currentOffset = 0;\r\n\r\n        std::vector<std::string> result;\r\n        while (itr.Next() != UBRK_DONE)\r\n        {\r\n            std::size_t nextOffset = itr.CurrentOffset();\r\n\r\n            // Ignore spaces and punctuation, accept words and numbers\r\n            if (itr.CurrentRuleStatus() != UBRK_WORD_NONE)\r\n            {\r\n                auto wordSize = nextOffset - currentOffset;\r\n                result.emplace_back(input, currentOffset, wordSize);\r\n            }\r\n\r\n            currentOffset = nextOffset;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<std::string> SplitIntoLines(std::string_view input, size_t maximum)\r\n    {\r\n        std::size_t currentOffset = 0;\r\n        std::vector<std::string> result;\r\n\r\n        while (currentOffset < input.size() && (!maximum || result.size() < maximum))\r\n        {\r\n            std::size_t nextOffset = input.find_first_of(\"\\r\\n\", currentOffset);\r\n            if (nextOffset == std::string_view::npos)\r\n            {\r\n                nextOffset = input.size();\r\n            }\r\n\r\n            if (nextOffset - currentOffset > 1)\r\n            {\r\n                result.emplace_back(input.substr(currentOffset, nextOffset - currentOffset));\r\n            }\r\n\r\n            currentOffset = nextOffset + 1;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    bool LimitOutputLines(std::vector<std::string>& lines, size_t lineWidth, size_t maximum)\r\n    {\r\n        size_t totalLines = 0;\r\n        size_t currentLine = 0;\r\n        bool result = false;\r\n\r\n        for (; currentLine < lines.size() && totalLines < maximum; ++currentLine)\r\n        {\r\n            size_t currentLineWidth = UTF8ColumnWidth(lines[currentLine]);\r\n            // If current line is empty, the cost is 1 line (0 + 1).\r\n            // If not, round up to the next line count (by rounding down through integer division after subtracting 1 + 1).\r\n            size_t currentLineActualLineCount = (currentLineWidth ? (currentLineWidth - 1) / lineWidth : 0) + 1;\r\n\r\n            // The current line may be too big to be the last line, or it may be just the right size but we will end up trimming\r\n            // additional lines. In either case, append an ellipsis to indicate that we trimmed the value.\r\n            size_t availableLines = maximum - totalLines;\r\n            if (currentLineActualLineCount > availableLines ||\r\n                (currentLineActualLineCount == availableLines && currentLine != lines.size() - 1))\r\n            {\r\n                size_t actualWidth = 0;\r\n                std::string trimmedLine = UTF8TrimRightToColumnWidth(lines[currentLine], (availableLines * lineWidth) - 1, actualWidth);\r\n                trimmedLine += \"\\xE2\\x80\\xA6\"; // UTF8 encoding of ellipsis (�) character\r\n                lines[currentLine] = trimmedLine;\r\n\r\n                currentLineActualLineCount = availableLines;\r\n                result = true;\r\n            }\r\n\r\n            totalLines += currentLineActualLineCount;\r\n        }\r\n\r\n        // Drop any unprocessed lines\r\n        if (currentLine != lines.size())\r\n        {\r\n            lines.resize(currentLine);\r\n            result = true;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::string ConvertToHexString(const std::vector<uint8_t>& buffer, size_t byteCount)\r\n    {\r\n        if (byteCount && buffer.size() != byteCount)\r\n        {\r\n            THROW_HR_MSG(E_INVALIDARG, \"ConvertToHexString: Invalid buffer size\");\r\n        }\r\n\r\n        std::string result(2 * buffer.size(), '\\0');\r\n        static constexpr std::array<char, 16> hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };\r\n\r\n        for (size_t i = 0; i < buffer.size(); ++i)\r\n        {\r\n            result[2 * i] = hexChars[(buffer[i] >> 4) & 0xF];\r\n            result[2 * i + 1] = hexChars[buffer[i] & 0xF];\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<uint8_t> ParseFromHexString(const std::string& value, size_t byteCount)\r\n    {\r\n        if ((byteCount && value.size() != (2 * byteCount)) ||\r\n            (value.size() % 2))\r\n        {\r\n            THROW_HR_MSG(E_INVALIDARG, \"ParseFromHexString: Invalid value size\");\r\n        }\r\n\r\n        const char* valuePtr = value.c_str();\r\n        std::vector<uint8_t> result;\r\n        result.resize(value.size() / 2);\r\n\r\n        for (size_t i = 0; i < result.size(); i++)\r\n        {\r\n            sscanf_s(valuePtr + 2 * i, \"%02hhx\", &result[i]);\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    template <typename StringLike>\r\n    static std::string JoinInternal(std::string_view separator, const std::vector<StringLike>& vector)\r\n    {\r\n        auto vectorSize = vector.size();\r\n        if (vectorSize == 0)\r\n        {\r\n            return {};\r\n        }\r\n\r\n        std::ostringstream ssJoin;\r\n        ssJoin << vector[0];\r\n        for (size_t i = 1; i < vectorSize; ++i)\r\n        {\r\n            ssJoin << separator << vector[i];\r\n        }\r\n        return ssJoin.str();\r\n    }\r\n\r\n    LocIndString Join(LocIndView separator, const std::vector<LocIndString>& vector)\r\n    {\r\n        return LocIndString{ JoinInternal(separator, vector) };\r\n    }\r\n\r\n    std::string Join(std::string_view separator, const std::vector<std::string>& vector)\r\n    {\r\n        return JoinInternal(separator, vector);\r\n    }\r\n\r\n    std::vector<std::string> Split(const std::string& input, char separator, bool trim)\r\n    {\r\n        return SplitTemplate(input, separator, trim);\r\n    }\r\n\r\n    std::vector<std::string_view> SplitView(const std::string& input, char separator, bool trim)\r\n    {\r\n        return SplitTemplate(static_cast<std::string_view>(input), separator, trim);\r\n    }\r\n\r\n    std::vector<std::string_view> Split(std::string_view input, char separator, bool trim)\r\n    {\r\n        return SplitTemplate(input, separator, trim);\r\n    }\r\n\r\n    std::vector<std::wstring> Split(const std::wstring& input, wchar_t separator, bool trim)\r\n    {\r\n        return SplitTemplate(input, separator, trim);\r\n    }\r\n\r\n    std::vector<std::wstring_view> SplitView(const std::wstring& input, wchar_t separator, bool trim)\r\n    {\r\n        return SplitTemplate(static_cast<std::wstring_view>(input), separator, trim);\r\n    }\r\n\r\n    std::vector<std::wstring_view> Split(std::wstring_view input, wchar_t separator, bool trim)\r\n    {\r\n        return SplitTemplate(input, separator, trim);\r\n    }\r\n\r\n    std::string_view ConvertBoolToString(bool value)\r\n    {\r\n        return value ? \"true\"sv : \"false\"sv;\r\n    }\r\n\r\n    std::optional<bool> TryConvertStringToBool(const std::string_view& input)\r\n    {\r\n        try\r\n        {\r\n            if (CaseInsensitiveEquals(input, \"false\"sv))\r\n            {\r\n                return { false };\r\n            }\r\n\r\n            if (CaseInsensitiveEquals(input, \"true\"sv))\r\n            {\r\n                return { true };\r\n            }\r\n\r\n            return {};\r\n        }\r\n        catch (...)\r\n        {\r\n            return {};\r\n        }\r\n    }\r\n\r\n    std::optional<int32_t> TryConvertStringToInt32(const std::string_view& input)\r\n    {\r\n        int32_t result = 0;\r\n        auto parseResult = std::from_chars(input.data(), input.data() + input.length(), result);\r\n\r\n        std::optional<int32_t> optionalResult;\r\n        if (parseResult.ec == std::errc{})\r\n        {\r\n            optionalResult = result;\r\n        }\r\n\r\n        return optionalResult;\r\n    }\r\n\r\n    std::string ConvertGuidToString(const GUID& value)\r\n    {\r\n        wchar_t buffer[40];\r\n        THROW_HR_IF(E_UNEXPECTED, !StringFromGUID2(value, buffer, ARRAYSIZE(buffer)));\r\n        return ConvertToUTF8(buffer);\r\n    }\r\n\r\n    std::wstring CreateNewGuidNameWString()\r\n    {\r\n        GUID guid;\r\n        THROW_IF_FAILED(CoCreateGuid(&guid));\r\n\r\n        wchar_t buffer[40];\r\n        THROW_HR_IF(E_UNEXPECTED, StringFromGUID2(guid, buffer, ARRAYSIZE(buffer)) != 39);\r\n\r\n        return std::wstring{ &buffer[1], 36 };\r\n    }\r\n\r\n    bool IsDwordFlagSet(const std::string& value)\r\n    {\r\n        if (std::empty(value))\r\n        {\r\n            return false;\r\n        }\r\n\r\n        try\r\n        {\r\n            DWORD dwordValue = std::stoul(value);\r\n\r\n            // If the value is 0, then it is not set.\r\n            return dwordValue != 0;\r\n        }\r\n        catch (...)\r\n        {\r\n            return false;\r\n        }\r\n    }\r\n\r\n    size_t FindControlCodeToConvert(std::string_view input, size_t offset)\r\n    {\r\n        size_t nextControl = offset;\r\n        while (nextControl < input.size())\r\n        {\r\n            char currentChar = input[nextControl];\r\n\r\n            // Convert all low controls except tab, line feed and carriage return\r\n            if (currentChar >= 0 && currentChar < 0x20 &&\r\n                currentChar != '\\t' &&\r\n                currentChar != '\\n' &&\r\n                currentChar != '\\r')\r\n            {\r\n                break;\r\n            }\r\n\r\n            // Convert the Delete control\r\n            if (currentChar == 0x7F)\r\n            {\r\n                break;\r\n            }\r\n\r\n            ++nextControl;\r\n        }\r\n\r\n        return nextControl < input.size() ? nextControl : std::string::npos;\r\n    }\r\n\r\n    std::string ConvertControlCodesToPictures(std::string_view input)\r\n    {\r\n        std::string result;\r\n        size_t pos = 0;\r\n\r\n        while (pos < input.size())\r\n        {\r\n            size_t nextControl = FindControlCodeToConvert(input, pos);\r\n\r\n            if (nextControl == std::string::npos)\r\n            {\r\n                // No more control codes found\r\n                result += input.substr(pos);\r\n                break;\r\n            }\r\n            else\r\n            {\r\n                result += input.substr(pos, nextControl - pos);\r\n\r\n                char currentChar = input[nextControl];\r\n\r\n                if (currentChar >= 0 && currentChar < 0x20)\r\n                {\r\n                    // ASCII 0x00 - 0x1F => UTF-8 0x2400 - 0x241F\r\n                    // Then manually converted to UTF-8 since only the last character is affected\r\n                    result += '\\xE2';\r\n                    result += '\\x90';\r\n                    result += ('\\x80' + currentChar);\r\n                }\r\n                else if (currentChar == 0x7F)\r\n                {\r\n                    // UTF-8 for control picture of DELETE\r\n                    result += \"\\xE2\\x90\\xA1\";\r\n                }\r\n\r\n                pos = nextControl + 1;\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::string GetRandomString(size_t size)\r\n    {\r\n        static constexpr char chars[] = \"0123456789abcdefghijklmnopqrstuvwxyz\";\r\n        static std::default_random_engine randomEngine(std::random_device{}());\r\n        static std::uniform_int_distribution<long long> distribution(0, 35);\r\n\r\n        std::string result;\r\n        result.resize(size);\r\n\r\n        for (size_t i = 0; i < size; i++)\r\n        {\r\n            result[i] = chars[distribution(randomEngine)];\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/COMStaticStorage.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/COMStaticStorage.h\"\r\n\r\nnamespace AppInstaller::WinRT\r\n{\r\n    COMStaticStorageStatics& COMStaticStorageStatics::Instance()\r\n    {\r\n        static COMStaticStorageStatics s_instance;\r\n        return s_instance;\r\n    }\r\n\r\n    void COMStaticStorageStatics::AddStaticStorageItem(const winrt::hstring& name, const winrt::Windows::Foundation::IInspectable& item)\r\n    {\r\n        COMStaticStorageStatics& instance = Instance();\r\n        const winrt::slim_lock_guard lock{ instance.m_lock };\r\n        winrt::Windows::ApplicationModel::Core::CoreApplication::Properties().Insert(name, item);\r\n        instance.m_items.emplace(std::wstring{ name });\r\n    }\r\n\r\n    void COMStaticStorageStatics::ResetAll() try\r\n    {\r\n        COMStaticStorageStatics& instance = Instance();\r\n        std::set<std::wstring> localItems;\r\n\r\n        {\r\n            const winrt::slim_lock_guard lock{ instance.m_lock };\r\n            instance.m_items.swap(localItems);\r\n        }\r\n\r\n        for (const auto& item : localItems)\r\n        {\r\n            winrt::Windows::ApplicationModel::Core::CoreApplication::Properties().TryRemove(item);\r\n        }\r\n    }\r\n    CATCH_LOG();\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Certificates.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"winget/Certificates.h\"\r\n#include \"AppInstallerDateTime.h\"\r\n#include \"AppInstallerLogging.h\"\r\n#include \"AppInstallerStrings.h\"\r\n#include \"winget/JsonUtil.h\"\r\n#include \"winget/Resources.h\"\r\n\r\nnamespace AppInstaller::Certificates\r\n{\r\n    namespace\r\n    {\r\n        std::string GetNameString(PCCERT_CONTEXT certContext, DWORD nameType, bool forIssuer, void* typeParam = nullptr)\r\n        {\r\n            if (!certContext)\r\n            {\r\n                return \"<no certificate loaded>\";\r\n            }\r\n\r\n            DWORD flags = forIssuer ? CERT_NAME_ISSUER_FLAG : 0;\r\n\r\n            DWORD characterCount = CertGetNameStringW(certContext, nameType, flags, typeParam, nullptr, 0);\r\n            std::wstring result(characterCount, L'\\0');\r\n            characterCount = CertGetNameStringW(certContext, nameType, flags, typeParam, &result[0], characterCount);\r\n\r\n            if (static_cast<size_t>(characterCount) == result.size())\r\n            {\r\n                return Utility::ConvertToUTF8(static_cast<std::wstring_view>(result).substr(0, result.size() - 1));\r\n            }\r\n            else\r\n            {\r\n                return \"<unknown>\";\r\n            }\r\n        }\r\n\r\n        std::string GetSimpleDisplayName(PCCERT_CONTEXT certContext, bool forIssuer = false)\r\n        {\r\n            return GetNameString(certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, forIssuer);\r\n        }\r\n\r\n        std::string GetX500Name(PCCERT_CONTEXT certContext, bool forIssuer = false)\r\n        {\r\n            DWORD stringType = CERT_X500_NAME_STR;\r\n            return GetNameString(certContext, CERT_NAME_RDN_TYPE, forIssuer, &stringType);\r\n        }\r\n\r\n        std::string GetCommonName(PCCERT_CONTEXT certContext, bool forIssuer = false)\r\n        {\r\n            std::string commonName = szOID_COMMON_NAME;\r\n            return GetNameString(certContext, CERT_NAME_ATTR_TYPE, forIssuer, &commonName[0]);\r\n        }\r\n\r\n        std::string GetDescriptionOfCertChain(PCCERT_CHAIN_CONTEXT chainContext)\r\n        {\r\n            PCCERT_SIMPLE_CHAIN chain = chainContext->rgpChain[0];\r\n            std::ostringstream stream;\r\n            std::string indent;\r\n\r\n            for (DWORD i = 0; i < chain->cElement; ++i)\r\n            {\r\n                PCCERT_CHAIN_ELEMENT element = chain->rgpElement[(chain->cElement - 1) - i];\r\n\r\n                if (!indent.empty())\r\n                {\r\n                    stream << std::endl;\r\n                }\r\n\r\n                stream << indent;\r\n\r\n                stream << GetSimpleDisplayName(element->pCertContext);\r\n\r\n                indent.append(\"  \");\r\n            }\r\n\r\n            return std::move(stream).str();\r\n        }\r\n\r\n        std::optional<PinningVerificationType> GetTypeFromString(std::string_view value)\r\n        {\r\n            std::string lowerValue = Utility::ToLower(value);\r\n\r\n            if (lowerValue == \"none\")\r\n            {\r\n                return PinningVerificationType::None;\r\n            }\r\n            else if (lowerValue == \"publickey\")\r\n            {\r\n                return PinningVerificationType::PublicKey;\r\n            }\r\n            else if (lowerValue == \"subject\")\r\n            {\r\n                return PinningVerificationType::Subject;\r\n            }\r\n            else if (lowerValue == \"issuer\")\r\n            {\r\n                return PinningVerificationType::Issuer;\r\n            }\r\n            else if (lowerValue == \"anyissuer\")\r\n            {\r\n                return PinningVerificationType::AnyIssuer;\r\n            }\r\n            else if (lowerValue == \"requirenonleaf\")\r\n            {\r\n                return PinningVerificationType::RequireNonLeaf;\r\n            }\r\n\r\n            return {};\r\n        }\r\n\r\n        CertificateChainPosition GetCertificateChainPosition(DWORD index, DWORD count)\r\n        {\r\n            THROW_HR_IF(E_INVALIDARG, count == 0);\r\n\r\n            CertificateChainPosition position = CertificateChainPosition::Unknown;\r\n\r\n            if (index == 0)\r\n            {\r\n                position |= CertificateChainPosition::Root;\r\n            }\r\n\r\n            if (index > 0 && index < (count - 1))\r\n            {\r\n                position |= CertificateChainPosition::Intermediate;\r\n            }\r\n\r\n            if (index == (count - 1))\r\n            {\r\n                position |= CertificateChainPosition::Leaf;\r\n            }\r\n\r\n            return position;\r\n        }\r\n    }\r\n\r\n    std::ostream& operator<<(std::ostream& out, PinningVerificationType value)\r\n    {\r\n        if (value == PinningVerificationType::None)\r\n        {\r\n            out << \"None\";\r\n        }\r\n        else\r\n        {\r\n            bool prepend = false;\r\n\r\n            for (const auto& flag : std::initializer_list<std::pair<PinningVerificationType, std::string_view>>{\r\n                { PinningVerificationType::PublicKey, \"PublicKey\" },\r\n                { PinningVerificationType::Subject, \"Subject\" },\r\n                { PinningVerificationType::Issuer, \"Issuer\" },\r\n                { PinningVerificationType::AnyIssuer, \"AnyIssuer\" },\r\n                { PinningVerificationType::RequireNonLeaf, \"RequireNonLeaf\" },\r\n                })\r\n            {\r\n                if (WI_IsAnyFlagSet(value, flag.first))\r\n                {\r\n                    if (prepend)\r\n                    {\r\n                        out << \" | \";\r\n                    }\r\n                    out << flag.second;\r\n                    prepend = true;\r\n                }\r\n            }\r\n        }\r\n\r\n        return out;\r\n    }\r\n\r\n    std::ostream& operator<<(std::ostream& out, CertificateChainPosition value)\r\n    {\r\n        if (value == CertificateChainPosition::Unknown)\r\n        {\r\n            out << \"Unknown\";\r\n        }\r\n        else\r\n        {\r\n            bool prepend = false;\r\n\r\n            for (const auto& flag : std::initializer_list<std::pair<CertificateChainPosition, std::string_view>>{\r\n                { CertificateChainPosition::Root, \"Root\" },\r\n                { CertificateChainPosition::Intermediate, \"Intermediate\" },\r\n                { CertificateChainPosition::Leaf, \"Leaf\" },\r\n                })\r\n            {\r\n                if (WI_IsAnyFlagSet(value, flag.first))\r\n                {\r\n                    if (prepend)\r\n                    {\r\n                        out << \" | \";\r\n                    }\r\n                    out << flag.second;\r\n                    prepend = true;\r\n                }\r\n            }\r\n        }\r\n\r\n        return out;\r\n    }\r\n\r\n    PinningDetails& PinningDetails::LoadCertificate(int resource, int resourceType)\r\n    {\r\n        return LoadCertificate(Resource::GetResourceAsBytes(resource, resourceType));\r\n    }\r\n\r\n    PinningDetails& PinningDetails::LoadCertificate(const std::vector<BYTE>& certificateBytes)\r\n    {\r\n        return LoadCertificate(std::make_pair(&certificateBytes[0], certificateBytes.size()));\r\n    }\r\n\r\n    PinningDetails& PinningDetails::LoadCertificate(const std::pair<const BYTE*, size_t> certificateBytes)\r\n    {\r\n        m_certificateContext.reset(CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, certificateBytes.first, static_cast<DWORD>(certificateBytes.second)));\r\n        THROW_LAST_ERROR_IF(!m_certificateContext);\r\n        return *this;\r\n    }\r\n\r\n    PinningDetails& PinningDetails::SetPinning(PinningVerificationType type)\r\n    {\r\n        m_pinning = type;\r\n        return *this;\r\n    }\r\n\r\n    // The JSON is expected to look like:\r\n    // {\r\n    //     \"Validation\":[\"publickey\"],\r\n    //     \"EmbeddedCertificate\":\"<Hexadecimal string data for certificate>\"\r\n    // }\r\n    bool PinningDetails::LoadFrom(const Json::Value& configuration)\r\n    {\r\n        const std::string validationName = \"Validation\";\r\n\r\n        if (!configuration.isMember(validationName))\r\n        {\r\n            AICLI_LOG(Core, Warning, << \"Details JSON item has no member \" << validationName);\r\n            return false;\r\n        }\r\n\r\n        auto validationValue = JSON::GetValue<std::vector<std::string>>(configuration[validationName]);\r\n        if (!validationValue)\r\n        {\r\n            AICLI_LOG(Core, Warning, << \"Details JSON item member \" << validationName << \" was not an array of strings\");\r\n            return false;\r\n        }\r\n\r\n        for (const std::string& singleValidation : validationValue.value())\r\n        {\r\n            auto validationType = GetTypeFromString(singleValidation);\r\n\r\n            if (!validationType)\r\n            {\r\n                AICLI_LOG(Core, Warning, << \"Details JSON validation is unknown: \" << singleValidation);\r\n                return false;\r\n            }\r\n\r\n            m_pinning |= validationType.value();\r\n        }\r\n\r\n        if (m_pinning == PinningVerificationType::None)\r\n        {\r\n            // No need to load a certificate if not doing any pinning\r\n            return true;\r\n        }\r\n\r\n        const std::string embeddedCertificateName = \"EmbeddedCertificate\";\r\n\r\n        if (!configuration.isMember(embeddedCertificateName))\r\n        {\r\n            AICLI_LOG(Core, Warning, << \"Details JSON item has no member \" << embeddedCertificateName);\r\n            return false;\r\n        }\r\n\r\n        auto embeddedCertificateValue = JSON::GetValue<std::string>(configuration[embeddedCertificateName]);\r\n        if (!validationValue)\r\n        {\r\n            AICLI_LOG(Core, Warning, << \"Details JSON item member \" << embeddedCertificateName << \" was not a string\");\r\n            return false;\r\n        }\r\n\r\n        auto embeddedCertificateBytes = Utility::ParseFromHexString(embeddedCertificateValue.value());\r\n        LoadCertificate(embeddedCertificateBytes);\r\n\r\n        return true;\r\n\r\n    }\r\n\r\n    CertificatePinningValidationResult PinningDetails::Validate(PCCERT_CONTEXT certContext, CertificateChainPosition position) const\r\n    {\r\n        CertificatePinningValidationResult failResult = WI_IsFlagSet(m_pinning, PinningVerificationType::AnyIssuer) ? CertificatePinningValidationResult::Skipped : CertificatePinningValidationResult::Rejected;\r\n\r\n        if (WI_IsFlagSet(m_pinning, PinningVerificationType::RequireNonLeaf) &&\r\n            WI_IsFlagSet(position, CertificateChainPosition::Leaf))\r\n        {\r\n            AICLI_LOG(Core, Verbose, << \"Required non-leaf mismatch: Expected certificate [\" << GetSimpleDisplayName(m_certificateContext.get()) << \"], Actual certificate [\" << GetSimpleDisplayName(certContext) << \"] was \" << position);\r\n            return CertificatePinningValidationResult::Rejected;\r\n        }\r\n\r\n        if (WI_IsFlagSet(m_pinning, PinningVerificationType::PublicKey))\r\n        {\r\n            THROW_HR_IF(E_NOT_VALID_STATE, !m_certificateContext);\r\n\r\n            if (!CertComparePublicKeyInfo(\r\n                X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,\r\n                &m_certificateContext.get()->pCertInfo->SubjectPublicKeyInfo,\r\n                &certContext->pCertInfo->SubjectPublicKeyInfo))\r\n            {\r\n                AICLI_LOG(Core, Verbose, << \"Public key mismatch: Expected certificate [\" << GetSimpleDisplayName(m_certificateContext.get()) << \"], Actual certificate [\" << GetSimpleDisplayName(certContext) << \"]\");\r\n                return failResult;\r\n            }\r\n        }\r\n\r\n        if (WI_IsFlagSet(m_pinning, PinningVerificationType::Subject))\r\n        {\r\n            THROW_HR_IF(E_NOT_VALID_STATE, !m_certificateContext);\r\n\r\n            if (!CertCompareCertificateName(\r\n                X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,\r\n                &m_certificateContext.get()->pCertInfo->Subject,\r\n                &certContext->pCertInfo->Subject))\r\n            {\r\n                AICLI_LOG(Core, Verbose, << \"Subject mismatch: Expected certificate [\" << GetSimpleDisplayName(m_certificateContext.get()) << \"], Actual certificate [\" << GetSimpleDisplayName(certContext) << \"]\");\r\n                return failResult;\r\n            }\r\n        }\r\n\r\n        if (WI_IsFlagSet(m_pinning, PinningVerificationType::Issuer))\r\n        {\r\n            THROW_HR_IF(E_NOT_VALID_STATE, !m_certificateContext);\r\n\r\n            if (!CertCompareCertificateName(\r\n                X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,\r\n                &m_certificateContext.get()->pCertInfo->Issuer,\r\n                &certContext->pCertInfo->Issuer))\r\n            {\r\n                AICLI_LOG(Core, Verbose, << \"Issuer mismatch: Expected certificate [\" << GetSimpleDisplayName(m_certificateContext.get()) << \"], Actual certificate [\" << GetSimpleDisplayName(certContext) << \"]\");\r\n                return failResult;\r\n            }\r\n        }\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        if (m_customValidation)\r\n        {\r\n            if (!m_customValidation(*this, certContext, position))\r\n            {\r\n                AICLI_LOG(Core, Verbose, << \"Custom validation returned false: Expected certificate [\" << GetSimpleDisplayName(m_certificateContext.get()) << \"], Actual certificate [\" << GetSimpleDisplayName(certContext) << \"]\");\r\n                return failResult;\r\n            }\r\n        }\r\n#endif\r\n\r\n        return CertificatePinningValidationResult::Accepted;\r\n    }\r\n\r\n    void PinningDetails::OutputDescription(std::ostream& stream, std::string_view indent) const\r\n    {\r\n        stream << indent << GetSimpleDisplayName(m_certificateContext.get()) << \" : \" << m_pinning;\r\n    }\r\n\r\n    double PinningDetails::GetRemainingLifetimePercentage() const\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !m_certificateContext);\r\n\r\n        auto notBefore = Utility::ConvertFiletimeToSystemClock(m_certificateContext.get()->pCertInfo->NotBefore);\r\n        auto notAfter = Utility::ConvertFiletimeToSystemClock(m_certificateContext.get()->pCertInfo->NotAfter);\r\n        THROW_HR_IF(E_NOT_VALID_STATE, notBefore > notAfter);\r\n\r\n        auto now = std::chrono::system_clock::now();\r\n\r\n        if (now < notBefore)\r\n        {\r\n            return 1.0;\r\n        }\r\n        else if (now > notAfter)\r\n        {\r\n            return 0.0;\r\n        }\r\n\r\n        auto totalTime = notAfter - notBefore;\r\n        auto remainingTime = notAfter - now;\r\n\r\n        return static_cast<double>(remainingTime.count()) / static_cast<double>(totalTime.count());\r\n    }\r\n\r\n    PinningChain::Node PinningChain::Node::Next()\r\n    {\r\n        if (!HasNext())\r\n        {\r\n            m_chain.get().emplace_back();\r\n        }\r\n\r\n        return { m_chain, m_index + 1 };\r\n    }\r\n\r\n    const PinningChain::Node PinningChain::Node::Next() const\r\n    {\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !HasNext());\r\n        return { m_chain, m_index + 1 };\r\n    }\r\n\r\n    void PinningChain::Node::RemoveNext()\r\n    {\r\n        m_chain.get().erase(m_chain.get().begin() + m_index + 1, m_chain.get().end());\r\n    }\r\n\r\n    bool PinningChain::Node::HasNext() const\r\n    {\r\n        return (m_index + 1 < m_chain.get().size());\r\n    }\r\n\r\n    PinningChain::Node::Node(std::vector<PinningDetails>& chain, size_t index) :\r\n        m_chain(chain), m_index(index) {}\r\n\r\n    PinningChain::Node PinningChain::Root()\r\n    {\r\n        if (m_chain.empty())\r\n        {\r\n            m_chain.emplace_back();\r\n        }\r\n\r\n        return { m_chain, 0 };\r\n    }\r\n\r\n    const PinningChain::Node PinningChain::Root() const\r\n    {\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), m_chain.empty());\r\n        return { const_cast<std::vector<PinningDetails>&>(m_chain), 0 };\r\n    }\r\n\r\n    PinningChain& PinningChain::PartialChain(bool isPartial)\r\n    {\r\n        m_partial = isPartial;\r\n        return *this;\r\n    }\r\n\r\n    bool PinningChain::Validate(PCCERT_CHAIN_CONTEXT chainContext) const\r\n    {\r\n        if (m_chain.empty())\r\n        {\r\n            // An empty chain rejects all inputs.\r\n            AICLI_LOG(Core, Warning, << \"Empty pinning chain blindly rejecting chain context\");\r\n            return false;\r\n        }\r\n\r\n        THROW_HR_IF(E_INVALIDARG, chainContext->cChain == 0);\r\n\r\n        // Currently don't support chains bridged with CTLs; there must be only one simple chain that terminates in a trusted root.\r\n        if (chainContext->cChain > 1)\r\n        {\r\n            AICLI_LOG(Core, Verbose, << \"Rejecting chain context with multiple chains\");\r\n            return false;\r\n        }\r\n\r\n        PCCERT_SIMPLE_CHAIN chain = chainContext->rgpChain[0];\r\n\r\n        if (chain->TrustStatus.dwErrorStatus != CERT_TRUST_NO_ERROR)\r\n        {\r\n            AICLI_LOG(Core, Verbose, << \"Rejecting simple chain context with bad TrustStatus: \" << chain->TrustStatus.dwErrorStatus << \" [\" << chain->TrustStatus.dwInfoStatus << \"]\");\r\n            return false;\r\n        }\r\n\r\n        if (chain->pTrustListInfo)\r\n        {\r\n            // This should not happen as the only reason for pTrustListInfo to be set is when `chainContext->cChain > 1`, which is rejected above\r\n            AICLI_LOG(Core, Verbose, << \"Rejecting simple chain context with CTL info\");\r\n            return false;\r\n        }\r\n\r\n        if (!m_partial && static_cast<size_t>(chain->cElement) != m_chain.size())\r\n        {\r\n            AICLI_LOG(Core, Verbose, << \"Rejecting simple chain context based on size: expected \" << m_chain.size() << \", got \" << chain->cElement);\r\n            return false;\r\n        }\r\n\r\n        size_t currentDetailsIndex = 0;\r\n\r\n        for (DWORD i = 0; i < chain->cElement; ++i)\r\n        {\r\n            PCCERT_CHAIN_ELEMENT element = chain->rgpElement[(chain->cElement - 1) - i];\r\n\r\n            if (element->TrustStatus.dwErrorStatus != CERT_TRUST_NO_ERROR)\r\n            {\r\n                AICLI_LOG(Core, Verbose, << \"Rejecting chain element with bad TrustStatus: \" << element->TrustStatus.dwErrorStatus << \" [\" << element->TrustStatus.dwInfoStatus << \"]\");\r\n                return false;\r\n            }\r\n\r\n            CertificatePinningValidationResult result = m_chain[currentDetailsIndex].Validate(element->pCertContext, GetCertificateChainPosition(i, chain->cElement));\r\n\r\n            if (result == CertificatePinningValidationResult::Rejected)\r\n            {\r\n                return false;\r\n            }\r\n            else if (result == CertificatePinningValidationResult::Accepted)\r\n            {\r\n                ++currentDetailsIndex;\r\n            }\r\n            else\r\n            {\r\n                THROW_HR_IF(E_UNEXPECTED, !m_partial || result != CertificatePinningValidationResult::Skipped);\r\n                AICLI_LOG(Core, Verbose, << \"Skipping [\" << GetSimpleDisplayName(element->pCertContext) << \"] in partial chain validation.\");\r\n            }\r\n\r\n            if (m_partial && m_chain.size() == currentDetailsIndex)\r\n            {\r\n                break;\r\n            }\r\n        }\r\n\r\n        // Ensure that all chain elements have been accepted\r\n        return m_chain.size() == currentDetailsIndex;\r\n    }\r\n\r\n    std::string PinningChain::GetDescription() const\r\n    {\r\n        if (m_chain.empty())\r\n        {\r\n            return \"<empty>\";\r\n        }\r\n\r\n        std::ostringstream stream;\r\n        std::string indent;\r\n\r\n        for (const PinningDetails& details : m_chain)\r\n        {\r\n            if (!indent.empty())\r\n            {\r\n                stream << std::endl;\r\n            }\r\n            else if (m_partial)\r\n            {\r\n                stream << \"[Partial Chain Validation]\" << std::endl;\r\n            }\r\n\r\n            details.OutputDescription(stream, indent);\r\n            indent.append(\"  \");\r\n        }\r\n\r\n        return std::move(stream).str();\r\n    }\r\n\r\n    // The JSON is expected to look like:\r\n    // {\r\n    //     \"Chain\":[\r\n    //         { <See PinningDetails::LoadFrom>\r\n    //             \"Validation\":[\"publickey\"],\r\n    //             \"EmbeddedCertificate\":\"<Hexadecimal string data for certificate>\"\r\n    //         },\r\n    //         {\r\n    //             \"Validation\":[\"subject\",\"issuer\"],\r\n    //             \"EmbeddedCertificate\":\"<Hexadecimal string data for certificate>\"\r\n    //         },\r\n    //         ...\r\n    //     ]\r\n    // }\r\n    bool PinningChain::LoadFrom(const Json::Value& configuration)\r\n    {\r\n        const std::string chainName = \"Chain\";\r\n        if (!configuration.isMember(chainName))\r\n        {\r\n            AICLI_LOG(Core, Warning, << \"Chains JSON item has no member \" << chainName);\r\n            return false;\r\n        }\r\n\r\n        const auto& chain = configuration[chainName];\r\n        if (!chain.isArray())\r\n        {\r\n            AICLI_LOG(Core, Warning, << \"Chain JSON input is not an array\");\r\n            return false;\r\n        }\r\n\r\n        for (const auto& configItem : chain)\r\n        {\r\n            PinningDetails details;\r\n            if (!details.LoadFrom(configItem))\r\n            {\r\n                return false;\r\n            }\r\n\r\n            m_chain.emplace_back(std::move(details));\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    double PinningChain::GetRemainingLifetimePercentage() const\r\n    {\r\n        double result = 1.0;\r\n\r\n        for (const auto& details : m_chain)\r\n        {\r\n            result = std::min(result, details.GetRemainingLifetimePercentage());\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    PinningConfiguration::PinningConfiguration(std::string identifier) : m_identifier(identifier)\r\n    {\r\n        if (m_identifier.empty())\r\n        {\r\n            GUID guid;\r\n            LOG_IF_FAILED(CoCreateGuid(&guid));\r\n            wchar_t identifierBuffer[256] = {};\r\n            (void)StringFromGUID2(guid, identifierBuffer, ARRAYSIZE(identifierBuffer));\r\n            m_identifier = Utility::ConvertToUTF8(identifierBuffer);\r\n        }\r\n    }\r\n\r\n    void PinningConfiguration::AddChain(PinningChain chain)\r\n    {\r\n        AICLI_LOG(Core, Verbose, << \"Adding chain to pinning configuration [\" << m_identifier << \"]:\\n\" << chain.GetDescription());\r\n        m_configuration.emplace_back(std::move(chain));\r\n    }\r\n\r\n    bool PinningConfiguration::Validate(PCCERT_CONTEXT certContext) const\r\n    {\r\n        if (m_configuration.empty())\r\n        {\r\n            // No pinning configured\r\n            return true;\r\n        }\r\n\r\n        const BYTE* encodedBegin = certContext->pbCertEncoded;\r\n        const BYTE* encodedEnd = encodedBegin + certContext->cbCertEncoded;\r\n        if (certContext->cbCertEncoded == m_cachedCertificate.size() &&\r\n            std::equal(encodedBegin, encodedEnd, m_cachedCertificate.begin()))\r\n        {\r\n            // We have seen this certificate and deemed it valid already.\r\n            return true;\r\n        }\r\n\r\n        // Get the chain for the given leaf certificate\r\n        wil::unique_cert_chain_context chainContext;\r\n\r\n        char oidPkixKpServerAuth[] = szOID_PKIX_KP_SERVER_AUTH;\r\n        std::array<char*, 1> chainUses = {\r\n            oidPkixKpServerAuth,\r\n        };\r\n\r\n        CERT_CHAIN_PARA chainParameters = {};\r\n        chainParameters.cbSize = sizeof(chainParameters);\r\n        chainParameters.RequestedUsage.dwType = USAGE_MATCH_TYPE_OR;\r\n        chainParameters.RequestedUsage.Usage.cUsageIdentifier = static_cast<DWORD>(chainUses.size());\r\n        chainParameters.RequestedUsage.Usage.rgpszUsageIdentifier = chainUses.data();\r\n\r\n        THROW_IF_WIN32_BOOL_FALSE(CertGetCertificateChain(nullptr, certContext, nullptr, certContext->hCertStore, &chainParameters, CERT_CHAIN_REVOCATION_CHECK_CHAIN, nullptr, &chainContext));\r\n\r\n        bool result = false;\r\n\r\n        for (const auto& chain : m_configuration)\r\n        {\r\n            if (chain.Validate(chainContext.get()))\r\n            {\r\n                AICLI_LOG(Core, Verbose, << \"Certificate `\" << GetSimpleDisplayName(certContext) << \"` accepted by pinning configuration:\\n\" << chain.GetDescription());\r\n                result = true;\r\n                break;\r\n            }\r\n        }\r\n\r\n        if (result)\r\n        {\r\n            // Only cache a successful validation\r\n            m_cachedCertificate.assign(encodedBegin, encodedEnd);\r\n        }\r\n        else\r\n        {\r\n            AICLI_LOG(Core, Error, << \"Rejecting certificate [\" << GetSimpleDisplayName(certContext) << \"] as it did not match anything in pinning configuration [\" << m_identifier << \"]:\\n\" << GetDescriptionOfCertChain(chainContext.get()));\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    // The JSON is expected to look like:\r\n    // {\r\n    //  \"Chains\":[\r\n    //      { <See PinningChain::LoadFrom>\r\n    //          \"Chain\":[\r\n    //              { <See PinningDetails::LoadFrom>\r\n    //                  \"Validation\":[\"publickey\"],\r\n    //                  \"EmbeddedCertificate\":\"<Hexadecimal string data for certificate>\"\r\n    //              },\r\n    //              {\r\n    //                  \"Validation\":[\"subject\",\"issuer\"],\r\n    //                  \"EmbeddedCertificate\":\"<Hexadecimal string data for certificate>\"\r\n    //              },\r\n    //              ...\r\n    //          ]\r\n    //      }\r\n    //  ]\r\n    // }\r\n    bool PinningConfiguration::LoadFrom(const Json::Value& configuration)\r\n    {\r\n        const std::string chainsName = \"Chains\";\r\n        if (!configuration.isMember(chainsName))\r\n        {\r\n            AICLI_LOG(Core, Warning, << \"PinningConfiguration JSON item has no member \" << chainsName);\r\n            return false;\r\n        }\r\n        const auto& chains = configuration[chainsName];\r\n\r\n        if (!chains.isArray())\r\n        {\r\n            AICLI_LOG(Core, Warning, << \"PinningConfiguration.Chains is not an array\");\r\n            return false;\r\n        }\r\n\r\n        std::vector<PinningChain> resultCache;\r\n\r\n        for (const auto& configItem : chains)\r\n        {\r\n            PinningChain chain;\r\n            if (!chain.LoadFrom(configItem))\r\n            {\r\n                return false;\r\n            }\r\n\r\n            resultCache.emplace_back(std::move(chain));\r\n        }\r\n\r\n        // Move all chains into the config now that we have succeeded\r\n        for (auto& result : resultCache)\r\n        {\r\n            AddChain(std::move(result));\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    double PinningConfiguration::GetRemainingLifetimePercentage() const\r\n    {\r\n        double result = 0.0;\r\n\r\n        for (const auto& chain : m_configuration)\r\n        {\r\n            result = std::max(result, chain.GetRemainingLifetimePercentage());\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Compression.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/Compression.h\"\r\n\r\nnamespace AppInstaller::Compression\r\n{\r\n    Compressor::Compressor(DWORD algorithm)\r\n    {\r\n        THROW_IF_WIN32_BOOL_FALSE(CreateCompressor(algorithm, nullptr, &m_compressor));\r\n    }\r\n\r\n    std::vector<uint8_t> Compressor::Compress(std::string_view data)\r\n    {\r\n        std::vector<uint8_t> result;\r\n\r\n        if (!data.empty())\r\n        {\r\n            SIZE_T compressedBufferSize = 0;\r\n            THROW_HR_IF(E_UNEXPECTED, ::Compress(m_compressor.get(), data.data(), data.size(), nullptr, 0, &compressedBufferSize));\r\n            THROW_LAST_ERROR_IF(GetLastError() != ERROR_INSUFFICIENT_BUFFER);\r\n\r\n            result.resize(compressedBufferSize);\r\n\r\n            SIZE_T compressedDataSize = 0;\r\n            THROW_IF_WIN32_BOOL_FALSE(::Compress(m_compressor.get(), data.data(), data.size(), &result[0], result.size(), &compressedDataSize));\r\n\r\n            result.resize(compressedDataSize);\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    void Compressor::Reset()\r\n    {\r\n        THROW_IF_WIN32_BOOL_FALSE(ResetCompressor(m_compressor.get()));\r\n    }\r\n\r\n    void Compressor::SetInformation(COMPRESS_INFORMATION_CLASS information, DWORD value)\r\n    {\r\n        THROW_IF_WIN32_BOOL_FALSE(SetCompressorInformation(m_compressor.get(), information, &value, sizeof(value)));\r\n    }\r\n\r\n    DWORD Compressor::GetInformation(COMPRESS_INFORMATION_CLASS information)\r\n    {\r\n        DWORD result = 0;\r\n        THROW_IF_WIN32_BOOL_FALSE(QueryCompressorInformation(m_compressor.get(), information, &result, sizeof(result)));\r\n        return result;\r\n    }\r\n\r\n    Decompressor::Decompressor(DWORD algorithm)\r\n    {\r\n        THROW_IF_WIN32_BOOL_FALSE(CreateDecompressor(algorithm, nullptr, &m_decompressor));\r\n    }\r\n\r\n    std::vector<uint8_t> Decompressor::Decompress(const std::vector<uint8_t>& data)\r\n    {\r\n        std::vector<uint8_t> result;\r\n\r\n        if (!data.empty())\r\n        {\r\n            SIZE_T decompressedBufferSize = 0;\r\n            THROW_HR_IF(E_UNEXPECTED, ::Decompress(m_decompressor.get(), data.data(), data.size(), nullptr, 0, &decompressedBufferSize));\r\n            THROW_LAST_ERROR_IF(GetLastError() != ERROR_INSUFFICIENT_BUFFER);\r\n\r\n            result.resize(decompressedBufferSize);\r\n\r\n            SIZE_T decompressedDataSize = 0;\r\n            THROW_IF_WIN32_BOOL_FALSE(::Decompress(m_decompressor.get(), data.data(), data.size(), &result[0], result.size(), &decompressedDataSize));\r\n\r\n            result.resize(decompressedDataSize);\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    void Decompressor::Reset()\r\n    {\r\n        THROW_IF_WIN32_BOOL_FALSE(ResetDecompressor(m_decompressor.get()));\r\n    }\r\n\r\n    void Decompressor::SetInformation(COMPRESS_INFORMATION_CLASS information, DWORD value)\r\n    {\r\n        THROW_IF_WIN32_BOOL_FALSE(SetDecompressorInformation(m_decompressor.get(), information, &value, sizeof(value)));\r\n    }\r\n\r\n    DWORD Decompressor::GetInformation(COMPRESS_INFORMATION_CLASS information)\r\n    {\r\n        DWORD result = 0;\r\n        THROW_IF_WIN32_BOOL_FALSE(QueryDecompressorInformation(m_decompressor.get(), information, &result, sizeof(result)));\r\n        return result;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/DateTime.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/AppInstallerDateTime.h\"\r\n\r\nusing namespace std::chrono;\r\n\r\nnamespace AppInstaller::Utility\r\n{\r\n    namespace\r\n    {\r\n        struct OutputTimePointContext\r\n        {\r\n            OutputTimePointContext(std::ostream& stream, const std::chrono::system_clock::time_point& time, TimeFacet facet) :\r\n                Stream(stream), Time(time), Facet(facet)\r\n            {\r\n                auto tt = system_clock::to_time_t(time);\r\n                _localtime64_s(&LocalTime, &tt);\r\n            }\r\n\r\n            std::ostream& Stream;\r\n            const std::chrono::system_clock::time_point& Time;\r\n            tm LocalTime{};\r\n            TimeFacet Facet;\r\n        };\r\n\r\n        struct OutputTimePointFacetInfo\r\n        {\r\n            TimeFacet Facet;\r\n            char FollowingSeparator;\r\n            void (*Action)(const OutputTimePointContext&);\r\n        };\r\n    }\r\n\r\n    void OutputTimePoint(std::ostream& stream, const std::chrono::system_clock::time_point& time, bool useRFC3339)\r\n    {\r\n        OutputTimePoint(stream, time, TimeFacet::Default | (useRFC3339 ? TimeFacet::RFC3339 : TimeFacet::None));\r\n    }\r\n\r\n    // If moved to C++20, this can be replaced with standard library implementations.\r\n    void OutputTimePoint(std::ostream& stream, const std::chrono::system_clock::time_point& time, TimeFacet facet)\r\n    {\r\n        OutputTimePointContext context{ stream, time, facet };\r\n        using Ctx = const OutputTimePointContext&;\r\n\r\n        bool useRFC3339 = WI_IsFlagSet(facet, TimeFacet::RFC3339);\r\n        bool filename = WI_IsFlagSet(facet, TimeFacet::Filename);\r\n        char day_time_separator = useRFC3339 ? 'T' : (filename ? '-' : ' ');\r\n        char time_field_separator = filename ? '-' : ':';\r\n\r\n        bool needsSeparator = false;\r\n        char currentSeparator = '-';\r\n\r\n        for (const auto& info : {\r\n            OutputTimePointFacetInfo{ TimeFacet::ShortYear, '-', [](Ctx ctx) { ctx.Stream << (ctx.LocalTime.tm_year - 100); }},\r\n            OutputTimePointFacetInfo{ TimeFacet::Year, '-', [](Ctx ctx) { ctx.Stream << (1900 + ctx.LocalTime.tm_year); }},\r\n            OutputTimePointFacetInfo{ TimeFacet::Month, '-', [](Ctx ctx) { ctx.Stream << std::setw(2) << std::setfill('0') << (1 + ctx.LocalTime.tm_mon); }},\r\n            OutputTimePointFacetInfo{ TimeFacet::Day, day_time_separator, [](Ctx ctx) { ctx.Stream << std::setw(2) << std::setfill('0') << ctx.LocalTime.tm_mday; }},\r\n            OutputTimePointFacetInfo{ TimeFacet::Hour, time_field_separator, [](Ctx ctx) { ctx.Stream << std::setw(2) << std::setfill('0') << ctx.LocalTime.tm_hour; }},\r\n            OutputTimePointFacetInfo{ TimeFacet::Minute, time_field_separator, [](Ctx ctx) { ctx.Stream << std::setw(2) << std::setfill('0') << ctx.LocalTime.tm_min; }},\r\n            OutputTimePointFacetInfo{ TimeFacet::Second, '.', [](Ctx ctx) { ctx.Stream << std::setw(2) << std::setfill('0') << ctx.LocalTime.tm_sec; }},\r\n            OutputTimePointFacetInfo{ TimeFacet::Millisecond, '-', [](Ctx ctx)\r\n            {\r\n                // Get partial seconds\r\n                auto sinceEpoch = ctx.Time.time_since_epoch();\r\n                auto leftoverMillis = duration_cast<milliseconds>(sinceEpoch) - duration_cast<seconds>(sinceEpoch);\r\n\r\n                ctx.Stream << std::setw(3) << std::setfill('0') << leftoverMillis.count();\r\n            }},\r\n            OutputTimePointFacetInfo{ TimeFacet::RFC3339, '\\0', [](Ctx ctx)\r\n            {\r\n                // RFC 3339 requires adding time zone info.\r\n                // No need to bother getting the actual time zone as we don't need it.\r\n                // -00:00 represents an unspecified time zone, not UTC.\r\n                ctx.Stream << \"00:00\";\r\n            }},\r\n            })\r\n        {\r\n            if (WI_AreAllFlagsSet(facet, info.Facet))\r\n            {\r\n                if (needsSeparator)\r\n                {\r\n                    stream << currentSeparator;\r\n                }\r\n\r\n                info.Action(context);\r\n                needsSeparator = true;\r\n            }\r\n\r\n            // Getting this right for every mix of facets is probably not possible.\r\n            // Future needs can dictate changes here.\r\n            currentSeparator = info.FollowingSeparator;\r\n        }\r\n    }\r\n\r\n    std::string TimePointToString(const std::chrono::system_clock::time_point& time, bool useRFC3339)\r\n    {\r\n        std::ostringstream stream;\r\n        OutputTimePoint(stream, time, useRFC3339);\r\n        return std::move(stream).str();\r\n    }\r\n\r\n    std::string TimePointToString(const std::chrono::system_clock::time_point& time, TimeFacet facet)\r\n    {\r\n        std::ostringstream stream;\r\n        OutputTimePoint(stream, time, facet);\r\n        return std::move(stream).str();\r\n    }\r\n\r\n    std::string GetCurrentTimeForFilename(bool shortTime)\r\n    {\r\n        return TimePointToString(std::chrono::system_clock::now(), (shortTime ? TimeFacet::ShortYearSecondPrecision : TimeFacet::Default) | TimeFacet::Filename);\r\n    }\r\n\r\n    std::string GetCurrentDateForARP()\r\n    {\r\n        auto now = std::chrono::system_clock::now();\r\n        std::time_t tt = std::chrono::system_clock::to_time_t(now);\r\n\r\n        struct tm newTime;\r\n        localtime_s(&newTime, &tt);\r\n\r\n        std::stringstream ss;\r\n        ss << std::put_time(&newTime, \"%Y%m%d\");\r\n        return ss.str();\r\n    }\r\n\r\n    int64_t GetCurrentUnixEpoch()\r\n    {\r\n        static_assert(std::is_same_v<int64_t, decltype(time(nullptr))>, \"time returns a 64-bit integer\");\r\n        time_t now = time(nullptr);\r\n        return static_cast<int64_t>(now);\r\n    }\r\n\r\n    int64_t ConvertSystemClockToUnixEpoch(const std::chrono::system_clock::time_point& time)\r\n    {\r\n        static_assert(std::is_same_v<int64_t, decltype(std::chrono::system_clock::to_time_t(time))>, \"to_time_t returns a 64-bit integer\");\r\n        time_t timeAsTimeT = std::chrono::system_clock::to_time_t(time);\r\n        return static_cast<int64_t>(timeAsTimeT);\r\n    }\r\n\r\n    std::chrono::system_clock::time_point ConvertUnixEpochToSystemClock(int64_t epoch)\r\n    {\r\n        return std::chrono::system_clock::from_time_t(static_cast<time_t>(epoch));\r\n    }\r\n\r\n    std::chrono::system_clock::time_point ConvertFiletimeToSystemClock(const FILETIME& fileTime)\r\n    {\r\n        return winrt::clock::to_sys(winrt::clock::from_FILETIME(fileTime));\r\n    }\r\n\r\n    std::chrono::system_clock::time_point GetTimePointFromVersion(const UInt64Version& version)\r\n    {\r\n        // Our custom format for converting UTC into a version is:\r\n        //  Major :: `Year` [1, 9999]\r\n        //  Minor :: `Month * 100 + Day` where Month [1, 12] and Day [1, 31]\r\n        //  Build :: `Hour * 100 + Minute` where Hour [1, 24] and Minute [0, 59]\r\n        //  Revision :: Milliseconds, but since no seconds are available we will disregard this\r\n\r\n        tm versionTime{};\r\n\r\n        // Limit to the range supported by _mkgmtime64, which is 1970 to 3000 (hello to Y3K maintainers from 2023!)\r\n        UINT64 majorVersion = version.Major();\r\n        if (majorVersion < 1970 || majorVersion > 3000)\r\n        {\r\n            return std::chrono::system_clock::time_point::min();\r\n        }\r\n        versionTime.tm_year = static_cast<int>(majorVersion) - 1900;\r\n\r\n        UINT64 minorVersion = version.Minor();\r\n        UINT64 monthValue = minorVersion / 100;\r\n        UINT64 dayValue = minorVersion % 100;\r\n        if (monthValue < 1 || monthValue > 12 || dayValue < 1 || dayValue > 31)\r\n        {\r\n            return std::chrono::system_clock::time_point::min();\r\n        }\r\n        versionTime.tm_mon = static_cast<int>(monthValue) - 1;\r\n        versionTime.tm_mday = static_cast<int>(dayValue);\r\n\r\n        UINT64 buildVersion = version.Build();\r\n        UINT64 hourValue = buildVersion / 100;\r\n        UINT64 minuteValue = buildVersion % 100;\r\n        if (hourValue < 1 || hourValue > 24 || minuteValue > 59)\r\n        {\r\n            return std::chrono::system_clock::time_point::min();\r\n        }\r\n        versionTime.tm_hour = static_cast<int>(hourValue) - 1;\r\n        versionTime.tm_min = static_cast<int>(minuteValue);\r\n\r\n        return std::chrono::system_clock::from_time_t(_mkgmtime64(&versionTime));\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Errors.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/AppInstallerErrors.h\"\r\n#include \"Public/AppInstallerLogging.h\"\r\n#include \"Public/AppInstallerStrings.h\"\r\n#include \"Public/winget/Resources.h\"\r\n\r\n\r\nnamespace AppInstaller\r\n{\r\n    namespace\r\n    {\r\n        // A simple struct to hold the data\r\n        struct HResultData\r\n        {\r\n            HRESULT Value;\r\n            std::string_view Symbol;\r\n            std::string_view Description;\r\n\r\n            bool operator<(const HResultData& other) const\r\n            {\r\n                return Value < other.Value;\r\n            }\r\n        };\r\n\r\n        // HRESULT information for our errors\r\n        struct WinGetHResultInformation : public Errors::HResultInformation\r\n        {\r\n            constexpr WinGetHResultInformation(HRESULT value, std::string_view symbol, std::string_view unlocalizedDescription) :\r\n                Errors::HResultInformation(value, symbol), m_unlocalizedDescription(unlocalizedDescription)\r\n            {}\r\n\r\n            constexpr WinGetHResultInformation(const HResultData& data) :\r\n                Errors::HResultInformation(data.Value, data.Symbol), m_unlocalizedDescription(data.Description)\r\n            {}\r\n\r\n            Utility::LocIndString GetDescription() const override\r\n            {\r\n                auto localizedDescription = StringResource::TryResolveString(Utility::ConvertToUTF16(Symbol()));\r\n                return localizedDescription ?\r\n                    std::move(localizedDescription).value() :\r\n                    Utility::LocIndString{ m_unlocalizedDescription };\r\n            }\r\n\r\n        private:\r\n            std::string_view m_unlocalizedDescription;\r\n        };\r\n\r\n        // HRESULT information for our errors, with the unlocalized description only.\r\n        struct WinGetHResultInformationUnlocalized : public Errors::HResultInformation\r\n        {\r\n            constexpr WinGetHResultInformationUnlocalized(HRESULT value, std::string_view symbol, std::string_view unlocalizedDescription) :\r\n                Errors::HResultInformation(value, symbol), m_unlocalizedDescription(unlocalizedDescription)\r\n            {}\r\n\r\n            constexpr WinGetHResultInformationUnlocalized(const HResultData& data) :\r\n                Errors::HResultInformation(data.Value, data.Symbol), m_unlocalizedDescription(data.Description)\r\n            {}\r\n\r\n            Utility::LocIndString GetDescription() const override\r\n            {\r\n                return Utility::LocIndString{ m_unlocalizedDescription };\r\n            }\r\n\r\n        private:\r\n            std::string_view m_unlocalizedDescription;\r\n        };\r\n\r\n        // The information entry for an HRESULT not in the list (someone probably forgot to add an entry)\r\n        struct UnknownHResultInformation : public Errors::HResultInformation\r\n        {\r\n            constexpr UnknownHResultInformation(HRESULT value) :\r\n                Errors::HResultInformation(value)\r\n            {}\r\n\r\n            Utility::LocIndString GetDescription() const override\r\n            {\r\n                auto localizedDescription = StringResource::TryResolveString(StringResource::String::UnknownErrorCode);\r\n                return localizedDescription ?\r\n                    std::move(localizedDescription).value() :\r\n                    Utility::LocIndString{ \"Unknown error code\"sv };\r\n            }\r\n        };\r\n\r\n#define WINGET_HRESULT_INFO(_name_,_description_) HResultData{ _name_, #_name_, _description_ }\r\n\r\n        constexpr const HResultData s_wingetHResultData[] =\r\n        {\r\n            // Changes to any of these errors require the corresponding resource string in winget.resw to be updated.\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INTERNAL_ERROR, \"Internal Error\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS, \"Invalid command line arguments\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_COMMAND_FAILED, \"Executing command failed\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_MANIFEST_FAILED, \"Opening manifest failed\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_CTRL_SIGNAL_RECEIVED, \"Cancellation signal received\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SHELLEXEC_INSTALL_FAILED, \"Running ShellExecute failed\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_UNSUPPORTED_MANIFESTVERSION, \"Cannot process manifest. The manifest version is higher than supported. Please update the client.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_DOWNLOAD_FAILED, \"Downloading installer failed\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX, \"Cannot write to index; it is a higher schema version\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INDEX_INTEGRITY_COMPROMISED, \"The index is corrupt\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SOURCES_INVALID, \"The configured source information is corrupt\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SOURCE_NAME_ALREADY_EXISTS, \"The source name is already configured\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INVALID_SOURCE_TYPE, \"The source type is invalid\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PACKAGE_IS_BUNDLE, \"The MSIX file is a bundle, not a package\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SOURCE_DATA_MISSING, \"Data required by the source is missing\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER, \"None of the installers are applicable for the current system\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALLER_HASH_MISMATCH, \"The installer file's hash does not match the manifest\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SOURCE_NAME_DOES_NOT_EXIST, \"The source name does not exist\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SOURCE_ARG_ALREADY_EXISTS, \"The source location is already configured under another name\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_NO_APPLICATIONS_FOUND, \"No packages found\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_NO_SOURCES_DEFINED, \"No sources are configured\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_MULTIPLE_APPLICATIONS_FOUND, \"Multiple packages found matching the criteria\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_NO_MANIFEST_FOUND, \"No manifest found matching the criteria\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_EXTENSION_PUBLIC_FAILED, \"Failed to get Public folder from source package\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_COMMAND_REQUIRES_ADMIN, \"Command requires administrator privileges to run\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SOURCE_NOT_SECURE, \"The source location is not secure\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_MSSTORE_BLOCKED_BY_POLICY, \"The Microsoft Store client is blocked by policy\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_MSSTORE_APP_BLOCKED_BY_POLICY, \"The Microsoft Store app is blocked by policy\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_EXPERIMENTAL_FEATURE_DISABLED, \"The feature is currently under development. It can be enabled using winget settings.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_MSSTORE_INSTALL_FAILED, \"Failed to install the Microsoft Store app\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_COMPLETE_INPUT_BAD, \"Failed to perform auto complete\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED, \"Failed to initialize YAML parser\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_YAML_INVALID_MAPPING_KEY, \"Encountered an invalid YAML key\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY, \"Encountered a duplicate YAML key\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_YAML_INVALID_OPERATION, \"Invalid YAML operation\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_YAML_DOC_BUILD_FAILED, \"Failed to build YAML doc\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_YAML_INVALID_EMITTER_STATE, \"Invalid YAML emitter state\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_YAML_INVALID_DATA, \"Invalid YAML data\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_LIBYAML_ERROR, \"LibYAML error\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_WARNING, \"Manifest validation succeeded with warning\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_FAILURE, \"Manifest validation failed\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INVALID_MANIFEST, \"Manifest is invalid\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE, \"No applicable update found\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_UPDATE_ALL_HAS_FAILURE, \"winget upgrade --all completed with failures\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALLER_SECURITY_CHECK_FAILED, \"Installer failed security check\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_DOWNLOAD_SIZE_MISMATCH, \"Download size does not match expected content length\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_NO_UNINSTALL_INFO_FOUND, \"Uninstall command not found\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_EXEC_UNINSTALL_COMMAND_FAILED, \"Running uninstall command failed\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_ICU_BREAK_ITERATOR_ERROR, \"ICU break iterator error\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_ICU_CASEMAP_ERROR, \"ICU casemap error\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_ICU_REGEX_ERROR, \"ICU regex error\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_IMPORT_INSTALL_FAILED, \"Failed to install one or more imported packages\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_NOT_ALL_PACKAGES_FOUND, \"Could not find one or more requested packages\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE, \"Json file is invalid\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SOURCE_NOT_REMOTE, \"The source location is not remote\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE, \"The configured rest source is not supported\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA, \"Invalid data returned by rest source\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY, \"Operation is blocked by Group Policy\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_RESTAPI_INTERNAL_ERROR, \"Rest API internal error\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_URL, \"Invalid rest source url\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_RESTAPI_UNSUPPORTED_MIME_TYPE, \"Unsupported MIME type returned by rest API\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_VERSION, \"Invalid rest source contract version\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE, \"The source data is corrupted or tampered\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_STREAM_READ_FAILURE, \"Error reading from the stream\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED, \"Package agreements were not agreed to\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PROMPT_INPUT_ERROR, \"Error reading input in prompt\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST, \"The search request is not supported by one or more sources\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_RESTAPI_ENDPOINT_NOT_FOUND, \"The rest API endpoint is not found.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SOURCE_OPEN_FAILED, \"Failed to open the source.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED, \"Source agreements were not agreed to\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_CUSTOMHEADER_EXCEEDS_MAXLENGTH, \"Header size exceeds the allowable limit of 1024 characters. Please reduce the size and try again.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_MISSING_RESOURCE_FILE, \"Missing resource file\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_MSI_INSTALL_FAILED, \"Running MSI install failed\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT, \"Arguments for msiexec are invalid\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_FAILED_TO_OPEN_ALL_SOURCES, \"Failed to open one or more sources\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED, \"Failed to validate dependencies\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_MISSING_PACKAGE, \"One or more package is missing\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INVALID_TABLE_COLUMN, \"Invalid table column\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_NOT_NEWER, \"The upgrade version is not newer than the installed version\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_UNKNOWN, \"Upgrade version is unknown and override is not specified\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_ICU_CONVERSION_ERROR, \"ICU conversion error\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PORTABLE_INSTALL_FAILED, \"Failed to install portable package\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PORTABLE_REPARSE_POINT_NOT_SUPPORTED, \"Volume does not support reparse points\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PORTABLE_PACKAGE_ALREADY_EXISTS, \"Portable package from a different source already exists.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PORTABLE_SYMLINK_PATH_IS_DIRECTORY, \"Unable to create symlink, path points to a directory.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALLER_PROHIBITS_ELEVATION, \"The installer cannot be run from an administrator context.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PORTABLE_UNINSTALL_FAILED, \"Failed to uninstall portable package\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_ARP_VERSION_VALIDATION_FAILED, \"Failed to validate DisplayVersion values against index.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_UNSUPPORTED_ARGUMENT, \"One or more arguments are not supported.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_BIND_WITH_EMBEDDED_NULL, \"Embedded null characters are disallowed for SQLite\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_NOT_FOUND, \"Failed to find the nested installer in the archive.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_EXTRACT_ARCHIVE_FAILED, \"Failed to extract archive.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_INVALID_PATH, \"Invalid relative file path to nested installer provided.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PINNED_CERTIFICATE_MISMATCH, \"The server certificate did not match any of the expected values.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_LOCATION_REQUIRED, \"Install location must be provided.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_ARCHIVE_SCAN_FAILED, \"Archive malware scan failed.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PACKAGE_ALREADY_INSTALLED, \"Found at least one version of the package installed.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PIN_ALREADY_EXISTS, \"A pin already exists for the package.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PIN_DOES_NOT_EXIST, \"There is no pin for the package.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_CANNOT_OPEN_PINNING_INDEX, \"Unable to open the pin database.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_MULTIPLE_INSTALL_FAILED, \"One or more applications failed to install\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_MULTIPLE_UNINSTALL_FAILED, \"One or more applications failed to uninstall\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_NOT_ALL_QUERIES_FOUND_SINGLE, \"One or more queries did not return exactly one match\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PACKAGE_IS_PINNED, \"The package has a pin that prevents upgrade.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB, \"The package currently installed is the stub package\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_APPTERMINATION_RECEIVED, \"Application shutdown signal received\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_DOWNLOAD_DEPENDENCIES, \"Failed to download package dependencies.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_DOWNLOAD_COMMAND_PROHIBITED, \"Failed to download package. Download for offline installation is prohibited.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SERVICE_UNAVAILABLE, \"A required service is busy or unavailable. Try again later.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_RESUME_ID_NOT_FOUND, \"The guid provided does not correspond to a valid resume state.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_CLIENT_VERSION_MISMATCH, \"The current client version did not match the client version of the saved state.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INVALID_RESUME_STATE, \"The resume state data is invalid.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_CANNOT_OPEN_CHECKPOINT_INDEX, \"Unable to open the checkpoint database.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_RESUME_LIMIT_EXCEEDED, \"Exceeded max resume limit.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INVALID_AUTHENTICATION_INFO, \"Invalid authentication info.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED, \"Authentication method not supported.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED, \"Authentication failed.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_AUTHENTICATION_INTERACTIVE_REQUIRED, \"Authentication failed. Interactive authentication required.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_AUTHENTICATION_CANCELLED_BY_USER, \"Authentication failed. User cancelled.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_AUTHENTICATION_INCORRECT_ACCOUNT, \"Authentication failed. Authenticated account is not the desired account.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_NO_REPAIR_INFO_FOUND, \"Repair command not found.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_REPAIR_NOT_APPLICABLE, \"Repair operation is not applicable.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_EXEC_REPAIR_FAILED, \"Repair operation failed.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_REPAIR_NOT_SUPPORTED, \"The installer technology in use doesn't support repair.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED, \"Repair operations involving administrator privileges are not permitted on packages installed within the user scope.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SQLITE_CONNECTION_TERMINATED, \"The SQLite connection was terminated to prevent corruption.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_DISPLAYCATALOG_API_FAILED, \"Failed to get Microsoft Store package catalog.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_NO_APPLICABLE_DISPLAYCATALOG_PACKAGE, \"No applicable Microsoft Store package found from Microsoft Store package catalog.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SFSCLIENT_API_FAILED, \"Failed to get Microsoft Store package download information.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_NO_APPLICABLE_SFSCLIENT_PACKAGE, \"No applicable Microsoft Store package download information found.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED, \"Failed to retrieve Microsoft Store package license.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SFSCLIENT_PACKAGE_NOT_SUPPORTED, \"The Microsoft Store package does not support download.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED_FORBIDDEN, \"Failed to retrieve Microsoft Store package license. The Microsoft Entra Id account does not have the required privilege.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALLER_ZERO_BYTE_FILE, \"Downloaded zero byte installer; ensure that your network connection is working properly.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_FONT_INSTALL_FAILED, \"Failed installing one or more fonts.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_SUPPORTED, \"Font file is not supported and cannot be installed.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_FONT_ALREADY_INSTALLED, \"Font package is already installed.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_FOUND, \"Font file not found.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_FONT_UNINSTALL_FAILED, \"Font uninstall failed. The font may not be in a good state. Try uninstalling after a restart.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_FONT_VALIDATION_FAILED, \"Font validation failed.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_FONT_ROLLBACK_FAILED, \"Font rollback failed. The font may not be in a good state. Try uninstalling after a restart.\"),\r\n\r\n            // Install errors.\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE, \"Application is currently running. Exit the application then try again.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_INSTALL_IN_PROGRESS, \"Another installation is already in progress. Try again later.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_FILE_IN_USE, \"One or more file is being used. Exit the application then try again.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_MISSING_DEPENDENCY, \"This package has a dependency missing from your system.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_DISK_FULL, \"There's no more space on your PC. Make space, then try again.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_INSUFFICIENT_MEMORY, \"There's not enough memory available to install. Close other applications then try again.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_NO_NETWORK, \"This application requires internet connectivity. Connect to a network then try again.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_CONTACT_SUPPORT, \"This application encountered an error during installation. Contact support.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_TO_FINISH, \"Restart your PC to finish installation.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_FOR_INSTALL, \"Installation failed. Restart your PC then try again.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_INITIATED, \"Your PC will restart to finish installation.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_CANCELLED_BY_USER, \"You cancelled the installation.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_ALREADY_INSTALLED, \"Another version of this application is already installed.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_DOWNGRADE, \"A higher version of this application is already installed.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_BLOCKED_BY_POLICY, \"Organization policies are preventing installation. Contact your admin.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_DEPENDENCIES, \"Failed to install package dependencies.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE_BY_APPLICATION, \"Application is currently in use by another application.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_INVALID_PARAMETER, \"Invalid parameter.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED, \"Package not supported by the system.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_UPGRADE_NOT_SUPPORTED, \"The installer does not support upgrading an existing package.\"),\r\n            WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_CUSTOM_ERROR, \"Installation failed with a custom installer error.\"),\r\n\r\n            // Status values for check package installed status results.\r\n            // Partial success has the success bit(first bit) set to 0.\r\n            WINGET_HRESULT_INFO(WINGET_INSTALLED_STATUS_ARP_ENTRY_NOT_FOUND, \"The Apps and Features Entry for the package could not be found.\"),\r\n            WINGET_HRESULT_INFO(WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_FOUND, \"The install location could not be found.\"),\r\n            WINGET_HRESULT_INFO(WINGET_INSTALLED_STATUS_FILE_HASH_MISMATCH, \"The hash of the existing file did not match.\"),\r\n            WINGET_HRESULT_INFO(WINGET_INSTALLED_STATUS_FILE_NOT_FOUND, \"File not found.\"),\r\n            WINGET_HRESULT_INFO(WINGET_INSTALLED_STATUS_FILE_ACCESS_ERROR, \"The file could not be accessed.\"),\r\n\r\n            // Configuration Errors\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE, \"The configuration file is invalid.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_INVALID_YAML, \"The YAML syntax is invalid.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_INVALID_FIELD_TYPE, \"A configuration field has an invalid type.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION, \"The configuration has an unknown version.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_SET_APPLY_FAILED, \"An error occurred while applying the configuration.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER, \"The configuration contains a duplicate identifier.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_MISSING_DEPENDENCY, \"The configuration is missing a dependency.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED, \"The configuration has an unsatisfied dependency.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_ASSERTION_FAILED, \"An assertion for the configuration unit failed.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_MANUALLY_SKIPPED, \"The configuration was manually skipped.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_WARNING_NOT_ACCEPTED, \"The user declined to continue execution.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_SET_DEPENDENCY_CYCLE, \"The dependency graph contains a cycle which cannot be resolved.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_INVALID_FIELD_VALUE, \"The configuration has an invalid field value.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_MISSING_FIELD, \"The configuration is missing a field.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_TEST_FAILED, \"Some of the configuration units failed while testing their state.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_TEST_NOT_RUN, \"Configuration state was not tested.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_GET_FAILED, \"The configuration unit failed getting its properties.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_HISTORY_ITEM_NOT_FOUND, \"The specified configuration could not be found.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_PARAMETER_INTEGRITY_BOUNDARY, \"Parameter cannot be passed across integrity boundary.\"),\r\n\r\n            // Configuration Processor Errors\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNIT_NOT_INSTALLED, \"The configuration unit was not installed.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNIT_NOT_FOUND_REPOSITORY, \"The configuration unit could not be found.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNIT_MULTIPLE_MATCHES, \"Multiple matches were found for the configuration unit; specify the module to select the correct one.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNIT_INVOKE_GET, \"The configuration unit failed while attempting to get the current system state.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNIT_INVOKE_TEST, \"The configuration unit failed while attempting to test the current system state.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNIT_INVOKE_SET, \"The configuration unit failed while attempting to apply the desired state.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNIT_MODULE_CONFLICT, \"The module for the configuration unit is available in multiple locations with the same version.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE, \"Loading the module for the configuration unit failed.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNIT_INVOKE_INVALID_RESULT, \"The configuration unit returned an unexpected result during execution.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNIT_SETTING_CONFIG_ROOT, \"A unit contains a setting that requires the config root.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE_ADMIN, \"Loading the module for the configuration unit failed because it requires administrator privileges to run.\"),\r\n            WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR, \"Operation is not supported by the configuration processor.\"),\r\n\r\n            // Errors without the error bit set\r\n            WINGET_HRESULT_INFO(WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_APPLICABLE, \"The install location is not applicable.\"),\r\n            WINGET_HRESULT_INFO(WINGET_INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK, \"The file was found but the hash was not checked.\"),\r\n        };\r\n\r\n        // Map externally defined HRESULTs to error messages we want to use here\r\n        constexpr const HResultData s_externalHResultData[] =\r\n        {\r\n            // Changes to any of these errors require the corresponding resource string in winget.resw to be updated.\r\n            HResultData{ static_cast<HRESULT>(0x803FB103), \"StoreInstall_PackageNotAvailableForCurrentSystem\", \"The package is not compatible with the current Windows version or platform.\" },\r\n            HResultData{ static_cast<HRESULT>(0x803FB104), \"StoreInstall_PackageNotAvailableForCurrentSystem\", \"The package is not compatible with the current Windows version or platform.\" },\r\n            HResultData{ static_cast<HRESULT>(0x803FB106), \"StoreInstall_PackageNotAvailableForCurrentSystem\", \"The package is not compatible with the current Windows version or platform.\" },\r\n        };\r\n\r\n        template <size_t ArraySize>\r\n        const HResultData* FindHResultData(HRESULT value, const HResultData (&dataArray)[ArraySize])\r\n        {\r\n            auto itr = std::lower_bound(std::cbegin(dataArray), std::cend(dataArray), HResultData{ value });\r\n\r\n            if (itr != std::cend(dataArray) && itr->Value == value)\r\n            {\r\n                return itr;\r\n            }\r\n\r\n            return nullptr;\r\n        }\r\n\r\n        const HResultData* FindWinGetHResultData(HRESULT value)\r\n        {\r\n            return FindHResultData(value, s_wingetHResultData);\r\n        }\r\n\r\n        const HResultData* FindExternalHResultData(HRESULT value)\r\n        {\r\n            return FindHResultData(value, s_externalHResultData);\r\n        }\r\n\r\n        Utility::LocIndString GetMessageForAppInstallerHR(HRESULT hr)\r\n        {\r\n            const HResultData* data = FindWinGetHResultData(hr);\r\n            return data ?\r\n                WinGetHResultInformation(*data).GetDescription() :\r\n                UnknownHResultInformation(hr).GetDescription();\r\n        }\r\n\r\n        void GetUserPresentableMessageForHR(std::ostringstream& strstr, HRESULT hr)\r\n        {\r\n            strstr << \"0x\" << Logging::SetHRFormat << hr << \" : \";\r\n\r\n            if (HRESULT_FACILITY(hr) == APPINSTALLER_CLI_ERROR_FACILITY)\r\n            {\r\n                strstr << GetMessageForAppInstallerHR(hr);\r\n            }\r\n            else\r\n            {\r\n                const HResultData* data = FindExternalHResultData(hr);\r\n\r\n                if (data)\r\n                {\r\n                    strstr << WinGetHResultInformation(*data).GetDescription();\r\n                }\r\n                else\r\n                {\r\n                    strstr << std::system_category().message(hr);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    std::string GetUserPresentableMessage(const wil::ResultException& re)\r\n    {\r\n        const auto& info = re.GetFailureInfo();\r\n\r\n        std::ostringstream strstr;\r\n\r\n        // We assume that if the exception has a message, that message is relevant to show to the user.\r\n        if (info.pszMessage)\r\n        {\r\n            strstr << Utility::ConvertToUTF8(info.pszMessage) << std::endl;\r\n        }\r\n\r\n        GetUserPresentableMessageForHR(strstr, re.GetErrorCode());\r\n\r\n        return strstr.str();\r\n    }\r\n\r\n    std::string GetUserPresentableMessage(const std::exception& e)\r\n    {\r\n        return e.what();\r\n    }\r\n\r\n    std::string GetUserPresentableMessage(HRESULT hr)\r\n    {\r\n        std::ostringstream strstr;\r\n        GetUserPresentableMessageForHR(strstr, hr);\r\n        return strstr.str();\r\n    }\r\n\r\n#ifndef WINGET_DISABLE_FOR_FUZZING\r\n    std::string GetUserPresentableMessage(const winrt::hresult_error& hre)\r\n    {\r\n        std::ostringstream strstr;\r\n        GetUserPresentableMessageForHR(strstr, hre.code());\r\n        return strstr.str();\r\n    }\r\n#endif\r\n\r\n    namespace Errors\r\n    {\r\n        constexpr HResultInformation::HResultInformation(HRESULT value) :\r\n            m_value(value) {}\r\n\r\n        constexpr HResultInformation::HResultInformation(HRESULT value, std::string_view symbol) :\r\n            m_value(value), m_symbol(symbol) {}\r\n\r\n        HRESULT HResultInformation::Value() const\r\n        {\r\n            return m_value;\r\n        }\r\n\r\n        bool HResultInformation::operator<(const HResultInformation& other) const\r\n        {\r\n            return m_value < other.m_value;\r\n        }\r\n\r\n        Utility::LocIndView HResultInformation::Symbol() const\r\n        {\r\n            return Utility::LocIndView{ m_symbol };\r\n        }\r\n\r\n        Utility::LocIndString HResultInformation::GetDescription() const\r\n        {\r\n            if (HRESULT_FACILITY(m_value) == APPINSTALLER_CLI_ERROR_FACILITY)\r\n            {\r\n                // In case external code attempts to construct HResultInformation directly\r\n                return GetMessageForAppInstallerHR(m_value);\r\n            }\r\n            else\r\n            {\r\n                return Utility::LocIndString{ std::system_category().message(m_value) };\r\n            }\r\n        }\r\n\r\n        std::unique_ptr<HResultInformation> HResultInformation::Find(HRESULT value)\r\n        {\r\n            if (HRESULT_FACILITY(value) == APPINSTALLER_CLI_ERROR_FACILITY)\r\n            {\r\n                const HResultData* data = FindWinGetHResultData(value);\r\n\r\n                if (data)\r\n                {\r\n                    return std::make_unique<WinGetHResultInformation>(*data);\r\n                }\r\n                else\r\n                {\r\n                    return std::make_unique<UnknownHResultInformation>(value);\r\n                }\r\n            }\r\n            else\r\n            {\r\n                return std::make_unique<HResultInformation>(value);\r\n            }\r\n        }\r\n\r\n        std::vector<std::unique_ptr<HResultInformation>> HResultInformation::Find(std::string_view value)\r\n        {\r\n            std::vector<std::unique_ptr<HResultInformation>> result;\r\n\r\n            auto addToResultIf = [&](auto predicate)\r\n            {\r\n                for (const HResultData& data : s_wingetHResultData)\r\n                {\r\n                    if (predicate(data) &&\r\n                        std::none_of(result.begin(), result.end(), [&](const std::unique_ptr<HResultInformation>& info) { return info->Value() == data.Value; }))\r\n                    {\r\n                        result.emplace_back(std::make_unique<WinGetHResultInformation>(data));\r\n                    }\r\n                }\r\n            };\r\n\r\n            addToResultIf([&](const HResultData& data) { return Utility::CaseInsensitiveEquals(data.Symbol, value); });\r\n            addToResultIf([&](const HResultData& data) { return Utility::CaseInsensitiveContainsSubstring(data.Symbol, value); });\r\n            addToResultIf([&](const HResultData& data) { return Utility::CaseInsensitiveContainsSubstring(data.Description, value); });\r\n\r\n            return result;\r\n        }\r\n\r\n        std::vector<std::unique_ptr<HResultInformation>> GetWinGetErrors()\r\n        {\r\n            std::vector<std::unique_ptr<HResultInformation>> result;\r\n            result.reserve(ARRAYSIZE(s_wingetHResultData));\r\n\r\n            for (const HResultData& data : s_wingetHResultData)\r\n            {\r\n                result.emplace_back(std::make_unique<WinGetHResultInformationUnlocalized>(data));\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Filesystem.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/Filesystem.h\"\r\n#include \"Public/AppInstallerStrings.h\"\r\n#include \"Public/AppInstallerLogging.h\"\r\n#include \"Public/winget/Runtime.h\"\r\n\r\nusing namespace std::chrono_literals;\r\nusing namespace std::string_view_literals;\r\nusing namespace AppInstaller::Runtime;\r\n\r\nnamespace AppInstaller::Filesystem\r\n{\r\n    namespace anon\r\n    {\r\n        constexpr std::string_view s_AppDataDir_Settings = \"Settings\"sv;\r\n        constexpr std::string_view s_AppDataDir_State = \"State\"sv;\r\n\r\n        constexpr std::string_view s_LocalAppDataEnvironmentVariable = \"%LOCALAPPDATA%\";\r\n\r\n        // Contains the information about an ACE entry for a given principal.\r\n        struct ACEDetails\r\n        {\r\n            ACEPrincipal Principal;\r\n            PSID SID;\r\n            TRUSTEE_TYPE TrusteeType;\r\n        };\r\n\r\n        DWORD AccessPermissionsFrom(ACEPermissions permissions)\r\n        {\r\n            DWORD result = 0;\r\n\r\n            if (permissions == ACEPermissions::All)\r\n            {\r\n                result |= GENERIC_ALL;\r\n            }\r\n            else\r\n            {\r\n                if (WI_IsFlagSet(permissions, ACEPermissions::Read))\r\n                {\r\n                    result |= GENERIC_READ;\r\n                }\r\n\r\n                if (WI_IsFlagSet(permissions, ACEPermissions::Write))\r\n                {\r\n                    result |= GENERIC_WRITE | FILE_DELETE_CHILD;\r\n                }\r\n\r\n                if (WI_IsFlagSet(permissions, ACEPermissions::Execute))\r\n                {\r\n                    result |= GENERIC_EXECUTE;\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        // Gets the path to the appdata root.\r\n        // *Only used by non packaged version!*\r\n        std::filesystem::path GetPathToAppDataRoot(bool anonymize)\r\n        {\r\n            std::filesystem::path result = anonymize ? s_LocalAppDataEnvironmentVariable : GetKnownFolderPath(FOLDERID_LocalAppData);\r\n            result /= \"Microsoft/WinGet\";\r\n\r\n            return result;\r\n        }\r\n\r\n        // Gets the path to the app data relative directory.\r\n        std::filesystem::path GetPathToAppDataDir(const std::filesystem::path& relative, bool anonymize)\r\n        {\r\n            THROW_HR_IF(E_INVALIDARG, !relative.has_relative_path());\r\n            THROW_HR_IF(E_INVALIDARG, relative.has_root_path());\r\n            THROW_HR_IF(E_INVALIDARG, !relative.has_filename());\r\n\r\n            std::filesystem::path result = GetPathToAppDataRoot(anonymize);\r\n            result /= relative;\r\n\r\n            return result;\r\n        }\r\n    }\r\n\r\n    DWORD GetVolumeInformationFlagsByHandle(HANDLE anyFileHandle)\r\n    {\r\n        DWORD flags = 0;\r\n        wchar_t fileSystemName[MAX_PATH];\r\n        THROW_LAST_ERROR_IF(!GetVolumeInformationByHandleW(\r\n            anyFileHandle, /*hFile*/\r\n            NULL, /*lpVolumeNameBuffer*/\r\n            0, /*nVolumeNameSize*/\r\n            NULL, /*lpVolumeSerialNumber*/\r\n            NULL, /*lpMaximumComponentLength*/\r\n            &flags, /*lpFileSystemFlags*/\r\n            fileSystemName, /*lpFileSystemNameBuffer*/\r\n            MAX_PATH /*nFileSystemNameSize*/));\r\n\r\n        // Vista and older does not report all flags, fix them up here\r\n        if (!(flags & FILE_SUPPORTS_HARD_LINKS) && !_wcsicmp(fileSystemName, L\"NTFS\"))\r\n        {\r\n            flags |= FILE_SUPPORTS_HARD_LINKS | FILE_SUPPORTS_EXTENDED_ATTRIBUTES | FILE_SUPPORTS_OPEN_BY_FILE_ID | FILE_SUPPORTS_USN_JOURNAL;\r\n        }\r\n\r\n        return flags;\r\n    }\r\n\r\n    DWORD GetVolumeInformationFlags(const std::filesystem::path& anyPath)\r\n    {\r\n        wil::unique_hfile fileHandle{ CreateFileW(\r\n            anyPath.c_str(), /*lpFileName*/\r\n            0, /*dwDesiredAccess*/\r\n            FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, /*dwShareMode*/\r\n            NULL, /*lpSecurityAttributes*/\r\n            OPEN_EXISTING, /*dwCreationDisposition*/\r\n            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, /*dwFlagsAndAttributes*/\r\n            NULL /*hTemplateFile*/) };\r\n\r\n        THROW_LAST_ERROR_IF(fileHandle.get() == INVALID_HANDLE_VALUE);\r\n\r\n        return GetVolumeInformationFlagsByHandle(fileHandle.get());\r\n    }\r\n\r\n    bool SupportsNamedStreams(const std::filesystem::path& path)\r\n    {\r\n        return (GetVolumeInformationFlags(path) & FILE_NAMED_STREAMS) != 0;\r\n    }\r\n\r\n    bool SupportsHardLinks(const std::filesystem::path& path)\r\n    {\r\n        return (GetVolumeInformationFlags(path) & FILE_SUPPORTS_HARD_LINKS) != 0;\r\n    }\r\n\r\n    bool SupportsReparsePoints(const std::filesystem::path& path)\r\n    {\r\n        return (GetVolumeInformationFlags(path) & FILE_SUPPORTS_REPARSE_POINTS) != 0;\r\n    }\r\n\r\n    bool PathEscapesBaseDirectory(const std::filesystem::path& target, const std::filesystem::path& base)\r\n    {\r\n        const auto& targetPath = std::filesystem::weakly_canonical(target);\r\n        const auto& basePath = std::filesystem::weakly_canonical(base);\r\n        auto [a, b] = std::mismatch(targetPath.begin(), targetPath.end(), basePath.begin(), basePath.end());\r\n        return (b != basePath.end());\r\n    }\r\n\r\n    // Complicated rename algorithm due to somewhat arbitrary failures.\r\n    // 1. First, try to rename.\r\n    // 2. Then, create an empty file for the target, and attempt to rename.\r\n    // 3. Then, try repeatedly for 500ms in case it is a timing thing.\r\n    // 4. Attempt to use a hard link if available.\r\n    // 5. Copy the file if nothing else has worked so far.\r\n    void RenameFile(const std::filesystem::path& from, const std::filesystem::path& to)\r\n    {\r\n        // 1. First, try to rename.\r\n        try\r\n        {\r\n            // std::filesystem::rename() handles motw correctly if applicable.\r\n            std::filesystem::rename(from, to);\r\n            return;\r\n        }\r\n        CATCH_LOG();\r\n\r\n        // 2. Then, create an empty file for the target, and attempt to rename.\r\n        //    This seems to fix things in certain cases, so we do it.\r\n        try\r\n        {\r\n            {\r\n                std::ofstream targetFile{ to };\r\n            }\r\n            std::filesystem::rename(from, to);\r\n            return;\r\n        }\r\n        CATCH_LOG();\r\n\r\n        // 3. Then, try repeatedly for 500ms in case it is a timing thing.\r\n        for (int i = 0; i < 5; ++i)\r\n        {\r\n            try\r\n            {\r\n                std::this_thread::sleep_for(100ms);\r\n                std::filesystem::rename(from, to);\r\n                return;\r\n            }\r\n            CATCH_LOG();\r\n        }\r\n\r\n        // 4. Attempt to use a hard link if available.\r\n        if (SupportsHardLinks(from))\r\n        {\r\n            try\r\n            {\r\n                // Create a hard link to the file; the installer will be left in the temp directory afterward\r\n                // but it is better to succeed the operation and leave a file around than to fail.\r\n                // First we have to remove the target file as the function will not overwrite.\r\n                std::filesystem::remove(to);\r\n                std::filesystem::create_hard_link(from, to);\r\n                return;\r\n            }\r\n            CATCH_LOG();\r\n        }\r\n\r\n        // 5. Copy the file if nothing else has worked so far.\r\n        // Create a copy of the file; the installer will be left in the temp directory afterward\r\n        // but it is better to succeed the operation and leave a file around than to fail.\r\n        std::filesystem::copy_file(from, to, std::filesystem::copy_options::overwrite_existing);\r\n    }\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n    static bool* s_CreateSymlinkResult_TestHook_Override = nullptr;\r\n\r\n    void TestHook_SetCreateSymlinkResult_Override(bool* status)\r\n    {\r\n        s_CreateSymlinkResult_TestHook_Override = status;\r\n    }\r\n#endif\r\n\r\n    bool CreateSymlink(const std::filesystem::path& target, const std::filesystem::path& link)\r\n    {\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        if (s_CreateSymlinkResult_TestHook_Override)\r\n        {\r\n            return *s_CreateSymlinkResult_TestHook_Override;\r\n        }\r\n#endif\r\n        try\r\n        {\r\n            std::filesystem::create_symlink(target, link);\r\n            return true;\r\n        }\r\n        catch (std::filesystem::filesystem_error& error)\r\n        {\r\n            if (error.code().value() == ERROR_PRIVILEGE_NOT_HELD)\r\n            {\r\n                return false;\r\n            }\r\n            else\r\n            {\r\n                throw;\r\n            }\r\n        }\r\n    }\r\n\r\n    bool VerifySymlink(const std::filesystem::path& symlink, const std::filesystem::path& target)\r\n    {\r\n        const std::filesystem::path& symlinkTargetPath = std::filesystem::weakly_canonical(symlink);\r\n        return symlinkTargetPath == std::filesystem::weakly_canonical(target);\r\n    }\r\n\r\n    void AppendExtension(std::filesystem::path& target, const std::string& value)\r\n    {\r\n        if (target.extension() != value)\r\n        {\r\n            target += value;\r\n        }\r\n    }\r\n\r\n    bool SymlinkExists(const std::filesystem::path& symlinkPath)\r\n    {\r\n        return std::filesystem::is_symlink(std::filesystem::symlink_status(symlinkPath));\r\n    }\r\n\r\n    std::filesystem::path GetExpandedPath(const std::string& path)\r\n    {\r\n        std::string trimPath = path;\r\n        Utility::Trim(trimPath);\r\n\r\n        try\r\n        {\r\n            return std::filesystem::weakly_canonical(Utility::ExpandEnvironmentVariables(Utility::ConvertToUTF16(trimPath)));\r\n        }\r\n        catch (...)\r\n        {\r\n            return Utility::ConvertToUTF16(path);\r\n        }\r\n    }\r\n\r\n    bool ReplaceCommonPathPrefix(std::filesystem::path& source, const std::filesystem::path& prefix, std::string_view replacement)\r\n    {\r\n        auto prefixItr = prefix.begin();\r\n        auto sourceItr = source.begin();\r\n\r\n        while (prefixItr != prefix.end() && sourceItr != source.end())\r\n        {\r\n            if (!Utility::ICUCaseInsensitiveEquals(prefixItr->u8string(), sourceItr->u8string()))\r\n            {\r\n                break;\r\n            }\r\n\r\n            ++prefixItr;\r\n            ++sourceItr;\r\n        }\r\n\r\n        // Only replace source if we found all of prefix\r\n        if (prefixItr == prefix.end())\r\n        {\r\n            std::filesystem::path temp{ replacement };\r\n\r\n            for (; sourceItr != source.end(); ++sourceItr)\r\n            {\r\n                temp /= *sourceItr;\r\n            }\r\n\r\n            source = std::move(temp);\r\n\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    std::filesystem::path GetKnownFolderPath(const KNOWNFOLDERID& id)\r\n    {\r\n        wil::unique_cotaskmem_string knownFolder = nullptr;\r\n        THROW_IF_FAILED(SHGetKnownFolderPath(id, KF_FLAG_NO_ALIAS | KF_FLAG_DONT_VERIFY | KF_FLAG_NO_PACKAGE_REDIRECTION, NULL, &knownFolder));\r\n        return knownFolder.get();\r\n    }\r\n\r\n    bool IsSameVolume(const std::filesystem::path& path1, const std::filesystem::path& path2)\r\n    {\r\n        WCHAR volumeName1[MAX_PATH];\r\n        WCHAR volumeName2[MAX_PATH];\r\n\r\n        // Note: GetVolumePathNameW will return false if the volume drive does not exist.\r\n        if (!GetVolumePathNameW(path1.c_str(), volumeName1, MAX_PATH) || !GetVolumePathNameW(path2.c_str(), volumeName2, MAX_PATH))\r\n        {\r\n            return false;\r\n        }\r\n        return Utility::ICUCaseInsensitiveEquals(Utility::ConvertToUTF8(volumeName1), Utility::ConvertToUTF8(volumeName2));\r\n    }\r\n\r\n    bool IsParentPath(const std::filesystem::path& path, const std::filesystem::path& parentPath)\r\n    {\r\n        return std::filesystem::weakly_canonical(path.parent_path()) == std::filesystem::weakly_canonical(parentPath);\r\n    }\r\n\r\n    void PathDetails::SetOwner(ACEPrincipal owner)\r\n    {\r\n        Owner = owner;\r\n        ACL[owner] = ACEPermissions::All;\r\n    }\r\n\r\n    bool PathDetails::ShouldApplyACL() const\r\n    {\r\n        // Could be expanded to actually check the current owner/ACL on the path, but isn't worth it currently\r\n        return !ACL.empty();\r\n    }\r\n\r\n    void PathDetails::ApplyACL() const\r\n    {\r\n        bool hasCurrentUser = ACL.count(ACEPrincipal::CurrentUser) != 0;\r\n        bool hasSystem = ACL.count(ACEPrincipal::System) != 0;\r\n\r\n        // Configuring permissions for both CurrentUser and SYSTEM while not having owner set as one of them is not valid because\r\n        // below we use only the owner permissions in the case of running as SYSTEM.\r\n        if ((hasCurrentUser && hasSystem) &&\r\n            IsRunningAsSystem() &&\r\n            (!Owner || (Owner.value() != ACEPrincipal::CurrentUser && Owner.value() != ACEPrincipal::System)))\r\n        {\r\n            THROW_HR(HRESULT_FROM_WIN32(ERROR_INVALID_STATE));\r\n        }\r\n\r\n        auto userToken = wil::get_token_information<TOKEN_USER>();\r\n        auto adminSID = wil::make_static_sid(SECURITY_NT_AUTHORITY, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS);\r\n        auto systemSID = wil::make_static_sid(SECURITY_NT_AUTHORITY, SECURITY_LOCAL_SYSTEM_RID);\r\n        PSID ownerSID = nullptr;\r\n\r\n        anon::ACEDetails aceDetails[] =\r\n        {\r\n            { ACEPrincipal::CurrentUser, userToken->User.Sid, TRUSTEE_IS_USER },\r\n            { ACEPrincipal::Admins, adminSID.get(), TRUSTEE_IS_WELL_KNOWN_GROUP},\r\n            { ACEPrincipal::System, systemSID.get(), TRUSTEE_IS_USER},\r\n        };\r\n\r\n        ULONG entriesCount = 0;\r\n        std::array<EXPLICIT_ACCESS_W, ARRAYSIZE(aceDetails)> explicitAccess;\r\n\r\n        // If the current user is SYSTEM, we want to take either the owner or the only configured set of permissions.\r\n        // The check above should prevent us from getting into situations outside of the ones below.\r\n        std::optional<ACEPrincipal> principalToIgnore;\r\n        if (hasCurrentUser && hasSystem && EqualSid(userToken->User.Sid, systemSID.get()))\r\n        {\r\n            principalToIgnore = (Owner.value() == ACEPrincipal::CurrentUser ? ACEPrincipal::System : ACEPrincipal::CurrentUser);\r\n        }\r\n\r\n        for (const auto& ace : aceDetails)\r\n        {\r\n            if (principalToIgnore && principalToIgnore.value() == ace.Principal)\r\n            {\r\n                continue;\r\n            }\r\n\r\n            if (Owner && Owner.value() == ace.Principal)\r\n            {\r\n                ownerSID = ace.SID;\r\n            }\r\n\r\n            auto itr = ACL.find(ace.Principal);\r\n            if (itr != ACL.end())\r\n            {\r\n                EXPLICIT_ACCESS_W& entry = explicitAccess[entriesCount++];\r\n                entry = {};\r\n\r\n                entry.grfAccessPermissions = anon::AccessPermissionsFrom(itr->second);\r\n                entry.grfAccessMode = SET_ACCESS;\r\n                entry.grfInheritance = CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE;\r\n\r\n                entry.Trustee.pMultipleTrustee = nullptr;\r\n                entry.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;\r\n                entry.Trustee.TrusteeForm = TRUSTEE_IS_SID;\r\n                entry.Trustee.TrusteeType = ace.TrusteeType;\r\n                entry.Trustee.ptstrName = reinterpret_cast<LPWCH>(ace.SID);\r\n            }\r\n        }\r\n\r\n        wil::unique_any<PACL, decltype(&::LocalFree), ::LocalFree> acl;\r\n        THROW_IF_WIN32_ERROR(SetEntriesInAclW(entriesCount, explicitAccess.data(), nullptr, &acl));\r\n\r\n        std::wstring path = Path.wstring();\r\n        SECURITY_INFORMATION securityInformation = DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION;\r\n\r\n        if (ownerSID)\r\n        {\r\n            securityInformation |= OWNER_SECURITY_INFORMATION;\r\n        }\r\n\r\n        DWORD result = SetNamedSecurityInfoW(&path[0], SE_FILE_OBJECT, securityInformation, ownerSID, nullptr, acl.get(), nullptr);\r\n\r\n        // We can be denied access attempting to set the owner when the owner is already correct.\r\n        // Determine if the owner is correct; if so, try again without attempting to set the owner.\r\n        if (result == ERROR_ACCESS_DENIED && ownerSID)\r\n        {\r\n            wil::unique_hlocal_security_descriptor securityDescriptor;\r\n            PSID currentOwnerSID = nullptr;\r\n            DWORD getResult = GetNamedSecurityInfoW(&path[0], SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, &currentOwnerSID, nullptr, nullptr, nullptr, &securityDescriptor);\r\n\r\n            if (SUCCEEDED_WIN32_LOG(getResult) && currentOwnerSID && EqualSid(currentOwnerSID, ownerSID))\r\n            {\r\n                result = SetNamedSecurityInfoW(&path[0], SE_FILE_OBJECT, securityInformation & ~OWNER_SECURITY_INFORMATION, nullptr, nullptr, acl.get(), nullptr);\r\n            }\r\n        }\r\n\r\n        THROW_IF_WIN32_ERROR(result);\r\n    }\r\n\r\n    std::filesystem::path InitializeAndGetPathTo(PathDetails&& details)\r\n    {\r\n        if (details.Create)\r\n        {\r\n            if (details.Path.is_absolute())\r\n            {\r\n                if (std::filesystem::exists(details.Path) && !std::filesystem::is_directory(details.Path))\r\n                {\r\n                    std::filesystem::remove(details.Path);\r\n                }\r\n\r\n                std::filesystem::create_directories(details.Path);\r\n\r\n                // Set the ACLs on the directory if needed. We do this after creating the directory because an attacker could\r\n                // have created the directory beforehand so we must be able to place the correct ACL on any directory or fail\r\n                // to operate.\r\n                if (details.ShouldApplyACL())\r\n                {\r\n                    details.ApplyACL();\r\n                }\r\n            }\r\n            else\r\n            {\r\n                AICLI_LOG(Core, Warning, << \"InitializeAndGetPathTo directory creation requested for path that was not absolute: \" << details.Path);\r\n            }\r\n        }\r\n\r\n        return std::move(details.Path);\r\n    }\r\n\r\n    PathDetails GetPathDetailsFor(PathName path, bool forDisplay)\r\n    {\r\n        PathDetails result;\r\n        // We should not create directories by default when they are retrieved for display purposes.\r\n        result.Create = !forDisplay;\r\n\r\n        switch (path)\r\n        {\r\n        case PathName::UnpackagedLocalStateRoot:\r\n            result.Path = anon::GetPathToAppDataDir(anon::s_AppDataDir_State, forDisplay);\r\n            result.SetOwner(ACEPrincipal::CurrentUser);\r\n            result.ACL[ACEPrincipal::System] = ACEPermissions::All;\r\n            result.ACL[ACEPrincipal::Admins] = ACEPermissions::All;\r\n            break;\r\n        case PathName::UnpackagedSettingsRoot:\r\n            result.Path = anon::GetPathToAppDataDir(anon::s_AppDataDir_Settings, forDisplay);\r\n            result.SetOwner(ACEPrincipal::CurrentUser);\r\n            result.ACL[ACEPrincipal::System] = ACEPermissions::All;\r\n            result.ACL[ACEPrincipal::Admins] = ACEPermissions::All;\r\n            break;\r\n        default:\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::filesystem::path GetExecutablePathForProcess(HANDLE process)\r\n    {\r\n        wil::unique_cotaskmem_string imageName = nullptr;\r\n        if (SUCCEEDED(wil::QueryFullProcessImageNameW(process, 0, imageName)) &&\r\n            (imageName.get() != nullptr))\r\n        {\r\n            return imageName.get();\r\n        }\r\n\r\n        return {};\r\n    }\r\n\r\n    std::vector<FileInfo> GetFileInfoFor(const std::filesystem::path& directory)\r\n    {\r\n        std::vector<FileInfo> result;\r\n\r\n        for (const auto& file : std::filesystem::directory_iterator{ directory })\r\n        {\r\n            if (file.is_regular_file())\r\n            {\r\n                result.emplace_back(FileInfo{ file.path(), file.last_write_time(), file.file_size() });\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    void FilterToFilesExceedingLimits(std::vector<FileInfo>& files, const FileLimits& limits)\r\n    {\r\n        auto now = std::filesystem::file_time_type::clock::now();\r\n        std::chrono::hours ageLimit = limits.Age;\r\n        static_assert(sizeof(uintmax_t) >= 8);\r\n        uintmax_t totalSizeLimit = static_cast<uintmax_t>(limits.TotalSizeInMB) << 20;\r\n        size_t countLimit = limits.Count;\r\n\r\n        // Sort with oldest first so that we can work backward to find the cutoff\r\n        std::sort(files.begin(), files.end(), [](const FileInfo& a, const FileInfo& b) { return a.LastWriteTime < b.LastWriteTime; });\r\n\r\n        // Walk the list backward until we find the first entry that goes over one of the limits\r\n        size_t i = files.size();\r\n        uintmax_t totalSize = 0;\r\n        for (; i > 0; --i)\r\n        {\r\n            const FileInfo& current = files[i - 1];\r\n\r\n            if (totalSizeLimit != 0)\r\n            {\r\n                totalSize += current.Size;\r\n                if (totalSize > totalSizeLimit)\r\n                {\r\n                    break;\r\n                }\r\n            }\r\n\r\n            if (countLimit != 0 && (files.size() - i + 1) > countLimit)\r\n            {\r\n                break;\r\n            }\r\n\r\n            if (ageLimit != 0h && now - current.LastWriteTime > ageLimit)\r\n            {\r\n                break;\r\n            }\r\n        }\r\n\r\n        files.resize(i);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/GroupPolicy.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"winget/GroupPolicy.h\"\r\n#include \"AppInstallerLogging.h\"\r\n\r\nusing namespace AppInstaller::StringResource;\r\n\r\nnamespace AppInstaller::Settings\r\n{\r\n    namespace\r\n    {\r\n        const GroupPolicy& InstanceInternal(std::optional<GroupPolicy*> overridePolicy = {})\r\n        {\r\n            const static GroupPolicy s_groupPolicy{ Registry::Key::OpenIfExists(HKEY_LOCAL_MACHINE, \"Software\\\\Policies\\\\Microsoft\\\\Windows\\\\AppInstaller\") };\r\n            static GroupPolicy* s_override = nullptr;\r\n\r\n            if (overridePolicy.has_value())\r\n            {\r\n                s_override = overridePolicy.value();\r\n            }\r\n\r\n            return (s_override ? *s_override : s_groupPolicy);\r\n        }\r\n\r\n        std::optional<Registry::Value> GetRegistryValueObject(const Registry::Key& key, const std::string_view valueName)\r\n        {\r\n            if (!key)\r\n            {\r\n                // Key does not exist; there's nothing to return\r\n                return std::nullopt;\r\n            }\r\n\r\n            return key[valueName];\r\n        }\r\n\r\n        template<Registry::Value::Type T>\r\n        std::optional<decltype(std::declval<Registry::Value>().GetValue<T>())> GetRegistryValueData(const Registry::Value& regValue, const std::string_view valueName)\r\n        {\r\n            auto value = regValue.TryGetValue<T>();\r\n            if (!value.has_value())\r\n            {\r\n                AICLI_LOG(Core, Warning, << \"Value for policy '\" << valueName << \"' does not have expected type\");\r\n                return std::nullopt;\r\n            }\r\n\r\n            return std::move(value.value());\r\n        }\r\n\r\n        template<Registry::Value::Type T>\r\n        std::optional<decltype(std::declval<Registry::Value>().GetValue<T>())> GetRegistryValueData(const Registry::Key& key, const std::string_view valueName)\r\n        {\r\n            auto regValue = GetRegistryValueObject(key, valueName);\r\n            if (!regValue.has_value())\r\n            {\r\n                // Value does not exist; there's nothing to return\r\n                return std::nullopt;\r\n            }\r\n\r\n            return GetRegistryValueData<T>(regValue.value(), valueName);\r\n        }\r\n\r\n        std::optional<bool> RegistryValueIsTrue(const Registry::Key& key, std::string_view valueName)\r\n        {\r\n            auto intValue = GetRegistryValueData<Registry::Value::Type::DWord>(key, valueName);\r\n            if (!intValue.has_value())\r\n            {\r\n                return std::nullopt;\r\n            }\r\n\r\n            AICLI_LOG(Core, Verbose, << \"Found policy '\" << valueName << \"', Value: \" << *intValue);\r\n            return (bool)*intValue;\r\n        }\r\n\r\n        PolicyState GetStateInternal(const Registry::Key& key, TogglePolicy::Policy policy)\r\n        {\r\n            // Default to not configured if there is no policy for this\r\n            if (policy == TogglePolicy::Policy::None)\r\n            {\r\n                return PolicyState::NotConfigured;\r\n            }\r\n\r\n            auto togglePolicy = TogglePolicy::GetPolicy(policy);\r\n\r\n            // Policies are not configured if there is no registry value.\r\n            auto setting = RegistryValueIsTrue(key, togglePolicy.RegValueName());\r\n            if (!setting.has_value())\r\n            {\r\n                return PolicyState::NotConfigured;\r\n            }\r\n\r\n            // Return flag as-is or invert depending on the policy\r\n            return *setting ? PolicyState::Enabled : PolicyState::Disabled;\r\n        }\r\n\r\n        template <ValuePolicy P>\r\n        void Validate(const Registry::Key& policiesKey, GroupPolicy::ValuePoliciesMap& policies)\r\n        {\r\n            auto value = details::ValuePolicyMapping<P>::ReadAndValidate(policiesKey);\r\n            if (value.has_value())\r\n            {\r\n                policies.Add<P>(std::move(*value));\r\n            }\r\n        }\r\n\r\n        template <>\r\n        void Validate<ValuePolicy::None>(const Registry::Key&, GroupPolicy::ValuePoliciesMap&) {};\r\n\r\n        template <size_t... P>\r\n        void ValidateAllValuePolicies(\r\n            const Registry::Key& policiesKey,\r\n            GroupPolicy::ValuePoliciesMap& policies,\r\n            std::index_sequence<P...>)\r\n        {\r\n            // Use folding to call each policy validate function.\r\n            (FoldHelper{}, ..., Validate<static_cast<ValuePolicy>(P)>(policiesKey, policies));\r\n        }\r\n\r\n        // Reads a list from a Group Policy.\r\n        // The list is stored in a sub-key of the policies key, and each value in that key is a list item.\r\n        // Cases not considered by this function because we don't use them:\r\n        //  - When the list is in an arbitrary key, not a sub key.\r\n        //  - When the list values are mixed with other values and are identified by a prefix in their names.\r\n        //  - When the value names are relevant.\r\n        template<ValuePolicy P>\r\n        std::optional<typename details::ValuePolicyMapping<P>::value_t> ReadList(const Registry::Key& policiesKey)\r\n        {\r\n            using Mapping = details::ValuePolicyMapping<P>;\r\n\r\n            auto listKey = policiesKey.SubKey(Mapping::KeyName);\r\n            if (!listKey.has_value())\r\n            {\r\n                return std::nullopt;\r\n            }\r\n\r\n            typename Mapping::value_t items;\r\n            for (const auto& value : listKey->Values())\r\n            {\r\n                std::optional<Registry::Value> potentialValue = value.Value();\r\n\r\n                if (potentialValue)\r\n                {\r\n                    auto item = Mapping::ReadAndValidateItem(potentialValue.value());\r\n                    if (item.has_value())\r\n                    {\r\n                        items.emplace_back(std::move(item.value()));\r\n                    }\r\n                    else\r\n                    {\r\n                        AICLI_LOG(Core, Warning, << \"Failed to read Group Policy list value. Policy [\" << Mapping::KeyName << \"], Value [\" << value.Name() << ']');\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(Core, Verbose, << \"Group Policy list value not found. Policy [\" << Mapping::KeyName << \"], Value [\" << value.Name() << ']');\r\n                }\r\n            }\r\n\r\n            return items;\r\n        }\r\n\r\n        std::optional<SourceFromPolicy> ReadSourceFromRegistryValue(const Registry::Value& item)\r\n        {\r\n            auto jsonString = item.TryGetValue<Registry::Value::Type::String>();\r\n            if (!jsonString.has_value())\r\n            {\r\n                AICLI_LOG(Core, Warning, << \"Registry value is not a string\");\r\n                return std::nullopt;\r\n            }\r\n\r\n            int stringLength = static_cast<int>(jsonString->length());\r\n            Json::Value sourceJson;\r\n            Json::CharReaderBuilder charReaderBuilder;\r\n            const std::unique_ptr<Json::CharReader> jsonReader(charReaderBuilder.newCharReader());\r\n            Json::String jsonErrors;\r\n            if (!jsonReader->parse(jsonString->c_str(), jsonString->c_str() + stringLength, &sourceJson, &jsonErrors))\r\n            {\r\n                AICLI_LOG(Core, Warning, << \"Registry value does not contain a valid JSON: \" << jsonErrors);\r\n                return std::nullopt;\r\n            }\r\n\r\n            SourceFromPolicy source;\r\n\r\n            auto readSourceAttribute = [&](const std::string& name, std::string SourceFromPolicy::* member)\r\n            {\r\n                if (sourceJson.isMember(name) && sourceJson[name].isString())\r\n                {\r\n                    source.*member = sourceJson[name].asString();\r\n                    return true;\r\n                }\r\n                else\r\n                {\r\n                    AICLI_LOG(Core, Warning, << \"Source JSON does not contain a string value for \" << name);\r\n                    return false;\r\n                }\r\n            };\r\n\r\n            // All required fields should be read here.\r\n            bool allRead = readSourceAttribute(\"Name\", &SourceFromPolicy::Name)\r\n                && readSourceAttribute(\"Arg\", &SourceFromPolicy::Arg)\r\n                && readSourceAttribute(\"Type\", &SourceFromPolicy::Type)\r\n                && readSourceAttribute(\"Data\", &SourceFromPolicy::Data)\r\n                && readSourceAttribute(\"Identifier\", &SourceFromPolicy::Identifier);\r\n\r\n            if (!allRead)\r\n            {\r\n                return std::nullopt;\r\n            }\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n            // Enable certificate pinning configuration through GP sources for testing\r\n            const std::string pinningConfigurationName = \"CertificatePinning\";\r\n            if (sourceJson.isMember(pinningConfigurationName))\r\n            {\r\n                source.PinningConfiguration = Certificates::PinningConfiguration(source.Name);\r\n                if (!source.PinningConfiguration.LoadFrom(sourceJson[pinningConfigurationName]))\r\n                {\r\n                    return std::nullopt;\r\n                }\r\n            }\r\n#endif\r\n            // TrustLevel, Explicit, and Priority are optional policy fields with default values.\r\n            const std::string trustLevelName = \"TrustLevel\";\r\n            if (sourceJson.isMember(trustLevelName) && sourceJson[trustLevelName].isArray())\r\n            {\r\n                const Json::Value in = sourceJson[trustLevelName];\r\n                std::vector<std::string> result;\r\n                result.reserve(in.size());\r\n                std::transform(in.begin(), in.end(), std::back_inserter(result), [](const auto& e) { return e.asString(); });\r\n                source.TrustLevel = result;\r\n            }\r\n\r\n            const std::string explicitName = \"Explicit\";\r\n            if (sourceJson.isMember(explicitName) && sourceJson[explicitName].isBool())\r\n            {\r\n                source.Explicit = sourceJson[explicitName].asBool();\r\n            }\r\n\r\n            const std::string priorityName = \"Priority\";\r\n            if (sourceJson.isMember(priorityName) && sourceJson[priorityName].isInt())\r\n            {\r\n                source.Priority = sourceJson[priorityName].asInt();\r\n            }\r\n\r\n            return source;\r\n        }\r\n    }\r\n\r\n    namespace details\r\n    {\r\n#define POLICY_MAPPING_DEFAULT_READ(_policy_) \\\r\n        std::optional<typename ValuePolicyMapping<_policy_>::value_t> ValuePolicyMapping<_policy_>::ReadAndValidate(const Registry::Key& policiesKey) \\\r\n        { \\\r\n            using Mapping = ValuePolicyMapping<_policy_>; \\\r\n            return GetRegistryValueData<Mapping::ValueType>(policiesKey, Mapping::ValueName); \\\r\n        }\r\n\r\n#define POLICY_MAPPING_DEFAULT_LIST_READ(_policy_) \\\r\n        std::optional<typename ValuePolicyMapping<_policy_>::value_t> ValuePolicyMapping<_policy_>::ReadAndValidate(const Registry::Key& policiesKey) \\\r\n        { \\\r\n            return ReadList<_policy_>(policiesKey); \\\r\n        }\r\n\r\n        POLICY_MAPPING_DEFAULT_LIST_READ(ValuePolicy::AdditionalSources);\r\n        POLICY_MAPPING_DEFAULT_LIST_READ(ValuePolicy::AllowedSources);\r\n        POLICY_MAPPING_DEFAULT_READ(ValuePolicy::DefaultProxy);\r\n\r\n        std::nullopt_t ValuePolicyMapping<ValuePolicy::None>::ReadAndValidate(const Registry::Key&)\r\n        {\r\n            return std::nullopt;\r\n        }\r\n\r\n        std::optional<uint32_t> ValuePolicyMapping<ValuePolicy::SourceAutoUpdateIntervalInMinutes>::ReadAndValidate(const Registry::Key& policiesKey)\r\n        {\r\n            // This policy used to have another name in the registry.\r\n            // Try to read first with the current name, and if it's not present\r\n            // check if the old name is present.\r\n            using Mapping = ValuePolicyMapping<ValuePolicy::SourceAutoUpdateIntervalInMinutes>;\r\n\r\n            auto regValueWithCurrentName = GetRegistryValueObject(policiesKey, Mapping::ValueName);\r\n            if (regValueWithCurrentName.has_value())\r\n            {\r\n                // We use the current name even if it doesn't have valid data.\r\n                return GetRegistryValueData<Mapping::ValueType>(regValueWithCurrentName.value(), Mapping::ValueName);\r\n            }\r\n            else\r\n            {\r\n                return GetRegistryValueData<Mapping::ValueType>(policiesKey, \"SourceAutoUpdateIntervalInMinutes\"sv);\r\n            }\r\n        }\r\n\r\n        std::optional<SourceFromPolicy> ValuePolicyMapping<ValuePolicy::AdditionalSources>::ReadAndValidateItem(const Registry::Value& item)\r\n        {\r\n            return ReadSourceFromRegistryValue(item);\r\n        }\r\n\r\n        std::optional<SourceFromPolicy> ValuePolicyMapping<ValuePolicy::AllowedSources>::ReadAndValidateItem(const Registry::Value& item)\r\n        {\r\n            return ReadSourceFromRegistryValue(item);\r\n        }\r\n    }\r\n\r\n    TogglePolicy TogglePolicy::GetPolicy(TogglePolicy::Policy policy)\r\n    {\r\n        switch (policy)\r\n        {\r\n        case TogglePolicy::Policy::WinGet:\r\n            return TogglePolicy(policy, \"EnableAppInstaller\"sv, String::PolicyEnableWinGet);\r\n        case TogglePolicy::Policy::Settings:\r\n            return TogglePolicy(policy, \"EnableSettings\"sv, String::PolicyEnableWingetSettings);\r\n        case TogglePolicy::Policy::ExperimentalFeatures:\r\n            return TogglePolicy(policy, \"EnableExperimentalFeatures\"sv, String::PolicyEnableExperimentalFeatures);\r\n        case TogglePolicy::Policy::LocalManifestFiles:\r\n            return TogglePolicy(policy, \"EnableLocalManifestFiles\"sv, String::PolicyEnableLocalManifests);\r\n        case TogglePolicy::Policy::HashOverride:\r\n            return TogglePolicy(policy, \"EnableHashOverride\"sv, String::PolicyEnableHashOverride);\r\n        case TogglePolicy::Policy::LocalArchiveMalwareScanOverride:\r\n            return TogglePolicy(policy, \"EnableLocalArchiveMalwareScanOverride\"sv, String::PolicyEnableLocalArchiveMalwareScanOverride);\r\n        case TogglePolicy::Policy::DefaultSource:\r\n            return TogglePolicy(policy, \"EnableDefaultSource\"sv, String::PolicyEnableDefaultSource);\r\n        case TogglePolicy::Policy::MSStoreSource:\r\n            return TogglePolicy(policy, \"EnableMicrosoftStoreSource\"sv, String::PolicyEnableMSStoreSource);\r\n        case TogglePolicy::Policy::FontSource:\r\n            return TogglePolicy(policy, \"EnableFontSource\"sv, String::PolicyEnableFontSource);\r\n        case TogglePolicy::Policy::AdditionalSources:\r\n            return TogglePolicy(policy, \"EnableAdditionalSources\"sv, String::PolicyAdditionalSources);\r\n        case TogglePolicy::Policy::AllowedSources:\r\n            return TogglePolicy(policy, \"EnableAllowedSources\"sv, String::PolicyAllowedSources);\r\n        case TogglePolicy::Policy::BypassCertificatePinningForMicrosoftStore:\r\n            return TogglePolicy(policy, \"EnableBypassCertificatePinningForMicrosoftStore\"sv, String::PolicyEnableBypassCertificatePinningForMicrosoftStore);\r\n        case TogglePolicy::Policy::WinGetCommandLineInterfaces:\r\n            return TogglePolicy(policy, \"EnableWindowsPackageManagerCommandLineInterfaces\"sv, String::PolicyEnableWindowsPackageManagerCommandLineInterfaces);\r\n        case TogglePolicy::Policy::Configuration:\r\n            return TogglePolicy(policy, \"EnableWindowsPackageManagerConfiguration\"sv, String::PolicyEnableWinGetConfiguration);\r\n        case TogglePolicy::Policy::ProxyCommandLineOptions:\r\n            return TogglePolicy(policy, \"EnableWindowsPackageManagerProxyCommandLineOptions\"sv, String::PolicyEnableProxyCommandLineOptions);\r\n        case TogglePolicy::Policy::McpServer:\r\n            return TogglePolicy(policy, \"EnableWindowsPackageManagerMcpServer\"sv, String::PolicyEnableMcpServer);\r\n        default:\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n    }\r\n\r\n    std::vector<TogglePolicy> TogglePolicy::GetAllPolicies()\r\n    {\r\n        using Toggle_t = std::underlying_type_t<TogglePolicy::Policy>;\r\n\r\n        std::vector<TogglePolicy> result;\r\n\r\n        // Skip \"None\"\r\n        for (Toggle_t i = 1 + static_cast<Toggle_t>(TogglePolicy::Policy::None); i < static_cast<Toggle_t>(TogglePolicy::Policy::Max); ++i)\r\n        {\r\n            result.emplace_back(GetPolicy(static_cast<Policy>(i)));\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::string SourceFromPolicy::ToJsonString() const\r\n    {\r\n        Json::Value json{ Json::ValueType::objectValue };\r\n        json[\"Name\"] = Name;\r\n        json[\"Type\"] = Type;\r\n        json[\"Arg\"] = Arg;\r\n        json[\"Data\"] = Data;\r\n        json[\"Identifier\"] = Identifier;\r\n        json[\"Explicit\"] = Explicit;\r\n\r\n        if (Priority)\r\n        {\r\n            json[\"Priority\"] = Priority.value();\r\n        }\r\n\r\n        // Trust level is represented as an array of trust level strings since there can be multiple flags set.\r\n        int trustLevelLength = static_cast<int>(TrustLevel.size());\r\n        for (int i = 0; i < trustLevelLength; ++i)\r\n        {\r\n            json[\"TrustLevel\"][i] = TrustLevel[i];\r\n        }\r\n\r\n        Json::StreamWriterBuilder writerBuilder;\r\n        writerBuilder.settings_[\"indentation\"] = \"\";\r\n        return Json::writeString(writerBuilder, json);\r\n    }\r\n\r\n    GroupPolicy::GroupPolicy(const Registry::Key& key)\r\n    {\r\n        ValidateAllValuePolicies(key, m_values, std::make_index_sequence<static_cast<size_t>(ValuePolicy::Max)>());\r\n\r\n        using Toggle_t = std::underlying_type_t<TogglePolicy::Policy>;\r\n        for (Toggle_t i = static_cast<Toggle_t>(TogglePolicy::Policy::None); i < static_cast<Toggle_t>(TogglePolicy::Policy::Max); ++i)\r\n        {\r\n            auto policy = static_cast<TogglePolicy::Policy>(i);\r\n            m_toggles[policy] = GetStateInternal(key, policy);\r\n        }\r\n    }\r\n\r\n    PolicyState GroupPolicy::GetState(TogglePolicy::Policy policy) const\r\n    {\r\n        auto itr = m_toggles.find(policy);\r\n        if (itr == m_toggles.end())\r\n        {\r\n            return PolicyState::NotConfigured;\r\n        }\r\n\r\n        return itr->second;\r\n    }\r\n\r\n    bool GroupPolicy::IsEnabled(TogglePolicy::Policy policy) const\r\n    {\r\n        if (policy == TogglePolicy::Policy::None)\r\n        {\r\n            return true;\r\n        }\r\n\r\n        PolicyState state = GetState(policy);\r\n        if (state == PolicyState::NotConfigured)\r\n        {\r\n            return TogglePolicy::GetPolicy(policy).DefaultIsEnabled();\r\n        }\r\n\r\n        return state == PolicyState::Enabled;\r\n    }\r\n\r\n    GroupPolicy const& GroupPolicy::Instance()\r\n    {\r\n        return InstanceInternal();\r\n    }\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n    void GroupPolicy::OverrideInstance(GroupPolicy* overridePolicy)\r\n    {\r\n        InstanceInternal(overridePolicy);\r\n    }\r\n\r\n    void GroupPolicy::ResetInstance()\r\n    {\r\n        InstanceInternal(nullptr);\r\n    }\r\n#endif\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/ICU/SQLiteICU.c",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include <winsqlite/winsqlite3.h>\n\n// Define values to force static linkage version of extension.\n// The code below the ICU header include should be changed as little as possible.\n#define SQLITE_CORE\n#define SQLITE_ENABLE_ICU\n#define SQLITE_PRIVATE\n#define SQLITE_DIRECTONLY       0x000080000\n#define SQLITE_INNOCUOUS        0x000200000\n\n#define STDCALL_FOR_INTEROP __stdcall\n\n// Adapted from the file icu.c (v 1.7 2007/12/13 21:54:11) to use the built-in Windows SQLite and ICU binaries.\n\n// This file implements an integration between the ICU library\n// (\"International Components for Unicode\", an open-source library\n// for handling unicode data) and SQLite. The integration uses\n// ICU to provide the following to SQLite:\n//\n//   * An implementation of the SQL regexp() function (and hence REGEXP\n//     operator) using the ICU uregex_XX() APIs.\n//\n//   * Implementations of the SQL scalar upper() and lower() functions\n//     for case mapping.\n//\n//   * Integration of ICU and SQLite collation sequences.\n//\n//   * An implementation of the LIKE operator that uses ICU to\n//     provide case-independent matching.\n\n// Include ICU headers\n#include <icu.h>\n\n/* #include <assert.h> */\n#include <assert.h>\n\n#ifndef SQLITE_CORE\n/*   #include \"sqlite3ext.h\" */\nSQLITE_EXTENSION_INIT1\n#else\n/*   #include \"sqlite3.h\" */\n#endif\n\n/*\n** This function is called when an ICU function called from within\n** the implementation of an SQL scalar function returns an error.\n**\n** The scalar function context passed as the first argument is\n** loaded with an error message based on the following two args.\n*/\nstatic void icuFunctionError(\n    sqlite3_context* pCtx,       /* SQLite scalar function context */\n    const char* zName,           /* Name of ICU function that failed */\n    UErrorCode e                 /* Error code returned by ICU function */\n) {\n    char zBuf[128];\n    sqlite3_snprintf(128, zBuf, \"ICU error: %s(): %s\", zName, u_errorName(e));\n    zBuf[127] = '\\0';\n    sqlite3_result_error(pCtx, zBuf, -1);\n}\n\n#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU)\n\n/*\n** Maximum length (in bytes) of the pattern in a LIKE or GLOB\n** operator.\n*/\n#ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH\n# define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000\n#endif\n\n/*\n** Version of sqlite3_free() that is always a function, never a macro.\n*/\nstatic void STDCALL_FOR_INTEROP xFree(void* p) {\n    sqlite3_free(p);\n}\n\n/*\n** This lookup table is used to help decode the first byte of\n** a multi-byte UTF8 character. It is copied here from SQLite source\n** code file utf8.c.\n*/\nstatic const unsigned char icuUtf8Trans1[] = {\n  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,\n  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,\n  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,\n  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,\n  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,\n  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,\n  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,\n  0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00,\n};\n\n#define SQLITE_ICU_READ_UTF8(zIn, c)                       \\\n  c = *(zIn++);                                            \\\n  if( c>=0xc0 ){                                           \\\n    c = icuUtf8Trans1[c-0xc0];                             \\\n    while( (*zIn & 0xc0)==0x80 ){                          \\\n      c = (c<<6) + (0x3f & *(zIn++));                      \\\n    }                                                      \\\n  }\n\n#define SQLITE_ICU_SKIP_UTF8(zIn)                          \\\n  assert( *zIn );                                          \\\n  if( *(zIn++)>=0xc0 ){                                    \\\n    while( (*zIn & 0xc0)==0x80 ){zIn++;}                   \\\n  }\n\n\n/*\n** Compare two UTF-8 strings for equality where the first string is\n** a \"LIKE\" expression. Return true (1) if they are the same and\n** false (0) if they are different.\n*/\nstatic int icuLikeCompare(\n    const uint8_t* zPattern,   /* LIKE pattern */\n    const uint8_t* zString,    /* The UTF-8 string to compare against */\n    const UChar32 uEsc         /* The escape character */\n) {\n    static const uint32_t MATCH_ONE = (uint32_t)'_';\n    static const uint32_t MATCH_ALL = (uint32_t)'%';\n\n    int prevEscape = 0;     /* True if the previous character was uEsc */\n\n    while (1) {\n\n        /* Read (and consume) the next character from the input pattern. */\n        uint32_t uPattern;\n        SQLITE_ICU_READ_UTF8(zPattern, uPattern);\n        if (uPattern == 0) break;\n\n        /* There are now 4 possibilities:\n        **\n        **     1. uPattern is an unescaped match-all character \"%\",\n        **     2. uPattern is an unescaped match-one character \"_\",\n        **     3. uPattern is an unescaped escape character, or\n        **     4. uPattern is to be handled as an ordinary character\n        */\n        if (!prevEscape && uPattern == MATCH_ALL) {\n            /* Case 1. */\n            uint8_t c;\n\n            /* Skip any MATCH_ALL or MATCH_ONE characters that follow a\n            ** MATCH_ALL. For each MATCH_ONE, skip one character in the\n            ** test string.\n            */\n            while ((c = *zPattern) == MATCH_ALL || c == MATCH_ONE) {\n                if (c == MATCH_ONE) {\n                    if (*zString == 0) return 0;\n                    SQLITE_ICU_SKIP_UTF8(zString);\n                }\n                zPattern++;\n            }\n\n            if (*zPattern == 0) return 1;\n\n            while (*zString) {\n                if (icuLikeCompare(zPattern, zString, uEsc)) {\n                    return 1;\n                }\n                SQLITE_ICU_SKIP_UTF8(zString);\n            }\n            return 0;\n\n        }\n        else if (!prevEscape && uPattern == MATCH_ONE) {\n            /* Case 2. */\n            if (*zString == 0) return 0;\n            SQLITE_ICU_SKIP_UTF8(zString);\n\n        }\n        else if (!prevEscape && uPattern == (uint32_t)uEsc) {\n            /* Case 3. */\n            prevEscape = 1;\n\n        }\n        else {\n            /* Case 4. */\n            uint32_t uString;\n            SQLITE_ICU_READ_UTF8(zString, uString);\n            uString = (uint32_t)u_foldCase((UChar32)uString, U_FOLD_CASE_DEFAULT);\n            uPattern = (uint32_t)u_foldCase((UChar32)uPattern, U_FOLD_CASE_DEFAULT);\n            if (uString != uPattern) {\n                return 0;\n            }\n            prevEscape = 0;\n        }\n    }\n\n    return *zString == 0;\n}\n\n/*\n** Implementation of the like() SQL function.  This function implements\n** the build-in LIKE operator.  The first argument to the function is the\n** pattern and the second argument is the string.  So, the SQL statements:\n**\n**       A LIKE B\n**\n** is implemented as like(B, A). If there is an escape character E,\n**\n**       A LIKE B ESCAPE E\n**\n** is mapped to like(B, A, E).\n*/\nstatic void STDCALL_FOR_INTEROP icuLikeFunc(\n    sqlite3_context* context,\n    int argc,\n    sqlite3_value** argv\n) {\n    const unsigned char* zA = sqlite3_value_text(argv[0]);\n    const unsigned char* zB = sqlite3_value_text(argv[1]);\n    UChar32 uEsc = 0;\n\n    /* Limit the length of the LIKE or GLOB pattern to avoid problems\n    ** of deep recursion and N*N behavior in patternCompare().\n    */\n    if (sqlite3_value_bytes(argv[0]) > SQLITE_MAX_LIKE_PATTERN_LENGTH) {\n        sqlite3_result_error(context, \"LIKE or GLOB pattern too complex\", -1);\n        return;\n    }\n\n\n    if (argc == 3) {\n        /* The escape character string must consist of a single UTF-8 character.\n        ** Otherwise, return an error.\n        */\n        int nE = sqlite3_value_bytes(argv[2]);\n        const unsigned char* zE = sqlite3_value_text(argv[2]);\n        int i = 0;\n        if (zE == 0) return;\n        U8_NEXT(zE, i, nE, uEsc);\n        if (i != nE) {\n            sqlite3_result_error(context,\n                \"ESCAPE expression must be a single character\", -1);\n            return;\n        }\n    }\n\n    if (zA && zB) {\n        sqlite3_result_int(context, icuLikeCompare(zA, zB, uEsc));\n    }\n}\n\n/*\n** Function to delete compiled regexp objects. Registered as\n** a destructor function with sqlite3_set_auxdata().\n*/\nstatic void STDCALL_FOR_INTEROP icuRegexpDelete(void* p) {\n    URegularExpression* pExpr = (URegularExpression*)p;\n    uregex_close(pExpr);\n}\n\n/*\n** Implementation of SQLite REGEXP operator. This scalar function takes\n** two arguments. The first is a regular expression pattern to compile\n** the second is a string to match against that pattern. If either\n** argument is an SQL NULL, then NULL Is returned. Otherwise, the result\n** is 1 if the string matches the pattern, or 0 otherwise.\n**\n** SQLite maps the regexp() function to the regexp() operator such\n** that the following two are equivalent:\n**\n**     zString REGEXP zPattern\n**     regexp(zPattern, zString)\n**\n** Uses the following ICU regexp APIs:\n**\n**     uregex_open()\n**     uregex_matches()\n**     uregex_close()\n*/\nstatic void STDCALL_FOR_INTEROP icuRegexpFunc(sqlite3_context* p, int nArg, sqlite3_value** apArg) {\n    UErrorCode status = U_ZERO_ERROR;\n    URegularExpression* pExpr;\n    UBool res;\n    const UChar* zString = sqlite3_value_text16(apArg[1]);\n\n    (void)nArg;  /* Unused parameter */\n\n    /* If the left hand side of the regexp operator is NULL,\n    ** then the result is also NULL.\n    */\n    if (!zString) {\n        return;\n    }\n\n    pExpr = sqlite3_get_auxdata(p, 0);\n    if (!pExpr) {\n        const UChar* zPattern = sqlite3_value_text16(apArg[0]);\n        if (!zPattern) {\n            return;\n        }\n        pExpr = uregex_open(zPattern, -1, 0, 0, &status);\n\n        if (U_SUCCESS(status)) {\n            sqlite3_set_auxdata(p, 0, pExpr, icuRegexpDelete);\n        }\n        else {\n            assert(!pExpr);\n            icuFunctionError(p, \"uregex_open\", status);\n            return;\n        }\n    }\n\n    /* Configure the text that the regular expression operates on. */\n    uregex_setText(pExpr, zString, -1, &status);\n    if (!U_SUCCESS(status)) {\n        icuFunctionError(p, \"uregex_setText\", status);\n        return;\n    }\n\n    /* Attempt the match */\n    res = uregex_matches(pExpr, 0, &status);\n    if (!U_SUCCESS(status)) {\n        icuFunctionError(p, \"uregex_matches\", status);\n        return;\n    }\n\n    /* Set the text that the regular expression operates on to a NULL\n    ** pointer. This is not really necessary, but it is tidier than\n    ** leaving the regular expression object configured with an invalid\n    ** pointer after this function returns.\n    */\n    uregex_setText(pExpr, 0, 0, &status);\n\n    /* Return 1 or 0. */\n    sqlite3_result_int(p, res ? 1 : 0);\n}\n\n/*\n** Implementations of scalar functions for case mapping - upper() and\n** lower(). Function upper() converts its input to upper-case (ABC).\n** Function lower() converts to lower-case (abc).\n**\n** ICU provides two types of case mapping, \"general\" case mapping and\n** \"language specific\". Refer to ICU documentation for the differences\n** between the two.\n**\n** To utilise \"general\" case mapping, the upper() or lower() scalar\n** functions are invoked with one argument:\n**\n**     upper('ABC') -> 'abc'\n**     lower('abc') -> 'ABC'\n**\n** To access ICU \"language specific\" case mapping, upper() or lower()\n** should be invoked with two arguments. The second argument is the name\n** of the locale to use. Passing an empty string (\"\") or SQL NULL value\n** as the second argument is the same as invoking the 1 argument version\n** of upper() or lower().\n**\n**     lower('I', 'en_us') -> 'i'\n**     lower('I', 'tr_tr') -> '\\u131' (small dotless i)\n**\n** http://www.icu-project.org/userguide/posix.html#case_mappings\n*/\nstatic void STDCALL_FOR_INTEROP icuCaseFunc16(sqlite3_context* p, int nArg, sqlite3_value** apArg) {\n    const UChar* zInput;            /* Pointer to input string */\n    UChar* zOutput = 0;             /* Pointer to output buffer */\n    int nInput;                     /* Size of utf-16 input string in bytes */\n    int nOut;                       /* Size of output buffer in bytes */\n    int cnt;\n    int bToUpper;                   /* True for toupper(), false for tolower() */\n    UErrorCode status;\n    const char* zLocale = 0;\n\n    assert(nArg == 1 || nArg == 2);\n    bToUpper = (sqlite3_user_data(p) != 0);\n    if (nArg == 2) {\n        zLocale = (const char*)sqlite3_value_text(apArg[1]);\n    }\n\n    zInput = sqlite3_value_text16(apArg[0]);\n    if (!zInput) {\n        return;\n    }\n    nOut = nInput = sqlite3_value_bytes16(apArg[0]);\n    if (nOut == 0) {\n        sqlite3_result_text16(p, \"\", 0, SQLITE_STATIC);\n        return;\n    }\n\n    for (cnt = 0; cnt < 2; cnt++) {\n        UChar* zNew = sqlite3_realloc(zOutput, nOut);\n        if (zNew == 0) {\n            sqlite3_free(zOutput);\n            sqlite3_result_error_nomem(p);\n            return;\n        }\n        zOutput = zNew;\n        status = U_ZERO_ERROR;\n        if (bToUpper) {\n            nOut = 2 * u_strToUpper(zOutput, nOut / 2, zInput, nInput / 2, zLocale, &status);\n        }\n        else {\n            nOut = 2 * u_strToLower(zOutput, nOut / 2, zInput, nInput / 2, zLocale, &status);\n        }\n\n        if (U_SUCCESS(status)) {\n            sqlite3_result_text16(p, zOutput, nOut, xFree);\n        }\n        else if (status == U_BUFFER_OVERFLOW_ERROR) {\n            assert(cnt == 0);\n            continue;\n        }\n        else {\n            icuFunctionError(p, bToUpper ? \"u_strToUpper\" : \"u_strToLower\", status);\n        }\n        return;\n    }\n    assert(0);     /* Unreachable */\n}\n\n#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) */\n\n/*\n** Collation sequence destructor function. The pCtx argument points to\n** a UCollator structure previously allocated using ucol_open().\n*/\nstatic void STDCALL_FOR_INTEROP icuCollationDel(void* pCtx) {\n    UCollator* p = (UCollator*)pCtx;\n    ucol_close(p);\n}\n\n/*\n** Collation sequence comparison function. The pCtx argument points to\n** a UCollator structure previously allocated using ucol_open().\n*/\nstatic int STDCALL_FOR_INTEROP icuCollationColl(\n    void* pCtx,\n    int nLeft,\n    const void* zLeft,\n    int nRight,\n    const void* zRight\n) {\n    UCollationResult res;\n    UCollator* p = (UCollator*)pCtx;\n    res = ucol_strcoll(p, (UChar*)zLeft, nLeft / 2, (UChar*)zRight, nRight / 2);\n    switch (res) {\n    case UCOL_LESS:    return -1;\n    case UCOL_GREATER: return +1;\n    case UCOL_EQUAL:   return 0;\n    }\n    assert(!\"Unexpected return value from ucol_strcoll()\");\n    return 0;\n}\n\n/*\n** Implementation of the scalar function icu_load_collation().\n**\n** This scalar function is used to add ICU collation based collation\n** types to an SQLite database connection. It is intended to be called\n** as follows:\n**\n**     SELECT icu_load_collation(<locale>, <collation-name>);\n**\n** Where <locale> is a string containing an ICU locale identifier (i.e.\n** \"en_AU\", \"tr_TR\" etc.) and <collation-name> is the name of the\n** collation sequence to create.\n*/\nstatic void STDCALL_FOR_INTEROP icuLoadCollation(\n    sqlite3_context* p,\n    int nArg,\n    sqlite3_value** apArg\n) {\n    sqlite3* db = (sqlite3*)sqlite3_user_data(p);\n    UErrorCode status = U_ZERO_ERROR;\n    const char* zLocale;      /* Locale identifier - (eg. \"jp_JP\") */\n    const char* zName;        /* SQL Collation sequence name (eg. \"japanese\") */\n    UCollator* pUCollator;    /* ICU library collation object */\n    int rc;                   /* Return code from sqlite3_create_collation_x() */\n\n    assert(nArg == 2);\n    (void)nArg; /* Unused parameter */\n    zLocale = (const char*)sqlite3_value_text(apArg[0]);\n    zName = (const char*)sqlite3_value_text(apArg[1]);\n\n    if (!zLocale || !zName) {\n        return;\n    }\n\n    pUCollator = ucol_open(zLocale, &status);\n    if (!U_SUCCESS(status)) {\n        icuFunctionError(p, \"ucol_open\", status);\n        return;\n    }\n    assert(p);\n\n    rc = sqlite3_create_collation_v2(db, zName, SQLITE_UTF16, (void*)pUCollator,\n        icuCollationColl, icuCollationDel\n    );\n    if (rc != SQLITE_OK) {\n        ucol_close(pUCollator);\n        sqlite3_result_error(p, \"Error registering collation function\", -1);\n    }\n}\n\n/*\n** Register the ICU extension functions with database db.\n*/\nSQLITE_PRIVATE int sqlite3IcuInit(sqlite3* db) {\n# define SQLITEICU_EXTRAFLAGS (SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS)\n    static const struct IcuScalar {\n        const char* zName;                        /* Function name */\n        unsigned char nArg;                       /* Number of arguments */\n        unsigned int enc;                         /* Optimal text encoding */\n        unsigned char iContext;                   /* sqlite3_user_data() context */\n        void (STDCALL_FOR_INTEROP *xFunc)(sqlite3_context*, int, sqlite3_value**);\n    } scalars[] = {\n      {\"icu_load_collation\",2,SQLITE_UTF8 | SQLITE_DIRECTONLY,1, icuLoadCollation},\n  #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU)\n      {\"regexp\", 2, SQLITE_ANY | SQLITEICU_EXTRAFLAGS,         0, icuRegexpFunc},\n      {\"lower\",  1, SQLITE_UTF16 | SQLITEICU_EXTRAFLAGS,       0, icuCaseFunc16},\n      {\"lower\",  2, SQLITE_UTF16 | SQLITEICU_EXTRAFLAGS,       0, icuCaseFunc16},\n      {\"upper\",  1, SQLITE_UTF16 | SQLITEICU_EXTRAFLAGS,       1, icuCaseFunc16},\n      {\"upper\",  2, SQLITE_UTF16 | SQLITEICU_EXTRAFLAGS,       1, icuCaseFunc16},\n      {\"lower\",  1, SQLITE_UTF8 | SQLITEICU_EXTRAFLAGS,        0, icuCaseFunc16},\n      {\"lower\",  2, SQLITE_UTF8 | SQLITEICU_EXTRAFLAGS,        0, icuCaseFunc16},\n      {\"upper\",  1, SQLITE_UTF8 | SQLITEICU_EXTRAFLAGS,        1, icuCaseFunc16},\n      {\"upper\",  2, SQLITE_UTF8 | SQLITEICU_EXTRAFLAGS,        1, icuCaseFunc16},\n      {\"like\",   2, SQLITE_UTF8 | SQLITEICU_EXTRAFLAGS,        0, icuLikeFunc},\n      {\"like\",   3, SQLITE_UTF8 | SQLITEICU_EXTRAFLAGS,        0, icuLikeFunc},\n  #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) */\n    };\n    int rc = SQLITE_OK;\n    int i;\n\n    for (i = 0; rc == SQLITE_OK && i < (int)(sizeof(scalars) / sizeof(scalars[0])); i++) {\n        const struct IcuScalar* p = &scalars[i];\n        rc = sqlite3_create_function(\n            db, p->zName, p->nArg, p->enc,\n            p->iContext ? (void*)db : (void*)0,\n            p->xFunc, 0, 0\n        );\n    }\n\n    return rc;\n}\n\n#ifndef SQLITE_CORE\n#ifdef _WIN32\n__declspec(dllexport)\n#endif\nSQLITE_API int sqlite3_icu_init(\n    sqlite3* db,\n    char** pzErrMsg,\n    const sqlite3_api_routines* pApi\n) {\n    SQLITE_EXTENSION_INIT2(pApi)\n        return sqlite3IcuInit(db);\n}\n#endif\n\n/************** End of icu.c *************************************************/"
  },
  {
    "path": "src/AppInstallerSharedLib/ICU/SQLiteICU.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winsqlite/winsqlite3.h>\r\n\r\n// Adapted from the file sqliteicu.h to use the built-in Windows SQLite and ICU binaries.\r\n\r\nextern \"C\"\r\n{\r\n    int sqlite3IcuInit(sqlite3* db);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/JsonSchemaValidation.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"winget/JsonSchemaValidation.h\"\r\n#include \"winget/Resources.h\"\r\n\r\nnamespace AppInstaller::JsonSchema\r\n{\r\n    Json::Value LoadSchemaDoc(std::string_view schemaStr)\r\n    {\r\n        Json::Value schemaJson;\r\n        int schemaLength = static_cast<int>(schemaStr.length());\r\n        Json::CharReaderBuilder charReaderBuilder;\r\n        const std::unique_ptr<Json::CharReader> jsonReader(charReaderBuilder.newCharReader());\r\n        std::string errorMsg;\r\n        if (!jsonReader->parse(schemaStr.data(), schemaStr.data() + schemaLength, &schemaJson, &errorMsg))\r\n        {\r\n            THROW_HR_MSG(E_UNEXPECTED, \"Jsoncpp parser failed to parse the schema doc. Reason: %hs\", errorMsg.c_str());\r\n        }\r\n\r\n        return schemaJson;\r\n    }\r\n\r\n    Json::Value LoadResourceAsSchemaDoc(PCWSTR resourceName, PCWSTR resourceType)\r\n    {\r\n        return LoadSchemaDoc(Resource::GetResourceAsString(resourceName, resourceType));\r\n    }\r\n\r\n    void PopulateSchema(const Json::Value& schemaJson, valijson::Schema& schema)\r\n    {\r\n        valijson::SchemaParser schemaParser;\r\n        valijson::adapters::JsonCppAdapter jsonSchemaAdapter(schemaJson);\r\n        schemaParser.populateSchema(jsonSchemaAdapter, schema);\r\n    }\r\n\r\n    bool Validate(const valijson::Schema& schema, const Json::Value& json, valijson::ValidationResults& results)\r\n    {\r\n        valijson::Validator schemaValidator;\r\n        valijson::adapters::JsonCppAdapter jsonAdapter(json);\r\n        return schemaValidator.validate(schema, jsonAdapter, &results);\r\n    }\r\n\r\n    std::string GetErrorStringFromResults(valijson::ValidationResults& results)\r\n    {\r\n        valijson::ValidationResults::Error error;\r\n        std::stringstream ss;\r\n\r\n        ss << \"Schema validation failed.\" << std::endl;\r\n        while (results.popError(error))\r\n        {\r\n            std::string context;\r\n            for (auto itr = error.context.begin(); itr != error.context.end(); itr++)\r\n            {\r\n                context += *itr;\r\n            }\r\n\r\n            ss << \"Error context: \" << context << \" Description: \" << error.description << std::endl;\r\n        }\r\n\r\n        return ss.str();\r\n    }\r\n}"
  },
  {
    "path": "src/AppInstallerSharedLib/JsonUtil.cpp",
    "content": "// Copyright(c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"winget/JsonUtil.h\"\n#include \"AppInstallerStrings.h\"\n\nnamespace AppInstaller::JSON\n{\n    template<>\n    std::optional<std::string> GetValue(const Json::Value& node)\n    {\n        std::optional<std::string> value;\n\n        if (node.isString())\n        {\n            value = node.asString();\n        }\n\n        return value;\n    }\n\n    template<>\n    std::optional<uint32_t> GetValue(const Json::Value& node)\n    {\n        std::optional<uint32_t> value;\n\n        if (node.isUInt())\n        {\n            value = node.asUInt();\n        }\n\n        return value;\n    }\n\n    template<>\n    std::optional<bool> GetValue(const Json::Value& node)\n    {\n        std::optional<bool> value;\n\n        if (node.isBool())\n        {\n            value = node.asBool();\n        }\n\n        return value;\n    }\n\n    template<>\n    std::optional<std::vector<std::string>> GetValue(const Json::Value& node)\n    {\n        std::vector<std::string> result;\n\n        if (node.isArray())\n        {\n            for (const Json::Value& entry : node)\n            {\n                if (!entry.isString())\n                {\n                    return std::nullopt;\n                }\n\n                result.emplace_back(entry.asString());\n            }\n\n            return result;\n        }\n\n        return std::nullopt;\n    }\n\n#ifndef WINGET_DISABLE_FOR_FUZZING\n    utility::string_t GetUtilityString(std::string_view nodeName)\n    {\n        return utility::conversions::to_string_t(nodeName.data());\n    }\n\n    web::json::value GetStringValue(std::string_view value)\n    {\n        return web::json::value::string(Utility::ConvertToUTF16(value));\n    }\n\n    std::optional<std::reference_wrapper<const web::json::value>> GetJsonValueFromNode(const web::json::value& node, const utility::string_t& keyName)\n    {\n        if (node.is_null() || !node.has_field(keyName))\n        {\n            return {};\n        }\n\n        return node.at(keyName);\n    }\n\n    std::optional<std::string> GetRawStringValueFromJsonValue(const web::json::value& value)\n    {\n        if (value.is_null() || !value.is_string())\n        {\n            return {};\n        }\n\n        return utility::conversions::to_utf8string(value.as_string());\n    }\n\n    std::optional<std::wstring> GetWideStringValueFromJsonValue(const web::json::value& value)\n    {\n        if (value.is_null() || !value.is_string())\n        {\n            return {};\n        }\n\n        return value.as_string();\n    }\n\n    std::optional<std::string> GetRawStringValueFromJsonNode(const web::json::value& node, const utility::string_t& keyName)\n    {\n        std::optional<std::reference_wrapper<const web::json::value>> jsonValue = GetJsonValueFromNode(node, keyName);\n\n        if (jsonValue)\n        {\n            return GetRawStringValueFromJsonValue(jsonValue.value().get());\n        }\n\n        return {};\n    }\n\n    std::optional<std::wstring> GetWideStringValueFromJsonNode(const web::json::value& node, const utility::string_t& keyName)\n    {\n        std::optional<std::reference_wrapper<const web::json::value>> jsonValue = GetJsonValueFromNode(node, keyName);\n\n        if (jsonValue)\n        {\n            return GetWideStringValueFromJsonValue(jsonValue.value().get());\n        }\n\n        return {};\n    }\n\n    std::optional<int> GetRawIntValueFromJsonValue(const web::json::value& value)\n    {\n        if (value.is_null() || !value.is_integer())\n        {\n            return {};\n        }\n\n        return value.as_integer();\n    }\r\n\n    std::optional<uint64_t> GetRawUInt64ValueFromJsonValue(const web::json::value& value)\r\n    {\n        if (value.is_null() || !value.is_number())\n        {\n            return {};\n        }\n\r\n        const web::json::number& valueNumber = value.as_number();\r\n\r\n        if (!valueNumber.is_uint64())\r\n        {\r\n            return {};\r\n        }\r\n\n        return valueNumber.to_uint64();\n    }\n\n    std::optional<int> GetRawIntValueFromJsonNode(const web::json::value& node, const utility::string_t& keyName)\n    {\n        std::optional<std::reference_wrapper<const web::json::value>> jsonValue = GetJsonValueFromNode(node, keyName);\n\n        if (jsonValue)\n        {\n            return GetRawIntValueFromJsonValue(jsonValue.value().get());\n        }\n\n        return {};\n    }\r\n\n    std::optional<uint64_t> GetRawUInt64ValueFromJsonNode(const web::json::value& node, const utility::string_t& keyName)\r\n    {\n        std::optional<std::reference_wrapper<const web::json::value>> jsonValue = GetJsonValueFromNode(node, keyName);\n\n        if (jsonValue)\n        {\n            return GetRawUInt64ValueFromJsonValue(jsonValue.value().get());\n        }\n\n        return {};\n    }\n\n    std::optional<bool> GetRawBoolValueFromJsonValue(const web::json::value& value)\n    {\n        if (value.is_null() || !value.is_boolean())\n        {\n            return {};\n        }\n\n        return value.as_bool();\n    }\n\n    std::optional<bool> GetRawBoolValueFromJsonNode(const web::json::value& node, const utility::string_t& keyName)\n    {\n        std::optional<std::reference_wrapper<const web::json::value>> jsonValue = GetJsonValueFromNode(node, keyName);\n\n        if (jsonValue)\n        {\n            return GetRawBoolValueFromJsonValue(jsonValue.value().get());\n        }\n\n        return {};\n    }\n\n    std::optional<std::reference_wrapper<const web::json::array>> GetRawJsonArrayFromJsonNode(const web::json::value& node, const utility::string_t& keyName)\n    {\n        std::optional<std::reference_wrapper<const web::json::value>> jsonValue = GetJsonValueFromNode(node, keyName);\n\n        if (!jsonValue || !jsonValue.value().get().is_array())\n        {\n            return {};\n        }\n\n        return jsonValue.value().get().as_array();\n    }\n\n    std::vector<std::string> GetRawStringArrayFromJsonNode(\n        const web::json::value& node, const utility::string_t& keyName)\n    {\n        std::optional<std::reference_wrapper<const web::json::array>> arrayValue = GetRawJsonArrayFromJsonNode(node, keyName);\n\n        std::vector<std::string> result;\n        if (!arrayValue)\n        {\n            return result;\n        }\n\n        for (auto& value : arrayValue.value().get())\n        {\n            std::optional<std::string> item = GetRawStringValueFromJsonValue(value);\n            if (item)\n            {\n                result.emplace_back(std::move(item.value()));\n            }\n        }\n\n        return result;\n    }\n\n    std::set<std::string> GetRawStringSetFromJsonNode(\n        const web::json::value& node, const utility::string_t& keyName)\n    {\n        std::optional<std::reference_wrapper<const web::json::array>> arrayValue = GetRawJsonArrayFromJsonNode(node, keyName);\n\n        std::set<std::string> result;\n        if (!arrayValue)\n        {\n            return result;\n        }\n\n        for (auto& value : arrayValue.value().get())\n        {\n            std::optional<std::string> item = GetRawStringValueFromJsonValue(value);\n            if (item)\n            {\n                result.emplace(std::move(item.value()));\n            }\n        }\n\n        return result;\n    }\n\n    std::string Base64Encode(const std::vector<BYTE>& input)\n    {\n        if (input.size() == 0)\n        {\n            return {};\n        }\n\n        std::wstring result;\n        DWORD resultSize = 0;\n        CryptBinaryToStringW(input.data(), static_cast<DWORD>(input.size()), CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, nullptr, &resultSize);\n        THROW_LAST_ERROR_IF(resultSize == 0);\n\n        result.resize(resultSize);\n        THROW_LAST_ERROR_IF(!CryptBinaryToStringW(input.data(), static_cast<DWORD>(input.size()), CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, result.data(), &resultSize));\n        // Resize to remove trailing null terminator\n        result.resize(resultSize);\n\n        return Utility::ConvertToUTF8(result);\n    }\n\n    std::vector<BYTE> Base64Decode(const std::string& input)\n    {\n        if (input.empty())\n        {\n            return {};\n        }\n\n        auto inputWide = Utility::ConvertToUTF16(input);\n\n        std::vector<BYTE> result;\n        DWORD resultSize = 0;\n        CryptStringToBinaryW(inputWide.data(), static_cast<DWORD>(inputWide.size()), CRYPT_STRING_BASE64, nullptr, &resultSize, nullptr, nullptr);\n        THROW_LAST_ERROR_IF(resultSize == 0);\n\n        result.resize(resultSize);\n        THROW_LAST_ERROR_IF(!CryptStringToBinaryW(inputWide.data(), static_cast<DWORD>(inputWide.size()), CRYPT_STRING_BASE64, result.data(), &resultSize, nullptr, nullptr));\n\n        return result;\n    }\n#endif\n\n    bool IsValidNonEmptyStringValue(std::optional<std::string>& value)\n    {\n        if (Utility::IsEmptyOrWhitespace(value.value_or(\"\")))\n        {\n            return false;\n        }\n\n        return true;\n    }\n\n    bool IsValidNonEmptyStringValue(std::optional<std::wstring>& value)\n    {\n        if (Utility::IsEmptyOrWhitespace(value.value_or(L\"\")))\n        {\n            return false;\n        }\n\n        return true;\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerSharedLib/ManagedFile.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"winget/ManagedFile.h\"\r\n#include \"AppInstallerLogging.h\"\r\n\r\nnamespace AppInstaller::Utility\r\n{\r\n    ManagedFile ManagedFile::CreateWriteLockedFile(const std::filesystem::path& path, DWORD desiredAccess, bool deleteOnExit)\r\n    {\r\n        ManagedFile file;\r\n        file.m_fileHandle.reset(CreateFileW(path.c_str(), desiredAccess, FILE_SHARE_READ, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr));\r\n        THROW_LAST_ERROR_IF(!file.m_fileHandle);\r\n        file.m_filePath = path;\r\n        file.m_deleteFileOnExit = deleteOnExit;\r\n\r\n        return file;\r\n    }\r\n\r\n    ManagedFile ManagedFile::OpenWriteLockedFile(const std::filesystem::path& path, DWORD desiredAccess)\r\n    {\r\n        ManagedFile file;\r\n        file.m_fileHandle.reset(CreateFileW(path.c_str(), desiredAccess, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr));\r\n        THROW_LAST_ERROR_IF(!file.m_fileHandle);\r\n        file.m_filePath = path;\r\n\r\n        return file;\r\n    }\r\n\r\n    ManagedFile::~ManagedFile()\r\n    {\r\n        if (m_deleteFileOnExit)\r\n        {\r\n            if (m_fileHandle)\r\n            {\r\n                m_fileHandle.reset();\r\n            }\r\n\r\n            try\r\n            {\r\n                std::filesystem::remove(m_filePath);\r\n            }\r\n            catch (...)\r\n            {\r\n                AICLI_LOG(Core, Info, << \"Failed to remove managed file at: \" << m_filePath);\r\n            }\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "src/AppInstallerSharedLib/PropertySheet.props",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ImportGroup Label=\"PropertySheets\" />\n  <PropertyGroup Label=\"UserMacros\" />\n    <!--\n    To customize common C++/WinRT project properties: \n    * right-click the project node\n    * expand the Common Properties item\n    * select the C++/WinRT property page\n\n    For more advanced scenarios, and complete documentation, please see:\n    https://github.com/Microsoft/xlang/tree/master/src/package/cppwinrt/nuget \n    -->\n  <PropertyGroup />\n  <ItemDefinitionGroup />\n</Project>"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/AppInstallerDateTime.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerVersions.h>\r\n#include <chrono>\r\n#include <ostream>\r\n\r\nnamespace AppInstaller::Utility\r\n{\r\n    // The individual aspects of a time point.\r\n    enum class TimeFacet\r\n    {\r\n        None        = 0x000,\r\n        Millisecond = 0x001,\r\n        Second      = 0x002,\r\n        Minute      = 0x004,\r\n        Hour        = 0x008,\r\n        Day         = 0x010,\r\n        Month       = 0x020,\r\n        Year        = 0x040,\r\n        // `Year - 2000` [2 digits for 75 more years]\r\n        ShortYear   = 0x080,\r\n        // Includes unspecified time zone\r\n        RFC3339     = 0x100,\r\n        // Limits special character use\r\n        Filename    = 0x200,\r\n\r\n        Default = Year | Month | Day | Hour | Minute | Second | Millisecond,\r\n        ShortYearSecondPrecision = ShortYear | Month | Day | Hour | Minute | Second,\r\n    };\r\n\r\n    DEFINE_ENUM_FLAG_OPERATORS(TimeFacet);\r\n\r\n    // Writes the given time to the given stream.\r\n    // Assumes that system_clock uses Linux epoch (as required by C++20 standard).\r\n    // Time is also assumed to be after the epoch.\r\n    void OutputTimePoint(std::ostream& stream, const std::chrono::system_clock::time_point& time, bool useRFC3339 = false);\r\n    void OutputTimePoint(std::ostream& stream, const std::chrono::system_clock::time_point& time, TimeFacet facet);\r\n\r\n    // Converts the time point to a string using OutputTimePoint.\r\n    std::string TimePointToString(const std::chrono::system_clock::time_point& time, bool useRFC3339 = false);\r\n    std::string TimePointToString(const std::chrono::system_clock::time_point& time, TimeFacet facet);\r\n\r\n    // Gets the current time as a string. Can be used as a file name.\r\n    // Tries to make things a little bit shorter when shortTime == true.\r\n    std::string GetCurrentTimeForFilename(bool shortTime = false);\r\n\r\n    // Gets the current date as a string to be used in the ARP registry.\r\n    std::string GetCurrentDateForARP();\r\n\r\n    // Gets the current time as a unix epoch value.\r\n    int64_t GetCurrentUnixEpoch();\r\n\r\n    // Converts the given unix epoch time to a system_clock::time_point.\r\n    int64_t ConvertSystemClockToUnixEpoch(const std::chrono::system_clock::time_point& time);\r\n\r\n    // Converts the given unix epoch time to a system_clock::time_point.\r\n    std::chrono::system_clock::time_point ConvertUnixEpochToSystemClock(int64_t epoch);\r\n\r\n    // Converts the given file time to a system_clock::time_point.\r\n    std::chrono::system_clock::time_point ConvertFiletimeToSystemClock(const FILETIME& fileTime);\r\n\r\n    // Converts the given package version into a time_point using our custom format.\r\n    // Ensure that the package is expected to use this format, or you may get strange times.\r\n    // If the version is not convertable, the minimum time is returned.\r\n    std::chrono::system_clock::time_point GetTimePointFromVersion(const UInt64Version& version);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/AppInstallerErrors.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/LocIndependent.h>\r\n#include <wil/result_macros.h>\r\n\r\n// Errors is the most ubiquitous header; including the mismatch detection in it should reach everywhere.\r\n#include <winget/DetectMismatch.h>\r\n\r\n#ifndef WINGET_DISABLE_FOR_FUZZING\r\n#include <winrt/base.h>\r\n#endif\r\n\r\n#include <exception>\r\n#include <memory>\r\n#include <string>\r\n#include <utility>\r\n#include <vector>\r\n\r\n\r\n#define APPINSTALLER_CLI_ERROR_FACILITY 0xA15\r\n\r\n// Changes to any of these errors require the corresponding resource string in winget.resw to be updated.\r\n#define APPINSTALLER_CLI_ERROR_INTERNAL_ERROR                       ((HRESULT)0x8A150001)\r\n#define APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS                 ((HRESULT)0x8A150002)\r\n#define APPINSTALLER_CLI_ERROR_COMMAND_FAILED                       ((HRESULT)0x8A150003)\r\n#define APPINSTALLER_CLI_ERROR_MANIFEST_FAILED                      ((HRESULT)0x8A150004)\r\n#define APPINSTALLER_CLI_ERROR_CTRL_SIGNAL_RECEIVED                 ((HRESULT)0x8A150005)\r\n#define APPINSTALLER_CLI_ERROR_SHELLEXEC_INSTALL_FAILED             ((HRESULT)0x8A150006)\r\n#define APPINSTALLER_CLI_ERROR_UNSUPPORTED_MANIFESTVERSION          ((HRESULT)0x8A150007)\r\n#define APPINSTALLER_CLI_ERROR_DOWNLOAD_FAILED                      ((HRESULT)0x8A150008)\r\n#define APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX        ((HRESULT)0x8A150009)\r\n#define APPINSTALLER_CLI_ERROR_INDEX_INTEGRITY_COMPROMISED          ((HRESULT)0x8A15000A)\r\n#define APPINSTALLER_CLI_ERROR_SOURCES_INVALID                      ((HRESULT)0x8A15000B)\r\n#define APPINSTALLER_CLI_ERROR_SOURCE_NAME_ALREADY_EXISTS           ((HRESULT)0x8A15000C)\r\n#define APPINSTALLER_CLI_ERROR_INVALID_SOURCE_TYPE                  ((HRESULT)0x8A15000D)\r\n#define APPINSTALLER_CLI_ERROR_PACKAGE_IS_BUNDLE                    ((HRESULT)0x8A15000E)\r\n#define APPINSTALLER_CLI_ERROR_SOURCE_DATA_MISSING                  ((HRESULT)0x8A15000F)\r\n#define APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER              ((HRESULT)0x8A150010)\r\n#define APPINSTALLER_CLI_ERROR_INSTALLER_HASH_MISMATCH              ((HRESULT)0x8A150011)\r\n#define APPINSTALLER_CLI_ERROR_SOURCE_NAME_DOES_NOT_EXIST           ((HRESULT)0x8A150012)\r\n#define APPINSTALLER_CLI_ERROR_SOURCE_ARG_ALREADY_EXISTS            ((HRESULT)0x8A150013)\r\n#define APPINSTALLER_CLI_ERROR_NO_APPLICATIONS_FOUND                ((HRESULT)0x8A150014)\r\n#define APPINSTALLER_CLI_ERROR_NO_SOURCES_DEFINED                   ((HRESULT)0x8A150015)\r\n#define APPINSTALLER_CLI_ERROR_MULTIPLE_APPLICATIONS_FOUND          ((HRESULT)0x8A150016)\r\n#define APPINSTALLER_CLI_ERROR_NO_MANIFEST_FOUND                    ((HRESULT)0x8A150017)\r\n#define APPINSTALLER_CLI_ERROR_EXTENSION_PUBLIC_FAILED              ((HRESULT)0x8A150018)\r\n#define APPINSTALLER_CLI_ERROR_COMMAND_REQUIRES_ADMIN               ((HRESULT)0x8A150019)\r\n#define APPINSTALLER_CLI_ERROR_SOURCE_NOT_SECURE                    ((HRESULT)0x8A15001A)\r\n#define APPINSTALLER_CLI_ERROR_MSSTORE_BLOCKED_BY_POLICY            ((HRESULT)0x8A15001B)\r\n#define APPINSTALLER_CLI_ERROR_MSSTORE_APP_BLOCKED_BY_POLICY        ((HRESULT)0x8A15001C)\r\n#define APPINSTALLER_CLI_ERROR_EXPERIMENTAL_FEATURE_DISABLED        ((HRESULT)0x8A15001D)\r\n#define APPINSTALLER_CLI_ERROR_MSSTORE_INSTALL_FAILED               ((HRESULT)0x8A15001E)\r\n#define APPINSTALLER_CLI_ERROR_COMPLETE_INPUT_BAD                   ((HRESULT)0x8A15001F)\r\n#define APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED                     ((HRESULT)0x8A150020)\r\n#define APPINSTALLER_CLI_ERROR_YAML_INVALID_MAPPING_KEY             ((HRESULT)0x8A150021)\r\n#define APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY           ((HRESULT)0x8A150022)\r\n#define APPINSTALLER_CLI_ERROR_YAML_INVALID_OPERATION               ((HRESULT)0x8A150023)\r\n#define APPINSTALLER_CLI_ERROR_YAML_DOC_BUILD_FAILED                ((HRESULT)0x8A150024)\r\n#define APPINSTALLER_CLI_ERROR_YAML_INVALID_EMITTER_STATE           ((HRESULT)0x8A150025)\r\n#define APPINSTALLER_CLI_ERROR_YAML_INVALID_DATA                    ((HRESULT)0x8A150026)\r\n#define APPINSTALLER_CLI_ERROR_LIBYAML_ERROR                        ((HRESULT)0x8A150027)\r\n#define APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_WARNING          ((HRESULT)0x8A150028)\r\n#define APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_FAILURE          ((HRESULT)0x8A150029)\r\n#define APPINSTALLER_CLI_ERROR_INVALID_MANIFEST                     ((HRESULT)0x8A15002A)\r\n#define APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE                ((HRESULT)0x8A15002B)\r\n#define APPINSTALLER_CLI_ERROR_UPDATE_ALL_HAS_FAILURE               ((HRESULT)0x8A15002C)\r\n#define APPINSTALLER_CLI_ERROR_INSTALLER_SECURITY_CHECK_FAILED      ((HRESULT)0x8A15002D)\r\n#define APPINSTALLER_CLI_ERROR_DOWNLOAD_SIZE_MISMATCH               ((HRESULT)0x8A15002E)\r\n#define APPINSTALLER_CLI_ERROR_NO_UNINSTALL_INFO_FOUND              ((HRESULT)0x8A15002F)\r\n#define APPINSTALLER_CLI_ERROR_EXEC_UNINSTALL_COMMAND_FAILED        ((HRESULT)0x8A150030)\r\n#define APPINSTALLER_CLI_ERROR_ICU_BREAK_ITERATOR_ERROR             ((HRESULT)0x8A150031)\r\n#define APPINSTALLER_CLI_ERROR_ICU_CASEMAP_ERROR                    ((HRESULT)0x8A150032)\r\n#define APPINSTALLER_CLI_ERROR_ICU_REGEX_ERROR                      ((HRESULT)0x8A150033)\r\n#define APPINSTALLER_CLI_ERROR_IMPORT_INSTALL_FAILED                ((HRESULT)0x8A150034)\r\n#define APPINSTALLER_CLI_ERROR_NOT_ALL_PACKAGES_FOUND               ((HRESULT)0x8A150035)\r\n#define APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE                    ((HRESULT)0x8A150036)\r\n#define APPINSTALLER_CLI_ERROR_SOURCE_NOT_REMOTE                    ((HRESULT)0x8A150037)\r\n#define APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE               ((HRESULT)0x8A150038)\r\n#define APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA              ((HRESULT)0x8A150039)\r\n#define APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY                    ((HRESULT)0x8A15003A)\r\n#define APPINSTALLER_CLI_ERROR_RESTAPI_INTERNAL_ERROR               ((HRESULT)0x8A15003B)\r\n#define APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_URL               ((HRESULT)0x8A15003C)\r\n#define APPINSTALLER_CLI_ERROR_RESTAPI_UNSUPPORTED_MIME_TYPE        ((HRESULT)0x8A15003D)\r\n#define APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_VERSION           ((HRESULT)0x8A15003E)\r\n#define APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE        ((HRESULT)0x8A15003F)\r\n#define APPINSTALLER_CLI_ERROR_STREAM_READ_FAILURE                  ((HRESULT)0x8A150040)\r\n#define APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED      ((HRESULT)0x8A150041)\r\n#define APPINSTALLER_CLI_ERROR_PROMPT_INPUT_ERROR                   ((HRESULT)0x8A150042)\r\n#define APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST           ((HRESULT)0x8A150043)\r\n#define APPINSTALLER_CLI_ERROR_RESTAPI_ENDPOINT_NOT_FOUND           ((HRESULT)0x8A150044)\r\n#define APPINSTALLER_CLI_ERROR_SOURCE_OPEN_FAILED                   ((HRESULT)0x8A150045)\r\n#define APPINSTALLER_CLI_ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED       ((HRESULT)0x8A150046)\r\n#define APPINSTALLER_CLI_ERROR_CUSTOMHEADER_EXCEEDS_MAXLENGTH       ((HRESULT)0x8A150047)\r\n#define APPINSTALLER_CLI_ERROR_MISSING_RESOURCE_FILE                ((HRESULT)0x8A150048)\r\n#define APPINSTALLER_CLI_ERROR_MSI_INSTALL_FAILED                   ((HRESULT)0x8A150049)\r\n#define APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT             ((HRESULT)0x8A15004A)\r\n#define APPINSTALLER_CLI_ERROR_FAILED_TO_OPEN_ALL_SOURCES           ((HRESULT)0x8A15004B)\r\n#define APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED       ((HRESULT)0x8A15004C)\r\n#define APPINSTALLER_CLI_ERROR_MISSING_PACKAGE                      ((HRESULT)0x8A15004D)\r\n#define APPINSTALLER_CLI_ERROR_INVALID_TABLE_COLUMN                 ((HRESULT)0x8A15004E)\r\n#define APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_NOT_NEWER            ((HRESULT)0x8A15004F)\r\n#define APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_UNKNOWN              ((HRESULT)0x8A150050)\r\n#define APPINSTALLER_CLI_ERROR_ICU_CONVERSION_ERROR                 ((HRESULT)0x8A150051)\r\n#define APPINSTALLER_CLI_ERROR_PORTABLE_INSTALL_FAILED              ((HRESULT)0x8A150052)\r\n#define APPINSTALLER_CLI_ERROR_PORTABLE_REPARSE_POINT_NOT_SUPPORTED ((HRESULT)0x8A150053)\r\n#define APPINSTALLER_CLI_ERROR_PORTABLE_PACKAGE_ALREADY_EXISTS      ((HRESULT)0x8A150054)\r\n#define APPINSTALLER_CLI_ERROR_PORTABLE_SYMLINK_PATH_IS_DIRECTORY   ((HRESULT)0x8A150055)\r\n#define APPINSTALLER_CLI_ERROR_INSTALLER_PROHIBITS_ELEVATION        ((HRESULT)0x8A150056)\r\n#define APPINSTALLER_CLI_ERROR_PORTABLE_UNINSTALL_FAILED            ((HRESULT)0x8A150057)\r\n#define APPINSTALLER_CLI_ERROR_ARP_VERSION_VALIDATION_FAILED        ((HRESULT)0x8A150058)\r\n#define APPINSTALLER_CLI_ERROR_UNSUPPORTED_ARGUMENT                 ((HRESULT)0x8A150059)\r\n#define APPINSTALLER_CLI_ERROR_BIND_WITH_EMBEDDED_NULL              ((HRESULT)0x8A15005A)\r\n#define APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_NOT_FOUND            ((HRESULT)0x8A15005B)\r\n#define APPINSTALLER_CLI_ERROR_EXTRACT_ARCHIVE_FAILED               ((HRESULT)0x8A15005C)\r\n#define APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_INVALID_PATH         ((HRESULT)0x8A15005D)\r\n#define APPINSTALLER_CLI_ERROR_PINNED_CERTIFICATE_MISMATCH          ((HRESULT)0x8A15005E)\r\n#define APPINSTALLER_CLI_ERROR_INSTALL_LOCATION_REQUIRED            ((HRESULT)0x8A15005F)\r\n#define APPINSTALLER_CLI_ERROR_ARCHIVE_SCAN_FAILED                  ((HRESULT)0x8A150060)\r\n#define APPINSTALLER_CLI_ERROR_PACKAGE_ALREADY_INSTALLED            ((HRESULT)0x8A150061)\r\n#define APPINSTALLER_CLI_ERROR_PIN_ALREADY_EXISTS                   ((HRESULT)0x8A150062)\r\n#define APPINSTALLER_CLI_ERROR_PIN_DOES_NOT_EXIST                   ((HRESULT)0x8A150063)\r\n#define APPINSTALLER_CLI_ERROR_CANNOT_OPEN_PINNING_INDEX            ((HRESULT)0x8A150064)\r\n#define APPINSTALLER_CLI_ERROR_MULTIPLE_INSTALL_FAILED              ((HRESULT)0x8A150065)\r\n#define APPINSTALLER_CLI_ERROR_MULTIPLE_UNINSTALL_FAILED            ((HRESULT)0x8A150066)\r\n#define APPINSTALLER_CLI_ERROR_NOT_ALL_QUERIES_FOUND_SINGLE         ((HRESULT)0x8A150067)\r\n#define APPINSTALLER_CLI_ERROR_PACKAGE_IS_PINNED                    ((HRESULT)0x8A150068)\r\n#define APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB                      ((HRESULT)0x8A150069)\r\n#define APPINSTALLER_CLI_ERROR_APPTERMINATION_RECEIVED              ((HRESULT)0x8A15006A)\r\n#define APPINSTALLER_CLI_ERROR_DOWNLOAD_DEPENDENCIES                ((HRESULT)0x8A15006B)\r\n#define APPINSTALLER_CLI_ERROR_DOWNLOAD_COMMAND_PROHIBITED          ((HRESULT)0x8A15006C)\r\n#define APPINSTALLER_CLI_ERROR_SERVICE_UNAVAILABLE                  ((HRESULT)0x8A15006D)\r\n#define APPINSTALLER_CLI_ERROR_RESUME_ID_NOT_FOUND                  ((HRESULT)0x8A15006E)\r\n#define APPINSTALLER_CLI_ERROR_CLIENT_VERSION_MISMATCH              ((HRESULT)0x8A15006F)\r\n#define APPINSTALLER_CLI_ERROR_INVALID_RESUME_STATE                 ((HRESULT)0x8A150070)\r\n#define APPINSTALLER_CLI_ERROR_CANNOT_OPEN_CHECKPOINT_INDEX         ((HRESULT)0x8A150071)\r\n#define APPINSTALLER_CLI_ERROR_RESUME_LIMIT_EXCEEDED                ((HRESULT)0x8A150072)\r\n#define APPINSTALLER_CLI_ERROR_INVALID_AUTHENTICATION_INFO          ((HRESULT)0x8A150073)\r\n#define APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED    ((HRESULT)0x8A150074)\r\n#define APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED                ((HRESULT)0x8A150075)\r\n#define APPINSTALLER_CLI_ERROR_AUTHENTICATION_INTERACTIVE_REQUIRED  ((HRESULT)0x8A150076)\r\n#define APPINSTALLER_CLI_ERROR_AUTHENTICATION_CANCELLED_BY_USER     ((HRESULT)0x8A150077)\r\n#define APPINSTALLER_CLI_ERROR_AUTHENTICATION_INCORRECT_ACCOUNT     ((HRESULT)0x8A150078)\r\n#define APPINSTALLER_CLI_ERROR_NO_REPAIR_INFO_FOUND                 ((HRESULT)0x8A150079)\r\n#define APPINSTALLER_CLI_ERROR_REPAIR_NOT_APPLICABLE                ((HRESULT)0x8A15007A)\r\n#define APPINSTALLER_CLI_ERROR_EXEC_REPAIR_FAILED                   ((HRESULT)0x8A15007B)\r\n#define APPINSTALLER_CLI_ERROR_REPAIR_NOT_SUPPORTED                 ((HRESULT)0x8A15007C)\r\n#define APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED      ((HRESULT)0x8A15007D)\r\n#define APPINSTALLER_CLI_ERROR_SQLITE_CONNECTION_TERMINATED         ((HRESULT)0x8A15007E)\r\n#define APPINSTALLER_CLI_ERROR_DISPLAYCATALOG_API_FAILED            ((HRESULT)0x8A15007F)\r\n#define APPINSTALLER_CLI_ERROR_NO_APPLICABLE_DISPLAYCATALOG_PACKAGE ((HRESULT)0x8A150080)\r\n#define APPINSTALLER_CLI_ERROR_SFSCLIENT_API_FAILED                 ((HRESULT)0x8A150081)\r\n#define APPINSTALLER_CLI_ERROR_NO_APPLICABLE_SFSCLIENT_PACKAGE      ((HRESULT)0x8A150082)\r\n#define APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED                 ((HRESULT)0x8A150083)\r\n#define APPINSTALLER_CLI_ERROR_SFSCLIENT_PACKAGE_NOT_SUPPORTED      ((HRESULT)0x8A150084)\r\n#define APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED_FORBIDDEN       ((HRESULT)0x8A150085)\r\n#define APPINSTALLER_CLI_ERROR_INSTALLER_ZERO_BYTE_FILE             ((HRESULT)0x8A150086)\r\n#define APPINSTALLER_CLI_ERROR_FONT_INSTALL_FAILED                  ((HRESULT)0x8A150087)\r\n#define APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_SUPPORTED              ((HRESULT)0x8A150088)\r\n#define APPINSTALLER_CLI_ERROR_FONT_ALREADY_INSTALLED               ((HRESULT)0x8A150089)\r\n#define APPINSTALLER_CLI_ERROR_FONT_FILE_NOT_FOUND                  ((HRESULT)0x8A15008A)\r\n#define APPINSTALLER_CLI_ERROR_FONT_UNINSTALL_FAILED                ((HRESULT)0x8A15008B)\r\n#define APPINSTALLER_CLI_ERROR_FONT_VALIDATION_FAILED               ((HRESULT)0x8A15008C)\r\n#define APPINSTALLER_CLI_ERROR_FONT_ROLLBACK_FAILED                 ((HRESULT)0x8A15008D)\r\n\r\n// Install errors.\r\n#define APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE                   ((HRESULT)0x8A150101)\r\n#define APPINSTALLER_CLI_ERROR_INSTALL_INSTALL_IN_PROGRESS              ((HRESULT)0x8A150102)\r\n#define APPINSTALLER_CLI_ERROR_INSTALL_FILE_IN_USE                      ((HRESULT)0x8A150103)\r\n#define APPINSTALLER_CLI_ERROR_INSTALL_MISSING_DEPENDENCY               ((HRESULT)0x8A150104)\r\n#define APPINSTALLER_CLI_ERROR_INSTALL_DISK_FULL                        ((HRESULT)0x8A150105)\r\n#define APPINSTALLER_CLI_ERROR_INSTALL_INSUFFICIENT_MEMORY              ((HRESULT)0x8A150106)\r\n#define APPINSTALLER_CLI_ERROR_INSTALL_NO_NETWORK                       ((HRESULT)0x8A150107)\r\n#define APPINSTALLER_CLI_ERROR_INSTALL_CONTACT_SUPPORT                  ((HRESULT)0x8A150108)\r\n#define APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_TO_FINISH        ((HRESULT)0x8A150109)\r\n#define APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_FOR_INSTALL      ((HRESULT)0x8A15010A)\r\n#define APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_INITIATED                 ((HRESULT)0x8A15010B)\r\n#define APPINSTALLER_CLI_ERROR_INSTALL_CANCELLED_BY_USER                ((HRESULT)0x8A15010C)\r\n#define APPINSTALLER_CLI_ERROR_INSTALL_ALREADY_INSTALLED                ((HRESULT)0x8A15010D)\r\n#define APPINSTALLER_CLI_ERROR_INSTALL_DOWNGRADE                        ((HRESULT)0x8A15010E)\r\n#define APPINSTALLER_CLI_ERROR_INSTALL_BLOCKED_BY_POLICY                ((HRESULT)0x8A15010F)\r\n#define APPINSTALLER_CLI_ERROR_INSTALL_DEPENDENCIES                     ((HRESULT)0x8A150110)\r\n#define APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE_BY_APPLICATION    ((HRESULT)0x8A150111)\r\n#define APPINSTALLER_CLI_ERROR_INSTALL_INVALID_PARAMETER                ((HRESULT)0x8A150112)\r\n#define APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED             ((HRESULT)0x8A150113)\r\n#define APPINSTALLER_CLI_ERROR_INSTALL_UPGRADE_NOT_SUPPORTED            ((HRESULT)0x8A150114)\r\n#define APPINSTALLER_CLI_ERROR_INSTALL_CUSTOM_ERROR                     ((HRESULT)0x8A150115)\r\n\r\n// Status values for check package installed status results.\r\n// Partial success has the success bit(first bit) set to 0.\r\n#define WINGET_INSTALLED_STATUS_ARP_ENTRY_FOUND                             S_OK\r\n#define WINGET_INSTALLED_STATUS_ARP_ENTRY_NOT_FOUND                         ((HRESULT)0x8A150201)\r\n#define WINGET_INSTALLED_STATUS_INSTALL_LOCATION_FOUND                      S_OK\r\n#define WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_APPLICABLE             ((HRESULT)0x0A150202)\r\n#define WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_FOUND                  ((HRESULT)0x8A150203)\r\n#define WINGET_INSTALLED_STATUS_FILE_HASH_MATCH                             S_OK\r\n#define WINGET_INSTALLED_STATUS_FILE_HASH_MISMATCH                          ((HRESULT)0x8A150204)\r\n#define WINGET_INSTALLED_STATUS_FILE_NOT_FOUND                              ((HRESULT)0x8A150205)\r\n#define WINGET_INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK               ((HRESULT)0x0A150206)\r\n#define WINGET_INSTALLED_STATUS_FILE_ACCESS_ERROR                           ((HRESULT)0x8A150207)\r\n\r\n// Configuration Errors\r\n#define WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE          ((HRESULT)0x8A15C001)\r\n#define WINGET_CONFIG_ERROR_INVALID_YAML                        ((HRESULT)0x8A15C002)\r\n#define WINGET_CONFIG_ERROR_INVALID_FIELD_TYPE                  ((HRESULT)0x8A15C003)\r\n#define WINGET_CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION  ((HRESULT)0x8A15C004)\r\n#define WINGET_CONFIG_ERROR_SET_APPLY_FAILED                    ((HRESULT)0x8A15C005)\r\n#define WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER                ((HRESULT)0x8A15C006)\r\n#define WINGET_CONFIG_ERROR_MISSING_DEPENDENCY                  ((HRESULT)0x8A15C007)\r\n#define WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED              ((HRESULT)0x8A15C008)\r\n#define WINGET_CONFIG_ERROR_ASSERTION_FAILED                    ((HRESULT)0x8A15C009)\r\n#define WINGET_CONFIG_ERROR_MANUALLY_SKIPPED                    ((HRESULT)0x8A15C00A)\r\n#define WINGET_CONFIG_ERROR_WARNING_NOT_ACCEPTED                ((HRESULT)0x8A15C00B)\r\n#define WINGET_CONFIG_ERROR_SET_DEPENDENCY_CYCLE                ((HRESULT)0x8A15C00C)\r\n#define WINGET_CONFIG_ERROR_INVALID_FIELD_VALUE                 ((HRESULT)0x8A15C00D)\r\n#define WINGET_CONFIG_ERROR_MISSING_FIELD                       ((HRESULT)0x8A15C00E)\r\n#define WINGET_CONFIG_ERROR_TEST_FAILED                         ((HRESULT)0x8A15C00F)\r\n#define WINGET_CONFIG_ERROR_TEST_NOT_RUN                        ((HRESULT)0x8A15C010)\r\n#define WINGET_CONFIG_ERROR_GET_FAILED                          ((HRESULT)0x8A15C011)\r\n#define WINGET_CONFIG_ERROR_HISTORY_ITEM_NOT_FOUND              ((HRESULT)0x8A15C012)\r\n#define WINGET_CONFIG_ERROR_PARAMETER_INTEGRITY_BOUNDARY        ((HRESULT)0x8A15C013)\r\n\r\n// Configuration Processor Errors\r\n#define WINGET_CONFIG_ERROR_UNIT_NOT_INSTALLED              ((HRESULT)0x8A15C101)\r\n#define WINGET_CONFIG_ERROR_UNIT_NOT_FOUND_REPOSITORY       ((HRESULT)0x8A15C102)\r\n#define WINGET_CONFIG_ERROR_UNIT_MULTIPLE_MATCHES           ((HRESULT)0x8A15C103)\r\n#define WINGET_CONFIG_ERROR_UNIT_INVOKE_GET                 ((HRESULT)0x8A15C104)\r\n#define WINGET_CONFIG_ERROR_UNIT_INVOKE_TEST                ((HRESULT)0x8A15C105)\r\n#define WINGET_CONFIG_ERROR_UNIT_INVOKE_SET                 ((HRESULT)0x8A15C106)\r\n#define WINGET_CONFIG_ERROR_UNIT_MODULE_CONFLICT            ((HRESULT)0x8A15C107)\r\n#define WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE              ((HRESULT)0x8A15C108)\r\n#define WINGET_CONFIG_ERROR_UNIT_INVOKE_INVALID_RESULT      ((HRESULT)0x8A15C109)\r\n#define WINGET_CONFIG_ERROR_UNIT_SETTING_CONFIG_ROOT        ((HRESULT)0x8A15C110)\r\n#define WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE_ADMIN        ((HRESULT)0x8A15C111)\r\n#define WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR      ((HRESULT)0x8A15C112)\r\n\r\nnamespace AppInstaller\r\n{\r\n    // Gets error messages that are presentable to the user.\r\n    std::string GetUserPresentableMessage(const wil::ResultException& re);\r\n    std::string GetUserPresentableMessage(const std::exception& e);\r\n    std::string GetUserPresentableMessage(HRESULT hr);\r\n\r\n#ifndef WINGET_DISABLE_FOR_FUZZING\r\n    std::string GetUserPresentableMessage(const winrt::hresult_error& hre);\r\n#endif\r\n\r\n    namespace Errors\r\n    {\r\n        // Details about an HRESULT\r\n        struct HResultInformation\r\n        {\r\n            constexpr HResultInformation(HRESULT value);\r\n            constexpr HResultInformation(HRESULT value, std::string_view symbol);\r\n\r\n            virtual ~HResultInformation() = default;\r\n\r\n            HRESULT Value() const;\r\n\r\n            bool operator<(const HResultInformation& other) const;\r\n\r\n            // The symbol will be an empty view if not known.\r\n            Utility::LocIndView Symbol() const;\r\n\r\n            // Looks up the description of the HRESULT\r\n            virtual Utility::LocIndString GetDescription() const;\r\n\r\n            // Find information by HRESULT; this lookup is optimized.\r\n            static std::unique_ptr<HResultInformation> Find(HRESULT value);\r\n\r\n            // Find information by substring match with the given value.\r\n            // This lookup is not optimized, as it should only be needed for the error command.\r\n            static std::vector<std::unique_ptr<HResultInformation>> Find(std::string_view value);\r\n\r\n        private:\r\n            HRESULT m_value;\r\n            std::string_view m_symbol;\r\n        };\r\n\r\n        // Gets all of the custom error information for our errors.\r\n        std::vector<std::unique_ptr<HResultInformation>> GetWinGetErrors();\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/AppInstallerLanguageUtilities.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <functional>\r\n#include <initializer_list>\r\n#include <map>\r\n#include <memory>\r\n#include <optional>\r\n#include <string>\r\n#include <string_view>\r\n#include <tuple>\r\n#include <type_traits>\r\n#include <utility>\r\n#include <variant>\r\n#include <vector>\r\n\r\nnamespace AppInstaller\r\n{\r\n    // A helper type that resets itself when it is moved from.\r\n    template <typename T>\r\n    struct ResetWhenMovedFrom\r\n    {\r\n        ResetWhenMovedFrom() : m_var{} {}\r\n\r\n        ResetWhenMovedFrom(T t) : m_var{ t } {}\r\n\r\n        // Not copyable\r\n        ResetWhenMovedFrom(const ResetWhenMovedFrom&) = delete;\r\n        ResetWhenMovedFrom& operator=(const ResetWhenMovedFrom&) = delete;\r\n\r\n        ResetWhenMovedFrom(ResetWhenMovedFrom&& other) noexcept :\r\n            m_var(std::move(other.m_var))\r\n        {\r\n            other.m_var = T{};\r\n        }\r\n\r\n        ResetWhenMovedFrom& operator=(ResetWhenMovedFrom&& other) noexcept\r\n        {\r\n            m_var = std::move(other.m_var);\r\n            other.m_var = T{};\r\n            return *this;\r\n        }\r\n\r\n        operator T& () { return m_var; }\r\n        operator const T& () const { return m_var; }\r\n\r\n    private:\r\n        T m_var;\r\n    };\r\n\r\n    // Enables a bool to be used as a destruction indicator.\r\n    // Default construction *sets the value to false!*\r\n    using DestructionToken = ResetWhenMovedFrom<bool>;\r\n\r\n    // Enable use of folding to execute functions across parameter packs.\r\n    struct FoldHelper\r\n    {\r\n        template <typename T>\r\n        FoldHelper& operator,(T&&) { return *this; }\r\n    };\r\n\r\n    // Get the integral value for an enum.\r\n    template <typename E>\r\n    constexpr inline std::enable_if_t<std::is_enum_v<E>, std::underlying_type_t<E>> ToIntegral(E e)\r\n    {\r\n        return static_cast<std::underlying_type_t<E>>(e);\r\n    }\r\n\r\n    // Get the enum value for an integral.\r\n    template <typename E>\r\n    constexpr inline std::enable_if_t<std::is_enum_v<E>, E> ToEnum(std::underlying_type_t<E> ut)\r\n    {\r\n        return static_cast<E>(ut);\r\n    }\r\n\r\n    // Enum based variant helper.\r\n    // Enum must be an enum whose first member has the value 0, each subsequent member increases by 1, and the final member is named Max.\r\n    // Mapping is a template type that takes one template parameter of type Enum, and whose members define value_t as the type for that enum value.\r\n    template <typename Enum, template<Enum> typename Mapping>\r\n    struct EnumBasedVariant\r\n    {\r\n    private:\r\n        // Used to deduce the variant type; making a variant that includes std::monostate and all Mapping types.\r\n        template <size_t... I>\r\n        static inline auto Deduce(std::index_sequence<I...>) { return std::variant<std::monostate, typename Mapping<static_cast<Enum>(I)>::value_t...>{}; }\r\n\r\n    public:\r\n        // Holds data of any type listed in Mapping.\r\n        using variant_t = decltype(Deduce(std::make_index_sequence<static_cast<size_t>(Enum::Max)>()));\r\n\r\n        // Gets the index into the variant for the given Data.\r\n        static constexpr inline size_t Index(Enum e) { return static_cast<size_t>(e) + 1; }\r\n    };\r\n\r\n    // An action that can be taken on an EnumBasedVariantMap.\r\n    enum class EnumBasedVariantMapAction\r\n    {\r\n        Add,\r\n        Contains,\r\n        Get,\r\n    };\r\n\r\n    // A callback function that can be used for logging map actions.\r\n    template <typename Enum>\r\n    using EnumBasedVariantMapActionCallback = void (*)(const void* map, Enum value, EnumBasedVariantMapAction action);\r\n\r\n    // Provides a map of the Enum to the mapped types.\r\n    template <typename Enum, template<Enum> typename Mapping, EnumBasedVariantMapActionCallback<Enum> Callback = nullptr>\r\n    struct EnumBasedVariantMap\r\n    {\r\n        using Variant = EnumBasedVariant<Enum, Mapping>;\r\n\r\n        template <Enum E>\r\n        using mapping_t = typename Mapping<E>::value_t;\r\n\r\n        // Adds a value to the map, or overwrites an existing entry.\r\n        // This must be used to create the initial data entry, but Get can be used to modify.\r\n        template <Enum E>\r\n        void Add(mapping_t<E>&& v)\r\n        {\r\n            if constexpr (Callback)\r\n            {\r\n                Callback(this, E, EnumBasedVariantMapAction::Add);\r\n            }\r\n            m_data[E].emplace<Variant::Index(E)>(std::move(std::forward<mapping_t<E>>(v)));\r\n        }\r\n\r\n        template <Enum E>\r\n        void Add(const mapping_t<E>& v)\r\n        {\r\n            if constexpr (Callback)\r\n            {\r\n                Callback(this, E, EnumBasedVariantMapAction::Add);\r\n            }\r\n            m_data[E].emplace<Variant::Index(E)>(v);\r\n        }\r\n\r\n        // Return a value indicating whether the given enum is stored in the map.\r\n        bool Contains(Enum e) const\r\n        {\r\n            if constexpr (Callback)\r\n            {\r\n                Callback(this, e, EnumBasedVariantMapAction::Contains);\r\n            }\r\n            return (m_data.find(e) != m_data.end());\r\n        }\r\n\r\n        // Gets the value.\r\n        template <Enum E>\r\n        mapping_t<E>& Get()\r\n        {\r\n            if constexpr (Callback)\r\n            {\r\n                Callback(this, E, EnumBasedVariantMapAction::Get);\r\n            }\r\n            return std::get<Variant::Index(E)>(GetVariant(E));\r\n        }\r\n\r\n        template <Enum E>\r\n        const mapping_t<E>& Get() const\r\n        {\r\n            if constexpr (Callback)\r\n            {\r\n                Callback(this, E, EnumBasedVariantMapAction::Get);\r\n            }\r\n            return std::get<Variant::Index(E)>(GetVariant(E));\r\n        }\r\n\r\n    private:\r\n        typename Variant::variant_t& GetVariant(Enum e)\r\n        {\r\n            auto itr = m_data.find(e);\r\n            THROW_HR_IF_MSG(E_NOT_SET, itr == m_data.end(), \"GetVariant(%d)\", static_cast<int>(e));\r\n            return itr->second;\r\n        }\r\n\r\n        const typename Variant::variant_t& GetVariant(Enum e) const\r\n        {\r\n            auto itr = m_data.find(e);\r\n            THROW_HR_IF_MSG(E_NOT_SET, itr == m_data.cend(), \"GetVariant(%d)\", static_cast<int>(e));\r\n            return itr->second;\r\n        }\r\n\r\n        std::map<Enum, typename Variant::variant_t> m_data;\r\n    };\r\n\r\n    template<typename E>\r\n    std::vector<E> GetAllSequentialEnumValues(E initialToSkip)\r\n    {\r\n        std::vector<E> result;\r\n        using underlying_t = std::underlying_type_t<E>;\r\n\r\n        for (underlying_t i = 1 + static_cast<underlying_t>(initialToSkip); i < static_cast<underlying_t>(E::Max); ++i)\r\n        {\r\n            result.emplace_back(static_cast<E>(i));\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    template<typename E>\r\n    std::vector<E> GetAllExponentialEnumValues(E initialToSkip)\r\n    {\r\n        std::vector<E> result;\r\n        using underlying_t = std::underlying_type_t<E>;\r\n\r\n        for (underlying_t i = 1 + static_cast<underlying_t>(initialToSkip); i < static_cast<underlying_t>(E::Max); i <<= 1)\r\n        {\r\n            result.emplace_back(static_cast<E>(i));\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n\r\n// Enable enums to be output generically (as their integral value).\r\ntemplate <typename E>\r\nstd::enable_if_t<std::is_enum_v<E>, std::ostream&> operator<<(std::ostream& out, E e)\r\n{\r\n    return out << AppInstaller::ToIntegral(e);\r\n}\r\n\r\ntemplate <typename T>\r\nstruct CopyConstructibleAtomic : public std::atomic<T>\r\n{\r\n    using std::atomic<T>::atomic;\r\n    using std::atomic<T>::operator=;\r\n\r\n    CopyConstructibleAtomic(const CopyConstructibleAtomic& other) :\r\n        std::atomic<T>(other.load()) {}\r\n};\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/AppInstallerLogging.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerLanguageUtilities.h>\r\n#include <chrono>\r\n#include <filesystem>\r\n#include <memory>\r\n#include <sstream>\r\n#include <string>\r\n#include <string_view>\r\n#include <type_traits>\r\n#include <vector>\r\n\r\n#define AICLI_LOG_DIRECT(_logger_,_channel_,_level_,_outstream_) \\\r\n    do { \\\r\n        auto _aicli_log_channel = AppInstaller::Logging::Channel:: _channel_; \\\r\n        auto _aicli_log_level = AppInstaller::Logging::Level:: _level_; \\\r\n        auto& _aicli_log_log = _logger_; \\\r\n        if (_aicli_log_log.IsEnabled(_aicli_log_channel, _aicli_log_level)) \\\r\n        { \\\r\n            AppInstaller::Logging::LoggingStream _aicli_log_strstr; \\\r\n            _aicli_log_strstr _outstream_; \\\r\n            _aicli_log_log.Write(_aicli_log_channel, _aicli_log_level, _aicli_log_strstr.str()); \\\r\n        } \\\r\n    } while (0, 0)\r\n\r\n#define AICLI_LOG(_channel_,_level_,_outstream_) AICLI_LOG_DIRECT(AppInstaller::Logging::Log(),_channel_,_level_,_outstream_)\r\n\r\n// Consider using this macro when the string might be larger than 4K.\r\n// The normal macro has some buffering that occurs; it can cut off larger strings and is slower.\r\n#define AICLI_LOG_LARGE_STRING(_channel_,_level_,_headerStream_,_largeString_) \\\r\n    do { \\\r\n        auto _aicli_log_channel = AppInstaller::Logging::Channel:: _channel_; \\\r\n        auto _aicli_log_level = AppInstaller::Logging::Level:: _level_; \\\r\n        auto& _aicli_log_log = AppInstaller::Logging::Log(); \\\r\n        if (_aicli_log_log.IsEnabled(_aicli_log_channel, _aicli_log_level)) \\\r\n        { \\\r\n            AppInstaller::Logging::LoggingStream _aicli_log_strstr; \\\r\n            _aicli_log_strstr _headerStream_; \\\r\n            _aicli_log_log.Write(_aicli_log_channel, _aicli_log_level, _aicli_log_strstr.str()); \\\r\n            _aicli_log_log.WriteDirect(_aicli_log_channel, _aicli_log_level, _largeString_); \\\r\n        } \\\r\n    } while (0, 0)\r\n\r\nnamespace AppInstaller::Logging\r\n{\r\n    // The channel that the log is from.\r\n    // Channels enable large groups of logs to be enabled or disabled together.\r\n    enum class Channel : uint32_t\r\n    {\r\n        Fail = 0x1,\r\n        CLI = 0x2,\r\n        SQL = 0x4,\r\n        Repo = 0x8,\r\n        YAML = 0x10,\r\n        Core = 0x20,\r\n        Test = 0x40,\r\n        Config = 0x80,\r\n        Workflow = 0x100,\r\n        None = 0,\r\n        All = 0xFFFFFFFF,\r\n        Defaults = All & ~(SQL | Workflow),\r\n    };\r\n\r\n    DEFINE_ENUM_FLAG_OPERATORS(Channel);\r\n\r\n    // Gets the channel's name as a string.\r\n    std::string_view GetChannelName(Channel channel);\r\n\r\n    // Gets the channel from it's name.\r\n    Channel GetChannelFromName(std::string_view channel);\r\n\r\n    // Gets the maximum channel name length in characters.\r\n    size_t GetMaxChannelNameLength();\r\n\r\n    // The level of the log.\r\n    enum class Level\r\n    {\r\n        Verbose,\r\n        Info,\r\n        Warning,\r\n        Error,\r\n        Crit,\r\n    };\r\n\r\n    // Indicates a location of significance in the logging stream.\r\n    enum class Tag\r\n    {\r\n        // The initial set of logging has been completed.\r\n        HeadersComplete,\r\n    };\r\n\r\n    // The interface that a log target must implement.\r\n    struct ILogger\r\n    {\r\n        virtual ~ILogger() = default;\r\n\r\n        // Gets the name of the logger for internal use.\r\n        virtual std::string GetName() const = 0;\r\n\r\n        // Informs the logger of the given log.\r\n        virtual void Write(Channel channel, Level level, std::string_view message) noexcept = 0;\r\n\r\n        // Informs the logger of the given log with the intention that no buffering occurs (in winget code).\r\n        virtual void WriteDirect(Channel channel, Level level, std::string_view message) noexcept = 0;\r\n\r\n        // Indicates that the given tag location has occurred.\r\n        virtual void SetTag(Tag) noexcept {}\r\n    };\r\n\r\n    // This type contains the set of loggers that diagnostic logging will be sent to.\r\n    // Each binary that leverages it must configure any loggers and filters to their\r\n    // desired level, as nothing is enabled by default.\r\n    struct DiagnosticLogger\r\n    {\r\n        DiagnosticLogger() = default;\r\n\r\n        ~DiagnosticLogger() = default;\r\n\r\n        DiagnosticLogger(const DiagnosticLogger&) = delete;\r\n        DiagnosticLogger& operator=(const DiagnosticLogger&) = delete;\r\n\r\n        DiagnosticLogger(DiagnosticLogger&&) = delete;\r\n        DiagnosticLogger& operator=(DiagnosticLogger&&) = delete;\r\n\r\n        // Gets the singleton instance of this type.\r\n        static DiagnosticLogger& GetInstance();\r\n\r\n        // NOTE: The logger management functionality is *SINGLE THREAD SAFE*.\r\n        //       This includes with logging itself.\r\n        //       As it is not expected that adding/removing loggers is an\r\n        //       extremely frequent operation, no care has been made to protect\r\n        //       it from modifying loggers while logging may be occurring.\r\n\r\n        // Adds a logger to the active set.\r\n        void AddLogger(std::unique_ptr<ILogger>&& logger);\r\n\r\n        // Determines if a logger with the given name is present.\r\n        bool ContainsLogger(const std::string& name);\r\n\r\n        // Removes a logger from the active set, returning it.\r\n        std::unique_ptr<ILogger> RemoveLogger(const std::string& name);\r\n\r\n        // Removes all loggers.\r\n        void RemoveAllLoggers();\r\n\r\n        // Enables the given channel(s), in addition to the currently enabled channels.\r\n        void EnableChannel(Channel channel);\r\n\r\n        // The given channel mask will become the only enabled channels.\r\n        void SetEnabledChannels(Channel channel);\r\n\r\n        // Disables the given channel.\r\n        void DisableChannel(Channel channel);\r\n\r\n        // Sets the enabled level.\r\n        // All levels above this level will be enabled.\r\n        // For example; SetLevel(Verbose) will enable all logs.\r\n        void SetLevel(Level level);\r\n\r\n        // Gets the enabled level.\r\n        Level GetLevel() const;\r\n\r\n        // Checks whether a given channel and level are enabled.\r\n        bool IsEnabled(Channel channel, Level level) const;\r\n\r\n        // Writes a log line, if the given channel and level are enabled.\r\n        void Write(Channel channel, Level level, std::string_view message);\r\n\r\n        // Writes a log line, if the given channel and level are enabled.\r\n        // Use to make large logs more efficient by writing directly to the output streams.\r\n        void WriteDirect(Channel channel, Level level, std::string_view message);\r\n\r\n        // Indicates that the given tag location has occurred.\r\n        void SetTag(Tag tag);\r\n\r\n    private:\r\n\r\n        std::vector<std::unique_ptr<ILogger>> m_loggers;\r\n        Channel m_enabledChannels = Channel::None;\r\n        Level m_enabledLevel = Level::Info;\r\n    };\r\n\r\n    DiagnosticLogger& Log();\r\n\r\n    // Calls the various stream format functions to produce an 8 character hexadecimal output.\r\n    std::ostream& SetHRFormat(std::ostream& out);\r\n\r\n    // This type allows us to override the default behavior of output operators for logging.\r\n    struct LoggingStream\r\n    {\r\n        // Force use of the UTF-8 string from a file path.\r\n        // This should not be necessary when we move to C++20 and convert to using u8string.\r\n        friend AppInstaller::Logging::LoggingStream& operator<<(AppInstaller::Logging::LoggingStream& out, const std::filesystem::path& path)\r\n        {\r\n            out.m_out << path.u8string();\r\n            return out;\r\n        }\r\n\r\n        // Enums\r\n        template <typename T>\r\n        friend std::enable_if_t<std::is_enum_v<std::decay_t<T>>, AppInstaller::Logging::LoggingStream&>\r\n            operator<<(AppInstaller::Logging::LoggingStream& out, T t)\r\n        {\r\n            out.m_out << ToIntegral(t);\r\n            return out;\r\n        }\r\n\r\n        // Everything else.\r\n        template <typename T>\r\n        friend std::enable_if_t<!std::disjunction_v<std::is_same<std::decay_t<T>, std::filesystem::path>, std::is_enum<std::decay_t<T>>>, AppInstaller::Logging::LoggingStream&>\r\n            operator<<(AppInstaller::Logging::LoggingStream& out, T&& t)\r\n        {\r\n            out.m_out << std::forward<T>(t);\r\n            return out;\r\n        }\r\n\r\n        std::string str() const { return m_out.str(); }\r\n\r\n    private:\r\n        std::stringstream m_out;\r\n    };\r\n}\r\n\r\nnamespace std\r\n{\r\n    std::ostream& operator<<(std::ostream& out, const std::chrono::system_clock::time_point& time);\r\n    std::ostream& operator<<(std::ostream& out, const GUID& guid);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/AppInstallerSHA256.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <filesystem>\r\n#include <memory>\r\n#include <string>\r\n#include <vector>\r\n#include <stdexcept>\r\n#include <string_view>\r\n\r\nnamespace AppInstaller::Utility {\r\n\r\n    // Forward declaration of type defined within PAL\r\n    struct SHA256Context;\r\n\r\n    // Class used to compute SHA256 hashes over various sets of data.\r\n    // Create one and Add data to it if the data is not all available,\r\n    // or simply call ComputeHash if the data is all in memory.\r\n    class SHA256\r\n    {\r\n    public:\r\n        using HashBuffer = std::vector<uint8_t>;\r\n        constexpr static size_t HashBufferSizeInBytes = 32;\r\n        constexpr static size_t HashStringSizeInChars = 64;\r\n\r\n        struct HashDetails\r\n        {\r\n            HashBuffer Hash;\r\n            uint64_t SizeInBytes = 0;\r\n        };\r\n\r\n        SHA256();\r\n\r\n        // Adds the next chunk of data to the hash.\r\n        void Add(const uint8_t* buffer, size_t cbBuffer);\r\n\r\n        inline void Add(const std::vector<std::uint8_t>& buffer)\r\n        {\r\n            Add(buffer.data(), buffer.size());\r\n        }\r\n\r\n        // Gets the hash of the data. This is a destructive action; the accumulated hash\r\n        // value will be returned and the object can no longer be used.\r\n        void Get(HashBuffer& hash);\r\n\r\n        inline HashBuffer Get()\r\n        {\r\n            HashBuffer result{};\r\n            Get(result);\r\n            return result;\r\n        }\r\n\r\n        // Computes the hash of the given buffer immediately.\r\n        static HashBuffer ComputeHash(const uint8_t* buffer, std::uint32_t cbBuffer);\r\n\r\n        // Computes the hash of the given buffer immediately.\r\n        static HashBuffer ComputeHash(const std::vector<uint8_t>& buffer);\r\n\r\n        // Computes the hash of the given string immediately.\r\n        static HashBuffer ComputeHash(std::string_view buffer);\r\n\r\n        // Computes the hash from a given stream.\r\n        static HashBuffer ComputeHash(std::istream& in);\r\n\r\n        // Computes the hash from a given stream.\r\n        static HashDetails ComputeHashDetails(std::istream& in);\r\n\r\n        // Computes the hash from a given file path.\r\n        static HashBuffer ComputeHashFromFile(const std::filesystem::path& path);\r\n\r\n        static std::string ConvertToString(const HashBuffer& hashBuffer);\r\n\r\n        static std::wstring ConvertToWideString(const HashBuffer& hashBuffer);\r\n\r\n        static HashBuffer ConvertToBytes(const std::string& hashStr);\r\n        static HashBuffer ConvertToBytes(const std::wstring& hashStr);\r\n\r\n        // Returns a value indicating whether the two hashes are equal.\r\n        static bool AreEqual(const HashBuffer& first, const HashBuffer& second);\r\n\r\n    private:\r\n        void EnsureNotFinished() const;\r\n\r\n        struct SHA256ContextDeleter\r\n        {\r\n            void operator()(SHA256Context* context);\r\n        };\r\n\r\n        std::unique_ptr<SHA256Context, SHA256ContextDeleter> context;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/AppInstallerStrings.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <filesystem>\r\n#include <ostream>\r\n#include <optional>\r\n#include <string>\r\n#include <string_view>\r\n#include <vector>\r\n#include <winget/LocIndependent.h>\r\n\r\nnamespace AppInstaller::Utility\r\n{\r\n    // Converts the given UTF16 string to UTF8\r\n    std::string ConvertToUTF8(std::wstring_view input);\r\n\r\n    // Converts the given UTF8 string to UTF16\r\n    std::wstring ConvertToUTF16(std::string_view input, UINT codePage = CP_UTF8);\r\n\r\n    // Tries to convert the given UTF8 string to UTF16\r\n    std::optional<std::wstring> TryConvertToUTF16(std::string_view input, UINT codePage = CP_UTF8);\r\n\r\n    // Converts the given UTF8 string to UTF32\r\n    std::u32string ConvertToUTF32(std::string_view input);\r\n\r\n    // Normalizes a UTF8 string to the given form.\r\n    std::string Normalize(std::string_view input, NORM_FORM form = NORM_FORM::NormalizationKC);\r\n\r\n    // Normalizes a UTF16 string to the given form.\r\n    std::wstring Normalize(std::wstring_view input, NORM_FORM form = NORM_FORM::NormalizationKC);\r\n\r\n    // Replaces any embedded null character found within the string.\r\n    void ReplaceEmbeddedNullCharacters(std::string& s, char c = ' ');\r\n\r\n    // Type to hold and force a normalized UTF8 string.\r\n    // Also enables further normalization by replacing embedded null characters with spaces.\r\n    template <NORM_FORM Form = NORM_FORM::NormalizationKC, bool ConvertEmbeddedNullToSpace = false>\r\n    struct NormalizedUTF8 : public std::string\r\n    {\r\n        NormalizedUTF8() = default;\r\n\r\n        template <size_t Size>\r\n        NormalizedUTF8(const char(&s)[Size]) { AssignValue(std::string_view{ s, (s[Size - 1] == '\\0' ? Size - 1 : Size) }); }\r\n\r\n        NormalizedUTF8(std::string_view sv) { AssignValue(sv); }\r\n\r\n        NormalizedUTF8(std::string& s) { AssignValue(s); }\r\n        NormalizedUTF8(const std::string& s) { AssignValue(s); }\r\n        NormalizedUTF8(std::string&& s) { AssignValue(s); }\r\n\r\n        NormalizedUTF8(std::wstring_view sv) { AssignValue(sv); }\r\n\r\n        NormalizedUTF8(const NormalizedUTF8& other) = default;\r\n        NormalizedUTF8& operator=(const NormalizedUTF8& other) = default;\r\n\r\n        NormalizedUTF8(NormalizedUTF8&& other) = default;\r\n        NormalizedUTF8& operator=(NormalizedUTF8&& other) = default;\r\n\r\n        template <size_t Size>\r\n        NormalizedUTF8& operator=(const char(&s)[Size])\r\n        {\r\n            AssignValue(std::string_view{ s, (s[Size - 1] == '\\0' ? Size - 1 : Size) });\r\n            return *this;\r\n        }\r\n\r\n        NormalizedUTF8& operator=(std::string_view sv)\r\n        {\r\n            AssignValue(sv);\r\n            return *this;\r\n        }\r\n\r\n        NormalizedUTF8& operator=(const std::string& s)\r\n        {\r\n            AssignValue(s);\r\n            return *this;\r\n        }\r\n\r\n        NormalizedUTF8& operator=(std::string&& s)\r\n        {\r\n            AssignValue(s);\r\n            return *this;\r\n        }\r\n\r\n    private:\r\n        void AssignValue(std::string_view sv)\r\n        {\r\n            assign(Normalize(sv, Form));\r\n\r\n            if constexpr (ConvertEmbeddedNullToSpace)\r\n            {\r\n                ReplaceEmbeddedNullCharacters(*this);\r\n            }\r\n        }\r\n\r\n        void AssignValue(std::wstring_view sv)\r\n        {\r\n            assign(ConvertToUTF8(Normalize(sv, Form)));\r\n\r\n            if constexpr (ConvertEmbeddedNullToSpace)\r\n            {\r\n                ReplaceEmbeddedNullCharacters(*this);\r\n            }\r\n        }\r\n    };\r\n\r\n    using NormalizedString = NormalizedUTF8<NORM_FORM::NormalizationKC, true>;\r\n\r\n    // Compares the two UTF8 strings in a case-insensitive manner.\r\n    // Use this if one of the values is a known value, and thus ToLower is sufficient.\r\n    bool CaseInsensitiveEquals(std::string_view a, std::string_view b);\r\n\r\n    // Compares the two UTF16 strings in a case-insensitive manner.\r\n    // Use this if one of the values is a known value, and thus ToLower is sufficient.\r\n    bool CaseInsensitiveEquals(std::wstring_view a, std::wstring_view b);\r\n\r\n    // Returns if a UTF8 string is contained within a vector in a case-insensitive manner.\r\n    bool CaseInsensitiveContains(const std::vector<std::string_view>& a, std::string_view b);\r\n\r\n    // Determines if string a starts with string b. UTF16.\r\n    bool StartsWith(std::wstring_view a, std::wstring_view b);\r\n\r\n    // Determines if string a starts with string b. UTF8.\r\n    // Use this if one of the values is a known value, and thus ToLower is sufficient.\r\n    bool CaseInsensitiveStartsWith(std::string_view a, std::string_view b);\r\n\r\n    // Determines if string a starts with string b. UTF16.\r\n    // Use this if one of the values is a known value, and thus ToLower is sufficient.\r\n    bool CaseInsensitiveStartsWith(std::wstring_view a, std::wstring_view b);\r\n\r\n    // Determines if string a contains string b.\r\n    // Use this if one of the values is a known value, and thus ToLower is sufficient.\r\n    bool CaseInsensitiveContainsSubstring(std::string_view a, std::string_view b);\r\n\r\n    // Determines if string a contains string b.\r\n    bool ContainsSubstring(std::string_view a, std::string_view b);\r\n\r\n    // Compares the two UTF8 strings in a case-insensitive manner, using ICU for case folding.\r\n    bool ICUCaseInsensitiveEquals(std::string_view a, std::string_view b);\r\n\r\n    // Determines if string a starts with string b, using ICU for case folding.\r\n    bool ICUCaseInsensitiveStartsWith(std::string_view a, std::string_view b);\r\n\r\n    // Returns the number of grapheme clusters (characters) in an UTF8-encoded string.\r\n    size_t UTF8Length(std::string_view input);\r\n\r\n    // Returns the number of units the UTF8-encoded string will take in terminal output. Some characters take 2 units in terminal output.\r\n    size_t UTF8ColumnWidth(const NormalizedUTF8<NormalizationC>& input);\r\n\r\n    // Returns a substring view in an UTF8-encoded string. Offset and count are measured in grapheme clusters (characters).\r\n    std::string_view UTF8Substring(std::string_view input, size_t offset, size_t count);\r\n\r\n    // Returns a substring view in an UTF8-encoded string trimmed to be at most expected length. Length is measured as units taken in terminal output.\r\n    // Note the returned substring view might be less than specified length as some characters might take 2 units in terminal output.\r\n    std::string UTF8TrimRightToColumnWidth(const NormalizedUTF8<NormalizationC>&, size_t expectedWidth, size_t& actualWidth);\r\n\r\n    // Get the lower case version of the given std::string\r\n    std::string ToLower(std::string_view in);\r\n\r\n    // Get the lower case version of the given std::wstring\r\n    std::wstring ToLower(std::wstring_view in);\r\n\r\n    // Folds the case of the given std::string\r\n    // See https://unicode-org.github.io/icu/userguide/transforms/casemappings.html#case-folding\r\n    std::string FoldCase(std::string_view input);\r\n\r\n    // Folds the case of the given NormalizedString, returning it as also Normalized\r\n    // See https://unicode-org.github.io/icu/userguide/transforms/casemappings.html#case-folding\r\n    NormalizedString FoldCase(const NormalizedString& input);\r\n\r\n    // Checks if the input string is empty or whitespace\r\n    bool IsEmptyOrWhitespace(std::string_view str);\r\n    bool IsEmptyOrWhitespace(std::wstring_view str);\r\n\r\n    // Find token in the input string and replace with value.\r\n    // Returns a value indicating whether a replacement occurred.\r\n    bool FindAndReplace(std::string& inputStr, std::string_view token, std::string_view value);\r\n\r\n    // Replaces the token in the input string with value while copying to a new result.\r\n    std::wstring ReplaceWhileCopying(std::wstring_view input, std::wstring_view token, std::wstring_view value);\r\n\r\n    // Removes whitespace from the beginning and end of the string.\r\n    std::string& Trim(std::string& str);\r\n    std::string Trim(const std::string& str);\r\n    std::string Trim(std::string&& str);\r\n    std::string_view& Trim(std::string_view& str);\r\n    std::string_view Trim(std::string_view&& str);\r\n\r\n    // Removes whitespace from the beginning and end of the string.\r\n    std::wstring& Trim(std::wstring& str);\r\n    std::wstring Trim(const std::wstring& str);\r\n    std::wstring Trim(std::wstring&& str);\r\n    std::wstring_view& Trim(std::wstring_view& str);\r\n    std::wstring_view Trim(std::wstring_view&& str);\r\n\r\n    // Reads the entire stream into a string.\r\n    std::string ReadEntireStream(std::istream& stream);\r\n\r\n    // Reads the entire stream into a byte array.\r\n    std::vector<std::uint8_t> ReadEntireStreamAsByteArray(std::istream& stream);\r\n\r\n    // Expands environment variables within the input.\r\n    std::wstring ExpandEnvironmentVariables(const std::wstring& input);\r\n\r\n    // Converts the candidate path part into one suitable for the actual file system\r\n    std::string MakeSuitablePathPart(std::string_view candidate);\r\n\r\n    // Splits the file name part off of the given URI.\r\n    std::pair<std::string, std::filesystem::path> SplitFileNameFromURI(std::string_view uri);\r\n\r\n    // Gets the file name part of the given URI.\r\n    std::filesystem::path GetFileNameFromURI(std::string_view uri);\r\n\r\n    // Splits the string into words.\r\n    std::vector<std::string> SplitIntoWords(std::string_view input);\r\n\r\n    // Splits the string into lines.\r\n    // Drops empty lines.\r\n    std::vector<std::string> SplitIntoLines(std::string_view input, size_t maximum = 0);\r\n\r\n    // Removes lines from the vector (and/or characters from the last line) so that it contains the maximum number of lines.\r\n    // Returns true if changes were made, false if not.\r\n    bool LimitOutputLines(std::vector<std::string>& lines, size_t lineWidth, size_t maximum);\r\n\r\n    // Converts a container to a string representation of it.\r\n    template <typename T, typename U>\r\n    std::string ConvertContainerToString(const T& container, U toString)\r\n    {\r\n        std::ostringstream strstr;\r\n        strstr << '[';\r\n\r\n        bool firstItem = true;\r\n        for (const auto& item : container)\r\n        {\r\n            if (firstItem)\r\n            {\r\n                firstItem = false;\r\n            }\r\n            else\r\n            {\r\n                strstr << \", \";\r\n            }\r\n\r\n            strstr << toString(item);\r\n        }\r\n\r\n        strstr << ']';\r\n        return strstr.str();  // We need C++20 to get std::move(strstr).str() to extract the string from inside the stream\r\n    }\r\n\r\n    template <typename T>\r\n    std::string ConvertContainerToString(const T& container)\r\n    {\r\n        return ConvertContainerToString(container, [](const auto& item) { return item; });\r\n    }\r\n\r\n    template <typename CharType>\r\n    std::basic_string<CharType> StringOrEmptyIfNull(const CharType* string)\r\n    {\r\n        if (string)\r\n        {\r\n            return { string };\r\n        }\r\n        else\r\n        {\r\n            return {};\r\n        }\r\n    }\r\n\r\n    // Converts the given bytes into a hexadecimal string.\r\n    std::string ConvertToHexString(const std::vector<uint8_t>& buffer, size_t byteCount = 0);\r\n\r\n    // Converts the given hexadecimal string into bytes.\r\n    std::vector<uint8_t> ParseFromHexString(const std::string& value, size_t byteCount = 0);\r\n\r\n    // Join a string vector using the provided separator.\r\n    LocIndString Join(LocIndView separator, const std::vector<LocIndString>& vector);\r\n\r\n    // Join a string vector using the provided separator.\r\n    std::string Join(std::string_view separator, const std::vector<std::string>& vector);\r\n\r\n    // Splits the string using the provided separator. Entries can also be trimmed.\r\n    std::vector<std::string> Split(const std::string& input, char separator, bool trim = false);\r\n    std::vector<std::string_view> SplitView(const std::string& input, char separator, bool trim = false);\r\n    std::vector<std::string_view> Split(std::string_view input, char separator, bool trim = false);\r\n\r\n    // Splits the string using the provided separator. Entries can also be trimmed.\r\n    std::vector<std::wstring> Split(const std::wstring& input, wchar_t separator, bool trim = false);\r\n    std::vector<std::wstring_view> SplitView(const std::wstring& input, wchar_t separator, bool trim = false);\r\n    std::vector<std::wstring_view> Split(std::wstring_view input, wchar_t separator, bool trim = false);\r\n\r\n    // Format an input string by replacing placeholders {index} with provided values at corresponding indices.\r\n    // Note: After upgrading to C++20, this function should be deprecated in favor of std::format.\r\n    template <typename ... T>\r\n    std::string Format(std::string inputStr, T ... args)\r\n    {\r\n        int index = 0;\r\n        (FindAndReplace(inputStr, \"{\" + std::to_string(index++) + \"}\", (std::ostringstream() << args).str()),...);\r\n        return inputStr;\r\n    }\r\n\r\n    // Converts the given boolean value to a string.\r\n    std::string_view ConvertBoolToString(bool value);\r\n\r\n    // Converts the given string view into a bool.\r\n    std::optional<bool> TryConvertStringToBool(const std::string_view& value);\r\n\r\n    // Converts the given string view into an int32.\r\n    std::optional<int32_t> TryConvertStringToInt32(const std::string_view& value);\r\n\r\n    // Converts the given GUID value to a string.\r\n    std::string ConvertGuidToString(const GUID& value);\r\n\r\n    // Creates a new GUID and returns the string value.\r\n    std::wstring CreateNewGuidNameWString();\r\n\r\n    // Converts the input string to a DWORD value using std::stoul and returns a boolean value based on the resulting DWORD value.\r\n    bool IsDwordFlagSet(const std::string& value);\r\n\r\n    // Finds the next control code index that would be replaced.\r\n    // Returns std::string::npos if not found.\r\n    size_t FindControlCodeToConvert(std::string_view input, size_t offset = 0);\r\n\r\n    // Converts most control codes in the input to their corresponding control picture in the output.\r\n    // Exempts tab, line feed, and carriage return from being replaced.\r\n    std::string ConvertControlCodesToPictures(std::string_view input);\r\n\r\n    // Generates a random alpha numeric string.\r\n    std::string GetRandomString(size_t size = 8);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/AppInstallerVersions.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <string>\r\n#include <string_view>\r\n#include <vector>\r\n\r\nnamespace AppInstaller::Utility\r\n{\r\n    using namespace std::string_view_literals;\r\n\r\n    // Creates a comparable version object from a string.\r\n    // Versions are parsed by:\r\n    //  1. Parse approximate comparator sign if applicable\r\n    //  2. Splitting the string based on the given splitChars (or DefaultSplitChars)\r\n    //  3. Parsing a leading, positive integer from each split part\r\n    //  4. Saving any remaining, non-digits as a supplemental value\r\n    //\r\n    // Versions are compared by:\r\n    //  for each part in each version\r\n    //      if one side has no more parts, perform the remaining comparisons against an empty part\r\n    //      if integers not equal, return comparison of integers\r\n    //      else if only one side has a non-empty string part, it is less\r\n    //      else if string parts not equal, return comparison of strings\r\n    //  if each part has been compared, use approximate comparator if applicable\r\n    //\r\n    //  Note: approximate to another approximate version is invalid.\r\n    //        approximate to Unknown is invalid.\r\n    struct Version\r\n    {\r\n        // Used in approximate version to indicate the relation to the base version.\r\n        enum class ApproximateComparator\r\n        {\r\n            None,\r\n            LessThan,\r\n            GreaterThan,\r\n        };\r\n\r\n        // The default characters to split a version string on.\r\n        constexpr static std::string_view DefaultSplitChars = \".\"sv;\r\n\r\n        Version() = default;\r\n\r\n        Version(const std::string& version, std::string_view splitChars = DefaultSplitChars) :\r\n            Version(std::string(version), splitChars) {}\r\n        Version(std::string&& version, std::string_view splitChars = DefaultSplitChars);\r\n\r\n        // Constructing an approximate version from a base version.\r\n        Version(Version baseVersion, ApproximateComparator approximateComparator);\r\n\r\n        // Resets the version's value to the input.\r\n        virtual void Assign(std::string version, std::string_view splitChars = DefaultSplitChars);\r\n\r\n        // Gets the full version string used to construct the Version.\r\n        const std::string& ToString() const { return m_version; }\r\n\r\n        bool operator<(const Version& other) const;\r\n        bool operator>(const Version& other) const;\r\n        bool operator<=(const Version& other) const;\r\n        bool operator>=(const Version& other) const;\r\n        bool operator==(const Version& other) const;\r\n        bool operator!=(const Version& other) const;\r\n\r\n        // Determines if this version is the sentinel value defining the 'Latest' version\r\n        bool IsLatest() const;\r\n\r\n        // Returns a Version that will return true for IsLatest\r\n        static Version CreateLatest();\r\n\r\n        // Determines if this version is the sentinel value defining an 'Unknown' version\r\n        bool IsUnknown() const;\r\n\r\n        // Returns a Version that will return true for IsUnknown\r\n        static Version CreateUnknown();\r\n\r\n        // Gets a bool indicating whether the full version string is empty.\r\n        // Does not indicate that Parts is empty; for instance when \"0.0\" is given,\r\n        // this will be false while GetParts().empty() would be true.\r\n        bool IsEmpty() const { return m_version.empty(); }\r\n\r\n        // An individual version part in between split characters.\r\n        struct Part\r\n        {\r\n            Part() = default;\r\n            Part(uint64_t integer) : Integer(integer) {}\r\n            Part(const std::string& part);\r\n            Part(uint64_t integer, std::string other);\r\n\r\n            bool operator<(const Part& other) const;\r\n            bool operator==(const Part& other) const;\r\n            bool operator!=(const Part& other) const;\r\n\r\n            uint64_t Integer = 0;\r\n            std::string Other;\r\n\r\n        private:\r\n            std::string m_foldedOther;\r\n        };\r\n\r\n        // Gets the part breakdown for a given version.\r\n        const std::vector<Part>& GetParts() const { return m_parts; }\r\n\r\n        // Gets the part at the given index; or the implied zero part if past the end.\r\n        const Part& PartAt(size_t index) const;\r\n        \r\n        // Returns if the version is an approximate version.\r\n        bool IsApproximate() const { return m_approximateComparator != ApproximateComparator::None; }\r\n\r\n        // Get the base version from approximate version, or return a copy if the version is not approximate.\r\n        Version GetBaseVersion() const;\r\n\r\n    protected:\r\n\r\n        bool IsBaseVersionLatest() const;\r\n        bool IsBaseVersionUnknown() const;\r\n        // Called by overloaded less than operator implementation when base version already compared and equal, less than determined by approximate comparator.\r\n        bool ApproximateCompareLessThan(const Version& other) const;\r\n\r\n        std::string m_version;\r\n        std::vector<Part> m_parts;\r\n        bool m_trimPrefix = true;\r\n        ApproximateComparator m_approximateComparator = ApproximateComparator::None;\r\n\r\n      // Remove trailing empty parts (0 or empty)\r\n        void Trim();\r\n    };\r\n\r\n    // Version that does not have leading non-digit characters trimmed\r\n    struct RawVersion : protected Version\r\n    {\r\n        RawVersion() { m_trimPrefix = false; }\r\n        RawVersion(std::string version, std::string_view splitChars = DefaultSplitChars);\r\n\r\n        using Version::GetParts;\r\n    };\r\n\r\n    // Four parts version number: 16-bits.16-bits.16-bits.16-bits\r\n    struct UInt64Version : public Version\r\n    {\r\n        UInt64Version() = default;\r\n        UInt64Version(UINT64 version);\r\n        UInt64Version(uint16_t major, uint16_t minor, uint16_t build, uint16_t revision);\r\n        UInt64Version(std::string&& version, std::string_view splitChars = DefaultSplitChars);\r\n        UInt64Version(const std::string& version, std::string_view splitChars = DefaultSplitChars) :\r\n            UInt64Version(std::string(version), splitChars) {}\r\n\r\n        void Assign(std::string version, std::string_view splitChars = DefaultSplitChars) override;\r\n        void Assign(UINT64 version);\r\n        void Assign(uint16_t major, uint16_t minor, uint16_t build, uint16_t revision);\r\n\r\n        UINT64 Major() const { return m_parts.size() > 0 ? m_parts[0].Integer : 0; }\r\n        UINT64 Minor() const { return m_parts.size() > 1 ? m_parts[1].Integer : 0; }\r\n        UINT64 Build() const { return m_parts.size() > 2 ? m_parts[2].Integer : 0; }\r\n        UINT64 Revision() const { return m_parts.size() > 3 ? m_parts[3].Integer : 0; }\r\n    };\r\n\r\n    // A semantic version as defined by semver.org\r\n    // This is currently fairly loose in its restrictions on a version, and is largely to separate out the prelease and build metadata portions.\r\n    struct SemanticVersion : public Version\r\n    {\r\n        SemanticVersion() = default;\r\n        SemanticVersion(std::string&& version);\r\n        SemanticVersion(const std::string& version) :\r\n            SemanticVersion(std::string(version)) {}\r\n\r\n        void Assign(std::string version, std::string_view splitChars = DefaultSplitChars) override;\r\n\r\n        // Indicates that the version is pre-release\r\n        bool IsPrerelease() const;\r\n        // The pre-release version\r\n        const Version& PrereleaseVersion() const;\r\n\r\n        // Indicates that the version has build metadata\r\n        bool HasBuildMetadata() const;\r\n        // The build metadata version\r\n        const Version& BuildMetadata() const;\r\n\r\n    private:\r\n        Version m_prerelease;\r\n        Version m_buildMetadata;\r\n    };\r\n\r\n    // Version range represented by a min version and max version, both inclusive.\r\n    struct VersionRange\r\n    {\r\n        VersionRange() { m_isEmpty = true; };\r\n        VersionRange(Version minVersion, Version maxVersion);\r\n\r\n        bool IsEmpty() const { return m_isEmpty; }\r\n\r\n        // Checks if version ranges overlap. Empty version range does not overlap with any version range.\r\n        bool Overlaps(const VersionRange& other) const;\r\n\r\n        // Checks if the version range is effectively the same as a single version.\r\n        bool IsSameAsSingleVersion(const Version& version) const;\r\n\r\n        // Checks if a version is within the version range\r\n        bool ContainsVersion(const Version& version) const;\r\n\r\n        // < operator will thow if compared with an empty range or an overlapped range\r\n        bool operator<(const VersionRange& other) const;\r\n\r\n        const Version& GetMinVersion() const;\r\n        const Version& GetMaxVersion() const;\r\n\r\n    private:\r\n        Version m_minVersion;\r\n        Version m_maxVersion;\r\n        bool m_isEmpty = false;\r\n    };\r\n\r\n    // A range of versions indicated by a version and optionally a wildcard at the end.\r\n    struct GatedVersion\r\n    {\r\n        GatedVersion() {}\r\n        GatedVersion(Version&& version) : m_version(std::move(version)) {}\r\n        GatedVersion(const Version& version) : m_version(version) {}\r\n        GatedVersion(std::string_view versionString) : m_version(std::string{ versionString }) {}\r\n        GatedVersion(const std::string& versionString) : m_version(versionString) {}\r\n\r\n        // Determines whether a given version falls within this Gated version.\r\n        // I.e., whether it matches up to the wildcard\r\n        bool IsValidVersion(Version version) const;\r\n\r\n        bool operator==(const GatedVersion& other) const { return m_version == other.m_version; }\r\n        const std::string& ToString() const { return m_version.ToString(); }\r\n\r\n    private:\r\n        // Hold the version string as a Version object that makes it easy to access each of\r\n        // the version's parts. The real magic is in IsValidVersion()\r\n        Version m_version;\r\n    };\r\n\r\n    // A channel string; existing solely to give a type.\r\n    //\r\n    // Compared lexicographically.\r\n    struct Channel\r\n    {\r\n        Channel() = default;\r\n        Channel(const std::string& channel) : m_channel(channel) {}\r\n        Channel(std::string&& channel) : m_channel(std::move(channel)) {}\r\n\r\n        const std::string& ToString() const { return m_channel; }\r\n\r\n        bool operator<(const Channel& other) const;\r\n\r\n    private:\r\n        std::string m_channel;\r\n    };\r\n\r\n    // Contains a version and channel.\r\n    // These are compared by:\r\n    //  if channel not equal, return compare channel\r\n    //  else return !compare version\r\n    //\r\n    // The implication of this is that the default less sort will be:\r\n    //  2.0, \"\"\r\n    //  1.0, \"\"\r\n    //  3.0, \"alpha\"\r\n    //  2.0, \"alpha\"\r\n    struct VersionAndChannel\r\n    {\r\n        VersionAndChannel() = default;\r\n        VersionAndChannel(Version&& version, Channel&& channel);\r\n\r\n        const Version& GetVersion() const { return m_version; }\r\n        const Channel& GetChannel() const { return m_channel; }\r\n\r\n        std::string ToString() const;\r\n\r\n        bool operator<(const VersionAndChannel& other) const;\r\n\r\n        // A convenience function to make more semantic sense at call sites over the somewhat awkward less than ordering.\r\n        bool IsUpdatedBy(const VersionAndChannel& other) const;\r\n\r\n    private:\r\n        Version m_version;\r\n        Channel m_channel;\r\n    };\r\n\r\n    // Checks if there are overlaps within the list of version ranges\r\n    bool HasOverlapInVersionRanges(const std::vector<VersionRange>& ranges);\r\n\r\n    // The OpenType font version.\r\n    // The format of this version type is 'Version 1.234 ;567'\r\n    // The only part that is of importance is the 'Major.Minor' parts.\r\n    // The 'Version' string is typically found at the beginning of the version string.\r\n    // Any value after a digit that is not a '.' represents some other meaning.\r\n    struct OpenTypeFontVersion : Version\r\n    {\r\n        OpenTypeFontVersion() = default;\r\n\r\n        OpenTypeFontVersion(std::string&& version);\r\n        OpenTypeFontVersion(const std::string& version) :\r\n            OpenTypeFontVersion(std::string(version)) {}\r\n\r\n        void Assign(std::string version, std::string_view splitChars = DefaultSplitChars) override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/Telemetry/MicrosoftTelemetry.h",
    "content": "﻿/* ++\n\nCopyright (c) Microsoft Corporation. All rights reserved.\nLicensed under the MIT License. See LICENSE in the project root for license information.\n\nModule Name:\n\n    MicrosoftTelemetry.h\n\nAbstract:\n\n    Macro definitions used by this project's TraceLogging ETW providers:\n\n    - Configuration macros that select the ETW Provider Groups to be used by\n      this project.\n    - Constants for tags that are commonly used in Microsoft's\n      TraceLogging-based ETW.\n\n    Different versions of this file use different definitions for the\n    TraceLoggingOption configuration macros. The definitions in this file are\n    empty. As a result, providers using this configuration file will not join\n    any ETW Provider Groups and will not be given any special treatment by\n    group-sensitive ETW listeners.\n\nEnvironment:\n\n    User mode or kernel mode.\n\n--*/\n\n#pragma once\n\n// Configuration macro for use in TRACELOGGING_DEFINE_PROVIDER. The definition\n// in this file configures the provider as a normal (non-telemetry) provider.\n#define TraceLoggingOptionMicrosoftTelemetry() \\\n    // Empty definition for TraceLoggingOptionMicrosoftTelemetry\n\n// Configuration macro for use in TRACELOGGING_DEFINE_PROVIDER. The definition\n// in this file configures the provider as a normal (non-telemetry) provider.\n#define TraceLoggingOptionWindowsCoreTelemetry() \\\n    // Empty definition for TraceLoggingOptionWindowsCoreTelemetry\n\n// Event privacy tags. Use the PDT macro values for the tag parameter, e.g.:\n// TraceLoggingWrite(...,\n//   TelemetryPrivacyDataTag(PDT_BrowsingHistory | PDT_ProductAndServiceUsage),\n//   ...);\n#define TelemetryPrivacyDataTag(tag) TraceLoggingUInt64((tag), \"PartA_PrivTags\")\n#define PDT_BrowsingHistory                    0x0000000000000002u\n#define PDT_DeviceConnectivityAndConfiguration 0x0000000000000800u\n#define PDT_InkingTypingAndSpeechUtterance     0x0000000000020000u\n#define PDT_ProductAndServicePerformance       0x0000000001000000u\n#define PDT_ProductAndServiceUsage             0x0000000002000000u\n#define PDT_SoftwareSetupAndInventory          0x0000000080000000u\n\n// Event categories specified via keywords, e.g.:\n// TraceLoggingWrite(...,\n//     TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),\n//     ...);\n#define MICROSOFT_KEYWORD_CRITICAL_DATA 0x0000800000000000 // Bit 47\n#define MICROSOFT_KEYWORD_MEASURES      0x0000400000000000 // Bit 46\n#define MICROSOFT_KEYWORD_TELEMETRY     0x0000200000000000 // Bit 45\n#define MICROSOFT_KEYWORD_RESERVED_44   0x0000100000000000 // Bit 44 (reserved for future assignment)\n\n// Event categories specified via event tags, e.g.:\n// TraceLoggingWrite(...,\n//     TraceLoggingEventTag(MICROSOFT_EVENTTAG_REALTIME_LATENCY),\n//     ...);\n#define MICROSOFT_EVENTTAG_DROP_USER_IDS            0x00008000\n#define MICROSOFT_EVENTTAG_AGGREGATE                0x00010000\n#define MICROSOFT_EVENTTAG_DROP_PII_EXCEPT_IP       0x00020000\n#define MICROSOFT_EVENTTAG_COSTDEFERRED_LATENCY     0x00040000\n#define MICROSOFT_EVENTTAG_CORE_DATA                0x00080000\n#define MICROSOFT_EVENTTAG_INJECT_XTOKEN            0x00100000\n#define MICROSOFT_EVENTTAG_REALTIME_LATENCY         0x00200000\n#define MICROSOFT_EVENTTAG_NORMAL_LATENCY           0x00400000\n#define MICROSOFT_EVENTTAG_CRITICAL_PERSISTENCE     0x00800000\n#define MICROSOFT_EVENTTAG_NORMAL_PERSISTENCE       0x01000000\n#define MICROSOFT_EVENTTAG_DROP_PII                 0x02000000\n#define MICROSOFT_EVENTTAG_HASH_PII                 0x04000000\n#define MICROSOFT_EVENTTAG_MARK_PII                 0x08000000\n\n// Field categories specified via field tags, e.g.:\n// TraceLoggingWrite(...,\n//     TraceLoggingString(szUser, \"UserName\", \"User's name\", MICROSOFT_FIELDTAG_HASH_PII),\n//     ...);\n#define MICROSOFT_FIELDTAG_DROP_PII 0x04000000\n#define MICROSOFT_FIELDTAG_HASH_PII 0x08000000\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/Telemetry/WinEventLogLevels.h",
    "content": "﻿// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project root for license information.\n\n// From winmeta.h\n\n#define WINEVENT_LEVEL_LOG_ALWAYS 0x0\n#define WINEVENT_LEVEL_CRITICAL 0x1\n#define WINEVENT_LEVEL_ERROR 0x2\n#define WINEVENT_LEVEL_WARNING 0x3\n#define WINEVENT_LEVEL_INFO 0x4\n#define WINEVENT_LEVEL_VERBOSE 0x5"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/AsyncTokens.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerLogging.h>\r\n#include <winrt/Windows.Foundation.h>\r\n#include <memory>\r\n\r\nnamespace AppInstaller::WinRT\r\n{\r\n    namespace details\r\n    {\r\n        // Type erasing interface for winrt cancellation token.\r\n        struct AsyncCancellationTypeErasure\r\n        {\r\n            virtual ~AsyncCancellationTypeErasure() = default;\r\n\r\n            virtual bool IsCancelled() const noexcept = 0;\r\n            virtual void Callback(winrt::delegate<>&& callback) const noexcept = 0;\r\n            virtual void Cancel() noexcept = 0;\r\n        };\r\n\r\n        // Type containing winrt cancellation token wrapper.\r\n        template <typename Promise>\r\n        struct AsyncCancellationT : public AsyncCancellationTypeErasure\r\n        {\r\n            using Token = winrt::impl::cancellation_token<Promise>;\r\n\r\n            AsyncCancellationT(Token&& token) : m_token(std::move(token)) {}\r\n\r\n            bool IsCancelled() const noexcept override\r\n            {\r\n                return m_token();\r\n            }\r\n\r\n            void Callback(winrt::delegate<>&& callback) const noexcept override\r\n            {\r\n                m_token.callback(std::move(callback));\r\n            }\r\n\r\n            void Cancel() noexcept override\r\n            {\r\n                // This is a bit of a hack, but the cancellation_token provides no access to the underlying promise for the purpose of cancellation.\r\n                static_assert(sizeof(Token) == sizeof(Promise*), \"We expect that the cancellation_token has only 1 member and it is a Promise*\");\r\n                (*reinterpret_cast<Promise**>(&m_token))->Cancel();\r\n            }\r\n\r\n        private:\r\n            Token m_token;\r\n        };\r\n    }\r\n\r\n    // May hold a cancellation token and provide the ability to check its status.\r\n    // If empty, it will act as if it is never cancelled.\r\n    struct AsyncCancellation\r\n    {\r\n        // Create an empty cancellation object, which will never be cancelled.\r\n        AsyncCancellation() = default;\r\n\r\n        // Create a cancellation object from the winrt token.\r\n        template <typename Promise>\r\n        AsyncCancellation(winrt::impl::cancellation_token<Promise>&& token)\r\n        {\r\n            m_token = std::make_shared<details::AsyncCancellationT<Promise>>(std::move(token));\r\n        }\r\n\r\n        // Returns true if the operation has been cancelled, false if not.\r\n        bool IsCancelled() const noexcept\r\n        {\r\n            return m_token ? m_token->IsCancelled() : false;\r\n        }\r\n\r\n        // Throws the appropriate exception if the operation has been cancelled.\r\n        void ThrowIfCancelled() const\r\n        {\r\n            if (IsCancelled())\r\n            {\r\n                AICLI_LOG(Core, Warning, << \"Operation cancelled\");\r\n                throw winrt::hresult_canceled();\r\n            }\r\n        }\r\n\r\n        // Sets a callback that will be invoked on cancellation.\r\n        void Callback(winrt::delegate<>&& callback) const noexcept\r\n        {\r\n            if (m_token)\r\n            {\r\n                m_token->Callback(std::move(callback));\r\n            }\r\n        }\r\n\r\n        std::weak_ptr<details::AsyncCancellationTypeErasure> GetWeak()\r\n        {\r\n            return m_token;\r\n        }\r\n\r\n    private:\r\n        std::shared_ptr<details::AsyncCancellationTypeErasure> m_token;\r\n    };\r\n\r\n    namespace details\r\n    {\r\n        // Type erasing interface for winrt progress token.\r\n        template <typename ResultT, typename ProgressT>\r\n        struct AsyncProgressTypeErasure\r\n        {\r\n            virtual ~AsyncProgressTypeErasure() = default;\r\n\r\n            virtual void Progress(ProgressT const& progress) const = 0;\r\n\r\n            virtual void Result(ResultT const& result) const = 0;\r\n        };\r\n\r\n        // Type containing winrt progress token wrapper.\r\n        template <typename Promise, typename ResultT, typename ProgressT>\r\n        struct AsyncProgressT : public AsyncProgressTypeErasure<ResultT, ProgressT>\r\n        {\r\n            using Token = winrt::impl::progress_token<Promise, ProgressT>;\r\n\r\n            AsyncProgressT(Token&& token) : m_token(std::move(token)) {}\r\n\r\n            void Progress(ProgressT const& progress) const override\r\n            {\r\n                m_token(progress);\r\n            }\r\n\r\n            void Result(ResultT const& result) const override\r\n            {\r\n                m_token.set_result(result);\r\n            }\r\n\r\n        private:\r\n            Token m_token;\r\n        };\r\n\r\n        // Type containing winrt EventHandler.\r\n        template <typename ResultT, typename ProgressT>\r\n        struct AsyncProgressEventHandlerT : public AsyncProgressTypeErasure<ResultT, ProgressT>\r\n        {\r\n            using Token = winrt::Windows::Foundation::EventHandler<ProgressT>;\r\n\r\n            AsyncProgressEventHandlerT(Token&& token) : m_token(std::move(token)) {}\r\n\r\n            void Progress(ProgressT const& progress) const override\r\n            {\r\n                m_token(m_result, progress);\r\n            }\r\n\r\n            void Result(ResultT const& result) const override\r\n            {\r\n                m_result = result;\r\n            }\r\n\r\n        private:\r\n            mutable ResultT m_result = nullptr;\r\n            Token m_token;\r\n        };\r\n    }\r\n\r\n    // May hold a progress token and provide the ability to send progress updates.\r\n    // If empty, progress will be dropped on calls here.\r\n    template <typename ResultT, typename ProgressT>\r\n    struct AsyncProgress : public AsyncCancellation\r\n    {\r\n        // Create an empty progress object.\r\n        AsyncProgress() = default;\r\n\r\n        // Create a progress object from the winrt token.\r\n        template <typename Promise>\r\n        AsyncProgress(winrt::impl::progress_token<Promise, ProgressT>&& progress, winrt::impl::cancellation_token<Promise>&& cancellation) :\r\n            AsyncCancellation(std::move(cancellation))\r\n        {\r\n            m_token = std::make_unique<details::AsyncProgressT<Promise, ResultT, ProgressT>>(std::move(progress));\r\n        }\r\n\r\n        // Create a progress object from an EventHandler.\r\n        template <typename Promise>\r\n        AsyncProgress(winrt::Windows::Foundation::EventHandler<ProgressT>&& progress, winrt::impl::cancellation_token<Promise>&& cancellation) :\r\n            AsyncCancellation(std::move(cancellation))\r\n        {\r\n            m_token = std::make_unique<details::AsyncProgressEventHandlerT<ResultT, ProgressT>>(std::move(progress));\r\n        }\r\n\r\n        // Create a cancellation only object.\r\n        template <typename Promise>\r\n        AsyncProgress(winrt::impl::cancellation_token<Promise>&& cancellation) :\r\n            AsyncCancellation(std::move(cancellation))\r\n        {\r\n        }\r\n\r\n        // Sends progress if this object is not empty.\r\n        void Progress(ProgressT const& progress) const\r\n        {\r\n            if (m_token)\r\n            {\r\n                m_token->Progress(progress);\r\n            }\r\n        }\r\n\r\n        // Sets the result onto the progress object if it is not empty.\r\n        void Result(ResultT const& result) const\r\n        {\r\n            if (m_token)\r\n            {\r\n                m_token->Result(result);\r\n            }\r\n        }\r\n\r\n    private:\r\n        std::unique_ptr<details::AsyncProgressTypeErasure<ResultT, ProgressT>> m_token;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/COMStaticStorage.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winrt/Windows.ApplicationModel.Core.h>\r\n#include <memory>\r\n#include <shared_mutex>\r\n#include <set>\r\n#include <string>\r\n#include <string_view>\r\n\r\nnamespace AppInstaller::WinRT\r\n{\r\n    // Contains registration for static storage so that they can be cleared.\r\n    struct COMStaticStorageStatics\r\n    {\r\n        // Adds a static storage key to the set of known items.\r\n        static void AddStaticStorageItem(const winrt::hstring& name, const winrt::Windows::Foundation::IInspectable& item);\r\n\r\n        // Removes all known static storage items.\r\n        static void ResetAll();\r\n\r\n    private:\r\n        COMStaticStorageStatics() = default;\r\n\r\n        static COMStaticStorageStatics& Instance();\r\n\r\n        winrt::slim_mutex m_lock;\r\n        std::set<std::wstring> m_items;\r\n    };\r\n\r\n    // https://devblogs.microsoft.com/oldnewthing/20210215-00/?p=104865\r\n    // Base class for an object that needs to live in the COM static store.\r\n    // An object needs to use this if it has:\r\n    //  - static lifetime\r\n    //  - references to externally implemented COM objects\r\n    //\r\n    // Additionally, it should *not* contain references to WRL counted objects implemented by this module.\r\n    // If it does, it will prevent the module from being unloaded until COM is uninitialized, which is often never.\r\n    template <typename DataType>\r\n    struct COMStaticStorageBase\r\n    {\r\n    private:\r\n        struct DataHolder : public winrt::implements<DataHolder, winrt::Windows::Foundation::IInspectable>\r\n        {\r\n            std::shared_ptr<DataType> m_shared{ std::make_shared<DataType>() };\r\n        };\r\n\r\n        std::weak_ptr<DataType> m_weak;\r\n        winrt::slim_mutex m_lock;\r\n        winrt::hstring m_name;\r\n\r\n    public:\r\n        COMStaticStorageBase(std::wstring_view name) : m_name(name) {}\r\n\r\n        std::shared_ptr<DataType> Get()\r\n        {\r\n            {\r\n                const std::shared_lock lock{ m_lock };\r\n                if (auto cached = m_weak.lock())\r\n                {\r\n                    return cached;\r\n                }\r\n            }\r\n\r\n            auto value = winrt::make_self<DataHolder>();\r\n\r\n            const winrt::slim_lock_guard lock{ m_lock };\r\n            if (auto cached = m_weak.lock())\r\n            {\r\n                return cached;\r\n            }\r\n\r\n            COMStaticStorageStatics::AddStaticStorageItem(m_name, value.as<winrt::Windows::Foundation::IInspectable>());\r\n            m_weak = value->m_shared;\r\n            return value->m_shared;\r\n        }\r\n\r\n        void Reset()\r\n        {\r\n            winrt::Windows::ApplicationModel::Core::CoreApplication::Properties().TryRemove(m_name);\r\n        }\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/Certificates.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <wincrypt.h>\r\n\r\n#include <json/forwards.h>\r\n#include <wil/resource.h>\r\n\r\n#include <functional>\r\n#include <ostream>\r\n#include <vector>\r\n\r\n\r\nnamespace AppInstaller::Certificates\r\n{\r\n    // Defines the types of certificate pinning to perform.\r\n    enum class PinningVerificationType : uint32_t\r\n    {\r\n        // No validation; accepts anything.\r\n        None = 0x0,\r\n        // Validates that the public keys match; requires a certificate to be loaded.\r\n        PublicKey = 0x1,\r\n        // Validates that the full subjects match; requires a certificate to be loaded.\r\n        Subject = 0x2,\r\n        // Validates that the full issuers match; requires a certificate to be loaded.\r\n        Issuer = 0x4,\r\n        // Allows for unknown certificates in the chain; will continue to consume certificates from the chain until it matches.\r\n        // Requires partial chain.\r\n        AnyIssuer = 0x8,\r\n        // Requires that the certificate is not a leaf.\r\n        RequireNonLeaf = 0x10,\r\n    };\r\n\r\n    DEFINE_ENUM_FLAG_OPERATORS(PinningVerificationType);\r\n\r\n    std::ostream& operator<<(std::ostream& out, PinningVerificationType value);\r\n\r\n    // The position within a chain that a certificate is located.\r\n    enum class CertificateChainPosition\r\n    {\r\n        Unknown = 0x0,\r\n        // The start of the chain.\r\n        Root = 0x1,\r\n        // An indeterminate intermediate along the chain.\r\n        Intermediate = 0x2,\r\n        // The final certificate of the chain.\r\n        Leaf = 0x4,\r\n    };\r\n\r\n    DEFINE_ENUM_FLAG_OPERATORS(CertificateChainPosition);\r\n\r\n    std::ostream& operator<<(std::ostream& out, CertificateChainPosition value);\r\n\r\n    // The result of validating a single certificate.\r\n    enum class CertificatePinningValidationResult\r\n    {\r\n        // The certificate was accepted as valid.\r\n        Accepted,\r\n        // The certificate was rejected as invalid.\r\n        Rejected,\r\n        // The next certificate in the chain should be validated against the current details.\r\n        // For use by partial chain validation that does not require exacting chain configurations.\r\n        Skipped,\r\n    };\r\n\r\n    // Contains the specific information about a certificate to pin.\r\n    struct PinningDetails\r\n    {\r\n        PinningDetails() = default;\r\n\r\n        PinningDetails(const PinningDetails&) = default;\r\n        PinningDetails& operator=(const PinningDetails&) = default;\r\n\r\n        PinningDetails(PinningDetails&&) = default;\r\n        PinningDetails& operator=(PinningDetails&&) = default;\r\n\r\n        // Loads the certificate context.\r\n        PinningDetails& LoadCertificate(int resource, int resourceType);\r\n        PinningDetails& LoadCertificate(const std::vector<BYTE>& certificateBytes);\r\n        PinningDetails& LoadCertificate(const std::pair<const BYTE*,size_t> certificateBytes);\r\n        PCCERT_CONTEXT GetCertificate() const { return m_certificateContext.get(); }\r\n\r\n        PinningDetails& SetPinning(PinningVerificationType type);\r\n        PinningVerificationType GetPinning() const { return m_pinning; }\r\n\r\n        // Validates the given certificate against the pinning information.\r\n        CertificatePinningValidationResult Validate(PCCERT_CONTEXT certContext, CertificateChainPosition position) const;\r\n\r\n        // Outputs a description of the pinning details.\r\n        void OutputDescription(std::ostream& stream, std::string_view indent) const;\r\n\r\n        // Loads the pinning details from the given JSON.\r\n        [[nodiscard]] bool LoadFrom(const Json::Value& configuration);\r\n\r\n        // Determines how far the certificate is through its lifespan.\r\n        double GetRemainingLifetimePercentage() const;\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        using CustomValidationFunction = std::function<bool(const PinningDetails&, PCCERT_CONTEXT, CertificateChainPosition)>;\r\n        void SetCustomValidationFunction(CustomValidationFunction function) { m_customValidation = std::move(function); }\r\n    private:\r\n        CustomValidationFunction m_customValidation;\r\n#endif\r\n\r\n    private:\r\n        wil::shared_cert_context m_certificateContext;\r\n        PinningVerificationType m_pinning = PinningVerificationType::None;\r\n    };\r\n\r\n    // Contains the full chain of pinning details.\r\n    struct PinningChain\r\n    {\r\n        PinningChain() = default;\r\n\r\n        PinningChain(const PinningChain&) = default;\r\n        PinningChain& operator=(const PinningChain&) = default;\r\n\r\n        PinningChain(PinningChain&&) = default;\r\n        PinningChain& operator=(PinningChain&&) = default;\r\n\r\n        // A single entry in the chain.\r\n        struct Node\r\n        {\r\n            friend PinningChain;\r\n\r\n            // Access the value\r\n            PinningDetails* operator->() { return &m_chain.get()[m_index]; }\r\n\r\n            // Create/access the next node in the chain.\r\n            Node Next();\r\n            const Node Next() const;\r\n\r\n            // Drops the next node (and all subsequent nodes) from the chain.\r\n            void RemoveNext();\r\n\r\n            // Indicates if there is already an existing next node.\r\n            bool HasNext() const;\r\n\r\n        private:\r\n            Node(std::vector<PinningDetails>& chain, size_t index);\r\n\r\n            std::reference_wrapper<std::vector<PinningDetails>> m_chain;\r\n            size_t m_index = 0;\r\n        };\r\n\r\n        // Gets the root certificate pinning details in the chain.\r\n        // These will correspond to the root of the certificate chain being verified.\r\n        Node Root();\r\n        const Node Root() const;\r\n\r\n        // A partial chain will validate success if all of its components are successful.\r\n        PinningChain& PartialChain(bool isPartial = true);\r\n        bool IsPartialChain() const { return m_partial; }\r\n\r\n        // Validates the given certificate chain against the configuration.\r\n        // Returns true to indicate that the chain meets the pinning configuration criteria.\r\n        // Returns false to indicate the it does not.\r\n        bool Validate(PCCERT_CHAIN_CONTEXT chainContext) const;\r\n\r\n        // Gets a description of the pinning chain.\r\n        std::string GetDescription() const;\r\n\r\n        // Loads the pinning chain from the given JSON.\r\n        [[nodiscard]] bool LoadFrom(const Json::Value& configuration);\r\n\r\n        // Determines how far the certificate chain is through its lifespan (the minimum of all of its certificates).\r\n        double GetRemainingLifetimePercentage() const;\r\n\r\n    private:\r\n        std::vector<PinningDetails> m_chain;\r\n        bool m_partial = false;\r\n    };\r\n\r\n    // Holds the details about how a certificate chain is to be validated (aka \"pinned\").\r\n    struct PinningConfiguration\r\n    {\r\n        PinningConfiguration(std::string identifier = {});\r\n\r\n        PinningConfiguration(const PinningConfiguration&) = default;\r\n        PinningConfiguration& operator=(const PinningConfiguration&) = default;\r\n\r\n        PinningConfiguration(PinningConfiguration&&) = default;\r\n        PinningConfiguration& operator=(PinningConfiguration&&) = default;\r\n\r\n        // Adds a possible chain to the configuration.\r\n        // For a certificate to be valid, it must match only one of the configured chains.\r\n        void AddChain(PinningChain chain);\r\n\r\n        // Validates the given leaf certificate against the configuration.\r\n        // Returns true to indicate that the certificate meets the pinning configuration criteria.\r\n        // Returns false to indicate the it does not.\r\n        bool Validate(PCCERT_CONTEXT certContext) const;\r\n\r\n        // True if no pinning is configured.\r\n        bool IsEmpty() const { return m_configuration.empty(); }\r\n\r\n        // Loads the pinning configuration from the given JSON.\r\n        [[nodiscard]] bool LoadFrom(const Json::Value& configuration);\r\n\r\n        // Determines how far the configuration is through its lifespan (the maximum of all of its chains).\r\n        double GetRemainingLifetimePercentage() const;\r\n\r\n    private:\r\n        // The identifier used when logging.\r\n        std::string m_identifier;\r\n\r\n        // The configured chains.\r\n        std::vector<PinningChain> m_configuration;\r\n\r\n        // We store the last certificate that was successfully validated to speed up subsequent checks.\r\n        // Only cache a single certificate under the assumption that most of the time there will\r\n        // only be a single server certificate in use.\r\n        mutable std::vector<BYTE> m_cachedCertificate;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/Compression.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <wil/resource.h>\r\n#include <compressapi.h>\r\n#include <vector>\r\n#include <string_view>\r\n\r\nnamespace AppInstaller::Compression\r\n{\r\n    // Contains a compressor from the Windows Compression API.\r\n    struct Compressor\r\n    {\r\n        // Create a compressor using the given algorithm (see COMPRESS_ALGORITHM_*)\r\n        Compressor(DWORD algorithm);\r\n\r\n        // Compresses the given data.\r\n        std::vector<uint8_t> Compress(std::string_view data);\r\n\r\n        // Resets the compressor.\r\n        void Reset();\r\n\r\n        // Sets compressor information values.\r\n        void SetInformation(COMPRESS_INFORMATION_CLASS information, DWORD value);\r\n\r\n        // Gets compressor information values.\r\n        DWORD GetInformation(COMPRESS_INFORMATION_CLASS information);\r\n\r\n    private:\r\n        wil::unique_any<COMPRESSOR_HANDLE, decltype(CloseCompressor), CloseCompressor> m_compressor;\r\n    };\r\n\r\n    // Contains a decompressor from the Windows Compression API.\r\n    struct Decompressor\r\n    {\r\n        // Create a decompressor using the given algorithm (see COMPRESS_ALGORITHM_*)\r\n        Decompressor(DWORD algorithm);\r\n\r\n        // Decompresses the given data.\r\n        std::vector<uint8_t> Decompress(const std::vector<uint8_t>& data);\r\n\r\n        // Resets the decompressor.\r\n        void Reset();\r\n\r\n        // Sets decompressor information values.\r\n        void SetInformation(COMPRESS_INFORMATION_CLASS information, DWORD value);\r\n\r\n        // Gets decompressor information values.\r\n        DWORD GetInformation(COMPRESS_INFORMATION_CLASS information);\r\n\r\n    private:\r\n        wil::unique_any<DECOMPRESSOR_HANDLE, decltype(CloseDecompressor), CloseDecompressor> m_decompressor;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/ConfigurationSetProcessorHandlers.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerLogging.h>\r\n#include <winrt/Windows.Foundation.h>\r\n#include <memory>\r\n\r\nnamespace AppInstaller::Configuration\r\n{\r\n    constexpr std::wstring_view PowerShellHandlerIdentifier = L\"pwsh\";\r\n    constexpr std::wstring_view DynamicRuntimeHandlerIdentifier = L\"{73fea39f-6f4a-41c9-ba94-6fd14d633e40}\";\r\n    constexpr std::wstring_view DSCv3HandlerIdentifier = L\"{dbb2ac6d-1b58-4b05-9c50-b463cc434771}\";\r\n    constexpr std::wstring_view DSCv3DynamicRuntimeHandlerIdentifier = L\"{5f83e564-ca26-41ca-89db-36f5f0517ffd}\";\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/DetectMismatch.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n\n#ifndef USE_PROD_CLSIDS\n#pragma detect_mismatch(\"USE_PROD_CLSIDS\", \"Not Defined\")\n#else\n#pragma detect_mismatch(\"USE_PROD_CLSIDS\", \"Defined\")\n#endif\n\n#ifndef AICLI_DISABLE_TEST_HOOKS\n#pragma detect_mismatch(\"AICLI_DISABLE_TEST_HOOKS\", \"Not Defined\")\n#else\n#pragma detect_mismatch(\"AICLI_DISABLE_TEST_HOOKS\", \"Defined\")\n#endif\n\n#ifndef WINGET_DISABLE_EXPERIMENTAL_FEATURES\n#pragma detect_mismatch(\"WINGET_DISABLE_EXPERIMENTAL_FEATURES\", \"Not Defined\")\n#else\n#pragma detect_mismatch(\"WINGET_DISABLE_EXPERIMENTAL_FEATURES\", \"Defined\")\n#endif\n\n#ifndef USE_PROD_WINGET_SERVER\n#pragma detect_mismatch(\"USE_PROD_WINGET_SERVER\", \"Not Defined\")\n#else\n#pragma detect_mismatch(\"USE_PROD_WINGET_SERVER\", \"Defined\")\n#endif\n\n#ifndef WINGET_ENABLE_RELEASE_BUILD\n#pragma detect_mismatch(\"WINGET_ENABLE_RELEASE_BUILD\", \"Not Defined\")\n#else\n#pragma detect_mismatch(\"WINGET_ENABLE_RELEASE_BUILD\", \"Defined\")\n#endif\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/Filesystem.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <filesystem>\r\n#include <map>\r\n#include <optional>\r\n#include <vector>\r\n#include <shtypes.h>\r\n\r\nusing namespace std::chrono_literals;\r\n\r\nnamespace AppInstaller::Filesystem\r\n{\r\n    // Checks if the file system at path supports named streams/ADS\r\n    bool SupportsNamedStreams(const std::filesystem::path& path);\r\n\r\n    // Checks if the file system at path supports hard links\r\n    bool SupportsHardLinks(const std::filesystem::path& path);\r\n\r\n    // Checks if the file system at path support reparse points\r\n    bool SupportsReparsePoints(const std::filesystem::path& path);\r\n\r\n    // Checks if the canonical form of the path points to a location outside of the provided base path.\r\n    bool PathEscapesBaseDirectory(const std::filesystem::path& target, const std::filesystem::path& base);\r\n\r\n    // Renames the file to a new path.\r\n    void RenameFile(const std::filesystem::path& from, const std::filesystem::path& to);\r\n\r\n    // Creates a symlink that points to the target path.\r\n    bool CreateSymlink(const std::filesystem::path& target, const std::filesystem::path& link);\r\n\r\n    // Verifies that a symlink points to the target path.\r\n    bool VerifySymlink(const std::filesystem::path& symlink, const std::filesystem::path& target);\r\n\r\n    // Appends the .exe extension to the path if not present.\r\n    void AppendExtension(std::filesystem::path& value, const std::string& extension);\r\n\r\n    // Checks if the path is a symlink and exists.\r\n    bool SymlinkExists(const std::filesystem::path& symlinkPath);\r\n    bool CreateSymlink(const std::filesystem::path& path, const std::filesystem::path& target);\r\n\r\n    // Get expanded file system path.\r\n    std::filesystem::path GetExpandedPath(const std::string& path);\r\n\r\n    // If `source` begins with all of `prefix`, replace that with `replacement`.\r\n    // Returns true if replacement happened, false otherwise.\r\n    bool ReplaceCommonPathPrefix(std::filesystem::path& source, const std::filesystem::path& prefix, std::string_view replacement);\r\n\r\n    // Gets the path of a known folder.\r\n    std::filesystem::path GetKnownFolderPath(const KNOWNFOLDERID& id);\r\n\r\n    // Verifies that the paths are on the same volume.\r\n    bool IsSameVolume(const std::filesystem::path& path1, const std::filesystem::path& path2);\r\n\r\n    // Verifies if 'path' has parent equal to 'parentPath'\r\n    bool IsParentPath(const std::filesystem::path& path, const std::filesystem::path& parentPath);\r\n\r\n    // The principal that an ACE applies to.\r\n    enum class ACEPrincipal : uint32_t\r\n    {\r\n        CurrentUser,\r\n        Admins,\r\n        System,\r\n    };\r\n\r\n    // The permissions granted to a specific ACE.\r\n    enum class ACEPermissions : uint32_t\r\n    {\r\n        // This is not \"Deny All\", but rather, \"Not mentioned\"\r\n        None = 0x0,\r\n        Read = 0x1,\r\n        Write = 0x2,\r\n        Execute = 0x4,\r\n        ReadWrite = Read | Write,\r\n        ReadExecute = Read | Execute,\r\n        ReadWriteExecute = Read | Write | Execute,\r\n        // All means that full control will be granted\r\n        All = 0xFFFFFFFF\r\n    };\r\n\r\n    DEFINE_ENUM_FLAG_OPERATORS(ACEPermissions);\r\n\r\n    // Information about a path that we use and how to set it up.\r\n    struct PathDetails\r\n    {\r\n        std::filesystem::path Path;\r\n        // Default to creating the directory with inherited ownership and permissions\r\n        bool Create = true;\r\n        std::optional<ACEPrincipal> Owner;\r\n        std::map<ACEPrincipal, ACEPermissions> ACL;\r\n\r\n        // Shorthand for setting Owner and giving them ACEPermissions::All\r\n        void SetOwner(ACEPrincipal owner);\r\n\r\n        // Determines if the ACL should be applied.\r\n        bool ShouldApplyACL() const;\r\n\r\n        // Applies the ACL unconditionally.\r\n        void ApplyACL() const;\r\n    };\r\n\r\n    // Initializes from the given details and returns the path to it.\r\n    // The path is moved out of the details.\r\n    std::filesystem::path InitializeAndGetPathTo(PathDetails&& details);\r\n\r\n    // Gets the path to the requested location.\r\n    template <class PathEnum>\r\n    std::filesystem::path GetPathTo(PathEnum path, bool forDisplay = false)\r\n    {\r\n        return InitializeAndGetPathTo(GetPathDetailsFor(path, forDisplay));\r\n    }\r\n\r\n    // A shared path.\r\n    enum class PathName\r\n    {\r\n        // Local state root that is specifically unpackaged (even if used from a packaged process).\r\n        UnpackagedLocalStateRoot,\r\n        // Local settings root that is specifically unpackaged (even if used from a packaged process).\r\n        UnpackagedSettingsRoot,\r\n    };\r\n\r\n    // Gets the PathDetails used for the given path.\r\n    // This is exposed primarily to allow for testing, GetPathTo should be preferred.\r\n    PathDetails GetPathDetailsFor(PathName path, bool forDisplay = false);\r\n\r\n    // Gets the path to the executable for the given process.\r\n    std::filesystem::path GetExecutablePathForProcess(HANDLE process);\r\n\r\n    // Information about a specific file.\r\n    struct FileInfo\r\n    {\r\n        std::filesystem::path Path;\r\n        std::filesystem::file_time_type LastWriteTime{};\r\n        uintmax_t Size = 0;\r\n    };\r\n\r\n    // Gets the FileInfo for each regular file directly under the given directory.\r\n    std::vector<FileInfo> GetFileInfoFor(const std::filesystem::path& directory);\r\n\r\n    // Limitations on a set of files.\r\n    // Any value that is 0 is treated as no limit.\r\n    struct FileLimits\r\n    {\r\n        std::chrono::hours Age = 0h;\r\n        uint32_t TotalSizeInMB = 0;\r\n        size_t Count = 0;\r\n    };\r\n\r\n    // Modifies the given files to only include those that exceed the limits that are provided.\r\n    void FilterToFilesExceedingLimits(std::vector<FileInfo>& files, const FileLimits& limits);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/GroupPolicy.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerLanguageUtilities.h>\r\n#include <winget/Certificates.h>\r\n#include <winget/Registry.h>\r\n#include <winget/Resources.h>\r\n\r\n#include <string_view>\r\n\r\nusing namespace std::string_view_literals;\r\n\r\nnamespace AppInstaller::Settings\r\n{\r\n\r\n    // A policy that sets a value for some setting.\r\n    // The value of the policy is a value in the registry key, or is\r\n    // made up of sub-keys for settings that are lists.\r\n    enum class ValuePolicy\r\n    {\r\n        None,\r\n        SourceAutoUpdateIntervalInMinutes,\r\n        AdditionalSources,\r\n        AllowedSources,\r\n        DefaultProxy,\r\n        Max,\r\n    };\r\n\r\n    // A policy that acts as a toggle to enable or disable a feature.\r\n    // They are backed by a DWORD value with values 0 and 1.\r\n    struct TogglePolicy\r\n    {\r\n        enum class Policy\r\n        {\r\n            None = 0,\r\n            WinGet,\r\n            Settings,\r\n            ExperimentalFeatures,\r\n            LocalManifestFiles,\r\n            HashOverride,\r\n            LocalArchiveMalwareScanOverride,\r\n            DefaultSource,\r\n            MSStoreSource,\r\n            FontSource,\r\n            AdditionalSources,\r\n            AllowedSources,\r\n            BypassCertificatePinningForMicrosoftStore,\r\n            WinGetCommandLineInterfaces,\r\n            Configuration,\r\n            ProxyCommandLineOptions,\r\n            McpServer,\r\n            Max,\r\n        };\r\n\r\n        TogglePolicy(Policy policy, std::string_view regValueName, StringResource::StringId policyName, bool defaultIsEnabled = true) :\r\n            m_policy(policy), m_regValueName(regValueName), m_policyName(policyName), m_defaultIsEnabled(defaultIsEnabled) {}\r\n\r\n        static TogglePolicy GetPolicy(Policy policy);\r\n        static std::vector<TogglePolicy> GetAllPolicies();\r\n\r\n        Policy GetPolicy() const { return m_policy; }\r\n        std::string_view RegValueName() const { return m_regValueName; }\r\n        StringResource::StringId PolicyName() const { return m_policyName; }\r\n        bool DefaultIsEnabled() const { return m_defaultIsEnabled; }\r\n\r\n    private:\r\n        Policy m_policy;\r\n        std::string_view m_regValueName;\r\n        StringResource::StringId m_policyName;\r\n        bool m_defaultIsEnabled;\r\n    };\r\n\r\n    // Possible configuration states for a policy.\r\n    enum class PolicyState\r\n    {\r\n        NotConfigured,\r\n        Disabled,\r\n        Enabled,\r\n    };\r\n\r\n    // A source defined by Group Policy to be added or allowed\r\n    struct SourceFromPolicy\r\n    {\r\n        std::string Name;\r\n        std::string Arg;\r\n        std::string Type;\r\n        std::string Data;\r\n        std::string Identifier;\r\n        std::vector<std::string> TrustLevel;\r\n        bool Explicit = false;\r\n        std::optional<int32_t> Priority;\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n        Certificates::PinningConfiguration PinningConfiguration;\r\n#endif\r\n\r\n        std::string ToJsonString() const;\r\n    };\r\n\r\n\r\n    namespace details\r\n    {\r\n\r\n        template <ValuePolicy P>\r\n        struct ValuePolicyMapping\r\n        {\r\n            // value_t - type of the policy\r\n            // ReadAndValidate() - Function that reads the value and does semantic validation.\r\n\r\n            // For simple values:\r\n            //  ValueName - Name of the registry value\r\n            //  ValueType - Type of the registry value\r\n            //  reg_value_t - Type returned by the registry when reading the value\r\n\r\n            // For lists:\r\n            //  item_t - Type of each item\r\n            //  KeyName -- Name of the sub-key containing the list\r\n            //  ReadAndValidateItem() - Function that reads a single item from a subkey\r\n        };\r\n\r\n        template<>\r\n        struct ValuePolicyMapping<ValuePolicy::None>\r\n        {\r\n            using value_t = std::monostate;\r\n            using opt_value_t = std::nullopt_t;\r\n            using opt_ref_value_t = std::nullopt_t;\r\n            static std::nullopt_t ReadAndValidate(const Registry::Key& policiesKey);\r\n        };\r\n\r\n#define POLICY_MAPPING_SPECIALIZATION(_policy_, _type_, _extra_) \\\r\n        template <> \\\r\n        struct ValuePolicyMapping<_policy_> \\\r\n        { \\\r\n            using value_t = _type_; \\\r\n            using opt_value_t = std::optional<value_t>; \\\r\n            using opt_ref_value_t = std::optional<std::reference_wrapper<const value_t>>; \\\r\n            static std::optional<value_t> ReadAndValidate(const Registry::Key& policiesKey); \\\r\n            _extra_ \\\r\n        }\r\n\r\n#define POLICY_MAPPING_VALUE_SPECIALIZATION(_policy_, _type_, _valueName_, _valueType_) \\\r\n        POLICY_MAPPING_SPECIALIZATION(_policy_, _type_, \\\r\n            static constexpr std::string_view ValueName = _valueName_; \\\r\n            static constexpr Registry::Value::Type ValueType = _valueType_; \\\r\n            using reg_value_t = decltype(std::declval<Registry::Value>().GetValue<ValueType>()); \\\r\n        )\r\n\r\n#define POLICY_MAPPING_LIST_SPECIALIZATION(_policy_, _type_, _keyName_) \\\r\n        POLICY_MAPPING_SPECIALIZATION(_policy_, std::vector<_type_>, \\\r\n            static constexpr std::string_view KeyName = _keyName_; \\\r\n            using item_t = _type_; \\\r\n            static std::optional<item_t> ReadAndValidateItem(const Registry::Value& item); \\\r\n        )\r\n\r\n        POLICY_MAPPING_VALUE_SPECIALIZATION(ValuePolicy::SourceAutoUpdateIntervalInMinutes, uint32_t, \"SourceAutoUpdateInterval\"sv, Registry::Value::Type::DWord);\r\n        POLICY_MAPPING_VALUE_SPECIALIZATION(ValuePolicy::DefaultProxy, std::string, \"DefaultProxy\"sv, Registry::Value::Type::String);\r\n\r\n        POLICY_MAPPING_LIST_SPECIALIZATION(ValuePolicy::AdditionalSources, SourceFromPolicy, \"AdditionalSources\"sv);\r\n        POLICY_MAPPING_LIST_SPECIALIZATION(ValuePolicy::AllowedSources, SourceFromPolicy, \"AllowedSources\"sv);\r\n    }\r\n\r\n    // Representation of the policies read from the registry.\r\n    struct GroupPolicy\r\n    {\r\n        using ValuePoliciesMap = EnumBasedVariantMap<ValuePolicy, details::ValuePolicyMapping>;\r\n\r\n        static GroupPolicy const& Instance();\r\n\r\n        GroupPolicy(const Registry::Key& key);\r\n        ~GroupPolicy() = default;\r\n\r\n        GroupPolicy() = delete;\r\n\r\n        GroupPolicy(const GroupPolicy&) = delete;\r\n        GroupPolicy& operator=(const GroupPolicy&) = delete;\r\n\r\n        GroupPolicy(GroupPolicy&&) = delete;\r\n        GroupPolicy& operator=(GroupPolicy&&) = delete;\r\n\r\n        template<ValuePolicy P>\r\n        using ValueType = typename details::ValuePolicyMapping<P>::value_t;\r\n\r\n        // Gets the policy value if it is present\r\n        template<ValuePolicy P>\r\n        typename details::ValuePolicyMapping<P>::opt_value_t GetValue() const\r\n        {\r\n            if (m_values.Contains(P))\r\n            {\r\n                return m_values.Get<P>();\r\n            }\r\n            else\r\n            {\r\n                return std::nullopt;\r\n            }\r\n        }\r\n\r\n        template<ValuePolicy P>\r\n        typename details::ValuePolicyMapping<P>::opt_ref_value_t GetValueRef() const\r\n        {\r\n            if (m_values.Contains(P))\r\n            {\r\n                return std::cref(m_values.Get<P>());\r\n            }\r\n            else\r\n            {\r\n                return std::nullopt;\r\n            }\r\n        }\r\n\r\n        template<>\r\n        std::nullopt_t GetValue<ValuePolicy::None>() const\r\n        {\r\n            return std::nullopt;\r\n        }\r\n\r\n        template<>\r\n        std::nullopt_t GetValueRef<ValuePolicy::None>() const\r\n        {\r\n            return std::nullopt;\r\n        }\r\n\r\n        PolicyState GetState(TogglePolicy::Policy policy) const;\r\n\r\n        // Checks whether a policy is enabled, using an appropriate default when not configured.\r\n        // Should not be used when not configured means something different than enabled/disabled.\r\n        bool IsEnabled(TogglePolicy::Policy policy) const;\r\n\r\n#ifndef AICLI_DISABLE_TEST_HOOKS\r\n    protected:\r\n        static void OverrideInstance(GroupPolicy* gp);\r\n        static void ResetInstance();\r\n#else\r\n    private:\r\n#endif\r\n        std::map<TogglePolicy::Policy, PolicyState> m_toggles;\r\n        ValuePoliciesMap m_values;\r\n    };\r\n\r\n    inline const GroupPolicy& GroupPolicies()\r\n    {\r\n        return GroupPolicy::Instance();\r\n    }\r\n\r\n    struct GroupPolicyException\r\n    {\r\n        GroupPolicyException(TogglePolicy::Policy policy) : m_policy(policy) {}\r\n\r\n        const TogglePolicy::Policy& Policy() const { return m_policy; }\r\n\r\n    private:\r\n        TogglePolicy::Policy m_policy;\r\n    };\r\n\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/IConfigurationStaticsInternals.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <Unknwn.h>\r\n#include <winrt/Windows.Foundation.h>\r\n\r\nnamespace AppInstaller::WinRT\r\n{\r\n    // Flag values for SetExperimentalState.\r\n    enum class ConfigurationStaticsInternalsStateFlags : UINT32\r\n    {\r\n        None = 0,\r\n        All = None\r\n    };\r\n\r\n    DEFINE_ENUM_FLAG_OPERATORS(ConfigurationStaticsInternalsStateFlags);\r\n\r\n    MIDL_INTERFACE(\"C3886148-148A-4A3D-8018-9CDACDFC0B8D\")\r\n    IConfigurationStaticsInternals : public IUnknown\r\n    {\r\n    public:\r\n        virtual /* [local] */ HRESULT STDMETHODCALLTYPE SetExperimentalState(\r\n            UINT32 state) = 0;\r\n\r\n        virtual /* [local] */ HRESULT STDMETHODCALLTYPE BlockNewWorkForShutdown() = 0;\r\n\r\n        virtual /* [local] */ HRESULT STDMETHODCALLTYPE BeginShutdown() = 0;\r\n\r\n        virtual /* [local] */ HRESULT STDMETHODCALLTYPE WaitForShutdown() = 0;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/ILifetimeWatcher.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <Unknwn.h>\r\n#include <winrt/Windows.Foundation.h>\r\n\r\nnamespace AppInstaller::WinRT\r\n{\r\n    MIDL_INTERFACE(\"59b5623f-d03e-41f8-b400-89ee04ea02d7\")\r\n    ILifetimeWatcher : public IUnknown\r\n    {\r\n    public:\r\n        // Due to the way the winrt types are set up, this watcher will not have AddRef called.\r\n        virtual /* [local] */ HRESULT STDMETHODCALLTYPE SetLifetimeWatcher(\r\n            IUnknown* watcher) = 0;\r\n    };\r\n\r\n    // Implements ILifetimeWatcher functionality.\r\n    struct LifetimeWatcherBase\r\n    {\r\n        HRESULT STDMETHODCALLTYPE SetLifetimeWatcher(IUnknown* watcher)\r\n        {\r\n            m_lifetimeWatcher = winrt::Windows::Foundation::IUnknown(watcher, winrt::take_ownership_from_abi);\r\n            return S_OK;\r\n        }\r\n\r\n        void PropagateLifetimeWatcher(const winrt::Windows::Foundation::IUnknown& child)\r\n        {\r\n            if (m_lifetimeWatcher && child)\r\n            {\r\n                // Require that any call to this function is for an object that implements watching to prevent\r\n                // accidental assumptions about the child object and lifetime management.\r\n                auto watcher = child.as<ILifetimeWatcher>();\r\n\r\n                // Create a copy of the lifetime watcher (to add_ref), then detach and pass it to the child to own.\r\n                watcher->SetLifetimeWatcher(static_cast<IUnknown*>(winrt::detach_abi(winrt::Windows::Foundation::IUnknown{ m_lifetimeWatcher })));\r\n            }\r\n        }\r\n\r\n    private:\r\n        winrt::Windows::Foundation::IUnknown m_lifetimeWatcher;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/JsonSchemaValidation.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <json/json.h>\r\n\r\nnamespace AppInstaller::JsonSchema\r\n{\r\n    // Load schema as parsed json doc\r\n    Json::Value LoadSchemaDoc(std::string_view schemaStr);\r\n\r\n    // Load an embedded resource from binary and return as Json::Value\r\n    Json::Value LoadResourceAsSchemaDoc(PCWSTR resourceName, PCWSTR resourceType);\r\n\r\n    // Populate a valijson Schema object from a json value\r\n    void PopulateSchema(const Json::Value& schemaJson, valijson::Schema& schema);\r\n\r\n    // Validate a json doc with a schema\r\n    // Returns whether it was successful and fills the results object\r\n    bool Validate(const valijson::Schema& schema, const Json::Value& json, valijson::ValidationResults& results);\r\n\r\n    // Extracts the error messages from a result into a single non-localized string\r\n    std::string GetErrorStringFromResults(valijson::ValidationResults& results);\r\n}"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/JsonUtil.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include <json/json.h>\n\n// Disable dllimport for cpprest JSON in any downstream consumers\n#ifndef _NO_ASYNCRTIMP\n#define _NO_ASYNCRTIMP\n#endif\n\n#ifndef WINGET_DISABLE_FOR_FUZZING\n#include <cpprest/json.h>\n#endif\n\n#include <optional>\n#include <string>\n#include <vector>\n\nnamespace AppInstaller::JSON\n{\n    // For JSON CPP Lib\n    template<class T>\n    std::optional<T> GetValue(const Json::Value& node);\n\n    template<>\n    std::optional<std::string> GetValue<std::string>(const Json::Value& node);\n\n    template<>\n    std::optional<uint32_t> GetValue<uint32_t>(const Json::Value& node);\n\n    template<>\n    std::optional<bool> GetValue<bool>(const Json::Value& node);\n\n    template<>\n    std::optional<std::vector<std::string>> GetValue<std::vector<std::string>>(const Json::Value& node);\n\n#ifndef WINGET_DISABLE_FOR_FUZZING\n    // For cpprestsdk JSON\n    std::optional<std::reference_wrapper<const web::json::value>> GetJsonValueFromNode(const web::json::value& node, const utility::string_t& keyName);\n\n    std::optional<std::string> GetRawStringValueFromJsonValue(const web::json::value& value);\n    std::optional<std::wstring> GetWideStringValueFromJsonValue(const web::json::value& value);\n\n    std::optional<std::string> GetRawStringValueFromJsonNode(const web::json::value& node, const utility::string_t& keyName);\n    std::optional<std::wstring> GetWideStringValueFromJsonNode(const web::json::value& node, const utility::string_t& keyName);\n\n    std::optional<bool> GetRawBoolValueFromJsonValue(const web::json::value& value);\n\n    std::optional<bool> GetRawBoolValueFromJsonNode(const web::json::value& node, const utility::string_t& keyName);\n\n    std::optional<std::reference_wrapper<const web::json::array>> GetRawJsonArrayFromJsonNode(const web::json::value& node, const utility::string_t& keyName);\n\n    std::vector<std::string> GetRawStringArrayFromJsonNode(const web::json::value& node, const utility::string_t& keyName);\n    std::set<std::string> GetRawStringSetFromJsonNode(const web::json::value& node, const utility::string_t& keyName);\n\n    std::optional<int> GetRawIntValueFromJsonValue(const web::json::value& value);\r\n\n    std::optional<uint64_t> GetRawUInt64ValueFromJsonValue(const web::json::value& value);\n\n    std::optional<int> GetRawIntValueFromJsonNode(const web::json::value& node, const utility::string_t& keyName);\r\n\n    std::optional<uint64_t> GetRawUInt64ValueFromJsonNode(const web::json::value& node, const utility::string_t& keyName);\n\n    utility::string_t GetUtilityString(std::string_view nodeName);\n\n    web::json::value GetStringValue(std::string_view value);\n\n    // Base64 encode\n    std::string Base64Encode(const std::vector<BYTE>& input);\n\n    // Base64 decode\n    std::vector<BYTE> Base64Decode(const std::string& input);\n#endif\n\n    bool IsValidNonEmptyStringValue(std::optional<std::string>& value);\n    bool IsValidNonEmptyStringValue(std::optional<std::wstring>& value);\n}\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/LocIndependent.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include <string>\n#include <string_view>\n\nnamespace AppInstaller::Utility\n{\n    // \"I solemnly swear that this string is indeed localization independent.\"\n    // A localization independent string view.\n    // Used as a wrapper around strings that do not need localization.\n    struct LocIndView : public std::string_view\n    {\n        constexpr LocIndView() = default;\n        explicit constexpr LocIndView(std::string_view sv) : std::string_view(sv) {}\n    };\n\n    // \"I solemnly swear that this string is indeed localization independent.\"\n    // A localization independent string; either through external localization\n    // or by virtue of not needing to be localized.\n    // Intentionally does not allow the value to be modified to prevent accidental\n    // reintroduction of a localization dependent value.\n    struct LocIndString\n    {\n        LocIndString() = default;\n\n        explicit LocIndString(std::string_view sv) : m_value(sv) {}\n        explicit LocIndString(std::string v) : m_value(std::move(v)) {}\n\n        LocIndString(const LocIndString&) = default;\n        LocIndString& operator=(const LocIndString&) = default;\n\n        LocIndString(LocIndString&&) = default;\n        LocIndString& operator=(LocIndString&&) = default;\n\n        bool empty() const { return m_value.empty(); }\n\n        const std::string& get() const & { return m_value; }\n        std::string&& get() && { return std::move(m_value); }\n\n        operator const std::string& () const { return m_value; }\n        operator std::string_view() const { return m_value; }\n        operator LocIndView() const { return LocIndView{ static_cast<std::string_view>(m_value) }; }\n\n        const std::string* operator->() const { return &m_value; }\n\n        bool operator==(std::string_view sv) const { return m_value == sv; }\n        bool operator!=(const LocIndString& other) const { return m_value != other.m_value; }\n\n        bool operator<(const LocIndString& other) const { return m_value < other.m_value; }\n        bool operator<(const std::string& other) const { return m_value < other; }\n\n        friend std::ostream& operator<<(std::ostream& out, const AppInstaller::Utility::LocIndString& lis)\n        {\n            return (out << lis.get());\n        }\n\n    private:\n        std::string m_value;\n    };\n\n    namespace literals\n    {\n        // \"I solemnly swear that this string is indeed localization independent.\"\n        // Enable easier use of a localization independent view through literals.\n        inline constexpr LocIndView operator \"\"_liv(const char* chars, size_t size)\n        {\n            return LocIndView{ std::string_view{ chars, size } };\n        }\n\n        // \"I solemnly swear that this string is indeed localization independent.\"\n        // Enable easier use of a localization independent string through literals.\n        inline LocIndString operator \"\"_lis(const char* chars, size_t size)\n        {\n            return LocIndString{ std::string_view{ chars, size } };\n        }\n    }\n}\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/ManagedFile.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <wil/resource.h>\r\n#include <filesystem>\r\n\r\nnamespace AppInstaller::Utility\r\n{\r\n    // Struct that holds a file handle and may perform additional operations on exit\r\n    struct ManagedFile\r\n    {\r\n        ManagedFile() = default;\r\n\r\n        ManagedFile(const ManagedFile&) = delete;\r\n        ManagedFile& operator=(const ManagedFile&) = delete;\r\n\r\n        ManagedFile(ManagedFile&&) = default;\r\n        ManagedFile& operator=(ManagedFile&&) = default;\r\n\r\n        HANDLE GetFileHandle() const { return m_fileHandle.get(); }\r\n        const std::filesystem::path& GetFilePath() const { return m_filePath; }\r\n\r\n        // Always creates a new write locked file at the path given. desiredAccess is passed to CreateFile call.\r\n        static ManagedFile CreateWriteLockedFile(const std::filesystem::path& path, DWORD desiredAccess, bool deleteOnExit);\r\n\r\n        // Always opens an existing file at the path given with write locked. desiredAccess is passed to CreateFile call.\r\n        static ManagedFile OpenWriteLockedFile(const std::filesystem::path& path, DWORD desiredAccess);\r\n\r\n        ~ManagedFile();\r\n\r\n    private:\r\n        std::filesystem::path m_filePath;\r\n        wil::unique_handle m_fileHandle;\r\n        bool m_deleteFileOnExit = false;\r\n    };\r\n}"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/ModuleCountBase.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <wrl\\module.h>\r\n\r\nnamespace AppInstaller::WinRT\r\n{\r\n    // Implements module count interactions.\r\n    struct ModuleCountBase\r\n    {\r\n        ModuleCountBase()\r\n        {\r\n            if (auto modulePtr = ::Microsoft::WRL::GetModuleBase())\r\n            {\r\n                modulePtr->IncrementObjectCount();\r\n            }\r\n        }\r\n\r\n        ~ModuleCountBase()\r\n        {\r\n            if (auto modulePtr = ::Microsoft::WRL::GetModuleBase())\r\n            {\r\n                modulePtr->DecrementObjectCount();\r\n            }\r\n        }\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/PathTree.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <wil/result.h>\r\n#include <functional>\r\n#include <map>\r\n#include <queue>\r\n\r\nnamespace AppInstaller::Filesystem\r\n{\r\n    // Container that holds a map of items addressable by path.\r\n    template <typename Value>\r\n    struct PathTree\r\n    {\r\n        using value_t = Value;\r\n\r\n        PathTree() = default;\r\n\r\n    private:\r\n        struct Node\r\n        {\r\n            value_t Value{};\r\n            std::map<std::filesystem::path, Node> Children;\r\n        };\r\n\r\n    public:\r\n        // Returns the value for the given path, inserting it if necessary.\r\n        value_t& FindOrInsert(const std::filesystem::path& path)\r\n        {\r\n            return FindNode(path, true)->Value;\r\n        }\r\n\r\n        // Finds the value for the given path; returns null if not found.\r\n        value_t* Find(const std::filesystem::path& path)\r\n        {\r\n            Node* node = FindNode(path, false);\r\n            return node ? &node->Value : nullptr;\r\n        }\r\n\r\n        // Finds the value for the given path; returns null if not found.\r\n        const value_t* Find(const std::filesystem::path& path) const\r\n        {\r\n            const Node* node = FindNode(path);\r\n            return node ? &node->Value : nullptr;\r\n        }\r\n\r\n        // Invokes the `visit` function for each value in the tree starting at `initialPath` (unconditionally)\r\n        // and recursively continuing on to children for whom the predicate returns true.\r\n        void VisitIf(const std::filesystem::path& initialPath, std::function<void(const value_t&)> visit, std::function<bool(const value_t&)> predicate) const\r\n        {\r\n            const Node* node = FindNode(initialPath);\r\n            if (node)\r\n            {\r\n                std::queue<const Node*> nodes;\r\n                nodes.push(node);\r\n\r\n                while (!nodes.empty())\r\n                {\r\n                    const Node* currentNode = nodes.front();\r\n                    nodes.pop();\r\n\r\n                    visit(currentNode->Value);\r\n\r\n                    for (const auto& child : currentNode->Children)\r\n                    {\r\n                        if (predicate(child.second.Value))\r\n                        {\r\n                            nodes.push(&child.second);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n    private:\r\n        // Finds the node for the given path, creating as needed if requested.\r\n        Node* FindNode(const std::filesystem::path& path, bool createIfNeeded)\r\n        {\r\n            if (path.empty())\r\n            {\r\n                if (createIfNeeded)\r\n                {\r\n                    THROW_HR(E_INVALIDARG);\r\n                }\r\n                else\r\n                {\r\n                    return nullptr;\r\n                }\r\n            }\r\n\r\n            const auto& nodePath = std::filesystem::weakly_canonical(path);\r\n            Node* currentNode = &m_rootNode;\r\n\r\n            for (const auto& pathPart : nodePath)\r\n            {\r\n                auto& children = currentNode->Children;\r\n\r\n                if (createIfNeeded)\r\n                {\r\n                    currentNode = &children[pathPart];\r\n                }\r\n                else\r\n                {\r\n                    auto itr = children.find(pathPart);\r\n\r\n                    if (itr != children.end())\r\n                    {\r\n                        currentNode = &itr->second;\r\n                    }\r\n                    else\r\n                    {\r\n                        // Not found and should not create\r\n                        return nullptr;\r\n                    }\r\n                }\r\n            }\r\n\r\n            return currentNode;\r\n        }\r\n\r\n        // Finds the node for the given path; returns null if not found.\r\n        const Node* FindNode(const std::filesystem::path& path) const\r\n        {\r\n            return const_cast<PathTree*>(this)->FindNode(path, false);\r\n        }\r\n\r\n        Node m_rootNode;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/Registry.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <wil/resource.h>\r\n\r\n#include <optional>\r\n#include <string>\r\n#include <string_view>\r\n#include <vector>\r\n\r\n#define AICLI_REGISTRY_UTF16_FLAG 0x08000000\r\n\r\nnamespace AppInstaller::Registry\r\n{\r\n    namespace details\r\n    {\r\n        template<DWORD>\r\n        constexpr bool dependent_false = false;\r\n\r\n        template <DWORD Type>\r\n        struct ValueTypeSpecifics\r\n        {\r\n            using value_t = void;\r\n\r\n            static value_t Convert(const std::vector<BYTE>& data)\r\n            {\r\n                static_assert(dependent_false<Type>, \"No Type specific override has been supplied\");\r\n            }\r\n        };\r\n\r\n        template <>\r\n        struct ValueTypeSpecifics<REG_NONE>\r\n        {\r\n            using value_t = std::vector<BYTE>;\r\n            static value_t Convert(const std::vector<BYTE>& data);\r\n        };\r\n\r\n        template <>\r\n        struct ValueTypeSpecifics<REG_SZ>\r\n        {\r\n            using value_t = std::string;\r\n            static value_t Convert(const std::vector<BYTE>& data);\r\n        };\r\n\r\n        template <>\r\n        struct ValueTypeSpecifics<REG_SZ | AICLI_REGISTRY_UTF16_FLAG>\r\n        {\r\n            using value_t = std::wstring;\r\n            static value_t Convert(const std::vector<BYTE>& data);\r\n        };\r\n\r\n        template <>\r\n        struct ValueTypeSpecifics<REG_EXPAND_SZ>\r\n        {\r\n            using value_t = std::string;\r\n            static value_t Convert(const std::vector<BYTE>& data);\r\n        };\r\n\r\n        template <>\r\n        struct ValueTypeSpecifics<REG_EXPAND_SZ | AICLI_REGISTRY_UTF16_FLAG>\r\n        {\r\n            using value_t = std::wstring;\r\n            static value_t Convert(const std::vector<BYTE>& data);\r\n        };\r\n\r\n        template <>\r\n        struct ValueTypeSpecifics<REG_BINARY>\r\n        {\r\n            using value_t = std::vector<BYTE>;\r\n            static value_t Convert(const std::vector<BYTE>& data);\r\n        };\r\n\r\n        template <>\r\n        struct ValueTypeSpecifics<REG_DWORD_LITTLE_ENDIAN>\r\n        {\r\n            using value_t = uint32_t;\r\n            static value_t Convert(const std::vector<BYTE>& data);\r\n        };\r\n    }\r\n\r\n    struct Key;\r\n    struct ValueList;\r\n\r\n    // A registry value.\r\n    struct Value\r\n    {\r\n        friend Key;\r\n        friend ValueList;\r\n\r\n        // The type of data stored in the Value.\r\n        enum class Type : DWORD\r\n        {\r\n            None = REG_NONE,\r\n            String = REG_SZ,\r\n            UTF16Flag = AICLI_REGISTRY_UTF16_FLAG,\r\n            UTF16String = REG_SZ | UTF16Flag,\r\n            ExpandString = REG_EXPAND_SZ,\r\n            UTF16ExpandString = REG_EXPAND_SZ | UTF16Flag,\r\n            Binary = REG_BINARY,\r\n            DWord = REG_DWORD,\r\n            DWordLittleEndian = REG_DWORD_LITTLE_ENDIAN,\r\n            DWordBigEndian = REG_DWORD_BIG_ENDIAN,\r\n            MultiString = REG_MULTI_SZ,\r\n            QWord = REG_QWORD,\r\n            QWordLittleEndian = REG_QWORD_LITTLE_ENDIAN,\r\n        };\r\n\r\n        Type GetType() const { return m_type; }\r\n\r\n        template <Type T>\r\n        typename details::ValueTypeSpecifics<static_cast<DWORD>(T)>::value_t GetValue() const\r\n        {\r\n            auto value = TryGetValue<T>();\r\n            if (!value.has_value())\r\n            {\r\n                THROW_HR(E_INVALIDARG);\r\n            }\r\n\r\n            return std::move(value.value());\r\n        }\r\n\r\n        template <Type T>\r\n        typename std::optional<typename details::ValueTypeSpecifics<static_cast<DWORD>(T)>::value_t> TryGetValue() const\r\n        {\r\n            if (HasCompatibleType(T))\r\n            {\r\n                return details::ValueTypeSpecifics<static_cast<DWORD>(T)>::Convert(m_data);\r\n            }\r\n            else\r\n            {\r\n                return std::nullopt;\r\n            }\r\n        }\r\n\r\n    private:\r\n        Value(DWORD type, std::vector<BYTE>&& data);\r\n\r\n        bool HasCompatibleType(Type type) const;\r\n\r\n        Type m_type;\r\n        std::vector<BYTE> m_data;\r\n    };\r\n\r\n    // Value iteration\r\n    struct ValueList\r\n    {\r\n        friend Key;\r\n\r\n        struct const_iterator;\r\n\r\n        struct ValueRef\r\n        {\r\n            friend const_iterator;\r\n\r\n            // Gets the name of the value.\r\n            std::string Name() const;\r\n\r\n            // Gets the actual value of the value.\r\n            // The optional allows for the potential race with the value being removed.\r\n            std::optional<Value> Value() const;\r\n\r\n        private:\r\n            ValueRef(wil::shared_hkey key, std::wstring&& valueName);\r\n\r\n            wil::shared_hkey m_key;\r\n            std::wstring m_valueName;\r\n        };\r\n\r\n        struct const_iterator\r\n        {\r\n            friend ValueList;\r\n\r\n            const_iterator& operator++();\r\n            const_iterator operator++(int);\r\n\r\n            bool operator==(const const_iterator& other) const;\r\n            bool operator!=(const const_iterator& other) const;\r\n\r\n            const ValueRef& operator*() const;\r\n            const ValueRef* operator->() const;\r\n\r\n        private:\r\n            // Create an iterator\r\n            const_iterator(const wil::shared_hkey& key, DWORD index = 0);\r\n\r\n            // Create an iterator for end\r\n            const_iterator() = default;\r\n\r\n            void GetValue();\r\n\r\n            // An empty handle represents the end iterator.\r\n            wil::shared_hkey m_key;\r\n            DWORD m_index = 0;\r\n            std::optional<ValueRef> m_value;\r\n        };\r\n\r\n        const_iterator begin() const;\r\n        const_iterator end() const;\r\n\r\n    private:\r\n        ValueList(wil::shared_hkey key);\r\n\r\n        wil::shared_hkey m_key;\r\n    };\r\n\r\n    // A registry key.\r\n    struct Key\r\n    {\r\n        Key() = default;\r\n        Key(HKEY key);\r\n        Key(HKEY key, std::string_view subKey, DWORD options = 0, REGSAM access = KEY_READ);\r\n        Key(HKEY key, const std::wstring& subKey, DWORD options = 0, REGSAM access = KEY_READ);\r\n\r\n        // --== Sub-Key iteration ==--\r\n        struct const_iterator;\r\n\r\n        struct SubKeyRef\r\n        {\r\n            friend const_iterator;\r\n\r\n            // Gets the name of the subkey.\r\n            std::string Name() const;\r\n\r\n            // Opens the subkey.\r\n            Key Open() const;\r\n\r\n            operator bool() const { return m_parentKey.operator bool(); }\r\n\r\n        private:\r\n            // For a valid iterator\r\n            SubKeyRef(const wil::shared_hkey& key, REGSAM access);\r\n\r\n            // For the end iterator\r\n            SubKeyRef() = default;\r\n\r\n            // Enumerates the subkey of m_parentKey at the given index.\r\n            void Enum(DWORD index);\r\n\r\n            wil::shared_hkey m_parentKey;\r\n            REGSAM m_access = KEY_READ;\r\n            std::wstring m_subKeyName;\r\n        };\r\n\r\n        struct const_iterator\r\n        {\r\n            friend Key;\r\n\r\n            const_iterator& operator++();\r\n            const_iterator operator++(int);\r\n\r\n            bool operator==(const const_iterator& other) const;\r\n            bool operator!=(const const_iterator& other) const;\r\n\r\n            const SubKeyRef& operator*() const;\r\n            const SubKeyRef* operator->() const;\r\n\r\n        private:\r\n            // Create an iterator for begin\r\n            const_iterator(const wil::shared_hkey& key, REGSAM access);\r\n\r\n            // Create an iterator for end\r\n            const_iterator() = default;\r\n\r\n            DWORD m_index = 0;\r\n            SubKeyRef m_subkey;\r\n        };\r\n\r\n        const_iterator begin() const;\r\n        const_iterator end() const;\r\n\r\n        std::optional<Value> operator[](std::string_view name) const;\r\n        std::optional<Value> operator[](const std::wstring& name) const;\r\n\r\n        void DeleteValue(std::string_view name) const;\r\n        void DeleteValue(const std::wstring& name) const;\r\n\r\n        std::optional<Key> SubKey(std::string_view name, DWORD options = 0) const;\r\n        std::optional<Key> SubKey(const std::wstring& name, DWORD options = 0) const;\r\n\r\n        // Set registry values.\r\n        void SetValue(const std::wstring& name, const std::wstring& value, DWORD type = REG_SZ) const;\r\n        void SetValue(const std::wstring& name, const std::vector<BYTE>& value, DWORD type = REG_BINARY) const;\r\n        void SetValue(const std::wstring& name, DWORD value) const;\r\n\r\n        ValueList Values() const;\r\n\r\n        operator bool() const { return m_key.operator bool(); }\r\n        operator HKEY() const { return m_key.get(); }\r\n\r\n        // Open a Key; will return an empty Key if the subkey does not exist.\r\n        static Key OpenIfExists(HKEY key, std::string_view subKey = {}, DWORD options = 0, REGSAM access = KEY_READ);\r\n        static Key OpenIfExists(HKEY key, const std::wstring& subKey = {}, DWORD options = 0, REGSAM access = KEY_READ);\r\n\r\n        // Creates a new Key or returns one if it already existed. \r\n        static Key Create(HKEY key, std::string_view subkey = {}, DWORD options = REG_OPTION_NON_VOLATILE, REGSAM access = KEY_ALL_ACCESS);\r\n        static Key Create(HKEY key, const std::wstring& subKey = {}, DWORD options = REG_OPTION_NON_VOLATILE, REGSAM access = KEY_ALL_ACCESS);\r\n\r\n        // Delete a key\r\n        static bool Delete(HKEY key, std::string_view subkey, DWORD samDesired);\r\n        static bool Delete(HKEY key, const std::wstring& subKey, DWORD samDesired);\r\n        static bool DeleteTree(HKEY key, const std::wstring& subKey);\r\n\r\n    private:\r\n        // When ignoring error, returns whether the key existed\r\n        bool Initialize(HKEY key, const std::wstring& subKey, DWORD options, REGSAM access, bool ignoreErrorIfDoesNotExist);\r\n\r\n        // Returns whether the key was created successfully.\r\n        bool CreateAndOpen(HKEY key, const std::wstring& subKey, DWORD options, REGSAM access);\r\n\r\n        wil::shared_hkey m_key;\r\n        REGSAM m_access = KEY_READ;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/Resources.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winrt/Windows.ApplicationModel.Resources.h>\r\n\r\n#include <string>\r\n#include <optional>\r\n#include <vector>\r\n#include \"AppInstallerStrings.h\"\r\n\r\nusing namespace std::string_view_literals;\r\n\r\nnamespace AppInstaller\r\n{\r\n    namespace StringResource\r\n    {\r\n#define WINGET_WIDE_STRINGIFY_HELP(_id_) L ## _id_\r\n#define WINGET_WIDE_STRINGIFY(_id_) WINGET_WIDE_STRINGIFY_HELP(_id_)\r\n#define WINGET_DEFINE_RESOURCE_STRINGID(_id_) static constexpr AppInstaller::StringResource::StringId _id_ { WINGET_WIDE_STRINGIFY(#_id_) ## sv }\r\n\r\n        // A resource identifier\r\n        struct StringId : public std::wstring_view\r\n        {\r\n            explicit constexpr StringId(std::wstring_view id) : std::wstring_view(id) {}\r\n\r\n            // Sets the placeholder values in the resolved string id.\r\n            // Example: out << myStringId(placeholderVal1, placeholderVal2, ...)\r\n            template<typename ...T>\r\n            Utility::LocIndString operator()(T ... args) const;\r\n\r\n            // Creates a StringId that represents an empty resource string\r\n            static StringId Empty();\r\n\r\n        private:\r\n            // Resolve the string ID to its corresponding localized string\r\n            // without replacing placeholders.\r\n            std::string Resolve() const;\r\n        };\r\n\r\n        inline StringId StringId::Empty() { return StringId{ {} }; }\r\n\r\n        // Output resource identifier as localized string.\r\n        std::ostream& operator<<(std::ostream& out, StringId si);\r\n\r\n        // Resource string identifiers.\r\n        struct String\r\n        {\r\n            WINGET_DEFINE_RESOURCE_STRINGID(PolicyEnableWinGet);\r\n            WINGET_DEFINE_RESOURCE_STRINGID(PolicyEnableWingetSettings);\r\n            WINGET_DEFINE_RESOURCE_STRINGID(PolicyEnableExperimentalFeatures);\r\n            WINGET_DEFINE_RESOURCE_STRINGID(PolicyEnableLocalManifests);\r\n            WINGET_DEFINE_RESOURCE_STRINGID(PolicyEnableHashOverride);\r\n            WINGET_DEFINE_RESOURCE_STRINGID(PolicyEnableLocalArchiveMalwareScanOverride);\r\n            WINGET_DEFINE_RESOURCE_STRINGID(PolicyEnableDefaultSource);\r\n            WINGET_DEFINE_RESOURCE_STRINGID(PolicyEnableMSStoreSource);\r\n            WINGET_DEFINE_RESOURCE_STRINGID(PolicyEnableFontSource);\r\n            WINGET_DEFINE_RESOURCE_STRINGID(PolicyAdditionalSources);\r\n            WINGET_DEFINE_RESOURCE_STRINGID(PolicyAllowedSources);\r\n            WINGET_DEFINE_RESOURCE_STRINGID(PolicySourceAutoUpdateInterval);\r\n            WINGET_DEFINE_RESOURCE_STRINGID(PolicyEnableBypassCertificatePinningForMicrosoftStore);\r\n            WINGET_DEFINE_RESOURCE_STRINGID(PolicyEnableWindowsPackageManagerCommandLineInterfaces);\r\n            WINGET_DEFINE_RESOURCE_STRINGID(PolicyEnableWinGetConfiguration);\r\n            WINGET_DEFINE_RESOURCE_STRINGID(PolicyEnableProxyCommandLineOptions);\r\n            WINGET_DEFINE_RESOURCE_STRINGID(PolicyEnableMcpServer);\r\n\r\n            WINGET_DEFINE_RESOURCE_STRINGID(SettingsWarningInvalidFieldFormat);\r\n            WINGET_DEFINE_RESOURCE_STRINGID(SettingsWarningInvalidFieldValue);\r\n            WINGET_DEFINE_RESOURCE_STRINGID(SettingsWarningInvalidValueFromPolicy);\r\n            WINGET_DEFINE_RESOURCE_STRINGID(SettingsWarningLoadedBackupSettings);\r\n            WINGET_DEFINE_RESOURCE_STRINGID(SettingsWarningParseError);\r\n            WINGET_DEFINE_RESOURCE_STRINGID(SettingsWarningUsingDefault);\r\n\r\n            WINGET_DEFINE_RESOURCE_STRINGID(UnknownErrorCode);\r\n        };\r\n    }\r\n\r\n    namespace Resource\r\n    {\r\n        // Get an embedded resource from the binary and return as std::string_view.\r\n        // Resource data is valid as long as the binary is loaded.\r\n        std::string_view GetResourceAsString(int resourceName, int resourceType);\r\n        std::string_view GetResourceAsString(PCWSTR resourceName, PCWSTR resourceType);\r\n\r\n        // Get an embedded resource from the binary and return as std::pair<BYTE*, size_t>.\r\n        // Resource data is valid as long as the binary is loaded.\r\n        std::pair<const BYTE*, size_t> GetResourceAsBytes(int resourceName, int resourceType);\r\n        std::pair<const BYTE*, size_t> GetResourceAsBytes(PCWSTR resourceName, PCWSTR resourceType);\r\n\r\n        // A localized string\r\n        struct LocString : public Utility::LocIndString\r\n        {\r\n            LocString() = default;\r\n\r\n            LocString(StringResource::StringId id) : Utility::LocIndString(id()) {}\r\n            LocString(Utility::LocIndString locIndString) : Utility::LocIndString(std::move(locIndString)) {}\r\n\r\n            LocString(const LocString&) = default;\r\n            LocString& operator=(const LocString&) = default;\r\n\r\n            LocString(LocString&&) = default;\r\n            LocString& operator=(LocString&&) = default;\r\n        };\r\n    }\r\n\r\n    namespace StringResource\r\n    {\r\n        // Tries to resolve a string, returning a nullopt if it cannot.\r\n        std::optional<Resource::LocString> TryResolveString(std::wstring_view resKey);\r\n    }\r\n\r\n    namespace details\r\n    {\r\n        // List of approved types for output, others are potentially not localized.\r\n        template <typename T>\r\n        struct IsApprovedForOutput\r\n        {\r\n            static constexpr bool value = std::is_arithmetic<T>::value;\r\n        };\r\n\r\n#define WINGET_CREATE_ISAPPROVEDFOROUTPUT_SPECIALIZATION(_t_) \\\r\n        template <> \\\r\n        struct IsApprovedForOutput<_t_> \\\r\n        { \\\r\n            static constexpr bool value = true; \\\r\n        }\r\n\r\n        // It is assumed that single char values need not be localized, as they are matched\r\n        // ordinally or they are punctuation / other.\r\n        WINGET_CREATE_ISAPPROVEDFOROUTPUT_SPECIALIZATION(char);\r\n        // Localized strings (and from an Id for one for convenience).\r\n        WINGET_CREATE_ISAPPROVEDFOROUTPUT_SPECIALIZATION(StringResource::StringId);\r\n        WINGET_CREATE_ISAPPROVEDFOROUTPUT_SPECIALIZATION(Resource::LocString);\r\n        // Strings explicitly declared as localization independent.\r\n        WINGET_CREATE_ISAPPROVEDFOROUTPUT_SPECIALIZATION(Utility::LocIndView);\r\n        WINGET_CREATE_ISAPPROVEDFOROUTPUT_SPECIALIZATION(Utility::LocIndString);\r\n        // Normalized strings come from user data and should therefore already by localized\r\n        // by how they are chosen (or there is no localized version).\r\n        WINGET_CREATE_ISAPPROVEDFOROUTPUT_SPECIALIZATION(Utility::NormalizedString);\r\n    }\r\n\r\n    template<typename ... T>\r\n    Utility::LocIndString StringResource::StringId::operator()(T ... args) const\r\n    {\r\n        static_assert((details::IsApprovedForOutput<std::decay_t<T>>::value && ...), \"This type may not be localized, see comment for more information\");\r\n        return Utility::LocIndString{ Utility::Format(Resolve(), std::forward<T>(args)...) };\r\n    }\r\n}\r\n\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/Runtime.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerVersions.h>\r\n#include <winget/LocIndependent.h>\r\n\r\n#include <filesystem>\r\n#include <memory>\r\n#include <string>\r\n#include <string_view>\r\n\r\nnamespace AppInstaller::Runtime\r\n{\r\n    // Determines whether the process is running in a packaged context or not.\r\n    bool IsRunningInPackagedContext();\r\n\r\n    // Determines the current version of the client and returns it.\r\n    Utility::LocIndString GetClientVersion();\r\n\r\n    // Gets the package family name of the current package (or empty string if not packaged).\r\n    std::wstring GetPackageFamilyName();\r\n\r\n    // Determines the current version of the package if running in a packaged context.\r\n    Utility::LocIndString GetPackageVersion();\r\n\r\n    // Gets a string representation of the OS version for debugging purposes.\r\n    Utility::LocIndString GetOSVersion();\r\n\r\n    // Gets the OS region.\r\n    // This can be used as the current market.\r\n    std::string GetOSRegion();\r\n\r\n    // Determines whether the current OS version is >= the given one.\r\n    // We treat the given Version struct as a standard 4 part Windows OS version.\r\n    bool IsCurrentOSVersionGreaterThanOrEqual(const Utility::Version& version);\r\n\r\n    // Determines whether the process is running with administrator privileges.\r\n    bool IsRunningAsAdmin();\r\n\r\n    // Determines whether the process is running with local system context.\r\n    bool IsRunningAsSystem();\r\n\r\n    // Determines whether the process is running with administrator or system privileges.\r\n    bool IsRunningAsAdminOrSystem();\r\n\r\n    // Determines whether the current token can be elevated.\r\n    // This only returns true for tokens that are TokenElevationTypeLimited.\r\n    // Thus, it will only be true if:\r\n    //  1. UAC is enabled\r\n    //  2. the user is in the Administrators group\r\n    //  3. the token is not already elevated\r\n    bool IsRunningWithLimitedToken();\r\n\r\n    // Returns true if this is a release build; false if not.\r\n    inline constexpr bool IsReleaseBuild()\r\n    {\r\n#ifdef WINGET_ENABLE_RELEASE_BUILD\r\n        return true;\r\n#else\r\n        return false;\r\n#endif\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/SQLiteDynamicStorage.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteStorageBase.h>\r\n#include <concurrencysal.h>\r\n#include <filesystem>\r\n#include <memory>\r\n\r\nnamespace AppInstaller::SQLite\r\n{\r\n    // Type the allows for the schema version of the underlying storage to be changed dynamically.\r\n    struct SQLiteDynamicStorage : public SQLiteStorageBase\r\n    {\r\n        // Creates a new database with the given schema version.\r\n        SQLiteDynamicStorage(const std::string& target, const Version& version);\r\n        SQLiteDynamicStorage(const std::filesystem::path& target, const Version& version);\r\n\r\n        // Opens an existing database with the given disposition.\r\n        SQLiteDynamicStorage(const std::string& filePath, SQLiteStorageBase::OpenDisposition disposition, Utility::ManagedFile&& file = {});\r\n        SQLiteDynamicStorage(const std::filesystem::path& filePath, SQLiteStorageBase::OpenDisposition disposition, Utility::ManagedFile&& file = {});\r\n\r\n        // Implicit conversion to a connection object for convenience.\r\n        operator Connection& ();\r\n        operator const Connection& () const;\r\n        Connection& GetConnection();\r\n        const Connection& GetConnection() const;\r\n\r\n        using SQLiteStorageBase::SetLastWriteTime;\r\n\r\n        // Must be kept alive to ensure consistent schema view and exclusive use of the owned connection.\r\n        struct TransactionLock\r\n        {\r\n            _Acquires_lock_(mutex)\r\n            TransactionLock(std::mutex& mutex);\r\n\r\n            _Acquires_lock_(mutex)\r\n            TransactionLock(std::mutex& mutex, Connection& connection, std::string_view name, bool immediateWrite);\r\n\r\n            // Abandons the transaction and any changes; releases the connection lock.\r\n            void Rollback(bool throwOnError = true);\r\n\r\n            // Commits the transaction and releases the connection lock.\r\n            void Commit();\r\n\r\n        private:\r\n            std::lock_guard<std::mutex> m_lock;\r\n            Transaction m_transaction;\r\n        };\r\n\r\n        // Acquires the connection lock and begins a transaction on the database.\r\n        // If the returned result is empty, the schema version has changed and the caller must handle this.\r\n        std::unique_ptr<TransactionLock> TryBeginTransaction(std::string_view name, bool immediateWrite);\r\n\r\n        // Locks the connection for use during the schema upgrade.\r\n        std::unique_ptr<TransactionLock> LockConnection();\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/SQLiteMetadataTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteWrapper.h>\r\n\r\n#include <wil/result_macros.h>\r\n#include <string_view>\r\n\r\nnamespace AppInstaller::SQLite\r\n{\r\n    using namespace std::string_view_literals;\r\n\r\n    static constexpr std::string_view s_MetadataValueName_DatabaseIdentifier = \"databaseIdentifier\"sv;\r\n    static constexpr std::string_view s_MetadataValueName_MajorVersion = \"majorVersion\"sv;\r\n    static constexpr std::string_view s_MetadataValueName_MinorVersion = \"minorVersion\"sv;\r\n    static constexpr std::string_view s_MetadataValueName_LastWriteTime = \"lastwritetime\"sv;\r\n\r\n    // The metadata table for the database.\r\n    // Contains a fixed-schema set of named values that can be used to determine how to read the rest of the database.\r\n    struct MetadataTable\r\n    {\r\n        static void Create(Connection& connection);\r\n\r\n        // Gets the named value from the metadata table, interpreting it as the given type.\r\n        template <typename Value>\r\n        static Value GetNamedValue(const Connection& connection, std::string_view name)\r\n        {\r\n            Statement statement = GetNamedValueStatement(connection, name);\r\n            return statement.GetColumn<Value>(0);\r\n        }\r\n\r\n        // Gets the named value from the metadata table, interpreting it as the given type.\r\n        // Returns nullopt if the value is not present.\r\n        template <typename Value>\r\n        static std::optional<Value> TryGetNamedValue(const Connection& connection, std::string_view name)\r\n        {\r\n            std::optional<Statement> statement = TryGetNamedValueStatement(connection, name);\r\n            if (statement)\r\n            {\r\n                return statement->GetColumn<Value>(0);\r\n            }\r\n            else\r\n            {\r\n                return std::nullopt;\r\n            }\r\n        }\r\n\r\n        // Sets the named value into the metadata table.\r\n        template <typename Value>\r\n        static void SetNamedValue(const Connection& connection, std::string_view name, Value&& v)\r\n        {\r\n            Statement statement = SetNamedValueStatement(connection, name);\r\n            statement.Bind(2, std::forward<Value>(v));\r\n            statement.Execute();\r\n        }\r\n\r\n    private:\r\n        // Internal function that gets the named value.\r\n        static Statement GetNamedValueStatement(const Connection& connection, std::string_view name);\r\n\r\n        // Internal function that gets the named value, or nullopt if it is not present.\r\n        static std::optional<Statement> TryGetNamedValueStatement(const Connection& connection, std::string_view name);\r\n\r\n        // Internal function that sets the named value.\r\n        static Statement SetNamedValueStatement(const Connection& connection, std::string_view name);\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/SQLiteStatementBuilder.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteWrapper.h>\r\n#include <AppInstallerLanguageUtilities.h>\r\n\r\n#include <functional>\r\n#include <initializer_list>\r\n#include <memory>\r\n#include <optional>\r\n#include <sstream>\r\n#include <string_view>\r\n#include <vector>\r\n\r\nusing namespace std::string_view_literals;\r\n\r\nnamespace AppInstaller::SQLite::Builder\r\n{\r\n    namespace details\r\n    {\r\n        // Sentinel types to indicate special cases to the builder.\r\n        struct unbound_t {};\r\n        struct rowcount_t {};\r\n\r\n        // Class for intake from external functions.\r\n        struct SubBuilder\r\n        {\r\n            SubBuilder(std::string&& s) : m_string(std::move(s)) {}\r\n\r\n            SubBuilder(const SubBuilder&) = default;\r\n            SubBuilder& operator=(const SubBuilder&) = default;\r\n\r\n            SubBuilder(SubBuilder&&) noexcept = default;\r\n            SubBuilder& operator=(SubBuilder&&) noexcept = default;\r\n\r\n            const std::string& GetString() const { return m_string; }\r\n\r\n        protected:\r\n            std::string m_string;\r\n        };\r\n\r\n        // Base class for all sub-builders.\r\n        struct SubBuilderBase\r\n        {\r\n            SubBuilderBase() = default;\r\n\r\n            SubBuilderBase(const SubBuilderBase&) = default;\r\n            SubBuilderBase& operator=(const SubBuilderBase&) = default;\r\n\r\n            SubBuilderBase(SubBuilderBase&&) noexcept = default;\r\n            SubBuilderBase& operator=(SubBuilderBase&&) noexcept = default;\r\n\r\n            virtual operator SubBuilder() { return { m_stream.str() }; }\r\n\r\n        protected:\r\n            std::ostringstream m_stream;\r\n        };\r\n    }\r\n\r\n    // Pass this value to indicate that the caller will bind the value later.\r\n    __declspec_selectany_ details::unbound_t Unbound;\r\n\r\n    // Pass this value to indicate that the number of rows is to be selected.\r\n    __declspec_selectany_ details::rowcount_t RowCount;\r\n\r\n    // A qualified table reference.\r\n    struct QualifiedTable\r\n    {\r\n        std::string_view Schema;\r\n        std::string_view Table;\r\n\r\n        explicit constexpr QualifiedTable(std::string_view table) : Table(table) {}\r\n        explicit constexpr QualifiedTable(std::string_view schema, std::string_view table) : Schema(schema), Table(table) {}\r\n    };\r\n\r\n    namespace Schema\r\n    {\r\n        // The main database's schema table.\r\n        // More info can be found at: https://www.sqlite.org/schematab.html\r\n        constexpr QualifiedTable MainTable{ \"main\"sv, \"sqlite_master\"sv };\r\n\r\n        // The sqlite_schema column name for the type of the object.\r\n        constexpr std::string_view TypeColumn = \"type\"sv;\r\n\r\n        // The sqlite_schema type value for a table.\r\n        constexpr std::string_view Type_Table = \"table\"sv;\r\n\r\n        // The sqlite_schema type value for an index.\r\n        constexpr std::string_view Type_Index = \"index\"sv;\r\n\r\n        // The sqlite_schema column name for the name of the object.\r\n        constexpr std::string_view NameColumn = \"name\"sv;\r\n    }\r\n\r\n    // A qualified column reference.\r\n    struct QualifiedColumn\r\n    {\r\n        std::string_view Table;\r\n        std::string_view Column;\r\n\r\n        explicit QualifiedColumn(std::string_view column) : Column(column) {}\r\n        explicit QualifiedColumn(std::string_view table, std::string_view column) : Table(table), Column(column) {}\r\n    };\r\n\r\n    // SQLite types as an enum.\r\n    enum class Type\r\n    {\r\n        Int,\r\n        Bool = Int,\r\n        Int64,\r\n        RowId = Int64,\r\n        Text,\r\n        Blob,\r\n        Integer, // Type for specifying a primary key column as a row id alias.\r\n        None, // Does not declare a type\r\n    };\r\n\r\n    template <Type type, bool allowNull>\r\n    struct TypeInfo\r\n    {\r\n    };\r\n\r\n    template <>\r\n    struct TypeInfo<Type::Text, false>\r\n    {\r\n        using value_t = std::string;\r\n    };\r\n\r\n    template <>\r\n    struct TypeInfo<Type::Text, true>\r\n    {\r\n        using value_t = std::optional<std::string>;\r\n    };\r\n\r\n    template <>\r\n    struct TypeInfo<Type::Blob, false>\r\n    {\r\n        using value_t = SQLite::blob_t;\r\n    };\r\n\r\n    template <>\r\n    struct TypeInfo<Type::Blob, true>\r\n    {\r\n        using value_t = std::optional<SQLite::blob_t>;\r\n    };\r\n\r\n    // Aggregate functions.\r\n    enum class Aggregate\r\n    {\r\n        Min,\r\n        Max,\r\n    };\r\n\r\n    // Helper to mark create an integer primary key for rowid, making it stable across vacuum.\r\n    struct IntegerPrimaryKey : public details::SubBuilderBase\r\n    {\r\n        IntegerPrimaryKey();\r\n\r\n        IntegerPrimaryKey(const IntegerPrimaryKey&) = default;\r\n        IntegerPrimaryKey& operator=(const IntegerPrimaryKey&) = default;\r\n\r\n        IntegerPrimaryKey(IntegerPrimaryKey&&) noexcept = default;\r\n        IntegerPrimaryKey& operator=(IntegerPrimaryKey&&) noexcept = default;\r\n\r\n        // Set the column to autoincrement. SQLite recommends against using this value unless\r\n        // you need to ensure that rowids are not ever reused.\r\n        IntegerPrimaryKey& AutoIncrement(bool isTrue = true);\r\n    };\r\n\r\n    // Helper used when creating a table.\r\n    struct ColumnBuilder : public details::SubBuilderBase\r\n    {\r\n        // Specify the column name and type when creating the builder.\r\n        ColumnBuilder(std::string_view column, Type type);\r\n\r\n        ColumnBuilder(const ColumnBuilder&) = default;\r\n        ColumnBuilder& operator=(const ColumnBuilder&) = default;\r\n\r\n        ColumnBuilder(ColumnBuilder&&) noexcept = default;\r\n        ColumnBuilder& operator=(ColumnBuilder&&) noexcept = default;\r\n\r\n        // Indicate that the column is not able to be null.\r\n        // Allow for data driven construction with input value.\r\n        ColumnBuilder& NotNull(bool isTrue = true);\r\n\r\n        // Indicate that the column is case-insensitive.\r\n        // Allow for data driven construction with input value.\r\n        ColumnBuilder& CollateNoCase(bool isTrue = true);\r\n\r\n        // Indicate the default value for the column.\r\n        // Note that a default value is not considered constant if it is bound,\r\n        // so this function directly places the incoming value into the SQL statement.\r\n        ColumnBuilder& Default(int64_t value);\r\n\r\n        // Indicate that the column is unique.\r\n        // Allow for data driven construction with input value.\r\n        ColumnBuilder& Unique(bool isTrue = true);\r\n\r\n        // Indicate that the column is the primary key.\r\n        // Allow for data driven construction with input value.\r\n        ColumnBuilder& PrimaryKey(bool isTrue = true);\r\n    };\r\n\r\n    // Helper used to specify a primary key with multiple columns.\r\n    struct PrimaryKeyBuilder : public details::SubBuilderBase\r\n    {\r\n        PrimaryKeyBuilder();\r\n        PrimaryKeyBuilder(std::initializer_list<std::string_view> columns);\r\n\r\n        PrimaryKeyBuilder(const PrimaryKeyBuilder&) = default;\r\n        PrimaryKeyBuilder& operator=(const PrimaryKeyBuilder&) = default;\r\n\r\n        PrimaryKeyBuilder(PrimaryKeyBuilder&&) noexcept = default;\r\n        PrimaryKeyBuilder& operator=(PrimaryKeyBuilder&&) noexcept = default;\r\n\r\n        virtual operator details::SubBuilder() override;\r\n\r\n        // Add a column to the primary key.\r\n        PrimaryKeyBuilder& Column(std::string_view column);\r\n\r\n    private:\r\n        bool m_isFirst = true;\r\n        bool m_needsClosing = true;\r\n    };\r\n\r\n    // A class that aids in building SQL statements in a more expressive manner than simple strings.\r\n    struct StatementBuilder\r\n    {\r\n        StatementBuilder() = default;\r\n\r\n        StatementBuilder(const StatementBuilder&) = default;\r\n        StatementBuilder& operator=(const StatementBuilder&) = default;\r\n\r\n        StatementBuilder(StatementBuilder&&) = default;\r\n        StatementBuilder& operator=(StatementBuilder&&) = default;\r\n\r\n        // Begin a select statement for the given columns.\r\n        StatementBuilder& Select();\r\n        StatementBuilder& Select(std::string_view column);\r\n        StatementBuilder& Select(std::initializer_list<std::string_view> columns);\r\n        StatementBuilder& Select(const QualifiedColumn& column);\r\n        StatementBuilder& Select(std::initializer_list<QualifiedColumn> columns);\r\n        StatementBuilder& Select(details::rowcount_t);\r\n\r\n        // Indicate the table that the statement will be operating on.\r\n        // The initializer_list form enables the table name to be constructed from multiple parts.\r\n        StatementBuilder& From();\r\n        StatementBuilder& From(std::string_view table);\r\n        StatementBuilder& From(QualifiedTable table);\r\n        StatementBuilder& From(std::initializer_list<std::string_view> table);\r\n\r\n        // Begin a filter clause on the given column.\r\n        StatementBuilder& Where(std::string_view column);\r\n        StatementBuilder& Where(const QualifiedColumn& column);\r\n\r\n        // A full filter clause looking for an embedded null character.\r\n        // Is extremely specific to consistency checks, and so a more detailed construct is not required.\r\n        StatementBuilder& WhereValueContainsEmbeddedNullCharacter(std::string_view column);\r\n        StatementBuilder& WhereValueContainsEmbeddedNullCharacter(const QualifiedColumn& column);\r\n\r\n        // Indicate the operation of the filter clause.\r\n        template <typename ValueType>\r\n        StatementBuilder& Equals(const ValueType& value)\r\n        {\r\n            AddBindFunctor(AppendOpAndBinder(Op::Equals), value);\r\n            return *this;\r\n        }\r\n        template <typename ValueType>\r\n        StatementBuilder& Equals(const std::optional<ValueType>& value)\r\n        {\r\n            if (value)\r\n            {\r\n                AddBindFunctor(AppendOpAndBinder(Op::Equals), value.value());\r\n                return *this;\r\n            }\r\n            else\r\n            {\r\n                return IsNull();\r\n            }\r\n        }\r\n        // The optional index value can be used to specify the parameter index.\r\n        StatementBuilder& Equals(details::unbound_t, std::optional<size_t> index = {});\r\n        StatementBuilder& Equals(std::nullptr_t);\r\n        StatementBuilder& Equals();\r\n        StatementBuilder& Equals(const QualifiedColumn& column);\r\n\r\n        template <typename ValueType>\r\n        StatementBuilder& IsGreaterThan(const ValueType& value)\r\n        {\r\n            AddBindFunctor(AppendOpAndBinder(Op::GreaterThan), value);\r\n            return *this;\r\n        }\r\n        StatementBuilder& IsGreaterThan(details::unbound_t, std::optional<size_t> index = {});\r\n\r\n        template <typename ValueType>\r\n        StatementBuilder& IsGreaterThanOrEqualTo(const ValueType& value)\r\n        {\r\n            AddBindFunctor(AppendOpAndBinder(Op::GreaterThanOrEqualTo), value);\r\n            return *this;\r\n        }\r\n        StatementBuilder& IsGreaterThanOrEqualTo(details::unbound_t, std::optional<size_t> index = {});\r\n\r\n        StatementBuilder& LikeWithEscape(std::string_view value);\r\n        StatementBuilder& Like(details::unbound_t);\r\n\r\n        StatementBuilder& Escape(std::string_view escapeChar);\r\n\r\n        StatementBuilder& Not();\r\n        StatementBuilder& In();\r\n\r\n        // Appends a set of value binders for the In clause.\r\n        StatementBuilder& In(size_t count);\r\n\r\n        // IsNull(true) means the value is null; IsNull(false) means the value is not null.\r\n        StatementBuilder& IsNull(bool isNull = true);\r\n        StatementBuilder& IsNotNull() { return IsNull(false); }\r\n\r\n        // Operators for combining filter clauses.\r\n        StatementBuilder& And(std::string_view column);\r\n        StatementBuilder& And(const QualifiedColumn& column);\r\n        StatementBuilder& Or(const QualifiedColumn& column);\r\n\r\n        // Begin a join clause.\r\n        // The initializer_list form enables the table name to be constructed from multiple parts.\r\n        StatementBuilder& Join(std::string_view table);\r\n        StatementBuilder& Join(QualifiedTable table);\r\n        StatementBuilder& Join(std::initializer_list<std::string_view> table);\r\n\r\n        // Begin a left outer join clause.\r\n        // The initializer_list form enables the table name to be constructed from multiple parts.\r\n        StatementBuilder& LeftOuterJoin(std::string_view table);\r\n        StatementBuilder& LeftOuterJoin(QualifiedTable table);\r\n        StatementBuilder& LeftOuterJoin(std::initializer_list<std::string_view> table);\r\n\r\n        // Set the join constraint.\r\n        StatementBuilder& On(const QualifiedColumn& column1, const QualifiedColumn& column2);\r\n\r\n        // Specify the grouping to use.\r\n        StatementBuilder& GroupBy(std::string_view column);\r\n        StatementBuilder& GroupBy(const QualifiedColumn& column);\r\n\r\n        // Specify the ordering to use.\r\n        StatementBuilder& OrderBy(std::string_view column);\r\n        StatementBuilder& OrderBy(const QualifiedColumn& column);\r\n        StatementBuilder& OrderBy(std::initializer_list<std::string_view> columns);\r\n\r\n        // Specify the ordering behavior.\r\n        StatementBuilder& Ascending();\r\n        StatementBuilder& Descending();\r\n\r\n        // Limits the result set to the given number of rows.\r\n        StatementBuilder& Limit(size_t rowCount);\r\n\r\n        // Begin an insert statement for the given table.\r\n        // The initializer_list form enables the table name to be constructed from multiple parts.\r\n        StatementBuilder& InsertInto(std::string_view table);\r\n        StatementBuilder& InsertInto(QualifiedTable table);\r\n        StatementBuilder& InsertInto(std::initializer_list<std::string_view> table);\r\n\r\n        // Begin an insert or ignore statement for the given table.\r\n        // The initializer_list form enables the table name to be constructed from multiple parts.\r\n        StatementBuilder& InsertOrIgnore(std::string_view table);\r\n        StatementBuilder& InsertOrIgnore(QualifiedTable table);\r\n        StatementBuilder& InsertOrIgnore(std::initializer_list<std::string_view> table);\r\n\r\n        // Set the columns for a statement (typically insert).\r\n        StatementBuilder& Columns(std::string_view column);\r\n        StatementBuilder& Columns(std::initializer_list<std::string_view> columns);\r\n        StatementBuilder& Columns(const QualifiedColumn& column);\r\n        StatementBuilder& Columns(std::initializer_list<QualifiedColumn> columns);\r\n\r\n        // Set the columns for a select or create table statement.\r\n        StatementBuilder& Columns(std::initializer_list<details::SubBuilder> columns);\r\n        StatementBuilder& BeginColumns();\r\n        StatementBuilder& Column(std::string_view column);\r\n        StatementBuilder& Column(const QualifiedColumn& column);\r\n        StatementBuilder& Column(Aggregate aggOp, std::string_view column);\r\n        StatementBuilder& Column(Aggregate aggOp, const QualifiedColumn& column);\r\n        StatementBuilder& Column(const details::SubBuilder& column);\r\n        StatementBuilder& EndColumns();\r\n\r\n        // Set the columns null constraint.\r\n        StatementBuilder& NotNull(bool isTrue = true);\r\n\r\n        // Set the column's default value.\r\n        template <typename ValueType>\r\n        StatementBuilder& Default(const ValueType& value)\r\n        {\r\n            m_stream << \" DEFAULT (\" << value << \")\";\r\n            return *this;\r\n        }\r\n\r\n        // Add the values clause for an insert statement.\r\n        template <typename... ValueTypes>\r\n        StatementBuilder& Values(const ValueTypes&... values)\r\n        {\r\n            int bindIndexBegin = AppendValuesAndBinders(sizeof...(ValueTypes));\r\n            // Use folding to add a binder for every value, specifically in the order they were given.\r\n            // Do not change this expression without understanding the implications to the bind order.\r\n            // See: https://en.cppreference.com/w/cpp/language/fold for more details.\r\n            (FoldHelper{}, ..., InsertValuesValueBinder(bindIndexBegin++, values));\r\n            return *this;\r\n        }\r\n        StatementBuilder& BeginValues();\r\n        template <typename ValueType>\r\n        StatementBuilder& Value(const ValueType& value)\r\n        {\r\n            InsertValuesValueBinder(AppendValueAndBinder(), value);\r\n            return *this;\r\n        }\r\n        StatementBuilder& EndValues();\r\n\r\n        // Begin a table creation statement.\r\n        // The initializer_list form enables the table name to be constructed from multiple parts.\r\n        StatementBuilder& CreateTable(std::string_view table);\r\n        StatementBuilder& CreateTable(QualifiedTable table);\r\n        StatementBuilder& CreateTable(std::initializer_list<std::string_view> table);\r\n\r\n        // Begin an alter table statement.\r\n        // The initializer_list form enables the table name to be constructed from multiple parts.\r\n        StatementBuilder& AlterTable(std::string_view table);\r\n        StatementBuilder& AlterTable(QualifiedTable table);\r\n        StatementBuilder& AlterTable(std::initializer_list<std::string_view> table);\r\n\r\n        // Complete an alter table statement by adding a column.\r\n        StatementBuilder& Add(std::string_view column, Type type);\r\n\r\n        // Begin a table deletion statement.\r\n        // The initializer_list form enables the table name to be constructed from multiple parts.\r\n        StatementBuilder& DropTable(std::string_view table);\r\n        StatementBuilder& DropTable(QualifiedTable table);\r\n        StatementBuilder& DropTable(std::initializer_list<std::string_view> table);\r\n\r\n        // Begin a table deletion statement.\r\n        // The initializer_list form enables the table name to be constructed from multiple parts.\r\n        StatementBuilder& DropTableIfExists(std::string_view table);\r\n        StatementBuilder& DropTableIfExists(QualifiedTable table);\r\n        StatementBuilder& DropTableIfExists(std::initializer_list<std::string_view> table);\r\n\r\n        // Begin an index creation statement.\r\n        // The initializer_list form enables the index name to be constructed from multiple parts.\r\n        StatementBuilder& CreateIndex(std::string_view table);\r\n        StatementBuilder& CreateIndex(QualifiedTable table);\r\n        StatementBuilder& CreateIndex(std::initializer_list<std::string_view> table);\r\n\r\n        // Begin an unique index creation statement.\r\n        // The initializer_list form enables the index name to be constructed from multiple parts.\r\n        StatementBuilder& CreateUniqueIndex(std::string_view table);\r\n        StatementBuilder& CreateUniqueIndex(QualifiedTable table);\r\n        StatementBuilder& CreateUniqueIndex(std::initializer_list<std::string_view> table);\r\n\r\n        // Begin an index deletion statement.\r\n        // The initializer_list form enables the table name to be constructed from multiple parts.\r\n        StatementBuilder& DropIndex(std::string_view index);\r\n        StatementBuilder& DropIndex(QualifiedTable index);\r\n        StatementBuilder& DropIndex(std::initializer_list<std::string_view> index);\r\n\r\n        // Set index target table.\r\n        StatementBuilder& On(std::string_view table);\r\n        StatementBuilder& On(std::initializer_list<std::string_view> table);\r\n\r\n        // Begin a delete statement.\r\n        // The initializer_list form enables the table name to be constructed from multiple parts.\r\n        StatementBuilder& DeleteFrom(std::string_view table);\r\n        StatementBuilder& DeleteFrom(QualifiedTable table);\r\n        StatementBuilder& DeleteFrom(std::initializer_list<std::string_view> table);\r\n\r\n        // Begin an update statement.\r\n        // The initializer_list form enables the table name to be constructed from multiple parts.\r\n        StatementBuilder& Update(std::string_view table);\r\n        StatementBuilder& Update(QualifiedTable table);\r\n        StatementBuilder& Update(std::initializer_list<std::string_view> table);\r\n\r\n        // Begin an `update or replace` statement.\r\n        // The initializer_list form enables the table name to be constructed from multiple parts.\r\n        StatementBuilder& UpdateOrReplace(std::string_view table);\r\n        StatementBuilder& UpdateOrReplace(QualifiedTable table);\r\n        StatementBuilder& UpdateOrReplace(std::initializer_list<std::string_view> table);\r\n\r\n        // Output the set portion of an update statement.\r\n        StatementBuilder& Set();\r\n\r\n        // Output the set portion of an update statement.\r\n        StatementBuilder& Vacuum();\r\n\r\n        // General purpose functions to begin and end a parenthetical expression.\r\n        StatementBuilder& BeginParenthetical();\r\n        StatementBuilder& EndParenthetical();\r\n\r\n        // Adds the `without rowid` clause.\r\n        StatementBuilder& WithoutRowID();\r\n\r\n        // Assign an alias to the previous item.\r\n        StatementBuilder& As(std::string_view alias);\r\n\r\n        // Gets the last bound index.\r\n        // A value of zero indicates that nothing has been bound.\r\n        int GetLastBindIndex() const { return m_bindIndex - 1; }\r\n\r\n        // Prepares and returns the statement, applying any bindings that were requested.\r\n        Statement Prepare(const Connection& connection);\r\n\r\n        // A convenience function that prepares, binds, and then executes a statement that does not return rows.\r\n        void Execute(const Connection& connection);\r\n\r\n    private:\r\n        enum class Op\r\n        {\r\n            Equals,\r\n            Like,\r\n            Escape,\r\n            Literal,\r\n            GreaterThan,\r\n            GreaterThanOrEqualTo,\r\n        };\r\n\r\n        // Appends given the operation.\r\n        // The optional index value can be used to specify the parameter index.\r\n        int AppendOpAndBinder(Op op, std::optional<size_t> index = {});\r\n\r\n        // Appends a set of binders for the values clause of an insert.\r\n        int AppendValuesAndBinders(size_t count);\r\n\r\n        // Appends a binder for the values clause of an insert.\r\n        int AppendValueAndBinder();\r\n\r\n        // Adds a functor to our list that will bind the given value.\r\n        template <typename ValueType>\r\n        void AddBindFunctor(int binderIndex, const ValueType& value)\r\n        {\r\n            m_binders.emplace_back([binderIndex, value](Statement& s) { s.Bind(binderIndex, value); });\r\n        }\r\n\r\n        // Helper template for binding incoming values for an insert.\r\n        template <typename ValueType>\r\n        StatementBuilder& InsertValuesValueBinder(int bindIndex, const ValueType& value)\r\n        {\r\n            AddBindFunctor(bindIndex, value);\r\n            return *this;\r\n        }\r\n        template <typename ValueType>\r\n        StatementBuilder& InsertValuesValueBinder(int bindIndex, const std::optional<ValueType>& value)\r\n        {\r\n            if (value)\r\n            {\r\n                AddBindFunctor(bindIndex, value.value());\r\n            }\r\n            else\r\n            {\r\n                AddBindFunctor(bindIndex, nullptr);\r\n            }\r\n            return *this;\r\n        }\r\n        StatementBuilder& InsertValuesValueBinder(int, details::unbound_t)\r\n        {\r\n            return *this;\r\n        }\r\n        StatementBuilder& InsertValuesValueBinder(int bindIndex, std::nullptr_t)\r\n        {\r\n            AddBindFunctor(bindIndex, nullptr);\r\n            return *this;\r\n        }\r\n\r\n        std::ostringstream m_stream;\r\n        // Because binding values starts at 1\r\n        int m_bindIndex = 1;\r\n        std::vector<std::function<void(Statement&)>> m_binders;\r\n        bool m_needsComma = false;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/SQLiteStorageBase.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteWrapper.h>\r\n#include <winget/SQLiteVersion.h>\r\n#include <winget/ManagedFile.h>\r\n\r\n#include <filesystem>\r\n#include <mutex>\r\n\r\nnamespace AppInstaller::SQLite\r\n{\r\n    // Type that wraps the basic SQLite storage functionality; the connection and metadata like schema version.\r\n    struct SQLiteStorageBase\r\n    {\r\n        // The disposition for opening the database.\r\n        enum class OpenDisposition\r\n        {\r\n            // Open for read only.\r\n            Read,\r\n            // Open for read and write.\r\n            ReadWrite,\r\n            // The database will not change while in use; open for immutable read.\r\n            Immutable,\r\n        };\r\n\r\n        // Gets the last write time for the database.\r\n        std::chrono::system_clock::time_point GetLastWriteTime() const;\r\n\r\n        // Gets the identifier written to the database when it was created.\r\n        std::string GetDatabaseIdentifier() const;\r\n\r\n        // Gets the schema version of the database.\r\n        const Version& GetVersion() const { return m_version; }\r\n\r\n        // Renames the database file and any auxiliary files given the inputs.\r\n        // Should only be used on an inactive database.\r\n        // If overwrite is given, existing destination files will be removed first.\r\n        static void RenameSQLiteDatabase(const std::filesystem::path& source, const std::filesystem::path& destination, bool overwrite = false);\r\n\r\n    protected:\r\n        SQLiteStorageBase(const std::string& target, const Version& version, size_t pageSize = 0);\r\n\r\n        SQLiteStorageBase(const std::string& filePath, SQLiteStorageBase::OpenDisposition disposition, Utility::ManagedFile&& indexFile);\r\n\r\n        SQLiteStorageBase(const std::string& target, SQLiteStorageBase& source);\r\n\r\n        // Sets the last write time metadata value in the database.\r\n        void SetLastWriteTime();\r\n\r\n        Utility::ManagedFile m_indexFile;\r\n        SQLite::Connection m_dbconn;\r\n        Version m_version;\r\n        std::unique_ptr<std::mutex> m_interfaceLock = std::make_unique<std::mutex>();\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/SQLiteTempTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteWrapper.h>\r\n#include <winget/SQLiteStatementBuilder.h>\r\n\r\n\r\nnamespace AppInstaller::SQLite\r\n{\r\n    // The base for a class that represents a temp table.\r\n    struct TempTable\r\n    {\r\n        TempTable();\r\n\r\n        ~TempTable();\r\n\r\n        TempTable(const TempTable&) = delete;\r\n        TempTable& operator=(const TempTable&) = delete;\r\n\r\n        TempTable(TempTable&&) = default;\r\n        TempTable& operator=(TempTable&&) = default;\r\n\r\n    protected:\r\n        // Gets the qualified name of the temp table.\r\n        Builder::QualifiedTable GetQualifiedName() const;\r\n\r\n        // Prepares the drop table statement for use in destructor.\r\n        // It needs to be run by the derived class after the table is actually created.\r\n        void InitDropStatement(const Connection& connection);\r\n\r\n    private:\r\n        std::string m_name;\r\n        Statement m_dropTableStatement;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/SQLiteVersion.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteWrapper.h>\r\n#include <memory>\r\n\r\nnamespace AppInstaller::SQLite\r\n{\r\n    // Represents the schema version of the database.\r\n    struct Version\r\n    {\r\n        // The major version of the schema.\r\n        // All minor changes to this major version must be backward compatible.\r\n        uint32_t MajorVersion{};\r\n        // The minor version of the schema.\r\n        // All changes to the schema warrant a change to the minor version.\r\n        uint32_t MinorVersion{};\r\n\r\n        bool operator==(const Version& other) const\r\n        {\r\n            return (MajorVersion == other.MajorVersion && MinorVersion == other.MinorVersion);\r\n        }\r\n\r\n        bool operator!=(const Version& other) const\r\n        {\r\n            return !operator==(other);\r\n        }\r\n\r\n        bool operator>=(const Version& other) const\r\n        {\r\n            if (MajorVersion > other.MajorVersion) return true;\r\n            if (MajorVersion < other.MajorVersion) return false;\r\n            return MinorVersion >= other.MinorVersion;\r\n        }\r\n\r\n        bool operator<(const Version& other) const\r\n        {\r\n            if (MajorVersion < other.MajorVersion) return true;\r\n            if (MajorVersion > other.MajorVersion) return false;\r\n            return MinorVersion < other.MinorVersion;\r\n        }\r\n\r\n        // Gets a version that represents the latest schema known to the implementation.\r\n        static Version Latest();\r\n\r\n        // Gets a version that represents the latest schema known to the implementation for the given major version.\r\n        static Version LatestForMajor(uint32_t majorVersion);\r\n\r\n        // Determines if this version represents the latest schema.\r\n        bool IsLatest() const;\r\n\r\n        // Determines if this version represents the latest schema of the given major version.\r\n        bool IsLatestForMajor(uint32_t majorVersion) const;\r\n\r\n        // Determines the schema version of the opened database.\r\n        static Version GetSchemaVersion(Connection& connection);\r\n\r\n        // Writes the current version to the given database.\r\n        void SetSchemaVersion(Connection& connection) const;\r\n    };\r\n\r\n    // Output the version\r\n    std::ostream& operator<<(std::ostream& out, const Version& version);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/SQLiteWrapper.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <wil/result_macros.h>\r\n#include <wil/resource.h>\r\n#include <winsqlite/winsqlite3.h>\r\n\r\n#include <AppInstallerLogging.h>\r\n#include <AppInstallerLanguageUtilities.h>\r\n\r\n#include <memory>\r\n#include <optional>\r\n#include <sstream>\r\n#include <string>\r\n#include <string_view>\r\n#include <tuple>\r\n#include <type_traits>\r\n#include <utility>\r\n#include <vector>\r\n\r\n#define SQLITE_MEMORY_DB_CONNECTION_TARGET \":memory:\"\r\n\r\nusing namespace std::string_view_literals;\r\n\r\nnamespace AppInstaller::SQLite\r\n{\r\n    // The name of the rowid column in SQLite.\r\n    extern std::string_view RowIDName;\r\n\r\n    // The type of a rowid column in code.\r\n    using rowid_t = int64_t;\r\n\r\n    // The type to use for blob data.\r\n    using blob_t = std::vector<uint8_t>;\r\n\r\n    namespace details\r\n    {\r\n        template<typename>\r\n        constexpr bool dependent_false = false;\r\n\r\n        template <typename T, typename = void>\r\n        struct ParameterSpecificsImpl\r\n        {\r\n            static T& ToLog(T&&)\r\n            {\r\n                static_assert(dependent_false<T>, \"No type specific override has been supplied\");\r\n            }\r\n            static void Bind(sqlite3_stmt*, int, T&&)\r\n            {\r\n                static_assert(dependent_false<T>, \"No type specific override has been supplied\");\r\n            }\r\n            static T GetColumn(sqlite3_stmt*, int)\r\n            {\r\n                static_assert(dependent_false<T>, \"No type specific override has been supplied\");\r\n            }\r\n        };\r\n\r\n        template <>\r\n        struct ParameterSpecificsImpl<nullptr_t>\r\n        {\r\n            inline static std::string_view ToLog(nullptr_t) { return \"null\"sv; }\r\n            static void Bind(sqlite3_stmt* stmt, int index, nullptr_t);\r\n        };\r\n\r\n        template <>\r\n        struct ParameterSpecificsImpl<std::string>\r\n        {\r\n            inline static const std::string& ToLog(const std::string& v) { return v; }\r\n            static void Bind(sqlite3_stmt* stmt, int index, const std::string& v);\r\n            static std::string GetColumn(sqlite3_stmt* stmt, int column);\r\n        };\r\n\r\n        template <>\r\n        struct ParameterSpecificsImpl<std::string_view>\r\n        {\r\n            inline static const std::string_view& ToLog(const std::string_view& v) { return v; }\r\n            static void Bind(sqlite3_stmt* stmt, int index, std::string_view v);\r\n        };\r\n\r\n        template <>\r\n        struct ParameterSpecificsImpl<int>\r\n        {\r\n            inline static int ToLog(int v) { return v; }\r\n            static void Bind(sqlite3_stmt* stmt, int index, int v);\r\n            static int GetColumn(sqlite3_stmt* stmt, int column);\r\n        };\r\n\r\n        template <>\r\n        struct ParameterSpecificsImpl<int64_t>\r\n        {\r\n            inline static int64_t ToLog(int64_t v) { return v; }\r\n            static void Bind(sqlite3_stmt* stmt, int index, int64_t v);\r\n            static int64_t GetColumn(sqlite3_stmt* stmt, int column);\r\n        };\r\n\r\n        template <>\r\n        struct ParameterSpecificsImpl<bool>\r\n        {\r\n            inline static bool ToLog(bool v) { return v; }\r\n            static void Bind(sqlite3_stmt* stmt, int index, bool v);\r\n            static bool GetColumn(sqlite3_stmt* stmt, int column);\r\n        };\r\n\r\n        template <>\r\n        struct ParameterSpecificsImpl<blob_t>\r\n        {\r\n            static std::string ToLog(const blob_t& v);\r\n            static void Bind(sqlite3_stmt* stmt, int index, const blob_t& v);\r\n            static blob_t GetColumn(sqlite3_stmt* stmt, int column);\r\n        };\r\n\r\n        template <>\r\n        struct ParameterSpecificsImpl<GUID>\r\n        {\r\n            static std::string ToLog(const GUID& v);\r\n            static void Bind(sqlite3_stmt* stmt, int index, const GUID& v);\r\n            static GUID GetColumn(sqlite3_stmt* stmt, int column);\r\n        };\r\n\r\n        template <typename E>\r\n        struct ParameterSpecificsImpl<E, typename std::enable_if_t<std::is_enum_v<E>>>\r\n        {\r\n            static auto ToLog(E v)\r\n            {\r\n                return ToIntegral(v);\r\n            }\r\n            static void Bind(sqlite3_stmt* stmt, int index, E v)\r\n            {\r\n                ParameterSpecificsImpl<std::underlying_type_t<E>>::Bind(stmt, index, ToIntegral(v));\r\n            }\r\n            static E GetColumn(sqlite3_stmt* stmt, int column)\r\n            {\r\n                return ToEnum<E>(ParameterSpecificsImpl<std::underlying_type_t<E>>::GetColumn(stmt, column));\r\n            }\r\n        };\r\n\r\n        template <typename Opt>\r\n        struct ParameterSpecificsImpl<std::optional<Opt>>\r\n        {\r\n            using Optional = std::optional<Opt>;\r\n\r\n            static auto ToLog(const Optional& v)\r\n            {\r\n                std::ostringstream result;\r\n                if (v)\r\n                {\r\n                    result << ParameterSpecificsImpl<Opt>::ToLog(v.value());\r\n                }\r\n                else\r\n                {\r\n                    result << \"{null}\";\r\n                }\r\n                return std::move(result).str();\r\n            }\r\n\r\n            static void Bind(sqlite3_stmt* stmt, int index, const Optional& v)\r\n            {\r\n                if (v)\r\n                {\r\n                    ParameterSpecificsImpl<Opt>::Bind(stmt, index, v.value());\r\n                }\r\n                else\r\n                {\r\n                    ParameterSpecificsImpl<nullptr_t>::Bind(stmt, index, nullptr);\r\n                }\r\n            }\r\n\r\n            static Optional GetColumn(sqlite3_stmt* stmt, int column)\r\n            {\r\n                if (sqlite3_column_type(stmt, column) == SQLITE_NULL)\r\n                {\r\n                    return std::nullopt;\r\n                }\r\n                else\r\n                {\r\n                    return ParameterSpecificsImpl<Opt>::GetColumn(stmt, column);\r\n                }\r\n            }\r\n        };\r\n\r\n        template <typename T>\r\n        using ParameterSpecifics = ParameterSpecificsImpl<std::decay_t<T>>;\r\n\r\n        // Allows the connection to be shared so that it can be closed in some circumstances.\r\n        struct SharedConnection\r\n        {\r\n            // Disables the connection, causing an exception to be thrown by `get`.\r\n            void Disable();\r\n\r\n            // Gets the connection object if active.\r\n            sqlite3* Get() const;\r\n\r\n            // Gets the connection object for creation.\r\n            sqlite3** GetPtr();\r\n\r\n        private:\r\n            std::atomic_bool m_active = true;\r\n            wil::unique_any<sqlite3*, decltype(sqlite3_close_v2), sqlite3_close_v2> m_dbconn;\r\n        };\r\n    }\r\n\r\n    // A SQLite exception.\r\n    struct SQLiteException : public wil::ResultException\r\n    {\r\n        SQLiteException(int error) : wil::ResultException(MAKE_HRESULT(SEVERITY_ERROR, FACILITY_SQLITE, error)) {}\r\n    };\r\n\r\n    struct Statement;\r\n\r\n    // The connection to a database.\r\n    struct Connection\r\n    {\r\n        friend Statement;\r\n\r\n        // The disposition for opening a database connection.\r\n        enum class OpenDisposition : int\r\n        {\r\n            // Open existing database for reading.\r\n            ReadOnly = SQLITE_OPEN_READONLY,\r\n            // Open existing database for reading and writing.\r\n            ReadWrite = SQLITE_OPEN_READWRITE,\r\n            // Create new database for reading and writing.\r\n            Create = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,\r\n        };\r\n\r\n        // Flags for opening a database connection.\r\n        enum class OpenFlags : int\r\n        {\r\n            // No flags specified.\r\n            None = 0,\r\n            // Indicate that the target can be a URI.\r\n            Uri = SQLITE_OPEN_URI,\r\n        };\r\n\r\n        static Connection Create(const std::string& target, OpenDisposition disposition, OpenFlags flags = OpenFlags::None);\r\n\r\n        Connection() = default;\r\n\r\n        Connection(const Connection&) = delete;\r\n        Connection& operator=(const Connection&) = delete;\r\n\r\n        Connection(Connection&& other) = default;\r\n        Connection& operator=(Connection&& other) = default;\r\n\r\n        ~Connection() = default;\r\n\r\n        // Enables the ICU integrations on this connection.\r\n        void EnableICU();\r\n\r\n        // Gets the last inserted rowid to the database.\r\n        rowid_t GetLastInsertRowID();\r\n\r\n        // Gets the count of changed rows for the last executed statement.\r\n        int GetChanges() const;\r\n\r\n        //. Gets the (fixed but arbitrary) identifier for this connection.\r\n        size_t GetID() const;\r\n\r\n        // Sets the busy timeout for the connection.\r\n        void SetBusyTimeout(std::chrono::milliseconds timeout);\r\n\r\n        // Sets the journal mode.\r\n        // Returns true if successful, false if not.\r\n        // Must be performed outside of a transaction.\r\n        bool SetJournalMode(std::string_view mode);\r\n\r\n        // Sets the page size for a new, empty database.\r\n        // Must be called before the first write to take effect.\r\n        // Must be a power of two between 512 and 65536 (inclusive), but we let SQLite enforce that.\r\n        void SetPageSize(size_t pageSize);\r\n\r\n        operator sqlite3* () const { return m_dbconn->Get(); }\r\n\r\n    protected:\r\n        // Gets the shared connection.\r\n        std::shared_ptr<details::SharedConnection> GetSharedConnection() const;\r\n\r\n    private:\r\n        Connection(const std::string& target, OpenDisposition disposition, OpenFlags flags);\r\n\r\n        size_t m_id = 0;\r\n        std::shared_ptr<details::SharedConnection> m_dbconn;\r\n    };\r\n\r\n    // A SQL statement.\r\n    struct Statement\r\n    {\r\n        static Statement Create(const Connection& connection, const std::string& sql);\r\n        static Statement Create(const Connection& connection, std::string_view sql);\r\n        static Statement Create(const Connection& connection, char const* const sql);\r\n\r\n        Statement() = default;\r\n\r\n        Statement(const Statement&) = delete;\r\n        Statement& operator=(const Statement&) = delete;\r\n\r\n        Statement(Statement&& other) = default;\r\n        Statement& operator=(Statement&& other) = default;\r\n\r\n        operator sqlite3_stmt* () const { return m_stmt.get(); }\r\n\r\n        // The state of the statement.\r\n        enum class State\r\n        {\r\n            // The statement has been prepared, but not evaluated.\r\n            Prepared = 0,\r\n            // The statement has a row available for reading.\r\n            HasRow = 1,\r\n            // The statement has been completed.\r\n            Completed = 2,\r\n            // The statement has resulted in an error.\r\n            Error = 3,\r\n        };\r\n\r\n        // Gets the current state of the statement.\r\n        State GetState() const { return m_state; }\r\n\r\n        // Bind parameters to the statement.\r\n        // The index is 1 based.\r\n        template <typename Value>\r\n        void Bind(int index, Value&& v)\r\n        {\r\n            AICLI_LOG(SQL, Verbose, << \"Binding statement #\" << m_connectionId << '-' << m_id << \": \" << index << \" => \" << details::ParameterSpecifics<Value>::ToLog(std::forward<Value>(v)));\r\n            details::ParameterSpecifics<Value>::Bind(m_stmt.get(), index, std::forward<Value>(v));\r\n        }\r\n\r\n        // Evaluate the statement; either retrieving the next row or executing some action.\r\n        // Returns true if there is a row of data, or false if there is none.\r\n        // This return value is the equivalent of 'GetState() == State::HasRow' after calling Step.\r\n        bool Step(bool closeConnectionOnError = false);\r\n\r\n        // Equivalent to Step, but does not ever expect a result, throwing if one is retrieved.\r\n        void Execute(bool closeConnectionOnError = false);\r\n\r\n        // Gets a boolean value that indicates whether the specified column value is null in the current row.\r\n        // The index is 0 based.\r\n        bool GetColumnIsNull(int column);\r\n\r\n        // Gets the value of the specified column from the current row.\r\n        // The index is 0 based.\r\n        template <typename Value>\r\n        Value GetColumn(int column)\r\n        {\r\n            THROW_HR_IF(E_BOUNDS, m_state != State::HasRow);\r\n            return details::ParameterSpecifics<Value>::GetColumn(m_stmt.get(), column);\r\n        }\r\n\r\n        // Gets the entire row of values from the current row.\r\n        // The values requested *must* be those available starting from the first column, but trailing columns can be omitted.\r\n        template <typename... Values>\r\n        std::tuple<Values...> GetRow()\r\n        {\r\n            return GetRowImpl<Values...>(std::make_integer_sequence<int, sizeof...(Values)>{});\r\n        }\r\n\r\n        // Resets the statement state, allowing it to be evaluated again.\r\n        // Note that this does not clear data bindings.\r\n        void Reset();\r\n\r\n        // Determines if the statement owns an underlying object.\r\n        operator bool() const { return static_cast<bool>(m_stmt); }\r\n\r\n    private:\r\n        Statement(const Connection& connection, std::string_view sql);\r\n\r\n        // Helper to receive the integer sequence from the public function.\r\n        // This is equivalent to calling:\r\n        //  for (i = 0 .. count of Values types)\r\n        //      GetColumn<current Value type>(i)\r\n        // Then putting them all into a tuple.\r\n        template <typename... Values, int... I>\r\n        std::tuple<Values...> GetRowImpl(std::integer_sequence<int, I...>)\r\n        {\r\n            THROW_HR_IF(E_BOUNDS, m_state != State::HasRow);\r\n            return std::make_tuple(details::ParameterSpecifics<Values>::GetColumn(m_stmt.get(), I)...);\r\n        }\r\n\r\n        std::shared_ptr<details::SharedConnection> m_dbconn;\r\n        size_t m_connectionId = 0;\r\n        size_t m_id = 0;\r\n        wil::unique_any<sqlite3_stmt*, decltype(sqlite3_finalize), sqlite3_finalize> m_stmt;\r\n        State m_state = State::Prepared;\r\n    };\r\n\r\n    // A SQLite transaction.\r\n    // Use as the beginning of a transaction stack, specifically when the transaction will write\r\n    // and the database is in WAL mode.\r\n    struct Transaction\r\n    {\r\n        // Creates a transaction, beginning it.\r\n        static Transaction Create(Connection& connection, std::string name, bool immediateWrite);\r\n\r\n        Transaction();\r\n\r\n        Transaction(const Transaction&) = delete;\r\n        Transaction& operator=(const Transaction&) = delete;\r\n\r\n        Transaction(Transaction&&) = default;\r\n        Transaction& operator=(Transaction&&) = default;\r\n\r\n        ~Transaction();\r\n\r\n        // Rolls back the Transaction.\r\n        void Rollback(bool throwOnError = true);\r\n\r\n        // Commits the Transaction.\r\n        void Commit();\r\n\r\n    private:\r\n        Transaction(Connection& connection, std::string&& name, bool immediateWrite);\r\n\r\n        std::string m_name;\r\n        DestructionToken m_inProgress = true;\r\n        Statement m_rollback;\r\n        Statement m_commit;\r\n    };\r\n\r\n    // A SQLite savepoint.\r\n    struct Savepoint\r\n    {\r\n        // Creates a savepoint, beginning it.\r\n        static Savepoint Create(Connection& connection, std::string name);\r\n\r\n        Savepoint();\r\n\r\n        Savepoint(const Savepoint&) = delete;\r\n        Savepoint& operator=(const Savepoint&) = delete;\r\n\r\n        Savepoint(Savepoint&&) = default;\r\n        Savepoint& operator=(Savepoint&&) = default;\r\n\r\n        ~Savepoint();\r\n\r\n        // Rolls back the Savepoint.\r\n        void Rollback(bool throwOnError = true);\r\n\r\n        // Commits the Savepoint.\r\n        void Commit();\r\n\r\n    private:\r\n        Savepoint(Connection& connection, std::string&& name);\r\n\r\n        std::string m_name;\r\n        DestructionToken m_inProgress = true;\r\n        Statement m_rollbackTo;\r\n        Statement m_release;\r\n    };\r\n\r\n    // A SQLite backup operation.\r\n    struct Backup\r\n    {\r\n        // Creates a backup.\r\n        static Backup Create(Connection& destination, const std::string& destinationName, Connection& source, const std::string& sourceName);\r\n\r\n        Backup(const Backup&) = delete;\r\n        Backup& operator=(const Backup&) = delete;\r\n\r\n        Backup(Backup&&) = default;\r\n        Backup& operator=(Backup&&) = default;\r\n\r\n        // Performs some or all of the backup.\r\n        // Returns true if the backup is completed, false if not.\r\n        bool Step(int pages = -1);\r\n\r\n    private:\r\n        Backup(Connection& destination, const std::string& destinationName, Connection& source, const std::string& sourceName);\r\n\r\n        wil::unique_any<sqlite3_backup*, decltype(sqlite3_backup_finish), sqlite3_backup_finish> m_backup;\r\n    };\r\n\r\n    // The escape character used in the EscapeStringForLike function.\r\n    extern std::string_view EscapeCharForLike;\r\n\r\n    // Escapes the given input string for passing to a like operation.\r\n    std::string EscapeStringForLike(std::string_view value);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/Security.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <wil/resource.h>\r\n#include <string>\r\n#include <string_view>\r\n\r\nnamespace AppInstaller::Security\r\n{\r\n    // A Windows integrity level.\r\n    enum class IntegrityLevel\r\n    {\r\n        Untrusted,\r\n        Low,\r\n        Medium,\r\n        MediumPlus,\r\n        High,\r\n        System,\r\n        ProtectedProcess,\r\n    };\r\n\r\n    // Gets the integrity level for the current effective token.\r\n    // Does not know how to determine MediumPlus, if that ever matters...\r\n    IntegrityLevel GetEffectiveIntegrityLevel();\r\n\r\n    // Determines if the current COM caller is the same user as the current process\r\n    // and is at least equal integrity level (higher will also be allowed).\r\n    bool IsCOMCallerSameUserAndIntegrityLevel();\r\n\r\n    // Determines if the current COM caller is at least the minimum integrity level provided.\r\n    bool IsCOMCallerIntegrityLevelAtLeast(IntegrityLevel minimumLevel);\r\n\r\n    // Determines if the current integrity level is at least the minimum integrity level provided.\r\n    bool IsCurrentIntegrityLevelAtLeast(IntegrityLevel minimumLevel);\r\n\r\n    // Gets the string representation of the given SID.\r\n    std::string ToString(PSID sid);\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/SharedThreadGlobals.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include <AppInstallerLogging.h>\n\nnamespace AppInstaller::ThreadLocalStorage\n{\n    struct PreviousThreadGlobals;\n\n    // Interface for access to values that are stored on a per-thread object.\n    struct ThreadGlobals\n    {\n        ThreadGlobals() = default;\n        virtual ~ThreadGlobals() = default;\n\n        virtual AppInstaller::Logging::DiagnosticLogger& GetDiagnosticLogger() = 0;\n\n        virtual void* GetTelemetryObject() = 0;\n\n        // Set Globals for Current Thread\n        // Return RAII object with its ownership to set the AppInstaller ThreadLocalStorage back to previous state\n        virtual std::unique_ptr<AppInstaller::ThreadLocalStorage::PreviousThreadGlobals> SetForCurrentThread();\n\n        // Return Globals for Current Thread\n        static ThreadGlobals* GetForCurrentThread();\n    };\n\n    // RAII object used to enable reverting back to the previous thread globals object.\n    struct PreviousThreadGlobals\n    {\n        ~PreviousThreadGlobals();\n\n        PreviousThreadGlobals(ThreadGlobals* previous);\n\n    private:\n        ThreadGlobals* m_previous;\n        DWORD m_threadId;\n    };\n}\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Public/winget/Yaml.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerSHA256.h>\r\n\r\n#include <fstream>\r\n#include <map>\r\n#include <memory>\r\n#include <optional>\r\n#include <stack>\r\n#include <string>\r\n#include <string_view>\r\n#include <vector>\r\n\r\n\r\nnamespace AppInstaller::YAML\r\n{\r\n    // A location within the stream.\r\n    struct Mark\r\n    {\r\n        Mark() = default;\r\n        Mark(size_t l, size_t c) : line(l), column(c) {}\r\n\r\n        size_t line = 0;\r\n        size_t column = 0;\r\n    };\r\n\r\n    // An exception from YAML.\r\n    struct Exception : public wil::ResultException\r\n    {\r\n        // The type of error that occurred.\r\n        enum class Type\r\n        {\r\n            None,\r\n            Memory,\r\n            Reader,\r\n            Scanner,\r\n            Parser,\r\n            Composer,\r\n            Writer,\r\n            Emitter,\r\n            Policy,\r\n        };\r\n\r\n        // Should only be used for Memory.\r\n        Exception(Type type);\r\n\r\n        // Should only be used for Reader.\r\n        Exception(Type type, const char* problem, size_t offset, int value);\r\n\r\n        // Used for Scanner, Parser, and Composer.\r\n        Exception(Type type, const char* problem, const Mark& problemMark, const char* context = {}, const Mark& contextMark = {});\r\n\r\n        // Used for Writer and Emitter.\r\n        Exception(Type type, const char* problem);\r\n\r\n        const char* what() const noexcept override;\r\n\r\n        const Mark& GetMark() const;\r\n\r\n    private:\r\n        std::string m_what;\r\n        YAML::Mark m_mark;\r\n    };\r\n\r\n    // A YAML node.\r\n    struct Node\r\n    {\r\n        // The node's type.\r\n        enum class Type\r\n        {\r\n            Invalid,\r\n            None,\r\n            Scalar,\r\n            Sequence,\r\n            Mapping\r\n        };\r\n\r\n        // The node's tag\r\n        enum class TagType\r\n        {\r\n            Unknown,\r\n            Null,\r\n            Bool,\r\n            Str,\r\n            Int,\r\n            Float,\r\n            Timestamp,\r\n            Seq,\r\n            Map,\r\n        };\r\n\r\n        Node() : m_type(Type::Invalid), m_tagType(TagType::Unknown) {}\r\n        Node(Type type, std::string tag, const Mark& mark);\r\n\r\n        // Sets the scalar value of the node.\r\n        void SetScalar(std::string value);\r\n        void SetScalar(std::string value, bool isQuoted);\r\n\r\n        // Adds a child node to the sequence.\r\n        template <typename... Args>\r\n        Node& AddSequenceNode(Args&&... args)\r\n        {\r\n            Require(Type::Sequence);\r\n            return m_sequence->emplace_back(std::forward<Args>(args)...);\r\n        }\r\n\r\n        // Merges sequence nodes. If both sequence have the specified key with the same value\r\n        // they will get merged together. All elements in sequence must have the key.\r\n        void MergeSequenceNode(Node other, std::string_view key, bool caseInsensitive = false);\r\n\r\n        // Adds a child node to the mapping.\r\n        template <typename... Args>\r\n        Node& AddMappingNode(Node&& key, Args&&... args)\r\n        {\r\n            Require(Type::Mapping);\r\n            return m_mapping->emplace(std::move(key), Node(std::forward<Args>(args)...))->second;\r\n        }\r\n\r\n        // Merge mapping node. If both contain a node with the same key preserve this.\r\n        void MergeMappingNode(Node other, bool caseInsensitive = false);\r\n\r\n        bool IsDefined() const { return m_type != Type::Invalid; }\r\n        bool IsNull() const { return m_type == Type::Invalid || m_type == Type::None || (m_type == Type::Scalar && m_scalar.empty()); }\r\n        bool IsScalar() const { return m_type == Type::Scalar; }\r\n        bool IsSequence() const { return m_type == Type::Sequence; }\r\n        bool IsMap() const { return m_type == Type::Mapping; }\r\n        Type GetType() const { return m_type; }\r\n        TagType GetTagType() const { return m_tagType; }\r\n\r\n        explicit operator bool() const { return IsDefined(); }\r\n\r\n        // Gets the scalar value as the requested type.\r\n        template <typename T>\r\n        T as() const\r\n        {\r\n            Require(Type::Scalar);\r\n            T* t = nullptr;\r\n            return as_dispatch(t);\r\n        }\r\n\r\n        template <typename T>\r\n        std::optional<T> try_as() const\r\n        {\r\n            if (m_type != Type::Scalar)\r\n            {\r\n                return {};\r\n            }\r\n\r\n            T* t = nullptr;\r\n            return try_as_dispatch(t);\r\n        }\r\n\r\n        bool operator<(const Node& other) const;\r\n\r\n        // Gets a child node from the mapping by its name.\r\n        Node& operator[](std::string_view key);\r\n        const Node& operator[](std::string_view key) const;\r\n\r\n        // Gets a child node from the mapping by its name case-insensitive.\r\n        Node& GetChildNode(std::string_view key);\r\n        const Node& GetChildNode(std::string_view key) const;\r\n\r\n        // Gets a child node from the sequence by its index.\r\n        Node& operator[](size_t index);\r\n        const Node& operator[](size_t index) const;\r\n\r\n        // Gets the number of child nodes.\r\n        size_t size() const;\r\n\r\n        // Gets the mark for this node.\r\n        const Mark& Mark() const { return m_mark; }\r\n\r\n        // Gets the nodes in the sequence.\r\n        const std::vector<Node>& Sequence() const;\r\n\r\n        // Gets the nodes in the mapping.\r\n        const std::multimap<Node, Node>& Mapping() const;\r\n\r\n    private:\r\n        Node(std::string_view key) : m_type(Type::Scalar), m_scalar(key), m_tagType(TagType::Str) {}\r\n\r\n        // Require certain node types to; throwing if the requirement is not met.\r\n        void Require(Type type) const;\r\n\r\n        // The workers for the as function.\r\n        std::string as_dispatch(std::string*) const;\r\n        std::optional<std::string> try_as_dispatch(std::string*) const;\r\n\r\n        std::wstring as_dispatch(std::wstring*) const;\r\n        std::optional<std::wstring> try_as_dispatch(std::wstring*) const;\r\n\r\n        int64_t as_dispatch(int64_t*) const;\r\n        std::optional<int64_t> try_as_dispatch(int64_t*) const;\r\n\r\n        int as_dispatch(int*) const;\r\n        std::optional<int> try_as_dispatch(int*) const;\r\n\r\n        bool as_dispatch(bool*) const;\r\n        std::optional<bool> try_as_dispatch(bool*) const;\r\n\r\n        Type m_type;\r\n        std::string m_tag;\r\n        TagType m_tagType;\r\n        YAML::Mark m_mark;\r\n        std::string m_scalar;\r\n        std::optional<std::vector<Node>> m_sequence;\r\n        std::optional<std::multimap<Node, Node>> m_mapping;\r\n    };\r\n\r\n    // Loads from the input; returns the root node of the first document.\r\n    Node Load(std::string_view input);\r\n    Node Load(const std::string& input);\r\n    Node Load(const std::filesystem::path& input);\r\n    Node Load(const std::filesystem::path& input, Utility::SHA256::HashBuffer& hashOut);\r\n\r\n    // Any emitter event.\r\n    // Not using enum class to enable existing code to function.\r\n    enum EmitterEvent\r\n    {\r\n        BeginSeq,\r\n        EndSeq,\r\n        BeginMap,\r\n        EndMap,\r\n        Key,\r\n        Value,\r\n    };\r\n\r\n    // Sets the scalar style to use for the next scalar output.\r\n    enum class ScalarStyle\r\n    {\r\n        Any,\r\n        Plain,\r\n        SingleQuoted,\r\n        DoubleQuoted,\r\n        Literal,\r\n        Folded,\r\n    };\r\n\r\n    // A schema header for a document.\r\n    struct DocumentSchemaHeader\r\n    {\r\n        DocumentSchemaHeader() = default;\r\n        DocumentSchemaHeader(std::string schemaHeaderString, const Mark& mark) : SchemaHeader(std::move(schemaHeaderString)), Mark(mark) {}\r\n\r\n        std::string SchemaHeader;\r\n        Mark Mark;\r\n        static constexpr std::string_view YamlLanguageServerKey = \"yaml-language-server\";\r\n    };\r\n\r\n    struct Document\r\n    {\r\n        Document() = default;\r\n        Document(Node root, DocumentSchemaHeader schemaHeader) : m_root(std::move(root)), m_schemaHeader(std::move(schemaHeader)) {}\r\n\r\n        const DocumentSchemaHeader& GetSchemaHeader() const { return m_schemaHeader; }\r\n\r\n        // Return r-values for move semantics\r\n        Node&& GetRoot() && { return std::move(m_root); }\r\n\r\n    private:\r\n        Node m_root;\r\n        DocumentSchemaHeader m_schemaHeader;\r\n    };\r\n\r\n    // Forward declaration to allow pImpl in this Emitter.\r\n    namespace Wrapper\r\n    {\r\n        struct Document;\r\n    }\r\n\r\n    // Loads from the input; returns the root node of the first document.\r\n    Document LoadDocument(std::string_view input);\r\n    Document LoadDocument(const std::string& input);\r\n    Document LoadDocument(const std::filesystem::path& input);\r\n    Document LoadDocument(const std::filesystem::path& input, Utility::SHA256::HashBuffer& hashOut);\r\n\r\n    // A YAML emitter.\r\n    struct Emitter\r\n    {\r\n        Emitter();\r\n\r\n        Emitter(const Emitter&) = delete;\r\n        Emitter& operator=(const Emitter&) = delete;\r\n\r\n        Emitter(Emitter&&) noexcept;\r\n        Emitter& operator=(Emitter&&) noexcept;\r\n\r\n        ~Emitter();\r\n\r\n        // Emit events and values.\r\n        Emitter& operator<<(EmitterEvent event);\r\n        Emitter& operator<<(std::string_view value);\r\n        Emitter& operator<<(int64_t value);\r\n        Emitter& operator<<(int value);\r\n        Emitter& operator<<(bool value);\r\n\r\n        Emitter& operator<<(ScalarStyle style);\r\n\r\n        // Gets the result of the emitter; can only be retrieved once.\r\n        std::string str();\r\n\r\n        // Gets the result of the emitter to out stream; can only be retrieved once.\r\n        void Emit(std::ostream& out);\r\n\r\n    private:\r\n        // Appends the given node to the current container if applicable.\r\n        void AppendNode(int id);\r\n\r\n        std::unique_ptr<Wrapper::Document> m_document;\r\n\r\n        // If set, stores the last Key that was set.\r\n        std::optional<int> m_keyId;\r\n\r\n        struct ContainerInfo\r\n        {\r\n            ContainerInfo(int id, bool map) : Id(id), IsMapping(map) {}\r\n\r\n            int Id;\r\n            bool IsMapping;\r\n        };\r\n\r\n        // The stack of containers being emitted.\r\n        std::stack<ContainerInfo> m_containers;\r\n\r\n        // *** State Machine ***\r\n\r\n        // The type of input coming into the emitter.\r\n        enum class InputType\r\n        {\r\n            Scalar,\r\n            BeginSeq,\r\n            EndSeq,\r\n            BeginMap,\r\n            EndMap,\r\n            Key,\r\n            Value,\r\n        };\r\n\r\n        // If set, defines the type of the next scalar (Key or Value).\r\n        std::optional<InputType> m_scalarType;\r\n\r\n        // If set, defines the style of the next scalar.\r\n        std::optional<ScalarStyle> m_scalarStyle;\r\n\r\n        // Converts the input type to a bitmask value.\r\n        size_t GetInputBitmask(InputType type);\r\n\r\n        // Checks the state of the emitter to ensure that the incoming value is acceptable.\r\n        void CheckInput(InputType type);\r\n\r\n        // The currently allowed input types.\r\n        size_t m_allowedInputs = 0;\r\n\r\n        template <InputType... types>\r\n        void SetAllowedInputs()\r\n        {\r\n            m_allowedInputs = (GetInputBitmask(types) | ...);\r\n        }\r\n\r\n        // Sets the allowed inputs for the container on the top of the stack.\r\n        void SetAllowedInputsForContainer();\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Registry.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/Registry.h\"\r\n#include \"Public/AppInstallerStrings.h\"\r\n#include \"Public/AppInstallerLogging.h\"\r\n\r\n\r\nnamespace AppInstaller::Registry\r\n{\r\n    namespace\r\n    {\r\n        std::wstring_view ConvertBytesToWideStringView(const std::vector<BYTE>& data)\r\n        {\r\n            // Remove any extra bytes because the data could just be dirty; better to not have a bad character than outright fail.\r\n            std::wstring_view result{ reinterpret_cast<const wchar_t*>(data.data()), data.size() / sizeof(wchar_t) };\r\n\r\n            // Registry values may or may not be null terminated; we will remove any trailing nulls\r\n            while (!result.empty() && result.back() == L'\\0')\r\n            {\r\n                result = result.substr(0, result.size() - 1);\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        std::wstring ConvertBytesToWideString(const std::vector<BYTE>& data)\r\n        {\r\n            return std::wstring{ ConvertBytesToWideStringView(data) };\r\n        }\r\n\r\n        std::string ConvertBytesToString(const std::vector<BYTE>& data)\r\n        {\r\n            return Utility::ConvertToUTF8(ConvertBytesToWideStringView(data));\r\n        }\r\n\r\n        uint32_t ConvertBytesToUInt32LE(const std::vector<BYTE>& data)\r\n        {\r\n            THROW_HR_IF(E_NOT_VALID_STATE, data.size() != sizeof(uint32_t));\r\n            uint32_t result = 0;\r\n            uint32_t shift = 0;\r\n\r\n            for (const BYTE datum : data)\r\n            {\r\n                result |= ((static_cast<uint32_t>(datum) & 0xFF) << shift);\r\n                shift += 8;\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        bool TryGetRegistryValueNameFromIndex(const wil::shared_hkey& key, DWORD index, std::wstring& valueName)\r\n        {\r\n            constexpr DWORD MaxNameLength = 32767;\r\n            LSTATUS status = ERROR_SUCCESS;\r\n            DWORD charCount = 0;\r\n            valueName = L'\\0';\r\n\r\n            while (valueName.size() <= MaxNameLength)\r\n            {\r\n                charCount = wil::safe_cast<DWORD>(valueName.size());\r\n\r\n                // We could also get the type and data here, but we read only the name instead\r\n                // to prevent duplication with the code that gets the data from the name.\r\n                status = RegEnumValueW(key.get(), index, &valueName[0], &charCount, nullptr, nullptr, nullptr, nullptr);\r\n\r\n                if (status == ERROR_MORE_DATA)\r\n                {\r\n                    // See if we can get away with the current capacity\r\n                    if (valueName.size() < valueName.capacity())\r\n                    {\r\n                        valueName.resize(valueName.capacity());\r\n                    }\r\n                    else\r\n                    {\r\n                        valueName.resize(valueName.capacity() * 2);\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    break;\r\n                }\r\n            }\r\n\r\n            if (status == ERROR_SUCCESS)\r\n            {\r\n                valueName.resize(wil::safe_cast<size_t>(charCount));\r\n                return true;\r\n            }\r\n            else if (status == ERROR_NO_MORE_ITEMS)\r\n            {\r\n                return false;\r\n            }\r\n            else\r\n            {\r\n                THROW_IF_WIN32_ERROR(status);\r\n                return false;\r\n            }\r\n        }\r\n\r\n        bool TryGetRegistryValueData(const wil::shared_hkey& key, const std::wstring& valueName, DWORD& type, std::vector<BYTE>& data)\r\n        {\r\n            data.resize(64);\r\n\r\n            LSTATUS status = ERROR_SUCCESS;\r\n            DWORD byteCount = 0;\r\n\r\n            while (data.size() < (64 << 20))\r\n            {\r\n                byteCount = wil::safe_cast<DWORD>(data.size());\r\n                status = RegGetValueW(key.get(), nullptr, valueName.c_str(), RRF_RT_ANY | RRF_NOEXPAND, &type, data.data(), &byteCount);\r\n\r\n                if (status == ERROR_MORE_DATA && byteCount > data.size())\r\n                {\r\n                    data.resize(byteCount);\r\n                }\r\n                else\r\n                {\r\n                    break;\r\n                }\r\n            }\r\n\r\n            if (status == ERROR_FILE_NOT_FOUND)\r\n            {\r\n                return false;\r\n            }\r\n\r\n            THROW_IF_WIN32_ERROR(status);\r\n\r\n            // Resize to actual data size\r\n            data.resize(byteCount);\r\n\r\n            return true;\r\n        }\r\n\r\n        bool DeleteRegistryValueData(const wil::shared_hkey& key, const std::wstring& valueName)\r\n        {\r\n            LSTATUS status = RegDeleteValueW(key.get(), valueName.c_str());\r\n\r\n            if (status == ERROR_FILE_NOT_FOUND)\r\n            {\r\n                return false;\r\n            }\r\n\r\n            THROW_IF_WIN32_ERROR(status);\r\n\r\n            return true;\r\n        }\r\n    }\r\n\r\n    namespace details\r\n    {\r\n        ValueTypeSpecifics<REG_NONE>::value_t ValueTypeSpecifics<REG_NONE>::Convert(const std::vector<BYTE>& data)\r\n        {\r\n            return data;\r\n        }\r\n\r\n        ValueTypeSpecifics<REG_SZ>::value_t ValueTypeSpecifics<REG_SZ>::Convert(const std::vector<BYTE>& data)\r\n        {\r\n            return ConvertBytesToString(data);\r\n        }\r\n\r\n        ValueTypeSpecifics<REG_SZ | AICLI_REGISTRY_UTF16_FLAG>::value_t ValueTypeSpecifics<REG_SZ | AICLI_REGISTRY_UTF16_FLAG>::Convert(const std::vector<BYTE>& data)\r\n        {\r\n            return ConvertBytesToWideString(data);\r\n        }\r\n\r\n        ValueTypeSpecifics<REG_EXPAND_SZ>::value_t ValueTypeSpecifics<REG_EXPAND_SZ>::Convert(const std::vector<BYTE>& data)\r\n        {\r\n            return Utility::ConvertToUTF8(Utility::ExpandEnvironmentVariables(ConvertBytesToWideString(data)));\r\n        }\r\n\r\n        ValueTypeSpecifics<REG_EXPAND_SZ | AICLI_REGISTRY_UTF16_FLAG>::value_t ValueTypeSpecifics<REG_EXPAND_SZ | AICLI_REGISTRY_UTF16_FLAG>::Convert(const std::vector<BYTE>& data)\r\n        {\r\n            return ConvertBytesToWideString(data);\r\n        }\r\n\r\n        ValueTypeSpecifics<REG_BINARY>::value_t ValueTypeSpecifics<REG_BINARY>::Convert(const std::vector<BYTE>& data)\r\n        {\r\n            return data;\r\n        }\r\n\r\n        ValueTypeSpecifics<REG_DWORD_LITTLE_ENDIAN>::value_t ValueTypeSpecifics<REG_DWORD_LITTLE_ENDIAN>::Convert(const std::vector<BYTE>& data)\r\n        {\r\n            return ConvertBytesToUInt32LE(data);\r\n        }\r\n    }\r\n\r\n    Value::Value(DWORD type, std::vector<BYTE>&& data) : m_type(static_cast<Type>(type)), m_data(std::move(data))\r\n    {\r\n    }\r\n\r\n    bool Value::HasCompatibleType(Type type) const\r\n    {\r\n        // Allow interop between String and ExpandString\r\n        if ((m_type == Type::String || m_type == Type::ExpandString || m_type == Type::UTF16String || m_type == Type::UTF16ExpandString) &&\r\n            (type == Type::String || type == Type::ExpandString || type == Type::UTF16String || type == Type::UTF16ExpandString))\r\n        {\r\n            return true;\r\n        }\r\n\r\n        return m_type == type;\r\n    }\r\n\r\n    ValueList::ValueRef::ValueRef(wil::shared_hkey key, std::wstring&& valueName) : m_key(std::move(key)), m_valueName(std::move(valueName)) {}\r\n\r\n    std::string ValueList::ValueRef::Name() const\r\n    {\r\n        return Utility::ConvertToUTF8(m_valueName);\r\n    }\r\n\r\n    std::optional<Value> ValueList::ValueRef::Value() const\r\n    {\r\n        DWORD type;\r\n        std::vector<BYTE> data;\r\n        if (!TryGetRegistryValueData(m_key, m_valueName, type, data))\r\n        {\r\n            return std::nullopt;\r\n        }\r\n\r\n        return Registry::Value{ type, std::move(data) };\r\n    }\r\n\r\n    ValueList::const_iterator& ValueList::const_iterator::operator++()\r\n    {\r\n        ++m_index;\r\n        GetValue();\r\n        return *this;\r\n    }\r\n\r\n    ValueList::const_iterator ValueList::const_iterator::operator++(int)\r\n    {\r\n        const_iterator result;\r\n        result.m_key = m_key;\r\n        result.m_index = m_index++;\r\n        result.m_value = std::nullopt;\r\n        std::swap(m_value, result.m_value);\r\n        GetValue();\r\n        return result;\r\n    }\r\n\r\n    bool ValueList::const_iterator::operator==(const const_iterator& other) const\r\n    {\r\n        return (!m_key && !other.m_key) || (m_key.get() == other.m_key.get() && m_index == other.m_index);\r\n    }\r\n\r\n    bool ValueList::const_iterator::operator!=(const const_iterator& other) const\r\n    {\r\n        return !operator==(other);\r\n    }\r\n\r\n    void ValueList::const_iterator::GetValue()\r\n    {\r\n        std::wstring valueName;\r\n        if (!TryGetRegistryValueNameFromIndex(m_key, m_index, valueName))\r\n        {\r\n            m_key.reset();\r\n            return;\r\n        }\r\n\r\n        m_value = ValueRef{ m_key, std::move(valueName) };\r\n    }\r\n\r\n    const ValueList::ValueRef& ValueList::const_iterator::operator*() const\r\n    {\r\n        return m_value.value();\r\n    }\r\n\r\n    const ValueList::ValueRef* ValueList::const_iterator::operator->() const\r\n    {\r\n        return &m_value.value();\r\n    }\r\n\r\n    ValueList::const_iterator::const_iterator(const wil::shared_hkey& key, DWORD index) : m_key(key), m_index(index)\r\n    {\r\n        GetValue();\r\n    }\r\n\r\n    ValueList::const_iterator ValueList::begin() const\r\n    {\r\n        return { m_key };\r\n    }\r\n\r\n    ValueList::const_iterator ValueList::end() const\r\n    {\r\n        return {};\r\n    }\r\n\r\n    ValueList::ValueList(wil::shared_hkey key) : m_key(key) {}\r\n\r\n    Key::Key(HKEY key)\r\n    {\r\n        Initialize(key, {}, 0, KEY_READ, false);\r\n    }\r\n\r\n    Key::Key(HKEY key, std::string_view subKey, DWORD options, REGSAM access)\r\n    {\r\n        Initialize(key, Utility::ConvertToUTF16(subKey), options, access, false);\r\n    }\r\n\r\n    Key::Key(HKEY key, const std::wstring& subKey, DWORD options, REGSAM access)\r\n    {\r\n        Initialize(key, subKey, options, access, false);\r\n    }\r\n\r\n    std::string Key::SubKeyRef::Name() const\r\n    {\r\n        return Utility::ConvertToUTF8(m_subKeyName);\r\n    }\r\n\r\n    Key Key::SubKeyRef::Open() const\r\n    {\r\n        return { m_parentKey.get(), m_subKeyName, 0, m_access };\r\n    }\r\n\r\n    Key::SubKeyRef::SubKeyRef(const wil::shared_hkey& key, REGSAM access) :\r\n        m_parentKey(key), m_access(access), m_subKeyName(64, L'\\0')\r\n    {\r\n        Enum(0);\r\n    }\r\n\r\n    void Key::SubKeyRef::Enum(DWORD index)\r\n    {\r\n        LSTATUS status = ERROR_SUCCESS;\r\n        DWORD charCount = 0;\r\n\r\n        while (m_subKeyName.size() < 4096)\r\n        {\r\n            charCount = wil::safe_cast<DWORD>(m_subKeyName.size());\r\n            status = RegEnumKeyExW(m_parentKey.get(), index, &m_subKeyName[0], &charCount, nullptr, nullptr, nullptr, nullptr);\r\n\r\n            if (status == ERROR_MORE_DATA)\r\n            {\r\n                // See if we can get away with the current capacity\r\n                if (m_subKeyName.size() < m_subKeyName.capacity())\r\n                {\r\n                    m_subKeyName.resize(m_subKeyName.capacity());\r\n                }\r\n                else\r\n                {\r\n                    m_subKeyName.resize(m_subKeyName.capacity() * 2);\r\n                }\r\n            }\r\n            else\r\n            {\r\n                break;\r\n            }\r\n        }\r\n\r\n        if (status == ERROR_SUCCESS)\r\n        {\r\n            m_subKeyName.resize(wil::safe_cast<size_t>(charCount));\r\n        }\r\n        else if (status == ERROR_NO_MORE_ITEMS)\r\n        {\r\n            m_parentKey.reset();\r\n        }\r\n        else\r\n        {\r\n            THROW_IF_WIN32_ERROR(status);\r\n        }\r\n    }\r\n\r\n    Key::const_iterator& Key::const_iterator::operator++()\r\n    {\r\n        m_subkey.Enum(++m_index);\r\n        return *this;\r\n    }\r\n\r\n    Key::const_iterator Key::const_iterator::operator++(int)\r\n    {\r\n        const_iterator result = *this;\r\n        m_subkey.Enum(++m_index);\r\n        return result;\r\n    }\r\n\r\n    bool Key::const_iterator::operator==(const const_iterator& other) const\r\n    {\r\n        return (!m_subkey.m_parentKey && !other.m_subkey.m_parentKey) || (m_subkey.m_parentKey.get() == other.m_subkey.m_parentKey.get() && m_index == other.m_index);\r\n    }\r\n\r\n    bool Key::const_iterator::operator!=(const const_iterator& other) const\r\n    {\r\n        return !operator==(other);\r\n    }\r\n\r\n    const Key::SubKeyRef& Key::const_iterator::operator*() const\r\n    {\r\n        return m_subkey;\r\n    }\r\n\r\n    const Key::SubKeyRef* Key::const_iterator::operator->() const\r\n    {\r\n        return &m_subkey;\r\n    }\r\n\r\n    Key::const_iterator::const_iterator(const wil::shared_hkey& key, REGSAM access) :\r\n        m_subkey(key, access)\r\n    {\r\n    }\r\n\r\n    Key::const_iterator Key::begin() const\r\n    {\r\n        return { m_key, m_access };\r\n    }\r\n\r\n    Key::const_iterator Key::end() const\r\n    {\r\n        return {};\r\n    }\r\n\r\n    std::optional<Value> Key::operator[](std::string_view name) const\r\n    {\r\n        return operator[](Utility::ConvertToUTF16(name));\r\n    }\r\n\r\n    std::optional<Value> Key::operator[](const std::wstring& name) const\r\n    {\r\n        DWORD type;\r\n        std::vector<BYTE> data;\r\n\r\n        if (TryGetRegistryValueData(m_key, name, type, data))\r\n        {\r\n            return Value{ type, std::move(data) };\r\n        }\r\n        else\r\n        {\r\n            return {};\r\n        }\r\n    }\r\n\r\n    void Key::DeleteValue(std::string_view name) const\r\n    {\r\n        DeleteValue(Utility::ConvertToUTF16(name));\r\n    }\r\n\r\n    void Key::DeleteValue(const std::wstring& name) const\r\n    {\r\n        if (DeleteRegistryValueData(m_key, name))\r\n        {\r\n            AICLI_LOG(Core, Verbose, << \"Registry value '\" << Utility::ConvertToUTF8(name) << \"' deleted successfully.\");\r\n        }\r\n        else\r\n        {\r\n            AICLI_LOG(Core, Verbose, << \"Registry value '\" << Utility::ConvertToUTF8(name) << \"' does not exist.\");\r\n        }\r\n    }\r\n\r\n    std::optional<Key> Key::SubKey(std::string_view subKey, DWORD options) const\r\n    {\r\n        return SubKey(Utility::ConvertToUTF16(subKey), options);\r\n    }\r\n\r\n    std::optional<Key> Key::SubKey(const std::wstring& subKey, DWORD options) const\r\n    {\r\n        if (!m_key)\r\n        {\r\n            return std::nullopt;\r\n        }\r\n\r\n        Key result;\r\n        if (result.Initialize(m_key.get(), subKey, options, m_access, true))\r\n        {\r\n            return result;\r\n        }\r\n        else\r\n        {\r\n            return std::nullopt;\r\n        }\r\n    }\r\n\r\n    void Key::SetValue(const std::wstring& name, const std::wstring& value, DWORD type) const\r\n    {\r\n        THROW_IF_WIN32_ERROR(RegSetValueExW(m_key.get(), name.c_str(), 0, type, reinterpret_cast<const BYTE*>(value.c_str()), static_cast<DWORD>(sizeof(wchar_t) * (value.size() + 1))));\r\n        AICLI_LOG(Core, Verbose, << \"Setting '\" << Utility::ConvertToUTF8(name) << \"' with the value: \" << Utility::ConvertToUTF8(value));\r\n    }\r\n\r\n    void Key::SetValue(const std::wstring& name, const std::vector<BYTE>& value, DWORD type) const\r\n    {\r\n        THROW_IF_WIN32_ERROR(RegSetValueExW(m_key.get(), name.c_str(), 0, type, reinterpret_cast<const BYTE*>(value.data()), static_cast<DWORD>(value.size())));\r\n        AICLI_LOG(Core, Verbose, << \"Setting '\" << Utility::ConvertToUTF8(name) << \"' with the value: \" << ConvertBytesToString(value));\r\n\r\n    }\r\n\r\n    void Key::SetValue(const std::wstring& name, DWORD value) const\r\n    {\r\n        THROW_IF_WIN32_ERROR(RegSetValueExW(m_key.get(), name.c_str(), 0, REG_DWORD, reinterpret_cast<const BYTE*>(&value), sizeof(DWORD)));\r\n        AICLI_LOG(Core, Verbose, << \"Setting '\" << Utility::ConvertToUTF8(name) << \"' with the value: \" << value);\r\n\r\n    }\r\n\r\n    ValueList Key::Values() const\r\n    {\r\n        return { m_key };\r\n    }\r\n\r\n    Key Key::OpenIfExists(HKEY key, std::string_view subKey, DWORD options, REGSAM access)\r\n    {\r\n        return OpenIfExists(key, Utility::ConvertToUTF16(subKey), options, access);\r\n    }\r\n\r\n    Key Key::OpenIfExists(HKEY key, const std::wstring& subKey, DWORD options, REGSAM access)\r\n    {\r\n        Key result;\r\n        result.Initialize(key, subKey, options, access, true);\r\n        return result;\r\n    }\r\n\r\n    Key Key::Create(HKEY key, std::string_view subKey, DWORD options, REGSAM access)\r\n    {\r\n        return Create(key, Utility::ConvertToUTF16(subKey), options, access);\r\n    }\r\n\r\n    Key Key::Create(HKEY key, const std::wstring& subKey, DWORD options, REGSAM access)\r\n    {\r\n        Key result;\r\n        result.CreateAndOpen(key, subKey, options, access);\r\n        return result;\r\n    }\r\n\r\n    bool Key::Delete(HKEY key, std::string_view subKey, DWORD samDesired)\r\n    {\r\n        return Delete(key, Utility::ConvertToUTF16(subKey), samDesired);\r\n    }\r\n\r\n    bool Key::Delete(HKEY key, const std::wstring& subKey, DWORD samDesired)\r\n    {\r\n        LSTATUS status = RegDeleteKeyExW(key, subKey.c_str(), samDesired, 0);\r\n        if (status == ERROR_SUCCESS)\r\n        {\r\n            AICLI_LOG(Core, Verbose, << \"Subkey '\" << Utility::ConvertToUTF8(subKey) << \"' was deleted successfully.\");\r\n            return true;\r\n        }\r\n        else if (status == ERROR_FILE_NOT_FOUND)\r\n        {\r\n            AICLI_LOG(Core, Verbose, << \"Subkey '\" << Utility::ConvertToUTF8(subKey) << \"' was not found.\");\r\n        }\r\n        else\r\n        {\r\n            THROW_IF_WIN32_ERROR(status);\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    bool Key::DeleteTree(HKEY key, const std::wstring& subKey)\r\n    {\r\n        LSTATUS status = RegDeleteTree(key, subKey.c_str());\r\n        if (status == ERROR_SUCCESS)\r\n        {\r\n            AICLI_LOG(Core, Verbose, << \"Subkey '\" << Utility::ConvertToUTF8(subKey) << \"' was deleted successfully.\");\r\n            return true;\r\n        }\r\n        else if (status == ERROR_FILE_NOT_FOUND)\r\n        {\r\n            AICLI_LOG(Core, Verbose, << \"Subkey '\" << Utility::ConvertToUTF8(subKey) << \"' was not found.\");\r\n        }\r\n        else\r\n        {\r\n            THROW_IF_WIN32_ERROR(status);\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    bool Key::CreateAndOpen(HKEY key, const std::wstring& subKey, DWORD options, REGSAM access)\r\n    {\r\n        m_access = access;\r\n        LPDWORD disposition = {};\r\n        LSTATUS status = RegCreateKeyExW(key, subKey.c_str(), 0, nullptr, options, access, NULL, &m_key, disposition);\r\n\r\n        if (disposition == (LPDWORD)REG_CREATED_NEW_KEY)\r\n        {\r\n            AICLI_LOG(Core, Verbose, << \"Subkey '\" << Utility::ConvertToUTF8(subKey) << \"' was created.\");\r\n        }\r\n        else if (disposition == (LPDWORD)REG_OPENED_EXISTING_KEY)\r\n        {\r\n            AICLI_LOG(Core, Verbose, << \"Subkey '\" << Utility::ConvertToUTF8(subKey) << \"' already existed and was opened.\");\r\n        }\r\n\r\n        THROW_IF_WIN32_ERROR(status);\r\n        return true;\r\n    }\r\n\r\n    bool Key::Initialize(HKEY key, const std::wstring& subKey, DWORD options, REGSAM access, bool ignoreErrorIfDoesNotExist)\r\n    {\r\n        m_access = access;\r\n        LSTATUS status = RegOpenKeyExW(key, subKey.c_str(), options, access, &m_key);\r\n\r\n        if (ignoreErrorIfDoesNotExist && status == ERROR_FILE_NOT_FOUND)\r\n        {\r\n            AICLI_LOG(Core, Verbose, << \"Subkey '\" << Utility::ConvertToUTF8(subKey) << \"' was not found\");\r\n            return false;\r\n        }\r\n\r\n        THROW_IF_WIN32_ERROR(status);\r\n        return true;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Resources.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"winget/Resources.h\"\r\n#include \"Public/AppInstallerLogging.h\"\r\n#include \"Public/AppInstallerStrings.h\"\r\n#include \"Public/AppInstallerErrors.h\"\r\n\r\nnamespace AppInstaller\r\n{\r\n    namespace Resource\r\n    {\r\n        namespace\r\n        {\r\n            std::pair<void*, size_t> GetResourceData(PCWSTR resourceName, PCWSTR resourceType)\r\n            {\r\n                HMODULE resourceModule = nullptr;\r\n                GetModuleHandleExW(\r\n                    GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,\r\n                    reinterpret_cast<PCWSTR>(GetResourceData),\r\n                    &resourceModule);\r\n                THROW_LAST_ERROR_IF_NULL(resourceModule);\r\n\r\n                HRSRC resourceInfoHandle = FindResourceW(resourceModule, resourceName, resourceType);\r\n                THROW_LAST_ERROR_IF_NULL(resourceInfoHandle);\r\n\r\n                HGLOBAL resourceMemoryHandle = LoadResource(resourceModule, resourceInfoHandle);\r\n                THROW_LAST_ERROR_IF_NULL(resourceMemoryHandle);\r\n\r\n                DWORD resourceSize = SizeofResource(resourceModule, resourceInfoHandle);\r\n                THROW_LAST_ERROR_IF(resourceSize == 0);\r\n\r\n                void* resourceContent = LockResource(resourceMemoryHandle);\r\n                THROW_HR_IF_NULL(E_UNEXPECTED, resourceContent);\r\n\r\n                return std::make_pair(resourceContent, static_cast<size_t>(resourceSize));\r\n            }\r\n        }\r\n\r\n        std::string_view GetResourceAsString(int resourceName, int resourceType)\r\n        {\r\n            return GetResourceAsString(MAKEINTRESOURCE(resourceName), MAKEINTRESOURCE(resourceType));\r\n        }\r\n\r\n        std::string_view GetResourceAsString(PCWSTR resourceName, PCWSTR resourceType)\r\n        {\r\n            auto resourceData = GetResourceData(resourceName, resourceType);\r\n            return { reinterpret_cast<char*>(resourceData.first), resourceData.second };\r\n        }\r\n\r\n        std::pair<const BYTE*, size_t> GetResourceAsBytes(int resourceName, int resourceType)\r\n        {\r\n            return GetResourceAsBytes(MAKEINTRESOURCE(resourceName), MAKEINTRESOURCE(resourceType));\r\n        }\r\n\r\n        std::pair<const BYTE*, size_t> GetResourceAsBytes(PCWSTR resourceName, PCWSTR resourceType)\r\n        {\r\n            auto resourceData = GetResourceData(resourceName, resourceType);\r\n            return std::make_pair(reinterpret_cast<BYTE*>(resourceData.first), resourceData.second);\r\n        }\r\n\r\n        // Utility class to load resources\r\n        struct Loader\r\n        {\r\n            // Gets the singleton instance of the resource loader.\r\n            static const Loader& Instance()\r\n            {\r\n                static Loader instance;\r\n                return instance;\r\n            }\r\n\r\n            // Gets the string resource value.\r\n            std::string ResolveString(std::wstring_view resKey) const\r\n            {\r\n                if (resKey.empty())\r\n                {\r\n                    return {};\r\n                }\r\n\r\n                if (m_wingetLoader)\r\n                {\r\n                    return Utility::ConvertToUTF8(m_wingetLoader.GetString(resKey));\r\n                }\r\n\r\n                // Loader failed to load resource file, print the resource key instead.\r\n                return Utility::ConvertToUTF8(resKey);\r\n            }\r\n\r\n            // Gets the string resource value or nothing if not present.\r\n            std::optional<Resource::LocString> TryResolveString(std::wstring_view resKey) const\r\n            {\r\n                if (!resKey.empty() && m_wingetLoader)\r\n                {\r\n                    try\r\n                    {\r\n                        winrt::hstring result = m_wingetLoader.GetString(resKey);\r\n\r\n                        if (!result.empty())\r\n                        {\r\n                            return Resource::LocString{ Utility::LocIndString{ Utility::ConvertToUTF8(result) } };\r\n                        }\r\n                    }\r\n                    CATCH_LOG()\r\n                }\r\n\r\n                return {};\r\n            }\r\n\r\n        private:\r\n            winrt::Windows::ApplicationModel::Resources::ResourceLoader m_wingetLoader;\r\n\r\n            Loader() : m_wingetLoader(nullptr)\r\n            {\r\n                try\r\n                {\r\n                    // The default constructor of ResourceLoader throws a winrt::hresult_error exception\r\n                    // when resource.pri is not found. ResourceLoader::GetForViewIndependentUse also throws\r\n                    // a winrt::hresult_error but for reasons unknown it only gets caught when running on the\r\n                    // debugger. Running without a debugger will result in a crash that not even adding a\r\n                    // catch all will fix. To provide a good error message we call the default constructor\r\n                    // before calling GetForViewIndependentUse.\r\n                    m_wingetLoader = winrt::Windows::ApplicationModel::Resources::ResourceLoader();\r\n                    m_wingetLoader = winrt::Windows::ApplicationModel::Resources::ResourceLoader::GetForViewIndependentUse(L\"winget\");\r\n                }\r\n                catch (const winrt::hresult_error& hre)\r\n                {\r\n                    // This message cannot be localized.\r\n                    AICLI_LOG(CLI, Error, << \"Failure loading resource file with error: \" << hre.code());\r\n                    m_wingetLoader = nullptr;\r\n                }\r\n            }\r\n        };\r\n    }\r\n\r\n    namespace StringResource\r\n    {\r\n        std::string StringId::Resolve() const\r\n        {\r\n            return Resource::Loader::Instance().ResolveString(*this);\r\n        }\r\n\r\n        std::ostream& operator<<(std::ostream& out, StringId si)\r\n        {\r\n            return (out << Resource::LocString{ si });\r\n        }\r\n\r\n        std::optional<Resource::LocString> TryResolveString(std::wstring_view resKey)\r\n        {\r\n            return Resource::Loader::Instance().TryResolveString(resKey);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Runtime.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include <binver/version.h>\r\n#include \"Public/winget/Runtime.h\"\r\n#include \"Public/AppInstallerLogging.h\"\r\n#include \"Public/AppInstallerStrings.h\"\r\n\r\n\r\nnamespace AppInstaller::Runtime\r\n{\r\n    using namespace Utility;\r\n\r\n    namespace\r\n    {\r\n        using namespace std::string_view_literals;\r\n        constexpr std::string_view s_PreviewBuildSuffix = \"-preview\"sv;\r\n\r\n        // Gets a boolean indicating whether the current process has identity.\r\n        bool DoesCurrentProcessHaveIdentity()\r\n        {\r\n            UINT32 length = 0;\r\n            LONG result = ::GetPackageFamilyName(GetCurrentProcess(), &length, nullptr);\r\n            return (result != APPMODEL_ERROR_NO_PACKAGE);\r\n        }\r\n\r\n        std::unique_ptr<byte[]> GetPACKAGE_ID()\r\n        {\r\n            UINT32 bufferLength = 0;\r\n            LONG gcpiResult = GetCurrentPackageId(&bufferLength, nullptr);\r\n            THROW_HR_IF(E_UNEXPECTED, gcpiResult != ERROR_INSUFFICIENT_BUFFER);\r\n\r\n            std::unique_ptr<byte[]> buffer = std::make_unique<byte[]>(bufferLength);\r\n\r\n            gcpiResult = GetCurrentPackageId(&bufferLength, buffer.get());\r\n            if (FAILED_WIN32_LOG(gcpiResult))\r\n            {\r\n                return {};\r\n            }\r\n\r\n            return buffer;\r\n        }\r\n\r\n        // Gets the package name; only succeeds if running in a packaged context.\r\n        std::string GetPackageName()\r\n        {\r\n            std::unique_ptr<byte[]> buffer = GetPACKAGE_ID();\r\n            if (!buffer)\r\n            {\r\n                return {};\r\n            }\r\n\r\n            PACKAGE_ID* packageId = reinterpret_cast<PACKAGE_ID*>(buffer.get());\r\n            return Utility::ConvertToUTF8(packageId->name);\r\n        }\r\n\r\n        // Gets the package version; only succeeds if running in a packaged context.\r\n        std::optional<PACKAGE_VERSION> GetPACKAGE_VERSION()\r\n        {\r\n            std::unique_ptr<byte[]> buffer = GetPACKAGE_ID();\r\n            if (!buffer)\r\n            {\r\n                return {};\r\n            }\r\n\r\n            PACKAGE_ID* packageId = reinterpret_cast<PACKAGE_ID*>(buffer.get());\r\n            return packageId->version;\r\n        }\r\n    }\r\n\r\n    bool IsRunningInPackagedContext()\r\n    {\r\n        static bool result = DoesCurrentProcessHaveIdentity();\r\n        return result;\r\n    }\r\n\r\n    LocIndString GetClientVersion()\r\n    {\r\n        std::ostringstream strstr;\r\n        strstr << VERSION_MAJOR << '.' << VERSION_MINOR << '.' << VERSION_BUILD;\r\n\r\n        if (!IsReleaseBuild())\r\n        {\r\n            strstr << s_PreviewBuildSuffix;\r\n        }\r\n\r\n        return LocIndString{ strstr.str() };\r\n    }\r\n\r\n    std::wstring GetPackageFamilyName()\r\n    {\r\n        UINT32 length = 0;\r\n        LONG returnValue = ::GetPackageFamilyName(GetCurrentProcess(), &length, nullptr);\r\n\r\n        if (returnValue == APPMODEL_ERROR_NO_PACKAGE)\r\n        {\r\n            return {};\r\n        }\r\n\r\n        if (returnValue != ERROR_INSUFFICIENT_BUFFER)\r\n        {\r\n            THROW_IF_WIN32_ERROR(returnValue);\r\n        }\r\n\r\n        std::wstring result(length, '\\0');\r\n        returnValue = ::GetPackageFamilyName(GetCurrentProcess(), &length, &result[0]);\r\n        THROW_IF_WIN32_ERROR(returnValue);\r\n        THROW_HR_IF(E_UNEXPECTED, length == 0);\r\n\r\n        result.resize(length - 1);\r\n        return result;\r\n    }\r\n\r\n    LocIndString GetPackageVersion()\r\n    {\r\n        using namespace std::string_literals;\r\n\r\n        if (IsRunningInPackagedContext())\r\n        {\r\n            auto version = GetPACKAGE_VERSION();\r\n\r\n            if (!version)\r\n            {\r\n                // In the extremely unlikely event of a failure, this is merely a sentinel value\r\n                // to indicated such.  The only other option is to completely prevent execution,\r\n                // which seems unnecessary.\r\n                return LocIndString{ \"error\"sv };\r\n            }\r\n\r\n            std::ostringstream strstr;\r\n            strstr << GetPackageName() << \" v\" << version->Major << '.' << version->Minor << '.' << version->Build << '.' << version->Revision;\r\n\r\n            return LocIndString{ strstr.str() };\r\n        }\r\n        else\r\n        {\r\n            // Calling code should avoid calling in when this is the case.\r\n            return LocIndString{ \"none\"sv };\r\n        }\r\n    }\r\n\r\n    LocIndString GetOSVersion()\r\n    {\r\n        winrt::Windows::System::Profile::AnalyticsInfo analyticsInfo{};\r\n        auto versionInfo = analyticsInfo.VersionInfo();\r\n\r\n        uint64_t version = std::stoull(Utility::ConvertToUTF8(versionInfo.DeviceFamilyVersion()));\r\n        uint16_t parts[4];\r\n\r\n        for (size_t i = 0; i < ARRAYSIZE(parts); ++i)\r\n        {\r\n            parts[i] = version & 0xFFFF;\r\n            version = version >> 16;\r\n        }\r\n\r\n        std::ostringstream strstr;\r\n        strstr << Utility::ConvertToUTF8(versionInfo.DeviceFamily()) << \" v\" << parts[3] << '.' << parts[2] << '.' << parts[1] << '.' << parts[0];\r\n\r\n        return LocIndString{ strstr.str() };\r\n    }\r\n\r\n    std::string GetOSRegion()\r\n    {\r\n        winrt::Windows::Globalization::GeographicRegion region;\r\n        return Utility::ConvertToUTF8(region.CodeTwoLetter());\r\n    }\r\n\r\n    bool IsCurrentOSVersionGreaterThanOrEqual(const Utility::Version& version)\r\n    {\r\n        DWORD versionParts[3] = {};\r\n\r\n        for (size_t i = 0; i < ARRAYSIZE(versionParts) && i < version.GetParts().size(); ++i)\r\n        {\r\n            versionParts[i] = static_cast<DWORD>(std::min(static_cast<decltype(version.GetParts()[i].Integer)>(std::numeric_limits<DWORD>::max()), version.GetParts()[i].Integer));\r\n        }\r\n\r\n        OSVERSIONINFOEXW osVersionInfo{};\r\n        osVersionInfo.dwOSVersionInfoSize = sizeof(osVersionInfo);\r\n        osVersionInfo.dwMajorVersion = versionParts[0];\r\n        osVersionInfo.dwMinorVersion = versionParts[1];\r\n        osVersionInfo.dwBuildNumber = versionParts[2];\r\n        osVersionInfo.wServicePackMajor = 0;\r\n        osVersionInfo.wServicePackMinor = 0;\r\n\r\n        DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR;\r\n\r\n        DWORDLONG conditions = 0;\r\n        VER_SET_CONDITION(conditions, VER_MAJORVERSION, VER_GREATER_EQUAL);\r\n        VER_SET_CONDITION(conditions, VER_MINORVERSION, VER_GREATER_EQUAL);\r\n        VER_SET_CONDITION(conditions, VER_BUILDNUMBER, VER_GREATER_EQUAL);\r\n        VER_SET_CONDITION(conditions, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);\r\n        VER_SET_CONDITION(conditions, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL);\r\n\r\n        BOOL result = VerifyVersionInfoW(&osVersionInfo, mask, conditions);\r\n        if (!result)\r\n        {\r\n            THROW_LAST_ERROR_IF(GetLastError() != ERROR_OLD_WIN_VERSION);\r\n        }\r\n        return !!result;\r\n    }\r\n\r\n    bool IsRunningAsAdmin()\r\n    {\r\n        return wil::test_token_membership(nullptr, SECURITY_NT_AUTHORITY, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS);\r\n    }\r\n\r\n    bool IsRunningAsSystem()\r\n    {\r\n        return wil::test_token_membership(nullptr, SECURITY_NT_AUTHORITY, SECURITY_LOCAL_SYSTEM_RID);\r\n    }\r\n\r\n    bool IsRunningAsAdminOrSystem()\r\n    {\r\n        return IsRunningAsAdmin() || IsRunningAsSystem();\r\n    }\r\n\r\n    bool IsRunningWithLimitedToken()\r\n    {\r\n        return wil::get_token_information<TOKEN_ELEVATION_TYPE>() == TokenElevationTypeLimited;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/SHA256.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include <pch.h>\r\n#define WIN32_NO_STATUS\r\n#include <bcrypt.h>\r\n#include \"Public/AppInstallerSHA256.h\"\r\n#include \"Public/AppInstallerErrors.h\"\r\n#include \"Public/AppInstallerStrings.h\"\r\n\r\nnamespace AppInstaller::Utility {\r\n\r\n    struct SHA256Context\r\n    {\r\n        wil::unique_bcrypt_algorithm algHandle;\r\n        wil::unique_bcrypt_hash hashHandle;\r\n        DWORD hashLength = 0;\r\n    };\r\n\r\n    SHA256::SHA256() : context(new SHA256Context{})\r\n    {\r\n        BCRYPT_ALG_HANDLE algHandleT{};\r\n        BCRYPT_HASH_HANDLE hashHandleT;\r\n        DWORD resultLength = 0;\r\n\r\n        // Open an algorithm handle\r\n        THROW_IF_NTSTATUS_FAILED_MSG(BCryptOpenAlgorithmProvider(\r\n            &algHandleT,                // Alg Handle pointer\r\n            BCRYPT_SHA256_ALGORITHM,    // Cryptographic Algorithm name (null terminated unicode string)\r\n            nullptr,                    // Provider name; if null, the default provider is loaded\r\n            0),                         // Flags\r\n            \"failed opening SHA256 algorithm provider\");\r\n        context->algHandle.reset(algHandleT);\r\n\r\n        // Obtain the length of the hash\r\n        THROW_IF_NTSTATUS_FAILED_MSG(BCryptGetProperty(\r\n            context->algHandle.get(),       // Handle to a CNG object\r\n            BCRYPT_HASH_LENGTH,             // Property name (null terminated unicode string)\r\n            (PBYTE) & (context->hashLength),  // Address of the output buffer which receives the property value\r\n            sizeof(context->hashLength),    // Size of the buffer in bytes\r\n            &resultLength,                  // Number of bytes that were copied into the buffer\r\n            0),                             // Flags\r\n            \"failed getting SHA256 hash length\");\r\n        \r\n        if (resultLength != sizeof(context->hashLength))\r\n        {\r\n            THROW_HR_MSG(E_UNEXPECTED, \"failed getting SHA256 hash length\");\r\n        }\r\n\r\n        // Create a hash handle\r\n        THROW_IF_NTSTATUS_FAILED_MSG(BCryptCreateHash(\r\n            context->algHandle.get(),   // Handle to an algorithm provider\r\n            &hashHandleT,               // A pointer to a hash handle - can be a hash or hmac object\r\n            nullptr,                    // Pointer to the buffer that receives the hash/hmac object\r\n            0,                          // Size of the buffer in bytes\r\n            nullptr,                    // A pointer to a key to use for the hash or MAC\r\n            0,                          // Size of the key in bytes\r\n            0),                         // Flags\r\n            \"failed creating SHA256 hash object\");\r\n        context->hashHandle.reset(hashHandleT);\r\n    }\r\n\r\n    void SHA256::Add(const uint8_t* buffer, size_t cbBuffer)\r\n    {\r\n        EnsureNotFinished();\r\n\r\n        // Add the data\r\n        THROW_IF_NTSTATUS_FAILED_MSG(\r\n            BCryptHashData(context->hashHandle.get(), const_cast<PUCHAR>(buffer), static_cast<ULONG>(cbBuffer), 0),\r\n            \"failed adding SHA256 data\");\r\n    }\r\n\r\n    void SHA256::Get(HashBuffer& hash)\r\n    {\r\n        EnsureNotFinished();\r\n\r\n        // Size the hash buffer appropriately\r\n        hash.resize(context->hashLength);\r\n\r\n        // Obtain the hash of the message(s) into the hash buffer\r\n        THROW_IF_NTSTATUS_FAILED_MSG(BCryptFinishHash(\r\n            context->hashHandle.get(),  // Handle to the hash or MAC object\r\n            hash.data(),                // A pointer to a buffer that receives the hash or MAC value\r\n            context->hashLength,        // Size of the buffer in bytes\r\n            0),                         // Flags\r\n            \"failed getting SHA256 hash\");\r\n\r\n        context.reset();\r\n    }\r\n\r\n    std::string SHA256::ConvertToString(const HashBuffer& hashBuffer)\r\n    {\r\n        return Utility::ConvertToHexString(hashBuffer, HashBufferSizeInBytes);\r\n    }\r\n\r\n    std::wstring SHA256::ConvertToWideString(const HashBuffer& hashBuffer)\r\n    {\r\n        return ConvertToUTF16(SHA256::ConvertToString(hashBuffer));\r\n    }\r\n\r\n    SHA256::HashBuffer SHA256::ConvertToBytes(const std::string& hashStr)\r\n    {\r\n        return Utility::ParseFromHexString(hashStr, HashBufferSizeInBytes);\r\n    }\r\n\r\n    SHA256::HashBuffer SHA256::ConvertToBytes(const std::wstring& hashStr)\r\n    {\r\n        return Utility::ParseFromHexString(Utility::ConvertToUTF8(hashStr), HashBufferSizeInBytes);\r\n    }\r\n\r\n    SHA256::HashBuffer SHA256::ComputeHash(const std::uint8_t* buffer, std::uint32_t cbBuffer)\r\n    {\r\n        SHA256 hasher;\r\n        hasher.Add(buffer, cbBuffer);\r\n        return hasher.Get();\r\n    }\r\n\r\n    SHA256::HashBuffer SHA256::ComputeHash(const std::vector<uint8_t>& buffer)\r\n    {\r\n        THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), buffer.size() > std::numeric_limits<uint32_t>::max());\r\n        return ComputeHash(buffer.data(), static_cast<uint32_t>(buffer.size()));\r\n    }\r\n\r\n    SHA256::HashBuffer SHA256::ComputeHash(std::string_view buffer)\r\n    {\r\n        return ComputeHash(reinterpret_cast<const std::uint8_t*>(buffer.data()), static_cast<std::uint32_t>(buffer.size()));\r\n    }\r\n\r\n    SHA256::HashBuffer SHA256::ComputeHash(std::istream& in)\r\n    {\r\n        return ComputeHashDetails(in).Hash;\r\n    }\r\n\r\n    SHA256::HashDetails SHA256::ComputeHashDetails(std::istream& in)\r\n    {\r\n        // Throw exceptions on badbit\r\n        auto excState = in.exceptions();\r\n        auto revertExcState = wil::scope_exit([excState, &in]() { in.exceptions(excState); });\r\n        in.exceptions(std::ios_base::badbit);\r\n\r\n        const int bufferSize = 1024 * 1024; // 1MB\r\n        auto buffer = std::make_unique<uint8_t[]>(bufferSize);\r\n\r\n        SHA256 hasher;\r\n        uint64_t totalSize = 0;\r\n\r\n        while (in.good())\r\n        {\r\n            in.read((char*)(buffer.get()), bufferSize);\r\n            std::streamsize bytesRead = in.gcount();\r\n            if (bytesRead)\r\n            {\r\n                hasher.Add(buffer.get(), static_cast<size_t>(bytesRead));\r\n                totalSize += static_cast<uint64_t>(bytesRead);\r\n            }\r\n        }\r\n\r\n        if (in.eof())\r\n        {\r\n            HashDetails result;\r\n            result.Hash = hasher.Get();\r\n            result.SizeInBytes = totalSize;\r\n            return result;\r\n        }\r\n        else\r\n        {\r\n            THROW_HR(APPINSTALLER_CLI_ERROR_STREAM_READ_FAILURE);\r\n        }\r\n    }\r\n\r\n    SHA256::HashBuffer SHA256::ComputeHashFromFile(const std::filesystem::path& path)\r\n    {\r\n        std::ifstream inStream{ path, std::ifstream::binary };\r\n        const Utility::SHA256::HashBuffer& targetFileHash = Utility::SHA256::ComputeHash(inStream);\r\n        inStream.close();\r\n        return targetFileHash;\r\n    }\r\n\r\n    void SHA256::SHA256ContextDeleter::operator()(SHA256Context* context)\r\n    {\r\n        delete context;\r\n    }\r\n\r\n    bool SHA256::AreEqual(const HashBuffer& first, const HashBuffer& second)\r\n    {\r\n        return (first.size() == second.size() && std::equal(first.begin(), first.end(), second.begin()));\r\n    }\r\n\r\n    void SHA256::EnsureNotFinished() const\r\n    {\r\n        if (!context)\r\n        {\r\n            THROW_HR_MSG(E_UNEXPECTED, \"The hash is already finished\");\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/SQLiteDynamicStorage.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/SQLiteDynamicStorage.h\"\r\n\r\nnamespace AppInstaller::SQLite\r\n{\r\n    SQLiteDynamicStorage::SQLiteDynamicStorage(const std::string& target, const Version& version) : SQLiteStorageBase(target, version)\r\n    {\r\n        version.SetSchemaVersion(m_dbconn);\r\n    }\r\n\r\n    SQLiteDynamicStorage::SQLiteDynamicStorage(const std::filesystem::path& target, const Version& version) : SQLiteDynamicStorage(target.u8string(), version)\r\n    {}\r\n\r\n    SQLiteDynamicStorage::SQLiteDynamicStorage(\r\n        const std::string& filePath,\r\n        SQLiteStorageBase::OpenDisposition disposition,\r\n        Utility::ManagedFile&& file)\r\n        : SQLiteStorageBase(filePath, disposition, std::move(file))\r\n    {}\r\n\r\n    SQLiteDynamicStorage::SQLiteDynamicStorage(\r\n        const std::filesystem::path& filePath,\r\n        SQLiteStorageBase::OpenDisposition disposition,\r\n        Utility::ManagedFile&& file)\r\n        : SQLiteDynamicStorage(filePath.u8string(), disposition, std::move(file))\r\n    {}\r\n\r\n    SQLiteDynamicStorage::operator Connection& ()\r\n    {\r\n        return m_dbconn;\r\n    }\r\n\r\n    SQLiteDynamicStorage::operator const Connection& () const\r\n    {\r\n        return m_dbconn;\r\n    }\r\n\r\n    Connection& SQLiteDynamicStorage::GetConnection()\r\n    {\r\n        return m_dbconn;\r\n    }\r\n\r\n    const Connection& SQLiteDynamicStorage::GetConnection() const\r\n    {\r\n        return m_dbconn;\r\n    }\r\n\r\n    _Acquires_lock_(mutex)\r\n    SQLiteDynamicStorage::TransactionLock::TransactionLock(std::mutex& mutex) :\r\n        m_lock(mutex)\r\n    {\r\n    }\r\n\r\n    _Acquires_lock_(mutex)\r\n    SQLiteDynamicStorage::TransactionLock::TransactionLock(std::mutex& mutex, Connection& connection, std::string_view name, bool immediateWrite) :\r\n        m_lock(mutex)\r\n    {\r\n        m_transaction = Transaction::Create(connection, std::string{ name }, immediateWrite);\r\n    }\r\n\r\n    void SQLiteDynamicStorage::TransactionLock::Rollback(bool throwOnError)\r\n    {\r\n        m_transaction.Rollback(throwOnError);\r\n    }\r\n\r\n    void SQLiteDynamicStorage::TransactionLock::Commit()\r\n    {\r\n        m_transaction.Commit();\r\n    }\r\n\r\n    std::unique_ptr<SQLiteDynamicStorage::TransactionLock> SQLiteDynamicStorage::TryBeginTransaction(std::string_view name, bool immediateWrite)\r\n    {\r\n        auto result = std::make_unique<TransactionLock>(*m_interfaceLock, m_dbconn, name, immediateWrite);\r\n\r\n        Version currentVersion = Version::GetSchemaVersion(m_dbconn);\r\n        if (currentVersion != m_version)\r\n        {\r\n            m_version = currentVersion;\r\n            result.reset();\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::unique_ptr<SQLiteDynamicStorage::TransactionLock> SQLiteDynamicStorage::LockConnection()\r\n    {\r\n        return std::make_unique<TransactionLock>(*m_interfaceLock);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/SQLiteMetadataTable.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/SQLiteMetadataTable.h\"\r\n\r\n\r\nusing namespace std::literals;\r\n\r\nnamespace AppInstaller::SQLite\r\n{\r\n    // Table data [note that this table is not versioned, and thus *cannot change*]\r\n    static constexpr std::string_view s_MetadataTable_Table_Name = \"metadata\"sv;\r\n    static constexpr std::string_view s_MetadataTable_Column_Name = \"name\"sv;\r\n    static constexpr std::string_view s_MetadataTable_Column_Value = \"value\"sv;\r\n\r\n    static constexpr std::string_view s_MetadataTable_Table_Create = R\"(\r\nCREATE TABLE [metadata](\r\n    [name] TEXT PRIMARY KEY NOT NULL,\r\n    [value] TEXT NOT NULL) WITHOUT ROWID\r\n)\"sv;\r\n\r\n    // Statements\r\n    static constexpr std::string_view s_MetadataTableStmt_GetNamedValue = \"select [value] from [metadata] where [name] = ?\"sv;\r\n    static constexpr std::string_view s_MetadataTableStmt_SetNamedValue = \"insert or replace into [metadata] ([name], [value]) values (?, ?)\"sv;\r\n\r\n    void MetadataTable::Create(Connection& connection)\r\n    {\r\n        Statement create = Statement::Create(connection, s_MetadataTable_Table_Create);\r\n        create.Execute();\r\n    }\r\n\r\n    Statement MetadataTable::GetNamedValueStatement(const Connection& connection, std::string_view name)\r\n    {\r\n        std::optional<Statement> result = TryGetNamedValueStatement(connection, name);\r\n        THROW_HR_IF(E_NOT_SET, !result);\r\n        return std::move(result).value();\r\n    }\r\n\r\n    std::optional<Statement> MetadataTable::TryGetNamedValueStatement(const Connection& connection, std::string_view name)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, name.empty());\r\n\r\n        Statement result = Statement::Create(connection, s_MetadataTableStmt_GetNamedValue);\r\n        result.Bind(1, name);\r\n\r\n        if (result.Step())\r\n        {\r\n            return result;\r\n        }\r\n        else\r\n        {\r\n            return std::nullopt;\r\n        }\r\n    }\r\n\r\n    Statement MetadataTable::SetNamedValueStatement(const Connection& connection, std::string_view name)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, name.empty());\r\n        Statement result = Statement::Create(connection, s_MetadataTableStmt_SetNamedValue);\r\n        result.Bind(1, name);\r\n        return result;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/SQLiteStatementBuilder.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/SQLiteStatementBuilder.h\"\r\n\r\nnamespace AppInstaller::SQLite::Builder\r\n{\r\n    std::ostream& operator<<(std::ostream& out, const QualifiedColumn& column)\r\n    {\r\n        if (!column.Table.empty())\r\n        {\r\n            out << '[' << column.Table << \"].\";\r\n        }\r\n        out << '[' << column.Column << ']';\r\n        return out;\r\n    }\r\n\r\n    std::ostream& operator<<(std::ostream& out, const QualifiedTable& table)\r\n    {\r\n        if (!table.Schema.empty())\r\n        {\r\n            out << '[' << table.Schema << \"].\";\r\n        }\r\n        out << '[' << table.Table << ']';\r\n        return out;\r\n    }\r\n\r\n    std::ostream& operator<<(std::ostream& out, const details::SubBuilder& column)\r\n    {\r\n        out << column.GetString();\r\n        return out;\r\n    }\r\n\r\n    namespace\r\n    {\r\n        void OutputColumns(std::ostream& out, std::string_view op, std::string_view column)\r\n        {\r\n            out << op << '[' << column << ']';\r\n        }\r\n\r\n        void OutputColumns(std::ostream& out, std::string_view op, std::initializer_list<std::string_view> columns)\r\n        {\r\n            out << op;\r\n            bool isFirst = true;\r\n            for (const auto& c : columns)\r\n            {\r\n                out << (isFirst ? \"[\" : \", [\") << c << ']';\r\n                isFirst = false;\r\n            }\r\n        }\r\n\r\n        void OutputColumns(std::ostream& out, std::string_view op, const QualifiedColumn& column)\r\n        {\r\n            out << op << column;\r\n        }\r\n\r\n        void OutputColumns(std::ostream& out, std::string_view op, std::initializer_list<QualifiedColumn> columns)\r\n        {\r\n            out << op;\r\n            bool isFirst = true;\r\n            for (const auto& c : columns)\r\n            {\r\n                out << (isFirst ? \"\" : \", \") << c;\r\n                isFirst = false;\r\n            }\r\n        }\r\n\r\n        void OutputColumns(std::ostream& out, std::string_view op, std::initializer_list<details::SubBuilder> columns)\r\n        {\r\n            out << op;\r\n            bool isFirst = true;\r\n            for (const auto& c : columns)\r\n            {\r\n                out << (isFirst ? \"\" : \", \") << c;\r\n                isFirst = false;\r\n            }\r\n        }\r\n\r\n        void OutputAggregate(std::ostream& out, Aggregate op)\r\n        {\r\n            out << ' ';\r\n            switch (op)\r\n            {\r\n            case Aggregate::Min:\r\n                out << \"MIN\";\r\n                break;\r\n            case Aggregate::Max:\r\n                out << \"MAX\";\r\n                break;\r\n            default:\r\n                THROW_HR(E_UNEXPECTED);\r\n            }\r\n        }\r\n\r\n        void OutputColumns(std::ostream& out, Aggregate op, std::string_view column)\r\n        {\r\n            OutputAggregate(out, op);\r\n            out << \"([\" << column << \"])\";\r\n        }\r\n\r\n        void OutputColumns(std::ostream& out, Aggregate op, const QualifiedColumn& column)\r\n        {\r\n            OutputAggregate(out, op);\r\n            out << '(' << column << ')';\r\n        }\r\n\r\n        // Use to output operation and table name, such as \" FROM [table]\"\r\n        void OutputOperationAndTable(std::ostream& out, std::string_view op, std::string_view table)\r\n        {\r\n            out << op << \" [\" << table << ']';\r\n        }\r\n\r\n        void OutputOperationAndTable(std::ostream& out, std::string_view op, QualifiedTable table)\r\n        {\r\n            out << op << table;\r\n        }\r\n\r\n        void OutputOperationAndTable(std::ostream& out, std::string_view op, std::initializer_list<std::string_view> table)\r\n        {\r\n            out << op << \" [\";\r\n            for (std::string_view t : table)\r\n            {\r\n                out << t;\r\n            }\r\n            out << ']';\r\n        }\r\n\r\n        void OutputType(std::ostream& out, Type type)\r\n        {\r\n            out << ' ';\r\n            switch (type)\r\n            {\r\n            case Type::Int:\r\n                out << \"INT\";\r\n                break;\r\n            case Type::Int64:\r\n                out << \"INT64\";\r\n                break;\r\n            case Type::Text:\r\n                out << \"TEXT\";\r\n                break;\r\n            case Type::Blob:\r\n                out << \"BLOB\";\r\n                break;\r\n            case Type::Integer:\r\n                out << \"INTEGER\";\r\n                break;\r\n            case Type::None:\r\n                break;\r\n            default:\r\n                THROW_HR(E_UNEXPECTED);\r\n            }\r\n        }\r\n    }\r\n\r\n    IntegerPrimaryKey::IntegerPrimaryKey()\r\n    {\r\n        m_stream << SQLite::RowIDName << \" INTEGER PRIMARY KEY\";\r\n    }\r\n\r\n    IntegerPrimaryKey& IntegerPrimaryKey::AutoIncrement(bool isTrue)\r\n    {\r\n        if (isTrue)\r\n        {\r\n            m_stream << \" AUTOINCREMENT\";\r\n        }\r\n        return *this;\r\n    }\r\n\r\n    ColumnBuilder::ColumnBuilder(std::string_view column, Type type)\r\n    {\r\n        OutputColumns(m_stream, \"\", column);\r\n        OutputType(m_stream, type);\r\n    }\r\n\r\n    ColumnBuilder& ColumnBuilder::NotNull(bool isTrue)\r\n    {\r\n        if (isTrue)\r\n        {\r\n            m_stream << \" NOT NULL\";\r\n        }\r\n        return *this;\r\n    }\r\n\r\n    ColumnBuilder& ColumnBuilder::CollateNoCase(bool isTrue)\r\n    {\r\n        if (isTrue)\r\n        {\r\n            m_stream << \" COLLATE NOCASE\";\r\n        }\r\n        return *this;\r\n    }\r\n\r\n    ColumnBuilder& ColumnBuilder::Default(int64_t value)\r\n    {\r\n        m_stream << \" DEFAULT \" << value;\r\n        return *this;\r\n    }\r\n\r\n    ColumnBuilder& ColumnBuilder::Unique(bool isTrue)\r\n    {\r\n        if (isTrue)\r\n        {\r\n            m_stream << \" UNIQUE\";\r\n        }\r\n        return *this;\r\n    }\r\n\r\n    ColumnBuilder& ColumnBuilder::PrimaryKey(bool isTrue)\r\n    {\r\n        if (isTrue)\r\n        {\r\n            m_stream << \" PRIMARY KEY\";\r\n        }\r\n        return *this;\r\n    }\r\n\r\n    PrimaryKeyBuilder::PrimaryKeyBuilder(std::initializer_list<std::string_view> columns)\r\n    {\r\n        OutputColumns(m_stream, \"PRIMARY KEY(\", columns);\r\n        m_stream << ')';\r\n        m_needsClosing = false;\r\n    }\r\n\r\n    PrimaryKeyBuilder::PrimaryKeyBuilder()\r\n    {\r\n        m_stream << \"PRIMARY KEY(\";\r\n    }\r\n\r\n    PrimaryKeyBuilder& PrimaryKeyBuilder::Column(std::string_view column)\r\n    {\r\n        if (m_isFirst)\r\n        {\r\n            m_isFirst = false;\r\n        }\r\n        else\r\n        {\r\n            m_stream << \", \";\r\n        }\r\n        OutputColumns(m_stream, \"\", column);\r\n        return *this;\r\n    }\r\n\r\n    PrimaryKeyBuilder::operator details::SubBuilder()\r\n    {\r\n        if (m_needsClosing)\r\n        {\r\n            m_stream << ')';\r\n            m_needsClosing = false;\r\n        }\r\n        return { m_stream.str() };\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Select()\r\n    {\r\n        m_stream << \"SELECT \";\r\n        m_needsComma = false;\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Select(std::string_view column)\r\n    {\r\n        OutputColumns(m_stream, \"SELECT \", column);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Select(std::initializer_list<std::string_view> columns)\r\n    {\r\n        OutputColumns(m_stream, \"SELECT \", columns);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Select(const QualifiedColumn& column)\r\n    {\r\n        OutputColumns(m_stream, \"SELECT \", column);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Select(std::initializer_list<QualifiedColumn> columns)\r\n    {\r\n        OutputColumns(m_stream, \"SELECT \", columns);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Select(details::rowcount_t)\r\n    {\r\n        m_stream << \"SELECT COUNT(*)\";\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::From()\r\n    {\r\n        m_stream << \" FROM \";\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::From(std::string_view table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \" FROM\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::From(QualifiedTable table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \" FROM\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::From(std::initializer_list<std::string_view> table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \" FROM\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Where(std::string_view column)\r\n    {\r\n        OutputColumns(m_stream, \" WHERE \", column);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Where(const QualifiedColumn& column)\r\n    {\r\n        OutputColumns(m_stream, \" WHERE \", column);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::WhereValueContainsEmbeddedNullCharacter(std::string_view column)\r\n    {\r\n        OutputColumns(m_stream, \" WHERE instr(\", column);\r\n        m_stream << \",char(0))>0\";\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::WhereValueContainsEmbeddedNullCharacter(const QualifiedColumn& column)\r\n    {\r\n        OutputColumns(m_stream, \" WHERE instr(\", column);\r\n        m_stream << \",char(0))>0\";\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Equals(details::unbound_t, std::optional<size_t> index)\r\n    {\r\n        AppendOpAndBinder(Op::Equals, index);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Equals(std::nullptr_t)\r\n    {\r\n        // This is almost certainly not what you want.\r\n        // In SQL, value = NULL is always false.\r\n        // Use StatementBuilder::IsNull instead.\r\n        THROW_HR(E_NOTIMPL);\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Equals()\r\n    {\r\n        m_stream << \" =\";\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Equals(const QualifiedColumn& column)\r\n    {\r\n        OutputColumns(m_stream, \" = \", column);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::IsGreaterThan(details::unbound_t, std::optional<size_t> index)\r\n    {\r\n        AppendOpAndBinder(Op::GreaterThan, index);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::IsGreaterThanOrEqualTo(details::unbound_t, std::optional<size_t> index)\r\n    {\r\n        AppendOpAndBinder(Op::GreaterThanOrEqualTo, index);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::LikeWithEscape(std::string_view value)\r\n    {\r\n        AddBindFunctor(AppendOpAndBinder(Op::Like), EscapeStringForLike(value));\r\n        return Escape(EscapeCharForLike);\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Like(details::unbound_t)\r\n    {\r\n        AppendOpAndBinder(Op::Like);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Escape(std::string_view escapeChar)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, escapeChar.length() != 1);\r\n        AddBindFunctor(AppendOpAndBinder(Op::Escape), escapeChar);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Not()\r\n    {\r\n        m_stream << \" NOT\";\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::In()\r\n    {\r\n        m_stream << \" IN\";\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::In(size_t count)\r\n    {\r\n        m_stream << \" IN (\";\r\n        for (size_t i = 0; i < count; ++i)\r\n        {\r\n            m_stream << (i == 0 ? \"?\" : \", ?\");\r\n        }\r\n        m_stream << ')';\r\n\r\n        m_bindIndex += static_cast<int>(count);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::IsNull(bool isNull)\r\n    {\r\n        m_stream << \" IS \" << (isNull ? \"\" : \"NOT \") << \"NULL\";\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::And(std::string_view column)\r\n    {\r\n        OutputColumns(m_stream, \" AND \", column);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::And(const QualifiedColumn& column)\r\n    {\r\n        OutputColumns(m_stream, \" AND \", column);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Or(const QualifiedColumn& column)\r\n    {\r\n        OutputColumns(m_stream, \" OR \", column);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Join(std::string_view table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \" JOIN\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Join(QualifiedTable table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \" JOIN\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Join(std::initializer_list<std::string_view> table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \" JOIN\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::LeftOuterJoin(std::string_view table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \" LEFT OUTER JOIN\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::LeftOuterJoin(QualifiedTable table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \" LEFT OUTER JOIN\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::LeftOuterJoin(std::initializer_list<std::string_view> table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \" LEFT OUTER JOIN\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::On(const QualifiedColumn& column1, const QualifiedColumn& column2)\r\n    {\r\n        m_stream << \" ON \" << column1 << \" = \" << column2;\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Limit(size_t rowCount)\r\n    {\r\n        m_stream << \" LIMIT \" << rowCount;\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::GroupBy(std::string_view column)\r\n    {\r\n        OutputColumns(m_stream, \" GROUP BY \", column);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::GroupBy(const QualifiedColumn& column)\r\n    {\r\n        OutputColumns(m_stream, \" GROUP BY \", column);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::OrderBy(std::string_view column)\r\n    {\r\n        OutputColumns(m_stream, \" ORDER BY \", column);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::OrderBy(const QualifiedColumn& column)\r\n    {\r\n        OutputColumns(m_stream, \" ORDER BY \", column);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::OrderBy(std::initializer_list<std::string_view> columns)\r\n    {\r\n        OutputColumns(m_stream, \" ORDER BY \", columns);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Ascending()\r\n    {\r\n        m_stream << \" ASC\";\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Descending()\r\n    {\r\n        m_stream << \" DESC\";\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::InsertInto(std::string_view table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"INSERT INTO\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::InsertInto(QualifiedTable table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"INSERT INTO\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::InsertInto(std::initializer_list<std::string_view> table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"INSERT INTO\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::InsertOrIgnore(std::string_view table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"INSERT OR IGNORE INTO\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::InsertOrIgnore(QualifiedTable table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"INSERT OR IGNORE INTO\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::InsertOrIgnore(std::initializer_list<std::string_view> table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"INSERT OR IGNORE INTO\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Columns(std::string_view column)\r\n    {\r\n        OutputColumns(m_stream, \"(\", column);\r\n        m_stream << ')';\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Columns(std::initializer_list<std::string_view> columns)\r\n    {\r\n        OutputColumns(m_stream, \"(\", columns);\r\n        m_stream << ')';\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Columns(const QualifiedColumn& column)\r\n    {\r\n        OutputColumns(m_stream, \"(\", column);\r\n        m_stream << ')';\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Columns(std::initializer_list<QualifiedColumn> columns)\r\n    {\r\n        OutputColumns(m_stream, \"(\", columns);\r\n        m_stream << ')';\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Columns(std::initializer_list<details::SubBuilder> columns)\r\n    {\r\n        OutputColumns(m_stream, \"(\", columns);\r\n        m_stream << ')';\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::BeginColumns()\r\n    {\r\n        m_stream << '(';\r\n        m_needsComma = false;\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Column(std::string_view column)\r\n    {\r\n        if (m_needsComma)\r\n        {\r\n            m_stream << \", \";\r\n        }\r\n        OutputColumns(m_stream, \"\", column);\r\n        m_needsComma = true;\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Column(const QualifiedColumn& column)\r\n    {\r\n        if (m_needsComma)\r\n        {\r\n            m_stream << \", \";\r\n        }\r\n        OutputColumns(m_stream, \"\", column);\r\n        m_needsComma = true;\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Column(Aggregate aggOp, std::string_view column)\r\n    {\r\n        if (m_needsComma)\r\n        {\r\n            m_stream << \", \";\r\n        }\r\n        OutputColumns(m_stream, aggOp, column);\r\n        m_needsComma = true;\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Column(Aggregate aggOp, const QualifiedColumn& column)\r\n    {\r\n        if (m_needsComma)\r\n        {\r\n            m_stream << \", \";\r\n        }\r\n        OutputColumns(m_stream, aggOp, column);\r\n        m_needsComma = true;\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Column(const details::SubBuilder& column)\r\n    {\r\n        if (m_needsComma)\r\n        {\r\n            m_stream << \", \";\r\n        }\r\n        m_stream << column;\r\n        m_needsComma = true;\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::EndColumns()\r\n    {\r\n        m_stream << ')';\r\n        m_needsComma = false;\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::NotNull(bool isTrue)\r\n    {\r\n        if (isTrue)\r\n        {\r\n            m_stream << \" NOT NULL\";\r\n        }\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::BeginValues()\r\n    {\r\n        m_stream << \" VALUES (\";\r\n        m_needsComma = false;\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::EndValues()\r\n    {\r\n        m_stream << ')';\r\n        m_needsComma = false;\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::CreateTable(std::string_view table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"CREATE TABLE\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::CreateTable(QualifiedTable table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"CREATE TABLE\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::CreateTable(std::initializer_list<std::string_view> table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"CREATE TABLE\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::AlterTable(std::string_view table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"ALTER TABLE\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::AlterTable(QualifiedTable table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"ALTER TABLE\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::AlterTable(std::initializer_list<std::string_view> table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"ALTER TABLE\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Add(std::string_view column, Type type)\r\n    {\r\n        m_stream << \" ADD \" << column;\r\n        OutputType(m_stream, type);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::DropTable(std::string_view table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"DROP TABLE\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::DropTable(QualifiedTable table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"DROP TABLE\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::DropTable(std::initializer_list<std::string_view> table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"DROP TABLE\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::DropTableIfExists(std::string_view table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"DROP TABLE IF EXISTS\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::DropTableIfExists(QualifiedTable table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"DROP TABLE IF EXISTS\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::DropTableIfExists(std::initializer_list<std::string_view> table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"DROP TABLE IF EXISTS\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::CreateIndex(std::string_view table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"CREATE INDEX\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::CreateIndex(QualifiedTable table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"CREATE INDEX\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::CreateIndex(std::initializer_list<std::string_view> table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"CREATE INDEX\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::CreateUniqueIndex(std::string_view table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"CREATE UNIQUE INDEX\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::CreateUniqueIndex(QualifiedTable table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"CREATE UNIQUE INDEX\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::CreateUniqueIndex(std::initializer_list<std::string_view> table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"CREATE UNIQUE INDEX\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::DropIndex(std::string_view index)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"DROP INDEX\", index);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::DropIndex(QualifiedTable index)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"DROP INDEX\", index);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::DropIndex(std::initializer_list<std::string_view> index)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"DROP INDEX\", index);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::On(std::string_view table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \" ON\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::On(std::initializer_list<std::string_view> table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \" ON\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::DeleteFrom(std::string_view table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"DELETE FROM\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::DeleteFrom(QualifiedTable table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"DELETE FROM\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::DeleteFrom(std::initializer_list<std::string_view> table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"DELETE FROM\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Update(std::string_view table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"UPDATE\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Update(QualifiedTable table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"UPDATE\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Update(std::initializer_list<std::string_view> table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"UPDATE\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::UpdateOrReplace(std::string_view table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"UPDATE OR REPLACE\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::UpdateOrReplace(QualifiedTable table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"UPDATE OR REPLACE\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::UpdateOrReplace(std::initializer_list<std::string_view> table)\r\n    {\r\n        OutputOperationAndTable(m_stream, \"UPDATE OR REPLACE\", table);\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Set()\r\n    {\r\n        m_stream << \" SET \";\r\n        m_needsComma = false;\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::Vacuum()\r\n    {\r\n        m_stream << \"VACUUM\";\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::BeginParenthetical()\r\n    {\r\n        m_stream << '(';\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::EndParenthetical()\r\n    {\r\n        m_stream << ')';\r\n        return *this;\r\n    }\r\n\r\n    StatementBuilder& StatementBuilder::WithoutRowID()\r\n    {\r\n        m_stream << \" WITHOUT ROWID\";\r\n        return *this;\r\n    }\r\n\r\n\r\n    StatementBuilder& StatementBuilder::As(std::string_view alias)\r\n    {\r\n        OutputOperationAndTable(m_stream, \" AS\", alias);\r\n        return *this;\r\n    }\r\n\r\n    Statement StatementBuilder::Prepare(const Connection& connection)\r\n    {\r\n        Statement result = Statement::Create(connection, m_stream.str());\r\n        for (const auto& f : m_binders)\r\n        {\r\n            f(result);\r\n        }\r\n        return result;\r\n    }\r\n\r\n    void StatementBuilder::Execute(const Connection& connection)\r\n    {\r\n        Prepare(connection).Execute();\r\n    }\r\n\r\n    int StatementBuilder::AppendOpAndBinder(Op op, std::optional<size_t> index)\r\n    {\r\n        switch (op)\r\n        {\r\n        case Op::Equals:\r\n            m_stream << \" = ?\";\r\n            break;\r\n        case Op::Like:\r\n            m_stream << \" LIKE ?\";\r\n            break;\r\n        case Op::Escape:\r\n            m_stream << \" ESCAPE ?\";\r\n            break;\r\n        case Op::Literal:\r\n            m_stream << \" ?\";\r\n            break;\r\n        case Op::GreaterThan:\r\n            m_stream << \" > ?\";\r\n            break;\r\n        case Op::GreaterThanOrEqualTo:\r\n            m_stream << \" >= ?\";\r\n            break;\r\n        default:\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n\r\n        if (index)\r\n        {\r\n            m_stream << index.value();\r\n        }\r\n\r\n        return m_bindIndex++;\r\n    }\r\n\r\n    int StatementBuilder::AppendValuesAndBinders(size_t count)\r\n    {\r\n        m_stream << \" VALUES (\";\r\n        for (size_t i = 0; i < count; ++i)\r\n        {\r\n            m_stream << (i == 0 ? \"?\" : \", ?\");\r\n        }\r\n        m_stream << ')';\r\n\r\n        int result = m_bindIndex;\r\n        m_bindIndex += static_cast<int>(count);\r\n        return result;\r\n    }\r\n\r\n    int StatementBuilder::AppendValueAndBinder()\r\n    {\r\n        if (m_needsComma)\r\n        {\r\n            m_stream << \", \";\r\n        }\r\n        m_stream << '?';\r\n        m_needsComma = true;\r\n        return m_bindIndex++;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/SQLiteStorageBase.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/SQLiteStorageBase.h\"\r\n#include \"Public/winget/SQLiteMetadataTable.h\"\r\n#include \"AppInstallerDateTime.h\"\r\n\r\nnamespace AppInstaller::SQLite\r\n{\r\n    namespace\r\n    {\r\n        static char const* const GetOpenDispositionString(SQLiteStorageBase::OpenDisposition disposition)\r\n        {\r\n            switch (disposition)\r\n            {\r\n            case SQLiteStorageBase::OpenDisposition::Read:\r\n                return \"Read\";\r\n            case SQLiteStorageBase::OpenDisposition::ReadWrite:\r\n                return \"ReadWrite\";\r\n            case SQLiteStorageBase::OpenDisposition::Immutable:\r\n                return \"ImmutableRead\";\r\n            default:\r\n                return \"Unknown\";\r\n            }\r\n        }\r\n\r\n        std::filesystem::path AddSuffix(const std::filesystem::path& source, std::wstring_view suffix)\r\n        {\r\n            std::filesystem::path result{ source };\r\n\r\n            if (!suffix.empty())\r\n            {\r\n                std::wstring filename = result.filename().wstring();\r\n                filename += suffix;\r\n                result.replace_filename(std::move(filename));\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n\r\n    // One method for converting open disposition to proper open disposition\r\n    // another method for obtaining the right flags\r\n    void SQLiteStorageBase::SetLastWriteTime()\r\n    {\r\n        MetadataTable::SetNamedValue(m_dbconn, s_MetadataValueName_LastWriteTime, Utility::GetCurrentUnixEpoch());\r\n    }\r\n\r\n    // Recording last write time based on MSDN documentation stating that time returns a POSIX epoch time and thus\r\n    // should be consistent across systems.\r\n    std::chrono::system_clock::time_point SQLiteStorageBase::GetLastWriteTime() const\r\n    {\r\n        int64_t lastWriteTime = MetadataTable::GetNamedValue<int64_t>(m_dbconn, s_MetadataValueName_LastWriteTime);\r\n        return Utility::ConvertUnixEpochToSystemClock(lastWriteTime);\r\n    }\r\n\r\n    std::string SQLiteStorageBase::GetDatabaseIdentifier() const\r\n    {\r\n        return MetadataTable::TryGetNamedValue<std::string>(m_dbconn, s_MetadataValueName_DatabaseIdentifier).value_or(std::string{});\r\n    }\r\n\r\n    void SQLiteStorageBase::RenameSQLiteDatabase(const std::filesystem::path& source, const std::filesystem::path& destination, bool overwrite)\r\n    {\r\n        auto fileSuffixes = { L\"\", L\"-journal\", L\"-wal\" };\r\n\r\n        THROW_WIN32_IF(ERROR_FILE_NOT_FOUND, !std::filesystem::exists(source));\r\n        THROW_WIN32_IF(ERROR_DIRECTORY, std::filesystem::is_directory(source));\r\n\r\n        if (overwrite)\r\n        {\r\n            for (const auto& suffix : fileSuffixes)\r\n            {\r\n                std::filesystem::path target = AddSuffix(destination, suffix);\r\n\r\n                if (std::filesystem::exists(target))\r\n                {\r\n                    std::filesystem::remove_all(target);\r\n                }\r\n            }\r\n        }\r\n\r\n        for (const auto& suffix : fileSuffixes)\r\n        {\r\n            std::filesystem::path target = AddSuffix(source, suffix);\r\n\r\n            if (std::filesystem::exists(target))\r\n            {\r\n                std::filesystem::rename(target, AddSuffix(destination, suffix));\r\n            }\r\n        }\r\n    }\r\n\r\n    SQLiteStorageBase::SQLiteStorageBase(const std::string& filePath, OpenDisposition disposition, Utility::ManagedFile&& file) :\r\n        m_indexFile(std::move(file))\r\n    {\r\n        AICLI_LOG(Repo, Info, << \"Opening database for \" << GetOpenDispositionString(disposition) << \" at '\" << filePath << \"'\");\r\n        switch (disposition)\r\n        {\r\n        case OpenDisposition::Read:\r\n            m_dbconn = SQLite::Connection::Create(filePath, SQLite::Connection::OpenDisposition::ReadOnly, SQLite::Connection::OpenFlags::None);\r\n            break;\r\n        case OpenDisposition::ReadWrite:\r\n            m_dbconn = SQLite::Connection::Create(filePath, SQLite::Connection::OpenDisposition::ReadWrite, SQLite::Connection::OpenFlags::None);\r\n            break;\r\n        case OpenDisposition::Immutable:\r\n        {\r\n            // Following the algorithm set forth at https://sqlite.org/uri.html [3.1] to convert to a URI path\r\n            // The execution order builds out the string so that it shouldn't require any moves (other than growing)\r\n            std::string target;\r\n            // Add an 'arbitrary' growth size to prevent the majority of needing to grow (adding 'file:/' and '?immutable=1')\r\n            target.reserve(filePath.size() + 20);\r\n\r\n            target += \"file:\";\r\n\r\n            bool wasLastCharSlash = false;\r\n\r\n            if (filePath.size() >= 2 && filePath[1] == ':' &&\r\n                ((filePath[0] >= 'a' && filePath[0] <= 'z') ||\r\n                    (filePath[0] >= 'A' && filePath[0] <= 'Z')))\r\n            {\r\n                target += '/';\r\n                wasLastCharSlash = true;\r\n            }\r\n\r\n            for (char c : filePath)\r\n            {\r\n                bool wasThisCharSlash = false;\r\n                switch (c)\r\n                {\r\n                case '?': target += \"%3f\"; break;\r\n                case '#': target += \"%23\"; break;\r\n                case '\\\\':\r\n                case '/':\r\n                {\r\n                    wasThisCharSlash = true;\r\n                    if (!wasLastCharSlash)\r\n                    {\r\n                        target += '/';\r\n                    }\r\n                    break;\r\n                }\r\n                default: target += c; break;\r\n                }\r\n\r\n                wasLastCharSlash = wasThisCharSlash;\r\n            }\r\n\r\n            target += \"?immutable=1\";\r\n            m_dbconn = SQLite::Connection::Create(filePath, SQLite::Connection::OpenDisposition::ReadOnly, SQLite::Connection::OpenFlags::Uri);\r\n            break;\r\n        }\r\n        default:\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n\r\n        m_version = Version::GetSchemaVersion(m_dbconn);\r\n    }\r\n\r\n    SQLiteStorageBase::SQLiteStorageBase(const std::string& target, const Version& version, size_t pageSize) :\r\n        m_dbconn(SQLite::Connection::Create(target, SQLite::Connection::OpenDisposition::Create))\r\n    {\r\n        m_version = version;\r\n        if (pageSize > 0)\r\n        {\r\n            m_dbconn.SetPageSize(pageSize);\r\n        }\r\n        MetadataTable::Create(m_dbconn);\r\n\r\n        // Write a new identifier for this database\r\n        GUID databaseIdentifier;\r\n        THROW_IF_FAILED(CoCreateGuid(&databaseIdentifier));\r\n        std::ostringstream stream;\r\n        stream << databaseIdentifier;\r\n        MetadataTable::SetNamedValue(m_dbconn, s_MetadataValueName_DatabaseIdentifier, stream.str());\r\n    }\r\n    \r\n    SQLiteStorageBase::SQLiteStorageBase(const std::string& target, SQLiteStorageBase& source) :\r\n        m_dbconn(SQLite::Connection::Create(target, SQLite::Connection::OpenDisposition::Create)),\r\n        m_version(source.m_version)\r\n    {\r\n        std::string mainDatabase = \"main\";\r\n        Backup backup = Backup::Create(m_dbconn, mainDatabase, source.m_dbconn, mainDatabase);\r\n        backup.Step();\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/SQLiteTempTable.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/SQLiteTempTable.h\"\r\n#include \"AppInstallerStrings.h\"\r\n\r\n\r\nnamespace AppInstaller::SQLite\r\n{\r\n    using namespace std::string_view_literals;\r\n\r\n    TempTable::TempTable()\r\n    {\r\n        GUID tempName;\r\n        THROW_IF_FAILED(CoCreateGuid(&tempName));\r\n\r\n        wchar_t guidAsString[MAX_PATH];\r\n        THROW_HR_IF(E_UNEXPECTED, StringFromGUID2(tempName, guidAsString, MAX_PATH) == 0);\r\n\r\n        m_name = Utility::ConvertToUTF8(guidAsString);\r\n    }\r\n\r\n    TempTable::~TempTable()\r\n    {\r\n        if (m_dropTableStatement)\r\n        {\r\n            m_dropTableStatement.Execute();\r\n        }\r\n    }\r\n\r\n    Builder::QualifiedTable TempTable::GetQualifiedName() const\r\n    {\r\n        return Builder::QualifiedTable(\"temp\"sv, m_name);\r\n    }\r\n\r\n    void TempTable::InitDropStatement(const Connection& connection)\r\n    {\r\n        Builder::StatementBuilder builder;\r\n        builder.DropTable(m_name);\r\n        \r\n        m_dropTableStatement = builder.Prepare(connection);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/SQLiteVersion.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/SQLiteVersion.h\"\r\n#include \"Public/winget/SQLiteMetadataTable.h\"\r\n\r\n#include <limits>\r\n\r\nnamespace AppInstaller::SQLite\r\n{\r\n    Version Version::GetSchemaVersion(Connection& connection)\r\n    {\r\n        int major = MetadataTable::GetNamedValue<int>(connection, s_MetadataValueName_MajorVersion);\r\n        int minor = MetadataTable::GetNamedValue<int>(connection, s_MetadataValueName_MinorVersion);\r\n\r\n        return { static_cast<uint32_t>(major), static_cast<uint32_t>(minor) };\r\n    }\r\n\r\n    void Version::SetSchemaVersion(Connection& connection) const\r\n    {\r\n        Savepoint savepoint = Savepoint::Create(connection, \"version_setschemaversion\");\r\n\r\n        MetadataTable::SetNamedValue(connection, s_MetadataValueName_MajorVersion, static_cast<int>(MajorVersion));\r\n        MetadataTable::SetNamedValue(connection, s_MetadataValueName_MinorVersion, static_cast<int>(MinorVersion));\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    std::ostream& operator<<(std::ostream& out, const Version& version)\r\n    {\r\n        if (version.IsLatest())\r\n        {\r\n            return out << \"Latest\";\r\n        }\r\n        else if (version.IsLatestForMajor(version.MajorVersion))\r\n        {\r\n            return out << version.MajorVersion << \".Latest\";\r\n        }\r\n        else\r\n        {\r\n            return out << version.MajorVersion << '.' << version.MinorVersion;\r\n        }\r\n    }\r\n\r\n    Version Version::Latest()\r\n    {\r\n        return { std::numeric_limits<uint32_t>::max(), std::numeric_limits<uint32_t>::max() };\r\n    }\r\n\r\n    Version Version::LatestForMajor(uint32_t majorVersion)\r\n    {\r\n        return { majorVersion, std::numeric_limits<uint32_t>::max() };\r\n    }\r\n\r\n    bool Version::IsLatest() const\r\n    {\r\n        return (MajorVersion == std::numeric_limits<uint32_t>::max() && MinorVersion == std::numeric_limits<uint32_t>::max());\r\n    }\r\n\r\n    bool Version::IsLatestForMajor(uint32_t majorVersion) const\r\n    {\r\n        return (MajorVersion == majorVersion && MinorVersion == std::numeric_limits<uint32_t>::max());\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/SQLiteWrapper.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/SQLiteWrapper.h\"\r\n#include \"Public/AppInstallerErrors.h\"\r\n#include \"Public/AppInstallerStrings.h\"\r\n#include \"ICU/SQLiteICU.h\"\r\n\r\n#include <wil/result_macros.h>\r\n\r\nusing namespace std::chrono_literals;\r\nusing namespace std::string_view_literals;\r\n\r\n// Enable this to have all Statement constructions output the associated query plan.\r\n#define WINGET_SQLITE_EXPLAIN_QUERY_PLAN_ENABLED 0\r\n\r\n#if WINGET_SQLITE_EXPLAIN_QUERY_PLAN_ENABLED\r\n#include <stack>\r\n#endif\r\n\r\n// Connection is used twice\r\n#define SQLITE_ERROR_MSG(_error_,_connection_) (_connection_ ? sqlite3_errmsg(_connection_) : sqlite3_errstr(_error_))\r\n\r\n#define THROW_SQLITE(_error_,_connection_) \\\r\n    do { \\\r\n        int _ts_sqliteReturnValue = (_error_); \\\r\n        sqlite3* _ts_sqliteConnection = (_connection_); \\\r\n        THROW_EXCEPTION_MSG(SQLiteException(_ts_sqliteReturnValue), \"%hs\", SQLITE_ERROR_MSG(_ts_sqliteReturnValue, _ts_sqliteConnection)); \\\r\n    } while (0,0)\r\n\r\n#define THROW_IF_SQLITE_FAILED(_statement_,_connection_) \\\r\n    do { \\\r\n        int _tisf_sqliteReturnValue = (_statement_); \\\r\n        if (_tisf_sqliteReturnValue != SQLITE_OK) \\\r\n        { \\\r\n            THROW_SQLITE(_tisf_sqliteReturnValue,_connection_); \\\r\n        } \\\r\n    } while (0,0)\r\n\r\nnamespace AppInstaller::SQLite\r\n{\r\n    std::string_view RowIDName = \"rowid\"sv;\r\n\r\n    namespace\r\n    {\r\n        size_t GetNextConnectionId()\r\n        {\r\n            static std::atomic_size_t connectionId(0);\r\n            return ++connectionId;\r\n        }\r\n\r\n        size_t GetNextStatementId()\r\n        {\r\n            static std::atomic_size_t statementId(0);\r\n            return ++statementId;\r\n        }\r\n    }\r\n\r\n    namespace details\r\n    {\r\n        void ParameterSpecificsImpl<nullptr_t>::Bind(sqlite3_stmt* stmt, int index, nullptr_t)\r\n        {\r\n            THROW_IF_SQLITE_FAILED(sqlite3_bind_null(stmt, index), sqlite3_db_handle(stmt));\r\n        }\r\n\r\n        void ThrowIfContainsEmbeddedNullCharacter(std::string_view v)\r\n        {\r\n            THROW_HR_IF(APPINSTALLER_CLI_ERROR_BIND_WITH_EMBEDDED_NULL, v.find('\\0') != std::string_view::npos);\r\n        }\r\n\r\n        void ParameterSpecificsImpl<std::string>::Bind(sqlite3_stmt* stmt, int index, const std::string& v)\r\n        {\r\n            ThrowIfContainsEmbeddedNullCharacter(v);\r\n            THROW_IF_SQLITE_FAILED(sqlite3_bind_text64(stmt, index, v.c_str(), v.size(), SQLITE_TRANSIENT, SQLITE_UTF8), sqlite3_db_handle(stmt));\r\n        }\r\n\r\n        std::string ParameterSpecificsImpl<std::string>::GetColumn(sqlite3_stmt* stmt, int column)\r\n        {\r\n            return reinterpret_cast<const char*>(sqlite3_column_text(stmt, column));\r\n        }\r\n\r\n        void ParameterSpecificsImpl<std::string_view>::Bind(sqlite3_stmt* stmt, int index, std::string_view v)\r\n        {\r\n            if (v.empty())\r\n            {\r\n                // An empty string_view can have it's data member return nullptr, which effectively binds a null value.\r\n                // We don't want that, so instead bind an empty string, which will have a non-null data pointer.\r\n                ParameterSpecificsImpl<std::string>::Bind(stmt, index, {});\r\n            }\r\n            else\r\n            {\r\n                ThrowIfContainsEmbeddedNullCharacter(v);\r\n                THROW_IF_SQLITE_FAILED(sqlite3_bind_text64(stmt, index, v.data(), v.size(), SQLITE_TRANSIENT, SQLITE_UTF8), sqlite3_db_handle(stmt));\r\n            }\r\n        }\r\n\r\n        void ParameterSpecificsImpl<int>::Bind(sqlite3_stmt* stmt, int index, int v)\r\n        {\r\n            THROW_IF_SQLITE_FAILED(sqlite3_bind_int(stmt, index, v), sqlite3_db_handle(stmt));\r\n        }\r\n\r\n        int ParameterSpecificsImpl<int>::GetColumn(sqlite3_stmt* stmt, int column)\r\n        {\r\n            return sqlite3_column_int(stmt, column);\r\n        }\r\n\r\n        void ParameterSpecificsImpl<int64_t>::Bind(sqlite3_stmt* stmt, int index, int64_t v)\r\n        {\r\n            THROW_IF_SQLITE_FAILED(sqlite3_bind_int64(stmt, index, v), sqlite3_db_handle(stmt));\r\n        }\r\n\r\n        int64_t ParameterSpecificsImpl<int64_t>::GetColumn(sqlite3_stmt* stmt, int column)\r\n        {\r\n            return sqlite3_column_int64(stmt, column);\r\n        }\r\n\r\n        void ParameterSpecificsImpl<bool>::Bind(sqlite3_stmt* stmt, int index, bool v)\r\n        {\r\n            THROW_IF_SQLITE_FAILED(sqlite3_bind_int(stmt, index, (v ? 1 : 0)), sqlite3_db_handle(stmt));\r\n        }\r\n\r\n        bool ParameterSpecificsImpl<bool>::GetColumn(sqlite3_stmt* stmt, int column)\r\n        {\r\n            return (sqlite3_column_int(stmt, column) != 0);\r\n        }\r\n\r\n        std::string ParameterSpecificsImpl<blob_t>::ToLog(const blob_t& v)\r\n        {\r\n            std::ostringstream strstr;\r\n            strstr << \"blob[\" << v.size() << \"]\";\r\n            return strstr.str();\r\n        }\r\n\r\n        void ParameterSpecificsImpl<blob_t>::Bind(sqlite3_stmt* stmt, int index, const blob_t& v)\r\n        {\r\n            THROW_IF_SQLITE_FAILED(sqlite3_bind_blob64(stmt, index, v.data(), v.size(), SQLITE_TRANSIENT), sqlite3_db_handle(stmt));\r\n        }\r\n\r\n        blob_t ParameterSpecificsImpl<blob_t>::GetColumn(sqlite3_stmt* stmt, int column)\r\n        {\r\n            const blob_t::value_type* blobPtr = reinterpret_cast<const blob_t::value_type *>(sqlite3_column_blob(stmt, column));\r\n            if (blobPtr)\r\n            {\r\n                int blobBytes = sqlite3_column_bytes(stmt, column);\r\n                return blob_t{ blobPtr, blobPtr + blobBytes };\r\n            }\r\n            else\r\n            {\r\n                return {};\r\n            }\r\n        }\r\n\r\n        std::string ParameterSpecificsImpl<GUID>::ToLog(const GUID& v)\r\n        {\r\n            std::ostringstream strstr;\r\n            strstr << v;\r\n            return strstr.str();\r\n        }\r\n\r\n        void ParameterSpecificsImpl<GUID>::Bind(sqlite3_stmt* stmt, int index, const GUID& v)\r\n        {\r\n            static_assert(sizeof(v) == 16);\r\n            THROW_IF_SQLITE_FAILED(sqlite3_bind_blob64(stmt, index, &v, sizeof(v), SQLITE_TRANSIENT), sqlite3_db_handle(stmt));\r\n        }\r\n\r\n        GUID ParameterSpecificsImpl<GUID>::GetColumn(sqlite3_stmt* stmt, int column)\r\n        {\r\n            GUID result{};\r\n\r\n            const void* blobPtr = sqlite3_column_blob(stmt, column);\r\n            if (blobPtr)\r\n            {\r\n                result = *reinterpret_cast<const GUID*>(blobPtr);\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        void SharedConnection::Disable()\r\n        {\r\n            m_active = false;\r\n        }\r\n\r\n        sqlite3* SharedConnection::Get() const\r\n        {\r\n            THROW_HR_IF(APPINSTALLER_CLI_ERROR_SQLITE_CONNECTION_TERMINATED, !m_active.load());\r\n            return m_dbconn.get();\r\n        }\r\n\r\n        sqlite3** SharedConnection::GetPtr()\r\n        {\r\n            return &m_dbconn;\r\n        }\r\n    }\r\n\r\n    Connection::Connection(const std::string& target, OpenDisposition disposition, OpenFlags flags)\r\n    {\r\n        m_dbconn = std::make_shared<details::SharedConnection>();\r\n        m_id = GetNextConnectionId();\r\n        AICLI_LOG(SQL, Info, << \"Opening SQLite connection #\" << m_id << \": '\" << target << \"' [\" << std::hex << static_cast<int>(disposition) << \", \" << std::hex << static_cast<int>(flags) << \"]\");\r\n        // Always force connection serialization until we determine that there are situations where it is not needed\r\n        int resultingFlags = static_cast<int>(disposition) | static_cast<int>(flags) | SQLITE_OPEN_FULLMUTEX;\r\n        THROW_IF_SQLITE_FAILED(sqlite3_open_v2(target.c_str(), m_dbconn->GetPtr(), resultingFlags, nullptr), nullptr);\r\n    }\r\n\r\n    Connection Connection::Create(const std::string& target, OpenDisposition disposition, OpenFlags flags)\r\n    {\r\n        Connection result{ target, disposition, flags };\r\n\r\n        THROW_IF_SQLITE_FAILED(sqlite3_extended_result_codes(result.m_dbconn->Get(), 1), result.m_dbconn->Get());\r\n        result.SetBusyTimeout(250ms);\r\n\r\n        return result;\r\n    }\r\n\r\n    void Connection::EnableICU()\r\n    {\r\n        AICLI_LOG(SQL, Verbose, << \"Enabling ICU\");\r\n        THROW_IF_SQLITE_FAILED(sqlite3IcuInit(m_dbconn->Get()), m_dbconn->Get());\r\n    }\r\n\r\n    rowid_t Connection::GetLastInsertRowID()\r\n    {\r\n        return sqlite3_last_insert_rowid(m_dbconn->Get());\r\n    }\r\n\r\n    int Connection::GetChanges() const\r\n    {\r\n        return sqlite3_changes(m_dbconn->Get());\r\n    }\r\n\r\n    size_t Connection::GetID() const\r\n    {\r\n        return m_id;\r\n    }\r\n\r\n    void Connection::SetBusyTimeout(std::chrono::milliseconds timeout)\r\n    {\r\n        THROW_IF_SQLITE_FAILED(sqlite3_busy_timeout(m_dbconn->Get(), static_cast<int>(timeout.count())), m_dbconn->Get());\r\n    }\r\n\r\n    bool Connection::SetJournalMode(std::string_view mode)\r\n    {\r\n        using namespace AppInstaller::Utility;\r\n\r\n        std::ostringstream stream;\r\n        stream << \"PRAGMA journal_mode=\" << mode;\r\n\r\n        Statement setJournalMode = Statement::Create(*this, stream.str());\r\n        THROW_HR_IF(E_UNEXPECTED, !setJournalMode.Step());\r\n        return ToLower(setJournalMode.GetColumn<std::string>(0)) == ToLower(mode);\r\n    }\r\n\r\n    void Connection::SetPageSize(size_t pageSize)\r\n    {\r\n        std::ostringstream stream;\r\n        stream << \"PRAGMA page_size=\" << pageSize;\r\n\r\n        Statement setPageSize = Statement::Create(*this, stream.str());\r\n        setPageSize.Step();\r\n    }\r\n\r\n    std::shared_ptr<details::SharedConnection> Connection::GetSharedConnection() const\r\n    {\r\n        return m_dbconn;\r\n    }\r\n\r\n    Statement::Statement(const Connection& connection, std::string_view sql)\r\n    {\r\n        m_dbconn = connection.GetSharedConnection();\r\n        m_connectionId = connection.GetID();\r\n        m_id = GetNextStatementId();\r\n        AICLI_LOG(SQL, Verbose, << \"Preparing statement #\" << m_connectionId << '-' << m_id << \": \" << sql);\r\n        // SQL string size should include the null terminator (https://www.sqlite.org/c3ref/prepare.html)\r\n        assert(sql.data()[sql.size()] == '\\0');\r\n        THROW_IF_SQLITE_FAILED(sqlite3_prepare_v2(connection, sql.data(), static_cast<int>(sql.size() + 1), &m_stmt, nullptr), connection);\r\n    }\r\n\r\n#if WINGET_SQLITE_EXPLAIN_QUERY_PLAN_ENABLED\r\n#define WINGET_SQLITE_EXPLAIN_QUERY_PLAN(_connection_,_sql_) \\\r\n    std::string _explainStatementSQL_ = \"EXPLAIN QUERY PLAN \"; \\\r\n    _explainStatementSQL_.append(_sql_); \\\r\n    try { \\\r\n        Statement _explainStatement_(_connection_,_explainStatementSQL_); \\\r\n        LogExplainQueryPlanResult(_sql_, _explainStatement_); \\\r\n    } catch(...) {}\r\n\r\n    void LogExplainQueryPlanResult(std::string_view sql, Statement& plan)\r\n    {\r\n        bool outputHeader = true;\r\n        std::stack<int> parents;\r\n\r\n        while (plan.Step())\r\n        {\r\n            if (outputHeader)\r\n            {\r\n                AICLI_LOG(SQL, Info, << \"Query plan for: \" << sql);\r\n                outputHeader = false;\r\n            }\r\n\r\n            int id = plan.GetColumn<int>(0);\r\n            int parent = plan.GetColumn<int>(1);\r\n\r\n            while (!parents.empty() && parents.top() != parent)\r\n            {\r\n                parents.pop();\r\n            }\r\n\r\n            AICLI_LOG(SQL, Info, << \"|-\" << std::string(parents.size() * 2, '-') << ' ' << plan.GetColumn<std::string>(3));\r\n\r\n            parents.push(id);\r\n        }\r\n    }\r\n#else\r\n#define WINGET_SQLITE_EXPLAIN_QUERY_PLAN(_connection_,_sql_)\r\n#endif\r\n\r\n    Statement Statement::Create(const Connection& connection, const std::string& sql)\r\n    {\r\n        WINGET_SQLITE_EXPLAIN_QUERY_PLAN(connection, sql);\r\n        return { connection, { sql.c_str(), sql.size() } };\r\n    }\r\n\r\n    Statement Statement::Create(const Connection& connection, std::string_view sql)\r\n    {\r\n        WINGET_SQLITE_EXPLAIN_QUERY_PLAN(connection, sql);\r\n        // We need the statement to be null terminated, and the only way to guarantee that with a string_view is to construct a string copy.\r\n        return Create(connection, std::string(sql));\r\n    }\r\n\r\n    Statement Statement::Create(const Connection& connection, char const* const sql)\r\n    {\r\n        WINGET_SQLITE_EXPLAIN_QUERY_PLAN(connection, sql);\r\n        return { connection, sql };\r\n    }\r\n\r\n    bool Statement::Step(bool closeConnectionOnError)\r\n    {\r\n        AICLI_LOG(SQL, Verbose, << \"Stepping statement #\" << m_connectionId << '-' << m_id);\r\n        int result = sqlite3_step(m_stmt.get());\r\n\r\n        if (result == SQLITE_ROW)\r\n        {\r\n            AICLI_LOG(SQL, Verbose, << \"Statement #\" << m_connectionId << '-' << m_id << \" has data\");\r\n            m_state = State::HasRow;\r\n            return true;\r\n        }\r\n        else if (result == SQLITE_DONE)\r\n        {\r\n            AICLI_LOG(SQL, Verbose, << \"Statement #\" << m_connectionId << '-' << m_id << \" has completed\");\r\n            m_state = State::Completed;\r\n            return false;\r\n        }\r\n        else\r\n        {\r\n            m_state = State::Error;\r\n\r\n            if (closeConnectionOnError)\r\n            {\r\n                m_dbconn->Disable();\r\n            }\r\n\r\n            THROW_SQLITE(result, sqlite3_db_handle(m_stmt.get()));\r\n        }\r\n    }\r\n\r\n    void Statement::Execute(bool closeConnectionOnError)\r\n    {\r\n        THROW_HR_IF(E_UNEXPECTED, Step(closeConnectionOnError));\r\n    }\r\n\r\n    bool Statement::GetColumnIsNull(int column)\r\n    {\r\n        int type = sqlite3_column_type(m_stmt.get(), column);\r\n        return type == SQLITE_NULL;\r\n    }\r\n\r\n    void Statement::Reset()\r\n    {\r\n        AICLI_LOG(SQL, Verbose, << \"Reset statement #\" << m_connectionId << '-' << m_id);\r\n        // Ignore return value from reset, as if it is an error, it was the error from the last call to step.\r\n        sqlite3_reset(m_stmt.get());\r\n        m_state = State::Prepared;\r\n    }\r\n\r\n    Transaction::Transaction() : m_inProgress(false)\r\n    {}\r\n\r\n    Transaction::Transaction(Connection& connection, std::string&& name, bool immediateWrite) :\r\n        m_name(std::move(name))\r\n    {\r\n        using namespace std::string_literals;\r\n\r\n        Statement begin = Statement::Create(connection, \"BEGIN \"s + (immediateWrite ? \"IMMEDIATE\" : \"DEFERRED\"));\r\n        m_rollback = Statement::Create(connection, \"ROLLBACK\");\r\n        m_commit = Statement::Create(connection, \"COMMIT\");\r\n\r\n        AICLI_LOG(SQL, Verbose, << \"Begin transaction: \" << m_name);\r\n        begin.Step();\r\n    }\r\n\r\n    Transaction Transaction::Create(Connection& connection, std::string name, bool immediateWrite)\r\n    {\r\n        return { connection, std::move(name), immediateWrite };\r\n    }\r\n\r\n    Transaction::~Transaction()\r\n    {\r\n        // Prevent a termination by not throwing on errors here\r\n        Rollback(false);\r\n    }\r\n\r\n    void Transaction::Rollback(bool throwOnError)\r\n    {\r\n        if (m_inProgress)\r\n        {\r\n            // Only try rollback once\r\n            m_inProgress = false;\r\n\r\n            try\r\n            {\r\n                AICLI_LOG(SQL, Verbose, << \"Roll back transaction: \" << m_name);\r\n                m_rollback.Step(true);\r\n            }\r\n            catch (...)\r\n            {\r\n                if (throwOnError)\r\n                {\r\n                    throw;\r\n                }\r\n\r\n                LOG_CAUGHT_EXCEPTION();\r\n            }\r\n        }\r\n    }\r\n\r\n    void Transaction::Commit()\r\n    {\r\n        if (m_inProgress)\r\n        {\r\n            AICLI_LOG(SQL, Verbose, << \"Commit transaction: \" << m_name);\r\n            m_commit.Step();\r\n            m_inProgress = false;\r\n        }\r\n    }\r\n\r\n    Savepoint::Savepoint() : m_inProgress(false)\r\n    {}\r\n\r\n    Savepoint::Savepoint(Connection& connection, std::string&& name) :\r\n        m_name(std::move(name))\r\n    {\r\n        using namespace std::string_literals;\r\n\r\n        Statement begin = Statement::Create(connection, \"SAVEPOINT [\"s + m_name + \"]\");\r\n        m_rollbackTo = Statement::Create(connection, \"ROLLBACK TO [\"s + m_name + \"]\");\r\n        m_release = Statement::Create(connection, \"RELEASE [\"s + m_name + \"]\");\r\n\r\n        AICLI_LOG(SQL, Verbose, << \"Begin savepoint: \" << m_name);\r\n        begin.Step();\r\n    }\r\n\r\n    Savepoint Savepoint::Create(Connection& connection, std::string name)\r\n    {\r\n        return { connection, std::move(name) };\r\n    }\r\n\r\n    Savepoint::~Savepoint()\r\n    {\r\n        // Prevent a termination by not throwing on errors here\r\n        Rollback(false);\r\n    }\r\n\r\n    void Savepoint::Rollback(bool throwOnError)\r\n    {\r\n        if (m_inProgress)\r\n        {\r\n            // Only try rollback once\r\n            m_inProgress = false;\r\n\r\n            try\r\n            {\r\n                AICLI_LOG(SQL, Verbose, << \"Roll back savepoint: \" << m_name);\r\n                m_rollbackTo.Step(true);\r\n                // 'ROLLBACK TO' *DOES NOT* remove the savepoint from the transaction stack.\r\n                // In order to remove it, we must RELEASE. Since we just invoked a ROLLBACK TO\r\n                // this should have the effect of 'committing' nothing.\r\n                m_release.Step(true);\r\n            }\r\n            catch (...)\r\n            {\r\n                if (throwOnError)\r\n                {\r\n                    throw;\r\n                }\r\n\r\n                LOG_CAUGHT_EXCEPTION();\r\n            }\r\n        }\r\n    }\r\n\r\n    void Savepoint::Commit()\r\n    {\r\n        if (m_inProgress)\r\n        {\r\n            AICLI_LOG(SQL, Verbose, << \"Commit savepoint: \" << m_name);\r\n            m_release.Step();\r\n            m_inProgress = false;\r\n        }\r\n    }\r\n\r\n    Backup::Backup(Connection& destination, const std::string& destinationName, Connection& source, const std::string& sourceName)\r\n    {\r\n        m_backup.reset(sqlite3_backup_init(destination, destinationName.c_str(), source, sourceName.c_str()));\r\n\r\n        if (!m_backup)\r\n        {\r\n            THROW_SQLITE(sqlite3_errcode(destination), destination);\r\n        }\r\n    }\r\n\r\n    Backup Backup::Create(Connection& destination, const std::string& destinationName, Connection& source, const std::string& sourceName)\r\n    {\r\n        return { destination, destinationName, source, sourceName };\r\n    }\r\n\r\n    bool Backup::Step(int pages)\r\n    {\r\n        int stepResult = sqlite3_backup_step(m_backup.get(), pages);\r\n\r\n        if (stepResult == SQLITE_OK)\r\n        {\r\n            // A negative number of pages should finish the operation\r\n            if (pages < 0)\r\n            {\r\n                THROW_HR(E_UNEXPECTED);\r\n            }\r\n\r\n            // Success but not done\r\n            return false;\r\n        }\r\n        else if (stepResult == SQLITE_DONE)\r\n        {\r\n            return true;\r\n        }\r\n        else\r\n        {\r\n            THROW_SQLITE(stepResult, nullptr);\r\n        }\r\n    }\r\n\r\n    std::string_view EscapeCharForLike = \"'\"sv;\r\n\r\n    std::string EscapeStringForLike(std::string_view value)\r\n    {\r\n        constexpr char singleChar = '_';\r\n        constexpr char multiChar = '%';\r\n        char escapeChar = EscapeCharForLike[0];\r\n\r\n        std::string result;\r\n        result.reserve(value.length());\r\n\r\n        for (char c : value)\r\n        {\r\n            if (c == singleChar || c == multiChar || c == escapeChar)\r\n            {\r\n                result.append(1, escapeChar);\r\n            }\r\n            result.append(1, c);\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Security.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"winget/Security.h\"\r\n#include \"AppInstallerLogging.h\"\r\n#include \"AppInstallerLanguageUtilities.h\"\r\n\r\nnamespace AppInstaller::Security\r\n{\r\n    namespace\r\n    {\r\n        bool IsSameAuthority(const SID_IDENTIFIER_AUTHORITY& a, const SID_IDENTIFIER_AUTHORITY& b)\r\n        {\r\n            for (size_t i = 0; i < ARRAYSIZE(a.Value); ++i)\r\n            {\r\n                if (a.Value[i] != b.Value[i])\r\n                {\r\n                    return false;\r\n                }\r\n            }\r\n\r\n            return true;\r\n        }\r\n\r\n        // Helper to impersonate the COM or RPC caller.\r\n        struct ImpersonateCOMorRPCCaller\r\n        {\r\n            static ImpersonateCOMorRPCCaller BeginImpersonation()\r\n            {\r\n                return {};\r\n            }\r\n\r\n            ~ImpersonateCOMorRPCCaller()\r\n            {\r\n                if (m_serverSecurity)\r\n                {\r\n                    FAIL_FAST_IF_FAILED(m_serverSecurity->RevertToSelf());\r\n                }\r\n                else\r\n                {\r\n                    FAIL_FAST_IF(RpcRevertToSelf() != RPC_S_OK);\r\n                }\r\n            }\r\n\r\n        private:\r\n            ImpersonateCOMorRPCCaller()\r\n            {\r\n                if (SUCCEEDED_LOG(CoGetCallContext(IID_IServerSecurity, m_serverSecurity.put_void())))\r\n                {\r\n                    THROW_IF_FAILED(m_serverSecurity->ImpersonateClient());\r\n                }\r\n                else\r\n                {\r\n                    RPC_STATUS status = RpcImpersonateClient(nullptr);\r\n                    THROW_HR_IF(MAKE_HRESULT(SEVERITY_ERROR, FACILITY_RPC, status), status != RPC_S_OK);\r\n                }\r\n            }\r\n\r\n            wil::com_ptr<IServerSecurity> m_serverSecurity;\r\n        };\r\n    }\r\n\r\n    IntegrityLevel GetEffectiveIntegrityLevel()\r\n    {\r\n        auto currentIntegrityLevel = wil::get_token_information<TOKEN_MANDATORY_LABEL>();\r\n        PSID sid = currentIntegrityLevel->Label.Sid;\r\n        THROW_HR_IF(CO_E_INVALIDSID, !IsValidSid(sid));\r\n\r\n        auto identifierAuthority = GetSidIdentifierAuthority(sid);\r\n        THROW_HR_IF(E_UNEXPECTED, !IsSameAuthority(*identifierAuthority, SECURITY_MANDATORY_LABEL_AUTHORITY));\r\n\r\n        PUCHAR subAuthorityCount = GetSidSubAuthorityCount(sid);\r\n        THROW_HR_IF(E_UNEXPECTED, *subAuthorityCount != 1);\r\n\r\n        PDWORD subAuthority = GetSidSubAuthority(sid, 0);\r\n\r\n        switch (*subAuthority)\r\n        {\r\n        case SECURITY_MANDATORY_UNTRUSTED_RID: return IntegrityLevel::Untrusted;\r\n        case SECURITY_MANDATORY_LOW_RID: return IntegrityLevel::Low;\r\n        case SECURITY_MANDATORY_MEDIUM_RID: return IntegrityLevel::Medium;\r\n        case SECURITY_MANDATORY_HIGH_RID: return IntegrityLevel::High;\r\n        case SECURITY_MANDATORY_SYSTEM_RID: return IntegrityLevel::System;\r\n        case SECURITY_MANDATORY_PROTECTED_PROCESS_RID: return IntegrityLevel::ProtectedProcess;\r\n        }\r\n\r\n        THROW_HR(E_UNEXPECTED);\r\n    }\r\n\r\n    bool IsCOMCallerSameUserAndIntegrityLevel()\r\n    {\r\n        auto serverUser = wil::get_token_information<TOKEN_USER>();\r\n        IntegrityLevel serverIntegrityLevel = GetEffectiveIntegrityLevel();\r\n\r\n        auto impersonation = ImpersonateCOMorRPCCaller::BeginImpersonation();\r\n\r\n        auto callingUser = wil::get_token_information<TOKEN_USER>();\r\n        IntegrityLevel callingIntegrityLevel = GetEffectiveIntegrityLevel();\r\n\r\n        if (!EqualSid(serverUser->User.Sid, callingUser->User.Sid))\r\n        {\r\n            AICLI_LOG(Core, Crit, << \"Attempt to access by another user: \" << ToString(callingUser->User.Sid));\r\n            return false;\r\n        }\r\n\r\n        if (ToIntegral(callingIntegrityLevel) < ToIntegral(serverIntegrityLevel))\r\n        {\r\n            AICLI_LOG(Core, Crit, << \"Attempt to access by a lower integrity process: \" << callingIntegrityLevel << \" < \" << serverIntegrityLevel);\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    bool IsCOMCallerIntegrityLevelAtLeast(IntegrityLevel minimumLevel)\r\n    {\r\n        auto impersonation = ImpersonateCOMorRPCCaller::BeginImpersonation();\r\n        return IsCurrentIntegrityLevelAtLeast(minimumLevel);\r\n    }\r\n\r\n    bool IsCurrentIntegrityLevelAtLeast(IntegrityLevel minimumLevel)\r\n    {\r\n        IntegrityLevel callingIntegrityLevel = GetEffectiveIntegrityLevel();\r\n\r\n        if (ToIntegral(callingIntegrityLevel) < ToIntegral(minimumLevel))\r\n        {\r\n            AICLI_LOG(Core, Crit, << \"Attempt to access by a lower integrity process than required: \" << callingIntegrityLevel << \" < \" << minimumLevel);\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    std::string ToString(PSID sid)\r\n    {\r\n        wil::unique_hlocal_ansistring result;\r\n        THROW_IF_WIN32_BOOL_FALSE(ConvertSidToStringSidA(sid, &result));\r\n        return result.get();\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/SharedThreadGlobals.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/winget/SharedThreadGlobals.h\"\r\n\r\nnamespace AppInstaller::ThreadLocalStorage\r\n{\r\n    using namespace AppInstaller::Logging;\r\n\r\n    static ThreadGlobals* SetOrGetThreadGlobals(bool setThreadGlobals, ThreadGlobals* pThreadGlobals = nullptr)\r\n    {\r\n        thread_local AppInstaller::ThreadLocalStorage::ThreadGlobals* t_pThreadGlobals = nullptr;\r\n\r\n        if (setThreadGlobals)\r\n        {\r\n            AppInstaller::ThreadLocalStorage::ThreadGlobals* previous_pThreadGlobals = t_pThreadGlobals;\r\n            t_pThreadGlobals = pThreadGlobals;\r\n            return previous_pThreadGlobals;\r\n        }\r\n\r\n        return t_pThreadGlobals;\r\n    }\r\n\r\n    std::unique_ptr<PreviousThreadGlobals> ThreadGlobals::SetForCurrentThread()\r\n    {\r\n        return std::make_unique<PreviousThreadGlobals>(SetOrGetThreadGlobals(true, this));\r\n    }\r\n\r\n    ThreadGlobals* ThreadGlobals::GetForCurrentThread()\r\n    {\r\n        return SetOrGetThreadGlobals(false);\r\n    }\r\n\r\n    PreviousThreadGlobals::PreviousThreadGlobals(ThreadGlobals* previous) : m_previous(previous)\r\n    {\r\n        m_threadId = GetCurrentThreadId();\r\n    }\r\n\r\n    PreviousThreadGlobals::~PreviousThreadGlobals()\r\n    {\r\n        // Not remaining on the same thread is a serious issue that must be resolved\r\n        FAIL_FAST_IF(GetCurrentThreadId() != m_threadId);\r\n        std::ignore = SetOrGetThreadGlobals(true, m_previous);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Versions.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/AppInstallerVersions.h\"\r\n#include \"Public/AppInstallerStrings.h\"\r\n\r\nnamespace AppInstaller::Utility\r\n{\r\n    using namespace std::string_view_literals;\r\n\r\n    static constexpr std::string_view s_Digit_Characters = \"0123456789\"sv;\r\n    static constexpr std::string_view s_Version_Part_Latest = \"Latest\"sv;\r\n    static constexpr std::string_view s_Version_Part_Unknown = \"Unknown\"sv;\r\n\r\n    static constexpr std::string_view s_Approximate_Less_Than = \"< \"sv;\r\n    static constexpr std::string_view s_Approximate_Greater_Than = \"> \"sv;\r\n\r\n    Version::Version(std::string&& version, std::string_view splitChars)\r\n    {\r\n        Assign(std::move(version), splitChars);\r\n    }\r\n\r\n    RawVersion::RawVersion(std::string version, std::string_view splitChars)\r\n    {\r\n        m_trimPrefix = false;\r\n        Assign(std::move(version), splitChars);\r\n    }\r\n\r\n    Version::Version(Version baseVersion, ApproximateComparator approximateComparator) : Version(std::move(baseVersion))\r\n    {\r\n        if (approximateComparator == ApproximateComparator::None)\r\n        {\r\n            return;\r\n        }\r\n\r\n        THROW_HR_IF(E_INVALIDARG, this->IsApproximate() || this->IsUnknown());\r\n\r\n        m_approximateComparator = approximateComparator;\r\n        if (approximateComparator == ApproximateComparator::LessThan)\r\n        {\r\n            m_version = std::string{ s_Approximate_Less_Than } + m_version;\r\n        }\r\n        else if (approximateComparator == ApproximateComparator::GreaterThan)\r\n        {\r\n            m_version = std::string{ s_Approximate_Greater_Than } + m_version;\r\n        }\r\n    }\r\n\r\n    void Version::Assign(std::string version, std::string_view splitChars)\r\n    {\r\n        m_version = std::move(Utility::Trim(version));\r\n\r\n        // Process approximate comparator if applicable\r\n        std::string baseVersion = m_version;\r\n        if (CaseInsensitiveStartsWith(m_version, s_Approximate_Less_Than))\r\n        {\r\n            m_approximateComparator = ApproximateComparator::LessThan;\r\n            baseVersion = m_version.substr(s_Approximate_Less_Than.length(), m_version.length() - s_Approximate_Less_Than.length());\r\n        }\r\n        else if (CaseInsensitiveStartsWith(m_version, s_Approximate_Greater_Than))\r\n        {\r\n            m_approximateComparator = ApproximateComparator::GreaterThan;\r\n            baseVersion = m_version.substr(s_Approximate_Greater_Than.length(), m_version.length() - s_Approximate_Greater_Than.length());\r\n        }\r\n\r\n        // If there is a digit before the split character, or no split characters exist, trim off all leading non-digit characters\r\n        size_t digitPos = baseVersion.find_first_of(s_Digit_Characters);\r\n        size_t splitPos = baseVersion.find_first_of(splitChars);\r\n        if (m_trimPrefix && digitPos != std::string::npos && (splitPos == std::string::npos || digitPos < splitPos))\r\n        {\r\n            baseVersion.erase(0, digitPos);\r\n        }\r\n\r\n        // Then parse the base version\r\n        size_t pos = 0;\r\n\r\n        while (pos < baseVersion.length())\r\n        {\r\n            size_t newPos = baseVersion.find_first_of(splitChars, pos);\r\n\r\n            size_t length = (newPos == std::string::npos ? baseVersion.length() : newPos) - pos;\r\n            m_parts.emplace_back(baseVersion.substr(pos, length));\r\n\r\n            pos += length + 1;\r\n        }\r\n\r\n        // Trim version parts\r\n        Trim();\r\n\r\n        THROW_HR_IF(E_INVALIDARG, m_approximateComparator != ApproximateComparator::None && IsBaseVersionUnknown());\r\n    }\r\n\r\n    void Version::Trim()\r\n    {\r\n        while (!m_parts.empty())\r\n        {\r\n            const Part& part = m_parts.back();\r\n            if (part.Integer == 0 && part.Other.empty())\r\n            {\r\n                m_parts.pop_back();\r\n            }\r\n            else\r\n            {\r\n                return;\r\n            }\r\n        }\r\n    }\r\n\r\n    bool Version::operator<(const Version& other) const\r\n    {\r\n        // Sort Latest higher than any other values\r\n        bool thisIsLatest = IsBaseVersionLatest();\r\n        bool otherIsLatest = other.IsBaseVersionLatest();\r\n\r\n        if (thisIsLatest && otherIsLatest)\r\n        {\r\n            return ApproximateCompareLessThan(other);\r\n        }\r\n        else if (thisIsLatest || otherIsLatest)\r\n        {\r\n            // If only one is latest, this can only be less than if the other is and this is not.\r\n            return (otherIsLatest && !thisIsLatest);\r\n        }\r\n\r\n        // Sort Unknown lower than any known values\r\n        bool thisIsUnknown = IsBaseVersionUnknown();\r\n        bool otherIsUnknown = other.IsBaseVersionUnknown();\r\n\r\n        if (thisIsUnknown && otherIsUnknown)\r\n        {\r\n            // This code path should always return false as we disable approximate version for Unknown for now\r\n            return ApproximateCompareLessThan(other);\r\n        }\r\n        else if (thisIsUnknown || otherIsUnknown)\r\n        {\r\n            // If at least one is unknown, this can only be less than if it is and the other is not.\r\n            return (thisIsUnknown && !otherIsUnknown);\r\n        }\r\n\r\n        const Part emptyPart{};\r\n        for (size_t i = 0; i < std::max(m_parts.size(), other.m_parts.size()); ++i)\r\n        {\r\n            // Whichever version is shorter, we need to pad it with empty parts\r\n            const Part& partA = (i >= m_parts.size()) ? emptyPart : m_parts[i];\r\n            const Part& partB = (i >= other.m_parts.size()) ? emptyPart : other.m_parts[i];\r\n\r\n            if (partA < partB)\r\n            {\r\n                return true;\r\n            }\r\n            else if (partB < partA)\r\n            {\r\n                return false;\r\n            }\r\n            // else parts are equal, so continue to next part\r\n        }\r\n\r\n        // All parts were compared and found to be equal\r\n        return ApproximateCompareLessThan(other);\r\n    }\r\n\r\n    bool Version::operator>(const Version& other) const\r\n    {\r\n        return other < *this;\r\n    }\r\n\r\n    bool Version::operator<=(const Version& other) const\r\n    {\r\n        return !(*this > other);\r\n    }\r\n\r\n    bool Version::operator>=(const Version& other) const\r\n    {\r\n        return !(*this < other);\r\n    }\r\n\r\n    bool Version::operator==(const Version& other) const\r\n    {\r\n        if (m_approximateComparator != other.m_approximateComparator)\r\n        {\r\n            return false;\r\n        }\r\n\r\n        if ((IsBaseVersionLatest() && other.IsBaseVersionLatest()) ||\r\n            (IsBaseVersionUnknown() && other.IsBaseVersionUnknown()))\r\n        {\r\n            return true;\r\n        }\r\n\r\n        if (m_parts.size() != other.m_parts.size())\r\n        {\r\n            return false;\r\n        }\r\n\r\n        for (size_t i = 0; i < m_parts.size(); ++i)\r\n        {\r\n            if (m_parts[i] != other.m_parts[i])\r\n            {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    bool Version::operator!=(const Version& other) const\r\n    {\r\n        return !(*this == other);\r\n    }\r\n\r\n    bool Version::IsLatest() const\r\n    {\r\n        return (m_approximateComparator != ApproximateComparator::LessThan && IsBaseVersionLatest());\r\n    }\r\n\r\n    Version Version::CreateLatest()\r\n    {\r\n        Version result;\r\n        result.m_version = s_Version_Part_Latest;\r\n        result.m_parts.emplace_back(0, std::string{ s_Version_Part_Latest });\r\n        return result;\r\n    }\r\n\r\n    bool Version::IsUnknown() const\r\n    {\r\n        return IsBaseVersionUnknown();\r\n    }\r\n\r\n    Version Version::CreateUnknown()\r\n    {\r\n        Version result;\r\n        result.m_version = s_Version_Part_Unknown;\r\n        result.m_parts.emplace_back(0, std::string{ s_Version_Part_Unknown });\r\n        return result;\r\n    }\r\n\r\n    const Version::Part& Version::PartAt(size_t index) const\r\n    {\r\n        static Part s_zero{};\r\n\r\n        if (index < m_parts.size())\r\n        {\r\n            return m_parts[index];\r\n        }\r\n        else\r\n        {\r\n            return s_zero;\r\n        }\r\n    }\r\n\r\n    Version Version::GetBaseVersion() const\r\n    {\r\n        Version baseVersion = *this;\r\n        baseVersion.m_approximateComparator = ApproximateComparator::None;\r\n        if (m_approximateComparator == ApproximateComparator::LessThan)\r\n        {\r\n            baseVersion.m_version = m_version.substr(s_Approximate_Less_Than.size());\r\n        }\r\n        else if (m_approximateComparator == ApproximateComparator::GreaterThan)\r\n        {\r\n            baseVersion.m_version = m_version.substr(s_Approximate_Greater_Than.size());\r\n        }\r\n        \r\n        return baseVersion;\r\n    }\r\n    \r\n    bool Version::IsBaseVersionLatest() const\r\n    {\r\n        return (m_parts.size() == 1 && m_parts[0].Integer == 0 && Utility::CaseInsensitiveEquals(m_parts[0].Other, s_Version_Part_Latest));\r\n    }\r\n\r\n    bool Version::IsBaseVersionUnknown() const\r\n    {\r\n        return (m_parts.size() == 1 && m_parts[0].Integer == 0 && Utility::CaseInsensitiveEquals(m_parts[0].Other, s_Version_Part_Unknown));\r\n    }\r\n\r\n    bool Version::ApproximateCompareLessThan(const Version& other) const\r\n    {\r\n        // Only true if this is less than, other is not, OR this is none, other is greater than\r\n        return (m_approximateComparator == ApproximateComparator::LessThan && other.m_approximateComparator != ApproximateComparator::LessThan) ||\r\n            (m_approximateComparator == ApproximateComparator::None && other.m_approximateComparator == ApproximateComparator::GreaterThan);\r\n    }\r\n\r\n    Version::Part::Part(const std::string& part)\r\n    {\r\n        std::string interimPart = Utility::Trim(part);\r\n        const char* begin = interimPart.c_str();\r\n        char* end = nullptr;\r\n        errno = 0;\r\n        Integer = strtoull(begin, &end, 10);\r\n\r\n        if (errno == ERANGE)\r\n        {\r\n            Integer = 0;\r\n            Other = interimPart;\r\n        }\r\n        else if (static_cast<size_t>(end - begin) != interimPart.length())\r\n        {\r\n            Other = end;\r\n        }\r\n\r\n        m_foldedOther = Utility::FoldCase(static_cast<std::string_view>(Other));\r\n    }\r\n\r\n    Version::Part::Part(uint64_t integer, std::string other) :\r\n        Integer(integer), Other(std::move(Utility::Trim(other)))\r\n    {\r\n        m_foldedOther = Utility::FoldCase(static_cast<std::string_view>(Other));\r\n    }\r\n\r\n    bool Version::Part::operator<(const Part& other) const\r\n    {\r\n        if (Integer < other.Integer)\r\n        {\r\n            return true;\r\n        }\r\n        else if (Integer > other.Integer)\r\n        {\r\n            return false;\r\n        }\r\n        else if (Other.empty())\r\n        {\r\n            // If this Other is empty, it is at least >=\r\n            return false;\r\n        }\r\n        else if (!Other.empty() && other.Other.empty())\r\n        {\r\n            // If the other Other is empty and this is not, this is less.\r\n            return true;\r\n        }\r\n        else if (m_foldedOther < other.m_foldedOther)\r\n        {\r\n            // Compare the folded versions\r\n            return true;\r\n        }\r\n\r\n        // else Other >= other.Other\r\n        return false;\r\n    }\r\n\r\n    bool Version::Part::operator==(const Part& other) const\r\n    {\r\n        return Integer == other.Integer && m_foldedOther == other.m_foldedOther;\r\n    }\r\n\r\n    bool Version::Part::operator!=(const Part& other) const\r\n    {\r\n        return !(*this == other);\r\n    }\r\n\r\n    bool Channel::operator<(const Channel& other) const\r\n    {\r\n        return m_channel < other.m_channel;\r\n    }\r\n\r\n    VersionAndChannel::VersionAndChannel(Version&& version, Channel&& channel) : \r\n        m_version(std::move(version)), m_channel(std::move(channel)) {}\r\n\r\n    std::string VersionAndChannel::ToString() const\r\n    {\r\n        std::string result;\r\n        result = m_version.ToString();\r\n        if (!m_channel.ToString().empty())\r\n        {\r\n            result += '[';\r\n            result += m_channel.ToString();\r\n            result += ']';\r\n        }\r\n        return result;\r\n    }\r\n\r\n    bool VersionAndChannel::operator<(const VersionAndChannel& other) const\r\n    {\r\n        if (m_channel < other.m_channel)\r\n        {\r\n            return true;\r\n        }\r\n        else if (other.m_channel < m_channel)\r\n        {\r\n            return false;\r\n        }\r\n        // We intentionally invert the order for version here.\r\n        else if (other.m_version < m_version)\r\n        {\r\n            return true;\r\n        }\r\n\r\n        // else m_version >= other.m_version\r\n        return false;\r\n    }\r\n\r\n    bool VersionAndChannel::IsUpdatedBy(const VersionAndChannel& other) const\r\n    {\r\n        // Channel crossing should not happen here.\r\n        if (!Utility::ICUCaseInsensitiveEquals(m_channel.ToString(), other.m_channel.ToString()))\r\n        {\r\n            return false;\r\n        }\r\n\r\n        return m_version < other.m_version;\r\n    }\r\n\r\n    UInt64Version::UInt64Version(UINT64 version)\r\n    {\r\n        Assign(version);\r\n    }\r\n\r\n    UInt64Version::UInt64Version(uint16_t major, uint16_t minor, uint16_t build, uint16_t revision)\r\n    {\r\n        Assign(major, minor, build, revision);\r\n    }\r\n\r\n    void UInt64Version::Assign(UINT64 version)\r\n    {\r\n        constexpr UINT64 mask16 = (1 << 16) - 1;\r\n        uint16_t revision = version & mask16;\r\n        uint16_t build = (version >> 0x10) & mask16;\r\n        uint16_t minor = (version >> 0x20) & mask16;\r\n        uint16_t major = (version >> 0x30) & mask16;\r\n\r\n        Assign(major, minor, build, revision);\r\n    }\r\n\r\n    void UInt64Version::Assign(uint16_t major, uint16_t minor, uint16_t build, uint16_t revision)\r\n    {\r\n        // Construct a string representation of the provided version\r\n        std::stringstream ssVersion;\r\n        ssVersion << major\r\n            << Version::DefaultSplitChars << minor\r\n            << Version::DefaultSplitChars << build\r\n            << Version::DefaultSplitChars << revision;\r\n        m_version = ssVersion.str();\r\n\r\n        // Construct the 4 parts\r\n        m_parts = { major, minor, build, revision };\r\n\r\n        // Trim version parts\r\n        Trim();\r\n    }\r\n\r\n    UInt64Version::UInt64Version(std::string&& version, std::string_view splitChars)\r\n    {\r\n        Assign(std::move(version), splitChars);\r\n    }\r\n\r\n    void UInt64Version::Assign(std::string version, std::string_view splitChars)\r\n    {\r\n        Version::Assign(std::move(version), splitChars);\r\n\r\n        // After trimming trailing parts (0 or empty),\r\n        // at most 4 parts must be present\r\n        THROW_HR_IF(E_INVALIDARG, m_parts.size() > 4);\r\n        for (const auto& part : m_parts)\r\n        {\r\n            // Check for non-empty Other part\r\n            THROW_HR_IF(E_INVALIDARG, !part.Other.empty());\r\n\r\n            // Check for overflow Integer part\r\n            THROW_HR_IF(E_INVALIDARG, part.Integer >> 16 != 0);\r\n        }\r\n    }\r\n\r\n    SemanticVersion::SemanticVersion(std::string&& version)\r\n    {\r\n        Assign(std::move(version), DefaultSplitChars);\r\n    }\r\n\r\n    void SemanticVersion::Assign(std::string version, std::string_view splitChars)\r\n    {\r\n        // Semantic versions require using the default split character\r\n        THROW_HR_IF(E_INVALIDARG, splitChars != DefaultSplitChars);\r\n\r\n        // First split off any trailing build metadata\r\n        std::string interimVersion = Utility::Trim(version);\r\n        size_t buildMetadataPos = interimVersion.find('+', 0);\r\n\r\n        if (buildMetadataPos != std::string::npos)\r\n        {\r\n            m_buildMetadata.Assign(interimVersion.substr(buildMetadataPos + 1));\r\n            interimVersion.resize(buildMetadataPos);\r\n        }\r\n\r\n        // Now split off the prerelease data\r\n        size_t prereleasePos = interimVersion.find('-', 0);\r\n\r\n        if (prereleasePos != std::string::npos)\r\n        {\r\n            m_prerelease.Assign(interimVersion.substr(prereleasePos + 1));\r\n            interimVersion.resize(prereleasePos);\r\n        }\r\n\r\n        // Parse main version\r\n        Version::Assign(std::move(interimVersion), splitChars);\r\n        THROW_HR_IF(E_INVALIDARG, IsApproximate());\r\n        THROW_HR_IF(E_INVALIDARG, m_parts.size() > 3);\r\n        for (size_t i = 0; i < 3; ++i)\r\n        {\r\n            THROW_HR_IF(E_INVALIDARG, !PartAt(i).Other.empty());\r\n        }\r\n\r\n        // Put rest of version back onto Other of last part\r\n        size_t otherSplit = (prereleasePos != std::string::npos ? prereleasePos : buildMetadataPos);\r\n        if (otherSplit != std::string::npos)\r\n        {\r\n            while (m_parts.size() < 3)\r\n            {\r\n                m_parts.emplace_back();\r\n            }\r\n            m_parts[2].Other = version.substr(otherSplit);\r\n        }\r\n\r\n        // Overwrite the whole version string with our whole version string\r\n        m_version = std::move(version);\r\n    }\r\n\r\n    bool SemanticVersion::IsPrerelease() const\r\n    {\r\n        return !m_prerelease.IsEmpty();\r\n    }\r\n\r\n    const Version& SemanticVersion::PrereleaseVersion() const\r\n    {\r\n        return m_prerelease;\r\n    }\r\n\r\n    bool SemanticVersion::HasBuildMetadata() const\r\n    {\r\n        return !m_buildMetadata.IsEmpty();\r\n    }\r\n\r\n    const Version& SemanticVersion::BuildMetadata() const\r\n    {\r\n        return m_buildMetadata;\r\n    }\r\n      \r\n    VersionRange::VersionRange(Version first, Version second)\r\n    {\r\n        if (first < second)\r\n        {\r\n            m_minVersion = std::move(first);\r\n            m_maxVersion = std::move(second);\r\n        }\r\n        else\r\n        {\r\n            m_minVersion = std::move(second);\r\n            m_maxVersion = std::move(first);\r\n        }\r\n    }\r\n\r\n    bool VersionRange::Overlaps(const VersionRange& other) const\r\n    {\r\n        // No overlap if either is an empty range.\r\n        if (IsEmpty() || other.IsEmpty())\r\n        {\r\n            return false;\r\n        }\r\n\r\n        return m_minVersion <= other.m_maxVersion && m_maxVersion >= other.m_minVersion;\r\n    }\r\n\r\n    bool VersionRange::IsSameAsSingleVersion(const Version& version) const\r\n    {\r\n        if (IsEmpty())\r\n        {\r\n            return false;\r\n        }\r\n    \r\n        return m_minVersion == version && m_maxVersion == version;\r\n    }\r\n\r\n    bool VersionRange::ContainsVersion(const Version& version) const\r\n    {\r\n        if (IsEmpty())\r\n        {\r\n            return false;\r\n        }\r\n\r\n        return version >= m_minVersion && version <= m_maxVersion;\r\n    }\r\n\r\n    bool VersionRange::operator<(const VersionRange& other) const\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, IsEmpty() || other.IsEmpty() || Overlaps(other));\r\n        \r\n        return m_minVersion < other.m_minVersion;\r\n    }\r\n\r\n    const Version& VersionRange::GetMinVersion() const\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, IsEmpty());\r\n        return m_minVersion;\r\n    }\r\n\r\n    const Version& VersionRange::GetMaxVersion() const\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, IsEmpty());\r\n        return m_maxVersion;\r\n    }\r\n\r\n    bool GatedVersion::IsValidVersion(Version version) const\r\n    {\r\n        auto gateParts = m_version.GetParts();\r\n        if (gateParts.empty())\r\n        {\r\n            return false;\r\n        }\r\n\r\n        if (gateParts.back() != Version::Part(\"*\"))\r\n        {\r\n            // Without wildcards, revert to direct comparison\r\n            return m_version == version;\r\n        }\r\n\r\n        auto versionParts = version.GetParts();\r\n        for (size_t i = 0; i < gateParts.size() - 1; ++i)\r\n        {\r\n            if (versionParts.size() > i)\r\n            {\r\n                if (gateParts[i] == versionParts[i])\r\n                {\r\n                    continue;\r\n                }\r\n                else\r\n                {\r\n                    // Mismatch with the gated version\r\n                    return false;\r\n                }\r\n            }\r\n            else\r\n            {\r\n                // Assume trailing 0s on the version\r\n                if (gateParts[i] != Version::Part(0))\r\n                {\r\n                    return false;\r\n                }\r\n            }\r\n        }\r\n\r\n        // All version parts matched\r\n        return true;\r\n    }\r\n\r\n    bool HasOverlapInVersionRanges(const std::vector<VersionRange>& ranges)\r\n    {\r\n        for (size_t i = 0; i < ranges.size(); i++)\r\n        {\r\n            for (size_t j = i + 1; j < ranges.size(); j++)\r\n            {\r\n                if (ranges[i].Overlaps(ranges[j]))\r\n                {\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    OpenTypeFontVersion::OpenTypeFontVersion(std::string&& version)\r\n    {\r\n        Assign(std::move(version), DefaultSplitChars);\r\n    }\r\n\r\n    void OpenTypeFontVersion::Assign(std::string version, std::string_view splitChars)\r\n    {\r\n        // Open type version requires using the default split character\r\n        THROW_HR_IF(E_INVALIDARG, splitChars != DefaultSplitChars);\r\n\r\n        // Split on default split character.\r\n        std::vector<std::string> parts = Split(version, '.', true);\r\n\r\n        std::string majorString;\r\n        std::string minorString;\r\n\r\n        // Font version must have a \"major.minor\" part.\r\n        if (parts.size() >= 2)\r\n        {\r\n            // Find first digit and trim all preceding characters. \r\n            std::string firstPart = parts[0];\r\n            size_t majorStartIndex = firstPart.find_first_of(s_Digit_Characters);\r\n\r\n            if (majorStartIndex != std::string::npos)\r\n            {\r\n                firstPart.erase(0, majorStartIndex);\r\n            }\r\n\r\n            size_t majorEndIndex = firstPart.find_last_of(s_Digit_Characters);\r\n            majorString = firstPart.substr(0, majorEndIndex + 1);\r\n\r\n            // Parse and verify minor part.\r\n            std::string secondPart = parts[1];\r\n            size_t endPos = secondPart.find_first_not_of(s_Digit_Characters);\r\n\r\n            // If a non-digit character exists, trim off the remainder.\r\n            if (endPos != std::string::npos)\r\n            {\r\n                secondPart.erase(endPos, secondPart.length());\r\n            }\r\n\r\n            minorString = secondPart;\r\n        }\r\n\r\n        // Verify results.\r\n        if (!majorString.empty() && !minorString.empty())\r\n        {\r\n            m_parts.emplace_back(majorString);\r\n            m_parts.emplace_back(minorString);\r\n            m_version = Utility::Join(DefaultSplitChars, { majorString, minorString });\r\n\r\n            Trim();\r\n        }\r\n        else\r\n        {\r\n            m_version = s_Version_Part_Unknown;\r\n            m_parts.emplace_back(0, std::string{ s_Version_Part_Unknown });\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/Yaml.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include <pch.h>\r\n#include \"winget/Yaml.h\"\r\n#include \"YamlWrapper.h\"\r\n#include \"AppInstallerErrors.h\"\r\n#include \"AppInstallerLogging.h\"\r\n#include \"AppInstallerStrings.h\"\r\n\r\n\r\nnamespace AppInstaller::YAML\r\n{\r\n    using namespace std::string_view_literals;\r\n\r\n    namespace\r\n    {\r\n        Node s_globalInvalidNode;\r\n\r\n        static constexpr std::string_view s_nullTag = \"tag:yaml.org,2002:null\"sv;\r\n        static constexpr std::string_view s_boolTag = \"tag:yaml.org,2002:bool\"sv;\r\n        static constexpr std::string_view s_strTag = \"tag:yaml.org,2002:str\"sv;\r\n        static constexpr std::string_view s_intTag = \"tag:yaml.org,2002:int\"sv;\r\n        static constexpr std::string_view s_floatTag = \"tag:yaml.org,2002:float\"sv;\r\n        static constexpr std::string_view s_timestampTag = \"tag:yaml.org,2002:timestamp\"sv;\r\n        static constexpr std::string_view s_seqTag = \"tag:yaml.org,2002:seq\"sv;\r\n        static constexpr std::string_view s_mapTag = \"tag:yaml.org,2002:map\"sv;\r\n\r\n        std::string_view GetExceptionTypeStringView(Exception::Type type)\r\n        {\r\n            switch (type)\r\n            {\r\n            case Exception::Type::None:\r\n                return \"None\"sv;\r\n            case Exception::Type::Memory:\r\n                return \"Memory\"sv;\r\n            case Exception::Type::Reader:\r\n                return \"Reader\"sv;\r\n            case Exception::Type::Scanner:\r\n                return \"Scanner\"sv;\r\n            case Exception::Type::Parser:\r\n                return \"Parser\"sv;\r\n            case Exception::Type::Composer:\r\n                return \"Composer\"sv;\r\n            case Exception::Type::Writer:\r\n                return \"Writer\"sv;\r\n            case Exception::Type::Emitter:\r\n                return \"Emitter\"sv;\r\n            case Exception::Type::Policy:\r\n                return \"Policy\"sv;\r\n            }\r\n\r\n            return \"Unknown\"sv;\r\n        }\r\n\r\n        void OutputExceptionHeader(std::ostringstream& out, Exception::Type type)\r\n        {\r\n            out << \"[YAML:\" << GetExceptionTypeStringView(type) << \"] \";\r\n        }\r\n\r\n        void OutputMark(std::ostringstream& out, const Mark& mark)\r\n        {\r\n            out << \"[line \" << mark.line << \"; col \" << mark.column << ']';\r\n        }\r\n\r\n        Node::TagType ConvertToTagType(const std::string& tag)\r\n        {\r\n            if (tag == s_strTag)\r\n            {\r\n                return Node::TagType::Str;\r\n            }\r\n            else if (tag == s_seqTag)\r\n            {\r\n                return Node::TagType::Seq;\r\n            }\r\n            else if (tag == s_mapTag)\r\n            {\r\n                return Node::TagType::Map;\r\n            }\r\n            else if (tag == s_boolTag)\r\n            {\r\n                return Node::TagType::Bool;\r\n            }\r\n            else if (tag == s_intTag)\r\n            {\r\n                return Node::TagType::Int;\r\n            }\r\n            else if (tag == s_floatTag)\r\n            {\r\n                return Node::TagType::Float;\r\n            }\r\n            else if (tag == s_timestampTag)\r\n            {\r\n                return Node::TagType::Timestamp;\r\n            }\r\n            else if (tag == s_nullTag)\r\n            {\r\n                return Node::TagType::Null;\r\n            }\r\n\r\n            return Node::TagType::Unknown;\r\n        }\r\n\r\n        DocumentSchemaHeader ExtractSchemaHeaderFromYaml( const std::string& yamlDocument, size_t rootNodeLine)\r\n        {\r\n            std::istringstream input(yamlDocument);\r\n            std::string line;\r\n            size_t currentLine = 1;\r\n\r\n            // Search for the schema header string in the comments before the root node.\r\n            while (currentLine < rootNodeLine && std::getline(input, line))\r\n            {\r\n                std::string comment = Utility::Trim(line);\r\n\r\n                // Check if the line is a comment\r\n                if (!comment.empty() && comment[0] == '#')\r\n                {\r\n                    size_t pos = line.find(DocumentSchemaHeader::YamlLanguageServerKey);\r\n\r\n                    // Check if the comment contains the schema header string\r\n                    if (pos != std::string::npos)\r\n                    {\r\n                        return DocumentSchemaHeader(std::move(comment), YAML::Mark{ currentLine, pos});\r\n                    }\r\n                }\r\n\r\n                currentLine++;\r\n            }\r\n\r\n            return {};\r\n        }\r\n    }\r\n\r\n    Exception::Exception(Type type) :\r\n        wil::ResultException(APPINSTALLER_CLI_ERROR_LIBYAML_ERROR)\r\n    {\r\n        std::ostringstream out;\r\n        OutputExceptionHeader(out, type);\r\n\r\n        if (type == Type::Memory)\r\n        {\r\n            out << \"Unable to (re)allocate memory\";\r\n        }\r\n        else\r\n        {\r\n            out << \"An unknown error occurred\";\r\n        }\r\n\r\n        m_what = out.str();\r\n    }\r\n\r\n    Exception::Exception(Type type, const char* problem, size_t offset, int value) :\r\n        wil::ResultException(APPINSTALLER_CLI_ERROR_LIBYAML_ERROR)\r\n    {\r\n        std::ostringstream out;\r\n        OutputExceptionHeader(out, type);\r\n\r\n        out << (problem ? problem : \"Unexplained error\");\r\n\r\n        if (value != -1)\r\n        {\r\n            out << \" [\" << value << ']';\r\n        }\r\n\r\n        out << \" at \" << offset;\r\n\r\n        m_what = out.str();\r\n    }\r\n\r\n    Exception::Exception(Type type, const char* problem, const Mark& problemMark, const char* context, const Mark& contextMark) :\r\n        wil::ResultException(APPINSTALLER_CLI_ERROR_LIBYAML_ERROR), m_mark(problemMark)\r\n    {\r\n        std::ostringstream out;\r\n        OutputExceptionHeader(out, type);\r\n\r\n        if (context)\r\n        {\r\n            out << context << ' ';\r\n            OutputMark(out, contextMark);\r\n            out << ' ' << (problem ? problem : \"unexplained error\");\r\n        }\r\n        else\r\n        {\r\n            out << (problem ? problem : \"Unexplained error\");\r\n        }\r\n\r\n        out << ' ';\r\n        OutputMark(out, problemMark);\r\n\r\n        m_what = out.str();\r\n    }\r\n\r\n    Exception::Exception(Type type, const char* problem) :\r\n        wil::ResultException(APPINSTALLER_CLI_ERROR_LIBYAML_ERROR)\r\n    {\r\n        std::ostringstream out;\r\n        OutputExceptionHeader(out, type);\r\n\r\n        out << (problem ? problem : \"Unexplained error\");\r\n\r\n        m_what = out.str();\r\n    }\r\n\r\n    const char* Exception::what() const noexcept\r\n    {\r\n        return m_what.c_str();\r\n    }\r\n\r\n    const Mark& Exception::GetMark() const\r\n    {\r\n        return m_mark;\r\n    }\r\n\r\n    Node::Node(Type type, std::string tag, const YAML::Mark& mark) :\r\n        m_type(type), m_tag(std::move(tag)), m_mark(mark)\r\n    {\r\n        if (m_type == Type::Sequence)\r\n        {\r\n            m_sequence = decltype(m_sequence)::value_type{};\r\n        }\r\n        else if (m_type == Type::Mapping)\r\n        {\r\n            m_mapping = decltype(m_mapping)::value_type{};\r\n        }\r\n\r\n        m_tagType = ConvertToTagType(m_tag);\r\n    }\r\n\r\n    void Node::SetScalar(std::string value)\r\n    {\r\n        Require(Type::Scalar);\r\n        m_scalar = std::move(value);\r\n    }\r\n\r\n    void Node::SetScalar(std::string value, bool isQuoted)\r\n    {\r\n        this->SetScalar(value);\r\n\r\n        // For untagged scalar nodes, libyaml always assigns the generic string\r\n        // tag. Here we just try our best and assume that if the value is unquoted\r\n        // then is not necessarily a string.\r\n        // TODO: handle float and timestamps\r\n        if (!isQuoted && this->GetTagType() == TagType::Str)\r\n        {\r\n            // Integer\r\n            // 0 | -? [1-9] [0-9]*\r\n            auto tryInt = this->try_as<int64_t>();\r\n            if (tryInt.has_value())\r\n            {\r\n                m_tagType = TagType::Int;\r\n                return;\r\n            }\r\n\r\n            // Boolean. Either 'true' or 'false'\r\n            auto tryBool = this->try_as<bool>();\r\n            if (tryBool.has_value())\r\n            {\r\n                m_tagType = TagType::Bool;\r\n            }\r\n        }\r\n    }\r\n\r\n    bool Node::operator<(const Node& other) const\r\n    {\r\n        Require(Type::Scalar);\r\n        other.Require(Type::Scalar);\r\n        return this->m_scalar < other.m_scalar;\r\n    }\r\n\r\n    Node& Node::operator[](std::string_view key)\r\n    {\r\n        Require(Type::Mapping);\r\n        auto itrs = m_mapping->equal_range(key);\r\n\r\n        if (itrs.first == itrs.second)\r\n        {\r\n            return s_globalInvalidNode;\r\n        }\r\n\r\n        Node& result = itrs.first->second;\r\n\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY, ++itrs.first != itrs.second);\r\n\r\n        return result;\r\n    }\r\n\r\n    const Node& Node::operator[](std::string_view key) const\r\n    {\r\n        Require(Type::Mapping);\r\n        auto itrs = m_mapping->equal_range(key);\r\n\r\n        if (itrs.first == itrs.second)\r\n        {\r\n            return s_globalInvalidNode;\r\n        }\r\n\r\n        const Node& result = itrs.first->second;\r\n\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY, ++itrs.first != itrs.second);\r\n\r\n        return result;\r\n    }\r\n\r\n    // Gets a child node from the mapping by its name.\r\n    Node& Node::GetChildNode(std::string_view key)\r\n    {\r\n        Require(Type::Mapping);\r\n\r\n        auto itr = m_mapping->begin();\r\n        for (; itr != m_mapping->end(); itr++)\r\n        {\r\n            if (Utility::CaseInsensitiveEquals(itr->first.m_scalar, key))\r\n            {\r\n                break;\r\n            }\r\n        }\r\n\r\n        if (itr == m_mapping->end())\r\n        {\r\n            return s_globalInvalidNode;\r\n        }\r\n\r\n        auto firstFound = itr;\r\n        for (++itr; itr != m_mapping->end(); itr++)\r\n        {\r\n            if (Utility::CaseInsensitiveEquals(itr->first.m_scalar, key))\r\n            {\r\n                break;\r\n            }\r\n        }\r\n\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY, itr != m_mapping->end());\r\n        Node& result = firstFound->second;\r\n        return result;\r\n    }\r\n\r\n    const Node& Node::GetChildNode(std::string_view key) const\r\n    {\r\n        Require(Type::Mapping);\r\n\r\n        auto itr = m_mapping->begin();\r\n        for (; itr != m_mapping->end(); itr++)\r\n        {\r\n            if (Utility::CaseInsensitiveEquals(itr->first.m_scalar, key))\r\n            {\r\n                break;\r\n            }\r\n        }\r\n\r\n        if (itr == m_mapping->end())\r\n        {\r\n            return s_globalInvalidNode;\r\n        }\r\n\r\n        auto firstFound = itr;\r\n        for (++itr; itr != m_mapping->end(); itr++)\r\n        {\r\n            if (Utility::CaseInsensitiveEquals(itr->first.m_scalar, key))\r\n            {\r\n                break;\r\n            }\r\n        }\r\n\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY, itr != m_mapping->end());\r\n        const Node& result = firstFound->second;\r\n        return result;\r\n    }\r\n\r\n    Node& Node::operator[](size_t index)\r\n    {\r\n        Require(Type::Sequence);\r\n        return m_sequence.value()[index];\r\n    }\r\n\r\n    const Node& Node::operator[](size_t index) const\r\n    {\r\n        Require(Type::Sequence);\r\n        return m_sequence.value()[index];\r\n    }\r\n\r\n    size_t Node::size() const\r\n    {\r\n        switch (m_type)\r\n        {\r\n        case Type::Invalid:\r\n        case Type::None:\r\n        case Type::Scalar:\r\n            return 0;\r\n        case Type::Sequence:\r\n            return m_sequence->size();\r\n        case Type::Mapping:\r\n            return m_mapping->size();\r\n        }\r\n\r\n        THROW_HR(E_UNEXPECTED);\r\n    }\r\n\r\n    const std::vector<Node>& Node::Sequence() const\r\n    {\r\n        Require(Type::Sequence);\r\n        return m_sequence.value();\r\n    }\r\n\r\n    const std::multimap<Node, Node>& Node::Mapping() const\r\n    {\r\n        Require(Type::Mapping);\r\n        return m_mapping.value();\r\n    }\r\n\r\n    void Node::Require(Type type) const\r\n    {\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_YAML_INVALID_OPERATION, m_type != type);\r\n    }\r\n\r\n    std::string Node::as_dispatch(std::string*) const\r\n    {\r\n        return m_scalar;\r\n    }\r\n\r\n    std::optional<std::string> Node::try_as_dispatch(std::string*) const\r\n    {\r\n        return std::optional{ m_scalar };\r\n    }\r\n\r\n    std::wstring Node::as_dispatch(std::wstring*) const\r\n    {\r\n        return Utility::ConvertToUTF16(m_scalar);\r\n    }\r\n\r\n    std::optional<std::wstring> Node::try_as_dispatch(std::wstring*) const\r\n    {\r\n        return Utility::TryConvertToUTF16(m_scalar);\r\n    }\r\n\r\n    int64_t Node::as_dispatch(int64_t*) const\r\n    {\r\n        return std::stoll(m_scalar);\r\n    }\r\n\r\n    std::optional<int64_t> Node::try_as_dispatch(int64_t*) const\r\n    {\r\n        if (m_scalar.empty())\r\n        {\r\n            return {};\r\n        }\r\n\r\n        const char* begin = m_scalar.c_str();\r\n        char* end = nullptr;\r\n        errno = 0;\r\n        int64_t result = static_cast<int64_t>(strtoll(begin, &end, 0));\r\n\r\n        if (errno == ERANGE || static_cast<size_t>(end - begin) != m_scalar.length())\r\n        {\r\n            return {};\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    int Node::as_dispatch(int*) const\r\n    {\r\n        // To allow HResult representation\r\n        return static_cast<int>(std::stoll(m_scalar, 0, 0));\r\n    }\r\n\r\n    std::optional<int> Node::try_as_dispatch(int*) const\r\n    {\r\n        try\r\n        {\r\n            return std::optional{ static_cast<int>(std::stoll(m_scalar, 0, 0)) };\r\n        }\r\n        catch (...)\r\n        {\r\n            return {};\r\n        }\r\n    }\r\n\r\n    bool Node::as_dispatch(bool*) const\r\n    {\r\n        bool* t = nullptr;\r\n        auto tryToBool = this->try_as_dispatch(t);\r\n        if (tryToBool.has_value())\r\n        {\r\n            return tryToBool.value();\r\n        }\r\n        else\r\n        {\r\n            THROW_HR(APPINSTALLER_CLI_ERROR_YAML_INVALID_DATA);\r\n        }\r\n    }\r\n\r\n    std::optional<bool> Node::try_as_dispatch(bool*) const\r\n    {\r\n        if (Utility::CaseInsensitiveEquals(m_scalar, \"true\"))\r\n        {\r\n            return std::optional{ true };\r\n        }\r\n        else if (Utility::CaseInsensitiveEquals(m_scalar, \"false\"))\r\n        {\r\n            return std::optional{ false };\r\n        }\r\n\r\n        return {};\r\n    }\r\n\r\n    void Node::MergeSequenceNode(Node other, std::string_view key, bool caseInsensitive)\r\n    {\r\n        Require(Type::Sequence);\r\n        other.Require(Type::Sequence);\r\n\r\n        auto getKeyValue = [&](const YAML::Node& node) {\r\n            auto keyNode = caseInsensitive ? node.GetChildNode(key) : node[key];\r\n            if (keyNode.IsNull())\r\n            {\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_YAML_INVALID_DATA);\r\n            }\r\n\r\n            auto keyValue = keyNode.as<std::string>();\r\n            return caseInsensitive ? std::string{ Utility::FoldCase(std::string_view{keyValue}) } : keyValue;\r\n        };\r\n\r\n        std::map<std::string, Node> newSequenceMap;\r\n        for (Node& node : m_sequence.value())\r\n        {\r\n            node.Require(Type::Mapping);\r\n            auto keyValue = getKeyValue(node);\r\n            newSequenceMap.emplace(std::move(keyValue), std::move(node));\r\n        }\r\n\r\n        for (Node& node : other.m_sequence.value())\r\n        {\r\n            node.Require(Type::Mapping);\r\n            auto keyValue = getKeyValue(node);\r\n            if (newSequenceMap.find(keyValue) == newSequenceMap.end())\r\n            {\r\n                newSequenceMap.emplace(std::move(keyValue), std::move(node));\r\n            }\r\n            else\r\n            {\r\n                newSequenceMap[keyValue].MergeMappingNode(node, caseInsensitive);\r\n            }\r\n        }\r\n\r\n        m_sequence.reset();\r\n        std::vector<Node> newSequence;\r\n        for (const auto& keyValuePair : newSequenceMap)\r\n        {\r\n            newSequence.push_back(keyValuePair.second);\r\n        }\r\n\r\n        m_sequence = std::move(newSequence);\r\n    }\r\n\r\n    void Node::MergeMappingNode(Node other, bool caseInsensitive)\r\n    {\r\n        Require(Type::Mapping);\r\n        other.Require(Type::Mapping);\r\n\r\n        std::multimap<Node, Node> uniques;\r\n        for (auto& keyValuePair : other.m_mapping.value())\r\n        {\r\n            if (caseInsensitive)\r\n            {\r\n                auto node = GetChildNode(keyValuePair.first.as<std::string>());\r\n                if (node.IsNull())\r\n                {\r\n                    uniques.emplace(std::move(keyValuePair));\r\n                }\r\n            }\r\n            else\r\n            {\r\n                if (m_mapping->count(keyValuePair.first) == 0)\r\n                {\r\n                    uniques.emplace(std::move(keyValuePair));\r\n                }\r\n            }\r\n        }\r\n\r\n        m_mapping->merge(uniques);\r\n    }\r\n\r\n    Node Load(std::string_view input)\r\n    {\r\n        Wrapper::Parser parser(input);\r\n        Wrapper::Document document = parser.Load();\r\n\r\n        if (document.HasRoot())\r\n        {\r\n            return document.GetRoot();\r\n        }\r\n        else\r\n        {\r\n            return {};\r\n        }\r\n    }\r\n\r\n    Node Load(const std::string& input)\r\n    {\r\n        return Load(static_cast<std::string_view>(input));\r\n    }\r\n\r\n    Node Load(std::istream& input, Utility::SHA256::HashBuffer* hashOut)\r\n    {\r\n        Wrapper::Parser parser(input, hashOut);\r\n        Wrapper::Document document = parser.Load();\r\n\r\n        if (document.HasRoot())\r\n        {\r\n            return document.GetRoot();\r\n        }\r\n        else\r\n        {\r\n            return {};\r\n        }\r\n    }\r\n\r\n    Node Load(const std::filesystem::path& input, Utility::SHA256::HashBuffer* hashOut)\r\n    {\r\n        std::ifstream stream(input, std::ios_base::in | std::ios_base::binary);\r\n        THROW_LAST_ERROR_IF(stream.fail());\r\n        return Load(stream, hashOut);\r\n    }\r\n\r\n    Node Load(const std::filesystem::path& input)\r\n    {\r\n        return Load(input, nullptr);\r\n    }\r\n\r\n    Node Load(const std::filesystem::path& input, Utility::SHA256::HashBuffer& hashOut)\r\n    {\r\n        return Load(input, &hashOut);\r\n    }\r\n\r\n    Document LoadDocument(std::string_view input)\r\n    {\r\n        Wrapper::Parser parser(input);\r\n        Wrapper::Document document = parser.Load();\r\n\r\n        if (document.HasRoot())\r\n        {\r\n            const Node root = document.GetRoot();\r\n            const DocumentSchemaHeader schemaHeader = ExtractSchemaHeaderFromYaml(parser.GetEncodedInput(), root.Mark().line);\r\n\r\n            return { root, schemaHeader };\r\n        }\r\n        else\r\n        {\r\n            // Return an empty root and schema header.\r\n            return {};\r\n        }\r\n    }\r\n\r\n    Document LoadDocument(const std::string& input)\r\n    {\r\n        return LoadDocument(static_cast<std::string_view>(input));\r\n    }\r\n\r\n    Document LoadDocument(std::istream& input, Utility::SHA256::HashBuffer* hashOut)\r\n    {\r\n        Wrapper::Parser parser(input, hashOut);\r\n        Wrapper::Document document = parser.Load();\r\n\r\n        if (document.HasRoot())\r\n        {\r\n            const Node root = document.GetRoot();\r\n            const DocumentSchemaHeader schemaHeader = ExtractSchemaHeaderFromYaml(parser.GetEncodedInput(), root.Mark().line);\r\n\r\n            return { root, schemaHeader };\r\n        }\r\n        else\r\n        {\r\n            // Return an empty root and schema header.\r\n            return {};\r\n        }\r\n    }\r\n\r\n    Document LoadDocument(const std::filesystem::path& input, Utility::SHA256::HashBuffer* hashOut)\r\n    {\r\n        std::ifstream stream(input, std::ios_base::in | std::ios_base::binary);\r\n        THROW_LAST_ERROR_IF(stream.fail());\r\n        return LoadDocument(stream, hashOut);\r\n    }\r\n\r\n    Document LoadDocument(const std::filesystem::path& input)\r\n    {\r\n        return LoadDocument(input, nullptr);\r\n    }\r\n\r\n    Document LoadDocument(const std::filesystem::path& input, Utility::SHA256::HashBuffer& hashOut)\r\n    {\r\n        return LoadDocument(input, &hashOut);\r\n    }\r\n\r\n    Emitter::Emitter() :\r\n        m_document(std::make_unique<Wrapper::Document>(true))\r\n    {\r\n        SetAllowedInputs<InputType::BeginMap, InputType::BeginSeq>();\r\n    }\r\n\r\n    Emitter::Emitter(Emitter&&) noexcept = default;\r\n    Emitter& Emitter::operator=(Emitter&&) noexcept = default;\r\n\r\n    Emitter::~Emitter() = default;\r\n\r\n    Emitter& Emitter::operator<<(EmitterEvent event)\r\n    {\r\n        switch (event)\r\n        {\r\n        case AppInstaller::YAML::BeginSeq:\r\n        {\r\n            CheckInput(InputType::BeginSeq);\r\n            int id = m_document->AddSequence();\r\n            AppendNode(id);\r\n            m_containers.emplace(id, false);\r\n            SetAllowedInputsForContainer();\r\n            break;\r\n        }\r\n        case AppInstaller::YAML::EndSeq:\r\n            CheckInput(InputType::EndSeq);\r\n            m_containers.pop();\r\n            SetAllowedInputsForContainer();\r\n            break;\r\n        case AppInstaller::YAML::BeginMap:\r\n        {\r\n            CheckInput(InputType::BeginMap);\r\n            int id = m_document->AddMapping();\r\n            AppendNode(id);\r\n            m_containers.emplace(id, true);\r\n            SetAllowedInputsForContainer();\r\n            break;\r\n        }\r\n        case AppInstaller::YAML::EndMap:\r\n            CheckInput(InputType::EndMap);\r\n            m_containers.pop();\r\n            SetAllowedInputsForContainer();\r\n            break;\r\n        case AppInstaller::YAML::Key:\r\n            CheckInput(InputType::Key);\r\n            m_scalarType = InputType::Key;\r\n            SetAllowedInputs<InputType::Scalar>();\r\n            break;\r\n        case AppInstaller::YAML::Value:\r\n            CheckInput(InputType::Value);\r\n            m_scalarType = InputType::Value;\r\n            SetAllowedInputs<InputType::Scalar, InputType::BeginMap, InputType::BeginSeq>();\r\n            break;\r\n        default:\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n\r\n        return *this;\r\n    }\r\n\r\n    Emitter& Emitter::operator<<(std::string_view value)\r\n    {\r\n        CheckInput(InputType::Scalar);\r\n\r\n        int id = m_document->AddScalar(value, m_scalarStyle.value_or(ScalarStyle::Any));\r\n        m_scalarStyle = std::nullopt;\r\n\r\n        if (!m_scalarType)\r\n        {\r\n            // Part of a sequence\r\n            AppendNode(id);\r\n            // No change to allowed inputs\r\n        }\r\n        else if (m_scalarType.value() == InputType::Key)\r\n        {\r\n            m_keyId = id;\r\n            m_scalarType = std::nullopt;\r\n            SetAllowedInputs<InputType::Value, InputType::BeginMap, InputType::BeginSeq>();\r\n        }\r\n        else if (m_scalarType.value() == InputType::Value)\r\n        {\r\n            // Mapping pair complete\r\n            AppendNode(id);\r\n            m_scalarType = std::nullopt;\r\n            SetAllowedInputsForContainer();\r\n        }\r\n        else\r\n        {\r\n            THROW_HR(APPINSTALLER_CLI_ERROR_YAML_INVALID_EMITTER_STATE);\r\n        }\r\n\r\n        return *this;\r\n    }\r\n\r\n    Emitter& Emitter::operator<<(int64_t value)\r\n    {\r\n        std::ostringstream stream;\r\n        stream << value;\r\n        return operator<<(stream.str());\r\n    }\r\n\r\n    Emitter& Emitter::operator<<(int value)\r\n    {\r\n        std::ostringstream stream;\r\n        stream << value;\r\n        return operator<<(stream.str());\r\n    }\r\n\r\n    Emitter& Emitter::operator<<(bool value)\r\n    {\r\n        return operator<<(value ? \"true\"sv : \"false\"sv);\r\n    }\r\n\r\n    Emitter& Emitter::operator<<(ScalarStyle style)\r\n    {\r\n        m_scalarStyle = style;\r\n        // Because without this you get a C26815...\r\n        (void)0;\r\n        return *this;\r\n    }\r\n\r\n    std::string Emitter::str()\r\n    {\r\n        std::ostringstream stream;\r\n        Wrapper::Emitter emitter(stream);\r\n\r\n        emitter.Dump(*m_document);\r\n        emitter.Flush();\r\n\r\n        return stream.str();\r\n    }\r\n\r\n    void Emitter::Emit(std::ostream& out)\r\n    {\r\n        Wrapper::Emitter emitter(out);\r\n\r\n        emitter.Dump(*m_document);\r\n        emitter.Flush();\r\n    }\r\n\r\n    void Emitter::AppendNode(int id)\r\n    {\r\n        if (!m_containers.empty())\r\n        {\r\n            ContainerInfo& ci = m_containers.top();\r\n\r\n            if (ci.IsMapping)\r\n            {\r\n                THROW_HR_IF(APPINSTALLER_CLI_ERROR_YAML_INVALID_EMITTER_STATE, !m_keyId);\r\n                m_document->AppendMappingPair(ci.Id, m_keyId.value(), id);\r\n                m_keyId = std::nullopt;\r\n            }\r\n            else\r\n            {\r\n                m_document->AppendSequenceItem(ci.Id, id);\r\n            }\r\n        }\r\n    }\r\n\r\n    size_t Emitter::GetInputBitmask(InputType type)\r\n    {\r\n        return static_cast<size_t>(1) << static_cast<size_t>(type);\r\n    }\r\n\r\n    void Emitter::CheckInput(InputType type)\r\n    {\r\n        if ((m_allowedInputs & GetInputBitmask(type)) == 0)\r\n        {\r\n            AICLI_LOG(YAML, Error, << \"Invalid emitter input [0x\" <<\r\n                std::hex << std::setw(2) << std::setfill('0') << GetInputBitmask(type) << \"], expected one of [0x\" <<\r\n                std::hex << std::setw(2) << std::setfill('0') << m_allowedInputs << \"]\");\r\n            THROW_HR(APPINSTALLER_CLI_ERROR_YAML_INVALID_EMITTER_STATE);\r\n        }\r\n    }\r\n\r\n    void Emitter::SetAllowedInputsForContainer()\r\n    {\r\n        if (m_containers.empty())\r\n        {\r\n            m_allowedInputs = 0;\r\n        }\r\n        else\r\n        {\r\n            if (m_containers.top().IsMapping)\r\n            {\r\n                SetAllowedInputs<InputType::Key, InputType::EndMap>();\r\n            }\r\n            else\r\n            {\r\n                SetAllowedInputs<InputType::Scalar, InputType::BeginMap, InputType::BeginSeq, InputType::EndSeq>();\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/YamlWrapper.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include <pch.h>\r\n#include \"YamlWrapper.h\"\r\n#include \"AppInstallerErrors.h\"\r\n#include \"AppInstallerLogging.h\"\r\n#include \"AppInstallerStrings.h\"\r\n\r\n\r\nnamespace AppInstaller::YAML::Wrapper\r\n{\r\n    namespace\r\n    {\r\n        Node::Type ConvertNodeType(yaml_node_type_t type)\r\n        {\r\n            switch (type)\r\n            {\r\n            case YAML_NO_NODE:\r\n                return Node::Type::None;\r\n            case YAML_SCALAR_NODE:\r\n                return Node::Type::Scalar;\r\n            case YAML_SEQUENCE_NODE:\r\n                return Node::Type::Sequence;\r\n            case YAML_MAPPING_NODE:\r\n                return Node::Type::Mapping;\r\n            }\r\n\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n\r\n        Exception::Type ConvertErrorType(yaml_error_type_t type)\r\n        {\r\n            switch (type)\r\n            {\r\n            case YAML_NO_ERROR:\r\n                return Exception::Type::None;\r\n            case YAML_MEMORY_ERROR:\r\n                return Exception::Type::Memory;\r\n            case YAML_READER_ERROR:\r\n                return Exception::Type::Reader;\r\n            case YAML_SCANNER_ERROR:\r\n                return Exception::Type::Scanner;\r\n            case YAML_PARSER_ERROR:\r\n                return Exception::Type::Parser;\r\n            case YAML_COMPOSER_ERROR:\r\n                return Exception::Type::Composer;\r\n            case YAML_WRITER_ERROR:\r\n                return Exception::Type::Writer;\r\n            case YAML_EMITTER_ERROR:\r\n                return Exception::Type::Emitter;\r\n            }\r\n\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n\r\n        Mark ConvertMark(const yaml_mark_t& mark)\r\n        {\r\n            return { mark.line + 1, mark.column + 1 };\r\n        }\r\n\r\n        std::string ConvertYamlString(yaml_char_t* string, const yaml_mark_t& mark, size_t length = std::string::npos)\r\n        {\r\n            std::string_view resultView;\r\n\r\n            if (length == std::string::npos)\r\n            {\r\n                resultView = { reinterpret_cast<char*>(string) };\r\n            }\r\n            else\r\n            {\r\n                resultView = { reinterpret_cast<char*>(string), length };\r\n            }\r\n\r\n            size_t invalidCharacter = Utility::FindControlCodeToConvert(resultView);\r\n            if (invalidCharacter != std::string::npos)\r\n            {\r\n                THROW_EXCEPTION(Exception(Exception::Type::Policy, \"unsupported control character\", ConvertMark(mark)));\r\n            }\r\n\r\n            return std::string{ resultView };\r\n        }\r\n\r\n        std::string ConvertScalarToString(yaml_node_t* node, const yaml_mark_t& mark)\r\n        {\r\n            return ConvertYamlString(node->data.scalar.value, mark, node->data.scalar.length);\r\n        }\r\n\r\n        yaml_scalar_style_t ConvertStyle(ScalarStyle style)\r\n        {\r\n            switch (style)\r\n            {\r\n            case ScalarStyle::Any: return yaml_scalar_style_t::YAML_ANY_SCALAR_STYLE;\r\n            case ScalarStyle::Plain: return yaml_scalar_style_t::YAML_PLAIN_SCALAR_STYLE;\r\n            case ScalarStyle::SingleQuoted: return yaml_scalar_style_t::YAML_SINGLE_QUOTED_SCALAR_STYLE;\r\n            case ScalarStyle::DoubleQuoted: return yaml_scalar_style_t::YAML_DOUBLE_QUOTED_SCALAR_STYLE;\r\n            case ScalarStyle::Literal: return yaml_scalar_style_t::YAML_LITERAL_SCALAR_STYLE;\r\n            case ScalarStyle::Folded: return yaml_scalar_style_t::YAML_FOLDED_SCALAR_STYLE;\r\n            default: THROW_HR(E_UNEXPECTED);\r\n            }\r\n        }\r\n    }\r\n\r\n    Document::Document(bool init) :\r\n        m_token(true)\r\n    {\r\n        if (init)\r\n        {\r\n            // Initialize with no version directive or tags, and implicit start and end.\r\n            if (!yaml_document_initialize(&m_document, NULL, NULL, NULL, 1, 1))\r\n            {\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_YAML_DOC_BUILD_FAILED);\r\n            }\r\n        }\r\n        else\r\n        {\r\n            memset(&m_document, 0, sizeof(m_document));\r\n        }\r\n    }\r\n\r\n    Document::~Document()\r\n    {\r\n        if (m_token)\r\n        {\r\n            yaml_document_delete(&m_document);\r\n        }\r\n    }\r\n\r\n    bool Document::HasRoot()\r\n    {\r\n        return yaml_document_get_root_node(&m_document) != nullptr;\r\n    }\r\n\r\n    Node Document::GetRoot()\r\n    {\r\n        yaml_node_t* root = yaml_document_get_root_node(&m_document);\r\n\r\n        if (!root)\r\n        {\r\n            return {};\r\n        }\r\n\r\n        Node result(ConvertNodeType(root->type), ConvertYamlString(root->tag, root->start_mark), ConvertMark(root->start_mark));\r\n\r\n        struct StackItem\r\n        {\r\n            StackItem(yaml_node_t* yn, Node* n) :\r\n                yamlNode(yn), node(n) {}\r\n\r\n            yaml_node_t* yamlNode = nullptr;\r\n            Node* node = nullptr;\r\n            size_t childOffset = 0;\r\n        };\r\n\r\n        static int YAML_DOCUMENT_NEST_LEVEL_LIMIT = 100;\r\n        int nestLevel = 0;\r\n\r\n        std::stack<StackItem> resultStack;\r\n        resultStack.emplace(root, &result);\r\n\r\n        while (!resultStack.empty())\r\n        {\r\n            StackItem& stackItem = resultStack.top();\r\n            bool pop = false;\r\n\r\n            switch (stackItem.yamlNode->type)\r\n            {\r\n            case YAML_NO_NODE:\r\n                pop = true;\r\n                break;\r\n            case YAML_SCALAR_NODE:\r\n                stackItem.node->SetScalar(\r\n                    ConvertScalarToString(stackItem.yamlNode, stackItem.yamlNode->start_mark),\r\n                    stackItem.yamlNode->data.scalar.style == YAML_SINGLE_QUOTED_SCALAR_STYLE ||\r\n                    stackItem.yamlNode->data.scalar.style == YAML_DOUBLE_QUOTED_SCALAR_STYLE);\r\n                pop = true;\r\n                break;\r\n            case YAML_SEQUENCE_NODE:\r\n            {\r\n                if (stackItem.childOffset == 0)\r\n                {\r\n                    // We've entered the sequence.\r\n                    nestLevel++;\r\n                }\r\n\r\n                yaml_node_item_t* child = stackItem.yamlNode->data.sequence.items.start + stackItem.childOffset++;\r\n                if (child < stackItem.yamlNode->data.sequence.items.top)\r\n                {\r\n                    yaml_node_t* childYamlNode = GetNode(*child);\r\n                    Node& childNode = stackItem.node->AddSequenceNode(ConvertNodeType(childYamlNode->type), ConvertYamlString(childYamlNode->tag, childYamlNode->start_mark), ConvertMark(childYamlNode->start_mark));\r\n                    resultStack.emplace(childYamlNode, &childNode);\r\n                }\r\n                else\r\n                {\r\n                    // We've reached the end of the sequence\r\n                    pop = true;\r\n                    nestLevel--;\r\n                }\r\n                break;\r\n            }\r\n            case YAML_MAPPING_NODE:\r\n            {\r\n                if (stackItem.childOffset == 0)\r\n                {\r\n                    // We've entered the mapping.\r\n                    nestLevel++;\r\n                }\r\n\r\n                yaml_node_pair_t* child = stackItem.yamlNode->data.mapping.pairs.start + stackItem.childOffset++;\r\n                if (child < stackItem.yamlNode->data.mapping.pairs.top)\r\n                {\r\n                    yaml_node_t* keyYamlNode = GetNode(child->key);\r\n                    THROW_HR_IF(APPINSTALLER_CLI_ERROR_YAML_INVALID_MAPPING_KEY, keyYamlNode->type != YAML_SCALAR_NODE);\r\n\r\n                    Node keyNode(ConvertNodeType(keyYamlNode->type), ConvertYamlString(keyYamlNode->tag, keyYamlNode->start_mark), ConvertMark(keyYamlNode->start_mark));\r\n                    keyNode.SetScalar(ConvertScalarToString(keyYamlNode, keyYamlNode->start_mark));\r\n\r\n                    yaml_node_t* valueYamlNode = GetNode(child->value);\r\n\r\n                    Node& childNode = stackItem.node->AddMappingNode(std::move(keyNode), ConvertNodeType(valueYamlNode->type), ConvertYamlString(valueYamlNode->tag, valueYamlNode->start_mark), ConvertMark(valueYamlNode->start_mark));\r\n                    resultStack.emplace(valueYamlNode, &childNode);\r\n                }\r\n                else\r\n                {\r\n                    // We've reached the end of the mapping\r\n                    pop = true;\r\n                    nestLevel--;\r\n                }\r\n                break;\r\n            }\r\n            }\r\n\r\n            if (pop)\r\n            {\r\n                resultStack.pop();\r\n            }\r\n\r\n            THROW_HR_IF_MSG(APPINSTALLER_CLI_ERROR_YAML_DOC_BUILD_FAILED, nestLevel > YAML_DOCUMENT_NEST_LEVEL_LIMIT, \"Too many layers of nested nodes.\");\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    int Document::AddScalar(std::string_view value, ScalarStyle style)\r\n    {\r\n        int result = yaml_document_add_scalar(&m_document, NULL, reinterpret_cast<const yaml_char_t*>(value.data()), static_cast<int>(value.size()), ConvertStyle(style));\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_YAML_DOC_BUILD_FAILED, result == 0);\r\n        return result;\r\n    }\r\n\r\n    int Document::AddSequence()\r\n    {\r\n        int result = yaml_document_add_sequence(&m_document, NULL, YAML_ANY_SEQUENCE_STYLE);\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_YAML_DOC_BUILD_FAILED, result == 0);\r\n        return result;\r\n    }\r\n\r\n    int Document::AddMapping()\r\n    {\r\n        int result = yaml_document_add_mapping(&m_document, NULL, YAML_ANY_MAPPING_STYLE);\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_YAML_DOC_BUILD_FAILED, result == 0);\r\n        return result;\r\n    }\r\n\r\n    void Document::AppendSequenceItem(int sequence, int item)\r\n    {\r\n        if (!yaml_document_append_sequence_item(&m_document, sequence, item))\r\n        {\r\n            THROW_HR(APPINSTALLER_CLI_ERROR_YAML_DOC_BUILD_FAILED);\r\n        }\r\n    }\r\n\r\n    void Document::AppendMappingPair(int mapping, int key, int value)\r\n    {\r\n        if (!yaml_document_append_mapping_pair(&m_document, mapping, key, value))\r\n        {\r\n            THROW_HR(APPINSTALLER_CLI_ERROR_YAML_DOC_BUILD_FAILED);\r\n        }\r\n    }\r\n\r\n    yaml_node_t* Document::GetNode(yaml_node_item_t index)\r\n    {\r\n        yaml_node_t* result = yaml_document_get_node(&m_document, index);\r\n        THROW_HR_IF(E_BOUNDS, !result);\r\n        return result;\r\n    }\r\n\r\n    Parser::Parser(std::string_view input) : m_token(true), m_input(input)\r\n    {\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED, !yaml_parser_initialize(&m_parser));\r\n\r\n        PrepareInput();\r\n        yaml_parser_set_input_string(&m_parser, reinterpret_cast<const unsigned char*>(m_input.c_str()), m_input.size());\r\n    }\r\n\r\n    Parser::Parser(std::istream& input, Utility::SHA256::HashBuffer* hashOut) : m_token(true)\r\n    {\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED, !yaml_parser_initialize(&m_parser));\r\n\r\n        m_input = Utility::ReadEntireStream(input);\r\n\r\n        if (hashOut)\r\n        {\r\n            *hashOut = Utility::SHA256::ComputeHash(reinterpret_cast<const uint8_t*>(m_input.data()), static_cast<uint32_t>(m_input.size()));\r\n        }\r\n\r\n        PrepareInput();\r\n        yaml_parser_set_input_string(&m_parser, reinterpret_cast<const unsigned char*>(m_input.c_str()), m_input.size());\r\n    }\r\n\r\n    Parser::~Parser()\r\n    {\r\n        if (m_token)\r\n        {\r\n            yaml_parser_delete(&m_parser);\r\n        }\r\n    }\r\n\r\n    Document Parser::Load()\r\n    {\r\n        Document result;\r\n\r\n        if (!yaml_parser_load(&m_parser, &result))\r\n        {\r\n            Exception::Type type = ConvertErrorType(m_parser.error);\r\n\r\n            switch (type)\r\n            {\r\n            case Exception::Type::Memory:\r\n                THROW_EXCEPTION(Exception(type));\r\n            case Exception::Type::Reader:\r\n                THROW_EXCEPTION(Exception(type, m_parser.problem, m_parser.problem_offset, m_parser.problem_value));\r\n            case Exception::Type::Scanner:\r\n            case Exception::Type::Parser:\r\n            case Exception::Type::Composer:\r\n                THROW_EXCEPTION(Exception(type, m_parser.problem, ConvertMark(m_parser.problem_mark), m_parser.context, ConvertMark(m_parser.context_mark)));\r\n            default:\r\n                THROW_EXCEPTION(Exception(type, \"An unexpected error type occurred in Parser::Load\"));\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    void Parser::PrepareInput()\r\n    {\r\n        constexpr char c_utf16LEBOM[2] = { static_cast<char>(0xFF), static_cast<char>(0xFE) };\r\n        constexpr char c_utf16BEBOM[2] = { static_cast<char>(0xFE), static_cast<char>(0xFF) };\r\n        constexpr char c_utf8BOM[3] = { static_cast<char>(0xEF), static_cast<char>(0xBB), static_cast<char>(0xBF) };\r\n\r\n        // If input has a BOM, we want to remove it to prevent errors with checking for comments within the input document.\r\n\r\n        // Check for UTF-16 BOMs\r\n        if (m_input.size() >= sizeof(c_utf16LEBOM) && std::memcmp(m_input.data(), c_utf16LEBOM, sizeof(c_utf16LEBOM)) == 0)\r\n        {\r\n            AICLI_LOG(YAML, Verbose, << \"Found UTF-16 LE BOM\");\r\n            yaml_parser_set_encoding(&m_parser, YAML_UTF16LE_ENCODING); // Without the BOM, the encoding must be explicitly set\r\n            m_input.erase(0, sizeof(c_utf16LEBOM)); // Remove the BOM from the input\r\n            return;\r\n        }\r\n\r\n        if (m_input.size() >= sizeof(c_utf16BEBOM) && std::memcmp(m_input.data(), c_utf16BEBOM, sizeof(c_utf16BEBOM)) == 0)\r\n        {\r\n            AICLI_LOG(YAML, Verbose, << \"Found UTF-16 BE BOM\");\r\n            yaml_parser_set_encoding(&m_parser, YAML_UTF16BE_ENCODING); // Without the BOM, the encoding must be explicitly set\r\n            m_input.erase(0, sizeof(c_utf16BEBOM)); // Remove the BOM from the input\r\n            return;\r\n        }\r\n\r\n        // Check for UTF-8 BOM\r\n        if (m_input.size() >= sizeof(c_utf8BOM) && std::memcmp(m_input.data(), c_utf8BOM, sizeof(c_utf8BOM)) == 0)\r\n        {\r\n            AICLI_LOG(YAML, Verbose, << \"Found UTF-8 BOM\");\r\n            yaml_parser_set_encoding(&m_parser, YAML_UTF8_ENCODING); // Without the BOM, the encoding must be explicitly set\r\n            m_input.erase(0, sizeof(c_utf8BOM)); // Remove the BOM from the input\r\n            return;\r\n        }\r\n\r\n        // Check for BOM-less UTF-16 LE\r\n        INT expectedTests = IS_TEXT_UNICODE_ASCII16 | IS_TEXT_UNICODE_STATISTICS | IS_TEXT_UNICODE_CONTROLS;\r\n        INT testResults = expectedTests;\r\n        if (IsTextUnicode(m_input.data(), wil::safe_cast<int>(m_input.size()), &testResults) || testResults == expectedTests)\r\n        {\r\n            AICLI_LOG(YAML, Verbose, << \"Detected UTF-16 LE\");\r\n            yaml_parser_set_encoding(&m_parser, YAML_UTF16LE_ENCODING);\r\n            return;\r\n        }\r\n\r\n        // Check for BOM-less UTF-16 BE\r\n        expectedTests = IS_TEXT_UNICODE_REVERSE_ASCII16 | IS_TEXT_UNICODE_REVERSE_STATISTICS | IS_TEXT_UNICODE_REVERSE_CONTROLS;\r\n        testResults = expectedTests;\r\n        if (IsTextUnicode(m_input.data(), wil::safe_cast<int>(m_input.size()), &testResults) || testResults == expectedTests)\r\n        {\r\n            AICLI_LOG(YAML, Verbose, << \"Detected UTF-16 BE\");\r\n            yaml_parser_set_encoding(&m_parser, YAML_UTF16BE_ENCODING);\r\n            return;\r\n        }\r\n\r\n        // Check for BOM-less UTF-8\r\n        UINT nChars = MultiByteToWideChar(\r\n            CP_UTF8,\r\n            MB_ERR_INVALID_CHARS,\r\n            m_input.data(),\r\n            wil::safe_cast<int>(m_input.size()),\r\n            NULL,\r\n            0);\r\n\r\n        if (nChars > 0 || GetLastError() != ERROR_NO_UNICODE_TRANSLATION)\r\n        {\r\n            AICLI_LOG(YAML, Verbose, << \"Detected UTF-8\");\r\n            yaml_parser_set_encoding(&m_parser, YAML_UTF8_ENCODING);\r\n            return;\r\n        }\r\n\r\n        // Must be ANSI (Windows-1252 assumed), convert to UTF-8\r\n        AICLI_LOG(YAML, Verbose, << \"Assuming ANSI Windows-1252\");\r\n        std::wstring utf16 = Utility::ConvertToUTF16(m_input, 1252);\r\n        m_input = Utility::ConvertToUTF8(utf16);\r\n        yaml_parser_set_encoding(&m_parser, YAML_UTF8_ENCODING);\r\n    }\r\n\r\n    Event::~Event()\r\n    {\r\n        if (m_token)\r\n        {\r\n            yaml_event_delete(&m_event);\r\n        }\r\n    }\r\n\r\n    Event Event::StreamStart()\r\n    {\r\n        Event result;\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED, !yaml_stream_start_event_initialize(&result, YAML_UTF8_ENCODING));\r\n        result.m_token = true;\r\n        return result;\r\n    }\r\n\r\n    Event Event::StreamEnd()\r\n    {\r\n        Event result;\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED, !yaml_stream_end_event_initialize(&result));\r\n        result.m_token = true;\r\n        return result;\r\n    }\r\n\r\n    Event Event::DocumentStart()\r\n    {\r\n        Event result;\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED, !yaml_document_start_event_initialize(&result, NULL, NULL, NULL, 1));\r\n        result.m_token = true;\r\n        return result;\r\n    }\r\n\r\n    Event Event::DocumentEnd()\r\n    {\r\n        Event result;\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED, !yaml_document_end_event_initialize(&result, 1));\r\n        result.m_token = true;\r\n        return result;\r\n    }\r\n\r\n    Event Event::SequenceStart()\r\n    {\r\n        Event result;\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED, !yaml_sequence_start_event_initialize(&result, NULL, NULL, 1, YAML_ANY_SEQUENCE_STYLE));\r\n        result.m_token = true;\r\n        return result;\r\n    }\r\n\r\n    Event Event::SequenceEnd()\r\n    {\r\n        Event result;\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED, !yaml_sequence_end_event_initialize(&result));\r\n        result.m_token = true;\r\n        return result;\r\n    }\r\n\r\n    Event Event::MappingStart()\r\n    {\r\n        Event result;\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED, !yaml_mapping_start_event_initialize(&result, NULL, NULL, 1, YAML_ANY_MAPPING_STYLE));\r\n        result.m_token = true;\r\n        return result;\r\n    }\r\n\r\n    Event Event::MappingEnd()\r\n    {\r\n        Event result;\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED, !yaml_mapping_end_event_initialize(&result));\r\n        result.m_token = true;\r\n        return result;\r\n    }\r\n\r\n    Emitter::Emitter(std::ostream& output) :\r\n        m_token(true), m_outputStream(&output)\r\n    {\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED, !yaml_emitter_initialize(&m_emitter));\r\n        yaml_emitter_set_output(&m_emitter, StreamWriteHandler, this);\r\n        yaml_emitter_set_encoding(&m_emitter, YAML_UTF8_ENCODING);\r\n    }\r\n\r\n    Emitter::~Emitter()\r\n    {\r\n        if (m_token)\r\n        {\r\n            yaml_emitter_delete(&m_emitter);\r\n        }\r\n    }\r\n\r\n    void Emitter::Emit(Event& event)\r\n    {\r\n        event.Detach();\r\n        if (!yaml_emitter_emit(&m_emitter, &event))\r\n        {\r\n            ThrowError();\r\n        }\r\n    }\r\n\r\n    void Emitter::Emit(Event&& event)\r\n    {\r\n        event.Detach();\r\n        if (!yaml_emitter_emit(&m_emitter, &event))\r\n        {\r\n            ThrowError();\r\n        }\r\n    }\r\n\r\n    void Emitter::Dump(Document& document)\r\n    {\r\n        document.Detach();\r\n        if (!yaml_emitter_dump(&m_emitter, &document))\r\n        {\r\n            ThrowError();\r\n        }\r\n    }\r\n\r\n    void Emitter::Flush()\r\n    {\r\n        if (!yaml_emitter_flush(&m_emitter))\r\n        {\r\n            ThrowError();\r\n        }\r\n    }\r\n\r\n    int Emitter::StreamWriteHandler(\r\n        void* data,\r\n        unsigned char* buffer,\r\n        size_t size)\r\n    {\r\n        Emitter& emitter = *reinterpret_cast<Emitter*>(data);\r\n\r\n        try\r\n        {\r\n            emitter.m_outputStream->write(reinterpret_cast<char*>(buffer), size);\r\n        }\r\n        catch (...)\r\n        {\r\n            LOG_CAUGHT_EXCEPTION();\r\n            return 0;\r\n        }\r\n\r\n        return 1;\r\n    }\r\n\r\n    void Emitter::ThrowError()\r\n    {\r\n        Exception::Type type = ConvertErrorType(m_emitter.error);\r\n\r\n        switch (type)\r\n        {\r\n        case Exception::Type::Memory:\r\n            THROW_EXCEPTION(Exception(type));\r\n        case Exception::Type::Emitter:\r\n        case Exception::Type::Writer:\r\n            THROW_EXCEPTION(Exception(type, m_emitter.problem));\r\n        default:\r\n            THROW_EXCEPTION(Exception(type, \"An unexpected error type occurred in Emitter\"));\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/YamlWrapper.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <yaml.h>\r\n#include \"winget/Yaml.h\"\r\n#include \"AppInstallerLanguageUtilities.h\"\r\n#include \"AppInstallerSHA256.h\"\r\n\r\n#include <iostream>\r\n#include <string_view>\r\n#include <vector>\r\n\r\n\r\nnamespace AppInstaller::YAML::Wrapper\r\n{\r\n    // A libyaml yaml_document_t.\r\n    // A parsed document, created by the Parser.\r\n    struct Document\r\n    {\r\n        // Initializes the document.\r\n        Document(bool init = false);\r\n\r\n        Document(const Document&) = delete;\r\n        Document& operator=(const Document&) = delete;\r\n\r\n        Document(Document&&) noexcept = default;\r\n        Document& operator=(Document&&) noexcept = delete;\r\n\r\n        ~Document();\r\n\r\n        yaml_document_t* operator&() { return &m_document; }\r\n\r\n        // Indicates that the document should not be deleted, as\r\n        // it has been handed off to the emitter.\r\n        void Detach() { m_token = false; }\r\n\r\n        // Determines whether the document has a root node.\r\n        bool HasRoot();\r\n\r\n        // Gets the root node of the document, if it has one.\r\n        Node GetRoot();\r\n\r\n        // Adds a scalar node to the document.\r\n        int AddScalar(std::string_view value, ScalarStyle style = ScalarStyle::Any);\r\n\r\n        // Adds a sequence node to the document.\r\n        int AddSequence();\r\n\r\n        // Adds a mapping node to the document.\r\n        int AddMapping();\r\n\r\n        // Appends a node to the end of the sequence.\r\n        void AppendSequenceItem(int sequence, int item);\r\n\r\n        // Adds a pair to the mapping.\r\n        void AppendMappingPair(int mapping, int key, int value);\r\n\r\n    private:\r\n        // Gets the node referenced by the index.\r\n        yaml_node_t* GetNode(yaml_node_item_t index);\r\n\r\n        DestructionToken m_token;\r\n        yaml_document_t m_document;\r\n    };\r\n\r\n    // A libyaml yaml_parser_t.\r\n    // The core parser construct for reading bytes directly.\r\n    struct Parser\r\n    {\r\n        Parser(std::string_view input);\r\n        Parser(std::istream& input, Utility::SHA256::HashBuffer* hashOut = nullptr);\r\n\r\n        Parser(const Parser&) = delete;\r\n        Parser& operator=(const Parser&) = delete;\r\n\r\n        Parser(Parser&&) noexcept = default;\r\n        Parser& operator=(Parser&&) noexcept = delete;\r\n\r\n        ~Parser();\r\n\r\n        yaml_parser_t* operator&() { return &m_parser; }\r\n\r\n        // Loads the next document from the input, if one exists.\r\n        Document Load();\r\n\r\n        // Retrieves the input that was used to create the parser with the correct encoding scheme.\r\n        const std::string& GetEncodedInput() const { return m_input; }\r\n\r\n    private:\r\n        // Determines the type of encoding in use, transforming the input as necessary.\r\n        void PrepareInput();\r\n\r\n        DestructionToken m_token;\r\n        yaml_parser_t m_parser;\r\n        std::string m_input;\r\n    };\r\n\r\n    // A libyaml yaml_event_t.\r\n    // The generic event type for.\r\n    struct Event\r\n    {\r\n        Event(const Event&) = delete;\r\n        Event& operator=(const Event&) = delete;\r\n\r\n        Event(Event&&) noexcept = default;\r\n        Event& operator=(Event&&) noexcept = delete;\r\n\r\n        ~Event();\r\n\r\n        yaml_event_t* operator&() { return &m_event; }\r\n\r\n        // Indicates that the event should not be deleted, as\r\n        // it has been handed off to the emitter.\r\n        void Detach() { m_token = false; }\r\n\r\n        // Event creation functions.\r\n        static Event StreamStart();\r\n        static Event StreamEnd();\r\n        static Event DocumentStart();\r\n        static Event DocumentEnd();\r\n        static Event SequenceStart();\r\n        static Event SequenceEnd();\r\n        static Event MappingStart();\r\n        static Event MappingEnd();\r\n\r\n    private:\r\n        Event() = default;\r\n\r\n        DestructionToken m_token;\r\n        yaml_event_t m_event = {};\r\n    };\r\n\r\n    // A libyaml yaml_emitter_t.\r\n    // Allows YAML to be written out.\r\n    struct Emitter\r\n    {\r\n        Emitter(std::ostream& output);\r\n\r\n        Emitter(const Emitter&) = delete;\r\n        Emitter& operator=(const Emitter&) = delete;\r\n\r\n        Emitter(Emitter&&) noexcept = default;\r\n        Emitter& operator=(Emitter&&) noexcept = delete;\r\n\r\n        ~Emitter();\r\n\r\n        yaml_emitter_t* operator&() { return &m_emitter; }\r\n\r\n        // Emits and event.\r\n        void Emit(Event& event);\r\n        void Emit(Event&& event);\r\n\r\n        // Dumps a document to the emitter.\r\n        void Dump(Document& document);\r\n\r\n        // Flushes the emitter.\r\n        void Flush();\r\n\r\n    private:\r\n        static int StreamWriteHandler(\r\n            void* data,\r\n            unsigned char* buffer,\r\n            size_t size);\r\n\r\n        void ThrowError();\r\n\r\n        DestructionToken m_token;\r\n        yaml_emitter_t m_emitter;\r\n        std::ostream* m_outputStream = nullptr;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerSharedLib/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<packages>\r\n  <package id=\"Microsoft.Windows.CppWinRT\" version=\"2.0.250303.1\" targetFramework=\"native\" />\r\n  <package id=\"Microsoft.Windows.ImplementationLibrary\" version=\"1.0.250325.1\" targetFramework=\"native\" />\r\n</packages>"
  },
  {
    "path": "src/AppInstallerSharedLib/pch.cpp",
    "content": "﻿// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n"
  },
  {
    "path": "src/AppInstallerSharedLib/pch.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n\n#define NOMINMAX\n#include <Windows.h>\n#include <AclAPI.h>\n#include <appmodel.h>\n#include <icu.h>\n#include <sddl.h>\n#include <Shlobj.h>\n#include <compressapi.h>\n#include <concurrencysal.h>\n\n#define YAML_DECLARE_STATIC\n#include <yaml.h>\n\n// TODO: See if we can get down to having just one JSON parser...\n#include <json/json.h>\n\n#pragma warning( push )\n#pragma warning ( disable : 4458 4100 4702 6031 26439 )\n#include <valijson/schema.hpp>\n#include <valijson/schema_parser.hpp>\n#include <valijson/validator.hpp>\n#include <valijson/adapters/jsoncpp_adapter.hpp>\n#pragma warning( pop )\n\n#include <algorithm>\n#include <chrono>\n#include <cwctype>\n#include <filesystem>\n#include <fstream>\n#include <functional>\n#include <iomanip>\n#include <limits>\n#include <map>\n#include <memory>\n#include <mutex>\n#include <optional>\n#include <ostream>\r\n#include <random>\n#include <set>\n#include <string>\n#include <sstream>\n#include <string_view>\n#include <type_traits>\n#include <vector>\n\n#pragma warning( push )\n#pragma warning ( disable : 6001 6285 6287 6340 6387 6388 26495 28196 )\n#include <wil/resource.h>\n#include <wil/result.h>\n#include <wil/result_macros.h>\n#include <wil/safecast.h>\n#include <wil/token_helpers.h>\n#include <wil/com.h>\n#include <wil/filesystem.h>\n#pragma warning( pop )\n\n#include <wil/cppwinrt.h>\r\n#include <winrt/Windows.ApplicationModel.Core.h>\n#include <winrt/Windows.ApplicationModel.Resources.h>\n#include <winrt/Windows.Foundation.h>\n#include <winrt/Windows.Foundation.Collections.h>\n#include <winrt/Windows.Globalization.h>\n#include <winrt/Windows.System.Profile.h>\n"
  },
  {
    "path": "src/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <PropertyGroup Label=\"Globals\">\r\n    <VCProjectVersion>15.0</VCProjectVersion>\r\n    <ProjectGuid>{6CB84692-5994-407D-B9BD-9216AF77FE83}</ProjectGuid>\r\n    <Keyword>Win32Proj</Keyword>\r\n    <RootNamespace>AppInstallerTestExeInstaller</RootNamespace>\r\n    <WindowsTargetPlatformVersion>10.0.26100.0</WindowsTargetPlatformVersion>\r\n    <WindowsTargetPlatformMinVersion>10.0.17763.0</WindowsTargetPlatformMinVersion>\r\n    <WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|Win32\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|Win32\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|ARM64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|ARM64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <PropertyGroup Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\r\n  <ImportGroup Label=\"ExtensionSettings\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"Shared\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <Import Project=\"$(ProjectDir)\\..\\vcpkg.props\" />\r\n  <PropertyGroup Label=\"UserMacros\" />\r\n  <ItemDefinitionGroup>\r\n    <ClCompile>\r\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>\r\n      <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>\r\n      <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <AdditionalOptions>%(AdditionalOptions) /permissive- /bigobj /Zi</AdditionalOptions>\r\n    </ClCompile>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Debug'\">\r\n    <ClCompile>\r\n      <Optimization>Disabled</Optimization>\r\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</TreatWarningAsError>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">stdcpp17</LanguageStandard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">stdcpp17</LanguageStandard>\r\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Platform)'=='Win32'\">\r\n    <ClCompile>\r\n      <PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</TreatWarningAsError>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">stdcpp17</LanguageStandard>\r\n    </ClCompile>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Release'\">\r\n    <ClCompile>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">true</TreatWarningAsError>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">stdcpp17</LanguageStandard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">stdcpp17</LanguageStandard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">stdcpp17</LanguageStandard>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"main.cpp\" />\r\n  </ItemGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\r\n  <ImportGroup Label=\"ExtensionTargets\">\r\n  </ImportGroup>\r\n  <Target Name=\"AfterBuild\">\r\n    <Copy SourceFiles=\"$(OutDir)\\$(TargetFileName)\" DestinationFolder=\"$(OutDir)\\..\\AppInstallerCLITests\" ContinueOnError=\"true\" />\r\n  </Target>\r\n</Project>"
  },
  {
    "path": "src/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup>\r\n    <Filter Include=\"Source Files\">\r\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Header Files\">\r\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r\n      <Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Resource Files\">\r\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\r\n    </Filter>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"main.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n  </ItemGroup>\r\n</Project>"
  },
  {
    "path": "src/AppInstallerTestExeInstaller/main.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n\r\n#include <windows.h>\r\n#include <winreg.h>\r\n#include <winerror.h>\r\n#include <initializer_list>\r\n#include <iostream>\r\n#include <fstream>\r\n#include <filesystem>\r\n#include <sstream>\r\n\r\nusing namespace std::filesystem;\r\n\r\nstd::wstring_view RegistrySubkey = L\"SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Uninstall\\\\\";\r\nstd::wstring_view DefaultProductID = L\"{A499DD5E-8DC5-4AD2-911A-BCD0263295E9}\";\r\nstd::wstring_view DefaultDisplayName = L\"AppInstallerTestExeInstaller\";\r\nstd::wstring_view DefaultDisplayVersion = L\"1.0.0.0\";\r\nstd::wstring_view DscSubDirectoryName = L\"SubDirectory\";\r\n\r\nvoid WriteModifyRepairScript(std::wofstream& script, const path& repairCompletedTextFilePath, bool isModifyScript) {\r\n    std::wstring scriptName = isModifyScript ? L\"Modify\" : L\"Uninstaller\";\r\n    script << L\"    if /I \\\"%%A\\\"==\\\"/repair\\\" (\\n\"\r\n        << L\"        ECHO \" << scriptName << L\" Repair operation for AppInstallerTestExeInstaller.exe completed successfully > \\\"\" << repairCompletedTextFilePath.wstring() << \"\\\"\\n\"\r\n        << L\"        ECHO \" << scriptName << L\" Repair operation for AppInstallerTestExeInstaller.exe completed successfully\\n\"\r\n        << L\"        EXIT /B 0\\n\"\r\n        << L\"    ) else if /I \\\"%%A\\\"==\\\"/r\\\" (\\n\"\r\n        << L\"        ECHO \" << scriptName << L\" Repair operation for AppInstallerTestExeInstaller.exe completed successfully > \\\"\" << repairCompletedTextFilePath.wstring() << \"\\\"\\n\"\r\n        << L\"        ECHO \" << scriptName << L\" Repair operation for AppInstallerTestExeInstaller.exe completed successfully\\n\"\r\n        << L\"        EXIT /B 0\\n\"\r\n        << L\"    )\";\r\n}\r\n\r\nvoid WriteModifyUninstallScript(std::wofstream& script) {\r\n    script << L\"    else if /I \\\"%%A\\\"==\\\"/uninstall\\\" (\\n\"\r\n        << L\"        call UninstallTestExe.bat\\n\"\r\n        << L\"        EXIT /B 0\\n\"\r\n        << L\"    ) else if /I \\\"%%A\\\"==\\\"/X\\\" (\\n\"\r\n        << L\"        call UninstallTestExe.bat\\n\"\r\n        << L\"        EXIT /B 0\\n\"\r\n        << L\"    )\\n\";\r\n}\r\n\r\nvoid WriteModifyInvalidOperationScript(std::wofstream& script) {\r\n    script << L\"echo Invalid operation\\n\"\r\n        << L\"EXIT /B 1\\n\";\r\n}\r\n\r\nvoid WriteUninstallerScript(\r\n    std::wofstream& uninstallerScript,\r\n    const path& uninstallerOutputTextFilePath,\r\n    const std::wstring& registryKey,\r\n    std::initializer_list<path> paths) {\r\n    uninstallerScript << \"ECHO. >\" << uninstallerOutputTextFilePath << \"\\n\";\r\n    uninstallerScript << \"ECHO AppInstallerTestExeInstaller.exe uninstalled successfully.\\n\";\r\n    uninstallerScript << \"REG DELETE \" << registryKey << \" /f\\n\";\r\n\r\n    for (const auto& path : paths)\r\n    {\r\n        std::wstring pathString = path.wstring();\r\n        uninstallerScript << \"if exist \\\"\" << pathString << \"\\\" del \\\"\" << pathString << \"\\\"\\n\";\r\n    }\r\n}\r\n\r\npath GenerateUninstaller(std::wostream& out, const path& installDirectory, const std::wstring& productID, bool useHKLM)\r\n{\r\n    path uninstallerPath = installDirectory;\r\n    uninstallerPath /= \"UninstallTestExe.bat\";\r\n\r\n    out << \"Uninstaller located at path: \" << uninstallerPath << std::endl;\r\n\r\n    path uninstallerOutputTextFilePath = installDirectory;\r\n    uninstallerOutputTextFilePath /= \"TestExeUninstalled.txt\";\r\n\r\n    path repairCompletedTextFilePath = installDirectory;\r\n    repairCompletedTextFilePath /= \"TestExeRepairCompleted.txt\";\r\n\r\n    std::wstring registryKey{ useHKLM ? L\"HKEY_LOCAL_MACHINE\\\\\" : L\"HKEY_CURRENT_USER\\\\\" };\r\n    registryKey += RegistrySubkey;\r\n    if (!productID.empty())\r\n    {\r\n        registryKey += productID;\r\n    }\r\n    else\r\n    {\r\n        registryKey += DefaultProductID;\r\n    }\r\n\r\n    std::wofstream uninstallerScript(uninstallerPath);\r\n    uninstallerScript << \"@echo off\\n\";\r\n    uninstallerScript << L\"for %%A in (%*) do (\\n\";\r\n    WriteModifyRepairScript(uninstallerScript, repairCompletedTextFilePath, false /*isModifyScript*/);\r\n    uninstallerScript << \")\\n\";\r\n    WriteUninstallerScript(uninstallerScript, uninstallerOutputTextFilePath, registryKey,\r\n        {\r\n            installDirectory / \"ModifyTestExe.bat\",\r\n            repairCompletedTextFilePath,\r\n            installDirectory / \"AppInstallerTestResource.exe\",\r\n            installDirectory / \"AppInstallerTest.dsc.resource.json\",\r\n            installDirectory / DscSubDirectoryName / \"AppInstallerTestResource.exe\",\r\n            installDirectory / DscSubDirectoryName / \"AppInstallerTest.dsc.resource.json\",\r\n        });\r\n\r\n    uninstallerScript.close();\r\n\r\n    return uninstallerPath;\r\n}\r\n\r\npath GenerateModifyPath(const path& installDirectory)\r\n{\r\n    path modifyScriptPath = installDirectory;\r\n    modifyScriptPath /= \"ModifyTestExe.bat\";\r\n\r\n    path repairCompletedTextFilePath = installDirectory;\r\n    repairCompletedTextFilePath /= \"TestExeRepairCompleted.txt\";\r\n\r\n    std::wofstream modifyScript(modifyScriptPath);\r\n\r\n    modifyScript << L\"@echo off\\n\";\r\n    modifyScript << L\"for %%A in (%*) do (\\n\";\r\n    WriteModifyRepairScript(modifyScript, repairCompletedTextFilePath, true /*isModifyScript*/);\r\n    WriteModifyUninstallScript(modifyScript);\r\n    modifyScript << L\")\\n\";\r\n    WriteModifyInvalidOperationScript(modifyScript);\r\n\r\n    modifyScript.close();\r\n\r\n    return modifyScriptPath;\r\n}\r\n\r\nvoid GenerateDSCv3ProviderFiles(const path& installDirectory, const std::wstring_view subDirectory)\r\n{\r\n    path dscResourceExecutablePath = installDirectory;\r\n    if (!subDirectory.empty())\r\n    {\r\n        dscResourceExecutablePath /= subDirectory;\r\n        std::filesystem::create_directories(dscResourceExecutablePath);\r\n    }\r\n    dscResourceExecutablePath /= \"AppInstallerTestResource.exe\";\r\n\r\n    WCHAR currentExecutable[MAX_PATH];\r\n    GetModuleFileName(nullptr, currentExecutable, MAX_PATH);\r\n    path currentExecutablePath{ currentExecutable };\r\n    copy_file(currentExecutablePath, dscResourceExecutablePath);\r\n\r\n    path dscResourceManifestPath = installDirectory;\r\n    if (!subDirectory.empty())\r\n    {\r\n        dscResourceManifestPath /= subDirectory;\r\n    }\r\n    dscResourceManifestPath /= \"AppInstallerTest.dsc.resource.json\";\r\n\r\n    std::wstring DscResourceJsonContent =\r\n        LR\"(\r\n    {\r\n        \"$schema\" : \"https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/bundled/resource/manifest.json\",\r\n        \"description\" : \"AppInstallerTest dsc Resource.\",\r\n        \"export\" :\r\n        {\r\n            \"args\" :\r\n            [\r\n                \"/DscExport\"\r\n            ],\r\n            \"executable\" : \"AppInstallerTestResource.exe\"\r\n        },\r\n        \"get\" :\r\n        {\r\n            \"args\" :\r\n            [\r\n                \"/DscGet\"\r\n            ],\r\n            \"executable\" : \"AppInstallerTestResource.exe\",\r\n            \"input\" : \"stdin\"\r\n        },\r\n        \"set\" :\r\n        {\r\n            \"args\" :\r\n            [\r\n                \"/DscSet\"\r\n            ] ,\r\n            \"executable\" : \"AppInstallerTestResource.exe\",\r\n            \"handlesExist\" : true,\r\n            \"implementsPretest\" : true,\r\n            \"input\" : \"stdin\",\r\n            \"return\" : \"state\"\r\n        },\r\n        \"test\" :\r\n        {\r\n            \"args\" :\r\n            [\r\n                \"/DscTest\"\r\n            ] ,\r\n            \"executable\" : \"AppInstallerTestResource.exe\",\r\n            \"input\" : \"stdin\",\r\n            \"return\" : \"state\"\r\n        },\r\n        \"schema\": {\r\n            \"embedded\": {\r\n                \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n                \"title\": \"AppInstallerTestResource\",\r\n                \"description\": \"App Installer Test Resource\",\r\n                \"type\": \"object\",\r\n                \"required\": [],\r\n                \"additionalProperties\": false,\r\n                \"properties\": {\r\n                    \"_inDesiredState\": {\r\n                        \"description\": \"Indicates whether an instance is in the desired state.\",\r\n                        \"type\": \"boolean\"\r\n                    },\r\n                    \"data\": {\r\n                        \"type\": \"string\",\r\n                        \"description\": \"Test data.\"\r\n                    }\r\n                }\r\n            }\r\n        },\r\n        \"type\" : \"AppInstallerTest/TestResource)\";\r\n\r\n    if (!subDirectory.empty())\r\n    {\r\n        DscResourceJsonContent += '.';\r\n        DscResourceJsonContent += subDirectory;\r\n    }\r\n\r\n        DscResourceJsonContent += LR\"(\",\r\n        \"version\" : \"1.0.0\"\r\n    }\r\n        )\";\r\n\r\n\r\n    std::wofstream dscResourceJson(dscResourceManifestPath);\r\n    dscResourceJson << DscResourceJsonContent;\r\n    dscResourceJson.close();\r\n}\r\n\r\nvoid WriteToUninstallRegistry(\r\n    std::wostream& out,\r\n    const std::wstring& productID,\r\n    const path& uninstallerPath,\r\n    const path& modifyPath,\r\n    const std::wstring& displayName,\r\n    const std::wstring& displayVersion,\r\n    const std::wstring& installLocation,\r\n    bool useHKLM,\r\n    bool noRepair,\r\n    bool noModify)\r\n{\r\n    HKEY hkey;\r\n    LONG lReg;\r\n\r\n    // String inputs to registry must be of wide char type\r\n    const wchar_t* publisher = L\"Microsoft Corporation\";\r\n    std::wstring uninstallString = uninstallerPath.wstring();\r\n    std::wstring modifyPathString = modifyPath.wstring();\r\n\r\n    DWORD version = 1;\r\n\r\n    std::wstring registryKey{ RegistrySubkey };\r\n\r\n    if (!productID.empty())\r\n    {\r\n        registryKey += productID;\r\n        out << \"Product Code overridden to: \" << registryKey << std::endl;\r\n    }\r\n    else\r\n    {\r\n        registryKey += DefaultProductID;\r\n        out << \"Default Product Code used: \" << registryKey << std::endl;\r\n    }\r\n\r\n    lReg = RegCreateKeyEx(\r\n        useHKLM ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,\r\n        registryKey.c_str(),\r\n        0,\r\n        NULL,\r\n        REG_OPTION_NON_VOLATILE,\r\n        KEY_ALL_ACCESS,\r\n        NULL,\r\n        &hkey,\r\n        NULL);\r\n\r\n    if (lReg == ERROR_SUCCESS)\r\n    {\r\n        out << \"Successfully opened registry key\" << std::endl;\r\n\r\n        // Set Display Name Property Value\r\n        if (LONG res = RegSetValueEx(hkey, L\"DisplayName\", NULL, REG_SZ, (LPBYTE)displayName.c_str(), (DWORD)(displayName.length() + 1) * sizeof(wchar_t)) != ERROR_SUCCESS)\r\n        {\r\n            out << \"Failed to write DisplayName value. Error Code: \" << res << std::endl;\r\n        }\r\n\r\n        // Set Display Version Property Value\r\n        if (LONG res = RegSetValueEx(hkey, L\"DisplayVersion\", NULL, REG_SZ, (LPBYTE)displayVersion.c_str(), (DWORD)(displayVersion.length() + 1) * sizeof(wchar_t)) != ERROR_SUCCESS)\r\n        {\r\n            out << \"Failed to write DisplayVersion value. Error Code: \" << res << std::endl;\r\n        }\r\n\r\n        // Set Publisher Property Value\r\n        if (LONG res = RegSetValueEx(hkey, L\"Publisher\", NULL, REG_SZ, (LPBYTE)publisher, (DWORD)(wcslen(publisher) + 1) * sizeof(wchar_t)) != ERROR_SUCCESS)\r\n        {\r\n            out << \"Failed to write Publisher value. Error Code: \" << res << std::endl;\r\n        }\r\n\r\n        // Set UninstallString Property Value\r\n        if (LONG res = RegSetValueEx(hkey, L\"UninstallString\", NULL, REG_EXPAND_SZ, (LPBYTE)uninstallString.c_str(), (DWORD)(uninstallString.length() + 1) * sizeof(wchar_t)) != ERROR_SUCCESS)\r\n        {\r\n            out << \"Failed to write UninstallString value. Error Code: \" << res << std::endl;\r\n        }\r\n\r\n        // Set Version Property Value\r\n        if (LONG res = RegSetValueEx(hkey, L\"Version\", NULL, REG_DWORD, (LPBYTE)&version, sizeof(version)) != ERROR_SUCCESS)\r\n        {\r\n            out << \"Failed to write Version value. Error Code: \" << res << std::endl;\r\n        }\r\n\r\n        // Set InstallLocation Property Value\r\n        if (LONG res = RegSetValueEx(hkey, L\"InstallLocation\", NULL, REG_SZ, (LPBYTE)installLocation.c_str(), (DWORD)(installLocation.length() + 1) * sizeof(wchar_t)) != ERROR_SUCCESS)\r\n        {\r\n            out << \"Failed to write InstallLocation value. Error Code: \" << res << std::endl;\r\n        }\r\n\r\n        // Set ModifyPath Property Value\r\n        if (LONG res = RegSetValueEx(hkey, L\"ModifyPath\", NULL, REG_EXPAND_SZ, (LPBYTE)modifyPathString.c_str(), (DWORD)(modifyPathString.length() + 1) * sizeof(wchar_t)) != ERROR_SUCCESS)\r\n        {\r\n            out << \"Failed to write ModifyPath value. Error Code: \" << res << std::endl;\r\n        }\r\n\r\n        if(noRepair)\r\n        {\r\n            // Set NoRepair Property Value\r\n            DWORD noRepairValue = 1;\r\n            if (LONG res = RegSetValueEx(hkey, L\"NoRepair\", NULL, REG_DWORD, (LPBYTE)&noRepairValue, sizeof(noRepairValue)) != ERROR_SUCCESS)\r\n            {\r\n                out << \"Failed to write NoRepair value. Error Code: \" << res << std::endl;\r\n            }\r\n        }\r\n\r\n        if(noModify)\r\n        {\r\n            // Set NoModify Property Value\r\n            DWORD noModifyValue = 1;\r\n            if (LONG res = RegSetValueEx(hkey, L\"NoModify\", NULL, REG_DWORD, (LPBYTE)&noModifyValue, sizeof(noModifyValue)) != ERROR_SUCCESS)\r\n            {\r\n                out << \"Failed to write NoModify value. Error Code: \" << res << std::endl;\r\n            }\r\n        }\r\n\r\n        out << \"Write to registry key completed\" << std::endl;\r\n    }\r\n    else {\r\n        out << \"Key Creation Failed\" << std::endl;\r\n    }\r\n\r\n    RegCloseKey(hkey);\r\n}\r\n\r\nvoid WriteToFile(const path& filePath, const std::wstringstream& content)\r\n{\r\n    std::wofstream file(filePath, std::ofstream::out);\r\n    file << content.str();\r\n    file.close();\r\n}\r\n\r\nvoid HandleRepairOperation(const std::wstring& productID, const std::wstringstream& outContent, bool useHKLM)\r\n{\r\n    path installDirectory;\r\n\r\n    // Open the registry key\r\n    HKEY hKey;\r\n    std::wstring registryPath = std::wstring(RegistrySubkey);\r\n\r\n    if (!productID.empty())\r\n    {\r\n        registryPath += productID;\r\n    }\r\n    else\r\n    {\r\n        registryPath += DefaultProductID;\r\n    }\r\n\r\n    LONG lReg = RegOpenKeyEx(useHKLM ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, registryPath.c_str(), 0, KEY_READ, &hKey);\r\n\r\n    if (lReg == ERROR_SUCCESS)\r\n    {\r\n        // Query the value of the InstallLocation\r\n        wchar_t regInstallLocation[MAX_PATH];\r\n        DWORD bufferSize = sizeof(regInstallLocation);\r\n        lReg = RegQueryValueEx(hKey, L\"InstallLocation\", NULL, NULL, (LPBYTE)regInstallLocation, &bufferSize);\r\n\r\n        if (lReg == ERROR_SUCCESS)\r\n        {\r\n            // Convert the InstallLocation to a path\r\n            installDirectory = std::wstring(regInstallLocation);\r\n        }\r\n\r\n        // Close the registry key\r\n        RegCloseKey(hKey);\r\n\r\n        if(installDirectory.empty())\r\n        {\r\n            // We could not find the install location, so we cannot repair\r\n            return;\r\n        }\r\n    }\r\n    else\r\n    {\r\n        // We could not find the uninstall APR registry key, so we cannot repair\r\n        return;\r\n    }\r\n\r\n    path outFilePath = installDirectory;\r\n    outFilePath /= \"TestExeRepairCompleted.txt\";\r\n    WriteToFile(outFilePath, outContent);\r\n}\r\n\r\nvoid HandleInstallationOperation(\r\n    std::wostream& out,\r\n    const path& installDirectory,\r\n    const std::wstringstream& outContent,\r\n    const std::wstring& productCode,\r\n    bool useHKLM,\r\n    const std::wstring& displayName,\r\n    const std::wstring& displayVersion,\r\n    bool noRepair,\r\n    bool noModify,\r\n    bool generateDscResourceFiles)\r\n{\r\n    path outFilePath = installDirectory;\r\n    outFilePath /= \"TestExeInstalled.txt\";\r\n\r\n    std::wofstream file(outFilePath, std::ofstream::out);\r\n    file << outContent.str();\r\n    file.close();\r\n\r\n    if (generateDscResourceFiles)\r\n    {\r\n        GenerateDSCv3ProviderFiles(installDirectory, {});\r\n        GenerateDSCv3ProviderFiles(installDirectory, DscSubDirectoryName);\r\n    }\r\n\r\n    path uninstallerPath = GenerateUninstaller(out, installDirectory, productCode, useHKLM);\r\n    path modifyPath = GenerateModifyPath(installDirectory);\r\n\r\n    WriteToUninstallRegistry(out, productCode, uninstallerPath, modifyPath, displayName, displayVersion, installDirectory.wstring(), useHKLM, noRepair, noModify);\r\n}\r\n\r\n// The installer prints all args to an output file and writes to the Uninstall registry key\r\nint wmain(int argc, const wchar_t** argv)\r\n{\r\n    path installDirectory = temp_directory_path();\r\n    std::wstringstream outContent;\r\n    std::wstring productCode;\r\n    std::wstring displayName;\r\n    std::wstring displayVersion;\r\n    std::wstring aliasToExecute;\r\n    std::wstring aliasArguments;\r\n    bool useHKLM = false;\r\n    bool noOperation = false;\r\n    int exitCode = 0;\r\n    bool isRepair = false;\r\n    bool noRepair = false;\r\n    bool noModify = false;\r\n    bool generateDscResourceFiles = false;\r\n\r\n    // Output to cout by default, but swap to a file if requested\r\n    std::wostream* out = &std::wcout;\r\n    std::wofstream logFile;\r\n\r\n    for (int i = 1; i < argc; i++)\r\n    {\r\n        outContent << argv[i] << ' ';\r\n\r\n        // Supports custom install path.\r\n        if (_wcsicmp(argv[i], L\"/InstallDir\") == 0)\r\n        {\r\n            if (++i < argc)\r\n            {\r\n                installDirectory = argv[i];\r\n                std::filesystem::create_directories(installDirectory);\r\n                outContent << argv[i] << ' ';\r\n            }\r\n        }\r\n\r\n        // Supports custom exit code\r\n        else if (_wcsicmp(argv[i], L\"/ExitCode\") == 0)\r\n        {\r\n            if (++i < argc)\r\n            {\r\n                exitCode = static_cast<int>(std::stoll(argv[i], 0, 0));\r\n                outContent << argv[i] << ' ';\r\n            }\r\n        }\r\n\r\n        // Supports custom product code ID\r\n        else if (_wcsicmp(argv[i], L\"/ProductID\") == 0)\r\n        {\r\n            if (++i < argc)\r\n            {\r\n                productCode = argv[i];\r\n                outContent << argv[i] << ' ';\r\n            }\r\n        }\r\n\r\n        // Supports custom DisplayName\r\n        else if (_wcsicmp(argv[i], L\"/DisplayName\") == 0)\r\n        {\r\n            if (++i < argc)\r\n            {\r\n                displayName = argv[i];\r\n                outContent << argv[i] << ' ';\r\n            }\r\n        }\r\n\r\n        // Supports custom version\r\n        else if (_wcsicmp(argv[i], L\"/Version\") == 0)\r\n        {\r\n            if (++i < argc)\r\n            {\r\n                displayVersion = argv[i];\r\n                outContent << argv[i] << ' ';\r\n            }\r\n        }\r\n\r\n        // Supports log file\r\n        else if (_wcsicmp(argv[i], L\"/LogFile\") == 0)\r\n        {\r\n            if (++i < argc)\r\n            {\r\n                logFile = std::wofstream(argv[i], std::wofstream::out | std::wofstream::trunc);\r\n                out = &logFile;\r\n                outContent << argv[i] << ' ';\r\n            }\r\n        }\r\n\r\n        // Writes to HKLM\r\n        else if (_wcsicmp(argv[i], L\"/UseHKLM\") == 0)\r\n        {\r\n            useHKLM = true;\r\n        }\r\n\r\n        // Executes a command alias during installation\r\n        else if (_wcsicmp(argv[i], L\"/AliasToExecute\") == 0)\r\n        {\r\n            if (++i < argc)\r\n            {\r\n                aliasToExecute = argv[i];\r\n                outContent << argv[i] << ' ';\r\n            }\r\n        }\r\n\r\n        // Additional arguments to include when executing the command alias during installation\r\n        else if (_wcsicmp(argv[i], L\"/AliasArguments\") == 0)\r\n        {\r\n            if (++i < argc)\r\n            {\r\n                aliasArguments = argv[i];\r\n                outContent << argv[i] << ' ';\r\n            }\r\n        }\r\n\r\n        // Supports /repair and /r to emulate repair operation using installer.\r\n        else if (_wcsicmp(argv[i], L\"/repair\") == 0\r\n            || _wcsicmp(argv[i], L\"/r\") == 0)\r\n        {\r\n            isRepair = true;\r\n        }\r\n\r\n        else if (_wcsicmp(argv[i], L\"/NoRepair\") == 0)\r\n        {\r\n            noRepair = true;\r\n        }\r\n\r\n        else if (_wcsicmp(argv[i], L\"/NoModify\") == 0)\r\n        {\r\n            noModify = true;\r\n        }\r\n\r\n        // Returns the success exit code to emulate being invoked by another caller.\r\n        else if (_wcsicmp(argv[i], L\"/NoOperation\") == 0)\r\n        {\r\n            noOperation = true;\r\n        }\r\n\r\n        // Also output dsc resource files\r\n        else if (_wcsicmp(argv[i], L\"/GenerateDscResourceFiles\") == 0)\r\n        {\r\n            generateDscResourceFiles = true;\r\n        }\r\n\r\n        // Dsc resource get\r\n        else if (_wcsicmp(argv[i], L\"/DscGet\") == 0)\r\n        {\r\n            std::cout << R\"({\"data\":\"TestData\"})\" << std::endl;\r\n            return 0;\r\n        }\r\n\r\n        // Dsc resource set\r\n        else if (_wcsicmp(argv[i], L\"/DscSet\") == 0)\r\n        {\r\n            std::cout << R\"({\"_inDesiredState\":true})\" << std::endl;\r\n            return 0;\r\n        }\r\n\r\n        // Dsc resource test\r\n        else if (_wcsicmp(argv[i], L\"/DscTest\") == 0)\r\n        {\r\n            std::cout << R\"({\"_inDesiredState\":true})\" << std::endl;\r\n            return 0;\r\n        }\r\n\r\n        // Dsc resource export\r\n        else if (_wcsicmp(argv[i], L\"/DscExport\") == 0)\r\n        {\r\n            std::cout << R\"({\"data\":\"TestData\"})\" << std::endl;\r\n            return 0;\r\n        }\r\n    }\r\n\r\n    if (noOperation)\r\n    {\r\n        return exitCode;\r\n    }\r\n\r\n    if (!aliasToExecute.empty())\r\n    {\r\n        SHELLEXECUTEINFOW execInfo = { 0 };\r\n        execInfo.cbSize = sizeof(execInfo);\r\n        execInfo.fMask = SEE_MASK_NOCLOSEPROCESS;\r\n        execInfo.lpFile = aliasToExecute.c_str();\r\n\r\n        if (!aliasArguments.empty())\r\n        {\r\n            execInfo.lpParameters = aliasArguments.c_str();\r\n        }\r\n        execInfo.nShow = SW_SHOW;\r\n\r\n        if (!ShellExecuteExW(&execInfo) || !execInfo.hProcess)\r\n        {\r\n            return -1;\r\n        }\r\n    }\r\n\r\n    if (displayName.empty())\r\n    {\r\n        displayName = DefaultDisplayName;\r\n    }\r\n\r\n    if (displayVersion.empty())\r\n    {\r\n        displayVersion = DefaultDisplayVersion;\r\n    }\r\n\r\n    path outFilePath = installDirectory;\r\n\r\n    if (isRepair)\r\n    {\r\n        outContent << L\"\\nInstaller Repair operation for AppInstallerTestExeInstaller.exe completed successfully.\";\r\n        HandleRepairOperation(productCode, outContent, useHKLM);\r\n    }\r\n    else\r\n    {\r\n        HandleInstallationOperation(*out, installDirectory, outContent, productCode, useHKLM, displayName, displayVersion, noRepair, noModify, generateDscResourceFiles);\r\n    }\r\n\r\n    return exitCode;\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerTestMsiInstaller/AppInstallerTestMsiInstaller.vdproj",
    "content": "﻿\"DeployProject\"\r\n{\r\n\"VSVersion\" = \"3:800\"\r\n\"ProjectType\" = \"8:{978C614F-708E-4E1A-B201-565925725DBA}\"\r\n\"IsWebType\" = \"8:FALSE\"\r\n\"ProjectName\" = \"8:AppInstallerTestMsiInstaller\"\r\n\"LanguageId\" = \"3:1033\"\r\n\"CodePage\" = \"3:1252\"\r\n\"UILanguageId\" = \"3:1033\"\r\n\"SccProjectName\" = \"8:\"\r\n\"SccLocalPath\" = \"8:\"\r\n\"SccAuxPath\" = \"8:\"\r\n\"SccProvider\" = \"8:\"\r\n    \"Hierarchy\"\r\n    {\r\n    }\r\n    \"Configurations\"\r\n    {\r\n        \"Debug\"\r\n        {\r\n        \"DisplayName\" = \"8:Debug\"\r\n        \"IsDebugOnly\" = \"11:TRUE\"\r\n        \"IsReleaseOnly\" = \"11:FALSE\"\r\n        \"OutputFilename\" = \"8:Debug\\\\AppInstallerTestMsiInstaller.msi\"\r\n        \"PackageFilesAs\" = \"3:2\"\r\n        \"PackageFileSize\" = \"3:-2147483648\"\r\n        \"CabType\" = \"3:1\"\r\n        \"Compression\" = \"3:2\"\r\n        \"SignOutput\" = \"11:FALSE\"\r\n        \"CertificateFile\" = \"8:\"\r\n        \"PrivateKeyFile\" = \"8:\"\r\n        \"TimeStampServer\" = \"8:\"\r\n        \"InstallerBootstrapper\" = \"3:2\"\r\n            \"BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}\"\r\n            {\r\n            \"Enabled\" = \"11:TRUE\"\r\n            \"PromptEnabled\" = \"11:TRUE\"\r\n            \"PrerequisitesLocation\" = \"2:1\"\r\n            \"Url\" = \"8:\"\r\n            \"ComponentsUrl\" = \"8:\"\r\n                \"Items\"\r\n                {\r\n                    \"{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:.NETFramework,Version=v4.7.2\"\r\n                    {\r\n                    \"Name\" = \"8:Microsoft .NET Framework 4.7.2 (x86 and x64)\"\r\n                    \"ProductCode\" = \"8:.NETFramework,Version=v4.7.2\"\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        \"Release\"\r\n        {\r\n        \"DisplayName\" = \"8:Release\"\r\n        \"IsDebugOnly\" = \"11:FALSE\"\r\n        \"IsReleaseOnly\" = \"11:TRUE\"\r\n        \"OutputFilename\" = \"8:Release\\\\AppInstallerTestMsiInstaller.msi\"\r\n        \"PackageFilesAs\" = \"3:2\"\r\n        \"PackageFileSize\" = \"3:-2147483648\"\r\n        \"CabType\" = \"3:1\"\r\n        \"Compression\" = \"3:2\"\r\n        \"SignOutput\" = \"11:FALSE\"\r\n        \"CertificateFile\" = \"8:\"\r\n        \"PrivateKeyFile\" = \"8:\"\r\n        \"TimeStampServer\" = \"8:\"\r\n        \"InstallerBootstrapper\" = \"3:2\"\r\n            \"BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}\"\r\n            {\r\n            \"Enabled\" = \"11:TRUE\"\r\n            \"PromptEnabled\" = \"11:TRUE\"\r\n            \"PrerequisitesLocation\" = \"2:1\"\r\n            \"Url\" = \"8:\"\r\n            \"ComponentsUrl\" = \"8:\"\r\n                \"Items\"\r\n                {\r\n                    \"{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:.NETFramework,Version=v4.7.2\"\r\n                    {\r\n                    \"Name\" = \"8:Microsoft .NET Framework 4.7.2 (x86 and x64)\"\r\n                    \"ProductCode\" = \"8:.NETFramework,Version=v4.7.2\"\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n    \"Deployable\"\r\n    {\r\n        \"CustomAction\"\r\n        {\r\n        }\r\n        \"DefaultFeature\"\r\n        {\r\n        \"Name\" = \"8:DefaultFeature\"\r\n        \"Title\" = \"8:\"\r\n        \"Description\" = \"8:\"\r\n        }\r\n        \"ExternalPersistence\"\r\n        {\r\n            \"LaunchCondition\"\r\n            {\r\n            }\r\n        }\r\n        \"File\"\r\n        {\r\n        }\r\n        \"FileType\"\r\n        {\r\n        }\r\n        \"Folder\"\r\n        {\r\n            \"{3C67513D-01DD-4637-8A68-80971EB9504F}:_3FD954FA64934D1C9D4F66157C4603AF\"\r\n            {\r\n            \"DefaultLocation\" = \"8:[ProgramFilesFolder][Manufacturer]\\\\[ProductName]\"\r\n            \"Name\" = \"8:#1925\"\r\n            \"AlwaysCreate\" = \"11:FALSE\"\r\n            \"Condition\" = \"8:\"\r\n            \"Transitive\" = \"11:FALSE\"\r\n            \"Property\" = \"8:TARGETDIR\"\r\n                \"Folders\"\r\n                {\r\n                }\r\n            }\r\n            \"{1525181F-901A-416C-8A58-119130FE478E}:_7CE3351BC05D486393C4720064B75896\"\r\n            {\r\n            \"Name\" = \"8:#1916\"\r\n            \"AlwaysCreate\" = \"11:FALSE\"\r\n            \"Condition\" = \"8:\"\r\n            \"Transitive\" = \"11:FALSE\"\r\n            \"Property\" = \"8:DesktopFolder\"\r\n                \"Folders\"\r\n                {\r\n                }\r\n            }\r\n            \"{1525181F-901A-416C-8A58-119130FE478E}:_9537533CAD3E4467B320694E22A39C4C\"\r\n            {\r\n            \"Name\" = \"8:#1919\"\r\n            \"AlwaysCreate\" = \"11:FALSE\"\r\n            \"Condition\" = \"8:\"\r\n            \"Transitive\" = \"11:FALSE\"\r\n            \"Property\" = \"8:ProgramMenuFolder\"\r\n                \"Folders\"\r\n                {\r\n                }\r\n            }\r\n        }\r\n        \"LaunchCondition\"\r\n        {\r\n        }\r\n        \"Locator\"\r\n        {\r\n        }\r\n        \"MsiBootstrapper\"\r\n        {\r\n        \"LangId\" = \"3:1033\"\r\n        \"RequiresElevation\" = \"11:FALSE\"\r\n        }\r\n        \"Product\"\r\n        {\r\n        \"Name\" = \"8:Microsoft Visual Studio\"\r\n        \"ProductName\" = \"8:AppInstallerTestMsiInstaller\"\r\n        \"ProductCode\" = \"8:{A5D36CF1-1993-4F63-BFB4-3ACD910D36A1}\"\r\n        \"PackageCode\" = \"8:{B21B22D8-5E23-401C-84FA-EE074DB23F8F}\"\r\n        \"UpgradeCode\" = \"8:{B9CF9DD5-D46F-4CE0-BFC9-633BF9D3A6F4}\"\r\n        \"AspNetVersion\" = \"8:4.0.30319.0\"\r\n        \"RestartWWWService\" = \"11:FALSE\"\r\n        \"RemovePreviousVersions\" = \"11:FALSE\"\r\n        \"DetectNewerInstalledVersion\" = \"11:TRUE\"\r\n        \"InstallAllUsers\" = \"11:FALSE\"\r\n        \"ProductVersion\" = \"8:1.0.0\"\r\n        \"Manufacturer\" = \"8:AppInstallerCLI\"\r\n        \"ARPHELPTELEPHONE\" = \"8:\"\r\n        \"ARPHELPLINK\" = \"8:\"\r\n        \"Title\" = \"8:AppInstallerTestMsiInstaller\"\r\n        \"Subject\" = \"8:\"\r\n        \"ARPCONTACT\" = \"8:AppInstallerCLI\"\r\n        \"Keywords\" = \"8:\"\r\n        \"ARPCOMMENTS\" = \"8:\"\r\n        \"ARPURLINFOABOUT\" = \"8:\"\r\n        \"ARPPRODUCTICON\" = \"8:\"\r\n        \"ARPIconIndex\" = \"3:0\"\r\n        \"SearchPath\" = \"8:\"\r\n        \"UseSystemSearchPath\" = \"11:TRUE\"\r\n        \"TargetPlatform\" = \"3:0\"\r\n        \"PreBuildEvent\" = \"8:\"\r\n        \"PostBuildEvent\" = \"8:\"\r\n        \"RunPostBuildEvent\" = \"3:0\"\r\n        }\r\n        \"Registry\"\r\n        {\r\n            \"HKLM\"\r\n            {\r\n                \"Keys\"\r\n                {\r\n                    \"{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_951AD5F7C8424CCAB911C2469F382BA0\"\r\n                    {\r\n                    \"Name\" = \"8:Software\"\r\n                    \"Condition\" = \"8:\"\r\n                    \"AlwaysCreate\" = \"11:FALSE\"\r\n                    \"DeleteAtUninstall\" = \"11:FALSE\"\r\n                    \"Transitive\" = \"11:FALSE\"\r\n                        \"Keys\"\r\n                        {\r\n                            \"{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_1245A15ED08E4D31AC11FE6C6AF43AA6\"\r\n                            {\r\n                            \"Name\" = \"8:[Manufacturer]\"\r\n                            \"Condition\" = \"8:\"\r\n                            \"AlwaysCreate\" = \"11:FALSE\"\r\n                            \"DeleteAtUninstall\" = \"11:FALSE\"\r\n                            \"Transitive\" = \"11:FALSE\"\r\n                                \"Keys\"\r\n                                {\r\n                                }\r\n                                \"Values\"\r\n                                {\r\n                                }\r\n                            }\r\n                        }\r\n                        \"Values\"\r\n                        {\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            \"HKCU\"\r\n            {\r\n                \"Keys\"\r\n                {\r\n                    \"{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_A0E8E016B459429AB33F8A8041B409CF\"\r\n                    {\r\n                    \"Name\" = \"8:Software\"\r\n                    \"Condition\" = \"8:\"\r\n                    \"AlwaysCreate\" = \"11:FALSE\"\r\n                    \"DeleteAtUninstall\" = \"11:FALSE\"\r\n                    \"Transitive\" = \"11:FALSE\"\r\n                        \"Keys\"\r\n                        {\r\n                            \"{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_6F792619739B49D49348459164023C26\"\r\n                            {\r\n                            \"Name\" = \"8:[Manufacturer]\"\r\n                            \"Condition\" = \"8:\"\r\n                            \"AlwaysCreate\" = \"11:FALSE\"\r\n                            \"DeleteAtUninstall\" = \"11:FALSE\"\r\n                            \"Transitive\" = \"11:FALSE\"\r\n                                \"Keys\"\r\n                                {\r\n                                }\r\n                                \"Values\"\r\n                                {\r\n                                }\r\n                            }\r\n                        }\r\n                        \"Values\"\r\n                        {\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            \"HKCR\"\r\n            {\r\n                \"Keys\"\r\n                {\r\n                }\r\n            }\r\n            \"HKU\"\r\n            {\r\n                \"Keys\"\r\n                {\r\n                }\r\n            }\r\n            \"HKPU\"\r\n            {\r\n                \"Keys\"\r\n                {\r\n                }\r\n            }\r\n        }\r\n        \"Sequences\"\r\n        {\r\n        }\r\n        \"Shortcut\"\r\n        {\r\n        }\r\n        \"UserInterface\"\r\n        {\r\n            \"{DF760B10-853B-4699-99F2-AFF7185B4A62}:_07F5BD380D034D2788D0E26EC943AF9E\"\r\n            {\r\n            \"Name\" = \"8:#1900\"\r\n            \"Sequence\" = \"3:2\"\r\n            \"Attributes\" = \"3:1\"\r\n                \"Dialogs\"\r\n                {\r\n                    \"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_0F2C662EB54446EEBB450AB41783B804\"\r\n                    {\r\n                    \"Sequence\" = \"3:300\"\r\n                    \"DisplayName\" = \"8:Confirm Installation\"\r\n                    \"UseDynamicProperties\" = \"11:TRUE\"\r\n                    \"IsDependency\" = \"11:FALSE\"\r\n                    \"SourcePath\" = \"8:<VsdDialogDir>\\\\VsdAdminConfirmDlg.wid\"\r\n                        \"Properties\"\r\n                        {\r\n                            \"BannerBitmap\"\r\n                            {\r\n                            \"Name\" = \"8:BannerBitmap\"\r\n                            \"DisplayName\" = \"8:#1001\"\r\n                            \"Description\" = \"8:#1101\"\r\n                            \"Type\" = \"3:8\"\r\n                            \"ContextData\" = \"8:Bitmap\"\r\n                            \"Attributes\" = \"3:4\"\r\n                            \"Setting\" = \"3:1\"\r\n                            \"UsePlugInResources\" = \"11:TRUE\"\r\n                            }\r\n                        }\r\n                    }\r\n                    \"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_5B669F9D2835440A97450ED9A579EBB0\"\r\n                    {\r\n                    \"Sequence\" = \"3:100\"\r\n                    \"DisplayName\" = \"8:Welcome\"\r\n                    \"UseDynamicProperties\" = \"11:TRUE\"\r\n                    \"IsDependency\" = \"11:FALSE\"\r\n                    \"SourcePath\" = \"8:<VsdDialogDir>\\\\VsdAdminWelcomeDlg.wid\"\r\n                        \"Properties\"\r\n                        {\r\n                            \"BannerBitmap\"\r\n                            {\r\n                            \"Name\" = \"8:BannerBitmap\"\r\n                            \"DisplayName\" = \"8:#1001\"\r\n                            \"Description\" = \"8:#1101\"\r\n                            \"Type\" = \"3:8\"\r\n                            \"ContextData\" = \"8:Bitmap\"\r\n                            \"Attributes\" = \"3:4\"\r\n                            \"Setting\" = \"3:1\"\r\n                            \"UsePlugInResources\" = \"11:TRUE\"\r\n                            }\r\n                            \"CopyrightWarning\"\r\n                            {\r\n                            \"Name\" = \"8:CopyrightWarning\"\r\n                            \"DisplayName\" = \"8:#1002\"\r\n                            \"Description\" = \"8:#1102\"\r\n                            \"Type\" = \"3:3\"\r\n                            \"ContextData\" = \"8:\"\r\n                            \"Attributes\" = \"3:0\"\r\n                            \"Setting\" = \"3:1\"\r\n                            \"Value\" = \"8:#1202\"\r\n                            \"DefaultValue\" = \"8:#1202\"\r\n                            \"UsePlugInResources\" = \"11:TRUE\"\r\n                            }\r\n                            \"Welcome\"\r\n                            {\r\n                            \"Name\" = \"8:Welcome\"\r\n                            \"DisplayName\" = \"8:#1003\"\r\n                            \"Description\" = \"8:#1103\"\r\n                            \"Type\" = \"3:3\"\r\n                            \"ContextData\" = \"8:\"\r\n                            \"Attributes\" = \"3:0\"\r\n                            \"Setting\" = \"3:1\"\r\n                            \"Value\" = \"8:#1203\"\r\n                            \"DefaultValue\" = \"8:#1203\"\r\n                            \"UsePlugInResources\" = \"11:TRUE\"\r\n                            }\r\n                        }\r\n                    }\r\n                    \"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_A1B6CF1DE99744E9BA298D9516F4FBBB\"\r\n                    {\r\n                    \"Sequence\" = \"3:200\"\r\n                    \"DisplayName\" = \"8:Installation Folder\"\r\n                    \"UseDynamicProperties\" = \"11:TRUE\"\r\n                    \"IsDependency\" = \"11:FALSE\"\r\n                    \"SourcePath\" = \"8:<VsdDialogDir>\\\\VsdAdminFolderDlg.wid\"\r\n                        \"Properties\"\r\n                        {\r\n                            \"BannerBitmap\"\r\n                            {\r\n                            \"Name\" = \"8:BannerBitmap\"\r\n                            \"DisplayName\" = \"8:#1001\"\r\n                            \"Description\" = \"8:#1101\"\r\n                            \"Type\" = \"3:8\"\r\n                            \"ContextData\" = \"8:Bitmap\"\r\n                            \"Attributes\" = \"3:4\"\r\n                            \"Setting\" = \"3:1\"\r\n                            \"UsePlugInResources\" = \"11:TRUE\"\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            \"{DF760B10-853B-4699-99F2-AFF7185B4A62}:_31DFC87DB7EB49BBBE91080D4E17EBC3\"\r\n            {\r\n            \"Name\" = \"8:#1901\"\r\n            \"Sequence\" = \"3:2\"\r\n            \"Attributes\" = \"3:2\"\r\n                \"Dialogs\"\r\n                {\r\n                    \"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_B0FC86DC72004463B28043005E93933D\"\r\n                    {\r\n                    \"Sequence\" = \"3:100\"\r\n                    \"DisplayName\" = \"8:Progress\"\r\n                    \"UseDynamicProperties\" = \"11:TRUE\"\r\n                    \"IsDependency\" = \"11:FALSE\"\r\n                    \"SourcePath\" = \"8:<VsdDialogDir>\\\\VsdAdminProgressDlg.wid\"\r\n                        \"Properties\"\r\n                        {\r\n                            \"BannerBitmap\"\r\n                            {\r\n                            \"Name\" = \"8:BannerBitmap\"\r\n                            \"DisplayName\" = \"8:#1001\"\r\n                            \"Description\" = \"8:#1101\"\r\n                            \"Type\" = \"3:8\"\r\n                            \"ContextData\" = \"8:Bitmap\"\r\n                            \"Attributes\" = \"3:4\"\r\n                            \"Setting\" = \"3:1\"\r\n                            \"UsePlugInResources\" = \"11:TRUE\"\r\n                            }\r\n                            \"ShowProgress\"\r\n                            {\r\n                            \"Name\" = \"8:ShowProgress\"\r\n                            \"DisplayName\" = \"8:#1009\"\r\n                            \"Description\" = \"8:#1109\"\r\n                            \"Type\" = \"3:5\"\r\n                            \"ContextData\" = \"8:1;True=1;False=0\"\r\n                            \"Attributes\" = \"3:0\"\r\n                            \"Setting\" = \"3:0\"\r\n                            \"Value\" = \"3:1\"\r\n                            \"DefaultValue\" = \"3:1\"\r\n                            \"UsePlugInResources\" = \"11:TRUE\"\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            \"{DF760B10-853B-4699-99F2-AFF7185B4A62}:_49F7C7303D464C18981485552AA18870\"\r\n            {\r\n            \"Name\" = \"8:#1901\"\r\n            \"Sequence\" = \"3:1\"\r\n            \"Attributes\" = \"3:2\"\r\n                \"Dialogs\"\r\n                {\r\n                    \"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_78EF5C34DBDB4BC88F2789CBE1F17043\"\r\n                    {\r\n                    \"Sequence\" = \"3:100\"\r\n                    \"DisplayName\" = \"8:Progress\"\r\n                    \"UseDynamicProperties\" = \"11:TRUE\"\r\n                    \"IsDependency\" = \"11:FALSE\"\r\n                    \"SourcePath\" = \"8:<VsdDialogDir>\\\\VsdProgressDlg.wid\"\r\n                        \"Properties\"\r\n                        {\r\n                            \"BannerBitmap\"\r\n                            {\r\n                            \"Name\" = \"8:BannerBitmap\"\r\n                            \"DisplayName\" = \"8:#1001\"\r\n                            \"Description\" = \"8:#1101\"\r\n                            \"Type\" = \"3:8\"\r\n                            \"ContextData\" = \"8:Bitmap\"\r\n                            \"Attributes\" = \"3:4\"\r\n                            \"Setting\" = \"3:1\"\r\n                            \"UsePlugInResources\" = \"11:TRUE\"\r\n                            }\r\n                            \"ShowProgress\"\r\n                            {\r\n                            \"Name\" = \"8:ShowProgress\"\r\n                            \"DisplayName\" = \"8:#1009\"\r\n                            \"Description\" = \"8:#1109\"\r\n                            \"Type\" = \"3:5\"\r\n                            \"ContextData\" = \"8:1;True=1;False=0\"\r\n                            \"Attributes\" = \"3:0\"\r\n                            \"Setting\" = \"3:0\"\r\n                            \"Value\" = \"3:1\"\r\n                            \"DefaultValue\" = \"3:1\"\r\n                            \"UsePlugInResources\" = \"11:TRUE\"\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            \"{DF760B10-853B-4699-99F2-AFF7185B4A62}:_68474A3513F54E56B4D451594D7639DC\"\r\n            {\r\n            \"Name\" = \"8:#1902\"\r\n            \"Sequence\" = \"3:2\"\r\n            \"Attributes\" = \"3:3\"\r\n                \"Dialogs\"\r\n                {\r\n                    \"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_3EC2CCC643CA4EEB9DAFF092520273EE\"\r\n                    {\r\n                    \"Sequence\" = \"3:100\"\r\n                    \"DisplayName\" = \"8:Finished\"\r\n                    \"UseDynamicProperties\" = \"11:TRUE\"\r\n                    \"IsDependency\" = \"11:FALSE\"\r\n                    \"SourcePath\" = \"8:<VsdDialogDir>\\\\VsdAdminFinishedDlg.wid\"\r\n                        \"Properties\"\r\n                        {\r\n                            \"BannerBitmap\"\r\n                            {\r\n                            \"Name\" = \"8:BannerBitmap\"\r\n                            \"DisplayName\" = \"8:#1001\"\r\n                            \"Description\" = \"8:#1101\"\r\n                            \"Type\" = \"3:8\"\r\n                            \"ContextData\" = \"8:Bitmap\"\r\n                            \"Attributes\" = \"3:4\"\r\n                            \"Setting\" = \"3:1\"\r\n                            \"UsePlugInResources\" = \"11:TRUE\"\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            \"{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_81A3A282324C416DB8EA6A5FABEAD776\"\r\n            {\r\n            \"UseDynamicProperties\" = \"11:FALSE\"\r\n            \"IsDependency\" = \"11:FALSE\"\r\n            \"SourcePath\" = \"8:<VsdDialogDir>\\\\VsdUserInterface.wim\"\r\n            }\r\n            \"{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_869386ADC36F4DAE92F694770A481917\"\r\n            {\r\n            \"UseDynamicProperties\" = \"11:FALSE\"\r\n            \"IsDependency\" = \"11:FALSE\"\r\n            \"SourcePath\" = \"8:<VsdDialogDir>\\\\VsdBasicDialogs.wim\"\r\n            }\r\n            \"{DF760B10-853B-4699-99F2-AFF7185B4A62}:_9E39D7A2A2BB4185AE8290AF159CBDE8\"\r\n            {\r\n            \"Name\" = \"8:#1902\"\r\n            \"Sequence\" = \"3:1\"\r\n            \"Attributes\" = \"3:3\"\r\n                \"Dialogs\"\r\n                {\r\n                    \"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_18EEDC13BA92450EA46E5CFAD31164FE\"\r\n                    {\r\n                    \"Sequence\" = \"3:100\"\r\n                    \"DisplayName\" = \"8:Finished\"\r\n                    \"UseDynamicProperties\" = \"11:TRUE\"\r\n                    \"IsDependency\" = \"11:FALSE\"\r\n                    \"SourcePath\" = \"8:<VsdDialogDir>\\\\VsdFinishedDlg.wid\"\r\n                        \"Properties\"\r\n                        {\r\n                            \"BannerBitmap\"\r\n                            {\r\n                            \"Name\" = \"8:BannerBitmap\"\r\n                            \"DisplayName\" = \"8:#1001\"\r\n                            \"Description\" = \"8:#1101\"\r\n                            \"Type\" = \"3:8\"\r\n                            \"ContextData\" = \"8:Bitmap\"\r\n                            \"Attributes\" = \"3:4\"\r\n                            \"Setting\" = \"3:1\"\r\n                            \"UsePlugInResources\" = \"11:TRUE\"\r\n                            }\r\n                            \"UpdateText\"\r\n                            {\r\n                            \"Name\" = \"8:UpdateText\"\r\n                            \"DisplayName\" = \"8:#1058\"\r\n                            \"Description\" = \"8:#1158\"\r\n                            \"Type\" = \"3:15\"\r\n                            \"ContextData\" = \"8:\"\r\n                            \"Attributes\" = \"3:0\"\r\n                            \"Setting\" = \"3:1\"\r\n                            \"Value\" = \"8:#1258\"\r\n                            \"DefaultValue\" = \"8:#1258\"\r\n                            \"UsePlugInResources\" = \"11:TRUE\"\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            \"{DF760B10-853B-4699-99F2-AFF7185B4A62}:_A1D7AFF21DC048769B063F0ABB6BAD93\"\r\n            {\r\n            \"Name\" = \"8:#1900\"\r\n            \"Sequence\" = \"3:1\"\r\n            \"Attributes\" = \"3:1\"\r\n                \"Dialogs\"\r\n                {\r\n                    \"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_6AFCB2A470844F02AC97138D2C4255B5\"\r\n                    {\r\n                    \"Sequence\" = \"3:300\"\r\n                    \"DisplayName\" = \"8:Confirm Installation\"\r\n                    \"UseDynamicProperties\" = \"11:TRUE\"\r\n                    \"IsDependency\" = \"11:FALSE\"\r\n                    \"SourcePath\" = \"8:<VsdDialogDir>\\\\VsdConfirmDlg.wid\"\r\n                        \"Properties\"\r\n                        {\r\n                            \"BannerBitmap\"\r\n                            {\r\n                            \"Name\" = \"8:BannerBitmap\"\r\n                            \"DisplayName\" = \"8:#1001\"\r\n                            \"Description\" = \"8:#1101\"\r\n                            \"Type\" = \"3:8\"\r\n                            \"ContextData\" = \"8:Bitmap\"\r\n                            \"Attributes\" = \"3:4\"\r\n                            \"Setting\" = \"3:1\"\r\n                            \"UsePlugInResources\" = \"11:TRUE\"\r\n                            }\r\n                        }\r\n                    }\r\n                    \"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_73B000DF31AF44D789DC52D2EB3AC63B\"\r\n                    {\r\n                    \"Sequence\" = \"3:200\"\r\n                    \"DisplayName\" = \"8:Installation Folder\"\r\n                    \"UseDynamicProperties\" = \"11:TRUE\"\r\n                    \"IsDependency\" = \"11:FALSE\"\r\n                    \"SourcePath\" = \"8:<VsdDialogDir>\\\\VsdFolderDlg.wid\"\r\n                        \"Properties\"\r\n                        {\r\n                            \"BannerBitmap\"\r\n                            {\r\n                            \"Name\" = \"8:BannerBitmap\"\r\n                            \"DisplayName\" = \"8:#1001\"\r\n                            \"Description\" = \"8:#1101\"\r\n                            \"Type\" = \"3:8\"\r\n                            \"ContextData\" = \"8:Bitmap\"\r\n                            \"Attributes\" = \"3:4\"\r\n                            \"Setting\" = \"3:1\"\r\n                            \"UsePlugInResources\" = \"11:TRUE\"\r\n                            }\r\n                            \"InstallAllUsersVisible\"\r\n                            {\r\n                            \"Name\" = \"8:InstallAllUsersVisible\"\r\n                            \"DisplayName\" = \"8:#1059\"\r\n                            \"Description\" = \"8:#1159\"\r\n                            \"Type\" = \"3:5\"\r\n                            \"ContextData\" = \"8:1;True=1;False=0\"\r\n                            \"Attributes\" = \"3:0\"\r\n                            \"Setting\" = \"3:0\"\r\n                            \"Value\" = \"3:1\"\r\n                            \"DefaultValue\" = \"3:1\"\r\n                            \"UsePlugInResources\" = \"11:TRUE\"\r\n                            }\r\n                        }\r\n                    }\r\n                    \"{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_E411887483814552AF4BF33BBB4F1B1D\"\r\n                    {\r\n                    \"Sequence\" = \"3:100\"\r\n                    \"DisplayName\" = \"8:Welcome\"\r\n                    \"UseDynamicProperties\" = \"11:TRUE\"\r\n                    \"IsDependency\" = \"11:FALSE\"\r\n                    \"SourcePath\" = \"8:<VsdDialogDir>\\\\VsdWelcomeDlg.wid\"\r\n                        \"Properties\"\r\n                        {\r\n                            \"BannerBitmap\"\r\n                            {\r\n                            \"Name\" = \"8:BannerBitmap\"\r\n                            \"DisplayName\" = \"8:#1001\"\r\n                            \"Description\" = \"8:#1101\"\r\n                            \"Type\" = \"3:8\"\r\n                            \"ContextData\" = \"8:Bitmap\"\r\n                            \"Attributes\" = \"3:4\"\r\n                            \"Setting\" = \"3:1\"\r\n                            \"UsePlugInResources\" = \"11:TRUE\"\r\n                            }\r\n                            \"CopyrightWarning\"\r\n                            {\r\n                            \"Name\" = \"8:CopyrightWarning\"\r\n                            \"DisplayName\" = \"8:#1002\"\r\n                            \"Description\" = \"8:#1102\"\r\n                            \"Type\" = \"3:3\"\r\n                            \"ContextData\" = \"8:\"\r\n                            \"Attributes\" = \"3:0\"\r\n                            \"Setting\" = \"3:1\"\r\n                            \"Value\" = \"8:#1202\"\r\n                            \"DefaultValue\" = \"8:#1202\"\r\n                            \"UsePlugInResources\" = \"11:TRUE\"\r\n                            }\r\n                            \"Welcome\"\r\n                            {\r\n                            \"Name\" = \"8:Welcome\"\r\n                            \"DisplayName\" = \"8:#1003\"\r\n                            \"Description\" = \"8:#1103\"\r\n                            \"Type\" = \"3:3\"\r\n                            \"ContextData\" = \"8:\"\r\n                            \"Attributes\" = \"3:0\"\r\n                            \"Setting\" = \"3:1\"\r\n                            \"Value\" = \"8:#1203\"\r\n                            \"DefaultValue\" = \"8:#1203\"\r\n                            \"UsePlugInResources\" = \"11:TRUE\"\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        \"MergeModule\"\r\n        {\r\n        }\r\n        \"ProjectOutput\"\r\n        {\r\n            \"{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_9892A03006D742BB8C58FDF406605C8B\"\r\n            {\r\n            \"SourcePath\" = \"8:..\\\\x86\\\\Release\\\\AppInstallerTestExeInstaller\\\\AppInstallerTestExeInstaller.exe\"\r\n            \"TargetName\" = \"8:\"\r\n            \"Tag\" = \"8:\"\r\n            \"Folder\" = \"8:_3FD954FA64934D1C9D4F66157C4603AF\"\r\n            \"Condition\" = \"8:\"\r\n            \"Transitive\" = \"11:FALSE\"\r\n            \"Vital\" = \"11:TRUE\"\r\n            \"ReadOnly\" = \"11:FALSE\"\r\n            \"Hidden\" = \"11:FALSE\"\r\n            \"System\" = \"11:FALSE\"\r\n            \"Permanent\" = \"11:FALSE\"\r\n            \"SharedLegacy\" = \"11:FALSE\"\r\n            \"PackageAs\" = \"3:1\"\r\n            \"Register\" = \"3:1\"\r\n            \"Exclude\" = \"11:FALSE\"\r\n            \"IsDependency\" = \"11:FALSE\"\r\n            \"IsolateTo\" = \"8:\"\r\n            \"ProjectOutputGroupRegister\" = \"3:1\"\r\n            \"OutputConfiguration\" = \"8:Release|Win32\"\r\n            \"OutputGroupCanonicalName\" = \"8:Built\"\r\n            \"OutputProjectGuid\" = \"8:{6CB84692-5994-407D-B9BD-9216AF77FE83}\"\r\n            \"ShowKeyOutput\" = \"11:TRUE\"\r\n                \"ExcludeFilters\"\r\n                {\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/AppInstallerTestMsixInstaller/AppInstallerTestMsixInstaller.wapproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"15.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <PropertyGroup Condition=\"'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '15.0'\">\r\n    <VisualStudioVersion>15.0</VisualStudioVersion>\r\n  </PropertyGroup>\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|x86\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x86</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x86\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x86</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|ARM64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|ARM64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|AnyCPU\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>AnyCPU</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|AnyCPU\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>AnyCPU</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <PropertyGroup>\r\n    <WapProjPath Condition=\"'$(WapProjPath)'==''\">$(MSBuildExtensionsPath)\\Microsoft\\DesktopBridge\\</WapProjPath>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(WapProjPath)\\Microsoft.DesktopBridge.props\" />\r\n  <PropertyGroup>\r\n    <ProjectGuid>3e2cba31-ceba-4d63-bf52-49c0718e19ea</ProjectGuid>\r\n    <TargetPlatformVersion>10.0.26100.0</TargetPlatformVersion>\r\n    <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>\r\n    <DefaultLanguage>en-US</DefaultLanguage>\r\n    <AppxPackageSigningEnabled>false</AppxPackageSigningEnabled>\r\n    <EntryPointProjectUniqueName>..\\AppInstallerTestExeInstaller\\AppInstallerTestExeInstaller.vcxproj</EntryPointProjectUniqueName>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x86'\">\r\n    <AppxBundle>Always</AppxBundle>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|AnyCPU'\">\r\n    <AppxBundle>Always</AppxBundle>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\r\n    <AppxBundle>Always</AppxBundle>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\r\n    <AppxBundle>Always</AppxBundle>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <AppxBundle>Always</AppxBundle>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x86'\">\r\n    <AppxBundle>Always</AppxBundle>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|AnyCPU'\">\r\n    <AppxBundle>Always</AppxBundle>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <AppxBundle>Always</AppxBundle>\r\n  </PropertyGroup>\r\n  <ItemGroup>\r\n    <AppxManifest Include=\"Package.appxmanifest\">\r\n      <SubType>Designer</SubType>\r\n    </AppxManifest>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Content Include=\"Images\\SplashScreen.scale-200.png\" />\r\n    <Content Include=\"Images\\LockScreenLogo.scale-200.png\" />\r\n    <Content Include=\"Images\\Square150x150Logo.scale-200.png\" />\r\n    <Content Include=\"Images\\Square44x44Logo.scale-200.png\" />\r\n    <Content Include=\"Images\\Square44x44Logo.targetsize-24_altform-unplated.png\" />\r\n    <Content Include=\"Images\\StoreLogo.png\" />\r\n    <Content Include=\"Images\\Wide310x150Logo.scale-200.png\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\AppInstallerTestExeInstaller\\AppInstallerTestExeInstaller.vcxproj\" />\r\n  </ItemGroup>\r\n  <Import Project=\"$(WapProjPath)\\Microsoft.DesktopBridge.targets\" />\r\n</Project>"
  },
  {
    "path": "src/AppInstallerTestMsixInstaller/Package.appxmanifest",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n\r\n<Package\r\n  xmlns=\"http://schemas.microsoft.com/appx/manifest/foundation/windows10\"\r\n  xmlns:uap=\"http://schemas.microsoft.com/appx/manifest/uap/windows10\"\r\n  xmlns:rescap=\"http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities\"\r\n  IgnorableNamespaces=\"uap rescap\">\r\n\r\n  <Identity\r\n    Name=\"6c6338fe-41b7-46ca-8ba6-b5ad5312bb0e\"\r\n    Publisher=\"CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US\"\r\n    Version=\"1.0.0.0\" />\r\n\r\n  <Properties>\r\n    <DisplayName>AppInstallerTestMsixInstaller</DisplayName>\r\n    <PublisherDisplayName>AppInstallerTest</PublisherDisplayName>\r\n    <Logo>Images\\StoreLogo.png</Logo>\r\n  </Properties>\r\n\r\n  <Dependencies>\r\n    <TargetDeviceFamily Name=\"Windows.Universal\" MinVersion=\"10.0.0.0\" MaxVersionTested=\"10.0.0.0\" />\r\n    <TargetDeviceFamily Name=\"Windows.Desktop\" MinVersion=\"10.0.14393.0\" MaxVersionTested=\"10.0.14393.0\" />\r\n  </Dependencies>\r\n\r\n  <Resources>\r\n    <Resource Language=\"x-generate\"/>\r\n  </Resources>\r\n\r\n  <Applications>\r\n    <Application Id=\"App\"\r\n      Executable=\"$targetnametoken$.exe\"\r\n      EntryPoint=\"$targetentrypoint$\">\r\n      <uap:VisualElements\r\n        DisplayName=\"AppInstallerTestMsixInstaller\"\r\n        Description=\"AppInstallerTestMsixInstaller\"\r\n        BackgroundColor=\"transparent\"\r\n        Square150x150Logo=\"Images\\Square150x150Logo.png\"\r\n        Square44x44Logo=\"Images\\Square44x44Logo.png\">\r\n        <uap:DefaultTile Wide310x150Logo=\"Images\\Wide310x150Logo.png\" />\r\n        <uap:SplashScreen Image=\"Images\\SplashScreen.png\" />\r\n      </uap:VisualElements>\r\n    </Application>\r\n  </Applications>\r\n\r\n  <Capabilities>\r\n    <Capability Name=\"internetClient\" />\r\n    <rescap:Capability Name=\"runFullTrust\" />\r\n  </Capabilities>\r\n</Package>\r\n"
  },
  {
    "path": "src/COMServer/COMServer.vcxitems",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <PropertyGroup Label=\"Globals\">\r\n    <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>\r\n    <HasSharedItems>true</HasSharedItems>\r\n    <ItemsProjectGuid>{409cd681-22a4-469d-88ae-cb5e4836e07a}</ItemsProjectGuid>\r\n  </PropertyGroup>\r\n  <ItemDefinitionGroup>\r\n    <ClCompile>\r\n      <PreprocessorDefinitions>__WRL_DISABLE_STATIC_INITIALIZE__;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n    </ClCompile>\r\n  </ItemDefinitionGroup>\r\n</Project>"
  },
  {
    "path": "src/CertificateResources/CertificateResources.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n\r\n#define CERTIFICATE_RESOURCE_TYPE               400\r\n\r\n#define IDX_CERTIFICATE_STORE_ROOT_1            401\r\n#define IDX_CERTIFICATE_STORE_INTERMEDIATE_1    402\r\n#define IDX_CERTIFICATE_STORE_LEAF_1            403\r\n#define IDX_CERTIFICATE_STORE_ROOT_2            404\r\n#define IDX_CERTIFICATE_STORE_INTERMEDIATE_2    405\r\n#define IDX_CERTIFICATE_STORE_LEAF_2            406\r\n#define IDX_CERTIFICATE_MS_TLS_ECC_ROOT_G2      407\r\n#define IDX_CERTIFICATE_MS_TLS_RSA_ROOT_G2      408\r\n"
  },
  {
    "path": "src/CertificateResources/CertificateResources.rc",
    "content": "// Microsoft Visual C++ generated resource script.\r\n//\r\n#include \"resource.h\"\r\n#include \"CertificateResources.h\"\r\n\r\n#define APSTUDIO_READONLY_SYMBOLS\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// Generated from the TEXTINCLUDE 2 resource.\r\n//\r\n#include \"winres.h\"\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n#undef APSTUDIO_READONLY_SYMBOLS\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n// English (United States) resources\r\n\r\n#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\nLANGUAGE 9, 1\r\n\r\n#ifdef APSTUDIO_INVOKED\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// TEXTINCLUDE\r\n//\r\n\r\n1 TEXTINCLUDE  \r\nBEGIN\r\n    \"resource.h\\0\"\r\nEND\r\n\r\n2 TEXTINCLUDE  \r\nBEGIN\r\n    \"#include \"\"winres.h\"\"\\r\\n\"\r\n    \"\\0\"\r\nEND\r\n\r\n3 TEXTINCLUDE  \r\nBEGIN\r\n    \"\\r\\n\"\r\n    \"\\0\"\r\nEND\r\n\r\n#endif    // APSTUDIO_INVOKED\r\n\r\n#endif    // English (United States) resources\r\n/////////////////////////////////////////////////////////////////////////////\r\n\r\n\r\n\r\n#ifndef APSTUDIO_INVOKED\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// Generated from the TEXTINCLUDE 3 resource.\r\n//\r\n\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n#endif    // not APSTUDIO_INVOKED\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// Packages schema\r\n//\r\n\r\nIDX_CERTIFICATE_STORE_ROOT_1            CERTIFICATE_RESOURCE_TYPE     \"StoreRoot1.cer\"\r\nIDX_CERTIFICATE_STORE_INTERMEDIATE_1    CERTIFICATE_RESOURCE_TYPE     \"StoreIntermediate1.cer\"\r\nIDX_CERTIFICATE_STORE_LEAF_1            CERTIFICATE_RESOURCE_TYPE     \"StoreLeaf1.cer\"\r\n\r\nIDX_CERTIFICATE_STORE_ROOT_2            CERTIFICATE_RESOURCE_TYPE     \"StoreRoot2.cer\"\r\nIDX_CERTIFICATE_STORE_INTERMEDIATE_2    CERTIFICATE_RESOURCE_TYPE     \"StoreIntermediate2.cer\"\r\nIDX_CERTIFICATE_STORE_LEAF_2            CERTIFICATE_RESOURCE_TYPE     \"StoreLeaf2.cer\"\r\n\r\nIDX_CERTIFICATE_MS_TLS_ECC_ROOT_G2      CERTIFICATE_RESOURCE_TYPE     \"Microsoft_TLS_ECC_Root_G2.crt\"\r\nIDX_CERTIFICATE_MS_TLS_RSA_ROOT_G2      CERTIFICATE_RESOURCE_TYPE     \"Microsoft_TLS_RSA_Root_G2.crt\"\r\n"
  },
  {
    "path": "src/CertificateResources/CertificateResources.vcxitems",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <PropertyGroup Label=\"Globals\">\r\n    <MSBuildAllProjects Condition=\"'$(MSBuildVersion)' == '' Or '$(MSBuildVersion)' &lt; '16.0'\">$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>\r\n    <HasSharedItems>true</HasSharedItems>\r\n    <ItemsProjectGuid>{b0bbbd92-943b-408f-b2b2-dbbab4a22d23}</ItemsProjectGuid>\r\n  </PropertyGroup>\r\n  <ItemDefinitionGroup>\r\n    <ClCompile>\r\n      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories>\r\n    </ClCompile>\r\n  </ItemDefinitionGroup>\r\n  <ItemGroup>\r\n    <ProjectCapability Include=\"SourceItemsFromImports\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"$(MSBuildThisFileDirectory)Microsoft_TLS_ECC_Root_G2.crt\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)Microsoft_TLS_RSA_Root_G2.crt\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)StoreRoot1.cer\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)StoreIntermediate1.cer\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)StoreLeaf1.cer\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)StoreRoot2.cer\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)StoreIntermediate2.cer\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)StoreLeaf2.cer\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)CertificateResources.h\" />\r\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)resource.h\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ResourceCompile Include=\"$(MSBuildThisFileDirectory)CertificateResources.rc\" />\r\n  </ItemGroup>\r\n</Project>"
  },
  {
    "path": "src/CertificateResources/CertificateResources.vcxitems.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup>\r\n    <Filter Include=\"Certificates\">\r\n      <UniqueIdentifier>{ad622b6a-16bb-4e32-921c-f1d6505fc0ed}</UniqueIdentifier>\r\n    </Filter>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"$(MSBuildThisFileDirectory)StoreRoot1.cer\">\r\n      <Filter>Certificates</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)StoreIntermediate1.cer\">\r\n      <Filter>Certificates</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)StoreLeaf1.cer\">\r\n      <Filter>Certificates</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)StoreRoot2.cer\">\r\n      <Filter>Certificates</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)StoreIntermediate2.cer\">\r\n      <Filter>Certificates</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)StoreLeaf2.cer\">\r\n      <Filter>Certificates</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)Microsoft_TLS_ECC_Root_G2.crt\">\r\n      <Filter>Certificates</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)Microsoft_TLS_RSA_Root_G2.crt\">\r\n      <Filter>Certificates</Filter>\r\n    </None>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)resource.h\" />\r\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)CertificateResources.h\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ResourceCompile Include=\"$(MSBuildThisFileDirectory)CertificateResources.rc\" />\r\n  </ItemGroup>\r\n</Project>"
  },
  {
    "path": "src/CertificateResources/resource.h",
    "content": "//{{NO_DEPENDENCIES}}\r\n// Microsoft Visual C++ generated include file.\r\n// Used by CertificateResources.rc\r\n\r\n// Next default values for new objects\r\n//\r\n#ifdef APSTUDIO_INVOKED\r\n#ifndef APSTUDIO_READONLY_SYMBOLS\r\n#define _APS_NEXT_RESOURCE_VALUE        101\r\n#define _APS_NEXT_COMMAND_VALUE         40001\r\n#define _APS_NEXT_CONTROL_VALUE         1001\r\n#define _APS_NEXT_SYMED_VALUE           101\r\n#endif\r\n#endif\r\n"
  },
  {
    "path": "src/CodeAnalysis.ruleset",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<RuleSet Name=\"Copy of Microsoft Native Recommended Rules\" Description=\"These rules focus on the most critical and common problems in your native code, including potential security holes and application crashes.  You should include this rule set in any custom rule set you create for your native projects.  This ruleset is designed to work with Visual Studio Professional edition and higher.\" ToolsVersion=\"16.0\">\r\n  <Rules AnalyzerId=\"Microsoft.Analyzers.NativeCodeAnalysis\" RuleNamespace=\"Microsoft.Rules.Native\">\r\n    <Rule Id=\"C26100\" Action=\"Warning\" />\r\n    <Rule Id=\"C26101\" Action=\"Warning\" />\r\n    <Rule Id=\"C26110\" Action=\"Warning\" />\r\n    <Rule Id=\"C26111\" Action=\"Warning\" />\r\n    <Rule Id=\"C26112\" Action=\"Warning\" />\r\n    <Rule Id=\"C26115\" Action=\"Warning\" />\r\n    <Rule Id=\"C26116\" Action=\"Warning\" />\r\n    <Rule Id=\"C26117\" Action=\"Warning\" />\r\n    <Rule Id=\"C26140\" Action=\"Warning\" />\r\n    <Rule Id=\"C26437\" Action=\"Warning\" />\r\n    <Rule Id=\"C26439\" Action=\"Warning\" />\r\n    <Rule Id=\"C26441\" Action=\"Warning\" />\r\n    <Rule Id=\"C26444\" Action=\"Warning\" />\r\n    <Rule Id=\"C26449\" Action=\"Warning\" />\r\n    <Rule Id=\"C26450\" Action=\"Warning\" />\r\n    <Rule Id=\"C26451\" Action=\"Warning\" />\r\n    <Rule Id=\"C26452\" Action=\"Warning\" />\r\n    <Rule Id=\"C26453\" Action=\"Warning\" />\r\n    <Rule Id=\"C26454\" Action=\"Warning\" />\r\n    <Rule Id=\"C26478\" Action=\"Warning\" />\r\n    <Rule Id=\"C26495\" Action=\"Warning\" />\r\n    <Rule Id=\"C26498\" Action=\"Warning\" />\r\n    <Rule Id=\"C26815\" Action=\"Warning\" />\r\n    <Rule Id=\"C26816\" Action=\"Warning\" />\r\n    <Rule Id=\"C26817\" Action=\"Warning\" />\r\n    <Rule Id=\"C26819\" Action=\"Warning\" />\r\n    <Rule Id=\"C26820\" Action=\"Warning\" />\r\n    <Rule Id=\"C28020\" Action=\"Warning\" />\r\n    <Rule Id=\"C28021\" Action=\"Warning\" />\r\n    <Rule Id=\"C28022\" Action=\"Warning\" />\r\n    <Rule Id=\"C28023\" Action=\"Warning\" />\r\n    <Rule Id=\"C28024\" Action=\"Warning\" />\r\n    <Rule Id=\"C28039\" Action=\"Warning\" />\r\n    <Rule Id=\"C28112\" Action=\"Warning\" />\r\n    <Rule Id=\"C28113\" Action=\"Warning\" />\r\n    <Rule Id=\"C28125\" Action=\"Warning\" />\r\n    <Rule Id=\"C28137\" Action=\"Warning\" />\r\n    <Rule Id=\"C28138\" Action=\"Warning\" />\r\n    <Rule Id=\"C28159\" Action=\"Warning\" />\r\n    <Rule Id=\"C28160\" Action=\"Warning\" />\r\n    <Rule Id=\"C28163\" Action=\"Warning\" />\r\n    <Rule Id=\"C28164\" Action=\"Warning\" />\r\n    <Rule Id=\"C28182\" Action=\"Warning\" />\r\n    <Rule Id=\"C28183\" Action=\"Warning\" />\r\n    <Rule Id=\"C28193\" Action=\"Warning\" />\r\n    <Rule Id=\"C28196\" Action=\"Warning\" />\r\n    <Rule Id=\"C28202\" Action=\"Warning\" />\r\n    <Rule Id=\"C28203\" Action=\"Warning\" />\r\n    <Rule Id=\"C28205\" Action=\"Warning\" />\r\n    <Rule Id=\"C28206\" Action=\"Warning\" />\r\n    <Rule Id=\"C28207\" Action=\"Warning\" />\r\n    <Rule Id=\"C28209\" Action=\"Warning\" />\r\n    <Rule Id=\"C28210\" Action=\"Warning\" />\r\n    <Rule Id=\"C28211\" Action=\"Warning\" />\r\n    <Rule Id=\"C28212\" Action=\"Warning\" />\r\n    <Rule Id=\"C28213\" Action=\"Warning\" />\r\n    <Rule Id=\"C28214\" Action=\"Warning\" />\r\n    <Rule Id=\"C28215\" Action=\"Warning\" />\r\n    <Rule Id=\"C28216\" Action=\"Warning\" />\r\n    <Rule Id=\"C28217\" Action=\"Warning\" />\r\n    <Rule Id=\"C28218\" Action=\"Warning\" />\r\n    <Rule Id=\"C28219\" Action=\"Warning\" />\r\n    <Rule Id=\"C28220\" Action=\"Warning\" />\r\n    <Rule Id=\"C28221\" Action=\"Warning\" />\r\n    <Rule Id=\"C28222\" Action=\"Warning\" />\r\n    <Rule Id=\"C28223\" Action=\"Warning\" />\r\n    <Rule Id=\"C28224\" Action=\"Warning\" />\r\n    <Rule Id=\"C28225\" Action=\"Warning\" />\r\n    <Rule Id=\"C28226\" Action=\"Warning\" />\r\n    <Rule Id=\"C28227\" Action=\"Warning\" />\r\n    <Rule Id=\"C28228\" Action=\"Warning\" />\r\n    <Rule Id=\"C28229\" Action=\"Warning\" />\r\n    <Rule Id=\"C28230\" Action=\"Warning\" />\r\n    <Rule Id=\"C28231\" Action=\"Warning\" />\r\n    <Rule Id=\"C28232\" Action=\"Warning\" />\r\n    <Rule Id=\"C28233\" Action=\"Warning\" />\r\n    <Rule Id=\"C28234\" Action=\"Warning\" />\r\n    <Rule Id=\"C28235\" Action=\"Warning\" />\r\n    <Rule Id=\"C28236\" Action=\"Warning\" />\r\n    <Rule Id=\"C28237\" Action=\"Warning\" />\r\n    <Rule Id=\"C28238\" Action=\"Warning\" />\r\n    <Rule Id=\"C28239\" Action=\"Warning\" />\r\n    <Rule Id=\"C28240\" Action=\"Warning\" />\r\n    <Rule Id=\"C28241\" Action=\"Warning\" />\r\n    <Rule Id=\"C28243\" Action=\"Warning\" />\r\n    <Rule Id=\"C28244\" Action=\"Warning\" />\r\n    <Rule Id=\"C28245\" Action=\"Warning\" />\r\n    <Rule Id=\"C28246\" Action=\"Warning\" />\r\n    <Rule Id=\"C28250\" Action=\"Warning\" />\r\n    <Rule Id=\"C28251\" Action=\"Warning\" />\r\n    <Rule Id=\"C28252\" Action=\"Warning\" />\r\n    <Rule Id=\"C28253\" Action=\"Warning\" />\r\n    <Rule Id=\"C28254\" Action=\"Warning\" />\r\n    <Rule Id=\"C28262\" Action=\"Warning\" />\r\n    <Rule Id=\"C28263\" Action=\"Warning\" />\r\n    <Rule Id=\"C28267\" Action=\"Warning\" />\r\n    <Rule Id=\"C28272\" Action=\"Warning\" />\r\n    <Rule Id=\"C28273\" Action=\"Warning\" />\r\n    <Rule Id=\"C28275\" Action=\"Warning\" />\r\n    <Rule Id=\"C28279\" Action=\"Warning\" />\r\n    <Rule Id=\"C28280\" Action=\"Warning\" />\r\n    <Rule Id=\"C28282\" Action=\"Warning\" />\r\n    <Rule Id=\"C28285\" Action=\"Warning\" />\r\n    <Rule Id=\"C28286\" Action=\"Warning\" />\r\n    <Rule Id=\"C28287\" Action=\"Warning\" />\r\n    <Rule Id=\"C28288\" Action=\"Warning\" />\r\n    <Rule Id=\"C28289\" Action=\"Warning\" />\r\n    <Rule Id=\"C28290\" Action=\"Warning\" />\r\n    <Rule Id=\"C28291\" Action=\"Warning\" />\r\n    <Rule Id=\"C28300\" Action=\"Warning\" />\r\n    <Rule Id=\"C28301\" Action=\"Warning\" />\r\n    <Rule Id=\"C28302\" Action=\"Warning\" />\r\n    <Rule Id=\"C28303\" Action=\"Warning\" />\r\n    <Rule Id=\"C28304\" Action=\"Warning\" />\r\n    <Rule Id=\"C28305\" Action=\"Warning\" />\r\n    <Rule Id=\"C28306\" Action=\"Warning\" />\r\n    <Rule Id=\"C28307\" Action=\"Warning\" />\r\n    <Rule Id=\"C28308\" Action=\"Warning\" />\r\n    <Rule Id=\"C28309\" Action=\"Warning\" />\r\n    <Rule Id=\"C28350\" Action=\"Warning\" />\r\n    <Rule Id=\"C28351\" Action=\"Warning\" />\r\n    <Rule Id=\"C33001\" Action=\"Warning\" />\r\n    <Rule Id=\"C33004\" Action=\"Warning\" />\r\n    <Rule Id=\"C33005\" Action=\"Warning\" />\r\n    <Rule Id=\"C33010\" Action=\"Warning\" />\r\n    <Rule Id=\"C33011\" Action=\"Warning\" />\r\n    <Rule Id=\"C33020\" Action=\"Warning\" />\r\n    <Rule Id=\"C6001\" Action=\"Warning\" />\r\n    <Rule Id=\"C6011\" Action=\"Warning\" />\r\n    <Rule Id=\"C6029\" Action=\"Warning\" />\r\n    <Rule Id=\"C6031\" Action=\"Warning\" />\r\n    <Rule Id=\"C6053\" Action=\"Warning\" />\r\n    <Rule Id=\"C6054\" Action=\"Warning\" />\r\n    <Rule Id=\"C6059\" Action=\"Warning\" />\r\n    <Rule Id=\"C6063\" Action=\"Warning\" />\r\n    <Rule Id=\"C6064\" Action=\"Warning\" />\r\n    <Rule Id=\"C6066\" Action=\"Warning\" />\r\n    <Rule Id=\"C6067\" Action=\"Warning\" />\r\n    <Rule Id=\"C6101\" Action=\"Warning\" />\r\n    <Rule Id=\"C6200\" Action=\"Warning\" />\r\n    <Rule Id=\"C6201\" Action=\"Warning\" />\r\n    <Rule Id=\"C6214\" Action=\"Warning\" />\r\n    <Rule Id=\"C6215\" Action=\"Warning\" />\r\n    <Rule Id=\"C6216\" Action=\"Warning\" />\r\n    <Rule Id=\"C6217\" Action=\"Warning\" />\r\n    <Rule Id=\"C6220\" Action=\"Warning\" />\r\n    <Rule Id=\"C6226\" Action=\"Warning\" />\r\n    <Rule Id=\"C6230\" Action=\"Warning\" />\r\n    <Rule Id=\"C6235\" Action=\"Warning\" />\r\n    <Rule Id=\"C6236\" Action=\"Warning\" />\r\n    <Rule Id=\"C6237\" Action=\"Warning\" />\r\n    <Rule Id=\"C6242\" Action=\"Warning\" />\r\n    <Rule Id=\"C6248\" Action=\"Warning\" />\r\n    <Rule Id=\"C6250\" Action=\"Warning\" />\r\n    <Rule Id=\"C6255\" Action=\"Warning\" />\r\n    <Rule Id=\"C6258\" Action=\"Warning\" />\r\n    <Rule Id=\"C6259\" Action=\"Warning\" />\r\n    <Rule Id=\"C6260\" Action=\"Warning\" />\r\n    <Rule Id=\"C6262\" Action=\"Warning\" />\r\n    <Rule Id=\"C6263\" Action=\"Warning\" />\r\n    <Rule Id=\"C6268\" Action=\"Warning\" />\r\n    <Rule Id=\"C6269\" Action=\"Warning\" />\r\n    <Rule Id=\"C6270\" Action=\"Warning\" />\r\n    <Rule Id=\"C6271\" Action=\"Warning\" />\r\n    <Rule Id=\"C6272\" Action=\"Warning\" />\r\n    <Rule Id=\"C6273\" Action=\"Warning\" />\r\n    <Rule Id=\"C6274\" Action=\"Warning\" />\r\n    <Rule Id=\"C6276\" Action=\"Warning\" />\r\n    <Rule Id=\"C6277\" Action=\"Warning\" />\r\n    <Rule Id=\"C6278\" Action=\"Warning\" />\r\n    <Rule Id=\"C6279\" Action=\"Warning\" />\r\n    <Rule Id=\"C6280\" Action=\"Warning\" />\r\n    <Rule Id=\"C6281\" Action=\"Warning\" />\r\n    <Rule Id=\"C6282\" Action=\"Warning\" />\r\n    <Rule Id=\"C6283\" Action=\"Warning\" />\r\n    <Rule Id=\"C6284\" Action=\"Warning\" />\r\n    <Rule Id=\"C6285\" Action=\"Warning\" />\r\n    <Rule Id=\"C6286\" Action=\"Warning\" />\r\n    <Rule Id=\"C6287\" Action=\"Warning\" />\r\n    <Rule Id=\"C6288\" Action=\"Warning\" />\r\n    <Rule Id=\"C6289\" Action=\"Warning\" />\r\n    <Rule Id=\"C6290\" Action=\"Warning\" />\r\n    <Rule Id=\"C6291\" Action=\"Warning\" />\r\n    <Rule Id=\"C6292\" Action=\"Warning\" />\r\n    <Rule Id=\"C6293\" Action=\"Warning\" />\r\n    <Rule Id=\"C6294\" Action=\"Warning\" />\r\n    <Rule Id=\"C6295\" Action=\"Warning\" />\r\n    <Rule Id=\"C6296\" Action=\"Warning\" />\r\n    <Rule Id=\"C6297\" Action=\"Warning\" />\r\n    <Rule Id=\"C6299\" Action=\"Warning\" />\r\n    <Rule Id=\"C6302\" Action=\"Warning\" />\r\n    <Rule Id=\"C6303\" Action=\"Warning\" />\r\n    <Rule Id=\"C6305\" Action=\"Warning\" />\r\n    <Rule Id=\"C6306\" Action=\"Warning\" />\r\n    <Rule Id=\"C6308\" Action=\"Warning\" />\r\n    <Rule Id=\"C6310\" Action=\"Warning\" />\r\n    <Rule Id=\"C6312\" Action=\"Warning\" />\r\n    <Rule Id=\"C6314\" Action=\"Warning\" />\r\n    <Rule Id=\"C6317\" Action=\"Warning\" />\r\n    <Rule Id=\"C6318\" Action=\"Warning\" />\r\n    <Rule Id=\"C6319\" Action=\"Warning\" />\r\n    <Rule Id=\"C6324\" Action=\"Warning\" />\r\n    <Rule Id=\"C6328\" Action=\"Warning\" />\r\n    <Rule Id=\"C6331\" Action=\"Warning\" />\r\n    <Rule Id=\"C6332\" Action=\"Warning\" />\r\n    <Rule Id=\"C6333\" Action=\"Warning\" />\r\n    <Rule Id=\"C6335\" Action=\"Warning\" />\r\n    <Rule Id=\"C6381\" Action=\"Warning\" />\r\n    <Rule Id=\"C6383\" Action=\"Warning\" />\r\n    <Rule Id=\"C6384\" Action=\"Warning\" />\r\n    <Rule Id=\"C6385\" Action=\"Warning\" />\r\n    <Rule Id=\"C6386\" Action=\"Warning\" />\r\n    <Rule Id=\"C6387\" Action=\"Warning\" />\r\n    <Rule Id=\"C6388\" Action=\"Warning\" />\r\n    <Rule Id=\"C6500\" Action=\"Warning\" />\r\n    <Rule Id=\"C6501\" Action=\"Warning\" />\r\n    <Rule Id=\"C6503\" Action=\"Warning\" />\r\n    <Rule Id=\"C6504\" Action=\"Warning\" />\r\n    <Rule Id=\"C6505\" Action=\"Warning\" />\r\n    <Rule Id=\"C6506\" Action=\"Warning\" />\r\n    <Rule Id=\"C6508\" Action=\"Warning\" />\r\n    <Rule Id=\"C6509\" Action=\"Warning\" />\r\n    <Rule Id=\"C6510\" Action=\"Warning\" />\r\n    <Rule Id=\"C6511\" Action=\"Warning\" />\r\n    <Rule Id=\"C6513\" Action=\"Warning\" />\r\n    <Rule Id=\"C6514\" Action=\"Warning\" />\r\n    <Rule Id=\"C6515\" Action=\"Warning\" />\r\n    <Rule Id=\"C6516\" Action=\"Warning\" />\r\n    <Rule Id=\"C6517\" Action=\"Warning\" />\r\n    <Rule Id=\"C6518\" Action=\"Warning\" />\r\n    <Rule Id=\"C6522\" Action=\"Warning\" />\r\n    <Rule Id=\"C6525\" Action=\"Warning\" />\r\n    <Rule Id=\"C6527\" Action=\"Warning\" />\r\n    <Rule Id=\"C6530\" Action=\"Warning\" />\r\n    <Rule Id=\"C6540\" Action=\"Warning\" />\r\n    <Rule Id=\"C6551\" Action=\"Warning\" />\r\n    <Rule Id=\"C6552\" Action=\"Warning\" />\r\n    <Rule Id=\"C6701\" Action=\"Warning\" />\r\n    <Rule Id=\"C6702\" Action=\"Warning\" />\r\n    <Rule Id=\"C6703\" Action=\"Warning\" />\r\n    <Rule Id=\"C6704\" Action=\"Warning\" />\r\n    <Rule Id=\"C6705\" Action=\"Warning\" />\r\n    <Rule Id=\"C6706\" Action=\"Warning\" />\r\n    <Rule Id=\"C6993\" Action=\"Warning\" />\r\n    <Rule Id=\"C6995\" Action=\"Warning\" />\r\n    <Rule Id=\"C6997\" Action=\"Warning\" />\r\n  </Rules>\r\n</RuleSet>"
  },
  {
    "path": "src/ComInprocTestbed/ComInprocTestbed.manifest",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<assembly manifestVersion=\"1.0\" xmlns=\"urn:schemas-microsoft-com:asm.v1\">\r\n\t<assemblyIdentity version=\"1.0.0.0\" name=\"ComInprocTestbed\"/>\r\n\r\n\t<compatibility xmlns=\"urn:schemas-microsoft-com:compatibility.v1\">\r\n\t\t<application>\r\n\t\t\t<!-- A list of the Windows versions that this application has been tested on\r\n           and is designed to work with. Uncomment the appropriate elements\r\n           and Windows will automatically select the most compatible environment. -->\r\n\r\n\t\t\t<!-- Windows Vista -->\r\n\t\t\t<!--<supportedOS Id=\"{e2011457-1546-43c5-a5fe-008deee3d3f0}\" />-->\r\n\r\n\t\t\t<!-- Windows 7 -->\r\n\t\t\t<!--<supportedOS Id=\"{35138b9a-5d96-4fbd-8e2d-a2440225f93a}\" />-->\r\n\r\n\t\t\t<!-- Windows 8 -->\r\n\t\t\t<!--<supportedOS Id=\"{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}\" />-->\r\n\r\n\t\t\t<!-- Windows 8.1 -->\r\n\t\t\t<!--<supportedOS Id=\"{1f676c76-80e1-4239-95bb-83d0f6d0da78}\" />-->\r\n\r\n\t\t\t<!-- Windows 10 -->\r\n\t\t\t<supportedOS Id=\"{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}\" />\r\n\r\n\t\t</application>\r\n\t</compatibility>\r\n\r\n\t<dependency>\r\n\t\t<dependentAssembly>\r\n\t\t\t<assemblyIdentity\r\n\t\t\t  name=\"Microsoft.Management.Deployment.InProc.dll\"\r\n\t\t\t  version=\"0.0.0.0\"/>\r\n\t\t</dependentAssembly>\r\n\t</dependency>\r\n</assembly>\r\n"
  },
  {
    "path": "src/ComInprocTestbed/ComInprocTestbed.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" />\r\n  <PropertyGroup Label=\"Globals\">\r\n    <VCProjectVersion>15.0</VCProjectVersion>\r\n    <ProjectGuid>{E5BCFF58-7D0C-4770-ABB9-AECE1027CD94}</ProjectGuid>\r\n    <Keyword>Win32Proj</Keyword>\r\n    <RootNamespace>ComInprocTestbed</RootNamespace>\r\n    <WindowsTargetPlatformVersion>10.0.26100.0</WindowsTargetPlatformVersion>\r\n    <WindowsTargetPlatformMinVersion>10.0.17763.0</WindowsTargetPlatformMinVersion>\r\n    <WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|Win32\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|Win32\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|ARM64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|ARM64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <PropertyGroup Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <EmbedManifest>false</EmbedManifest>\r\n    <CopyLocalProjectReference>true</CopyLocalProjectReference>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <EmbedManifest>false</EmbedManifest>\r\n    <CopyLocalProjectReference>true</CopyLocalProjectReference>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <EmbedManifest>false</EmbedManifest>\r\n    <CopyLocalProjectReference>true</CopyLocalProjectReference>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <EmbedManifest>false</EmbedManifest>\r\n    <CopyLocalProjectReference>true</CopyLocalProjectReference>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <EmbedManifest>false</EmbedManifest>\r\n    <CopyLocalProjectReference>true</CopyLocalProjectReference>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <EmbedManifest>false</EmbedManifest>\r\n    <CopyLocalProjectReference>true</CopyLocalProjectReference>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\r\n  <ImportGroup Label=\"ExtensionSettings\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"Shared\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <Import Project=\"$(ProjectDir)\\..\\vcpkg.props\" />\r\n  <PropertyGroup Label=\"UserMacros\" />\r\n  <ItemDefinitionGroup>\r\n    <ClCompile>\r\n      <PrecompiledHeader>Use</PrecompiledHeader>\r\n      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>\r\n      <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>\r\n      <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <AdditionalOptions>%(AdditionalOptions) /permissive- /bigobj /Zi</AdditionalOptions>\r\n    </ClCompile>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Debug'\">\r\n    <ClCompile>\r\n      <Optimization>Disabled</Optimization>\r\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</TreatWarningAsError>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">stdcpp17</LanguageStandard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">stdcpp17</LanguageStandard>\r\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n    </Link>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">ComInprocTestbed.manifest</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">ComInprocTestbed.manifest</AdditionalManifestFiles>\r\n    </Manifest>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Platform)'=='Win32'\">\r\n    <ClCompile>\r\n      <PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</TreatWarningAsError>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">stdcpp17</LanguageStandard>\r\n    </ClCompile>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">ComInprocTestbed.manifest</AdditionalManifestFiles>\r\n    </Manifest>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Release'\">\r\n    <ClCompile>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">true</TreatWarningAsError>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">stdcpp17</LanguageStandard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">stdcpp17</LanguageStandard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">stdcpp17</LanguageStandard>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n    </Link>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">ComInprocTestbed.manifest</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">ComInprocTestbed.manifest</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">ComInprocTestbed.manifest</AdditionalManifestFiles>\r\n    </Manifest>\r\n  </ItemDefinitionGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"main.cpp\" />\r\n    <ClCompile Include=\"PackageManager.cpp\" />\r\n    <ClCompile Include=\"pch.cpp\">\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Create</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Create</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">Create</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">Create</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">Create</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Create</PrecompiledHeader>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Tests.cpp\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"packages.config\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\Microsoft.Management.Deployment.InProc\\Microsoft.Management.Deployment.InProc.vcxproj\">\r\n      <Project>{9ac3c6a4-1875-4d3e-bf9c-c31e81eff6b4}</Project>\r\n      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r\n      <LinkLibraryDependencies>false</LinkLibraryDependencies>\r\n      <Private>true</Private>\r\n    </ProjectReference>\r\n    <ProjectReference Include=\"..\\Microsoft.Management.Deployment\\Microsoft.Management.Deployment.vcxproj\">\r\n      <Project>{1cc41a9a-ae66-459d-9210-1e572dd7be69}</Project>\r\n    </ProjectReference>\r\n    <ProjectReference Include=\"..\\WindowsPackageManager\\WindowsPackageManager.vcxproj\">\r\n      <Project>{2046b5af-666d-4ce8-8d3e-c32c57908a56}</Project>\r\n      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r\n      <LinkLibraryDependencies>false</LinkLibraryDependencies>\r\n      <Private>true</Private>\r\n    </ProjectReference>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <CopyFileToFolders Include=\"..\\Microsoft.Management.Deployment.InProc\\Microsoft.Management.Deployment.InProc.dll.manifest\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n  </ItemGroup>\r\n  <!-- Because we use C++/WinRT and WinMDAssembly is set to `true`, the default targets resets our preference. Return it to our desired value. -->\r\n  <!-- This does result in every referenced WinMD being copied locally, but that is a small price to pay for getting the references we need easily. -->\r\n  <Target Name=\"OverrideCopyLocalProjectReferenceOverride\" AfterTargets=\"_PrepareForReferenceResolution\">\r\n    <PropertyGroup>\r\n      <CopyLocalProjectReference>true</CopyLocalProjectReference>\r\n    </PropertyGroup>\r\n  </Target>\r\n  <ItemGroup>\r\n    <Manifest Include=\"ComInprocTestbed.manifest\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"PackageManager.h\" />\r\n    <ClInclude Include=\"pch.h\" />\r\n    <ClInclude Include=\"Tests.h\" />\r\n  </ItemGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\r\n  <ImportGroup Label=\"ExtensionTargets\">\r\n    <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" />\r\n  </ImportGroup>\r\n  <Target Name=\"EnsureNuGetPackageBuildImports\" BeforeTargets=\"PrepareForBuild\">\r\n    <PropertyGroup>\r\n      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>\r\n    </PropertyGroup>\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props'))\" />\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets'))\" />\r\n  </Target>\r\n</Project>"
  },
  {
    "path": "src/ComInprocTestbed/ComInprocTestbed.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup>\r\n    <Filter Include=\"Source Files\">\r\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Header Files\">\r\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r\n      <Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Resource Files\">\r\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\r\n    </Filter>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"main.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"PackageManager.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Tests.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"pch.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"packages.config\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <CopyFileToFolders Include=\"..\\Microsoft.Management.Deployment.InProc\\Microsoft.Management.Deployment.InProc.dll.manifest\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Manifest Include=\"ComInprocTestbed.manifest\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"PackageManager.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Tests.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"pch.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n  </ItemGroup>\r\n</Project>"
  },
  {
    "path": "src/ComInprocTestbed/PackageManager.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"PackageManager.h\"\r\n\r\nusing namespace winrt::Microsoft::Management::Deployment;\r\n\r\n// Work around the assertions about waiting on an STA thread from C++/WinRT\r\ntemplate <typename Operation>\r\nauto WaitForResult(Operation&& operation)\r\n{\r\n    std::promise<void> promise;\r\n    auto future = promise.get_future();\r\n    operation.Completed([&](const auto&, const auto&) { promise.set_value(); });\r\n    future.wait();\r\n    return operation.GetResults();\r\n}\r\n\r\nPackageCatalog Connect(const PackageCatalogReference& reference, std::string_view name)\r\n{\r\n    auto connectResult = reference.Connect();\r\n\r\n    if (connectResult.Status() != ConnectResultStatus::Ok)\r\n    {\r\n        std::cout << \"Connecting to \" << name << \" got: \" << static_cast<int32_t>(connectResult.Status()) << \" [\" << connectResult.ExtendedErrorCode() << \"]\\n\";\r\n        return nullptr;\r\n    }\r\n\r\n    return connectResult.PackageCatalog();\r\n}\r\n\r\nPackageCatalog ConnectComposite(const PackageManager& packageManager, const TestParameters& testParameters, CompositeSearchBehavior searchBehavior, PackageInstallScope scope = PackageInstallScope::Any)\r\n{\r\n    CreateCompositePackageCatalogOptions options = testParameters.CreateCreateCompositePackageCatalogOptions();\r\n    options.InstalledScope(scope);\r\n    options.CompositeSearchBehavior(searchBehavior);\r\n\r\n    auto sourceName = winrt::to_hstring(testParameters.SourceName);\r\n\r\n    for (PackageCatalogReference catalogRef : packageManager.GetPackageCatalogs())\r\n    {\r\n        if (sourceName.empty() || catalogRef.Info().Name() == sourceName)\r\n        {\r\n            options.Catalogs().Append(catalogRef);\r\n        }\r\n    }\r\n\r\n    // Inputs are provided for a source that we did not find; add it.\r\n    if (!sourceName.empty() && !testParameters.SourceURL.empty() && options.Catalogs().Size() == 0)\r\n    {\r\n        AddPackageCatalogOptions addPackageCatalogOptions = testParameters.CreateAddPackageCatalogOptions();\r\n        addPackageCatalogOptions.Name(sourceName);\r\n        addPackageCatalogOptions.SourceUri(winrt::to_hstring(testParameters.SourceURL));\r\n        addPackageCatalogOptions.TrustLevel(PackageCatalogTrustLevel::Trusted);\r\n\r\n        auto addCatalogResult = WaitForResult(packageManager.AddPackageCatalogAsync(addPackageCatalogOptions));\r\n\r\n        if (addCatalogResult.Status() != AddPackageCatalogStatus::Ok)\r\n        {\r\n            std::cout << \"Adding catalog `\" << testParameters.SourceName << \"` [`\" << testParameters.SourceURL << \"`] got: \" << static_cast<int32_t>(addCatalogResult.Status()) << \" [\" << addCatalogResult.ExtendedErrorCode() << \"]\\n\";\r\n            return nullptr;\r\n        }\r\n\r\n        // Get the new catalog\r\n        options.Catalogs().Append(packageManager.GetPackageCatalogByName(sourceName));\r\n    }\r\n\r\n    return Connect(packageManager.CreateCompositePackageCatalog(options), \"Composite Catalog\");\r\n}\r\n\r\nCatalogPackage FindPackage(const PackageCatalog& compositeCatalog, const TestParameters& testParameters)\r\n{\r\n    PackageMatchFilter filter = testParameters.CreatePackageMatchFilter();\r\n    filter.Field(PackageMatchField::Id);\r\n    filter.Option(PackageFieldMatchOption::EqualsCaseInsensitive);\r\n    filter.Value(winrt::to_hstring(testParameters.PackageName));\r\n\r\n    FindPackagesOptions findOptions = testParameters.CreateFindPackagesOptions();\r\n    findOptions.Filters().Append(filter);\r\n\r\n    auto findResult = compositeCatalog.FindPackages(findOptions);\r\n    if (findResult.Status() != FindPackagesResultStatus::Ok)\r\n    {\r\n        std::cout << \"Finding package \" << testParameters.PackageName << \" got: \" << static_cast<int32_t>(findResult.Status()) << \" [\" << findResult.ExtendedErrorCode() << \"]\\n\";\r\n        return nullptr;\r\n    }\r\n\r\n    if (findResult.Matches().Size() != 1)\r\n    {\r\n        std::cout << \"Finding package \" << testParameters.PackageName << \" got \" << findResult.Matches().Size() << \" results.\\n\";\r\n        return nullptr;\r\n    }\r\n\r\n    return findResult.Matches().GetAt(0).CatalogPackage();\r\n}\r\n\r\nbool UsePackageManager(const TestParameters& testParameters)\r\n{\r\n    PackageManager packageManager = testParameters.CreatePackageManager();\r\n\r\n    // Force installed cache to be created\r\n    auto installedCatalogRef = packageManager.GetLocalPackageCatalog(LocalPackageCatalog::InstalledPackages);\r\n    auto installedCatalog = Connect(installedCatalogRef, \"Installed Catalog\");\r\n    if (!installedCatalog)\r\n    {\r\n        return false;\r\n    }\r\n\r\n    // Force TerminationSignalHandler to be created\r\n    auto compositeCatalog = ConnectComposite(packageManager, testParameters, CompositeSearchBehavior::RemotePackagesFromRemoteCatalogs);\r\n    if (!compositeCatalog)\r\n    {\r\n        return false;\r\n    }\r\n\r\n    auto package = FindPackage(compositeCatalog, testParameters);\r\n    if (!package)\r\n    {\r\n        return false;\r\n    }\r\n\r\n    DownloadOptions downloadOptions = testParameters.CreateDownloadOptions();\r\n    auto downloadResult = WaitForResult(packageManager.DownloadPackageAsync(package, downloadOptions));\r\n\r\n    if (downloadResult.Status() != DownloadResultStatus::Ok)\r\n    {\r\n        std::cout << \"Downloading package \" << testParameters.PackageName << \" got: \" << static_cast<int32_t>(downloadResult.Status()) << \"\\n\";\r\n        return false;\r\n    }\r\n\r\n    return true;\r\n}\r\n\r\nvoid InitializePackageManagerGlobals()\r\n{\r\n    PackageManagerSettings settings;\r\n    settings.SetCallerIdentifier(L\"ComInprocTestbed\");\r\n    settings.SetStateIdentifier(L\"ComInprocTestbed\");\r\n}\r\n\r\nvoid SetUnloadPreference(bool value)\r\n{\r\n    PackageManagerSettings settings;\r\n    settings.CanUnloadPreference(value);\r\n}\r\nvoid SetDisableTerminationSignals(bool value)\r\n{\r\n    PackageManagerSettings settings;\r\n    settings.TerminationSignalMonitoring(!value);\r\n}\r\n\r\nbool DetectForSystem(const TestParameters& testParameters)\r\n{\r\n    PackageManager packageManager = testParameters.CreatePackageManager();\r\n\r\n    auto compositeCatalog = ConnectComposite(packageManager, testParameters, CompositeSearchBehavior::RemotePackagesFromAllCatalogs, PackageInstallScope::SystemOrUnknown);\r\n    if (!compositeCatalog)\r\n    {\r\n        winrt::throw_hresult(HRESULT_FROM_WIN32(ERROR_INVALID_STATE));\r\n    }\r\n\r\n    auto package = FindPackage(compositeCatalog, testParameters);\r\n    if (!package)\r\n    {\r\n        winrt::throw_hresult(HRESULT_FROM_WIN32(ERROR_INVALID_STATE));\r\n    }\r\n\r\n    return package.DefaultInstallVersion() && package.InstalledVersion();\r\n}\r\n\r\nbool InstallForSystem(const TestParameters& testParameters)\r\n{\r\n    PackageManager packageManager = testParameters.CreatePackageManager();\r\n\r\n    auto compositeCatalog = ConnectComposite(packageManager, testParameters, CompositeSearchBehavior::RemotePackagesFromAllCatalogs, PackageInstallScope::SystemOrUnknown);\r\n    if (!compositeCatalog)\r\n    {\r\n        winrt::throw_hresult(HRESULT_FROM_WIN32(ERROR_INVALID_STATE));\r\n    }\r\n\r\n    auto package = FindPackage(compositeCatalog, testParameters);\r\n    if (!package)\r\n    {\r\n        winrt::throw_hresult(HRESULT_FROM_WIN32(ERROR_INVALID_STATE));\r\n    }\r\n\r\n    InstallOptions options = testParameters.CreateInstallOptions();\r\n    options.AcceptPackageAgreements(true);\r\n    options.BypassIsStoreClientBlockedPolicyCheck(true);\r\n    options.Force(true);\r\n    options.PackageInstallScope(PackageInstallScope::SystemOrUnknown);\r\n    auto installResult = WaitForResult(packageManager.InstallPackageAsync(package, options));\r\n\r\n    if (installResult.Status() != InstallResultStatus::Ok)\r\n    {\r\n        std::cout << \"Installing package \" << testParameters.PackageName << \" got: \" << static_cast<int32_t>(installResult.Status()) << \" [\" << installResult.ExtendedErrorCode() << \"] [\" << installResult.InstallerErrorCode() << \"]\\n\";\r\n        return false;\r\n    }\r\n\r\n    return true;\r\n}\r\n"
  },
  {
    "path": "src/ComInprocTestbed/PackageManager.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <string_view>\r\n#include \"Tests.h\"\r\n\r\n// Attempts to instantiate all static objects\r\nbool UsePackageManager(const TestParameters& testParameters);\r\n\r\n// Sets up the globals for the test caller.\r\nvoid InitializePackageManagerGlobals();\r\n\r\n// Sets the module to prevent it from unloading.\r\nvoid SetUnloadPreference(bool value);\r\n\r\n// Sets the module to prevent it from listening to termination signals.\r\nvoid SetDisableTerminationSignals(bool value);\r\n\r\n// Attempts to detect the target package as installed for the system.\r\nbool DetectForSystem(const TestParameters& testParameters);\r\n\r\n// Installs the target package for the system.\r\nbool InstallForSystem(const TestParameters& testParameters);\r\n"
  },
  {
    "path": "src/ComInprocTestbed/Tests.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Tests.h\"\r\n#include \"PackageManager.h\"\r\n\r\nusing namespace std::string_view_literals;\r\nusing namespace winrt::Microsoft::Management::Deployment;\r\n\r\nnamespace\r\n{\r\n#define ADVANCE_ARG_PARAMETER if (++i >= argc) { winrt::throw_hresult(E_INVALIDARG); }\r\n\r\n    std::string ToLower(std::string_view in)\r\n    {\r\n        std::string result(in);\r\n        std::transform(result.begin(), result.end(), result.begin(),\r\n            [](unsigned char c) { return static_cast<char>(std::tolower(c)); });\r\n        return result;\r\n    }\r\n\r\n#define BEGIN_ENUM_PARSE_FUNC(_type_) \\\r\n    _type_ Parse ## _type_(const char* input) \\\r\n    { \\\r\n        auto lower = ToLower(input); \\\r\n        if (lower.empty()) {}\r\n\r\n#define ITEM_ENUM_PARSE_FUNC(_type_, _value_) \\\r\n        else if (ToLower(#_value_) == lower) \\\r\n        { \\\r\n            return _type_ ## :: ## _value_; \\\r\n        }\r\n\r\n#define END_ENUM_PARSE_FUNC \\\r\n        winrt::throw_hresult(E_INVALIDARG); \\\r\n    }\r\n\r\n#define BEGIN_ENUM_NAME_FUNC(_type_) \\\r\n    std::string_view ToString(_type_); \\\r\n    std::ostream& operator<<(std::ostream& o, _type_ input) { return (o << ToString(input)); } \\\r\n    std::string_view ToString(_type_ input) \\\r\n    { \\\r\n        switch (input) {\r\n\r\n#define ITEM_ENUM_NAME_FUNC(_type_, _value_) \\\r\n        case _type_ ## :: ## _value_: return #_value_;\r\n\r\n#define END_ENUM_NAME_FUNC \\\r\n        } \\\r\n        return \"Unknown\"; \\\r\n    }\r\n\r\n    BEGIN_ENUM_PARSE_FUNC(ComInitializationType)\r\n        ITEM_ENUM_PARSE_FUNC(ComInitializationType, STA)\r\n        ITEM_ENUM_PARSE_FUNC(ComInitializationType, MTA)\r\n    END_ENUM_PARSE_FUNC\r\n\r\n    BEGIN_ENUM_NAME_FUNC(ComInitializationType)\r\n        ITEM_ENUM_NAME_FUNC(ComInitializationType, STA)\r\n        ITEM_ENUM_NAME_FUNC(ComInitializationType, MTA)\r\n    END_ENUM_NAME_FUNC\r\n\r\n    BEGIN_ENUM_PARSE_FUNC(UnloadBehavior)\r\n        ITEM_ENUM_PARSE_FUNC(UnloadBehavior, Allow)\r\n        ITEM_ENUM_PARSE_FUNC(UnloadBehavior, AtUninitialize)\r\n        ITEM_ENUM_PARSE_FUNC(UnloadBehavior, Never)\r\n    END_ENUM_PARSE_FUNC\r\n\r\n    BEGIN_ENUM_NAME_FUNC(UnloadBehavior)\r\n        ITEM_ENUM_NAME_FUNC(UnloadBehavior, Allow)\r\n        ITEM_ENUM_NAME_FUNC(UnloadBehavior, AtUninitialize)\r\n        ITEM_ENUM_NAME_FUNC(UnloadBehavior, Never)\r\n    END_ENUM_NAME_FUNC\r\n\r\n    BEGIN_ENUM_PARSE_FUNC(ActivationType)\r\n        ITEM_ENUM_PARSE_FUNC(ActivationType, ClassName)\r\n        ITEM_ENUM_PARSE_FUNC(ActivationType, CoCreateInstance)\r\n    END_ENUM_PARSE_FUNC\r\n\r\n    BEGIN_ENUM_NAME_FUNC(ActivationType)\r\n        ITEM_ENUM_NAME_FUNC(ActivationType, ClassName)\r\n        ITEM_ENUM_NAME_FUNC(ActivationType, CoCreateInstance)\r\n    END_ENUM_NAME_FUNC\r\n\r\n    BOOL CALLBACK CheckForWinGetWindow(HWND hwnd, LPARAM param)\r\n    {\r\n        bool* result = reinterpret_cast<bool*>(param);\r\n\r\n        DWORD windowProcessId = 0;\r\n        GetWindowThreadProcessId(hwnd, &windowProcessId);\r\n\r\n        if (GetCurrentProcessId() == windowProcessId)\r\n        {\r\n            int textLength = GetWindowTextLengthW(hwnd) + 1;\r\n            std::wstring windowText(textLength, '\\0');\r\n            textLength = GetWindowTextW(hwnd, &windowText[0], textLength);\r\n            windowText.resize(textLength);\r\n\r\n            if (L\"WingetMessageOnlyWindow\"sv == windowText)\r\n            {\r\n                *result = true;\r\n                return FALSE;\r\n            }\r\n        }\r\n\r\n        return TRUE;\r\n    }\r\n\r\n    // Look for the set of well known objects that should be present after we have spun everything up.\r\n    // Returns true if all well known objects are found in the expected state.\r\n    bool SearchForWellKnownObjects(bool expectExist, const Snapshot& snapshot)\r\n    {\r\n        bool result = true;\r\n\r\n        // Known modules in snapshot\r\n        bool knownModulesLoaded = snapshot.MicrosoftManagementDeploymentInProcLoaded && snapshot.WindowsPackageManagerLoaded;\r\n        if (knownModulesLoaded != expectExist)\r\n        {\r\n            std::cout << \"Known modules were not in expected state [\" << (expectExist ? \"loaded\" : \"unloaded\") << \"]\\n\";\r\n            result = false;\r\n        }\r\n\r\n        auto coreApplicationProperties = winrt::Windows::ApplicationModel::Core::CoreApplication::Properties();\r\n\r\n        // COM statics\r\n        for (std::wstring_view item : {\r\n            L\"WindowsPackageManager.CachedInstalledIndex\"sv,\r\n            L\"WindowsPackageManager.TerminationSignalHandler\"sv,\r\n        })\r\n        {\r\n            bool present = coreApplicationProperties.HasKey(item);\r\n\r\n            if (present != expectExist)\r\n            {\r\n                std::cout << \"CoreApplication property `\" << winrt::to_string(item) << \"` was not in expected state [\" << (expectExist ? \"should exist\" : \"should not exist\") << \"]\\n\";\r\n                result = false;\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    // Look for the set of termination signal monitoring objects that should be present after we have spun everything up.\r\n    // Returns true if all objects are found in the expected state.\r\n    bool SearchForTerminationSignalObjects(bool expectExist)\r\n    {\r\n        bool result = true;\r\n\r\n        // Shutdown monitoring window\r\n        bool foundWindow = false;\r\n        EnumWindows(CheckForWinGetWindow, reinterpret_cast<LPARAM>(&foundWindow));\r\n\r\n        if (foundWindow != expectExist)\r\n        {\r\n            std::cout << \"WinGet Window `WingetMessageOnlyWindow` was not in expected state [\" << (expectExist ? \"should exist\" : \"should not exist\") << \"]\\n\";\r\n            result = false;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::string GetBytesString(SIZE_T bytes)\r\n    {\r\n        constexpr SIZE_T s_kilo = 1024;\r\n        constexpr std::string_view s_sizes = \"BKMG\"sv;\r\n        size_t i = 0;\r\n\r\n        while ((i + 1) < s_sizes.size() && bytes > s_kilo)\r\n        {\r\n            bytes /= s_kilo;\r\n            ++i;\r\n        }\r\n\r\n        return std::to_string(bytes) + s_sizes[i];\r\n    }\r\n\r\n    const CLSID CLSID_PackageManager = { 0x2DDE4456, 0x64D9, 0x4673, 0x8F, 0x7E, 0xA4, 0xF1, 0x9A, 0x2E, 0x6C, 0xC3 }; // 2DDE4456-64D9-4673-8F7E-A4F19A2E6CC3\r\n    const CLSID CLSID_FindPackagesOptions = { 0x96B9A53A, 0x9228, 0x4DA0, 0xB0, 0x13, 0xBB, 0x1B, 0x20, 0x31, 0xAB, 0x3D }; // 96B9A53A-9228-4DA0-B013-BB1B2031AB3D\r\n    const CLSID CLSID_CreateCompositePackageCatalogOptions = { 0x768318A6, 0x2EB5, 0x400D, 0x84, 0xD0, 0xDF, 0x35, 0x34, 0xC3, 0x0F, 0x5D }; // 768318A6-2EB5-400D-84D0-DF3534C30F5D\r\n    const CLSID CLSID_InstallOptions = { 0xE2AF3BA8, 0x8A88, 0x4766, 0x9D, 0xDA, 0xAE, 0x40, 0x13, 0xAD, 0xE2, 0x86 }; // E2AF3BA8-8A88-4766-9DDA-AE4013ADE286\r\n    const CLSID CLSID_UninstallOptions = { 0x869CB959, 0xEB54, 0x425C, 0xA1, 0xE4, 0x1A, 0x1C, 0x29, 0x1C, 0x64, 0xE9 }; // 869CB959-EB54-425C-A1E4-1A1C291C64E9\r\n    const CLSID CLSID_PackageMatchFilter = { 0x57DC8962, 0x7343, 0x42CD, 0xB9, 0x1C, 0x04, 0xF6, 0xA2, 0x5D, 0xB1, 0xD0 }; // 57DC8962-7343-42CD-B91C-04F6A25DB1D0\r\n    const CLSID CLSID_PackageManagerSettings = { 0x80CF9D63, 0x5505, 0x4342, 0xB9, 0xB4, 0xBB, 0x87, 0x89, 0x5C, 0xA8, 0xBB }; // 80CF9D63-5505-4342-B9B4-BB87895CA8BB\r\n    const CLSID CLSID_DownloadOptions = { 0x4288DF96, 0xFDC9, 0x4B68, 0xB4, 0x03, 0x19, 0x3D, 0xBB, 0xF5, 0x6A, 0x24 }; // 4288DF96-FDC9-4B68-B403-193DBBF56A24\r\n    const CLSID CLSID_AuthenticationArguments = { 0x8D593114, 0x1CF1, 0x43B9, 0x87, 0x22, 0x4D, 0xBB, 0x30, 0x10, 0x32, 0x96 }; // 8D593114-1CF1-43B9-8722-4DBB30103296\r\n    const CLSID CLSID_RepairOptions = { 0x30c024c4, 0x852c, 0x4dd4, 0x98, 0x10, 0x13, 0x48, 0xc5, 0x1e, 0xf9, 0xbb }; // {30C024C4-852C-4DD4-9810-1348C51EF9BB}\r\n    const CLSID CLSID_AddPackageCatalogOptions = { 0x24e6f1fa, 0xe4c3, 0x4acd, 0x96, 0x5d, 0xdf, 0x21, 0x3f, 0xd5, 0x8f, 0x15 }; // {24E6F1FA-E4C3-4ACD-965D-DF213FD58F15}\r\n    const CLSID CLSID_RemovePackageCatalogOptions = { 0x1125d3a6, 0xe2ce, 0x479a, 0x91, 0xd5, 0x71, 0xa3, 0xf6, 0xf8, 0xb0, 0xb }; // {1125D3A6-E2CE-479A-91D5-71A3F6F8B00B}\r\n\r\n    template <typename T>\r\n    T CreatePackageManagerObject(ActivationType activationType, const CLSID& clsid)\r\n    {\r\n        if (ActivationType::ClassName == activationType)\r\n        {\r\n            return T{};\r\n        }\r\n        else if (ActivationType::CoCreateInstance == activationType)\r\n        {\r\n            return winrt::create_instance<T>(clsid);\r\n        }\r\n\r\n        winrt::throw_hresult(E_UNEXPECTED);\r\n    }\r\n}\r\n\r\nTestParameters::TestParameters(int argc, const char** argv)\r\n{\r\n    for (int i = 0; i < argc; ++i)\r\n    {\r\n        if (\"-test\"sv == argv[i])\r\n        {\r\n            ADVANCE_ARG_PARAMETER\r\n            TestToRun = ToLower(argv[i]);\r\n        }\r\n        else if (\"-com\"sv == argv[i])\r\n        {\r\n            ADVANCE_ARG_PARAMETER\r\n            ComInit = ParseComInitializationType(argv[i]);\r\n        }\r\n        else if (\"-leak-com\"sv == argv[i])\r\n        {\r\n            LeakCOM = true;\r\n        }\r\n        else if (\"-itr\"sv == argv[i])\r\n        {\r\n            ADVANCE_ARG_PARAMETER\r\n            Iterations = atoi(argv[i]);\r\n        }\r\n        else if (\"-pkg\"sv == argv[i])\r\n        {\r\n            ADVANCE_ARG_PARAMETER\r\n            PackageName = argv[i];\r\n        }\r\n        else if (\"-src\"sv == argv[i])\r\n        {\r\n            ADVANCE_ARG_PARAMETER\r\n            SourceName = argv[i];\r\n        }\r\n        else if (\"-url\"sv == argv[i])\r\n        {\r\n            ADVANCE_ARG_PARAMETER\r\n            SourceURL = argv[i];\r\n        }\r\n        else if (\"-unload\"sv == argv[i])\r\n        {\r\n            ADVANCE_ARG_PARAMETER\r\n            UnloadBehavior = ParseUnloadBehavior(argv[i]);\r\n        }\r\n        else if (\"-activation\"sv == argv[i])\r\n        {\r\n            ADVANCE_ARG_PARAMETER\r\n            ActivationType = ParseActivationType(argv[i]);\r\n        }\r\n        else if (\"-keep-factories\"sv == argv[i])\r\n        {\r\n            SkipClearFactories = true;\r\n        }\r\n        else if (\"-work-test-sleep\"sv == argv[i])\r\n        {\r\n            ADVANCE_ARG_PARAMETER\r\n            WorkTestSleepInterval = atoi(argv[i]);\r\n        }\r\n        else if (\"-no-term\"sv == argv[i])\r\n        {\r\n            DisableTerminationSignals = true;\r\n        }\r\n    }\r\n}\r\n\r\nvoid TestParameters::OutputDetails() const\r\n{\r\n    std::cout << \"Running inproc testbed with:\\n\"\r\n        \"  COM Init : \" << ComInit << \"\\n\"\r\n        \"  Activate : \" << ActivationType << \"\\n\"\r\n        \"    Clear  : \" << std::boolalpha << !SkipClearFactories << \"\\n\"\r\n        \"  Leak COM : \" << std::boolalpha << LeakCOM << \"\\n\"\r\n        \"  Unload   : \" << UnloadBehavior << \"\\n\"\r\n        \"    Expect : \" << std::boolalpha << UnloadExpected() << \"\\n\"\r\n        \"  Test     : \" << TestToRun << \"\\n\"\r\n        \"    Sleep  : \" << WorkTestSleepInterval << \"\\n\"\r\n        \"  Package  : \" << PackageName << \"\\n\"\r\n        \"  Source   : \" << SourceName << \"\\n\"\r\n        \"    URL    : \" << SourceURL << \"\\n\"\r\n        \"  Passes   : \" << Iterations << std::endl;\r\n}\r\n\r\nbool TestParameters::InitializeTestState() const\r\n{\r\n    HRESULT hr = S_OK;\r\n\r\n    if (ComInitializationType::STA == ComInit)\r\n    {\r\n        hr = RoInitialize(RO_INIT_SINGLETHREADED);\r\n    }\r\n    else if (ComInitializationType::MTA == ComInit)\r\n    {\r\n        hr = RoInitialize(RO_INIT_MULTITHREADED);\r\n    }\r\n\r\n    if (FAILED(hr))\r\n    {\r\n        std::cout << \"RoInitialize returned \" << hr << std::endl;\r\n        return false;\r\n    }\r\n\r\n    if (UnloadBehavior::Never == UnloadBehavior || UnloadBehavior::AtUninitialize == UnloadBehavior)\r\n    {\r\n        SetUnloadPreference(false);\r\n    }\r\n\r\n    return true;\r\n}\r\n\r\nbool TestParameters::InitializeIterationState() const\r\n{\r\n    InitializePackageManagerGlobals();\r\n\r\n    if (DisableTerminationSignals)\r\n    {\r\n        SetDisableTerminationSignals(true);\r\n    }\r\n\r\n    return true;\r\n}\r\n\r\nstd::unique_ptr<ITest> TestParameters::CreateTest() const\r\n{\r\n    if (\"unload_check\"sv == TestToRun)\r\n    {\r\n        return std::make_unique<UnloadAndCheckForLeaks>(*this);\r\n    }\r\n    else if (\"install_detect\"sv == TestToRun)\r\n    {\r\n        return std::make_unique<InstallForSystem_DetectPresence>(*this);\r\n    }\r\n\r\n    return {};\r\n}\r\n\r\nvoid TestParameters::UninitializeTestState() const\r\n{\r\n    if (UnloadBehavior::AtUninitialize == UnloadBehavior)\r\n    {\r\n        SetUnloadPreference(true);\r\n    }\r\n\r\n    if (!LeakCOM)\r\n    {\r\n        RoUninitialize();\r\n    }\r\n}\r\n\r\nbool TestParameters::UnloadExpected() const\r\n{\r\n    bool shouldUnload = true;\r\n    if (UnloadBehavior::Never == UnloadBehavior || UnloadBehavior::AtUninitialize == UnloadBehavior ||\r\n        (ActivationType::ClassName == ActivationType && SkipClearFactories))\r\n    {\r\n        shouldUnload = false;\r\n    }\r\n    return shouldUnload;\r\n}\r\n\r\nPackageManager TestParameters::CreatePackageManager() const\r\n{\r\n    return CreatePackageManagerObject<PackageManager>(ActivationType, CLSID_PackageManager);\r\n}\r\n\r\nCreateCompositePackageCatalogOptions TestParameters::CreateCreateCompositePackageCatalogOptions() const\r\n{\r\n    return CreatePackageManagerObject<CreateCompositePackageCatalogOptions>(ActivationType, CLSID_CreateCompositePackageCatalogOptions);\r\n}\r\n\r\nPackageMatchFilter TestParameters::CreatePackageMatchFilter() const\r\n{\r\n    return CreatePackageManagerObject<PackageMatchFilter>(ActivationType, CLSID_PackageMatchFilter);\r\n}\r\n\r\nFindPackagesOptions TestParameters::CreateFindPackagesOptions() const\r\n{\r\n    return CreatePackageManagerObject<FindPackagesOptions>(ActivationType, CLSID_FindPackagesOptions);\r\n}\r\n\r\nDownloadOptions TestParameters::CreateDownloadOptions() const\r\n{\r\n    return CreatePackageManagerObject<DownloadOptions>(ActivationType, CLSID_DownloadOptions);\r\n}\r\n\r\nAddPackageCatalogOptions TestParameters::CreateAddPackageCatalogOptions() const\r\n{\r\n    return CreatePackageManagerObject<AddPackageCatalogOptions>(ActivationType, CLSID_AddPackageCatalogOptions);\r\n}\r\n\r\nInstallOptions TestParameters::CreateInstallOptions() const\r\n{\r\n    return CreatePackageManagerObject<InstallOptions>(ActivationType, CLSID_InstallOptions);\r\n}\r\n\r\nSnapshot::Snapshot()\r\n{\r\n    const DWORD processId = GetCurrentProcessId();\r\n    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE, processId);\r\n\r\n    // Count threads in this process\r\n    THREADENTRY32 threadEntry{};\r\n    threadEntry.dwSize = sizeof(threadEntry);\r\n\r\n    if (Thread32First(snapshot, &threadEntry))\r\n    {\r\n        do\r\n        {\r\n            if (processId == threadEntry.th32OwnerProcessID)\r\n            {\r\n                ++ThreadCount;\r\n            }\r\n        } while (Thread32Next(snapshot, &threadEntry));\r\n    }\r\n\r\n    // Count modules\r\n    MODULEENTRY32 moduleEntry{};\r\n    moduleEntry.dwSize = sizeof(moduleEntry);\r\n\r\n    if (Module32First(snapshot, &moduleEntry))\r\n    {\r\n        do\r\n        {\r\n            if (moduleEntry.szModule == L\"Microsoft.Management.Deployment.InProc.dll\"sv)\r\n            {\r\n                MicrosoftManagementDeploymentInProcLoaded = true;\r\n            }\r\n            else if (moduleEntry.szModule == L\"WindowsPackageManager.dll\"sv)\r\n            {\r\n                WindowsPackageManagerLoaded = true;\r\n            }\r\n\r\n            ++ModuleCount;\r\n        } while (Module32Next(snapshot, &moduleEntry));\r\n    }\r\n\r\n    // Get memory stats\r\n    GetProcessMemoryInfo(GetCurrentProcess(), reinterpret_cast<PPROCESS_MEMORY_COUNTERS>(&Memory), sizeof(Memory));\r\n\r\n    CloseHandle(snapshot);\r\n}\r\n\r\nUnloadAndCheckForLeaks::UnloadAndCheckForLeaks(const TestParameters& parameters) : m_parameters(parameters)\r\n{\r\n}\r\n\r\nbool UnloadAndCheckForLeaks::RunIterationWork()\r\n{\r\n    std::cout << \"UnloadAndCheckForLeaks::RunIterationWork\\n\";\r\n    return UsePackageManager(m_parameters);\r\n}\r\n\r\nbool UnloadAndCheckForLeaks::RunIterationTest()\r\n{\r\n    std::cout << \"UnloadAndCheckForLeaks::RunIterationTest\\n\";\r\n\r\n    Snapshot beforeUnload;\r\n    if (!SearchForWellKnownObjects(true, beforeUnload) ||\r\n        !SearchForTerminationSignalObjects(!m_parameters.DisableTerminationSignals))\r\n    {\r\n        return false;\r\n    }\r\n\r\n    CoFreeUnusedLibrariesEx(0, 0);\r\n\r\n    Snapshot afterUnload;\r\n    m_iterationSnapshots.emplace_back(beforeUnload, afterUnload);\r\n\r\n    if (!SearchForWellKnownObjects(!m_parameters.UnloadExpected(), afterUnload) ||\r\n        !SearchForTerminationSignalObjects(!m_parameters.UnloadExpected() && !m_parameters.DisableTerminationSignals))\r\n    {\r\n        return false;\r\n    }\r\n\r\n    return true;\r\n}\r\n\r\nbool UnloadAndCheckForLeaks::RunFinal()\r\n{\r\n    constexpr std::streamsize s_columnWidth = 5;\r\n\r\n    bool result = true;\r\n\r\n    std::cout << \"--- UnloadAndCheckForLeaks results ---\\n\";\r\n    std::cout << std::setfill(' ');\r\n\r\n    // --- Threads ---\r\n    std::cout << \"Thread Count [Initial: \" << m_initialSnapshot.ThreadCount << \"]\\n\";\r\n\r\n    std::cout << \"Iteration  \";\r\n    for (size_t i = 0; i < m_iterationSnapshots.size(); ++i)\r\n    {\r\n        std::cout << std::setw(s_columnWidth) << (i + 1);\r\n    }\r\n    std::cout << '\\n';\r\n\r\n    std::cout << \"Pre Unload \";\r\n    for (const auto& snapshot : m_iterationSnapshots)\r\n    {\r\n        std::cout << std::setw(s_columnWidth) << snapshot.first.ThreadCount;\r\n    }\r\n    std::cout << '\\n';\r\n\r\n    std::cout << \"Post Unload\";\r\n    for (const auto& snapshot : m_iterationSnapshots)\r\n    {\r\n        std::cout << std::setw(s_columnWidth) << snapshot.second.ThreadCount;\r\n    }\r\n    std::cout << '\\n';\r\n\r\n    // Look for consistent increase in measured values\r\n    if (m_iterationSnapshots.size() > 1)\r\n    {\r\n        size_t previousValue = m_iterationSnapshots[0].second.ThreadCount;\r\n        bool consistentIncrease = true;\r\n\r\n        for (size_t i = 1; i < m_iterationSnapshots.size(); ++i)\r\n        {\r\n            size_t currentValue = m_iterationSnapshots[i].second.ThreadCount;\r\n            if (currentValue > previousValue)\r\n            {\r\n                previousValue = currentValue;\r\n            }\r\n            else\r\n            {\r\n                consistentIncrease = false;\r\n                break;\r\n            }\r\n        }\r\n\r\n        if (consistentIncrease)\r\n        {\r\n            std::cout << \"Post unload thread count shows consistent increase; failing test.\\n\";\r\n            result = false;\r\n        }\r\n    }\r\n\r\n    // --- Modules ---\r\n    std::cout << \"Module Count [Initial: \" << m_initialSnapshot.ModuleCount << \"]\\n\";\r\n\r\n    std::cout << \"Iteration  \";\r\n    for (size_t i = 0; i < m_iterationSnapshots.size(); ++i)\r\n    {\r\n        std::cout << std::setw(s_columnWidth) << (i + 1);\r\n    }\r\n    std::cout << '\\n';\r\n\r\n    std::cout << \"Pre Unload \";\r\n    for (const auto& snapshot : m_iterationSnapshots)\r\n    {\r\n        std::cout << std::setw(s_columnWidth) << snapshot.first.ModuleCount;\r\n    }\r\n    std::cout << '\\n';\r\n\r\n    std::cout << \"Post Unload\";\r\n    for (const auto& snapshot : m_iterationSnapshots)\r\n    {\r\n        std::cout << std::setw(s_columnWidth) << snapshot.second.ModuleCount;\r\n    }\r\n    std::cout << '\\n';\r\n\r\n    // Look for modules not unloading\r\n    if (m_parameters.UnloadExpected() && m_iterationSnapshots.size() > 1)\r\n    {\r\n        bool noUnloadFound = false;\r\n\r\n        for (size_t i = 0; i < m_iterationSnapshots.size(); ++i)\r\n        {\r\n            if (m_iterationSnapshots[i].first.ModuleCount == m_iterationSnapshots[i].second.ModuleCount)\r\n            {\r\n                noUnloadFound = true;\r\n            }\r\n        }\r\n\r\n        if (noUnloadFound)\r\n        {\r\n            std::cout << \"Module count did not decrease during at least one iteration; failing test.\\n\";\r\n            result = false;\r\n        }\r\n    }\r\n\r\n    // --- Memory ---\r\n    std::cout << \"Private Usage [Initial: \" << GetBytesString(m_initialSnapshot.Memory.PrivateUsage) << \"]\\n\";\r\n\r\n    std::cout << \"Iteration  \";\r\n    for (size_t i = 0; i < m_iterationSnapshots.size(); ++i)\r\n    {\r\n        std::cout << std::setw(s_columnWidth) << (i + 1);\r\n    }\r\n    std::cout << '\\n';\r\n\r\n    std::cout << \"Pre Unload \";\r\n    for (const auto& snapshot : m_iterationSnapshots)\r\n    {\r\n        std::cout << std::setw(s_columnWidth) << GetBytesString(snapshot.first.Memory.PrivateUsage);\r\n    }\r\n    std::cout << '\\n';\r\n\r\n    std::cout << \"Post Unload\";\r\n    for (const auto& snapshot : m_iterationSnapshots)\r\n    {\r\n        std::cout << std::setw(s_columnWidth) << GetBytesString(snapshot.second.Memory.PrivateUsage);\r\n    }\r\n    std::cout << '\\n';\r\n\r\n    return result;\r\n}\r\n\r\nInstallForSystem_DetectPresence::InstallForSystem_DetectPresence(const TestParameters& parameters) : m_parameters(parameters)\r\n{\r\n}\r\n\r\nbool InstallForSystem_DetectPresence::RunIterationWork()\r\n{\r\n    std::cout << \"Before installing, the detection state was: \" << std::boolalpha << DetectForSystem(m_parameters) << '\\n';\r\n\r\n    return InstallForSystem(m_parameters);\r\n}\r\n\r\nbool InstallForSystem_DetectPresence::RunIterationTest()\r\n{\r\n    bool result = DetectForSystem(m_parameters);\r\n    std::cout << \"After installing, the detection state was: \" << std::boolalpha << result << '\\n';\r\n    return result;\r\n}\r\n\r\nbool InstallForSystem_DetectPresence::RunFinal()\r\n{\r\n    return true;\r\n}\r\n"
  },
  {
    "path": "src/ComInprocTestbed/Tests.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <Windows.h>\r\n#include <winrt/Microsoft.Management.Deployment.h>\r\n#include <memory>\r\n#include <vector>\r\n\r\n// Represents a test that will be performed.\r\nstruct ITest\r\n{\r\n    virtual ~ITest() = default;\r\n\r\n    // Runs an iteration of the work. Performed at the beginning of the iteration.\r\n    virtual bool RunIterationWork() = 0;\r\n\r\n    // Runs an iteration of the test. Performed at the end of the iteration.\r\n    virtual bool RunIterationTest() = 0;\r\n\r\n    // Performs the final test validation.\r\n    virtual bool RunFinal() = 0;\r\n};\r\n\r\nenum class ComInitializationType\r\n{\r\n    STA,\r\n    MTA,\r\n};\r\n\r\nenum class UnloadBehavior\r\n{\r\n    Allow,\r\n    AtUninitialize,\r\n    Never,\r\n};\r\n\r\nenum class ActivationType\r\n{\r\n    ClassName,\r\n    CoCreateInstance,\r\n};\r\n\r\n// Test parameters from command line\r\nstruct TestParameters\r\n{\r\n    TestParameters(int argc, const char** argv);\r\n\r\n    void OutputDetails() const;\r\n\r\n    bool InitializeTestState() const;\r\n\r\n    bool InitializeIterationState() const;\r\n\r\n    std::unique_ptr<ITest> CreateTest() const;\r\n\r\n    void UninitializeTestState() const;\r\n\r\n    // Determines if we expect COM to unload the module based on inputs.\r\n    bool UnloadExpected() const;\r\n\r\n    winrt::Microsoft::Management::Deployment::PackageManager CreatePackageManager() const;\r\n    winrt::Microsoft::Management::Deployment::CreateCompositePackageCatalogOptions CreateCreateCompositePackageCatalogOptions() const;\r\n    winrt::Microsoft::Management::Deployment::PackageMatchFilter CreatePackageMatchFilter() const;\r\n    winrt::Microsoft::Management::Deployment::FindPackagesOptions CreateFindPackagesOptions() const;\r\n    winrt::Microsoft::Management::Deployment::DownloadOptions CreateDownloadOptions() const;\r\n    winrt::Microsoft::Management::Deployment::AddPackageCatalogOptions CreateAddPackageCatalogOptions() const;\r\n    winrt::Microsoft::Management::Deployment::InstallOptions CreateInstallOptions() const;\r\n\r\n    std::string TestToRun;\r\n    ComInitializationType ComInit = ComInitializationType::MTA;\r\n    bool LeakCOM = false;\r\n    int Iterations = 1;\r\n    std::string PackageName = \"Microsoft.Edit\";\r\n    std::string SourceName = \"winget\";\r\n    std::string SourceURL;\r\n    UnloadBehavior UnloadBehavior = UnloadBehavior::Allow;\r\n    ActivationType ActivationType = ActivationType::ClassName;\r\n    bool SkipClearFactories = false;\r\n    DWORD WorkTestSleepInterval = 0;\r\n    bool DisableTerminationSignals = false;\r\n};\r\n\r\n// Captures a snapshot of current resource usage.\r\nstruct Snapshot\r\n{\r\n    Snapshot();\r\n\r\n    size_t ThreadCount = 0;\r\n    size_t ModuleCount = 0;\r\n    bool MicrosoftManagementDeploymentInProcLoaded = false;\r\n    bool WindowsPackageManagerLoaded = false;\r\n    PROCESS_MEMORY_COUNTERS_EX2 Memory{};\r\n};\r\n\r\n// A test that unloads the COM module and looks for resources that were not released.\r\nstruct UnloadAndCheckForLeaks : public ITest\r\n{\r\n    UnloadAndCheckForLeaks(const TestParameters& parameters);\r\n\r\n    bool RunIterationWork() override;\r\n\r\n    bool RunIterationTest() override;\r\n\r\n    bool RunFinal() override;\r\n\r\nprivate:\r\n    const TestParameters& m_parameters;\r\n    Snapshot m_initialSnapshot;\r\n    std::vector<std::pair<Snapshot, Snapshot>> m_iterationSnapshots;\r\n};\r\n\r\n// A test that installs the package machine wide and then attempts to detect that it is installed.\r\nstruct InstallForSystem_DetectPresence : public ITest\r\n{\r\n    InstallForSystem_DetectPresence(const TestParameters& parameters);\r\n\r\n    bool RunIterationWork() override;\r\n\r\n    bool RunIterationTest() override;\r\n\r\n    bool RunFinal() override;\r\n\r\nprivate:\r\n    const TestParameters& m_parameters;\r\n};\r\n"
  },
  {
    "path": "src/ComInprocTestbed/main.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"PackageManager.h\"\r\n#include \"Tests.h\"\r\n\r\nusing namespace std::string_view_literals;\r\n\r\nint main(int argc, const char** argv) try\r\n{\r\n    const TestParameters testParameters(argc, argv);\r\n    testParameters.OutputDetails();\r\n    if (!testParameters.InitializeTestState())\r\n    {\r\n        return 2;\r\n    }\r\n\r\n    auto test = testParameters.CreateTest();\r\n\r\n    for (int i = 0; i < testParameters.Iterations; ++i)\r\n    {\r\n        std::cout << \"Begin iteration \" << (i + 1) << std::endl;\r\n\r\n        if (!testParameters.InitializeIterationState())\r\n        {\r\n            return 2;\r\n        }\r\n\r\n        if (test && !test->RunIterationWork())\r\n        {\r\n            return 3;\r\n        }\r\n\r\n        if (!testParameters.SkipClearFactories)\r\n        {\r\n            winrt::clear_factory_cache();\r\n        }\r\n\r\n        if (testParameters.WorkTestSleepInterval)\r\n        {\r\n            Sleep(testParameters.WorkTestSleepInterval);\r\n        }\r\n\r\n        if (test && !test->RunIterationTest())\r\n        {\r\n            return 4;\r\n        }\r\n\r\n        std::cout << \"Iteration \" << (i + 1) << \" completed\" << std::endl;\r\n    }\r\n\r\n    if (test && !test->RunFinal())\r\n    {\r\n        return 5;\r\n    }\r\n\r\n    testParameters.UninitializeTestState();\r\n\r\n    std::cout << \"Tests completed\" << std::endl;\r\n    return 0;\r\n}\r\ncatch (const std::exception& e)\r\n{\r\n    std::cout << \"Caught std exception: \" << e.what() << std::endl;\r\n    return 1;\r\n}\r\ncatch (const winrt::hresult_error& hre)\r\n{\r\n    std::cout << \"Caught winrt exception: \" << winrt::to_string(hre.message()) << std::endl;\r\n    return 1;\r\n}\r\ncatch (...)\r\n{\r\n    std::cout << \"Caught unknown exception\" << std::endl;\r\n    return 1;\r\n}\r\n"
  },
  {
    "path": "src/ComInprocTestbed/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<packages>\r\n  <package id=\"Microsoft.Windows.CppWinRT\" version=\"2.0.250303.1\" targetFramework=\"native\" />\r\n</packages>"
  },
  {
    "path": "src/ComInprocTestbed/pch.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n"
  },
  {
    "path": "src/ComInprocTestbed/pch.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n\r\n#define NOMINMAX\r\n#include <Windows.h>\r\n#include <psapi.h>\r\n#include <roapi.h>\r\n#include <tlhelp32.h>\r\n\r\n#include <winrt/Windows.ApplicationModel.Core.h>\r\n#include <winrt/Windows.Foundation.Collections.h>\r\n#include <winrt/Microsoft.Management.Deployment.h>\r\n\r\n#include <algorithm>\r\n#include <future>\r\n#include <iomanip>\r\n#include <iostream>\r\n#include <memory>\r\n#include <string>\r\n#include <string_view>\r\n#include <utility>\r\n"
  },
  {
    "path": "src/ConfigurationRemotingServer/ConfigurationRemotingServer.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n    <SupportedOSPlatformVersion>10.0.17763.0</SupportedOSPlatformVersion>\r\n    <Platforms>x64;x86;arm64</Platforms>\r\n    <OutputPath>$(SolutionDir)$(Platform)\\$(Configuration)\\$(MSBuildProjectName)\\</OutputPath>\r\n    <SelfContained>true</SelfContained>\r\n    <RuntimeIdentifiers>win-x64;win-x86;win-arm64</RuntimeIdentifiers>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\" '$(Platform)' == 'x64' \">\r\n    <RuntimeIdentifier>win-x64</RuntimeIdentifier>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\" '$(Platform)' == 'x86' \">\r\n    <RuntimeIdentifier>win-x86</RuntimeIdentifier>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\" '$(Platform)' == 'arm64' \">\r\n    <RuntimeIdentifier>win-arm64</RuntimeIdentifier>\r\n  </PropertyGroup>\r\n\r\n  <Import Project=\"..\\targets\\ReferenceEmbeddedCsWinRTProject.targets\" />\r\n\r\n  <ItemGroup>\r\n    <PackageReference Include=\"Newtonsoft.Json\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\Microsoft.Management.Configuration.Processor\\Microsoft.Management.Configuration.Processor.csproj\" />\r\n    <ProjectReference Include=\"..\\Microsoft.Management.Configuration\\Microsoft.Management.Configuration.vcxproj\" />\r\n    <!-- Pull in any other .NET projects that need to ship with the package so that they can resolve the nuget graph together and land in the same output location. -->\r\n    <ProjectReference Include=\"..\\WinGetMCPServer\\WinGetMCPServer.csproj\" />\r\n  </ItemGroup>\r\n\r\n  <Target Name=\"PwshFiles\" AfterTargets=\"AfterBuild\">\r\n    <ItemGroup>\r\n      <RefFiles Include=\"$(SolutionDir)\\AnyCPU\\$(Configuration)\\Microsoft.Management.Configuration.Processor\\$(TargetFramework)\\win\\ref\\**\\*.*\" />\r\n      <WinModuleFiles Include=\"$(SolutionDir)\\AnyCPU\\$(Configuration)\\Microsoft.Management.Configuration.Processor\\$(TargetFramework)\\win\\Modules\\**\\*.*\" />\r\n      <!-- The output path for this project is different on some builds where the RIDs are not used in the output. -->\r\n      <RefFiles Condition=\"!Exists(@(RefFiles))\" Include=\"$(SolutionDir)\\AnyCPU\\$(Configuration)\\Microsoft.Management.Configuration.Processor\\ref\\**\\*.*\" />\r\n      <WinModuleFiles Condition=\"!Exists(@(WinModuleFiles))\" Include=\"$(SolutionDir)\\AnyCPU\\$(Configuration)\\Microsoft.Management.Configuration.Processor\\Modules\\**\\*.*\" />\r\n    </ItemGroup>\r\n    <Copy SourceFiles=\"@(RefFiles)\" DestinationFolder=\"$(OutputPath)\\ref\\\" />\r\n    <Copy SourceFiles=\"@(WinModuleFiles)\" DestinationFolder=\"$(OutputPath)\\Modules\\%(RecursiveDir)\\\" />\r\n  </Target>\r\n\r\n</Project>"
  },
  {
    "path": "src/ConfigurationRemotingServer/EnvironmentChangeListener.cs",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n\r\nusing System.Runtime.InteropServices;\r\nusing System.Threading;\r\n\r\nnamespace ConfigurationRemotingServer\r\n{\r\n    internal class EnvironmentChangeListener\r\n    {\r\n        // Window message constants\r\n        private const int WM_SETTINGCHANGE = 0x001A;\r\n        private const int WM_QUIT = 0x0012;\r\n\r\n        // User32.dll imports\r\n        [DllImport(\"user32.dll\")]\r\n        private static extern IntPtr CreateWindowEx(\r\n            uint dwExStyle, string lpClassName, string lpWindowName, uint dwStyle,\r\n            int x, int y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu,\r\n            IntPtr hInstance, IntPtr lpParam);\r\n\r\n        [DllImport(\"user32.dll\")]\r\n        private static extern bool DestroyWindow(IntPtr hWnd);\r\n\r\n        [DllImport(\"user32.dll\")]\r\n        private static extern IntPtr DefWindowProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);\r\n\r\n        [DllImport(\"user32.dll\")]\r\n        private static extern bool GetMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax);\r\n\r\n        [DllImport(\"user32.dll\")]\r\n        private static extern bool PostMessageW(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);\r\n\r\n        [DllImport(\"user32.dll\")]\r\n        private static extern bool TranslateMessage(ref MSG lpMsg);\r\n\r\n        [DllImport(\"user32.dll\")]\r\n        private static extern IntPtr DispatchMessage(ref MSG lpMsg);\r\n\r\n        [DllImport(\"user32.dll\")]\r\n        private static extern ushort RegisterClass(ref WNDCLASS lpWndClass);\r\n\r\n        [DllImport(\"kernel32.dll\")]\r\n        private static extern IntPtr GetModuleHandle(string? lpModuleName);\r\n\r\n        // Windows message structure\r\n        [StructLayout(LayoutKind.Sequential)]\r\n        public struct MSG\r\n        {\r\n            public IntPtr hwnd;\r\n            public uint message;\r\n            public IntPtr wParam;\r\n            public IntPtr lParam;\r\n            public uint time;\r\n            public POINT pt;\r\n            public uint lPrivate;\r\n        }\r\n\r\n        [StructLayout(LayoutKind.Sequential)]\r\n        public struct POINT\r\n        {\r\n            public int x;\r\n            public int y;\r\n        }\r\n\r\n        // Window class structure\r\n        [StructLayout(LayoutKind.Sequential)]\r\n        public struct WNDCLASS\r\n        {\r\n            public uint style;\r\n            public IntPtr lpfnWndProc;\r\n            public int cbClsExtra;\r\n            public int cbWndExtra;\r\n            public IntPtr hInstance;\r\n            public IntPtr hIcon;\r\n            public IntPtr hCursor;\r\n            public IntPtr hBackground;\r\n            [MarshalAs(UnmanagedType.LPStr)]\r\n            public string? lpszMenuName;\r\n            [MarshalAs(UnmanagedType.LPStr)]\r\n            public string lpszClassName;\r\n        }\r\n\r\n        // Window procedure delegate\r\n        private delegate IntPtr WndProcDelegate(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);\r\n        // Keep a reference to the delegate to prevent it from being garbage collected\r\n        private static WndProcDelegate? _wndProcDelegate;\r\n\r\n        private IntPtr _hwnd;\r\n        private Thread _thread;\r\n\r\n        public delegate void EnvironmentChangedEventHandler();\r\n        public static event EnvironmentChangedEventHandler? EnvironmentChanged;\r\n\r\n        public EnvironmentChangeListener()\r\n        {\r\n            _thread = new Thread(MessageLoop);\r\n            _thread.Start();\r\n        }\r\n\r\n        public void Stop()\r\n        {\r\n            if (PostMessageW(_hwnd, WM_QUIT, IntPtr.Zero, IntPtr.Zero))\r\n            {\r\n                _thread.Join();\r\n            }\r\n        }\r\n\r\n        private void MessageLoop()\r\n        {\r\n            // Register window class\r\n            string className = \"EnvironmentMonitorClass\";\r\n            _wndProcDelegate = WndProc;\r\n\r\n            WNDCLASS wndClass = new WNDCLASS\r\n            {\r\n                style = 0,\r\n                lpfnWndProc = Marshal.GetFunctionPointerForDelegate(_wndProcDelegate),\r\n                cbClsExtra = 0,\r\n                cbWndExtra = 0,\r\n                hInstance = GetModuleHandle(null),\r\n                hIcon = IntPtr.Zero,\r\n                hCursor = IntPtr.Zero,\r\n                hBackground = IntPtr.Zero,\r\n                lpszMenuName = \"\",\r\n                lpszClassName = className\r\n            };\r\n\r\n            RegisterClass(ref wndClass);\r\n\r\n            // Create hidden window\r\n            const uint WS_OVERLAPPED = 0x00000000;\r\n            const uint WS_EX_TOOL_WINDOW = 0x00000080;\r\n\r\n            _hwnd = CreateWindowEx(\r\n                WS_EX_TOOL_WINDOW,\r\n                className,\r\n                \"Environment Monitor\",\r\n                WS_OVERLAPPED,\r\n                0, 0, 0, 0,\r\n                IntPtr.Zero, IntPtr.Zero,\r\n                GetModuleHandle(null), IntPtr.Zero);\r\n\r\n            if (_hwnd == IntPtr.Zero)\r\n            {\r\n                return;\r\n            }\r\n\r\n            MSG msg;\r\n            while (GetMessage(out msg, IntPtr.Zero, 0, 0))\r\n            {\r\n                TranslateMessage(ref msg);\r\n                DispatchMessage(ref msg);\r\n            }\r\n\r\n            // Clean up\r\n            DestroyWindow(_hwnd);\r\n        }\r\n\r\n        private static IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)\r\n        {\r\n            switch (msg)\r\n            {\r\n                case WM_SETTINGCHANGE:\r\n                    // Check if this is an environment variable change notification\r\n                    string? msgInfo = Marshal.PtrToStringAnsi(lParam);\r\n                    if (msgInfo == \"Environment\")\r\n                    {\r\n                        if (EnvironmentChanged != null)\r\n                        {\r\n                            EnvironmentChanged.Invoke();\r\n                        }\r\n                    }\r\n                    break;\r\n            }\r\n\r\n            return DefWindowProc(hWnd, msg, wParam, lParam);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/ConfigurationRemotingServer/Program.cs",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\nusing System.Reflection;\r\nusing System.Runtime.InteropServices;\r\nusing System.Runtime.Loader;\r\nusing System.Text;\r\nusing System.Text.Json;\r\nusing System.Text.Json.Serialization;\r\nusing Microsoft.Management.Configuration;\r\nusing Microsoft.Management.Configuration.Processor;\r\nusing Microsoft.Management.Configuration.Processor.Helpers;\r\nusing WinRT;\r\nusing IConfigurationSetProcessorFactory = global::Microsoft.Management.Configuration.IConfigurationSetProcessorFactory;\r\n\r\nnamespace ConfigurationRemotingServer\r\n{\r\n    /// <summary>\r\n    /// Custom assembly load context.\r\n    /// </summary>\r\n    internal class NativeAssemblyLoadContext : AssemblyLoadContext\r\n    {\r\n        private static readonly string PackageRootPath;\r\n\r\n        private static readonly NativeAssemblyLoadContext NativeALC = new();\r\n\r\n        static NativeAssemblyLoadContext()\r\n        {\r\n            var self = typeof(NativeAssemblyLoadContext).Assembly;\r\n            PackageRootPath = Path.Combine(\r\n                Path.GetDirectoryName(self.Location)!,\r\n                \"..\");\r\n        }\r\n\r\n        private NativeAssemblyLoadContext()\r\n            : base(\"NativeAssemblyLoadContext\", isCollectible: false)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Handler to resolve unmanaged assemblies.\r\n        /// </summary>\r\n        /// <param name=\"context\">Assembly load context.</param>\r\n        /// <param name=\"name\">Assembly name.</param>\r\n        /// <returns>The assembly, null if not in our assembly location.</returns>\r\n        internal static IntPtr ResolvingUnmanagedHandler(Assembly context, string name)\r\n        {\r\n            if (name.Equals(\"WindowsPackageManager.dll\", StringComparison.OrdinalIgnoreCase))\r\n            {\r\n                return NativeALC.LoadUnmanagedDll(name);\r\n            }\r\n\r\n            return IntPtr.Zero;\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)\r\n        {\r\n            string path = Path.Combine(PackageRootPath, unmanagedDllName);\r\n            if (File.Exists(path))\r\n            {\r\n                return this.LoadUnmanagedDllFromPath(path);\r\n            }\r\n\r\n            return IntPtr.Zero;\r\n        }\r\n    }\r\n\r\n    internal class Program\r\n    {\r\n        private const string CommandLineSectionSeparator = \"~~~~~~\";\r\n        private const string ExternalModulesName = \"ExternalModules\";\r\n\r\n        static int Main(string[] args)\r\n        {\r\n            // Remove any attached console to prevent modules (or their actions) from writing to our console.\r\n            FreeConsole();\r\n\r\n            // Help find WindowsPackageManager.dll\r\n            AssemblyLoadContext.Default.ResolvingUnmanagedDll += NativeAssemblyLoadContext.ResolvingUnmanagedHandler;\r\n\r\n            string staticsCallback = args[1];\r\n\r\n            // Listen for setting change message and update PATH if needed.\r\n            EnvironmentChangeListener.EnvironmentChanged += OnEnvironmentChanged;\r\n            EnvironmentChangeListener environmentChangeListener = new EnvironmentChangeListener();\r\n\r\n            try\r\n            {\r\n                string completionEventName = args[2];\r\n                uint parentProcessId = uint.Parse(args[3]);\r\n                string processorEngine = args[4];\r\n\r\n                ConfigurationSet? limitationSet = null;\r\n                LimitationSetMetadata? limitationSetMetadata = null;\r\n\r\n                // Parse limitation set if applicable.\r\n                // The format will be:\r\n                //     <Common args for initialization> ~~~~~~ <Metadata json> ~~~~~~ <Limitation Set in yaml>\r\n                // Metadata json format:\r\n                //     {\r\n                //         \"path\": \"C:\\full\\file\\path.yaml\"\r\n                //     }\r\n                // If a limitation set is provided, the processor will be limited\r\n                // to only work on units defined inside the limitation set.\r\n                var commandPtr = GetCommandLineW();\r\n                var commandStr = Marshal.PtrToStringUni(commandPtr) ?? string.Empty;\r\n\r\n                // In case the limitation set content contains the separator, we'll not use Split method.\r\n                var firstSeparatorIndex = commandStr.IndexOf(CommandLineSectionSeparator);\r\n                if (firstSeparatorIndex > 0)\r\n                {\r\n                    var secondSeparatorIndex = commandStr.IndexOf(CommandLineSectionSeparator, firstSeparatorIndex + CommandLineSectionSeparator.Length);\r\n                    if (secondSeparatorIndex <= 0)\r\n                    {\r\n                        throw new ArgumentException(\"The input command contains only one separator string.\");\r\n                    }\r\n\r\n                    // Parse limitation set.\r\n                    byte[] limitationSetBytes = Encoding.UTF8.GetBytes(commandStr.Substring(secondSeparatorIndex + CommandLineSectionSeparator.Length));\r\n                    MemoryStream memoryStream = new MemoryStream();\r\n                    memoryStream.Write(limitationSetBytes);\r\n                    memoryStream.Flush();\r\n                    memoryStream.Seek(0, SeekOrigin.Begin);\r\n                    ConfigurationProcessor processor = new ConfigurationProcessor((IConfigurationSetProcessorFactory?)null);\r\n                    var limitationSetResult = processor.OpenConfigurationSet(memoryStream.AsInputStream());\r\n                    memoryStream.Close();\r\n\r\n                    if (limitationSetResult.ResultCode != null)\r\n                    {\r\n                        throw limitationSetResult.ResultCode;\r\n                    }\r\n\r\n                    limitationSet = limitationSetResult.Set;\r\n                    if (limitationSet == null)\r\n                    {\r\n                        throw new ArgumentException(\"The limitation set cannot be parsed.\");\r\n                    }\r\n\r\n                    // Now parse metadata json and update the limitation set\r\n                    limitationSetMetadata = JsonSerializer.Deserialize<LimitationSetMetadata>(commandStr.Substring(\r\n                        firstSeparatorIndex + CommandLineSectionSeparator.Length,\r\n                        secondSeparatorIndex - firstSeparatorIndex - CommandLineSectionSeparator.Length));\r\n\r\n                    if (limitationSetMetadata != null)\r\n                    {\r\n                        limitationSet.Path = limitationSetMetadata.Path;\r\n                    }\r\n                }\r\n\r\n                IConfigurationSetProcessorFactory factory = CreateFactory(processorEngine, limitationSet, limitationSetMetadata);\r\n                IObjectReference factoryInterface = MarshalInterface<IConfigurationSetProcessorFactory>.CreateMarshaler(factory);\r\n\r\n                return WindowsPackageManagerConfigurationCompleteOutOfProcessFactoryInitialization(0, factoryInterface.ThisPtr, staticsCallback, completionEventName, parentProcessId);\r\n            }\r\n            catch (Exception ex)\r\n            {\r\n                WindowsPackageManagerConfigurationCompleteOutOfProcessFactoryInitialization(ex.HResult, IntPtr.Zero, staticsCallback, null, 0);\r\n                return ex.HResult;\r\n            }\r\n            finally\r\n            {\r\n                environmentChangeListener.Stop();\r\n            }\r\n        }\r\n\r\n        private static void OnEnvironmentChanged()\r\n        {\r\n            PathEnvironmentVariableHandler.UpdatePath();\r\n        }\r\n\r\n        private class LimitationSetMetadata\r\n        {\r\n            [JsonPropertyName(\"path\")]\r\n            public string Path { get; set; } = string.Empty;\r\n\r\n            [JsonPropertyName(\"modulePath\")]\r\n            public string? ModulePath { get; set; } = null;\r\n\r\n            [JsonPropertyName(\"processorPath\")]\r\n            public string? ProcessorPath { get; set; } = null;\r\n        }\r\n\r\n        private static IConfigurationSetProcessorFactory CreateFactory(string processorEngine, ConfigurationSet? limitationSet, LimitationSetMetadata? limitationSetMetadata)\r\n        {\r\n            switch (processorEngine)\r\n            {\r\n                case \"pwsh\":\r\n                    return CreatePowerShellFactory(limitationSet, limitationSetMetadata);\r\n                case \"dscv3\":\r\n                    return CreateDSCv3Factory(limitationSet, limitationSetMetadata);\r\n            }\r\n\r\n            throw new NotImplementedException($\"Processor engine unknown: {processorEngine}\");\r\n        }\r\n\r\n        private static IConfigurationSetProcessorFactory CreatePowerShellFactory(ConfigurationSet? limitationSet, LimitationSetMetadata? limitationSetMetadata)\r\n        {\r\n            PowerShellConfigurationSetProcessorFactory factory = new PowerShellConfigurationSetProcessorFactory();\r\n\r\n            // Set default properties.\r\n            var externalModulesPath = GetExternalModulesPath();\r\n            if (string.IsNullOrWhiteSpace(externalModulesPath))\r\n            {\r\n                throw new DirectoryNotFoundException(\"Failed to get ExternalModules.\");\r\n            }\r\n\r\n            // Set as implicit module paths so it will be always included in AdditionalModulePaths\r\n            factory.ImplicitModulePaths = new List<string>() { externalModulesPath };\r\n            factory.ProcessorType = PowerShellConfigurationProcessorType.Hosted;\r\n\r\n            if (limitationSetMetadata != null)\r\n            {\r\n                if (limitationSetMetadata.ModulePath != null)\r\n                {\r\n                    PowerShellConfigurationProcessorLocation parsedLocation = PowerShellConfigurationProcessorLocation.Default;\r\n                    if (Enum.TryParse(limitationSetMetadata.ModulePath, out parsedLocation))\r\n                    {\r\n                        factory.Location = parsedLocation;\r\n                    }\r\n                    else\r\n                    {\r\n                        factory.Location = PowerShellConfigurationProcessorLocation.Custom;\r\n                        factory.CustomLocation = limitationSetMetadata.ModulePath;\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Apply limitation set and thereby disable changing properties.\r\n            if (limitationSet != null)\r\n            {\r\n                factory.LimitationSet = limitationSet;\r\n            }\r\n\r\n            return factory;\r\n        }\r\n\r\n        private static IConfigurationSetProcessorFactory CreateDSCv3Factory(ConfigurationSet? limitationSet, LimitationSetMetadata? limitationSetMetadata)\r\n        {\r\n            DSCv3ConfigurationSetProcessorFactory factory = new DSCv3ConfigurationSetProcessorFactory();\r\n\r\n            if (limitationSetMetadata != null)\r\n            {\r\n                if (limitationSetMetadata.ProcessorPath != null)\r\n                {\r\n                    factory.DscExecutablePath = limitationSetMetadata.ProcessorPath;\r\n                }\r\n                else\r\n                {\r\n                    // Require that the path to the DSC executable be presented to the user in limitation mode.\r\n                    // This helps prevent path attacks against an elevated process (as long as the user checks the value).\r\n                    throw new ArgumentNullException(\"The path to the DSC executable must be supplied in limitation mode.\");\r\n                }\r\n            }\r\n\r\n            // Apply limitation set and thereby disable changing properties.\r\n            if (limitationSet != null)\r\n            {\r\n                factory.LimitationSet = limitationSet;\r\n            }\r\n\r\n            return factory;\r\n        }\r\n\r\n        private static string GetExternalModulesPath()\r\n        {\r\n            var currentAssemblyDirectoryPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);\r\n            if (currentAssemblyDirectoryPath != null)\r\n            {\r\n                var packageRootPath = Directory.GetParent(currentAssemblyDirectoryPath)?.FullName;\r\n                if (packageRootPath != null)\r\n                {\r\n                    var externalModulesPath = Path.Combine(packageRootPath, ExternalModulesName);\r\n                    if (Directory.Exists(externalModulesPath))\r\n                    {\r\n                        return externalModulesPath;\r\n                    }\r\n                }\r\n            }\r\n\r\n            return string.Empty;\r\n        }\r\n\r\n        [DllImport(\"WindowsPackageManager.dll\")]\r\n        private static extern int WindowsPackageManagerConfigurationCompleteOutOfProcessFactoryInitialization(\r\n            int result,\r\n            IntPtr factory,\r\n            [MarshalAs(UnmanagedType.LPWStr)]string staticsCallback,\r\n            [MarshalAs(UnmanagedType.LPWStr)]string? completionEventName,\r\n            uint parentProcessId);\r\n\r\n        [DllImport(\"kernel32.dll\", CharSet = CharSet.Unicode)]\r\n        private static extern IntPtr GetCommandLineW();\r\n\r\n        [DllImport(\"kernel32.dll\")]\r\n        [return: MarshalAs(UnmanagedType.Bool)]\r\n        private static extern bool FreeConsole();\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Directory.Build.props",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <!-- Consume containing solution build props if present. -->\n  <Import Project=\"$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))\" Condition=\"'' != $([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))\" />\n\n  <PropertyGroup>\n    <WinGetMacros Condition=\"'$(UseProdCLSIDs)' == 'true'\">USE_PROD_CLSIDS;$(WinGetMacros)</WinGetMacros>\n    <WinGetMacros Condition=\"'$(WingetDisableTestHooks)' == 'true'\">AICLI_DISABLE_TEST_HOOKS;$(WinGetMacros)</WinGetMacros>\n    <WinGetMacros Condition=\"'$(WingetDisableExperimentalFeatures)' == 'true'\">WINGET_DISABLE_EXPERIMENTAL_FEATURES;$(WinGetMacros)</WinGetMacros>\n    <WinGetMacros Condition=\"'$(UseProdWingetServer)' == 'true'\">USE_PROD_WINGET_SERVER;$(WinGetMacros)</WinGetMacros>\n    <WinGetMacros Condition=\"'$(WingetEnableReleaseBuild)' == 'true'\">WINGET_ENABLE_RELEASE_BUILD;$(WinGetMacros)</WinGetMacros>\n  </PropertyGroup>\n\n  <!-- For C++ -->\n  <PropertyGroup Label=\"Configuration\">\n    <PlatformToolset Condition=\"'$(VisualStudioVersion)' == '16.0'\">v142</PlatformToolset>\n    <PlatformToolset Condition=\"'$(VisualStudioVersion)' == '17.0'\">v143</PlatformToolset>\n    <PlatformToolset Condition=\"'$(VisualStudioVersion)' == '18.0'\">v145</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(WinGetMacros)' != ''\">\n    <ClCompile>\n      <PreprocessorDefinitions>$(WinGetMacros)%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup>\n    <ClCompile>\n      <MultiProcessorCompilation>true</MultiProcessorCompilation>\n    </ClCompile>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='ReleaseStatic'\">\n    <Link>\n      <!-- Link statically against the runtime and STL, but link dynamically against the CRT by ignoring the static CRT\n           lib and instead linking against the Universal CRT DLL import library. This \"hybrid\" linking mechanism is\n           supported according to the CRT maintainer. Dynamic linking against the CRT makes the binaries a bit smaller\n           than they would otherwise be if the CRT, runtime, and STL were all statically linked in. \n           See https://aka.ms/hybridcrt for more details. -->\n      <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries);libucrt.lib</IgnoreSpecificDefaultLibraries>\n      <AdditionalOptions>%(AdditionalOptions) /defaultlib:ucrt.lib</AdditionalOptions>\n    </Link>\n  </ItemDefinitionGroup>\n\n  <!-- For C# -->\n  <PropertyGroup Condition=\"'$(WinGetMacros)' != ''\">\n    <DefineConstants>$(WinGetMacros)$(DefineConstants)</DefineConstants>\n  </PropertyGroup>\n\n  <!-- To prevent build agents from running out of disk space, clean as we go. -->\n  <Target Name=\"CleanIntermediateFiles\" AfterTargets=\"Build\" Condition=\"'$(WingetCleanIntermediateFiles)'=='true'\">\n    <RemoveDir Directories=\"$(IntDir)\" />\n  </Target>\n</Project>\n"
  },
  {
    "path": "src/Directory.Packages.props",
    "content": "<Project>\r\n  <PropertyGroup>\r\n    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>\r\n    <!--\n    !!! Remove or update this on the next Microsoft.Windows.CsWinRT package version update. !!!\n    -->\r\n    <WindowsSdkPackageVersion>10.0.26100.53</WindowsSdkPackageVersion>\r\n  </PropertyGroup>\r\n  <ItemGroup>\r\n    <PackageVersion Include=\"coverlet.collector\" Version=\"3.1.2\" />\r\n    <PackageVersion Include=\"Microsoft.ApplicationInsights\" Version=\"2.21.0\" />\r\n    <PackageVersion Include=\"Microsoft.AspNet.WebApi.Client\" Version=\"5.2.9\" />\r\n    <PackageVersion Include=\"Microsoft.Extensions.Hosting\" Version=\"9.0.6\" />\r\n    <PackageVersion Include=\"Microsoft.CSharp\" Version=\"4.7.0\" />\r\n    <PackageVersion Include=\"Microsoft.Msix.Utils\" Version=\"2.1.1\" />\r\n    <PackageVersion Include=\"Microsoft.NET.Test.Sdk\" Version=\"17.3.2\" />\r\n    <PackageVersion Include=\"Microsoft.PowerShell.SDK\" Version=\"7.4.12\" />\r\n    <PackageVersion Include=\"Microsoft.Win32.Registry\" Version=\"5.0.0\" />\r\n    <PackageVersion Include=\"Microsoft.Windows.CsWinRT\" Version=\"2.1.6\" />\r\n    <PackageVersion Include=\"Microsoft.Windows.SDK.Contracts\" Version=\"10.0.26100.1742\" />\r\n    <PackageVersion Include=\"ModelContextProtocol\" Version=\"0.3.0-preview.3\" />\r\n    <PackageVersion Include=\"Moq\" Version=\"4.18.2\" />\r\n    <PackageVersion Include=\"Newtonsoft.Json\" Version=\"13.0.3\" />\r\n    <PackageVersion Include=\"nunit\" Version=\"3.12.0\" />\r\n    <PackageVersion Include=\"NUnit3TestAdapter\" Version=\"3.15.1\" />\r\n    <PackageVersion Include=\"Octokit\" Version=\"4.0.3\" />\r\n    <PackageVersion Include=\"PowerShellStandard.Library\" Version=\"5.1.1\" />\r\n    <PackageVersion Include=\"Semver\" Version=\"2.3.0\" />\r\n    <PackageVersion Include=\"StyleCop.Analyzers\" Version=\"1.1.118\" />\r\n    <PackageVersion Include=\"System.Data.SqlClient\" Version=\"4.9.0\" />\r\n    <PackageVersion Include=\"System.Net.Http\" Version=\"4.3.4\" />\r\n    <PackageVersion Include=\"System.Private.Uri\" Version=\"4.3.2\" />\r\n    <PackageVersion Include=\"System.Security.Principal.Windows\" Version=\"5.0.0\" />\r\n    <PackageVersion Include=\"System.Text.RegularExpressions\" Version=\"4.3.1\" />\r\n    <PackageVersion Include=\"xunit\" Version=\"2.4.2\" />\r\n    <PackageVersion Include=\"xunit.runner.visualstudio\" Version=\"2.4.5\" />\r\n    <PackageVersion Include=\"YamlDotNet\" Version=\"16.3.0\" />\r\n  </ItemGroup>\r\n</Project>\r\n"
  },
  {
    "path": "src/Directory.Solution.props",
    "content": "<!-- This file is automatically included in the (autogenerated) project file for the solution. -->\n<Project>\n    <Import Project=\"$(MSBuildProjectDirectory)\\vcpkg.props\" />\n</Project>"
  },
  {
    "path": "src/Get-VcxprojNugetPackageVersions.ps1",
    "content": "#Requires -Version 5.1\r\n\r\n<#\r\n.SYNOPSIS\r\n    Recursively searches for .vcxproj files and extracts NuGet package versions from associated packages.config files.\r\n\r\n.DESCRIPTION\r\n    This script searches directories below the script location for Visual Studio C++ project files (.vcxproj)\r\n    and their corresponding packages.config files. It extracts all NuGet package references with their versions\r\n    and generates a comprehensive report.\r\n\r\n.PARAMETER OutputFormat\r\n    Specifies the output format: Table, CSV, JSON, or Object. Default is Table. Object format returns PackageInfo objects without printing anything.\r\n\r\n.PARAMETER ExportPath\r\n    Optional path to export the results to a file. Not applicable for Object format.\r\n\r\n.PARAMETER PackageFilter\r\n    Optional filter to search for specific package names. Supports wildcards. If specified, only packages matching this filter will be included in the results.\r\n\r\n.EXAMPLE\r\n    .\\Get-VcxprojNugetPackageVersions.ps1\r\n    \r\n.EXAMPLE\r\n    .\\Get-VcxprojNugetPackageVersions.ps1 -OutputFormat CSV -ExportPath \"packages-report.csv\"\r\n\r\n.EXAMPLE\r\n    .\\Get-VcxprojNugetPackageVersions.ps1 -PackageFilter \"Microsoft*\"\r\n\r\n.EXAMPLE\r\n    .\\Get-VcxprojNugetPackageVersions.ps1 -PackageFilter \"Newtonsoft.Json\" -OutputFormat JSON\r\n\r\n.EXAMPLE\r\n    $packages = .\\Get-VcxprojNugetPackageVersions.ps1 -OutputFormat Object\r\n#>\r\n\r\n[CmdletBinding()]\r\nparam(\r\n    [ValidateSet(\"Table\", \"CSV\", \"JSON\", \"Object\")]\r\n    [string]$OutputFormat = \"Table\",\r\n    \r\n    [string]$ExportPath,\r\n    \r\n    [string]$PackageFilter\r\n)\r\n\r\n# Custom class to hold package information\r\nclass PackageInfo {\r\n    [string]$ProjectFile\r\n    [string]$ProjectName\r\n    [string]$PackageId\r\n    [string]$Version\r\n    [string]$TargetFramework\r\n    [string]$PackagesConfigPath\r\n    [bool]$PackagesConfigExists\r\n}\r\n\r\nfunction Get-VcxprojFiles {\r\n    param(\r\n        [string]$SearchPath,\r\n        [bool]$SuppressOutput = $false\r\n    )\r\n    \r\n    Write-Verbose \"Searching for .vcxproj files in: $SearchPath\"\r\n    \r\n    try {\r\n        $vcxprojFiles = Get-ChildItem -Path $SearchPath -Filter \"*.vcxproj\" -Recurse -ErrorAction SilentlyContinue\r\n        if (-not $SuppressOutput) {\r\n            Write-Host \"Found $($vcxprojFiles.Count) .vcxproj files\" -ForegroundColor Green\r\n        }\r\n        return $vcxprojFiles\r\n    }\r\n    catch {\r\n        Write-Warning \"Error searching for .vcxproj files: $($_.Exception.Message)\"\r\n        return @()\r\n    }\r\n}\r\n\r\nfunction Get-PackagesFromConfig {\r\n    param(\r\n        [string]$PackagesConfigPath,\r\n        [string]$ProjectFile,\r\n        [string]$ProjectName,\r\n        [string]$PackageFilter\r\n    )\r\n    \r\n    $packages = @()\r\n    \r\n    if (-not (Test-Path $PackagesConfigPath)) {\r\n        Write-Verbose \"No packages.config found for project: $ProjectName\"\r\n        \r\n        # If a package filter is specified and there's no packages.config, don't include this project\r\n        if ($PackageFilter) {\r\n            Write-Verbose \"Package filter specified but no packages.config exists for project: $ProjectName. Excluding from results.\"\r\n            return @()\r\n        }\r\n        \r\n        # Return empty package info to indicate no packages.config\r\n        $packageInfo = [PackageInfo]::new()\r\n        $packageInfo.ProjectFile = $ProjectFile\r\n        $packageInfo.ProjectName = $ProjectName\r\n        $packageInfo.PackageId = \"N/A\"\r\n        $packageInfo.Version = \"N/A\"\r\n        $packageInfo.TargetFramework = \"N/A\"\r\n        $packageInfo.PackagesConfigPath = $PackagesConfigPath\r\n        $packageInfo.PackagesConfigExists = $false\r\n        return @($packageInfo)\r\n    }\r\n    \r\n    try {\r\n        Write-Verbose \"Processing packages.config: $PackagesConfigPath\"\r\n        [xml]$packagesXml = Get-Content $PackagesConfigPath -ErrorAction Stop\r\n        \r\n        $packageNodes = $packagesXml.packages.package\r\n        \r\n        if ($null -eq $packageNodes) {\r\n            Write-Verbose \"No package nodes found in packages.config for project: $ProjectName\"\r\n            return @()\r\n        }\r\n        \r\n        # Handle both single package and multiple packages scenarios\r\n        if ($packageNodes -is [System.Xml.XmlElement]) {\r\n            # Single package\r\n            $packageNodes = @($packageNodes)\r\n        }\r\n        \r\n        foreach ($package in $packageNodes) {\r\n            # Apply package filter if specified\r\n            if ($PackageFilter -and $package.id -notlike $PackageFilter) {\r\n                Write-Verbose \"Package '$($package.id)' does not match filter '$PackageFilter', skipping\"\r\n                continue\r\n            }\r\n            \r\n            $packageInfo = [PackageInfo]::new()\r\n            $packageInfo.ProjectFile = $ProjectFile\r\n            $packageInfo.ProjectName = $ProjectName\r\n            $packageInfo.PackageId = $package.id\r\n            $packageInfo.Version = $package.version\r\n            $packageInfo.TargetFramework = $package.targetFramework\r\n            $packageInfo.PackagesConfigPath = $PackagesConfigPath\r\n            $packageInfo.PackagesConfigExists = $true\r\n            \r\n            $packages += $packageInfo\r\n        }\r\n        \r\n        Write-Verbose \"Found $($packages.Count) packages in $ProjectName\"\r\n    }\r\n    catch {\r\n        Write-Warning \"Error parsing packages.config for project '$ProjectName': $($_.Exception.Message)\"\r\n    }\r\n    \r\n    return $packages\r\n}\r\n\r\nfunction Get-ProjectName {\r\n    param([string]$VcxprojPath)\r\n    \r\n    try {\r\n        [xml]$projectXml = Get-Content $VcxprojPath -ErrorAction Stop\r\n        \r\n        # Try to get project name from PropertyGroup\r\n        $projectNameNode = $projectXml.Project.PropertyGroup.ProjectName | Select-Object -First 1\r\n        if ($projectNameNode) {\r\n            return $projectNameNode\r\n        }\r\n        \r\n        # Fallback to filename without extension\r\n        return [System.IO.Path]::GetFileNameWithoutExtension($VcxprojPath)\r\n    }\r\n    catch {\r\n        Write-Verbose \"Could not parse project file for name, using filename: $($_.Exception.Message)\"\r\n        return [System.IO.Path]::GetFileNameWithoutExtension($VcxprojPath)\r\n    }\r\n}\r\n\r\nfunction Export-Results {\r\n    param(\r\n        [array]$Results,\r\n        [string]$Format,\r\n        [string]$Path\r\n    )\r\n    \r\n    if (-not $Path) {\r\n        return\r\n    }\r\n    \r\n    try {\r\n        switch ($Format) {\r\n            \"CSV\" {\r\n                $Results | Export-Csv -Path $Path -NoTypeInformation\r\n                Write-Host \"Results exported to CSV: $Path\" -ForegroundColor Green\r\n            }\r\n            \"JSON\" {\r\n                $Results | ConvertTo-Json -Depth 3 | Out-File -FilePath $Path -Encoding utf8\r\n                Write-Host \"Results exported to JSON: $Path\" -ForegroundColor Green\r\n            }\r\n            default {\r\n                $Results | Format-Table -AutoSize | Out-File -FilePath $Path -Encoding utf8\r\n                Write-Host \"Results exported to text file: $Path\" -ForegroundColor Green\r\n            }\r\n        }\r\n    }\r\n    catch {\r\n        Write-Warning \"Failed to export results to '$Path': $($_.Exception.Message)\"\r\n    }\r\n}\r\n\r\nfunction Show-Summary {\r\n    param([array]$AllPackages)\r\n    \r\n    $projectsWithPackages = $AllPackages | Where-Object { $_.PackagesConfigExists } | Group-Object ProjectFile\r\n    $projectsWithoutPackages = $AllPackages | Where-Object { -not $_.PackagesConfigExists } | Group-Object ProjectFile\r\n    \r\n    Write-Host \"`n=== SUMMARY ===\" -ForegroundColor Cyan\r\n    Write-Host \"Total .vcxproj files found: $($projectsWithPackages.Count + $projectsWithoutPackages.Count)\"\r\n    Write-Host \"Projects with packages.config: $($projectsWithPackages.Count)\" -ForegroundColor Green\r\n    Write-Host \"Projects without packages.config: $($projectsWithoutPackages.Count)\" -ForegroundColor Yellow\r\n    Write-Host \"Total package references: $(($AllPackages | Where-Object { $_.PackagesConfigExists }).Count)\" -ForegroundColor Green\r\n}\r\n\r\n# Main execution\r\ntry {\r\n    $scriptPath = Split-Path -Parent $MyInvocation.MyCommand.Path\r\n    \r\n    # Suppress output messages for Object format\r\n    if ($OutputFormat -ne \"Object\") {\r\n        Write-Host \"Starting search from: $scriptPath\" -ForegroundColor Cyan\r\n        Write-Host \"Output format: $OutputFormat\" -ForegroundColor Cyan\r\n        \r\n        if ($PackageFilter) {\r\n            Write-Host \"Package filter: $PackageFilter\" -ForegroundColor Cyan\r\n        }\r\n        \r\n        if ($ExportPath) {\r\n            Write-Host \"Export path: $ExportPath\" -ForegroundColor Cyan\r\n        }\r\n    }\r\n    \r\n    # Find all .vcxproj files\r\n    $vcxprojFiles = Get-VcxprojFiles -SearchPath $scriptPath -SuppressOutput ($OutputFormat -eq \"Object\")\r\n    \r\n    if ($vcxprojFiles.Count -eq 0) {\r\n        if ($OutputFormat -ne \"Object\") {\r\n            Write-Warning \"No .vcxproj files found in the search directory.\"\r\n        }\r\n        return @()  # Return empty array for Object format\r\n    }\r\n    \r\n    # Process each .vcxproj file\r\n    $allPackages = @()\r\n    $processedCount = 0\r\n    \r\n    foreach ($vcxproj in $vcxprojFiles) {\r\n        $processedCount++\r\n        Write-Progress -Activity \"Processing .vcxproj files\" -Status \"$processedCount of $($vcxprojFiles.Count)\" -PercentComplete (($processedCount / $vcxprojFiles.Count) * 100)\r\n        \r\n        $projectName = Get-ProjectName -VcxprojPath $vcxproj.FullName\r\n        $packagesConfigPath = Join-Path $vcxproj.DirectoryName \"packages.config\"\r\n        \r\n        $packages = Get-PackagesFromConfig -PackagesConfigPath $packagesConfigPath -ProjectFile $vcxproj.FullName -ProjectName $projectName -PackageFilter $PackageFilter\r\n        $allPackages += $packages\r\n    }\r\n    \r\n    Write-Progress -Activity \"Processing .vcxproj files\" -Completed\r\n    \r\n    # Display results\r\n    if ($allPackages.Count -gt 0) {\r\n        switch ($OutputFormat) {\r\n            \"CSV\" {\r\n                if ($ExportPath) {\r\n                    Export-Results -Results $allPackages -Format \"CSV\" -Path $ExportPath\r\n                } else {\r\n                    $allPackages | ConvertTo-Csv -NoTypeInformation | Write-Output\r\n                }\r\n            }\r\n            \"JSON\" {\r\n                if ($ExportPath) {\r\n                    Export-Results -Results $allPackages -Format \"JSON\" -Path $ExportPath\r\n                } else {\r\n                    $allPackages | ConvertTo-Json -Depth 3 | Write-Output\r\n                }\r\n            }\r\n            \"Object\" {\r\n                # Return only packages where PackagesConfigExists is true\r\n                $packagesWithConfig = $allPackages | Where-Object { $_.PackagesConfigExists }\r\n                return $packagesWithConfig\r\n            }\r\n            default {\r\n                # Table format\r\n                Write-Host \"`n=== PACKAGE DETAILS ===\" -ForegroundColor Cyan\r\n\r\n                # Show the set of packages and versions found across all projects\r\n                $uniquePackages = $allPackages | Where-Object { $_.PackagesConfigExists } | Group-Object PackageId, Version\r\n                if ($uniquePackages.Count -gt 0) {\r\n                    $uniquePackages | Format-Table -Property Name, Count -AutoSize\r\n                }\r\n\r\n                # Output the URL of each package on nuget.org\r\n                Write-Host \"`n=== PACKAGE URLS ===\" -ForegroundColor Cyan\r\n\r\n                $uniquePackages = $allPackages | Where-Object { $_.PackagesConfigExists } | Group-Object PackageId\r\n                foreach ($packageGroup in $uniquePackages) {\r\n                    $packageId = $packageGroup.Name\r\n                    $url = \"https://www.nuget.org/packages/$packageId#versions-body-tab\"\r\n                    Write-Host \"  $packageId : $url\" -ForegroundColor Yellow\r\n                }\r\n\r\n                Write-Host \"`n=== PROJECT DETAILS ===\" -ForegroundColor Cyan\r\n                \r\n                # Show projects with packages\r\n                $packagesWithConfig = $allPackages | Where-Object { $_.PackagesConfigExists }\r\n                if ($packagesWithConfig.Count -gt 0) {\r\n                    $packagesWithConfig | Format-Table -Property ProjectName, PackageId, Version, TargetFramework -AutoSize\r\n                }\r\n                \r\n                if ($ExportPath) {\r\n                    Export-Results -Results $allPackages -Format $OutputFormat -Path $ExportPath\r\n                }\r\n            }\r\n        }\r\n        \r\n        # Show summary (but not for Object format)\r\n        if ($OutputFormat -ne \"Object\") {\r\n            Show-Summary -AllPackages $allPackages\r\n        }\r\n    } else {\r\n        if ($OutputFormat -ne \"Object\") {\r\n            Write-Host \"No packages found in any .vcxproj files.\" -ForegroundColor Yellow\r\n        }\r\n    }\r\n}\r\ncatch {\r\n    Write-Error \"An error occurred during execution: $($_.Exception.Message)\"\r\n    Write-Error $_.ScriptStackTrace\r\n}\r\n\r\nif ($OutputFormat -ne \"Object\") {\r\n    Write-Host \"`nScript completed.\" -ForegroundColor Green\r\n}"
  },
  {
    "path": "src/IndexCreationTool/IndexCreationTool.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\IndexCreationTool\\</OutDir>\r\n    <Platforms>x64;x86</Platforms>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\WinGetSourceCreator\\WinGetSourceCreator.csproj\" />\r\n    <ProjectReference Include=\"..\\WinGetUtilInterop\\WinGetUtilInterop.csproj\" />\r\n    <ProjectReference Include=\"..\\WinGetUtil\\WinGetUtil.vcxproj\" >\r\n      <OutputItemType>Content</OutputItemType>\r\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\r\n      <ReferenceOutputAssembly>True</ReferenceOutputAssembly>\r\n    </ProjectReference>\r\n  </ItemGroup>\r\n\r\n  <Target Name=\"PostBuild\" AfterTargets=\"PostBuildEvent\">\r\n    <Copy SourceFiles=\"$(TargetDir)..\\WinGetUtil\\WinGetUtil.dll\" DestinationFiles=\"$(TargetDir)WinGetUtil.dll\" />\r\n  </Target>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "src/IndexCreationTool/Program.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n\r\nnamespace IndexCreationTool\r\n{\r\n    using Microsoft.WinGetSourceCreator;\r\n    using System;\r\n    using System.IO;\r\n    using System.Text.Json;\r\n    using System.Text.Json.Serialization;\r\n    using WinGetSourceCreator.Model;\r\n\r\n    class Program\r\n    {\r\n        private static void PrintUsage()\r\n        {\r\n            Console.WriteLine(\"Usage: IndexCreationTool.exe -f <local source input json file>\");\r\n        }\r\n\r\n        static int Main(string[] args)\r\n        {\r\n            try\r\n            {\r\n                string inputFile = string.Empty;\r\n                for (int i = 0; i < args.Length; i++)\r\n                {\r\n                    if (args[i] == \"-f\" && ++i < args.Length)\r\n                    {\r\n                        inputFile = args[i];\r\n                    }\r\n                }\r\n\r\n                if (string.IsNullOrEmpty(inputFile) || !File.Exists(inputFile))\r\n                {\r\n                    PrintUsage();\r\n                    throw new ArgumentException(\"Missing input file\");\r\n                }\r\n\r\n                WinGetLocalSource.CreateFromLocalSourceFile(inputFile);\r\n            }\r\n            catch (Exception e)\r\n            {\r\n                PrintUsage();\r\n                Console.WriteLine(e.Message);\r\n                return -1;\r\n            }\r\n\r\n            return 0;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/LocalhostWebServer/LocalhostWebServer.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\r\n\r\n  <PropertyGroup>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\LocalhostWebServer\\</OutDir>\r\n    <Platforms>x64;x86</Platforms>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\WinGetSourceCreator\\WinGetSourceCreator.csproj\" />\r\n    <ProjectReference Include=\"..\\WinGetUtilInterop\\WinGetUtilInterop.csproj\" />\r\n    <ProjectReference Include=\"..\\WinGetUtil\\WinGetUtil.vcxproj\" >\r\n      <OutputItemType>Content</OutputItemType>\r\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\r\n      <ReferenceOutputAssembly>True</ReferenceOutputAssembly>\r\n    </ProjectReference>\r\n  </ItemGroup>\r\n\r\n  <Target Name=\"PostBuild\" AfterTargets=\"PostBuildEvent\">\r\n    <Copy SourceFiles=\"$(TargetDir)..\\WinGetUtil\\WinGetUtil.dll\" DestinationFiles=\"$(TargetDir)WinGetUtil.dll\" />\r\n  </Target>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "src/LocalhostWebServer/Program.cs",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n\r\nnamespace LocalhostWebServer\r\n{\r\n    using Microsoft.AspNetCore.Builder;\r\n    using Microsoft.AspNetCore.Hosting;\r\n    using Microsoft.Extensions.Hosting;\r\n    using System;\r\n    using System.IO;\r\n    using Microsoft.Extensions.Configuration;\r\n    using System.Security.Cryptography.X509Certificates;\r\n    using System.Text.Json.Serialization;\r\n    using System.Text.Json;\r\n    using WinGetSourceCreator.Model;\r\n    using Microsoft.WinGetSourceCreator;\r\n    using System.Runtime.InteropServices;\r\n\r\n    public class Program\r\n    {\r\n        const string CertificateProviderString = \"Microsoft.PowerShell.Security\\\\Certificate::\";\r\n        const string StoreLocationCurrentUser = \"CurrentUser\";\r\n        const string StoreLocationLocalMachine = \"LocalMachine\";\r\n\r\n        static void Main(string[] args)\r\n        {\r\n            IConfiguration config = new ConfigurationBuilder()\r\n                .AddCommandLine(args)\r\n                .Build();\r\n\r\n            Startup.StaticFileRoot = config.GetValue<string>(\"StaticFileRoot\");\r\n            Startup.CertPath = config.GetValue<string>(\"CertPath\");\r\n            Startup.CertPassword = config.GetValue<string>(\"CertPassword\");\r\n            Startup.Port = config.GetValue<Int32>(\"Port\", 5001);\r\n            Startup.OutCertFile = config.GetValue<string>(\"OutCertFile\");\r\n            Startup.LocalSourceJson = config.GetValue<string>(\"LocalSourceJson\");\r\n            Startup.TestDataPath = config.GetValue<string>(\"TestDataPath\");\r\n            Startup.ExitBeforeRun = config.GetValue<bool>(\"ExitBeforeRun\");\r\n\r\n            if (string.IsNullOrEmpty(Startup.StaticFileRoot) || \r\n                string.IsNullOrEmpty(Startup.CertPath))\r\n            {\r\n                Console.WriteLine(\"Usage: LocalhostWebServer.exe StaticFileRoot=<Path to Serve Static Root Directory> \" +\r\n                    \"CertPath=<Path to HTTPS Developer Certificate> CertPassword=<Certificate Password> <Port=Port Number> <PutCertInRoot=Boolean>\");\r\n                return;\r\n            }\r\n\r\n            Directory.CreateDirectory(Startup.StaticFileRoot);\r\n\r\n            if (Startup.CertPath.StartsWith(CertificateProviderString))\r\n            {\r\n                string certPath = Startup.CertPath.Substring(CertificateProviderString.Length);\r\n                string[] pathParts = certPath.Split('\\\\');\r\n\r\n                if (pathParts.Length != 3)\r\n                {\r\n                    throw new InvalidDataException($\"Don't know how to handle: {Startup.CertPath}\");\r\n                }\r\n\r\n                StoreLocation storeLocation = StoreLocation.CurrentUser;\r\n                if (pathParts[0] == StoreLocationCurrentUser)\r\n                {\r\n                    // The default\r\n                }\r\n                else if (pathParts[0] == StoreLocationLocalMachine)\r\n                {\r\n                    storeLocation = StoreLocation.LocalMachine;\r\n                }\r\n                else\r\n                {\r\n                    throw new InvalidDataException($\"Unknown store scope: {Startup.CertPath}\");\r\n                }\r\n\r\n                X509Store x509Store = new X509Store(pathParts[1], storeLocation);\r\n                x509Store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);\r\n                X509Certificate2Collection collection = x509Store.Certificates;\r\n\r\n                if (collection.Count == 0)\r\n                {\r\n                    throw new InvalidDataException($\"Found {collection.Count} certificates in store '{pathParts[0]}' [{storeLocation}] \\\\ '{pathParts[1]}': {Startup.CertPath}\");\r\n                }\r\n\r\n                X509Certificate2Collection results = collection.Find(X509FindType.FindByThumbprint, pathParts[2], true);\r\n\r\n                if (results.Count != 1)\r\n                {\r\n                    throw new InvalidDataException($\"Found {results.Count} matches for '{pathParts[2]}': {Startup.CertPath}\");\r\n                }\r\n\r\n                ServerCertificate = results[0];\r\n            }\r\n            else\r\n            {\r\n                ServerCertificate = new X509Certificate2(Startup.CertPath, Startup.CertPassword);\r\n            }\r\n\r\n            if (!string.IsNullOrEmpty(Startup.OutCertFile))\r\n            {\r\n                string parent = Path.GetDirectoryName(Startup.OutCertFile);\r\n                if (!string.IsNullOrEmpty(parent))\r\n                {\r\n                    Directory.CreateDirectory(parent);\r\n                }\r\n\r\n                File.WriteAllBytes(Startup.OutCertFile, ServerCertificate.Export(X509ContentType.Cert));\r\n            }\r\n\r\n            if (!string.IsNullOrEmpty(Startup.LocalSourceJson))\r\n            {\r\n                if (!File.Exists(Startup.LocalSourceJson))\r\n                {\r\n                    throw new FileNotFoundException(Startup.LocalSourceJson);\r\n                }\r\n\r\n                WinGetLocalSource.CreateFromLocalSourceFile(Startup.LocalSourceJson);\r\n            }\r\n\r\n            if (!string.IsNullOrEmpty(Startup.TestDataPath))\r\n            {\r\n                if (!Directory.Exists(Startup.TestDataPath))\r\n                {\r\n                    throw new DirectoryNotFoundException(Startup.TestDataPath);\r\n                }\r\n\r\n                var testDataDirectory = Path.Combine(Startup.StaticFileRoot, \"TestData\");\r\n                Directory.CreateDirectory(testDataDirectory);\r\n\r\n                CopyDirectoryRecursive(Startup.TestDataPath, testDataDirectory);\r\n            }\r\n\r\n            if (Startup.ExitBeforeRun)\r\n            {\r\n                return;\r\n            }\r\n\r\n            CreateHostBuilder(args).Build().Run();\r\n        }\r\n\r\n        public static IHostBuilder CreateHostBuilder(string[] args) =>\r\n            Host.CreateDefaultBuilder(args)\r\n                .ConfigureWebHostDefaults(webBuilder =>\r\n                {\r\n                    webBuilder.UseKestrel(opt =>\r\n                    {\r\n                        opt.ListenAnyIP(Startup.Port, listOpt =>\r\n                        {\r\n                            listOpt.UseHttps(ServerCertificate);\r\n                        });\r\n                    });\r\n                    webBuilder.UseContentRoot(Startup.StaticFileRoot);\r\n                    webBuilder.UseStartup<Startup>();\r\n                });\r\n\r\n        public static X509Certificate2 ServerCertificate { get; private set; }\r\n\r\n        private static void CopyDirectoryRecursive(string sourceDir, string destDir)\r\n        {\r\n            if (!Directory.Exists(destDir))\r\n            {\r\n                Directory.CreateDirectory(destDir);\r\n            }\r\n\r\n            string[] files = Directory.GetFiles(sourceDir);\r\n            foreach (string file in files)\r\n            {\r\n                string dest = Path.Combine(destDir, Path.GetFileName(file));\r\n                File.Copy(file, dest, overwrite: true);\r\n            }\r\n\r\n            string[] directories = Directory.GetDirectories(sourceDir);\r\n            foreach (string dir in directories)\r\n            {\r\n                string dest = Path.Combine(destDir, Path.GetFileName(dir));\r\n                CopyDirectoryRecursive(dir, dest);\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/LocalhostWebServer/Run-LocalhostWebServer.ps1",
    "content": "<#\r\n.SYNOPSIS\r\n    Runs the LocalhostWebServer.\r\n.PARAMETER BuildRoot\r\n    The root of the build output directory for LocalhostWebServer\r\n.PARAMETER StaticFileRoot\r\n    The root of the static files to be served through Localhost\r\n.PARAMETER CertPath\r\n    Path to HTTPS Development Certificate File (pfx)\r\n.PARAMETER CertPassword\r\n    Secure Password for HTTPS Certificate\r\n.PARAMETER OutCertFile\r\n    Export cert location.\r\n.PARAMETER LocalSourceJson\r\n    Local source json definition\r\n.PARAMETER SourceCert\r\n    The certificate of the source package.\r\n#>\r\n\r\nparam(\r\n    [Parameter(Mandatory=$true)]\r\n    [string]$BuildRoot,\r\n\r\n    [Parameter(Mandatory=$true)]\r\n    [string]$StaticFileRoot,\r\n\r\n    [Parameter(Mandatory=$true)]\r\n    [string]$CertPath,\r\n\r\n    [Parameter()]\r\n    [string]$CertPassword,\r\n\r\n    [Parameter()]\r\n    [string]$OutCertFile,\r\n\r\n    [Parameter()]\r\n    [string]$LocalSourceJson,\r\n\r\n    [Parameter()]\r\n    [string]$SourceCert,\r\n\r\n    [Parameter()]\r\n    [string]$TestDataPath,\r\n\r\n    [Parameter()]\r\n    [switch]$ExitBeforeRun\r\n)\r\n\r\nif (-not [System.String]::IsNullOrEmpty($sourceCert))\r\n{\r\n    # Requires admin\r\n    & certutil.exe -addstore -f \"TRUSTEDPEOPLE\" $sourceCert\r\n}\r\n\r\nPush-Location $BuildRoot\r\n\r\n$startProcessArguments = @{\r\n    FilePath = Join-Path $BuildRoot \"LocalhostWebServer.exe\"\r\n    ArgumentList = \"StaticFileRoot=$StaticFileRoot CertPath=$CertPath CertPassword=$CertPassword OutCertFile=$OutCertFile LocalSourceJson=$LocalSourceJson TestDataPath=$TestDataPath ExitBeforeRun=$ExitBeforeRun\"\r\n    PassThru = $true\r\n}\r\n\r\nif (-not [System.string]::IsNullOrEmpty($env:artifactsDir))\r\n{\r\n    $startProcessArguments.RedirectStandardOutput = Join-Path $env:artifactsDir \"LocalhostWebServer.out\"\r\n    $startProcessArguments.RedirectStandardError = Join-Path $env:artifactsDir \"LocalhostWebServer.err\"\r\n}\r\n\r\n$Local:process = Start-Process @startProcessArguments\r\n\r\nif ($ExitBeforeRun)\r\n{\r\n    Wait-Process -InputObject $Local:process\r\n}\r\n\r\nPop-Location\r\n"
  },
  {
    "path": "src/LocalhostWebServer/Startup.cs",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n\r\nnamespace LocalhostWebServer\r\n{\r\n    using Microsoft.AspNetCore.Builder;\r\n    using Microsoft.AspNetCore.Hosting;\r\n    using Microsoft.AspNetCore.StaticFiles;\r\n    using Microsoft.Extensions.Configuration;\r\n    using Microsoft.Extensions.DependencyInjection;\r\n    using Microsoft.Extensions.FileProviders;\r\n    using Microsoft.Extensions.Hosting;\r\n\r\n    public class Startup\r\n    {\r\n        public const string StaticFileRequestPath = \"/TestKit\";\r\n\r\n        public static string StaticFileRoot { get; set; }\r\n\r\n        public static string CertPath { get; set; }\r\n\r\n        public static string CertPassword { get; set; }\r\n\r\n        public static string OutCertFile { get; set; }\r\n\r\n        public static int Port { get; set; }\r\n\r\n        public static string LocalSourceJson { get; set; }\r\n\r\n        public static string TestDataPath { get; set; }\r\n\r\n        public static bool ExitBeforeRun { get; set; }\r\n\r\n        public Startup(IConfiguration configuration)\r\n        {\r\n            Configuration = configuration;\r\n        }\r\n\r\n        public void ConfigureServices(IServiceCollection services)\r\n        {\r\n            services.AddControllersWithViews();\r\n        }\r\n\r\n        public IConfiguration Configuration { get; }\r\n\r\n        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)\r\n        {\r\n            if (env.IsDevelopment())\r\n            {\r\n                app.UseDeveloperExceptionPage();\r\n            }\r\n\r\n            app.UseHttpsRedirection();\r\n\r\n            //Add .yaml and .msix mappings\r\n            var provider = new FileExtensionContentTypeProvider();\r\n            provider.Mappings[\".yml\"] = \"application/x-yaml\";\r\n            provider.Mappings[\".yaml\"] = \"application/x-yaml\";\r\n            provider.Mappings[\".msix\"] = \"application/msix\";\r\n            provider.Mappings[\".exe\"] = \"application/x-msdownload\";\r\n            provider.Mappings[\".msi\"] = \"application/msi\";\r\n            provider.Mappings[\".appx\"] = \"application/vns.ms-appx\";\r\n            provider.Mappings[\".appxbundle\"] = \"application/vns.ms-appx\";\r\n            provider.Mappings[\".mszyml\"] = \"application/x-ms-zip-yaml\";\r\n            provider.Mappings[\".ttf\"] = \"application/x-font-ttf\";\r\n\r\n            //Enable static file serving\r\n            app.UseStaticFiles(new StaticFileOptions\r\n            {\r\n                FileProvider = new PhysicalFileProvider(StaticFileRoot),\r\n                RequestPath = StaticFileRequestPath,\r\n                ContentTypeProvider = provider,\r\n                ServeUnknownFileTypes = true,\r\n                DefaultContentType = \"application/octet-stream\"\r\n            });\r\n\r\n            app.UseDirectoryBrowser(new DirectoryBrowserOptions\r\n            {\r\n                FileProvider = new PhysicalFileProvider(StaticFileRoot),\r\n                RequestPath = StaticFileRequestPath\r\n            });\r\n\r\n            app.UseRouting();\r\n\r\n            app.UseAuthorization();\r\n\r\n            app.UseEndpoints(endpoints =>\r\n            {\r\n                endpoints.MapDefaultControllerRoute();\r\n            });\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/ManifestSchema/ManifestSchema.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n\r\n// 0 is reserved to represent when there is no resource.\r\n#define MANIFESTSCHEMA_NO_RESOURCE                      0\r\n\r\n#define MANIFESTSCHEMA_RESOURCE_TYPE                  200\r\n\r\n#define IDX_MANIFEST_SCHEMA_PREVIEW                   201\r\n\r\n#define IDX_MANIFEST_SCHEMA_V1_SINGLETON              202\r\n#define IDX_MANIFEST_SCHEMA_V1_VERSION                203\r\n#define IDX_MANIFEST_SCHEMA_V1_INSTALLER              204\r\n#define IDX_MANIFEST_SCHEMA_V1_DEFAULTLOCALE          205\r\n#define IDX_MANIFEST_SCHEMA_V1_LOCALE                 206\r\n\r\n#define IDX_MANIFEST_SCHEMA_V1_1_SINGLETON            207\r\n#define IDX_MANIFEST_SCHEMA_V1_1_VERSION              208\r\n#define IDX_MANIFEST_SCHEMA_V1_1_INSTALLER            209\r\n#define IDX_MANIFEST_SCHEMA_V1_1_DEFAULTLOCALE        210\r\n#define IDX_MANIFEST_SCHEMA_V1_1_LOCALE               211\r\n\r\n#define IDX_MANIFEST_SCHEMA_V1_2_SINGLETON            212\r\n#define IDX_MANIFEST_SCHEMA_V1_2_VERSION              213\r\n#define IDX_MANIFEST_SCHEMA_V1_2_INSTALLER            214\r\n#define IDX_MANIFEST_SCHEMA_V1_2_DEFAULTLOCALE        215\r\n#define IDX_MANIFEST_SCHEMA_V1_2_LOCALE               216\r\n\r\n#define IDX_MANIFEST_SCHEMA_V1_4_SINGLETON            217\r\n#define IDX_MANIFEST_SCHEMA_V1_4_VERSION              218\r\n#define IDX_MANIFEST_SCHEMA_V1_4_INSTALLER            219\r\n#define IDX_MANIFEST_SCHEMA_V1_4_DEFAULTLOCALE        220\r\n#define IDX_MANIFEST_SCHEMA_V1_4_LOCALE               221\r\n\r\n#define IDX_MANIFEST_SCHEMA_V1_5_SINGLETON            222\r\n#define IDX_MANIFEST_SCHEMA_V1_5_VERSION              223\r\n#define IDX_MANIFEST_SCHEMA_V1_5_INSTALLER            224\r\n#define IDX_MANIFEST_SCHEMA_V1_5_DEFAULTLOCALE        225\r\n#define IDX_MANIFEST_SCHEMA_V1_5_LOCALE               226\r\n\r\n#define IDX_MANIFEST_SCHEMA_V1_6_SINGLETON            227\r\n#define IDX_MANIFEST_SCHEMA_V1_6_VERSION              228\r\n#define IDX_MANIFEST_SCHEMA_V1_6_INSTALLER            229\r\n#define IDX_MANIFEST_SCHEMA_V1_6_DEFAULTLOCALE        230\r\n#define IDX_MANIFEST_SCHEMA_V1_6_LOCALE               231\r\n\r\n#define IDX_MANIFEST_SCHEMA_V1_7_SINGLETON            232\r\n#define IDX_MANIFEST_SCHEMA_V1_7_VERSION              233\r\n#define IDX_MANIFEST_SCHEMA_V1_7_INSTALLER            234\r\n#define IDX_MANIFEST_SCHEMA_V1_7_DEFAULTLOCALE        235\r\n#define IDX_MANIFEST_SCHEMA_V1_7_LOCALE               236\r\n\r\n#define IDX_MANIFEST_SCHEMA_V1_9_SINGLETON            237\r\n#define IDX_MANIFEST_SCHEMA_V1_9_VERSION              238\r\n#define IDX_MANIFEST_SCHEMA_V1_9_INSTALLER            239\r\n#define IDX_MANIFEST_SCHEMA_V1_9_DEFAULTLOCALE        240\r\n#define IDX_MANIFEST_SCHEMA_V1_9_LOCALE               241\r\n\r\n#define IDX_MANIFEST_SCHEMA_V1_10_SINGLETON           242\r\n#define IDX_MANIFEST_SCHEMA_V1_10_VERSION             243\r\n#define IDX_MANIFEST_SCHEMA_V1_10_INSTALLER           244\r\n#define IDX_MANIFEST_SCHEMA_V1_10_DEFAULTLOCALE       245\r\n#define IDX_MANIFEST_SCHEMA_V1_10_LOCALE              246\r\n\r\n#define IDX_MANIFEST_SCHEMA_V1_12_SINGLETON           247\r\n#define IDX_MANIFEST_SCHEMA_V1_12_VERSION             248\r\n#define IDX_MANIFEST_SCHEMA_V1_12_INSTALLER           249\r\n#define IDX_MANIFEST_SCHEMA_V1_12_DEFAULTLOCALE       250\r\n#define IDX_MANIFEST_SCHEMA_V1_12_LOCALE              251\r\n\r\n#define IDX_MANIFEST_SCHEMA_V1_28_SINGLETON           252\r\n#define IDX_MANIFEST_SCHEMA_V1_28_VERSION             253\r\n#define IDX_MANIFEST_SCHEMA_V1_28_INSTALLER           254\r\n#define IDX_MANIFEST_SCHEMA_V1_28_DEFAULTLOCALE       255\r\n#define IDX_MANIFEST_SCHEMA_V1_28_LOCALE              256\r\n\r\n// Packages schema starts at 300\r\n// Certificates start at 400\r\n// If we get to 300, either move the others or skip over them\r\n"
  },
  {
    "path": "src/ManifestSchema/ManifestSchema.rc",
    "content": "// Microsoft Visual C++ generated resource script.\r\n//\r\n#include \"resource.h\"\r\n#include \"ManifestSchema.h\"\r\n\r\n#define APSTUDIO_READONLY_SYMBOLS\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// Generated from the TEXTINCLUDE 2 resource.\r\n//\r\n#include \"winres.h\"\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n#undef APSTUDIO_READONLY_SYMBOLS\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n// English (United States) resources\r\n\r\n#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\nLANGUAGE 9, 1\r\n\r\n#ifdef APSTUDIO_INVOKED\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// TEXTINCLUDE\r\n//\r\n\r\n1 TEXTINCLUDE  \r\nBEGIN\r\n    \"resource.h\\0\"\r\nEND\r\n\r\n2 TEXTINCLUDE  \r\nBEGIN\r\n    \"#include \"\"winres.h\"\"\\r\\n\"\r\n    \"\\0\"\r\nEND\r\n\r\n3 TEXTINCLUDE  \r\nBEGIN\r\n    \"\\r\\n\"\r\n    \"\\0\"\r\nEND\r\n\r\n#endif    // APSTUDIO_INVOKED\r\n\r\n#endif    // English (United States) resources\r\n/////////////////////////////////////////////////////////////////////////////\r\n\r\n\r\n\r\n#ifndef APSTUDIO_INVOKED\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// Generated from the TEXTINCLUDE 3 resource.\r\n//\r\n\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n#endif    // not APSTUDIO_INVOKED\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// Manifest schema\r\n//\r\nIDX_MANIFEST_SCHEMA_PREVIEW                 MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\preview\\\\manifest.0.1.0.json\"\r\n\r\nIDX_MANIFEST_SCHEMA_V1_SINGLETON            MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.0.0\\\\manifest.singleton.1.0.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_VERSION              MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.0.0\\\\manifest.version.1.0.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_INSTALLER            MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.0.0\\\\manifest.installer.1.0.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_DEFAULTLOCALE        MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.0.0\\\\manifest.defaultLocale.1.0.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_LOCALE               MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.0.0\\\\manifest.locale.1.0.0.json\"\r\n\r\nIDX_MANIFEST_SCHEMA_V1_1_SINGLETON          MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.1.0\\\\manifest.singleton.1.1.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_1_VERSION            MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.1.0\\\\manifest.version.1.1.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_1_INSTALLER          MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.1.0\\\\manifest.installer.1.1.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_1_DEFAULTLOCALE      MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.1.0\\\\manifest.defaultLocale.1.1.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_1_LOCALE             MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.1.0\\\\manifest.locale.1.1.0.json\"\r\n\r\nIDX_MANIFEST_SCHEMA_V1_2_SINGLETON          MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.2.0\\\\manifest.singleton.1.2.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_2_VERSION            MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.2.0\\\\manifest.version.1.2.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_2_INSTALLER          MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.2.0\\\\manifest.installer.1.2.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_2_DEFAULTLOCALE      MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.2.0\\\\manifest.defaultLocale.1.2.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_2_LOCALE             MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.2.0\\\\manifest.locale.1.2.0.json\"\r\n\r\nIDX_MANIFEST_SCHEMA_V1_4_SINGLETON          MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.4.0\\\\manifest.singleton.1.4.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_4_VERSION            MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.4.0\\\\manifest.version.1.4.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_4_INSTALLER          MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.4.0\\\\manifest.installer.1.4.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_4_DEFAULTLOCALE      MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.4.0\\\\manifest.defaultLocale.1.4.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_4_LOCALE             MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.4.0\\\\manifest.locale.1.4.0.json\"\r\n\r\nIDX_MANIFEST_SCHEMA_V1_5_SINGLETON          MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.5.0\\\\manifest.singleton.1.5.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_5_VERSION            MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.5.0\\\\manifest.version.1.5.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_5_INSTALLER          MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.5.0\\\\manifest.installer.1.5.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_5_DEFAULTLOCALE      MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.5.0\\\\manifest.defaultLocale.1.5.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_5_LOCALE             MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.5.0\\\\manifest.locale.1.5.0.json\"\r\n\r\nIDX_MANIFEST_SCHEMA_V1_6_SINGLETON          MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.6.0\\\\manifest.singleton.1.6.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_6_VERSION            MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.6.0\\\\manifest.version.1.6.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_6_INSTALLER          MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.6.0\\\\manifest.installer.1.6.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_6_DEFAULTLOCALE      MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.6.0\\\\manifest.defaultLocale.1.6.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_6_LOCALE             MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.6.0\\\\manifest.locale.1.6.0.json\"\r\n\r\nIDX_MANIFEST_SCHEMA_V1_7_SINGLETON          MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.7.0\\\\manifest.singleton.1.7.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_7_VERSION            MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.7.0\\\\manifest.version.1.7.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_7_INSTALLER          MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.7.0\\\\manifest.installer.1.7.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_7_DEFAULTLOCALE      MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.7.0\\\\manifest.defaultLocale.1.7.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_7_LOCALE             MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.7.0\\\\manifest.locale.1.7.0.json\"\r\n\r\nIDX_MANIFEST_SCHEMA_V1_9_SINGLETON          MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.9.0\\\\manifest.singleton.1.9.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_9_VERSION            MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.9.0\\\\manifest.version.1.9.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_9_INSTALLER          MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.9.0\\\\manifest.installer.1.9.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_9_DEFAULTLOCALE      MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.9.0\\\\manifest.defaultLocale.1.9.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_9_LOCALE             MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.9.0\\\\manifest.locale.1.9.0.json\"\r\n\r\nIDX_MANIFEST_SCHEMA_V1_10_SINGLETON         MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.10.0\\\\manifest.singleton.1.10.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_10_VERSION           MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.10.0\\\\manifest.version.1.10.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_10_INSTALLER         MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.10.0\\\\manifest.installer.1.10.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_10_DEFAULTLOCALE     MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.10.0\\\\manifest.defaultLocale.1.10.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_10_LOCALE            MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.10.0\\\\manifest.locale.1.10.0.json\"\r\n\r\nIDX_MANIFEST_SCHEMA_V1_12_SINGLETON         MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.12.0\\\\manifest.singleton.1.12.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_12_VERSION           MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.12.0\\\\manifest.version.1.12.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_12_INSTALLER         MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.12.0\\\\manifest.installer.1.12.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_12_DEFAULTLOCALE     MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.12.0\\\\manifest.defaultLocale.1.12.0.json\"\r\nIDX_MANIFEST_SCHEMA_V1_12_LOCALE            MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\v1.12.0\\\\manifest.locale.1.12.0.json\"\r\n\r\nIDX_MANIFEST_SCHEMA_V1_28_SINGLETON         MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\latest\\\\manifest.singleton.latest.json\"\r\nIDX_MANIFEST_SCHEMA_V1_28_VERSION           MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\latest\\\\manifest.version.latest.json\"\r\nIDX_MANIFEST_SCHEMA_V1_28_INSTALLER         MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\latest\\\\manifest.installer.latest.json\"\r\nIDX_MANIFEST_SCHEMA_V1_28_DEFAULTLOCALE     MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\latest\\\\manifest.defaultLocale.latest.json\"\r\nIDX_MANIFEST_SCHEMA_V1_28_LOCALE            MANIFESTSCHEMA_RESOURCE_TYPE    \"..\\\\..\\\\schemas\\\\JSON\\\\manifests\\\\latest\\\\manifest.locale.latest.json\"\r\n"
  },
  {
    "path": "src/ManifestSchema/ManifestSchema.vcxitems",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <PropertyGroup Label=\"Globals\">\r\n    <MSBuildAllProjects Condition=\"'$(MSBuildVersion)' == '' Or '$(MSBuildVersion)' &lt; '16.0'\">$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>\r\n    <HasSharedItems>true</HasSharedItems>\r\n    <ItemsProjectGuid>{7d05f64d-ce5a-42aa-a2c1-e91458f061cf}</ItemsProjectGuid>\r\n  </PropertyGroup>\r\n  <ItemDefinitionGroup>\r\n    <ClCompile>\r\n      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories>\r\n    </ClCompile>\r\n  </ItemDefinitionGroup>\r\n  <ItemGroup>\r\n    <ProjectCapability Include=\"SourceItemsFromImports\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)ManifestSchema.h\" />\r\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)resource.h\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ResourceCompile Include=\"$(MSBuildThisFileDirectory)ManifestSchema.rc\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\latest\\manifest.defaultLocale.latest.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\latest\\manifest.installer.latest.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\latest\\manifest.locale.latest.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\latest\\manifest.singleton.latest.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\latest\\manifest.version.latest.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\preview\\manifest.0.1.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.0.0\\manifest.defaultLocale.1.0.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.0.0\\manifest.installer.1.0.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.0.0\\manifest.locale.1.0.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.0.0\\manifest.singleton.1.0.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.0.0\\manifest.version.1.0.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.1.0\\manifest.defaultLocale.1.1.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.1.0\\manifest.installer.1.1.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.1.0\\manifest.locale.1.1.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.1.0\\manifest.singleton.1.1.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.1.0\\manifest.version.1.1.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.12.0\\manifest.defaultLocale.1.12.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.12.0\\manifest.installer.1.12.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.12.0\\manifest.locale.1.12.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.12.0\\manifest.singleton.1.12.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.12.0\\manifest.version.1.12.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.2.0\\manifest.defaultLocale.1.2.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.2.0\\manifest.installer.1.2.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.2.0\\manifest.locale.1.2.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.2.0\\manifest.singleton.1.2.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.2.0\\manifest.version.1.2.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.4.0\\manifest.defaultLocale.1.4.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.4.0\\manifest.installer.1.4.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.4.0\\manifest.locale.1.4.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.4.0\\manifest.singleton.1.4.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.4.0\\manifest.version.1.4.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.5.0\\manifest.defaultLocale.1.5.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.5.0\\manifest.installer.1.5.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.5.0\\manifest.locale.1.5.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.5.0\\manifest.singleton.1.5.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.5.0\\manifest.version.1.5.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.6.0\\manifest.defaultLocale.1.6.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.6.0\\manifest.installer.1.6.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.6.0\\manifest.locale.1.6.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.6.0\\manifest.singleton.1.6.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.6.0\\manifest.version.1.6.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.7.0\\manifest.defaultLocale.1.7.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.7.0\\manifest.installer.1.7.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.7.0\\manifest.locale.1.7.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.7.0\\manifest.singleton.1.7.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.7.0\\manifest.version.1.7.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.9.0\\manifest.defaultLocale.1.9.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.9.0\\manifest.installer.1.9.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.9.0\\manifest.locale.1.9.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.9.0\\manifest.singleton.1.9.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.9.0\\manifest.version.1.9.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.10.0\\manifest.defaultLocale.1.10.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.10.0\\manifest.installer.1.10.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.10.0\\manifest.locale.1.10.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.10.0\\manifest.singleton.1.10.0.json\" />\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.10.0\\manifest.version.1.10.0.json\" />\r\n  </ItemGroup>\r\n</Project>"
  },
  {
    "path": "src/ManifestSchema/ManifestSchema.vcxitems.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup>\r\n    <Filter Include=\"schema\">\r\n      <UniqueIdentifier>{d6998b42-8ce1-440a-ad12-8b505a284d7b}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"schema\\latest\">\r\n      <UniqueIdentifier>{f392b73a-3389-4d29-86d9-539a98e2bf3b}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"schema\\preview\">\r\n      <UniqueIdentifier>{fe494b58-5e5c-415a-922f-c6e10725e06a}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"schema\\v1.0.0\">\r\n      <UniqueIdentifier>{74616d1e-e987-4c28-bd85-7bbd205ee813}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"schema\\v1.1.0\">\r\n      <UniqueIdentifier>{36190723-3948-462f-97c2-47fa1b770826}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"schema\\v1.2.0\">\r\n      <UniqueIdentifier>{fb3524f4-5541-468d-a33c-ddcdad90484d}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"schema\\v1.4.0\">\r\n      <UniqueIdentifier>{422a18e9-7735-412d-b16b-98d9d53a1632}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"schema\\v1.5.0\">\r\n      <UniqueIdentifier>{27ca448e-4d6f-4039-bc55-46a7df7c69e2}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"schema\\v1.6.0\">\r\n      <UniqueIdentifier>{d14a3093-eaa9-49d0-9fc4-fbc596afa673}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"schema\\v1.7.0\">\r\n      <UniqueIdentifier>{040a7f05-fd31-466c-bb71-0d59e4cdf1c4}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"schema\\v1.9.0\">\r\n      <UniqueIdentifier>{f7069050-9235-44e0-ab07-72e4addfd765}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"schema\\v1.10.0\">\r\n      <UniqueIdentifier>{9c132cfd-cf4c-48d0-a32b-c52213f742fe}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"schema\\v1.12.0\">\r\n      <UniqueIdentifier>{99217106-7710-40c7-a2df-e5b69c758e5a}</UniqueIdentifier>\r\n    </Filter>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)ManifestSchema.h\" />\r\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)resource.h\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ResourceCompile Include=\"$(MSBuildThisFileDirectory)ManifestSchema.rc\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\latest\\manifest.defaultLocale.latest.json\">\r\n      <Filter>schema\\latest</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\latest\\manifest.installer.latest.json\">\r\n      <Filter>schema\\latest</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\latest\\manifest.locale.latest.json\">\r\n      <Filter>schema\\latest</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\latest\\manifest.singleton.latest.json\">\r\n      <Filter>schema\\latest</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\latest\\manifest.version.latest.json\">\r\n      <Filter>schema\\latest</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\preview\\manifest.0.1.0.json\">\r\n      <Filter>schema\\preview</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.0.0\\manifest.installer.1.0.0.json\">\r\n      <Filter>schema\\v1.0.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.0.0\\manifest.defaultLocale.1.0.0.json\">\r\n      <Filter>schema\\v1.0.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.0.0\\manifest.locale.1.0.0.json\">\r\n      <Filter>schema\\v1.0.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.0.0\\manifest.singleton.1.0.0.json\">\r\n      <Filter>schema\\v1.0.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.0.0\\manifest.version.1.0.0.json\">\r\n      <Filter>schema\\v1.0.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.1.0\\manifest.defaultLocale.1.1.0.json\">\r\n      <Filter>schema\\v1.1.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.1.0\\manifest.installer.1.1.0.json\">\r\n      <Filter>schema\\v1.1.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.1.0\\manifest.locale.1.1.0.json\">\r\n      <Filter>schema\\v1.1.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.1.0\\manifest.singleton.1.1.0.json\">\r\n      <Filter>schema\\v1.1.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.1.0\\manifest.version.1.1.0.json\">\r\n      <Filter>schema\\v1.1.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.2.0\\manifest.version.1.2.0.json\">\r\n      <Filter>schema\\v1.2.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.2.0\\manifest.defaultLocale.1.2.0.json\">\r\n      <Filter>schema\\v1.2.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.2.0\\manifest.installer.1.2.0.json\">\r\n      <Filter>schema\\v1.2.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.2.0\\manifest.locale.1.2.0.json\">\r\n      <Filter>schema\\v1.2.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.2.0\\manifest.singleton.1.2.0.json\">\r\n      <Filter>schema\\v1.2.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.4.0\\manifest.version.1.4.0.json\">\r\n      <Filter>schema\\v1.4.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.4.0\\manifest.defaultLocale.1.4.0.json\">\r\n      <Filter>schema\\v1.4.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.4.0\\manifest.installer.1.4.0.json\">\r\n      <Filter>schema\\v1.4.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.4.0\\manifest.locale.1.4.0.json\">\r\n      <Filter>schema\\v1.4.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.4.0\\manifest.singleton.1.4.0.json\">\r\n      <Filter>schema\\v1.4.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.5.0\\manifest.version.1.5.0.json\">\r\n      <Filter>schema\\v1.5.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.5.0\\manifest.defaultLocale.1.5.0.json\">\r\n      <Filter>schema\\v1.5.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.5.0\\manifest.installer.1.5.0.json\">\r\n      <Filter>schema\\v1.5.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.5.0\\manifest.locale.1.5.0.json\">\r\n      <Filter>schema\\v1.5.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.5.0\\manifest.singleton.1.5.0.json\">\r\n      <Filter>schema\\v1.5.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.6.0\\manifest.version.1.6.0.json\">\r\n      <Filter>schema\\v1.6.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.6.0\\manifest.defaultLocale.1.6.0.json\">\r\n      <Filter>schema\\v1.6.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.6.0\\manifest.installer.1.6.0.json\">\r\n      <Filter>schema\\v1.6.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.6.0\\manifest.locale.1.6.0.json\">\r\n      <Filter>schema\\v1.6.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.6.0\\manifest.singleton.1.6.0.json\">\r\n      <Filter>schema\\v1.6.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.7.0\\manifest.defaultLocale.1.7.0.json\">\r\n      <Filter>schema\\v1.7.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.7.0\\manifest.installer.1.7.0.json\">\r\n      <Filter>schema\\v1.7.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.7.0\\manifest.locale.1.7.0.json\">\r\n      <Filter>schema\\v1.7.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.7.0\\manifest.singleton.1.7.0.json\">\r\n      <Filter>schema\\v1.7.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.7.0\\manifest.version.1.7.0.json\">\r\n      <Filter>schema\\v1.7.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.9.0\\manifest.defaultLocale.1.9.0.json\">\r\n      <Filter>schema\\v1.9.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.9.0\\manifest.installer.1.9.0.json\">\r\n      <Filter>schema\\v1.9.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.9.0\\manifest.locale.1.9.0.json\">\r\n      <Filter>schema\\v1.9.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.9.0\\manifest.singleton.1.9.0.json\">\r\n      <Filter>schema\\v1.9.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.9.0\\manifest.version.1.9.0.json\">\r\n      <Filter>schema\\v1.9.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.10.0\\manifest.defaultLocale.1.10.0.json\">\r\n      <Filter>schema\\v1.10.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.10.0\\manifest.installer.1.10.0.json\">\r\n      <Filter>schema\\v1.10.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.10.0\\manifest.locale.1.10.0.json\">\r\n      <Filter>schema\\v1.10.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.10.0\\manifest.singleton.1.10.0.json\">\r\n      <Filter>schema\\v1.10.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.10.0\\manifest.version.1.10.0.json\">\r\n      <Filter>schema\\v1.10.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.12.0\\manifest.defaultLocale.1.12.0.json\">\r\n      <Filter>schema\\v1.12.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.12.0\\manifest.installer.1.12.0.json\">\r\n      <Filter>schema\\v1.12.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.12.0\\manifest.locale.1.12.0.json\">\r\n      <Filter>schema\\v1.12.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.12.0\\manifest.singleton.1.12.0.json\">\r\n      <Filter>schema\\v1.12.0</Filter>\r\n    </None>\r\n    <None Include=\"$(MSBuildThisFileDirectory)..\\..\\schemas\\JSON\\manifests\\v1.12.0\\manifest.version.1.12.0.json\">\r\n      <Filter>schema\\v1.12.0</Filter>\r\n    </None>\r\n  </ItemGroup>\r\n</Project>"
  },
  {
    "path": "src/ManifestSchema/resource.h",
    "content": "//{{NO_DEPENDENCIES}}\r\n// Microsoft Visual C++ generated include file.\r\n// Used by ManifestSchema.rc\r\n\r\n// Next default values for new objects\r\n//\r\n#ifdef APSTUDIO_INVOKED\r\n#ifndef APSTUDIO_READONLY_SYMBOLS\r\n#define _APS_NEXT_RESOURCE_VALUE        101\r\n#define _APS_NEXT_COMMAND_VALUE         40001\r\n#define _APS_NEXT_CONTROL_VALUE         1001\r\n#define _APS_NEXT_SYMED_VALUE           101\r\n#endif\r\n#endif\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ApplyConfigurationSetResult.h\"\r\n#include \"ApplyConfigurationSetResult.g.cpp\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    ApplyConfigurationSetResult::ApplyConfigurationSetResult() :\r\n        m_unitResults(multi_threaded_vector<ApplyConfigurationUnitResult>())\r\n    {}\r\n\r\n    Windows::Foundation::Collections::IVectorView<ApplyConfigurationUnitResult> ApplyConfigurationSetResult::UnitResults() const\r\n    {\r\n        return m_unitResults.GetView();\r\n    }\r\n\r\n    const Windows::Foundation::Collections::IVector<ApplyConfigurationUnitResult>& ApplyConfigurationSetResult::UnitResultsVector()\r\n    {\r\n        return m_unitResults;\r\n    }\r\n\r\n    hresult ApplyConfigurationSetResult::ResultCode() const\r\n    {\r\n        return m_resultCode;\r\n    }\r\n\r\n    void ApplyConfigurationSetResult::ResultCode(hresult value)\r\n    {\r\n        m_resultCode = value;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ApplyConfigurationSetResult.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ApplyConfigurationSetResult.g.h\"\r\n#include <winrt/Windows.Foundation.Collections.h>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    struct ApplyConfigurationSetResult : ApplyConfigurationSetResultT<ApplyConfigurationSetResult>\r\n    {\r\n        using ApplyConfigurationUnitResult = Configuration::ApplyConfigurationUnitResult;\r\n\r\n        ApplyConfigurationSetResult();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        const Windows::Foundation::Collections::IVector<ApplyConfigurationUnitResult>& UnitResultsVector();\r\n        void ResultCode(hresult value);\r\n#endif\r\n\r\n        Windows::Foundation::Collections::IVectorView<ApplyConfigurationUnitResult> UnitResults() const;\r\n        hresult ResultCode() const;\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        Windows::Foundation::Collections::IVector<ApplyConfigurationUnitResult> m_unitResults;\r\n        hresult m_resultCode;\r\n#endif\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ApplyConfigurationUnitResult.h\"\r\n#include \"ApplyConfigurationUnitResult.g.cpp\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    ApplyConfigurationUnitResult::ApplyConfigurationUnitResult() :\r\n        m_resultInformation(make_self<wil::details::module_count_wrapper<implementation::ConfigurationUnitResultInformation>>())\r\n    {\r\n    }\r\n\r\n    void ApplyConfigurationUnitResult::Initialize(const IApplySettingsResult& result)\r\n    {\r\n        m_unit = result.Unit();\r\n        THROW_HR_IF(E_POINTER, !m_unit);\r\n        m_resultInformation->Initialize(result.ResultInformation());\r\n    }\r\n\r\n    void ApplyConfigurationUnitResult::Initialize(const IApplyGroupMemberSettingsResult& unitResult)\r\n    {\r\n        m_unit = unitResult.Unit();\r\n        THROW_HR_IF(E_POINTER, !m_unit);\r\n        m_resultInformation->Initialize(unitResult.ResultInformation());\r\n        m_state = unitResult.State();\r\n        m_previouslyInDesiredState = unitResult.PreviouslyInDesiredState();\r\n        m_rebootRequired = unitResult.RebootRequired();\r\n    }\r\n\r\n    ConfigurationUnit ApplyConfigurationUnitResult::Unit()\r\n    {\r\n        return m_unit;\r\n    }\r\n\r\n    void ApplyConfigurationUnitResult::Unit(ConfigurationUnit value)\r\n    {\r\n        m_unit = std::move(value);\r\n    }\r\n\r\n    ConfigurationUnitState ApplyConfigurationUnitResult::State() const\r\n    {\r\n        return m_state.load();\r\n    }\r\n\r\n    void ApplyConfigurationUnitResult::State(ConfigurationUnitState value)\r\n    {\r\n        m_state.store(value);\r\n    }\r\n\r\n    bool ApplyConfigurationUnitResult::PreviouslyInDesiredState() const\r\n    {\r\n        return m_previouslyInDesiredState;\r\n    }\r\n\r\n    void ApplyConfigurationUnitResult::PreviouslyInDesiredState(bool value)\r\n    {\r\n        m_previouslyInDesiredState = value;\r\n    }\r\n\r\n    bool ApplyConfigurationUnitResult::RebootRequired() const\r\n    {\r\n        return m_rebootRequired;\r\n    }\r\n\r\n    void ApplyConfigurationUnitResult::RebootRequired(bool value)\r\n    {\r\n        m_rebootRequired = value;\r\n    }\r\n\r\n    IConfigurationUnitResultInformation ApplyConfigurationUnitResult::ResultInformation()\r\n    {\r\n        return *m_resultInformation;\r\n    }\r\n\r\n    void ApplyConfigurationUnitResult::ResultInformation(const Configuration::IConfigurationUnitResultInformation& value)\r\n    {\r\n        m_resultInformation->Initialize(value);\r\n    }\r\n\r\n    ApplyConfigurationUnitResult::ResultInformationT ApplyConfigurationUnitResult::ResultInformationInternal()\r\n    {\r\n        return m_resultInformation;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ApplyConfigurationUnitResult.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ApplyConfigurationUnitResult.g.h\"\r\n#include \"ConfigurationUnitResultInformation.h\"\r\n#include <atomic>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    struct ApplyConfigurationUnitResult : ApplyConfigurationUnitResultT<ApplyConfigurationUnitResult, IApplyGroupMemberSettingsResult>\r\n    {\r\n        using ConfigurationUnit = Configuration::ConfigurationUnit;\r\n        using ResultInformationT = decltype(make_self<wil::details::module_count_wrapper<implementation::ConfigurationUnitResultInformation>>());\r\n\r\n        ApplyConfigurationUnitResult();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        void Initialize(const IApplySettingsResult& result);\r\n        void Initialize(const IApplyGroupMemberSettingsResult& unitResult);\r\n\r\n        void Unit(ConfigurationUnit value);\r\n        void State(ConfigurationUnitState value);\r\n        void PreviouslyInDesiredState(bool value);\r\n        void RebootRequired(bool value);\r\n        void ResultInformation(const Configuration::IConfigurationUnitResultInformation& value);\r\n        ResultInformationT ResultInformationInternal();\r\n#endif\r\n\r\n        ConfigurationUnit Unit();\r\n        ConfigurationUnitState State() const;\r\n        bool PreviouslyInDesiredState() const;\r\n        bool RebootRequired() const;\r\n        IConfigurationUnitResultInformation ResultInformation();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        ConfigurationUnit m_unit = nullptr;\r\n        std::atomic<ConfigurationUnitState> m_state = ConfigurationUnitState::Pending;\r\n        bool m_previouslyInDesiredState = false;\r\n        bool m_rebootRequired = false;\r\n        ResultInformationT m_resultInformation;\r\n#endif\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ApplyGroupSettingsResult.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ApplyGroupSettingsResult.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    ApplyGroupSettingsResult::ApplyGroupSettingsResult() :\r\n        m_resultInformation(make_self<wil::details::module_count_wrapper<implementation::ConfigurationUnitResultInformation>>()),\r\n        m_unitResults(winrt::multi_threaded_vector<IApplyGroupMemberSettingsResult>())\r\n    {}\r\n\r\n    void ApplyGroupSettingsResult::Group(const Windows::Foundation::IInspectable& value)\r\n    {\r\n        m_group = value;\r\n    }\r\n\r\n    void ApplyGroupSettingsResult::RebootRequired(bool value)\r\n    {\r\n        m_rebootRequired = value;\r\n    }\r\n\r\n    ApplyGroupSettingsResult::ResultInformationPtr ApplyGroupSettingsResult::ResultInformationInternal()\r\n    {\r\n        return m_resultInformation;\r\n    }\r\n\r\n    Windows::Foundation::IInspectable ApplyGroupSettingsResult::Group()\r\n    {\r\n        return m_group;\r\n    }\r\n\r\n    bool ApplyGroupSettingsResult::RebootRequired()\r\n    {\r\n        return m_rebootRequired;\r\n    }\r\n\r\n    IConfigurationUnitResultInformation ApplyGroupSettingsResult::ResultInformation()\r\n    {\r\n        return *m_resultInformation;\r\n    }\r\n\r\n    Windows::Foundation::Collections::IVector<IApplyGroupMemberSettingsResult> ApplyGroupSettingsResult::UnitResults()\r\n    {\r\n        return m_unitResults;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ApplyGroupSettingsResult.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"winrt/Microsoft.Management.Configuration.h\"\r\n#include \"ConfigurationUnitResultInformation.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    struct ApplyGroupSettingsResult : winrt::implements<ApplyGroupSettingsResult, IApplyGroupSettingsResult>\r\n    {\r\n        ApplyGroupSettingsResult();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        using ResultInformationPtr = decltype(make_self<wil::details::module_count_wrapper<implementation::ConfigurationUnitResultInformation>>());\r\n\r\n        void Group(const Windows::Foundation::IInspectable& value);\r\n        void RebootRequired(bool value);\r\n        ResultInformationPtr ResultInformationInternal();\r\n#endif\r\n\r\n        Windows::Foundation::IInspectable Group();\r\n        bool RebootRequired();\r\n        IConfigurationUnitResultInformation ResultInformation();\r\n        Windows::Foundation::Collections::IVector<IApplyGroupMemberSettingsResult> UnitResults();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        Windows::Foundation::IInspectable m_group;\r\n        bool m_rebootRequired = false;\r\n        ResultInformationPtr m_resultInformation;\r\n        Windows::Foundation::Collections::IVector<IApplyGroupMemberSettingsResult> m_unitResults;\r\n#endif\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ArgumentValidation.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include <pch.h>\r\n#include \"ArgumentValidation.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    void EnsureSupportedType(Windows::Foundation::PropertyType type)\r\n    {\r\n        switch (type)\r\n        {\r\n        case Windows::Foundation::PropertyType::UInt8:\r\n        case Windows::Foundation::PropertyType::Int16:\r\n        case Windows::Foundation::PropertyType::UInt16:\r\n        case Windows::Foundation::PropertyType::Int32:\r\n        case Windows::Foundation::PropertyType::UInt32:\r\n        case Windows::Foundation::PropertyType::Int64:\r\n        case Windows::Foundation::PropertyType::UInt64:\r\n        case Windows::Foundation::PropertyType::Single:\r\n        case Windows::Foundation::PropertyType::Double:\r\n        case Windows::Foundation::PropertyType::Char16:\r\n        case Windows::Foundation::PropertyType::Boolean:\r\n        case Windows::Foundation::PropertyType::String:\r\n        case Windows::Foundation::PropertyType::Inspectable:\r\n        case Windows::Foundation::PropertyType::DateTime:\r\n        case Windows::Foundation::PropertyType::TimeSpan:\r\n        case Windows::Foundation::PropertyType::Guid:\r\n        case Windows::Foundation::PropertyType::UInt8Array:\r\n        case Windows::Foundation::PropertyType::Int16Array:\r\n        case Windows::Foundation::PropertyType::UInt16Array:\r\n        case Windows::Foundation::PropertyType::Int32Array:\r\n        case Windows::Foundation::PropertyType::UInt32Array:\r\n        case Windows::Foundation::PropertyType::Int64Array:\r\n        case Windows::Foundation::PropertyType::UInt64Array:\r\n        case Windows::Foundation::PropertyType::SingleArray:\r\n        case Windows::Foundation::PropertyType::DoubleArray:\r\n        case Windows::Foundation::PropertyType::Char16Array:\r\n        case Windows::Foundation::PropertyType::BooleanArray:\r\n        case Windows::Foundation::PropertyType::StringArray:\r\n        case Windows::Foundation::PropertyType::InspectableArray:\r\n        case Windows::Foundation::PropertyType::DateTimeArray:\r\n        case Windows::Foundation::PropertyType::TimeSpanArray:\r\n        case Windows::Foundation::PropertyType::GuidArray:\r\n            return;\r\n        }\r\n\r\n        THROW_HR(E_INVALIDARG);\r\n    }\r\n\r\n    bool IsValidObjectType(Windows::Foundation::IInspectable const& value, Windows::Foundation::PropertyType type)\r\n    {\r\n        auto propertyValue = value.try_as<Windows::Foundation::IPropertyValue>();\r\n\r\n        // If the type is an object, it is acceptable for the value to be a ValueSet directly\r\n        if (type == Windows::Foundation::PropertyType::Inspectable &&\r\n            (propertyValue || value.try_as<Windows::Foundation::Collections::ValueSet>()))\r\n        {\r\n            return true;\r\n        }\r\n\r\n        // If it wasn't an object type and a ValueSet, it must be an IPropertyValue\r\n        if (!propertyValue)\r\n        {\r\n            return false;\r\n        }\r\n\r\n        // If it is an IPropertyValue, it must have the required type\r\n        return (propertyValue.Type() == type);\r\n    }\r\n\r\n    void EnsureObjectType(Windows::Foundation::IInspectable const& value, Windows::Foundation::PropertyType type)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, !IsValidObjectType(value, type));\r\n    }\r\n\r\n    bool IsComparableType(Windows::Foundation::PropertyType type)\r\n    {\r\n        switch (type)\r\n        {\r\n        case Windows::Foundation::PropertyType::UInt8:\r\n        case Windows::Foundation::PropertyType::Int16:\r\n        case Windows::Foundation::PropertyType::UInt16:\r\n        case Windows::Foundation::PropertyType::Int32:\r\n        case Windows::Foundation::PropertyType::UInt32:\r\n        case Windows::Foundation::PropertyType::Int64:\r\n        case Windows::Foundation::PropertyType::UInt64:\r\n        case Windows::Foundation::PropertyType::Single:\r\n        case Windows::Foundation::PropertyType::Double:\r\n        case Windows::Foundation::PropertyType::Char16:\r\n        case Windows::Foundation::PropertyType::DateTime:\r\n        case Windows::Foundation::PropertyType::TimeSpan:\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    void EnsureComparableType(Windows::Foundation::PropertyType type)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, !IsComparableType(type));\r\n    }\r\n\r\n    bool IsLengthType(Windows::Foundation::PropertyType type)\r\n    {\r\n        switch (type)\r\n        {\r\n        case Windows::Foundation::PropertyType::String:\r\n        case Windows::Foundation::PropertyType::UInt8Array:\r\n        case Windows::Foundation::PropertyType::Int16Array:\r\n        case Windows::Foundation::PropertyType::UInt16Array:\r\n        case Windows::Foundation::PropertyType::Int32Array:\r\n        case Windows::Foundation::PropertyType::UInt32Array:\r\n        case Windows::Foundation::PropertyType::Int64Array:\r\n        case Windows::Foundation::PropertyType::UInt64Array:\r\n        case Windows::Foundation::PropertyType::SingleArray:\r\n        case Windows::Foundation::PropertyType::DoubleArray:\r\n        case Windows::Foundation::PropertyType::Char16Array:\r\n        case Windows::Foundation::PropertyType::BooleanArray:\r\n        case Windows::Foundation::PropertyType::StringArray:\r\n        case Windows::Foundation::PropertyType::InspectableArray:\r\n        case Windows::Foundation::PropertyType::DateTimeArray:\r\n        case Windows::Foundation::PropertyType::TimeSpanArray:\r\n        case Windows::Foundation::PropertyType::GuidArray:\r\n        case Windows::Foundation::PropertyType::PointArray:\r\n        case Windows::Foundation::PropertyType::SizeArray:\r\n        case Windows::Foundation::PropertyType::RectArray:\r\n        case Windows::Foundation::PropertyType::OtherTypeArray:\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    void EnsureLengthType(Windows::Foundation::PropertyType type)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, !IsLengthType(type));\r\n    }\r\n\r\n    bool IsStringableType(Windows::Foundation::PropertyType type)\r\n    {\r\n        switch (type)\r\n        {\r\n        case Windows::Foundation::PropertyType::UInt8:\r\n        case Windows::Foundation::PropertyType::Int16:\r\n        case Windows::Foundation::PropertyType::UInt16:\r\n        case Windows::Foundation::PropertyType::Int32:\r\n        case Windows::Foundation::PropertyType::UInt32:\r\n        case Windows::Foundation::PropertyType::Int64:\r\n        case Windows::Foundation::PropertyType::UInt64:\r\n        case Windows::Foundation::PropertyType::Single:\r\n        case Windows::Foundation::PropertyType::Double:\r\n        case Windows::Foundation::PropertyType::Char16:\r\n        case Windows::Foundation::PropertyType::Boolean:\r\n        case Windows::Foundation::PropertyType::String:\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    hstring ToString(Windows::Foundation::IPropertyValue value)\r\n    {\r\n        Windows::Foundation::PropertyType type = value.Type();\r\n        if (type == Windows::Foundation::PropertyType::String)\r\n        {\r\n            return value.GetString();\r\n        }\r\n\r\n        std::wostringstream stream;\r\n\r\n        switch (value.Type())\r\n        {\r\n        case Windows::Foundation::PropertyType::UInt8:\r\n            stream << value.GetUInt8();\r\n            break;\r\n        case Windows::Foundation::PropertyType::Int16:\r\n            stream << value.GetInt16();\r\n            break;\r\n        case Windows::Foundation::PropertyType::UInt16:\r\n            stream << value.GetUInt16();\r\n            break;\r\n        case Windows::Foundation::PropertyType::Int32:\r\n            stream << value.GetInt32();\r\n            break;\r\n        case Windows::Foundation::PropertyType::UInt32:\r\n            stream << value.GetUInt32();\r\n            break;\r\n        case Windows::Foundation::PropertyType::Int64:\r\n            stream << value.GetInt64();\r\n            break;\r\n        case Windows::Foundation::PropertyType::UInt64:\r\n            stream << value.GetUInt64();\r\n            break;\r\n        case Windows::Foundation::PropertyType::Single:\r\n            stream << value.GetSingle();\r\n            break;\r\n        case Windows::Foundation::PropertyType::Double:\r\n            stream << value.GetDouble();\r\n            break;\r\n        case Windows::Foundation::PropertyType::Char16:\r\n            stream << value.GetChar16();\r\n            break;\r\n        case Windows::Foundation::PropertyType::Boolean:\r\n            stream << value.GetBoolean() ? L\"true\" : L\"false\";\r\n            break;\r\n        }\r\n\r\n        return hstring{ stream.str() };\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ArgumentValidation.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winrt/Windows.Foundation.h>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    // Ensures that the given type is supported.\r\n    void EnsureSupportedType(Windows::Foundation::PropertyType type);\r\n\r\n    // Ensures that the value object matches the expected property type.\r\n    bool IsValidObjectType(Windows::Foundation::IInspectable const& value, Windows::Foundation::PropertyType type);\r\n\r\n    // Ensures that the value object matches the expected property type.\r\n    void EnsureObjectType(Windows::Foundation::IInspectable const& value, Windows::Foundation::PropertyType type);\r\n\r\n    // Determines if the given type supports comparison.\r\n    bool IsComparableType(Windows::Foundation::PropertyType type);\r\n\r\n    // Ensures that the given type supports comparison.\r\n    void EnsureComparableType(Windows::Foundation::PropertyType type);\r\n\r\n    // Determines if the given type supports length restrictions.\r\n    bool IsLengthType(Windows::Foundation::PropertyType type);\r\n\r\n    // Ensures that the given type supports length restrictions.\r\n    void EnsureLengthType(Windows::Foundation::PropertyType type);\r\n\r\n    // Determines if the given type is a scalar that can be converted to a reasonable string representation.\r\n    bool IsStringableType(Windows::Foundation::PropertyType type);\r\n\r\n    // Gets the string version of the given property, if it is stringable.\r\n    hstring ToString(Windows::Foundation::IPropertyValue value);\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigThreadGlobals.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigThreadGlobals.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    AppInstaller::Logging::DiagnosticLogger& ConfigThreadGlobals::GetDiagnosticLogger()\r\n    {\r\n        return m_logger;\r\n    }\r\n\r\n    void* ConfigThreadGlobals::GetTelemetryObject()\r\n    {\r\n        return &m_telemetry;\r\n    }\r\n\r\n    TelemetryTraceLogger& ConfigThreadGlobals::GetTelemetryLogger()\r\n    {\r\n        return m_telemetry;\r\n    }\r\n\r\n    const TelemetryTraceLogger& ConfigThreadGlobals::GetTelemetryLogger() const\r\n    {\r\n        return m_telemetry;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigThreadGlobals.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SharedThreadGlobals.h>\r\n#include <Telemetry/Telemetry.h>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    // Interface for access to values that are stored on a per-thread object.\r\n    struct ConfigThreadGlobals : public AppInstaller::ThreadLocalStorage::ThreadGlobals\r\n    {\r\n        ConfigThreadGlobals() = default;\r\n        virtual ~ConfigThreadGlobals() = default;\r\n\r\n        AppInstaller::Logging::DiagnosticLogger& GetDiagnosticLogger() override;\r\n\r\n        void* GetTelemetryObject() override;\r\n\r\n        TelemetryTraceLogger& GetTelemetryLogger();\r\n        const TelemetryTraceLogger& GetTelemetryLogger() const;\r\n\r\n    protected:\r\n        AppInstaller::Logging::DiagnosticLogger m_logger;\r\n        TelemetryTraceLogger m_telemetry;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationChangeData.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigurationChangeData.h\"\r\n#include \"ConfigurationChangeData.g.cpp\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    void ConfigurationChangeData::Initialize(ConfigurationChangeEventType change, guid instanceIdentifier, ConfigurationSetState state)\n    {\n        m_change = change;\n        m_instanceIdentifier = instanceIdentifier;\n        m_state = state;\n    }\n\r\n    ConfigurationChangeEventType ConfigurationChangeData::Change()\n    {\n        return m_change;\n    }\n\r\n    guid ConfigurationChangeData::InstanceIdentifier()\n    {\n        return m_instanceIdentifier;\n    }\n\r\n    ConfigurationSetState ConfigurationChangeData::State()\n    {\n        return m_state;\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationChangeData.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ConfigurationChangeData.g.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    struct ConfigurationChangeData : ConfigurationChangeDataT<ConfigurationChangeData>\r\n    {\r\n        ConfigurationChangeData() = default;\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        void Initialize(ConfigurationChangeEventType change, guid instanceIdentifier, ConfigurationSetState state);\r\n#endif\r\n\r\n        ConfigurationChangeEventType Change();\r\n        guid InstanceIdentifier();\r\n        ConfigurationSetState State();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        ConfigurationChangeEventType m_change{};\r\n        guid m_instanceIdentifier{};\r\n        ConfigurationSetState m_state{};\r\n#endif\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationConflict.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigurationConflict.h\"\r\n#include \"ConfigurationConflict.g.cpp\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    void ConfigurationConflict::Initialize(ConfigurationConflictType conflict)\n    {\n        m_conflict = conflict;\n    }\n\r\n    ConfigurationConflictType ConfigurationConflict::Conflict()\n    {\n        return m_conflict;\n    }\n\r\n    ConfigurationSet ConfigurationConflict::FirstSet()\n    {\n        return m_firstSet;\n    }\n\r\n    ConfigurationSet ConfigurationConflict::SecondSet()\n    {\n        return m_secondSet;\n    }\n\r\n    ConfigurationUnit ConfigurationConflict::FirstUnit()\n    {\n        return m_firstUnit;\n    }\n\r\n    ConfigurationUnit ConfigurationConflict::SecondUnit()\n    {\n        return m_secondUnit;\n    }\n\r\n    Windows::Foundation::Collections::IVectorView<ConfigurationConflictSetting> ConfigurationConflict::Settings()\n    {\n        if (m_settings)\n        {\n            return m_settings.GetView();\n        }\n        else\n        {\n            return nullptr;\n        }\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationConflict.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ConfigurationConflict.g.h\"\r\n#include <winrt/Windows.Foundation.Collections.h>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    struct ConfigurationConflict : ConfigurationConflictT<ConfigurationConflict>\r\n    {\r\n        ConfigurationConflict() = default;\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        void Initialize(ConfigurationConflictType conflict);\r\n#endif\r\n\r\n        ConfigurationConflictType Conflict();\r\n        ConfigurationSet FirstSet();\r\n        ConfigurationSet SecondSet();\r\n        ConfigurationUnit FirstUnit();\r\n        ConfigurationUnit SecondUnit();\r\n        Windows::Foundation::Collections::IVectorView<ConfigurationConflictSetting> Settings();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        ConfigurationConflictType m_conflict{};\r\n        ConfigurationSet m_firstSet = nullptr;\r\n        ConfigurationSet m_secondSet = nullptr;\r\n        ConfigurationUnit m_firstUnit = nullptr;\r\n        ConfigurationUnit m_secondUnit = nullptr;\r\n        Windows::Foundation::Collections::IVector<ConfigurationConflictSetting> m_settings = nullptr;\r\n#endif\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationConflictSetting.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigurationConflictSetting.h\"\r\n#include \"ConfigurationConflictSetting.g.cpp\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    void ConfigurationConflictSetting::Initialize(std::wstring_view name, const IInspectable& firstValue, const IInspectable& secondValue)\r\n    {\r\n        m_name = name;\r\n        m_firstValue = firstValue;\r\n        m_secondValue = secondValue;\r\n    }\r\n\r\n    hstring ConfigurationConflictSetting::Name()\r\n    {\r\n        return m_name;\r\n    }\r\n\r\n    ConfigurationConflictSetting::IInspectable ConfigurationConflictSetting::FirstValue()\r\n    {\r\n        return m_firstValue;\r\n    }\r\n\r\n    ConfigurationConflictSetting::IInspectable ConfigurationConflictSetting::SecondValue()\r\n    {\r\n        return m_secondValue;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationConflictSetting.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ConfigurationConflictSetting.g.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    struct ConfigurationConflictSetting : ConfigurationConflictSettingT<ConfigurationConflictSetting>\r\n    {\r\n        ConfigurationConflictSetting() = default;\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        void Initialize(std::wstring_view name, const IInspectable& firstValue, const IInspectable& secondValue);\r\n#endif\r\n\r\n        hstring Name();\r\n        IInspectable FirstValue();\r\n        IInspectable SecondValue();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        hstring m_name;\r\n        IInspectable m_firstValue = nullptr;\r\n        IInspectable m_secondValue = nullptr;\r\n#endif\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationEnvironment.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigurationEnvironment.h\"\r\n#include \"ConfigurationEnvironment.g.cpp\"\r\n#include \"ArgumentValidation.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    namespace\r\n    {\r\n        template <typename T>\r\n        void DeepCopyEnvironmentFrom(implementation::ConfigurationEnvironment& self, const T& toDeepCopy)\r\n        {\r\n            self.Context(toDeepCopy.Context());\r\n            self.ProcessorIdentifier(toDeepCopy.ProcessorIdentifier());\r\n            self.ProcessorProperties(toDeepCopy.ProcessorProperties());\r\n        }\r\n    }\r\n\r\n    ConfigurationEnvironment::ConfigurationEnvironment() :\r\n        m_processorProperties(multi_threaded_map<hstring, hstring>())\r\n    {}\r\n\r\n    ConfigurationEnvironment::ConfigurationEnvironment(SecurityContext context, const std::wstring& processorIdentifier, std::map<hstring, hstring>&& processorProperties) :\r\n        m_context(context), m_processorIdentifier(processorIdentifier), m_processorProperties(multi_threaded_map(std::move(processorProperties)))\r\n    {}\r\n\r\n    ConfigurationEnvironment::ConfigurationEnvironment(const implementation::ConfigurationEnvironment& toDeepCopy)\r\n    {\r\n        DeepCopy(toDeepCopy);\r\n    }\r\n\r\n    ConfigurationEnvironment::ConfigurationEnvironment(const Configuration::ConfigurationEnvironment& toDeepCopy)\r\n    {\r\n        DeepCopyEnvironmentFrom(*this, toDeepCopy);\r\n    }\r\n\r\n    SecurityContext ConfigurationEnvironment::Context() const\r\n    {\r\n        return m_context;\r\n    }\r\n\r\n    void ConfigurationEnvironment::Context(SecurityContext value)\r\n    {\r\n        m_context = value;\r\n    }\r\n\r\n    hstring ConfigurationEnvironment::ProcessorIdentifier() const\r\n    {\r\n        return m_processorIdentifier;\r\n    }\r\n\r\n    void ConfigurationEnvironment::ProcessorIdentifier(const hstring& value)\r\n    {\r\n        m_processorIdentifier = value;\r\n    }\r\n\r\n    Windows::Foundation::Collections::IMap<hstring, hstring> ConfigurationEnvironment::ProcessorProperties() const\r\n    {\r\n        return m_processorProperties;\r\n    }\r\n\r\n    void ConfigurationEnvironment::DeepCopy(const implementation::ConfigurationEnvironment& toDeepCopy)\r\n    {\r\n        DeepCopyEnvironmentFrom(*this, toDeepCopy);\r\n    }\r\n\r\n    void ConfigurationEnvironment::ProcessorProperties(const Windows::Foundation::Collections::IMap<hstring, hstring>& values)\r\n    {\r\n        std::map<hstring, hstring> properties;\r\n        for (const auto& property : values)\r\n        {\r\n            properties.emplace(property.Key(), property.Value());\r\n        }\r\n        m_processorProperties = multi_threaded_map(std::move(properties));\r\n    }\r\n\r\n    void ConfigurationEnvironment::ProcessorProperties(const Windows::Foundation::Collections::ValueSet& values)\r\n    {\r\n        std::map<hstring, hstring> properties;\r\n\r\n        for (const auto& value : values)\r\n        {\r\n            Windows::Foundation::IPropertyValue property = value.Value().try_as<Windows::Foundation::IPropertyValue>();\r\n            if (property && IsStringableType(property.Type()))\r\n            {\r\n                properties.emplace(value.Key(), ToString(property));\r\n            }\r\n        }\r\n\r\n        m_processorProperties = multi_threaded_map(std::move(properties));\r\n    }\r\n\r\n    bool ConfigurationEnvironment::IsDefault() const\r\n    {\r\n        return m_context == SecurityContext::Current && m_processorIdentifier.empty() && m_processorProperties.Size() == 0;\r\n    }\r\n\r\n    com_ptr<ConfigurationEnvironment> ConfigurationEnvironment::CalculateCommonEnvironment(const std::vector<Configuration::ConfigurationEnvironment>& environments)\r\n    {\r\n        com_ptr<ConfigurationEnvironment> result;\r\n\r\n        if (environments.empty())\r\n        {\r\n            result = make_self<ConfigurationEnvironment>();\r\n        }\r\n        else\r\n        {\r\n            result = make_self<ConfigurationEnvironment>(environments.front());\r\n\r\n            for (size_t i = 1; i < environments.size(); ++i)\r\n            {\r\n               const Configuration::ConfigurationEnvironment& environment = environments[i];\r\n\r\n               if (result->m_context != environment.Context())\r\n               {\r\n                   result->m_context = SecurityContext::Current;\r\n               }\r\n\r\n               if (result->m_processorIdentifier != environment.ProcessorIdentifier())\r\n               {\r\n                   result->m_processorIdentifier.clear();\r\n               }\r\n\r\n               if (!AreEqual(result->m_processorProperties, environment.ProcessorProperties()))\r\n               {\r\n                   result->m_processorProperties = single_threaded_map<hstring, hstring>();\r\n               }\r\n\r\n               // Check if we have already found everything to be different\r\n               if (result->IsDefault())\r\n               {\r\n                   break;\r\n               }\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    bool ConfigurationEnvironment::AreEqual(const Windows::Foundation::Collections::IMap<hstring, hstring>& a, const Windows::Foundation::Collections::IMap<hstring, hstring>& b)\r\n    {\r\n        uint32_t a_size = a ? a.Size() : 0;\r\n        uint32_t b_size = b ? b.Size() : 0;\r\n\r\n        if (a_size == 0 && b_size == 0)\r\n        {\r\n            return true;\r\n        }\r\n        else if (a_size != b_size)\r\n        {\r\n            return false;\r\n        }\r\n\r\n        for (const auto& entry : a)\r\n        {\r\n            hstring key = entry.Key();\r\n            if (!b.HasKey(key) || entry.Value() != b.Lookup(key))\r\n            {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        return true;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationEnvironment.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ConfigurationEnvironment.g.h\"\r\n#include <winrt/Windows.Foundation.Collections.h>\r\n#include <winget/ModuleCountBase.h>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    struct ConfigurationEnvironment : ConfigurationEnvironmentT<ConfigurationEnvironment>, AppInstaller::WinRT::ModuleCountBase\r\n    {\r\n        ConfigurationEnvironment();\r\n        ConfigurationEnvironment(SecurityContext context, const std::wstring& processorIdentifier, std::map<hstring, hstring>&& processorProperties);\r\n        ConfigurationEnvironment(const implementation::ConfigurationEnvironment& toDeepCopy);\r\n        ConfigurationEnvironment(const Configuration::ConfigurationEnvironment& toDeepCopy);\r\n\r\n        SecurityContext Context() const;\r\n        void Context(SecurityContext value);\r\n\r\n        hstring ProcessorIdentifier() const;\r\n        void ProcessorIdentifier(const hstring& value);\r\n\r\n        Windows::Foundation::Collections::IMap<hstring, hstring> ProcessorProperties() const;\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        // Copies the values from the given environment, including making a new map of the properties.\r\n        void DeepCopy(const implementation::ConfigurationEnvironment& toDeepCopy);\r\n\r\n        // Copies the properties from the given map.\r\n        void ProcessorProperties(const Windows::Foundation::Collections::IMap<hstring, hstring>& values);\r\n\r\n        // Copies the scalar properties from the given ValueSet.\r\n        // Ignores all values that cannot be converted to a string.\r\n        void ProcessorProperties(const Windows::Foundation::Collections::ValueSet& values);\r\n\r\n        // Determines if this environment represents the default environment.\r\n        bool IsDefault() const;\r\n\r\n        // Creates an environment, setting only fields that are identical between all given environments.\r\n        static com_ptr<ConfigurationEnvironment> CalculateCommonEnvironment(const std::vector<Configuration::ConfigurationEnvironment>& environments);\r\n\r\n        // Checks if the two given properties maps are equal.\r\n        static bool AreEqual(const Windows::Foundation::Collections::IMap<hstring, hstring>& a, const Windows::Foundation::Collections::IMap<hstring, hstring>& b);\r\n\r\n    private:\r\n        SecurityContext m_context = SecurityContext::Current;\r\n        hstring m_processorIdentifier;\r\n        Windows::Foundation::Collections::IMap<hstring, hstring> m_processorProperties;\r\n#endif\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationParameter.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigurationParameter.h\"\r\n#include \"ConfigurationParameter.g.cpp\"\r\n#include \"ArgumentValidation.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    hstring ConfigurationParameter::Name() const\r\n    {\r\n        return m_name;\r\n    }\r\n\r\n    void ConfigurationParameter::Name(hstring const& value)\r\n    {\r\n        m_name = value;\r\n    }\r\n\r\n    hstring ConfigurationParameter::Description() const\r\n    {\r\n        return m_description;\r\n    }\r\n\r\n    void ConfigurationParameter::Description(hstring const& value)\r\n    {\r\n        m_description = value;\r\n    }\r\n\r\n    Windows::Foundation::Collections::ValueSet ConfigurationParameter::Metadata() const\r\n    {\r\n        return m_metadata;\r\n    }\r\n\r\n    void ConfigurationParameter::Metadata(const Windows::Foundation::Collections::ValueSet& value)\r\n    {\r\n        THROW_HR_IF(E_POINTER, !value);\r\n        m_metadata = value;\r\n    }\r\n\r\n    bool ConfigurationParameter::IsSecure() const\r\n    {\r\n        return m_isSecure;\r\n    }\r\n\r\n    void ConfigurationParameter::IsSecure(bool value)\r\n    {\r\n        m_isSecure = value;\r\n    }\r\n\r\n    Windows::Foundation::PropertyType ConfigurationParameter::Type() const\r\n    {\r\n        return m_type;\r\n    }\r\n\r\n    void ConfigurationParameter::Type(Windows::Foundation::PropertyType value)\r\n    {\r\n        EnsureSupportedType(value);\r\n        m_type = value;\r\n    }\r\n\r\n    Windows::Foundation::IInspectable ConfigurationParameter::DefaultValue() const\r\n    {\r\n        return m_defaultValue;\r\n    }\r\n\r\n    void ConfigurationParameter::DefaultValue(Windows::Foundation::IInspectable const& value)\r\n    {\r\n        if (value)\r\n        {\r\n            EnsureObjectType(value, m_type);\r\n        }\r\n\r\n        m_defaultValue = value;\r\n    }\r\n\r\n    Windows::Foundation::Collections::IVector<Windows::Foundation::IInspectable> ConfigurationParameter::AllowedValues() const\r\n    {\r\n        return m_allowedValues;\r\n    }\r\n\r\n    void ConfigurationParameter::AllowedValues(Windows::Foundation::Collections::IVector<Windows::Foundation::IInspectable> const& value)\r\n    {\r\n        if (value)\r\n        {\r\n            for (const auto& item : value)\r\n            {\r\n                if (item)\r\n                {\r\n                    EnsureObjectType(item, m_type);\r\n                }\r\n            }\r\n        }\r\n\r\n        m_allowedValues = value;\r\n    }\r\n\r\n    void ConfigurationParameter::AllowedValues(std::vector<Windows::Foundation::IInspectable>&& value)\r\n    {\r\n        m_allowedValues = winrt::multi_threaded_vector<Windows::Foundation::IInspectable>(std::move(value));\r\n    }\r\n\r\n    uint32_t ConfigurationParameter::MinimumLength() const\r\n    {\r\n        return m_minimumLength;\r\n    }\r\n\r\n    void ConfigurationParameter::MinimumLength(uint32_t value)\r\n    {\r\n        EnsureLengthType(m_type);\r\n        m_minimumLength = value;\r\n    }\r\n\r\n    uint32_t ConfigurationParameter::MaximumLength() const\r\n    {\r\n        return m_maximumLength;\r\n    }\r\n\r\n    void ConfigurationParameter::MaximumLength(uint32_t value)\r\n    {\r\n        EnsureLengthType(m_type);\r\n        m_maximumLength = value;\r\n    }\r\n\r\n    Windows::Foundation::IInspectable ConfigurationParameter::MinimumValue() const\r\n    {\r\n        return m_minimumValue;\r\n    }\r\n\r\n    void ConfigurationParameter::MinimumValue(Windows::Foundation::IInspectable const& value)\r\n    {\r\n        if (value)\r\n        {\r\n            EnsureObjectType(value, m_type);\r\n            EnsureComparableType(m_type);\r\n        }\r\n\r\n        m_minimumValue = value;\r\n    }\r\n\r\n    Windows::Foundation::IInspectable ConfigurationParameter::MaximumValue() const\r\n    {\r\n        return m_maximumValue;\r\n    }\r\n\r\n    void ConfigurationParameter::MaximumValue(Windows::Foundation::IInspectable const& value)\r\n    {\r\n        if (value)\r\n        {\r\n            EnsureObjectType(value, m_type);\r\n            EnsureComparableType(m_type);\r\n        }\r\n\r\n        m_maximumValue = value;\r\n    }\r\n\r\n    Windows::Foundation::IInspectable ConfigurationParameter::ProvidedValue() const\r\n    {\r\n        return m_providedValue;\r\n    }\r\n\r\n    void ConfigurationParameter::ProvidedValue(Windows::Foundation::IInspectable const& value)\r\n    {\r\n        if (value)\r\n        {\r\n            EnsureObjectType(value, m_type);\r\n        }\r\n\r\n        m_providedValue = value;\r\n    }\r\n\r\n    HRESULT STDMETHODCALLTYPE ConfigurationParameter::SetLifetimeWatcher(IUnknown* watcher)\r\n    {\r\n        return AppInstaller::WinRT::LifetimeWatcherBase::SetLifetimeWatcher(watcher);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationParameter.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"ConfigurationParameter.g.h\"\n#include <winget/ILifetimeWatcher.h>\n#include <winrt/Windows.Foundation.h>\n#include <winrt/Windows.Foundation.Collections.h>\n#include <limits>\n\nnamespace winrt::Microsoft::Management::Configuration::implementation\n{\n    struct ConfigurationParameter : ConfigurationParameterT<ConfigurationParameter, winrt::cloaked<AppInstaller::WinRT::ILifetimeWatcher>>, AppInstaller::WinRT::LifetimeWatcherBase\n    {\n        ConfigurationParameter() = default;\n\n        hstring Name() const;\n        void Name(hstring const& value);\n\n        hstring Description() const;\n        void Description(hstring const& value);\n\n        Windows::Foundation::Collections::ValueSet Metadata() const;\n        void Metadata(const Windows::Foundation::Collections::ValueSet& value);\n\n        bool IsSecure() const;\n        void IsSecure(bool value);\n\n        Windows::Foundation::PropertyType Type() const;\n        void Type(Windows::Foundation::PropertyType value);\n\n        Windows::Foundation::IInspectable DefaultValue() const;\n        void DefaultValue(Windows::Foundation::IInspectable const& value);\n\n        Windows::Foundation::Collections::IVector<Windows::Foundation::IInspectable> AllowedValues() const;\n        void AllowedValues(Windows::Foundation::Collections::IVector<Windows::Foundation::IInspectable> const& value);\n\n        uint32_t MinimumLength() const;\n        void MinimumLength(uint32_t value);\n\n        uint32_t MaximumLength() const;\n        void MaximumLength(uint32_t value);\n\n        Windows::Foundation::IInspectable MinimumValue() const;\n        void MinimumValue(Windows::Foundation::IInspectable const& value);\n\n        Windows::Foundation::IInspectable MaximumValue() const;\n        void MaximumValue(Windows::Foundation::IInspectable const& value);\n\n        Windows::Foundation::IInspectable ProvidedValue() const;\n        void ProvidedValue(Windows::Foundation::IInspectable const& value);\n\n        HRESULT STDMETHODCALLTYPE SetLifetimeWatcher(IUnknown* watcher);\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void AllowedValues(std::vector<Windows::Foundation::IInspectable>&& value);\n\n    private:\n        hstring m_name;\n        hstring m_description;\n        Windows::Foundation::Collections::ValueSet m_metadata;\n        bool m_isSecure = false;\n        Windows::Foundation::PropertyType m_type = Windows::Foundation::PropertyType::Inspectable;\n        Windows::Foundation::IInspectable m_defaultValue;\n        Windows::Foundation::Collections::IVector<Windows::Foundation::IInspectable> m_allowedValues;\n        uint32_t m_minimumLength = 0;\n        uint32_t m_maximumLength = std::numeric_limits<uint32_t>::max();\n        Windows::Foundation::IInspectable m_minimumValue;\n        Windows::Foundation::IInspectable m_maximumValue;\n        Windows::Foundation::IInspectable m_providedValue;\n#endif\n    };\n}\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\nnamespace winrt::Microsoft::Management::Configuration::factory_implementation\n{\n    struct ConfigurationParameter : ConfigurationParameterT<ConfigurationParameter, implementation::ConfigurationParameter>\n    {\n    };\n}\n#endif\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationProcessor.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigurationProcessor.h\"\r\n#include \"ConfigurationProcessor.g.cpp\"\r\n#include \"ConfigurationSet.h\"\r\n#include \"OpenConfigurationSetResult.h\"\r\n#include \"ConfigurationSetParser.h\"\r\n#include \"DiagnosticInformationInstance.h\"\r\n#include \"ApplyConfigurationSetResult.h\"\r\n#include \"ApplyConfigurationUnitResult.h\"\r\n#include \"TestConfigurationSetResult.h\"\r\n#include \"TestConfigurationUnitResult.h\"\r\n#include \"ConfigurationUnitResultInformation.h\"\r\n#include \"GetConfigurationUnitSettingsResult.h\"\r\n#include \"GetAllConfigurationUnitSettingsResult.h\"\r\n#include \"GetAllConfigurationUnitsResult.h\"\r\n#include \"ExceptionResultHelpers.h\"\r\n#include \"ConfigurationSetChangeData.h\"\r\n#include \"GetConfigurationUnitDetailsResult.h\"\r\n#include \"GetConfigurationSetDetailsResult.h\"\r\n#include \"DefaultSetGroupProcessor.h\"\r\n#include \"ConfigurationSequencer.h\"\r\n#include \"ConfigurationStatus.h\"\r\n\r\n#include <AppInstallerErrors.h>\r\n#include <AppInstallerStrings.h>\r\n#include <AppInstallerSHA256.h>\r\n#include <winget/GroupPolicy.h>\r\n\r\nusing namespace std::chrono_literals;\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    namespace\r\n    {\r\n        AppInstaller::Logging::Level ConvertLevel(DiagnosticLevel level)\r\n        {\r\n            switch (level)\r\n            {\r\n            case DiagnosticLevel::Verbose: return AppInstaller::Logging::Level::Verbose;\r\n            case DiagnosticLevel::Informational: return AppInstaller::Logging::Level::Info;\r\n            case DiagnosticLevel::Warning: return AppInstaller::Logging::Level::Warning;\r\n            case DiagnosticLevel::Error: return AppInstaller::Logging::Level::Error;\r\n            case DiagnosticLevel::Critical: return AppInstaller::Logging::Level::Crit;\r\n            default: return AppInstaller::Logging::Level::Warning;\r\n            }\r\n        }\r\n\r\n        DiagnosticLevel ConvertLevel(AppInstaller::Logging::Level level)\r\n        {\r\n            switch (level)\r\n            {\r\n            case AppInstaller::Logging::Level::Verbose: return DiagnosticLevel::Verbose;\r\n            case AppInstaller::Logging::Level::Info: return DiagnosticLevel::Informational;\r\n            case AppInstaller::Logging::Level::Warning: return DiagnosticLevel::Warning;\r\n            case AppInstaller::Logging::Level::Error: return DiagnosticLevel::Error;\r\n            case AppInstaller::Logging::Level::Crit: return DiagnosticLevel::Critical;\r\n            default: return DiagnosticLevel::Warning;\r\n            }\r\n        }\r\n\r\n        // ILogger that sends data back to the Diagnostics event of the ConfigurationProcessor.\r\n        struct ConfigurationProcessorDiagnosticsLogger : public AppInstaller::Logging::ILogger\r\n        {\r\n            ConfigurationProcessorDiagnosticsLogger(ConfigurationProcessor& processor) : m_processor(processor) {}\r\n\r\n            std::string GetName() const override\r\n            {\r\n                return \"ConfigurationProcessorDiagnosticsLogger\";\r\n            }\r\n\r\n            void Write(AppInstaller::Logging::Channel channel, AppInstaller::Logging::Level level, std::string_view message) noexcept override try\r\n            {\r\n                std::ostringstream strstr;\r\n                strstr << '[' << AppInstaller::Logging::GetChannelName(channel) << \"] \" << message;\r\n                m_processor.SendDiagnostics(ConvertLevel(level), strstr.str());\r\n            }\r\n            catch (...) {}\r\n\r\n            void WriteDirect(AppInstaller::Logging::Channel, AppInstaller::Logging::Level level, std::string_view message) noexcept override try\r\n            {\r\n                m_processor.SendDiagnostics(ConvertLevel(level), message);\r\n            }\r\n            catch (...) {}\r\n\r\n        private:\r\n            ConfigurationProcessor& m_processor;\r\n        };\r\n\r\n        // Helper to ensure a one-time callback attach\r\n        struct AttachWilFailureCallback\r\n        {\r\n            AttachWilFailureCallback()\r\n            {\r\n                wil::SetResultLoggingCallback(wilResultLoggingCallback);\r\n            }\r\n\r\n            ~AttachWilFailureCallback() = default;\r\n\r\n            static void __stdcall wilResultLoggingCallback(const wil::FailureInfo& info) noexcept\r\n            {\r\n                AICLI_LOG(Fail, Error, << [&]() {\r\n                    wchar_t message[2048];\r\n                    GetFailureLogString(message, ARRAYSIZE(message), info);\r\n                    return AppInstaller::Utility::ConvertToUTF8(message);\r\n                    }());\r\n            }\r\n\r\n            static void Ensure()\r\n            {\r\n                static AttachWilFailureCallback s_callbackAttach;\r\n            }\r\n        };\r\n    }\r\n\r\n    ConfigurationProcessor::ConfigurationProcessor()\r\n    {\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY, !::AppInstaller::Settings::GroupPolicies().IsEnabled(::AppInstaller::Settings::TogglePolicy::Policy::WinGet));\r\n        THROW_HR_IF(APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY, !::AppInstaller::Settings::GroupPolicies().IsEnabled(::AppInstaller::Settings::TogglePolicy::Policy::Configuration));\r\n\r\n        AppInstaller::Logging::DiagnosticLogger& logger = m_threadGlobals.GetDiagnosticLogger();\r\n        logger.SetEnabledChannels(AppInstaller::Logging::Channel::All);\r\n        logger.SetLevel(AppInstaller::Logging::Level::Verbose);\r\n        logger.AddLogger(std::make_unique<ConfigurationProcessorDiagnosticsLogger>(*this));\r\n    }\r\n\r\n    ConfigurationProcessor::ConfigurationProcessor(const IConfigurationSetProcessorFactory& factory) : ConfigurationProcessor()\r\n    {\r\n        ConfigurationSetProcessorFactory(factory);\r\n    }\r\n\r\n    event_token ConfigurationProcessor::Diagnostics(const Windows::Foundation::EventHandler<IDiagnosticInformation>& handler)\r\n    {\r\n        AttachWilFailureCallback::Ensure();\r\n        return m_diagnostics.add(handler);\r\n    }\r\n\r\n    void ConfigurationProcessor::Diagnostics(const event_token& token) noexcept\r\n    {\r\n        m_diagnostics.remove(token);\r\n    }\r\n\r\n    DiagnosticLevel ConfigurationProcessor::MinimumLevel()\r\n    {\r\n        return m_minimumLevel;\r\n    }\r\n\r\n    void ConfigurationProcessor::MinimumLevel(DiagnosticLevel value)\r\n    {\r\n        m_minimumLevel = value;\r\n        m_threadGlobals.GetDiagnosticLogger().SetLevel(ConvertLevel(value));\r\n        if (m_factory)\r\n        {\r\n            m_factory.MinimumLevel(value);\r\n        }\r\n    }\r\n\r\n    hstring ConfigurationProcessor::Caller() const\r\n    {\r\n        return hstring{ AppInstaller::Utility::ConvertToUTF16(m_threadGlobals.GetTelemetryLogger().GetCaller()) };\r\n    }\r\n\r\n    void ConfigurationProcessor::Caller(hstring value)\r\n    {\r\n        m_threadGlobals.GetTelemetryLogger().SetCaller(AppInstaller::Utility::ConvertToUTF8(value));\r\n    }\r\n\r\n    guid ConfigurationProcessor::ActivityIdentifier()\r\n    {\r\n        return *m_threadGlobals.GetTelemetryLogger().GetActivityId();\r\n    }\r\n\r\n    void ConfigurationProcessor::ActivityIdentifier(const guid& value)\r\n    {\r\n        m_threadGlobals.GetTelemetryLogger().SetActivityId(value);\r\n    }\r\n\r\n    bool ConfigurationProcessor::GenerateTelemetryEvents()\r\n    {\r\n        return m_threadGlobals.GetTelemetryLogger().IsEnabled();\r\n    }\r\n\r\n    void ConfigurationProcessor::GenerateTelemetryEvents(bool value)\r\n    {\r\n        std::ignore = m_threadGlobals.GetTelemetryLogger().EnableRuntime(value);\r\n    }\r\n\r\n    event_token ConfigurationProcessor::ConfigurationChange(const Windows::Foundation::TypedEventHandler<Configuration::ConfigurationSet, Configuration::ConfigurationChangeData>& handler)\r\n    {\r\n        if (!m_configurationChange)\r\n        {\r\n            auto status = ConfigurationStatus::Instance();\r\n            std::atomic_store(&m_changeRegistration, status->RegisterForChange(*this));\r\n        }\r\n\r\n        return m_configurationChange.add(handler);\r\n    }\r\n\r\n    void ConfigurationProcessor::ConfigurationChange(const event_token& token) noexcept\r\n    {\r\n        m_configurationChange.remove(token);\r\n\r\n        if (!m_configurationChange)\r\n        {\r\n            std::atomic_store(&m_changeRegistration, {});\r\n        }\r\n    }\r\n\r\n    void ConfigurationProcessor::ConfigurationChange(const Configuration::ConfigurationSet& set, const Configuration::ConfigurationChangeData& data) try\r\n    {\r\n        m_configurationChange(set, data);\r\n    }\r\n    CATCH_LOG();\r\n\r\n    Windows::Foundation::Collections::IVector<Configuration::ConfigurationSet> ConfigurationProcessor::GetConfigurationHistory()\r\n    {\r\n        return GetConfigurationHistoryImpl();\r\n    }\r\n\r\n    Windows::Foundation::IAsyncOperation<Windows::Foundation::Collections::IVector<Configuration::ConfigurationSet>> ConfigurationProcessor::GetConfigurationHistoryAsync()\r\n    {\r\n        auto strong_this{ get_strong() };\r\n        co_await winrt::resume_background();\r\n        co_return GetConfigurationHistoryImpl({ co_await winrt::get_cancellation_token() });\r\n    }\r\n\r\n    Configuration::OpenConfigurationSetResult ConfigurationProcessor::OpenConfigurationSet(const Windows::Storage::Streams::IInputStream& stream)\r\n    {\r\n        return OpenConfigurationSetAsync(stream).get();\r\n    }\r\n\r\n    Windows::Foundation::IAsyncOperation<Configuration::OpenConfigurationSetResult> ConfigurationProcessor::OpenConfigurationSetAsync(const Windows::Storage::Streams::IInputStream& stream)\r\n    {\r\n        auto strong_this{ get_strong() };\r\n        Windows::Storage::Streams::IInputStream localStream = stream;\r\n\r\n        co_await winrt::resume_background();\r\n        auto cancellation = co_await winrt::get_cancellation_token();\r\n\r\n        auto threadGlobals = m_threadGlobals.SetForCurrentThread();\r\n        auto result = make_self<wil::details::module_count_wrapper<OpenConfigurationSetResult>>();\r\n\r\n        if (!localStream)\r\n        {\r\n            result->Initialize(E_POINTER, {});\r\n            co_return *result;\r\n        }\r\n\r\n        try\r\n        {\r\n            // Read the entire file into memory as we expect them to be small and\r\n            // our YAML parser doesn't support streaming at this time.\r\n            // This is done here to enable easy cancellation propagation to the stream reads.\r\n            uint32_t bufferSize = 1 << 20;\r\n            Windows::Storage::Streams::Buffer buffer(bufferSize);\r\n\r\n            // Memory stream in mixed elevation does not support InputStreamOptions as flags.\r\n            Windows::Storage::Streams::InputStreamOptions readOptions = Windows::Storage::Streams::InputStreamOptions::Partial;\r\n            std::string inputString;\r\n\r\n            for (;;)\r\n            {\r\n                auto asyncOperation = localStream.ReadAsync(buffer, bufferSize, readOptions);\r\n\r\n                // Manually poll status and propagate cancellation to stay on this thread for thread globals\r\n                while (asyncOperation.Status() == Windows::Foundation::AsyncStatus::Started)\r\n                {\r\n                    if (cancellation())\r\n                    {\r\n                        asyncOperation.Cancel();\r\n                    }\r\n\r\n                    std::this_thread::sleep_for(100ms);\r\n                }\r\n\r\n                Windows::Storage::Streams::IBuffer readBuffer = asyncOperation.GetResults();\r\n\r\n                size_t readSize = static_cast<size_t>(readBuffer.Length());\r\n                if (readSize)\r\n                {\r\n                    static_assert(sizeof(char) == sizeof(*readBuffer.data()));\r\n                    inputString.append(reinterpret_cast<char*>(readBuffer.data()), readSize);\r\n                }\r\n                else\r\n                {\r\n                    break;\r\n                }\r\n            }\r\n\r\n            std::unique_ptr<ConfigurationSetParser> parser = ConfigurationSetParser::Create(inputString);\r\n\r\n            if (FAILED(parser->Result()))\r\n            {\r\n                result->Initialize(parser->Result(), parser->Field(), parser->Value(), parser->Line(), parser->Column());\r\n                co_return *result;\r\n            }\r\n\r\n            parser->Parse();\r\n            if (FAILED(parser->Result()))\r\n            {\r\n                result->Initialize(parser->Result(), parser->Field(), parser->Value(), parser->Line(), parser->Column());\r\n                co_return *result;\r\n            }\r\n\r\n            auto configurationSet = parser->GetConfigurationSet();\r\n            PropagateLifetimeWatcher(configurationSet.as<Windows::Foundation::IUnknown>());\r\n            configurationSet->SetInputHash(AppInstaller::Utility::SHA256::ConvertToString(AppInstaller::Utility::SHA256::ComputeHash(inputString)));\r\n\r\n            result->Initialize(*configurationSet);\r\n        }\r\n        catch (const wil::ResultException& resultException)\r\n        {\r\n            result->Initialize(resultException.GetErrorCode());\r\n        }\r\n        catch (...)\r\n        {\r\n            result->Initialize(WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE);\r\n            LOG_CAUGHT_EXCEPTION();\r\n        }\r\n\r\n        co_return *result;\r\n    }\r\n\r\n    Windows::Foundation::Collections::IVector<ConfigurationConflict> ConfigurationProcessor::CheckForConflicts(\r\n        const Windows::Foundation::Collections::IVectorView<Configuration::ConfigurationSet>& configurationSets,\r\n        bool includeConfigurationHistory)\r\n    {\r\n        UNREFERENCED_PARAMETER(configurationSets);\r\n        UNREFERENCED_PARAMETER(includeConfigurationHistory);\r\n        THROW_HR(E_NOTIMPL);\r\n    }\r\n\r\n    Windows::Foundation::IAsyncOperation<Windows::Foundation::Collections::IVector<ConfigurationConflict>> ConfigurationProcessor::CheckForConflictsAsync(\r\n        const Windows::Foundation::Collections::IVectorView<Configuration::ConfigurationSet>& configurationSets,\r\n        bool includeConfigurationHistory)\r\n    {\r\n        co_return CheckForConflicts(configurationSets, includeConfigurationHistory);\r\n    }\r\n\r\n    Configuration::GetConfigurationSetDetailsResult ConfigurationProcessor::GetSetDetails(const Configuration::ConfigurationSet& configurationSet, ConfigurationUnitDetailFlags detailFlags)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !m_factory);\r\n        return GetSetDetailsImpl(configurationSet, detailFlags);\r\n    }\r\n\r\n    Windows::Foundation::IAsyncOperationWithProgress<Configuration::GetConfigurationSetDetailsResult, Configuration::GetConfigurationUnitDetailsResult> ConfigurationProcessor::GetSetDetailsAsync(\r\n        const Configuration::ConfigurationSet& configurationSet,\r\n        ConfigurationUnitDetailFlags detailFlags)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !m_factory);\r\n\r\n        auto strong_this{ get_strong() };\r\n        Configuration::ConfigurationSet localSet = configurationSet;\r\n\r\n        co_await winrt::resume_background();\r\n\r\n        co_return GetSetDetailsImpl(localSet, detailFlags, { co_await winrt::get_progress_token(), co_await winrt::get_cancellation_token()});\r\n    }\r\n\r\n    Windows::Foundation::Collections::IVector<Configuration::ConfigurationSet> ConfigurationProcessor::GetConfigurationHistoryImpl(ShutdownAwareAsyncCancellation cancellation)\r\n    {\r\n        auto threadGlobals = m_threadGlobals.SetForCurrentThread();\r\n\r\n        m_database.EnsureOpened(false);\r\n        cancellation.ThrowIfCancelled();\r\n\r\n        std::vector<Configuration::ConfigurationSet> result;\r\n        for (const auto& set : m_database.GetSetHistory())\r\n        {\r\n            PropagateLifetimeWatcher(*set);\r\n            result.emplace_back(*set);\r\n        }\r\n\r\n        return multi_threaded_vector(std::move(result));\r\n    }\r\n\r\n    Configuration::GetConfigurationSetDetailsResult ConfigurationProcessor::GetSetDetailsImpl(\r\n        const Configuration::ConfigurationSet& configurationSet,\r\n        ConfigurationUnitDetailFlags detailFlags,\r\n        ShutdownAwareAsyncProgress<GetConfigurationSetDetailsResult, GetConfigurationUnitDetailsResult> progress)\r\n    {\r\n        auto threadGlobals = m_threadGlobals.SetForCurrentThread();\r\n\r\n        IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(configurationSet);\r\n\r\n        auto result = make_self<wil::details::module_count_wrapper<implementation::GetConfigurationSetDetailsResult>>();\r\n        progress.Result(*result);\r\n\r\n        for (const auto& unit : configurationSet.Units())\r\n        {\r\n            progress.ThrowIfCancelled();\r\n\r\n            auto unitResult = make_self<wil::details::module_count_wrapper<implementation::GetConfigurationUnitDetailsResult>>();\r\n            auto unitResultInformation = make_self<wil::details::module_count_wrapper<implementation::ConfigurationUnitResultInformation>>();\r\n            unitResult->Unit(unit);\r\n            unitResult->ResultInformation(*unitResultInformation);\r\n\r\n            try\r\n            {\r\n                IConfigurationUnitProcessorDetails details = setProcessor.GetUnitProcessorDetails(unit, detailFlags);\r\n                unitResult->Details(details);\r\n                get_self<implementation::ConfigurationUnit>(unit)->Details(std::move(details));\r\n            }\r\n            catch (...)\r\n            {\r\n                ExtractUnitResultInformation(std::current_exception(), unitResultInformation);\r\n            }\r\n\r\n            result->UnitResultsVector().Append(*unitResult);\r\n            progress.Progress(*unitResult);\r\n        }\r\n\r\n        return *result;\r\n    }\r\n\r\n    Configuration::GetConfigurationUnitDetailsResult ConfigurationProcessor::GetUnitDetails(const ConfigurationUnit& unit, ConfigurationUnitDetailFlags detailFlags)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !m_factory);\r\n        return GetUnitDetailsImpl(unit, detailFlags);\r\n    }\r\n\r\n    Windows::Foundation::IAsyncOperation<Configuration::GetConfigurationUnitDetailsResult> ConfigurationProcessor::GetUnitDetailsAsync(const ConfigurationUnit& unit, ConfigurationUnitDetailFlags detailFlags)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !m_factory);\r\n\r\n        auto strong_this{ get_strong() };\r\n        ConfigurationUnit localUnit = unit;\r\n\r\n        co_await winrt::resume_background();\r\n\r\n        co_return GetUnitDetailsImpl(localUnit, detailFlags);\r\n    }\r\n\r\n    Configuration::GetConfigurationUnitDetailsResult ConfigurationProcessor::GetUnitDetailsImpl(const ConfigurationUnit& unit, ConfigurationUnitDetailFlags detailFlags)\r\n    {\r\n        auto threadGlobals = m_threadGlobals.SetForCurrentThread();\r\n\r\n        IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(nullptr);\r\n\r\n        auto unitResult = make_self<wil::details::module_count_wrapper<implementation::GetConfigurationUnitDetailsResult>>();\r\n        auto unitResultInformation = make_self<wil::details::module_count_wrapper<implementation::ConfigurationUnitResultInformation>>();\r\n        unitResult->Unit(unit);\r\n        unitResult->ResultInformation(*unitResultInformation);\r\n\r\n        try\r\n        {\r\n            IConfigurationUnitProcessorDetails details = setProcessor.GetUnitProcessorDetails(unit, detailFlags);\r\n            unitResult->Details(details);\r\n            get_self<implementation::ConfigurationUnit>(unit)->Details(std::move(details));\r\n        }\r\n        catch (...)\r\n        {\r\n            ExtractUnitResultInformation(std::current_exception(), unitResultInformation);\r\n        }\r\n\r\n        return *unitResult;\r\n    }\r\n\r\n    Configuration::ApplyConfigurationSetResult ConfigurationProcessor::ApplySet(const Configuration::ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !m_factory);\r\n        return ApplySetImpl(configurationSet, flags);\r\n    }\r\n\r\n    Windows::Foundation::IAsyncOperationWithProgress<Configuration::ApplyConfigurationSetResult, Configuration::ConfigurationSetChangeData> ConfigurationProcessor::ApplySetAsync(\r\n        const Configuration::ConfigurationSet& configurationSet,\r\n        ApplyConfigurationSetFlags flags)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !m_factory);\r\n\r\n        auto strong_this{ get_strong() };\r\n        Configuration::ConfigurationSet localSet = configurationSet;\r\n\r\n        co_await winrt::resume_background();\r\n\r\n        co_return ApplySetImpl(localSet, flags, { co_await winrt::get_progress_token(), co_await winrt::get_cancellation_token() });\r\n    }\r\n\r\n    Configuration::ApplyConfigurationSetResult ConfigurationProcessor::ApplySetImpl(\r\n        const Configuration::ConfigurationSet& configurationSet,\r\n        ApplyConfigurationSetFlags flags,\r\n        ShutdownAwareAsyncProgress<ApplyConfigurationSetResult, ConfigurationSetChangeData> progress)\r\n    {\r\n        auto threadGlobals = m_threadGlobals.SetForCurrentThread();\r\n\r\n        IConfigurationGroupProcessor groupProcessor;\r\n        bool recordHistoryAndStatus = false;\r\n\r\n        if (WI_IsFlagSet(flags, ApplyConfigurationSetFlags::PerformConsistencyCheckOnly))\r\n        {\r\n            // If performing a consistency check, always use the default processor and let it know as well\r\n            auto defaultGroupProcessor = make_self<wil::details::module_count_wrapper<implementation::DefaultSetGroupProcessor>>();\r\n            defaultGroupProcessor->Initialize(configurationSet, nullptr, m_threadGlobals, true);\r\n            groupProcessor = *defaultGroupProcessor;\r\n        }\r\n        else\r\n        {\r\n            groupProcessor = GetSetGroupProcessor(configurationSet);\r\n\r\n            // Write this set to the database history\r\n            // This is a somewhat arbitrary time to write it, but it should not be done if PerformConsistencyCheckOnly is passed, so this is convenient.\r\n            recordHistoryAndStatus = true;\r\n            m_database.EnsureOpened();\r\n            progress.ThrowIfCancelled();\r\n            m_database.WriteSetHistory(configurationSet, WI_IsFlagSet(flags, ApplyConfigurationSetFlags::DoNotOverwriteMatchingOriginSet));\r\n        }\r\n\r\n        auto result = make_self<wil::details::module_count_wrapper<implementation::ApplyConfigurationSetResult>>();\r\n\r\n        // Build out the unit results and a map to find them quickly\r\n        using UnitResultType = decltype(make_self<wil::details::module_count_wrapper<implementation::ApplyConfigurationUnitResult>>());\r\n        std::map<guid, UnitResultType> unitResultMap;\r\n\r\n        std::function<void(const winrt::Windows::Foundation::Collections::IVector<Configuration::ConfigurationUnit>&)> createUnitResults =\r\n            [&](const winrt::Windows::Foundation::Collections::IVector<Configuration::ConfigurationUnit>& units)\r\n            {\r\n                for (const Configuration::ConfigurationUnit& unit : units)\r\n                {\r\n                    // Add to result\r\n                    UnitResultType applyUnitResult = make_self<wil::details::module_count_wrapper<implementation::ApplyConfigurationUnitResult>>();\r\n                    applyUnitResult->Unit(unit);\r\n                    result->UnitResultsVector().Append(*applyUnitResult);\r\n\r\n                    // Add to map\r\n                    unitResultMap.emplace(unit.InstanceIdentifier(), applyUnitResult);\r\n\r\n                    // Handle members if present\r\n                    if (unit.IsGroup())\r\n                    {\r\n                        createUnitResults(unit.Units());\r\n                    }\r\n                }\r\n            };\r\n\r\n        createUnitResults(configurationSet.Units());\r\n\r\n        progress.Result(*result);\r\n\r\n        try\r\n        {\r\n            ConfigurationSequencer sequencer{ m_database };\r\n            auto status = ConfigurationStatus::Instance();\r\n            guid setInstanceIdentifier = configurationSet.InstanceIdentifier();\r\n            auto updateState = [&](ConfigurationSetState state)\r\n                {\r\n                    try\r\n                    {\r\n                        progress.Progress(implementation::ConfigurationSetChangeData::Create(state));\r\n                    }\r\n                    CATCH_LOG();\r\n\r\n                    if (recordHistoryAndStatus)\r\n                    {\r\n                        status->UpdateSetState(setInstanceIdentifier, state);\r\n                    }\r\n                };\r\n\r\n            if (!WI_IsFlagSet(flags, ApplyConfigurationSetFlags::PerformConsistencyCheckOnly))\r\n            {\r\n                if (sequencer.Enqueue(configurationSet))\r\n                {\r\n                    updateState(ConfigurationSetState::Pending);\r\n                    sequencer.Wait(progress.GetCancellation());\r\n                }\r\n            }\r\n\r\n            progress.ThrowIfCancelled();\r\n\r\n            updateState(ConfigurationSetState::InProgress);\r\n\r\n            // Forward unit result progress to caller\r\n            auto applyOperation = groupProcessor.ApplyGroupSettingsAsync([&](const auto&, const IApplyGroupMemberSettingsResult& unitResult)\r\n                {\r\n                    auto itr = unitResultMap.find(unitResult.Unit().InstanceIdentifier());\r\n                    if (itr != unitResultMap.end())\r\n                    {\r\n                        itr->second->Initialize(unitResult);\r\n                    }\r\n\r\n                    // Create progress object\r\n                    auto applyResult = make_self<implementation::ConfigurationSetChangeData>();\r\n                    applyResult->Initialize(unitResult);\r\n                    progress.Progress(*applyResult);\r\n\r\n                    if (recordHistoryAndStatus)\r\n                    {\r\n                        status->UpdateUnitState(setInstanceIdentifier, applyResult);\r\n                    }\r\n                });\r\n\r\n            // Cancel the inner operation if we are cancelled\r\n            progress.Callback([applyOperation]() { applyOperation.Cancel(); });\r\n\r\n            IApplyGroupSettingsResult applyResult = applyOperation.get();\r\n\r\n            // Place all results from the processor into our result\r\n            if (applyResult.ResultInformation())\r\n            {\r\n                result->ResultCode(applyResult.ResultInformation().ResultCode());\r\n            }\r\n\r\n            for (const IApplyGroupMemberSettingsResult& unitResult : applyResult.UnitResults())\r\n            {\r\n                // Update overall result\r\n                auto itr = unitResultMap.find(unitResult.Unit().InstanceIdentifier());\r\n                if (itr == unitResultMap.end())\r\n                {\r\n                    continue;\r\n                }\r\n\r\n                itr->second->Initialize(unitResult);\r\n\r\n                m_threadGlobals.GetTelemetryLogger().LogConfigUnitRunIfAppropriate(\r\n                    configurationSet.InstanceIdentifier(),\r\n                    itr->second->Unit(),\r\n                    ConfigurationUnitIntent::Apply,\r\n                    TelemetryTraceLogger::ApplyAction,\r\n                    itr->second->ResultInformation());\r\n            }\r\n\r\n            updateState(ConfigurationSetState::Completed);\r\n\r\n            m_threadGlobals.GetTelemetryLogger().LogConfigProcessingSummaryForApply(*winrt::get_self<implementation::ConfigurationSet>(configurationSet), *result);\r\n            return *result;\r\n        }\r\n        catch (...)\r\n        {\r\n            m_threadGlobals.GetTelemetryLogger().LogConfigProcessingSummaryForApplyException(\r\n                *winrt::get_self<implementation::ConfigurationSet>(configurationSet),\r\n                LOG_CAUGHT_EXCEPTION(),\r\n                *result);\r\n            throw;\r\n        }\r\n    }\r\n\r\n    Configuration::TestConfigurationSetResult ConfigurationProcessor::TestSet(const Configuration::ConfigurationSet& configurationSet)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !m_factory);\r\n        return TestSetImpl(configurationSet);\r\n    }\r\n\r\n    Windows::Foundation::IAsyncOperationWithProgress<Configuration::TestConfigurationSetResult, Configuration::TestConfigurationUnitResult> ConfigurationProcessor::TestSetAsync(const Configuration::ConfigurationSet& configurationSet)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !m_factory);\r\n\r\n        auto strong_this{ get_strong() };\r\n        Configuration::ConfigurationSet localSet = configurationSet;\r\n\r\n        co_await winrt::resume_background();\r\n\r\n        co_return TestSetImpl(localSet, { co_await winrt::get_progress_token(), co_await winrt::get_cancellation_token() });\r\n    }\r\n\r\n    Configuration::TestConfigurationSetResult ConfigurationProcessor::TestSetImpl(\r\n        const Configuration::ConfigurationSet& configurationSet,\r\n        ShutdownAwareAsyncProgress<TestConfigurationSetResult, TestConfigurationUnitResult> progress)\r\n    {\r\n        auto threadGlobals = m_threadGlobals.SetForCurrentThread();\r\n\r\n        IConfigurationGroupProcessor groupProcessor = GetSetGroupProcessor(configurationSet);\r\n        auto result = make_self<wil::details::module_count_wrapper<implementation::TestConfigurationSetResult>>();\r\n        result->TestResult(ConfigurationTestResult::NotRun);\r\n        progress.Result(*result);\r\n\r\n        try\r\n        {\r\n            // Forward unit result progress to caller\r\n            auto testOperation = groupProcessor.TestGroupSettingsAsync([&](const auto&, const ITestSettingsResult& unitResult)\r\n                {\r\n                    auto testResult = make_self<wil::details::module_count_wrapper<implementation::TestConfigurationUnitResult>>();\r\n                    testResult->Initialize(unitResult);\r\n\r\n                    result->AppendUnitResult(*testResult);\r\n                    progress.Progress(*testResult);\r\n                });\r\n\r\n            // Cancel the inner operation if we are cancelled\r\n            progress.Callback([testOperation]() { testOperation.Cancel(); });\r\n\r\n            ITestGroupSettingsResult testResult = testOperation.get();\r\n\r\n            // Send telemetry for all results\r\n            for (const ITestSettingsResult& unitResult : testResult.UnitResults())\r\n            {\r\n                auto testUnitResult = make_self<wil::details::module_count_wrapper<implementation::TestConfigurationUnitResult>>();\r\n                testUnitResult->Initialize(unitResult);\r\n\r\n                m_threadGlobals.GetTelemetryLogger().LogConfigUnitRunIfAppropriate(\r\n                    configurationSet.InstanceIdentifier(),\r\n                    testUnitResult->Unit(),\r\n                    ConfigurationUnitIntent::Assert,\r\n                    TelemetryTraceLogger::TestAction,\r\n                    testUnitResult->ResultInformation());\r\n            }\r\n\r\n            m_threadGlobals.GetTelemetryLogger().LogConfigProcessingSummaryForTest(*winrt::get_self<implementation::ConfigurationSet>(configurationSet), *result);\r\n            return *result;\r\n        }\r\n        catch (...)\r\n        {\r\n            m_threadGlobals.GetTelemetryLogger().LogConfigProcessingSummaryForTestException(\r\n                *winrt::get_self<implementation::ConfigurationSet>(configurationSet),\r\n                LOG_CAUGHT_EXCEPTION(),\r\n                *result);\r\n            throw;\r\n        }\r\n    }\r\n\r\n    Configuration::GetConfigurationUnitSettingsResult ConfigurationProcessor::GetUnitSettings(const ConfigurationUnit& unit)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !m_factory);\r\n        return GetUnitSettingsImpl(unit);\r\n    }\r\n\r\n    Windows::Foundation::IAsyncOperation<Configuration::GetConfigurationUnitSettingsResult> ConfigurationProcessor::GetUnitSettingsAsync(const ConfigurationUnit& unit)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !m_factory);\r\n\r\n        auto strong_this{ get_strong() };\r\n        ConfigurationUnit localUnit = unit;\r\n\r\n        co_await winrt::resume_background();\r\n\r\n        co_return GetUnitSettingsImpl(localUnit, { co_await winrt::get_cancellation_token() });\r\n    }\r\n\r\n    Configuration::GetConfigurationUnitSettingsResult ConfigurationProcessor::GetUnitSettingsImpl(\r\n        const ConfigurationUnit& unit,\r\n        ShutdownAwareAsyncCancellation cancellation)\r\n    {\r\n        auto threadGlobals = m_threadGlobals.SetForCurrentThread();\r\n\r\n        IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(nullptr);\r\n        auto result = make_self<wil::details::module_count_wrapper<implementation::GetConfigurationUnitSettingsResult>>();\r\n        auto unitResult = make_self<wil::details::module_count_wrapper<implementation::ConfigurationUnitResultInformation>>();\r\n        result->ResultInformation(*unitResult);\r\n\r\n        cancellation.ThrowIfCancelled();\r\n\r\n        IConfigurationUnitProcessor unitProcessor;\r\n\r\n        try\r\n        {\r\n            unitProcessor = setProcessor.CreateUnitProcessor(unit);\r\n        }\r\n        catch (...)\r\n        {\r\n            ExtractUnitResultInformation(std::current_exception(), unitResult);\r\n        }\r\n\r\n        cancellation.ThrowIfCancelled();\r\n\r\n        if (unitProcessor)\r\n        {\r\n            try\r\n            {\r\n                IGetSettingsResult settingsResult = unitProcessor.GetSettings();\r\n                result->Settings(settingsResult.Settings());\r\n                result->ResultInformation(settingsResult.ResultInformation());\r\n            }\r\n            catch (...)\r\n            {\r\n                ExtractUnitResultInformation(std::current_exception(), unitResult);\r\n            }\r\n\r\n            m_threadGlobals.GetTelemetryLogger().LogConfigUnitRunIfAppropriate(GUID_NULL, unit, ConfigurationUnitIntent::Inform, TelemetryTraceLogger::GetAction, result->ResultInformation());\r\n        }\r\n\r\n        return *result;\r\n    }\r\n\r\n    Configuration::GetAllConfigurationUnitSettingsResult ConfigurationProcessor::GetAllUnitSettings(const ConfigurationUnit& unit)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !m_factory);\r\n        return GetAllUnitSettingsImpl(unit);\r\n    }\r\n\r\n    Windows::Foundation::IAsyncOperation<Configuration::GetAllConfigurationUnitSettingsResult> ConfigurationProcessor::GetAllUnitSettingsAsync(const ConfigurationUnit& unit)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !m_factory);\r\n\r\n        auto strong_this{ get_strong() };\r\n        ConfigurationUnit localUnit = unit;\r\n\r\n        co_await winrt::resume_background();\r\n\r\n        co_return GetAllUnitSettingsImpl(localUnit, { co_await winrt::get_cancellation_token() });\r\n    }\r\n\r\n    Configuration::GetAllConfigurationUnitSettingsResult ConfigurationProcessor::GetAllUnitSettingsImpl(\r\n        const ConfigurationUnit& unit,\r\n        ShutdownAwareAsyncCancellation cancellation)\r\n    {\r\n        auto threadGlobals = m_threadGlobals.SetForCurrentThread();\r\n\r\n        IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(nullptr);\r\n        auto result = make_self<wil::details::module_count_wrapper<implementation::GetAllConfigurationUnitSettingsResult>>();\r\n        auto unitResult = make_self<wil::details::module_count_wrapper<implementation::ConfigurationUnitResultInformation>>();\r\n        result->ResultInformation(*unitResult);\r\n\r\n        cancellation.ThrowIfCancelled();\r\n\r\n        IConfigurationUnitProcessor unitProcessor;\r\n\r\n        try\r\n        {\r\n            unitProcessor = setProcessor.CreateUnitProcessor(unit);\r\n        }\r\n        catch (...)\r\n        {\r\n            ExtractUnitResultInformation(std::current_exception(), unitResult);\r\n        }\r\n\r\n        cancellation.ThrowIfCancelled();\r\n\r\n        IGetAllSettingsConfigurationUnitProcessor getAllSettingsUnitProcessor;\r\n        if (unitProcessor.try_as<IGetAllSettingsConfigurationUnitProcessor>(getAllSettingsUnitProcessor))\r\n        {\r\n            cancellation.ThrowIfCancelled();\r\n\r\n            try\r\n            {\r\n                IGetAllSettingsResult allSettingsResult = getAllSettingsUnitProcessor.GetAllSettings();\r\n                result->Settings(allSettingsResult.Settings());\r\n                result->ResultInformation(allSettingsResult.ResultInformation());\r\n            }\r\n            catch (...)\r\n            {\r\n                ExtractUnitResultInformation(std::current_exception(), unitResult);\r\n            }\r\n\r\n            m_threadGlobals.GetTelemetryLogger().LogConfigUnitRunIfAppropriate(GUID_NULL, unit, ConfigurationUnitIntent::Inform, TelemetryTraceLogger::ExportAction, result->ResultInformation());\r\n        }\r\n        else\r\n        {\r\n            AICLI_LOG(Config, Error, << \"Unit Processor does not support GetAllSettings operation\");\r\n            unitResult->Initialize(WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR, hstring{});\r\n        }\r\n\r\n        return *result;\r\n    }\r\n\r\n    Configuration::GetAllConfigurationUnitsResult ConfigurationProcessor::GetAllUnits(const ConfigurationUnit& unit)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !m_factory);\r\n        return GetAllUnitsImpl(unit);\r\n    }\r\n\r\n    Windows::Foundation::IAsyncOperation<Configuration::GetAllConfigurationUnitsResult> ConfigurationProcessor::GetAllUnitsAsync(const ConfigurationUnit& unit)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !m_factory);\r\n\r\n        auto strong_this{ get_strong() };\r\n        ConfigurationUnit localUnit = unit;\r\n\r\n        co_await winrt::resume_background();\r\n\r\n        co_return GetAllUnitsImpl(localUnit, { co_await winrt::get_cancellation_token() });\r\n    }\r\n\r\n    Configuration::GetAllConfigurationUnitsResult ConfigurationProcessor::GetAllUnitsImpl(\r\n        const ConfigurationUnit& unit,\r\n        ShutdownAwareAsyncCancellation cancellation)\r\n    {\r\n        auto threadGlobals = m_threadGlobals.SetForCurrentThread();\r\n\r\n        IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(nullptr);\r\n        auto result = make_self<wil::details::module_count_wrapper<implementation::GetAllConfigurationUnitsResult>>();\r\n        auto unitResult = make_self<wil::details::module_count_wrapper<implementation::ConfigurationUnitResultInformation>>();\r\n        result->ResultInformation(*unitResult);\r\n\r\n        cancellation.ThrowIfCancelled();\r\n\r\n        IConfigurationUnitProcessor unitProcessor;\r\n\r\n        try\r\n        {\r\n            unitProcessor = setProcessor.CreateUnitProcessor(unit);\r\n        }\r\n        catch (...)\r\n        {\r\n            ExtractUnitResultInformation(std::current_exception(), unitResult);\r\n        }\r\n\r\n        cancellation.ThrowIfCancelled();\r\n\r\n        IGetAllUnitsConfigurationUnitProcessor getAllUnitsUnitProcessor;\r\n        IGetAllSettingsConfigurationUnitProcessor getAllSettingsUnitProcessor;\r\n\r\n        if (unitProcessor.try_as<IGetAllUnitsConfigurationUnitProcessor>(getAllUnitsUnitProcessor))\r\n        {\r\n            cancellation.ThrowIfCancelled();\r\n\r\n            try\r\n            {\r\n                IGetAllUnitsResult allUnitsResult = getAllUnitsUnitProcessor.GetAllUnits();\r\n                result->Units(allUnitsResult.Units());\r\n                result->ResultInformation(allUnitsResult.ResultInformation());\r\n            }\r\n            catch (...)\r\n            {\r\n                ExtractUnitResultInformation(std::current_exception(), unitResult);\r\n            }\r\n\r\n            m_threadGlobals.GetTelemetryLogger().LogConfigUnitRunIfAppropriate(GUID_NULL, unit, ConfigurationUnitIntent::Inform, TelemetryTraceLogger::ExportAction, result->ResultInformation());\r\n        }\r\n        else if (unitProcessor.try_as<IGetAllSettingsConfigurationUnitProcessor>(getAllSettingsUnitProcessor))\r\n        {\r\n            cancellation.ThrowIfCancelled();\r\n\r\n            try\r\n            {\r\n                IGetAllSettingsResult allSettingsResult = getAllSettingsUnitProcessor.GetAllSettings();\r\n\r\n                auto allSettings = allSettingsResult.Settings();\r\n                if (allSettings)\r\n                {\r\n                    std::vector<Configuration::ConfigurationUnit> units;\r\n\r\n                    size_t index = 0;\r\n                    auto currentType = unit.Type();\r\n                    auto currentDetails = unit.Details();\r\n\r\n                    for (const auto& settings : allSettings)\r\n                    {\r\n                        auto newUnit = make_self<implementation::ConfigurationUnit>();\r\n\r\n                        newUnit->Type(currentType);\r\n                        newUnit->Settings(settings);\r\n                        newUnit->Details(currentDetails);\r\n\r\n                        std::wostringstream identifierStream;\r\n                        identifierStream << static_cast<std::wstring_view>(currentType) << L'-' << index++;\r\n                        newUnit->Identifier(hstring{ identifierStream.str() });\r\n\r\n                        units.push_back(*newUnit);\r\n                    }\r\n\r\n                    result->Units(single_threaded_vector(std::move(units)));\r\n                }\r\n\r\n                result->ResultInformation(allSettingsResult.ResultInformation());\r\n            }\r\n            catch (...)\r\n            {\r\n                ExtractUnitResultInformation(std::current_exception(), unitResult);\r\n            }\r\n\r\n            m_threadGlobals.GetTelemetryLogger().LogConfigUnitRunIfAppropriate(GUID_NULL, unit, ConfigurationUnitIntent::Inform, TelemetryTraceLogger::ExportAction, result->ResultInformation());\r\n        }\r\n        else\r\n        {\r\n            AICLI_LOG(Config, Error, << \"Unit Processor does not support GetAllUnits or GetAllSettings operation\");\r\n            unitResult->Initialize(WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR, hstring{});\r\n        }\r\n\r\n        return *result;\r\n    }\r\n\r\n    Windows::Foundation::Collections::IVector<IConfigurationUnitProcessorDetails> ConfigurationProcessor::FindUnitProcessors(const FindUnitProcessorsOptions& findOptions)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !m_factory);\r\n        return FindUnitProcessorsImpl(findOptions);\r\n    }\r\n\r\n    Windows::Foundation::IAsyncOperation<Windows::Foundation::Collections::IVector<IConfigurationUnitProcessorDetails>> ConfigurationProcessor::FindUnitProcessorsAsync(const FindUnitProcessorsOptions& findOptions)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !m_factory);\r\n\r\n        auto strong_this{ get_strong() };\r\n        FindUnitProcessorsOptions localOptions = findOptions;\r\n\r\n        co_await winrt::resume_background();\r\n\r\n        co_return FindUnitProcessorsImpl(localOptions, { co_await winrt::get_cancellation_token() });\r\n    }\r\n\r\n    Windows::Foundation::Collections::IVector<IConfigurationUnitProcessorDetails> ConfigurationProcessor::FindUnitProcessorsImpl(\r\n        const FindUnitProcessorsOptions& findOptions,\r\n        ShutdownAwareAsyncCancellation cancellation)\r\n    {\r\n        auto threadGlobals = m_threadGlobals.SetForCurrentThread();\r\n\r\n        IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(nullptr);\r\n\r\n        cancellation.ThrowIfCancelled();\r\n\r\n        IFindUnitProcessorsSetProcessor findUnitProcessorsSetProcessor;\r\n\r\n        if (setProcessor.try_as<IFindUnitProcessorsSetProcessor>(findUnitProcessorsSetProcessor))\r\n        {\r\n            return findUnitProcessorsSetProcessor.FindUnitProcessors(findOptions);\r\n        }\r\n        else\r\n        {\r\n            AICLI_LOG(Config, Error, << \"Set Processor does not support FindUnitProcessors operation\");\r\n            THROW_HR(WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR);\r\n        }\r\n    }\r\n\r\n    Configuration::ApplyConfigurationUnitResult ConfigurationProcessor::ApplyUnit(const ConfigurationUnit& unit)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !m_factory);\r\n        return ApplyUnitImpl(unit);\r\n    }\r\n\r\n    Windows::Foundation::IAsyncOperation<Configuration::ApplyConfigurationUnitResult> ConfigurationProcessor::ApplyUnitAsync(const ConfigurationUnit& unit)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !m_factory);\r\n\r\n        auto strong_this{ get_strong() };\r\n        ConfigurationUnit localUnit = unit;\r\n\r\n        co_await winrt::resume_background();\r\n\r\n        co_return ApplyUnitImpl(localUnit, { co_await winrt::get_cancellation_token() });\r\n    }\r\n\r\n    Configuration::ApplyConfigurationUnitResult ConfigurationProcessor::ApplyUnitImpl(\r\n        const ConfigurationUnit& unit,\r\n        ShutdownAwareAsyncCancellation cancellation)\r\n    {\r\n        auto threadGlobals = m_threadGlobals.SetForCurrentThread();\r\n\r\n        IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(nullptr);\r\n        auto result = make_self<wil::details::module_count_wrapper<implementation::ApplyConfigurationUnitResult>>();\r\n        auto unitResult = make_self<wil::details::module_count_wrapper<implementation::ConfigurationUnitResultInformation>>();\r\n        result->Unit(unit);\r\n        result->ResultInformation(*unitResult);\r\n\r\n        cancellation.ThrowIfCancelled();\r\n\r\n        IConfigurationUnitProcessor unitProcessor;\r\n\r\n        try\r\n        {\r\n            unitProcessor = setProcessor.CreateUnitProcessor(unit);\r\n        }\r\n        catch (...)\r\n        {\r\n            ExtractUnitResultInformation(std::current_exception(), unitResult);\r\n        }\r\n\r\n        cancellation.ThrowIfCancelled();\r\n\r\n        if (unitProcessor)\r\n        {\r\n            try\r\n            {\r\n                auto applyResult = unitProcessor.ApplySettings();\r\n                result->Unit(applyResult.Unit());\r\n                result->State(Configuration::ConfigurationUnitState::Completed);\r\n                result->ResultInformation(applyResult.ResultInformation());\r\n                result->RebootRequired(applyResult.RebootRequired());\r\n            }\r\n            catch (...)\r\n            {\r\n                ExtractUnitResultInformation(std::current_exception(), unitResult);\r\n            }\r\n\r\n            m_threadGlobals.GetTelemetryLogger().LogConfigUnitRunIfAppropriate(GUID_NULL, unit, ConfigurationUnitIntent::Apply, TelemetryTraceLogger::ApplyAction, result->ResultInformation());\r\n        }\r\n\r\n        return *result;\r\n    }\r\n\r\n    Configuration::TestConfigurationUnitResult ConfigurationProcessor::TestUnit(const ConfigurationUnit& unit)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !m_factory);\r\n        return TestUnitImpl(unit);\r\n    }\r\n\r\n    Windows::Foundation::IAsyncOperation<Configuration::TestConfigurationUnitResult> ConfigurationProcessor::TestUnitAsync(const ConfigurationUnit& unit)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !m_factory);\r\n\r\n        auto strong_this{ get_strong() };\r\n        ConfigurationUnit localUnit = unit;\r\n\r\n        co_await winrt::resume_background();\r\n\r\n        co_return TestUnitImpl(localUnit, { co_await winrt::get_cancellation_token() });\r\n    }\r\n\r\n    Configuration::TestConfigurationUnitResult ConfigurationProcessor::TestUnitImpl(\r\n        const ConfigurationUnit& unit,\r\n        ShutdownAwareAsyncCancellation cancellation)\r\n    {\r\n        auto threadGlobals = m_threadGlobals.SetForCurrentThread();\r\n\r\n        IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(nullptr);\r\n        auto result = make_self<wil::details::module_count_wrapper<implementation::TestConfigurationUnitResult>>();\r\n        auto unitResult = make_self<wil::details::module_count_wrapper<implementation::ConfigurationUnitResultInformation>>();\r\n        result->Unit(unit);\r\n        result->ResultInformation(*unitResult);\r\n\r\n        cancellation.ThrowIfCancelled();\r\n\r\n        IConfigurationUnitProcessor unitProcessor;\r\n\r\n        try\r\n        {\r\n            unitProcessor = setProcessor.CreateUnitProcessor(unit);\r\n        }\r\n        catch (...)\r\n        {\r\n            ExtractUnitResultInformation(std::current_exception(), unitResult);\r\n        }\r\n\r\n        cancellation.ThrowIfCancelled();\r\n\r\n        if (unitProcessor)\r\n        {\r\n            try\r\n            {\r\n                auto testResult = unitProcessor.TestSettings();\r\n                result->Unit(testResult.Unit());\r\n                result->TestResult(testResult.TestResult());\r\n                result->ResultInformation(testResult.ResultInformation());\r\n            }\r\n            catch (...)\r\n            {\r\n                ExtractUnitResultInformation(std::current_exception(), unitResult);\r\n            }\r\n\r\n            m_threadGlobals.GetTelemetryLogger().LogConfigUnitRunIfAppropriate(GUID_NULL, unit, ConfigurationUnitIntent::Assert, TelemetryTraceLogger::TestAction, result->ResultInformation());\r\n        }\r\n\r\n        return *result;\r\n    }\r\n\r\n    IConfigurationGroupProcessor ConfigurationProcessor::GetSetGroupProcessor(const Configuration::ConfigurationSet& configurationSet)\r\n    {\r\n        IConfigurationSetProcessor setProcessor = m_factory.CreateSetProcessor(configurationSet);\r\n\r\n        IConfigurationGroupProcessor result = setProcessor.try_as<IConfigurationGroupProcessor>();\r\n        if (!result)\r\n        {\r\n            auto groupProcessor = make_self<wil::details::module_count_wrapper<implementation::DefaultSetGroupProcessor>>();\r\n            groupProcessor->Initialize(configurationSet, setProcessor, m_threadGlobals);\r\n            result = *groupProcessor;\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    HRESULT STDMETHODCALLTYPE ConfigurationProcessor::SetLifetimeWatcher(IUnknown* watcher)\r\n    {\r\n        return AppInstaller::WinRT::LifetimeWatcherBase::SetLifetimeWatcher(watcher);\r\n    }\r\n\r\n    void ConfigurationProcessor::ConfigurationSetProcessorFactory(const IConfigurationSetProcessorFactory& value)\r\n    {\r\n        m_factory = value;\r\n\r\n        if (m_factory)\r\n        {\r\n            m_factoryDiagnosticsEventRevoker = m_factory.Diagnostics(winrt::auto_revoke,\r\n                [weak_this{ get_weak() }](const IInspectable&, const IDiagnosticInformation& information)\r\n                {\r\n                    if (auto strong_this{ weak_this.get() })\r\n                    {\r\n                        strong_this->SendDiagnostics(information);\r\n                    }\r\n                });\r\n        }\r\n    }\r\n\r\n    void ConfigurationProcessor::SendDiagnostics(DiagnosticLevel level, std::string_view message) try\r\n    {\r\n        if (level >= m_minimumLevel)\r\n        {\r\n            auto diagnostics = make_self<wil::details::module_count_wrapper<implementation::DiagnosticInformationInstance>>();\r\n            diagnostics->Initialize(level, AppInstaller::Utility::ConvertToUTF16(message));\r\n            SendDiagnosticsImpl(*diagnostics);\r\n        }\r\n    }\r\n    // While diagnostics can be important, a failure to send them should not cause additional issues.\r\n    catch (...) {}\r\n\r\n    void ConfigurationProcessor::SendDiagnostics(const IDiagnosticInformation& information) try\r\n    {\r\n        if (information.Level() >= m_minimumLevel)\r\n        {\r\n            SendDiagnosticsImpl(information);\r\n        }\r\n    }\r\n    // While diagnostics can be important, a failure to send them should not cause additional issues.\r\n    catch (...) {}\r\n\r\n    void ConfigurationProcessor::SendDiagnosticsImpl(const IDiagnosticInformation& information)\r\n    {\r\n        std::lock_guard<std::recursive_mutex> lock{ m_diagnosticsMutex };\r\n\r\n        // Prevent a winrt/wil error recursion here by detecting that this thread failed to send a previous message.\r\n        if (m_isHandlingDiagnostics)\r\n        {\r\n            std::wstring debugMessage = L\"An error occurred while trying to send a previous diagnostics message:\\n\";\r\n            debugMessage.append(information.Message());\r\n            OutputDebugStringW(debugMessage.c_str());\r\n            return;\r\n        }\r\n\r\n        m_isHandlingDiagnostics = true;\r\n        auto notHandling = wil::scope_exit([&] { m_isHandlingDiagnostics = false; });\r\n\r\n        m_diagnostics(*this, information);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationProcessor.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ConfigurationProcessor.g.h\"\r\n#include <winrt/Windows.Foundation.h>\r\n#include <winrt/Windows.Foundation.Collections.h>\r\n#include <winrt/Windows.Storage.Streams.h>\r\n#include \"ConfigThreadGlobals.h\"\r\n#include \"ConfigurationStatus.h\"\r\n#include \"Database/ConfigurationDatabase.h\"\r\n#include <winget/AsyncTokens.h>\r\n#include \"ShutdownSynchronization.h\"\r\n#include <winget/ILifetimeWatcher.h>\r\n\r\n#include <functional>\r\n#include <mutex>\r\n#include <string_view>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    struct ConfigurationProcessor : ConfigurationProcessorT<ConfigurationProcessor, winrt::cloaked<AppInstaller::WinRT::ILifetimeWatcher>>, AppInstaller::WinRT::LifetimeWatcherBase\r\n    {\r\n        using ConfigurationSetChangeData = Configuration::ConfigurationSetChangeData;\r\n        using ConfigurationUnit = Configuration::ConfigurationUnit;\r\n        using ApplyConfigurationSetResult = Configuration::ApplyConfigurationSetResult;\r\n        using TestConfigurationSetResult = Configuration::TestConfigurationSetResult;\r\n        using TestConfigurationUnitResult = Configuration::TestConfigurationUnitResult;\r\n        using GetConfigurationUnitSettingsResult = Configuration::GetConfigurationUnitSettingsResult;\r\n        using GetAllConfigurationUnitSettingsResult = Configuration::GetAllConfigurationUnitSettingsResult;\r\n        using GetConfigurationSetDetailsResult = Configuration::GetConfigurationSetDetailsResult;\r\n        using GetConfigurationUnitDetailsResult = Configuration::GetConfigurationUnitDetailsResult;\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        ConfigurationProcessor();\r\n#endif\r\n\r\n        ConfigurationProcessor(const IConfigurationSetProcessorFactory& factory);\r\n\r\n        event_token Diagnostics(const Windows::Foundation::EventHandler<IDiagnosticInformation>& handler);\r\n        void Diagnostics(const event_token& token) noexcept;\r\n\r\n        DiagnosticLevel MinimumLevel();\r\n        void MinimumLevel(DiagnosticLevel value);\r\n\r\n        hstring Caller() const;\r\n        void Caller(hstring value);\r\n\r\n        guid ActivityIdentifier();\r\n        void ActivityIdentifier(const guid& value);\r\n\r\n        bool GenerateTelemetryEvents();\r\n        void GenerateTelemetryEvents(bool value);\r\n\r\n        event_token ConfigurationChange(const Windows::Foundation::TypedEventHandler<Configuration::ConfigurationSet, Configuration::ConfigurationChangeData>& handler);\r\n        void ConfigurationChange(const event_token& token) noexcept;\r\n\r\n        Windows::Foundation::Collections::IVector<Configuration::ConfigurationSet> GetConfigurationHistory();\r\n        Windows::Foundation::IAsyncOperation<Windows::Foundation::Collections::IVector<Configuration::ConfigurationSet>> GetConfigurationHistoryAsync();\r\n\r\n        Configuration::OpenConfigurationSetResult OpenConfigurationSet(const Windows::Storage::Streams::IInputStream& stream);\r\n        Windows::Foundation::IAsyncOperation<Configuration::OpenConfigurationSetResult> OpenConfigurationSetAsync(const Windows::Storage::Streams::IInputStream& stream);\r\n\r\n        Windows::Foundation::Collections::IVector<ConfigurationConflict> CheckForConflicts(\r\n            const Windows::Foundation::Collections::IVectorView<Configuration::ConfigurationSet>& configurationSets,\r\n            bool includeConfigurationHistory);\r\n        Windows::Foundation::IAsyncOperation<Windows::Foundation::Collections::IVector<ConfigurationConflict>> CheckForConflictsAsync(\r\n            const Windows::Foundation::Collections::IVectorView<Configuration::ConfigurationSet>& configurationSets,\r\n            bool includeConfigurationHistory);\r\n\r\n        GetConfigurationSetDetailsResult GetSetDetails(const Configuration::ConfigurationSet& configurationSet, ConfigurationUnitDetailFlags detailFlags);\r\n        Windows::Foundation::IAsyncOperationWithProgress<GetConfigurationSetDetailsResult, GetConfigurationUnitDetailsResult> GetSetDetailsAsync(const Configuration::ConfigurationSet& configurationSet, ConfigurationUnitDetailFlags detailFlags);\r\n\r\n        GetConfigurationUnitDetailsResult GetUnitDetails(const ConfigurationUnit& unit, ConfigurationUnitDetailFlags detailFlags);\r\n        Windows::Foundation::IAsyncOperation<GetConfigurationUnitDetailsResult> GetUnitDetailsAsync(const ConfigurationUnit& unit, ConfigurationUnitDetailFlags detailFlags);\r\n\r\n        ApplyConfigurationSetResult ApplySet(const Configuration::ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags);\r\n        Windows::Foundation::IAsyncOperationWithProgress<ApplyConfigurationSetResult, ConfigurationSetChangeData> ApplySetAsync(const Configuration::ConfigurationSet& configurationSet, ApplyConfigurationSetFlags flags);\r\n\r\n        TestConfigurationSetResult TestSet(const Configuration::ConfigurationSet& configurationSet);\r\n        Windows::Foundation::IAsyncOperationWithProgress<TestConfigurationSetResult, TestConfigurationUnitResult> TestSetAsync(const Configuration::ConfigurationSet& configurationSet);\r\n\r\n        GetConfigurationUnitSettingsResult GetUnitSettings(const ConfigurationUnit& unit);\r\n        Windows::Foundation::IAsyncOperation<GetConfigurationUnitSettingsResult> GetUnitSettingsAsync(const ConfigurationUnit& unit);\r\n\r\n        GetAllConfigurationUnitSettingsResult GetAllUnitSettings(const ConfigurationUnit& unit);\r\n        Windows::Foundation::IAsyncOperation<GetAllConfigurationUnitSettingsResult> GetAllUnitSettingsAsync(const ConfigurationUnit& unit);\r\n\r\n        Configuration::GetAllConfigurationUnitsResult GetAllUnits(const ConfigurationUnit& unit);\r\n        Windows::Foundation::IAsyncOperation<Configuration::GetAllConfigurationUnitsResult> GetAllUnitsAsync(const ConfigurationUnit& unit);\r\n\r\n        Windows::Foundation::Collections::IVector<Configuration::IConfigurationUnitProcessorDetails> FindUnitProcessors(const Configuration::FindUnitProcessorsOptions& findOptions);\r\n        Windows::Foundation::IAsyncOperation<Windows::Foundation::Collections::IVector<Configuration::IConfigurationUnitProcessorDetails>> FindUnitProcessorsAsync(const Configuration::FindUnitProcessorsOptions& findOptions);\r\n\r\n        Configuration::ApplyConfigurationUnitResult ApplyUnit(const ConfigurationUnit& unit);\r\n        Windows::Foundation::IAsyncOperation<Configuration::ApplyConfigurationUnitResult> ApplyUnitAsync(const ConfigurationUnit& unit);\r\n        \r\n        Configuration::TestConfigurationUnitResult TestUnit(const ConfigurationUnit& unit);\r\n        Windows::Foundation::IAsyncOperation<Configuration::TestConfigurationUnitResult> TestUnitAsync(const ConfigurationUnit& unit);\r\n\r\n        HRESULT STDMETHODCALLTYPE SetLifetimeWatcher(IUnknown* watcher);\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        void ConfigurationSetProcessorFactory(const IConfigurationSetProcessorFactory& value);\r\n\r\n        // Sends diagnostics objects to the event.\r\n        void SendDiagnostics(DiagnosticLevel level, std::string_view message);\r\n\r\n        // Sends diagnostics objects to the event.\r\n        void SendDiagnostics(const IDiagnosticInformation& information);\r\n\r\n        // Indicate a configuration change occurred.\r\n        void ConfigurationChange(const Configuration::ConfigurationSet& set, const Configuration::ConfigurationChangeData& data);\r\n\r\n    private:\r\n        Windows::Foundation::Collections::IVector<Configuration::ConfigurationSet> GetConfigurationHistoryImpl(ShutdownAwareAsyncCancellation cancellation = {});\r\n\r\n        GetConfigurationSetDetailsResult GetSetDetailsImpl(\r\n            const Configuration::ConfigurationSet& configurationSet,\r\n            ConfigurationUnitDetailFlags detailFlags,\r\n            ShutdownAwareAsyncProgress<GetConfigurationSetDetailsResult, GetConfigurationUnitDetailsResult> progress = {});\r\n\r\n        GetConfigurationUnitDetailsResult GetUnitDetailsImpl(const ConfigurationUnit& unit, ConfigurationUnitDetailFlags detailFlags);\r\n\r\n        ApplyConfigurationSetResult ApplySetImpl(\r\n            const Configuration::ConfigurationSet& configurationSet,\r\n            ApplyConfigurationSetFlags flags,\r\n            ShutdownAwareAsyncProgress<ApplyConfigurationSetResult, ConfigurationSetChangeData> progress = {});\r\n\r\n        TestConfigurationSetResult TestSetImpl(\r\n            const Configuration::ConfigurationSet& configurationSet,\r\n            ShutdownAwareAsyncProgress<TestConfigurationSetResult, TestConfigurationUnitResult> progress = {});\r\n\r\n        GetConfigurationUnitSettingsResult GetUnitSettingsImpl(const ConfigurationUnit& unit, ShutdownAwareAsyncCancellation cancellation = {});\r\n\r\n        GetAllConfigurationUnitSettingsResult GetAllUnitSettingsImpl(const ConfigurationUnit& unit, ShutdownAwareAsyncCancellation cancellation = {});\r\n\r\n        Configuration::GetAllConfigurationUnitsResult GetAllUnitsImpl(const ConfigurationUnit& unit, ShutdownAwareAsyncCancellation cancellation = {});\r\n\r\n        Windows::Foundation::Collections::IVector<Configuration::IConfigurationUnitProcessorDetails> FindUnitProcessorsImpl(const Configuration::FindUnitProcessorsOptions& findOptions, ShutdownAwareAsyncCancellation cancellation = {});\r\n\r\n        Configuration::ApplyConfigurationUnitResult ApplyUnitImpl(const ConfigurationUnit& unit, ShutdownAwareAsyncCancellation cancellation = {});\r\n\r\n        Configuration::TestConfigurationUnitResult TestUnitImpl(const ConfigurationUnit& unit, ShutdownAwareAsyncCancellation cancellation = {});\r\n\r\n        IConfigurationGroupProcessor GetSetGroupProcessor(const Configuration::ConfigurationSet& configurationSet);\r\n\r\n        void SendDiagnosticsImpl(const IDiagnosticInformation& information);\r\n\r\n        IConfigurationSetProcessorFactory m_factory = nullptr;\r\n        event<Windows::Foundation::EventHandler<IDiagnosticInformation>> m_diagnostics;\r\n        event<Windows::Foundation::TypedEventHandler<Configuration::ConfigurationSet, Configuration::ConfigurationChangeData>> m_configurationChange;\r\n        ConfigThreadGlobals m_threadGlobals;\r\n        IConfigurationSetProcessorFactory::Diagnostics_revoker m_factoryDiagnosticsEventRevoker;\r\n        DiagnosticLevel m_minimumLevel = DiagnosticLevel::Informational;\r\n        std::recursive_mutex m_diagnosticsMutex;\r\n        ConfigurationDatabase m_database;\r\n        bool m_isHandlingDiagnostics = false;\r\n        std::shared_ptr<ConfigurationStatus::ChangeRegistration> m_changeRegistration;\r\n#endif\r\n    };\r\n}\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\nnamespace winrt::Microsoft::Management::Configuration::factory_implementation\r\n{\r\n    struct ConfigurationProcessor : ConfigurationProcessorT<ConfigurationProcessor, implementation::ConfigurationProcessor>\r\n    {\r\n    };\r\n}\r\n#endif\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationSequencer.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigurationSequencer.h\"\r\n#include \"ConfigurationStatus.h\"\r\n#include <AppInstallerStrings.h>\r\n\r\nusing namespace std::chrono_literals;\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    ConfigurationSequencer::ConfigurationSequencer(ConfigurationDatabase& database) : m_database(database) {}\r\n\r\n    ConfigurationSequencer::~ConfigurationSequencer()\r\n    {\r\n        // Best effort attempt to remove our queue row\r\n        try\r\n        {\r\n            m_database.RemoveQueueItem(m_queueItemObjectName);\r\n\r\n            auto status = ConfigurationStatus::Instance();\r\n            status->UpdateSetState(m_setInstanceIdentifier, false);\r\n        }\r\n        CATCH_LOG();\r\n    }\r\n\r\n    // This function creates necessary objects and records this operation into the table.\r\n    // It then performs the equivalent of `Wait` with a timeout of 0.\r\n    bool ConfigurationSequencer::Enqueue(const Configuration::ConfigurationSet& configurationSet)\r\n    {\r\n        m_setInstanceIdentifier = configurationSet.InstanceIdentifier();\r\n\r\n        // Create an arbitrarily named object\r\n        std::wstring objectName = L\"WinGetConfigQueue_\" + AppInstaller::Utility::CreateNewGuidNameWString();\r\n        m_queueItemObjectName = AppInstaller::Utility::ConvertToUTF8(objectName);\r\n        m_queueItemObject.create(wil::EventOptions::None, objectName.c_str());\r\n\r\n        m_database.AddQueueItem(configurationSet, m_queueItemObjectName);\r\n\r\n        auto statusInstance = ConfigurationStatus::Instance();\r\n        statusInstance->UpdateSetState(m_setInstanceIdentifier, true);\r\n\r\n        // Create shared mutex\r\n        constexpr PCWSTR applyMutexName = L\"WinGetConfigQueueApplyMutex\";\r\n\r\n        for (int i = 0; !m_applyMutex && i < 2; ++i)\r\n        {\r\n            if (!m_applyMutex.try_create(applyMutexName, 0, SYNCHRONIZE))\r\n            {\r\n                m_applyMutex.try_open(applyMutexName, SYNCHRONIZE);\r\n            }\r\n        }\r\n\r\n        THROW_LAST_ERROR_IF(!m_applyMutex);\r\n\r\n        // Probe for an empty queue\r\n        DWORD status = 0;\r\n        m_applyMutexScope = m_applyMutex.acquire(&status, 0);\r\n        THROW_LAST_ERROR_IF(status == WAIT_FAILED);\r\n\r\n        if (status == WAIT_TIMEOUT)\r\n        {\r\n            return true;\r\n        }\r\n\r\n        if (GetQueuePosition() == 0)\r\n        {\r\n            m_database.SetActiveQueueItem(m_queueItemObjectName);\r\n            return false;\r\n        }\r\n        else\r\n        {\r\n            m_applyMutexScope.reset();\r\n            return true;\r\n        }\r\n    }\r\n\r\n    // The configuration queue consists of a table in the shared database and cooperative handling of said table.\r\n    // At any moment, the active processor must be holding a common named mutex.\r\n    // Each active queue entry also holds their own arbitrarily named object, recorded in the table.\r\n    // \r\n    // The general mechanism to wait is:\r\n    //  1. Wait on common named mutex\r\n    //  2. Check if first in queue, including probing arbitrary named objects of entries ahead of us\r\n    //  3. If not first, wait for X * queue position, where X is sufficiently high to prevent contention on main mutex\r\n    void ConfigurationSequencer::Wait(AppInstaller::WinRT::AsyncCancellation& cancellation)\r\n    {\r\n        THROW_HR_IF(E_NOT_VALID_STATE, !m_applyMutex);\r\n\r\n        wil::unique_event cancellationEvent;\r\n        cancellationEvent.create();\r\n\r\n        HANDLE waitHandles[2];\r\n        waitHandles[0] = cancellationEvent.get();\r\n        waitHandles[1] = m_applyMutex.get();\r\n\r\n        cancellation.Callback([&]() { cancellationEvent.SetEvent(); });\r\n        auto clearCancelCallback = wil::scope_exit([&cancellation]() { cancellation.Callback([]() {}); });\r\n\r\n        for (;;)\r\n        {\r\n            DWORD waitResult = WaitForMultipleObjects(ARRAYSIZE(waitHandles), waitHandles, FALSE, INFINITE);\r\n            THROW_LAST_ERROR_IF(waitResult == WAIT_FAILED);\r\n\r\n            if (waitResult == WAIT_OBJECT_0)\r\n            {\r\n                // Cancellation\r\n                break;\r\n            }\r\n            else if (waitResult == WAIT_OBJECT_0 + 1 || waitResult == WAIT_ABANDONED_0 + 1)\r\n            {\r\n                // We now hold the apply mutex\r\n                wil::mutex_release_scope_exit applyMutexScope{ m_applyMutex.get() };\r\n\r\n                size_t queuePosition = GetQueuePosition();\r\n                if (queuePosition == 0)\r\n                {\r\n                    m_applyMutexScope = std::move(applyMutexScope);\r\n                    m_database.SetActiveQueueItem(m_queueItemObjectName);\r\n                    break;\r\n                }\r\n                else\r\n                {\r\n                    applyMutexScope.reset();\r\n                    std::this_thread::sleep_for(queuePosition * 100ms);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    size_t ConfigurationSequencer::GetQueuePosition()\r\n    {\r\n        auto queueItems = m_database.GetQueueItems();\r\n\r\n        // If we get no queue items at all, we assume that the database doesn't support queueing.\r\n        if (queueItems.empty())\r\n        {\r\n            return 0;\r\n        }\r\n\r\n        size_t result = 0;\r\n        bool found = false;\r\n\r\n        for (const auto& item : queueItems)\r\n        {\r\n            if (item.ObjectName == m_queueItemObjectName)\r\n            {\r\n                found = true;\r\n                break;\r\n            }\r\n\r\n            std::wstring objectName = AppInstaller::Utility::ConvertToUTF16(item.ObjectName);\r\n            QueueObjectType itemObject;\r\n            if (itemObject.try_open(objectName.c_str(), SYNCHRONIZE))\r\n            {\r\n                ++result;\r\n            }\r\n            else\r\n            {\r\n                // Best effort attempt to remove the dead queue row\r\n                try\r\n                {\r\n                    m_database.RemoveQueueItem(item.ObjectName);\r\n                }\r\n                CATCH_LOG();\r\n            }\r\n        }\r\n\r\n        THROW_HR_IF(E_NOT_SET, !found);\r\n\r\n        return result;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationSequencer.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Database/ConfigurationDatabase.h\"\r\n#include <winget/AsyncTokens.h>\r\n#include <wil/resource.h>\r\n#include <winrt/Microsoft.Management.Configuration.h>\r\n\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    // Allows for sequencing of configuration set applications.\r\n    struct ConfigurationSequencer\r\n    {\r\n        ConfigurationSequencer(ConfigurationDatabase& database);\r\n\r\n        ConfigurationSequencer(const ConfigurationSequencer&) = delete;\r\n        ConfigurationSequencer& operator=(const ConfigurationSequencer&) = delete;\r\n\r\n        ConfigurationSequencer(ConfigurationSequencer&&) = delete;\r\n        ConfigurationSequencer& operator=(ConfigurationSequencer&&) = delete;\r\n\r\n        ~ConfigurationSequencer();\r\n\r\n        // Enters the current sequencer into the queue of operations.\r\n        // Returns true to indicate that this operation has been queued and must wait.\r\n        // Returns false to indicate that this operation is able to proceed (queued directly to the front).\r\n        bool Enqueue(const Configuration::ConfigurationSet& configurationSet);\r\n\r\n        // Waits for this operation to reach the front of the queue.\r\n        // Registers a cancellation callback so that we can halt our waiting.\r\n        void Wait(AppInstaller::WinRT::AsyncCancellation& cancellation);\r\n\r\n    private:\r\n        // Determines the effective queue position of this operation; removing queue entries that are not longer active.\r\n        // 0 is the front of the queue.\r\n        size_t GetQueuePosition();\r\n\r\n        using QueueObjectType = wil::unique_event;\r\n\r\n        ConfigurationDatabase& m_database;\r\n        guid m_setInstanceIdentifier{};\r\n        std::string m_queueItemObjectName;\r\n        QueueObjectType m_queueItemObject;\r\n        wil::unique_mutex m_applyMutex;\r\n        wil::mutex_release_scope_exit m_applyMutexScope;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationSet.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigurationSet.h\"\r\n#include \"ConfigurationSet.g.cpp\"\r\n#include \"ConfigurationSetParser.h\"\r\n#include \"ConfigurationSetSerializer.h\"\r\n#include \"Database/ConfigurationDatabase.h\"\r\n#include <AppInstallerLanguageUtilities.h>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    namespace impl\r\n    {\r\n        struct EnvironmentData\r\n        {\r\n            EnvironmentData(Configuration::ConfigurationEnvironment environment) :\r\n                Environment(environment), Context(environment.Context()), Identifier(environment.ProcessorIdentifier()), Properties(environment.ProcessorProperties())\r\n            {\r\n            }\r\n\r\n            EnvironmentData(EnvironmentData&&) = default;\r\n\r\n            bool operator==(const EnvironmentData& other) const\r\n            {\r\n                return\r\n                    Context == other.Context &&\r\n                    Identifier == other.Identifier &&\r\n                    ConfigurationEnvironment::AreEqual(Properties, other.Properties);\r\n            }\r\n\r\n            Configuration::ConfigurationEnvironment Environment;\r\n            SecurityContext Context;\r\n            hstring Identifier;\r\n            Windows::Foundation::Collections::IMap<hstring, hstring> Properties;\r\n        };\r\n\r\n        bool ContainsEnvironment(const std::vector<EnvironmentData>& uniqueEnvironments, const EnvironmentData& data)\r\n        {\r\n            for (const EnvironmentData& item : uniqueEnvironments)\r\n            {\r\n                if (item == data)\r\n                {\r\n                    return true;\r\n                }\r\n            }\r\n\r\n            return false;\r\n        }\r\n\r\n        void ComputeUniqueEnvironments(std::vector<EnvironmentData>& uniqueEnvironments, const Windows::Foundation::Collections::IVector<Configuration::ConfigurationUnit>& units)\r\n        {\r\n            for (const Configuration::ConfigurationUnit& unit : units)\r\n            {\r\n                if (unit.IsActive())\r\n                {\r\n                    EnvironmentData data{ unit.Environment() };\r\n                    if (!ContainsEnvironment(uniqueEnvironments, data))\r\n                    {\r\n                        uniqueEnvironments.emplace_back(std::move(data));\r\n                    }\r\n\r\n                    if (unit.IsGroup())\r\n                    {\r\n                        ComputeUniqueEnvironments(uniqueEnvironments, unit.Units());\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    ConfigurationSet::ConfigurationSet()\r\n    {\r\n        GUID instanceIdentifier;\r\n        THROW_IF_FAILED(CoCreateGuid(&instanceIdentifier));\r\n        m_instanceIdentifier = instanceIdentifier;\r\n        std::tie(m_schemaVersion, m_schemaUri) = ConfigurationSetParser::LatestVersion();\r\n    }\r\n\r\n    ConfigurationSet::ConfigurationSet(const guid& instanceIdentifier) :\r\n        m_instanceIdentifier(instanceIdentifier)\r\n    {\r\n    }\r\n\r\n    void ConfigurationSet::Units(std::vector<Configuration::ConfigurationUnit>&& units)\r\n    {\r\n        m_units = winrt::multi_threaded_vector<Configuration::ConfigurationUnit>(std::move(units));\r\n    }\r\n\r\n    void ConfigurationSet::Parameters(std::vector<Configuration::ConfigurationParameter>&& value)\r\n    {\r\n        m_parameters = winrt::multi_threaded_vector<Configuration::ConfigurationParameter>(std::move(value));\r\n    }\r\n\r\n    hstring ConfigurationSet::Name()\r\n    {\r\n        return m_name;\r\n    }\r\n\r\n    void ConfigurationSet::Name(const hstring& value)\r\n    {\r\n        m_name = value;\r\n    }\r\n\r\n    hstring ConfigurationSet::Origin()\r\n    {\r\n        return m_origin;\r\n    }\r\n\r\n    void ConfigurationSet::Origin(const hstring& value)\r\n    {\r\n        m_origin = value;\r\n    }\r\n\r\n    hstring ConfigurationSet::Path()\r\n    {\r\n        return m_path;\r\n    }\r\n\r\n    void ConfigurationSet::Path(const hstring& value)\r\n    {\r\n        m_path = value;\r\n    }\r\n\r\n    guid ConfigurationSet::InstanceIdentifier() const\r\n    {\r\n        return m_instanceIdentifier;\r\n    }\r\n\r\n    ConfigurationSetState ConfigurationSet::State()\r\n    {\r\n        auto status = ConfigurationStatus::Instance();\r\n        return status->GetSetState(m_instanceIdentifier);\r\n    }\r\n\r\n    clock::time_point ConfigurationSet::FirstApply()\r\n    {\r\n        auto status = ConfigurationStatus::Instance();\r\n        return status->GetSetFirstApply(m_instanceIdentifier);\r\n    }\r\n\r\n    clock::time_point ConfigurationSet::ApplyBegun()\r\n    {\r\n        auto status = ConfigurationStatus::Instance();\r\n        return status->GetSetApplyBegun(m_instanceIdentifier);\r\n    }\r\n\r\n    clock::time_point ConfigurationSet::ApplyEnded()\r\n    {\r\n        auto status = ConfigurationStatus::Instance();\r\n        return status->GetSetApplyEnded(m_instanceIdentifier);\r\n    }\r\n\r\n    Windows::Foundation::Collections::IVector<Configuration::ConfigurationUnit> ConfigurationSet::Units()\r\n    {\r\n        return m_units;\r\n    }\r\n\r\n    void ConfigurationSet::Units(const Windows::Foundation::Collections::IVector<ConfigurationUnit>& value)\r\n    {\r\n        THROW_HR_IF(E_POINTER, !value);\r\n        m_units = value;\r\n    }\r\n\r\n    hstring ConfigurationSet::SchemaVersion()\r\n    {\r\n        return m_schemaVersion;\r\n    }\r\n\r\n    void ConfigurationSet::SchemaVersion(const hstring& value)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, !ConfigurationSetParser::IsRecognizedSchemaVersion(value));\r\n        m_schemaUri = ConfigurationSetParser::GetSchemaUriForVersion(value);\r\n        m_schemaVersion = value;\r\n    }\r\n\r\n    void ConfigurationSet::ConfigurationSetChange(com_ptr<ConfigurationSetChangeData>& data, const std::optional<guid>& unitInstanceIdentifier) try\r\n    {\r\n        if (unitInstanceIdentifier)\r\n        {\r\n            Windows::Foundation::Collections::IVector<ConfigurationUnit> comUnits = m_units;\r\n\r\n            std::vector<ConfigurationUnit> units{ comUnits.Size() };\r\n            units.resize(comUnits.GetMany(0, units));\r\n\r\n            for (const ConfigurationUnit& unit : units)\r\n            {\r\n                if (unit.InstanceIdentifier() == unitInstanceIdentifier.value())\r\n                {\r\n                    data->Unit(unit);\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n\r\n        m_configurationSetChange(*get_strong(), *data);\r\n    }\r\n    CATCH_LOG();\r\n\r\n    event_token ConfigurationSet::ConfigurationSetChange(const Windows::Foundation::TypedEventHandler<WinRT_Self, Configuration::ConfigurationSetChangeData>& handler)\r\n    {\r\n        if (!m_configurationSetChange)\r\n        {\r\n            auto status = ConfigurationStatus::Instance();\r\n            std::atomic_store(&m_setChangeRegistration, status->RegisterForSetChange(*this));\r\n        }\r\n\r\n        return m_configurationSetChange.add(handler);\r\n    }\r\n\r\n    void ConfigurationSet::ConfigurationSetChange(const event_token& token) noexcept\r\n    {\r\n        m_configurationSetChange.remove(token);\r\n\r\n        if (!m_configurationSetChange)\r\n        {\r\n            std::atomic_store(&m_setChangeRegistration, {});\r\n        }\r\n    }\r\n\r\n    void ConfigurationSet::Serialize(const Windows::Storage::Streams::IOutputStream& stream)\r\n    {\r\n        std::unique_ptr<ConfigurationSetSerializer> serializer = ConfigurationSetSerializer::CreateSerializer(m_schemaVersion);\r\n        hstring result = serializer->Serialize(this);\r\n        auto resultUtf8 = winrt::to_string(result);\r\n        std::vector<uint8_t> bytes(resultUtf8.begin(), resultUtf8.end());\r\n\r\n        Windows::Storage::Streams::DataWriter dataWriter{ stream };\r\n        dataWriter.WriteBytes(bytes);\r\n        dataWriter.StoreAsync().get();\r\n        dataWriter.DetachStream();\r\n    }\r\n\r\n    void ConfigurationSet::Remove()\r\n    {\r\n        ConfigurationDatabase database;\r\n        database.EnsureOpened(false);\r\n        database.RemoveSetHistory(*get_strong());\r\n    }\r\n\r\n    Windows::Foundation::Collections::ValueSet ConfigurationSet::Metadata()\r\n    {\r\n        return m_metadata;\r\n    }\r\n\r\n    void ConfigurationSet::Metadata(const Windows::Foundation::Collections::ValueSet& value)\r\n    {\r\n        THROW_HR_IF(E_POINTER, !value);\r\n        m_metadata = value;\r\n    }\r\n\r\n    Windows::Foundation::Collections::IVector<ConfigurationParameter> ConfigurationSet::Parameters()\r\n    {\r\n        return m_parameters;\r\n    }\r\n\r\n    void ConfigurationSet::Parameters(const Windows::Foundation::Collections::IVector<ConfigurationParameter>& value)\r\n    {\r\n        THROW_HR_IF(E_POINTER, !value);\r\n        m_parameters = value;\r\n    }\r\n\r\n    Windows::Foundation::Collections::ValueSet ConfigurationSet::Variables()\r\n    {\r\n        return m_variables;\r\n    }\r\n\r\n    void ConfigurationSet::Variables(const Windows::Foundation::Collections::ValueSet& value)\r\n    {\r\n        THROW_HR_IF(E_POINTER, !value);\r\n        m_variables = value;\r\n    }\r\n\r\n    Windows::Foundation::Uri ConfigurationSet::SchemaUri()\r\n    {\r\n        return m_schemaUri;\r\n    }\r\n\r\n    void ConfigurationSet::SchemaUri(const Windows::Foundation::Uri& value)\r\n    {\r\n        THROW_HR_IF(E_INVALIDARG, !ConfigurationSetParser::IsRecognizedSchemaUri(value));\r\n        m_schemaVersion = ConfigurationSetParser::GetSchemaVersionForUri(value);\r\n        m_schemaUri = value;\r\n    }\r\n\r\n    Configuration::ConfigurationEnvironment ConfigurationSet::Environment()\r\n    {\r\n        return *m_environment;\r\n    }\r\n\r\n    implementation::ConfigurationEnvironment& ConfigurationSet::EnvironmentInternal()\r\n    {\r\n        return *m_environment;\r\n    }\r\n\r\n    std::vector<Configuration::ConfigurationEnvironment> ConfigurationSet::GetUnitEnvironmentsInternal()\r\n    {\r\n        std::vector<impl::EnvironmentData> uniqueEnvironments;\r\n        ComputeUniqueEnvironments(uniqueEnvironments, m_units);\r\n\r\n        std::vector<Configuration::ConfigurationEnvironment> result;\r\n        for (const impl::EnvironmentData& data : uniqueEnvironments)\r\n        {\r\n            result.emplace_back(*make_self<implementation::ConfigurationEnvironment>(data.Environment));\r\n        }\r\n        return result;\r\n    }\r\n\r\n    Windows::Foundation::Collections::IVector<Configuration::ConfigurationEnvironment> ConfigurationSet::GetUnitEnvironments()\r\n    {\r\n        return single_threaded_vector(GetUnitEnvironmentsInternal());\r\n    }\r\n\r\n    HRESULT STDMETHODCALLTYPE ConfigurationSet::SetLifetimeWatcher(IUnknown* watcher)\r\n    {\r\n        return AppInstaller::WinRT::LifetimeWatcherBase::SetLifetimeWatcher(watcher);\r\n    }\r\n\r\n    void ConfigurationSet::SetInputHash(std::string inputHash)\r\n    {\r\n        m_inputHash = std::move(inputHash);\r\n    }\r\n\r\n    const std::string& ConfigurationSet::GetInputHash() const\r\n    {\r\n        return m_inputHash;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationSet.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ConfigurationSet.g.h\"\r\n#include \"ConfigurationEnvironment.h\"\r\n#include \"ConfigurationSetChangeData.h\"\r\n#include \"ConfigurationStatus.h\"\r\n#include <winget/ILifetimeWatcher.h>\r\n#include <winget/ModuleCountBase.h>\r\n#include <winrt/Windows.Foundation.h>\r\n#include <winrt/Windows.Foundation.Collections.h>\r\n#include <vector>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    struct ConfigurationSet : ConfigurationSetT<ConfigurationSet, winrt::cloaked<AppInstaller::WinRT::ILifetimeWatcher>>, AppInstaller::WinRT::LifetimeWatcherBase, AppInstaller::WinRT::ModuleCountBase\r\n    {\r\n        using WinRT_Self = ::winrt::Microsoft::Management::Configuration::ConfigurationSet;\r\n        using ConfigurationUnit = ::winrt::Microsoft::Management::Configuration::ConfigurationUnit;\r\n        using ConfigurationParameter = ::winrt::Microsoft::Management::Configuration::ConfigurationParameter;\r\n\r\n        ConfigurationSet();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        ConfigurationSet(const guid& instanceIdentifier);\r\n        void Units(std::vector<Configuration::ConfigurationUnit>&& units);\r\n        void Parameters(std::vector<Configuration::ConfigurationParameter>&& value);\r\n        void ConfigurationSetChange(com_ptr<ConfigurationSetChangeData>& data, const std::optional<guid>& unitInstanceIdentifier);\r\n        implementation::ConfigurationEnvironment& EnvironmentInternal();\r\n        std::vector<Configuration::ConfigurationEnvironment> GetUnitEnvironmentsInternal();\r\n#endif\r\n\r\n        hstring Name();\r\n        void Name(const hstring& value);\r\n\r\n        hstring Origin();\r\n        void Origin(const hstring& value);\r\n\r\n        hstring Path();\r\n        void Path(const hstring& value);\r\n\r\n        guid InstanceIdentifier() const;\r\n        ConfigurationSetState State();\r\n        clock::time_point FirstApply();\r\n        clock::time_point ApplyBegun();\r\n        clock::time_point ApplyEnded();\r\n\r\n        Windows::Foundation::Collections::IVector<ConfigurationUnit> Units();\r\n        void Units(const Windows::Foundation::Collections::IVector<ConfigurationUnit>& value);\r\n\r\n        hstring SchemaVersion();\r\n        void SchemaVersion(const hstring& value);\r\n\r\n        event_token ConfigurationSetChange(const Windows::Foundation::TypedEventHandler<WinRT_Self, Configuration::ConfigurationSetChangeData>& handler);\r\n        void ConfigurationSetChange(const event_token& token) noexcept;\r\n\r\n        void Serialize(const Windows::Storage::Streams::IOutputStream& stream);\r\n\r\n        void Remove();\r\n\r\n        Windows::Foundation::Collections::ValueSet Metadata();\r\n        void Metadata(const Windows::Foundation::Collections::ValueSet& value);\r\n\r\n        Windows::Foundation::Collections::IVector<ConfigurationParameter> Parameters();\r\n        void Parameters(const Windows::Foundation::Collections::IVector<ConfigurationParameter>& value);\r\n\r\n        Windows::Foundation::Collections::ValueSet Variables();\r\n        void Variables(const Windows::Foundation::Collections::ValueSet& value);\r\n\r\n        Windows::Foundation::Uri SchemaUri();\r\n        void SchemaUri(const Windows::Foundation::Uri& value);\r\n\r\n        Configuration::ConfigurationEnvironment Environment();\r\n\r\n        Windows::Foundation::Collections::IVector<Configuration::ConfigurationEnvironment> GetUnitEnvironments();\r\n\r\n        HRESULT STDMETHODCALLTYPE SetLifetimeWatcher(IUnknown* watcher);\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        void SetInputHash(std::string inputHash);\r\n        const std::string& GetInputHash() const;\r\n\r\n    private:\r\n        hstring m_name;\r\n        hstring m_origin;\r\n        hstring m_path;\r\n        guid m_instanceIdentifier;\r\n        clock::time_point m_firstApply{};\r\n        Windows::Foundation::Collections::IVector<ConfigurationUnit> m_units{ winrt::multi_threaded_vector<ConfigurationUnit>() };\r\n        hstring m_schemaVersion;\r\n        winrt::event<Windows::Foundation::TypedEventHandler<WinRT_Self, Configuration::ConfigurationSetChangeData>> m_configurationSetChange;\r\n        Windows::Foundation::Collections::ValueSet m_metadata;\r\n        Windows::Foundation::Collections::IVector<ConfigurationParameter> m_parameters{ winrt::multi_threaded_vector<ConfigurationParameter>() };\r\n        Windows::Foundation::Collections::ValueSet m_variables;\r\n        Windows::Foundation::Uri m_schemaUri = nullptr;\r\n        std::string m_inputHash;\r\n        std::shared_ptr<ConfigurationStatus::SetChangeRegistration> m_setChangeRegistration;\r\n        com_ptr<implementation::ConfigurationEnvironment> m_environment{ make_self<implementation::ConfigurationEnvironment>() };\r\n#endif\r\n    };\r\n}\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\nnamespace winrt::Microsoft::Management::Configuration::factory_implementation\r\n{\r\n    struct ConfigurationSet : ConfigurationSetT<ConfigurationSet, implementation::ConfigurationSet>\r\n    {\r\n    };\r\n}\r\n#endif\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigurationSetApplyProcessor.h\"\r\n#include \"ConfigurationSetChangeData.h\"\r\n#include \"ExceptionResultHelpers.h\"\r\n\r\n#include <AppInstallerErrors.h>\r\n#include <AppInstallerLogging.h>\r\n#include <AppInstallerStrings.h>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    namespace\r\n    {\r\n        constexpr std::wstring_view s_ResourceType_RunCommandOnSet = L\"Microsoft.DSC.Transitional/RunCommandOnSet\";\r\n\r\n        std::string GetNormalizedIdentifier(hstring identifier)\r\n        {\r\n            using namespace AppInstaller::Utility;\r\n            return FoldCase(NormalizedString{ identifier });\r\n        }\r\n\r\n        bool AssertFilter(ConfigurationUnitIntent intent)\r\n        {\r\n            return intent == ConfigurationUnitIntent::Assert;\r\n        }\r\n\r\n        bool InformFilter(ConfigurationUnitIntent intent)\r\n        {\r\n            return intent == ConfigurationUnitIntent::Inform;\r\n        }\r\n\r\n        bool ApplyFilter(ConfigurationUnitIntent intent)\r\n        {\r\n            return intent == ConfigurationUnitIntent::Apply || intent == ConfigurationUnitIntent::Unknown;\r\n        }\r\n\r\n        // Check if a unit should always be applied. No TestSettings is needed.\r\n        bool ShouldApplyAlways(const Configuration::ConfigurationUnit& unit)\r\n        {\r\n            if (AppInstaller::Utility::CaseInsensitiveEquals(s_ResourceType_RunCommandOnSet, unit.Type()))\r\n            {\r\n                return true;\r\n            }\r\n\r\n            return false;\r\n        }\r\n    }\r\n\r\n    ConfigurationSetApplyProcessor::ConfigurationSetApplyProcessor(\r\n        const Configuration::ConfigurationSet& configurationSet,\r\n        IConfigurationSetProcessor setProcessor,\r\n        progress_type&& progress) :\r\n            m_configurationSet(configurationSet),\r\n            m_setProcessor(std::move(setProcessor)),\r\n            m_result(make_self<wil::details::module_count_wrapper<implementation::ApplyGroupSettingsResult>>()),\r\n            m_progress(std::move(progress))\r\n    {\r\n        // Create a copy of the set of configuration units\r\n        auto unitsView = configurationSet.Units();\r\n        std::vector<ConfigurationUnit> unitsToProcess{ unitsView.Size() };\r\n        unitsView.GetMany(0, unitsToProcess);\r\n\r\n        // Create the unit info vector from these units\r\n        for (const auto& unit : unitsToProcess)\r\n        {\r\n            m_unitInfo.emplace_back(unit);\r\n            m_result->UnitResults().Append(*m_unitInfo.back().Result);\r\n        }\r\n\r\n        m_progress.Result(*m_result);\r\n    }\r\n\r\n    void ConfigurationSetApplyProcessor::Process(bool preProcessOnly)\r\n    {\r\n        if (PreProcess() && !preProcessOnly)\r\n        {\r\n            ProcessInternal(HasProcessedSuccessfully, &ConfigurationSetApplyProcessor::ProcessUnit, true);\r\n        }\r\n    }\r\n\r\n    IApplyGroupSettingsResult ConfigurationSetApplyProcessor::Result() const\r\n    {\r\n        return *m_result;\r\n    }\r\n\r\n    ConfigurationSetApplyProcessor::UnitInfo::UnitInfo(const Configuration::ConfigurationUnit& unit) :\r\n        Unit(unit), Result(make_self<wil::details::module_count_wrapper<implementation::ApplyConfigurationUnitResult>>())\r\n    {\r\n        Result->Unit(unit);\r\n        ResultInformation = Result->ResultInformationInternal();\r\n    }\r\n\r\n    bool ConfigurationSetApplyProcessor::PreProcess()\r\n    {\r\n        bool result = true;\r\n\r\n        for (size_t i = 0; i < m_unitInfo.size(); ++i)\r\n        {\r\n            if (!AddUnitToMap(m_unitInfo[i], i))\r\n            {\r\n                result = false;\r\n            }\r\n        }\r\n\r\n        if (!result)\r\n        {\r\n            // This is the only error that adding to the map can produce\r\n            m_result->ResultInformationInternal()->ResultCode(WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER);\r\n            return false;\r\n        }\r\n\r\n        for (UnitInfo& unitInfo : m_unitInfo)\r\n        {\r\n            for (hstring dependencyHstring : unitInfo.Unit.Dependencies())\r\n            {\r\n                // Throw out empty dependency strings\r\n                if (dependencyHstring.empty())\r\n                {\r\n                    continue;\r\n                }\r\n\r\n                std::string dependency = GetNormalizedIdentifier(dependencyHstring);\r\n                auto itr = m_idToUnitInfoIndex.find(dependency);\r\n                if (itr == m_idToUnitInfoIndex.end())\r\n                {\r\n                    AICLI_LOG(Config, Error, << \"Found missing dependency: \" << dependency);\r\n                    unitInfo.ResultInformation->Initialize(WINGET_CONFIG_ERROR_MISSING_DEPENDENCY, ConfigurationUnitResultSource::ConfigurationSet);\r\n                    unitInfo.ResultInformation->Details(dependencyHstring);\r\n                    SendProgress(ConfigurationUnitState::Completed, unitInfo);\r\n                    result = false;\r\n                    // TODO: Consider collecting all missing dependencies, for now just the first\r\n                    break;\r\n                }\r\n                else\r\n                {\r\n                    unitInfo.DependencyIndices.emplace_back(itr->second);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (!result)\r\n        {\r\n            // This is the only error that adding to the map can produce\r\n            m_result->ResultInformationInternal()->ResultCode(WINGET_CONFIG_ERROR_MISSING_DEPENDENCY);\r\n            return false;\r\n        }\r\n\r\n        if (!ProcessInternal(HasPreprocessed, &ConfigurationSetApplyProcessor::MarkPreprocessed))\r\n        {\r\n            // The preprocessing simulates processing as if every unit run was successful.\r\n            // If it fails, this means that there are unit definitions whose dependencies cannot be satisfied.\r\n            // The only reason for that is a cycle in the dependency graph somewhere.\r\n            m_result->ResultInformationInternal()->ResultCode(WINGET_CONFIG_ERROR_SET_DEPENDENCY_CYCLE);\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    bool ConfigurationSetApplyProcessor::AddUnitToMap(UnitInfo& unitInfo, size_t unitInfoIndex)\r\n    {\r\n        hstring originalIdentifier = unitInfo.Unit.Identifier();\r\n        if (originalIdentifier.empty())\r\n        {\r\n            return true;\r\n        }\r\n\r\n        std::string identifier = GetNormalizedIdentifier(originalIdentifier);\r\n\r\n        auto itr = m_idToUnitInfoIndex.find(identifier);\r\n        if (itr != m_idToUnitInfoIndex.end())\r\n        {\r\n            AICLI_LOG(Config, Error, << \"Found duplicate identifier: \" << identifier);\r\n            // Found a duplicate identifier, mark both as such\r\n            m_unitInfo[itr->second].ResultInformation->Initialize(WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER, ConfigurationUnitResultSource::ConfigurationSet);\r\n            SendProgressIfNotComplete(ConfigurationUnitState::Completed, m_unitInfo[itr->second]);\r\n            unitInfo.ResultInformation->Initialize(WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER, ConfigurationUnitResultSource::ConfigurationSet);\r\n            SendProgress(ConfigurationUnitState::Completed, unitInfo);\r\n            return false;\r\n        }\r\n        else\r\n        {\r\n            m_idToUnitInfoIndex.emplace(std::move(identifier), unitInfoIndex);\r\n            return true;\r\n        }\r\n    }\r\n\r\n    bool ConfigurationSetApplyProcessor::ProcessInternal(CheckDependencyPtr checkDependencyFunction, ProcessUnitPtr processUnitFunction, bool sendProgress)\r\n    {\r\n        // Create the set of units that need to be processed\r\n        std::vector<size_t> unitsToProcess;\r\n        for (size_t i = 0, size = m_unitInfo.size(); i < size; ++i)\r\n        {\r\n            unitsToProcess.emplace_back(i);\r\n        }\r\n\r\n        // Always process all ConfigurationUnitIntent::Assert first\r\n        if (!ProcessIntentInternal(\r\n            unitsToProcess,\r\n            checkDependencyFunction,\r\n            processUnitFunction,\r\n            AssertFilter,\r\n            WINGET_CONFIG_ERROR_ASSERTION_FAILED,\r\n            WINGET_CONFIG_ERROR_ASSERTION_FAILED,\r\n            sendProgress))\r\n        {\r\n            return false;\r\n        }\r\n\r\n        // Then all ConfigurationUnitIntent::Inform\r\n        if (!ProcessIntentInternal(\r\n            unitsToProcess,\r\n            checkDependencyFunction,\r\n            processUnitFunction,\r\n            InformFilter,\r\n            WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED,\r\n            WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED,\r\n            sendProgress))\r\n        {\r\n            return false;\r\n        }\r\n\r\n        // Then all ConfigurationUnitIntent::Apply\r\n        return ProcessIntentInternal(\r\n            unitsToProcess,\r\n            checkDependencyFunction,\r\n            processUnitFunction,\r\n            ApplyFilter,\r\n            E_FAIL, // This should not happen as there are no other intents left\r\n            WINGET_CONFIG_ERROR_SET_APPLY_FAILED,\r\n            sendProgress);\r\n    }\r\n\r\n    bool ConfigurationSetApplyProcessor::ProcessIntentInternal(\r\n        std::vector<size_t>& unitsToProcess,\r\n        CheckDependencyPtr checkDependencyFunction,\r\n        ProcessUnitPtr processUnitFunction,\r\n        IntentFilterPtr intentFilter,\r\n        hresult errorForOtherIntents,\r\n        hresult errorForFailures,\r\n        bool sendProgress)\r\n    {\r\n        // Always process the first item in the list that is available to be processed\r\n        bool hasProcessed = true;\r\n        bool hasFailure = false;\r\n        while (hasProcessed)\r\n        {\r\n            hasProcessed = false;\r\n            for (auto itr = unitsToProcess.begin(), end = unitsToProcess.end(); itr != end; ++itr)\r\n            {\r\n                UnitInfo& unitInfo = m_unitInfo[*itr];\r\n                if (HasIntentAndSatisfiedDependencies(unitInfo, intentFilter, checkDependencyFunction))\r\n                {\r\n                    if (!(this->*processUnitFunction)(unitInfo))\r\n                    {\r\n                        hasFailure = true;\r\n                    }\r\n                    unitsToProcess.erase(itr);\r\n                    hasProcessed = true;\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n\r\n        // Mark all remaining items with intent as failed due to dependency\r\n        bool hasRemainingDependencies = false;\r\n        for (size_t index : unitsToProcess)\r\n        {\r\n            UnitInfo& unitInfo = m_unitInfo[index];\r\n            if (intentFilter(unitInfo.Unit.Intent()))\r\n            {\r\n                hasRemainingDependencies = true;\r\n                unitInfo.ResultInformation->Initialize(WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED, ConfigurationUnitResultSource::Precondition);\r\n                if (sendProgress)\r\n                {\r\n                    SendProgress(ConfigurationUnitState::Skipped, unitInfo);\r\n                }\r\n            }\r\n        }\r\n\r\n        // Any failures are fatal, mark all other units as failed due to that\r\n        if (hasFailure || hasRemainingDependencies)\r\n        {\r\n            for (size_t index : unitsToProcess)\r\n            {\r\n                UnitInfo& unitInfo = m_unitInfo[index];\r\n                if (!intentFilter(unitInfo.Unit.Intent()))\r\n                {\r\n                    unitInfo.ResultInformation->Initialize(errorForOtherIntents, ConfigurationUnitResultSource::Precondition);\r\n                    if (sendProgress)\r\n                    {\r\n                        SendProgress(ConfigurationUnitState::Skipped, unitInfo);\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (hasFailure)\r\n            {\r\n                m_result->ResultInformationInternal()->ResultCode(errorForFailures);\r\n            }\r\n            else // hasRemainingDependencies\r\n            {\r\n                m_result->ResultInformationInternal()->ResultCode(WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED);\r\n            }\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    bool ConfigurationSetApplyProcessor::HasIntentAndSatisfiedDependencies(\r\n        const UnitInfo& unitInfo,\r\n        IntentFilterPtr intentFilter,\r\n        CheckDependencyPtr checkDependencyFunction) const\r\n    {\r\n        bool result = false;\r\n\r\n        if (intentFilter(unitInfo.Unit.Intent()))\r\n        {\r\n            result = true;\r\n            for (size_t dependencyIndex : unitInfo.DependencyIndices)\r\n            {\r\n                if (!checkDependencyFunction(m_unitInfo[dependencyIndex]))\r\n                {\r\n                    result = false;\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    bool ConfigurationSetApplyProcessor::HasPreprocessed(const UnitInfo& unitInfo)\r\n    {\r\n        return unitInfo.PreProcessed;\r\n    }\r\n\r\n    bool ConfigurationSetApplyProcessor::MarkPreprocessed(UnitInfo& unitInfo)\r\n    {\r\n        unitInfo.PreProcessed = true;\r\n        return true;\r\n    }\r\n\r\n    bool ConfigurationSetApplyProcessor::HasProcessedSuccessfully(const UnitInfo& unitInfo)\r\n    {\r\n        return unitInfo.Processed && SUCCEEDED(unitInfo.ResultInformation->ResultCode());\r\n    }\r\n\r\n    bool ConfigurationSetApplyProcessor::ProcessUnit(UnitInfo& unitInfo)\r\n    {\r\n        m_progress.ThrowIfCancelled();\r\n\r\n        IConfigurationUnitProcessor unitProcessor;\r\n\r\n        // Once we get this far, consider the unit processed even if we fail to create the actual processor.\r\n        unitInfo.Processed = true;\r\n\r\n        if (!unitInfo.Unit.IsActive())\r\n        {\r\n            // If the unit is requested to be skipped, we mark it with a failure to prevent any dependency from running.\r\n            // But we return true from this function to indicate a successful \"processing\".\r\n            unitInfo.ResultInformation->Initialize(WINGET_CONFIG_ERROR_MANUALLY_SKIPPED, ConfigurationUnitResultSource::Precondition);\r\n            SendProgress(ConfigurationUnitState::Skipped, unitInfo);\r\n            return true;\r\n        }\r\n\r\n        // Send a progress event that we are starting, and prepare one for completion when we exit the function\r\n        SendProgress(ConfigurationUnitState::InProgress, unitInfo);\r\n        auto sendCompletedProgress = wil::scope_exit([this, &unitInfo]() { SendProgress(ConfigurationUnitState::Completed, unitInfo); });\r\n\r\n        try\r\n        {\r\n            unitProcessor = m_setProcessor.CreateUnitProcessor(unitInfo.Unit);\r\n        }\r\n        catch (...)\r\n        {\r\n            ExtractUnitResultInformation(std::current_exception(), unitInfo.ResultInformation);\r\n            return false;\r\n        }\r\n\r\n        // As the process of creating the unit processor could take a while, check for cancellation again\r\n        m_progress.ThrowIfCancelled();\r\n\r\n        bool result = false;\r\n\r\n        try\r\n        {\r\n            switch (unitInfo.Unit.Intent())\r\n            {\r\n            case ConfigurationUnitIntent::Assert:\r\n            {\r\n                ITestSettingsResult settingsResult = unitProcessor.TestSettings();\r\n\r\n                if (settingsResult.TestResult() == ConfigurationTestResult::Positive)\r\n                {\r\n                    result = true;\r\n                }\r\n                else if (settingsResult.TestResult() == ConfigurationTestResult::Negative)\r\n                {\r\n                    unitInfo.ResultInformation->Initialize(WINGET_CONFIG_ERROR_ASSERTION_FAILED, ConfigurationUnitResultSource::Precondition);\r\n                }\r\n                else if (settingsResult.TestResult() == ConfigurationTestResult::Failed)\r\n                {\r\n                    unitInfo.ResultInformation->Initialize(settingsResult.ResultInformation());\r\n                }\r\n                else\r\n                {\r\n                    unitInfo.ResultInformation->Initialize(E_UNEXPECTED, ConfigurationUnitResultSource::Internal);\r\n                }\r\n            }\r\n                break;\r\n\r\n            case ConfigurationUnitIntent::Inform:\r\n            {\r\n                // Force the processor to retrieve the settings\r\n                IGetSettingsResult settingsResult = unitProcessor.GetSettings();\r\n                if (SUCCEEDED(settingsResult.ResultInformation().ResultCode()))\r\n                {\r\n                    result = true;\r\n                }\r\n                else\r\n                {\r\n                    unitInfo.ResultInformation->Initialize(settingsResult.ResultInformation());\r\n                }\r\n            }\r\n                break;\r\n\r\n            case ConfigurationUnitIntent::Apply:\r\n            case ConfigurationUnitIntent::Unknown:\r\n            {\r\n                // Check for a group processor and let it do the work if present\r\n                IConfigurationGroupProcessor groupProcessor = unitProcessor.try_as<IConfigurationGroupProcessor>();\r\n\r\n                if (groupProcessor)\r\n                {\r\n                    auto applyOperation = groupProcessor.ApplyGroupSettingsAsync([&](const auto&, const IApplyGroupMemberSettingsResult& unitResult)\r\n                        {\r\n                            m_progress.Progress(unitResult);\r\n                        });\r\n\r\n                    // Cancel the inner operation if we are cancelled\r\n                    m_progress.Callback([applyOperation]() { applyOperation.Cancel(); });\r\n\r\n                    IApplyGroupSettingsResult groupResult = applyOperation.get();\r\n\r\n                    // Put all of the group's unit results in our unit results\r\n                    bool groupPreviouslyInDesiredState = true;\r\n\r\n                    for (const auto& groupUnitResult : groupResult.UnitResults())\r\n                    {\r\n                        m_result->UnitResults().Append(groupUnitResult);\r\n                        groupPreviouslyInDesiredState = groupPreviouslyInDesiredState && groupUnitResult.PreviouslyInDesiredState();\r\n                    }\r\n\r\n                    // Copy the group result into the existing unit result for the group\r\n                    unitInfo.Result->PreviouslyInDesiredState(groupPreviouslyInDesiredState);\r\n                    unitInfo.ResultInformation->Initialize(groupResult.ResultInformation());\r\n\r\n                    if (SUCCEEDED(unitInfo.ResultInformation->ResultCode()))\r\n                    {\r\n                        unitInfo.Result->RebootRequired(groupResult.RebootRequired());\r\n                        result = true;\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    ITestSettingsResult testSettingsResult = nullptr;\r\n                    bool applyAlways = ShouldApplyAlways(unitProcessor.Unit());\r\n\r\n                    if (!applyAlways)\r\n                    {\r\n                        testSettingsResult = unitProcessor.TestSettings();\r\n                    }\r\n\r\n                    if (applyAlways || testSettingsResult.TestResult() == ConfigurationTestResult::Negative)\r\n                    {\r\n                        // Just in case testing took a while, check for cancellation before moving on to applying\r\n                        m_progress.ThrowIfCancelled();\r\n\r\n                        IApplySettingsResult applySettingsResult = unitProcessor.ApplySettings();\r\n                        if (SUCCEEDED(applySettingsResult.ResultInformation().ResultCode()))\r\n                        {\r\n                            unitInfo.Result->RebootRequired(applySettingsResult.RebootRequired());\r\n                            result = true;\r\n                        }\r\n                        else\r\n                        {\r\n                            unitInfo.ResultInformation->Initialize(applySettingsResult.ResultInformation());\r\n                        }\r\n                    }\r\n                    else if (testSettingsResult.TestResult() == ConfigurationTestResult::Positive)\r\n                    {\r\n                        unitInfo.Result->PreviouslyInDesiredState(true);\r\n                        result = true;\r\n                    }\r\n                    else if (testSettingsResult.TestResult() == ConfigurationTestResult::Failed)\r\n                    {\r\n                        unitInfo.ResultInformation->Initialize(testSettingsResult.ResultInformation());\r\n                    }\r\n                    else\r\n                    {\r\n                        unitInfo.ResultInformation->Initialize(E_UNEXPECTED, ConfigurationUnitResultSource::Internal);\r\n                    }\r\n                }\r\n            }\r\n                break;\r\n\r\n            default:\r\n                unitInfo.ResultInformation->Initialize(E_UNEXPECTED, ConfigurationUnitResultSource::Internal);\r\n                break;\r\n            }\r\n        }\r\n        catch (...)\r\n        {\r\n            ExtractUnitResultInformation(std::current_exception(), unitInfo.ResultInformation);\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    void ConfigurationSetApplyProcessor::SendProgress(ConfigurationUnitState state, const UnitInfo& unitInfo)\r\n    {\r\n        unitInfo.Result->State(state);\r\n\r\n        try\r\n        {\r\n            m_progress.Progress(*unitInfo.Result);\r\n        }\r\n        CATCH_LOG();\r\n    }\r\n\r\n    void ConfigurationSetApplyProcessor::SendProgressIfNotComplete(ConfigurationUnitState state, const UnitInfo& unitInfo)\r\n    {\r\n        if (unitInfo.Result->State() != ConfigurationUnitState::Completed)\r\n        {\r\n            SendProgress(state, unitInfo);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationSetApplyProcessor.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ConfigurationSet.h\"\r\n#include \"ConfigurationUnit.h\"\r\n#include \"ApplyGroupSettingsResult.h\"\r\n#include \"ApplyConfigurationUnitResult.h\"\r\n#include \"ConfigurationUnitResultInformation.h\"\r\n#include \"ShutdownSynchronization.h\"\r\n\r\n#include <map>\r\n#include <string>\r\n#include <vector>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    // A helper to better organize the configuration set Apply.\r\n    struct ConfigurationSetApplyProcessor\r\n    {\r\n        using ConfigurationSet = Configuration::ConfigurationSet;\r\n        using ConfigurationUnit = Configuration::ConfigurationUnit;\r\n        using ConfigurationSetChangeData = Configuration::ConfigurationSetChangeData;\r\n\r\n        using result_type = decltype(make_self<wil::details::module_count_wrapper<implementation::ApplyGroupSettingsResult>>());\r\n        using progress_type = ShutdownAwareAsyncProgress<IApplyGroupSettingsResult, IApplyGroupMemberSettingsResult>;\r\n\r\n        ConfigurationSetApplyProcessor(const ConfigurationSet& configurationSet, IConfigurationSetProcessor setProcessor, progress_type&& progress);\r\n\r\n        // Processes the apply for the configuration set.\r\n        void Process(bool preProcessOnly = false);\r\n\r\n        // Gets the result object.\r\n        IApplyGroupSettingsResult Result() const;\r\n\r\n    private:\r\n        // Contains all of the relevant data for a configuration unit.\r\n        struct UnitInfo\r\n        {\r\n            UnitInfo(const ConfigurationUnit& unit);\r\n\r\n            ConfigurationUnit Unit;\r\n            std::vector<size_t> DependencyIndices;\r\n            decltype(make_self<wil::details::module_count_wrapper<implementation::ApplyConfigurationUnitResult>>()) Result;\r\n            decltype(make_self<wil::details::module_count_wrapper<implementation::ConfigurationUnitResultInformation>>()) ResultInformation;\r\n            bool PreProcessed = false;\r\n            bool Processed = false;\r\n        };\r\n\r\n        // Builds out some data used during processing and validates the set along the way.\r\n        bool PreProcess();\r\n\r\n        // Adds the given unit to the identifier to unit info index map.\r\n        bool AddUnitToMap(UnitInfo& unitInfo, size_t unitInfoIndex);\r\n\r\n        // Checks the dependency; returns true to indicate that the dependency is satisfied, false if not.\r\n        using CheckDependencyPtr = bool (*)(const UnitInfo&);\r\n\r\n        // Processes the unit; returns true if successful, false if not.\r\n        using ProcessUnitPtr = bool (ConfigurationSetApplyProcessor::*)(UnitInfo&);\r\n\r\n        // Return true to process these intents, false to skip them.\r\n        using IntentFilterPtr = bool (*)(ConfigurationUnitIntent);\r\n\r\n        // Runs the processing using the given functions.\r\n        bool ProcessInternal(CheckDependencyPtr checkDependencyFunction, ProcessUnitPtr processUnitFunction, bool sendProgress = false);\r\n\r\n        // Processes one of the non-writing intent types, which are fatal if not all successful\r\n        bool ProcessIntentInternal(\r\n            std::vector<size_t>& unitsToProcess,\r\n            CheckDependencyPtr checkDependencyFunction,\r\n            ProcessUnitPtr processUnitFunction,\r\n            IntentFilterPtr intentFilter,\r\n            hresult errorForOtherIntents,\r\n            hresult errorForFailures,\r\n            bool sendProgress);\r\n\r\n        // Determines if the given unit has the given intent and all of its dependencies are satisfied\r\n        bool HasIntentAndSatisfiedDependencies(\r\n            const UnitInfo& unitInfo,\r\n            IntentFilterPtr intentFilter,\r\n            CheckDependencyPtr checkDependencyFunction) const;\r\n\r\n        // Checks a dependency for preprocessing.\r\n        static bool HasPreprocessed(const UnitInfo& unitInfo);\r\n\r\n        // Marks a unit as preprocessed.\r\n        bool MarkPreprocessed(UnitInfo& unitInfo);\r\n\r\n        // Checks a dependency for having processed successfully.\r\n        static bool HasProcessedSuccessfully(const UnitInfo& unitInfo);\r\n\r\n        // Processes a configuration unit per its intent.\r\n        bool ProcessUnit(UnitInfo& unitInfo);\r\n\r\n        // Sends progress\r\n        // TODO: Eventually these functions/call sites will be used for history\r\n        void SendProgress(ConfigurationUnitState state, const UnitInfo& unitInfo);\r\n        void SendProgressIfNotComplete(ConfigurationUnitState state, const UnitInfo& unitInfo);\r\n\r\n        ConfigurationSet m_configurationSet;\r\n        IConfigurationSetProcessor m_setProcessor;\r\n        result_type m_result;\r\n        progress_type m_progress;\r\n        std::vector<UnitInfo> m_unitInfo;\r\n        std::map<std::string, size_t> m_idToUnitInfoIndex;\r\n        hresult m_resultCode;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationSetChangeData.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigurationSetChangeData.h\"\r\n#include \"ConfigurationSetChangeData.g.cpp\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    Configuration::ConfigurationSetChangeData ConfigurationSetChangeData::Create(ConfigurationSetState state)\r\n    {\r\n        auto result = make_self<implementation::ConfigurationSetChangeData>();\r\n        result->Initialize(state);\r\n        return *result;\r\n    }\r\n\r\n    Configuration::ConfigurationSetChangeData ConfigurationSetChangeData::Create(ConfigurationUnitState state, IConfigurationUnitResultInformation resultInformation, ConfigurationUnit unit)\r\n    {\r\n        auto result = make_self<implementation::ConfigurationSetChangeData>();\r\n        result->Initialize(state, resultInformation, unit);\r\n        return *result;\r\n    }\r\n\r\n    void ConfigurationSetChangeData::Initialize(ConfigurationSetState state)\r\n    {\r\n        m_change = ConfigurationSetChangeEventType::SetStateChanged;\r\n        m_setState = state;\r\n    }\r\n\r\n    void ConfigurationSetChangeData::Initialize(ConfigurationUnitState state, IConfigurationUnitResultInformation resultInformation, ConfigurationUnit unit)\r\n    {\r\n        m_change = ConfigurationSetChangeEventType::UnitStateChanged;\r\n        m_setState = ConfigurationSetState::InProgress;\r\n        m_unitState = state;\r\n        m_resultInformation = resultInformation;\r\n        m_unit = unit;\r\n    }\r\n\r\n    void ConfigurationSetChangeData::Initialize(const IApplyGroupMemberSettingsResult& unitResult)\r\n    {\r\n        m_change = ConfigurationSetChangeEventType::UnitStateChanged;\r\n        m_setState = ConfigurationSetState::InProgress;\r\n        m_unitState = unitResult.State();\r\n        m_resultInformation = unitResult.ResultInformation();\r\n        m_unit = unitResult.Unit();\r\n    }\r\n\r\n    ConfigurationSetChangeEventType ConfigurationSetChangeData::Change()\r\n    {\r\n        return m_change;\r\n    }\r\n\r\n    ConfigurationSetState ConfigurationSetChangeData::SetState()\r\n    {\r\n        return m_setState;\r\n    }\r\n\r\n    ConfigurationUnitState ConfigurationSetChangeData::UnitState()\r\n    {\r\n        return m_unitState;\r\n    }\r\n\r\n    IConfigurationUnitResultInformation ConfigurationSetChangeData::ResultInformation()\r\n    {\r\n        return m_resultInformation;\r\n    }\r\n\r\n    ConfigurationUnit ConfigurationSetChangeData::Unit()\r\n    {\r\n        return m_unit;\r\n    }\r\n\r\n    void ConfigurationSetChangeData::Unit(const ConfigurationUnit& unit)\r\n    {\r\n        m_unit = unit;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationSetChangeData.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ConfigurationSetChangeData.g.h\"\r\n#include \"ConfigurationUnitResultInformation.h\"\r\n#include <winget/ModuleCountBase.h>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    struct ConfigurationSetChangeData : ConfigurationSetChangeDataT<ConfigurationSetChangeData>, AppInstaller::WinRT::ModuleCountBase\r\n    {\r\n        using ConfigurationUnit = Configuration::ConfigurationUnit;\r\n\r\n        ConfigurationSetChangeData() = default;\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        static Configuration::ConfigurationSetChangeData Create(ConfigurationSetState state);\r\n        static Configuration::ConfigurationSetChangeData Create(ConfigurationUnitState state, IConfigurationUnitResultInformation resultInformation, ConfigurationUnit unit);\r\n\r\n        void Initialize(ConfigurationSetState state);\r\n        void Initialize(ConfigurationUnitState state, IConfigurationUnitResultInformation resultInformation, ConfigurationUnit unit);\r\n        void Initialize(const IApplyGroupMemberSettingsResult& unitResult);\r\n\r\n        void Unit(const ConfigurationUnit& unit);\r\n#endif\r\n\r\n        ConfigurationSetChangeEventType Change();\r\n        ConfigurationSetState SetState();\r\n        ConfigurationUnitState UnitState();\r\n        IConfigurationUnitResultInformation ResultInformation();\r\n        ConfigurationUnit Unit();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        ConfigurationSetChangeEventType m_change = ConfigurationSetChangeEventType::Unknown;\r\n        ConfigurationSetState m_setState = ConfigurationSetState::Unknown;\r\n        ConfigurationUnitState m_unitState = ConfigurationUnitState::Unknown;\r\n        IConfigurationUnitResultInformation m_resultInformation;\r\n        ConfigurationUnit m_unit = nullptr;\r\n#endif\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationSetParser.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigurationSetParser.h\"\r\n#include \"ParsingMacros.h\"\r\n#include \"ArgumentValidation.h\"\r\n\r\n#include <AppInstallerErrors.h>\r\n#include <AppInstallerLogging.h>\r\n#include <AppInstallerStrings.h>\r\n#include <AppInstallerVersions.h>\r\n\r\n#include \"ConfigurationSetUtilities.h\"\r\n#include \"ConfigurationSetParserError.h\"\r\n#include \"ConfigurationSetParser_0_1.h\"\r\n#include \"ConfigurationSetParser_0_2.h\"\r\n#include \"ConfigurationSetParser_0_3.h\"\r\n\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::YAML;\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    namespace\r\n    {\r\n        struct SchemaVersionAndUri\r\n        {\r\n            std::string_view Version;\r\n            std::wstring_view VersionWide;\r\n            std::string_view Uri;\r\n            std::wstring_view UriWide;\r\n        };\r\n\r\n#define SCHEMA_VERSION_MAP_ITEM(_version_,_uri_) _version_, TEXT(_version_), _uri_, TEXT(_uri_)\r\n\r\n        // Please keep in sorted order with the highest version last.\r\n        // Duplicate URIs are supported, but duplicate versions are not. The highest version for a URI will be the one mapped to, the lower versions will be aliases.\r\n        SchemaVersionAndUri SchemaVersionAndUriMap[] =\r\n        {\r\n            { SCHEMA_VERSION_MAP_ITEM(\"0.1\", \"\") },\r\n            { SCHEMA_VERSION_MAP_ITEM(\"0.2\", \"\") },\r\n            { SCHEMA_VERSION_MAP_ITEM(\"0.3\", \"https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json\") },\r\n        };\r\n\r\n        Windows::Foundation::IInspectable GetIInspectableFromNode(const Node& node);\r\n\r\n        // Fills the ValueSet from the given node, which is assumed to be a map.\r\n        void FillValueSetFromMap(const Node& mapNode, const Windows::Foundation::Collections::ValueSet& valueSet)\r\n        {\r\n            for (const auto& mapItem : mapNode.Mapping())\r\n            {\r\n                // Insert returns true if it replaces an existing key, and that indicates an invalid map.\r\n                THROW_HR_IF(WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE, valueSet.Insert(mapItem.first.as<std::wstring>(), GetIInspectableFromNode(mapItem.second)));\r\n            }\r\n        }\r\n\r\n        // Returns the appropriate IPropertyValue for the given node, which is assumed to be a scalar.\r\n        Windows::Foundation::IInspectable GetPropertyValueFromScalar(const Node& node)\r\n        {\r\n            ::winrt::Windows::Foundation::IInspectable result;\r\n\r\n            switch (node.GetTagType())\r\n            {\r\n            case Node::TagType::Null:\r\n                return Windows::Foundation::PropertyValue::CreateEmpty();\r\n            case Node::TagType::Bool:\r\n                return Windows::Foundation::PropertyValue::CreateBoolean(node.as<bool>());\r\n            case Node::TagType::Str:\r\n                return Windows::Foundation::PropertyValue::CreateString(node.as<std::wstring>());\r\n            case Node::TagType::Int:\r\n                return Windows::Foundation::PropertyValue::CreateInt64(node.as<int64_t>());\r\n            case Node::TagType::Float:\r\n                THROW_HR(E_NOTIMPL);\r\n            case Node::TagType::Timestamp:\r\n                THROW_HR(E_NOTIMPL);\r\n            default:\r\n                THROW_HR(E_UNEXPECTED);\r\n            }\r\n        }\r\n\r\n        // Returns the appropriate IPropertyValue for the given node, which is assumed to be a scalar.\r\n        Windows::Foundation::IInspectable GetPropertyValueFromSequence(const Node& sequenceNode)\r\n        {\r\n            Windows::Foundation::Collections::ValueSet result;\r\n            size_t index = 0;\r\n\r\n            for (const Node& sequenceItem : sequenceNode.Sequence())\r\n            {\r\n                std::wostringstream strstr;\r\n                strstr << index++;\r\n                result.Insert(strstr.str(), GetIInspectableFromNode(sequenceItem));\r\n            }\r\n\r\n            result.Insert(L\"treatAsArray\", Windows::Foundation::PropertyValue::CreateBoolean(true));\r\n            return result;\r\n        }\r\n\r\n        // Returns the appropriate IInspectable for the given node.\r\n        Windows::Foundation::IInspectable GetIInspectableFromNode(const Node& node)\r\n        {\r\n            ::winrt::Windows::Foundation::IInspectable result;\r\n\r\n            switch (node.GetType())\r\n            {\r\n            case Node::Type::Invalid:\r\n            case Node::Type::None:\r\n                // Leave value as null\r\n                break;\r\n            case Node::Type::Scalar:\r\n                result = GetPropertyValueFromScalar(node);\r\n                break;\r\n            case Node::Type::Sequence:\r\n                result = GetPropertyValueFromSequence(node);\r\n                break;\r\n            case Node::Type::Mapping:\r\n            {\r\n                Windows::Foundation::Collections::ValueSet subset;\r\n                FillValueSetFromMap(node, subset);\r\n                result = std::move(subset);\r\n            }\r\n            break;\r\n            default:\r\n                THROW_HR(E_UNEXPECTED);\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        // Contains the qualified resource name information.\r\n        struct QualifiedResourceName\r\n        {\r\n            QualifiedResourceName(hstring input)\r\n            {\r\n                std::wstring_view inputView = input;\r\n                size_t pos = inputView.find('/');\r\n\r\n                if (pos != std::wstring_view::npos)\r\n                {\r\n                    Module = inputView.substr(0, pos);\r\n                    Resource = inputView.substr(pos + 1);\r\n                }\r\n                else\r\n                {\r\n                    Resource = input;\r\n                }\r\n            }\r\n\r\n            hstring Module;\r\n            hstring Resource;\r\n        };\r\n    }\r\n\r\n    std::unique_ptr<ConfigurationSetParser> ConfigurationSetParser::Create(std::string_view input)\r\n    {\r\n        AICLI_LOG_LARGE_STRING(Config, Verbose, << \"Parsing configuration set:\", input);\r\n\r\n        Node document;\r\n        std::string documentError;\r\n        Mark documentErrorMark;\r\n\r\n        try\r\n        {\r\n            document = Load(input);\r\n        }\r\n        catch (const Exception& exc)\r\n        {\r\n            documentError = exc.what();\r\n            documentErrorMark = exc.GetMark();\r\n        }\r\n        CATCH_LOG();\r\n\r\n        if (!document.IsMap())\r\n        {\r\n            AICLI_LOG(Config, Error, << \"Invalid YAML: \" << documentError << \" at [line \" << documentErrorMark.line << \", col \" << documentErrorMark.column << \"]\");\r\n            return std::make_unique<ConfigurationSetParserError>(WINGET_CONFIG_ERROR_INVALID_YAML, documentError, documentErrorMark);\r\n        }\r\n\r\n        // The schema version for parsing the rest of the document\r\n        std::string schemaUriString;\r\n        std::string schemaVersionString;\r\n\r\n        Node& schemaNode = document[GetConfigurationFieldName(ConfigurationField::Schema)];\r\n        if (schemaNode.IsScalar())\r\n        {\r\n            schemaUriString = schemaNode.as<std::string>();\r\n            schemaVersionString = GetSchemaVersionForUri(schemaUriString);\r\n            AICLI_LOG(Config, Verbose, << \"Configuration schema `\" << schemaNode.as<std::string>() << \"` mapped to version `\" << schemaVersionString << \"`.\");\r\n        }\r\n\r\n        // If we recognize the schema, use that version.\r\n        // If we didn't recognize it, try using the older format.\r\n        if (schemaVersionString.empty())\r\n        {\r\n            std::unique_ptr<ConfigurationSetParser> oldFormatError = GetSchemaVersionFromOldFormat(document, schemaVersionString);\r\n\r\n            // We have no schema version at all...\r\n            if (oldFormatError)\r\n            {\r\n                // If the schema was provided and we didn't recognize it, make that the error.\r\n                if (schemaNode.IsScalar())\r\n                {\r\n                    AICLI_LOG(Config, Error, << \"Unknown configuration schema: \" << schemaUriString);\r\n                    return std::make_unique<ConfigurationSetParserError>(WINGET_CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION, GetConfigurationFieldName(ConfigurationField::Schema), schemaUriString);\r\n                }\r\n                else\r\n                {\r\n                    // Otherwise, this is an older format file (or neither). The proper error came back from that function.\r\n                    return oldFormatError;\r\n                }\r\n            }\r\n        }\r\n\r\n        // Create the parser based on the version selected\r\n        auto result = CreateForSchemaVersion(std::move(schemaVersionString));\r\n        result->SetDocument(std::move(document));\r\n        return result;\r\n    }\r\n\r\n    std::unique_ptr<ConfigurationSetParser> ConfigurationSetParser::CreateForSchemaVersion(std::string input)\r\n    {\r\n        SemanticVersion schemaVersion(std::move(input));\r\n\r\n        // TODO: Consider having the version/uri/type information all together in the future\r\n        if (schemaVersion.PartAt(0).Integer == 0 && schemaVersion.PartAt(1).Integer == 1)\r\n        {\r\n            return std::make_unique<ConfigurationSetParser_0_1>();\r\n        }\r\n        else if (schemaVersion.PartAt(0).Integer == 0 && schemaVersion.PartAt(1).Integer == 2)\r\n        {\r\n            return std::make_unique<ConfigurationSetParser_0_2>();\r\n        }\r\n        else if (schemaVersion.PartAt(0).Integer == 0 && schemaVersion.PartAt(1).Integer == 3)\r\n        {\r\n            return std::make_unique<ConfigurationSetParser_0_3>();\r\n        }\r\n\r\n        AICLI_LOG(Config, Error, << \"Unknown configuration version: \" << schemaVersion.ToString());\r\n        return std::make_unique<ConfigurationSetParserError>(WINGET_CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION, GetConfigurationFieldName(ConfigurationField::ConfigurationVersion), schemaVersion.ToString());\r\n    }\r\n\r\n    bool ConfigurationSetParser::IsRecognizedSchemaVersion(hstring value) try\r\n    {\r\n        SemanticVersion schemaVersion(ConvertToUTF8(value));\r\n\r\n        for (const auto& item : SchemaVersionAndUriMap)\r\n        {\r\n            if (schemaVersion == SemanticVersion{ std::string{ item.Version } })\r\n            {\r\n                return true;\r\n            }\r\n        }\r\n\r\n        return false;\r\n    }\r\n    catch (...) { LOG_CAUGHT_EXCEPTION(); return false; }\r\n\r\n    bool ConfigurationSetParser::IsRecognizedSchemaUri(const Windows::Foundation::Uri& value)\r\n    {\r\n        return !GetSchemaVersionForUri(value).empty();\r\n    }\r\n\r\n    Windows::Foundation::Uri ConfigurationSetParser::GetSchemaUriForVersion(hstring value)\r\n    {\r\n        for (const auto& item : SchemaVersionAndUriMap)\r\n        {\r\n            if (value == item.VersionWide)\r\n            {\r\n                return item.Uri.empty() ? nullptr : Windows::Foundation::Uri{ item.UriWide };\r\n            }\r\n        }\r\n\r\n        return nullptr;\r\n    }\r\n\r\n    hstring ConfigurationSetParser::GetSchemaVersionForUri(Windows::Foundation::Uri value)\r\n    {\r\n        // Do a reverse search in order to give the highest version back for a given URI.\r\n        auto itr = std::rbegin(SchemaVersionAndUriMap);\r\n        auto end = std::rend(SchemaVersionAndUriMap);\r\n        for (; itr != end; ++itr)\r\n        {\r\n            const auto& item = *itr;\r\n            if (!item.Uri.empty())\r\n            {\r\n                Windows::Foundation::Uri uri{ item.UriWide };\r\n                if (value.Equals(uri))\r\n                {\r\n                    return hstring{ item.VersionWide };\r\n                }\r\n            }\r\n        }\r\n\r\n        return {};\r\n    }\r\n\r\n    std::string ConfigurationSetParser::GetSchemaVersionForUri(std::string_view value)\r\n    {\r\n        // Do a reverse search in order to give the highest version back for a given URI.\r\n        auto itr = std::rbegin(SchemaVersionAndUriMap);\r\n        auto end = std::rend(SchemaVersionAndUriMap);\r\n        for (; itr != end; ++itr)\r\n        {\r\n            const auto& item = *itr;\r\n            if (!item.Uri.empty())\r\n            {\r\n                if (item.Uri == value)\r\n                {\r\n                    return std::string{ item.Version };\r\n                }\r\n            }\r\n        }\r\n\r\n        return {};\r\n    }\r\n\r\n    std::pair<hstring, Windows::Foundation::Uri> ConfigurationSetParser::LatestVersion()\r\n    {\r\n        auto latest = std::rbegin(SchemaVersionAndUriMap);\r\n        return { hstring{ latest->VersionWide }, Windows::Foundation::Uri{ latest->UriWide } };\r\n    }\r\n\r\n    Windows::Foundation::Collections::ValueSet ConfigurationSetParser::ParseValueSet(std::string_view input)\r\n    {\r\n        Windows::Foundation::Collections::ValueSet result;\r\n        FillValueSetFromMap(Load(input), result);\r\n        return result;\r\n    }\r\n\r\n    std::vector<hstring> ConfigurationSetParser::ParseStringArray(std::string_view input)\r\n    {\r\n        std::vector<hstring> result;\r\n        ParseSequence(Load(input), \"string_array\", Node::Type::Scalar, [&](const AppInstaller::YAML::Node& item)\r\n        {\r\n            result.emplace_back(item.as<std::wstring>());\r\n        });\r\n        return result;\r\n    }\r\n\r\n    void ConfigurationSetParser::SetError(hresult result, std::string_view field, std::string_view value, uint32_t line, uint32_t column)\r\n    {\r\n        AICLI_LOG(Config, Error, << \"ConfigurationSetParser error: \" << AppInstaller::Logging::SetHRFormat << result << \" for \" << field << \" with value `\" << value << \"` at [line \" << line << \", col \" << column << \"]\");\r\n        m_result = result;\r\n        m_field = ConvertToUTF16(field);\r\n        m_value = ConvertToUTF16(value);\r\n        m_line = line;\r\n        m_column = column;\r\n    }\r\n\r\n    void ConfigurationSetParser::SetError(hresult result, std::string_view field, const Mark& mark, std::string_view value)\r\n    {\r\n        SetError(result, field, value, static_cast<uint32_t>(mark.line), static_cast<uint32_t>(mark.column));\r\n    }\r\n\r\n    const Node& ConfigurationSetParser::GetAndEnsureField(const Node& parent, ConfigurationField field, bool required, std::optional<Node::Type> type)\r\n    {\r\n        const Node& fieldNode = parent[GetConfigurationFieldName(field)];\r\n\r\n        if (fieldNode)\r\n        {\r\n            if (type && fieldNode.GetType() != type.value())\r\n            {\r\n                SetError(WINGET_CONFIG_ERROR_INVALID_FIELD_TYPE, GetConfigurationFieldName(field), fieldNode.Mark());\r\n            }\r\n        }\r\n        else if (required)\r\n        {\r\n            SetError(WINGET_CONFIG_ERROR_MISSING_FIELD, GetConfigurationFieldName(field));\r\n        }\r\n\r\n        return fieldNode;\r\n    }\r\n\r\n    void ConfigurationSetParser::EnsureFieldAbsent(const Node& parent, ConfigurationField field)\r\n    {\r\n        const Node& fieldNode = parent[GetConfigurationFieldName(field)];\r\n\r\n        if (fieldNode)\r\n        {\r\n            SetError(WINGET_CONFIG_ERROR_INVALID_FIELD_VALUE, GetConfigurationFieldName(field), fieldNode.Mark(), fieldNode.as<std::string>());\r\n        }\r\n    }\r\n\r\n    void ConfigurationSetParser::ParseValueSet(const Node& node, ConfigurationField field, bool required, const Windows::Foundation::Collections::ValueSet& valueSet)\r\n    {\r\n        const Node& mapNode = CHECK_ERROR(GetAndEnsureField(node, field, required, Node::Type::Mapping));\r\n\r\n        if (mapNode)\r\n        {\r\n            FillValueSetFromMap(mapNode, valueSet);\r\n        }\r\n    }\r\n\r\n    void ConfigurationSetParser::ParseMapping(const AppInstaller::YAML::Node& node, ConfigurationField field, bool required, AppInstaller::YAML::Node::Type elementType, std::function<void(std::string, const AppInstaller::YAML::Node&)> operation)\r\n    {\r\n        const Node& mapNode = CHECK_ERROR(GetAndEnsureField(node, field, required, Node::Type::Mapping));\r\n        if (!mapNode)\r\n        {\r\n            return;\r\n        }\r\n\r\n        std::ostringstream strstr;\r\n        strstr << GetConfigurationFieldName(field);\r\n        size_t index = 0;\r\n\r\n        for (const auto& mapItem : mapNode.Mapping())\r\n        {\r\n            std::string name = mapItem.first.as<std::string>();\r\n            if (name.empty())\r\n            {\r\n                strstr << '[' << index << ']';\r\n                FIELD_VALUE_ERROR(strstr.str(), name, mapItem.first.Mark());\r\n            }\r\n\r\n            if (mapItem.second.GetType() != elementType)\r\n            {\r\n                strstr << '[' << index << ']';\r\n                FIELD_TYPE_ERROR(strstr.str(), mapItem.second.Mark());\r\n            }\r\n            index++;\r\n\r\n            CHECK_ERROR(operation(std::move(name), mapItem.second));\r\n        }\r\n    }\r\n\r\n    void ConfigurationSetParser::ParseSequence(const AppInstaller::YAML::Node& node, ConfigurationField field, bool required, std::optional<Node::Type> elementType, std::function<void(const AppInstaller::YAML::Node&)> operation)\r\n    {\r\n        const Node& sequenceNode = CHECK_ERROR(GetAndEnsureField(node, field, required, Node::Type::Sequence));\r\n        if (!sequenceNode)\r\n        {\r\n            return;\r\n        }\r\n\r\n        ParseSequence(sequenceNode, GetConfigurationFieldName(field), elementType, operation);\r\n    }\r\n\r\n    void ConfigurationSetParser::ParseSequence(const AppInstaller::YAML::Node& node, std::string_view nameForErrors, std::optional<Node::Type> elementType, std::function<void(const AppInstaller::YAML::Node&)> operation)\r\n    {\r\n        std::ostringstream strstr;\r\n        strstr << nameForErrors;\r\n        size_t index = 0;\r\n\r\n        for (const Node& item : node.Sequence())\r\n        {\r\n            if (elementType && item.GetType() != elementType.value())\r\n            {\r\n                strstr << '[' << index << ']';\r\n                FIELD_TYPE_ERROR(strstr.str(), item.Mark());\r\n            }\r\n            index++;\r\n\r\n            CHECK_ERROR(operation(item));\r\n        }\r\n    }\r\n\r\n    std::unique_ptr<ConfigurationSetParser> ConfigurationSetParser::GetSchemaVersionFromOldFormat(AppInstaller::YAML::Node& document, std::string& schemaVersionString)\r\n    {\r\n        Node& propertiesNode = document[GetConfigurationFieldName(ConfigurationField::Properties)];\r\n        if (!propertiesNode)\r\n        {\r\n            AICLI_LOG(Config, Error, << \"No properties\");\r\n            // Even though this is for the \"older\" format, if there is no properties entry then give an error for the newer format since this is probably neither.\r\n            return std::make_unique<ConfigurationSetParserError>(WINGET_CONFIG_ERROR_MISSING_FIELD, GetConfigurationFieldName(ConfigurationField::Schema));\r\n        }\r\n        else if (!propertiesNode.IsMap())\r\n        {\r\n            AICLI_LOG(Config, Error, << \"Invalid properties type\");\r\n            return std::make_unique<ConfigurationSetParserError>(WINGET_CONFIG_ERROR_INVALID_FIELD_TYPE, GetConfigurationFieldName(ConfigurationField::Properties), propertiesNode.Mark());\r\n        }\r\n\r\n        Node& versionNode = propertiesNode[GetConfigurationFieldName(ConfigurationField::ConfigurationVersion)];\r\n        if (!versionNode)\r\n        {\r\n            AICLI_LOG(Config, Error, << \"No configuration version\");\r\n            return std::make_unique<ConfigurationSetParserError>(WINGET_CONFIG_ERROR_MISSING_FIELD, GetConfigurationFieldName(ConfigurationField::ConfigurationVersion));\r\n        }\r\n        else if (!versionNode.IsScalar())\r\n        {\r\n            AICLI_LOG(Config, Error, << \"Invalid configuration version type\");\r\n            return std::make_unique<ConfigurationSetParserError>(WINGET_CONFIG_ERROR_INVALID_FIELD_TYPE, GetConfigurationFieldName(ConfigurationField::ConfigurationVersion), versionNode.Mark());\r\n        }\r\n\r\n        schemaVersionString = versionNode.as<std::string>();\r\n        return {};\r\n    }\r\n\r\n    void ConfigurationSetParser::GetStringValueForUnit(const Node& node, ConfigurationField field, bool required, ConfigurationUnit* unit, void(ConfigurationUnit::* propertyFunction)(const hstring& value))\r\n    {\r\n        const Node& valueNode = CHECK_ERROR(GetAndEnsureField(node, field, required, Node::Type::Scalar));\r\n\r\n        if (valueNode)\r\n        {\r\n            hstring value{ valueNode.as<std::wstring>() };\r\n            FIELD_MISSING_ERROR_IF(value.empty() && required, GetConfigurationFieldName(field));\r\n\r\n            (unit->*propertyFunction)(std::move(value));\r\n        }\r\n    }\r\n\r\n    void ConfigurationSetParser::GetStringArrayForUnit(const Node& node, ConfigurationField field, bool required, ConfigurationUnit* unit, void(ConfigurationUnit::* propertyFunction)(std::vector<hstring>&& value))\r\n    {\r\n        std::vector<hstring> arrayValue;\r\n        CHECK_ERROR(ParseSequence(node, field, required, Node::Type::Scalar, [&](const AppInstaller::YAML::Node& item)\r\n            {\r\n                arrayValue.emplace_back(item.as<std::wstring>());\r\n            }));\r\n\r\n        if (!arrayValue.empty())\r\n        {\r\n            (unit->*propertyFunction)(std::move(arrayValue));\r\n        }\r\n    }\r\n\r\n    void ConfigurationSetParser::ValidateType(ConfigurationUnit* unit, const Node& unitNode, ConfigurationField typeField, bool moveModuleNameToMetadata, bool moduleNameRequiredInType)\r\n    {\r\n        QualifiedResourceName qualifiedName{ unit->Type() };\r\n\r\n        const Node& typeNode = CHECK_ERROR(GetAndEnsureField(unitNode, typeField, true, Node::Type::Scalar));\r\n        FIELD_VALUE_ERROR_IF(qualifiedName.Resource.empty(), GetConfigurationFieldName(typeField), ConvertToUTF8(unit->Type()), typeNode.Mark());\r\n\r\n        if (!qualifiedName.Module.empty())\r\n        {\r\n            // If the module is provided in both the resource name and the directives, ensure that it matches\r\n            hstring moduleDirectiveFieldName = GetConfigurationFieldNameHString(ConfigurationField::ModuleDirective);\r\n            auto moduleDirective = unit->Metadata().TryLookup(moduleDirectiveFieldName);\r\n            if (moduleDirective)\r\n            {\r\n                auto moduleProperty = moduleDirective.try_as<Windows::Foundation::IPropertyValue>();\r\n                FIELD_TYPE_ERROR_IF(!moduleProperty, GetConfigurationFieldName(ConfigurationField::ModuleDirective), unitNode.Mark());\r\n                FIELD_TYPE_ERROR_IF(moduleProperty.Type() != Windows::Foundation::PropertyType::String, GetConfigurationFieldName(ConfigurationField::ModuleDirective), unitNode.Mark());\r\n                hstring moduleValue = moduleProperty.GetString();\r\n                FIELD_VALUE_ERROR_IF(qualifiedName.Module != moduleValue, GetConfigurationFieldName(ConfigurationField::ModuleDirective), ConvertToUTF8(moduleValue), unitNode.Mark());\r\n            }\r\n            else if (moveModuleNameToMetadata)\r\n            {\r\n                unit->Metadata().Insert(moduleDirectiveFieldName, Windows::Foundation::PropertyValue::CreateString(qualifiedName.Module));\r\n            }\r\n\r\n            if (moveModuleNameToMetadata)\r\n            {\r\n                // Set the unit name to be just the resource portion\r\n                unit->Type(qualifiedName.Resource);\r\n            }\r\n        }\r\n        else if (moduleNameRequiredInType)\r\n        {\r\n            FIELD_VALUE_ERROR(GetConfigurationFieldName(typeField), ConvertToUTF8(unit->Type()), typeNode.Mark());\r\n        }\r\n    }\r\n\r\n    void ConfigurationSetParser::ParseObject(const Node& node, ConfigurationField fieldForErrors, Windows::Foundation::PropertyType type, Windows::Foundation::IInspectable& result)\r\n    {\r\n        try\r\n        {\r\n            Windows::Foundation::IInspectable object = GetIInspectableFromNode(node);\r\n            FIELD_VALUE_ERROR_IF(!IsValidObjectType(object, type), GetConfigurationFieldName(fieldForErrors), node.as<std::string>(), node.Mark());\r\n            result = std::move(object);\r\n        }\r\n        catch (...)\r\n        {\r\n            LOG_CAUGHT_EXCEPTION();\r\n            FIELD_VALUE_ERROR(GetConfigurationFieldName(fieldForErrors), node.as<std::string>(), node.Mark());\r\n        }\r\n    }\r\n\r\n    void ConfigurationSetParser::ExtractSecurityContext(implementation::ConfigurationUnit* unit, SecurityContext defaultContext)\r\n    {\r\n        THROW_HR_IF_NULL(E_POINTER, unit);\r\n\r\n        ExtractSecurityContext(unit->Metadata(), unit->EnvironmentInternal(), defaultContext);\r\n    }\r\n\r\n    void ConfigurationSetParser::ExtractSecurityContext(Windows::Foundation::Collections::ValueSet metadata, implementation::ConfigurationEnvironment& environment, SecurityContext defaultContext)\r\n    {\r\n        SecurityContext computedContext = defaultContext;\r\n\r\n        auto securityContext = TryLookupProperty(metadata, ConfigurationField::SecurityContextMetadata, Windows::Foundation::PropertyType::String);\r\n        if (securityContext)\r\n        {\r\n            TryParseSecurityContext(securityContext.GetString(), computedContext);\r\n            metadata.Remove(GetConfigurationFieldNameHString(ConfigurationField::SecurityContextMetadata));\r\n        }\r\n\r\n        environment.Context(computedContext);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationSetParser.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <ConfigurationUnit.h>\r\n#include <ConfigurationSet.h>\r\n#include <ConfigurationSetUtilities.h>\r\n#include <winget/Yaml.h>\r\n#include <winrt/Windows.Storage.Streams.h>\r\n#include <functional>\r\n#include <memory>\r\n#include <string_view>\r\n#include <utility>\r\n#include <vector>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    // Interface for parsing a configuration set stream.\r\n    struct ConfigurationSetParser\r\n    {\r\n        // Create a parser from the given bytes (the encoding is detected).\r\n        static std::unique_ptr<ConfigurationSetParser> Create(std::string_view input);\r\n\r\n        // Create a parser for the given schema version.\r\n        static std::unique_ptr<ConfigurationSetParser> CreateForSchemaVersion(std::string schemaVersion);\r\n\r\n        // Determines if the given value is a recognized schema version.\r\n        // This will only return true for a version that we fully recognize.\r\n        static bool IsRecognizedSchemaVersion(hstring value);\r\n\r\n        // Determines if the given value is a recognized schema URI.\r\n        // This will only return true for a URI that we fully recognize.\r\n        static bool IsRecognizedSchemaUri(const Windows::Foundation::Uri& value);\r\n\r\n        // Gets the schema URI associated with the given version, or null if there is not one.\r\n        static Windows::Foundation::Uri GetSchemaUriForVersion(hstring value);\r\n\r\n        // Gets the schema version associated with the given URI, or null if there is not one.\r\n        static hstring GetSchemaVersionForUri(Windows::Foundation::Uri value);\r\n\r\n        // Gets the schema version associated with the given URI, or null if there is not one.\r\n        static std::string GetSchemaVersionForUri(std::string_view value);\r\n\r\n        // Gets the latest schema version.\r\n        static std::pair<hstring, Windows::Foundation::Uri> LatestVersion();\r\n\r\n        virtual ~ConfigurationSetParser() noexcept = default;\r\n\r\n        ConfigurationSetParser(const ConfigurationSetParser&) = delete;\r\n        ConfigurationSetParser& operator=(const ConfigurationSetParser&) = delete;\r\n        ConfigurationSetParser(ConfigurationSetParser&&) = default;\r\n        ConfigurationSetParser& operator=(ConfigurationSetParser&&) = default;\r\n\r\n        // Parse the full document.\r\n        virtual void Parse() = 0;\r\n\r\n        // Retrieves the schema version of the parser.\r\n        virtual hstring GetSchemaVersion() = 0;\r\n\r\n        // Extracts (and removes) the environment information from the given metadata.\r\n        virtual void ExtractEnvironmentFromMetadata(Windows::Foundation::Collections::ValueSet valueSet, implementation::ConfigurationEnvironment& environment) = 0;\r\n\r\n        using ConfigurationSetPtr = winrt::com_ptr<implementation::ConfigurationSet>;\r\n\r\n        // Retrieve the configuration set from the parser.\r\n        ConfigurationSetPtr GetConfigurationSet() const { return m_configurationSet; }\r\n\r\n        // The latest result code from the parser.\r\n        hresult Result() const { return m_result; }\r\n\r\n        // The field related to the result code.\r\n        hstring Field() const { return m_field; }\r\n\r\n        // The value of the field.\r\n        hstring Value() const { return m_value; }\r\n\r\n        // The line related to the result code.\r\n        uint32_t Line() const { return m_line; }\r\n\r\n        // The column related to the result code.\r\n        uint32_t Column() const { return m_column; }\r\n\r\n        // Parse a ValueSet from the given input.\r\n        Windows::Foundation::Collections::ValueSet ParseValueSet(std::string_view input);\r\n\r\n        // Parse a string array from the given input.\r\n        std::vector<hstring> ParseStringArray(std::string_view input);\r\n\r\n    protected:\r\n        ConfigurationSetParser() = default;\r\n\r\n        // Sets (or resets) the document to parse.\r\n        virtual void SetDocument(AppInstaller::YAML::Node&& document) = 0;\r\n\r\n        // Set the error state\r\n        void SetError(hresult result, std::string_view field = {}, std::string_view value = {}, uint32_t line = 0, uint32_t column = 0);\r\n        void SetError(hresult result, std::string_view field, const AppInstaller::YAML::Mark& mark, std::string_view value = {});\r\n\r\n        ConfigurationSetPtr m_configurationSet;\r\n        hresult m_result;\r\n        hstring m_field;\r\n        hstring m_value;\r\n        uint32_t m_line = 0;\r\n        uint32_t m_column = 0;\r\n\r\n        // Gets the given `field` from the `parent` node, checking against the requirement and type.\r\n        const AppInstaller::YAML::Node& GetAndEnsureField(const AppInstaller::YAML::Node& parent, ConfigurationField field, bool required, std::optional<AppInstaller::YAML::Node::Type> type);\r\n\r\n        // Errors if the given `field` is present.\r\n        void EnsureFieldAbsent(const AppInstaller::YAML::Node& parent, ConfigurationField field);\r\n\r\n        // Parse the ValueSet named `field` from the given `node`.\r\n        void ParseValueSet(const AppInstaller::YAML::Node& node, ConfigurationField field, bool required, const Windows::Foundation::Collections::ValueSet& valueSet);\r\n\r\n        // Parse the mapping named `field` from the given `node`.\r\n        void ParseMapping(const AppInstaller::YAML::Node& node, ConfigurationField field, bool required, AppInstaller::YAML::Node::Type elementType, std::function<void(std::string, const AppInstaller::YAML::Node&)> operation);\r\n\r\n        // Parse the sequence named `field` from the given `node`.\r\n        void ParseSequence(const AppInstaller::YAML::Node& node, ConfigurationField field, bool required, std::optional<AppInstaller::YAML::Node::Type> elementType, std::function<void(const AppInstaller::YAML::Node&)> operation);\r\n\r\n        // Parse the sequence from the given `node`.\r\n        void ParseSequence(const AppInstaller::YAML::Node& node, std::string_view nameForErrors, std::optional<AppInstaller::YAML::Node::Type> elementType, std::function<void(const AppInstaller::YAML::Node&)> operation);\r\n\r\n        // Gets the string value in `field` from the given `node`, setting this value on `unit` using the `propertyFunction`.\r\n        void GetStringValueForUnit(const AppInstaller::YAML::Node& node, ConfigurationField field, bool required, ConfigurationUnit* unit, void(ConfigurationUnit::* propertyFunction)(const hstring& value));\r\n\r\n        // Gets the string array in `field` from the given `node`, setting this value on `unit` using the `propertyFunction`.\r\n        void GetStringArrayForUnit(const AppInstaller::YAML::Node& node, ConfigurationField field, bool required, ConfigurationUnit* unit, void(ConfigurationUnit::* propertyFunction)(std::vector<hstring>&& value));\r\n\r\n        // Validates the unit's Type property for correctness and consistency with the metadata. Should be called after parsing the Metadata value.\r\n        void ValidateType(ConfigurationUnit* unit, const AppInstaller::YAML::Node& unitNode, ConfigurationField typeField, bool moveModuleNameToMetadata, bool moduleNameRequiredInType);\r\n\r\n        // Parses an object from the given node, attempting to treat it as the requested type if possible.\r\n        void ParseObject(const AppInstaller::YAML::Node& node, ConfigurationField fieldForErrors, Windows::Foundation::PropertyType type, Windows::Foundation::IInspectable& result);\r\n\r\n        // Extracts the security context from the metadata in the given unit; if not present use `defaultContext`.\r\n        void ExtractSecurityContext(implementation::ConfigurationUnit* unit, SecurityContext defaultContext = SecurityContext::Current);\r\n        void ExtractSecurityContext(Windows::Foundation::Collections::ValueSet metadata, implementation::ConfigurationEnvironment& environment, SecurityContext defaultContext = SecurityContext::Current);\r\n\r\n    private:\r\n        // Support older schema parsing.\r\n        static std::unique_ptr<ConfigurationSetParser> GetSchemaVersionFromOldFormat(AppInstaller::YAML::Node& document, std::string& schemaVersionString);\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationSetParserError.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ConfigurationSetParser.h\"\r\n#include <string_view>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    // Parser object that only indicates an error occurred.\r\n    struct ConfigurationSetParserError : public ConfigurationSetParser\r\n    {\r\n        ConfigurationSetParserError(hresult result, std::string_view field = {}, std::string_view value = {})\r\n        {\r\n            SetError(result, field, value);\r\n        }\r\n\r\n        ConfigurationSetParserError(hresult result, std::string_view field, const AppInstaller::YAML::Mark& mark)\r\n        {\r\n            SetError(result, field, mark);\r\n        }\r\n\r\n        void Parse() override {}\r\n\r\n        hstring GetSchemaVersion() override { return {}; }\r\n\r\n        void ExtractEnvironmentFromMetadata(Windows::Foundation::Collections::ValueSet, implementation::ConfigurationEnvironment&) override {}\r\n\r\n    protected:\r\n        void SetDocument(AppInstaller::YAML::Node&&) override {}\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationSetParser_0_1.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigurationSetParser_0_1.h\"\r\n#include \"ParsingMacros.h\"\r\n\r\n#include <AppInstallerErrors.h>\r\n#include <AppInstallerStrings.h>\r\n\r\n#include <sstream>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    using namespace AppInstaller::YAML;\r\n\r\n    void ConfigurationSetParser_0_1::Parse()\r\n    {\r\n        std::vector<Configuration::ConfigurationUnit> units;\r\n        const Node& properties = m_document[GetConfigurationFieldName(ConfigurationField::Properties)];\r\n        ParseConfigurationUnitsFromField(properties, ConfigurationField::Assertions, ConfigurationUnitIntent::Assert, units);\r\n        ParseConfigurationUnitsFromField(properties, ConfigurationField::Parameters, ConfigurationUnitIntent::Inform, units);\r\n        ParseConfigurationUnitsFromField(properties, ConfigurationField::Resources, ConfigurationUnitIntent::Apply, units);\r\n\r\n        m_configurationSet = make_self<implementation::ConfigurationSet>();\r\n        m_configurationSet->Units(std::move(units));\r\n        m_configurationSet->SchemaVersion(GetSchemaVersion());\r\n    }\r\n\r\n    hstring ConfigurationSetParser_0_1::GetSchemaVersion()\r\n    {\r\n        static hstring s_schemaVersion{ L\"0.1\" };\r\n        return s_schemaVersion;\r\n    }\r\n\r\n    void ConfigurationSetParser_0_1::ExtractEnvironmentFromMetadata(Windows::Foundation::Collections::ValueSet, implementation::ConfigurationEnvironment&)\r\n    {\r\n    }\r\n\r\n    void ConfigurationSetParser_0_1::SetDocument(AppInstaller::YAML::Node&& document)\r\n    {\r\n        m_document = std::move(document);\r\n    }\r\n\r\n    void ConfigurationSetParser_0_1::ParseConfigurationUnitsFromField(const Node& document, ConfigurationField field, ConfigurationUnitIntent intent, std::vector<Configuration::ConfigurationUnit>& result)\r\n    {\r\n        ParseSequence(document, field, false, Node::Type::Mapping, [&](const Node& item)\r\n            {\r\n                auto configurationUnit = make_self<ConfigurationUnit>();\r\n                ParseConfigurationUnit(configurationUnit.get(), item, intent);\r\n                result.emplace_back(*configurationUnit);\r\n            });\r\n    }\r\n\r\n    void ConfigurationSetParser_0_1::ParseConfigurationUnit(ConfigurationUnit* unit, const Node& unitNode, ConfigurationUnitIntent intent)\r\n    {\r\n        CHECK_ERROR(GetStringValueForUnit(unitNode, ConfigurationField::Resource, true, unit, &ConfigurationUnit::Type));\r\n        CHECK_ERROR(GetStringValueForUnit(unitNode, ConfigurationField::Id, false, unit, &ConfigurationUnit::Identifier));\r\n        unit->Intent(intent);\r\n        CHECK_ERROR(GetStringArrayForUnit(unitNode, ConfigurationField::DependsOn, false, unit, &ConfigurationUnit::Dependencies));\r\n        CHECK_ERROR(ParseValueSet(unitNode, ConfigurationField::Directives, false, unit->Metadata()));\r\n        CHECK_ERROR(ParseValueSet(unitNode, ConfigurationField::Settings, false, unit->Settings()));\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationSetParser_0_1.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ConfigurationSetParser.h\"\r\n\r\n#include <winget/Yaml.h>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    // Parser for schema version 0.1\r\n    struct ConfigurationSetParser_0_1 : public ConfigurationSetParser\r\n    {\r\n        ConfigurationSetParser_0_1() = default;\r\n\r\n        virtual ~ConfigurationSetParser_0_1() noexcept = default;\r\n\r\n        ConfigurationSetParser_0_1(const ConfigurationSetParser_0_1&) = delete;\r\n        ConfigurationSetParser_0_1& operator=(const ConfigurationSetParser_0_1&) = delete;\r\n        ConfigurationSetParser_0_1(ConfigurationSetParser_0_1&&) = default;\r\n        ConfigurationSetParser_0_1& operator=(ConfigurationSetParser_0_1&&) = default;\r\n\r\n        void Parse() override;\r\n\r\n        // Retrieves the schema version of the parser.\r\n        hstring GetSchemaVersion() override;\r\n\r\n        void ExtractEnvironmentFromMetadata(Windows::Foundation::Collections::ValueSet valueSet, implementation::ConfigurationEnvironment& environment) override;\r\n\r\n    protected:\r\n        // Sets (or resets) the document to parse.\r\n        void SetDocument(AppInstaller::YAML::Node&& document) override;\r\n\r\n        void ParseConfigurationUnitsFromField(const AppInstaller::YAML::Node& document, ConfigurationField field, ConfigurationUnitIntent intent, std::vector<Configuration::ConfigurationUnit>& result);\r\n        virtual void ParseConfigurationUnit(ConfigurationUnit* unit, const AppInstaller::YAML::Node& unitNode, ConfigurationUnitIntent intent);\r\n\r\n        AppInstaller::YAML::Node m_document;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationSetParser_0_2.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigurationSetParser_0_2.h\"\r\n#include \"ParsingMacros.h\"\r\n\r\n#include <AppInstallerErrors.h>\r\n#include <AppInstallerStrings.h>\r\n\r\n#include <sstream>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    using namespace AppInstaller::YAML;\r\n\r\n    hstring ConfigurationSetParser_0_2::GetSchemaVersion()\r\n    {\r\n        static hstring s_schemaVersion{ L\"0.2\" };\r\n        return s_schemaVersion;\r\n    }\r\n\r\n    void ConfigurationSetParser_0_2::ExtractEnvironmentFromMetadata(Windows::Foundation::Collections::ValueSet valueSet, implementation::ConfigurationEnvironment& environment)\r\n    {\r\n        ExtractSecurityContext(valueSet, environment);\r\n    }\r\n\r\n    void ConfigurationSetParser_0_2::SetDocument(AppInstaller::YAML::Node&& document)\r\n    {\r\n        m_document = std::move(document);\r\n    }\r\n\r\n    void ConfigurationSetParser_0_2::ParseConfigurationUnit(ConfigurationUnit* unit, const Node& unitNode, ConfigurationUnitIntent intent)\r\n    {\r\n        CHECK_ERROR(ConfigurationSetParser_0_1::ParseConfigurationUnit(unit, unitNode, intent));\r\n        ValidateType(unit, unitNode, ConfigurationField::Resource, true, false);\r\n        ExtractSecurityContext(unit);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationSetParser_0_2.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ConfigurationSetParser_0_1.h\"\r\n\r\n#include <winget/Yaml.h>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    // Parser for schema version 0.2\r\n    struct ConfigurationSetParser_0_2 : public ConfigurationSetParser_0_1\r\n    {\r\n        ConfigurationSetParser_0_2() = default;\r\n\r\n        virtual ~ConfigurationSetParser_0_2() noexcept = default;\r\n\r\n        ConfigurationSetParser_0_2(const ConfigurationSetParser_0_2&) = delete;\r\n        ConfigurationSetParser_0_2& operator=(const ConfigurationSetParser_0_2&) = delete;\r\n        ConfigurationSetParser_0_2(ConfigurationSetParser_0_2&&) = default;\r\n        ConfigurationSetParser_0_2& operator=(ConfigurationSetParser_0_2&&) = default;\r\n\r\n        // Retrieves the schema version of the parser.\r\n        hstring GetSchemaVersion() override;\r\n\r\n        void ExtractEnvironmentFromMetadata(Windows::Foundation::Collections::ValueSet valueSet, implementation::ConfigurationEnvironment& environment) override;\r\n\r\n    protected:\r\n        // Sets (or resets) the document to parse.\r\n        void SetDocument(AppInstaller::YAML::Node&& document) override;\r\n\r\n        void ParseConfigurationUnit(ConfigurationUnit* unit, const AppInstaller::YAML::Node& unitNode, ConfigurationUnitIntent intent) override;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationSetParser_0_3.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigurationSetParser_0_3.h\"\r\n#include \"ParsingMacros.h\"\r\n#include \"ArgumentValidation.h\"\r\n\r\n#include <AppInstallerErrors.h>\r\n#include <AppInstallerStrings.h>\r\n\r\n#include <sstream>\r\n\r\nusing namespace AppInstaller::YAML;\r\nusing namespace winrt::Windows::Foundation;\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    using IInspectable = winrt::Windows::Foundation::IInspectable;\r\n\r\n    void ConfigurationSetParser_0_3::Parse()\r\n    {\r\n        auto result = make_self<implementation::ConfigurationSet>();\r\n\r\n        CHECK_ERROR(ParseValueSet(m_document, ConfigurationField::Metadata, false, result->Metadata()));\r\n\r\n        CHECK_ERROR(ExtractEnvironmentFromMetadata(result->Metadata(), result->EnvironmentInternal()));\r\n\r\n        CHECK_ERROR(ParseParameters(result));\r\n        CHECK_ERROR(ParseValueSet(m_document, ConfigurationField::Variables, false, result->Variables()));\r\n\r\n        std::vector<Configuration::ConfigurationUnit> units;\r\n        CHECK_ERROR(ParseConfigurationUnitsFromField(m_document, ConfigurationField::Resources, units));\r\n        result->Units(std::move(units));\r\n\r\n        result->SchemaVersion(GetSchemaVersion());\r\n        m_configurationSet = std::move(result);\r\n    }\r\n\r\n    hstring ConfigurationSetParser_0_3::GetSchemaVersion()\r\n    {\r\n        static hstring s_schemaVersion{ L\"0.3\" };\r\n        return s_schemaVersion;\r\n    }\r\n\r\n    void ConfigurationSetParser_0_3::SetDocument(AppInstaller::YAML::Node&& document)\r\n    {\r\n        m_document = std::move(document);\r\n    }\r\n\r\n    void ConfigurationSetParser_0_3::ParseParameters(ConfigurationSetParser::ConfigurationSetPtr& set)\r\n    {\r\n        std::vector<Configuration::ConfigurationParameter> parameters;\r\n\r\n        ParseMapping(m_document, ConfigurationField::Parameters, false, Node::Type::Mapping, [&](std::string name, const Node& item)\r\n            {\r\n                auto parameter = make_self<wil::details::module_count_wrapper<ConfigurationParameter>>();\r\n                CHECK_ERROR(ParseParameter(parameter.get(), item));\r\n                parameter->Name(hstring{ AppInstaller::Utility::ConvertToUTF16(name) });\r\n                parameters.emplace_back(*parameter);\r\n            });\r\n\r\n        set->Parameters(std::move(parameters));\r\n    }\r\n\r\n    void ConfigurationSetParser_0_3::ParseParameter(ConfigurationParameter* parameter, const AppInstaller::YAML::Node& node)\r\n    {\r\n        CHECK_ERROR(ParseParameterType(parameter, node));\r\n        CHECK_ERROR(ParseValueSet(node, ConfigurationField::Metadata, false, parameter->Metadata()));\r\n        CHECK_ERROR(GetStringValueForParameter(node, ConfigurationField::Description, parameter, &ConfigurationParameter::Description));\r\n\r\n        PropertyType parameterType = parameter->Type();\r\n        CHECK_ERROR(ParseObjectValueForParameter(node, ConfigurationField::DefaultValue, parameterType, parameter, &ConfigurationParameter::DefaultValue));\r\n\r\n        std::vector<IInspectable> allowedValues;\r\n\r\n        CHECK_ERROR(ParseSequence(node, ConfigurationField::AllowedValues, false, std::nullopt, [&](const Node& item)\r\n            {\r\n                IInspectable object;\r\n                CHECK_ERROR(ParseObject(item, ConfigurationField::AllowedValues, parameterType, object));\r\n                allowedValues.emplace_back(std::move(object));\r\n            }));\r\n\r\n        if (!allowedValues.empty())\r\n        {\r\n            parameter->AllowedValues(std::move(allowedValues));\r\n        }\r\n\r\n        if (IsLengthType(parameterType))\r\n        {\r\n            CHECK_ERROR(GetUInt32ValueForParameter(node, ConfigurationField::MinimumLength, parameter, &ConfigurationParameter::MinimumLength));\r\n            CHECK_ERROR(GetUInt32ValueForParameter(node, ConfigurationField::MaximumLength, parameter, &ConfigurationParameter::MaximumLength));\r\n        }\r\n        else\r\n        {\r\n            CHECK_ERROR(EnsureFieldAbsent(node, ConfigurationField::MinimumLength));\r\n            CHECK_ERROR(EnsureFieldAbsent(node, ConfigurationField::MaximumLength));\r\n        }\r\n\r\n        if (IsComparableType(parameterType))\r\n        {\r\n            CHECK_ERROR(ParseObjectValueForParameter(node, ConfigurationField::MinimumValue, parameterType, parameter, &ConfigurationParameter::MinimumValue));\r\n            CHECK_ERROR(ParseObjectValueForParameter(node, ConfigurationField::MaximumValue, parameterType, parameter, &ConfigurationParameter::MaximumValue));\r\n        }\r\n        else\r\n        {\r\n            CHECK_ERROR(EnsureFieldAbsent(node, ConfigurationField::MinimumValue));\r\n            CHECK_ERROR(EnsureFieldAbsent(node, ConfigurationField::MaximumValue));\r\n        }\r\n    }\r\n\r\n    void ConfigurationSetParser_0_3::ParseParameterType(ConfigurationParameter* parameter, const AppInstaller::YAML::Node& node)\r\n    {\r\n        const Node& typeNode = CHECK_ERROR(GetAndEnsureField(node, ConfigurationField::Type, true, Node::Type::Scalar));\r\n        std::string typeValue = typeNode.as<std::string>();\r\n        auto parsedType = ParseWindowsFoundationPropertyType(typeValue);\r\n\r\n        if (parsedType)\r\n        {\r\n            parameter->Type(parsedType->first);\r\n            parameter->IsSecure(parsedType->second);\r\n        }\r\n        else\r\n        {\r\n            FIELD_VALUE_ERROR(GetConfigurationFieldName(ConfigurationField::Type), typeValue, typeNode.Mark());\r\n        }\r\n    }\r\n\r\n    void ConfigurationSetParser_0_3::GetStringValueForParameter(\r\n        const Node& node,\r\n        ConfigurationField field,\r\n        ConfigurationParameter* parameter,\r\n        void(ConfigurationParameter::* propertyFunction)(const hstring& value))\r\n    {\r\n        const Node& valueNode = CHECK_ERROR(GetAndEnsureField(node, field, false, Node::Type::Scalar));\r\n\r\n        if (valueNode)\r\n        {\r\n            (parameter->*propertyFunction)(hstring{ valueNode.as<std::wstring>() });\r\n        }\r\n    }\r\n\r\n    void ConfigurationSetParser_0_3::GetUInt32ValueForParameter(\r\n        const AppInstaller::YAML::Node& node,\r\n        ConfigurationField field,\r\n        ConfigurationParameter* parameter,\r\n        void(ConfigurationParameter::* propertyFunction)(uint32_t value))\r\n    {\r\n        const Node& valueNode = CHECK_ERROR(GetAndEnsureField(node, field, false, Node::Type::Scalar));\r\n\r\n        if (valueNode)\r\n        {\r\n            int64_t value = valueNode.as<int64_t>();\r\n            if (value < 0 || value > static_cast<int64_t>(std::numeric_limits<uint32_t>::max()))\r\n            {\r\n                FIELD_VALUE_ERROR(GetConfigurationFieldName(field), valueNode.as<std::string>(), valueNode.Mark());\r\n            }\r\n            (parameter->*propertyFunction)(static_cast<uint32_t>(value));\r\n        }\r\n    }\r\n\r\n    void ConfigurationSetParser_0_3::ParseObjectValueForParameter(\r\n        const AppInstaller::YAML::Node& node,\r\n        ConfigurationField field,\r\n        PropertyType type,\r\n        ConfigurationParameter* parameter,\r\n        void(ConfigurationParameter::* propertyFunction)(const IInspectable& value))\r\n    {\r\n        const Node& valueNode = CHECK_ERROR(GetAndEnsureField(node, field, false, std::nullopt));\r\n\r\n        if (valueNode)\r\n        {\r\n            IInspectable valueObject;\r\n            CHECK_ERROR(ParseObject(valueNode, field, type, valueObject));\r\n\r\n            (parameter->*propertyFunction)(valueObject);\r\n        }\r\n    }\r\n\r\n    void ConfigurationSetParser_0_3::ParseConfigurationUnitsFromField(const Node& document, ConfigurationField field, std::vector<Configuration::ConfigurationUnit>& result)\r\n    {\r\n        ParseSequence(document, field, false, Node::Type::Mapping, [&](const Node& item)\r\n            {\r\n                auto configurationUnit = make_self<ConfigurationUnit>();\r\n                ParseConfigurationUnit(configurationUnit.get(), item);\r\n                result.emplace_back(*configurationUnit);\r\n            });\r\n    }\r\n\r\n    void ConfigurationSetParser_0_3::ParseConfigurationUnit(ConfigurationUnit* unit, const Node& unitNode)\r\n    {\r\n        // Set unknown intent as the new schema doesn't express it directly\r\n        unit->Intent(ConfigurationUnitIntent::Unknown);\r\n\r\n        CHECK_ERROR(GetStringValueForUnit(unitNode, ConfigurationField::Name, true, unit, &ConfigurationUnit::Identifier));\r\n        CHECK_ERROR(GetStringValueForUnit(unitNode, ConfigurationField::Type, true, unit, &ConfigurationUnit::Type));\r\n        CHECK_ERROR(ParseValueSet(unitNode, ConfigurationField::Metadata, false, unit->Metadata()));\r\n        CHECK_ERROR(ExtractEnvironmentForUnit(unit));\r\n        CHECK_ERROR(ValidateType(unit, unitNode, ConfigurationField::Type, false, true));\r\n        CHECK_ERROR(GetStringArrayForUnit(unitNode, ConfigurationField::DependsOn, false, unit, &ConfigurationUnit::Dependencies));\r\n\r\n        // Regardless of being a group or not, parse the settings.\r\n        CHECK_ERROR(ParseValueSet(unitNode, ConfigurationField::Properties, false, unit->Settings()));\r\n\r\n        if (ShouldConvertToGroup(unit))\r\n        {\r\n            unit->IsGroup(true);\r\n\r\n            // TODO: The PS DSC v3 POR looks like it supports each group defining a new schema to be used for its group items.\r\n            //       Consider supporting that in the future; but for now just use the same schema for everything.\r\n            const Node& propertiesNode = GetAndEnsureField(unitNode, ConfigurationField::Properties, false, Node::Type::Mapping);\r\n            if (propertiesNode)\r\n            {\r\n                std::vector<Configuration::ConfigurationUnit> units;\r\n                CHECK_ERROR(ParseConfigurationUnitsFromField(propertiesNode, ConfigurationField::Resources, units));\r\n                unit->Units(std::move(units));\r\n            }\r\n        }\r\n    }\r\n\r\n    bool ConfigurationSetParser_0_3::ShouldConvertToGroup(ConfigurationUnit* unit)\r\n    {\r\n        // Allow the metadata to inform us that we should treat it as a group, including preventing a known type from being treated as one.\r\n        auto isGroupObject = unit->Metadata().TryLookup(GetConfigurationFieldNameHString(ConfigurationField::IsGroupMetadata));\r\n        if (isGroupObject)\r\n        {\r\n            auto isGroupProperty = isGroupObject.try_as<IPropertyValue>();\r\n            if (isGroupProperty && isGroupProperty.Type() == PropertyType::Boolean)\r\n            {\r\n                return isGroupProperty.GetBoolean();\r\n            }\r\n        }\r\n\r\n        // TODO: Check for known types\r\n\r\n        return false;\r\n    }\r\n\r\n    void ConfigurationSetParser_0_3::ExtractEnvironmentFromMetadata(Collections::ValueSet metadata, ConfigurationEnvironment& targetEnvironment)\r\n    {\r\n        auto root = TryLookupValueSet(metadata, ConfigurationField::WingetMetadataRoot);\r\n        if (root)\r\n        {\r\n            // Get security context\r\n            auto securityContext = TryLookupProperty(root, ConfigurationField::SecurityContextMetadata, PropertyType::String);\r\n            if (securityContext)\r\n            {\r\n                SecurityContext computedContext = SecurityContext::Current;\r\n                if (TryParseSecurityContext(securityContext.GetString(), computedContext))\r\n                {\r\n                    targetEnvironment.Context(computedContext);\r\n                }\r\n                root.Remove(GetConfigurationFieldNameHString(ConfigurationField::SecurityContextMetadata));\r\n            }\r\n\r\n            // Get processor\r\n            hstring processorFieldName = GetConfigurationFieldNameHString(ConfigurationField::ProcessorMetadata);\r\n            IInspectable processor = root.TryLookup(processorFieldName);\r\n            Collections::ValueSet processorValueSet = processor.try_as<Collections::ValueSet>();\r\n            if (processorValueSet)\r\n            {\r\n                targetEnvironment.ProcessorIdentifier({});\r\n                targetEnvironment.ProcessorProperties().Clear();\r\n\r\n                IPropertyValue identifier = TryLookupProperty(processorValueSet, ConfigurationField::ProcessorIdentifierMetadata, PropertyType::String);\r\n                if (identifier)\r\n                {\r\n                    targetEnvironment.ProcessorIdentifier(identifier.GetString());\r\n\r\n                    Collections::ValueSet processorSettings = TryLookupValueSet(processorValueSet, ConfigurationField::ProcessorPropertiesMetadata);\r\n                    if (processorSettings)\r\n                    {\r\n                        targetEnvironment.ProcessorProperties(processorSettings);\r\n                    }\r\n                }\r\n\r\n                root.Remove(processorFieldName);\r\n            }\r\n            else\r\n            {\r\n                IPropertyValue processorProperty = processor.try_as<IPropertyValue>();\r\n                if (processorProperty)\r\n                {\r\n                    targetEnvironment.ProcessorIdentifier(processorProperty.GetString());\r\n                    targetEnvironment.ProcessorProperties().Clear();\r\n                    root.Remove(processorFieldName);\r\n                }\r\n            }\r\n\r\n            if (root.Size() == 0)\r\n            {\r\n                metadata.Remove(GetConfigurationFieldNameHString(ConfigurationField::WingetMetadataRoot));\r\n            }\r\n        }\r\n    }\r\n\r\n    void ConfigurationSetParser_0_3::ExtractEnvironmentForUnit(ConfigurationUnit* unit)\r\n    {\r\n        // Get unnested security context\r\n        ExtractSecurityContext(unit);\r\n\r\n        // Get nested environment\r\n        ExtractEnvironmentFromMetadata(unit->Metadata(), unit->EnvironmentInternal());\r\n    }\r\n\r\n    std::optional<std::pair<PropertyType, bool>> ParseWindowsFoundationPropertyType(std::string_view value)\r\n    {\r\n        if (value == \"string\")\r\n        {\r\n            return std::make_pair(PropertyType::String, false);\r\n        }\r\n        else if (value == \"securestring\")\r\n        {\r\n            return std::make_pair(PropertyType::String, true);\r\n        }\r\n        else if (value == \"int\")\r\n        {\r\n            return std::make_pair(PropertyType::Int64, false);\r\n        }\r\n        else if (value == \"bool\")\r\n        {\r\n            return std::make_pair(PropertyType::Boolean, false);\r\n        }\r\n        else if (value == \"object\")\r\n        {\r\n            return std::make_pair(PropertyType::Inspectable, false);\r\n        }\r\n        else if (value == \"secureobject\")\r\n        {\r\n            return std::make_pair(PropertyType::Inspectable, true);\r\n        }\r\n        else if (value == \"array\")\r\n        {\r\n            return std::make_pair(PropertyType::InspectableArray, false);\r\n        }\r\n\r\n        // TODO: Consider supporting an expanded set of type strings\r\n        return std::nullopt;\r\n    }\r\n\r\n    std::string_view ToString(PropertyType value, bool isSecure)\r\n    {\r\n        switch (value)\r\n        {\r\n        case PropertyType::Int16:\r\n        case PropertyType::Int32:\r\n        case PropertyType::Int64:\r\n            return \"int\"sv;\r\n        case PropertyType::Boolean:\r\n            return \"bool\"sv;\r\n        case PropertyType::String:\r\n            return isSecure ? \"securestring\"sv : \"string\"sv;\r\n        case PropertyType::Inspectable:\r\n            return isSecure ? \"secureobject\"sv : \"object\"sv;\r\n        case PropertyType::InspectableArray:\r\n            return \"array\"sv;\r\n        default:\r\n            return {};\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationSetParser_0_3.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ConfigurationSetParser.h\"\r\n#include \"ConfigurationParameter.h\"\r\n#include <winrt/Microsoft.Management.Configuration.h>\r\n\r\n#include <winget/Yaml.h>\r\n#include <optional>\r\n#include <utility>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    // Parser for schema version 0.3\r\n    struct ConfigurationSetParser_0_3 : public ConfigurationSetParser\r\n    {\r\n        ConfigurationSetParser_0_3() = default;\r\n\r\n        virtual ~ConfigurationSetParser_0_3() noexcept = default;\r\n\r\n        ConfigurationSetParser_0_3(const ConfigurationSetParser_0_3&) = delete;\r\n        ConfigurationSetParser_0_3& operator=(const ConfigurationSetParser_0_3&) = delete;\r\n        ConfigurationSetParser_0_3(ConfigurationSetParser_0_3&&) = default;\r\n        ConfigurationSetParser_0_3& operator=(ConfigurationSetParser_0_3&&) = default;\r\n\r\n        // Retrieve the configuration units from the parser.\r\n        void Parse() override;\r\n\r\n        // Retrieves the schema version of the parser.\r\n        hstring GetSchemaVersion() override;\r\n\r\n        // Extracts the environment configuration from the given metadata.\r\n        // This only examines the winget subnode.\r\n        void ExtractEnvironmentFromMetadata(Windows::Foundation::Collections::ValueSet valueSet, implementation::ConfigurationEnvironment& environment) override;\r\n\r\n    protected:\r\n        // Sets (or resets) the document to parse.\r\n        void SetDocument(AppInstaller::YAML::Node&& document) override;\r\n\r\n        void ParseParameters(ConfigurationSetParser::ConfigurationSetPtr& set);\r\n        void ParseParameter(ConfigurationParameter* parameter, const AppInstaller::YAML::Node& node);\r\n        void ParseParameterType(ConfigurationParameter* parameter, const AppInstaller::YAML::Node& node);\r\n        void GetStringValueForParameter(\r\n            const AppInstaller::YAML::Node& node,\r\n            ConfigurationField field,\r\n            ConfigurationParameter* parameter,\r\n            void(ConfigurationParameter::* propertyFunction)(const hstring& value));\r\n        void GetUInt32ValueForParameter(\r\n            const AppInstaller::YAML::Node& node,\r\n            ConfigurationField field,\r\n            ConfigurationParameter* parameter,\r\n            void(ConfigurationParameter::* propertyFunction)(uint32_t value));\r\n        void ParseObjectValueForParameter(\r\n            const AppInstaller::YAML::Node& node,\r\n            ConfigurationField field,\r\n            Windows::Foundation::PropertyType type,\r\n            ConfigurationParameter* parameter,\r\n            void(ConfigurationParameter::* propertyFunction)(const Windows::Foundation::IInspectable& value));\r\n\r\n        void ParseConfigurationUnitsFromField(const AppInstaller::YAML::Node& document, ConfigurationField field, std::vector<Configuration::ConfigurationUnit>& result);\r\n        virtual void ParseConfigurationUnit(ConfigurationUnit* unit, const AppInstaller::YAML::Node& unitNode);\r\n        // Determines if the given unit should be converted to a group.\r\n        bool ShouldConvertToGroup(ConfigurationUnit* unit);\r\n\r\n        // Extracts the environment for a unit.\r\n        void ExtractEnvironmentForUnit(ConfigurationUnit* unit);\r\n\r\n        AppInstaller::YAML::Node m_document;\r\n    };\r\n\r\n    std::optional<std::pair<Windows::Foundation::PropertyType, bool>> ParseWindowsFoundationPropertyType(std::string_view value);\r\n    std::string_view ToString(Windows::Foundation::PropertyType value, bool isSecure);\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationSetSerializer.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n\r\n#include <AppInstallerLogging.h>\r\n#include <AppInstallerVersions.h>\r\n#include <AppInstallerStrings.h>\r\n\r\n#include \"ConfigurationSetSerializer.h\"\r\n#include \"ConfigurationSetSerializer_0_2.h\"\r\n#include \"ConfigurationSetSerializer_0_3.h\"\r\n#include \"ConfigurationSetUtilities.h\"\r\n\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::YAML;\r\nusing namespace winrt::Windows::Foundation;\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    namespace anon\r\n    {\r\n        static constexpr std::string_view s_nullValue = \"null\";\r\n\r\n        struct ValueSetWriter\r\n        {\r\n            ValueSetWriter(const Windows::Foundation::Collections::ValueSet& valueSet, const std::vector<std::pair<ConfigurationField, Windows::Foundation::IInspectable>>& overrides) :\r\n                m_valueSet(valueSet), m_overrides(overrides)\r\n            {\r\n                // Create a sorted list of the field names to exclude\r\n                for (const auto & override : m_overrides)\r\n                {\r\n                    m_exclusionStrings.push_back(GetConfigurationFieldNameHString(override.first));\r\n                }\r\n                std::sort(m_exclusionStrings.begin(), m_exclusionStrings.end());\r\n            }\r\n\r\n            bool IsResultEmpty()\r\n            {\r\n                size_t nullOverrides = 0;\r\n\r\n                for (const auto& override : m_overrides)\r\n                {\r\n                    // A non-null override will always be output\r\n                    if (override.second)\r\n                    {\r\n                        return false;\r\n                    }\r\n                    else\r\n                    {\r\n                        ++nullOverrides;\r\n                    }\r\n                }\r\n\r\n                if (m_valueSet)\r\n                {\r\n                    // If there are more values than null overrides, something will be output\r\n                    if (static_cast<size_t>(m_valueSet.Size()) > nullOverrides)\r\n                    {\r\n                        return false;\r\n                    }\r\n\r\n                    // Check for a value that we would output\r\n                    for (const auto& [key, value] : m_valueSet)\r\n                    {\r\n                        if (value != nullptr &&\r\n                            !std::binary_search(m_exclusionStrings.begin(), m_exclusionStrings.end(), key))\r\n                        {\r\n                            return false;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                return true;\r\n            }\r\n\r\n            void Write(AppInstaller::YAML::Emitter& emitter, void(* WriteYamlValue)(AppInstaller::YAML::Emitter& emitter, const winrt::Windows::Foundation::IInspectable& value))\r\n            {\r\n                emitter << BeginMap;\r\n\r\n                WriteValues(emitter, WriteYamlValue);\r\n\r\n                emitter << EndMap;\r\n            }\r\n\r\n            void WriteValues(AppInstaller::YAML::Emitter& emitter, void(*WriteYamlValue)(AppInstaller::YAML::Emitter& emitter, const winrt::Windows::Foundation::IInspectable& value))\r\n            {\r\n                if (m_valueSet)\r\n                {\r\n                    for (const auto& [key, value] : m_valueSet)\r\n                    {\r\n                        if (value != nullptr &&\r\n                            !std::binary_search(m_exclusionStrings.begin(), m_exclusionStrings.end(), key))\r\n                        {\r\n                            std::string keyName = winrt::to_string(key);\r\n                            emitter << Key << keyName << Value;\r\n                            WriteYamlValue(emitter, value);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                for (const auto & override : m_overrides)\r\n                {\r\n                    if (override.second != nullptr)\r\n                    {\r\n                        std::string_view keyName = GetConfigurationFieldName(override.first);\r\n                        emitter << Key << keyName << Value;\r\n                        WriteYamlValue(emitter, override.second);\r\n                    }\r\n                }\r\n            }\r\n\r\n        private:\r\n            const Windows::Foundation::Collections::ValueSet& m_valueSet;\r\n            const std::vector<std::pair<ConfigurationField, Windows::Foundation::IInspectable>>& m_overrides;\r\n            std::vector<winrt::hstring> m_exclusionStrings;\r\n        };\r\n    }\r\n\r\n    std::unique_ptr<ConfigurationSetSerializer> ConfigurationSetSerializer::CreateSerializer(hstring version, bool strictVersionMatching)\r\n    {\r\n        // Create the parser based on the version selected\r\n        SemanticVersion schemaVersion(std::move(winrt::to_string(version)));\r\n\r\n        // TODO: Consider having the version/uri/type information all together in the future\r\n        if (schemaVersion.PartAt(0).Integer == 0 && schemaVersion.PartAt(1).Integer == 1)\r\n        {\r\n            // Remove this once the 0.1 serializer is implemented.\r\n            THROW_HR_IF(E_NOTIMPL, strictVersionMatching);\r\n\r\n            return std::make_unique<ConfigurationSetSerializer_0_2>();\r\n\r\n        }\r\n        else if (schemaVersion.PartAt(0).Integer == 0 && schemaVersion.PartAt(1).Integer == 2)\r\n        {\r\n            return std::make_unique<ConfigurationSetSerializer_0_2>();\r\n        }\r\n        else if (schemaVersion.PartAt(0).Integer == 0 && schemaVersion.PartAt(1).Integer == 3)\r\n        {\r\n            return std::make_unique<ConfigurationSetSerializer_0_3>();\r\n        }\r\n        else\r\n        {\r\n            AICLI_LOG(Config, Error, << \"Unknown configuration version: \" << schemaVersion.ToString());\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n    }\r\n\r\n    std::string ConfigurationSetSerializer::SerializeValueSet(const Windows::Foundation::Collections::ValueSet& valueSet)\r\n    {\r\n        Emitter emitter;\r\n        WriteYamlValueSet(emitter, valueSet);\r\n        return emitter.str();\r\n    }\r\n\r\n    std::string ConfigurationSetSerializer::SerializeStringArray(const Windows::Foundation::Collections::IVector<hstring>& stringArray)\r\n    {\r\n        Emitter emitter;\r\n        WriteYamlStringArray(emitter, stringArray);\r\n        return emitter.str();\r\n    }\r\n\r\n    void ConfigurationSetSerializer::WriteYamlValueSetIfNotEmpty(AppInstaller::YAML::Emitter& emitter, ConfigurationField key, const Windows::Foundation::Collections::ValueSet& valueSet, const OverrideMap& overrides)\r\n    {\r\n        anon::ValueSetWriter writer{ valueSet, overrides };\r\n\r\n        if (!writer.IsResultEmpty())\r\n        {\r\n            emitter << Key << GetConfigurationFieldName(key);\r\n            writer.Write(emitter, WriteYamlValue);\r\n        }\r\n    }\r\n\r\n    void ConfigurationSetSerializer::WriteYamlValueSet(AppInstaller::YAML::Emitter& emitter, const Windows::Foundation::Collections::ValueSet& valueSet, const OverrideMap& overrides)\r\n    {\r\n        anon::ValueSetWriter writer{ valueSet, overrides };\r\n        writer.Write(emitter, WriteYamlValue);\r\n    }\r\n\r\n    void ConfigurationSetSerializer::WriteYamlValueSetValues(AppInstaller::YAML::Emitter& emitter, const Windows::Foundation::Collections::ValueSet& valueSet, const OverrideMap& overrides)\r\n    {\r\n        anon::ValueSetWriter writer{ valueSet, overrides };\r\n        writer.WriteValues(emitter, WriteYamlValue);\r\n    }\r\n\r\n    void ConfigurationSetSerializer::WriteYamlStringArray(AppInstaller::YAML::Emitter& emitter, const Windows::Foundation::Collections::IVector<hstring>& values)\r\n    {\r\n        emitter << BeginSeq;\r\n\r\n        for (const auto& value : values)\r\n        {\r\n            emitter << ConvertToUTF8(value);\r\n        }\r\n\r\n        emitter << EndSeq;\r\n    }\r\n\r\n    void ConfigurationSetSerializer::WriteYamlValue(AppInstaller::YAML::Emitter& emitter, const winrt::Windows::Foundation::IInspectable& value)\r\n    {\r\n        if (value == nullptr)\r\n        {\r\n            emitter << anon::s_nullValue;\r\n        }\r\n        else\r\n        {\r\n            const auto& currentValueSet = value.try_as<Windows::Foundation::Collections::ValueSet>();\r\n            if (currentValueSet)\r\n            {\r\n                if (currentValueSet.HasKey(L\"treatAsArray\"))\r\n                {\r\n                    WriteYamlValueSetAsArray(emitter, currentValueSet);\r\n                }\r\n                else\r\n                {\r\n                    WriteYamlValueSet(emitter, currentValueSet);\r\n                }\r\n            }\r\n            else\r\n            {\r\n                IPropertyValue property = value.as<IPropertyValue>();\r\n                auto type = property.Type();\r\n\r\n                if (type == PropertyType::Boolean)\r\n                {\r\n                    emitter << property.GetBoolean();\r\n                }\r\n                else if (type == PropertyType::String)\r\n                {\r\n                    emitter << ScalarStyle::DoubleQuoted << ConvertToUTF8(property.GetString());\r\n                }\r\n                else if (type == PropertyType::Int64)\r\n                {\r\n                    emitter << property.GetInt64();\r\n                }\r\n                else\r\n                {\r\n                    THROW_HR(E_NOTIMPL);\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    void ConfigurationSetSerializer::WriteYamlValueIfNotEmpty(AppInstaller::YAML::Emitter& emitter, ConfigurationField key, const winrt::Windows::Foundation::IInspectable& value)\r\n    {\r\n        if (value != nullptr)\r\n        {\r\n            emitter << Key << GetConfigurationFieldName(key) << Value;\r\n            WriteYamlValue(emitter, value);\r\n        }\r\n    }\r\n\r\n    void ConfigurationSetSerializer::WriteYamlStringValueIfNotEmpty(AppInstaller::YAML::Emitter& emitter, ConfigurationField key, hstring value)\r\n    {\r\n        if (!value.empty())\r\n        {\r\n            emitter << Key << GetConfigurationFieldName(key) << Value << ConvertToUTF8(value);\r\n        }\r\n    }\r\n\r\n    void ConfigurationSetSerializer::WriteYamlValueSetAsArray(AppInstaller::YAML::Emitter& emitter, const Windows::Foundation::Collections::ValueSet& valueSetArray)\r\n    {\r\n        std::vector<std::pair<int, winrt::Windows::Foundation::IInspectable>> arrayValues;\r\n        for (const auto& arrayValue : valueSetArray)\r\n        {\r\n            if (arrayValue.Key() != L\"treatAsArray\")\r\n            {\r\n                arrayValues.emplace_back(std::make_pair(std::stoi(arrayValue.Key().c_str()), arrayValue.Value()));\r\n            }\r\n        }\r\n\r\n        std::sort(\r\n            arrayValues.begin(),\r\n            arrayValues.end(),\r\n            [](const std::pair<int, winrt::Windows::Foundation::IInspectable>& a, const std::pair<int, winrt::Windows::Foundation::IInspectable>& b)\r\n            {\r\n                return a.first < b.first;\r\n            });\r\n\r\n        emitter << BeginSeq;\r\n\r\n        for (const auto& arrayValue : arrayValues)\r\n        {\r\n            WriteYamlValue(emitter, arrayValue.second);\r\n        }\r\n\r\n        emitter << EndSeq;\r\n    }\r\n\r\n    std::wstring_view ConfigurationSetSerializer::GetSchemaVersionCommentPrefix()\r\n    {\r\n        return L\"# yaml-language-server: $schema=https://aka.ms/configuration-dsc-schema/\"sv;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationSetSerializer.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ConfigurationSetSerializer.h\"\r\n#include \"ConfigurationSetUtilities.h\"\r\n#include \"ConfigurationSet.h\"\r\n\r\n#include <winget/Yaml.h>\r\n#include <initializer_list>\r\n#include <string_view>\r\n#include <utility>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    struct ConfigurationSetSerializer\r\n    {\r\n        using OverrideMap = std::vector<std::pair<ConfigurationField, Windows::Foundation::IInspectable>>;\r\n\r\n        static std::unique_ptr<ConfigurationSetSerializer> CreateSerializer(hstring version, bool strictVersionMatching = false);\r\n\r\n        virtual ~ConfigurationSetSerializer() noexcept = default;\r\n\r\n        ConfigurationSetSerializer(const ConfigurationSetSerializer&) = delete;\r\n        ConfigurationSetSerializer& operator=(const ConfigurationSetSerializer&) = delete;\r\n        ConfigurationSetSerializer(ConfigurationSetSerializer&&) = default;\r\n        ConfigurationSetSerializer& operator=(ConfigurationSetSerializer&&) = default;\r\n\r\n        // Serializes a configuration set to the original yaml string.\r\n        virtual hstring Serialize(ConfigurationSet*) = 0;\r\n\r\n        // Serialize the metadata with the given environment.\r\n        virtual std::string SerializeMetadataWithEnvironment(const Windows::Foundation::Collections::ValueSet& metadata, const Configuration::ConfigurationEnvironment& environment) = 0;\r\n\r\n        // Serializes a value set only.\r\n        std::string SerializeValueSet(const Windows::Foundation::Collections::ValueSet& valueSet);\r\n\r\n        // Serializes a value set only.\r\n        std::string SerializeStringArray(const Windows::Foundation::Collections::IVector<hstring>& stringArray);\r\n\r\n    protected:\r\n        ConfigurationSetSerializer() = default;\r\n\r\n        static void WriteYamlValueSet(AppInstaller::YAML::Emitter& emitter, const Windows::Foundation::Collections::ValueSet& valueSet, const OverrideMap& overrides = {});\r\n        static void WriteYamlValueSetValues(AppInstaller::YAML::Emitter& emitter, const Windows::Foundation::Collections::ValueSet& valueSet, const OverrideMap& overrides = {});\r\n        static void WriteYamlValueSetIfNotEmpty(AppInstaller::YAML::Emitter& emitter, ConfigurationField key, const Windows::Foundation::Collections::ValueSet& valueSet, const OverrideMap& overrides = {});\r\n        static void WriteYamlValueSetAsArray(AppInstaller::YAML::Emitter& emitter, const Windows::Foundation::Collections::ValueSet& valueSetArray);\r\n\r\n        static void WriteYamlStringArray(AppInstaller::YAML::Emitter& emitter, const Windows::Foundation::Collections::IVector<hstring>& values);\r\n\r\n        static void WriteYamlValue(AppInstaller::YAML::Emitter& emitter, const winrt::Windows::Foundation::IInspectable& value);\r\n        static void WriteYamlValueIfNotEmpty(AppInstaller::YAML::Emitter& emitter, ConfigurationField key, const winrt::Windows::Foundation::IInspectable& value);\r\n        static void WriteYamlStringValueIfNotEmpty(AppInstaller::YAML::Emitter& emitter, ConfigurationField key, hstring value);\r\n\r\n        std::wstring_view GetSchemaVersionCommentPrefix();\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationSetSerializer_0_2.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigurationSetSerializer_0_2.h\"\r\n#include \"ConfigurationSetUtilities.h\"\r\n\r\n#include <AppInstallerStrings.h>\r\n\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::YAML;\r\nusing namespace winrt::Windows::Foundation;\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    hstring ConfigurationSetSerializer_0_2::Serialize(ConfigurationSet* configurationSet)\r\n    {\r\n        std::vector<ConfigurationUnit> assertions;\r\n        std::vector<ConfigurationUnit> resources;\r\n\r\n        for (auto unit : configurationSet->Units())\r\n        {\r\n            ConfigurationUnitIntent unitIntent = unit.Intent();\r\n\r\n            if (unitIntent == ConfigurationUnitIntent::Assert)\r\n            {\r\n                assertions.emplace_back(unit);\r\n            }\r\n            else if (unitIntent == ConfigurationUnitIntent::Apply)\r\n            {\r\n                resources.emplace_back(unit);\r\n            }\r\n        }\r\n\r\n        Emitter emitter;\r\n\r\n        emitter << BeginMap;\r\n        emitter << Key << GetConfigurationFieldName(ConfigurationField::Properties);\r\n\r\n        emitter << BeginMap;\r\n        emitter << Key << GetConfigurationFieldName(ConfigurationField::ConfigurationVersion) << Value << ConvertToUTF8(configurationSet->SchemaVersion());\r\n\r\n        if (!assertions.empty())\r\n        {\r\n            emitter << Key << GetConfigurationFieldName(ConfigurationField::Assertions);\r\n            WriteYamlConfigurationUnits(emitter, assertions);\r\n        }\r\n\r\n        if (!resources.empty())\r\n        {\r\n            emitter << Key << GetConfigurationFieldName(ConfigurationField::Resources);\r\n            WriteYamlConfigurationUnits(emitter, resources);\r\n        }\r\n\r\n        emitter << EndMap;\r\n        emitter << EndMap;\r\n\r\n        std::wostringstream result;\r\n        result << GetSchemaVersionCommentPrefix() << static_cast<std::wstring_view>(configurationSet->SchemaVersion()) << L\"\\n\" << ConvertToUTF16(emitter.str());\r\n        return hstring{ std::move(result).str() };\r\n    }\r\n\r\n    std::string ConfigurationSetSerializer_0_2::SerializeMetadataWithEnvironment(const Windows::Foundation::Collections::ValueSet& metadata, const Configuration::ConfigurationEnvironment& environment)\r\n    {\r\n        Emitter emitter;\r\n        WriteYamlValueSet(emitter, metadata, GetMetadataWithEnvironmentOverrides(false, environment.Context()));\r\n        return emitter.str();\r\n    }\r\n\r\n    void ConfigurationSetSerializer_0_2::WriteYamlConfigurationUnits(AppInstaller::YAML::Emitter& emitter, const std::vector<ConfigurationUnit>& units)\r\n    {\r\n        emitter << BeginSeq;\r\n\r\n        for (const auto& unit : units)\r\n        {\r\n            // Resource\r\n            emitter << BeginMap;\r\n            emitter << Key << GetConfigurationFieldName(ConfigurationField::Resource) << Value << AppInstaller::Utility::ConvertToUTF8(GetResourceName(unit));\r\n\r\n            // Id\r\n            if (!unit.Identifier().empty())\r\n            {\r\n                emitter << Key << GetConfigurationFieldName(ConfigurationField::Id) << Value << AppInstaller::Utility::ConvertToUTF8(unit.Identifier());\r\n            }\r\n\r\n            // Dependencies\r\n            if (unit.Dependencies().Size() > 0)\r\n            {\r\n                emitter << Key << GetConfigurationFieldName(ConfigurationField::DependsOn);\r\n                emitter << BeginSeq;\r\n\r\n                for (const auto& dependency : unit.Dependencies())\r\n                {\r\n                    emitter << AppInstaller::Utility::ConvertToUTF8(dependency);\r\n                }\r\n\r\n                emitter << EndSeq;\r\n            }\r\n\r\n            // Directives\r\n            WriteResourceDirectives(emitter, unit);\r\n\r\n            // Settings\r\n            const auto& settings = unit.Settings();\r\n            emitter << Key << GetConfigurationFieldName(ConfigurationField::Settings);\r\n            WriteYamlValueSet(emitter, settings);\r\n\r\n            emitter << EndMap;\r\n        }\r\n\r\n        emitter << EndSeq;\r\n    }\r\n\r\n    winrt::hstring ConfigurationSetSerializer_0_2::GetResourceName(const ConfigurationUnit& unit)\r\n    {\r\n        const auto& metadata = unit.Metadata();\r\n        const auto moduleKey = GetConfigurationFieldNameHString(ConfigurationField::ModuleDirective);\r\n        if (metadata.HasKey(moduleKey))\r\n        {\r\n            auto object = metadata.Lookup(moduleKey);\r\n            auto property = object.try_as<IPropertyValue>();\r\n            if (property && property.Type() == PropertyType::String)\r\n            {\r\n                return property.GetString() + '/' + unit.Type();\r\n            }\r\n        }\r\n\r\n        return unit.Type();\r\n    }\r\n\r\n    void ConfigurationSetSerializer_0_2::WriteResourceDirectives(AppInstaller::YAML::Emitter& emitter, const ConfigurationUnit& unit)\r\n    {\r\n        WriteYamlValueSetIfNotEmpty(emitter, ConfigurationField::Directives, unit.Metadata(), GetMetadataWithEnvironmentOverrides(true, unit.Environment().Context()));\r\n    }\r\n\r\n    ConfigurationSetSerializer::OverrideMap ConfigurationSetSerializer_0_2::GetMetadataWithEnvironmentOverrides(bool includeModuleOverride, SecurityContext securityContext)\r\n    {\r\n        ConfigurationSetSerializer::OverrideMap result {\r\n            { ConfigurationField::SecurityContextMetadata, (securityContext != SecurityContext::Current ? PropertyValue::CreateString(ToWString(securityContext)) : nullptr)}\r\n        };\r\n\r\n        if (includeModuleOverride)\r\n        {\r\n            result.emplace_back(ConfigurationField::ModuleDirective, nullptr);\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationSetSerializer_0_2.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ConfigurationSetSerializer.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    // Serializer for schema version 0.2\r\n    struct ConfigurationSetSerializer_0_2 : public ConfigurationSetSerializer\r\n    {\r\n        ConfigurationSetSerializer_0_2() {}\r\n\r\n        virtual ~ConfigurationSetSerializer_0_2() noexcept = default;\r\n\r\n        ConfigurationSetSerializer_0_2(const ConfigurationSetSerializer_0_2&) = delete;\r\n        ConfigurationSetSerializer_0_2& operator=(const ConfigurationSetSerializer_0_2&) = delete;\r\n        ConfigurationSetSerializer_0_2(ConfigurationSetSerializer_0_2&&) = default;\r\n        ConfigurationSetSerializer_0_2& operator=(ConfigurationSetSerializer_0_2&&) = default;\r\n\r\n        hstring Serialize(ConfigurationSet* configurationSet) override;\r\n\r\n        std::string SerializeMetadataWithEnvironment(const Windows::Foundation::Collections::ValueSet& metadata, const Configuration::ConfigurationEnvironment& environment) override;\r\n\r\n    protected:\r\n        void WriteYamlConfigurationUnits(AppInstaller::YAML::Emitter& emitter, const std::vector<ConfigurationUnit>& units);\r\n\r\n        virtual winrt::hstring GetResourceName(const ConfigurationUnit& unit);\r\n        virtual void WriteResourceDirectives(AppInstaller::YAML::Emitter& emitter, const ConfigurationUnit& unit);\r\n        static ConfigurationSetSerializer::OverrideMap GetMetadataWithEnvironmentOverrides(bool includeModuleOverride, SecurityContext securityContext);\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationSetSerializer_0_3.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigurationSetSerializer_0_3.h\"\r\n#include \"ArgumentValidation.h\"\r\n#include \"ConfigurationSetParser_0_3.h\"\r\n#include \"ConfigurationSetUtilities.h\"\r\n#include \"ConfigurationEnvironment.h\"\r\n#include <AppInstallerErrors.h>\r\n#include <AppInstallerStrings.h>\r\n\r\nusing namespace AppInstaller::Utility;\r\nusing namespace AppInstaller::YAML;\r\nusing namespace winrt::Windows::Foundation;\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    namespace\r\n    {\r\n        Windows::Foundation::Collections::ValueSet GetWingetProcessorMetadataValueSet(Windows::Foundation::Collections::ValueSet& metadata)\r\n        {\r\n            Windows::Foundation::Collections::ValueSet result = nullptr;\r\n            hstring processorMetadataKey = GetConfigurationFieldNameHString(ConfigurationField::ProcessorMetadata);\r\n\r\n            if (metadata)\r\n            {\r\n                Windows::Foundation::IInspectable processorMetadataObject = metadata.TryLookup(processorMetadataKey);\r\n                if (processorMetadataObject)\r\n                {\r\n                    result = processorMetadataObject.try_as<Windows::Foundation::Collections::ValueSet>();\r\n                    THROW_HR_IF(WINGET_CONFIG_ERROR_INVALID_FIELD_VALUE, !result);\r\n                }\r\n            }\r\n            else\r\n            {\r\n                metadata = Collections::ValueSet{};\r\n            }\r\n\r\n            if (!result)\r\n            {\r\n                result = Collections::ValueSet{};\r\n                metadata.Insert(processorMetadataKey, result);\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        Windows::Foundation::Collections::ValueSet CreateValueSetFromStringMap(const Windows::Foundation::Collections::IMap<hstring, hstring>& map)\r\n        {\r\n            Windows::Foundation::Collections::ValueSet result;\r\n            if (map)\r\n            {\r\n                for (const auto& item : map)\r\n                {\r\n                    result.Insert(item.Key(), PropertyValue::CreateString(item.Value()));\r\n                }\r\n            }\r\n            return result;\r\n        }\r\n\r\n        void AddEnvironmentToMetadata(\r\n            Windows::Foundation::Collections::ValueSet& metadata,\r\n            SecurityContext context,\r\n            hstring processor,\r\n            Windows::Foundation::Collections::IMap<hstring, hstring> properties,\r\n            SecurityContext defaultContext = SecurityContext::Current,\r\n            hstring defaultProcessor = {},\r\n            Windows::Foundation::Collections::IMap<hstring, hstring> defaultProperties = nullptr)\r\n        {\r\n            if (context != defaultContext)\r\n            {\r\n                if (!metadata)\r\n                {\r\n                    metadata = Collections::ValueSet{};\r\n                }\r\n\r\n                metadata.Insert(GetConfigurationFieldNameHString(ConfigurationField::SecurityContextMetadata), PropertyValue::CreateString(ToWString(context)));\r\n            }\r\n\r\n            Windows::Foundation::Collections::ValueSet processorValueSet{ nullptr };\r\n\r\n            if (processor != defaultProcessor)\r\n            {\r\n                if (!processorValueSet)\r\n                {\r\n                    processorValueSet = GetWingetProcessorMetadataValueSet(metadata);\r\n                }\r\n\r\n                processorValueSet.Insert(GetConfigurationFieldNameHString(ConfigurationField::ProcessorIdentifierMetadata), PropertyValue::CreateString(processor));\r\n            }\r\n\r\n            if (!ConfigurationEnvironment::AreEqual(properties, defaultProperties))\r\n            {\r\n                if (!processorValueSet)\r\n                {\r\n                    processorValueSet = GetWingetProcessorMetadataValueSet(metadata);\r\n                }\r\n\r\n                processorValueSet.Insert(GetConfigurationFieldNameHString(ConfigurationField::ProcessorPropertiesMetadata), CreateValueSetFromStringMap(properties));\r\n            }\r\n        }\r\n\r\n        void AddEnvironmentToMetadata(\r\n            Windows::Foundation::Collections::ValueSet& metadata,\r\n            const com_ptr<implementation::ConfigurationEnvironment>& environment)\r\n        {\r\n            if (environment)\r\n            {\r\n                AddEnvironmentToMetadata(metadata, environment->Context(), environment->ProcessorIdentifier(), environment->ProcessorProperties());\r\n            }\r\n        }\r\n\r\n        void AddEnvironmentToMetadata(\r\n            Windows::Foundation::Collections::ValueSet& metadata,\r\n            const Configuration::ConfigurationEnvironment& environment)\r\n        {\r\n            AddEnvironmentToMetadata(metadata,\r\n                environment.Context(), environment.ProcessorIdentifier(), environment.ProcessorProperties());\r\n        }\r\n    }\r\n\r\n    hstring ConfigurationSetSerializer_0_3::Serialize(ConfigurationSet* configurationSet)\r\n    {\r\n        Emitter emitter;\r\n\r\n        emitter << BeginMap;\r\n\r\n        emitter << Key << GetConfigurationFieldName(ConfigurationField::Schema) << Value << ConvertToUTF8(configurationSet->SchemaUri().ToString());\r\n\r\n        // Prepare an override if necessary\r\n        Collections::ValueSet wingetMetadataOverride = nullptr;\r\n        AddEnvironmentToMetadata(wingetMetadataOverride, configurationSet->EnvironmentInternal());\r\n\r\n        WriteYamlValueSetIfNotEmpty(emitter, ConfigurationField::Metadata, configurationSet->Metadata(),\r\n            {\r\n                { ConfigurationField::WingetMetadataRoot, wingetMetadataOverride },\r\n                { ConfigurationField::SecurityContextMetadata, nullptr },\r\n            });\r\n\r\n        WriteYamlParameters(emitter, configurationSet->Parameters());\r\n        WriteYamlValueSetIfNotEmpty(emitter, ConfigurationField::Variables, configurationSet->Variables());\r\n        WriteYamlConfigurationUnits(emitter, configurationSet->Units());\r\n\r\n        emitter << EndMap;\r\n\r\n        std::wostringstream result;\r\n        result << GetSchemaVersionCommentPrefix() << static_cast<std::wstring_view>(configurationSet->SchemaVersion()) << L\"\\n\" << ConvertToUTF16(emitter.str());\r\n        return hstring{ std::move(result).str() };\r\n    }\r\n\r\n    std::string ConfigurationSetSerializer_0_3::SerializeMetadataWithEnvironment(const Windows::Foundation::Collections::ValueSet& metadata, const Configuration::ConfigurationEnvironment& environment)\r\n    {\r\n        Emitter emitter;\r\n\r\n        Collections::ValueSet wingetMetadataOverride = nullptr;\r\n        AddEnvironmentToMetadata(wingetMetadataOverride, environment);\r\n\r\n        WriteYamlValueSet(emitter, metadata,\r\n            {\r\n                { ConfigurationField::WingetMetadataRoot, wingetMetadataOverride },\r\n                { ConfigurationField::SecurityContextMetadata, nullptr },\r\n            });\r\n\r\n        return emitter.str();\r\n    }\r\n\r\n    void ConfigurationSetSerializer_0_3::WriteYamlParameters(AppInstaller::YAML::Emitter& emitter, const Windows::Foundation::Collections::IVector<Configuration::ConfigurationParameter>& values)\r\n    {\r\n        if (!values || values.Size() == 0)\r\n        {\r\n            return;\r\n        }\r\n\r\n        emitter << Key << GetConfigurationFieldName(ConfigurationField::Parameters);\r\n\r\n        emitter << BeginMap;\r\n\r\n        for (const Configuration::ConfigurationParameter& parameter : values)\r\n        {\r\n            emitter << Key << ConvertToUTF8(parameter.Name());\r\n\r\n            emitter << BeginMap;\r\n\r\n            auto type = parameter.Type();\r\n\r\n            emitter << Key << GetConfigurationFieldName(ConfigurationField::Type) << Value << ToString(type, parameter.IsSecure());\r\n            WriteYamlValueSetIfNotEmpty(emitter, ConfigurationField::Metadata, parameter.Metadata());\r\n            WriteYamlStringValueIfNotEmpty(emitter, ConfigurationField::Description, parameter.Description());\r\n            WriteYamlValueIfNotEmpty(emitter, ConfigurationField::DefaultValue, parameter.DefaultValue());\r\n\r\n            auto allowedValues = parameter.AllowedValues();\r\n            if (allowedValues && allowedValues.Size() != 0)\r\n            {\r\n                emitter << Key << GetConfigurationFieldName(ConfigurationField::AllowedValues);\r\n\r\n                emitter << BeginSeq;\r\n\r\n                for (const auto& value : allowedValues)\r\n                {\r\n                    emitter << Value;\r\n                    WriteYamlValue(emitter, value);\r\n                }\r\n\r\n                emitter << EndSeq;\r\n            }\r\n\r\n            if (IsLengthType(type))\r\n            {\r\n                uint32_t minimumLength = parameter.MinimumLength();\r\n                if (minimumLength != 0)\r\n                {\r\n                    emitter << Key << GetConfigurationFieldName(ConfigurationField::MinimumLength) << Value << static_cast<int64_t>(minimumLength);\r\n                }\r\n\r\n                uint32_t maximumLength = parameter.MaximumLength();\r\n                if (maximumLength != std::numeric_limits<uint32_t>::max())\r\n                {\r\n                    emitter << Key << GetConfigurationFieldName(ConfigurationField::MaximumLength) << Value << static_cast<int64_t>(maximumLength);\r\n                }\r\n            }\r\n\r\n            if (IsComparableType(type))\r\n            {\r\n                WriteYamlValueIfNotEmpty(emitter, ConfigurationField::MinimumValue, parameter.MinimumValue());\r\n                WriteYamlValueIfNotEmpty(emitter, ConfigurationField::MaximumValue, parameter.MaximumValue());\r\n            }\r\n\r\n            emitter << EndMap;\r\n        }\r\n\r\n        emitter << EndMap;\r\n    }\r\n\r\n    void ConfigurationSetSerializer_0_3::WriteYamlConfigurationUnits(\r\n        AppInstaller::YAML::Emitter& emitter,\r\n        const Windows::Foundation::Collections::IVector<Configuration::ConfigurationUnit>& values)\r\n    {\r\n        emitter << Key << GetConfigurationFieldName(ConfigurationField::Resources);\r\n\r\n        emitter << BeginSeq;\r\n\r\n        for (const Configuration::ConfigurationUnit& unit : values)\r\n        {\r\n            emitter << BeginMap;\r\n\r\n            hstring identifier = unit.Identifier();\r\n            THROW_HR_IF(WINGET_CONFIG_ERROR_MISSING_FIELD, identifier.empty());\r\n            emitter << Key << GetConfigurationFieldName(ConfigurationField::Name) << Value << ConvertToUTF8(identifier);\r\n\r\n            hstring type = unit.Type();\r\n            THROW_HR_IF(WINGET_CONFIG_ERROR_MISSING_FIELD, type.empty());\r\n            emitter << Key << GetConfigurationFieldName(ConfigurationField::Type) << Value << ConvertToUTF8(type);\r\n\r\n            // Prepare an override if necessary\r\n            Collections::ValueSet wingetMetadataOverride = nullptr;\r\n            Configuration::ConfigurationEnvironment unitEnvironment = unit.Environment();\r\n            AddEnvironmentToMetadata(wingetMetadataOverride, unitEnvironment);\r\n\r\n            WriteYamlValueSetIfNotEmpty(emitter, ConfigurationField::Metadata, unit.Metadata(),\r\n                { { ConfigurationField::WingetMetadataRoot, wingetMetadataOverride } });\r\n\r\n            auto dependencies = unit.Dependencies();\r\n            if (dependencies && dependencies.Size() != 0)\r\n            {\r\n                emitter << Key << GetConfigurationFieldName(ConfigurationField::DependsOn);\r\n\r\n                emitter << BeginSeq;\r\n\r\n                for (const auto& value : dependencies)\r\n                {\r\n                    emitter << ConvertToUTF8(value);\r\n                }\r\n\r\n                emitter << EndSeq;\r\n            }\r\n\r\n            // If this unit is a group, write the units directly\r\n            if (unit.IsGroup())\r\n            {\r\n                auto groupUnits = unit.Units();\r\n\r\n                if (groupUnits.Size() != 0)\r\n                {\r\n                    emitter << Key << GetConfigurationFieldName(ConfigurationField::Properties);\r\n                    emitter << BeginMap;\r\n\r\n                    // Write everything but the resources\r\n                    WriteYamlValueSetValues(emitter, unit.Settings(),\r\n                        { { ConfigurationField::Resources, nullptr } });\r\n\r\n                    // Write the resources from the individual units\r\n                    WriteYamlConfigurationUnits(emitter, groupUnits);\r\n\r\n                    emitter << EndMap;\r\n                }\r\n            }\r\n            else\r\n            {\r\n                WriteYamlValueSetIfNotEmpty(emitter, ConfigurationField::Properties, unit.Settings());\r\n            }\r\n\r\n            emitter << EndMap;\r\n        }\r\n\r\n        emitter << EndSeq;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationSetSerializer_0_3.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ConfigurationSetSerializer.h\"\r\n#include \"ConfigurationEnvironment.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    // Serializer for schema version 0.3\r\n    struct ConfigurationSetSerializer_0_3 : public ConfigurationSetSerializer\r\n    {\r\n        ConfigurationSetSerializer_0_3() {}\r\n\r\n        virtual ~ConfigurationSetSerializer_0_3() noexcept = default;\r\n\r\n        ConfigurationSetSerializer_0_3(const ConfigurationSetSerializer_0_3&) = delete;\r\n        ConfigurationSetSerializer_0_3& operator=(const ConfigurationSetSerializer_0_3&) = delete;\r\n        ConfigurationSetSerializer_0_3(ConfigurationSetSerializer_0_3&&) = default;\r\n        ConfigurationSetSerializer_0_3& operator=(ConfigurationSetSerializer_0_3&&) = default;\r\n\r\n        hstring Serialize(ConfigurationSet* configurationSet) override;\r\n\r\n        std::string SerializeMetadataWithEnvironment(const Windows::Foundation::Collections::ValueSet& metadata, const Configuration::ConfigurationEnvironment& environment) override;\r\n\r\n    protected:\r\n        void WriteYamlParameters(AppInstaller::YAML::Emitter& emitter, const Windows::Foundation::Collections::IVector<Configuration::ConfigurationParameter>& values);\r\n        void WriteYamlConfigurationUnits(\r\n            AppInstaller::YAML::Emitter& emitter,\r\n            const Windows::Foundation::Collections::IVector<Configuration::ConfigurationUnit>& values);\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationSetUtilities.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigurationSetUtilities.h\"\r\n#include <AppInstallerStrings.h>\r\n\r\nusing namespace std::string_view_literals;\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    std::string_view GetConfigurationFieldName(ConfigurationField fieldName)\r\n    {\r\n        switch (fieldName)\r\n        {\r\n        case ConfigurationField::ConfigurationVersion: return \"configurationVersion\"sv;\r\n        case ConfigurationField::Properties: return \"properties\"sv;\r\n        case ConfigurationField::Resource: return \"resource\"sv;\r\n        case ConfigurationField::Directives: return \"directives\"sv;\r\n        case ConfigurationField::Settings: return \"settings\"sv;\r\n        case ConfigurationField::Assertions: return \"assertions\"sv;\r\n        case ConfigurationField::Id: return \"id\"sv;\r\n        case ConfigurationField::DependsOn: return \"dependsOn\"sv;\r\n\r\n        case ConfigurationField::Resources: return \"resources\"sv;\r\n        case ConfigurationField::ModuleDirective: return \"module\"sv;\r\n        case ConfigurationField::SecurityContextMetadata: return \"securityContext\"sv;\r\n\r\n        case ConfigurationField::Schema: return \"$schema\"sv;\r\n        case ConfigurationField::Metadata: return \"metadata\"sv;\r\n        case ConfigurationField::Parameters: return \"parameters\"sv;\r\n        case ConfigurationField::Variables: return \"variables\"sv;\r\n        case ConfigurationField::Type: return \"type\"sv;\r\n        case ConfigurationField::Description: return \"description\"sv;\r\n        case ConfigurationField::Name: return \"name\"sv;\r\n        case ConfigurationField::IsGroupMetadata: return \"isGroup\"sv;\r\n        case ConfigurationField::DefaultValue: return \"defaultValue\"sv;\r\n        case ConfigurationField::AllowedValues: return \"allowedValues\"sv;\r\n        case ConfigurationField::MinimumLength: return \"minLength\"sv;\r\n        case ConfigurationField::MaximumLength: return \"maxLength\"sv;\r\n        case ConfigurationField::MinimumValue: return \"minValue\"sv;\r\n        case ConfigurationField::MaximumValue: return \"maxValue\"sv;\r\n        case ConfigurationField::WingetMetadataRoot: return \"winget\"sv;\r\n        case ConfigurationField::ProcessorMetadata: return \"processor\"sv;\r\n        case ConfigurationField::ProcessorIdentifierMetadata: return \"identifier\"sv;\r\n        case ConfigurationField::ProcessorPropertiesMetadata: return \"properties\"sv;\r\n        }\r\n\r\n        THROW_HR(E_UNEXPECTED);\r\n    }\r\n\r\n    hstring GetConfigurationFieldNameHString(ConfigurationField fieldName)\r\n    {\r\n        return hstring{ AppInstaller::Utility::ConvertToUTF16(GetConfigurationFieldName(fieldName)) };\r\n    }\r\n\r\n    bool TryParseSecurityContext(const hstring& value, SecurityContext& result)\r\n    {\r\n        std::wstring securityContextLower = AppInstaller::Utility::ToLower(value);\r\n\r\n        if (securityContextLower == L\"elevated\")\r\n        {\r\n            result = SecurityContext::Elevated;\r\n        }\r\n        else if (securityContextLower == L\"restricted\")\r\n        {\r\n            result = SecurityContext::Restricted;\r\n        }\r\n        else if (securityContextLower == L\"current\")\r\n        {\r\n            result = SecurityContext::Current;\r\n        }\r\n        else\r\n        {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    SecurityContext ParseSecurityContext(const hstring& value)\r\n    {\r\n        SecurityContext result = SecurityContext::Current;\r\n        THROW_HR_IF(E_INVALIDARG, !TryParseSecurityContext(value, result));\r\n        return result;\r\n    }\r\n\r\n    std::string_view ToString(SecurityContext value)\r\n    {\r\n        switch (value)\r\n        {\r\n        case SecurityContext::Current: return \"current\";\r\n        case SecurityContext::Restricted: return \"restricted\";\r\n        case SecurityContext::Elevated: return \"elevated\";\r\n        }\r\n\r\n        THROW_HR(E_INVALIDARG);\r\n    }\r\n\r\n    std::wstring_view ToWString(SecurityContext value)\r\n    {\r\n        switch (value)\r\n        {\r\n        case SecurityContext::Current: return L\"current\";\r\n        case SecurityContext::Restricted: return L\"restricted\";\r\n        case SecurityContext::Elevated: return L\"elevated\";\r\n        }\r\n\r\n        THROW_HR(E_INVALIDARG);\r\n    }\r\n\r\n    Windows::Foundation::Collections::ValueSet TryLookupValueSet(const Windows::Foundation::Collections::ValueSet& valueSet, ConfigurationField field)\r\n    {\r\n        Windows::Foundation::IInspectable value = valueSet.TryLookup(GetConfigurationFieldNameHString(field));\r\n\r\n        if (value)\r\n        {\r\n            return value.try_as<Windows::Foundation::Collections::ValueSet>();\r\n        }\r\n\r\n        return nullptr;\r\n    }\r\n\r\n    Windows::Foundation::IPropertyValue TryLookupProperty(const Windows::Foundation::Collections::ValueSet& valueSet, ConfigurationField field, Windows::Foundation::PropertyType type)\r\n    {\r\n        Windows::Foundation::IInspectable value = valueSet.TryLookup(GetConfigurationFieldNameHString(field));\r\n\r\n        if (value)\r\n        {\r\n            Windows::Foundation::IPropertyValue property = value.try_as<Windows::Foundation::IPropertyValue>();\r\n            if (property && (type == Windows::Foundation::PropertyType::Empty || property.Type() == type))\r\n            {\r\n                return property;\r\n            }\r\n        }\r\n\r\n        return nullptr;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationSetUtilities.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <string_view>\r\n#include <winrt/Microsoft.Management.Configuration.h>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    // The various configuration fields that are used in parsing/serialization.\r\n    enum class ConfigurationField\r\n    {\r\n        // v0.1 and v0.2\r\n        ConfigurationVersion,\r\n        Properties,\r\n        Resource,\r\n        Directives,\r\n        Settings,\r\n        Assertions,\r\n        Id,\r\n        DependsOn,\r\n\r\n        // Universal\r\n        Resources,\r\n        ModuleDirective,\r\n        SecurityContextMetadata,\r\n\r\n        // v0.3\r\n        Schema,\r\n        Metadata,\r\n        Parameters,\r\n        Variables,\r\n        Type,\r\n        Description,\r\n        Name,\r\n        IsGroupMetadata,\r\n        DefaultValue,\r\n        AllowedValues,\r\n        MinimumLength,\r\n        MaximumLength,\r\n        MinimumValue,\r\n        MaximumValue,\r\n        WingetMetadataRoot,\r\n        ProcessorMetadata,\r\n        ProcessorIdentifierMetadata,\r\n        ProcessorPropertiesMetadata,\r\n    };\r\n\r\n    // Gets the name value of the configuration field.\r\n    std::string_view GetConfigurationFieldName(ConfigurationField fieldName);\r\n\r\n    winrt::hstring GetConfigurationFieldNameHString(ConfigurationField fieldName);\r\n\r\n    // Attempts to parse a security context from a string.\r\n    // Returns true if successful; false otherwise.\r\n    bool TryParseSecurityContext(const hstring& value, SecurityContext& result);\r\n\r\n    // Parses a security context from a string.\r\n    SecurityContext ParseSecurityContext(const hstring& value);\r\n\r\n    // Gets the string representation of a security context.\r\n    std::string_view ToString(SecurityContext value);\r\n\r\n    // Gets the string representation of a security context.\r\n    std::wstring_view ToWString(SecurityContext value);\r\n\r\n    // Tries to get the field value from the given value set; only if it is a value set.\r\n    Windows::Foundation::Collections::ValueSet TryLookupValueSet(const Windows::Foundation::Collections::ValueSet& valueSet, ConfigurationField field);\r\n\r\n    // Tries to get the field value from the given value set; only if it is a value set.\r\n    Windows::Foundation::IPropertyValue TryLookupProperty(const Windows::Foundation::Collections::ValueSet& valueSet, ConfigurationField field, Windows::Foundation::PropertyType type = Windows::Foundation::PropertyType::Empty);\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationStaticFunctions.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"ConfigurationStaticFunctions.h\"\n#include \"ConfigurationStaticFunctions.g.cpp\"\n#include \"ConfigurationUnit.h\"\n#include \"ConfigurationSet.h\"\n#include \"ConfigurationProcessor.h\"\n#include \"ConfigurationParameter.h\"\r\n#include \"FindUnitProcessorsOptions.h\"\r\n#include \"ShutdownSynchronization.h\"\n#include <AppInstallerStrings.h>\n#include <winget/ConfigurationSetProcessorHandlers.h>\n\nnamespace winrt::Microsoft::Management::Configuration::implementation\n{\n    Configuration::ConfigurationUnit ConfigurationStaticFunctions::CreateConfigurationUnit()\n    {\n        return *make_self<implementation::ConfigurationUnit>();\n    }\n\n    Configuration::ConfigurationSet ConfigurationStaticFunctions::CreateConfigurationSet()\n    {\n        return *make_self<implementation::ConfigurationSet>();\n    }\n\n    Windows::Foundation::IAsyncOperation<IConfigurationSetProcessorFactory> ConfigurationStaticFunctions::CreateConfigurationSetProcessorFactoryAsync(hstring const& handler)\n    {\n        std::wstring lowerHandler = AppInstaller::Utility::ToLower(handler);\n\n        if (lowerHandler == AppInstaller::Configuration::PowerShellHandlerIdentifier)\n        {\n            THROW_HR(E_NOTIMPL);\n        }\n\n        AICLI_LOG(Config, Error, << \"Unknown handler in CreateConfigurationSetProcessorFactory: \" << AppInstaller::Utility::ConvertToUTF8(handler));\n        THROW_HR(E_NOT_SET);\n    }\n\n    Configuration::ConfigurationProcessor ConfigurationStaticFunctions::CreateConfigurationProcessor(IConfigurationSetProcessorFactory const& factory)\n    {\n        auto result = make_self<wil::details::module_count_wrapper<implementation::ConfigurationProcessor>>();\n        result->ConfigurationSetProcessorFactory(factory);\n        return *result;\n    }\n\n    Windows::Foundation::IAsyncActionWithProgress<uint32_t> ConfigurationStaticFunctions::EnsureConfigurationAvailableAsync()\n    {\n        THROW_HR(E_NOTIMPL);\n    }\n\n    Configuration::ConfigurationParameter ConfigurationStaticFunctions::CreateConfigurationParameter()\n    {\n        return *make_self<wil::details::module_count_wrapper<implementation::ConfigurationParameter>>();\n    }\n\n    Configuration::FindUnitProcessorsOptions ConfigurationStaticFunctions::CreateFindUnitProcessorsOptions()\n    {\n        return *make_self<wil::details::module_count_wrapper<implementation::FindUnitProcessorsOptions>>();\n    }\n\n    HRESULT STDMETHODCALLTYPE ConfigurationStaticFunctions::SetExperimentalState(UINT32 state)\n    {\n        m_state = static_cast<AppInstaller::WinRT::ConfigurationStaticsInternalsStateFlags>(state);\n        return S_OK;\n    }\r\n\r\n    HRESULT STDMETHODCALLTYPE ConfigurationStaticFunctions::BlockNewWorkForShutdown()\r\n    {\r\n        ShutdownSynchronization::Instance().BlockNewWork();\r\n        return S_OK;\n    }\r\n\r\n    HRESULT STDMETHODCALLTYPE ConfigurationStaticFunctions::BeginShutdown()\r\n    {\r\n        ShutdownSynchronization::Instance().CancelAllWork();\r\n        return S_OK;\n    }\r\n\r\n    HRESULT STDMETHODCALLTYPE ConfigurationStaticFunctions::WaitForShutdown()\r\n    {\r\n        ShutdownSynchronization::Instance().Wait();\n        return S_OK;\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationStaticFunctions.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"ConfigurationStaticFunctions.g.h\"\n#include <winget/IConfigurationStaticsInternals.h>\n\nnamespace winrt::Microsoft::Management::Configuration::implementation\n{\n    struct ConfigurationStaticFunctions : ConfigurationStaticFunctionsT<ConfigurationStaticFunctions, winrt::cloaked<AppInstaller::WinRT::IConfigurationStaticsInternals>>\n    { \n        ConfigurationStaticFunctions() = default;\n\n        Configuration::ConfigurationUnit CreateConfigurationUnit();\n        Configuration::ConfigurationSet CreateConfigurationSet();\n        Windows::Foundation::IAsyncOperation<IConfigurationSetProcessorFactory> CreateConfigurationSetProcessorFactoryAsync(hstring const& handler);\n        Configuration::ConfigurationProcessor CreateConfigurationProcessor(IConfigurationSetProcessorFactory const& factory);\n        bool IsConfigurationAvailable() { return true; }\n        Windows::Foundation::IAsyncActionWithProgress<uint32_t> EnsureConfigurationAvailableAsync();\n        Configuration::ConfigurationParameter CreateConfigurationParameter();\r\n        Configuration::FindUnitProcessorsOptions CreateFindUnitProcessorsOptions();\n\n        // IConfigurationStaticsInternals\n        HRESULT STDMETHODCALLTYPE SetExperimentalState(UINT32 state);\r\n        HRESULT STDMETHODCALLTYPE BlockNewWorkForShutdown();\r\n        HRESULT STDMETHODCALLTYPE BeginShutdown();\r\n        HRESULT STDMETHODCALLTYPE WaitForShutdown();\n\n    private:\n        // By default, enable all state so that in-proc usage contains it.\n        AppInstaller::WinRT::ConfigurationStaticsInternalsStateFlags m_state = AppInstaller::WinRT::ConfigurationStaticsInternalsStateFlags::All;\n    };\n}\nnamespace winrt::Microsoft::Management::Configuration::factory_implementation\n{\n    struct ConfigurationStaticFunctions : ConfigurationStaticFunctionsT<ConfigurationStaticFunctions, implementation::ConfigurationStaticFunctions>\n    {\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationStatus.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigurationStatus.h\"\r\n#include \"ConfigurationChangeData.h\"\r\n#include \"ConfigurationProcessor.h\"\r\n#include \"ConfigurationSet.h\"\r\n#include \"ConfigurationUnitResultInformation.h\"\r\n#include <AppInstallerStrings.h>\r\n#include <AppInstallerLanguageUtilities.h>\r\n\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    namespace details\r\n    {\r\n        // Implements the consuming side of the status signaling.\r\n        struct ChangeListener\r\n        {\r\n            struct SetStatusItem\r\n            {\r\n                ConfigurationDatabase::StatusItem Status;\r\n                com_ptr<implementation::ConfigurationSet> Set;\r\n            };\r\n\r\n            ChangeListener(ConfigurationStatus& status) : m_status(status)\r\n            {\r\n                ConfigurationDatabase::StatusBaseline baseline = m_status.Database().GetStatusBaseline();\r\n                m_changeIdentifier = baseline.ChangeIdentifier;\r\n\r\n                for (const auto& item : baseline.SetStatus)\r\n                {\r\n                    m_lastSetStatus.emplace(item.SetInstanceIdentifier, SetStatusItem{ item });\r\n                }\r\n\r\n                std::wstring objectName = L\"WinGetConfigListener_\" + AppInstaller::Utility::CreateNewGuidNameWString();\r\n                m_listenerEventName = AppInstaller::Utility::ConvertToUTF8(objectName);\r\n                m_listenerEvent.create(wil::EventOptions::None, objectName.c_str());\r\n\r\n                m_status.Database().AddListener(m_listenerEventName);\r\n\r\n                m_threadPoolWait.reset(CreateThreadpoolWait(StaticWaitCallback, this, nullptr));\r\n                THROW_LAST_ERROR_IF(!m_threadPoolWait);\r\n\r\n                SetThreadpoolWait(m_threadPoolWait.get(), m_listenerEvent.get(), NULL);\r\n            }\r\n\r\n            ~ChangeListener()\r\n            {\r\n                try\r\n                {\r\n                    m_status.Database().RemoveListener(m_listenerEventName);\r\n                }\r\n                CATCH_LOG();\r\n            }\r\n\r\n        private:\r\n            static void NTAPI StaticWaitCallback(PTP_CALLBACK_INSTANCE, void* context, TP_WAIT*, TP_WAIT_RESULT)\r\n            {\r\n                reinterpret_cast<ChangeListener*>(context)->WaitCallback();\r\n            }\r\n\r\n            void WaitCallback() try\r\n            {\r\n                std::vector<ConfigurationDatabase::StatusItem> changes = m_status.Database().GetStatusSince(m_changeIdentifier);\r\n\r\n                // Convert status items to relevant change information\r\n                for (const auto& change : changes)\r\n                {\r\n                    if (change.UnitInstanceIdentifier)\r\n                    {\r\n                        if (m_status.HasSetChangeRegistration(change.SetInstanceIdentifier))\r\n                        {\r\n                            // A unit status change\r\n                            ConfigurationUnitState state = AppInstaller::ToEnum<ConfigurationUnitState>(change.State);\r\n\r\n                            decltype(make_self<wil::details::module_count_wrapper<implementation::ConfigurationUnitResultInformation>>()) resultInformation;\r\n\r\n                            if (change.ResultCode)\r\n                            {\r\n                                resultInformation = make_self<wil::details::module_count_wrapper<implementation::ConfigurationUnitResultInformation>>();\r\n                                resultInformation->ResultCode(change.ResultCode.value());\r\n                                resultInformation->Description(hstring{ AppInstaller::Utility::ConvertToUTF16(change.ResultDescription) });\r\n                                resultInformation->Details(hstring{ AppInstaller::Utility::ConvertToUTF16(change.ResultDetails) });\r\n                                resultInformation->ResultSource(change.ResultSource);\r\n                            }\r\n\r\n                            auto changeData = make_self<implementation::ConfigurationSetChangeData>();\r\n                            changeData->Initialize(state, *resultInformation, nullptr);\r\n\r\n                            m_status.SetChangeDetected(change.SetInstanceIdentifier, changeData, change.UnitInstanceIdentifier);\r\n                        }\r\n                    }\r\n                    else\r\n                    {\r\n                        // A set status change\r\n                        ConfigurationSetState state = AppInstaller::ToEnum<ConfigurationSetState>(change.State);\r\n                        ConfigurationChangeEventType changeType = ConfigurationChangeEventType::Unknown;\r\n\r\n                        SetStatusItem* setStatusItem = nullptr;\r\n                        auto itr = m_lastSetStatus.find(change.SetInstanceIdentifier);\r\n                        if (itr != m_lastSetStatus.end())\r\n                        {\r\n                            setStatusItem = &itr->second;\r\n                        }\r\n\r\n                        if (!setStatusItem)\r\n                        {\r\n                            changeType = ConfigurationChangeEventType::SetAdded;\r\n\r\n                            std::tie(itr, std::ignore) = m_lastSetStatus.emplace(change.SetInstanceIdentifier, SetStatusItem{ change });\r\n                            setStatusItem = &itr->second;\r\n                        }\r\n                        else\r\n                        {\r\n                            changeType = (change.InQueue ? ConfigurationChangeEventType::SetStateChanged : ConfigurationChangeEventType::SetRemoved);\r\n                        }\r\n\r\n                        if (m_status.HasChangeRegistrations())\r\n                        {\r\n                            if (!setStatusItem->Set)\r\n                            {\r\n                                setStatusItem->Set = m_status.Database().GetSet(change.SetInstanceIdentifier);\r\n                            }\r\n\r\n                            auto changeData = make_self<wil::details::module_count_wrapper<implementation::ConfigurationChangeData>>();\r\n                            changeData->Initialize(changeType, change.SetInstanceIdentifier, state);\r\n\r\n                            m_status.ChangeDetected(*setStatusItem->Set, *changeData);\r\n                        }\r\n\r\n                        auto setChangeData = make_self<implementation::ConfigurationSetChangeData>();\r\n                        setChangeData->Initialize(state);\r\n\r\n                        m_status.SetChangeDetected(change.SetInstanceIdentifier, setChangeData, std::nullopt);\r\n                    }\r\n\r\n                    m_changeIdentifier = change.ChangeIdentifier;\r\n                }\r\n\r\n                SetThreadpoolWait(m_threadPoolWait.get(), m_listenerEvent.get(), NULL);\r\n            }\r\n            CATCH_LOG_MSG(\"ChangeListener::WaitCallback exception\");\r\n\r\n            ConfigurationStatus& m_status;\r\n            int64_t m_changeIdentifier;\r\n            std::map<winrt::guid, SetStatusItem> m_lastSetStatus;\r\n            wil::unique_event m_listenerEvent;\r\n            std::string m_listenerEventName;\r\n\r\n            // Keep last to destroy first\r\n            wil::unique_threadpool_wait m_threadPoolWait;\r\n        };\r\n    }\r\n\r\n    ConfigurationStatus::ConfigurationStatus(private_construction) {}\r\n\r\n    ConfigurationStatus::~ConfigurationStatus() = default;\r\n\r\n    std::shared_ptr<ConfigurationStatus> ConfigurationStatus::Instance()\r\n    {\r\n        static std::shared_ptr<ConfigurationStatus> s_instance;\r\n\r\n        std::shared_ptr<ConfigurationStatus> result = std::atomic_load(&s_instance);\r\n        if (!result)\r\n        {\r\n            result = std::make_shared<ConfigurationStatus>(private_construction{});\r\n            std::shared_ptr<ConfigurationStatus> empty;\r\n\r\n            if (!std::atomic_compare_exchange_strong(&s_instance, &empty, result))\r\n            {\r\n                result = empty;\r\n            }\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    ConfigurationSetState ConfigurationStatus::GetSetState(const winrt::guid& instanceIdentifier)\r\n    {\r\n        m_database.EnsureOpened(false);\r\n        return m_database.GetSetState(instanceIdentifier);\r\n    }\r\n\r\n    clock::time_point ConfigurationStatus::GetSetFirstApply(const winrt::guid& instanceIdentifier)\r\n    {\r\n        m_database.EnsureOpened(false);\r\n        return clock::from_sys(m_database.GetSetFirstApply(instanceIdentifier));\r\n    }\r\n\r\n    clock::time_point ConfigurationStatus::GetSetApplyBegun(const winrt::guid& instanceIdentifier)\r\n    {\r\n        using system_clock = std::chrono::system_clock;\r\n\r\n        m_database.EnsureOpened(false);\r\n        system_clock::time_point result = m_database.GetSetApplyBegun(instanceIdentifier);\r\n        return (result == system_clock::time_point{} ? clock::time_point{} : clock::from_sys(result));\r\n    }\r\n\r\n    clock::time_point ConfigurationStatus::GetSetApplyEnded(const winrt::guid& instanceIdentifier)\r\n    {\r\n        using system_clock = std::chrono::system_clock;\r\n\r\n        m_database.EnsureOpened(false);\r\n        system_clock::time_point result = m_database.GetSetApplyEnded(instanceIdentifier);\r\n        return (result == system_clock::time_point{} ? clock::time_point{} : clock::from_sys(result));\r\n    }\r\n\r\n    ConfigurationUnitState ConfigurationStatus::GetUnitState(const winrt::guid& instanceIdentifier)\r\n    {\r\n        m_database.EnsureOpened(false);\r\n        return m_database.GetUnitState(instanceIdentifier);\r\n    }\r\n\r\n    IConfigurationUnitResultInformation ConfigurationStatus::GetUnitResultInformation(const winrt::guid& instanceIdentifier)\r\n    {\r\n        m_database.EnsureOpened(false);\r\n        return m_database.GetUnitResultInformation(instanceIdentifier);\r\n    }\r\n\r\n    void ConfigurationStatus::UpdateSetState(const guid& setInstanceIdentifier, ConfigurationSetState state)\r\n    {\r\n        m_database.EnsureOpened();\r\n        m_database.UpdateSetState(setInstanceIdentifier, state);\r\n        SignalChangeListeners();\r\n    }\r\n\r\n    void ConfigurationStatus::UpdateSetState(const guid& setInstanceIdentifier, bool inQueue)\r\n    {\r\n        m_database.EnsureOpened();\r\n        m_database.UpdateSetInQueue(setInstanceIdentifier, inQueue);\r\n        SignalChangeListeners();\r\n    }\r\n\r\n    void ConfigurationStatus::UpdateUnitState(const guid& setInstanceIdentifier, const com_ptr<implementation::ConfigurationSetChangeData>& changeData)\r\n    {\r\n        m_database.EnsureOpened();\r\n        m_database.UpdateUnitState(setInstanceIdentifier, changeData);\r\n        SignalChangeListeners();\r\n    }\r\n\r\n    ConfigurationStatus::SetChangeRegistration::SetChangeRegistration(const winrt::guid& instanceIdentifier, ConfigurationSet* configurationSet) :\r\n        m_status(Instance()), m_instanceIdentifier(instanceIdentifier), m_configurationSet(configurationSet) {}\r\n\r\n    ConfigurationStatus::SetChangeRegistration::~SetChangeRegistration()\r\n    {\r\n        m_status->RemoveSetChangeRegistration(m_instanceIdentifier, m_configurationSet);\r\n    }\r\n\r\n    std::shared_ptr<ConfigurationStatus::SetChangeRegistration> ConfigurationStatus::RegisterForSetChange(ConfigurationSet& set)\r\n    {\r\n        m_database.EnsureOpened();\r\n\r\n        winrt::guid instanceIdentifier = set.InstanceIdentifier();\r\n\r\n        {\r\n            std::lock_guard<std::mutex> lock{ m_changeRegistrationsMutex };\r\n            m_setChangeRegistrations.emplace(instanceIdentifier, &set);\r\n            EnableChangeListeningIfNeeded();\r\n        }\r\n\r\n        return std::make_shared<SetChangeRegistration>(instanceIdentifier, &set);\r\n    }\r\n\r\n    void ConfigurationStatus::RemoveSetChangeRegistration(const winrt::guid& instanceIdentifier, ConfigurationSet* configurationSet) noexcept\r\n    {\r\n        std::lock_guard<std::mutex> lock{ m_changeRegistrationsMutex };\r\n\r\n        auto [begin, end] = m_setChangeRegistrations.equal_range(instanceIdentifier);\r\n\r\n        for (; begin != end; ++begin)\r\n        {\r\n            if (begin->second == configurationSet)\r\n            {\r\n                m_setChangeRegistrations.erase(begin);\r\n                break;\r\n            }\r\n        }\r\n\r\n        DisableChangeListeningIfNeeded();\r\n    }\r\n\r\n    ConfigurationStatus::ChangeRegistration::ChangeRegistration(const winrt::guid& instanceIdentifier) :\r\n        m_status(Instance()), m_instanceIdentifier(instanceIdentifier) {}\r\n\r\n    ConfigurationStatus::ChangeRegistration::~ChangeRegistration()\r\n    {\r\n        m_status->RemoveChangeRegistration(m_instanceIdentifier);\r\n    }\r\n\r\n    std::shared_ptr<ConfigurationStatus::ChangeRegistration> ConfigurationStatus::RegisterForChange(ConfigurationProcessor& processor)\r\n    {\r\n        m_database.EnsureOpened();\r\n\r\n        GUID instanceIdentifier;\r\n        std::ignore = CoCreateGuid(&instanceIdentifier);\r\n\r\n        {\r\n            std::lock_guard<std::mutex> lock{ m_changeRegistrationsMutex };\r\n            m_changeRegistrations.emplace_back(instanceIdentifier, &processor);\r\n            EnableChangeListeningIfNeeded();\r\n        }\r\n\r\n        return std::make_shared<ChangeRegistration>(instanceIdentifier);\r\n    }\r\n\r\n    void ConfigurationStatus::RemoveChangeRegistration(const winrt::guid& instanceIdentifier) noexcept\r\n    {\r\n        std::lock_guard<std::mutex> lock{ m_changeRegistrationsMutex };\r\n\r\n        for (auto itr = m_changeRegistrations.begin(); itr != m_changeRegistrations.end(); ++itr)\r\n        {\r\n            if (itr->first == instanceIdentifier)\r\n            {\r\n                m_changeRegistrations.erase(itr);\r\n                DisableChangeListeningIfNeeded();\r\n                return;\r\n            }\r\n        }\r\n    }\r\n\r\n    void ConfigurationStatus::EnableChangeListeningIfNeeded()\r\n    {\r\n        if (!m_changeListener)\r\n        {\r\n            m_changeListener = std::make_unique<details::ChangeListener>(*this);\r\n        }\r\n    }\r\n\r\n    void ConfigurationStatus::DisableChangeListeningIfNeeded()\r\n    {\r\n        if (m_changeListener && m_setChangeRegistrations.empty() && m_changeRegistrations.empty())\r\n        {\r\n            m_changeListener.reset();\r\n        }\r\n    }\r\n\r\n    void ConfigurationStatus::SignalChangeListeners()\r\n    {\r\n        std::vector<ConfigurationDatabase::StatusChangeListener> changeListeners = m_database.GetChangeListeners();\r\n\r\n        for (const auto& listener : changeListeners)\r\n        {\r\n            std::wstring objectName = AppInstaller::Utility::ConvertToUTF16(listener.ObjectName);\r\n            wil::unique_event listenerEvent;\r\n            if (listenerEvent.try_open(objectName.c_str(), EVENT_MODIFY_STATE))\r\n            {\r\n                listenerEvent.SetEvent();\r\n            }\r\n            else\r\n            {\r\n                m_database.RemoveListener(listener.ObjectName);\r\n            }\r\n        }\r\n    }\r\n\r\n    ConfigurationDatabase& ConfigurationStatus::Database()\r\n    {\r\n        return m_database;\r\n    }\r\n\r\n    bool ConfigurationStatus::HasSetChangeRegistration(const guid& setInstanceIdentifier)\r\n    {\r\n        std::lock_guard<std::mutex> lock{ m_changeRegistrationsMutex };\r\n        auto [begin, end] = m_setChangeRegistrations.equal_range(setInstanceIdentifier);\r\n        return begin != end;\r\n    }\r\n\r\n    bool ConfigurationStatus::HasChangeRegistrations()\r\n    {\r\n        std::lock_guard<std::mutex> lock{ m_changeRegistrationsMutex };\r\n        return !m_changeRegistrations.empty();\r\n    }\r\n\r\n    void ConfigurationStatus::SetChangeDetected(const winrt::guid& setInstanceIdentifier, com_ptr<ConfigurationSetChangeData>& data, const std::optional<GUID>& unitInstanceIdentifier)\r\n    {\r\n        std::vector<ConfigurationSet*> setChangeRegistrations;\r\n\r\n        {\r\n            std::lock_guard<std::mutex> lock{ m_changeRegistrationsMutex };\r\n\r\n            auto [begin, end] = m_setChangeRegistrations.equal_range(setInstanceIdentifier);\r\n\r\n            for (; begin != end; ++begin)\r\n            {\r\n                setChangeRegistrations.emplace_back(begin->second);\r\n            }\r\n        }\r\n\r\n        for (ConfigurationSet* set : setChangeRegistrations)\r\n        {\r\n            set->ConfigurationSetChange(data, unitInstanceIdentifier);\r\n        }\r\n    }\r\n\r\n    void ConfigurationStatus::ChangeDetected(const Configuration::ConfigurationSet& set, const Configuration::ConfigurationChangeData& data)\r\n    {\r\n        std::vector<std::pair<winrt::guid, ConfigurationProcessor*>> changeRegistrations;\r\n\r\n        {\r\n            std::lock_guard<std::mutex> lock{ m_changeRegistrationsMutex };\r\n            changeRegistrations = m_changeRegistrations;\r\n        }\r\n\r\n        for (const auto& registration : changeRegistrations)\r\n        {\r\n            registration.second->ConfigurationChange(set, data);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationStatus.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Database/ConfigurationDatabase.h\"\r\n#include \"ConfigurationSetChangeData.h\"\r\n#include <winrt/Microsoft.Management.Configuration.h>\r\n#include <map>\r\n#include <memory>\r\n#include <mutex>\r\n#include <optional>\r\n#include <vector>\r\n\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    // Forward declarations\r\n    struct ConfigurationProcessor;\r\n    struct ConfigurationSet;\r\n    struct ConfigurationSetChangeData;\r\n\r\n    namespace details\r\n    {\r\n        struct ChangeListener;\r\n    }\r\n\r\n    // Provides access to overall configuration status information.\r\n    struct ConfigurationStatus\r\n    {\r\n    private:\r\n        struct private_construction {};\r\n\r\n    public:\r\n        friend details::ChangeListener;\r\n\r\n        ConfigurationStatus(private_construction);\r\n\r\n        ConfigurationStatus(const ConfigurationStatus&) = delete;\r\n        ConfigurationStatus& operator=(const ConfigurationStatus&) = delete;\r\n\r\n        ConfigurationStatus(ConfigurationStatus&&) = delete;\r\n        ConfigurationStatus& operator=(ConfigurationStatus&&) = delete;\r\n\r\n        ~ConfigurationStatus();\r\n\r\n        // Gets the singleton instance.\r\n        static std::shared_ptr<ConfigurationStatus> Instance();\r\n\r\n        // Get various set state information\r\n        ConfigurationSetState GetSetState(const guid& instanceIdentifier);\r\n        clock::time_point GetSetFirstApply(const guid& instanceIdentifier);\r\n        clock::time_point GetSetApplyBegun(const guid& instanceIdentifier);\r\n        clock::time_point GetSetApplyEnded(const guid& instanceIdentifier);\r\n        ConfigurationUnitState GetUnitState(const guid& instanceIdentifier);\r\n        IConfigurationUnitResultInformation GetUnitResultInformation(const guid& instanceIdentifier);\r\n\r\n        // Record state changes\r\n        void UpdateSetState(const guid& setInstanceIdentifier, ConfigurationSetState state);\r\n        void UpdateSetState(const guid& setInstanceIdentifier, bool inQueue);\r\n        void UpdateUnitState(const guid& setInstanceIdentifier, const com_ptr<implementation::ConfigurationSetChangeData>& changeData);\r\n\r\n        // Keeps data for a set change listener.\r\n        struct SetChangeRegistration\r\n        {\r\n            SetChangeRegistration(const guid& instanceIdentifier, ConfigurationSet* configurationSet);\r\n\r\n            SetChangeRegistration(const SetChangeRegistration&) = delete;\r\n            SetChangeRegistration& operator=(const SetChangeRegistration&) = delete;\r\n\r\n            SetChangeRegistration(SetChangeRegistration&&) = delete;\r\n            SetChangeRegistration& operator=(SetChangeRegistration&&) = delete;\r\n\r\n            ~SetChangeRegistration();\r\n\r\n        private:\r\n            std::shared_ptr<ConfigurationStatus> m_status;\r\n            guid m_instanceIdentifier;\r\n            ConfigurationSet* m_configurationSet;\r\n        };\r\n\r\n        std::shared_ptr<SetChangeRegistration> RegisterForSetChange(ConfigurationSet& set);\r\n        void RemoveSetChangeRegistration(const guid& instanceIdentifier, ConfigurationSet* configurationSet) noexcept;\r\n\r\n        // Keeps data for a change listener.\r\n        struct ChangeRegistration\r\n        {\r\n            ChangeRegistration(const guid& instanceIdentifier);\r\n\r\n            ChangeRegistration(const ChangeRegistration&) = delete;\r\n            ChangeRegistration& operator=(const ChangeRegistration&) = delete;\r\n\r\n            ChangeRegistration(ChangeRegistration&&) = delete;\r\n            ChangeRegistration& operator=(ChangeRegistration&&) = delete;\r\n\r\n            ~ChangeRegistration();\r\n\r\n        private:\r\n            std::shared_ptr<ConfigurationStatus> m_status;\r\n            guid m_instanceIdentifier;\r\n        };\r\n\r\n        std::shared_ptr<ChangeRegistration> RegisterForChange(ConfigurationProcessor& processor);\r\n        void RemoveChangeRegistration(const guid& instanceIdentifier) noexcept;\r\n\r\n    private:\r\n        void EnableChangeListeningIfNeeded();\r\n        void DisableChangeListeningIfNeeded();\r\n\r\n        void SignalChangeListeners();\r\n\r\n        ConfigurationDatabase& Database();\r\n\r\n        bool HasSetChangeRegistration(const guid& setInstanceIdentifier);\r\n        bool HasChangeRegistrations();\r\n\r\n        void SetChangeDetected(const guid& setInstanceIdentifier, com_ptr<ConfigurationSetChangeData>& data, const std::optional<GUID>& unitInstanceIdentifier);\r\n        void ChangeDetected(const Configuration::ConfigurationSet& set, const Configuration::ConfigurationChangeData& data);\r\n\r\n        ConfigurationDatabase m_database;\r\n\r\n        std::mutex m_changeRegistrationsMutex;\r\n        std::multimap<guid, ConfigurationSet*> m_setChangeRegistrations;\r\n        std::vector<std::pair<guid, ConfigurationProcessor*>> m_changeRegistrations;\r\n\r\n        // Keep this last to ensure it is destroyed first\r\n        std::unique_ptr<details::ChangeListener> m_changeListener;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationUnit.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ConfigurationUnit.h\"\r\n#include \"ConfigurationUnit.g.cpp\"\r\n#include \"ConfigurationSetParser.h\"\r\n#include \"ConfigurationStatus.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    namespace\r\n    {\r\n        using ValueSet = Windows::Foundation::Collections::ValueSet;\r\n\r\n        ValueSet Clone(const ValueSet& source)\r\n        {\r\n            ValueSet result;\r\n\r\n            for (const auto& entry : source)\r\n            {\r\n                ValueSet child = entry.Value().try_as<ValueSet>();\r\n\r\n                if (child)\r\n                {\r\n                    result.Insert(entry.Key(), Clone(child));\r\n                }\r\n                else\r\n                {\r\n                    result.Insert(entry.Key(), entry.Value());\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        Windows::Foundation::Collections::IVector<hstring> Clone(const Windows::Foundation::Collections::IVector<hstring>& value)\r\n        {\r\n            std::vector<hstring> temp{ value.Size() };\r\n            value.GetMany(0, temp);\r\n            return winrt::multi_threaded_vector<hstring>(std::move(temp));\r\n        }\r\n    }\r\n\r\n    ConfigurationUnit::ConfigurationUnit()\r\n    {\r\n        GUID instanceIdentifier;\r\n        THROW_IF_FAILED(CoCreateGuid(&instanceIdentifier));\r\n        m_instanceIdentifier = instanceIdentifier;\r\n    }\r\n\r\n    ConfigurationUnit::ConfigurationUnit(const guid& instanceIdentifier) :\r\n        m_instanceIdentifier(instanceIdentifier)\r\n    {\r\n    }\r\n\r\n    hstring ConfigurationUnit::Type()\r\n    {\r\n        return m_type;\r\n    }\r\n\r\n    void ConfigurationUnit::Type(const hstring& value)\r\n    {\r\n        m_type = value;\r\n    }\r\n\r\n    guid ConfigurationUnit::InstanceIdentifier()\r\n    {\r\n        return m_instanceIdentifier;\r\n    }\r\n\r\n    hstring ConfigurationUnit::Identifier()\r\n    {\r\n        return m_identifier;\r\n    }\r\n\r\n    void ConfigurationUnit::Identifier(const hstring& value)\r\n    {\r\n        m_identifier = value;\r\n    }\r\n\r\n    ConfigurationUnitIntent ConfigurationUnit::Intent()\r\n    {\r\n        return m_intent;\r\n    }\r\n\r\n    void ConfigurationUnit::Intent(ConfigurationUnitIntent value)\r\n    {\r\n        m_intent = value;\r\n    }\r\n\r\n    Windows::Foundation::Collections::IVector<hstring> ConfigurationUnit::Dependencies()\r\n    {\r\n        return m_dependencies;\r\n    }\r\n\r\n    void ConfigurationUnit::Dependencies(const Windows::Foundation::Collections::IVector<hstring>& value)\r\n    {\r\n        THROW_HR_IF(E_POINTER, !value);\r\n        m_dependencies = value;\r\n    }\r\n\r\n    void ConfigurationUnit::Dependencies(std::vector<hstring>&& value)\r\n    {\r\n        m_dependencies = winrt::multi_threaded_vector<hstring>(std::move(value));\r\n    }\r\n\r\n    Windows::Foundation::Collections::ValueSet ConfigurationUnit::Metadata()\r\n    {\r\n        return m_metadata;\r\n    }\r\n\r\n    void ConfigurationUnit::Metadata(const Windows::Foundation::Collections::ValueSet& value)\r\n    {\r\n        THROW_HR_IF(E_POINTER, !value);\r\n        m_metadata = value;\r\n    }\r\n\r\n    Windows::Foundation::Collections::ValueSet ConfigurationUnit::Settings()\r\n    {\r\n        return m_settings;\r\n    }\r\n\r\n    void ConfigurationUnit::Settings(const Windows::Foundation::Collections::ValueSet& value)\r\n    {\r\n        THROW_HR_IF(E_POINTER, !value);\r\n        m_settings = value;\r\n    }\r\n\r\n    IConfigurationUnitProcessorDetails ConfigurationUnit::Details()\r\n    {\r\n        return m_details;\r\n    }\r\n\r\n    void ConfigurationUnit::Details(IConfigurationUnitProcessorDetails details)\r\n    {\r\n        m_details = std::move(details);\r\n    }\r\n\r\n    ConfigurationUnitState ConfigurationUnit::State()\r\n    {\r\n        auto status = ConfigurationStatus::Instance();\r\n        return status->GetUnitState(m_instanceIdentifier);\r\n    }\r\n\r\n    IConfigurationUnitResultInformation ConfigurationUnit::ResultInformation()\r\n    {\r\n        auto status = ConfigurationStatus::Instance();\r\n        return status->GetUnitResultInformation(m_instanceIdentifier);\r\n    }\r\n\r\n    bool ConfigurationUnit::IsActive()\r\n    {\r\n        return m_isActive;\r\n    }\r\n\r\n    void ConfigurationUnit::IsActive(bool value)\r\n    {\r\n        m_isActive = value;\r\n    }\r\n\r\n    Configuration::ConfigurationUnit ConfigurationUnit::Copy()\r\n    {\r\n        auto result = make_self<ConfigurationUnit>();\r\n\r\n        result->m_type = m_type;\r\n        result->m_intent = m_intent;\r\n        result->m_dependencies = Clone(m_dependencies);\r\n        result->m_metadata = Clone(m_metadata);\r\n        result->m_settings = Clone(m_settings);\r\n        result->m_details = m_details;\r\n        result->m_environment = make_self<implementation::ConfigurationEnvironment>(*m_environment);\r\n\r\n        return *result;\r\n    }\r\n\r\n    bool ConfigurationUnit::IsGroup()\r\n    {\r\n        return m_isGroup;\r\n    }\r\n\r\n    void ConfigurationUnit::IsGroup(bool value)\r\n    {\r\n        m_isGroup = value;\r\n\r\n        if (value)\r\n        {\r\n            if (!m_units)\r\n            {\r\n                m_units = winrt::multi_threaded_vector<Configuration::ConfigurationUnit>();\r\n            }\r\n        }\r\n    }\r\n\r\n    Windows::Foundation::Collections::IVector<Configuration::ConfigurationUnit> ConfigurationUnit::Units()\r\n    {\r\n        return m_units;\r\n    }\r\n\r\n    void ConfigurationUnit::Units(const Windows::Foundation::Collections::IVector<Configuration::ConfigurationUnit>& value)\r\n    {\r\n        if (m_isGroup)\r\n        {\r\n            THROW_HR_IF(E_POINTER, !value);\r\n        }\r\n        else if (value)\r\n        {\r\n            m_isGroup = true;\r\n        }\r\n\r\n        m_units = value;\r\n    }\r\n\r\n    void ConfigurationUnit::Units(std::vector<Configuration::ConfigurationUnit>&& value)\r\n    {\r\n        m_units = winrt::multi_threaded_vector<Configuration::ConfigurationUnit>(std::move(value));\r\n    }\r\n\r\n    Configuration::ConfigurationEnvironment ConfigurationUnit::Environment()\r\n    {\r\n        return *m_environment;\r\n    }\r\n\r\n    implementation::ConfigurationEnvironment& ConfigurationUnit::EnvironmentInternal()\r\n    {\r\n        return *m_environment;\r\n    }\r\n\r\n    HRESULT STDMETHODCALLTYPE ConfigurationUnit::SetLifetimeWatcher(IUnknown* watcher)\r\n    {\r\n        return AppInstaller::WinRT::LifetimeWatcherBase::SetLifetimeWatcher(watcher);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationUnit.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ConfigurationUnit.g.h\"\r\n#include \"ConfigurationEnvironment.h\"\r\n#include <winget/ILifetimeWatcher.h>\r\n#include <winget/ModuleCountBase.h>\r\n#include <winrt/Windows.Foundation.Collections.h>\r\n#include <vector>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    struct ConfigurationUnit : ConfigurationUnitT<ConfigurationUnit, winrt::cloaked<AppInstaller::WinRT::ILifetimeWatcher>>, AppInstaller::WinRT::LifetimeWatcherBase, AppInstaller::WinRT::ModuleCountBase\r\n    {\r\n        ConfigurationUnit();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        ConfigurationUnit(const guid& instanceIdentifier);\r\n\r\n        implementation::ConfigurationEnvironment& EnvironmentInternal();\r\n#endif\r\n\r\n        hstring Type();\r\n        void Type(const hstring& value);\r\n\r\n        guid InstanceIdentifier();\r\n\r\n        hstring Identifier();\r\n        void Identifier(const hstring& value);\r\n\r\n        ConfigurationUnitIntent Intent();\r\n        void Intent(ConfigurationUnitIntent value);\r\n\r\n        Windows::Foundation::Collections::IVector<hstring> Dependencies();\r\n        void Dependencies(const Windows::Foundation::Collections::IVector<hstring>& value);\r\n\r\n        Windows::Foundation::Collections::ValueSet Metadata();\r\n        void Metadata(const Windows::Foundation::Collections::ValueSet& value);\r\n\r\n        Windows::Foundation::Collections::ValueSet Settings();\r\n        void Settings(const Windows::Foundation::Collections::ValueSet& value);\r\n\r\n        IConfigurationUnitProcessorDetails Details();\r\n\r\n        ConfigurationUnitState State();\r\n\r\n        IConfigurationUnitResultInformation ResultInformation();\r\n\r\n        bool IsActive();\r\n        void IsActive(bool value);\r\n\r\n        Configuration::ConfigurationUnit Copy();\r\n\r\n        bool IsGroup();\r\n        void IsGroup(bool value);\r\n\r\n        Windows::Foundation::Collections::IVector<Configuration::ConfigurationUnit> Units();\r\n        void Units(const Windows::Foundation::Collections::IVector<Configuration::ConfigurationUnit>& value);\r\n\r\n        Configuration::ConfigurationEnvironment Environment();\r\n\r\n        HRESULT STDMETHODCALLTYPE SetLifetimeWatcher(IUnknown* watcher);\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        void Dependencies(std::vector<hstring>&& value);\r\n        void Details(IConfigurationUnitProcessorDetails details);\r\n        void Units(std::vector<Configuration::ConfigurationUnit>&& value);\r\n\r\n    private:\r\n        hstring m_type;\r\n        guid m_instanceIdentifier;\r\n        hstring m_identifier;\r\n        ConfigurationUnitIntent m_intent = ConfigurationUnitIntent::Apply;\r\n        Windows::Foundation::Collections::IVector<hstring> m_dependencies{ winrt::multi_threaded_vector<hstring>() };\r\n        Windows::Foundation::Collections::ValueSet m_metadata;\r\n        Windows::Foundation::Collections::ValueSet m_settings;\r\n        IConfigurationUnitProcessorDetails m_details{ nullptr };\r\n        bool m_isActive = true;\r\n        bool m_isGroup = false;\r\n        Windows::Foundation::Collections::IVector<Configuration::ConfigurationUnit> m_units = nullptr;\r\n        com_ptr<implementation::ConfigurationEnvironment> m_environment{ make_self<implementation::ConfigurationEnvironment>() };\r\n#endif\r\n    };\r\n}\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\nnamespace winrt::Microsoft::Management::Configuration::factory_implementation\r\n{\r\n    struct ConfigurationUnit : ConfigurationUnitT<ConfigurationUnit, implementation::ConfigurationUnit>\r\n    {\r\n    };\r\n}\r\n#endif\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"ConfigurationUnitResultInformation.h\"\n#include \"AppInstallerErrors.h\"\r\n#include \"AppInstallerStrings.h\"\n\nnamespace winrt::Microsoft::Management::Configuration::implementation\n{\n    namespace\n    {\n        ConfigurationUnitResultSource FromHRESULT(hresult resultCode)\n        {\n            switch (resultCode)\n            {\n                case WINGET_CONFIG_ERROR_UNIT_NOT_INSTALLED:\n                case WINGET_CONFIG_ERROR_UNIT_NOT_FOUND_REPOSITORY:\n                case WINGET_CONFIG_ERROR_UNIT_MULTIPLE_MATCHES:\n                case WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE:\n                case WINGET_CONFIG_ERROR_UNIT_SETTING_CONFIG_ROOT:\n                case WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE_ADMIN:\n                    return ConfigurationUnitResultSource::ConfigurationSet;\n                case WINGET_CONFIG_ERROR_UNIT_MODULE_CONFLICT:\n                    return ConfigurationUnitResultSource::SystemState;\n            }\n\n            return ConfigurationUnitResultSource::Internal;\n        }\r\n\r\n        hstring SanitizeString(std::wstring_view value)\r\n        {\r\n            using namespace AppInstaller::Utility;\n            return hstring{ ConvertToUTF16(ConvertControlCodesToPictures(ConvertToUTF8(value))) };\n        }\n    }\n\n    void ConfigurationUnitResultInformation::Initialize(const Configuration::IConfigurationUnitResultInformation& other)\n    {\n        if (other)\n        {\n            m_resultCode = other.ResultCode();\n            m_description = SanitizeString(other.Description());\n            m_details = SanitizeString(other.Details());\n            m_resultSource = other.ResultSource();\n        }\n    }\n\n    void ConfigurationUnitResultInformation::Initialize(hresult resultCode, std::wstring_view description)\n    {\n        m_resultCode = resultCode;\n        m_description = SanitizeString(description);\n        m_resultSource = FromHRESULT(resultCode);\n    }\n\n    void ConfigurationUnitResultInformation::Initialize(hresult resultCode, hstring description)\n    {\n        m_resultCode = resultCode;\n        m_description = SanitizeString(description);\n        m_resultSource = FromHRESULT(resultCode);\n    }\n\n    void ConfigurationUnitResultInformation::Initialize(hresult resultCode, ConfigurationUnitResultSource resultSource)\n    {\n        m_resultCode = resultCode;\n        m_resultSource = resultSource;\n    }\r\n\r\n    void ConfigurationUnitResultInformation::Initialize(hresult resultCode, std::wstring_view description, std::wstring_view details, ConfigurationUnitResultSource resultSource)\r\n    {\n        m_resultCode = resultCode;\n        m_description = SanitizeString(description);\n        m_details = SanitizeString(details);\n        m_resultSource = resultSource;\n    }\n\n    hresult ConfigurationUnitResultInformation::ResultCode() const\n    {\n        return m_resultCode;\n    }\n\n    void ConfigurationUnitResultInformation::ResultCode(hresult resultCode)\n    {\n        m_resultCode = resultCode;\n    }\n\n    hstring ConfigurationUnitResultInformation::Description()\n    {\n        return m_description;\n    }\n\n    void ConfigurationUnitResultInformation::Description(hstring value)\n    {\n        m_description = value;\n    }\n\n    hstring ConfigurationUnitResultInformation::Details()\n    {\n        return m_details;\n    }\n\n    void ConfigurationUnitResultInformation::Details(hstring value)\n    {\n        m_details = value;\n    }\n\n    ConfigurationUnitResultSource ConfigurationUnitResultInformation::ResultSource() const\n    {\n        return m_resultSource;\n    }\n\n    void ConfigurationUnitResultInformation::ResultSource(ConfigurationUnitResultSource value)\n    {\n        m_resultSource = value;\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ConfigurationUnitResultInformation.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"winrt/Microsoft.Management.Configuration.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    struct ConfigurationUnitResultInformation : winrt::implements<ConfigurationUnitResultInformation, IConfigurationUnitResultInformation>\r\n    {\r\n        ConfigurationUnitResultInformation() = default;\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        void Initialize(const Configuration::IConfigurationUnitResultInformation& other);\r\n        void Initialize(hresult resultCode, std::wstring_view description);\r\n        void Initialize(hresult resultCode, hstring description);\r\n        void Initialize(hresult resultCode, ConfigurationUnitResultSource resultSource);\r\n        void Initialize(hresult resultCode, std::wstring_view description, std::wstring_view details, ConfigurationUnitResultSource resultSource);\r\n#endif\r\n\r\n        hresult ResultCode() const;\r\n        void ResultCode(hresult resultCode);\r\n\r\n        hstring Description();\r\n        void Description(hstring value);\r\n\r\n        hstring Details();\r\n        void Details(hstring value);\r\n\r\n        ConfigurationUnitResultSource ResultSource() const;\r\n        void ResultSource(ConfigurationUnitResultSource value);\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        hresult m_resultCode;\r\n        hstring m_description;\r\n        hstring m_details;\r\n        ConfigurationUnitResultSource m_resultSource = ConfigurationUnitResultSource::None;\r\n#endif\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Database/ConfigurationDatabase.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Database/ConfigurationDatabase.h\"\r\n#include \"Database/Schema/IConfigurationDatabase.h\"\r\n#include \"ConfigurationUnitResultInformation.h\"\r\n#include <AppInstallerStrings.h>\r\n#include <winget/Filesystem.h>\r\n#include \"Filesystem.h\"\r\n\r\nusing namespace AppInstaller::SQLite;\r\nusing namespace AppInstaller::Utility;\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    namespace\r\n    {\r\n        // Use an alternate location for the dev build history.\r\n#ifdef AICLI_DISABLE_TEST_HOOKS\r\n        constexpr std::string_view s_Database_DirectoryName = \"History\"sv;\r\n#else\r\n        constexpr std::string_view s_Database_DirectoryName = \"DevHistory\"sv;\r\n#endif\r\n\r\n        constexpr std::string_view s_Database_FileName = \"config.db\"sv;\r\n\r\n        #define s_Database_MutexName L\"WindowsPackageManager_Configuration_DatabaseMutex\"\r\n\r\n        std::vector<ConfigurationDatabase::StatusItem> ConvertStatusItems(const std::vector<IConfigurationDatabase::StatusItemTuple>& input)\r\n        {\r\n            std::vector<ConfigurationDatabase::StatusItem> result;\r\n\r\n            for (const auto& item : input)\r\n            {\r\n                ConfigurationDatabase::StatusItem statusItem{};\r\n                std::tie(\r\n                    statusItem.ChangeIdentifier,\r\n                    statusItem.ChangeTime,\r\n                    statusItem.SetInstanceIdentifier,\r\n                    statusItem.InQueue,\r\n                    statusItem.UnitInstanceIdentifier,\r\n                    statusItem.State,\r\n                    statusItem.ResultCode,\r\n                    statusItem.ResultDescription,\r\n                    statusItem.ResultDetails,\r\n                    statusItem.ResultSource) = item;\r\n                result.emplace_back(std::move(statusItem));\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n\r\n    ConfigurationDatabase::ConfigurationDatabase() = default;\r\n\r\n    ConfigurationDatabase::ConfigurationDatabase(ConfigurationDatabase&&) = default;\r\n    ConfigurationDatabase& ConfigurationDatabase::operator=(ConfigurationDatabase&&) = default;\r\n\r\n    ConfigurationDatabase::~ConfigurationDatabase() = default;\r\n\r\n    void ConfigurationDatabase::EnsureOpened(bool createIfNeeded)\r\n    {\r\n#ifdef AICLI_DISABLE_TEST_HOOKS\r\n        // While under development, treat errors escaping this function as a test hook.\r\n        try\r\n        {\r\n#endif\r\n        if (!std::atomic_load(&m_database))\r\n        {\r\n            std::filesystem::path databaseDirectory = AppInstaller::Filesystem::GetPathTo(PathName::LocalState) / s_Database_DirectoryName;\r\n            std::filesystem::path databaseFile = databaseDirectory / s_Database_FileName;\r\n\r\n            {\r\n                wil::unique_mutex databaseMutex;\r\n                databaseMutex.create(s_Database_MutexName);\r\n                auto databaseLock = databaseMutex.acquire();\r\n\r\n                if (!std::filesystem::is_regular_file(databaseFile) && createIfNeeded)\r\n                {\r\n                    if (std::filesystem::exists(databaseFile))\r\n                    {\r\n                        std::filesystem::remove_all(databaseDirectory);\r\n                    }\r\n\r\n                    std::filesystem::create_directories(databaseDirectory);\r\n\r\n                    auto connection = std::make_shared<SQLiteDynamicStorage>(databaseFile, IConfigurationDatabase::GetLatestVersion());\r\n                    auto database = std::shared_ptr{ IConfigurationDatabase::CreateFor(connection) };\r\n                    database->InitializeDatabase();\r\n\r\n                    std::atomic_store(&m_connection, connection);\r\n                    std::atomic_store(&m_database, database);\r\n                }\r\n            }\r\n\r\n            if (!std::atomic_load(&m_connection))\r\n            {\r\n                std::shared_ptr<SQLiteDynamicStorage> empty;\r\n                auto connection = std::make_shared<SQLiteDynamicStorage>(databaseFile, SQLiteStorageBase::OpenDisposition::ReadWrite);\r\n                std::atomic_compare_exchange_strong(&m_connection, &empty, connection);\r\n            }\r\n\r\n            if (!std::atomic_load(&m_database))\r\n            {\r\n                std::shared_ptr<IConfigurationDatabase> empty;\r\n                auto database = std::shared_ptr{ IConfigurationDatabase::CreateFor(std::atomic_load(&m_connection), true) };\r\n                std::atomic_compare_exchange_strong(&m_database, &empty, database);\r\n            }\r\n        }\r\n#ifdef AICLI_DISABLE_TEST_HOOKS\r\n        }\r\n        CATCH_LOG();\r\n#endif\r\n    }\r\n\r\n    template <typename OperationT>\r\n    auto ConfigurationDatabase::ExecuteReadOperation(std::string_view operationName, OperationT&& operation, bool requireDatabase) const\r\n    {\r\n        using ResultT = decltype(operation(std::declval<std::shared_ptr<IConfigurationDatabase>&>()));\r\n        ResultT result{};\r\n\r\n#ifdef AICLI_DISABLE_TEST_HOOKS\r\n        // While under development, treat errors escaping this function as a test hook.\r\n        try\r\n        {\r\n#endif\r\n            auto database = std::atomic_load(&m_database);\r\n\r\n            if (database)\r\n            {\r\n                auto transaction = BeginTransaction(operationName, false, database);\r\n                result = operation(database);\r\n            }\r\n            else if (requireDatabase)\r\n            {\r\n                THROW_HR(E_NOT_VALID_STATE);\r\n            }\r\n#ifdef AICLI_DISABLE_TEST_HOOKS\r\n        }\r\n        CATCH_LOG();\r\n#endif\r\n\r\n        return result;\r\n    }\r\n\r\n    template <typename OperationT>\r\n    void ConfigurationDatabase::ExecuteWriteOperation(std::string_view operationName, OperationT&& operation, bool silentlyIgnoreNoDatabase)\r\n    {\r\n#ifdef AICLI_DISABLE_TEST_HOOKS\r\n        // While under development, treat errors escaping this function as a test hook.\r\n        try\r\n        {\r\n#endif\r\n            auto database = std::atomic_load(&m_database);\r\n\r\n            if (!database)\r\n            {\r\n                THROW_HR_IF(E_NOT_VALID_STATE, !silentlyIgnoreNoDatabase);\r\n                return;\r\n            }\r\n\r\n            auto transaction = BeginTransaction(operationName, true, database);\r\n            operation(database);\r\n            std::atomic_load(&m_connection)->SetLastWriteTime();\r\n            transaction->Commit();\r\n#ifdef AICLI_DISABLE_TEST_HOOKS\r\n        }\r\n        CATCH_LOG();\r\n#endif\r\n    }\r\n\r\n    std::vector<ConfigurationDatabase::ConfigurationSetPtr> ConfigurationDatabase::GetSetHistory() const\r\n    {\r\n        return ExecuteReadOperation(\"GetSetHistory\",\r\n            [&](std::shared_ptr<IConfigurationDatabase>& database)\r\n            {\r\n                return database->GetSets();\r\n            });\r\n    }\r\n\r\n    ConfigurationDatabase::ConfigurationSetPtr ConfigurationDatabase::GetSet(const GUID& instanceIdentifier) const\r\n    {\r\n        return ExecuteReadOperation(\"GetSet\",\r\n            [&](std::shared_ptr<IConfigurationDatabase>& database)\r\n            {\r\n                return database->GetSet(instanceIdentifier);\r\n            });\r\n    }\r\n\r\n    void ConfigurationDatabase::WriteSetHistory(const Configuration::ConfigurationSet& configurationSet, bool preferNewHistory)\r\n    {\r\n        THROW_HR_IF_NULL(E_POINTER, configurationSet);\r\n\r\n        ExecuteWriteOperation(\"WriteSetHistory\",\r\n            [&](std::shared_ptr<IConfigurationDatabase>& database)\r\n            {\r\n                std::optional<rowid_t> setRowId = database->GetSetRowId(configurationSet.InstanceIdentifier());\r\n\r\n                if (!setRowId && !preferNewHistory)\r\n                {\r\n                    // TODO: Use conflict detection code to check for a matching set\r\n                }\r\n\r\n                if (setRowId)\r\n                {\r\n                    database->UpdateSet(setRowId.value(), configurationSet);\r\n                }\r\n                else\r\n                {\r\n                    database->AddSet(configurationSet);\r\n                }\r\n            });\r\n    }\r\n\r\n    void ConfigurationDatabase::RemoveSetHistory(const Configuration::ConfigurationSet& configurationSet)\r\n    {\r\n        THROW_HR_IF_NULL(E_POINTER, configurationSet);\r\n\r\n        ExecuteWriteOperation(\"RemoveSetHistory\",\r\n            [&](std::shared_ptr<IConfigurationDatabase>& database)\r\n            {\r\n                std::optional<rowid_t> setRowId = database->GetSetRowId(configurationSet.InstanceIdentifier());\r\n\r\n                if (!setRowId)\r\n                {\r\n                    // TODO: Use conflict detection code to check for a matching set\r\n                }\r\n\r\n                if (setRowId)\r\n                {\r\n                    database->RemoveSet(setRowId.value());\r\n                    std::atomic_load(&m_connection)->SetLastWriteTime();\r\n                }\r\n            }, true);\r\n    }\r\n\r\n\r\n    void ConfigurationDatabase::AddQueueItem(const Configuration::ConfigurationSet& configurationSet, const std::string& objectName)\r\n    {\r\n        THROW_HR_IF_NULL(E_POINTER, configurationSet);\r\n\r\n        ExecuteWriteOperation(\"AddQueueItem\",\r\n            [&](std::shared_ptr<IConfigurationDatabase>& database)\r\n            {\r\n                database->AddQueueItem(configurationSet.InstanceIdentifier(), objectName);\r\n            });\r\n    }\r\n\r\n    void ConfigurationDatabase::SetActiveQueueItem(const std::string& objectName)\r\n    {\r\n        ExecuteWriteOperation(\"SetActiveQueueItem\",\r\n            [&](std::shared_ptr<IConfigurationDatabase>& database)\r\n            {\r\n                database->SetActiveQueueItem(objectName);\r\n            });\r\n    }\r\n\r\n    std::vector<ConfigurationDatabase::QueueItem> ConfigurationDatabase::GetQueueItems() const\r\n    {\r\n        return ExecuteReadOperation(\"GetQueueItems\",\r\n            [&](std::shared_ptr<IConfigurationDatabase>& database)\r\n            {\r\n                std::vector<QueueItem> result;\r\n                auto queueItems = database->GetQueueItems();\r\n                result.reserve(queueItems.size());\r\n\r\n                for (const auto& item : queueItems)\r\n                {\r\n                    QueueItem resultItem;\r\n                    std::tie(resultItem.SetInstanceIdentifier, resultItem.ObjectName, resultItem.QueuedAt, resultItem.ProcessId, resultItem.Active) = item;\r\n                    result.emplace_back(std::move(resultItem));\r\n                }\r\n\r\n                return result;\r\n            }, true);\r\n    }\r\n\r\n    void ConfigurationDatabase::RemoveQueueItem(const std::string& objectName)\r\n    {\r\n        ExecuteWriteOperation(\"RemoveQueueItem\",\r\n            [&](std::shared_ptr<IConfigurationDatabase>& database)\r\n            {\r\n                database->RemoveQueueItem(objectName);\r\n            });\r\n    }\r\n\r\n    std::vector<ConfigurationDatabase::StatusItem> ConfigurationDatabase::GetStatusSince(int64_t changeIdentifier) const\r\n    {\r\n        return ExecuteReadOperation(\"GetStatusSince\",\r\n            [&](std::shared_ptr<IConfigurationDatabase>& database)\r\n            {\r\n                return ConvertStatusItems(database->GetStatusSince(changeIdentifier));\r\n            });\r\n    }\r\n\r\n    ConfigurationDatabase::StatusBaseline ConfigurationDatabase::GetStatusBaseline() const\r\n    {\r\n        return ExecuteReadOperation(\"GetStatusBaseline\",\r\n            [&](std::shared_ptr<IConfigurationDatabase>& database)\r\n            {\r\n                auto [changeIdentifier, setStatus] = database->GetStatusBaseline();\r\n\r\n                StatusBaseline result{};\r\n                result.ChangeIdentifier = changeIdentifier;\r\n                result.SetStatus = ConvertStatusItems(setStatus);\r\n                return result;\r\n            });\r\n    }\r\n\r\n    void ConfigurationDatabase::AddListener(const std::string& objectName)\r\n    {\r\n        ExecuteWriteOperation(\"AddListener\",\r\n            [&](std::shared_ptr<IConfigurationDatabase>& database)\r\n            {\r\n                database->AddListener(objectName);\r\n            });\r\n    }\r\n\r\n    void ConfigurationDatabase::RemoveListener(const std::string& objectName)\r\n    {\r\n        ExecuteWriteOperation(\"RemoveListener\",\r\n            [&](std::shared_ptr<IConfigurationDatabase>& database)\r\n            {\r\n                database->RemoveListener(objectName);\r\n            });\r\n    }\r\n\r\n    std::vector<ConfigurationDatabase::StatusChangeListener> ConfigurationDatabase::GetChangeListeners() const\r\n    {\r\n        return ExecuteReadOperation(\"GetChangeListeners\",\r\n            [&](std::shared_ptr<IConfigurationDatabase>& database)\r\n            {\r\n                std::vector<StatusChangeListener> result;\r\n\r\n                for (const auto& item : database->GetChangeListeners())\r\n                {\r\n                    StatusChangeListener listener{};\r\n                    std::tie(listener.ObjectName, listener.Started, listener.ProcessId) = item;\r\n                    result.emplace_back(std::move(listener));\r\n                }\r\n\r\n                return result;\r\n            });\r\n    }\r\n\r\n    void ConfigurationDatabase::UpdateSetState(const guid& setInstanceIdentifier, ConfigurationSetState state)\r\n    {\r\n        ExecuteWriteOperation(\"UpdateSetState\",\r\n            [&](std::shared_ptr<IConfigurationDatabase>& database)\r\n            {\r\n                database->UpdateSetState(setInstanceIdentifier, state);\r\n            });\r\n    }\r\n\r\n    void ConfigurationDatabase::UpdateSetInQueue(const guid& setInstanceIdentifier, bool inQueue)\r\n    {\r\n        ExecuteWriteOperation(\"UpdateSetInQueue\",\r\n            [&](std::shared_ptr<IConfigurationDatabase>& database)\r\n            {\r\n                database->UpdateSetInQueue(setInstanceIdentifier, inQueue);\r\n            });\r\n    }\r\n\r\n    void ConfigurationDatabase::UpdateUnitState(const guid& setInstanceIdentifier, const com_ptr<implementation::ConfigurationSetChangeData>& changeData)\r\n    {\r\n        ExecuteWriteOperation(\"UpdateUnitState\",\r\n            [&](std::shared_ptr<IConfigurationDatabase>& database)\r\n            {\r\n                database->UpdateUnitState(setInstanceIdentifier, changeData);\r\n            });\r\n    }\r\n\r\n    ConfigurationSetState ConfigurationDatabase::GetSetState(const guid& instanceIdentifier)\r\n    {\r\n        return ExecuteReadOperation(\"GetSetState\",\r\n            [&](std::shared_ptr<IConfigurationDatabase>& database)\r\n            {\r\n                return database->GetSetState(instanceIdentifier);\r\n            });\r\n    }\r\n\r\n    std::chrono::system_clock::time_point ConfigurationDatabase::GetSetFirstApply(const guid& instanceIdentifier)\r\n    {\r\n        return ExecuteReadOperation(\"GetSetFirstApply\",\r\n            [&](std::shared_ptr<IConfigurationDatabase>& database)\r\n            {\r\n                return database->GetSetFirstApply(instanceIdentifier);\r\n            });\r\n    }\r\n\r\n    std::chrono::system_clock::time_point ConfigurationDatabase::GetSetApplyBegun(const guid& instanceIdentifier)\r\n    {\r\n        return ExecuteReadOperation(\"GetSetApplyBegun\",\r\n            [&](std::shared_ptr<IConfigurationDatabase>& database)\r\n            {\r\n                return database->GetSetApplyBegun(instanceIdentifier);\r\n            });\r\n    }\r\n\r\n    std::chrono::system_clock::time_point ConfigurationDatabase::GetSetApplyEnded(const guid& instanceIdentifier)\r\n    {\r\n        return ExecuteReadOperation(\"GetSetApplyEnded\",\r\n            [&](std::shared_ptr<IConfigurationDatabase>& database)\r\n            {\r\n                return database->GetSetApplyEnded(instanceIdentifier);\r\n            });\r\n    }\r\n\r\n    ConfigurationUnitState ConfigurationDatabase::GetUnitState(const guid& instanceIdentifier)\r\n    {\r\n        return ExecuteReadOperation(\"GetUnitState\",\r\n            [&](std::shared_ptr<IConfigurationDatabase>& database)\r\n            {\r\n                return database->GetUnitState(instanceIdentifier);\r\n            });\r\n    }\r\n\r\n    IConfigurationUnitResultInformation ConfigurationDatabase::GetUnitResultInformation(const guid& instanceIdentifier)\r\n    {\r\n        return ExecuteReadOperation(\"GetUnitResultInformation\",\r\n            [&](std::shared_ptr<IConfigurationDatabase>& database)\r\n            {\r\n                com_ptr<wil::details::module_count_wrapper<implementation::ConfigurationUnitResultInformation>> result;\r\n\r\n                auto resultInformation = database->GetUnitResultInformation(instanceIdentifier);\r\n\r\n                if (resultInformation)\r\n                {\r\n                    result = make_self<wil::details::module_count_wrapper<implementation::ConfigurationUnitResultInformation>>();\r\n                    result->Initialize(\r\n                        std::get<0>(resultInformation.value()),\r\n                        ConvertToUTF16(std::get<1>(resultInformation.value())),\r\n                        ConvertToUTF16(std::get<2>(resultInformation.value())),\r\n                        std::get<3>(resultInformation.value()));\r\n                }\r\n\r\n                IConfigurationUnitResultInformation actualResult;\r\n                if (result)\r\n                {\r\n                    actualResult = *result;\r\n                }\r\n\r\n                return actualResult;\r\n            });\r\n    }\r\n\r\n    ConfigurationDatabase::TransactionLock ConfigurationDatabase::BeginTransaction(std::string_view name, bool forWrite, std::shared_ptr<IConfigurationDatabase>& database) const\r\n    {\r\n        auto connection = std::atomic_load(&m_connection);\r\n        THROW_HR_IF_NULL(E_NOT_VALID_STATE, connection);\r\n\r\n        TransactionLock result = connection->TryBeginTransaction(name, forWrite);\r\n\r\n        while (!result)\r\n        {\r\n            {\r\n                auto connectionLock = connection->LockConnection();\r\n                auto newDatabase = std::shared_ptr{ IConfigurationDatabase::CreateFor(connection) };\r\n                if (std::atomic_compare_exchange_strong(&m_database, &database, newDatabase))\r\n                {\r\n                    database = newDatabase;\r\n                }\r\n            }\r\n\r\n            result = connection->TryBeginTransaction(name, forWrite);\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Database/ConfigurationDatabase.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"ConfigurationSetChangeData.h\"\r\n#include <winget/SQLiteWrapper.h>\r\n#include <winget/SQLiteDynamicStorage.h>\r\n#include <winrt/Microsoft.Management.Configuration.h>\r\n#include <memory>\r\n#include <optional>\r\n#include <vector>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    // Forward declarations\r\n    struct ConfigurationSet;\r\n    struct IConfigurationDatabase;\r\n\r\n    // Allows access to the configuration database.\r\n    struct ConfigurationDatabase\r\n    {\r\n        using ConfigurationSetPtr = winrt::com_ptr<implementation::ConfigurationSet>;\r\n\r\n        ConfigurationDatabase();\r\n\r\n        ConfigurationDatabase(const ConfigurationDatabase&) = delete;\r\n        ConfigurationDatabase& operator=(const ConfigurationDatabase&) = delete;\r\n\r\n        ConfigurationDatabase(ConfigurationDatabase&&);\r\n        ConfigurationDatabase& operator=(ConfigurationDatabase&&);\r\n\r\n        ~ConfigurationDatabase();\r\n\r\n        // Ensures that the database connection is established and the schema interface is created appropriately.\r\n        // If `createIfNeeded` is false, this function will not create the database if it does not exist.\r\n        // If not connected, any read methods will return empty results and any write methods will throw.\r\n        void EnsureOpened(bool createIfNeeded = true);\r\n\r\n        // Gets all of the configuration sets from the database.\r\n        std::vector<ConfigurationSetPtr> GetSetHistory() const;\r\n\r\n        // Gets the set with the given identifier.\r\n        ConfigurationSetPtr GetSet(const GUID& instanceIdentifier) const;\r\n\r\n        // Writes the given set to the database history, attempting to merge with a matching set if one exists unless preferNewHistory is true.\r\n        void WriteSetHistory(const Configuration::ConfigurationSet& configurationSet, bool preferNewHistory);\r\n\r\n        // Removes the given set from the database history if it is present.\r\n        void RemoveSetHistory(const Configuration::ConfigurationSet& configurationSet);\r\n\r\n        // Adds a new queue item for the given configuration set and object name.\r\n        void AddQueueItem(const Configuration::ConfigurationSet& configurationSet, const std::string& objectName);\r\n\r\n        // Sets the queue item with the given object name as active.\r\n        void SetActiveQueueItem(const std::string& objectName);\r\n\r\n        // Data about a queue item.\r\n        struct QueueItem\r\n        {\r\n            GUID SetInstanceIdentifier{};\r\n            std::string ObjectName;\r\n            std::chrono::system_clock::time_point QueuedAt;\r\n            DWORD ProcessId{};\r\n            bool Active = false;\r\n        };\r\n\r\n        // Gets all queue items in queue order (item at index 0 is active/next).\r\n        std::vector<QueueItem> GetQueueItems() const;\r\n\r\n        // Removes the queue item with the given object name.\r\n        void RemoveQueueItem(const std::string& objectName);\r\n\r\n        // A status line item.\r\n        struct StatusItem\r\n        {\r\n            int64_t ChangeIdentifier;\r\n            std::chrono::system_clock::time_point ChangeTime;\r\n            GUID SetInstanceIdentifier;\r\n            bool InQueue;\r\n            std::optional<GUID> UnitInstanceIdentifier;\r\n            int32_t State;\r\n            std::optional<HRESULT> ResultCode;\r\n            std::string ResultDescription;\r\n            std::string ResultDetails;\r\n            ConfigurationUnitResultSource ResultSource;\r\n        };\r\n\r\n        // Gets all changed status items after the given change identifier.\r\n        std::vector<StatusItem> GetStatusSince(int64_t changeIdentifier) const;\r\n\r\n        // The status baseline data.\r\n        struct StatusBaseline\r\n        {\r\n            int64_t ChangeIdentifier = 0;\r\n            std::vector<StatusItem> SetStatus;\r\n        };\r\n\r\n        // Gets the current status baseline.\r\n        StatusBaseline GetStatusBaseline() const;\r\n\r\n        // Data about a status change listener.\r\n        struct StatusChangeListener\r\n        {\r\n            std::string ObjectName;\r\n            std::chrono::system_clock::time_point Started;\r\n            DWORD ProcessId{};\r\n        };\r\n\r\n        // Adds a listener to the database.\r\n        void AddListener(const std::string& objectName);\r\n\r\n        // Removes a listener from the database.\r\n        void RemoveListener(const std::string& objectName);\r\n\r\n        // Gets all listeners in the database.\r\n        std::vector<StatusChangeListener> GetChangeListeners() const;\r\n\r\n        // Updates the set state in the database.\r\n        void UpdateSetState(const guid& setInstanceIdentifier, ConfigurationSetState state);\r\n\r\n        // Updates the set \"in queue\" state in the database.\r\n        void UpdateSetInQueue(const guid& setInstanceIdentifier, bool inQueue);\r\n\r\n        // Updates the unit state in the database.\r\n        void UpdateUnitState(const guid& setInstanceIdentifier, const com_ptr<implementation::ConfigurationSetChangeData>& changeData);\r\n\r\n        // Read various status values.\r\n        ConfigurationSetState GetSetState(const guid& instanceIdentifier);\r\n        std::chrono::system_clock::time_point GetSetFirstApply(const guid& instanceIdentifier);\r\n        std::chrono::system_clock::time_point GetSetApplyBegun(const guid& instanceIdentifier);\r\n        std::chrono::system_clock::time_point GetSetApplyEnded(const guid& instanceIdentifier);\r\n        ConfigurationUnitState GetUnitState(const guid& instanceIdentifier);\r\n        IConfigurationUnitResultInformation GetUnitResultInformation(const guid& instanceIdentifier);\r\n\r\n    private:\r\n        std::shared_ptr<AppInstaller::SQLite::SQLiteDynamicStorage> m_connection;\r\n        mutable std::shared_ptr<IConfigurationDatabase> m_database;\r\n\r\n        using TransactionLock = decltype(m_connection->TryBeginTransaction({}, true));\r\n\r\n        // Begins a transaction, which may require upgrading to a newer schema version.\r\n        TransactionLock BeginTransaction(std::string_view name, bool forWrite, std::shared_ptr<IConfigurationDatabase>& database) const;\r\n\r\n        // Performs the boilerplate setup for a read, then executes the given operation.\r\n        template <typename OperationT>\r\n        auto ExecuteReadOperation(std::string_view operationName, OperationT&& operation, bool requireDatabase = false) const;\r\n\r\n        // Performs the boilerplate setup for a write, then executes the given operation.\r\n        template <typename OperationT>\r\n        void ExecuteWriteOperation(std::string_view operationName, OperationT&& operation, bool silentlyIgnoreNoDatabase = false);\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Database/Schema/0_1/Interface.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Database/Schema/IConfigurationDatabase.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation::Database::Schema::V0_1\r\n{\r\n    struct Interface : public IConfigurationDatabase\r\n    {\r\n        Interface(std::shared_ptr<AppInstaller::SQLite::SQLiteDynamicStorage> storage);\r\n\r\n        const AppInstaller::SQLite::Version& GetSchemaVersion() override;\r\n\r\n        // Version 0.1\r\n        void InitializeDatabase() override;\r\n        void AddSet(const Configuration::ConfigurationSet& configurationSet) override;\r\n        void UpdateSet(AppInstaller::SQLite::rowid_t target, const Configuration::ConfigurationSet& configurationSet) override;\r\n        void RemoveSet(AppInstaller::SQLite::rowid_t target) override;\r\n        std::vector<ConfigurationSetPtr> GetSets() override;\r\n        std::optional<AppInstaller::SQLite::rowid_t> GetSetRowId(const GUID& instanceIdentifier) override;\r\n\r\n        // Version 0.2\r\n        bool MigrateFrom(IConfigurationDatabase* current) override;\r\n\r\n        // Version 0.3\r\n        ConfigurationSetPtr GetSet(const GUID& instanceIdentifier) override;\r\n\r\n    protected:\r\n        std::shared_ptr<AppInstaller::SQLite::SQLiteDynamicStorage> m_storage;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Database/Schema/0_1/Interface_0_1.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Interface.h\"\r\n#include \"SetInfoTable.h\"\r\n#include \"UnitInfoTable.h\"\r\n\r\nusing namespace AppInstaller::SQLite;\r\nusing namespace AppInstaller::Utility;\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation::Database::Schema::V0_1\r\n{\r\n    static constexpr AppInstaller::SQLite::Version s_InterfaceVersion{ 0, 1 };\r\n\r\n    Interface::Interface(std::shared_ptr<AppInstaller::SQLite::SQLiteDynamicStorage> storage) :\r\n        m_storage(std::move(storage))\r\n    {}\r\n\r\n    const AppInstaller::SQLite::Version& Interface::GetSchemaVersion()\r\n    {\r\n        return s_InterfaceVersion;\r\n    }\r\n\r\n    void Interface::InitializeDatabase()\r\n    {\r\n        // Must enable WAL mode outside of a transaction\r\n        THROW_HR_IF(E_UNEXPECTED, !m_storage->GetConnection().SetJournalMode(\"WAL\"));\r\n\r\n        Savepoint savepoint = Savepoint::Create(*m_storage, \"InitializeDatabase_0_1\");\r\n\r\n        SetInfoTable setInfoTable(*m_storage);\r\n        setInfoTable.Create();\r\n\r\n        UnitInfoTable unitInfoTable(*m_storage);\r\n        unitInfoTable.Create();\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    void Interface::AddSet(const Configuration::ConfigurationSet& configurationSet)\r\n    {\r\n        Savepoint savepoint = Savepoint::Create(*m_storage, \"AddSet_0_1\");\r\n\r\n        SetInfoTable setInfoTable(*m_storage);\r\n        setInfoTable.Add(configurationSet);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    void Interface::UpdateSet(rowid_t target, const Configuration::ConfigurationSet& configurationSet)\r\n    {\r\n        Savepoint savepoint = Savepoint::Create(*m_storage, \"UpdateSet_0_1\");\r\n\r\n        SetInfoTable setInfoTable(*m_storage);\r\n        setInfoTable.Update(target, configurationSet);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    void Interface::RemoveSet(rowid_t target)\r\n    {\r\n        Savepoint savepoint = Savepoint::Create(*m_storage, \"RemoveSet_0_1\");\r\n\r\n        SetInfoTable setInfoTable(*m_storage);\r\n        setInfoTable.Remove(target);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    std::vector<IConfigurationDatabase::ConfigurationSetPtr> Interface::GetSets()\r\n    {\r\n        SetInfoTable setInfoTable(*m_storage);\r\n        return setInfoTable.GetAllSets();\r\n    }\r\n\r\n    std::optional<rowid_t> Interface::GetSetRowId(const GUID& instanceIdentifier)\r\n    {\r\n        SetInfoTable setInfoTable(*m_storage);\r\n        return setInfoTable.GetSetRowId(instanceIdentifier);\r\n    }\r\n\r\n    bool Interface::MigrateFrom(IConfigurationDatabase* current)\r\n    {\r\n        return current->GetSchemaVersion() == s_InterfaceVersion;\r\n    }\r\n\r\n    Interface::ConfigurationSetPtr Interface::GetSet(const GUID& instanceIdentifier)\r\n    {\r\n        SetInfoTable setInfoTable(*m_storage);\r\n        return setInfoTable.GetSet(instanceIdentifier);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Database/Schema/0_1/SetInfoTable.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"SetInfoTable.h\"\r\n#include \"UnitInfoTable.h\"\r\n#include \"ConfigurationSetSerializer.h\"\r\n#include \"ConfigurationSetParser.h\"\r\n#include <AppInstallerDateTime.h>\r\n#include <AppInstallerStrings.h>\r\n#include <winget/SQLiteStatementBuilder.h>\r\n\r\nusing namespace AppInstaller::SQLite;\r\nusing namespace AppInstaller::SQLite::Builder;\r\nusing namespace AppInstaller::Utility;\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation::Database::Schema::V0_1\r\n{\r\n    namespace\r\n    {\r\n        constexpr std::string_view s_SetInfoTable_Table = \"set_info\"sv;\r\n\r\n        constexpr std::string_view s_SetInfoTable_Column_InstanceIdentifier = \"instance_identifier\"sv;\r\n        constexpr std::string_view s_SetInfoTable_Column_Name = \"name\"sv;\r\n        constexpr std::string_view s_SetInfoTable_Column_Origin = \"origin\"sv;\r\n        constexpr std::string_view s_SetInfoTable_Column_Path = \"path\"sv;\r\n        constexpr std::string_view s_SetInfoTable_Column_FirstApply = \"first_apply\"sv;\r\n        constexpr std::string_view s_SetInfoTable_Column_SchemaVersion = \"schema_version\"sv;\r\n        constexpr std::string_view s_SetInfoTable_Column_Metadata = \"metadata\"sv;\r\n        constexpr std::string_view s_SetInfoTable_Column_Parameters = \"parameters\"sv;\r\n        constexpr std::string_view s_SetInfoTable_Column_Variables = \"variables\"sv;\r\n\r\n        void BuildBaseSetSelectStatement(StatementBuilder& builder)\r\n        {\r\n            builder.Select({\r\n                RowIDName,                                  // 0\r\n                s_SetInfoTable_Column_InstanceIdentifier,   // 1\r\n                s_SetInfoTable_Column_Name,                 // 2\r\n                s_SetInfoTable_Column_Origin,               // 3\r\n                s_SetInfoTable_Column_Path,                 // 4\r\n                s_SetInfoTable_Column_SchemaVersion,        // 5\r\n                s_SetInfoTable_Column_Metadata,             // 6\r\n                s_SetInfoTable_Column_Parameters,           // 7\r\n                s_SetInfoTable_Column_Variables,            // 8\r\n            }).From(s_SetInfoTable_Table);\r\n        }\r\n\r\n        IConfigurationDatabase::ConfigurationSetPtr GetSetFromStatement(Statement& statement, UnitInfoTable& unitInfoTable)\r\n        {\r\n            auto configurationSet = make_self<implementation::ConfigurationSet>(statement.GetColumn<GUID>(1));\r\n\r\n            configurationSet->Name(hstring{ ConvertToUTF16(statement.GetColumn<std::string>(2)) });\r\n            configurationSet->Origin(hstring{ ConvertToUTF16(statement.GetColumn<std::string>(3)) });\r\n            configurationSet->Path(hstring{ ConvertToUTF16(statement.GetColumn<std::string>(4)) });\r\n\r\n            std::string schemaVersion = statement.GetColumn<std::string>(5);\r\n            configurationSet->SchemaVersion(hstring{ ConvertToUTF16(schemaVersion) });\r\n\r\n            auto parser = ConfigurationSetParser::CreateForSchemaVersion(schemaVersion);\r\n            configurationSet->Metadata(parser->ParseValueSet(statement.GetColumn<std::string>(6)));\r\n            parser->ExtractEnvironmentFromMetadata(configurationSet->Metadata(), configurationSet->EnvironmentInternal());\r\n\r\n            THROW_HR_IF(E_NOTIMPL, !statement.GetColumn<std::string>(7).empty());\r\n            configurationSet->Variables(parser->ParseValueSet(statement.GetColumn<std::string>(8)));\r\n\r\n            std::vector<Configuration::ConfigurationUnit> winrtUnits;\r\n            for (const auto& unit : unitInfoTable.GetAllUnitsForSet(statement.GetColumn<rowid_t>(0), schemaVersion))\r\n            {\r\n                winrtUnits.emplace_back(*unit);\r\n            }\r\n            configurationSet->Units(std::move(winrtUnits));\r\n\r\n            return configurationSet;\r\n        }\r\n    }\r\n\r\n    SetInfoTable::SetInfoTable(Connection& connection) : m_connection(connection) {}\r\n\r\n    std::string_view SetInfoTable::TableName()\r\n    {\r\n        return s_SetInfoTable_Table;\r\n    }\r\n\r\n    std::string_view SetInfoTable::InstanceIdentifierColumn()\r\n    {\r\n        return s_SetInfoTable_Column_InstanceIdentifier;\r\n    }\r\n\r\n    void SetInfoTable::Create()\r\n    {\r\n        Savepoint savepoint = Savepoint::Create(m_connection, \"SetInfoTable_Create_0_1\");\r\n\r\n        StatementBuilder tableBuilder;\r\n        tableBuilder.CreateTable(s_SetInfoTable_Table).Columns({\r\n            IntegerPrimaryKey(),\r\n            ColumnBuilder(s_SetInfoTable_Column_InstanceIdentifier, Type::Blob).Unique().NotNull(),\r\n            ColumnBuilder(s_SetInfoTable_Column_Name, Type::Text).NotNull(),\r\n            ColumnBuilder(s_SetInfoTable_Column_Origin, Type::Text).NotNull(),\r\n            ColumnBuilder(s_SetInfoTable_Column_Path, Type::Text).NotNull(),\r\n            ColumnBuilder(s_SetInfoTable_Column_FirstApply, Type::Int64).NotNull(),\r\n            ColumnBuilder(s_SetInfoTable_Column_SchemaVersion, Type::Text).NotNull(),\r\n            ColumnBuilder(s_SetInfoTable_Column_Metadata, Type::Text).NotNull(),\r\n            ColumnBuilder(s_SetInfoTable_Column_Parameters, Type::Text).NotNull(),\r\n            ColumnBuilder(s_SetInfoTable_Column_Variables, Type::Text).NotNull(),\r\n        });\r\n\r\n        tableBuilder.Execute(m_connection);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    rowid_t SetInfoTable::Add(const Configuration::ConfigurationSet& configurationSet)\r\n    {\r\n        THROW_HR_IF(E_NOTIMPL, configurationSet.Parameters().Size() > 0);\r\n\r\n        Savepoint savepoint = Savepoint::Create(m_connection, \"SetInfoTable_Add_0_1\");\r\n\r\n        hstring schemaVersion = configurationSet.SchemaVersion();\r\n        auto serializer = ConfigurationSetSerializer::CreateSerializer(schemaVersion);\r\n\r\n        StatementBuilder builder;\r\n        builder.InsertInto(s_SetInfoTable_Table).Columns({\r\n            s_SetInfoTable_Column_InstanceIdentifier,\r\n            s_SetInfoTable_Column_Name,\r\n            s_SetInfoTable_Column_Origin,\r\n            s_SetInfoTable_Column_Path,\r\n            s_SetInfoTable_Column_FirstApply,\r\n            s_SetInfoTable_Column_SchemaVersion,\r\n            s_SetInfoTable_Column_Metadata,\r\n            s_SetInfoTable_Column_Parameters,\r\n            s_SetInfoTable_Column_Variables,\r\n        }).Values(\r\n            static_cast<GUID>(configurationSet.InstanceIdentifier()),\r\n            ConvertToUTF8(configurationSet.Name()),\r\n            ConvertToUTF8(configurationSet.Origin()),\r\n            ConvertToUTF8(configurationSet.Path()),\r\n            GetCurrentUnixEpoch(),\r\n            ConvertToUTF8(schemaVersion),\r\n            serializer->SerializeMetadataWithEnvironment(configurationSet.Metadata(), configurationSet.Environment()),\r\n            std::string{}, // Parameters\r\n            serializer->SerializeValueSet(configurationSet.Variables())\r\n        );\r\n\r\n        builder.Execute(m_connection);\r\n        rowid_t result = m_connection.GetLastInsertRowID();\r\n\r\n        UnitInfoTable unitInfoTable(m_connection);\r\n\r\n        auto winrtUnits = configurationSet.Units();\r\n        std::vector<Configuration::ConfigurationUnit> units{ winrtUnits.Size() };\r\n        winrtUnits.GetMany(0, units);\r\n\r\n        for (const auto& unit : units)\r\n        {\r\n            unitInfoTable.Add(unit, result, schemaVersion);\r\n        }\r\n\r\n        savepoint.Commit();\r\n        return result;\r\n    }\r\n\r\n    void SetInfoTable::Update(rowid_t target, const Configuration::ConfigurationSet& configurationSet)\r\n    {\r\n        THROW_HR_IF(E_NOTIMPL, configurationSet.Parameters().Size() > 0);\r\n\r\n        Savepoint savepoint = Savepoint::Create(m_connection, \"SetInfoTable_Update_0_1\");\r\n\r\n        hstring schemaVersion = configurationSet.SchemaVersion();\r\n        auto serializer = ConfigurationSetSerializer::CreateSerializer(schemaVersion);\r\n\r\n        StatementBuilder builder;\r\n        builder.Update(s_SetInfoTable_Table).Set().\r\n            Column(s_SetInfoTable_Column_Name).Equals(ConvertToUTF8(configurationSet.Name())).\r\n            Column(s_SetInfoTable_Column_Origin).Equals(ConvertToUTF8(configurationSet.Origin())).\r\n            Column(s_SetInfoTable_Column_Path).Equals(ConvertToUTF8(configurationSet.Path())).\r\n            Column(s_SetInfoTable_Column_SchemaVersion).Equals(ConvertToUTF8(schemaVersion)).\r\n            Column(s_SetInfoTable_Column_Metadata).Equals(serializer->SerializeMetadataWithEnvironment(configurationSet.Metadata(), configurationSet.Environment())).\r\n            Column(s_SetInfoTable_Column_Variables).Equals(serializer->SerializeValueSet(configurationSet.Variables())).\r\n        Where(RowIDName).Equals(target);\r\n\r\n        builder.Execute(m_connection);\r\n\r\n        UnitInfoTable unitInfoTable(m_connection);\r\n        unitInfoTable.UpdateForSet(target, configurationSet.Units(), schemaVersion);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    void SetInfoTable::Remove(rowid_t target)\r\n    {\r\n        Savepoint savepoint = Savepoint::Create(m_connection, \"SetInfoTable_Remove_0_1\");\r\n\r\n        StatementBuilder builder;\r\n        builder.DeleteFrom(s_SetInfoTable_Table).Where(RowIDName).Equals(target);\r\n        builder.Execute(m_connection);\r\n\r\n        UnitInfoTable unitInfoTable(m_connection);\r\n        unitInfoTable.RemoveForSet(target);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    std::vector<IConfigurationDatabase::ConfigurationSetPtr> SetInfoTable::GetAllSets()\r\n    {\r\n        std::vector<IConfigurationDatabase::ConfigurationSetPtr> result;\r\n\r\n        StatementBuilder builder;\r\n        BuildBaseSetSelectStatement(builder);\r\n\r\n        Statement getAllSets = builder.Prepare(m_connection);\r\n\r\n        UnitInfoTable unitInfoTable(m_connection);\r\n\r\n        while (getAllSets.Step())\r\n        {\r\n            result.emplace_back(GetSetFromStatement(getAllSets, unitInfoTable));\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::optional<rowid_t> SetInfoTable::GetSetRowId(const GUID& instanceIdentifier)\r\n    {\r\n        StatementBuilder builder;\r\n        builder.Select(RowIDName).From(s_SetInfoTable_Table).Where(s_SetInfoTable_Column_InstanceIdentifier).Equals(instanceIdentifier);\r\n\r\n        Statement select = builder.Prepare(m_connection);\r\n\r\n        if (select.Step())\r\n        {\r\n            return select.GetColumn<rowid_t>(0);\r\n        }\r\n\r\n        return std::nullopt;\r\n    }\r\n\r\n    IConfigurationDatabase::ConfigurationSetPtr SetInfoTable::GetSet(const GUID& instanceIdentifier)\r\n    {\r\n        IConfigurationDatabase::ConfigurationSetPtr result;\r\n\r\n        StatementBuilder builder;\r\n        BuildBaseSetSelectStatement(builder);\r\n        builder.Where(s_SetInfoTable_Column_InstanceIdentifier).Equals(instanceIdentifier);\r\n\r\n        Statement getSet = builder.Prepare(m_connection);\r\n\r\n        if (getSet.Step())\r\n        {\r\n            UnitInfoTable unitInfoTable(m_connection);\r\n            result = GetSetFromStatement(getSet, unitInfoTable);\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::chrono::system_clock::time_point SetInfoTable::GetSetFirstApply(const GUID& instanceIdentifier)\r\n    {\r\n        StatementBuilder builder;\r\n        builder.Select(s_SetInfoTable_Column_FirstApply).From(s_SetInfoTable_Table).Where(s_SetInfoTable_Column_InstanceIdentifier).Equals(instanceIdentifier);\r\n\r\n        Statement statement = builder.Prepare(m_connection);\r\n\r\n        return (statement.Step() ? ConvertUnixEpochToSystemClock(statement.GetColumn<int64_t>(0)) : std::chrono::system_clock::time_point{});\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Database/Schema/0_1/SetInfoTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"winrt/Microsoft.Management.Configuration.h\"\r\n#include \"Database/Schema/IConfigurationDatabase.h\"\r\n#include <winget/SQLiteWrapper.h>\r\n#include <optional>\r\n#include <vector>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation::Database::Schema::V0_1\r\n{\r\n    struct SetInfoTable\r\n    {\r\n        SetInfoTable(AppInstaller::SQLite::Connection& connection);\r\n\r\n        static std::string_view TableName();\r\n        static std::string_view InstanceIdentifierColumn();\r\n\r\n        // Creates the set info table.\r\n        void Create();\r\n\r\n        // Adds the given configuration set to the table.\r\n        // Returns the row id of the added set.\r\n        AppInstaller::SQLite::rowid_t Add(const Configuration::ConfigurationSet& configurationSet);\r\n\r\n        // Updates the set with the target row id using the given set.\r\n        void Update(AppInstaller::SQLite::rowid_t target, const Configuration::ConfigurationSet& configurationSet);\r\n\r\n        // Removes the set with the target row id.\r\n        void Remove(AppInstaller::SQLite::rowid_t target);\r\n\r\n        // Gets all of the sets from the table.\r\n        std::vector<IConfigurationDatabase::ConfigurationSetPtr> GetAllSets();\r\n\r\n        // Gets the row id of the set with the given instance identifier.\r\n        std::optional<AppInstaller::SQLite::rowid_t> GetSetRowId(const GUID& instanceIdentifier);\r\n\r\n        // Gets the set with the given instance identifier.\r\n        IConfigurationDatabase::ConfigurationSetPtr GetSet(const GUID& instanceIdentifier);\r\n\r\n        // Gets a set's first apply time.\r\n        std::chrono::system_clock::time_point GetSetFirstApply(const GUID& instanceIdentifier);\r\n\r\n    private:\r\n        AppInstaller::SQLite::Connection& m_connection;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Database/Schema/0_1/UnitInfoTable.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"UnitInfoTable.h\"\r\n#include \"ConfigurationUnit.h\"\r\n#include \"ConfigurationSetParser.h\"\r\n#include \"ConfigurationSetSerializer.h\"\r\n#include <AppInstallerLanguageUtilities.h>\r\n#include <AppInstallerStrings.h>\r\n#include <winget/SQLiteStatementBuilder.h>\r\n\r\nusing namespace AppInstaller::SQLite;\r\nusing namespace AppInstaller::SQLite::Builder;\r\nusing namespace AppInstaller::Utility;\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation::Database::Schema::V0_1\r\n{\r\n    namespace\r\n    {\r\n        constexpr std::string_view s_UnitInfoTable_Table = \"unit_info\"sv;\r\n        constexpr std::string_view s_UnitInfoTable_SetRowIdIndex = \"unit_info_set_idx\"sv;\r\n\r\n        constexpr std::string_view s_UnitInfoTable_Column_SetRowId = \"set_rowid\"sv;\r\n        constexpr std::string_view s_UnitInfoTable_Column_ParentRowId = \"parent_rowid\"sv;\r\n        constexpr std::string_view s_UnitInfoTable_Column_InstanceIdentifier = \"instance_identifier\"sv;\r\n        constexpr std::string_view s_UnitInfoTable_Column_Type = \"type\"sv;\r\n        constexpr std::string_view s_UnitInfoTable_Column_Identifier = \"identifier\"sv;\r\n        constexpr std::string_view s_UnitInfoTable_Column_Intent = \"intent\"sv;\r\n        constexpr std::string_view s_UnitInfoTable_Column_Dependencies = \"dependencies\"sv;\r\n        constexpr std::string_view s_UnitInfoTable_Column_Metadata = \"metadata\"sv;\r\n        constexpr std::string_view s_UnitInfoTable_Column_Settings = \"settings\"sv;\r\n        constexpr std::string_view s_UnitInfoTable_Column_IsActive = \"is_active\"sv;\r\n        constexpr std::string_view s_UnitInfoTable_Column_IsGroup = \"is_group\"sv;\r\n    }\r\n\r\n    UnitInfoTable::UnitInfoTable(Connection& connection) : m_connection(connection) {}\r\n\r\n    void UnitInfoTable::Create()\r\n    {\r\n        Savepoint savepoint = Savepoint::Create(m_connection, \"UnitInfoTable_Create_0_1\");\r\n\r\n        StatementBuilder tableBuilder;\r\n        tableBuilder.CreateTable(s_UnitInfoTable_Table).Columns({\r\n            IntegerPrimaryKey(),\r\n            ColumnBuilder(s_UnitInfoTable_Column_SetRowId, Type::RowId).NotNull(),\r\n            ColumnBuilder(s_UnitInfoTable_Column_ParentRowId, Type::RowId),\r\n            ColumnBuilder(s_UnitInfoTable_Column_InstanceIdentifier, Type::Blob).NotNull(),\r\n            ColumnBuilder(s_UnitInfoTable_Column_Type, Type::Text).NotNull(),\r\n            ColumnBuilder(s_UnitInfoTable_Column_Identifier, Type::Text).NotNull(),\r\n            ColumnBuilder(s_UnitInfoTable_Column_Intent, Type::Int).NotNull(),\r\n            ColumnBuilder(s_UnitInfoTable_Column_Dependencies, Type::Text).NotNull(),\r\n            ColumnBuilder(s_UnitInfoTable_Column_Metadata, Type::Text).NotNull(),\r\n            ColumnBuilder(s_UnitInfoTable_Column_Settings, Type::Text).NotNull(),\r\n            ColumnBuilder(s_UnitInfoTable_Column_IsActive, Type::Bool).NotNull(),\r\n            ColumnBuilder(s_UnitInfoTable_Column_IsGroup, Type::Bool).NotNull(),\r\n            });\r\n\r\n        tableBuilder.Execute(m_connection);\r\n\r\n        StatementBuilder indexBuilder;\r\n        indexBuilder.CreateIndex(s_UnitInfoTable_SetRowIdIndex).On(s_UnitInfoTable_Table).Columns(s_UnitInfoTable_Column_SetRowId);\r\n\r\n        indexBuilder.Execute(m_connection);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    void UnitInfoTable::Add(const Configuration::ConfigurationUnit& configurationUnit, AppInstaller::SQLite::rowid_t setRowId, hstring schemaVersion)\r\n    {\r\n        Savepoint savepoint = Savepoint::Create(m_connection, \"UnitInfoTable_Add_0_1\");\r\n\r\n        StatementBuilder builder;\r\n        builder.InsertInto(s_UnitInfoTable_Table).Columns({\r\n            s_UnitInfoTable_Column_SetRowId,\r\n            s_UnitInfoTable_Column_ParentRowId,\r\n            s_UnitInfoTable_Column_InstanceIdentifier,\r\n            s_UnitInfoTable_Column_Type,\r\n            s_UnitInfoTable_Column_Identifier,\r\n            s_UnitInfoTable_Column_Intent,\r\n            s_UnitInfoTable_Column_Dependencies,\r\n            s_UnitInfoTable_Column_Metadata,\r\n            s_UnitInfoTable_Column_Settings,\r\n            s_UnitInfoTable_Column_IsActive,\r\n            s_UnitInfoTable_Column_IsGroup,\r\n        }).Values(\r\n            Unbound,\r\n            Unbound,\r\n            Unbound,\r\n            Unbound,\r\n            Unbound,\r\n            Unbound,\r\n            Unbound,\r\n            Unbound,\r\n            Unbound,\r\n            Unbound,\r\n            Unbound\r\n        );\r\n\r\n        Statement insertStatement = builder.Prepare(m_connection);\r\n\r\n        struct UnitsToInsert\r\n        {\r\n            std::optional<rowid_t> Parent;\r\n            Configuration::ConfigurationUnit Unit;\r\n        };\r\n\r\n        std::queue<UnitsToInsert> unitsToInsert;\r\n        unitsToInsert.emplace(UnitsToInsert{ std::nullopt, configurationUnit });\r\n        auto serializer = ConfigurationSetSerializer::CreateSerializer(schemaVersion);\r\n\r\n        while (!unitsToInsert.empty())\r\n        {\r\n            const auto& current = unitsToInsert.front();\r\n\r\n            insertStatement.Reset();\r\n\r\n            bool isGroup = current.Unit.IsGroup();\r\n\r\n            insertStatement.Bind(1, setRowId);\r\n            insertStatement.Bind(2, current.Parent);\r\n            insertStatement.Bind(3, static_cast<GUID>(current.Unit.InstanceIdentifier()));\r\n            insertStatement.Bind(4, ConvertToUTF8(current.Unit.Type()));\r\n            insertStatement.Bind(5, ConvertToUTF8(current.Unit.Identifier()));\r\n            insertStatement.Bind(6, AppInstaller::ToIntegral(current.Unit.Intent()));\r\n            insertStatement.Bind(7, serializer->SerializeStringArray(current.Unit.Dependencies()));\r\n            insertStatement.Bind(8, serializer->SerializeMetadataWithEnvironment(current.Unit.Metadata(), current.Unit.Environment()));\r\n            insertStatement.Bind(9, serializer->SerializeValueSet(current.Unit.Settings()));\r\n            insertStatement.Bind(10, current.Unit.IsActive());\r\n            insertStatement.Bind(11, isGroup);\r\n\r\n            insertStatement.Execute();\r\n\r\n            if (isGroup)\r\n            {\r\n                rowid_t currentRowId = m_connection.GetLastInsertRowID();\r\n\r\n                auto winrtUnits = current.Unit.Units();\r\n                std::vector<Configuration::ConfigurationUnit> units{ winrtUnits.Size() };\r\n                winrtUnits.GetMany(0, units);\r\n\r\n                for (const auto& unit : units)\r\n                {\r\n                    unitsToInsert.emplace(UnitsToInsert{ currentRowId, unit });\r\n                }\r\n            }\r\n\r\n            unitsToInsert.pop();\r\n        }\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    void UnitInfoTable::UpdateForSet(AppInstaller::SQLite::rowid_t target, const Windows::Foundation::Collections::IVector<Configuration::ConfigurationUnit>& winrtUnits, hstring schemaVersion)\r\n    {\r\n        Savepoint savepoint = Savepoint::Create(m_connection, \"UnitInfoTable_UpdateForSet_0_1\");\r\n\r\n        RemoveForSet(target);\r\n\r\n        std::vector<Configuration::ConfigurationUnit> units{ winrtUnits.Size() };\r\n        winrtUnits.GetMany(0, units);\r\n\r\n        for (const auto& unit : units)\r\n        {\r\n            Add(unit, target, schemaVersion);\r\n        }\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    void UnitInfoTable::RemoveForSet(AppInstaller::SQLite::rowid_t target)\r\n    {\r\n        StatementBuilder builder;\r\n        builder.DeleteFrom(s_UnitInfoTable_Table).Where(s_UnitInfoTable_Column_SetRowId).Equals(target);\r\n        builder.Execute(m_connection);\r\n    }\r\n\r\n    std::vector<IConfigurationDatabase::ConfigurationUnitPtr> UnitInfoTable::GetAllUnitsForSet(AppInstaller::SQLite::rowid_t setRowId, std::string_view schemaVersion)\r\n    {\r\n        StatementBuilder builder;\r\n        builder.Select({\r\n            RowIDName,                                 // 0\r\n            s_UnitInfoTable_Column_ParentRowId,        // 1\r\n            s_UnitInfoTable_Column_InstanceIdentifier, // 2\r\n            s_UnitInfoTable_Column_Type,               // 3\r\n            s_UnitInfoTable_Column_Identifier,         // 4\r\n            s_UnitInfoTable_Column_Intent,             // 5\r\n            s_UnitInfoTable_Column_Dependencies,       // 6\r\n            s_UnitInfoTable_Column_Metadata,           // 7\r\n            s_UnitInfoTable_Column_Settings,           // 8\r\n            s_UnitInfoTable_Column_IsActive,           // 9\r\n            s_UnitInfoTable_Column_IsGroup,            // 10\r\n        }).From(s_UnitInfoTable_Table).Where(s_UnitInfoTable_Column_SetRowId).Equals(setRowId);\r\n\r\n        Statement statement = builder.Prepare(m_connection);\r\n\r\n        std::vector<IConfigurationDatabase::ConfigurationUnitPtr> result;\r\n        std::map<rowid_t, IConfigurationDatabase::ConfigurationUnitPtr> rowToUnitMap;\r\n        auto parser = ConfigurationSetParser::CreateForSchemaVersion(std::string{ schemaVersion });\r\n\r\n        while (statement.Step())\r\n        {\r\n            auto unit = make_self<implementation::ConfigurationUnit>(statement.GetColumn<GUID>(2));\r\n\r\n            unit->Type(hstring{ ConvertToUTF16(statement.GetColumn<std::string>(3)) });\r\n            unit->Identifier(hstring{ ConvertToUTF16(statement.GetColumn<std::string>(4)) });\r\n            unit->Intent(statement.GetColumn<ConfigurationUnitIntent>(5));\r\n            unit->Dependencies(parser->ParseStringArray(statement.GetColumn<std::string>(6)));\r\n            unit->Metadata(parser->ParseValueSet(statement.GetColumn<std::string>(7)));\r\n            unit->Settings(parser->ParseValueSet(statement.GetColumn<std::string>(8)));\r\n            unit->IsActive(statement.GetColumn<bool>(9));\r\n            unit->IsGroup(statement.GetColumn<bool>(10));\r\n\r\n            parser->ExtractEnvironmentFromMetadata(unit->Metadata(), unit->EnvironmentInternal());\r\n\r\n            if (statement.GetColumnIsNull(1))\r\n            {\r\n                result.emplace_back(unit);\r\n            }\r\n            else\r\n            {\r\n                rowToUnitMap.at(statement.GetColumn<rowid_t>(1))->Units().Append(*unit);\r\n            }\r\n\r\n            rowToUnitMap.emplace(statement.GetColumn<rowid_t>(0), unit);\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Database/Schema/0_1/UnitInfoTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"winrt/Microsoft.Management.Configuration.h\"\r\n#include \"Database/Schema/IConfigurationDatabase.h\"\r\n#include <winget/SQLiteWrapper.h>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation::Database::Schema::V0_1\r\n{\r\n    struct UnitInfoTable\r\n    {\r\n        UnitInfoTable(AppInstaller::SQLite::Connection& connection);\r\n\r\n        // Creates the unit info table.\r\n        void Create();\r\n\r\n        // Adds the given configuration unit to the table.\r\n        void Add(const Configuration::ConfigurationUnit& configurationUnit, AppInstaller::SQLite::rowid_t setRowId, hstring schemaVersion);\r\n\r\n        // Updates the units for the target set.\r\n        void UpdateForSet(AppInstaller::SQLite::rowid_t target, const Windows::Foundation::Collections::IVector<Configuration::ConfigurationUnit>& units, hstring schemaVersion);\r\n\r\n        // Removes the units from the target set.\r\n        void RemoveForSet(AppInstaller::SQLite::rowid_t target);\r\n\r\n        // Gets all of the units for the given set.\r\n        std::vector<IConfigurationDatabase::ConfigurationUnitPtr> GetAllUnitsForSet(AppInstaller::SQLite::rowid_t setRowId, std::string_view schemaVersion);\r\n\r\n    private:\r\n        AppInstaller::SQLite::Connection& m_connection;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Database/Schema/0_2/Interface.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Database/Schema/IConfigurationDatabase.h\"\r\n#include \"Database/Schema/0_1/Interface.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation::Database::Schema::V0_2\r\n{\r\n    struct Interface : public V0_1::Interface\r\n    {\r\n        using V0_1::Interface::Interface;\r\n\r\n        const AppInstaller::SQLite::Version& GetSchemaVersion() override;\r\n\r\n        // Version 0.1\r\n        void InitializeDatabase() override;\r\n\r\n        // Version 0.2\r\n        bool MigrateFrom(IConfigurationDatabase* current) override;\r\n        void AddQueueItem(const GUID& instanceIdentifier, const std::string& objectName) override;\r\n        void SetActiveQueueItem(const std::string& objectName) override;\r\n        std::vector<std::tuple<GUID, std::string, std::chrono::system_clock::time_point, DWORD, bool>> GetQueueItems() override;\r\n        void RemoveQueueItem(const std::string& objectName) override;\r\n\r\n    private:\r\n        // Unconditionally attempts to migrate from the 0.1 base.\r\n        void MigrateFrom0_1();\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Database/Schema/0_2/Interface_0_2.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Interface.h\"\r\n#include \"QueueTable.h\"\r\n#include <winget/SQLiteMetadataTable.h>\r\n\r\nusing namespace AppInstaller::SQLite;\r\nusing namespace AppInstaller::Utility;\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation::Database::Schema::V0_2\r\n{\r\n    static constexpr AppInstaller::SQLite::Version s_InterfaceVersion{ 0, 2 };\r\n\r\n    const AppInstaller::SQLite::Version& Interface::GetSchemaVersion()\r\n    {\r\n        return s_InterfaceVersion;\r\n    }\r\n\r\n    void Interface::InitializeDatabase()\r\n    {\r\n        V0_1::Interface::InitializeDatabase();\r\n\r\n        Savepoint savepoint = Savepoint::Create(*m_storage, \"InitializeDatabase_0_2\");\r\n        MigrateFrom0_1();\r\n        savepoint.Commit();\r\n    }\r\n\r\n    bool Interface::MigrateFrom(IConfigurationDatabase* current)\r\n    {\r\n        auto currentSchemaVersion = current->GetSchemaVersion();\r\n        if (currentSchemaVersion < s_InterfaceVersion)\r\n        {\r\n            if (V0_1::Interface::MigrateFrom(current))\r\n            {\r\n                Savepoint savepoint = Savepoint::Create(*m_storage, \"MigrateFrom0_1\");\r\n\r\n                MigrateFrom0_1();\r\n                s_InterfaceVersion.SetSchemaVersion(*m_storage);\r\n\r\n                savepoint.Commit();\r\n\r\n                return true;\r\n            }\r\n        }\r\n        else if (currentSchemaVersion == s_InterfaceVersion)\r\n        {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    void Interface::AddQueueItem(const GUID& instanceIdentifier, const std::string& objectName)\r\n    {\r\n        QueueTable queueTable(*m_storage);\r\n        queueTable.AddQueueItemWithoutProcess(instanceIdentifier, objectName);\r\n    }\r\n\r\n    void Interface::SetActiveQueueItem(const std::string& objectName)\r\n    {\r\n        QueueTable queueTable(*m_storage);\r\n        queueTable.SetActiveQueueItem(objectName);\r\n    }\r\n\r\n    std::vector<std::tuple<GUID, std::string, std::chrono::system_clock::time_point, DWORD, bool>> Interface::GetQueueItems()\r\n    {\r\n        QueueTable queueTable(*m_storage);\r\n        return queueTable.GetQueueItemsWithoutProcess();\r\n    }\r\n\r\n    void Interface::RemoveQueueItem(const std::string& objectName)\r\n    {\r\n        QueueTable queueTable(*m_storage);\r\n        queueTable.RemoveQueueItem(objectName);\r\n    }\r\n\r\n    void Interface::MigrateFrom0_1()\r\n    {\r\n        QueueTable queueTable(*m_storage);\r\n        queueTable.Create();\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Database/Schema/0_2/QueueTable.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"QueueTable.h\"\r\n#include <AppInstallerDateTime.h>\r\n#include <winget/SQLiteStatementBuilder.h>\r\n\r\nusing namespace AppInstaller::SQLite;\r\nusing namespace AppInstaller::SQLite::Builder;\r\nusing namespace AppInstaller::Utility;\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation::Database::Schema::V0_2\r\n{\r\n    namespace\r\n    {\r\n        constexpr std::string_view s_QueueTable_Table = \"queue\"sv;\r\n\r\n        constexpr std::string_view s_QueueTable_Column_SetInstanceIdentifier = \"set_instance_identifier\"sv;\r\n        constexpr std::string_view s_QueueTable_Column_ObjectName = \"object_name\"sv;\r\n        constexpr std::string_view s_QueueTable_Column_QueuedAt = \"queued_at\"sv;\r\n        constexpr std::string_view s_QueueTable_Column_Active = \"active\"sv;\r\n        constexpr std::string_view s_QueueTable_Column_Process = \"process\"sv;\r\n    }\r\n\r\n    QueueTable::QueueTable(Connection& connection) : m_connection(connection) {}\r\n\r\n    void QueueTable::Create()\r\n    {\r\n        Savepoint savepoint = Savepoint::Create(m_connection, \"QueueTable_Create_0_2\");\r\n\r\n        StatementBuilder tableBuilder;\r\n        tableBuilder.CreateTable(s_QueueTable_Table).Columns({\r\n            IntegerPrimaryKey(),\r\n            ColumnBuilder(s_QueueTable_Column_SetInstanceIdentifier, Type::Blob).NotNull(),\r\n            ColumnBuilder(s_QueueTable_Column_ObjectName, Type::Text).Unique().NotNull(),\r\n            ColumnBuilder(s_QueueTable_Column_QueuedAt, Type::Int64).NotNull(),\r\n            ColumnBuilder(s_QueueTable_Column_Active, Type::Bool).NotNull(),\r\n        });\r\n\r\n        tableBuilder.Execute(m_connection);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    void QueueTable::AddProcessColumn()\r\n    {\r\n        Savepoint savepoint = Savepoint::Create(m_connection, \"QueueTable_AddProcessColumn_0_3\");\r\n\r\n        StatementBuilder builder;\r\n        builder.AlterTable(s_QueueTable_Table).Add(s_QueueTable_Column_Process, Type::Int64).NotNull().Default(0);\r\n\r\n        builder.Execute(m_connection);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    void QueueTable::AddQueueItemWithoutProcess(const GUID& instanceIdentifier, const std::string& objectName)\r\n    {\r\n        StatementBuilder builder;\r\n        builder.InsertInto(s_QueueTable_Table).Columns({\r\n            s_QueueTable_Column_SetInstanceIdentifier,\r\n            s_QueueTable_Column_ObjectName,\r\n            s_QueueTable_Column_QueuedAt,\r\n            s_QueueTable_Column_Active\r\n        }).Values(\r\n            instanceIdentifier,\r\n            objectName,\r\n            GetCurrentUnixEpoch(),\r\n            false\r\n        );\r\n\r\n        builder.Execute(m_connection);\r\n    }\r\n\r\n    void QueueTable::AddQueueItemWithProcess(const GUID& instanceIdentifier, const std::string& objectName)\r\n    {\r\n        StatementBuilder builder;\r\n        builder.InsertInto(s_QueueTable_Table).Columns({\r\n            s_QueueTable_Column_SetInstanceIdentifier,\r\n            s_QueueTable_Column_ObjectName,\r\n            s_QueueTable_Column_QueuedAt,\r\n            s_QueueTable_Column_Active,\r\n            s_QueueTable_Column_Process\r\n            }).Values(\r\n                instanceIdentifier,\r\n                objectName,\r\n                GetCurrentUnixEpoch(),\r\n                false,\r\n                static_cast<int64_t>(GetCurrentProcessId())\r\n            );\r\n\r\n        builder.Execute(m_connection);\r\n    }\r\n\r\n    void QueueTable::SetActiveQueueItem(const std::string& objectName)\r\n    {\r\n        StatementBuilder builder;\r\n        builder.Update(s_QueueTable_Table).Set().Column(s_QueueTable_Column_Active).Equals(true).Where(s_QueueTable_Column_ObjectName).Equals(objectName);\r\n\r\n        builder.Execute(m_connection);\r\n    }\r\n\r\n    std::vector<std::tuple<GUID, std::string, std::chrono::system_clock::time_point, DWORD, bool>> QueueTable::GetQueueItemsWithoutProcess()\r\n    {\r\n        StatementBuilder builder;\r\n        builder.Select({\r\n            s_QueueTable_Column_SetInstanceIdentifier,\r\n            s_QueueTable_Column_ObjectName,\r\n            s_QueueTable_Column_QueuedAt,\r\n            s_QueueTable_Column_Active\r\n            }).From(s_QueueTable_Table).OrderBy({ s_QueueTable_Column_QueuedAt, RowIDName });\r\n\r\n        Statement statement = builder.Prepare(m_connection);\r\n\r\n        std::vector<std::tuple<GUID, std::string, std::chrono::system_clock::time_point, DWORD, bool>> result;\r\n\r\n        while (statement.Step())\r\n        {\r\n            result.emplace_back(std::make_tuple(statement.GetColumn<GUID>(0), statement.GetColumn<std::string>(1), ConvertUnixEpochToSystemClock(statement.GetColumn<int64_t>(2)), 0, statement.GetColumn<bool>(3)));\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::vector<std::tuple<GUID, std::string, std::chrono::system_clock::time_point, DWORD, bool>> QueueTable::GetQueueItemsWithProcess()\r\n    {\r\n        StatementBuilder builder;\r\n        builder.Select({\r\n            s_QueueTable_Column_SetInstanceIdentifier,\r\n            s_QueueTable_Column_ObjectName,\r\n            s_QueueTable_Column_QueuedAt,\r\n            s_QueueTable_Column_Active,\r\n            s_QueueTable_Column_Process\r\n        }).From(s_QueueTable_Table).OrderBy({ s_QueueTable_Column_QueuedAt, RowIDName });\r\n\r\n        Statement statement = builder.Prepare(m_connection);\r\n\r\n        std::vector<std::tuple<GUID, std::string, std::chrono::system_clock::time_point, DWORD, bool>> result;\r\n\r\n        while (statement.Step())\r\n        {\r\n            result.emplace_back(std::make_tuple(statement.GetColumn<GUID>(0), statement.GetColumn<std::string>(1), ConvertUnixEpochToSystemClock(statement.GetColumn<int64_t>(2)), static_cast<DWORD>(statement.GetColumn<int64_t>(4)), statement.GetColumn<bool>(3)));\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    void QueueTable::RemoveQueueItem(const std::string& objectName)\r\n    {\r\n        StatementBuilder builder;\r\n        builder.DeleteFrom(s_QueueTable_Table).Where(s_QueueTable_Column_ObjectName).Equals(objectName);\r\n\r\n        builder.Execute(m_connection);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Database/Schema/0_2/QueueTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteWrapper.h>\r\n#include <vector>\r\n#include <tuple>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation::Database::Schema::V0_2\r\n{\r\n    struct QueueTable\r\n    {\r\n        QueueTable(AppInstaller::SQLite::Connection& connection);\r\n\r\n        // Creates the queue table.\r\n        void Create();\r\n\r\n        // Adds the process column to the table.\r\n        void AddProcessColumn();\r\n\r\n        // Adds a new queue item for the given configuration set and object name.\r\n        void AddQueueItemWithoutProcess(const GUID& instanceIdentifier, const std::string& objectName);\r\n\r\n        // Adds a new queue item for the given configuration set and object name.\r\n        void AddQueueItemWithProcess(const GUID& instanceIdentifier, const std::string& objectName);\r\n\r\n        // Sets the queue item with the given object name as active.\r\n        void SetActiveQueueItem(const std::string& objectName);\r\n\r\n        // Gets all queue items in queue order (item at index 0 is active/next).\r\n        std::vector<std::tuple<GUID, std::string, std::chrono::system_clock::time_point, DWORD, bool>> GetQueueItemsWithoutProcess();\r\n\r\n        // Gets all queue items in queue order (item at index 0 is active/next).\r\n        std::vector<std::tuple<GUID, std::string, std::chrono::system_clock::time_point, DWORD, bool>> GetQueueItemsWithProcess();\r\n\r\n        // Removes the queue item with the given object name.\r\n        void RemoveQueueItem(const std::string& objectName);\r\n\r\n    private:\r\n        AppInstaller::SQLite::Connection& m_connection;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Database/Schema/0_3/ChangeListenerTable.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ChangeListenerTable.h\"\r\n#include <AppInstallerDateTime.h>\r\n#include <winget/SQLiteStatementBuilder.h>\r\n\r\nusing namespace AppInstaller::SQLite;\r\nusing namespace AppInstaller::SQLite::Builder;\r\nusing namespace AppInstaller::Utility;\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation::Database::Schema::V0_3\r\n{\r\n    namespace\r\n    {\r\n        constexpr std::string_view s_ChangeListenerTable_Table = \"change_listeners\"sv;\r\n\r\n        constexpr std::string_view s_ChangeListenerTable_Column_ObjectName = \"object_name\"sv;\r\n        constexpr std::string_view s_ChangeListenerTable_Column_StartedAt = \"started_at\"sv;\r\n        constexpr std::string_view s_ChangeListenerTable_Column_Process = \"process\"sv;\r\n    }\r\n\r\n    ChangeListenerTable::ChangeListenerTable(Connection& connection) : m_connection(connection) {}\r\n\r\n    void ChangeListenerTable::Create()\r\n    {\r\n        Savepoint savepoint = Savepoint::Create(m_connection, \"ChangeListenerTable_Create_0_3\");\r\n\r\n        StatementBuilder tableBuilder;\r\n        tableBuilder.CreateTable(s_ChangeListenerTable_Table).Columns({\r\n            IntegerPrimaryKey(),\r\n            ColumnBuilder(s_ChangeListenerTable_Column_ObjectName, Type::Text).Unique().NotNull(),\r\n            ColumnBuilder(s_ChangeListenerTable_Column_StartedAt, Type::Int64).NotNull(),\r\n            ColumnBuilder(s_ChangeListenerTable_Column_Process, Type::Int64).NotNull(),\r\n        });\r\n\r\n        tableBuilder.Execute(m_connection);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    void ChangeListenerTable::AddChangeListener(const std::string& objectName)\r\n    {\r\n        StatementBuilder builder;\r\n        builder.InsertInto(s_ChangeListenerTable_Table).Columns({\r\n            s_ChangeListenerTable_Column_ObjectName,\r\n            s_ChangeListenerTable_Column_StartedAt,\r\n            s_ChangeListenerTable_Column_Process\r\n            }).Values(\r\n                objectName,\r\n                GetCurrentUnixEpoch(),\r\n                static_cast<int64_t>(GetCurrentProcessId())\r\n            );\r\n\r\n        builder.Execute(m_connection);\r\n    }\r\n\r\n    void ChangeListenerTable::RemoveChangeListener(const std::string& objectName)\r\n    {\r\n        StatementBuilder builder;\r\n        builder.DeleteFrom(s_ChangeListenerTable_Table).Where(s_ChangeListenerTable_Column_ObjectName).Equals(objectName);\r\n\r\n        builder.Execute(m_connection);\r\n    }\r\n\r\n    std::vector<std::tuple<std::string, std::chrono::system_clock::time_point, DWORD>> ChangeListenerTable::GetChangeListeners()\r\n    {\r\n        StatementBuilder builder;\r\n        builder.Select({\r\n            s_ChangeListenerTable_Column_ObjectName,\r\n            s_ChangeListenerTable_Column_StartedAt,\r\n            s_ChangeListenerTable_Column_Process\r\n        }).From(s_ChangeListenerTable_Table);\r\n\r\n        Statement statement = builder.Prepare(m_connection);\r\n\r\n        std::vector<std::tuple<std::string, std::chrono::system_clock::time_point, DWORD>> result;\r\n\r\n        while (statement.Step())\r\n        {\r\n            result.emplace_back(std::make_tuple(statement.GetColumn<std::string>(0), ConvertUnixEpochToSystemClock(statement.GetColumn<int64_t>(1)), static_cast<DWORD>(statement.GetColumn<int64_t>(2))));\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Database/Schema/0_3/ChangeListenerTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/SQLiteWrapper.h>\r\n#include <vector>\r\n#include <tuple>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation::Database::Schema::V0_3\r\n{\r\n    struct ChangeListenerTable\r\n    {\r\n        ChangeListenerTable(AppInstaller::SQLite::Connection& connection);\r\n\r\n        // Creates the table.\r\n        void Create();\r\n\r\n        // Adds a new change listener to the table.\r\n        void AddChangeListener(const std::string& objectName);\r\n\r\n        // Removes the change listener with the given name from the table.\r\n        void RemoveChangeListener(const std::string& objectName);\r\n\r\n        // Gets all change listeners.\r\n        std::vector<std::tuple<std::string, std::chrono::system_clock::time_point, DWORD>> GetChangeListeners();\r\n\r\n    private:\r\n        AppInstaller::SQLite::Connection& m_connection;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Database/Schema/0_3/Interface.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Database/Schema/IConfigurationDatabase.h\"\r\n#include \"Database/Schema/0_2/Interface.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation::Database::Schema::V0_3\r\n{\r\n    struct Interface : public V0_2::Interface\r\n    {\r\n        using V0_2::Interface::Interface;\r\n\r\n        const AppInstaller::SQLite::Version& GetSchemaVersion() override;\r\n\r\n        // Version 0.1\r\n        void InitializeDatabase() override;\r\n        void RemoveSet(AppInstaller::SQLite::rowid_t target) override;\r\n\r\n        // Version 0.2\r\n        bool MigrateFrom(IConfigurationDatabase* current) override;\r\n        void AddQueueItem(const GUID& instanceIdentifier, const std::string& objectName) override;\r\n        std::vector<std::tuple<GUID, std::string, std::chrono::system_clock::time_point, DWORD, bool>> GetQueueItems() override;\r\n\r\n        // Version 0.3\r\n        std::vector<StatusItemTuple> GetStatusSince(int64_t changeIdentifier) override;\r\n        std::tuple<int64_t, std::vector<StatusItemTuple>> GetStatusBaseline() override;\r\n        void AddListener(const std::string& objectName) override;\r\n        void RemoveListener(const std::string& objectName) override;\r\n        std::vector<std::tuple<std::string, std::chrono::system_clock::time_point, DWORD>> GetChangeListeners() override;\r\n        void UpdateSetState(const guid& setInstanceIdentifier, ConfigurationSetState state) override;\r\n        void UpdateSetInQueue(const guid& setInstanceIdentifier, bool inQueue) override;\r\n        void UpdateUnitState(const guid& setInstanceIdentifier, const ConfigurationSetChangeDataPtr& changeData) override;\r\n        ConfigurationSetState GetSetState(const guid& instanceIdentifier) override;\r\n        std::chrono::system_clock::time_point GetSetFirstApply(const guid& instanceIdentifier) override;\r\n        std::chrono::system_clock::time_point GetSetApplyBegun(const guid& instanceIdentifier) override;\r\n        std::chrono::system_clock::time_point GetSetApplyEnded(const guid& instanceIdentifier) override;\r\n        ConfigurationUnitState GetUnitState(const guid& instanceIdentifier) override;\r\n        std::optional<std::tuple<HRESULT, std::string, std::string, ConfigurationUnitResultSource>> GetUnitResultInformation(const guid& instanceIdentifier) override;\r\n\r\n    private:\r\n        // Unconditionally attempts to migrate from the 0.2 base.\r\n        void MigrateFrom0_2();\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Database/Schema/0_3/Interface_0_3.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Interface.h\"\r\n#include \"Database/Schema/0_1/SetInfoTable.h\"\r\n#include \"Database/Schema/0_2/QueueTable.h\"\r\n#include \"StatusItemTable.h\"\r\n#include \"ChangeListenerTable.h\"\r\n#include <winget/SQLiteMetadataTable.h>\r\n\r\nusing namespace AppInstaller::SQLite;\r\nusing namespace AppInstaller::Utility;\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation::Database::Schema::V0_3\r\n{\r\n    static constexpr AppInstaller::SQLite::Version s_InterfaceVersion{ 0, 3 };\r\n\r\n    const AppInstaller::SQLite::Version& Interface::GetSchemaVersion()\r\n    {\r\n        return s_InterfaceVersion;\r\n    }\r\n\r\n    void Interface::InitializeDatabase()\r\n    {\r\n        V0_2::Interface::InitializeDatabase();\r\n\r\n        Savepoint savepoint = Savepoint::Create(*m_storage, \"InitializeDatabase_0_3\");\r\n        MigrateFrom0_2();\r\n        savepoint.Commit();\r\n    }\r\n\r\n    void Interface::RemoveSet(AppInstaller::SQLite::rowid_t target)\r\n    {\r\n        Savepoint savepoint = Savepoint::Create(*m_storage, \"RemoveSet_0_3\");\r\n\r\n        V0_2::Interface::RemoveSet(target);\r\n\r\n        StatusItemTable statusItemTable(*m_storage);\r\n        statusItemTable.RemoveForSet(target);\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    bool Interface::MigrateFrom(IConfigurationDatabase* current)\r\n    {\r\n        auto currentSchemaVersion = current->GetSchemaVersion();\r\n        if (currentSchemaVersion < s_InterfaceVersion)\r\n        {\r\n            if (V0_2::Interface::MigrateFrom(current))\r\n            {\r\n                Savepoint savepoint = Savepoint::Create(*m_storage, \"MigrateFrom0_2\");\r\n\r\n                MigrateFrom0_2();\r\n                s_InterfaceVersion.SetSchemaVersion(*m_storage);\r\n\r\n                savepoint.Commit();\r\n\r\n                return true;\r\n            }\r\n        }\r\n        else if (currentSchemaVersion == s_InterfaceVersion)\r\n        {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    void Interface::AddQueueItem(const GUID& instanceIdentifier, const std::string& objectName)\r\n    {\r\n        V0_2::QueueTable queueTable(*m_storage);\r\n        queueTable.AddQueueItemWithProcess(instanceIdentifier, objectName);\r\n    }\r\n\r\n    std::vector<std::tuple<GUID, std::string, std::chrono::system_clock::time_point, DWORD, bool>> Interface::GetQueueItems()\r\n    {\r\n        V0_2::QueueTable queueTable(*m_storage);\r\n        return queueTable.GetQueueItemsWithProcess();\r\n    }\r\n\r\n    void Interface::MigrateFrom0_2()\r\n    {\r\n        V0_2::QueueTable queueTable(*m_storage);\r\n        queueTable.AddProcessColumn();\r\n\r\n        ChangeListenerTable changeListenerTable(*m_storage);\r\n        changeListenerTable.Create();\r\n\r\n        StatusItemTable statusItemTable(*m_storage);\r\n        statusItemTable.Create();\r\n    }\r\n\r\n    std::vector<IConfigurationDatabase::StatusItemTuple> Interface::GetStatusSince(int64_t changeIdentifier)\r\n    {\r\n        StatusItemTable statusItemTable(*m_storage);\r\n        return statusItemTable.GetStatusSince(changeIdentifier);\r\n    }\r\n\r\n    std::tuple<int64_t, std::vector<IConfigurationDatabase::StatusItemTuple>> Interface::GetStatusBaseline()\r\n    {\r\n        StatusItemTable statusItemTable(*m_storage);\r\n        return statusItemTable.GetStatusBaseline();\r\n    }\r\n\r\n    void Interface::AddListener(const std::string& objectName)\r\n    {\r\n        ChangeListenerTable changeListenerTable(*m_storage);\r\n        changeListenerTable.AddChangeListener(objectName);\r\n    }\r\n\r\n    void Interface::RemoveListener(const std::string& objectName)\r\n    {\r\n        ChangeListenerTable changeListenerTable(*m_storage);\r\n        changeListenerTable.RemoveChangeListener(objectName);\r\n    }\r\n\r\n    std::vector<std::tuple<std::string, std::chrono::system_clock::time_point, DWORD>> Interface::GetChangeListeners()\r\n    {\r\n        ChangeListenerTable changeListenerTable(*m_storage);\r\n        return changeListenerTable.GetChangeListeners();\r\n    }\r\n\r\n    void Interface::UpdateSetState(const guid& setInstanceIdentifier, ConfigurationSetState state)\r\n    {\r\n        StatusItemTable statusItemTable(*m_storage);\r\n        statusItemTable.UpdateSetState(setInstanceIdentifier, state);\r\n    }\r\n\r\n    void Interface::UpdateSetInQueue(const guid& setInstanceIdentifier, bool inQueue)\r\n    {\r\n        StatusItemTable statusItemTable(*m_storage);\r\n        statusItemTable.UpdateSetInQueue(setInstanceIdentifier, inQueue);\r\n    }\r\n\r\n    void Interface::UpdateUnitState(const guid& setInstanceIdentifier, const ConfigurationSetChangeDataPtr& changeData)\r\n    {\r\n        StatusItemTable statusItemTable(*m_storage);\r\n        statusItemTable.UpdateUnitState(setInstanceIdentifier, changeData);\r\n    }\r\n\r\n    ConfigurationSetState Interface::GetSetState(const guid& instanceIdentifier)\r\n    {\r\n        StatusItemTable statusItemTable(*m_storage);\r\n        return statusItemTable.GetSetState(instanceIdentifier);\r\n    }\r\n\r\n    std::chrono::system_clock::time_point Interface::GetSetFirstApply(const guid& instanceIdentifier)\r\n    {\r\n        V0_1::SetInfoTable setInfoTable(*m_storage);\r\n        return setInfoTable.GetSetFirstApply(instanceIdentifier);\r\n    }\r\n\r\n    std::chrono::system_clock::time_point Interface::GetSetApplyBegun(const guid& instanceIdentifier)\r\n    {\r\n        StatusItemTable statusItemTable(*m_storage);\r\n        return statusItemTable.GetSetApplyBegun(instanceIdentifier);\r\n    }\r\n\r\n    std::chrono::system_clock::time_point Interface::GetSetApplyEnded(const guid& instanceIdentifier)\r\n    {\r\n        StatusItemTable statusItemTable(*m_storage);\r\n        return statusItemTable.GetSetApplyEnded(instanceIdentifier);\r\n    }\r\n\r\n    ConfigurationUnitState Interface::GetUnitState(const guid& instanceIdentifier)\r\n    {\r\n        StatusItemTable statusItemTable(*m_storage);\r\n        return statusItemTable.GetUnitState(instanceIdentifier);\r\n    }\r\n\r\n    std::optional<std::tuple<HRESULT, std::string, std::string, ConfigurationUnitResultSource>> Interface::GetUnitResultInformation(const guid& instanceIdentifier)\r\n    {\r\n        StatusItemTable statusItemTable(*m_storage);\r\n        return statusItemTable.GetUnitResultInformation(instanceIdentifier);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Database/Schema/0_3/StatusItemTable.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"StatusItemTable.h\"\r\n#include \"Database/Schema/0_1/SetInfoTable.h\"\r\n#include <AppInstallerDateTime.h>\r\n#include <AppInstallerLanguageUtilities.h>\r\n#include <AppInstallerStrings.h>\r\n#include <winget/SQLiteStatementBuilder.h>\r\n\r\nusing namespace AppInstaller::SQLite;\r\nusing namespace AppInstaller::SQLite::Builder;\r\nusing namespace AppInstaller::Utility;\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation::Database::Schema::V0_3\r\n{\r\n    namespace\r\n    {\r\n        constexpr std::string_view s_StatusItemTable_Table = \"status_items\"sv;\r\n        constexpr std::string_view s_StatusItemTable_ChangeIdentifierIndex = \"status_items_change_idx\"sv;\r\n        constexpr std::string_view s_StatusItemTable_SetRowIdIndex = \"status_items_set_idx\"sv;\r\n        constexpr std::string_view s_StatusItemTable_UnitInstanceIndex = \"status_items_unit_idx\"sv;\r\n\r\n        constexpr std::string_view s_StatusItemTable_Column_ChangeIdentifier = \"change_identifier\"sv;\r\n        constexpr std::string_view s_StatusItemTable_Column_ChangeTimeInitial = \"change_time_initial\"sv;\r\n        constexpr std::string_view s_StatusItemTable_Column_ChangeTimeLatest = \"change_time_latest\"sv;\r\n        constexpr std::string_view s_StatusItemTable_Column_SetRowId = \"set_rowid\"sv;\r\n        constexpr std::string_view s_StatusItemTable_Column_InQueue = \"in_queue\"sv;\r\n        constexpr std::string_view s_StatusItemTable_Column_UnitInstanceIdentifier = \"unit_instance_identifier\"sv;\r\n        constexpr std::string_view s_StatusItemTable_Column_State = \"state\"sv;\r\n        constexpr std::string_view s_StatusItemTable_Column_ResultCode = \"result_code\"sv;\r\n        constexpr std::string_view s_StatusItemTable_Column_ResultDescription = \"result_description\"sv;\r\n        constexpr std::string_view s_StatusItemTable_Column_ResultDetails = \"result_details\"sv;\r\n        constexpr std::string_view s_StatusItemTable_Column_ResultSource = \"result_source\"sv;\r\n\r\n        void BuildBaseStatusSelectStatement(StatementBuilder& builder)\r\n        {\r\n            builder.Select({\r\n                s_StatusItemTable_Column_ChangeIdentifier,          // 0\r\n                s_StatusItemTable_Column_ChangeTimeLatest,          // 1\r\n                V0_1::SetInfoTable::InstanceIdentifierColumn(),     // 2\r\n                s_StatusItemTable_Column_InQueue,                   // 3\r\n                s_StatusItemTable_Column_UnitInstanceIdentifier,    // 4\r\n                s_StatusItemTable_Column_State,                     // 5\r\n                s_StatusItemTable_Column_ResultCode,                // 6\r\n                s_StatusItemTable_Column_ResultDescription,         // 7\r\n                s_StatusItemTable_Column_ResultDetails,             // 8\r\n                s_StatusItemTable_Column_ResultSource,              // 9\r\n            }).From(s_StatusItemTable_Table).LeftOuterJoin(V0_1::SetInfoTable::TableName()).On(QualifiedColumn{ s_StatusItemTable_Table, s_StatusItemTable_Column_SetRowId }, QualifiedColumn{ V0_1::SetInfoTable::TableName(), RowIDName });\r\n        }\r\n\r\n        IConfigurationDatabase::StatusItemTuple GetTupleFromStatement(Statement& statement)\r\n        {\r\n            return std::make_tuple(\r\n                statement.GetColumn<int64_t>(0),\r\n                ConvertUnixEpochToSystemClock(statement.GetColumn<int64_t>(1)),\r\n                statement.GetColumn<GUID>(2),\r\n                statement.GetColumn<bool>(3),\r\n                statement.GetColumnIsNull(4) ? std::nullopt : std::make_optional<GUID>(statement.GetColumn<GUID>(4)),\r\n                statement.GetColumn<int32_t>(5),\r\n                statement.GetColumnIsNull(6) ? std::nullopt : std::make_optional<HRESULT>(statement.GetColumn<int32_t>(6)),\r\n                statement.GetColumnIsNull(7) ? std::string{} : statement.GetColumn<std::string>(7),\r\n                statement.GetColumnIsNull(8) ? std::string{} : statement.GetColumn<std::string>(8),\r\n                statement.GetColumnIsNull(9) ? ConfigurationUnitResultSource::None : statement.GetColumn<ConfigurationUnitResultSource>(9)\r\n            );\r\n        }\r\n\r\n        int64_t GetLatestChangeIdentifier(Connection& connection)\r\n        {\r\n            StatementBuilder getLatestChangeBuilder;\r\n            getLatestChangeBuilder.Select().Column(Aggregate::Max, s_StatusItemTable_Column_ChangeIdentifier).From(s_StatusItemTable_Table);\r\n\r\n            Statement getLatestChange = getLatestChangeBuilder.Prepare(connection);\r\n\r\n            return (getLatestChange.Step() ? getLatestChange.GetColumn<int64_t>(0) : 0);\r\n        }\r\n\r\n        int64_t GetNextChangeIdentifier(Connection& connection)\r\n        {\r\n            return GetLatestChangeIdentifier(connection) + 1;\r\n        }\r\n\r\n        void UpdateStatus(\r\n            Connection& connection,\r\n            const GUID& setInstanceIdentifier,\r\n            const std::optional<int32_t>& state,\r\n            const std::optional<bool>& inQueue,\r\n            const std::optional<GUID>& unitInstanceIdentifier = std::nullopt,\r\n            const std::optional<int32_t>& resultCode = std::nullopt,\r\n            const std::optional<std::string>& resultDescription = std::nullopt,\r\n            const std::optional<std::string>& resultDetails = std::nullopt,\r\n            const std::optional<ConfigurationUnitResultSource>& resultSource = std::nullopt)\r\n        {\r\n            static constexpr std::string_view s_alias = \"sub_expression\";\r\n\r\n            int64_t changeIdentifier = GetNextChangeIdentifier(connection);\r\n            int64_t changeTime = GetCurrentUnixEpoch();\r\n\r\n            // Statement like:\r\n            // Update status_items set state = 1 from (Select rowid from set_info where instance_identifier = \"foo\") as sub where status_items.set_rowid = sub.rowid\r\n            StatementBuilder updateBuilder;\r\n            updateBuilder.Update(s_StatusItemTable_Table).Set();\r\n\r\n            if (state)\r\n            {\r\n                updateBuilder.Column(s_StatusItemTable_Column_State).Equals(state.value());\r\n            }\r\n\r\n            if (inQueue)\r\n            {\r\n                updateBuilder.Column(s_StatusItemTable_Column_InQueue).Equals(inQueue.value());\r\n            }\r\n\r\n            if (resultCode)\r\n            {\r\n                updateBuilder.Column(s_StatusItemTable_Column_ResultCode).Equals(resultCode.value());\r\n            }\r\n\r\n            if (resultDescription)\r\n            {\r\n                updateBuilder.Column(s_StatusItemTable_Column_ResultDescription).Equals(resultDescription.value());\r\n            }\r\n\r\n            if (resultDetails)\r\n            {\r\n                updateBuilder.Column(s_StatusItemTable_Column_ResultDetails).Equals(resultDetails.value());\r\n            }\r\n\r\n            if (resultSource)\r\n            {\r\n                updateBuilder.Column(s_StatusItemTable_Column_ResultSource).Equals(resultSource.value());\r\n            }\r\n\r\n            updateBuilder.\r\n                Column(s_StatusItemTable_Column_ChangeIdentifier).Equals(changeIdentifier).\r\n                Column(s_StatusItemTable_Column_ChangeTimeLatest).Equals(changeTime).\r\n            From().BeginParenthetical().\r\n                Select(RowIDName).From(V0_1::SetInfoTable::TableName()).Where(V0_1::SetInfoTable::InstanceIdentifierColumn()).Equals(setInstanceIdentifier).\r\n            EndParenthetical().As(s_alias).Where(QualifiedColumn{ s_StatusItemTable_Table, s_StatusItemTable_Column_SetRowId }).Equals(QualifiedColumn{ s_alias, RowIDName }).\r\n                And(QualifiedColumn{ s_StatusItemTable_Table, s_StatusItemTable_Column_UnitInstanceIdentifier }).Equals(unitInstanceIdentifier);\r\n\r\n            updateBuilder.Execute(connection);\r\n\r\n            if (connection.GetChanges() == 0)\r\n            {\r\n                // No change; we need to insert the status row\r\n                StatementBuilder insertBuilder;\r\n                insertBuilder.InsertInto(s_StatusItemTable_Table).Columns({\r\n                    s_StatusItemTable_Column_ChangeIdentifier,\r\n                    s_StatusItemTable_Column_ChangeTimeInitial,\r\n                    s_StatusItemTable_Column_ChangeTimeLatest,\r\n                    s_StatusItemTable_Column_SetRowId,\r\n                    s_StatusItemTable_Column_InQueue,\r\n                    s_StatusItemTable_Column_UnitInstanceIdentifier,\r\n                    s_StatusItemTable_Column_State,\r\n                    s_StatusItemTable_Column_ResultCode,\r\n                    s_StatusItemTable_Column_ResultDescription,\r\n                    s_StatusItemTable_Column_ResultDetails,\r\n                    s_StatusItemTable_Column_ResultSource,\r\n                }).Select().\r\n                    Value(changeIdentifier).\r\n                    Value(changeTime).\r\n                    Value(changeTime).\r\n                    Column(QualifiedColumn{ V0_1::SetInfoTable::TableName(), RowIDName }).\r\n                    Value(inQueue.value_or(false)).\r\n                    Value(unitInstanceIdentifier).\r\n                    Value(state.value_or(0)).\r\n                    Value(resultCode).\r\n                    Value(resultDescription).\r\n                    Value(resultDetails).\r\n                    Value(resultSource).\r\n                From(V0_1::SetInfoTable::TableName()).Where(QualifiedColumn{ V0_1::SetInfoTable::TableName(), V0_1::SetInfoTable::InstanceIdentifierColumn() }).Equals(setInstanceIdentifier);\r\n\r\n                insertBuilder.Execute(connection);\r\n            }\r\n        }\r\n\r\n        Statement PrepareSelectStatusValues(Connection& connection, const std::optional<GUID>& setInstanceIdentifier, const std::optional<GUID>& unitInstanceIdentifier, std::initializer_list<std::string_view> columns)\r\n        {\r\n            THROW_HR_IF(E_INVALIDARG, (setInstanceIdentifier && unitInstanceIdentifier) || (!setInstanceIdentifier && !unitInstanceIdentifier));\r\n\r\n            StatementBuilder builder;\r\n            builder.Select(columns).From(s_StatusItemTable_Table);\r\n\r\n            if (setInstanceIdentifier)\r\n            {\r\n                builder.Join(V0_1::SetInfoTable::TableName()).On(QualifiedColumn{ s_StatusItemTable_Table, s_StatusItemTable_Column_SetRowId }, QualifiedColumn{ V0_1::SetInfoTable::TableName(), RowIDName }).\r\n                    Where(QualifiedColumn{ V0_1::SetInfoTable::TableName(), V0_1::SetInfoTable::InstanceIdentifierColumn() }).Equals(setInstanceIdentifier).\r\n                    And(s_StatusItemTable_Column_UnitInstanceIdentifier).IsNull();\r\n            }\r\n            else\r\n            {\r\n                builder.Where(s_StatusItemTable_Column_UnitInstanceIdentifier).Equals(unitInstanceIdentifier.value());\r\n            }\r\n\r\n            return builder.Prepare(connection);\r\n        }\r\n    }\r\n\r\n    StatusItemTable::StatusItemTable(Connection& connection) : m_connection(connection) {}\r\n\r\n    void StatusItemTable::Create()\r\n    {\r\n        Savepoint savepoint = Savepoint::Create(m_connection, \"StatusItemTable_Create_0_3\");\r\n\r\n        StatementBuilder tableBuilder;\r\n        tableBuilder.CreateTable(s_StatusItemTable_Table).Columns({\r\n            IntegerPrimaryKey(),\r\n            ColumnBuilder(s_StatusItemTable_Column_ChangeIdentifier, Type::Int64).NotNull(),\r\n            ColumnBuilder(s_StatusItemTable_Column_ChangeTimeInitial, Type::Int64).NotNull(),\r\n            ColumnBuilder(s_StatusItemTable_Column_ChangeTimeLatest, Type::Int64).NotNull(),\r\n            ColumnBuilder(s_StatusItemTable_Column_SetRowId, Type::RowId).NotNull(),\r\n            ColumnBuilder(s_StatusItemTable_Column_InQueue, Type::Bool).NotNull(),\r\n            ColumnBuilder(s_StatusItemTable_Column_UnitInstanceIdentifier, Type::Blob),\r\n            ColumnBuilder(s_StatusItemTable_Column_State, Type::Int).NotNull(),\r\n            ColumnBuilder(s_StatusItemTable_Column_ResultCode, Type::Int),\r\n            ColumnBuilder(s_StatusItemTable_Column_ResultDescription, Type::Text),\r\n            ColumnBuilder(s_StatusItemTable_Column_ResultDetails, Type::Text),\r\n            ColumnBuilder(s_StatusItemTable_Column_ResultSource, Type::Int),\r\n        });\r\n\r\n        tableBuilder.Execute(m_connection);\r\n\r\n        {\r\n            StatementBuilder indexBuilder;\r\n            indexBuilder.CreateIndex(s_StatusItemTable_ChangeIdentifierIndex).On(s_StatusItemTable_Table).Columns(s_StatusItemTable_Column_ChangeIdentifier);\r\n            indexBuilder.Execute(m_connection);\r\n        }\r\n\r\n        {\r\n            StatementBuilder indexBuilder;\r\n            indexBuilder.CreateIndex(s_StatusItemTable_SetRowIdIndex).On(s_StatusItemTable_Table).Columns(s_StatusItemTable_Column_SetRowId);\r\n            indexBuilder.Execute(m_connection);\r\n        }\r\n\r\n        {\r\n            StatementBuilder indexBuilder;\r\n            indexBuilder.CreateUniqueIndex(s_StatusItemTable_UnitInstanceIndex).On(s_StatusItemTable_Table).Columns(s_StatusItemTable_Column_UnitInstanceIdentifier);\r\n            indexBuilder.Execute(m_connection);\r\n        }\r\n\r\n        savepoint.Commit();\r\n    }\r\n\r\n    void StatusItemTable::RemoveForSet(AppInstaller::SQLite::rowid_t target)\r\n    {\r\n        StatementBuilder builder;\r\n        builder.DeleteFrom(s_StatusItemTable_Table).Where(s_StatusItemTable_Column_SetRowId).Equals(target);\r\n        builder.Execute(m_connection);\r\n    }\r\n\r\n    std::vector<IConfigurationDatabase::StatusItemTuple> StatusItemTable::GetStatusSince(int64_t changeIdentifier)\r\n    {\r\n        StatementBuilder builder;\r\n        BuildBaseStatusSelectStatement(builder);\r\n        builder.Where(s_StatusItemTable_Column_ChangeIdentifier).IsGreaterThan(changeIdentifier).OrderBy(s_StatusItemTable_Column_ChangeIdentifier);\r\n\r\n        Statement statement = builder.Prepare(m_connection);\r\n\r\n        std::vector<IConfigurationDatabase::StatusItemTuple> result;\r\n\r\n        while (statement.Step())\r\n        {\r\n            result.emplace_back(GetTupleFromStatement(statement));\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    std::tuple<int64_t, std::vector<IConfigurationDatabase::StatusItemTuple>> StatusItemTable::GetStatusBaseline()\r\n    {\r\n        int64_t latestChange = GetLatestChangeIdentifier(m_connection);\r\n        std::vector<IConfigurationDatabase::StatusItemTuple> setStatus;\r\n\r\n        StatementBuilder builder;\r\n        BuildBaseStatusSelectStatement(builder);\r\n        builder.Where(s_StatusItemTable_Column_UnitInstanceIdentifier).IsNull();\r\n\r\n        Statement statement = builder.Prepare(m_connection);\r\n\r\n        while (statement.Step())\r\n        {\r\n            setStatus.emplace_back(GetTupleFromStatement(statement));\r\n        }\r\n\r\n        return std::make_tuple(latestChange, std::move(setStatus));\r\n    }\r\n\r\n    void StatusItemTable::UpdateSetState(const guid& setInstanceIdentifier, ConfigurationSetState state)\r\n    {\r\n        UpdateStatus(m_connection, setInstanceIdentifier, AppInstaller::ToIntegral(state), std::nullopt);\r\n    }\r\n\r\n    void StatusItemTable::UpdateSetInQueue(const guid& setInstanceIdentifier, bool inQueue)\r\n    {\r\n        UpdateStatus(m_connection, setInstanceIdentifier, std::nullopt, inQueue);\r\n    }\r\n\r\n    void StatusItemTable::UpdateUnitState(const guid& setInstanceIdentifier, const IConfigurationDatabase::ConfigurationSetChangeDataPtr& changeData)\r\n    {\r\n        const auto& resultInformation = changeData->ResultInformation();\r\n\r\n        std::optional<HRESULT> resultCode;\r\n        std::optional<std::string> resultDescription;\r\n        std::optional<std::string> resultDetails;\r\n        std::optional<ConfigurationUnitResultSource> resultSource;\r\n\r\n        if (resultInformation)\r\n        {\r\n            resultCode = resultInformation.ResultCode();\r\n            resultDescription = ConvertToUTF8(resultInformation.Description());\r\n            resultDetails = ConvertToUTF8(resultInformation.Details());\r\n            resultSource = resultInformation.ResultSource();\r\n        }\r\n\r\n        UpdateStatus(m_connection, setInstanceIdentifier, AppInstaller::ToIntegral(changeData->UnitState()), std::nullopt, changeData->Unit().InstanceIdentifier(), resultCode, resultDescription, resultDetails, resultSource);\r\n    }\r\n\r\n    ConfigurationSetState StatusItemTable::GetSetState(const guid& instanceIdentifier)\r\n    {\r\n        Statement statement = PrepareSelectStatusValues(m_connection, instanceIdentifier, std::nullopt, { s_StatusItemTable_Column_State });\r\n\r\n        return (statement.Step() ? statement.GetColumn<ConfigurationSetState>(0) : ConfigurationSetState::Unknown);\r\n    }\r\n\r\n    std::chrono::system_clock::time_point StatusItemTable::GetSetApplyBegun(const GUID& instanceIdentifier)\r\n    {\r\n        Statement statement = PrepareSelectStatusValues(m_connection, instanceIdentifier, std::nullopt, { s_StatusItemTable_Column_ChangeTimeInitial });\r\n\r\n        return (statement.Step() ? ConvertUnixEpochToSystemClock(statement.GetColumn<int64_t>(0)) : std::chrono::system_clock::time_point{});\r\n    }\r\n\r\n    std::chrono::system_clock::time_point StatusItemTable::GetSetApplyEnded(const GUID& instanceIdentifier)\r\n    {\r\n        Statement statement = PrepareSelectStatusValues(m_connection, instanceIdentifier, std::nullopt, { s_StatusItemTable_Column_ChangeTimeLatest, s_StatusItemTable_Column_InQueue });\r\n\r\n        // Only return the end time if no longer in the queue\r\n        if (statement.Step() && !statement.GetColumn<bool>(1))\r\n        {\r\n            return ConvertUnixEpochToSystemClock(statement.GetColumn<int64_t>(0));\r\n        }\r\n\r\n        return std::chrono::system_clock::time_point{};\r\n    }\r\n\r\n    ConfigurationUnitState StatusItemTable::GetUnitState(const guid& instanceIdentifier)\r\n    {\r\n        Statement statement = PrepareSelectStatusValues(m_connection, std::nullopt, instanceIdentifier, { s_StatusItemTable_Column_State });\r\n\r\n        return (statement.Step() ? statement.GetColumn<ConfigurationUnitState>(0) : ConfigurationUnitState::Unknown);\r\n    }\r\n\r\n    std::optional<std::tuple<HRESULT, std::string, std::string, ConfigurationUnitResultSource>> StatusItemTable::GetUnitResultInformation(const guid& instanceIdentifier)\r\n    {\r\n        Statement statement = PrepareSelectStatusValues(m_connection, std::nullopt, instanceIdentifier,\r\n            { s_StatusItemTable_Column_ResultCode, s_StatusItemTable_Column_ResultDescription, s_StatusItemTable_Column_ResultDetails, s_StatusItemTable_Column_ResultSource });\r\n\r\n        if (statement.Step() && !statement.GetColumnIsNull(0))\r\n        {\r\n            return statement.GetRow<int32_t, std::string, std::string, ConfigurationUnitResultSource>();\r\n        }\r\n\r\n        return std::nullopt;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Database/Schema/0_3/StatusItemTable.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Database/Schema/IConfigurationDatabase.h\"\r\n#include <winget/SQLiteWrapper.h>\r\n#include <vector>\r\n#include <tuple>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation::Database::Schema::V0_3\r\n{\r\n    struct StatusItemTable\r\n    {\r\n        StatusItemTable(AppInstaller::SQLite::Connection& connection);\r\n\r\n        // Creates the table.\r\n        void Create();\r\n\r\n        // Removes the status for the target set.\r\n        void RemoveForSet(AppInstaller::SQLite::rowid_t target);\r\n\r\n        // Gets all status items that have changed since the given change identifier, in order of changes (last item is the new latest change to pass next).\r\n        std::vector<IConfigurationDatabase::StatusItemTuple> GetStatusSince(int64_t changeIdentifier);\r\n\r\n        // Gets the latest change identifier and the set status items.\r\n        std::tuple<int64_t, std::vector<IConfigurationDatabase::StatusItemTuple>> GetStatusBaseline();\r\n\r\n        // Updates a set's state.\r\n        void UpdateSetState(const guid& setInstanceIdentifier, ConfigurationSetState state);\r\n\r\n        // Updates whether a set is in the queue or not.\r\n        void UpdateSetInQueue(const guid& setInstanceIdentifier, bool inQueue);\r\n\r\n        // Updates a unit's state.\r\n        void UpdateUnitState(const guid& setInstanceIdentifier, const IConfigurationDatabase::ConfigurationSetChangeDataPtr& changeData);\r\n\r\n        // Gets a set's state.\r\n        ConfigurationSetState GetSetState(const guid& instanceIdentifier);\r\n\r\n        // Gets a set's latest apply begin time.\r\n        std::chrono::system_clock::time_point GetSetApplyBegun(const GUID& instanceIdentifier);\r\n\r\n        // Gets a set's latest apply end time.\r\n        std::chrono::system_clock::time_point GetSetApplyEnded(const GUID& instanceIdentifier);\r\n\r\n        // Gets a unit's state.\r\n        ConfigurationUnitState GetUnitState(const guid& instanceIdentifier);\r\n\r\n        // Gets a unit's latest result information.\r\n        std::optional<std::tuple<HRESULT, std::string, std::string, ConfigurationUnitResultSource>> GetUnitResultInformation(const guid& instanceIdentifier);\r\n\r\n    private:\r\n        AppInstaller::SQLite::Connection& m_connection;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Database/Schema/IConfigurationDatabase.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Database/Schema/IConfigurationDatabase.h\"\r\n\r\n#include \"Database/Schema/0_1/Interface.h\"\r\n#include \"Database/Schema/0_2/Interface.h\"\r\n#include \"Database/Schema/0_3/Interface.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    namespace\r\n    {\r\n        std::unique_ptr<IConfigurationDatabase> CreateForVersion(const AppInstaller::SQLite::Version& version, const std::shared_ptr<AppInstaller::SQLite::SQLiteDynamicStorage>& storage)\r\n        {\r\n            using StorageT = std::shared_ptr<AppInstaller::SQLite::SQLiteDynamicStorage>;\r\n\r\n            if (version.MajorVersion == 0)\r\n            {\r\n                constexpr std::array<std::unique_ptr<IConfigurationDatabase>(*)(const StorageT& s), 3> versionCreatorMap =\r\n                {\r\n                    [](const StorageT& s) { return std::unique_ptr<IConfigurationDatabase>(std::make_unique<Database::Schema::V0_1::Interface>(s)); },\r\n                    [](const StorageT& s) { return std::unique_ptr<IConfigurationDatabase>(std::make_unique<Database::Schema::V0_2::Interface>(s)); },\r\n                    [](const StorageT& s) { return std::unique_ptr<IConfigurationDatabase>(std::make_unique<Database::Schema::V0_3::Interface>(s)); },\r\n                };\r\n\r\n                size_t minorVersion = static_cast<size_t>(version.MinorVersion);\r\n                if (minorVersion >= 1 && minorVersion <= versionCreatorMap.size())\r\n                {\r\n                    return versionCreatorMap[minorVersion - 1](storage);\r\n                }\r\n            }\r\n\r\n            // We do not have the capacity to operate on this schema version\r\n            THROW_WIN32(ERROR_NOT_SUPPORTED);\r\n        }\r\n    }\r\n\r\n    AppInstaller::SQLite::Version IConfigurationDatabase::GetLatestVersion()\r\n    {\r\n        return { 0, 3 };\r\n    }\r\n\r\n    std::unique_ptr<IConfigurationDatabase> IConfigurationDatabase::CreateFor(const std::shared_ptr<AppInstaller::SQLite::SQLiteDynamicStorage>& storage, bool allowMigration)\r\n    {\r\n        using StorageT = std::shared_ptr<AppInstaller::SQLite::SQLiteDynamicStorage>;\r\n        const AppInstaller::SQLite::Version& version = storage->GetVersion();\r\n\r\n        std::unique_ptr<IConfigurationDatabase> result = CreateForVersion(version, storage);\r\n\r\n        AppInstaller::SQLite::Version latestVersion = GetLatestVersion();\r\n        if (allowMigration && version < latestVersion)\r\n        {\r\n            // Always migrate to the latest version until a reason comes along to not do that\r\n            std::unique_ptr<IConfigurationDatabase> latest = CreateForVersion(latestVersion, storage);\r\n            THROW_WIN32_IF(ERROR_NOT_SUPPORTED, !latest->MigrateFrom(result.get()));\r\n            result = std::move(latest);\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    void IConfigurationDatabase::AddQueueItem(const GUID&, const std::string&)\r\n    {\r\n    }\r\n\r\n    void IConfigurationDatabase::SetActiveQueueItem(const std::string&)\r\n    {\r\n    }\r\n\r\n    std::vector<std::tuple<GUID, std::string, std::chrono::system_clock::time_point, DWORD, bool>> IConfigurationDatabase::GetQueueItems()\r\n    {\r\n        return {};\r\n    }\r\n\r\n    void IConfigurationDatabase::RemoveQueueItem(const std::string&)\r\n    {\r\n    }\r\n\r\n    std::vector<IConfigurationDatabase::StatusItemTuple> IConfigurationDatabase::GetStatusSince(int64_t)\r\n    {\r\n        return {};\r\n    }\r\n\r\n    std::tuple<int64_t, std::vector<IConfigurationDatabase::StatusItemTuple>> IConfigurationDatabase::GetStatusBaseline()\r\n    {\r\n        return { 0, {} };\r\n    }\r\n\r\n    void IConfigurationDatabase::AddListener(const std::string&)\r\n    {\r\n    }\r\n\r\n    void IConfigurationDatabase::RemoveListener(const std::string&)\r\n    {\r\n    }\r\n\r\n    std::vector<std::tuple<std::string, std::chrono::system_clock::time_point, DWORD>> IConfigurationDatabase::GetChangeListeners()\r\n    {\r\n        return {};\r\n    }\r\n\r\n    void IConfigurationDatabase::UpdateSetState(const guid&, ConfigurationSetState)\r\n    {\r\n    }\r\n\r\n    void IConfigurationDatabase::UpdateSetInQueue(const guid&, bool)\r\n    {\r\n    }\r\n\r\n    void IConfigurationDatabase::UpdateUnitState(const guid&, const ConfigurationSetChangeDataPtr&)\r\n    {\r\n    }\r\n\r\n    ConfigurationSetState IConfigurationDatabase::GetSetState(const guid&)\r\n    {\r\n        return ConfigurationSetState::Unknown;\r\n    }\r\n\r\n    std::chrono::system_clock::time_point IConfigurationDatabase::GetSetFirstApply(const guid&)\r\n    {\r\n        return {};\r\n    }\r\n\r\n    std::chrono::system_clock::time_point IConfigurationDatabase::GetSetApplyBegun(const guid&)\r\n    {\r\n        return {};\r\n    }\r\n\r\n    std::chrono::system_clock::time_point IConfigurationDatabase::GetSetApplyEnded(const guid&)\r\n    {\r\n        return {};\r\n    }\r\n\r\n    ConfigurationUnitState IConfigurationDatabase::GetUnitState(const guid&)\r\n    {\r\n        return ConfigurationUnitState::Unknown;\r\n    }\r\n\r\n    std::optional<std::tuple<HRESULT, std::string, std::string, ConfigurationUnitResultSource>> IConfigurationDatabase::GetUnitResultInformation(const guid&)\r\n    {\r\n        return std::nullopt;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Database/Schema/IConfigurationDatabase.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"winrt/Microsoft.Management.Configuration.h\"\r\n#include \"ConfigurationSet.h\"\r\n#include \"ConfigurationUnit.h\"\r\n#include \"ConfigurationSetChangeData.h\"\r\n#include <winget/SQLiteVersion.h>\r\n#include <winget/SQLiteDynamicStorage.h>\r\n#include <wil/cppwinrt_wrl.h>\r\n#include <memory>\r\n#include <tuple>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    // Interface for interacting with the configuration database.\r\n    struct IConfigurationDatabase\r\n    {\r\n        using ConfigurationSetPtr = winrt::com_ptr<implementation::ConfigurationSet>;\r\n        using ConfigurationUnitPtr = winrt::com_ptr<implementation::ConfigurationUnit>;\r\n        using ConfigurationSetChangeDataPtr = winrt::com_ptr<implementation::ConfigurationSetChangeData>;\r\n\r\n        virtual ~IConfigurationDatabase() = default;\r\n\r\n        // Gets the latest schema version for the configuration database.\r\n        static AppInstaller::SQLite::Version GetLatestVersion();\r\n\r\n        // Creates the version appropriate database object for the given storage.\r\n        static std::unique_ptr<IConfigurationDatabase> CreateFor(const std::shared_ptr<AppInstaller::SQLite::SQLiteDynamicStorage>& storage, bool allowMigration = false);\r\n\r\n        // Gets the schema version from the current interface.\r\n        virtual const AppInstaller::SQLite::Version& GetSchemaVersion() = 0;\r\n\r\n        // Version 0.1\r\n\r\n        // Acts on a database that has been created but contains no tables beyond metadata.\r\n        virtual void InitializeDatabase() = 0;\r\n\r\n        // Adds the given set to the database.\r\n        virtual void AddSet(const Configuration::ConfigurationSet& configurationSet) = 0;\r\n\r\n        // Updates the set with the given row id using the given set.\r\n        virtual void UpdateSet(AppInstaller::SQLite::rowid_t target, const Configuration::ConfigurationSet& configurationSet) = 0;\r\n\r\n        // Removes the set with the given row id from the database.\r\n        virtual void RemoveSet(AppInstaller::SQLite::rowid_t target) = 0;\r\n\r\n        // Gets all of the sets in the database.\r\n        virtual std::vector<ConfigurationSetPtr> GetSets() = 0;\r\n\r\n        // Gets the row id of the set with the given instance identifier, if present.\r\n        virtual std::optional<AppInstaller::SQLite::rowid_t> GetSetRowId(const GUID& instanceIdentifier) = 0;\r\n\r\n        // Version 0.2\r\n\r\n        // Migrates from the current interface given.\r\n        // Returns true if supported (or is already same schema version); false if not.\r\n        // Throws on errors that occur during an attempted migration.\r\n        virtual bool MigrateFrom(IConfigurationDatabase* current) = 0;\r\n\r\n        // Adds a new queue item for the given configuration set and object name.\r\n        virtual void AddQueueItem(const GUID& instanceIdentifier, const std::string& objectName);\r\n\r\n        // Sets the queue item with the given object name as active.\r\n        virtual void SetActiveQueueItem(const std::string& objectName);\r\n\r\n        // Gets all queue items in queue order (item at index 0 is active/next).\r\n        virtual std::vector<std::tuple<GUID, std::string, std::chrono::system_clock::time_point, DWORD, bool>> GetQueueItems();\r\n\r\n        // Removes the queue item with the given object name.\r\n        virtual void RemoveQueueItem(const std::string& objectName);\r\n\r\n        // Version 0.3\r\n\r\n        // Gets a set from the database.\r\n        virtual ConfigurationSetPtr GetSet(const GUID& instanceIdentifier) = 0;\r\n\r\n        // The tuple returned for status items.\r\n        using StatusItemTuple = std::tuple<\r\n            int64_t,\r\n            std::chrono::system_clock::time_point,\r\n            GUID,\r\n            bool,\r\n            std::optional<GUID>,\r\n            int32_t,\r\n            std::optional<HRESULT>,\r\n            std::string,\r\n            std::string,\r\n            ConfigurationUnitResultSource>;\r\n\r\n        // Gets all status items that have changed since the given change identifier, in order of changes (last item is the new latest change to pass next).\r\n        virtual std::vector<StatusItemTuple> GetStatusSince(int64_t changeIdentifier);\r\n\r\n        // Gets the latest change identifier and the set status items.\r\n        virtual std::tuple<int64_t, std::vector<StatusItemTuple>> GetStatusBaseline();\r\n\r\n        // Adds a new listener to the database.\r\n        virtual void AddListener(const std::string& objectName);\r\n\r\n        // Removes a listener from the database.\r\n        virtual void RemoveListener(const std::string& objectName);\r\n\r\n        // Gets all of the change listeners in the database.\r\n        virtual std::vector<std::tuple<std::string, std::chrono::system_clock::time_point, DWORD>> GetChangeListeners();\r\n\r\n        // Updates a set's state.\r\n        virtual void UpdateSetState(const guid& setInstanceIdentifier, ConfigurationSetState state);\r\n\r\n        // Updates whether a set is in the queue or not.\r\n        virtual void UpdateSetInQueue(const guid& setInstanceIdentifier, bool inQueue);\r\n\r\n        // Updates a unit's state.\r\n        virtual void UpdateUnitState(const guid& setInstanceIdentifier, const ConfigurationSetChangeDataPtr& changeData);\r\n\r\n        // Gets a set's state.\r\n        virtual ConfigurationSetState GetSetState(const guid& instanceIdentifier);\r\n\r\n        // Gets a set's first apply time.\r\n        virtual std::chrono::system_clock::time_point GetSetFirstApply(const guid& instanceIdentifier);\r\n\r\n        // Gets a set's latest apply begin time.\r\n        virtual std::chrono::system_clock::time_point GetSetApplyBegun(const guid& instanceIdentifier);\r\n\r\n        // Gets a set's latest apply end time.\r\n        virtual std::chrono::system_clock::time_point GetSetApplyEnded(const guid& instanceIdentifier);\r\n\r\n        // Gets a unit's state.\r\n        virtual ConfigurationUnitState GetUnitState(const guid& instanceIdentifier);\r\n\r\n        // Gets a unit's latest result information.\r\n        virtual std::optional<std::tuple<HRESULT, std::string, std::string, ConfigurationUnitResultSource>> GetUnitResultInformation(const guid& instanceIdentifier);\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/DefaultSetGroupProcessor.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"DefaultSetGroupProcessor.h\"\r\n#include \"ConfigurationSetApplyProcessor.h\"\r\n#include \"ExceptionResultHelpers.h\"\r\n#include \"TestGroupSettingsResult.h\"\r\n#include \"TestSettingsResult.h\"\r\n\r\n#include <AppInstallerStrings.h>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    namespace\r\n    {\r\n        // Determines whether a configuration unit should be tested.\r\n        bool ShouldTestDuringTest(const Configuration::ConfigurationUnit& unit)\r\n        {\r\n            return unit.IsActive() && unit.Intent() != ConfigurationUnitIntent::Inform;\r\n        }\r\n    }\r\n\r\n    void DefaultSetGroupProcessor::Initialize(const ConfigurationSet& set, const IConfigurationSetProcessor& setProcessor, ConfigThreadGlobals& threadGlobals, bool consistencyCheckOnly)\r\n    {\r\n        m_set = set;\r\n        m_setProcessor = setProcessor;\r\n        m_threadGlobals = &threadGlobals;\r\n        m_consistencyCheckOnly = consistencyCheckOnly;\r\n    }\r\n\r\n    Windows::Foundation::IInspectable DefaultSetGroupProcessor::Group()\r\n    {\r\n        return m_set;\r\n    }\r\n\r\n    Windows::Foundation::IAsyncOperation<ITestGroupSettingsResult> DefaultSetGroupProcessor::TestGroupSettingsAsync(Windows::Foundation::EventHandler<ITestSettingsResult> progressHandler)\r\n    {\r\n        auto strongThis = get_strong();\r\n        co_await resume_background();\r\n\r\n        auto cancellation = co_await get_cancellation_token();\r\n        cancellation.enable_propagation();\r\n\r\n        auto result = make_self<wil::details::module_count_wrapper<implementation::TestGroupSettingsResult>>();\r\n        result->Group(m_set);\r\n\r\n        try\r\n        {\r\n            for (const auto& unit : m_set.Units())\r\n            {\r\n                ThrowIf(cancellation());\r\n\r\n                AICLI_LOG_DIRECT(m_threadGlobals->GetDiagnosticLogger(), Config, Info, << \"Testing configuration unit: `\" << AppInstaller::Utility::ConvertToUTF8(unit.Identifier()) << \"` [\" << AppInstaller::Utility::ConvertToUTF8(unit.Type()) << ']');\r\n\r\n                ITestSettingsResult settingsResult;\r\n                ConfigurationTestResult testResult = ConfigurationTestResult::Unknown;\r\n                auto unitResult = make_self<wil::details::module_count_wrapper<implementation::ConfigurationUnitResultInformation>>();\r\n\r\n                if (ShouldTestDuringTest(unit))\r\n                {\r\n                    IConfigurationUnitProcessor unitProcessor;\r\n\r\n                    try\r\n                    {\r\n                        unitProcessor = m_setProcessor.CreateUnitProcessor(unit);\r\n                    }\r\n                    catch (...)\r\n                    {\r\n                        ExtractUnitResultInformation(std::current_exception(), unitResult);\r\n                    }\r\n\r\n                    // Check again as creating the unit processor could take time\r\n                    ThrowIf(cancellation());\r\n\r\n                    if (unitProcessor)\r\n                    {\r\n                        IConfigurationGroupProcessor groupProcessor = unitProcessor.try_as<IConfigurationGroupProcessor>();\r\n\r\n                        if (groupProcessor)\r\n                        {\r\n                            auto testOperation = groupProcessor.TestGroupSettingsAsync([&](const auto&, const ITestSettingsResult& unitResult)\r\n                                {\r\n                                    progressHandler(nullptr, unitResult);\r\n                                });\r\n\r\n                            ITestGroupSettingsResult groupResult = co_await testOperation;\r\n\r\n                            // Put all of the group's unit results in our unit results\r\n                            for (const auto& groupUnitResult : groupResult.UnitResults())\r\n                            {\r\n                                result->AppendUnitResult(groupUnitResult);\r\n                            }\r\n\r\n                            // Convert group result into a unit result for the group\r\n                            auto testSettingsResult = make_self<wil::details::module_count_wrapper<implementation::TestSettingsResult>>();\r\n                            testSettingsResult->Unit(unit);\r\n                            testSettingsResult->TestResult(groupResult.TestResult());\r\n                            testSettingsResult->ResultInformation(groupResult.ResultInformation());\r\n                            settingsResult = *testSettingsResult;\r\n                        }\r\n                        else\r\n                        {\r\n                            try\r\n                            {\r\n                                settingsResult = unitProcessor.TestSettings();\r\n                            }\r\n                            catch (...)\r\n                            {\r\n                                ExtractUnitResultInformation(std::current_exception(), unitResult);\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    testResult = ConfigurationTestResult::NotRun;\r\n                }\r\n\r\n                if (FAILED(unitResult->ResultCode()))\r\n                {\r\n                    testResult = ConfigurationTestResult::Failed;\r\n                }\r\n\r\n                // Check if we need to construct our own result object\r\n                if (!settingsResult)\r\n                {\r\n                    auto testSettingsResult = make_self<wil::details::module_count_wrapper<implementation::TestSettingsResult>>();\r\n                    testSettingsResult->Unit(unit);\r\n                    testSettingsResult->TestResult(testResult);\r\n                    testSettingsResult->ResultInformation(*unitResult);\r\n                    settingsResult = *testSettingsResult;\r\n                }\r\n\r\n                result->AppendUnitResult(settingsResult);\r\n\r\n                try\r\n                {\r\n                    progressHandler(nullptr, settingsResult);\r\n                }\r\n                CATCH_LOG();\r\n            }\r\n\r\n            co_return *result;\r\n        }\r\n        catch (...)\r\n        {\r\n            ExtractUnitResultInformation(std::current_exception(), result->ResultInformationInternal());\r\n            throw;\r\n        }\r\n    }\r\n\r\n    Windows::Foundation::IAsyncOperation<IApplyGroupSettingsResult> DefaultSetGroupProcessor::ApplyGroupSettingsAsync(Windows::Foundation::EventHandler<IApplyGroupMemberSettingsResult> progressHandler)\r\n    {\r\n        auto strongThis = get_strong();\r\n        co_await resume_background();\r\n\r\n        ConfigurationSetApplyProcessor applyProcessor{ m_set, m_setProcessor, { std::move(progressHandler), co_await winrt::get_cancellation_token() } };\r\n        applyProcessor.Process(m_consistencyCheckOnly);\r\n\r\n        co_return applyProcessor.Result();\r\n    }\r\n\r\n    void DefaultSetGroupProcessor::ThrowIf(bool cancellation)\r\n    {\r\n        if (cancellation)\r\n        {\r\n            AICLI_LOG_DIRECT(m_threadGlobals->GetDiagnosticLogger(), Config, Warning, << \"Operation cancelled\");\r\n            throw winrt::hresult_canceled();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/DefaultSetGroupProcessor.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"winrt/Microsoft.Management.Configuration.h\"\r\n#include \"ConfigThreadGlobals.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    // Implements the default group processing for configuration sets when the set processor doesn't handle it.\r\n    struct DefaultSetGroupProcessor : winrt::implements<DefaultSetGroupProcessor, IConfigurationGroupProcessor>\r\n    {\r\n        using ConfigurationSet = Configuration::ConfigurationSet;\r\n\r\n        DefaultSetGroupProcessor() = default;\r\n\r\n        void Initialize(const ConfigurationSet& set, const IConfigurationSetProcessor& setProcessor, ConfigThreadGlobals& threadGlobals, bool consistencyCheckOnly = false);\r\n\r\n        IInspectable Group();\r\n\r\n        Windows::Foundation::IAsyncOperation<ITestGroupSettingsResult> TestGroupSettingsAsync(Windows::Foundation::EventHandler<ITestSettingsResult> progressHandler);\r\n\r\n        Windows::Foundation::IAsyncOperation<IApplyGroupSettingsResult> ApplyGroupSettingsAsync(Windows::Foundation::EventHandler<IApplyGroupMemberSettingsResult> progressHandler);\r\n\r\n    private:\r\n        void ThrowIf(bool cancellation);\r\n\r\n        ConfigurationSet m_set = nullptr;\r\n        IConfigurationSetProcessor m_setProcessor;\r\n        ConfigThreadGlobals* m_threadGlobals = nullptr;\r\n        bool m_consistencyCheckOnly = false;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/DiagnosticInformationInstance.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"DiagnosticInformationInstance.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    void DiagnosticInformationInstance::Initialize(DiagnosticLevel level, std::wstring_view message)\r\n    {\r\n        m_level = level;\r\n        m_message = message;\r\n    }\r\n\r\n    DiagnosticLevel DiagnosticInformationInstance::Level()\r\n    {\r\n        return m_level;\r\n    }\r\n\r\n    void DiagnosticInformationInstance::Level(DiagnosticLevel value)\r\n    {\r\n        m_level = value;\r\n    }\r\n\r\n    hstring DiagnosticInformationInstance::Message()\r\n    {\r\n        return m_message;\r\n    }\r\n\r\n    void DiagnosticInformationInstance::Message(const hstring& value)\r\n    {\r\n        m_message = value;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/DiagnosticInformationInstance.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"winrt/Microsoft.Management.Configuration.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    struct DiagnosticInformationInstance : winrt::implements<DiagnosticInformationInstance, IDiagnosticInformation>\r\n    {\r\n        DiagnosticInformationInstance() = default;\r\n\r\n        void Initialize(DiagnosticLevel level, std::wstring_view message);\r\n\r\n        DiagnosticLevel Level();\r\n        void Level(DiagnosticLevel value);\r\n\r\n        hstring Message();\r\n        void Message(const hstring& value);\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        DiagnosticLevel m_level = DiagnosticLevel::Verbose;\r\n        hstring m_message;\r\n#endif\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ExceptionResultHelpers.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <exception>\r\n#include <AppInstallerLogging.h>\r\n#include <AppInstallerStrings.h>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    template <typename UnitResult>\r\n    void ExtractUnitResultInformation(std::exception_ptr exc, const UnitResult& unitResult)\r\n    {\r\n        try\r\n        {\r\n            std::rethrow_exception(exc);\r\n        }\r\n        catch (const winrt::hresult_error& hre)\r\n        {\r\n            unitResult->Initialize(hre.code(), hre.message());\r\n        }\r\n        catch (const std::exception& ex)\r\n        {\r\n            unitResult->Initialize(E_FAIL, AppInstaller::Utility::ConvertToUTF16(ex.what()));\r\n        }\r\n        catch (...)\r\n        {\r\n            unitResult->Initialize(E_FAIL, hstring{});\r\n        }\r\n\r\n        AICLI_LOG(Config, Error, << \"Unit Processor exception: \" << AppInstaller::Logging::SetHRFormat << unitResult->ResultCode() << \" [\" << AppInstaller::Utility::ConvertToUTF8(unitResult->Description()) << \"]\");\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Filesystem.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Filesystem.h\"\r\n\r\nusing namespace std::string_view_literals;\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    namespace anon\r\n    {\r\n        constexpr std::string_view s_Configuration_LocalState = \"Configuration\"sv;\r\n    }\r\n\r\n    AppInstaller::Filesystem::PathDetails GetPathDetailsFor(PathName path, bool forDisplay)\r\n    {\r\n        AppInstaller::Filesystem::PathDetails result;\r\n        // We should not create directories by default when they are retrieved for display purposes.\r\n        result.Create = !forDisplay;\r\n\r\n        switch (path)\r\n        {\r\n        case PathName::LocalState:\r\n            result = GetPathDetailsFor(AppInstaller::Filesystem::PathName::UnpackagedLocalStateRoot, forDisplay);\r\n            result.Path /= anon::s_Configuration_LocalState;\r\n            break;\r\n        default:\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n\r\n        return result;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Filesystem.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/Filesystem.h>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    // Paths used by configuration.\r\n    enum class PathName\r\n    {\r\n        // Local state root for configuration.\r\n        LocalState,\r\n    };\r\n\r\n    // Gets the PathDetails used for the given path.\r\n    // This is exposed primarily to allow for testing, GetPathTo should be preferred.\r\n    AppInstaller::Filesystem::PathDetails GetPathDetailsFor(PathName path, bool forDisplay = false);\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/FindUnitProcessorsOptions.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"FindUnitProcessorsOptions.h\"\r\n#include \"FindUnitProcessorsOptions.g.cpp\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    hstring FindUnitProcessorsOptions::SearchPaths() const\r\n    {\r\n        return m_searchPaths;\r\n    }\r\n\r\n    void FindUnitProcessorsOptions::SearchPaths(hstring const& value)\r\n    {\r\n        m_searchPaths = value;\r\n    }\r\n\r\n    bool FindUnitProcessorsOptions::SearchPathsExclusive() const\r\n    {\r\n        return m_searchPathsExclusive;\r\n    }\r\n\r\n    void FindUnitProcessorsOptions::SearchPathsExclusive(bool value)\r\n    {\r\n        m_searchPathsExclusive = value;\r\n    }\r\n\r\n    Microsoft::Management::Configuration::ConfigurationUnitDetailFlags FindUnitProcessorsOptions::UnitDetailFlags() const\r\n    {\r\n        return m_detailFlags;\r\n    }\r\n\r\n    void FindUnitProcessorsOptions::UnitDetailFlags(Microsoft::Management::Configuration::ConfigurationUnitDetailFlags value)\r\n    {\r\n        m_detailFlags = value;\r\n    }\r\n\r\n    HRESULT STDMETHODCALLTYPE FindUnitProcessorsOptions::SetLifetimeWatcher(IUnknown* watcher)\r\n    {\r\n        return AppInstaller::WinRT::LifetimeWatcherBase::SetLifetimeWatcher(watcher);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/FindUnitProcessorsOptions.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"FindUnitProcessorsOptions.g.h\"\n#include <winget/ILifetimeWatcher.h>\n#include <winrt/Windows.Foundation.h>\n\nnamespace winrt::Microsoft::Management::Configuration::implementation\n{\n    struct FindUnitProcessorsOptions : FindUnitProcessorsOptionsT<FindUnitProcessorsOptions, winrt::cloaked<AppInstaller::WinRT::ILifetimeWatcher>>, AppInstaller::WinRT::LifetimeWatcherBase\n    {\n        FindUnitProcessorsOptions() = default;\n\n        hstring SearchPaths() const;\n        void SearchPaths(hstring const& value);\n\n        bool SearchPathsExclusive() const;\r\n        void SearchPathsExclusive(bool value);\n\n        Microsoft::Management::Configuration::ConfigurationUnitDetailFlags UnitDetailFlags() const;\r\n        void UnitDetailFlags(Microsoft::Management::Configuration::ConfigurationUnitDetailFlags value);\r\n\r\n        HRESULT STDMETHODCALLTYPE SetLifetimeWatcher(IUnknown* watcher);\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        hstring m_searchPaths;\n        bool m_searchPathsExclusive = false;\n        Microsoft::Management::Configuration::ConfigurationUnitDetailFlags m_detailFlags = Microsoft::Management::Configuration::ConfigurationUnitDetailFlags::None;\n#endif\n    };\n}\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\nnamespace winrt::Microsoft::Management::Configuration::factory_implementation\n{\n    struct FindUnitProcessorsOptions : FindUnitProcessorsOptionsT<FindUnitProcessorsOptions, implementation::FindUnitProcessorsOptions>\n    {\n    };\n}\n#endif\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/GetAllConfigurationUnitSettingsResult.cpp",
    "content": "﻿// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"GetAllConfigurationUnitSettingsResult.h\"\n#include \"ConfigurationUnitResultInformation.h\"\n\nnamespace winrt::Microsoft::Management::Configuration::implementation\n{\n    GetAllConfigurationUnitSettingsResult::GetAllConfigurationUnitSettingsResult() :\n        m_resultInformation(*make_self<wil::details::module_count_wrapper<implementation::ConfigurationUnitResultInformation>>())\n    {\n    }\n\n    void GetAllConfigurationUnitSettingsResult::ResultInformation(const IConfigurationUnitResultInformation& resultInformation)\n    {\n        m_resultInformation = resultInformation;\n    }\n\n    IConfigurationUnitResultInformation GetAllConfigurationUnitSettingsResult::ResultInformation() const\n    {\n        return m_resultInformation;\n    }\n\n    Windows::Foundation::Collections::IVector<Windows::Foundation::Collections::ValueSet> GetAllConfigurationUnitSettingsResult::Settings()\n    {\n        return m_settings;\n    }\n\n    void GetAllConfigurationUnitSettingsResult::Settings(Windows::Foundation::Collections::IVector<Windows::Foundation::Collections::ValueSet>&& value)\n    {\n        m_settings = std::move(value);\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/GetAllConfigurationUnitSettingsResult.h",
    "content": "﻿// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"GetAllConfigurationUnitSettingsResult.g.h\"\n#include <winrt/Windows.Foundation.Collections.h>\n\nnamespace winrt::Microsoft::Management::Configuration::implementation\n{\n    struct GetAllConfigurationUnitSettingsResult : GetAllConfigurationUnitSettingsResultT<GetAllConfigurationUnitSettingsResult>\n    {\n        GetAllConfigurationUnitSettingsResult();\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void ResultInformation(const IConfigurationUnitResultInformation& resultInformation);\n        void Settings(Windows::Foundation::Collections::IVector<Windows::Foundation::Collections::ValueSet>&& value);\n#endif\n\n        IConfigurationUnitResultInformation ResultInformation() const;\n        Windows::Foundation::Collections::IVector<Windows::Foundation::Collections::ValueSet> Settings();\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        IConfigurationUnitResultInformation m_resultInformation;\n        Windows::Foundation::Collections::IVector<Windows::Foundation::Collections::ValueSet> m_settings;\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/GetAllConfigurationUnitsResult.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"GetAllConfigurationUnitsResult.h\"\n#include \"ConfigurationUnitResultInformation.h\"\n\nnamespace winrt::Microsoft::Management::Configuration::implementation\n{\n    GetAllConfigurationUnitsResult::GetAllConfigurationUnitsResult() :\n        m_resultInformation(*make_self<wil::details::module_count_wrapper<implementation::ConfigurationUnitResultInformation>>())\n    {\n    }\n\n    void GetAllConfigurationUnitsResult::ResultInformation(const IConfigurationUnitResultInformation& resultInformation)\n    {\n        m_resultInformation = resultInformation;\n    }\n\n    IConfigurationUnitResultInformation GetAllConfigurationUnitsResult::ResultInformation() const\n    {\n        return m_resultInformation;\n    }\n\n    Windows::Foundation::Collections::IVector<Configuration::ConfigurationUnit> GetAllConfigurationUnitsResult::Units()\n    {\n        return m_units;\n    }\n\n    void GetAllConfigurationUnitsResult::Units(Windows::Foundation::Collections::IVector<Configuration::ConfigurationUnit>&& value)\n    {\n        m_units = std::move(value);\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/GetAllConfigurationUnitsResult.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"GetAllConfigurationUnitsResult.g.h\"\n#include <winrt/Windows.Foundation.Collections.h>\n\nnamespace winrt::Microsoft::Management::Configuration::implementation\n{\n    struct GetAllConfigurationUnitsResult : GetAllConfigurationUnitsResultT<GetAllConfigurationUnitsResult>\n    {\n        GetAllConfigurationUnitsResult();\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void ResultInformation(const IConfigurationUnitResultInformation& resultInformation);\n        void Units(Windows::Foundation::Collections::IVector<Configuration::ConfigurationUnit>&& value);\n#endif\n\n        IConfigurationUnitResultInformation ResultInformation() const;\n        Windows::Foundation::Collections::IVector<Configuration::ConfigurationUnit> Units();\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        IConfigurationUnitResultInformation m_resultInformation;\n        Windows::Foundation::Collections::IVector<Configuration::ConfigurationUnit> m_units;\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/GetConfigurationSetDetailsResult.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"GetConfigurationSetDetailsResult.h\"\r\n#include \"GetConfigurationSetDetailsResult.g.cpp\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    GetConfigurationSetDetailsResult::GetConfigurationSetDetailsResult() :\r\n        m_unitResults(multi_threaded_vector<GetConfigurationUnitDetailsResult>())\r\n    {};\r\n\r\n    const Windows::Foundation::Collections::IVector<GetConfigurationUnitDetailsResult>& GetConfigurationSetDetailsResult::UnitResultsVector()\r\n    {\r\n        return m_unitResults;\r\n    }\r\n\r\n    Windows::Foundation::Collections::IVectorView<GetConfigurationUnitDetailsResult> GetConfigurationSetDetailsResult::UnitResults()\r\n    {\r\n        return m_unitResults.GetView();\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/GetConfigurationSetDetailsResult.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"GetConfigurationSetDetailsResult.g.h\"\r\n#include <winrt/Windows.Foundation.Collections.h>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    struct GetConfigurationSetDetailsResult : GetConfigurationSetDetailsResultT<GetConfigurationSetDetailsResult>\r\n    {\r\n        using GetConfigurationUnitDetailsResult = Configuration::GetConfigurationUnitDetailsResult;\r\n\r\n        GetConfigurationSetDetailsResult();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        const Windows::Foundation::Collections::IVector<GetConfigurationUnitDetailsResult>& UnitResultsVector();\r\n#endif\r\n\r\n        Windows::Foundation::Collections::IVectorView<GetConfigurationUnitDetailsResult> UnitResults();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        Windows::Foundation::Collections::IVector<GetConfigurationUnitDetailsResult> m_unitResults;\r\n#endif\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/GetConfigurationUnitDetailsResult.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"GetConfigurationUnitDetailsResult.h\"\r\n#include \"GetConfigurationUnitDetailsResult.g.cpp\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    void GetConfigurationUnitDetailsResult::Unit(ConfigurationUnit value)\r\n    {\r\n        m_unit = std::move(value);\r\n    }\r\n\r\n    void GetConfigurationUnitDetailsResult::Details(IConfigurationUnitProcessorDetails value)\r\n    {\r\n        m_details = std::move(value);\r\n    }\r\n\r\n    void GetConfigurationUnitDetailsResult::ResultInformation(IConfigurationUnitResultInformation value)\r\n    {\r\n        m_resultInformation = std::move(value);\r\n    }\r\n\r\n    ConfigurationUnit GetConfigurationUnitDetailsResult::Unit()\r\n    {\r\n        return m_unit;\r\n    }\r\n\r\n    IConfigurationUnitProcessorDetails GetConfigurationUnitDetailsResult::Details()\r\n    {\r\n        return m_details;\r\n    }\r\n\r\n    IConfigurationUnitResultInformation GetConfigurationUnitDetailsResult::ResultInformation()\r\n    {\r\n        return m_resultInformation;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/GetConfigurationUnitDetailsResult.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"GetConfigurationUnitDetailsResult.g.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    struct GetConfigurationUnitDetailsResult : GetConfigurationUnitDetailsResultT<GetConfigurationUnitDetailsResult>\r\n    {\r\n        using ConfigurationUnit = Configuration::ConfigurationUnit;\r\n\r\n        GetConfigurationUnitDetailsResult() = default;\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        void Unit(ConfigurationUnit value);\r\n        void Details(IConfigurationUnitProcessorDetails value);\r\n        void ResultInformation(IConfigurationUnitResultInformation value);\r\n#endif\r\n\r\n        ConfigurationUnit Unit();\r\n        IConfigurationUnitProcessorDetails Details();\r\n        IConfigurationUnitResultInformation ResultInformation();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        ConfigurationUnit m_unit = nullptr;\r\n        IConfigurationUnitProcessorDetails m_details;\r\n        IConfigurationUnitResultInformation m_resultInformation;\r\n#endif\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"GetConfigurationUnitSettingsResult.h\"\r\n#include \"GetConfigurationUnitSettingsResult.g.cpp\"\r\n#include \"ConfigurationUnitResultInformation.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    GetConfigurationUnitSettingsResult::GetConfigurationUnitSettingsResult() :\r\n        m_resultInformation(*make_self<wil::details::module_count_wrapper<implementation::ConfigurationUnitResultInformation>>())\r\n    {\r\n    }\r\n\r\n    void GetConfigurationUnitSettingsResult::ResultInformation(const IConfigurationUnitResultInformation& resultInformation)\r\n    {\r\n        m_resultInformation = resultInformation;\r\n    }\r\n\r\n    IConfigurationUnitResultInformation GetConfigurationUnitSettingsResult::ResultInformation() const\r\n    {\r\n        return m_resultInformation;\r\n    }\r\n\r\n    Windows::Foundation::Collections::ValueSet GetConfigurationUnitSettingsResult::Settings()\r\n    {\r\n        return m_settings;\r\n    }\r\n\r\n    void GetConfigurationUnitSettingsResult::Settings(Windows::Foundation::Collections::ValueSet&& value)\r\n    {\r\n        m_settings = std::move(value);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/GetConfigurationUnitSettingsResult.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"GetConfigurationUnitSettingsResult.g.h\"\r\n#include <winrt/Windows.Foundation.Collections.h>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    struct GetConfigurationUnitSettingsResult : GetConfigurationUnitSettingsResultT<GetConfigurationUnitSettingsResult>\r\n    {\r\n        GetConfigurationUnitSettingsResult();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        void ResultInformation(const IConfigurationUnitResultInformation& resultInformation);\r\n        void Settings(Windows::Foundation::Collections::ValueSet&& value);\r\n#endif\r\n\r\n        IConfigurationUnitResultInformation ResultInformation() const;\r\n        Windows::Foundation::Collections::ValueSet Settings();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        IConfigurationUnitResultInformation m_resultInformation;\r\n        Windows::Foundation::Collections::ValueSet m_settings;\r\n#endif\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.idl",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\nnamespace Microsoft.Management.Configuration\r\n{\r\n    [contractversion(4)]\r\n    apicontract Contract{};\r\n\r\n    // The current state of a configuration set.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    enum ConfigurationSetState\r\n    {\r\n        // The state of the configuration set is unknown.\r\n        Unknown,\r\n        // The configuration set is in the queue to be applied.\r\n        Pending,\r\n        // The configuration set is actively being applied.\r\n        InProgress,\r\n        // The configuration set has completed being applied.\r\n        Completed,\r\n    };\r\n\r\n    // The current state of a configuration unit.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    enum ConfigurationUnitState\r\n    {\r\n        // The state of the configuration unit is unknown.\r\n        Unknown,\r\n        // The configuration unit is in the queue to be applied.\r\n        Pending,\r\n        // The configuration unit is actively being applied.\r\n        InProgress,\r\n        // The configuration unit has completed being applied.\r\n        Completed,\r\n        // The configuration unit was not applied due to external factors.\r\n        Skipped,\r\n    };\r\n\r\n    // Defines the type of detail probing that is allowed about a configuration unit.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    [flags]\r\n    enum ConfigurationUnitDetailFlags\r\n    {\r\n        // For completeness.\r\n        None = 0,\r\n        // Only reads details from local data.\r\n        Local = 0x1,\r\n        // Can query the catalog information for details, but will not download any modules.\r\n        Catalog = 0x2,\r\n        // Can only read data, not write or execute.\r\n        ReadOnly = Local | Catalog,\r\n        // Can download modules, but not load them.\r\n        Download = 0x4,\r\n        // Can load modules for details.\r\n        Load = 0x8,\r\n    };\r\n\r\n    // The source of a result; for instance, the part of the system that generated a failure.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    enum ConfigurationUnitResultSource\r\n    {\r\n        // The source is not known, or more likely, there was no failure.\r\n        None,\r\n        // The result came from inside the configuration system; this is likely a bug.\r\n        Internal,\r\n        // The configuration set was ill formed. For instance, referencing a configuration unit\r\n        // that does not exist or a dependency that is not present.\r\n        ConfigurationSet,\r\n        // The external module that processes the configuration unit generated the result.\r\n        UnitProcessing,\r\n        // The system state is causing the error.\r\n        SystemState,\r\n        // The configuration unit was not run due to a precondition not being met.\r\n        // For example, if a dependency fails to be applied, this will be set.\r\n        Precondition,\r\n    };\r\n\r\n    // A security context; typically used to define the context in which a configuration unit should be processed.\r\n    [contract(Microsoft.Management.Configuration.Contract, 3)]\r\n    enum SecurityContext\r\n    {\r\n        // The default value; indicates that the configuration unit should be processed at the caller's current level.\r\n        Current,\r\n        // A standard user without administrator privileges.\r\n        Restricted,\r\n        // A user with administrator privileges.\r\n        Elevated,\r\n    };\r\n\r\n    // Information about the environment in which a configuration is processed.\r\n    [contract(Microsoft.Management.Configuration.Contract, 3)]\r\n    runtimeclass ConfigurationEnvironment\r\n    {\r\n        // The security context in which a configuration is processed.\r\n        SecurityContext Context;\r\n\r\n        // A string that identifies the processor that should be used for the configuration.\r\n        String ProcessorIdentifier;\r\n\r\n        // Processor specific properties.\r\n        Windows.Foundation.Collections.IMap<String, String> ProcessorProperties{ get; };\r\n    };\r\n\r\n    // Information on a result for a single unit of configuration.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    interface IConfigurationUnitResultInformation\r\n    {\r\n        // The error code of the failure.\r\n        HRESULT ResultCode{ get; };\r\n\r\n        // The short description of the failure.\r\n        String Description{ get; };\r\n\r\n        // A more detailed error message appropriate for diagnosing the root cause of an error.\r\n        String Details{ get; };\r\n\r\n        // The source of the result.\r\n        ConfigurationUnitResultSource ResultSource{ get; };\r\n    }\r\n\r\n    // Provides information for a specific configuration unit setting.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    interface IConfigurationUnitSettingDetails\r\n    {\r\n        // The name of the setting.\r\n        String Identifier{ get; };\r\n        // A brief description of the setting.\r\n        String Title{ get; };\r\n        // The detailed description of the setting.\r\n        String Description{ get; };\r\n        // Whether the setting is a key. This is used to determine if different settings are in conflict.\r\n        Boolean IsKey{ get; };\r\n        // Whether a non-empty value for the setting is required.\r\n        Boolean IsRequired{ get; };\r\n        // Whether the setting should be serialized in order to be applied on another system.\r\n        // When the current settings are retrieved from the system, this can be used to exclude settings that are not relevant to a future application of the unit of configuration.\r\n        Boolean IsInformational{ get; };\r\n        // The data type for the value of this setting.\r\n        Windows.Foundation.PropertyType Type{ get; };\r\n\r\n        // The schema fragment to be used for this setting.\r\n        // Using a single entry of the `properties` object from a JSON schema is suggested, for instance:\r\n        // {\r\n        // \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\r\n        // \"scope\": {\r\n        //          \"title\": \"Target scope\",\r\n        //          \"description\": \"The scope at which the configuration should be applied.\",\r\n        //          \"type\": \"string\",\r\n        //          \"enum\": [\r\n        //              \"machine\",\r\n        //              \"user\"\r\n        //          ]\r\n        //      }\r\n        // }\r\n        String Schema{ get; };\r\n    }\r\n\r\n    // Provides information for a specific configuration unit within the runtime.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    interface IConfigurationUnitProcessorDetails\r\n    {\r\n        // The type of configuration unit.\r\n        String UnitType{ get; };\r\n        // A description of the unit of configuration.\r\n        String UnitDescription{ get; };\r\n        // The URI of the documentation for the unit of configuration.\r\n        Windows.Foundation.Uri UnitDocumentationUri{ get; };\r\n        // The URI of the icon for the unit of configuration.\r\n        Windows.Foundation.Uri UnitIconUri{ get; };\r\n        // The name of the module containing the unit of configuration.\r\n        String ModuleName{ get; };\r\n        // The type of the module containing the unit of configuration.\r\n        String ModuleType{ get; };\r\n        // The source of the module containing the unit of configuration.\r\n        String ModuleSource{ get; };\r\n        // The description of the module containing the unit of configuration.\r\n        String ModuleDescription{ get; };\r\n        // The URI of the documentation for the module containing the unit of configuration.\r\n        Windows.Foundation.Uri ModuleDocumentationUri{ get; };\r\n        // The URI for the published module containing the unit of configuration.\r\n        Windows.Foundation.Uri PublishedModuleUri{ get; };\r\n        // The version of the module containing the unit of configuration.\r\n        String Version{ get; };\r\n        // The publishing date of the module containing the unit of configuration.\r\n        Windows.Foundation.DateTime PublishedDate{ get; };\r\n        // Whether the module is already present on the system.\r\n        Boolean IsLocal{ get; };\r\n        // The author of the module containing the unit of configuration.\r\n        String Author{ get; };\r\n        // The publisher of the module containing the unit of configuration.\r\n        String Publisher{ get; };\r\n        // The signing information of the module files containing the unit of configuration.\r\n        // May contain Windows.Security.Cryptography.Certificates.Certificate or Windows.Security.Cryptography.Certificates.CertificateChain.\r\n        Windows.Foundation.Collections.IVectorView<IInspectable> SigningInformation{ get; };\r\n        // The settings information for the unit of configuration.\r\n        Windows.Foundation.Collections.IVectorView<IConfigurationUnitSettingDetails> Settings{ get; };\r\n        // Does it comes from a public repository\r\n        Boolean IsPublic{ get; };\r\n    }\r\n\r\n    // Provides information for a specific configuration unit within the runtime.\r\n    [contract(Microsoft.Management.Configuration.Contract, 2)]\r\n    interface IConfigurationUnitProcessorDetails2 requires IConfigurationUnitProcessorDetails\r\n    {\r\n        // Determines if this configuration unit should be treated as a group.\r\n        Boolean IsGroup{ get; };\r\n    }\r\n\r\n    // Provides information for a specific configuration unit within the runtime.\r\n    [contract(Microsoft.Management.Configuration.Contract, 4)]\r\n    interface IConfigurationUnitProcessorDetails3 requires IConfigurationUnitProcessorDetails2\r\n    {\r\n        // The path of the resource.\r\n        String Path{ get; };\r\n    }\r\n\r\n    // Defines how the configuration unit is to be used within the configuration system.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    enum ConfigurationUnitIntent\r\n    {\r\n        // The configuration unit will only be used to Test the current system state.\r\n        Assert,\r\n        // The configuration unit will only be used to Get the current system state.\r\n        Inform,\r\n        // The configuration unit will be used to Apply the current system state.\r\n        // The configuration unit will be used to Test and Get the current system state as part of that process.\r\n        Apply,\r\n        // The configuration unit's intent is unknown.\r\n        // Currently not supported.\r\n        Unknown,\r\n    };\r\n\r\n    // A single unit of configuration.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    runtimeclass ConfigurationUnit\r\n    {\r\n        // Creates an empty configuration unit for authoring purposes.\r\n        ConfigurationUnit();\r\n\r\n        // The type of the unit being configured; not a name for this instance.\r\n        String Type;\r\n\r\n        // An identifier used to uniquely identify the instance of a configuration unit on the system.\r\n        // May change upon applying a configuration unit from a historical context if some part of the set changed.\r\n        Guid InstanceIdentifier{ get; };\r\n\r\n        // The identifier name of this instance within the set.\r\n        String Identifier;\r\n\r\n        // Describes how this configuration unit will be used.\r\n        ConfigurationUnitIntent Intent;\r\n\r\n        // The `Identifier` values of the configuration units that this unit depends on.\r\n        Windows.Foundation.Collections.IVector<String> Dependencies;\r\n\r\n        // The metadata properties associated with the configuration unit.\r\n        // TODO: This is being used to drive processing decisions when it should not.\r\n        //       There is ongoing discussion about this at https://github.com/PowerShell/DSC/issues/47 and https://github.com/PowerShell/DSC/issues/92.\r\n        Windows.Foundation.Collections.ValueSet Metadata;\r\n\r\n        // Contains the values that are for use by the configuration unit itself.\r\n        Windows.Foundation.Collections.ValueSet Settings;\r\n\r\n        // Contains information on the origin of the configuration unit.\r\n        // May be null if ConfigurationProcessor.GetDetailsAsync has not been called yet.\r\n        IConfigurationUnitProcessorDetails Details{ get; };\r\n\r\n        // The current state of the configuration unit.\r\n        ConfigurationUnitState State{ get; };\r\n\r\n        // Contains information on the result of the latest attempt to apply the configuration unit.\r\n        IConfigurationUnitResultInformation ResultInformation{ get; };\r\n\r\n        // Controls whether this unit will be processed when part of a set.\r\n        Boolean IsActive;\r\n\r\n        // Creates a copy of this configuration unit, with the following notes:\r\n        //  InstanceIdentifier will be a new value\r\n        //  Identifier will be empty\r\n        //  Dependencies, Metadata, and Settings will by new containers with identical values inside\r\n        //  Details will be the same value (not a copy, just another reference)\r\n        //  State, ResultInformation, and ShouldApply will be their default constructed state\r\n        //  IsGroup will be false and child units will not be copied\r\n        //  Environment will be copied\r\n        ConfigurationUnit Copy();\r\n\r\n        [contract(Microsoft.Management.Configuration.Contract, 2)]\r\n        {\r\n            // Determines if this configuration unit should be treated as a group.\r\n            // A configuration unit group treats its `Settings` as the definition of child units.\r\n            Boolean IsGroup;\r\n\r\n            // The configuration units that are part of this unit (if IsGroup is true).\r\n            Windows.Foundation.Collections.IVector<ConfigurationUnit> Units;\r\n        }\r\n\r\n        [contract(Microsoft.Management.Configuration.Contract, 3)]\r\n        {\r\n            // The environment in which to process the configuration unit.\r\n            // This defines the initial processing environment state used by the configuration system,\r\n            // and may be overridden by the processor later.\r\n            ConfigurationEnvironment Environment{ get; };\r\n        }\r\n    }\r\n\r\n    // The change event type that has occurred for a configuration set change.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    enum ConfigurationSetChangeEventType\r\n    {\r\n        Unknown,\r\n        // The change event was for the set state. Only ConfigurationSetChangeData.SetState is valid.\r\n        SetStateChanged,\r\n        // The change event was for the unit state. All ConfigurationSetChangeData properties are valid.\r\n        UnitStateChanged,\r\n    };\r\n\r\n    // The change data sent about changes to a specific set.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    runtimeclass ConfigurationSetChangeData\r\n    {\r\n        // The change event type that occurred.\r\n        ConfigurationSetChangeEventType Change{ get; };\r\n\r\n        // The state of the configuration set for this event (the ConfigurationSet can be used to get the current state, which may be different).\r\n        ConfigurationSetState SetState{ get; };\r\n\r\n        // The state of the configuration unit for this event (the ConfigurationUnit can be used to get the current state, which may be different).\r\n        ConfigurationUnitState UnitState{ get; };\r\n\r\n        // Contains information on the result of the attempt to apply the configuration unit.\r\n        IConfigurationUnitResultInformation ResultInformation{ get; };\r\n\r\n        // The configuration unit whose state changed.\r\n        ConfigurationUnit Unit{ get; };\r\n    }\r\n\r\n    // The definition of a configuration parameter; a value that may be provided to alter the processing of a configuration set.\r\n    [contract(Microsoft.Management.Configuration.Contract, 2)]\r\n    runtimeclass ConfigurationParameter\r\n    {\r\n        ConfigurationParameter();\r\n\r\n        // The name of the parameter.\r\n        String Name;\r\n\r\n        // The description of the parameter.\r\n        String Description;\r\n\r\n        // The metadata properties associated with the configuration parameter.\r\n        Windows.Foundation.Collections.ValueSet Metadata;\r\n\r\n        // The value of the parameter should be treated as a secret; not logged our output.\r\n        Boolean IsSecure;\r\n\r\n        // The type of the parameter.\r\n        Windows.Foundation.PropertyType Type;\r\n\r\n        // The default value; may be null if no default is provided.\r\n        Object DefaultValue;\r\n\r\n        // The set of allowed values; a null container indicates that the values are not restricted.\r\n        Windows.Foundation.Collections.IVector<Object> AllowedValues;\r\n\r\n        // The minimum length for a parameter type with the concept (string, array, etc.).\r\n        UInt32 MinimumLength;\r\n\r\n        // The maximum length for a parameter type with the concept (string, array, etc.).\r\n        UInt32 MaximumLength;\r\n\r\n        // For comparable parameter types, the minimum value allowed (integrals, DateTime, etc.).\r\n        Object MinimumValue;\r\n\r\n        // For comparable parameter types, the maximum value allowed (integrals, DateTime, etc.).\r\n        Object MaximumValue;\r\n\r\n        // The input value; may be null if no value is provided.\r\n        Object ProvidedValue;\r\n    }\r\n\r\n    // A configuration set contains a collection of configuration units and details about the set.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    runtimeclass ConfigurationSet\r\n    {\r\n        // Creates an empty configuration set for authoring purposes.\r\n        ConfigurationSet();\r\n\r\n        // The name of the set; if from a file this could be the file name.\r\n        String Name;\r\n        // The origin of the set; if it came from a repository it could be the remote URL (ex. https://github.com/microsoft/winget-cli.git).\r\n        String Origin;\r\n        // The location of the configuration set on the local filesystem.\r\n        // If this set is from history, the file may no longer exist or it's contents may have been changed.\r\n        String Path;\r\n\r\n        // An identifier used to uniquely identify the instance of a configuration set on the system.\r\n        // May change upon applying a configuration set from a historical context if some part of the set changed.\r\n        Guid InstanceIdentifier{ get; };\r\n        // The state that the set is in.\r\n        ConfigurationSetState State{ get; };\r\n        // The time that this set was recorded with intent to apply.\r\n        Windows.Foundation.DateTime FirstApply{ get; };\r\n        // The time that this set was last started to be applied.\r\n        Windows.Foundation.DateTime ApplyBegun{ get; };\r\n        // The time that this set was last finished being applied (does not indicate success).\r\n        Windows.Foundation.DateTime ApplyEnded{ get; };\r\n\r\n        // The configuration units that are part of this set.\r\n        Windows.Foundation.Collections.IVector<ConfigurationUnit> Units;\r\n\r\n        // The schema version to use for the set.\r\n        // Will be set to the schema version when read in, and default to the latest if created manually.\r\n        // Setting SchemaVersion to a different value will change SchemaUri.\r\n        String SchemaVersion;\r\n\r\n        // Only changes for this set are sent to this event.\r\n        // This includes things like: start/stop of the entire set for application, start/stop of a unit for application.\r\n        event Windows.Foundation.TypedEventHandler<ConfigurationSet, ConfigurationSetChangeData> ConfigurationSetChange;\r\n\r\n        // Writes the configuration set to the given stream.\r\n        void Serialize(Windows.Storage.Streams.IOutputStream stream);\r\n\r\n        // Removes the configuration set from the recorded history, if present.\r\n        void Remove();\r\n\r\n        [contract(Microsoft.Management.Configuration.Contract, 2)]\r\n        {\r\n            // The metadata properties associated with the configuration set.\r\n            Windows.Foundation.Collections.ValueSet Metadata;\r\n\r\n            // The parameters that this configuration set supports.\r\n            Windows.Foundation.Collections.IVector<ConfigurationParameter> Parameters;\r\n\r\n            // The variables that this configuration set uses.\r\n            Windows.Foundation.Collections.ValueSet Variables;\r\n\r\n            // The schema URI to use for the set.\r\n            // Will be set to the schema version when read in, and default to the latest if created manually.\r\n            // Setting SchemaUri to a different value will change SchemaVersion.\r\n            Windows.Foundation.Uri SchemaUri;\r\n        }\r\n\r\n        [contract(Microsoft.Management.Configuration.Contract, 3)]\r\n        {\r\n            // The environment in which to process the configuration set.\r\n            // This defines the initial processing environment state used by the configuration system,\r\n            // and may be overridden by the processor later.\r\n            ConfigurationEnvironment Environment{ get; };\r\n\r\n            // Gets the union of environments as defined by all of the active units within the set.\r\n            Windows.Foundation.Collections.IVector<ConfigurationEnvironment> GetUnitEnvironments();\r\n        }\r\n    }\r\n\r\n    // The result of applying the settings with an IConfigurationUnitProcessor.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    interface IApplySettingsResult\r\n    {\r\n        // The configuration unit.\r\n        ConfigurationUnit Unit{ get; };\r\n\r\n        // Indicates whether a reboot is required after the settings were applied.\r\n        Boolean RebootRequired{ get; };\r\n\r\n        // The result of applying the configuration unit.\r\n        IConfigurationUnitResultInformation ResultInformation{ get; };\r\n    }\r\n\r\n    // Informs the caller of the result of running a Test.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    enum ConfigurationTestResult\r\n    {\r\n        // The result is unknown.\r\n        Unknown,\r\n        // The system is in the state described by the configuration.\r\n        Positive,\r\n        // The system is not in the state described by the configuration.\r\n        Negative,\r\n        // Running the test failed.\r\n        Failed,\r\n        // The test was not run because it was not applicable.\r\n        NotRun,\r\n    };\r\n\r\n    // The result of testing the settings with an IConfigurationUnitProcessor.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    interface ITestSettingsResult\r\n    {\r\n        // The configuration unit.\r\n        ConfigurationUnit Unit{ get; };\r\n\r\n        // The result (if any) of running Test on the configuration unit.\r\n        ConfigurationTestResult TestResult{ get; };\r\n\r\n        // The result of testing the configuration unit.\r\n        // This is not the response for the test, but rather contains information about the actual attempt to run the test.\r\n        IConfigurationUnitResultInformation ResultInformation{ get; };\r\n    }\r\n\r\n    // The result of getting the settings with an IConfigurationUnitProcessor.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    interface IGetSettingsResult\r\n    {\r\n        // The configuration unit.\r\n        ConfigurationUnit Unit{ get; };\r\n\r\n        // The current state of the system for the configuration unit.\r\n        Windows.Foundation.Collections.ValueSet Settings{ get; };\r\n\r\n        // The result of getting the configuration unit settings.\r\n        // This is not the response for the retrieval, but rather contains information about the actual attempt to retrieve the settings.\r\n        IConfigurationUnitResultInformation ResultInformation{ get; };\r\n    }\r\n\r\n    // The result of getting the settings for all instances of a configuration unit.\r\n    [contract(Microsoft.Management.Configuration.Contract, 2)]\r\n    interface IGetAllSettingsResult\r\n    {\r\n        // The configuration unit.\r\n        ConfigurationUnit Unit{ get; };\r\n\r\n        // The current state of the system for all the instances of the configuration unit.\r\n        Windows.Foundation.Collections.IVector<Windows.Foundation.Collections.ValueSet> Settings{ get; };\r\n\r\n        // The result of getting the configuration unit settings.\r\n        // This is not the response for the retrieval, but rather contains information about the actual attempt to retrieve the settings.\r\n        IConfigurationUnitResultInformation ResultInformation{ get; };\r\n    }\r\n\r\n    // The result of getting all of the units for a configuration unit.\r\n    [contract(Microsoft.Management.Configuration.Contract, 4)]\r\n    interface IGetAllUnitsResult\r\n    {\r\n        // The configuration unit.\r\n        ConfigurationUnit Unit{ get; };\r\n\r\n        // The units retrieved for the given unit.\r\n        Windows.Foundation.Collections.IVector<ConfigurationUnit> Units{ get; };\r\n\r\n        // The result of getting the configuration units.\r\n        // This is not the response for the retrieval, but rather contains information about the actual attempt to retrieve the settings.\r\n        IConfigurationUnitResultInformation ResultInformation{ get; };\r\n    }\r\n\r\n    // Provides access to a specific configuration unit within the runtime.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    interface IConfigurationUnitProcessor\r\n    {\r\n        // The configuration unit that the processor was created for.\r\n        ConfigurationUnit Unit{ get; };\r\n\r\n        // Determines if the system is already in the state described by the configuration unit.\r\n        ITestSettingsResult TestSettings();\r\n\r\n        // Gets the current system state for the configuration unit.\r\n        IGetSettingsResult GetSettings();\r\n\r\n        // Applies the state described in the configuration unit.\r\n        IApplySettingsResult ApplySettings();\r\n    }\r\n\r\n    [contract(Microsoft.Management.Configuration.Contract, 2)]\r\n    interface IGetAllSettingsConfigurationUnitProcessor requires IConfigurationUnitProcessor\r\n    {\r\n        // Gets the current system state for all the instances of the configuration unit, each of which has their own settings.\r\n        IGetAllSettingsResult GetAllSettings();\r\n    }\r\n\r\n    [contract(Microsoft.Management.Configuration.Contract, 4)]\r\n    interface IGetAllUnitsConfigurationUnitProcessor requires IConfigurationUnitProcessor\r\n    {\r\n        // Gets all units for the configuration unit.\r\n        IGetAllUnitsResult GetAllUnits();\r\n    }\r\n\r\n    // Controls the lifetime of operations for a single configuration set.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    interface IConfigurationSetProcessor\r\n    {\r\n        // Gets the configuration unit processor details for the given unit.\r\n        IConfigurationUnitProcessorDetails GetUnitProcessorDetails(ConfigurationUnit unit, ConfigurationUnitDetailFlags detailFlags);\r\n\r\n        // Creates a configuration unit processor for the given unit.\r\n        IConfigurationUnitProcessor CreateUnitProcessor(ConfigurationUnit unit);\r\n    }\r\n\r\n    // The definition of find unit processors option.\r\n    [contract(Microsoft.Management.Configuration.Contract, 4)]\r\n    runtimeclass FindUnitProcessorsOptions\r\n    {\r\n        FindUnitProcessorsOptions();\r\n\r\n        // Search paths for finding configuration unit processors. The value has the same format as\r\n        // PATH environment variable. Paths are absolute paths separated by semicolons(;).\r\n        String SearchPaths;\r\n\r\n        // If the search paths provided are exclusive.\r\n        Boolean SearchPathsExclusive;\r\n\r\n        // Defines the type of detail probing that is allowed when finding unit processors.\r\n        ConfigurationUnitDetailFlags UnitDetailFlags;\r\n    }\r\n\r\n    // Find unit processors.\r\n    [contract(Microsoft.Management.Configuration.Contract, 4)]\r\n    interface IFindUnitProcessorsSetProcessor requires IConfigurationSetProcessor\r\n    {\r\n        // Find unit processors.\r\n        Windows.Foundation.Collections.IVector<IConfigurationUnitProcessorDetails> FindUnitProcessors(FindUnitProcessorsOptions findOptions);\r\n    }\r\n\r\n    // The result of applying an individual unit settings with an IConfigurationGroupProcessor.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    interface IApplyGroupMemberSettingsResult\r\n    {\r\n        // The configuration unit.\r\n        ConfigurationUnit Unit{ get; };\r\n\r\n        // The state of the unit.\r\n        // Properties other than `Unit` are not valid unless this value is `Completed`.\r\n        ConfigurationUnitState State{ get; };\r\n\r\n        // Will be true if the configuration unit was in the desired state (Test returns true) prior to the apply action.\r\n        Boolean PreviouslyInDesiredState{ get; };\r\n\r\n        // Indicates whether a reboot is required after the settings were applied.\r\n        Boolean RebootRequired{ get; };\r\n\r\n        // The result of applying the configuration unit.\r\n        IConfigurationUnitResultInformation ResultInformation{ get; };\r\n    }\r\n\r\n    // The result of applying the settings with an IConfigurationGroupProcessor.\r\n    [contract(Microsoft.Management.Configuration.Contract, 2)]\r\n    interface IApplyGroupSettingsResult\r\n    {\r\n        // The configuration group object (set or unit).\r\n        Object Group{ get; };\r\n\r\n        // Indicates whether a reboot is required after the settings were applied.\r\n        Boolean RebootRequired{ get; };\r\n\r\n        // The result of applying the configuration unit group.\r\n        IConfigurationUnitResultInformation ResultInformation{ get; };\r\n\r\n        // Results for each configuration unit in the group.\r\n        Windows.Foundation.Collections.IVector<IApplyGroupMemberSettingsResult> UnitResults{ get; };\r\n    }\r\n\r\n    // The result of testing the settings with an IConfigurationGroupProcessor.\r\n    [contract(Microsoft.Management.Configuration.Contract, 2)]\r\n    interface ITestGroupSettingsResult\r\n    {\r\n        // The configuration group object (set or unit).\r\n        Object Group{ get; };\r\n\r\n        // The result (if any) of running Test on the configuration unit group.\r\n        ConfigurationTestResult TestResult{ get; };\r\n\r\n        // The result of testing the configuration unit group.\r\n        // This is not the response for the test, but rather contains information about the actual attempt to run the test.\r\n        IConfigurationUnitResultInformation ResultInformation{ get; };\r\n\r\n        // Results for each configuration unit in the group.\r\n        Windows.Foundation.Collections.IVector<ITestSettingsResult> UnitResults{ get; };\r\n    }\r\n\r\n    // Provides access to a specific configuration unit group within the runtime.\r\n    // An object returned by `CreateUnitProcessor` or `CreateSetProcessor` can implement this interface to indicate that it can take\r\n    // the responsibility of executing the units that it contains.\r\n    [contract(Microsoft.Management.Configuration.Contract, 2)]\r\n    interface IConfigurationGroupProcessor\r\n    {\r\n        // The configuration group object (set or unit).\r\n        Object Group{ get; };\r\n\r\n        // Determines if the system is already in the state described by the configuration unit group.\r\n        // Progress is expected for every descendant unit and finally the group unit itself.\r\n        Windows.Foundation.IAsyncOperation<ITestGroupSettingsResult> TestGroupSettingsAsync(Windows.Foundation.EventHandler<ITestSettingsResult> progressHandler);\r\n\r\n        // Applies the state described in the configuration unit group.\r\n        // Progress is expected for every descendant unit and finally the group unit itself.\r\n        Windows.Foundation.IAsyncOperation<IApplyGroupSettingsResult> ApplyGroupSettingsAsync(Windows.Foundation.EventHandler<IApplyGroupMemberSettingsResult> progressHandler);\r\n    }\r\n\r\n    // The level of the diagnostic information.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    enum DiagnosticLevel\r\n    {\r\n        Verbose,\r\n        Informational,\r\n        Warning,\r\n        Error,\r\n        Critical,\r\n    };\r\n\r\n    // Enables diagnostic information from the configuration system to be inspected/stored by callers.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    interface IDiagnosticInformation\r\n    {\r\n        // Indicates the importance of the diagnostic information.\r\n        DiagnosticLevel Level{ get; };\r\n\r\n        // The diagnostic message.\r\n        String Message{ get; };\r\n    }\r\n\r\n    // Allows different runtimes to provide specialized handling of configuration processing.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    interface IConfigurationSetProcessorFactory\r\n    {\r\n        // Creates a configuration set processor for the given set.\r\n        IConfigurationSetProcessor CreateSetProcessor(ConfigurationSet configurationSet);\r\n\r\n        // Diagnostics event; useful for logging and/or verbose output.\r\n        event Windows.Foundation.EventHandler<IDiagnosticInformation> Diagnostics;\r\n\r\n        // Indicates the minimum importance desired for diagnostics.\r\n        DiagnosticLevel MinimumLevel;\r\n    }\r\n\r\n    // The change event type that has occurred.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    enum ConfigurationChangeEventType\r\n    {\r\n        Unknown,\r\n        SetAdded,\r\n        SetStateChanged,\r\n        SetRemoved,\r\n    };\r\n\r\n    // The change data sent about changes to sets.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    runtimeclass ConfigurationChangeData\r\n    {\r\n        // The change event type that occurred.\r\n        ConfigurationChangeEventType Change{ get; };\r\n\r\n        // The identifier used to uniquely identify the instance of a configuration set on the system.\r\n        Guid InstanceIdentifier{ get; };\r\n\r\n        // The state of the configuration set for this event (the ConfigurationSet can be used to get the current state, which may be different).\r\n        ConfigurationSetState State{ get; };\r\n    }\r\n\r\n    // The result of calling OpenConfigurationSet, containing either the set or details about the failure.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    runtimeclass OpenConfigurationSetResult\r\n    {\r\n        // The configuration set if successful; null otherwise.\r\n        ConfigurationSet Set{ get; };\r\n\r\n        // The result from opening the set.\r\n        HRESULT ResultCode{ get; };\r\n\r\n        // The field that is missing/invalid, if appropriate for the specific ResultCode.\r\n        String Field{ get; };\r\n\r\n        // The value of the field, if appropriate for the specific ResultCode.\r\n        String Value{ get; };\r\n\r\n        // The line number for the failure reason, if determined.\r\n        UInt32 Line{ get; };\r\n\r\n        // The column number for the failure reason, if determined.\r\n        UInt32 Column{ get; };\r\n    }\r\n\r\n    // The type of conflict between configuration sets that was detected.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    enum ConfigurationConflictType\r\n    {\r\n        Unknown,\r\n        // Indicates that the first configuration set has a matching name and origin to the second, which has already been applied.\r\n        // This is likely an update to the existing set, and should be applied as such, rather than an entirely new set.\r\n        MatchingOrigin,\r\n        // Indicates that the first configuration set is identical to the second, which has already been applied.\r\n        // This is based solely on the configuration unit settings.\r\n        IdenticalSetApplied,\r\n        // Indicates a conflict between the settings of two configuration units.\r\n        SettingsConflict,\r\n    };\r\n\r\n    // Describes a conflict between a setting of two configuration units.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    runtimeclass ConfigurationConflictSetting\r\n    {\r\n        // The name of the setting.\r\n        String Name{ get; };\r\n\r\n        // The value from the first configuration unit.\r\n        // These are the values from a `ValueSet`, and are thus required to be a `PropertyValue` or a 'ValueSet`.\r\n        Object FirstValue{ get; };\r\n\r\n        // The value from the second configuration unit.\r\n        // These are the values from a `ValueSet`, and are thus required to be a `PropertyValue` or a 'ValueSet`.\r\n        Object SecondValue{ get; };\r\n    }\r\n\r\n    // Describes a conflict between two configuration sets.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    runtimeclass ConfigurationConflict\r\n    {\r\n        // The type of conflict detected.\r\n        ConfigurationConflictType Conflict{ get; };\r\n\r\n        // The first of the configuration sets involved in the conflict.\r\n        ConfigurationSet FirstSet{ get; };\r\n\r\n        // The second of the configuration sets involved in the conflict.\r\n        ConfigurationSet SecondSet{ get; };\r\n\r\n        // The first of the configuration units involved in the conflict.\r\n        ConfigurationUnit FirstUnit{ get; };\r\n\r\n        // The second of the configuration units involved in the conflict.\r\n        ConfigurationUnit SecondUnit{ get; };\r\n\r\n        // Contains information about the particular settings that are conflicting.\r\n        Windows.Foundation.Collections.IVectorView<ConfigurationConflictSetting> Settings{ get; };\r\n    }\r\n\r\n    // The result of getting the configuration unit details.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    runtimeclass GetConfigurationUnitDetailsResult\r\n    {\r\n        // The configuration unit whose details were retrieved.\r\n        ConfigurationUnit Unit{ get; };\r\n\r\n        // The details, if they were able to be acquired successfully.\r\n        IConfigurationUnitProcessorDetails Details{ get; };\r\n\r\n        // The result of getting the configuration unit details.\r\n        IConfigurationUnitResultInformation ResultInformation{ get; };\r\n    }\r\n\r\n    // The result of getting the configuration set details.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    runtimeclass GetConfigurationSetDetailsResult\r\n    {\r\n        // The configuration unit whose details were retrieved.\r\n        Windows.Foundation.Collections.IVectorView<GetConfigurationUnitDetailsResult> UnitResults{ get; };\r\n    }\r\n\r\n    // Flags to control how a configuration set should be applied to the system.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    [flags]\r\n    enum ApplyConfigurationSetFlags\r\n    {\r\n        None = 0x0,\r\n        // Forces a new configuration set instance to be recorded when the set being applied matches a previous set's origin.\r\n        // The default behavior is to assume that the incoming set is an update to the existing set and overwrite it.\r\n        DoNotOverwriteMatchingOriginSet = 0x1,\r\n        // Does not apply the configuration set, only checks the configuration set for internal consistency.\r\n        PerformConsistencyCheckOnly = 0x2,\r\n    };\r\n\r\n    // The result of applying the settings for a configuration unit.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    runtimeclass ApplyConfigurationUnitResult\r\n    {\r\n        // The configuration unit that was applied.\r\n        ConfigurationUnit Unit{ get; };\r\n\r\n        // The state of the configuration unit with regards to the current execution of ApplySet.\r\n        ConfigurationUnitState State{ get; };\r\n\r\n        // Will be true if the configuration unit was in the desired state (Test returns true) prior to the apply action.\r\n        Boolean PreviouslyInDesiredState{ get; };\r\n\r\n        // Indicates whether a reboot is required after the configuration unit was applied.\r\n        Boolean RebootRequired{ get; };\r\n\r\n        // The result of applying the configuration unit.\r\n        IConfigurationUnitResultInformation ResultInformation{ get; };\r\n    }\r\n\r\n    // The result of applying the settings for a configuration set.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    runtimeclass ApplyConfigurationSetResult\r\n    {\r\n        // Results for each configuration unit in the set.\r\n        Windows.Foundation.Collections.IVectorView<ApplyConfigurationUnitResult> UnitResults{ get; };\r\n\r\n        // The overall result from applying the configuration set.\r\n        HRESULT ResultCode{ get; };\r\n    }\r\n\r\n    // The result of testing the settings for a configuration unit.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    runtimeclass TestConfigurationUnitResult\r\n    {\r\n        // The configuration unit that was tested.\r\n        ConfigurationUnit Unit{ get; };\r\n\r\n        // The result of testing the configuration unit.\r\n        // This is not the response for the test, but rather contains information about the actual attempt to run the test.\r\n        IConfigurationUnitResultInformation ResultInformation{ get; };\r\n\r\n        // The result (if any) of running Test on the configuration unit.\r\n        ConfigurationTestResult TestResult{ get; };\r\n    }\r\n\r\n    // The result of testing the settings for a configuration set.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    runtimeclass TestConfigurationSetResult\r\n    {\r\n        // Results for each configuration unit in the set.\r\n        Windows.Foundation.Collections.IVectorView<TestConfigurationUnitResult> UnitResults{ get; };\r\n\r\n        // The result (if any) of running Test on the configuration set.\r\n        // If this value is NotRun, every unit result will be NotRun.\r\n        // If this value is Positive, every unit result will be Positive (or NotRun with at least one being Positive).\r\n        // Any Negative result for a unit will result in this value being Negative.\r\n        // Any Failed result for a unit will result in this value being Failed (overriding the Negative statement above).\r\n        ConfigurationTestResult TestResult{ get; };\r\n    }\r\n\r\n    // The result of getting the settings for a configuration unit.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    runtimeclass GetConfigurationUnitSettingsResult\r\n    {\r\n        // The result of getting the configuration unit settings.\r\n        // This is not the response for the retrieval, but rather contains information about the actual attempt to retrieve the settings.\r\n        IConfigurationUnitResultInformation ResultInformation{ get; };\r\n\r\n        // The current state of the system for the configuration unit.\r\n        Windows.Foundation.Collections.ValueSet Settings { get; };\r\n    }\r\n\r\n    // The result of getting the settings for all the instances of a configuration unit.\r\n    [contract(Microsoft.Management.Configuration.Contract, 2)]\r\n    runtimeclass GetAllConfigurationUnitSettingsResult\r\n    {\r\n        // The result of getting the settings for all the instances of the configuration unit.\r\n        // This is not the response for the retrieval, but rather contains information about the actual attempt to retrieve the settings.\r\n        IConfigurationUnitResultInformation ResultInformation{ get; };\r\n\r\n        // The current state of the system for all the instances of the configuration unit.\r\n        Windows.Foundation.Collections.IVector<Windows.Foundation.Collections.ValueSet> Settings { get; };\r\n    }\r\n\r\n    // The result of getting the all units for a configuration unit.\r\n    [contract(Microsoft.Management.Configuration.Contract, 4)]\r\n    runtimeclass GetAllConfigurationUnitsResult\r\n    {\r\n        // The result of getting the all units for a configuration unit.\r\n        // This is not the response for the retrieval, but rather contains information about the actual attempt to retrieve the settings.\r\n        IConfigurationUnitResultInformation ResultInformation{ get; };\r\n\r\n        // The units retrieved for the given unit.\r\n        Windows.Foundation.Collections.IVector<ConfigurationUnit> Units { get; };\r\n    }\r\n\r\n    // The configuration processor is responsible for the interactions with the system.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    runtimeclass ConfigurationProcessor\r\n    {\r\n        ConfigurationProcessor(IConfigurationSetProcessorFactory factory);\r\n\r\n        // Diagnostics event; useful for logging and/or verbose output.\r\n        event Windows.Foundation.EventHandler<IDiagnosticInformation> Diagnostics;\r\n\r\n        // Indicates the minimum importance desired for diagnostics.\r\n        DiagnosticLevel MinimumLevel;\r\n\r\n        // Set the caller to used to identify the usage in telemetry events.\r\n        String Caller;\r\n\r\n        // The identifier for the current activity, enabling multiple calls into the processor to be correlated.\r\n        Guid ActivityIdentifier;\r\n\r\n        // If true, ETW events will be generated. Some of those events may be sent to Microsoft depending on the system settings.\r\n        Boolean GenerateTelemetryEvents;\r\n\r\n        // Only top level configuration changes are sent to this event.\r\n        // This includes things like: creation of a new set for intent to run, start/stop of a set for application, deletion of a not started set.\r\n        event Windows.Foundation.TypedEventHandler<ConfigurationSet, ConfigurationChangeData> ConfigurationChange;\r\n\r\n        // Gets the configuration sets that have already been applied or with the intent to be applied (this may include in progress sets or those that are waiting on others).\r\n        Windows.Foundation.Collections.IVector<ConfigurationSet> GetConfigurationHistory();\r\n        Windows.Foundation.IAsyncOperation< Windows.Foundation.Collections.IVector<ConfigurationSet> > GetConfigurationHistoryAsync();\r\n\r\n        // Loads a configuration set from the given stream.\r\n        OpenConfigurationSetResult OpenConfigurationSet(Windows.Storage.Streams.IInputStream stream);\r\n        Windows.Foundation.IAsyncOperation<OpenConfigurationSetResult> OpenConfigurationSetAsync(Windows.Storage.Streams.IInputStream stream);\r\n\r\n        // Checks for conflicts amongst the configuration sets provided, optionally including the configuration sets already applied to the system.\r\n        Windows.Foundation.Collections.IVector<ConfigurationConflict> CheckForConflicts(Windows.Foundation.Collections.IVectorView<ConfigurationSet> configurationSets, Boolean includeConfigurationHistory);\r\n        Windows.Foundation.IAsyncOperation< Windows.Foundation.Collections.IVector<ConfigurationConflict> > CheckForConflictsAsync(Windows.Foundation.Collections.IVectorView<ConfigurationSet> configurationSets, Boolean includeConfigurationHistory);\r\n\r\n        // Gets the details for all configuration units in a set.\r\n        GetConfigurationSetDetailsResult GetSetDetails(ConfigurationSet configurationSet, ConfigurationUnitDetailFlags detailFlags);\r\n        Windows.Foundation.IAsyncOperationWithProgress<GetConfigurationSetDetailsResult, GetConfigurationUnitDetailsResult> GetSetDetailsAsync(ConfigurationSet configurationSet, ConfigurationUnitDetailFlags detailFlags);\r\n\r\n        // Gets the details for a configuration unit.\r\n        GetConfigurationUnitDetailsResult GetUnitDetails(ConfigurationUnit unit, ConfigurationUnitDetailFlags detailFlags);\r\n        Windows.Foundation.IAsyncOperation<GetConfigurationUnitDetailsResult> GetUnitDetailsAsync(ConfigurationUnit unit, ConfigurationUnitDetailFlags detailFlags);\r\n\r\n        // Applies the configuration set state.\r\n        ApplyConfigurationSetResult ApplySet(ConfigurationSet configurationSet, ApplyConfigurationSetFlags flags);\r\n        Windows.Foundation.IAsyncOperationWithProgress<ApplyConfigurationSetResult, ConfigurationSetChangeData> ApplySetAsync(ConfigurationSet configurationSet, ApplyConfigurationSetFlags flags);\r\n\r\n        // Tests the configuration set state.\r\n        TestConfigurationSetResult TestSet(ConfigurationSet configurationSet);\r\n        Windows.Foundation.IAsyncOperationWithProgress<TestConfigurationSetResult, TestConfigurationUnitResult> TestSetAsync(ConfigurationSet configurationSet);\r\n\r\n        // Gets the current configuration unit settings.\r\n        GetConfigurationUnitSettingsResult GetUnitSettings(ConfigurationUnit unit);\r\n        Windows.Foundation.IAsyncOperation<GetConfigurationUnitSettingsResult> GetUnitSettingsAsync(ConfigurationUnit unit);\r\n\r\n        [contract(Microsoft.Management.Configuration.Contract, 2)]\r\n        {\r\n            // Gets the current settings for all the instances of a configuration unit.\r\n            GetAllConfigurationUnitSettingsResult GetAllUnitSettings(ConfigurationUnit unit);\r\n            Windows.Foundation.IAsyncOperation<GetAllConfigurationUnitSettingsResult> GetAllUnitSettingsAsync(ConfigurationUnit unit);\r\n        }\r\n\r\n        [contract(Microsoft.Management.Configuration.Contract, 4)]\r\n        {\r\n            // Gets all configuration units for the given unit type.\r\n            // Returned units may be of types other than the one passed in.\r\n            GetAllConfigurationUnitsResult GetAllUnits(ConfigurationUnit unit);\r\n            Windows.Foundation.IAsyncOperation<GetAllConfigurationUnitsResult> GetAllUnitsAsync(ConfigurationUnit unit);\r\n\r\n            // Find unit processors.\r\n            Windows.Foundation.Collections.IVector<IConfigurationUnitProcessorDetails> FindUnitProcessors(FindUnitProcessorsOptions findOptions);\r\n            Windows.Foundation.IAsyncOperation< Windows.Foundation.Collections.IVector<IConfigurationUnitProcessorDetails> > FindUnitProcessorsAsync(FindUnitProcessorsOptions findOptions);\r\n\r\n            // Apply the current configuration unit.\r\n            ApplyConfigurationUnitResult ApplyUnit(ConfigurationUnit unit);\r\n            Windows.Foundation.IAsyncOperation<ApplyConfigurationUnitResult> ApplyUnitAsync(ConfigurationUnit unit);\r\n            \r\n            // Test the current configuration unit.\r\n            TestConfigurationUnitResult TestUnit(ConfigurationUnit unit);\r\n            Windows.Foundation.IAsyncOperation<TestConfigurationUnitResult> TestUnitAsync(ConfigurationUnit unit);\r\n        }\r\n    }\r\n\r\n    // Top level entry point for configuration, enabling easier usage in out-of-process scenarios.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    interface IConfigurationStatics\r\n    {\r\n        // Creates an empty configuration unit.\r\n        ConfigurationUnit CreateConfigurationUnit();\r\n\r\n        // Creates an empty configuration set.\r\n        ConfigurationSet CreateConfigurationSet();\r\n\r\n        // Creates a processor factory for the given handler.\r\n        Windows.Foundation.IAsyncOperation<IConfigurationSetProcessorFactory> CreateConfigurationSetProcessorFactoryAsync(String handler);\r\n\r\n        // Creates a processor from the given factory.\r\n        ConfigurationProcessor CreateConfigurationProcessor(IConfigurationSetProcessorFactory factory);\r\n\r\n        // Whether configuration is enabled.\r\n        Boolean IsConfigurationAvailable{ get; };\r\n\r\n        // Enables configuration. Requires store access.\r\n        Windows.Foundation.IAsyncActionWithProgress<UInt32> EnsureConfigurationAvailableAsync();\r\n    }\r\n\r\n    // Top level entry point for configuration, enabling easier usage in out-of-process scenarios.\r\n    [contract(Microsoft.Management.Configuration.Contract, 2)]\r\n    interface IConfigurationStatics2 requires IConfigurationStatics\r\n    {\r\n        // Creates an empty configuration parameter.\r\n        ConfigurationParameter CreateConfigurationParameter();\r\n    }\r\n\r\n    // Top level entry point for configuration, enabling easier usage in out-of-process scenarios.\r\n    [contract(Microsoft.Management.Configuration.Contract, 4)]\r\n    interface IConfigurationStatics3 requires IConfigurationStatics2\r\n    {\r\n        // Creates an empty configuration parameter.\r\n        FindUnitProcessorsOptions CreateFindUnitProcessorsOptions();\r\n    }\r\n\r\n    // Top level entry point for configuration, enabling easier usage in out-of-process scenarios.\r\n    [contract(Microsoft.Management.Configuration.Contract, 1)]\r\n    runtimeclass ConfigurationStaticFunctions : [default]IConfigurationStatics, IConfigurationStatics2, IConfigurationStatics3\r\n    {\r\n        ConfigurationStaticFunctions();\r\n    }\r\n\r\n    /// Force midl3 to generate vector marshalling info.\r\n    declare\r\n    {\r\n        // Due to the way that metadata (WinMD) based marshalling works, in order for any of these to be IIterable<T>, they need to be\r\n        // included in the manifest of the package. Update the DumpProxyStubRegistrationsCommand to add any new types to make it easier\r\n        // to iterate over these collections, especially in C#.\r\n        interface Windows.Foundation.Collections.IVector<ConfigurationUnit>;\r\n        interface Windows.Foundation.Collections.IVector<ConfigurationSet>;\r\n        interface Windows.Foundation.Collections.IVector<ConfigurationConflict>;\r\n        interface Windows.Foundation.Collections.IVectorView<IConfigurationUnitSettingDetails>;\r\n        interface Windows.Foundation.Collections.IVectorView<ConfigurationConflictSetting>;\r\n        interface Windows.Foundation.Collections.IVectorView<GetConfigurationUnitDetailsResult>;\r\n        interface Windows.Foundation.Collections.IVectorView<ApplyConfigurationUnitResult>;\r\n        interface Windows.Foundation.Collections.IVectorView<TestConfigurationUnitResult>;\r\n        interface Windows.Foundation.Collections.IVectorView<ConfigurationSet>;\r\n        interface Windows.Foundation.Collections.IVector<ConfigurationEnvironment>;\r\n        interface Windows.Foundation.Collections.IVector<IConfigurationUnitProcessorDetails>;\r\n    }\r\n\r\n    // Provides a way to centralize the distribution of interfaces relevant to specific implementations of IConfigurationSetProcessorFactory.\r\n    namespace SetProcessorFactory\r\n    {\r\n        // The same as PowerShell ExecutionPolicy:\r\n        // https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_execution_policies\r\n        enum PwshConfigurationProcessorPolicy\r\n        {\r\n            Unrestricted = 0,\r\n            RemoteSigned = 1,\r\n            AllSigned = 2,\r\n            Restricted = 3,\r\n            Bypass = 4,\r\n            Undefined = 5,\r\n            Default = RemoteSigned,\r\n        };\r\n\r\n        enum PwshConfigurationProcessorLocation\r\n        {\r\n            CurrentUser = 0,\r\n            AllUsers = 1,\r\n            WinGetModulePath = 2,\r\n            Custom = 3,\r\n            Default = WinGetModulePath,\r\n        };\r\n\r\n        // The properties provided by the \"pwsh\" processor factory.\r\n        interface IPwshConfigurationSetProcessorFactoryProperties\r\n        {\r\n            // The module paths to add to the processor.\r\n            // This will be in addition to any paths added by the processor and those inherent to PowerShell.\r\n            Windows.Foundation.Collections.IVectorView<String> AdditionalModulePaths;\r\n\r\n            // The execution policy to apply; must be set before taking actions with the processor.\r\n            PwshConfigurationProcessorPolicy Policy;\r\n\r\n            // The location to install modules. Default is WinGetModulePath\r\n            PwshConfigurationProcessorLocation Location;\r\n\r\n            // The custom location. Only applicable for Scope.Custom\r\n            String CustomLocation;\r\n        };\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" />\r\n  <PropertyGroup Label=\"Globals\">\r\n    <CppWinRTOptimized>true</CppWinRTOptimized>\r\n    <CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>\r\n    <CppWinRTGenerateWindowsMetadata>true</CppWinRTGenerateWindowsMetadata>\r\n    <MinimalCoreWin>true</MinimalCoreWin>\r\n    <ProjectGuid>{CA460806-5E41-4E97-9A3D-1D74B433B663}</ProjectGuid>\r\n    <ProjectName>Microsoft.Management.Configuration</ProjectName>\r\n    <RootNamespace>Microsoft.Management.Configuration</RootNamespace>\r\n    <DefaultLanguage>en-US</DefaultLanguage>\r\n    <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>\r\n    <ApplicationTypeRevision>10.0</ApplicationTypeRevision>\r\n    <WindowsTargetPlatformVersion>10.0.26100.0</WindowsTargetPlatformVersion>\r\n    <WindowsTargetPlatformMinVersion>10.0.17763.0</WindowsTargetPlatformMinVersion>\r\n    <WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|ARM64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|Win32\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|ARM64\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|Win32\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|x64\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|ARM64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|Win32\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <PropertyGroup Label=\"Configuration\">\r\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\r\n    <GenerateManifest>false</GenerateManifest>\r\n    <DesktopCompatible>true</DesktopCompatible>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Debug'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n    <LinkIncremental>true</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Release'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='ReleaseStatic'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\r\n  <ImportGroup Label=\"ExtensionSettings\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"PropertySheet.props\" />\r\n  </ImportGroup>\r\n  <PropertyGroup Label=\"UserMacros\" />\r\n  <PropertyGroup>\r\n    <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>\r\n    <OutDir>$(SolutionDir)$(PlatformTarget)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <IntDir>$(PlatformTarget)\\$(Configuration)\\</IntDir>\r\n    <TargetName>$(RootNamespace)</TargetName>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>true</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(ProjectDir)\\..\\vcpkg.props\" />\r\n  <ItemDefinitionGroup>\r\n    <ClCompile>\r\n      <PrecompiledHeader>Use</PrecompiledHeader>\r\n      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>\r\n      <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <AdditionalOptions>%(AdditionalOptions) /bigobj</AdditionalOptions>\r\n      <TreatWarningAsError>true</TreatWarningAsError>\r\n      <SDLCheck>true</SDLCheck>\r\n      <PreprocessorDefinitions>_WINRT_DLL;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>\r\n      <AdditionalIncludeDirectories>$(ProjectDir);$(ProjectDir)..\\AppInstallerSharedLib\\Public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <ModuleDefinitionFile>Microsoft_Management_Configuration.def</ModuleDefinitionFile>\r\n      <WindowsMetadataFile>$(OutDir)$(ProjectName).winmd</WindowsMetadataFile>\r\n      <AdditionalDependencies>Advapi32.lib;icuuc.lib;icuin.lib;onecoreuap.lib;winsqlite3.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Debug'\">\r\n    <ClCompile>\r\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</RuntimeTypeInfo>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">false</ControlFlowGuard>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</ControlFlowGuard>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</ControlFlowGuard>\r\n    </ClCompile>\r\n    <Link>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</CETCompat>\r\n    </Link>\r\n    <Link>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</CETCompat>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Release'\">\r\n    <ClCompile>\r\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</RuntimeTypeInfo>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">Guard</ControlFlowGuard>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Guard</ControlFlowGuard>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Guard</ControlFlowGuard>\r\n    </ClCompile>\r\n    <Link>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <AdditionalOptions Condition=\"'$(ForceDebugTypeCVFixup)'=='true'\">/debugtype:cv,fixup /incremental:no %(AdditionalOptions)</AdditionalOptions>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">/debug:full %(AdditionalOptions)</AdditionalOptions>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">/debug:full %(AdditionalOptions)</AdditionalOptions>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">/debug:full %(AdditionalOptions)</AdditionalOptions>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</CETCompat>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">true</CETCompat>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='ReleaseStatic'\">\r\n    <ClCompile>\r\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">false</RuntimeTypeInfo>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">MultiThreaded</RuntimeLibrary>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">MultiThreaded</RuntimeLibrary>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">MultiThreaded</RuntimeLibrary>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">Guard</ControlFlowGuard>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">Guard</ControlFlowGuard>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">Guard</ControlFlowGuard>\r\n    </ClCompile>\r\n    <Link>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">true</CETCompat>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">true</CETCompat>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"ApplyConfigurationSetResult.h\" />\r\n    <ClInclude Include=\"ApplyConfigurationUnitResult.h\" />\r\n    <ClInclude Include=\"ApplyGroupSettingsResult.h\" />\r\n    <ClInclude Include=\"ArgumentValidation.h\" />\r\n    <ClInclude Include=\"ConfigThreadGlobals.h\" />\r\n    <ClInclude Include=\"ConfigurationChangeData.h\" />\r\n    <ClInclude Include=\"ConfigurationConflict.h\" />\r\n    <ClInclude Include=\"ConfigurationConflictSetting.h\" />\r\n    <ClInclude Include=\"ConfigurationEnvironment.h\" />\r\n    <ClInclude Include=\"ConfigurationParameter.h\" />\r\n    <ClInclude Include=\"ConfigurationProcessor.h\" />\r\n    <ClInclude Include=\"ConfigurationSequencer.h\" />\r\n    <ClInclude Include=\"ConfigurationSet.h\" />\r\n    <ClInclude Include=\"ConfigurationSetApplyProcessor.h\" />\r\n    <ClInclude Include=\"ConfigurationSetChangeData.h\" />\r\n    <ClInclude Include=\"ConfigurationSetParser.h\" />\r\n    <ClInclude Include=\"ConfigurationSetParserError.h\" />\r\n    <ClInclude Include=\"ConfigurationSetParser_0_1.h\" />\r\n    <ClInclude Include=\"ConfigurationSetParser_0_2.h\" />\r\n    <ClInclude Include=\"ConfigurationSetParser_0_3.h\" />\r\n    <ClInclude Include=\"ConfigurationSetSerializer.h\" />\r\n    <ClInclude Include=\"ConfigurationSetSerializer_0_2.h\" />\r\n    <ClInclude Include=\"ConfigurationSetSerializer_0_3.h\" />\r\n    <ClInclude Include=\"ConfigurationSetUtilities.h\" />\r\n    <ClInclude Include=\"ConfigurationStaticFunctions.h\" />\r\n    <ClInclude Include=\"ConfigurationStatus.h\" />\r\n    <ClInclude Include=\"ConfigurationUnit.h\" />\r\n    <ClInclude Include=\"ConfigurationUnitResultInformation.h\" />\r\n    <ClInclude Include=\"Database\\ConfigurationDatabase.h\" />\r\n    <ClInclude Include=\"Database\\Schema\\0_1\\Interface.h\" />\r\n    <ClInclude Include=\"Database\\Schema\\0_1\\SetInfoTable.h\" />\r\n    <ClInclude Include=\"Database\\Schema\\0_1\\UnitInfoTable.h\" />\r\n    <ClInclude Include=\"Database\\Schema\\0_2\\Interface.h\" />\r\n    <ClInclude Include=\"Database\\Schema\\0_2\\QueueTable.h\" />\r\n    <ClInclude Include=\"Database\\Schema\\0_3\\ChangeListenerTable.h\" />\r\n    <ClInclude Include=\"Database\\Schema\\0_3\\Interface.h\" />\r\n    <ClInclude Include=\"Database\\Schema\\0_3\\StatusItemTable.h\" />\r\n    <ClInclude Include=\"Database\\Schema\\IConfigurationDatabase.h\" />\r\n    <ClInclude Include=\"DefaultSetGroupProcessor.h\" />\r\n    <ClInclude Include=\"DiagnosticInformationInstance.h\" />\r\n    <ClInclude Include=\"ExceptionResultHelpers.h\" />\r\n    <ClInclude Include=\"Filesystem.h\" />\r\n    <ClInclude Include=\"FindUnitProcessorsOptions.h\" />\r\n    <ClInclude Include=\"GetAllConfigurationUnitSettingsResult.h\" />\r\n    <ClInclude Include=\"GetAllConfigurationUnitsResult.h\" />\r\n    <ClInclude Include=\"GetConfigurationSetDetailsResult.h\" />\r\n    <ClInclude Include=\"GetConfigurationUnitDetailsResult.h\" />\r\n    <ClInclude Include=\"GetConfigurationUnitSettingsResult.h\" />\r\n    <ClInclude Include=\"OpenConfigurationSetResult.h\" />\r\n    <ClInclude Include=\"ParsingMacros.h\" />\r\n    <ClInclude Include=\"pch.h\" />\r\n    <ClInclude Include=\"ShutdownSynchronization.h\" />\r\n    <ClInclude Include=\"Telemetry\\Telemetry.h\" />\r\n    <ClInclude Include=\"Telemetry\\TraceLogging.h\" />\r\n    <ClInclude Include=\"TestConfigurationSetResult.h\" />\r\n    <ClInclude Include=\"TestConfigurationUnitResult.h\" />\r\n    <ClInclude Include=\"TestGroupSettingsResult.h\" />\r\n    <ClInclude Include=\"TestSettingsResult.h\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"ApplyConfigurationSetResult.cpp\" />\r\n    <ClCompile Include=\"ApplyConfigurationUnitResult.cpp\" />\r\n    <ClCompile Include=\"ApplyGroupSettingsResult.cpp\" />\r\n    <ClCompile Include=\"ArgumentValidation.cpp\" />\r\n    <ClCompile Include=\"ConfigThreadGlobals.cpp\" />\r\n    <ClCompile Include=\"ConfigurationChangeData.cpp\" />\r\n    <ClCompile Include=\"ConfigurationConflict.cpp\" />\r\n    <ClCompile Include=\"ConfigurationConflictSetting.cpp\" />\r\n    <ClCompile Include=\"ConfigurationEnvironment.cpp\" />\r\n    <ClCompile Include=\"ConfigurationParameter.cpp\" />\r\n    <ClCompile Include=\"ConfigurationProcessor.cpp\" />\r\n    <ClCompile Include=\"ConfigurationSequencer.cpp\" />\r\n    <ClCompile Include=\"ConfigurationSet.cpp\" />\r\n    <ClCompile Include=\"ConfigurationSetApplyProcessor.cpp\" />\r\n    <ClCompile Include=\"ConfigurationSetChangeData.cpp\" />\r\n    <ClCompile Include=\"ConfigurationSetParser.cpp\" />\r\n    <ClCompile Include=\"ConfigurationSetParser_0_1.cpp\" />\r\n    <ClCompile Include=\"ConfigurationSetParser_0_2.cpp\" />\r\n    <ClCompile Include=\"ConfigurationSetParser_0_3.cpp\" />\r\n    <ClCompile Include=\"ConfigurationSetSerializer.cpp\" />\r\n    <ClCompile Include=\"ConfigurationSetSerializer_0_2.cpp\" />\r\n    <ClCompile Include=\"ConfigurationSetSerializer_0_3.cpp\" />\r\n    <ClCompile Include=\"ConfigurationSetUtilities.cpp\" />\r\n    <ClCompile Include=\"ConfigurationStaticFunctions.cpp\" />\r\n    <ClCompile Include=\"ConfigurationStatus.cpp\" />\r\n    <ClCompile Include=\"ConfigurationUnit.cpp\" />\r\n    <ClCompile Include=\"ConfigurationUnitResultInformation.cpp\" />\r\n    <ClCompile Include=\"Database\\ConfigurationDatabase.cpp\" />\r\n    <ClCompile Include=\"Database\\Schema\\0_1\\Interface_0_1.cpp\" />\r\n    <ClCompile Include=\"Database\\Schema\\0_1\\SetInfoTable.cpp\" />\r\n    <ClCompile Include=\"Database\\Schema\\0_1\\UnitInfoTable.cpp\" />\r\n    <ClCompile Include=\"Database\\Schema\\0_2\\Interface_0_2.cpp\" />\r\n    <ClCompile Include=\"Database\\Schema\\0_2\\QueueTable.cpp\" />\r\n    <ClCompile Include=\"Database\\Schema\\0_3\\ChangeListenerTable.cpp\" />\r\n    <ClCompile Include=\"Database\\Schema\\0_3\\Interface_0_3.cpp\" />\r\n    <ClCompile Include=\"Database\\Schema\\0_3\\StatusItemTable.cpp\" />\r\n    <ClCompile Include=\"Database\\Schema\\IConfigurationDatabase.cpp\" />\r\n    <ClCompile Include=\"DefaultSetGroupProcessor.cpp\" />\r\n    <ClCompile Include=\"DiagnosticInformationInstance.cpp\" />\r\n    <ClCompile Include=\"Filesystem.cpp\" />\r\n    <ClCompile Include=\"FindUnitProcessorsOptions.cpp\" />\r\n    <ClCompile Include=\"GetAllConfigurationUnitSettingsResult.cpp\" />\r\n    <ClCompile Include=\"GetAllConfigurationUnitsResult.cpp\" />\r\n    <ClCompile Include=\"GetConfigurationSetDetailsResult.cpp\" />\r\n    <ClCompile Include=\"GetConfigurationUnitDetailsResult.cpp\" />\r\n    <ClCompile Include=\"GetConfigurationUnitSettingsResult.cpp\" />\r\n    <ClCompile Include=\"OpenConfigurationSetResult.cpp\" />\r\n    <ClCompile Include=\"pch.cpp\">\r\n      <PrecompiledHeader>Create</PrecompiledHeader>\r\n    </ClCompile>\r\n    <ClCompile Include=\"$(GeneratedFilesDir)module.g.cpp\" />\r\n    <ClCompile Include=\"ShutdownSynchronization.cpp\" />\r\n    <ClCompile Include=\"Telemetry\\Telemetry.cpp\" />\r\n    <ClCompile Include=\"Telemetry\\TraceLogging.cpp\" />\r\n    <ClCompile Include=\"TestConfigurationSetResult.cpp\" />\r\n    <ClCompile Include=\"TestConfigurationUnitResult.cpp\" />\r\n    <ClCompile Include=\"TestGroupSettingsResult.cpp\" />\r\n    <ClCompile Include=\"TestSettingsResult.cpp\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"Microsoft_Management_Configuration.def\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"packages.config\" />\r\n    <None Include=\"PropertySheet.props\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Midl Include=\"Microsoft.Management.Configuration.idl\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\AppInstallerSharedLib\\AppInstallerSharedLib.vcxproj\">\r\n      <Project>{f3f6e699-bc5d-4950-8a05-e49dd9eb0d51}</Project>\r\n    </ProjectReference>\r\n  </ItemGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\r\n  <ImportGroup Label=\"ExtensionTargets\">\r\n    <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" />\r\n    <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets')\" />\r\n  </ImportGroup>\r\n  <Target Name=\"EnsureNuGetPackageBuildImports\" BeforeTargets=\"PrepareForBuild\">\r\n    <PropertyGroup>\r\n      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>\r\n    </PropertyGroup>\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props'))\" />\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets'))\" />\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets'))\" />\r\n  </Target>\r\n</Project>\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup>\r\n    <ClCompile Include=\"pch.cpp\" />\r\n    <ClCompile Include=\"$(GeneratedFilesDir)module.g.cpp\" />\r\n    <ClCompile Include=\"ApplyConfigurationSetResult.cpp\">\r\n      <Filter>API Source</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ApplyConfigurationUnitResult.cpp\">\r\n      <Filter>API Source</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationChangeData.cpp\">\r\n      <Filter>API Source</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationConflict.cpp\">\r\n      <Filter>API Source</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationConflictSetting.cpp\">\r\n      <Filter>API Source</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationSet.cpp\">\r\n      <Filter>API Source</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationSetChangeData.cpp\">\r\n      <Filter>API Source</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationUnit.cpp\">\r\n      <Filter>API Source</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"GetConfigurationUnitSettingsResult.cpp\">\r\n      <Filter>API Source</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"TestConfigurationSetResult.cpp\">\r\n      <Filter>API Source</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"TestConfigurationUnitResult.cpp\">\r\n      <Filter>API Source</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationProcessor.cpp\">\r\n      <Filter>API Source</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationSetParser.cpp\">\r\n      <Filter>Parser</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationSetParser_0_1.cpp\">\r\n      <Filter>Parser</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"OpenConfigurationSetResult.cpp\">\r\n      <Filter>API Source</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigThreadGlobals.cpp\">\r\n      <Filter>Internals</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationSetApplyProcessor.cpp\">\r\n      <Filter>Internals</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"GetConfigurationUnitDetailsResult.cpp\">\r\n      <Filter>API Source</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"GetConfigurationSetDetailsResult.cpp\">\r\n      <Filter>API Source</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Telemetry\\TraceLogging.cpp\">\r\n      <Filter>Telemetry</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Telemetry\\Telemetry.cpp\">\r\n      <Filter>Telemetry</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationSetParser_0_2.cpp\">\r\n      <Filter>Parser</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationUnitResultInformation.cpp\">\r\n      <Filter>Internals</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationStaticFunctions.cpp\">\r\n      <Filter>API Source</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"DiagnosticInformationInstance.cpp\">\r\n      <Filter>Internals</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"GetAllConfigurationUnitSettingsResult.cpp\">\r\n      <Filter>API Source</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationParameter.cpp\">\r\n      <Filter>API Source</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ArgumentValidation.cpp\">\r\n      <Filter>Internals</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationSetParser_0_3.cpp\">\r\n      <Filter>Parser</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"DefaultSetGroupProcessor.cpp\">\r\n      <Filter>Internals</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"TestGroupSettingsResult.cpp\">\r\n      <Filter>Internals</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"TestSettingsResult.cpp\">\r\n      <Filter>Internals</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ApplyGroupSettingsResult.cpp\">\r\n      <Filter>Internals</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationSetSerializer.cpp\">\r\n      <Filter>Parser</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationSetSerializer_0_2.cpp\">\r\n      <Filter>Parser</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationSetUtilities.cpp\">\r\n      <Filter>Parser</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Database\\ConfigurationDatabase.cpp\">\r\n      <Filter>Database</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Database\\Schema\\IConfigurationDatabase.cpp\">\r\n      <Filter>Database\\Schema</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Database\\Schema\\0_1\\Interface_0_1.cpp\">\r\n      <Filter>Database\\Schema\\0_1</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Filesystem.cpp\">\r\n      <Filter>Internals</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Database\\Schema\\0_1\\SetInfoTable.cpp\">\r\n      <Filter>Database\\Schema\\0_1</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Database\\Schema\\0_1\\UnitInfoTable.cpp\">\r\n      <Filter>Database\\Schema\\0_1</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationSequencer.cpp\">\r\n      <Filter>Internals</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Database\\Schema\\0_2\\Interface_0_2.cpp\">\r\n      <Filter>Database\\Schema\\0_2</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Database\\Schema\\0_2\\QueueTable.cpp\">\r\n      <Filter>Database\\Schema\\0_2</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationStatus.cpp\">\r\n      <Filter>Internals</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Database\\Schema\\0_3\\Interface_0_3.cpp\">\r\n      <Filter>Database\\Schema\\0_3</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Database\\Schema\\0_3\\ChangeListenerTable.cpp\">\r\n      <Filter>Database\\Schema\\0_3</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Database\\Schema\\0_3\\StatusItemTable.cpp\">\r\n      <Filter>Database\\Schema\\0_3</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationSetSerializer_0_3.cpp\">\r\n      <Filter>Parser</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ConfigurationEnvironment.cpp\">\r\n      <Filter>API Source</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"GetAllConfigurationUnitsResult.cpp\">\r\n      <Filter>API Source</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"FindUnitProcessorsOptions.cpp\">\r\n      <Filter>API Source</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"ShutdownSynchronization.cpp\">\r\n      <Filter>Internals</Filter>\r\n    </ClCompile>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"pch.h\" />\r\n    <ClInclude Include=\"ApplyConfigurationSetResult.h\">\r\n      <Filter>API Headers</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ApplyConfigurationUnitResult.h\">\r\n      <Filter>API Headers</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationChangeData.h\">\r\n      <Filter>API Headers</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationConflict.h\">\r\n      <Filter>API Headers</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationConflictSetting.h\">\r\n      <Filter>API Headers</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationSet.h\">\r\n      <Filter>API Headers</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationSetChangeData.h\">\r\n      <Filter>API Headers</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationUnit.h\">\r\n      <Filter>API Headers</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"GetConfigurationUnitSettingsResult.h\">\r\n      <Filter>API Headers</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"TestConfigurationSetResult.h\">\r\n      <Filter>API Headers</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"TestConfigurationUnitResult.h\">\r\n      <Filter>API Headers</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationProcessor.h\">\r\n      <Filter>API Headers</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationSetParser.h\">\r\n      <Filter>Parser</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationSetParser_0_1.h\">\r\n      <Filter>Parser</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"OpenConfigurationSetResult.h\">\r\n      <Filter>API Headers</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationSetParserError.h\">\r\n      <Filter>Parser</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigThreadGlobals.h\">\r\n      <Filter>Internals</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationSetApplyProcessor.h\">\r\n      <Filter>Internals</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ExceptionResultHelpers.h\">\r\n      <Filter>Internals</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"GetConfigurationUnitDetailsResult.h\">\r\n      <Filter>API Headers</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"GetConfigurationSetDetailsResult.h\">\r\n      <Filter>API Headers</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Telemetry\\TraceLogging.h\">\r\n      <Filter>Telemetry</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Telemetry\\Telemetry.h\">\r\n      <Filter>Telemetry</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationSetParser_0_2.h\">\r\n      <Filter>Parser</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationUnitResultInformation.h\">\r\n      <Filter>Internals</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationStaticFunctions.h\">\r\n      <Filter>API Headers</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"DiagnosticInformationInstance.h\">\r\n      <Filter>Internals</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"GetAllConfigurationUnitSettingsResult.h\">\r\n      <Filter>API Headers</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationParameter.h\">\r\n      <Filter>API Headers</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ArgumentValidation.h\">\r\n      <Filter>Internals</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ParsingMacros.h\">\r\n      <Filter>Parser</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationSetParser_0_3.h\">\r\n      <Filter>Parser</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"DefaultSetGroupProcessor.h\">\r\n      <Filter>Internals</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"TestGroupSettingsResult.h\">\r\n      <Filter>Internals</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"TestSettingsResult.h\">\r\n      <Filter>Internals</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ApplyGroupSettingsResult.h\">\r\n      <Filter>Internals</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationSetUtilities.h\">\r\n      <Filter>Parser</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationSetSerializer.h\">\r\n      <Filter>Parser</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationSetSerializer_0_2.h\">\r\n      <Filter>Parser</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Database\\ConfigurationDatabase.h\">\r\n      <Filter>Database</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Database\\Schema\\IConfigurationDatabase.h\">\r\n      <Filter>Database\\Schema</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Database\\Schema\\0_1\\Interface.h\">\r\n      <Filter>Database\\Schema\\0_1</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Filesystem.h\">\r\n      <Filter>Internals</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Database\\Schema\\0_1\\SetInfoTable.h\">\r\n      <Filter>Database\\Schema\\0_1</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Database\\Schema\\0_1\\UnitInfoTable.h\">\r\n      <Filter>Database\\Schema\\0_1</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationSequencer.h\">\r\n      <Filter>Internals</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Database\\Schema\\0_2\\Interface.h\">\r\n      <Filter>Database\\Schema\\0_2</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Database\\Schema\\0_2\\QueueTable.h\">\r\n      <Filter>Database\\Schema\\0_2</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationStatus.h\">\r\n      <Filter>Internals</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Database\\Schema\\0_3\\Interface.h\">\r\n      <Filter>Database\\Schema\\0_3</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Database\\Schema\\0_3\\ChangeListenerTable.h\">\r\n      <Filter>Database\\Schema\\0_3</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Database\\Schema\\0_3\\StatusItemTable.h\">\r\n      <Filter>Database\\Schema\\0_3</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationSetSerializer_0_3.h\">\r\n      <Filter>Parser</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ConfigurationEnvironment.h\">\r\n      <Filter>API Headers</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"GetAllConfigurationUnitsResult.h\">\r\n      <Filter>API Headers</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"FindUnitProcessorsOptions.h\">\r\n      <Filter>API Headers</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"ShutdownSynchronization.h\">\r\n      <Filter>Internals</Filter>\r\n    </ClInclude>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Midl Include=\"Microsoft.Management.Configuration.idl\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"Microsoft_Management_Configuration.def\" />\r\n    <None Include=\"packages.config\" />\r\n    <None Include=\"PropertySheet.props\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Filter Include=\"API Headers\">\r\n      <UniqueIdentifier>{0826fc0e-120c-4e31-bde7-ce0a1278b1b1}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"API Source\">\r\n      <UniqueIdentifier>{6dbfe76d-646d-43b0-b162-e1dedad10ab8}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Internals\">\r\n      <UniqueIdentifier>{c5f2f74e-de80-4235-abbd-bacd6771eaf2}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Parser\">\r\n      <UniqueIdentifier>{b31f8336-b4d8-4c05-b08d-6b82c550a30b}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Telemetry\">\r\n      <UniqueIdentifier>{5a02f1a5-14f3-4a28-8bed-212f3e6b1a00}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Database\">\r\n      <UniqueIdentifier>{c82c1df2-4ef3-4d54-9c18-a13ade2ab16a}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Database\\Schema\">\r\n      <UniqueIdentifier>{6f544d8a-2c3f-4d26-9b53-84dbd2144d43}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Database\\Schema\\0_1\">\r\n      <UniqueIdentifier>{efb71f71-31e4-42db-9105-f10c2e89e1d5}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Database\\Schema\\0_2\">\r\n      <UniqueIdentifier>{f214d0f3-3e9c-469b-91ae-213315d39a69}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Database\\Schema\\0_3\">\r\n      <UniqueIdentifier>{d059436d-cd54-4cf2-96bc-4db53c617537}</UniqueIdentifier>\r\n    </Filter>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Natvis Include=\"$(MSBuildThisFileDirectory)..\\..\\natvis\\wil.natvis\" />\r\n  </ItemGroup>\r\n</Project>"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Microsoft_Management_Configuration.def",
    "content": "﻿EXPORTS\r\nDllCanUnloadNow = WINRT_CanUnloadNow                    PRIVATE\r\nDllGetActivationFactory = WINRT_GetActivationFactory    PRIVATE\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/OpenConfigurationSetResult.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"OpenConfigurationSetResult.h\"\n#include \"OpenConfigurationSetResult.g.cpp\"\n\nnamespace winrt::Microsoft::Management::Configuration::implementation\n{\n    void OpenConfigurationSetResult::Initialize(Configuration::ConfigurationSet configurationSet)\n    {\n        m_set = std::move(configurationSet);\n    }\n\n    void OpenConfigurationSetResult::Initialize(hresult resultCode, hstring field, hstring value, uint32_t line, uint32_t column)\n    {\n        m_resultCode = resultCode;\n        m_field = field;\n        m_value = value;\n        m_line = line;\n        m_column = column;\n    }\n\n    Configuration::ConfigurationSet OpenConfigurationSetResult::Set()\n    {\n        return m_set;\n    }\n\n    hresult OpenConfigurationSetResult::ResultCode()\n    {\n        return m_resultCode;\n    }\n\n    hstring OpenConfigurationSetResult::Field()\n    {\n        return m_field;\n    }\n\n    hstring OpenConfigurationSetResult::Value()\n    {\n        return m_value;\n    }\n\n    uint32_t OpenConfigurationSetResult::Line()\n    {\n        return m_line;\n    }\n\n    uint32_t OpenConfigurationSetResult::Column()\n    {\n        return m_column;\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/OpenConfigurationSetResult.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"OpenConfigurationSetResult.g.h\"\n#include \"ConfigurationSet.h\"\n\nnamespace winrt::Microsoft::Management::Configuration::implementation\n{\n    struct OpenConfigurationSetResult : OpenConfigurationSetResultT<OpenConfigurationSetResult>\n    {\n        OpenConfigurationSetResult() = default;\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void Initialize(Configuration::ConfigurationSet configurationSet);\n        void Initialize(hresult resultCode, hstring field = {}, hstring value = {}, uint32_t line = 0, uint32_t column = 0);\n#endif\n\n        Configuration::ConfigurationSet Set();\n        hresult ResultCode();\n        hstring Field();\n        hstring Value();\n        uint32_t Line();\n        uint32_t Column();\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        Configuration::ConfigurationSet m_set = nullptr;\n        hresult m_resultCode;\n        hstring m_field;\n        hstring m_value;\n        uint32_t m_line = 0;\n        uint32_t m_column = 0;\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ParsingMacros.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n\r\n#define CHECK_ERROR(_op_) (_op_); if (FAILED(m_result)) { return; }\r\n\r\n#define FIELD_TYPE_ERROR(_field_,_mark_) SetError(WINGET_CONFIG_ERROR_INVALID_FIELD_TYPE, (_field_), (_mark_)); return\r\n#define FIELD_TYPE_ERROR_IF(_condition_,_field_,_mark_) if (_condition_) { FIELD_TYPE_ERROR(_field_,_mark_); }\r\n\r\n#define FIELD_MISSING_ERROR(_field_) SetError(WINGET_CONFIG_ERROR_MISSING_FIELD, (_field_)); return\r\n#define FIELD_MISSING_ERROR_IF(_condition_,_field_) if (_condition_) { FIELD_MISSING_ERROR(_field_); }\r\n\r\n#define FIELD_VALUE_ERROR(_field_,_value_,_mark_) SetError(WINGET_CONFIG_ERROR_INVALID_FIELD_VALUE, (_field_), (_mark_), (_value_)); return\r\n#define FIELD_VALUE_ERROR_IF(_condition_,_field_,_value_,_mark_) if (_condition_) { FIELD_VALUE_ERROR(_field_,_value_,_mark_); }\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/PropertySheet.props",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ImportGroup Label=\"PropertySheets\" />\n  <PropertyGroup Label=\"UserMacros\" />\n  <!--\n    To customize common C++/WinRT project properties: \n    * right-click the project node\n    * expand the Common Properties item\n    * select the C++/WinRT property page\n\n    For more advanced scenarios, and complete documentation, please see:\n    https://github.com/Microsoft/cppwinrt/tree/master/nuget \n    -->\n  <PropertyGroup />\n  <ItemDefinitionGroup />\n</Project>"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ShutdownSynchronization.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"ShutdownSynchronization.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    ShutdownAwareAsyncCancellation::ShutdownAwareAsyncCancellation()\r\n    {\r\n        m_defaultPromise = std::make_unique<ShutdownAwareAsyncCancellationPromise>();\r\n        m_cancellation = std::make_unique<AppInstaller::WinRT::AsyncCancellation>(winrt::impl::cancellation_token<ShutdownAwareAsyncCancellationPromise>{ m_defaultPromise.get() });\r\n        RegisterWithShutdownSynchronization();\r\n    }\r\n\r\n    ShutdownAwareAsyncCancellation::~ShutdownAwareAsyncCancellation()\r\n    {\r\n        if (m_cancellation)\r\n        {\r\n            ShutdownSynchronization::Instance().RegisterWorkEnd(m_cancellation->GetWeak());\r\n        }\r\n    }\r\n\r\n    bool ShutdownAwareAsyncCancellation::IsCancelled() const noexcept\r\n    {\r\n        return m_cancellation->IsCancelled();\r\n    }\r\n\r\n    void ShutdownAwareAsyncCancellation::ThrowIfCancelled() const\r\n    {\r\n        m_cancellation->ThrowIfCancelled();\r\n    }\r\n\r\n    void ShutdownAwareAsyncCancellation::Callback(winrt::delegate<>&& callback) const noexcept\r\n    {\r\n        m_cancellation->Callback(std::move(callback));\r\n    }\r\n\r\n    void ShutdownAwareAsyncCancellation::RegisterWithShutdownSynchronization()\r\n    {\r\n        ShutdownSynchronization::Instance().RegisterWorkBegin(m_cancellation->GetWeak());\r\n    }\r\n\r\n    Windows::Foundation::AsyncStatus ShutdownAwareAsyncCancellationPromise::Status() noexcept\r\n    {\r\n        return m_status.load(std::memory_order_acquire);\r\n    }\r\n\r\n    void ShutdownAwareAsyncCancellationPromise::cancellation_callback(winrt::delegate<>&& cancel) noexcept\r\n    {\r\n        {\r\n            slim_lock_guard const guard(m_lock);\r\n\r\n            if (m_status.load(std::memory_order_relaxed) != Windows::Foundation::AsyncStatus::Canceled)\r\n            {\r\n                m_cancel = std::move(cancel);\r\n                return;\r\n            }\r\n        }\r\n\r\n        if (cancel)\r\n        {\r\n            cancel();\r\n        }\r\n    }\r\n\r\n    bool ShutdownAwareAsyncCancellationPromise::enable_cancellation_propagation(bool) noexcept\r\n    {\r\n        THROW_HR(E_NOTIMPL);\r\n    }\r\n\r\n    void ShutdownAwareAsyncCancellationPromise::Cancel() noexcept\r\n    {\r\n        winrt::delegate<> cancel;\r\n\r\n        {\r\n            slim_lock_guard const guard(m_lock);\r\n\r\n            if (m_status.load(std::memory_order_relaxed) == Windows::Foundation::AsyncStatus::Started)\r\n            {\r\n                m_status.store(Windows::Foundation::AsyncStatus::Canceled, std::memory_order_relaxed);\r\n                cancel = std::move(m_cancel);\r\n            }\r\n        }\r\n\r\n        if (cancel)\r\n        {\r\n            cancel();\r\n        }\r\n    }\r\n\r\n    ShutdownSynchronization& ShutdownSynchronization::Instance()\r\n    {\r\n        static ShutdownSynchronization s_instance;\r\n        return s_instance;\r\n    }\r\n\r\n    void ShutdownSynchronization::BlockNewWork()\r\n    {\r\n        m_disabled = true;\r\n    }\r\n\r\n    void ShutdownSynchronization::RegisterWorkBegin(CancellableWeakPtr&& ptr)\r\n    {\r\n        if (m_disabled)\r\n        {\r\n            THROW_HR(E_ABORT);\r\n        }\r\n\r\n        std::lock_guard<std::mutex> lock{ m_workLock };\r\n        m_work.emplace(std::move(ptr));\r\n        m_noActiveWork.ResetEvent();\r\n    }\r\n\r\n    void ShutdownSynchronization::RegisterWorkEnd(CancellableWeakPtr&& ptr)\r\n    {\r\n        std::lock_guard<std::mutex> lock{ m_workLock };\r\n\r\n        auto itr = m_work.find(ptr);\r\n        if (itr != m_work.end())\r\n        {\r\n            m_work.erase(itr);\r\n\r\n            if (m_work.empty())\r\n            {\r\n                m_noActiveWork.SetEvent();\r\n            }\r\n        }\r\n    }\r\n\r\n    void ShutdownSynchronization::CancelAllWork()\r\n    {\r\n        std::lock_guard<std::mutex> lock{ m_workLock };\r\n\r\n        for (auto itr = m_work.begin(); itr != m_work.end(); ++itr)\r\n        {\r\n            if (auto locked = itr->lock())\r\n            {\r\n                locked->Cancel();\r\n            }\r\n            else\r\n            {\r\n                m_work.erase(itr);\r\n            }\r\n        }\r\n\r\n        if (m_work.empty())\r\n        {\r\n            m_noActiveWork.SetEvent();\r\n        }\r\n    }\r\n\r\n    void ShutdownSynchronization::Wait()\r\n    {\r\n        for (;;)\r\n        {\r\n            {\r\n                std::lock_guard<std::mutex> lock{ m_workLock };\r\n\r\n                // Check for any inactive work before waiting\r\n                for (auto itr = m_work.begin(); itr != m_work.end(); ++itr)\r\n                {\r\n                    if (!itr->lock())\r\n                    {\r\n                        m_work.erase(itr);\r\n                    }\r\n                }\r\n\r\n                if (m_work.empty())\r\n                {\r\n                    break;\r\n                }\r\n            }\r\n\r\n            if (m_noActiveWork.wait(250))\r\n            {\r\n                break;\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/ShutdownSynchronization.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <winget/AsyncTokens.h>\r\n#include <wil/resource.h>\r\n#include <atomic>\r\n#include <set>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    // Promise type implementation for cancellation_token\r\n    struct ShutdownAwareAsyncCancellationPromise\r\n    {\r\n        Windows::Foundation::AsyncStatus Status() noexcept;\r\n        void cancellation_callback(winrt::delegate<>&& cancel) noexcept;\r\n        bool enable_cancellation_propagation(bool value) noexcept;\r\n        void Cancel() noexcept;\r\n\r\n    private:\r\n        slim_mutex m_lock;\r\n        winrt::delegate<> m_cancel;\r\n        std::atomic<Windows::Foundation::AsyncStatus> m_status{ Windows::Foundation::AsyncStatus::Started };\r\n    };\r\n\r\n    // An AsyncCancellation that registers with ShutdownSynchronization.\r\n    struct ShutdownAwareAsyncCancellation\r\n    {\r\n        // Creates a cancellable object without an external cancellation token.\r\n        ShutdownAwareAsyncCancellation();\r\n\r\n        // Create a cancellation object from the winrt token.\r\n        template <typename Promise>\r\n        ShutdownAwareAsyncCancellation(winrt::impl::cancellation_token<Promise>&& token)\r\n        {\r\n            m_cancellation = std::make_unique<AppInstaller::WinRT::AsyncCancellation>(std::move(token));\r\n            RegisterWithShutdownSynchronization();\r\n        }\r\n\r\n        // Removes the shutdown registration.\r\n        ~ShutdownAwareAsyncCancellation();\r\n\r\n        // Returns true if the operation has been cancelled, false if not.\r\n        bool IsCancelled() const noexcept;\r\n\r\n        // Throws the appropriate exception if the operation has been cancelled.\r\n        void ThrowIfCancelled() const;\r\n\r\n        // Sets a callback that will be invoked on cancellation.\r\n        void Callback(winrt::delegate<>&& callback) const noexcept;\r\n\r\n    protected:\r\n        void RegisterWithShutdownSynchronization();\r\n\r\n        std::unique_ptr<ShutdownAwareAsyncCancellationPromise> m_defaultPromise;\r\n        std::unique_ptr<AppInstaller::WinRT::AsyncCancellation> m_cancellation;\r\n    };\r\n\r\n    struct ShutdownSynchronization\r\n    {\r\n        using CancellableWeakPtr = std::weak_ptr<AppInstaller::WinRT::details::AsyncCancellationTypeErasure>;\r\n\r\n        ShutdownSynchronization() = default;\r\n\r\n        static ShutdownSynchronization& Instance();\r\n\r\n        // Signals that new work should be blocked.\r\n        void BlockNewWork();\r\n\r\n        // Call to register the begin and end of work.\r\n        void RegisterWorkBegin(CancellableWeakPtr&& ptr);\r\n        void RegisterWorkEnd(CancellableWeakPtr&& ptr);\r\n\r\n        // Cancels all currently registered work.\r\n        void CancelAllWork();\r\n\r\n        // Waits for outstanding work to be completed.\r\n        void Wait();\r\n\r\n    private:\r\n        std::atomic_bool m_disabled{ false };\r\n        std::mutex m_workLock;\r\n        std::set<CancellableWeakPtr, std::owner_less<CancellableWeakPtr>> m_work;\r\n        wil::slim_event_manual_reset m_noActiveWork{ true };\r\n    };\r\n\r\n    // An AsyncProgress that registers with ShutdownSynchronization.\r\n    template <typename ResultT, typename ProgressT>\r\n    struct ShutdownAwareAsyncProgress\r\n    {\r\n        // Creates a cancellable object without an external cancellation token.\r\n        ShutdownAwareAsyncProgress()\r\n        {\r\n            m_defaultPromise = std::make_unique<ShutdownAwareAsyncCancellationPromise>();\r\n            m_progress = std::make_unique<AppInstaller::WinRT::AsyncProgress<ResultT, ProgressT>>(winrt::impl::cancellation_token<ShutdownAwareAsyncCancellationPromise>{ m_defaultPromise.get() });\r\n            RegisterWithShutdownSynchronization();\r\n        }\r\n\r\n        // Create a progress object from the winrt token.\r\n        template <typename Promise>\r\n        ShutdownAwareAsyncProgress(winrt::impl::progress_token<Promise, ProgressT>&& progress, winrt::impl::cancellation_token<Promise>&& cancellation)\r\n        {\r\n            m_progress = std::make_unique<AppInstaller::WinRT::AsyncProgress<ResultT, ProgressT>>(std::move(progress), std::move(cancellation));\r\n            RegisterWithShutdownSynchronization();\r\n        }\r\n\r\n        // Create a progress object from an EventHandler.\r\n        template <typename Promise>\r\n        ShutdownAwareAsyncProgress(winrt::Windows::Foundation::EventHandler<ProgressT>&& progress, winrt::impl::cancellation_token<Promise>&& cancellation)\r\n        {\r\n            m_progress = std::make_unique<AppInstaller::WinRT::AsyncProgress<ResultT, ProgressT>>(std::move(progress), std::move(cancellation));\r\n            RegisterWithShutdownSynchronization();\r\n        }\r\n\r\n        ShutdownAwareAsyncProgress(const ShutdownAwareAsyncProgress&) = delete;\r\n        ShutdownAwareAsyncProgress& operator=(const ShutdownAwareAsyncProgress&) = delete;\r\n\r\n        ShutdownAwareAsyncProgress(ShutdownAwareAsyncProgress&&) = default;\r\n        ShutdownAwareAsyncProgress& operator=(ShutdownAwareAsyncProgress&&) = default;\r\n\r\n        // Removes the shutdown registration.\r\n        ~ShutdownAwareAsyncProgress()\r\n        {\r\n            if (m_progress)\r\n            {\r\n                ShutdownSynchronization::Instance().RegisterWorkEnd(m_progress->GetWeak());\r\n            }\r\n        }\r\n\r\n        AppInstaller::WinRT::AsyncCancellation& GetCancellation()\r\n        {\r\n            return *m_progress;\r\n        }\r\n\r\n        // Returns true if the operation has been cancelled, false if not.\r\n        bool IsCancelled() const noexcept\r\n        {\r\n            return m_progress->IsCancelled();\r\n        }\r\n\r\n        // Throws the appropriate exception if the operation has been cancelled.\r\n        void ThrowIfCancelled() const\r\n        {\r\n            m_progress->ThrowIfCancelled();\r\n        }\r\n\r\n        // Sets a callback that will be invoked on cancellation.\r\n        void Callback(winrt::delegate<>&& callback) const noexcept\r\n        {\r\n            m_progress->Callback(std::move(callback));\r\n        }\r\n\r\n        // Sends progress if this object is not empty.\r\n        void Progress(ProgressT const& progress) const\r\n        {\r\n            m_progress->Progress(progress);\r\n        }\r\n\r\n        // Sets the result onto the progress object if it is not empty.\r\n        void Result(ResultT const& result) const\r\n        {\r\n            m_progress->Result(result);\r\n        }\r\n\r\n    protected:\r\n        void RegisterWithShutdownSynchronization()\r\n        {\r\n            ShutdownSynchronization::Instance().RegisterWorkBegin(m_progress->GetWeak());\r\n        }\r\n\r\n        std::unique_ptr<ShutdownAwareAsyncCancellationPromise> m_defaultPromise;\r\n        std::unique_ptr<AppInstaller::WinRT::AsyncProgress<ResultT, ProgressT>> m_progress;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Telemetry/Telemetry.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Telemetry.h\"\r\n#include \"TraceLogging.h\"\r\n#include <AppInstallerErrors.h>\r\n#include <AppInstallerLogging.h>\r\n#include <AppInstallerStrings.h>\r\n#include <winget/Runtime.h>\r\n\r\n#define AICLI_TraceLoggingStringView(_sv_,_name_) TraceLoggingCountedUtf8String(_sv_.data(), static_cast<ULONG>(_sv_.size()), _name_)\r\n#define AICLI_TraceLoggingWStringView(_sv_,_name_) TraceLoggingCountedWideString(_sv_.data(), static_cast<ULONG>(_sv_.size()), _name_)\r\n\r\n#define AICLI_TraceLoggingProcessingSummaryForIntent(_forIntent_,_name_,_pluralName_) \\\r\n    TraceLoggingUInt32(_forIntent_.Count, _name_ ## \"Count\"), \\\r\n    TraceLoggingUInt32(_forIntent_.Run, _pluralName_ ## \"Run\"), \\\r\n    TraceLoggingUInt32(_forIntent_.Failed, _pluralName_ ## \"Failed\")\r\n\r\n#define AICLI_TraceLoggingWriteActivity(_eventName_,...) TraceLoggingWriteActivity(\\\r\ng_hTraceProvider,\\\r\n_eventName_,\\\r\nGetActivityId(),\\\r\nnullptr,\\\r\nTraceLoggingCountedUtf8String(m_version.c_str(),  static_cast<ULONG>(m_version.size()), \"CodeVersion\"),\\\r\nTraceLoggingCountedUtf8String(m_caller.c_str(),  static_cast<ULONG>(m_caller.size()), \"Caller\"),\\\r\n__VA_ARGS__)\r\n\r\n#ifdef AICLI_DISABLE_TEST_HOOKS\r\n\r\n#define WinGet_EventItem(_value_,_name_) \r\n#define WinGet_SummaryForIntentItem(_forIntent_,_name_,_pluralName_) \r\n#define WinGet_WriteEventToDiagnostics(_eventName_,...) \r\n\r\n#else\r\n\r\nstruct WinGetAbsorbVA_ARGSCommas\r\n{\r\n    WinGetAbsorbVA_ARGSCommas(int, int) {}\r\n};\r\n\r\ninline std::ostream& operator<<(std::ostream& out, const WinGetAbsorbVA_ARGSCommas&) { return out; }\r\ninline std::ostream& operator<<(std::ostream& out, std::wstring_view value) { out << AppInstaller::Utility::ConvertToUTF8(value); return out; }\r\n\r\n#define WinGet_EventItem(_value_,_name_) \\\r\n    0) << (_name_) << \": \" << (_value_) << '\\n' << WinGetAbsorbVA_ARGSCommas(0\r\n\r\n#define WinGet_SummaryForIntentItem(_forIntent_,_name_,_pluralName_) \\\r\n    WinGet_EventItem(_forIntent_.Count, _name_ ## \"Count\"), \\\r\n    WinGet_EventItem(_forIntent_.Run, _pluralName_ ## \"Run\"), \\\r\n    WinGet_EventItem(_forIntent_.Failed, _pluralName_ ## \"Failed\")\r\n\r\n#define WinGet_WriteEventToDiagnostics(_eventName_,...) \\\r\n{ \\\r\n    std::ostringstream _debugEventStream; \\\r\n    _debugEventStream << \\\r\n        \"#DebugEventStream\\n\" << \\\r\n        \"Event: \" << (_eventName_) << '\\n' << \\\r\n        \"ActivityID: \" << *GetActivityId() << '\\n' << \\\r\n        \"CodeVersion: \" << m_version << '\\n' << \\\r\n        \"Caller: \" << m_caller << '\\n' \\\r\n        << WinGetAbsorbVA_ARGSCommas(0, __VA_ARGS__ ,0) \\\r\n        ; \\\r\n    AICLI_LOG_LARGE_STRING(Config, Verbose, , _debugEventStream.str()); \\\r\n}\r\n\r\n#endif\r\n\r\nusing namespace std::string_view_literals;\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    namespace\r\n    {\r\n        // The data collected from running through a set of results.\r\n        struct ConfigRunSummaryData\r\n        {\r\n            hresult Result = S_OK;\r\n            ConfigurationUnitResultSource FailurePoint = ConfigurationUnitResultSource::None;\r\n            TelemetryTraceLogger::ProcessingSummaryForIntent AssertSummary{ ConfigurationUnitIntent::Assert };\r\n            TelemetryTraceLogger::ProcessingSummaryForIntent InformSummary{ ConfigurationUnitIntent::Inform };\r\n            TelemetryTraceLogger::ProcessingSummaryForIntent ApplySummary{ ConfigurationUnitIntent::Apply };\r\n        };\r\n\r\n        size_t GetPriority(ConfigurationUnitResultSource source)\r\n        {\r\n            switch (source)\r\n            {\r\n            case ConfigurationUnitResultSource::Internal: return 0;\r\n            case ConfigurationUnitResultSource::UnitProcessing: return 100;\r\n            case ConfigurationUnitResultSource::SystemState: return 200;\r\n            case ConfigurationUnitResultSource::ConfigurationSet: return 300;\r\n            case ConfigurationUnitResultSource::Precondition: return 400;\r\n            default: return 500;\r\n            case ConfigurationUnitResultSource::None: return 600;\r\n            }\r\n        }\r\n\r\n        bool FirstHasPriority(ConfigurationUnitResultSource first, ConfigurationUnitResultSource second)\r\n        {\r\n            return GetPriority(first) < GetPriority(second);\r\n        }\r\n\r\n        void ProcessUnitResult(const Configuration::ConfigurationUnit unit, const IConfigurationUnitResultInformation& resultInformation, ConfigRunSummaryData& result)\r\n        {\r\n            hresult resultCode = resultInformation.ResultCode();\r\n            if (FAILED(resultCode))\r\n            {\r\n                if (result.Result == S_OK || result.Result == resultCode)\r\n                {\r\n                    result.Result = resultCode;\r\n                }\r\n                else\r\n                {\r\n                    result.Result = WINGET_CONFIG_ERROR_SET_APPLY_FAILED;\r\n                }\r\n            }\r\n\r\n            ConfigurationUnitResultSource unitFailurePoint = resultInformation.ResultSource();\r\n            if (FirstHasPriority(unitFailurePoint, result.FailurePoint))\r\n            {\r\n                result.FailurePoint = unitFailurePoint;\r\n            }\r\n\r\n            TelemetryTraceLogger::ProcessingSummaryForIntent* summaryItem = nullptr;\r\n            switch (unit.Intent())\r\n            {\r\n            case ConfigurationUnitIntent::Assert:\r\n                summaryItem = &result.AssertSummary;\r\n                break;\r\n            case ConfigurationUnitIntent::Inform:\r\n                summaryItem = &result.InformSummary;\r\n                break;\r\n            case ConfigurationUnitIntent::Apply:\r\n            case ConfigurationUnitIntent::Unknown:\r\n                summaryItem = &result.ApplySummary;\r\n                break;\r\n            default:\r\n                return;\r\n            }\r\n\r\n            summaryItem->Count++;\r\n\r\n            ConfigurationUnitResultSource resultSource = resultInformation.ResultSource();\r\n            if (resultSource != ConfigurationUnitResultSource::Precondition &&\r\n                resultSource != ConfigurationUnitResultSource::ConfigurationSet)\r\n            {\r\n                summaryItem->Run++;\r\n            }\r\n\r\n            if (FAILED(resultCode))\r\n            {\r\n                summaryItem->Failed++;\r\n            }\r\n        }\r\n\r\n        // Runs through a set of results, summarizing them.\r\n        template <typename Enumerable>\r\n        ConfigRunSummaryData ProcessRunResult(const Enumerable& results)\r\n        {\r\n            ConfigRunSummaryData result;\r\n\r\n            for (const auto& item : results)\r\n            {\r\n                ProcessUnitResult(item.Unit(), item.ResultInformation(), result);\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n\r\n    TelemetryTraceLogger::TelemetryTraceLogger()\r\n    {\r\n        std::ignore = CoCreateGuid(&m_activityId);\r\n        m_version = AppInstaller::Runtime::GetClientVersion();\r\n    }\r\n\r\n    void TelemetryTraceLogger::SetActivityId(const guid& value)\r\n    {\r\n        m_activityId = value;\r\n    }\r\n\r\n    const GUID* TelemetryTraceLogger::GetActivityId() const\r\n    {\r\n        return &m_activityId;\r\n    }\r\n\r\n    bool TelemetryTraceLogger::EnableRuntime(bool value)\r\n    {\r\n        return m_isRuntimeEnabled.exchange(value);\r\n    }\r\n\r\n    bool TelemetryTraceLogger::IsEnabled() const\r\n    {\r\n        return m_isRuntimeEnabled;\r\n    }\r\n\r\n    void TelemetryTraceLogger::SetCaller(std::string_view caller)\r\n    {\r\n        m_caller = caller;\r\n    }\r\n\r\n    std::string_view TelemetryTraceLogger::GetCaller() const\r\n    {\r\n        return m_caller;\r\n    }\r\n\r\n    void TelemetryTraceLogger::LogConfigUnitRun(\r\n        const guid& setIdentifier,\r\n        const guid& unitIdentifier,\r\n        hstring unitName,\r\n        hstring moduleName,\r\n        ConfigurationUnitIntent unitIntent,\r\n        ConfigurationUnitIntent runIntent,\r\n        std::string_view action,\r\n        hresult result,\r\n        ConfigurationUnitResultSource failurePoint,\r\n        std::wstring_view settingNames) const noexcept try\r\n    {\r\n        // Change unknown to Apply for telemetry, as it will have been treated that way\r\n        if (unitIntent == ConfigurationUnitIntent::Unknown)\r\n        {\r\n            unitIntent = ConfigurationUnitIntent::Apply;\r\n        }\r\n\r\n        if (IsTelemetryEnabled())\r\n        {\r\n            AICLI_TraceLoggingWriteActivity(\r\n                \"ConfigUnitRun\",\r\n                TraceLoggingGuid(setIdentifier, \"SetID\"),\r\n                TraceLoggingGuid(unitIdentifier, \"UnitID\"),\r\n                AICLI_TraceLoggingWStringView(unitName, \"UnitName\"),\r\n                AICLI_TraceLoggingWStringView(moduleName, \"ModuleName\"),\r\n                TraceLoggingInt32(static_cast<int32_t>(unitIntent), \"UnitIntent\"),\r\n                TraceLoggingInt32(static_cast<int32_t>(runIntent), \"RunIntent\"),\r\n                AICLI_TraceLoggingStringView(action, \"Action\"),\r\n                TraceLoggingHResult(result, \"Result\"),\r\n                TraceLoggingInt32(static_cast<int32_t>(failurePoint), \"FailurePoint\"),\r\n                AICLI_TraceLoggingWStringView(settingNames, \"SettingsProvided\"),\r\n                TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance),\r\n                TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));\r\n\r\n            // Keep in sync with above event!\r\n            WinGet_WriteEventToDiagnostics(\r\n                \"ConfigUnitRun\",\r\n                WinGet_EventItem(setIdentifier, \"SetID\"),\r\n                WinGet_EventItem(unitIdentifier, \"UnitID\"),\r\n                WinGet_EventItem(unitName, \"UnitName\"),\r\n                WinGet_EventItem(moduleName, \"ModuleName\"),\r\n                WinGet_EventItem(static_cast<int32_t>(unitIntent), \"UnitIntent\"),\r\n                WinGet_EventItem(static_cast<int32_t>(runIntent), \"RunIntent\"),\r\n                WinGet_EventItem(action, \"Action\"),\r\n                WinGet_EventItem(result, \"Result\"),\r\n                WinGet_EventItem(static_cast<int32_t>(failurePoint), \"FailurePoint\"),\r\n                WinGet_EventItem(settingNames, \"SettingsProvided\"));\r\n        }\r\n    }\r\n    CATCH_LOG();\r\n\r\n    void TelemetryTraceLogger::LogConfigUnitRunIfAppropriate(\r\n        const guid& setIdentifier,\r\n        const Configuration::ConfigurationUnit& unit,\r\n        ConfigurationUnitIntent runIntent,\r\n        std::string_view action,\r\n        const IConfigurationUnitResultInformation& resultInformation) const noexcept try\r\n    {\r\n        if (!IsTelemetryEnabled())\r\n        {\r\n            return;\r\n        }\r\n\r\n        // We only want to send telemetry for publicly available units.\r\n        IConfigurationUnitProcessorDetails details = unit.Details();\r\n        if (!details || !details.IsPublic())\r\n        {\r\n            return;\r\n        }\r\n\r\n        // Create a single string from the set of top level setting names, ex. \"a|b|c\".\r\n        const winrt::Windows::Foundation::Collections::ValueSet& settings = unit.Settings();\r\n        std::wostringstream strstr;\r\n\r\n        for (const auto& setting : settings)\r\n        {\r\n            strstr << static_cast<std::wstring_view>(setting.Key()) << L'|';\r\n        }\r\n        std::wstring allSettingsNames = strstr.str();\r\n        if (!allSettingsNames.empty())\r\n        {\r\n            allSettingsNames.pop_back();\r\n        }\r\n\r\n        LogConfigUnitRun(setIdentifier, unit.InstanceIdentifier(), unit.Type(), details.ModuleName(), unit.Intent(), runIntent, action, resultInformation.ResultCode(), resultInformation.ResultSource(), allSettingsNames);\r\n    }\r\n    CATCH_LOG();\r\n\r\n    void TelemetryTraceLogger::LogConfigProcessingSummary(\r\n        const guid& setIdentifier,\r\n        std::string_view inputHash,\r\n        ConfigurationUnitIntent runIntent,\r\n        hresult result,\r\n        ConfigurationUnitResultSource failurePoint,\r\n        const ProcessingSummaryForIntent& assertSummary,\r\n        const ProcessingSummaryForIntent& informSummary,\r\n        const ProcessingSummaryForIntent& applySummary) const noexcept try\r\n    {\r\n        if (IsTelemetryEnabled())\r\n        {\r\n            AICLI_TraceLoggingWriteActivity(\r\n                \"ConfigProcessingSummary\",\r\n                TraceLoggingGuid(setIdentifier, \"SetID\"),\r\n                AICLI_TraceLoggingStringView(inputHash, \"InputHash\"),\r\n                TraceLoggingBool(false, \"FromHistory\"), // deprecated\r\n                TraceLoggingInt32(static_cast<int32_t>(runIntent), \"RunIntent\"),\r\n                TraceLoggingHResult(result, \"Result\"),\r\n                TraceLoggingInt32(static_cast<int32_t>(failurePoint), \"FailurePoint\"),\r\n                AICLI_TraceLoggingProcessingSummaryForIntent(assertSummary, \"Assert\", \"Asserts\"),\r\n                AICLI_TraceLoggingProcessingSummaryForIntent(informSummary, \"Inform\", \"Informs\"),\r\n                AICLI_TraceLoggingProcessingSummaryForIntent(applySummary, \"Apply\", \"Applies\"),\r\n                TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance),\r\n                TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));\r\n\r\n            // Keep in sync with above event!\r\n            WinGet_WriteEventToDiagnostics(\r\n                \"ConfigProcessingSummary\",\r\n                WinGet_EventItem(setIdentifier, \"SetID\"),\r\n                WinGet_EventItem(inputHash, \"InputHash\"),\r\n                WinGet_EventItem(false, \"FromHistory\"), // deprecated\r\n                WinGet_EventItem(static_cast<int32_t>(runIntent), \"RunIntent\"),\r\n                WinGet_EventItem(result, \"Result\"),\r\n                WinGet_EventItem(static_cast<int32_t>(failurePoint), \"FailurePoint\"),\r\n                WinGet_SummaryForIntentItem(assertSummary, \"Assert\", \"Asserts\"),\r\n                WinGet_SummaryForIntentItem(informSummary, \"Inform\", \"Informs\"),\r\n                WinGet_SummaryForIntentItem(applySummary, \"Apply\", \"Applies\"));\r\n        }\r\n    }\r\n    CATCH_LOG();\r\n\r\n    void TelemetryTraceLogger::LogConfigProcessingSummaryForTest(\r\n        const ConfigurationSet& configurationSet,\r\n        const TestConfigurationSetResult& result) const noexcept try\r\n    {\r\n        if (!IsTelemetryEnabled())\r\n        {\r\n            return;\r\n        }\r\n\r\n        ConfigRunSummaryData summaryData = ProcessRunResult(result.UnitResults());\r\n\r\n        LogConfigProcessingSummary(configurationSet.InstanceIdentifier(), configurationSet.GetInputHash(), ConfigurationUnitIntent::Assert,\r\n            summaryData.Result, summaryData.FailurePoint, summaryData.AssertSummary, summaryData.InformSummary, summaryData.ApplySummary);\r\n    }\r\n    CATCH_LOG();\r\n\r\n    void TelemetryTraceLogger::LogConfigProcessingSummaryForTestException(\r\n        const ConfigurationSet& configurationSet,\r\n        hresult error,\r\n        const TestConfigurationSetResult& result) const noexcept try\r\n    {\r\n        if (!IsTelemetryEnabled())\r\n        {\r\n            return;\r\n        }\r\n\r\n        ConfigRunSummaryData summaryData = ProcessRunResult(result.UnitResults());\r\n\r\n        LogConfigProcessingSummary(configurationSet.InstanceIdentifier(), configurationSet.GetInputHash(), ConfigurationUnitIntent::Assert,\r\n            error, ConfigurationUnitResultSource::Internal, summaryData.AssertSummary, summaryData.InformSummary, summaryData.ApplySummary);\r\n    }\r\n    CATCH_LOG();\r\n\r\n    void TelemetryTraceLogger::LogConfigProcessingSummaryForApply(\r\n        const ConfigurationSet& configurationSet,\r\n        const ApplyConfigurationSetResult& result) const noexcept try\r\n    {\r\n        if (!IsTelemetryEnabled())\r\n        {\r\n            return;\r\n        }\r\n\r\n        ConfigRunSummaryData summaryData = ProcessRunResult(result.UnitResults());\r\n\r\n        LogConfigProcessingSummary(configurationSet.InstanceIdentifier(), configurationSet.GetInputHash(), ConfigurationUnitIntent::Apply,\r\n            result.ResultCode(), summaryData.FailurePoint, summaryData.AssertSummary, summaryData.InformSummary, summaryData.ApplySummary);\r\n    }\r\n    CATCH_LOG();\r\n\r\n    void TelemetryTraceLogger::LogConfigProcessingSummaryForApplyException(\r\n        const ConfigurationSet& configurationSet,\r\n        hresult error,\r\n        const ApplyConfigurationSetResult& result) const noexcept try\r\n    {\r\n        if (!IsTelemetryEnabled())\r\n        {\r\n            return;\r\n        }\r\n\r\n        ConfigRunSummaryData summaryData = ProcessRunResult(result.UnitResults());\r\n\r\n        LogConfigProcessingSummary(configurationSet.InstanceIdentifier(), configurationSet.GetInputHash(), ConfigurationUnitIntent::Apply,\r\n            error, ConfigurationUnitResultSource::Internal, summaryData.AssertSummary, summaryData.InformSummary, summaryData.ApplySummary);\r\n    }\r\n    CATCH_LOG();\r\n\r\n    bool TelemetryTraceLogger::IsTelemetryEnabled() const noexcept\r\n    {\r\n#ifdef AICLI_DISABLE_TEST_HOOKS\r\n        return g_IsTelemetryProviderEnabled && m_isRuntimeEnabled;\r\n#else\r\n        // For testing, only use the local enable state.\r\n        return m_isRuntimeEnabled;\r\n#endif\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Telemetry/Telemetry.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerLanguageUtilities.h>\r\n#include <winrt/Microsoft.Management.Configuration.h>\r\n#include <winrt/Windows.Foundation.Collections.h>\r\n#include \"ConfigurationUnitResultInformation.h\"\r\n#include \"ConfigurationSet.h\"\r\n#include \"TestConfigurationSetResult.h\"\r\n#include \"ApplyConfigurationSetResult.h\"\r\n\r\n#include <cguid.h>\r\n#include <string>\r\n#include <string_view>\r\n#include <vector>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    // Provides the ability to write telemetry events.\r\n    struct TelemetryTraceLogger\r\n    {\r\n        TelemetryTraceLogger();\r\n\r\n        TelemetryTraceLogger(const TelemetryTraceLogger&) = default;\r\n        TelemetryTraceLogger& operator=(const TelemetryTraceLogger&) = default;\r\n\r\n        TelemetryTraceLogger(TelemetryTraceLogger&&) = default;\r\n        TelemetryTraceLogger& operator=(TelemetryTraceLogger&&) = default;\r\n\r\n        // Control whether this trace logger is enabled at runtime.\r\n        // Returns the previous value.\r\n        bool EnableRuntime(bool value);\r\n\r\n        // Returns a value indicating whether the logger is enabled.\r\n        bool IsEnabled() const;\r\n\r\n        // Sets the current activity identifier.\r\n        void SetActivityId(const guid& value);\r\n\r\n        // Return address of m_activityId\r\n        const GUID* GetActivityId() const;\r\n\r\n        // Store the passed in name of the caller\r\n        void SetCaller(std::string_view caller);\r\n\r\n        // Get the current caller value\r\n        std::string_view GetCaller() const;\r\n\r\n        static constexpr std::string_view GetAction = \"get\";\r\n        static constexpr std::string_view ApplyAction = \"apply\";\r\n        static constexpr std::string_view TestAction = \"test\";\r\n        static constexpr std::string_view ExportAction = \"export\";\r\n\r\n        // Logs information about running a configuration unit.\r\n        // The caller is expected to only call this for failures from publicly available units.\r\n        void LogConfigUnitRun(\r\n            const guid& setIdentifier,\r\n            const guid& unitIdentifier,\r\n            hstring unitName,\r\n            hstring moduleName,\r\n            ConfigurationUnitIntent unitIntent,\r\n            ConfigurationUnitIntent runIntent,\r\n            std::string_view action,\r\n            hresult result,\r\n            ConfigurationUnitResultSource failurePoint,\r\n            std::wstring_view settingNames) const noexcept;\r\n\r\n        // Logs information about running a configuration unit in the appropriate conditions.\r\n        void LogConfigUnitRunIfAppropriate(\r\n            const guid& setIdentifier,\r\n            const Configuration::ConfigurationUnit& unit,\r\n            ConfigurationUnitIntent runIntent,\r\n            std::string_view action,\r\n            const IConfigurationUnitResultInformation& resultInformation) const noexcept;\r\n\r\n        // The summary information for a specific unit intent.\r\n        struct ProcessingSummaryForIntent\r\n        {\r\n            ConfigurationUnitIntent Intent;\r\n            uint32_t Count;\r\n            uint32_t Run;\r\n            uint32_t Failed;\r\n        };\r\n\r\n        // Logs a processing summary event for a configuration set.\r\n        void LogConfigProcessingSummary(\r\n            const guid& setIdentifier,\r\n            std::string_view inputHash,\r\n            ConfigurationUnitIntent runIntent,\r\n            hresult result,\r\n            ConfigurationUnitResultSource failurePoint,\r\n            const ProcessingSummaryForIntent& assertSummary,\r\n            const ProcessingSummaryForIntent& informSummary,\r\n            const ProcessingSummaryForIntent& applySummary) const noexcept;\r\n\r\n        // Logs a processing summary event for a configuration set test run.\r\n        void LogConfigProcessingSummaryForTest(\r\n            const ConfigurationSet& configurationSet,\r\n            const TestConfigurationSetResult& result) const noexcept;\r\n\r\n        // Logs a processing summary event for a configuration set test run exception.\r\n        void LogConfigProcessingSummaryForTestException(\r\n            const ConfigurationSet& configurationSet,\r\n            hresult error,\r\n            const TestConfigurationSetResult& result) const noexcept;\r\n\r\n        // Logs a processing summary event for a configuration set apply run.\r\n        void LogConfigProcessingSummaryForApply(\r\n            const ConfigurationSet& configurationSet,\r\n            const ApplyConfigurationSetResult& result) const noexcept;\r\n\r\n        // Logs a processing summary event for a configuration set apply run exception.\r\n        void LogConfigProcessingSummaryForApplyException(\r\n            const ConfigurationSet& configurationSet,\r\n            hresult error,\r\n            const ApplyConfigurationSetResult& result) const noexcept;\r\n\r\n    protected:\r\n        bool IsTelemetryEnabled() const noexcept;\r\n\r\n        CopyConstructibleAtomic<bool> m_isRuntimeEnabled{ true };\r\n\r\n        GUID m_activityId = GUID_NULL;\r\n        std::string m_version;\r\n        std::string m_caller;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Telemetry/TraceLogging.cpp",
    "content": "﻿// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project root for license information.\n\n#include \"pch.h\"\n#include \"TraceLogging.h\"\n\n// GUID for Microsoft.Management.Configuration : {9be929c4-3582-4629-aaa2-f427a5032b33}\nTRACELOGGING_DEFINE_PROVIDER(\n    g_hTraceProvider,\n    \"Microsoft.Management.Configuration\",\n    (0x9be929c4, 0x3582, 0x4629, 0xaa, 0xa2, 0xf4, 0x27, 0xa5, 0x03, 0x2b, 0x33),\n    TraceLoggingOptionMicrosoftTelemetry());\n\nbool g_IsTelemetryProviderEnabled{};\nUCHAR g_TelemetryProviderLevel{};\nULONGLONG g_TelemetryProviderMatchAnyKeyword{};\n\nstruct TraceProvider\n{\n    TraceProvider();\n\n    ~TraceProvider();\n};\n\nTraceProvider g_TraceProvider{};\n\nvoid WINAPI TelemetryProviderEnabledCallback(\n    _In_      LPCGUID /*sourceId*/,\n    _In_      ULONG isEnabled,\n    _In_      UCHAR level,\n    _In_      ULONGLONG matchAnyKeyword,\n    _In_      ULONGLONG /*matchAllKeywords*/,\n    _In_opt_  PEVENT_FILTER_DESCRIPTOR /*filterData*/,\n    _In_opt_  PVOID /*callbackContext*/)\n{\n    g_IsTelemetryProviderEnabled = !!isEnabled;\n    g_TelemetryProviderLevel = level;\n    g_TelemetryProviderMatchAnyKeyword = matchAnyKeyword;\n}\n\nTraceProvider::TraceProvider()\n{\n    TraceLoggingRegisterEx(g_hTraceProvider, TelemetryProviderEnabledCallback, nullptr);\n}\n\nTraceProvider::~TraceProvider()\n{\n    TraceLoggingUnregister(g_hTraceProvider);\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/Telemetry/TraceLogging.h",
    "content": "﻿// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT License. See LICENSE in the project root for license information.\n\n#pragma once\n\n#include <Telemetry/WinEventLogLevels.h>\n#include <TraceLoggingProvider.h>\n\n#include <Telemetry/MicrosoftTelemetry.h>\n\n// Keywords\n#define KEYWORD_REPEATER         0x0000000000000001\n#define KEYWORD_SCROLLER         0x0000000000000002\n#define KEYWORD_PTR              0x0000000000000004\n#define KEYWORD_SCROLLVIEWER     0x0000000000000008\n#define KEYWORD_SWIPECONTROL     0x0000000000000010\n#define KEYWORD_COMMANDBARFLYOUT 0x0000000000000020\n\n// Common output formats\n#define TRACE_MSG_METH L\"%s[0x%p]()\\n\"\n#define TRACE_MSG_METH_DBL L\"%s[0x%p](%lf)\\n\"\n#define TRACE_MSG_METH_DBL_DBL L\"%s[0x%p](%lf, %lf)\\n\"\n#define TRACE_MSG_METH_DBL_INT L\"%s[0x%p](%lf, %d)\\n\"\n#define TRACE_MSG_METH_DBL_DBL_INT L\"%s[0x%p](%lf, %lf, %d)\\n\"\n#define TRACE_MSG_METH_DBL_DBL_FLT L\"%s[0x%p](%lf, %lf, %f)\\n\"\n#define TRACE_MSG_METH_DBL_DBL_STR L\"%s[0x%p](%lf, %lf, %s)\\n\"\n#define TRACE_MSG_METH_FLT L\"%s[0x%p](%f)\\n\"\n#define TRACE_MSG_METH_FLT_FLT L\"%s[0x%p](%f, %f)\\n\"\n#define TRACE_MSG_METH_FLT_FLT_FLT L\"%s[0x%p](%f, %f, %f)\\n\"\n#define TRACE_MSG_METH_FLT_FLT_FLT_FLT L\"%s[0x%p](%f, %f, %f, %f)\\n\"\n#define TRACE_MSG_METH_FLT_FLT_STR_INT L\"%s[0x%p](%f, %f, %s, %d)\\n\"\n#define TRACE_MSG_METH_INT L\"%s[0x%p](%d)\\n\"\n#define TRACE_MSG_METH_INT_INT L\"%s[0x%p](%d, %d)\\n\"\n#define TRACE_MSG_METH_PTR L\"%s[0x%p](0x%p)\\n\"\n#define TRACE_MSG_METH_PTR_PTR L\"%s[0x%p](0x%p, 0x%p)\\n\"\n#define TRACE_MSG_METH_PTR_DBL L\"%s[0x%p](0x%p, %lf)\\n\"\n#define TRACE_MSG_METH_PTR_INT L\"%s[0x%p](0x%p, %d)\\n\"\n#define TRACE_MSG_METH_PTR_STR L\"%s[0x%p](0x%p, %s)\\n\"\n#define TRACE_MSG_METH_STR L\"%s[0x%p](%s)\\n\"\n#define TRACE_MSG_METH_STR_STR L\"%s[0x%p](%s, %s)\\n\"\n#define TRACE_MSG_METH_STR_DBL L\"%s[0x%p](%s, %lf)\\n\"\n#define TRACE_MSG_METH_STR_FLT L\"%s[0x%p](%s, %f)\\n\"\n#define TRACE_MSG_METH_STR_INT L\"%s[0x%p](%s, %d)\\n\"\n#define TRACE_MSG_METH_STR_STR_STR L\"%s[0x%p](%s, %s, %s)\\n\"\n#define TRACE_MSG_METH_STR_INT_INT L\"%s[0x%p](%s, %d, %d)\\n\"\n#define TRACE_MSG_METH_STR_FLT_FLT L\"%s[0x%p](%s, %f, %f)\\n\"\n#define TRACE_MSG_METH_STR_STR_FLT L\"%s[0x%p](%s, %s, %f)\\n\"\n#define TRACE_MSG_METH_STR_STR_INT_INT L\"%s[0x%p](%s, %s, %d, %d)\\n\"\n\n#define TRACE_MSG_METH_METH L\"%s[0x%p] - calls %s()\\n\"\n#define TRACE_MSG_METH_METH_INT L\"%s[0x%p] - calls %s(%d)\\n\"\n#define TRACE_MSG_METH_METH_STR L\"%s[0x%p] - calls %s(%s)\\n\"\n#define TRACE_MSG_METH_METH_STR_STR L\"%s[0x%p] - calls %s(%s, %s)\\n\"\n#define TRACE_MSG_METH_METH_FLT_STR L\"%s[0x%p] - calls %s(%f, %s)\\n\"\n#define TRACE_MSG_METH_METH_FLT_FLT_FLT L\"%s[0x%p] - calls %s(%f, %f, %f)\\n\"\n\n// Current method name\n#define METH_NAME StringUtil::Utf8ToUtf16(__FUNCTION__).c_str()\n\n// TraceLogging provider name for telemetry.\n#define TELEMETRY_PROVIDER_NAME \"Microsoft.Management.Configuration\"\n\nTRACELOGGING_DECLARE_PROVIDER(g_hTraceProvider);\nextern bool g_IsTelemetryProviderEnabled;\nextern UCHAR g_TelemetryProviderLevel;\nextern ULONGLONG g_TelemetryProviderMatchAnyKeyword;\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/TestConfigurationSetResult.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestConfigurationSetResult.h\"\r\n#include \"TestConfigurationSetResult.g.cpp\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    TestConfigurationSetResult::TestConfigurationSetResult() : m_unitResults(multi_threaded_vector<TestConfigurationUnitResult>())\r\n    {\r\n    }\r\n\r\n    void TestConfigurationSetResult::AppendUnitResult(const TestConfigurationUnitResult& unitResult)\r\n    {\r\n        m_unitResults.Append(unitResult);\r\n\r\n        // Also aggregate the result of this incoming test into the overall result\r\n        m_testResult = FoldInTestResult(m_testResult, unitResult.TestResult());\r\n    }\r\n\r\n    ConfigurationTestResult TestConfigurationSetResult::FoldInTestResult(ConfigurationTestResult current, ConfigurationTestResult incoming)\r\n    {\r\n        switch (current)\r\n        {\r\n        case ConfigurationTestResult::Unknown:\r\n        case ConfigurationTestResult::NotRun:\r\n            // In these \"default\" cases, just take the unit result\r\n            return incoming;\r\n            break;\r\n        case ConfigurationTestResult::Positive:\r\n            if (incoming == ConfigurationTestResult::Negative || incoming == ConfigurationTestResult::Failed)\r\n            {\r\n                return incoming;\r\n            }\r\n            break;\r\n        case ConfigurationTestResult::Negative:\r\n            if (incoming == ConfigurationTestResult::Failed)\r\n            {\r\n                return incoming;\r\n            }\r\n            break;\r\n        case ConfigurationTestResult::Failed:\r\n            // If a unit failed, the set failed\r\n            break;\r\n        default:\r\n            THROW_HR(E_UNEXPECTED);\r\n        }\r\n\r\n        return current;\r\n    }\r\n\r\n    Windows::Foundation::Collections::IVectorView<TestConfigurationUnitResult> TestConfigurationSetResult::UnitResults() const\r\n    {\r\n        return m_unitResults.GetView();\r\n    }\r\n\r\n    ConfigurationTestResult TestConfigurationSetResult::TestResult() const\r\n    {\r\n        return m_testResult;\r\n    }\r\n\r\n    void TestConfigurationSetResult::TestResult(ConfigurationTestResult value)\r\n    {\r\n        m_testResult = value;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/TestConfigurationSetResult.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"TestConfigurationSetResult.g.h\"\r\n#include <winrt/Windows.Foundation.Collections.h>\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    struct TestConfigurationSetResult : TestConfigurationSetResultT<TestConfigurationSetResult>\r\n    {\r\n        TestConfigurationSetResult();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        void AppendUnitResult(const TestConfigurationUnitResult& unitResult);\r\n        void TestResult(ConfigurationTestResult value);\r\n\r\n        static ConfigurationTestResult FoldInTestResult(ConfigurationTestResult current, ConfigurationTestResult incoming);\r\n#endif\r\n\r\n        Windows::Foundation::Collections::IVectorView<TestConfigurationUnitResult> UnitResults() const;\r\n        ConfigurationTestResult TestResult() const;\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        Windows::Foundation::Collections::IVector<TestConfigurationUnitResult> m_unitResults = nullptr;\r\n        ConfigurationTestResult m_testResult = ConfigurationTestResult::Unknown;\r\n#endif\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/TestConfigurationUnitResult.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestConfigurationUnitResult.h\"\r\n#include \"TestConfigurationUnitResult.g.cpp\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    void TestConfigurationUnitResult::Initialize(const ITestSettingsResult& result)\r\n    {\r\n        m_unit = result.Unit();\r\n        THROW_HR_IF(E_POINTER, !m_unit);\r\n        m_testResult = result.TestResult();\r\n        m_resultInformation = result.ResultInformation();\r\n        THROW_HR_IF(E_POINTER, !m_resultInformation);\r\n    }\r\n\r\n    void TestConfigurationUnitResult::Unit(const ConfigurationUnit& unit)\r\n    {\r\n        m_unit = unit;\r\n    }\r\n\r\n    ConfigurationUnit TestConfigurationUnitResult::Unit()\r\n    {\r\n        return m_unit;\r\n    }\r\n\r\n    IConfigurationUnitResultInformation TestConfigurationUnitResult::ResultInformation()\r\n    {\r\n        return m_resultInformation;\r\n    }\r\n\r\n    void TestConfigurationUnitResult::ResultInformation(const IConfigurationUnitResultInformation& value)\r\n    {\r\n        m_resultInformation = value;\r\n    }\r\n\r\n    ConfigurationTestResult TestConfigurationUnitResult::TestResult()\r\n    {\r\n        return m_testResult;\r\n    }\r\n\r\n    void TestConfigurationUnitResult::TestResult(ConfigurationTestResult value)\r\n    {\r\n        m_testResult = value;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/TestConfigurationUnitResult.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"TestConfigurationUnitResult.g.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    struct TestConfigurationUnitResult : TestConfigurationUnitResultT<TestConfigurationUnitResult>\r\n    {\r\n        using ConfigurationUnit = Configuration::ConfigurationUnit;\r\n\r\n        TestConfigurationUnitResult() = default;\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        void Initialize(const ITestSettingsResult& result);\r\n\r\n        void Unit(const ConfigurationUnit& unit);\r\n        void ResultInformation(const IConfigurationUnitResultInformation& value);\r\n        void TestResult(ConfigurationTestResult value);\r\n#endif\r\n\r\n        ConfigurationUnit Unit();\r\n        IConfigurationUnitResultInformation ResultInformation();\r\n        ConfigurationTestResult TestResult();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        ConfigurationUnit m_unit = nullptr;\r\n        IConfigurationUnitResultInformation m_resultInformation;\r\n        ConfigurationTestResult m_testResult = ConfigurationTestResult::Unknown;\r\n#endif\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/TestGroupSettingsResult.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestGroupSettingsResult.h\"\r\n#include \"TestConfigurationSetResult.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    TestGroupSettingsResult::TestGroupSettingsResult() :\r\n        m_resultInformation(make_self<wil::details::module_count_wrapper<implementation::ConfigurationUnitResultInformation>>()),\r\n        m_unitResults(winrt::multi_threaded_vector<ITestSettingsResult>())\r\n    {}\r\n\r\n    void TestGroupSettingsResult::Group(const Windows::Foundation::IInspectable& value)\r\n    {\r\n        m_group = value;\r\n    }\r\n\r\n    void TestGroupSettingsResult::TestResult(ConfigurationTestResult value)\r\n    {\r\n        m_testResult = value;\r\n    }\r\n\r\n    TestGroupSettingsResult::ResultInformationPtr TestGroupSettingsResult::ResultInformationInternal()\r\n    {\r\n        return m_resultInformation;\r\n    }\r\n\r\n    void TestGroupSettingsResult::AppendUnitResult(const ITestSettingsResult& value)\r\n    {\r\n        m_unitResults.Append(value);\r\n\r\n        // Also aggregate the result of this incoming test into the overall result\r\n        m_testResult = TestConfigurationSetResult::FoldInTestResult(m_testResult, value.TestResult());\r\n    }\r\n\r\n    Windows::Foundation::IInspectable TestGroupSettingsResult::Group()\r\n    {\r\n        return m_group;\r\n    }\r\n\r\n    ConfigurationTestResult TestGroupSettingsResult::TestResult()\r\n    {\r\n        return m_testResult;\r\n    }\r\n\r\n    IConfigurationUnitResultInformation TestGroupSettingsResult::ResultInformation()\r\n    {\r\n        return *m_resultInformation;\r\n    }\r\n\r\n    Windows::Foundation::Collections::IVector<ITestSettingsResult> TestGroupSettingsResult::UnitResults()\r\n    {\r\n        return m_unitResults;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/TestGroupSettingsResult.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"winrt/Microsoft.Management.Configuration.h\"\r\n#include \"ConfigurationUnitResultInformation.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    struct TestGroupSettingsResult : winrt::implements<TestGroupSettingsResult, ITestGroupSettingsResult>\r\n    {\r\n        TestGroupSettingsResult();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        using ResultInformationPtr = decltype(make_self<wil::details::module_count_wrapper<implementation::ConfigurationUnitResultInformation>>());\r\n\r\n        void Group(const Windows::Foundation::IInspectable& value);\r\n        void TestResult(ConfigurationTestResult value);\r\n        ResultInformationPtr ResultInformationInternal();\r\n        void AppendUnitResult(const ITestSettingsResult& value);\r\n#endif\r\n\r\n        Windows::Foundation::IInspectable Group();\r\n        ConfigurationTestResult TestResult();\r\n        IConfigurationUnitResultInformation ResultInformation();\r\n        Windows::Foundation::Collections::IVector<ITestSettingsResult> UnitResults();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        Windows::Foundation::IInspectable m_group;\r\n        ConfigurationTestResult m_testResult = ConfigurationTestResult::Unknown;\r\n        ResultInformationPtr m_resultInformation;\r\n        Windows::Foundation::Collections::IVector<ITestSettingsResult> m_unitResults;\r\n#endif\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/TestSettingsResult.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"TestSettingsResult.h\"\r\n#include \"ConfigurationUnitResultInformation.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    void TestSettingsResult::Unit(const ConfigurationUnit& value)\r\n    {\r\n        m_unit = value;\r\n    }\r\n\r\n    void TestSettingsResult::TestResult(ConfigurationTestResult value)\r\n    {\r\n        m_testResult = value;\r\n    }\r\n\r\n    void TestSettingsResult::ResultInformation(const IConfigurationUnitResultInformation& value)\r\n    {\r\n        m_resultInformation = value;\r\n    }\r\n\r\n    ConfigurationUnit TestSettingsResult::Unit()\r\n    {\r\n        return m_unit;\r\n    }\r\n\r\n    ConfigurationTestResult TestSettingsResult::TestResult()\r\n    {\r\n        return m_testResult;\r\n    }\r\n\r\n    IConfigurationUnitResultInformation TestSettingsResult::ResultInformation()\r\n    {\r\n        return m_resultInformation;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/TestSettingsResult.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"winrt/Microsoft.Management.Configuration.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Configuration::implementation\r\n{\r\n    struct TestSettingsResult : winrt::implements<TestSettingsResult, ITestSettingsResult>\r\n    {\r\n        using ConfigurationUnit = Configuration::ConfigurationUnit;\r\n\r\n        TestSettingsResult() = default;\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        void Unit(const ConfigurationUnit& value);\r\n        void TestResult(ConfigurationTestResult value);\r\n        void ResultInformation(const IConfigurationUnitResultInformation& value);\r\n#endif\r\n\r\n        ConfigurationUnit Unit();\r\n        ConfigurationTestResult TestResult();\r\n        IConfigurationUnitResultInformation ResultInformation();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        ConfigurationUnit m_unit = nullptr;\r\n        ConfigurationTestResult m_testResult = ConfigurationTestResult::Unknown;\r\n        IConfigurationUnitResultInformation m_resultInformation;\r\n#endif\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<packages>\r\n  <package id=\"Microsoft.Windows.CppWinRT\" version=\"2.0.250303.1\" targetFramework=\"native\" />\r\n  <package id=\"Microsoft.Windows.ImplementationLibrary\" version=\"1.0.250325.1\" targetFramework=\"native\" />\r\n</packages>"
  },
  {
    "path": "src/Microsoft.Management.Configuration/pch.cpp",
    "content": "﻿// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration/pch.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n\r\n#define NOMINMAX\r\n\r\n#include <unknwn.h>\r\n#include <winrt/Windows.Foundation.h>\r\n#include <winrt/Windows.Foundation.Collections.h>\r\n#include <winrt/Windows.Storage.Streams.h>\r\n\r\n#pragma warning( push )\r\n#pragma warning ( disable : 4324 4467 6388 )\r\n// 4324 Structure was padded due to alignment specifier\r\n// 4467 Allow use of uuid attribute for com object creation.\r\n// 6388 Allow CreateInstance.\r\n#include <wil/cppwinrt_wrl.h>\r\n#include <wil/resource.h>\r\n#pragma warning( pop )\r\n\r\n#include <atomic>\r\n#include <chrono>\r\n#include <filesystem>\r\n#include <fstream>\r\n#include <functional>\r\n#include <limits>\r\n#include <map>\r\n#include <memory>\r\n#include <mutex>\r\n#include <optional>\r\n#include <queue>\r\n#include <sstream>\r\n#include <stack>\r\n#include <stdexcept>\r\n#include <string>\r\n#include <string_view>\r\n#include <tuple>\r\n#include <utility>\r\n#include <vector>\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.OutOfProc/Collect-ConfigurationOOPTests.ps1",
    "content": "# Copyright (c) Microsoft Corporation.\r\n# Licensed under the MIT License.\r\n[CmdletBinding()]\r\nparam(\r\n    [string]$TargetLocation\r\n)\r\n\r\n$Local:settingsExport = ConvertFrom-Json (wingetdev.exe settings export)\r\n$Local:logsFilePath = Join-Path (Split-Path $Local:settingsExport.userSettingsFile -Parent) \"DiagOutputDir\"\r\n\r\nGet-AppxPackage WinGetDevCLI | Remove-AppxPackage\r\n\r\nCopy-Item $Local:logsFilePath $TargetLocation -Recurse -Force -ErrorAction Ignore\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.OutOfProc/Factory.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Factory.h\"\r\n#include <winrt/Microsoft.Management.Configuration.h>\r\n#include <winget/Runtime.h>\r\n#include <WinGetServerManualActivation_Client.h>\r\n\r\nnamespace Microsoft::Management::Configuration::OutOfProc\r\n{\r\n    namespace\r\n    {\r\n        const CLSID& GetConfigurationStaticsCLSID()\r\n        {\r\n#if USE_PROD_CLSIDS\r\n            static const CLSID CLSID_ConfigurationStatics = { 0x73d763b7,0x2937,0x432f,{0xa9,0x7a,0xd9,0x8a,0x4a,0x59,0x61,0x26} };  // 73D763B7-2937-432F-A97A-D98A4A596126\r\n#else\r\n            static const CLSID CLSID_ConfigurationStatics = { 0xc9ed7917,0x66ab,0x4e31,{0xa9,0x2a,0xf6,0x5f,0x18,0xef,0x79,0x33} };  // C9ED7917-66AB-4E31-A92A-F65F18EF7933\r\n#endif\r\n\r\n            return CLSID_ConfigurationStatics;\r\n        }\r\n\r\n        winrt::Microsoft::Management::Configuration::IConfigurationStatics CreateOOPStaticsObject()\r\n        {\r\n            bool isAdmin = AppInstaller::Runtime::IsRunningAsAdmin();\r\n\r\n            try\r\n            {\r\n                return winrt::create_instance<winrt::Microsoft::Management::Configuration::IConfigurationStatics>(GetConfigurationStaticsCLSID(), CLSCTX_LOCAL_SERVER | CLSCTX_NO_CODE_DOWNLOAD);\r\n            }\r\n            catch (const winrt::hresult_error& hre)\r\n            {\r\n                // We only want to fall through to trying the manual activation if we are running as admin and couldn't find the registration.\r\n                if (!(isAdmin && hre.code() == REGDB_E_CLASSNOTREG))\r\n                {\r\n                    throw;\r\n                }\r\n            }\r\n\r\n            winrt::com_ptr<::IUnknown> result;\r\n            THROW_IF_FAILED(WinGetServerManualActivation_CreateInstance(GetConfigurationStaticsCLSID(), winrt::guid_of<winrt::Microsoft::Management::Configuration::IConfigurationStatics>(), 0, result.put_void()));\r\n            return result.as<winrt::Microsoft::Management::Configuration::IConfigurationStatics>();\r\n        }\r\n    }\r\n\r\n    Factory::Factory()\r\n    {\r\n        IncrementRefCount();\r\n    }\r\n\r\n    Factory::~Factory()\r\n    {\r\n        DecrementRefCount();\r\n    }\r\n\r\n    bool Factory::HasReferences()\r\n    {\r\n        return s_referenceCount.load() != 0;\r\n    }\r\n\r\n    void Factory::Terminate()\r\n    {\r\n        WinGetServerManualActivation_Terminate();\r\n    }\r\n\r\n    bool Factory::IsCLSID(const GUID& clsid)\r\n    {\r\n        if (clsid == GetConfigurationStaticsCLSID())\r\n        {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    bool Factory::IsCLSID(HSTRING clsid)\r\n    {\r\n        constexpr std::wstring_view s_ClassName = L\"Microsoft.Management.Configuration.ConfigurationStaticFunctions\";\r\n\r\n        UINT32 length = 0;\r\n        PCWSTR buffer = WindowsGetStringRawBuffer(clsid, &length);\r\n\r\n        if (std::wstring_view{ buffer, length } == s_ClassName)\r\n        {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    winrt::Windows::Foundation::IInspectable Factory::ActivateInstance()\r\n    {\r\n        return CreateOOPStaticsObject().as<winrt::Windows::Foundation::IInspectable>();\r\n    }\r\n\r\n    HRESULT STDMETHODCALLTYPE Factory::CreateInstance(::IUnknown* pUnkOuter, REFIID riid, void** ppvObject) try\r\n    {\r\n        RETURN_HR_IF(E_POINTER, !ppvObject);\r\n        *ppvObject = nullptr;\r\n        RETURN_HR_IF(CLASS_E_NOAGGREGATION, pUnkOuter != nullptr);\r\n\r\n        return CreateOOPStaticsObject().as(riid, ppvObject);\r\n    }\r\n    CATCH_RETURN();\r\n\r\n    HRESULT STDMETHODCALLTYPE Factory::LockServer(BOOL fLock)\r\n    {\r\n        if (fLock)\r\n        {\r\n            IncrementRefCount();\r\n        }\r\n        else\r\n        {\r\n            DecrementRefCount();\r\n        }\r\n\r\n        return S_OK;\r\n    }\r\n\r\n    void Factory::IncrementRefCount()\r\n    {\r\n        ++s_referenceCount;\r\n    }\r\n\r\n    void Factory::DecrementRefCount()\r\n    {\r\n        --s_referenceCount;\r\n    }\r\n\r\n    std::atomic<int32_t> Factory::s_referenceCount = ATOMIC_VAR_INIT(0);\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.OutOfProc/Factory.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <hstring.h>\r\n#include <inspectable.h>\r\n#include <winrt/Windows.Foundation.h>\r\n#include <atomic>\r\n\r\nnamespace Microsoft::Management::Configuration::OutOfProc\r\n{\r\n    struct Factory : winrt::implements<Factory, winrt::Windows::Foundation::IActivationFactory, IClassFactory>\r\n    {\r\n        Factory();\r\n        ~Factory();\r\n\r\n        // Returns true if the reference count is not 0; false if it is.\r\n        static bool HasReferences();\r\n\r\n        // Forcibly destroys any static objects.\r\n        static void Terminate();\r\n\r\n        // Determines if the given CLSID is the CLSID for the factory.\r\n        static bool IsCLSID(const GUID& clsid);\r\n\r\n        // Determines if the given CLSID is the CLSID for the factory.\r\n        static bool IsCLSID(HSTRING clsid);\r\n\r\n        // IActivationFactory\r\n        winrt::Windows::Foundation::IInspectable ActivateInstance();\r\n\r\n        // IClassFactory\r\n        HRESULT STDMETHODCALLTYPE CreateInstance(::IUnknown *pUnkOuter, REFIID riid, void **ppvObject);\r\n        HRESULT STDMETHODCALLTYPE LockServer(BOOL fLock);\r\n\r\n    private:\r\n        static void IncrementRefCount();\r\n        static void DecrementRefCount();\r\n\r\n        static std::atomic<int32_t> s_referenceCount;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.OutOfProc/Microsoft.Management.Configuration.OutOfProc.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" />\r\n  <PropertyGroup Label=\"Globals\">\r\n    <CppWinRTOptimized>true</CppWinRTOptimized>\r\n    <CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>\r\n    <MinimalCoreWin>true</MinimalCoreWin>\r\n    <VCProjectVersion>15.0</VCProjectVersion>\r\n    <Keyword>Win32Proj</Keyword>\r\n    <RootNamespace>MicrosoftManagementConfigurationOutOfProc</RootNamespace>\r\n    <WindowsTargetPlatformVersion>10.0.26100.0</WindowsTargetPlatformVersion>\r\n    <WindowsTargetPlatformMinVersion>10.0.17763.0</WindowsTargetPlatformMinVersion>\r\n    <WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>\r\n    <CppWinRTGenerateWindowsMetadata>false</CppWinRTGenerateWindowsMetadata>\r\n    <ProjectGuid>{2268D5AD-7F2A-485A-8C4B-C574497514C9}</ProjectGuid>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|ARM64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|Win32\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|ARM64\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|Win32\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|x64\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|ARM64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|Win32\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <PropertyGroup Label=\"Configuration\">\r\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Debug'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n    <LinkIncremental>true</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Release'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <LinkIncremental>false</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='ReleaseStatic'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <LinkIncremental>false</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\" Label=\"Configuration\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\" Label=\"Configuration\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\" Label=\"Configuration\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\r\n  <ImportGroup Label=\"ExtensionSettings\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"Shared\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"PropertySheet.props\" />\r\n  </ImportGroup>\r\n  <PropertyGroup Label=\"UserMacros\" />\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>true</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>true</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>true</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(ProjectDir)\\..\\vcpkg.props\" />\r\n  <ItemDefinitionGroup>\r\n    <ClCompile>\r\n      <PrecompiledHeader>Use</PrecompiledHeader>\r\n      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>\r\n      <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>\r\n      <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <AdditionalOptions>%(AdditionalOptions) /permissive- /bigobj /D _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING</AdditionalOptions>\r\n    </ClCompile>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Debug'\">\r\n    <ClCompile>\r\n      <Optimization>Disabled</Optimization>\r\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\WinGetServer;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\WinGetServer;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</TreatWarningAsError>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">false</ControlFlowGuard>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</ControlFlowGuard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">stdcpp17</LanguageStandard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">stdcpp17</LanguageStandard>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</EnablePREfast>\r\n      <DisableSpecificWarnings Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">6001</DisableSpecificWarnings>\r\n      <DisableSpecificWarnings Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">6001</DisableSpecificWarnings>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">Windows</SubSystem>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Source.def</ModuleDefinitionFile>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">Source.def</ModuleDefinitionFile>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">Source.def</ModuleDefinitionFile>\r\n      <AdditionalDependencies Condition=\"'$(Configuration)'=='Debug'\">wininet.lib;shell32.lib;winsqlite3.lib;shlwapi.lib;icuuc.lib;icuin.lib;urlmon.lib;Advapi32.lib;winhttp.lib;onecoreuap.lib;msi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</CETCompat>\r\n    </Link>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Platform)'=='Win32'\">\r\n    <ClCompile>\r\n      <PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\WinGetServer;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</TreatWarningAsError>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</ControlFlowGuard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">stdcpp17</LanguageStandard>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</EnablePREfast>\r\n      <DisableSpecificWarnings Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">6001</DisableSpecificWarnings>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Link>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</CETCompat>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Release'\">\r\n    <ClCompile>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\WinGetServer;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\WinGetServer;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\WinGetServer;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">true</TreatWarningAsError>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">Guard</ControlFlowGuard>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Guard</ControlFlowGuard>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Guard</ControlFlowGuard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">stdcpp17</LanguageStandard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">stdcpp17</LanguageStandard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">stdcpp17</LanguageStandard>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</EnablePREfast>\r\n      <DisableSpecificWarnings Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">6001</DisableSpecificWarnings>\r\n      <DisableSpecificWarnings Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">6001</DisableSpecificWarnings>\r\n      <DisableSpecificWarnings Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">6001</DisableSpecificWarnings>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Windows</SubSystem>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Source.def</ModuleDefinitionFile>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">Source.def</ModuleDefinitionFile>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Source.def</ModuleDefinitionFile>\r\n      <AdditionalDependencies Condition=\"'$(Configuration)'=='Release'\">wininet.lib;shell32.lib;winsqlite3.lib;shlwapi.lib;icuuc.lib;icuin.lib;urlmon.lib;Advapi32.lib;winhttp.lib;onecoreuap.lib;msi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">/debug:full /debugtype:cv,fixup /incremental:no %(AdditionalOptions)</AdditionalOptions>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">/debug:full /debugtype:cv,fixup /incremental:no %(AdditionalOptions)</AdditionalOptions>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">/debug:full /debugtype:cv,fixup /incremental:no %(AdditionalOptions)</AdditionalOptions>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</CETCompat>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">true</CETCompat>\r\n    </Link>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='ReleaseStatic'\">\r\n    <ClCompile>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\WinGetServer;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\WinGetServer;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\WinGetServer;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">true</TreatWarningAsError>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">Guard</ControlFlowGuard>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">Guard</ControlFlowGuard>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">Guard</ControlFlowGuard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">stdcpp17</LanguageStandard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">stdcpp17</LanguageStandard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">stdcpp17</LanguageStandard>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">false</EnablePREfast>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">MultiThreaded</RuntimeLibrary>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">MultiThreaded</RuntimeLibrary>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">MultiThreaded</RuntimeLibrary>\r\n      <DisableSpecificWarnings Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">6001</DisableSpecificWarnings>\r\n      <DisableSpecificWarnings Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">6001</DisableSpecificWarnings>\r\n      <DisableSpecificWarnings Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">6001</DisableSpecificWarnings>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">Windows</SubSystem>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">Source.def</ModuleDefinitionFile>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">Source.def</ModuleDefinitionFile>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">Source.def</ModuleDefinitionFile>\r\n      <AdditionalDependencies Condition=\"'$(Configuration)'=='ReleaseStatic'\">wininet.lib;shell32.lib;winsqlite3.lib;shlwapi.lib;icuuc.lib;icuin.lib;urlmon.lib;Advapi32.lib;winhttp.lib;onecoreuap.lib;msi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">/debug:full /debugtype:cv,fixup /incremental:no %(AdditionalOptions)</AdditionalOptions>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">/debug:full /debugtype:cv,fixup /incremental:no %(AdditionalOptions)</AdditionalOptions>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">/debug:full /debugtype:cv,fixup /incremental:no %(AdditionalOptions)</AdditionalOptions>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">true</CETCompat>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">true</CETCompat>\r\n    </Link>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n  </ItemDefinitionGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"Factory.h\" />\r\n    <ClInclude Include=\"pch.h\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"..\\WinGetServer\\Utils.cpp\">\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">NotUsing</PrecompiledHeader>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\WinGetServer\\WinGetServerManualActivation_Client.cpp\">\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">NotUsing</PrecompiledHeader>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\WinGetServer\\WinGetServer_c.c\">\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">NotUsing</PrecompiledHeader>\r\n    </ClCompile>\r\n    <ClCompile Include=\"dllmain.cpp\" />\r\n    <ClCompile Include=\"Factory.cpp\" />\r\n    <ClCompile Include=\"pch.cpp\">\r\n      <PrecompiledHeader>Create</PrecompiledHeader>\r\n    </ClCompile>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"Collect-ConfigurationOOPTests.ps1\" />\r\n    <None Include=\"packages.config\" />\r\n    <None Include=\"Prepare-ConfigurationOOPTests.ps1\" />\r\n    <None Include=\"PropertySheet.props\" />\r\n    <None Include=\"Source.def\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\AppInstallerSharedLib\\AppInstallerSharedLib.vcxproj\">\r\n      <Project>{f3f6e699-bc5d-4950-8a05-e49dd9eb0d51}</Project>\r\n    </ProjectReference>\r\n    <ProjectReference Include=\"..\\Microsoft.Management.Configuration\\Microsoft.Management.Configuration.vcxproj\">\r\n      <Project>{ca460806-5e41-4e97-9a3d-1d74b433b663}</Project>\r\n    </ProjectReference>\r\n  </ItemGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\r\n  <ImportGroup Label=\"ExtensionTargets\">\r\n    <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets')\" />\r\n    <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" />\r\n  </ImportGroup>\r\n  <Target Name=\"EnsureNuGetPackageBuildImports\" BeforeTargets=\"PrepareForBuild\">\r\n    <PropertyGroup>\r\n      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>\r\n    </PropertyGroup>\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets'))\" />\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props'))\" />\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets'))\" />\r\n  </Target>\r\n</Project>\r\n\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.OutOfProc/Microsoft.Management.Configuration.OutOfProc.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup>\r\n    <Filter Include=\"Source Files\">\r\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r\n      <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Header Files\">\r\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r\n      <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Resource Files\">\r\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"WinGetServerManualActivation\">\r\n      <UniqueIdentifier>{6017fd94-3eb1-40bc-964f-5dd571077d3c}</UniqueIdentifier>\r\n    </Filter>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"pch.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Factory.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"dllmain.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"pch.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Factory.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\WinGetServer\\WinGetServer_c.c\">\r\n      <Filter>WinGetServerManualActivation</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\WinGetServer\\WinGetServerManualActivation_Client.cpp\">\r\n      <Filter>WinGetServerManualActivation</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\WinGetServer\\Utils.cpp\">\r\n      <Filter>WinGetServerManualActivation</Filter>\r\n    </ClCompile>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"packages.config\" />\r\n    <None Include=\"PropertySheet.props\" />\r\n    <None Include=\"Source.def\">\r\n      <Filter>Source Files</Filter>\r\n    </None>\r\n    <None Include=\"Collect-ConfigurationOOPTests.ps1\" />\r\n    <None Include=\"Prepare-ConfigurationOOPTests.ps1\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Natvis Include=\"$(MSBuildThisFileDirectory)..\\..\\natvis\\wil.natvis\" />\r\n  </ItemGroup>\r\n</Project>"
  },
  {
    "path": "src/Microsoft.Management.Configuration.OutOfProc/Prepare-ConfigurationOOPTests.ps1",
    "content": "# Copyright (c) Microsoft Corporation.\r\n# Licensed under the MIT License.\r\n[CmdletBinding()]\r\nparam(\r\n    [string]$BuildOutputPath,\r\n\r\n    [string]$PackageLayoutPath\r\n)\r\n\r\n# Copy the winmd into the unit test directory since it will be needed for marshalling\r\n$Local:winmdSourcePath = Join-Path $BuildOutputPath \"Microsoft.Management.Configuration\\Microsoft.Management.Configuration.winmd\"\r\n$Local:winmdTargetPath = Join-Path $BuildOutputPath \"Microsoft.Management.Configuration.UnitTests\\net8.0-windows10.0.26100.0\\Microsoft.Management.Configuration.winmd\"\r\n\r\nCopy-Item $Local:winmdSourcePath $Local:winmdTargetPath -Force\r\n\r\n# Copy the OOP helper dll into the unit test directory to make activation look the same as in-proc\r\n$Local:dllSourcePath = Join-Path $BuildOutputPath \"Microsoft.Management.Configuration.OutOfProc\\Microsoft.Management.Configuration.OutOfProc.dll\"\r\n$Local:dllTargetPath = Join-Path $BuildOutputPath \"Microsoft.Management.Configuration.UnitTests\\net8.0-windows10.0.26100.0\\Microsoft.Management.Configuration.dll\"\r\n\r\nCopy-Item $Local:dllSourcePath $Local:dllTargetPath -Force\r\n\r\n# Register the package\r\nif (-not [System.String]::IsNullOrEmpty($PackageLayoutPath))\r\n{\r\n    $Local:packageManifestPath = Join-Path $PackageLayoutPath \"AppxManifest.xml\"\r\n\r\n    Add-AppxPackage -ForceApplicationShutdown -Register $Local:packageManifestPath\r\n\r\n    # Configure crash dump and log file settings\r\n    $Local:settingsExport = ConvertFrom-Json (wingetdev.exe settings export)\r\n    $Local:settingsFilePath = $Local:settingsExport.userSettingsFile\r\n    $Local:settingsFileContent = ConvertTo-Json @{ debugging= @{ enableSelfInitiatedMinidump=$true ; keepAllLogFiles=$true } ; experimentalFeatures= @{ configuration03=$true } }\r\n\r\n    Set-Content -Path $Local:settingsFilePath -Value $Local:settingsFileContent\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.OutOfProc/PropertySheet.props",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ImportGroup Label=\"PropertySheets\" />\n  <PropertyGroup Label=\"UserMacros\" />\n    <!--\n    To customize common C++/WinRT project properties: \n    * right-click the project node\n    * expand the Common Properties item\n    * select the C++/WinRT property page\n\n    For more advanced scenarios, and complete documentation, please see:\n    https://github.com/Microsoft/xlang/tree/master/src/package/cppwinrt/nuget \n    -->\n  <PropertyGroup />\n  <ItemDefinitionGroup />\n</Project>"
  },
  {
    "path": "src/Microsoft.Management.Configuration.OutOfProc/Source.def",
    "content": "EXPORTS\nDllCanUnloadNow             PRIVATE\nDllGetClassObject           PRIVATE\nDllGetActivationFactory     PRIVATE\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.OutOfProc/dllmain.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Factory.h\"\r\n#include <hstring.h>\r\n\r\nusing namespace Microsoft::Management::Configuration::OutOfProc;\r\n\r\nEXTERN_C BOOL WINAPI DllMain(\r\n    HMODULE /* hModule */,\r\n    DWORD reason,\r\n    LPVOID /* lpReserved */)\r\n{\r\n    switch (reason)\r\n    {\r\n    case DLL_PROCESS_DETACH:\r\n        Factory::Terminate();\r\n        break;\r\n    }\r\n\r\n    return TRUE;\r\n}\r\n\r\n_Check_return_\r\nSTDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ LPVOID FAR* ppv) try\r\n{\r\n    RETURN_HR_IF(E_POINTER, !ppv);\r\n    *ppv = nullptr;\r\n\r\n    winrt::Windows::Foundation::IUnknown result;\r\n\r\n    if (Factory::IsCLSID(rclsid))\r\n    {\r\n        result = winrt::make<Factory>().as<winrt::Windows::Foundation::IUnknown>();\r\n    }\r\n\r\n    if (result)\r\n    {\r\n        return result.as(riid, ppv);\r\n    }\r\n\r\n    return REGDB_E_CLASSNOTREG;\r\n}\r\nCATCH_RETURN();\r\n\r\n__control_entrypoint(DllExport)\r\nSTDAPI DllCanUnloadNow()\r\n{\r\n    return Factory::HasReferences() ? S_FALSE : S_OK;\r\n}\r\n\r\nSTDAPI DllGetActivationFactory(HSTRING classId, void** factory) try\r\n{\r\n    RETURN_HR_IF(E_POINTER, !factory);\r\n    *factory = nullptr;\r\n\r\n    winrt::Windows::Foundation::IUnknown result;\r\n\r\n    if (Factory::IsCLSID(classId))\r\n    {\r\n        result = winrt::make<Factory>().as<winrt::Windows::Foundation::IUnknown>();\r\n    }\r\n\r\n    if (result)\r\n    {\r\n        return result.as(winrt::guid_of<winrt::Windows::Foundation::IActivationFactory>(), factory);\r\n    }\r\n\r\n    return REGDB_E_CLASSNOTREG;\r\n}\r\nCATCH_RETURN();\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.OutOfProc/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<packages>\r\n  <package id=\"Microsoft.Windows.CppWinRT\" version=\"2.0.250303.1\" targetFramework=\"native\" />\r\n  <package id=\"Microsoft.Windows.ImplementationLibrary\" version=\"1.0.250325.1\" targetFramework=\"native\" />\r\n</packages>"
  },
  {
    "path": "src/Microsoft.Management.Configuration.OutOfProc/pch.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n\r\n#include \"pch.h\"\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.OutOfProc/pch.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#define WIN32_LEAN_AND_MEAN\r\n#include <Windows.h>\r\n#include <Unknwnbase.h>\r\n#include <inspectable.h>\r\n#include <winstring.h>\r\n\r\n#include <wil/result_macros.h>\r\n#include <winrt/Windows.Foundation.h>\r\n\r\n#include <atomic>\r\n#include <string_view>\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Constants/DirectiveConstants.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"DirectiveConstants.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Constants\r\n{\r\n    /// <summary>\r\n    /// Directives.\r\n    /// </summary>\r\n    internal static class DirectiveConstants\r\n    {\r\n#pragma warning disable SA1600 // ElementsMustBeDocumented\r\n        public const string MaxVersion = \"maxVersion\";\r\n        public const string MinVersion = \"minVersion\";\r\n        public const string Module = \"module\";\r\n        public const string ModuleGuid = \"moduleGuid\";\r\n        public const string Repository = \"repository\";\r\n        public const string Version = \"version\";\r\n        public const string AllowPrerelease = \"allowPrerelease\";\r\n#pragma warning restore SA1600 // ElementsMustBeDocumented\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Helpers/FindDscPackageStateMachine.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"FindDscPackageStateMachine.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Helpers\r\n{\r\n    using System;\r\n\r\n    /// <summary>\r\n    /// Provides the state machine that decides which DSC package to use.\r\n    /// </summary>\r\n    internal class FindDscPackageStateMachine\r\n    {\r\n        private const string StableDscPackageFamilyName = \"Microsoft.DesiredStateConfiguration_8wekyb3d8bbwe\";\r\n        private const string PreviewDscPackageFamilyName = \"Microsoft.DesiredStateConfiguration-Preview_8wekyb3d8bbwe\";\r\n\r\n        private readonly Version minimumStableVersion = new Version(3, 1);\r\n        private readonly Version minimumPreviewVersion = new Version(3, 1, 7);\r\n\r\n        private State currentState = State.Initial;\r\n        private string? dscExecutablePath;\r\n\r\n        /// <summary>\r\n        /// A state of the state machine.\r\n        /// </summary>\r\n        public enum State\r\n        {\r\n            /// <summary>\r\n            /// The initial state.\r\n            /// </summary>\r\n            Initial,\r\n\r\n            /// <summary>\r\n            /// A stable installation attempt has been made.\r\n            /// </summary>\r\n            StableInstallAttempted,\r\n\r\n            /// <summary>\r\n            /// A preview installation attempt has been made.\r\n            /// </summary>\r\n            PreviewInstallAttempted,\r\n\r\n            /// <summary>\r\n            /// The state machine is terminated.\r\n            /// </summary>\r\n            Terminated,\r\n        }\r\n\r\n        /// <summary>\r\n        /// A transition of the state machine.\r\n        /// </summary>\r\n        public enum Transition\r\n        {\r\n            /// <summary>\r\n            /// Transition to a terminated state with DSC being found.\r\n            /// </summary>\r\n            Found,\r\n\r\n            /// <summary>\r\n            /// Attempt to install the stable version of DSC.\r\n            /// </summary>\r\n            InstallStable,\r\n\r\n            /// <summary>\r\n            /// Attempt to install the preview version of DSC.\r\n            /// </summary>\r\n            InstallPreview,\r\n\r\n            /// <summary>\r\n            /// Transition to a terminated state with DSC *not* being found.\r\n            /// </summary>\r\n            NotFound,\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the file path of the DSC (Desired State Configuration) executable.\r\n        /// </summary>\r\n        public string? DscExecutablePath\r\n        {\r\n            get\r\n            {\r\n                if (this.currentState == State.Terminated)\r\n                {\r\n                    return this.dscExecutablePath;\r\n                }\r\n                else\r\n                {\r\n                    PackageInformation stableInformation = new PackageInformation(StableDscPackageFamilyName);\r\n                    if (stableInformation.IsInstalled && stableInformation.Version >= this.minimumStableVersion)\r\n                    {\r\n                        return stableInformation.AliasPath;\r\n                    }\r\n                    else\r\n                    {\r\n                        PackageInformation previewInformation = new PackageInformation(PreviewDscPackageFamilyName);\r\n                        if (previewInformation.IsInstalled && previewInformation.Version >= this.minimumPreviewVersion)\r\n                        {\r\n                            return previewInformation.AliasPath;\r\n                        }\r\n                        else\r\n                        {\r\n                            return null;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Determines the next state transition based on the current context or conditions.\r\n        /// </summary>\r\n        /// <returns>\r\n        /// A string representing the name of the next transition.\r\n        /// </returns>\r\n        public Transition DetermineNextTransition()\r\n        {\r\n            switch (this.currentState)\r\n            {\r\n                case State.Initial:\r\n                    {\r\n                        PackageInformation stableInformation = new PackageInformation(StableDscPackageFamilyName);\r\n                        if (stableInformation.IsInstalled && stableInformation.Version >= this.minimumStableVersion)\r\n                        {\r\n                            return this.Found(stableInformation);\r\n                        }\r\n                        else\r\n                        {\r\n                            this.currentState = State.StableInstallAttempted;\r\n                            return Transition.InstallStable;\r\n                        }\r\n                    }\r\n\r\n                case State.StableInstallAttempted:\r\n                    {\r\n                        PackageInformation stableInformation = new PackageInformation(StableDscPackageFamilyName);\r\n                        if (stableInformation.IsInstalled && stableInformation.Version >= this.minimumStableVersion)\r\n                        {\r\n                            return this.Found(stableInformation);\r\n                        }\r\n                        else\r\n                        {\r\n                            PackageInformation previewInformation = new PackageInformation(PreviewDscPackageFamilyName);\r\n                            if (previewInformation.IsInstalled && previewInformation.Version >= this.minimumPreviewVersion)\r\n                            {\r\n                                return this.Found(previewInformation);\r\n                            }\r\n                            else\r\n                            {\r\n                                this.currentState = State.PreviewInstallAttempted;\r\n                                return Transition.InstallPreview;\r\n                            }\r\n                        }\r\n                    }\r\n\r\n                case State.PreviewInstallAttempted:\r\n                    {\r\n                        PackageInformation previewInformation = new PackageInformation(PreviewDscPackageFamilyName);\r\n                        if (previewInformation.IsInstalled && previewInformation.Version >= this.minimumPreviewVersion)\r\n                        {\r\n                            return this.Found(previewInformation);\r\n                        }\r\n                        else\r\n                        {\r\n                            this.currentState = State.Terminated;\r\n                            return Transition.NotFound;\r\n                        }\r\n                    }\r\n\r\n                case State.Terminated:\r\n                    return this.DscExecutablePath == null ? Transition.NotFound : Transition.Found;\r\n\r\n                default:\r\n                    throw new InvalidOperationException($\"Unexpected state: {this.currentState}\");\r\n            }\r\n        }\r\n\r\n        private Transition Found(PackageInformation packageInformation)\r\n        {\r\n            this.dscExecutablePath = packageInformation.AliasPath;\r\n            this.currentState = State.Terminated;\r\n            return Transition.Found;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Helpers/IDiagnosticsSink.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"IDiagnosticsSink.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Helpers\r\n{\r\n    /// <summary>\r\n    /// Defines the interface for a diagnostics sink.\r\n    /// </summary>\r\n    internal interface IDiagnosticsSink\r\n    {\r\n        /// <summary>\r\n        /// Sends a diagnostic message.\r\n        /// </summary>\r\n        /// <param name=\"level\">The level of the message.</param>\r\n        /// <param name=\"message\">The message.</param>\r\n        public void OnDiagnostics(DiagnosticLevel level, string message);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Helpers/PackageInformation.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"PackageInformation.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Helpers\r\n{\r\n    using System;\r\n    using System.IO;\r\n    using Windows.Management.Deployment;\r\n\r\n    /// <summary>\r\n    /// Contains information about a package.\r\n    /// </summary>\r\n    internal class PackageInformation\r\n    {\r\n        private const string DscExecutableFileName = \"dsc.exe\";\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"PackageInformation\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"familyName\">The package family name.</param>\r\n        public PackageInformation(string familyName)\r\n        {\r\n            PackageManager packageManager = new PackageManager();\r\n\r\n            var packages = packageManager.FindPackagesForUserWithPackageTypes(null, familyName, PackageTypes.Main);\r\n\r\n            if (packages != null)\r\n            {\r\n                foreach (var package in packages)\r\n                {\r\n                    var packageVersion = package.Id.Version;\r\n                    Version version = new Version(packageVersion.Major, packageVersion.Minor, packageVersion.Build, packageVersion.Revision);\r\n\r\n                    if (this.Version == null || version > this.Version)\r\n                    {\r\n                        this.Version = version;\r\n                    }\r\n                }\r\n            }\r\n\r\n            string localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);\r\n            string aliasPath = Path.Combine(localAppData, \"Microsoft\\\\WindowsApps\", familyName, DscExecutableFileName);\r\n\r\n            if (Path.Exists(aliasPath))\r\n            {\r\n                this.AliasPath = aliasPath;\r\n            }\r\n\r\n            if (this.AliasPath != null && this.Version != null)\r\n            {\r\n                this.IsInstalled = true;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets a value indicating whether the package is installed or not.\r\n        /// </summary>\r\n        public bool IsInstalled { get; private set; }\r\n\r\n        /// <summary>\r\n        /// Gets the path to the dsc.exe alias.\r\n        /// </summary>\r\n        public string? AliasPath { get; private set; }\r\n\r\n        /// <summary>\r\n        /// Gets the version of the package.\r\n        /// </summary>\r\n        public Version? Version { get; private set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Helpers/ProcessExecution.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ProcessExecution.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Helpers\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.Diagnostics;\r\n    using System.Text;\r\n    using System.Threading;\r\n    using Microsoft.Management.Configuration.Processor.Helpers;\r\n\r\n    /// <summary>\r\n    /// Wrapper for a single process execution and its output.\r\n    /// </summary>\r\n    internal class ProcessExecution\r\n    {\r\n        private List<string> outputLines = new List<string>();\r\n        private List<string> errorLines = new List<string>();\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ProcessExecution\"/> class.\r\n        /// </summary>\r\n        public ProcessExecution()\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// An event that receives the output lines as they are delivered.\r\n        /// </summary>\r\n        public event EventHandler<string>? OutputLineReceived;\r\n\r\n        /// <summary>\r\n        /// An event that receives the error lines as they are delivered.\r\n        /// </summary>\r\n        public event EventHandler<string>? ErrorLineReceived;\r\n\r\n        /// <summary>\r\n        /// Gets the executable path.\r\n        /// </summary>\r\n        required public string ExecutablePath { get; init; }\r\n\r\n        /// <summary>\r\n        /// Gets the arguments to use for the process.\r\n        /// </summary>\r\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"StyleCop.CSharp.SpacingRules\", \"SA1010:Opening square brackets should be spaced correctly\", Justification = \"https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3687 pending SC 1.2 release\")]\r\n        public IEnumerable<string> Arguments { get; init; } = [];\r\n\r\n        /// <summary>\r\n        /// Gets the data to write to standard input of the process.\r\n        /// </summary>\r\n        public string? Input { get; init; } = null;\r\n\r\n        /// <summary>\r\n        /// Gets the list of custom environment variables to use for the process.\r\n        /// </summary>\r\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"StyleCop.CSharp.SpacingRules\", \"SA1010:Opening square brackets should be spaced correctly\", Justification = \"https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3687 pending SC 1.2 release\")]\r\n        public IEnumerable<ProcessExecutionEnvironmentVariable> EnvironmentVariables { get; init; } = [];\r\n\r\n        /// <summary>\r\n        /// Gets the argument string passed to the process.\r\n        /// </summary>\r\n        public string SerializedArguments\r\n        {\r\n            get\r\n            {\r\n                StringBuilder processArguments = new StringBuilder();\r\n\r\n                foreach (string arg in this.Arguments)\r\n                {\r\n                    if (processArguments.Length != 0)\r\n                    {\r\n                        processArguments.Append(' ');\r\n                    }\r\n\r\n                    processArguments.Append(arg);\r\n                }\r\n\r\n                return processArguments.ToString();\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the full command line that the process should see.\r\n        /// </summary>\r\n        public string CommandLine\r\n        {\r\n            get\r\n            {\r\n                return $\"{this.ExecutablePath} {this.SerializedArguments}\";\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the current set of output lines.\r\n        /// Not thread safe, use OutputLineReceived for async flows.\r\n        /// </summary>\r\n        public IReadOnlyCollection<string> Output\r\n        {\r\n            get { return this.outputLines; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the current set of error lines.\r\n        /// Not thread safe, use ErrorLineReceived for async flows.\r\n        /// </summary>\r\n        public IReadOnlyCollection<string> Error\r\n        {\r\n            get { return this.errorLines; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the exit code of the process.\r\n        /// Will be null until the process exits.\r\n        /// </summary>\r\n        public int? ExitCode { get; private set; } = null;\r\n\r\n        /// <summary>\r\n        /// Gets or sets the process object; null until Start called.\r\n        /// </summary>\r\n        private Process? Process { get; set; }\r\n\r\n        /// <summary>\r\n        /// Starts the process.\r\n        /// </summary>\r\n        /// <returns>This object.</returns>\r\n        /// <exception cref=\"InvalidOperationException\">Thrown if Start has already been called.</exception>\r\n        public ProcessExecution Start()\r\n        {\r\n            if (this.Process != null)\r\n            {\r\n                throw new InvalidOperationException(\"Process has already been started.\");\r\n            }\r\n\r\n            ProcessStartInfo startInfo;\r\n\r\n            lock (PathEnvironmentVariableHandler.Lock)\r\n            {\r\n                startInfo = new ProcessStartInfo(this.ExecutablePath, this.SerializedArguments);\r\n            }\r\n\r\n            this.Process = new Process() { StartInfo = startInfo };\r\n\r\n            startInfo.UseShellExecute = false;\r\n            startInfo.WindowStyle = ProcessWindowStyle.Hidden;\r\n\r\n            startInfo.StandardOutputEncoding = Encoding.UTF8;\r\n            startInfo.RedirectStandardOutput = true;\r\n            this.Process.OutputDataReceived += (sender, args) =>\r\n            {\r\n                string? output = args.Data;\r\n\r\n                if (output != null)\r\n                {\r\n                    this.outputLines.Add(output);\r\n\r\n                    this.OutputLineReceived?.Invoke(this, output);\r\n                }\r\n            };\r\n\r\n            startInfo.StandardErrorEncoding = Encoding.UTF8;\r\n            startInfo.RedirectStandardError = true;\r\n            this.Process.ErrorDataReceived += (sender, args) =>\r\n            {\r\n                string? error = args.Data;\r\n\r\n                if (error != null)\r\n                {\r\n                    this.errorLines.Add(error);\r\n\r\n                    this.ErrorLineReceived?.Invoke(this, error);\r\n                }\r\n            };\r\n\r\n            if (this.Input != null)\r\n            {\r\n                startInfo.StandardInputEncoding = Encoding.UTF8;\r\n                startInfo.RedirectStandardInput = true;\r\n            }\r\n\r\n            foreach (var env in this.EnvironmentVariables)\r\n            {\r\n                switch (env.ValueType)\r\n                {\r\n                    case ProcessExecutionEnvironmentVariableValueType.Override:\r\n                        startInfo.EnvironmentVariables[env.Name] = env.Value;\r\n                        break;\r\n\r\n                    case ProcessExecutionEnvironmentVariableValueType.Prepend:\r\n                        startInfo.EnvironmentVariables[env.Name] = MergeStringsWithSeparator(env.Value, startInfo.EnvironmentVariables[env.Name] ?? string.Empty, env.Separator);\r\n                        break;\r\n\r\n                    case ProcessExecutionEnvironmentVariableValueType.Append:\r\n                        startInfo.EnvironmentVariables[env.Name] = MergeStringsWithSeparator(startInfo.EnvironmentVariables[env.Name] ?? string.Empty, env.Value, env.Separator);\r\n                        break;\r\n                }\r\n            }\r\n\r\n            this.Process.Start();\r\n            this.Process.BeginOutputReadLine();\r\n            this.Process.BeginErrorReadLine();\r\n\r\n            if (this.Input != null)\r\n            {\r\n                this.Process.StandardInput.Write(this.Input);\r\n                this.Process.StandardInput.Close();\r\n            }\r\n\r\n            return this;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Waits for the process to exit.\r\n        /// </summary>\r\n        /// <param name=\"milliseconds\">The minimum amount of time to wait for the process to exit, in milliseconds.</param>\r\n        /// <returns>True if the process exited; false if not.</returns>\r\n        /// <exception cref=\"InvalidOperationException\">Thrown if Start has not been called.</exception>\r\n        public bool WaitForExit(int milliseconds = Timeout.Infinite)\r\n        {\r\n            if (this.Process == null)\r\n            {\r\n                throw new InvalidOperationException(\"Process has not been started.\");\r\n            }\r\n\r\n            if (this.Process.WaitForExit(milliseconds))\r\n            {\r\n                // According to documentation, this extra call will ensure that the redirected streams have finished reading all of the data.\r\n                this.Process.WaitForExit();\r\n\r\n                this.ExitCode = this.Process.ExitCode;\r\n\r\n                return true;\r\n            }\r\n            else\r\n            {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets all of the output lines as a single string.\r\n        /// </summary>\r\n        /// <returns>The output lines as a string.</returns>\r\n        public string GetAllOutputLines()\r\n        {\r\n            return GetAllLines(this.outputLines);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets all of the error lines as a single string.\r\n        /// </summary>\r\n        /// <returns>The error lines as a string.</returns>\r\n        public string GetAllErrorLines()\r\n        {\r\n            return GetAllLines(this.errorLines);\r\n        }\r\n\r\n        private static string GetAllLines(List<string> lines)\r\n        {\r\n            StringBuilder stringBuilder = new StringBuilder();\r\n\r\n            foreach (string line in lines)\r\n            {\r\n                stringBuilder.AppendLine(line);\r\n            }\r\n\r\n            return stringBuilder.ToString();\r\n        }\r\n\r\n        private static string MergeStringsWithSeparator(string first, string second, string separator)\r\n        {\r\n            if (string.IsNullOrEmpty(separator))\r\n            {\r\n                return first + second;\r\n            }\r\n            else\r\n            {\r\n                if (first.EndsWith(separator) && second.StartsWith(separator))\r\n                {\r\n                    return first + second.Substring(separator.Length);\r\n                }\r\n                else if (first.EndsWith(separator) || second.StartsWith(separator))\r\n                {\r\n                    return first + second;\r\n                }\r\n                else\r\n                {\r\n                    return first + separator + second;\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Helpers/ProcessExecutionEnvironmentVariable.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ProcessExecutionEnvironmentVariable.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Helpers\r\n{\r\n    /// <summary>\r\n    /// Contains custom environment variable info for ProcessExecution.\r\n    /// </summary>\r\n    internal class ProcessExecutionEnvironmentVariable\r\n    {\r\n        /// <summary>\r\n        /// Gets the name of the environment variable.\r\n        /// </summary>\r\n        required public string Name { get; init; }\r\n\r\n        /// <summary>\r\n        /// Gets the value of the environment variable.\r\n        /// </summary>\r\n        required public string Value { get; init; }\r\n\r\n        /// <summary>\r\n        /// Gets the value type of the environment variable.\r\n        /// </summary>\r\n        public ProcessExecutionEnvironmentVariableValueType ValueType { get; init; } = ProcessExecutionEnvironmentVariableValueType.Override;\r\n\r\n        /// <summary>\r\n        /// Gets the separator of the environment variable if value type is prepend or append.\r\n        /// </summary>\r\n        public string Separator { get; init; } = \";\";\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Helpers/ProcessExecutionEnvironmentVariableValueType.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ProcessExecutionEnvironmentVariableValueType.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Helpers\r\n{\r\n    /// <summary>\r\n    /// The environment variable value type.\r\n    /// </summary>\r\n    internal enum ProcessExecutionEnvironmentVariableValueType\r\n    {\r\n        /// <summary>\r\n        /// Prepend.\r\n        /// </summary>\r\n        Prepend,\r\n\r\n        /// <summary>\r\n        /// Append.\r\n        /// </summary>\r\n        Append,\r\n\r\n        /// <summary>\r\n        /// Override.\r\n        /// </summary>\r\n        Override,\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Helpers/ProcessorRunSettings.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ProcessorRunSettings.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Helpers\r\n{\r\n    using System.Collections.Generic;\r\n    using System.IO;\r\n    using System.Linq;\r\n    using System.Text;\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Model;\r\n    using Microsoft.Management.Configuration.Processor.Helpers;\r\n\r\n    /// <summary>\r\n    /// Contains settings for the DSC v3 processor components to share.\r\n    /// </summary>\r\n    internal class ProcessorRunSettings\r\n    {\r\n        /// <summary>\r\n        /// Gets the paths for finding DSC resources and executables.\r\n        /// </summary>\r\n        public string ResourceSearchPaths { get; private set; } = string.Empty;\r\n\r\n        /// <summary>\r\n        /// Gets a value indicating whether the resource search paths are exclusive.\r\n        /// </summary>\r\n        public bool ResourceSearchPathsExclusive { get; private set; } = false;\r\n\r\n        /// <summary>\r\n        /// Creates ProcessorRunSettings from FindUnitProcessorsOptions.\r\n        /// </summary>\r\n        /// <param name=\"findOptions\">The find unit processors options.</param>\r\n        /// <returns>A ProcessorRunSettings.</returns>\r\n        public static ProcessorRunSettings CreateFromFindUnitProcessorsOptions(FindUnitProcessorsOptions findOptions)\r\n        {\r\n            return new ProcessorRunSettings\r\n            {\r\n                ResourceSearchPaths = findOptions.SearchPaths,\r\n                ResourceSearchPathsExclusive = findOptions.SearchPathsExclusive,\r\n            };\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates ProcessorRunSettings from a ResourceDetails.\r\n        /// </summary>\r\n        /// <param name=\"resourceDetails\">The resource details to be used.</param>\r\n        /// <returns>A ProcessorRunSettings.</returns>\r\n        public static ProcessorRunSettings CreateFromResourceDetails(ResourceDetails? resourceDetails)\r\n        {\r\n            return new ProcessorRunSettings\r\n            {\r\n                ResourceSearchPaths = Path.GetDirectoryName(resourceDetails?.Path) ?? string.Empty,\r\n                ResourceSearchPathsExclusive = false,\r\n            };\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Helpers/ProcessorSettings.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ProcessorSettings.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Helpers\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.IO;\r\n    using System.Text;\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Model;\r\n    using Microsoft.Management.Configuration.Processor.Helpers;\r\n\r\n    /// <summary>\r\n    /// Contains settings for the DSC v3 processor components to share.\r\n    /// </summary>\r\n    internal class ProcessorSettings\r\n    {\r\n        private readonly object dscV3Lock = new ();\r\n        private readonly object defaultPathLock = new ();\r\n\r\n        private FindDscPackageStateMachine dscPackageStateMachine = new ();\r\n        private IDSCv3? dscV3 = null;\r\n        private string? defaultPath = null;\r\n\r\n        private Dictionary<string, ResourceDetails> resourceDetailsDictionary = new ();\r\n\r\n        /// <summary>\r\n        /// Gets or sets the path to the DSC v3 executable.\r\n        /// </summary>\r\n        public string? DscExecutablePath { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets the path to the DSC v3 executable.\r\n        /// </summary>\r\n        public string EffectiveDscExecutablePath\r\n        {\r\n            get\r\n            {\r\n                if (this.DscExecutablePath != null)\r\n                {\r\n                    return this.DscExecutablePath;\r\n                }\r\n\r\n                lock (this.defaultPathLock)\r\n                {\r\n                    if (this.defaultPath != null)\r\n                    {\r\n                        return this.defaultPath;\r\n                    }\r\n                }\r\n\r\n                string? localDefaultPath = this.GetFoundDscExecutablePath();\r\n\r\n                if (localDefaultPath == null)\r\n                {\r\n                    throw new FileNotFoundException(\"Could not find DSC v3 executable path.\");\r\n                }\r\n\r\n                lock (this.defaultPathLock)\r\n                {\r\n                    if (this.defaultPath == null)\r\n                    {\r\n                        this.defaultPath = localDefaultPath;\r\n                    }\r\n\r\n                    return this.defaultPath;\r\n                }\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets an object for interacting with the DSC executable at EffectiveDscExecutablePath.\r\n        /// </summary>\r\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"StyleCop.CSharp.DocumentationRules\", \"SA1623:Property summary documentation should match accessors\", Justification = \"Set is only provided for tests.\")]\r\n        public IDSCv3 DSCv3\r\n        {\r\n            get\r\n            {\r\n                lock (this.dscV3Lock)\r\n                {\r\n                    if (this.dscV3 == null)\r\n                    {\r\n                        this.dscV3 = IDSCv3.Create(this);\r\n                    }\r\n\r\n                    return this.dscV3;\r\n                }\r\n            }\r\n\r\n#if !AICLI_DISABLE_TEST_HOOKS\r\n            set\r\n            {\r\n                lock (this.dscV3Lock)\r\n                {\r\n                    this.dscV3 = value;\r\n                }\r\n            }\r\n#endif\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the diagnostics sink to use.\r\n        /// </summary>\r\n        public IDiagnosticsSink? DiagnosticsSink { get; set; } = null;\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether the processor should produce more verbose output.\r\n        /// </summary>\r\n        public bool DiagnosticTraceEnabled { get; set; } = false;\r\n\r\n        /// <summary>\r\n        /// Find the DSC v3 executable.\r\n        /// </summary>\r\n        /// <returns>The full path to the dsc.exe executable, or null if not found.</returns>\r\n        public string? GetFoundDscExecutablePath()\r\n        {\r\n            return this.dscPackageStateMachine.DscExecutablePath;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Invokes a step in the DSC search state machine.\r\n        /// </summary>\r\n        /// <returns>The transition to take in the state machine.</returns>\r\n        public FindDscPackageStateMachine.Transition PumpFindDscStateMachine()\r\n        {\r\n            return this.dscPackageStateMachine.DetermineNextTransition();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Create a deep copy of this settings object.\r\n        /// </summary>\r\n        /// <returns>A deep copy of this object.</returns>\r\n        public ProcessorSettings Clone()\r\n        {\r\n            ProcessorSettings result = new ProcessorSettings();\r\n\r\n            result.resourceDetailsDictionary = this.resourceDetailsDictionary;\r\n            result.DiagnosticsSink = this.DiagnosticsSink;\r\n            result.DscExecutablePath = this.DscExecutablePath;\r\n            result.DiagnosticTraceEnabled = this.DiagnosticTraceEnabled;\r\n#if !AICLI_DISABLE_TEST_HOOKS\r\n            result.dscV3 = this.DSCv3;\r\n#endif\r\n\r\n            return result;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets a string representation of this object.\r\n        /// </summary>\r\n        /// <returns>A string representation of this object.</returns>\r\n        public override string ToString()\r\n        {\r\n            StringBuilder sb = new StringBuilder();\r\n\r\n            sb.Append(\"EffectiveDscExecutablePath: \");\r\n            sb.AppendLine(this.EffectiveDscExecutablePath);\r\n\r\n            sb.Append(\"DiagnosticTraceLevel: \");\r\n            sb.Append(this.DiagnosticTraceEnabled);\r\n\r\n            return sb.ToString();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the ResourceDetails for a configuration unit.\r\n        /// </summary>\r\n        /// <param name=\"configurationUnitInternal\">The configuration unit to find details for.</param>\r\n        /// <param name=\"detailFlags\">The level of detail to get.</param>\r\n        /// <returns>The ResourceDetails for the unit, or null if not found.</returns>\r\n        public ResourceDetails? GetResourceDetails(ConfigurationUnitInternal configurationUnitInternal, ConfigurationUnitDetailFlags detailFlags)\r\n        {\r\n            ResourceDetails? result = null;\r\n            bool inDictionary = false;\r\n\r\n            lock (this.resourceDetailsDictionary)\r\n            {\r\n                inDictionary = this.resourceDetailsDictionary.TryGetValue(configurationUnitInternal.QualifiedName, out result);\r\n            }\r\n\r\n            if (result == null)\r\n            {\r\n                result = new ResourceDetails(configurationUnitInternal.QualifiedName);\r\n            }\r\n\r\n            result.EnsureDetails(this, detailFlags);\r\n\r\n            if (result.Exists)\r\n            {\r\n                if (!inDictionary)\r\n                {\r\n                    lock (this.resourceDetailsDictionary)\r\n                    {\r\n                        this.resourceDetailsDictionary.Add(configurationUnitInternal.QualifiedName, result);\r\n                    }\r\n                }\r\n\r\n                return result;\r\n            }\r\n            else\r\n            {\r\n                return null;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets all ResourceDetails matching find options.\r\n        /// </summary>\r\n        /// <param name=\"findOptions\">The find options.</param>\r\n        /// <returns>A list of ResourceDetails.</returns>\r\n        public List<ResourceDetails> FindAllResourceDetails(FindUnitProcessorsOptions findOptions)\r\n        {\r\n            List<ResourceDetails> result = new List<ResourceDetails>();\r\n\r\n            var resourceItemList = this.DSCv3.GetAllResources(ProcessorRunSettings.CreateFromFindUnitProcessorsOptions(findOptions));\r\n\r\n            foreach (var item in resourceItemList)\r\n            {\r\n                ResourceDetails? details = null;\r\n                bool inDictionary = false;\r\n                lock (this.resourceDetailsDictionary)\r\n                {\r\n                    inDictionary = this.resourceDetailsDictionary.TryGetValue(item.Type, out details);\r\n                }\r\n\r\n                if (details == null)\r\n                {\r\n                    details = new ResourceDetails(item.Type);\r\n                }\r\n\r\n                if (!details.Exists)\r\n                {\r\n                    details.SetResourceListItem(item);\r\n                }\r\n\r\n                details.EnsureDetails(this, findOptions.UnitDetailFlags);\r\n\r\n                if (!inDictionary)\r\n                {\r\n                    lock (this.resourceDetailsDictionary)\r\n                    {\r\n                        this.resourceDetailsDictionary.Add(item.Type, details);\r\n                    }\r\n                }\r\n\r\n                result.Add(details);\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Helpers/ResourceDetails.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ResourceDetails.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Helpers\r\n{\r\n    using System;\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Model;\r\n    using Microsoft.Management.Configuration.Processor.Helpers;\r\n    using Microsoft.Management.Configuration.Processor.Unit;\r\n\r\n    /// <summary>\r\n    /// Cached data about a resource.\r\n    /// </summary>\r\n    internal class ResourceDetails\r\n    {\r\n        private readonly string resourceTypeName;\r\n\r\n        private object detailsUpdateLock = new object();\r\n        private IResourceListItem? resourceListItem = null;\r\n\r\n        /// <summary>\r\n        /// The current level of detail stored by this object.\r\n        ///\r\n        /// The method of discovery for each of the levels in ConfigurationUnitDetailFlags:\r\n        ///     None: No details, either because the resource was not found or EnsureDetails has not been called.\r\n        ///     Local: `resource list` is used to determine the details. An embedded schema may enable \"Load\" details level.\r\n        ///            Property information may not be available at this level.\r\n        ///     Catalog: Same as local; there is currently no catalog to query against.\r\n        ///     Download: Same as local; there is currently no catalog to find anything to download.\r\n        ///     Load: `resource schema` is used to get the full schema for the resource.\r\n        ///           This ensures that property information is available.\r\n        /// </summary>\r\n        private ConfigurationUnitDetailFlags currentDetailLevel = ConfigurationUnitDetailFlags.None;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ResourceDetails\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"resourceTypeName\">The resource type name.</param>\r\n        public ResourceDetails(string resourceTypeName)\r\n        {\r\n            this.resourceTypeName = resourceTypeName;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets a value indicating whether this resource exists.\r\n        /// Will be false until EnsureDetails is called and the resource is found.\r\n        /// </summary>\r\n        public bool Exists\r\n        {\r\n            get\r\n            {\r\n                lock (this.detailsUpdateLock)\r\n                {\r\n                    return this.currentDetailLevel != ConfigurationUnitDetailFlags.None;\r\n                }\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the path of the resource.\r\n        /// </summary>\r\n        public string? Path\r\n        {\r\n            get\r\n            {\r\n                lock (this.detailsUpdateLock)\r\n                {\r\n                    return this.resourceListItem?.Path;\r\n                }\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Sets the resource list item directly to avoid duplicate \"dsc resource list\" calls.\r\n        /// </summary>\r\n        /// <param name=\"item\">The resource list item.</param>\r\n        public void SetResourceListItem(IResourceListItem item)\r\n        {\r\n            lock (this.detailsUpdateLock)\r\n            {\r\n                if (this.resourceListItem != null)\r\n                {\r\n                    throw new InvalidOperationException(\"Resource list item is already set\");\r\n                }\r\n\r\n                this.resourceListItem = item;\r\n                this.currentDetailLevel |= ConfigurationUnitDetailFlags.Local;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Ensures that the given detail level is present.\r\n        /// </summary>\r\n        /// <param name=\"processorSettings\">The processor settings to use when getting details.</param>\r\n        /// <param name=\"detailFlags\">The detail level flags.</param>\r\n        public void EnsureDetails(ProcessorSettings processorSettings, ConfigurationUnitDetailFlags detailFlags)\r\n        {\r\n            if (this.DetailsNeededFor(detailFlags, ConfigurationUnitDetailFlags.Local))\r\n            {\r\n                // If we can't get local details, then exit until we have more options.\r\n                if (!this.GetLocalDetails(processorSettings))\r\n                {\r\n                    return;\r\n                }\r\n            }\r\n\r\n            if (this.DetailsNeededFor(detailFlags, ConfigurationUnitDetailFlags.Load))\r\n            {\r\n                this.GetLoadDetails(processorSettings);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets a ConfigurationUnitProcessorDetails populated with all available data.\r\n        /// </summary>\r\n        /// <returns>A ConfigurationUnitProcessorDetails populated with all available data.</returns>\r\n        public ConfigurationUnitProcessorDetails? GetConfigurationUnitProcessorDetails()\r\n        {\r\n            if (!this.Exists)\r\n            {\r\n                return null;\r\n            }\r\n\r\n            ConfigurationUnitProcessorDetails result = new ConfigurationUnitProcessorDetails() { UnitType = this.resourceTypeName };\r\n\r\n            lock (this.detailsUpdateLock)\r\n            {\r\n                if (this.resourceListItem != null)\r\n                {\r\n                    result.UnitType = this.resourceListItem.Type;\r\n                    result.IsGroup = IsGroup(this.resourceListItem.Kind);\r\n                    result.Version = this.resourceListItem.Version;\r\n                    result.UnitDescription = this.resourceListItem.Description;\r\n                    result.Author = this.resourceListItem.Author;\r\n                    result.Path = this.resourceListItem.Path;\r\n\r\n                    result.IsLocal = true;\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        private static bool IsGroup(ResourceKind kind) => kind switch\r\n        {\r\n            ResourceKind.Adapter => true,\r\n            ResourceKind.Group => true,\r\n            _ => false,\r\n        };\r\n\r\n        private bool DetailsNeededFor(ConfigurationUnitDetailFlags detailFlags, ConfigurationUnitDetailFlags targetLevel)\r\n        {\r\n            if (!detailFlags.HasFlag(targetLevel))\r\n            {\r\n                return false;\r\n            }\r\n\r\n            lock (this.detailsUpdateLock)\r\n            {\r\n                return !this.currentDetailLevel.HasFlag(targetLevel);\r\n            }\r\n        }\r\n\r\n        private bool GetLocalDetails(ProcessorSettings processorSettings)\r\n        {\r\n            IResourceListItem? resourceListItem = processorSettings.DSCv3.GetResourceByType(this.resourceTypeName, null);\r\n\r\n            if (resourceListItem != null)\r\n            {\r\n                // TODO: Attempt to extract embedded schema to avoid the need for Load.\r\n                lock (this.detailsUpdateLock)\r\n                {\r\n                    if (!this.currentDetailLevel.HasFlag(ConfigurationUnitDetailFlags.Local))\r\n                    {\r\n                        this.resourceListItem = resourceListItem;\r\n                        this.currentDetailLevel |= ConfigurationUnitDetailFlags.Local;\r\n                    }\r\n                }\r\n\r\n                return true;\r\n            }\r\n            else\r\n            {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        private void GetLoadDetails(ProcessorSettings processorSettings)\r\n        {\r\n            throw new NotImplementedException();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Model/IDSCv3.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"IDSCv3.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Model\r\n{\r\n    using System.Collections.Generic;\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Helpers;\r\n    using Microsoft.Management.Configuration.Processor.Helpers;\r\n\r\n    /// <summary>\r\n    /// Interface for interacting with DSC v3.\r\n    /// </summary>\r\n    internal interface IDSCv3\r\n    {\r\n        /// <summary>\r\n        /// Creates the appropriate instance of the DSCv3 interface for the given executable.\r\n        /// </summary>\r\n        /// <param name=\"processorSettings\">The processor settings.</param>\r\n        /// <returns>An object that properly interacts with the specific version of DSC v3.</returns>\r\n        public static IDSCv3 Create(ProcessorSettings processorSettings)\r\n        {\r\n            // Expand as needed to detect the version of dsc.exe and/or its schemas in use.\r\n            return new Schema_2024_04.DSCv3(processorSettings);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets a single resource by its type name.\r\n        /// </summary>\r\n        /// <param name=\"resourceType\">The type name of the resource.</param>\r\n        /// <param name=\"runSettings\">The processor run settings.</param>\r\n        /// <returns>A single resource item.</returns>\r\n        public IResourceListItem? GetResourceByType(string resourceType, ProcessorRunSettings? runSettings);\r\n\r\n        /// <summary>\r\n        /// Gets all resource items.\r\n        /// </summary>\r\n        /// <param name=\"runSettings\">The processor run settings.</param>\r\n        /// <returns>A list of resource items.</returns>\r\n        public List<IResourceListItem> GetAllResources(ProcessorRunSettings? runSettings);\r\n\r\n        /// <summary>\r\n        /// Tests a configuration unit.\r\n        /// </summary>\r\n        /// <param name=\"unitInternal\">The unit to test.</param>\r\n        /// <param name=\"runSettings\">The processor run settings.</param>\r\n        /// <returns>A test result.</returns>\r\n        public IResourceTestItem TestResource(ConfigurationUnitInternal unitInternal, ProcessorRunSettings? runSettings);\r\n\r\n        /// <summary>\r\n        /// Gets a configuration unit settings.\r\n        /// </summary>\r\n        /// <param name=\"unitInternal\">The unit to get.</param>\r\n        /// <param name=\"runSettings\">The processor run settings.</param>\r\n        /// <returns>A get result.</returns>\r\n        public IResourceGetItem GetResourceSettings(ConfigurationUnitInternal unitInternal, ProcessorRunSettings? runSettings);\r\n\r\n        /// <summary>\r\n        /// Sets a configuration unit settings.\r\n        /// </summary>\r\n        /// <param name=\"unitInternal\">The unit to set.</param>\r\n        /// <param name=\"runSettings\">The processor run settings.</param>\r\n        /// <returns>A set result.</returns>\r\n        public IResourceSetItem SetResourceSettings(ConfigurationUnitInternal unitInternal, ProcessorRunSettings? runSettings);\r\n\r\n        /// <summary>\r\n        /// Exports configuration unit.\r\n        /// </summary>\r\n        /// <param name=\"unitInternal\">The unit to export.</param>\r\n        /// <param name=\"runSettings\">The processor run settings.</param>\r\n        /// <returns>A list of export results.</returns>\r\n        public IList<IResourceExportItem> ExportResource(ConfigurationUnitInternal unitInternal, ProcessorRunSettings? runSettings);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Model/IResourceExportItem.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"IResourceExportItem.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Model\r\n{\r\n    using System.Collections.Generic;\r\n    using Windows.Foundation.Collections;\r\n\r\n    /// <summary>\r\n    /// The interface to a `resource export` command result.\r\n    /// </summary>\r\n    internal interface IResourceExportItem\r\n    {\r\n        /// <summary>\r\n        /// Gets the type of the resource.\r\n        /// </summary>\r\n        public string Type { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the name of the resource instance.\r\n        /// </summary>\r\n        public string Name { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the settings for this item.\r\n        /// </summary>\r\n        public ValueSet Settings { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the metadata for this item.\r\n        /// </summary>\r\n        public ValueSet Metadata { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the dependencies for this item.\r\n        /// </summary>\r\n        public IList<string> Dependencies { get; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Model/IResourceGetItem.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"IResourceGetItem.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Model\r\n{\r\n    using Windows.Foundation.Collections;\r\n\r\n    /// <summary>\r\n    /// The interface to a `resource get` command result.\r\n    /// </summary>\r\n    internal interface IResourceGetItem\r\n    {\r\n        /// <summary>\r\n        /// Gets the settings for this item.\r\n        /// </summary>\r\n        public ValueSet Settings { get; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Model/IResourceListItem.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"IResourceListItem.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Model\r\n{\r\n    /// <summary>\r\n    /// The interface to a single JSON line output by the `resource list` command.\r\n    /// </summary>\r\n    internal interface IResourceListItem\r\n    {\r\n        /// <summary>\r\n        /// Gets the type of the resource.\r\n        /// Should match the regex \"^\\\\w+(\\\\.\\\\w+){0,2}\\\\/\\\\w+$\".\r\n        /// </summary>\r\n        public string Type { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the kind of the resource.\r\n        /// </summary>\r\n        public ResourceKind Kind { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the version of the resource.\r\n        /// This is a semver version.\r\n        /// </summary>\r\n        public string? Version { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the description of the resource.\r\n        /// </summary>\r\n        public string? Description { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the path to the directory containing the resource.\r\n        /// </summary>\r\n        public string? Directory { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the author of the resource.\r\n        /// </summary>\r\n        public string? Author { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the path of the resource.\r\n        /// </summary>\r\n        public string? Path { get; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Model/IResourceSetItem.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"IResourceSetItem.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Model\r\n{\r\n    using System.Collections.Generic;\r\n\r\n    /// <summary>\r\n    /// The interface to a `resource set` command result.\r\n    /// </summary>\r\n    internal interface IResourceSetItem\r\n    {\r\n        /// <summary>\r\n        /// Gets a value indicating whether a reboot is required.\r\n        /// </summary>\r\n        public bool RebootRequired { get; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Model/IResourceTestItem.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"IResourceTestItem.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Model\r\n{\r\n    /// <summary>\r\n    /// The interface to a `resource test` command result.\r\n    /// </summary>\r\n    internal interface IResourceTestItem\r\n    {\r\n        /// <summary>\r\n        /// Gets a value indicating whether the resource is in the desired state.\r\n        /// </summary>\r\n        public bool InDesiredState { get; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Model/ResourceKind.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ResourceKind.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Model\r\n{\r\n    /// <summary>\r\n    /// https://learn.microsoft.com/en-us/powershell/dsc/reference/schemas/definitions/resourcekind?view=dsc-3.0\r\n    /// The kind of resource.\r\n    /// </summary>\r\n    internal enum ResourceKind\r\n    {\r\n        /// <summary>\r\n        /// The kind is unknown.\r\n        /// </summary>\r\n        Unknown,\r\n\r\n        /// <summary>\r\n        /// A standard resource.\r\n        /// </summary>\r\n        Resource,\r\n\r\n        /// <summary>\r\n        /// An adapter resource.\r\n        /// </summary>\r\n        Adapter,\r\n\r\n        /// <summary>\r\n        /// A group resource.\r\n        /// </summary>\r\n        Group,\r\n\r\n        /// <summary>\r\n        /// An importer resource.\r\n        /// </summary>\r\n        Importer,\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Schema_2024_04/DSCv3.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"DSCv3.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Schema_2024_04\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.Linq;\r\n    using System.Text.Json;\r\n    using System.Text.Json.Serialization;\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Helpers;\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Model;\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Schema_2024_04.Outputs;\r\n    using Microsoft.Management.Configuration.Processor.Extensions;\r\n    using Microsoft.Management.Configuration.Processor.Helpers;\r\n    using Windows.Foundation.Collections;\r\n\r\n    /// <summary>\r\n    /// An instance of IDSCv3 for interacting with 1.0.\r\n    /// </summary>\r\n    internal class DSCv3 : IDSCv3\r\n    {\r\n        private const string PlainTextTraces = \"-t plaintext\";\r\n        private const string DiagnosticTraceLevelArguments = \"-l trace\";\r\n        private const string ResourceCommand = \"resource\";\r\n        private const string ListCommand = \"list\";\r\n        private const string TestCommand = \"test\";\r\n        private const string GetCommand = \"get\";\r\n        private const string SetCommand = \"set\";\r\n        private const string ExportCommand = \"export\";\r\n        private const string ResourceParameter = \"-r\";\r\n        private const string FileParameter = \"-f\";\r\n        private const string StdInputIdentifier = \"-\";\r\n\r\n        private const string PathEnvironmentVariable = \"PATH\";\r\n        private const string DSCResourcePathEnvironmentVariable = \"DSC_RESOURCE_PATH\";\r\n\r\n        private readonly ProcessorSettings processorSettings;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"DSCv3\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"processorSettings\">The processor settings.</param>\r\n        public DSCv3(ProcessorSettings processorSettings)\r\n        {\r\n            this.processorSettings = processorSettings;\r\n        }\r\n\r\n        private string DiagnosticTraceLevel\r\n        {\r\n            get\r\n            {\r\n                return this.processorSettings.DiagnosticTraceEnabled ? DiagnosticTraceLevelArguments : string.Empty;\r\n            }\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        public IResourceListItem? GetResourceByType(string resourceType, ProcessorRunSettings? runSettings)\r\n        {\r\n            ResourceListItem? result = this.GetResourceByTypeInternal(resourceType, null, runSettings);\r\n            if (result != null)\r\n            {\r\n                return result;\r\n            }\r\n\r\n            // Check for this resource within adapters\r\n            List<ResourceListItem> results = new List<ResourceListItem>();\r\n\r\n            foreach (ResourceListItem resource in this.GetAllResources(runSettings))\r\n            {\r\n                if (resource.Kind == Definitions.ResourceKind.Adapter)\r\n                {\r\n                    result = this.GetResourceByTypeInternal(resourceType, resource.Type, runSettings);\r\n                    if (result != null)\r\n                    {\r\n                        results.Add(result);\r\n                    }\r\n                }\r\n            }\r\n\r\n            return this.GetResourceByLatestVersion(results);\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        public IResourceTestItem TestResource(ConfigurationUnitInternal unitInternal, ProcessorRunSettings? runSettings)\r\n        {\r\n            ProcessExecution processExecution = new ProcessExecution()\r\n            {\r\n                ExecutablePath = this.processorSettings.EffectiveDscExecutablePath,\r\n                Arguments = new[] { PlainTextTraces, this.DiagnosticTraceLevel, ResourceCommand, TestCommand, ResourceParameter, unitInternal.QualifiedName, FileParameter, StdInputIdentifier },\r\n                Input = ConvertValueSetToJSON(unitInternal.GetExpandedSettings()),\r\n                EnvironmentVariables = CreateEnvironmentVariablesFromProcessorRunSettings(runSettings),\r\n            };\r\n\r\n            if (this.RunSynchronously(processExecution))\r\n            {\r\n                throw new Exceptions.InvokeDscResourceException(Exceptions.InvokeDscResourceException.Test, unitInternal.QualifiedName, null, processExecution.GetAllErrorLines());\r\n            }\r\n\r\n            return TestFullItem.CreateFrom(GetRequiredSingleOutputLineAsJSON(processExecution, Exceptions.InvokeDscResourceException.Test, unitInternal.QualifiedName), GetDefaultJsonOptions());\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        public IResourceGetItem GetResourceSettings(ConfigurationUnitInternal unitInternal, ProcessorRunSettings? runSettings)\r\n        {\r\n            ProcessExecution processExecution = new ProcessExecution()\r\n            {\r\n                ExecutablePath = this.processorSettings.EffectiveDscExecutablePath,\r\n                Arguments = new[] { PlainTextTraces, this.DiagnosticTraceLevel, ResourceCommand, GetCommand, ResourceParameter, unitInternal.QualifiedName, FileParameter, StdInputIdentifier },\r\n                Input = ConvertValueSetToJSON(unitInternal.GetExpandedSettings()),\r\n                EnvironmentVariables = CreateEnvironmentVariablesFromProcessorRunSettings(runSettings),\r\n            };\r\n\r\n            if (this.RunSynchronously(processExecution))\r\n            {\r\n                throw new Exceptions.InvokeDscResourceException(Exceptions.InvokeDscResourceException.Get, unitInternal.QualifiedName, null, processExecution.GetAllErrorLines());\r\n            }\r\n\r\n            return GetFullItem.CreateFrom(GetRequiredSingleOutputLineAsJSON(processExecution, Exceptions.InvokeDscResourceException.Get, unitInternal.QualifiedName), GetDefaultJsonOptions());\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        public IResourceSetItem SetResourceSettings(ConfigurationUnitInternal unitInternal, ProcessorRunSettings? runSettings)\r\n        {\r\n            ProcessExecution processExecution = new ProcessExecution()\r\n            {\r\n                ExecutablePath = this.processorSettings.EffectiveDscExecutablePath,\r\n                Arguments = new[] { PlainTextTraces, this.DiagnosticTraceLevel, ResourceCommand, SetCommand, ResourceParameter, unitInternal.QualifiedName, FileParameter, StdInputIdentifier },\r\n                Input = ConvertValueSetToJSON(unitInternal.GetExpandedSettings()),\r\n                EnvironmentVariables = CreateEnvironmentVariablesFromProcessorRunSettings(runSettings),\r\n            };\r\n\r\n            if (this.RunSynchronously(processExecution))\r\n            {\r\n                throw new Exceptions.InvokeDscResourceException(Exceptions.InvokeDscResourceException.Set, unitInternal.QualifiedName, null, processExecution.GetAllErrorLines());\r\n            }\r\n\r\n            return SetFullItem.CreateFrom(GetRequiredSingleOutputLineAsJSON(processExecution, Exceptions.InvokeDscResourceException.Set, unitInternal.QualifiedName), GetDefaultJsonOptions());\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        public IList<IResourceExportItem> ExportResource(ConfigurationUnitInternal unitInternal, ProcessorRunSettings? runSettings)\r\n        {\r\n            // 3.0 can't handle input to export; 3.1 will fix that.\r\n            ValueSet expandedSettings = unitInternal.GetExpandedSettings();\r\n            if (expandedSettings.Count != 0)\r\n            {\r\n                throw new NotImplementedException(\"Must use DSC v3.1.* to provide input to export.\");\r\n            }\r\n\r\n            ProcessExecution processExecution = new ProcessExecution()\r\n            {\r\n                ExecutablePath = this.processorSettings.EffectiveDscExecutablePath,\r\n                Arguments = new[] { PlainTextTraces, this.DiagnosticTraceLevel, ResourceCommand, ExportCommand, ResourceParameter, unitInternal.QualifiedName },\r\n                EnvironmentVariables = CreateEnvironmentVariablesFromProcessorRunSettings(runSettings),\r\n            };\r\n\r\n            if (this.RunSynchronously(processExecution))\r\n            {\r\n                throw new Exceptions.InvokeDscResourceException(Exceptions.InvokeDscResourceException.Export, unitInternal.QualifiedName, null, processExecution.GetAllErrorLines());\r\n            }\r\n\r\n            return ConfigurationDocument.CreateFrom(GetRequiredSingleOutputLineAsJSON(processExecution, Exceptions.InvokeDscResourceException.Set, unitInternal.QualifiedName), GetDefaultJsonOptions()).InterfaceResources;\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        public List<IResourceListItem> GetAllResources(ProcessorRunSettings? runSettings)\r\n        {\r\n            ProcessExecution processExecution = new ProcessExecution()\r\n            {\r\n                ExecutablePath = this.processorSettings.EffectiveDscExecutablePath,\r\n                Arguments = new[] { PlainTextTraces, this.DiagnosticTraceLevel, ResourceCommand, ListCommand },\r\n                EnvironmentVariables = CreateEnvironmentVariablesFromProcessorRunSettings(runSettings),\r\n            };\r\n\r\n            this.RunSynchronously(processExecution);\r\n\r\n            return GetOutputLinesAs<ResourceListItem>(processExecution).ToList<IResourceListItem>();\r\n        }\r\n\r\n        private static void ThrowOnMultipleOutputLines(ProcessExecution processExecution, string method, string resourceName)\r\n        {\r\n            if (processExecution.Output.Count > 1)\r\n            {\r\n                throw new Exceptions.InvokeDscResourceException(method, resourceName, processExecution.GetAllOutputLines());\r\n            }\r\n        }\r\n\r\n        private static void ThrowOnZeroOutputLines(ProcessExecution processExecution, string method, string resourceName)\r\n        {\r\n            if (processExecution.Output.Count == 0)\r\n            {\r\n                throw new Exceptions.InvokeDscResourceException(method, resourceName);\r\n            }\r\n        }\r\n\r\n        private static T? GetOptionalSingleOutputLineAs<T>(ProcessExecution processExecution)\r\n        {\r\n            if (processExecution.Output.Count == 0)\r\n            {\r\n                return default;\r\n            }\r\n\r\n            return JsonSerializer.Deserialize<T>(processExecution.Output.First(), GetDefaultJsonOptions());\r\n        }\r\n\r\n        private static List<T> GetOutputLinesAs<T>(ProcessExecution processExecution)\r\n        {\r\n            List<T> result = new List<T>();\r\n            var options = GetDefaultJsonOptions();\r\n\r\n            foreach (string line in processExecution.Output)\r\n            {\r\n                T? lineObject = JsonSerializer.Deserialize<T>(line, options);\r\n                if (lineObject != null)\r\n                {\r\n                    result.Add(lineObject);\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        private static JsonDocument GetRequiredSingleOutputLineAsJSON(ProcessExecution processExecution, string method, string resourceName)\r\n        {\r\n            ThrowOnMultipleOutputLines(processExecution, method, resourceName);\r\n            ThrowOnZeroOutputLines(processExecution, method, resourceName);\r\n\r\n            return JsonDocument.Parse(processExecution.Output.First());\r\n        }\r\n\r\n        private static JsonSerializerOptions GetDefaultJsonOptions()\r\n        {\r\n            return new JsonSerializerOptions()\r\n            {\r\n                PropertyNamingPolicy = JsonNamingPolicy.CamelCase,\r\n                Converters =\r\n                {\r\n                    new JsonStringEnumConverter(),\r\n                },\r\n            };\r\n        }\r\n\r\n        private static string ConvertValueSetToJSON(ValueSet valueSet)\r\n        {\r\n            return JsonSerializer.Serialize(valueSet.ToHashtable());\r\n        }\r\n\r\n        private static List<ProcessExecutionEnvironmentVariable> CreateEnvironmentVariablesFromProcessorRunSettings(ProcessorRunSettings? runSettings)\r\n        {\r\n            List<ProcessExecutionEnvironmentVariable> result = new List<ProcessExecutionEnvironmentVariable>();\r\n            if (runSettings is not null && !string.IsNullOrEmpty(runSettings.ResourceSearchPaths))\r\n            {\r\n                // For exclusive search paths, adding to PATH is still needed as anything referenced in the manifest is still searched from PATH.\r\n                result.Add(new ProcessExecutionEnvironmentVariable { Name = PathEnvironmentVariable, Value = runSettings.ResourceSearchPaths, ValueType = ProcessExecutionEnvironmentVariableValueType.Prepend });\r\n\r\n                if (runSettings.ResourceSearchPathsExclusive)\r\n                {\r\n                    result.Add(new ProcessExecutionEnvironmentVariable { Name = DSCResourcePathEnvironmentVariable, Value = runSettings.ResourceSearchPaths, ValueType = ProcessExecutionEnvironmentVariableValueType.Override });\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Runs the process, waiting until it completes.\r\n        /// </summary>\r\n        /// <param name=\"processExecution\">The process to run.</param>\r\n        /// <returns>True if the exit code was not 0.</returns>\r\n        private bool RunSynchronously(ProcessExecution processExecution)\r\n        {\r\n            this.processorSettings.DiagnosticsSink?.OnDiagnostics(DiagnosticLevel.Verbose, $\"Starting process: {processExecution.CommandLine}{(processExecution.Input == null ? string.Empty : $\"\\n--- Input Stream ---\\n{processExecution.Input}\")}\");\r\n\r\n            processExecution.Start().WaitForExit();\r\n\r\n            this.processorSettings.DiagnosticsSink?.OnDiagnostics(DiagnosticLevel.Verbose, $\"Process exited with code: {processExecution.ExitCode}\\n--- Output Stream ---\\n{processExecution.GetAllOutputLines()}\\n--- Error Stream ---\\n{processExecution.GetAllErrorLines()}\");\r\n\r\n            return processExecution.ExitCode != 0;\r\n        }\r\n\r\n        private ResourceListItem? GetResourceByTypeInternal(string resourceType, string? adapter, ProcessorRunSettings? runSettings)\r\n        {\r\n            ProcessExecution processExecution = new ProcessExecution()\r\n            {\r\n                ExecutablePath = this.processorSettings.EffectiveDscExecutablePath,\r\n                Arguments = new[] { PlainTextTraces, this.DiagnosticTraceLevel, ResourceCommand, ListCommand, adapter != null ? $\"-a {adapter}\" : string.Empty, resourceType },\r\n                EnvironmentVariables = CreateEnvironmentVariablesFromProcessorRunSettings(runSettings),\r\n            };\r\n\r\n            this.RunSynchronously(processExecution);\r\n\r\n            List<ResourceListItem> results = GetOutputLinesAs<ResourceListItem>(processExecution);\r\n\r\n            return this.GetResourceByLatestVersion(results);\r\n        }\r\n\r\n        private ResourceListItem? GetResourceByLatestVersion(List<ResourceListItem> resources)\r\n        {\r\n            // There may be different versions of same resource on the system. We check if all\r\n            // resource types match, we return the first one.\r\n            // TODO: May want to pick the latest one from the list. But since we are not using\r\n            // the version in our commands, picking any one is good for now.\r\n            ResourceListItem? candidate = null;\r\n            string candidateType = string.Empty;\r\n\r\n            foreach (ResourceListItem resource in resources)\r\n            {\r\n                if (candidate == null)\r\n                {\r\n                    candidate = resource;\r\n                    candidateType = resource.Type;\r\n                }\r\n                else if (!candidateType.Equals(resource.Type, StringComparison.OrdinalIgnoreCase))\r\n                {\r\n                    throw new Exceptions.GetDscResourceMultipleMatches(candidateType, null);\r\n                }\r\n            }\r\n\r\n            return candidate;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Schema_2024_04/Definitions/ResourceKind.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ResourceKind.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Schema_2024_04.Definitions\r\n{\r\n    /// <summary>\r\n    /// https://learn.microsoft.com/en-us/powershell/dsc/reference/schemas/definitions/resourcekind?view=dsc-3.0\r\n    /// The kind of resource.\r\n    /// </summary>\r\n    internal enum ResourceKind\r\n    {\r\n        /// <summary>\r\n        /// The kind is unknown.\r\n        /// </summary>\r\n        Unknown,\r\n\r\n        /// <summary>\r\n        /// A standard resource.\r\n        /// </summary>\r\n        Resource,\r\n\r\n        /// <summary>\r\n        /// An adapter resource.\r\n        /// </summary>\r\n        Adapter,\r\n\r\n        /// <summary>\r\n        /// A group resource.\r\n        /// </summary>\r\n        Group,\r\n\r\n        /// <summary>\r\n        /// An import(er) resource.\r\n        /// The name listed in the DSC schema.\r\n        /// </summary>\r\n        Import,\r\n\r\n        /// <summary>\r\n        /// An importer resource.\r\n        /// The name used by the code.\r\n        /// </summary>\r\n        Importer = Import,\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Schema_2024_04/Metadata/ResourceInstanceResult.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ResourceInstanceResult.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Schema_2024_04.Metadata\r\n{\r\n    using System;\r\n    using System.Text.Json.Serialization;\r\n\r\n    /// <summary>\r\n    /// Defines metadata DSC returns for a DSC configuration operation against a resource instance.\r\n    /// </summary>\r\n    internal class ResourceInstanceResult\r\n    {\r\n        /// <summary>\r\n        /// Gets or sets the context metadata for this instance result.\r\n        /// </summary>\r\n        [JsonRequired]\r\n        [JsonPropertyName(\"Microsoft.DSC\")]\r\n        public ContextMetadata? MicrosoftDSC { get; set; }\r\n\r\n        /// <summary>\r\n        /// Contains properties generated by the DSC v3 platform.\r\n        /// </summary>\r\n        public class ContextMetadata\r\n        {\r\n            /// <summary>\r\n            /// Gets or sets the duration of a resource instance execution.\r\n            /// </summary>\r\n            [JsonRequired]\r\n            public TimeSpan Duration { get; set; }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Schema_2024_04/Outputs/ConfigurationDocument.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationDocument.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Schema_2024_04.Outputs\r\n{\r\n    using System.Collections.Generic;\r\n    using System.IO;\r\n    using System.Linq;\r\n    using System.Text.Json;\r\n    using System.Text.Json.Serialization;\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Model;\r\n\r\n    /// <summary>\r\n    /// A configuration document.\r\n    /// </summary>\r\n    internal class ConfigurationDocument\r\n    {\r\n        /// <summary>\r\n        /// Gets or sets the list of resources in the document.\r\n        /// </summary>\r\n        public List<ResourceItem> Resources { get; set; } = new List<ResourceItem>();\r\n\r\n        /// <summary>\r\n        /// Gets the list of resources as the interface version.\r\n        /// </summary>\r\n        [JsonIgnore]\r\n        public IList<IResourceExportItem> InterfaceResources\r\n        {\r\n            get\r\n            {\r\n                return new List<IResourceExportItem>(this.Resources.AsEnumerable<IResourceExportItem>());\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the ConfigurationDocument class.\r\n        /// </summary>\r\n        /// <param name=\"document\">The document to construct from.</param>\r\n        /// <param name=\"options\">The options to use.</param>\r\n        /// <returns>The item created.</returns>\r\n        public static ConfigurationDocument CreateFrom(JsonDocument document, JsonSerializerOptions options)\r\n        {\r\n            ConfigurationDocument? result = JsonSerializer.Deserialize<ConfigurationDocument>(document, options);\r\n\r\n            if (result == null)\r\n            {\r\n                throw new InvalidDataException(\"Unable to deserialize ConfigurationDocument.\");\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Schema_2024_04/Outputs/FullItemBase.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"FullItemBase.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Schema_2024_04.Outputs\r\n{\r\n    using System.IO;\r\n    using System.Text.Json;\r\n    using System.Text.Json.Nodes;\r\n    using System.Text.Json.Serialization;\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Schema_2024_04.Metadata;\r\n\r\n    /// <summary>\r\n    /// The base implementation of the full form output.\r\n    /// When the retrieved instance is for group resource, adapter resource, or nested inside a group or adapter resource, DSC returns a full result, which also includes the resource type and instance name.\r\n    /// </summary>\r\n    /// <typeparam name=\"TSimple\">The simple item type.</typeparam>\r\n    /// <typeparam name=\"TFull\">The full item type.</typeparam>\r\n    internal class FullItemBase<TSimple, TFull>\r\n        where TFull : FullItemBase<TSimple, TFull>, new()\r\n    {\r\n        private const string NameProperty = \"name\";\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"FullItemBase{TSimple,TFull}\"/> class.\r\n        /// </summary>\r\n        public FullItemBase()\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the metadata for this test result.\r\n        /// </summary>\r\n        [JsonRequired]\r\n        public ResourceInstanceResult? Metadata { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the name for this test result.\r\n        /// </summary>\r\n        [JsonRequired]\r\n        public string? Name { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the type for the resource.\r\n        /// </summary>\r\n        [JsonRequired]\r\n        public string? Type { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the result of the test.\r\n        /// </summary>\r\n        [JsonRequired]\r\n        public JsonNode? Result { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the simple result.\r\n        /// </summary>\r\n        [JsonIgnore]\r\n        public TSimple? SimpleResult { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the full results.\r\n        /// </summary>\r\n        [JsonIgnore]\r\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"StyleCop.CSharp.SpacingRules\", \"SA1011:Opening square brackets should be spaced correctly\", Justification = \"Pending SC 1.2 release\")]\r\n        protected TFull[]? FullResults { get; set; }\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the TFull class.\r\n        /// </summary>\r\n        /// <param name=\"document\">The document to construct from.</param>\r\n        /// <param name=\"options\">The options to use.</param>\r\n        /// <returns>The item created.</returns>\r\n        public static TFull CreateFrom(JsonDocument document, JsonSerializerOptions options)\r\n        {\r\n            if (!document.RootElement.TryGetProperty(NameProperty, out JsonElement jsonElement))\r\n            {\r\n                return new () { SimpleResult = JsonSerializer.Deserialize<TSimple>(document, options) };\r\n            }\r\n            else\r\n            {\r\n                TFull? result = JsonSerializer.Deserialize<TFull>(document, options);\r\n\r\n                if (result == null)\r\n                {\r\n                    throw new InvalidDataException(\"Unable to deserialize full result.\");\r\n                }\r\n\r\n                result.ProcessResult(options);\r\n                return result;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Converts the Result property into the appropriate simple or full results.\r\n        /// </summary>\r\n        /// <param name=\"options\">The options to use.</param>\r\n        public void ProcessResult(JsonSerializerOptions options)\r\n        {\r\n            if (this.Result == null)\r\n            {\r\n                throw new System.InvalidOperationException(\"JSON result has not been initialized.\");\r\n            }\r\n\r\n            if (this.Result is JsonObject jsonObject)\r\n            {\r\n                this.SimpleResult = JsonSerializer.Deserialize<TSimple>(this.Result, options);\r\n            }\r\n            else\r\n            {\r\n                this.FullResults = JsonSerializer.Deserialize<TFull[]>(this.Result, options);\r\n\r\n                if (this.FullResults == null)\r\n                {\r\n                    throw new InvalidDataException(\"Unable to deserialize full results.\");\r\n                }\r\n\r\n                foreach (TFull result in this.FullResults)\r\n                {\r\n                    result.ProcessResult(options);\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Schema_2024_04/Outputs/GetFullItem.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"GetFullItem.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Schema_2024_04.Outputs\r\n{\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Model;\r\n    using Microsoft.Management.Configuration.Processor.Extensions;\r\n    using Windows.Foundation.Collections;\r\n\r\n    /// <summary>\r\n    /// The full form of the get output.\r\n    /// When the retrieved instance is for group resource, adapter resource, or nested inside a group or adapter resource, DSC returns a full get result, which also includes the resource type and instance name.\r\n    /// </summary>\r\n    internal class GetFullItem : FullItemBase<GetSimpleItem, GetFullItem>, IResourceGetItem\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"GetFullItem\"/> class.\r\n        /// </summary>\r\n        public GetFullItem()\r\n        {\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        public ValueSet Settings\r\n        {\r\n            get\r\n            {\r\n                if (this.SimpleResult != null)\r\n                {\r\n                    return this.SimpleResult.ActualState?.ToValueSet() ?? throw new System.InvalidOperationException(\"Get result has not been initialized.\");\r\n                }\r\n                else if (this.FullResults != null)\r\n                {\r\n                    throw new System.NotImplementedException(\"Requires constructing the entire group as the settings.\");\r\n                }\r\n                else\r\n                {\r\n                    throw new System.InvalidOperationException(\"Get result has not been initialized.\");\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Schema_2024_04/Outputs/GetSimpleItem.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"GetSimpleItem.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Schema_2024_04.Outputs\r\n{\r\n    using System.Text.Json.Nodes;\r\n    using System.Text.Json.Serialization;\r\n\r\n    /// <summary>\r\n    /// The simple form of the get output.\r\n    /// DSC returns a simple get response when the instance isn't a group resource, adapter resource, or nested inside a group or adapter resource.\r\n    /// </summary>\r\n    internal class GetSimpleItem\r\n    {\r\n        /// <summary>\r\n        /// Gets or sets the state of the resource properties.\r\n        /// </summary>\r\n        [JsonRequired]\r\n        public JsonObject? ActualState { get; set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Schema_2024_04/Outputs/ResourceCapability.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ResourceCapability.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Schema_2024_04.Outputs\r\n{\r\n    /// <summary>\r\n    /// https://learn.microsoft.com/en-us/powershell/dsc/reference/schemas/outputs/resource/list?view=dsc-3.0#capabilities\r\n    /// The capabilities that a resource can have.\r\n    /// </summary>\r\n    internal enum ResourceCapability\r\n    {\r\n        /// <summary>\r\n        /// Can call get on the resource.\r\n        /// Required.\r\n        /// </summary>\r\n        Get,\r\n\r\n        /// <summary>\r\n        /// Can call set on the resource.\r\n        /// </summary>\r\n        Set,\r\n\r\n        /// <summary>\r\n        /// The resource operates properly in the presence of the `_exist` property.\r\n        /// If not present, DSC will use `delete` when `_exist == false`.\r\n        /// </summary>\r\n        SetHandlesExist,\r\n\r\n        /// <summary>\r\n        /// The resource can handle a \"what if\" query directly.\r\n        /// Otherwise, DSC will handle it synthetically.\r\n        /// </summary>\r\n        WhatIf,\r\n\r\n        /// <summary>\r\n        /// The resource can handle a \"test\" query directly.\r\n        /// Otherwise, DSC will handle it synthetically.\r\n        /// </summary>\r\n        Test,\r\n\r\n        /// <summary>\r\n        /// Can call delete on the resource.\r\n        /// </summary>\r\n        Delete,\r\n\r\n        /// <summary>\r\n        /// Can call export on the resource.\r\n        /// </summary>\r\n        Export,\r\n\r\n        /// <summary>\r\n        /// Can call resolve on the resource.\r\n        /// This can produce new resources, such as importing another configuration document.\r\n        /// </summary>\r\n        Resolve,\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Schema_2024_04/Outputs/ResourceItem.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ResourceItem.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Schema_2024_04.Outputs\r\n{\r\n    using System.Collections.Generic;\r\n    using System.Text.Json.Nodes;\r\n    using System.Text.Json.Serialization;\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Model;\r\n    using Microsoft.Management.Configuration.Processor.Extensions;\r\n    using Windows.Foundation.Collections;\r\n\r\n    /// <summary>\r\n    /// The object type from a single resource item.\r\n    /// </summary>\r\n    internal class ResourceItem : IResourceExportItem\r\n    {\r\n        /// <summary>\r\n        /// Gets or sets the type of the resource.\r\n        /// Should match the regex \"^\\\\w+(\\\\.\\\\w+){0,2}\\\\/\\\\w+$\".\r\n        /// </summary>\r\n        [JsonRequired]\r\n        required public string Type { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the name of the resource instance.\r\n        /// </summary>\r\n        [JsonRequired]\r\n        required public string Name { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the properties object.\r\n        /// </summary>\r\n        public JsonObject? Properties { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the metadata object.\r\n        /// </summary>\r\n        [JsonPropertyName(\"metadata\")]\r\n        public JsonObject? MetadataObject { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the dependencies.\r\n        /// </summary>\r\n        [JsonPropertyName(\"dependencies\")]\r\n        public List<string> DependenciesList { get; set; } = new List<string>();\r\n\r\n        /// <inheritdoc />\r\n        [JsonIgnore]\r\n        public ValueSet Settings\r\n        {\r\n            get\r\n            {\r\n                return this.Properties.ToValueSet();\r\n            }\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        [JsonIgnore]\r\n        public ValueSet Metadata\r\n        {\r\n            get\r\n            {\r\n                return this.MetadataObject.ToValueSet();\r\n            }\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        [JsonIgnore]\r\n        public IList<string> Dependencies\r\n        {\r\n            get\r\n            {\r\n                return this.DependenciesList;\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Schema_2024_04/Outputs/ResourceListItem.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ResourceListItem.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Schema_2024_04.Outputs\r\n{\r\n    using System.Text.Json.Nodes;\r\n    using System.Text.Json.Serialization;\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Model;\r\n\r\n    /// <summary>\r\n    /// The object type from a single JSON line output by the `resource list` command.\r\n    /// </summary>\r\n    internal class ResourceListItem : IResourceListItem\r\n    {\r\n        /// <summary>\r\n        /// Gets or sets the type of the resource.\r\n        /// Should match the regex \"^\\\\w+(\\\\.\\\\w+){0,2}\\\\/\\\\w+$\".\r\n        /// </summary>\r\n        [JsonRequired]\r\n        required public string Type { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the kind of the resource.\r\n        /// </summary>\r\n        public Definitions.ResourceKind Kind { get; set; } = Definitions.ResourceKind.Unknown;\r\n\r\n        /// <inheritdoc />\r\n        [JsonIgnore]\r\n        Model.ResourceKind IResourceListItem.Kind => this.Kind switch\r\n        {\r\n            Definitions.ResourceKind.Unknown => Model.ResourceKind.Unknown,\r\n            Definitions.ResourceKind.Resource => Model.ResourceKind.Resource,\r\n            Definitions.ResourceKind.Adapter => Model.ResourceKind.Adapter,\r\n            Definitions.ResourceKind.Group => Model.ResourceKind.Group,\r\n            Definitions.ResourceKind.Import => Model.ResourceKind.Importer,\r\n            _ => throw new System.IO.InvalidDataException($\"Unknown ResourceKind: {this.Kind}\")\r\n        };\r\n\r\n        /// <summary>\r\n        /// Gets or sets the version of the resource.\r\n        /// This is a semver version.\r\n        /// </summary>\r\n        public string? Version { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the capabilities of the resource.\r\n        /// </summary>\r\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"StyleCop.CSharp.SpacingRules\", \"SA1010:Opening square brackets should be spaced correctly\", Justification = \"https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3687 pending SC 1.2 release\")]\r\n        public ResourceCapability[] Capabilities { get; set; } = [];\r\n\r\n        /// <summary>\r\n        /// Gets or sets the description of the resource.\r\n        /// </summary>\r\n        public string? Description { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the path to the resource definition file.\r\n        /// </summary>\r\n        public string? Path { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the path to the directory containing the resource.\r\n        /// </summary>\r\n        public string? Directory { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value that indicates implementation details of the resource.\r\n        /// </summary>\r\n        public JsonNode? ImplementedAs { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the author of the resource.\r\n        /// </summary>\r\n        public string? Author { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the names of the properties of the resource.\r\n        /// </summary>\r\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"StyleCop.CSharp.SpacingRules\", \"SA1010:Opening square brackets should be spaced correctly\", Justification = \"https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3687 pending SC 1.2 release\")]\r\n        public string[] Properties { get; set; } = [];\r\n\r\n        /// <summary>\r\n        /// Gets or sets the adapter required by the resource.\r\n        /// </summary>\r\n        public string? RequireAdapter { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the resource definition manifest.\r\n        /// </summary>\r\n        public JsonObject? Manifest { get; set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Schema_2024_04/Outputs/SetFullItem.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"SetFullItem.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Schema_2024_04.Outputs\r\n{\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Model;\r\n\r\n    /// <summary>\r\n    /// The full form of the set output.\r\n    /// When the retrieved instance is for group resource, adapter resource, or nested inside a group or adapter resource, DSC returns a full set result, which also includes the resource type and instance name.\r\n    /// </summary>\r\n    internal class SetFullItem : FullItemBase<SetSimpleItem, SetFullItem>, IResourceSetItem\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"SetFullItem\"/> class.\r\n        /// </summary>\r\n        public SetFullItem()\r\n        {\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        public bool RebootRequired => false;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Schema_2024_04/Outputs/SetSimpleItem.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"SetSimpleItem.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Schema_2024_04.Outputs\r\n{\r\n    using System.Text.Json.Nodes;\r\n    using System.Text.Json.Serialization;\r\n\r\n    /// <summary>\r\n    /// The simple form of the set output.\r\n    /// DSC returns a simple set response when the instance isn't a group resource, adapter resource, or nested inside a group or adapter resource.\r\n    /// </summary>\r\n    internal class SetSimpleItem\r\n    {\r\n        /// <summary>\r\n        /// Gets or sets the state of the resource properties before the attempt to set them.\r\n        /// </summary>\r\n        [JsonRequired]\r\n        public JsonObject? BeforeState { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the state of the resource properties after the attempt to set them.\r\n        /// </summary>\r\n        [JsonRequired]\r\n        public JsonObject? AfterState { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the list of properties that changed.\r\n        /// </summary>\r\n        [JsonRequired]\r\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"StyleCop.CSharp.SpacingRules\", \"SA1010:Opening square brackets should be spaced correctly\", Justification = \"https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3687 pending SC 1.2 release\")]\r\n        public string[] ChangedProperties { get; set; } = [];\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Schema_2024_04/Outputs/TestFullItem.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"TestFullItem.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Schema_2024_04.Outputs\r\n{\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Model;\r\n\r\n    /// <summary>\r\n    /// The full form of the test output.\r\n    /// When the retrieved instance is for group resource, adapter resource, or nested inside a group or adapter resource, DSC returns a full test result, which also includes the resource type and instance name.\r\n    /// </summary>\r\n    internal class TestFullItem : FullItemBase<TestSimpleItem, TestFullItem>, IResourceTestItem\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"TestFullItem\"/> class.\r\n        /// </summary>\r\n        public TestFullItem()\r\n        {\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        public bool InDesiredState\r\n        {\r\n            get\r\n            {\r\n                if (this.SimpleResult != null)\r\n                {\r\n                    return this.SimpleResult.InDesiredState;\r\n                }\r\n                else if (this.FullResults != null)\r\n                {\r\n                    bool result = true;\r\n\r\n                    foreach (var item in this.FullResults)\r\n                    {\r\n                        result = result && item.InDesiredState;\r\n                    }\r\n\r\n                    return result;\r\n                }\r\n                else\r\n                {\r\n                    throw new System.InvalidOperationException(\"Test result has not been initialized.\");\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Schema_2024_04/Outputs/TestSimpleItem.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"TestSimpleItem.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Schema_2024_04.Outputs\r\n{\r\n    using System.Text.Json.Nodes;\r\n    using System.Text.Json.Serialization;\r\n\r\n    /// <summary>\r\n    /// The simple form of the test output.\r\n    /// DSC returns a simple test response when the instance isn't a group resource, adapter resource, or nested inside a group or adapter resource.\r\n    /// </summary>\r\n    internal class TestSimpleItem\r\n    {\r\n        /// <summary>\r\n        /// Gets or sets the desired state of the resource properties.\r\n        /// </summary>\r\n        [JsonRequired]\r\n        public JsonObject? DesiredState { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the actual state of the resource properties.\r\n        /// </summary>\r\n        [JsonRequired]\r\n        public JsonObject? ActualState { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether the resource is in the desired state.\r\n        /// </summary>\r\n        [JsonRequired]\r\n        public bool InDesiredState { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the list of properties that are not in the desired state.\r\n        /// </summary>\r\n        [JsonRequired]\r\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"StyleCop.CSharp.SpacingRules\", \"SA1010:Opening square brackets should be spaced correctly\", Justification = \"https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3687 pending SC 1.2 release\")]\r\n        public string[] DifferingProperties { get; set; } = [];\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Set/DSCv3ConfigurationSetProcessor.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"DSCv3ConfigurationSetProcessor.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Set\r\n{\r\n    using System.Collections.Generic;\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Helpers;\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Unit;\r\n    using Microsoft.Management.Configuration.Processor.Helpers;\r\n    using Microsoft.Management.Configuration.Processor.Set;\r\n\r\n    /// <summary>\r\n    /// Configuration set processor.\r\n    /// </summary>\r\n    internal sealed partial class DSCv3ConfigurationSetProcessor : ConfigurationSetProcessorBase, IConfigurationSetProcessor, IFindUnitProcessorsSetProcessor\r\n    {\r\n        private readonly ProcessorSettings processorSettings;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"DSCv3ConfigurationSetProcessor\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"processorSettings\">The processor settings to use.</param>\r\n        /// <param name=\"configurationSet\">Configuration set.</param>\r\n        /// <param name=\"isLimitMode\">Whether the set processor should work in limitation mode.</param>\r\n        public DSCv3ConfigurationSetProcessor(ProcessorSettings processorSettings, ConfigurationSet? configurationSet, bool isLimitMode = false)\r\n            : base(configurationSet, isLimitMode)\r\n        {\r\n            this.processorSettings = processorSettings;\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        protected override IConfigurationUnitProcessor CreateUnitProcessorInternal(ConfigurationUnit unit)\r\n        {\r\n            ConfigurationUnitInternal configurationUnitInternal = new ConfigurationUnitInternal(unit, this.ConfigurationSet?.Path);\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, $\"Creating unit processor for: {configurationUnitInternal.QualifiedName}...\");\r\n\r\n            ResourceDetails? resourceDetails = this.processorSettings.GetResourceDetails(configurationUnitInternal, ConfigurationUnitDetailFlags.Local);\r\n            if (resourceDetails == null)\r\n            {\r\n                this.OnDiagnostics(DiagnosticLevel.Verbose, $\"Resource not found: {configurationUnitInternal.QualifiedName}\");\r\n\r\n                // Don't throw when the resource is not found until https://github.com/PowerShell/DSC/issues/786 is resolved\r\n                // throw new Exceptions.FindDscResourceNotFoundException(configurationUnitInternal.QualifiedName, null);\r\n            }\r\n\r\n            return new DSCv3ConfigurationUnitProcessor(this.processorSettings, resourceDetails, configurationUnitInternal, this.IsLimitMode) { SetProcessorFactory = this.SetProcessorFactory };\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        protected override IConfigurationUnitProcessorDetails? GetUnitProcessorDetailsInternal(ConfigurationUnit unit, ConfigurationUnitDetailFlags detailFlags)\r\n        {\r\n            ConfigurationUnitInternal configurationUnitInternal = new ConfigurationUnitInternal(unit, this.ConfigurationSet?.Path);\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, $\"Getting resource details [{detailFlags}] for: {configurationUnitInternal.QualifiedName}...\");\r\n\r\n            ResourceDetails? resourceDetails = this.processorSettings.GetResourceDetails(configurationUnitInternal, detailFlags);\r\n            if (resourceDetails == null)\r\n            {\r\n                this.OnDiagnostics(DiagnosticLevel.Verbose, $\"Resource not found: {configurationUnitInternal.QualifiedName}\");\r\n                return null;\r\n            }\r\n\r\n            return resourceDetails.GetConfigurationUnitProcessorDetails();\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        protected override IList<IConfigurationUnitProcessorDetails> FindUnitProcessorsInternal(FindUnitProcessorsOptions findOptions)\r\n        {\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, $\"Finding unit processors with following options. SearchPaths: {findOptions.SearchPaths}, SearchPathsExclusive: {findOptions.SearchPathsExclusive}, DetailFlags: [{findOptions.UnitDetailFlags}]\");\r\n            List<IConfigurationUnitProcessorDetails> result = new List<IConfigurationUnitProcessorDetails>();\r\n\r\n            var resourceDetailsList = this.processorSettings.FindAllResourceDetails(findOptions);\r\n            foreach (var resourceDetails in resourceDetailsList)\r\n            {\r\n                result.Add(resourceDetails.GetConfigurationUnitProcessorDetails() !);\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/DSCv3/Unit/DSCv3ConfigurationUnitProcessor.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"DSCv3ConfigurationUnitProcessor.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.DSCv3.Unit\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using Microsoft.Management.Configuration;\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Helpers;\r\n    using Microsoft.Management.Configuration.Processor.Exceptions;\r\n    using Microsoft.Management.Configuration.Processor.Helpers;\r\n    using Microsoft.Management.Configuration.Processor.Unit;\r\n    using Windows.Foundation.Collections;\r\n\r\n    /// <summary>\r\n    /// Provides access to a specific configuration unit within the runtime.\r\n    /// </summary>\r\n    internal sealed partial class DSCv3ConfigurationUnitProcessor : ConfigurationUnitProcessorBase, IConfigurationUnitProcessor, IGetAllSettingsConfigurationUnitProcessor, IGetAllUnitsConfigurationUnitProcessor, IDiagnosticsSink\r\n    {\r\n        private readonly ProcessorSettings processorSettings;\r\n        private readonly ResourceDetails? resourceDetails;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"DSCv3ConfigurationUnitProcessor\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"processorSettings\">The processor settings to use.</param>\r\n        /// <param name=\"resourceDetails\">The resource to use.</param>\r\n        /// <param name=\"unitInternal\">Internal unit.</param>\r\n        /// <param name=\"isLimitMode\">Whether it is under limit mode.</param>\r\n        internal DSCv3ConfigurationUnitProcessor(ProcessorSettings processorSettings, ResourceDetails? resourceDetails, ConfigurationUnitInternal unitInternal, bool isLimitMode = false)\r\n            : base(unitInternal, isLimitMode)\r\n        {\r\n            this.processorSettings = processorSettings;\r\n            this.resourceDetails = resourceDetails;\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        void IDiagnosticsSink.OnDiagnostics(DiagnosticLevel level, string message)\r\n        {\r\n            this.OnDiagnostics(level, message);\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        protected override ValueSet GetSettingsInternal()\r\n        {\r\n            return this.processorSettings.DSCv3.GetResourceSettings(this.UnitInternal, ProcessorRunSettings.CreateFromResourceDetails(this.resourceDetails)).Settings;\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        protected override bool TestSettingsInternal()\r\n        {\r\n            return this.processorSettings.DSCv3.TestResource(this.UnitInternal, ProcessorRunSettings.CreateFromResourceDetails(this.resourceDetails)).InDesiredState;\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        protected override bool ApplySettingsInternal()\r\n        {\r\n            return this.processorSettings.DSCv3.SetResourceSettings(this.UnitInternal, ProcessorRunSettings.CreateFromResourceDetails(this.resourceDetails)).RebootRequired;\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        protected override IList<ValueSet>? GetAllSettingsInternal()\r\n        {\r\n            var exportResult = this.processorSettings.DSCv3.ExportResource(this.UnitInternal, ProcessorRunSettings.CreateFromResourceDetails(this.resourceDetails));\r\n\r\n            string expectedType = this.UnitInternal.QualifiedName.ToLowerInvariant();\r\n            List<ValueSet> result = new List<ValueSet>();\r\n\r\n            foreach (var exportItem in exportResult)\r\n            {\r\n                if (exportItem.Type.ToLowerInvariant() != expectedType)\r\n                {\r\n                    throw new UnitPropertyUnsupportedException(typeof(IGetAllSettingsConfigurationUnitProcessor));\r\n                }\r\n\r\n                result.Add(exportItem.Settings);\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        protected override IList<ConfigurationUnit>? GetAllUnitsInternal()\r\n        {\r\n            var exportResult = this.processorSettings.DSCv3.ExportResource(this.UnitInternal, ProcessorRunSettings.CreateFromResourceDetails(this.resourceDetails));\r\n\r\n            List<ConfigurationUnit> result = new List<ConfigurationUnit>();\r\n\r\n            foreach (var exportItem in exportResult)\r\n            {\r\n                ConfigurationUnit unit = new ConfigurationUnit();\r\n\r\n                unit.Type = exportItem.Type;\r\n                unit.Identifier = exportItem.Name;\r\n                unit.Settings = exportItem.Settings;\r\n                unit.Metadata = exportItem.Metadata;\r\n                unit.Dependencies = exportItem.Dependencies;\r\n\r\n                result.Add(unit);\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Exceptions/ErrorCodes.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ErrorCodes.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Exceptions\r\n{\r\n    /// <summary>\r\n    /// This should match the ones in AppInstallerErrors.h.\r\n    /// </summary>\r\n    internal static class ErrorCodes\r\n    {\r\n        /// <summary>\r\n        /// Corresponds to E_UNEXPECTED; this code path was reached without the developer realizing it was possible.\r\n        /// </summary>\r\n        internal const int Unexpected = unchecked((int)0x8000ffff);\r\n\r\n        /// <summary>\r\n        /// The module of the unit was installed, but the unit was not found.\r\n        /// </summary>\r\n        internal const int WinGetConfigUnitNotFound = unchecked((int)0x8A15C101);\r\n\r\n        /// <summary>\r\n        /// The unit couldn't be found in the repository.\r\n        /// </summary>\r\n        internal const int WinGetConfigUnitNotFoundRepository = unchecked((int)0x8A15C102);\r\n\r\n        /// <summary>\r\n        /// Multiple units found with the same criteria.\r\n        /// </summary>\r\n        internal const int WinGetConfigUnitMultipleMatches = unchecked((int)0x8A15C103);\r\n\r\n        /// <summary>\r\n        /// Unit error calling Invoke-DscResource Get.\r\n        /// </summary>\r\n        internal const int WinGetConfigUnitInvokeGet = unchecked((int)0x8A15C104);\r\n\r\n        /// <summary>\r\n        /// Unit error calling Invoke-DscResource Test.\r\n        /// </summary>\r\n        internal const int WinGetConfigUnitInvokeTest = unchecked((int)0x8A15C105);\r\n\r\n        /// <summary>\r\n        /// Unit error calling Invoke-DscResource Set.\r\n        /// </summary>\r\n        internal const int WinGetConfigUnitInvokeSet = unchecked((int)0x8A15C106);\r\n\r\n        /// <summary>\r\n        /// Internal error calling Get-DscResource. More than one module found with the same version.\r\n        /// </summary>\r\n        internal const int WinGetConfigUnitModuleConflict = unchecked((int)0x8A15C107);\r\n\r\n        /// <summary>\r\n        /// The module where the DSC resource is implemented cannot be imported.\r\n        /// </summary>\r\n        internal const int WinGetConfigUnitImportModule = unchecked((int)0x8A15C108);\r\n\r\n        /// <summary>\r\n        /// The unit returned an invalid result.\r\n        /// </summary>\r\n        internal const int WinGetConfigUnitInvokeInvalidResult = unchecked((int)0x8A15C109);\r\n\r\n        /// <summary>\r\n        /// The unit contains a setting that requires config root.\r\n        /// </summary>\r\n        internal const int WinGetConfigUnitSettingConfigRoot = unchecked((int)0x8A15C110);\r\n\r\n        /// <summary>\r\n        /// The module where the DSC resource is implemented requires admin.\r\n        /// </summary>\r\n        internal const int WinGetConfigUnitImportModuleAdmin = unchecked((int)0x8A15C111);\r\n\r\n        /// <summary>\r\n        /// The property type of a unit is not supported.\r\n        /// </summary>\r\n        internal const int WinGetConfigUnitUnsupportedType = unchecked((int)0x8A15C112);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Exceptions/FindDscResourceNotFoundException.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"FindDscResourceNotFoundException.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Exceptions\r\n{\r\n    using System;\r\n    using Microsoft.PowerShell.Commands;\r\n\r\n    /// <summary>\r\n    /// Resource not found by Find-DscResource.\r\n    /// </summary>\r\n    internal class FindDscResourceNotFoundException : Exception\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"FindDscResourceNotFoundException\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"resourceName\">Resource name.</param>\r\n        /// <param name=\"module\">Optional module.</param>\r\n        public FindDscResourceNotFoundException(string resourceName, ModuleSpecification? module)\r\n            : base($\"Could not find resource: {resourceName} [{module?.ToString() ?? \"<no module>\"}]\")\r\n        {\r\n            this.HResult = ErrorCodes.WinGetConfigUnitNotFoundRepository;\r\n            this.ResourceName = resourceName;\r\n            this.Module = module;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the resource name.\r\n        /// </summary>\r\n        public string ResourceName { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the module, if any.\r\n        /// </summary>\r\n        public ModuleSpecification? Module { get; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Exceptions/GetDscResourceModuleConflict.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"GetDscResourceModuleConflict.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Exceptions\r\n{\r\n    using System;\r\n    using System.Management.Automation;\r\n    using Microsoft.PowerShell.Commands;\r\n\r\n    /// <summary>\r\n    /// A call to Get-DscResource failed because at least two modules with the same version where found in the module path.\r\n    /// If you are getting this verify the module path.\r\n    /// </summary>\r\n    internal class GetDscResourceModuleConflict : Exception\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"GetDscResourceModuleConflict\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"resourceName\">Resource name.</param>\r\n        /// <param name=\"module\">Optional module.</param>\r\n        /// <param name=\"inner\">The original runtime exception thrown.</param>\r\n        public GetDscResourceModuleConflict(string? resourceName, ModuleSpecification? module, RuntimeException inner)\r\n            : base($\"Multiple modules with same version in module path: {resourceName?.ToString() ?? \"<no resource>\"} [{module?.ToString() ?? \"<no module>\"}]\", inner)\r\n        {\r\n            this.HResult = ErrorCodes.WinGetConfigUnitModuleConflict;\r\n            this.ResourceName = resourceName;\r\n            this.Module = module;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the resource name.\r\n        /// </summary>\r\n        public string? ResourceName { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the module, if any.\r\n        /// </summary>\r\n        public ModuleSpecification? Module { get; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Exceptions/GetDscResourceMultipleMatches.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"GetDscResourceMultipleMatches.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Exceptions\r\n{\r\n    using System;\r\n    using Microsoft.PowerShell.Commands;\r\n\r\n    /// <summary>\r\n    /// A call to Get-DscResource return multiple results for a specific resource.\r\n    /// </summary>\r\n    internal class GetDscResourceMultipleMatches : Exception\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"GetDscResourceMultipleMatches\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"resourceName\">Resource name.</param>\r\n        /// <param name=\"module\">Optional module.</param>\r\n        public GetDscResourceMultipleMatches(string resourceName, ModuleSpecification? module)\r\n            : base($\"Multiple matches found for resource: {resourceName} [{module?.ToString() ?? \"<no module>\"}]\")\r\n        {\r\n            this.HResult = ErrorCodes.WinGetConfigUnitMultipleMatches;\r\n            this.ResourceName = resourceName;\r\n            this.Module = module;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the resource name.\r\n        /// </summary>\r\n        public string ResourceName { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the module, if any.\r\n        /// </summary>\r\n        public ModuleSpecification? Module { get; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Exceptions/IConfigurationUnitResultException.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"IConfigurationUnitResultException.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Exceptions\r\n{\r\n    using System;\r\n    using Microsoft.PowerShell.Commands;\r\n\r\n    /// <summary>\r\n    /// An interface that enables an exception to expose information appropriate for a unit result.\r\n    /// </summary>\r\n    internal interface IConfigurationUnitResultException\r\n    {\r\n        /// <summary>\r\n        /// Gets a value indicating the source of the result.\r\n        /// </summary>\r\n        public ConfigurationUnitResultSource ResultSource { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the description of the result.\r\n        /// </summary>\r\n        public string Description { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the details for the result.\r\n        /// </summary>\r\n        public string Details { get; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Exceptions/ImportModuleException.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"ImportModuleException.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Exceptions\r\n{\r\n    using System;\r\n    using System.Management.Automation;\r\n\r\n    /// <summary>\r\n    /// Import-Module threw an exception.\r\n    /// </summary>\r\n    internal class ImportModuleException : Exception\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ImportModuleException\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"moduleName\">Module name.</param>\r\n        /// <param name=\"pwshEx\">Inner exception.</param>\r\n        public ImportModuleException(string? moduleName, Exception pwshEx)\r\n            : base($\"Could not import module: {moduleName?.ToString() ?? \"<no module>\"}\", pwshEx)\r\n        {\r\n            this.HResult = this.GetHResult(pwshEx);\r\n            this.ModuleName = moduleName;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the module name.\r\n        /// </summary>\r\n        public string? ModuleName { get; }\r\n\r\n        private int GetHResult(Exception pwshEx)\r\n        {\r\n            if (pwshEx.InnerException is not null)\r\n            {\r\n                var scriptEx = pwshEx.InnerException as ScriptRequiresException;\r\n                if (scriptEx is not null)\r\n                {\r\n                    if (scriptEx.ErrorRecord.CategoryInfo.Category == ErrorCategory.PermissionDenied)\r\n                    {\r\n                        return ErrorCodes.WinGetConfigUnitImportModuleAdmin;\r\n                    }\r\n                }\r\n            }\r\n\r\n            return ErrorCodes.WinGetConfigUnitImportModule;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Exceptions/InstallDscResourceException.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"InstallDscResourceException.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Exceptions\r\n{\r\n    using System;\r\n    using Microsoft.PowerShell.Commands;\r\n\r\n    /// <summary>\r\n    /// Installing a DSC resource failed unexpectedly.\r\n    /// </summary>\r\n    internal class InstallDscResourceException : Exception\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"InstallDscResourceException\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"resourceName\">Resource name.</param>\r\n        /// <param name=\"module\">Module.</param>\r\n        public InstallDscResourceException(string resourceName, ModuleSpecification? module)\r\n            : base($\"Unable to find resource after install: {resourceName} [{module?.ToString() ?? \"<no module>\"}]\")\r\n        {\r\n            this.HResult = ErrorCodes.WinGetConfigUnitNotFound;\r\n            this.ResourceName = resourceName;\r\n            this.Module = module;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the resource name.\r\n        /// </summary>\r\n        public string ResourceName { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the module, if any.\r\n        /// </summary>\r\n        public ModuleSpecification? Module { get; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Exceptions/InvokeDscResourceException.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"InvokeDscResourceException.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Exceptions\r\n{\r\n    using System;\r\n    using System.Management.Automation;\r\n    using Microsoft.Management.Configuration;\r\n    using Microsoft.PowerShell.Commands;\r\n\r\n    /// <summary>\r\n    /// A call to Invoke-DscResource failed unexpectedly.\r\n    /// </summary>\r\n    internal class InvokeDscResourceException : Exception, IConfigurationUnitResultException\r\n    {\r\n        /// <summary>\r\n        /// The string for the Get method.\r\n        /// </summary>\r\n        public const string Get = \"Get\";\r\n\r\n        /// <summary>\r\n        /// The string for the Set method.\r\n        /// </summary>\r\n        public const string Set = \"Set\";\r\n\r\n        /// <summary>\r\n        /// The string for the Test method.\r\n        /// </summary>\r\n        public const string Test = \"Test\";\r\n\r\n        /// <summary>\r\n        /// The string for the Export method.\r\n        /// </summary>\r\n        public const string Export = \"Export\";\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"InvokeDscResourceException\"/> class.\r\n        /// Use this constructor when no error is generated by the invoke and the result is not a valid value.\r\n        /// </summary>\r\n        /// <param name=\"method\">Method.</param>\r\n        /// <param name=\"resourceName\">Resource name.</param>\r\n        /// <param name=\"module\">Optional module.</param>\r\n        public InvokeDscResourceException(string method, string resourceName, ModuleSpecification? module = null)\r\n            : base(CreateMessage(method, resourceName, module, null))\r\n        {\r\n            // No message means that the invoke returned an invalid result.\r\n            this.HResult = ErrorCodes.WinGetConfigUnitInvokeInvalidResult;\r\n            this.Method = method;\r\n            this.ResourceName = resourceName;\r\n            this.Module = module;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"InvokeDscResourceException\"/> class.\r\n        /// Use this constructor when there is a message and the result is not valid.\r\n        /// </summary>\r\n        /// <param name=\"method\">Method.</param>\r\n        /// <param name=\"resourceName\">Resource name.</param>\r\n        /// <param name=\"message\">Message.</param>\r\n        public InvokeDscResourceException(string method, string resourceName, string message)\r\n            : base(CreateMessage(method, resourceName, null, message))\r\n        {\r\n            this.HResult = ErrorCodes.WinGetConfigUnitInvokeInvalidResult;\r\n            this.Method = method;\r\n            this.ResourceName = resourceName;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"InvokeDscResourceException\"/> class.\r\n        /// Use this constructor when the invoke fails with an error message.\r\n        /// </summary>\r\n        /// <param name=\"method\">Method.</param>\r\n        /// <param name=\"resourceName\">Resource name.</param>\r\n        /// <param name=\"module\">Optional module.</param>\r\n        /// <param name=\"message\">Message.</param>\r\n        /// <param name=\"configurationSetSource\">If true, the source of this error is set to be the configuration.</param>\r\n        public InvokeDscResourceException(string method, string resourceName, ModuleSpecification? module, string message, bool configurationSetSource = false)\r\n            : base(CreateMessage(method, resourceName, module, message))\r\n        {\r\n            this.HResult = GetHRForMethod(method);\r\n            this.Method = method;\r\n            this.ResourceName = resourceName;\r\n            this.Module = module;\r\n            this.Description = message;\r\n\r\n            if (configurationSetSource)\r\n            {\r\n                this.ResultSource = ConfigurationUnitResultSource.ConfigurationSet;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"InvokeDscResourceException\"/> class.\r\n        /// Use this constructor when the invoke fails with an exception.\r\n        /// </summary>\r\n        /// <param name=\"method\">Method.</param>\r\n        /// <param name=\"resourceName\">Resource name.</param>\r\n        /// <param name=\"module\">Optional module.</param>\r\n        /// <param name=\"inner\">The invoke exception.</param>\r\n        public InvokeDscResourceException(string method, string resourceName, ModuleSpecification? module, Exception inner)\r\n            : base(CreateMessage(method, resourceName, module, inner.Message), inner)\r\n        {\r\n            this.HResult = GetHRForMethod(method);\r\n            this.Method = method;\r\n            this.ResourceName = resourceName;\r\n            this.Module = module;\r\n            this.Description = (inner as RuntimeException)?.ErrorRecord.ToString() ?? inner.Message;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the invoke method.\r\n        /// </summary>\r\n        public string Method { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the resource name.\r\n        /// </summary>\r\n        public string ResourceName { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the module, if any.\r\n        /// </summary>\r\n        public ModuleSpecification? Module { get; }\r\n\r\n        /// <summary>\r\n        /// Gets a value indicating the source of the result.\r\n        /// </summary>\r\n        public ConfigurationUnitResultSource ResultSource { get; } = ConfigurationUnitResultSource.UnitProcessing;\r\n\r\n        /// <summary>\r\n        /// Gets the description of the result.\r\n        /// </summary>\r\n        public string Description { get; } = string.Empty;\r\n\r\n        /// <summary>\r\n        /// Gets the details for the result.\r\n        /// </summary>\r\n        public string Details\r\n        {\r\n            get\r\n            {\r\n                RuntimeException? re = this.InnerException as RuntimeException;\r\n                if (re != null)\r\n                {\r\n                    return re.ErrorRecord.ScriptStackTrace;\r\n                }\r\n\r\n                return this.ToString();\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the HRESULT value for the given method.\r\n        /// </summary>\r\n        /// <param name=\"method\">The method.</param>\r\n        /// <returns>The HRESULT for the method.</returns>\r\n        private static int GetHRForMethod(string method)\r\n        {\r\n            switch (method)\r\n            {\r\n                case Get: return ErrorCodes.WinGetConfigUnitInvokeGet;\r\n                case Set: return ErrorCodes.WinGetConfigUnitInvokeSet;\r\n                case Test: return ErrorCodes.WinGetConfigUnitInvokeTest;\r\n                case Export: return ErrorCodes.WinGetConfigUnitInvokeGet;\r\n            }\r\n\r\n            return ErrorCodes.Unexpected;\r\n        }\r\n\r\n        private static string CreateMessage(string method, string resourceName, ModuleSpecification? module, string? message)\r\n        {\r\n            string result = $\"Failed when calling `{method}` for resource: {resourceName} [{module?.ToString() ?? \"<no module>\"}]\";\r\n            if (message != null)\r\n            {\r\n                result += $\" Message: '{message}'\";\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Exceptions/UnitPropertyUnsupportedException.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"UnitPropertyUnsupportedException.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Exceptions\r\n{\r\n    using System;\r\n\r\n    /// <summary>\r\n    /// The property type of a unit is not supported.\r\n    /// </summary>\r\n    internal class UnitPropertyUnsupportedException : Exception\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"UnitPropertyUnsupportedException\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"name\">Name.</param>\r\n        /// <param name=\"type\">Type.</param>\r\n        /// <param name=\"inner\">Inner exception.</param>\r\n        public UnitPropertyUnsupportedException(string name, Type type, Exception inner)\r\n            : base($\"Property {name} of type {type.FullName} is not supported.\", inner)\r\n        {\r\n            this.HResult = ErrorCodes.WinGetConfigUnitUnsupportedType;\r\n            this.Name = name;\r\n            this.Type = type;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"UnitPropertyUnsupportedException\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"type\">Type.</param>\r\n        public UnitPropertyUnsupportedException(Type type)\r\n            : base($\"Type {type.FullName} is not supported.\")\r\n        {\r\n            this.HResult = ErrorCodes.WinGetConfigUnitUnsupportedType;\r\n            this.Type = type;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the name.\r\n        /// </summary>\r\n        public string? Name { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the type.\r\n        /// </summary>\r\n        public Type Type { get; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Exceptions/UnitSettingConfigRootException.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"UnitSettingConfigRootException.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Exceptions\r\n{\r\n    using System;\r\n\r\n    /// <summary>\r\n    /// A setting uses the config root variable and the Path was not set in the ConfigurationSet.\r\n    /// </summary>\r\n    internal class UnitSettingConfigRootException : Exception\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"UnitSettingConfigRootException\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"unitName\">Unit name.</param>\r\n        /// <param name=\"setting\">Setting.</param>\r\n        public UnitSettingConfigRootException(string unitName, string setting)\r\n            : base($\"Unit: {unitName} Setting {setting} requires the ConfigurationSet Path\")\r\n        {\r\n            this.HResult = ErrorCodes.WinGetConfigUnitSettingConfigRoot;\r\n            this.UnitName = unitName;\r\n            this.Setting = setting;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the resource name.\r\n        /// </summary>\r\n        public string UnitName { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the setting that reference the config root variable.\r\n        /// </summary>\r\n        public string Setting { get; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Extensions/DictionaryExtensions.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"DictionaryExtensions.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Extensions\r\n{\r\n    using System;\r\n    using System.Collections;\r\n    using System.Collections.Generic;\r\n    using Windows.Foundation.Collections;\r\n\r\n    /// <summary>\r\n    /// Extensions for dictionaries.\r\n    /// </summary>\r\n    internal static class DictionaryExtensions\r\n    {\r\n        /// <summary>\r\n        /// Performs a deep compare of the dictionaries.\r\n        /// </summary>\r\n        /// <param name=\"first\">First dictionary.</param>\r\n        /// <param name=\"second\">Second dictionary.</param>\r\n        /// <returns>Whether the two dictionaries equal.</returns>\r\n        internal static bool ContentEquals(this IDictionary<string, string> first, IDictionary<string, string> second)\r\n        {\r\n            if (first.Count != second.Count)\r\n            {\r\n                return false;\r\n            }\r\n\r\n            foreach (var keyValuePair in first)\r\n            {\r\n                string key = keyValuePair.Key;\r\n                if (!second.ContainsKey(key))\r\n                {\r\n                    return false;\r\n                }\r\n\r\n                var firstValue = keyValuePair.Value;\r\n                var secondValue = second[key];\r\n\r\n                // Empty value check.\r\n                if (firstValue == null && secondValue == null)\r\n                {\r\n                    continue;\r\n                }\r\n                else if (firstValue == null || secondValue == null)\r\n                {\r\n                    return false;\r\n                }\r\n\r\n                if (firstValue != secondValue)\r\n                {\r\n                    return false;\r\n                }\r\n            }\r\n\r\n            return true;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Extensions/ExceptionExtensions.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"ExceptionExtensions.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Extensions\r\n{\r\n    using System;\r\n\r\n    /// <summary>\r\n    /// Extension method for Exception.\r\n    /// </summary>\r\n    internal static class ExceptionExtensions\r\n    {\r\n        /// <summary>\r\n        /// Gets the most inner exception.\r\n        /// </summary>\r\n        /// <param name=\"e\">Exception.</param>\r\n        /// <returns>Most inner exception.</returns>\r\n        public static Exception GetMostInnerException(this Exception e)\r\n        {\r\n            Exception ex = e;\r\n            while (ex.InnerException != null)\r\n            {\r\n                ex = ex.InnerException;\r\n            }\r\n\r\n            return ex;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Extensions/HashtableExtensions.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"HashtableExtensions.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Extensions\r\n{\r\n    using System.Collections;\r\n    using Microsoft.Management.Configuration.Processor.Exceptions;\r\n    using Microsoft.Management.Configuration.Processor.Helpers;\r\n    using Windows.Foundation.Collections;\r\n\r\n    /// <summary>\r\n    /// Extensions for Hashtable.\r\n    /// </summary>\r\n    internal static class HashtableExtensions\r\n    {\r\n        /// <summary>\r\n        /// Convert a hashtable to a value set.\r\n        /// </summary>\r\n        /// <param name=\"hashtable\">hashtable.</param>\r\n        /// <returns>Value set.</returns>\r\n        public static ValueSet ToValueSet(this Hashtable hashtable)\r\n        {\r\n            var valueSet = new ValueSet();\r\n\r\n            foreach (DictionaryEntry entry in hashtable)\r\n            {\r\n                if (entry.Key is string key)\r\n                {\r\n                    if (entry.Value is null)\r\n                    {\r\n                        valueSet.Add(key, null);\r\n                    }\r\n                    else\r\n                    {\r\n                        var value = TypeHelpers.GetCompatibleValueSetValueOfProperty(entry.Value.GetType(), entry.Value);\r\n                        if (value != null)\r\n                        {\r\n                            valueSet.Add(key, value);\r\n                        }\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    throw new UnitPropertyUnsupportedException(entry.Key.GetType());\r\n                }\r\n            }\r\n\r\n            return valueSet;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Extensions/JsonObjectExtensions.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"JsonObjectExtensions.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Extensions\r\n{\r\n    using System.Text.Json;\r\n    using System.Text.Json.Nodes;\r\n    using Windows.Foundation.Collections;\r\n\r\n    /// <summary>\r\n    /// Extensions for JsonObject.\r\n    /// </summary>\r\n    internal static class JsonObjectExtensions\r\n    {\r\n        /// <summary>\r\n        /// Converts the JSON object to a ValueSet.\r\n        /// </summary>\r\n        /// <param name=\"jsonObject\">The object to convert.</param>\r\n        /// <returns>The ValueSet.</returns>\r\n        public static ValueSet ToValueSet(this JsonObject? jsonObject)\r\n        {\r\n            ValueSet result = new ValueSet();\r\n\r\n            if (jsonObject != null)\r\n            {\r\n                foreach (var item in jsonObject)\r\n                {\r\n                    result.Add(item.Key, ToValue(item.Value));\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        private static object? ToValue(JsonNode? node) => node switch\r\n        {\r\n            JsonObject obj => obj.ToValueSet(),\r\n            JsonArray array => ToValueSet(array),\r\n            JsonValue value => ToValue(value),\r\n            _ => null,\r\n        };\r\n\r\n        private static ValueSet ToValueSet(JsonArray array)\r\n        {\r\n            ValueSet result = new ValueSet();\r\n            result.Add(ValueSetExtensions.TreatAsArray, true);\r\n\r\n            int index = 0;\r\n            foreach (var item in array)\r\n            {\r\n                result.Add(index.ToString(), ToValue(item));\r\n                ++index;\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        private static object? ToValue(JsonValue value) => value.GetValueKind() switch\r\n        {\r\n            JsonValueKind.Null => null,\r\n            JsonValueKind.Undefined => null,\r\n            JsonValueKind.String => value.GetValue<string>(),\r\n            JsonValueKind.Number => value.GetValue<long>(),\r\n            JsonValueKind.True => true,\r\n            JsonValueKind.False => false,\r\n            _ => throw new System.NotImplementedException(\"Unexpected default case\")\r\n        };\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Extensions/ValueSetExtensions.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ValueSetExtensions.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Extensions\r\n{\r\n    using System;\r\n    using System.Collections;\r\n    using System.Collections.Generic;\r\n    using Windows.Foundation.Collections;\r\n\r\n    /// <summary>\r\n    /// Extensions for ValueSet.\r\n    /// </summary>\r\n    internal static class ValueSetExtensions\r\n    {\r\n        /// <summary>\r\n        /// The value in a ValueSet that indicates that it is an array of items.\r\n        /// </summary>\r\n        internal const string TreatAsArray = \"treatAsArray\";\r\n\r\n        /// <summary>\r\n        /// Extension method to transform a ValueSet to a Hashtable.\r\n        /// </summary>\r\n        /// <param name=\"valueSet\">Value set.</param>\r\n        /// <returns>A hashtable.</returns>\r\n        public static Hashtable ToHashtable(this ValueSet valueSet)\r\n        {\r\n            var hashtable = new Hashtable();\r\n\r\n            foreach (var keyValuePair in valueSet)\r\n            {\r\n                if (keyValuePair.Value is ValueSet innerValueSet)\r\n                {\r\n                    if (innerValueSet.ContainsKey(TreatAsArray))\r\n                    {\r\n                        hashtable.Add(keyValuePair.Key, innerValueSet.ToArray());\r\n                    }\r\n                    else\r\n                    {\r\n                        hashtable.Add(keyValuePair.Key, innerValueSet.ToHashtable());\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    hashtable.Add(keyValuePair.Key, keyValuePair.Value);\r\n                }\r\n            }\r\n\r\n            return hashtable;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets ordered list from a ValueSet that is threated as an array.\r\n        /// </summary>\r\n        /// <param name=\"valueSet\">ValueSet.</param>\r\n        /// <returns>Ordered list.</returns>\r\n        public static IList<object> ToArray(this ValueSet valueSet)\r\n        {\r\n            if (!valueSet.ContainsKey(TreatAsArray))\r\n            {\r\n                throw new InvalidOperationException();\r\n            }\r\n\r\n            var sortedList = new SortedList<int, object>();\r\n\r\n            foreach (var keyValuePair in valueSet)\r\n            {\r\n                if (keyValuePair.Key == TreatAsArray)\r\n                {\r\n                    continue;\r\n                }\r\n\r\n                if (int.TryParse(keyValuePair.Key, out int key))\r\n                {\r\n                    if (keyValuePair.Value is ValueSet innerValueSet)\r\n                    {\r\n                        sortedList.Add(key, innerValueSet.ToHashtable());\r\n                    }\r\n                    else\r\n                    {\r\n                        sortedList.Add(key, keyValuePair.Value);\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    throw new InvalidOperationException($\"Invalid key for ValueSet to array {keyValuePair.Key}\");\r\n                }\r\n            }\r\n\r\n            return sortedList.Values;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Performs a deep compare of the ValueSets.\r\n        /// </summary>\r\n        /// <param name=\"first\">First ValueSet.</param>\r\n        /// <param name=\"second\">Second ValueSet.</param>\r\n        /// <returns>Whether the two ValueSets equal.</returns>\r\n        public static bool ContentEquals(this ValueSet first, ValueSet second)\r\n        {\r\n            if (first.Count != second.Count)\r\n            {\r\n                return false;\r\n            }\r\n\r\n            foreach (var keyValuePair in first)\r\n            {\r\n                string key = keyValuePair.Key;\r\n                if (!second.ContainsKey(key))\r\n                {\r\n                    return false;\r\n                }\r\n\r\n                var firstValue = keyValuePair.Value;\r\n                var secondValue = second[key];\r\n\r\n                // Empty value check.\r\n                if (firstValue == null && secondValue == null)\r\n                {\r\n                    continue;\r\n                }\r\n                else if (firstValue == null || secondValue == null)\r\n                {\r\n                    return false;\r\n                }\r\n\r\n                // Try as ValueSet.\r\n                var firstValueSet = firstValue as ValueSet;\r\n                var secondValueSet = secondValue as ValueSet;\r\n\r\n                if (firstValueSet != null && secondValueSet != null)\r\n                {\r\n                    if (!firstValueSet.ContentEquals(secondValueSet))\r\n                    {\r\n                        return false;\r\n                    }\r\n                    else\r\n                    {\r\n                        continue;\r\n                    }\r\n                }\r\n                else if (firstValueSet != null || secondValueSet != null)\r\n                {\r\n                    return false;\r\n                }\r\n\r\n                // Try as scalar.\r\n                if (firstValue is string firstString && secondValue is string secondString)\r\n                {\r\n                    if (firstString != secondString)\r\n                    {\r\n                        return false;\r\n                    }\r\n                }\r\n                else if (firstValue is long firstLong && secondValue is long secondLong)\r\n                {\r\n                    if (firstLong != secondLong)\r\n                    {\r\n                        return false;\r\n                    }\r\n                }\r\n                else if (firstValue is bool firstBool && secondValue is bool secondBool)\r\n                {\r\n                    if (firstBool != secondBool)\r\n                    {\r\n                        return false;\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    // Note: DateTime and float are not supported in parser yet.\r\n                    return false;\r\n                }\r\n            }\r\n\r\n            return true;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Factory/ConfigurationSetProcessorFactoryBase.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationSetProcessorFactoryBase.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Factory\r\n{\r\n    using System;\r\n    using System.Runtime.CompilerServices;\r\n    using Microsoft.Management.Configuration;\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Helpers;\r\n    using Microsoft.Management.Configuration.Processor.Set;\r\n\r\n    /// <summary>\r\n    /// IConfigurationSetProcessorFactory base implementation.\r\n    /// </summary>\r\n    internal abstract partial class ConfigurationSetProcessorFactoryBase : IDiagnosticsSink\r\n    {\r\n        private bool isCreateProcessorInvoked = false;\r\n\r\n        // Backing variables for properties that are restricted in limit mode.\r\n        private ConfigurationSet? limitationSet;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ConfigurationSetProcessorFactoryBase\"/> class.\r\n        /// </summary>\r\n        public ConfigurationSetProcessorFactoryBase()\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Diagnostics event; useful for logging and/or verbose output.\r\n        /// </summary>\r\n        public event EventHandler<IDiagnosticInformation>? Diagnostics;\r\n\r\n        /// <summary>\r\n        /// Gets or sets the minimum diagnostic level to send.\r\n        /// </summary>\r\n        public DiagnosticLevel MinimumLevel { get; set; } = DiagnosticLevel.Informational;\r\n\r\n        /// <summary>\r\n        /// Gets or sets the limitation set. Limitation set can only be set once.\r\n        /// </summary>\r\n        public ConfigurationSet? LimitationSet\r\n        {\r\n            get\r\n            {\r\n                return this.limitationSet;\r\n            }\r\n\r\n            set\r\n            {\r\n                if (this.IsLimitMode())\r\n                {\r\n                    throw new InvalidOperationException(\"Setting LimitationSet in limit mode is invalid.\");\r\n                }\r\n\r\n                this.limitationSet = value;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the configuration unit processor details for the given unit.\r\n        /// </summary>\r\n        /// <param name=\"incomingSet\">Configuration Set.</param>\r\n        /// <returns>Configuration set processor.</returns>\r\n        public IConfigurationSetProcessor CreateSetProcessor(ConfigurationSet? incomingSet)\r\n        {\r\n            try\r\n            {\r\n                bool isLimitMode = this.IsLimitMode();\r\n                this.OnDiagnostics(DiagnosticLevel.Informational, $\"The set processor factory is running in limit mode: {isLimitMode}.\");\r\n\r\n                this.CheckLimitMode();\r\n\r\n                ConfigurationSet? set = isLimitMode ? this.limitationSet : incomingSet;\r\n\r\n                this.OnDiagnostics(DiagnosticLevel.Verbose, $\"Creating set processor for `{set?.Name ?? \"<null>\"}`...\");\r\n\r\n                if (set != null && (set.Parameters.Count > 0 || set.Variables.Count > 0))\r\n                {\r\n                    this.OnDiagnostics(DiagnosticLevel.Error, $\"  Parameters/variables are not yet supported.\");\r\n                    throw new NotImplementedException();\r\n                }\r\n\r\n                IConfigurationSetProcessor result = this.CreateSetProcessorInternal(set, isLimitMode);\r\n\r\n                this.OnDiagnostics(DiagnosticLevel.Verbose, \"... done creating set processor.\");\r\n\r\n                return result;\r\n            }\r\n            catch (Exception ex)\r\n            {\r\n                this.OnDiagnostics(DiagnosticLevel.Error, ex.ToString());\r\n                throw;\r\n            }\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        void IDiagnosticsSink.OnDiagnostics(DiagnosticLevel level, string message)\r\n        {\r\n            this.OnDiagnostics(level, message);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Sends diagnostics if appropriate.\r\n        /// </summary>\r\n        /// <param name=\"level\">The level of this diagnostic message.</param>\r\n        /// <param name=\"message\">The diagnostic message.</param>\r\n        internal void OnDiagnostics(DiagnosticLevel level, string message)\r\n        {\r\n            EventHandler<IDiagnosticInformation>? diagnostics = this.Diagnostics;\r\n            if (diagnostics != null && level >= this.MinimumLevel)\r\n            {\r\n                this.InvokeDiagnostics(diagnostics, level, message);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Determines if diagnostics are enabled.\r\n        /// This allows optimizing out string construction for some cases.\r\n        /// </summary>\r\n        /// <returns>True if diagnostics are enabled; false if not.</returns>\r\n        protected bool AreDiagnosticsEnabled()\r\n        {\r\n            return this.Diagnostics != null;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the configuration unit processor details for the given unit.\r\n        /// </summary>\r\n        /// <param name=\"set\">Configuration Set.</param>\r\n        /// <param name=\"isLimitMode\">Whether the processor should be in limit mode.</param>\r\n        /// <returns>Configuration set processor.</returns>\r\n        protected abstract IConfigurationSetProcessor CreateSetProcessorInternal(ConfigurationSet? set, bool isLimitMode);\r\n\r\n        /// <summary>\r\n        /// Gets a value indicating whether the factory is operation in limit mode.\r\n        /// </summary>\r\n        /// <returns>True if the factory is in limit mode, false otherwise.</returns>\r\n        protected bool IsLimitMode()\r\n        {\r\n            return this.limitationSet != null;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Sends diagnostics to the given handler.\r\n        /// </summary>\r\n        /// <param name=\"diagnostics\">The handler to invoke.</param>\r\n        /// <param name=\"level\">The level of this diagnostic message.</param>\r\n        /// <param name=\"message\">The diagnostic message.</param>\r\n        private void InvokeDiagnostics(EventHandler<IDiagnosticInformation> diagnostics, DiagnosticLevel level, string message)\r\n        {\r\n            Helpers.DiagnosticInformation information = new ()\r\n            {\r\n                Level = level,\r\n                Message = message,\r\n            };\r\n            diagnostics.Invoke(this, information);\r\n        }\r\n\r\n        [MethodImpl(MethodImplOptions.Synchronized)]\r\n        private void CheckLimitMode()\r\n        {\r\n            if (!this.IsLimitMode())\r\n            {\r\n                return;\r\n            }\r\n\r\n            if (this.isCreateProcessorInvoked)\r\n            {\r\n                this.OnDiagnostics(DiagnosticLevel.Error, \"CreateSetProcessor is already invoked in limit mode.\");\r\n                throw new InvalidOperationException(\"CreateSetProcessor is already invoked in limit mode.\");\r\n            }\r\n            else\r\n            {\r\n                this.isCreateProcessorInvoked = true;\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Helpers/ConfigurationUnitInternal.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationUnitInternal.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Helpers\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.Diagnostics.CodeAnalysis;\r\n    using System.IO;\r\n    using Microsoft.Management.Configuration.Processor.Constants;\r\n    using Microsoft.Management.Configuration.Processor.Exceptions;\r\n    using Windows.Foundation.Collections;\r\n\r\n    /// <summary>\r\n    /// Wrapper around Configuration units and its directives.\r\n    /// Creates a normalized directives map for consumption.\r\n    /// </summary>\r\n    internal class ConfigurationUnitInternal\r\n    {\r\n        private const string ConfigRootVar = \"${WinGetConfigRoot}\";\r\n\r\n        private readonly string? configurationFileRootPath = null;\r\n        private readonly Dictionary<string, object> normalizedDirectives = new ();\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ConfigurationUnitInternal\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"unit\">Configuration unit.</param>\r\n        /// <param name=\"configurationFilePath\">The configuration file path.</param>\r\n        public ConfigurationUnitInternal(\r\n            ConfigurationUnit unit,\r\n            string? configurationFilePath)\r\n        {\r\n            this.Unit = unit;\r\n            this.InitializeDirectives();\r\n            this.InitializeNames();\r\n\r\n            if (!string.IsNullOrEmpty(configurationFilePath))\r\n            {\r\n                if (!File.Exists(configurationFilePath))\r\n                {\r\n                    throw new FileNotFoundException(configurationFilePath);\r\n                }\r\n\r\n                this.configurationFileRootPath = Path.GetDirectoryName(configurationFilePath);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the configuration unit.\r\n        /// </summary>\r\n        public ConfigurationUnit Unit { get; }\r\n\r\n        /// <summary>\r\n        /// Gets a value indicating whether the unit type should be treated as the resource name.\r\n        /// </summary>\r\n        public bool UnitTypeIsResourceName { get; init; } = false;\r\n\r\n        /// <summary>\r\n        /// Gets the resource name *only*. For example, \"Resource\".\r\n        /// </summary>\r\n        public string ResourceName { get; private set; }\r\n\r\n        /// <summary>\r\n        /// Gets the qualified name, which includes the module. For example, \"Module/Resource\".\r\n        /// </summary>\r\n        public string QualifiedName { get; private set; }\r\n\r\n        /// <summary>\r\n        /// Gets the directive value from the unit taking into account the directives overlay.\r\n        /// </summary>\r\n        /// <param name=\"directiveName\">Directive name.</param>\r\n        /// <returns>Value of directive, null if not found.</returns>\r\n        /// <typeparam name=\"TType\">Directive type value.</typeparam>\r\n        public TType? GetDirective<TType>(string directiveName)\r\n            where TType : class\r\n        {\r\n            var normalizedDirectiveName = StringHelpers.Normalize(directiveName);\r\n            if (this.normalizedDirectives.TryGetValue(normalizedDirectiveName, out object? value))\r\n            {\r\n                return value as TType;\r\n            }\r\n\r\n            return null;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the bool value of a directive from the unit taking into account the directives overlay.\r\n        /// </summary>\r\n        /// <param name=\"directiveName\">Directive name.</param>\r\n        /// <returns>Value of directive, false if not found.</returns>\r\n        public bool? GetDirective(string directiveName)\r\n        {\r\n            var normalizedDirectiveName = StringHelpers.Normalize(directiveName);\r\n            if (this.normalizedDirectives.TryGetValue(normalizedDirectiveName, out object? value))\r\n            {\r\n                return value as bool?;\r\n            }\r\n\r\n            return null;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the semantic version, if any.\r\n        /// </summary>\r\n        /// <returns>SemanticVersion, null if not specified.</returns>\r\n        public SemanticVersion? GetSemanticVersion()\r\n        {\r\n            string? semanticVersion = this.GetDirective<string>(DirectiveConstants.Version);\r\n            if (!string.IsNullOrWhiteSpace(semanticVersion))\r\n            {\r\n                return new SemanticVersion(semanticVersion);\r\n            }\r\n\r\n            return null;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the semantic min version, if any.\r\n        /// </summary>\r\n        /// <returns>SemanticVersion, null if not specified.</returns>\r\n        public SemanticVersion? GetSemanticMinVersion()\r\n        {\r\n            string? semanticVersion = this.GetDirective<string>(DirectiveConstants.MinVersion);\r\n            if (!string.IsNullOrWhiteSpace(semanticVersion))\r\n            {\r\n                return new SemanticVersion(semanticVersion);\r\n            }\r\n\r\n            return null;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the semantic max version, if any.\r\n        /// </summary>\r\n        /// <returns>SemanticVersion, null if not specified.</returns>\r\n        public SemanticVersion? GetSemanticMaxVersion()\r\n        {\r\n            string? semanticVersion = this.GetDirective<string>(DirectiveConstants.MaxVersion);\r\n            if (!string.IsNullOrWhiteSpace(semanticVersion))\r\n            {\r\n                return new SemanticVersion(semanticVersion);\r\n            }\r\n\r\n            return null;\r\n        }\r\n\r\n        /// <summary>\r\n        /// TODO: Implement for more variables.\r\n        /// I am so sad because rs.SessionStateProxy.InvokeCommand.ExpandString doesn't work as I wanted.\r\n        /// PowerShell assumes all code passed to ExpandString is trusted and we cannot assume that.\r\n        /// </summary>\r\n        /// <returns>ValueSet with settings.</returns>\r\n        public ValueSet GetExpandedSettings()\r\n        {\r\n            var valueSet = new ValueSet();\r\n            foreach (var value in this.Unit.Settings)\r\n            {\r\n                if (value.Value is string)\r\n                {\r\n                    // For now, we just expand config root.\r\n                    valueSet.Add(value.Key, this.ExpandConfigRoot(value.Value as string, value.Key));\r\n                }\r\n                else\r\n                {\r\n                    valueSet.Add(value);\r\n                }\r\n            }\r\n\r\n            return valueSet;\r\n        }\r\n\r\n        private string? ExpandConfigRoot(string? value, string settingName)\r\n        {\r\n            if (!string.IsNullOrEmpty(value))\r\n            {\r\n                // TODO: since we only support one variable, this only finds and replace\r\n                // ${WingetConfigRoot} if found in the string when the work of expanding\r\n                // string is done it should take into account other operators like the subexpression operator $()\r\n                if (value.Contains(ConfigRootVar, StringComparison.OrdinalIgnoreCase))\r\n                {\r\n                    if (string.IsNullOrEmpty(this.configurationFileRootPath))\r\n                    {\r\n                        throw new UnitSettingConfigRootException(this.QualifiedName, settingName);\r\n                    }\r\n\r\n                    return value.Replace(ConfigRootVar, this.configurationFileRootPath, StringComparison.OrdinalIgnoreCase);\r\n                }\r\n            }\r\n\r\n            return value;\r\n        }\r\n\r\n        private void InitializeDirectives()\r\n        {\r\n            foreach (var directive in this.Unit.Metadata)\r\n            {\r\n                var normalizedKey = StringHelpers.Normalize(directive.Key);\r\n                this.normalizedDirectives.Add(normalizedKey, directive.Value);\r\n            }\r\n        }\r\n\r\n        private string ConstructQualifiedName(string? moduleName)\r\n        {\r\n            return $\"{(moduleName == null ? string.Empty : $\"{moduleName}/\")}{this.ResourceName}\";\r\n        }\r\n\r\n        [MemberNotNull(nameof(ResourceName), nameof(QualifiedName))]\r\n        private void InitializeNames()\r\n        {\r\n            // Determine ResourceName, QualifiedName, and the module directive\r\n            string unitType = this.Unit.Type;\r\n            string? moduleDirective = this.GetDirective<string>(DirectiveConstants.Module);\r\n\r\n            if (this.UnitTypeIsResourceName)\r\n            {\r\n                this.ResourceName = unitType;\r\n                this.QualifiedName = this.ConstructQualifiedName(moduleDirective);\r\n                return;\r\n            }\r\n\r\n            int unitTypeDividerPosition = unitType.IndexOf('/');\r\n\r\n            if (unitTypeDividerPosition == unitType.Length - 1)\r\n            {\r\n                throw new ArgumentException($\"Invalid unit Type: {unitType}\");\r\n            }\r\n\r\n            string? moduleName;\r\n\r\n            if (unitTypeDividerPosition == -1)\r\n            {\r\n                moduleName = moduleDirective;\r\n                this.ResourceName = unitType;\r\n                this.QualifiedName = this.ConstructQualifiedName(moduleDirective);\r\n            }\r\n            else\r\n            {\r\n                moduleName = unitType.Substring(0, unitTypeDividerPosition);\r\n                this.ResourceName = unitType.Substring(unitTypeDividerPosition + 1);\r\n                this.QualifiedName = unitType;\r\n            }\r\n\r\n            if (moduleName != null)\r\n            {\r\n                if (moduleDirective != null)\r\n                {\r\n                    if (moduleName != moduleDirective)\r\n                    {\r\n                        throw new ArgumentException($\"Mismatched module specifiers: {moduleName} != {moduleDirective}\");\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    this.normalizedDirectives.Add(DirectiveConstants.Module, moduleName);\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Helpers/DiagnosticInformation.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"DiagnosticInformation.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Helpers\r\n{\r\n    using System;\r\n    using Microsoft.Management.Configuration;\r\n\r\n    /// <summary>\r\n    /// Implements IDiagnosticInformation.\r\n    /// </summary>\r\n    internal sealed partial class DiagnosticInformation : IDiagnosticInformation\r\n    {\r\n        /// <inheritdoc/>\r\n        public DiagnosticLevel Level { get; internal set; }\r\n\r\n        /// <inheritdoc/>\r\n        public string? Message { get; internal set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Helpers/SemanticVersion.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"SemanticVersion.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Helpers\r\n{\r\n    using System;\r\n\r\n    /// <summary>\r\n    /// A semantic version.\r\n    /// </summary>\r\n    internal class SemanticVersion\r\n    {\r\n        private const string MaxRange = \"999999999\";\r\n\r\n        private readonly string semanticVersion;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"SemanticVersion\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"version\">Version.</param>\r\n        public SemanticVersion(string version)\r\n        {\r\n            this.semanticVersion = GetMaximumVersion(version);\r\n\r\n            // Prerelease versions append the prerelease tag after a -\r\n            // PowerShell doesn't handle semantic versions.\r\n            if (this.semanticVersion.Contains(\"-\"))\r\n            {\r\n                var indexOf = this.semanticVersion.IndexOf(\"-\");\r\n                this.Version = new Version(this.semanticVersion[..indexOf]);\r\n                this.PrereleaseTag = this.semanticVersion[(indexOf + 1) ..];\r\n            }\r\n            else\r\n            {\r\n                this.Version = new Version(this.semanticVersion);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the version without a prerelease tag.\r\n        /// </summary>\r\n        public Version Version { get; }\r\n\r\n        /// <summary>\r\n        /// Gets prerelease tag if any.\r\n        /// </summary>\r\n        public string? PrereleaseTag { get; } = null;\r\n\r\n        /// <summary>\r\n        /// Gets a value indicating whether if the semantic version is prerelease.\r\n        /// </summary>\r\n        public bool IsPrerelease => !string.IsNullOrEmpty(this.PrereleaseTag);\r\n\r\n        /// <inheritdoc/>\r\n        public override string ToString()\r\n        {\r\n            return this.semanticVersion;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Max out a version by replacing * if needed.\r\n        /// </summary>\r\n        /// <param name=\"version\">Version.</param>\r\n        /// <returns>Maxed version.</returns>\r\n        private static string GetMaximumVersion(string version)\r\n        {\r\n            return version.Replace(\"*\", MaxRange);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Helpers/StringHelpers.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"StringHelpers.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Helpers\r\n{\r\n    /// <summary>\r\n    /// String helpers.\r\n    /// </summary>\r\n    internal static class StringHelpers\r\n    {\r\n        /// <summary>\r\n        /// Normalize string.\r\n        /// </summary>\r\n        /// <param name=\"value\">Value.</param>\r\n        /// <returns>Normalized string.</returns>\r\n        public static string Normalize(string value)\r\n        {\r\n            return value.ToLowerInvariant();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Helpers/TypeHelpers.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"TypeHelpers.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Helpers\r\n{\r\n    using System;\r\n    using System.Collections;\r\n    using System.Collections.Generic;\r\n    using System.Reflection;\r\n    using Microsoft.Management.Configuration.Processor.Exceptions;\r\n    using Microsoft.Management.Configuration.Processor.Extensions;\r\n    using Microsoft.Management.Configuration.SetProcessorFactory;\r\n    using Windows.Foundation.Collections;\r\n\r\n    /// <summary>\r\n    /// Type helpers.\r\n    /// </summary>\r\n    internal static class TypeHelpers\r\n    {\r\n        /// <summary>\r\n        /// Verifies a property exists.\r\n        /// </summary>\r\n        /// <param name=\"obj\">Dynamic object.</param>\r\n        /// <param name=\"name\">Name of property.</param>\r\n        /// <returns>True if property exists.</returns>\r\n        public static bool PropertyExists(dynamic obj, string name)\r\n        {\r\n            return obj.GetType().GetProperty(name) is not null;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies a property exists with the specified type.\r\n        /// </summary>\r\n        /// <typeparam name=\"TType\">Expected type.</typeparam>\r\n        /// <param name=\"obj\">Dynamic object.</param>\r\n        /// <param name=\"name\">Name of property.</param>\r\n        /// <returns>True if property and is of the specified type.</returns>\r\n        public static bool PropertyWithTypeExists<TType>(dynamic obj, string name)\r\n        {\r\n            return PropertyExists(obj, name) &&\r\n                   obj.GetType().GetProperty(name).PropertyType == typeof(TType);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies the property exist and is an enum.\r\n        /// </summary>\r\n        /// <param name=\"obj\">Dynamic object.</param>\r\n        /// <param name=\"name\">Name of property.</param>\r\n        /// <returns>True if property exists and is an enum.</returns>\r\n        public static bool PropertyExistsAndIsEnum(dynamic obj, string name)\r\n        {\r\n            return PropertyExists(obj, name) &&\r\n                   obj.GetType().GetProperty(name).PropertyType.IsEnum;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies the property exists and is a list. Use this when you don't know the type of the List.\r\n        /// </summary>\r\n        /// <param name=\"obj\">Dynamic object.</param>\r\n        /// <param name=\"name\">Name of property.</param>\r\n        /// <returns>True if property exists and is a list.</returns>\r\n        public static bool PropertyExistsAndIsList(dynamic obj, string name)\r\n        {\r\n            return PropertyExists(obj, name) &&\r\n                   obj.GetType().GetProperty(name).PropertyType.IsGenericType &&\r\n                   obj.GetType().GetProperty(name).PropertyType.GetGenericTypeDefinition() == typeof(List<>);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets all the properties and values from an object.\r\n        /// </summary>\r\n        /// <param name=\"obj\">Object.</param>\r\n        /// <returns>ValueSet with properties names and values.</returns>\r\n        public static ValueSet GetAllPropertiesValues(object obj)\r\n        {\r\n            var result = new ValueSet();\r\n            foreach (PropertyInfo property in obj.GetType().GetProperties())\r\n            {\r\n                var key = property.Name;\r\n                var value = GetCompatibleValueSetValueOfProperty(property.PropertyType, property.GetValue(obj));\r\n                result.Add(key, value);\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets a compatible type for a ValueSet value.\r\n        /// </summary>\r\n        /// <param name=\"type\">Type.</param>\r\n        /// <param name=\"value\">Value.</param>\r\n        /// <returns>Value converted to a compatible type.</returns>\r\n        public static object? GetCompatibleValueSetValueOfProperty(Type type, object? value)\r\n        {\r\n            if (value == null)\r\n            {\r\n                return null;\r\n            }\r\n\r\n            // Specialize here.\r\n            if (type.IsEnum)\r\n            {\r\n                return value.ToString();\r\n            }\r\n            else if (type == typeof(Hashtable))\r\n            {\r\n                Hashtable hashtable = (Hashtable)value;\r\n                return hashtable.ToValueSet();\r\n            }\r\n            else if (type.IsArray)\r\n            {\r\n                var valueSetArray = new ValueSet();\r\n                int index = 0;\r\n                foreach (object arrayObj in (Array)value)\r\n                {\r\n                    var arrayValue = GetCompatibleValueSetValueOfProperty(arrayObj.GetType(), arrayObj);\r\n                    if (arrayValue != null)\r\n                    {\r\n                        valueSetArray.Add(index.ToString(), arrayValue);\r\n                        index++;\r\n                    }\r\n                }\r\n\r\n                if (valueSetArray.Count > 0)\r\n                {\r\n                    valueSetArray.Add(\"treatAsArray\", true);\r\n                }\r\n\r\n                return valueSetArray;\r\n            }\r\n            else if (type == typeof(string))\r\n            {\r\n                // Ignore empty strings.\r\n                string propertyString = (string)value;\r\n                if (!string.IsNullOrEmpty(propertyString))\r\n                {\r\n                    return propertyString;\r\n                }\r\n                else\r\n                {\r\n                    return null;\r\n                }\r\n            }\r\n            else if (type.IsValueType)\r\n            {\r\n                return value;\r\n            }\r\n\r\n            // This might be too restrictive but anything else is going to be some object that we don't support anyway.\r\n            throw new UnitPropertyUnsupportedException(value.GetType());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Converts PowerShellConfigurationProcessorPolicy string value to PwshConfigurationProcessorPolicy.\r\n        /// </summary>\r\n        /// <param name=\"value\">PowerShellConfigurationProcessorPolicy value.</param>\r\n        /// <returns>PwshConfigurationProcessorPolicy.</returns>\r\n        public static PwshConfigurationProcessorPolicy ToPwshConfigurationProcessorPolicy(PowerShellConfigurationProcessorPolicy value)\r\n        {\r\n            return value switch\r\n            {\r\n                PowerShellConfigurationProcessorPolicy.Unrestricted => PwshConfigurationProcessorPolicy.Unrestricted,\r\n                PowerShellConfigurationProcessorPolicy.RemoteSigned => PwshConfigurationProcessorPolicy.RemoteSigned,\r\n                PowerShellConfigurationProcessorPolicy.AllSigned => PwshConfigurationProcessorPolicy.AllSigned,\r\n                PowerShellConfigurationProcessorPolicy.Restricted => PwshConfigurationProcessorPolicy.Restricted,\r\n                PowerShellConfigurationProcessorPolicy.Bypass => PwshConfigurationProcessorPolicy.Bypass,\r\n                PowerShellConfigurationProcessorPolicy.Undefined => PwshConfigurationProcessorPolicy.Undefined,\r\n                _ => throw new InvalidOperationException(),\r\n            };\r\n        }\r\n\r\n        /// <summary>\r\n        /// Converts PwshConfigurationProcessorPolicy string value to PowerShellConfigurationProcessorPolicy.\r\n        /// </summary>\r\n        /// <param name=\"value\">PwshConfigurationProcessorPolicy value.</param>\r\n        /// <returns>PowerShellConfigurationProcessorPolicy.</returns>\r\n        public static PowerShellConfigurationProcessorPolicy ToPowerShellConfigurationProcessorPolicy(PwshConfigurationProcessorPolicy value)\r\n        {\r\n            return value switch\r\n            {\r\n                PwshConfigurationProcessorPolicy.Unrestricted => PowerShellConfigurationProcessorPolicy.Unrestricted,\r\n                PwshConfigurationProcessorPolicy.RemoteSigned => PowerShellConfigurationProcessorPolicy.RemoteSigned,\r\n                PwshConfigurationProcessorPolicy.AllSigned => PowerShellConfigurationProcessorPolicy.AllSigned,\r\n                PwshConfigurationProcessorPolicy.Restricted => PowerShellConfigurationProcessorPolicy.Restricted,\r\n                PwshConfigurationProcessorPolicy.Bypass => PowerShellConfigurationProcessorPolicy.Bypass,\r\n                PwshConfigurationProcessorPolicy.Undefined => PowerShellConfigurationProcessorPolicy.Undefined,\r\n                _ => throw new InvalidOperationException(),\r\n            };\r\n        }\r\n\r\n        /// <summary>\r\n        /// Converts PowerShellConfigurationProcessorLocation string value to PwshConfigurationProcessorLocation.\r\n        /// </summary>\r\n        /// <param name=\"value\">PowerShellConfigurationProcessorLocation value.</param>\r\n        /// <returns>PwshConfigurationProcessorLocation.</returns>\r\n        public static PwshConfigurationProcessorLocation ToPwshConfigurationProcessorLocation(PowerShellConfigurationProcessorLocation value)\r\n        {\r\n            return value switch\r\n            {\r\n                PowerShellConfigurationProcessorLocation.CurrentUser => PwshConfigurationProcessorLocation.CurrentUser,\r\n                PowerShellConfigurationProcessorLocation.AllUsers => PwshConfigurationProcessorLocation.AllUsers,\r\n                PowerShellConfigurationProcessorLocation.WinGetModulePath => PwshConfigurationProcessorLocation.WinGetModulePath,\r\n                PowerShellConfigurationProcessorLocation.Custom => PwshConfigurationProcessorLocation.Custom,\r\n                _ => throw new InvalidOperationException(),\r\n            };\r\n        }\r\n\r\n        /// <summary>\r\n        /// Converts PwshConfigurationProcessorLocation string value to PowerShellConfigurationProcessorLocation.\r\n        /// </summary>\r\n        /// <param name=\"value\">PwshConfigurationProcessorLocation value.</param>\r\n        /// <returns>PowerShellConfigurationProcessorLocation.</returns>\r\n        public static PowerShellConfigurationProcessorLocation ToPowerShellConfigurationProcessorLocation(PwshConfigurationProcessorLocation value)\r\n        {\r\n            return value switch\r\n            {\r\n                PwshConfigurationProcessorLocation.CurrentUser => PowerShellConfigurationProcessorLocation.CurrentUser,\r\n                PwshConfigurationProcessorLocation.AllUsers => PowerShellConfigurationProcessorLocation.AllUsers,\r\n                PwshConfigurationProcessorLocation.WinGetModulePath => PowerShellConfigurationProcessorLocation.WinGetModulePath,\r\n                PwshConfigurationProcessorLocation.Custom => PowerShellConfigurationProcessorLocation.Custom,\r\n                _ => throw new InvalidOperationException(),\r\n            };\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Microsoft.Management.Configuration.Processor.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <DotNetVersion>net8.0</DotNetVersion>\r\n    <!-- Keep in sync with attributes in AssemblyInfo.cs -->\r\n    <TargetFramework>$(DotNetVersion)-windows10.0.26100.0</TargetFramework>\r\n    <Nullable>enable</Nullable>\r\n    <!-- Keep in sync with attributes in AssemblyInfo.cs -->\r\n    <SupportedOSPlatformVersion>10.0.17763.0</SupportedOSPlatformVersion>\r\n    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>\r\n    <Platform>AnyCpu</Platform>\r\n    <RuntimeIdentifier>win</RuntimeIdentifier>\r\n    <OutputPath>$(SolutionDir)$(Platform)\\$(Configuration)\\$(MSBuildProjectName)\\</OutputPath>\r\n    <GenerateDocumentationFile>true</GenerateDocumentationFile>\r\n    <!-- Workaround for MSB3271 error on processor architecture mismatch -->\r\n    <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>\r\n    <!-- Disable warning CS1591 for cswinrt auto-generated files and CS8785 for SourceGenerator compilation errors -->\r\n    <NoWarn>1591,8785</NoWarn>\r\n    <Configurations>Debug;Release;ReleaseStatic</Configurations>\r\n    <CsWinRTEnableLogging>true</CsWinRTEnableLogging>\r\n    <WinGetCsWinRTEmbedded Condition=\"'$(WinGetCsWinRTEmbedded)'==''\">true</WinGetCsWinRTEmbedded>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Release'\">\r\n    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='ReleaseStatic'\">\r\n    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup>\r\n    <CsWinRTComponent>true</CsWinRTComponent>\r\n    <CsWinRTWindowsMetadata>10.0.26100.0</CsWinRTWindowsMetadata>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <AdditionalFiles Include=\"..\\stylecop.json\" Link=\"stylecop.json\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <PackageReference Include=\"Microsoft.Windows.CsWinRT\" />\r\n    <PackageReference Include=\"Microsoft.PowerShell.SDK\" GeneratePathProperty=\"true\">\r\n      <ExcludeAssets>contentFiles</ExcludeAssets>\r\n    </PackageReference>\r\n    <PackageReference Include=\"Newtonsoft.Json\" />\r\n    <PackageReference Include=\"StyleCop.Analyzers\">\r\n      <PrivateAssets>all</PrivateAssets>\r\n    </PackageReference>\r\n    <PackageReference Include=\"System.Data.SqlClient\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup Condition=\"'$(WinGetCsWinRTEmbedded)'!='true'\">\r\n    <ProjectReference Include=\"..\\Microsoft.Management.Configuration.Projection\\Microsoft.Management.Configuration.Projection.csproj\">\r\n      <OutputItemType>Content</OutputItemType>\r\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\r\n      <ReferenceOutputAssembly>True</ReferenceOutputAssembly>\r\n    </ProjectReference>\r\n  </ItemGroup>\r\n\r\n  <ItemGroup Condition=\"'$(WinGetCsWinRTEmbedded)'=='true'\">\r\n    <ProjectReference Include=\"..\\Microsoft.Management.Configuration\\Microsoft.Management.Configuration.vcxproj\">\r\n      <OutputItemType>Content</OutputItemType>\r\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\r\n    </ProjectReference>\r\n  </ItemGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(WinGetCsWinRTEmbedded)'=='true'\">\r\n    <DefineConstants>$(DefineConstants);WinGetCsWinRTEmbedded</DefineConstants>\r\n    <CsWinRTComponent>false</CsWinRTComponent>\r\n    <CsWinRTIncludes>\r\n      Microsoft.Management.Configuration;\r\n      Windows.ApplicationModel.AppDisplayInf;\r\n      Windows.ApplicationModel.IAppDisplayInf;\r\n      Windows.ApplicationModel.AppExecutionContex;\r\n      Windows.ApplicationModel.IAppExecutionContex;\r\n      Windows.ApplicationModel.AppInf;\r\n      Windows.ApplicationModel.IAppInf;\r\n      Windows.ApplicationModel.AppInstallerInf;\r\n      Windows.ApplicationModel.IAppInstallerInf;\r\n      Windows.ApplicationModel.AppInstallerPolicySourc;\r\n      Windows.ApplicationModel.AddResourcePackageOption;\r\n      Windows.ApplicationModel.IAddResourcePackageOption;\r\n      Windows.ApplicationModel.FindRelatedPackagesOption;\r\n      Windows.ApplicationModel.IFindRelatedPackagesOption;\r\n      Windows.ApplicationModel.Packag;\r\n      Windows.ApplicationModel.IPackag;\r\n      Windows.ApplicationModel.Core.AppListEntr;\r\n      Windows.ApplicationModel.Core.IAppListEntr;\r\n      Windows.Data.Text.TextSegmen;\r\n      Windows.Management.Deployment;\r\n      Windows.Devices.Geolocation;\r\n      Windows.Foundation;\r\n      Windows.Globalization.DayOfWee;\r\n      Windows.Networking.Connectivity;\r\n      Windows.Networking.DomainNameTyp;\r\n      Windows.Networking.EndpointPai;\r\n      Windows.Networking.IEndpointPai;\r\n      Windows.Networking.HostNam;\r\n      Windows.Networking.IHostNam;\r\n      Windows.Security.Cryptography.Certificates;\r\n      Windows.Storage;\r\n      Windows.Storage.Provider.FileUpdateStatu;\r\n      Windows.System.ProcessorArchitectur;\r\n      Windows.System.Use;\r\n      Windows.System.IUse;\r\n    </CsWinRTIncludes>\r\n    <CsWinRTExcludes>\r\n      Windows.Foundation.PropertyType;\r\n      Windows.Storage.Provider;\r\n    </CsWinRTExcludes>\r\n    <!-- Ensure Support for Windows 10, Version 1809 -->\r\n    <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>\r\n  </PropertyGroup>\r\n\r\n  <Import Project=\"..\\targets\\EmbeddedCsWinRT.targets\" Condition=\"'$(WinGetCsWinRTEmbedded)'=='true'\" />\r\n\r\n  <Target Name=\"MicrosoftManagementConfigurationPathTarget\" BeforeTargets=\"CsWinRTSetAuthoringWinMDs\">\r\n    <PropertyGroup>\r\n      <MicrosoftManagementConfigurationPath>$(OutputPath)..\\Microsoft.Management.Configuration\\Microsoft.Management.Configuration.winmd</MicrosoftManagementConfigurationPath>\r\n      <MicrosoftManagementConfigurationPath Condition=\"!Exists('$(MicrosoftManagementConfigurationPath)')\">$(SolutionDir)x64\\$(Configuration)\\Microsoft.Management.Configuration\\Microsoft.Management.Configuration.winmd</MicrosoftManagementConfigurationPath>\r\n      <MicrosoftManagementConfigurationPath Condition=\"!Exists('$(MicrosoftManagementConfigurationPath)')\">$(SolutionDir)x86\\$(Configuration)\\Microsoft.Management.Configuration\\Microsoft.Management.Configuration.winmd</MicrosoftManagementConfigurationPath>\r\n      <MicrosoftManagementConfigurationPath Condition=\"!Exists('$(MicrosoftManagementConfigurationPath)')\">$(SolutionDir)arm64\\$(Configuration)\\Microsoft.Management.Configuration\\Microsoft.Management.Configuration.winmd</MicrosoftManagementConfigurationPath>\r\n    </PropertyGroup>\r\n\r\n    <Message Importance=\"normal\" Text=\"Microsoft.Management.Configuration.winmd -&gt; $(MicrosoftManagementConfigurationPath)\" />\r\n    <Error Condition=\"!Exists('$(MicrosoftManagementConfigurationPath)')\" Text=\"Microsoft.Management.Configuration.winmd was not found\" />\r\n    <ItemGroup Condition=\"Exists('$(MicrosoftManagementConfigurationPath)')\">\r\n      <CsWinRTAuthoringWinMDs Include=\"$(MicrosoftManagementConfigurationPath)\" />\r\n    </ItemGroup>\r\n  </Target>\r\n\r\n  <Target Name=\"PwshFiles\" AfterTargets=\"AfterBuild\">\r\n    <ItemGroup>\r\n      <RefFiles Include=\"$(PkgMicrosoft_PowerShell_SDK)\\contentFiles\\any\\any\\ref\\*.*\" />\r\n      <WinModuleFiles Include=\"$(PkgMicrosoft_PowerShell_SDK)\\contentFiles\\any\\any\\runtimes\\win\\lib\\$(DotNetVersion)\\Modules\\**\\*.*\" />\r\n    </ItemGroup>\r\n    <Copy SourceFiles=\"@(RefFiles)\" DestinationFolder=\"$(OutputPath)\\ref\\\" />\r\n    <Copy SourceFiles=\"@(WinModuleFiles)\" DestinationFolder=\"$(OutputPath)\\Modules\\%(RecursiveDir)\\\" />\r\n  </Target>\r\n\r\n</Project>"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/PowerShell/Constants/PowerShellConstants.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"PowerShellConstants.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.PowerShell.Constants\r\n{\r\n    /// <summary>\r\n    /// Constants related to PowerShell.\r\n    /// </summary>\r\n    internal static class PowerShellConstants\r\n    {\r\n#pragma warning disable SA1600 // ElementsMustBeDocumented\r\n        public const string Core = \"Core\";\r\n\r\n        internal static class Variables\r\n        {\r\n            public const string PSEdition = \"PSEdition\";\r\n            public const string Error = \"Error\";\r\n            public const string PSModulePath = \"env:PSModulePath\";\r\n        }\r\n\r\n        internal static class Modules\r\n        {\r\n            public const string PSDesiredStateConfiguration = \"PSDesiredStateConfiguration\";\r\n            public const string PSDesiredStateConfigurationMinVersion = \"2.0.7\";\r\n            public const string PowerShellGet = \"PowerShellGet\";\r\n            public const string PowerShellGetMinVersion = \"2.2.5\";\r\n            public const string PSDesiredStateConfigurationMaxVersion = \"2.*\";\r\n        }\r\n\r\n        internal static class Commands\r\n        {\r\n            public const string FindDscResource = \"Find-DscResource\";\r\n            public const string GetAuthenticodeSignature = \"Get-AuthenticodeSignature\";\r\n            public const string GetChildItem = \"Get-ChildItem\";\r\n            public const string GetCommand = \"Get-Command\";\r\n            public const string GetDscResource = \"Get-DscResource\";\r\n            public const string GetInstalledModule = \"Get-InstalledModule\";\r\n            public const string GetModule = \"Get-Module\";\r\n            public const string ImportModule = \"Import-Module\";\r\n            public const string InstallModule = \"Install-Module\";\r\n            public const string InvokeDscResource = \"Invoke-DscResource\";\r\n            public const string SaveModule = \"Save-Module\";\r\n            public const string FindModule = \"Find-Module\";\r\n            public const string ImportCliXml = \"Import-CliXml\";\r\n        }\r\n\r\n        internal static class Parameters\r\n        {\r\n            public const string AllowPrerelease = \"AllowPrerelease\";\r\n            public const string Force = \"Force\";\r\n            public const string FullyQualifiedName = \"FullyQualifiedName\";\r\n            public const string Guid = \"GUID\";\r\n            public const string InputObject = \"InputObject\";\r\n            public const string ListAvailable = \"ListAvailable\";\r\n            public const string MaximumVersion = \"MaximumVersion\";\r\n            public const string Method = \"Method\";\r\n            public const string MinimumVersion = \"MinimumVersion\";\r\n            public const string Module = \"Module\";\r\n            public const string ModuleName = \"ModuleName\";\r\n            public const string ModuleVersion = \"ModuleVersion\";\r\n            public const string Name = \"Name\";\r\n            public const string Path = \"Path\";\r\n            public const string Property = \"Property\";\r\n            public const string Recurse = \"Recurse\";\r\n            public const string Repository = \"Repository\";\r\n            public const string RequiredVersion = \"RequiredVersion\";\r\n            public const string Scope = \"Scope\";\r\n        }\r\n\r\n        internal static class DscMethods\r\n        {\r\n            public const string Get = \"Get\";\r\n            public const string Set = \"Set\";\r\n            public const string Test = \"Test\";\r\n        }\r\n#pragma warning restore SA1600 // ElementsMustBeDocumented\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/PowerShell/DscModules/DscModuleV2.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"DscModuleV2.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.PowerShell.DscModules\r\n{\r\n    using System;\r\n    using System.Collections;\r\n    using System.Collections.Generic;\r\n    using System.Collections.ObjectModel;\r\n    using System.Linq;\r\n    using System.Management.Automation;\r\n    using Microsoft.Management.Configuration.Processor.Exceptions;\r\n    using Microsoft.Management.Configuration.Processor.Extensions;\r\n    using Microsoft.Management.Configuration.Processor.Helpers;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.DscResourcesInfo;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.Extensions;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.Helpers;\r\n    using Microsoft.PowerShell.Commands;\r\n    using Windows.Foundation.Collections;\r\n    using static Microsoft.Management.Configuration.Processor.PowerShell.Constants.PowerShellConstants;\r\n\r\n    /// <summary>\r\n    /// PSDesiredStateConfiguration v2.\r\n    /// </summary>\r\n    internal class DscModuleV2 : IDscModule\r\n    {\r\n        private const string InDesiredState = \"InDesiredState\";\r\n        private const string RebootRequired = \"RebootRequired\";\r\n\r\n        private static readonly IEnumerable<string> ExclusionResourcesParentPath = new string[]\r\n        {\r\n            @\"C:\\WINDOWS\\system32\\WindowsPowershell\\v1.0\\Modules\\PsDesiredStateConfiguration\\DscResources\",\r\n            @\"C:\\Program Files\\WindowsPowerShell\\Modules\\PackageManagement\\1.0.0.1\",\r\n        };\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"DscModuleV2\"/> class.\r\n        /// </summary>\r\n        public DscModuleV2()\r\n        {\r\n            this.ModuleSpecification = PowerShellHelpers.CreateModuleSpecification(\r\n                Modules.PSDesiredStateConfiguration,\r\n                minVersion: Modules.PSDesiredStateConfigurationMinVersion,\r\n                maxVersion: Modules.PSDesiredStateConfigurationMaxVersion);\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public ModuleSpecification ModuleSpecification { get; private init; }\r\n\r\n        /// <inheritdoc/>\r\n        public string GetDscResourceCmd { get; } = Commands.GetDscResource;\r\n\r\n        /// <inheritdoc/>\r\n        public string InvokeDscResourceCmd { get; } = Commands.InvokeDscResource;\r\n\r\n        /// <inheritdoc/>\r\n        public IReadOnlyList<DscResourceInfoInternal> GetAllDscResources(PowerShell pwsh)\r\n        {\r\n            return this.GetDscResources(pwsh, null, null);\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public IReadOnlyList<DscResourceInfoInternal> GetDscResourcesInModule(\r\n            PowerShell pwsh,\r\n            ModuleSpecification moduleSpecification)\r\n        {\r\n            return this.GetDscResources(pwsh, null, moduleSpecification);\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public DscResourceInfoInternal? GetDscResource(\r\n            PowerShell pwsh,\r\n            string name,\r\n            ModuleSpecification? moduleSpecification)\r\n        {\r\n            var dscResourceInfos = this.GetDscResources(pwsh, name, moduleSpecification);\r\n\r\n            if (dscResourceInfos.Count == 0)\r\n            {\r\n                return null;\r\n            }\r\n            else if (dscResourceInfos.Count > 1)\r\n            {\r\n                throw new GetDscResourceMultipleMatches(name, moduleSpecification);\r\n            }\r\n\r\n            return dscResourceInfos[0];\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public ValueSet InvokeGetResource(\r\n            PowerShell pwsh,\r\n            ValueSet settings,\r\n            string name,\r\n            ModuleSpecification? moduleSpecification)\r\n        {\r\n            PSObject? getResult = null;\r\n\r\n            try\r\n            {\r\n                getResult = pwsh.AddCommand(this.InvokeDscResourceCmd)\r\n                                .AddParameters(PrepareInvokeParameters(name, settings, moduleSpecification))\r\n                                .AddParameter(Parameters.Method, DscMethods.Get)\r\n                                .InvokeAndStopOnError()\r\n                                .FirstOrDefault();\r\n            }\r\n            catch (Exception ex)\r\n            {\r\n                throw new InvokeDscResourceException(InvokeDscResourceException.Get, name, moduleSpecification, ex);\r\n            }\r\n\r\n            string? errorMessage = pwsh.GetErrorMessage();\r\n            if (errorMessage is not null)\r\n            {\r\n                throw new InvokeDscResourceException(InvokeDscResourceException.Get, name, moduleSpecification, errorMessage);\r\n            }\r\n\r\n            if (getResult is null)\r\n            {\r\n                throw new InvokeDscResourceException(InvokeDscResourceException.Get, name, moduleSpecification);\r\n            }\r\n\r\n            // Script based resource.\r\n            if (getResult.BaseObject is Hashtable)\r\n            {\r\n                Hashtable hashTable = (Hashtable)getResult.BaseObject;\r\n                var resultSettings = new ValueSet();\r\n                foreach (DictionaryEntry entry in hashTable)\r\n                {\r\n                    resultSettings.Add(entry.Key as string, entry.Value);\r\n                }\r\n\r\n                return resultSettings;\r\n            }\r\n\r\n            // Class-based resource.\r\n            return TypeHelpers.GetAllPropertiesValues(getResult.BaseObject);\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public bool InvokeTestResource(\r\n            PowerShell pwsh,\r\n            ValueSet settings,\r\n            string name,\r\n            ModuleSpecification? moduleSpecification)\r\n        {\r\n            // Returned type is InvokeDscResourceTestResult which is a PowerShell classed defined\r\n            // in PSDesiredStateConfiguration.psm1.\r\n            dynamic? testResult = null;\r\n\r\n            try\r\n            {\r\n                testResult = pwsh.AddCommand(this.InvokeDscResourceCmd)\r\n                                 .AddParameters(PrepareInvokeParameters(name, settings, moduleSpecification))\r\n                                 .AddParameter(Parameters.Method, DscMethods.Test)\r\n                                 .InvokeAndStopOnError()\r\n                                 .FirstOrDefault();\r\n            }\r\n            catch (Exception ex)\r\n            {\r\n                throw new InvokeDscResourceException(InvokeDscResourceException.Test, name, moduleSpecification, ex);\r\n            }\r\n\r\n            string? errorMessage = pwsh.GetErrorMessage();\r\n            if (errorMessage is not null)\r\n            {\r\n                throw new InvokeDscResourceException(InvokeDscResourceException.Test, name, moduleSpecification, errorMessage);\r\n            }\r\n\r\n            if (testResult is null ||\r\n                !TypeHelpers.PropertyWithTypeExists<bool>(testResult, InDesiredState))\r\n            {\r\n                throw new InvokeDscResourceException(InvokeDscResourceException.Test, name, moduleSpecification);\r\n            }\r\n\r\n            return testResult?.InDesiredState;\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public bool InvokeSetResource(\r\n            PowerShell pwsh,\r\n            ValueSet settings,\r\n            string name,\r\n            ModuleSpecification? moduleSpecification)\r\n        {\r\n            // Returned type is InvokeDscResourceSetResult which is a PowerShell classed defined\r\n            // in PSDesiredStateConfiguration.psm1.\r\n            dynamic? setResult = null;\r\n\r\n            try\r\n            {\r\n                setResult = pwsh.AddCommand(this.InvokeDscResourceCmd)\r\n                                .AddParameters(PrepareInvokeParameters(name, settings, moduleSpecification))\r\n                                .AddParameter(Parameters.Method, DscMethods.Set)\r\n                                .InvokeAndStopOnError()\r\n                                .FirstOrDefault();\r\n            }\r\n            catch (Exception ex)\r\n            {\r\n                throw new InvokeDscResourceException(InvokeDscResourceException.Set, name, moduleSpecification, ex);\r\n            }\r\n\r\n            string? errorMessage = pwsh.GetErrorMessage();\r\n            if (errorMessage is not null)\r\n            {\r\n                throw new InvokeDscResourceException(InvokeDscResourceException.Set, name, moduleSpecification, errorMessage, pwsh.ContainsPropertyError());\r\n            }\r\n\r\n            if (setResult is null ||\r\n                !TypeHelpers.PropertyWithTypeExists<bool>(setResult, RebootRequired))\r\n            {\r\n                throw new InvokeDscResourceException(InvokeDscResourceException.Set, name, moduleSpecification);\r\n            }\r\n\r\n            return setResult?.RebootRequired;\r\n        }\r\n\r\n        private static Dictionary<string, object> PrepareInvokeParameters(\r\n            string name,\r\n            ValueSet settings,\r\n            ModuleSpecification? moduleSpecification)\r\n        {\r\n            Hashtable properties = settings.ToHashtable();\r\n\r\n            var parameters = new Dictionary<string, object>()\r\n            {\r\n                { Parameters.Name, name },\r\n                { Parameters.Property, properties },\r\n            };\r\n\r\n            if (moduleSpecification is not null)\r\n            {\r\n                parameters.Add(Parameters.ModuleName, moduleSpecification);\r\n            }\r\n\r\n            return parameters;\r\n        }\r\n\r\n        private IReadOnlyList<DscResourceInfoInternal> GetDscResources(\r\n            PowerShell pwsh,\r\n            string? name,\r\n            ModuleSpecification? moduleSpecification)\r\n        {\r\n            pwsh.AddCommand(this.GetDscResourceCmd);\r\n\r\n            if (name is not null)\r\n            {\r\n                pwsh.AddParameter(Parameters.Name, name);\r\n            }\r\n\r\n            if (moduleSpecification is not null)\r\n            {\r\n                pwsh.AddParameter(Parameters.Module, moduleSpecification);\r\n            }\r\n\r\n            try\r\n            {\r\n                var resources = pwsh.Invoke();\r\n                return this.ConvertToDscResourceInfoInternal(resources);\r\n            }\r\n            catch (RuntimeException e)\r\n            {\r\n                // Detect easily this.\r\n                if (e.ErrorRecord.FullyQualifiedErrorId == \"ExceptionWhenSetting,GetResourceFromKeyword\")\r\n                {\r\n                    throw new GetDscResourceModuleConflict(name, moduleSpecification, e);\r\n                }\r\n\r\n                throw;\r\n            }\r\n        }\r\n\r\n        private List<DscResourceInfoInternal> ConvertToDscResourceInfoInternal(Collection<PSObject> psObjects)\r\n        {\r\n            var result = new List<DscResourceInfoInternal>();\r\n            foreach (dynamic psObject in psObjects)\r\n            {\r\n                var dscResourceInfo = new DscResourceInfoInternal(psObject);\r\n\r\n                // Explicitly don't support old DSC resources from v1 PSDesiredStateConfiguration.\r\n                // Even if the Windows System32 Windows PowerShell module path is removed they\r\n                // will show up.\r\n                if (ExclusionResourcesParentPath.Any(e => dscResourceInfo.ParentPath!.StartsWith(e)))\r\n                {\r\n                    continue;\r\n                }\r\n\r\n                result.Add(dscResourceInfo);\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/PowerShell/DscModules/IDscModule.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"IDscModule.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.PowerShell.DscModules\r\n{\r\n    using System.Collections.Generic;\r\n    using System.Management.Automation;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.DscResourcesInfo;\r\n    using Microsoft.PowerShell.Commands;\r\n    using Windows.Foundation.Collections;\r\n\r\n    /// <summary>\r\n    /// Interface for defining a PSDesiredStateConfiguration module.\r\n    /// </summary>\r\n    internal interface IDscModule\r\n    {\r\n        /// <summary>\r\n        /// Gets the module specification.\r\n        /// </summary>\r\n        ModuleSpecification ModuleSpecification { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the name of the Get-DscResource Cmdlet.\r\n        /// </summary>\r\n        string GetDscResourceCmd { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the name of the Invoke-DscResource Cmdlet.\r\n        /// </summary>\r\n        string InvokeDscResourceCmd { get; }\r\n\r\n        /// <summary>\r\n        /// Gets all DSC resource.\r\n        /// </summary>\r\n        /// <param name=\"pwsh\">PowerShell.</param>\r\n        /// <returns>A list with the DSC resource.</returns>\r\n        IReadOnlyList<DscResourceInfoInternal> GetAllDscResources(PowerShell pwsh);\r\n\r\n        /// <summary>\r\n        /// Gets all resources in a module.\r\n        /// </summary>\r\n        /// <param name=\"pwsh\">PowerShell.</param>\r\n        /// <param name=\"moduleSpecification\">Module specification.</param>\r\n        /// <returns>List of resources of that module and version.</returns>\r\n        IReadOnlyList<DscResourceInfoInternal> GetDscResourcesInModule(PowerShell pwsh, ModuleSpecification moduleSpecification);\r\n\r\n        /// <summary>\r\n        /// Gets a DSC Resource.\r\n        /// </summary>\r\n        /// <param name=\"pwsh\">PowerShell.</param>\r\n        /// <param name=\"name\">Name.</param>\r\n        /// <param name=\"moduleSpecification\">Module specification.</param>\r\n        /// <returns>DSC Resource from that module and version.</returns>\r\n        DscResourceInfoInternal? GetDscResource(PowerShell pwsh, string name, ModuleSpecification? moduleSpecification);\r\n\r\n        /// <summary>\r\n        /// Calls Invoke-DscResource -Method Get from this module.\r\n        /// </summary>\r\n        /// <param name=\"pwsh\">PowerShell.</param>\r\n        /// <param name=\"settings\">Settings.</param>\r\n        /// <param name=\"name\">Name.</param>\r\n        /// <param name=\"moduleSpecification\">Module specification.</param>\r\n        /// <returns>Properties of resource.</returns>\r\n        ValueSet InvokeGetResource(PowerShell pwsh, ValueSet settings, string name, ModuleSpecification? moduleSpecification);\r\n\r\n        /// <summary>\r\n        /// Calls Invoke-DscResource -Method Test from this module.\r\n        /// </summary>\r\n        /// <param name=\"pwsh\">PowerShell.</param>\r\n        /// <param name=\"settings\">Settings.</param>\r\n        /// <param name=\"name\">Name.</param>\r\n        /// <param name=\"moduleSpecification\">Module specification.</param>\r\n        /// <returns>Is in desired state.</returns>\r\n        bool InvokeTestResource(PowerShell pwsh, ValueSet settings, string name, ModuleSpecification? moduleSpecification);\r\n\r\n        /// <summary>\r\n        /// Calls Invoke-DscResource -Method Set from this module.\r\n        /// </summary>\r\n        /// <param name=\"pwsh\">PowerShell.</param>\r\n        /// <param name=\"settings\">Settings.</param>\r\n        /// <param name=\"name\">Name.</param>\r\n        /// <param name=\"moduleSpecification\">Module specification.</param>\r\n        /// <returns>If a reboot is required.</returns>\r\n        bool InvokeSetResource(PowerShell pwsh, ValueSet settings, string name, ModuleSpecification? moduleSpecification);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/PowerShell/DscResourcesInfo/DscResourceInfoInternal.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"DscResourceInfoInternal.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.PowerShell.DscResourcesInfo\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.Management.Automation;\r\n    using Microsoft.Management.Configuration.Processor.Helpers;\r\n\r\n    /// <summary>\r\n    /// Contains a DSC resource information.\r\n    /// This object should be initialized with a Microsoft.PowerShell.DesiredStateConfiguration.DscResourceInfo.\r\n    /// That object is the result of Get-DscResource and is not the same as System.Management.Automation.DscResourceInfo.\r\n    /// The type is defined in a psd1 in the PSDesiredStateConfiguration. This file is based on that.\r\n    /// If Invoke-DscResource gets support for passing the DscResourceInfo, we could keep the original object as member\r\n    /// to then pass it in code.\r\n    /// </summary>\r\n    internal class DscResourceInfoInternal\r\n    {\r\n        private const string DscResourceInfoFullName = \"Microsoft.PowerShell.DesiredStateConfiguration.DscResourceInfo\";\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"DscResourceInfoInternal\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"info\">Dynamic object. Expected DscResourceInfo.</param>\r\n        public DscResourceInfoInternal(dynamic info)\r\n        {\r\n            if (info.GetType().FullName != DscResourceInfoFullName)\r\n            {\r\n                throw new ArgumentException();\r\n            }\r\n\r\n            this.ResourceType = info.ResourceType;\r\n            this.Name = info.Name;\r\n            this.FriendlyName = info.FriendlyName;\r\n            this.Module = info.Module;\r\n            this.Path = info.Path;\r\n            this.ParentPath = info.ParentPath;\r\n            this.ImplementedAs = Enum.Parse<ImplementedAsTypeInternal>(info.ImplementedAs.ToString());\r\n            this.CompanyName = info.CompanyName;\r\n\r\n            if (this.Module is not null)\r\n            {\r\n                this.ModuleName = this.Module.Name;\r\n                this.Version = this.Module.Version;\r\n            }\r\n\r\n            foreach (object property in info.Properties)\r\n            {\r\n                this.Properties.Add(new DscResourcePropertyInfoInternal(property));\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"DscResourceInfoInternal\"/> class.\r\n        /// Used for unit tests.\r\n        /// </summary>\r\n        /// <param name=\"name\">Resource name.</param>\r\n        /// <param name=\"moduleName\">Module name.</param>\r\n        /// <param name=\"version\">Version.</param>\r\n        internal DscResourceInfoInternal(string name, string? moduleName, Version? version)\r\n        {\r\n            this.Name = name;\r\n            this.ModuleName = moduleName;\r\n            this.Version = version;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets resource type name.\r\n        /// </summary>\r\n        public string? ResourceType { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets Name of the resource. This name is used to access the resource.\r\n        /// </summary>\r\n        public string Name { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets the normalized resource name.\r\n        /// </summary>\r\n        public string NormalizedName\r\n        {\r\n            get { return StringHelpers.Normalize(this.Name); }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets friendly name defined for the resource.\r\n        /// </summary>\r\n        public string? FriendlyName { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets module which implements the resource. This could point to parent module, if the DSC resource is implemented.\r\n        /// by one of nested modules.\r\n        /// </summary>\r\n        public PSModuleInfo? Module { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets name of the module which implements the resource.\r\n        /// </summary>\r\n        public string? ModuleName { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets the normalized module name.\r\n        /// </summary>\r\n        public string? NormalizedModuleName\r\n        {\r\n            get { return this.ModuleName is not null ? StringHelpers.Normalize(this.ModuleName) : null; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets version of the module which implements the resource.\r\n        /// </summary>\r\n        public Version? Version { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets of the file which implements the resource. For the resources which are defined using\r\n        /// MOF file, this will be path to a module which resides in the same folder where schema.mof file is present.\r\n        /// For composite resources, this will be the module which implements the resource.\r\n        /// </summary>\r\n        public string? Path { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets parent folder, where the resource is defined\r\n        /// It is the folder containing either the implementing module(=Path) or folder containing \".schema.mof\".\r\n        /// For native providers, Path will be null and only ParentPath will be present.\r\n        /// </summary>\r\n        public string? ParentPath { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value which indicate how DSC resource is implemented.\r\n        /// </summary>\r\n        public ImplementedAsTypeInternal? ImplementedAs { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets company which owns this resource.\r\n        /// </summary>\r\n        public string? CompanyName { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets properties of the resource.\r\n        /// </summary>\r\n        public List<DscResourcePropertyInfoInternal> Properties { get; private set; } = new List<DscResourcePropertyInfoInternal>();\r\n\r\n        /// <summary>\r\n        /// Updates properties of the resource.\r\n        /// </summary>\r\n        /// <param name=\"properties\">Updated properties.</param>\r\n        public void UpdateProperties(List<DscResourcePropertyInfoInternal> properties)\r\n        {\r\n            this.Properties = properties;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/PowerShell/DscResourcesInfo/DscResourcePropertyInfoInternal.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"DscResourcePropertyInfoInternal.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.PowerShell.DscResourcesInfo\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n\r\n    /// <summary>\r\n    /// Contains a DSC resource property information.\r\n    /// </summary>\r\n    internal sealed class DscResourcePropertyInfoInternal\r\n    {\r\n        private const string DscResourcePropertyInfoFullName = \"Microsoft.PowerShell.DesiredStateConfiguration.DscResourcePropertyInfo\";\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"DscResourcePropertyInfoInternal\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"dscPropertyInfo\">Dynamic DSC property info.</param>\r\n        public DscResourcePropertyInfoInternal(dynamic dscPropertyInfo)\r\n        {\r\n            if (dscPropertyInfo.GetType().FullName != DscResourcePropertyInfoFullName)\r\n            {\r\n                throw new ArgumentException();\r\n            }\r\n\r\n            this.Name = dscPropertyInfo.Name;\r\n            this.PropertyType = dscPropertyInfo.PropertyType;\r\n            this.IsMandatory = dscPropertyInfo.IsMandatory;\r\n            this.Values = dscPropertyInfo.Values;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets name of the property.\r\n        /// </summary>\r\n        public string Name { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets type of the property.\r\n        /// </summary>\r\n        public string PropertyType { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether the property is mandatory or not.\r\n        /// </summary>\r\n        public bool IsMandatory { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets Values for a resource property.\r\n        /// </summary>\r\n        public List<string> Values { get; private set; } = new List<string>();\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/PowerShell/DscResourcesInfo/ImplementedAsTypeInternal.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"ImplementedAsTypeInternal.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.PowerShell.DscResourcesInfo\r\n{\r\n    /// <summary>\r\n    /// Enumerated values for DSC resource implementation type.\r\n    /// </summary>\r\n    internal enum ImplementedAsTypeInternal\r\n    {\r\n        /// <summary>\r\n        /// DSC resource implementation type not known.\r\n        /// </summary>\r\n        None = 0,\r\n\r\n        /// <summary>\r\n        /// DSC resource is implemented using PowerShell module.\r\n        /// </summary>\r\n        PowerShell = 1,\r\n\r\n        /// <summary>\r\n        /// DSC resource is implemented using a CIM provider.\r\n        /// </summary>\r\n        Binary = 2,\r\n\r\n        /// <summary>\r\n        /// DSC resource is a composite and implemented using configuration keyword.\r\n        /// </summary>\r\n        Composite = 3,\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/PowerShell/Extensions/PowerShellExtensions.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"PowerShellExtensions.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.PowerShell.Extensions\r\n{\r\n    using System.Collections.ObjectModel;\r\n    using System.Management.Automation;\r\n    using System.Text;\r\n\r\n    /// <summary>\r\n    /// Extensions methods for <see cref=\"PowerShell\"/> class.\r\n    /// </summary>\r\n    internal static class PowerShellExtensions\r\n    {\r\n        /// <summary>\r\n        /// Calls Invoke with <see cref=\"ActionPreference.Stop\"/> to stop execution of commands.\r\n        /// </summary>\r\n        /// <param name=\"pwsh\">PowerShell.</param>\r\n        /// <returns>Collection of PSObjects representing output.</returns>\r\n        public static Collection<PSObject> InvokeAndStopOnError(this PowerShell pwsh)\r\n        {\r\n            var settings = new PSInvocationSettings()\r\n            {\r\n                ErrorActionPreference = ActionPreference.Stop,\r\n            };\r\n\r\n            return pwsh.Invoke(null, settings);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls Invoke with <see cref=\"ActionPreference.Stop\"/> to stop execution of commands.\r\n        /// </summary>\r\n        /// <typeparam name=\"T\">Type of output object(s) expected from the command invocation.</typeparam>\r\n        /// <param name=\"pwsh\">PowerShell.</param>\r\n        /// <returns>Collection of the type output representing output.</returns>\r\n        public static Collection<T> InvokeAndStopOnError<T>(this PowerShell pwsh)\r\n        {\r\n            var settings = new PSInvocationSettings()\r\n            {\r\n                ErrorActionPreference = ActionPreference.Stop,\r\n            };\r\n\r\n            return pwsh.Invoke<T>(null, settings);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the error stream message if any.\r\n        /// </summary>\r\n        /// <param name=\"pwsh\">PowerShell.</param>\r\n        /// <returns>Error message. Null if none.</returns>\r\n        public static string? GetErrorMessage(this PowerShell pwsh)\r\n        {\r\n            if (pwsh.HadErrors)\r\n            {\r\n                var psStreamBuilder = new StringBuilder();\r\n                foreach (var line in pwsh.Streams.Error)\r\n                {\r\n                    psStreamBuilder.AppendLine(line.ToString());\r\n                }\r\n\r\n                return psStreamBuilder.ToString();\r\n            }\r\n\r\n            return null;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Determines if the given shell contains a property error, meaning that the source of this error is the\r\n        /// configuration values and not the configuration unit itself.\r\n        /// </summary>\r\n        /// <param name=\"pwsh\">The shell to inspect.</param>\r\n        /// <returns>True if it only contains property errors; false otherwise.</returns>\r\n        public static bool ContainsPropertyError(this PowerShell pwsh)\r\n        {\r\n            if (!pwsh.HadErrors)\r\n            {\r\n                return false;\r\n            }\r\n\r\n            bool result = true;\r\n\r\n            foreach (ErrorRecord? error in pwsh.Streams.Error)\n            {\n                if (error?.FullyQualifiedErrorId == \"PropertyAssignmentException\")\r\n                {\r\n                    result = result && true;\r\n                }\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/PowerShell/Helpers/ConfigurationUnitAndModule.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationUnitAndModule.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.PowerShell.Helpers\r\n{\r\n    using System;\r\n    using Microsoft.Management.Configuration;\r\n    using Microsoft.Management.Configuration.Processor.Constants;\r\n    using Microsoft.Management.Configuration.Processor.Helpers;\r\n    using Microsoft.PowerShell.Commands;\r\n\r\n    /// <summary>\r\n    /// Contains information about the unit and the DSC resource that applies to it.\r\n    /// </summary>\r\n    internal class ConfigurationUnitAndModule : ConfigurationUnitInternal\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ConfigurationUnitAndModule\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"unit\">Configuration unit.</param>\r\n        /// <param name=\"configurationFilePath\">The configuration file path.</param>\r\n        public ConfigurationUnitAndModule(ConfigurationUnit unit, string? configurationFilePath)\r\n            : base(unit, configurationFilePath)\r\n        {\r\n            string? moduleName = this.GetDirective<string>(DirectiveConstants.Module);\r\n            if (string.IsNullOrEmpty(moduleName))\r\n            {\r\n                this.Module = null;\r\n            }\r\n            else\r\n            {\r\n                this.Module = PowerShellHelpers.CreateModuleSpecification(\r\n                    moduleName,\r\n                    this.GetDirective<string>(DirectiveConstants.Version),\r\n                    this.GetDirective<string>(DirectiveConstants.MinVersion),\r\n                    this.GetDirective<string>(DirectiveConstants.MaxVersion),\r\n                    this.GetDirective<string>(DirectiveConstants.ModuleGuid));\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the module specification.\r\n        /// </summary>\r\n        public ModuleSpecification? Module { get; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/PowerShell/Helpers/ConfigurationUnitAndResource.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationUnitAndResource.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.PowerShell.Helpers\r\n{\r\n    using System;\r\n    using Microsoft.Management.Configuration;\r\n    using Microsoft.Management.Configuration.Processor.Helpers;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.DscResourcesInfo;\r\n    using Microsoft.PowerShell.Commands;\r\n    using Windows.Foundation.Collections;\r\n\r\n    /// <summary>\r\n    /// Contains information about the unit and the DSC resource that applies to it.\r\n    /// </summary>\r\n    internal class ConfigurationUnitAndResource\r\n    {\r\n        private readonly DscResourceInfoInternal dscResourceInfoInternal;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ConfigurationUnitAndResource\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"configurationUnitInternal\">Configuration unit internal.</param>\r\n        /// <param name=\"dscResourceInfoInternal\">DscResourceInfoInternal.</param>\r\n        public ConfigurationUnitAndResource(\r\n            ConfigurationUnitAndModule configurationUnitInternal,\r\n            DscResourceInfoInternal dscResourceInfoInternal)\r\n        {\r\n            if (!configurationUnitInternal.ResourceName.Equals(dscResourceInfoInternal.Name, StringComparison.OrdinalIgnoreCase))\r\n            {\r\n                throw new ArgumentException();\r\n            }\r\n\r\n            this.UnitInternal = configurationUnitInternal;\r\n            this.dscResourceInfoInternal = dscResourceInfoInternal;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or initializes the internal unit.\r\n        /// </summary>\r\n        public ConfigurationUnitAndModule UnitInternal { get; private init; }\r\n\r\n        /// <summary>\r\n        /// Gets the configuration unit.\r\n        /// </summary>\r\n        public ConfigurationUnit Unit\r\n        {\r\n            get { return this.UnitInternal.Unit; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the DSC resource name.\r\n        /// </summary>\r\n        /// <returns>DSC resource name.</returns>\r\n        public string ResourceName\r\n        {\r\n            get { return this.dscResourceInfoInternal.Name; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the module specification.\r\n        /// </summary>\r\n        public ModuleSpecification? Module\r\n        {\r\n            get { return this.UnitInternal.Module; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets a directive if exits.\r\n        /// </summary>\r\n        /// <param name=\"directiveName\">Name of directive.</param>\r\n        /// <returns>The value of the directive. Null if doesn't exist.</returns>\r\n        /// <typeparam name=\"TType\">Directive type value.</typeparam>\r\n        public TType? GetDirective<TType>(string directiveName)\r\n            where TType : class\r\n        {\r\n            return this.UnitInternal.GetDirective<TType>(directiveName);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets a directive bool value.\r\n        /// </summary>\r\n        /// <param name=\"directiveName\">Name of directive.</param>\r\n        /// <returns>The value of the directive. False if not set.</returns>\r\n        public bool? GetDirective(string directiveName)\r\n        {\r\n            return this.UnitInternal.GetDirective(directiveName);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the settings of the unit.\r\n        /// </summary>\r\n        /// <returns>ValueSet with settings.</returns>\r\n        public ValueSet GetSettings()\r\n        {\r\n            return this.UnitInternal.GetExpandedSettings();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/PowerShell/Helpers/DscResourcesMap.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"DscResourcesMap.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.PowerShell.Helpers\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.Linq;\r\n    using Microsoft.Management.Configuration.Processor.Helpers;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.DscResourcesInfo;\r\n\r\n    /// <summary>\r\n    /// DscResources in the system. Get-DscResource looks the entire PSModulePath to find resources every time, so\r\n    /// calling it multiples times is expensive. This class will store them in memory per configuration set.\r\n    /// The resources are stored in a dictionary in the following hierarchy.\r\n    /// - Module name\r\n    ///   - Resource name\r\n    ///     - Module Version\r\n    ///       - DscResourceInfo obj.\r\n    /// There are some resources that don't have a module name. These are modules that live under\r\n    /// C:\\WINDOWS\\system32\\WindowsPowershell\\v1.0\\Modules\\PsDesiredStateConfiguration\\DscResources.\r\n    /// This is not currently used. For now, we let PowerShell handle all the versioning. In order to avoid\r\n    /// calls to Get-DscResource every time a unit is set, this class needs to be updated to handle min and max\r\n    /// version. As it is, it just does RequiredVersion.\r\n    /// </summary>\r\n    internal sealed class DscResourcesMap\r\n    {\r\n        private readonly Dictionary<string, ModuleDscResources> resources = new Dictionary<string, ModuleDscResources>();\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"DscResourcesMap\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"resources\">DSC Resources.</param>\r\n        public DscResourcesMap(IReadOnlyList<DscResourceInfoInternal> resources)\r\n        {\r\n            foreach (var resource in resources)\r\n            {\r\n                if (string.IsNullOrEmpty(resource.Name))\r\n                {\r\n                    throw new ArgumentException(nameof(resource.Name));\r\n                }\r\n\r\n                if (resource.Version is null)\r\n                {\r\n                    throw new ArgumentException(nameof(resource.Version));\r\n                }\r\n\r\n                this.Insert(resource);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Looks for a DSC resource in the specified module.\r\n        /// </summary>\r\n        /// <param name=\"dscResourceName\">DSC resource name.</param>\r\n        /// <param name=\"moduleName\">Optional module name.</param>\r\n        /// <param name=\"version\">Optional module version.</param>\r\n        /// <returns>DscResourceInfoInternal. Null if not found.</returns>\r\n        public DscResourceInfoInternal? GetResource(string dscResourceName, string? moduleName, Version? version)\r\n        {\r\n            string normalizedResourceName = StringHelpers.Normalize(dscResourceName);\r\n            string? normalizedModuleName = null;\r\n            if (moduleName is not null)\r\n            {\r\n                normalizedModuleName = StringHelpers.Normalize(moduleName);\r\n            }\r\n\r\n            if (normalizedModuleName is null)\r\n            {\r\n                foreach (var module in this.resources.Values)\r\n                {\r\n                    var resourceInfo = module.GetDscResourceInfo(normalizedResourceName, version);\r\n                    if (resourceInfo is not null)\r\n                    {\r\n                        return resourceInfo;\r\n                    }\r\n                }\r\n            }\r\n            else\r\n            {\r\n                if (this.resources.TryGetValue(normalizedModuleName, out ModuleDscResources? module))\r\n                {\r\n                    return module.GetDscResourceInfo(normalizedResourceName, version);\r\n                }\r\n            }\r\n\r\n            return null;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Does a DSC resource exists.\r\n        /// </summary>\r\n        /// <param name=\"dscResourceName\">DSC resource name.</param>\r\n        /// <param name=\"moduleName\">Optional module name.</param>\r\n        /// <param name=\"version\">Optional module version.</param>\r\n        /// <returns>True if resource exists.</returns>\r\n        public bool Exists(string dscResourceName, string? moduleName, Version? version)\r\n        {\r\n            return this.GetResource(dscResourceName, moduleName, version) != null;\r\n        }\r\n\r\n        private void Insert(DscResourceInfoInternal dscResourceInfo)\r\n        {\r\n            string? normalizedModuleName = dscResourceInfo.NormalizedModuleName;\r\n\r\n            // There are some resources that doesn't have module, use empty as key.\r\n            string moduleKey = string.Empty;\r\n            if (normalizedModuleName is not null)\r\n            {\r\n                moduleKey = normalizedModuleName;\r\n            }\r\n\r\n            if (!this.resources.ContainsKey(moduleKey))\r\n            {\r\n                this.resources.Add(moduleKey, new ModuleDscResources(moduleKey, dscResourceInfo));\r\n            }\r\n            else\r\n            {\r\n                this.resources[moduleKey].AddResource(moduleKey, dscResourceInfo);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Represents a map versions for a DscResource.\r\n        /// </summary>\r\n        private class DscResourceVersions : Dictionary<Version, DscResourceInfoInternal>\r\n        {\r\n            private readonly string resourceName;\r\n\r\n            public DscResourceVersions(DscResourceInfoInternal dscResourceInfo)\r\n            {\r\n                this.resourceName = dscResourceInfo.NormalizedName;\r\n                this.AddVersion(dscResourceInfo);\r\n            }\r\n\r\n            /// <summary>\r\n            /// Adds a resource version.\r\n            /// </summary>\r\n            /// <param name=\"dscResourceInfo\">DscResourceInfo.</param>\r\n            public void AddVersion(DscResourceInfoInternal dscResourceInfo)\r\n            {\r\n                if (this.resourceName != dscResourceInfo.NormalizedName)\r\n                {\r\n                    throw new ArgumentException(dscResourceInfo.NormalizedName);\r\n                }\r\n\r\n                // There are some system resources without version or module name.\r\n                if (dscResourceInfo.Version is null)\r\n                {\r\n                    this.Add(new Version(), dscResourceInfo);\r\n                }\r\n                else\r\n                {\r\n                    // Get-DscResource will fail if the same module with same\r\n                    // resources and same version exists in the module path\r\n                    // so this shouldn't happen. Either way, we should throw there or here.\r\n                    this.Add(dscResourceInfo.Version, dscResourceInfo);\r\n                }\r\n            }\r\n\r\n            public DscResourceInfoInternal? GetDscResourceInfo(Version? version)\r\n            {\r\n                if (version is null)\r\n                {\r\n                    // Sort keys, get the latest.\r\n                    var newestVersion = this.Keys.OrderByDescending(v => v).First();\r\n                    return this[newestVersion];\r\n                }\r\n\r\n                if (this.TryGetValue(version, out DscResourceInfoInternal? resourceInfo))\r\n                {\r\n                    return resourceInfo;\r\n                }\r\n\r\n                return null;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Represent a map of resources for a module.\r\n        /// </summary>\r\n        private class ModuleDscResources : Dictionary<string, DscResourceVersions>\r\n        {\r\n            private readonly string normalizedModuleName;\r\n\r\n            public ModuleDscResources(string normalizedModuleName, DscResourceInfoInternal dscResourceInfo)\r\n            {\r\n                this.normalizedModuleName = normalizedModuleName;\r\n                this.AddResource(this.normalizedModuleName, dscResourceInfo);\r\n            }\r\n\r\n            public void AddResource(string normalizedModuleName, DscResourceInfoInternal dscResourceInfo)\r\n            {\r\n                if (this.normalizedModuleName != normalizedModuleName)\r\n                {\r\n                    throw new ArgumentException(nameof(normalizedModuleName));\r\n                }\r\n\r\n                var normalizedResourceName = dscResourceInfo.NormalizedName;\r\n                if (!this.ContainsKey(normalizedResourceName))\r\n                {\r\n                    this.Add(normalizedResourceName, new DscResourceVersions(dscResourceInfo));\r\n                }\r\n                else\r\n                {\r\n                    this[normalizedResourceName].AddVersion(dscResourceInfo);\r\n                }\r\n            }\r\n\r\n            public DscResourceInfoInternal? GetDscResourceInfo(string dscResourceName, Version? version)\r\n            {\r\n                if (this.TryGetValue(dscResourceName, out DscResourceVersions? versions))\r\n                {\r\n                    return versions.GetDscResourceInfo(version);\r\n                }\r\n\r\n                return null;\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/PowerShell/Helpers/Factory.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"Factory.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.PowerShell.Helpers\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.Linq;\r\n    using System.Management.Automation;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.DscResourcesInfo;\r\n    using Microsoft.Management.Configuration.Processor.Unit;\r\n    using Windows.Security.Cryptography.Certificates;\r\n\r\n    /// <summary>\r\n    /// Enables creation of PowerShell specific instances of configuration interfaces.\r\n    /// </summary>\r\n    internal static class Factory\r\n    {\r\n        private static readonly IEnumerable<string> PublicRepositories = new string[]\r\n        {\r\n            \"https://www.powershellgallery.com/api/v2\",\r\n        };\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ConfigurationUnitProcessorDetails\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"unitName\">Unit name.</param>\r\n        /// <param name=\"dscResourceInfo\">DSC Resource Info.</param>\r\n        /// <param name=\"psModuleInfo\">PSModuleInfo.</param>\r\n        /// <param name=\"getModuleInfo\">GetModuleInfo.</param>\r\n        /// <param name=\"certs\">List of certificates.</param>\r\n        /// <returns>An initialized instance of <see cref=\"ConfigurationUnitProcessorDetails\"/>.</returns>\r\n        public static ConfigurationUnitProcessorDetails CreateUnitProcessorDetails(\r\n            string unitName,\r\n            DscResourceInfoInternal? dscResourceInfo,\r\n            PSModuleInfo? psModuleInfo,\r\n            PSObject? getModuleInfo,\r\n            List<Certificate>? certs)\r\n        {\r\n            if (dscResourceInfo is null &&\r\n                psModuleInfo is null &&\r\n                getModuleInfo is null)\r\n            {\r\n                throw new ArgumentException();\r\n            }\r\n\r\n            ConfigurationUnitProcessorDetails result = new ConfigurationUnitProcessorDetails\r\n            {\r\n                UnitType = unitName,\r\n            };\r\n\r\n            if (dscResourceInfo is not null)\r\n            {\r\n                result.IsLocal = true;\r\n\r\n                var settings = new List<IConfigurationUnitSettingDetails>();\r\n                foreach (var properties in dscResourceInfo.Properties)\r\n                {\r\n                    settings.Add(CreateUnitSettingDetails(properties));\r\n                }\r\n\r\n                result.Settings = settings;\r\n\r\n                if (psModuleInfo is null)\r\n                {\r\n                    result.ModuleName = dscResourceInfo.ModuleName;\r\n                    result.Version = dscResourceInfo.Version is not null ? dscResourceInfo.Version.ToString() : null;\r\n                }\r\n            }\r\n\r\n            if (psModuleInfo is not null)\r\n            {\r\n                result.ModuleDocumentationUri = psModuleInfo.HelpInfoUri is not null ? new Uri(psModuleInfo.HelpInfoUri) : null;\r\n                result.UnitIconUri = psModuleInfo.IconUri;\r\n                result.ModuleName = psModuleInfo.Name;\r\n                result.ModuleType = psModuleInfo.ModuleType.ToString();\r\n                result.ModuleDescription = psModuleInfo.Description;\r\n                result.PublishedModuleUri = psModuleInfo.ProjectUri;\r\n                result.Version = psModuleInfo.Version.ToString();\r\n                result.Author = psModuleInfo.Author;\r\n                result.Publisher = psModuleInfo.CompanyName;\r\n            }\r\n\r\n            if (getModuleInfo is not null)\r\n            {\r\n                result.ModuleSource = TryGetPropertyAsString(getModuleInfo, \"Repository\");\r\n                result.PublishedDate = TryGetPropertyFromDateTimeToDateTimeOffset(getModuleInfo, \"PublishedDate\");\r\n\r\n                var repoSourceLocation = getModuleInfo.Properties[\"RepositorySourceLocation\"];\r\n                if (repoSourceLocation is not null)\r\n                {\r\n                    string? repoSourceLocationValue = repoSourceLocation.Value as string;\r\n                    if (repoSourceLocationValue is not null)\r\n                    {\r\n                        result.IsPublic = PublicRepositories.Any(r => r == repoSourceLocationValue);\r\n                    }\r\n                }\r\n\r\n                if (psModuleInfo is null)\r\n                {\r\n                    // Type is not the same as this PSModuleType.\r\n                    result.UnitIconUri = TryGetPropertyAsUri(getModuleInfo, \"IconUri\");\r\n                    result.ModuleName = TryGetPropertyAsString(getModuleInfo, \"Name\");\r\n                    result.ModuleDescription = TryGetPropertyAsString(getModuleInfo, \"Description\");\r\n                    result.Version = TryGetPropertyAsString(getModuleInfo, \"Version\");\r\n                    result.Author = TryGetPropertyAsString(getModuleInfo, \"Author\");\r\n                    result.Publisher = TryGetPropertyAsString(getModuleInfo, \"CompanyName\");\r\n                }\r\n            }\r\n\r\n            result.SigningInformation = certs;\r\n\r\n            return result;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"Factory\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"dscResourceInfo\">DSC Resource info.</param>\r\n        /// <returns>An initialized instance of <see cref=\"ConfigurationUnitSettingDetails\"/>.</returns>\r\n        public static ConfigurationUnitSettingDetails CreateUnitSettingDetails(DscResourcePropertyInfoInternal dscResourceInfo)\r\n        {\r\n            return new ConfigurationUnitSettingDetails\r\n            {\r\n                Identifier = dscResourceInfo.Name,\r\n                IsRequired = dscResourceInfo.IsMandatory,\r\n                Type = GetPropertyType(dscResourceInfo.PropertyType),\r\n            };\r\n        }\r\n\r\n        private static string? TryGetPropertyAsString(PSObject getModuleInfo, string getModuleInfoProperty)\r\n        {\r\n            var moduleProperty = getModuleInfo.Properties[getModuleInfoProperty];\r\n            if (moduleProperty is not null)\r\n            {\r\n                return moduleProperty.Value as string;\r\n            }\r\n\r\n            return null;\r\n        }\r\n\r\n        private static Uri? TryGetPropertyAsUri(PSObject getModuleInfo, string getModuleInfoProperty)\r\n        {\r\n            var moduleProperty = getModuleInfo.Properties[getModuleInfoProperty];\r\n            if (moduleProperty is not null)\r\n            {\r\n                string? modulePropertyString = moduleProperty.Value as string;\r\n                if (modulePropertyString is not null)\r\n                {\r\n                    return new Uri(modulePropertyString);\r\n                }\r\n            }\r\n\r\n            return null;\r\n        }\r\n\r\n        private static DateTimeOffset TryGetPropertyFromDateTimeToDateTimeOffset(PSObject getModuleInfo, string getModuleInfoProperty)\r\n        {\r\n            var moduleProperty = getModuleInfo.Properties[getModuleInfoProperty];\r\n            if (moduleProperty is not null)\r\n            {\r\n                DateTime propertyAsDateTime;\r\n\r\n                try\r\n                {\r\n                    propertyAsDateTime = (DateTime)moduleProperty.Value;\r\n                    return new DateTimeOffset(propertyAsDateTime);\r\n                }\r\n                catch\r\n                {\r\n                }\r\n            }\r\n\r\n            return default;\r\n        }\r\n\r\n        private static Windows.Foundation.PropertyType GetPropertyType(string propertyType)\r\n        {\r\n            switch (propertyType.ToLowerInvariant())\r\n            {\r\n                case \"[byte]\": return Windows.Foundation.PropertyType.UInt8;\r\n                case \"[int16]\": return Windows.Foundation.PropertyType.Int16;\r\n                case \"[uint16]\": return Windows.Foundation.PropertyType.UInt16;\r\n                case \"[int32]\": return Windows.Foundation.PropertyType.Int32;\r\n                case \"[uint32]\": return Windows.Foundation.PropertyType.UInt32;\r\n                case \"[int64]\": return Windows.Foundation.PropertyType.Int64;\r\n                case \"[uint64]\": return Windows.Foundation.PropertyType.UInt64;\r\n                case \"[single]\": return Windows.Foundation.PropertyType.Single;\r\n                case \"[double]\": return Windows.Foundation.PropertyType.Double;\r\n                case \"[char]\": return Windows.Foundation.PropertyType.Char16;\r\n                case \"[bool]\": return Windows.Foundation.PropertyType.Boolean;\r\n                case \"[string]\": return Windows.Foundation.PropertyType.String;\r\n                case \"[datetime]\": return Windows.Foundation.PropertyType.DateTime;\r\n                case \"[datetimeoffset]\": return Windows.Foundation.PropertyType.DateTime;\r\n                case \"[timespan]\": return Windows.Foundation.PropertyType.TimeSpan;\r\n                case \"[guid]\": return Windows.Foundation.PropertyType.Guid;\r\n                case \"[byte[]]\": return Windows.Foundation.PropertyType.UInt8Array;\r\n                case \"[int16[]]\": return Windows.Foundation.PropertyType.Int16Array;\r\n                case \"[uint16[]]\": return Windows.Foundation.PropertyType.UInt16Array;\r\n                case \"[int32[]]\": return Windows.Foundation.PropertyType.Int32Array;\r\n                case \"[uint32[]]\": return Windows.Foundation.PropertyType.UInt32Array;\r\n                case \"[int64[]]\": return Windows.Foundation.PropertyType.Int64Array;\r\n                case \"[uint64[]]\": return Windows.Foundation.PropertyType.UInt64Array;\r\n                case \"[single[]]\": return Windows.Foundation.PropertyType.SingleArray;\r\n                case \"[double[]]\": return Windows.Foundation.PropertyType.DoubleArray;\r\n                case \"[char[]]\": return Windows.Foundation.PropertyType.Char16Array;\r\n                case \"[bool[]]\": return Windows.Foundation.PropertyType.BooleanArray;\r\n                case \"[string[]]\": return Windows.Foundation.PropertyType.StringArray;\r\n                case \"[object[]]\": return Windows.Foundation.PropertyType.InspectableArray;\r\n                case \"[datetime[]]\": return Windows.Foundation.PropertyType.DateTimeArray;\r\n                case \"[datetimeoffset[]]\": return Windows.Foundation.PropertyType.DateTimeArray;\r\n                case \"[timespan[]]\": return Windows.Foundation.PropertyType.TimeSpanArray;\r\n                case \"[guid[]]\": return Windows.Foundation.PropertyType.GuidArray;\r\n\r\n                // Everything else will just be an object...\r\n                default: return Windows.Foundation.PropertyType.Inspectable;\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/PowerShell/Helpers/IPowerShellGet.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"IPowerShellGet.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.PowerShell.Helpers\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.PowerShell.Commands;\r\n    using SemanticVersion = Microsoft.Management.Configuration.Processor.Helpers.SemanticVersion;\r\n\r\n    /// <summary>\r\n    /// Interface for PowerShellGet cmdlets.\r\n    /// </summary>\r\n    internal interface IPowerShellGet\r\n    {\r\n        /// <summary>\r\n        /// Calls Find-Module.\r\n        /// </summary>\r\n        /// <param name=\"pwsh\">PowerShell instance.</param>\r\n        /// <param name=\"moduleName\">Module name.</param>\r\n        /// <param name=\"semanticVersion\">Optional version.</param>\r\n        /// <param name=\"semanticMinVersion\">Optional min version.</param>\r\n        /// <param name=\"semanticMaxVersion\">Optional max version.</param>\r\n        /// <param name=\"repository\">Optional repository.</param>\r\n        /// <param name=\"allowPrerelease\">Optional allow prerelease module.</param>\r\n        /// <returns>Module info, null if not found.</returns>\r\n        PSObject? FindModule(\r\n            PowerShell pwsh,\r\n            string moduleName,\r\n            SemanticVersion? semanticVersion,\r\n            SemanticVersion? semanticMinVersion,\r\n            SemanticVersion? semanticMaxVersion,\r\n            string? repository,\r\n            bool? allowPrerelease);\r\n\r\n        /// <summary>\r\n        /// Calls Find-DscResource.\r\n        /// </summary>\r\n        /// <param name=\"pwsh\">PowerShell instance.</param>\r\n        /// <param name=\"resourceName\">resource name.</param>\r\n        /// <param name=\"moduleName\">Optional module name.</param>\r\n        /// <param name=\"semanticVersion\">Optional version.</param>\r\n        /// <param name=\"semanticMinVersion\">Optional min version.</param>\r\n        /// <param name=\"semanticMaxVersion\">Optional max version.</param>\r\n        /// <param name=\"repository\">Optional repository.</param>\r\n        /// <param name=\"allowPrerelease\">Optional allow prerelease module.</param>\r\n        /// <returns>Dsc Resource info, null if not found.</returns>\r\n        PSObject? FindDscResource(\r\n            PowerShell pwsh,\r\n            string resourceName,\r\n            string? moduleName,\r\n            SemanticVersion? semanticVersion,\r\n            SemanticVersion? semanticMinVersion,\r\n            SemanticVersion? semanticMaxVersion,\r\n            string? repository,\r\n            bool? allowPrerelease);\r\n\r\n        /// <summary>\r\n        /// Calls Save-Module with module specification.\r\n        /// </summary>\r\n        /// <param name=\"pwsh\">PowerShell instance.</param>\r\n        /// <param name=\"moduleSpecification\">Module specification.</param>\r\n        /// <param name=\"location\">Location to save module.</param>\r\n        void SaveModule(PowerShell pwsh, ModuleSpecification moduleSpecification, string location);\r\n\r\n        /// <summary>\r\n        /// Calls Save-Module -InputObject object -Path location.\r\n        /// Input object must be the result of Find cmdlets of PowerShellGet.\r\n        /// </summary>\r\n        /// <param name=\"pwsh\">PowerShell instance.</param>\r\n        /// <param name=\"inputObject\">Input object.</param>\r\n        /// <param name=\"location\">Location to save module.</param>\r\n        void SaveModule(PowerShell pwsh, PSObject inputObject, string location);\r\n\r\n        /// <summary>\r\n        /// Calls Install-Module -InputObject object.\r\n        /// Input object must be the result of Find cmdlets of PowerShellGet.\r\n        /// </summary>\r\n        /// <param name=\"pwsh\">PowerShell instance.</param>\r\n        /// <param name=\"inputObject\">Input object.</param>\r\n        /// <param name=\"allUsers\">If to install to all users.</param>\r\n        void InstallModule(PowerShell pwsh, PSObject inputObject, bool allUsers);\r\n\r\n        /// <summary>\r\n        /// Calls Install-Module with a module specification.\r\n        /// </summary>\r\n        /// <param name=\"pwsh\">PowerShell instance.</param>\r\n        /// <param name=\"moduleSpecification\">Module specification.</param>\r\n        /// <param name=\"allUsers\">If to install to all users.</param>\r\n        void InstallModule(PowerShell pwsh, ModuleSpecification moduleSpecification, bool allUsers);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/PowerShell/Helpers/PowerShellGetV2.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"PowerShellGetV2.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.PowerShell.Helpers\r\n{\r\n    using System.Collections.Generic;\r\n    using System.Linq;\r\n    using System.Management.Automation;\r\n    using Microsoft.PowerShell.Commands;\r\n    using static Microsoft.Management.Configuration.Processor.PowerShell.Constants.PowerShellConstants;\r\n    using SemanticVersion = Microsoft.Management.Configuration.Processor.Helpers.SemanticVersion;\r\n\r\n    /// <summary>\r\n    /// PowerShellGet implementation for 2.2.5 .\r\n    /// </summary>\r\n    internal class PowerShellGetV2 : IPowerShellGet\r\n    {\r\n        private const string AllUsers = \"AllUsers\";\r\n\r\n        /// <inheritdoc/>\r\n        public PSObject? FindModule(\r\n            PowerShell pwsh,\r\n            string moduleName,\r\n            SemanticVersion? semanticVersion,\r\n            SemanticVersion? semanticMinVersion,\r\n            SemanticVersion? semanticMaxVersion,\r\n            string? repository,\r\n            bool? allowPrerelease)\r\n        {\r\n            bool implicitAllowPrerelease = false;\r\n\r\n            var parameters = new Dictionary<string, object>()\r\n            {\r\n                { Parameters.Name, moduleName },\r\n            };\r\n\r\n            if (semanticVersion != null)\r\n            {\r\n                implicitAllowPrerelease |= semanticVersion.IsPrerelease;\r\n                parameters.Add(Parameters.RequiredVersion, semanticVersion.ToString());\r\n            }\r\n\r\n            if (semanticMinVersion != null)\r\n            {\r\n                implicitAllowPrerelease |= semanticMinVersion.IsPrerelease;\r\n                parameters.Add(Parameters.MinimumVersion, semanticMinVersion.ToString());\r\n            }\r\n\r\n            if (semanticMaxVersion != null)\r\n            {\r\n                implicitAllowPrerelease |= semanticMaxVersion.IsPrerelease;\r\n                parameters.Add(Parameters.MaximumVersion, semanticMaxVersion.ToString());\r\n            }\r\n\r\n            if (!string.IsNullOrEmpty(repository))\r\n            {\r\n                parameters.Add(Parameters.Repository, repository);\r\n            }\r\n\r\n            if (allowPrerelease.HasValue || implicitAllowPrerelease)\r\n            {\r\n                // If explicit allowPrerelease = false don't use implicit.\r\n                bool allow = allowPrerelease ?? implicitAllowPrerelease;\r\n                parameters.Add(Parameters.AllowPrerelease, allow);\r\n            }\r\n\r\n            pwsh.AddCommand(Commands.FindModule)\r\n                .AddParameters(parameters);\r\n\r\n            return pwsh.Invoke().FirstOrDefault();\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public PSObject? FindDscResource(\r\n            PowerShell pwsh,\r\n            string resourceName,\r\n            string? moduleName,\r\n            SemanticVersion? semanticVersion,\r\n            SemanticVersion? semanticMinVersion,\r\n            SemanticVersion? semanticMaxVersion,\r\n            string? repository,\r\n            bool? allowPrerelease)\r\n        {\r\n            var parameters = new Dictionary<string, object>()\r\n            {\r\n                { Parameters.Name, resourceName },\r\n            };\r\n\r\n            bool implicitAllowPrerelease = false;\r\n\r\n            if (!string.IsNullOrEmpty(moduleName))\r\n            {\r\n                parameters.Add(Parameters.ModuleName, moduleName);\r\n            }\r\n\r\n            if (semanticVersion != null)\r\n            {\r\n                implicitAllowPrerelease |= semanticVersion.IsPrerelease;\r\n                parameters.Add(Parameters.RequiredVersion, semanticVersion.ToString());\r\n            }\r\n\r\n            if (semanticMinVersion != null)\r\n            {\r\n                implicitAllowPrerelease |= semanticMinVersion.IsPrerelease;\r\n                parameters.Add(Parameters.MinimumVersion, semanticMinVersion.ToString());\r\n            }\r\n\r\n            if (semanticMaxVersion != null)\r\n            {\r\n                implicitAllowPrerelease |= semanticMaxVersion.IsPrerelease;\r\n                parameters.Add(Parameters.MaximumVersion, semanticMaxVersion.ToString());\r\n            }\r\n\r\n            if (!string.IsNullOrEmpty(repository))\r\n            {\r\n                parameters.Add(Parameters.Repository, repository);\r\n            }\r\n\r\n            if (allowPrerelease.HasValue || implicitAllowPrerelease)\r\n            {\r\n                // If explicit allowPrerelease = false don't use implicit.\r\n                bool allow = allowPrerelease ?? implicitAllowPrerelease;\r\n                parameters.Add(Parameters.AllowPrerelease, allow);\r\n            }\r\n\r\n            pwsh.AddCommand(Commands.FindDscResource)\r\n                .AddParameters(parameters);\r\n\r\n            // The result is just a PSCustomObject with a type name of Microsoft.PowerShell.Commands.PSGetDscResourceInfo.\r\n            // When no module is passed and a resource is not found, this will return an empty list. If a module\r\n            // is specified and no resource is found then it will fail earlier because of a Write-Error.\r\n            return pwsh.Invoke().FirstOrDefault();\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public void SaveModule(\r\n            PowerShell pwsh,\r\n            ModuleSpecification moduleSpecification,\r\n            string location)\r\n        {\r\n            var parameters = new Dictionary<string, object>()\r\n            {\r\n                { Parameters.Name, moduleSpecification.Name },\r\n                { Parameters.Path, location },\r\n            };\r\n\r\n            if (moduleSpecification.Version is not null)\r\n            {\r\n                parameters.Add(Parameters.MinimumVersion, moduleSpecification.Version);\r\n            }\r\n\r\n            if (moduleSpecification.MaximumVersion is not null)\r\n            {\r\n                parameters.Add(Parameters.MaximumVersion, moduleSpecification.MaximumVersion);\r\n            }\r\n\r\n            if (moduleSpecification.RequiredVersion is not null)\r\n            {\r\n                parameters.Add(Parameters.RequiredVersion, moduleSpecification.RequiredVersion);\r\n            }\r\n\r\n            _ = pwsh.AddCommand(Commands.SaveModule)\r\n                    .AddParameters(parameters)\r\n                    .AddParameter(Parameters.Force)\r\n                    .Invoke();\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public void SaveModule(\r\n            PowerShell pwsh,\r\n            PSObject inputObject,\r\n            string location)\r\n        {\r\n            _ = pwsh.AddCommand(Commands.SaveModule)\r\n                    .AddParameter(Parameters.Path, location)\r\n                    .AddParameter(Parameters.InputObject, inputObject)\r\n                    .AddParameter(Parameters.Force)\r\n                    .Invoke();\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public void InstallModule(\r\n            PowerShell pwsh,\r\n            PSObject inputObject,\r\n            bool allUsers)\r\n        {\r\n            var parameters = new Dictionary<string, object>()\r\n            {\r\n                { Parameters.InputObject, inputObject },\r\n            };\r\n\r\n            if (allUsers)\r\n            {\r\n                parameters.Add(Parameters.Scope, AllUsers);\r\n            }\r\n\r\n            // If the repository is untrusted, it will fail with:\r\n            //   Microsoft.PowerShell.Commands.WriteErrorException : Exception calling \"ShouldContinue\" with \"5\"\r\n            //   argument(s): \"A command that prompts the user failed because the host program or the command type\r\n            //   does not support user interaction.\r\n            // If its trusted, PowerShellGets adds the Force parameter to the call to PackageManager\\Install-Package.\r\n            // TODO: Once we have policies, we should remove Force. For hosted environments and depending\r\n            // on the policy we will trust PSGallery when we create the Runspace or add Force here.\r\n            _ = pwsh.AddCommand(Commands.InstallModule)\r\n                    .AddParameters(parameters)\r\n                    .AddParameter(Parameters.Force)\r\n                    .Invoke();\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public void InstallModule(\r\n            PowerShell pwsh,\r\n            ModuleSpecification moduleSpecification,\r\n            bool allUsers)\r\n        {\r\n            var parameters = new Dictionary<string, object>()\r\n            {\r\n                { Parameters.Name, moduleSpecification.Name },\r\n            };\r\n\r\n            if (moduleSpecification.Version is not null)\r\n            {\r\n                parameters.Add(Parameters.MinimumVersion, moduleSpecification.Version);\r\n            }\r\n\r\n            if (moduleSpecification.MaximumVersion is not null)\r\n            {\r\n                parameters.Add(Parameters.MaximumVersion, moduleSpecification.MaximumVersion);\r\n            }\r\n\r\n            if (moduleSpecification.RequiredVersion is not null)\r\n            {\r\n                parameters.Add(Parameters.RequiredVersion, moduleSpecification.RequiredVersion);\r\n            }\r\n\r\n            if (allUsers)\r\n            {\r\n                parameters.Add(Parameters.Scope, AllUsers);\r\n            }\r\n\r\n            _ = pwsh.AddCommand(Commands.InstallModule)\r\n                    .AddParameters(parameters)\r\n                    .AddParameter(Parameters.Force)\r\n                    .Invoke();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/PowerShell/Helpers/PowerShellHelpers.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"PowerShellHelpers.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.PowerShell.Helpers\r\n{\r\n    using System.Collections;\r\n    using Microsoft.Management.Configuration.Processor.Helpers;\r\n    using Microsoft.PowerShell.Commands;\r\n    using static Microsoft.Management.Configuration.Processor.PowerShell.Constants.PowerShellConstants;\r\n\r\n    /// <summary>\r\n    /// General PowerShell helpers.\r\n    /// </summary>\r\n    internal static class PowerShellHelpers\r\n    {\r\n        /// <summary>\r\n        /// Creates a module specification object.\r\n        /// </summary>\r\n        /// <param name=\"moduleName\">Module name.</param>\r\n        /// <param name=\"version\">Optional version.</param>\r\n        /// <param name=\"minVersion\">Optional min version.</param>\r\n        /// <param name=\"maxVersion\">Optional max version.</param>\r\n        /// <param name=\"guid\">Optional guid.</param>\r\n        /// <returns>ModuleSpecification.</returns>\r\n        public static ModuleSpecification CreateModuleSpecification(\r\n            string moduleName,\r\n            string? version = null,\r\n            string? minVersion = null,\r\n            string? maxVersion = null,\r\n            string? guid = null)\r\n        {\r\n            if (version is null &&\r\n                minVersion is null &&\r\n                maxVersion is null)\r\n            {\r\n                // Otherwise will fail with MissingMemberException...\r\n                return new ModuleSpecification(moduleName);\r\n            }\r\n\r\n            var moduleInfo = new Hashtable\r\n            {\r\n                { Parameters.ModuleName, moduleName },\r\n            };\r\n\r\n            if (!string.IsNullOrEmpty(version))\r\n            {\r\n                var semanticVersion = new SemanticVersion(version);\r\n                moduleInfo.Add(Parameters.RequiredVersion, semanticVersion.Version);\r\n            }\r\n\r\n            if (!string.IsNullOrEmpty(minVersion))\r\n            {\r\n                var semanticVersion = new SemanticVersion(minVersion);\r\n                moduleInfo.Add(Parameters.ModuleVersion, semanticVersion.Version);\r\n            }\r\n\r\n            if (!string.IsNullOrEmpty(maxVersion))\r\n            {\r\n                var semanticVersion = new SemanticVersion(maxVersion);\r\n\r\n                // For some reason, the constructor of ModuleSpecification that takes\r\n                // a hashtable calls ModuleCmdletBase.GetMaximumVersion. This method will\r\n                // validate the max version and replace * for 999999999 only if its the last\r\n                // char in the string. But then the returned value is not assigned to the\r\n                // ModuleSpecification's MaximumVersion property. If we want to set a\r\n                // MaximumVersion with a wildcard and pass this to Install-Module it will\r\n                // fail with \"Cannot convert value 'x.*' to type 'System.Version'.\"\r\n                moduleInfo.Add(Parameters.MaximumVersion, semanticVersion.Version.ToString());\r\n            }\r\n\r\n            if (!string.IsNullOrEmpty(guid))\r\n            {\r\n                moduleInfo.Add(Parameters.Guid, guid);\r\n            }\r\n\r\n            // Using the Hashtable constructor will verify that RequiredVersion is used properly.\r\n            return new ModuleSpecification(moduleInfo);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/PowerShell/ProcessorEnvironments/HostedEnvironment.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"HostedEnvironment.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.PowerShell.Runspaces\r\n{\r\n    using System;\r\n    using System.Collections;\r\n    using System.Collections.Generic;\r\n    using System.IO;\r\n    using System.Linq;\r\n    using System.Management.Automation;\r\n    using System.Management.Automation.Runspaces;\r\n    using System.Runtime.InteropServices.WindowsRuntime;\r\n    using Microsoft.Management.Configuration.Processor.Constants;\r\n    using Microsoft.Management.Configuration.Processor.Helpers;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.DscModules;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.DscResourcesInfo;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.Helpers;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.ProcessorEnvironments;\r\n    using Microsoft.PowerShell.Commands;\r\n    using Windows.Foundation.Collections;\r\n    using Windows.Security.Cryptography.Certificates;\r\n    using Windows.Storage.Streams;\r\n    using static Microsoft.Management.Configuration.Processor.PowerShell.Constants.PowerShellConstants;\r\n\r\n    /// <summary>\r\n    /// Process environment. Provides interaction with PowerShell for a hosted environment.\r\n    /// </summary>\r\n    internal class HostedEnvironment : IProcessorEnvironment\r\n    {\r\n        private readonly PowerShellConfigurationProcessorType type;\r\n        private readonly IPowerShellGet powerShellGet;\r\n\r\n        private PowerShellConfigurationProcessorLocation location = PowerShellConfigurationProcessorLocation.CurrentUser;\r\n        private string? customLocation;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"HostedEnvironment\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"runspace\">PowerShell Runspace.</param>\r\n        /// <param name=\"type\">Configuration processor type.</param>\r\n        /// <param name=\"dscModule\">IDscModule.</param>\r\n        public HostedEnvironment(\r\n            Runspace runspace,\r\n            PowerShellConfigurationProcessorType type,\r\n            IDscModule dscModule)\r\n        {\r\n            this.Runspace = runspace;\r\n            this.type = type;\r\n            this.DscModule = dscModule;\r\n\r\n            // TODO: once v3 is release implement v3 version.\r\n            this.powerShellGet = new PowerShellGetV2();\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public Runspace Runspace { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the DscModule.\r\n        /// </summary>\r\n        internal IDscModule DscModule { get; }\r\n\r\n        /// <summary>\r\n        /// Gets or initializes the set processor factory.\r\n        /// </summary>\r\n        internal PowerShellConfigurationSetProcessorFactory? SetProcessorFactory { get; init; }\r\n\r\n        /// <inheritdoc/>\r\n        public void ValidateRunspace()\r\n        {\r\n            // Only support PowerShell Core.\r\n            if (this.GetVariable<string>(Variables.PSEdition) != Core)\r\n            {\r\n                throw new NotSupportedException(\"Only PowerShell Core is supported.\");\r\n            }\r\n\r\n            // If opening a runspace has failures, like one of the modules in ImportPSModule is not found, it won't throw but\r\n            // write to the error output. This is not a fatal error, since we install PSDesiredStateConfiguration\r\n            // module if not found, so unless there's a real reason keep it in verbose.\r\n            var errors = this.GetVariable<ArrayList>(Variables.Error);\r\n            if (errors.Count > 0)\r\n            {\r\n                this.OnDiagnostics(\r\n                    DiagnosticLevel.Verbose,\r\n                    $\"Error creating runspace '{string.Join(\"\\n\", errors.Cast<string>().ToArray())}'\");\r\n            }\r\n\r\n            var powerShellGet = PowerShellHelpers.CreateModuleSpecification(\r\n                    Modules.PowerShellGet,\r\n                    minVersion: Modules.PowerShellGetMinVersion);\r\n            if (!this.ValidateModule(powerShellGet))\r\n            {\r\n                var previousVersion = this.GetAvailableModule(\r\n                    PowerShellHelpers.CreateModuleSpecification(\r\n                        Modules.PowerShellGet));\r\n                string message = $\"Required '{powerShellGet}'\";\r\n                if (previousVersion is not null)\r\n                {\r\n                    message += $\" Found '{previousVersion.Name} {previousVersion.Version}'\";\r\n                }\r\n\r\n                throw new NotSupportedException(message);\r\n            }\r\n\r\n            // Make sure PSDesiredConfiguration is present.\r\n            this.InstallModule(this.DscModule.ModuleSpecification);\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public IReadOnlyList<DscResourceInfoInternal> GetAllDscResources()\r\n        {\r\n            using PowerShell pwsh = PowerShell.Create(this.Runspace);\r\n            var results = this.DscModule.GetAllDscResources(pwsh);\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);\r\n            return results;\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public IReadOnlyList<DscResourceInfoInternal> GetDscResourcesInModule(ModuleSpecification moduleSpecification)\r\n        {\r\n            using PowerShell pwsh = PowerShell.Create(this.Runspace);\r\n            var results = this.DscModule.GetDscResourcesInModule(pwsh, moduleSpecification);\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);\r\n            return results;\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public DscResourceInfoInternal? GetDscResource(ConfigurationUnitAndModule unitInternal)\r\n        {\r\n            using PowerShell pwsh = PowerShell.Create(this.Runspace);\r\n            var result = this.DscModule.GetDscResource(pwsh, unitInternal.ResourceName, unitInternal.Module);\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);\r\n            return result;\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public ValueSet InvokeGetResource(ValueSet settings, string name, ModuleSpecification? moduleSpecification)\r\n        {\r\n            using PowerShell pwsh = PowerShell.Create(this.Runspace);\r\n            var result = this.DscModule.InvokeGetResource(pwsh, settings, name, moduleSpecification);\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);\r\n            return result;\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public bool InvokeTestResource(ValueSet settings, string name, ModuleSpecification? moduleSpecification)\r\n        {\r\n            using PowerShell pwsh = PowerShell.Create(this.Runspace);\r\n            var result = this.DscModule.InvokeTestResource(pwsh, settings, name, moduleSpecification);\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);\r\n            return result;\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public bool InvokeSetResource(ValueSet settings, string name, ModuleSpecification? moduleSpecification)\r\n        {\r\n            using PowerShell pwsh = PowerShell.Create(this.Runspace);\r\n            var result = this.DscModule.InvokeSetResource(pwsh, settings, name, moduleSpecification);\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);\r\n            return result;\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public PSModuleInfo? GetImportedModule(ModuleSpecification moduleSpecification)\r\n        {\r\n            using PowerShell pwsh = PowerShell.Create(this.Runspace);\r\n\r\n            var moduleInfo = pwsh.AddCommand(Commands.GetModule)\r\n                                 .AddParameter(Parameters.FullyQualifiedName, moduleSpecification)\r\n                                 .Invoke<PSModuleInfo>()\r\n                                 .FirstOrDefault();\r\n\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);\r\n            return moduleInfo;\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public PSModuleInfo? GetAvailableModule(ModuleSpecification moduleSpecification)\r\n        {\r\n            using PowerShell pwsh = PowerShell.Create(this.Runspace);\r\n\r\n            var moduleInfo = pwsh.AddCommand(Commands.GetModule)\r\n                                 .AddParameter(Parameters.FullyQualifiedName, moduleSpecification)\r\n                                 .AddParameter(Parameters.ListAvailable)\r\n                                 .Invoke<PSModuleInfo>()\r\n                                 .FirstOrDefault();\r\n\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);\r\n            return moduleInfo;\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public PSModuleInfo? GetAvailableModule(string path)\r\n        {\r\n            using PowerShell pwsh = PowerShell.Create(this.Runspace);\r\n\r\n            var moduleInfo = pwsh.AddCommand(Commands.GetModule)\r\n                                 .AddParameter(Parameters.Name, path)\r\n                                 .AddParameter(Parameters.ListAvailable)\r\n                                 .Invoke<PSModuleInfo>()\r\n                                 .FirstOrDefault();\r\n\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);\r\n            return moduleInfo;\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public void ImportModule(ModuleSpecification moduleSpecification)\r\n        {\r\n            using PowerShell pwsh = PowerShell.Create(this.Runspace);\r\n\r\n            _ = pwsh.AddCommand(Commands.ImportModule)\r\n                    .AddParameter(Parameters.FullyQualifiedName, moduleSpecification)\r\n                    .Invoke();\r\n\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public void ImportModule(string path)\r\n        {\r\n            if (!File.Exists(path))\r\n            {\r\n                throw new FileNotFoundException(path);\r\n            }\r\n\r\n            using PowerShell pwsh = PowerShell.Create(this.Runspace);\r\n\r\n            _ = pwsh.AddCommand(Commands.ImportModule)\r\n                    .AddParameter(Parameters.Name, path)\r\n                    .Invoke();\r\n\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public PSObject? GetInstalledModule(ModuleSpecification moduleSpecification)\r\n        {\r\n            // Instead of Get-InstalledModule, we look for PSGetModuleInfo.xml and serialize it\r\n            // if found. This allow us to get the information from Install-Module and Save-Module.\r\n            var module = this.GetAvailableModule(moduleSpecification);\r\n            if (module is null)\r\n            {\r\n                return null;\r\n            }\r\n\r\n            var getModuleInfoFile = Path.Combine(module.ModuleBase, \"PSGetModuleInfo.xml\");\r\n            if (!File.Exists(getModuleInfoFile))\r\n            {\r\n                // Keep Get-InstalledModule behaviour.\r\n                return null;\r\n            }\r\n\r\n            using PowerShell pwsh = PowerShell.Create(this.Runspace);\r\n            var installedModule = pwsh.AddCommand(Commands.ImportCliXml)\r\n                                      .AddParameter(Parameters.Path, getModuleInfoFile)\r\n                                      .Invoke()\r\n                                      .FirstOrDefault();\r\n\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);\r\n            return installedModule;\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public PSObject? FindModule(ConfigurationUnitInternal unitInternal)\r\n        {\r\n            // Don't use ModuleSpecification here. Each parameter is independent and\r\n            // we need version even if a module was not specified.\r\n            string? moduleName = unitInternal.GetDirective<string>(DirectiveConstants.Module);\r\n\r\n            if (string.IsNullOrEmpty(moduleName))\r\n            {\r\n                return null;\r\n            }\r\n\r\n            using PowerShell pwsh = PowerShell.Create(this.Runspace);\r\n\r\n            var result = this.powerShellGet.FindModule(\r\n                pwsh,\r\n                moduleName,\r\n                unitInternal.GetSemanticVersion(),\r\n                unitInternal.GetSemanticMinVersion(),\r\n                unitInternal.GetSemanticMaxVersion(),\r\n                unitInternal.GetDirective<string>(DirectiveConstants.Repository),\r\n                unitInternal.GetDirective(DirectiveConstants.AllowPrerelease));\r\n\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);\r\n            return result;\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public PSObject? FindDscResource(ConfigurationUnitInternal unitInternal)\r\n        {\r\n            using PowerShell pwsh = PowerShell.Create(this.Runspace);\r\n\r\n            var result = this.powerShellGet.FindDscResource(\r\n                pwsh,\r\n                unitInternal.ResourceName,\r\n                unitInternal.GetDirective<string>(DirectiveConstants.Module),\r\n                unitInternal.GetSemanticVersion(),\r\n                unitInternal.GetSemanticMinVersion(),\r\n                unitInternal.GetSemanticMaxVersion(),\r\n                unitInternal.GetDirective<string>(DirectiveConstants.Repository),\r\n                unitInternal.GetDirective(DirectiveConstants.AllowPrerelease));\r\n\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);\r\n            return result;\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public void SaveModule(PSObject inputObject, string location)\r\n        {\r\n            using PowerShell pwsh = PowerShell.Create(this.Runspace);\r\n            this.powerShellGet.SaveModule(pwsh, inputObject, location);\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public void SaveModule(ModuleSpecification moduleSpecification, string location)\r\n        {\r\n            using PowerShell pwsh = PowerShell.Create(this.Runspace);\r\n            this.powerShellGet.SaveModule(pwsh, moduleSpecification, location);\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public void InstallModule(PSObject inputObject)\r\n        {\r\n            if (this.location == PowerShellConfigurationProcessorLocation.Custom)\r\n            {\r\n                if (string.IsNullOrEmpty(this.customLocation))\r\n                {\r\n                    throw new ArgumentNullException(nameof(this.customLocation));\r\n                }\r\n\r\n                this.SaveModule(inputObject, this.customLocation);\r\n            }\r\n            else\r\n            {\r\n                using PowerShell pwsh = PowerShell.Create(this.Runspace);\r\n                this.powerShellGet.InstallModule(pwsh, inputObject, this.location == PowerShellConfigurationProcessorLocation.AllUsers);\r\n                this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);\r\n            }\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public void InstallModule(ModuleSpecification moduleSpecification)\r\n        {\r\n            // Maybe is already there.\r\n            if (!this.ValidateModule(moduleSpecification))\r\n            {\r\n                this.OnDiagnostics(DiagnosticLevel.Verbose, $\"Installing module: {moduleSpecification.Name} ...\");\r\n\r\n                // Ok, we have to get it.\r\n                if (this.location == PowerShellConfigurationProcessorLocation.Custom)\r\n                {\r\n                    if (string.IsNullOrEmpty(this.customLocation))\r\n                    {\r\n                        throw new ArgumentNullException(nameof(this.customLocation));\r\n                    }\r\n\r\n                    this.OnDiagnostics(DiagnosticLevel.Verbose, $\"... calling save module ...\");\r\n                    this.SaveModule(moduleSpecification, this.customLocation);\r\n                }\r\n                else\r\n                {\r\n                    this.OnDiagnostics(DiagnosticLevel.Verbose, $\"... calling install module ...\");\r\n                    using PowerShell pwsh = PowerShell.Create(this.Runspace);\r\n                    this.powerShellGet.InstallModule(pwsh, moduleSpecification, this.location == PowerShellConfigurationProcessorLocation.AllUsers);\r\n                    this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);\r\n                }\r\n\r\n                this.OnDiagnostics(DiagnosticLevel.Verbose, $\" ... module installed.\");\r\n            }\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public List<Certificate> GetCertsOfValidSignedFiles(string[] paths)\r\n        {\r\n            using PowerShell pwsh = PowerShell.Create(this.Runspace);\r\n\r\n            var signatures = pwsh.AddCommand(Commands.GetChildItem)\r\n                                 .AddParameter(Parameters.Path, paths)\r\n                                 .AddCommand(Commands.GetAuthenticodeSignature)\r\n                                 .Invoke<Signature>();\r\n\r\n            var thumbprint = new HashSet<string>();\r\n            var certificates = new List<Certificate>();\r\n            foreach (var signature in signatures)\r\n            {\r\n                if (signature.Status == SignatureStatus.Valid)\r\n                {\r\n                    if (thumbprint.Add(signature.SignerCertificate.Thumbprint))\r\n                    {\r\n                        IBuffer buffer = signature.SignerCertificate.GetRawCertData().AsBuffer();\r\n                        certificates.Add(new Certificate(buffer));\r\n                    }\r\n                }\r\n            }\r\n\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, pwsh);\r\n            return certificates;\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public TType GetVariable<TType>(string name)\r\n        {\r\n            return (TType)this.Runspace.SessionStateProxy.PSVariable.GetValue(name);\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public void SetVariable(string name, object value)\r\n        {\r\n            this.Runspace.SessionStateProxy.PSVariable.Set(name, value);\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public void SetPSModulePath(string path)\r\n        {\r\n            this.SetVariable(Variables.PSModulePath, path);\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public void SetPSModulePaths(IReadOnlyList<string> paths)\r\n        {\r\n            this.SetVariable(Variables.PSModulePath, string.Join(\";\", paths));\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public void PrependPSModulePath(string path)\r\n        {\r\n            var oldModulePath = this.GetModulePaths();\r\n            if (!oldModulePath.Contains(path))\r\n            {\r\n                this.SetPSModulePath($\"{path};{string.Join(\";\", oldModulePath)}\");\r\n            }\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public void PrependPSModulePaths(IReadOnlyList<string> paths)\r\n        {\r\n            var newPaths = paths.ToList();\r\n            var oldModulePath = this.GetModulePaths();\r\n            foreach (var newPath in paths)\r\n            {\r\n                if (oldModulePath.Contains(newPath))\r\n                {\r\n                    newPaths.Remove(newPath);\r\n                }\r\n            }\r\n\r\n            if (newPaths.Any())\r\n            {\r\n                this.SetPSModulePath($\"{string.Join(\";\", newPaths)};{string.Join(\";\", oldModulePath)}\");\r\n            }\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public void AppendPSModulePath(string path)\r\n        {\r\n            var oldModulePath = this.GetModulePaths();\r\n            if (!oldModulePath.Contains(path))\r\n            {\r\n                this.SetPSModulePath($\"{string.Join(\";\", oldModulePath)};{path}\");\r\n            }\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public void AppendPSModulePaths(IReadOnlyList<string> paths)\r\n        {\r\n            var newPaths = paths.ToList();\r\n            var oldModulePath = this.GetModulePaths();\r\n            foreach (var newPath in paths)\r\n            {\r\n                if (oldModulePath.Contains(newPath))\r\n                {\r\n                    newPaths.Remove(newPath);\r\n                }\r\n            }\r\n\r\n            if (newPaths.Any())\r\n            {\r\n                this.SetPSModulePath($\"{string.Join(\";\", oldModulePath)};{string.Join(\";\", newPaths)}\");\r\n            }\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public void CleanupPSModulePath(string path)\r\n        {\r\n            string newModulePath = this.GetVariable<string>(Variables.PSModulePath)\r\n                                       .Replace($\"{path};\", null)\r\n                                       .Replace($\";{path}\", null);\r\n\r\n            this.SetPSModulePath(newModulePath);\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public void SetLocation(PowerShellConfigurationProcessorLocation location, string? customLocation)\r\n        {\r\n            this.location = location;\r\n            if (this.location == PowerShellConfigurationProcessorLocation.Custom)\r\n            {\r\n                if (string.IsNullOrEmpty(customLocation))\r\n                {\r\n                    throw new ArgumentNullException(nameof(customLocation));\r\n                }\r\n\r\n                this.customLocation = customLocation;\r\n            }\r\n        }\r\n\r\n        private bool ValidateModule(ModuleSpecification moduleSpecification)\r\n        {\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, $\"Validating module: {moduleSpecification.Name} ...\");\r\n\r\n            var loadedModule = this.GetImportedModule(moduleSpecification);\r\n            if (loadedModule is not null)\r\n            {\r\n                this.OnDiagnostics(DiagnosticLevel.Verbose, $\" ... module is already imported.\");\r\n                return true;\r\n            }\r\n\r\n            var availableModule = this.GetAvailableModule(moduleSpecification);\r\n            if (availableModule is not null)\r\n            {\r\n                this.OnDiagnostics(DiagnosticLevel.Verbose, $\" ... module is available, importing ...\");\r\n                this.ImportModule(moduleSpecification);\r\n                this.OnDiagnostics(DiagnosticLevel.Verbose, $\" ... module imported.\");\r\n                return true;\r\n            }\r\n\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, $\" ... module not found.\");\r\n            return false;\r\n        }\r\n\r\n        private void OnDiagnostics(DiagnosticLevel level, PowerShell pwsh)\r\n        {\r\n            this.SetProcessorFactory?.OnDiagnostics(level, pwsh);\r\n        }\r\n\r\n        private void OnDiagnostics(DiagnosticLevel level, string message)\r\n        {\r\n            this.SetProcessorFactory?.OnDiagnostics(level, message);\r\n        }\r\n\r\n        private HashSet<string> GetModulePaths()\r\n        {\r\n            return this.GetVariable<string>(Variables.PSModulePath).Split(\";\").ToHashSet<string>();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/PowerShell/ProcessorEnvironments/IProcessorEnvironment.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"IProcessorEnvironment.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.PowerShell.ProcessorEnvironments\r\n{\r\n    using System.Collections.Generic;\r\n    using System.Management.Automation;\r\n    using Microsoft.Management.Configuration.Processor.Helpers;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.DscResourcesInfo;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.Helpers;\r\n    using Microsoft.PowerShell.Commands;\r\n    using Windows.Foundation.Collections;\r\n    using Windows.Security.Cryptography.Certificates;\r\n\r\n    /// <summary>\r\n    /// IProcessorEnvironment. Provides interaction with PowerShell.\r\n    /// </summary>\r\n    internal interface IProcessorEnvironment\r\n    {\r\n        /// <summary>\r\n        /// Gets the runspace.\r\n        /// </summary>\r\n        System.Management.Automation.Runspaces.Runspace Runspace { get; }\r\n\r\n        /// <summary>\r\n        /// Validates the runspace.\r\n        /// </summary>\r\n        void ValidateRunspace();\r\n\r\n        /// <summary>\r\n        /// Gets all DSC resource.\r\n        /// </summary>\r\n        /// <returns>A list with the DSC resource.</returns>\r\n        IReadOnlyList<DscResourceInfoInternal> GetAllDscResources();\r\n\r\n        /// <summary>\r\n        /// Gets all resources in a module.\r\n        /// </summary>\r\n        /// <param name=\"moduleSpecification\">Module specification.</param>\r\n        /// <returns>List of resources.</returns>\r\n        IReadOnlyList<DscResourceInfoInternal> GetDscResourcesInModule(ModuleSpecification moduleSpecification);\r\n\r\n        /// <summary>\r\n        /// Gets a DSC Resource.\r\n        /// </summary>\r\n        /// <param name=\"unitInternal\">Configuration unit internal.</param>\r\n        /// <returns>DSC Resource.</returns>\r\n        DscResourceInfoInternal? GetDscResource(ConfigurationUnitAndModule unitInternal);\r\n\r\n        /// <summary>\r\n        /// Calls Invoke-DscResource -Method Get from this module.\r\n        /// </summary>\r\n        /// <param name=\"settings\">Settings.</param>\r\n        /// <param name=\"name\">Name.</param>\r\n        /// <param name=\"moduleSpecification\">Module specification.</param>\r\n        /// <returns>Properties of resource.</returns>\r\n        ValueSet InvokeGetResource(ValueSet settings, string name, ModuleSpecification? moduleSpecification);\r\n\r\n        /// <summary>\r\n        /// Calls Invoke-DscResource -Method Test from this module.\r\n        /// </summary>\r\n        /// <param name=\"settings\">Settings.</param>\r\n        /// <param name=\"name\">Name.</param>\r\n        /// <param name=\"moduleSpecification\">Module specification.</param>\r\n        /// <returns>Is in desired state.</returns>\r\n        bool InvokeTestResource(ValueSet settings, string name, ModuleSpecification? moduleSpecification);\r\n\r\n        /// <summary>\r\n        /// Calls Invoke-DscResource -Method Set from this module.\r\n        /// </summary>\r\n        /// <param name=\"settings\">Settings.</param>\r\n        /// <param name=\"name\">Name.</param>\r\n        /// <param name=\"moduleSpecification\">Module specification.</param>\r\n        /// <returns>If a reboot is required.</returns>\r\n        bool InvokeSetResource(ValueSet settings, string name, ModuleSpecification? moduleSpecification);\r\n\r\n        /// <summary>\r\n        /// Calls Get-Module with fully qualified name.\r\n        /// </summary>\r\n        /// <param name=\"moduleSpecification\">Module name.</param>\r\n        /// <returns>PSModuleInfo, null if not imported.</returns>\r\n        PSModuleInfo? GetImportedModule(ModuleSpecification moduleSpecification);\r\n\r\n        /// <summary>\r\n        /// Calls Get-Module with the fully qualified name and using ListAvailable.\r\n        /// </summary>\r\n        /// <param name=\"moduleSpecification\">Module specification.</param>\r\n        /// <returns>PSModuleInfo, null if not found.</returns>\r\n        PSModuleInfo? GetAvailableModule(ModuleSpecification moduleSpecification);\r\n\r\n        /// <summary>\r\n        /// Calls Get-Module from a path using ListAvailable.\r\n        /// </summary>\r\n        /// <param name=\"path\">Path.</param>\r\n        /// <returns>The first module returned, null if none.</returns>\r\n        PSModuleInfo? GetAvailableModule(string path);\r\n\r\n        /// <summary>\r\n        /// Calls Import-Module with the fully qualified name.\r\n        /// </summary>\r\n        /// <param name=\"moduleSpecification\">Module specification.</param>\r\n        void ImportModule(ModuleSpecification moduleSpecification);\r\n\r\n        /// <summary>\r\n        /// Calls Import-Module with a file path.\r\n        /// </summary>\r\n        /// <param name=\"path\">Module file path.</param>\r\n        void ImportModule(string path);\r\n\r\n        /// <summary>\r\n        /// Calls Get-InstalledModule.\r\n        /// </summary>\r\n        /// <param name=\"moduleSpecification\">Module specification.</param>\r\n        /// <returns>Module info, null if not installed.</returns>\r\n        PSObject? GetInstalledModule(ModuleSpecification moduleSpecification);\r\n\r\n        /// <summary>\r\n        /// Calls Find-Module.\r\n        /// </summary>\r\n        /// <param name=\"unitInternal\">Configuration unit internal.</param>\r\n        /// <returns>Module info, null if not found.</returns>\r\n        PSObject? FindModule(ConfigurationUnitInternal unitInternal);\r\n\r\n        /// <summary>\r\n        /// Calls Find-DscResource.\r\n        /// </summary>\r\n        /// <param name=\"unitInternal\">Configuration unit internal.</param>\r\n        /// <returns>Dsc Resource info, null if not found.</returns>\r\n        PSObject? FindDscResource(ConfigurationUnitInternal unitInternal);\r\n\r\n        /// <summary>\r\n        /// Calls Save-Module -InputObject object -Path location.\r\n        /// Input object must be the result of Find cmdlets of PowerShellGet.\r\n        /// </summary>\r\n        /// <param name=\"inputObject\">Input object.</param>\r\n        /// <param name=\"location\">Location to save module.</param>\r\n        void SaveModule(PSObject inputObject, string location);\r\n\r\n        /// <summary>\r\n        /// Calls Save-Module.\r\n        /// </summary>\r\n        /// <param name=\"moduleSpecification\">Module specification.</param>\r\n        /// <param name=\"location\">Location to save module.</param>\r\n        void SaveModule(ModuleSpecification moduleSpecification, string location);\r\n\r\n        /// <summary>\r\n        /// Calls Install-Module -InputObject object.\r\n        /// Input object must be the result of Find cmdlets of PowerShellGet.\r\n        /// </summary>\r\n        /// <param name=\"inputObject\">Input object.</param>\r\n        void InstallModule(PSObject inputObject);\r\n\r\n        /// <summary>\r\n        /// Calls Install-Module with a module specification.\r\n        /// </summary>\r\n        /// <param name=\"moduleSpecification\">Module specification.</param>\r\n        void InstallModule(ModuleSpecification moduleSpecification);\r\n\r\n        /// <summary>\r\n        /// Get unique certificates of valid signed files from the specified paths.\r\n        /// </summary>\r\n        /// <param name=\"paths\">Path.</param>\r\n        /// <returns>List with valid signatures.</returns>\r\n        List<Certificate> GetCertsOfValidSignedFiles(string[] paths);\r\n\r\n        /// <summary>\r\n        /// Gets the value of a variable.\r\n        /// </summary>\r\n        /// <typeparam name=\"TType\">Type of the variable.</typeparam>\r\n        /// <param name=\"name\">Name of variable.</param>\r\n        /// <returns>The value of a variable, null if doesn't exist.</returns>\r\n        TType GetVariable<TType>(string name);\r\n\r\n        /// <summary>\r\n        /// Sets a variable with its value.\r\n        /// </summary>\r\n        /// <param name=\"name\">Name of variable.</param>\r\n        /// <param name=\"value\">Value of variable.</param>\r\n        void SetVariable(string name, object value);\r\n\r\n        /// <summary>\r\n        /// Overwrites PSModulePath with the specified path.\r\n        /// </summary>\r\n        /// <param name=\"path\">Path.</param>\r\n        void SetPSModulePath(string path);\r\n\r\n        /// <summary>\r\n        /// Overwrites PSModulePath with the specified paths.\r\n        /// </summary>\r\n        /// <param name=\"paths\">Paths.</param>\r\n        void SetPSModulePaths(IReadOnlyList<string> paths);\r\n\r\n        /// <summary>\r\n        /// Prepends path to the PSModulePath.\r\n        /// </summary>\r\n        /// <param name=\"path\">Path.</param>\r\n        void PrependPSModulePath(string path);\r\n\r\n        /// <summary>\r\n        /// Prepends paths to the PSModulePath.\r\n        /// </summary>\r\n        /// <param name=\"paths\">Paths.</param>\r\n        void PrependPSModulePaths(IReadOnlyList<string> paths);\r\n\r\n        /// <summary>\r\n        /// Append path to the PSModulePath.\r\n        /// </summary>\r\n        /// <param name=\"path\">Path.</param>\r\n        void AppendPSModulePath(string path);\r\n\r\n        /// <summary>\r\n        /// Append paths to the PSModulePath.\r\n        /// </summary>\r\n        /// <param name=\"paths\">Path.</param>\r\n        void AppendPSModulePaths(IReadOnlyList<string> paths);\r\n\r\n        /// <summary>\r\n        /// Removes a path from the module path.\r\n        /// </summary>\r\n        /// <param name=\"path\">Path.</param>\r\n        void CleanupPSModulePath(string path);\r\n\r\n        /// <summary>\r\n        /// Sets the location for installing modules.\r\n        /// </summary>\r\n        /// <param name=\"location\">Location.</param>\r\n        /// <param name=\"customLocation\">Path for custom location.</param>\r\n        void SetLocation(PowerShellConfigurationProcessorLocation location, string? customLocation);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/PowerShell/ProcessorEnvironments/ProcessorEnvironmentFactory.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ProcessorEnvironmentFactory.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.PowerShell.ProcessorEnvironments\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.Management.Automation.Runspaces;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.DscModules;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.Runspaces;\r\n    using Microsoft.PowerShell;\r\n    using Microsoft.PowerShell.Commands;\r\n\r\n    /// <summary>\r\n    /// Factory class to create a processor environment.\r\n    /// </summary>\r\n    internal class ProcessorEnvironmentFactory\r\n    {\r\n        private readonly PowerShellConfigurationProcessorType type;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ProcessorEnvironmentFactory\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"type\">Configuration processor type.</param>\r\n        public ProcessorEnvironmentFactory(PowerShellConfigurationProcessorType type)\r\n        {\r\n            this.type = type;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Create process environment.\r\n        /// </summary>\r\n        /// <param name=\"setProcessorFactory\">Optional processor factory.</param>\r\n        /// <param name=\"policy\">Configuration processor policy.</param>\r\n        /// <returns>IProcessorEnvironment.</returns>\r\n        public IProcessorEnvironment CreateEnvironment(\r\n            PowerShellConfigurationSetProcessorFactory? setProcessorFactory,\r\n            PowerShellConfigurationProcessorPolicy policy)\r\n        {\r\n            IDscModule dscModule = new DscModuleV2();\r\n            ExecutionPolicy executionPolicy = this.GetExecutionPolicy(policy);\r\n\r\n            // The for ConfigurationProcessorType.Default the idea was that since is already running in PowerShell we will\r\n            // have access to the variables in the current runspace, but we can't use that runspace and AFAIK\r\n            // there's not a simple way to simply clone a runspace. If we want to do it, we will need to get the\r\n            // variables from the current runspace and add them here, but maybe some of them are objects that can't\r\n            // handle being used in different runspace. It will also be time consuming and we can't block for creating\r\n            // the create set processor. Even if we could clone it, at this point we are running in a different thread,\r\n            // so there's no default runspace to clone here (aka. PowerShell.Create(RunspaceMode.CurrentRunspace) throws)\r\n            //\r\n            // If we want to somehow support, it might be easier to explicitly ask for the variables that need to be\r\n            // ported. We can add a new property to IConfigurationProcessorFactoryProperties with the variable names\r\n            // and set them here, but if they change they won't get reflected in our runspace (which might be a good thing).\r\n            // The problem with that is that they will need to be defined when the configuration set is opened and it really\r\n            // just makes sense before the ConfigurationSetProcessor gets created. We could add a new IConfigurationSetProcessorProperties\r\n            // Then in PowerShell it can be something like\r\n            // Get-WinGetConfiguration | Add-WinGetConfigurationVariable -Name foo | Start-WinGetConfiguration\r\n            if (this.type == PowerShellConfigurationProcessorType.Hosted ||\r\n                this.type == PowerShellConfigurationProcessorType.Default)\r\n            {\r\n                var initialSessionState = this.CreateInitialSessionState(\r\n                    executionPolicy,\r\n                    new List<ModuleSpecification>\r\n                    {\r\n                        dscModule.ModuleSpecification,\r\n                    });\r\n\r\n                var runspace = RunspaceFactory.CreateRunspace(initialSessionState);\r\n                runspace.Open();\r\n\r\n                return new HostedEnvironment(runspace, this.type, dscModule)\r\n                {\r\n                    SetProcessorFactory = setProcessorFactory,\r\n                };\r\n            }\r\n\r\n            throw new ArgumentException(this.type.ToString());\r\n        }\r\n\r\n        private InitialSessionState CreateInitialSessionState(ExecutionPolicy policy, IReadOnlyList<ModuleSpecification> modules)\r\n        {\r\n            InitialSessionState initialSessionState = InitialSessionState.CreateDefault();\r\n\r\n            // If this call fails importing the module, it won't throw but write to the error output. DSCModule is\r\n            // in charge of verifying that it got loaded correctly and if not, to install it.\r\n            initialSessionState.ImportPSModule(modules);\r\n\r\n            initialSessionState.ExecutionPolicy = policy;\r\n\r\n            return initialSessionState;\r\n        }\r\n\r\n        private ExecutionPolicy GetExecutionPolicy(PowerShellConfigurationProcessorPolicy policy)\r\n        {\r\n            return policy switch\r\n            {\r\n                PowerShellConfigurationProcessorPolicy.Unrestricted => ExecutionPolicy.Unrestricted,\r\n                PowerShellConfigurationProcessorPolicy.RemoteSigned => ExecutionPolicy.RemoteSigned,\r\n                PowerShellConfigurationProcessorPolicy.AllSigned => ExecutionPolicy.AllSigned,\r\n                PowerShellConfigurationProcessorPolicy.Restricted => ExecutionPolicy.Restricted,\r\n                PowerShellConfigurationProcessorPolicy.Bypass => ExecutionPolicy.Bypass,\r\n                _ => throw new InvalidOperationException(),\r\n            };\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/PowerShell/Set/PowerShellConfigurationSetProcessor.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"PowerShellConfigurationSetProcessor.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.PowerShell.Set\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.IO;\r\n    using System.Management.Automation;\r\n    using Microsoft.Management.Configuration.Processor.Exceptions;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.DscResourcesInfo;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.Helpers;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.ProcessorEnvironments;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.Unit;\r\n    using Microsoft.Management.Configuration.Processor.Set;\r\n    using Microsoft.Management.Configuration.Processor.Unit;\r\n    using Windows.Security.Cryptography.Certificates;\r\n\r\n    /// <summary>\r\n    /// IConfigurationSetProcessor implementation using PowerShell DSC v2.\r\n    /// </summary>\r\n    internal sealed partial class PowerShellConfigurationSetProcessor : ConfigurationSetProcessorBase, IConfigurationSetProcessor\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"PowerShellConfigurationSetProcessor\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"processorEnvironment\">The processor environment.</param>\r\n        /// <param name=\"configurationSet\">Configuration set.</param>\r\n        /// <param name=\"isLimitMode\">Whether the set processor should work in limitation mode.</param>\r\n        public PowerShellConfigurationSetProcessor(IProcessorEnvironment processorEnvironment, ConfigurationSet? configurationSet, bool isLimitMode = false)\r\n            : base(configurationSet, isLimitMode)\r\n        {\r\n            this.ProcessorEnvironment = processorEnvironment;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the processor environment.\r\n        /// </summary>\r\n        internal IProcessorEnvironment ProcessorEnvironment { get; }\r\n\r\n        /// <inheritdoc />\r\n        protected override IConfigurationUnitProcessor CreateUnitProcessorInternal(ConfigurationUnit unit)\r\n        {\r\n            var configurationUnitInternal = new ConfigurationUnitAndModule(unit, this.ConfigurationSet?.Path) { UnitTypeIsResourceName = IsUnitTypeResourceName(this.ConfigurationSet?.SchemaVersion) };\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, $\"Creating unit processor for: {configurationUnitInternal.QualifiedName}...\");\r\n\r\n            var dscResourceInfo = this.PrepareUnitForProcessing(configurationUnitInternal);\r\n\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, $\"Using unit from location: {dscResourceInfo.Path}\");\r\n            return new PowerShellConfigurationUnitProcessor(\r\n                this.ProcessorEnvironment,\r\n                new ConfigurationUnitAndResource(configurationUnitInternal, dscResourceInfo),\r\n                this.IsLimitMode)\r\n            { SetProcessorFactory = this.SetProcessorFactory };\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        protected override IConfigurationUnitProcessorDetails? GetUnitProcessorDetailsInternal(ConfigurationUnit unit, ConfigurationUnitDetailFlags detailFlags)\r\n        {\r\n            var unitInternal = new ConfigurationUnitAndModule(unit, this.ConfigurationSet?.Path);\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, $\"Getting unit details [{detailFlags}] for: {unitInternal.QualifiedName}\");\r\n\r\n            // (Local | Download | Load) will all work off of local files, so if any one is an option just use the local module info if found.\r\n            DscResourceInfoInternal? dscResourceInfo = null;\r\n            if (detailFlags.HasFlag(ConfigurationUnitDetailFlags.Local) || detailFlags.HasFlag(ConfigurationUnitDetailFlags.Download) || detailFlags.HasFlag(ConfigurationUnitDetailFlags.Load))\r\n            {\r\n                dscResourceInfo = this.ProcessorEnvironment.GetDscResource(unitInternal);\r\n            }\r\n\r\n            if (dscResourceInfo is not null)\r\n            {\r\n                return this.GetUnitProcessorDetailsLocal(\r\n                    dscResourceInfo.Name,\r\n                    dscResourceInfo,\r\n                    detailFlags.HasFlag(ConfigurationUnitDetailFlags.Load));\r\n            }\r\n\r\n            if (!(detailFlags.HasFlag(ConfigurationUnitDetailFlags.Catalog) || detailFlags.HasFlag(ConfigurationUnitDetailFlags.Download) || detailFlags.HasFlag(ConfigurationUnitDetailFlags.Load)))\r\n            {\r\n                // Not found locally.\r\n                return null;\r\n            }\r\n\r\n            var unitModuleInfo = this.FindUnitModule(unitInternal);\r\n            if (unitModuleInfo is null)\r\n            {\r\n                // Not found in catalog.\r\n                return null;\r\n            }\r\n\r\n            PSObject foundModule = unitModuleInfo.Value.Module;\r\n            string resourceName = unitModuleInfo.Value.ResourceName;\r\n\r\n            dynamic foundModuleInfo = foundModule;\r\n\r\n            if (detailFlags.HasFlag(ConfigurationUnitDetailFlags.Catalog))\r\n            {\r\n                return Factory.CreateUnitProcessorDetails(\r\n                    resourceName,\r\n                    null,\r\n                    null,\r\n                    foundModule,\r\n                    null);\r\n            }\r\n\r\n            if (detailFlags.HasFlag(ConfigurationUnitDetailFlags.Download))\r\n            {\r\n                var tempSavePath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());\r\n                Directory.CreateDirectory(tempSavePath);\r\n                this.ProcessorEnvironment.SaveModule(foundModule, tempSavePath);\r\n\r\n                var moduleInfo = this.ProcessorEnvironment.GetAvailableModule(\r\n                    Path.Combine(tempSavePath, foundModuleInfo.Name));\r\n\r\n                return Factory.CreateUnitProcessorDetails(\r\n                    resourceName,\r\n                    null,\r\n                    moduleInfo,\r\n                    foundModule,\r\n                    this.GetCertificates(moduleInfo));\r\n            }\r\n\r\n            if (detailFlags.HasFlag(ConfigurationUnitDetailFlags.Load))\r\n            {\r\n                this.ProcessorEnvironment.InstallModule(foundModule);\r\n\r\n                dscResourceInfo = this.ProcessorEnvironment.GetDscResource(unitInternal);\r\n\r\n                if (dscResourceInfo is null)\r\n                {\r\n                    // Well, this is awkward.\r\n                    throw new InstallDscResourceException(\r\n                        unitInternal.ResourceName,\r\n                        PowerShellHelpers.CreateModuleSpecification(foundModuleInfo.Name, foundModuleInfo.Version));\r\n                }\r\n\r\n                return this.GetUnitProcessorDetailsLocal(dscResourceInfo.Name, dscResourceInfo, true);\r\n            }\r\n\r\n            return null;\r\n        }\r\n\r\n        private static bool IsUnitTypeResourceName(string? schemaVersion)\r\n        {\r\n            return schemaVersion != null && schemaVersion == \"0.1\";\r\n        }\r\n\r\n        /// <summary>\r\n        /// Finds the module and preferred resource name for processing the configuration unit.\r\n        /// </summary>\r\n        /// <param name=\"unitInternal\">The internal configuration unit.</param>\r\n        /// <returns>A tuple containing the module info and preferred resource name, or null if not found.</returns>\r\n        private (PSObject Module, string ResourceName)? FindUnitModule(ConfigurationUnitAndModule unitInternal)\r\n        {\r\n            PSObject? foundModule = null;\r\n            string resourceName = string.Empty;\r\n\r\n            // If module has been specified, find it and assume that the resource will be within it.\r\n            // Do this first as we do not currently gain much from FindDscResource; if that changes then it can be the primary.\r\n            if (unitInternal.Module != null)\r\n            {\r\n                foundModule = this.ProcessorEnvironment.FindModule(unitInternal);\r\n                if (foundModule != null)\r\n                {\r\n                    resourceName = unitInternal.ResourceName;\r\n                }\r\n            }\r\n            else\r\n            {\r\n                dynamic? foundResource = this.ProcessorEnvironment.FindDscResource(unitInternal);\r\n                if (foundResource != null)\r\n                {\r\n                    foundModule = foundResource.PSGetModuleInfo;\r\n\r\n                    // Hopefully they will never change the properties name. If someone can explain to me\r\n                    // why assign it Name to $_ in Find-DscResource turns into a string in PowerShell but\r\n                    // into a PSObject here that would be nice...\r\n                    resourceName = foundResource.Name.ToString();\r\n                }\r\n            }\r\n\r\n            if (foundModule != null)\r\n            {\r\n                return (foundModule, resourceName);\r\n            }\r\n\r\n            return null;\r\n        }\r\n\r\n        private DscResourceInfoInternal PrepareUnitForProcessing(ConfigurationUnitAndModule unitInternal)\r\n        {\r\n            // Invoke-DscResource makes a call to Get-DscResource which looks at the entire PSModulePath\r\n            // to see if a resource exists. DscResourcesMap is an attempt to try to optimize Get-DscResource\r\n            // by making just one call and get all of them, but it doesn't support minVersion and maxVersion.\r\n            // For now, lets make PowerShell fully figure out which module to use and try to optimize it later.\r\n            // This class will have a private member Lazy<DscResourcesMap> which will be initialized by calling\r\n            // this.ProcessorEnvironment.GetAllDscResources()\r\n            // To improve the performance even more, we will still need Invoke-DscResource to be update to\r\n            // get a DSC resource info object instead of calling Get-DscResource every time.\r\n            var dscResourceInfo = this.ProcessorEnvironment.GetDscResource(unitInternal);\r\n\r\n            if (dscResourceInfo is null)\r\n            {\r\n                var findUnitModuleResult = this.FindUnitModule(unitInternal);\r\n\r\n                if (findUnitModuleResult is null)\r\n                {\r\n                    throw new FindDscResourceNotFoundException(unitInternal.ResourceName, unitInternal.Module);\r\n                }\r\n\r\n                this.ProcessorEnvironment.InstallModule(findUnitModuleResult.Value.Module);\r\n\r\n                // Now we should find it.\r\n                dscResourceInfo = this.ProcessorEnvironment.GetDscResource(unitInternal);\r\n                if (dscResourceInfo is null)\r\n                {\r\n                    throw new InstallDscResourceException(unitInternal.ResourceName, unitInternal.Module);\r\n                }\r\n            }\r\n\r\n            // PowerShell will prompt the user when a module that is downloaded from the internet is imported.\r\n            // For a hosted environment, this will throw an exception because it doesn't support user interaction.\r\n            // In the case we don't import the module here, eventually Invoke-DscResource will fail for class\r\n            // resources because they will call a method on a null obj. It is easier to just fail here.\r\n            // The exception being thrown will have the correct details (user needs to call Unblock-File)\r\n            // instead of the cryptic Invoke with 0 arguments.\r\n            if (!string.IsNullOrEmpty(dscResourceInfo.Path))\r\n            {\r\n                try\r\n                {\r\n                    this.ProcessorEnvironment.ImportModule(dscResourceInfo.Path);\r\n                }\r\n                catch (Exception e)\r\n                {\r\n                    throw new ImportModuleException(dscResourceInfo.ModuleName, e);\r\n                }\r\n            }\r\n\r\n            return dscResourceInfo;\r\n        }\r\n\r\n        private ConfigurationUnitProcessorDetails GetUnitProcessorDetailsLocal(\r\n            string unitName,\r\n            DscResourceInfoInternal dscResourceInfo,\r\n            bool importModule)\r\n        {\r\n            // I'm looking at you resources under C:\\WINDOWS\\system32\\WindowsPowershell\r\n            if (dscResourceInfo.ModuleName is null ||\r\n                dscResourceInfo.Version is null)\r\n            {\r\n                return Factory.CreateUnitProcessorDetails(\r\n                    dscResourceInfo.Name,\r\n                    dscResourceInfo,\r\n                    null,\r\n                    null,\r\n                    null);\r\n            }\r\n\r\n            var module = PowerShellHelpers.CreateModuleSpecification(\r\n                            dscResourceInfo.ModuleName,\r\n                            dscResourceInfo.Version.ToString());\r\n\r\n            // Get-InstalledModule only works for modules installed via PowerShell-Get.\r\n            // There are some properties that can only be obtain by that it so is better to take both.\r\n            var moduleInfo = this.ProcessorEnvironment.GetAvailableModule(module);\r\n            var installedModule = this.ProcessorEnvironment.GetInstalledModule(module);\r\n\r\n            if (importModule)\r\n            {\r\n                this.ProcessorEnvironment.ImportModule(module);\r\n            }\r\n\r\n            return Factory.CreateUnitProcessorDetails(\r\n                dscResourceInfo.Name,\r\n                dscResourceInfo,\r\n                moduleInfo,\r\n                installedModule,\r\n                this.GetCertificates(moduleInfo));\r\n        }\r\n\r\n        private List<Certificate>? GetCertificates(PSModuleInfo? moduleInfo)\r\n        {\r\n            if (moduleInfo is null)\r\n            {\r\n                return null;\r\n            }\r\n\r\n            // TODO: we still need to investigate more here, but lets start with something.\r\n            var paths = new List<string>();\r\n\r\n            var psdPath = Path.Combine(moduleInfo.ModuleBase, $\"{moduleInfo.Name}.psd1\");\r\n            if (File.Exists(psdPath))\r\n            {\r\n                paths.Add(psdPath);\r\n            }\r\n\r\n            var psmPath = Path.Combine(moduleInfo.ModuleBase, $\"{moduleInfo.Name}.psm1\");\r\n            if (File.Exists(psmPath))\r\n            {\r\n                paths.Add(psmPath);\r\n            }\r\n\r\n            return this.ProcessorEnvironment.GetCertsOfValidSignedFiles(paths.ToArray());\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/PowerShell/Unit/PowerShellConfigurationUnitProcessor.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"PowerShellConfigurationUnitProcessor.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.PowerShell.Unit\r\n{\r\n    using Microsoft.Management.Configuration;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.Helpers;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.ProcessorEnvironments;\r\n    using Microsoft.Management.Configuration.Processor.Unit;\r\n    using Windows.Foundation.Collections;\r\n\r\n    /// <summary>\r\n    /// Provides access to a specific configuration unit within the runtime.\r\n    /// </summary>\r\n    internal sealed partial class PowerShellConfigurationUnitProcessor : ConfigurationUnitProcessorBase, IConfigurationUnitProcessor\r\n    {\r\n        private readonly IProcessorEnvironment processorEnvironment;\r\n        private readonly ConfigurationUnitAndResource unitResource;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"PowerShellConfigurationUnitProcessor\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"processorEnvironment\">Processor environment.</param>\r\n        /// <param name=\"unitResource\">UnitResource.</param>\r\n        /// <param name=\"isLimitMode\">Whether it is under limit mode.</param>\r\n        internal PowerShellConfigurationUnitProcessor(IProcessorEnvironment processorEnvironment, ConfigurationUnitAndResource unitResource, bool isLimitMode = false)\r\n            : base(unitResource.UnitInternal, isLimitMode)\r\n        {\r\n            this.processorEnvironment = processorEnvironment;\r\n            this.unitResource = unitResource;\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        protected override ValueSet GetSettingsInternal()\r\n        {\r\n            return this.processorEnvironment.InvokeGetResource(\r\n                this.unitResource.GetSettings(),\r\n                this.unitResource.ResourceName,\r\n                this.unitResource.Module);\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        protected override bool TestSettingsInternal()\r\n        {\r\n            return this.processorEnvironment.InvokeTestResource(\r\n                this.unitResource.GetSettings(),\r\n                this.unitResource.ResourceName,\r\n                this.unitResource.Module);\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        protected override bool ApplySettingsInternal()\r\n        {\r\n            return this.processorEnvironment.InvokeSetResource(\r\n                this.unitResource.GetSettings(),\r\n                this.unitResource.ResourceName,\r\n                this.unitResource.Module);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Properties/AssemblyInfo.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"AssemblyInfo.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nusing System.Runtime.CompilerServices;\r\nusing System.Runtime.Versioning;\r\n\r\n// InternalsVisibleTo specifies that types that are ordinarily visible only within the current\r\n// assembly are visible to a specified assembly. This is only for types and members with internal\r\n// or private protected scope, NOT private. Add any test dll that requires access to internal members.\r\n[assembly: InternalsVisibleTo(\"Microsoft.Management.Configuration.UnitTests\")]\r\n\r\n// Needed to allow us mock internal interfaces.\r\n[assembly: InternalsVisibleTo(\"DynamicProxyGenAssembly2\")]\r\n\r\n#if WinGetCsWinRTEmbedded\r\n// Allow our consuming assemblies access when built embedded.\r\n[assembly: InternalsVisibleTo(\"Microsoft.WinGet.Configuration.Engine\")]\r\n[assembly: InternalsVisibleTo(\"ConfigurationRemotingServer\")]\r\n#endif\r\n\r\n// Forcibly set the target and supported platforms due to the internal build setup.\r\n// Keep in sync with project versions.\r\n[assembly: TargetPlatform(\"Windows10.0.26100.0\")]\r\n[assembly: SupportedOSPlatform(\"Windows10.0.17763.0\")]\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Public/DSCv3ConfigurationSetProcessorFactory.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"DSCv3ConfigurationSetProcessorFactory.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor\r\n{\r\n    using System;\r\n    using System.Collections;\r\n    using System.Collections.Generic;\r\n    using System.Diagnostics.CodeAnalysis;\r\n    using Microsoft.Management.Configuration;\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Helpers;\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Set;\r\n    using Microsoft.Management.Configuration.Processor.Factory;\r\n\r\n    /// <summary>\r\n    /// IConfigurationSetProcessorFactory implementation using DSC v3.\r\n    /// </summary>\r\n    internal sealed partial class DSCv3ConfigurationSetProcessorFactory : ConfigurationSetProcessorFactoryBase, IConfigurationSetProcessorFactory, IDictionary<string, string>\r\n    {\r\n        private const string DscExecutablePathPropertyName = \"DscExecutablePath\";\r\n        private const string FoundDscExecutablePathPropertyName = \"FoundDscExecutablePath\";\r\n        private const string DiagnosticTraceEnabledPropertyName = \"DiagnosticTraceEnabled\";\r\n        private const string FindDscStateMachinePropertyName = \"FindDscStateMachine\";\r\n\r\n        private ProcessorSettings processorSettings = new ();\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"DSCv3ConfigurationSetProcessorFactory\"/> class.\r\n        /// </summary>\r\n        public DSCv3ConfigurationSetProcessorFactory()\r\n        {\r\n            this.processorSettings.DiagnosticsSink = this;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the path to the DSC v3 executable.\r\n        /// </summary>\r\n        public string? DscExecutablePath\r\n        {\r\n            get\r\n            {\r\n                return this.processorSettings.DscExecutablePath;\r\n            }\r\n\r\n            set\r\n            {\r\n                if (this.IsLimitMode())\r\n                {\r\n                    throw new InvalidOperationException(\"Setting DscExecutablePath in limit mode is invalid.\");\r\n                }\r\n\r\n                this.processorSettings.DscExecutablePath = value;\r\n            }\r\n        }\r\n\r\n#if !AICLI_DISABLE_TEST_HOOKS\r\n        /// <summary>\r\n        /// Gets the processor settings; for tests only.\r\n        /// </summary>\r\n        public ProcessorSettings Settings\r\n        {\r\n            get\r\n            {\r\n                return this.processorSettings;\r\n            }\r\n        }\r\n#endif\r\n\r\n        /// <inheritdoc />\r\n        public ICollection<string> Keys => throw new NotImplementedException();\r\n\r\n        /// <inheritdoc />\r\n        public ICollection<string> Values => throw new NotImplementedException();\r\n\r\n        /// <inheritdoc />\r\n        public int Count => throw new NotImplementedException();\r\n\r\n        /// <inheritdoc />\r\n        public bool IsReadOnly => this.IsLimitMode();\r\n\r\n        /// <inheritdoc />\r\n        public string this[string key] { get => this.GetValue(key); set => this.SetValue(key, value); }\r\n\r\n        /// <inheritdoc />\r\n        public void Add(string key, string value)\r\n        {\r\n            this.SetValue(key, value);\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        public void Add(KeyValuePair<string, string> item)\r\n        {\r\n            this.SetValue(item.Key, item.Value);\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        public void Clear()\r\n        {\r\n            throw new NotImplementedException();\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        public bool Contains(KeyValuePair<string, string> item)\r\n        {\r\n            throw new NotImplementedException();\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        public bool ContainsKey(string key)\r\n        {\r\n            switch (key)\r\n            {\r\n                case DscExecutablePathPropertyName:\r\n                    return this.DscExecutablePath != null;\r\n            }\r\n\r\n            return false;\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        public void CopyTo(KeyValuePair<string, string>[] array, int arrayIndex)\r\n        {\r\n            throw new NotImplementedException();\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        public IEnumerator<KeyValuePair<string, string>> GetEnumerator()\r\n        {\r\n            throw new NotImplementedException();\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        public bool Remove(string key)\r\n        {\r\n            throw new NotImplementedException();\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        public bool Remove(KeyValuePair<string, string> item)\r\n        {\r\n            throw new NotImplementedException();\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        public bool TryGetValue(string key, [MaybeNullWhen(false)] out string value)\r\n        {\r\n            value = null;\r\n\r\n            switch (key)\r\n            {\r\n                case DscExecutablePathPropertyName:\r\n                    value = this.DscExecutablePath!;\r\n                    return true;\r\n                case FoundDscExecutablePathPropertyName:\r\n                    value = this.processorSettings.GetFoundDscExecutablePath() !;\r\n                    return true;\r\n                case DiagnosticTraceEnabledPropertyName:\r\n                    value = this.processorSettings.DiagnosticTraceEnabled.ToString();\r\n                    return true;\r\n                case FindDscStateMachinePropertyName:\r\n                    value = this.processorSettings.PumpFindDscStateMachine().ToString();\r\n                    return true;\r\n            }\r\n\r\n            return false;\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        IEnumerator IEnumerable.GetEnumerator()\r\n        {\r\n            return this.GetEnumerator();\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        protected override IConfigurationSetProcessor CreateSetProcessorInternal(ConfigurationSet? set, bool isLimitMode)\r\n        {\r\n            ProcessorSettings processorSettingsCopy = this.processorSettings.Clone();\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, \"Creating set processor with settings:\\n\" + processorSettingsCopy.ToString());\r\n            return new DSCv3ConfigurationSetProcessor(processorSettingsCopy, set, isLimitMode) { SetProcessorFactory = this };\r\n        }\r\n\r\n        private string GetValue(string name)\r\n        {\r\n            if (this.TryGetValue(name, out string? result))\r\n            {\r\n                return result;\r\n            }\r\n\r\n            throw new ArgumentOutOfRangeException($\"Invalid property name: {name}\");\r\n        }\r\n\r\n        private void SetValue(string name, string value)\r\n        {\r\n            switch (name)\r\n            {\r\n                case DscExecutablePathPropertyName:\r\n                    this.DscExecutablePath = value;\r\n                    break;\r\n                case DiagnosticTraceEnabledPropertyName:\r\n                    this.processorSettings.DiagnosticTraceEnabled = bool.Parse(value);\r\n                    break;\r\n                default:\r\n                    throw new ArgumentOutOfRangeException($\"Invalid property name: {name}\");\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Public/IPowerShellConfigurationProcessorFactoryProperties.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"IPowerShellConfigurationProcessorFactoryProperties.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor\r\n{\r\n    using System.Collections.Generic;\r\n\r\n    /// <summary>\r\n    /// Properties for the configuration processor factory.\r\n    /// </summary>\r\n    public interface IPowerShellConfigurationProcessorFactoryProperties\r\n    {\r\n        /// <summary>\r\n        /// Gets or sets the processor type.\r\n        /// </summary>\r\n        PowerShellConfigurationProcessorType ProcessorType { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the additional module paths.\r\n        /// </summary>\r\n        IReadOnlyList<string>? AdditionalModulePaths { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the configuration policy.\r\n        /// </summary>\r\n        PowerShellConfigurationProcessorPolicy Policy { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the module location.\r\n        /// </summary>\r\n        PowerShellConfigurationProcessorLocation Location { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the install module path. Only used for Scope.Custom.\r\n        /// </summary>\r\n        string? CustomLocation { get; set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Public/PathEnvironmentVariableHandler.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"PathEnvironmentVariableHandler.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Helpers\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n\r\n    /// <summary>\r\n    /// Class for handling PATH environment variable.\r\n    /// </summary>\r\n    public static class PathEnvironmentVariableHandler\r\n    {\r\n        private const string PathEnvironmentVariable = \"PATH\";\r\n\r\n        private static readonly object EnvironmentVariableLock = new object();\r\n\r\n        /// <summary>\r\n        /// Gets the lock to read or write PATH environment variable.\r\n        /// </summary>\r\n        public static object Lock\r\n        {\r\n            get { return EnvironmentVariableLock; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Updates the process's PATH environment variable if new paths added.\r\n        /// Only adds new paths since we add to PATH in other code which may not be in the registry.\r\n        /// </summary>\r\n        public static void UpdatePath()\r\n        {\r\n            HashSet<string> paths = new HashSet<string>(Environment.GetEnvironmentVariable(PathEnvironmentVariable)?.Split(';') ?? Array.Empty<string>());\r\n            var originalPathsSize = paths.Count;\r\n\r\n            AddPathsIfNotExist(paths, Environment.GetEnvironmentVariable(PathEnvironmentVariable, EnvironmentVariableTarget.Machine)?.Split(';'));\r\n            AddPathsIfNotExist(paths, Environment.GetEnvironmentVariable(PathEnvironmentVariable, EnvironmentVariableTarget.User)?.Split(';'));\r\n\r\n            if (paths.Count > originalPathsSize)\r\n            {\r\n                lock (Lock)\r\n                {\r\n                    Environment.SetEnvironmentVariable(PathEnvironmentVariable, string.Join(';', paths));\r\n                }\r\n            }\r\n        }\r\n\r\n        // TODO: Currently it always adds new paths to the end. The \"proper\" thing to do would probably be to calculate\r\n        // the full new list of paths (what one would expect to get from a new process launch) and use a line merge algorithm\r\n        // with a strategy that puts the ephemeral entries before the new permanent ones.\r\n#pragma warning disable SA1011 // Closing square brackets should be spaced correctly\r\n        private static void AddPathsIfNotExist(HashSet<string> currentPaths, string[]? paths)\r\n#pragma warning restore SA1011 // Closing square brackets should be spaced correctly\r\n        {\r\n            if (paths is not null)\r\n            {\r\n                foreach (var path in paths)\r\n                {\r\n                    if (!currentPaths.Contains(path))\r\n                    {\r\n                        currentPaths.Add(path);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Public/PowerShellConfigurationProcessorLocation.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"PowerShellConfigurationProcessorLocation.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor\r\n{\r\n    /// <summary>\r\n    /// The location where modules are going to be installed.\r\n    /// </summary>\r\n    public enum PowerShellConfigurationProcessorLocation\r\n    {\r\n        /// <summary>\r\n        /// Current user path.\r\n        /// </summary>\r\n        CurrentUser = 0,\r\n\r\n        /// <summary>\r\n        /// AllUsers path. Requires admin.\r\n        /// </summary>\r\n        AllUsers = 1,\r\n\r\n        /// <summary>\r\n        /// The winget location %LOCALAPPDATA%\\Microsoft\\WinGet\\Configuration\\Modules.\r\n        /// </summary>\r\n        WinGetModulePath = 2,\r\n\r\n        /// <summary>\r\n        /// Custom path.\r\n        /// </summary>\r\n        Custom = 3,\r\n\r\n        /// <summary>\r\n        /// Default.\r\n        /// </summary>\r\n        Default = WinGetModulePath,\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Public/PowerShellConfigurationProcessorPolicy.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"PowerShellConfigurationProcessorPolicy.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor\r\n{\r\n    /// <summary>\r\n    /// Processor policy.\r\n    /// For Processor type Default and Hosted they mean the same as PowerShell ExecutionPolicy.\r\n    /// https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_execution_policies.\r\n    /// </summary>\r\n    public enum PowerShellConfigurationProcessorPolicy\r\n    {\r\n        /// <summary>\r\n        /// Unrestricted.\r\n        /// </summary>\r\n        Unrestricted = 0,\r\n\r\n        /// <summary>\r\n        /// RemoteSigned.\r\n        /// </summary>\r\n        RemoteSigned = 1,\r\n\r\n        /// <summary>\r\n        /// AllSigned.\r\n        /// </summary>\r\n        AllSigned = 2,\r\n\r\n        /// <summary>\r\n        /// Restricted.\r\n        /// </summary>\r\n        Restricted = 3,\r\n\r\n        /// <summary>\r\n        /// Bypass.\r\n        /// </summary>\r\n        Bypass = 4,\r\n\r\n        /// <summary>\r\n        /// Undefined.\r\n        /// </summary>\r\n        Undefined = 5,\r\n\r\n        /// <summary>\r\n        /// Default.\r\n        /// </summary>\r\n        Default = RemoteSigned,\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Public/PowerShellConfigurationProcessorType.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"PowerShellConfigurationProcessorType.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor\r\n{\r\n    /// <summary>\r\n    /// Configuration processor runspace type.\r\n    /// </summary>\r\n    public enum PowerShellConfigurationProcessorType\r\n    {\r\n        /// <summary>\r\n        /// Uses default runspace. Requires to be running in PowerShell. Uses current runspace.\r\n        /// </summary>\r\n        Default,\r\n\r\n        /// <summary>\r\n        /// Creates a new runspace in a hosted environment.\r\n        /// </summary>\r\n        Hosted,\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Public/PowerShellConfigurationSetProcessorFactory.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"PowerShellConfigurationSetProcessorFactory.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.IO;\r\n    using System.Text;\r\n    using Microsoft.Management.Configuration;\r\n    using Microsoft.Management.Configuration.Processor.Factory;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.ProcessorEnvironments;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.Set;\r\n    using Microsoft.Management.Configuration.SetProcessorFactory;\r\n    using static Microsoft.Management.Configuration.Processor.PowerShell.Constants.PowerShellConstants;\r\n\r\n    /// <summary>\r\n    /// IConfigurationSetProcessorFactory implementation using PowerShell DSC v2.\r\n    /// </summary>\r\n#if WinGetCsWinRTEmbedded\r\n    internal\r\n#else\r\n    public\r\n#endif\r\n        sealed partial class PowerShellConfigurationSetProcessorFactory : ConfigurationSetProcessorFactoryBase, IConfigurationSetProcessorFactory, IPowerShellConfigurationProcessorFactoryProperties, IPwshConfigurationSetProcessorFactoryProperties\r\n    {\r\n        // Backing variables for properties that are restricted in limit mode.\r\n        private PowerShellConfigurationProcessorType processorType = PowerShellConfigurationProcessorType.Default;\r\n        private IReadOnlyList<string>? additionalModulePaths;\r\n        private IReadOnlyList<string>? implicitModulePaths;\r\n        private PowerShellConfigurationProcessorPolicy policy = PowerShellConfigurationProcessorPolicy.Default;\r\n        private PowerShellConfigurationProcessorLocation location = PowerShellConfigurationProcessorLocation.Default;\r\n        private string? customLocation;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"PowerShellConfigurationSetProcessorFactory\"/> class.\r\n        /// </summary>\r\n        public PowerShellConfigurationSetProcessorFactory()\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the processor type.\r\n        /// </summary>\r\n        public PowerShellConfigurationProcessorType ProcessorType\r\n        {\r\n            get\r\n            {\r\n                return this.processorType;\r\n            }\r\n\r\n            set\r\n            {\r\n                if (this.IsLimitMode())\r\n                {\r\n                    throw new InvalidOperationException(\"Setting ProcessorType in limit mode is invalid.\");\r\n                }\r\n\r\n                this.processorType = value;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the additional module paths.\r\n        /// </summary>\r\n        public IReadOnlyList<string>? AdditionalModulePaths\r\n        {\r\n            get\r\n            {\r\n                return this.additionalModulePaths;\r\n            }\r\n\r\n            set\r\n            {\r\n                if (this.IsLimitMode())\r\n                {\r\n                    throw new InvalidOperationException(\"Setting AdditionalModulePaths in limit mode is invalid.\");\r\n                }\r\n\r\n                // Create a copy of incoming value\r\n                List<string> newModulePaths = new List<string>();\r\n                if (value != null)\r\n                {\r\n                    foreach (string path in value)\r\n                    {\r\n                        newModulePaths.Add(path);\r\n                    }\r\n                }\r\n\r\n                // Add implicit module paths if applicable\r\n                if (this.implicitModulePaths != null)\r\n                {\r\n                    foreach (string path in this.implicitModulePaths)\r\n                    {\r\n                        if (!newModulePaths.Contains(path))\r\n                        {\r\n                            newModulePaths.Add(path);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                this.additionalModulePaths = newModulePaths;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the implicit module paths. These paths are always included in AdditionalModulePaths.\r\n        /// </summary>\r\n        public IReadOnlyList<string>? ImplicitModulePaths\r\n        {\r\n            get\r\n            {\r\n                return this.implicitModulePaths;\r\n            }\r\n\r\n            set\r\n            {\r\n                if (this.IsLimitMode())\r\n                {\r\n                    throw new InvalidOperationException(\"Setting ImplicitModulePaths in limit mode is invalid.\");\r\n                }\r\n\r\n                this.implicitModulePaths = value;\r\n\r\n                // Apply to additional module paths if applicable.\r\n                if (this.implicitModulePaths != null)\r\n                {\r\n                    List<string> newModulePaths = new List<string>();\r\n                    if (this.additionalModulePaths != null)\r\n                    {\r\n                        foreach (string path in this.additionalModulePaths)\r\n                        {\r\n                            newModulePaths.Add(path);\r\n                        }\r\n                    }\r\n\r\n                    foreach (string path in this.implicitModulePaths)\r\n                    {\r\n                        if (!newModulePaths.Contains(path))\r\n                        {\r\n                            newModulePaths.Add(path);\r\n                        }\r\n                    }\r\n\r\n                    this.additionalModulePaths = newModulePaths;\r\n                }\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the configuration policy.\r\n        /// </summary>\r\n        public PowerShellConfigurationProcessorPolicy Policy\r\n        {\r\n            get\r\n            {\r\n                return this.policy;\r\n            }\r\n\r\n            set\r\n            {\r\n                if (this.IsLimitMode())\r\n                {\r\n                    throw new InvalidOperationException(\"Setting Policy in limit mode is invalid.\");\r\n                }\r\n\r\n                this.policy = value;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the configuration policy.\r\n        /// </summary>\r\n        PwshConfigurationProcessorPolicy IPwshConfigurationSetProcessorFactoryProperties.Policy\r\n        {\r\n            get { return Helpers.TypeHelpers.ToPwshConfigurationProcessorPolicy(this.Policy); }\r\n            set { this.Policy = Helpers.TypeHelpers.ToPowerShellConfigurationProcessorPolicy(value); }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the module location.\r\n        /// </summary>\r\n        public PowerShellConfigurationProcessorLocation Location\r\n        {\r\n            get\r\n            {\r\n                return this.location;\r\n            }\r\n\r\n            set\r\n            {\r\n                if (this.IsLimitMode())\r\n                {\r\n                    throw new InvalidOperationException(\"Setting Location in limit mode is invalid.\");\r\n                }\r\n\r\n                this.location = value;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the module location.\r\n        /// </summary>\r\n        PwshConfigurationProcessorLocation IPwshConfigurationSetProcessorFactoryProperties.Location\r\n        {\r\n            get { return Helpers.TypeHelpers.ToPwshConfigurationProcessorLocation(this.Location); }\r\n            set { this.Location = Helpers.TypeHelpers.ToPowerShellConfigurationProcessorLocation(value); }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the install module path. Only used for Scope = Custom.\r\n        /// </summary>\r\n        public string? CustomLocation\r\n        {\r\n            get\r\n            {\r\n                return this.customLocation;\r\n            }\r\n\r\n            set\r\n            {\r\n                if (this.IsLimitMode())\r\n                {\r\n                    throw new InvalidOperationException(\"Setting CustomLocation in limit mode is invalid.\");\r\n                }\r\n\r\n                this.customLocation = value;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the winget module path.\r\n        /// </summary>\r\n        /// <returns>The winget module path.</returns>\r\n        internal static string GetWinGetModulePath()\r\n        {\r\n            return Path.Combine(\r\n                    Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),\r\n                    @\"Microsoft\\WinGet\\Configuration\\Modules\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Sends diagnostic if appropriate for PowerShell streams.\r\n        /// </summary>\r\n        /// <param name=\"level\">The level of this diagnostic message.</param>\r\n        /// <param name=\"pwsh\">The PowerShell object.</param>\r\n        internal void OnDiagnostics(DiagnosticLevel level, System.Management.Automation.PowerShell pwsh)\r\n        {\r\n            if (this.AreDiagnosticsEnabled() && level >= this.MinimumLevel && pwsh.HadErrors)\r\n            {\r\n                var builder = new StringBuilder();\r\n\r\n                // There are the last commands ran by that PowerShell obj, not all in our session.\r\n                builder.Append(\"PowerShellCommands: \");\r\n                foreach (var c in pwsh.Commands.Commands)\r\n                {\r\n                    builder.Append($\"['{c.CommandText}'\");\r\n                    if (c.Parameters.Count > 0)\r\n                    {\r\n                        builder.Append(\" Parameters: \");\r\n                        foreach (var p in c.Parameters)\r\n                        {\r\n                            builder.Append($\"{p.Name} = '{p.Value}' \");\r\n                        }\r\n\r\n                        builder.Append(\"]\");\r\n                    }\r\n\r\n                    builder.AppendLine();\r\n                }\r\n\r\n                foreach (var error in pwsh.Streams.Error)\r\n                {\r\n                    builder.AppendLine($\"[WriteError] {error}\");\r\n                }\r\n\r\n                this.OnDiagnostics(level, builder.ToString());\r\n            }\r\n        }\r\n\r\n        /// <inheritdoc />\r\n        protected override IConfigurationSetProcessor CreateSetProcessorInternal(ConfigurationSet? set, bool isLimitMode)\r\n        {\r\n            var envFactory = new ProcessorEnvironmentFactory(this.ProcessorType);\r\n            var processorEnvironment = envFactory.CreateEnvironment(\r\n                this,\r\n                this.Policy);\r\n\r\n            if (this.AdditionalModulePaths is not null)\r\n            {\r\n                processorEnvironment.PrependPSModulePaths(this.AdditionalModulePaths);\r\n            }\r\n\r\n            // Always add the winget path.\r\n            var wingetModulePath = GetWinGetModulePath();\r\n            processorEnvironment.PrependPSModulePath(wingetModulePath);\r\n            if (this.Location == PowerShellConfigurationProcessorLocation.WinGetModulePath)\r\n            {\r\n                this.OnDiagnostics(DiagnosticLevel.Verbose, \"Using winget module path\");\r\n                processorEnvironment.SetLocation(PowerShellConfigurationProcessorLocation.Custom, wingetModulePath);\r\n            }\r\n            else if (this.Location == PowerShellConfigurationProcessorLocation.Custom)\r\n            {\r\n                if (string.IsNullOrEmpty(this.CustomLocation))\r\n                {\r\n                    throw new ArgumentNullException(nameof(this.CustomLocation));\r\n                }\r\n\r\n                processorEnvironment.SetLocation(this.Location, this.CustomLocation);\r\n                processorEnvironment.PrependPSModulePath(this.CustomLocation);\r\n            }\r\n            else\r\n            {\r\n                processorEnvironment.SetLocation(this.Location, null);\r\n            }\r\n\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, $\"  Effective module path:\\n{processorEnvironment.GetVariable<string>(Variables.PSModulePath)}\");\r\n\r\n            processorEnvironment.ValidateRunspace();\r\n\r\n            return new PowerShellConfigurationSetProcessor(processorEnvironment, set, isLimitMode) { SetProcessorFactory = this };\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Set/ConfigurationSetProcessorBase.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationSetProcessorBase.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Set\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.Runtime.CompilerServices;\r\n    using Microsoft.Management.Configuration.Processor.Extensions;\r\n    using Microsoft.Management.Configuration.Processor.Factory;\r\n    using Microsoft.Management.Configuration.Processor.Unit;\r\n\r\n    /// <summary>\r\n    /// IConfigurationSetProcessor base implementation.\r\n    /// </summary>\r\n    internal abstract partial class ConfigurationSetProcessorBase\r\n    {\r\n        private readonly ConfigurationSet? configurationSet;\r\n        private List<ConfigurationUnit> limitUnitList = new List<ConfigurationUnit>();\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ConfigurationSetProcessorBase\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"configurationSet\">Configuration set.</param>\r\n        /// <param name=\"isLimitMode\">Whether the set processor should work in limitation mode.</param>\r\n        public ConfigurationSetProcessorBase(ConfigurationSet? configurationSet, bool isLimitMode)\r\n        {\r\n            this.configurationSet = configurationSet;\r\n            this.IsLimitMode = isLimitMode;\r\n\r\n            // In limit mode, configurationSet is the limitation set to be used. It cannot be null.\r\n            if (this.IsLimitMode)\r\n            {\r\n                if (this.configurationSet == null)\r\n                {\r\n                    throw new ArgumentNullException(nameof(configurationSet), \"configurationSet is required in limit mode.\");\r\n                }\r\n\r\n                foreach (var unit in this.configurationSet.Units)\r\n                {\r\n                    this.limitUnitList.Add(unit);\r\n                }\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or initializes the set processor factory.\r\n        /// </summary>\r\n        internal ConfigurationSetProcessorFactoryBase? SetProcessorFactory { get; init; }\r\n\r\n        /// <summary>\r\n        /// Gets a value indicating whether the set processor is running in limit mode.\r\n        /// </summary>\r\n        internal bool IsLimitMode { get; private set; }\r\n\r\n        /// <summary>\r\n        /// Gets the configuration set for this processor.\r\n        /// </summary>\r\n        protected ConfigurationSet? ConfigurationSet\r\n        {\r\n            get { return this.configurationSet; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates a configuration unit processor for the given unit.\r\n        /// </summary>\r\n        /// <param name=\"incomingUnit\">Configuration unit.</param>\r\n        /// <returns>A configuration unit processor.</returns>\r\n        public IConfigurationUnitProcessor CreateUnitProcessor(ConfigurationUnit incomingUnit)\r\n        {\r\n            try\r\n            {\r\n                this.OnDiagnostics(DiagnosticLevel.Informational, $\"GetUnitProcessorDetails is running in limit mode: {this.IsLimitMode}.\");\r\n\r\n                // CreateUnitProcessor can only be called once on each configuration unit in limit mode.\r\n                var unit = this.GetConfigurationUnit(incomingUnit, true);\r\n\r\n                IConfigurationUnitProcessor result = this.CreateUnitProcessorInternal(unit);\r\n\r\n                this.OnDiagnostics(DiagnosticLevel.Verbose, \"... done creating unit processor.\");\r\n\r\n                return result;\r\n            }\r\n            catch (Exception ex)\r\n            {\r\n                this.OnDiagnostics(DiagnosticLevel.Error, ex.ToString());\r\n                throw;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the configuration unit processor details for the given unit.\r\n        /// </summary>\r\n        /// <param name=\"incomingUnit\">Configuration unit.</param>\r\n        /// <param name=\"detailFlags\">Detail flags.</param>\r\n        /// <returns>Configuration unit processor details.</returns>\r\n        public IConfigurationUnitProcessorDetails? GetUnitProcessorDetails(ConfigurationUnit incomingUnit, ConfigurationUnitDetailFlags detailFlags)\r\n        {\r\n            try\r\n            {\r\n                this.OnDiagnostics(DiagnosticLevel.Informational, $\"GetUnitProcessorDetails is running in limit mode: {this.IsLimitMode}.\");\r\n\r\n                // GetUnitProcessorDetails can be invoked multiple times on each configuration unit in limit mode.\r\n                var unit = this.GetConfigurationUnit(incomingUnit);\r\n\r\n                return this.GetUnitProcessorDetailsInternal(unit, detailFlags);\r\n            }\r\n            catch (Exception ex)\r\n            {\r\n                this.OnDiagnostics(DiagnosticLevel.Error, ex.ToString());\r\n                throw;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets all configuration units for the given unit type.\r\n        /// Returned units may be of types other than the one passed in.\r\n        /// </summary>\r\n        /// <param name=\"findOptions\">Find unit processors options.</param>\r\n        /// <returns>A list of unit processor details.</returns>\r\n        public IList<IConfigurationUnitProcessorDetails> FindUnitProcessors(FindUnitProcessorsOptions findOptions)\r\n        {\r\n            try\r\n            {\r\n                this.OnDiagnostics(DiagnosticLevel.Verbose, $\"Invoking `FindUnitProcessors` ...\");\r\n\r\n                return this.FindUnitProcessorsInternal(findOptions);\r\n            }\r\n            catch (Exception ex)\r\n            {\r\n                this.OnDiagnostics(DiagnosticLevel.Error, ex.ToString());\r\n                throw;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates a configuration unit processor for the given unit.\r\n        /// </summary>\r\n        /// <param name=\"unit\">Configuration unit.</param>\r\n        /// <returns>A configuration unit processor.</returns>\r\n        protected abstract IConfigurationUnitProcessor CreateUnitProcessorInternal(ConfigurationUnit unit);\r\n\r\n        /// <summary>\r\n        /// Gets the configuration unit processor details for the given unit.\r\n        /// </summary>\r\n        /// <param name=\"unit\">Configuration unit.</param>\r\n        /// <param name=\"detailFlags\">Detail flags.</param>\r\n        /// <returns>Configuration unit processor details.</returns>\r\n        protected abstract IConfigurationUnitProcessorDetails? GetUnitProcessorDetailsInternal(ConfigurationUnit unit, ConfigurationUnitDetailFlags detailFlags);\r\n\r\n        /// <summary>\r\n        /// Finds unit processors based on the input FindUnitProcessorsOptions.\r\n        /// Derive from IFindUnitProcessorsSetProcessor and implement an override to support this.\r\n        /// </summary>\r\n        /// <param name=\"findOptions\">Find unit processors options.</param>\r\n        /// <returns>A list of unit processor details.</returns>\r\n        protected virtual IList<IConfigurationUnitProcessorDetails> FindUnitProcessorsInternal(FindUnitProcessorsOptions findOptions)\r\n        {\r\n            throw new NotImplementedException(\"Configuration set processor did not implement FindUnitProcessorsInternal.\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Sends diagnostics to factory.\r\n        /// </summary>\r\n        /// <param name=\"level\">The level of this diagnostic message.</param>\r\n        /// <param name=\"message\">The diagnostic message.</param>\r\n        protected void OnDiagnostics(DiagnosticLevel level, string message)\r\n        {\r\n            this.SetProcessorFactory?.OnDiagnostics(level, message);\r\n        }\r\n\r\n        private static bool ConfigurationUnitEquals(ConfigurationUnit first, ConfigurationUnit second)\r\n        {\r\n            var firstIdentifier = first.Identifier;\r\n            var firstIntent = first.Intent;\r\n            var firstType = first.Type;\r\n            var secondIdentifier = second.Identifier;\r\n            var secondType = second.Type;\r\n            var secondIntent = second.Intent;\r\n\r\n            if (firstIdentifier != secondIdentifier ||\r\n                firstType != secondType ||\r\n                firstIntent != secondIntent)\r\n            {\r\n                return false;\r\n            }\r\n\r\n            var firstEnvironment = first.Environment;\r\n            var secondEnvironment = second.Environment;\r\n            if (firstEnvironment.Context != secondEnvironment.Context ||\r\n                firstEnvironment.ProcessorIdentifier != secondEnvironment.ProcessorIdentifier ||\r\n                !firstEnvironment.ProcessorProperties.ContentEquals(secondEnvironment.ProcessorProperties))\r\n            {\r\n                return false;\r\n            }\r\n\r\n            if (!first.Settings.ContentEquals(second.Settings))\r\n            {\r\n                return false;\r\n            }\r\n\r\n            if (!first.Metadata.ContentEquals(second.Metadata))\r\n            {\r\n                return false;\r\n            }\r\n\r\n            // Note: Consider group units logic when group units are supported.\r\n            return true;\r\n        }\r\n\r\n        [MethodImpl(MethodImplOptions.Synchronized)]\r\n        private ConfigurationUnit GetConfigurationUnit(ConfigurationUnit incomingUnit, bool useLimitList = false)\r\n        {\r\n            if (this.IsLimitMode)\r\n            {\r\n                if (this.configurationSet == null)\r\n                {\r\n                    throw new InvalidOperationException(\"Configuration set should not be null in limit mode.\");\r\n                }\r\n\r\n                var unitList = useLimitList ? this.limitUnitList : this.configurationSet.Units;\r\n\r\n                for (int i = 0; i < unitList.Count; i++)\r\n                {\r\n                    var unit = unitList[i];\r\n                    if (ConfigurationUnitEquals(incomingUnit, unit))\r\n                    {\r\n                        if (useLimitList)\r\n                        {\r\n                            this.limitUnitList.RemoveAt(i);\r\n                        }\r\n\r\n                        return unit;\r\n                    }\r\n\r\n                    // Note: Consider group units logic when group units are supported.\r\n                }\r\n\r\n                this.OnDiagnostics(DiagnosticLevel.Error, \"Configuration unit not found in limit mode.\");\r\n                throw new InvalidOperationException(\"Configuration unit not found in limit mode.\");\r\n            }\r\n            else\r\n            {\r\n                return incomingUnit;\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Unit/ApplySettingsResult.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ApplySettingsResult.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Unit\r\n{\r\n    using Microsoft.Management.Configuration;\r\n\r\n    /// <summary>\r\n    /// Implements IApplySettingsResult.\r\n    /// </summary>\r\n    internal sealed partial class ApplySettingsResult : IApplySettingsResult\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ApplySettingsResult\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"unit\">The configuration unit that the result is for.</param>\r\n        public ApplySettingsResult(ConfigurationUnit unit)\r\n        {\r\n            this.Unit = unit;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the configuration unit that the result is for.\r\n        /// </summary>\r\n        public ConfigurationUnit Unit { get; private set; }\r\n\r\n        /// <inheritdoc/>\r\n        public IConfigurationUnitResultInformation ResultInformation\r\n        {\r\n            get { return this.InternalResult; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the implementation object for ResultInformation.\r\n        /// </summary>\r\n        public ConfigurationUnitResultInformation InternalResult { get; } = new ConfigurationUnitResultInformation();\r\n\r\n        /// <inheritdoc/>\r\n        public bool RebootRequired { get; internal set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Unit/ConfigurationUnitProcessorBase.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationUnitProcessorBase.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Unit\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.ComponentModel;\r\n    using System.Runtime.CompilerServices;\r\n    using Microsoft.Management.Configuration;\r\n    using Microsoft.Management.Configuration.Processor.Exceptions;\r\n    using Microsoft.Management.Configuration.Processor.Extensions;\r\n    using Microsoft.Management.Configuration.Processor.Factory;\r\n    using Microsoft.Management.Configuration.Processor.Helpers;\r\n    using Windows.Foundation.Collections;\r\n\r\n    /// <summary>\r\n    /// IConfigurationUnitProcessor base implementation.\r\n    /// </summary>\r\n    internal abstract partial class ConfigurationUnitProcessorBase\r\n    {\r\n        private readonly ConfigurationUnitInternal unitInternal;\r\n        private readonly bool isLimitMode;\r\n\r\n        private bool isTestInvoked = false;\r\n        private bool isApplyInvoked = false;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ConfigurationUnitProcessorBase\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"unitInternal\">UnitInternal.</param>\r\n        /// <param name=\"isLimitMode\">Whether it is under limit mode.</param>\r\n        internal ConfigurationUnitProcessorBase(ConfigurationUnitInternal unitInternal, bool isLimitMode)\r\n        {\r\n            this.unitInternal = unitInternal;\r\n            this.isLimitMode = isLimitMode;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the configuration unit that the processor was created for.\r\n        /// </summary>\r\n        public ConfigurationUnit Unit => this.unitInternal.Unit;\r\n\r\n        /// <summary>\r\n        /// Gets or initializes the set processor factory.\r\n        /// </summary>\r\n        internal ConfigurationSetProcessorFactoryBase? SetProcessorFactory { get; init; }\r\n\r\n        /// <summary>\r\n        /// Gets the internal configuration unit.\r\n        /// </summary>\r\n        protected ConfigurationUnitInternal UnitInternal => this.unitInternal;\r\n\r\n        /// <summary>\r\n        /// Gets the current system state for the configuration unit.\r\n        /// Calls Get on the DSC resource.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"IGetSettingsResult\"/>.</returns>\r\n        public IGetSettingsResult GetSettings()\r\n        {\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, $\"Invoking `Get` for resource: {this.unitInternal.QualifiedName}...\");\r\n\r\n            this.CheckLimitMode(ConfigurationUnitIntent.Inform);\r\n            var result = new GetSettingsResult(this.Unit);\r\n\r\n            try\r\n            {\r\n                result.Settings = this.GetSettingsInternal();\r\n            }\r\n            catch (Exception e)\r\n            {\r\n                this.ExtractExceptionInformation(e, result.InternalResult);\r\n            }\r\n\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, $\"... done invoking `Get`.\");\r\n            return result;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Determines if the system is already in the state described by the configuration unit.\r\n        /// Calls Test on the DSC resource.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"ITestSettingsResult\"/>.</returns>\r\n        public ITestSettingsResult TestSettings()\r\n        {\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, $\"Invoking `Test` for resource: {this.unitInternal.QualifiedName}...\");\r\n\r\n            if (this.Unit.Intent == ConfigurationUnitIntent.Inform)\r\n            {\r\n                this.OnDiagnostics(DiagnosticLevel.Error, \"`Test` should not be called on a unit with intent of `Inform`\");\r\n                throw new NotSupportedException();\r\n            }\r\n\r\n            this.CheckLimitMode(ConfigurationUnitIntent.Assert);\r\n            var result = new TestSettingsResult(this.Unit);\r\n            result.TestResult = ConfigurationTestResult.Failed;\r\n            try\r\n            {\r\n                bool testResult = this.TestSettingsInternal();\r\n\r\n                result.TestResult = testResult ? ConfigurationTestResult.Positive : ConfigurationTestResult.Negative;\r\n            }\r\n            catch (Exception e)\r\n            {\r\n                this.ExtractExceptionInformation(e, result.InternalResult);\r\n            }\r\n\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, $\"... done invoking `Test`.\");\r\n            return result;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Applies the state described in the configuration unit.\r\n        /// Calls Set in the DSC resource.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"IApplySettingsResult\"/>.</returns>\r\n        public IApplySettingsResult ApplySettings()\r\n        {\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, $\"Invoking `Apply` for resource: {this.unitInternal.QualifiedName}...\");\r\n\r\n            if (this.Unit.Intent == ConfigurationUnitIntent.Inform ||\r\n                this.Unit.Intent == ConfigurationUnitIntent.Assert)\r\n            {\r\n                this.OnDiagnostics(DiagnosticLevel.Error, $\"`Apply` should not be called on a unit with intent of `{this.Unit.Intent}`\");\r\n                throw new NotSupportedException();\r\n            }\r\n\r\n            this.CheckLimitMode(ConfigurationUnitIntent.Apply);\r\n            var result = new ApplySettingsResult(this.Unit);\r\n            try\r\n            {\r\n                result.RebootRequired = this.ApplySettingsInternal();\r\n            }\r\n            catch (Exception e)\r\n            {\r\n                this.ExtractExceptionInformation(e, result.InternalResult);\r\n            }\r\n\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, $\"... done invoking `Apply`.\");\r\n            return result;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the current settings for all the instances of a configuration unit.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"IGetAllSettingsResult\"/>.</returns>\r\n        public IGetAllSettingsResult GetAllSettings()\r\n        {\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, $\"Invoking `GetAllSettings` for resource: {this.unitInternal.QualifiedName}...\");\r\n\r\n            this.CheckLimitMode(ConfigurationUnitIntent.Inform);\r\n            var result = new GetAllSettingsResult(this.Unit);\r\n\r\n            try\r\n            {\r\n                result.Settings = this.GetAllSettingsInternal();\r\n            }\r\n            catch (Exception e)\r\n            {\r\n                this.ExtractExceptionInformation(e, result.InternalResult);\r\n            }\r\n\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, $\"... done invoking `GetAllSettings`.\");\r\n            return result;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets all configuration units for the given unit type.\r\n        /// Returned units may be of types other than the one passed in.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"IGetAllUnitsResult\"/>.</returns>\r\n        public IGetAllUnitsResult GetAllUnits()\r\n        {\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, $\"Invoking `GetAllUnits` for resource: {this.unitInternal.QualifiedName}...\");\r\n\r\n            this.CheckLimitMode(ConfigurationUnitIntent.Inform);\r\n            var result = new GetAllUnitsResult(this.Unit);\r\n\r\n            try\r\n            {\r\n                result.Units = this.GetAllUnitsInternal();\r\n            }\r\n            catch (Exception e)\r\n            {\r\n                this.ExtractExceptionInformation(e, result.InternalResult);\r\n            }\r\n\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, $\"... done invoking `GetAllUnits`.\");\r\n            return result;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the current settings.\r\n        /// </summary>\r\n        /// <returns>The current settings.</returns>\r\n        protected abstract ValueSet GetSettingsInternal();\r\n\r\n        /// <summary>\r\n        /// Tests the current settings.\r\n        /// </summary>\r\n        /// <returns>A boolean indicating whether the settings are in the desired state.</returns>\r\n        protected abstract bool TestSettingsInternal();\r\n\r\n        /// <summary>\r\n        /// Applies the desired settings.\r\n        /// </summary>\r\n        /// <returns>A boolean indicating whether a reboot is required.</returns>\r\n        protected abstract bool ApplySettingsInternal();\r\n\r\n        /// <summary>\r\n        /// Gets the current settings for all the instances of a configuration unit.\r\n        /// Derive from IGetAllSettingsConfigurationUnitProcessor and implement an override to support this.\r\n        /// </summary>\r\n        /// <returns>The settings as ValueSets.</returns>\r\n        protected virtual IList<ValueSet>? GetAllSettingsInternal()\r\n        {\r\n            throw new NotImplementedException(\"Configuration unit processor did not implement GetAllSettingsInternal.\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets all configuration units for the given unit type.\r\n        /// Returned units may be of types other than the one passed in.\r\n        /// Derive from IGetAllUnitsConfigurationUnitProcessor and implement an override to support this.\r\n        /// </summary>\r\n        /// <returns>The configuration units.</returns>\r\n        protected virtual IList<ConfigurationUnit>? GetAllUnitsInternal()\r\n        {\r\n            throw new NotImplementedException(\"Configuration unit processor did not implement GetAllUnitsInternal.\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Sends diagnostics if appropriate.\r\n        /// </summary>\r\n        /// <param name=\"level\">The level of this diagnostic message.</param>\r\n        /// <param name=\"message\">The diagnostic message.</param>\r\n        protected void OnDiagnostics(DiagnosticLevel level, string message)\r\n        {\r\n            this.SetProcessorFactory?.OnDiagnostics(level, message);\r\n        }\r\n\r\n        private void ExtractExceptionInformation(Exception e, ConfigurationUnitResultInformation resultInformation)\r\n        {\r\n            this.OnDiagnostics(DiagnosticLevel.Verbose, e.ToString());\r\n\r\n            IConfigurationUnitResultException? configurationUnitResultException = e as IConfigurationUnitResultException;\r\n            if (configurationUnitResultException != null)\r\n            {\r\n                resultInformation.ResultCode = e;\r\n                resultInformation.Description = configurationUnitResultException.Description;\r\n                resultInformation.Details = configurationUnitResultException.Details;\r\n                resultInformation.ResultSource = configurationUnitResultException.ResultSource;\r\n            }\r\n            else\r\n            {\r\n                var inner = e.GetMostInnerException();\r\n                resultInformation.ResultCode = inner;\r\n                resultInformation.Description = e.Message;\r\n                resultInformation.Details = e.ToString();\r\n                resultInformation.ResultSource = ConfigurationUnitResultSource.Internal;\r\n            }\r\n        }\r\n\r\n        [MethodImpl(MethodImplOptions.Synchronized)]\r\n        private void CheckLimitMode(ConfigurationUnitIntent intent)\r\n        {\r\n            if (!this.isLimitMode)\r\n            {\r\n                return;\r\n            }\r\n\r\n            if (intent == ConfigurationUnitIntent.Unknown)\r\n            {\r\n                throw new InvalidEnumArgumentException(nameof(ConfigurationUnitIntent.Unknown));\r\n            }\r\n\r\n            if (intent == ConfigurationUnitIntent.Assert)\r\n            {\r\n                if (this.isTestInvoked)\r\n                {\r\n                    this.OnDiagnostics(DiagnosticLevel.Error, \"TestSettings is already invoked in limit mode.\");\r\n                    throw new InvalidOperationException(\"TestSettings is already invoked in limit mode.\");\r\n                }\r\n                else\r\n                {\r\n                    this.isTestInvoked = true;\r\n                }\r\n            }\r\n\r\n            if (intent == ConfigurationUnitIntent.Apply)\r\n            {\r\n                if (this.isApplyInvoked)\r\n                {\r\n                    this.OnDiagnostics(DiagnosticLevel.Error, \"ApplySettings is already invoked in limit mode.\");\r\n                    throw new InvalidOperationException(\"ApplySettings is already invoked in limit mode.\");\r\n                }\r\n                else\r\n                {\r\n                    this.isApplyInvoked = true;\r\n                }\r\n            }\r\n\r\n            // Get is always allowed now.\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Unit/ConfigurationUnitProcessorDetails.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationUnitProcessorDetails.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Unit\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using Microsoft.Management.Configuration;\r\n\r\n    /// <summary>\r\n    /// Provides information for a specific configuration unit within the runtime.\r\n    /// </summary>\r\n    internal sealed partial class ConfigurationUnitProcessorDetails : IConfigurationUnitProcessorDetails, IConfigurationUnitProcessorDetails2, IConfigurationUnitProcessorDetails3\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ConfigurationUnitProcessorDetails\"/> class.\r\n        /// </summary>\r\n        public ConfigurationUnitProcessorDetails()\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the name of the unit of configuration.\r\n        /// </summary>\r\n        required public string UnitType { get; internal set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the description of the unit of configuration.\r\n        /// </summary>\r\n        public string? UnitDescription { get; internal set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the URI of the documentation for the unit of configuration.\r\n        /// </summary>\r\n        public Uri? UnitDocumentationUri { get; internal set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the URI of the icon for the unit of configuration.\r\n        /// </summary>\r\n        public Uri? UnitIconUri { get; internal set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the name of the module containing the unit of configuration.\r\n        /// </summary>\r\n        public string? ModuleName { get; internal set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the type of the module containing the unit of configuration.\r\n        /// </summary>\r\n        public string? ModuleType { get; internal set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the source of the module containing the unit of configuration.\r\n        /// </summary>\r\n        public string? ModuleSource { get; internal set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the description of the module containing the unit of configuration.\r\n        /// </summary>\r\n        public string? ModuleDescription { get; internal set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the URI of the documentation for the module containing the unit of configuration.\r\n        /// </summary>\r\n        public Uri? ModuleDocumentationUri { get; internal set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the URI for the published module containing the unit of configuration.\r\n        /// </summary>\r\n        public Uri? PublishedModuleUri { get; internal set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the version of the module containing the unit of configuration.\r\n        /// </summary>\r\n        public string? Version { get; internal set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the publishing date of the module containing the unit of configuration.\r\n        /// </summary>\r\n        public DateTimeOffset PublishedDate { get; internal set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether the module is already present on the system.\r\n        /// </summary>\r\n        public bool IsLocal { get; internal set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the author of the module containing the unit of configuration.\r\n        /// </summary>\r\n        public string? Author { get; internal set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the publisher of the module containing the unit of configuration.\r\n        /// </summary>\r\n        public string? Publisher { get; internal set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the signing certificate of the module files containing the unit of configuration.\r\n        /// </summary>\r\n        public IReadOnlyList<object>? SigningInformation { get; internal set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the settings information for the unit of configuration.\r\n        /// </summary>\r\n        public IReadOnlyList<IConfigurationUnitSettingDetails>? Settings { get; internal set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether the module comes from a public repository.\r\n        /// </summary>\r\n        public bool IsPublic { get; internal set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether this resource is a group.\r\n        /// </summary>\r\n        public bool IsGroup { get; internal set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the path of the resource.\r\n        /// </summary>\r\n        public string? Path { get; internal set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Unit/ConfigurationUnitResultInformation.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationUnitResultInformation.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Unit\r\n{\r\n    using System;\r\n    using Microsoft.Management.Configuration;\r\n\r\n    /// <summary>\r\n    /// Implements IConfigurationUnitResultInformation.\r\n    /// </summary>\r\n    internal sealed partial class ConfigurationUnitResultInformation : IConfigurationUnitResultInformation\r\n    {\r\n        /// <inheritdoc/>\r\n        public string? Description { get; internal set; }\r\n\r\n        /// <inheritdoc/>\r\n        public string? Details { get; internal set; }\r\n\r\n        /// <inheritdoc/>\r\n        public Exception? ResultCode { get; internal set; }\r\n\r\n        /// <inheritdoc/>\r\n        public ConfigurationUnitResultSource ResultSource { get; internal set; } = ConfigurationUnitResultSource.None;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Unit/ConfigurationUnitSettingDetails.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationUnitSettingDetails.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Unit\r\n{\r\n    using Microsoft.Management.Configuration;\r\n\r\n    /// <summary>\r\n    /// Provides information for a specific configuration unit setting.\r\n    /// </summary>\r\n    internal sealed partial class ConfigurationUnitSettingDetails : IConfigurationUnitSettingDetails\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ConfigurationUnitSettingDetails\"/> class.\r\n        /// </summary>\r\n        public ConfigurationUnitSettingDetails()\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the name of the setting.\r\n        /// </summary>\r\n        required public string Identifier { get; init; }\r\n\r\n        /// <summary>\r\n        /// Gets the title of the setting.\r\n        /// </summary>\r\n        public string Title { get; init; } = string.Empty;\r\n\r\n        /// <summary>\r\n        /// Gets the description of the setting.\r\n        /// </summary>\r\n        public string Description { get; init; } = string.Empty;\r\n\r\n        /// <summary>\r\n        /// Gets a value indicating whether the setting is a key. This is used to determine if different settings are in conflict.\r\n        /// </summary>\r\n        public bool IsKey { get; init; } = false;\r\n\r\n        /// <summary>\r\n        /// Gets a value indicating whether a non-empty value for the setting is required.\r\n        /// </summary>\r\n        public bool IsRequired { get; init; } = false;\r\n\r\n        /// <summary>\r\n        /// Gets a value indicating whether the setting should be serialized in order to be applied on another system.\r\n        /// </summary>\r\n        public bool IsInformational { get; init; } = false;\r\n\r\n        /// <summary>\r\n        /// Gets the data type for the value of this setting.\r\n        /// </summary>\r\n        public Windows.Foundation.PropertyType Type { get; init; } = Windows.Foundation.PropertyType.Inspectable;\r\n\r\n        /// <summary>\r\n        /// Gets the semantics to be used for this setting. The goal is to enable richer conflict detection and authoring\r\n        /// scenarios by having a deeper understanding of this value than \"String\".\r\n        /// </summary>\r\n        public string Schema { get; init; } = string.Empty;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Unit/GetAllSettingsResult.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"GetAllSettingsResult.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Unit\r\n{\r\n    using System.Collections.Generic;\r\n    using Microsoft.Management.Configuration;\r\n    using Windows.Foundation.Collections;\r\n\r\n    /// <summary>\r\n    /// Implements IGetAllSettingsResult.\r\n    /// </summary>\r\n    internal partial class GetAllSettingsResult : IGetAllSettingsResult\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"GetAllSettingsResult\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"unit\">The configuration unit that the result is for.</param>\r\n        public GetAllSettingsResult(ConfigurationUnit unit)\r\n        {\r\n            this.Unit = unit;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the configuration unit that the result is for.\r\n        /// </summary>\r\n        public ConfigurationUnit Unit { get; private set; }\r\n\r\n        /// <inheritdoc/>\r\n        public IConfigurationUnitResultInformation ResultInformation\r\n        {\r\n            get { return this.InternalResult; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the implementation object for ResultInformation.\r\n        /// </summary>\r\n        public ConfigurationUnitResultInformation InternalResult { get; } = new ConfigurationUnitResultInformation();\r\n\r\n        /// <inheritdoc/>\r\n        public IList<ValueSet>? Settings { get; internal set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Unit/GetAllUnitsResult.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"GetAllUnitsResult.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Unit\r\n{\r\n    using System.Collections.Generic;\r\n    using Microsoft.Management.Configuration;\r\n    using Windows.Foundation.Collections;\r\n\r\n    /// <summary>\r\n    /// Implements IGetAllUnitsResult.\r\n    /// </summary>\r\n    internal partial class GetAllUnitsResult : IGetAllUnitsResult\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"GetAllUnitsResult\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"unit\">The configuration unit that the result is for.</param>\r\n        public GetAllUnitsResult(ConfigurationUnit unit)\r\n        {\r\n            this.Unit = unit;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the configuration unit that the result is for.\r\n        /// </summary>\r\n        public ConfigurationUnit Unit { get; private set; }\r\n\r\n        /// <inheritdoc/>\r\n        public IConfigurationUnitResultInformation ResultInformation\r\n        {\r\n            get { return this.InternalResult; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the implementation object for ResultInformation.\r\n        /// </summary>\r\n        public ConfigurationUnitResultInformation InternalResult { get; } = new ConfigurationUnitResultInformation();\r\n\r\n        /// <inheritdoc/>\r\n        public IList<ConfigurationUnit>? Units { get; internal set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Unit/GetSettingsResult.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"GetSettingsResult.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Unit\r\n{\r\n    using Microsoft.Management.Configuration;\r\n    using Windows.Foundation.Collections;\r\n\r\n    /// <summary>\r\n    /// Implements IGetSettingsResult.\r\n    /// </summary>\r\n    internal sealed partial class GetSettingsResult : IGetSettingsResult\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"GetSettingsResult\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"unit\">The configuration unit that the result is for.</param>\r\n        public GetSettingsResult(ConfigurationUnit unit)\r\n        {\r\n            this.Unit = unit;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the configuration unit that the result is for.\r\n        /// </summary>\r\n        public ConfigurationUnit Unit { get; private set; }\r\n\r\n        /// <inheritdoc/>\r\n        public IConfigurationUnitResultInformation ResultInformation\r\n        {\r\n            get { return this.InternalResult; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the implementation object for ResultInformation.\r\n        /// </summary>\r\n        public ConfigurationUnitResultInformation InternalResult { get; } = new ConfigurationUnitResultInformation();\r\n\r\n        /// <inheritdoc/>\r\n        public ValueSet? Settings { get; internal set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Processor/Unit/TestSettingsResult.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"TestSettingsResult.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.Processor.Unit\r\n{\r\n    using Microsoft.Management.Configuration;\r\n\r\n    /// <summary>\r\n    /// Implements ITestSettingsResult.\r\n    /// </summary>\r\n    internal sealed partial class TestSettingsResult : ITestSettingsResult\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"TestSettingsResult\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"unit\">The configuration unit that the result is for.</param>\r\n        public TestSettingsResult(ConfigurationUnit unit)\r\n        {\r\n            this.Unit = unit;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the configuration unit that the result is for.\r\n        /// </summary>\r\n        public ConfigurationUnit Unit { get; private set; }\r\n\r\n        /// <inheritdoc/>\r\n        public IConfigurationUnitResultInformation ResultInformation\r\n        {\r\n            get { return this.InternalResult; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the implementation object for ResultInformation.\r\n        /// </summary>\r\n        public ConfigurationUnitResultInformation InternalResult { get; } = new ConfigurationUnitResultInformation();\r\n\r\n        /// <inheritdoc/>\r\n        public ConfigurationTestResult TestResult { get; internal set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.Projection/Microsoft.Management.Configuration.Projection.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework>\r\n    <Platform>AnyCpu</Platform>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n    <OutputPath>$(SolutionDir)$(Platform)\\$(Configuration)\\$(MSBuildProjectName)\\</OutputPath>\r\n    <Configurations>Debug;Release;ReleaseStatic</Configurations>\r\n    <EmbedUntrackedSources>true</EmbedUntrackedSources>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup>\r\n    <CsWinRTIncludes>Microsoft.Management.Configuration</CsWinRTIncludes>\r\n    <CsWinRTGeneratedFilesDir>$(OutDir)</CsWinRTGeneratedFilesDir>\r\n    <CsWinRTWindowsMetadata>10.0.26100.0</CsWinRTWindowsMetadata>\r\n    <!-- Ensure Support for Windows 10, Version 1809 -->\r\n    <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>\r\n    <!-- \r\n      Disables the AssemblyInfo generation override in the internal build.\r\n      Without this, values like TargetPlatformMinVersion are not placed into the assembly attributes\r\n      and .NET static analysis tools will assume that this assembly requires the OS version in our TargetFramework.\r\n    -->\r\n    <XesDisableAssemblyInfoWrite>True</XesDisableAssemblyInfoWrite>\r\n  </PropertyGroup>\r\n  \r\n  <PropertyGroup>\r\n    <!-- Workaround for MSB3271 error on processor architecture mismatch -->\r\n    <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <PackageReference Include=\"Microsoft.Windows.CsWinRT\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\Microsoft.Management.Configuration\\Microsoft.Management.Configuration.vcxproj\">\r\n      <OutputItemType>Content</OutputItemType>\r\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\r\n      <ReferenceOutputAssembly>True</ReferenceOutputAssembly>\r\n    </ProjectReference>\r\n  </ItemGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Fixtures/UnitTestCollection.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"UnitTestCollection.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Fixtures\r\n{\r\n    using Xunit;\r\n\r\n    /// <summary>\r\n    /// Unit test collection.\r\n    /// </summary>\r\n    [CollectionDefinition(\"UnitTestCollection\")]\r\n    public class UnitTestCollection : ICollectionFixture<UnitTestFixture>\r\n    {\r\n        // This class has no code, and is never created. Its purpose is simply\r\n        // to be the place to apply [CollectionDefinition] and all the\r\n        // ICollectionFixture<> interfaces.\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Fixtures/UnitTestFixture.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"UnitTestFixture.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Fixtures\r\n{\r\n    using System;\r\n    using System.Diagnostics.CodeAnalysis;\r\n    using System.IO;\r\n    using System.Reflection;\r\n    using Microsoft.Management.Configuration.Processor;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.ProcessorEnvironments;\r\n    using WinRT;\r\n    using Xunit.Abstractions;\r\n\r\n    /// <summary>\r\n    /// Unit test fixture.\r\n    /// </summary>\r\n    public class UnitTestFixture\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"UnitTestFixture\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"messageSink\">The message sink for the fixture.</param>\r\n        public UnitTestFixture(IMessageSink messageSink)\r\n        {\r\n            this.MessageSink = messageSink;\r\n\r\n            string assemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)\r\n                ?? throw new ArgumentException();\r\n\r\n            this.TestModulesPath = Path.Combine(assemblyPath, \"TestCollateral\", \"PowerShellModules\");\r\n            if (!Directory.Exists(this.TestModulesPath))\r\n            {\r\n                throw new DirectoryNotFoundException(this.TestModulesPath);\r\n            }\r\n\r\n            // Use the environment variable if present, which is how ADO pipelines will find it.\r\n            string? gitSearchPath = Environment.GetEnvironmentVariable(\"BUILD_SOURCESDIRECTORY\");\r\n\r\n            if (string.IsNullOrWhiteSpace(gitSearchPath))\r\n            {\r\n                gitSearchPath = Path.GetDirectoryName(assemblyPath);\r\n\r\n                while (!string.IsNullOrEmpty(gitSearchPath))\r\n                {\r\n                    if (Directory.Exists(Path.Combine(gitSearchPath, \".git\")))\r\n                    {\r\n                        break;\r\n                    }\r\n\r\n                    gitSearchPath = Path.GetDirectoryName(gitSearchPath);\r\n                }\r\n            }\r\n\r\n            this.GitRootPath = gitSearchPath ?? throw new DirectoryNotFoundException(\"git root path\");\r\n\r\n            this.ExternalModulesPath = Path.Combine(this.GitRootPath, \"src\", \"PowerShell\", \"ExternalModules\");\r\n            if (!Directory.Exists(this.ExternalModulesPath))\r\n            {\r\n                throw new DirectoryNotFoundException(this.ExternalModulesPath);\r\n            }\r\n\r\n            this.RecreateStatics();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the message sink for the fixture.\r\n        /// </summary>\r\n        public IMessageSink MessageSink { get; private init; }\r\n\r\n        /// <summary>\r\n        /// Gets the test module path.\r\n        /// </summary>\r\n        public string TestModulesPath { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the git root path.\r\n        /// </summary>\r\n        public string GitRootPath { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the external module path.\r\n        /// </summary>\r\n        public string ExternalModulesPath { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the configuration statics object to use.\r\n        /// </summary>\r\n        internal IConfigurationStatics2 ConfigurationStatics { get; private set; }\r\n\r\n        /// <summary>\r\n        /// Creates a new statics object for use by the tests.\r\n        /// </summary>\r\n        [MemberNotNull(\"ConfigurationStatics\")]\r\n        public void RecreateStatics()\r\n        {\r\n            this.ConfigurationStatics = new ConfigurationStaticFunctions().As<IConfigurationStatics2>();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates a runspace adding the test module path.\r\n        /// </summary>\r\n        /// <param name=\"validate\">Validate runspace.</param>\r\n        /// <returns>PowerShellRunspace.</returns>\r\n        internal IProcessorEnvironment PrepareTestProcessorEnvironment(bool validate = false)\r\n        {\r\n            var processorEnv = new ProcessorEnvironmentFactory(PowerShellConfigurationProcessorType.Hosted).CreateEnvironment(null, PowerShellConfigurationProcessorPolicy.Unrestricted);\r\n            processorEnv.PrependPSModulePath(this.ExternalModulesPath);\r\n            processorEnv.PrependPSModulePath(this.TestModulesPath);\r\n\r\n            if (validate)\r\n            {\r\n                processorEnv.ValidateRunspace();\r\n            }\r\n\r\n            return processorEnv;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/ApplyGroupMemberSettingsResultInstance.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ApplyGroupMemberSettingsResultInstance.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    /// <summary>\r\n    /// Implements IApplyGroupMemberSettingsResult.\r\n    /// </summary>\r\n    internal sealed partial class ApplyGroupMemberSettingsResultInstance : IApplyGroupMemberSettingsResult\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ApplyGroupMemberSettingsResultInstance\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"unit\">The unit for this result.</param>\r\n        internal ApplyGroupMemberSettingsResultInstance(ConfigurationUnit unit)\r\n        {\r\n            this.Unit = unit;\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public bool PreviouslyInDesiredState { get; internal set; }\r\n\r\n        /// <inheritdoc/>\r\n        public bool RebootRequired { get; internal set; }\r\n\r\n        /// <inheritdoc/>\r\n        public IConfigurationUnitResultInformation ResultInformation\r\n        {\r\n            get { return this.InternalResult; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the implementation object for ResultInformation.\r\n        /// </summary>\r\n        public TestConfigurationUnitResultInformation InternalResult { get; } = new TestConfigurationUnitResultInformation();\r\n\r\n        /// <inheritdoc/>\r\n        public ConfigurationUnitState State { get; internal set; }\r\n\r\n        /// <inheritdoc/>\r\n        public ConfigurationUnit Unit { get; private init; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/ApplyGroupSettingsResultInstance.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ApplyGroupSettingsResultInstance.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using System.Collections.Generic;\r\n\r\n    /// <summary>\r\n    /// Implements IApplyGroupSettingsResult.\r\n    /// </summary>\r\n    internal sealed partial class ApplyGroupSettingsResultInstance : IApplyGroupSettingsResult\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ApplyGroupSettingsResultInstance\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"group\">The group for this result.</param>\r\n        internal ApplyGroupSettingsResultInstance(object? group)\r\n        {\r\n            this.Group = group;\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public object? Group { get; private init; }\r\n\r\n        /// <inheritdoc/>\r\n        public bool RebootRequired { get; internal set; }\r\n\r\n        /// <inheritdoc/>\r\n        public IConfigurationUnitResultInformation? ResultInformation\r\n        {\r\n            get { return this.InternalResult; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the implementation object for ResultInformation.\r\n        /// </summary>\r\n        public TestConfigurationUnitResultInformation InternalResult { get; } = new TestConfigurationUnitResultInformation();\r\n\r\n        /// <inheritdoc/>\r\n        public IList<IApplyGroupMemberSettingsResult>? UnitResults { get; internal set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/ApplySettingsResultInstance.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ApplySettingsResultInstance.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using Microsoft.Management.Configuration;\r\n\r\n    /// <summary>\r\n    /// Implements IApplySettingsResult.\r\n    /// </summary>\r\n    internal sealed partial class ApplySettingsResultInstance : IApplySettingsResult\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ApplySettingsResultInstance\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"unit\">The configuration unit that the result is for.</param>\r\n        public ApplySettingsResultInstance(ConfigurationUnit unit)\r\n        {\r\n            this.Unit = unit;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the configuration unit that the result is for.\r\n        /// </summary>\r\n        public ConfigurationUnit Unit { get; private set; }\r\n\r\n        /// <inheritdoc/>\r\n        public IConfigurationUnitResultInformation ResultInformation\r\n        {\r\n            get { return this.InternalResult; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the implementation object for ResultInformation.\r\n        /// </summary>\r\n        public TestConfigurationUnitResultInformation InternalResult { get; } = new TestConfigurationUnitResultInformation();\r\n\r\n        /// <inheritdoc/>\r\n        public bool RebootRequired { get; internal set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationEnvironmentData.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationEnvironmentData.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n\r\n    /// <summary>\r\n    /// Contains the data defining a configuration environment.\r\n    /// </summary>\r\n    internal class ConfigurationEnvironmentData\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ConfigurationEnvironmentData\"/> class.\r\n        /// </summary>\r\n        internal ConfigurationEnvironmentData()\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the security context.\r\n        /// </summary>\r\n        internal SecurityContext Context { get; set; } = SecurityContext.Current;\r\n\r\n        /// <summary>\r\n        /// Gets or sets the processor identifier.\r\n        /// </summary>\r\n        internal string ProcessorIdentifier { get; set; } = string.Empty;\r\n\r\n        /// <summary>\r\n        /// Gets or sets the processor properties.\r\n        /// </summary>\r\n        internal Dictionary<string, string> ProcessorProperties { get; set; } = new ();\r\n\r\n        /// <summary>\r\n        /// Applies this environment to the given unit.\r\n        /// </summary>\r\n        /// <param name=\"unit\">The unit to apply to.</param>\r\n        /// <returns>The given unit.</returns>\r\n        internal ConfigurationUnit ApplyToUnit(ConfigurationUnit unit)\r\n        {\r\n            var environment = unit.Environment;\r\n\r\n            environment.Context = this.Context;\r\n            environment.ProcessorIdentifier = this.ProcessorIdentifier;\r\n            environment.ProcessorProperties.Clear();\r\n            foreach (var property in this.ProcessorProperties)\r\n            {\r\n                environment.ProcessorProperties.Add(property.Key, property.Value);\r\n            }\r\n\r\n            return unit;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests whether the given properties match this object's properties.\r\n        /// </summary>\r\n        /// <param name=\"properties\">The properties to test.</param>\r\n        /// <returns>True if the properties match; false if not.</returns>\r\n        internal bool PropertiesEqual(IDictionary<string, string> properties)\r\n        {\r\n            if (properties.Count != this.ProcessorProperties.Count)\r\n            {\r\n                return false;\r\n            }\r\n\r\n            foreach (var property in properties)\r\n            {\r\n                string? value = null;\r\n                if (!this.ProcessorProperties.TryGetValue(property.Key, out value))\r\n                {\r\n                    return false;\r\n                }\r\n\r\n                if (property.Value != value)\r\n                {\r\n                    return false;\r\n                }\r\n            }\r\n\r\n            return true;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationExtensions.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationExtensions.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using System.Linq;\r\n    using System.Reflection;\r\n\r\n    /// <summary>\r\n    /// Contains extension methods for configuration objects.\r\n    /// </summary>\r\n    internal static class ConfigurationExtensions\r\n    {\r\n        /// <summary>\r\n        /// Assigns the given properties to the configuration unit.\r\n        /// </summary>\r\n        /// <param name=\"unit\">The unit to assign the properties of.</param>\r\n        /// <param name=\"properties\">The properties to assign.</param>\r\n        /// <returns>The given ConfigurationUnit.</returns>\r\n        internal static ConfigurationUnit Assign(this ConfigurationUnit unit, object properties)\r\n        {\r\n            PropertyInfo[] unitProperties = typeof(ConfigurationUnit).GetProperties();\r\n\r\n            foreach (PropertyInfo property in properties.GetType().GetProperties())\r\n            {\r\n                PropertyInfo matchingProperty = unitProperties.First(pi => pi.Name == property.Name);\r\n                matchingProperty.SetValue(unit, property.GetValue(properties));\r\n            }\r\n\r\n            return unit;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/ConfigurationProcessorTestBase.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationProcessorTestBase.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using System;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Windows.Storage.Streams;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n\r\n    /// <summary>\r\n    /// Test base that provides helpers for dealing with <see cref=\"ConfigurationProcessor\"/>.\r\n    /// </summary>\r\n    public class ConfigurationProcessorTestBase\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ConfigurationProcessorTestBase\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Unit test fixture.</param>\r\n        /// <param name=\"log\">Log helper.</param>\r\n        protected ConfigurationProcessorTestBase(UnitTestFixture fixture, ITestOutputHelper log)\r\n        {\r\n            this.Fixture = fixture;\r\n            this.Log = log;\r\n            this.EventSink = new DiagnosticsEventSink(fixture, log);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the event sink for this test base.\r\n        /// </summary>\r\n        protected DiagnosticsEventSink EventSink { get; private set; }\r\n\r\n        /// <summary>\r\n        /// Gets the test fixture.\r\n        /// </summary>\r\n        protected UnitTestFixture Fixture { get; private init; }\r\n\r\n        /// <summary>\r\n        /// Gets the output helper.\r\n        /// </summary>\r\n        protected ITestOutputHelper Log { get; private init; }\r\n\r\n        /// <summary>\r\n        /// Create a new <see cref=\"ConfigurationProcessor\"/> with the diagnostics event hooked up.\r\n        /// </summary>\r\n        /// <param name=\"factory\">The factory to use.</param>\r\n        /// <returns>The new <see cref=\"ConfigurationProcessor\"/> object.</returns>\r\n        internal ConfigurationProcessor CreateConfigurationProcessorWithDiagnostics(IConfigurationSetProcessorFactory? factory = null)\r\n        {\r\n            ConfigurationProcessor result = this.Fixture.ConfigurationStatics.CreateConfigurationProcessor(factory);\r\n            result.Diagnostics += this.EventSink.DiagnosticsHandler;\r\n            result.MinimumLevel = DiagnosticLevel.Verbose;\r\n            return result;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates an input stream from the given string.\r\n        /// </summary>\r\n        /// <param name=\"contents\">The contents that the stream should contain.</param>\r\n        /// <returns>The created stream.</returns>\r\n        internal IInputStream CreateStream(string contents)\r\n        {\r\n            InMemoryRandomAccessStream result = new InMemoryRandomAccessStream();\r\n\r\n            using (DataWriter writer = new DataWriter(result))\r\n            {\r\n                writer.UnicodeEncoding = UnicodeEncoding.Utf8;\r\n                writer.WriteString(contents);\r\n                writer.StoreAsync().AsTask().Wait();\r\n                writer.DetachStream();\r\n            }\r\n\r\n            result.Seek(0);\r\n            return result;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates an string from the given output stream.\r\n        /// </summary>\r\n        /// <param name=\"stream\">The output stream.</param>\r\n        /// <returns>The created string.</returns>\r\n        internal string ReadStream(InMemoryRandomAccessStream stream)\r\n        {\r\n            string result = string.Empty;\r\n            using (DataReader reader = new DataReader(stream.GetInputStreamAt(0)))\r\n            {\r\n                reader.UnicodeEncoding = UnicodeEncoding.Utf8;\r\n                reader.LoadAsync((uint)stream.Size).AsTask().Wait();\r\n                uint bytesToRead = reader.UnconsumedBufferLength;\r\n\r\n                if (bytesToRead > 0)\r\n                {\r\n                    result = reader.ReadString(bytesToRead);\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates a configuration unit via the configuration statics object.\r\n        /// </summary>\r\n        /// <returns>A new configuration unit.</returns>\r\n        internal ConfigurationUnit ConfigurationUnit()\r\n        {\r\n            return this.Fixture.ConfigurationStatics.CreateConfigurationUnit();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates a configuration parameter via the configuration statics object.\r\n        /// </summary>\r\n        /// <returns>A new configuration parameter.</returns>\r\n        internal ConfigurationParameter ConfigurationParameter()\r\n        {\r\n            return this.Fixture.ConfigurationStatics.CreateConfigurationParameter();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates a configuration set via the configuration statics object.\r\n        /// </summary>\r\n        /// <returns>A new configuration set.</returns>\r\n        internal ConfigurationSet ConfigurationSet()\r\n        {\r\n            return this.Fixture.ConfigurationStatics.CreateConfigurationSet();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies the summary event generated by a processing run.\r\n        /// </summary>\r\n        /// <param name=\"configurationSet\">The configuration set.</param>\r\n        /// <param name=\"setResult\">The set result.</param>\r\n        /// <param name=\"resultSource\">The result source.</param>\r\n        internal void VerifySummaryEvent(ConfigurationSet configurationSet, ApplyConfigurationSetResult setResult, ConfigurationUnitResultSource resultSource)\r\n        {\r\n            TelemetryEvent summary = this.VerifySummaryEventShared(configurationSet, ConfigurationUnitIntent.Apply, resultSource == ConfigurationUnitResultSource.None ? 0 : setResult.ResultCode.HResult, resultSource);\r\n\r\n            int[] counts = new int[3];\r\n            int[] runs = new int[3];\r\n            int[] failures = new int[3];\r\n\r\n            var unitResults = setResult.UnitResults;\r\n            for (int i = 0; i < unitResults.Count; ++i)\r\n            {\r\n                ApplyConfigurationUnitResult unitResult = unitResults[i];\r\n                SummaryCountByIntent(counts, runs, failures, unitResult.Unit.Intent, unitResult.ResultInformation);\r\n            }\r\n\r\n            VerifySummaryCounts(summary, counts, runs, failures);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies the summary event generated by a processing run.\r\n        /// </summary>\r\n        /// <param name=\"configurationSet\">The configuration set.</param>\r\n        /// <param name=\"setResult\">The set result.</param>\r\n        /// <param name=\"resultCode\">The result code.</param>\r\n        /// <param name=\"resultSource\">The result source.</param>\r\n        internal void VerifySummaryEvent(ConfigurationSet configurationSet, TestConfigurationSetResult setResult, int resultCode, ConfigurationUnitResultSource resultSource)\r\n        {\r\n            TelemetryEvent summary = this.VerifySummaryEventShared(configurationSet, ConfigurationUnitIntent.Assert, resultCode, resultSource);\r\n\r\n            int[] counts = new int[3];\r\n            int[] runs = new int[3];\r\n            int[] failures = new int[3];\r\n\r\n            foreach (TestConfigurationUnitResult unitResult in setResult.UnitResults)\r\n            {\r\n                SummaryCountByIntent(counts, runs, failures, unitResult.Unit.Intent, unitResult.ResultInformation);\r\n            }\r\n\r\n            VerifySummaryCounts(summary, counts, runs, failures);\r\n        }\r\n\r\n        private static void SummaryCountByIntent(int[] counts, int[] runs, int[] failures, ConfigurationUnitIntent intent, IConfigurationUnitResultInformation resultInformation)\r\n        {\r\n            if (intent == ConfigurationUnitIntent.Unknown)\r\n            {\r\n                intent = ConfigurationUnitIntent.Apply;\r\n            }\r\n\r\n            int index = (int)intent;\r\n\r\n            counts[index]++;\r\n\r\n            if (resultInformation.ResultSource != ConfigurationUnitResultSource.ConfigurationSet && resultInformation.ResultSource != ConfigurationUnitResultSource.Precondition)\r\n            {\r\n                runs[index]++;\r\n            }\r\n\r\n            if (resultInformation.ResultCode != null)\r\n            {\r\n                failures[index]++;\r\n            }\r\n        }\r\n\r\n        private static void VerifySummaryCounts(TelemetryEvent summary, int[] counts, int[] runs, int[] failures)\r\n        {\r\n            Assert.Equal(counts[(int)ConfigurationUnitIntent.Assert].ToString(), summary.Properties[TelemetryEvent.AssertCount]);\r\n            Assert.Equal(runs[(int)ConfigurationUnitIntent.Assert].ToString(), summary.Properties[TelemetryEvent.AssertsRun]);\r\n            Assert.Equal(failures[(int)ConfigurationUnitIntent.Assert].ToString(), summary.Properties[TelemetryEvent.AssertsFailed]);\r\n\r\n            Assert.Equal(counts[(int)ConfigurationUnitIntent.Inform].ToString(), summary.Properties[TelemetryEvent.InformCount]);\r\n            Assert.Equal(runs[(int)ConfigurationUnitIntent.Inform].ToString(), summary.Properties[TelemetryEvent.InformsRun]);\r\n            Assert.Equal(failures[(int)ConfigurationUnitIntent.Inform].ToString(), summary.Properties[TelemetryEvent.InformsFailed]);\r\n\r\n            Assert.Equal(counts[(int)ConfigurationUnitIntent.Apply].ToString(), summary.Properties[TelemetryEvent.ApplyCount]);\r\n            Assert.Equal(runs[(int)ConfigurationUnitIntent.Apply].ToString(), summary.Properties[TelemetryEvent.AppliesRun]);\r\n            Assert.Equal(failures[(int)ConfigurationUnitIntent.Apply].ToString(), summary.Properties[TelemetryEvent.AppliesFailed]);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies the summary event generated by a processing run.\r\n        /// </summary>\r\n        /// <param name=\"configurationSet\">The configuration set.</param>\r\n        /// <param name=\"runIntent\">The run intent.</param>\r\n        /// <param name=\"resultCode\">The result code.</param>\r\n        /// <param name=\"resultSource\">The result source.</param>\r\n        private TelemetryEvent VerifySummaryEventShared(ConfigurationSet configurationSet, ConfigurationUnitIntent runIntent, int resultCode, ConfigurationUnitResultSource resultSource)\r\n        {\r\n            Assert.Single(this.EventSink.Events);\r\n            TelemetryEvent summary = this.EventSink.Events[0];\r\n\r\n            Assert.Equal(TelemetryEvent.ConfigProcessingSummaryName, summary.Name);\r\n            Assert.NotEqual(string.Empty, summary.CodeVersion);\r\n            Assert.NotEqual(Guid.Empty, summary.ActivityID);\r\n            Assert.Equal(string.Empty, summary.Caller);\r\n            Assert.Equal(configurationSet.InstanceIdentifier, Guid.Parse(summary.Properties[TelemetryEvent.SetID]));\r\n            Assert.False(int.Parse(summary.Properties[TelemetryEvent.FromHistory]) != 0);\r\n            Assert.Equal(((int)runIntent).ToString(), summary.Properties[TelemetryEvent.RunIntent]);\r\n            Assert.Equal(resultCode.ToString(), summary.Properties[TelemetryEvent.Result]);\r\n            Assert.Equal(((int)resultSource).ToString(), summary.Properties[TelemetryEvent.FailurePoint]);\r\n\r\n            return summary;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/Constants.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"Constants.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    /// <summary>\r\n    /// Constants used by the tests.\r\n    /// </summary>\r\n    public class Constants\r\n    {\r\n        /// <summary>\r\n        /// The assembly name value used by xUnit traits.\r\n        /// </summary>\r\n        public const string AssemblyNameForTraits = \"Microsoft.Management.Configuration.UnitTests\";\r\n\r\n        /// <summary>\r\n        /// The namespace where xUnit traits will be defined.\r\n        /// </summary>\r\n        public const string NamespaceNameForTraits = \"Microsoft.Management.Configuration.UnitTests.Helpers\";\r\n\r\n        /// <summary>\r\n        /// The dynamic runtime factory handler identifier.\r\n        /// </summary>\r\n        public const string DynamicRuntimeHandlerIdentifier = \"{73fea39f-6f4a-41c9-ba94-6fd14d633e40}\";\r\n\r\n        /// <summary>\r\n        /// Test guid for enabling test mode for the dynamic runtime factory. Forces factory to exclude 'runas' verb and sets current IL to medium.\r\n        /// </summary>\r\n        public const string EnableDynamicFactoryTestMode = \"1e62d683-2999-44e7-81f7-6f8f35e8d731\";\r\n\r\n        /// <summary>\r\n        /// Test guid for allowing the restricted integrity level to be supported.\r\n        /// </summary>\r\n        public const string EnableRestrictedIntegrityLevelTestGuid = \"5cae3226-185f-4289-815c-3c089d238dc6\";\r\n\r\n        /// <summary>\r\n        /// Test guid for forcing units to have a high integrity level during the final routing of unit processor creation.\r\n        /// </summary>\r\n        public const string ForceHighIntegrityLevelUnitsTestGuid = \"f698d20f-3584-4f28-bc75-28037e08e651\";\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/DiagnosticsEventSink.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"DiagnosticsEventSink.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using System.Collections.Generic;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Xunit.Abstractions;\r\n    using Xunit.Sdk;\r\n\r\n    /// <summary>\r\n    /// This class aids in getting diagnostics data from the <see cref=\"ConfigurationProcessor\"/> out to the xUnit infrastructure.\r\n    /// </summary>\r\n    public class DiagnosticsEventSink\r\n    {\r\n        private readonly UnitTestFixture fixture;\r\n        private readonly ITestOutputHelper log;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"DiagnosticsEventSink\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Unit test fixture.</param>\r\n        /// <param name=\"log\">Log helper.</param>\r\n        public DiagnosticsEventSink(UnitTestFixture fixture, ITestOutputHelper log)\r\n        {\r\n            this.fixture = fixture;\r\n            this.log = log;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the telemetry events that have been seen.\r\n        /// </summary>\r\n        public List<TelemetryEvent> Events { get; private set; } = new List<TelemetryEvent>();\r\n\r\n        /// <summary>\r\n        /// Handles diagnostic information from a <see cref=\"ConfigurationProcessor\"/>.\r\n        /// </summary>\r\n        /// <param name=\"sender\">The object sending the information.</param>\r\n        /// <param name=\"e\">The diagnostic information.</param>\r\n        internal void DiagnosticsHandler(object? sender, IDiagnosticInformation e)\r\n        {\r\n            if (e.Message.Contains(TelemetryEvent.Preamble))\r\n            {\r\n                this.Events.Add(new TelemetryEvent(e.Message));\r\n            }\r\n\r\n            if (e.Level == DiagnosticLevel.Verbose)\r\n            {\r\n                this.fixture.MessageSink.OnMessage(new DiagnosticMessage(e.Message));\r\n            }\r\n            else\r\n            {\r\n                this.log.WriteLine(e.Message);\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/Errors.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"Errors.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    /// <summary>\r\n    /// Contains the error codes used by Microsoft.Management.Configuration.\r\n    /// </summary>\r\n    internal static class Errors\r\n    {\r\n#pragma warning disable SA1310 // Field names should not contain underscore\r\n#pragma warning disable SA1600 // Elements should be documented\r\n#pragma warning disable SA1025 // Code should not contain multiple whitespace in a row\r\n\r\n        public static readonly int WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE           = unchecked((int)0x8A15C001);\r\n        public static readonly int WINGET_CONFIG_ERROR_INVALID_YAML                         = unchecked((int)0x8A15C002);\r\n        public static readonly int WINGET_CONFIG_ERROR_INVALID_FIELD_TYPE                   = unchecked((int)0x8A15C003);\r\n        public static readonly int WINGET_CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION   = unchecked((int)0x8A15C004);\r\n        public static readonly int WINGET_CONFIG_ERROR_SET_APPLY_FAILED                     = unchecked((int)0x8A15C005);\r\n        public static readonly int WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER                 = unchecked((int)0x8A15C006);\r\n        public static readonly int WINGET_CONFIG_ERROR_MISSING_DEPENDENCY                   = unchecked((int)0x8A15C007);\r\n        public static readonly int WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED               = unchecked((int)0x8A15C008);\r\n        public static readonly int WINGET_CONFIG_ERROR_ASSERTION_FAILED                     = unchecked((int)0x8A15C009);\r\n        public static readonly int WINGET_CONFIG_ERROR_MANUALLY_SKIPPED                     = unchecked((int)0x8A15C00A);\r\n        public static readonly int WINGET_CONFIG_ERROR_WARNING_NOT_ACCEPTED                 = unchecked((int)0x8A15C00B);\r\n        public static readonly int WINGET_CONFIG_ERROR_SET_DEPENDENCY_CYCLE                 = unchecked((int)0x8A15C00C);\r\n        public static readonly int WINGET_CONFIG_ERROR_INVALID_FIELD_VALUE                  = unchecked((int)0x8A15C00D);\r\n        public static readonly int WINGET_CONFIG_ERROR_MISSING_FIELD                        = unchecked((int)0x8A15C00E);\r\n        public static readonly int WINGET_CONFIG_ERROR_TEST_FAILED                          = unchecked((int)0x8A15C00F);\r\n        public static readonly int WINGET_CONFIG_ERROR_TEST_NOT_RUN                         = unchecked((int)0x8A15C010);\r\n        public static readonly int WINGET_CONFIG_ERROR_GET_FAILED                           = unchecked((int)0x8A15C011);\r\n\r\n        // Configuration Processor Errors\r\n        public static readonly int WINGET_CONFIG_ERROR_UNIT_NOT_INSTALLED                   = unchecked((int)0x8A15C101);\r\n        public static readonly int WINGET_CONFIG_ERROR_UNIT_NOT_FOUND_REPOSITORY            = unchecked((int)0x8A15C102);\r\n        public static readonly int WINGET_CONFIG_ERROR_UNIT_MULTIPLE_MATCHES                = unchecked((int)0x8A15C103);\r\n        public static readonly int WINGET_CONFIG_ERROR_UNIT_INVOKE_GET                      = unchecked((int)0x8A15C104);\r\n        public static readonly int WINGET_CONFIG_ERROR_UNIT_INVOKE_TEST                     = unchecked((int)0x8A15C105);\r\n        public static readonly int WINGET_CONFIG_ERROR_UNIT_INVOKE_SET                      = unchecked((int)0x8A15C106);\r\n        public static readonly int WINGET_CONFIG_ERROR_UNIT_MODULE_CONFLICT                 = unchecked((int)0x8A15C107);\r\n        public static readonly int WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE                   = unchecked((int)0x8A15C108);\r\n        public static readonly int WINGET_CONFIG_ERROR_UNIT_INVOKE_INVALID_RESULT           = unchecked((int)0x8A15C109);\r\n        public static readonly int WINGET_CONFIG_ERROR_UNIT_SETTING_CONFIG_ROOT             = unchecked((int)0x8A15C110);\r\n        public static readonly int WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE_ADMIN             = unchecked((int)0x8A15C111);\r\n        public static readonly int WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR           = unchecked((int)0x8A15C112);\r\n        public static readonly int WINGET_CONFIG_ERROR_PARAMETER_INTEGRITY_BOUNDARY         = unchecked((int)0x8A15C013);\r\n\r\n        // Limitation Set Errors\r\n        public static readonly int CORE_INVALID_OPERATION = unchecked((int)0x80131509);\r\n\r\n#pragma warning restore SA1025 // Code should not contain multiple whitespace in a row\r\n#pragma warning restore SA1600 // Elements should be documented\r\n#pragma warning restore SA1310 // Field names should not contain underscore\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/FactSkipIfCI.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"FactSkipIfCI.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using System;\r\n    using Xunit;\r\n\r\n    /// <summary>\r\n    /// Skip fact tests if running in CI builds.\r\n    /// </summary>\r\n    public class FactSkipIfCI : FactAttribute\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"FactSkipIfCI\"/> class.\r\n        /// </summary>\r\n        public FactSkipIfCI()\r\n        {\r\n            if (Environment.GetEnvironmentVariable(\"BUILD_BUILDNUMBER\") is not null)\r\n            {\r\n                this.Skip = \"Skip test for CI builds\";\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/GetAllSettingsResultInstance.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"GetAllSettingsResultInstance.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using System.Collections.Generic;\r\n    using Microsoft.Management.Configuration;\r\n    using Windows.Foundation.Collections;\r\n\r\n    /// <summary>\r\n    /// Implements IGetAllSettingsResult.\r\n    /// </summary>\r\n    internal sealed partial class GetAllSettingsResultInstance : IGetAllSettingsResult\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"GetAllSettingsResultInstance\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"unit\">The configuration unit that the result is for.</param>\r\n        public GetAllSettingsResultInstance(ConfigurationUnit unit)\r\n        {\r\n            this.Unit = unit;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the configuration unit that the result is for.\r\n        /// </summary>\r\n        public ConfigurationUnit Unit { get; private set; }\r\n\r\n        /// <inheritdoc/>\r\n        public IConfigurationUnitResultInformation ResultInformation\r\n        {\r\n            get { return this.InternalResult; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the implementation object for ResultInformation.\r\n        /// </summary>\r\n        public TestConfigurationUnitResultInformation InternalResult { get; } = new TestConfigurationUnitResultInformation();\r\n\r\n        /// <inheritdoc/>\r\n        public IList<ValueSet>? Settings { get; internal set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/GetSettingsResultInstance.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"GetSettingsResultInstance.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using Microsoft.Management.Configuration;\r\n    using Windows.Foundation.Collections;\r\n\r\n    /// <summary>\r\n    /// Implements IGetSettingsResult.\r\n    /// </summary>\r\n    internal sealed partial class GetSettingsResultInstance : IGetSettingsResult\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"GetSettingsResultInstance\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"unit\">The configuration unit that the result is for.</param>\r\n        public GetSettingsResultInstance(ConfigurationUnit unit)\r\n        {\r\n            this.Unit = unit;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the configuration unit that the result is for.\r\n        /// </summary>\r\n        public ConfigurationUnit Unit { get; private set; }\r\n\r\n        /// <inheritdoc/>\r\n        public IConfigurationUnitResultInformation ResultInformation\r\n        {\r\n            get { return this.InternalResult; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the implementation object for ResultInformation.\r\n        /// </summary>\r\n        public TestConfigurationUnitResultInformation InternalResult { get; } = new TestConfigurationUnitResultInformation();\r\n\r\n        /// <inheritdoc/>\r\n        public ValueSet? Settings { get; internal set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/InProcAttribute.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"InProcAttribute.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using System;\r\n    using Xunit.Sdk;\r\n\r\n    /// <summary>\r\n    /// Trait used to mark a test as only for the in proc scenario.\r\n    /// </summary>\r\n    [TraitDiscoverer(InProcDiscoverer.TypeName, Constants.AssemblyNameForTraits)]\r\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]\r\n    public class InProcAttribute : Attribute, ITraitAttribute\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"InProcAttribute\"/> class.\r\n        /// </summary>\r\n        public InProcAttribute()\r\n        {\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/InProcDiscoverer.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"InProcDiscoverer.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using System.Collections.Generic;\r\n    using Xunit.Abstractions;\r\n    using Xunit.Sdk;\r\n\r\n    /// <summary>\r\n    /// Enables integration with xUnit trait system.\r\n    /// </summary>\r\n    public class InProcDiscoverer : ITraitDiscoverer\r\n    {\r\n        /// <summary>\r\n        /// The type name for this discoverer.\r\n        /// </summary>\r\n        public const string TypeName = Constants.NamespaceNameForTraits + \".InProcDiscoverer\";\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"InProcDiscoverer\"/> class.\r\n        /// </summary>\r\n        public InProcDiscoverer()\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the trait information for the InProcAttribute.\r\n        /// </summary>\r\n        /// <param name=\"traitAttribute\">The trait information.</param>\r\n        /// <returns>Trait name/value pairs.</returns>\r\n        public IEnumerable<KeyValuePair<string, string>> GetTraits(IAttributeInfo traitAttribute)\r\n        {\r\n            yield return new KeyValuePair<string, string>(\"Category\", \"InProc\");\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/OutOfProcAttribute.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"OutOfProcAttribute.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using System;\r\n    using Xunit.Sdk;\r\n\r\n    /// <summary>\r\n    /// Trait used to mark a test as being able to run against the out of proc server.\r\n    /// </summary>\r\n    [TraitDiscoverer(OutOfProcDiscoverer.TypeName, Constants.AssemblyNameForTraits)]\r\n    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]\r\n    public class OutOfProcAttribute : Attribute, ITraitAttribute\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"OutOfProcAttribute\"/> class.\r\n        /// </summary>\r\n        public OutOfProcAttribute()\r\n        {\r\n            // To run the tests OOP, you need to replace Microsoft.Management.Configuration.dll with Microsoft.Management.Configuration.OutOfProc.dll (renamed to remove the OutOfProc).\r\n            // You will also need to copy over Microsoft.Management.Configuration.winmd as it is needed by COM.\r\n            //\r\n            // You can use the script to do this:\r\n            //  <git root>\\src\\Microsoft.Management.Configuration.OutOfProc\\Prepare-ConfigurationOOPTests.ps1 -BuildOutputPath <git root>\\src\\x64\\Debug\r\n            //\r\n            // It can be easier to run the tests on the command line because any changes needing a recompile will overwrite the DLL update above.\r\n            // The test runner is located somewhere like this:\r\n            //  C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\Common7\\IDE\\Extensions\\TestPlatform\r\n            // and the command line from there is:\r\n            //  .\\vstest.console.exe \"<location of your repo>\\src\\x64\\Debug\\Microsoft.Management.Configuration.UnitTests\\net8.0-windows10.0.26100.0\\Microsoft.Management.Configuration.UnitTests.dll\" --TestCaseFilter:Category=OutOfProc\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/OutOfProcDiscoverer.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"OutOfProcDiscoverer.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using System.Collections.Generic;\r\n    using Xunit.Abstractions;\r\n    using Xunit.Sdk;\r\n\r\n    /// <summary>\r\n    /// Enables integration with xUnit trait system.\r\n    /// </summary>\r\n    public class OutOfProcDiscoverer : ITraitDiscoverer\r\n    {\r\n        /// <summary>\r\n        /// The type name for this discoverer.\r\n        /// </summary>\r\n        public const string TypeName = Constants.NamespaceNameForTraits + \".OutOfProcDiscoverer\";\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"OutOfProcDiscoverer\"/> class.\r\n        /// </summary>\r\n        public OutOfProcDiscoverer()\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the trait information for the OutOfProcAttribute.\r\n        /// </summary>\r\n        /// <param name=\"traitAttribute\">The trait information.</param>\r\n        /// <returns>Trait name/value pairs.</returns>\r\n        public IEnumerable<KeyValuePair<string, string>> GetTraits(IAttributeInfo traitAttribute)\r\n        {\r\n            yield return new KeyValuePair<string, string>(\"Category\", \"OutOfProc\");\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/PowerShellTestsConstants.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"PowerShellTestsConstants.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    /// <summary>\r\n    /// PowerShell related constants.\r\n    /// </summary>\r\n    internal static class PowerShellTestsConstants\r\n    {\r\n#pragma warning disable SA1600 // ElementsMustBeDocumented\r\n        public static class TestModule\r\n        {\r\n            public const string SimpleTestResourceModuleName = \"xSimpleTestResource\";\r\n            public const string SimpleFileResourceName = \"SimpleFileResource\";\r\n            public const string SimpleTestResourceName = \"SimpleTestResource\";\r\n            public const string SimpleTestResourceThrowsName = \"SimpleTestResourceThrows\";\r\n            public const string SimpleTestResourceErrorName = \"SimpleTestResourceError\";\r\n            public const string SimpleTestResourceManifestFileName = \"xSimpleTestResource.psd1\";\r\n            public const string SimpleTestResourceVersion = \"0.0.0.1\";\r\n        }\r\n#pragma warning restore SA1600 // ElementsMustBeDocumented\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/TelemetryEvent.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"TelemetryEvent.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n\r\n    /// <summary>\r\n    /// This class holds the data about a telemetry event detected via the diagnostics side channel.\r\n    /// </summary>\r\n    public class TelemetryEvent\r\n    {\r\n        /// <summary>\r\n        /// The initial indicator that the diagnostics message contains the contents of a telemetry event.\r\n        /// </summary>\r\n        public const string Preamble = \"#DebugEventStream\";\r\n\r\n        /// <summary>\r\n        /// The name of the ConfigUnitRun event.\r\n        /// </summary>\r\n        public const string ConfigUnitRunName = \"ConfigUnitRun\";\r\n\r\n        /// <summary>\r\n        /// The name of the ConfigProcessingSummary event.\r\n        /// </summary>\r\n        public const string ConfigProcessingSummaryName = \"ConfigProcessingSummary\";\r\n\r\n#pragma warning disable SA1600 // Elements should be documented\r\n\r\n        // Shared fields\r\n        public const string SetID = \"SetID\";\r\n        public const string RunIntent = \"RunIntent\";\r\n        public const string Result = \"Result\";\r\n        public const string FailurePoint = \"FailurePoint\";\r\n\r\n        // ConfigUnitRun fields\r\n        public const string UnitID = \"UnitID\";\r\n        public const string UnitName = \"UnitName\";\r\n        public const string ModuleName = \"ModuleName\";\r\n        public const string UnitIntent = \"UnitIntent\";\r\n        public const string Action = \"Action\";\r\n        public const string SettingsProvided = \"SettingsProvided\";\r\n\r\n        // ConfigProcessingSummary fields\r\n        public const string FromHistory = \"FromHistory\";\r\n        public const string AssertCount = \"AssertCount\";\r\n        public const string AssertsRun = \"AssertsRun\";\r\n        public const string AssertsFailed = \"AssertsFailed\";\r\n        public const string InformCount = \"InformCount\";\r\n        public const string InformsRun = \"InformsRun\";\r\n        public const string InformsFailed = \"InformsFailed\";\r\n        public const string ApplyCount = \"ApplyCount\";\r\n        public const string AppliesRun = \"AppliesRun\";\r\n        public const string AppliesFailed = \"AppliesFailed\";\r\n#pragma warning restore SA1600 // Elements should be documented\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"TelemetryEvent\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"eventMessage\">The message containing the event data.</param>\r\n        public TelemetryEvent(string eventMessage)\r\n        {\r\n            bool preambleSeen = false;\r\n\r\n            foreach (string line in eventMessage.Split('\\n'))\r\n            {\r\n                if (line == Preamble)\r\n                {\r\n                    preambleSeen = true;\r\n                    continue;\r\n                }\r\n\r\n                if (!preambleSeen)\r\n                {\r\n                    // Skip all lines until the preamble is seen\r\n                    continue;\r\n                }\r\n\r\n                int splitIndex = line.IndexOf(\": \");\r\n                if (splitIndex != -1)\r\n                {\r\n                    this.Properties.Add(line.Substring(0, splitIndex), line.Substring(splitIndex + 2));\r\n                }\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the properties for this event.\r\n        /// </summary>\r\n        public Dictionary<string, string> Properties { get; private set; } = new Dictionary<string, string>();\r\n\r\n        /// <summary>\r\n        /// Gets the name of the event.\r\n        /// </summary>\r\n        public string Name\r\n        {\r\n            get\r\n            {\r\n                return this.Properties[\"Event\"];\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the activity id.\r\n        /// </summary>\r\n        public Guid ActivityID\r\n        {\r\n            get\r\n            {\r\n                return Guid.Parse(this.Properties[\"ActivityID\"]);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the version of the code.\r\n        /// </summary>\r\n        public string CodeVersion\r\n        {\r\n            get\r\n            {\r\n                return this.Properties[\"CodeVersion\"];\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the caller.\r\n        /// </summary>\r\n        public string Caller\r\n        {\r\n            get\r\n            {\r\n                return this.Properties[\"Caller\"];\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/TempDirectory.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"TempDirectory.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using System;\r\n    using System.IO;\r\n\r\n    /// <summary>\r\n    /// Creates a temporary directory in the user's temporary directory.\r\n    /// </summary>\r\n    internal class TempDirectory : IDisposable\r\n    {\r\n        private bool disposed = false;\r\n        private bool cleanup;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"TempDirectory\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"directoryName\">Optional directory name. If null, creates a random directory name.</param>\r\n        /// <param name=\"deleteIfExists\">Delete directory if already exists. Default true.</param>\r\n        /// <param name=\"cleanup\">Deletes directory at disposing time. Default true.</param>\r\n        public TempDirectory(\r\n            string? directoryName = null,\r\n            bool deleteIfExists = true,\r\n            bool cleanup = true)\r\n        {\r\n            var path = Path.GetTempPath();\r\n\r\n            if (directoryName is null)\r\n            {\r\n                this.DirectoryName = Path.GetRandomFileName();\r\n            }\r\n            else\r\n            {\r\n                this.DirectoryName = directoryName;\r\n            }\r\n\r\n            this.FullDirectoryPath = Path.Combine(Path.GetTempPath(), this.DirectoryName);\r\n\r\n            if (deleteIfExists && Directory.Exists(this.FullDirectoryPath))\r\n            {\r\n                Directory.Delete(this.FullDirectoryPath, true);\r\n            }\r\n\r\n            Directory.CreateDirectory(this.FullDirectoryPath);\r\n            this.cleanup = cleanup;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the directory name.\r\n        /// </summary>\r\n        public string DirectoryName { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the full directory name.\r\n        /// </summary>\r\n        public string FullDirectoryPath { get; }\r\n\r\n        /// <summary>\r\n        /// IDisposable.Dispose .\r\n        /// </summary>\r\n        public void Dispose()\r\n        {\r\n            this.Dispose(true);\r\n            GC.SuppressFinalize(this);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Copies all contents of a directory into this directory.\r\n        /// </summary>\r\n        /// <param name=\"sourceDir\">Source directory.</param>\r\n        public void CopyDirectory(string sourceDir)\r\n        {\r\n            this.CopyDirectory(sourceDir, this.FullDirectoryPath);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Protected disposed.\r\n        /// </summary>\r\n        /// <param name=\"disposing\">Disposing.</param>\r\n        protected virtual void Dispose(bool disposing)\r\n        {\r\n            if (!this.disposed)\r\n            {\r\n                if (this.cleanup && Directory.Exists(this.FullDirectoryPath))\r\n                {\r\n                    Directory.Delete(this.FullDirectoryPath, true);\r\n                }\r\n\r\n                this.disposed = true;\r\n            }\r\n        }\r\n\r\n        private void CopyDirectory(string sourceDir, string destinationDir)\r\n        {\r\n            var dir = new DirectoryInfo(sourceDir);\r\n\r\n            if (!dir.Exists)\r\n            {\r\n                throw new DirectoryNotFoundException(dir.FullName);\r\n            }\r\n\r\n            Directory.CreateDirectory(destinationDir);\r\n\r\n            foreach (FileInfo file in dir.GetFiles())\r\n            {\r\n                file.CopyTo(Path.Combine(destinationDir, file.Name));\r\n            }\r\n\r\n            foreach (DirectoryInfo subDir in dir.GetDirectories())\r\n            {\r\n                this.CopyDirectory(subDir.FullName, Path.Combine(destinationDir, subDir.Name));\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/TempFile.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"TempFile.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using System;\r\n    using System.IO;\r\n\r\n    /// <summary>\r\n    /// Creates a temporary file in the user's temporary directory.\r\n    /// </summary>\r\n    internal class TempFile : IDisposable\r\n    {\r\n        private bool disposed = false;\r\n        private bool cleanup;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"TempFile\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fileName\">Optional file name. If null, creates a random file name.</param>\r\n        /// <param name=\"deleteIfExists\">Delete file if already exists. Default true.</param>\r\n        /// <param name=\"content\">Optional content. If not null or empty, creates file and writes to it.</param>\r\n        /// <param name=\"cleanup\">Deletes file at disposing time. Default true.</param>\r\n        public TempFile(\r\n            string? fileName = null,\r\n            bool deleteIfExists = true,\r\n            string? content = null,\r\n            bool cleanup = true)\r\n        {\r\n            if (fileName is null)\r\n            {\r\n                this.FileName = Path.GetRandomFileName();\r\n            }\r\n            else\r\n            {\r\n                this.FileName = fileName;\r\n            }\r\n\r\n            this.FullFileName = Path.Combine(Path.GetTempPath(), this.FileName);\r\n\r\n            if (deleteIfExists && File.Exists(this.FullFileName))\r\n            {\r\n                File.Delete(this.FullFileName);\r\n            }\r\n\r\n            if (!string.IsNullOrWhiteSpace(content))\r\n            {\r\n                this.CreateFile(content);\r\n            }\r\n\r\n            this.cleanup = cleanup;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the file name.\r\n        /// </summary>\r\n        public string FileName { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the full file name.\r\n        /// </summary>\r\n        public string FullFileName { get; }\r\n\r\n        /// <summary>\r\n        /// IDisposable.Dispose .\r\n        /// </summary>\r\n        public void Dispose()\r\n        {\r\n            this.Dispose(true);\r\n            GC.SuppressFinalize(this);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates the file.\r\n        /// </summary>\r\n        /// <param name=\"content\">Content.</param>\r\n        public void CreateFile(string? content = null)\r\n        {\r\n            if (content is null)\r\n            {\r\n                using var fs = File.Create(this.FullFileName);\r\n            }\r\n            else\r\n            {\r\n                File.WriteAllText(this.FullFileName, content);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Protected disposed.\r\n        /// </summary>\r\n        /// <param name=\"disposing\">Disposing.</param>\r\n        protected virtual void Dispose(bool disposing)\r\n        {\r\n            if (!this.disposed)\r\n            {\r\n                if (this.cleanup && File.Exists(this.FullFileName))\r\n                {\r\n                    File.Delete(this.FullFileName);\r\n                }\r\n\r\n                this.disposed = true;\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationProcessorFactory.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"TestConfigurationProcessorFactory.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n\r\n    /// <summary>\r\n    /// A test implementation of IConfigurationSetProcessorFactory.\r\n    /// </summary>\r\n    internal partial class TestConfigurationProcessorFactory : IConfigurationSetProcessorFactory\r\n    {\r\n        /// <summary>\r\n        /// Delegate type for CreateSetProcessor.\r\n        /// </summary>\r\n        /// <param name=\"factory\">The TestConfigurationProcessorFactory that is calling this function.</param>\r\n        /// <param name=\"configurationSet\">The set.</param>\r\n        /// <returns>A new TestConfigurationSetProcessor for the set.</returns>\r\n        internal delegate IConfigurationSetProcessor CreateSetProcessorDelegateType(TestConfigurationProcessorFactory factory, ConfigurationSet configurationSet);\r\n\r\n        /// <summary>\r\n        /// Diagnostics event; useful for logging and/or verbose output.\r\n        /// </summary>\r\n#pragma warning disable CS0067 // The event is never used\r\n        public event EventHandler<IDiagnosticInformation>? Diagnostics;\r\n#pragma warning restore CS0067 // The event is never used\r\n\r\n        /// <summary>\r\n        /// Gets or sets the minimum diagnostic level to send.\r\n        /// </summary>\r\n        public DiagnosticLevel MinimumLevel { get; set; } = DiagnosticLevel.Informational;\r\n\r\n        /// <summary>\r\n        /// Gets or sets the processor used when the incoming configuration set is null.\r\n        /// </summary>\r\n        internal TestConfigurationSetProcessor? NullProcessor { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the processors to be used by this factory.\r\n        /// </summary>\r\n        internal Dictionary<ConfigurationSet, TestConfigurationSetProcessor> Processors { get; set; } =\r\n            new Dictionary<ConfigurationSet, TestConfigurationSetProcessor>();\r\n\r\n        /// <summary>\r\n        /// Gets or sets the exception used when the incoming configuration set is null.\r\n        /// </summary>\r\n        internal Exception? NullException { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the exceptions to be used by this factory.\r\n        /// </summary>\r\n        internal Dictionary<ConfigurationSet, Exception> Exceptions { get; set; } =\r\n            new Dictionary<ConfigurationSet, Exception>();\r\n\r\n        /// <summary>\r\n        /// Gets or sets the delegate use to replace the default CreateSetProcessor functionality.\r\n        /// </summary>\r\n        internal CreateSetProcessorDelegateType? CreateSetProcessorDelegate { get; set; }\r\n\r\n        /// <summary>\r\n        /// Creates a new TestConfigurationSetProcessor for the set.\r\n        /// </summary>\r\n        /// <param name=\"configurationSet\">The set.</param>\r\n        /// <returns>A new TestConfigurationSetProcessor for the set.</returns>\r\n        public IConfigurationSetProcessor CreateSetProcessor(ConfigurationSet configurationSet)\r\n        {\r\n            if (this.CreateSetProcessorDelegate != null)\r\n            {\r\n                return this.CreateSetProcessorDelegate(this, configurationSet);\r\n            }\r\n\r\n            return this.DefaultCreateSetProcessor(configurationSet);\r\n        }\r\n\r\n        /// <summary>\r\n        /// The default test implementation that creates a new TestConfigurationSetProcessor for the set.\r\n        /// </summary>\r\n        /// <param name=\"configurationSet\">The set.</param>\r\n        /// <returns>A new TestConfigurationSetProcessor for the set.</returns>\r\n        internal IConfigurationSetProcessor DefaultCreateSetProcessor(ConfigurationSet configurationSet)\r\n        {\r\n            if (configurationSet == null)\r\n            {\r\n                if (this.NullException != null)\r\n                {\r\n                    throw this.NullException;\r\n                }\r\n\r\n                if (this.NullProcessor == null)\r\n                {\r\n                    this.NullProcessor = new TestConfigurationSetProcessor(null);\r\n                }\r\n\r\n                return this.NullProcessor;\r\n            }\r\n\r\n            if (this.Exceptions.ContainsKey(configurationSet))\r\n            {\r\n                throw this.Exceptions[configurationSet];\r\n            }\r\n\r\n            if (!this.Processors.ContainsKey(configurationSet))\r\n            {\r\n                this.Processors.Add(configurationSet, new TestConfigurationSetProcessor(configurationSet));\r\n            }\r\n\r\n            return this.Processors[configurationSet];\r\n        }\r\n\r\n        /// <summary>\r\n        /// A convenience function to create a new processor for the given set and store it in the dictionary for use in the test.\r\n        /// </summary>\r\n        /// <param name=\"configurationSet\">The set.</param>\r\n        /// <returns>A new TestConfigurationSetProcessor for the set.</returns>\r\n        internal TestConfigurationSetProcessor CreateTestProcessor(ConfigurationSet configurationSet)\r\n        {\r\n            this.Processors[configurationSet] = new TestConfigurationSetProcessor(configurationSet);\r\n            return this.Processors[configurationSet];\r\n        }\r\n\r\n        /// <summary>\r\n        /// A convenience function to create a new group processor for the given set and store it in the dictionary for use in the test.\r\n        /// </summary>\r\n        /// <param name=\"configurationSet\">The set.</param>\r\n        /// <returns>A new TestConfigurationSetGroupProcessor for the set.</returns>\r\n        internal TestConfigurationSetGroupProcessor CreateTestGroupProcessor(ConfigurationSet configurationSet)\r\n        {\r\n            TestConfigurationSetGroupProcessor result = new (configurationSet);\r\n            this.Processors[configurationSet] = result;\r\n            return result;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationSetGroupProcessor.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"TestConfigurationSetGroupProcessor.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.Diagnostics;\r\n    using System.Runtime.InteropServices.WindowsRuntime;\r\n    using System.Threading;\r\n    using System.Threading.Tasks;\r\n    using Windows.Foundation;\r\n    using Windows.Foundation.Collections;\r\n\r\n    /// <summary>\r\n    /// A test implementation of IConfigurationGroupProcessor.\r\n    /// </summary>\r\n    internal partial class TestConfigurationSetGroupProcessor : TestConfigurationSetProcessor, IConfigurationGroupProcessor\r\n    {\r\n        /// <summary>\r\n        /// The event that is waited on before actually processing the async operations.\r\n        /// </summary>\r\n        private AutoResetEvent asyncWaitEvent = new AutoResetEvent(false);\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"TestConfigurationSetGroupProcessor\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"set\">The set that this processor is for.</param>\r\n        internal TestConfigurationSetGroupProcessor(ConfigurationSet? set)\r\n            : base(set)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the group that this processor targets.\r\n        /// </summary>\r\n        public object? Group\r\n        {\r\n            get { return this.Set; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether the async methods should wait on an event before processing.\r\n        /// </summary>\r\n        internal bool ShouldWaitOnAsyncEvent { get; set; } = false;\r\n\r\n        /// <summary>\r\n        /// Apply settings for the group.\r\n        /// </summary>\r\n        /// <param name=\"progressHandler\">The progress handler.</param>\r\n        /// <returns>The operation to apply settings.</returns>\r\n        public IAsyncOperation<IApplyGroupSettingsResult> ApplyGroupSettingsAsync(EventHandler<IApplyGroupMemberSettingsResult> progressHandler)\r\n        {\r\n            return AsyncInfo.Run((CancellationToken cancellationToken) => Task.Run<IApplyGroupSettingsResult>(() =>\r\n            {\r\n                this.WaitOnAsyncEvent(cancellationToken);\r\n\r\n                ApplyGroupSettingsResultInstance result = new (this.Group);\r\n                result.UnitResults = new List<IApplyGroupMemberSettingsResult>();\r\n\r\n                if (this.Set != null)\r\n                {\r\n                    TestConfigurationUnitGroupProcessor.ApplyGroupSettings(this.Set.Units, progressHandler, result);\r\n                }\r\n\r\n                return result;\r\n            }));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test settings for the group.\r\n        /// </summary>\r\n        /// <param name=\"progressHandler\">The progress handler.</param>\r\n        /// <returns>The operation to test settings.</returns>\r\n        public IAsyncOperation<ITestGroupSettingsResult> TestGroupSettingsAsync(EventHandler<ITestSettingsResult> progressHandler)\r\n        {\r\n            return AsyncInfo.Run((CancellationToken cancellationToken) => Task.Run<ITestGroupSettingsResult>(() =>\r\n            {\r\n                this.WaitOnAsyncEvent(cancellationToken);\r\n\r\n                TestGroupSettingsResultInstance result = new (this.Group);\r\n                result.UnitResults = new List<ITestSettingsResult>();\r\n\r\n                if (this.Set != null)\r\n                {\r\n                    result.TestResult = TestConfigurationUnitGroupProcessor.GetTestResult(this.Set.Metadata);\r\n                    TestConfigurationUnitGroupProcessor.TestGroupSettings(this.Set.Units, progressHandler, result);\r\n                }\r\n\r\n                return result;\r\n            }));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Signals the async event.\r\n        /// </summary>\r\n        internal void SignalAsyncEvent()\r\n        {\r\n            this.asyncWaitEvent.Set();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Waits on the async event.\r\n        /// </summary>\r\n        private void WaitOnAsyncEvent(CancellationToken cancellationToken)\r\n        {\r\n            if (this.ShouldWaitOnAsyncEvent)\r\n            {\r\n                cancellationToken.Register(() => this.asyncWaitEvent.Set());\r\n                if (!this.asyncWaitEvent.WaitOne(10000))\r\n                {\r\n                    throw new TimeoutException();\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationSetProcessor.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"TestConfigurationSetProcessor.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n\r\n    /// <summary>\r\n    /// A test implementation of IConfigurationSetProcessor.\r\n    /// </summary>\r\n    internal partial class TestConfigurationSetProcessor : IConfigurationSetProcessor\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"TestConfigurationSetProcessor\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"set\">The set that this processor is for.</param>\r\n        internal TestConfigurationSetProcessor(ConfigurationSet? set)\r\n        {\r\n            this.Set = set;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the processors to be used by this factory.\r\n        /// </summary>\r\n        internal Dictionary<ConfigurationUnit, TestConfigurationUnitProcessor> Processors { get; set; } =\r\n            new Dictionary<ConfigurationUnit, TestConfigurationUnitProcessor>();\r\n\r\n        /// <summary>\r\n        /// Gets or sets the details to be used by this factory.\r\n        /// </summary>\r\n        internal Dictionary<ConfigurationUnit, TestConfigurationUnitProcessorDetails> Details { get; set; } =\r\n            new Dictionary<ConfigurationUnit, TestConfigurationUnitProcessorDetails>();\r\n\r\n        /// <summary>\r\n        /// Gets or sets the exceptions to be used by this factory.\r\n        /// </summary>\r\n        internal Dictionary<ConfigurationUnit, Exception> Exceptions { get; set; } =\r\n            new Dictionary<ConfigurationUnit, Exception>();\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether the default unit processors for groups will enable group processing.\r\n        /// </summary>\r\n        internal bool EnableDefaultGroupProcessorCreation { get; set; } = false;\r\n\r\n        /// <summary>\r\n        /// Gets the ConfigurationSet that this processor targets.\r\n        /// </summary>\r\n        protected ConfigurationSet? Set { get; private set; }\r\n\r\n        /// <summary>\r\n        /// Creates a new unit processor for the given unit.\r\n        /// </summary>\r\n        /// <param name=\"unit\">The unit.</param>\r\n        /// <returns>The configuration unit processor.</returns>\r\n        public IConfigurationUnitProcessor CreateUnitProcessor(ConfigurationUnit unit)\r\n        {\r\n            if (this.Exceptions.ContainsKey(unit))\r\n            {\r\n                throw this.Exceptions[unit];\r\n            }\r\n\r\n            if (!this.Processors.ContainsKey(unit))\r\n            {\r\n                if (this.EnableDefaultGroupProcessorCreation && unit.IsGroup)\r\n                {\r\n                    this.Processors.Add(unit, new TestConfigurationUnitGroupProcessor(unit));\r\n                }\r\n                else\r\n                {\r\n                    this.Processors.Add(unit, new TestConfigurationUnitProcessor(unit));\r\n                }\r\n            }\r\n\r\n            return this.Processors[unit];\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the unit processor details for the given unit.\r\n        /// </summary>\r\n        /// <param name=\"unit\">The unit.</param>\r\n        /// <param name=\"detailFlags\">The detail flags.</param>\r\n        /// <returns>The details requested.</returns>\r\n        public IConfigurationUnitProcessorDetails GetUnitProcessorDetails(ConfigurationUnit unit, ConfigurationUnitDetailFlags detailFlags)\r\n        {\r\n            if (this.Exceptions.ContainsKey(unit))\r\n            {\r\n                throw this.Exceptions[unit];\r\n            }\r\n\r\n            if (!this.Details.ContainsKey(unit))\r\n            {\r\n                this.Details.Add(unit, new TestConfigurationUnitProcessorDetails(unit, detailFlags));\r\n            }\r\n\r\n            return this.Details[unit];\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates a new test processor for the given unit.\r\n        /// </summary>\r\n        /// <param name=\"unit\">The unit.</param>\r\n        /// <returns>The configuration unit processor.</returns>\r\n        internal TestConfigurationUnitProcessor CreateTestProcessor(ConfigurationUnit unit)\r\n        {\r\n            this.Processors[unit] = new TestConfigurationUnitProcessor(unit);\r\n            return this.Processors[unit];\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates a new test group processor for the given unit.\r\n        /// </summary>\r\n        /// <param name=\"unit\">The unit.</param>\r\n        /// <returns>A new TestConfigurationUnitGroupProcessor for the unit.</returns>\r\n        internal TestConfigurationUnitGroupProcessor CreateTestGroupProcessor(ConfigurationUnit unit)\r\n        {\r\n            TestConfigurationUnitGroupProcessor result = new (unit);\r\n            this.Processors[unit] = result;\r\n            return result;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates a new test processor that supports GetAllSettings for the given unit.\r\n        /// </summary>\r\n        /// <param name=\"unit\">The unit.</param>\r\n        /// <returns>The configuration unit processor.</returns>\r\n        internal TestGetAllSettingsConfigurationUnitProcessor CreateGetAllSettingsTestProcessor(ConfigurationUnit unit)\r\n        {\r\n            var processor = new TestGetAllSettingsConfigurationUnitProcessor(unit);\r\n            this.Processors[unit] = processor;\r\n            return processor;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates a new unit processor details for the given unit.\r\n        /// </summary>\r\n        /// <param name=\"unit\">The unit.</param>\r\n        /// <param name=\"detailFlags\">The detail flags.</param>\r\n        /// <returns>The details requested.</returns>\r\n        internal TestConfigurationUnitProcessorDetails CreateUnitDetails(ConfigurationUnit unit, ConfigurationUnitDetailFlags detailFlags)\r\n        {\r\n            this.Details[unit] = new TestConfigurationUnitProcessorDetails(unit, detailFlags);\r\n            return this.Details[unit];\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitGroupProcessor.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"TestConfigurationUnitGroupProcessor.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.Diagnostics;\r\n    using System.Runtime.InteropServices.WindowsRuntime;\r\n    using System.Threading;\r\n    using System.Threading.Tasks;\r\n    using Windows.Foundation;\r\n    using Windows.Foundation.Collections;\r\n\r\n    /// <summary>\r\n    /// A test implementation of IConfigurationGroupProcessor.\r\n    /// </summary>\r\n    internal partial class TestConfigurationUnitGroupProcessor : TestConfigurationUnitProcessor, IConfigurationGroupProcessor\r\n    {\r\n        /// <summary>\r\n        /// The Setting key that will be used to set the TestResult of the unit.\r\n        /// </summary>\r\n        internal const string TestResultSetting = \"TestResult\";\r\n\r\n        /// <summary>\r\n        /// The event that is waited on before actually processing the async operations.\r\n        /// </summary>\r\n        private AutoResetEvent asyncWaitEvent = new AutoResetEvent(false);\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"TestConfigurationUnitGroupProcessor\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"unit\">The unit that this processor is for.</param>\r\n        internal TestConfigurationUnitGroupProcessor(ConfigurationUnit unit)\r\n            : base(unit)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the group that this processor targets.\r\n        /// </summary>\r\n        public object Group\r\n        {\r\n            get { return this.Unit; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether the async methods should wait on an event before processing.\r\n        /// </summary>\r\n        internal bool ShouldWaitOnAsyncEvent { get; set; } = false;\r\n\r\n        /// <summary>\r\n        /// Apply settings for the group.\r\n        /// </summary>\r\n        /// <param name=\"progressHandler\">The progress handler.</param>\r\n        /// <returns>The operation to apply settings.</returns>\r\n        public IAsyncOperation<IApplyGroupSettingsResult> ApplyGroupSettingsAsync(EventHandler<IApplyGroupMemberSettingsResult> progressHandler)\r\n        {\r\n            return AsyncInfo.Run((CancellationToken cancellationToken) => Task.Run<IApplyGroupSettingsResult>(() =>\r\n            {\r\n                this.WaitOnAsyncEvent(cancellationToken);\r\n\r\n                ApplyGroupSettingsResultInstance result = new (this.Group);\r\n                result.UnitResults = new List<IApplyGroupMemberSettingsResult>();\r\n\r\n                ApplyGroupSettings(this.Unit.Units, progressHandler, result);\r\n\r\n                return result;\r\n            }));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test settings for the group.\r\n        /// </summary>\r\n        /// <param name=\"progressHandler\">The progress handler.</param>\r\n        /// <returns>The operation to test settings.</returns>\r\n        public IAsyncOperation<ITestGroupSettingsResult> TestGroupSettingsAsync(EventHandler<ITestSettingsResult> progressHandler)\r\n        {\r\n            return AsyncInfo.Run((CancellationToken cancellationToken) => Task.Run<ITestGroupSettingsResult>(() =>\r\n            {\r\n                this.WaitOnAsyncEvent(cancellationToken);\r\n\r\n                TestGroupSettingsResultInstance result = new (this.Group);\r\n                result.UnitResults = new List<ITestSettingsResult>();\r\n\r\n                result.TestResult = GetTestResult(this.Unit.Metadata);\r\n                TestGroupSettings(this.Unit.Units, progressHandler, result);\r\n\r\n                return result;\r\n            }));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the tests result for the given unit.\r\n        /// </summary>\r\n        /// <param name=\"unit\">The unit.</param>\r\n        /// <returns>The test result for the unit.</returns>\r\n        internal static ConfigurationTestResult GetTestResult(ConfigurationUnit unit)\r\n        {\r\n            return GetTestResult(unit.Settings);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the tests result for the given values.\r\n        /// </summary>\r\n        /// <param name=\"values\">The values.</param>\r\n        /// <returns>The test result for the values.</returns>\r\n        internal static ConfigurationTestResult GetTestResult(ValueSet values)\r\n        {\r\n            if (values.ContainsKey(TestResultSetting))\r\n            {\r\n                string? valueString = values[TestResultSetting]?.ToString();\r\n                if (valueString != null)\r\n                {\r\n                    return Enum.Parse<ConfigurationTestResult>(valueString);\r\n                }\r\n            }\r\n\r\n            return ConfigurationTestResult.Positive;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Applies group settings for the given group members.\r\n        /// </summary>\r\n        /// <param name=\"groupMembers\">The group members.</param>\r\n        /// <param name=\"progress\">The progress reporting object.</param>\r\n        /// <param name=\"result\">The result object.</param>\r\n        internal static void ApplyGroupSettings(IList<ConfigurationUnit>? groupMembers, EventHandler<IApplyGroupMemberSettingsResult> progress, ApplyGroupSettingsResultInstance result)\r\n        {\r\n            if (groupMembers != null)\r\n            {\r\n                foreach (ConfigurationUnit unit in groupMembers)\r\n                {\r\n                    ApplyGroupMemberSettingsResultInstance unitResult = new (unit);\r\n                    result.UnitResults!.Add(unitResult);\r\n\r\n                    unitResult.State = ConfigurationUnitState.InProgress;\r\n                    progress.Invoke(null, unitResult);\r\n\r\n                    unitResult.PreviouslyInDesiredState = GetTestResult(unit) == ConfigurationTestResult.Positive;\r\n\r\n                    if (unit.IsGroup)\r\n                    {\r\n                        ApplyGroupSettings(unit.Units, progress, result);\r\n                    }\r\n\r\n                    unitResult.State = ConfigurationUnitState.Completed;\r\n                    progress.Invoke(null, unitResult);\r\n                }\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests group settings for the given group members.\r\n        /// </summary>\r\n        /// <param name=\"groupMembers\">The group members.</param>\r\n        /// <param name=\"progress\">The progress reporting object.</param>\r\n        /// <param name=\"result\">The result object.</param>\r\n        internal static void TestGroupSettings(IList<ConfigurationUnit>? groupMembers, EventHandler<ITestSettingsResult> progress, TestGroupSettingsResultInstance result)\r\n        {\r\n            if (groupMembers != null)\r\n            {\r\n                foreach (ConfigurationUnit unit in groupMembers)\r\n                {\r\n                    TestSettingsResultInstance unitResult = new (unit);\r\n\r\n                    if (unit.IsGroup)\r\n                    {\r\n                        TestGroupSettings(unit.Units, progress, result);\r\n                    }\r\n\r\n                    unitResult.TestResult = GetTestResult(unit);\r\n                    result.UnitResults!.Add(unitResult);\r\n                    progress.Invoke(null, unitResult);\r\n                }\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Signals the async event.\r\n        /// </summary>\r\n        internal void SignalAsyncEvent()\r\n        {\r\n            this.asyncWaitEvent.Set();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Waits on the async event.\r\n        /// </summary>\r\n        private void WaitOnAsyncEvent(CancellationToken cancellationToken)\r\n        {\r\n            if (this.ShouldWaitOnAsyncEvent)\r\n            {\r\n                cancellationToken.Register(() => this.asyncWaitEvent.Set());\r\n                if (!this.asyncWaitEvent.WaitOne(10000))\r\n                {\r\n                    throw new TimeoutException();\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitProcessor.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"TestConfigurationUnitProcessor.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using System.Collections.Generic;\r\n\r\n    /// <summary>\r\n    /// A test implementation of IConfigurationProcessorFactory.\r\n    /// </summary>\r\n    internal partial class TestConfigurationUnitProcessor : IConfigurationUnitProcessor\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"TestConfigurationUnitProcessor\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"unit\">The unit.</param>\r\n        internal TestConfigurationUnitProcessor(ConfigurationUnit unit)\r\n        {\r\n            this.Unit = unit;\r\n        }\r\n\r\n        /// <summary>\r\n        /// The delegate for ApplySettings.\r\n        /// </summary>\r\n        /// <returns>The result.</returns>\r\n        internal delegate IApplySettingsResult ApplySettingsDelegateType();\r\n\r\n        /// <summary>\r\n        /// The delegate for GetSettings.\r\n        /// </summary>\r\n        /// <returns>The result.</returns>\r\n        internal delegate IGetSettingsResult GetSettingsDelegateType();\r\n\r\n        /// <summary>\r\n        /// The delegate for TestSettings.\r\n        /// </summary>\r\n        /// <returns>The result.</returns>\r\n        internal delegate ITestSettingsResult TestSettingsDelegateType();\r\n\r\n        /// <summary>\r\n        /// The delegate for TestSettings that passes the unit in.\r\n        /// </summary>\r\n        /// <param name=\"unit\">The unit.</param>\r\n        /// <returns>The result.</returns>\r\n        internal delegate ITestSettingsResult TestSettingsDelegateWithUnitType(ConfigurationUnit unit);\r\n\r\n        /// <summary>\r\n        /// Gets or sets the directives overlay.\r\n        /// </summary>\r\n        public IReadOnlyDictionary<string, object>? DirectivesOverlay { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets the configuration unit.\r\n        /// </summary>\r\n        public ConfigurationUnit Unit { get; private set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the delegate object for ApplySettings.\r\n        /// </summary>\r\n        internal ApplySettingsDelegateType? ApplySettingsDelegate { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets the number of times ApplySettings is called.\r\n        /// </summary>\r\n        internal int ApplySettingsCalls { get; private set; } = 0;\r\n\r\n        /// <summary>\r\n        /// Gets or sets the delegate object for GetSettings.\r\n        /// </summary>\r\n        internal GetSettingsDelegateType? GetSettingsDelegate { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets the number of times GetSettings is called.\r\n        /// </summary>\r\n        internal int GetSettingsCalls { get; private set; } = 0;\r\n\r\n        /// <summary>\r\n        /// Gets or sets the delegate object for TestSettings.\r\n        /// </summary>\r\n        internal TestSettingsDelegateType? TestSettingsDelegate { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the delegate object for TestSettings that takes in the unit.\r\n        /// </summary>\r\n        internal TestSettingsDelegateWithUnitType? TestSettingsDelegateWithUnit { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets the number of times TestSettings is called.\r\n        /// </summary>\r\n        internal int TestSettingsCalls { get; private set; } = 0;\r\n\r\n        /// <summary>\r\n        /// Calls the ApplySettingsDelegate if one is provided; returns success if not.\r\n        /// </summary>\r\n        /// <returns>The result.</returns>\r\n        public IApplySettingsResult ApplySettings()\r\n        {\r\n            ++this.ApplySettingsCalls;\r\n            if (this.ApplySettingsDelegate != null)\r\n            {\r\n                return this.ApplySettingsDelegate();\r\n            }\r\n            else\r\n            {\r\n                return new ApplySettingsResultInstance(this.Unit);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls the GetSettingsDelegate if one is provided; returns success if not (with no settings values).\r\n        /// </summary>\r\n        /// <returns>The result.</returns>\r\n        public IGetSettingsResult GetSettings()\r\n        {\r\n            ++this.GetSettingsCalls;\r\n            if (this.GetSettingsDelegate != null)\r\n            {\r\n                return this.GetSettingsDelegate();\r\n            }\r\n            else\r\n            {\r\n                return new GetSettingsResultInstance(this.Unit);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls the TestSettingsDelegate if one is provided; returns success if not (with a positive test result).\r\n        /// </summary>\r\n        /// <returns>The result.</returns>\r\n        public ITestSettingsResult TestSettings()\r\n        {\r\n            ++this.TestSettingsCalls;\r\n            if (this.TestSettingsDelegateWithUnit != null)\r\n            {\r\n                return this.TestSettingsDelegateWithUnit(this.Unit);\r\n            }\r\n            else if (this.TestSettingsDelegate != null)\r\n            {\r\n                return this.TestSettingsDelegate();\r\n            }\r\n            else\r\n            {\r\n                return new TestSettingsResultInstance(this.Unit) { TestResult = ConfigurationTestResult.Positive };\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitProcessorDetails.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"TestConfigurationUnitProcessorDetails.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using Windows.Security.Cryptography.Certificates;\r\n\r\n    /// <summary>\r\n    /// A test implementation of IConfigurationProcessorFactory.\r\n    /// </summary>\r\n    internal partial class TestConfigurationUnitProcessorDetails : IConfigurationUnitProcessorDetails\r\n    {\r\n        private ConfigurationUnit unit;\r\n        private ConfigurationUnitDetailFlags detailFlags;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"TestConfigurationUnitProcessorDetails\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"unit\">The unit.</param>\r\n        /// <param name=\"detailFlags\">The flags of the details.</param>\r\n        internal TestConfigurationUnitProcessorDetails(ConfigurationUnit unit, ConfigurationUnitDetailFlags detailFlags)\r\n        {\r\n            this.unit = unit;\r\n            this.detailFlags = detailFlags;\r\n        }\r\n\r\n#pragma warning disable SA1600 // Elements should be documented\r\n        public string? Author { get; internal set; }\r\n\r\n        public bool IsLocal { get; internal set; }\r\n\r\n        public string? ModuleDescription { get; internal set; }\r\n\r\n        public Uri? ModuleDocumentationUri { get; internal set; }\r\n\r\n        public string? ModuleName { get; internal set; }\r\n\r\n        public string? ModuleSource { get; internal set; }\r\n\r\n        public string? ModuleType { get; internal set; }\r\n\r\n        public DateTimeOffset PublishedDate { get; internal set; }\r\n\r\n        public Uri? PublishedModuleUri { get; internal set; }\r\n\r\n        public string? Publisher { get; internal set; }\r\n\r\n        public IReadOnlyList<IConfigurationUnitSettingDetails>? Settings { get; internal set; }\r\n\r\n        public IReadOnlyList<object>? SigningInformation { get; internal set; }\r\n\r\n        public string? UnitDescription { get; internal set; }\r\n\r\n        public Uri? UnitDocumentationUri { get; internal set; }\r\n\r\n        public Uri? UnitIconUri { get; internal set; }\r\n\r\n        public string? UnitType { get; internal set; }\r\n\r\n        public string? Version { get; internal set; }\r\n\r\n        public bool IsPublic { get; internal set; }\r\n#pragma warning restore SA1600 // Elements should be documented\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/TestConfigurationUnitResultInformation.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"TestConfigurationUnitResultInformation.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n\r\n    /// <summary>\r\n    /// A test implementation of IConfigurationSetProcessorFactory.\r\n    /// </summary>\r\n    internal partial class TestConfigurationUnitResultInformation : IConfigurationUnitResultInformation\r\n    {\r\n        /// <summary>\r\n        /// Gets or sets the description.\r\n        /// </summary>\r\n        public string Description { get; set; } = string.Empty;\r\n\r\n        /// <summary>\r\n        /// Gets or sets the details.\r\n        /// </summary>\r\n        public string Details { get; set; } = string.Empty;\r\n\r\n        /// <summary>\r\n        /// Gets or sets the result code.\r\n        /// </summary>\r\n        public Exception? ResultCode { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the result source.\r\n        /// </summary>\r\n        public ConfigurationUnitResultSource ResultSource { get; set; } = ConfigurationUnitResultSource.None;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/TestDSCv3.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"TestDSCv3.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using System.Collections.Generic;\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Helpers;\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Model;\r\n    using Microsoft.Management.Configuration.Processor.Helpers;\r\n\r\n    /// <summary>\r\n    /// Implements IDSCv3 for tests.\r\n    /// </summary>\r\n    internal class TestDSCv3 : IDSCv3\r\n    {\r\n        /// <summary>\r\n        /// The delegate type for GetResourceByType.\r\n        /// </summary>\r\n        /// <param name=\"resourceType\">The type name of the resource.</param>\r\n        /// <returns>A single resource item.</returns>\r\n        internal delegate IResourceListItem? GetResourceByTypeDelegateType(string resourceType);\r\n\r\n        /// <summary>\r\n        /// The delegate type for GetResourceSettings.\r\n        /// </summary>\r\n        /// <param name=\"unitInternal\">The unit to get.</param>\r\n        /// <returns>A get result.</returns>\r\n        internal delegate IResourceGetItem GetResourceSettingsDelegateType(ConfigurationUnitInternal unitInternal);\r\n\r\n        /// <summary>\r\n        /// The delegate type for SetResourceSettings.\r\n        /// </summary>\r\n        /// <param name=\"unitInternal\">The unit to set.</param>\r\n        /// <returns>A set result.</returns>\r\n        internal delegate IResourceSetItem SetResourceSettingsDelegateType(ConfigurationUnitInternal unitInternal);\r\n\r\n        /// <summary>\r\n        /// The delegate type for TestResource.\r\n        /// </summary>\r\n        /// <param name=\"unitInternal\">The unit to test.</param>\r\n        /// <returns>A test result.</returns>\r\n        internal delegate IResourceTestItem TestResourceDelegateType(ConfigurationUnitInternal unitInternal);\r\n\r\n        /// <summary>\r\n        /// The delegate type for TestResource.\r\n        /// </summary>\r\n        /// <param name=\"unitInternal\">The unit to test.</param>\r\n        /// <returns>A test result.</returns>\r\n        internal delegate IList<IResourceExportItem> ExportResourceDelegateType(ConfigurationUnitInternal unitInternal);\r\n\r\n        /// <summary>\r\n        /// Gets or sets the GetResourceByType result.\r\n        /// </summary>\r\n        public IResourceListItem? GetResourceByTypeResult { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the GetResourceByType delegate.\r\n        /// </summary>\r\n        public GetResourceByTypeDelegateType? GetResourceByTypeDelegate { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the GetResourceSettings result.\r\n        /// </summary>\r\n        public IResourceGetItem? GetResourceSettingsResult { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the GetResourceSettings delegate.\r\n        /// </summary>\r\n        public GetResourceSettingsDelegateType? GetResourceSettingsDelegate { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the SetResourceSettings result.\r\n        /// </summary>\r\n        public IResourceSetItem? SetResourceSettingsResult { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the SetResourceSettings delegate.\r\n        /// </summary>\r\n        public SetResourceSettingsDelegateType? SetResourceSettingsDelegate { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the TestResource result.\r\n        /// </summary>\r\n        public IResourceTestItem? TestResourceResult { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the TestResource delegate.\r\n        /// </summary>\r\n        public TestResourceDelegateType? TestResourceDelegate { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the ExportResource result.\r\n        /// </summary>\r\n        public IList<IResourceExportItem>? ExportResourceResult { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the ExportResource delegate.\r\n        /// </summary>\r\n        public ExportResourceDelegateType? ExportResourceDelegate { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the GetAllResources result.\r\n        /// </summary>\r\n        public List<IResourceListItem>? GetAllResourcesResult { get; set; }\r\n\r\n        /// <inheritdoc/>\r\n        public IResourceListItem? GetResourceByType(string resourceType, ProcessorRunSettings? runSettings)\r\n        {\r\n            return this.GetResourceByTypeResult ?? this.GetResourceByTypeDelegate?.Invoke(resourceType);\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public IResourceGetItem GetResourceSettings(ConfigurationUnitInternal unitInternal, ProcessorRunSettings? runSettings)\r\n        {\r\n            return this.GetResourceSettingsResult ?? this.GetResourceSettingsDelegate?.Invoke(unitInternal) ?? throw new System.NotImplementedException();\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public IResourceSetItem SetResourceSettings(ConfigurationUnitInternal unitInternal, ProcessorRunSettings? runSettings)\r\n        {\r\n            return this.SetResourceSettingsResult ?? this.SetResourceSettingsDelegate?.Invoke(unitInternal) ?? throw new System.NotImplementedException();\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public IResourceTestItem TestResource(ConfigurationUnitInternal unitInternal, ProcessorRunSettings? runSettings)\r\n        {\r\n            return this.TestResourceResult ?? this.TestResourceDelegate?.Invoke(unitInternal) ?? throw new System.NotImplementedException();\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public IList<IResourceExportItem> ExportResource(ConfigurationUnitInternal unitInternal, ProcessorRunSettings? runSettings)\r\n        {\r\n            return this.ExportResourceResult ?? this.ExportResourceDelegate?.Invoke(unitInternal) ?? throw new System.NotImplementedException();\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public List<IResourceListItem> GetAllResources(ProcessorRunSettings? runSettings)\r\n        {\r\n            return this.GetAllResourcesResult ?? throw new System.NotImplementedException();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/TestGetAllSettingsConfigurationUnitProcessor.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"TestGetAllSettingsConfigurationUnitProcessor.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    /// <summary>\r\n    /// A test implementation of IConfigurationProcessorFactory.\r\n    /// </summary>\r\n    internal partial class TestGetAllSettingsConfigurationUnitProcessor : TestConfigurationUnitProcessor, IGetAllSettingsConfigurationUnitProcessor\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"TestGetAllSettingsConfigurationUnitProcessor\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"unit\">The unit.</param>\r\n        internal TestGetAllSettingsConfigurationUnitProcessor(ConfigurationUnit unit)\r\n            : base(unit)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// The delegate for GetAllSettings.\r\n        /// </summary>\r\n        /// <returns>The result.</returns>\r\n        internal delegate IGetAllSettingsResult GetAllSettingsDelegateType();\r\n\r\n        /// <summary>\r\n        /// Gets or sets the delegate object for GetAllSettings.\r\n        /// </summary>\r\n        internal GetAllSettingsDelegateType? GetAllSettingsDelegate { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets the number of times GetAllSettings is called.\r\n        /// </summary>\r\n        internal int GetAllSettingsCalls { get; private set; } = 0;\r\n\r\n        /// <summary>\r\n        /// Calls the GetAllSettingsDelegate if one is provided; returns success if not (with no settings values).\r\n        /// </summary>\r\n        /// <returns>The result.</returns>\r\n        public IGetAllSettingsResult GetAllSettings()\r\n        {\r\n            ++this.GetAllSettingsCalls;\r\n            if (this.GetAllSettingsDelegate != null)\r\n            {\r\n                return this.GetAllSettingsDelegate();\r\n            }\r\n            else\r\n            {\r\n                return new GetAllSettingsResultInstance(this.Unit);\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/TestGroupSettingsResultInstance.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"TestGroupSettingsResultInstance.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using System.Collections.Generic;\r\n\r\n    /// <summary>\r\n    /// Implements ITestGroupSettingsResult.\r\n    /// </summary>\r\n    internal partial class TestGroupSettingsResultInstance : ITestGroupSettingsResult\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"TestGroupSettingsResultInstance\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"group\">The group for this result.</param>\r\n        internal TestGroupSettingsResultInstance(object? group)\r\n        {\r\n            this.Group = group;\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public object? Group { get; private init; }\r\n\r\n        /// <inheritdoc/>\r\n        public IConfigurationUnitResultInformation ResultInformation\r\n        {\r\n            get { return this.InternalResult; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the implementation object for ResultInformation.\r\n        /// </summary>\r\n        public TestConfigurationUnitResultInformation InternalResult { get; } = new TestConfigurationUnitResultInformation();\r\n\r\n        /// <inheritdoc/>\r\n        public ConfigurationTestResult TestResult { get; internal set; }\r\n\r\n        /// <inheritdoc/>\r\n        public IList<ITestSettingsResult>? UnitResults { get; internal set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/TestResourceExportItem.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"TestResourceExportItem.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using System.Collections.Generic;\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Model;\r\n    using Windows.Foundation.Collections;\r\n\r\n    /// <summary>\r\n    /// Implements IResourceExportItem for tests.\r\n    /// </summary>\r\n    internal class TestResourceExportItem : IResourceExportItem\r\n    {\r\n        /// <summary>\r\n        /// Gets or sets the type.\r\n        /// </summary>\r\n        required public string Type { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the name.\r\n        /// </summary>\r\n        required public string Name { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the settings.\r\n        /// </summary>\r\n        public ValueSet Settings { get; set; } = new ValueSet();\r\n\r\n        /// <summary>\r\n        /// Gets or sets the metadata.\r\n        /// </summary>\r\n        public ValueSet Metadata { get; set; } = new ValueSet();\r\n\r\n        /// <summary>\r\n        /// Gets or sets the dependencies.\r\n        /// </summary>\r\n        public IList<string> Dependencies { get; set; } = new List<string>();\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/TestResourceGetItem.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"TestResourceGetItem.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Model;\r\n    using Windows.Foundation.Collections;\r\n\r\n    /// <summary>\r\n    /// Implements IResourceGetItem for tests.\r\n    /// </summary>\r\n    internal class TestResourceGetItem : IResourceGetItem\r\n    {\r\n        /// <summary>\r\n        /// Gets or sets the settings.\r\n        /// </summary>\r\n        public ValueSet Settings { get; set; } = new ValueSet();\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/TestResourceListItem.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"TestResourceListItem.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Model;\r\n\r\n    /// <summary>\r\n    /// Implements IResourceListItem for tests.\r\n    /// </summary>\r\n    internal class TestResourceListItem : IResourceListItem\r\n    {\r\n        /// <summary>\r\n        /// Gets or sets the type.\r\n        /// </summary>\r\n        required public string Type { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the kind.\r\n        /// </summary>\r\n        public ResourceKind Kind { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the version.\r\n        /// </summary>\r\n        public string? Version { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the description.\r\n        /// </summary>\r\n        public string? Description { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the directory.\r\n        /// </summary>\r\n        public string? Directory { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the author.\r\n        /// </summary>\r\n        public string? Author { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the path.\r\n        /// </summary>\r\n        public string? Path { get; set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/TestResourceSetItem.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"TestResourceSetItem.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Model;\r\n\r\n    /// <summary>\r\n    /// Implements IResourceSetItem for tests.\r\n    /// </summary>\r\n    internal class TestResourceSetItem : IResourceSetItem\r\n    {\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether a reboot is required.\r\n        /// </summary>\r\n        public bool RebootRequired { get; set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/TestResourceTestItem.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"TestResourceTestItem.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Model;\r\n\r\n    /// <summary>\r\n    /// Implements IResourceTestItem for tests.\r\n    /// </summary>\r\n    internal class TestResourceTestItem : IResourceTestItem\r\n    {\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether the system is in the desired state.\r\n        /// </summary>\r\n        public bool InDesiredState { get; set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/TestSettingsResultInstance.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"TestSettingsResultInstance.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using Microsoft.Management.Configuration;\r\n\r\n    /// <summary>\r\n    /// Implements ITestSettingsResult.\r\n    /// </summary>\r\n    internal sealed partial class TestSettingsResultInstance : ITestSettingsResult\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"TestSettingsResultInstance\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"unit\">The configuration unit that the result is for.</param>\r\n        public TestSettingsResultInstance(ConfigurationUnit unit)\r\n        {\r\n            this.Unit = unit;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the configuration unit that the result is for.\r\n        /// </summary>\r\n        public ConfigurationUnit Unit { get; private set; }\r\n\r\n        /// <inheritdoc/>\r\n        public IConfigurationUnitResultInformation ResultInformation\r\n        {\r\n            get { return this.InternalResult; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the implementation object for ResultInformation.\r\n        /// </summary>\r\n        public TestConfigurationUnitResultInformation InternalResult { get; } = new TestConfigurationUnitResultInformation();\r\n\r\n        /// <inheritdoc/>\r\n        public ConfigurationTestResult TestResult { get; internal set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/TheorySkipIfCI.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"TheorySkipIfCI.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\r\n{\r\n    using System;\r\n    using Xunit;\r\n\r\n    /// <summary>\r\n    /// Skip theory test if running in CI builds.\r\n    /// </summary>\r\n    public sealed class TheorySkipIfCI : TheoryAttribute\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"TheorySkipIfCI\"/> class.\r\n        /// </summary>\r\n        public TheorySkipIfCI()\r\n        {\r\n            if (Environment.GetEnvironmentVariable(\"BUILD_BUILDNUMBER\") is not null)\r\n            {\r\n                this.Skip = \"Skip test for CI builds\";\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Helpers/ValueSetExtensions.cs",
    "content": "// -----------------------------------------------------------------------------\n// <copyright file=\"ValueSetExtensions.cs\" company=\"Microsoft Corporation\">\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\n// </copyright>\n// -----------------------------------------------------------------------------\n\nnamespace Microsoft.Management.Configuration.UnitTests.Helpers\n{\n    using System;\n    using System.Text;\n    using Windows.Foundation.Collections;\n\n    /// <summary>\n    /// Extensions for ValueSet.\n    /// </summary>\n    internal static class ValueSetExtensions\n    {\n        /// <summary>\n        /// Converts the value set to YAML like output.\n        /// </summary>\n        /// <param name=\"set\">The set to output.</param>\n        /// <returns>The string.</returns>\n        public static string ToYaml(this ValueSet set)\n        {\n            StringBuilder sb = new StringBuilder();\n            ToYaml(set, sb);\n            return sb.ToString();\n        }\n\n        private static void ToYaml(ValueSet set, StringBuilder sb, int indentation = 0)\n        {\n            foreach (var keyValuePair in set)\n            {\n                bool addLine = true;\n\n                sb.Append(' ', indentation);\n                sb.Append(keyValuePair.Key);\n                sb.Append(\": \");\n\n                if (keyValuePair.Value == null)\n                {\n                    sb.Append(\"null\");\n                }\n                else\n                {\n                    switch (keyValuePair.Value)\n                    {\n                        case int i:\n                            sb.Append(i);\n                            break;\n                        case long l:\n                            sb.Append(l);\n                            break;\n                        case string s:\n                            sb.Append(s);\n                            break;\n                        case bool b:\n                            sb.Append(b);\n                            break;\n                        case ValueSet v:\n                            sb.AppendLine();\n                            ToYaml(v, sb, indentation + 2);\n                            addLine = false;\n                            break;\n                        default:\n                            throw new NotImplementedException($\"Add ToYaml type `{keyValuePair.Value.GetType().Name}`\");\n                    }\n                }\n\n                if (addLine)\n                {\n                    sb.AppendLine();\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Microsoft.Management.Configuration.UnitTests.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework>\r\n    <Nullable>enable</Nullable>\r\n    <SupportedOSPlatformVersion>10.0.17763.0</SupportedOSPlatformVersion>\r\n    <Platforms>x64;x86;arm64</Platforms>\r\n    <OutputPath>$(SolutionDir)$(Platform)\\$(Configuration)\\$(MSBuildProjectName)\\</OutputPath>\r\n    <RuntimeIdentifiers>win-x64;win-x86;win-arm64</RuntimeIdentifiers>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Release'\">\r\n    <!-- See comments on Microsoft.Management.Configuration.Processor.csproj  -->\r\n    <!-- <TreatWarningsAsErrors>true</TreatWarningsAsErrors> -->\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <AdditionalFiles Include=\"..\\stylecop.json\" Link=\"stylecop.json\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" />\r\n    <PackageReference Include=\"Newtonsoft.Json\" />\r\n    <PackageReference Include=\"System.Net.Http\" />\r\n    <PackageReference Include=\"System.Private.Uri\" />\r\n    <PackageReference Include=\"System.Text.RegularExpressions\" />\r\n    <PackageReference Include=\"xunit\" />\r\n    <PackageReference Include=\"xunit.runner.visualstudio\">\r\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\r\n      <PrivateAssets>all</PrivateAssets>\r\n    </PackageReference>\r\n    <PackageReference Include=\"coverlet.collector\">\r\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\r\n      <PrivateAssets>all</PrivateAssets>\r\n    </PackageReference>\r\n    <PackageReference Include=\"StyleCop.Analyzers\">\r\n      <PrivateAssets>all</PrivateAssets>\r\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\r\n    </PackageReference>\r\n    <PackageReference Include=\"Moq\" />\r\n    <PackageReference Include=\"Microsoft.PowerShell.SDK\" GeneratePathProperty=\"true\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\Microsoft.Management.Configuration\\Microsoft.Management.Configuration.vcxproj\">\r\n      <Private>True</Private>\r\n    </ProjectReference>\r\n    <ProjectReference Include=\"..\\Microsoft.Management.Configuration.Processor\\Microsoft.Management.Configuration.Processor.csproj\">\r\n      <Private>True</Private>\r\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\r\n    </ProjectReference>\r\n    <ProjectReference Include=\"..\\WinGetTestCommon\\WinGetTestCommon.csproj\">\r\n      <Private>True</Private>\r\n    </ProjectReference>\r\n  </ItemGroup>\r\n\r\n  <Import Project=\"..\\targets\\ReferenceEmbeddedCsWinRTProject.targets\" />\r\n\r\n  <Target Name=\"PwshFiles\" AfterTargets=\"AfterBuild\">\r\n    <ItemGroup>\r\n      <RefFiles Include=\"$(OutputPath)..\\..\\..\\..\\..\\AnyCPU\\$(Configuration)\\Microsoft.Management.Configuration.Processor\\$(TargetFramework)\\win\\ref\\**\\*.*\" />\r\n      <WinModuleFiles Include=\"$(OutputPath)..\\..\\..\\..\\..\\AnyCPU\\$(Configuration)\\Microsoft.Management.Configuration.Processor\\$(TargetFramework)\\win\\Modules\\**\\*.*\" />\r\n    </ItemGroup>\r\n    <Copy SourceFiles=\"@(RefFiles)\" DestinationFolder=\"$(OutputPath)\\ref\\\" />\r\n    <Copy SourceFiles=\"@(WinModuleFiles)\" DestinationFolder=\"$(OutputPath)\\Modules\\%(RecursiveDir)%(Filename)%(Extension)\" />\r\n  </Target>\r\n\r\n  <ItemGroup>\r\n    <None Update=\"TestCollateral\\PowerShellModules\\xAdminTestResource\\xAdminTestResource.psd1\">\r\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\r\n    </None>\r\n    <None Update=\"TestCollateral\\PowerShellModules\\xAdminTestResource\\xAdminTestResource.psm1\">\r\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\r\n    </None>\r\n    <None Update=\"TestCollateral\\PowerShellModules\\xSimpleTestResource\\xSimpleTestResource.psd1\">\r\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\r\n    </None>\r\n    <None Update=\"TestCollateral\\PowerShellModules\\xSimpleTestResource\\xSimpleTestResource.psm1\">\r\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\r\n    </None>\r\n  </ItemGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/TestCollateral/PowerShellModules/xAdminTestResource/xAdminTestResource.psd1",
    "content": "﻿#\r\n# Module manifest for module 'xAdminTestResource'\r\n#\r\n# Generated by: Luffytaro\r\n#\r\n# Generated on: 10/11/2023\r\n#\r\n\r\n@{\r\n\r\nRootModule = 'xAdminTestResource.psm1'\r\nModuleVersion = '0.0.0.1'\r\nGUID = 'a0be43e8-ac22-4244-8efc-7263dfa58b8c'\r\nCompatiblePSEditions = 'Core'\r\nAuthor = 'Luffytaro'\r\nCompanyName = 'Microsoft Corporation'\r\nCopyright = '(c) Microsoft Corporation. All rights reserved.'\r\nDescription = 'PowerShell module with DSC resources for unit tests that requires admin'\r\nPowerShellVersion = '7.2'\r\nFunctionsToExport = @()\r\nCmdletsToExport = @()\r\nDscResourcesToExport = @(\r\n    'AdminResource'\r\n)\r\nHelpInfoURI = 'https://www.contoso.com/help'\r\n\r\n# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.\r\nPrivateData = @{\r\n\r\n    PSData = @{\r\n        ProjectUri = 'https://github.com/microsoft/winget-cli'\r\n        IconUri = 'https://www.contoso.com/icons/icon.png'\r\n    }\r\n\r\n}\r\n\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/TestCollateral/PowerShellModules/xAdminTestResource/xAdminTestResource.psm1",
    "content": "﻿# Simple module that requires admin.\r\n#Requires -RunAsAdministrator\r\nenum Ensure\r\n{\r\n    Absent\r\n    Present\r\n}\r\n\r\n[DscResource()]\r\nclass AdminResource\r\n{\r\n    [DscProperty(Key)]\r\n    [string] $key\r\n\r\n    [AdminResource] Get()\r\n    {\r\n        return $this\r\n    }\r\n\r\n    [bool] Test()\r\n    {\r\n        return $false\r\n    }\r\n\r\n    [void] Set()\r\n    {\r\n    }\r\n}\r\n\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/TestCollateral/PowerShellModules/xSimpleTestResource/xSimpleTestResource.psd1",
    "content": "﻿#\r\n# Module manifest for module 'xSimpleTestResource'\r\n#\r\n# Generated by: Luffytaro\r\n#\r\n# Generated on: 1/24/2023\r\n#\r\n\r\n@{\r\n\r\nRootModule = 'xSimpleTestResource.psm1'\r\nModuleVersion = '0.0.0.1'\r\nGUID = 'a0be43e8-ac22-4244-8efc-7263dfa50b8c'\r\nCompatiblePSEditions = 'Core'\r\nAuthor = 'Luffytaro'\r\nCompanyName = 'Microsoft Corporation'\r\nCopyright = '(c) Microsoft Corporation. All rights reserved.'\r\nDescription = 'PowerShell module with DSC resources for unit tests'\r\nPowerShellVersion = '7.2'\r\nFunctionsToExport = @()\r\nCmdletsToExport = @()\r\nDscResourcesToExport = @(\r\n    'SimpleFileResource'\r\n    'SimpleTestResource'\r\n    'SimpleTestResourceThrows'\r\n    'SimpleTestResourceError'\r\n    'SimpleTestResourceTypes'\r\n)\r\nHelpInfoURI = 'https://www.contoso.com/help'\r\n\r\n# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.\r\nPrivateData = @{\r\n\r\n    PSData = @{\r\n        ProjectUri = 'https://github.com/microsoft/winget-cli'\r\n        IconUri = 'https://www.contoso.com/icons/icon.png'\r\n    }\r\n\r\n}\r\n\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/TestCollateral/PowerShellModules/xSimpleTestResource/xSimpleTestResource.psm1",
    "content": "﻿# Simple module with resources.\r\n\r\nenum Ensure\r\n{\r\n    Absent\r\n    Present\r\n}\r\n\r\n# This resource just checks if a file is there or not with and if its with the specified content.\r\n[DscResource()]\r\nclass SimpleFileResource\r\n{\r\n    [DscProperty(Key)]\r\n    [string] $Path\r\n\r\n    [DscProperty()]\r\n    [Ensure] $Ensure = [Ensure]::Present\r\n\r\n    [DscProperty()]\r\n    [string] $Content = $null\r\n\r\n    [SimpleFileResource] Get()\r\n    {\r\n        if ([string]::IsNullOrEmpty($this.Path))\r\n        {\r\n            throw\r\n        }\r\n\r\n        $fileContent = $null\r\n        if (Test-Path -Path $this.Path -PathType Leaf)\r\n        {\r\n            $fileContent = Get-Content $this.Path -Raw\r\n        }\r\n\r\n        $result = @{\r\n            Path = $this.Path\r\n            Content = $fileContent\r\n        }\r\n\r\n        return $result\r\n    }\r\n\r\n    [bool] Test()\r\n    {\r\n        $get = $this.Get()\r\n\r\n        if (Test-Path -Path $this.Path -PathType Leaf)\r\n        {\r\n            if ($this.Ensure -eq [Ensure]::Present)\r\n            {\r\n                return $this.Content -eq $get.Content\r\n            }\r\n        }\r\n        elseif ($this.Ensure -eq [Ensure]::Absent)\r\n        {\r\n            return $true\r\n        }\r\n\r\n        return $false\r\n    }\r\n\r\n    [void] Set()\r\n    {\r\n        if (-not $this.Test())\r\n        {\r\n            if (Test-Path -Path $this.Path -PathType Leaf)\r\n            {\r\n                if ($this.Ensure -eq [Ensure]::Present)\r\n                {\r\n                    Set-Content $this.Path $this.Content -NoNewline\r\n                }\r\n                else\r\n                {\r\n                    Remove-Item $this.Path\r\n                }\r\n            }\r\n            else\r\n            {\r\n                if ($this.Ensure -eq [Ensure]::Present)\r\n                {\r\n                    Set-Content $this.Path $this.Content -NoNewline\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\n[DscResource()]\r\nclass SimpleTestResource\r\n{\r\n    [DscProperty(Key)]\r\n    [string] $key\r\n\r\n    [DscProperty(Mandatory)]\r\n    [string] $secretCode\r\n\r\n    [SimpleTestResource] Get()\r\n    {\r\n        $result = @{\r\n            key = \"SimpleTestResourceKey\"\r\n        }\r\n        return $result\r\n    }\r\n\r\n    [bool] Test()\r\n    {\r\n        return $this.secretCode -eq \"4815162342\"\r\n    }\r\n\r\n    [void] Set()\r\n    {\r\n        if (-not $this.Test())\r\n        {\r\n            $global:DSCMachineStatus = 1\r\n        }\r\n    }\r\n}\r\n\r\n[DscResource()]\r\nclass SimpleTestResourceThrows\r\n{\r\n    [DscProperty(Key)]\r\n    [string] $key\r\n\r\n    [SimpleTestResourceThrows] Get()\r\n    {\r\n        $result = @{\r\n            key = \"SimpleTestResourceThrowsKey\"\r\n        }\r\n        throw \"throws in Get\"\r\n        return $result\r\n    }\r\n\r\n    [bool] Test()\r\n    {\r\n        throw \"throws in Test\"\r\n        return $false\r\n    }\r\n\r\n    [void] Set()\r\n    {\r\n        throw \"throws in Set\"\r\n    }\r\n}\r\n\r\n[DscResource()]\r\nclass SimpleTestResourceError\r\n{\r\n    [DscProperty(Key)]\r\n    [string] $key\r\n\r\n    [SimpleTestResourceError] Get()\r\n    {\r\n        $result = @{\r\n            key = \"SimpleTestResourceErrorKey\"\r\n        }\r\n        Write-Error \"Error in Get\"\r\n        return $result\r\n    }\r\n\r\n    [bool] Test()\r\n    {\r\n        Write-Error \"Error in Test\"\r\n        return $true\r\n    }\r\n\r\n    [void] Set()\r\n    {\r\n        Write-Error \"Error in Set\"\r\n    }\r\n}\r\n\r\n[DscResource()]\r\nclass SimpleTestResourceTypes\r\n{\r\n    [DscProperty(Key)]\r\n    [string] $key\r\n\r\n    [DscProperty()]\r\n    [boolean] $boolProperty\r\n\r\n    [DscProperty()]\r\n    [int] $intProperty;\r\n\r\n    [DscProperty()]\r\n    [double] $doubleProperty;\r\n\r\n    [DscProperty()]\r\n    [char] $charProperty;\r\n\r\n    [DscProperty()]\r\n    [Hashtable] $hashtableProperty;\r\n\r\n    [SimpleTestResourceTypes] Get()\r\n    {\r\n        $result = @{\r\n            key = \"SimpleTestResourceTypesKey\"\r\n            boolProperty = $false\r\n            intProperty = 0\r\n            doubleProperty = 0.0\r\n            charProperty = 'z'\r\n            hashtableProperty = @{}\r\n        }\r\n        return $result\r\n    }\r\n\r\n    [bool] Test()\r\n    {\r\n        # Because we can't get the error stream from a class based resource, I throw so is easier to know if\r\n        # there's something wrong.\r\n        if ($this.boolProperty -ne $true)\r\n        {\r\n            throw \"Failed boolProperty\"\r\n        }\r\n\r\n        if ($this.intProperty -ne 3)\r\n        {\r\n            throw \"Failed intProperty. Got $($this.intProperty)\"\r\n        }\r\n\r\n        if ($this.doubleProperty -ne -9.876)\r\n        {\r\n            throw \"Failed doubleProperty Got $($this.doubleProperty)\"\r\n        }\r\n\r\n        if ($this.charProperty -ne 'f')\r\n        {\r\n            throw \"Failed charProperty Got $($this.charProperty)\"\r\n        }\r\n\r\n        if ($this.hashtableProperty.ContainsKey(\"secretStringKey\"))\r\n        {\r\n            if ($this.hashtableProperty[\"secretStringKey\"] -ne \"secretCode\")\r\n            {\r\n                throw \"Failed comparing value of `$hashtableProperty.secretStringKey Got $($this.hashtableProperty[\"secretStringKey\"])\"\r\n            }\r\n        }\r\n        else\r\n        {\r\n            throw \"Failed finding secretStringKey in hashtableProperty\"\r\n        }\r\n\r\n        if ($this.hashtableProperty.ContainsKey(\"secretIntKey\"))\r\n        {\r\n            if ($this.hashtableProperty[\"secretIntKey\"] -ne 123456)\r\n            {\r\n                throw \"Failed comparing value of `$hashtableProperty.secretIntKey Got $($this.hashtableProperty[\"secretIntKey\"])\"\r\n            }\r\n        }\r\n        else\r\n        {\r\n            throw \"Failed finding secretIntKey in hashtableProperty\"\r\n        }\r\n\r\n        return $true\r\n    }\r\n\r\n    [void] Set()\r\n    {\r\n        # no-op\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationDetailsTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationDetailsTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.Linq;\r\n    using System.Management.Automation;\r\n    using Microsoft.Management.Configuration.Processor.Helpers;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.DscResourcesInfo;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.Helpers;\r\n    using Microsoft.Management.Configuration.Processor.Unit;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using Windows.Security.Cryptography.Certificates;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n\r\n    /// <summary>\r\n    /// Tests for ConfigurationUnitProcessorDetails and ConfigurationUnitSettingDetails.\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [InProc]\r\n    public class ConfigurationDetailsTests\r\n    {\r\n        private readonly UnitTestFixture fixture;\r\n        private readonly ITestOutputHelper log;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ConfigurationDetailsTests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Fixture.</param>\r\n        /// <param name=\"log\">log.</param>\r\n        public ConfigurationDetailsTests(UnitTestFixture fixture, ITestOutputHelper log)\r\n        {\r\n            this.fixture = fixture;\r\n            this.log = log;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests creating ConfigurationUnitProcessorDetails and ConfigurationUnitSettingDetails with different inputs.\r\n        /// </summary>\r\n        /// <param name=\"hasDscInfo\">Has dsc info.</param>\r\n        /// <param name=\"hasPSModuleInfo\">Has ps module info.</param>\r\n        /// <param name=\"hasGetModuleInfo\">Has get module info.</param>\r\n        /// <param name=\"hasCerts\">Has certs.</param>\r\n        [Theory]\r\n        [InlineData(false, false, false, false)]\r\n        [InlineData(false, false, false, true)]\r\n        [InlineData(false, false, true, false)]\r\n        [InlineData(false, false, true, true)]\r\n        [InlineData(false, true, false, false)]\r\n        [InlineData(false, true, false, true)]\r\n        [InlineData(false, true, true, false)]\r\n        [InlineData(false, true, true, true)]\r\n        [InlineData(true, false, false, false)]\r\n        [InlineData(true, false, false, true)]\r\n        [InlineData(true, false, true, false)]\r\n        [InlineData(true, false, true, true)]\r\n        [InlineData(true, true, false, false)]\r\n        [InlineData(true, true, false, true)]\r\n        [InlineData(true, true, true, false)]\r\n        [InlineData(true, true, true, true)]\r\n        public void ConfigurationUnitProcessorDetails_CreationTest(bool hasDscInfo, bool hasPSModuleInfo, bool hasGetModuleInfo, bool hasCerts)\r\n        {\r\n            List<Certificate>? certsInput = null;\r\n            if (hasCerts)\r\n            {\r\n                certsInput = new List<Certificate>();\r\n            }\r\n\r\n            if (!hasDscInfo && !hasPSModuleInfo && !hasGetModuleInfo)\r\n            {\r\n                Assert.Throws<ArgumentException>(\r\n                    () => Factory.CreateUnitProcessorDetails(\"unitName\", null, null, null, certsInput));\r\n            }\r\n            else\r\n            {\r\n                var unit = this.CreateConfigurationUnit();\r\n                var (dscResourceInfo, psModuleInfo) = this.GetResourceAndModuleInfo(unit);\r\n\r\n                DscResourceInfoInternal? dscResourceInfoInput = null;\r\n                if (hasDscInfo)\r\n                {\r\n                    dscResourceInfoInput = dscResourceInfo;\r\n                }\r\n\r\n                PSModuleInfo? psModuleInfoInput = null;\r\n                if (hasPSModuleInfo)\r\n                {\r\n                    psModuleInfoInput = psModuleInfo;\r\n                }\r\n\r\n                PSObject? getModuleInfo = null;\r\n                if (hasGetModuleInfo)\r\n                {\r\n                    getModuleInfo = this.CreateGetModuleInfo();\r\n                }\r\n\r\n                var details = Factory.CreateUnitProcessorDetails(unit.Type, dscResourceInfoInput, psModuleInfoInput, getModuleInfo, certsInput);\r\n\r\n                Assert.Equal(unit.Type, details.UnitType);\r\n\r\n                if (hasDscInfo)\r\n                {\r\n                    Assert.True(details.IsLocal);\r\n                    Assert.Equal(\"xSimpleTestResource\", details.ModuleName);\r\n                    Assert.Equal(\"0.0.0.1\", details.Version);\r\n                    Assert.NotNull(details.Settings);\r\n                    Assert.True(details.Settings.Count == 5);\r\n\r\n                    var pathSetting = details.Settings.Where(s => s.Identifier == \"Path\").FirstOrDefault();\r\n                    Assert.NotNull(pathSetting);\r\n                    Assert.Equal(Windows.Foundation.PropertyType.String, pathSetting.Type);\r\n                    Assert.True(pathSetting.IsRequired);\r\n                    Assert.Equal(string.Empty, pathSetting.Schema);\r\n\r\n                    var contentSetting = details.Settings.Where(s => s.Identifier == \"Content\").FirstOrDefault();\r\n                    Assert.NotNull(contentSetting);\r\n                    Assert.Equal(Windows.Foundation.PropertyType.String, contentSetting.Type);\r\n                    Assert.False(contentSetting.IsRequired);\r\n                    Assert.Equal(string.Empty, contentSetting.Schema);\r\n\r\n                    var dependsOnSetting = details.Settings.Where(s => s.Identifier == \"DependsOn\").FirstOrDefault();\r\n                    Assert.NotNull(dependsOnSetting);\r\n                    Assert.Equal(Windows.Foundation.PropertyType.StringArray, dependsOnSetting.Type);\r\n                    Assert.False(dependsOnSetting.IsRequired);\r\n                    Assert.Equal(string.Empty, dependsOnSetting.Schema);\r\n\r\n                    var ensureSetting = details.Settings.Where(s => s.Identifier == \"Ensure\").FirstOrDefault();\r\n                    Assert.NotNull(ensureSetting);\r\n                    Assert.Equal(Windows.Foundation.PropertyType.String, ensureSetting.Type);\r\n                    Assert.False(ensureSetting.IsRequired);\r\n                    Assert.Equal(string.Empty, ensureSetting.Schema);\r\n\r\n                    var psDscRunAsCredentialSetting = details.Settings.Where(s => s.Identifier == \"PsDscRunAsCredential\").FirstOrDefault();\r\n                    Assert.NotNull(psDscRunAsCredentialSetting);\r\n                    Assert.Equal(Windows.Foundation.PropertyType.Inspectable, psDscRunAsCredentialSetting.Type);\r\n                    Assert.False(psDscRunAsCredentialSetting.IsRequired);\r\n                    Assert.Equal(string.Empty, psDscRunAsCredentialSetting.Schema);\r\n                }\r\n\r\n                if (hasPSModuleInfo)\r\n                {\r\n                    Assert.Equal(new Uri(\"https://www.contoso.com/help\"), details.ModuleDocumentationUri);\r\n                    Assert.Equal(new Uri(\"https://www.contoso.com/icons/icon.png\"), details.UnitIconUri);\r\n                    Assert.Equal(\"xSimpleTestResource\", details.ModuleName);\r\n                    Assert.Equal(ModuleType.Script.ToString(), details.ModuleType);\r\n                    Assert.Equal(\"PowerShell module with DSC resources for unit tests\", details.ModuleDescription);\r\n                    Assert.Equal(new Uri(\"https://github.com/microsoft/winget-cli\"), details.PublishedModuleUri);\r\n                    Assert.Equal(\"0.0.0.1\", details.Version);\r\n                    Assert.Equal(\"Luffytaro\", details.Author);\r\n                    Assert.Equal(\"Microsoft Corporation\", details.Publisher);\r\n                }\r\n\r\n                if (hasGetModuleInfo)\r\n                {\r\n                    Assert.Equal(\"PSGallery\", details.ModuleSource);\r\n                    Assert.Equal(new DateTimeOffset(new DateTime(2017, 12, 10)), details.PublishedDate);\r\n                    Assert.Equal(new Uri(\"https://www.contoso.com/icons/icon.png\"), details.UnitIconUri);\r\n                    Assert.Equal(\"xSimpleTestResource\", details.ModuleName);\r\n                    Assert.Equal(\"PowerShell module with DSC resources for unit tests\", details.ModuleDescription);\r\n                    Assert.Equal(\"0.0.0.1\", details.Version);\r\n                    Assert.Equal(\"Luffytaro\", details.Author);\r\n                    Assert.Equal(\"Microsoft Corporation\", details.Publisher);\r\n                    Assert.True(details.IsPublic);\r\n                }\r\n\r\n                if (hasCerts)\r\n                {\r\n                    Assert.NotNull(details.SigningInformation);\r\n                }\r\n            }\r\n        }\r\n\r\n        private ConfigurationUnit CreateConfigurationUnit()\r\n        {\r\n            var unit = new ConfigurationUnit();\r\n            unit.Type = \"SimpleFileResource\";\r\n            unit.Metadata.Add(\"module\", \"xSimpleTestResource\");\r\n            unit.Metadata.Add(\"version\", \"0.0.0.1\");\r\n\r\n            return unit;\r\n        }\r\n\r\n        private (DscResourceInfoInternal dscResourceInfo, PSModuleInfo psModuleInfo) GetResourceAndModuleInfo(ConfigurationUnit unit)\r\n        {\r\n            // This is easier than trying to mock sealed class from external code...\r\n            var testEnv = this.fixture.PrepareTestProcessorEnvironment(true);\r\n\r\n            var dscResourceInfo = testEnv.GetDscResource(new ConfigurationUnitAndModule(unit, string.Empty));\r\n            var psModuleInfo = testEnv.GetAvailableModule(PowerShellHelpers.CreateModuleSpecification(\"xSimpleTestResource\", \"0.0.0.1\"));\r\n\r\n            if (dscResourceInfo is null || psModuleInfo is null)\r\n            {\r\n                throw new ArgumentNullException(\"Test processor environment not set correctly\");\r\n            }\r\n\r\n            return (dscResourceInfo, psModuleInfo);\r\n        }\r\n\r\n        private PSObject CreateGetModuleInfo()\r\n        {\r\n            return new PSObject(new\r\n            {\r\n                Repository = \"PSGallery\",\r\n                PublishedDate = new DateTime(2017, 12, 10),\r\n                IconUri = \"https://www.contoso.com/icons/icon.png\",\r\n                Name = \"xSimpleTestResource\",\r\n                Description = \"PowerShell module with DSC resources for unit tests\",\r\n                RepositorySourceLocation = \"https://www.powershellgallery.com/api/v2\",\r\n                Version = \"0.0.0.1\",\r\n                Author = \"Luffytaro\",\r\n                CompanyName = \"Microsoft Corporation\",\r\n            });\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationHistoryTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationHistoryTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.Diagnostics;\r\n    using System.Diagnostics.CodeAnalysis;\r\n    using System.Xml.Linq;\r\n    using Microsoft.Management.Configuration.Processor.Extensions;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using Microsoft.VisualBasic;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n\r\n    /// <summary>\r\n    /// Unit tests for configuration history.\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [InProc]\r\n    public class ConfigurationHistoryTests : ConfigurationProcessorTestBase\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ConfigurationHistoryTests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Unit test fixture.</param>\r\n        /// <param name=\"log\">Log helper.</param>\r\n        public ConfigurationHistoryTests(UnitTestFixture fixture, ITestOutputHelper log)\r\n            : base(fixture, log)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Checks that the history matches the applied set.\r\n        /// </summary>\r\n        [Fact]\r\n        [OutOfProc]\r\n        public void ApplySet_HistoryMatches_0_1()\r\n        {\r\n            this.RunApplyHistoryMatchTest(\r\n                @\"\r\nproperties:\r\n  configurationVersion: 0.1\r\n  assertions:\r\n    - resource: Assert\r\n      id: AssertIdentifier1\r\n      directives:\r\n        module: Module\r\n      settings:\r\n        Setting1: '1'\r\n        Setting2: 2\r\n    - resource: Assert\r\n      id: AssertIdentifier2\r\n      dependsOn:\r\n        - AssertIdentifier1\r\n      directives:\r\n        module: Module\r\n      settings:\r\n        Setting1:\r\n          Setting2: 2\r\n  parameters:\r\n    - resource: Inform\r\n      id: InformIdentifier1\r\n      directives:\r\n        module: Module2\r\n      settings:\r\n        Setting1:\r\n          Setting2:\r\n            Setting3: 3\r\n  resources:\r\n    - resource: Apply\r\n\", new string[] { \"AssertIdentifier2\" });\r\n        }\r\n\r\n        /// <summary>\r\n        /// Checks that the history matches the applied set.\r\n        /// </summary>\r\n        [Fact]\r\n        [OutOfProc]\r\n        public void ApplySet_HistoryMatches_0_2()\r\n        {\r\n            this.RunApplyHistoryMatchTest(\r\n                @\"\r\nproperties:\r\n  configurationVersion: 0.2\r\n  assertions:\r\n    - resource: Module/Assert\r\n      id: AssertIdentifier1\r\n      settings:\r\n        Setting1: '1'\r\n        Setting2: 2\r\n    - resource: Module/Assert\r\n      id: AssertIdentifier2\r\n      dependsOn:\r\n        - AssertIdentifier1\r\n      directives:\r\n        description: Describe!\r\n      settings:\r\n        Setting1:\r\n          Setting2: 2\r\n  parameters:\r\n    - resource: Module2/Inform\r\n      id: InformIdentifier1\r\n      settings:\r\n        Setting1:\r\n          Setting2:\r\n            Setting3: 3\r\n  resources:\r\n    - resource: Apply\r\n\", new string[] { \"AssertIdentifier2\" });\r\n        }\r\n\r\n        /// <summary>\r\n        /// Checks that the history matches the applied set.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ApplySet_HistoryMatches_0_3()\r\n        {\r\n            this.RunApplyHistoryMatchTest(\r\n                @\"\r\n$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json\r\nmetadata:\r\n  a: 1\r\n  b: '2'\r\nvariables:\r\n  v1: var1\r\n  v2: 42\r\nresources:\r\n  - name: Name\r\n    type: Module/Resource\r\n    metadata:\r\n      e: '5'\r\n      f: 6\r\n    properties:\r\n      c: 3\r\n      d: '4'\r\n  - name: Name2\r\n    type: Module/Resource2\r\n    dependsOn:\r\n      - Name\r\n    properties:\r\n      l: '10'\r\n    metadata:\r\n      i: '7'\r\n      j: 8\r\n      q: 42\r\n  - name: Group\r\n    type: Module2/Resource\r\n    metadata:\r\n      isGroup: true\r\n    properties:\r\n      resources:\r\n        - name: Child1\r\n          type: Module3/Resource\r\n          metadata:\r\n            e: '5'\r\n            f: 6\r\n          properties:\r\n            c: 3\r\n            d: '4'\r\n        - name: Child2\r\n          type: Module4/Resource2\r\n          properties:\r\n            l: '10'\r\n          metadata:\r\n            i: '7'\r\n            j: 8\r\n            q: 42\r\n\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Applies a set, reads the history, changes the read set and reapplies it.\r\n        /// </summary>\r\n        [Fact]\r\n        [OutOfProc]\r\n        public void ApplySet_ChangeHistory()\r\n        {\r\n            string disabledIdentifier = \"AssertIdentifier2\";\r\n\r\n            ConfigurationSet returnedSet = this.RunApplyHistoryMatchTest(\r\n                @\"\r\nproperties:\r\n  configurationVersion: 0.2\r\n  assertions:\r\n    - resource: Module/Assert\r\n      id: AssertIdentifier1\r\n      settings:\r\n        Setting1: '1'\r\n        Setting2: 2\r\n    - resource: Module/Assert\r\n      id: AssertIdentifier2\r\n      dependsOn:\r\n        - AssertIdentifier1\r\n      directives:\r\n        description: Describe!\r\n      settings:\r\n        Setting1:\r\n          Setting2: 2\r\n  parameters:\r\n    - resource: Module2/Inform\r\n      id: InformIdentifier1\r\n      settings:\r\n        Setting1:\r\n          Setting2:\r\n            Setting3: 3\r\n  resources:\r\n    - resource: Apply\r\n\", new string[] { disabledIdentifier });\r\n\r\n            foreach (ConfigurationUnit unit in returnedSet.Units)\r\n            {\r\n                if (unit.Identifier == disabledIdentifier)\r\n                {\r\n                    unit.IsActive = true;\r\n                }\r\n            }\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            ApplyConfigurationSetResult result = processor.ApplySet(returnedSet, ApplyConfigurationSetFlags.None);\r\n            Assert.NotNull(result);\r\n            Assert.Null(result.ResultCode);\r\n\r\n            ConfigurationSet? historySet = null;\r\n\r\n            foreach (ConfigurationSet set in processor.GetConfigurationHistory())\r\n            {\r\n                if (set.InstanceIdentifier == returnedSet.InstanceIdentifier)\r\n                {\r\n                    historySet = set;\r\n                }\r\n            }\r\n\r\n            this.AssertSetsEqual(returnedSet, historySet);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Applies a set, reads the history and removes it.\r\n        /// </summary>\r\n        [Fact]\r\n        [OutOfProc]\r\n        public void ApplySet_RemoveHistory()\r\n        {\r\n            ConfigurationSet returnedSet = this.RunApplyHistoryMatchTest(\r\n                @\"\r\nproperties:\r\n  configurationVersion: 0.2\r\n  assertions:\r\n    - resource: Module/Assert\r\n      id: AssertIdentifier1\r\n      settings:\r\n        Setting1: '1'\r\n        Setting2: 2\r\n    - resource: Module/Assert\r\n      id: AssertIdentifier2\r\n      dependsOn:\r\n        - AssertIdentifier1\r\n      directives:\r\n        description: Describe!\r\n      settings:\r\n        Setting1:\r\n          Setting2: 2\r\n  parameters:\r\n    - resource: Module2/Inform\r\n      id: InformIdentifier1\r\n      settings:\r\n        Setting1:\r\n          Setting2:\r\n            Setting3: 3\r\n  resources:\r\n    - resource: Apply\r\n\");\r\n\r\n            returnedSet.Remove();\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            ConfigurationSet? historySet = null;\r\n\r\n            foreach (ConfigurationSet set in processor.GetConfigurationHistory())\r\n            {\r\n                if (set.InstanceIdentifier == returnedSet.InstanceIdentifier)\r\n                {\r\n                    historySet = set;\r\n                }\r\n            }\r\n\r\n            Assert.Null(historySet);\r\n        }\r\n\r\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"StyleCop.CSharp.SpacingRules\", \"SA1011:Closing square brackets should be spaced correctly\", Justification = \"https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2927\")]\r\n        private ConfigurationSet RunApplyHistoryMatchTest(string contents, string[]? inactiveIdentifiers = null)\r\n        {\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            OpenConfigurationSetResult configurationSetResult = processor.OpenConfigurationSet(this.CreateStream(contents));\r\n            ConfigurationSet configurationSet = configurationSetResult.Set;\r\n            Assert.NotNull(configurationSet);\r\n\r\n            TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet);\r\n            setProcessor.EnableDefaultGroupProcessorCreation = true;\r\n\r\n            configurationSet.Name = \"Test Name\";\r\n            configurationSet.Origin = \"Test Origin\";\r\n            configurationSet.Path = \"Test Path\";\r\n\r\n            if (inactiveIdentifiers != null)\r\n            {\r\n                foreach (string identifier in inactiveIdentifiers)\r\n                {\r\n                    foreach (ConfigurationUnit unit in configurationSet.Units)\r\n                    {\r\n                        if (unit.Identifier == identifier)\r\n                        {\r\n                            unit.IsActive = false;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            ApplyConfigurationSetResult result = processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None);\r\n            Assert.NotNull(result);\r\n            Assert.Null(result.ResultCode);\r\n\r\n            ConfigurationSet? historySet = null;\r\n\r\n            foreach (ConfigurationSet set in processor.GetConfigurationHistory())\r\n            {\r\n                if (set.InstanceIdentifier == configurationSet.InstanceIdentifier)\r\n                {\r\n                    historySet = set;\r\n                }\r\n            }\r\n\r\n            this.AssertSetsEqual(configurationSet, historySet);\r\n            this.AssertResultsEqual(result, historySet);\r\n            return historySet;\r\n        }\r\n\r\n        private void AssertSetsEqual(ConfigurationSet expectedSet, [NotNull] ConfigurationSet? actualSet)\r\n        {\r\n            Assert.NotNull(actualSet);\r\n            Assert.Equal(expectedSet.Name, actualSet.Name);\r\n            Assert.Equal(expectedSet.Origin, actualSet.Origin);\r\n            Assert.Equal(expectedSet.Path, actualSet.Path);\r\n\r\n            Assert.Equal(ConfigurationSetState.Completed, actualSet.State);\r\n\r\n            this.AssertTimeNotZero(actualSet.FirstApply);\r\n            this.AssertTimeNotZero(actualSet.ApplyBegun);\r\n            this.AssertTimeNotZero(actualSet.ApplyEnded);\r\n            Assert.True(actualSet.FirstApply <= actualSet.ApplyBegun);\r\n            Assert.True(actualSet.ApplyBegun <= actualSet.ApplyEnded);\r\n\r\n            Assert.Equal(expectedSet.SchemaVersion, actualSet.SchemaVersion);\r\n            Assert.Equal(expectedSet.SchemaUri, actualSet.SchemaUri);\r\n            Assert.True(expectedSet.Metadata.ContentEquals(actualSet.Metadata));\r\n\r\n            this.AssertUnitsListEqual(expectedSet.Units, actualSet.Units);\r\n        }\r\n\r\n        private void AssertTimeNotZero(DateTimeOffset actualTime)\r\n        {\r\n            Assert.NotEqual(DateTimeOffset.UnixEpoch, actualTime);\r\n            Assert.NotEqual(DateTimeOffset.MinValue, actualTime);\r\n        }\r\n\r\n        private void AssertUnitsListEqual(IList<ConfigurationUnit> expectedUnits, IList<ConfigurationUnit> actualUnits)\r\n        {\r\n            Assert.Equal(expectedUnits.Count, actualUnits.Count);\r\n\r\n            foreach (ConfigurationUnit expectedUnit in expectedUnits)\r\n            {\r\n                ConfigurationUnit? actualUnit = null;\r\n                foreach (ConfigurationUnit historyUnit in actualUnits)\r\n                {\r\n                    if (historyUnit.InstanceIdentifier == expectedUnit.InstanceIdentifier)\r\n                    {\r\n                        actualUnit = historyUnit;\r\n                    }\r\n                }\r\n\r\n                this.AssertUnitsEqual(expectedUnit, actualUnit);\r\n            }\r\n        }\r\n\r\n        private void AssertUnitsEqual(ConfigurationUnit expectedUnit, ConfigurationUnit? actualUnit)\r\n        {\r\n            Assert.NotNull(actualUnit);\r\n            Assert.Equal(expectedUnit.Type, actualUnit.Type);\r\n            Assert.Equal(expectedUnit.Identifier, actualUnit.Identifier);\r\n            Assert.Equal(expectedUnit.Intent, actualUnit.Intent);\r\n            Assert.Equal(expectedUnit.Dependencies, actualUnit.Dependencies);\r\n            Assert.True(expectedUnit.Metadata.ContentEquals(actualUnit.Metadata), $\"Metadata not equal: {expectedUnit.Identifier}\\n---expected---:\\n{expectedUnit.Metadata.ToYaml()}\\n---actual---:\\n{actualUnit.Metadata.ToYaml()}\");\r\n            Assert.True(expectedUnit.Settings.ContentEquals(actualUnit.Settings));\r\n            Assert.Equal(expectedUnit.IsActive, actualUnit.IsActive);\r\n            Assert.Equal(expectedUnit.IsGroup, actualUnit.IsGroup);\r\n\r\n            if (expectedUnit.IsGroup)\r\n            {\r\n                this.AssertUnitsListEqual(expectedUnit.Units, actualUnit.Units);\r\n            }\r\n        }\r\n\r\n        private void AssertResultsEqual(ApplyConfigurationSetResult expected, ConfigurationSet actualSet)\r\n        {\r\n            List<ConfigurationUnit> actualUnitList = new List<ConfigurationUnit>();\r\n\r\n            foreach (ConfigurationUnit unit in actualSet.Units)\r\n            {\r\n                this.AccumulateUnits(actualUnitList, unit);\r\n            }\r\n\r\n            foreach (ApplyConfigurationUnitResult expectedUnitResult in expected.UnitResults)\r\n            {\r\n                ConfigurationUnit? actualUnit = null;\r\n                foreach (ConfigurationUnit historyUnit in actualUnitList)\r\n                {\r\n                    if (historyUnit.InstanceIdentifier == expectedUnitResult.Unit.InstanceIdentifier)\r\n                    {\r\n                        actualUnit = historyUnit;\r\n                    }\r\n                }\r\n\r\n                this.AssertUnitResultsEqual(expectedUnitResult, actualUnit);\r\n            }\r\n        }\r\n\r\n        private void AccumulateUnits(List<ConfigurationUnit> unitList, ConfigurationUnit unit)\r\n        {\r\n            unitList.Add(unit);\r\n            if (unit.IsGroup)\r\n            {\r\n                foreach (ConfigurationUnit child in unit.Units)\r\n                {\r\n                    this.AccumulateUnits(unitList, child);\r\n                }\r\n            }\r\n        }\r\n\r\n        private void AssertUnitResultsEqual(ApplyConfigurationUnitResult expectedResult, ConfigurationUnit? actualUnit)\r\n        {\r\n            Assert.NotNull(actualUnit);\r\n            Assert.Equal(expectedResult.State, actualUnit.State);\r\n\r\n            var expectedResultInformation = expectedResult.ResultInformation;\r\n            if (expectedResultInformation != null)\r\n            {\r\n                var actualResultInformation = actualUnit.ResultInformation;\r\n                Assert.NotNull(actualResultInformation);\r\n\r\n                Assert.Equal(expectedResultInformation.ResultCode == null, actualResultInformation.ResultCode == null);\r\n                if (expectedResultInformation.ResultCode != null)\r\n                {\r\n                    Assert.Equal(expectedResultInformation.ResultCode.HResult, actualResultInformation.ResultCode!.HResult);\r\n                }\r\n\r\n                Assert.Equal(expectedResultInformation.Description, actualResultInformation.Description);\r\n                Assert.Equal(expectedResultInformation.Details, actualResultInformation.Details);\r\n                Assert.Equal(expectedResultInformation.ResultSource, actualResultInformation.ResultSource);\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationMixedElevationTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationMixedElevationTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System;\r\n    using System.IO;\r\n    using System.Threading.Tasks;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n\r\n    /// <summary>\r\n    /// Unit tests for verifying the processor behavior for handling mixed elevation scenarios.\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [OutOfProc]\r\n    public class ConfigurationMixedElevationTests : ConfigurationProcessorTestBase\r\n    {\r\n        private readonly UnitTestFixture fixture;\r\n        private readonly ITestOutputHelper log;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ConfigurationMixedElevationTests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Unit test fixture.</param>\r\n        /// <param name=\"log\">Log helper.</param>\r\n        public ConfigurationMixedElevationTests(UnitTestFixture fixture, ITestOutputHelper log)\r\n            : base(fixture, log)\r\n        {\r\n            this.fixture = fixture;\r\n            this.log = log;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies that applying units of mixed elevation is successful. Also verifies that the elevated processor has a different process id.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Fact]\r\n        public async Task ApplyMixedElevationUnits()\r\n        {\r\n            string resourceName = \"E2ETestResourcePID\";\r\n            string moduleName = \"xE2ETestResource\";\r\n            Version version = new Version(\"0.0.0.1\");\r\n\r\n            string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());\r\n            Directory.CreateDirectory(tempDirectory);\r\n\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            configurationSet.SchemaVersion = \"0.2\";\r\n            configurationSet.Metadata.Add(Helpers.Constants.EnableDynamicFactoryTestMode, true);\r\n\r\n            ConfigurationUnit unit = this.ConfigurationUnit();\r\n            unit.Metadata.Add(\"version\", version.ToString());\r\n            unit.Metadata.Add(\"module\", moduleName);\r\n            unit.Settings.Add(\"directoryPath\", tempDirectory);\r\n            unit.Type = resourceName;\r\n            unit.Intent = ConfigurationUnitIntent.Apply;\r\n\r\n            ConfigurationUnit elevatedUnit = this.ConfigurationUnit();\r\n            elevatedUnit.Metadata.Add(\"version\", version.ToString());\r\n            elevatedUnit.Metadata.Add(\"module\", moduleName);\r\n            elevatedUnit.Environment.Context = SecurityContext.Elevated;\r\n            elevatedUnit.Settings.Add(\"directoryPath\", tempDirectory);\r\n            elevatedUnit.Type = resourceName;\r\n            elevatedUnit.Intent = ConfigurationUnitIntent.Apply;\r\n\r\n            configurationSet.Units = new ConfigurationUnit[] { unit, elevatedUnit };\r\n\r\n            IConfigurationSetProcessorFactory dynamicFactory = await this.fixture.ConfigurationStatics.CreateConfigurationSetProcessorFactoryAsync(Helpers.Constants.DynamicRuntimeHandlerIdentifier);\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(dynamicFactory);\r\n\r\n            ApplyConfigurationSetResult result = processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None);\r\n\r\n            // Get the number of unique PIDs from temp directory.\r\n            int pidCount = Directory.GetFiles(tempDirectory).Length;\r\n\r\n            // Clean up temp directory folder.\r\n            Directory.Delete(tempDirectory, true);\r\n\r\n            Assert.NotNull(result);\r\n            Assert.Null(result.ResultCode);\r\n            Assert.Equal(2, result.UnitResults.Count);\r\n\r\n            foreach (var unitResult in result.UnitResults)\r\n            {\r\n                Assert.NotNull(unitResult);\r\n                Assert.False(unitResult.PreviouslyInDesiredState);\r\n                Assert.False(unitResult.RebootRequired);\r\n                Assert.NotNull(unitResult.ResultInformation);\r\n                Assert.Null(unitResult.ResultInformation.ResultCode);\r\n                Assert.Equal(ConfigurationUnitResultSource.None, unitResult.ResultInformation.ResultSource);\r\n            }\r\n\r\n            // There should be exactly 2 unique PIDs, one for each integrity level.\r\n            Assert.Equal(2, pidCount);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies that applying units of mixed elevation is successful. Also verifies that the elevated processor has a different process id.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Fact]\r\n        public async Task ApplyMixedElevationUnits_Schema_0_3()\r\n        {\r\n            string resourceName = \"xE2ETestResource/E2ETestResourcePID\";\r\n            Version version = new Version(\"0.0.0.1\");\r\n\r\n            string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());\r\n            Directory.CreateDirectory(tempDirectory);\r\n\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            configurationSet.SchemaVersion = \"0.3\";\r\n            configurationSet.Metadata.Add(Helpers.Constants.EnableDynamicFactoryTestMode, true);\r\n\r\n            ConfigurationUnit unit = this.ConfigurationUnit();\r\n            unit.Metadata.Add(\"version\", version.ToString());\r\n            unit.Settings.Add(\"directoryPath\", tempDirectory);\r\n            unit.Type = resourceName;\r\n            unit.Identifier = \"current\";\r\n\r\n            ConfigurationUnit elevatedUnit = this.ConfigurationUnit();\r\n            elevatedUnit.Intent = ConfigurationUnitIntent.Unknown;\r\n            elevatedUnit.Metadata.Add(\"version\", version.ToString());\r\n            elevatedUnit.Environment.Context = SecurityContext.Elevated;\r\n            elevatedUnit.Settings.Add(\"directoryPath\", tempDirectory);\r\n            elevatedUnit.Type = resourceName;\r\n            elevatedUnit.Identifier = \"elevated\";\r\n\r\n            configurationSet.Units = new ConfigurationUnit[] { unit, elevatedUnit };\r\n\r\n            IConfigurationSetProcessorFactory dynamicFactory = await this.fixture.ConfigurationStatics.CreateConfigurationSetProcessorFactoryAsync(Helpers.Constants.DynamicRuntimeHandlerIdentifier);\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(dynamicFactory);\r\n\r\n            ApplyConfigurationSetResult result = processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None);\r\n\r\n            // Get the number of unique PIDs from temp directory.\r\n            int pidCount = Directory.GetFiles(tempDirectory).Length;\r\n\r\n            // Clean up temp directory folder.\r\n            Directory.Delete(tempDirectory, true);\r\n\r\n            Assert.NotNull(result);\r\n            Assert.Null(result.ResultCode);\r\n            Assert.Equal(2, result.UnitResults.Count);\r\n\r\n            foreach (var unitResult in result.UnitResults)\r\n            {\r\n                Assert.NotNull(unitResult);\r\n                Assert.False(unitResult.PreviouslyInDesiredState);\r\n                Assert.False(unitResult.RebootRequired);\r\n                Assert.NotNull(unitResult.ResultInformation);\r\n                Assert.Null(unitResult.ResultInformation.ResultCode);\r\n                Assert.Equal(ConfigurationUnitResultSource.None, unitResult.ResultInformation.ResultSource);\r\n            }\r\n\r\n            // There should be exactly 2 unique PIDs, one for each integrity level.\r\n            Assert.Equal(2, pidCount);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies that creating a high integrity unit processor for a non elevated unit should return an invalid operation result.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Fact]\r\n        public async Task ApplyUnitNotInLimitationSet()\r\n        {\r\n            string resourceName = \"E2ETestResource\";\r\n            string moduleName = \"xE2ETestResource\";\r\n            Version version = new Version(\"0.0.0.1\");\r\n\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            configurationSet.SchemaVersion = \"0.2\";\r\n            configurationSet.Metadata.Add(Helpers.Constants.EnableDynamicFactoryTestMode, true);\r\n            configurationSet.Metadata.Add(Helpers.Constants.ForceHighIntegrityLevelUnitsTestGuid, true);\r\n            configurationSet.Metadata.Add(Helpers.Constants.EnableRestrictedIntegrityLevelTestGuid, true);\r\n\r\n            ConfigurationUnit unit = this.ConfigurationUnit();\r\n            unit.Metadata.Add(\"version\", version.ToString());\r\n            unit.Metadata.Add(\"module\", moduleName);\r\n            unit.Metadata.Add(\"unique\", \"value\");\r\n            unit.Type = resourceName;\r\n            unit.Intent = ConfigurationUnitIntent.Apply;\r\n\r\n            ConfigurationUnit elevatedUnit = this.ConfigurationUnit();\r\n            elevatedUnit.Metadata.Add(\"version\", version.ToString());\r\n            elevatedUnit.Metadata.Add(\"module\", moduleName);\r\n            elevatedUnit.Environment.Context = SecurityContext.Elevated;\r\n            elevatedUnit.Type = resourceName;\r\n            elevatedUnit.Intent = ConfigurationUnitIntent.Apply;\r\n\r\n            configurationSet.Units = new ConfigurationUnit[] { unit, elevatedUnit };\r\n\r\n            IConfigurationSetProcessorFactory dynamicFactory = await this.fixture.ConfigurationStatics.CreateConfigurationSetProcessorFactoryAsync(Helpers.Constants.DynamicRuntimeHandlerIdentifier);\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(dynamicFactory);\r\n\r\n            ApplyConfigurationSetResult result = processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None);\r\n            Assert.NotNull(result);\r\n            Assert.NotNull(result.ResultCode);\r\n            Assert.Equal(Errors.WINGET_CONFIG_ERROR_SET_APPLY_FAILED, result.ResultCode.HResult);\r\n            Assert.Equal(2, result.UnitResults.Count);\r\n\r\n            ApplyConfigurationUnitResult unitResult = result.UnitResults[0];\r\n            Assert.NotNull(unitResult);\r\n            Assert.False(unitResult.PreviouslyInDesiredState);\r\n            Assert.False(unitResult.RebootRequired);\r\n            Assert.NotNull(unitResult.ResultInformation);\r\n            Assert.NotNull(unitResult.ResultInformation.ResultCode);\r\n            Assert.Equal(Errors.CORE_INVALID_OPERATION, unitResult.ResultInformation.ResultCode.HResult);\r\n            Assert.Equal(ConfigurationUnitResultSource.Internal, unitResult.ResultInformation.ResultSource);\r\n\r\n            // Elevated unit should still succeed when applied.\r\n            ApplyConfigurationUnitResult elevatedUnitResult = result.UnitResults[1];\r\n            Assert.NotNull(elevatedUnitResult);\r\n            Assert.False(elevatedUnitResult.PreviouslyInDesiredState);\r\n            Assert.False(elevatedUnitResult.RebootRequired);\r\n            Assert.NotNull(elevatedUnitResult.ResultInformation);\r\n            Assert.Null(elevatedUnitResult.ResultInformation.ResultCode);\r\n            Assert.Equal(ConfigurationUnitResultSource.None, elevatedUnitResult.ResultInformation.ResultSource);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies that attempting to pass a secure parameter across the integrity boundary fails.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Fact]\r\n        public async Task SecureParameterAcrossIntegrityBoundaryFails()\r\n        {\r\n            string resourceName = \"E2ETestResourcePID\";\r\n            string moduleName = \"xE2ETestResource\";\r\n            Version version = new Version(\"0.0.0.1\");\r\n\r\n            string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());\r\n            Directory.CreateDirectory(tempDirectory);\r\n\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            configurationSet.Metadata.Add(Helpers.Constants.EnableDynamicFactoryTestMode, true);\r\n\r\n            ConfigurationUnit elevatedUnit = this.ConfigurationUnit();\r\n            elevatedUnit.Metadata.Add(\"version\", version.ToString());\r\n            elevatedUnit.Metadata.Add(\"module\", moduleName);\r\n            elevatedUnit.Environment.Context = SecurityContext.Elevated;\r\n            elevatedUnit.Settings.Add(\"directoryPath\", tempDirectory);\r\n            elevatedUnit.Type = resourceName;\r\n            elevatedUnit.Intent = ConfigurationUnitIntent.Apply;\r\n\r\n            configurationSet.Units = new ConfigurationUnit[] { elevatedUnit };\r\n\r\n            ConfigurationParameter parameter = this.ConfigurationParameter();\r\n            parameter.Name = \"param\";\r\n            parameter.Type = Windows.Foundation.PropertyType.String;\r\n            parameter.IsSecure = true;\r\n            parameter.ProvidedValue = \"secrets\";\r\n\r\n            configurationSet.Parameters = new ConfigurationParameter[] { parameter };\r\n\r\n            IConfigurationSetProcessorFactory dynamicFactory = await this.fixture.ConfigurationStatics.CreateConfigurationSetProcessorFactoryAsync(Helpers.Constants.DynamicRuntimeHandlerIdentifier);\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(dynamicFactory);\r\n\r\n            // While parameters are not supported, we expect to get a not implemented exception.\r\n            // Once they are implemented, swap to the appropriate error mechanism for the parameter integrity boundary.\r\n            Assert.Throws<NotImplementedException>(() => processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies that DynamicFactoryProcessors do not break on empty set when working with only units.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous unit test.</returns>\r\n        [Fact]\r\n        public async Task CreateDynamicFactoryProcessorsWithEmptyConfigurationSet()\r\n        {\r\n            string resourceName = \"E2ETestResourcePID\";\r\n            string moduleName = \"xE2ETestResource\";\r\n            Version version = new Version(\"0.0.0.1\");\r\n\r\n            string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());\r\n            Directory.CreateDirectory(tempDirectory);\r\n\r\n            ConfigurationUnit unit = this.ConfigurationUnit();\r\n            unit.Metadata.Add(\"version\", version.ToString());\r\n            unit.Metadata.Add(\"module\", moduleName);\r\n            unit.Settings.Add(\"directoryPath\", tempDirectory);\r\n            unit.Type = resourceName;\r\n            unit.Intent = ConfigurationUnitIntent.Inform;\r\n\r\n            IConfigurationSetProcessorFactory dynamicFactory = await this.fixture.ConfigurationStatics.CreateConfigurationSetProcessorFactoryAsync(Helpers.Constants.DynamicRuntimeHandlerIdentifier);\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(dynamicFactory);\r\n\r\n            var result = await processor.GetUnitSettingsAsync(unit);\r\n\r\n            Assert.NotNull(result);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorApplyTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationProcessorApplyTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.IO;\r\n    using System.Linq;\r\n    using System.Threading;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using Microsoft.VisualBasic;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n\r\n    /// <summary>\r\n    /// Unit tests for running apply on the processor.\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [InProc]\r\n    [OutOfProc]\r\n    public class ConfigurationProcessorApplyTests : ConfigurationProcessorTestBase\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ConfigurationProcessorApplyTests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Unit test fixture.</param>\r\n        /// <param name=\"log\">Log helper.</param>\r\n        public ConfigurationProcessorApplyTests(UnitTestFixture fixture, ITestOutputHelper log)\r\n            : base(fixture, log)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// An error creating the set processor results in an error for the function.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ApplySet_SetProcessorError()\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            factory.Exceptions.Add(configurationSet, new FileNotFoundException());\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            Assert.Throws<FileNotFoundException>(() => processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None));\r\n\r\n            Assert.Empty(this.EventSink.Events);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Multiple configuration units with the same identifier.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ApplySet_DuplicateIdentifiers()\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            ConfigurationUnit configurationUnit1 = this.ConfigurationUnit();\r\n            ConfigurationUnit configurationUnit2 = this.ConfigurationUnit();\r\n            ConfigurationUnit configurationUnitDifferentIdentifier = this.ConfigurationUnit();\r\n            string sharedIdentifier = \"SameIdentifier\";\r\n            configurationUnit1.Identifier = sharedIdentifier;\r\n            configurationUnit2.Identifier = sharedIdentifier;\r\n            configurationSet.Units = new ConfigurationUnit[] { configurationUnit1, configurationUnit2, configurationUnitDifferentIdentifier };\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            ApplyConfigurationSetResult result = processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None);\r\n            Assert.NotNull(result);\r\n            Assert.NotNull(result.ResultCode);\r\n            Assert.Equal(Errors.WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER, result.ResultCode.HResult);\r\n            Assert.Equal(3, result.UnitResults.Count);\r\n\r\n            foreach (var configurationUnit in new ConfigurationUnit[] { configurationUnit1, configurationUnit2 })\r\n            {\r\n                ApplyConfigurationUnitResult? unitResult = result.UnitResults.First(x => x.Unit == configurationUnit);\r\n                Assert.NotNull(unitResult);\r\n                Assert.False(unitResult.PreviouslyInDesiredState);\r\n                Assert.False(unitResult.RebootRequired);\r\n                Assert.NotNull(unitResult.ResultInformation);\r\n                Assert.NotNull(unitResult.ResultInformation.ResultCode);\r\n                Assert.Equal(Errors.WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER, unitResult.ResultInformation.ResultCode.HResult);\r\n                Assert.Equal(ConfigurationUnitResultSource.ConfigurationSet, unitResult.ResultInformation.ResultSource);\r\n            }\r\n\r\n            ApplyConfigurationUnitResult unitResultDifferentIdentifier = result.UnitResults.First(x => x.Unit == configurationUnitDifferentIdentifier);\r\n            Assert.NotNull(unitResultDifferentIdentifier);\r\n            Assert.False(unitResultDifferentIdentifier.PreviouslyInDesiredState);\r\n            Assert.False(unitResultDifferentIdentifier.RebootRequired);\r\n            Assert.NotNull(unitResultDifferentIdentifier.ResultInformation);\r\n            Assert.Null(unitResultDifferentIdentifier.ResultInformation.ResultCode);\r\n            Assert.Equal(ConfigurationUnitResultSource.None, unitResultDifferentIdentifier.ResultInformation.ResultSource);\r\n\r\n            this.VerifySummaryEvent(configurationSet, result, ConfigurationUnitResultSource.ConfigurationSet);\r\n        }\r\n\r\n        /// <summary>\r\n        /// A configuration unit has a dependency that is not in the set.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ApplySet_MissingDependency()\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            ConfigurationUnit configurationUnit = this.ConfigurationUnit();\r\n            ConfigurationUnit configurationUnitMissingDependency = this.ConfigurationUnit();\r\n            configurationUnit.Identifier = \"Identifier\";\r\n            configurationUnitMissingDependency.Dependencies = new string[] { \"Dependency\" };\r\n            configurationSet.Units = new ConfigurationUnit[] { configurationUnit, configurationUnitMissingDependency };\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            ApplyConfigurationSetResult result = processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None);\r\n            Assert.NotNull(result);\r\n            Assert.NotNull(result.ResultCode);\r\n            Assert.Equal(Errors.WINGET_CONFIG_ERROR_MISSING_DEPENDENCY, result.ResultCode.HResult);\r\n            Assert.Equal(2, result.UnitResults.Count);\r\n\r\n            ApplyConfigurationUnitResult unitResult = result.UnitResults.First(x => x.Unit == configurationUnit);\r\n            Assert.NotNull(unitResult);\r\n            Assert.False(unitResult.PreviouslyInDesiredState);\r\n            Assert.False(unitResult.RebootRequired);\r\n            Assert.NotNull(unitResult.ResultInformation);\r\n            Assert.Null(unitResult.ResultInformation.ResultCode);\r\n            Assert.Equal(ConfigurationUnitResultSource.None, unitResult.ResultInformation.ResultSource);\r\n\r\n            unitResult = result.UnitResults.First(x => x.Unit == configurationUnitMissingDependency);\r\n            Assert.NotNull(unitResult);\r\n            Assert.False(unitResult.PreviouslyInDesiredState);\r\n            Assert.False(unitResult.RebootRequired);\r\n            Assert.NotNull(unitResult.ResultInformation);\r\n            Assert.NotNull(unitResult.ResultInformation.ResultCode);\r\n            Assert.Equal(Errors.WINGET_CONFIG_ERROR_MISSING_DEPENDENCY, unitResult.ResultInformation.ResultCode.HResult);\r\n            Assert.Equal(ConfigurationUnitResultSource.ConfigurationSet, unitResult.ResultInformation.ResultSource);\r\n\r\n            this.VerifySummaryEvent(configurationSet, result, ConfigurationUnitResultSource.ConfigurationSet);\r\n        }\r\n\r\n        /// <summary>\r\n        /// The configuration set has a dependency cycle.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ApplySet_DependencyCycle()\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            ConfigurationUnit configurationUnit1 = this.ConfigurationUnit();\r\n            ConfigurationUnit configurationUnit2 = this.ConfigurationUnit();\r\n            ConfigurationUnit configurationUnit3 = this.ConfigurationUnit();\r\n            configurationUnit1.Identifier = \"Identifier1\";\r\n            configurationUnit2.Identifier = \"Identifier2\";\r\n            configurationUnit3.Identifier = \"Identifier3\";\r\n            configurationUnit1.Dependencies = new string[] { \"Identifier3\" };\r\n            configurationUnit2.Dependencies = new string[] { \"Identifier1\" };\r\n            configurationUnit3.Dependencies = new string[] { \"Identifier2\" };\r\n            configurationSet.Units = new ConfigurationUnit[] { configurationUnit1, configurationUnit2, configurationUnit3 };\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            ApplyConfigurationSetResult result = processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None);\r\n            Assert.NotNull(result);\r\n            Assert.NotNull(result.ResultCode);\r\n            Assert.Equal(Errors.WINGET_CONFIG_ERROR_SET_DEPENDENCY_CYCLE, result.ResultCode.HResult);\r\n            Assert.Equal(3, result.UnitResults.Count);\r\n\r\n            foreach (var unitResult in result.UnitResults)\r\n            {\r\n                Assert.NotNull(unitResult);\r\n                Assert.False(unitResult.PreviouslyInDesiredState);\r\n                Assert.False(unitResult.RebootRequired);\r\n                Assert.NotNull(unitResult.ResultInformation);\r\n                Assert.NotNull(unitResult.ResultInformation.ResultCode);\r\n                Assert.Equal(Errors.WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED, unitResult.ResultInformation.ResultCode.HResult);\r\n                Assert.Equal(ConfigurationUnitResultSource.Precondition, unitResult.ResultInformation.ResultSource);\r\n            }\r\n\r\n            this.VerifySummaryEvent(configurationSet, result, ConfigurationUnitResultSource.Precondition);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Checks that the intent for configuration units is handled properly.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ApplySet_IntentRespected()\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            ConfigurationUnit configurationUnitAssert = this.ConfigurationUnit().Assign(new { Intent = ConfigurationUnitIntent.Assert });\r\n            ConfigurationUnit configurationUnitInform = this.ConfigurationUnit().Assign(new { Intent = ConfigurationUnitIntent.Inform });\r\n            ConfigurationUnit configurationUnitApply = this.ConfigurationUnit().Assign(new { Intent = ConfigurationUnitIntent.Apply });\r\n            configurationSet.Units = new ConfigurationUnit[] { configurationUnitInform, configurationUnitApply, configurationUnitAssert };\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet);\r\n            TestConfigurationUnitProcessor unitProcessorAssert = setProcessor.CreateTestProcessor(configurationUnitAssert);\r\n            TestConfigurationUnitProcessor unitProcessorInform = setProcessor.CreateTestProcessor(configurationUnitInform);\r\n            TestConfigurationUnitProcessor unitProcessorApply = setProcessor.CreateTestProcessor(configurationUnitApply);\r\n            unitProcessorApply.TestSettingsDelegate = () => new TestSettingsResultInstance(configurationUnitApply) { TestResult = ConfigurationTestResult.Negative };\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            ApplyConfigurationSetResult result = processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None);\r\n            Assert.NotNull(result);\r\n            Assert.Null(result.ResultCode);\r\n            Assert.Equal(3, result.UnitResults.Count);\r\n\r\n            foreach (var unitResult in result.UnitResults)\r\n            {\r\n                Assert.NotNull(unitResult);\r\n                Assert.False(unitResult.PreviouslyInDesiredState);\r\n                Assert.False(unitResult.RebootRequired);\r\n                Assert.NotNull(unitResult.ResultInformation);\r\n                Assert.Null(unitResult.ResultInformation.ResultCode);\r\n                Assert.Equal(ConfigurationUnitResultSource.None, unitResult.ResultInformation.ResultSource);\r\n            }\r\n\r\n            Assert.Equal(1, unitProcessorAssert.TestSettingsCalls);\r\n            Assert.Equal(0, unitProcessorAssert.GetSettingsCalls);\r\n            Assert.Equal(0, unitProcessorAssert.ApplySettingsCalls);\r\n\r\n            Assert.Equal(0, unitProcessorInform.TestSettingsCalls);\r\n            Assert.Equal(1, unitProcessorInform.GetSettingsCalls);\r\n            Assert.Equal(0, unitProcessorInform.ApplySettingsCalls);\r\n\r\n            Assert.Equal(1, unitProcessorApply.TestSettingsCalls);\r\n            Assert.Equal(0, unitProcessorApply.GetSettingsCalls);\r\n            Assert.Equal(1, unitProcessorApply.ApplySettingsCalls);\r\n\r\n            this.VerifySummaryEvent(configurationSet, result, ConfigurationUnitResultSource.None);\r\n        }\r\n\r\n        /// <summary>\r\n        /// An assertion fails to run.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ApplySet_AssertionFailure()\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            ConfigurationUnit configurationUnitAssert = this.ConfigurationUnit().Assign(new { Intent = ConfigurationUnitIntent.Assert });\r\n            ConfigurationUnit configurationUnitApply = this.ConfigurationUnit().Assign(new { Intent = ConfigurationUnitIntent.Apply });\r\n            configurationSet.Units = new ConfigurationUnit[] { configurationUnitApply, configurationUnitAssert };\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet);\r\n            TestConfigurationUnitProcessor unitProcessorAssert = setProcessor.CreateTestProcessor(configurationUnitAssert);\r\n            unitProcessorAssert.TestSettingsDelegate = () => throw new NullReferenceException();\r\n            TestConfigurationUnitProcessor unitProcessorApply = setProcessor.CreateTestProcessor(configurationUnitApply);\r\n            unitProcessorApply.TestSettingsDelegate = () => new TestSettingsResultInstance(configurationUnitApply) { TestResult = ConfigurationTestResult.Negative };\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            ApplyConfigurationSetResult result = processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None);\r\n            Assert.NotNull(result);\r\n            Assert.NotNull(result.ResultCode);\r\n            Assert.Equal(Errors.WINGET_CONFIG_ERROR_ASSERTION_FAILED, result.ResultCode.HResult);\r\n            Assert.Equal(2, result.UnitResults.Count);\r\n\r\n            ApplyConfigurationUnitResult unitResult = result.UnitResults.First(x => x.Unit == configurationUnitAssert);\r\n            Assert.NotNull(unitResult);\r\n            Assert.False(unitResult.PreviouslyInDesiredState);\r\n            Assert.False(unitResult.RebootRequired);\r\n            Assert.NotNull(unitResult.ResultInformation);\r\n            Assert.NotNull(unitResult.ResultInformation.ResultCode);\r\n            Assert.IsType<NullReferenceException>(unitResult.ResultInformation.ResultCode);\r\n            Assert.Equal(ConfigurationUnitResultSource.Internal, unitResult.ResultInformation.ResultSource);\r\n\r\n            unitResult = result.UnitResults.First(x => x.Unit == configurationUnitApply);\r\n            Assert.NotNull(unitResult);\r\n            Assert.False(unitResult.PreviouslyInDesiredState);\r\n            Assert.False(unitResult.RebootRequired);\r\n            Assert.NotNull(unitResult.ResultInformation);\r\n            Assert.NotNull(unitResult.ResultInformation.ResultCode);\r\n            Assert.Equal(Errors.WINGET_CONFIG_ERROR_ASSERTION_FAILED, unitResult.ResultInformation.ResultCode.HResult);\r\n            Assert.Equal(ConfigurationUnitResultSource.Precondition, unitResult.ResultInformation.ResultSource);\r\n\r\n            this.VerifySummaryEvent(configurationSet, result, ConfigurationUnitResultSource.Internal);\r\n        }\r\n\r\n        /// <summary>\r\n        /// An assertion is found to be false.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ApplySet_AssertionNegative()\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            ConfigurationUnit configurationUnitAssert = this.ConfigurationUnit().Assign(new { Intent = ConfigurationUnitIntent.Assert });\r\n            ConfigurationUnit configurationUnitApply = this.ConfigurationUnit().Assign(new { Intent = ConfigurationUnitIntent.Apply });\r\n            configurationSet.Units = new ConfigurationUnit[] { configurationUnitApply, configurationUnitAssert };\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet);\r\n            TestConfigurationUnitProcessor unitProcessorAssert = setProcessor.CreateTestProcessor(configurationUnitAssert);\r\n            unitProcessorAssert.TestSettingsDelegate = () => new TestSettingsResultInstance(configurationUnitAssert) { TestResult = ConfigurationTestResult.Negative };\r\n            TestConfigurationUnitProcessor unitProcessorApply = setProcessor.CreateTestProcessor(configurationUnitApply);\r\n            unitProcessorApply.TestSettingsDelegate = () => new TestSettingsResultInstance(configurationUnitApply) { TestResult = ConfigurationTestResult.Negative };\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            ApplyConfigurationSetResult result = processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None);\r\n            Assert.NotNull(result);\r\n            Assert.NotNull(result.ResultCode);\r\n            Assert.Equal(Errors.WINGET_CONFIG_ERROR_ASSERTION_FAILED, result.ResultCode.HResult);\r\n            Assert.Equal(2, result.UnitResults.Count);\r\n\r\n            foreach (var unitResult in result.UnitResults)\r\n            {\r\n                Assert.NotNull(unitResult);\r\n                Assert.False(unitResult.PreviouslyInDesiredState);\r\n                Assert.False(unitResult.RebootRequired);\r\n                Assert.NotNull(unitResult.ResultInformation);\r\n                Assert.NotNull(unitResult.ResultInformation.ResultCode);\r\n                Assert.Equal(Errors.WINGET_CONFIG_ERROR_ASSERTION_FAILED, unitResult.ResultInformation.ResultCode.HResult);\r\n                Assert.Equal(ConfigurationUnitResultSource.Precondition, unitResult.ResultInformation.ResultSource);\r\n            }\r\n\r\n            this.VerifySummaryEvent(configurationSet, result, ConfigurationUnitResultSource.Precondition);\r\n        }\r\n\r\n        /// <summary>\r\n        /// A unit in the correct state is not applied again.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ApplySet_UnitAlreadyInCorrectState()\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            ConfigurationUnit configurationUnit = this.ConfigurationUnit().Assign(new { Intent = ConfigurationUnitIntent.Apply });\r\n            configurationSet.Units = new ConfigurationUnit[] { configurationUnit };\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet);\r\n            TestConfigurationUnitProcessor unitProcessor = setProcessor.CreateTestProcessor(configurationUnit);\r\n            unitProcessor.TestSettingsDelegate = () => new TestSettingsResultInstance(configurationUnit) { TestResult = ConfigurationTestResult.Positive };\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            ApplyConfigurationSetResult result = processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None);\r\n            Assert.NotNull(result);\r\n            Assert.Null(result.ResultCode);\r\n            Assert.Equal(1, result.UnitResults.Count);\r\n\r\n            ApplyConfigurationUnitResult unitResult = result.UnitResults.First();\r\n            Assert.NotNull(unitResult);\r\n            Assert.True(unitResult.PreviouslyInDesiredState);\r\n            Assert.False(unitResult.RebootRequired);\r\n            Assert.NotNull(unitResult.ResultInformation);\r\n            Assert.Null(unitResult.ResultInformation.ResultCode);\r\n            Assert.Equal(ConfigurationUnitResultSource.None, unitResult.ResultInformation.ResultSource);\r\n\r\n            this.VerifySummaryEvent(configurationSet, result, ConfigurationUnitResultSource.None);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Checks the progress reporting.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ApplySet_Progress()\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            ConfigurationUnit assert1 = this.ConfigurationUnit().Assign(new { Intent = ConfigurationUnitIntent.Assert, Identifier = \"Assert1\" });\r\n            ConfigurationUnit assert2 = this.ConfigurationUnit().Assign(new { Intent = ConfigurationUnitIntent.Assert, Identifier = \"Assert2\", Dependencies = new string[] { assert1.Identifier } });\r\n            ConfigurationUnit inform1 = this.ConfigurationUnit().Assign(new { Intent = ConfigurationUnitIntent.Inform, Identifier = \"Inform1\" });\r\n            ConfigurationUnit apply1 = this.ConfigurationUnit().Assign(new { Intent = ConfigurationUnitIntent.Apply, Identifier = \"Apply1\" });\r\n            ConfigurationUnit apply2 = this.ConfigurationUnit().Assign(new { Intent = ConfigurationUnitIntent.Apply, Identifier = \"Apply2\" });\r\n            ConfigurationUnit apply3 = this.ConfigurationUnit().Assign(new { Intent = ConfigurationUnitIntent.Apply, Identifier = \"Apply3\", Dependencies = new string[] { apply1.Identifier, apply2.Identifier } });\r\n            ConfigurationUnit apply4 = this.ConfigurationUnit().Assign(new { Intent = ConfigurationUnitIntent.Apply, Identifier = \"Apply4\", IsActive = false });\r\n            ConfigurationUnit apply5 = this.ConfigurationUnit().Assign(new { Intent = ConfigurationUnitIntent.Apply, Identifier = \"Apply5\", Dependencies = new string[] { apply4.Identifier } });\r\n            configurationSet.Units = new ConfigurationUnit[] { assert2, assert1, inform1, apply1, apply3, apply4,  apply2, apply5 };\r\n\r\n            ManualResetEvent startProcessing = new ManualResetEvent(false);\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            factory.CreateSetProcessorDelegate = (f, c) =>\r\n            {\r\n                startProcessing.WaitOne();\r\n                return f.DefaultCreateSetProcessor(c);\r\n            };\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n            List<ConfigurationSetChangeData> progressEvents = new List<ConfigurationSetChangeData>();\r\n\r\n            var operation = processor.ApplySetAsync(configurationSet, ApplyConfigurationSetFlags.None);\r\n            operation.Progress = (asyncInfo, progress) => progressEvents.Add(progress);\r\n            startProcessing.Set();\r\n            operation.AsTask().Wait();\r\n            ApplyConfigurationSetResult result = operation.GetResults();\r\n\r\n            Assert.NotNull(result);\r\n            Assert.NotNull(result.ResultCode);\r\n            Assert.Equal(Errors.WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED, result.ResultCode.HResult);\r\n            Assert.NotNull(result.UnitResults);\r\n            Assert.Equal(configurationSet.Units.Count, result.UnitResults.Count);\r\n\r\n            // Verify that progress events match the expected\r\n            ExpectedConfigurationChangeData[] expectedProgress = new ExpectedConfigurationChangeData[]\r\n            {\r\n                new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.SetStateChanged, SetState = ConfigurationSetState.InProgress },\r\n                new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.InProgress, Unit = assert1 },\r\n                new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.Completed, Unit = assert1 },\r\n                new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.InProgress, Unit = assert2 },\r\n                new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.Completed, Unit = assert2 },\r\n                new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.InProgress, Unit = inform1 },\r\n                new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.Completed, Unit = inform1 },\r\n                new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.InProgress, Unit = apply1 },\r\n                new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.Completed, Unit = apply1 },\r\n                new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.Skipped, Unit = apply4, HResult = Errors.WINGET_CONFIG_ERROR_MANUALLY_SKIPPED },\r\n                new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.InProgress, Unit = apply2 },\r\n                new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.Completed, Unit = apply2 },\r\n                new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.InProgress, Unit = apply3 },\r\n                new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.Completed, Unit = apply3 },\r\n                new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.UnitStateChanged, UnitState = ConfigurationUnitState.Skipped, Unit = apply5, HResult = Errors.WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED },\r\n                new ExpectedConfigurationChangeData() { Change = ConfigurationSetChangeEventType.SetStateChanged, SetState = ConfigurationSetState.Completed },\r\n            };\r\n\r\n            // Drop the pending event if it happens to be present\r\n            if (progressEvents.Count > 0 && progressEvents[0].Change == ConfigurationSetChangeEventType.SetStateChanged && progressEvents[0].SetState == ConfigurationSetState.Pending)\r\n            {\r\n                progressEvents.RemoveAt(0);\r\n            }\r\n\r\n            Assert.Equal(expectedProgress.Count(), progressEvents.Count);\r\n\r\n            for (int i = 0; i < progressEvents.Count; ++i)\r\n            {\r\n                this.Log.WriteLine($\"Comparing event {i}\");\r\n                Assert.Equal(expectedProgress[i].Change, progressEvents[i].Change);\r\n                switch (expectedProgress[i].Change)\r\n                {\r\n                    case ConfigurationSetChangeEventType.SetStateChanged:\r\n                        Assert.Equal(expectedProgress[i].SetState, progressEvents[i].SetState);\r\n                        break;\r\n                    case ConfigurationSetChangeEventType.UnitStateChanged:\r\n                        Assert.Equal(expectedProgress[i].UnitState, progressEvents[i].UnitState);\r\n                        Assert.Same(expectedProgress[i].Unit, progressEvents[i].Unit);\r\n\r\n                        Assert.NotNull(progressEvents[i].ResultInformation);\r\n                        if (expectedProgress[i].HResult == 0)\r\n                        {\r\n                            Assert.Null(progressEvents[i].ResultInformation.ResultCode);\r\n                            Assert.Equal(ConfigurationUnitResultSource.None, progressEvents[i].ResultInformation.ResultSource);\r\n                        }\r\n                        else\r\n                        {\r\n                            Assert.NotNull(progressEvents[i].ResultInformation.ResultCode);\r\n                            Assert.Equal(expectedProgress[i].HResult, progressEvents[i].ResultInformation.ResultCode.HResult);\r\n                            Assert.Equal(ConfigurationUnitResultSource.Precondition, progressEvents[i].ResultInformation.ResultSource);\r\n                        }\r\n\r\n                        break;\r\n                    default:\r\n                        Assert.Fail(\"Unexpected ConfigurationSetChangeEventType value\");\r\n                        break;\r\n                }\r\n            }\r\n\r\n            this.VerifySummaryEvent(configurationSet, result, ConfigurationUnitResultSource.Precondition);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Ensures that multiple apply operations are sequenced.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ApplySet_Sequenced()\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            ConfigurationUnit configurationUnitApply = this.ConfigurationUnit().Assign(new { Intent = ConfigurationUnitIntent.Apply });\r\n            configurationSet.Units = new ConfigurationUnit[] { configurationUnitApply };\r\n\r\n            ManualResetEvent startProcessing = new ManualResetEvent(true);\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            factory.CreateSetProcessorDelegate = (f, c) =>\r\n            {\r\n                WaitOn(startProcessing);\r\n                return f.DefaultCreateSetProcessor(c);\r\n            };\r\n\r\n            TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet);\r\n            TestConfigurationUnitProcessor unitProcessorApply = setProcessor.CreateTestProcessor(configurationUnitApply);\r\n            unitProcessorApply.TestSettingsDelegate = () => new TestSettingsResultInstance(configurationUnitApply) { TestResult = ConfigurationTestResult.Negative };\r\n\r\n            ManualResetEvent applyEventWaiting = new ManualResetEvent(false);\r\n            ManualResetEvent completeApplyEvent = new ManualResetEvent(false);\r\n            unitProcessorApply.ApplySettingsDelegate = () =>\r\n            {\r\n                applyEventWaiting.Set();\r\n                WaitOn(completeApplyEvent);\r\n                return new ApplySettingsResultInstance(configurationUnitApply);\r\n            };\r\n\r\n            ConfigurationSet configurationSetThatWaits = this.ConfigurationSet();\r\n            ConfigurationUnit configurationUnitThatWaits = this.ConfigurationUnit().Assign(new { Intent = ConfigurationUnitIntent.Apply });\r\n            configurationSetThatWaits.Units = new ConfigurationUnit[] { configurationUnitThatWaits };\r\n\r\n            TestConfigurationSetProcessor setThatWaitsProcessor = factory.CreateTestProcessor(configurationSetThatWaits);\r\n            TestConfigurationUnitProcessor unitThatWaitsProcessor = setProcessor.CreateTestProcessor(configurationUnitThatWaits);\r\n            unitThatWaitsProcessor.TestSettingsDelegate = () => new TestSettingsResultInstance(configurationUnitApply) { TestResult = ConfigurationTestResult.Negative };\r\n\r\n            ManualResetEvent waitingUnitApply = new ManualResetEvent(false);\r\n            unitThatWaitsProcessor.ApplySettingsDelegate = () =>\r\n            {\r\n                WaitOn(waitingUnitApply);\r\n                return new ApplySettingsResultInstance(configurationUnitThatWaits);\r\n            };\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            var applySetOperation = processor.ApplySetAsync(configurationSet, ApplyConfigurationSetFlags.None);\r\n            WaitOn(applyEventWaiting);\r\n\r\n            startProcessing.Reset();\r\n            var waitingSetOperation = processor.ApplySetAsync(configurationSetThatWaits, ApplyConfigurationSetFlags.None);\r\n            AutoResetEvent waitingProgress = new AutoResetEvent(false);\r\n            ConfigurationSetState progressState = ConfigurationSetState.Unknown;\r\n            waitingSetOperation.Progress += (result, changeData) =>\r\n            {\r\n                if (changeData.Change == ConfigurationSetChangeEventType.SetStateChanged)\r\n                {\r\n                    progressState = changeData.SetState;\r\n                    waitingProgress.Set();\r\n                }\r\n            };\r\n\r\n            startProcessing.Set();\r\n            WaitOn(waitingProgress);\r\n            Assert.Equal(ConfigurationSetState.Pending, progressState);\r\n\r\n            completeApplyEvent.Set();\r\n            WaitOn(waitingProgress);\r\n            Assert.Equal(ConfigurationSetState.InProgress, progressState);\r\n\r\n            waitingUnitApply.Set();\r\n            WaitOn(waitingProgress);\r\n            Assert.Equal(ConfigurationSetState.Completed, progressState);\r\n\r\n            waitingSetOperation.AsTask().Wait();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Ensures that a consistency check apply is not blocked.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ApplySet_ConsistencyCheckNotSequenced()\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            ConfigurationUnit configurationUnitApply = this.ConfigurationUnit().Assign(new { Intent = ConfigurationUnitIntent.Apply });\r\n            configurationSet.Units = new ConfigurationUnit[] { configurationUnitApply };\r\n\r\n            ManualResetEvent startProcessing = new ManualResetEvent(true);\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            factory.CreateSetProcessorDelegate = (f, c) =>\r\n            {\r\n                WaitOn(startProcessing);\r\n                return f.DefaultCreateSetProcessor(c);\r\n            };\r\n\r\n            TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet);\r\n            TestConfigurationUnitProcessor unitProcessorApply = setProcessor.CreateTestProcessor(configurationUnitApply);\r\n            unitProcessorApply.TestSettingsDelegate = () => new TestSettingsResultInstance(configurationUnitApply) { TestResult = ConfigurationTestResult.Negative };\r\n\r\n            ManualResetEvent applyEventWaiting = new ManualResetEvent(false);\r\n            ManualResetEvent completeApplyEvent = new ManualResetEvent(false);\r\n            unitProcessorApply.ApplySettingsDelegate = () =>\r\n            {\r\n                applyEventWaiting.Set();\r\n                WaitOn(completeApplyEvent);\r\n                return new ApplySettingsResultInstance(configurationUnitApply);\r\n            };\r\n\r\n            ConfigurationSet configurationSetThatWaits = this.ConfigurationSet();\r\n            ConfigurationUnit configurationUnitThatWaits = this.ConfigurationUnit().Assign(new { Intent = ConfigurationUnitIntent.Apply });\r\n            configurationSetThatWaits.Units = new ConfigurationUnit[] { configurationUnitThatWaits };\r\n\r\n            TestConfigurationSetProcessor setThatWaitsProcessor = factory.CreateTestProcessor(configurationSetThatWaits);\r\n            TestConfigurationUnitProcessor unitThatWaitsProcessor = setProcessor.CreateTestProcessor(configurationUnitThatWaits);\r\n            unitThatWaitsProcessor.TestSettingsDelegate = () => new TestSettingsResultInstance(configurationUnitApply) { TestResult = ConfigurationTestResult.Negative };\r\n\r\n            ManualResetEvent waitingUnitApply = new ManualResetEvent(false);\r\n            unitThatWaitsProcessor.ApplySettingsDelegate = () =>\r\n            {\r\n                WaitOn(waitingUnitApply);\r\n                return new ApplySettingsResultInstance(configurationUnitThatWaits);\r\n            };\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            var applySetOperation = processor.ApplySetAsync(configurationSet, ApplyConfigurationSetFlags.None);\r\n            WaitOn(applyEventWaiting);\r\n\r\n            startProcessing.Reset();\r\n            var waitingSetOperation = processor.ApplySetAsync(configurationSetThatWaits, ApplyConfigurationSetFlags.PerformConsistencyCheckOnly);\r\n            Assert.True(waitingSetOperation.AsTask().Wait(10000));\r\n\r\n            completeApplyEvent.Set();\r\n        }\r\n\r\n        private static void WaitOn(WaitHandle waitable)\r\n        {\r\n            if (!waitable.WaitOne(10000))\r\n            {\r\n                throw new TimeoutException();\r\n            }\r\n        }\r\n\r\n        private struct ExpectedConfigurationChangeData\r\n        {\r\n            public ConfigurationSetChangeEventType Change;\r\n            public ConfigurationSetState SetState;\r\n            public ConfigurationUnitState UnitState;\r\n            public int HResult;\r\n            public ConfigurationUnit Unit;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorFactoryTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationProcessorFactoryTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System.Collections.Generic;\r\n    using Microsoft.Management.Configuration.Processor;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.Set;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using WinRT;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n    using static Microsoft.Management.Configuration.Processor.PowerShell.Constants.PowerShellConstants;\r\n\r\n    /// <summary>\r\n    /// Tests ConfigurationProcessorFactory.\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [InProc]\r\n    public class ConfigurationProcessorFactoryTests\r\n    {\r\n        private readonly UnitTestFixture fixture;\r\n        private readonly ITestOutputHelper log;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ConfigurationProcessorFactoryTests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Unit test fixture.</param>\r\n        /// <param name=\"log\">Log helper.</param>\r\n        public ConfigurationProcessorFactoryTests(UnitTestFixture fixture, ITestOutputHelper log)\r\n        {\r\n            this.fixture = fixture;\r\n            this.log = log;\r\n        }\r\n\r\n        /// <summary>\r\n        /// CreateSetProcessor test.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CreateSetProcessor_Test()\r\n        {\r\n            var configurationProcessorFactory = new PowerShellConfigurationSetProcessorFactory();\r\n\r\n            var properties = configurationProcessorFactory.As<IPowerShellConfigurationProcessorFactoryProperties>();\r\n            properties.ProcessorType = PowerShellConfigurationProcessorType.Hosted;\r\n\r\n            var configurationSet = new ConfigurationSet();\r\n\r\n            var configurationProcessorSet = configurationProcessorFactory.CreateSetProcessor(configurationSet);\r\n\r\n            Assert.NotNull(configurationProcessorSet);\r\n            Assert.IsType<PowerShellConfigurationSetProcessor>(configurationProcessorSet);\r\n            var processorSet = configurationProcessorSet as PowerShellConfigurationSetProcessor;\r\n            Assert.NotNull(processorSet);\r\n        }\r\n\r\n        /// <summary>\r\n        /// AdditionalModulePaths test.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CreateSetProcessor_Properties_PsModulePath()\r\n        {\r\n            var configurationProcessorFactory = new PowerShellConfigurationSetProcessorFactory();\r\n\r\n            var properties = configurationProcessorFactory.As<IPowerShellConfigurationProcessorFactoryProperties>();\r\n            properties.ProcessorType = PowerShellConfigurationProcessorType.Hosted;\r\n            properties.AdditionalModulePaths = new List<string>\r\n                {\r\n                    \"ThisIsOnePath\",\r\n                    \"ThisIsAnotherPath\",\r\n                };\r\n\r\n            var configurationSet = new ConfigurationSet();\r\n\r\n            var configurationProcessorSet = configurationProcessorFactory.CreateSetProcessor(configurationSet);\r\n\r\n            Assert.IsType<PowerShellConfigurationSetProcessor>(configurationProcessorSet);\r\n            var processorSet = configurationProcessorSet as PowerShellConfigurationSetProcessor;\r\n            Assert.NotNull(processorSet);\r\n\r\n            var modulePath = processorSet.ProcessorEnvironment.GetVariable<string>(Variables.PSModulePath);\r\n            Assert.Contains(\"ThisIsOnePath;ThisIsAnotherPath\", modulePath);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Make sure the winget path is always added to PSModulePath.\r\n        /// </summary>\r\n        /// <param name=\"location\">Location.</param>\r\n        [Theory]\r\n        [InlineData(PowerShellConfigurationProcessorLocation.CurrentUser)]\r\n        [InlineData(PowerShellConfigurationProcessorLocation.AllUsers)]\r\n        [InlineData(PowerShellConfigurationProcessorLocation.WinGetModulePath)]\r\n        [InlineData(PowerShellConfigurationProcessorLocation.Custom)]\r\n        public void CreateSetProcessor_WinGetPath(PowerShellConfigurationProcessorLocation location)\r\n        {\r\n            var configurationProcessorFactory = new PowerShellConfigurationSetProcessorFactory();\r\n\r\n            var properties = configurationProcessorFactory.As<IPowerShellConfigurationProcessorFactoryProperties>();\r\n            properties.Location = location;\r\n\r\n            if (properties.Location == PowerShellConfigurationProcessorLocation.Custom)\r\n            {\r\n                properties.CustomLocation = @\"c:\\this\\is\\a\\module\\path\";\r\n            }\r\n\r\n            var configurationSet = new ConfigurationSet();\r\n\r\n            var setProcessor = configurationProcessorFactory.CreateSetProcessor(configurationSet) as PowerShellConfigurationSetProcessor;\r\n            Assert.NotNull(setProcessor);\r\n\r\n            var modulePath = setProcessor.ProcessorEnvironment.GetVariable<string>(Variables.PSModulePath);\r\n            Assert.Contains($\"{PowerShellConfigurationSetProcessorFactory.GetWinGetModulePath()};\", modulePath);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests the custom location is added successfully.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CreateSetProcessor_CustomLocation()\r\n        {\r\n            var configurationProcessorFactory = new PowerShellConfigurationSetProcessorFactory();\r\n\r\n            var properties = configurationProcessorFactory.As<IPowerShellConfigurationProcessorFactoryProperties>();\r\n            properties.Location = PowerShellConfigurationProcessorLocation.Custom;\r\n            properties.CustomLocation = @\"c:\\this\\is\\a\\module\\path\";\r\n\r\n            var configurationSet = new ConfigurationSet();\r\n\r\n            var setProcessor = configurationProcessorFactory.CreateSetProcessor(configurationSet) as PowerShellConfigurationSetProcessor;\r\n            Assert.NotNull(setProcessor);\r\n\r\n            var modulePath = setProcessor.ProcessorEnvironment.GetVariable<string>(Variables.PSModulePath);\r\n            Assert.Contains($\"{properties.CustomLocation};\", modulePath);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests the configuration set processor in limitation mode.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CreateSetProcessor_LimitMode()\r\n        {\r\n            var configurationProcessorFactory = new PowerShellConfigurationSetProcessorFactory();\r\n            var configurationSet = new ConfigurationSet();\r\n            configurationProcessorFactory.LimitationSet = configurationSet;\r\n\r\n            Assert.Throws<System.InvalidOperationException>(() => configurationProcessorFactory.LimitationSet = configurationSet);\r\n            Assert.Throws<System.InvalidOperationException>(() => configurationProcessorFactory.ProcessorType = PowerShellConfigurationProcessorType.Default);\r\n            Assert.Throws<System.InvalidOperationException>(() => configurationProcessorFactory.AdditionalModulePaths = new List<string>());\r\n            Assert.Throws<System.InvalidOperationException>(() => configurationProcessorFactory.ImplicitModulePaths = new List<string>());\r\n            Assert.Throws<System.InvalidOperationException>(() => configurationProcessorFactory.Policy = PowerShellConfigurationProcessorPolicy.Unrestricted);\r\n            Assert.Throws<System.InvalidOperationException>(() => configurationProcessorFactory.Location = PowerShellConfigurationProcessorLocation.Custom);\r\n            Assert.Throws<System.InvalidOperationException>(() => configurationProcessorFactory.CustomLocation = @\"c:\\this\\is\\a\\module\\path\");\r\n\r\n            var setProcessor = configurationProcessorFactory.CreateSetProcessor(configurationSet) as PowerShellConfigurationSetProcessor;\r\n            Assert.NotNull(setProcessor);\r\n            Assert.True(setProcessor.IsLimitMode);\r\n\r\n            // Create processor again in limit mode should fail\r\n            Assert.Throws<System.InvalidOperationException>(() => configurationProcessorFactory.CreateSetProcessor(configurationSet));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests the configuration set processor factory with ImplicitModulePaths.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ImplicitModulePaths()\r\n        {\r\n            var configurationProcessorFactory = new PowerShellConfigurationSetProcessorFactory();\r\n\r\n            // When ImplicitModulePaths module paths are not set\r\n            configurationProcessorFactory.AdditionalModulePaths = new List<string> { @\"c:\\this\\is\\additional\" };\r\n            Assert.Equal(configurationProcessorFactory.AdditionalModulePaths, new List<string> { @\"c:\\this\\is\\additional\" });\r\n\r\n            // Implicit ModulePaths are set, it automatically populates AdditionalModulePaths\r\n            configurationProcessorFactory.ImplicitModulePaths = new List<string> { @\"c:\\this\\is\\implicit\" };\r\n            Assert.Equal(configurationProcessorFactory.AdditionalModulePaths, new List<string> { @\"c:\\this\\is\\additional\", @\"c:\\this\\is\\implicit\" });\r\n\r\n            // Set AdditionalModulePaths when ImplicitModulePaths module paths are set\r\n            configurationProcessorFactory.AdditionalModulePaths = new List<string> { @\"c:\\this\\is\\additional\\2\" };\r\n            Assert.Equal(configurationProcessorFactory.AdditionalModulePaths, new List<string> { @\"c:\\this\\is\\additional\\2\", @\"c:\\this\\is\\implicit\" });\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorGetAllTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationProcessorGetAllTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System.Collections.Generic;\r\n    using System.IO;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using Microsoft.VisualBasic;\r\n    using Windows.Foundation.Collections;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n\r\n    /// <summary>\r\n    /// Unit tests for getting details on processors.\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [InProc]\r\n    [OutOfProc]\r\n    public class ConfigurationProcessorGetAllTests : ConfigurationProcessorTestBase\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ConfigurationProcessorGetAllTests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Unit test fixture.</param>\r\n        /// <param name=\"log\">Log helper.</param>\r\n        public ConfigurationProcessorGetAllTests(UnitTestFixture fixture, ITestOutputHelper log)\r\n            : base(fixture, log)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// The unit settings processor returns an error HRESULT.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetAllSettings_ProcessorSettingsError()\r\n        {\r\n            ConfigurationUnit configurationUnit = this.ConfigurationUnit();\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            factory.NullProcessor = new TestConfigurationSetProcessor(null);\r\n            var unitProcessor = factory.NullProcessor.CreateGetAllSettingsTestProcessor(configurationUnit);\r\n            unitProcessor.GetAllSettingsDelegate = () => throw new FileNotFoundException();\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            GetAllConfigurationUnitSettingsResult result = processor.GetAllUnitSettings(configurationUnit);\r\n\r\n            Assert.NotNull(result);\r\n            Assert.Null(result.Settings);\r\n            Assert.NotNull(result.ResultInformation);\r\n            Assert.NotNull(result.ResultInformation.ResultCode);\r\n            Assert.IsType<FileNotFoundException>(result.ResultInformation.ResultCode);\r\n        }\r\n\r\n        /// <summary>\r\n        /// The unit settings processor returns an error in its result.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetAllSettings_ProcessorSettingsFailedResult()\r\n        {\r\n            ConfigurationUnit configurationUnit = this.ConfigurationUnit();\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            factory.NullProcessor = new TestConfigurationSetProcessor(null);\r\n            var unitProcessor = factory.NullProcessor.CreateGetAllSettingsTestProcessor(configurationUnit);\r\n\r\n            GetAllSettingsResultInstance getAllSettingsResult = new GetAllSettingsResultInstance(configurationUnit);\r\n            getAllSettingsResult.InternalResult.ResultCode = new InvalidDataException();\r\n            getAllSettingsResult.InternalResult.Description = \"We fail because we must\";\r\n            unitProcessor.GetAllSettingsDelegate = () => getAllSettingsResult;\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            GetAllConfigurationUnitSettingsResult result = processor.GetAllUnitSettings(configurationUnit);\r\n\r\n            Assert.NotNull(result);\r\n            Assert.Null(result.Settings);\r\n            Assert.NotNull(result.ResultInformation);\r\n            Assert.Equal(getAllSettingsResult.ResultInformation.ResultCode.HResult, result.ResultInformation.ResultCode.HResult);\r\n            Assert.Equal(getAllSettingsResult.ResultInformation.Description, result.ResultInformation.Description);\r\n        }\r\n\r\n        /// <summary>\r\n        /// The unit settings processor returns good settings.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetAllSettings_ProcessorSettingsSuccess()\r\n        {\r\n            ConfigurationUnit configurationUnit = this.ConfigurationUnit();\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            factory.NullProcessor = new TestConfigurationSetProcessor(null);\r\n            var unitProcessor = factory.NullProcessor.CreateGetAllSettingsTestProcessor(configurationUnit);\r\n\r\n            GetAllSettingsResultInstance getAllSettingsResult = new GetAllSettingsResultInstance(configurationUnit);\r\n            getAllSettingsResult.Settings = new List<ValueSet>()\r\n            {\r\n                new ValueSet\r\n                {\r\n                    { \"key\", \"value\" },\r\n                },\r\n            };\r\n            unitProcessor.GetAllSettingsDelegate = () => getAllSettingsResult;\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            GetAllConfigurationUnitSettingsResult result = processor.GetAllUnitSettings(configurationUnit);\r\n\r\n            Assert.NotNull(result);\r\n            Assert.NotNull(result.ResultInformation);\r\n            Assert.Null(result.ResultInformation.ResultCode);\r\n            Assert.Empty(result.ResultInformation.Description);\r\n            Assert.NotNull(result.Settings);\r\n            Assert.Equal(1, result.Settings.Count);\r\n            Assert.Contains(\"key\", result.Settings[0]);\r\n            Assert.IsType<string>(result.Settings[0][\"key\"]);\r\n            Assert.Equal(\"value\", (string)result.Settings[0][\"key\"]);\r\n        }\r\n\r\n        /// <summary>\r\n        /// The unit settings processor does not support GetAllSettings.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetAllSettings_UnsupportedByProcessor()\r\n        {\r\n            ConfigurationUnit configurationUnit = this.ConfigurationUnit();\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            factory.NullProcessor = new TestConfigurationSetProcessor(null);\r\n            var unitProcessor = factory.NullProcessor.CreateTestProcessor(configurationUnit);\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            GetAllConfigurationUnitSettingsResult result = processor.GetAllUnitSettings(configurationUnit);\r\n\r\n            Assert.NotNull(result);\r\n            Assert.NotNull(result.ResultInformation);\r\n            Assert.NotNull(result.ResultInformation.ResultCode);\r\n            Assert.Equal(Errors.WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR, result.ResultInformation.ResultCode.HResult);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorGetTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationProcessorGetTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System.IO;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using Microsoft.VisualBasic;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n\r\n    /// <summary>\r\n    /// Unit tests for getting details on processors.\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [InProc]\r\n    [OutOfProc]\r\n    public class ConfigurationProcessorGetTests : ConfigurationProcessorTestBase\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ConfigurationProcessorGetTests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Unit test fixture.</param>\r\n        /// <param name=\"log\">Log helper.</param>\r\n        public ConfigurationProcessorGetTests(UnitTestFixture fixture, ITestOutputHelper log)\r\n            : base(fixture, log)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Getting unit details throws an error.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetUnitDetailsError()\r\n        {\r\n            ConfigurationUnit configurationUnitThrows = this.ConfigurationUnit();\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            factory.NullProcessor = new TestConfigurationSetProcessor(null);\r\n            var thrownException = new FileNotFoundException();\r\n            factory.NullProcessor.Exceptions.Add(configurationUnitThrows, thrownException);\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            GetConfigurationUnitDetailsResult result = processor.GetUnitDetails(configurationUnitThrows, ConfigurationUnitDetailFlags.Local);\r\n\r\n            Assert.Null(result.Details);\r\n            Assert.Equal(configurationUnitThrows, result.Unit);\r\n            Assert.Equal(thrownException.HResult, result.ResultInformation.ResultCode.HResult);\r\n            Assert.Equal(ConfigurationUnitResultSource.Internal, result.ResultInformation.ResultSource);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Getting unit details retrieves a value.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetUnitDetailsSuccess()\r\n        {\r\n            ConfigurationUnit configurationUnit = this.ConfigurationUnit();\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            Assert.Null(configurationUnit.Details);\r\n            processor.GetUnitDetails(configurationUnit, ConfigurationUnitDetailFlags.Local);\r\n            Assert.NotNull(configurationUnit.Details);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Getting set details throws an error.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetSetDetailsError()\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            ConfigurationUnit configurationUnitWorks = this.ConfigurationUnit();\r\n            ConfigurationUnit configurationUnitThrows = this.ConfigurationUnit();\r\n            configurationSet.Units = new ConfigurationUnit[] { configurationUnitWorks, configurationUnitThrows };\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet);\r\n            var thrownException = new InvalidDataException();\r\n            setProcessor.Exceptions.Add(configurationUnitThrows, thrownException);\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            GetConfigurationSetDetailsResult result = processor.GetSetDetails(configurationSet, ConfigurationUnitDetailFlags.Local);\r\n            var unitResults = result.UnitResults;\r\n            Assert.Equal(2, unitResults.Count);\r\n\r\n            Assert.Equal(configurationUnitWorks, unitResults[0].Unit);\r\n            Assert.Null(unitResults[0].ResultInformation.ResultCode);\r\n            Assert.NotNull(configurationUnitWorks.Details);\r\n\r\n            Assert.Equal(configurationUnitThrows, unitResults[1].Unit);\r\n            Assert.NotNull(unitResults[1].ResultInformation.ResultCode);\r\n            Assert.Equal(thrownException.HResult, unitResults[1].ResultInformation.ResultCode.HResult);\r\n            Assert.Null(configurationUnitThrows.Details);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Getting set details retrieves all values.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetSetDetailsSuccess()\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            ConfigurationUnit configurationUnit1 = this.ConfigurationUnit();\r\n            ConfigurationUnit configurationUnit2 = this.ConfigurationUnit();\r\n            configurationSet.Units = new ConfigurationUnit[] { configurationUnit1, configurationUnit2 };\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            processor.GetSetDetails(configurationSet, ConfigurationUnitDetailFlags.Local);\r\n            Assert.NotNull(configurationUnit1.Details);\r\n            Assert.NotNull(configurationUnit2.Details);\r\n        }\r\n\r\n        /// <summary>\r\n        /// The unit settings processor returns an error HRESULT.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetSettings_ProcessorSettingsError()\r\n        {\r\n            ConfigurationUnit configurationUnit = this.ConfigurationUnit();\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            factory.NullProcessor = new TestConfigurationSetProcessor(null);\r\n            TestConfigurationUnitProcessor unitProcessor = factory.NullProcessor.CreateTestProcessor(configurationUnit);\r\n            unitProcessor.GetSettingsDelegate = () => throw new FileNotFoundException();\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            GetConfigurationUnitSettingsResult result = processor.GetUnitSettings(configurationUnit);\r\n\r\n            Assert.NotNull(result);\r\n            Assert.NotNull(result.Settings);\r\n            Assert.NotNull(result.ResultInformation);\r\n            Assert.NotNull(result.ResultInformation.ResultCode);\r\n            Assert.IsType<FileNotFoundException>(result.ResultInformation.ResultCode);\r\n        }\r\n\r\n        /// <summary>\r\n        /// The unit settings processor returns an error in it's result.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetSettings_ProcessorSettingsFailedResult()\r\n        {\r\n            ConfigurationUnit configurationUnit = this.ConfigurationUnit();\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            factory.NullProcessor = new TestConfigurationSetProcessor(null);\r\n            TestConfigurationUnitProcessor unitProcessor = factory.NullProcessor.CreateTestProcessor(configurationUnit);\r\n            GetSettingsResultInstance getSettingsResult = new GetSettingsResultInstance(configurationUnit);\r\n            getSettingsResult.InternalResult.ResultCode = new InvalidDataException();\r\n            getSettingsResult.InternalResult.Description = \"We fail because we must\";\r\n            unitProcessor.GetSettingsDelegate = () => getSettingsResult;\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            GetConfigurationUnitSettingsResult result = processor.GetUnitSettings(configurationUnit);\r\n\r\n            Assert.NotNull(result);\r\n            Assert.Null(result.Settings);\r\n            Assert.NotNull(result.ResultInformation);\r\n            Assert.Equal(getSettingsResult.ResultInformation.ResultCode.HResult, result.ResultInformation.ResultCode.HResult);\r\n            Assert.Equal(getSettingsResult.ResultInformation.Description, result.ResultInformation.Description);\r\n        }\r\n\r\n        /// <summary>\r\n        /// The unit settings processor returns good settings.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetSettings_ProcessorSettingsSuccess()\r\n        {\r\n            ConfigurationUnit configurationUnit = this.ConfigurationUnit();\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            factory.NullProcessor = new TestConfigurationSetProcessor(null);\r\n            TestConfigurationUnitProcessor unitProcessor = factory.NullProcessor.CreateTestProcessor(configurationUnit);\r\n            GetSettingsResultInstance getSettingsResult = new GetSettingsResultInstance(configurationUnit);\r\n            getSettingsResult.Settings = new Windows.Foundation.Collections.ValueSet();\r\n            getSettingsResult.Settings.Add(\"key\", \"value\");\r\n            unitProcessor.GetSettingsDelegate = () => getSettingsResult;\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            GetConfigurationUnitSettingsResult result = processor.GetUnitSettings(configurationUnit);\r\n\r\n            Assert.NotNull(result);\r\n            Assert.NotNull(result.ResultInformation);\r\n            Assert.Null(result.ResultInformation.ResultCode);\r\n            Assert.Empty(result.ResultInformation.Description);\r\n            Assert.NotNull(result.Settings);\r\n            Assert.NotEmpty(result.Settings);\r\n            Assert.Contains(\"key\", result.Settings);\r\n            Assert.IsType<string>(result.Settings[\"key\"]);\r\n            Assert.Equal(\"value\", (string)result.Settings[\"key\"]);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorGroupTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationProcessorGroupTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.Linq;\r\n    using System.Threading;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n\r\n    /// <summary>\r\n    /// Unit tests for running group processing.\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [InProc]\r\n    public class ConfigurationProcessorGroupTests : ConfigurationProcessorTestBase\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ConfigurationProcessorGroupTests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Unit test fixture.</param>\r\n        /// <param name=\"log\">Log helper.</param>\r\n        public ConfigurationProcessorGroupTests(UnitTestFixture fixture, ITestOutputHelper log)\r\n            : base(fixture, log)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test a set that was parsed with schema 0.3.\r\n        /// </summary>\r\n        [Fact]\r\n        public void TestSet_Parsed_0_3()\r\n        {\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            OpenConfigurationSetResult openResult = processor.OpenConfigurationSet(this.CreateStream(@\"\r\n$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json\r\nresources:\r\n  - name: Name\r\n    type: Module/Resource\r\n    properties:\r\n      c: 3\r\n      d: '4'\r\n  - name: Name2\r\n    type: Module/Resource2\r\n    properties:\r\n      l: '10'\r\n\"));\r\n\r\n            Assert.Null(openResult.ResultCode);\r\n            Assert.NotNull(openResult.Set);\r\n            Assert.Equal(string.Empty, openResult.Field);\r\n            Assert.Equal(string.Empty, openResult.Value);\r\n            Assert.Equal(0U, openResult.Line);\r\n            Assert.Equal(0U, openResult.Column);\r\n\r\n            ConfigurationSet configurationSet = openResult.Set;\r\n            int unitCount = configurationSet.Units.Count;\r\n\r\n            TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet);\r\n\r\n            TestConfigurationUnitProcessor[] unitProcessors = new TestConfigurationUnitProcessor[unitCount];\r\n            for (int i = 0; i < unitCount; ++i)\r\n            {\r\n                unitProcessors[i] = setProcessor.CreateTestProcessor(configurationSet.Units[i]);\r\n                if (i == 0)\r\n                {\r\n                    unitProcessors[i].TestSettingsDelegateWithUnit = (ConfigurationUnit unit) => new TestSettingsResultInstance(unit) { TestResult = ConfigurationTestResult.Negative };\r\n                }\r\n                else\r\n                {\r\n                    unitProcessors[i].TestSettingsDelegateWithUnit = (ConfigurationUnit unit) => new TestSettingsResultInstance(unit) { TestResult = ConfigurationTestResult.Positive };\r\n                }\r\n            }\r\n\r\n            TestConfigurationSetResult result = processor.TestSet(configurationSet);\r\n            Assert.NotNull(result);\r\n            Assert.Equal(ConfigurationTestResult.Negative, result.TestResult);\r\n            Assert.Equal(unitCount, result.UnitResults.Count);\r\n\r\n            for (int i = 0; i < unitCount; ++i)\r\n            {\r\n                var unitResult = result.UnitResults[i];\r\n                Assert.NotNull(unitResult);\r\n\r\n                if (i == 0)\r\n                {\r\n                    Assert.Equal(ConfigurationTestResult.Negative, unitResult.TestResult);\r\n                }\r\n                else\r\n                {\r\n                    Assert.Equal(ConfigurationTestResult.Positive, unitResult.TestResult);\r\n                }\r\n\r\n                Assert.NotNull(unitResult.ResultInformation);\r\n                Assert.Null(unitResult.ResultInformation.ResultCode);\r\n                Assert.Equal(ConfigurationUnitResultSource.None, unitResult.ResultInformation.ResultSource);\r\n            }\r\n\r\n            this.VerifySummaryEvent(configurationSet, result, 0, ConfigurationUnitResultSource.None);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test when the set processor is a group processor.\r\n        /// </summary>\r\n        [Fact]\r\n        public void TestSet_SetGroupProcessor()\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            configurationSet.Metadata[TestConfigurationUnitGroupProcessor.TestResultSetting] = ConfigurationTestResult.Negative.ToString();\r\n            ConfigurationUnit configurationUnitNegative = this.ConfigurationUnit();\r\n            configurationUnitNegative.Settings[TestConfigurationUnitGroupProcessor.TestResultSetting] = ConfigurationTestResult.Negative.ToString();\r\n            ConfigurationUnit configurationUnitPositive = this.ConfigurationUnit();\r\n            configurationUnitPositive.Settings[TestConfigurationUnitGroupProcessor.TestResultSetting] = ConfigurationTestResult.Positive.ToString();\r\n            configurationSet.Units = new ConfigurationUnit[] { configurationUnitNegative, configurationUnitPositive };\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            TestConfigurationSetGroupProcessor setProcessor = factory.CreateTestGroupProcessor(configurationSet);\r\n            setProcessor.ShouldWaitOnAsyncEvent = true;\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n            List<TestConfigurationUnitResult> progressValues = new List<TestConfigurationUnitResult>();\r\n\r\n            var operation = processor.TestSetAsync(configurationSet);\r\n            operation.Progress = (Windows.Foundation.IAsyncOperationWithProgress<TestConfigurationSetResult, TestConfigurationUnitResult> op, TestConfigurationUnitResult unitResult) => { progressValues.Add(unitResult); };\r\n            setProcessor.SignalAsyncEvent();\r\n\r\n            operation.AsTask().Wait();\r\n            TestConfigurationSetResult result = operation.GetResults();\r\n\r\n            Assert.NotNull(result);\r\n            Assert.Equal(ConfigurationTestResult.Negative, result.TestResult);\r\n            Assert.NotNull(result.UnitResults);\r\n            Assert.Equal(2, result.UnitResults.Count);\r\n            Assert.Equal(2, progressValues.Count);\r\n\r\n            TestConfigurationUnitResult negativeResult = result.UnitResults.First(x => x.Unit == configurationUnitNegative);\r\n            TestConfigurationUnitResult negativeProgress = progressValues.First(x => x.Unit == configurationUnitNegative);\r\n\r\n            foreach (TestConfigurationUnitResult unitResult in new TestConfigurationUnitResult[] { negativeResult, negativeProgress })\r\n            {\r\n                Assert.NotNull(unitResult);\r\n                Assert.Equal(ConfigurationTestResult.Negative, unitResult.TestResult);\r\n                Assert.NotNull(unitResult.ResultInformation);\r\n                Assert.Null(unitResult.ResultInformation.ResultCode);\r\n                Assert.Equal(ConfigurationUnitResultSource.None, unitResult.ResultInformation.ResultSource);\r\n            }\r\n\r\n            TestConfigurationUnitResult positiveResult = result.UnitResults.First(x => x.Unit == configurationUnitPositive);\r\n            TestConfigurationUnitResult positiveProgress = progressValues.First(x => x.Unit == configurationUnitPositive);\r\n\r\n            foreach (TestConfigurationUnitResult unitResult in new TestConfigurationUnitResult[] { positiveResult, positiveProgress })\r\n            {\r\n                Assert.NotNull(unitResult);\r\n                Assert.Equal(ConfigurationTestResult.Positive, unitResult.TestResult);\r\n                Assert.NotNull(unitResult.ResultInformation);\r\n                Assert.Null(unitResult.ResultInformation.ResultCode);\r\n                Assert.Equal(ConfigurationUnitResultSource.None, unitResult.ResultInformation.ResultSource);\r\n            }\r\n\r\n            this.VerifySummaryEvent(configurationSet, result, 0, ConfigurationUnitResultSource.None);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test when the set processor is a group processor and contains a unit that is also a group.\r\n        /// </summary>\r\n        [Fact]\r\n        public void TestSet_SetGroupProcessor_WithGroupUnit()\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            configurationSet.Metadata[TestConfigurationUnitGroupProcessor.TestResultSetting] = ConfigurationTestResult.Negative.ToString();\r\n\r\n            ConfigurationUnit configurationUnit = this.ConfigurationUnit();\r\n            ConfigurationUnit configurationUnitGroup = this.ConfigurationUnit();\r\n\r\n            configurationSet.Units = new ConfigurationUnit[] { configurationUnit, configurationUnitGroup };\r\n\r\n            ConfigurationUnit configurationUnitGroupMember = this.ConfigurationUnit();\r\n            configurationUnitGroup.IsGroup = true;\r\n            configurationUnitGroup.Units = new ConfigurationUnit[] { configurationUnitGroupMember };\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            TestConfigurationSetGroupProcessor setProcessor = factory.CreateTestGroupProcessor(configurationSet);\r\n            setProcessor.ShouldWaitOnAsyncEvent = true;\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n            List<TestConfigurationUnitResult> progressValues = new List<TestConfigurationUnitResult>();\r\n\r\n            var operation = processor.TestSetAsync(configurationSet);\r\n            operation.Progress = (Windows.Foundation.IAsyncOperationWithProgress<TestConfigurationSetResult, TestConfigurationUnitResult> op, TestConfigurationUnitResult unitResult) => { progressValues.Add(unitResult); };\r\n            setProcessor.SignalAsyncEvent();\r\n\r\n            operation.AsTask().Wait();\r\n            TestConfigurationSetResult result = operation.GetResults();\r\n\r\n            Assert.NotNull(result);\r\n            Assert.Equal(ConfigurationTestResult.Positive, result.TestResult);\r\n            Assert.NotNull(result.UnitResults);\r\n            Assert.Equal(3, result.UnitResults.Count);\r\n            Assert.Equal(3, progressValues.Count);\r\n\r\n            foreach (ConfigurationUnit unit in new ConfigurationUnit[] { configurationUnit, configurationUnitGroup, configurationUnitGroupMember })\r\n            {\r\n                foreach (IReadOnlyList<TestConfigurationUnitResult> unitResults in new IReadOnlyList<TestConfigurationUnitResult>[] { result.UnitResults, progressValues })\r\n                {\r\n                    TestConfigurationUnitResult unitResult = unitResults.First(x => x.Unit == unit);\r\n\r\n                    Assert.NotNull(unitResult);\r\n                    Assert.Equal(ConfigurationTestResult.Positive, unitResult.TestResult);\r\n                    Assert.NotNull(unitResult.ResultInformation);\r\n                    Assert.Null(unitResult.ResultInformation.ResultCode);\r\n                    Assert.Equal(ConfigurationUnitResultSource.None, unitResult.ResultInformation.ResultSource);\r\n                }\r\n            }\r\n\r\n            this.VerifySummaryEvent(configurationSet, result, 0, ConfigurationUnitResultSource.None);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test when the standard set processor is used and there is a group unit.\r\n        /// </summary>\r\n        [Fact]\r\n        public void TestSet_UnitGroupProcessor_WithGroupUnit()\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            configurationSet.Metadata[TestConfigurationUnitGroupProcessor.TestResultSetting] = ConfigurationTestResult.Negative.ToString();\r\n\r\n            ConfigurationUnit configurationUnit = this.ConfigurationUnit();\r\n            ConfigurationUnit configurationUnitGroup = this.ConfigurationUnit();\r\n\r\n            configurationSet.Units = new ConfigurationUnit[] { configurationUnit, configurationUnitGroup };\r\n\r\n            ConfigurationUnit configurationUnitGroupMember = this.ConfigurationUnit();\r\n            configurationUnitGroup.IsGroup = true;\r\n            configurationUnitGroup.Units = new ConfigurationUnit[] { configurationUnitGroupMember };\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet);\r\n            setProcessor.CreateTestProcessor(configurationUnit);\r\n            setProcessor.CreateTestGroupProcessor(configurationUnitGroup);\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            TestConfigurationSetResult result = processor.TestSet(configurationSet);\r\n\r\n            Assert.NotNull(result);\r\n            Assert.Equal(ConfigurationTestResult.Positive, result.TestResult);\r\n            Assert.NotNull(result.UnitResults);\r\n            Assert.Equal(3, result.UnitResults.Count);\r\n\r\n            foreach (ConfigurationUnit unit in new ConfigurationUnit[] { configurationUnit, configurationUnitGroup, configurationUnitGroupMember })\r\n            {\r\n                TestConfigurationUnitResult unitResult = result.UnitResults.First(x => x.Unit == unit);\r\n\r\n                Assert.NotNull(unitResult);\r\n                Assert.Equal(ConfigurationTestResult.Positive, unitResult.TestResult);\r\n                Assert.NotNull(unitResult.ResultInformation);\r\n                Assert.Null(unitResult.ResultInformation.ResultCode);\r\n                Assert.Equal(ConfigurationUnitResultSource.None, unitResult.ResultInformation.ResultSource);\r\n            }\r\n\r\n            this.VerifySummaryEvent(configurationSet, result, 0, ConfigurationUnitResultSource.None);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test when the standard set processor is used and there is a non-group unit that still exposes a group processor.\r\n        /// </summary>\r\n        [Fact]\r\n        public void TestSet_UnitGroupProcessor_WithNonGroupUnit()\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            configurationSet.Metadata[TestConfigurationUnitGroupProcessor.TestResultSetting] = ConfigurationTestResult.Negative.ToString();\r\n\r\n            ConfigurationUnit configurationUnit = this.ConfigurationUnit();\r\n            ConfigurationUnit configurationUnitGroup = this.ConfigurationUnit();\r\n\r\n            configurationSet.Units = new ConfigurationUnit[] { configurationUnit, configurationUnitGroup };\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet);\r\n            setProcessor.CreateTestProcessor(configurationUnit);\r\n            setProcessor.CreateTestGroupProcessor(configurationUnitGroup);\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            TestConfigurationSetResult result = processor.TestSet(configurationSet);\r\n\r\n            Assert.NotNull(result);\r\n            Assert.Equal(ConfigurationTestResult.Positive, result.TestResult);\r\n            Assert.NotNull(result.UnitResults);\r\n            Assert.Equal(2, result.UnitResults.Count);\r\n\r\n            foreach (ConfigurationUnit unit in new ConfigurationUnit[] { configurationUnit, configurationUnitGroup })\r\n            {\r\n                TestConfigurationUnitResult unitResult = result.UnitResults.First(x => x.Unit == unit);\r\n\r\n                Assert.NotNull(unitResult);\r\n                Assert.Equal(ConfigurationTestResult.Positive, unitResult.TestResult);\r\n                Assert.NotNull(unitResult.ResultInformation);\r\n                Assert.Null(unitResult.ResultInformation.ResultCode);\r\n                Assert.Equal(ConfigurationUnitResultSource.None, unitResult.ResultInformation.ResultSource);\r\n            }\r\n\r\n            this.VerifySummaryEvent(configurationSet, result, 0, ConfigurationUnitResultSource.None);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Apply a set that was parsed with schema 0.3.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ApplySet_Parsed_0_3()\r\n        {\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            OpenConfigurationSetResult openResult = processor.OpenConfigurationSet(this.CreateStream(@\"\r\n$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json\r\nresources:\r\n  - name: Name\r\n    type: Module/Resource\r\n    properties:\r\n      c: 3\r\n      d: '4'\r\n  - name: Name2\r\n    type: Module/Resource2\r\n    properties:\r\n      l: '10'\r\n\"));\r\n\r\n            Assert.Null(openResult.ResultCode);\r\n            Assert.NotNull(openResult.Set);\r\n            Assert.Equal(string.Empty, openResult.Field);\r\n            Assert.Equal(string.Empty, openResult.Value);\r\n            Assert.Equal(0U, openResult.Line);\r\n            Assert.Equal(0U, openResult.Column);\r\n\r\n            ConfigurationSet configurationSet = openResult.Set;\r\n            int unitCount = configurationSet.Units.Count;\r\n\r\n            TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet);\r\n\r\n            TestConfigurationUnitProcessor[] unitProcessors = new TestConfigurationUnitProcessor[unitCount];\r\n            for (int i = 0; i < unitCount; ++i)\r\n            {\r\n                unitProcessors[i] = setProcessor.CreateTestProcessor(configurationSet.Units[i]);\r\n                if (i == 0)\r\n                {\r\n                    unitProcessors[i].TestSettingsDelegateWithUnit = (ConfigurationUnit unit) => new TestSettingsResultInstance(unit) { TestResult = ConfigurationTestResult.Negative };\r\n                }\r\n                else\r\n                {\r\n                    unitProcessors[i].TestSettingsDelegateWithUnit = (ConfigurationUnit unit) => new TestSettingsResultInstance(unit) { TestResult = ConfigurationTestResult.Positive };\r\n                }\r\n            }\r\n\r\n            ApplyConfigurationSetResult result = processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None);\r\n            Assert.NotNull(result);\r\n            Assert.Null(result.ResultCode);\r\n            Assert.Equal(unitCount, result.UnitResults.Count);\r\n\r\n            for (int i = 0; i < unitCount; ++i)\r\n            {\r\n                var unitResult = result.UnitResults[i];\r\n                Assert.NotNull(unitResult);\r\n\r\n                if (i == 0)\r\n                {\r\n                    Assert.False(unitResult.PreviouslyInDesiredState);\r\n                }\r\n                else\r\n                {\r\n                    Assert.True(unitResult.PreviouslyInDesiredState);\r\n                }\r\n\r\n                Assert.False(unitResult.RebootRequired);\r\n                Assert.NotNull(unitResult.ResultInformation);\r\n                Assert.Null(unitResult.ResultInformation.ResultCode);\r\n                Assert.Equal(ConfigurationUnitResultSource.None, unitResult.ResultInformation.ResultSource);\r\n            }\r\n\r\n            for (int i = 0; i < unitCount; ++i)\r\n            {\r\n                Assert.Equal(1, unitProcessors[i].TestSettingsCalls);\r\n                Assert.Equal(0, unitProcessors[i].GetSettingsCalls);\r\n                if (i == 0)\r\n                {\r\n                    Assert.Equal(1, unitProcessors[i].ApplySettingsCalls);\r\n                }\r\n                else\r\n                {\r\n                    Assert.Equal(0, unitProcessors[i].ApplySettingsCalls);\r\n                }\r\n            }\r\n\r\n            this.VerifySummaryEvent(configurationSet, result, ConfigurationUnitResultSource.None);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test when the set processor is a group processor.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ApplySet_SetGroupProcessor()\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n\r\n            ConfigurationUnit configurationUnitNegative = this.ConfigurationUnit();\r\n            configurationUnitNegative.Settings[TestConfigurationUnitGroupProcessor.TestResultSetting] = ConfigurationTestResult.Negative.ToString();\r\n            ConfigurationUnit configurationUnitPositive = this.ConfigurationUnit();\r\n            configurationUnitPositive.Settings[TestConfigurationUnitGroupProcessor.TestResultSetting] = ConfigurationTestResult.Positive.ToString();\r\n            configurationSet.Units = new ConfigurationUnit[] { configurationUnitNegative, configurationUnitPositive };\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n            ManualResetEvent startProcessing = new ManualResetEvent(false);\r\n            factory.CreateSetProcessorDelegate = (f, c) =>\r\n            {\r\n                startProcessing.WaitOne();\r\n                return f.CreateTestGroupProcessor(c);\r\n            };\r\n\r\n            var operation = processor.ApplySetAsync(configurationSet, ApplyConfigurationSetFlags.None);\r\n\r\n            List<ConfigurationSetChangeData> progressValues = new List<ConfigurationSetChangeData>();\r\n            operation.Progress = (Windows.Foundation.IAsyncOperationWithProgress<ApplyConfigurationSetResult, ConfigurationSetChangeData> op, ConfigurationSetChangeData unitResult) => { progressValues.Add(unitResult); };\r\n            startProcessing.Set();\r\n            operation.AsTask().Wait();\r\n            ApplyConfigurationSetResult result = operation.GetResults();\r\n\r\n            Assert.NotNull(result);\r\n            Assert.Null(result.ResultCode);\r\n            Assert.NotNull(result.UnitResults);\r\n            Assert.Equal(configurationSet.Units.Count, result.UnitResults.Count);\r\n            Assert.Equal((configurationSet.Units.Count * 2) + 2, progressValues.Count);\r\n\r\n            ApplyConfigurationUnitResult negativeResult = result.UnitResults.First(x => x.Unit == configurationUnitNegative);\r\n\r\n            Assert.NotNull(negativeResult);\r\n            Assert.NotNull(negativeResult.ResultInformation);\r\n            Assert.Null(negativeResult.ResultInformation.ResultCode);\r\n            Assert.Equal(ConfigurationUnitResultSource.None, negativeResult.ResultInformation.ResultSource);\r\n            Assert.Equal(ConfigurationUnitState.Completed, negativeResult.State);\r\n            Assert.False(negativeResult.PreviouslyInDesiredState);\r\n\r\n            IEnumerable<ConfigurationSetChangeData> negativeProgress = progressValues.Where(x => x.Unit == configurationUnitNegative);\r\n            Assert.Equal(2, negativeProgress.Count());\r\n\r\n            foreach (ConfigurationSetChangeData change in negativeProgress)\r\n            {\r\n                Assert.Equal(ConfigurationSetChangeEventType.UnitStateChanged, change.Change);\r\n                Assert.Equal(ConfigurationSetState.InProgress, change.SetState);\r\n                Assert.NotNull(change.ResultInformation);\r\n                Assert.Null(change.ResultInformation.ResultCode);\r\n                Assert.Equal(ConfigurationUnitResultSource.None, change.ResultInformation.ResultSource);\r\n            }\r\n\r\n            Assert.Single(negativeProgress.Where(x => x.UnitState == ConfigurationUnitState.InProgress));\r\n            Assert.Single(negativeProgress.Where(x => x.UnitState == ConfigurationUnitState.Completed));\r\n\r\n            ApplyConfigurationUnitResult positiveResult = result.UnitResults.First(x => x.Unit == configurationUnitPositive);\r\n\r\n            Assert.NotNull(positiveResult);\r\n            Assert.NotNull(positiveResult.ResultInformation);\r\n            Assert.Null(positiveResult.ResultInformation.ResultCode);\r\n            Assert.Equal(ConfigurationUnitResultSource.None, positiveResult.ResultInformation.ResultSource);\r\n            Assert.Equal(ConfigurationUnitState.Completed, positiveResult.State);\r\n            Assert.True(positiveResult.PreviouslyInDesiredState);\r\n\r\n            IEnumerable<ConfigurationSetChangeData> positiveProgress = progressValues.Where(x => x.Unit == configurationUnitPositive);\r\n            Assert.Equal(2, positiveProgress.Count());\r\n\r\n            foreach (ConfigurationSetChangeData change in positiveProgress)\r\n            {\r\n                Assert.Equal(ConfigurationSetChangeEventType.UnitStateChanged, change.Change);\r\n                Assert.Equal(ConfigurationSetState.InProgress, change.SetState);\r\n                Assert.NotNull(change.ResultInformation);\r\n                Assert.Null(change.ResultInformation.ResultCode);\r\n                Assert.Equal(ConfigurationUnitResultSource.None, change.ResultInformation.ResultSource);\r\n            }\r\n\r\n            Assert.Single(positiveProgress.Where(x => x.UnitState == ConfigurationUnitState.InProgress));\r\n            Assert.Single(positiveProgress.Where(x => x.UnitState == ConfigurationUnitState.Completed));\r\n\r\n            this.VerifySummaryEvent(configurationSet, result, ConfigurationUnitResultSource.None);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test when the set processor is a group processor and contains a unit that is also a group.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ApplySet_SetGroupProcessor_WithGroupUnit()\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            configurationSet.Metadata[TestConfigurationUnitGroupProcessor.TestResultSetting] = ConfigurationTestResult.Negative.ToString();\r\n\r\n            ConfigurationUnit configurationUnit = this.ConfigurationUnit();\r\n            ConfigurationUnit configurationUnitGroup = this.ConfigurationUnit();\r\n\r\n            configurationSet.Units = new ConfigurationUnit[] { configurationUnit, configurationUnitGroup };\r\n\r\n            ConfigurationUnit configurationUnitGroupMember = this.ConfigurationUnit();\r\n            configurationUnitGroup.IsGroup = true;\r\n            configurationUnitGroup.Units = new ConfigurationUnit[] { configurationUnitGroupMember };\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n            ManualResetEvent startProcessing = new ManualResetEvent(false);\r\n            factory.CreateSetProcessorDelegate = (f, c) =>\r\n            {\r\n                startProcessing.WaitOne();\r\n                return f.CreateTestGroupProcessor(c);\r\n            };\r\n\r\n            var operation = processor.ApplySetAsync(configurationSet, ApplyConfigurationSetFlags.None);\r\n\r\n            List<ConfigurationSetChangeData> progressValues = new List<ConfigurationSetChangeData>();\r\n            operation.Progress = (Windows.Foundation.IAsyncOperationWithProgress<ApplyConfigurationSetResult, ConfigurationSetChangeData> op, ConfigurationSetChangeData unitResult) => { progressValues.Add(unitResult); };\r\n            startProcessing.Set();\r\n            operation.AsTask().Wait();\r\n            ApplyConfigurationSetResult result = operation.GetResults();\r\n\r\n            Assert.NotNull(result);\r\n            Assert.Null(result.ResultCode);\r\n            Assert.NotNull(result.UnitResults);\r\n            Assert.Equal(3, result.UnitResults.Count);\r\n            Assert.Equal(2 + (3 * 2), progressValues.Count);\r\n\r\n            foreach (ConfigurationUnit unit in new ConfigurationUnit[] { configurationUnit, configurationUnitGroup, configurationUnitGroupMember })\r\n            {\r\n                ApplyConfigurationUnitResult unitResult = result.UnitResults.First(x => x.Unit == unit);\r\n\r\n                Assert.NotNull(unitResult);\r\n                Assert.NotNull(unitResult.ResultInformation);\r\n                Assert.Null(unitResult.ResultInformation.ResultCode);\r\n                Assert.Equal(ConfigurationUnitResultSource.None, unitResult.ResultInformation.ResultSource);\r\n                Assert.Equal(ConfigurationUnitState.Completed, unitResult.State);\r\n                Assert.True(unitResult.PreviouslyInDesiredState);\r\n\r\n                IEnumerable<ConfigurationSetChangeData> unitProgress = progressValues.Where(x => x.Unit == unit);\r\n                Assert.Equal(2, unitProgress.Count());\r\n\r\n                foreach (ConfigurationSetChangeData change in unitProgress)\r\n                {\r\n                    Assert.Equal(ConfigurationSetChangeEventType.UnitStateChanged, change.Change);\r\n                    Assert.Equal(ConfigurationSetState.InProgress, change.SetState);\r\n                    Assert.NotNull(change.ResultInformation);\r\n                    Assert.Null(change.ResultInformation.ResultCode);\r\n                    Assert.Equal(ConfigurationUnitResultSource.None, change.ResultInformation.ResultSource);\r\n                }\r\n\r\n                Assert.True(unitProgress.Where(x => x.UnitState == ConfigurationUnitState.InProgress).Count() <= 1);\r\n                Assert.True(unitProgress.Where(x => x.UnitState == ConfigurationUnitState.Completed).Count() <= 1);\r\n            }\r\n\r\n            this.VerifySummaryEvent(configurationSet, result, ConfigurationUnitResultSource.None);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test when the standard set processor is used and there is a group unit.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ApplySet_UnitGroupProcessor_WithGroupUnit()\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            configurationSet.Metadata[TestConfigurationUnitGroupProcessor.TestResultSetting] = ConfigurationTestResult.Negative.ToString();\r\n\r\n            ConfigurationUnit configurationUnit = this.ConfigurationUnit();\r\n            ConfigurationUnit configurationUnitGroup = this.ConfigurationUnit();\r\n\r\n            configurationSet.Units = new ConfigurationUnit[] { configurationUnit, configurationUnitGroup };\r\n\r\n            ConfigurationUnit configurationUnitGroupMember = this.ConfigurationUnit();\r\n            configurationUnitGroup.IsGroup = true;\r\n            configurationUnitGroup.Units = new ConfigurationUnit[] { configurationUnitGroupMember };\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet);\r\n            setProcessor.CreateTestProcessor(configurationUnit);\r\n            setProcessor.CreateTestGroupProcessor(configurationUnitGroup);\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            ApplyConfigurationSetResult result = processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None);\r\n\r\n            Assert.NotNull(result);\r\n            Assert.Null(result.ResultCode);\r\n            Assert.NotNull(result.UnitResults);\r\n            Assert.Equal(3, result.UnitResults.Count);\r\n\r\n            foreach (ConfigurationUnit unit in new ConfigurationUnit[] { configurationUnit, configurationUnitGroup, configurationUnitGroupMember })\r\n            {\r\n                ApplyConfigurationUnitResult unitResult = result.UnitResults.First(x => x.Unit == unit);\r\n\r\n                Assert.NotNull(unitResult);\r\n                Assert.NotNull(unitResult.ResultInformation);\r\n                Assert.Null(unitResult.ResultInformation.ResultCode);\r\n                Assert.Equal(ConfigurationUnitResultSource.None, unitResult.ResultInformation.ResultSource);\r\n                Assert.Equal(ConfigurationUnitState.Completed, unitResult.State);\r\n                Assert.True(unitResult.PreviouslyInDesiredState);\r\n            }\r\n\r\n            this.VerifySummaryEvent(configurationSet, result, ConfigurationUnitResultSource.None);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test when the standard set processor is used and there is a non-group unit that still exposes a group processor.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ApplySet_UnitGroupProcessor_WithNonGroupUnit()\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            configurationSet.Metadata[TestConfigurationUnitGroupProcessor.TestResultSetting] = ConfigurationTestResult.Negative.ToString();\r\n\r\n            ConfigurationUnit configurationUnit = this.ConfigurationUnit();\r\n            ConfigurationUnit configurationUnitGroup = this.ConfigurationUnit();\r\n\r\n            configurationSet.Units = new ConfigurationUnit[] { configurationUnit, configurationUnitGroup };\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet);\r\n            setProcessor.CreateTestProcessor(configurationUnit);\r\n            setProcessor.CreateTestGroupProcessor(configurationUnitGroup);\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            ApplyConfigurationSetResult result = processor.ApplySet(configurationSet, ApplyConfigurationSetFlags.None);\r\n\r\n            Assert.NotNull(result);\r\n            Assert.Null(result.ResultCode);\r\n            Assert.NotNull(result.UnitResults);\r\n            Assert.Equal(2, result.UnitResults.Count);\r\n\r\n            foreach (ConfigurationUnit unit in new ConfigurationUnit[] { configurationUnit, configurationUnitGroup })\r\n            {\r\n                ApplyConfigurationUnitResult unitResult = result.UnitResults.First(x => x.Unit == unit);\r\n\r\n                Assert.NotNull(unitResult);\r\n                Assert.NotNull(unitResult.ResultInformation);\r\n                Assert.Null(unitResult.ResultInformation.ResultCode);\r\n                Assert.Equal(ConfigurationUnitResultSource.None, unitResult.ResultInformation.ResultSource);\r\n                Assert.Equal(ConfigurationUnitState.Completed, unitResult.State);\r\n                Assert.True(unitResult.PreviouslyInDesiredState);\r\n            }\r\n\r\n            this.VerifySummaryEvent(configurationSet, result, ConfigurationUnitResultSource.None);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorTelemetryTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationProcessorTelemetryTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System;\r\n    using System.Collections;\r\n    using System.Collections.Generic;\r\n    using System.IO;\r\n    using System.Linq;\r\n    using System.Runtime.InteropServices;\r\n    using System.Threading;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using Microsoft.VisualBasic;\r\n    using Microsoft.VisualStudio.TestPlatform.ObjectModel;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n    using static System.Collections.Specialized.BitVector32;\r\n\r\n    /// <summary>\r\n    /// Unit tests for running test on the processor.\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [InProc]\r\n    public class ConfigurationProcessorTelemetryTests : ConfigurationProcessorTestBase\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ConfigurationProcessorTelemetryTests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Unit test fixture.</param>\r\n        /// <param name=\"log\">Log helper.</param>\r\n        public ConfigurationProcessorTelemetryTests(UnitTestFixture fixture, ITestOutputHelper log)\r\n            : base(fixture, log)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// No event is generated if the unit succeeds.\r\n        /// </summary>\r\n        [Fact]\r\n        public void Telemetry_NoUnitEventOnSuccess()\r\n        {\r\n            TelemetryTestObjects testObjects = new TelemetryTestObjects(getFails: false);\r\n            testObjects.Processor = this.CreateConfigurationProcessorWithDiagnostics(testObjects.Factory);\r\n            testObjects.CreateDetails();\r\n\r\n            GetConfigurationUnitSettingsResult result = testObjects.Processor.GetUnitSettings(testObjects.Unit);\r\n\r\n            Assert.Single(this.EventSink.Events);\r\n            Assert.Equal(TelemetryEvent.ConfigUnitRunName, this.EventSink.Events[0].Name);\r\n        }\r\n\r\n        /// <summary>\r\n        /// No event is generated if the details have not been retrieved.\r\n        /// </summary>\r\n        [Fact]\r\n        public void Telemetry_NoUnitEventIfNoDetails()\r\n        {\r\n            TelemetryTestObjects testObjects = new TelemetryTestObjects();\r\n            testObjects.Processor = this.CreateConfigurationProcessorWithDiagnostics(testObjects.Factory);\r\n\r\n            GetConfigurationUnitSettingsResult result = testObjects.Processor.GetUnitSettings(testObjects.Unit);\r\n\r\n            Assert.Empty(this.EventSink.Events);\r\n        }\r\n\r\n        /// <summary>\r\n        /// No event is generated if the module is not public.\r\n        /// </summary>\r\n        [Fact]\r\n        public void Telemetry_NoUnitEventIfNotPublic()\r\n        {\r\n            TelemetryTestObjects testObjects = new TelemetryTestObjects();\r\n            testObjects.Processor = this.CreateConfigurationProcessorWithDiagnostics(testObjects.Factory);\r\n            testObjects.CreateDetails(isPublic: false);\r\n\r\n            GetConfigurationUnitSettingsResult result = testObjects.Processor.GetUnitSettings(testObjects.Unit);\r\n\r\n            Assert.Empty(this.EventSink.Events);\r\n        }\r\n\r\n        /// <summary>\r\n        /// The activity set by the caller is the value in the event.\r\n        /// </summary>\r\n        [Fact]\r\n        public void Telemetry_ActivityID()\r\n        {\r\n            TelemetryTestObjects testObjects = new TelemetryTestObjects();\r\n            testObjects.Processor = this.CreateConfigurationProcessorWithDiagnostics(testObjects.Factory);\r\n            testObjects.CreateDetails();\r\n\r\n            Guid activity = Guid.NewGuid();\r\n            testObjects.Processor.ActivityIdentifier = activity;\r\n\r\n            GetConfigurationUnitSettingsResult result = testObjects.Processor.GetUnitSettings(testObjects.Unit);\r\n\r\n            Assert.Single(this.EventSink.Events);\r\n            Assert.Equal(TelemetryEvent.ConfigUnitRunName, this.EventSink.Events[0].Name);\r\n            Assert.Equal(activity, this.EventSink.Events[0].ActivityID);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Disabling telemetry causes no event to be produced.\r\n        /// </summary>\r\n        /// <param name=\"state\">The state of telemetry.</param>\r\n        [Theory]\r\n        [InlineData(true)]\r\n        [InlineData(false)]\r\n        public void Telemetry_EnableState(bool state)\r\n        {\r\n            TelemetryTestObjects testObjects = new TelemetryTestObjects();\r\n            testObjects.Processor = this.CreateConfigurationProcessorWithDiagnostics(testObjects.Factory);\r\n            testObjects.CreateDetails();\r\n\r\n            testObjects.Processor.GenerateTelemetryEvents = state;\r\n\r\n            GetConfigurationUnitSettingsResult result = testObjects.Processor.GetUnitSettings(testObjects.Unit);\r\n\r\n            if (state)\r\n            {\r\n                Assert.Single(this.EventSink.Events);\r\n                Assert.Equal(TelemetryEvent.ConfigUnitRunName, this.EventSink.Events[0].Name);\r\n            }\r\n            else\r\n            {\r\n                Assert.Empty(this.EventSink.Events);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// The caller set by the caller is the value in the event.\r\n        /// </summary>\r\n        [Fact]\r\n        public void Telemetry_Caller()\r\n        {\r\n            TelemetryTestObjects testObjects = new TelemetryTestObjects();\r\n            testObjects.Processor = this.CreateConfigurationProcessorWithDiagnostics(testObjects.Factory);\r\n            testObjects.CreateDetails();\r\n\r\n            string caller = \"TheTests\";\r\n            testObjects.Processor.Caller = caller;\r\n\r\n            GetConfigurationUnitSettingsResult result = testObjects.Processor.GetUnitSettings(testObjects.Unit);\r\n\r\n            Assert.Single(this.EventSink.Events);\r\n            Assert.Equal(TelemetryEvent.ConfigUnitRunName, this.EventSink.Events[0].Name);\r\n            Assert.Equal(caller, this.EventSink.Events[0].Caller);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies all of the telemetry fields that come from executing a specific unit.\r\n        /// </summary>\r\n        [Fact]\r\n        public void Telemetry_UnitFields()\r\n        {\r\n#pragma warning disable CS8602 // Dereference of a possibly null reference.\r\n            TelemetryTestObjects testObjects = new TelemetryTestObjects();\r\n            testObjects.Processor = this.CreateConfigurationProcessorWithDiagnostics(testObjects.Factory);\r\n            testObjects.CreateDetails();\r\n\r\n            testObjects.Unit.Type = \"TestUnitName\";\r\n            testObjects.UnitDetails.ModuleName = \"TestModuleName\";\r\n\r\n            string setting1 = \"setting1\";\r\n            string setting2 = \"setting2\";\r\n\r\n            testObjects.Unit.Settings.Add(setting1, 0);\r\n            testObjects.Unit.Settings.Add(setting2, 0);\r\n\r\n            GetConfigurationUnitSettingsResult result = testObjects.Processor.GetUnitSettings(testObjects.Unit);\r\n\r\n            Assert.Single(this.EventSink.Events);\r\n            TelemetryEvent runEvent = this.EventSink.Events[0];\r\n            Assert.Equal(TelemetryEvent.ConfigUnitRunName, runEvent.Name);\r\n            Assert.NotEqual(string.Empty, runEvent.CodeVersion);\r\n            Assert.NotEqual(Guid.Empty, runEvent.ActivityID);\r\n            Assert.Equal(string.Empty, runEvent.Caller);\r\n            Assert.Equal(Guid.Empty, Guid.Parse(runEvent.Properties[TelemetryEvent.SetID]));\r\n            Assert.NotEqual(Guid.Empty, Guid.Parse(runEvent.Properties[TelemetryEvent.UnitID]));\r\n            Assert.Equal(testObjects.Unit.Type, runEvent.Properties[TelemetryEvent.UnitName]);\r\n            Assert.Equal(testObjects.UnitDetails.ModuleName, runEvent.Properties[TelemetryEvent.ModuleName]);\r\n            Assert.Equal(((int)testObjects.Unit.Intent).ToString(), runEvent.Properties[TelemetryEvent.UnitIntent]);\r\n            Assert.Equal(((int)ConfigurationUnitIntent.Inform).ToString(), runEvent.Properties[TelemetryEvent.RunIntent]);\r\n            Assert.NotEqual(string.Empty, runEvent.Properties[TelemetryEvent.Action]);\r\n            Assert.Equal(testObjects.GetResult.ResultInformation.ResultCode.HResult.ToString(), runEvent.Properties[TelemetryEvent.Result]);\r\n            Assert.Equal(((int)testObjects.GetResult.ResultInformation.ResultSource).ToString(), runEvent.Properties[TelemetryEvent.FailurePoint]);\r\n            Assert.Equal(setting1 + \"|\" + setting2, runEvent.Properties[TelemetryEvent.SettingsProvided]);\r\n#pragma warning restore CS8602 // Dereference of a possibly null reference.\r\n        }\r\n\r\n        private class TelemetryTestObjects\r\n        {\r\n            public TelemetryTestObjects(bool getFails = true)\r\n            {\r\n                this.Unit = new ConfigurationUnit { Intent = ConfigurationUnitIntent.Apply };\r\n\r\n                this.Factory = new TestConfigurationProcessorFactory();\r\n                this.Factory.NullProcessor = new TestConfigurationSetProcessor(null);\r\n\r\n                this.UnitProcessor = this.Factory.NullProcessor.CreateTestProcessor(this.Unit);\r\n\r\n                if (getFails)\r\n                {\r\n                    var getResult = new GetSettingsResultInstance(this.Unit);\r\n                    getResult.InternalResult.ResultCode = new NullReferenceException();\r\n                    getResult.InternalResult.ResultSource = ConfigurationUnitResultSource.UnitProcessing;\r\n                    this.GetResult = getResult;\r\n                    this.UnitProcessor.GetSettingsDelegate = () => this.GetResult;\r\n                }\r\n            }\r\n\r\n            public ConfigurationUnit Unit { get; set; }\r\n\r\n            public TestConfigurationProcessorFactory Factory { get; set; }\r\n\r\n            public TestConfigurationUnitProcessor UnitProcessor { get; set; }\r\n\r\n            public IGetSettingsResult? GetResult { get; set; }\r\n\r\n            public TestConfigurationUnitProcessorDetails? UnitDetails { get; set; }\r\n\r\n            public ConfigurationProcessor? Processor { get; set; }\r\n\r\n            public void CreateDetails(bool isPublic = true)\r\n            {\r\n#pragma warning disable CS8602 // Dereference of a possibly null reference.\r\n                this.UnitDetails = this.Factory.NullProcessor.CreateUnitDetails(this.Unit, ConfigurationUnitDetailFlags.ReadOnly);\r\n#pragma warning restore CS8602 // Dereference of a possibly null reference.\r\n                this.UnitDetails.IsPublic = isPublic;\r\n\r\n                this.Processor?.GetUnitDetails(this.Unit, ConfigurationUnitDetailFlags.ReadOnly);\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationProcessorTestTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationProcessorTestTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System;\r\n    using System.IO;\r\n    using System.Linq;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using Microsoft.VisualBasic;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n\r\n    /// <summary>\r\n    /// Unit tests for running test on the processor.\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [InProc]\r\n    [OutOfProc]\r\n    public class ConfigurationProcessorTestTests : ConfigurationProcessorTestBase\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ConfigurationProcessorTestTests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Unit test fixture.</param>\r\n        /// <param name=\"log\">Log helper.</param>\r\n        public ConfigurationProcessorTestTests(UnitTestFixture fixture, ITestOutputHelper log)\r\n            : base(fixture, log)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// An error creating the set processor results in an error for the function.\r\n        /// </summary>\r\n        [Fact]\r\n        public void TestSet_SetProcessorError()\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            factory.Exceptions.Add(configurationSet, new FileNotFoundException());\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            Assert.Throws<FileNotFoundException>(() => processor.TestSet(configurationSet));\r\n\r\n            Assert.Empty(this.EventSink.Events);\r\n        }\r\n\r\n        /// <summary>\r\n        /// An error creating a unit processor results in an error for that unit.\r\n        /// </summary>\r\n        [Fact]\r\n        public void TestSet_UnitProcessorCreationError()\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            ConfigurationUnit configurationUnitThrows = this.ConfigurationUnit();\r\n            ConfigurationUnit configurationUnitWorks = this.ConfigurationUnit();\r\n            configurationSet.Units = new ConfigurationUnit[] { configurationUnitThrows, configurationUnitWorks };\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet);\r\n            setProcessor.Exceptions.Add(configurationUnitThrows, new NullReferenceException());\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            TestConfigurationSetResult result = processor.TestSet(configurationSet);\r\n\r\n            Assert.NotNull(result);\r\n            Assert.Equal(ConfigurationTestResult.Failed, result.TestResult);\r\n            Assert.NotNull(result.UnitResults);\r\n            Assert.Equal(2, result.UnitResults.Count);\r\n\r\n            TestConfigurationUnitResult throwsResult = result.UnitResults.First(x => x.Unit == configurationUnitThrows);\r\n            Assert.NotNull(throwsResult);\r\n            Assert.Equal(ConfigurationTestResult.Failed, throwsResult.TestResult);\r\n            Assert.NotNull(throwsResult.ResultInformation);\r\n            Assert.NotNull(throwsResult.ResultInformation.ResultCode);\r\n            Assert.IsType<NullReferenceException>(throwsResult.ResultInformation.ResultCode);\r\n            Assert.Equal(ConfigurationUnitResultSource.Internal, throwsResult.ResultInformation.ResultSource);\r\n\r\n            TestConfigurationUnitResult worksResult = result.UnitResults.First(x => x.Unit == configurationUnitWorks);\r\n            Assert.NotNull(worksResult);\r\n            Assert.Equal(ConfigurationTestResult.Positive, worksResult.TestResult);\r\n            Assert.NotNull(worksResult.ResultInformation);\r\n            Assert.Null(worksResult.ResultInformation.ResultCode);\r\n            Assert.Equal(ConfigurationUnitResultSource.None, worksResult.ResultInformation.ResultSource);\r\n\r\n            this.VerifySummaryEvent(configurationSet, result, throwsResult.ResultInformation.ResultCode.HResult, ConfigurationUnitResultSource.Internal);\r\n        }\r\n\r\n        /// <summary>\r\n        /// An error running a unit processor results in an error for that unit.\r\n        /// </summary>\r\n        [Fact]\r\n        public void TestSet_UnitProcessorExecutionError()\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            ConfigurationUnit configurationUnitThrows = this.ConfigurationUnit();\r\n            ConfigurationUnit configurationUnitWorks = this.ConfigurationUnit();\r\n            configurationSet.Units = new ConfigurationUnit[] { configurationUnitWorks, configurationUnitThrows };\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet);\r\n            TestConfigurationUnitProcessor unitProcessor = setProcessor.CreateTestProcessor(configurationUnitThrows);\r\n            unitProcessor.TestSettingsDelegate = () => throw new NullReferenceException();\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            TestConfigurationSetResult result = processor.TestSet(configurationSet);\r\n\r\n            Assert.NotNull(result);\r\n            Assert.Equal(ConfigurationTestResult.Failed, result.TestResult);\r\n            Assert.NotNull(result.UnitResults);\r\n            Assert.Equal(2, result.UnitResults.Count);\r\n\r\n            TestConfigurationUnitResult throwsResult = result.UnitResults.First(x => x.Unit == configurationUnitThrows);\r\n            Assert.NotNull(throwsResult);\r\n            Assert.Equal(ConfigurationTestResult.Failed, throwsResult.TestResult);\r\n            Assert.NotNull(throwsResult.ResultInformation);\r\n            Assert.NotNull(throwsResult.ResultInformation.ResultCode);\r\n            Assert.IsType<NullReferenceException>(throwsResult.ResultInformation.ResultCode);\r\n            Assert.Equal(ConfigurationUnitResultSource.Internal, throwsResult.ResultInformation.ResultSource);\r\n\r\n            TestConfigurationUnitResult worksResult = result.UnitResults.First(x => x.Unit == configurationUnitWorks);\r\n            Assert.NotNull(worksResult);\r\n            Assert.Equal(ConfigurationTestResult.Positive, worksResult.TestResult);\r\n            Assert.NotNull(worksResult.ResultInformation);\r\n            Assert.Null(worksResult.ResultInformation.ResultCode);\r\n            Assert.Equal(ConfigurationUnitResultSource.None, worksResult.ResultInformation.ResultSource);\r\n\r\n            this.VerifySummaryEvent(configurationSet, result, throwsResult.ResultInformation.ResultCode.HResult, ConfigurationUnitResultSource.Internal);\r\n        }\r\n\r\n        /// <summary>\r\n        /// An error running a unit processor results in an error for that unit.\r\n        /// </summary>\r\n        [Fact]\r\n        public void TestSet_UnitProcessorResultError()\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            ConfigurationUnit configurationUnitThrows = this.ConfigurationUnit();\r\n            ConfigurationUnit configurationUnitWorks = this.ConfigurationUnit();\r\n            configurationSet.Units = new ConfigurationUnit[] { configurationUnitWorks, configurationUnitThrows };\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet);\r\n            TestConfigurationUnitProcessor unitProcessor = setProcessor.CreateTestProcessor(configurationUnitThrows);\r\n            TestSettingsResultInstance testResult = new TestSettingsResultInstance(configurationUnitThrows);\r\n            testResult.TestResult = ConfigurationTestResult.Failed;\r\n            testResult.InternalResult.ResultCode = new NullReferenceException();\r\n            testResult.InternalResult.Description = \"Failed again\";\r\n            testResult.InternalResult.ResultSource = ConfigurationUnitResultSource.UnitProcessing;\r\n            unitProcessor.TestSettingsDelegate = () => testResult;\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            TestConfigurationSetResult result = processor.TestSet(configurationSet);\r\n\r\n            Assert.NotNull(result);\r\n            Assert.Equal(ConfigurationTestResult.Failed, result.TestResult);\r\n            Assert.NotNull(result.UnitResults);\r\n            Assert.Equal(2, result.UnitResults.Count);\r\n\r\n            TestConfigurationUnitResult throwsResult = result.UnitResults.First(x => x.Unit == configurationUnitThrows);\r\n            Assert.NotNull(throwsResult);\r\n            Assert.Equal(ConfigurationTestResult.Failed, throwsResult.TestResult);\r\n            Assert.NotNull(throwsResult.ResultInformation);\r\n            Assert.NotNull(throwsResult.ResultInformation.ResultCode);\r\n            Assert.IsType<NullReferenceException>(throwsResult.ResultInformation.ResultCode);\r\n            Assert.Equal(testResult.ResultInformation.Description, throwsResult.ResultInformation.Description);\r\n            Assert.Equal(testResult.ResultInformation.ResultSource, throwsResult.ResultInformation.ResultSource);\r\n\r\n            TestConfigurationUnitResult worksResult = result.UnitResults.First(x => x.Unit == configurationUnitWorks);\r\n            Assert.NotNull(worksResult);\r\n            Assert.Equal(ConfigurationTestResult.Positive, worksResult.TestResult);\r\n            Assert.NotNull(worksResult.ResultInformation);\r\n            Assert.Null(worksResult.ResultInformation.ResultCode);\r\n            Assert.Equal(ConfigurationUnitResultSource.None, worksResult.ResultInformation.ResultSource);\r\n\r\n            this.VerifySummaryEvent(configurationSet, result, testResult.ResultInformation.ResultCode.HResult, testResult.ResultInformation.ResultSource);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Ensures that the expected TestResult comes back for all types.\r\n        /// </summary>\r\n        [Fact]\r\n        public void TestSet_ResultTypes()\r\n        {\r\n            this.RunTestSetTestForResultTypes(new ConfigurationTestResult[] { ConfigurationTestResult.Positive, ConfigurationTestResult.Negative, ConfigurationTestResult.Failed, ConfigurationTestResult.NotRun }, ConfigurationTestResult.Failed);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Ensures that a single negative makes the overall result negative.\r\n        /// </summary>\r\n        [Fact]\r\n        public void TestSet_Negative()\r\n        {\r\n            this.RunTestSetTestForResultTypes(new ConfigurationTestResult[] { ConfigurationTestResult.Positive, ConfigurationTestResult.Negative, ConfigurationTestResult.Positive, ConfigurationTestResult.NotRun }, ConfigurationTestResult.Negative);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Ensures that a single not run test does not impact the positive result.\r\n        /// </summary>\r\n        [Fact]\r\n        public void TestSet_Positive()\r\n        {\r\n            this.RunTestSetTestForResultTypes(new ConfigurationTestResult[] { ConfigurationTestResult.Positive, ConfigurationTestResult.Positive, ConfigurationTestResult.Positive, ConfigurationTestResult.NotRun }, ConfigurationTestResult.Positive);\r\n        }\r\n\r\n        private TestSettingsResultInstance PositiveResult(ConfigurationUnit unit)\r\n        {\r\n            TestSettingsResultInstance positiveResult = new TestSettingsResultInstance(unit);\r\n            positiveResult.TestResult = ConfigurationTestResult.Positive;\r\n            return positiveResult;\r\n        }\r\n\r\n        private TestSettingsResultInstance NegativeResult(ConfigurationUnit unit)\r\n        {\r\n            TestSettingsResultInstance negativeResult = new TestSettingsResultInstance(unit);\r\n            negativeResult.TestResult = ConfigurationTestResult.Negative;\r\n            return negativeResult;\r\n        }\r\n\r\n        private TestSettingsResultInstance FailedResult(ConfigurationUnit unit, string description, ConfigurationUnitResultSource resultSource)\r\n        {\r\n            TestSettingsResultInstance failedResult = new TestSettingsResultInstance(unit);\r\n            failedResult.TestResult = ConfigurationTestResult.Failed;\r\n            failedResult.InternalResult.ResultCode = new NullReferenceException();\r\n            failedResult.InternalResult.Description = description;\r\n            failedResult.InternalResult.ResultSource = resultSource;\r\n            return failedResult;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates a test scenario where the units produce the given test results.\r\n        /// </summary>\r\n        /// <param name=\"resultTypes\">The result types for each unit.</param>\r\n        /// <param name=\"overallResult\">The expected overall test result.</param>\r\n        private void RunTestSetTestForResultTypes(ConfigurationTestResult[] resultTypes, ConfigurationTestResult overallResult)\r\n        {\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            ConfigurationUnit[] configurationUnits = new ConfigurationUnit[resultTypes.Length];\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet);\r\n\r\n            string failedDescription = \"Failed again\";\r\n            ConfigurationUnitResultSource failedResultSource = ConfigurationUnitResultSource.UnitProcessing;\r\n\r\n            for (int i = 0; i < resultTypes.Length; ++i)\r\n            {\r\n                configurationUnits[i] = this.ConfigurationUnit();\r\n                configurationUnits[i].Type = $\"Unit {i}\";\r\n                TestConfigurationUnitProcessor unitProcessor = setProcessor.CreateTestProcessor(configurationUnits[i]);\r\n\r\n                switch (resultTypes[i])\r\n                {\r\n                    case ConfigurationTestResult.Positive:\r\n                        unitProcessor.TestSettingsDelegateWithUnit = (ConfigurationUnit unit) => this.PositiveResult(unit);\r\n                        break;\r\n                    case ConfigurationTestResult.Negative:\r\n                        unitProcessor.TestSettingsDelegateWithUnit = (ConfigurationUnit unit) => this.NegativeResult(unit);\r\n                        break;\r\n                    case ConfigurationTestResult.NotRun:\r\n                        configurationUnits[i].Intent = ConfigurationUnitIntent.Inform;\r\n                        break;\r\n                    case ConfigurationTestResult.Failed:\r\n                        unitProcessor.TestSettingsDelegateWithUnit = (ConfigurationUnit unit) => this.FailedResult(unit, failedDescription, failedResultSource);\r\n                        break;\r\n                }\r\n            }\r\n\r\n            configurationSet.Units = configurationUnits;\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            TestConfigurationSetResult result = processor.TestSet(configurationSet);\r\n\r\n            Assert.NotNull(result);\r\n            Assert.Equal(overallResult, result.TestResult);\r\n            Assert.NotNull(result.UnitResults);\r\n            Assert.Equal(resultTypes.Length, result.UnitResults.Count);\r\n\r\n            int summaryEventResult = 0;\r\n            ConfigurationUnitResultSource resultSource = ConfigurationUnitResultSource.None;\r\n\r\n            for (int i = 0; i < resultTypes.Length; ++i)\r\n            {\r\n                TestConfigurationUnitResult unitResult = result.UnitResults.First(x => x.Unit == configurationUnits[i]);\r\n\r\n                Assert.NotNull(unitResult);\r\n                Assert.Equal(resultTypes[i], unitResult.TestResult);\r\n                Assert.NotNull(unitResult.ResultInformation);\r\n\r\n                switch (resultTypes[i])\r\n                {\r\n                    case ConfigurationTestResult.Positive:\r\n                    case ConfigurationTestResult.Negative:\r\n                    case ConfigurationTestResult.NotRun:\r\n                        Assert.Null(unitResult.ResultInformation.ResultCode);\r\n                        Assert.Empty(unitResult.ResultInformation.Description);\r\n                        Assert.Equal(ConfigurationUnitResultSource.None, unitResult.ResultInformation.ResultSource);\r\n                        break;\r\n                    case ConfigurationTestResult.Failed:\r\n                        Assert.NotNull(unitResult.ResultInformation.ResultCode);\r\n                        Assert.IsType<NullReferenceException>(unitResult.ResultInformation.ResultCode);\r\n                        Assert.Equal(failedDescription, unitResult.ResultInformation.Description);\r\n                        Assert.Equal(failedResultSource, unitResult.ResultInformation.ResultSource);\r\n                        summaryEventResult = unitResult.ResultInformation.ResultCode.HResult;\r\n                        resultSource = unitResult.ResultInformation.ResultSource;\r\n                        break;\r\n                }\r\n            }\r\n\r\n            this.VerifySummaryEvent(configurationSet, result, summaryEventResult, resultSource);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationSetAuthoringTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationSetAuthoringTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using Microsoft.VisualBasic;\r\n    using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces;\r\n    using Windows.Foundation.Collections;\r\n    using Windows.Storage.Streams;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n\r\n    /// <summary>\r\n    /// Unit tests for configuration set authoring (creating objects).\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [InProc]\r\n    [OutOfProc]\r\n    public class ConfigurationSetAuthoringTests : ConfigurationProcessorTestBase\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ConfigurationSetAuthoringTests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Unit test fixture.</param>\r\n        /// <param name=\"log\">Log helper.</param>\r\n        public ConfigurationSetAuthoringTests(UnitTestFixture fixture, ITestOutputHelper log)\r\n            : base(fixture, log)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates a configuration set and sets all available properties.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ConfigurationSetAndProperties()\r\n        {\r\n            string testName = \"Test Name\";\r\n            string testOrigin = \"Test Origin\";\r\n            string testPath = \"TestPath.ext\";\r\n\r\n            ConfigurationSet testSet = this.ConfigurationSet();\r\n\r\n            testSet.Name = testName;\r\n            Assert.Equal(testName, testSet.Name);\r\n            testSet.Origin = testOrigin;\r\n            Assert.Equal(testOrigin, testSet.Origin);\r\n            testSet.Path = testPath;\r\n            Assert.Equal(testPath, testSet.Path);\r\n\r\n            Assert.NotEqual(Guid.Empty, testSet.InstanceIdentifier);\r\n            Assert.Equal(ConfigurationSetState.Unknown, testSet.State);\r\n\r\n            Assert.Empty(testSet.Units);\r\n            testSet.Units = new ConfigurationUnit[] { this.ConfigurationUnit() };\r\n            Assert.Equal(1, testSet.Units.Count);\r\n\r\n            Assert.NotEqual(string.Empty, testSet.SchemaVersion);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates a configuration unit and sets all available properties.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ConfigurationUnitAndProperties()\r\n        {\r\n            string testName = \"Test Name\";\r\n            string testIdentifier = \"Test Identifier\";\r\n            ConfigurationUnitIntent testIntent = ConfigurationUnitIntent.Assert;\r\n\r\n            ConfigurationUnit testUnit = this.ConfigurationUnit();\r\n            testUnit.Type = testName;\r\n            Assert.Equal(testName, testUnit.Type);\r\n            testUnit.Identifier = testIdentifier;\r\n            Assert.Equal(testIdentifier, testUnit.Identifier);\r\n\r\n            Assert.NotEqual(Guid.Empty, testUnit.InstanceIdentifier);\r\n\r\n            Assert.Equal(ConfigurationUnitIntent.Apply, testUnit.Intent);\r\n            testUnit.Intent = testIntent;\r\n            Assert.Equal(testIntent, testUnit.Intent);\r\n\r\n            Assert.Empty(testUnit.Dependencies);\r\n            testUnit.Dependencies = new string[] { \"dependency1\", \"dependency2\" };\r\n            Assert.Equal(2, testUnit.Dependencies.Count);\r\n\r\n            Assert.Empty(testUnit.Metadata);\r\n            Assert.Empty(testUnit.Settings);\r\n            Assert.Null(testUnit.Details);\r\n\r\n            Assert.Equal(ConfigurationUnitState.Unknown, testUnit.State);\r\n\r\n            Assert.Null(testUnit.ResultInformation);\r\n\r\n            Assert.True(testUnit.IsActive);\r\n            testUnit.IsActive = false;\r\n            Assert.False(testUnit.IsActive);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Basic sanity check to verify that nested value sets can be serialized successfully.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ConfigurationSetSerializeNestedValueSets()\r\n        {\r\n            ConfigurationSet testSet = this.ConfigurationSet();\r\n\r\n            testSet.SchemaVersion = \"0.2\";\r\n            ConfigurationUnit testUnit = this.ConfigurationUnit();\r\n            string testName = \"Test Name\";\r\n            string testIdentifier = \"Test Identifier\";\r\n            testUnit.Type = testName;\r\n            testUnit.Identifier = testIdentifier;\r\n\r\n            ValueSet innerValueSet = new ValueSet();\r\n            innerValueSet.Add(\"innerKey\", \"innerValue\");\r\n\r\n            ValueSet outerValueSet = new ValueSet();\r\n            outerValueSet.Add(\"outerKey\", innerValueSet);\r\n            testUnit.Metadata = outerValueSet;\r\n            testSet.Units.Add(testUnit);\r\n\r\n            InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream();\r\n            testSet.Serialize(stream);\r\n\r\n            string yamlOutput = this.ReadStream(stream);\r\n            Assert.NotNull(yamlOutput);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test for unique unit environment calculation.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ConfigurationSet_UnitEnvironments()\r\n        {\r\n            ConfigurationSet testSet = this.ConfigurationSet();\r\n\r\n            Dictionary<string, string> firstProperty = new Dictionary<string, string>();\r\n            firstProperty.Add(\"property\", \"value1\");\r\n\r\n            Dictionary<string, string> secondProperty = new Dictionary<string, string>();\r\n            secondProperty.Add(\"property\", \"value2\");\r\n\r\n            Helpers.ConfigurationEnvironmentData[] environments = new Helpers.ConfigurationEnvironmentData[]\r\n            {\r\n                new () { ProcessorIdentifier = \"dscv3\" },\r\n                new () { ProcessorIdentifier = \"pwsh\" },\r\n                new () { ProcessorIdentifier = \"dscv3\", Context = SecurityContext.Elevated },\r\n                new () { ProcessorIdentifier = \"pwsh\", Context = SecurityContext.Restricted },\r\n                new () { ProcessorIdentifier = \"dscv3\", ProcessorProperties = firstProperty },\r\n                new () { ProcessorIdentifier = \"pwsh\", ProcessorProperties = firstProperty },\r\n                new () { ProcessorIdentifier = \"pwsh\", ProcessorProperties = secondProperty },\r\n                new () { ProcessorIdentifier = \"dscv3\", Context = SecurityContext.Restricted, ProcessorProperties = firstProperty },\r\n                new () { ProcessorIdentifier = \"pwsh\", Context = SecurityContext.Elevated, ProcessorProperties = firstProperty },\r\n            };\r\n\r\n            foreach (int index in new int[] { 0, 1, 1, 2, 3, 5, 4, 6, 7, 8, 2, 7, 7, 7 })\r\n            {\r\n                Assert.True(index < environments.Length);\r\n                testSet.Units.Add(environments[index].ApplyToUnit(this.ConfigurationUnit()));\r\n            }\r\n\r\n            var uniqueEnvironments = testSet.GetUnitEnvironments();\r\n            this.EnsureEnvironmentEquivalence(environments, uniqueEnvironments);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test for unique unit environment calculation with group units.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ConfigurationSet_GroupUnitEnvironments()\r\n        {\r\n            ConfigurationSet testSet = this.ConfigurationSet();\r\n\r\n            Dictionary<string, string> firstProperty = new Dictionary<string, string>();\r\n            firstProperty.Add(\"property\", \"value1\");\r\n\r\n            Dictionary<string, string> secondProperty = new Dictionary<string, string>();\r\n            secondProperty.Add(\"property\", \"value2\");\r\n\r\n            Helpers.ConfigurationEnvironmentData[] environments = new Helpers.ConfigurationEnvironmentData[]\r\n            {\r\n                new () { ProcessorIdentifier = \"dscv3\" },\r\n                new () { ProcessorIdentifier = \"pwsh\" },\r\n                new () { ProcessorIdentifier = \"dscv3\", Context = SecurityContext.Elevated },\r\n                new () { ProcessorIdentifier = \"pwsh\", Context = SecurityContext.Restricted },\r\n                new () { ProcessorIdentifier = \"dscv3\", ProcessorProperties = firstProperty },\r\n                new () { ProcessorIdentifier = \"pwsh\", ProcessorProperties = firstProperty },\r\n                new () { ProcessorIdentifier = \"pwsh\", ProcessorProperties = secondProperty },\r\n                new () { ProcessorIdentifier = \"dscv3\", Context = SecurityContext.Restricted, ProcessorProperties = firstProperty },\r\n                new () { ProcessorIdentifier = \"pwsh\", Context = SecurityContext.Elevated, ProcessorProperties = firstProperty },\r\n                new (), // The default environment for the group unit\r\n            };\r\n\r\n            foreach (int index in new int[] { 0, 1, 1, 3, 5, 4, 6, 8 })\r\n            {\r\n                Assert.True(index < environments.Length);\r\n                testSet.Units.Add(environments[index].ApplyToUnit(this.ConfigurationUnit()));\r\n            }\r\n\r\n            var groupUnit = this.ConfigurationUnit();\r\n            groupUnit.IsGroup = true;\r\n\r\n            foreach (int index in new int[] { 7, 5, 2 })\r\n            {\r\n                Assert.True(index < environments.Length);\r\n                groupUnit.Units.Add(environments[index].ApplyToUnit(this.ConfigurationUnit()));\r\n            }\r\n\r\n            testSet.Units.Add(groupUnit);\r\n\r\n            var uniqueEnvironments = testSet.GetUnitEnvironments();\r\n            this.EnsureEnvironmentEquivalence(environments, uniqueEnvironments);\r\n        }\r\n\r\n        private void EnsureEnvironmentEquivalence(Helpers.ConfigurationEnvironmentData[] expectedEnvironments, IList<ConfigurationEnvironment>? actualEnvironments)\r\n        {\r\n            Assert.NotNull(actualEnvironments);\r\n            Assert.Equal(expectedEnvironments.Length, actualEnvironments.Count);\r\n\r\n            bool[] foundEnvironments = new bool[expectedEnvironments.Length];\r\n            foreach (var actual in actualEnvironments)\r\n            {\r\n                for (int i = 0; i < expectedEnvironments.Length; i++)\r\n                {\r\n                    var expected = expectedEnvironments[i];\r\n                    if (actual.Context == expected.Context && actual.ProcessorIdentifier == expected.ProcessorIdentifier && expected.PropertiesEqual(actual.ProcessorProperties))\r\n                    {\r\n                        foundEnvironments[i] = true;\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n\r\n            for (int i = 0; i < foundEnvironments.Length; i++)\r\n            {\r\n                Assert.True(foundEnvironments[i], $\"Found expected environment: {i}\");\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationSetProcessorTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationSetProcessorTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.Management.Automation;\r\n    using Microsoft.Management.Configuration;\r\n    using Microsoft.Management.Configuration.Processor.Exceptions;\r\n    using Microsoft.Management.Configuration.Processor.Helpers;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.DscResourcesInfo;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.Helpers;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.ProcessorEnvironments;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.Set;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using Microsoft.PowerShell.Commands;\r\n    using Moq;\r\n    using Windows.Foundation.Collections;\r\n    using Windows.Security.Cryptography.Certificates;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n\r\n    /// <summary>\r\n    /// Unit tests for configuration processor tests.\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [InProc]\r\n    public class ConfigurationSetProcessorTests\r\n    {\r\n        private readonly UnitTestFixture fixture;\r\n        private readonly ITestOutputHelper log;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ConfigurationSetProcessorTests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Unit test fixture.</param>\r\n        /// <param name=\"log\">Log helper.</param>\r\n        public ConfigurationSetProcessorTests(UnitTestFixture fixture, ITestOutputHelper log)\r\n        {\r\n            this.fixture = fixture;\r\n            this.log = log;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test CreateUnitProcessor. Happy path.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CreateUnitProcessor_ResourceExists()\r\n        {\r\n            string resourceName = \"xResourceName\";\r\n            string moduleName = \"xModuleName\";\r\n            Version version = new Version(\"1.0\");\r\n\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(\r\n                    m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))\r\n                .Returns(new DscResourceInfoInternal(resourceName, moduleName, version))\r\n                .Verifiable();\r\n\r\n            var configurationSetProcessor = new PowerShellConfigurationSetProcessor(\r\n                processorEnvMock.Object,\r\n                new ConfigurationSet());\r\n\r\n            var unit = new ConfigurationUnit\r\n            {\r\n                Type = resourceName,\r\n            };\r\n            unit.Metadata.Add(\"module\", moduleName);\r\n            unit.Metadata.Add(\"version\", version.ToString());\r\n\r\n            var unitProcessor = configurationSetProcessor.CreateUnitProcessor(unit);\r\n            Assert.NotNull(unitProcessor);\r\n            Assert.Equal(unit.Type, unitProcessor.Unit.Type);\r\n\r\n            processorEnvMock.Verify();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test CreateUnitProcessor case-insensitive.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CreateUnitProcessor_CaseInsensitive()\r\n        {\r\n            string resourceName = \"name\";\r\n            string moduleName = \"xModuleName\";\r\n            Version version = new Version(\"1.0\");\r\n\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(\r\n                    m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type.Equals(\"Name\", StringComparison.OrdinalIgnoreCase))))\r\n                .Returns(new DscResourceInfoInternal(\"Name\", moduleName, version))\r\n                .Verifiable();\r\n\r\n            var configurationSetProcessor = new PowerShellConfigurationSetProcessor(\r\n                processorEnvMock.Object,\r\n                new ConfigurationSet());\r\n\r\n            var unit = new ConfigurationUnit\r\n            {\r\n                Type = resourceName,\r\n            };\r\n            unit.Metadata.Add(\"module\", moduleName);\r\n            unit.Metadata.Add(\"version\", version.ToString());\r\n\r\n            var unitProcessor = configurationSetProcessor.CreateUnitProcessor(unit);\r\n            Assert.NotNull(unitProcessor);\r\n            Assert.Equal(unit.Type, unitProcessor.Unit.Type);\r\n\r\n            processorEnvMock.Verify();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test CreateUnitProcessor case-insensitive.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CreateUnitProcessor_ResourceNameMismatch()\r\n        {\r\n            string resourceName = \"name\";\r\n            string moduleName = \"xModuleName\";\r\n            Version version = new Version(\"1.0\");\r\n\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(\r\n                    m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))\r\n                .Returns(new DscResourceInfoInternal(\"OtherName\", moduleName, version))\r\n                .Verifiable();\r\n\r\n            var configurationSetProcessor = new PowerShellConfigurationSetProcessor(\r\n                processorEnvMock.Object,\r\n                new ConfigurationSet());\r\n\r\n            var unit = new ConfigurationUnit\r\n            {\r\n                Type = resourceName,\r\n            };\r\n            unit.Metadata.Add(\"module\", moduleName);\r\n            unit.Metadata.Add(\"version\", version.ToString());\r\n\r\n            Assert.Throws<ArgumentException>(() => configurationSetProcessor.CreateUnitProcessor(unit));\r\n\r\n            processorEnvMock.Verify();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test CreateUnitProcessor with no version directive.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CreateUnitProcessor_ResourceExists_NoVersionDirective()\r\n        {\r\n            string resourceName = \"xResourceName\";\r\n            string moduleName = \"xModuleName\";\r\n            Version version = new Version(\"1.0.0.0\");\r\n\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(\r\n                    m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))\r\n                .Returns(new DscResourceInfoInternal(resourceName, moduleName, version))\r\n                .Verifiable();\r\n\r\n            var configurationSetProcessor = new PowerShellConfigurationSetProcessor(\r\n                processorEnvMock.Object,\r\n                new ConfigurationSet());\r\n\r\n            var unit = new ConfigurationUnit\r\n            {\r\n                Type = resourceName,\r\n            };\r\n            unit.Metadata.Add(\"module\", moduleName);\r\n\r\n            var unitProcessor = configurationSetProcessor.CreateUnitProcessor(unit);\r\n            Assert.NotNull(unitProcessor);\r\n            Assert.Equal(unit.Type, unitProcessor.Unit.Type);\r\n\r\n            processorEnvMock.Verify();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test CreateUnitProcessor with no module directive.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CreateUnitProcessor_ResourceExists_NoModuleDirective()\r\n        {\r\n            string resourceName = \"xResourceName\";\r\n            string moduleName = \"xModuleName\";\r\n            Version version = new Version(\"1.0\");\r\n\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(\r\n                    m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))\r\n                .Returns(new DscResourceInfoInternal(resourceName, moduleName, version))\r\n                .Verifiable();\r\n\r\n            var configurationSetProcessor = new PowerShellConfigurationSetProcessor(\r\n                processorEnvMock.Object,\r\n                new ConfigurationSet());\r\n\r\n            var unit = new ConfigurationUnit\r\n            {\r\n                Type = resourceName,\r\n            };\r\n\r\n            var unitProcessor = configurationSetProcessor.CreateUnitProcessor(unit);\r\n            Assert.NotNull(unitProcessor);\r\n            Assert.Equal(unit.Type, unitProcessor.Unit.Type);\r\n\r\n            processorEnvMock.Verify();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests Creating a unit processor by downloading the resource.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CreateUnitProcessor_InstallResource()\r\n        {\r\n            string resourceName = \"xResourceName\";\r\n            string moduleName = \"xModuleName\";\r\n            Version version = new Version(\"1.0\");\r\n\r\n            DscResourceInfoInternal? nullResource = null;\r\n            DscResourceInfoInternal dscResourceInfo = new DscResourceInfoInternal(resourceName, moduleName, version);\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.SetupSequence(\r\n                m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))\r\n                .Returns(nullResource)\r\n                .Returns(dscResourceInfo);\r\n\r\n            PSObject findDscResourceResult = new PSObject(processorEnvMock);\r\n            processorEnvMock.Setup(\r\n                m => m.FindModule(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))\r\n                .Returns(findDscResourceResult)\r\n                .Verifiable();\r\n\r\n            processorEnvMock.Setup(\r\n                m => m.InstallModule(findDscResourceResult))\r\n                .Verifiable();\r\n\r\n            var configurationSetProcessor = new PowerShellConfigurationSetProcessor(\r\n                processorEnvMock.Object,\r\n                new ConfigurationSet());\r\n\r\n            var unit = new ConfigurationUnit\r\n            {\r\n                Type = resourceName,\r\n            };\r\n            unit.Metadata.Add(\"module\", moduleName);\r\n            unit.Metadata.Add(\"version\", version.ToString());\r\n\r\n            var unitProcessor = configurationSetProcessor.CreateUnitProcessor(unit);\r\n            Assert.NotNull(unitProcessor);\r\n            Assert.Equal(unit.Type, unitProcessor.Unit.Type);\r\n\r\n            processorEnvMock.Verify();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests Creating a unit processor by downloading the resource.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CreateUnitProcessor_InstallResource_WithoutModule()\r\n        {\r\n            string resourceName = \"SimpleFileResource\";\r\n            Version version = new Version(\"0.0.0.1\");\r\n\r\n            DscResourceInfoInternal? nullResource = null;\r\n            DscResourceInfoInternal dscResourceInfo = new DscResourceInfoInternal(resourceName, null, version);\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.SetupSequence(\r\n                m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))\r\n                .Returns(nullResource)\r\n                .Returns(dscResourceInfo);\r\n\r\n            PSObject findDscResourceResult = this.CreateFindResourceInfo();\r\n            processorEnvMock.Setup(\r\n                m => m.FindDscResource(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))\r\n                .Returns(findDscResourceResult)\r\n                .Verifiable();\r\n\r\n            PSObject moduleInfo = ((dynamic)findDscResourceResult).PSGetModuleInfo;\r\n            processorEnvMock.Setup(\r\n                m => m.InstallModule(moduleInfo))\r\n                .Verifiable();\r\n\r\n            var configurationSetProcessor = new PowerShellConfigurationSetProcessor(\r\n                processorEnvMock.Object,\r\n                new ConfigurationSet());\r\n\r\n            var unit = new ConfigurationUnit\r\n            {\r\n                Type = resourceName,\r\n            };\r\n            unit.Metadata.Add(\"version\", version.ToString());\r\n\r\n            var unitProcessor = configurationSetProcessor.CreateUnitProcessor(unit);\r\n            Assert.NotNull(unitProcessor);\r\n            Assert.Equal(unit.Type, unitProcessor.Unit.Type);\r\n\r\n            processorEnvMock.Verify();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests Creating a unit processor by downloading the resource.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CreateUnitProcessor_InstallResource_NotFoundAfterInstall()\r\n        {\r\n            string resourceName = \"xResourceName\";\r\n            string moduleName = \"xModuleName\";\r\n            Version version = new Version(\"1.0\");\r\n\r\n            DscResourceInfoInternal? nullResource = null;\r\n            DscResourceInfoInternal dscResourceInfo = new DscResourceInfoInternal(resourceName, moduleName, version);\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(\r\n                m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))\r\n                .Returns(nullResource);\r\n\r\n            PSObject findDscResourceResult = new PSObject(processorEnvMock);\r\n            processorEnvMock.Setup(\r\n                m => m.FindModule(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))\r\n                .Returns(findDscResourceResult)\r\n                .Verifiable();\r\n\r\n            processorEnvMock.Setup(\r\n                m => m.InstallModule(findDscResourceResult))\r\n                .Verifiable();\r\n\r\n            var configurationSetProcessor = new PowerShellConfigurationSetProcessor(\r\n                processorEnvMock.Object,\r\n                new ConfigurationSet());\r\n\r\n            var unit = new ConfigurationUnit\r\n            {\r\n                Type = resourceName,\r\n            };\r\n            unit.Metadata.Add(\"module\", moduleName);\r\n            unit.Metadata.Add(\"version\", version.ToString());\r\n\r\n            Assert.Throws<InstallDscResourceException>(\r\n                () => configurationSetProcessor.CreateUnitProcessor(unit));\r\n\r\n            processorEnvMock.Verify();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests Creating a unit processor by downloading the resource.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CreateUnitProcessor_InstallResource_NotFound()\r\n        {\r\n            string resourceName = \"xResourceName\";\r\n            string moduleName = \"xModuleName\";\r\n            Version version = new Version(\"1.0\");\r\n\r\n            DscResourceInfoInternal? nullResource = null;\r\n            DscResourceInfoInternal dscResourceInfo = new DscResourceInfoInternal(resourceName, moduleName, version);\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(\r\n                m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))\r\n                .Returns(nullResource);\r\n\r\n            PSObject? findDscResourceResult = null;\r\n            processorEnvMock.Setup(\r\n                m => m.FindModule(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))\r\n                .Returns(findDscResourceResult)\r\n                .Verifiable();\r\n\r\n            var configurationSetProcessor = new PowerShellConfigurationSetProcessor(\r\n                processorEnvMock.Object,\r\n                new ConfigurationSet());\r\n\r\n            var unit = new ConfigurationUnit\r\n            {\r\n                Type = resourceName,\r\n            };\r\n            unit.Metadata.Add(\"module\", moduleName);\r\n            unit.Metadata.Add(\"version\", version.ToString());\r\n\r\n            Assert.Throws<FindDscResourceNotFoundException>(\r\n                () => configurationSetProcessor.CreateUnitProcessor(unit));\r\n\r\n            processorEnvMock.Verify();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test GetUnitProcessorDetails Local Resource not found.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetUnitProcessorDetails_Local_NoFound()\r\n        {\r\n            string resourceName = \"xResource\";\r\n            DscResourceInfoInternal? nullDscInfoInternal = null;\r\n\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(\r\n                m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(u => u.Unit.Type == resourceName)))\r\n                .Returns(nullDscInfoInternal)\r\n                .Verifiable();\r\n\r\n            var configurationSetProcessor = new PowerShellConfigurationSetProcessor(\r\n                processorEnvMock.Object,\r\n                new ConfigurationSet());\r\n\r\n            var unit = new ConfigurationUnit()\r\n            {\r\n                Type = resourceName,\r\n            };\r\n\r\n            var configurationUnitProcessorDetails = configurationSetProcessor.GetUnitProcessorDetails(\r\n                unit,\r\n                ConfigurationUnitDetailFlags.Local);\r\n\r\n            Assert.Null(configurationUnitProcessorDetails);\r\n\r\n            processorEnvMock.Verify();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test GetUnitProcessorDetails Local Found. Module not installed by PowerShellGet.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetUnitProcessorDetails_Local_NotInstalledByPowerShellGet()\r\n        {\r\n            var unit = this.CreateConfigurationUnit();\r\n            var (dscResourceInfo, psModuleInfo) = this.GetResourceAndModuleInfo(unit);\r\n            PSObject? nullPsModuleInfo = null;\r\n\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(\r\n                m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(u => u.Unit.Type == dscResourceInfo.Name)))\r\n                .Returns(dscResourceInfo)\r\n                .Verifiable();\r\n            processorEnvMock.Setup(\r\n                m => m.GetAvailableModule(It.Is<ModuleSpecification>(s => s.Name == dscResourceInfo.ModuleName)))\r\n                .Returns(psModuleInfo)\r\n                .Verifiable();\r\n            processorEnvMock.Setup(\r\n                m => m.GetInstalledModule(It.Is<ModuleSpecification>(s => s.Name == dscResourceInfo.ModuleName)))\r\n                .Returns(nullPsModuleInfo)\r\n                .Verifiable();\r\n            processorEnvMock.Setup(\r\n                m => m.GetCertsOfValidSignedFiles(It.IsAny<string[]>()))\r\n                .Returns(new List<Certificate>())\r\n                .Verifiable();\r\n\r\n            var configurationSetProcessor = new PowerShellConfigurationSetProcessor(\r\n                processorEnvMock.Object,\r\n                new ConfigurationSet());\r\n\r\n            var configurationUnitProcessorDetails = configurationSetProcessor.GetUnitProcessorDetails(\r\n                unit,\r\n                ConfigurationUnitDetailFlags.Local);\r\n\r\n            Assert.NotNull(configurationUnitProcessorDetails);\r\n            Assert.Equal(dscResourceInfo.Name, configurationUnitProcessorDetails.UnitType);\r\n\r\n            processorEnvMock.Verify();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test GetUnitProcessorDetails locally found. Do not include Load.\r\n        /// </summary>\r\n        /// <param name=\"detailFlags\">Detail flags.</param>\r\n        [Theory]\r\n        [InlineData(ConfigurationUnitDetailFlags.Local)]\r\n        [InlineData(ConfigurationUnitDetailFlags.ReadOnly)]\r\n        [InlineData(ConfigurationUnitDetailFlags.Download)]\r\n        public void GetUnitProcessorDetails_Local(object detailFlags)\r\n        {\r\n            var unit = this.CreateConfigurationUnit();\r\n            var (dscResourceInfo, psModuleInfo) = this.GetResourceAndModuleInfo(unit);\r\n            var getModuleInfo = this.CreateGetModuleInfo();\r\n\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(\r\n                m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(u => u.Unit.Type == dscResourceInfo.Name)))\r\n                .Returns(dscResourceInfo)\r\n                .Verifiable();\r\n            processorEnvMock.Setup(\r\n                m => m.GetAvailableModule(It.Is<ModuleSpecification>(s => s.Name == dscResourceInfo.ModuleName)))\r\n                .Returns(psModuleInfo)\r\n                .Verifiable();\r\n            processorEnvMock.Setup(\r\n                m => m.GetInstalledModule(It.Is<ModuleSpecification>(s => s.Name == dscResourceInfo.ModuleName)))\r\n                .Returns(getModuleInfo)\r\n                .Verifiable();\r\n            processorEnvMock.Setup(\r\n                m => m.GetCertsOfValidSignedFiles(It.IsAny<string[]>()))\r\n                .Returns(new List<Certificate>())\r\n                .Verifiable();\r\n\r\n            var configurationSetProcessor = new PowerShellConfigurationSetProcessor(\r\n                processorEnvMock.Object,\r\n                new ConfigurationSet());\r\n\r\n            var configurationUnitProcessorDetails = configurationSetProcessor.GetUnitProcessorDetails(\r\n                unit,\r\n                Assert.IsType<ConfigurationUnitDetailFlags>(detailFlags));\r\n\r\n            Assert.NotNull(configurationUnitProcessorDetails);\r\n            Assert.Equal(dscResourceInfo.Name, configurationUnitProcessorDetails.UnitType);\r\n\r\n            processorEnvMock.Verify();\r\n            processorEnvMock.Verify(m => m.FindDscResource(It.IsAny<ConfigurationUnitAndModule>()), Times.Never());\r\n            processorEnvMock.Verify(m => m.ImportModule(It.IsAny<ModuleSpecification>()), Times.Never());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test GetUnitProcessorDetails locally found and load.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetUnitProcessorDetails_Local_Load()\r\n        {\r\n            var unit = this.CreateConfigurationUnit();\r\n            var (dscResourceInfo, psModuleInfo) = this.GetResourceAndModuleInfo(unit);\r\n            var getModuleInfo = this.CreateGetModuleInfo();\r\n\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(\r\n                m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(u => u.Unit.Type == dscResourceInfo.Name)))\r\n                .Returns(dscResourceInfo)\r\n                .Verifiable();\r\n            processorEnvMock.Setup(\r\n                m => m.GetAvailableModule(It.Is<ModuleSpecification>(s => s.Name == dscResourceInfo.ModuleName)))\r\n                .Returns(psModuleInfo)\r\n                .Verifiable();\r\n            processorEnvMock.Setup(\r\n                m => m.GetInstalledModule(It.Is<ModuleSpecification>(s => s.Name == dscResourceInfo.ModuleName)))\r\n                .Returns(getModuleInfo)\r\n                .Verifiable();\r\n            processorEnvMock.Setup(\r\n                m => m.ImportModule(It.Is<ModuleSpecification>(s => s.Name == dscResourceInfo.ModuleName)))\r\n                .Verifiable();\r\n            processorEnvMock.Setup(\r\n                m => m.GetCertsOfValidSignedFiles(It.IsAny<string[]>()))\r\n                .Returns(new List<Certificate>())\r\n                .Verifiable();\r\n\r\n            var configurationSetProcessor = new PowerShellConfigurationSetProcessor(\r\n                processorEnvMock.Object,\r\n                new ConfigurationSet());\r\n\r\n            var configurationUnitProcessorDetails = configurationSetProcessor.GetUnitProcessorDetails(\r\n                unit,\r\n                ConfigurationUnitDetailFlags.Load);\r\n\r\n            Assert.NotNull(configurationUnitProcessorDetails);\r\n            Assert.Equal(dscResourceInfo.Name, configurationUnitProcessorDetails.UnitType);\r\n\r\n            processorEnvMock.Verify();\r\n            processorEnvMock.Verify(m => m.FindDscResource(It.IsAny<ConfigurationUnitAndModule>()), Times.Never());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test GetUnitProcessorDetails Catalog Not Found.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetUnitProcessorDetails_Catalog_NotFound()\r\n        {\r\n            var unit = this.CreateConfigurationUnit();\r\n            DscResourceInfoInternal? nullDscResourceInfo = null;\r\n            PSObject? nullPsModuleInfo = null;\r\n\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(\r\n                m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(u => u.Unit.Type == unit.Type)))\r\n                .Returns(nullDscResourceInfo)\r\n                .Verifiable();\r\n            processorEnvMock.Setup(\r\n                m => m.FindModule(It.Is<ConfigurationUnitAndModule>(c => unit.Type == unit.Type)))\r\n                .Returns(nullPsModuleInfo)\r\n                .Verifiable();\r\n\r\n            var configurationSetProcessor = new PowerShellConfigurationSetProcessor(\r\n                processorEnvMock.Object,\r\n                new ConfigurationSet());\r\n\r\n            var configurationUnitProcessorDetails = configurationSetProcessor.GetUnitProcessorDetails(\r\n                unit,\r\n                ConfigurationUnitDetailFlags.ReadOnly);\r\n\r\n            Assert.Null(configurationUnitProcessorDetails);\r\n\r\n            processorEnvMock.Verify();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test GetUnitProcessorDetails Catalog Found.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetUnitProcessorDetails_Catalog()\r\n        {\r\n            var unit = this.CreateConfigurationUnit();\r\n            DscResourceInfoInternal? nullDscResourceInfo = null;\r\n            var getFindResourceInfo = this.CreateFindResourceInfo();\r\n\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(\r\n                m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(u => u.Unit.Type == unit.Type)))\r\n                .Returns(nullDscResourceInfo)\r\n                .Verifiable();\r\n            processorEnvMock.Setup(\r\n                m => m.FindModule(It.Is<ConfigurationUnitAndModule>(c => unit.Type == unit.Type)))\r\n                .Returns(getFindResourceInfo)\r\n                .Verifiable();\r\n\r\n            var configurationSetProcessor = new PowerShellConfigurationSetProcessor(\r\n                processorEnvMock.Object,\r\n                new ConfigurationSet());\r\n\r\n            var configurationUnitProcessorDetails = configurationSetProcessor.GetUnitProcessorDetails(\r\n                unit,\r\n                ConfigurationUnitDetailFlags.ReadOnly);\r\n\r\n            Assert.NotNull(configurationUnitProcessorDetails);\r\n            Assert.Equal(\"SimpleFileResource\", configurationUnitProcessorDetails.UnitType);\r\n\r\n            processorEnvMock.Verify();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test GetUnitProcessorDetails downloading module.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetUnitProcessorDetails_Download()\r\n        {\r\n            var unit = this.CreateConfigurationUnit();\r\n            DscResourceInfoInternal? nullDscResourceInfo = null;\r\n            var (_, psModuleInfo) = this.GetResourceAndModuleInfo(unit);\r\n            var getFindModuleInfo = this.CreateGetModuleInfo();\r\n\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(\r\n                m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(u => u.Unit.Type == unit.Type)))\r\n                .Returns(nullDscResourceInfo)\r\n                .Verifiable();\r\n            processorEnvMock.Setup(\r\n                m => m.FindModule(It.Is<ConfigurationUnitAndModule>(c => unit.Type == unit.Type)))\r\n                .Returns(getFindModuleInfo)\r\n                .Verifiable();\r\n            processorEnvMock.Setup(\r\n                m => m.SaveModule(getFindModuleInfo, It.IsAny<string>()))\r\n                .Verifiable();\r\n            processorEnvMock.Setup(\r\n                m => m.GetAvailableModule(It.Is<string>(s => s.EndsWith(\"xSimpleTestResource\"))))\r\n                .Returns(psModuleInfo)\r\n                .Verifiable();\r\n            processorEnvMock.Setup(\r\n                m => m.GetCertsOfValidSignedFiles(It.IsAny<string[]>()))\r\n                .Returns(new List<Certificate>())\r\n                .Verifiable();\r\n\r\n            var configurationSetProcessor = new PowerShellConfigurationSetProcessor(\r\n                processorEnvMock.Object,\r\n                new ConfigurationSet());\r\n\r\n            var configurationUnitProcessorDetails = configurationSetProcessor.GetUnitProcessorDetails(\r\n                unit,\r\n                ConfigurationUnitDetailFlags.Download);\r\n\r\n            Assert.NotNull(configurationUnitProcessorDetails);\r\n            Assert.Equal(\"SimpleFileResource\", configurationUnitProcessorDetails.UnitType);\r\n\r\n            processorEnvMock.Verify();\r\n\r\n            processorEnvMock.Verify(m => m.InstallModule(It.IsAny<PSObject>()), Times.Never());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests GetUnitProcessorDetails install module, but resource not found anyway.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetUnitProcessorDetails_Load_NotFoundAfterInstall()\r\n        {\r\n            var unit = this.CreateConfigurationUnit();\r\n            DscResourceInfoInternal? nullDscResourceInfo = null;\r\n            var (_, psModuleInfo) = this.GetResourceAndModuleInfo(unit);\r\n            var getFindResourceInfo = this.CreateFindResourceInfo();\r\n\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(\r\n                m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(u => u.Unit.Type == unit.Type)))\r\n                .Returns(nullDscResourceInfo)\r\n                .Verifiable();\r\n            processorEnvMock.Setup(\r\n                m => m.FindModule(It.Is<ConfigurationUnitAndModule>(c => unit.Type == unit.Type)))\r\n                .Returns(getFindResourceInfo)\r\n                .Verifiable();\r\n            processorEnvMock.Setup(\r\n                m => m.InstallModule(getFindResourceInfo))\r\n                .Verifiable();\r\n\r\n            var configurationSetProcessor = new PowerShellConfigurationSetProcessor(\r\n                processorEnvMock.Object,\r\n                new ConfigurationSet());\r\n\r\n            Assert.Throws<InstallDscResourceException>(() => configurationSetProcessor.GetUnitProcessorDetails(\r\n                unit,\r\n                ConfigurationUnitDetailFlags.Load));\r\n\r\n            processorEnvMock.Verify();\r\n            processorEnvMock.Verify(\r\n                m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(u => u.Unit.Type == unit.Type)),\r\n                Times.Exactly(2));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests GetUnitProcessorDetails install module.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetUnitProcessorDetails_Load()\r\n        {\r\n            var unit = this.CreateConfigurationUnit();\r\n            DscResourceInfoInternal? nullDscResourceInfo = null;\r\n            var (dscResourceInfo, psModuleInfo) = this.GetResourceAndModuleInfo(unit);\r\n            var getFindResourceInfo = this.CreateFindResourceInfo();\r\n\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.SetupSequence(\r\n                m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(u => u.Unit.Type == unit.Type)))\r\n                .Returns(nullDscResourceInfo)\r\n                .Returns(dscResourceInfo);\r\n            processorEnvMock.Setup(\r\n                m => m.FindModule(It.Is<ConfigurationUnitAndModule>(c => unit.Type == unit.Type)))\r\n                .Returns(getFindResourceInfo)\r\n                .Verifiable();\r\n            processorEnvMock.Setup(\r\n                m => m.InstallModule(getFindResourceInfo))\r\n                .Verifiable();\r\n            processorEnvMock.Setup(\r\n                m => m.GetInstalledModule(It.Is<ModuleSpecification>(s => s.Name == dscResourceInfo.ModuleName)))\r\n                .Returns(getFindResourceInfo)\r\n                .Verifiable();\r\n            processorEnvMock.Setup(\r\n                m => m.ImportModule(It.Is<ModuleSpecification>(s => s.Name == dscResourceInfo.ModuleName)))\r\n                .Verifiable();\r\n\r\n            var configurationSetProcessor = new PowerShellConfigurationSetProcessor(\r\n                processorEnvMock.Object,\r\n                new ConfigurationSet());\r\n\r\n            var configurationUnitProcessorDetails = configurationSetProcessor.GetUnitProcessorDetails(\r\n                unit,\r\n                ConfigurationUnitDetailFlags.Load);\r\n\r\n            Assert.NotNull(configurationUnitProcessorDetails);\r\n            Assert.Equal(dscResourceInfo.Name, configurationUnitProcessorDetails.UnitType);\r\n\r\n            processorEnvMock.Verify();\r\n            processorEnvMock.Verify(\r\n                m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(u => u.Unit.Type == unit.Type)),\r\n                Times.Exactly(2));\r\n        }\r\n\r\n        /// <summary>\r\n        /// This tests uses SimpleTestResourceTypes Test to validate the resource got the correct types\r\n        /// from the processor.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CreateUnitProcessor_TestTypes()\r\n        {\r\n            var processorEnv = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            var setProcessor = new PowerShellConfigurationSetProcessor(processorEnv, new ConfigurationSet());\r\n\r\n            var unit = new ConfigurationUnit\r\n            {\r\n                Type = \"SimpleTestResourceTypes\",\r\n                Intent = ConfigurationUnitIntent.Assert,\r\n            };\r\n\r\n            unit.Metadata.Add(\"module\", \"xSimpleTestResource\");\r\n            unit.Metadata.Add(\"version\", \"0.0.0.1\");\r\n\r\n            var hashtableProperty = new ValueSet\r\n            {\r\n                { \"secretStringKey\", \"secretCode\" },\r\n                { \"secretIntKey\", \"123456\" },\r\n            };\r\n\r\n            unit.Settings.Add(\"boolProperty\", true);\r\n            unit.Settings.Add(\"intProperty\", 3);\r\n            unit.Settings.Add(\"doubleProperty\", -9.876);\r\n            unit.Settings.Add(\"charProperty\", 'f');\r\n            unit.Settings.Add(\"hashtableProperty\", hashtableProperty);\r\n\r\n            var unitProcessor = setProcessor.CreateUnitProcessor(unit);\r\n\r\n            unitProcessor.TestSettings();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests a module that requires admin is loaded from non admin.\r\n        /// </summary>\r\n        [FactSkipIfCI]\r\n        public void CreateUnitProcessor_ModuleRequiresAdmin()\r\n        {\r\n            var processorEnv = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            var setProcessor = new PowerShellConfigurationSetProcessor(processorEnv, new ConfigurationSet());\r\n\r\n            var unit = new ConfigurationUnit\r\n            {\r\n                Type = \"AdminResource\",\r\n                Intent = ConfigurationUnitIntent.Assert,\r\n            };\r\n            unit.Metadata.Add(\"module\", \"xAdminTestResource\");\r\n            unit.Metadata.Add(\"version\", \"0.0.0.1\");\r\n\r\n            unit.Settings.Add(\"key\", \"key\");\r\n\r\n            var importModuleException = Assert.Throws<ImportModuleException>(() => setProcessor.CreateUnitProcessor(unit));\r\n            Assert.Equal(ErrorCodes.WinGetConfigUnitImportModuleAdmin, importModuleException.HResult);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test CreateUnitProcessor. Limit mode.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CreateUnitProcessor_LimitMode()\r\n        {\r\n            string resourceName = \"xResourceName\";\r\n            string moduleName = \"xModuleName\";\r\n            Version version = new Version(\"1.0\");\r\n\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(\r\n                    m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))\r\n                .Returns(new DscResourceInfoInternal(resourceName, moduleName, version))\r\n                .Verifiable();\r\n\r\n            var limitSet = new ConfigurationSet();\r\n            var limitUnit = new ConfigurationUnit\r\n            {\r\n                Type = resourceName,\r\n                Intent = ConfigurationUnitIntent.Apply,\r\n            };\r\n            limitUnit.Metadata.Add(\"module\", moduleName);\r\n            limitUnit.Metadata.Add(\"version\", version.ToString());\r\n            limitSet.Units = new List<ConfigurationUnit> { limitUnit };\r\n\r\n            var configurationSetProcessor = new PowerShellConfigurationSetProcessor(\r\n                processorEnvMock.Object,\r\n                limitSet,\r\n                true);\r\n\r\n            // Calling with unit different from limit set should throw.\r\n            var unitDifferentContent = new ConfigurationUnit\r\n            {\r\n                Type = \"differentResourceName\",\r\n                Intent = ConfigurationUnitIntent.Apply,\r\n            };\r\n\r\n            Assert.Throws<System.InvalidOperationException>(() => configurationSetProcessor.CreateUnitProcessor(unitDifferentContent));\r\n            Assert.Throws<System.InvalidOperationException>(() => configurationSetProcessor.GetUnitProcessorDetails(unitDifferentContent, ConfigurationUnitDetailFlags.Load));\r\n\r\n            // Calling with unit matching limit set.\r\n            var unitProcessor = configurationSetProcessor.CreateUnitProcessor(limitUnit);\r\n            Assert.NotNull(unitProcessor);\r\n            Assert.Equal(limitUnit.Type, unitProcessor.Unit.Type);\r\n            var processorDetails = configurationSetProcessor.GetUnitProcessorDetails(limitUnit, ConfigurationUnitDetailFlags.Load);\r\n            Assert.NotNull(processorDetails);\r\n            Assert.Equal(moduleName, processorDetails.ModuleName);\r\n\r\n            // Calling CreateProcessor again should thow. Calling GetProcessorDetails multiple times is ok.\r\n            Assert.Throws<System.InvalidOperationException>(() => configurationSetProcessor.CreateUnitProcessor(limitUnit));\r\n            var processorDetails2 = configurationSetProcessor.GetUnitProcessorDetails(limitUnit, ConfigurationUnitDetailFlags.Load);\r\n            Assert.NotNull(processorDetails2);\r\n            Assert.Equal(moduleName, processorDetails2.ModuleName);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test CreateUnitProcessor. Limit mode. Duplicate units in limit set.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CreateUnitProcessor_LimitMode_DuplicateUnits()\r\n        {\r\n            string resourceName = \"xResourceName\";\r\n            string moduleName = \"xModuleName\";\r\n            Version version = new Version(\"1.0\");\r\n\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(\r\n                    m => m.GetDscResource(It.Is<ConfigurationUnitAndModule>(c => c.Unit.Type == resourceName)))\r\n                .Returns(new DscResourceInfoInternal(resourceName, moduleName, version))\r\n                .Verifiable();\r\n\r\n            var limitSet = new ConfigurationSet();\r\n            var limitUnit = new ConfigurationUnit\r\n            {\r\n                Type = resourceName,\r\n                Intent = ConfigurationUnitIntent.Apply,\r\n            };\r\n            limitUnit.Metadata.Add(\"module\", moduleName);\r\n            limitUnit.Metadata.Add(\"version\", version.ToString());\r\n            limitSet.Units = new List<ConfigurationUnit> { limitUnit, limitUnit };\r\n\r\n            var configurationSetProcessor = new PowerShellConfigurationSetProcessor(\r\n                processorEnvMock.Object,\r\n                limitSet,\r\n                true);\r\n\r\n            // Calling with unit different from limit set should throw.\r\n            var unitDifferentContent = new ConfigurationUnit\r\n            {\r\n                Type = \"differentResourceName\",\r\n                Intent = ConfigurationUnitIntent.Apply,\r\n            };\r\n\r\n            Assert.Throws<System.InvalidOperationException>(() => configurationSetProcessor.CreateUnitProcessor(unitDifferentContent));\r\n\r\n            // Calling with unit matching limit set.\r\n            var unitProcessor = configurationSetProcessor.CreateUnitProcessor(limitUnit);\r\n            Assert.NotNull(unitProcessor);\r\n            Assert.Equal(limitUnit.Type, unitProcessor.Unit.Type);\r\n\r\n            // Calling again should also not thow.\r\n            var unitProcessor2 = configurationSetProcessor.CreateUnitProcessor(limitUnit);\r\n            Assert.NotNull(unitProcessor2);\r\n            Assert.Equal(limitUnit.Type, unitProcessor2.Unit.Type);\r\n\r\n            // Calling third time should throw.\r\n            Assert.Throws<System.InvalidOperationException>(() => configurationSetProcessor.CreateUnitProcessor(limitUnit));\r\n        }\r\n\r\n        private ConfigurationUnit CreateConfigurationUnit()\r\n        {\r\n            var unit = new ConfigurationUnit();\r\n            unit.Type = \"SimpleFileResource\";\r\n            unit.Metadata.Add(\"module\", \"xSimpleTestResource\");\r\n            unit.Metadata.Add(\"version\", \"0.0.0.1\");\r\n\r\n            return unit;\r\n        }\r\n\r\n        private (DscResourceInfoInternal dscResourceInfo, PSModuleInfo psModuleInfo) GetResourceAndModuleInfo(ConfigurationUnit unit)\r\n        {\r\n            // This is easier than trying to mock sealed class from external code...\r\n            var testEnv = this.fixture.PrepareTestProcessorEnvironment(true);\r\n            var dscResourceInfo = testEnv.GetDscResource(new ConfigurationUnitAndModule(unit, string.Empty));\r\n            var psModuleInfo = testEnv.GetAvailableModule(PowerShellHelpers.CreateModuleSpecification(\"xSimpleTestResource\", \"0.0.0.1\"));\r\n\r\n            if (dscResourceInfo is null || psModuleInfo is null)\r\n            {\r\n                throw new ArgumentNullException(\"Test processor environment not set correctly\");\r\n            }\r\n\r\n            return (dscResourceInfo, psModuleInfo);\r\n        }\r\n\r\n        private PSObject CreateGetModuleInfo()\r\n        {\r\n            return new PSObject(new\r\n            {\r\n                Repository = \"PSGallery\",\r\n                PublishedDate = new DateTime(2017, 12, 10),\r\n                IconUri = \"https://github.com/microsoft/winget-cli\",\r\n                Name = \"xSimpleTestResource\",\r\n                Description = \"PowerShell module with DSC resources for unit tests\",\r\n                RepositorySourceLocation = \"https://github.com/microsoft/winget-cli\",\r\n                Version = \"0.0.0.1\",\r\n                Author = \"Luffytaro\",\r\n                CompanyName = \"Microsoft Corporation\",\r\n            });\r\n        }\r\n\r\n        private PSObject CreateFindResourceInfo()\r\n        {\r\n            var getModuleInfo = this.CreateGetModuleInfo();\r\n            return new PSObject(new\r\n            {\r\n                Name = \"SimpleFileResource\",\r\n                ModuleName = \"xSimpleTestResource\",\r\n                Version = \"0.0.0.1\",\r\n                PSGetModuleInfo = getModuleInfo,\r\n            });\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationUnitInternalTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationUnitInternalTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.IO;\r\n    using System.Management.Automation;\r\n    using Microsoft.Management.Configuration;\r\n    using Microsoft.Management.Configuration.Processor.Exceptions;\r\n    using Microsoft.Management.Configuration.Processor.Helpers;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.Helpers;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n\r\n    /// <summary>\r\n    /// Tests ConfigurationUnitExtensionsTests.\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [InProc]\r\n    public class ConfigurationUnitInternalTests\r\n    {\r\n        private readonly UnitTestFixture fixture;\r\n        private readonly ITestOutputHelper log;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ConfigurationUnitInternalTests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Unit test fixture.</param>\r\n        /// <param name=\"log\">Log helper.</param>\r\n        public ConfigurationUnitInternalTests(UnitTestFixture fixture, ITestOutputHelper log)\r\n        {\r\n            this.fixture = fixture;\r\n            this.log = log;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test GetDirectives.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetDirectivesTest()\r\n        {\r\n            string moduleDirective = \"module\";\r\n            string unitModule = \"xModule\";\r\n\r\n            string versionDirective = \"version\";\r\n            string unitVersion = \"1.0.0.0\";\r\n\r\n            string descriptionDirective = \"description\";\r\n            string unitDescription = \"beep beep boop i am a text\";\r\n\r\n            string boolDirective = \"boolDirective\";\r\n            bool boolDirectiveValue = true;\r\n\r\n            string boolDirective2 = \"boolDirective2\";\r\n            bool boolDirective2Value = false;\r\n\r\n            var unit = new ConfigurationUnit().Assign(new { Type = $\"{unitModule}/unitResource\" });\r\n            unit.Metadata.Add(moduleDirective, unitModule);\r\n            unit.Metadata.Add(versionDirective, unitVersion);\r\n            unit.Metadata.Add(descriptionDirective, unitDescription);\r\n            unit.Metadata.Add(boolDirective, boolDirectiveValue);\r\n            unit.Metadata.Add(boolDirective2, boolDirective2Value);\r\n\r\n            var unitInternal = new ConfigurationUnitAndModule(unit, string.Empty);\r\n\r\n            var description = unitInternal.GetDirective<string>(descriptionDirective);\r\n            Assert.Equal(description, unitDescription);\r\n\r\n            var fake = unitInternal.GetDirective<string>(\"fake\");\r\n            Assert.Null(fake);\r\n\r\n            var description2 = unitInternal.GetDirective<string>(\"DESCRIPTION\");\r\n            Assert.Equal(description2, unitDescription);\r\n\r\n            Assert.Equal(unitModule, unitInternal.Module!.Name);\r\n\r\n            Assert.Equal(Version.Parse(unitVersion), unitInternal.Module!.RequiredVersion);\r\n\r\n            Assert.Equal(boolDirectiveValue, unitInternal.GetDirective(boolDirective));\r\n            Assert.Equal(boolDirective2Value, unitInternal.GetDirective(boolDirective2));\r\n            Assert.Null(unitInternal.GetDirective(\"fakeBool\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests GetVersion with a bad version.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetVersion_BadVersion()\r\n        {\r\n            var unit = new ConfigurationUnit();\r\n            unit.Metadata.Add(\"module\", \"module\");\r\n            unit.Metadata.Add(\"version\", \"not a version\");\r\n\r\n            Assert.Throws<ArgumentException>(\r\n                () => new ConfigurationUnitInternal(unit, string.Empty));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies expansion of ConfigRoot.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetExpandedSettings_ConfigRoot()\r\n        {\r\n            using var tmpFile = new TempFile(\"fakeConfigFile.yml\", content: \"content\");\r\n\r\n            var unit = new ConfigurationUnit().Assign(new { Type = \"unitModule/unitResource\" });\r\n            unit.Settings.Add(\"var1\", @\"$WinGetConfigRoot\\this\\is\\a\\path.txt\");\r\n            unit.Settings.Add(\"var2\", @\"${WinGetConfigRoot}\\this\\is\\a\\path.txt\");\r\n            unit.Settings.Add(\"var3\", @\"this\\is\\a\\$WINGETCONFIGROOT\\path.txt\");\r\n            unit.Settings.Add(\"var4\", @\"this\\is\\a\\${WINGETCONFIGROOT}\\path.txt\");\r\n            unit.Settings.Add(\"var5\", @\"this\\is\\a\\path\\$wingetconfigroot\");\r\n            unit.Settings.Add(\"var6\", @\"this\\is\\a\\path\\${wingetconfigroot}\");\r\n\r\n            string configPath = tmpFile.FullFileName;\r\n            string? expectedPath = Path.GetDirectoryName(configPath);\r\n            var unitInternal = new ConfigurationUnitInternal(unit, configPath);\r\n\r\n            var expandedSettings = unitInternal.GetExpandedSettings();\r\n\r\n            var var1 = expandedSettings[\"var1\"];\r\n            Assert.Equal(@\"$WinGetConfigRoot\\this\\is\\a\\path.txt\", var1 as string);\r\n\r\n            var var2 = expandedSettings[\"var2\"];\r\n            Assert.Equal($@\"{expectedPath}\\this\\is\\a\\path.txt\", var2 as string);\r\n\r\n            var var3 = expandedSettings[\"var3\"];\r\n            Assert.Equal(@\"this\\is\\a\\$WINGETCONFIGROOT\\path.txt\", var3 as string);\r\n\r\n            var var4 = expandedSettings[\"var4\"];\r\n            Assert.Equal($@\"this\\is\\a\\{expectedPath}\\path.txt\", var4 as string);\r\n\r\n            var var5 = expandedSettings[\"var5\"];\r\n            Assert.Equal(@\"this\\is\\a\\path\\$wingetconfigroot\", var5 as string);\r\n\r\n            var var6 = expandedSettings[\"var6\"];\r\n            Assert.Equal($@\"this\\is\\a\\path\\{expectedPath}\", var6 as string);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies throws when config root is not set.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetExpandedSetting_ConfigRoot_Throw()\r\n        {\r\n            var unit = new ConfigurationUnit().Assign(new { Type = \"unitModule/unitResource\" });\r\n            unit.Settings.Add(\"var2\", @\"${WinGetConfigRoot}\\this\\is\\a\\path.txt\");\r\n\r\n            var unitInternal = new ConfigurationUnitInternal(unit, null!);\r\n            Assert.Throws<UnitSettingConfigRootException>(() => unitInternal.GetExpandedSettings());\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/ConfigurationUnitProcessorTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ConfigurationUnitProcessorTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System;\r\n    using System.Management.Automation;\r\n    using Microsoft.Management.Configuration;\r\n    using Microsoft.Management.Configuration.Processor.Helpers;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.DscResourcesInfo;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.Helpers;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.ProcessorEnvironments;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.Unit;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using Microsoft.PowerShell.Commands;\r\n    using Moq;\r\n    using Windows.Foundation.Collections;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n\r\n    /// <summary>\r\n    /// Configuration unit processor tests.\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [InProc]\r\n    public class ConfigurationUnitProcessorTests\r\n    {\r\n        private readonly UnitTestFixture fixture;\r\n        private readonly ITestOutputHelper log;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ConfigurationUnitProcessorTests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Unit test fixture.</param>\r\n        /// <param name=\"log\">Log helper.</param>\r\n        public ConfigurationUnitProcessorTests(UnitTestFixture fixture, ITestOutputHelper log)\r\n        {\r\n            this.fixture = fixture;\r\n            this.log = log;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Call GetSettings with all intents should succeed.\r\n        /// </summary>\r\n        /// <param name=\"intent\">Intent.</param>\r\n        [Theory]\r\n        [InlineData(ConfigurationUnitIntent.Inform)]\r\n        [InlineData(ConfigurationUnitIntent.Assert)]\r\n        [InlineData(ConfigurationUnitIntent.Apply)]\r\n        public void GetSettings_Test(object intent)\r\n        {\r\n            string theKey = \"key\";\r\n            string theValue = \"value\";\r\n            var valueGetResult = new ValueSet\r\n            {\r\n                { theKey, theValue },\r\n            };\r\n\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(m => m.InvokeGetResource(\r\n                It.IsAny<ValueSet>(),\r\n                It.IsAny<string>(),\r\n                It.IsAny<ModuleSpecification?>()))\r\n                .Returns(valueGetResult)\r\n                .Verifiable();\r\n\r\n            var unitResource = this.CreateUnitResource(Assert.IsType<ConfigurationUnitIntent>(intent));\r\n\r\n            var unitProcessor = new PowerShellConfigurationUnitProcessor(processorEnvMock.Object, unitResource);\r\n\r\n            var result = unitProcessor.GetSettings();\r\n\r\n            processorEnvMock.Verify();\r\n\r\n            Assert.True(result.Settings.Count == 1);\r\n            Assert.True(result.Settings.ContainsKey(theKey));\r\n            Assert.True(result.Settings.TryGetValue(theKey, out object keyValue));\r\n            Assert.Equal(theValue, keyValue as string);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests GetSettings when a System.Management.Automation.RuntimeException is thrown.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetSettings_Throws_Pwsh_RuntimeException()\r\n        {\r\n            var thrownException = new RuntimeException(\"a message\");\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(m => m.InvokeGetResource(\r\n                It.IsAny<ValueSet>(),\r\n                It.IsAny<string>(),\r\n                It.IsAny<ModuleSpecification?>()))\r\n                .Throws(() => thrownException)\r\n                .Verifiable();\r\n\r\n            var unitResource = this.CreateUnitResource(ConfigurationUnitIntent.Inform);\r\n\r\n            var unitProcessor = new PowerShellConfigurationUnitProcessor(processorEnvMock.Object, unitResource);\r\n\r\n            var result = unitProcessor.GetSettings();\r\n\r\n            processorEnvMock.Verify();\r\n\r\n            // Do not check for the type.\r\n            Assert.Equal(thrownException.HResult, result.ResultInformation.ResultCode.HResult);\r\n            Assert.True(!string.IsNullOrWhiteSpace(result.ResultInformation.Description));\r\n            Assert.Equal(ConfigurationUnitResultSource.Internal, result.ResultInformation.ResultSource);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests GetSettings when a Microsoft.PowerShell.Commands.WriteErrorException is thrown.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetSettings_Throws_Pwsh_WriteErrorException()\r\n        {\r\n            var thrownException = new WriteErrorException(\"a message\");\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(m => m.InvokeGetResource(\r\n                It.IsAny<ValueSet>(),\r\n                It.IsAny<string>(),\r\n                It.IsAny<ModuleSpecification?>()))\r\n                .Throws(() => thrownException)\r\n                .Verifiable();\r\n\r\n            var unitResource = this.CreateUnitResource(ConfigurationUnitIntent.Inform);\r\n\r\n            var unitProcessor = new PowerShellConfigurationUnitProcessor(processorEnvMock.Object, unitResource);\r\n\r\n            var result = unitProcessor.GetSettings();\r\n\r\n            processorEnvMock.Verify();\r\n\r\n            // Do not check for the type.\r\n            Assert.Equal(thrownException.HResult, result.ResultInformation.ResultCode.HResult);\r\n            Assert.True(!string.IsNullOrWhiteSpace(result.ResultInformation.Description));\r\n            Assert.Equal(ConfigurationUnitResultSource.Internal, result.ResultInformation.ResultSource);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Call TestSettings with Inform intent is not allowed.\r\n        /// </summary>\r\n        [Fact]\r\n        public void TestSettings_InformIntent()\r\n        {\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            var unitResource = this.CreateUnitResource(ConfigurationUnitIntent.Inform);\r\n\r\n            var unitProcessor = new PowerShellConfigurationUnitProcessor(processorEnvMock.Object, unitResource);\r\n\r\n            Assert.Throws<NotSupportedException>(() => unitProcessor.TestSettings());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Call TestSettings with Assert and Apply should work.\r\n        /// </summary>\r\n        /// <param name=\"intent\">Intent.</param>\r\n        /// <param name=\"invokeTestResult\">Invoke test result.</param>\r\n        [Theory]\r\n        [InlineData(ConfigurationUnitIntent.Assert, false)]\r\n        [InlineData(ConfigurationUnitIntent.Apply, false)]\r\n        [InlineData(ConfigurationUnitIntent.Assert, true)]\r\n        [InlineData(ConfigurationUnitIntent.Apply, true)]\r\n        public void TestSettings_TestSucceeded(object intent, bool invokeTestResult)\r\n        {\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(m => m.InvokeTestResource(\r\n                It.IsAny<ValueSet>(),\r\n                It.IsAny<string>(),\r\n                It.IsAny<ModuleSpecification?>()))\r\n                .Returns(invokeTestResult)\r\n                .Verifiable();\r\n\r\n            var unitResource = this.CreateUnitResource(Assert.IsType<ConfigurationUnitIntent>(intent));\r\n\r\n            var unitProcessor = new PowerShellConfigurationUnitProcessor(processorEnvMock.Object, unitResource);\r\n\r\n            var testResult = unitProcessor.TestSettings();\r\n\r\n            processorEnvMock.Verify();\r\n\r\n            var expectedConfigTestResult = ConfigurationTestResult.Negative;\r\n            if (invokeTestResult)\r\n            {\r\n                expectedConfigTestResult = ConfigurationTestResult.Positive;\r\n            }\r\n\r\n            Assert.Equal(expectedConfigTestResult, testResult.TestResult);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests TestSettings when a System.Management.Automation.RuntimeException is thrown.\r\n        /// </summary>\r\n        [Fact]\r\n        public void TestSettings_Throws_Pwsh_RuntimeException()\r\n        {\r\n            var thrownException = new RuntimeException(\"a message\");\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(m => m.InvokeTestResource(\r\n                It.IsAny<ValueSet>(),\r\n                It.IsAny<string>(),\r\n                It.IsAny<ModuleSpecification?>()))\r\n                .Throws(() => thrownException)\r\n                .Verifiable();\r\n\r\n            var unitResource = this.CreateUnitResource(ConfigurationUnitIntent.Assert);\r\n\r\n            var unitProcessor = new PowerShellConfigurationUnitProcessor(processorEnvMock.Object, unitResource);\r\n\r\n            var result = unitProcessor.TestSettings();\r\n\r\n            processorEnvMock.Verify();\r\n\r\n            Assert.Equal(ConfigurationTestResult.Failed, result.TestResult);\r\n\r\n            // Do not check for the type.\r\n            Assert.Equal(thrownException.HResult, result.ResultInformation.ResultCode.HResult);\r\n            Assert.True(!string.IsNullOrWhiteSpace(result.ResultInformation.Description));\r\n            Assert.Equal(ConfigurationUnitResultSource.Internal, result.ResultInformation.ResultSource);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests TestSettings when a Microsoft.PowerShell.Commands.WriteErrorException is thrown.\r\n        /// </summary>\r\n        [Fact]\r\n        public void TestSettings_Throws_Pwsh_WriteErrorException()\r\n        {\r\n            var thrownException = new WriteErrorException(\"a message\");\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(m => m.InvokeTestResource(\r\n                It.IsAny<ValueSet>(),\r\n                It.IsAny<string>(),\r\n                It.IsAny<ModuleSpecification?>()))\r\n                .Throws(() => thrownException)\r\n                .Verifiable();\r\n\r\n            var unitResource = this.CreateUnitResource(ConfigurationUnitIntent.Assert);\r\n\r\n            var unitProcessor = new PowerShellConfigurationUnitProcessor(processorEnvMock.Object, unitResource);\r\n\r\n            var result = unitProcessor.TestSettings();\r\n\r\n            processorEnvMock.Verify();\r\n\r\n            Assert.Equal(ConfigurationTestResult.Failed, result.TestResult);\r\n\r\n            // Do not check for the type.\r\n            Assert.Equal(thrownException.HResult, result.ResultInformation.ResultCode.HResult);\r\n            Assert.True(!string.IsNullOrWhiteSpace(result.ResultInformation.Description));\r\n            Assert.Equal(ConfigurationUnitResultSource.Internal, result.ResultInformation.ResultSource);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Call ApplySettings with invalid intents.\r\n        /// </summary>\r\n        /// <param name=\"intent\">Intent.</param>\r\n        [Theory]\r\n        [InlineData(ConfigurationUnitIntent.Inform)]\r\n        [InlineData(ConfigurationUnitIntent.Assert)]\r\n        public void ApplySettings_InvalidIntent(object intent)\r\n        {\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            var unitResource = this.CreateUnitResource(Assert.IsType<ConfigurationUnitIntent>(intent));\r\n\r\n            var unitProcessor = new PowerShellConfigurationUnitProcessor(processorEnvMock.Object, unitResource);\r\n\r\n            Assert.Throws<NotSupportedException>(() => unitProcessor.ApplySettings());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Call ApplySettings.\r\n        /// </summary>\r\n        /// <param name=\"rebootRequired\">Reboot required.</param>\r\n        [Theory]\r\n        [InlineData(true)]\r\n        [InlineData(false)]\r\n        public void ApplySettings_Test(bool rebootRequired)\r\n        {\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(m => m.InvokeSetResource(\r\n                It.IsAny<ValueSet>(),\r\n                It.IsAny<string>(),\r\n                It.IsAny<ModuleSpecification?>()))\r\n                .Returns(rebootRequired)\r\n                .Verifiable();\r\n\r\n            var unitResource = this.CreateUnitResource(ConfigurationUnitIntent.Apply);\r\n\r\n            var unitProcessor = new PowerShellConfigurationUnitProcessor(processorEnvMock.Object, unitResource);\r\n\r\n            var result = unitProcessor.ApplySettings();\r\n\r\n            Assert.Equal(rebootRequired, result.RebootRequired);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests ApplySettings when a System.Management.Automation.RuntimeException is thrown.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ApplySettings_Throws_Pwsh_RuntimeException()\r\n        {\r\n            var thrownException = new RuntimeException(\"a message\");\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(m => m.InvokeSetResource(\r\n                It.IsAny<ValueSet>(),\r\n                It.IsAny<string>(),\r\n                It.IsAny<ModuleSpecification?>()))\r\n                .Throws(() => thrownException)\r\n                .Verifiable();\r\n\r\n            var unitResource = this.CreateUnitResource(ConfigurationUnitIntent.Apply);\r\n\r\n            var unitProcessor = new PowerShellConfigurationUnitProcessor(processorEnvMock.Object, unitResource);\r\n\r\n            var result = unitProcessor.ApplySettings();\r\n\r\n            processorEnvMock.Verify();\r\n\r\n            // Do not check for the type.\r\n            Assert.Equal(thrownException.HResult, result.ResultInformation.ResultCode.HResult);\r\n            Assert.True(!string.IsNullOrWhiteSpace(result.ResultInformation.Description));\r\n            Assert.Equal(ConfigurationUnitResultSource.Internal, result.ResultInformation.ResultSource);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests ApplySettings when a Microsoft.PowerShell.Commands.WriteErrorException is thrown.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ApplySettings_Throws_Pwsh_WriteErrorException()\r\n        {\r\n            var thrownException = new RuntimeException(\"a message\");\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(m => m.InvokeSetResource(\r\n                It.IsAny<ValueSet>(),\r\n                It.IsAny<string>(),\r\n                It.IsAny<ModuleSpecification?>()))\r\n                .Throws(() => thrownException)\r\n                .Verifiable();\r\n\r\n            var unitResource = this.CreateUnitResource(ConfigurationUnitIntent.Apply);\r\n\r\n            var unitProcessor = new PowerShellConfigurationUnitProcessor(processorEnvMock.Object, unitResource);\r\n\r\n            var result = unitProcessor.ApplySettings();\r\n\r\n            processorEnvMock.Verify();\r\n\r\n            // Do not check for the type.\r\n            Assert.Equal(thrownException.HResult, result.ResultInformation.ResultCode.HResult);\r\n            Assert.True(!string.IsNullOrWhiteSpace(result.ResultInformation.Description));\r\n            Assert.Equal(ConfigurationUnitResultSource.Internal, result.ResultInformation.ResultSource);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests ApplySettings in limit mode.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ApplySettings_Test_LimitMode()\r\n        {\r\n            string theKey = \"key\";\r\n            string theValue = \"value\";\r\n            var valueGetResult = new ValueSet\r\n            {\r\n                { theKey, theValue },\r\n            };\r\n\r\n            var processorEnvMock = new Mock<IProcessorEnvironment>();\r\n            processorEnvMock.Setup(m => m.InvokeGetResource(\r\n                It.IsAny<ValueSet>(),\r\n                It.IsAny<string>(),\r\n                It.IsAny<ModuleSpecification?>()))\r\n                .Returns(valueGetResult)\r\n                .Verifiable();\r\n\r\n            var unitResource = this.CreateUnitResource(ConfigurationUnitIntent.Apply);\r\n\r\n            var unitProcessor = new PowerShellConfigurationUnitProcessor(processorEnvMock.Object, unitResource, true);\r\n\r\n            // GetSettings can be called multiple times.\r\n            var getResult = unitProcessor.GetSettings();\r\n            getResult = unitProcessor.GetSettings();\r\n\r\n            // TestSettings can be called only once.\r\n            var testResult = unitProcessor.TestSettings();\r\n            Assert.Throws<System.InvalidOperationException>(() => unitProcessor.TestSettings());\r\n\r\n            // ApplySettings can be called only once.\r\n            var applyResult = unitProcessor.ApplySettings();\r\n            Assert.Throws<System.InvalidOperationException>(() => unitProcessor.ApplySettings());\r\n        }\r\n\r\n        private ConfigurationUnitAndResource CreateUnitResource(ConfigurationUnitIntent intent)\r\n        {\r\n            string resourceName = \"xResourceName\";\r\n            return new ConfigurationUnitAndResource(\r\n                new ConfigurationUnitAndModule(\r\n                    new ConfigurationUnit\r\n                    {\r\n                        Type = resourceName,\r\n                        Intent = intent,\r\n                    },\r\n                    string.Empty),\r\n                new DscResourceInfoInternal(resourceName, null, null));\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/DSCv3ProcessorTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"DSCv3ProcessorTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System.Collections.Generic;\r\n    using System.Linq;\r\n    using Microsoft.Management.Configuration.Processor;\r\n    using Microsoft.Management.Configuration.Processor.DSCv3.Model;\r\n    using Microsoft.Management.Configuration.Processor.Exceptions;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using Windows.Foundation.Collections;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n\r\n    /// <summary>\r\n    /// Tests for the DSCv3 processor.\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [InProc]\r\n    public class DSCv3ProcessorTests : ConfigurationProcessorTestBase\r\n    {\r\n        private readonly UnitTestFixture fixture;\r\n        private readonly ITestOutputHelper log;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"DSCv3ProcessorTests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Unit test fixture.</param>\r\n        /// <param name=\"log\">Log helper.</param>\r\n        public DSCv3ProcessorTests(UnitTestFixture fixture, ITestOutputHelper log)\r\n            : base(fixture, log)\r\n        {\r\n            this.fixture = fixture;\r\n            this.log = log;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests for the unit details caching.\r\n        /// </summary>\r\n        [Fact]\r\n        public void Set_UnitPropertyDetailsCached()\r\n        {\r\n            var (factory, dsc) = CreateTestFactory();\r\n            var set = this.ConfigurationSet();\r\n            string type1 = \"Type1\";\r\n            string type2 = \"Type2\";\r\n            var unit1 = this.ConfigurationUnit().Assign(new { Type = type1 });\r\n            var unit2 = this.ConfigurationUnit().Assign(new { Type = type2 });\r\n\r\n            var setProcessor = factory.CreateSetProcessor(set);\r\n\r\n            // Initially, no details\r\n            var details = setProcessor.GetUnitProcessorDetails(unit1, ConfigurationUnitDetailFlags.Local);\r\n            Assert.Null(details);\r\n\r\n            // Null result not cached\r\n            dsc.GetResourceByTypeResult = new TestResourceListItem() { Type = type1 };\r\n            details = setProcessor.GetUnitProcessorDetails(unit1, ConfigurationUnitDetailFlags.Local);\r\n            Assert.NotNull(details);\r\n            Assert.Equal(type1, details.UnitType);\r\n\r\n            // Not-null result cached\r\n            dsc.GetResourceByTypeResult = null;\r\n            dsc.GetResourceByTypeDelegate = s => throw new System.Exception(\"Shouldn't be called\");\r\n            details = setProcessor.GetUnitProcessorDetails(unit1, ConfigurationUnitDetailFlags.Local);\r\n            Assert.NotNull(details);\r\n            Assert.Equal(type1, details.UnitType);\r\n\r\n            // Different type, no details\r\n            dsc.GetResourceByTypeDelegate = null;\r\n            details = setProcessor.GetUnitProcessorDetails(unit2, ConfigurationUnitDetailFlags.Local);\r\n            Assert.Null(details);\r\n\r\n            // Null result not cached\r\n            dsc.GetResourceByTypeResult = new TestResourceListItem() { Type = type2 };\r\n            details = setProcessor.GetUnitProcessorDetails(unit2, ConfigurationUnitDetailFlags.Local);\r\n            Assert.NotNull(details);\r\n            Assert.Equal(type2, details.UnitType);\r\n\r\n            // First type is still first type\r\n            dsc.GetResourceByTypeResult = null;\r\n            dsc.GetResourceByTypeDelegate = s => throw new System.Exception(\"Shouldn't be called\");\r\n            details = setProcessor.GetUnitProcessorDetails(unit1, ConfigurationUnitDetailFlags.Local);\r\n            Assert.NotNull(details);\r\n            Assert.Equal(type1, details.UnitType);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test for unit processor creation requiring resource to be found.\r\n        /// </summary>\r\n        [Fact(Skip = \"Disable this test while we have the bypass in place\")]\r\n        public void Set_ResourceNotFoundIsError()\r\n        {\r\n            var (factory, dsc) = CreateTestFactory();\r\n            var set = this.ConfigurationSet();\r\n            string type1 = \"Type1\";\r\n            var unit1 = this.ConfigurationUnit().Assign(new { Type = type1 });\r\n\r\n            var setProcessor = factory.CreateSetProcessor(set);\r\n\r\n            // Not found is error\r\n            Assert.Throws<FindDscResourceNotFoundException>(() => setProcessor.CreateUnitProcessor(unit1));\r\n\r\n            // Found is not error\r\n            dsc.GetResourceByTypeResult = new TestResourceListItem() { Type = type1 };\r\n            var unitProcessor = setProcessor.CreateUnitProcessor(unit1);\r\n            Assert.NotNull(unitProcessor);\r\n            Assert.Equal(type1, unitProcessor.Unit.Type);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test for settings export.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetAllSettings_Expected()\r\n        {\r\n            var (factory, dsc) = CreateTestFactory();\r\n            var processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            string type1 = \"Type1\";\r\n            var unit1 = this.ConfigurationUnit().Assign(new { Type = type1 });\r\n\r\n            dsc.GetResourceByTypeDelegate = (type) =>\r\n            {\r\n                Assert.Equal(type1, type);\r\n                return new TestResourceListItem() { Type = type1 };\r\n            };\r\n\r\n            ValueSet set1 = new ValueSet();\r\n            set1.Add(\"key1\", \"val1\");\r\n\r\n            ValueSet set2 = new ValueSet();\r\n            set2.Add(\"key2\", \"val2\");\r\n\r\n            dsc.ExportResourceResult = new List<IResourceExportItem>()\r\n            {\r\n                new TestResourceExportItem() { Type = type1, Name = \"1\", Settings = set1 },\r\n                new TestResourceExportItem() { Type = type1, Name = \"2\", Settings = set2 },\r\n            };\r\n\r\n            var result = processor.GetAllUnitSettings(unit1);\r\n\r\n            Assert.NotNull(result);\r\n            Assert.NotNull(result.ResultInformation);\r\n            Assert.Null(result.ResultInformation.ResultCode);\r\n\r\n            Assert.Equal(2, result.Settings.Count);\r\n            Assert.NotNull(result.Settings.Single(set => set.Contains(set1.First())));\r\n            Assert.NotNull(result.Settings.Single(set => set.Contains(set2.First())));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test for settings export with differing types.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetAllSettings_DifferentType()\r\n        {\r\n            var (factory, dsc) = CreateTestFactory();\r\n            var processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            string type1 = \"Type1\";\r\n            string type2 = \"Type2\";\r\n            var unit1 = this.ConfigurationUnit().Assign(new { Type = type1 });\r\n\r\n            dsc.GetResourceByTypeDelegate = (type) =>\r\n            {\r\n                Assert.Equal(type1, type);\r\n                return new TestResourceListItem() { Type = type1 };\r\n            };\r\n\r\n            ValueSet set1 = new ValueSet();\r\n            set1.Add(\"key1\", \"val1\");\r\n\r\n            ValueSet set2 = new ValueSet();\r\n            set2.Add(\"key2\", \"val2\");\r\n\r\n            dsc.ExportResourceResult = new List<IResourceExportItem>()\r\n            {\r\n                new TestResourceExportItem() { Type = type1, Name = \"1\", Settings = set1 },\r\n                new TestResourceExportItem() { Type = type2, Name = \"2\", Settings = set2 },\r\n            };\r\n\r\n            var result = processor.GetAllUnitSettings(unit1);\r\n\r\n            Assert.NotNull(result);\r\n            Assert.NotNull(result.ResultInformation);\r\n            Assert.NotNull(result.ResultInformation.ResultCode);\r\n            Assert.Equal(ErrorCodes.WinGetConfigUnitUnsupportedType, result.ResultInformation.ResultCode.HResult);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test for unit export.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetAllUnits_Simple()\r\n        {\r\n            var (factory, dsc) = CreateTestFactory();\r\n            var processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            string type1 = \"Type1\";\r\n            var unit1 = this.ConfigurationUnit().Assign(new { Type = type1 });\r\n\r\n            dsc.GetResourceByTypeDelegate = (type) =>\r\n            {\r\n                Assert.Equal(type1, type);\r\n                return new TestResourceListItem() { Type = type1 };\r\n            };\r\n\r\n            ValueSet set1 = new ValueSet();\r\n            set1.Add(\"key1\", \"val1\");\r\n\r\n            ValueSet set2 = new ValueSet();\r\n            set2.Add(\"key2\", \"val2\");\r\n\r\n            dsc.ExportResourceResult = new List<IResourceExportItem>()\r\n            {\r\n                new TestResourceExportItem() { Type = type1, Name = \"1\", Settings = set1 },\r\n                new TestResourceExportItem() { Type = type1, Name = \"2\", Settings = set2 },\r\n            };\r\n\r\n            var result = processor.GetAllUnits(unit1);\r\n\r\n            Assert.NotNull(result);\r\n            Assert.NotNull(result.ResultInformation);\r\n            Assert.Null(result.ResultInformation.ResultCode);\r\n\r\n            Assert.Equal(2, result.Units.Count);\r\n\r\n            foreach (var unit in result.Units)\r\n            {\r\n                Assert.Equal(type1, unit.Type);\r\n                Assert.NotEmpty(unit.Identifier);\r\n            }\r\n\r\n            Assert.NotEqual(result.Units[0].Identifier, result.Units[1].Identifier);\r\n\r\n            Assert.NotNull(result.Units.Single(unit => unit.Settings.Contains(set1.First())));\r\n            Assert.NotNull(result.Units.Single(unit => unit.Settings.Contains(set2.First())));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test for unit export with complex data.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetAllUnits_Complex()\r\n        {\r\n            var (factory, dsc) = CreateTestFactory();\r\n            var processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            string type1 = \"Type1\";\r\n            string type2 = \"Type2\";\r\n\r\n            string name1 = \"1\";\r\n            string name2 = \"2\";\r\n\r\n            var unit1 = this.ConfigurationUnit().Assign(new { Type = type1 });\r\n\r\n            dsc.GetResourceByTypeDelegate = (type) =>\r\n            {\r\n                Assert.Equal(type1, type);\r\n                return new TestResourceListItem() { Type = type1 };\r\n            };\r\n\r\n            ValueSet set1 = new ValueSet();\r\n            set1.Add(\"key1\", \"val1\");\r\n\r\n            ValueSet metadata1 = new ValueSet();\r\n            metadata1.Add(\"met1\", \"val11\");\r\n\r\n            ValueSet set2 = new ValueSet();\r\n            set2.Add(\"key2\", \"val2\");\r\n\r\n            List<string> dependencies2 = new List<string>();\r\n            dependencies2.Add(name1);\r\n\r\n            dsc.ExportResourceResult = new List<IResourceExportItem>()\r\n            {\r\n                new TestResourceExportItem() { Type = type1, Name = name1, Settings = set1, Metadata = metadata1 },\r\n                new TestResourceExportItem() { Type = type2, Name = name2, Settings = set2, Dependencies = dependencies2 },\r\n            };\r\n\r\n            var result = processor.GetAllUnits(unit1);\r\n\r\n            Assert.NotNull(result);\r\n            Assert.NotNull(result.ResultInformation);\r\n            Assert.Null(result.ResultInformation.ResultCode);\r\n\r\n            Assert.Equal(2, result.Units.Count);\r\n\r\n            var result1 = result.Units.Single(unit => unit.Identifier == name1);\r\n            var result2 = result.Units.Single(unit => unit.Identifier == name2);\r\n\r\n            Assert.Equal(type1, result1.Type);\r\n            Assert.Equal(type2, result2.Type);\r\n\r\n            Assert.Contains(set1.First(), result1.Settings);\r\n            Assert.Contains(set2.First(), result2.Settings);\r\n\r\n            Assert.Contains(metadata1.First(), result1.Metadata);\r\n            Assert.Empty(result2.Metadata);\r\n\r\n            Assert.Empty(result1.Dependencies);\r\n            Assert.Contains(dependencies2.First(), result2.Dependencies);\r\n        }\r\n\r\n        private static (DSCv3ConfigurationSetProcessorFactory, TestDSCv3) CreateTestFactory()\r\n        {\r\n            DSCv3ConfigurationSetProcessorFactory factory = new DSCv3ConfigurationSetProcessorFactory();\r\n            TestDSCv3 dsc = new TestDSCv3();\r\n            factory.Settings.DSCv3 = dsc;\r\n            factory.Settings.DscExecutablePath = \"Test-Path-Not-Used.txt\";\r\n\r\n            return (factory, dsc);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/DscModuleV2SimpleFileResourceTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"DscModuleV2SimpleFileResourceTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System.IO;\r\n    using System.Management.Automation;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.DscModules;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.Helpers;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using Windows.Foundation.Collections;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n    using static Microsoft.Management.Configuration.UnitTests.Helpers.PowerShellTestsConstants;\r\n\r\n    /// <summary>\r\n    /// Class that tests a little not that complex resource.\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [InProc]\r\n    public class DscModuleV2SimpleFileResourceTests\r\n    {\r\n        private readonly UnitTestFixture fixture;\r\n        private readonly ITestOutputHelper log;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"DscModuleV2SimpleFileResourceTests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Fixture.</param>\r\n        /// <param name=\"log\">log.</param>\r\n        public DscModuleV2SimpleFileResourceTests(UnitTestFixture fixture, ITestOutputHelper log)\r\n        {\r\n            this.fixture = fixture;\r\n            this.log = log;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test SimpleFileResource Ensure Present and Absent when file doesn't exist.\r\n        /// </summary>\r\n        /// <param name=\"ensureValue\">Ensure value.</param>\r\n        /// <param name=\"expectedResult\">Expected result.</param>\r\n        [Theory]\r\n        [InlineData(\"Absent\", true)]\r\n        [InlineData(\"Present\", false)]\r\n        public void SimpleFileResource_FileAbsent(string ensureValue, bool expectedResult)\r\n        {\r\n            var processorEnv = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            // Doesn't create a file.\r\n            using var tmpFile = new TempFile();\r\n\r\n            var settings = new ValueSet\r\n            {\r\n                { \"Path\", tmpFile.FullFileName },\r\n                { \"Ensure\", ensureValue },\r\n            };\r\n\r\n            var dscModule = new DscModuleV2();\r\n\r\n            using PowerShell pwsh = PowerShell.Create(processorEnv.Runspace);\r\n            Assert.Equal(\r\n                expectedResult,\r\n                dscModule.InvokeTestResource(\r\n                    pwsh,\r\n                    settings,\r\n                    TestModule.SimpleFileResourceName,\r\n                    PowerShellHelpers.CreateModuleSpecification(\r\n                        TestModule.SimpleTestResourceModuleName)));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test SimpleFileResource when the file exists.\r\n        /// </summary>\r\n        [Fact]\r\n        public void SimpleFileResource_FilePresent()\r\n        {\r\n            var processorEnv = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            using var tmpFile = new TempFile();\r\n            tmpFile.CreateFile();\r\n\r\n            var settings = new ValueSet\r\n            {\r\n                { \"Path\", tmpFile.FullFileName },\r\n                { \"Ensure\", \"Present\" },\r\n            };\r\n\r\n            var dscModule = new DscModuleV2();\r\n            using PowerShell pwsh = PowerShell.Create(processorEnv.Runspace);\r\n            Assert.True(dscModule.InvokeTestResource(\r\n                pwsh,\r\n                settings,\r\n                TestModule.SimpleFileResourceName,\r\n                PowerShellHelpers.CreateModuleSpecification(\r\n                    TestModule.SimpleTestResourceModuleName)));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test SimpleFileResource with different content.\r\n        /// </summary>\r\n        [Fact]\r\n        public void SimpleFileResource_DifferentContent()\r\n        {\r\n            var processorEnv = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            using var tmpFile = new TempFile(content: \"All work and no play makes Ruben a dull boy\");\r\n\r\n            var settings = new ValueSet\r\n            {\r\n                { \"Path\", tmpFile.FullFileName },\r\n                { \"Ensure\", \"Present\" },\r\n                { \"Content\", \"Is that a from somewhere?\" },\r\n            };\r\n\r\n            var dscModule = new DscModuleV2();\r\n            using PowerShell pwsh = PowerShell.Create(processorEnv.Runspace);\r\n            Assert.False(dscModule.InvokeTestResource(\r\n                pwsh,\r\n                settings,\r\n                TestModule.SimpleFileResourceName,\r\n                PowerShellHelpers.CreateModuleSpecification(\r\n                    TestModule.SimpleTestResourceModuleName)));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test SimpleFileResource with same context.\r\n        /// </summary>\r\n        [Fact]\r\n        public void SimpleFileResource_SameContent()\r\n        {\r\n            var processorEnv = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            string content = \"This is literally the same, dont fail\";\r\n            using var tmpFile = new TempFile(content: content);\r\n\r\n            var settings = new ValueSet\r\n            {\r\n                { \"Path\", tmpFile.FullFileName },\r\n                { \"Ensure\", \"Present\" },\r\n                { \"Content\", content },\r\n            };\r\n\r\n            var dscModule = new DscModuleV2();\r\n            using PowerShell pwsh = PowerShell.Create(processorEnv.Runspace);\r\n            Assert.True(dscModule.InvokeTestResource(\r\n                pwsh,\r\n                settings,\r\n                TestModule.SimpleFileResourceName,\r\n                PowerShellHelpers.CreateModuleSpecification(\r\n                    TestModule.SimpleTestResourceModuleName)));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test SimpleFileResource Set creates the file.\r\n        /// </summary>\r\n        /// <param name=\"ensureValue\">Ensure value.</param>\r\n        /// <param name=\"preCondition\">If file exists before calling set.</param>\r\n        /// <param name=\"postCondition\">If file exists after calling set.</param>\r\n        [Theory]\r\n        [InlineData(\"Absent\", false, false)]\r\n        [InlineData(\"Present\", false, true)]\r\n        [InlineData(\"Absent\", true, false)]\r\n        [InlineData(\"Present\", true, true)]\r\n        public void SimpleFileResource_Set_Ensure(string ensureValue, bool preCondition, bool postCondition)\r\n        {\r\n            var processorEnv = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            // Doesn't create a file.\r\n            using var tmpFile = new TempFile();\r\n\r\n            var settings = new ValueSet\r\n            {\r\n                { \"Path\", tmpFile.FullFileName },\r\n                { \"Ensure\", ensureValue },\r\n            };\r\n\r\n            if (preCondition)\r\n            {\r\n                tmpFile.CreateFile();\r\n            }\r\n\r\n            Assert.Equal(\r\n                preCondition,\r\n                File.Exists(tmpFile.FullFileName));\r\n\r\n            var dscModule = new DscModuleV2();\r\n            using PowerShell pwsh = PowerShell.Create(processorEnv.Runspace);\r\n            dscModule.InvokeSetResource(\r\n                pwsh,\r\n                settings,\r\n                TestModule.SimpleFileResourceName,\r\n                PowerShellHelpers.CreateModuleSpecification(\r\n                    TestModule.SimpleTestResourceModuleName));\r\n\r\n            Assert.Equal(\r\n                postCondition,\r\n                File.Exists(tmpFile.FullFileName));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests SimpleFileResource Set writes to the file.\r\n        /// </summary>\r\n        /// <param name=\"preSetContent\">The text in the file before calling Set.</param>\r\n        /// <param name=\"postSetContent\">The test in the file after calling Set.</param>\r\n        [Theory]\r\n        [InlineData(null, \"after content\")]\r\n        [InlineData(\"i am a content\", \"and im another\")]\r\n        [InlineData(\"copy paste\", \"copy paste\")]\r\n        public void SimpleFileResource_Set_Content(string? preSetContent, string postSetContent)\r\n        {\r\n            var processorEnv = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            // Doesn't create a file.\r\n            using var tmpFile = new TempFile();\r\n            if (preSetContent is not null)\r\n            {\r\n                tmpFile.CreateFile(preSetContent);\r\n            }\r\n\r\n            var settings = new ValueSet\r\n            {\r\n                { \"Path\", tmpFile.FullFileName },\r\n                { \"Ensure\", \"Present\" },\r\n                { \"Content\", postSetContent },\r\n            };\r\n\r\n            var dscModule = new DscModuleV2();\r\n            using PowerShell pwsh = PowerShell.Create(processorEnv.Runspace);\r\n            dscModule.InvokeSetResource(\r\n                pwsh,\r\n                settings,\r\n                TestModule.SimpleFileResourceName,\r\n                PowerShellHelpers.CreateModuleSpecification(\r\n                    TestModule.SimpleTestResourceModuleName));\r\n\r\n            Assert.Equal(\r\n                postSetContent,\r\n                File.ReadAllText(tmpFile.FullFileName));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test SimpleFileResource Get.\r\n        /// </summary>\r\n        [Fact]\r\n        public void SimpleFileResource_Get()\r\n        {\r\n            var processorEnv = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            string content = \"I'm out of ideas\";\r\n            using var tmpFile = new TempFile(content: content);\r\n\r\n            var settings = new ValueSet\r\n            {\r\n                { \"Path\", tmpFile.FullFileName },\r\n            };\r\n\r\n            var dscModule = new DscModuleV2();\r\n            using PowerShell pwsh = PowerShell.Create(processorEnv.Runspace);\r\n            var properties = dscModule.InvokeGetResource(\r\n                                pwsh,\r\n                                settings,\r\n                                TestModule.SimpleFileResourceName,\r\n                                PowerShellHelpers.CreateModuleSpecification(\r\n                                    TestModule.SimpleTestResourceModuleName));\r\n\r\n            Assert.True(properties.ContainsKey(\"Path\"));\r\n            Assert.True(properties.TryGetValue(\"Path\", out object pathResult));\r\n            Assert.Equal(tmpFile.FullFileName, pathResult as string);\r\n\r\n            // Present is just the default value.\r\n            Assert.True(properties.ContainsKey(\"Ensure\"));\r\n            Assert.True(properties.TryGetValue(\"Ensure\", out object ensureResult));\r\n            Assert.Equal(\"Present\", ensureResult as string);\r\n\r\n            Assert.True(properties.ContainsKey(\"Content\"));\r\n            Assert.True(properties.TryGetValue(\"Content\", out object contentResult));\r\n            Assert.Equal(content, contentResult);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/DscModuleV2Tests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"DscModuleV2Tests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System;\r\n    using System.IO;\r\n    using System.Management.Automation;\r\n    using Microsoft.Management.Configuration.Processor.Exceptions;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.DscModules;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.Helpers;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using Microsoft.PowerShell.Commands;\r\n    using Windows.Foundation.Collections;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n    using static Microsoft.Management.Configuration.UnitTests.Helpers.PowerShellTestsConstants;\r\n\r\n    /// <summary>\r\n    /// Tests DscModuleV2 with really simple resources.\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [InProc]\r\n    public class DscModuleV2Tests\r\n    {\r\n        private readonly UnitTestFixture fixture;\r\n        private readonly ITestOutputHelper log;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"DscModuleV2Tests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Fixture.</param>\r\n        /// <param name=\"log\">log.</param>\r\n        public DscModuleV2Tests(UnitTestFixture fixture, ITestOutputHelper log)\r\n        {\r\n            this.fixture = fixture;\r\n            this.log = log;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests GetAllDscResources.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetAllDscResources_Test()\r\n        {\r\n            var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            var dscModule = new DscModuleV2();\r\n            using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n            var resources = dscModule.GetAllDscResources(pwsh);\r\n\r\n            Assert.True(resources.Count > 0);\r\n            Assert.Contains(resources, r => r.Name == TestModule.SimpleFileResourceName);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests GetDscResourcesInModule.\r\n        /// </summary>\r\n        /// <param name=\"module\">Module.</param>\r\n        /// <param name=\"expectedResources\">Expected DSC resources.</param>\r\n        [Theory]\r\n        [InlineData(TestModule.SimpleTestResourceModuleName, 5)]\r\n        [InlineData(\"MyReallyFakeModule\", 0)]\r\n        public void GetDscResourcesInModule_Test(string module, int expectedResources)\r\n        {\r\n            var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            var dscModule = new DscModuleV2();\r\n            using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n            var resources = dscModule.GetDscResourcesInModule(\r\n                pwsh,\r\n                PowerShellHelpers.CreateModuleSpecification(module));\r\n            Assert.Equal(expectedResources, resources.Count);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests GetDscResourcesInModule with versions.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetDscResourcesInModule_VersionTest()\r\n        {\r\n            string newVersion = \"1.0.0.0\";\r\n            var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            // Get duplicated resources by creating a new directory and copy our modules.\r\n            // Change version and add them to the PSModulePath.\r\n            using var tmpDir = new TempDirectory();\r\n            tmpDir.CopyDirectory(this.fixture.TestModulesPath);\r\n            var manifestFile = Path.Combine(\r\n                tmpDir.FullDirectoryPath,\r\n                TestModule.SimpleTestResourceModuleName,\r\n                TestModule.SimpleTestResourceManifestFileName);\r\n            File.WriteAllText(\r\n                manifestFile,\r\n                File.ReadAllText(manifestFile).Replace(\"0.0.0.1\", newVersion));\r\n            testEnvironment.AppendPSModulePath(tmpDir.FullDirectoryPath);\r\n\r\n            var dscModule = new DscModuleV2();\r\n\r\n            // This doesn't work on v2\r\n            ////var allResources = dscModule.GetDscResourcesInModule(\r\n            ////    testEnvironment.Runspace,\r\n            ////    PowerShellHelpers.CreateModuleSpecification(TestModule.SimpleTestResourceModuleName));\r\n            ////Assert.Equal(8, allResources.Count);\r\n            {\r\n                using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n                var ogResources = dscModule.GetDscResourcesInModule(\r\n                pwsh,\r\n                PowerShellHelpers.CreateModuleSpecification(\r\n                    TestModule.SimpleTestResourceModuleName,\r\n                    version: TestModule.SimpleTestResourceVersion));\r\n                Assert.Equal(5, ogResources.Count);\r\n            }\r\n\r\n            {\r\n                using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n                var newVersionResources = dscModule.GetDscResourcesInModule(\r\n                    pwsh,\r\n                    PowerShellHelpers.CreateModuleSpecification(\r\n                        TestModule.SimpleTestResourceModuleName,\r\n                        version: newVersion));\r\n                Assert.Equal(5, newVersionResources.Count);\r\n            }\r\n\r\n            {\r\n                using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n                var badVersionResources = dscModule.GetDscResourcesInModule(\r\n                    pwsh,\r\n                    PowerShellHelpers.CreateModuleSpecification(\r\n                        TestModule.SimpleTestResourceModuleName,\r\n                        version: \"1.2.3.4\"));\r\n                Assert.Equal(0, badVersionResources.Count);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests GetDscResource. Should return a resource.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetDscResource_ResourceExists()\r\n        {\r\n            var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            var dscModule = new DscModuleV2();\r\n            using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n            var resource = dscModule.GetDscResource(\r\n                pwsh,\r\n                TestModule.SimpleTestResourceName,\r\n                PowerShellHelpers.CreateModuleSpecification(TestModule.SimpleTestResourceModuleName));\r\n\r\n            Assert.NotNull(resource);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test GetDscResource for a resource that doesn't exist.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetDscResource_ResourceDoesntExist()\r\n        {\r\n            var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            var dscModule = new DscModuleV2();\r\n            using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n            var resource = dscModule.GetDscResource(\r\n                pwsh,\r\n                \"FakeResourceName\",\r\n                PowerShellHelpers.CreateModuleSpecification(\r\n                    TestModule.SimpleTestResourceModuleName));\r\n            Assert.Null(resource);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test GetDscResource when the same module is in different paths.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetDscResource_Conflict()\r\n        {\r\n            var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            // Get duplicated resources by creating a new directory and copy our modules.\r\n            // Then add it to the PSModulePath.\r\n            using var tmpDir = new TempDirectory();\r\n            tmpDir.CopyDirectory(this.fixture.TestModulesPath);\r\n            testEnvironment.AppendPSModulePath(tmpDir.FullDirectoryPath);\r\n\r\n            var dscModule = new DscModuleV2();\r\n            using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n            Assert.Throws<GetDscResourceModuleConflict>(\r\n                () => dscModule.GetDscResource(\r\n                    pwsh,\r\n                    TestModule.SimpleTestResourceName,\r\n                    PowerShellHelpers.CreateModuleSpecification(\r\n                        TestModule.SimpleTestResourceModuleName)));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests GetDscResource when there are multiple versions of a resource.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetDscResource_DiffVersions()\r\n        {\r\n            string newVersion = \"2.0.0.0\";\r\n            var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            // Get duplicated resources by creating a new directory and copy our modules.\r\n            // Change version and add them to the PSModulePath.\r\n            using var tmpDir = new TempDirectory();\r\n            tmpDir.CopyDirectory(this.fixture.TestModulesPath);\r\n            var manifestFile = Path.Combine(\r\n                tmpDir.FullDirectoryPath,\r\n                TestModule.SimpleTestResourceModuleName,\r\n                TestModule.SimpleTestResourceManifestFileName);\r\n            File.WriteAllText(\r\n                manifestFile,\r\n                File.ReadAllText(manifestFile).Replace(\"0.0.0.1\", newVersion));\r\n            testEnvironment.AppendPSModulePath(tmpDir.FullDirectoryPath);\r\n\r\n            var dscModule = new DscModuleV2();\r\n\r\n            // specific version.\r\n            {\r\n                using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n                var resource = dscModule.GetDscResource(\r\n                    pwsh,\r\n                    TestModule.SimpleTestResourceName,\r\n                    PowerShellHelpers.CreateModuleSpecification(\r\n                        TestModule.SimpleTestResourceModuleName,\r\n                        TestModule.SimpleTestResourceVersion));\r\n                Assert.NotNull(resource);\r\n            }\r\n\r\n            {\r\n                using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n                var dsc = dscModule.GetDscResource(\r\n                    pwsh,\r\n                    TestModule.SimpleTestResourceName,\r\n                    PowerShellHelpers.CreateModuleSpecification(\r\n                        TestModule.SimpleTestResourceModuleName,\r\n                        version: newVersion));\r\n\r\n                Assert.NotNull(dsc);\r\n                Assert.NotNull(dsc.Version);\r\n                Assert.Equal(newVersion, dsc.Version.ToString());\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls Invoke-DscResource Get.\r\n        /// </summary>\r\n        [Fact]\r\n        public void InvokeGetResource_Test()\r\n        {\r\n            var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            var dscModule = new DscModuleV2();\r\n            using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n            var getResult = dscModule.InvokeGetResource(\r\n                pwsh,\r\n                new ValueSet(),\r\n                TestModule.SimpleTestResourceName,\r\n                PowerShellHelpers.CreateModuleSpecification(\r\n                    TestModule.SimpleTestResourceModuleName));\r\n\r\n            Assert.True(getResult.ContainsKey(\"key\"));\r\n            Assert.True(getResult.TryGetValue(\"key\", out object keyValue));\r\n            Assert.Equal(\"SimpleTestResourceKey\", keyValue as string);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls Invoke-DscResource Get. Resource Get throws.\r\n        /// </summary>\r\n        [Fact]\r\n        public void InvokeGetResource_ResourceThrows()\r\n        {\r\n            var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            var dscModule = new DscModuleV2();\r\n\r\n            using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n            var exception = Assert.Throws<InvokeDscResourceException>(() =>\r\n                dscModule.InvokeGetResource(\r\n                    pwsh,\r\n                    new ValueSet(),\r\n                    TestModule.SimpleTestResourceThrowsName,\r\n                    PowerShellHelpers.CreateModuleSpecification(\r\n                        TestModule.SimpleTestResourceModuleName)));\r\n\r\n            Assert.IsType<RuntimeException>(exception.InnerException);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls Invoke-DscResource Get. Resource writes error.\r\n        /// </summary>\r\n        [Fact(Skip = \"Not supported in PSDesiredStateConfiguration 2.0.7\")]\r\n        public void InvokeGetResource_ResourceError()\r\n        {\r\n            var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            var dscModule = new DscModuleV2();\r\n            using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n            Assert.Throws<WriteErrorException>(() =>\r\n                dscModule.InvokeGetResource(\r\n                    pwsh,\r\n                    new ValueSet(),\r\n                    TestModule.SimpleTestResourceErrorName,\r\n                    PowerShellHelpers.CreateModuleSpecification(\r\n                        TestModule.SimpleTestResourceModuleName)));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls Invoke-DscResource Get. Resource does not exist.\r\n        /// </summary>\r\n        [Fact]\r\n        public void InvokeGetResource_ResourceDoesntExist()\r\n        {\r\n            var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            var dscModule = new DscModuleV2();\r\n            using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n            var exception = Assert.Throws<InvokeDscResourceException>(\r\n                () => dscModule.InvokeGetResource(\r\n                    pwsh,\r\n                    new ValueSet(),\r\n                    \"FakeResourceName\",\r\n                    PowerShellHelpers.CreateModuleSpecification(\r\n                        TestModule.SimpleTestResourceModuleName)));\r\n\r\n            Assert.IsType<RuntimeException>(exception.InnerException);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls Invoke-DscResource Test.\r\n        /// </summary>\r\n        /// <param name=\"value\">Setting value.</param>\r\n        /// <param name=\"expectedResult\">Expected result.</param>\r\n        [Theory]\r\n        [InlineData(\"4815162342\", true)]\r\n        [InlineData(\"notalostreference\", false)]\r\n        public void InvokeTestResource_Test(string value, bool expectedResult)\r\n        {\r\n            var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            var dscModule = new DscModuleV2();\r\n\r\n            var settings = new ValueSet()\r\n            {\r\n                { \"secretCode\", value },\r\n            };\r\n\r\n            using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n            var testResult = dscModule.InvokeTestResource(\r\n                pwsh,\r\n                settings,\r\n                TestModule.SimpleTestResourceName,\r\n                PowerShellHelpers.CreateModuleSpecification(\r\n                        TestModule.SimpleTestResourceModuleName));\r\n\r\n            Assert.Equal(expectedResult, testResult);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls Invoke-DscResource Test. Resource throws.\r\n        /// </summary>\r\n        [Fact]\r\n        public void InvokeTestResource_Throws()\r\n        {\r\n            var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            var dscModule = new DscModuleV2();\r\n            using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n            var exception = Assert.Throws<InvokeDscResourceException>(() =>\r\n                dscModule.InvokeTestResource(\r\n                    pwsh,\r\n                    new ValueSet(),\r\n                    TestModule.SimpleTestResourceThrowsName,\r\n                    PowerShellHelpers.CreateModuleSpecification(\r\n                        TestModule.SimpleTestResourceModuleName)));\r\n\r\n            Assert.IsType<RuntimeException>(exception.InnerException);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls Invoke-DscResource Test. Resource writes error.\r\n        /// </summary>\r\n        [Fact(Skip = \"Not supported in PSDesiredStateConfiguration 2.0.7\")]\r\n        public void InvokeTestResource_ResourceError()\r\n        {\r\n            var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            var dscModule = new DscModuleV2();\r\n            using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n            Assert.Throws<WriteErrorException>(() =>\r\n                dscModule.InvokeTestResource(\r\n                    pwsh,\r\n                    new ValueSet(),\r\n                    TestModule.SimpleTestResourceErrorName,\r\n                    PowerShellHelpers.CreateModuleSpecification(\r\n                        TestModule.SimpleTestResourceModuleName)));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls Invoke-DscResource Test. Resource does not exist.\r\n        /// </summary>\r\n        [Fact]\r\n        public void InvokeTestResource_ResourceDoesntExist()\r\n        {\r\n            var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            var dscModule = new DscModuleV2();\r\n            using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n            var exception = Assert.Throws<InvokeDscResourceException>(() =>\r\n                _ = dscModule.InvokeTestResource(\r\n                    pwsh,\r\n                    new ValueSet(),\r\n                    \"FakeResourceName\",\r\n                    PowerShellHelpers.CreateModuleSpecification(\r\n                        TestModule.SimpleTestResourceModuleName)));\r\n\r\n            Assert.IsType<RuntimeException>(exception.InnerException);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls Invoke-DscResource Set.\r\n        /// </summary>\r\n        /// <param name=\"value\">Setting value.</param>\r\n        /// <param name=\"rebootRequired\">Expected reboot required.</param>\r\n        [Fact]\r\n        public void InvokeSetResource_Test()\r\n        {\r\n            var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            var dscModule = new DscModuleV2();\r\n\r\n            var settings = new ValueSet()\r\n            {\r\n                { \"secretCode\", \"4815162342\" },\r\n            };\r\n\r\n            using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n            var testResult = dscModule.InvokeSetResource(\r\n                pwsh,\r\n                settings,\r\n                TestModule.SimpleTestResourceName,\r\n                PowerShellHelpers.CreateModuleSpecification(\r\n                    TestModule.SimpleTestResourceModuleName));\r\n\r\n            // TODO: Verify reboot required when is supported for class resources.\r\n            ////Assert.Equal(rebootRequired, testResult);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls Invoke-DscResource Set. Resource throws.\r\n        /// </summary>\r\n        [Fact]\r\n        public void InvokeSetResource_Throws()\r\n        {\r\n            var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            var dscModule = new DscModuleV2();\r\n            using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n            var exception = Assert.Throws<InvokeDscResourceException>(() =>\r\n                dscModule.InvokeSetResource(\r\n                    pwsh,\r\n                    new ValueSet(),\r\n                    TestModule.SimpleTestResourceThrowsName,\r\n                    PowerShellHelpers.CreateModuleSpecification(\r\n                        TestModule.SimpleTestResourceModuleName)));\r\n\r\n            Assert.IsType<RuntimeException>(exception.InnerException);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls Invoke-DscResource Set. Resource writes error.\r\n        /// </summary>\r\n        [Fact(Skip = \"Not supported in PSDesiredStateConfiguration 2.0.7\")]\r\n        public void InvokeSetResource_ResourceError()\r\n        {\r\n            var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            var dscModule = new DscModuleV2();\r\n            using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n            Assert.Throws<WriteErrorException>(() =>\r\n                dscModule.InvokeSetResource(\r\n                    pwsh,\r\n                    new ValueSet(),\r\n                    TestModule.SimpleTestResourceErrorName,\r\n                    PowerShellHelpers.CreateModuleSpecification(\r\n                        TestModule.SimpleTestResourceModuleName)));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls Invoke-DscResource Set. Resource does not exist.\r\n        /// </summary>\r\n        [Fact]\r\n        public void InvokeSetResource_ResourceDoesntExist()\r\n        {\r\n            var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            var dscModule = new DscModuleV2();\r\n            using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n            var exception = Assert.Throws<InvokeDscResourceException>(() =>\r\n                dscModule.InvokeSetResource(\r\n                    pwsh,\r\n                    new ValueSet(),\r\n                    \"FakeResourceName\",\r\n                    PowerShellHelpers.CreateModuleSpecification(\r\n                        TestModule.SimpleTestResourceModuleName)));\r\n\r\n            Assert.IsType<RuntimeException>(exception.InnerException);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test calling Invoke-DscResource when a resource has multiple versions.\r\n        /// </summary>\r\n        [Fact]\r\n        public void InvokeResource_MultipleVersions()\r\n        {\r\n            string newVersion = \"0.0.2.0\";\r\n            var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            // Get duplicated resources by creating a new directory and copy our modules.\r\n            // Change version and add them to the PSModulePath.\r\n            using var tmpDir = new TempDirectory();\r\n            tmpDir.CopyDirectory(this.fixture.TestModulesPath);\r\n            var manifestFile = Path.Combine(\r\n                tmpDir.FullDirectoryPath,\r\n                TestModule.SimpleTestResourceModuleName,\r\n                TestModule.SimpleTestResourceManifestFileName);\r\n            File.WriteAllText(\r\n                manifestFile,\r\n                File.ReadAllText(manifestFile).Replace(\"0.0.0.1\", newVersion));\r\n            testEnvironment.AppendPSModulePath(tmpDir.FullDirectoryPath);\r\n\r\n            var dscModule = new DscModuleV2();\r\n            {\r\n                using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n                dscModule.InvokeSetResource(\r\n                    pwsh,\r\n                    new ValueSet(),\r\n                    TestModule.SimpleTestResourceName,\r\n                    PowerShellHelpers.CreateModuleSpecification(\r\n                        TestModule.SimpleTestResourceModuleName,\r\n                        TestModule.SimpleTestResourceVersion));\r\n            }\r\n\r\n            {\r\n                using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n                dscModule.InvokeSetResource(\r\n                    pwsh,\r\n                    new ValueSet(),\r\n                    TestModule.SimpleTestResourceName,\r\n                    PowerShellHelpers.CreateModuleSpecification(\r\n                        TestModule.SimpleTestResourceModuleName,\r\n                        version: newVersion));\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls Invoke-DscResource invalid arguments.\r\n        /// </summary>\r\n        [Fact]\r\n        public void InvokeSetResource_InvalidArguments()\r\n        {\r\n            var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            var dscModule = new DscModuleV2();\r\n\r\n            var settings = new ValueSet()\r\n            {\r\n                { \"Fake\", \"please dont add it\" },\r\n            };\r\n\r\n            using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n            var e = Assert.Throws<InvokeDscResourceException>(() => dscModule.InvokeSetResource(\r\n                pwsh,\r\n                settings,\r\n                TestModule.SimpleTestResourceName,\r\n                PowerShellHelpers.CreateModuleSpecification(\r\n                    TestModule.SimpleTestResourceModuleName)));\r\n\r\n            Assert.Contains(\"The property 'Fake' cannot be found on this object.\", e.Message);\r\n            Assert.Equal(ConfigurationUnitResultSource.ConfigurationSet, e.ResultSource);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests GetDscResourcesInModule with versions.\r\n        /// </summary>\r\n        [Fact]\r\n        public void InvokeSetResource_ModulePathSpaces()\r\n        {\r\n            // Copy test module to a directory with spaces.\r\n            using var tmpDir = new TempDirectory(directoryName: Path.Combine(Guid.NewGuid().ToString(), \"Path With Spaces\"));\r\n            tmpDir.CopyDirectory(this.fixture.TestModulesPath);\r\n            var manifestFile = Path.Combine(\r\n                tmpDir.FullDirectoryPath,\r\n                TestModule.SimpleTestResourceModuleName,\r\n                TestModule.SimpleTestResourceManifestFileName);\r\n\r\n            var testEnvironment = this.fixture.PrepareTestProcessorEnvironment();\r\n            testEnvironment.CleanupPSModulePath(this.fixture.TestModulesPath);\r\n            testEnvironment.AppendPSModulePath(tmpDir.FullDirectoryPath);\r\n\r\n            var dscModule = new DscModuleV2();\r\n\r\n            var settings = new ValueSet()\r\n            {\r\n                { \"secretCode\", \"4815162342\" },\r\n            };\r\n\r\n            using PowerShell pwsh = PowerShell.Create(testEnvironment.Runspace);\r\n            var testResult = dscModule.InvokeSetResource(\r\n                pwsh,\r\n                settings,\r\n                TestModule.SimpleTestResourceName,\r\n                PowerShellHelpers.CreateModuleSpecification(\r\n                    TestModule.SimpleTestResourceModuleName));\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/DscResourceMapTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"DscResourceMapTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.DscResourcesInfo;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.Helpers;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n\r\n    /// <summary>\r\n    /// DscResourceMap tests.\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [InProc]\r\n    public class DscResourceMapTests\r\n    {\r\n        private const string ResourceZoro = \"xResourceZoro\";\r\n\r\n        private const string ModuleMugiwara = \"xMugiwaraModule\";\r\n        private const string ModuleMugiwaraResourceLuffy = \"xResourceLuffy\";\r\n\r\n        private const string ModuleOni = \"xModuleOni\";\r\n        private const string ModuleOniResourceKaido = \"xResourceKaido\";\r\n        private const string ModuleOniResourceYamato = \"xResourceYamato\";\r\n\r\n        private static readonly Version VersionZoro = new Version(\"1.0.0.0\");\r\n\r\n        private static readonly Version VersionLuffyGear4 = new Version(\"4.0.0.1\");\r\n        private static readonly Version VersionLuffyGear5 = new Version(\"5.0.0.0\");\r\n\r\n        private static readonly Version VersionKaido = new Version(\"0.0.0.4\");\r\n        private static readonly Version VersionYamato = new Version(\"0.0.0.11\");\r\n\r\n        private readonly UnitTestFixture fixture;\r\n        private readonly ITestOutputHelper log;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"DscResourceMapTests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Unit test fixture.</param>\r\n        /// <param name=\"log\">Log.</param>\r\n        public DscResourceMapTests(UnitTestFixture fixture, ITestOutputHelper log)\r\n        {\r\n            this.fixture = fixture;\r\n            this.log = log;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test GetResource for resources in the map.\r\n        /// </summary>\r\n        [Fact]\r\n        public void DscResourcesMap_GetResource()\r\n        {\r\n            var dscResourceMap = new DscResourcesMap(this.CreateDscResourceInfo());\r\n\r\n            // Get just by name.\r\n            var zoroResult = dscResourceMap.GetResource(ResourceZoro, null, null);\r\n            Assert.NotNull(zoroResult);\r\n            Assert.Equal(ResourceZoro, zoroResult.Name);\r\n            Assert.Equal(VersionZoro, zoroResult.Version);\r\n\r\n            // Name not normalized.\r\n            var zoroResultNormalize = dscResourceMap.GetResource(\"XRESOURCEZORO\", null, null);\r\n            Assert.NotNull(zoroResultNormalize);\r\n            Assert.Equal(ResourceZoro, zoroResultNormalize.Name);\r\n            Assert.Equal(VersionZoro, zoroResultNormalize.Version);\r\n\r\n            var yamatoResult = dscResourceMap.GetResource(ModuleOniResourceYamato, null, null);\r\n            Assert.NotNull(yamatoResult);\r\n            Assert.Equal(ModuleOniResourceYamato, yamatoResult.Name);\r\n            Assert.Equal(ModuleOni, yamatoResult.ModuleName);\r\n            Assert.Equal(VersionYamato, yamatoResult.Version);\r\n\r\n            // Just by name and module get latest.\r\n            var luffyResult5 = dscResourceMap.GetResource(ModuleMugiwaraResourceLuffy, ModuleMugiwara, null);\r\n            Assert.NotNull(luffyResult5);\r\n            Assert.Equal(ModuleMugiwaraResourceLuffy, luffyResult5.Name);\r\n            Assert.Equal(ModuleMugiwara, luffyResult5.ModuleName);\r\n            Assert.Equal(VersionLuffyGear5, luffyResult5.Version);\r\n\r\n            // Specific version.\r\n            var luffyResult4 = dscResourceMap.GetResource(ModuleMugiwaraResourceLuffy, ModuleMugiwara, VersionLuffyGear4);\r\n            Assert.NotNull(luffyResult4);\r\n            Assert.Equal(ModuleMugiwaraResourceLuffy, luffyResult4.Name);\r\n            Assert.Equal(ModuleMugiwara, luffyResult4.ModuleName);\r\n            Assert.Equal(VersionLuffyGear4, luffyResult4.Version);\r\n\r\n            // Module name not normalized\r\n            var luffyResult4Normalized = dscResourceMap.GetResource(ModuleMugiwaraResourceLuffy, \"XMUGIWARAMODULE\", VersionLuffyGear4);\r\n            Assert.NotNull(luffyResult4Normalized);\r\n            Assert.Equal(ModuleMugiwaraResourceLuffy, luffyResult4Normalized.Name);\r\n            Assert.Equal(ModuleMugiwara, luffyResult4Normalized.ModuleName);\r\n            Assert.Equal(VersionLuffyGear4, luffyResult4Normalized.Version);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests GetResource when resources are not in the maps.\r\n        /// </summary>\r\n        [Fact]\r\n        public void DscResourcesMap_GetResource_NoResource()\r\n        {\r\n            var dscResourceMap = new DscResourcesMap(this.CreateDscResourceInfo());\r\n\r\n            // Zoro is lost.\r\n            var zoroResult = dscResourceMap.GetResource(ResourceZoro, ModuleMugiwara, null);\r\n            Assert.Null(zoroResult);\r\n\r\n            // Yamato didn't join (spoilers)\r\n            var yamatoResult = dscResourceMap.GetResource(ModuleOniResourceYamato, ModuleMugiwara, VersionYamato);\r\n            Assert.Null(yamatoResult);\r\n\r\n            // Gear 6 is not a thing (?)\r\n            var luffyResult = dscResourceMap.GetResource(ModuleMugiwaraResourceLuffy, ModuleMugiwara, Version.Parse(\"6.0.0.0\"));\r\n            Assert.Null(luffyResult);\r\n\r\n            // Wrong universe.\r\n            var gokuResult = dscResourceMap.GetResource(\"xResourceGoku\", null, null);\r\n            Assert.Null(gokuResult);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test Exists for resources in the map.\r\n        /// </summary>\r\n        [Fact]\r\n        public void DscResourcesMap_Exists()\r\n        {\r\n            var dscResourceMap = new DscResourcesMap(this.CreateDscResourceInfo());\r\n\r\n            Assert.True(dscResourceMap.Exists(ResourceZoro, null, null));\r\n            Assert.True(dscResourceMap.Exists(ModuleOniResourceYamato, null, null));\r\n            Assert.True(dscResourceMap.Exists(ModuleMugiwaraResourceLuffy, ModuleMugiwara, null));\r\n            Assert.True(dscResourceMap.Exists(ModuleMugiwaraResourceLuffy, ModuleMugiwara, VersionLuffyGear4));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests Exists when resources are not in the maps.\r\n        /// </summary>\r\n        [Fact]\r\n        public void DscResourcesMap_Exists_NoResource()\r\n        {\r\n            var dscResourceMap = new DscResourcesMap(this.CreateDscResourceInfo());\r\n\r\n            Assert.False(dscResourceMap.Exists(ResourceZoro, ModuleMugiwara, null));\r\n            Assert.False(dscResourceMap.Exists(ModuleOniResourceYamato, ModuleMugiwara, VersionYamato));\r\n            Assert.False(dscResourceMap.Exists(ModuleMugiwaraResourceLuffy, ModuleMugiwara, Version.Parse(\"6.0.0.0\")));\r\n            Assert.False(dscResourceMap.Exists(\"xResourceGoku\", null, null));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates 5 fake resources.\r\n        /// 1 resource without module name.\r\n        /// 2 resources module A same resource v1 v2.\r\n        /// 2 resources module B different resources.\r\n        /// </summary>\r\n        /// <returns>Fake resources.</returns>\r\n        private IReadOnlyList<DscResourceInfoInternal> CreateDscResourceInfo()\r\n        {\r\n            return new List<DscResourceInfoInternal>()\r\n            {\r\n                new DscResourceInfoInternal(ResourceZoro, null, VersionZoro),\r\n\r\n                new DscResourceInfoInternal(ModuleMugiwaraResourceLuffy, ModuleMugiwara, VersionLuffyGear4),\r\n                new DscResourceInfoInternal(ModuleMugiwaraResourceLuffy, ModuleMugiwara, VersionLuffyGear5),\r\n\r\n                new DscResourceInfoInternal(ModuleOniResourceKaido, ModuleOni, VersionKaido),\r\n                new DscResourceInfoInternal(ModuleOniResourceYamato, ModuleOni, VersionYamato),\r\n            };\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/ExceptionExtensionsTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ExceptionExtensionsTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System;\r\n    using Microsoft.Management.Configuration.Processor.Extensions;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using Microsoft.PowerShell.Commands;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n\r\n    /// <summary>\r\n    /// Exception extension tests.\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [InProc]\r\n    public class ExceptionExtensionsTests\r\n    {\r\n        private readonly UnitTestFixture fixture;\r\n        private readonly ITestOutputHelper log;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ExceptionExtensionsTests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Unit test fixture.</param>\r\n        /// <param name=\"log\">Log helper.</param>\r\n        public ExceptionExtensionsTests(UnitTestFixture fixture, ITestOutputHelper log)\r\n        {\r\n            this.fixture = fixture;\r\n            this.log = log;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests GetMostInnerException.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetMostInnerException_Test()\r\n        {\r\n            var exception = new Exception(\r\n                \"message1\",\r\n                new WriteErrorException(\r\n                    \"WriteException\",\r\n                    new ArgumentNullException()));\r\n\r\n            var mostInner = exception.GetMostInnerException();\r\n            Assert.IsType<ArgumentNullException>(mostInner);\r\n\r\n            var exception2 = new Exception(\r\n                \"message2\",\r\n                new WriteErrorException(\r\n                    \"WriteException2\"));\r\n\r\n            mostInner = exception2.GetMostInnerException();\r\n            Assert.IsType<WriteErrorException>(mostInner);\r\n\r\n            var exception3 = new ArgumentOutOfRangeException(\"message2\");\r\n            mostInner = exception3.GetMostInnerException();\r\n            Assert.IsType<ArgumentOutOfRangeException>(mostInner);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/HashtableExtensionsTests.cs",
    "content": "// -----------------------------------------------------------------------------\n// <copyright file=\"HashtableExtensionsTests.cs\" company=\"Microsoft Corporation\">\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\n// </copyright>\n// -----------------------------------------------------------------------------\n\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\n{\n    using System.Collections;\n    using Microsoft.Management.Configuration.Processor.Exceptions;\n    using Microsoft.Management.Configuration.Processor.Extensions;\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using Windows.Foundation.Collections;\n    using Xunit;\n    using Xunit.Abstractions;\n\n    /// <summary>\n    /// Hashtable extension tests.\n    /// </summary>\n    [Collection(\"UnitTestCollection\")]\r\n    [InProc]\n    public class HashtableExtensionsTests\n    {\n        private readonly UnitTestFixture fixture;\n        private readonly ITestOutputHelper log;\n\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"HashtableExtensionsTests\"/> class.\n        /// </summary>\n        /// <param name=\"fixture\">Unit test fixture.</param>\n        /// <param name=\"log\">Log helper.</param>\n        public HashtableExtensionsTests(UnitTestFixture fixture, ITestOutputHelper log)\n        {\n            this.fixture = fixture;\n            this.log = log;\n        }\n\n        /// <summary>\n        /// Tests ToValueSet with simple types.\n        /// </summary>\n        [Fact]\n        public void ToValueSet_Test()\n        {\n            var ht = new Hashtable()\n            {\n                { \"key1\", \"value1\" },\n                { \"key2\", 2 },\n                { \"key3\", true },\n            };\n\n            var valueSet = ht.ToValueSet();\n\n            Assert.True(valueSet.ContainsKey(\"key1\"));\n            Assert.Equal(\"value1\", (string)valueSet[\"key1\"]);\n\n            Assert.True(valueSet.ContainsKey(\"key2\"));\n            Assert.Equal(2, (int)valueSet[\"key2\"]);\n\n            Assert.True(valueSet.ContainsKey(\"key3\"));\n            Assert.True((bool)valueSet[\"key3\"]);\n        }\n\n        /// <summary>\n        /// Test for inner hashtables.\n        /// </summary>\n        [Fact]\n        public void ToValueSet_InnerHashtable()\n        {\n            var ht = new Hashtable()\n            {\n                {\r\n                    \"hashtableKey\", new Hashtable()\n                    {\n                        { \"key1\", \"value1\" },\n                        { \"key2\", 2 },\n                        { \"key3\", true },\n                    }\n                },\n            };\n\n            var valueSet = ht.ToValueSet();\n\n            Assert.True(valueSet.ContainsKey(\"hashtableKey\"));\n            var resultValueSet = (ValueSet)valueSet[\"hashtableKey\"];\n\n            Assert.True(resultValueSet.ContainsKey(\"key1\"));\n            Assert.Equal(\"value1\", (string)resultValueSet[\"key1\"]);\n\n            Assert.True(resultValueSet.ContainsKey(\"key2\"));\n            Assert.Equal(2, (int)resultValueSet[\"key2\"]);\n\n            Assert.True(resultValueSet.ContainsKey(\"key3\"));\n            Assert.True((bool)resultValueSet[\"key3\"]);\n        }\n\n        /// <summary>\n        /// Test for inner arrays.\n        /// </summary>\n        [Fact]\n        public void ToValueSet_InnerArray()\n        {\n            var ht = new Hashtable()\n            {\n                {\n                    \"arrayKey\", new string[]\n                    {\n                        \"s1\",\n                        \"s2\",\n                        \"s3\",\n                    }\n                },\n            };\n\n            var valueSet = ht.ToValueSet();\n\n            Assert.True(valueSet.ContainsKey(\"arrayKey\"));\n            var resultValueSet = (ValueSet)valueSet[\"arrayKey\"];\n            Assert.True(resultValueSet.ContainsKey(\"treatAsArray\"));\n            Assert.Equal(4, resultValueSet.Count);\n        }\n\n        /// <summary>\n        /// Test when a key is not a string.\n        /// </summary>\n        [Fact]\n        public void ToValueSet_KeyNotString()\n        {\n            var ht = new Hashtable()\n            {\n                { 1, \"value\" },\n            };\n\n            Assert.Throws<UnitPropertyUnsupportedException>(() => ht.ToValueSet());\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/OpenConfigurationSetTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"OpenConfigurationSetTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.DirectoryServices;\r\n    using Microsoft.Management.Configuration.Processor.Extensions;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using Microsoft.VisualBasic;\r\n    using Windows.Foundation.Collections;\r\n    using Windows.Storage.Streams;\r\n    using WinRT;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n\r\n    /// <summary>\r\n    /// Unit tests for parsing configuration sets from streams.\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [InProc]\r\n    [OutOfProc]\r\n    public class OpenConfigurationSetTests : ConfigurationProcessorTestBase\r\n    {\r\n        /// <summary>\r\n        /// The directives key for the module property.\r\n        /// </summary>\r\n        internal const string ModuleDirective = \"module\";\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"OpenConfigurationSetTests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Unit test fixture.</param>\r\n        /// <param name=\"log\">Log helper.</param>\r\n        public OpenConfigurationSetTests(UnitTestFixture fixture, ITestOutputHelper log)\r\n            : base(fixture, log)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Passes a null stream as input.\r\n        /// </summary>\r\n        [Fact]\r\n        public void NullStream()\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult result = processor.OpenConfigurationSet(null);\r\n            Assert.Null(result.Set);\r\n            Assert.IsType<NullReferenceException>(result.ResultCode);\r\n            Assert.Equal(string.Empty, result.Field);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Passes an empty stream as input.\r\n        /// </summary>\r\n        [Fact]\r\n        public void EmptyStream()\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(string.Empty));\r\n            Assert.Null(result.Set);\r\n            Assert.NotNull(result.ResultCode);\r\n            Assert.Equal(Errors.WINGET_CONFIG_ERROR_INVALID_YAML, result.ResultCode.HResult);\r\n            Assert.Equal(string.Empty, result.Field);\r\n            Assert.Equal(0U, result.Line);\r\n            Assert.Equal(0U, result.Column);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Passes a stream with a single null byte in it.\r\n        /// </summary>\r\n        [Fact]\r\n        public void NullByteStream()\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(\"\\0\"));\r\n            Assert.Null(result.Set);\r\n            Assert.NotNull(result.ResultCode);\r\n            Assert.Equal(Errors.WINGET_CONFIG_ERROR_INVALID_YAML, result.ResultCode.HResult);\r\n            Assert.NotEqual(string.Empty, result.Field);\r\n            Assert.Equal(0U, result.Line);\r\n            Assert.Equal(0U, result.Column);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Passes YAML, but it isn't anything like a configuration file.\r\n        /// </summary>\r\n        [Fact]\r\n        public void NotConfigYAML()\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(\"yaml: yep\"));\r\n            Assert.Null(result.Set);\r\n            Assert.NotNull(result.ResultCode);\r\n            Assert.Equal(Errors.WINGET_CONFIG_ERROR_MISSING_FIELD, result.ResultCode.HResult);\r\n            Assert.Equal(\"$schema\", result.Field);\r\n            Assert.Equal(0U, result.Line);\r\n            Assert.Equal(0U, result.Column);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Passes YAML without a schema version.\r\n        /// </summary>\r\n        [Fact]\r\n        public void NoConfigVersion()\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(@\"\r\nproperties:\r\n  thing: 1\r\n\"));\r\n            Assert.Null(result.Set);\r\n            Assert.NotNull(result.ResultCode);\r\n            Assert.Equal(Errors.WINGET_CONFIG_ERROR_MISSING_FIELD, result.ResultCode.HResult);\r\n            Assert.Equal(\"configurationVersion\", result.Field);\r\n            Assert.Equal(0U, result.Line);\r\n            Assert.Equal(0U, result.Column);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Passes YAML that appears to be from the distant future.\r\n        /// </summary>\r\n        [Fact]\r\n        public void UnknownConfigVersion()\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(@\"\r\nproperties:\r\n  configurationVersion: 99999999\r\n\"));\r\n            Assert.Null(result.Set);\r\n            Assert.NotNull(result.ResultCode);\r\n            Assert.Equal(Errors.WINGET_CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION, result.ResultCode.HResult);\r\n            Assert.Equal(\"configurationVersion\", result.Field);\r\n            Assert.Equal(\"99999999\", result.Value);\r\n            Assert.Equal(0U, result.Line);\r\n            Assert.Equal(0U, result.Column);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Has one of each type of intent to ensure that it is set properly.\r\n        /// </summary>\r\n        [Fact]\r\n        public void EnsureIntent()\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(@\"\r\nproperties:\r\n  configurationVersion: 0.1\r\n  assertions:\r\n    - resource: Assert\r\n  parameters:\r\n    - resource: Inform\r\n  resources:\r\n    - resource: Apply\r\n\"));\r\n\r\n            Assert.NotNull(result.Set);\r\n            Assert.Null(result.ResultCode);\r\n            Assert.Equal(string.Empty, result.Field);\r\n\r\n            var units = result.Set.Units;\r\n            Assert.Equal(3, units.Count);\r\n            bool sawAssert = false;\r\n            bool sawInform = false;\r\n            bool sawApply = false;\r\n\r\n            foreach (var unit in units)\r\n            {\r\n                Assert.Equal(unit.Type, unit.Intent.ToString());\r\n                switch (unit.Intent)\r\n                {\r\n                    case ConfigurationUnitIntent.Assert: sawAssert = true; break;\r\n                    case ConfigurationUnitIntent.Inform: sawInform = true; break;\r\n                    case ConfigurationUnitIntent.Apply: sawApply = true; break;\r\n                    default: Assert.Fail(\"Unknown intent\"); break;\r\n                }\r\n            }\r\n\r\n            Assert.True(sawAssert);\r\n            Assert.True(sawInform);\r\n            Assert.True(sawApply);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Passes YAML with resources being something other than a sequence.\r\n        /// </summary>\r\n        [Fact]\r\n        public void NonSequenceUnits()\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(@\"\r\nproperties:\r\n  configurationVersion: 0.1\r\n  resources: 1\r\n\"));\r\n            Assert.Null(result.Set);\r\n            Assert.NotNull(result.ResultCode);\r\n            Assert.Equal(Errors.WINGET_CONFIG_ERROR_INVALID_FIELD_TYPE, result.ResultCode.HResult);\r\n            Assert.Equal(\"resources\", result.Field);\r\n            Assert.Equal(4U, result.Line);\r\n            Assert.NotEqual(0U, result.Column);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Passes YAML with a resource being something other than a map.\r\n        /// </summary>\r\n        [Fact]\r\n        public void NonMapSequenceUnits()\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(@\"\r\nproperties:\r\n  configurationVersion: 0.1\r\n  resources:\r\n    - string\r\n\"));\r\n            Assert.Null(result.Set);\r\n            Assert.NotNull(result.ResultCode);\r\n            Assert.Equal(Errors.WINGET_CONFIG_ERROR_INVALID_FIELD_TYPE, result.ResultCode.HResult);\r\n            Assert.Equal(\"resources[0]\", result.Field);\r\n            Assert.Equal(5U, result.Line);\r\n            Assert.NotEqual(0U, result.Column);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Passes YAML with all values present.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CheckAllUnitProperties()\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(@\"\r\nproperties:\r\n  configurationVersion: 0.1\r\n  resources:\r\n    - resource: Resource\r\n      id: Identifier\r\n      dependsOn:\r\n        - Dependency1\r\n        - Dependency2\r\n      directives:\r\n        Directive1: A\r\n        Directive2: B\r\n      settings:\r\n        Setting1: '1'\r\n        Setting2: 2\r\n\"));\r\n            Assert.NotNull(result.Set);\r\n            Assert.Null(result.ResultCode);\r\n            Assert.Equal(string.Empty, result.Field);\r\n\r\n            Assert.NotEqual(Guid.Empty, result.Set.InstanceIdentifier);\r\n\r\n            var units = result.Set.Units;\r\n            Assert.NotNull(units);\r\n            Assert.Equal(1, units.Count);\r\n\r\n            ConfigurationUnit unit = units[0];\r\n            Assert.NotNull(unit);\r\n            Assert.Equal(\"Resource\", unit.Type);\r\n            Assert.NotEqual(Guid.Empty, unit.InstanceIdentifier);\r\n            Assert.Equal(\"Identifier\", unit.Identifier);\r\n            Assert.Equal(ConfigurationUnitIntent.Apply, unit.Intent);\r\n\r\n            var dependencies = unit.Dependencies;\r\n            Assert.NotNull(dependencies);\r\n            Assert.Equal(2, dependencies.Count);\r\n            Assert.Contains(\"Dependency1\", dependencies);\r\n            Assert.Contains(\"Dependency2\", dependencies);\r\n\r\n            var directives = unit.Metadata;\r\n            Assert.NotNull(directives);\r\n            Assert.Equal(2, directives.Count);\r\n            Assert.Contains(\"Directive1\", directives);\r\n            Assert.Equal(\"A\", directives[\"Directive1\"]);\r\n            Assert.Contains(\"Directive2\", directives);\r\n            Assert.Equal(\"B\", directives[\"Directive2\"]);\r\n\r\n            var settings = unit.Settings;\r\n            Assert.NotNull(settings);\r\n            Assert.Equal(2, settings.Count);\r\n            Assert.Contains(\"Setting1\", settings);\r\n            Assert.Equal(\"1\", settings[\"Setting1\"]);\r\n            Assert.Contains(\"Setting2\", settings);\r\n            Assert.Equal(2L, settings[\"Setting2\"]);\r\n\r\n            Assert.Null(unit.Details);\r\n            Assert.Equal(ConfigurationUnitState.Unknown, unit.State);\r\n            Assert.Null(unit.ResultInformation);\r\n            Assert.True(unit.IsActive);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test type of scalar nodes.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CheckUnitScalarTypes()\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(@\"\r\nproperties:\r\n  configurationVersion: 0.1\r\n  resources:\r\n    - resource: Resource\r\n      id: Identifier\r\n      settings:\r\n        SettingInt: 1\r\n        SettingString: '1' \r\n        SettingBool: false\r\n        SettingStringBool: 'false'\r\n\"));\r\n            Assert.NotNull(result.Set);\r\n            Assert.Null(result.ResultCode);\r\n\r\n            var units = result.Set.Units;\r\n            Assert.NotNull(units);\r\n            Assert.Equal(1, units.Count);\r\n\r\n            ConfigurationUnit unit = units[0];\r\n            Assert.NotNull(unit);\r\n\r\n            var settings = unit.Settings;\r\n            Assert.NotNull(settings);\r\n            Assert.Equal(4, settings.Count);\r\n            Assert.Contains(\"SettingInt\", settings);\r\n            Assert.Equal(1L, settings[\"SettingInt\"]);\r\n            Assert.Contains(\"SettingString\", settings);\r\n            Assert.Equal(\"1\", settings[\"SettingString\"]);\r\n            Assert.Contains(\"SettingBool\", settings);\r\n            Assert.Equal(false, settings[\"SettingBool\"]);\r\n            Assert.Contains(\"SettingStringBool\", settings);\r\n            Assert.Equal(\"false\", settings[\"SettingStringBool\"]);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test that module gets left in resource name in 0.1.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ModuleInResourceName_NotFor0_1()\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(@\"\r\nproperties:\r\n  configurationVersion: 0.1\r\n  resources:\r\n    - resource: Module/Resource\r\n      id: Identifier\r\n      settings:\r\n        SettingInt: 1\r\n\"));\r\n\r\n            Assert.NotNull(result.Set);\r\n            Assert.Null(result.ResultCode);\r\n\r\n            Assert.Equal(\"0.1\", result.Set.SchemaVersion);\r\n            Assert.Single(result.Set.Units);\r\n\r\n            var unit = result.Set.Units[0];\r\n            Assert.NotNull(unit);\r\n            Assert.Equal(\"Module/Resource\", unit.Type);\r\n            Assert.Empty(unit.Metadata);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test that module gets parsed out of resource name in 0.2.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ModuleInResourceName()\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(@\"\r\nproperties:\r\n  configurationVersion: 0.2\r\n  resources:\r\n    - resource: Module/Resource\r\n      id: Identifier\r\n      directives:\r\n        module: Module\r\n      settings:\r\n        SettingInt: 1\r\n\"));\r\n\r\n            Assert.NotNull(result.Set);\r\n            Assert.Null(result.ResultCode);\r\n\r\n            Assert.Equal(\"0.2\", result.Set.SchemaVersion);\r\n            Assert.Single(result.Set.Units);\r\n\r\n            var unit = result.Set.Units[0];\r\n            Assert.NotNull(unit);\r\n            Assert.Equal(\"Resource\", unit.Type);\r\n            Assert.Single(unit.Metadata);\r\n            Assert.True(unit.Metadata.ContainsKey(ModuleDirective));\r\n            Assert.Equal(\"Module\", unit.Metadata[ModuleDirective]);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test that module is in the resource name and the directives and are different.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ModuleInResourceName_DirectiveDifferent()\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(@\"\r\nproperties:\r\n  configurationVersion: 0.2\r\n  resources:\r\n    - resource: Module/Resource\r\n      id: Identifier\r\n      directives:\r\n        module: DifferentModule\r\n      settings:\r\n        SettingInt: 1\r\n\"));\r\n\r\n            Assert.Null(result.Set);\r\n            Assert.NotNull(result.ResultCode);\r\n            Assert.Equal(Errors.WINGET_CONFIG_ERROR_INVALID_FIELD_VALUE, result.ResultCode.HResult);\r\n            Assert.Equal(ModuleDirective, result.Field);\r\n            Assert.Equal(\"DifferentModule\", result.Value);\r\n            Assert.Equal(5U, result.Line);\r\n            Assert.NotEqual(0U, result.Column);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test that providing only the module in the qualified name is an error.\r\n        /// </summary>\r\n        [Fact]\r\n        public void EmptyResourceWithModule()\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(@\"\r\nproperties:\r\n  configurationVersion: 0.2\r\n  resources:\r\n    - resource: Module/\r\n      id: Identifier\r\n      settings:\r\n        SettingInt: 1\r\n\"));\r\n\r\n            Assert.Null(result.Set);\r\n            Assert.NotNull(result.ResultCode);\r\n            Assert.Equal(Errors.WINGET_CONFIG_ERROR_INVALID_FIELD_VALUE, result.ResultCode.HResult);\r\n            Assert.Equal(\"resource\", result.Field);\r\n            Assert.Equal(\"Module/\", result.Value);\r\n            Assert.Equal(5U, result.Line);\r\n            Assert.NotEqual(0U, result.Column);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies that the configuration set (0.2) can be serialized and reopened correctly.\r\n        /// </summary>\r\n        [Fact]\r\n        public void TestSet_Serialize_0_2()\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult openResult = processor.OpenConfigurationSet(this.CreateStream(@\"\r\nproperties:\r\n  configurationVersion: 0.2\r\n  assertions:\r\n    - resource: FakeModule/FakeResource\r\n      id: TestId\r\n      directives:\r\n        description: FakeDescription\r\n        allowPrerelease: true\r\n        securityContext: elevated\r\n      settings:\r\n        TestString: Hello\r\n        TestBool: false\r\n        TestInt: 1234  \r\n  resources:\r\n    - resource: FakeModule2/FakeResource2\r\n      id: TestId2\r\n      dependsOn:\r\n        - TestId\r\n        - dependency2\r\n        - dependency3\r\n      directives:\r\n        description: FakeDescription2\r\n        securityContext: elevated\r\n      settings:\r\n        TestString: Bye\r\n        TestBool: true\r\n        TestInt: 4321\r\n        Mapping:\r\n          Key: TestValue\r\n\"));\r\n\r\n            // Serialize set.\r\n            ConfigurationSet configurationSet = openResult.Set;\r\n            InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream();\r\n            configurationSet.Serialize(stream);\r\n\r\n            string yamlOutput = this.ReadStream(stream);\r\n\r\n            // Reopen configuration set from serialized string and verify values.\r\n            OpenConfigurationSetResult serializedSetResult = processor.OpenConfigurationSet(this.CreateStream(yamlOutput));\r\n            Assert.Null(serializedSetResult.ResultCode);\r\n            ConfigurationSet set = serializedSetResult.Set;\r\n            Assert.NotNull(set);\r\n\r\n            Assert.Equal(\"0.2\", set.SchemaVersion);\r\n            Assert.Equal(2, set.Units.Count);\r\n\r\n            Assert.Equal(\"FakeResource\", set.Units[0].Type);\r\n            Assert.Equal(ConfigurationUnitIntent.Assert, set.Units[0].Intent);\r\n            Assert.Equal(\"TestId\", set.Units[0].Identifier);\r\n            this.VerifyValueSet(set.Units[0].Metadata, new (\"description\", \"FakeDescription\"), new (\"allowPrerelease\", true), new (\"module\", \"FakeModule\"));\r\n            this.VerifyValueSet(set.Units[0].Settings, new (\"TestString\", \"Hello\"), new (\"TestBool\", false), new (\"TestInt\", 1234));\r\n\r\n            Assert.Equal(\"FakeResource2\", set.Units[1].Type);\r\n            Assert.Equal(ConfigurationUnitIntent.Apply, set.Units[1].Intent);\r\n            Assert.Equal(\"TestId2\", set.Units[1].Identifier);\r\n            this.VerifyStringArray(set.Units[1].Dependencies, \"TestId\", \"dependency2\", \"dependency3\");\r\n            this.VerifyValueSet(set.Units[1].Metadata, new (\"description\", \"FakeDescription2\"), new (\"module\", \"FakeModule2\"));\r\n\r\n            ValueSet mapping = new ValueSet();\r\n            mapping.Add(\"Key\", \"TestValue\");\r\n            this.VerifyValueSet(set.Units[1].Settings, new (\"TestString\", \"Bye\"), new (\"TestBool\", true), new (\"TestInt\", 4321), new (\"Mapping\", mapping));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies that the configuration set (0.3) can be serialized and reopened correctly.\r\n        /// </summary>\r\n        [Fact]\r\n        public void TestSet_Serialize_0_3()\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult openResult = processor.OpenConfigurationSet(this.CreateStream(@\"\r\n$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json\r\nmetadata:\r\n  description: FakeSetDescription\r\nvariables:\r\n  var1: Test1\r\n  var2: 42\r\nparameters:\r\n  param1:\r\n    type: securestring\r\n  param2:\r\n    type: int\r\n    defaultValue: 89\r\nresources:\r\n  - type: FakeModule/FakeResource\r\n    name: TestId\r\n    metadata:\r\n      description: FakeDescription\r\n      allowPrerelease: true\r\n      myVal: mine\r\n    properties:\r\n      TestString: Hello\r\n      TestBool: false\r\n      TestInt: 1234  \r\n  - type: FakeModule2/FakeResource2\r\n    name: TestId2\r\n    dependsOn:\r\n      - TestId\r\n      - dependency2\r\n      - dependency3\r\n    metadata:\r\n      description: FakeDescription2\r\n      myVal: yours\r\n    properties:\r\n      TestString: Bye\r\n      TestBool: true\r\n      TestInt: 4321\r\n      Mapping:\r\n        Key: TestValue\r\n  - type: FakeModule/FakeResource3\r\n    name: TestId3\r\n    metadata:\r\n      isGroup: true\r\n    properties:\r\n      other: value\r\n      resources:\r\n        - type: Grouped/Resource\r\n          name: Child\r\n          properties:\r\n            b: c\r\n\"));\r\n\r\n            // Serialize set.\r\n            ConfigurationSet configurationSet = openResult.Set;\r\n            InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream();\r\n            configurationSet.Serialize(stream);\r\n\r\n            string yamlOutput = this.ReadStream(stream);\r\n\r\n            // Reopen configuration set from serialized string and verify values.\r\n            OpenConfigurationSetResult serializedSetResult = processor.OpenConfigurationSet(this.CreateStream(yamlOutput));\r\n            Assert.Null(serializedSetResult.ResultCode);\r\n            ConfigurationSet set = serializedSetResult.Set;\r\n            Assert.NotNull(set);\r\n\r\n            Assert.Equal(\"0.3\", set.SchemaVersion);\r\n            Assert.Equal(3, set.Units.Count);\r\n\r\n            this.VerifyValueSet(set.Metadata, new KeyValuePair<string, object>(\"description\", \"FakeSetDescription\"));\r\n            this.VerifyValueSet(set.Variables, new (\"var1\", \"Test1\"), new (\"var2\", 42));\r\n\r\n            Assert.Equal(2, set.Parameters.Count);\r\n            this.VerifyParameter(set.Parameters[0], \"param1\", Windows.Foundation.PropertyType.String, true);\r\n            this.VerifyParameter(set.Parameters[1], \"param2\", Windows.Foundation.PropertyType.Int64, false, 89);\r\n\r\n            Assert.Equal(\"FakeModule/FakeResource\", set.Units[0].Type);\r\n            Assert.Equal(\"TestId\", set.Units[0].Identifier);\r\n            this.VerifyValueSet(set.Units[0].Metadata, new (\"description\", \"FakeDescription\"), new (\"allowPrerelease\", true), new (\"myVal\", \"mine\"));\r\n            this.VerifyValueSet(set.Units[0].Settings, new (\"TestString\", \"Hello\"), new (\"TestBool\", false), new (\"TestInt\", 1234));\r\n\r\n            Assert.Equal(\"FakeModule2/FakeResource2\", set.Units[1].Type);\r\n            Assert.Equal(\"TestId2\", set.Units[1].Identifier);\r\n            this.VerifyStringArray(set.Units[1].Dependencies, \"TestId\", \"dependency2\", \"dependency3\");\r\n            this.VerifyValueSet(set.Units[1].Metadata, new (\"description\", \"FakeDescription2\"), new (\"myVal\", \"yours\"));\r\n\r\n            ValueSet mapping = new ValueSet();\r\n            mapping.Add(\"Key\", \"TestValue\");\r\n            this.VerifyValueSet(set.Units[1].Settings, new (\"TestString\", \"Bye\"), new (\"TestBool\", true), new (\"TestInt\", 4321), new (\"Mapping\", mapping));\r\n\r\n            Assert.Equal(\"FakeModule/FakeResource3\", set.Units[2].Type);\r\n            Assert.Equal(\"TestId3\", set.Units[2].Identifier);\r\n            Assert.True(set.Units[2].IsGroup);\r\n\r\n            ValueSet childResource = new ValueSet();\r\n            childResource.Add(\"type\", \"Grouped/Resource\");\r\n            childResource.Add(\"name\", \"Child\");\r\n            ValueSet childResourceProperties = new ValueSet();\r\n            childResourceProperties.Add(\"b\", \"c\");\r\n            childResource.Add(\"properties\", childResourceProperties);\r\n\r\n            ValueSet resourcesArray = new ValueSet();\r\n            resourcesArray.Add(\"treatAsArray\", true);\r\n            resourcesArray.Add(\"0\", childResource);\r\n\r\n            this.VerifyValueSet(set.Units[2].Settings, new (\"other\", \"value\"), new (\"resources\", resourcesArray));\r\n\r\n            var groupChildren = set.Units[2].Units;\r\n            Assert.Single(groupChildren);\r\n\r\n            Assert.Equal(\"Grouped/Resource\", groupChildren[0].Type);\r\n            Assert.Equal(\"Child\", groupChildren[0].Identifier);\r\n            this.VerifyValueSet(groupChildren[0].Settings, new KeyValuePair<string, object>(\"b\", \"c\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test for using version 0.3 schema.\r\n        /// </summary>\r\n        [Fact]\r\n        public void BasicVersion_0_3()\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(@\"\r\n$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json\r\nmetadata:\r\n  a: 1\r\n  b: '2'\r\nvariables:\r\n  v1: var1\r\n  v2: 42\r\nresources:\r\n  - name: Name\r\n    type: Module/Resource\r\n    metadata:\r\n      e: '5'\r\n      f: 6\r\n    properties:\r\n      c: 3\r\n      d: '4'\r\n    dependsOn:\r\n      - g\r\n      - h\r\n  - name: Name2\r\n    type: Module/Resource2\r\n    dependsOn:\r\n      - m\r\n    properties:\r\n      l: '10'\r\n    metadata:\r\n      i: '7'\r\n      j: 8\r\n      q: 42\r\n\"));\r\n\r\n            Assert.Null(result.ResultCode);\r\n            Assert.NotNull(result.Set);\r\n            Assert.Equal(string.Empty, result.Field);\r\n            Assert.Equal(string.Empty, result.Value);\r\n            Assert.Equal(0U, result.Line);\r\n            Assert.Equal(0U, result.Column);\r\n\r\n            ConfigurationSet set = result.Set;\r\n\r\n            Assert.Equal(\"0.3\", set.SchemaVersion);\r\n            Assert.NotNull(set.SchemaUri);\r\n            Assert.Equal(\"https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json\", set.SchemaUri.ToString());\r\n\r\n            this.VerifyValueSet(set.Metadata, new (\"a\", 1), new (\"b\", \"2\"));\r\n            this.VerifyValueSet(set.Variables, new (\"v1\", \"var1\"), new (\"v2\", 42));\r\n\r\n            Assert.Empty(set.Parameters);\r\n\r\n            Assert.Equal(2, set.Units.Count);\r\n\r\n            this.VerifyUnitProperties(set.Units[0], \"Name\", \"Module/Resource\");\r\n            this.VerifyValueSet(set.Units[0].Metadata, new (\"e\", \"5\"), new (\"f\", 6));\r\n            this.VerifyValueSet(set.Units[0].Settings, new (\"c\", 3), new (\"d\", \"4\"));\r\n            this.VerifyStringArray(set.Units[0].Dependencies, \"g\", \"h\");\r\n\r\n            this.VerifyUnitProperties(set.Units[1], \"Name2\", \"Module/Resource2\");\r\n            this.VerifyValueSet(set.Units[1].Metadata, new (\"i\", \"7\"), new (\"j\", 8), new (\"q\", 42));\r\n            this.VerifyValueSet(set.Units[1].Settings, new KeyValuePair<string, object>(\"l\", \"10\"));\r\n            this.VerifyStringArray(set.Units[1].Dependencies, \"m\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test for the successful parsing of default value of a parameter.\r\n        /// </summary>\r\n        /// <param name=\"type\">The type.</param>\r\n        /// <param name=\"defaultValue\">The default value.</param>\r\n        /// <param name=\"expectedValue\">The expected value.</param>\r\n        /// <param name=\"expectedType\">The expected type.</param>\r\n        /// <param name=\"secure\">The secure state.</param>\r\n        [Theory]\r\n        [InlineData(\"string\", \"abc\", \"abc\", Windows.Foundation.PropertyType.String)]\r\n        [InlineData(\"string\", \"'42'\", \"42\", Windows.Foundation.PropertyType.String)]\r\n        [InlineData(\"securestring\", \"abcdef\", \"abcdef\", Windows.Foundation.PropertyType.String, true)]\r\n        [InlineData(\"int\", \"42\", 42, Windows.Foundation.PropertyType.Int64)]\r\n        [InlineData(\"bool\", \"true\", true, Windows.Foundation.PropertyType.Boolean)]\r\n        [InlineData(\"object\", \"string\", \"string\", Windows.Foundation.PropertyType.Inspectable)]\r\n        [InlineData(\"object\", \"42\", 42, Windows.Foundation.PropertyType.Inspectable)]\r\n        [InlineData(\"secureobject\", \"string\", \"string\", Windows.Foundation.PropertyType.Inspectable, true)]\r\n        [InlineData(\"secureobject\", \"42\", 42, Windows.Foundation.PropertyType.Inspectable, true)]\r\n        public void Parameters_DefaultValue_Success(string type, string defaultValue, object expectedValue, object expectedType, bool secure = false)\r\n        {\r\n            this.TestParameterDefaultValue(type, defaultValue, expectedValue, Assert.IsType<Windows.Foundation.PropertyType>(expectedType), secure);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test for the failed parsing of default value of a parameter.\r\n        /// </summary>\r\n        /// <param name=\"type\">The type.</param>\r\n        /// <param name=\"defaultValue\">The default value.</param>\r\n        /// <param name=\"expectedValue\">The expected value.</param>\r\n        [Theory]\r\n        [InlineData(\"string\", \"42\")]\r\n        [InlineData(\"int\", \"abc\")]\r\n        [InlineData(\"int\", \"'42'\", \"42\")]\r\n        [InlineData(\"bool\", \"'true'\", \"true\")]\r\n        public void Parameters_DefaultValue_Failure(string type, string defaultValue, object? expectedValue = null)\r\n        {\r\n            this.TestParameterDefaultValue(type, defaultValue, expectedValue);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test to ensure that schema version and uri is working as expected.\r\n        /// </summary>\r\n        /// <param name=\"version\">The version.</param>\r\n        /// <param name=\"uri\">The uri.</param>\r\n        [Theory]\r\n        [InlineData(\"0.1\", null)]\r\n        [InlineData(\"0.2\", null)]\r\n        [InlineData(\"0.3\", \"https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json\")]\r\n        public void Schema_Version_Uri(string version, string? uri)\r\n        {\r\n            ConfigurationSet set = this.ConfigurationSet();\r\n\r\n            set.SchemaVersion = version;\r\n            if (uri != null)\r\n            {\r\n                Assert.Equal(uri, set.SchemaUri.AbsoluteUri);\r\n            }\r\n            else\r\n            {\r\n                Assert.Null(set.SchemaUri);\r\n            }\r\n\r\n            if (!string.IsNullOrEmpty(uri))\r\n            {\r\n                set.SchemaUri = new Uri(uri);\r\n                Assert.Equal(version, set.SchemaVersion);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies that the configuration set (0.2) with environments parses and serializes.\r\n        /// </summary>\r\n        [Fact]\r\n        public void Environment_0_2()\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult openResult = processor.OpenConfigurationSet(this.CreateStream(@\"\r\nproperties:\r\n  configurationVersion: 0.2\r\n  resources:\r\n    - resource: FakeModule/FakeResource\r\n      id: elevated\r\n      directives:\r\n        description: FakeDescription\r\n        allowPrerelease: true\r\n        securityContext: elevated\r\n      settings:\r\n        TestString: Hello\r\n    - resource: FakeModule2/FakeResource2\r\n      id: restricted\r\n      directives:\r\n        description: FakeDescription2\r\n        securityContext: restricted\r\n      settings:\r\n        TestString: Bye\r\n    - resource: FakeModule2/FakeResource2\r\n      id: current\r\n      directives:\r\n        securityContext: current\r\n      settings:\r\n        TestString: Bye\r\n    - resource: FakeModule2/FakeResource2\r\n      id: default\r\n      settings:\r\n        TestString: Bye\r\n\"));\r\n\r\n            Dictionary<string, SecurityContext> expectedEnvironments = new Dictionary<string, SecurityContext>();\r\n            expectedEnvironments.Add(\"elevated\", SecurityContext.Elevated);\r\n            expectedEnvironments.Add(\"restricted\", SecurityContext.Restricted);\r\n            expectedEnvironments.Add(\"current\", SecurityContext.Current);\r\n            expectedEnvironments.Add(\"default\", SecurityContext.Current);\r\n\r\n            this.ValidateSecurityContexts(openResult, expectedEnvironments);\r\n\r\n            // Shuffle security contexts, serialize, parse and validate again\r\n            expectedEnvironments[\"elevated\"] = SecurityContext.Restricted;\r\n            expectedEnvironments[\"restricted\"] = SecurityContext.Current;\r\n            expectedEnvironments[\"current\"] = SecurityContext.Restricted;\r\n            expectedEnvironments[\"default\"] = SecurityContext.Elevated;\r\n\r\n            var units = openResult.Set.Units;\r\n            foreach (var unit in units)\r\n            {\r\n                SecurityContext newContext = SecurityContext.Current;\r\n                Assert.True(expectedEnvironments.TryGetValue(unit.Identifier, out newContext));\r\n                unit.Environment.Context = newContext;\r\n            }\r\n\r\n            // Serialize set.\r\n            InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream();\r\n            openResult.Set.Serialize(stream);\r\n\r\n            string yamlOutput = this.ReadStream(stream);\r\n\r\n            // Reopen configuration set from serialized string and verify values.\r\n            OpenConfigurationSetResult serializedSetResult = processor.OpenConfigurationSet(this.CreateStream(yamlOutput));\r\n\r\n            this.ValidateSecurityContexts(serializedSetResult, expectedEnvironments);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies that the configuration set (0.3) inherits set environment.\r\n        /// </summary>\r\n        [Fact]\r\n        public void SetMetadataEnvironmentInheritance_0_3()\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult openResult = processor.OpenConfigurationSet(this.CreateStream(@\"\r\n$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json\r\nmetadata:\r\n  winget:\r\n    securityContext: elevated\r\n    processor:\r\n      identifier: pwsh\r\n      properties:\r\n        a: b\r\nresources:\r\n  - name: first\r\n    type: Module/Resource\r\n    properties:\r\n      c: 3\r\n  - name: second\r\n    type: Module/Resource2\r\n    properties:\r\n      l: '10'\r\n\"));\r\n\r\n            Dictionary<string, string> environmentProperties = new Dictionary<string, string>();\r\n            environmentProperties.Add(\"a\", \"b\");\r\n            ConfigurationEnvironmentData setEnvironment = new ConfigurationEnvironmentData() { Context = SecurityContext.Elevated, ProcessorIdentifier = \"pwsh\", ProcessorProperties = environmentProperties };\r\n\r\n            Dictionary<string, ConfigurationEnvironmentData> expectedEnvironments = new Dictionary<string, ConfigurationEnvironmentData>();\r\n            expectedEnvironments.Add(\"first\", new ConfigurationEnvironmentData());\r\n            expectedEnvironments.Add(\"second\", new ConfigurationEnvironmentData());\r\n\r\n            this.ValidateEnvironments(openResult, setEnvironment, expectedEnvironments);\r\n\r\n            // Serialize set.\r\n            InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream();\r\n            openResult.Set.Serialize(stream);\r\n\r\n            string yamlOutput = this.ReadStream(stream);\r\n\r\n            // Reopen configuration set from serialized string and verify values.\r\n            OpenConfigurationSetResult serializedSetResult = processor.OpenConfigurationSet(this.CreateStream(yamlOutput));\r\n\r\n            this.ValidateEnvironments(serializedSetResult, setEnvironment, expectedEnvironments);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies that the configuration set (0.3) inherits set environment.\r\n        /// </summary>\r\n        [Fact]\r\n        public void SetMetadataEnvironmentInheritance_ProcessorOverridden_0_3()\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult openResult = processor.OpenConfigurationSet(this.CreateStream(@\"\r\n$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json\r\nmetadata:\r\n  winget:\r\n    securityContext: elevated\r\n    processor:\r\n      identifier: pwsh\r\n      properties:\r\n        a: b\r\nresources:\r\n  - name: first\r\n    type: Module/Resource\r\n    properties:\r\n      c: 3\r\n  - name: second\r\n    type: Module/Resource2\r\n    properties:\r\n      l: '10'\r\n    metadata:\r\n      winget:\r\n        processor: not-pwsh\r\n\"));\r\n\r\n            Dictionary<string, string> environmentProperties = new Dictionary<string, string>();\r\n            environmentProperties.Add(\"a\", \"b\");\r\n            ConfigurationEnvironmentData setEnvironment = new ConfigurationEnvironmentData() { Context = SecurityContext.Elevated, ProcessorIdentifier = \"pwsh\", ProcessorProperties = environmentProperties };\r\n\r\n            Dictionary<string, ConfigurationEnvironmentData> expectedEnvironments = new Dictionary<string, ConfigurationEnvironmentData>();\r\n            expectedEnvironments.Add(\"first\", new ConfigurationEnvironmentData());\r\n            expectedEnvironments.Add(\"second\", new ConfigurationEnvironmentData() { ProcessorIdentifier = \"not-pwsh\" });\r\n\r\n            this.ValidateEnvironments(openResult, setEnvironment, expectedEnvironments);\r\n\r\n            // Serialize set.\r\n            InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream();\r\n            openResult.Set.Serialize(stream);\r\n\r\n            string yamlOutput = this.ReadStream(stream);\r\n\r\n            // Reopen configuration set from serialized string and verify values.\r\n            OpenConfigurationSetResult serializedSetResult = processor.OpenConfigurationSet(this.CreateStream(yamlOutput));\r\n\r\n            this.ValidateEnvironments(serializedSetResult, setEnvironment, expectedEnvironments);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies that the configuration set (0.3) inherits set environment.\r\n        /// </summary>\r\n        [Fact]\r\n        public void SetMetadataEnvironmentInheritance_ContextOverridden_0_3()\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult openResult = processor.OpenConfigurationSet(this.CreateStream(@\"\r\n$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json\r\nmetadata:\r\n  winget:\r\n    securityContext: elevated\r\n    processor:\r\n      identifier: pwsh\r\n      properties:\r\n        a: b\r\nresources:\r\n  - name: first\r\n    type: Module/Resource\r\n    properties:\r\n      c: 3\r\n  - name: second\r\n    type: Module/Resource2\r\n    properties:\r\n      l: '10'\r\n    metadata:\r\n      winget:\r\n        securityContext: restricted\r\n\"));\r\n\r\n            Dictionary<string, string> environmentProperties = new Dictionary<string, string>();\r\n            environmentProperties.Add(\"a\", \"b\");\r\n            ConfigurationEnvironmentData setEnvironment = new ConfigurationEnvironmentData() { Context = SecurityContext.Elevated, ProcessorIdentifier = \"pwsh\", ProcessorProperties = environmentProperties };\r\n\r\n            Dictionary<string, ConfigurationEnvironmentData> expectedEnvironments = new Dictionary<string, ConfigurationEnvironmentData>();\r\n            expectedEnvironments.Add(\"first\", new ConfigurationEnvironmentData());\r\n            expectedEnvironments.Add(\"second\", new ConfigurationEnvironmentData() { Context = SecurityContext.Restricted });\r\n\r\n            this.ValidateEnvironments(openResult, setEnvironment, expectedEnvironments);\r\n\r\n            // Serialize set.\r\n            InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream();\r\n            openResult.Set.Serialize(stream);\r\n\r\n            string yamlOutput = this.ReadStream(stream);\r\n\r\n            // Reopen configuration set from serialized string and verify values.\r\n            OpenConfigurationSetResult serializedSetResult = processor.OpenConfigurationSet(this.CreateStream(yamlOutput));\r\n\r\n            this.ValidateEnvironments(serializedSetResult, setEnvironment, expectedEnvironments);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies that the configuration set (0.3) serializes common environment to the set metadata.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CommonEnvironmentElevatedToSetMetadata_0_3()\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult openResult = processor.OpenConfigurationSet(this.CreateStream(@\"\r\n$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json\r\nresources:\r\n  - name: first\r\n    type: Module/Resource\r\n    metadata:\r\n      winget:\r\n        securityContext: elevated\r\n        processor: pwsh\r\n    properties:\r\n      c: 3\r\n  - name: second\r\n    type: Module/Resource2\r\n    properties:\r\n      l: '10'\r\n    metadata:\r\n      winget:\r\n        securityContext: elevated\r\n        processor:\r\n          identifier: pwsh\r\n\"));\r\n\r\n            ConfigurationEnvironmentData setEnvironment = new ConfigurationEnvironmentData();\r\n\r\n            Dictionary<string, ConfigurationEnvironmentData> expectedEnvironments = new Dictionary<string, ConfigurationEnvironmentData>();\r\n            expectedEnvironments.Add(\"first\", new ConfigurationEnvironmentData() { Context = SecurityContext.Elevated, ProcessorIdentifier = \"pwsh\" });\r\n            expectedEnvironments.Add(\"second\", new ConfigurationEnvironmentData() { Context = SecurityContext.Elevated, ProcessorIdentifier = \"pwsh\" });\r\n\r\n            this.ValidateEnvironments(openResult, setEnvironment, expectedEnvironments);\r\n\r\n            // Serialize set.\r\n            InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream();\r\n            openResult.Set.Serialize(stream);\r\n\r\n            string yamlOutput = this.ReadStream(stream);\r\n\r\n            // Reopen configuration set from serialized string and verify values.\r\n            OpenConfigurationSetResult serializedSetResult = processor.OpenConfigurationSet(this.CreateStream(yamlOutput));\r\n\r\n            this.ValidateEnvironments(serializedSetResult, setEnvironment, expectedEnvironments);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies that the configuration set (0.3) serializes common environment to the set metadata.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CommonProcessorElevatedToSetMetadata_0_3()\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult openResult = processor.OpenConfigurationSet(this.CreateStream(@\"\r\n$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json\r\nresources:\r\n  - name: first\r\n    type: Module/Resource\r\n    metadata:\r\n      winget:\r\n        securityContext: elevated\r\n        processor: pwsh\r\n    properties:\r\n      c: 3\r\n  - name: second\r\n    type: Module/Resource2\r\n    properties:\r\n      l: '10'\r\n    metadata:\r\n      winget:\r\n        securityContext: restricted\r\n        processor:\r\n          identifier: pwsh\r\n\"));\r\n\r\n            ConfigurationEnvironmentData setEnvironment = new ConfigurationEnvironmentData();\r\n\r\n            Dictionary<string, ConfigurationEnvironmentData> expectedEnvironments = new Dictionary<string, ConfigurationEnvironmentData>();\r\n            expectedEnvironments.Add(\"first\", new ConfigurationEnvironmentData() { Context = SecurityContext.Elevated, ProcessorIdentifier = \"pwsh\" });\r\n            expectedEnvironments.Add(\"second\", new ConfigurationEnvironmentData() { Context = SecurityContext.Restricted, ProcessorIdentifier = \"pwsh\" });\r\n\r\n            this.ValidateEnvironments(openResult, setEnvironment, expectedEnvironments);\r\n\r\n            // Serialize set.\r\n            InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream();\r\n            openResult.Set.Serialize(stream);\r\n\r\n            string yamlOutput = this.ReadStream(stream);\r\n\r\n            // Reopen configuration set from serialized string and verify values.\r\n            OpenConfigurationSetResult serializedSetResult = processor.OpenConfigurationSet(this.CreateStream(yamlOutput));\r\n\r\n            this.ValidateEnvironments(serializedSetResult, setEnvironment, expectedEnvironments);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies that the configuration set (0.3) environments work with group units.\r\n        /// </summary>\r\n        [Fact]\r\n        public void EnvironmentsWithGroups_0_3()\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult openResult = processor.OpenConfigurationSet(this.CreateStream(@\"\r\n$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json\r\nmetadata:\r\n  winget:\r\n    securityContext: elevated\r\n    processor:\r\n      identifier: pwsh\r\n      properties:\r\n        a: b\r\nresources:\r\n  - name: non-group\r\n    type: Module/Resource2\r\n    properties:\r\n      l: '10'\r\n  - name: group\r\n    type: Module/Resource\r\n    metadata:\r\n      isGroup: true\r\n      winget:\r\n        securityContext: restricted\r\n    properties:\r\n      resources:\r\n        - name: inherit\r\n          type: Module/Resource\r\n          properties:\r\n            a: b\r\n        - name: override\r\n          type: Module/Resource\r\n          properties:\r\n            c: d\r\n          metadata:\r\n            winget:\r\n              processor: not-pwsh\r\n\"));\r\n\r\n            Dictionary<string, string> environmentProperties = new Dictionary<string, string>();\r\n            environmentProperties.Add(\"a\", \"b\");\r\n            ConfigurationEnvironmentData setEnvironment = new ConfigurationEnvironmentData() { Context = SecurityContext.Elevated, ProcessorIdentifier = \"pwsh\", ProcessorProperties = environmentProperties };\r\n\r\n            Dictionary<string, ConfigurationEnvironmentData> expectedEnvironments = new Dictionary<string, ConfigurationEnvironmentData>();\r\n            expectedEnvironments.Add(\"non-group\", new ConfigurationEnvironmentData());\r\n            expectedEnvironments.Add(\"group\", new ConfigurationEnvironmentData() { Context = SecurityContext.Restricted });\r\n\r\n            Dictionary<string, ConfigurationEnvironmentData> groupExpectedEnvironments = new Dictionary<string, ConfigurationEnvironmentData>();\r\n            groupExpectedEnvironments.Add(\"inherit\", new ConfigurationEnvironmentData());\r\n            groupExpectedEnvironments.Add(\"override\", new ConfigurationEnvironmentData() { ProcessorIdentifier = \"not-pwsh\" });\r\n\r\n            this.ValidateEnvironments(openResult, setEnvironment, expectedEnvironments, \"group\", groupExpectedEnvironments);\r\n\r\n            // Serialize set.\r\n            InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream();\r\n            openResult.Set.Serialize(stream);\r\n\r\n            string yamlOutput = this.ReadStream(stream);\r\n\r\n            // Reopen configuration set from serialized string and verify values.\r\n            OpenConfigurationSetResult serializedSetResult = processor.OpenConfigurationSet(this.CreateStream(yamlOutput));\r\n\r\n            this.ValidateEnvironments(openResult, setEnvironment, expectedEnvironments, \"group\", groupExpectedEnvironments);\r\n        }\r\n\r\n        private void ValidateEnvironments(OpenConfigurationSetResult openResult, ConfigurationEnvironmentData setEnvironment, Dictionary<string, ConfigurationEnvironmentData> expectedEnvironments, string? groupToCheck = null, Dictionary<string, ConfigurationEnvironmentData>? groupExpectedEnvironments = null)\r\n        {\r\n            Assert.Null(openResult.ResultCode);\r\n            Assert.NotNull(openResult.Set);\r\n            ConfigurationSet configurationSet = openResult.Set;\r\n\r\n            this.ValidateEnvironment(setEnvironment, configurationSet.Environment);\r\n\r\n            var units = configurationSet.Units;\r\n            this.ValidateEnvironments(units, expectedEnvironments, groupToCheck, groupExpectedEnvironments);\r\n        }\r\n\r\n        private void ValidateEnvironments(IList<ConfigurationUnit> units, Dictionary<string, ConfigurationEnvironmentData> expectedEnvironments, string? groupToCheck = null, Dictionary<string, ConfigurationEnvironmentData>? groupExpectedEnvironments = null)\r\n        {\r\n            Assert.Equal(expectedEnvironments.Count, units.Count);\r\n            foreach (var unit in units)\r\n            {\r\n                ConfigurationEnvironmentData? expectedEnvironment = null;\r\n                Assert.True(expectedEnvironments.TryGetValue(unit.Identifier, out expectedEnvironment));\r\n                this.ValidateEnvironment(expectedEnvironment, unit.Environment);\r\n\r\n                if (unit.Identifier == groupToCheck)\r\n                {\r\n                    Assert.True(unit.IsGroup);\r\n                    Assert.NotNull(groupExpectedEnvironments);\r\n                    var groupUnits = unit.Units;\r\n                    this.ValidateEnvironments(groupUnits, groupExpectedEnvironments);\r\n                }\r\n            }\r\n        }\r\n\r\n        private void ValidateEnvironment(ConfigurationEnvironmentData? expectedEnvironment, ConfigurationEnvironment? actualEnvironment)\r\n        {\r\n            Assert.NotNull(expectedEnvironment);\r\n            Assert.NotNull(actualEnvironment);\r\n            Assert.Equal(expectedEnvironment.Context, actualEnvironment.Context);\r\n            Assert.Equal(expectedEnvironment.ProcessorIdentifier, actualEnvironment.ProcessorIdentifier);\r\n            Assert.True(expectedEnvironment.PropertiesEqual(actualEnvironment.ProcessorProperties));\r\n        }\r\n\r\n        private void ValidateSecurityContexts(OpenConfigurationSetResult openResult, Dictionary<string, SecurityContext> expectedContexts)\r\n        {\r\n            Assert.Null(openResult.ResultCode);\r\n            Assert.NotNull(openResult.Set);\r\n            ConfigurationSet configurationSet = openResult.Set;\r\n\r\n            var units = configurationSet.Units;\r\n            Assert.Equal(expectedContexts.Count, units.Count);\r\n            foreach (var unit in units)\r\n            {\r\n                SecurityContext expectedContext = SecurityContext.Current;\r\n                Assert.True(expectedContexts.TryGetValue(unit.Identifier, out expectedContext));\r\n                Assert.Equal(expectedContext, unit.Environment.Context);\r\n            }\r\n        }\r\n\r\n        private void TestParameterDefaultValue(string type, string defaultValue, object? expectedValue = null, Windows.Foundation.PropertyType? expectedType = null, bool secure = false)\r\n        {\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics();\r\n\r\n            OpenConfigurationSetResult result = processor.OpenConfigurationSet(this.CreateStream(string.Format(\r\n                @\"\r\n$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json\r\nparameters:\r\n  {0}:\r\n    type: {0}\r\n    defaultValue: {1}\r\n\",\r\n                type,\r\n                defaultValue)));\r\n\r\n            if (expectedType != null)\r\n            {\r\n                Assert.Null(result.ResultCode);\r\n                Assert.NotNull(result.Set);\r\n                Assert.Equal(string.Empty, result.Field);\r\n                Assert.Equal(string.Empty, result.Value);\r\n                Assert.Equal(0U, result.Line);\r\n                Assert.Equal(0U, result.Column);\r\n\r\n                var parameters = result.Set.Parameters;\r\n                Assert.NotNull(parameters);\r\n                Assert.Single(parameters);\r\n\r\n                Assert.Equal(type, parameters[0].Name);\r\n                Assert.Equal(expectedType, parameters[0].Type);\r\n                Assert.Equal(secure, parameters[0].IsSecure);\r\n\r\n                Assert.NotNull(expectedValue);\r\n                this.VerifyObject(type, expectedValue, parameters[0].DefaultValue);\r\n            }\r\n            else\r\n            {\r\n                Assert.NotNull(result.ResultCode);\r\n                Assert.Equal(Errors.WINGET_CONFIG_ERROR_INVALID_FIELD_VALUE, result.ResultCode.HResult);\r\n                Assert.Null(result.Set);\r\n                Assert.Equal(\"defaultValue\", result.Field);\r\n                Assert.Equal(expectedValue?.ToString() ?? defaultValue, result.Value);\r\n                Assert.NotEqual(0U, result.Line);\r\n                Assert.NotEqual(0U, result.Column);\r\n            }\r\n        }\r\n\r\n        private void VerifyUnitProperties(ConfigurationUnit unit, string identifier, string type)\r\n        {\r\n            Assert.NotNull(unit);\r\n            Assert.Equal(identifier, unit.Identifier);\r\n            Assert.Equal(type, unit.Type);\r\n        }\r\n\r\n        private void VerifyValueSet(ValueSet values, params KeyValuePair<string, object>[] expected)\r\n        {\r\n            Assert.NotNull(values);\r\n            Assert.Equal(expected.Length, values.Count);\r\n\r\n            foreach (var expectation in expected)\r\n            {\r\n                Assert.True(values.ContainsKey(expectation.Key), $\"Not Found {expectation.Key}\");\r\n                object value = values[expectation.Key];\r\n\r\n                this.VerifyObject(expectation.Key, expectation.Value, value);\r\n            }\r\n        }\r\n\r\n        private void VerifyStringArray(IList<string> strings, params string[] expected)\r\n        {\r\n            Assert.NotNull(strings);\r\n            Assert.Equal(expected.Length, strings.Count);\r\n\r\n            foreach (var expectation in expected)\r\n            {\r\n                bool found = false;\r\n                foreach (var value in strings)\r\n                {\r\n                    if (!found)\r\n                    {\r\n                        found = expectation == value;\r\n                    }\r\n                }\r\n\r\n                Assert.True(found, $\"Did not find {expectation} in string array\");\r\n            }\r\n        }\r\n\r\n        private void VerifyParameter(ConfigurationParameter parameter, string name, Windows.Foundation.PropertyType type, bool secure, object? defaultValue = null)\r\n        {\r\n            Assert.Equal(name, parameter.Name);\r\n            Assert.Equal(type, parameter.Type);\r\n            Assert.Equal(secure, parameter.IsSecure);\r\n            this.VerifyObject(name, defaultValue, parameter.DefaultValue);\r\n        }\r\n\r\n        private void VerifyObject(string name, object? expectedValue, object? actualValue)\r\n        {\r\n            if (expectedValue != null)\r\n            {\r\n                Assert.NotNull(actualValue);\r\n\r\n                switch (expectedValue)\r\n                {\r\n                    case int i:\r\n                        Assert.True(i == (int)(long)actualValue, $\"{name}: expected[{i}], actual[{(int)(long)actualValue}]\");\r\n                        break;\r\n                    case string s:\r\n                        Assert.True(s == (string)actualValue, $\"{name}: expected[{s}], actual[{(string)actualValue}]\");\r\n                        break;\r\n                    case bool b:\r\n                        Assert.True(b == (bool)actualValue, $\"{name}: expected[{b}], actual[{(bool)actualValue}]\");\r\n                        break;\r\n                    case ValueSet v:\r\n                        var actualValueSet = actualValue.As<ValueSet>();\r\n                        Assert.True(v.ContentEquals(actualValueSet), $\"ValueSets not equal: {name}\\n---expected---:\\n{v.ToYaml()}\\n---actual---:\\n{actualValueSet.ToYaml()}\");\r\n                        break;\r\n                    default:\r\n                        Assert.Fail($\"Add expected type `{expectedValue.GetType().Name}` to switch statement for {name}.\");\r\n                        break;\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/PowerShellHelperTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"PowerShellHelperTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System;\r\n    using Microsoft.Management.Configuration.Processor.PowerShell.Helpers;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n\r\n    /// <summary>\r\n    /// PowerShell helper tests.\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [InProc]\r\n    public class PowerShellHelperTests\r\n    {\r\n        private readonly UnitTestFixture fixture;\r\n        private readonly ITestOutputHelper log;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"PowerShellHelperTests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Unit test fixture.</param>\r\n        /// <param name=\"log\">Log helper.</param>\r\n        public PowerShellHelperTests(UnitTestFixture fixture, ITestOutputHelper log)\r\n        {\r\n            this.fixture = fixture;\r\n            this.log = log;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests CreateModuleSpecification.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CreateModuleSpecification_Module_Test()\r\n        {\r\n            string moduleName = \"MyModule\";\r\n\r\n            var moduleSpecification = PowerShellHelpers.CreateModuleSpecification(moduleName);\r\n            Assert.Equal(moduleName, moduleSpecification.Name);\r\n            Assert.Null(moduleSpecification.RequiredVersion);\r\n            Assert.Null(moduleSpecification.Version);\r\n            Assert.Null(moduleSpecification.MaximumVersion);\r\n            Assert.Null(moduleSpecification.Guid);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests CreateModuleSpecification with arguments. use version.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CreateModuleSpecification_Required_Test()\r\n        {\r\n            string moduleName = \"MyModule\";\r\n            string version = \"0.1.0\";\r\n            string guid = Guid.NewGuid().ToString();\r\n\r\n            var moduleSpecification = PowerShellHelpers.CreateModuleSpecification(\r\n                moduleName,\r\n                version,\r\n                null,\r\n                null,\r\n                guid);\r\n            Assert.Equal(moduleName, moduleSpecification.Name);\r\n            Assert.NotNull(moduleSpecification.RequiredVersion);\r\n            Assert.Equal(version, moduleSpecification.RequiredVersion.ToString());\r\n            Assert.Null(moduleSpecification.Version);\r\n            Assert.Null(moduleSpecification.MaximumVersion);\r\n            Assert.NotNull(moduleSpecification.Guid);\r\n            Assert.Equal(guid, moduleSpecification.Guid.ToString());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests CreateModuleSpecification with arguments. Use min version.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CreateModuleSpecification_MinMax_Test()\r\n        {\r\n            string moduleName = \"MyModule\";\r\n            string minVersion = \"0.0.1\";\r\n            string maxVersion = \"1.0.0\";\r\n            string guid = Guid.NewGuid().ToString();\r\n\r\n            var moduleSpecification = PowerShellHelpers.CreateModuleSpecification(\r\n                moduleName,\r\n                null,\r\n                minVersion,\r\n                maxVersion,\r\n                guid);\r\n            Assert.Equal(moduleName, moduleSpecification.Name);\r\n            Assert.Null(moduleSpecification.RequiredVersion);\r\n            Assert.NotNull(moduleSpecification.Version);\r\n            Assert.Equal(minVersion, moduleSpecification.Version.ToString());\r\n            Assert.NotNull(moduleSpecification.MaximumVersion);\r\n            Assert.Equal(maxVersion, moduleSpecification.MaximumVersion.ToString());\r\n            Assert.NotNull(moduleSpecification.Guid);\r\n            Assert.Equal(guid, moduleSpecification.Guid.ToString());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests CreateModuleSpecification with prerelease versions.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CreateModuleSpecification_PrereleaseVersions_Required_Test()\r\n        {\r\n            string moduleName = \"MyModule\";\r\n            string preVersion = \"0.1.0-pre\";\r\n            string version = \"0.1.0\";\r\n\r\n            var moduleSpecification = PowerShellHelpers.CreateModuleSpecification(\r\n                moduleName,\r\n                preVersion);\r\n            Assert.Equal(moduleName, moduleSpecification.Name);\r\n            Assert.NotNull(moduleSpecification.RequiredVersion);\r\n            Assert.Equal(version, moduleSpecification.RequiredVersion.ToString());\r\n            Assert.Null(moduleSpecification.Version);\r\n            Assert.Null(moduleSpecification.MaximumVersion);\r\n            Assert.Null(moduleSpecification.Guid);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests CreateModuleSpecification with prerelease versions.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CreateModuleSpecification_PrereleaseVersions_Test()\r\n        {\r\n            string moduleName = \"MyModule\";\r\n            string preMinVersion = \"0.0.1-pre\";\r\n            string minVersion = \"0.0.1\";\r\n            string preMaxVersion = \"1.0.0-pre\";\r\n            string maxVersion = \"1.0.0\";\r\n\r\n            var moduleSpecification = PowerShellHelpers.CreateModuleSpecification(\r\n                moduleName,\r\n                null,\r\n                preMinVersion,\r\n                preMaxVersion);\r\n            Assert.Equal(moduleName, moduleSpecification.Name);\r\n            Assert.Null(moduleSpecification.RequiredVersion);\r\n            Assert.NotNull(moduleSpecification.Version);\r\n            Assert.Equal(minVersion, moduleSpecification.Version.ToString());\r\n            Assert.NotNull(moduleSpecification.MaximumVersion);\r\n            Assert.Equal(maxVersion, moduleSpecification.MaximumVersion.ToString());\r\n            Assert.Null(moduleSpecification.Guid);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests CreateModuleSpecification with arguments. Don't use minVersion and version.\r\n        /// </summary>\r\n        [Fact]\r\n        public void CreateModuleSpecification_Args_Throws_Test()\r\n        {\r\n            string moduleName = \"MyModule\";\r\n            string version = \"0.1.0\";\r\n            string minVersion = \"0.0.1\";\r\n            string maxVersion = \"1.0.0\";\r\n\r\n            Assert.Throws<ArgumentException>(() => PowerShellHelpers.CreateModuleSpecification(\r\n                moduleName,\r\n                version,\r\n                minVersion,\r\n                null,\r\n                null));\r\n\r\n            Assert.Throws<ArgumentException>(() => PowerShellHelpers.CreateModuleSpecification(\r\n                moduleName,\r\n                version,\r\n                null,\r\n                maxVersion,\r\n                null));\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/ProcessorEnvironmentTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ProcessorEnvironmentTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System.Collections.Generic;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using Moq;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n    using static Microsoft.Management.Configuration.Processor.PowerShell.Constants.PowerShellConstants;\r\n\r\n    /// <summary>\r\n    /// HostedEnvironment tests, that is more ProcessorEnvironmentBase tests for non forwarding functions.\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [InProc]\r\n    public class ProcessorEnvironmentTests\r\n    {\r\n        private readonly UnitTestFixture fixture;\r\n        private readonly ITestOutputHelper log;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ProcessorEnvironmentTests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Unit test fixture.</param>\r\n        /// <param name=\"log\">Log.</param>\r\n        public ProcessorEnvironmentTests(UnitTestFixture fixture, ITestOutputHelper log)\r\n        {\r\n            this.fixture = fixture;\r\n            this.log = log;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test SetVariable and SetVariable methods.\r\n        /// </summary>\r\n        [Fact]\r\n        public void HostedEnvironment_Variables()\r\n        {\r\n            var processorEnv = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            // As string.\r\n            string var1Name = \"var1\";\r\n            string var1 = \"This is a string\";\r\n            processorEnv.SetVariable(var1Name, var1);\r\n            string var1Result = processorEnv.GetVariable<string>(var1Name);\r\n            Assert.Equal(var1, var1Result);\r\n\r\n            // As int.\r\n            string var2Name = \"var2\";\r\n            int var2 = 42;\r\n            processorEnv.SetVariable(var2Name, var2);\r\n            int var2Result = processorEnv.GetVariable<int>(var2Name);\r\n\r\n            // Wrong type.\r\n            Assert.Throws<System.InvalidCastException>(() => processorEnv.GetVariable<int>(var1Name));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests SetPsModulePath.\r\n        /// </summary>\r\n        [Fact]\r\n        public void HostedEnvironment_SetPSModulePath()\r\n        {\r\n            var processorEnv = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            string psModulePathInput = \"SetPSModulePathModulePath\";\r\n            string psModulePath = processorEnv.GetVariable<string>(Variables.PSModulePath);\r\n            Assert.NotEqual(psModulePathInput, psModulePath);\r\n\r\n            processorEnv.SetPSModulePath(psModulePathInput);\r\n            psModulePath = processorEnv.GetVariable<string>(Variables.PSModulePath);\r\n            Assert.Equal(psModulePathInput, psModulePath);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests SetPsModulePaths.\r\n        /// </summary>\r\n        [Fact]\r\n        public void HostedEnvironment_SetPSModulePaths()\r\n        {\r\n            var processorEnv = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            var psModulePathInput = new List<string>()\r\n            {\r\n                \"Path1\",\r\n                \"Path2\",\r\n                \"Path3\",\r\n                \"Path4\",\r\n            };\r\n            string psModulePathExpected = \"Path1;Path2;Path3;Path4\";\r\n\r\n            string psModulePath = processorEnv.GetVariable<string>(Variables.PSModulePath);\r\n            Assert.NotEqual(psModulePathExpected, psModulePath);\r\n\r\n            processorEnv.SetPSModulePaths(psModulePathInput);\r\n            psModulePath = processorEnv.GetVariable<string>(Variables.PSModulePath);\r\n            Assert.Equal(psModulePathExpected, psModulePath);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests AppendPSModulePath.\r\n        /// </summary>\r\n        [Fact]\r\n        public void HostedEnvironment_AppendPSModulePath()\r\n        {\r\n            var processorEnv = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            string psModulePathInput = \"AppendPSModulePathModulePath\";\r\n            string psModulePath = processorEnv.GetVariable<string>(Variables.PSModulePath);\r\n            Assert.False(psModulePath.EndsWith($\";{psModulePathInput}\"));\r\n\r\n            processorEnv.AppendPSModulePath(psModulePathInput);\r\n            psModulePath = processorEnv.GetVariable<string>(Variables.PSModulePath);\r\n            Assert.EndsWith($\";{psModulePathInput}\", psModulePath);\r\n\r\n            // No duplicates\r\n            processorEnv.AppendPSModulePath(psModulePathInput);\r\n            psModulePath = processorEnv.GetVariable<string>(Variables.PSModulePath);\r\n            Assert.False(psModulePath.EndsWith($\";{psModulePathInput};{psModulePathInput}\"));\r\n            Assert.EndsWith($\";{psModulePathInput}\", psModulePath);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests AppendPSModulePaths.\r\n        /// </summary>\r\n        [Fact]\r\n        public void HostedEnvironment_AppendPSModulePaths()\r\n        {\r\n            var processorEnv = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            var psModulePathInput = new List<string>()\r\n            {\r\n                \"AppendPSModulePathsPath1\",\r\n                \"AppendPSModulePathsPath2\",\r\n                \"AppendPSModulePathsPath3\",\r\n                \"AppendPSModulePathsPath4\",\r\n            };\r\n            string psModulePathExpected = \"AppendPSModulePathsPath1;AppendPSModulePathsPath2;AppendPSModulePathsPath3;AppendPSModulePathsPath4\";\r\n\r\n            string psModulePath = processorEnv.GetVariable<string>(Variables.PSModulePath);\r\n            Assert.False(psModulePath.EndsWith($\";{psModulePathExpected}\"));\r\n\r\n            processorEnv.AppendPSModulePaths(psModulePathInput);\r\n            psModulePath = processorEnv.GetVariable<string>(Variables.PSModulePath);\r\n            Assert.EndsWith($\";{psModulePathExpected}\", psModulePath);\r\n\r\n            // No duplicates\r\n            psModulePathInput = new List<string>()\r\n            {\r\n                \"AppendPSModulePathsPath1\",\r\n                \"AppendPSModulePathsPath5\",\r\n                \"AppendPSModulePathsPath2\",\r\n            };\r\n            processorEnv.AppendPSModulePaths(psModulePathInput);\r\n            psModulePath = processorEnv.GetVariable<string>(Variables.PSModulePath);\r\n            Assert.EndsWith($\";{psModulePathExpected};AppendPSModulePathsPath5\", psModulePath);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests PrependPSModulePath.\r\n        /// </summary>\r\n        [Fact]\r\n        public void HostedEnvironment_PrependPSModulePath()\r\n        {\r\n            var processorEnv = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            string psModulePathInput = \"PrependPSModulePathModulePath\";\r\n            string psModulePath = processorEnv.GetVariable<string>(Variables.PSModulePath);\r\n            Assert.False(psModulePath.StartsWith($\";{psModulePathInput}\"));\r\n\r\n            processorEnv.PrependPSModulePath(psModulePathInput);\r\n            psModulePath = processorEnv.GetVariable<string>(Variables.PSModulePath);\r\n            Assert.StartsWith($\"{psModulePathInput};\", psModulePath);\r\n\r\n            // No duplicates\r\n            processorEnv.PrependPSModulePath(psModulePathInput);\r\n            psModulePath = processorEnv.GetVariable<string>(Variables.PSModulePath);\r\n            Assert.False(psModulePath.StartsWith($\"{psModulePathInput};{psModulePathInput};\"));\r\n            Assert.StartsWith($\"{psModulePathInput};\", psModulePath);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests PrependPSModulePaths.\r\n        /// </summary>\r\n        [Fact]\r\n        public void HostedEnvironment_PrependPSModulePaths()\r\n        {\r\n            var processorEnv = this.fixture.PrepareTestProcessorEnvironment();\r\n\r\n            var psModulePathInput = new List<string>()\r\n            {\r\n                \"PrependPSModulePathsPath1\",\r\n                \"PrependPSModulePathsPath2\",\r\n                \"PrependPSModulePathsPath3\",\r\n                \"PrependPSModulePathsPath4\",\r\n            };\r\n            string psModulePathExpected = \"PrependPSModulePathsPath1;PrependPSModulePathsPath2;PrependPSModulePathsPath3;PrependPSModulePathsPath4\";\r\n\r\n            string psModulePath = processorEnv.GetVariable<string>(Variables.PSModulePath);\r\n            Assert.False(psModulePath.StartsWith($\";{psModulePathExpected}\"));\r\n\r\n            processorEnv.PrependPSModulePaths(psModulePathInput);\r\n            psModulePath = processorEnv.GetVariable<string>(Variables.PSModulePath);\r\n            Assert.StartsWith($\"{psModulePathExpected};\", psModulePath);\r\n\r\n            // No duplicates\r\n            psModulePathInput = new List<string>()\r\n            {\r\n                \"PrependPSModulePathsPath1\",\r\n                \"PrependPSModulePathsPath5\",\r\n                \"PrependPSModulePathsPath2\",\r\n            };\r\n            processorEnv.PrependPSModulePaths(psModulePathInput);\r\n            psModulePath = processorEnv.GetVariable<string>(Variables.PSModulePath);\r\n            Assert.StartsWith($\"PrependPSModulePathsPath5;{psModulePathExpected};\", psModulePath);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test CleanupPSModulePath.\r\n        /// </summary>\r\n        [Fact]\r\n        public void HostedEnvironment_CleanupPSModulePath()\r\n        {\r\n            var processorEnv = this.fixture.PrepareTestProcessorEnvironment();\r\n            var psModulePathInput = new List<string>()\r\n            {\r\n                \"CleanupPSModulePathPath1\",\r\n                \"CleanupPSModulePathPath2\",\r\n                \"CleanupPSModulePathPath3\",\r\n                \"CleanupPSModulePathPath1\",\r\n                \"CleanupPSModulePathPath1\",\r\n            };\r\n\r\n            string psModulePathExpected = \"CleanupPSModulePathPath1;CleanupPSModulePathPath2;CleanupPSModulePathPath3;CleanupPSModulePathPath1;CleanupPSModulePathPath1\";\r\n            processorEnv.SetPSModulePaths(psModulePathInput);\r\n            string psModulePath = processorEnv.GetVariable<string>(Variables.PSModulePath);\r\n            Assert.Equal(psModulePathExpected, psModulePath);\r\n\r\n            processorEnv.CleanupPSModulePath(\"CleanupPSModulePathPath1\");\r\n\r\n            psModulePathExpected = \"CleanupPSModulePathPath2;CleanupPSModulePathPath3\";\r\n            psModulePath = processorEnv.GetVariable<string>(Variables.PSModulePath);\r\n            Assert.Equal(psModulePathExpected, psModulePath);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/SemanticVersionTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"SemanticVersionTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System;\r\n    using Microsoft.Management.Configuration.Processor.Helpers;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n\r\n    /// <summary>\r\n    /// Semantic version tests.\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [InProc]\r\n    public class SemanticVersionTests\r\n    {\r\n        private readonly UnitTestFixture fixture;\r\n        private readonly ITestOutputHelper log;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"SemanticVersionTests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Unit test fixture.</param>\r\n        /// <param name=\"log\">Log helper.</param>\r\n        public SemanticVersionTests(UnitTestFixture fixture, ITestOutputHelper log)\r\n        {\r\n            this.fixture = fixture;\r\n            this.log = log;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test version.\r\n        /// </summary>\r\n        [Fact]\r\n        public void SemanticVersion_Test()\r\n        {\r\n            var semanticVersion = new SemanticVersion(\"1.0.1\");\r\n            Assert.Equal(\"1.0.1\", semanticVersion.ToString());\r\n            Assert.Equal(new Version(\"1.0.1\"), semanticVersion.Version);\r\n            Assert.False(semanticVersion.IsPrerelease);\r\n            Assert.Null(semanticVersion.PrereleaseTag);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests prerelease version.\r\n        /// </summary>\r\n        [Fact]\r\n        public void PrereleaseVersion_Test()\r\n        {\r\n            var semanticVersion = new SemanticVersion(\"1.0.1-pre\");\r\n            Assert.Equal(\"1.0.1-pre\", semanticVersion.ToString());\r\n            Assert.Equal(new Version(\"1.0.1\"), semanticVersion.Version);\r\n            Assert.True(semanticVersion.IsPrerelease);\r\n            Assert.Equal(\"pre\", semanticVersion.PrereleaseTag);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests GetMaximumVersion.\r\n        /// </summary>\r\n        /// <param name=\"input\">Input.</param>\r\n        /// <param name=\"expected\">Expected.</param>\r\n        [Theory]\r\n        [InlineData(\"1.0.1\", \"1.0.1\")]\r\n        [InlineData(\"1.0.*\", \"1.0.999999999\")]\r\n        [InlineData(\"*.*.1\", \"999999999.999999999.1\")]\r\n        public void MaximumVersion_Test(string input, string expected)\r\n        {\r\n            var semanticVersion = new SemanticVersion(input);\r\n            Assert.Equal(expected, semanticVersion.ToString());\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/ShutdownTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ShutdownTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System;\r\n    using System.Threading;\r\n    using System.Threading.Tasks;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using WinGetTestCommon;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n\r\n    /// <summary>\r\n    /// Unit tests for running test on the processor.\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [OutOfProc]\r\n    public class ShutdownTests : ConfigurationProcessorTestBase\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ShutdownTests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Unit test fixture.</param>\r\n        /// <param name=\"log\">Log helper.</param>\r\n        public ShutdownTests(UnitTestFixture fixture, ITestOutputHelper log)\r\n            : base(fixture, log)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Initiates a shutdown on the process when it is running a synchronous operation.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ShutdownSynchronization_SyncCall()\r\n        {\r\n            this.Fixture.RecreateStatics();\r\n\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            ConfigurationUnit configurationUnitWaits = this.ConfigurationUnit();\r\n            ConfigurationUnit configurationUnitWorks = this.ConfigurationUnit();\r\n            configurationSet.Units = new ConfigurationUnit[] { configurationUnitWaits, configurationUnitWorks };\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet);\r\n            TestConfigurationUnitProcessor unitProcessor = setProcessor.CreateTestProcessor(configurationUnitWaits);\r\n\r\n            ManualResetEvent isWaiting = new ManualResetEvent(false);\r\n            ManualResetEvent waitingOn = new ManualResetEvent(false);\r\n            unitProcessor.TestSettingsDelegate = () =>\r\n            {\r\n                isWaiting.Set();\r\n                waitingOn.WaitOne();\r\n                return new TestSettingsResultInstance(configurationUnitWaits) { TestResult = ConfigurationTestResult.Positive };\r\n            };\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            TestConfigurationSetResult? result = null;\r\n            Exception? exception = null;\r\n\r\n            ManualResetEvent syncCallDone = new ManualResetEvent(false);\r\n            Thread thread = new Thread(() =>\r\n            {\r\n                try\r\n                {\r\n                    result = processor.TestSet(configurationSet);\r\n                }\r\n                catch (Exception ex)\r\n                {\r\n                    exception = ex;\r\n                }\r\n\r\n                syncCallDone.Set();\r\n            });\r\n            thread.Start();\r\n\r\n            Assert.True(isWaiting.WaitOne(5000));\r\n\r\n            var servers = WinGetServerInstance.GetInstances();\r\n            Assert.Single(servers);\r\n\r\n            var server = servers[0];\r\n            Assert.True(server.HasWindow);\r\n\r\n            // This is the call pattern from Windows\r\n            this.SendMessageAndLog(server, WindowMessage.QueryEndSession);\r\n\r\n            Thread thread2 = new Thread(() =>\r\n            {\r\n                // Release the wait after initiating the shutdown, but before waiting on it\r\n                waitingOn.Set();\r\n            });\r\n            thread2.Start();\r\n\r\n            this.SendMessageAndLog(server, WindowMessage.EndSession);\r\n            this.SendMessageAndLog(server, WindowMessage.Close);\r\n\r\n            Assert.True(syncCallDone.WaitOne(5000));\r\n\r\n            Assert.NotNull(exception);\r\n\r\n            Assert.True(server.Process.WaitForExit(5000));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Initiates a shutdown on the process when it is running an asynchronous operation.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ShutdownSynchronization_AsyncCall()\r\n        {\r\n            this.Fixture.RecreateStatics();\r\n\r\n            ConfigurationSet configurationSet = this.ConfigurationSet();\r\n            ConfigurationUnit configurationUnitWaits = this.ConfigurationUnit();\r\n            ConfigurationUnit configurationUnitWorks = this.ConfigurationUnit();\r\n            configurationSet.Units = new ConfigurationUnit[] { configurationUnitWaits, configurationUnitWorks };\r\n\r\n            TestConfigurationProcessorFactory factory = new TestConfigurationProcessorFactory();\r\n            TestConfigurationSetProcessor setProcessor = factory.CreateTestProcessor(configurationSet);\r\n            TestConfigurationUnitProcessor unitProcessor = setProcessor.CreateTestProcessor(configurationUnitWaits);\r\n\r\n            ManualResetEvent isWaiting = new ManualResetEvent(false);\r\n            ManualResetEvent waitingOn = new ManualResetEvent(false);\r\n            unitProcessor.TestSettingsDelegate = () =>\r\n            {\r\n                isWaiting.Set();\r\n                waitingOn.WaitOne();\r\n                return new TestSettingsResultInstance(configurationUnitWaits) { TestResult = ConfigurationTestResult.Positive };\r\n            };\r\n\r\n            ConfigurationProcessor processor = this.CreateConfigurationProcessorWithDiagnostics(factory);\r\n\r\n            var operation = processor.TestSetAsync(configurationSet);\r\n            Assert.True(isWaiting.WaitOne(5000));\r\n\r\n            var servers = WinGetServerInstance.GetInstances();\r\n            Assert.Single(servers);\r\n\r\n            var server = servers[0];\r\n            Assert.True(server.HasWindow);\r\n\r\n            // This is the call pattern from Windows\r\n            this.SendMessageAndLog(server, WindowMessage.QueryEndSession);\r\n\r\n            Thread thread2 = new Thread(() =>\r\n            {\r\n                // Release the wait after initiating the shutdown, but before waiting on it\r\n                waitingOn.Set();\r\n            });\r\n            thread2.Start();\r\n\r\n            this.SendMessageAndLog(server, WindowMessage.EndSession);\r\n            this.SendMessageAndLog(server, WindowMessage.Close);\r\n\r\n            Assert.ThrowsAny<Exception>(() => operation.GetAwaiter().GetResult());\r\n\r\n            Assert.True(server.Process.WaitForExit(5000));\r\n        }\r\n\r\n        private void SendMessageAndLog(WinGetServerInstance server, WindowMessage message)\r\n        {\r\n            this.Log.WriteLine($\"Sending message {message} to process {server.Process.Id}...\");\r\n            try\r\n            {\r\n                if (server.SendMessage(message))\r\n                {\r\n                    this.Log.WriteLine(\"... succeeded.\");\r\n                }\r\n                else\r\n                {\r\n                    this.Log.WriteLine(\"... failed.\");\r\n                }\r\n            }\r\n            catch (Exception e)\r\n            {\r\n                this.Log.WriteLine($\"... had exception: {e.Message}\");\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/TypeHelpersTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"TypeHelpersTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System.Collections;\r\n    using System.Collections.Generic;\r\n    using Microsoft.Management.Configuration.Processor.Helpers;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using Windows.Foundation.Collections;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n\r\n    /// <summary>\r\n    /// TypeHelpers tests.\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [InProc]\r\n    public class TypeHelpersTests\r\n    {\r\n        private readonly UnitTestFixture fixture;\r\n        private readonly ITestOutputHelper log;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"TypeHelpersTests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Unit test fixture.</param>\r\n        /// <param name=\"log\">Log helper.</param>\r\n        public TypeHelpersTests(UnitTestFixture fixture, ITestOutputHelper log)\r\n        {\r\n            this.fixture = fixture;\r\n            this.log = log;\r\n        }\r\n\r\n        private enum TestEnum\r\n        {\r\n            Value,\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests PropertyExists.\r\n        /// </summary>\r\n        [Fact]\r\n        public void PropertyExistsTests()\r\n        {\r\n            dynamic obj = new\r\n            {\r\n                Property1 = \"value\",\r\n            };\r\n\r\n            Assert.True(TypeHelpers.PropertyExists(obj, \"Property1\"));\r\n            Assert.False(TypeHelpers.PropertyExists(obj, \"Property2\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests PropertyWithTypeExists.\r\n        /// </summary>\r\n        [Fact]\r\n        public void PropertyWithTypeExistsTests()\r\n        {\r\n            dynamic obj = new\r\n            {\r\n                Property1 = \"value\",\r\n                Property2 = 42,\r\n            };\r\n\r\n            Assert.True(TypeHelpers.PropertyWithTypeExists<string>(obj, \"Property1\"));\r\n            Assert.True(TypeHelpers.PropertyWithTypeExists<int>(obj, \"Property2\"));\r\n\r\n            Assert.False(TypeHelpers.PropertyWithTypeExists<int>(obj, \"Property1\"));\r\n            Assert.False(TypeHelpers.PropertyWithTypeExists<string>(obj, \"Property2\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test PropertyExistsAndIsEnum.\r\n        /// </summary>\r\n        [Fact]\r\n        public void PropertyExistsAndIsEnumTests()\r\n        {\r\n            dynamic obj = new\r\n            {\r\n                Property1 = TestEnum.Value,\r\n                Property2 = \"string\",\r\n            };\r\n\r\n            Assert.True(TypeHelpers.PropertyExistsAndIsEnum(obj, \"Property1\"));\r\n            Assert.False(TypeHelpers.PropertyExistsAndIsEnum(obj, \"Property2\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests PropertyExistsAndIsList.\r\n        /// </summary>\r\n        [Fact]\r\n        public void PropertyExistsAndIsListTests()\r\n        {\r\n            dynamic obj = new\r\n            {\r\n                Property1 = new List<string>() { \"value\" },\r\n                Property2 = \"string\",\r\n            };\r\n\r\n            Assert.True(TypeHelpers.PropertyExistsAndIsList(obj, \"Property1\"));\r\n            Assert.False(TypeHelpers.PropertyExistsAndIsList(obj, \"Property2\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests GetAllPropertiesValues.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetAllPropertiesValuesTests()\r\n        {\r\n            string s = \"value\";\r\n            int i = 42;\r\n            TestEnum e = TestEnum.Value;\r\n            dynamic obj = new\r\n            {\r\n                Property1 = s,\r\n                Property2 = i,\r\n                Property3 = e,\r\n            };\r\n\r\n            ValueSet set = TypeHelpers.GetAllPropertiesValues(obj);\r\n            Assert.Equal(3, set.Count);\r\n\r\n            Assert.True(set.ContainsKey(\"Property1\"));\r\n            Assert.True(set.TryGetValue(\"Property1\", out object v1));\r\n            Assert.Equal(s, v1 as string);\r\n\r\n            Assert.True(set.ContainsKey(\"Property2\"));\r\n            Assert.True(set.TryGetValue(\"Property2\", out object v2));\r\n            Assert.Equal(i, (int)v2);\r\n\r\n            Assert.True(set.ContainsKey(\"Property3\"));\r\n            Assert.True(set.TryGetValue(\"Property3\", out object v3));\r\n            Assert.Equal(e.ToString(), v3);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies when a property is a Hashtable. It must be converted to a ValueSet.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetAllPropertiesValuesTest_Hashtable()\r\n        {\r\n            string k1 = \"key1\";\r\n            string k2 = \"key2\";\r\n            int v1 = 7;\r\n            string v2 = \"value2\";\r\n            dynamic obj = new\r\n            {\r\n                Property1 = new Hashtable\r\n                {\r\n                    { k1, v1 },\r\n                    { k2, v2 },\r\n                },\r\n            };\r\n\r\n            ValueSet set = TypeHelpers.GetAllPropertiesValues(obj);\r\n            Assert.Single(set);\r\n\r\n            Assert.True(set.ContainsKey(\"Property1\"));\r\n            Assert.True(set.TryGetValue(\"Property1\", out object valueSetResultObj));\r\n\r\n            ValueSet? valueSetResult = valueSetResultObj as ValueSet;\r\n            Assert.NotNull(valueSetResult);\r\n            Assert.Equal(2, valueSetResult.Count);\r\n            Assert.True(valueSetResult.ContainsKey(k1));\r\n            Assert.Equal(v1, (int)valueSetResult[k1]);\r\n            Assert.True(valueSetResult.ContainsKey(k2));\r\n            Assert.Equal(v2, (string)valueSetResult[k2]);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Verifies when a property is an array. It must generate a ValueSet\r\n        /// where the keys are the index and a key treatAsArray means the value\r\n        /// must be treated an array.\r\n        /// </summary>\r\n        [Fact]\r\n        public void GetAllPropertiesValuesTest_Array()\r\n        {\r\n            dynamic obj = new\r\n            {\r\n                Property1 = new int[]\r\n                {\r\n                    1,\r\n                    2,\r\n                    3,\r\n                    4,\r\n                },\r\n            };\r\n\r\n            ValueSet set = TypeHelpers.GetAllPropertiesValues(obj);\r\n            Assert.Single(set);\r\n\r\n            Assert.True(set.ContainsKey(\"Property1\"));\r\n            Assert.True(set.TryGetValue(\"Property1\", out object valueSetResultObj));\r\n\r\n            ValueSet? valueSetResult = valueSetResultObj as ValueSet;\r\n            Assert.NotNull(valueSetResult);\r\n            Assert.Equal(5, valueSetResult.Count);\r\n\r\n            Assert.True(valueSetResult.ContainsKey(\"treatAsArray\"));\r\n            Assert.True(valueSetResult.ContainsKey(\"0\"));\r\n            Assert.True(valueSetResult.ContainsKey(\"1\"));\r\n            Assert.True(valueSetResult.ContainsKey(\"2\"));\r\n            Assert.True(valueSetResult.ContainsKey(\"3\"));\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Configuration.UnitTests/Tests/ValueSetExtensionsTests.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ValueSetExtensionsTests.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.Management.Configuration.UnitTests.Tests\r\n{\r\n    using System;\r\n    using System.Collections;\r\n    using System.Collections.Generic;\r\n    using Microsoft.Management.Configuration.Processor.Extensions;\r\n    using Microsoft.Management.Configuration.UnitTests.Fixtures;\r\n    using Microsoft.Management.Configuration.UnitTests.Helpers;\r\n    using Windows.Foundation.Collections;\r\n    using Xunit;\r\n    using Xunit.Abstractions;\r\n\r\n    /// <summary>\r\n    /// ValueSet extension tests.\r\n    /// </summary>\r\n    [Collection(\"UnitTestCollection\")]\r\n    [InProc]\r\n    public class ValueSetExtensionsTests\r\n    {\r\n        private readonly UnitTestFixture fixture;\r\n        private readonly ITestOutputHelper log;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ValueSetExtensionsTests\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fixture\">Unit test fixture.</param>\r\n        /// <param name=\"log\">Log helper.</param>\r\n        public ValueSetExtensionsTests(UnitTestFixture fixture, ITestOutputHelper log)\r\n        {\r\n            this.fixture = fixture;\r\n            this.log = log;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests PropertyExists.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ValueSet_SimpleTypes()\r\n        {\r\n            string stringProperty = \"stringProperty\";\r\n            string stringPropertyValue = \"string\";\r\n\r\n            string intProperty = \"intProperty\";\r\n            long intPropertyValue = 64;\r\n\r\n            string boolProperty = \"boolProperty\";\r\n            bool boolPropertyValue = true;\r\n\r\n            var valueSet = new ValueSet\r\n            {\r\n                { stringProperty, stringPropertyValue },\r\n                { intProperty, intPropertyValue },\r\n                { boolProperty, boolPropertyValue },\r\n            };\r\n\r\n            var resultHashtable = valueSet.ToHashtable();\r\n\r\n            Assert.NotNull(resultHashtable);\r\n\r\n            Assert.True(resultHashtable.ContainsKey(stringProperty));\r\n            Assert.Equal(stringPropertyValue, resultHashtable[stringProperty]);\r\n\r\n            Assert.True(resultHashtable.ContainsKey(intProperty));\r\n            Assert.Equal(intPropertyValue, resultHashtable[intProperty]);\r\n\r\n            Assert.True(resultHashtable.ContainsKey(boolProperty));\r\n            Assert.Equal(boolPropertyValue, resultHashtable[boolProperty]);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests when a ValueSet has inner value sets.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ValueSet_NestedValueSets()\r\n        {\r\n            string boolPropertyInner = \"boolPropertyInner\";\r\n            bool boolPropertyValueInner = true;\r\n            var valueSetInner = new ValueSet()\r\n            {\r\n                { boolPropertyInner, boolPropertyValueInner },\r\n            };\r\n\r\n            string stringPropertyInnerInner = \"stringPropertyInnerInner\";\r\n            string stringPropertyValueInnerInner = \"stringInnerInner\";\r\n            var valueSetInnerInner = new ValueSet()\r\n            {\r\n                { stringPropertyInnerInner, stringPropertyValueInnerInner },\r\n            };\r\n\r\n            string inner2Key = \"InnerKey2\";\r\n            var valueSetInner2 = new ValueSet()\r\n            {\r\n                { inner2Key, valueSetInnerInner },\r\n            };\r\n\r\n            string key1 = \"key1\";\r\n            string key2 = \"key2\";\r\n            var valueSet = new ValueSet()\r\n            {\r\n                { key1, valueSetInner },\r\n                { key2, valueSetInner2 },\r\n            };\r\n\r\n            var hashtable = valueSet.ToHashtable();\r\n            Assert.NotNull(hashtable);\r\n            Assert.Equal(2, hashtable.Count);\r\n            Assert.True(hashtable.ContainsKey(key1));\r\n            Assert.True(hashtable.ContainsKey(key2));\r\n\r\n            var key1Result = hashtable[key1] as Hashtable;\r\n            Assert.NotNull(key1Result);\r\n            Assert.Single(key1Result);\r\n            Assert.True(key1Result.ContainsKey(boolPropertyInner));\r\n            Assert.Equal(boolPropertyValueInner, key1Result[boolPropertyInner]);\r\n\r\n            var key2Result = hashtable[key2] as Hashtable;\r\n            Assert.NotNull(key2Result);\r\n            Assert.Single(key2Result);\r\n            Assert.True(key2Result.ContainsKey(inner2Key));\r\n            var key2ResultInner = key2Result[inner2Key] as Hashtable;\r\n            Assert.NotNull(key2ResultInner);\r\n            Assert.True(key2ResultInner.ContainsKey(stringPropertyInnerInner));\r\n            Assert.Equal(stringPropertyValueInnerInner, key2ResultInner[stringPropertyInnerInner]);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test when ValueSet contains a ValueSet that is threated as an.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ValueSet_ArraySimpleTypes()\r\n        {\r\n            var valueSetArray = new ValueSet()\r\n            {\r\n                { \"treatAsArray\", true },\r\n                { \"0\", \"value1\" },\r\n                { \"1\", \"value1\" },\r\n                { \"2\", \"value1\" },\r\n                { \"3\", \"value1\" },\r\n            };\r\n\r\n            string arrayKey = \"arrayKey\";\r\n            var valueSet = new ValueSet()\r\n            {\r\n                { arrayKey, valueSetArray },\r\n            };\r\n\r\n            var hashtable = valueSet.ToHashtable();\r\n            Assert.NotNull(hashtable);\r\n            Assert.True(hashtable.ContainsKey(arrayKey));\r\n\r\n            var expectedList = hashtable[arrayKey] as IList<object>;\r\n            Assert.NotNull(expectedList);\r\n            Assert.Equal(4, expectedList.Count);\r\n            foreach (var element in expectedList)\r\n            {\r\n                Assert.IsType<string>(element);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test ValueSet with an array of value sets.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ValueSet_ArrayHashtable()\r\n        {\r\n            var arrayValue1 = new ValueSet()\r\n            {\r\n                { \"key11\", \"value11\" },\r\n                { \"key12\", \"value12\" },\r\n            };\r\n\r\n            var arrayValue2 = new ValueSet()\r\n            {\r\n                { \"key21\", \"value21\" },\r\n            };\r\n\r\n            var valueSetArray = new ValueSet()\r\n            {\r\n                { \"treatAsArray\", true },\r\n                { \"0\", arrayValue1 },\r\n                { \"1\", arrayValue2 },\r\n            };\r\n\r\n            string arrayKey = \"arrayKey\";\r\n            var valueSet = new ValueSet()\r\n            {\r\n                { arrayKey, valueSetArray },\r\n            };\r\n\r\n            var hashtable = valueSet.ToHashtable();\r\n            Assert.NotNull(hashtable);\r\n            Assert.True(hashtable.ContainsKey(arrayKey));\r\n\r\n            var expectedList = hashtable[arrayKey] as IList<object>;\r\n            Assert.NotNull(expectedList);\r\n            Assert.Equal(2, expectedList.Count);\r\n\r\n            var resultValue1 = expectedList[0] as Hashtable;\r\n            Assert.NotNull(resultValue1);\r\n            Assert.Equal(2, resultValue1.Count);\r\n\r\n            var resultValue2 = expectedList[1] as Hashtable;\r\n            Assert.NotNull(resultValue2);\r\n            Assert.Single(resultValue2);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests ConvertValueSetToArray.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ValueSet_ArrayOrder()\r\n        {\r\n            string arrayValue0 = \"arrayValue0\";\r\n            string arrayValue1 = \"arrayValue1\";\r\n            string arrayValue2 = \"arrayValue2\";\r\n            string arrayValue3 = \"arrayValue3\";\r\n            string arrayValue4 = \"arrayValue4\";\r\n            string arrayValue5 = \"arrayValue5\";\r\n            string arrayValue6 = \"arrayValue6\";\r\n            string arrayValue7 = \"arrayValue7\";\r\n            string arrayValue8 = \"arrayValue8\";\r\n            string arrayValue9 = \"arrayValue9\";\r\n            string arrayValue10 = \"arrayValue10\";\r\n            string arrayValue11 = \"arrayValue11\";\r\n            string arrayValue12 = \"arrayValue12\";\r\n            var valueSetArray = new ValueSet()\r\n            {\r\n                { \"10\", arrayValue10 },\r\n                { \"7\", arrayValue7 },\r\n                { \"2\", arrayValue2 },\r\n                { \"12\", arrayValue12 },\r\n                { \"6\", arrayValue6 },\r\n                { \"treatAsArray\", true },\r\n                { \"3\", arrayValue3 },\r\n                { \"1\", arrayValue1 },\r\n                { \"9\", arrayValue9 },\r\n                { \"0\", arrayValue0 },\r\n                { \"4\", arrayValue4 },\r\n                { \"11\", arrayValue11 },\r\n                { \"8\", arrayValue8 },\r\n                { \"5\", arrayValue5 },\r\n            };\r\n\r\n            var result = valueSetArray.ToArray();\r\n            Assert.NotNull(result);\r\n            Assert.Equal(valueSetArray.Count - 1, result.Count);\r\n            Assert.Equal(arrayValue0, result[0]);\r\n            Assert.Equal(arrayValue1, result[1]);\r\n            Assert.Equal(arrayValue2, result[2]);\r\n            Assert.Equal(arrayValue3, result[3]);\r\n            Assert.Equal(arrayValue4, result[4]);\r\n            Assert.Equal(arrayValue5, result[5]);\r\n            Assert.Equal(arrayValue6, result[6]);\r\n            Assert.Equal(arrayValue7, result[7]);\r\n            Assert.Equal(arrayValue8, result[8]);\r\n            Assert.Equal(arrayValue9, result[9]);\r\n            Assert.Equal(arrayValue10, result[10]);\r\n            Assert.Equal(arrayValue11, result[11]);\r\n            Assert.Equal(arrayValue12, result[12]);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests ConvertValueSetToArray.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ValueSet_InvalidArray()\r\n        {\r\n            string arrayValue0 = \"arrayValue0\";\r\n            string arrayValue1 = \"arrayValue1\";\r\n            string arrayValue2 = \"arrayValue2\";\r\n            string arrayValue3 = \"arrayValue3\";\r\n            string arrayValue4 = \"arrayValue4\";\r\n            string arrayValue5 = \"arrayValue5\";\r\n            string arrayValue6 = \"arrayValue6\";\r\n            string arrayValue7 = \"arrayValue7\";\r\n            string arrayValue8 = \"arrayValue8\";\r\n            string arrayValue9 = \"arrayValue9\";\r\n            string arrayValue10 = \"arrayValue10\";\r\n            string arrayValue11 = \"arrayValue11\";\r\n            string arrayValue12 = \"arrayValue12\";\r\n            var valueSetArray = new ValueSet()\r\n            {\r\n                { \"10\", arrayValue10 },\r\n                { \"7\", arrayValue7 },\r\n                { \"2\", arrayValue2 },\r\n                { \"12\", arrayValue12 },\r\n                { \"6\", arrayValue6 },\r\n                { \"3\", arrayValue3 },\r\n                { \"1\", arrayValue1 },\r\n                { \"9\", arrayValue9 },\r\n                { \"0\", arrayValue0 },\r\n                { \"4\", arrayValue4 },\r\n                { \"11\", arrayValue11 },\r\n                { \"8\", arrayValue8 },\r\n                { \"5\", arrayValue5 },\r\n            };\r\n\r\n            Assert.Throws<InvalidOperationException>(() => valueSetArray.ToArray());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests ConvertValueSetToArray.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ValueSet_InvalidArrayKey()\r\n        {\r\n            string arrayValue0 = \"arrayValue0\";\r\n            string arrayValue1 = \"arrayValue1\";\r\n            string arrayValue2 = \"arrayValue2\";\r\n            string arrayValue3 = \"arrayValue3\";\r\n            string arrayValue4 = \"arrayValue4\";\r\n            string arrayValue5 = \"arrayValue5\";\r\n            string arrayValue6 = \"arrayValue6\";\r\n            string arrayValue7 = \"arrayValue7\";\r\n            string arrayValue8 = \"arrayValue8\";\r\n            string arrayValue9 = \"arrayValue9\";\r\n            string arrayValue10 = \"arrayValue10\";\r\n            string arrayValue11 = \"arrayValue11\";\r\n            string arrayValue12 = \"arrayValue12\";\r\n            var valueSetArray = new ValueSet()\r\n            {\r\n                { \"10\", arrayValue10 },\r\n                { \"7\", arrayValue7 },\r\n                { \"2\", arrayValue2 },\r\n                { \"a\", arrayValue12 },\r\n                { \"6\", arrayValue6 },\r\n                { \"3\", arrayValue3 },\r\n                { \"1\", arrayValue1 },\r\n                { \"9\", arrayValue9 },\r\n                { \"0\", arrayValue0 },\r\n                { \"4\", arrayValue4 },\r\n                { \"11\", arrayValue11 },\r\n                { \"8\", arrayValue8 },\r\n                { \"5\", arrayValue5 },\r\n            };\r\n\r\n            Assert.Throws<InvalidOperationException>(() => valueSetArray.ToArray());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests ValueSet simple types content equals.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ValueSet_SimpleTypes_ContentEquals()\r\n        {\r\n            string stringProperty = \"stringProperty\";\r\n            string stringPropertyValue = \"string\";\r\n\r\n            string intProperty = \"intProperty\";\r\n            long intPropertyValue = 64;\r\n\r\n            string boolProperty = \"boolProperty\";\r\n            bool boolPropertyValue = true;\r\n\r\n            var valueSet = new ValueSet\r\n            {\r\n                { stringProperty, stringPropertyValue },\r\n                { intProperty, intPropertyValue },\r\n                { boolProperty, boolPropertyValue },\r\n            };\r\n\r\n            // Same content different order\r\n            var valueSetDifferentOrder = new ValueSet\r\n            {\r\n                { boolProperty, boolPropertyValue },\r\n                { stringProperty, stringPropertyValue },\r\n                { intProperty, intPropertyValue },\r\n            };\r\n\r\n            Assert.True(valueSet.ContentEquals(valueSetDifferentOrder));\r\n\r\n            // Entry missing\r\n            var valueSetEntryMissing = new ValueSet\r\n            {\r\n                { stringProperty, stringPropertyValue },\r\n                { intProperty, intPropertyValue },\r\n            };\r\n\r\n            Assert.False(valueSet.ContentEquals(valueSetEntryMissing));\r\n\r\n            // Different entry\r\n            var valueSetEntryDifferent = new ValueSet\r\n            {\r\n                { stringProperty, stringPropertyValue },\r\n                { intProperty, intPropertyValue },\r\n                { \"Another\", \"AnotherValue\" },\r\n            };\r\n\r\n            Assert.False(valueSet.ContentEquals(valueSetEntryDifferent));\r\n\r\n            // Different value\r\n            var valueSetDifferentValue = new ValueSet\r\n            {\r\n                { boolProperty, boolPropertyValue },\r\n                { stringProperty, stringPropertyValue },\r\n                { intProperty, 0 },\r\n            };\r\n\r\n            Assert.False(valueSet.ContentEquals(valueSetDifferentValue));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tests when a ValueSet has inner value sets.\r\n        /// </summary>\r\n        [Fact]\r\n        public void ValueSet_NestedValueSets_ContentEquals()\r\n        {\r\n            string boolPropertyInner = \"boolPropertyInner\";\r\n            bool boolPropertyValueInner = true;\r\n            var valueSetInner = new ValueSet()\r\n            {\r\n                { boolPropertyInner, boolPropertyValueInner },\r\n            };\r\n\r\n            string stringPropertyInnerInner = \"stringPropertyInnerInner\";\r\n            string stringPropertyValueInnerInner = \"stringInnerInner\";\r\n            var valueSetInnerInner = new ValueSet()\r\n            {\r\n                { stringPropertyInnerInner, stringPropertyValueInnerInner },\r\n            };\r\n\r\n            string inner2Key = \"InnerKey2\";\r\n            var valueSetInner2 = new ValueSet()\r\n            {\r\n                { inner2Key, valueSetInnerInner },\r\n            };\r\n\r\n            string key1 = \"key1\";\r\n            string key2 = \"key2\";\r\n            var valueSet = new ValueSet()\r\n            {\r\n                { key1, valueSetInner },\r\n                { key2, valueSetInner2 },\r\n            };\r\n\r\n            // Same content different order\r\n            var valueSetDifferentOrder = new ValueSet()\r\n            {\r\n                { key2, valueSetInner2 },\r\n                { key1, valueSetInner },\r\n            };\r\n\r\n            Assert.True(valueSet.ContentEquals(valueSetDifferentOrder));\r\n\r\n            // Different nested content\r\n            var valueSetDifferentContent = new ValueSet()\r\n            {\r\n                { key2, valueSetInner },\r\n                { key1, valueSetInner2 },\r\n            };\r\n\r\n            Assert.False(valueSet.ContentEquals(valueSetDifferentContent));\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/AddPackageCatalogOptions.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#pragma warning( push )\r\n#pragma warning ( disable : 4467 6388)\r\n// 6388 Allow CreateInstance.\r\n#include <wil\\cppwinrt_wrl.h>\r\n// 4467 Allow use of uuid attribute for com object creation.\r\n#include \"AddPackageCatalogOptions.h\"\r\n#pragma warning( pop )\r\n#include \"AddPackageCatalogOptions.g.cpp\"\r\n#include \"Converters.h\"\r\n#include \"Helpers.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    hstring AddPackageCatalogOptions::Name()\r\n    {\r\n        return hstring(m_name);\r\n    }\r\n    void AddPackageCatalogOptions::Name(hstring const& value)\r\n    {\r\n        m_name = value;\r\n    }\r\n    hstring AddPackageCatalogOptions::SourceUri()\r\n    {\r\n        return hstring(m_sourceUri);\r\n    }\r\n    void AddPackageCatalogOptions::SourceUri(hstring const& value)\r\n    {\r\n        m_sourceUri = value;\r\n    }\r\n    hstring AddPackageCatalogOptions::Type()\r\n    {\r\n        return hstring(m_type);\r\n    }\r\n    void AddPackageCatalogOptions::Type(hstring const& value)\r\n    {\r\n        m_type = value;\r\n    }\r\n    winrt::Microsoft::Management::Deployment::PackageCatalogTrustLevel AddPackageCatalogOptions::TrustLevel()\r\n    {\r\n        return m_trustLevel;\r\n    }\r\n    void AddPackageCatalogOptions::TrustLevel(winrt::Microsoft::Management::Deployment::PackageCatalogTrustLevel const& value)\r\n    {\r\n        m_trustLevel = value;\r\n    }\r\n    hstring AddPackageCatalogOptions::CustomHeader()\r\n    {\r\n        return hstring(m_customHeader);\r\n    }\r\n    void AddPackageCatalogOptions::CustomHeader(hstring const& value)\r\n    {\r\n        m_customHeader = value;\r\n    }\r\n    bool AddPackageCatalogOptions::Explicit()\r\n    {\r\n        return m_explicit;\r\n    }\r\n    void AddPackageCatalogOptions::Explicit(bool value)\r\n    {\r\n        m_explicit = value;\r\n    }\r\n\r\n    int32_t AddPackageCatalogOptions::Priority()\r\n    {\r\n        return m_priority;\r\n    }\r\n\r\n    void AddPackageCatalogOptions::Priority(int32_t value)\r\n    {\r\n        m_priority = value;\r\n    }\r\n\r\n    CoCreatableMicrosoftManagementDeploymentClass(AddPackageCatalogOptions);\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/AddPackageCatalogOptions.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"AddPackageCatalogOptions.g.h\"\r\n#include \"public/ComClsids.h\"\r\n#include <winget/ModuleCountBase.h>\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    [uuid(WINGET_OUTOFPROC_COM_CLSID_AddPackageCatalogOptions)]\r\n    struct AddPackageCatalogOptions : AddPackageCatalogOptionsT<AddPackageCatalogOptions>\r\n    {\r\n        AddPackageCatalogOptions() = default;\r\n\r\n        hstring Name();\r\n        void Name(hstring const& value);\r\n\r\n        hstring SourceUri();\r\n        void SourceUri(hstring const& value);\r\n\r\n        hstring Type();\r\n        void Type(hstring const& value);\r\n\r\n        winrt::Microsoft::Management::Deployment::PackageCatalogTrustLevel TrustLevel();\r\n        void TrustLevel(winrt::Microsoft::Management::Deployment::PackageCatalogTrustLevel const& value);\r\n\r\n        hstring CustomHeader();\r\n        void CustomHeader(hstring const& value);\r\n\r\n        bool Explicit();\r\n        void Explicit(bool value);\r\n\r\n        int32_t Priority();\r\n        void Priority(int32_t value);\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        hstring m_name = L\"\";\r\n        hstring m_sourceUri = L\"\";\r\n        hstring m_type = L\"\";\r\n        winrt::Microsoft::Management::Deployment::PackageCatalogTrustLevel m_trustLevel = winrt::Microsoft::Management::Deployment::PackageCatalogTrustLevel::None;\r\n        hstring m_customHeader = L\"\";\r\n        bool m_explicit = false;\r\n        int32_t m_priority = 0;\r\n#endif\r\n    };\r\n}\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\nnamespace winrt::Microsoft::Management::Deployment::factory_implementation\r\n{\r\n    struct AddPackageCatalogOptions : AddPackageCatalogOptionsT<AddPackageCatalogOptions, implementation::AddPackageCatalogOptions>, AppInstaller::WinRT::ModuleCountBase\r\n    {\r\n    };\r\n}\r\n#endif\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/AddPackageCatalogResult.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"AddPackageCatalogResult.h\"\r\n#include \"AddPackageCatalogResult.g.cpp\"\r\n#include <wil\\cppwinrt_wrl.h>\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    void AddPackageCatalogResult::Initialize(\r\n        winrt::Microsoft::Management::Deployment::AddPackageCatalogStatus status,\r\n        winrt::hresult extendedErrorCode)\r\n    {\r\n        m_status = status;\r\n        m_extendedErrorCode = extendedErrorCode;\r\n    }\r\n    winrt::Microsoft::Management::Deployment::AddPackageCatalogStatus AddPackageCatalogResult::Status()\r\n    {\r\n        return m_status;\r\n    }\r\n    winrt::hresult AddPackageCatalogResult::ExtendedErrorCode()\r\n    {\r\n        return m_extendedErrorCode;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/AddPackageCatalogResult.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"AddPackageCatalogResult.g.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    struct AddPackageCatalogResult : AddPackageCatalogResultT<AddPackageCatalogResult>\r\n    {\r\n        AddPackageCatalogResult() = default;\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        void Initialize(\r\n            winrt::Microsoft::Management::Deployment::AddPackageCatalogStatus status,\r\n            winrt::hresult extendedErrorCode);\r\n#endif\r\n\r\n        winrt::Microsoft::Management::Deployment::AddPackageCatalogStatus Status();\r\n        winrt::hresult ExtendedErrorCode();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        winrt::Microsoft::Management::Deployment::AddPackageCatalogStatus m_status = winrt::Microsoft::Management::Deployment::AddPackageCatalogStatus::Ok;\r\n        winrt::hresult m_extendedErrorCode = S_OK;\r\n#endif\r\n    };\r\n}\r\n#pragma once\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/AuthenticationArguments.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#pragma warning( push )\n#pragma warning ( disable : 4467 6388)\n// 6388 Allow CreateInstance.\n#include <wil\\cppwinrt_wrl.h>\n// 4467 Allow use of uuid attribute for com object creation.\n#include \"AuthenticationArguments.h\"\n#pragma warning( pop )\n#include \"AuthenticationArguments.g.cpp\"\n#include \"Helpers.h\"\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    winrt::Microsoft::Management::Deployment::AuthenticationMode AuthenticationArguments::AuthenticationMode()\n    {\n        return m_authenticationMode;\n    }\n    void AuthenticationArguments::AuthenticationMode(winrt::Microsoft::Management::Deployment::AuthenticationMode const& value)\n    {\n        m_authenticationMode = value;\n    }\n    hstring AuthenticationArguments::AuthenticationAccount()\n    {\n        return winrt::hstring(m_authenticationAccount);\n    }\n    void AuthenticationArguments::AuthenticationAccount(hstring const& value)\n    {\n        m_authenticationAccount = value;\n    }\n    CoCreatableMicrosoftManagementDeploymentClass(AuthenticationArguments);\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/AuthenticationArguments.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"AuthenticationArguments.g.h\"\n#include \"Public/ComClsids.h\"\n#include <winget/ModuleCountBase.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    [uuid(WINGET_OUTOFPROC_COM_CLSID_AuthenticationArguments)]\n    struct AuthenticationArguments : AuthenticationArgumentsT<AuthenticationArguments>\n    {\n        AuthenticationArguments() = default;\n\n        winrt::Microsoft::Management::Deployment::AuthenticationMode AuthenticationMode();\n        void AuthenticationMode(winrt::Microsoft::Management::Deployment::AuthenticationMode const& value);\n        hstring AuthenticationAccount();\n        void AuthenticationAccount(hstring const& value);\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        winrt::Microsoft::Management::Deployment::AuthenticationMode m_authenticationMode = winrt::Microsoft::Management::Deployment::AuthenticationMode::Silent;\n        std::wstring m_authenticationAccount = L\"\";\n#endif\n    };\n}\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\nnamespace winrt::Microsoft::Management::Deployment::factory_implementation\n{\n    struct AuthenticationArguments : AuthenticationArgumentsT<AuthenticationArguments, implementation::AuthenticationArguments>, AppInstaller::WinRT::ModuleCountBase\n    {\n    };\n}\n#endif\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/AuthenticationInfo.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"AuthenticationInfo.h\"\n#include \"AuthenticationInfo.g.cpp\"\n#include \"MicrosoftEntraIdAuthenticationInfo.h\"\n#include \"Converters.h\"\n#include <wil\\cppwinrt_wrl.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    void AuthenticationInfo::Initialize(::AppInstaller::Authentication::AuthenticationInfo authenticationInfo)\n    {\n        m_authenticationType = GetDeploymentAuthenticationType(authenticationInfo.Type);\n\n        if (authenticationInfo.MicrosoftEntraIdInfo.has_value())\n        {\n            auto microsoftEntraIdAuthenticationInfo = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::MicrosoftEntraIdAuthenticationInfo>>();\n            microsoftEntraIdAuthenticationInfo->Initialize(authenticationInfo.MicrosoftEntraIdInfo.value());\n            m_microsoftEntraIdAuthenticationInfo = *microsoftEntraIdAuthenticationInfo;\n        }\n    }\n    winrt::Microsoft::Management::Deployment::AuthenticationType AuthenticationInfo::AuthenticationType()\n    {\n        return m_authenticationType;\n    }\n    winrt::Microsoft::Management::Deployment::MicrosoftEntraIdAuthenticationInfo AuthenticationInfo::MicrosoftEntraIdAuthenticationInfo()\n    {\n        return m_microsoftEntraIdAuthenticationInfo;\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/AuthenticationInfo.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"AuthenticationInfo.g.h\"\n#include <winget/Authentication.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    struct AuthenticationInfo : AuthenticationInfoT<AuthenticationInfo>\n    {\n        AuthenticationInfo() = default;\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void Initialize(::AppInstaller::Authentication::AuthenticationInfo authenticationInfo);\n#endif\n\n        winrt::Microsoft::Management::Deployment::AuthenticationType AuthenticationType();\n        winrt::Microsoft::Management::Deployment::MicrosoftEntraIdAuthenticationInfo MicrosoftEntraIdAuthenticationInfo();\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        winrt::Microsoft::Management::Deployment::AuthenticationType m_authenticationType = winrt::Microsoft::Management::Deployment::AuthenticationType::None;\n        winrt::Microsoft::Management::Deployment::MicrosoftEntraIdAuthenticationInfo m_microsoftEntraIdAuthenticationInfo{ nullptr };\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/CanUnload.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    static std::atomic_bool s_canUnload = true;\r\n\r\n    void SetCanUnload(bool value)\r\n    {\r\n        s_canUnload = value;\r\n    }\r\n\r\n    bool GetCanUnload()\r\n    {\r\n        return s_canUnload;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/CatalogPackage.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include <mutex>\r\n#include <winget/RepositorySource.h>\r\n#include \"CatalogPackage.h\"\r\n#include \"CatalogPackage.g.cpp\"\r\n#include \"PackageCatalog.h\"\r\n#include \"PackageVersionInfo.h\"\r\n#include \"PackageVersionId.h\"\r\n#include \"PackageInstallerInstalledStatus.h\"\r\n#include \"CheckInstalledStatusResult.h\"\r\n#include <ComContext.h>\r\n#include <wil\\cppwinrt_wrl.h>\r\n#include <winget/PinningData.h>\r\n#include <winget/PackageVersionSelection.h>\r\n\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    void CatalogPackage::Initialize(\r\n        ::AppInstaller::Repository::Source source,\r\n        std::shared_ptr<::AppInstaller::Repository::ICompositePackage> package)\r\n    {\r\n        m_source = std::move(source);\r\n        m_package = std::move(package);\r\n    }\r\n    hstring CatalogPackage::Id()\r\n    {\r\n        return winrt::to_hstring(m_package->GetProperty(::AppInstaller::Repository::PackageProperty::Id).get());\r\n    }\r\n    hstring CatalogPackage::Name()\r\n    {\r\n        return winrt::to_hstring(m_package->GetProperty(::AppInstaller::Repository::PackageProperty::Name));\r\n    }\r\n    Microsoft::Management::Deployment::PackageVersionInfo CatalogPackage::InstalledVersion()\r\n    {\r\n        std::call_once(m_installedVersionOnceFlag,\r\n            [&]()\r\n            {\r\n                std::shared_ptr<::AppInstaller::Repository::IPackageVersion> installedVersion = GetInstalledVersion(m_package);\r\n                if (installedVersion)\r\n                {\r\n                    auto installedVersionImpl = winrt::make_self<wil::details::module_count_wrapper<\r\n                        winrt::Microsoft::Management::Deployment::implementation::PackageVersionInfo>>();\r\n                    installedVersionImpl->Initialize(std::move(installedVersion));\r\n                    m_installedVersion = *installedVersionImpl;\r\n                }\r\n            });\r\n        return m_installedVersion;\r\n    }\r\n    Windows::Foundation::Collections::IVectorView<Microsoft::Management::Deployment::PackageVersionId> CatalogPackage::AvailableVersions()\r\n    {\r\n        std::call_once(m_availableVersionsOnceFlag,\r\n            [&]()\r\n            {\r\n                // Vector hasn't been populated yet.\r\n                for (auto const& versionKey : ::AppInstaller::Repository::GetAllAvailableVersions(m_package)->GetVersionKeys())\r\n                {\r\n                    auto packageVersionId = winrt::make_self<wil::details::module_count_wrapper<\r\n                        winrt::Microsoft::Management::Deployment::implementation::PackageVersionId>>();\r\n                    packageVersionId->Initialize(versionKey);\r\n                    m_availableVersions.Append(*packageVersionId);\r\n                }\r\n            });\r\n        return m_availableVersions.GetView();\r\n    }\r\n\r\n    void CatalogPackage::InitializeLatestApplicableVersion()\r\n    {\r\n        std::call_once(m_latestApplicableVersionOnceFlag,\r\n            [&]()\r\n            {\r\n                auto data = AppInstaller::Repository::GetLatestApplicableVersion(m_package);\r\n\r\n                m_updateAvailable = data.UpdateAvailable;\r\n\r\n                if (data.LatestApplicableVersion)\r\n                {\r\n                    // DefaultInstallVersion hasn't been created yet, create and populate it.\r\n                    // DefaultInstallVersion is the latest applicable version of the internal package object.\r\n                    auto latestVersionImpl = winrt::make_self<wil::details::module_count_wrapper<\r\n                        winrt::Microsoft::Management::Deployment::implementation::PackageVersionInfo>>();\r\n                    latestVersionImpl->Initialize(std::move(data.LatestApplicableVersion));\r\n                    m_latestApplicableVersion = *latestVersionImpl;\r\n                }\r\n            });\r\n    }\r\n\r\n    Microsoft::Management::Deployment::PackageVersionInfo CatalogPackage::DefaultInstallVersion()\r\n    {\r\n        InitializeLatestApplicableVersion();\r\n\r\n        if (m_latestApplicableVersion)\r\n        {\r\n            return m_latestApplicableVersion;\r\n        }\r\n        else if (AvailableVersions().Size() > 0)\r\n        {\r\n            return GetPackageVersionInfo(m_availableVersions.GetAt(0));\r\n        }\r\n        else\r\n        {\r\n            return nullptr;\r\n        }\r\n    }\r\n\r\n    Microsoft::Management::Deployment::PackageVersionInfo CatalogPackage::GetPackageVersionInfo(Microsoft::Management::Deployment::PackageVersionId const& versionKey)\r\n    {\r\n        winrt::Microsoft::Management::Deployment::PackageVersionInfo packageVersionInfo{ nullptr };\r\n\r\n        ::AppInstaller::Repository::PackageVersionKey internalVersionKey(winrt::to_string(versionKey.PackageCatalogId()), winrt::to_string(versionKey.Version()), winrt::to_string(versionKey.Channel()));\r\n        std::shared_ptr<::AppInstaller::Repository::IPackageVersion> availableVersion =\r\n            ::AppInstaller::Repository::GetAllAvailableVersions(m_package)->GetVersion(internalVersionKey);\r\n        if (availableVersion)\r\n        {\r\n            auto packageVersionInfoImpl = winrt::make_self<wil::details::module_count_wrapper<\r\n                winrt::Microsoft::Management::Deployment::implementation::PackageVersionInfo>>();\r\n            packageVersionInfoImpl->Initialize(std::move(availableVersion));\r\n            packageVersionInfo =*packageVersionInfoImpl;\r\n        }\r\n        return packageVersionInfo;\r\n    }\r\n\r\n    bool CatalogPackage::IsUpdateAvailable()\r\n    {\r\n        InitializeLatestApplicableVersion();\r\n        return m_updateAvailable;\r\n    }\r\n\r\n    Windows::Foundation::IAsyncOperation<winrt::Microsoft::Management::Deployment::CheckInstalledStatusResult> CatalogPackage::CheckInstalledStatusAsync(\r\n        Microsoft::Management::Deployment::InstalledStatusType checkTypes)\r\n    {\r\n        co_return CheckInstalledStatus(checkTypes);\r\n    }\r\n    Microsoft::Management::Deployment::CheckInstalledStatusResult CatalogPackage::CheckInstalledStatus(\r\n        Microsoft::Management::Deployment::InstalledStatusType checkTypes)\r\n    {\r\n        Microsoft::Management::Deployment::CheckInstalledStatusResultStatus status = winrt::Microsoft::Management::Deployment::CheckInstalledStatusResultStatus::Ok;\r\n        Windows::Foundation::Collections::IVector<Microsoft::Management::Deployment::PackageInstallerInstalledStatus> installedStatus{\r\n            winrt::single_threaded_vector<Microsoft::Management::Deployment::PackageInstallerInstalledStatus>() };\r\n\r\n        try\r\n        {\r\n            auto checkResult = ::AppInstaller::Repository::CheckPackageInstalledStatus(m_package, static_cast<::AppInstaller::Repository::InstalledStatusType>(checkTypes));\r\n\r\n            // Build the result object from the checkResult\r\n            for (auto const& entry : checkResult)\r\n            {\r\n                auto checkInstallerResult = winrt::make_self<wil::details::module_count_wrapper<\r\n                    winrt::Microsoft::Management::Deployment::implementation::PackageInstallerInstalledStatus>>();\r\n                checkInstallerResult->Initialize(entry);\r\n\r\n                installedStatus.Append(*checkInstallerResult);\r\n            }\r\n        }\r\n        catch (...)\r\n        {\r\n            status = winrt::Microsoft::Management::Deployment::CheckInstalledStatusResultStatus::InternalError;\r\n        }\r\n\r\n        auto checkInstalledStatusResult = winrt::make_self<wil::details::module_count_wrapper<\r\n            winrt::Microsoft::Management::Deployment::implementation::CheckInstalledStatusResult>>();\r\n        checkInstalledStatusResult->Initialize(status, installedStatus);\r\n        return *checkInstalledStatusResult;\r\n    }\r\n    winrt::Windows::Foundation::IAsyncOperation<winrt::Microsoft::Management::Deployment::CheckInstalledStatusResult> CatalogPackage::CheckInstalledStatusAsync()\r\n    {\r\n        co_return CheckInstalledStatus(InstalledStatusType::AllChecks);\r\n    }\r\n    winrt::Microsoft::Management::Deployment::CheckInstalledStatusResult CatalogPackage::CheckInstalledStatus()\r\n    {\r\n        return CheckInstalledStatus(InstalledStatusType::AllChecks);\r\n    }\r\n    std::shared_ptr<::AppInstaller::Repository::ICompositePackage> CatalogPackage::GetRepositoryPackage()\r\n    {\r\n        return m_package;\r\n    }\r\n\r\n    Windows::Foundation::IReference<int32_t> CatalogPackage::CatalogPriority()\r\n    {\r\n        return AppInstaller::Repository::GetSourcePriority(m_package);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/CatalogPackage.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"CatalogPackage.g.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    struct CatalogPackage : CatalogPackageT<CatalogPackage>\r\n    {\r\n        CatalogPackage() = default;\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        void Initialize(\r\n            ::AppInstaller::Repository::Source source,\r\n            std::shared_ptr<::AppInstaller::Repository::ICompositePackage> package);\r\n        std::shared_ptr<::AppInstaller::Repository::ICompositePackage> GetRepositoryPackage();\r\n#endif\r\n\r\n        hstring Id();\r\n        hstring Name();\r\n        winrt::Microsoft::Management::Deployment::PackageVersionInfo InstalledVersion();\r\n        winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Management::Deployment::PackageVersionId> AvailableVersions();\r\n        winrt::Microsoft::Management::Deployment::PackageVersionInfo DefaultInstallVersion();\r\n        winrt::Microsoft::Management::Deployment::PackageVersionInfo GetPackageVersionInfo(winrt::Microsoft::Management::Deployment::PackageVersionId const& versionKey);\r\n        bool IsUpdateAvailable();\r\n        // Contract 5.0\r\n        winrt::Windows::Foundation::IAsyncOperation<winrt::Microsoft::Management::Deployment::CheckInstalledStatusResult> CheckInstalledStatusAsync(\r\n            winrt::Microsoft::Management::Deployment::InstalledStatusType checkTypes);\r\n        winrt::Microsoft::Management::Deployment::CheckInstalledStatusResult CheckInstalledStatus(\r\n            winrt::Microsoft::Management::Deployment::InstalledStatusType checkTypes);\r\n        winrt::Windows::Foundation::IAsyncOperation<winrt::Microsoft::Management::Deployment::CheckInstalledStatusResult> CheckInstalledStatusAsync();\r\n        winrt::Microsoft::Management::Deployment::CheckInstalledStatusResult CheckInstalledStatus();\r\n\r\n        Windows::Foundation::IReference<int32_t> CatalogPriority();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        ::AppInstaller::Repository::Source m_source;\r\n        std::shared_ptr<::AppInstaller::Repository::ICompositePackage> m_package;\r\n        bool m_updateAvailable = false;\r\n        Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::PackageVersionId> m_availableVersions{ winrt::single_threaded_vector<winrt::Microsoft::Management::Deployment::PackageVersionId>() };\r\n        winrt::Microsoft::Management::Deployment::PackageVersionInfo m_installedVersion{ nullptr };\r\n        winrt::Microsoft::Management::Deployment::PackageVersionInfo m_latestApplicableVersion{ nullptr };\r\n        std::once_flag m_installedVersionOnceFlag;\r\n        std::once_flag m_availableVersionsOnceFlag;\r\n        std::once_flag m_latestApplicableVersionOnceFlag;\r\n\r\n        void InitializeLatestApplicableVersion();\r\n#endif\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/CatalogPackageMetadata.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include <winget/RepositorySource.h>\n#include \"CatalogPackageMetadata.h\"\n#include \"CatalogPackageMetadata.g.cpp\"\n#include <wil\\cppwinrt_wrl.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    using Localization = ::AppInstaller::Manifest::Localization;\n\n    void CatalogPackageMetadata::Initialize(::AppInstaller::Manifest::ManifestLocalization manifestLocalization)\n    {\n        m_manifestLocalization = std::move(manifestLocalization);\n    }\n\n    hstring CatalogPackageMetadata::Locale()\n    {\n        return winrt::to_hstring(m_manifestLocalization.Locale);\n    }\n    hstring CatalogPackageMetadata::Publisher()\n    {\n        return winrt::to_hstring(m_manifestLocalization.Get<Localization::Publisher>());\n    }\n    hstring CatalogPackageMetadata::PublisherUrl()\n    {\n        return winrt::to_hstring(m_manifestLocalization.Get<Localization::PublisherUrl>());\n    }\n    hstring CatalogPackageMetadata::PublisherSupportUrl()\n    {\n        return winrt::to_hstring(m_manifestLocalization.Get<Localization::PublisherSupportUrl>());\n    }\n    hstring CatalogPackageMetadata::PrivacyUrl()\n    {\n        return winrt::to_hstring(m_manifestLocalization.Get<Localization::PrivacyUrl>());\n    }\n    hstring CatalogPackageMetadata::Author()\n    {\n        return winrt::to_hstring(m_manifestLocalization.Get<Localization::Author>());\n    }\n    hstring CatalogPackageMetadata::PackageName()\n    {\n        return winrt::to_hstring(m_manifestLocalization.Get<Localization::PackageName>());\n    }\n    hstring CatalogPackageMetadata::PackageUrl()\n    {\n        return winrt::to_hstring(m_manifestLocalization.Get<Localization::PackageUrl>());\n    }\n    hstring CatalogPackageMetadata::License()\n    {\n        return winrt::to_hstring(m_manifestLocalization.Get<Localization::License>());\n    }\n    hstring CatalogPackageMetadata::LicenseUrl()\n    {\n        return winrt::to_hstring(m_manifestLocalization.Get<Localization::LicenseUrl>());\n    }\n    hstring CatalogPackageMetadata::Copyright()\n    {\n        return winrt::to_hstring(m_manifestLocalization.Get<Localization::Copyright>());\n    }\n    hstring CatalogPackageMetadata::CopyrightUrl()\n    {\n        return winrt::to_hstring(m_manifestLocalization.Get<Localization::CopyrightUrl>());\n    }\n    hstring CatalogPackageMetadata::ShortDescription()\n    {\n        return winrt::to_hstring(m_manifestLocalization.Get<Localization::ShortDescription>());\n    }\n    hstring CatalogPackageMetadata::Description()\n    {\n        return winrt::to_hstring(m_manifestLocalization.Get<Localization::Description>());\n    }\n    hstring CatalogPackageMetadata::ReleaseNotes()\n    {\n        return winrt::to_hstring(m_manifestLocalization.Get<Localization::ReleaseNotes>());\n    }\n    hstring CatalogPackageMetadata::ReleaseNotesUrl()\n    {\n        return winrt::to_hstring(m_manifestLocalization.Get<Localization::ReleaseNotesUrl>());\n    }\n    hstring CatalogPackageMetadata::PurchaseUrl()\n    {\n        return winrt::to_hstring(m_manifestLocalization.Get<Localization::PurchaseUrl>());\n    }\n    hstring CatalogPackageMetadata::InstallationNotes()\n    {\n        return winrt::to_hstring(m_manifestLocalization.Get<Localization::InstallationNotes>());\n    }\n    winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Management::Deployment::PackageAgreement> CatalogPackageMetadata::Agreements()\n    {\n        if (!m_packageAgreements)\n        {\n            auto agreements = winrt::single_threaded_vector<winrt::Microsoft::Management::Deployment::PackageAgreement>();\n            for (auto const& agreement : m_manifestLocalization.Get<AppInstaller::Manifest::Localization::Agreements>())\n            {\n                auto packageAgreement = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageAgreement>>();\n                packageAgreement->Initialize(agreement);\n                agreements.Append(*packageAgreement);\n            }\n            m_packageAgreements = agreements;\n        }\n\n        return m_packageAgreements.GetView();\n    }\n    winrt::Windows::Foundation::Collections::IVectorView<hstring> CatalogPackageMetadata::Tags()\n    {\n        if (!m_tags)\n        {\n            // Vector hasn't been created yet, create and populate it.\n            auto tags = winrt::single_threaded_vector<hstring>();\n            for (auto&& tag : m_manifestLocalization.Get<Localization::Tags>())\n            {\n                tags.Append(winrt::to_hstring(tag));\n            }\n            m_tags = tags;\n        }\n\n        return m_tags.GetView();\n    }\n    winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Management::Deployment::Documentation> CatalogPackageMetadata::Documentations()\n    {\n        if (!m_documentations)\n        {\n            auto documentations = winrt::single_threaded_vector<winrt::Microsoft::Management::Deployment::Documentation>();\n            for (auto const& documentation : m_manifestLocalization.Get<AppInstaller::Manifest::Localization::Documentations>())\n            {\n                auto documentationImpl = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::Documentation>>();\n                documentationImpl->Initialize(documentation);\n                documentations.Append(*documentationImpl);\n            }\n            m_documentations = documentations;\n        }\n\n        return m_documentations.GetView();\n    }\n    winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Management::Deployment::Icon> CatalogPackageMetadata::Icons()\n    {\n        if (!m_icons)\n        {\n            auto icons = winrt::single_threaded_vector<winrt::Microsoft::Management::Deployment::Icon>();\n            for (auto const& icon : m_manifestLocalization.Get<AppInstaller::Manifest::Localization::Icons>())\n            {\n                auto iconImpl = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::Icon>>();\n                iconImpl->Initialize(icon);\n                icons.Append(*iconImpl);\n            }\n            m_icons = icons;\n        }\n\n        return m_icons.GetView();\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/CatalogPackageMetadata.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"CatalogPackageMetadata.g.h\"\n#include \"PackageAgreement.h\"\n#include \"Documentation.h\"\n#include \"Icon.h\"\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    struct CatalogPackageMetadata : CatalogPackageMetadataT<CatalogPackageMetadata>\n    {\n        CatalogPackageMetadata() = default;\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void Initialize(::AppInstaller::Manifest::ManifestLocalization manifestLocalization);\n#endif\n        hstring Locale();\n\n        hstring Publisher();\n\n        hstring PublisherUrl();\n\n        hstring PublisherSupportUrl();\n\n        hstring PrivacyUrl();\n\n        hstring Author();\n\n        hstring PackageName();\n\n        hstring PackageUrl();\n\n        hstring License();\n\n        hstring LicenseUrl();\n\n        hstring Copyright();\n\n        hstring CopyrightUrl();\n\n        hstring ShortDescription();\n\n        hstring Description();\n\n        winrt::Windows::Foundation::Collections::IVectorView<hstring> Tags();\n\n        winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Management::Deployment::PackageAgreement> Agreements();\n\n        winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Management::Deployment::Documentation> Documentations();\n\n        winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Management::Deployment::Icon> Icons();\n\n        hstring ReleaseNotes();\n\n        hstring ReleaseNotesUrl();\n\n        hstring PurchaseUrl();\n\n        hstring InstallationNotes();\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        ::AppInstaller::Manifest::ManifestLocalization m_manifestLocalization;\n        Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::PackageAgreement> m_packageAgreements{ nullptr };\n        Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::Documentation> m_documentations{ nullptr };\n        Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::Icon> m_icons{ nullptr };\n        Windows::Foundation::Collections::IVector<hstring> m_tags{ nullptr };\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/CheckInstalledStatusResult.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"CheckInstalledStatusResult.h\"\n#include \"CheckInstalledStatusResult.g.cpp\"\n#include <wil\\cppwinrt_wrl.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    void CheckInstalledStatusResult::Initialize(\n        winrt::Microsoft::Management::Deployment::CheckInstalledStatusResultStatus status,\n        Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::PackageInstallerInstalledStatus> installedStatus)\n    {\n        m_status = status;\n        m_installedStatus = installedStatus;\n    }\n    winrt::Microsoft::Management::Deployment::CheckInstalledStatusResultStatus CheckInstalledStatusResult::Status()\r\n    {\r\n        return m_status;\r\n    }\n    winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Management::Deployment::PackageInstallerInstalledStatus> CheckInstalledStatusResult::PackageInstalledStatus()\r\n    {\r\n        return m_installedStatus.GetView();\r\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/CheckInstalledStatusResult.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"CheckInstalledStatusResult.g.h\"\n#include <winrt/Windows.Foundation.Collections.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    struct CheckInstalledStatusResult : CheckInstalledStatusResultT<CheckInstalledStatusResult>\n    {\n        CheckInstalledStatusResult() = default;\n        \n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void Initialize(\n            winrt::Microsoft::Management::Deployment::CheckInstalledStatusResultStatus status,\n            Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::PackageInstallerInstalledStatus> installedStatus);\n#endif\n\n        winrt::Microsoft::Management::Deployment::CheckInstalledStatusResultStatus Status();\n        winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Management::Deployment::PackageInstallerInstalledStatus> PackageInstalledStatus();\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        winrt::Microsoft::Management::Deployment::CheckInstalledStatusResultStatus m_status = winrt::Microsoft::Management::Deployment::CheckInstalledStatusResultStatus::Ok;\n        Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::PackageInstallerInstalledStatus> m_installedStatus{\n            winrt::single_threaded_vector<winrt::Microsoft::Management::Deployment::PackageInstallerInstalledStatus>() };\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/ComClsids.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"Public/ComClsids.h\"\n#pragma warning( push )\n#pragma warning ( disable : 4467 )\n// 4467 Allow use of uuid attribute for com object creation.\n#include \"PackageManager.h\"\n#include \"FindPackagesOptions.h\"\n#include \"CreateCompositePackageCatalogOptions.h\"\n#include \"InstallOptions.h\"\n#include \"UninstallOptions.h\"\n#include \"PackageMatchFilter.h\"\n#include \"PackageManagerSettings.h\"\n#include \"DownloadOptions.h\"\n#include \"AuthenticationArguments.h\"\r\n#include \"RepairOptions.h\"\r\n#include \"AddPackageCatalogOptions.h\"\r\n#include \"RemovePackageCatalogOptions.h\"\n#include \"EditPackageCatalogOptions.h\"\n#pragma warning( pop )\n\nnamespace winrt::Microsoft::Management::Deployment\n{\n    CLSID GetRedirectedClsidFromInProcClsid(REFCLSID clsid)\n    {\n        if (IsEqualCLSID(clsid, WINGET_INPROC_COM_CLSID_PackageManager))\n        {\n            return __uuidof(winrt::Microsoft::Management::Deployment::implementation::PackageManager);\n        }\n        else if (IsEqualCLSID(clsid, WINGET_INPROC_COM_CLSID_FindPackagesOptions))\n        {\n            return __uuidof(winrt::Microsoft::Management::Deployment::implementation::FindPackagesOptions);\n        }\n        else if (IsEqualCLSID(clsid, WINGET_INPROC_COM_CLSID_CreateCompositePackageCatalogOptions))\n        {\n            return __uuidof(winrt::Microsoft::Management::Deployment::implementation::CreateCompositePackageCatalogOptions);\n        }\n        else if (IsEqualCLSID(clsid, WINGET_INPROC_COM_CLSID_InstallOptions))\n        {\n            return __uuidof(winrt::Microsoft::Management::Deployment::implementation::InstallOptions);\n        }\n        else if (IsEqualCLSID(clsid, WINGET_INPROC_COM_CLSID_UninstallOptions))\n        {\n            return __uuidof(winrt::Microsoft::Management::Deployment::implementation::UninstallOptions);\n        }\n        else if (IsEqualCLSID(clsid, WINGET_INPROC_COM_CLSID_DownloadOptions))\n        {\n            return __uuidof(winrt::Microsoft::Management::Deployment::implementation::DownloadOptions);\n        }\n        else if (IsEqualCLSID(clsid, WINGET_INPROC_COM_CLSID_PackageMatchFilter))\n        {\n            return __uuidof(winrt::Microsoft::Management::Deployment::implementation::PackageMatchFilter);\n        }\n        else if (IsEqualCLSID(clsid, WINGET_INPROC_COM_CLSID_AuthenticationArguments))\n        {\n            return __uuidof(winrt::Microsoft::Management::Deployment::implementation::AuthenticationArguments);\n        }\n        else if (IsEqualCLSID(clsid, WINGET_INPROC_COM_CLSID_PackageManagerSettings))\n        {\n            return __uuidof(winrt::Microsoft::Management::Deployment::implementation::PackageManagerSettings);\n        }\r\n        else if (IsEqualCLSID(clsid, WINGET_INPROC_COM_CLSID_RepairOptions))\r\n        {\r\n           return __uuidof(winrt::Microsoft::Management::Deployment::implementation::RepairOptions);\r\n        }\r\n        else if (IsEqualCLSID(clsid, WINGET_INPROC_COM_CLSID_AddPackageCatalogOptions))\r\n        {\r\n            return __uuidof(winrt::Microsoft::Management::Deployment::implementation::AddPackageCatalogOptions);\r\n        }\r\n        else if (IsEqualCLSID(clsid, WINGET_INPROC_COM_CLSID_RemovePackageCatalogOptions))\r\n        {\r\n            return __uuidof(winrt::Microsoft::Management::Deployment::implementation::RemovePackageCatalogOptions);\r\n        }\r\n        else if (IsEqualCLSID(clsid, WINGET_INPROC_COM_CLSID_EditPackageCatalogOptions))\r\n        {\r\n            return __uuidof(winrt::Microsoft::Management::Deployment::implementation::EditPackageCatalogOptions);\r\n        }\n        else\n        {\n            return CLSID_NULL;\n        }\n    }\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/ConnectResult.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"ConnectResult.h\"\n#include \"ConnectResult.g.cpp\"\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    void ConnectResult::Initialize(winrt::Microsoft::Management::Deployment::ConnectResultStatus status, winrt::Microsoft::Management::Deployment::PackageCatalog packageCatalog, winrt::hresult extendedErrorCode)\n    {\n        m_status = status;\n        m_packageCatalog = packageCatalog;\r\n        m_extendedErrorCode = extendedErrorCode;\n    }\n    winrt::Microsoft::Management::Deployment::ConnectResultStatus ConnectResult::Status()\n    {\n        return m_status;\n    }\n    winrt::Microsoft::Management::Deployment::PackageCatalog ConnectResult::PackageCatalog()\n    {\n        return m_packageCatalog;\n    }\r\n\r\n    winrt::hresult ConnectResult::ExtendedErrorCode()\r\n    {\n        return m_extendedErrorCode;\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/ConnectResult.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"ConnectResult.g.h\"\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    struct ConnectResult : ConnectResultT<ConnectResult>\n    {\n        ConnectResult() = default;\n        \n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void Initialize(winrt::Microsoft::Management::Deployment::ConnectResultStatus status, winrt::Microsoft::Management::Deployment::PackageCatalog packageCatalog, winrt::hresult extendedErrorCode);\n#endif\n\n        winrt::Microsoft::Management::Deployment::ConnectResultStatus Status();\n        winrt::Microsoft::Management::Deployment::PackageCatalog PackageCatalog();\n        winrt::hresult ExtendedErrorCode();\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        winrt::Microsoft::Management::Deployment::ConnectResultStatus m_status = winrt::Microsoft::Management::Deployment::ConnectResultStatus::Ok;\n        winrt::Microsoft::Management::Deployment::PackageCatalog m_packageCatalog{ nullptr };\n        winrt::hresult m_extendedErrorCode = S_OK;\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/Converters.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include <AppInstallerErrors.h>\r\n#include <winget/RepositorySource.h>\r\n#include \"Microsoft/PredefinedInstalledSourceFactory.h\"\r\n#include \"Workflows/WorkflowBase.h\"\r\n#include \"Converters.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    Microsoft::Management::Deployment::PackageMatchField GetDeploymentMatchField(::AppInstaller::Repository::PackageMatchField field)\r\n    {\r\n        Microsoft::Management::Deployment::PackageMatchField matchField = Microsoft::Management::Deployment::PackageMatchField::Id;\r\n        switch (field)\r\n        {\r\n        case ::AppInstaller::Repository::PackageMatchField::Command:\r\n            matchField = Microsoft::Management::Deployment::PackageMatchField::Command;\r\n            break;\r\n        case ::AppInstaller::Repository::PackageMatchField::Id:\r\n            matchField = Microsoft::Management::Deployment::PackageMatchField::Id;\r\n            break;\r\n        case ::AppInstaller::Repository::PackageMatchField::Moniker:\r\n            matchField = Microsoft::Management::Deployment::PackageMatchField::Moniker;\r\n            break;\r\n        case ::AppInstaller::Repository::PackageMatchField::Name:\r\n            matchField = Microsoft::Management::Deployment::PackageMatchField::Name;\r\n            break;\r\n        case ::AppInstaller::Repository::PackageMatchField::Tag:\r\n            matchField = Microsoft::Management::Deployment::PackageMatchField::Tag;\r\n            break;\r\n        case ::AppInstaller::Repository::PackageMatchField::ProductCode:\r\n            matchField = Microsoft::Management::Deployment::PackageMatchField::ProductCode;\r\n            break;\r\n        case ::AppInstaller::Repository::PackageMatchField::PackageFamilyName:\r\n            matchField = Microsoft::Management::Deployment::PackageMatchField::PackageFamilyName;\r\n            break;\r\n        default:\r\n            matchField = Microsoft::Management::Deployment::PackageMatchField::Id;\r\n            break;\r\n        }\r\n        return matchField;\r\n    }\r\n\r\n    ::AppInstaller::Repository::PackageMatchField GetRepositoryMatchField(Microsoft::Management::Deployment::PackageMatchField field)\r\n    {\r\n        ::AppInstaller::Repository::PackageMatchField matchField = ::AppInstaller::Repository::PackageMatchField::Id;\r\n        switch (field)\r\n        {\r\n        case Microsoft::Management::Deployment::PackageMatchField::Command:\r\n            matchField = ::AppInstaller::Repository::PackageMatchField::Command;\r\n            break;\r\n        case Microsoft::Management::Deployment::PackageMatchField::Id:\r\n            matchField = ::AppInstaller::Repository::PackageMatchField::Id;\r\n            break;\r\n        case Microsoft::Management::Deployment::PackageMatchField::Moniker:\r\n            matchField = ::AppInstaller::Repository::PackageMatchField::Moniker;\r\n            break;\r\n        case Microsoft::Management::Deployment::PackageMatchField::Name:\r\n            matchField = ::AppInstaller::Repository::PackageMatchField::Name;\r\n            break;\r\n        case Microsoft::Management::Deployment::PackageMatchField::Tag:\r\n            matchField = ::AppInstaller::Repository::PackageMatchField::Tag;\r\n            break;\r\n        case Microsoft::Management::Deployment::PackageMatchField::ProductCode:\r\n            matchField = ::AppInstaller::Repository::PackageMatchField::ProductCode;\r\n            break;\r\n        case Microsoft::Management::Deployment::PackageMatchField::PackageFamilyName:\r\n            matchField = ::AppInstaller::Repository::PackageMatchField::PackageFamilyName;\r\n            break;\r\n        default:\r\n            matchField = ::AppInstaller::Repository::PackageMatchField::Id;\r\n            break;\r\n        }\r\n        return matchField;\r\n    }\r\n\r\n    Microsoft::Management::Deployment::PackageFieldMatchOption GetDeploymentMatchOption(::AppInstaller::Repository::MatchType type)\r\n    {\r\n        Microsoft::Management::Deployment::PackageFieldMatchOption matchOption = Microsoft::Management::Deployment::PackageFieldMatchOption::Equals;\r\n        switch (type)\r\n        {\r\n        case ::AppInstaller::Repository::MatchType::CaseInsensitive:\r\n            matchOption = Microsoft::Management::Deployment::PackageFieldMatchOption::EqualsCaseInsensitive;\r\n            break;\r\n        case ::AppInstaller::Repository::MatchType::Exact:\r\n            matchOption = Microsoft::Management::Deployment::PackageFieldMatchOption::Equals;\r\n            break;\r\n        case ::AppInstaller::Repository::MatchType::StartsWith:\r\n            matchOption = Microsoft::Management::Deployment::PackageFieldMatchOption::StartsWithCaseInsensitive;\r\n            break;\r\n        case ::AppInstaller::Repository::MatchType::Substring:\r\n            matchOption = Microsoft::Management::Deployment::PackageFieldMatchOption::ContainsCaseInsensitive;\r\n            break;\r\n        default:\r\n            matchOption = Microsoft::Management::Deployment::PackageFieldMatchOption::Equals;\r\n            break;\r\n        }\r\n        return matchOption;\r\n    }\r\n\r\n    ::AppInstaller::Repository::MatchType GetRepositoryMatchType(Microsoft::Management::Deployment::PackageFieldMatchOption option)\r\n    {\r\n        ::AppInstaller::Repository::MatchType packageFieldMatchOption = ::AppInstaller::Repository::MatchType::Exact;\r\n        switch (option)\r\n        {\r\n        case Microsoft::Management::Deployment::PackageFieldMatchOption::EqualsCaseInsensitive:\r\n            packageFieldMatchOption = ::AppInstaller::Repository::MatchType::CaseInsensitive;\r\n            break;\r\n        case Microsoft::Management::Deployment::PackageFieldMatchOption::Equals:\r\n            packageFieldMatchOption = ::AppInstaller::Repository::MatchType::Exact;\r\n            break;\r\n        case Microsoft::Management::Deployment::PackageFieldMatchOption::StartsWithCaseInsensitive:\r\n            packageFieldMatchOption = ::AppInstaller::Repository::MatchType::StartsWith;\r\n            break;\r\n        case Microsoft::Management::Deployment::PackageFieldMatchOption::ContainsCaseInsensitive:\r\n            packageFieldMatchOption = ::AppInstaller::Repository::MatchType::Substring;\r\n            break;\r\n        default:\r\n            packageFieldMatchOption = ::AppInstaller::Repository::MatchType::Exact;\r\n            break;\r\n        }\r\n        return packageFieldMatchOption;\r\n    }\r\n\r\n    ::AppInstaller::Repository::CompositeSearchBehavior GetRepositoryCompositeSearchBehavior(Microsoft::Management::Deployment::CompositeSearchBehavior searchBehavior)\r\n    {\r\n        ::AppInstaller::Repository::CompositeSearchBehavior repositorySearchBehavior = ::AppInstaller::Repository::CompositeSearchBehavior::AllPackages;\r\n        switch (searchBehavior)\r\n        {\r\n        case Microsoft::Management::Deployment::CompositeSearchBehavior::LocalCatalogs:\r\n            repositorySearchBehavior = ::AppInstaller::Repository::CompositeSearchBehavior::Installed;\r\n            break;\r\n        case Microsoft::Management::Deployment::CompositeSearchBehavior::RemotePackagesFromRemoteCatalogs:\r\n            repositorySearchBehavior = ::AppInstaller::Repository::CompositeSearchBehavior::AvailablePackages;\r\n            break;\r\n        case Microsoft::Management::Deployment::CompositeSearchBehavior::RemotePackagesFromAllCatalogs:\r\n            repositorySearchBehavior = ::AppInstaller::Repository::CompositeSearchBehavior::AvailablePackages;\r\n            break;\r\n        case Microsoft::Management::Deployment::CompositeSearchBehavior::AllCatalogs:\r\n        default:\r\n            repositorySearchBehavior = ::AppInstaller::Repository::CompositeSearchBehavior::AllPackages;\r\n            break;\r\n        }\r\n        return repositorySearchBehavior;\r\n    }\r\n\r\n    ::AppInstaller::Repository::PackageVersionMetadata GetRepositoryPackageVersionMetadata(Microsoft::Management::Deployment::PackageVersionMetadataField packageVersionMetadataField)\r\n    {\r\n        ::AppInstaller::Repository::PackageVersionMetadata metadataKey = ::AppInstaller::Repository::PackageVersionMetadata::InstalledLocation;\r\n        switch (packageVersionMetadataField)\r\n        {\r\n        case Microsoft::Management::Deployment::PackageVersionMetadataField::InstalledLocation:\r\n            metadataKey = ::AppInstaller::Repository::PackageVersionMetadata::InstalledLocation;\r\n            break;\r\n        case Microsoft::Management::Deployment::PackageVersionMetadataField::InstalledScope:\r\n            metadataKey = ::AppInstaller::Repository::PackageVersionMetadata::InstalledScope;\r\n            break;\r\n        case Microsoft::Management::Deployment::PackageVersionMetadataField::InstallerType:\r\n            metadataKey = ::AppInstaller::Repository::PackageVersionMetadata::InstalledType;\r\n            break;\r\n        case Microsoft::Management::Deployment::PackageVersionMetadataField::PublisherDisplayName:\r\n            metadataKey = ::AppInstaller::Repository::PackageVersionMetadata::Publisher;\r\n            break;\r\n        case Microsoft::Management::Deployment::PackageVersionMetadataField::SilentUninstallCommand:\r\n            metadataKey = ::AppInstaller::Repository::PackageVersionMetadata::SilentUninstallCommand;\r\n            break;\r\n        case Microsoft::Management::Deployment::PackageVersionMetadataField::StandardUninstallCommand:\r\n            metadataKey = ::AppInstaller::Repository::PackageVersionMetadata::StandardUninstallCommand;\r\n            break;\r\n        }\r\n        return metadataKey;\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::FindPackagesResultStatus FindPackagesResultStatus(winrt::hresult hresult)\r\n    {\r\n        winrt::Microsoft::Management::Deployment::FindPackagesResultStatus resultStatus = winrt::Microsoft::Management::Deployment::FindPackagesResultStatus::Ok;\r\n        switch (hresult)\r\n        {\r\n        case(S_OK):\r\n            resultStatus = winrt::Microsoft::Management::Deployment::FindPackagesResultStatus::Ok;\r\n            break;\r\n        case APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY:\r\n            resultStatus = winrt::Microsoft::Management::Deployment::FindPackagesResultStatus::BlockedByPolicy;\r\n            break;\r\n        case APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE:\r\n        case APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA:\r\n        case APPINSTALLER_CLI_ERROR_RESTAPI_ENDPOINT_NOT_FOUND:\r\n        case APPINSTALLER_CLI_ERROR_RESTAPI_INTERNAL_ERROR:\r\n        case APPINSTALLER_CLI_ERROR_RESTAPI_UNSUPPORTED_MIME_TYPE:\r\n        case APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_VERSION:\r\n        case APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE:\r\n            resultStatus = winrt::Microsoft::Management::Deployment::FindPackagesResultStatus::CatalogError;\r\n            break;\r\n        case E_INVALIDARG:\r\n        case APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS:\r\n            resultStatus = winrt::Microsoft::Management::Deployment::FindPackagesResultStatus::InvalidOptions;\r\n            break;\r\n        case APPINSTALLER_CLI_ERROR_INVALID_AUTHENTICATION_INFO:\r\n        case APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED:\r\n        case APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED:\r\n        case APPINSTALLER_CLI_ERROR_AUTHENTICATION_INTERACTIVE_REQUIRED:\r\n        case APPINSTALLER_CLI_ERROR_AUTHENTICATION_CANCELLED_BY_USER:\r\n        case APPINSTALLER_CLI_ERROR_AUTHENTICATION_INCORRECT_ACCOUNT:\r\n            resultStatus = winrt::Microsoft::Management::Deployment::FindPackagesResultStatus::AuthenticationError;\r\n            break;\r\n        case HTTP_E_STATUS_DENIED:\r\n        case HTTP_E_STATUS_FORBIDDEN:\r\n            resultStatus = winrt::Microsoft::Management::Deployment::FindPackagesResultStatus::AccessDenied;\r\n            break;\r\n        case APPINSTALLER_CLI_ERROR_COMMAND_FAILED:\r\n        case APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX:\r\n        case APPINSTALLER_CLI_ERROR_INDEX_INTEGRITY_COMPROMISED:\r\n        default:\r\n            resultStatus = winrt::Microsoft::Management::Deployment::FindPackagesResultStatus::InternalError;\r\n            break;\r\n        }\r\n        return resultStatus;\r\n    }\r\n\r\n    std::optional<::AppInstaller::Utility::Architecture> GetUtilityArchitecture(winrt::Windows::System::ProcessorArchitecture architecture)\r\n    {\r\n        return ::AppInstaller::Utility::ConvertToArchitectureEnum(architecture);\r\n    }\r\n\r\n    std::optional<winrt::Windows::System::ProcessorArchitecture> GetWindowsSystemProcessorArchitecture(::AppInstaller::Utility::Architecture architecture)\r\n    {\r\n        switch (architecture)\r\n        {\r\n        case ::AppInstaller::Utility::Architecture::X86:\r\n            return winrt::Windows::System::ProcessorArchitecture::X86;\r\n        case ::AppInstaller::Utility::Architecture::Arm:\r\n            return winrt::Windows::System::ProcessorArchitecture::Arm;\r\n        case ::AppInstaller::Utility::Architecture::X64:\r\n            return winrt::Windows::System::ProcessorArchitecture::X64;\r\n        case ::AppInstaller::Utility::Architecture::Neutral:\r\n            return winrt::Windows::System::ProcessorArchitecture::Neutral;\r\n        case ::AppInstaller::Utility::Architecture::Arm64:\r\n            return winrt::Windows::System::ProcessorArchitecture::Arm64;\r\n        }\r\n\r\n        return {};\r\n    }\r\n\r\n    std::pair<::AppInstaller::Manifest::ScopeEnum, bool> GetManifestScope(winrt::Microsoft::Management::Deployment::PackageInstallScope scope)\r\n    {\r\n        switch (scope)\r\n        {\r\n        case winrt::Microsoft::Management::Deployment::PackageInstallScope::Any:\r\n            return std::make_pair(::AppInstaller::Manifest::ScopeEnum::Unknown, false);\r\n        case winrt::Microsoft::Management::Deployment::PackageInstallScope::User:\r\n            return std::make_pair(::AppInstaller::Manifest::ScopeEnum::User, false);\r\n        case winrt::Microsoft::Management::Deployment::PackageInstallScope::System:\r\n            return std::make_pair(::AppInstaller::Manifest::ScopeEnum::Machine, false);\r\n        case winrt::Microsoft::Management::Deployment::PackageInstallScope::UserOrUnknown:\r\n            return std::make_pair(::AppInstaller::Manifest::ScopeEnum::User, true);\r\n        case winrt::Microsoft::Management::Deployment::PackageInstallScope::SystemOrUnknown:\r\n            return std::make_pair(::AppInstaller::Manifest::ScopeEnum::Machine, true);\r\n        }\r\n\r\n        return std::make_pair(::AppInstaller::Manifest::ScopeEnum::Unknown, false);\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::PackageInstallerType GetDeploymentInstallerType(::AppInstaller::Manifest::InstallerTypeEnum installerType)\r\n    {\r\n        switch (installerType)\r\n        {\r\n        case ::AppInstaller::Manifest::InstallerTypeEnum::Burn:\r\n            return Microsoft::Management::Deployment::PackageInstallerType::Burn;\r\n        case ::AppInstaller::Manifest::InstallerTypeEnum::Exe:\r\n            return Microsoft::Management::Deployment::PackageInstallerType::Exe;\r\n        case ::AppInstaller::Manifest::InstallerTypeEnum::Inno:\r\n            return Microsoft::Management::Deployment::PackageInstallerType::Inno;\r\n        case ::AppInstaller::Manifest::InstallerTypeEnum::Msi:\r\n            return Microsoft::Management::Deployment::PackageInstallerType::Msi;\r\n        case ::AppInstaller::Manifest::InstallerTypeEnum::Msix:\r\n            return Microsoft::Management::Deployment::PackageInstallerType::Msix;\r\n        case ::AppInstaller::Manifest::InstallerTypeEnum::MSStore:\r\n            return Microsoft::Management::Deployment::PackageInstallerType::MSStore;\r\n        case ::AppInstaller::Manifest::InstallerTypeEnum::Nullsoft:\r\n            return Microsoft::Management::Deployment::PackageInstallerType::Nullsoft;\r\n        case ::AppInstaller::Manifest::InstallerTypeEnum::Portable:\r\n            return Microsoft::Management::Deployment::PackageInstallerType::Portable;\r\n        case ::AppInstaller::Manifest::InstallerTypeEnum::Wix:\r\n            return Microsoft::Management::Deployment::PackageInstallerType::Wix;\r\n        case ::AppInstaller::Manifest::InstallerTypeEnum::Zip:\r\n            return Microsoft::Management::Deployment::PackageInstallerType::Zip;\r\n        case ::AppInstaller::Manifest::InstallerTypeEnum::Unknown:\r\n            return Microsoft::Management::Deployment::PackageInstallerType::Unknown;\r\n        }\r\n\r\n        return Microsoft::Management::Deployment::PackageInstallerType::Unknown;\r\n    }\r\n\r\n    ::AppInstaller::Manifest::InstallerTypeEnum GetManifestInstallerType(winrt::Microsoft::Management::Deployment::PackageInstallerType installerType)\r\n    {\r\n        switch (installerType)\r\n        {\r\n        case Microsoft::Management::Deployment::PackageInstallerType::Burn:\r\n            return ::AppInstaller::Manifest::InstallerTypeEnum::Burn;\r\n        case Microsoft::Management::Deployment::PackageInstallerType::Exe:\r\n            return ::AppInstaller::Manifest::InstallerTypeEnum::Exe;\r\n        case Microsoft::Management::Deployment::PackageInstallerType::Inno:\r\n            return ::AppInstaller::Manifest::InstallerTypeEnum::Inno;\r\n        case Microsoft::Management::Deployment::PackageInstallerType::Msi:\r\n            return ::AppInstaller::Manifest::InstallerTypeEnum::Msi;\r\n        case Microsoft::Management::Deployment::PackageInstallerType::Msix:\r\n            return ::AppInstaller::Manifest::InstallerTypeEnum::Msix;\r\n        case Microsoft::Management::Deployment::PackageInstallerType::MSStore:\r\n            return ::AppInstaller::Manifest::InstallerTypeEnum::MSStore;\r\n        case Microsoft::Management::Deployment::PackageInstallerType::Nullsoft:\r\n            return ::AppInstaller::Manifest::InstallerTypeEnum::Nullsoft;\r\n        case Microsoft::Management::Deployment::PackageInstallerType::Portable:\r\n            return ::AppInstaller::Manifest::InstallerTypeEnum::Portable;\r\n        case Microsoft::Management::Deployment::PackageInstallerType::Wix:\r\n            return ::AppInstaller::Manifest::InstallerTypeEnum::Wix;\r\n        case Microsoft::Management::Deployment::PackageInstallerType::Zip:\r\n            return ::AppInstaller::Manifest::InstallerTypeEnum::Zip;\r\n        case Microsoft::Management::Deployment::PackageInstallerType::Unknown:\r\n            return ::AppInstaller::Manifest::InstallerTypeEnum::Unknown;\r\n        }\r\n\r\n        return ::AppInstaller::Manifest::InstallerTypeEnum::Unknown;\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::PackageInstallerScope GetDeploymentInstallerScope(::AppInstaller::Manifest::ScopeEnum installerScope)\r\n    {\r\n        switch (installerScope)\r\n        {\r\n        case ::AppInstaller::Manifest::ScopeEnum::User:\r\n            return Microsoft::Management::Deployment::PackageInstallerScope::User;\r\n        case ::AppInstaller::Manifest::ScopeEnum::Machine:\r\n            return Microsoft::Management::Deployment::PackageInstallerScope::System;\r\n        case ::AppInstaller::Manifest::ScopeEnum::Unknown:\r\n            return Microsoft::Management::Deployment::PackageInstallerScope::Unknown;\r\n        }\r\n\r\n        return Microsoft::Management::Deployment::PackageInstallerScope::Unknown;\r\n    }\r\n\r\n    ::AppInstaller::Manifest::ScopeEnum GetManifestUninstallScope(winrt::Microsoft::Management::Deployment::PackageUninstallScope scope)\r\n    {\r\n        switch (scope)\r\n        {\r\n        case winrt::Microsoft::Management::Deployment::PackageUninstallScope::Any:\r\n            return ::AppInstaller::Manifest::ScopeEnum::Unknown;\r\n        case winrt::Microsoft::Management::Deployment::PackageUninstallScope::User:\r\n            return ::AppInstaller::Manifest::ScopeEnum::User;\r\n        case winrt::Microsoft::Management::Deployment::PackageUninstallScope::System:\r\n            return ::AppInstaller::Manifest::ScopeEnum::Machine;\r\n        }\r\n\r\n        return ::AppInstaller::Manifest::ScopeEnum::Unknown;\r\n    }\r\n\r\n    ::AppInstaller::Manifest::ScopeEnum GetManifestRepairScope(winrt::Microsoft::Management::Deployment::PackageRepairScope scope)\r\n    {\r\n        switch (scope)\r\n        {\r\n        case winrt::Microsoft::Management::Deployment::PackageRepairScope::Any:\r\n            return ::AppInstaller::Manifest::ScopeEnum::Unknown;\r\n        case winrt::Microsoft::Management::Deployment::PackageRepairScope::User:\r\n            return ::AppInstaller::Manifest::ScopeEnum::User;\r\n        case winrt::Microsoft::Management::Deployment::PackageRepairScope::System:\r\n            return ::AppInstaller::Manifest::ScopeEnum::Machine;\r\n        }\r\n\r\n        return ::AppInstaller::Manifest::ScopeEnum::Unknown;\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::ElevationRequirement GetDeploymentElevationRequirement(::AppInstaller::Manifest::ElevationRequirementEnum elevationRequirement)\r\n    {\r\n        switch (elevationRequirement)\r\n        {\r\n        case ::AppInstaller::Manifest::ElevationRequirementEnum::ElevationRequired:\r\n            return Microsoft::Management::Deployment::ElevationRequirement::ElevationRequired;\r\n        case ::AppInstaller::Manifest::ElevationRequirementEnum::ElevationProhibited:\r\n            return Microsoft::Management::Deployment::ElevationRequirement::ElevationProhibited;\r\n        case ::AppInstaller::Manifest::ElevationRequirementEnum::ElevatesSelf:\r\n            return Microsoft::Management::Deployment::ElevationRequirement::ElevatesSelf;\r\n        case ::AppInstaller::Manifest::ElevationRequirementEnum::Unknown:\r\n            return Microsoft::Management::Deployment::ElevationRequirement::Unknown;\r\n        }\r\n\r\n        return Microsoft::Management::Deployment::ElevationRequirement::Unknown;\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::IconFileType GetDeploymentIconFileType(::AppInstaller::Manifest::IconFileTypeEnum iconFileType)\r\n    {\r\n        switch (iconFileType)\r\n        {\r\n        case ::AppInstaller::Manifest::IconFileTypeEnum::Ico:\r\n            return Microsoft::Management::Deployment::IconFileType::Ico;\r\n        case ::AppInstaller::Manifest::IconFileTypeEnum::Jpeg:\r\n            return Microsoft::Management::Deployment::IconFileType::Jpeg;\r\n        case ::AppInstaller::Manifest::IconFileTypeEnum::Png:\r\n            return Microsoft::Management::Deployment::IconFileType::Png;\r\n        }\r\n\r\n        return Microsoft::Management::Deployment::IconFileType::Unknown;\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::IconResolution GetDeploymentIconResolution(::AppInstaller::Manifest::IconResolutionEnum iconResolution)\r\n    {\r\n        switch (iconResolution)\r\n        {\r\n        case ::AppInstaller::Manifest::IconResolutionEnum::Custom:\r\n            return Microsoft::Management::Deployment::IconResolution::Custom;\r\n        case ::AppInstaller::Manifest::IconResolutionEnum::Square16:\r\n            return Microsoft::Management::Deployment::IconResolution::Square16;\r\n        case ::AppInstaller::Manifest::IconResolutionEnum::Square20:\r\n            return Microsoft::Management::Deployment::IconResolution::Square20;\r\n        case ::AppInstaller::Manifest::IconResolutionEnum::Square24:\r\n            return Microsoft::Management::Deployment::IconResolution::Square24;\r\n        case ::AppInstaller::Manifest::IconResolutionEnum::Square30:\r\n            return Microsoft::Management::Deployment::IconResolution::Square30;\r\n        case ::AppInstaller::Manifest::IconResolutionEnum::Square32:\r\n            return Microsoft::Management::Deployment::IconResolution::Square32;\r\n        case ::AppInstaller::Manifest::IconResolutionEnum::Square36:\r\n            return Microsoft::Management::Deployment::IconResolution::Square36;\r\n        case ::AppInstaller::Manifest::IconResolutionEnum::Square40:\r\n            return Microsoft::Management::Deployment::IconResolution::Square40;\r\n        case ::AppInstaller::Manifest::IconResolutionEnum::Square48:\r\n            return Microsoft::Management::Deployment::IconResolution::Square48;\r\n        case ::AppInstaller::Manifest::IconResolutionEnum::Square60:\r\n            return Microsoft::Management::Deployment::IconResolution::Square60;\r\n        case ::AppInstaller::Manifest::IconResolutionEnum::Square64:\r\n            return Microsoft::Management::Deployment::IconResolution::Square64;\r\n        case ::AppInstaller::Manifest::IconResolutionEnum::Square72:\r\n            return Microsoft::Management::Deployment::IconResolution::Square72;\r\n        case ::AppInstaller::Manifest::IconResolutionEnum::Square80:\r\n            return Microsoft::Management::Deployment::IconResolution::Square80;\r\n        case ::AppInstaller::Manifest::IconResolutionEnum::Square96:\r\n            return Microsoft::Management::Deployment::IconResolution::Square96;\r\n        case ::AppInstaller::Manifest::IconResolutionEnum::Square256:\r\n            return Microsoft::Management::Deployment::IconResolution::Square256;\r\n        }\r\n\r\n        return Microsoft::Management::Deployment::IconResolution::Custom;\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::IconTheme GetDeploymentIconTheme(::AppInstaller::Manifest::IconThemeEnum iconTheme)\r\n    {\r\n        switch (iconTheme)\r\n        {\r\n        case ::AppInstaller::Manifest::IconThemeEnum::Default:\r\n            return Microsoft::Management::Deployment::IconTheme::Default;\r\n        case ::AppInstaller::Manifest::IconThemeEnum::Light:\r\n            return Microsoft::Management::Deployment::IconTheme::Light;\r\n        case ::AppInstaller::Manifest::IconThemeEnum::Dark:\r\n            return Microsoft::Management::Deployment::IconTheme::Dark;\r\n        case ::AppInstaller::Manifest::IconThemeEnum::HighContrast:\r\n            return Microsoft::Management::Deployment::IconTheme::HighContrast;\r\n        }\r\n\r\n        return Microsoft::Management::Deployment::IconTheme::Unknown;\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::AuthenticationType GetDeploymentAuthenticationType(::AppInstaller::Authentication::AuthenticationType authType)\r\n    {\r\n        switch (authType)\r\n        {\r\n        case ::AppInstaller::Authentication::AuthenticationType::None:\r\n            return Microsoft::Management::Deployment::AuthenticationType::None;\r\n        case ::AppInstaller::Authentication::AuthenticationType::MicrosoftEntraId:\r\n            return Microsoft::Management::Deployment::AuthenticationType::MicrosoftEntraId;\r\n        case ::AppInstaller::Authentication::AuthenticationType::MicrosoftEntraIdForAzureBlobStorage:\r\n            return Microsoft::Management::Deployment::AuthenticationType::MicrosoftEntraIdForAzureBlobStorage;\r\n        }\r\n\r\n        return Microsoft::Management::Deployment::AuthenticationType::Unknown;\r\n    }\r\n\r\n    ::AppInstaller::Authentication::AuthenticationMode GetAuthenticationMode(winrt::Microsoft::Management::Deployment::AuthenticationMode authMode)\r\n    {\r\n        switch (authMode)\r\n        {\r\n        case winrt::Microsoft::Management::Deployment::AuthenticationMode::Interactive:\r\n            return ::AppInstaller::Authentication::AuthenticationMode::Interactive;\r\n        case winrt::Microsoft::Management::Deployment::AuthenticationMode::SilentPreferred:\r\n            return ::AppInstaller::Authentication::AuthenticationMode::SilentPreferred;\r\n        case winrt::Microsoft::Management::Deployment::AuthenticationMode::Silent:\r\n            return ::AppInstaller::Authentication::AuthenticationMode::Silent;\r\n        }\r\n\r\n        return ::AppInstaller::Authentication::AuthenticationMode::Unknown;\r\n    }\r\n\r\n    ::AppInstaller::Authentication::AuthenticationArguments GetAuthenticationArguments(winrt::Microsoft::Management::Deployment::AuthenticationArguments authArgs)\r\n    {\r\n        ::AppInstaller::Authentication::AuthenticationArguments result;\r\n        result.Mode = ::AppInstaller::Authentication::AuthenticationMode::Silent; // Default to silent for com invocations.\r\n\r\n        if (authArgs)\r\n        {\r\n            result.Mode = GetAuthenticationMode(authArgs.AuthenticationMode());\r\n            result.AuthenticationAccount = ::AppInstaller::Utility::ConvertToUTF8(authArgs.AuthenticationAccount());\r\n        }\r\n\r\n        return result;\r\n    }\r\n\r\n    AddPackageCatalogStatus GetAddPackageCatalogOperationStatus(winrt::hresult hresult)\r\n    {\r\n        switch (hresult)\r\n        {\r\n        case APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED:\r\n            return AddPackageCatalogStatus::AuthenticationError;\r\n        case APPINSTALLER_CLI_ERROR_SOURCE_NOT_SECURE:\r\n        case APPINSTALLER_CLI_ERROR_INVALID_SOURCE_TYPE:\r\n        case APPINSTALLER_CLI_ERROR_SOURCE_NOT_REMOTE:\r\n        case APPINSTALLER_CLI_ERROR_SOURCE_NAME_ALREADY_EXISTS:\r\n        case APPINSTALLER_CLI_ERROR_SOURCE_ARG_ALREADY_EXISTS:\r\n            return AddPackageCatalogStatus::InvalidOptions;\r\n        default:\r\n            return HandleCommonCatalogOperationStatus<AddPackageCatalogStatus>(hresult);\r\n        }\r\n    }\r\n\r\n    RemovePackageCatalogStatus GetRemovePackageCatalogOperationStatus(winrt::hresult hresult)\r\n    {\r\n        switch (hresult)\r\n        {\r\n        case APPINSTALLER_CLI_ERROR_SOURCE_NAME_DOES_NOT_EXIST:\r\n            return RemovePackageCatalogStatus::InvalidOptions;\r\n        case APPINSTALLER_CLI_ERROR_INVALID_SOURCE_TYPE:\r\n            return RemovePackageCatalogStatus::CatalogError;\r\n        default:\r\n            return HandleCommonCatalogOperationStatus<RemovePackageCatalogStatus>(hresult);\r\n        }\r\n    }\r\n\r\n    EditPackageCatalogStatus GetEditPackageCatalogOperationStatus(winrt::hresult hresult)\r\n    {\r\n        switch (hresult)\r\n        {\r\n        case APPINSTALLER_CLI_ERROR_SOURCE_NAME_DOES_NOT_EXIST:\r\n            return EditPackageCatalogStatus::InvalidOptions;\r\n        case APPINSTALLER_CLI_ERROR_INVALID_SOURCE_TYPE:\r\n            return EditPackageCatalogStatus::CatalogError;\r\n        default:\r\n            return HandleCommonCatalogOperationStatus<EditPackageCatalogStatus>(hresult);\r\n        }\r\n    }\r\n\r\n    ::AppInstaller::Manifest::PlatformEnum GetPlatformEnum(WindowsPlatform value)\r\n    {\r\n        switch (value)\r\n        {\r\n        case WindowsPlatform::Unknown: return AppInstaller::Manifest::PlatformEnum::Unknown;\r\n        case WindowsPlatform::Universal: return AppInstaller::Manifest::PlatformEnum::Universal;\r\n        case WindowsPlatform::Desktop: return AppInstaller::Manifest::PlatformEnum::Desktop;\r\n        case WindowsPlatform::IoT: return AppInstaller::Manifest::PlatformEnum::IoT;\r\n        case WindowsPlatform::Team: return AppInstaller::Manifest::PlatformEnum::Team;\r\n        case WindowsPlatform::Holographic: return AppInstaller::Manifest::PlatformEnum::Holographic;\r\n        default: return AppInstaller::Manifest::PlatformEnum::Unknown;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/Converters.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"PackageMatchFilter.g.h\"\r\n#include <AppInstallerArchitecture.h>\r\n#include <winget/RepositorySource.h>\r\n#include <Workflows/WorkflowBase.h>\r\n#include <winget/Authentication.h>\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    winrt::Microsoft::Management::Deployment::PackageMatchField GetDeploymentMatchField(::AppInstaller::Repository::PackageMatchField field);\r\n    ::AppInstaller::Repository::PackageMatchField GetRepositoryMatchField(winrt::Microsoft::Management::Deployment::PackageMatchField field);\r\n    winrt::Microsoft::Management::Deployment::PackageFieldMatchOption GetDeploymentMatchOption(::AppInstaller::Repository::MatchType type);\r\n    ::AppInstaller::Repository::MatchType GetRepositoryMatchType(winrt::Microsoft::Management::Deployment::PackageFieldMatchOption option);\r\n    ::AppInstaller::Repository::CompositeSearchBehavior GetRepositoryCompositeSearchBehavior(winrt::Microsoft::Management::Deployment::CompositeSearchBehavior searchBehavior);\r\n    ::AppInstaller::Repository::PackageVersionMetadata GetRepositoryPackageVersionMetadata(winrt::Microsoft::Management::Deployment::PackageVersionMetadataField packageVersionMetadataField);\r\n    winrt::Microsoft::Management::Deployment::FindPackagesResultStatus FindPackagesResultStatus(winrt::hresult hresult);\r\n    std::optional<::AppInstaller::Utility::Architecture> GetUtilityArchitecture(winrt::Windows::System::ProcessorArchitecture architecture);\r\n    std::optional<winrt::Windows::System::ProcessorArchitecture> GetWindowsSystemProcessorArchitecture(::AppInstaller::Utility::Architecture architecture);\r\n    std::pair<::AppInstaller::Manifest::ScopeEnum, bool> GetManifestScope(winrt::Microsoft::Management::Deployment::PackageInstallScope scope);\r\n    ::AppInstaller::Manifest::InstallerTypeEnum GetManifestInstallerType(winrt::Microsoft::Management::Deployment::PackageInstallerType installerType);\r\n    winrt::Microsoft::Management::Deployment::PackageInstallerType GetDeploymentInstallerType(::AppInstaller::Manifest::InstallerTypeEnum installerType);\r\n    winrt::Microsoft::Management::Deployment::PackageInstallerScope GetDeploymentInstallerScope(::AppInstaller::Manifest::ScopeEnum installerScope);\r\n    ::AppInstaller::Manifest::ScopeEnum GetManifestUninstallScope(winrt::Microsoft::Management::Deployment::PackageUninstallScope scope);\r\n    winrt::Microsoft::Management::Deployment::ElevationRequirement GetDeploymentElevationRequirement(::AppInstaller::Manifest::ElevationRequirementEnum elevationRequirement);\r\n    winrt::Microsoft::Management::Deployment::IconFileType GetDeploymentIconFileType(::AppInstaller::Manifest::IconFileTypeEnum iconFileType);\r\n    winrt::Microsoft::Management::Deployment::IconResolution GetDeploymentIconResolution(::AppInstaller::Manifest::IconResolutionEnum iconResolution);\r\n    winrt::Microsoft::Management::Deployment::IconTheme GetDeploymentIconTheme(::AppInstaller::Manifest::IconThemeEnum iconTheme);\r\n    winrt::Microsoft::Management::Deployment::AuthenticationType GetDeploymentAuthenticationType(::AppInstaller::Authentication::AuthenticationType authType);\r\n    ::AppInstaller::Authentication::AuthenticationMode GetAuthenticationMode(winrt::Microsoft::Management::Deployment::AuthenticationMode authMode);\r\n    ::AppInstaller::Authentication::AuthenticationArguments GetAuthenticationArguments(winrt::Microsoft::Management::Deployment::AuthenticationArguments authArgs);\r\n    ::AppInstaller::Manifest::ScopeEnum GetManifestRepairScope(winrt::Microsoft::Management::Deployment::PackageRepairScope scope);\r\n    winrt::Microsoft::Management::Deployment::AddPackageCatalogStatus GetAddPackageCatalogOperationStatus(winrt::hresult hresult);\r\n    winrt::Microsoft::Management::Deployment::RemovePackageCatalogStatus GetRemovePackageCatalogOperationStatus(winrt::hresult hresult);\r\n    winrt::Microsoft::Management::Deployment::EditPackageCatalogStatus GetEditPackageCatalogOperationStatus(winrt::hresult hresult);\r\n    ::AppInstaller::Manifest::PlatformEnum GetPlatformEnum(winrt::Microsoft::Management::Deployment::WindowsPlatform value);\r\n\r\n#define WINGET_GET_OPERATION_RESULT_STATUS(_installResultStatus_, _uninstallResultStatus_, _downloadResultStatus_, _repairResultStatus_) \\\r\n    if constexpr (std::is_same_v<TStatus, winrt::Microsoft::Management::Deployment::InstallResultStatus>) \\\r\n    { \\\r\n        resultStatus = TStatus::_installResultStatus_; \\\r\n    } \\\r\n    else if constexpr (std::is_same_v<TStatus, winrt::Microsoft::Management::Deployment::UninstallResultStatus>) \\\r\n    { \\\r\n        resultStatus = TStatus::_uninstallResultStatus_; \\\r\n    } \\\r\n    else if constexpr (std::is_same_v<TStatus, winrt::Microsoft::Management::Deployment::DownloadResultStatus>) \\\r\n    { \\\r\n        resultStatus = TStatus::_downloadResultStatus_; \\\r\n    } \\\r\n    else if constexpr (std::is_same_v<TStatus, winrt::Microsoft::Management::Deployment::RepairResultStatus>) \\\r\n    { \\\r\n        resultStatus = TStatus::_repairResultStatus_; \\\r\n    } \\\r\n\r\n    template <typename TStatus>\r\n    TStatus GetOperationResultStatus(::AppInstaller::CLI::Workflow::ExecutionStage executionStage, winrt::hresult hresult)\r\n    {\r\n        TStatus resultStatus = TStatus::Ok;\r\n\r\n        // Map some known hresults to specific statuses, otherwise use the execution stage to determine the status.\r\n        switch (hresult)\r\n        {\r\n        case S_OK:\r\n            resultStatus = TStatus::Ok;\r\n            break;\r\n        case APPINSTALLER_CLI_ERROR_MSSTORE_BLOCKED_BY_POLICY:\r\n        case APPINSTALLER_CLI_ERROR_MSSTORE_APP_BLOCKED_BY_POLICY:\r\n        case APPINSTALLER_CLI_ERROR_EXPERIMENTAL_FEATURE_DISABLED:\r\n        case APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY:\r\n            resultStatus = TStatus::BlockedByPolicy;\r\n            break;\r\n        case APPINSTALLER_CLI_ERROR_INVALID_MANIFEST:\r\n            resultStatus = TStatus::ManifestError;\r\n            break;\r\n        case E_INVALIDARG:\r\n        case APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS:\r\n            resultStatus = TStatus::InvalidOptions;\r\n            break;\r\n        case APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER:\r\n            WINGET_GET_OPERATION_RESULT_STATUS(NoApplicableInstallers, InternalError, NoApplicableInstallers, NoApplicableRepairer);\r\n            break;\r\n        case APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE:\r\n        case APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_UNKNOWN:\r\n        case APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_NOT_NEWER:\r\n            WINGET_GET_OPERATION_RESULT_STATUS(NoApplicableUpgrade, InternalError, InternalError, InternalError);\r\n            break;\r\n        case APPINSTALLER_CLI_ERROR_NO_UNINSTALL_INFO_FOUND:\r\n        case APPINSTALLER_CLI_ERROR_EXEC_UNINSTALL_COMMAND_FAILED:\r\n            WINGET_GET_OPERATION_RESULT_STATUS(InstallError, UninstallError, InternalError, InternalError);\r\n            break;\r\n        case APPINSTALLER_CLI_ERROR_NO_REPAIR_INFO_FOUND:\r\n        case APPINSTALLER_CLI_ERROR_REPAIR_NOT_APPLICABLE:\r\n        case APPINSTALLER_CLI_ERROR_EXEC_REPAIR_FAILED:\r\n        case APPINSTALLER_CLI_ERROR_REPAIR_NOT_SUPPORTED:\r\n        case APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED:\r\n            WINGET_GET_OPERATION_RESULT_STATUS(InternalError, InternalError, InternalError, RepairError);\r\n            break;\r\n        case APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED:\r\n            WINGET_GET_OPERATION_RESULT_STATUS(PackageAgreementsNotAccepted, InternalError, PackageAgreementsNotAccepted, PackageAgreementsNotAccepted);\r\n            break;\r\n        case APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX:\r\n        case APPINSTALLER_CLI_ERROR_INDEX_INTEGRITY_COMPROMISED:\r\n        case APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED:\r\n        case APPINSTALLER_CLI_ERROR_YAML_INVALID_MAPPING_KEY:\r\n        case APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY:\r\n        case APPINSTALLER_CLI_ERROR_YAML_INVALID_OPERATION:\r\n        case APPINSTALLER_CLI_ERROR_YAML_DOC_BUILD_FAILED:\r\n        case APPINSTALLER_CLI_ERROR_YAML_INVALID_EMITTER_STATE:\r\n        case APPINSTALLER_CLI_ERROR_YAML_INVALID_DATA:\r\n        case APPINSTALLER_CLI_ERROR_LIBYAML_ERROR:\r\n        case APPINSTALLER_CLI_ERROR_INTERNAL_ERROR:\r\n            resultStatus = TStatus::InternalError;\r\n            break;\r\n        default:\r\n            switch (executionStage)\r\n            {\r\n            case ::AppInstaller::CLI::Workflow::ExecutionStage::Initial:\r\n                resultStatus = TStatus::InternalError;\r\n                break;\r\n            case ::AppInstaller::CLI::Workflow::ExecutionStage::ParseArgs:\r\n                resultStatus = TStatus::InvalidOptions;\r\n                break;\r\n            case ::AppInstaller::CLI::Workflow::ExecutionStage::Discovery:\r\n                resultStatus = TStatus::CatalogError;\r\n                break;\r\n            case ::AppInstaller::CLI::Workflow::ExecutionStage::Download:\r\n                WINGET_GET_OPERATION_RESULT_STATUS(DownloadError, InternalError, DownloadError, DownloadError);\r\n                break;\r\n            case ::AppInstaller::CLI::Workflow::ExecutionStage::PreExecution:\r\n                resultStatus = TStatus::InternalError;\r\n                break;\r\n            case ::AppInstaller::CLI::Workflow::ExecutionStage::Execution:\r\n                WINGET_GET_OPERATION_RESULT_STATUS(InstallError, UninstallError, InternalError, RepairError);\r\n                break;\r\n            case ::AppInstaller::CLI::Workflow::ExecutionStage::PostExecution:\r\n                resultStatus = TStatus::InternalError;\r\n                break;\r\n            default:\r\n                resultStatus = TStatus::InternalError;\r\n                break;\r\n            }\r\n        }\r\n\r\n        return resultStatus;\r\n    }\r\n\r\n    template <typename TStatus>\r\n    TStatus HandleCommonCatalogOperationStatus(winrt::hresult hresult)\r\n    {\r\n        // Common status handling for AddPackageCatalogStatus and RemovePackageCatalogStatus.\r\n        if constexpr (std::is_same_v<TStatus, winrt::Microsoft::Management::Deployment::AddPackageCatalogStatus> || std::is_same_v<TStatus, winrt::Microsoft::Management::Deployment::RemovePackageCatalogStatus>)\r\n        {\r\n            switch (hresult)\r\n            {\r\n            case APPINSTALLER_CLI_ERROR_COMMAND_REQUIRES_ADMIN:\r\n            case E_ACCESSDENIED:\r\n                return TStatus::AccessDenied;\r\n            case APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS:\r\n            case E_INVALIDARG:\r\n                return TStatus::InvalidOptions;\r\n            default:\r\n                break;\r\n            }\r\n        }\r\n\r\n        // Common status handling for AddPackageCatalogStatus, RemovePackageCatalogStatus, and RefreshPackageCatalogStatus.\r\n        switch (hresult)\r\n        {\r\n        case S_OK:\r\n            return TStatus::Ok;\r\n        case APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY:\r\n            return TStatus::GroupPolicyError;\r\n        case APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE:\r\n            return TStatus::CatalogError;\r\n        case APPINSTALLER_CLI_ERROR_INTERNAL_ERROR:\r\n        default:\r\n            return TStatus::InternalError;\r\n        }\r\n    }\r\n\r\n    template <typename TStatus>\r\n    TStatus GetPackageCatalogOperationStatus(winrt::hresult hresult)\r\n    {\r\n        if constexpr (std::is_same_v<TStatus, winrt::Microsoft::Management::Deployment::AddPackageCatalogStatus>)\r\n        {\r\n            return GetAddPackageCatalogOperationStatus(hresult);\r\n        }\r\n        else if constexpr (std::is_same_v<TStatus, winrt::Microsoft::Management::Deployment::RemovePackageCatalogStatus>)\r\n        {\r\n            return GetRemovePackageCatalogOperationStatus(hresult);\r\n        }\r\n        else if constexpr (std::is_same_v<TStatus, winrt::Microsoft::Management::Deployment::RefreshPackageCatalogStatus>)\r\n        {\r\n            return HandleCommonCatalogOperationStatus<RefreshPackageCatalogStatus>(hresult);\r\n        }\r\n        else if constexpr (std::is_same_v<TStatus, winrt::Microsoft::Management::Deployment::EditPackageCatalogStatus>)\r\n        {\r\n            return GetEditPackageCatalogOperationStatus(hresult);\r\n        }\r\n        else\r\n        {\r\n            throw winrt::hresult_error(E_UNEXPECTED);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/CreateCompositePackageCatalogOptions.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#pragma warning( push )\r\n#pragma warning ( disable : 4467 6388)\r\n// 6388 Allow CreateInstance.\r\n#include <wil\\cppwinrt_wrl.h>\r\n// 4467 Allow use of uuid attribute for com object creation.\r\n#include \"CreateCompositePackageCatalogOptions.h\"\r\n#pragma warning( pop )\r\n#include \"CreateCompositePackageCatalogOptions.g.cpp\"\r\n#include \"Helpers.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::PackageCatalogReference> CreateCompositePackageCatalogOptions::Catalogs()\r\n    {\r\n        return m_catalogs;\r\n    }\r\n    winrt::Microsoft::Management::Deployment::CompositeSearchBehavior CreateCompositePackageCatalogOptions::CompositeSearchBehavior()\r\n    {\r\n        return m_compositeSearchBehavior;\r\n    }\r\n    void CreateCompositePackageCatalogOptions::CompositeSearchBehavior(winrt::Microsoft::Management::Deployment::CompositeSearchBehavior const& value)\r\n    {\r\n        m_compositeSearchBehavior = value;\r\n    }\r\n    winrt::Microsoft::Management::Deployment::PackageInstallScope CreateCompositePackageCatalogOptions::InstalledScope()\r\n    {\r\n        return m_installedScope;\r\n    }\r\n    void CreateCompositePackageCatalogOptions::InstalledScope(winrt::Microsoft::Management::Deployment::PackageInstallScope const& value)\r\n    {\r\n        m_installedScope = value;\r\n    }\r\n\r\n    CoCreatableMicrosoftManagementDeploymentClass(CreateCompositePackageCatalogOptions);\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/CreateCompositePackageCatalogOptions.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"CreateCompositePackageCatalogOptions.g.h\"\r\n#include \"Public/ComClsids.h\"\r\n#include <winget/ModuleCountBase.h>\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    [uuid(WINGET_OUTOFPROC_COM_CLSID_CreateCompositePackageCatalogOptions)]\r\n    struct CreateCompositePackageCatalogOptions : CreateCompositePackageCatalogOptionsT<CreateCompositePackageCatalogOptions>\r\n    {\r\n        CreateCompositePackageCatalogOptions() = default;\r\n\r\n        winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::PackageCatalogReference> Catalogs();\r\n        winrt::Microsoft::Management::Deployment::CompositeSearchBehavior CompositeSearchBehavior();\r\n        void CompositeSearchBehavior(winrt::Microsoft::Management::Deployment::CompositeSearchBehavior const& value);\r\n        winrt::Microsoft::Management::Deployment::PackageInstallScope InstalledScope();\r\n        void InstalledScope(winrt::Microsoft::Management::Deployment::PackageInstallScope const& value);\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::PackageCatalogReference> m_catalogs{ winrt::single_threaded_vector<Microsoft::Management::Deployment::PackageCatalogReference>() };\r\n        winrt::Microsoft::Management::Deployment::CompositeSearchBehavior m_compositeSearchBehavior = winrt::Microsoft::Management::Deployment::CompositeSearchBehavior::RemotePackagesFromAllCatalogs;\r\n        winrt::Microsoft::Management::Deployment::PackageInstallScope m_installedScope = winrt::Microsoft::Management::Deployment::PackageInstallScope::Any;\r\n#endif\r\n    };\r\n}\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\nnamespace winrt::Microsoft::Management::Deployment::factory_implementation\r\n{\r\n    struct CreateCompositePackageCatalogOptions :\r\n        CreateCompositePackageCatalogOptionsT<CreateCompositePackageCatalogOptions, implementation::CreateCompositePackageCatalogOptions>,\r\n        AppInstaller::WinRT::ModuleCountBase\r\n    {\r\n    };\r\n}\r\n#endif\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/Documentation.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"Documentation.g.cpp\"\n#include \"Documentation.h\"\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    void Documentation::Initialize(::AppInstaller::Manifest::Documentation documentation)\n    {\n        m_documentation = std::move(documentation);\n    }\n    hstring Documentation::DocumentLabel()\n    {\n        return winrt::to_hstring(m_documentation.DocumentLabel);\n    }\n    hstring Documentation::DocumentUrl()\n    {\n        return winrt::to_hstring(m_documentation.DocumentUrl);\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/Documentation.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"Documentation.g.h\"\n#include <winget/Manifest.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    struct Documentation : DocumentationT<Documentation>\n    {\n        Documentation() = default;\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void Initialize(::AppInstaller::Manifest::Documentation documentation);\n#endif\n\n        hstring DocumentLabel();\n        hstring DocumentUrl();\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        ::AppInstaller::Manifest::Documentation m_documentation{};\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/DownloadOptions.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#pragma warning( push )\n#pragma warning ( disable : 4467 6388)\n// 6388 Allow CreateInstance.\n#include <wil\\cppwinrt_wrl.h>\n// 4467 Allow use of uuid attribute for com object creation.\n#include \"DownloadOptions.h\"\n#pragma warning( pop )\n#include \"DownloadOptions.g.cpp\"\n#include \"Helpers.h\"\n\n#include <AppInstallerArchitecture.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    DownloadOptions::DownloadOptions()\n    {\n    }\n    winrt::Microsoft::Management::Deployment::PackageVersionId DownloadOptions::PackageVersionId()\n    {\n        return m_packageVersionId;\n    }\n    void DownloadOptions::PackageVersionId(winrt::Microsoft::Management::Deployment::PackageVersionId const& value)\n    {\n        m_packageVersionId = value;\n    }\n    winrt::Microsoft::Management::Deployment::PackageInstallScope DownloadOptions::Scope()\n    {\n        return m_scope;\n    }\n    void DownloadOptions::Scope(winrt::Microsoft::Management::Deployment::PackageInstallScope const& value)\n    {\n        m_scope = value;\n    }\n    winrt::Microsoft::Management::Deployment::PackageInstallerType DownloadOptions::InstallerType()\n    {\n        return m_installerType;\n    }\n    void DownloadOptions::InstallerType(winrt::Microsoft::Management::Deployment::PackageInstallerType const& value)\n    {\n        m_installerType = value;\n    }\n    winrt::Windows::System::ProcessorArchitecture DownloadOptions::Architecture()\n    {\n        return m_architecture;\n    }\n    void DownloadOptions::Architecture(winrt::Windows::System::ProcessorArchitecture const& value)\n    {\n        m_architecture = value;\n    }\n    hstring DownloadOptions::Locale()\n    {\n        return hstring(m_locale);\n    }\n    void DownloadOptions::Locale(hstring const& value)\n    {\n        m_locale = value;\n    }\n    hstring DownloadOptions::DownloadDirectory()\n    {\n        return hstring(m_downloadDirectory);\n    }\n    void DownloadOptions::DownloadDirectory(hstring const& value)\n    {\n        m_downloadDirectory = value;\n    }\n    bool DownloadOptions::AllowHashMismatch()\n    {\n        return m_allowHashMismatch;\n    }\n    void DownloadOptions::AllowHashMismatch(bool value)\n    {\n        m_allowHashMismatch = value;\n    }\n    bool DownloadOptions::SkipDependencies()\n    {\n        return m_skipDependencies;\n    }\n    void DownloadOptions::SkipDependencies(bool value)\n    {\n        m_skipDependencies = value;\n    }\n    bool DownloadOptions::AcceptPackageAgreements()\n    {\n        return m_acceptPackageAgreements;\n    }\n    void DownloadOptions::AcceptPackageAgreements(bool value)\n    {\n        m_acceptPackageAgreements = value;\n    }\n    hstring DownloadOptions::CorrelationData()\n    {\n        return hstring(m_correlationData);\n    }\n    void DownloadOptions::CorrelationData(hstring const& value)\n    {\n        m_correlationData = value;\n    }\r\n    winrt::Microsoft::Management::Deployment::AuthenticationArguments DownloadOptions::AuthenticationArguments()\r\n    {\r\n        return m_authenticationArguments;\r\n    }\r\n    void DownloadOptions::AuthenticationArguments(winrt::Microsoft::Management::Deployment::AuthenticationArguments const& value)\r\n    {\r\n        m_authenticationArguments = value;\r\n    }\r\n\n    bool DownloadOptions::SkipMicrosoftStoreLicense()\r\n    {\n        return m_skipMicrosoftStoreLicense;\n    }\r\n\n    void DownloadOptions::SkipMicrosoftStoreLicense(bool value)\r\n    {\r\n        m_skipMicrosoftStoreLicense = value;\r\n    }\r\n\n    winrt::Microsoft::Management::Deployment::WindowsPlatform DownloadOptions::Platform()\r\n    {\n        return m_platform;\n    }\r\n\n    void DownloadOptions::Platform(winrt::Microsoft::Management::Deployment::WindowsPlatform value)\r\n    {\r\n        m_platform = value;\r\n    }\r\n\n    hstring DownloadOptions::TargetOSVersion()\r\n    {\n        return hstring(m_targetOSVersion);\n    }\r\n\n    void DownloadOptions::TargetOSVersion(hstring const& value)\r\n    {\r\n        m_targetOSVersion = value;\r\n    }\r\n\n    CoCreatableMicrosoftManagementDeploymentClass(DownloadOptions);\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/DownloadOptions.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"DownloadOptions.g.h\"\r\n#include \"Public/ComClsids.h\"\r\n#include <winget/ModuleCountBase.h>\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    [uuid(WINGET_OUTOFPROC_COM_CLSID_DownloadOptions)]\r\n    struct DownloadOptions : DownloadOptionsT<DownloadOptions>\r\n    {\r\n        DownloadOptions();\r\n\r\n        winrt::Microsoft::Management::Deployment::PackageVersionId PackageVersionId();\r\n        void PackageVersionId(winrt::Microsoft::Management::Deployment::PackageVersionId const& value);\r\n        winrt::Microsoft::Management::Deployment::PackageInstallScope Scope();\r\n        void Scope(winrt::Microsoft::Management::Deployment::PackageInstallScope const& value);\r\n        winrt::Microsoft::Management::Deployment::PackageInstallerType InstallerType();\r\n        void InstallerType(winrt::Microsoft::Management::Deployment::PackageInstallerType const& value);\r\n        winrt::Windows::System::ProcessorArchitecture Architecture();\r\n        void Architecture(winrt::Windows::System::ProcessorArchitecture const& value);\r\n        hstring Locale();\r\n        void Locale(hstring const& value);\r\n        hstring DownloadDirectory();\r\n        void DownloadDirectory(hstring const& value);\r\n        bool AllowHashMismatch();\r\n        void AllowHashMismatch(bool value);\r\n        bool SkipDependencies();\r\n        void SkipDependencies(bool value);\r\n        bool AcceptPackageAgreements();\r\n        void AcceptPackageAgreements(bool value);\r\n        hstring CorrelationData();\r\n        void CorrelationData(hstring const& value);\r\n        winrt::Microsoft::Management::Deployment::AuthenticationArguments AuthenticationArguments();\r\n        void AuthenticationArguments(winrt::Microsoft::Management::Deployment::AuthenticationArguments const& value);\r\n        bool SkipMicrosoftStoreLicense();\r\n        void SkipMicrosoftStoreLicense(bool value);\r\n        winrt::Microsoft::Management::Deployment::WindowsPlatform Platform();\r\n        void Platform(winrt::Microsoft::Management::Deployment::WindowsPlatform value);\r\n        hstring TargetOSVersion();\r\n        void TargetOSVersion(hstring const& value);\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        winrt::Microsoft::Management::Deployment::PackageVersionId m_packageVersionId{ nullptr };\r\n        winrt::Microsoft::Management::Deployment::PackageInstallScope m_scope = winrt::Microsoft::Management::Deployment::PackageInstallScope::Any;\r\n        winrt::Microsoft::Management::Deployment::PackageInstallerType m_installerType = winrt::Microsoft::Management::Deployment::PackageInstallerType::Unknown;\r\n        winrt::Windows::System::ProcessorArchitecture m_architecture = winrt::Windows::System::ProcessorArchitecture::Unknown;\r\n        std::wstring m_locale = L\"\";\r\n        std::wstring m_downloadDirectory = L\"\";\r\n        bool m_allowHashMismatch = false;\r\n        bool m_skipDependencies = false;\r\n        bool m_acceptPackageAgreements = true;\r\n        std::wstring m_correlationData = L\"\";\r\n        winrt::Microsoft::Management::Deployment::AuthenticationArguments m_authenticationArguments{ nullptr };\r\n        bool m_skipMicrosoftStoreLicense = false;\r\n        winrt::Microsoft::Management::Deployment::WindowsPlatform m_platform = winrt::Microsoft::Management::Deployment::WindowsPlatform::Unknown;\r\n        std::wstring m_targetOSVersion;\r\n#endif\r\n    };\r\n}\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\nnamespace winrt::Microsoft::Management::Deployment::factory_implementation\r\n{\r\n    struct DownloadOptions : DownloadOptionsT<DownloadOptions, implementation::DownloadOptions>, AppInstaller::WinRT::ModuleCountBase\r\n    {\r\n    };\r\n}\r\n#endif\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/DownloadResult.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"DownloadResult.h\"\n#include \"DownloadResult.g.cpp\"\n#include <wil\\cppwinrt_wrl.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    void DownloadResult::Initialize(\n        winrt::Microsoft::Management::Deployment::DownloadResultStatus status,\n        winrt::hresult extendedErrorCode,\n        hstring const& correlationData)\n    {\n        m_status = status;\n        m_extendedErrorCode = extendedErrorCode;\n        m_correlationData = correlationData;\n    }\n    hstring DownloadResult::CorrelationData()\n    {\n        return hstring(m_correlationData);\n    }\n    winrt::Microsoft::Management::Deployment::DownloadResultStatus DownloadResult::Status()\n    {\n        return m_status;\n    }\n    winrt::hresult DownloadResult::ExtendedErrorCode()\n    {\n        return m_extendedErrorCode;\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/DownloadResult.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"DownloadResult.g.h\"\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    struct DownloadResult : DownloadResultT<DownloadResult>\n    {\n        DownloadResult() = default;\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void Initialize(\n            winrt::Microsoft::Management::Deployment::DownloadResultStatus status,\n            winrt::hresult extendedErrorCode,\n            hstring const& correlationData);\n#endif\n\n        hstring CorrelationData();\n        winrt::Microsoft::Management::Deployment::DownloadResultStatus Status();\n        winrt::hresult ExtendedErrorCode();\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        std::wstring m_correlationData = L\"\";\n        winrt::Microsoft::Management::Deployment::DownloadResultStatus m_status = winrt::Microsoft::Management::Deployment::DownloadResultStatus::Ok;\n        winrt::hresult m_extendedErrorCode = S_OK;\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/EditPackageCatalogOptions.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#pragma warning( push )\n#pragma warning ( disable : 4467 6388)\n// 6388 Allow CreateInstance.\n#include <wil\\cppwinrt_wrl.h>\n// 4467 Allow use of uuid attribute for com object creation.\n#include \"EditPackageCatalogOptions.h\"\n#pragma warning( pop )\n#include \"EditPackageCatalogOptions.g.cpp\"\n#include \"Converters.h\"\n#include \"Helpers.h\"\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    hstring EditPackageCatalogOptions::Name()\n    {\n        return hstring(m_name);\n    }\n\n    void EditPackageCatalogOptions::Name(hstring const& value)\n    {\n        m_name = value;\n    }\n\n    Windows::Foundation::IReference<bool> EditPackageCatalogOptions::Explicit()\n    {\n        return m_explicit;\n    }\n\n    void EditPackageCatalogOptions::Explicit(Windows::Foundation::IReference<bool> value)\n    {\n        m_explicit = value;\n    }\n\n    Windows::Foundation::IReference<int32_t> EditPackageCatalogOptions::Priority()\n    {\n        return m_priority;\n    }\n\n    void EditPackageCatalogOptions::Priority(Windows::Foundation::IReference<int32_t> value)\n    {\n        m_priority = value;\n    }\n\n    CoCreatableMicrosoftManagementDeploymentClass(EditPackageCatalogOptions);\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/EditPackageCatalogOptions.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"EditPackageCatalogOptions.g.h\"\n#include \"public/ComClsids.h\"\n#include <winget/ModuleCountBase.h>\n#include <winrt/Windows.Foundation.h>\n#include <optional>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    [uuid(WINGET_OUTOFPROC_COM_CLSID_EditPackageCatalogOptions)]\n    struct EditPackageCatalogOptions : EditPackageCatalogOptionsT<EditPackageCatalogOptions>\n    {\n        EditPackageCatalogOptions() = default;\n\n        hstring Name();\n        void Name(hstring const& value);\n\n        Windows::Foundation::IReference<bool> Explicit();\n        void Explicit(Windows::Foundation::IReference<bool> value);\n\n        Windows::Foundation::IReference<int32_t> Priority();\n        void Priority(Windows::Foundation::IReference<int32_t> value);\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        hstring m_name = L\"\";\n        std::optional<bool> m_explicit;\n        std::optional<int32_t> m_priority;\n#endif\n    };\n}\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\nnamespace winrt::Microsoft::Management::Deployment::factory_implementation\n{\n    struct EditPackageCatalogOptions :\n        EditPackageCatalogOptionsT<EditPackageCatalogOptions, implementation::EditPackageCatalogOptions>,\n        AppInstaller::WinRT::ModuleCountBase\n    {\n    };\n}\n#endif\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/EditPackageCatalogResult.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"EditPackageCatalogResult.h\"\n#include \"EditPackageCatalogResult.g.cpp\"\n#include <wil\\cppwinrt_wrl.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    void EditPackageCatalogResult::Initialize(\n        winrt::Microsoft::Management::Deployment::EditPackageCatalogStatus status,\n        winrt::hresult extendedErrorCode)\n    {\n        m_status = status;\n        m_extendedErrorCode = extendedErrorCode;\n    }\n    winrt::Microsoft::Management::Deployment::EditPackageCatalogStatus EditPackageCatalogResult::Status()\n    {\n        return m_status;\n    }\n    winrt::hresult EditPackageCatalogResult::ExtendedErrorCode()\n    {\n        return m_extendedErrorCode;\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/EditPackageCatalogResult.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"EditPackageCatalogResult.g.h\"\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    struct EditPackageCatalogResult : EditPackageCatalogResultT<EditPackageCatalogResult>\n    {\n        EditPackageCatalogResult() = default;\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void Initialize(\n            winrt::Microsoft::Management::Deployment::EditPackageCatalogStatus status,\n            winrt::hresult extendedErrorCode);\n#endif\n\n        winrt::Microsoft::Management::Deployment::EditPackageCatalogStatus Status();\n        winrt::hresult ExtendedErrorCode();\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        winrt::Microsoft::Management::Deployment::EditPackageCatalogStatus m_status = winrt::Microsoft::Management::Deployment::EditPackageCatalogStatus::Ok;\n        winrt::hresult m_extendedErrorCode = S_OK;\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/FindPackagesOptions.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#pragma warning( push )\r\n#pragma warning ( disable : 4467 6388)\r\n// 6388 Allow CreateInstance.\r\n#include <wil\\cppwinrt_wrl.h>\r\n// 4467 Allow use of uuid attribute for com object creation.\r\n#include \"FindPackagesOptions.h\"\r\n#pragma warning( pop )\r\n#include \"FindPackagesOptions.g.cpp\"\r\n#include \"Helpers.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::PackageMatchFilter> FindPackagesOptions::Selectors()\r\n    {\r\n        return m_selectors;\r\n    }\r\n    winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::PackageMatchFilter> FindPackagesOptions::Filters()\r\n    {\r\n        return m_filters;\r\n    }\r\n    uint32_t FindPackagesOptions::ResultLimit()\r\n    {\r\n        return m_resultLimit;\r\n    }\r\n    void FindPackagesOptions::ResultLimit(uint32_t value)\r\n    {\r\n        m_resultLimit = value;\r\n    }\r\n\r\n    CoCreatableMicrosoftManagementDeploymentClass(FindPackagesOptions);\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/FindPackagesOptions.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"FindPackagesOptions.g.h\"\r\n#include \"Public/ComClsids.h\"\r\n#include <winget/ModuleCountBase.h>\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    [uuid(WINGET_OUTOFPROC_COM_CLSID_FindPackagesOptions)]\r\n    struct FindPackagesOptions : FindPackagesOptionsT<FindPackagesOptions>\r\n    {\r\n        FindPackagesOptions() = default;\r\n\r\n        winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::PackageMatchFilter> Selectors();\r\n        winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::PackageMatchFilter> Filters();\r\n        uint32_t ResultLimit();\r\n        void ResultLimit(uint32_t value);\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        uint32_t m_resultLimit = 0;\r\n        Windows::Foundation::Collections::IVector<Microsoft::Management::Deployment::PackageMatchFilter> m_selectors{ \r\n            winrt::single_threaded_vector<winrt::Microsoft::Management::Deployment::PackageMatchFilter>() };\r\n        Windows::Foundation::Collections::IVector<Microsoft::Management::Deployment::PackageMatchFilter> m_filters{ \r\n            winrt::single_threaded_vector<winrt::Microsoft::Management::Deployment::PackageMatchFilter>() };\r\n#endif\r\n    };\r\n}\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\nnamespace winrt::Microsoft::Management::Deployment::factory_implementation\r\n{\r\n    struct FindPackagesOptions : FindPackagesOptionsT<FindPackagesOptions, implementation::FindPackagesOptions>, AppInstaller::WinRT::ModuleCountBase\r\n    {\r\n    };\r\n}\r\n#endif\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/FindPackagesResult.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"FindPackagesResult.h\"\n#include \"FindPackagesResult.g.cpp\"\n#include <wil\\cppwinrt_wrl.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    void FindPackagesResult::Initialize(\n        winrt::Microsoft::Management::Deployment::FindPackagesResultStatus status,\n        bool wasLimitExceeded, \n        Windows::Foundation::Collections::IVector<Microsoft::Management::Deployment::MatchResult> matches,\r\n        winrt::hresult extendedErrorCode)\n    {\n        m_status = status;\n        m_matches = matches;\n        m_wasLimitExceeded = wasLimitExceeded;\n        m_extendedErrorCode = extendedErrorCode;\n    }\n    winrt::Microsoft::Management::Deployment::FindPackagesResultStatus FindPackagesResult::Status()\n    {\n        return m_status;\n    }\n    winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Management::Deployment::MatchResult> FindPackagesResult::Matches()\n    {\n        return m_matches.GetView();\n    }\n    bool FindPackagesResult::WasLimitExceeded()\n    {\n        return m_wasLimitExceeded;\n    }\n\n    winrt::hresult FindPackagesResult::ExtendedErrorCode()\n    {\n        return m_extendedErrorCode;\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/FindPackagesResult.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"FindPackagesResult.g.h\"\n#include <winrt/Windows.Foundation.Collections.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    struct FindPackagesResult : FindPackagesResultT<FindPackagesResult>\n    {\n        FindPackagesResult() = default;\n        \n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void Initialize(\n            winrt::Microsoft::Management::Deployment::FindPackagesResultStatus status,\n            bool wasLimitExceeded, \n            Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::MatchResult> matches,\r\n            winrt::hresult extendedErrorCode);\n#endif\n\n        winrt::Microsoft::Management::Deployment::FindPackagesResultStatus Status();\n        winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Management::Deployment::MatchResult> Matches();\n        bool WasLimitExceeded();\n        winrt::hresult ExtendedErrorCode();\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        winrt::Microsoft::Management::Deployment::FindPackagesResultStatus m_status = winrt::Microsoft::Management::Deployment::FindPackagesResultStatus::Ok;\n        Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::MatchResult> m_matches{ \n            winrt::single_threaded_vector<winrt::Microsoft::Management::Deployment::MatchResult>() };\n        bool m_wasLimitExceeded = false;\n        winrt::hresult m_extendedErrorCode = S_OK;\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/Helpers.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include <wil/resource.h>\r\n#include <wil/win32_helpers.h>\r\n#include <winrt/Windows.Security.Authorization.AppCapabilityAccess.h>\r\n#include <appmodel.h>\r\n#include <Helpers.h>\r\n#include <winget/Filesystem.h>\r\n#include <winget/Security.h>\r\n#include <AppInstallerRuntime.h>\r\n#include <AppInstallerLogging.h>\r\n\r\nusing namespace std::string_literals;\r\nusing namespace std::string_view_literals;\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    namespace\r\n    {\r\n        static std::optional<std::string> s_callerName;\r\n        static wil::srwlock s_callerNameLock;\r\n    }\r\n\r\n    void SetComCallerName(std::string name)\r\n    {\r\n        auto lock = s_callerNameLock.lock_exclusive();\r\n        s_callerName.emplace(std::move(name));\r\n    }\r\n\r\n    std::string GetComCallerName(std::string defaultNameIfNotSet)\r\n    {\r\n        auto lock = s_callerNameLock.lock_shared();\r\n        return s_callerName.has_value() ? s_callerName.value() : defaultNameIfNotSet;\r\n    }\r\n\r\n    std::pair<HRESULT, DWORD> GetCallerProcessId()\r\n    {\r\n        RPC_STATUS rpcStatus = RPC_S_OK;\r\n        RPC_CALL_ATTRIBUTES callAttributes = {};\r\n        callAttributes.Version = RPC_CALL_ATTRIBUTES_VERSION;\r\n        callAttributes.Flags = RPC_QUERY_CLIENT_PID;\r\n        rpcStatus = RpcServerInqCallAttributes(nullptr, &callAttributes);\r\n\r\n        if (rpcStatus == RPC_S_NO_CALL_ACTIVE ||\r\n            (rpcStatus == RPC_S_OK && HandleToULong(callAttributes.ClientPID) == GetCurrentProcessId()))\r\n        {\r\n            // in-proc is supported now.\r\n            return { S_OK, GetCurrentProcessId() };\r\n        }\r\n        else if (rpcStatus == RPC_S_OK)\r\n        {\r\n            // out-of-proc case.\r\n            return { S_OK, HandleToULong(callAttributes.ClientPID) };\r\n        }\r\n        else\r\n        {\r\n            return { E_ACCESSDENIED, 0 };\r\n        }\r\n    }\r\n\r\n    std::wstring_view GetStringForCapability(Capability capability)\r\n    {\r\n        switch (capability)\r\n        {\r\n        case Capability::PackageManagement:\r\n            return L\"packageManagement\"sv;\r\n        case Capability::PackageQuery:\r\n            return L\"packageQuery\"sv;\r\n        default:\r\n            winrt::throw_hresult(E_UNEXPECTED);\r\n        }\r\n    }\r\n\r\n    HRESULT EnsureProcessHasCapability(Capability requiredCapability, DWORD callerProcessId)\r\n    {\r\n        bool allowed = false;\r\n\r\n        if (winrt::Windows::Foundation::Metadata::ApiInformation::IsTypePresent(winrt::name_of<winrt::Windows::Security::Authorization::AppCapabilityAccess::AppCapability>()))\r\n        {\r\n            // Get the caller process id and use it to check if the caller has permissions to access the feature.\r\n            winrt::Windows::Security::Authorization::AppCapabilityAccess::AppCapabilityAccessStatus status = winrt::Windows::Security::Authorization::AppCapabilityAccess::AppCapabilityAccessStatus::DeniedBySystem;\r\n\r\n            winrt::Windows::Security::Authorization::AppCapabilityAccess::AppCapability capability{ nullptr };\r\n\r\n            try\r\n            {\r\n                capability = winrt::Windows::Security::Authorization::AppCapabilityAccess::AppCapability::CreateWithProcessIdForUser(nullptr, GetStringForCapability(requiredCapability), callerProcessId);\r\n            }\r\n            catch (const winrt::hresult_invalid_argument&)\r\n            {\r\n            }\r\n\r\n            if (capability)\r\n            {\r\n                status = capability.CheckAccess();\r\n\r\n                return ((status == winrt::Windows::Security::Authorization::AppCapabilityAccess::AppCapabilityAccessStatus::Allowed) ? S_OK : E_ACCESSDENIED);\r\n            }\r\n        }\r\n\r\n        // If AppCapability is not present, require at least medium IL callers\r\n        auto requiredIntegrityLevel = AppInstaller::Security::IntegrityLevel::Medium;\r\n\r\n        if (callerProcessId != GetCurrentProcessId())\r\n        {\r\n            allowed = AppInstaller::Security::IsCOMCallerIntegrityLevelAtLeast(requiredIntegrityLevel);\r\n        }\r\n        else\r\n        {\r\n            allowed = AppInstaller::Security::IsCurrentIntegrityLevelAtLeast(requiredIntegrityLevel);\r\n        }\r\n\r\n        return (allowed ? S_OK : E_ACCESSDENIED);\r\n    }\r\n\r\n    HRESULT EnsureComCallerHasCapability(Capability requiredCapability)\r\n    {\r\n        auto [hr, callerProcessId] = GetCallerProcessId();\r\n        RETURN_IF_FAILED(hr);\r\n        hr = EnsureProcessHasCapability(requiredCapability, callerProcessId);\r\n        // The Windows.Management.Deployment API has set the precedent that packageManagement is a superset of packageQuery\r\n        // and packageQuery does not need to be declared separately.\r\n        if (FAILED(hr) && requiredCapability == Capability::PackageQuery)\r\n        {\r\n            hr = EnsureProcessHasCapability(Capability::PackageManagement, callerProcessId);\r\n        }\r\n        RETURN_HR(hr);\r\n    }\r\n\r\n    // Best effort at getting caller info. This should only be used for logging.\r\n    std::wstring TryGetCallerProcessInfo(DWORD callerProcessId)\r\n    {\r\n        wil::unique_process_handle processHandle(OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, callerProcessId));\r\n        if (processHandle)\r\n        {\r\n            WCHAR packageFamilyName[PACKAGE_FAMILY_NAME_MAX_LENGTH]{};\r\n            UINT32 length = ARRAYSIZE(packageFamilyName);\r\n            if (::GetPackageFamilyName(processHandle.get(), &length, packageFamilyName) == ERROR_SUCCESS)\r\n            {\r\n                // If the package is calling into itself, fall through to the executable name\r\n                if (AppInstaller::Runtime::GetPackageFamilyName() != packageFamilyName)\r\n                {\r\n                    return { packageFamilyName };\r\n                }\r\n            }\r\n\r\n            // if the caller doesn't have an AppUserModelID then fall back to the executable name\r\n            std::filesystem::path executablePath = AppInstaller::Filesystem::GetExecutablePathForProcess(processHandle.get());\r\n            if (executablePath.has_filename())\r\n            {\r\n                return executablePath.filename();\r\n            }\r\n            else if (!executablePath.empty())\r\n            {\r\n                AICLI_LOG(Fail, Error, << \"Unable to get valid executable for process ID [\" << callerProcessId << \"]: \" << executablePath);\r\n            }\r\n        }\r\n\r\n        return {};\r\n    }\r\n\r\n    std::string GetCallerName()\r\n    {\r\n        // See if caller name is set by caller\r\n        std::string callerName = GetComCallerName(\"\");\r\n\r\n        // Get process string\r\n        if (callerName.empty())\r\n        {\r\n            try\r\n            {\r\n                auto [hrGetCallerId, callerProcessId] = GetCallerProcessId();\r\n                if (SUCCEEDED(hrGetCallerId))\r\n                {\r\n                    callerName = AppInstaller::Utility::ConvertToUTF8(TryGetCallerProcessInfo(callerProcessId));\r\n                }\r\n            }\r\n            CATCH_LOG();\r\n        }\r\n\r\n        if (callerName.empty())\r\n        {\r\n            callerName = \"UnknownComCaller\";\r\n        }\r\n\r\n        return callerName;\r\n    }\r\n\r\n    bool IsBackgroundProcessForPolicy()\r\n    {\r\n        bool isBackgroundProcessForPolicy = false;\r\n        try\r\n        {\r\n            auto [hrGetCallerId, callerProcessId] = GetCallerProcessId();\r\n            if (SUCCEEDED(hrGetCallerId) && callerProcessId != GetCurrentProcessId())\r\n            {\r\n                // OutOfProc case, we check for explorer.exe\r\n                auto callerNameWide = AppInstaller::Utility::ConvertToUTF16(GetCallerName());\r\n                auto processName = AppInstaller::Utility::ConvertToUTF8(std::filesystem::path{ callerNameWide }.filename().wstring());\r\n                if (::AppInstaller::Utility::CaseInsensitiveEquals(\"explorer.exe\", processName) ||\r\n                    ::AppInstaller::Utility::CaseInsensitiveEquals(\"taskhostw.exe\", processName))\r\n                {\r\n                    isBackgroundProcessForPolicy = true;\r\n                }\r\n            }\r\n        }\r\n        CATCH_LOG();\r\n\r\n        return isBackgroundProcessForPolicy;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/Helpers.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"Public/CoCreatableMicrosoftManagementDeploymentClass.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    void SetComCallerName(std::string name);\r\n    std::string GetComCallerName(std::string defaultNameIfNotSet);\r\n\r\n    enum class Capability\r\n    {\r\n        PackageManagement,\r\n        PackageQuery\r\n    };\r\n\r\n    HRESULT EnsureProcessHasCapability(Capability requiredCapability, DWORD callerProcessId);\r\n    HRESULT EnsureComCallerHasCapability(Capability requiredCapability);\r\n    std::pair<HRESULT, DWORD> GetCallerProcessId();\r\n    std::wstring TryGetCallerProcessInfo(DWORD callerProcessId);\r\n    std::string GetCallerName();\r\n    bool IsBackgroundProcessForPolicy();\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/Icon.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"Icon.g.cpp\"\n#include \"Icon.h\"\n#include \"Converters.h\"\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    void Icon::Initialize(::AppInstaller::Manifest::Icon icon)\n    {\n        m_icon = std::move(icon);\n    }\n    hstring Icon::Url()\n    {\n        return winrt::to_hstring(m_icon.Url);\n    }\n    IconFileType Icon::FileType()\n    {\n        return GetDeploymentIconFileType(m_icon.FileType);\n    }\n    IconResolution Icon::Resolution()\n    {\n        return GetDeploymentIconResolution(m_icon.Resolution);\n    }\n    IconTheme Icon::Theme()\n    {\n        return GetDeploymentIconTheme(m_icon.Theme);\n    }\n    com_array<uint8_t> Icon::Sha256()\n    {\n        return com_array<uint8_t>(m_icon.Sha256);\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/Icon.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"Icon.g.h\"\n#include <winget/Manifest.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    struct Icon : IconT<Icon>\n    {\n        Icon() = default;\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void Initialize(::AppInstaller::Manifest::Icon icon);\n#endif\n\n        hstring Url();\n        IconFileType FileType();\n        IconResolution Resolution();\n        IconTheme Theme();\n        com_array<uint8_t> Sha256();\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        ::AppInstaller::Manifest::Icon m_icon{};\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/InstallOptions.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#pragma warning( push )\r\n#pragma warning ( disable : 4467 6388)\r\n// 6388 Allow CreateInstance.\r\n#include <wil\\cppwinrt_wrl.h>\r\n// 4467 Allow use of uuid attribute for com object creation.\r\n#include \"InstallOptions.h\"\r\n#pragma warning( pop )\r\n#include \"InstallOptions.g.cpp\"\r\n#include \"Converters.h\"\r\n#include \"Helpers.h\"\r\n\r\n#include <AppInstallerArchitecture.h>\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    InstallOptions::InstallOptions()\r\n    {\r\n        // Populate the allowed architectures with the default values for the machine\r\n        for (AppInstaller::Utility::Architecture architecture : AppInstaller::Utility::GetApplicableArchitectures())\r\n        {\r\n            auto convertedArchitecture = GetWindowsSystemProcessorArchitecture(architecture);\r\n            if (convertedArchitecture)\r\n            {\r\n                m_allowedArchitectures.Append(convertedArchitecture.value());\r\n            }\r\n        }\r\n    }\r\n    winrt::Microsoft::Management::Deployment::PackageVersionId InstallOptions::PackageVersionId()\r\n    {\r\n        return m_packageVersionId;\r\n    }\r\n    void InstallOptions::PackageVersionId(winrt::Microsoft::Management::Deployment::PackageVersionId const& value)\r\n    {\r\n        m_packageVersionId = value;\r\n    }\r\n    hstring InstallOptions::PreferredInstallLocation()\r\n    {\r\n        return hstring(m_preferredInstallLocation);\r\n    }\r\n    void InstallOptions::PreferredInstallLocation(hstring const& value)\r\n    {\r\n        m_preferredInstallLocation = value;\r\n    }\r\n    winrt::Microsoft::Management::Deployment::PackageInstallScope InstallOptions::PackageInstallScope()\r\n    {\r\n        return m_packageInstallScope;\r\n    }\r\n    void InstallOptions::PackageInstallScope(winrt::Microsoft::Management::Deployment::PackageInstallScope const& value)\r\n    {\r\n        m_packageInstallScope = value;\r\n    }\r\n    winrt::Microsoft::Management::Deployment::PackageInstallMode InstallOptions::PackageInstallMode()\r\n    {\r\n        return m_packageInstallMode;\r\n    }\r\n    void InstallOptions::PackageInstallMode(winrt::Microsoft::Management::Deployment::PackageInstallMode const& value)\r\n    {\r\n        m_packageInstallMode = value;\r\n    }\r\n    winrt::Microsoft::Management::Deployment::PackageInstallerType InstallOptions::InstallerType()\r\n    {\r\n        return m_installerType;\r\n    }\r\n    void InstallOptions::InstallerType(winrt::Microsoft::Management::Deployment::PackageInstallerType const& value)\r\n    {\r\n        m_installerType = value;\r\n    }\r\n    hstring InstallOptions::LogOutputPath()\r\n    {\r\n        return hstring(m_logOutputPath);\r\n    }\r\n    void InstallOptions::LogOutputPath(hstring const& value)\r\n    {\r\n        m_logOutputPath = value;\r\n    }\r\n    bool InstallOptions::AllowHashMismatch()\r\n    {\r\n        return m_allowHashMismatch;\r\n    }\r\n    void InstallOptions::AllowHashMismatch(bool value)\r\n    {\r\n        m_allowHashMismatch = value;\r\n    }\r\n    bool InstallOptions::BypassIsStoreClientBlockedPolicyCheck()\r\n    {\r\n        return m_bypassIsStoreClientBlockedPolicyCheck;\r\n    }\r\n    void InstallOptions::BypassIsStoreClientBlockedPolicyCheck(bool value)\r\n    {\r\n        m_bypassIsStoreClientBlockedPolicyCheck = value;\r\n    }\r\n    hstring InstallOptions::ReplacementInstallerArguments()\r\n    {\r\n        return hstring(m_replacementInstallerArguments);\r\n    }\r\n    void InstallOptions::ReplacementInstallerArguments(hstring const& value)\r\n    {\r\n        m_replacementInstallerArguments = value;\r\n    }\r\n    hstring InstallOptions::AdditionalInstallerArguments()\r\n    {\r\n        return hstring(m_additionalInstallerArguments);\r\n    }\r\n    void InstallOptions::AdditionalInstallerArguments(hstring const& value)\r\n    {\r\n        m_additionalInstallerArguments = value;\r\n    }\r\n    hstring InstallOptions::CorrelationData()\r\n    {\r\n        return hstring(m_correlationData);\r\n    }\r\n    void InstallOptions::CorrelationData(hstring const& value)\r\n    {\r\n        m_correlationData = value;\r\n    }\r\n    hstring InstallOptions::AdditionalPackageCatalogArguments()\r\n    {\r\n        return hstring(m_additionalPackageCatalogArguments);\r\n    }\r\n    void InstallOptions::AdditionalPackageCatalogArguments(hstring const& value)\r\n    {\r\n        m_additionalPackageCatalogArguments = value;\r\n    }\r\n    winrt::Windows::Foundation::Collections::IVector<winrt::Windows::System::ProcessorArchitecture> InstallOptions::AllowedArchitectures()\r\n    {\r\n        return m_allowedArchitectures;\r\n    }\r\n    bool InstallOptions::AllowUpgradeToUnknownVersion()\r\n    {\r\n        return m_allowUpgradeToUnknownVersion;\r\n    }\r\n    void InstallOptions::AllowUpgradeToUnknownVersion(bool value)\r\n    {\r\n        m_allowUpgradeToUnknownVersion = value;\r\n    }\r\n    bool InstallOptions::Force()\r\n    {\r\n        return m_force;\r\n    }\r\n    void InstallOptions::Force(bool value)\r\n    {\r\n        m_force = value;\r\n    }\r\n    void InstallOptions::AcceptPackageAgreements(bool value)\r\n    {\r\n        m_acceptPackageAgreements = value;\r\n    }\r\n    bool InstallOptions::AcceptPackageAgreements()\r\n    {\r\n        return m_acceptPackageAgreements;\r\n    }\r\n    void InstallOptions::SkipDependencies(bool value)\r\n    {\r\n        m_skipDependencies = value;\r\n    }\r\n    bool InstallOptions::SkipDependencies()\r\n    {\r\n        return m_skipDependencies;\r\n    }\r\n    winrt::Microsoft::Management::Deployment::AuthenticationArguments InstallOptions::AuthenticationArguments()\r\n    {\r\n        return m_authenticationArguments;\r\n    }\r\n    void InstallOptions::AuthenticationArguments(winrt::Microsoft::Management::Deployment::AuthenticationArguments const& value)\r\n    {\r\n        m_authenticationArguments = value;\r\n    }\r\n    CoCreatableMicrosoftManagementDeploymentClass(InstallOptions);\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/InstallOptions.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"InstallOptions.g.h\"\r\n#include \"Public/ComClsids.h\"\r\n#include <winget/ModuleCountBase.h>\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    [uuid(WINGET_OUTOFPROC_COM_CLSID_InstallOptions)]\r\n    struct InstallOptions : InstallOptionsT<InstallOptions>\r\n    {\r\n        InstallOptions();\r\n\r\n        winrt::Microsoft::Management::Deployment::PackageVersionId PackageVersionId();\r\n        void PackageVersionId(winrt::Microsoft::Management::Deployment::PackageVersionId const& value);\r\n        hstring PreferredInstallLocation();\r\n        void PreferredInstallLocation(hstring const& value);\r\n        winrt::Microsoft::Management::Deployment::PackageInstallScope PackageInstallScope();\r\n        void PackageInstallScope(winrt::Microsoft::Management::Deployment::PackageInstallScope const& value);\r\n        winrt::Microsoft::Management::Deployment::PackageInstallMode PackageInstallMode();\r\n        void PackageInstallMode(winrt::Microsoft::Management::Deployment::PackageInstallMode const& value);\r\n        winrt::Microsoft::Management::Deployment::PackageInstallerType InstallerType();\r\n        void InstallerType(winrt::Microsoft::Management::Deployment::PackageInstallerType const& value);\r\n        hstring LogOutputPath();\r\n        void LogOutputPath(hstring const& value);\r\n        bool AllowHashMismatch();\r\n        void AllowHashMismatch(bool value);\r\n        bool BypassIsStoreClientBlockedPolicyCheck();\r\n        void BypassIsStoreClientBlockedPolicyCheck(bool value);\r\n        hstring ReplacementInstallerArguments();\r\n        void ReplacementInstallerArguments(hstring const& value);\r\n        hstring AdditionalInstallerArguments();\r\n        void AdditionalInstallerArguments(hstring const& value);\r\n        hstring CorrelationData();\r\n        void CorrelationData(hstring const& value);\r\n        hstring AdditionalPackageCatalogArguments();\r\n        void AdditionalPackageCatalogArguments(hstring const& value);\r\n        winrt::Windows::Foundation::Collections::IVector<winrt::Windows::System::ProcessorArchitecture> AllowedArchitectures();\r\n        bool AllowUpgradeToUnknownVersion();\r\n        void AllowUpgradeToUnknownVersion(bool value);\r\n        bool Force();\r\n        void Force(bool value);\r\n        bool AcceptPackageAgreements();\r\n        void AcceptPackageAgreements(bool value);\r\n        bool SkipDependencies();\r\n        void SkipDependencies(bool value);\r\n        winrt::Microsoft::Management::Deployment::AuthenticationArguments AuthenticationArguments();\r\n        void AuthenticationArguments(winrt::Microsoft::Management::Deployment::AuthenticationArguments const& value);\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        winrt::Microsoft::Management::Deployment::PackageVersionId m_packageVersionId{ nullptr };\r\n        std::wstring m_preferredInstallLocation = L\"\";\r\n        winrt::Microsoft::Management::Deployment::PackageInstallScope m_packageInstallScope = winrt::Microsoft::Management::Deployment::PackageInstallScope::Any;\r\n        winrt::Microsoft::Management::Deployment::PackageInstallMode m_packageInstallMode = winrt::Microsoft::Management::Deployment::PackageInstallMode::Default;\r\n        winrt::Microsoft::Management::Deployment::PackageInstallerType m_installerType = winrt::Microsoft::Management::Deployment::PackageInstallerType::Unknown;\r\n        std::wstring m_logOutputPath = L\"\";\r\n        bool m_allowHashMismatch = false;\r\n        bool m_bypassIsStoreClientBlockedPolicyCheck = false;\r\n        std::wstring m_replacementInstallerArguments = L\"\";\r\n        std::wstring m_additionalInstallerArguments = L\"\";\r\n        std::wstring m_correlationData = L\"\";\r\n        std::wstring m_additionalPackageCatalogArguments = L\"\";\r\n        Windows::Foundation::Collections::IVector<Windows::System::ProcessorArchitecture> m_allowedArchitectures{\r\n            winrt::single_threaded_vector<winrt::Windows::System::ProcessorArchitecture>() };\r\n        bool m_allowUpgradeToUnknownVersion = false;\r\n        bool m_force = false;\r\n        bool m_acceptPackageAgreements = true;\r\n        bool m_skipDependencies = false;\r\n        winrt::Microsoft::Management::Deployment::AuthenticationArguments m_authenticationArguments{ nullptr };\r\n#endif\r\n    };\r\n}\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\nnamespace winrt::Microsoft::Management::Deployment::factory_implementation\r\n{\r\n    struct InstallOptions : InstallOptionsT<InstallOptions, implementation::InstallOptions>, AppInstaller::WinRT::ModuleCountBase\r\n    {\r\n    };\r\n}\r\n#endif\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/InstallResult.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"InstallResult.h\"\n#include \"InstallResult.g.cpp\"\n#include <wil\\cppwinrt_wrl.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    void InstallResult::Initialize(\n        winrt::Microsoft::Management::Deployment::InstallResultStatus status,\n        winrt::hresult extendedErrorCode,\n        uint32_t installerErrorCode,\n        hstring const& correlationData, \n        bool rebootRequired)\n    {\n        m_status = status;\n        m_extendedErrorCode = extendedErrorCode;\n        m_installerErrorCode = installerErrorCode;\n        m_correlationData = correlationData;\n        m_rebootRequired = rebootRequired;\n    }\n    hstring InstallResult::CorrelationData()\n    {\n        return hstring(m_correlationData);\n    }\n    bool InstallResult::RebootRequired()\n    {\n        return m_rebootRequired;\n    }\n    winrt::Microsoft::Management::Deployment::InstallResultStatus InstallResult::Status()\n    {\n        return m_status;\n    }\n    winrt::hresult InstallResult::ExtendedErrorCode()\n    {\n        return m_extendedErrorCode;\n    }\n\n    uint32_t InstallResult::InstallerErrorCode()\n    {\n        return m_installerErrorCode;\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/InstallResult.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"InstallResult.g.h\"\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    struct InstallResult : InstallResultT<InstallResult>\n    {\n        InstallResult() = default;\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void Initialize(\n            winrt::Microsoft::Management::Deployment::InstallResultStatus status,\n            winrt::hresult extendedErrorCode,\n            uint32_t installerErrorCode,\n            hstring const& correlationData, \n            bool rebootRequired);\n#endif\n\n        hstring CorrelationData();\n        bool RebootRequired();\n        winrt::Microsoft::Management::Deployment::InstallResultStatus Status();\n        winrt::hresult ExtendedErrorCode();\n        uint32_t InstallerErrorCode();\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        std::wstring m_correlationData = L\"\";\n        bool m_rebootRequired = false;\n        winrt::Microsoft::Management::Deployment::InstallResultStatus m_status = winrt::Microsoft::Management::Deployment::InstallResultStatus::Ok;\n        winrt::hresult m_extendedErrorCode = S_OK;\n        uint32_t m_installerErrorCode = 0;\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/InstalledStatus.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"InstalledStatus.h\"\n#include \"InstalledStatus.g.cpp\"\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    void InstalledStatus::Initialize(const ::AppInstaller::Repository::InstalledStatus& installedStatus)\n    {\n        m_type = static_cast<Microsoft::Management::Deployment::InstalledStatusType>(installedStatus.Type);\n        m_path = winrt::to_hstring(installedStatus.Path);\n        m_status = installedStatus.Status;\n    }\n    winrt::Microsoft::Management::Deployment::InstalledStatusType InstalledStatus::Type()\r\n    {\r\n        return m_type;\r\n    }\n    hstring InstalledStatus::Path()\r\n    {\r\n        return m_path;\r\n    }\n    winrt::hresult InstalledStatus::Status()\r\n    {\r\n        return m_status;\r\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/InstalledStatus.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"InstalledStatus.g.h\"\n#include <winget/RepositorySearch.h>\n#include <winget/InstalledStatus.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    struct InstalledStatus : InstalledStatusT<InstalledStatus>\n    {\n        InstalledStatus() = default;\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void Initialize(const ::AppInstaller::Repository::InstalledStatus& installedStatus);\n#endif\n\n        winrt::Microsoft::Management::Deployment::InstalledStatusType Type();\n        hstring Path();\n        winrt::hresult Status();\n        \n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        winrt::Microsoft::Management::Deployment::InstalledStatusType m_type = winrt::Microsoft::Management::Deployment::InstalledStatusType::None;\n        hstring m_path;\n        winrt::hresult m_status = S_OK;\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/MatchResult.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include <winget/RepositorySource.h>\n#include \"MatchResult.h\"\n#include \"MatchResult.g.cpp\"\n#include \"CatalogPackage.h\"\n#include <wil\\cppwinrt_wrl.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    void MatchResult::Initialize(Microsoft::Management::Deployment::CatalogPackage package, Microsoft::Management::Deployment::PackageMatchFilter matchCriteria)\n    {\n        m_catalogPackage = package;\n        m_matchCriteria = matchCriteria;\n    }\n    winrt::Microsoft::Management::Deployment::CatalogPackage MatchResult::CatalogPackage()\n    {\n        return m_catalogPackage;\n    }\n    winrt::Microsoft::Management::Deployment::PackageMatchFilter MatchResult::MatchCriteria()\n    {\n        return m_matchCriteria;\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/MatchResult.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"MatchResult.g.h\"\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    struct MatchResult : MatchResultT<MatchResult>\n    {\n        MatchResult() = default;\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void Initialize(Microsoft::Management::Deployment::CatalogPackage package, Microsoft::Management::Deployment::PackageMatchFilter matchCriteria);\n#endif\n\n        winrt::Microsoft::Management::Deployment::CatalogPackage CatalogPackage();\n        winrt::Microsoft::Management::Deployment::PackageMatchFilter MatchCriteria();\n        \n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        Microsoft::Management::Deployment::CatalogPackage m_catalogPackage{ nullptr };\n        Microsoft::Management::Deployment::PackageMatchFilter m_matchCriteria{ nullptr };\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/Microsoft.Management.Deployment.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" />\r\n  <PropertyGroup Label=\"Globals\">\r\n    <CppWinRTOptimized>true</CppWinRTOptimized>\r\n    <CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>\r\n    <CppWinRTGenerateWindowsMetadata>true</CppWinRTGenerateWindowsMetadata>\r\n    <MinimalCoreWin>true</MinimalCoreWin>\r\n    <ProjectGuid>{1cc41a9a-ae66-459d-9210-1e572dd7be69}</ProjectGuid>\r\n    <ProjectName>Microsoft.Management.Deployment</ProjectName>\r\n    <RootNamespace>Microsoft.Management.Deployment</RootNamespace>\r\n    <DefaultLanguage>en-US</DefaultLanguage>\r\n    <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>\r\n    <ApplicationTypeRevision>10.0</ApplicationTypeRevision>\r\n    <WindowsTargetPlatformVersion>10.0.26100.0</WindowsTargetPlatformVersion>\r\n    <WindowsTargetPlatformMinVersion>10.0.17763.0</WindowsTargetPlatformMinVersion>\r\n    <WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>\r\n    <CppWinRTParameters>-library Microsoft_Management_Deployment</CppWinRTParameters>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|ARM64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|Win32\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|ARM64\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|Win32\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|x64\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|ARM64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|Win32\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <PropertyGroup Label=\"Configuration\">\r\n    <ConfigurationType>StaticLibrary</ConfigurationType>\r\n    <GenerateManifest>false</GenerateManifest>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Debug'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n    <LinkIncremental>true</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Release'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='ReleaseStatic'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\r\n  <ImportGroup Label=\"ExtensionSettings\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"Shared\">\r\n    <Import Project=\"..\\COMServer\\COMServer.vcxitems\" Label=\"Shared\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"PropertySheet.props\" />\r\n  </ImportGroup>\r\n  <PropertyGroup Label=\"UserMacros\" />\r\n  <PropertyGroup>\r\n    <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>\r\n    <OutDir>$(SolutionDir)$(PlatformTarget)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <IntDir>$(PlatformTarget)\\$(Configuration)\\</IntDir>\r\n    <TargetName>$(RootNamespace).Server</TargetName>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(ProjectDir)\\..\\vcpkg.props\" />\r\n  <ItemDefinitionGroup>\r\n    <ClCompile>\r\n      <PrecompiledHeader>Use</PrecompiledHeader>\r\n      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>\r\n      <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <AdditionalOptions>%(AdditionalOptions) /bigobj</AdditionalOptions>\r\n      <TreatWarningAsError>true</TreatWarningAsError>\r\n      <SDLCheck>true</SDLCheck>\r\n      <PreprocessorDefinitions>_WINRT_DLL;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>\r\n      <AdditionalIncludeDirectories>$(ProjectDir)..\\AppInstallerCLICore;$(ProjectDir);$(ProjectDir)..\\AppInstallerRepositoryCore;$(ProjectDir)..\\AppInstallerRepositoryCore\\Public;$(ProjectDir)..\\AppInstallerCommonCore\\Public;$(ProjectDir)..\\AppInstallerSharedLib\\Public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <ModuleDefinitionFile>Microsoft_Management_Deployment.def</ModuleDefinitionFile>\r\n      <WindowsMetadataFile>$(OutDir)$(ProjectName).winmd</WindowsMetadataFile>\r\n      <AdditionalDependencies>AppInstallerCLICore.lib;AppInstallerCommonCore.lib;AppInstallerRepositoryCore.lib;JsonCppLib.lib;YamlCppLib.lib;wininet.lib;shell32.lib;winsqlite3.lib;shlwapi.lib;icuuc.lib;icuin.lib;urlmon.lib;Advapi32.lib;winhttp.lib;pure.lib%(AdditionalDependencies)</AdditionalDependencies>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Debug'\">\r\n    <ClCompile>\r\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <ProgramDataBaseFileName>$(OutDir)$(TargetName)Debug.pdb</ProgramDataBaseFileName>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Release'\">\r\n    <ClCompile>\r\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='ReleaseStatic'\">\r\n    <ClCompile>\r\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">MultiThreaded</RuntimeLibrary>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">MultiThreaded</RuntimeLibrary>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">MultiThreaded</RuntimeLibrary>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"AddPackageCatalogOptions.h\" />\r\n    <ClInclude Include=\"AddPackageCatalogResult.h\" />\r\n    <ClInclude Include=\"AuthenticationArguments.h\" />\r\n    <ClInclude Include=\"AuthenticationInfo.h\" />\r\n    <ClInclude Include=\"CatalogPackage.h\" />\r\n    <ClInclude Include=\"CheckInstalledStatusResult.h\" />\r\n    <ClInclude Include=\"ConnectResult.h\" />\r\n    <ClInclude Include=\"Converters.h\" />\r\n    <ClInclude Include=\"CreateCompositePackageCatalogOptions.h\" />\r\n    <ClInclude Include=\"Documentation.h\" />\r\n    <ClInclude Include=\"DownloadOptions.h\" />\r\n    <ClInclude Include=\"DownloadResult.h\" />\r\n    <ClInclude Include=\"EditPackageCatalogOptions.h\" />\r\n    <ClInclude Include=\"EditPackageCatalogResult.h\" />\r\n    <ClInclude Include=\"FindPackagesOptions.h\" />\r\n    <ClInclude Include=\"FindPackagesResult.h\" />\r\n    <ClInclude Include=\"Helpers.h\" />\r\n    <ClInclude Include=\"Icon.h\" />\r\n    <ClInclude Include=\"InstalledStatus.h\" />\r\n    <ClInclude Include=\"InstallOptions.h\" />\r\n    <ClInclude Include=\"InstallResult.h\" />\r\n    <ClInclude Include=\"MatchResult.h\" />\r\n    <ClInclude Include=\"MicrosoftEntraIdAuthenticationInfo.h\" />\r\n    <ClInclude Include=\"PackageAgreement.h\" />\r\n    <ClInclude Include=\"PackageCatalog.h\" />\r\n    <ClInclude Include=\"PackageCatalogInfo.h\" />\r\n    <ClInclude Include=\"PackageCatalogProgress.h\" />\r\n    <ClInclude Include=\"PackageCatalogReference.h\" />\r\n    <ClInclude Include=\"PackageInstallerInfo.h\" />\r\n    <ClInclude Include=\"PackageInstallerInstalledStatus.h\" />\r\n    <ClInclude Include=\"CatalogPackageMetadata.h\" />\r\n    <ClInclude Include=\"PackageManager.h\" />\r\n    <ClInclude Include=\"PackageManagerSettings.h\" />\r\n    <ClInclude Include=\"PackageMatchFilter.h\" />\r\n    <ClInclude Include=\"PackageVersionId.h\" />\r\n    <ClInclude Include=\"PackageVersionInfo.h\" />\r\n    <ClInclude Include=\"pch.h\" />\r\n    <ClInclude Include=\"Public\\CanUnload.h\" />\r\n    <ClInclude Include=\"Public\\CoCreatableMicrosoftManagementDeploymentClass.h\" />\r\n    <ClInclude Include=\"Public\\ComClsids.h\" />\r\n    <ClInclude Include=\"RemovePackageCatalogOptions.h\" />\r\n    <ClInclude Include=\"RepairOptions.h\" />\r\n    <ClInclude Include=\"RepairResult.h\" />\r\n    <ClInclude Include=\"RemovePackageCatalogResult.h\" />\r\n    <ClInclude Include=\"SourceAgreement.h\" />\r\n    <ClInclude Include=\"UninstallOptions.h\" />\r\n    <ClInclude Include=\"UninstallResult.h\" />\r\n    <ClInclude Include=\"RefreshPackageCatalogResult.h\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"AddPackageCatalogOptions.cpp\" />\r\n    <ClCompile Include=\"AddPackageCatalogResult.cpp\" />\r\n    <ClCompile Include=\"AuthenticationArguments.cpp\" />\r\n    <ClCompile Include=\"AuthenticationInfo.cpp\" />\r\n    <ClCompile Include=\"CanUnload.cpp\" />\r\n    <ClCompile Include=\"CatalogPackage.cpp\" />\r\n    <ClCompile Include=\"CheckInstalledStatusResult.cpp\" />\r\n    <ClCompile Include=\"ComClsids.cpp\" />\r\n    <ClCompile Include=\"ConnectResult.cpp\" />\r\n    <ClCompile Include=\"Converters.cpp\" />\r\n    <ClCompile Include=\"CreateCompositePackageCatalogOptions.cpp\" />\r\n    <ClCompile Include=\"Documentation.cpp\" />\r\n    <ClCompile Include=\"DownloadOptions.cpp\" />\r\n    <ClCompile Include=\"DownloadResult.cpp\" />\r\n    <ClCompile Include=\"EditPackageCatalogOptions.cpp\" />\r\n    <ClCompile Include=\"EditPackageCatalogResult.cpp\" />\r\n    <ClCompile Include=\"FindPackagesOptions.cpp\" />\r\n    <ClCompile Include=\"FindPackagesResult.cpp\" />\r\n    <ClCompile Include=\"Helpers.cpp\" />\r\n    <ClCompile Include=\"Icon.cpp\" />\r\n    <ClCompile Include=\"InstalledStatus.cpp\" />\r\n    <ClCompile Include=\"InstallOptions.cpp\" />\r\n    <ClCompile Include=\"InstallResult.cpp\" />\r\n    <ClCompile Include=\"MatchResult.cpp\" />\r\n    <ClCompile Include=\"MicrosoftEntraIdAuthenticationInfo.cpp\" />\r\n    <ClCompile Include=\"PackageAgreement.cpp\" />\r\n    <ClCompile Include=\"PackageCatalog.cpp\" />\r\n    <ClCompile Include=\"PackageCatalogInfo.cpp\" />\r\n    <ClCompile Include=\"PackageCatalogProgress.cpp\" />\r\n    <ClCompile Include=\"PackageCatalogReference.cpp\" />\r\n    <ClCompile Include=\"PackageInstallerInfo.cpp\" />\r\n    <ClCompile Include=\"PackageInstallerInstalledStatus.cpp\" />\r\n    <ClCompile Include=\"CatalogPackageMetadata.cpp\" />\r\n    <ClCompile Include=\"PackageManager.cpp\" />\r\n    <ClCompile Include=\"PackageManagerSettings.cpp\" />\r\n    <ClCompile Include=\"PackageMatchFilter.cpp\" />\r\n    <ClCompile Include=\"PackageVersionId.cpp\" />\r\n    <ClCompile Include=\"PackageVersionInfo.cpp\" />\r\n    <ClCompile Include=\"pch.cpp\">\r\n      <PrecompiledHeader>Create</PrecompiledHeader>\r\n    </ClCompile>\r\n    <ClCompile Include=\"RemovePackageCatalogOptions.cpp\" />\r\n    <ClCompile Include=\"RepairOptions.cpp\" />\r\n    <ClCompile Include=\"RepairResult.cpp\" />\r\n    <ClCompile Include=\"RemovePackageCatalogResult.cpp\" />\r\n    <ClCompile Include=\"SourceAgreement.cpp\" />\r\n    <ClCompile Include=\"$(GeneratedFilesDir)module.g.cpp\" />\r\n    <ClCompile Include=\"UninstallOptions.cpp\" />\r\n    <ClCompile Include=\"UninstallResult.cpp\" />\r\n    <ClCompile Include=\"RefreshPackageCatalogResult.cpp\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"Microsoft_Management_Deployment.def\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"packages.config\" />\r\n    <None Include=\"PropertySheet.props\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Midl Include=\"PackageManager.idl\" />\r\n  </ItemGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\r\n  <ImportGroup Label=\"ExtensionTargets\">\r\n    <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" />\r\n    <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets')\" />\r\n  </ImportGroup>\r\n  <Target Name=\"EnsureNuGetPackageBuildImports\" BeforeTargets=\"PrepareForBuild\">\r\n    <PropertyGroup>\r\n      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>\r\n    </PropertyGroup>\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props'))\" />\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets'))\" />\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets'))\" />\r\n  </Target>\r\n</Project>"
  },
  {
    "path": "src/Microsoft.Management.Deployment/Microsoft.Management.Deployment.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup>\r\n    <ClCompile Include=\"CatalogPackage.cpp\" />\r\n    <ClCompile Include=\"CheckInstalledStatusResult.cpp\" />\r\n    <ClCompile Include=\"ComClsids.cpp\" />\r\n    <ClCompile Include=\"ConnectResult.cpp\" />\r\n    <ClCompile Include=\"Converters.cpp\" />\r\n    <ClCompile Include=\"CreateCompositePackageCatalogOptions.cpp\" />\r\n    <ClCompile Include=\"Documentation.cpp\" />\r\n    <ClCompile Include=\"DownloadOptions.cpp\" />\r\n    <ClCompile Include=\"DownloadResult.cpp\" />\r\n    <ClCompile Include=\"FindPackagesOptions.cpp\" />\r\n    <ClCompile Include=\"FindPackagesResult.cpp\" />\r\n    <ClCompile Include=\"Helpers.cpp\" />\r\n    <ClCompile Include=\"Icon.cpp\" />\r\n    <ClCompile Include=\"InstallOptions.cpp\" />\r\n    <ClCompile Include=\"InstallResult.cpp\" />\r\n    <ClCompile Include=\"InstalledStatus.cpp\" />\r\n    <ClCompile Include=\"MatchResult.cpp\" />\r\n    <ClCompile Include=\"PackageAgreement.cpp\" />\r\n    <ClCompile Include=\"PackageCatalog.cpp\" />\r\n    <ClCompile Include=\"PackageCatalogInfo.cpp\" />\r\n    <ClCompile Include=\"PackageCatalogReference.cpp\" />\r\n    <ClCompile Include=\"CatalogPackageMetadata.cpp\" />\r\n    <ClCompile Include=\"PackageManager.cpp\" />\r\n    <ClCompile Include=\"PackageMatchFilter.cpp\" />\r\n    <ClCompile Include=\"PackageVersionId.cpp\" />\r\n    <ClCompile Include=\"PackageVersionInfo.cpp\" />\r\n    <ClCompile Include=\"pch.cpp\" />\r\n    <ClCompile Include=\"$(GeneratedFilesDir)module.g.cpp\" />\r\n    <ClCompile Include=\"SourceAgreement.cpp\" />\r\n    <ClCompile Include=\"UninstallOptions.cpp\" />\r\n    <ClCompile Include=\"UninstallResult.cpp\" />\r\n    <ClCompile Include=\"PackageManagerSettings.cpp\" />\r\n    <ClCompile Include=\"PackageInstallerInfo.cpp\" />\r\n    <ClCompile Include=\"PackageInstallerInstalledStatus.cpp\" />\r\n    <ClCompile Include=\"AuthenticationArguments.cpp\" />\r\n    <ClCompile Include=\"AuthenticationInfo.cpp\" />\r\n    <ClCompile Include=\"MicrosoftEntraIdAuthenticationInfo.cpp\" />\r\n    <ClCompile Include=\"RepairResult.cpp\" />\r\n    <ClCompile Include=\"RepairOptions.cpp\" />\r\n    <ClCompile Include=\"AddPackageCatalogOptions.cpp\" />\r\n    <ClCompile Include=\"AddPackageCatalogResult.cpp\" />\r\n    <ClCompile Include=\"RemovePackageCatalogResult.cpp\" />\r\n    <ClCompile Include=\"RefreshPackageCatalogResult.cpp\" />\r\n    <ClCompile Include=\"RemovePackageCatalogOptions.cpp\" />\r\n    <ClCompile Include=\"PackageCatalogProgress.cpp\" />\r\n    <ClCompile Include=\"EditPackageCatalogOptions.cpp\" />\r\n    <ClCompile Include=\"EditPackageCatalogResult.cpp\" />\r\n    <ClCompile Include=\"CanUnload.cpp\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"CatalogPackage.h\" />\r\n    <ClInclude Include=\"CatalogPackageMetadata.h\" />\r\n    <ClInclude Include=\"CheckInstalledStatusResult.h\" />\r\n    <ClInclude Include=\"ConnectResult.h\" />\r\n    <ClInclude Include=\"Converters.h\" />\r\n    <ClInclude Include=\"CreateCompositePackageCatalogOptions.h\" />\r\n    <ClInclude Include=\"Documentation.h\" />\r\n    <ClInclude Include=\"DownloadOptions.h\" />\r\n    <ClInclude Include=\"DownloadResult.h\" />\r\n    <ClInclude Include=\"FindPackagesOptions.h\" />\r\n    <ClInclude Include=\"FindPackagesResult.h\" />\r\n    <ClInclude Include=\"Helpers.h\" />\r\n    <ClInclude Include=\"Icon.h\" />\r\n    <ClInclude Include=\"InstallOptions.h\" />\r\n    <ClInclude Include=\"InstallResult.h\" />\r\n    <ClInclude Include=\"InstalledStatus.h\" />\r\n    <ClInclude Include=\"MatchResult.h\" />\r\n    <ClInclude Include=\"PackageAgreement.h\" />\r\n    <ClInclude Include=\"PackageCatalog.h\" />\r\n    <ClInclude Include=\"PackageCatalogInfo.h\" />\r\n    <ClInclude Include=\"PackageCatalogReference.h\" />\r\n    <ClInclude Include=\"PackageInstallerInfo.h\" />\r\n    <ClInclude Include=\"PackageInstallerInstalledStatus.h\" />\r\n    <ClInclude Include=\"PackageManager.h\" />\r\n    <ClInclude Include=\"PackageManagerSettings.h\" />\r\n    <ClInclude Include=\"PackageMatchFilter.h\" />\r\n    <ClInclude Include=\"PackageVersionId.h\" />\r\n    <ClInclude Include=\"PackageVersionInfo.h\" />\r\n    <ClInclude Include=\"pch.h\" />\r\n    <ClInclude Include=\"SourceAgreement.h\" />\r\n    <ClInclude Include=\"UninstallOptions.h\" />\r\n    <ClInclude Include=\"UninstallResult.h\" />\r\n    <ClInclude Include=\"Public\\ComClsids.h\">\r\n      <Filter>Public</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Public\\CoCreatableMicrosoftManagementDeploymentClass.h\">\r\n      <Filter>Public</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"AuthenticationArguments.h\" />\r\n    <ClInclude Include=\"AuthenticationInfo.h\" />\r\n    <ClInclude Include=\"MicrosoftEntraIdAuthenticationInfo.h\" />\r\n    <ClInclude Include=\"RepairResult.h\" />\r\n    <ClInclude Include=\"RepairOptions.h\" />\r\n    <ClInclude Include=\"AddPackageCatalogOptions.h\" />\r\n    <ClInclude Include=\"AddPackageCatalogResult.h\" />\r\n    <ClInclude Include=\"RemovePackageCatalogResult.h\" />\r\n    <ClInclude Include=\"RefreshPackageCatalogResult.h\" />\r\n    <ClInclude Include=\"RemovePackageCatalogOptions.h\" />\r\n    <ClInclude Include=\"PackageCatalogProgress.h\" />\r\n    <ClInclude Include=\"EditPackageCatalogOptions.h\" />\r\n    <ClInclude Include=\"EditPackageCatalogResult.h\" />\r\n    <ClInclude Include=\"Public\\CanUnload.h\">\r\n      <Filter>Public</Filter>\r\n    </ClInclude>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Midl Include=\"PackageManager.idl\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"Microsoft_Management_Deployment.def\" />\r\n    <None Include=\"packages.config\" />\r\n    <None Include=\"PropertySheet.props\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Filter Include=\"Public\">\r\n      <UniqueIdentifier>{9c3907ed-84d9-4485-9b15-04c50717f0ab}</UniqueIdentifier>\r\n    </Filter>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Natvis Include=\"$(MSBuildThisFileDirectory)..\\..\\natvis\\wil.natvis\" />\r\n    <Natvis Include=\"$(MSBuildThisFileDirectory)..\\..\\natvis\\wil.natstepfilter\" />\r\n  </ItemGroup>\r\n</Project>"
  },
  {
    "path": "src/Microsoft.Management.Deployment/MicrosoftEntraIdAuthenticationInfo.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"MicrosoftEntraIdAuthenticationInfo.h\"\n#include \"MicrosoftEntraIdAuthenticationInfo.g.cpp\"\n#include <wil\\cppwinrt_wrl.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    void MicrosoftEntraIdAuthenticationInfo::Initialize(::AppInstaller::Authentication::MicrosoftEntraIdAuthenticationInfo authInfo)\n    {\n        m_authInfo = std::move(authInfo);\n    }\n    hstring MicrosoftEntraIdAuthenticationInfo::Resource()\n    {\n        return winrt::to_hstring(m_authInfo.Resource);\n    }\n    hstring MicrosoftEntraIdAuthenticationInfo::Scope()\n    {\n        return winrt::to_hstring(m_authInfo.Scope);\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/MicrosoftEntraIdAuthenticationInfo.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"MicrosoftEntraIdAuthenticationInfo.g.h\"\n#include <winget/Authentication.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    struct MicrosoftEntraIdAuthenticationInfo : MicrosoftEntraIdAuthenticationInfoT<MicrosoftEntraIdAuthenticationInfo>\n    {\n        MicrosoftEntraIdAuthenticationInfo() = default;\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void Initialize(::AppInstaller::Authentication::MicrosoftEntraIdAuthenticationInfo authInfo);\n#endif\n\n        hstring Resource();\n        hstring Scope();\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        ::AppInstaller::Authentication::MicrosoftEntraIdAuthenticationInfo m_authInfo;\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/Microsoft_Management_Deployment.def",
    "content": "﻿EXPORTS\r\nDllCanUnloadNow = WINRT_CanUnloadNow                    PRIVATE\r\nDllGetActivationFactory = WINRT_GetActivationFactory    PRIVATE\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PackageAgreement.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"PackageAgreement.h\"\n#include \"PackageAgreement.g.cpp\"\n#include <wil\\cppwinrt_wrl.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    void PackageAgreement::Initialize(::AppInstaller::Manifest::Agreement packageAgreement)\n    {\n        m_packageAgreement = std::move(packageAgreement);\n    }\n    hstring PackageAgreement::Label()\n    {\n        return winrt::to_hstring(m_packageAgreement.Label);\n    }\n    hstring PackageAgreement::Text()\n    {\n        return winrt::to_hstring(m_packageAgreement.AgreementText);\n    }\n    hstring PackageAgreement::Url()\n    {\n        return winrt::to_hstring(m_packageAgreement.AgreementUrl);\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PackageAgreement.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"PackageAgreement.g.h\"\n#include <winget/Manifest.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    struct PackageAgreement : PackageAgreementT<PackageAgreement>\n    {\n        PackageAgreement() = default;\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void Initialize(::AppInstaller::Manifest::Agreement packageAgreement);\n#endif\n\n        hstring Label();\n        hstring Text();\n        hstring Url();\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        ::AppInstaller::Manifest::Agreement m_packageAgreement{};\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PackageCatalog.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include <mutex>\r\n#include <winget/RepositorySource.h>\r\n#include \"Workflows/WorkflowBase.h\"\r\n#include \"Converters.h\"\r\n#include \"PackageCatalog.h\"\r\n#include \"PackageCatalog.g.cpp\"\r\n#include \"PackageCatalogInfo.h\"\r\n#include \"FindPackagesResult.h\"\r\n#include \"MatchResult.h\"\r\n#include \"CatalogPackage.h\"\r\n#include \"Commands/RootCommand.h\"\r\n#include \"ExecutionContext.h\"\r\n#pragma warning( push )\r\n#pragma warning ( disable : 4467 6388)\r\n// 6388 Allow CreateInstance.\r\n#include <wil\\cppwinrt_wrl.h>\r\n// 4467 Allow use of uuid attribute for com object creation.\r\n#include \"PackageMatchFilter.h\"\r\n#pragma warning( pop )\r\n#include \"Microsoft/PredefinedInstalledSourceFactory.h\"\r\n#include <winget/GroupPolicy.h>\r\n#include <AppInstallerErrors.h>\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    void PackageCatalog::Initialize(\r\n        winrt::Microsoft::Management::Deployment::PackageCatalogInfo info,\r\n        ::AppInstaller::Repository::Source source,\r\n        bool isComposite)\r\n    {\r\n        m_info = info;\r\n        m_source = std::move(source);\r\n        m_isComposite = isComposite;\r\n    }\r\n    bool PackageCatalog::IsComposite()\r\n    {\r\n        // Can't use m_source->IsComposite for this because all remote sources are turned into composite sources \r\n        // behind the scenes when being opened in PackageCatalogReference.cpp so that CatalogPackage.IsInstalled works.\r\n        return m_isComposite;\r\n    }\r\n    winrt::Microsoft::Management::Deployment::PackageCatalogInfo PackageCatalog::Info()\r\n    {\r\n        return m_info;\r\n    }\r\n    winrt::Windows::Foundation::IAsyncOperation<winrt::Microsoft::Management::Deployment::FindPackagesResult> PackageCatalog::FindPackagesAsync(winrt::Microsoft::Management::Deployment::FindPackagesOptions options)\r\n    {\r\n        auto strong_this = get_strong();\r\n        co_await resume_background();\r\n        co_return FindPackages(options);\r\n    }\r\n\r\n    HRESULT PopulateSearchRequestFromVector(\r\n        ::AppInstaller::Repository::SearchRequest* searchRequest,\r\n        Windows::Foundation::Collections::IVector<Microsoft::Management::Deployment::PackageMatchFilter> vector,\r\n        bool isSelector)\r\n    {\r\n        // Populates either the Filters vector of a searchRequest (if isSelector is false),\r\n        // or the Inclusions and Query (if true)\r\n        for (uint32_t i = 0; i < vector.Size(); ++i)\r\n        {\r\n            Microsoft::Management::Deployment::PackageMatchFilter filter = vector.GetAt(i);\r\n\r\n            if (filter.Value().size() == 0)\r\n            {\r\n                // If the caller did not add a value it can't actually be used to filter or include anything so just ignore it.\r\n                continue;\r\n            }\r\n            ::AppInstaller::Repository::MatchType packageFieldMatchOption = GetRepositoryMatchType(filter.Option());\r\n            ::AppInstaller::Repository::PackageMatchField matchField = GetRepositoryMatchField(filter.Field());\r\n\r\n            if (isSelector)\r\n            {\r\n                if (filter.Field() == Microsoft::Management::Deployment::PackageMatchField::CatalogDefault)\r\n                {\r\n                    if (searchRequest->Query.has_value())\r\n                    {\r\n                        // CatalogDefault match field can't be used twice.\r\n                        return E_INVALIDARG;\r\n                    }\r\n                    searchRequest->Query = ::AppInstaller::Repository::RequestMatch(packageFieldMatchOption, winrt::to_string(filter.Value()));\r\n                }\r\n                else\r\n                {\r\n                    auto matchFilter = ::AppInstaller::Repository::PackageMatchFilter(matchField, packageFieldMatchOption, winrt::to_string(filter.Value()));\r\n                    searchRequest->Inclusions.emplace_back(matchFilter);\r\n                }\r\n            }\r\n            else\r\n            {\r\n                if (filter.Field() == Microsoft::Management::Deployment::PackageMatchField::CatalogDefault)\r\n                {\r\n                    // CatalogDefault match fields can't be used in the Filters.\r\n                    return E_INVALIDARG;\r\n                }\r\n                auto matchFilter = ::AppInstaller::Repository::PackageMatchFilter(matchField, packageFieldMatchOption, winrt::to_string(filter.Value()));\r\n                searchRequest->Filters.emplace_back(matchFilter);\r\n            }\r\n        }\r\n        return S_OK;\r\n    }\r\n\r\n    HRESULT PopulateSearchRequest(\r\n        ::AppInstaller::Repository::SearchRequest* searchRequest,\r\n        winrt::Microsoft::Management::Deployment::FindPackagesOptions const& options)\r\n    {\r\n        RETURN_IF_FAILED(PopulateSearchRequestFromVector(searchRequest, options.Filters(), false));\r\n        RETURN_IF_FAILED(PopulateSearchRequestFromVector(searchRequest, options.Selectors(), true));\r\n        return S_OK;\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::FindPackagesResult GetFindPackagesResult(HRESULT hr, bool isTruncated, Windows::Foundation::Collections::IVector<Microsoft::Management::Deployment::MatchResult> matches)\r\n    {\r\n        auto findPackagesResult = winrt::make_self<wil::details::module_count_wrapper<\r\n            winrt::Microsoft::Management::Deployment::implementation::FindPackagesResult>>();\r\n        // TODO: Add search timeout and error code.\r\n        winrt::Microsoft::Management::Deployment::FindPackagesResultStatus status = FindPackagesResultStatus(hr);\r\n        findPackagesResult->Initialize(status, isTruncated, matches, hr);\r\n        return *findPackagesResult;\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::FindPackagesResult PackageCatalog::FindPackages(winrt::Microsoft::Management::Deployment::FindPackagesOptions const& options)\r\n    {\r\n        bool isTruncated = false;\r\n        Windows::Foundation::Collections::IVector<Microsoft::Management::Deployment::MatchResult> matches{ winrt::single_threaded_vector<Microsoft::Management::Deployment::MatchResult>() };\r\n        ::AppInstaller::Repository::SearchRequest searchRequest;\r\n\r\n        HRESULT hr = S_OK;\r\n        try\r\n        {\r\n            // No need to check for caller capability again since packageQuery was required in order to get the PackageCatalog object through Connect\r\n\r\n            if (FAILED(hr = PopulateSearchRequest(&searchRequest, options)))\r\n            {\r\n                return GetFindPackagesResult(hr, isTruncated, matches);\r\n            }\r\n        \r\n            searchRequest.MaximumResults = options.ResultLimit();\r\n            auto searchResult = m_source.Search(searchRequest);\r\n\r\n            // Handle failures by just rethrowing the first one for now.\r\n            // TODO: Look into updating the COM interface to enable the single source\r\n            //       failures to flow out.\r\n            if (!searchResult.Failures.empty())\r\n            {\r\n                std::rethrow_exception(searchResult.Failures[0].Exception);\r\n            }\r\n\r\n            // Build the result object from the searchResult\r\n            for (size_t i = 0; i < searchResult.Matches.size(); ++i)\r\n            {\r\n                auto match = searchResult.Matches[i];\r\n                auto catalogPackage = winrt::make_self<wil::details::module_count_wrapper<\r\n                    winrt::Microsoft::Management::Deployment::implementation::CatalogPackage>>();\r\n                catalogPackage->Initialize(m_source, match.Package);\r\n\r\n                auto packageMatchFilter = winrt::make_self<wil::details::module_count_wrapper<\r\n                    winrt::Microsoft::Management::Deployment::implementation::PackageMatchFilter>>();\r\n                packageMatchFilter->Initialize(match.MatchCriteria);\r\n\r\n                auto matchResult = winrt::make_self<wil::details::module_count_wrapper<\r\n                    winrt::Microsoft::Management::Deployment::implementation::MatchResult>>();\r\n                matchResult->Initialize(*catalogPackage, *packageMatchFilter);\r\n\r\n                matches.Append(*matchResult);\r\n            }\r\n            isTruncated = searchResult.Truncated;\r\n        }\r\n        WINGET_CATCH_STORE(hr, APPINSTALLER_CLI_ERROR_COMMAND_FAILED);\r\n\r\n        return GetFindPackagesResult(hr, isTruncated, matches);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PackageCatalog.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"PackageCatalog.g.h\"\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    struct PackageCatalog : PackageCatalogT<PackageCatalog>\n    {\n        PackageCatalog() = default;\n        \n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void Initialize(\n            winrt::Microsoft::Management::Deployment::PackageCatalogInfo info, \n            ::AppInstaller::Repository::Source source,\n            bool isComposite);\n#endif\n\n        bool IsComposite();\n        winrt::Microsoft::Management::Deployment::PackageCatalogInfo Info();\n        winrt::Windows::Foundation::IAsyncOperation<winrt::Microsoft::Management::Deployment::FindPackagesResult> FindPackagesAsync(winrt::Microsoft::Management::Deployment::FindPackagesOptions options);\n        winrt::Microsoft::Management::Deployment::FindPackagesResult FindPackages(winrt::Microsoft::Management::Deployment::FindPackagesOptions const& options);\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        winrt::Microsoft::Management::Deployment::PackageCatalogInfo m_info{ nullptr };\n        ::AppInstaller::Repository::Source m_source;\n        bool m_isComposite = false;\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PackageCatalogInfo.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"PackageCatalogInfo.h\"\n#include \"PackageCatalogInfo.g.cpp\"\n#include <wil\\cppwinrt_wrl.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    void PackageCatalogInfo::Initialize(const ::AppInstaller::Repository::SourceDetails& sourceDetails)\n    {\n        m_sourceDetails = sourceDetails;\n    }\n    ::AppInstaller::Repository::SourceDetails& PackageCatalogInfo::GetSourceDetails()\n    {\n        return m_sourceDetails;\n    }\n    hstring PackageCatalogInfo::Id()\n    {\n        return winrt::to_hstring(m_sourceDetails.Identifier);\n    }\n    hstring PackageCatalogInfo::Name()\n    {\n        return winrt::to_hstring(m_sourceDetails.Name);\n    }\n    hstring PackageCatalogInfo::Type()\n    {\n        return winrt::to_hstring(m_sourceDetails.Type);\n    }\n    hstring PackageCatalogInfo::Argument()\n    {\n        return winrt::to_hstring(m_sourceDetails.Arg);\n    }\n    winrt::Windows::Foundation::DateTime PackageCatalogInfo::LastUpdateTime()\n    {\n        return winrt::clock::from_time_t(std::chrono::system_clock::to_time_t(m_sourceDetails.LastUpdateTime));\n    }\n    winrt::Microsoft::Management::Deployment::PackageCatalogOrigin PackageCatalogInfo::Origin()\n    {\n        switch (m_sourceDetails.Origin)\n        {\n        case ::AppInstaller::Repository::SourceOrigin::Default :\n        case ::AppInstaller::Repository::SourceOrigin::Predefined:\n            return PackageCatalogOrigin::Predefined;\n        case ::AppInstaller::Repository::SourceOrigin::User:\n        case ::AppInstaller::Repository::SourceOrigin::GroupPolicy:\n        default:\n            return PackageCatalogOrigin::User;\n        }\n    }\n    winrt::Microsoft::Management::Deployment::PackageCatalogTrustLevel PackageCatalogInfo::TrustLevel()\n    {\r\n        if (WI_IsFlagSet(m_sourceDetails.TrustLevel, ::AppInstaller::Repository::SourceTrustLevel::Trusted))\r\n        {\n            return PackageCatalogTrustLevel::Trusted;\r\n        }\r\n\n        return PackageCatalogTrustLevel::None;\n    }\n    bool PackageCatalogInfo::Explicit()\n    {\n        return m_sourceDetails.Explicit;\n    }\r\n\r\n    int32_t PackageCatalogInfo::Priority()\r\n    {\n        return m_sourceDetails.Priority;\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PackageCatalogInfo.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"PackageCatalogInfo.g.h\"\n#include <winget/RepositorySource.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    struct PackageCatalogInfo : PackageCatalogInfoT<PackageCatalogInfo>\n    {\n        PackageCatalogInfo() = default;\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void Initialize(const ::AppInstaller::Repository::SourceDetails& sourceDetails);\n        ::AppInstaller::Repository::SourceDetails& GetSourceDetails();\n#endif\n\n        hstring Id();\n        hstring Name();\n        hstring Type();\n        hstring Argument();\n        winrt::Windows::Foundation::DateTime LastUpdateTime();\n        winrt::Microsoft::Management::Deployment::PackageCatalogOrigin Origin();\n        winrt::Microsoft::Management::Deployment::PackageCatalogTrustLevel TrustLevel();\n        bool Explicit();\n        int32_t Priority();\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        ::AppInstaller::Repository::SourceDetails m_sourceDetails;\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PackageCatalogProgress.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"PackageCatalogProgress.h\"\r\n#include \"AppInstallerStrings.h\"\r\n#include \"Microsoft/PredefinedInstalledSourceFactory.h\"\r\n\r\nusing namespace AppInstaller;\r\nusing namespace AppInstaller::Repository;\r\n\r\nnamespace winrt::Microsoft::Management::Deployment\r\n{\r\n    namespace ProgressSinkFactory\r\n    {\r\n        std::shared_ptr<AppInstaller::IProgressSink> CreatePackageCatalogProgressSink(std::string sourceType, std::function<void(double)> progressReporter, bool removeOperation)\r\n        {\r\n            if (sourceType.empty()\r\n                || Utility::CaseInsensitiveEquals( Repository::Microsoft::PredefinedInstalledSourceFactory::Type(), sourceType))\r\n            {\r\n                std::vector<std::pair<AppInstaller::ProgressType, double>> progressWeights;\r\n\r\n                // There is no download operation for remove operation, so use only percentage based progress to account for uninstall.\r\n                if (removeOperation)\r\n                {\r\n                    // it is percentage based progress.\r\n                    progressWeights.push_back(std::make_pair(AppInstaller::ProgressType::Percent, 1.0));\r\n                }\r\n                else\r\n                {\r\n                    // Add/Update operation has two progress types:\r\n                    // 1. Bytes for downloading index and\r\n                    // 2. Percent for index installation.\r\n                    progressWeights.push_back(std::make_pair(AppInstaller::ProgressType::Bytes, 0.7));\r\n                    progressWeights.push_back(std::make_pair(AppInstaller::ProgressType::Percent, 0.3));\r\n                }\r\n\r\n                return std::make_shared<PreIndexedPackageCatalogProgressSink>(progressWeights, progressReporter);\r\n            }\r\n            else\r\n            {\r\n                return std::make_shared<CompletionOnlyProgressSink>(progressReporter);\r\n            }\r\n        }\r\n    }\r\n\r\n    CompletionOnlyProgressSink::CompletionOnlyProgressSink(std::function<void(double)> progressReporter) :\r\n        m_progressReporter(progressReporter)\r\n    {\r\n        if (!m_progressReporter)\r\n        {\r\n            THROW_HR(E_INVALIDARG);\r\n        }\r\n    }\r\n\r\n    void CompletionOnlyProgressSink::OnProgress(uint64_t /*current*/, uint64_t /*maximum*/, AppInstaller::ProgressType /*type*/)\r\n    {\r\n    }\r\n\r\n    void CompletionOnlyProgressSink::SetProgressMessage(std::string_view /*message*/)\r\n    {\r\n    }\r\n\r\n    void CompletionOnlyProgressSink::BeginProgress()\r\n    {\r\n        m_progressReporter(0);\r\n    }\r\n\r\n    void CompletionOnlyProgressSink::EndProgress(bool /*hideProgressWhenDone*/)\r\n    {\r\n        m_progressReporter(100);\r\n    }\r\n\r\n    PreIndexedPackageCatalogProgressSink::PreIndexedPackageCatalogProgressSink(std::vector<std::pair<AppInstaller::ProgressType, double>> progressWeights, std::function<void(double)> progressReporter) :\r\n        m_progressWeights(progressWeights), m_progressReporter(progressReporter)\r\n    {\r\n        if (!m_progressReporter)\r\n        {\r\n            THROW_HR(E_INVALIDARG);\r\n        }\r\n\r\n        // If no weights are provided, default to percent.\r\n        if (m_progressWeights.empty())\r\n        {\r\n            m_progressWeights.push_back(std::make_pair(AppInstaller::ProgressType::Percent, 1.0));\r\n        }\r\n\r\n        // Calculate the total weight.\r\n        double totalWeight = 0;\r\n        for (const auto& weight : m_progressWeights)\r\n        {\r\n            if (weight.first != AppInstaller::ProgressType::None)\r\n            {\r\n                totalWeight += weight.second;\r\n            }\r\n        }\r\n\r\n        // If the total weight is greater than 1, throw an exception.\r\n        if (totalWeight != 1.0)\r\n        {\r\n            THROW_HR(E_INVALIDARG);\r\n        }\r\n    }\r\n\r\n    void PreIndexedPackageCatalogProgressSink::OnProgress(uint64_t current, uint64_t maximum, AppInstaller::ProgressType type)\r\n    {\r\n        if (maximum == 0 || type == AppInstaller::ProgressType::None)\r\n        {\r\n            return;\r\n        }\r\n\r\n        double progress = static_cast<double>(current) / maximum;\r\n        m_progressValues[type] = progress;\r\n\r\n        double totalProgress = 0.0;\r\n        double totalWeight = 0.0;\r\n\r\n        // Calculate the total progress.\r\n        for (const auto& [progressType, weight] : m_progressWeights)\r\n        {\r\n            double progressValue = m_progressValues[progressType];\r\n\r\n            // [NOTE:] Sequential execution assumption & Handling incomplete progress reports :\r\n            // This progress calculation assumes that each operation is executed sequentially, meaning the download must be complete before\r\n            // the installation begins.If the download fails, the installation will not proceed.However, there may be cases where the previous\r\n            // operation completes successfully, but its onprogress callback does not report 100% completion(e.g., the last progress report for\r\n            // the download was at 90%, but the download is complete, and the installation has started).This can result in the total progress not\r\n            // reaching 100% after the last operation completes due to the gap in the previous operation's progress report.To handle this, consider\r\n            // the progress for the last operation as complete by assigning its full weight while computing progress for the following operation.\r\n            // For example, while computing progress for the installation, consider the download operation complete even if it did not report progress\r\n            // exactly at 100%.\r\n            if (progressValue != 0)\r\n            {\r\n                totalProgress = totalWeight;\r\n            }\r\n\r\n            // Adjust the total progress value based on the weight.\r\n            totalWeight += weight;\r\n            totalProgress += progressValue * weight;\r\n        }\r\n\r\n        m_progressReporter(totalProgress * 100);\r\n    }\r\n\r\n    void PreIndexedPackageCatalogProgressSink::SetProgressMessage(std::string_view /*message*/)\r\n    {\r\n    }\r\n\r\n    void PreIndexedPackageCatalogProgressSink::BeginProgress()\r\n    {\r\n        m_progressReporter(0);\r\n    }\r\n\r\n    void PreIndexedPackageCatalogProgressSink::EndProgress(bool /*hideProgressWhenDone*/)\r\n    {\r\n        m_progressReporter(100);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PackageCatalogProgress.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"AppInstallerProgress.h\"\r\n#include <unordered_map>\r\n#include <functional>\r\n\r\nnamespace winrt::Microsoft::Management::Deployment\r\n{\r\n    namespace ProgressSinkFactory\r\n    {\r\n        /// <summary>\r\n        /// Creates a progress sink for package catalog operations based on sourceType.\r\n        /// </summary>\r\n        /// <param name=\"sourceType\">sourceType.</param>\r\n        /// <param name=\"progressReporter\">callback function that reports progress to caller.</param>\r\n        /// <param name=\"removeOperation\"> Default value is false. Identifies if the operation is a PackageCatalog removal and requests the ProgressSink.</param>\r\n        /// <returns>IProgressSink.</returns>\r\n        std::shared_ptr<AppInstaller::IProgressSink> CreatePackageCatalogProgressSink(std::string sourceType, std::function<void(double)> progressReporter, bool removeOperation = false);\r\n    }\r\n\r\n    /// <summary>\r\n    /// Progress sink that only reports start and completion to caller.\r\n    /// </summary>\r\n    struct CompletionOnlyProgressSink : AppInstaller::IProgressSink\r\n    {\r\n        /// <summary>\r\n        /// Constructor.\r\n        /// </summary>\r\n        /// <param name=\"progressReporter\">callback that reports progress to caller.</param>\r\n        CompletionOnlyProgressSink(std::function<void(double)> progressReporter);\r\n\r\n        void OnProgress(uint64_t current, uint64_t maximum, AppInstaller::ProgressType type) override;\r\n        void SetProgressMessage(std::string_view message) override;\r\n        void BeginProgress() override;\r\n        void EndProgress(bool hideProgressWhenDone) override;\r\n\r\n    private:\r\n        std::function<void(double)> m_progressReporter;\r\n    };\r\n\r\n    /// <summary>\r\n    /// Progress sink for pre-indexed package catalog operations.\r\n    /// capable of reporting progress for download and installation of index.\r\n    /// Add/update operation has two progress types: Bytes for downloading index and Percent for index installation.\r\n    /// Remove operation has only percentage based progress.\r\n    /// </summary>\r\n    struct PreIndexedPackageCatalogProgressSink : AppInstaller::IProgressSink\r\n    {\r\n        /// <summary>\r\n        /// Constructor.\r\n        /// </summary>\r\n        /// <param name=\"progressWeights\">ProgressType weight map.</param>\r\n        /// <param name=\"progressReporter\">Callback function that reports progress to caller.</param>\r\n        PreIndexedPackageCatalogProgressSink(std::vector<std::pair<AppInstaller::ProgressType, double>> progressWeights, std::function<void(double)> progressReporter);\r\n\r\n        /// <summary>\r\n        /// Reports combined progress to caller when configured for multiple progress types.\r\n        /// </summary>\r\n        /// <param name=\"current\">The current progress value.</param>\r\n        /// <param name=\"maximum\">The maximum progress value.</param>\r\n        /// <param name=\"type\">ProgressType for which progress is applicable.</param>\r\n        void OnProgress(uint64_t current, uint64_t maximum, AppInstaller::ProgressType type) override;\r\n        void SetProgressMessage(std::string_view message) override;\r\n        void BeginProgress() override;\r\n        void EndProgress(bool hideProgressWhenDone) override;\r\n\r\n    private:\r\n        std::vector<std::pair<AppInstaller::ProgressType, double>> m_progressWeights;\r\n        std::function<void(double)> m_progressReporter;\r\n        std::unordered_map<AppInstaller::ProgressType, double> m_progressValues;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PackageCatalogReference.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include <winget/RepositorySource.h>\r\n#include \"PackageCatalogReference.h\"\r\n#include \"PackageCatalogReference.g.cpp\"\r\n#include \"PackageCatalogInfo.h\"\r\n#include \"PackageCatalog.h\"\r\n#include \"SourceAgreement.h\"\r\n#include \"ConnectResult.h\"\r\n#include \"AuthenticationInfo.h\"\r\n#include \"Workflows/WorkflowBase.h\"\r\n#include \"Converters.h\"\r\n#include \"Microsoft/PredefinedInstalledSourceFactory.h\"\r\n#include <wil\\cppwinrt_wrl.h>\r\n#include <winget/GroupPolicy.h>\r\n#include <AppInstallerErrors.h>\r\n#include <AppInstallerStrings.h>\r\n#include <winget/UserSettings.h>\r\n#include <Helpers.h>\r\n#include <ExecutionContext.h>\r\n#include <RefreshPackageCatalogResult.h>\r\n#include <PackageCatalogProgress.h>\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    namespace\r\n    {\r\n        winrt::Microsoft::Management::Deployment::RefreshPackageCatalogResult GetRefreshPackageCatalogResult(winrt::hresult terminationStatus)\r\n        {\r\n            winrt::Microsoft::Management::Deployment::RefreshPackageCatalogStatus status = GetPackageCatalogOperationStatus<RefreshPackageCatalogStatus>(terminationStatus);\r\n            auto updateResult = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::RefreshPackageCatalogResult>>();\r\n            updateResult->Initialize(status, terminationStatus);\r\n            return *updateResult;\r\n        }\r\n    }\r\n\r\n    void PackageCatalogReference::Initialize(winrt::Microsoft::Management::Deployment::PackageCatalogInfo packageCatalogInfo, ::AppInstaller::Repository::Source sourceReference)\r\n    {\r\n        m_info = packageCatalogInfo;\r\n        m_sourceReference = std::move(sourceReference);\r\n        m_packageCatalogBackgroundUpdateInterval = ::AppInstaller::Settings::User().Get<::AppInstaller::Settings::Setting::AutoUpdateTimeInMinutes>();\r\n\r\n        if (IsBackgroundProcessForPolicy())\r\n        {\r\n            // Delay the default update interval for these background processes\r\n            static constexpr winrt::Windows::Foundation::TimeSpan s_PackageCatalogUpdateIntervalDelay_Base = 168h; //1 week\r\n\r\n            // Add a bit of randomness to the default interval time\r\n            std::default_random_engine randomEngine(std::random_device{}());\r\n            std::uniform_int_distribution<long long> distribution(0, 604800);\r\n\r\n            m_packageCatalogBackgroundUpdateInterval = s_PackageCatalogUpdateIntervalDelay_Base + std::chrono::seconds(distribution(randomEngine));\r\n\r\n            // Prevent any update / data processing by default for these background processes for now\r\n            m_installedPackageInformationOnly = m_sourceReference.IsWellKnownSource(AppInstaller::Repository::WellKnownSource::WinGet) ||\r\n                                                m_sourceReference.IsWellKnownSource(AppInstaller::Repository::WellKnownSource::WinGetFont);\r\n        }\r\n    }\r\n\r\n    void PackageCatalogReference::Initialize(winrt::Microsoft::Management::Deployment::CreateCompositePackageCatalogOptions options)\r\n    {\r\n        m_compositePackageCatalogOptions = options;\r\n    }\r\n\r\n    bool PackageCatalogReference::IsComposite()\r\n    {\r\n        return (m_compositePackageCatalogOptions != nullptr);\r\n    }\r\n    winrt::Microsoft::Management::Deployment::PackageCatalogInfo PackageCatalogReference::Info()\r\n    {\r\n        return m_info;\r\n    }\r\n    winrt::Windows::Foundation::IAsyncOperation<winrt::Microsoft::Management::Deployment::ConnectResult> PackageCatalogReference::ConnectAsync()\r\n    {\r\n        co_return Connect();\r\n    }\r\n    winrt::Microsoft::Management::Deployment::ConnectResult GetConnectCatalogErrorResult(hresult hr)\r\n    {\r\n        auto connectResult = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::ConnectResult>>();\r\n        connectResult->Initialize(winrt::Microsoft::Management::Deployment::ConnectResultStatus::CatalogError, nullptr, hr);\r\n        return *connectResult;\r\n    }\r\n    winrt::Microsoft::Management::Deployment::ConnectResult GetConnectSourceAgreementsNotAcceptedErrorResult()\r\n    {\r\n        auto connectResult = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::ConnectResult>>();\r\n        connectResult->Initialize(winrt::Microsoft::Management::Deployment::ConnectResultStatus::SourceAgreementsNotAccepted, nullptr, APPINSTALLER_CLI_ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED);\r\n        return *connectResult;\r\n    }\r\n    winrt::Microsoft::Management::Deployment::ConnectResult PackageCatalogReference::Connect() try\r\n    {\r\n        HRESULT hr = EnsureComCallerHasCapability(Capability::PackageQuery);\r\n        if (FAILED(hr))\r\n        {\r\n            // TODO: When more error codes are added, this should go back as something other than CatalogError.\r\n            return GetConnectCatalogErrorResult(hr);\r\n        }\r\n\r\n        std::string callerName = GetCallerName();\r\n\r\n        ::AppInstaller::ProgressCallback progress;\r\n        ::AppInstaller::Repository::Source source;\r\n        if (m_compositePackageCatalogOptions)\r\n        {\r\n            std::vector<::AppInstaller::Repository::Source> remoteSources;\r\n\r\n            for (uint32_t i = 0; i < m_compositePackageCatalogOptions.Catalogs().Size(); ++i)\r\n            {\r\n                auto catalog = m_compositePackageCatalogOptions.Catalogs().GetAt(i);\r\n                if (!catalog.AcceptSourceAgreements() && catalog.SourceAgreements().Size() != 0)\r\n                {\r\n                    return GetConnectSourceAgreementsNotAcceptedErrorResult();\r\n                }\r\n\r\n                winrt::Microsoft::Management::Deployment::implementation::PackageCatalogReference* catalogImpl = get_self<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogReference>(catalog);\r\n                auto copy = catalogImpl->m_sourceReference;\r\n                copy.SetCaller(callerName);\r\n                copy.SetBackgroundUpdateInterval(catalog.PackageCatalogBackgroundUpdateInterval());\r\n                copy.InstalledPackageInformationOnly(catalog.InstalledPackageInformationOnly());\r\n                if (catalog.AuthenticationInfo().AuthenticationType() != winrt::Microsoft::Management::Deployment::AuthenticationType::None)\r\n                {\r\n                    copy.SetAuthenticationArguments(GetAuthenticationArguments(catalog.AuthenticationArguments()));\r\n                }\r\n                copy.Open(progress);\r\n                remoteSources.emplace_back(std::move(copy));\r\n            }\r\n\r\n            // Create the aggregated source.\r\n            source = ::AppInstaller::Repository::Source{ remoteSources };\r\n\r\n            // Create composite with installed source if needed.\r\n            ::AppInstaller::Repository::CompositeSearchBehavior searchBehavior = GetRepositoryCompositeSearchBehavior(m_compositePackageCatalogOptions.CompositeSearchBehavior());\r\n\r\n            // Check if search behavior indicates that the caller does not want to do local correlation.\r\n            if (m_compositePackageCatalogOptions.CompositeSearchBehavior() != Microsoft::Management::Deployment::CompositeSearchBehavior::RemotePackagesFromRemoteCatalogs)\r\n            {\r\n                ::AppInstaller::Repository::Source installedSource;\r\n                auto manifestInstalledScope = GetManifestScope(m_compositePackageCatalogOptions.InstalledScope()).first;\r\n                if (manifestInstalledScope == ::AppInstaller::Manifest::ScopeEnum::User)\r\n                {\r\n                    installedSource = ::AppInstaller::Repository::Source{ ::AppInstaller::Repository::PredefinedSource::InstalledUser };\r\n                }\r\n                else if (manifestInstalledScope == ::AppInstaller::Manifest::ScopeEnum::Machine)\r\n                {\r\n                    installedSource = ::AppInstaller::Repository::Source{ ::AppInstaller::Repository::PredefinedSource::InstalledMachine };\r\n                }\r\n                else\r\n                {\r\n                    installedSource = ::AppInstaller::Repository::Source{ ::AppInstaller::Repository::PredefinedSource::Installed };\r\n                }\r\n\r\n                installedSource.Open(progress);\r\n                source = ::AppInstaller::Repository::Source{ installedSource, source, searchBehavior };\r\n            }\r\n        }\r\n        else\r\n        {\r\n            if (!AcceptSourceAgreements() && SourceAgreements().Size() != 0)\r\n            {\r\n                return GetConnectSourceAgreementsNotAcceptedErrorResult();\r\n            }\r\n\r\n            source = m_sourceReference;\r\n            source.SetCaller(callerName);\r\n            source.SetBackgroundUpdateInterval(PackageCatalogBackgroundUpdateInterval());\r\n            source.InstalledPackageInformationOnly(m_installedPackageInformationOnly);\r\n            if (AuthenticationInfo().AuthenticationType() != winrt::Microsoft::Management::Deployment::AuthenticationType::None)\r\n            {\r\n                source.SetAuthenticationArguments(GetAuthenticationArguments(m_authenticationArguments));\r\n            }\r\n            source.Open(progress);\r\n        }\r\n\r\n        if (!source)\r\n        {\r\n            // We call `Open` on each individual source above, meaning that they should throw any error that occurs.\r\n            // If the source is still not open at this point it is a bug.\r\n            return GetConnectCatalogErrorResult(E_UNEXPECTED);\r\n        }\r\n\r\n        // Have to make another package catalog info because source->GetDetails has more fields than m_info does.\r\n        // Specifically, Rest sources do not have the Ids filled in m_info since they only get the id from the rest server after being Opened.\r\n        auto packageCatalogInfo = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogInfo>>();\r\n        packageCatalogInfo->Initialize(source.GetDetails());\r\n        auto connectResult = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::ConnectResult>>();\r\n        auto packageCatalog = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalog>>();\r\n        packageCatalog->Initialize(*packageCatalogInfo, source, (m_compositePackageCatalogOptions != nullptr));\r\n        connectResult->Initialize(winrt::Microsoft::Management::Deployment::ConnectResultStatus::Ok, *packageCatalog, S_OK);\r\n        return *connectResult;\r\n    }\r\n    catch (...)\r\n    {\r\n        return GetConnectCatalogErrorResult(AppInstaller::CLI::Workflow::HandleException(nullptr, std::current_exception()));\r\n    }\r\n\r\n    winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Management::Deployment::SourceAgreement> PackageCatalogReference::SourceAgreements()\r\n    {\r\n        std::call_once(m_sourceAgreementsOnceFlag,\r\n            [&]()\r\n            {\r\n                if (!IsComposite())\r\n                {\r\n                    for (auto const& agreement : m_sourceReference.GetInformation().SourceAgreements)\r\n                    {\r\n                        auto sourceAgreement = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::SourceAgreement>>();\r\n                        sourceAgreement->Initialize(agreement);\r\n                        m_sourceAgreements.Append(*sourceAgreement);\r\n                    }\r\n                }\r\n            });\r\n        return m_sourceAgreements.GetView();\r\n    }\r\n    hstring PackageCatalogReference::AdditionalPackageCatalogArguments()\r\n    {\r\n        if (!IsComposite())\r\n        {\r\n            if (m_additionalPackageCatalogArguments.has_value())\r\n            {\r\n                return winrt::to_hstring(m_additionalPackageCatalogArguments.value());\r\n            }\r\n        }\r\n\r\n        return {};\r\n    }\r\n    void PackageCatalogReference::AdditionalPackageCatalogArguments(hstring const& value)\r\n    {\r\n        if (IsComposite())\r\n        {\r\n            // Can't set AdditionalPackageCatalogArguments on a composite. Callers should set it on each non-composite PackageCatalogReference in the composite.\r\n            throw winrt::hresult_illegal_state_change();\r\n        }\r\n        else\r\n        {\r\n            m_additionalPackageCatalogArguments = ::AppInstaller::Utility::ConvertToUTF8(value);\r\n            m_sourceReference.SetCustomHeader(m_additionalPackageCatalogArguments);\r\n        }\r\n    }\r\n    void PackageCatalogReference::AcceptSourceAgreements(bool value)\r\n    {\r\n        if (IsComposite())\r\n        {\r\n            // Can't set AcceptSourceAgreements on a composite. Callers should set it on each non-composite PackageCatalogReference in the composite.\r\n            throw winrt::hresult_illegal_state_change();\r\n        }\r\n        m_acceptSourceAgreements = value;\r\n    }\r\n    bool PackageCatalogReference::AcceptSourceAgreements()\r\n    {\r\n        return m_acceptSourceAgreements;\r\n    }\r\n\r\n    void PackageCatalogReference::PackageCatalogBackgroundUpdateInterval(winrt::Windows::Foundation::TimeSpan const& value)\r\n    {\r\n        if (IsComposite())\r\n        {\r\n            // Can't set PackageCatalogBackgroundUpdateInterval on a composite. Callers should set it on each non-composite PackageCatalogReference in the composite.\r\n            throw winrt::hresult_illegal_state_change();\r\n        }\r\n        m_packageCatalogBackgroundUpdateInterval = value;\r\n    }\r\n    winrt::Windows::Foundation::TimeSpan PackageCatalogReference::PackageCatalogBackgroundUpdateInterval()\r\n    {\r\n        return m_packageCatalogBackgroundUpdateInterval;\r\n    }\r\n\r\n    bool PackageCatalogReference::InstalledPackageInformationOnly()\r\n    {\r\n        return m_installedPackageInformationOnly;\r\n    }\r\n\r\n    void PackageCatalogReference::InstalledPackageInformationOnly(bool value)\r\n    {\r\n        if (IsComposite())\r\n        {\r\n            throw winrt::hresult_illegal_state_change();\r\n        }\r\n\r\n        m_installedPackageInformationOnly = value;\r\n    }\r\n    winrt::Microsoft::Management::Deployment::AuthenticationArguments PackageCatalogReference::AuthenticationArguments()\r\n    {\r\n        return m_authenticationArguments;\r\n    }\r\n    void PackageCatalogReference::AuthenticationArguments(winrt::Microsoft::Management::Deployment::AuthenticationArguments const& value)\r\n    {\r\n        if (IsComposite())\r\n        {\r\n            throw winrt::hresult_illegal_state_change();\r\n        }\r\n\r\n        m_authenticationArguments = value;\r\n    }\r\n    winrt::Microsoft::Management::Deployment::AuthenticationInfo PackageCatalogReference::AuthenticationInfo()\r\n    {\r\n        std::call_once(m_authenticationInfoOnceFlag,\r\n            [&]()\r\n            {\r\n                if (!IsComposite())\r\n                {\r\n                    auto authenticationInfo = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::AuthenticationInfo>>();\r\n                    authenticationInfo->Initialize(m_sourceReference.GetInformation().Authentication);\r\n                    m_authenticationInfo = *authenticationInfo;\r\n                }\r\n            });\r\n        return m_authenticationInfo;\r\n    }\r\n\r\n    winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Microsoft::Management::Deployment::RefreshPackageCatalogResult, double> PackageCatalogReference::RefreshPackageCatalogAsync()\r\n    {\r\n        HRESULT terminationHR = S_OK;\r\n        try {\r\n            // Check for permissions and get caller info for telemetry\r\n            THROW_IF_FAILED(EnsureComCallerHasCapability(Capability::PackageQuery));\r\n\r\n            auto strong_this = get_strong();\r\n            auto report_progress{ co_await winrt::get_progress_token() };\r\n            co_await winrt::resume_background();\r\n\r\n            auto packageCatalogProgressSink = winrt::Microsoft::Management::Deployment::ProgressSinkFactory::CreatePackageCatalogProgressSink(this->m_sourceReference.GetDetails().Type, report_progress);\r\n\r\n            packageCatalogProgressSink->BeginProgress();\r\n            ::AppInstaller::ProgressCallback progress(packageCatalogProgressSink.get());\r\n            this->m_sourceReference.Update(progress);\r\n            packageCatalogProgressSink->EndProgress(false);\r\n        }\r\n        catch (...)\r\n        {\r\n            terminationHR = AppInstaller::CLI::Workflow::HandleException(nullptr, std::current_exception());\r\n        }\r\n\r\n        co_return GetRefreshPackageCatalogResult(terminationHR);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PackageCatalogReference.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"PackageCatalogReference.g.h\"\n#include <optional>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    struct PackageCatalogReference : PackageCatalogReferenceT<PackageCatalogReference>\n    {\n        PackageCatalogReference() = default;\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void Initialize(Deployment::PackageCatalogInfo packageCatalogInfo, ::AppInstaller::Repository::Source sourceReference);\n        void Initialize(Deployment::CreateCompositePackageCatalogOptions options);\n#endif\n\n        bool IsComposite();\n        winrt::Microsoft::Management::Deployment::PackageCatalogInfo Info();\n        winrt::Windows::Foundation::IAsyncOperation<winrt::Microsoft::Management::Deployment::ConnectResult> ConnectAsync();\n        winrt::Microsoft::Management::Deployment::ConnectResult Connect();\n        winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Management::Deployment::SourceAgreement> SourceAgreements();\n        hstring AdditionalPackageCatalogArguments();\n        void AdditionalPackageCatalogArguments(hstring const& value);\n        // Contract 6\n        bool AcceptSourceAgreements();\n        void AcceptSourceAgreements(bool value);\n        // Contract 8.0\n        winrt::Windows::Foundation::TimeSpan PackageCatalogBackgroundUpdateInterval();\n        void PackageCatalogBackgroundUpdateInterval(winrt::Windows::Foundation::TimeSpan const& value);\n        bool InstalledPackageInformationOnly();\n        void InstalledPackageInformationOnly(bool value);\n        winrt::Microsoft::Management::Deployment::AuthenticationArguments AuthenticationArguments();\n        void AuthenticationArguments(winrt::Microsoft::Management::Deployment::AuthenticationArguments const& value);\n        winrt::Microsoft::Management::Deployment::AuthenticationInfo AuthenticationInfo();\r\n        // Contract 12.0\r\n        winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Microsoft::Management::Deployment::RefreshPackageCatalogResult, double> RefreshPackageCatalogAsync();\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        winrt::Microsoft::Management::Deployment::CreateCompositePackageCatalogOptions m_compositePackageCatalogOptions{ nullptr };\n        winrt::Microsoft::Management::Deployment::PackageCatalogInfo m_info{ nullptr };\n        std::once_flag m_sourceAgreementsOnceFlag;\n        winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::SourceAgreement> m_sourceAgreements{ winrt::single_threaded_vector<winrt::Microsoft::Management::Deployment::SourceAgreement>() };\n        ::AppInstaller::Repository::Source m_sourceReference;\n        std::optional<std::string> m_additionalPackageCatalogArguments;\n        bool m_acceptSourceAgreements = true;\n        bool m_installedPackageInformationOnly = false;\n        winrt::Windows::Foundation::TimeSpan m_packageCatalogBackgroundUpdateInterval = winrt::Windows::Foundation::TimeSpan::zero();\n        winrt::Microsoft::Management::Deployment::AuthenticationArguments m_authenticationArguments{ nullptr };\n        std::once_flag m_authenticationInfoOnceFlag;\n        winrt::Microsoft::Management::Deployment::AuthenticationInfo m_authenticationInfo{ nullptr };\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PackageInstallerInfo.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"PackageInstallerInfo.h\"\n#include \"PackageInstallerInfo.g.cpp\"\r\n#include \"AuthenticationInfo.h\"\n#include \"Converters.h\"\n#include <wil\\cppwinrt_wrl.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    void PackageInstallerInfo::Initialize(const ::AppInstaller::Manifest::ManifestInstaller& manifestInstaller)\n    {\n        m_manifestInstaller = manifestInstaller;\n    }\n    winrt::Microsoft::Management::Deployment::PackageInstallerType PackageInstallerInfo::InstallerType()\r\n    {\r\n        return GetDeploymentInstallerType(m_manifestInstaller.BaseInstallerType);\r\n    }\n    winrt::Microsoft::Management::Deployment::PackageInstallerType PackageInstallerInfo::NestedInstallerType()\r\n    {\r\n        return GetDeploymentInstallerType(m_manifestInstaller.NestedInstallerType);\r\n    }\n    winrt::Windows::System::ProcessorArchitecture PackageInstallerInfo::Architecture()\r\n    {\r\n        auto convertedArchitecture = GetWindowsSystemProcessorArchitecture(m_manifestInstaller.Arch);\r\n        return convertedArchitecture ? convertedArchitecture.value() : Windows::System::ProcessorArchitecture::Unknown;\r\n    }\n    winrt::Microsoft::Management::Deployment::PackageInstallerScope PackageInstallerInfo::Scope()\r\n    {\r\n        return GetDeploymentInstallerScope(m_manifestInstaller.Scope);\r\n    }\n    hstring PackageInstallerInfo::Locale()\r\n    {\r\n        return winrt::to_hstring(m_manifestInstaller.Locale);\r\n    }\n    winrt::Microsoft::Management::Deployment::ElevationRequirement PackageInstallerInfo::ElevationRequirement()\n    {\n        return GetDeploymentElevationRequirement(m_manifestInstaller.ElevationRequirement);\n    }\n    winrt::Microsoft::Management::Deployment::AuthenticationInfo PackageInstallerInfo::AuthenticationInfo()\n    {\n        std::call_once(m_authenticationInfoOnceFlag,\r\n            [&]()\r\n            {\r\n                auto authenticationInfo = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::AuthenticationInfo>>();\r\n                authenticationInfo->Initialize(m_manifestInstaller.AuthInfo);\r\n                m_authenticationInfo = *authenticationInfo;\r\n            });\r\n        return m_authenticationInfo;\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PackageInstallerInfo.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"PackageInstallerInfo.g.h\"\n#include <winget/ManifestInstaller.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    struct PackageInstallerInfo : PackageInstallerInfoT<PackageInstallerInfo>\n    {\n        PackageInstallerInfo() = default;\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void Initialize(const ::AppInstaller::Manifest::ManifestInstaller& manifestInstaller);\n#endif\n\n        winrt::Microsoft::Management::Deployment::PackageInstallerType InstallerType();\n        winrt::Microsoft::Management::Deployment::PackageInstallerType NestedInstallerType();\n        winrt::Windows::System::ProcessorArchitecture Architecture();\n        winrt::Microsoft::Management::Deployment::PackageInstallerScope Scope();\n        hstring Locale();\n        // Contract 6.0\n        winrt::Microsoft::Management::Deployment::ElevationRequirement ElevationRequirement();\r\n        // Contract 12.0\r\n        winrt::Microsoft::Management::Deployment::AuthenticationInfo AuthenticationInfo();\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        ::AppInstaller::Manifest::ManifestInstaller m_manifestInstaller;\r\n        std::once_flag m_authenticationInfoOnceFlag;\n        winrt::Microsoft::Management::Deployment::AuthenticationInfo m_authenticationInfo{ nullptr };\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PackageInstallerInstalledStatus.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"PackageInstallerInstalledStatus.h\"\n#include \"PackageInstallerInstalledStatus.g.cpp\"\n#include \"InstalledStatus.h\"\n#include \"PackageInstallerInfo.h\"\n#include <wil\\cppwinrt_wrl.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    void PackageInstallerInstalledStatus::Initialize(const ::AppInstaller::Repository::InstallerInstalledStatus& installerInstalledStatus)\n    {\n        // Initialize m_installerInfo\n        auto installerInfo = winrt::make_self<wil::details::module_count_wrapper<\n            winrt::Microsoft::Management::Deployment::implementation::PackageInstallerInfo>>();\n        installerInfo->Initialize(installerInstalledStatus.Installer);\n        m_installerInfo = *installerInfo;\n\n        // Initialize m_installedStatus\n        for (auto const& entry : installerInstalledStatus.Status)\n        {\n            auto status = winrt::make_self<wil::details::module_count_wrapper<\n                winrt::Microsoft::Management::Deployment::implementation::InstalledStatus>>();\n            status->Initialize(entry);\n\n            m_installedStatus.Append(*status);\n        }\n    }\n    winrt::Microsoft::Management::Deployment::PackageInstallerInfo PackageInstallerInstalledStatus::InstallerInfo()\r\n    {\r\n        return m_installerInfo;\r\n    }\n    winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Management::Deployment::InstalledStatus> PackageInstallerInstalledStatus::InstallerInstalledStatus()\r\n    {\r\n        return m_installedStatus.GetView();\r\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PackageInstallerInstalledStatus.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"PackageInstallerInstalledStatus.g.h\"\n#include <winget/RepositorySearch.h>\n#include <winget/InstalledStatus.h>\n#include <winrt/Windows.Foundation.Collections.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    struct PackageInstallerInstalledStatus : PackageInstallerInstalledStatusT<PackageInstallerInstalledStatus>\n    {\n        PackageInstallerInstalledStatus() = default;\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void Initialize(const ::AppInstaller::Repository::InstallerInstalledStatus& installerInstalledStatus);\n#endif\n\n        winrt::Microsoft::Management::Deployment::PackageInstallerInfo InstallerInfo();\n        winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Management::Deployment::InstalledStatus> InstallerInstalledStatus();\n        \n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        winrt::Microsoft::Management::Deployment::PackageInstallerInfo m_installerInfo{ nullptr };\n        winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::Management::Deployment::InstalledStatus> m_installedStatus{\n            winrt::single_threaded_vector<winrt::Microsoft::Management::Deployment::InstalledStatus>() };\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PackageManager.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Public/AppInstallerCLICore.h\"\r\n#include \"Microsoft/PredefinedInstalledSourceFactory.h\"\r\n#include \"Commands/RootCommand.h\"\r\n#include \"ComContext.h\"\r\n#include \"ExecutionContext.h\"\r\n#include \"Workflows/WorkflowBase.h\"\r\n#include <winget/Authentication.h>\r\n#include <winget/UserSettings.h>\r\n#include <winget/Manifest.h>\r\n#include \"Commands/COMCommand.h\"\r\n#include <AppInstallerArchitecture.h>\r\n#include <AppInstallerTelemetry.h>\r\n#include <AppInstallerErrors.h>\r\n#pragma warning( push )\r\n#pragma warning ( disable : 4467 6388)\r\n// 6388 Allow CreateInstance.\r\n#include <wil\\cppwinrt_wrl.h>\r\n// 4467 Allow use of uuid attribute for com object creation.\r\n#include \"PackageManager.h\"\r\n#pragma warning( pop )\r\n#include \"PackageManager.g.cpp\"\r\n#include \"CatalogPackage.h\"\r\n#include \"DownloadResult.h\"\r\n#include \"InstallResult.h\"\r\n#include \"UninstallResult.h\"\r\n#include \"RepairResult.h\"\r\n#include \"PackageCatalogInfo.h\"\r\n#include \"PackageCatalogReference.h\"\r\n#include \"PackageVersionInfo.h\"\r\n#include \"PackageVersionId.h\"\r\n#include \"AddPackageCatalogResult.h\"\r\n#include \"RemovePackageCatalogResult.h\"\r\n#include \"EditPackageCatalogResult.h\"\r\n#include \"Converters.h\"\r\n#include \"Helpers.h\"\r\n#include \"ContextOrchestrator.h\"\r\n#include \"AppInstallerRuntime.h\"\r\n#include <optional>\r\n#include <PackageCatalogProgress.h>\r\n\r\nusing namespace std::literals::chrono_literals;\r\nusing namespace ::AppInstaller::CLI;\r\nusing namespace ::AppInstaller::CLI::Execution;\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    namespace\r\n    {\r\n        void LogStartupIfApplicable()\r\n        {\r\n            static std::once_flag logStartupOnceFlag;\r\n            std::call_once(logStartupOnceFlag,\r\n                [&]()\r\n                {\r\n                    ::AppInstaller::Logging::Telemetry().SetCaller(GetCallerName());\r\n                    ::AppInstaller::Logging::Telemetry().LogStartup(true);\r\n                });\r\n        }\r\n\r\n        winrt::Microsoft::Management::Deployment::AddPackageCatalogResult GetAddPackageCatalogResult(winrt::hresult terminationStatus)\r\n        {\r\n            winrt::Microsoft::Management::Deployment::AddPackageCatalogStatus status = GetPackageCatalogOperationStatus<AddPackageCatalogStatus>(terminationStatus);\r\n            auto addPackageCatalogResult = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::AddPackageCatalogResult>>();\r\n            addPackageCatalogResult->Initialize(status, terminationStatus);\r\n            return *addPackageCatalogResult;\r\n        }\r\n\r\n        void CheckForDuplicateSource(const std::string& name, const std::string& type, const std::string& sourceUri)\r\n        {\r\n            auto sourceList = ::AppInstaller::Repository::Source::GetCurrentSources();\r\n\r\n            std::string sourceType = type;\r\n\r\n            // [NOTE:] If the source type is not specified, the default source type will be used for validation.In cases where the source type is empty,\r\n            // it remains unassigned until the add operation, at which point it is assigned.Without this default assignment, an empty string could be\r\n            // compared to the default type, potentially allowing different source names with the same URI to be seen as unique.\r\n            // To avoid this, assign the default source type prior to comparison.\r\n            if (sourceType.empty())\r\n            {\r\n                // This method of obtaining the default source type is slightly expensive as it requires creating a SourceFactory object\r\n                // and fetching the type name.Nonetheless, it future-proofs the code against any changes in the SourceFactory's default type.\r\n                sourceType = ::AppInstaller::Repository::Source::GetDefaultSourceType();\r\n            }\r\n\r\n            for (const auto& source : sourceList)\r\n            {\r\n                THROW_HR_IF(APPINSTALLER_CLI_ERROR_SOURCE_NAME_ALREADY_EXISTS, ::AppInstaller::Utility::ICUCaseInsensitiveEquals(source.Name, name));\r\n\r\n                bool sourceUriAlreadyExists = !source.Arg.empty() && source.Arg == sourceUri && source.Type == sourceType;\r\n                THROW_HR_IF(APPINSTALLER_CLI_ERROR_SOURCE_ARG_ALREADY_EXISTS, sourceUriAlreadyExists);\r\n            }\r\n        }\r\n\r\n        ::AppInstaller::Repository::Source CreateSourceFromOptions(const winrt::Microsoft::Management::Deployment::AddPackageCatalogOptions& options)\r\n        {\r\n            std::string name = winrt::to_string(options.Name());\r\n            std::string type = winrt::to_string(options.Type());\r\n            std::string sourceUri = winrt::to_string(options.SourceUri());\r\n\r\n            AppInstaller::Repository::SourceTrustLevel trustLevel = AppInstaller::Repository::SourceTrustLevel::None;\r\n            if (options.TrustLevel() == winrt::Microsoft::Management::Deployment::PackageCatalogTrustLevel::Trusted)\r\n            {\r\n                trustLevel = AppInstaller::Repository::SourceTrustLevel::Trusted;\r\n            }\r\n\r\n            CheckForDuplicateSource(name, type, sourceUri);\r\n\r\n            ::AppInstaller::Repository::SourceEdit additionalProperties;\r\n            additionalProperties.Explicit = options.Explicit();\r\n            additionalProperties.Priority = options.Priority();\r\n\r\n            ::AppInstaller::Repository::Source source = ::AppInstaller::Repository::Source{ name, sourceUri, type, trustLevel, additionalProperties };\r\n\r\n            std::string customHeader = winrt::to_string(options.CustomHeader());\r\n            if (!customHeader.empty())\r\n            {\r\n                source.SetCustomHeader(customHeader);\r\n            }\r\n\r\n            auto sourceInfo = source.GetInformation();\r\n\r\n            if (sourceInfo.Authentication.Type == ::AppInstaller::Authentication::AuthenticationType::Unknown)\r\n            {\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED);\r\n            }\r\n\r\n            return source;\r\n        }\r\n\r\n        winrt::Microsoft::Management::Deployment::RemovePackageCatalogResult GetRemovePackageCatalogResult(winrt::hresult terminationStatus)\r\n        {\r\n            winrt::Microsoft::Management::Deployment::RemovePackageCatalogStatus status = GetPackageCatalogOperationStatus<RemovePackageCatalogStatus>(terminationStatus);\r\n            auto removeResult = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::RemovePackageCatalogResult>>();\r\n            removeResult->Initialize(status, terminationStatus);\r\n            return *removeResult;\r\n        }\r\n\r\n        std::optional<::AppInstaller::Repository::SourceDetails> GetMatchingSource(const std::string& name)\r\n        {\r\n            auto sourceList = ::AppInstaller::Repository::Source::GetCurrentSources();\r\n\r\n            for (const auto& source : sourceList)\r\n            {\r\n                if (::AppInstaller::Utility::ICUCaseInsensitiveEquals(source.Name, name))\r\n                {\r\n                    return source; // Return the first matching source\r\n                }\r\n            }\r\n\r\n            return std::nullopt; // Return std::nullopt if no matching source is found\r\n        }\r\n    }\r\n\r\n    PackageManager::PackageManager()\r\n    {\r\n        Execution::ContextOrchestrator::RegisterForShutdownSynchronization();\r\n    }\r\n\r\n    winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Management::Deployment::PackageCatalogReference> PackageManager::GetPackageCatalogs()\r\n    {\r\n        LogStartupIfApplicable();\r\n        Windows::Foundation::Collections::IVector<Microsoft::Management::Deployment::PackageCatalogReference> catalogs{ winrt::single_threaded_vector<Microsoft::Management::Deployment::PackageCatalogReference>() };\r\n        std::vector<::AppInstaller::Repository::SourceDetails> sources = ::AppInstaller::Repository::Source::GetCurrentSources();\r\n        for (uint32_t i = 0; i < sources.size(); i++)\r\n        {\r\n            auto packageCatalogInfo = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogInfo>>();\r\n            ::AppInstaller::Repository::Source sourceReference{ sources.at(i).Name };\r\n            packageCatalogInfo->Initialize(sourceReference.GetDetails());\r\n            auto packageCatalogRef = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogReference>>();\r\n            packageCatalogRef->Initialize(*packageCatalogInfo, sourceReference);\r\n            catalogs.Append(*packageCatalogRef);\r\n        }\r\n        return catalogs.GetView();\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::PackageCatalogReference PackageManager::GetPredefinedPackageCatalog(winrt::Microsoft::Management::Deployment::PredefinedPackageCatalog const& predefinedPackageCatalog)\r\n    {\r\n        LogStartupIfApplicable();\r\n        ::AppInstaller::Repository::Source source;\r\n        switch (predefinedPackageCatalog)\r\n        {\r\n        case winrt::Microsoft::Management::Deployment::PredefinedPackageCatalog::OpenWindowsCatalog:\r\n            source = ::AppInstaller::Repository::Source{ ::AppInstaller::Repository::WellKnownSource::WinGet };\r\n            break;\r\n        case winrt::Microsoft::Management::Deployment::PredefinedPackageCatalog::MicrosoftStore:\r\n            source = ::AppInstaller::Repository::Source{ ::AppInstaller::Repository::WellKnownSource::MicrosoftStore };\r\n            break;\r\n        case winrt::Microsoft::Management::Deployment::PredefinedPackageCatalog::DesktopFrameworks:\r\n            source = ::AppInstaller::Repository::Source{ ::AppInstaller::Repository::WellKnownSource::DesktopFrameworks };\r\n            break;\r\n        case winrt::Microsoft::Management::Deployment::PredefinedPackageCatalog::OpenWindowsCatalogFont:\r\n            source = ::AppInstaller::Repository::Source{ ::AppInstaller::Repository::WellKnownSource::WinGetFont };\r\n            break;\r\n        default:\r\n            throw hresult_invalid_argument();\r\n        }\r\n        auto packageCatalogInfo = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogInfo>>();\r\n        packageCatalogInfo->Initialize(source.GetDetails());\r\n        auto packageCatalogRef = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogReference>>();\r\n        packageCatalogRef->Initialize(*packageCatalogInfo, source);\r\n        return *packageCatalogRef;\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::PackageCatalogReference PackageManager::GetLocalPackageCatalog(winrt::Microsoft::Management::Deployment::LocalPackageCatalog const& localPackageCatalog)\r\n    {\r\n        LogStartupIfApplicable();\r\n        ::AppInstaller::Repository::Source source;\r\n        switch (localPackageCatalog)\r\n        {\r\n        case winrt::Microsoft::Management::Deployment::LocalPackageCatalog::InstalledPackages:\r\n            source = ::AppInstaller::Repository::Source{ ::AppInstaller::Repository::PredefinedSource::Installed };\r\n            break;\r\n        case winrt::Microsoft::Management::Deployment::LocalPackageCatalog::InstallingPackages:\r\n            source = ::AppInstaller::Repository::Source{ ::AppInstaller::Repository::PredefinedSource::Installing };\r\n            break;\r\n        default:\r\n            throw hresult_invalid_argument();\r\n        }\r\n        auto packageCatalogInfo = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogInfo>>();\r\n        packageCatalogInfo->Initialize(source.GetDetails());\r\n        auto packageCatalogRef = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogReference>>();\r\n        packageCatalogRef->Initialize(*packageCatalogInfo, source);\r\n        return *packageCatalogRef;\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::PackageCatalogReference PackageManager::GetPackageCatalogByName(hstring const& catalogName)\r\n    {\r\n        LogStartupIfApplicable();\r\n        std::string name = winrt::to_string(catalogName);\r\n        if (name.empty())\r\n        {\r\n            return nullptr;\r\n        }\r\n\r\n        ::AppInstaller::Repository::Source source{ name };\r\n        // Create the catalog object if the source is found, otherwise return null. Don't throw.\r\n        if (source)\r\n        {\r\n            auto packageCatalogInfo = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogInfo>>();\r\n            packageCatalogInfo->Initialize(source.GetDetails());\r\n            auto packageCatalogRef = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogReference>>();\r\n            packageCatalogRef->Initialize(*packageCatalogInfo, source);\r\n            return *packageCatalogRef;\r\n        }\r\n        else\r\n        {\r\n            return nullptr;\r\n        }\r\n    }\r\n\r\n    void AddPackageManifestToContext(winrt::Microsoft::Management::Deployment::PackageVersionInfo packageVersionInfo, ::AppInstaller::CLI::Execution::Context* context)\r\n    {\r\n        winrt::Microsoft::Management::Deployment::implementation::PackageVersionInfo* packageVersionInfoImpl = get_self<winrt::Microsoft::Management::Deployment::implementation::PackageVersionInfo>(packageVersionInfo);\r\n        std::shared_ptr<::AppInstaller::Repository::IPackageVersion> internalPackageVersion = packageVersionInfoImpl->GetRepositoryPackageVersion();\r\n        ::AppInstaller::Manifest::Manifest manifest = internalPackageVersion->GetManifest();\r\n\r\n        std::string targetLocale;\r\n        if (context->Args.Contains(::AppInstaller::CLI::Execution::Args::Type::Locale))\r\n        {\r\n            targetLocale = context->Args.GetArg(::AppInstaller::CLI::Execution::Args::Type::Locale);\r\n        }\r\n        manifest.ApplyLocale(targetLocale);\r\n\r\n        context->GetThreadGlobals().GetTelemetryLogger().LogManifestFields(manifest.Id, manifest.DefaultLocalization.Get<::AppInstaller::Manifest::Localization::PackageName>(), manifest.Version);\r\n\r\n        context->Add<::AppInstaller::CLI::Execution::Data::Manifest>(std::move(manifest));\r\n        context->Add<::AppInstaller::CLI::Execution::Data::PackageVersion>(std::move(internalPackageVersion));\r\n    }\r\n\r\n    void AddInstalledVersionToContext(winrt::Microsoft::Management::Deployment::PackageVersionInfo installedVersionInfo, ::AppInstaller::CLI::Execution::Context* context)\r\n    {\r\n        winrt::Microsoft::Management::Deployment::implementation::PackageVersionInfo* installedVersionInfoImpl = get_self<winrt::Microsoft::Management::Deployment::implementation::PackageVersionInfo>(installedVersionInfo);\r\n        std::shared_ptr<::AppInstaller::Repository::IPackageVersion> internalInstalledVersion = installedVersionInfoImpl->GetRepositoryPackageVersion();\r\n        context->Add<AppInstaller::CLI::Execution::Data::InstalledPackageVersion>(internalInstalledVersion);\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::PackageCatalogReference PackageManager::CreateCompositePackageCatalog(winrt::Microsoft::Management::Deployment::CreateCompositePackageCatalogOptions const& options)\r\n    {\r\n        LogStartupIfApplicable();\r\n        if (!options)\r\n        {\r\n            // Can't make a composite source if the options aren't specified.\r\n            throw hresult_invalid_argument();\r\n        }\r\n\r\n        for (uint32_t i = 0; i < options.Catalogs().Size(); ++i)\r\n        {\r\n            auto catalog = options.Catalogs().GetAt(i);\r\n            if (catalog.IsComposite())\r\n            {\r\n                // Can't make a composite source out of a source that's already a composite.\r\n                throw hresult_invalid_argument();\r\n            }\r\n        }\r\n        auto packageCatalogImpl = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogReference>>();\r\n        packageCatalogImpl->Initialize(options);\r\n        return *packageCatalogImpl;\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::InstallResult GetInstallResult(::Workflow::ExecutionStage executionStage, winrt::hresult terminationHR, uint32_t installerError, winrt::hstring correlationData, bool rebootRequired)\r\n    {\r\n        winrt::Microsoft::Management::Deployment::InstallResultStatus installResultStatus = GetOperationResultStatus<InstallResultStatus>(executionStage, terminationHR);\r\n        auto installResult = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::InstallResult>>();\r\n        installResult->Initialize(installResultStatus, terminationHR, installerError, correlationData, rebootRequired);\r\n        return *installResult;\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::UninstallResult GetUninstallResult(::Workflow::ExecutionStage executionStage, winrt::hresult terminationHR, uint32_t uninstallerError, winrt::hstring correlationData, bool rebootRequired)\r\n    {\r\n        winrt::Microsoft::Management::Deployment::UninstallResultStatus uninstallResultStatus = GetOperationResultStatus<UninstallResultStatus>(executionStage, terminationHR);\r\n        auto uninstallResult = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::UninstallResult>>();\r\n        uninstallResult->Initialize(uninstallResultStatus, terminationHR, uninstallerError, correlationData, rebootRequired);\r\n        return *uninstallResult;\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::DownloadResult GetDownloadResult(::Workflow::ExecutionStage executionStage, winrt::hresult terminationHR, winrt::hstring correlationData)\r\n    {\r\n        winrt::Microsoft::Management::Deployment::DownloadResultStatus downloadResultStatus = GetOperationResultStatus<DownloadResultStatus>(executionStage, terminationHR);\r\n        auto downloadResult = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::DownloadResult>>();\r\n        downloadResult->Initialize(downloadResultStatus, terminationHR, correlationData);\r\n        return *downloadResult;\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::RepairResult GetRepairResult(::Workflow::ExecutionStage executionStage, winrt::hresult terminationHR, uint32_t repairError, winrt::hstring correlationData, bool rebootRequired)\r\n    {\r\n        winrt::Microsoft::Management::Deployment::RepairResultStatus repairResultStatus = GetOperationResultStatus<RepairResultStatus>(executionStage, terminationHR);\r\n        auto repairResult = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::RepairResult>>();\r\n        repairResult->Initialize(repairResultStatus, terminationHR, repairError, correlationData, rebootRequired);\r\n        return *repairResult;\r\n    }\r\n\r\n    template <typename TResult>\r\n    TResult GetOperationResult(::Workflow::ExecutionStage executionStage, winrt::hresult terminationHR, uint32_t operationError, winrt::hstring correlationData, bool rebootRequired)\r\n    {\r\n        if constexpr (std::is_same_v<TResult, winrt::Microsoft::Management::Deployment::InstallResult>)\r\n        {\r\n            return GetInstallResult(executionStage, terminationHR, operationError, correlationData, rebootRequired);\r\n        }\r\n        else if constexpr (std::is_same_v<TResult, winrt::Microsoft::Management::Deployment::UninstallResult>)\r\n        {\r\n            return GetUninstallResult(executionStage, terminationHR, operationError, correlationData, rebootRequired);\r\n        }\r\n        else if constexpr (std::is_same_v<TResult, winrt::Microsoft::Management::Deployment::DownloadResult>)\r\n        {\r\n            return GetDownloadResult(executionStage, terminationHR, correlationData);\r\n        }\r\n        else if constexpr (std::is_same_v<TResult, winrt::Microsoft::Management::Deployment::RepairResult>)\r\n        {\r\n            return GetRepairResult(executionStage, terminationHR, operationError, correlationData, rebootRequired);\r\n        }\r\n    }\r\n\r\n#define WINGET_GET_PROGRESS_STATE(_installState_, _uninstallState_, _repairState_) \\\r\n    if constexpr (std::is_same_v<TState, winrt::Microsoft::Management::Deployment::PackageInstallProgressState>) \\\r\n    { \\\r\n        progressState = TState::_installState_; \\\r\n    } \\\r\n    else if constexpr (std::is_same_v<TState, winrt::Microsoft::Management::Deployment::PackageUninstallProgressState>) \\\r\n    { \\\r\n        progressState = TState::_uninstallState_; \\\r\n    } \\\r\n    else if constexpr (std::is_same_v<TState, winrt::Microsoft::Management::Deployment::PackageRepairProgressState>) \\\r\n    { \\\r\n        progressState = TState::_repairState_; \\\r\n    } \\\r\n\r\n    template <typename TProgress, typename TState>\r\n    std::optional<TProgress> GetProgress(\r\n        ReportType reportType,\r\n        uint64_t current,\r\n        uint64_t maximum,\r\n        ::AppInstaller::ProgressType progressType,\r\n        ::Workflow::ExecutionStage executionPhase)\r\n    {\r\n        bool reportProgress = false;\r\n        TState progressState = TState::Queued;\r\n        double downloadProgress = 0;\r\n        double operationProgress = 0;\r\n        uint64_t downloadBytesDownloaded = 0;\r\n        uint64_t downloadBytesRequired = 0;\r\n        switch (executionPhase)\r\n        {\r\n        case ::Workflow::ExecutionStage::Initial:\r\n        case ::Workflow::ExecutionStage::ParseArgs:\r\n        case ::Workflow::ExecutionStage::Discovery:\r\n            // We already reported queued progress up front.\r\n            break;\r\n        case ::Workflow::ExecutionStage::Download:\r\n            if constexpr (std::is_same_v<TProgress, winrt::Microsoft::Management::Deployment::InstallProgress> ||\r\n                std::is_same_v<TProgress, winrt::Microsoft::Management::Deployment::PackageDownloadProgress>)\r\n            {\r\n                progressState = TState::Downloading;\r\n                if (reportType == ReportType::BeginProgress)\r\n                {\r\n                    reportProgress = true;\r\n                }\r\n                else if (progressType == ::AppInstaller::ProgressType::Bytes)\r\n                {\r\n                    downloadBytesDownloaded = current;\r\n                    downloadBytesRequired = maximum;\r\n                    if (maximum > 0 && maximum >= current)\r\n                    {\r\n                        reportProgress = true;\r\n                        downloadProgress = static_cast<double>(current) / static_cast<double>(maximum);\r\n                    }\r\n                }\r\n            }\r\n            break;\r\n        case ::Workflow::ExecutionStage::PreExecution:\r\n            // Wait until installer starts to report operation.\r\n            break;\r\n        case ::Workflow::ExecutionStage::Execution:\r\n            WINGET_GET_PROGRESS_STATE(Installing, Uninstalling, Repairing);\r\n            downloadProgress = 1;\r\n            if (reportType == ReportType::ExecutionPhaseUpdate)\r\n            {\r\n                // Operation is starting. Send progress so callers know the AsyncOperation can't be cancelled.\r\n                reportProgress = true;\r\n            }\r\n            else if (reportType == ReportType::EndProgress)\r\n            {\r\n                // Operation is \"finished\". May not have succeeded.\r\n                reportProgress = true;\r\n                operationProgress = 1;\r\n            }\r\n            else if (progressType == ::AppInstaller::ProgressType::Percent)\r\n            {\r\n                if (maximum > 0 && maximum >= current)\r\n                {\r\n                    // Operation is progressing\r\n                    reportProgress = true;\r\n                    operationProgress = static_cast<double>(current) / static_cast<double>(maximum);\r\n                }\r\n            }\r\n            break;\r\n        case ::Workflow::ExecutionStage::PostExecution:\r\n            if (reportType == ReportType::ExecutionPhaseUpdate)\r\n            {\r\n                // Send PostInstall progress when it switches to PostExecution phase.\r\n                reportProgress = true;\r\n                WINGET_GET_PROGRESS_STATE(PostInstall, PostUninstall, PostRepair);\r\n                downloadProgress = 1;\r\n                operationProgress = 1;\r\n            }\r\n            break;\r\n        }\r\n        if (reportProgress)\r\n        {\r\n            if constexpr (std::is_same_v<TProgress, winrt::Microsoft::Management::Deployment::InstallProgress>)\r\n            {\r\n                TProgress progress{ progressState, downloadBytesDownloaded, downloadBytesRequired, downloadProgress, operationProgress };\r\n                return progress;\r\n            }\r\n            else if constexpr (std::is_same_v<TProgress, winrt::Microsoft::Management::Deployment::UninstallProgress>)\r\n            {\r\n                TProgress progress{ progressState, operationProgress };\r\n                return progress;\r\n            }\r\n            else if constexpr (std::is_same_v<TProgress, winrt::Microsoft::Management::Deployment::PackageDownloadProgress>)\r\n            {\r\n                TProgress progress{ progressState, downloadBytesDownloaded, downloadBytesRequired, downloadProgress };\r\n                return progress;\r\n            }\r\n            else if constexpr (std::is_same_v<TProgress, winrt::Microsoft::Management::Deployment::RepairProgress>)\r\n            {\r\n                TProgress progress{ progressState, operationProgress };\r\n                return progress;\r\n            }\r\n        }\r\n        else\r\n        {\r\n            return {};\r\n        }\r\n    }\r\n\r\n    template <typename TOptions>\r\n    Microsoft::Management::Deployment::PackageVersionInfo GetPackageVersionInfo(winrt::Microsoft::Management::Deployment::CatalogPackage package, TOptions options)\r\n    {\r\n        Microsoft::Management::Deployment::PackageVersionInfo packageVersionInfo{ nullptr };\r\n\r\n        winrt::Microsoft::Management::Deployment::PackageVersionId versionId = (options) ? options.PackageVersionId() : nullptr;\r\n        // If the version of the package is specified use that, otherwise use the default.\r\n        if (versionId)\r\n        {\r\n            packageVersionInfo = package.GetPackageVersionInfo(versionId);\r\n        }\r\n        else\r\n        {\r\n            if constexpr (std::is_same_v<TOptions, winrt::Microsoft::Management::Deployment::InstallOptions>)\r\n            {\r\n                packageVersionInfo = package.DefaultInstallVersion();\r\n            }\r\n            else if constexpr (std::is_same_v<TOptions, winrt::Microsoft::Management::Deployment::DownloadOptions>)\r\n            {\r\n                // For download, applicability check is not needed. Just use latest.\r\n                if (package.AvailableVersions().Size() > 0)\r\n                {\r\n                    packageVersionInfo = package.GetPackageVersionInfo(package.AvailableVersions().GetAt(0));\r\n                }\r\n            }\r\n        }\r\n        // If the specified version wasn't found then return a failure. This is unusual, since all packages that came from a non-local catalog have a default version,\r\n        // and the versionId is strongly typed and comes from the CatalogPackage.GetAvailableVersions.\r\n        // If version is not specified, DefaultInstallVersion may be empty due to applicability check.\r\n        THROW_HR_IF(versionId ? APPINSTALLER_CLI_ERROR_NO_MANIFEST_FOUND : APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER, !packageVersionInfo);\r\n        return packageVersionInfo;\r\n    }\r\n\r\n    void PopulateContextFromInstallOptions(\r\n        ::AppInstaller::CLI::Execution::Context* context,\r\n        winrt::Microsoft::Management::Deployment::InstallOptions options)\r\n    {\r\n        if (options)\r\n        {\r\n            if (!options.LogOutputPath().empty())\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::Log, ::AppInstaller::Utility::ConvertToUTF8(options.LogOutputPath()));\r\n                context->Args.AddArg(Execution::Args::Type::VerboseLogs);\r\n            }\r\n            if (options.AllowHashMismatch())\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::HashOverride);\r\n            }\r\n\r\n            if (options.BypassIsStoreClientBlockedPolicyCheck())\r\n            {\r\n                context->SetFlags(Execution::ContextFlag::BypassIsStoreClientBlockedPolicyCheck);\r\n            }\r\n\r\n            if (options.Force())\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::Force);\r\n            }\r\n\r\n            // If the PackageInstallScope is anything other than ::Any then set it as a requirement.\r\n            auto manifestScope = GetManifestScope(options.PackageInstallScope());\r\n            if (manifestScope.first != ::AppInstaller::Manifest::ScopeEnum::Unknown)\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::InstallScope, ScopeToString(manifestScope.first));\r\n                context->Add<Execution::Data::AllowUnknownScope>(manifestScope.second);\r\n            }\r\n\r\n            if (options.PackageInstallMode() == PackageInstallMode::Interactive)\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::Interactive);\r\n            }\r\n            else if (options.PackageInstallMode() == PackageInstallMode::Silent)\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::Silent);\r\n            }\r\n\r\n            auto installerType = GetManifestInstallerType(options.InstallerType());\r\n            if (installerType != AppInstaller::Manifest::InstallerTypeEnum::Unknown)\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::InstallerType, AppInstaller::Manifest::InstallerTypeToString(installerType));\r\n            }\r\n\r\n            if (!options.PreferredInstallLocation().empty())\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::InstallLocation, ::AppInstaller::Utility::ConvertToUTF8(options.PreferredInstallLocation()));\r\n            }\r\n\r\n            if (!options.ReplacementInstallerArguments().empty())\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::Override, ::AppInstaller::Utility::ConvertToUTF8(options.ReplacementInstallerArguments()));\r\n            }\r\n\r\n            if (!options.AdditionalInstallerArguments().empty())\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::CustomSwitches, ::AppInstaller::Utility::ConvertToUTF8(options.AdditionalInstallerArguments()));\r\n            }\r\n\r\n            if (options.AllowedArchitectures().Size() != 0)\r\n            {\r\n                std::vector<AppInstaller::Utility::Architecture> allowedArchitectures;\r\n                for (auto architecture : options.AllowedArchitectures())\r\n                {\r\n                    auto convertedArchitecture = GetUtilityArchitecture(architecture);\r\n                    if (convertedArchitecture)\r\n                    {\r\n                        allowedArchitectures.push_back(convertedArchitecture.value());\r\n                    }\r\n                }\r\n                context->Add<Data::AllowedArchitectures>(std::move(allowedArchitectures));\r\n            }\r\n\r\n            // Note: AdditionalPackageCatalogArguments is not needed during install since the manifest is already known so no additional calls to the source are needed. The property is deprecated.\r\n\r\n            if (options.AcceptPackageAgreements())\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::AcceptPackageAgreements);\r\n            }\r\n\r\n            if (options.SkipDependencies())\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::SkipDependencies);\r\n            }\r\n\r\n            if (options.AuthenticationArguments())\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::AuthenticationMode, ::AppInstaller::Authentication::AuthenticationModeToString(GetAuthenticationMode(options.AuthenticationArguments().AuthenticationMode())));\r\n                context->Args.AddArg(Execution::Args::Type::AuthenticationAccount, ::AppInstaller::Utility::ConvertToUTF8(options.AuthenticationArguments().AuthenticationAccount()));\r\n            }\r\n        }\r\n        else\r\n        {\r\n            // Note: If no install options are specified, we assume the caller is accepting the package agreements by default.\r\n            context->Args.AddArg(Execution::Args::Type::AcceptPackageAgreements);\r\n        }\r\n    }\r\n\r\n    void PopulateContextFromUninstallOptions(\r\n        ::AppInstaller::CLI::Execution::Context* context,\r\n        winrt::Microsoft::Management::Deployment::UninstallOptions options)\r\n    {\r\n        if (options)\r\n        {\r\n            if (!options.LogOutputPath().empty())\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::Log, ::AppInstaller::Utility::ConvertToUTF8(options.LogOutputPath()));\r\n                context->Args.AddArg(Execution::Args::Type::VerboseLogs);\r\n            }\r\n            if (options.Force())\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::Force);\r\n            }\r\n\r\n            if (options.PackageUninstallMode() == PackageUninstallMode::Interactive)\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::Interactive);\r\n            }\r\n            else if (options.PackageUninstallMode() == PackageUninstallMode::Silent)\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::Silent);\r\n            }\r\n\r\n            auto uninstallScope = GetManifestUninstallScope(options.PackageUninstallScope());\r\n            if (uninstallScope != ::AppInstaller::Manifest::ScopeEnum::Unknown)\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::InstallScope, ScopeToString(uninstallScope));\r\n            }\r\n        }\r\n    }\r\n\r\n    void PopulateContextFromDownloadOptions(\r\n        ::AppInstaller::CLI::Execution::Context* context,\r\n        winrt::Microsoft::Management::Deployment::DownloadOptions options)\r\n    {\r\n        if (options)\r\n        {\r\n            if (!options.DownloadDirectory().empty())\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::DownloadDirectory, ::AppInstaller::Utility::ConvertToUTF8(options.DownloadDirectory()));\r\n            }\r\n            if (!options.Locale().empty())\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::Locale, ::AppInstaller::Utility::ConvertToUTF8(options.Locale()));\r\n            }\r\n            if (options.AllowHashMismatch())\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::HashOverride);\r\n            }\r\n            if (options.SkipDependencies())\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::SkipDependencies);\r\n            }\r\n            if (options.AcceptPackageAgreements())\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::AcceptPackageAgreements);\r\n            }\r\n            auto manifestScope = GetManifestScope(options.Scope());\r\n            if (manifestScope.first != ::AppInstaller::Manifest::ScopeEnum::Unknown)\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::InstallScope, ScopeToString(manifestScope.first));\r\n            }\r\n\r\n            auto architecture = options.Architecture();\r\n            if (architecture != Windows::System::ProcessorArchitecture::Unknown)\r\n            {\r\n                auto convertedArchitecture = GetUtilityArchitecture(architecture);\r\n                if (convertedArchitecture)\r\n                {\r\n                    context->Args.AddArg(Execution::Args::Type::InstallerArchitecture, ToString(convertedArchitecture.value()));\r\n                }\r\n            }\r\n\r\n            auto installerType = GetManifestInstallerType(options.InstallerType());\r\n            if (installerType != AppInstaller::Manifest::InstallerTypeEnum::Unknown)\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::InstallerType, AppInstaller::Manifest::InstallerTypeToString(installerType));\r\n            }\r\n\r\n            if (options.AuthenticationArguments())\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::AuthenticationMode, ::AppInstaller::Authentication::AuthenticationModeToString(GetAuthenticationMode(options.AuthenticationArguments().AuthenticationMode())));\r\n                context->Args.AddArg(Execution::Args::Type::AuthenticationAccount, ::AppInstaller::Utility::ConvertToUTF8(options.AuthenticationArguments().AuthenticationAccount()));\r\n            }\r\n\r\n            if (options.SkipMicrosoftStoreLicense())\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::SkipMicrosoftStorePackageLicense);\r\n            }\r\n\r\n            WindowsPlatform platform = options.Platform();\r\n            if (platform != WindowsPlatform::Unknown)\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::Platform, AppInstaller::Manifest::PlatformToString(GetPlatformEnum(platform)));\r\n            }\r\n\r\n            hstring targetOSVersion = options.TargetOSVersion();\r\n            if (!targetOSVersion.empty())\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::OSVersion, ::AppInstaller::Utility::ConvertToUTF8(targetOSVersion));\r\n            }\r\n        }\r\n    }\r\n\r\n    void PopulateContextFromRepairOptions(\r\n        ::AppInstaller::CLI::Execution::Context* context,\r\n        winrt::Microsoft::Management::Deployment::RepairOptions options)\r\n    {\r\n        if (options)\r\n        {\r\n            if (!options.LogOutputPath().empty())\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::Log, ::AppInstaller::Utility::ConvertToUTF8(options.LogOutputPath()));\r\n                context->Args.AddArg(Execution::Args::Type::VerboseLogs);\r\n            }\r\n\r\n            if (options.PackageRepairMode() == PackageRepairMode::Interactive)\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::Interactive);\r\n            }\r\n            else if (options.PackageRepairMode() == PackageRepairMode::Silent)\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::Silent);\r\n            }\r\n\r\n            if (options.AcceptPackageAgreements())\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::AcceptPackageAgreements);\r\n            }\r\n\r\n            if (options.AllowHashMismatch())\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::HashOverride);\r\n            }\r\n\r\n            if (options.BypassIsStoreClientBlockedPolicyCheck())\r\n            {\r\n                context->SetFlags(Execution::ContextFlag::BypassIsStoreClientBlockedPolicyCheck);\r\n            }\r\n\r\n            if (options.Force())\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::Force);\r\n            }\r\n\r\n            auto repairScope = GetManifestRepairScope(options.PackageRepairScope());\r\n            if (repairScope != ::AppInstaller::Manifest::ScopeEnum::Unknown)\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::InstallScope, ScopeToString(repairScope));\r\n            }\r\n\r\n            if (options.AuthenticationArguments())\r\n            {\r\n                context->Args.AddArg(Execution::Args::Type::AuthenticationMode, ::AppInstaller::Authentication::AuthenticationModeToString(GetAuthenticationMode(options.AuthenticationArguments().AuthenticationMode())));\r\n                context->Args.AddArg(Execution::Args::Type::AuthenticationAccount, ::AppInstaller::Utility::ConvertToUTF8(options.AuthenticationArguments().AuthenticationAccount()));\r\n            }\r\n        }\r\n    }\r\n\r\n    template <typename TOptions>\r\n    std::unique_ptr<COMContext> CreateContextFromOperationOptions(\r\n        TOptions options,\r\n        std::wstring callerProcessInfoString)\r\n    {\r\n        std::unique_ptr<COMContext> context = std::make_unique<COMContext>();\r\n        hstring correlationData = (options) ? options.CorrelationData() : L\"\";\r\n\r\n        context->SetContextLoggers(correlationData, GetComCallerName(AppInstaller::Utility::ConvertToUTF8(callerProcessInfoString)));\r\n\r\n        // Convert the options to arguments for the installer.\r\n        if constexpr (std::is_same_v<TOptions, winrt::Microsoft::Management::Deployment::InstallOptions>)\r\n        {\r\n            PopulateContextFromInstallOptions(context.get(), options);\r\n        }\r\n        else if constexpr (std::is_same_v<TOptions, winrt::Microsoft::Management::Deployment::UninstallOptions>)\r\n        {\r\n            PopulateContextFromUninstallOptions(context.get(), options);\r\n        }\r\n        else if constexpr (std::is_same_v<TOptions, winrt::Microsoft::Management::Deployment::DownloadOptions>)\r\n        {\r\n            PopulateContextFromDownloadOptions(context.get(), options);\r\n        }\r\n        else if constexpr (std::is_same_v<TOptions, winrt::Microsoft::Management::Deployment::RepairOptions>)\r\n        {\r\n            PopulateContextFromRepairOptions(context.get(), options);\r\n        }\r\n\r\n        return context;\r\n    }\r\n\r\n    std::shared_ptr<Execution::OrchestratorQueueItem> GetExistingQueueItemForPackage(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::PackageCatalogInfo catalogInfo)\r\n    {\r\n        std::shared_ptr<Execution::OrchestratorQueueItem> queueItem = nullptr;\r\n        std::unique_ptr<COMContext> context = std::make_unique<COMContext>();\r\n        if (catalogInfo)\r\n        {\r\n            // If the caller has passed in the catalog they expect the package to have come from, then only look for an install from that catalog.\r\n            // Fail if they've used a catalog that doesn't have an Id. This can currently happen for Info objects that come from PackageCatalogReference objects for REST catalogs.\r\n            THROW_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS, catalogInfo.Id().empty());\r\n            auto searchItem = Execution::OrchestratorQueueItemFactory::CreateItemForSearch(std::wstring{ package.Id() }, std::wstring{ catalogInfo.Id() }, std::move(context));\r\n            queueItem = Execution::ContextOrchestrator::Instance().GetQueueItem(searchItem->GetId());\r\n            return queueItem;\r\n        }\r\n\r\n        // If the caller has not specified the catalog, then check InstalledVersion. When the package comes from the Installing catalog the PackageCatalog\r\n        // of the InstalledVersion will be set to the original catalog that the install was from, so checking the InstalledVersion first is most likely to \r\n        // find a result.\r\n        Microsoft::Management::Deployment::PackageVersionInfo installedVersionInfo = package.InstalledVersion();\r\n        if (installedVersionInfo)\r\n        {\r\n            auto searchItem = Execution::OrchestratorQueueItemFactory::CreateItemForSearch(std::wstring{ package.Id() }, std::wstring{ installedVersionInfo.PackageCatalog().Info().Id() }, std::move(context));\r\n            queueItem = Execution::ContextOrchestrator::Instance().GetQueueItem(searchItem->GetId());\r\n            if (queueItem)\r\n            {\r\n                return queueItem;\r\n            }\r\n        }\r\n\r\n        // If InstalledVersion was not found, check DefaultInstallVersion\r\n        Microsoft::Management::Deployment::PackageVersionInfo defaultInstallVersionInfo = package.DefaultInstallVersion();\r\n        if (defaultInstallVersionInfo)\r\n        {\r\n            auto searchItem = Execution::OrchestratorQueueItemFactory::CreateItemForSearch(std::wstring{ package.Id() }, std::wstring{ defaultInstallVersionInfo.PackageCatalog().Info().Id() }, std::move(context));\r\n            queueItem = Execution::ContextOrchestrator::Instance().GetQueueItem(searchItem->GetId());\r\n            if (queueItem)\r\n            {\r\n                return queueItem;\r\n            }\r\n        }\r\n\r\n        // Finally check all catalogs in AvailableVersions.\r\n        for (Microsoft::Management::Deployment::PackageVersionId versionId : package.AvailableVersions())\r\n        {\r\n            auto searchItem = Execution::OrchestratorQueueItemFactory::CreateItemForSearch(std::wstring{ package.Id() }, std::wstring{ package.GetPackageVersionInfo(versionId).PackageCatalog().Info().Id() }, std::move(context));\r\n            queueItem = Execution::ContextOrchestrator::Instance().GetQueueItem(searchItem->GetId());\r\n            if (queueItem)\r\n            {\r\n                return queueItem;\r\n            }\r\n        }\r\n        return nullptr;\r\n    }\r\n\r\n    std::unique_ptr<Execution::OrchestratorQueueItem> CreateQueueItemForInstall(\r\n        std::unique_ptr<::AppInstaller::CLI::Execution::COMContext> comContext,\r\n        winrt::Microsoft::Management::Deployment::CatalogPackage package,\r\n        winrt::Microsoft::Management::Deployment::InstallOptions options,\r\n        bool isUpgrade)\r\n    {\r\n        // Add manifest and PackageVersion to context for install/upgrade.\r\n        // If the version of the package is specified use that, otherwise use the default.\r\n        Microsoft::Management::Deployment::PackageVersionInfo packageVersionInfo = GetPackageVersionInfo(package, options);\r\n        AddPackageManifestToContext(packageVersionInfo, comContext.get());\r\n\r\n        if (isUpgrade)\r\n        {\r\n            AppInstaller::Utility::VersionAndChannel installedVersion{ winrt::to_string(package.InstalledVersion().Version()), winrt::to_string(package.InstalledVersion().Channel()) };\r\n            AppInstaller::Utility::VersionAndChannel upgradeVersion{ winrt::to_string(packageVersionInfo.Version()), winrt::to_string(packageVersionInfo.Channel()) };\r\n\r\n            // Perform upgrade version check\r\n            if (upgradeVersion.GetVersion().IsUnknown())\r\n            {\r\n                if (!(options.AllowUpgradeToUnknownVersion() &&\r\n                    AppInstaller::Utility::ICUCaseInsensitiveEquals(installedVersion.GetChannel().ToString(), upgradeVersion.GetChannel().ToString())))\r\n                {\r\n                    THROW_HR(APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_UNKNOWN);\r\n                }\r\n            }\r\n            else if (!installedVersion.IsUpdatedBy(upgradeVersion))\r\n            {\r\n                THROW_HR(APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_NOT_NEWER);\r\n            }\r\n\r\n            // Set upgrade flag\r\n            comContext->SetFlags(AppInstaller::CLI::Execution::ContextFlag::InstallerExecutionUseUpdate);\r\n            // Add installed version\r\n            AddInstalledVersionToContext(package.InstalledVersion(), comContext.get());\r\n        }\r\n\r\n        return Execution::OrchestratorQueueItemFactory::CreateItemForInstall(std::wstring{ package.Id() }, std::wstring{ packageVersionInfo.PackageCatalog().Info().Id() }, std::move(comContext), isUpgrade);\r\n    }\r\n\r\n    std::unique_ptr<Execution::OrchestratorQueueItem> CreateQueueItemForUninstall(\r\n        std::unique_ptr<::AppInstaller::CLI::Execution::COMContext> comContext,\r\n        winrt::Microsoft::Management::Deployment::CatalogPackage package)\r\n    {\r\n        // Add installed version\r\n        AddInstalledVersionToContext(package.InstalledVersion(), comContext.get());\r\n\r\n        // Add Package which is used by RecordUninstall later for removing from tracking catalog of correlated available sources as best effort\r\n        winrt::Microsoft::Management::Deployment::implementation::CatalogPackage* catalogPackageImpl = get_self<winrt::Microsoft::Management::Deployment::implementation::CatalogPackage>(package);\r\n        std::shared_ptr<::AppInstaller::Repository::ICompositePackage> internalPackage = catalogPackageImpl->GetRepositoryPackage();\r\n        comContext->Add<AppInstaller::CLI::Execution::Data::Package>(internalPackage);\r\n\r\n        return Execution::OrchestratorQueueItemFactory::CreateItemForUninstall(std::wstring{ package.Id() }, std::wstring{ package.InstalledVersion().PackageCatalog().Info().Id() }, std::move(comContext));\r\n    }\r\n\r\n    std::unique_ptr<Execution::OrchestratorQueueItem> CreateQueueItemForDownload(\r\n        std::unique_ptr<::AppInstaller::CLI::Execution::COMContext> comContext,\r\n        winrt::Microsoft::Management::Deployment::CatalogPackage package,\r\n        winrt::Microsoft::Management::Deployment::DownloadOptions options)\r\n    {\r\n        // Add manifest and PackageVersion to context for download.\r\n        // If the version of the package is specified use that, otherwise use the default.\r\n        Microsoft::Management::Deployment::PackageVersionInfo packageVersionInfo = GetPackageVersionInfo(package, options);\r\n        AddPackageManifestToContext(packageVersionInfo, comContext.get());\r\n\r\n        comContext->SetFlags(AppInstaller::CLI::Execution::ContextFlag::InstallerDownloadOnly);\r\n\r\n        return Execution::OrchestratorQueueItemFactory::CreateItemForDownload(std::wstring{ package.Id() }, std::wstring{ packageVersionInfo.PackageCatalog().Info().Id() }, std::move(comContext));\r\n    }\r\n\r\n    std::unique_ptr<Execution::OrchestratorQueueItem> CreateQueueItemForRepair(\r\n        std::unique_ptr<::AppInstaller::CLI::Execution::COMContext> comContext,\r\n        winrt::Microsoft::Management::Deployment::CatalogPackage package)\r\n    {\r\n        // Add installed version\r\n        AddInstalledVersionToContext(package.InstalledVersion(), comContext.get());\r\n\r\n        // Add Package which is used to co-relate installed package with available package for repair\r\n        winrt::Microsoft::Management::Deployment::implementation::CatalogPackage* catalogPackageImpl = get_self<winrt::Microsoft::Management::Deployment::implementation::CatalogPackage>(package);\r\n        std::shared_ptr<::AppInstaller::Repository::ICompositePackage> internalPackage = catalogPackageImpl->GetRepositoryPackage();\r\n        comContext->Add<AppInstaller::CLI::Execution::Data::Package>(internalPackage);\r\n\r\n        comContext->SetFlags(AppInstaller::CLI::Execution::ContextFlag::InstallerExecutionUseRepair);\r\n\r\n        return Execution::OrchestratorQueueItemFactory::CreateItemForRepair(std::wstring{ package.Id() }, std::wstring{ package.InstalledVersion().PackageCatalog().Info().Id() }, std::move(comContext));\r\n    }\r\n\r\n    template <typename TResult, typename TProgress, typename TOptions, typename TProgressState>\r\n    winrt::Windows::Foundation::IAsyncOperationWithProgress<TResult, TProgress> GetPackageOperation(\r\n        bool canCancelQueueItem,\r\n        std::shared_ptr<Execution::OrchestratorQueueItem> queueItemParam,\r\n        winrt::Microsoft::Management::Deployment::CatalogPackage package = nullptr,\r\n        TOptions options = nullptr,\r\n        std::wstring callerProcessInfoString = {},\r\n        bool isUpgrade = false)\r\n    {\r\n        winrt::hresult terminationHR = S_OK;\r\n        uint32_t operationError = 0;\r\n        hstring correlationData = (options) ? options.CorrelationData() : L\"\";\r\n        ::Workflow::ExecutionStage executionStage = ::Workflow::ExecutionStage::Initial;\r\n\r\n        try\r\n        {\r\n            // re-scope the parameter to inside the try block to avoid lifetime management issues.\r\n            std::shared_ptr<Execution::OrchestratorQueueItem> queueItem = std::move(queueItemParam);\r\n\r\n            auto report_progress{ co_await winrt::get_progress_token() };\r\n            auto cancellationToken{ co_await winrt::get_cancellation_token() };\r\n            // co_await does not guarantee that it's on a background thread, so do so explicitly.\r\n            co_await winrt::resume_background();\r\n\r\n            if (queueItem == nullptr)\r\n            {\r\n                std::unique_ptr<COMContext> comContext = CreateContextFromOperationOptions<TOptions>(options, callerProcessInfoString);\r\n\r\n                if constexpr (std::is_same_v<TOptions, winrt::Microsoft::Management::Deployment::InstallOptions>)\r\n                {\r\n                    queueItem = CreateQueueItemForInstall(std::move(comContext), package, options, isUpgrade);\r\n                }\r\n                else if constexpr (std::is_same_v<TOptions, winrt::Microsoft::Management::Deployment::UninstallOptions>)\r\n                {\r\n                    queueItem = CreateQueueItemForUninstall(std::move(comContext), package);\r\n                }\r\n                else if constexpr (std::is_same_v<TOptions, winrt::Microsoft::Management::Deployment::DownloadOptions>)\r\n                {\r\n                    queueItem = CreateQueueItemForDownload(std::move(comContext), package, options);\r\n                }\r\n                else if constexpr (std::is_same_v<TOptions, winrt::Microsoft::Management::Deployment::RepairOptions>)\r\n                {\r\n                    queueItem = CreateQueueItemForRepair(std::move(comContext), package);\r\n                }\r\n\r\n                Execution::ContextOrchestrator::Instance().EnqueueAndRunItem(queueItem);\r\n\r\n                if constexpr (std::is_same_v<TProgress, winrt::Microsoft::Management::Deployment::PackageInstallProgressState>)\r\n                {\r\n                    TProgress queuedProgress{ TProgressState::Queued, 0, 0, 0 };\r\n                    report_progress(queuedProgress);\r\n                }\r\n                else if constexpr (std::is_same_v<TProgress, winrt::Microsoft::Management::Deployment::PackageUninstallProgressState>)\r\n                {\r\n                    TProgress queuedProgress{ TProgressState::Queued, 0 };\r\n                    report_progress(queuedProgress);\r\n                }\r\n                else if constexpr (std::is_same_v<TProgress, winrt::Microsoft::Management::Deployment::PackageDownloadProgressState>)\r\n                {\r\n                    TProgress queuedProgress{ TProgressState::Queued, 0 };\r\n                    report_progress(queuedProgress);\r\n                }\r\n                else if constexpr (std::is_same_v<TProgress, winrt::Microsoft::Management::Deployment::PackageRepairProgressState>)\r\n                {\r\n                    TProgress queuedProgress{ TProgressState::Queued, 0 };\r\n                    report_progress(queuedProgress);\r\n                }\r\n            }\r\n            {\r\n                // correlation data is not passed in when retrieving an existing queue item, so get it from the existing context.\r\n                correlationData = hstring(queueItem->GetContext().GetCorrelationJson());\r\n            }\r\n\r\n            wil::unique_event progressEvent{ wil::EventOptions::None };\r\n\r\n            std::atomic<TProgress> operationProgress;\r\n            queueItem->GetContext().AddProgressCallbackFunction([&operationProgress, &progressEvent](\r\n                ReportType reportType,\r\n                uint64_t current,\r\n                uint64_t maximum,\r\n                ::AppInstaller::ProgressType progressType,\r\n                ::Workflow::ExecutionStage executionPhase)\r\n                {\r\n                    std::optional<TProgress> operationProgressOptional = GetProgress<TProgress, TProgressState>(reportType, current, maximum, progressType, executionPhase);\r\n                    if (operationProgressOptional.has_value())\r\n                    {\r\n                        operationProgress = operationProgressOptional.value();\r\n                        progressEvent.SetEvent();\r\n                    }\r\n                    return;\r\n                }\r\n            );\r\n\r\n            std::weak_ptr<Execution::OrchestratorQueueItem> weakQueueItem(queueItem);\r\n            cancellationToken.callback([weakQueueItem, &canCancelQueueItem]\r\n                {\r\n                    if (canCancelQueueItem)\r\n                    {\r\n                        auto strongQueueItem = weakQueueItem.lock();\r\n                        if (strongQueueItem) {\r\n                            // The cancellation of the AsyncOperation on the client triggers Cancel which causes the Execute to end.\r\n                            Execution::ContextOrchestrator::Instance().CancelQueueItem(*strongQueueItem);\r\n                        }\r\n                    }\r\n                });\r\n\r\n            // Wait for completion or progress events.\r\n            // Waiting for both on the same thread ensures that progress is never reported after the async operation itself has completed.\r\n            bool completionEventFired = false;\r\n            HANDLE operationEvents[2];\r\n            operationEvents[0] = progressEvent.get();\r\n            operationEvents[1] = queueItem->GetCompletedEvent().get();\r\n            while (!completionEventFired)\r\n            {\r\n                DWORD dwEvent = WaitForMultipleObjects(\r\n                    _countof(operationEvents) /* number of events */,\r\n                    operationEvents /* event array */,\r\n                    FALSE /* bWaitAll, FALSE to wake on any event */,\r\n                    INFINITE /* wait until operation completion */);\r\n\r\n                switch (dwEvent)\r\n                {\r\n                    // operationEvents[0] was signaled, progress\r\n                case WAIT_OBJECT_0 + 0:\r\n                    // The report_progress call will hang when making callbacks to suspended processes so it's important that this is now on a background thread.\r\n                    // Progress events are not queued - some will be missed if multiple progress events are fired from the ComContext to the callback \r\n                    // while the report_progress call is hung\\in progress.\r\n                    // Duplicate progress events can be fired if another progress event comes from the ComContext to the callback after the listener\r\n                    // has been awaked, but before it has gotten the installProgress.\r\n                    report_progress(operationProgress);\r\n                    break;\r\n\r\n                    // operationEvents[1] was signaled, operation completed\r\n                case WAIT_OBJECT_0 + 1:\r\n                    completionEventFired = true;\r\n                    break;\r\n\r\n                    // Return value is invalid.\r\n                default:\r\n                    THROW_LAST_ERROR();\r\n                }\r\n            }\r\n\r\n            if (completionEventFired)\r\n            {\r\n                // The install command has finished, check for success/failure and how far it got.\r\n                terminationHR = queueItem->GetContext().GetTerminationHR();\r\n                executionStage = queueItem->GetContext().GetExecutionStage();\r\n                if (queueItem->GetContext().Contains(Data::OperationReturnCode))\r\n                {\r\n                    operationError = static_cast<uint32_t>(queueItem->GetContext().Get<Data::OperationReturnCode>());\r\n                }\r\n            }\r\n        }\r\n        WINGET_CATCH_STORE(terminationHR, APPINSTALLER_CLI_ERROR_COMMAND_FAILED);\r\n\r\n        // TODO - RebootRequired not yet populated, msi arguments not returned from Execute.\r\n        co_return GetOperationResult<TResult>(executionStage, terminationHR, operationError, correlationData, false);\r\n    }\r\n\r\n    template <typename TResult, typename TProgress>\r\n    winrt::Windows::Foundation::IAsyncOperationWithProgress<TResult, TProgress> GetEmptyAsynchronousResultForOperation(\r\n        HRESULT hr,\r\n        hstring correlationData)\r\n    {\r\n        // If a function uses co_await or co_return (i.e. if it is a co_routine), it cannot use return directly.\r\n        // This helper helps a function that is not a coroutine itself to return errors asynchronously.\r\n        co_return GetOperationResult<TResult>(::Workflow::ExecutionStage::Initial, hr, 0, correlationData, false);\r\n    }\r\n\r\n#define WINGET_RETURN_INSTALL_RESULT_HR_IF(hr, boolVal) { if(boolVal) { return GetEmptyAsynchronousResultForOperation<Deployment::InstallResult, Deployment::InstallProgress>(hr, correlationData); }}\r\n#define WINGET_RETURN_INSTALL_RESULT_HR_IF_FAILED(hr) { WINGET_RETURN_INSTALL_RESULT_HR_IF(hr, FAILED(hr)) }\r\n\r\n    winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Microsoft::Management::Deployment::InstallResult, winrt::Microsoft::Management::Deployment::InstallProgress> PackageManager::InstallPackageAsync(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::InstallOptions options)\r\n    {\r\n        hstring correlationData = (options) ? options.CorrelationData() : L\"\";\r\n\r\n        // options and catalog can both be null, package must be set.\r\n        WINGET_RETURN_INSTALL_RESULT_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS, !package);\r\n\r\n        HRESULT hr = S_OK;\r\n        std::wstring callerProcessInfoString;\r\n        try\r\n        {\r\n            // Check for permissions and get caller info for telemetry.\r\n            // This must be done before any co_awaits since it requires info from the rpc caller thread.\r\n            auto [hrGetCallerId, callerProcessId] = GetCallerProcessId();\r\n            WINGET_RETURN_INSTALL_RESULT_HR_IF_FAILED(hrGetCallerId);\r\n            WINGET_RETURN_INSTALL_RESULT_HR_IF_FAILED(EnsureProcessHasCapability(Capability::PackageManagement, callerProcessId));\r\n            callerProcessInfoString = TryGetCallerProcessInfo(callerProcessId);\r\n        }\r\n        WINGET_CATCH_STORE(hr, APPINSTALLER_CLI_ERROR_COMMAND_FAILED);\r\n        WINGET_RETURN_INSTALL_RESULT_HR_IF_FAILED(hr);\r\n\r\n        return GetPackageOperation<Deployment::InstallResult, Deployment::InstallProgress, Deployment::InstallOptions, Deployment::PackageInstallProgressState>(\r\n            true /*canCancelQueueItem*/, nullptr /*queueItem*/, package, options, std::move(callerProcessInfoString));\r\n    }\r\n\r\n    winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Microsoft::Management::Deployment::InstallResult, winrt::Microsoft::Management::Deployment::InstallProgress> PackageManager::UpgradePackageAsync(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::InstallOptions options)\r\n    {\r\n        hstring correlationData = (options) ? options.CorrelationData() : L\"\";\r\n\r\n        // options and catalog can both be null, package must be set.\r\n        WINGET_RETURN_INSTALL_RESULT_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS, !package);\r\n        // the package should have an installed version to be upgraded.\r\n        WINGET_RETURN_INSTALL_RESULT_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS, !package.InstalledVersion());\r\n\r\n        HRESULT hr = S_OK;\r\n        std::wstring callerProcessInfoString;\r\n        try\r\n        {\r\n            // Check for permissions and get caller info for telemetry.\r\n            // This must be done before any co_awaits since it requires info from the rpc caller thread.\r\n            auto [hrGetCallerId, callerProcessId] = GetCallerProcessId();\r\n            WINGET_RETURN_INSTALL_RESULT_HR_IF_FAILED(hrGetCallerId);\r\n            WINGET_RETURN_INSTALL_RESULT_HR_IF_FAILED(EnsureProcessHasCapability(Capability::PackageManagement, callerProcessId));\r\n            callerProcessInfoString = TryGetCallerProcessInfo(callerProcessId);\r\n        }\r\n        WINGET_CATCH_STORE(hr, APPINSTALLER_CLI_ERROR_COMMAND_FAILED);\r\n        WINGET_RETURN_INSTALL_RESULT_HR_IF_FAILED(hr);\r\n\r\n        return GetPackageOperation<Deployment::InstallResult, Deployment::InstallProgress, Deployment::InstallOptions, Deployment::PackageInstallProgressState>(\r\n            true /*canCancelQueueItem*/, nullptr /*queueItem*/, package, options, std::move(callerProcessInfoString), true /* isUpgrade */);\r\n    }\r\n\r\n    winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Microsoft::Management::Deployment::InstallResult, winrt::Microsoft::Management::Deployment::InstallProgress> PackageManager::GetInstallProgress(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::PackageCatalogInfo catalogInfo)\r\n    {\r\n        hstring correlationData;\r\n        WINGET_RETURN_INSTALL_RESULT_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS, !package);\r\n\r\n        HRESULT hr = S_OK;\r\n        std::shared_ptr<Execution::OrchestratorQueueItem> queueItem = nullptr;\r\n        bool canCancelQueueItem = false;\r\n        try\r\n        {\r\n            // Check for permissions\r\n            // This must be done before any co_awaits since it requires info from the rpc caller thread.\r\n            auto [hrGetCallerId, callerProcessId] = GetCallerProcessId();\r\n            WINGET_RETURN_INSTALL_RESULT_HR_IF_FAILED(hrGetCallerId);\r\n            canCancelQueueItem = SUCCEEDED(EnsureProcessHasCapability(Capability::PackageManagement, callerProcessId));\r\n            if (!canCancelQueueItem)\r\n            {\r\n                WINGET_RETURN_INSTALL_RESULT_HR_IF_FAILED(EnsureProcessHasCapability(Capability::PackageQuery, callerProcessId));\r\n            }\r\n\r\n            // Get the queueItem synchronously.\r\n            queueItem = GetExistingQueueItemForPackage(package, catalogInfo);\r\n            if (queueItem == nullptr ||\r\n                (queueItem->GetPackageOperationType() != PackageOperationType::Install && queueItem->GetPackageOperationType() != PackageOperationType::Upgrade))\r\n            {\r\n                return nullptr;\r\n            }\r\n        }\r\n        WINGET_CATCH_STORE(hr, APPINSTALLER_CLI_ERROR_COMMAND_FAILED);\r\n        WINGET_RETURN_INSTALL_RESULT_HR_IF_FAILED(hr);\r\n\r\n        return GetPackageOperation<Deployment::InstallResult, Deployment::InstallProgress, Deployment::InstallOptions, Deployment::PackageInstallProgressState>(\r\n            canCancelQueueItem, std::move(queueItem));\r\n    }\r\n\r\n#define WINGET_RETURN_UNINSTALL_RESULT_HR_IF(hr, boolVal) { if(boolVal) { return GetEmptyAsynchronousResultForOperation<Deployment::UninstallResult, Deployment::UninstallProgress>(hr, correlationData); }}\r\n#define WINGET_RETURN_UNINSTALL_RESULT_HR_IF_FAILED(hr) { WINGET_RETURN_UNINSTALL_RESULT_HR_IF(hr, FAILED(hr)) }\r\n\r\n    winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Microsoft::Management::Deployment::UninstallResult, winrt::Microsoft::Management::Deployment::UninstallProgress> PackageManager::UninstallPackageAsync(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::UninstallOptions options)\r\n    {\r\n        hstring correlationData = (options) ? options.CorrelationData() : L\"\";\r\n\r\n        // options and catalog can both be null, package must be set.\r\n        WINGET_RETURN_UNINSTALL_RESULT_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS, !package);\r\n        // the package should have an installed version to be uninstalled.\r\n        WINGET_RETURN_UNINSTALL_RESULT_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS, !package.InstalledVersion());\r\n\r\n        HRESULT hr = S_OK;\r\n        std::wstring callerProcessInfoString;\r\n        try\r\n        {\r\n            // Check for permissions and get caller info for telemetry.\r\n            // This must be done before any co_awaits since it requires info from the rpc caller thread.\r\n            auto [hrGetCallerId, callerProcessId] = GetCallerProcessId();\r\n            WINGET_RETURN_UNINSTALL_RESULT_HR_IF_FAILED(hrGetCallerId);\r\n            WINGET_RETURN_UNINSTALL_RESULT_HR_IF_FAILED(EnsureProcessHasCapability(Capability::PackageManagement, callerProcessId));\r\n            callerProcessInfoString = TryGetCallerProcessInfo(callerProcessId);\r\n        }\r\n        WINGET_CATCH_STORE(hr, APPINSTALLER_CLI_ERROR_COMMAND_FAILED);\r\n        WINGET_RETURN_UNINSTALL_RESULT_HR_IF_FAILED(hr);\r\n\r\n        return GetPackageOperation<Deployment::UninstallResult, Deployment::UninstallProgress, Deployment::UninstallOptions, Deployment::PackageUninstallProgressState>(\r\n            true /*canCancelQueueItem*/, nullptr /*queueItem*/, package, options, std::move(callerProcessInfoString));\r\n    }\r\n\r\n    winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Microsoft::Management::Deployment::UninstallResult, winrt::Microsoft::Management::Deployment::UninstallProgress> PackageManager::GetUninstallProgress(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::PackageCatalogInfo catalogInfo)\r\n    {\r\n        hstring correlationData;\r\n        WINGET_RETURN_UNINSTALL_RESULT_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS, !package);\r\n\r\n        HRESULT hr = S_OK;\r\n        std::shared_ptr<Execution::OrchestratorQueueItem> queueItem = nullptr;\r\n        bool canCancelQueueItem = false;\r\n        try\r\n        {\r\n            // Check for permissions\r\n            // This must be done before any co_awaits since it requires info from the rpc caller thread.\r\n            auto [hrGetCallerId, callerProcessId] = GetCallerProcessId();\r\n            WINGET_RETURN_UNINSTALL_RESULT_HR_IF_FAILED(hrGetCallerId);\r\n            canCancelQueueItem = SUCCEEDED(EnsureProcessHasCapability(Capability::PackageManagement, callerProcessId));\r\n            if (!canCancelQueueItem)\r\n            {\r\n                WINGET_RETURN_UNINSTALL_RESULT_HR_IF_FAILED(EnsureProcessHasCapability(Capability::PackageQuery, callerProcessId));\r\n            }\r\n\r\n            // Get the queueItem synchronously.\r\n            queueItem = GetExistingQueueItemForPackage(package, catalogInfo);\r\n            if (queueItem == nullptr ||\r\n                queueItem->GetPackageOperationType() != PackageOperationType::Uninstall)\r\n            {\r\n                return nullptr;\r\n            }\r\n        }\r\n        WINGET_CATCH_STORE(hr, APPINSTALLER_CLI_ERROR_COMMAND_FAILED);\r\n        WINGET_RETURN_UNINSTALL_RESULT_HR_IF_FAILED(hr);\r\n\r\n        return GetPackageOperation<Deployment::UninstallResult, Deployment::UninstallProgress, Deployment::UninstallOptions, Deployment::PackageUninstallProgressState>(\r\n            canCancelQueueItem, std::move(queueItem));\r\n    }\r\n\r\n#define WINGET_RETURN_DOWNLOAD_RESULT_HR_IF(hr, boolVal) { if(boolVal) { return GetEmptyAsynchronousResultForOperation<Deployment::DownloadResult, Deployment::PackageDownloadProgress>(hr, correlationData); }}\r\n#define WINGET_RETURN_DOWNLOAD_RESULT_HR_IF_FAILED(hr) { WINGET_RETURN_DOWNLOAD_RESULT_HR_IF(hr, FAILED(hr)) }\r\n\r\n    winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Microsoft::Management::Deployment::DownloadResult, winrt::Microsoft::Management::Deployment::PackageDownloadProgress> PackageManager::DownloadPackageAsync(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::DownloadOptions options)\r\n    {\r\n        hstring correlationData = (options) ? options.CorrelationData() : L\"\";\r\n\r\n        // options and catalog can both be null, package must be set.\r\n        WINGET_RETURN_DOWNLOAD_RESULT_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS, !package);\r\n\r\n        HRESULT hr = S_OK;\r\n        std::wstring callerProcessInfoString;\r\n        try\r\n        {\r\n            // Check for permissions and get caller info for telemetry.\r\n            // This must be done before any co_awaits since it requires info from the rpc caller thread.\r\n            auto [hrGetCallerId, callerProcessId] = GetCallerProcessId();\r\n            WINGET_RETURN_DOWNLOAD_RESULT_HR_IF_FAILED(hrGetCallerId);\r\n            WINGET_RETURN_DOWNLOAD_RESULT_HR_IF_FAILED(EnsureComCallerHasCapability(Capability::PackageQuery));\r\n            callerProcessInfoString = TryGetCallerProcessInfo(callerProcessId);\r\n        }\r\n        WINGET_CATCH_STORE(hr, APPINSTALLER_CLI_ERROR_COMMAND_FAILED);\r\n        WINGET_RETURN_DOWNLOAD_RESULT_HR_IF_FAILED(hr);\r\n\r\n        return GetPackageOperation<Deployment::DownloadResult, Deployment::PackageDownloadProgress, Deployment::DownloadOptions, Deployment::PackageDownloadProgressState>(\r\n            true /*canCancelQueueItem*/, nullptr /*queueItem*/, package, options, std::move(callerProcessInfoString));\r\n    }\r\n\r\n    winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Microsoft::Management::Deployment::DownloadResult, winrt::Microsoft::Management::Deployment::PackageDownloadProgress> PackageManager::GetDownloadProgress(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::PackageCatalogInfo catalogInfo)\r\n    {\r\n        hstring correlationData;\r\n        WINGET_RETURN_DOWNLOAD_RESULT_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS, !package);\r\n\r\n        HRESULT hr = S_OK;\r\n        std::shared_ptr<Execution::OrchestratorQueueItem> queueItem = nullptr;\r\n        try\r\n        {\r\n            WINGET_RETURN_DOWNLOAD_RESULT_HR_IF_FAILED(EnsureComCallerHasCapability(Capability::PackageQuery));\r\n\r\n            // Get the queueItem synchronously.\r\n            queueItem = GetExistingQueueItemForPackage(package, catalogInfo);\r\n            if (queueItem == nullptr ||\r\n                queueItem->GetPackageOperationType() != PackageOperationType::Download)\r\n            {\r\n                return nullptr;\r\n            }\r\n        }\r\n        WINGET_CATCH_STORE(hr, APPINSTALLER_CLI_ERROR_COMMAND_FAILED);\r\n        WINGET_RETURN_DOWNLOAD_RESULT_HR_IF_FAILED(hr);\r\n\r\n        return GetPackageOperation<Deployment::DownloadResult, Deployment::PackageDownloadProgress, Deployment::DownloadOptions, Deployment::PackageDownloadProgressState>(true, std::move(queueItem));\r\n    }\r\n\r\n#define WINGET_RETURN_REPAIR_RESULT_HR_IF(hr, boolVal) { if(boolVal) { return GetEmptyAsynchronousResultForOperation<Deployment::RepairResult, Deployment::RepairProgress>(hr, correlationData); }}\r\n#define WINGET_RETURN_REPAIR_RESULT_HR_IF_FAILED(hr) { WINGET_RETURN_REPAIR_RESULT_HR_IF(hr, FAILED(hr)) }\r\n\r\n    winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Microsoft::Management::Deployment::RepairResult, winrt::Microsoft::Management::Deployment::RepairProgress> PackageManager::RepairPackageAsync(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::RepairOptions options)\r\n    {\r\n        hstring correlationData = (options) ? options.CorrelationData() : L\"\";\r\n\r\n        // options and catalog can both be null, package must be set.\r\n        WINGET_RETURN_REPAIR_RESULT_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS, !package);\r\n        // the package should have an installed version to be repaired.\r\n        WINGET_RETURN_REPAIR_RESULT_HR_IF(APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS, !package.InstalledVersion());\r\n\r\n        HRESULT hr = S_OK;\r\n        std::wstring callerProcessInfoString;\r\n        try\r\n        {\r\n            // Check for permissions and get caller info for telemetry.\r\n            // This must be done before any co_awaits since it requires info from the rpc caller thread.\r\n            auto [hrGetCallerId, callerProcessId] = GetCallerProcessId();\r\n            WINGET_RETURN_REPAIR_RESULT_HR_IF_FAILED(hrGetCallerId);\r\n            WINGET_RETURN_REPAIR_RESULT_HR_IF_FAILED(EnsureProcessHasCapability(Capability::PackageManagement, callerProcessId));\r\n            callerProcessInfoString = TryGetCallerProcessInfo(callerProcessId);\r\n        }\r\n        WINGET_CATCH_STORE(hr, APPINSTALLER_CLI_ERROR_COMMAND_FAILED);\r\n        WINGET_RETURN_REPAIR_RESULT_HR_IF_FAILED(hr);\r\n\r\n        return GetPackageOperation<Deployment::RepairResult, Deployment::RepairProgress, Deployment::RepairOptions, Deployment::PackageRepairProgressState>(\r\n            true /*canCancelQueueItem*/, nullptr /*queueItem*/, package, options, std::move(callerProcessInfoString));\r\n    }\r\n\r\n    winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Microsoft::Management::Deployment::AddPackageCatalogResult, double> PackageManager::AddPackageCatalogAsync(winrt::Microsoft::Management::Deployment::AddPackageCatalogOptions options)\r\n    {\r\n        LogStartupIfApplicable();\r\n\r\n        // options must be set.\r\n        THROW_HR_IF_NULL(E_POINTER, options);\r\n        THROW_HR_IF(E_INVALIDARG, options.Name().empty());\r\n        THROW_HR_IF(E_INVALIDARG, options.SourceUri().empty());\r\n\r\n        HRESULT terminationHR = S_OK;\r\n        try {\r\n\r\n            // Check if running as admin/system.\r\n            // [NOTE:] For OutOfProc calls, the Windows Package Manager Service executes in the context initiated by the caller process,\r\n            // so the same admin/system validation check is applicable for both InProc and OutOfProc calls.\r\n            THROW_HR_IF(APPINSTALLER_CLI_ERROR_COMMAND_REQUIRES_ADMIN, !AppInstaller::Runtime::IsRunningAsAdminOrSystem());\r\n\r\n            ::AppInstaller::Repository::Source sourceToAdd = CreateSourceFromOptions(options);\r\n\r\n            auto strong_this = get_strong();\r\n            auto report_progress{ co_await winrt::get_progress_token() };\r\n            co_await winrt::resume_background();\r\n\r\n            std::string type = winrt::to_string(options.Type());\r\n            auto packageCatalogProgressSink = winrt::Microsoft::Management::Deployment::ProgressSinkFactory::CreatePackageCatalogProgressSink(type, report_progress );\r\n\r\n            packageCatalogProgressSink->BeginProgress();\r\n            ::AppInstaller::ProgressCallback progress(packageCatalogProgressSink.get());\r\n            sourceToAdd.Add(progress);\r\n            packageCatalogProgressSink->EndProgress(false);\r\n        }\r\n        catch (...)\r\n        {\r\n            terminationHR = AppInstaller::CLI::Workflow::HandleException(nullptr, std::current_exception());\r\n        }\r\n\r\n        co_return GetAddPackageCatalogResult(terminationHR);\r\n    }\r\n\r\n    winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Microsoft::Management::Deployment::RemovePackageCatalogResult, double> PackageManager::RemovePackageCatalogAsync(winrt::Microsoft::Management::Deployment::RemovePackageCatalogOptions options)\r\n    {\r\n        LogStartupIfApplicable();\r\n\r\n        // options must be set.\r\n        THROW_HR_IF_NULL(E_POINTER, options);\r\n        THROW_HR_IF(E_INVALIDARG, options.Name().empty());\r\n\r\n        HRESULT terminationHR = S_OK;\r\n        try {\r\n\r\n            // Check if running as admin/system.\r\n            // [NOTE:] For OutOfProc calls, the Windows Package Manager Service executes in the context initiated by the caller process,\r\n            // so the same admin/system validation check is applicable for both InProc and OutOfProc calls.\r\n            THROW_HR_IF(APPINSTALLER_CLI_ERROR_COMMAND_REQUIRES_ADMIN, !AppInstaller::Runtime::IsRunningAsAdminOrSystem());\r\n\r\n            auto matchingSource = GetMatchingSource(winrt::to_string(options.Name()));\r\n            THROW_HR_IF(APPINSTALLER_CLI_ERROR_SOURCE_NAME_DOES_NOT_EXIST, !matchingSource.has_value());\r\n\r\n            auto strong_this = get_strong();\r\n            auto report_progress{ co_await winrt::get_progress_token() };\r\n            co_await winrt::resume_background();\r\n\r\n            auto packageCatalogProgressSink = winrt::Microsoft::Management::Deployment::ProgressSinkFactory::CreatePackageCatalogProgressSink(matchingSource.value().Type, report_progress, true);\r\n\r\n            packageCatalogProgressSink->BeginProgress();\r\n            ::AppInstaller::Repository::Source sourceToRemove = ::AppInstaller::Repository::Source{ matchingSource.value().Name };\r\n            ::AppInstaller::ProgressCallback progress(packageCatalogProgressSink.get());\r\n\r\n            // If the PreserveData option is set, this is equivalent to the WinGet CLI Reset command on a single source; otherwise, it removes the source.\r\n            if (options.PreserveData())\r\n            {\r\n                THROW_HR_IF(APPINSTALLER_CLI_ERROR_SOURCE_NAME_DOES_NOT_EXIST, !sourceToRemove.DropSource(matchingSource.value().Name));\r\n            }\r\n            else\r\n            {\r\n                sourceToRemove.Remove(progress);\r\n            }\r\n            packageCatalogProgressSink->EndProgress(false);\r\n        }\r\n        catch (...)\r\n        {\r\n            terminationHR = AppInstaller::CLI::Workflow::HandleException(nullptr, std::current_exception());\r\n        }\r\n\r\n        co_return GetRemovePackageCatalogResult(terminationHR);\r\n    }\r\n\r\n    winrt::hstring PackageManager::Version() const\r\n    {\r\n        return winrt::hstring{ AppInstaller::Utility::ConvertToUTF16(AppInstaller::Runtime::GetClientVersion()) };\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::EditPackageCatalogResult GetEditPackageCatalogResult(winrt::hresult terminationStatus)\r\n    {\r\n        winrt::Microsoft::Management::Deployment::EditPackageCatalogStatus status = GetPackageCatalogOperationStatus<EditPackageCatalogStatus>(terminationStatus);\r\n        auto editResult = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::EditPackageCatalogResult>>();\r\n        editResult->Initialize(status, terminationStatus);\r\n        return *editResult;\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::EditPackageCatalogResult PackageManager::EditPackageCatalog(winrt::Microsoft::Management::Deployment::EditPackageCatalogOptions options)\r\n    {\r\n        LogStartupIfApplicable();\r\n\r\n        // options must be set.\r\n        THROW_HR_IF_NULL(E_POINTER, options);\r\n        THROW_HR_IF(E_INVALIDARG, options.Name().empty());\r\n\r\n        HRESULT terminationHR = S_OK;\r\n        try {\r\n\r\n            // Check if running as admin/system.\r\n            // [NOTE:] For OutOfProc calls, the Windows Package Manager Service executes in the context initiated by the caller process,\r\n            // so the same admin/system validation check is applicable for both InProc and OutOfProc calls.\r\n            THROW_HR_IF(APPINSTALLER_CLI_ERROR_COMMAND_REQUIRES_ADMIN, !AppInstaller::Runtime::IsRunningAsAdminOrSystem());\r\n\r\n            auto matchingSource = GetMatchingSource(winrt::to_string(options.Name()));\r\n            THROW_HR_IF(APPINSTALLER_CLI_ERROR_SOURCE_NAME_DOES_NOT_EXIST, !matchingSource.has_value());\r\n            ::AppInstaller::Repository::Source sourceToEdit = ::AppInstaller::Repository::Source{ matchingSource.value().Name };\r\n\r\n            ::AppInstaller::Repository::SourceEdit edits;\r\n            edits.Explicit = options.Explicit();\r\n            edits.Priority = options.Priority();\r\n\r\n            if (sourceToEdit.RequiresChanges(edits))\r\n            {\r\n                sourceToEdit.Edit(edits);\r\n            }\r\n        }\r\n        catch (...)\r\n        {\r\n            terminationHR = AppInstaller::CLI::Workflow::HandleException(nullptr, std::current_exception());\r\n        }\r\n\r\n        return GetEditPackageCatalogResult(terminationHR);\r\n    }\r\n\r\n    CoCreatableMicrosoftManagementDeploymentClass(PackageManager);\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PackageManager.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"PackageManager.g.h\"\r\n#include \"Public/ComClsids.h\"\r\n#include <winget/ModuleCountBase.h>\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n// Forward declaration\r\nnamespace AppInstaller::CLI::Execution\r\n{\r\n    struct Context;\r\n}\r\n#endif\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    [uuid(WINGET_OUTOFPROC_COM_CLSID_PackageManager)]\r\n    struct PackageManager : PackageManagerT<PackageManager>\r\n    {\r\n        PackageManager();\r\n\r\n        winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::Management::Deployment::PackageCatalogReference> GetPackageCatalogs();\r\n        winrt::Microsoft::Management::Deployment::PackageCatalogReference GetPredefinedPackageCatalog(winrt::Microsoft::Management::Deployment::PredefinedPackageCatalog const& predefinedPackageCatalog);\r\n        winrt::Microsoft::Management::Deployment::PackageCatalogReference GetLocalPackageCatalog(winrt::Microsoft::Management::Deployment::LocalPackageCatalog const& localPackageCatalog);\r\n        winrt::Microsoft::Management::Deployment::PackageCatalogReference GetPackageCatalogByName(hstring const& catalogName);\r\n        winrt::Microsoft::Management::Deployment::PackageCatalogReference CreateCompositePackageCatalog(winrt::Microsoft::Management::Deployment::CreateCompositePackageCatalogOptions const& options);\r\n        winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Microsoft::Management::Deployment::InstallResult, winrt::Microsoft::Management::Deployment::InstallProgress> \r\n            InstallPackageAsync(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::InstallOptions options);\r\n        // Contract 2.0\r\n        winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Microsoft::Management::Deployment::InstallResult, winrt::Microsoft::Management::Deployment::InstallProgress> \r\n            GetInstallProgress(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::PackageCatalogInfo catalogInfo);\r\n        // Contract 4.0\r\n        winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Microsoft::Management::Deployment::InstallResult, winrt::Microsoft::Management::Deployment::InstallProgress>\r\n            UpgradePackageAsync(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::InstallOptions options);\r\n        winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Microsoft::Management::Deployment::UninstallResult, winrt::Microsoft::Management::Deployment::UninstallProgress>\r\n            UninstallPackageAsync(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::UninstallOptions options);\r\n        winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Microsoft::Management::Deployment::UninstallResult, winrt::Microsoft::Management::Deployment::UninstallProgress>\r\n            GetUninstallProgress(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::PackageCatalogInfo catalogInfo);\r\n        // Contract 7.0\r\n        winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Microsoft::Management::Deployment::DownloadResult, winrt::Microsoft::Management::Deployment::PackageDownloadProgress>\r\n            DownloadPackageAsync(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::DownloadOptions options);\r\n        winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Microsoft::Management::Deployment::DownloadResult, winrt::Microsoft::Management::Deployment::PackageDownloadProgress>\r\n            GetDownloadProgress(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::PackageCatalogInfo catalogInfo);\r\n        // Contract 11.0\r\n        winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Microsoft::Management::Deployment::RepairResult, winrt::Microsoft::Management::Deployment::RepairProgress>\r\n            RepairPackageAsync(winrt::Microsoft::Management::Deployment::CatalogPackage package, winrt::Microsoft::Management::Deployment::RepairOptions options);\r\n        // Contract 12.0\r\n        winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Microsoft::Management::Deployment::AddPackageCatalogResult, double>\r\n            AddPackageCatalogAsync(winrt::Microsoft::Management::Deployment::AddPackageCatalogOptions options);\r\n        winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Microsoft::Management::Deployment::RemovePackageCatalogResult, double>\r\n            RemovePackageCatalogAsync(winrt::Microsoft::Management::Deployment::RemovePackageCatalogOptions options);\r\n        // Contract 13.0\r\n        winrt::hstring Version() const;\r\n        // Contract 28.0\r\n        winrt::Microsoft::Management::Deployment::EditPackageCatalogResult EditPackageCatalog(winrt::Microsoft::Management::Deployment::EditPackageCatalogOptions options);\r\n    };\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    void SetComCallerName(std::string name);\r\n    void PopulateContextFromInstallOptions(AppInstaller::CLI::Execution::Context* context, winrt::Microsoft::Management::Deployment::InstallOptions options);\r\n#endif\r\n}\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\nnamespace winrt::Microsoft::Management::Deployment::factory_implementation\r\n{\r\n    struct PackageManager : PackageManagerT<PackageManager, implementation::PackageManager>, AppInstaller::WinRT::ModuleCountBase\r\n    {\r\n    };\r\n}\r\n#endif\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PackageManager.idl",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\nnamespace Microsoft.Management.Deployment\r\n{\r\n    [contractversion(29)] // For version 1.29\r\n    apicontract WindowsPackageManagerContract{};\r\n\r\n    /// State of the install\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum PackageInstallProgressState\r\n    {\r\n        /// The install is queued but not yet active. Cancellation of the IAsyncOperationWithProgress in this \r\n        /// state will prevent the package from downloading or installing.\r\n        Queued,\r\n        /// The installer is downloading. Cancellation of the IAsyncOperationWithProgress in this state will \r\n        /// end the download and prevent the package from installing.\r\n        Downloading,\r\n        /// The install is in progress. Cancellation of the IAsyncOperationWithProgress in this state will not\r\n        /// stop the installation or the post install cleanup.\r\n        Installing,\r\n        /// The installer has completed and cleanup actions are in progress. Cancellation of the \r\n        /// IAsyncOperationWithProgress in this state will not stop cleanup or roll back the install.\r\n        PostInstall,\r\n        /// The operation has completed.\r\n        Finished,\r\n    };\r\n\r\n    /// Progress object for the install\r\n    /// DESIGN NOTE: percentage for the install as a whole is purposefully not included as there is no way to \r\n    /// estimate progress when the installer is running.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    struct InstallProgress\r\n    {\r\n        /// State of the install\r\n        PackageInstallProgressState State;\r\n        /// DESIGN NOTE: BytesDownloaded may only be available for downloads done by Windows Package Manager itself.\r\n        /// Number of bytes downloaded if known\r\n        UInt64 BytesDownloaded;\r\n        /// DESIGN NOTE: BytesRequired may only be available for downloads done by Windows Package Manager itself.\r\n        /// Number of bytes required if known\r\n        UInt64 BytesRequired;\r\n        /// Download percentage completed\r\n        Double DownloadProgress;\r\n        /// Install percentage if known.\r\n        Double InstallationProgress;\r\n    };\r\n\r\n    /// Status of the Install call\r\n    /// Implementation Note: Errors mapped from AppInstallerErrors.h\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum InstallResultStatus\r\n    {\r\n        Ok,\r\n        BlockedByPolicy,\r\n        CatalogError,\r\n        InternalError,\r\n        InvalidOptions,\r\n        DownloadError,\r\n        InstallError,\r\n        ManifestError,\r\n        NoApplicableInstallers,\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 4)]\r\n        {\r\n            NoApplicableUpgrade,\r\n        },\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 6)]\r\n        {\r\n            PackageAgreementsNotAccepted,\r\n        }\r\n    };\r\n\r\n    /// Result of the install\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass InstallResult\r\n    {\r\n        /// Used by a caller to correlate the install with a caller's data.\r\n        String CorrelationData { get; };\r\n        /// Whether a restart is required to complete the install.\r\n        Boolean RebootRequired { get; };\r\n\r\n        /// Batched error code, example APPINSTALLER_CLI_ERROR_SHELLEXEC_INSTALL_FAILED\r\n        InstallResultStatus Status { get; };\r\n        /// The error code of the overall operation.\r\n        HRESULT ExtendedErrorCode { get; };\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 4)]\r\n        {\r\n            /// The error code from the install attempt. Only valid if the Status is InstallError.\r\n            /// This value's meaning will require knowledge of the specific installer or install technology.\r\n            UInt32 InstallerErrorCode { get; };\r\n        }\r\n    }\r\n\r\n    /// State of the uninstall\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 4)]\r\n    enum PackageUninstallProgressState\r\n    {\r\n        /// The uninstall is queued but not yet active. Cancellation of the IAsyncOperationWithProgress in this \r\n        /// state will prevent the package from uninstalling.\r\n        Queued,\r\n        /// The uninstall is in progress. Cancellation of the IAsyncOperationWithProgress in this state will not\r\n        /// stop the installation or the post uninstall steps.\r\n        Uninstalling,\r\n        /// The uninstaller has completed and cleanup actions are in progress. Cancellation of the \r\n        /// IAsyncOperationWithProgress in this state will not stop cleanup or roll back the uninstall.\r\n        PostUninstall,\r\n        /// The operation has completed.\r\n        Finished,\r\n    };\r\n\r\n    /// Progress object for the uninstall\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 4)]\r\n    struct UninstallProgress\r\n    {\r\n        /// State of the uninstall\r\n        PackageUninstallProgressState State;\r\n        /// Uninstall percentage if known.\r\n        Double UninstallationProgress;\r\n    };\r\n\r\n    /// Status of the uninstall call\r\n    /// Implementation Note: Errors mapped from AppInstallerErrors.h\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 4)]\r\n    enum UninstallResultStatus\r\n    {\r\n        Ok,\r\n        BlockedByPolicy,\r\n        CatalogError,\r\n        InternalError,\r\n        InvalidOptions,\r\n        UninstallError,\r\n        ManifestError,\r\n    };\r\n\r\n    /// Result of the uninstall\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 4)]\r\n    runtimeclass UninstallResult\r\n    {\r\n        /// Used by a caller to correlate the install with a caller's data.\r\n        String CorrelationData { get; };\r\n        /// Whether a restart is required to complete the install.\r\n        Boolean RebootRequired { get; };\r\n\r\n        /// Batched error code, example APPINSTALLER_CLI_ERROR_SHELLEXEC_INSTALL_FAILED\r\n        UninstallResultStatus Status { get; };\r\n        /// The error code of the overall operation.\r\n        HRESULT ExtendedErrorCode { get; };\r\n\r\n        /// The error code from the uninstall attempt. Only valid if the Status is UninstallError.\r\n        /// This value's meaning will require knowledge of the specific uninstaller or install technology.\r\n        UInt32 UninstallerErrorCode { get; };\r\n    }\r\n\r\n    /// State of the repair\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 11)]\r\n    enum PackageRepairProgressState\r\n    {\r\n        /// The repair is queued but not yet active. Cancellation of the IAsyncOperationWithProgress in this \r\n        /// state will prevent the package from repairing.\r\n        Queued,\r\n        /// The repair is in progress. Cancellation of the IAsyncOperationWithProgress in this state will not\r\n        /// stop the repair or the post repair steps.\r\n        Repairing,\r\n        /// The repair has completed and cleanup actions are in progress. Cancellation of the \r\n        /// IAsyncOperationWithProgress in this state will not stop cleanup or roll back the repair.\r\n        PostRepair,\r\n        /// The operation has completed.\r\n        Finished,\r\n    };\r\n\r\n    /// Progress object for the repair\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 11)]\r\n    struct RepairProgress\r\n    {\r\n        /// State of the repair\r\n        PackageRepairProgressState State;\r\n\r\n        /// Repair percentage if known.\r\n        Double RepairCompletionProgress;\r\n    };\r\n\r\n    /// Status of the repair call\r\n    /// Implementation Note: Errors mapped from AppInstallerErrors.h\r\n    /// DESIGN NOTE: RepairResultStatus from AppInstallerErrors.h is not implemented in V1.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 11)]\r\n    enum RepairResultStatus\r\n    {\r\n        Ok,\r\n        BlockedByPolicy,\r\n        CatalogError,\r\n        DownloadError,\r\n        InternalError,\r\n        InvalidOptions,\r\n        RepairError,\r\n        ManifestError,\r\n        NoApplicableRepairer,\r\n        PackageAgreementsNotAccepted,\r\n    };\r\n\r\n    /// Result of the repair\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 11)]\r\n    runtimeclass RepairResult\r\n    {\r\n       /// Used by a caller to correlate the repair with a caller's data.\r\n       String CorrelationData { get; };\r\n\r\n       /// Whether a restart is required to complete the repair.\r\n       Boolean RebootRequired { get; };\r\n\r\n       /// Batched error code, example APPINSTALLER_CLI_ERROR_SHELLEXEC_INSTALL_FAILED\r\n       RepairResultStatus Status { get; };\r\n\r\n       /// The error code of the overall operation.\r\n       HRESULT ExtendedErrorCode { get; };\r\n\r\n       /// The error code from the repair attempt. Only valid if the Status is RepairError.\r\n       /// This value's meaning will require knowledge of the specific repairer or repair technology.\r\n       UInt32 RepairerErrorCode { get; };\r\n     }\r\n\r\n    /// State of the download\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 7)]\r\n    enum PackageDownloadProgressState\r\n    {\r\n        /// The download is queued but not yet active. Cancellation of the IAsyncOperationWithProgress in this \r\n        /// state will prevent the package from downloading.\r\n        Queued,\r\n        /// The installer is downloading. Cancellation of the IAsyncOperationWithProgress in this state will \r\n        /// end the download.\r\n        Downloading,\r\n        /// The operation has completed.\r\n        Finished,\r\n    };\r\n\r\n    /// Status of the download call\r\n    /// Implementation Note: Errors mapped from AppInstallerErrors.h\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 7)]\r\n    enum DownloadResultStatus\r\n    {\r\n        Ok,\r\n        BlockedByPolicy,\r\n        CatalogError,\r\n        InternalError,\r\n        InvalidOptions,\r\n        DownloadError,\r\n        ManifestError,\r\n        NoApplicableInstallers,\r\n        PackageAgreementsNotAccepted,\r\n    };\r\n\r\n    /// Result of the download\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 7)]\r\n    runtimeclass DownloadResult\r\n    {\r\n        /// Used by a caller to correlate the download with a caller's data.\r\n        String CorrelationData { get; };\r\n\r\n        /// Batched error code.\r\n        DownloadResultStatus Status { get; };\r\n\r\n        /// The error code of the overall operation.\r\n        HRESULT ExtendedErrorCode { get; };\r\n    };\r\n\r\n    /// Progress object for the uninstall\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 7)]\r\n    struct PackageDownloadProgress\r\n    {\r\n        /// State of the download\r\n        PackageDownloadProgressState State;\r\n\r\n        /// DESIGN NOTE: BytesDownloaded may only be available for downloads done by Windows Package Manager itself.\r\n        /// Number of bytes downloaded if known\r\n        UInt64 BytesDownloaded;\r\n\r\n        /// DESIGN NOTE: BytesRequired may only be available for downloads done by Windows Package Manager itself.\r\n        /// Number of bytes required if known\r\n        UInt64 BytesRequired;\r\n\r\n        /// Download percentage completed\r\n        Double DownloadProgress;\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: SourceOrigin from winget/RepositorySource.h\r\n    /// Defines the origin of the package catalog details.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum PackageCatalogOrigin\r\n    {\r\n        /// Predefined means it came as part of the Windows Package Manager package and cannot be removed.\r\n        Predefined,\r\n        /// User means it was added by the user and could be removed.\r\n        User,\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: SourceTrustLevel from winget/RepositorySource.h\r\n    /// Defines the trust level of the package catalog.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum PackageCatalogTrustLevel\r\n    {\r\n        None,\r\n        Trusted,\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: SourceDetails from winget/RepositorySource.h\r\n    /// Interface for retrieving information about an package catalog without acting on it.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass PackageCatalogInfo\r\n    {\r\n        /// The package catalog's unique identifier. \r\n        /// SAMPLE VALUES: For OpenWindowsCatalog \"Microsoft.Winget.Source_8wekyb3d8bbwe\"\r\n        /// For contoso sample on msdn \"contoso\"\r\n        String Id { get; };\r\n        /// The name of the package catalog. \r\n        /// SAMPLE VALUES: For OpenWindowsCatalog \"winget\".\r\n        /// For contoso sample on msdn \"contoso\"\r\n        String Name { get; };\r\n        /// The type of the package catalog.\r\n        /// ALLOWED VALUES: \"Microsoft.Rest\", \"Microsoft.PreIndexed.Package\"\r\n        /// SAMPLE VALUES: For OpenWindowsCatalog \"Microsoft.PreIndexed.Package\".\r\n        /// For contoso sample on msdn \"Microsoft.PreIndexed.Package\"\r\n        String Type { get; };\r\n        /// The argument used when adding the package catalog.\r\n        /// SAMPLE VALUES: For OpenWindowsCatalog \"https://winget.azureedge.net/cache\"\r\n        /// For contoso sample on msdn \"https://pkgmgr-int.azureedge.net/cache\"\r\n        String Argument { get; };\r\n        /// The last time that this package catalog was updated.\r\n        Windows.Foundation.DateTime LastUpdateTime { get; };\r\n        /// The origin of the package catalog.\r\n        PackageCatalogOrigin Origin { get; };\r\n        /// The trust level of the package catalog\r\n        PackageCatalogTrustLevel TrustLevel { get; };\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 11)]\r\n        {\r\n            /// Excludes a source from discovery unless specified.\r\n            Boolean Explicit{ get; };\r\n        }\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 29)]\r\n        {\r\n            /// The priority of this catalog. Higher values are sorted first.\r\n            Int32 Priority{ get; };\r\n        }\r\n    }\r\n\r\n    /// A metadata item of a package version.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum PackageVersionMetadataField\r\n    {\r\n        /// The InstallerType of an installed package\r\n        InstallerType,\r\n        /// The Scope of an installed package\r\n        InstalledScope,\r\n        /// The system path where the package is installed\r\n        InstalledLocation,\r\n        /// The standard uninstall command; which may be interactive\r\n        StandardUninstallCommand,\r\n        /// An uninstall command that should be non-interactive\r\n        SilentUninstallCommand,\r\n        /// The publisher of the package\r\n        PublisherDisplayName,\r\n    };\r\n\r\n    /// The result of a comparison.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 2)]\r\n    enum CompareResult\r\n    {\r\n        /// The comparison did not result in a succesful ordering.\r\n        Unknown,\r\n        /// The object value is lesser than the given value.\r\n        Lesser,\r\n        /// The object value is equal to the given value.\r\n        Equal,\r\n        /// The object value is greater than the given value.\r\n        Greater,\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: IPackageVersion from winget/RepositorySearch.h\r\n    /// A single package version.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass PackageVersionInfo\r\n    {\r\n        /// IMPLEMENTATION NOTE: PackageVersionMetadata fields from winget/RepositorySearch.h\r\n        /// Gets any metadata associated with this package version.\r\n        /// Primarily stores data on installed packages.\r\n        /// Metadata fields may have no value (e.g. packages that aren't installed will not have an InstalledLocation).\r\n        String GetMetadata(PackageVersionMetadataField metadataField);\r\n        /// IMPLEMENTATION NOTE: PackageVersionProperty fields from winget/RepositorySearch.h\r\n        String Id { get; };\r\n        String DisplayName { get; };\r\n        String Version { get; };\r\n        String Channel { get; };\r\n        /// DESIGN NOTE: RelativePath from winget/RepositorySearch.h is excluded as not needed.\r\n        /// String RelativePath;\r\n\r\n        /// IMPLEMENTATION NOTE: PackageVersionMultiProperty fields from winget/RepositorySearch.h\r\n        /// PackageFamilyName and ProductCode can have multiple values.\r\n        Windows.Foundation.Collections.IVectorView<String> PackageFamilyNames { get; };\r\n        Windows.Foundation.Collections.IVectorView<String> ProductCodes { get; };\r\n\r\n        /// Gets the package catalog  where this package version is from.\r\n        PackageCatalog PackageCatalog { get; };\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 2)]\r\n        {\r\n            /// Compares the given value against the package version of this object, with the result being\r\n            /// the enum value that represents where PackageVersionInfo::Version is ordered relative to the\r\n            /// versionString.  \"if (this.CompareToVersion(that) == Greater)\" can be thought of as reading\r\n            /// the sentence \"If this is compared to version that and is found to be greater\".\r\n            /// IE if PackageVersionInfo::Version returns \"2\", then CompareToVersion(\"1\") will return Greater.\r\n            /// Passing in an empty string will result in Unknown.\r\n            CompareResult CompareToVersion(String versionString);\r\n        }\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 4)]\r\n        {\r\n            /// Checks if this package version has at least one applicable installer.\r\n            Boolean HasApplicableInstaller(InstallOptions options);\r\n\r\n            /// Gets the publisher string for this package version, if one is available.\r\n            String Publisher { get; };\r\n        }\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 6)]\r\n        {\r\n            /// Gets the package catalog metadata of this package version with the default localization based on user settings.\r\n            CatalogPackageMetadata GetCatalogPackageMetadata();\r\n\r\n            /// Gets the package catalog metadata of this package version with the preferred locale.\r\n            CatalogPackageMetadata GetCatalogPackageMetadata(String preferredLocale);\r\n\r\n            /// Gets the applicable installer for this package version.\r\n            PackageInstallerInfo GetApplicableInstaller(InstallOptions options);\r\n        }\r\n    }\r\n\r\n    /// IMPLEMENTATION NOTE: PackageVersionKey from winget/RepositorySearch.h\r\n    /// A key to identify a package version within a package.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass PackageVersionId\r\n    {\r\n        /// The package catalog id that this version came from.\r\n        String PackageCatalogId { get; };\r\n        /// The version.\r\n        String Version { get; };\r\n        /// The channel.\r\n        String Channel { get; };\r\n    };\r\n\r\n    /// The package installer type.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 5)]\r\n    enum PackageInstallerType\r\n    {\r\n        /// Unknown type.\r\n        Unknown,\r\n        /// Inno type.\r\n        Inno,\r\n        /// Wix type.\r\n        Wix,\r\n        /// Msi type.\r\n        Msi,\r\n        /// Nullsoft type.\r\n        Nullsoft,\r\n        /// Zip type.\r\n        Zip,\r\n        /// Msix or Appx type.\r\n        Msix,\r\n        /// Exe type.\r\n        Exe,\r\n        /// Burn type.\r\n        Burn,\r\n        /// MSStore type.\r\n        MSStore,\r\n        /// Portable type.\r\n        Portable,\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 13)]\r\n        {\r\n            /// Font type.\r\n            Font,\r\n        },\r\n    };\r\n\r\n    /// The package installer scope.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 5)]\r\n    enum PackageInstallerScope\r\n    {\r\n        /// Scope not declared.\r\n        Unknown,\r\n        /// User scope.\r\n        User,\r\n        /// System scope.\r\n        System,\r\n    };\r\n\r\n    /// The package installer elevation requirement.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 6)]\r\n    enum ElevationRequirement\r\n    {\r\n        /// Elevation requirement not declared.\r\n        Unknown,\r\n        /// Package installer requires elevation.\r\n        ElevationRequired,\r\n        /// Package installer prohibits elevation.\r\n        ElevationProhibited,\r\n        /// Package installer elevates self.\r\n        ElevatesSelf,\r\n    };\r\n\r\n    /// Interface for retrieving information about a package installer.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 5)]\r\n    runtimeclass PackageInstallerInfo\r\n    {\r\n        /// The package installer type.\r\n        PackageInstallerType InstallerType { get; };\r\n        /// The nested package installer type for archives.\r\n        PackageInstallerType NestedInstallerType { get; };\r\n        /// The package installer architecture.\r\n        Windows.System.ProcessorArchitecture Architecture { get; };\r\n        /// The package installer scope.\r\n        PackageInstallerScope Scope { get; };\r\n        /// The package installer locale.\r\n        String Locale { get; };\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 6)]\r\n        {\r\n            /// The package installer elevation requirement.\r\n            ElevationRequirement ElevationRequirement { get; };\r\n        }\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 12)]\r\n        {\r\n            /// Authentication info from the package installer.\r\n            AuthenticationInfo AuthenticationInfo { get; };\r\n        }\r\n    };\r\n\r\n    /// The installed status type. The values need to match InstalledStatusType from winget/RepositorySearch.h.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 5)]\r\n    [flags]\r\n    enum InstalledStatusType\r\n    {\r\n        /// None is checked.\r\n        None = 0x0,\r\n        /// Check Apps and Features entry.\r\n        AppsAndFeaturesEntry = 0x0001,\r\n        /// Check Apps and Features entry install location if applicable.\r\n        AppsAndFeaturesEntryInstallLocation = 0x0002,\r\n        /// Check Apps and Features entry install location with installed files if applicable.\r\n        AppsAndFeaturesEntryInstallLocationFile = 0x0004,\r\n        /// Check default install location if applicable.\r\n        DefaultInstallLocation = 0x0008,\r\n        /// Check default install location with installed files if applicable.\r\n        DefaultInstallLocationFile = 0x0010,\r\n\r\n        /// Below are helper values for calling CheckInstalledStatus as input.\r\n        /// AppsAndFeaturesEntry related checks\r\n        AllAppsAndFeaturesEntryChecks = AppsAndFeaturesEntry | AppsAndFeaturesEntryInstallLocation | AppsAndFeaturesEntryInstallLocationFile,\r\n        /// DefaultInstallLocation related checks\r\n        AllDefaultInstallLocationChecks = DefaultInstallLocation | DefaultInstallLocationFile,\r\n        /// All checks\r\n        AllChecks = AllAppsAndFeaturesEntryChecks | AllDefaultInstallLocationChecks,\r\n    };\r\n\r\n    /// Interface representing an individual installed status.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 5)]\r\n    runtimeclass InstalledStatus\r\n    {\r\n        /// The installed status type.\r\n        InstalledStatusType Type { get; };\r\n        /// The installed status path.\r\n        String Path { get; };\r\n        /// The installed status result.\r\n        HRESULT Status { get; };\r\n    };\r\n\r\n    /// Interface for retrieving information about a package installer installed status.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 5)]\r\n    runtimeclass PackageInstallerInstalledStatus\r\n    {\r\n        /// The package installer info.\r\n        PackageInstallerInfo InstallerInfo { get; };\r\n        /// A list of various types of installed status of the package installer.\r\n        Windows.Foundation.Collections.IVectorView<InstalledStatus> InstallerInstalledStatus { get; };\r\n    };\r\n\r\n    /// Status of the check installed status call.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 5)]\r\n    enum CheckInstalledStatusResultStatus\r\n    {\r\n        Ok,\r\n        InternalError,\r\n    };\r\n\r\n    /// Interface for retrieving information about a package installer installed status.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 5)]\r\n    runtimeclass CheckInstalledStatusResult\r\n    {\r\n        /// Status of the check installed status call.\r\n        CheckInstalledStatusResultStatus Status { get; };\r\n\r\n        /// A list of package installer installed status.\r\n        Windows.Foundation.Collections.IVectorView<PackageInstallerInstalledStatus> PackageInstalledStatus { get; };\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: IPackage from winget/RepositorySearch.h\r\n    /// A package, potentially containing information about it's local state and the available versions.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass CatalogPackage\r\n    {\r\n        /// IMPLEMENTATION NOTE: PackageProperty fields from winget/RepositorySearch.h\r\n        /// Gets a property of this package.\r\n        String Id { get; };\r\n        String Name { get; };\r\n\r\n        /// Gets the installed package information if the package is installed.\r\n        PackageVersionInfo InstalledVersion { get; };\r\n\r\n        /// Gets all available versions of this package. Ordering is not guaranteed.\r\n        Windows.Foundation.Collections.IVectorView<PackageVersionId> AvailableVersions { get; };\r\n\r\n        /// Gets the version of this package that will be installed if version is not set in InstallOptions.\r\n        PackageVersionInfo DefaultInstallVersion { get; };\r\n\r\n        /// Gets a specific version of this package.\r\n        PackageVersionInfo GetPackageVersionInfo(PackageVersionId versionKey);\r\n\r\n        /// Gets a value indicating whether an available version is newer than the installed version.\r\n        Boolean IsUpdateAvailable { get; };\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 5)]\r\n        {\r\n            /// Check the installed status of the package. For more accurate and complete installed status, it's required to\r\n            /// call this method from a composite package from a newly created package catalog with installed info.\r\n            /// This may require downloading information from a server.\r\n            Windows.Foundation.IAsyncOperation<CheckInstalledStatusResult> CheckInstalledStatusAsync(InstalledStatusType checkTypes);\r\n            CheckInstalledStatusResult CheckInstalledStatus(InstalledStatusType checkTypes);\r\n            Windows.Foundation.IAsyncOperation<CheckInstalledStatusResult> CheckInstalledStatusAsync();\r\n            CheckInstalledStatusResult CheckInstalledStatus();\r\n        }\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 29)]\r\n        {\r\n            /// Determines the priority of the catalog for this package object.\r\n            /// This should match the priority of the DefaultInstallVersion, but it is much more efficient than using that route.\r\n            /// May be null if the package refers only to an installed item.\r\n            Windows.Foundation.IReference<Int32> CatalogPriority { get; };\r\n        }\r\n    }\r\n\r\n    /// IMPLEMENTATION NOTE: CompositeSearchBehavior from winget/RepositorySource.h\r\n    /// Search behavior for composite catalogs.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum CompositeSearchBehavior\r\n    {\r\n        /// Search local catalogs only\r\n        LocalCatalogs,\r\n        /// Search remote catalogs only, don't check local catalogs for InstalledVersion\r\n        RemotePackagesFromRemoteCatalogs,\r\n        /// Search remote catalogs, and check local catalogs for InstalledVersion\r\n        RemotePackagesFromAllCatalogs,\r\n        /// Search both local and remote catalogs.\r\n        AllCatalogs,\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: PackageFieldMatchOption from winget/RepositorySearch.h\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum PackageFieldMatchOption\r\n    {\r\n        Equals,\r\n        EqualsCaseInsensitive,\r\n        StartsWithCaseInsensitive,\r\n        ContainsCaseInsensitive,\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: PackageFieldMatchOption from winget/RepositorySearch.h\r\n    /// The field to match on.\r\n    /// The values must be declared in order of preference in search results.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum PackageMatchField\r\n    {\r\n        CatalogDefault,\r\n        Id,\r\n        Name,\r\n        Moniker,\r\n        Command,\r\n        Tag,\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 3)]\r\n        {\r\n            PackageFamilyName,\r\n            ProductCode,\r\n        }\r\n        /// DESIGN NOTE: The following PackageFieldMatchOption from winget/RepositorySearch.h are not implemented in V1.\r\n        /// NormalizedNameAndPublisher,\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: PackageMatchFilter from winget/RepositorySearch.h\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass PackageMatchFilter\r\n    {\r\n        PackageMatchFilter();\r\n        /// The type of string comparison for matching\r\n        PackageFieldMatchOption Option;\r\n        /// The field to search\r\n        PackageMatchField Field;\r\n        /// The value to match\r\n        String Value;\r\n        /// DESIGN NOTE: \"Additional\" from RequestMatch winget/RepositorySearch.h is not implemented here.\r\n    }\r\n\r\n    /// IMPLEMENTATION NOTE: MatchResult from winget/RepositorySearch.h\r\n    /// A single result from the search.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass MatchResult\r\n    {\r\n        /// The package found by the search request.\r\n        CatalogPackage CatalogPackage { get; };\r\n\r\n        /// The highest order field on which the package matched the search.\r\n        PackageMatchFilter MatchCriteria { get; };\r\n    }\r\n\r\n    /// Status of the FindPackages call\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum FindPackagesResultStatus\r\n    {\r\n        Ok,\r\n        BlockedByPolicy,\r\n        CatalogError,\r\n        InternalError,\r\n        InvalidOptions,\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 10)]\r\n        {\r\n            AuthenticationError,\r\n            AccessDenied,\r\n        }\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: SearchResult from winget/RepositorySearch.h\r\n    /// Search result data returned from FindPackages\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass FindPackagesResult\r\n    {\r\n        /// Error codes\r\n        FindPackagesResultStatus Status{ get; };\r\n\r\n        /// The full set of results from the search.\r\n        Windows.Foundation.Collections.IVectorView<MatchResult> Matches { get; };\r\n\r\n        /// If true, the results were truncated by the given ResultLimit\r\n        /// USAGE NOTE: Windows Package Manager does not support result pagination, there is no way to continue \r\n        /// getting more results.\r\n        Boolean WasLimitExceeded { get; };\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 11)]\r\n        {\r\n            /// The error code of the operation.\r\n            HRESULT ExtendedErrorCode{ get; };\r\n        }\r\n    }\r\n\r\n    /// Options for FindPackages\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass FindPackagesOptions\r\n    {\r\n        FindPackagesOptions();\r\n\r\n        /// DESIGN NOTE: \r\n        /// This class maps to SearchRequest from  winget/RepositorySearch.h \r\n        /// That class is a container for data used to filter the available manifests in an package catalog.\r\n        /// Its properties can be thought of as:\r\n        /// (Query || Inclusions...) && Filters...\r\n        /// If Query and Inclusions are both empty, the starting data set will be the entire database.\r\n        /// Everything && Filters...\r\n        /// That has been translated in this api so that \r\n        /// Inclusions are Selectors below\r\n        /// Filters are Filters below\r\n        /// Query is PackageFieldMatchOption::PackageCatalogDefined and in the Selector list.\r\n        /// USAGE NOTE: Only one selector with PackageFieldMatchOption::PackageCatalogDefined is allowed.\r\n\r\n        /// Selectors = you have to match at least one selector (if there are no selectors, then nothing is selected)\r\n        Windows.Foundation.Collections.IVector<PackageMatchFilter> Selectors { get; };\r\n        /// Filters = you have to match all filters(if there are no filters, then there is no filtering of selected items)\r\n        Windows.Foundation.Collections.IVector<PackageMatchFilter> Filters{ get; };\r\n\r\n        /// Restricts the length of the returned results to the specified count.\r\n        UInt32 ResultLimit;\r\n    }\r\n\r\n    /// IMPLEMENTATION NOTE: Source from winget/RepositorySource.h\r\n    /// A catalog for searching for packages\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass PackageCatalog\r\n    {\r\n        /// Gets a value indicating whether this package catalog is a composite of other package catalogs,\r\n        /// and thus the packages may come from disparate package catalogs as well.\r\n        Boolean IsComposite { get; };\r\n        /// The details of the package catalog if it is not a composite.\r\n        PackageCatalogInfo Info { get; };\r\n\r\n        /// Searches for Packages in the catalog.\r\n        Windows.Foundation.IAsyncOperation<FindPackagesResult> FindPackagesAsync(FindPackagesOptions options);\r\n        FindPackagesResult FindPackages(FindPackagesOptions options);\r\n    }\r\n\r\n    /// Authentication mode\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 10)]\r\n    enum AuthenticationMode\r\n    {\r\n        /// Always use interactive authentication flow on first authentication request, following requests may use cached result.\r\n        Interactive,\r\n        /// Try silent authentication flow first. If failed, use interactive authentication flow.\r\n        SilentPreferred,\r\n        /// Only use silent authentication flow. If failed, fail the authentication.\r\n        Silent,\r\n    };\r\n\r\n    /// Authentication related arguments\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 10)]\r\n    runtimeclass AuthenticationArguments\r\n    {\r\n        AuthenticationArguments();\r\n\r\n        /// Choice of authentication flow behavior.\r\n        AuthenticationMode AuthenticationMode;\r\n        /// Optional. The authentication account to be used for authentication.\r\n        String AuthenticationAccount;\r\n    }\r\n\r\n    /// Authentication method\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 10)]\r\n    enum AuthenticationType\r\n    {\r\n        Unknown,\r\n        None,\r\n        MicrosoftEntraId,\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 12)]\r\n        {\r\n            MicrosoftEntraIdForAzureBlobStorage,\r\n        }\r\n    };\r\n\r\n    /// Microsoft Entra Id related authentication info.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 10)]\r\n    runtimeclass MicrosoftEntraIdAuthenticationInfo\r\n    {\r\n        /// The resource identifier or resource uri.\r\n        String Resource { get; };\r\n        /// Requested scope. May be empty.\r\n        String Scope { get; };\r\n    }\r\n\r\n    /// Authentication info.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 10)]\r\n    runtimeclass AuthenticationInfo\r\n    {\r\n        /// The authentication type.\r\n        AuthenticationType AuthenticationType { get; };\r\n        /// Microsoft Entra Id related authentication info.\r\n        MicrosoftEntraIdAuthenticationInfo MicrosoftEntraIdAuthenticationInfo { get; };\r\n    }\r\n\r\n    /// Status of the Connect call\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum ConnectResultStatus\r\n    {\r\n        Ok,\r\n        CatalogError,\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 6)]\r\n        {\r\n            SourceAgreementsNotAccepted,\r\n        }\r\n    };\r\n\r\n    /// Result of the Connect call\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass ConnectResult\r\n    {\r\n        /// Error codes\r\n        ConnectResultStatus Status { get; };\r\n\r\n        PackageCatalog PackageCatalog { get; };\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 11)]\r\n        {\r\n            /// The error code of the operation.\r\n            HRESULT ExtendedErrorCode{ get; };\r\n        }\r\n    }\r\n\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 12)]\r\n    enum RefreshPackageCatalogStatus\r\n    {\r\n        Ok,\r\n        GroupPolicyError,\r\n        CatalogError,\r\n        InternalError,\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: RefreshPackageCatalogResult\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 12)]\r\n    runtimeclass RefreshPackageCatalogResult\r\n    {\r\n        RefreshPackageCatalogStatus Status { get; };\r\n\r\n        /// Error codes\r\n        HRESULT ExtendedErrorCode { get; };\r\n    };\r\n\r\n    /// A reference to a catalog that callers can try to Connect.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass PackageCatalogReference\r\n    {\r\n        /// Gets a value indicating whether this package catalog is a composite of other package catalogs,\r\n        /// and thus the packages may come from disparate package catalogs as well.\r\n        Boolean IsComposite { get; };\r\n\r\n        /// The details of the package catalog if it is not a composite.\r\n        PackageCatalogInfo Info { get; };\r\n\r\n        /// Opens a catalog. Required before searching. For remote catalogs (i.e. not Installed and Installing) this \r\n        /// may require downloading information from a server.\r\n        Windows.Foundation.IAsyncOperation<ConnectResult> ConnectAsync();\r\n        ConnectResult Connect();\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 2)]\r\n        {\r\n            /// A string that will be passed to the source server if using a REST source\r\n            String AdditionalPackageCatalogArguments;\r\n        }\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 6)]\r\n        {\r\n            /// Gets the required agreements for connecting to the package catalog (source).\r\n            Windows.Foundation.Collections.IVectorView<SourceAgreement> SourceAgreements { get; };\r\n\r\n            Boolean AcceptSourceAgreements;\r\n        }\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 8)]\r\n        {\r\n            /// Time interval for package catalog to check for an update. Setting to zero will disable the check for update.\r\n            Windows.Foundation.TimeSpan PackageCatalogBackgroundUpdateInterval;\r\n        }\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 9)]\r\n        {\r\n            /// When set to true, the opened catalog will only provide the information regarding packages installed from this catalog.\r\n            /// In this mode, no external resources should be required.\r\n            Boolean InstalledPackageInformationOnly;\r\n        }\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 10)]\r\n        {\r\n            /// Authentication arguments used in authentication flow during package catalog operations if applicable.\r\n            /// This is user or caller input.\r\n            AuthenticationArguments AuthenticationArguments;\r\n\r\n            /// Authentication info from the package catalog.\r\n            /// This is defined by individual package catalog.\r\n            AuthenticationInfo AuthenticationInfo { get; };\r\n        }\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 12)]\r\n        {\r\n            /// Updates the package catalog.\r\n            /// The progress value, represented as a double, indicates the percentage of update package catalog operation completion.\r\n            /// The progress range is from 0 to 100.\r\n            Windows.Foundation.IAsyncOperationWithProgress<RefreshPackageCatalogResult, Double> RefreshPackageCatalogAsync();\r\n        }\r\n    }\r\n\r\n    /// Catalogs with PackageCatalogOrigin Predefined\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum PredefinedPackageCatalog\r\n    {\r\n        OpenWindowsCatalog,\r\n        MicrosoftStore,\r\n        DesktopFrameworks,\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 13)]\r\n        {\r\n            OpenWindowsCatalogFont,\r\n        },\r\n    };\r\n\r\n    /// Local Catalogs with PackageCatalogOrigin Predefined\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum LocalPackageCatalog\r\n    {\r\n        InstalledPackages,\r\n        InstallingPackages\r\n    };\r\n\r\n    /// Options for creating a composite catalog.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass CreateCompositePackageCatalogOptions\r\n    {\r\n        CreateCompositePackageCatalogOptions();\r\n\r\n        /// Create a composite catalog to allow searching a user defined or pre defined source\r\n        /// and a local source (Installed packages) together\r\n        IVector<PackageCatalogReference> Catalogs { get; };\r\n        /// Sets the default search behavior if the catalog is a composite catalog.\r\n        CompositeSearchBehavior CompositeSearchBehavior;\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 5)]\r\n        {\r\n            /// Create installed package catalog with required installed scope.\r\n            PackageInstallScope InstalledScope;\r\n        }\r\n    }\r\n\r\n    /// Required install scope for the package. If the package does not have an installer that\r\n    /// supports the specified scope the Install call will fail with InstallResultStatus.NoApplicableInstallers\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum PackageInstallScope\r\n    {\r\n        /// An installer with any install scope is valid.\r\n        Any,\r\n        /// Only User install scope installers are valid\r\n        User,\r\n        /// Only System installers will be valid\r\n        System,\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 5)]\r\n        {\r\n            /// Both User and Unknown install scope installers are valid\r\n            UserOrUnknown,\r\n            /// Both System and Unknown install scope installers are valid\r\n            SystemOrUnknown,\r\n        }\r\n    };\r\n\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    enum PackageInstallMode\r\n    {\r\n        /// The default experience for the installer. Installer may show some UI.\r\n        Default,\r\n        /// Runs the installer in silent mode. This suppresses the installer's UI to the extent \r\n        /// possible (installer may still show some required UI).\r\n        Silent,\r\n        /// Runs the installer in interactive mode.\r\n        Interactive,\r\n    };\r\n\r\n    /// Options when installing a package.\r\n    /// Intended to allow full compatibility with the \"winget install\" command line interface.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass InstallOptions\r\n    {\r\n        InstallOptions();\r\n\r\n        /// Optionally specifies the version from the package to install. If unspecified, the CatalogPackage.DefaultInstallVersion\r\n        /// version is used. DefaultInstallVersion is the latest applicable version of the package. DefaultInstallVersion may be\r\n        /// empty if there's no applicable version. In that case, install attempts without setting this PackageVersionId\r\n        /// will return No Applicable Installer error code.\r\n        PackageVersionId PackageVersionId;\r\n\r\n        /// Specifies alternate location to install package (if supported).\r\n        String PreferredInstallLocation;\r\n        /// User or Machine. \r\n        PackageInstallScope PackageInstallScope;\r\n        /// Silent, Interactive, or Default\r\n        PackageInstallMode PackageInstallMode;\r\n        /// Directs the logging to a log file. If provided, the installer must have write access to the file \r\n        String LogOutputPath;\r\n        /// Continues the install even if the hash in the catalog does not match the linked installer.\r\n        Boolean AllowHashMismatch;\r\n        /// A string that will be passed to the installer. \r\n        /// IMPLEMENTATION NOTE: maps to \"--override\" in the winget cmd line\r\n        String ReplacementInstallerArguments;\r\n\r\n        /// Used by a caller to correlate the install with a caller's data.\r\n        /// The string must be JSON encoded.\r\n        String CorrelationData;\r\n        /// A string that will be passed to the source server if using a REST source\r\n        String AdditionalPackageCatalogArguments;\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 2)]\r\n        {\r\n            /// The set of allowed Architectures, in preference order, that will be considered for\r\n            /// the install operation.  Initially the vector contains the default allowed architectures\r\n            /// in the default preference order for the current system.  It is allowed to have repeated\r\n            /// values in the list, to make prepending a preference override easier.  Instances of an\r\n            /// architecture after the first will simply be ignored.\r\n            Windows.Foundation.Collections.IVector<Windows.System.ProcessorArchitecture> AllowedArchitectures { get; };\r\n        }\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 4)]\r\n        {\r\n            /// Allow the upgrade to continue for upgrade packages with manifest versions Unknown.\r\n            Boolean AllowUpgradeToUnknownVersion;\r\n        }\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 5)]\r\n        {\r\n            /// Force the operation to continue upon non security related failures.\r\n            Boolean Force;\r\n        }\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 6)]\r\n        {\r\n            /// A string that will be passed to the installer\r\n            /// IMPLEMENTATION NOTE: maps to \"--custom\" in the winget cmd line\r\n            String AdditionalInstallerArguments;\r\n\r\n            /// Accept the package agreements required for installation.\r\n            Boolean AcceptPackageAgreements;\r\n\r\n            /// Bypasses the Disabled Store Policy\r\n            Boolean BypassIsStoreClientBlockedPolicyCheck;\r\n        }\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 7)]\r\n        {\r\n            /// Skip installing the dependencies for the package.\r\n            Boolean SkipDependencies;\r\n\r\n            /// The package installer type.\r\n            PackageInstallerType InstallerType;\r\n        }\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 12)]\r\n        {\r\n            /// Authentication arguments used when downloading the package installer if authentication is required.\r\n            AuthenticationArguments AuthenticationArguments;\r\n        }\r\n    }\r\n\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 4)]\r\n    enum PackageUninstallMode\r\n    {\r\n        /// The default experience for the installer. Installer may show some UI.\r\n        Default,\r\n        /// Runs the installer in silent mode. This suppresses the installer's UI to the extent \r\n        /// possible (installer may still show some required UI).\r\n        Silent,\r\n        /// Runs the installer in interactive mode.\r\n        Interactive,\r\n    };\r\n\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 5)]\r\n    enum PackageUninstallScope\r\n    {\r\n        /// Use default uninstall behavior.\r\n        Any,\r\n        /// Uninstall for current user. Currently only applicable to msix.\r\n        User,\r\n        /// Uninstall for all users. Currently only applicable to msix.\r\n        System,\r\n    };\r\n\r\n    /// Options when uninstalling a package.\r\n    /// Intended to allow full compatibility with the \"winget uninstall\" command line interface.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 4)]\r\n    runtimeclass UninstallOptions\r\n    {\r\n        UninstallOptions();\r\n\r\n        /// This property is not currently used. The version of CatalogPackage.InstalledVersion is used for uninstall.\r\n        PackageVersionId PackageVersionId;\r\n\r\n        /// Silent, Interactive, or Default\r\n        PackageUninstallMode PackageUninstallMode;\r\n\r\n        /// Directs the logging to a log file. If provided, the installer must have write access to the file \r\n        String LogOutputPath;\r\n\r\n        /// Used by a caller to correlate the install with a caller's data.\r\n        /// The string must be JSON encoded.\r\n        String CorrelationData;\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 5)]\r\n        {\r\n            /// Force the operation to continue upon non security related failures.\r\n            Boolean Force;\r\n            // The scope the uninstall will perform. Currently only applicable to msix.\r\n            PackageUninstallScope PackageUninstallScope;\r\n        }\r\n    }\r\n\r\n    /// The Windows platform type.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 13)]\r\n    enum WindowsPlatform\r\n    {\r\n        /// An unknown platform\r\n        Unknown,\r\n        /// Windows.Universal\r\n        Universal,\r\n        /// Windows.Desktop\r\n        Desktop,\r\n        /// Windows.IoT\r\n        IoT,\r\n        /// Windows.Team\r\n        Team,\r\n        /// Windows.Holographic\r\n        Holographic,\r\n    };\r\n\r\n    /// Options when downloading a package.\r\n    /// Intended to allow full compatibility with the \"winget download\" command line interface.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 7)]\r\n    runtimeclass DownloadOptions\r\n    {\r\n        DownloadOptions();\r\n\r\n        /// Optionally specifies the version from the package to download. If unspecified the version matching \r\n        /// CatalogPackage.GetLatestVersion() is used.\r\n        PackageVersionId PackageVersionId;\r\n\r\n        /// The package installer type.\r\n        PackageInstallerType InstallerType;\r\n\r\n        /// The package installer scope.\r\n        PackageInstallScope Scope;\r\n\r\n        /// The package installer architecture.\r\n        Windows.System.ProcessorArchitecture Architecture;\r\n\r\n        /// The package installer locale.\r\n        String Locale;\r\n\r\n        /// The directory where the installers are downloaded to.\r\n        String DownloadDirectory;\r\n\r\n        /// Continues the download even if the hash in the catalog does not match the linked installer.\r\n        Boolean AllowHashMismatch;\r\n\r\n        /// Skip downloading the dependencies for the package.\r\n        Boolean SkipDependencies;\r\n\r\n        /// Accept the package agreements required for download.\r\n        Boolean AcceptPackageAgreements;\r\n\r\n        /// Used by a caller to correlate the download with a caller's data.\r\n        /// The string must be JSON encoded.\r\n        String CorrelationData;\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 12)]\r\n        {\r\n            /// Authentication arguments used when downloading the package installer if authentication is required.\r\n            AuthenticationArguments AuthenticationArguments;\r\n        }\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 13)]\r\n        {\r\n            /// If the package is licensed from the Microsoft Store, setting this value to true will not attempt to download the license file.\r\n            Boolean SkipMicrosoftStoreLicense;\r\n\r\n            /// The platform to download the package for.\r\n            WindowsPlatform Platform;\r\n\r\n            /// When applicable, uses the provided value as the target OS version for the download.\r\n            String TargetOSVersion;\r\n        }\r\n    }\r\n\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 11)]\r\n    enum PackageRepairMode\r\n    {\r\n        /// The default experience for the installer. Installer may show some UI.\r\n        Default,\r\n        /// Runs the installer in silent mode. This suppresses the installer's UI to the extent \r\n        /// possible (installer may still show some required UI).\r\n        Silent,\r\n        /// Runs the installer in interactive mode.\r\n        Interactive,\r\n    };\r\n\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 11)]\r\n    enum PackageRepairScope\r\n    {\r\n        /// Use default repair behavior.\r\n        Any,\r\n        /// Repair for current user. Currently only applicable to msix.\r\n        User,\r\n        /// Repair for all users.\r\n        System,\r\n    };\r\n\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 11)]\r\n    runtimeclass RepairOptions\r\n    {\r\n        RepairOptions();\r\n\r\n        /// This property is not currently used. The version of CatalogPackage.InstalledVersion is used for repair.\r\n        PackageVersionId PackageVersionId;\r\n\r\n        /// The package Repair scope.\r\n        PackageRepairScope PackageRepairScope;\r\n\r\n        /// The package repair mode.\r\n        PackageRepairMode PackageRepairMode;\r\n\r\n        /// Optional parameter specifying Accept the package agreements required for download.\r\n        Boolean AcceptPackageAgreements;\r\n\r\n        /// Used by a caller to correlate the repair with a caller's data.\r\n        /// The string must be JSON encoded.\r\n        String CorrelationData;\r\n\r\n        /// Continues the download even if the hash in the catalog does not match the linked installer used for repair.\r\n        Boolean AllowHashMismatch;\r\n\r\n        /// Directs the logging to a log file. If provided, the installer must have write access to the file\r\n        String LogOutputPath;\r\n\r\n        /// Force the operation to continue upon non security related failures.\r\n        Boolean Force;\r\n\r\n        /// Bypasses the Disabled Store Policy\r\n        Boolean BypassIsStoreClientBlockedPolicyCheck;\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 12)]\r\n        {\r\n            /// Authentication arguments used when downloading the package installer if authentication is required.\r\n            AuthenticationArguments AuthenticationArguments;\r\n        }\r\n    }\r\n\r\n    /// IMPLEMENTATION NOTE: Documentation from AppInstaller::Manifest::Documentation\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 6)]\r\n    runtimeclass Documentation\r\n    {\r\n        String DocumentLabel { get; };\r\n\r\n        String DocumentUrl { get; };\r\n    }\r\n\r\n    /// Icon resolution\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 6)]\r\n    enum IconResolution\r\n    {\r\n        Custom,\r\n        Square16,\r\n        Square20,\r\n        Square24,\r\n        Square30,\r\n        Square32,\r\n        Square36,\r\n        Square40,\r\n        Square48,\r\n        Square60,\r\n        Square64,\r\n        Square72,\r\n        Square80,\r\n        Square96,\r\n        Square256,\r\n    };\r\n\r\n    /// Icon file type\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 6)]\r\n    enum IconFileType\r\n    {\r\n        Unknown,\r\n        Jpeg,\r\n        Png,\r\n        Ico,\r\n    };\r\n\r\n    /// Icon theme\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 6)]\r\n    enum IconTheme\r\n    {\r\n        Unknown,\r\n        Default,\r\n        Light,\r\n        Dark,\r\n        HighContrast,\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: Icon from AppInstaller::Manifest::Icon\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 6)]\r\n    runtimeclass Icon\r\n    {\r\n        String Url { get; };\r\n\r\n        IconFileType FileType{ get; };\r\n\r\n        IconResolution Resolution{ get; };\r\n\r\n        IconTheme Theme{ get; };\r\n\r\n        UInt8[] Sha256 { get; };\r\n    }\r\n\r\n    /// IMPLEMENTATION NOTE: SourceAgreement from AppInstaller::Manifest::SourceAgreement\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 6)]\r\n    runtimeclass SourceAgreement\r\n    {\r\n        String Label { get; };\r\n\r\n        String Text { get; };\r\n    \r\n        String Url { get; };\r\n    }\r\n\r\n    /// IMPLEMENTATION NOTE: PackageAgreement from AppInstaller::Manifest::Agreement\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 6)]\r\n    runtimeclass PackageAgreement\r\n    {\r\n        String Label { get; };\r\n\r\n        String Text { get; };\r\n\r\n        String Url { get; };\r\n    }\r\n\r\n    /// IMPLEMENTATION NOTE: CatalogPackageMetadata from AppInstaller::Manifest::Localization\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 6)]\r\n    runtimeclass CatalogPackageMetadata\r\n    {\r\n        String Locale { get; };\r\n\r\n        String Publisher { get; };\r\n\r\n        String PublisherUrl { get; };\r\n\r\n        String PublisherSupportUrl { get; };\r\n\r\n        String PrivacyUrl { get; };\r\n\r\n        String Author { get; };\r\n\r\n        String PackageName { get; };\r\n\r\n        String PackageUrl { get; };\r\n\r\n        String License { get; };\r\n\r\n        String LicenseUrl { get; };\r\n\r\n        String Copyright { get; };\r\n\r\n        String CopyrightUrl { get; };\r\n\r\n        String ShortDescription { get; };\r\n\r\n        String Description { get; };\r\n\r\n        Windows.Foundation.Collections.IVectorView<String> Tags { get; };\r\n\r\n        Windows.Foundation.Collections.IVectorView<PackageAgreement> Agreements { get; };\r\n\r\n        Windows.Foundation.Collections.IVectorView<Documentation> Documentations { get; };\r\n\r\n        Windows.Foundation.Collections.IVectorView<Icon> Icons { get; };\r\n\r\n        String ReleaseNotes { get; };\r\n\r\n        String ReleaseNotesUrl { get; };\r\n\r\n        String PurchaseUrl { get; };\r\n\r\n        String InstallationNotes { get; };\r\n    }\r\n\r\n    /// IMPLEMENTATION NOTE: AddPackageCatalogOptions\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 12)]\r\n    runtimeclass AddPackageCatalogOptions\r\n    {\r\n        AddPackageCatalogOptions();\r\n\r\n        /// The name of the package catalog. \r\n        /// SAMPLE VALUES: For OpenWindowsCatalog \"winget\".\r\n        /// For contoso sample on msdn \"contoso\"\r\n        String Name;\r\n\r\n        /// The SourceUri used when adding the package catalog.\r\n        /// SAMPLE VALUES: For OpenWindowsCatalog \"https://winget.azureedge.net/cache\"\r\n        /// For contoso sample on msdn \"https://pkgmgr-int.azureedge.net/cache\"\r\n        String SourceUri;\r\n\r\n        /// ALLOWED VALUES: \"Microsoft.Rest\", \"Microsoft.PreIndexed.Package\"\r\n        /// SAMPLE VALUES: For OpenWindowsCatalog \"Microsoft.PreIndexed.Package\".\r\n        /// For contoso sample on msdn \"Microsoft.PreIndexed.Package\"\r\n        String Type;\r\n\r\n        /// The trust level of the catalog to add.\r\n        PackageCatalogTrustLevel TrustLevel;\r\n\r\n        /// Custom header to pass to the catalog.\r\n        String CustomHeader;\r\n\r\n        /// Excludes a source from discovery unless specified.\r\n        Boolean Explicit;\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 29)]\r\n        {\r\n            /// The priority of this catalog. Higher values are sorted first.\r\n            Int32 Priority;\r\n        }\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: AddPackageCatalogStatus\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 12)]\r\n    enum AddPackageCatalogStatus\r\n    {\r\n        Ok,\r\n        GroupPolicyError,\r\n        CatalogError,\r\n        InternalError,\r\n        InvalidOptions,\r\n        AccessDenied,\r\n        AuthenticationError,\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: AddPackageCatalogResult\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 12)]\r\n    runtimeclass AddPackageCatalogResult\r\n    {\r\n        AddPackageCatalogStatus Status { get; };\r\n\r\n        /// Error codes\r\n        HRESULT ExtendedErrorCode { get; };\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: RemovePackageCatalogOptions\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 12)]\r\n    runtimeclass RemovePackageCatalogOptions\r\n    {\r\n        RemovePackageCatalogOptions();\r\n\r\n        /// The name of the package catalog. \r\n        /// SAMPLE VALUES: For OpenWindowsCatalog \"winget\".\r\n        /// For contoso sample on msdn \"contoso\"\r\n        String Name;\r\n\r\n        /// By default, the value is 'false', resulting in the removal of the package catalog registration\r\n        /// from the winget Package catalogs list and the deletion of all associated system artifacts. This \r\n        /// mirrors the WinGet Source remove operation on a specific Package Catalog. \r\n        /// If set to 'true', it removes the package catalog registration from the Windows Package Catalogs\r\n        /// list without any cleanup, similar to the WinGet source reset operation on a specific Package\r\n        /// Catalog.\r\n        Boolean PreserveData;\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: RemovePackageCatalogStatus\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 12)]\r\n    enum RemovePackageCatalogStatus\r\n    {\r\n        Ok,\r\n        GroupPolicyError,\r\n        CatalogError,\r\n        InternalError,\r\n        AccessDenied,\r\n        InvalidOptions,\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: RemovePackageCatalogResult\r\n    /// Result of removing a package catalog.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 12)]\r\n    runtimeclass RemovePackageCatalogResult\r\n    {\r\n        RemovePackageCatalogStatus Status { get; };\r\n\r\n        /// Error codes\r\n        HRESULT ExtendedErrorCode { get; };\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: EditPackageCatalogOptions\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 28)]\r\n    runtimeclass EditPackageCatalogOptions\r\n    {\r\n        EditPackageCatalogOptions();\r\n\r\n        /// The name of the package catalog. \r\n        /// SAMPLE VALUES: For OpenWindowsCatalog \"winget\".\r\n        /// For contoso sample on msdn \"contoso\"\r\n        String Name;\r\n\r\n        /// Editing the Explicit property has three states: true, false, and not specified (null).\r\n        Windows.Foundation.IReference<Boolean> Explicit;\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 29)]\r\n        {\r\n            /// The priority of this catalog. Higher values are sorted first.\r\n            Windows.Foundation.IReference<Int32> Priority;\r\n        }\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: RemovePackageCatalogStatus\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 28)]\r\n    enum EditPackageCatalogStatus\r\n    {\r\n        Ok,\r\n        GroupPolicyError,\r\n        CatalogError,\r\n        InternalError,\r\n        AccessDenied,\r\n        InvalidOptions,\r\n    };\r\n\r\n    /// IMPLEMENTATION NOTE: RemovePackageCatalogResult\r\n    /// Result of editing a package catalog.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 28)]\r\n    runtimeclass EditPackageCatalogResult\r\n    {\r\n        EditPackageCatalogStatus Status { get; };\r\n\r\n        /// Error codes\r\n        HRESULT ExtendedErrorCode { get; };\r\n    };\r\n\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 1)]\r\n    runtimeclass PackageManager\r\n    {\r\n        PackageManager();\r\n\r\n        /// Get the available catalogs. Each source will have a separate catalog.\r\n        /// This does not open the catalog. These catalogs can be used individually or merged with CreateCompositePackageCatalogAsync. \r\n        /// IMPLEMENTATION NOTE: This is a list of sources returned by Windows Package Manager source list \r\n        Windows.Foundation.Collections.IVectorView<PackageCatalogReference> GetPackageCatalogs();\r\n        /// Get a built in catalog\r\n        PackageCatalogReference GetPredefinedPackageCatalog(PredefinedPackageCatalog predefinedPackageCatalog);\r\n        /// Get a built in catalog\r\n        PackageCatalogReference GetLocalPackageCatalog(LocalPackageCatalog localPackageCatalog);\r\n        /// Get a catalog by a known name\r\n        PackageCatalogReference GetPackageCatalogByName(String catalogName);\r\n        /// Get a composite catalog to allow searching a user defined or pre defined source and a local source\r\n        /// (Installing, Installed) together at the same time.\r\n        PackageCatalogReference CreateCompositePackageCatalog(CreateCompositePackageCatalogOptions options);\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 12)]\r\n        {\r\n            /// Add a catalog to the Windows Package Catalogs.\r\n            /// The progress value, represented as a double, indicates the percentage of add package catalog operation completion.\r\n            /// The progress range is from 0 to 100.\r\n            Windows.Foundation.IAsyncOperationWithProgress<AddPackageCatalogResult, Double> AddPackageCatalogAsync(AddPackageCatalogOptions options);\r\n\r\n            /// Unregisters a Package Catalog from the Windows Package Catalogs and eliminates the system artifacts based on the provided options.\r\n            /// The progress value, represented as a double, indicates the percentage of remove package catalog operation completion.\r\n            /// The progress range is from 0 to 100.\r\n            Windows.Foundation.IAsyncOperationWithProgress<RemovePackageCatalogResult, Double> RemovePackageCatalogAsync(RemovePackageCatalogOptions options);\r\n        }\r\n\r\n        /// Install the specified package\r\n        Windows.Foundation.IAsyncOperationWithProgress<InstallResult, InstallProgress> InstallPackageAsync(CatalogPackage package, InstallOptions options);\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 2)]\r\n        {\r\n            /// Get install progress\r\n            Windows.Foundation.IAsyncOperationWithProgress<InstallResult, InstallProgress> GetInstallProgress(CatalogPackage package, PackageCatalogInfo catalogInfo);\r\n        }\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 4)]\r\n        {\r\n            /// Upgrade the specified package\r\n            Windows.Foundation.IAsyncOperationWithProgress<InstallResult, InstallProgress> UpgradePackageAsync(CatalogPackage package, InstallOptions options);\r\n\r\n            /// Uninstall the specified package\r\n            Windows.Foundation.IAsyncOperationWithProgress<UninstallResult, UninstallProgress> UninstallPackageAsync(CatalogPackage package, UninstallOptions options);\r\n\r\n            /// Get uninstall progress\r\n            Windows.Foundation.IAsyncOperationWithProgress<UninstallResult, UninstallProgress> GetUninstallProgress(CatalogPackage package, PackageCatalogInfo catalogInfo);\r\n        }\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 7)]\r\n        {\r\n            // Download the specified package\r\n            Windows.Foundation.IAsyncOperationWithProgress<DownloadResult, PackageDownloadProgress> DownloadPackageAsync(CatalogPackage package, DownloadOptions options);\r\n\r\n            // Get download progress\r\n            Windows.Foundation.IAsyncOperationWithProgress<DownloadResult, PackageDownloadProgress> GetDownloadProgress(CatalogPackage package, PackageCatalogInfo catalogInfo);\r\n        }\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 11)]\r\n        {\r\n            // Repair the specified package\r\n            Windows.Foundation.IAsyncOperationWithProgress<RepairResult, RepairProgress> RepairPackageAsync(CatalogPackage package, RepairOptions options);\r\n        }\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 13)]\r\n        {\r\n            // The version of the Windows Package Manager that is running.\r\n            String Version{ get; };\r\n        }\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 28)]\r\n        {\r\n            /// Edit an existing Windows Package Catalog.\r\n            EditPackageCatalogResult EditPackageCatalog(EditPackageCatalogOptions options);\r\n        }\r\n    }\r\n\r\n    /// Global settings for PackageManager operations.\r\n    /// This settings should be invoked prior to invocation of PackageManager class.\r\n    /// This settings is only exposed in in-proc Com invocation.\r\n    [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 4)]\r\n    runtimeclass PackageManagerSettings\r\n    {\r\n        PackageManagerSettings();\r\n\r\n        /// Sets caller name to be used in telemetry logging. Default value is the calling process name.\r\n        /// Call this before any PackageManager operations.\r\n        /// Returns true if successful, false if caller name is already set.\r\n        /// This is a one time setup, multiple calls will not override existing caller name.\r\n        Boolean SetCallerIdentifier(String callerIdentifier);\r\n\r\n        /// Sets state name for state separation. If not set, state will be written in a default location and states may be affected by other callers.\r\n        /// Call this before any PackageManager operations.\r\n        /// Returns true if successful, false if state name is already set.\r\n        /// This is a one time setup, multiple calls will not override existing state name.\r\n        Boolean SetStateIdentifier(String stateIdentifier);\r\n\r\n        /// Sets custom UserSettings.\r\n        /// Returns true if successful, false if settingsContent cannot be parsed or UserSettings is already created.\r\n        /// This is a one time setup, multiple calls will not override existing UserSettings.\r\n        Boolean SetUserSettings(String settingsContent);\r\n\r\n        [contract(Microsoft.Management.Deployment.WindowsPackageManagerContract, 28)]\r\n        {\r\n            /// Gets or sets a value indicating whether the caller would prefer the module to stay loaded or not.\r\n            /// This affects how the DllCanUnloadNow function called by COM behaves. If set to false it will act as if\r\n            /// there are active objects at all times. If set to true it will allow the unload when there are no\r\n            /// active objects.\r\n            /// Defaults to true.\r\n            Boolean CanUnloadPreference{ get; set; };\r\n\r\n            /// Gets or sets a value indicating whether the module should listen for termination signals (CTRL+C, window messages, package updates)\r\n            /// and begin the process of cancelling active operations and preventing new ones.\r\n            /// If set to false, the caller is responsible for handling these termination signals and cancelling active operations as necessary.\r\n            /// Set this to the desired state before any PackageManager operations. Changing it after the first operation for the process may have undefined behavior.\r\n            /// Defaults to true.\r\n            Boolean TerminationSignalMonitoring{ get; set; };\r\n        }\r\n    }\r\n\r\n    /// Force midl3 to generate vector marshalling info. \r\n    declare\r\n    {\r\n        interface Windows.Foundation.Collections.IVector<PackageCatalog>;\r\n        interface Windows.Foundation.Collections.IVectorView<PackageCatalog>;\r\n        interface Windows.Foundation.Collections.IVector<PackageCatalogInfo>;\r\n        interface Windows.Foundation.Collections.IVectorView<PackageCatalogInfo>;\r\n        interface Windows.Foundation.Collections.IVector<PackageCatalogReference>;\r\n        interface Windows.Foundation.Collections.IVectorView<PackageCatalogReference>;\r\n        interface Windows.Foundation.Collections.IVector<CatalogPackage>;\r\n        interface Windows.Foundation.Collections.IVectorView<CatalogPackage>;\r\n        interface Windows.Foundation.Collections.IVector<FindPackagesOptions>;\r\n        interface Windows.Foundation.Collections.IVectorView<FindPackagesOptions>;\r\n        interface Windows.Foundation.Collections.IVector<FindPackagesResult>;\r\n        interface Windows.Foundation.Collections.IVectorView<FindPackagesResult>;\r\n        interface Windows.Foundation.Collections.IVector<CreateCompositePackageCatalogOptions>;\r\n        interface Windows.Foundation.Collections.IVectorView<CreateCompositePackageCatalogOptions>;\r\n        interface Windows.Foundation.Collections.IVector<InstallOptions>;\r\n        interface Windows.Foundation.Collections.IVectorView<InstallOptions>;\r\n        interface Windows.Foundation.Collections.IVector<InstallResult>;\r\n        interface Windows.Foundation.Collections.IVectorView<InstallResult>;\r\n        interface Windows.Foundation.Collections.IVector<UninstallOptions>;\r\n        interface Windows.Foundation.Collections.IVectorView<UninstallOptions>;\r\n        interface Windows.Foundation.Collections.IVector<UninstallResult>;\r\n        interface Windows.Foundation.Collections.IVectorView<UninstallResult>;\r\n        interface Windows.Foundation.Collections.IVector<DownloadOptions>;\r\n        interface Windows.Foundation.Collections.IVectorView<DownloadOptions>;\r\n        interface Windows.Foundation.Collections.IVector<DownloadResult>;\r\n        interface Windows.Foundation.Collections.IVectorView<DownloadResult>;\r\n        interface Windows.Foundation.Collections.IVector<MatchResult>;\r\n        interface Windows.Foundation.Collections.IVectorView<MatchResult>;\r\n        interface Windows.Foundation.Collections.IVector<PackageMatchFilter>;\r\n        interface Windows.Foundation.Collections.IVectorView<PackageMatchFilter>;\r\n        interface Windows.Foundation.Collections.IVector<PackageVersionId>;\r\n        interface Windows.Foundation.Collections.IVectorView<PackageVersionId>;\r\n        interface Windows.Foundation.Collections.IVector<PackageVersionInfo>;\r\n        interface Windows.Foundation.Collections.IVectorView<PackageVersionInfo>;\r\n        interface Windows.Foundation.Collections.IVector<PackageInstallerInfo>;\r\n        interface Windows.Foundation.Collections.IVectorView<PackageInstallerInfo>;\r\n        interface Windows.Foundation.Collections.IVector<InstalledStatus>;\r\n        interface Windows.Foundation.Collections.IVectorView<InstalledStatus>;\r\n        interface Windows.Foundation.Collections.IVector<PackageInstallerInstalledStatus>;\r\n        interface Windows.Foundation.Collections.IVectorView<PackageInstallerInstalledStatus>;\r\n        interface Windows.Foundation.Collections.IVector<CheckInstalledStatusResult>;\r\n        interface Windows.Foundation.Collections.IVectorView<CheckInstalledStatusResult>;\r\n        interface Windows.Foundation.Collections.IVector<SourceAgreement>;\r\n        interface Windows.Foundation.Collections.IVectorView<SourceAgreement>;\r\n        interface Windows.Foundation.Collections.IVector<PackageAgreement>;\r\n        interface Windows.Foundation.Collections.IVectorView<PackageAgreement>;\r\n        interface Windows.Foundation.Collections.IVector<Documentation>;\r\n        interface Windows.Foundation.Collections.IVectorView<Documentation>;\r\n        interface Windows.Foundation.Collections.IVector<Icon>;\r\n        interface Windows.Foundation.Collections.IVectorView<Icon>;\r\n        interface Windows.Foundation.Collections.IVector<CatalogPackageMetadata>;\r\n        interface Windows.Foundation.Collections.IVectorView<CatalogPackageMetadata>;\r\n        interface Windows.Foundation.Collections.IVector<AuthenticationArguments>;\r\n        interface Windows.Foundation.Collections.IVectorView<AuthenticationArguments>;\r\n        interface Windows.Foundation.Collections.IVector<MicrosoftEntraIdAuthenticationInfo>;\r\n        interface Windows.Foundation.Collections.IVectorView<MicrosoftEntraIdAuthenticationInfo>;\r\n        interface Windows.Foundation.Collections.IVector<AuthenticationInfo>;\r\n        interface Windows.Foundation.Collections.IVectorView<AuthenticationInfo>;\r\n        interface Windows.Foundation.Collections.IVector<RepairOptions>;\r\n        interface Windows.Foundation.Collections.IVectorView<RepairOptions>;\r\n        interface Windows.Foundation.Collections.IVector<RepairResult>;\r\n        interface Windows.Foundation.Collections.IVectorView<RepairResult>;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PackageManagerSettings.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#pragma warning( push )\r\n#pragma warning ( disable : 4467 6388)\r\n// 6388 Allow CreateInstance.\r\n#include <wil\\cppwinrt_wrl.h>\r\n// 4467 Allow use of uuid attribute for com object creation.\r\n#include \"PackageManager.h\"\r\n#include \"PackageManagerSettings.h\"\r\n#pragma warning( pop )\r\n#include \"PackageManagerSettings.g.cpp\"\r\n#include \"Helpers.h\"\r\n#include \"Public/CanUnload.h\"\r\n#include \"Public/ShutdownMonitoring.h\"\r\n#include <winget/UserSettings.h>\r\n#include <AppInstallerRuntime.h>\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    bool PackageManagerSettings::SetCallerIdentifier(hstring const& callerIdentifier)\r\n    {\r\n        bool success = false;\r\n        static std::once_flag setCallerOnceFlag;\r\n        std::call_once(setCallerOnceFlag,\r\n            [&]()\r\n            {\r\n                SetComCallerName(AppInstaller::Utility::ConvertToUTF8(callerIdentifier));\r\n                success = true;\r\n            });\r\n        return success;\r\n    }\r\n    bool PackageManagerSettings::SetStateIdentifier(hstring const& stateIdentifier)\r\n    {\r\n        bool success = false;\r\n        static std::once_flag setStateOnceFlag;\r\n        std::call_once(setStateOnceFlag,\r\n            [&]()\r\n            {\r\n                AppInstaller::Runtime::SetRuntimePathStateName(AppInstaller::Utility::ConvertToUTF8(stateIdentifier));\r\n                success = true;\r\n            });\r\n        return success;\r\n    }\r\n    bool PackageManagerSettings::SetUserSettings(hstring const& settingsContent)\r\n    {\r\n        bool success = false;\r\n        static std::once_flag setSettingsOnceFlag;\r\n        std::call_once(setSettingsOnceFlag,\r\n            [&]()\r\n            {\r\n                success = AppInstaller::Settings::TryInitializeCustomUserSettings(AppInstaller::Utility::ConvertToUTF8(settingsContent));\r\n                if (success)\r\n                {\r\n                    AppInstaller::Logging::Log().SetEnabledChannels(AppInstaller::Settings::User().Get<AppInstaller::Settings::Setting::LoggingChannelPreference>());\r\n                    AppInstaller::Logging::Log().SetLevel(AppInstaller::Settings::User().Get<AppInstaller::Settings::Setting::LoggingLevelPreference>());\r\n                }\r\n            });\r\n        return success;\r\n    }\r\n\r\n    bool PackageManagerSettings::CanUnloadPreference() const\r\n    {\r\n        return GetCanUnload();\r\n    }\r\n\r\n    void PackageManagerSettings::CanUnloadPreference(bool value)\r\n    {\r\n        SetCanUnload(value);\r\n    }\r\n\r\n    bool PackageManagerSettings::TerminationSignalMonitoring() const\r\n    {\r\n        return AppInstaller::ShutdownMonitoring::TerminationSignalHandler::Enabled();\r\n    }\r\n\r\n    void PackageManagerSettings::TerminationSignalMonitoring(bool value)\r\n    {\r\n        AppInstaller::ShutdownMonitoring::TerminationSignalHandler::Enabled(value);\r\n    }\r\n\r\n    CoCreatableMicrosoftManagementDeploymentClass(PackageManagerSettings);\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PackageManagerSettings.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"PackageManagerSettings.g.h\"\r\n#include \"Public/ComClsids.h\"\r\n#include <winget/ModuleCountBase.h>\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    [uuid(WINGET_INPROC_ONLY_COM_CLSID_PackageManagerSettings)]\r\n    struct PackageManagerSettings : PackageManagerSettingsT<PackageManagerSettings>\r\n    {\r\n        PackageManagerSettings() = default;\r\n\r\n        // Contract 4.0\r\n        bool SetCallerIdentifier(hstring const& callerIdentifier);\r\n        bool SetStateIdentifier(hstring const& stateIdentifier);\r\n        bool SetUserSettings(hstring const& settingsContent);\r\n\r\n        // Contract 28\r\n        bool CanUnloadPreference() const;\r\n        void CanUnloadPreference(bool value);\r\n        bool TerminationSignalMonitoring() const;\r\n        void TerminationSignalMonitoring(bool value);\r\n    };\r\n}\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\nnamespace winrt::Microsoft::Management::Deployment::factory_implementation\r\n{\r\n    struct PackageManagerSettings : PackageManagerSettingsT<PackageManagerSettings, implementation::PackageManagerSettings>, AppInstaller::WinRT::ModuleCountBase\r\n    {\r\n    };\r\n}\r\n#endif\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PackageMatchFilter.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include <winget/RepositorySource.h>\r\n#include \"Workflows/WorkflowBase.h\"\r\n#include \"Converters.h\"\r\n#pragma warning( push )\r\n#pragma warning ( disable : 4467 6388)\r\n// 6388 Allow CreateInstance.\r\n#include <wil\\cppwinrt_wrl.h>\r\n// 4467 Allow use of uuid attribute for com object creation.\r\n#include \"PackageMatchFilter.h\"\r\n#pragma warning( pop )\r\n#include \"PackageMatchFilter.g.cpp\"\r\n#include \"Helpers.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    void PackageMatchFilter::Initialize(::AppInstaller::Repository::PackageMatchFilter matchFilter)\r\n    {\r\n        m_value = winrt::to_hstring(matchFilter.Value);\r\n        m_matchField = GetDeploymentMatchField(matchFilter.Field);\r\n        m_packageFieldMatchOption = GetDeploymentMatchOption(matchFilter.Type);\r\n    }\r\n    winrt::Microsoft::Management::Deployment::PackageFieldMatchOption PackageMatchFilter::Option()\r\n    {\r\n        return m_packageFieldMatchOption;\r\n    }\r\n    void PackageMatchFilter::Option(winrt::Microsoft::Management::Deployment::PackageFieldMatchOption const& value)\r\n    {\r\n        m_packageFieldMatchOption = value;\r\n    }\r\n    winrt::Microsoft::Management::Deployment::PackageMatchField PackageMatchFilter::Field()\r\n    {\r\n        return m_matchField;\r\n    }\r\n    void PackageMatchFilter::Field(winrt::Microsoft::Management::Deployment::PackageMatchField const& value)\r\n    {\r\n        m_matchField = value;\r\n    }\r\n    hstring PackageMatchFilter::Value()\r\n    {\r\n        return hstring(m_value);\r\n    }\r\n    void PackageMatchFilter::Value(hstring const& value)\r\n    {\r\n        m_value = value;\r\n    }\r\n\r\n    CoCreatableMicrosoftManagementDeploymentClass(PackageMatchFilter);\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PackageMatchFilter.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"PackageMatchFilter.g.h\"\r\n#include \"Public/ComClsids.h\"\r\n#include <winget/ModuleCountBase.h>\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\nnamespace AppInstaller::Repository\r\n{\r\n    struct PackageMatchFilter;\r\n}\r\n#endif\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    [uuid(WINGET_OUTOFPROC_COM_CLSID_PackageMatchFilter)]\r\n    struct PackageMatchFilter : PackageMatchFilterT<PackageMatchFilter>\r\n    {\r\n        PackageMatchFilter() = default;\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        void Initialize(::AppInstaller::Repository::PackageMatchFilter matchFilter);\r\n#endif\r\n\r\n        winrt::Microsoft::Management::Deployment::PackageFieldMatchOption Option();\r\n        void Option(winrt::Microsoft::Management::Deployment::PackageFieldMatchOption const& value);\r\n        winrt::Microsoft::Management::Deployment::PackageMatchField Field();\r\n        void Field(winrt::Microsoft::Management::Deployment::PackageMatchField const& value);\r\n        hstring Value();\r\n        void Value(hstring const& value);\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        hstring m_value;\r\n        winrt::Microsoft::Management::Deployment::PackageMatchField m_matchField = winrt::Microsoft::Management::Deployment::PackageMatchField::CatalogDefault;\r\n        winrt::Microsoft::Management::Deployment::PackageFieldMatchOption m_packageFieldMatchOption = winrt::Microsoft::Management::Deployment::PackageFieldMatchOption::Equals;\r\n#endif\r\n    };\r\n}\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\nnamespace winrt::Microsoft::Management::Deployment::factory_implementation\r\n{\r\n    struct PackageMatchFilter : PackageMatchFilterT<PackageMatchFilter, implementation::PackageMatchFilter>, AppInstaller::WinRT::ModuleCountBase\r\n    {\r\n    };\r\n}\r\n#endif\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PackageVersionId.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include <winget/RepositorySource.h>\n#include \"PackageVersionId.h\"\n#include \"PackageVersionId.g.cpp\"\n#include <wil\\cppwinrt_wrl.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    void PackageVersionId::Initialize(::AppInstaller::Repository::PackageVersionKey packageVersionKey)\n    {\n        m_packageVersionKey = packageVersionKey;\n    }\n    hstring PackageVersionId::PackageCatalogId()\n    {\n        return winrt::to_hstring(m_packageVersionKey.SourceId);\n    }\n    hstring PackageVersionId::Version()\n    {\n        return winrt::to_hstring(m_packageVersionKey.Version);\n    }\n    hstring PackageVersionId::Channel()\n    {\n        return winrt::to_hstring(m_packageVersionKey.Channel);\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PackageVersionId.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"PackageVersionId.g.h\"\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    struct PackageVersionId : PackageVersionIdT<PackageVersionId>\n    {\n        PackageVersionId() = default;\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void Initialize(::AppInstaller::Repository::PackageVersionKey packageVersionKey);\n#endif\n\n        hstring PackageCatalogId();\n        hstring Version();\n        hstring Channel();\n        \n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        ::AppInstaller::Repository::PackageVersionKey m_packageVersionKey{};\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PackageVersionInfo.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include <mutex>\r\n#include <winget/RepositorySource.h>\r\n#include \"PackageVersionInfo.h\"\r\n#include \"PackageVersionInfo.g.cpp\"\r\n#include \"PackageCatalogInfo.h\"\r\n#include \"PackageCatalog.h\"\r\n#include \"PackageInstallerInfo.h\"\r\n#include \"CatalogPackage.h\"\r\n#include \"CatalogPackageMetadata.h\"\r\n#include \"ComContext.h\"\r\n#include \"Workflows/WorkflowBase.h\"\r\n#include <winget/ManifestComparator.h>\r\n#include \"winget/RepositorySearch.h\"\r\n#include \"AppInstallerVersions.h\"\r\n#include \"Converters.h\"\r\n#pragma warning( push )\r\n#pragma warning ( disable : 4467 )\r\n// 4467 Allow use of uuid attribute for com object creation.\r\n#include \"PackageManager.h\"\r\n#pragma warning( pop )\r\n#include <wil\\cppwinrt_wrl.h>\r\n#include <winget/Locale.h>\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    namespace\r\n    {\r\n        // Do the same thing as PopulateContextFromInstallOptions but without all the string conversions.\r\n        AppInstaller::Manifest::ManifestComparator::Options GetComparatorOptionsFromInstallOptions(InstallOptions options)\r\n        {\r\n            AppInstaller::Manifest::ManifestComparator::Options result;\r\n\r\n            auto installerType = GetManifestInstallerType(options.InstallerType());\r\n            if (installerType != AppInstaller::Manifest::InstallerTypeEnum::Unknown)\r\n            {\r\n                result.RequestedInstallerType = installerType;\r\n            }\r\n\r\n            auto manifestScope = GetManifestScope(options.PackageInstallScope());\r\n            if (manifestScope.first != ::AppInstaller::Manifest::ScopeEnum::Unknown)\r\n            {\r\n                result.RequestedInstallerScope = manifestScope.first;\r\n                result.AllowUnknownScope = manifestScope.second;\r\n            }\r\n\r\n            if (options.AllowedArchitectures().Size() != 0)\r\n            {\r\n                for (auto architecture : options.AllowedArchitectures())\r\n                {\r\n                    auto convertedArchitecture = GetUtilityArchitecture(architecture);\r\n                    if (convertedArchitecture)\r\n                    {\r\n                        result.AllowedArchitectures.push_back(convertedArchitecture.value());\r\n                    }\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n\r\n    void PackageVersionInfo::Initialize(std::shared_ptr<::AppInstaller::Repository::IPackageVersion> packageVersion)\r\n    {\r\n        m_packageVersion = std::move(packageVersion);\r\n    }\r\n    std::shared_ptr<::AppInstaller::Repository::IPackageVersion> PackageVersionInfo::GetRepositoryPackageVersion()\r\n    {\r\n        return m_packageVersion;\r\n    }\r\n    hstring PackageVersionInfo::GetMetadata(winrt::Microsoft::Management::Deployment::PackageVersionMetadataField const& metadataField)\r\n    {\r\n        ::AppInstaller::Repository::PackageVersionMetadata metadataKey = GetRepositoryPackageVersionMetadata(metadataField);\r\n        ::AppInstaller::Repository::IPackageVersion::Metadata metadata = m_packageVersion->GetMetadata();\r\n        auto result = metadata.find(metadataKey);\r\n        if (result == metadata.end())\r\n        {\r\n            return {};\r\n        }\r\n\r\n        hstring resultString = winrt::to_hstring(result->second);\r\n        // The api uses \"System\" rather than \"Machine\" for install scope.\r\n        if (metadataField == PackageVersionMetadataField::InstalledScope && resultString == L\"Machine\")\r\n        {\r\n            return winrt::to_hstring(L\"System\");\r\n        }\r\n        return resultString;\r\n    }\r\n    hstring PackageVersionInfo::Id()\r\n    {\r\n        return winrt::to_hstring(m_packageVersion->GetProperty(::AppInstaller::Repository::PackageVersionProperty::Id).get());\r\n    }\r\n    hstring PackageVersionInfo::DisplayName()\r\n    {\r\n        return winrt::to_hstring(m_packageVersion->GetProperty(::AppInstaller::Repository::PackageVersionProperty::Name).get());\r\n    }\r\n    hstring PackageVersionInfo::Publisher()\r\n    {\r\n        return winrt::to_hstring(m_packageVersion->GetProperty(::AppInstaller::Repository::PackageVersionProperty::Publisher).get());\r\n    }\r\n    hstring PackageVersionInfo::Version()\r\n    {\r\n        return winrt::to_hstring(m_packageVersion->GetProperty(::AppInstaller::Repository::PackageVersionProperty::Version).get());\r\n    }\r\n    hstring PackageVersionInfo::Channel()\r\n    {\r\n        return winrt::to_hstring(m_packageVersion->GetProperty(::AppInstaller::Repository::PackageVersionProperty::Channel).get());\r\n    }\r\n    winrt::Windows::Foundation::Collections::IVectorView<hstring> PackageVersionInfo::PackageFamilyNames()\r\n    {\r\n        if (!m_packageFamilyNames)\r\n        {\r\n            // Vector hasn't been created yet, create and populate it.\r\n            auto packageFamilyNames = winrt::single_threaded_vector<hstring>(); \r\n            for (auto&& string : m_packageVersion->GetMultiProperty(::AppInstaller::Repository::PackageVersionMultiProperty::PackageFamilyName))\r\n            {\r\n                packageFamilyNames.Append(winrt::to_hstring(string));\r\n            }\r\n            m_packageFamilyNames = packageFamilyNames;\r\n        }\r\n        return m_packageFamilyNames.GetView();\r\n    }\r\n    winrt::Windows::Foundation::Collections::IVectorView<hstring> PackageVersionInfo::ProductCodes()\r\n    {\r\n        if (!m_productCodes)\r\n        {\r\n            // Vector hasn't been created yet, create and populate it.\r\n            auto productCodes = winrt::single_threaded_vector<hstring>();\r\n            for (auto&& string : m_packageVersion->GetMultiProperty(::AppInstaller::Repository::PackageVersionMultiProperty::ProductCode))\r\n            {\r\n                productCodes.Append(winrt::to_hstring(string));\r\n            }\r\n            m_productCodes = productCodes;\r\n        }\r\n        return m_productCodes.GetView();\r\n    }\r\n    winrt::Microsoft::Management::Deployment::PackageCatalog PackageVersionInfo::PackageCatalog()\r\n    {\r\n        if (!m_packageCatalog)\r\n        {\r\n            auto packageCatalogInfo = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalogInfo>>();\r\n            packageCatalogInfo->Initialize(m_packageVersion->GetSource().GetDetails());\r\n            auto packageCatalog = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageCatalog>>();\r\n            packageCatalog->Initialize(*packageCatalogInfo, m_packageVersion->GetSource(), false);\r\n            m_packageCatalog = *packageCatalog;\r\n        }\r\n        return m_packageCatalog;\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::CompareResult PackageVersionInfo::CompareToVersion(const hstring& versionString)\r\n    {\r\n        if (versionString.empty())\r\n        {\r\n            return CompareResult::Unknown;\r\n        }\r\n\r\n        AppInstaller::Utility::Version thisVersion{ m_packageVersion->GetProperty(::AppInstaller::Repository::PackageVersionProperty::Version).get() };\r\n        AppInstaller::Utility::Version otherVersion{ AppInstaller::Utility::ConvertToUTF8(versionString) };\r\n\r\n        if (thisVersion < otherVersion)\r\n        {\r\n            return CompareResult::Lesser;\r\n        }\r\n        else if (otherVersion < thisVersion)\r\n        {\r\n            return CompareResult::Greater;\r\n        }\r\n        else\r\n        {\r\n            return CompareResult::Equal;\r\n        }\r\n    }\r\n    bool PackageVersionInfo::HasApplicableInstaller(InstallOptions options)\r\n    {\r\n        AppInstaller::Manifest::ManifestComparator manifestComparator{ GetComparatorOptionsFromInstallOptions(options) };\r\n        AppInstaller::Manifest::Manifest manifest = m_packageVersion->GetManifest();\r\n        auto result = manifestComparator.GetPreferredInstaller(manifest);\r\n        return result.installer.has_value();\r\n    }\r\n    winrt::Microsoft::Management::Deployment::PackageInstallerInfo PackageVersionInfo::GetApplicableInstaller(InstallOptions options)\r\n    {\r\n        AppInstaller::Manifest::ManifestComparator manifestComparator{ GetComparatorOptionsFromInstallOptions(options) };\r\n        AppInstaller::Manifest::Manifest manifest = m_packageVersion->GetManifest();\r\n        auto result = manifestComparator.GetPreferredInstaller(manifest);\r\n\r\n        if (result.installer.has_value())\r\n        {\r\n            auto packageInstallerInfo = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::PackageInstallerInfo>>();\r\n            packageInstallerInfo->Initialize(result.installer.value());\r\n            return *packageInstallerInfo;\r\n        }\r\n        else\r\n        {\r\n            return nullptr;\r\n        }\r\n    }\r\n    Microsoft::Management::Deployment::CatalogPackageMetadata PackageVersionInfo::GetCatalogPackageMetadata()\r\n    {\r\n        auto catalogPackageMetadata = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::CatalogPackageMetadata>>();\r\n        if (m_packageVersion)\r\n        {\r\n            auto manifest = m_packageVersion->GetManifest();\r\n            manifest.ApplyLocale();\r\n            catalogPackageMetadata->Initialize(manifest.CurrentLocalization);\r\n        }\r\n\r\n        return *catalogPackageMetadata;\r\n    }\r\n    Microsoft::Management::Deployment::CatalogPackageMetadata PackageVersionInfo::GetCatalogPackageMetadata(const hstring& preferredLocale)\r\n    {\r\n        std::string localeString = winrt::to_string(preferredLocale);\r\n        if (!::AppInstaller::Locale::IsWellFormedBcp47Tag(localeString))\r\n        {\r\n            throw hresult_invalid_argument();\r\n        }\r\n\r\n        auto catalogPackageMetadata = winrt::make_self<wil::details::module_count_wrapper<winrt::Microsoft::Management::Deployment::implementation::CatalogPackageMetadata>>();\r\n        if (m_packageVersion)\r\n        {\r\n            auto manifest = m_packageVersion->GetManifest();\r\n            manifest.ApplyLocale(localeString);\r\n            catalogPackageMetadata->Initialize(manifest.CurrentLocalization);\r\n        }\r\n\r\n        return *catalogPackageMetadata;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PackageVersionInfo.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"PackageVersionInfo.g.h\"\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    struct PackageVersionInfo : PackageVersionInfoT<PackageVersionInfo>\n    {\n        PackageVersionInfo() = default;\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void Initialize(std::shared_ptr<::AppInstaller::Repository::IPackageVersion> packageVersion);\n        std::shared_ptr<::AppInstaller::Repository::IPackageVersion> GetRepositoryPackageVersion();\n#endif\n\n        hstring GetMetadata(winrt::Microsoft::Management::Deployment::PackageVersionMetadataField const& metadataField);\n        hstring Id();\n        hstring DisplayName();\n        hstring Publisher();\n        hstring Version();\n        hstring Channel();\n        winrt::Windows::Foundation::Collections::IVectorView<hstring> PackageFamilyNames();\n        winrt::Windows::Foundation::Collections::IVectorView<hstring> ProductCodes();\n        winrt::Microsoft::Management::Deployment::PackageCatalog PackageCatalog();\n        winrt::Microsoft::Management::Deployment::CompareResult CompareToVersion(const hstring& versionString);\n        // Contract 4.0\n        bool HasApplicableInstaller(InstallOptions options);\n        // Contract 6.0\n        winrt::Microsoft::Management::Deployment::CatalogPackageMetadata GetCatalogPackageMetadata();\n        winrt::Microsoft::Management::Deployment::CatalogPackageMetadata GetCatalogPackageMetadata(const hstring& preferredLocale);\n        winrt::Microsoft::Management::Deployment::PackageInstallerInfo GetApplicableInstaller(InstallOptions options);\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        winrt::Microsoft::Management::Deployment::PackageCatalog m_packageCatalog{ nullptr };\n        std::shared_ptr<::AppInstaller::Repository::IPackageVersion> m_packageVersion;\n        Windows::Foundation::Collections::IVector<hstring> m_packageFamilyNames{ nullptr };\n        Windows::Foundation::Collections::IVector<hstring> m_productCodes{ nullptr };\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/PropertySheet.props",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ImportGroup Label=\"PropertySheets\" />\n  <PropertyGroup Label=\"UserMacros\" />\n  <!--\n    To customize common C++/WinRT project properties: \n    * right-click the project node\n    * expand the Common Properties item\n    * select the C++/WinRT property page\n\n    For more advanced scenarios, and complete documentation, please see:\n    https://github.com/Microsoft/cppwinrt/tree/master/nuget \n    -->\n  <PropertyGroup />\n  <ItemDefinitionGroup />\n</Project>"
  },
  {
    "path": "src/Microsoft.Management.Deployment/Public/CanUnload.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    // Sets whether the module can unload or not.\r\n    void SetCanUnload(bool value);\r\n\r\n    // Gets whether the module can unload or not.\r\n    bool GetCanUnload();\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/Public/CoCreatableMicrosoftManagementDeploymentClass.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <AppInstallerErrors.h>\r\n#include <winget/GroupPolicy.h>\r\n#include <winget/ModuleCountBase.h>\r\n#include <wil\\cppwinrt_wrl.h>\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    // Enable custom code to run before creating any object through the factory.\r\n    // Currently that means requiring the overall WinGet policy to be enabled.\r\n    template <typename TCppWinRTClass>\r\n    class wrl_factory_for_winrt_com_class : public ::wil::wrl_factory_for_winrt_com_class<TCppWinRTClass>\r\n    {\r\n    public:\r\n        IFACEMETHODIMP CreateInstance(_In_opt_::IUnknown* unknownOuter, REFIID riid, _COM_Outptr_ void** object) noexcept try\r\n        {\r\n            *object = nullptr;\r\n            RETURN_HR_IF(APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY, !::AppInstaller::Settings::GroupPolicies().IsEnabled(::AppInstaller::Settings::TogglePolicy::Policy::WinGet));\r\n\r\n            return ::wil::wrl_factory_for_winrt_com_class<TCppWinRTClass>::CreateInstance(unknownOuter, riid, object);\r\n        }\r\n        CATCH_RETURN()\r\n    };\r\n\r\n#define CoCreatableMicrosoftManagementDeploymentClass(className) \\\r\n    CoCreatableClassWithFactory(className, ::winrt::Microsoft::Management::Deployment::implementation::wrl_factory_for_winrt_com_class<className>) \\\r\n    void CoCreatableMicrosoftManagementDeploymentClass_WRL_ModuleCountCheckFor_ ## className() { \\\r\n        static_assert(__is_base_of(::AppInstaller::WinRT::ModuleCountBase, ::winrt::Microsoft::Management::Deployment::factory_implementation:: ## className), \"Object factories must derive from AppInstaller::WinRT::ModuleCountBase\"); \\\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/Public/ComClsids.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <guiddef.h>\r\n\r\n// Clsids for out-of-proc com invocation\r\n#if USE_PROD_CLSIDS \r\n#define WINGET_OUTOFPROC_COM_CLSID_PackageManager \"C53A4F16-787E-42A4-B304-29EFFB4BF597\"\r\n#define WINGET_OUTOFPROC_COM_CLSID_FindPackagesOptions \"572DED96-9C60-4526-8F92-EE7D91D38C1A\"\r\n#define WINGET_OUTOFPROC_COM_CLSID_CreateCompositePackageCatalogOptions \"526534B8-7E46-47C8-8416-B1685C327D37\"\r\n#define WINGET_OUTOFPROC_COM_CLSID_InstallOptions \"1095F097-EB96-453B-B4E6-1613637F3B14\"\r\n#define WINGET_OUTOFPROC_COM_CLSID_UninstallOptions \"E1D9A11E-9F85-4D87-9C17-2B93143ADB8D\"\r\n#define WINGET_OUTOFPROC_COM_CLSID_PackageMatchFilter \"D02C9DAF-99DC-429C-B503-4E504E4AB000\"\r\n#define WINGET_OUTOFPROC_COM_CLSID_ConfigurationStaticFunctions \"73D763B7-2937-432F-A97A-D98A4A596126\"\r\n#define WINGET_OUTOFPROC_COM_CLSID_DownloadOptions \"4CBABE76-7322-4BE4-9CEA-2589A80682DC\"\r\n#define WINGET_OUTOFPROC_COM_CLSID_AuthenticationArguments \"BA580786-BDE3-4F6C-B8F3-44698AC8711A\"\r\n#define WINGET_OUTOFPROC_COM_CLSID_RepairOptions \"0498F441-3097-455F-9CAF-148F28293865\"\r\n#define WINGET_OUTOFPROC_COM_CLSID_AddPackageCatalogOptions \"DB9D012D-00D7-47EE-8FB1-606E10AC4F51\"\r\n#define WINGET_OUTOFPROC_COM_CLSID_RemovePackageCatalogOptions \"032B1C58-B975-469B-A013-E632B6ECE8D8\"\r\n#define WINGET_OUTOFPROC_COM_CLSID_EditPackageCatalogOptions \"A9F5E736-68CE-463C-BA6D-DE968F0CCE04\"\r\n#else\r\n#define WINGET_OUTOFPROC_COM_CLSID_PackageManager \"74CB3139-B7C5-4B9E-9388-E6616DEA288C\"\r\n#define WINGET_OUTOFPROC_COM_CLSID_FindPackagesOptions \"1BD8FF3A-EC50-4F69-AEEE-DF4C9D3BAA96\"\r\n#define WINGET_OUTOFPROC_COM_CLSID_CreateCompositePackageCatalogOptions \"EE160901-B317-4EA7-9CC6-5355C6D7D8A7\"\r\n#define WINGET_OUTOFPROC_COM_CLSID_InstallOptions \"44FE0580-62F7-44D4-9E91-AA9614AB3E86\"\r\n#define WINGET_OUTOFPROC_COM_CLSID_UninstallOptions \"AA2A5C04-1AD9-46C4-B74F-6B334AD7EB8C\"\r\n#define WINGET_OUTOFPROC_COM_CLSID_PackageMatchFilter \"3F85B9F4-487A-4C48-9035-2903F8A6D9E8\"\r\n#define WINGET_OUTOFPROC_COM_CLSID_ConfigurationStaticFunctions \"C9ED7917-66AB-4E31-A92A-F65F18EF7933\"\r\n#define WINGET_OUTOFPROC_COM_CLSID_DownloadOptions \"8EF324ED-367C-4880-83E5-BB2ABD0B72F6\"\r\n#define WINGET_OUTOFPROC_COM_CLSID_AuthenticationArguments \"6484A61D-50FA-41F0-B71E-F4370C6EB37C\"\r\n#define WINGET_OUTOFPROC_COM_CLSID_RepairOptions \"E62BB1E7-C7B2-4AEC-9E28-FB649B30FF03\"\r\n#define WINGET_OUTOFPROC_COM_CLSID_AddPackageCatalogOptions \"D58C7E4C-70E6-476C-A5D4-80341ED80252\"\r\n#define WINGET_OUTOFPROC_COM_CLSID_RemovePackageCatalogOptions \"87A96609-1A39-4955-BE72-7174E147B7DC\"\r\n#define WINGET_OUTOFPROC_COM_CLSID_EditPackageCatalogOptions \"29B19238-81AD-4A8E-A2FC-ADF17C38CAEB\"\r\n#endif\r\n\r\n// Clsids only used in in-proc invocation\r\n#define WINGET_INPROC_ONLY_COM_CLSID_PackageManagerSettings \"80CF9D63-5505-4342-B9B4-BB87895CA8BB\"\r\n\r\nnamespace winrt::Microsoft::Management::Deployment\r\n{\r\n    // clsid constants for in-proc com invocation\r\n    const CLSID WINGET_INPROC_COM_CLSID_PackageManager = { 0x2DDE4456, 0x64D9, 0x4673, 0x8F, 0x7E, 0xA4, 0xF1, 0x9A, 0x2E, 0x6C, 0xC3 }; // 2DDE4456-64D9-4673-8F7E-A4F19A2E6CC3\r\n    const CLSID WINGET_INPROC_COM_CLSID_FindPackagesOptions = { 0x96B9A53A, 0x9228, 0x4DA0, 0xB0, 0x13, 0xBB, 0x1B, 0x20, 0x31, 0xAB, 0x3D }; // 96B9A53A-9228-4DA0-B013-BB1B2031AB3D\r\n    const CLSID WINGET_INPROC_COM_CLSID_CreateCompositePackageCatalogOptions = { 0x768318A6, 0x2EB5, 0x400D, 0x84, 0xD0, 0xDF, 0x35, 0x34, 0xC3, 0x0F, 0x5D }; // 768318A6-2EB5-400D-84D0-DF3534C30F5D\r\n    const CLSID WINGET_INPROC_COM_CLSID_InstallOptions = { 0xE2AF3BA8, 0x8A88, 0x4766, 0x9D, 0xDA, 0xAE, 0x40, 0x13, 0xAD, 0xE2, 0x86 }; // E2AF3BA8-8A88-4766-9DDA-AE4013ADE286\r\n    const CLSID WINGET_INPROC_COM_CLSID_UninstallOptions = { 0x869CB959, 0xEB54, 0x425C, 0xA1, 0xE4, 0x1A, 0x1C, 0x29, 0x1C, 0x64, 0xE9 }; // 869CB959-EB54-425C-A1E4-1A1C291C64E9\r\n    const CLSID WINGET_INPROC_COM_CLSID_PackageMatchFilter = { 0x57DC8962, 0x7343, 0x42CD, 0xB9, 0x1C, 0x04, 0xF6, 0xA2, 0x5D, 0xB1, 0xD0 }; // 57DC8962-7343-42CD-B91C-04F6A25DB1D0\r\n    const CLSID WINGET_INPROC_COM_CLSID_PackageManagerSettings = { 0x80CF9D63, 0x5505, 0x4342, 0xB9, 0xB4, 0xBB, 0x87, 0x89, 0x5C, 0xA8, 0xBB }; // 80CF9D63-5505-4342-B9B4-BB87895CA8BB\r\n    const CLSID WINGET_INPROC_COM_CLSID_DownloadOptions = { 0x4288DF96, 0xFDC9, 0x4B68, 0xB4, 0x03, 0x19, 0x3D, 0xBB, 0xF5, 0x6A, 0x24 }; // 4288DF96-FDC9-4B68-B403-193DBBF56A24\r\n    const CLSID WINGET_INPROC_COM_CLSID_AuthenticationArguments = { 0x8D593114, 0x1CF1, 0x43B9, 0x87, 0x22, 0x4D, 0xBB, 0x30, 0x10, 0x32, 0x96 }; // 8D593114-1CF1-43B9-8722-4DBB30103296\r\n    const CLSID WINGET_INPROC_COM_CLSID_RepairOptions = { 0x30c024c4, 0x852c, 0x4dd4, 0x98, 0x10, 0x13, 0x48, 0xc5, 0x1e, 0xf9, 0xbb }; // {30C024C4-852C-4DD4-9810-1348C51EF9BB}\r\n    const CLSID WINGET_INPROC_COM_CLSID_AddPackageCatalogOptions = { 0x24e6f1fa, 0xe4c3, 0x4acd, 0x96, 0x5d, 0xdf, 0x21, 0x3f, 0xd5, 0x8f, 0x15 }; // {24E6F1FA-E4C3-4ACD-965D-DF213FD58F15}\r\n    const CLSID WINGET_INPROC_COM_CLSID_RemovePackageCatalogOptions = { 0x1125d3a6, 0xe2ce, 0x479a, 0x91, 0xd5, 0x71, 0xa3, 0xf6, 0xf8, 0xb0, 0xb }; // {1125D3A6-E2CE-479A-91D5-71A3F6F8B00B}\r\n    const CLSID WINGET_INPROC_COM_CLSID_EditPackageCatalogOptions = { 0xe8e12fe1, 0xab77, 0x40c4, 0xa5, 0x62, 0xe9, 0x1f, 0xb5, 0x1b, 0x4e, 0x82 }; // {E8E12FE1-AB77-40C4-A562-E91FB51B4E82}\r\n\r\n    CLSID GetRedirectedClsidFromInProcClsid(REFCLSID clsid);\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/RefreshPackageCatalogResult.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"RefreshPackageCatalogResult.h\"\r\n#include \"RefreshPackageCatalogResult.g.cpp\"\r\n#include <wil\\cppwinrt_wrl.h>\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    void RefreshPackageCatalogResult::Initialize(\r\n        winrt::Microsoft::Management::Deployment::RefreshPackageCatalogStatus status,\r\n        winrt::hresult extendedErrorCode)\r\n    {\r\n        m_status = status;\r\n        m_extendedErrorCode = extendedErrorCode;\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::RefreshPackageCatalogStatus RefreshPackageCatalogResult::Status()\r\n    {\r\n        return m_status;\r\n    }\r\n\r\n    winrt::hresult RefreshPackageCatalogResult::ExtendedErrorCode()\r\n    {\r\n        return m_extendedErrorCode;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/RefreshPackageCatalogResult.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"RefreshPackageCatalogResult.g.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    struct RefreshPackageCatalogResult : RefreshPackageCatalogResultT<RefreshPackageCatalogResult>\r\n    {\r\n        RefreshPackageCatalogResult() = default;\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        void Initialize(\r\n            winrt::Microsoft::Management::Deployment::RefreshPackageCatalogStatus status,\r\n            winrt::hresult extendedErrorCode);\r\n#endif\r\n\r\n        winrt::Microsoft::Management::Deployment::RefreshPackageCatalogStatus Status();\r\n        winrt::hresult ExtendedErrorCode();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        winrt::Microsoft::Management::Deployment::RefreshPackageCatalogStatus m_status = winrt::Microsoft::Management::Deployment::RefreshPackageCatalogStatus::Ok;\r\n        winrt::hresult m_extendedErrorCode = S_OK;\r\n#endif\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/RemovePackageCatalogOptions.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#pragma warning( push )\r\n#pragma warning ( disable : 4467 6388)\r\n// 6388 Allow CreateInstance.\r\n#include <wil\\cppwinrt_wrl.h>\r\n// 4467 Allow use of uuid attribute for com object creation.\r\n#include \"RemovePackageCatalogOptions.h\"\r\n#pragma warning( pop )\r\n#include \"RemovePackageCatalogOptions.g.cpp\"\r\n#include \"Converters.h\"\r\n#include \"Helpers.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    hstring RemovePackageCatalogOptions::Name()\r\n    {\r\n        return hstring(m_name);\r\n    }\r\n    void RemovePackageCatalogOptions::Name(hstring const& value)\r\n    {\r\n        m_name = value;\r\n    }\r\n    bool RemovePackageCatalogOptions::PreserveData()\r\n    {\r\n        return m_preserveData;\r\n    }\r\n    void RemovePackageCatalogOptions::PreserveData(bool const& value)\r\n    {\r\n        m_preserveData = value;\r\n    }\r\n\r\n    CoCreatableMicrosoftManagementDeploymentClass(RemovePackageCatalogOptions);\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/RemovePackageCatalogOptions.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"RemovePackageCatalogOptions.g.h\"\r\n#include \"public/ComClsids.h\"\r\n#include <winget/ModuleCountBase.h>\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    [uuid(WINGET_OUTOFPROC_COM_CLSID_RemovePackageCatalogOptions)]\r\n    struct RemovePackageCatalogOptions : RemovePackageCatalogOptionsT<RemovePackageCatalogOptions>\r\n    {\r\n        RemovePackageCatalogOptions() = default;\r\n\r\n        hstring Name();\r\n        void Name(hstring const& value);\r\n\r\n        bool PreserveData();\r\n        void PreserveData(bool const& value);\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        hstring m_name = L\"\";\r\n        bool m_preserveData = false;\r\n#endif\r\n    };\r\n}\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\nnamespace winrt::Microsoft::Management::Deployment::factory_implementation\r\n{\r\n    struct RemovePackageCatalogOptions :\r\n        RemovePackageCatalogOptionsT<RemovePackageCatalogOptions, implementation::RemovePackageCatalogOptions>,\r\n        AppInstaller::WinRT::ModuleCountBase\r\n    {\r\n    };\r\n}\r\n#endif\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/RemovePackageCatalogResult.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"RemovePackageCatalogResult.h\"\r\n#include \"RemovePackageCatalogResult.g.cpp\"\r\n#include <wil\\cppwinrt_wrl.h>\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    void RemovePackageCatalogResult::Initialize(\r\n        winrt::Microsoft::Management::Deployment::RemovePackageCatalogStatus status,\r\n        winrt::hresult extendedErrorCode)\r\n    {\r\n        m_status = status;\r\n        m_extendedErrorCode = extendedErrorCode;\r\n    }\r\n    winrt::Microsoft::Management::Deployment::RemovePackageCatalogStatus RemovePackageCatalogResult::Status()\r\n    {\r\n        return m_status;\r\n    }\r\n    winrt::hresult RemovePackageCatalogResult::ExtendedErrorCode()\r\n    {\r\n        return m_extendedErrorCode;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/RemovePackageCatalogResult.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"RemovePackageCatalogResult.g.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    struct RemovePackageCatalogResult : RemovePackageCatalogResultT<RemovePackageCatalogResult>\r\n    {\r\n        RemovePackageCatalogResult() = default;\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        void Initialize(\r\n            winrt::Microsoft::Management::Deployment::RemovePackageCatalogStatus status,\r\n            winrt::hresult extendedErrorCode);\r\n#endif\r\n\r\n        winrt::Microsoft::Management::Deployment::RemovePackageCatalogStatus Status();\r\n        winrt::hresult ExtendedErrorCode();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        winrt::Microsoft::Management::Deployment::RemovePackageCatalogStatus m_status = winrt::Microsoft::Management::Deployment::RemovePackageCatalogStatus::Ok;\r\n        winrt::hresult m_extendedErrorCode = S_OK;\r\n#endif\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/RepairOptions.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n\r\n#include \"pch.h\"\r\n#pragma warning( push )\r\n#pragma warning ( disable : 4467 6388)\r\n// 6388 Allow CreateInstance.\r\n#include <wil\\cppwinrt_wrl.h>\r\n// 4467 Allow use of uuid attribute for com object creation.\r\n#include \"RepairOptions.h\"\r\n#pragma warning( pop )\r\n#include \"RepairOptions.g.cpp\"\r\n#include \"Converters.h\"\r\n#include \"Helpers.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    RepairOptions::RepairOptions()\r\n    {\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::PackageVersionId RepairOptions::PackageVersionId()\r\n    {\r\n        return m_packageVersionId;\r\n    }\r\n    void RepairOptions::PackageVersionId(winrt::Microsoft::Management::Deployment::PackageVersionId const& value)\r\n    {\r\n        m_packageVersionId = value;\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::PackageRepairScope RepairOptions::PackageRepairScope()\r\n    {\r\n        return m_packageRepairScope;\r\n    }\r\n\r\n    void RepairOptions::PackageRepairScope(winrt::Microsoft::Management::Deployment::PackageRepairScope const& value)\r\n    {\r\n        m_packageRepairScope = value;\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::PackageRepairMode RepairOptions::PackageRepairMode()\r\n    {\r\n        return m_packageRepairMode;\r\n    }\r\n\r\n    void RepairOptions::PackageRepairMode(winrt::Microsoft::Management::Deployment::PackageRepairMode const& value)\r\n    {\r\n        m_packageRepairMode = value;\r\n    }\r\n\r\n    bool RepairOptions::AcceptPackageAgreements()\r\n    {\r\n        return m_acceptPackageAgreements;\r\n    }\r\n\r\n    void RepairOptions::AcceptPackageAgreements(bool value)\r\n    {\r\n        m_acceptPackageAgreements = value;\r\n    }\r\n\r\n    hstring RepairOptions::LogOutputPath()\r\n    {\r\n        return hstring(m_logOutputPath);\r\n    }\r\n\r\n    void RepairOptions::LogOutputPath(hstring const& value)\r\n    {\r\n        m_logOutputPath = value;\r\n    }\r\n\r\n    hstring RepairOptions::CorrelationData()\r\n    {\r\n        return hstring(m_correlationData);\r\n    }\r\n\r\n    void RepairOptions::CorrelationData(hstring const& value)\r\n    {\r\n        m_correlationData = value;\r\n    }\r\n\r\n    bool RepairOptions::AllowHashMismatch()\r\n    {\r\n        return m_allowHashMismatch;\r\n    }\r\n\r\n    void RepairOptions::AllowHashMismatch(bool value)\r\n    {\r\n        m_allowHashMismatch = value;\r\n    }\r\n\r\n    bool RepairOptions::BypassIsStoreClientBlockedPolicyCheck()\r\n    {\r\n        return m_bypassIsStoreClientBlockedPolicyCheck;\r\n    }\r\n\r\n    void RepairOptions::BypassIsStoreClientBlockedPolicyCheck(bool value)\r\n    {\r\n        m_bypassIsStoreClientBlockedPolicyCheck = value;\r\n    }\r\n\r\n    bool RepairOptions::Force()\r\n    {\r\n        return m_force;\r\n    }\r\n\r\n    void RepairOptions::Force(bool value)\r\n    {\r\n        m_force = value;\r\n    }\r\n\r\n    winrt::Microsoft::Management::Deployment::AuthenticationArguments RepairOptions::AuthenticationArguments()\r\n    {\r\n        return m_authenticationArguments;\r\n    }\r\n\r\n    void RepairOptions::AuthenticationArguments(winrt::Microsoft::Management::Deployment::AuthenticationArguments const& value)\r\n    {\r\n        m_authenticationArguments = value;\r\n    }\r\n\r\n    CoCreatableMicrosoftManagementDeploymentClass(RepairOptions);\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/RepairOptions.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"RepairOptions.g.h\"\r\n#include \"Public/ComClsids.h\"\r\n#include <winget/ModuleCountBase.h>\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    [uuid(WINGET_OUTOFPROC_COM_CLSID_RepairOptions)]\r\n    struct RepairOptions : RepairOptionsT<RepairOptions>\r\n    {\r\n        RepairOptions();\r\n\r\n        winrt::Microsoft::Management::Deployment::PackageVersionId PackageVersionId();\r\n        void PackageVersionId(winrt::Microsoft::Management::Deployment::PackageVersionId const& value);\r\n        winrt::Microsoft::Management::Deployment::PackageRepairScope PackageRepairScope();\r\n        void PackageRepairScope(winrt::Microsoft::Management::Deployment::PackageRepairScope const& value);\r\n        winrt::Microsoft::Management::Deployment::PackageRepairMode PackageRepairMode();\r\n        void PackageRepairMode(winrt::Microsoft::Management::Deployment::PackageRepairMode const& value);\r\n        bool AcceptPackageAgreements();\r\n        void AcceptPackageAgreements(bool value);\r\n        hstring LogOutputPath();\r\n        void LogOutputPath(hstring const& value);\r\n        hstring CorrelationData();\r\n        void CorrelationData(hstring const& value);\r\n        bool AllowHashMismatch();\r\n        void AllowHashMismatch(bool value);\r\n        bool BypassIsStoreClientBlockedPolicyCheck();\r\n        void BypassIsStoreClientBlockedPolicyCheck(bool value);\r\n        bool Force();\r\n        void Force(bool value);\r\n        winrt::Microsoft::Management::Deployment::AuthenticationArguments AuthenticationArguments();\r\n        void AuthenticationArguments(winrt::Microsoft::Management::Deployment::AuthenticationArguments const& value);\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        winrt::Microsoft::Management::Deployment::PackageVersionId m_packageVersionId{ nullptr };\r\n        bool m_acceptPackageAgreements = false;\r\n        bool m_allowHashMismatch = false;\r\n        bool m_bypassIsStoreClientBlockedPolicyCheck = false;\r\n        bool m_force = false;\r\n        std::wstring m_logOutputPath = L\"\";\r\n        std::wstring m_correlationData = L\"\";\r\n        winrt::Microsoft::Management::Deployment::PackageRepairScope m_packageRepairScope = winrt::Microsoft::Management::Deployment::PackageRepairScope::Any;\r\n        winrt::Microsoft::Management::Deployment::PackageRepairMode m_packageRepairMode = winrt::Microsoft::Management::Deployment::PackageRepairMode::Default;\r\n        winrt::Microsoft::Management::Deployment::AuthenticationArguments m_authenticationArguments{ nullptr };\r\n#endif\r\n    };\r\n}\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\nnamespace winrt::Microsoft::Management::Deployment::factory_implementation\r\n{\r\n    struct RepairOptions : RepairOptionsT<RepairOptions, implementation::RepairOptions>, AppInstaller::WinRT::ModuleCountBase\r\n    {\r\n    };\r\n}\r\n#endif\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/RepairResult.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n\r\n#include \"pch.h\"\r\n#include \"RepairResult.h\"\r\n#include \"RepairResult.g.cpp\"\r\n#include <wil\\cppwinrt_wrl.h>\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    void RepairResult::Initialize(\r\n        winrt::Microsoft::Management::Deployment::RepairResultStatus status,\r\n        winrt::hresult extendedErrorCode,\r\n        uint32_t repairerErrorCode,\r\n        hstring const& correlationData,\r\n        bool rebootRequired)\r\n    {\r\n        m_status = status;\r\n        m_extendedErrorCode = extendedErrorCode;\r\n        m_repairerErrorCode = repairerErrorCode;\r\n        m_correlationData = correlationData;\r\n        m_rebootRequired = rebootRequired;\r\n    }\r\n    hstring RepairResult::CorrelationData()\r\n    {\r\n        return hstring(m_correlationData);\r\n    }\r\n    bool RepairResult::RebootRequired()\r\n    {\r\n        return m_rebootRequired;\r\n    }\r\n    winrt::Microsoft::Management::Deployment::RepairResultStatus RepairResult::Status()\r\n    {\r\n        return m_status;\r\n    }\r\n    winrt::hresult RepairResult::ExtendedErrorCode()\r\n    {\r\n        return m_extendedErrorCode;\r\n    }\r\n    uint32_t RepairResult::RepairerErrorCode()\r\n    {\r\n        return m_repairerErrorCode;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/RepairResult.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"RepairResult.g.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    struct RepairResult : RepairResultT<RepairResult>\r\n    {\r\n        RepairResult() = default;\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n        void Initialize(\r\n            winrt::Microsoft::Management::Deployment::RepairResultStatus status,\r\n            winrt::hresult extendedErrorCode,\r\n            uint32_t repairerErrorCode,\r\n            hstring const& correlationData,\r\n            bool rebootRequired);\r\n#endif\r\n\r\n        hstring CorrelationData();\r\n        bool RebootRequired();\r\n        winrt::Microsoft::Management::Deployment::RepairResultStatus Status();\r\n        winrt::hresult ExtendedErrorCode();\r\n        uint32_t RepairerErrorCode();\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        std::wstring m_correlationData = L\"\";\r\n        bool m_rebootRequired = false;\r\n        winrt::Microsoft::Management::Deployment::RepairResultStatus m_status = winrt::Microsoft::Management::Deployment::RepairResultStatus::Ok;\r\n        winrt::hresult m_extendedErrorCode = S_OK;\r\n        uint32_t m_repairerErrorCode = 0;\r\n#endif\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/SourceAgreement.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include <winget/RepositorySource.h>\n#include \"SourceAgreement.h\"\n#include \"SourceAgreement.g.cpp\"\n#include <wil\\cppwinrt_wrl.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    void SourceAgreement::Initialize(::AppInstaller::Repository::SourceAgreement sourceAgreement)\n    {\n        m_sourceAgreement = std::move(sourceAgreement);\n    }\n    hstring SourceAgreement::Label()\n    {\n        return winrt::to_hstring(m_sourceAgreement.Label);\n    }\n    hstring SourceAgreement::Text()\n    {\n        return winrt::to_hstring(m_sourceAgreement.Text);\n    }\n    hstring SourceAgreement::Url()\n    {\n        return winrt::to_hstring(m_sourceAgreement.Url);\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/SourceAgreement.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"SourceAgreement.g.h\"\n#include <winget/RepositorySource.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    struct SourceAgreement : SourceAgreementT<SourceAgreement>\n    {\n        SourceAgreement() = default;\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void Initialize(::AppInstaller::Repository::SourceAgreement sourceAgreement);\n#endif\n\n        hstring Label();\n        hstring Text();\n        hstring Url();\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        ::AppInstaller::Repository::SourceAgreement m_sourceAgreement{};\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/UninstallOptions.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#pragma warning( push )\r\n#pragma warning ( disable : 4467 6388)\r\n// 6388 Allow CreateInstance.\r\n#include <wil\\cppwinrt_wrl.h>\r\n// 4467 Allow use of uuid attribute for com object creation.\r\n#include \"UninstallOptions.h\"\r\n#pragma warning( pop )\r\n#include \"UninstallOptions.g.cpp\"\r\n#include \"Converters.h\"\r\n#include \"Helpers.h\"\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    UninstallOptions::UninstallOptions()\r\n    {\r\n    }\r\n    winrt::Microsoft::Management::Deployment::PackageVersionId UninstallOptions::PackageVersionId()\r\n    {\r\n        return m_packageVersionId;\r\n    }\r\n    void UninstallOptions::PackageVersionId(winrt::Microsoft::Management::Deployment::PackageVersionId const& value)\r\n    {\r\n        m_packageVersionId = value;\r\n    }\r\n    winrt::Microsoft::Management::Deployment::PackageUninstallMode UninstallOptions::PackageUninstallMode()\r\n    {\r\n        return m_packageUninstallMode;\r\n    }\r\n    void UninstallOptions::PackageUninstallMode(winrt::Microsoft::Management::Deployment::PackageUninstallMode const& value)\r\n    {\r\n        m_packageUninstallMode = value;\r\n    }\r\n    hstring UninstallOptions::LogOutputPath()\r\n    {\r\n        return hstring(m_logOutputPath);\r\n    }\r\n    void UninstallOptions::LogOutputPath(hstring const& value)\r\n    {\r\n        m_logOutputPath = value;\r\n    }\r\n    hstring UninstallOptions::CorrelationData()\r\n    {\r\n        return hstring(m_correlationData);\r\n    }\r\n    void UninstallOptions::CorrelationData(hstring const& value)\r\n    {\r\n        m_correlationData = value;\r\n    }\r\n    bool UninstallOptions::Force()\r\n    {\r\n        return m_force;\r\n    }\r\n    void UninstallOptions::Force(bool value)\r\n    {\r\n        m_force = value;\r\n    }\r\n    winrt::Microsoft::Management::Deployment::PackageUninstallScope UninstallOptions::PackageUninstallScope()\r\n    {\r\n        return m_packageUninstallScope;\r\n    }\r\n    void UninstallOptions::PackageUninstallScope(winrt::Microsoft::Management::Deployment::PackageUninstallScope const& value)\r\n    {\r\n        m_packageUninstallScope = value;\r\n    }\r\n\r\n    CoCreatableMicrosoftManagementDeploymentClass(UninstallOptions);\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/UninstallOptions.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include \"UninstallOptions.g.h\"\r\n#include \"Public/ComClsids.h\"\r\n#include <winget/ModuleCountBase.h>\r\n\r\nnamespace winrt::Microsoft::Management::Deployment::implementation\r\n{\r\n    [uuid(WINGET_OUTOFPROC_COM_CLSID_UninstallOptions)]\r\n    struct UninstallOptions : UninstallOptionsT<UninstallOptions>\r\n    {\r\n        UninstallOptions();\r\n\r\n        winrt::Microsoft::Management::Deployment::PackageVersionId PackageVersionId();\r\n        void PackageVersionId(winrt::Microsoft::Management::Deployment::PackageVersionId const& value);\r\n        winrt::Microsoft::Management::Deployment::PackageUninstallMode PackageUninstallMode();\r\n        void PackageUninstallMode(winrt::Microsoft::Management::Deployment::PackageUninstallMode const& value);\r\n        hstring LogOutputPath();\r\n        void LogOutputPath(hstring const& value);\r\n        hstring CorrelationData();\r\n        void CorrelationData(hstring const& value);\r\n        bool Force();\r\n        void Force(bool value);\r\n        winrt::Microsoft::Management::Deployment::PackageUninstallScope PackageUninstallScope();\r\n        void PackageUninstallScope(winrt::Microsoft::Management::Deployment::PackageUninstallScope const& value);\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\n    private:\r\n        winrt::Microsoft::Management::Deployment::PackageVersionId m_packageVersionId{ nullptr };\r\n        winrt::Microsoft::Management::Deployment::PackageUninstallMode m_packageUninstallMode = winrt::Microsoft::Management::Deployment::PackageUninstallMode::Default;\r\n        std::wstring m_logOutputPath = L\"\";\r\n        std::wstring m_correlationData = L\"\";\r\n        bool m_force = false;\r\n        winrt::Microsoft::Management::Deployment::PackageUninstallScope m_packageUninstallScope = winrt::Microsoft::Management::Deployment::PackageUninstallScope::Any;\r\n#endif\r\n    };\r\n}\r\n\r\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\r\nnamespace winrt::Microsoft::Management::Deployment::factory_implementation\r\n{\r\n    struct UninstallOptions : UninstallOptionsT<UninstallOptions, implementation::UninstallOptions>, AppInstaller::WinRT::ModuleCountBase\r\n    {\r\n    };\r\n}\r\n#endif\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/UninstallResult.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#include \"pch.h\"\n#include \"UninstallResult.h\"\n#include \"UninstallResult.g.cpp\"\n#include <wil\\cppwinrt_wrl.h>\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    void UninstallResult::Initialize(\n        winrt::Microsoft::Management::Deployment::UninstallResultStatus status,\n        winrt::hresult extendedErrorCode,\n        uint32_t uninstallerErrorCode,\n        hstring const& correlationData, \n        bool rebootRequired)\n    {\n        m_status = status;\n        m_extendedErrorCode = extendedErrorCode;\n        m_uninstallerErrorCode = uninstallerErrorCode;\n        m_correlationData = correlationData;\n        m_rebootRequired = rebootRequired;\n    }\n    hstring UninstallResult::CorrelationData()\n    {\n        return hstring(m_correlationData);\n    }\n    bool UninstallResult::RebootRequired()\n    {\n        return m_rebootRequired;\n    }\n    winrt::Microsoft::Management::Deployment::UninstallResultStatus UninstallResult::Status()\n    {\n        return m_status;\n    }\n    winrt::hresult UninstallResult::ExtendedErrorCode()\n    {\n        return m_extendedErrorCode;\n    }\n\n    uint32_t UninstallResult::UninstallerErrorCode()\n    {\n        return m_uninstallerErrorCode;\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/UninstallResult.h",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n#pragma once\n#include \"UninstallResult.g.h\"\n\nnamespace winrt::Microsoft::Management::Deployment::implementation\n{\n    struct UninstallResult : UninstallResultT<UninstallResult>\n    {\n        UninstallResult() = default;\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n        void Initialize(\n            winrt::Microsoft::Management::Deployment::UninstallResultStatus status,\n            winrt::hresult extendedErrorCode,\n            uint32_t uninstallerErrorCode,\n            hstring const& correlationData, \n            bool rebootRequired);\n#endif\n\n        hstring CorrelationData();\n        bool RebootRequired();\n        winrt::Microsoft::Management::Deployment::UninstallResultStatus Status();\n        winrt::hresult ExtendedErrorCode();\n        uint32_t UninstallerErrorCode();\n\n#if !defined(INCLUDE_ONLY_INTERFACE_METHODS)\n    private:\n        std::wstring m_correlationData = L\"\";\n        bool m_rebootRequired = false;\n        winrt::Microsoft::Management::Deployment::UninstallResultStatus m_status = winrt::Microsoft::Management::Deployment::UninstallResultStatus::Ok;\n        winrt::hresult m_extendedErrorCode = S_OK;\n        uint32_t m_uninstallerErrorCode = 0;\n#endif\n    };\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<packages>\r\n  <package id=\"Microsoft.Windows.CppWinRT\" version=\"2.0.250303.1\" targetFramework=\"native\" />\r\n  <package id=\"Microsoft.Windows.ImplementationLibrary\" version=\"1.0.250325.1\" targetFramework=\"native\" />\r\n</packages>"
  },
  {
    "path": "src/Microsoft.Management.Deployment/pch.cpp",
    "content": "﻿// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment/pch.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <unknwn.h>\r\n#include <winrt/Windows.Foundation.h>\r\n#include <winrt/Windows.Foundation.Collections.h>\r\n#include <winrt/Windows.Foundation.Metadata.h>\r\n#include <winrt/Windows.Web.Http.h>\r\n\r\n#include <ostream>\r\n#include <string>\r\n#include <mutex>\r\n#include <random>\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment.CsWinRTProjection/Microsoft.Management.Deployment.CsWinRTProjection.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <TargetFrameworks>net8.0-windows10.0.26100.0</TargetFrameworks>\r\n    <Platform>AnyCpu</Platform>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n    <OutputPath>$(SolutionDir)$(Platform)\\$(Configuration)\\$(MSBuildProjectName)\\</OutputPath>\r\n    <Configurations>Debug;Release;ReleaseStatic</Configurations>\r\n    <EmbedUntrackedSources>true</EmbedUntrackedSources>\r\n    <IsAotCompatible>true</IsAotCompatible>\r\n    <DisableRuntimeMarshalling>true</DisableRuntimeMarshalling>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup>\r\n    <CsWinRTIncludes>Microsoft.Management.Deployment</CsWinRTIncludes>\r\n    <CsWinRTGeneratedFilesDir>$(OutDir)</CsWinRTGeneratedFilesDir>\r\n    <CsWinRTWindowsMetadata>10.0.26100.0</CsWinRTWindowsMetadata>\r\n    <!-- Ensure Support for Windows 10, Version 1809 -->\r\n    <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>\r\n    <!-- \r\n      Disables the AssemblyInfo generation override in the internal build.\r\n      Without this, values like TargetPlatformMinVersion are not placed into the assembly attributes\r\n      and .NET static analysis tools will assume that this assembly requires the OS version in our TargetFramework.\r\n    -->\r\n    <XesDisableAssemblyInfoWrite>True</XesDisableAssemblyInfoWrite>\r\n  </PropertyGroup>\r\n  \r\n  <PropertyGroup>\r\n    <!-- Workaround for MSB3271 error on processor architecture mismatch -->\r\n    <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <PackageReference Include=\"Microsoft.Windows.CsWinRT\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\Microsoft.Management.Deployment\\Microsoft.Management.Deployment.vcxproj\">\r\n      <OutputItemType>Content</OutputItemType>\r\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\r\n      <ReferenceOutputAssembly>True</ReferenceOutputAssembly>\r\n    </ProjectReference>\r\n  </ItemGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment.InProc/Microsoft.Management.Deployment.InProc.dll.manifest",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?> \r\n\r\n<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">\r\n\r\n  <assemblyIdentity\r\n      name=\"Microsoft.Management.Deployment.InProc.dll\"\r\n      version=\"0.0.0.0\"/>\r\n\r\n  <file name=\"Microsoft.Management.Deployment.InProc.dll\">\r\n    <comClass\r\n        clsid=\"{2DDE4456-64D9-4673-8F7E-A4F19A2E6CC3}\"\r\n        threadingModel=\"Both\"\r\n        description=\"PackageManager\"/>\r\n    <activatableClass\r\n        name=\"Microsoft.Management.Deployment.PackageManager\"\r\n        threadingModel=\"both\"\r\n        xmlns=\"urn:schemas-microsoft-com:winrt.v1\"/>\r\n    <comClass\r\n        clsid=\"{96B9A53A-9228-4DA0-B013-BB1B2031AB3D}\"\r\n        threadingModel=\"Both\"\r\n        description=\"FindPackagesOptions\"/>\r\n    <activatableClass\r\n        name=\"Microsoft.Management.Deployment.FindPackagesOptions\"\r\n        threadingModel=\"both\"\r\n        xmlns=\"urn:schemas-microsoft-com:winrt.v1\"/>\r\n    <comClass\r\n        clsid=\"{768318A6-2EB5-400D-84D0-DF3534C30F5D}\"\r\n        threadingModel=\"Both\"\r\n        description=\"CreateCompositePackageCatalogOptions\"/>\r\n    <activatableClass\r\n        name=\"Microsoft.Management.Deployment.CreateCompositePackageCatalogOptions\"\r\n        threadingModel=\"both\"\r\n        xmlns=\"urn:schemas-microsoft-com:winrt.v1\"/>\r\n    <comClass\r\n        clsid=\"{E2AF3BA8-8A88-4766-9DDA-AE4013ADE286}\"\r\n        threadingModel=\"Both\"\r\n        description=\"InstallOptions\"/>\r\n    <activatableClass\r\n        name=\"Microsoft.Management.Deployment.InstallOptions\"\r\n        threadingModel=\"both\"\r\n        xmlns=\"urn:schemas-microsoft-com:winrt.v1\"/>\r\n    <comClass\r\n        clsid=\"{869CB959-EB54-425C-A1E4-1A1C291C64E9}\"\r\n        threadingModel=\"Both\"\r\n        description=\"UninstallOptions\"/>\r\n    <activatableClass\r\n        name=\"Microsoft.Management.Deployment.UninstallOptions\"\r\n        threadingModel=\"both\"\r\n        xmlns=\"urn:schemas-microsoft-com:winrt.v1\"/>\r\n    <comClass\r\n        clsid=\"{4288DF96-FDC9-4B68-B403-193DBBF56A24}\"\r\n        threadingModel=\"Both\"\r\n        description=\"DownloadOptions\"/>\r\n    <activatableClass\r\n        name=\"Microsoft.Management.Deployment.DownloadOptions\"\r\n        threadingModel=\"both\"\r\n        xmlns=\"urn:schemas-microsoft-com:winrt.v1\"/>\r\n    <comClass\r\n        clsid=\"{57DC8962-7343-42CD-B91C-04F6A25DB1D0}\"\r\n        threadingModel=\"Both\"\r\n        description=\"PackageMatchFilter\"/>\r\n    <activatableClass\r\n        name=\"Microsoft.Management.Deployment.PackageMatchFilter\"\r\n        threadingModel=\"both\"\r\n        xmlns=\"urn:schemas-microsoft-com:winrt.v1\"/>\r\n    <comClass\r\n        clsid=\"{8D593114-1CF1-43B9-8722-4DBB30103296}\"\r\n        threadingModel=\"Both\"\r\n        description=\"AuthenticationArguments\"/>\r\n    <activatableClass\r\n        name=\"Microsoft.Management.Deployment.AuthenticationArguments\"\r\n        threadingModel=\"both\"\r\n        xmlns=\"urn:schemas-microsoft-com:winrt.v1\"/>\r\n    <comClass\r\n        clsid=\"{80CF9D63-5505-4342-B9B4-BB87895CA8BB}\"\r\n        threadingModel=\"Both\"\r\n        description=\"PackageManagerSettings\"/>\r\n    <activatableClass\r\n        name=\"Microsoft.Management.Deployment.PackageManagerSettings\"\r\n        threadingModel=\"both\"\r\n        xmlns=\"urn:schemas-microsoft-com:winrt.v1\"/>\r\n     <comClass\r\n         clsid=\"{30C024C4-852C-4DD4-9810-1348C51EF9BB}\"\r\n        threadingModel=\"Both\"\r\n        description=\"RepairOptions\"/>\r\n    <activatableClass\r\n        name=\"Microsoft.Management.Deployment.RepairOptions\"\r\n        threadingModel=\"both\"\r\n        xmlns=\"urn:schemas-microsoft-com:winrt.v1\"/>\r\n    <comClass\r\n        clsid=\"{24E6F1FA-E4C3-4ACD-965D-DF213FD58F15}\"\r\n        threadingModel=\"Both\"\r\n        description=\"AddPackageCatalogOptions\"/>\r\n    <activatableClass\r\n        name=\"Microsoft.Management.Deployment.AddPackageCatalogOptions\"\r\n        threadingModel=\"both\"\r\n        xmlns=\"urn:schemas-microsoft-com:winrt.v1\"/>\r\n     <comClass\r\n        clsid=\"{1125D3A6-E2CE-479A-91D5-71A3F6F8B00B}\"\r\n        threadingModel=\"Both\"\r\n        description=\"RemovePackageCatalogOptions\"/>\r\n    <activatableClass\r\n        name=\"Microsoft.Management.Deployment.RemovePackageCatalogOptions\"\r\n        threadingModel=\"both\"\r\n        xmlns=\"urn:schemas-microsoft-com:winrt.v1\"/>\r\n    <comClass\r\n       clsid=\"{E8E12FE1-AB77-40C4-A562-E91FB51B4E82}\"\r\n       threadingModel=\"Both\"\r\n       description=\"EditPackageCatalogOptions\"/>\r\n    <activatableClass\r\n        name=\"Microsoft.Management.Deployment.EditPackageCatalogOptions\"\r\n        threadingModel=\"both\"\r\n        xmlns=\"urn:schemas-microsoft-com:winrt.v1\"/>\r\n  </file>\r\n</assembly>\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment.InProc/Microsoft.Management.Deployment.InProc.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" />\r\n  <PropertyGroup Label=\"Globals\">\r\n    <CppWinRTOptimized>true</CppWinRTOptimized>\r\n    <CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>\r\n    <MinimalCoreWin>true</MinimalCoreWin>\r\n    <VCProjectVersion>15.0</VCProjectVersion>\r\n    <Keyword>Win32Proj</Keyword>\r\n    <ProjectGuid>{9ac3c6a4-1875-4d3e-bf9c-c31e81eff6b4}</ProjectGuid>\r\n    <RootNamespace>MicrosoftManagementDeploymentInProc</RootNamespace>\r\n    <WindowsTargetPlatformVersion>10.0.26100.0</WindowsTargetPlatformVersion>\r\n    <WindowsTargetPlatformMinVersion>10.0.17763.0</WindowsTargetPlatformMinVersion>\r\n    <WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>\r\n    <CppWinRTGenerateWindowsMetadata>false</CppWinRTGenerateWindowsMetadata>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|ARM64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|Win32\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|ARM64\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|Win32\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|x64\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|ARM64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|Win32\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <PropertyGroup Label=\"Configuration\">\r\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Debug'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n    <LinkIncremental>true</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Release'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <LinkIncremental>false</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='ReleaseStatic'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <LinkIncremental>false</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\" Label=\"Configuration\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\" Label=\"Configuration\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\" Label=\"Configuration\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\r\n  <ImportGroup Label=\"ExtensionSettings\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"Shared\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"PropertySheet.props\" />\r\n  </ImportGroup>\r\n  <PropertyGroup Label=\"UserMacros\" />\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>true</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>true</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>true</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(ProjectDir)\\..\\vcpkg.props\" />\r\n  <ItemDefinitionGroup>\r\n    <ClCompile>\r\n      <PrecompiledHeader>Use</PrecompiledHeader>\r\n      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>\r\n      <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>\r\n      <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <AdditionalOptions>%(AdditionalOptions) /permissive- /bigobj /D _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING</AdditionalOptions>\r\n    </ClCompile>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Debug'\">\r\n    <ClCompile>\r\n      <Optimization>Disabled</Optimization>\r\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">$(ProjectDir)..\\WindowsPackageManager;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">$(ProjectDir)..\\WindowsPackageManager;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</TreatWarningAsError>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">false</ControlFlowGuard>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</ControlFlowGuard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">stdcpp17</LanguageStandard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">stdcpp17</LanguageStandard>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</EnablePREfast>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">Windows</SubSystem>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Source.def</ModuleDefinitionFile>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">Source.def</ModuleDefinitionFile>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">Source.def</ModuleDefinitionFile>\r\n      <AdditionalDependencies Condition=\"'$(Configuration)'=='Debug'\">wininet.lib;shell32.lib;winsqlite3.lib;shlwapi.lib;icuuc.lib;icuin.lib;urlmon.lib;Advapi32.lib;winhttp.lib;onecoreuap.lib;msi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</CETCompat>\r\n    </Link>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Platform)'=='Win32'\">\r\n    <ClCompile>\r\n      <PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">$(ProjectDir)..\\WindowsPackageManager;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</TreatWarningAsError>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</ControlFlowGuard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">stdcpp17</LanguageStandard>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</EnablePREfast>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Link>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</CETCompat>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Release'\">\r\n    <ClCompile>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">$(ProjectDir)..\\WindowsPackageManager;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">$(ProjectDir)..\\WindowsPackageManager;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">$(ProjectDir)..\\WindowsPackageManager;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">true</TreatWarningAsError>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">Guard</ControlFlowGuard>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Guard</ControlFlowGuard>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Guard</ControlFlowGuard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">stdcpp17</LanguageStandard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">stdcpp17</LanguageStandard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">stdcpp17</LanguageStandard>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</EnablePREfast>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Windows</SubSystem>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Source.def</ModuleDefinitionFile>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">Source.def</ModuleDefinitionFile>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Source.def</ModuleDefinitionFile>\r\n      <AdditionalDependencies Condition=\"'$(Configuration)'=='Release'\">wininet.lib;shell32.lib;winsqlite3.lib;shlwapi.lib;icuuc.lib;icuin.lib;urlmon.lib;Advapi32.lib;winhttp.lib;onecoreuap.lib;msi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\n      <AdditionalOptions Condition=\"'$(ForceDebugTypeCVFixup)'=='true'\">/debugtype:cv,fixup /incremental:no %(AdditionalOptions)</AdditionalOptions>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">/debug:full %(AdditionalOptions)</AdditionalOptions>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">/debug:full %(AdditionalOptions)</AdditionalOptions>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">/debug:full %(AdditionalOptions)</AdditionalOptions>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</CETCompat>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">true</CETCompat>\r\n    </Link>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='ReleaseStatic'\">\r\n    <ClCompile>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">$(ProjectDir)..\\WindowsPackageManager;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">$(ProjectDir)..\\WindowsPackageManager;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">$(ProjectDir)..\\WindowsPackageManager;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">true</TreatWarningAsError>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">Guard</ControlFlowGuard>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">Guard</ControlFlowGuard>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">Guard</ControlFlowGuard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">stdcpp17</LanguageStandard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">stdcpp17</LanguageStandard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">stdcpp17</LanguageStandard>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">false</EnablePREfast>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">MultiThreaded</RuntimeLibrary>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">MultiThreaded</RuntimeLibrary>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">MultiThreaded</RuntimeLibrary>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">Windows</SubSystem>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">Source.def</ModuleDefinitionFile>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">Source.def</ModuleDefinitionFile>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">Source.def</ModuleDefinitionFile>\r\n      <AdditionalDependencies Condition=\"'$(Configuration)'=='ReleaseStatic'\">wininet.lib;shell32.lib;winsqlite3.lib;shlwapi.lib;icuuc.lib;icuin.lib;urlmon.lib;Advapi32.lib;winhttp.lib;onecoreuap.lib;msi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">/debug:full /debugtype:cv,fixup /incremental:no %(AdditionalOptions)</AdditionalOptions>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">/debug:full /debugtype:cv,fixup /incremental:no %(AdditionalOptions)</AdditionalOptions>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">/debug:full /debugtype:cv,fixup /incremental:no %(AdditionalOptions)</AdditionalOptions>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">true</CETCompat>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">true</CETCompat>\r\n    </Link>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n  </ItemDefinitionGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"pch.h\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"dllmain.cpp\" />\r\n    <ClCompile Include=\"pch.cpp\">\r\n      <PrecompiledHeader>Create</PrecompiledHeader>\r\n    </ClCompile>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\WindowsPackageManager\\WindowsPackageManager.vcxproj\">\r\n      <Project>{2046b5af-666d-4ce8-8d3e-c32c57908a56}</Project>\r\n    </ProjectReference>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"packages.config\" />\r\n    <None Include=\"PropertySheet.props\" />\r\n    <None Include=\"Source.def\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <CopyFileToFolders Include=\"Microsoft.Management.Deployment.InProc.dll.manifest\">\r\n      <DeploymentContent>true</DeploymentContent>\r\n    </CopyFileToFolders>\r\n  </ItemGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\r\n  <ImportGroup Label=\"ExtensionTargets\">\r\n    <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets')\" />\r\n    <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" />\r\n  </ImportGroup>\r\n  <Target Name=\"EnsureNuGetPackageBuildImports\" BeforeTargets=\"PrepareForBuild\">\r\n    <PropertyGroup>\r\n      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>\r\n    </PropertyGroup>\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets'))\" />\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props'))\" />\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets'))\" />\r\n  </Target>\r\n  <!-- Rename Microsoft.Management.Deployment.InProc.dll to Microsoft.Management.Deployment.dll -->\r\n  <Target Name=\"RenameMicrosoftManagementDeployment\" AfterTargets=\"AfterBuild\">\r\n    <Copy SourceFiles=\"$(OutDir)\\Microsoft.Management.Deployment.InProc.dll\" DestinationFiles=\"$(OutDir)\\Microsoft.Management.Deployment.dll\" />\r\n  </Target>\r\n</Project>\r\n\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment.InProc/Microsoft.Management.Deployment.InProc.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup>\r\n    <Filter Include=\"Source Files\">\r\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r\n      <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Header Files\">\r\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r\n      <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Resource Files\">\r\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\r\n    </Filter>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"pch.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"dllmain.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"pch.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"packages.config\" />\r\n    <None Include=\"PropertySheet.props\" />\r\n    <None Include=\"Source.def\">\r\n      <Filter>Source Files</Filter>\r\n    </None>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <CopyFileToFolders Include=\"Microsoft.Management.Deployment.InProc.dll.manifest\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Natvis Include=\"$(MSBuildThisFileDirectory)..\\..\\natvis\\wil.natvis\" />\r\n  </ItemGroup>\r\n</Project>"
  },
  {
    "path": "src/Microsoft.Management.Deployment.InProc/PropertySheet.props",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ImportGroup Label=\"PropertySheets\" />\n  <PropertyGroup Label=\"UserMacros\" />\n    <!--\n    To customize common C++/WinRT project properties: \n    * right-click the project node\n    * expand the Common Properties item\n    * select the C++/WinRT property page\n\n    For more advanced scenarios, and complete documentation, please see:\n    https://github.com/Microsoft/xlang/tree/master/src/package/cppwinrt/nuget \n    -->\n  <PropertyGroup />\n  <ItemDefinitionGroup />\n</Project>"
  },
  {
    "path": "src/Microsoft.Management.Deployment.InProc/Source.def",
    "content": "EXPORTS\nDllCanUnloadNow             PRIVATE\nDllGetClassObject           PRIVATE\nDllGetActivationFactory     PRIVATE\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment.InProc/dllmain.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include <WindowsPackageManager.h>\r\n#include <hstring.h>\r\n\r\nEXTERN_C BOOL WINAPI DllMain(\r\n    HMODULE /* hModule */,\r\n    DWORD reason,\r\n    LPVOID /* lpReserved */)\r\n{\r\n    switch (reason)\r\n    {\r\n    case DLL_PROCESS_ATTACH:\r\n    {\r\n        if (FAILED(WindowsPackageManagerInProcModuleInitialize()))\r\n        {\r\n            return FALSE;\r\n        }\r\n    }\r\n    break;\r\n    }\r\n    return TRUE;\r\n}\r\n\r\nSTDAPI DllGetClassObject(\r\n    REFCLSID rclsid,\r\n    REFIID riid,\r\n    LPVOID* ppv)\r\n{\r\n    RETURN_HR(WindowsPackageManagerInProcModuleGetClassObject(rclsid, riid, ppv));\r\n}\r\n\r\nSTDAPI DllCanUnloadNow()\r\n{\r\n    return WindowsPackageManagerInProcModuleTerminate() ? S_OK : S_FALSE;\r\n}\r\n\r\nSTDAPI DllGetActivationFactory(HSTRING classId, void** factory)\r\n{\r\n    return WindowsPackageManagerInProcModuleGetActivationFactory(classId, factory);\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment.InProc/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<packages>\r\n  <package id=\"Microsoft.Windows.CppWinRT\" version=\"2.0.250303.1\" targetFramework=\"native\" />\r\n  <package id=\"Microsoft.Windows.ImplementationLibrary\" version=\"1.0.250325.1\" targetFramework=\"native\" />\r\n</packages>"
  },
  {
    "path": "src/Microsoft.Management.Deployment.InProc/pch.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n\r\n#include \"pch.h\"\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment.InProc/pch.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#define WIN32_LEAN_AND_MEAN\r\n#include <Windows.h>\r\n#include <wil/result_macros.h>"
  },
  {
    "path": "src/Microsoft.Management.Deployment.OutOfProc/Factory.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Factory.h\"\r\n#include <winrt/Microsoft.Management.Deployment.h>\r\n#include <winget/Runtime.h>\r\n#include <WinGetServerManualActivation_Client.h>\r\n\r\nusing namespace std::string_view_literals;\r\n\r\nnamespace Microsoft::Management::Deployment::OutOfProc\r\n{\r\n    namespace\r\n    {\r\n#if USE_PROD_CLSIDS\r\n        constexpr CLSID CLSID_PackageManager = { 0xC53A4F16, 0x787E, 0x42A4, { 0xB3, 0x04, 0x29, 0xEF, 0xFB, 0x4B, 0xF5, 0x97 } }; //C53A4F16-787E-42A4-B304-29EFFB4BF597\r\n        constexpr CLSID CLSID_InstallOptions = { 0x1095f097, 0xEB96, 0x453B, { 0xB4, 0xE6, 0x16, 0x13, 0x63, 0x7F, 0x3B, 0x14 } }; //1095F097-EB96-453B-B4E6-1613637F3B14\r\n        constexpr CLSID CLSID_UninstallOptions = { 0xE1D9A11E, 0x9F85, 0x4D87, { 0x9C, 0x17, 0x2B, 0x93, 0x14, 0x3A, 0xDB, 0x8D } }; //E1D9A11E-9F85-4D87-9C17-2B93143ADB8D\r\n        constexpr CLSID CLSID_FindPackagesOptions = { 0x572DED96, 0x9C60, 0x4526, { 0x8F, 0x92, 0xEE, 0x7D, 0x91, 0xD3, 0x8C, 0x1A } }; //572DED96-9C60-4526-8F92-EE7D91D38C1A\r\n        constexpr CLSID CLSID_PackageMatchFilter = { 0xD02C9DAF, 0x99DC, 0x429C, { 0xB5, 0x03, 0x4E, 0x50, 0x4E, 0x4A, 0xB0, 0x00 } }; //D02C9DAF-99DC-429C-B503-4E504E4AB000\r\n        constexpr CLSID CLSID_CreateCompositePackageCatalogOptions = { 0x526534B8, 0x7E46, 0x47C8, { 0x84, 0x16, 0xB1, 0x68, 0x5C, 0x32, 0x7D, 0x37 } }; //526534B8-7E46-47C8-8416-B1685C327D37\r\n        constexpr CLSID CLSID_DownloadOptions = { 0x4CBABE76, 0x7322, 0x4BE4, { 0x9C, 0xEA, 0x25, 0x89, 0xA8, 0x06, 0x82, 0xDC } }; //4CBABE76-7322-4BE4-9CEA-2589A80682DC\r\n        constexpr CLSID CLSID_AuthenticationArguments = { 0xBA580786, 0xBDE3, 0x4F6C, { 0xB8, 0xF3, 0x44, 0x69, 0x8A, 0xC8, 0x71, 0x1A } }; //BA580786-BDE3-4F6C-B8F3-44698AC8711A\r\n        constexpr CLSID CLSID_RepairOptions = { 0x0498F441, 0x3097, 0x455F, { 0x9C, 0xAF, 0x14, 0x8F, 0x28, 0x29, 0x38, 0x65 } }; //0498F441-3097-455F-9CAF-148F28293865\r\n        constexpr CLSID CLSID_AddPackageCatalogOptions = { 0xDB9D012D, 0x00D7, 0x47EE, { 0x8F, 0xB1, 0x60, 0x6E, 0x10, 0xAC, 0x4F, 0x51 } }; //DB9D012D-00D7-47EE-8FB1-606E10AC4F51\r\n        constexpr CLSID CLSID_RemovePackageCatalogOptions = { 0x032B1C58, 0xB975, 0x469B, { 0xA0, 0x13, 0xE6, 0x32, 0xB6, 0xEC, 0xE8, 0xD8 } }; //032B1C58-B975-469B-A013-E632B6ECE8D8\r\n        constexpr CLSID CLSID_EditPackageCatalogOptions = { 0xA9F5E736, 0x68CE, 0x463C, { 0xBA, 0x6D, 0xDE, 0x96, 0x8F, 0x0C, 0xCE, 0x04 } }; //A9F5E736-68CE-463C-BA6D-DE968F0CCE04\r\n#else\r\n        constexpr CLSID CLSID_PackageManager = { 0x74CB3139, 0xB7C5, 0x4B9E, { 0x93, 0x88, 0xE6, 0x61, 0x6D, 0xEA, 0x28, 0x8C } }; //74CB3139-B7C5-4B9E-9388-E6616DEA288C\r\n        constexpr CLSID CLSID_InstallOptions = { 0x44FE0580, 0x62F7, 0x44D4, { 0x9E, 0x91, 0xAA, 0x96, 0x14, 0xAB, 0x3E, 0x86 } }; //44FE0580-62F7-44D4-9E91-AA9614AB3E86\r\n        constexpr CLSID CLSID_UninstallOptions = { 0xAA2A5C04, 0x1AD9, 0x46C4, { 0xB7, 0x4F, 0x6B, 0x33, 0x4A, 0xD7, 0xEB, 0x8C } }; //AA2A5C04-1AD9-46C4-B74F-6B334AD7EB8C\r\n        constexpr CLSID CLSID_FindPackagesOptions = { 0x1BD8FF3A, 0xEC50, 0x4F69, { 0xAE, 0xEE, 0xDF, 0x4C, 0x9D, 0x3B, 0xAA, 0x96 } }; //1BD8FF3A-EC50-4F69-AEEE-DF4C9D3BAA96\r\n        constexpr CLSID CLSID_PackageMatchFilter = { 0x3F85B9F4, 0x487A, 0x4C48, { 0x90, 0x35, 0x29, 0x03, 0xF8, 0xA6, 0xD9, 0xE8 } }; //3F85B9F4-487A-4C48-9035-2903F8A6D9E8\r\n        constexpr CLSID CLSID_CreateCompositePackageCatalogOptions = { 0xEE160901, 0xB317, 0x4EA7, { 0x9C, 0xC6, 0x53, 0x55, 0xC6, 0xD7, 0xD8, 0xA7 } }; //EE160901-B317-4EA7-9CC6-5355C6D7D8A7\r\n        constexpr CLSID CLSID_DownloadOptions = { 0x8EF324ED, 0x367C, 0x4880, { 0x83, 0xE5, 0xBB, 0x2A, 0xBD, 0x0B, 0x72, 0xF6 } }; //8EF324ED-367C-4880-83E5-BB2ABD0B72F6\r\n        constexpr CLSID CLSID_AuthenticationArguments = { 0x6484A61D, 0x50FA, 0x41F0, { 0xB7, 0x1E, 0xF4, 0x37, 0x0C, 0x6E, 0xB3, 0x7C } }; //6484A61D-50FA-41F0-B71E-F4370C6EB37C\r\n        constexpr CLSID CLSID_RepairOptions = { 0xE62BB1E7, 0xC7B2, 0x4AEC, { 0x9E, 0x28, 0xFB, 0x64, 0x9B, 0x30, 0xFF, 0x03 } }; //E62BB1E7-C7B2-4AEC-9E28-FB649B30FF03\r\n        constexpr CLSID CLSID_AddPackageCatalogOptions = { 0xD58C7E4C, 0x70E6, 0x476C, { 0xA5, 0xD4, 0x80, 0x34, 0x1E, 0xD8, 0x02, 0x52 } }; //D58C7E4C-70E6-476C-A5D4-80341ED80252\r\n        constexpr CLSID CLSID_RemovePackageCatalogOptions = { 0x87A96609, 0x1A39, 0x4955, { 0xBE, 0x72, 0x71, 0x74, 0xE1, 0x47, 0xB7, 0xDC } }; //87A96609-1A39-4955-BE72-7174E147B7DC\r\n        constexpr CLSID CLSID_EditPackageCatalogOptions = { 0x29B19238, 0x81AD, 0x4A8E, { 0xA2, 0xFC, 0xAD, 0xF1, 0x7C, 0x38, 0xCA, 0xEB } }; //29B19238-81AD-4A8E-A2FC-ADF17C38CAEB\r\n\r\n#endif\r\n\r\n        struct NameCLSIDPair\r\n        {\r\n            std::wstring_view Name;\r\n            GUID CLSID;\r\n        };\r\n\r\n        constexpr std::array<NameCLSIDPair, 12> s_nameCLSIDPairs\r\n        {\r\n            NameCLSIDPair{ L\"Microsoft.Management.Deployment.PackageManager\"sv, CLSID_PackageManager },\r\n            NameCLSIDPair{ L\"Microsoft.Management.Deployment.InstallOptions\"sv, CLSID_InstallOptions },\r\n            NameCLSIDPair{ L\"Microsoft.Management.Deployment.UninstallOptions\"sv, CLSID_UninstallOptions },\r\n            NameCLSIDPair{ L\"Microsoft.Management.Deployment.FindPackagesOptions\"sv, CLSID_FindPackagesOptions },\r\n            NameCLSIDPair{ L\"Microsoft.Management.Deployment.PackageMatchFilter\"sv, CLSID_PackageMatchFilter },\r\n            NameCLSIDPair{ L\"Microsoft.Management.Deployment.CreateCompositePackageCatalogOptions\"sv, CLSID_CreateCompositePackageCatalogOptions },\r\n            NameCLSIDPair{ L\"Microsoft.Management.Deployment.DownloadOptions\"sv, CLSID_DownloadOptions },\r\n            NameCLSIDPair{ L\"Microsoft.Management.Deployment.AuthenticationArguments\"sv, CLSID_AuthenticationArguments },\r\n            NameCLSIDPair{ L\"Microsoft.Management.Deployment.RepairOptions\"sv, CLSID_RepairOptions },\r\n            NameCLSIDPair{ L\"Microsoft.Management.Deployment.AddPackageCatalogOptions\"sv, CLSID_AddPackageCatalogOptions },\r\n            NameCLSIDPair{ L\"Microsoft.Management.Deployment.RemovePackageCatalogOptions\"sv, CLSID_RemovePackageCatalogOptions },\r\n            NameCLSIDPair{ L\"Microsoft.Management.Deployment.EditPackageCatalogOptions\"sv, CLSID_EditPackageCatalogOptions },\r\n        };\r\n\r\n        bool IsCLSIDPresent(const GUID& clsid)\r\n        {\r\n            for (const auto& pair : s_nameCLSIDPairs)\r\n            {\r\n                if (pair.CLSID == clsid)\r\n                {\r\n                    return true;\r\n                }\r\n            }\r\n\r\n            return false;\r\n        }\r\n\r\n        const GUID* GetCLSIDFor(HSTRING clsid)\r\n        {\r\n            UINT32 length = 0;\r\n            PCWSTR buffer = WindowsGetStringRawBuffer(clsid, &length);\r\n            std::wstring_view clsidView{ buffer, length };\r\n\r\n            for (const auto& pair : s_nameCLSIDPairs)\r\n            {\r\n                if (pair.Name == clsidView)\r\n                {\r\n                    return &pair.CLSID;\r\n                }\r\n            }\r\n\r\n            return nullptr;\r\n        }\r\n\r\n        winrt::Windows::Foundation::IInspectable CreateOOPObject(const GUID& clsid)\r\n        {\r\n            bool isAdmin = AppInstaller::Runtime::IsRunningAsAdmin();\r\n\r\n            try\r\n            {\r\n                return winrt::create_instance<winrt::Windows::Foundation::IInspectable>(clsid, CLSCTX_LOCAL_SERVER | CLSCTX_NO_CODE_DOWNLOAD);\r\n            }\r\n            catch (const winrt::hresult_error& hre)\r\n            {\r\n                // We only want to fall through to trying the manual activation if we are running as admin and couldn't find the registration.\r\n                if (!(isAdmin && hre.code() == REGDB_E_CLASSNOTREG))\r\n                {\r\n                    throw;\r\n                }\r\n            }\r\n\r\n            winrt::com_ptr<::IUnknown> result;\r\n            THROW_IF_FAILED(WinGetServerManualActivation_CreateInstance(clsid, winrt::guid_of<winrt::Windows::Foundation::IInspectable>(), 0, result.put_void()));\r\n            return result.as<winrt::Windows::Foundation::IInspectable>();\r\n        }\r\n    }\r\n\r\n    Factory::Factory(const GUID& clsid) : m_clsid(clsid)\r\n    {\r\n        IncrementRefCount();\r\n    }\r\n\r\n    Factory::Factory(HSTRING clsid) : m_clsid(*GetCLSIDFor(clsid))\r\n    {\r\n        IncrementRefCount();\r\n    }\r\n\r\n    Factory::~Factory()\r\n    {\r\n        DecrementRefCount();\r\n    }\r\n\r\n    bool Factory::HasReferences()\r\n    {\r\n        return s_referenceCount.load() != 0;\r\n    }\r\n\r\n    void Factory::Terminate()\r\n    {\r\n        WinGetServerManualActivation_Terminate();\r\n    }\r\n\r\n    bool Factory::IsCLSID(const GUID& clsid)\r\n    {\r\n        return IsCLSIDPresent(clsid);\r\n    }\r\n\r\n    bool Factory::IsCLSID(HSTRING clsid)\r\n    {\r\n        return GetCLSIDFor(clsid) != nullptr;\r\n    }\r\n\r\n    winrt::Windows::Foundation::IInspectable Factory::ActivateInstance()\r\n    {\r\n        return CreateOOPObject(m_clsid);\r\n    }\r\n\r\n    HRESULT STDMETHODCALLTYPE Factory::CreateInstance(::IUnknown* pUnkOuter, REFIID riid, void** ppvObject) try\r\n    {\r\n        RETURN_HR_IF(E_POINTER, !ppvObject);\r\n        *ppvObject = nullptr;\r\n        RETURN_HR_IF(CLASS_E_NOAGGREGATION, pUnkOuter != nullptr);\r\n\r\n        return CreateOOPObject(m_clsid).as(riid, ppvObject);\r\n    }\r\n    CATCH_RETURN();\r\n\r\n    HRESULT STDMETHODCALLTYPE Factory::LockServer(BOOL fLock)\r\n    {\r\n        if (fLock)\r\n        {\r\n            IncrementRefCount();\r\n        }\r\n        else\r\n        {\r\n            DecrementRefCount();\r\n        }\r\n\r\n        return S_OK;\r\n    }\r\n\r\n    void Factory::IncrementRefCount()\r\n    {\r\n        ++s_referenceCount;\r\n    }\r\n\r\n    void Factory::DecrementRefCount()\r\n    {\r\n        --s_referenceCount;\r\n    }\r\n\r\n    std::atomic<int32_t> Factory::s_referenceCount = ATOMIC_VAR_INIT(0);\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment.OutOfProc/Factory.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#pragma once\r\n#include <hstring.h>\r\n#include <inspectable.h>\r\n#include <winrt/Windows.Foundation.h>\r\n#include <atomic>\r\n\r\nnamespace Microsoft::Management::Deployment::OutOfProc\r\n{\r\n    struct Factory : winrt::implements<Factory, IClassFactory, winrt::Windows::Foundation::IActivationFactory>\r\n    {\r\n        Factory(const GUID& clsid);\r\n        Factory(HSTRING clsid);\r\n        ~Factory();\r\n\r\n        // Returns true if the reference count is not 0; false if it is.\r\n        static bool HasReferences();\r\n\r\n        // Forcibly destroys any static objects.\r\n        static void Terminate();\r\n\r\n        // Determines if the given CLSID is the CLSID for the factory.\r\n        static bool IsCLSID(const GUID& clsid);\r\n\r\n        // Determines if the given CLSID is the CLSID for the factory.\r\n        static bool IsCLSID(HSTRING clsid);\r\n\r\n        // IActivationFactory\r\n        winrt::Windows::Foundation::IInspectable ActivateInstance();\r\n\r\n        // IClassFactory\r\n        HRESULT STDMETHODCALLTYPE CreateInstance(::IUnknown *pUnkOuter, REFIID riid, void **ppvObject);\r\n        HRESULT STDMETHODCALLTYPE LockServer(BOOL fLock);\r\n\r\n    private:\r\n        static void IncrementRefCount();\r\n        static void DecrementRefCount();\r\n\r\n        static std::atomic<int32_t> s_referenceCount;\r\n\r\n        GUID m_clsid;\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment.OutOfProc/Microsoft.Management.Deployment.OutOfProc.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" />\r\n  <PropertyGroup Label=\"Globals\">\r\n    <CppWinRTOptimized>true</CppWinRTOptimized>\r\n    <CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>\r\n    <MinimalCoreWin>true</MinimalCoreWin>\r\n    <VCProjectVersion>15.0</VCProjectVersion>\r\n    <Keyword>Win32Proj</Keyword>\r\n    <RootNamespace>MicrosoftManagementDeploymentOutOfProc</RootNamespace>\r\n    <WindowsTargetPlatformVersion>10.0.26100.0</WindowsTargetPlatformVersion>\r\n    <WindowsTargetPlatformMinVersion>10.0.17763.0</WindowsTargetPlatformMinVersion>\r\n    <WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>\r\n    <CppWinRTGenerateWindowsMetadata>false</CppWinRTGenerateWindowsMetadata>\r\n    <ProjectGuid>{0BA531C8-CF0C-405B-8221-0FE51BA529D1}</ProjectGuid>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|ARM64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|Win32\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|ARM64\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|Win32\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"ReleaseStatic|x64\">\r\n      <Configuration>ReleaseStatic</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|ARM64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>ARM64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|Win32\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <PropertyGroup Label=\"Configuration\">\r\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Debug'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n    <LinkIncremental>true</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Release'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <LinkIncremental>false</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='ReleaseStatic'\" Label=\"Configuration\">\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <LinkIncremental>false</LinkIncremental>\r\n  </PropertyGroup>\r\n  <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\" Label=\"Configuration\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\" Label=\"Configuration\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Label=\"Configuration\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\" Label=\"Configuration\">\r\n    <SpectreMitigation>Spectre</SpectreMitigation>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\r\n  <ImportGroup Label=\"ExtensionSettings\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"Shared\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\">\r\n    <Import Project=\"PropertySheet.props\" />\r\n  </ImportGroup>\r\n  <PropertyGroup Label=\"UserMacros\" />\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>true</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>true</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>true</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)x86\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\$(ProjectName)\\</OutDir>\r\n    <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>\r\n    <RunCodeAnalysis>false</RunCodeAnalysis>\r\n    <CodeAnalysisRuleSet>..\\CodeAnalysis.ruleset</CodeAnalysisRuleSet>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(ProjectDir)\\..\\vcpkg.props\" />\r\n  <ItemDefinitionGroup>\r\n    <ClCompile>\r\n      <PrecompiledHeader>Use</PrecompiledHeader>\r\n      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>\r\n      <PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>\r\n      <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <AdditionalOptions>%(AdditionalOptions) /permissive- /bigobj /D _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING</AdditionalOptions>\r\n    </ClCompile>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Debug'\">\r\n    <ClCompile>\r\n      <Optimization>Disabled</Optimization>\r\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\WinGetServer;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\WinGetServer;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</TreatWarningAsError>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">false</ControlFlowGuard>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</ControlFlowGuard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">stdcpp17</LanguageStandard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">stdcpp17</LanguageStandard>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">true</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</EnablePREfast>\r\n      <DisableSpecificWarnings Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">6001</DisableSpecificWarnings>\r\n      <DisableSpecificWarnings Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">6001</DisableSpecificWarnings>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">Windows</SubSystem>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Source.def</ModuleDefinitionFile>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">Source.def</ModuleDefinitionFile>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">Source.def</ModuleDefinitionFile>\r\n      <AdditionalDependencies Condition=\"'$(Configuration)'=='Debug'\">wininet.lib;shell32.lib;winsqlite3.lib;shlwapi.lib;icuuc.lib;icuin.lib;urlmon.lib;Advapi32.lib;winhttp.lib;onecoreuap.lib;msi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</CETCompat>\r\n    </Link>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Platform)'=='Win32'\">\r\n    <ClCompile>\r\n      <PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\WinGetServer;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</TreatWarningAsError>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</ControlFlowGuard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">stdcpp17</LanguageStandard>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</EnablePREfast>\r\n      <DisableSpecificWarnings Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">6001</DisableSpecificWarnings>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Link>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</CETCompat>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Release'\">\r\n    <ClCompile>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\WinGetServer;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\WinGetServer;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\WinGetServer;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">true</TreatWarningAsError>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">Guard</ControlFlowGuard>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Guard</ControlFlowGuard>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Guard</ControlFlowGuard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">stdcpp17</LanguageStandard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">stdcpp17</LanguageStandard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">stdcpp17</LanguageStandard>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</EnablePREfast>\r\n      <DisableSpecificWarnings Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">6001</DisableSpecificWarnings>\r\n      <DisableSpecificWarnings Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">6001</DisableSpecificWarnings>\r\n      <DisableSpecificWarnings Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">6001</DisableSpecificWarnings>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Windows</SubSystem>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Source.def</ModuleDefinitionFile>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">Source.def</ModuleDefinitionFile>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Source.def</ModuleDefinitionFile>\r\n      <AdditionalDependencies Condition=\"'$(Configuration)'=='Release'\">wininet.lib;shell32.lib;winsqlite3.lib;shlwapi.lib;icuuc.lib;icuin.lib;urlmon.lib;Advapi32.lib;winhttp.lib;onecoreuap.lib;msi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">/debug:full /debugtype:cv,fixup /incremental:no %(AdditionalOptions)</AdditionalOptions>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">/debug:full /debugtype:cv,fixup /incremental:no %(AdditionalOptions)</AdditionalOptions>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">/debug:full /debugtype:cv,fixup /incremental:no %(AdditionalOptions)</AdditionalOptions>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</CETCompat>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">true</CETCompat>\r\n    </Link>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='ReleaseStatic'\">\r\n    <ClCompile>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\WinGetServer;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\WinGetServer;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <AdditionalIncludeDirectories Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">$(ProjectDir)..\\AppInstallerSharedLib\\Public;$(ProjectDir)..\\WinGetServer;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">true</TreatWarningAsError>\r\n      <TreatWarningAsError Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">true</TreatWarningAsError>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">Guard</ControlFlowGuard>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">Guard</ControlFlowGuard>\r\n      <ControlFlowGuard Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">Guard</ControlFlowGuard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">stdcpp17</LanguageStandard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">stdcpp17</LanguageStandard>\r\n      <LanguageStandard Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">stdcpp17</LanguageStandard>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">true</SDLCheck>\r\n      <SDLCheck Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">true</SDLCheck>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">false</EnablePREfast>\r\n      <EnablePREfast Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">false</EnablePREfast>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">MultiThreaded</RuntimeLibrary>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">MultiThreaded</RuntimeLibrary>\r\n      <RuntimeLibrary Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">MultiThreaded</RuntimeLibrary>\r\n      <DisableSpecificWarnings Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">6001</DisableSpecificWarnings>\r\n      <DisableSpecificWarnings Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">6001</DisableSpecificWarnings>\r\n      <DisableSpecificWarnings Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">6001</DisableSpecificWarnings>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">false</RuntimeTypeInfo>\r\n      <RuntimeTypeInfo Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">false</RuntimeTypeInfo>\r\n    </ClCompile>\r\n    <Link>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateWindowsMetadata>false</GenerateWindowsMetadata>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">Windows</SubSystem>\r\n      <SubSystem Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">Windows</SubSystem>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">Source.def</ModuleDefinitionFile>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">Source.def</ModuleDefinitionFile>\r\n      <ModuleDefinitionFile Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">Source.def</ModuleDefinitionFile>\r\n      <AdditionalDependencies Condition=\"'$(Configuration)'=='ReleaseStatic'\">wininet.lib;shell32.lib;winsqlite3.lib;shlwapi.lib;icuuc.lib;icuin.lib;urlmon.lib;Advapi32.lib;winhttp.lib;onecoreuap.lib;msi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">/debug:full /debugtype:cv,fixup /incremental:no %(AdditionalOptions)</AdditionalOptions>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">/debug:full /debugtype:cv,fixup /incremental:no %(AdditionalOptions)</AdditionalOptions>\r\n      <AdditionalOptions Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">/debug:full /debugtype:cv,fixup /incremental:no %(AdditionalOptions)</AdditionalOptions>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">true</CETCompat>\r\n      <CETCompat Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">true</CETCompat>\r\n    </Link>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n    <Manifest>\r\n      <AdditionalManifestFiles Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">$(ProjectDir)..\\manifest\\shared.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\r\n    </Manifest>\r\n  </ItemDefinitionGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"Factory.h\" />\r\n    <ClInclude Include=\"pch.h\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"..\\WinGetServer\\Utils.cpp\">\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">NotUsing</PrecompiledHeader>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\WinGetServer\\WinGetServerManualActivation_Client.cpp\">\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">NotUsing</PrecompiledHeader>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\WinGetServer\\WinGetServer_c.c\">\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|Win32'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|ARM64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|ARM64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|ARM64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">NotUsing</PrecompiledHeader>\r\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='ReleaseStatic|x64'\">NotUsing</PrecompiledHeader>\r\n    </ClCompile>\r\n    <ClCompile Include=\"dllmain.cpp\" />\r\n    <ClCompile Include=\"Factory.cpp\" />\r\n    <ClCompile Include=\"pch.cpp\">\r\n      <PrecompiledHeader>Create</PrecompiledHeader>\r\n    </ClCompile>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"packages.config\" />\r\n    <None Include=\"PropertySheet.props\" />\r\n    <None Include=\"Source.def\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\AppInstallerSharedLib\\AppInstallerSharedLib.vcxproj\">\r\n      <Project>{f3f6e699-bc5d-4950-8a05-e49dd9eb0d51}</Project>\r\n    </ProjectReference>\r\n    <ProjectReference Include=\"..\\Microsoft.Management.Deployment\\Microsoft.Management.Deployment.vcxproj\">\r\n      <Project>{1cc41a9a-ae66-459d-9210-1e572dd7be69}</Project>\r\n    </ProjectReference>\r\n  </ItemGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\r\n  <ImportGroup Label=\"ExtensionTargets\">\r\n    <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets')\" />\r\n    <Import Project=\"$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets\" Condition=\"Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" />\r\n  </ImportGroup>\r\n  <Target Name=\"EnsureNuGetPackageBuildImports\" BeforeTargets=\"PrepareForBuild\">\r\n    <PropertyGroup>\r\n      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>\r\n    </PropertyGroup>\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets'))\" />\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.props'))\" />\r\n    <Error Condition=\"!Exists('$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\\packages\\Microsoft.Windows.CppWinRT.2.0.250303.1\\build\\native\\Microsoft.Windows.CppWinRT.targets'))\" />\r\n  </Target>\r\n</Project>\r\n\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment.OutOfProc/Microsoft.Management.Deployment.OutOfProc.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup>\r\n    <Filter Include=\"Source Files\">\r\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r\n      <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Header Files\">\r\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r\n      <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Resource Files\">\r\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"WinGetServerManualActivation\">\r\n      <UniqueIdentifier>{6017fd94-3eb1-40bc-964f-5dd571077d3c}</UniqueIdentifier>\r\n    </Filter>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"pch.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"Factory.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"dllmain.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"pch.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"Factory.cpp\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\WinGetServer\\WinGetServer_c.c\">\r\n      <Filter>WinGetServerManualActivation</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\WinGetServer\\WinGetServerManualActivation_Client.cpp\">\r\n      <Filter>WinGetServerManualActivation</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\WinGetServer\\Utils.cpp\">\r\n      <Filter>WinGetServerManualActivation</Filter>\r\n    </ClCompile>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"packages.config\" />\r\n    <None Include=\"PropertySheet.props\" />\r\n    <None Include=\"Source.def\">\r\n      <Filter>Source Files</Filter>\r\n    </None>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Natvis Include=\"$(MSBuildThisFileDirectory)..\\..\\natvis\\wil.natvis\" />\r\n  </ItemGroup>\r\n</Project>"
  },
  {
    "path": "src/Microsoft.Management.Deployment.OutOfProc/PropertySheet.props",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ImportGroup Label=\"PropertySheets\" />\n  <PropertyGroup Label=\"UserMacros\" />\n    <!--\n    To customize common C++/WinRT project properties: \n    * right-click the project node\n    * expand the Common Properties item\n    * select the C++/WinRT property page\n\n    For more advanced scenarios, and complete documentation, please see:\n    https://github.com/Microsoft/xlang/tree/master/src/package/cppwinrt/nuget \n    -->\n  <PropertyGroup />\n  <ItemDefinitionGroup />\n</Project>"
  },
  {
    "path": "src/Microsoft.Management.Deployment.OutOfProc/Source.def",
    "content": "EXPORTS\nDllCanUnloadNow             PRIVATE\nDllGetClassObject           PRIVATE\nDllGetActivationFactory     PRIVATE\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment.OutOfProc/dllmain.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#include \"pch.h\"\r\n#include \"Factory.h\"\r\n#include <hstring.h>\r\n\r\nusing namespace Microsoft::Management::Deployment::OutOfProc;\r\n\r\nEXTERN_C BOOL WINAPI DllMain(\r\n    HMODULE /* hModule */,\r\n    DWORD reason,\r\n    LPVOID /* lpReserved */)\r\n{\r\n    switch (reason)\r\n    {\r\n    case DLL_PROCESS_DETACH:\r\n        Factory::Terminate();\r\n        break;\r\n    }\r\n\r\n    return TRUE;\r\n}\r\n\r\n_Check_return_\r\nSTDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ LPVOID FAR* ppv) try\r\n{\r\n    RETURN_HR_IF(E_POINTER, !ppv);\r\n    *ppv = nullptr;\r\n\r\n    winrt::Windows::Foundation::IUnknown result;\r\n\r\n    if (Factory::IsCLSID(rclsid))\r\n    {\r\n        result = winrt::make<Factory>(rclsid).as<winrt::Windows::Foundation::IUnknown>();\r\n    }\r\n\r\n    if (result)\r\n    {\r\n        return result.as(riid, ppv);\r\n    }\r\n\r\n    return REGDB_E_CLASSNOTREG;\r\n}\r\nCATCH_RETURN();\r\n\r\n__control_entrypoint(DllExport)\r\nSTDAPI DllCanUnloadNow()\r\n{\r\n    return Factory::HasReferences() ? S_FALSE : S_OK;\r\n}\r\n\r\nSTDAPI DllGetActivationFactory(HSTRING classId, void** factory) try\r\n{\r\n    RETURN_HR_IF(E_POINTER, !factory);\r\n    *factory = nullptr;\r\n\r\n    winrt::Windows::Foundation::IUnknown result;\r\n\r\n    if (Factory::IsCLSID(classId))\r\n    {\r\n        result = winrt::make<Factory>(classId).as<winrt::Windows::Foundation::IUnknown>();\r\n    }\r\n\r\n    if (result)\r\n    {\r\n        return result.as(winrt::guid_of<winrt::Windows::Foundation::IActivationFactory>(), factory);\r\n    }\r\n\r\n    return REGDB_E_CLASSNOTREG;\r\n}\r\nCATCH_RETURN();\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment.OutOfProc/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<packages>\r\n  <package id=\"Microsoft.Windows.CppWinRT\" version=\"2.0.250303.1\" targetFramework=\"native\" />\r\n  <package id=\"Microsoft.Windows.ImplementationLibrary\" version=\"1.0.250325.1\" targetFramework=\"native\" />\r\n</packages>"
  },
  {
    "path": "src/Microsoft.Management.Deployment.OutOfProc/pch.cpp",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n\r\n#include \"pch.h\"\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment.OutOfProc/pch.h",
    "content": "// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n#define WIN32_LEAN_AND_MEAN\r\n#include <Windows.h>\r\n#include <Unknwnbase.h>\r\n#include <inspectable.h>\r\n#include <winstring.h>\r\n\r\n#include <wil/result_macros.h>\r\n#include <winrt/Windows.Foundation.h>\r\n\r\n#include <atomic>\r\n#include <string_view>\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment.Projection/ClassModel.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nnamespace Microsoft.Management.Deployment.Projection\n{\n    using System;\n    using System.Collections.Generic;\n\n    public enum ClsidContext\n    {\n        // In process\n        InProc,\n\n        // Out of process production\n        OutOfProc,\n\n        // Out of process development\n        OutOfProcDev\n    }\n\n    internal class ClassModel\n    {\n        /// <summary>\n        /// Interface type corresponding to the object's IID\n        /// </summary>\n        public Type InterfaceType { init;  get; }\n\n        /// <summary>\n        /// Projected class type by CsWinRT\n        /// </summary>\n        public Type ProjectedClassType { init;  get; }\n\n        /// <summary>\n        /// Clsids for each context (e.g. InProc, OutOfProc, OutOfProcDev)\n        /// </summary>\n        public IReadOnlyDictionary<ClsidContext, Guid> Clsids { init; get; }\n\n        /// <summary>\n        /// Get CLSID based on the provided context\n        /// </summary>\n        /// <param name=\"context\">Context</param>\n        /// <returns>CLSID for the provided context, or throw an exception if not found.</returns>\n        /// <exception cref=\"InvalidOperationException\"></exception>\n        public Guid GetClsid(ClsidContext context)\n        {\n            if (!Clsids.TryGetValue(context, out Guid clsid))\n            {\n                throw new InvalidOperationException($\"{ProjectedClassType.FullName} is not implemented in context {context}\");\n            }\n\n            return clsid;\n        }\n\n        /// <summary>\n        /// Get IID corresponding to the COM object\n        /// </summary>\n        /// <returns>IID.</returns>\n        public Guid GetIid()\n        {\n            return InterfaceType.GUID;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment.Projection/ClassesDefinition.cs",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nnamespace Microsoft.Management.Deployment.Projection\n{\n    using System;\n    using System.Collections.Generic;\n\n    internal static class ClassesDefinition\n    {\n        private static Dictionary<Type, ClassModel> Classes { get; set; } = new()\n        {\n            [typeof(PackageManager)] = new()\n            {\n                ProjectedClassType = typeof(PackageManager),\n                InterfaceType = typeof(IPackageManager),\n                Clsids = new Dictionary<ClsidContext, Guid>()\n                {\n                    [ClsidContext.InProc] = new Guid(\"2DDE4456-64D9-4673-8F7E-A4F19A2E6CC3\"),\n                    [ClsidContext.OutOfProc] = new Guid(\"C53A4F16-787E-42A4-B304-29EFFB4BF597\"),\n                    [ClsidContext.OutOfProcDev] = new Guid(\"74CB3139-B7C5-4B9E-9388-E6616DEA288C\"),\n                }\n            },\n\n            [typeof(FindPackagesOptions)] = new()\n            {\n                ProjectedClassType = typeof(FindPackagesOptions),\n                InterfaceType = typeof(IFindPackagesOptions),\n                Clsids = new Dictionary<ClsidContext, Guid>()\n                {\n                    [ClsidContext.InProc] = new Guid(\"96B9A53A-9228-4DA0-B013-BB1B2031AB3D\"),\n                    [ClsidContext.OutOfProc] = new Guid(\"572DED96-9C60-4526-8F92-EE7D91D38C1A\"),\n                    [ClsidContext.OutOfProcDev] = new Guid(\"1BD8FF3A-EC50-4F69-AEEE-DF4C9D3BAA96\"),\n                }\n            },\n\n            [typeof(CreateCompositePackageCatalogOptions)] = new()\n            {\n                ProjectedClassType = typeof(CreateCompositePackageCatalogOptions),\n                InterfaceType = typeof(ICreateCompositePackageCatalogOptions),\n                Clsids = new Dictionary<ClsidContext, Guid>()\n                {\n                    [ClsidContext.InProc] = new Guid(\"768318A6-2EB5-400D-84D0-DF3534C30F5D\"),\n                    [ClsidContext.OutOfProc] = new Guid(\"526534B8-7E46-47C8-8416-B1685C327D37\"),\n                    [ClsidContext.OutOfProcDev] = new Guid(\"EE160901-B317-4EA7-9CC6-5355C6D7D8A7\"),\n                }\n            },\n\n            [typeof(InstallOptions)] = new()\n            {\n                ProjectedClassType = typeof(InstallOptions),\n                InterfaceType = typeof(IInstallOptions),\n                Clsids = new Dictionary<ClsidContext, Guid>()\n                {\n                    [ClsidContext.InProc] = new Guid(\"E2AF3BA8-8A88-4766-9DDA-AE4013ADE286\"),\n                    [ClsidContext.OutOfProc] = new Guid(\"1095F097-EB96-453B-B4E6-1613637F3B14\"),\n                    [ClsidContext.OutOfProcDev] = new Guid(\"44FE0580-62F7-44D4-9E91-AA9614AB3E86\"),\n                }\n            },\n\n            [typeof(UninstallOptions)] = new()\n            {\n                ProjectedClassType = typeof(UninstallOptions),\n                InterfaceType = typeof(IUninstallOptions),\n                Clsids = new Dictionary<ClsidContext, Guid>()\n                {\n                    [ClsidContext.InProc] = new Guid(\"869CB959-EB54-425C-A1E4-1A1C291C64E9\"),\n                    [ClsidContext.OutOfProc] = new Guid(\"E1D9A11E-9F85-4D87-9C17-2B93143ADB8D\"),\n                    [ClsidContext.OutOfProcDev] = new Guid(\"AA2A5C04-1AD9-46C4-B74F-6B334AD7EB8C\"),\n                }\n            },\r\n\r\n            [typeof(DownloadOptions)] = new()\n            {\n                ProjectedClassType = typeof(DownloadOptions),\n                InterfaceType = typeof(IDownloadOptions),\n                Clsids = new Dictionary<ClsidContext, Guid>()\n                {\n                    [ClsidContext.InProc] = new Guid(\"4288DF96-FDC9-4B68-B403-193DBBF56A24\"),\n                    [ClsidContext.OutOfProc] = new Guid(\"4CBABE76-7322-4BE4-9CEA-2589A80682DC\"),\n                    [ClsidContext.OutOfProcDev] = new Guid(\"8EF324ED-367C-4880-83E5-BB2ABD0B72F6\"),\n                }\n            },\n\n            [typeof(PackageMatchFilter)] = new()\n            {\n                ProjectedClassType = typeof(PackageMatchFilter),\n                InterfaceType = typeof(IPackageMatchFilter),\n                Clsids = new Dictionary<ClsidContext, Guid>()\n                {\n                    [ClsidContext.InProc] = new Guid(\"57DC8962-7343-42CD-B91C-04F6A25DB1D0\"),\n                    [ClsidContext.OutOfProc] = new Guid(\"D02C9DAF-99DC-429C-B503-4E504E4AB000\"),\n                    [ClsidContext.OutOfProcDev] = new Guid(\"3F85B9F4-487A-4C48-9035-2903F8A6D9E8\"),\n                }\n            },\r\n\r\n            [typeof(AuthenticationArguments)] = new()\n            {\n                ProjectedClassType = typeof(AuthenticationArguments),\n                InterfaceType = typeof(IAuthenticationArguments),\n                Clsids = new Dictionary<ClsidContext, Guid>()\n                {\n                    [ClsidContext.InProc] = new Guid(\"8D593114-1CF1-43B9-8722-4DBB30103296\"),\n                    [ClsidContext.OutOfProc] = new Guid(\"BA580786-BDE3-4F6C-B8F3-44698AC8711A\"),\n                    [ClsidContext.OutOfProcDev] = new Guid(\"6484A61D-50FA-41F0-B71E-F4370C6EB37C\"),\n                }\n            },\r\n\r\n            [typeof(PackageManagerSettings)] = new()\n            {\n                ProjectedClassType = typeof(PackageManagerSettings),\n                InterfaceType = typeof(IPackageManagerSettings),\n                Clsids = new Dictionary<ClsidContext, Guid>()\n                {\n                    [ClsidContext.InProc] = new Guid(\"80CF9D63-5505-4342-B9B4-BB87895CA8BB\"),\n                }\n            },\r\n\r\n            [typeof(RepairOptions)] = new ()\r\n            {\r\n                ProjectedClassType = typeof(RepairOptions),\r\n                InterfaceType = typeof(IRepairOptions),\r\n                Clsids = new Dictionary<ClsidContext, Guid>()\r\n                {\r\n                    [ClsidContext.InProc] = new Guid(\"30C024C4-852C-4DD4-9810-1348C51EF9BB\"),\r\n                    [ClsidContext.OutOfProc] = new Guid(\"0498F441-3097-455F-9CAF-148F28293865\"),\r\n                    [ClsidContext.OutOfProcDev] = new Guid(\"E62BB1E7-C7B2-4AEC-9E28-FB649B30FF03\"),\r\n                }\r\n            },\r\n\r\n            [typeof(AddPackageCatalogOptions)] = new()\r\n            {\r\n                ProjectedClassType = typeof(AddPackageCatalogOptions),\r\n                InterfaceType = typeof(IAddPackageCatalogOptions),\r\n                Clsids = new Dictionary<ClsidContext, Guid>()\r\n                {\r\n                    [ClsidContext.InProc] = new Guid(\"24E6F1FA-E4C3-4ACD-965D-DF213FD58F15\"),\r\n                    [ClsidContext.OutOfProc] = new Guid(\"DB9D012D-00D7-47EE-8FB1-606E10AC4F51\"),\r\n                    [ClsidContext.OutOfProcDev] = new Guid(\"D58C7E4C-70E6-476C-A5D4-80341ED80252\"),\r\n                }\r\n            },\r\n\r\n            [typeof(RemovePackageCatalogOptions)] = new()\r\n            {\r\n                ProjectedClassType = typeof(RemovePackageCatalogOptions),\r\n                InterfaceType = typeof(IRemovePackageCatalogOptions),\r\n                Clsids = new Dictionary<ClsidContext, Guid>()\r\n                {\r\n                    [ClsidContext.InProc] = new Guid(\"1125D3A6-E2CE-479A-91D5-71A3F6F8B00B\"),\r\n                    [ClsidContext.OutOfProc] = new Guid(\"032B1C58-B975-469B-A013-E632B6ECE8D8\"),\r\n                    [ClsidContext.OutOfProcDev] = new Guid(\"87A96609-1A39-4955-BE72-7174E147B7DC\"),\r\n                }\r\n            },\r\n\r\n            [typeof(EditPackageCatalogOptions)] = new()\r\n            {\r\n                ProjectedClassType = typeof(EditPackageCatalogOptions),\r\n                InterfaceType = typeof(IEditPackageCatalogOptions),\r\n                Clsids = new Dictionary<ClsidContext, Guid>()\r\n                {\r\n                    [ClsidContext.InProc] = new Guid(\"E8E12FE1-AB77-40C4-A562-E91FB51B4E82\"),\r\n                    [ClsidContext.OutOfProc] = new Guid(\"A9F5E736-68CE-463C-BA6D-DE968F0CCE04\"),\r\n                    [ClsidContext.OutOfProcDev] = new Guid(\"29B19238-81AD-4A8E-A2FC-ADF17C38CAEB\"),\r\n                }\r\n            }\n        };\n\n        /// <summary>\n        /// Get CLSID based on the provided context for the specified type\n        /// </summary>\n        /// <typeparam name=\"T\">Projected class type</typeparam>\n        /// <param name=\"context\">Context</param>\n        /// <returns>CLSID for the provided context and type, or throw an exception if not found.</returns>\n        public static Guid GetClsid<T>(ClsidContext context)\n        {\n            ValidateType(typeof(T));\n            return Classes[typeof(T)].GetClsid(context);\n        }\n\n        /// <summary>\n        /// Get IID corresponding to the COM object\n        /// </summary>\n        /// <typeparam name=\"T\">Projected class type</typeparam>\n        /// <returns>IID or throw an exception if not found.</returns>\n        public static Guid GetIid<T>()\n        {\n            ValidateType(typeof(T));\n            return Classes[typeof(T)].GetIid();\n        }\n\n        /// <summary>\n        /// Validate that the provided type is defined.\n        /// </summary>\n        /// <param name=\"type\">Projected class type</param>\n        /// <exception cref=\"InvalidOperationException\"></exception>\n        private static void ValidateType(Type type)\n        {\n            if (!Classes.ContainsKey(type))\n            {\n                throw new InvalidOperationException($\"{type.Name} is not a projected class type.\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment.Projection/Initializers/ActivationFactoryInstanceInitializer.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nnamespace Microsoft.Management.Deployment.Projection\n{\n    using Microsoft.Management.Deployment.Projection.Initializers;\n\n    /// <summary>\n    /// Activation factory instance initializer requires that:\n    /// - DllGetActivationFactory is exported\n    ///   More details: https://github.com/microsoft/CsWinRT/blob/master/docs/hosting.md#exports\n    /// - Host dll file name should be Microsoft.Management.Deployment.dll or a child namespace\n    ///   to match the projected classes (e.g. PackageManager) namespace\n    ///   More details: https://docs.microsoft.com/en-us/windows/apps/develop/platform/csharp-winrt/#winrt-type-activation\n    /// </summary>\n    public class ActivationFactoryInstanceInitializer : PolicyEnforcedInstanceInitializer\n    {\n        /// <summary>\n        /// In-process context\n        /// </summary>\n        public override ClsidContext Context => ClsidContext.InProc;\r\n\r\n        /// <summary>\n        /// Calls default projected class constructor implemented by CsWinRT.\n        /// Default constructor uses DllGetActivationFactory to create an object\n        /// based on the full name of the projected class.\n        /// </summary>\n        /// <typeparam name=\"T\">Projected class type</typeparam>\n        /// <returns>Instance of the provided type.</returns>\n        protected override T CreateInstanceInternal<T>() => new();\r\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment.Projection/Initializers/IInstanceInitializer.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nnamespace Microsoft.Management.Deployment.Projection\n{\n    public interface IInstanceInitializer\n    {\n        /// <summary>\n        /// CLSID context.\n        /// </summary>\n        public ClsidContext Context { get; }\n\n        /// <summary>\n        /// Create an in-process or out-of process instance.\n        /// </summary>\n        /// <typeparam name=\"T\">Projected class typ</typeparam>\n        /// <returns>Projected class instance</returns>\n        public T CreateInstance<T>() where T : new();\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment.Projection/Initializers/LocalServerInstanceInitializer.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nnamespace Microsoft.Management.Deployment.Projection\n{\r\n    using Microsoft.Management.Deployment.Projection.Initializers;\r\n    using WinRT;\n\n    // Out-of-process COM instance initializer.\n    public class LocalServerInstanceInitializer : PolicyEnforcedInstanceInitializer\n    {\n        /// <summary>\n        /// Out-of-process context.\n        /// </summary>\n        public override ClsidContext Context => UseDevClsids ? ClsidContext.OutOfProcDev : ClsidContext.OutOfProc;\n\n        /// <summary>\n        /// Allow lower trust registration.\n        /// This is useful when running COM client with admin privileges. (e.g. E2E tests)\n        /// </summary>\n        public bool AllowLowerTrustRegistration { init; get; }\n\n        /// <summary>\n        /// Use Prod or Dev Clsids\n        /// </summary>\n        public bool UseDevClsids { init; get; }\n\n        /// <summary>\n        /// Create instance of the provided type.\n        /// </summary>\n        /// <typeparam name=\"T\">Projected class type.</typeparam>\n        /// <returns>Instance of the provided type.</returns>\n        protected override T CreateInstanceInternal<T>()\n        {\n            var clsid = ClassesDefinition.GetClsid<T>(Context);\n            var iid = ClassesDefinition.GetIid<T>();\n\n            var instanceInPtr = ComUtils.CoCreateInstanceLocalServer(clsid, iid, AllowLowerTrustRegistration);\n            return MarshalGeneric<T>.FromAbi(instanceInPtr);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment.Projection/Initializers/PolicyEnforcedInstanceInitializer.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation.\r\n// Licensed under the MIT License.\r\n\r\nnamespace Microsoft.Management.Deployment.Projection.Initializers\r\n{\r\n    using Microsoft.WinGet.SharedLib.Exceptions;\r\n    using Microsoft.WinGet.SharedLib.PolicySettings;\r\n\r\n    /// <summary>\r\n    /// An abstract base that enforces group policy before creating derived class instance.\r\n    /// </summary>\r\n    public abstract class PolicyEnforcedInstanceInitializer : IInstanceInitializer\r\n    {\r\n        /// <summary>\r\n        /// CLSID context.\r\n        /// </summary>\r\n        public abstract ClsidContext Context { get; }\r\n\r\n        /// <summary>\r\n        /// Create instance of the provided type.\r\n        /// </summary>\r\n        /// <typeparam name=\"T\">Projected class type.</typeparam>\r\n        /// <returns>Instance of the provided type.</returns>\r\n        public T CreateInstance<T>() where T : new()\r\n        {\r\n            GroupPolicy groupPolicy = GroupPolicy.GetInstance();\r\n\r\n            if (!groupPolicy.IsEnabled(Policy.WinGet))\r\n            {\r\n                throw new GroupPolicyException(Policy.WinGet, GroupPolicyFailureType.BlockedByPolicy);\r\n            }\r\n\r\n            return this.CreateInstanceInternal<T>();\r\n        }\r\n\r\n        protected abstract T CreateInstanceInternal<T>() where T : new();\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment.Projection/Microsoft.Management.Deployment.Projection.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>net8.0-windows</TargetFramework>\n    <OutDir>$(SolutionDir)$(Platform)\\$(Configuration)\\Microsoft.Management.Deployment.Projection\\</OutDir>\n    <IsPackable>false</IsPackable>\n    <Platforms>x64;x86;arm64</Platforms>\n    <OutputType>Library</OutputType>\n    <Configurations>Debug;Release;ReleaseStatic</Configurations>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.Windows.CsWinRT\" />\n  </ItemGroup>\n\n  <!-- CsWinRT properties -->\n  <PropertyGroup>\n    <CsWinRTWindowsMetadata>10.0.26100.0</CsWinRTWindowsMetadata>\n    <CsWinRTIncludes>Microsoft.Management.Deployment;Windows.Foundation;Windows.System.ProcessorArchitecture</CsWinRTIncludes>\n    <CsWinRTExcludes>Windows.Foundation.Diagnostics</CsWinRTExcludes>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\Microsoft.Management.Deployment\\Microsoft.Management.Deployment.vcxproj\">\n      <OutputItemType>Content</OutputItemType>\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n      <ReferenceOutputAssembly>True</ReferenceOutputAssembly>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\PowerShell\\Microsoft.WinGet.SharedLib\\Microsoft.WinGet.SharedLib.csproj\" />\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment.Projection/Utils/ComUtils.cs",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nnamespace Microsoft.Management.Deployment.Projection\n{\n    using System;\n    using System.Runtime.InteropServices;\n\n    internal static class ComUtils\n    {\r\n        [DllImport(\"api-ms-win-core-com-l1-1-0.dll\")]\n        private static extern unsafe int CoCreateInstance(ref Guid clsid, IntPtr outer, uint clsContext, ref Guid iid, IntPtr* instance);\r\n\n        /// <summary>\n        /// CLSCTX enumeration\n        /// https://docs.microsoft.com/en-us/windows/win32/api/wtypesbase/ne-wtypesbase-clsctx\n        /// </summary>\n        private enum CLSCTX : uint\n        {\n            CLSCTX_INPROC_SERVER = 0x1,\n            CLSCTX_LOCAL_SERVER = 0x4,\n            CLSCTX_ALLOW_LOWER_TRUST_REGISTRATION = 0x4000000\n        }\n\n        /// <summary>\n        /// CoCreateInstance function\n        /// https://docs.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-cocreateinstance\n        /// </summary>\n        /// <param name=\"clsid\">CLSID</param>\n        /// <param name=\"clsContext\">CLSCTX</param>\n        /// <param name=\"iid\">IID</param>\n        /// <returns>Interface pointer, or throw an exception if HRESULT was not successful.</returns>\n        private static unsafe IntPtr CoCreateInstance(Guid clsid, CLSCTX clsContext, Guid iid)\n        {\n            IntPtr instanceIntPtr;\n            int hr = CoCreateInstance(ref clsid, IntPtr.Zero, (uint)clsContext, ref iid, &instanceIntPtr);\n            Marshal.ThrowExceptionForHR(hr);\n            return instanceIntPtr;\n        }\n\n        /// <summary>\n        /// CoCreateInstance with an out-of-process context.\n        /// </summary>\n        /// <param name=\"clsid\">CLSID</param>\n        /// <param name=\"iid\">CLSCTX</param>\n        /// <param name=\"allowLowerTrustRegistration\">Allow lower trust registration</param>\n        /// <returns><see cref=\"CoCreateInstance\"/> ></returns>\n        public static IntPtr CoCreateInstanceLocalServer(Guid clsid, Guid iid, bool allowLowerTrustRegistration = false)\n        {\n            CLSCTX clsctx = CLSCTX.CLSCTX_LOCAL_SERVER;\n            if (allowLowerTrustRegistration)\n            {\n                clsctx |= CLSCTX.CLSCTX_ALLOW_LOWER_TRUST_REGISTRATION;\n            }\n\n            return CoCreateInstance(clsid, clsctx, iid);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Microsoft.Management.Deployment.Projection/WinGetProjectionFactory.cs",
    "content": "// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nnamespace Microsoft.Management.Deployment.Projection\n{\n    /// <summary>\n    /// Factory class to created CsWinRT projected class instances for in-process or out-of-process objects.\n    /// </summary>\n    public class WinGetProjectionFactory\n    {\n        public WinGetProjectionFactory(IInstanceInitializer instanceInitializer)\n        {\n            InstanceInitializer = instanceInitializer;\n        }\n\n        private IInstanceInitializer InstanceInitializer { get; set; }\n\n        public ClsidContext Context => InstanceInitializer.Context;\n\n        public PackageManager CreatePackageManager() => InstanceInitializer.CreateInstance<PackageManager>();\n\n        public FindPackagesOptions CreateFindPackagesOptions() => InstanceInitializer.CreateInstance<FindPackagesOptions>();\n\n        public CreateCompositePackageCatalogOptions CreateCreateCompositePackageCatalogOptions() => InstanceInitializer.CreateInstance<CreateCompositePackageCatalogOptions>();\n\n        public InstallOptions CreateInstallOptions() => InstanceInitializer.CreateInstance<InstallOptions>();\n\n        public UninstallOptions CreateUninstallOptions() => InstanceInitializer.CreateInstance<UninstallOptions>();\n\n        public DownloadOptions CreateDownloadOptions() => InstanceInitializer.CreateInstance<DownloadOptions>();\n\n        public PackageMatchFilter CreatePackageMatchFilter() => InstanceInitializer.CreateInstance<PackageMatchFilter>();\n\n        public AuthenticationArguments CreateAuthenticationArguments() => InstanceInitializer.CreateInstance<AuthenticationArguments>();\n\n        public PackageManagerSettings CreatePackageManagerSettings() => InstanceInitializer.CreateInstance<PackageManagerSettings>();\n\r\n        public RepairOptions CreateRepairOptions() => InstanceInitializer.CreateInstance<RepairOptions>();\n\r\n        public AddPackageCatalogOptions CreateAddPackageCatalogOptions() => InstanceInitializer.CreateInstance<AddPackageCatalogOptions>();\r\n\r\n        public RemovePackageCatalogOptions CreateRemovePackageCatalogOptions() => InstanceInitializer.CreateInstance<RemovePackageCatalogOptions>();\r\n\r\n        public EditPackageCatalogOptions CreateEditPackageCatalogOptions() => InstanceInitializer.CreateInstance<EditPackageCatalogOptions>();\n    }\n}\n"
  },
  {
    "path": "src/PowerShell/CommonFiles/PowerShellCmdlet.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"PowerShellCmdlet.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Common.Command\r\n{\r\n    using System;\r\n    using System.Collections.Concurrent;\r\n    using System.Collections.Generic;\r\n    using System.Management.Automation;\r\n    using System.Runtime.ExceptionServices;\r\n    using System.Threading;\r\n    using System.Threading.Tasks;\r\n    using Microsoft.WinGet.Resources;\r\n    using Microsoft.WinGet.SharedLib.Exceptions;\r\n    using Microsoft.WinGet.SharedLib.PolicySettings;\r\n\r\n    /// <summary>\r\n    /// This must be the base class for every cmdlet for winget PowerShell modules.\r\n    /// It supports:\r\n    ///  - Async operations.\r\n    ///  - Execute on an MTA. If the thread is already running on an MTA it will executed it, otherwise\r\n    ///    it will create a new MTA thread.\r\n    /// Wait must be used to synchronously wait con the task.\r\n    /// </summary>\r\n    public abstract class PowerShellCmdlet\r\n    {\r\n        private const string Debug = \"Debug\";\r\n        private static readonly string[] WriteInformationTags = new string[] { \"PSHOST\" };\r\n\r\n        private readonly PSCmdlet psCmdlet;\r\n        private readonly Thread pwshThread;\r\n\r\n        private readonly CancellationTokenSource source = new ();\r\n        private readonly SemaphoreSlim semaphore = new (1, 1);\r\n        private readonly ManualResetEventSlim pwshThreadActionReady = new (false);\r\n        private readonly ManualResetEventSlim pwshThreadActionCompleted = new (false);\r\n\r\n        private BlockingCollection<QueuedStream> queuedStreams = new ();\r\n        private int progressActivityId = 0;\r\n        private ConcurrentDictionary<int, ProgressRecordType> progressRecords = new ();\r\n        private Action? pwshThreadAction = null;\r\n        private ExceptionDispatchInfo? pwshThreadEdi = null;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"PowerShellCmdlet\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"psCmdlet\">PSCmdlet.</param>\r\n        /// <param name=\"policies\">Policies.</param>\r\n        public PowerShellCmdlet(PSCmdlet psCmdlet, HashSet<Policy> policies)\r\n        {\r\n            // Passing Debug will make all the message actions to be Inquire. For async operations\r\n            // and the current queue message implementation this doesn't make sense.\r\n            // PowerShell will inquire for any message giving the impression that the task is\r\n            // paused, but the async operation is still running.\r\n            if (psCmdlet.MyInvocation.BoundParameters.ContainsKey(Debug))\r\n            {\r\n                throw new NotSupportedException(Resources.DebugNotSupported);\r\n            }\r\n\r\n            this.ValidatePolicies(policies);\r\n\r\n            this.psCmdlet = psCmdlet;\r\n            this.pwshThread = Thread.CurrentThread;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Request cancellation for this command.\r\n        /// </summary>\r\n        public void Cancel()\r\n        {\r\n            this.source.Cancel();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Execute the delegate in a MTA thread.\r\n        /// Caller must wait on task.\r\n        /// </summary>\r\n        /// <param name=\"func\">Function to execute.</param>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous operation.</returns>\r\n        internal Task RunOnMTA(Func<Task> func)\r\n        {\r\n            // .NET 4.8 doesn't support TaskCompletionSource.\r\n#if POWERSHELL_WINDOWS\r\n            throw new NotImplementedException();\r\n#else\r\n            // This must be called in the main thread.\r\n            if (this.pwshThread != Thread.CurrentThread)\r\n            {\r\n                throw new InvalidOperationException();\r\n            }\r\n\r\n            if (Thread.CurrentThread.GetApartmentState() == ApartmentState.MTA)\r\n            {\r\n                this.Write(StreamType.Verbose, \"Already running on MTA\");\r\n                try\r\n                {\r\n                    Task result = func();\r\n                    result.ContinueWith((task) => this.Complete(), TaskContinuationOptions.ExecuteSynchronously);\r\n                    return result;\r\n                }\r\n                catch\r\n                {\r\n                    this.Complete();\r\n                    throw;\r\n                }\r\n            }\r\n\r\n            this.Write(StreamType.Verbose, \"Creating MTA thread\");\r\n            var tcs = new TaskCompletionSource();\r\n            var thread = new Thread(() =>\r\n            {\r\n                try\r\n                {\r\n                    func().GetAwaiter().GetResult();\r\n                    tcs.SetResult();\r\n                }\r\n                catch (Exception e)\r\n                {\r\n                    tcs.SetException(e);\r\n                }\r\n                finally\r\n                {\r\n                    this.Complete();\r\n                }\r\n            });\r\n\r\n            thread.SetApartmentState(ApartmentState.MTA);\r\n            thread.Start();\r\n            return tcs.Task;\r\n#endif\r\n        }\r\n\r\n        /// <summary>\r\n        /// Execute the delegate in a MTA thread.\r\n        /// Caller must wait on task.\r\n        /// </summary>\r\n        /// <param name=\"func\">Function to execute.</param>\r\n        /// <typeparam name=\"TResult\">Return type of function.</typeparam>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous operation.</returns>\r\n        internal Task<TResult> RunOnMTA<TResult>(Func<Task<TResult>> func)\r\n        {\r\n            // This must be called in the main thread.\r\n            if (this.pwshThread != Thread.CurrentThread)\r\n            {\r\n                throw new InvalidOperationException();\r\n            }\r\n\r\n            if (Thread.CurrentThread.GetApartmentState() == ApartmentState.MTA)\r\n            {\r\n                this.Write(StreamType.Verbose, \"Already running on MTA\");\r\n                try\r\n                {\r\n                    Task<TResult> result = func();\r\n                    result.ContinueWith((task) => this.Complete(), TaskContinuationOptions.ExecuteSynchronously);\r\n                    return result;\r\n                }\r\n                catch\r\n                {\r\n                    this.Complete();\r\n                    throw;\r\n                }\r\n            }\r\n\r\n            this.Write(StreamType.Verbose, \"Creating MTA thread\");\r\n            var tcs = new TaskCompletionSource<TResult>();\r\n            var thread = new Thread(() =>\r\n            {\r\n                try\r\n                {\r\n                    var result = func().GetAwaiter().GetResult();\r\n                    tcs.SetResult(result);\r\n                }\r\n                catch (Exception e)\r\n                {\r\n                    tcs.SetException(e);\r\n                }\r\n                finally\r\n                {\r\n                    this.Complete();\r\n                }\r\n            });\r\n\r\n            thread.SetApartmentState(ApartmentState.MTA);\r\n            thread.Start();\r\n            return tcs.Task;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Execute the delegate in a MTA thread.\r\n        /// Synchronous call.\r\n        /// </summary>\r\n        /// <param name=\"func\">Function to execute.</param>\r\n        /// <typeparam name=\"TResult\">Return type of function.</typeparam>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous operation.</returns>\r\n        internal TResult RunOnMTA<TResult>(Func<TResult> func)\r\n        {\r\n            // This must be called in the main thread.\r\n            if (this.pwshThread != Thread.CurrentThread)\r\n            {\r\n                throw new InvalidOperationException();\r\n            }\r\n\r\n            if (Thread.CurrentThread.GetApartmentState() == ApartmentState.MTA)\r\n            {\r\n                this.Write(StreamType.Verbose, \"Already running on MTA\");\r\n                try\r\n                {\r\n                    return func();\r\n                }\r\n                finally\r\n                {\r\n                    this.Complete();\r\n                }\r\n            }\r\n\r\n            this.Write(StreamType.Verbose, \"Creating MTA thread\");\r\n            var tcs = new TaskCompletionSource<TResult>();\r\n            var thread = new Thread(() =>\r\n            {\r\n                try\r\n                {\r\n                    var result = func();\r\n                    tcs.SetResult(result);\r\n                }\r\n                catch (Exception e)\r\n                {\r\n                    tcs.SetException(e);\r\n                }\r\n                finally\r\n                {\r\n                    this.Complete();\r\n                }\r\n            });\r\n\r\n            thread.SetApartmentState(ApartmentState.MTA);\r\n            thread.Start();\r\n            this.Wait(tcs.Task);\r\n            return tcs.Task.Result;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Executes an action in the main thread.\r\n        /// Blocks until call is executed.\r\n        /// </summary>\r\n        /// <param name=\"action\">Action to perform.</param>\r\n        internal void ExecuteInPowerShellThread(Action action)\r\n        {\r\n            if (this.pwshThread == Thread.CurrentThread)\r\n            {\r\n                action();\r\n                return;\r\n            }\r\n\r\n            this.WaitForOurTurn();\r\n\r\n            this.pwshThreadAction = action;\r\n            this.pwshThreadActionReady.Set();\r\n            this.WaitMainThreadActionCompletion();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Waits for the task to be completed. This MUST be called from the main thread.\r\n        /// </summary>\r\n        /// <param name=\"runningTask\">Task to wait for.</param>\r\n        /// <param name=\"writeCmdlet\">The cmdlet that can write to PowerShell.</param>\r\n        internal void Wait(Task runningTask, PowerShellCmdlet? writeCmdlet = null)\r\n        {\r\n            writeCmdlet ??= this;\r\n\r\n            // This must be called in the main thread.\r\n            if (this.pwshThread != Thread.CurrentThread)\r\n            {\r\n                throw new InvalidOperationException();\r\n            }\r\n\r\n            do\r\n            {\r\n                if (this.pwshThreadActionReady.IsSet)\r\n                {\r\n                    // Someone needs the main thread.\r\n                    this.pwshThreadActionReady.Reset();\r\n\r\n                    if (this.pwshThreadAction != null)\r\n                    {\r\n                        try\r\n                        {\r\n                            this.pwshThreadEdi = null;\r\n                            this.pwshThreadAction();\r\n                        }\r\n                        catch (Exception e)\r\n                        {\r\n                            // Make sure we don't throw in the PowerShell thread, this way\r\n                            // we'll get a more meaningful stack by Get-Error.\r\n                            this.pwshThreadEdi = ExceptionDispatchInfo.Capture(e);\r\n                        }\r\n\r\n                        this.pwshThreadAction = null;\r\n                    }\r\n\r\n                    // Done.\r\n                    this.pwshThreadActionCompleted.Set();\r\n                }\r\n\r\n                // Take from the blocking collection.\r\n                if (!this.queuedStreams.IsCompleted && this.queuedStreams.Count > 0)\r\n                {\r\n                    try\r\n                    {\r\n                        var queuedOutput = this.queuedStreams.Take();\r\n                        if (queuedOutput != null)\r\n                        {\r\n                            this.CmdletWrite(queuedOutput.Type, queuedOutput.Data, writeCmdlet);\r\n                        }\r\n                    }\r\n                    catch (InvalidOperationException)\r\n                    {\r\n                        // An InvalidOperationException means that Take() was called on a completed collection.\r\n                    }\r\n                }\r\n            }\r\n            while (!(runningTask.IsCompleted && this.queuedStreams.IsCompleted));\r\n\r\n            if (runningTask.IsFaulted)\r\n            {\r\n                // If IsFaulted is true, the task's Status is equal to Faulted,\r\n                // and its Exception property will be non-null.\r\n                AggregateException? ae = runningTask.Exception! as AggregateException;\r\n                if (ae != null && ae.InnerExceptions.Count == 1)\r\n                {\r\n                    ExceptionDispatchInfo.Capture(ae.InnerExceptions[0]).Throw();\r\n                }\r\n\r\n                throw runningTask.Exception!;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Writes into the corresponding stream if running on the main thread.\r\n        /// Otherwise queue the message.\r\n        /// Is the caller responsibility to use the correct types.\r\n        /// </summary>\r\n        /// <param name=\"type\">Stream type.</param>\r\n        /// <param name=\"data\">Data.</param>\r\n        internal void Write(StreamType type, object data)\r\n        {\r\n            if (type == StreamType.Progress)\r\n            {\r\n                ProgressRecord progressRecord = (ProgressRecord)data;\r\n                if (progressRecord.RecordType == ProgressRecordType.Completed)\r\n                {\r\n                    throw new NotSupportedException(\"Use CompleteProgress\");\r\n                }\r\n\r\n                // Keep track of all progress activity.\r\n                _ = this.progressRecords.TryAdd(progressRecord.ActivityId, progressRecord.RecordType);\r\n            }\r\n\r\n            if (this.pwshThread == Thread.CurrentThread)\r\n            {\r\n                this.CmdletWrite(type, data, this);\r\n                return;\r\n            }\r\n\r\n            this.queuedStreams.Add(new QueuedStream(type, data));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Helper to compute percentage and write progress for processing activities.\r\n        /// </summary>\r\n        /// <param name=\"activityId\">Activity id.</param>\r\n        /// <param name=\"activity\">The activity in progress.</param>\r\n        /// <param name=\"status\">The status of the activity.</param>\r\n        /// <param name=\"completed\">Number of completed actions.</param>\r\n        /// <param name=\"total\">The expected total.</param>\r\n        internal void WriteProgressWithPercentage(int activityId, string activity, string status, int completed, int total)\r\n        {\r\n            double percentComplete = (double)completed / total;\r\n            var record = new ProgressRecord(activityId, activity, status)\r\n            {\r\n                RecordType = ProgressRecordType.Processing,\r\n                PercentComplete = (int)(100.0 * percentComplete),\r\n            };\r\n            this.Write(StreamType.Progress, record);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Helper to complete progress records.\r\n        /// </summary>\r\n        /// <param name=\"activityId\">Activity id.</param>\r\n        /// <param name=\"activity\">The activity in progress.</param>\r\n        /// <param name=\"status\">The status of the activity.</param>\r\n        /// <param name=\"force\">Force write complete progress.</param>\r\n        internal void CompleteProgress(int activityId, string activity, string status, bool force = false)\r\n        {\r\n            var record = new ProgressRecord(activityId, activity, status)\r\n            {\r\n                RecordType = ProgressRecordType.Completed,\r\n                PercentComplete = 100,\r\n            };\r\n\r\n            if (!this.progressRecords.TryAdd(activityId, record.RecordType))\r\n            {\r\n                _ = this.progressRecords.TryUpdate(activityId, record.RecordType, ProgressRecordType.Processing);\r\n            }\r\n\r\n            if (this.pwshThread == Thread.CurrentThread)\r\n            {\r\n                this.CmdletWrite(StreamType.Progress, record, this);\r\n            }\r\n            else\r\n            {\r\n                // You should only use force if you know the cmdlet that is completing this progress is a sync cmdlet that\r\n                // is running in an async context. A sync cmdlet is anything that doesn't start with Start-*\r\n                if (force)\r\n                {\r\n                    this.ExecuteInPowerShellThread(() => this.CmdletWrite(StreamType.Progress, record, this));\r\n                }\r\n                else\r\n                {\r\n                    this.queuedStreams.Add(new QueuedStream(StreamType.Progress, record));\r\n                }\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Writes to PowerShell streams.\r\n        /// This method must be called in the original thread.\r\n        /// WARNING: You must only call this when the task is completed.\r\n        /// </summary>\r\n        /// <param name=\"writeCmdlet\">The cmdlet that can write to PowerShell.</param>\r\n        internal void ConsumeAndWriteStreams(PowerShellCmdlet writeCmdlet)\r\n        {\r\n            // This must be called in the main thread.\r\n            if (this.pwshThread != Thread.CurrentThread)\r\n            {\r\n                throw new InvalidOperationException();\r\n            }\r\n\r\n            // Take from the blocking collection until is completed.\r\n            try\r\n            {\r\n                while (true)\r\n                {\r\n                    var queuedOutput = this.queuedStreams.Take();\r\n                    if (queuedOutput != null)\r\n                    {\r\n                        this.CmdletWrite(queuedOutput.Type, queuedOutput.Data, writeCmdlet);\r\n                    }\r\n                }\r\n            }\r\n            catch (InvalidOperationException)\r\n            {\r\n                // We are done.\r\n                // An InvalidOperationException means that Take() was called on a completed collection.\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets a new progress activity id.\r\n        /// </summary>\r\n        /// <returns>The new progress record id.</returns>\r\n        internal int GetNewProgressActivityId()\r\n        {\r\n            return Interlocked.Increment(ref this.progressActivityId);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the cancellation token.\r\n        /// </summary>\r\n        /// <returns>CancellationToken.</returns>\r\n        internal CancellationToken GetCancellationToken()\r\n        {\r\n            return this.source.Token;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the current file system location from the cmdlet.\r\n        /// </summary>\r\n        /// <returns>Path.</returns>\r\n        internal string GetCurrentFileSystemLocation()\r\n        {\r\n            return this.psCmdlet.SessionState.Path.CurrentFileSystemLocation.Path;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Sets a variable.\r\n        /// </summary>\r\n        /// <param name=\"variableName\">Variable name.</param>\r\n        /// <param name=\"value\">Value.</param>\r\n        internal void SetVariable(string variableName, object value)\r\n        {\r\n            this.psCmdlet.SessionState.PSVariable.Set(variableName, value);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Prompts the user if it should continue processing if possible.\r\n        /// </summary>\r\n        /// <param name=\"target\">Message.</param>\r\n        /// <returns>If the operation should continue.</returns>\r\n        internal bool ShouldProcess(string target)\r\n        {\r\n            // If not on the main thread just continue.\r\n            if (this.pwshThread != Thread.CurrentThread)\r\n            {\r\n                return true;\r\n            }\r\n\r\n            return this.psCmdlet.ShouldProcess(target);\r\n        }\r\n\r\n        private void Complete()\r\n        {\r\n            this.queuedStreams.CompleteAdding();\r\n        }\r\n\r\n        private void CmdletWrite(StreamType streamType, object data, PowerShellCmdlet writeCmdlet)\r\n        {\r\n            switch (streamType)\r\n            {\r\n                case StreamType.Debug:\r\n                    throw new NotSupportedException();\r\n                case StreamType.Verbose:\r\n                    writeCmdlet.psCmdlet.WriteVerbose((string)data);\r\n                    break;\r\n                case StreamType.Warning:\r\n                    writeCmdlet.psCmdlet.WriteWarning((string)data);\r\n                    break;\r\n                case StreamType.Error:\r\n                    writeCmdlet.psCmdlet.WriteError((ErrorRecord)data);\r\n                    break;\r\n                case StreamType.Progress:\r\n                    // If the activity is already completed don't write progress.\r\n                    var progressRecord = (ProgressRecord)data;\r\n                    if (this.progressRecords[progressRecord.ActivityId] == progressRecord.RecordType)\r\n                    {\r\n                        writeCmdlet.psCmdlet.WriteProgress(progressRecord);\r\n                    }\r\n\r\n                    break;\r\n                case StreamType.Object:\r\n                    writeCmdlet.psCmdlet.WriteObject(data);\r\n                    break;\r\n                case StreamType.Information:\r\n                    writeCmdlet.psCmdlet.WriteInformation(data, WriteInformationTags);\r\n                    break;\r\n            }\r\n        }\r\n\r\n        private void ValidatePolicies(HashSet<Policy> policies)\r\n        {\r\n            GroupPolicy groupPolicy = GroupPolicy.GetInstance();\r\n\r\n            if (policies.Contains(Policy.WinGet))\r\n            {\r\n                if (!groupPolicy.IsEnabled(Policy.WinGet))\r\n                {\r\n                    throw new GroupPolicyException(Policy.WinGet, GroupPolicyFailureType.BlockedByPolicy);\r\n                }\r\n\r\n                policies.Remove(Policy.WinGet);\r\n            }\r\n\r\n            if (policies.Contains(Policy.Configuration))\r\n            {\r\n                if (!groupPolicy.IsEnabled(Policy.Configuration))\r\n                {\r\n                    throw new GroupPolicyException(Policy.Configuration, GroupPolicyFailureType.BlockedByPolicy);\r\n                }\r\n\r\n                policies.Remove(Policy.Configuration);\r\n            }\r\n\r\n            if (policies.Contains(Policy.WinGetCommandLineInterfaces))\r\n            {\r\n                if (!groupPolicy.IsEnabled(Policy.WinGetCommandLineInterfaces))\r\n                {\r\n                    throw new GroupPolicyException(Policy.WinGetCommandLineInterfaces, GroupPolicyFailureType.BlockedByPolicy);\r\n                }\r\n\r\n                policies.Remove(Policy.WinGetCommandLineInterfaces);\r\n            }\r\n\r\n            if (policies.Count > 0)\r\n            {\r\n                throw new NotSupportedException($\"Invalid policies {string.Join(\",\", policies)}\");\r\n            }\r\n        }\r\n\r\n        private void WaitForOurTurn()\r\n        {\r\n            this.semaphore.Wait(this.GetCancellationToken());\r\n            this.pwshThreadActionCompleted.Reset();\r\n        }\r\n\r\n        private void WaitMainThreadActionCompletion()\r\n        {\r\n            WaitHandle.WaitAny(new[]\r\n            {\r\n                this.GetCancellationToken().WaitHandle,\r\n                this.pwshThreadActionCompleted.WaitHandle,\r\n            });\r\n\r\n            try\r\n            {\r\n                if (this.pwshThreadEdi != null)\r\n                {\r\n                    this.pwshThreadEdi.Throw();\r\n                }\r\n            }\r\n            finally\r\n            {\r\n                this.semaphore.Release();\r\n            }\r\n        }\r\n\r\n        private class QueuedStream\r\n        {\r\n            public QueuedStream(StreamType type, object data)\r\n            {\r\n                this.Type = type;\r\n                this.Data = data;\r\n            }\r\n\r\n            public StreamType Type { get; }\r\n\r\n            public object Data { get; }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/CommonFiles/StreamType.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"StreamType.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Common.Command\r\n{\r\n    /// <summary>\r\n    /// The write stream type of the cmdlet.\r\n    /// </summary>\r\n    public enum StreamType\r\n    {\r\n        /// <summary>\r\n        /// Debug.\r\n        /// </summary>\r\n        Debug,\r\n\r\n        /// <summary>\r\n        /// Verbose.\r\n        /// </summary>\r\n        Verbose,\r\n\r\n        /// <summary>\r\n        /// Warning.\r\n        /// </summary>\r\n        Warning,\r\n\r\n        /// <summary>\r\n        /// Error.\r\n        /// </summary>\r\n        Error,\r\n\r\n        /// <summary>\r\n        /// Progress.\r\n        /// </summary>\r\n        Progress,\r\n\r\n        /// <summary>\r\n        /// Object.\r\n        /// </summary>\r\n        Object,\r\n\r\n        /// <summary>\r\n        /// Information.\r\n        /// </summary>\r\n        Information,\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/CommonFiles/WinGetAssemblyLoadContext.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"WinGetAssemblyLoadContext.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n#if !POWERSHELL_WINDOWS\r\nnamespace Microsoft.WinGet.Resolver\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.IO;\r\n    using System.Linq;\r\n    using System.Reflection;\r\n    using System.Runtime.InteropServices;\r\n    using System.Runtime.Loader;\r\n\r\n    /// <summary>\r\n    /// Custom assembly load context for this module.\r\n    /// This helps us load our dependencies without carrying about apps importing this module.\r\n    /// All dependencies except the Engine dll needs to be under a Dependencies directory.\r\n    /// </summary>\r\n    internal class WinGetAssemblyLoadContext : AssemblyLoadContext\r\n    {\r\n        // The assemblies must be loaded in the default context.\r\n        // Loading WinRT.Runtime.dll in an ALC when is already loaded in the default context\r\n        // will result on 'Attempt to update previously set global instance.'\r\n        private static readonly IEnumerable<string> DefaultContextAssemblies = new string[]\r\n        {\r\n            @\"WinRT.Runtime.dll\",\r\n        };\r\n\r\n        private static readonly string SharedDependencyPath;\r\n        private static readonly string SharedArchDependencyPath;\r\n        private static readonly string DirectDependencyPath;\r\n\r\n        private static readonly WinGetAssemblyLoadContext WinGetAcl = new ();\r\n\r\n        static WinGetAssemblyLoadContext()\r\n        {\r\n            var self = typeof(WinGetAssemblyLoadContext).Assembly;\r\n            SharedDependencyPath = Path.Combine(\r\n                Path.GetDirectoryName(self.Location),\r\n                \"SharedDependencies\");\r\n            SharedArchDependencyPath = Path.Combine(\r\n                SharedDependencyPath,\r\n                RuntimeInformation.ProcessArchitecture.ToString().ToLower());\r\n            DirectDependencyPath = Path.Combine(\r\n                Path.GetDirectoryName(self.Location),\r\n                \"DirectDependencies\");\r\n        }\r\n\r\n        private WinGetAssemblyLoadContext()\r\n            : base(\"WinGetAssemblyLoadContext\", isCollectible: false)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Handler to resolve assemblies.\r\n        /// </summary>\r\n        /// <param name=\"context\">Assembly load context.</param>\r\n        /// <param name=\"assemblyName\">Assembly name.</param>\r\n        /// <returns>The assembly, null if not in our assembly location.</returns>\r\n        internal static Assembly ResolvingHandler(AssemblyLoadContext context, AssemblyName assemblyName)\r\n        {\r\n            string name = $\"{assemblyName.Name}.dll\";\r\n            if (DefaultContextAssemblies.Any(a => a.Equals(name, StringComparison.OrdinalIgnoreCase)))\r\n            {\r\n                string sharedPath = Path.Combine(SharedDependencyPath, name);\r\n                if (File.Exists(sharedPath))\r\n                {\r\n                    return AssemblyLoadContext.Default.LoadFromAssemblyPath(sharedPath);\r\n                }\r\n            }\r\n\r\n            string path = Path.Combine(DirectDependencyPath, name);\r\n            if (File.Exists(path))\r\n            {\r\n                return WinGetAcl.LoadFromAssemblyName(assemblyName);\r\n            }\r\n\r\n            return null;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Handler to resolve unmanaged assemblies.\r\n        /// </summary>\r\n        /// <param name=\"assembly\">Assembly initiating the unmanaged load.</param>\r\n        /// <param name=\"unmanagedDllName\">Unmanaged dll name.</param>\r\n        /// <returns>The assembly ptr, zero if not in our assembly location.</returns>\r\n        internal static IntPtr ResolvingUnmanagedDllHandler(Assembly assembly, string unmanagedDllName)\r\n        {\r\n            return WinGetAcl.LoadUnmanagedDll(unmanagedDllName);\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        protected override Assembly Load(AssemblyName assemblyName)\r\n        {\r\n            string name = $\"{assemblyName.Name}.dll\";\r\n            if (DefaultContextAssemblies.Any(a => a.Equals(name, StringComparison.OrdinalIgnoreCase)))\r\n            {\r\n                return null;\r\n            }\r\n\r\n            string path = Path.Combine(SharedDependencyPath, name);\r\n            if (File.Exists(path))\r\n            {\r\n                return this.LoadFromAssemblyPath(path);\r\n            }\r\n\r\n            path = Path.Combine(SharedArchDependencyPath, name);\r\n            if (File.Exists(path))\r\n            {\r\n                return this.LoadFromAssemblyPath(path);\r\n            }\r\n\r\n            path = Path.Combine(DirectDependencyPath, name);\r\n            if (File.Exists(path))\r\n            {\r\n                return this.LoadFromAssemblyPath(path);\r\n            }\r\n\r\n            return null;\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)\r\n        {\r\n            string path = Path.Combine(SharedArchDependencyPath, unmanagedDllName);\r\n            if (File.Exists(path))\r\n            {\r\n                return this.LoadUnmanagedDllFromPath(path);\r\n            }\r\n\r\n            return IntPtr.Zero;\r\n        }\r\n    }\r\n}\r\n#endif\r\n"
  },
  {
    "path": "src/PowerShell/ExternalModules/PackageManagement/1.4.8.1/DSCResources/MSFT_PackageManagement/MSFT_PackageManagement.psm1",
    "content": "#\r\n# Copyright (c) Microsoft Corporation.\r\n#\r\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n# THE SOFTWARE.\r\n#\r\n# This PS DSC resource enables installing a package. The resource uses Install-Package cmdlet\r\n# to install the package from various providers/sources.\r\n\r\nImport-LocalizedData -BindingVariable LocalizedData -filename MSFT_PackageManagement.strings.psd1\r\n\r\nImport-Module -Name \"$PSScriptRoot\\..\\PackageManagementDscUtilities.psm1\"\r\n\r\nfunction Get-TargetResource\r\n{\r\n    <#\r\n    .SYNOPSIS\r\n\r\n    This DSC resource provides a mechanism to download and install packages on a computer. \r\n\r\n    Get-TargetResource returns the current state of the resource.\r\n\r\n    .PARAMETER Name\r\n    Specifies the name of the Package to be installed or uninstalled.\r\n\r\n    .PARAMETER Source\r\n    Specifies the name of the package source where the package can be found.\r\n    This can either be a URI or a source registered with Register-PackageSource cmdlet.\r\n    The DSC resource MSFT_PackageManagementSource can also register a package source.\r\n    \r\n    .PARAMETER RequiredVersion\r\n    Specifies the exact version of the package that you want to install. If you do not specify this parameter, \r\n    this DSC resource installs the newest available version of the package that also satisfies any\r\n    maximum version specified by the MaximumVersion parameter.\r\n\r\n    .PARAMETER MaximumVersion\r\n    Specifies the maximum allowed version of the package that you want to install. If you do not specify this parameter, \r\n    this DSC resource installs the highest-numbered available version of the package.\r\n\r\n    .PARAMETER MinimumVersion\r\n    Specifies the minimum allowed version of the package that you want to install. If you do not add this parameter, \r\n    this DSC resource intalls the highest available version of the package that also satisfies any maximum \r\n    specified version specified by the MaximumVersion parameter.\r\n\r\n    .PARAMETER SourceCredential\r\n    Specifies a user account that has rights to install a package for a specified package provider or source.\r\n\r\n    .PARAMETER ProviderName\r\n    Specifies a package provider name to which to scope your package search. You can get package provider names \r\n    by running the Get-PackageProvider cmdlet.\r\n\r\n    .PARAMETER AdditionalParameters\r\n    Provider specific parameters that are passed as an Hashtable. For example, for NuGet provider you can\r\n    pass additional parameters like DestinationPath.\r\n    #>\r\n\r\n    [CmdletBinding()]\r\n    [OutputType([System.Collections.Hashtable])]\r\n    param\r\n    (\r\n        [Parameter(Mandatory = $true)]\r\n        [System.String]\r\n        $Name,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $RequiredVersion,\r\n        \r\n        [Parameter()]\r\n        [System.String]\r\n        $MinimumVersion,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $MaximumVersion,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $Source,\r\n\r\n        [Parameter()]\r\n        [PSCredential] $SourceCredential,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $ProviderName,\r\n        \r\n        [Parameter()]\r\n        [Microsoft.Management.Infrastructure.CimInstance[]]$AdditionalParameters        \r\n    )\r\n    \r\n    $ensure = \"Absent\"\r\n    $null = $PSBoundParameters.Remove(\"Source\")\r\n    $null = $PSBoundParameters.Remove(\"SourceCredential\")\r\n\r\n    if ($AdditionalParameters)\r\n    {\r\n         foreach($instance in $AdditionalParameters)\r\n         {\r\n             Write-Verbose ('AdditionalParameter: {0}, AdditionalParameterValue: {1}' -f $instance.Key, $instance.Value)\r\n             $null = $PSBoundParameters.Add($instance.Key, $instance.Value)\r\n         }\r\n    }\r\n    $null = $PSBoundParameters.Remove(\"AdditionalParameters\")\r\n    \r\n    $verboseMessage =$localizedData.StartGetPackage -f (GetMessageFromParameterDictionary $PSBoundParameters),$env:PSModulePath\r\n    Write-Verbose -Message $verboseMessage\r\n    $result = PackageManagement\\Get-Package @PSBoundParameters -ErrorAction SilentlyContinue -WarningAction SilentlyContinue\r\n        \r\n\r\n    if ($result.count -eq 1)\r\n    {\r\n        Write-Verbose -Message ($localizedData.PackageFound -f $Name)\r\n        $ensure = \"Present\"\r\n    }\r\n    elseif ($result.count -gt 1)\r\n    {\r\n        Write-Verbose -Message ($localizedData.MultiplePackagesFound -f $Name)\r\n        $ensure = \"Present\"\r\n    }\r\n    else\r\n    {\r\n        Write-Verbose -Message ($localizedData.PackageNotFound -f $($Name))\r\n    }\r\n\r\n    Write-Debug -Message \"Source $($Name) is $($ensure)\"\r\n                         \r\n    \r\n    if ($ensure -eq 'Absent')\r\n    {\r\n        return @{\r\n            Ensure       = $ensure\r\n            Name         = $Name\r\n            ProviderName = $ProviderName\r\n            RequiredVersion = $RequiredVersion\r\n            MinimumVersion = $MinimumVersion\r\n            MaximumVersion = $MaximumVersion\r\n        }\r\n    }\r\n    else\r\n    {\r\n        if ($result.Count -gt 1)\r\n        {\r\n          $result = $result[0]\r\n        }\r\n\r\n        return  @{\r\n                Ensure             = $ensure\r\n                Name               = $result.Name\r\n                ProviderName       = $result.ProviderName\r\n                Source             = $result.source\r\n                RequiredVersion    = $result.Version\r\n            } \r\n    } \r\n}\r\n\r\nfunction Test-TargetResource\r\n{\r\n    <#\r\n    .SYNOPSIS\r\n\r\n    This DSC resource provides a mechanism to download and install packages on a computer. \r\n\r\n    Test-TargetResource returns a boolean which determines whether the resource is in\r\n    desired state or not.\r\n\r\n    .PARAMETER Name\r\n    Specifies the name of the Package to be installed or uninstalled.\r\n\r\n    .PARAMETER Source\r\n    Specifies the name of the package source where the package can be found.\r\n    This can either be a URI or a source registered with Register-PackageSource cmdlet.\r\n    The DSC resource MSFT_PackageManagementSource can also register a package source.\r\n    \r\n    .PARAMETER RequiredVersion\r\n    Specifies the exact version of the package that you want to install. If you do not specify this parameter, \r\n    this DSC resource installs the newest available version of the package that also satisfies any\r\n    maximum version specified by the MaximumVersion parameter.\r\n\r\n    .PARAMETER MaximumVersion\r\n    Specifies the maximum allowed version of the package that you want to install. If you do not specify this parameter, \r\n    this DSC resource installs the highest-numbered available version of the package.\r\n\r\n    .PARAMETER MinimumVersion\r\n    Specifies the minimum allowed version of the package that you want to install. If you do not add this parameter, \r\n    this DSC resource intalls the highest available version of the package that also satisfies any maximum \r\n    specified version specified by the MaximumVersion parameter.\r\n\r\n    .PARAMETER SourceCredential\r\n    Specifies a user account that has rights to install a package for a specified package provider or source.\r\n\r\n    .PARAMETER ProviderName\r\n    Specifies a package provider name to which to scope your package search. You can get package provider names \r\n    by running the Get-PackageProvider cmdlet.\r\n\r\n    .PARAMETER AdditionalParameters\r\n    Provider specific parameters that are passed as an Hashtable. For example, for NuGet provider you can\r\n    pass additional parameters like DestinationPath.\r\n    #>\r\n\r\n    [CmdletBinding()]\r\n    [OutputType([bool])]\r\n    param\r\n    (\r\n        [Parameter(Mandatory = $true)]\r\n        [System.String]\r\n        $Name,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $RequiredVersion,\r\n        \r\n        [Parameter()]\r\n        [System.String]\r\n        $MinimumVersion,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $MaximumVersion,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $Source,\r\n\r\n        [Parameter()]\r\n        [PSCredential] $SourceCredential,\r\n                \r\n        [ValidateSet(\"Present\",\"Absent\")]\r\n        [System.String]\r\n        $Ensure=\"Present\",\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $ProviderName,\r\n        \r\n        [Parameter()]\r\n        [Microsoft.Management.Infrastructure.CimInstance[]]$AdditionalParameters         \r\n    )\r\n\r\n    \r\n    Write-Verbose -Message ($localizedData.StartTestPackage -f (GetMessageFromParameterDictionary $PSBoundParameters))\r\n    $null = $PSBoundParameters.Remove(\"Ensure\")\r\n    \r\n    $temp = Get-TargetResource @PSBoundParameters\r\n\r\n    if ($temp.Ensure -eq $ensure)\r\n    {\r\n        Write-Verbose -Message ($localizedData.InDesiredState -f $Name, $Ensure, $temp.Ensure)            \r\n        return $True \r\n    }\r\n    else\r\n    {\r\n        Write-Verbose -Message ($localizedData.NotInDesiredState -f $Name,$ensure,$temp.ensure)            \r\n        return [bool] $False\r\n    }    \r\n}\r\n\r\nfunction Set-TargetResource\r\n{\r\n    <#\r\n    .SYNOPSIS\r\n\r\n    This DSC resource provides a mechanism to download and install packages on a computer. \r\n\r\n    Set-TargetResource either intalls or uninstall a package as defined by the vaule of Ensure parameter.\r\n\r\n    .PARAMETER Name\r\n    Specifies the name of the Package to be installed or uninstalled.\r\n\r\n    .PARAMETER Source\r\n    Specifies the name of the package source where the package can be found.\r\n    This can either be a URI or a source registered with Register-PackageSource cmdlet.\r\n    The DSC resource MSFT_PackageManagementSource can also register a package source.\r\n    \r\n    .PARAMETER RequiredVersion\r\n    Specifies the exact version of the package that you want to install. If you do not specify this parameter, \r\n    this DSC resource installs the newest available version of the package that also satisfies any\r\n    maximum version specified by the MaximumVersion parameter.\r\n\r\n    .PARAMETER MaximumVersion\r\n    Specifies the maximum allowed version of the package that you want to install. If you do not specify this parameter, \r\n    this DSC resource installs the highest-numbered available version of the package.\r\n\r\n    .PARAMETER MinimumVersion\r\n    Specifies the minimum allowed version of the package that you want to install. If you do not add this parameter, \r\n    this DSC resource intalls the highest available version of the package that also satisfies any maximum \r\n    specified version specified by the MaximumVersion parameter.\r\n\r\n    .PARAMETER SourceCredential\r\n    Specifies a user account that has rights to install a package for a specified package provider or source.\r\n\r\n    .PARAMETER ProviderName\r\n    Specifies a package provider name to which to scope your package search. You can get package provider names \r\n    by running the Get-PackageProvider cmdlet.\r\n\r\n    .PARAMETER AdditionalParameters\r\n    Provider specific parameters that are passed as an Hashtable. For example, for NuGet provider you can\r\n    pass additional parameters like DestinationPath.\r\n    #>\r\n\r\n    [CmdletBinding()]\r\n    param\r\n    (\r\n        [Parameter(Mandatory = $true)]\r\n        [System.String]\r\n        $Name,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $RequiredVersion,\r\n        \r\n        [Parameter()]\r\n        [System.String]\r\n        $MinimumVersion,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $MaximumVersion,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $Source,\r\n\r\n        [Parameter()]\r\n        [PSCredential] $SourceCredential,\r\n\r\n        [ValidateSet(\"Present\",\"Absent\")]\r\n        [System.String]\r\n        $Ensure=\"Present\",\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $ProviderName,\r\n        \r\n        [Parameter()]\r\n        [Microsoft.Management.Infrastructure.CimInstance[]]$AdditionalParameters        \r\n    )\r\n\r\n    Write-Verbose -Message ($localizedData.StartSetPackage -f (GetMessageFromParameterDictionary $PSBoundParameters))\r\n    \r\n    $null = $PSBoundParameters.Remove(\"Ensure\")\r\n\r\n    if ($PSBoundParameters.ContainsKey(\"SourceCredential\"))\r\n    {\r\n        $PSBoundParameters.Add(\"Credential\", $SourceCredential)\r\n        $null = $PSBoundParameters.Remove(\"SourceCredential\")\r\n    }\r\n    \r\n    if ($AdditionalParameters)\r\n    {\r\n         foreach($instance in $AdditionalParameters)\r\n         {\r\n             Write-Verbose ('AdditionalParameter: {0}, AdditionalParameterValue: {1}' -f $instance.Key, $instance.Value)\r\n             $null = $PSBoundParameters.Add($instance.Key, $instance.Value)\r\n         }\r\n    }\r\n\r\n    $PSBoundParameters.Remove(\"AdditionalParameters\")\r\n\r\n       \r\n        # We do not want others to control the behavior of ErrorAction\r\n        # while calling Install-Package/Uninstall-Package.\r\n        $PSBoundParameters.Remove(\"ErrorAction\")\r\n        if ($Ensure -eq \"Present\")\r\n        {\r\n            PackageManagement\\Install-Package @PSBoundParameters -ErrorAction Stop\r\n        }   \r\n        else\r\n        {\r\n            # we dont source location for uninstalling an already\r\n            # installed package\r\n            $PSBoundParameters.Remove(\"Source\")\r\n            # Ensure is Absent\r\n            PackageManagement\\Uninstall-Package @PSBoundParameters -ErrorAction Stop\r\n        }\r\n }\r\n \r\n function GetMessageFromParameterDictionary\r\n {\r\n    <#\r\n        Returns a strng of form \"ParameterName:ParameterValue\"\r\n        Used with Write-Verbose message. The input is mostly $PSBoundParameters\r\n    #>\r\n    param([System.Collections.IDictionary] $paramDictionary)\r\n\r\n    $returnValue = \"\"\r\n    $paramDictionary.Keys | ForEach-Object { $returnValue += \"-{0} {1} \" -f $_,$paramDictionary[$_] }\r\n    return $returnValue\r\n }\r\n\r\nExport-ModuleMember -function Get-TargetResource, Set-TargetResource, Test-TargetResource\r\n\r\n\r\n# SIG # Begin signature block\r\n# MIInoQYJKoZIhvcNAQcCoIInkjCCJ44CAQExDzANBglghkgBZQMEAgEFADB5Bgor\r\n# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG\r\n# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBNHExVsaD0kyJT\r\n# faO9Fdru5c5dZNw/I2f/WOIZwqnZQKCCDYEwggX/MIID56ADAgECAhMzAAACUosz\r\n# qviV8znbAAAAAAJSMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD\r\n# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p\r\n# bmcgUENBIDIwMTEwHhcNMjEwOTAyMTgzMjU5WhcNMjIwOTAxMTgzMjU5WjB0MQsw\r\n# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u\r\n# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\r\n# AQDQ5M+Ps/X7BNuv5B/0I6uoDwj0NJOo1KrVQqO7ggRXccklyTrWL4xMShjIou2I\r\n# sbYnF67wXzVAq5Om4oe+LfzSDOzjcb6ms00gBo0OQaqwQ1BijyJ7NvDf80I1fW9O\r\n# L76Kt0Wpc2zrGhzcHdb7upPrvxvSNNUvxK3sgw7YTt31410vpEp8yfBEl/hd8ZzA\r\n# v47DCgJ5j1zm295s1RVZHNp6MoiQFVOECm4AwK2l28i+YER1JO4IplTH44uvzX9o\r\n# RnJHaMvWzZEpozPy4jNO2DDqbcNs4zh7AWMhE1PWFVA+CHI/En5nASvCvLmuR/t8\r\n# q4bc8XR8QIZJQSp+2U6m2ldNAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE\r\n# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUNZJaEUGL2Guwt7ZOAu4efEYXedEw\r\n# UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1\r\n# ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDY3NTk3MB8GA1UdIwQYMBaAFEhu\r\n# ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu\r\n# bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w\r\n# Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3\r\n# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx\r\n# MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAFkk3\r\n# uSxkTEBh1NtAl7BivIEsAWdgX1qZ+EdZMYbQKasY6IhSLXRMxF1B3OKdR9K/kccp\r\n# kvNcGl8D7YyYS4mhCUMBR+VLrg3f8PUj38A9V5aiY2/Jok7WZFOAmjPRNNGnyeg7\r\n# l0lTiThFqE+2aOs6+heegqAdelGgNJKRHLWRuhGKuLIw5lkgx9Ky+QvZrn/Ddi8u\r\n# TIgWKp+MGG8xY6PBvvjgt9jQShlnPrZ3UY8Bvwy6rynhXBaV0V0TTL0gEx7eh/K1\r\n# o8Miaru6s/7FyqOLeUS4vTHh9TgBL5DtxCYurXbSBVtL1Fj44+Od/6cmC9mmvrti\r\n# yG709Y3Rd3YdJj2f3GJq7Y7KdWq0QYhatKhBeg4fxjhg0yut2g6aM1mxjNPrE48z\r\n# 6HWCNGu9gMK5ZudldRw4a45Z06Aoktof0CqOyTErvq0YjoE4Xpa0+87T/PVUXNqf\r\n# 7Y+qSU7+9LtLQuMYR4w3cSPjuNusvLf9gBnch5RqM7kaDtYWDgLyB42EfsxeMqwK\r\n# WwA+TVi0HrWRqfSx2olbE56hJcEkMjOSKz3sRuupFCX3UroyYf52L+2iVTrda8XW\r\n# esPG62Mnn3T8AuLfzeJFuAbfOSERx7IFZO92UPoXE1uEjL5skl1yTZB3MubgOA4F\r\n# 8KoRNhviFAEST+nG8c8uIsbZeb08SeYQMqjVEmkwggd6MIIFYqADAgECAgphDpDS\r\n# AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK\r\n# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0\r\n# IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0\r\n# ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla\r\n# MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS\r\n# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT\r\n# H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB\r\n# AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG\r\n# OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S\r\n# 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz\r\n# y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7\r\n# 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u\r\n# M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33\r\n# X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl\r\n# XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP\r\n# 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB\r\n# l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF\r\n# RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM\r\n# CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ\r\n# BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud\r\n# DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO\r\n# 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0\r\n# LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p\r\n# Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB\r\n# FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw\r\n# cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA\r\n# XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY\r\n# 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj\r\n# 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd\r\n# d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ\r\n# Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf\r\n# wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ\r\n# aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j\r\n# NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B\r\n# xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96\r\n# eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7\r\n# r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I\r\n# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIZdjCCGXICAQEwgZUwfjELMAkG\r\n# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx\r\n# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z\r\n# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAlKLM6r4lfM52wAAAAACUjAN\r\n# BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor\r\n# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQg8R1Pmfow\r\n# cdRZqYArE66BbwlcVzLXx5t2tD5hSPvyDEowQgYKKwYBBAGCNwIBDDE0MDKgFIAS\r\n# AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN\r\n# BgkqhkiG9w0BAQEFAASCAQAeXps4tjAFtlAdjZLwORhr3TtESrcKHZnVBHZ0zYbM\r\n# unaWRYc0OysS4qo+BomxtH9p6wL8QAOILHlQvCYdMoEI2jbAbBzb61wFHb8g2qeX\r\n# l5dLpSgZnOU+Ej+r2EieXi4DSYANTCOsEVnHWa+9tYZ1qZYB7dDysy0hMJ9F0lpI\r\n# FLhooei9J7aB5z1sSUEpBqoEgSn/+unhSlHMTasmYyzxBsb+KoFbwzavZPFluy5R\r\n# HmWt7m0HSfkzScoYM0CUpnCRAyQELq/ubtCIbxbDfddl4JGJToAABc3akuXY9WDc\r\n# 2MdT2gqPPX0+Acp861u/hlYfiZipnoE0K3cSZ6WJH2JvoYIXADCCFvwGCisGAQQB\r\n# gjcDAwExghbsMIIW6AYJKoZIhvcNAQcCoIIW2TCCFtUCAQMxDzANBglghkgBZQME\r\n# AgEFADCCAVEGCyqGSIb3DQEJEAEEoIIBQASCATwwggE4AgEBBgorBgEEAYRZCgMB\r\n# MDEwDQYJYIZIAWUDBAIBBQAEICEiVK6WSVgxKzH21qRCzrs8poUE/CmvuRL5UN+N\r\n# A1gpAgZitMncVAUYEzIwMjIwNzAxMjEwMDAwLjM2NVowBIACAfSggdCkgc0wgcox\r\n# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt\r\n# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1p\r\n# Y3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJjAkBgNVBAsTHVRoYWxlcyBUU1Mg\r\n# RVNOOjIyNjQtRTMzRS03ODBDMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFt\r\n# cCBTZXJ2aWNloIIRVzCCBwwwggT0oAMCAQICEzMAAAGYdrOMxdAFoQEAAQAAAZgw\r\n# DQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0\r\n# b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh\r\n# dGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwHhcN\r\n# MjExMjAyMTkwNTE1WhcNMjMwMjI4MTkwNTE1WjCByjELMAkGA1UEBhMCVVMxEzAR\r\n# BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p\r\n# Y3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2Eg\r\n# T3BlcmF0aW9uczEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046MjI2NC1FMzNFLTc4\r\n# MEMxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggIiMA0G\r\n# CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDG1JWsVksp8xG4sLMnfxfit3ShI+7G\r\n# 1MfTT+5XvQzuAOe8r5MRAFITTmjFxzoLFfmaxLvPVlmDgkDi0rqsOs9Al9jVwYSF\r\n# VF/wWC2+B76OysiyRjw+NPj5A4cmMhPqIdNkRLCE+wtuI/wCaq3/Lf4koDGudIcE\r\n# YRgMqqToOOUIV4e7EdYb3k9rYPN7SslwsLFSp+Fvm/Qcy5KqfkmMX4S3oJx7HdiQ\r\n# hKbK1C6Zfib+761bmrdPLT6eddlnywls7hCrIIuFtgUbUj6KJIZn1MbYY8hrAM59\r\n# tvLpeGmFW3GjeBAmvBxAn7o9Lp2nykT1w9I0s9ddwpFnjLT2PK74GDSsxFUZG1Ut\r\n# Lypi/kZcg9WenPAZpUtPFfO5Mtif8Ja8jXXLIP6K+b5LiQV8oIxFSBfgFN7/TL2t\r\n# SSfQVcvqX1mcSOrx/tsgq3L6YAxI6Pl4h1zQrcAmToypEoPYNc/RlSBk6ljmNyND\r\n# sX3gtK8p6c7HCWUhF+YjMgfanQmMjUYsbjdEsCyL6QAojZ0f6kteN4cV6obFwcUE\r\n# viYygWbedaT86OGe9LEOxPuhzgFv2ZobVr0J8hl1FVdcZFbfFN/gdjHZ/ncDDqLN\r\n# WgcoMoEhwwzo7FAObqKaxfB5zCBqYSj45miNO5g3hP8AgC0eSCHl3rK7JPMr1B+8\r\n# JTHtwRkSKz/+cwIDAQABo4IBNjCCATIwHQYDVR0OBBYEFG6RhHKNpsg3mgons7LR\r\n# 5YHTzeE3MB8GA1UdIwQYMBaAFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMF8GA1UdHwRY\r\n# MFYwVKBSoFCGTmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01p\r\n# Y3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNybDBsBggrBgEF\r\n# BQcBAQRgMF4wXAYIKwYBBQUHMAKGUGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9w\r\n# a2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAo\r\n# MSkuY3J0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwgwDQYJKoZI\r\n# hvcNAQELBQADggIBACT6B6F33i/89zXTgqQ8L6CYMHx9BiaHOV+wk53JOriCzeaL\r\n# jYgRyssJhmnnJ/CdHa5qjcSwvRptWpZJPVK5sxhOIjRBPgs/3+ER0vS87IA+aGbf\r\n# 7NF7LZZlxWPOl/yFBg9qZ3tpOGOohQInQn5zpV23hWopaN4c49jGJHLPAfy9u7+Z\r\n# SGQuw14CsW/XRLELHT18I60W0uKOBa5Pm2ViohMovcbpNUCEERqIO9WPwzIwMRRw\r\n# 34/LgjuslHJop+/1Ve/CfyNqweUmwepQHJrd+wTLUlgm4ENbXF6i52jFfYpESwLd\r\n# An56o/pj+grsd2LrAEPQRyh49rWvI/qZfOhtT2FWmzFw6IJvZ7CzT1O+Fc0gIDBN\r\n# qass5QbmkOkKYy9U7nFA6qn3ZZ+MrZMsJTj7gxAf0yMkVqwYWZRk4brY9q8JDPmc\r\n# fNSjRrVfpYyzEVEqemGanmxvDDTzS2wkSBa3zcNwOgYhWBTmJdLgyiWJGeqyj1m5\r\n# bwNgnOw6NzXCiVMzfbztdkqOdTR88LtAJGNRjevWjQd5XitGuegSp2mMJglFzRwk\r\n# ncQau1BJsCj/1aDY4oMiO8conkmaWBrYe11QCS896/sZwSdnEUJak0qpnBRFB+TH\r\n# RIxIivCKNbxG2QRZ8dh95cOXgo0YvBN5a1p+iJ3vNwzneU2AIC7z3rrIbN2fMIIH\r\n# cTCCBVmgAwIBAgITMwAAABXF52ueAptJmQAAAAAAFTANBgkqhkiG9w0BAQsFADCB\r\n# iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl\r\n# ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMp\r\n# TWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMjEw\r\n# OTMwMTgyMjI1WhcNMzAwOTMwMTgzMjI1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UE\r\n# CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z\r\n# b2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQ\r\n# Q0EgMjAxMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOThpkzntHIh\r\n# C3miy9ckeb0O1YLT/e6cBwfSqWxOdcjKNVf2AX9sSuDivbk+F2Az/1xPx2b3lVNx\r\n# WuJ+Slr+uDZnhUYjDLWNE893MsAQGOhgfWpSg0S3po5GawcU88V29YZQ3MFEyHFc\r\n# UTE3oAo4bo3t1w/YJlN8OWECesSq/XJprx2rrPY2vjUmZNqYO7oaezOtgFt+jBAc\r\n# nVL+tuhiJdxqD89d9P6OU8/W7IVWTe/dvI2k45GPsjksUZzpcGkNyjYtcI4xyDUo\r\n# veO0hyTD4MmPfrVUj9z6BVWYbWg7mka97aSueik3rMvrg0XnRm7KMtXAhjBcTyzi\r\n# YrLNueKNiOSWrAFKu75xqRdbZ2De+JKRHh09/SDPc31BmkZ1zcRfNN0Sidb9pSB9\r\n# fvzZnkXftnIv231fgLrbqn427DZM9ituqBJR6L8FA6PRc6ZNN3SUHDSCD/AQ8rdH\r\n# GO2n6Jl8P0zbr17C89XYcz1DTsEzOUyOArxCaC4Q6oRRRuLRvWoYWmEBc8pnol7X\r\n# KHYC4jMYctenIPDC+hIK12NvDMk2ZItboKaDIV1fMHSRlJTYuVD5C4lh8zYGNRiE\r\n# R9vcG9H9stQcxWv2XFJRXRLbJbqvUAV6bMURHXLvjflSxIUXk8A8FdsaN8cIFRg/\r\n# eKtFtvUeh17aj54WcmnGrnu3tz5q4i6tAgMBAAGjggHdMIIB2TASBgkrBgEEAYI3\r\n# FQEEBQIDAQABMCMGCSsGAQQBgjcVAgQWBBQqp1L+ZMSavoKRPEY1Kc8Q/y8E7jAd\r\n# BgNVHQ4EFgQUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXAYDVR0gBFUwUzBRBgwrBgEE\r\n# AYI3TIN9AQEwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29t\r\n# L3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMBMGA1UdJQQMMAoGCCsGAQUFBwMI\r\n# MBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMB\r\n# Af8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fOmhjEMFYGA1Ud\r\n# HwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3By\r\n# b2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggrBgEFBQcBAQRO\r\n# MEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2Vy\r\n# dHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MA0GCSqGSIb3DQEBCwUAA4IC\r\n# AQCdVX38Kq3hLB9nATEkW+Geckv8qW/qXBS2Pk5HZHixBpOXPTEztTnXwnE2P9pk\r\n# bHzQdTltuw8x5MKP+2zRoZQYIu7pZmc6U03dmLq2HnjYNi6cqYJWAAOwBb6J6Gng\r\n# ugnue99qb74py27YP0h1AdkY3m2CDPVtI1TkeFN1JFe53Z/zjj3G82jfZfakVqr3\r\n# lbYoVSfQJL1AoL8ZthISEV09J+BAljis9/kpicO8F7BUhUKz/AyeixmJ5/ALaoHC\r\n# gRlCGVJ1ijbCHcNhcy4sa3tuPywJeBTpkbKpW99Jo3QMvOyRgNI95ko+ZjtPu4b6\r\n# MhrZlvSP9pEB9s7GdP32THJvEKt1MMU0sHrYUP4KWN1APMdUbZ1jdEgssU5HLcEU\r\n# BHG/ZPkkvnNtyo4JvbMBV0lUZNlz138eW0QBjloZkWsNn6Qo3GcZKCS6OEuabvsh\r\n# VGtqRRFHqfG3rsjoiV5PndLQTHa1V1QJsWkBRH58oWFsc/4Ku+xBZj1p/cvBQUl+\r\n# fpO+y/g75LcVv7TOPqUxUYS8vwLBgqJ7Fx0ViY1w/ue10CgaiQuPNtq6TPmb/wrp\r\n# NPgkNWcr4A245oyZ1uEi6vAnQj0llOZ0dFtq0Z4+7X6gMTN9vMvpe784cETRkPHI\r\n# qzqKOghif9lwY1NNje6CbaUFEMFxBmoQtB1VM1izoXBm8qGCAs4wggI3AgEBMIH4\r\n# oYHQpIHNMIHKMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G\r\n# A1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUw\r\n# IwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMSYwJAYDVQQLEx1U\r\n# aGFsZXMgVFNTIEVTTjoyMjY0LUUzM0UtNzgwQzElMCMGA1UEAxMcTWljcm9zb2Z0\r\n# IFRpbWUtU3RhbXAgU2VydmljZaIjCgEBMAcGBSsOAwIaAxUA8ywe/iF5M8fIU2aT\r\n# 6yQ3vnPpV5OggYMwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu\r\n# Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv\r\n# cmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAN\r\n# BgkqhkiG9w0BAQUFAAIFAOZp1AIwIhgPMjAyMjA3MDIwNDEzNTRaGA8yMDIyMDcw\r\n# MzA0MTM1NFowdzA9BgorBgEEAYRZCgQBMS8wLTAKAgUA5mnUAgIBADAKAgEAAgIN\r\n# NAIB/zAHAgEAAgIRtDAKAgUA5mslggIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgor\r\n# BgEEAYRZCgMCoAowCAIBAAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUA\r\n# A4GBAIcnMC784m6T/edBW3cq9r/yFVNA0QEvStf82Kw/R7tlaHDt097cO2b04KMC\r\n# V009JquDovHm5hKa95HNl/EcSVOy0XSzCkkFRCFfHvQyCepHU+f2lAfJkKPfQoBH\r\n# UYXvMMVFDB2X/i6sM5rB50pw+es9vpAGic/VoX7HQkPz/x74MYIEDTCCBAkCAQEw\r\n# gZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT\r\n# B1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UE\r\n# AxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAGYdrOMxdAFoQEA\r\n# AQAAAZgwDQYJYIZIAWUDBAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0B\r\n# CRABBDAvBgkqhkiG9w0BCQQxIgQgPSBQh4cqea+akWI4bmlSCCKf/KlFhtOwg6A6\r\n# 6ghYSTQwgfoGCyqGSIb3DQEJEAIvMYHqMIHnMIHkMIG9BCC/ps4GOTn/9wO1NhHM\r\n# 9Qfe0loB3slkw1FF3r+bh21WxDCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYD\r\n# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1w\r\n# IFBDQSAyMDEwAhMzAAABmHazjMXQBaEBAAEAAAGYMCIEIES78xtiuDaV9ywXzTl8\r\n# XWUH8mqeO6XZWBLLhxayXSClMA0GCSqGSIb3DQEBCwUABIICAJXsTUtHPNUMQu1x\r\n# h6OSxx18cwjD6ncubNtd0T2LpuIaJ6P+Dog/ZNDl2qUBHPn6UvCdrCQSVXxWyVKj\r\n# bsPvxf7gLJPmCOlCgQ+F4ocGoMx759e0H9NWGUD1OczeBEkcVtwycN4ZboslQbiP\r\n# W32gbaZFOaujV+Xigrl4OtIebOZXH47ys+B8rSHX+sb2wejdUy5UyUexiLg6t1Jj\r\n# Y253gM9vW5GqRpseJwAZ7gukmjvEjeCpC16l2hNi++vo8ktAkduWDsz6RbDBqqz+\r\n# g9FjOkAPZ//+eA0BGHrOwn2Piw8UCSl48hInvC/hqvS67T2ysb+nTy/Wn2BUHdaa\r\n# 6bfaGh0nqclQjWjkRfcxPxk1b61mYErRaBmqZvgrQK/FiFA/TYt1vegvpDKrz2Ey\r\n# /hKY2GaAKlDE2fjRRvUgzVXw7j9ZbJfmrTC/QzXvnfYyAGvdj5M93DwmOWL4rfRH\r\n# QDQVxegfmlrolnZUE5BirFk4mdZT7mihghMO8POWpo2oG5ehqasflzQNaXyq97w7\r\n# tLe78SK0CBIqDuEbOVznD1/wDCLha0iYwKmBHmhk5ElB36whfabC6PvHS5jndpSa\r\n# STUZG+2PcqUTGR3CVrZOVarkLXshyHgDSJfkS5aCW4GPDsqWmhznCoIZWDdlkak1\r\n# vE5R3wCfHoZ7HLzzkdvfZlIhuwOn\r\n# SIG # End signature block\r\n"
  },
  {
    "path": "src/PowerShell/ExternalModules/PackageManagement/1.4.8.1/DSCResources/PackageManagementDscUtilities.psm1",
    "content": "#\r\n# Copyright (c) Microsoft Corporation.\r\n#\r\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n# THE SOFTWARE.\r\n#\r\n#Helper functions for PackageManagement DSC Resouces\r\n\r\nImport-LocalizedData -BindingVariable LocalizedData -filename PackageManagementDscUtilities.strings.psd1\r\n\r\n\r\n Function ExtractArguments\r\n{\r\n    <#\r\n    .SYNOPSIS\r\n\r\n    This is a helper function that extract the parameters from a given table. \r\n\r\n    .PARAMETER FunctionBoundParameters\r\n    Specifies the hashtable containing a set of parameters to be extracted\r\n\r\n    .PARAMETER ArgumentNames\r\n    Specifies A list of arguments you want to extract\r\n    #>\r\n\r\n    Param\r\n    (\r\n        [parameter(Mandatory = $true)]\r\n        [System.Collections.Hashtable]\r\n        $FunctionBoundParameters,\r\n\r\n        #A list of arguments you want to extract\r\n        [parameter(Mandatory = $true)]\r\n        [System.String[]]$ArgumentNames\r\n    )\r\n\r\n    Write-Verbose -Message ($LocalizedData.CallingFunction -f $($MyInvocation.mycommand))\r\n\r\n    $returnValue=@{}\r\n\r\n    foreach ($arg in $ArgumentNames)\r\n    {\r\n        if($FunctionBoundParameters.ContainsKey($arg))\r\n        {\r\n            #Found an argument we are looking for, so we add it to return collection\r\n            $returnValue.Add($arg,$FunctionBoundParameters[$arg])\r\n        }\r\n    }\r\n\r\n    return $returnValue\r\n }\r\n\r\nfunction ThrowError\r\n{\r\n    <#\r\n    .SYNOPSIS\r\n\r\n    This is a helper function that throws an error. \r\n\r\n    .PARAMETER ExceptionName\r\n    Specifies the type of errors, e.g. System.ArgumentException\r\n\r\n    .PARAMETER ExceptionMessage\r\n    Specifies the exception message\r\n\r\n    .PARAMETER ErrorId\r\n    Specifies an identifier of the error\r\n\r\n    .PARAMETER ErrorCategory\r\n    Specifies the error category, e.g., InvalidArgument defined in System.Management.Automation. \r\n\r\n    #>\r\n\r\n    param\r\n    (        \r\n        [parameter(Mandatory = $true)]\r\n        [ValidateNotNullOrEmpty()]\r\n        [System.String]        \r\n        $ExceptionName,\r\n\r\n        [parameter(Mandatory = $true)]\r\n        [ValidateNotNullOrEmpty()]\r\n        [System.String]\r\n        $ExceptionMessage,      \r\n        \r\n        [parameter(Mandatory = $true)]\r\n        [ValidateNotNullOrEmpty()]\r\n        [System.String]\r\n        $ErrorId,\r\n\r\n        [parameter(Mandatory = $true)]\r\n        [ValidateNotNull()]\r\n        [System.Management.Automation.ErrorCategory]\r\n        $ErrorCategory\r\n    )\r\n    \r\n    Write-Verbose -Message ($LocalizedData.CallingFunction -f $($MyInvocation.mycommand))\r\n        \r\n    $exception   = New-Object -TypeName $ExceptionName -ArgumentList $ExceptionMessage;\r\n    $errorRecord = New-Object -TypeName System.Management.Automation.ErrorRecord -ArgumentList ($exception, $ErrorId, $ErrorCategory, $null)    \r\n    throw $errorRecord\r\n}\r\n\r\nFunction ValidateArgument\r\n{\r\n    <#\r\n    .SYNOPSIS\r\n\r\n    This is a helper function that validates the arguments. \r\n\r\n    .PARAMETER Argument\r\n    Specifies the argument to be validated.\r\n\r\n    .PARAMETER Type\r\n    Specifies the type of argument.\r\n    #>\r\n\r\n    [CmdletBinding()]\r\n    param\r\n    (\r\n        [parameter(Mandatory = $true)]\r\n        [ValidateNotNullOrEmpty()]\r\n        [string]$Argument,\r\n\r\n        [parameter(Mandatory = $true)]\r\n        [ValidateNotNullOrEmpty()]\r\n        [String]$Type,\r\n\r\n        [parameter(Mandatory = $true)]\r\n        [ValidateNotNullOrEmpty()]\r\n        [String]$ProviderName\r\n    )\r\n\r\n    Write-Verbose -Message ($LocalizedData.CallingFunction -f $($MyInvocation.mycommand))\r\n\r\n    switch ($Type)\r\n    {\r\n\r\n        \"SourceUri\"\r\n        {\r\n            # Checks whether given URI represents specific scheme\r\n            # Most common schemes: file, http, https, ftp        \r\n            $scheme =@('http', 'https', 'file', 'ftp')\r\n \r\n            $newUri = $Argument -as [System.URI]  \r\n            $returnValue = ($newUri -and $newUri.AbsoluteURI -and ($scheme -icontains $newuri.Scheme)) \r\n\r\n            if ($returnValue -eq $false)\r\n            {                \r\n                ThrowError  -ExceptionName \"System.ArgumentException\" `\r\n                            -ExceptionMessage ($LocalizedData.InValidUri -f $Argument)`\r\n                            -ErrorId \"InValidUri\" `\r\n                            -ErrorCategory InvalidArgument\r\n            }\r\n            \r\n            #Check whether it's a valid uri. Wait for the response within 2mins.\r\n            <#$result = Invoke-WebRequest $newUri -TimeoutSec 120 -UseBasicParsing -ErrorAction SilentlyContinue\r\n\r\n            if ($null -eq (([xml]$result.Content).service ))\r\n            {\r\n                ThrowError  -ExceptionName \"System.ArgumentException\" `\r\n                            -ExceptionMessage ($LocalizedData.InValidUri -f $Argument)`\r\n                            -ErrorId \"InValidUri\" `\r\n                            -ErrorCategory InvalidArgument\r\n            }#>\r\n                                         \r\n        }\r\n        \"DestinationPath\"\r\n        {\r\n            $returnValue = Test-Path -Path $Argument\r\n            if ($returnValue -eq $false)\r\n            {\r\n                ThrowError  -ExceptionName \"System.ArgumentException\" `\r\n                            -ExceptionMessage ($LocalizedData.PathDoesNotExist -f $Argument)`\r\n                            -ErrorId \"PathDoesNotExist\" `\r\n                            -ErrorCategory InvalidArgument\r\n            }\r\n        }\r\n        \"PackageSource\"\r\n        {      \r\n            #Argument can be either the package source Name or source Uri.  \r\n            \r\n            #Check if the source is a uri \r\n            $uri = $Argument -as [System.URI]  \r\n\r\n            if($uri -and $uri.AbsoluteURI) \r\n            {\r\n                # Check if it's a valid Uri\r\n                ValidateArgument -Argument $Argument -Type \"SourceUri\" -ProviderName $ProviderName\r\n            }\r\n            else\r\n            {\r\n                #Check if it's a registered package source name                                                             \r\n                $source = PackageManagement\\Get-PackageSource -Name $Argument -ProviderName $ProviderName -verbose -ErrorVariable ev\r\n                if ((-not $source) -or $ev) \r\n                {\r\n                    #We do not need to throw error here as Get-PackageSource does already\r\n                    Write-Verbose -Message ($LocalizedData.SourceNotFound -f $source)                \r\n                }\r\n            }\r\n        }\r\n        default\r\n        {\r\n            ThrowError  -ExceptionName \"System.ArgumentException\" `\r\n                        -ExceptionMessage ($LocalizedData.UnexpectedArgument -f $Type)`\r\n                        -ErrorId \"UnexpectedArgument\" `\r\n                        -ErrorCategory InvalidArgument\r\n        }\r\n     }           \r\n}\r\n\r\nFunction ValidateVersionArgument\r\n{\r\n    <#\r\n    .SYNOPSIS\r\n\r\n    This is a helper function that does the version validation. \r\n\r\n    .PARAMETER RequiredVersion\r\n    Provides the required version.\r\n\r\n    .PARAMETER MaximumVersion\r\n    Provides the maximum version.\r\n\r\n    .PARAMETER MinimumVersion\r\n    Provides the minimum version.\r\n    #>\r\n\r\n    [CmdletBinding()]\r\n    param\r\n    (\r\n        [string]$RequiredVersion,\r\n        [string]$MinimumVersion,\r\n        [string]$MaximumVersion\r\n\r\n    )\r\n         \r\n    Write-Verbose -Message ($LocalizedData.CallingFunction -f $($MyInvocation.mycommand))\r\n\r\n    $isValid = $false\r\n         \r\n    #Case 1: No further check required if a user provides either none or one of these: minimumVersion, maximumVersion, and requiredVersion\r\n    if ($PSBoundParameters.Count -le 1)\r\n    {\r\n        return $true\r\n    }\r\n\r\n    #Case 2: #If no RequiredVersion is provided \r\n    if (-not $PSBoundParameters.ContainsKey('RequiredVersion'))\r\n    {\r\n        #If no RequiredVersion, both MinimumVersion and MaximumVersion are provided. Otherwise fall into the Case #1\r\n        $isValid = $PSBoundParameters['MinimumVersion'] -le $PSBoundParameters['MaximumVersion']\r\n    }\r\n    \r\n    #Case 3: RequiredVersion is provided. \r\n    #        In this case  MinimumVersion and/or MaximumVersion also are provided. Otherwise fall in to Case #1.\r\n    #        This is an invalid case. When RequiredVersion is provided, others are not allowed. so $isValid is false, which is already set in the init\r\n\r\n    if ($isValid -eq $false)\r\n    {        \r\n        ThrowError  -ExceptionName \"System.ArgumentException\" `\r\n                    -ExceptionMessage ($LocalizedData.VersionError)`\r\n                    -ErrorId \"VersionError\" `\r\n                    -ErrorCategory InvalidArgument\r\n    }\r\n}\r\n\r\nFunction Get-InstallationPolicy\r\n{\r\n    <#\r\n    .SYNOPSIS\r\n\r\n    This is a helper function that retrives the InstallationPolicy from the given repository. \r\n\r\n    .PARAMETER RepositoryName\r\n    Provides the repository Name.\r\n\r\n    #>\r\n\r\n    Param\r\n    (\r\n        [parameter(Mandatory = $true)]\r\n        [ValidateNotNullOrEmpty()]\r\n        [System.String]$RepositoryName\r\n    )\r\n\r\n    Write-Verbose -Message ($LocalizedData.CallingFunction -f $($MyInvocation.mycommand))\r\n\r\n    $repositoryobj = PackageManagement\\Get-PackageSource -Name $RepositoryName -ErrorAction SilentlyContinue -WarningAction SilentlyContinue\r\n\r\n    if ($repositoryobj)\r\n    {      \r\n        return $repositoryobj.IsTrusted\r\n    }                  \r\n}\r\n\r\n# SIG # Begin signature block\r\n# MIInoQYJKoZIhvcNAQcCoIInkjCCJ44CAQExDzANBglghkgBZQMEAgEFADB5Bgor\r\n# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG\r\n# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCD+xe8u4YoS6UEO\r\n# jtW70wceL89huvuluOvdcbeefpOXLqCCDYEwggX/MIID56ADAgECAhMzAAACUosz\r\n# qviV8znbAAAAAAJSMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD\r\n# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p\r\n# bmcgUENBIDIwMTEwHhcNMjEwOTAyMTgzMjU5WhcNMjIwOTAxMTgzMjU5WjB0MQsw\r\n# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u\r\n# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\r\n# AQDQ5M+Ps/X7BNuv5B/0I6uoDwj0NJOo1KrVQqO7ggRXccklyTrWL4xMShjIou2I\r\n# sbYnF67wXzVAq5Om4oe+LfzSDOzjcb6ms00gBo0OQaqwQ1BijyJ7NvDf80I1fW9O\r\n# L76Kt0Wpc2zrGhzcHdb7upPrvxvSNNUvxK3sgw7YTt31410vpEp8yfBEl/hd8ZzA\r\n# v47DCgJ5j1zm295s1RVZHNp6MoiQFVOECm4AwK2l28i+YER1JO4IplTH44uvzX9o\r\n# RnJHaMvWzZEpozPy4jNO2DDqbcNs4zh7AWMhE1PWFVA+CHI/En5nASvCvLmuR/t8\r\n# q4bc8XR8QIZJQSp+2U6m2ldNAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE\r\n# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUNZJaEUGL2Guwt7ZOAu4efEYXedEw\r\n# UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1\r\n# ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDY3NTk3MB8GA1UdIwQYMBaAFEhu\r\n# ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu\r\n# bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w\r\n# Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3\r\n# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx\r\n# MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAFkk3\r\n# uSxkTEBh1NtAl7BivIEsAWdgX1qZ+EdZMYbQKasY6IhSLXRMxF1B3OKdR9K/kccp\r\n# kvNcGl8D7YyYS4mhCUMBR+VLrg3f8PUj38A9V5aiY2/Jok7WZFOAmjPRNNGnyeg7\r\n# l0lTiThFqE+2aOs6+heegqAdelGgNJKRHLWRuhGKuLIw5lkgx9Ky+QvZrn/Ddi8u\r\n# TIgWKp+MGG8xY6PBvvjgt9jQShlnPrZ3UY8Bvwy6rynhXBaV0V0TTL0gEx7eh/K1\r\n# o8Miaru6s/7FyqOLeUS4vTHh9TgBL5DtxCYurXbSBVtL1Fj44+Od/6cmC9mmvrti\r\n# yG709Y3Rd3YdJj2f3GJq7Y7KdWq0QYhatKhBeg4fxjhg0yut2g6aM1mxjNPrE48z\r\n# 6HWCNGu9gMK5ZudldRw4a45Z06Aoktof0CqOyTErvq0YjoE4Xpa0+87T/PVUXNqf\r\n# 7Y+qSU7+9LtLQuMYR4w3cSPjuNusvLf9gBnch5RqM7kaDtYWDgLyB42EfsxeMqwK\r\n# WwA+TVi0HrWRqfSx2olbE56hJcEkMjOSKz3sRuupFCX3UroyYf52L+2iVTrda8XW\r\n# esPG62Mnn3T8AuLfzeJFuAbfOSERx7IFZO92UPoXE1uEjL5skl1yTZB3MubgOA4F\r\n# 8KoRNhviFAEST+nG8c8uIsbZeb08SeYQMqjVEmkwggd6MIIFYqADAgECAgphDpDS\r\n# AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK\r\n# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0\r\n# IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0\r\n# ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla\r\n# MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS\r\n# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT\r\n# H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB\r\n# AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG\r\n# OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S\r\n# 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz\r\n# y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7\r\n# 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u\r\n# M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33\r\n# X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl\r\n# XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP\r\n# 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB\r\n# l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF\r\n# RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM\r\n# CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ\r\n# BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud\r\n# DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO\r\n# 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0\r\n# LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p\r\n# Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB\r\n# FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw\r\n# cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA\r\n# XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY\r\n# 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj\r\n# 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd\r\n# d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ\r\n# Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf\r\n# wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ\r\n# aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j\r\n# NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B\r\n# xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96\r\n# eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7\r\n# r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I\r\n# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIZdjCCGXICAQEwgZUwfjELMAkG\r\n# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx\r\n# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z\r\n# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAlKLM6r4lfM52wAAAAACUjAN\r\n# BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor\r\n# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgCZ2K5xbK\r\n# 27tyibqtMV5AHpyNN7lNy3nCNEZ+gshCPtAwQgYKKwYBBAGCNwIBDDE0MDKgFIAS\r\n# AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN\r\n# BgkqhkiG9w0BAQEFAASCAQCyqH1a6wilw9tLp1PBwdpHqB1Ami+jaRaJh0DD1pMa\r\n# 0Wv61B/88vYVxgOsFfBcBqZvVoQsYtlAjEcx/dg5Vamacy+LfO+8cm8uRq1uSXOq\r\n# gn3FDJ6Xy0j3pcU44/X1uzh8KoUaQJzNpcjLn8WpqABD0w7WfIA7A+o1yMZUcUsP\r\n# XejK8HpbV8Qrtz9okvl/hsK0zQuajckvm/odt+IgmwBr4yomlRFJ1AAqyKYp//4H\r\n# 7gPo5CBjh3H7wHn0mXMkES24T37LXmxxSncAShECTMvJMhiuM01TN6PziqI6ER0S\r\n# XFvKYHyfqwXvsfn71rcKAIWWjtWXz4a1mIZjkXJfUcf7oYIXADCCFvwGCisGAQQB\r\n# gjcDAwExghbsMIIW6AYJKoZIhvcNAQcCoIIW2TCCFtUCAQMxDzANBglghkgBZQME\r\n# AgEFADCCAVEGCyqGSIb3DQEJEAEEoIIBQASCATwwggE4AgEBBgorBgEEAYRZCgMB\r\n# MDEwDQYJYIZIAWUDBAIBBQAEIB/6Ll6BcpT6c9557ujfliR3kAn4lZRikouo1ahJ\r\n# /NiIAgZitNXDgmUYEzIwMjIwNzAxMjEwMDAwLjQ0OVowBIACAfSggdCkgc0wgcox\r\n# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt\r\n# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1p\r\n# Y3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJjAkBgNVBAsTHVRoYWxlcyBUU1Mg\r\n# RVNOOjhBODItRTM0Ri05RERBMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFt\r\n# cCBTZXJ2aWNloIIRVzCCBwwwggT0oAMCAQICEzMAAAGZyI+vrbZ9vosAAQAAAZkw\r\n# DQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0\r\n# b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh\r\n# dGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwHhcN\r\n# MjExMjAyMTkwNTE2WhcNMjMwMjI4MTkwNTE2WjCByjELMAkGA1UEBhMCVVMxEzAR\r\n# BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p\r\n# Y3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2Eg\r\n# T3BlcmF0aW9uczEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046OEE4Mi1FMzRGLTlE\r\n# REExJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggIiMA0G\r\n# CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC4E/lXXKMsy9rVa2a8bRb0Ar/Pj4+b\r\n# KiAgMgKayvCMFn3ddGof8eWFgJWp5JdKjWjrnmW1r9tHpcP2kFpjXp2Udrj55jt5\r\n# NYi1MERcoIo+E29XuCwFAMJftGdvsWea/OTQPIFsZEWqEteXdRncyVwct5xFzBIC\r\n# 1JWCdmfc7R59RMIyvgWjIz8356mweowkOstN1fe53KIJ8flrYILIQWsNRMOT3znA\r\n# GwIb9kyL54C6jZjFxOSusGYmVQ+Gr/qZQELw1ipx9s5jNP1LSpOpfTEBFu+y9KLN\r\n# BmMBARkSPpTFkGEyGSwGGgSdOi6BU6FPK+6urZ830jrRemK4JkIJ9tQhlGcIhAjh\r\n# cqZStn+38lRjVvrfbBI5EpI2NwlVIK2ibGW7sWeTAz/yNPNISUbQhGAJse/OgGj/\r\n# 1qz/Ha9mqfYZ8BHchNxn08nWkqyrjrKicQyxuD8mCatTrVSbOJYfQyZdHR9a4vgy\r\n# GeZEXBYQNAlIuB37QCOAgs/VeDU8M4dc/IlrTyC0uV1SS4Gk8zV+5X5eRu+XORN8\r\n# FWqzI6k/9y6cWwOWMK6aUN1XqLcaF/sm9rX84eKW2lhDc3C31WLjp8UOfOHZfPuy\r\n# y54xfilnhhCPy4QKJ9jggoqqeeEhCEfgDYjy+PByV/e5HDB2xHdtlL93wltAkI3a\r\n# Cxo84kVPBCa0OwIDAQABo4IBNjCCATIwHQYDVR0OBBYEFI26Vrg+nGWvrvIh0dQP\r\n# EonENR0QMB8GA1UdIwQYMBaAFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMF8GA1UdHwRY\r\n# MFYwVKBSoFCGTmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01p\r\n# Y3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNybDBsBggrBgEF\r\n# BQcBAQRgMF4wXAYIKwYBBQUHMAKGUGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9w\r\n# a2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAo\r\n# MSkuY3J0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwgwDQYJKoZI\r\n# hvcNAQELBQADggIBAHGzWh29ibBNro3ns8E3EOHGsLB1Gzk90SFYUKBilIu4jDbR\r\n# 7qbvXNd8nnl/z5D9LKgw3T81jqy5tMiWp+p4jYBBk3PRx1ySqLUfhF5ZMWolRzW+\r\n# cQZGXV38iSmdAUG0CpR5x1rMdPIrTczVUFsOYGqmkoUQ/dRiVL4iAXJLCNTj4x3Y\r\n# wIQcCPt0ijJVinPIMAYzA8f99BbeiskyI0BHGAd0kGUX2I2/puYnlyS8toBnANjh\r\n# 21xgvEuaZ2dvRqvWk/i1XIlO67au/XCeMTvXhPOIUmq80U32Tifw3SSiBKTyir7m\r\n# oWH1i7H2q5QAnrBxuyy//ZsDfARDV/Atmj5jr6ATfRHDdUanQpeoBS+iylNU6RAR\r\n# u8g+TMCu/ZndZmrs9w+8galUIGg+GmlNk07fXJ58Oc+qFqgNAsNkMi+dSzKkWGA4\r\n# /klJFn0XichXL8+t7KOayXKGzQja6CdtCjisnyS8hbv4PKhaeMtf68wJWKKOs0tt\r\n# 2AJfYC5vSbH9ck8BGj2e/yQXEZEu88L5/fHK5XUk/IKXx3zaLkxXTSZ43Ea/WKXV\r\n# BzMasHZ3Pmny0moEekAXx1UhLNNYv4Vum33VirxSB6r/GKQxFSHu7yFfrWQpYyyD\r\n# H119TmhAedS8T1VabqdtO5ZP2E14TK82Vyxy3xEPelOo4dRIlhm7XY6k9B68MIIH\r\n# cTCCBVmgAwIBAgITMwAAABXF52ueAptJmQAAAAAAFTANBgkqhkiG9w0BAQsFADCB\r\n# iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl\r\n# ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMp\r\n# TWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMjEw\r\n# OTMwMTgyMjI1WhcNMzAwOTMwMTgzMjI1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UE\r\n# CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z\r\n# b2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQ\r\n# Q0EgMjAxMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOThpkzntHIh\r\n# C3miy9ckeb0O1YLT/e6cBwfSqWxOdcjKNVf2AX9sSuDivbk+F2Az/1xPx2b3lVNx\r\n# WuJ+Slr+uDZnhUYjDLWNE893MsAQGOhgfWpSg0S3po5GawcU88V29YZQ3MFEyHFc\r\n# UTE3oAo4bo3t1w/YJlN8OWECesSq/XJprx2rrPY2vjUmZNqYO7oaezOtgFt+jBAc\r\n# nVL+tuhiJdxqD89d9P6OU8/W7IVWTe/dvI2k45GPsjksUZzpcGkNyjYtcI4xyDUo\r\n# veO0hyTD4MmPfrVUj9z6BVWYbWg7mka97aSueik3rMvrg0XnRm7KMtXAhjBcTyzi\r\n# YrLNueKNiOSWrAFKu75xqRdbZ2De+JKRHh09/SDPc31BmkZ1zcRfNN0Sidb9pSB9\r\n# fvzZnkXftnIv231fgLrbqn427DZM9ituqBJR6L8FA6PRc6ZNN3SUHDSCD/AQ8rdH\r\n# GO2n6Jl8P0zbr17C89XYcz1DTsEzOUyOArxCaC4Q6oRRRuLRvWoYWmEBc8pnol7X\r\n# KHYC4jMYctenIPDC+hIK12NvDMk2ZItboKaDIV1fMHSRlJTYuVD5C4lh8zYGNRiE\r\n# R9vcG9H9stQcxWv2XFJRXRLbJbqvUAV6bMURHXLvjflSxIUXk8A8FdsaN8cIFRg/\r\n# eKtFtvUeh17aj54WcmnGrnu3tz5q4i6tAgMBAAGjggHdMIIB2TASBgkrBgEEAYI3\r\n# FQEEBQIDAQABMCMGCSsGAQQBgjcVAgQWBBQqp1L+ZMSavoKRPEY1Kc8Q/y8E7jAd\r\n# BgNVHQ4EFgQUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXAYDVR0gBFUwUzBRBgwrBgEE\r\n# AYI3TIN9AQEwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29t\r\n# L3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMBMGA1UdJQQMMAoGCCsGAQUFBwMI\r\n# MBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMB\r\n# Af8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fOmhjEMFYGA1Ud\r\n# HwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3By\r\n# b2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggrBgEFBQcBAQRO\r\n# MEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2Vy\r\n# dHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MA0GCSqGSIb3DQEBCwUAA4IC\r\n# AQCdVX38Kq3hLB9nATEkW+Geckv8qW/qXBS2Pk5HZHixBpOXPTEztTnXwnE2P9pk\r\n# bHzQdTltuw8x5MKP+2zRoZQYIu7pZmc6U03dmLq2HnjYNi6cqYJWAAOwBb6J6Gng\r\n# ugnue99qb74py27YP0h1AdkY3m2CDPVtI1TkeFN1JFe53Z/zjj3G82jfZfakVqr3\r\n# lbYoVSfQJL1AoL8ZthISEV09J+BAljis9/kpicO8F7BUhUKz/AyeixmJ5/ALaoHC\r\n# gRlCGVJ1ijbCHcNhcy4sa3tuPywJeBTpkbKpW99Jo3QMvOyRgNI95ko+ZjtPu4b6\r\n# MhrZlvSP9pEB9s7GdP32THJvEKt1MMU0sHrYUP4KWN1APMdUbZ1jdEgssU5HLcEU\r\n# BHG/ZPkkvnNtyo4JvbMBV0lUZNlz138eW0QBjloZkWsNn6Qo3GcZKCS6OEuabvsh\r\n# VGtqRRFHqfG3rsjoiV5PndLQTHa1V1QJsWkBRH58oWFsc/4Ku+xBZj1p/cvBQUl+\r\n# fpO+y/g75LcVv7TOPqUxUYS8vwLBgqJ7Fx0ViY1w/ue10CgaiQuPNtq6TPmb/wrp\r\n# NPgkNWcr4A245oyZ1uEi6vAnQj0llOZ0dFtq0Z4+7X6gMTN9vMvpe784cETRkPHI\r\n# qzqKOghif9lwY1NNje6CbaUFEMFxBmoQtB1VM1izoXBm8qGCAs4wggI3AgEBMIH4\r\n# oYHQpIHNMIHKMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G\r\n# A1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUw\r\n# IwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMSYwJAYDVQQLEx1U\r\n# aGFsZXMgVFNTIEVTTjo4QTgyLUUzNEYtOUREQTElMCMGA1UEAxMcTWljcm9zb2Z0\r\n# IFRpbWUtU3RhbXAgU2VydmljZaIjCgEBMAcGBSsOAwIaAxUAku/zYujnqapN6BJ9\r\n# MJ5jtgDrlOuggYMwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu\r\n# Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv\r\n# cmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAN\r\n# BgkqhkiG9w0BAQUFAAIFAOZpNz0wIhgPMjAyMjA3MDExNzA1MDFaGA8yMDIyMDcw\r\n# MjE3MDUwMVowdzA9BgorBgEEAYRZCgQBMS8wLTAKAgUA5mk3PQIBADAKAgEAAgIR\r\n# FQIB/zAHAgEAAgIRszAKAgUA5mqIvQIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgor\r\n# BgEEAYRZCgMCoAowCAIBAAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUA\r\n# A4GBAFPnj5aYeiMxAJhCBC3XyLLyNYf/OubzwI5EX68hNX+TC87/MMvxocAgfMk1\r\n# zLkJek8rPLlWGWf2oeGQYwyOQ0OMjD5YU4LnkVjN0l027+vwT2Rafc6RIWFiQbIG\r\n# RRBFfXDFgyuM97dVEf8ICSKsRlCCgFAV8JMNdND7JtN+xEb6MYIEDTCCBAkCAQEw\r\n# gZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT\r\n# B1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UE\r\n# AxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAGZyI+vrbZ9vosA\r\n# AQAAAZkwDQYJYIZIAWUDBAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0B\r\n# CRABBDAvBgkqhkiG9w0BCQQxIgQgkB6lWYhfhU1/DxjvSurvGL3RL89ss6hg4476\r\n# tkRKHTwwgfoGCyqGSIb3DQEJEAIvMYHqMIHnMIHkMIG9BCBmfWn58qKN7WWpBTYO\r\n# rUO1BSCSnKPLC/G7wCOIc2JsfjCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYD\r\n# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1w\r\n# IFBDQSAyMDEwAhMzAAABmciPr622fb6LAAEAAAGZMCIEILRj7rb7JnV73e8wLbPq\r\n# CULQreKtMxdbry8TgOxho5edMA0GCSqGSIb3DQEBCwUABIICAKDNJpuPLp51vjon\r\n# QG0U01L3EGiaTgFCweFx7+x4vL5mVQ8JQBPaYJoy+34wnXF2U+0FwXW0SiTzzIHb\r\n# 0lFXKRkSMqCPnpW/1Oz474m9w95SvR86JgRC/kuJWtyD+TZg++zCafJeaLAXnuj3\r\n# LbpJlbNp7P6jW5Kz05J8xrz/Q+5g16VQ7RqqHImBKubLqAHEWrRcZiOXZZuIyDT4\r\n# 2L1vyDMMVHjGZfghQO5on6LsAmBmS2Ne7VteWUQxVWI/0yl1e81xjLzPFmiU0PrL\r\n# oWwI+fYVuKCYo5bwYQEhlVb5iVhNYYeNo0Voyh5Nnl75ClP/Xp/jeRb4hI9w6cdf\r\n# rlHWIhrKmNDb2Hmu7fVOF+A4O2j32EXG7sJPMNmboMFOeQf8eTcohw0LImS/eay/\r\n# 6vAcPeJw7jhHpJG20zDfusn4HDR1nD4oKTENvK7EIMSheRvsxAR1KS90sQLoPkyc\r\n# k5rkNTr8MHhvE4Nz5eeNfO7FIw2xPxwRST4p/hLes9xUw4H59TdSe9H0N92q118J\r\n# NNo/xo7e5d6lSLoonrL/TIYbvuoqM5PGw8HPS8ve09kV00MXTAGcnxpr2j1CzMAv\r\n# Y4i7KMGesQfOB5ounL187ZV/e+bhhHfLA0mgSnehHjXtQP/MNOvQ9/EXIK3/xcXg\r\n# mr4TmGPRZkuxUnXFoqN0pPOr9NOY\r\n# SIG # End signature block\r\n"
  },
  {
    "path": "src/PowerShell/ExternalModules/PackageManagement/1.4.8.1/PSGetModuleInfo.xml",
    "content": "<Objs Version=\"1.1.0.1\" xmlns=\"http://schemas.microsoft.com/powershell/2004/04\">\r\n  <Obj RefId=\"0\">\r\n    <TN RefId=\"0\">\r\n      <T>Microsoft.PowerShell.Commands.PSRepositoryItemInfo</T>\r\n      <T>System.Management.Automation.PSCustomObject</T>\r\n      <T>System.Object</T>\r\n    </TN>\r\n    <MS>\r\n      <S N=\"Name\">PackageManagement</S>\r\n      <S N=\"Version\">1.4.8.1</S>\r\n      <S N=\"Type\">Module</S>\r\n      <S N=\"Description\">PackageManagement (a.k.a. OneGet) is a new way to discover and install software packages from around the web._x000D__x000A_ It is a manager or multiplexor of existing package managers (also called package providers) that unifies Windows package management with a single Windows PowerShell interface. With PackageManagement, you can do the following._x000D__x000A_  - Manage a list of software repositories in which packages can be searched, acquired and installed_x000D__x000A_  - Discover software packages_x000D__x000A_  - Seamlessly install, uninstall, and inventory packages from one or more software repositories</S>\r\n      <S N=\"Author\">Microsoft Corporation</S>\r\n      <Obj N=\"CompanyName\" RefId=\"1\">\r\n        <TN RefId=\"1\">\r\n          <T>System.Object[]</T>\r\n          <T>System.Array</T>\r\n          <T>System.Object</T>\r\n        </TN>\r\n        <LST>\r\n          <S>PowerShellTeam</S>\r\n          <S>alerickson</S>\r\n          <S>NateLehman</S>\r\n          <S>krishnayalavarthi</S>\r\n          <S>anamnavi</S>\r\n        </LST>\r\n      </Obj>\r\n      <S N=\"Copyright\">(C) Microsoft Corporation. All rights reserved.</S>\r\n      <DT N=\"PublishedDate\">2022-07-01T21:21:49-07:00</DT>\r\n      <Nil N=\"InstalledDate\" />\r\n      <Nil N=\"UpdatedDate\" />\r\n      <Nil N=\"LicenseUri\" />\r\n      <URI N=\"ProjectUri\">https://oneget.org/</URI>\r\n      <Nil N=\"IconUri\" />\r\n      <Obj N=\"Tags\" RefId=\"2\">\r\n        <TNRef RefId=\"1\" />\r\n        <LST>\r\n          <S>PackageManagement</S>\r\n          <S>PSEdition_Core</S>\r\n          <S>PSEdition_Desktop</S>\r\n          <S>Linux</S>\r\n          <S>Mac</S>\r\n          <S>PSModule</S>\r\n        </LST>\r\n      </Obj>\r\n      <Obj N=\"Includes\" RefId=\"3\">\r\n        <TN RefId=\"2\">\r\n          <T>System.Collections.Hashtable</T>\r\n          <T>System.Object</T>\r\n        </TN>\r\n        <DCT>\r\n          <En>\r\n            <S N=\"Key\">Command</S>\r\n            <Obj N=\"Value\" RefId=\"4\">\r\n              <TNRef RefId=\"1\" />\r\n              <LST>\r\n                <S>Find-Package</S>\r\n                <S>Get-Package</S>\r\n                <S>Get-PackageProvider</S>\r\n                <S>Get-PackageSource</S>\r\n                <S>Install-Package</S>\r\n                <S>Import-PackageProvider</S>\r\n                <S>Find-PackageProvider</S>\r\n                <S>Install-PackageProvider</S>\r\n                <S>Register-PackageSource</S>\r\n                <S>Set-PackageSource</S>\r\n                <S>Unregister-PackageSource</S>\r\n                <S>Uninstall-Package</S>\r\n                <S>Save-Package</S>\r\n              </LST>\r\n            </Obj>\r\n          </En>\r\n          <En>\r\n            <S N=\"Key\">Function</S>\r\n            <Obj N=\"Value\" RefId=\"5\">\r\n              <TNRef RefId=\"1\" />\r\n              <LST />\r\n            </Obj>\r\n          </En>\r\n          <En>\r\n            <S N=\"Key\">Cmdlet</S>\r\n            <Obj N=\"Value\" RefId=\"6\">\r\n              <TNRef RefId=\"1\" />\r\n              <LST>\r\n                <S>Find-Package</S>\r\n                <S>Get-Package</S>\r\n                <S>Get-PackageProvider</S>\r\n                <S>Get-PackageSource</S>\r\n                <S>Install-Package</S>\r\n                <S>Import-PackageProvider</S>\r\n                <S>Find-PackageProvider</S>\r\n                <S>Install-PackageProvider</S>\r\n                <S>Register-PackageSource</S>\r\n                <S>Set-PackageSource</S>\r\n                <S>Unregister-PackageSource</S>\r\n                <S>Uninstall-Package</S>\r\n                <S>Save-Package</S>\r\n              </LST>\r\n            </Obj>\r\n          </En>\r\n          <En>\r\n            <S N=\"Key\">DscResource</S>\r\n            <Obj N=\"Value\" RefId=\"7\">\r\n              <TNRef RefId=\"1\" />\r\n              <LST>\r\n                <S>MSFT_PackageManagement</S>\r\n                <S>MSFT_PackageManagementSource</S>\r\n              </LST>\r\n            </Obj>\r\n          </En>\r\n          <En>\r\n            <S N=\"Key\">Workflow</S>\r\n            <Ref N=\"Value\" RefId=\"5\" />\r\n          </En>\r\n          <En>\r\n            <S N=\"Key\">RoleCapability</S>\r\n            <Ref N=\"Value\" RefId=\"5\" />\r\n          </En>\r\n        </DCT>\r\n      </Obj>\r\n      <Nil N=\"PowerShellGetFormatVersion\" />\r\n      <S N=\"ReleaseNotes\">## 1.4.8.1_x000D__x000A_- Update PackageManagement's strong name signing_x000D__x000A__x000D__x000A_## 1.4.8_x000D__x000A_- Add NuGet as a source when generating nuget.config file for user in the NuGet Provider_x000D__x000A__x000D__x000A_## 1.4.7_x000D__x000A_- Update security protocol to use TLS 1.2_x000D__x000A_- Remove catalog file_x000D__x000A__x000D__x000A_## 1.4.6_x000D__x000A_- Update `HelpInfoUri` to point to the latest content_x000D__x000A__x000D__x000A_## 1.4.5_x000D__x000A_- Bug fix for deadlock when getting parameters in an event_x000D__x000A__x000D__x000A_## 1.4.4_x000D__x000A_- Bug fix when installing modules from private feeds_x000D__x000A__x000D__x000A_ ## 1.4.3_x000D__x000A_- Another bug fix when registering repositories with PowerShellGet_x000D__x000A__x000D__x000A_## 1.4.2_x000D__x000A_- Bug fix for passing credentials from PowerShellGet when registering repositories_x000D__x000A__x000D__x000A_## 1.4.1_x000D__x000A_- Bug fix for using credential provider installed in Visual Studio_x000D__x000A__x000D__x000A_## 1.4_x000D__x000A_- Allow credential persistance for registering private repositories and finding or installing packages from those repositories_x000D__x000A__x000D__x000A_## 1.3.2_x000D__x000A_- Enable bootstrap on PSCore_x000D__x000A_- Bug fix to run on .NET Core 3.0_x000D__x000A__x000D__x000A_## 1.3.1_x000D__x000A_- Targets net452 and netstandard2.0 instead of net451, netcoreapp2.0, and netstandard1.6_x000D__x000A_            _x000D__x000A_## Previous releases are not included in this Changelog</S>\r\n      <Obj N=\"Dependencies\" RefId=\"8\">\r\n        <TNRef RefId=\"1\" />\r\n        <LST />\r\n      </Obj>\r\n      <S N=\"RepositorySourceLocation\">https://www.powershellgallery.com/api/v2</S>\r\n      <S N=\"Repository\">PSGallery</S>\r\n      <S N=\"PackageManagementProvider\">NuGet</S>\r\n      <Obj N=\"AdditionalMetadata\" RefId=\"9\">\r\n        <TN RefId=\"3\">\r\n          <T>System.Management.Automation.PSCustomObject</T>\r\n          <T>System.Object</T>\r\n        </TN>\r\n        <MS>\r\n          <S N=\"copyright\">(C) Microsoft Corporation. All rights reserved.</S>\r\n          <S N=\"description\">PackageManagement (a.k.a. OneGet) is a new way to discover and install software packages from around the web._x000D__x000A_ It is a manager or multiplexor of existing package managers (also called package providers) that unifies Windows package management with a single Windows PowerShell interface. With PackageManagement, you can do the following._x000D__x000A_  - Manage a list of software repositories in which packages can be searched, acquired and installed_x000D__x000A_  - Discover software packages_x000D__x000A_  - Seamlessly install, uninstall, and inventory packages from one or more software repositories</S>\r\n          <S N=\"requireLicenseAcceptance\">False</S>\r\n          <S N=\"releaseNotes\">## 1.4.8.1_x000D__x000A_- Update PackageManagement's strong name signing_x000D__x000A__x000D__x000A_## 1.4.8_x000D__x000A_- Add NuGet as a source when generating nuget.config file for user in the NuGet Provider_x000D__x000A__x000D__x000A_## 1.4.7_x000D__x000A_- Update security protocol to use TLS 1.2_x000D__x000A_- Remove catalog file_x000D__x000A__x000D__x000A_## 1.4.6_x000D__x000A_- Update `HelpInfoUri` to point to the latest content_x000D__x000A__x000D__x000A_## 1.4.5_x000D__x000A_- Bug fix for deadlock when getting parameters in an event_x000D__x000A__x000D__x000A_## 1.4.4_x000D__x000A_- Bug fix when installing modules from private feeds_x000D__x000A__x000D__x000A_ ## 1.4.3_x000D__x000A_- Another bug fix when registering repositories with PowerShellGet_x000D__x000A__x000D__x000A_## 1.4.2_x000D__x000A_- Bug fix for passing credentials from PowerShellGet when registering repositories_x000D__x000A__x000D__x000A_## 1.4.1_x000D__x000A_- Bug fix for using credential provider installed in Visual Studio_x000D__x000A__x000D__x000A_## 1.4_x000D__x000A_- Allow credential persistance for registering private repositories and finding or installing packages from those repositories_x000D__x000A__x000D__x000A_## 1.3.2_x000D__x000A_- Enable bootstrap on PSCore_x000D__x000A_- Bug fix to run on .NET Core 3.0_x000D__x000A__x000D__x000A_## 1.3.1_x000D__x000A_- Targets net452 and netstandard2.0 instead of net451, netcoreapp2.0, and netstandard1.6_x000D__x000A_            _x000D__x000A_## Previous releases are not included in this Changelog</S>\r\n          <S N=\"isLatestVersion\">True</S>\r\n          <S N=\"isAbsoluteLatestVersion\">True</S>\r\n          <S N=\"versionDownloadCount\">38794156</S>\r\n          <S N=\"downloadCount\">128454435</S>\r\n          <S N=\"packageSize\">1153134</S>\r\n          <S N=\"published\">7/1/2022 9:21:49 PM -07:00</S>\r\n          <S N=\"created\">7/1/2022 9:21:49 PM -07:00</S>\r\n          <S N=\"lastEdited\">7/5/2022 6:42:00 PM -07:00</S>\r\n          <S N=\"lastUpdated\">3/21/2023 6:34:18 PM -07:00</S>\r\n          <S N=\"tags\">PackageManagement PSEdition_Core PSEdition_Desktop Linux Mac PSModule PSCmdlet_Find-Package PSCommand_Find-Package PSCmdlet_Get-Package PSCommand_Get-Package PSCmdlet_Get-PackageProvider PSCommand_Get-PackageProvider PSCmdlet_Get-PackageSource PSCommand_Get-PackageSource PSCmdlet_Install-Package PSCommand_Install-Package PSCmdlet_Import-PackageProvider PSCommand_Import-PackageProvider PSCmdlet_Find-PackageProvider PSCommand_Find-PackageProvider PSCmdlet_Install-PackageProvider PSCommand_Install-PackageProvider PSCmdlet_Register-PackageSource PSCommand_Register-PackageSource PSCmdlet_Set-PackageSource PSCommand_Set-PackageSource PSCmdlet_Unregister-PackageSource PSCommand_Unregister-PackageSource PSCmdlet_Uninstall-Package PSCommand_Uninstall-Package PSCmdlet_Save-Package PSCommand_Save-Package PSIncludes_Cmdlet PSDscResource_MSFT_PackageManagement PSDscResource_MSFT_PackageManagementSource PSIncludes_DscResource</S>\r\n          <S N=\"developmentDependency\">False</S>\r\n          <S N=\"updated\">2023-03-21T18:34:18Z</S>\r\n          <S N=\"NormalizedVersion\">1.4.8.1</S>\r\n          <S N=\"Authors\">Microsoft Corporation</S>\r\n          <S N=\"IsPrerelease\">false</S>\r\n          <S N=\"ItemType\">Module</S>\r\n          <S N=\"FileList\">PackageManagement.nuspec|PackageManagement.format.ps1xml|PackageManagement.psd1|PackageManagement.psm1|PackageManagement.Resources.psd1|PackageProviderFunctions.psm1|DSCResources\\PackageManagementDscUtilities.psm1|DSCResources\\PackageManagementDscUtilities.strings.psd1|fullclr\\Microsoft.PackageManagement.ArchiverProviders.dll|fullclr\\Microsoft.PackageManagement.CoreProviders.dll|fullclr\\Microsoft.PackageManagement.dll|fullclr\\Microsoft.PackageManagement.MetaProvider.PowerShell.dll|fullclr\\Microsoft.PackageManagement.MsiProvider.dll|fullclr\\Microsoft.PackageManagement.MsuProvider.dll|fullclr\\Microsoft.PackageManagement.NuGetProvider.dll|fullclr\\Microsoft.PowerShell.PackageManagement.dll|coreclr\\netstandard2.0\\Microsoft.PackageManagement.ArchiverProviders.dll|coreclr\\netstandard2.0\\Microsoft.PackageManagement.CoreProviders.dll|coreclr\\netstandard2.0\\Microsoft.PackageManagement.dll|coreclr\\netstandard2.0\\Microsoft.PackageManagement.MetaProvider.PowerShell.dll|coreclr\\netstandard2.0\\Microsoft.PackageManagement.NuGetProvider.dll|coreclr\\netstandard2.0\\Microsoft.PowerShell.PackageManagement.dll|DSCResources\\MSFT_PackageManagement\\MSFT_PackageManagement.psm1|DSCResources\\MSFT_PackageManagement\\MSFT_PackageManagement.schema.mof|DSCResources\\MSFT_PackageManagement\\MSFT_PackageManagement.strings.psd1|DSCResources\\MSFT_PackageManagementSource\\MSFT_PackageManagementSource.psm1|DSCResources\\MSFT_PackageManagementSource\\MSFT_PackageManagementSource.schema.mof|DSCResources\\MSFT_PackageManagementSource\\MSFT_PackageManagementSource.strings.psd1</S>\r\n          <S N=\"GUID\">4ae9fd46-338a-459c-8186-07f910774cb8</S>\r\n          <S N=\"PowerShellVersion\">3.0</S>\r\n          <S N=\"CLRVersion\">4.0</S>\r\n          <S N=\"CompanyName\">Microsoft Corporation</S>\r\n        </MS>\r\n      </Obj>\r\n      <S N=\"InstalledLocation\">D:\\mspkg\\src\\PowerShell\\ExternalModules\\PackageManagement\\1.4.8.1</S>\r\n    </MS>\r\n  </Obj>\r\n</Objs>\r\n"
  },
  {
    "path": "src/PowerShell/ExternalModules/PackageManagement/1.4.8.1/PackageManagement.Resources.psd1",
    "content": "#########################################################################################\r\n#\r\n# Copyright (c) Microsoft Corporation. All rights reserved.\r\n#\r\n# Localized PackageManagement.Resources.psd1\r\n#\r\n#########################################################################################\r\n\r\nConvertFrom-StringData @'\r\n###PSLOC\r\n\r\n    OldPowerShellCoreVersion=PackageManagement no longer supports PowerShell Core '{0}'. Please install the latest version of PowerShell Core from 'https://aka.ms/i6t6o3' and try again.\r\n###PSLOC\r\n'@\r\n# SIG # Begin signature block\r\n# MIInogYJKoZIhvcNAQcCoIInkzCCJ48CAQExDzANBglghkgBZQMEAgEFADB5Bgor\r\n# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG\r\n# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBIBsoYrH/WngZG\r\n# wcwl3oPmFWjeg9nVV4OusKRd1BszsaCCDYUwggYDMIID66ADAgECAhMzAAACU+OD\r\n# 3pbexW7MAAAAAAJTMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD\r\n# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p\r\n# bmcgUENBIDIwMTEwHhcNMjEwOTAyMTgzMzAwWhcNMjIwOTAxMTgzMzAwWjB0MQsw\r\n# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u\r\n# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\r\n# AQDLhxHwq3OhH+4J+SX4qS/VQG8HybccH7tnG+BUqrXubfGuDFYPZ29uCuHfQlO1\r\n# lygLgMpJ4Geh6/6poQ5VkDKfVssn6aA1PCzIh8iOPMQ9Mju3sLF9Sn+Pzuaie4BN\r\n# rp0MuZLDEXgVYx2WNjmzqcxC7dY9SC3znOh5qUy2vnmWygC7b9kj0d3JrGtjc5q5\r\n# 0WfV3WLXAQHkeRROsJFBZfXFGoSvRljFFUAjU/zdhP92P+1JiRRRikVy/sqIhMDY\r\n# +7tVdzlE2fwnKOv9LShgKeyEevgMl0B1Fq7E2YeBZKF6KlhmYi9CE1350cnTUoU4\r\n# YpQSnZo0YAnaenREDLfFGKTdAgMBAAGjggGCMIIBfjAfBgNVHSUEGDAWBgorBgEE\r\n# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUlZpLWIccXoxessA/DRbe26glhEMw\r\n# VAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh\r\n# dGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjMwMDEyKzQ2NzU5ODAfBgNVHSMEGDAW\r\n# gBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8v\r\n# d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIw\r\n# MTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDov\r\n# L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDEx\r\n# XzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB\r\n# AKVY+yKcJVVxf9W2vNkL5ufjOpqcvVOOOdVyjy1dmsO4O8khWhqrecdVZp09adOZ\r\n# 8kcMtQ0U+oKx484Jg11cc4Ck0FyOBnp+YIFbOxYCqzaqMcaRAgy48n1tbz/EFYiF\r\n# zJmMiGnlgWFCStONPvQOBD2y/Ej3qBRnGy9EZS1EDlRN/8l5Rs3HX2lZhd9WuukR\r\n# bUk83U99TPJyo12cU0Mb3n1HJv/JZpwSyqb3O0o4HExVJSkwN1m42fSVIVtXVVSa\r\n# YZiVpv32GoD/dyAS/gyplfR6FI3RnCOomzlycSqoz0zBCPFiCMhVhQ6qn+J0GhgR\r\n# BJvGKizw+5lTfnBFoqKZJDROz+uGDl9tw6JvnVqAZKGrWv/CsYaegaPePFrAVSxA\r\n# yUwOFTkAqtNC8uAee+rv2V5xLw8FfpKJ5yKiMKnCKrIaFQDr5AZ7f2ejGGDf+8Tz\r\n# OiK1AgBvOW3iTEEa/at8Z4+s1CmnEAkAi0cLjB72CJedU1LAswdOCWM2MDIZVo9j\r\n# 0T74OkJLTjPd3WNEyw0rBXTyhlbYQsYt7ElT2l2TTlF5EmpVixGtj4ChNjWoKr9y\r\n# TAqtadd2Ym5FNB792GzwNwa631BPCgBJmcRpFKXt0VEQq7UXVNYBiBRd+x4yvjqq\r\n# 5aF7XC5nXCgjbCk7IXwmOphNuNDNiRq83Ejjnc7mxrJGMIIHejCCBWKgAwIBAgIK\r\n# YQ6Q0gAAAAAAAzANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNV\r\n# BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv\r\n# c29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlm\r\n# aWNhdGUgQXV0aG9yaXR5IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEw\r\n# OTA5WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE\r\n# BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYD\r\n# VQQDEx9NaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG\r\n# 9w0BAQEFAAOCAg8AMIICCgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+la\r\n# UKq4BjgaBEm6f8MMHt03a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc\r\n# 6Whe0t+bU7IKLMOv2akrrnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4D\r\n# dato88tt8zpcoRb0RrrgOGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+\r\n# lD3v++MrWhAfTVYoonpy4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nk\r\n# kDstrjNYxbc+/jLTswM9sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6\r\n# A4aN91/w0FK/jJSHvMAhdCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmd\r\n# X4jiJV3TIUs+UsS1Vz8kA/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL\r\n# 5zmhD+kjSbwYuER8ReTBw3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zd\r\n# sGbiwZeBe+3W7UvnSSmnEyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3\r\n# T8HhhUSJxAlMxdSlQy90lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS\r\n# 4NaIjAsCAwEAAaOCAe0wggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRI\r\n# bmTlUAXTgqoXNzcitW2oynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAL\r\n# BgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBD\r\n# uRQFTuHqp8cx0SOJNDBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jv\r\n# c29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf\r\n# MDNfMjIuY3JsMF4GCCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3\r\n# dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf\r\n# MDNfMjIuY3J0MIGfBgNVHSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEF\r\n# BQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1h\r\n# cnljcHMuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkA\r\n# YwB5AF8AcwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn\r\n# 8oalmOBUeRou09h0ZyKbC5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7\r\n# v0epo/Np22O/IjWll11lhJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0b\r\n# pdS1HXeUOeLpZMlEPXh6I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/\r\n# KmtYSWMfCWluWpiW5IP0wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvy\r\n# CInWH8MyGOLwxS3OW560STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBp\r\n# mLJZiWhub6e3dMNABQamASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJi\r\n# hsMdYzaXht/a8/jyFqGaJ+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYb\r\n# BL7fQccOKO7eZS/sl/ahXJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbS\r\n# oqKfenoi+kiVH6v7RyOA9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sL\r\n# gOppO6/8MO0ETI7f33VtY5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtX\r\n# cVZOSEXAQsmbdlsKgEhr/Xmfwb1tbWrJUnMTDXpQzTGCGXMwghlvAgEBMIGVMH4x\r\n# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt\r\n# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p\r\n# Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAAJT44Pelt7FbswAAAAA\r\n# AlMwDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw\r\n# HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEII0M\r\n# q4L3/1947bwnMVvGP5Dmwbb971etV96SBKgFIvZRMEIGCisGAQQBgjcCAQwxNDAy\r\n# oBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5j\r\n# b20wDQYJKoZIhvcNAQEBBQAEggEAobv6NU6XVA64f3V2uUUkdzyvJ6z+Fh3abvbP\r\n# G8Jes921e5G3kFIkII8uqVjju3kaR0V6CprgswF4sRa6DG8q6i5XGczd7uNgt4fn\r\n# 11MLiky6r6km9N53YZHfSQunYurfHKee4D4qfYluaLCPQCSQ5Jri0I8cBAbYfb3k\r\n# hKJaiMV+DesnimsETP0eExyCjzYgt9+calYTAZc1yCMzQxoshOp5AIsj/VFv184V\r\n# 9p/QsfHKIfbK+eNb9VclXcSu1Nbxi/D82w5SdVVjyjViE7GyEMG76J9UZveKUlth\r\n# FYZ+IPWT9xZ9POk4+wzGHP49jCVInEWFnmObLgF1kE/LJ4K79KGCFv0wghb5Bgor\r\n# BgEEAYI3AwMBMYIW6TCCFuUGCSqGSIb3DQEHAqCCFtYwghbSAgEDMQ8wDQYJYIZI\r\n# AWUDBAIBBQAwggFRBgsqhkiG9w0BCRABBKCCAUAEggE8MIIBOAIBAQYKKwYBBAGE\r\n# WQoDATAxMA0GCWCGSAFlAwQCAQUABCA6fmswW5cfPwuOva/mZGh76WqyLmVw68W5\r\n# Kyj7PkdiJQIGYrThpN06GBMyMDIyMDcwMTIxMDAwMS45NjNaMASAAgH0oIHQpIHN\r\n# MIHKMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH\r\n# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQL\r\n# ExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMSYwJAYDVQQLEx1UaGFsZXMg\r\n# VFNTIEVTTjpFQUNFLUUzMTYtQzkxRDElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt\r\n# U3RhbXAgU2VydmljZaCCEVQwggcMMIIE9KADAgECAhMzAAABmsB1osQhbT6FAAEA\r\n# AAGaMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo\r\n# aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y\r\n# cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw\r\n# MB4XDTIxMTIwMjE5MDUxN1oXDTIzMDIyODE5MDUxN1owgcoxCzAJBgNVBAYTAlVT\r\n# MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK\r\n# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVy\r\n# aWNhIE9wZXJhdGlvbnMxJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNOOkVBQ0UtRTMx\r\n# Ni1DOTFEMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIIC\r\n# IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA2nIGrCort2RhFP5q+gObfaFw\r\n# IG7AiatDZzrvueM2T7fWP7axB0k5aRNp+I7muFZ2nROLH9jYPMX1MQ0DzuFW/91B\r\n# 4YXR4gpy6FCLFt8LRNjj8xxYQHFDc8bkqZOuu6JuKPxnGj5cIiDeGXQ8Ujs+qI0j\r\n# U/Ws7Cl8EBQHLuHPbbL14rpffbInwt7NnRBCdPwYch4iQMLHFODdp5tVA3+LjAHw\r\n# tQe0gUGS99LLD8olI1O4CIo69SEZQQHQWJoskdBe0Sb88vnYsI5tCLI93/G7FSKv\r\n# YGZFFscRZCmS3wcpXhKOATJkTGRPfgH06a0J3upnI7VQHQS0Sl714y0lz0eoeeKb\r\n# bbEoSmldyD+g6em10X9hm9gn3VUsbctxxwFMmV7hcILiFdjlt4Bd5BUCt7i+kGbz\r\n# fGuigdIbaNOlffDrXstTkzr59ZkZwL1buFo/H9XXPvXDj3T4LRc+HHd+5kUTxJAH\r\n# V9mGnk4KXDRMWvowmzkjfvlbTUnMcLuAIz6E30I7kPi9afEjGX4IE/JIWl2llmfb\r\n# y7zuzyMCGeG9kit/15lqZNAJmk4WuUBtH7ubr3eGGf8S7iP5IsB1nE8pL4gGTpcJ\r\n# K57KGGSSdN0bCAFr+lB52IwCPBt1IAhRZQJtJ4LkN6yF+eKZro0vN5YK5tWKmy9i\r\n# 65YZovfDJNpLQhwlykcCAwEAAaOCATYwggEyMB0GA1UdDgQWBBRftp5Z8JzbUeml\r\n# Wb0KlcitNivRcDAfBgNVHSMEGDAWgBSfpxVdAF5iXYP05dJlpxtTNRnpcjBfBgNV\r\n# HR8EWDBWMFSgUqBQhk5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2Ny\r\n# bC9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcmwwbAYI\r\n# KwYBBQUHAQEEYDBeMFwGCCsGAQUFBzAChlBodHRwOi8vd3d3Lm1pY3Jvc29mdC5j\r\n# b20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAy\r\n# MDEwKDEpLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMIMA0G\r\n# CSqGSIb3DQEBCwUAA4ICAQAAE7uHzEbUR9tPpzcxgFxcXVxKUT032zNCyQ3jXuEA\r\n# sY9BTPsKyXbulCqzNsELjt9VA3EOJ61CQXvNTeltkbxGvMTV42ztKszYrcFHzlS3\r\n# maeh1RnDU7WBDALyvZP/9HWgRcW6dOAczGiMmh0cu8vyv82fXJBMO4xfVbCapa8K\r\n# pMfR6iPyAbAqSXZU7SgZf/i0Ww/LVr8OhQ60pL/yA4inGqzxNAVOv/2xV72ef4e3\r\n# YhNd3ar+Qz1OSp+PfR71DgHBxt9YK/0yTxH7aqiuNHX6QftWwT0swHn+fKycUSVz\r\n# SeutRmzmeXuuBLsiEL9FaOWabWlmYn7UOaYJs7WmQrjSCL8TxwsryAI5kn0bl+1M\r\n# pHtJNva0k67kbAVSLInxt/YJXbG8ozr5Aze0t6SbU8CVdE6AuFVoNNJKbp5O9jzk\r\n# bqd9WoVvfX1N48QYdnx44nn42VGtPHf50EHS1gs2nbbaZGbwoB/3XPDLbNgsK3MQ\r\n# j2eafVbhnKshYStiOj0tDzpzLn+9Ed5a5eWPO3TvH+Cr/N25IauYPiK2OSry3CBB\r\n# EeZLebrqK6VsyZgTRgfutjlTTM/dmCRZfy7fjb5BhU7hmcvekyzD3S3KzUqTxlea\r\n# h6px5a/8FM/VAFYkyiQK70m75P7IlO5otvaKkcW9GoQeKGFTzbr+3HB0wRqjTRqJ\r\n# eDCCB3EwggVZoAMCAQICEzMAAAAVxedrngKbSZkAAAAAABUwDQYJKoZIhvcNAQEL\r\n# BQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH\r\n# EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNV\r\n# BAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDEwMB4X\r\n# DTIxMDkzMDE4MjIyNVoXDTMwMDkzMDE4MzIyNVowfDELMAkGA1UEBhMCVVMxEzAR\r\n# BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p\r\n# Y3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3Rh\r\n# bXAgUENBIDIwMTAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDk4aZM\r\n# 57RyIQt5osvXJHm9DtWC0/3unAcH0qlsTnXIyjVX9gF/bErg4r25PhdgM/9cT8dm\r\n# 95VTcVrifkpa/rg2Z4VGIwy1jRPPdzLAEBjoYH1qUoNEt6aORmsHFPPFdvWGUNzB\r\n# RMhxXFExN6AKOG6N7dcP2CZTfDlhAnrEqv1yaa8dq6z2Nr41JmTamDu6GnszrYBb\r\n# fowQHJ1S/rboYiXcag/PXfT+jlPP1uyFVk3v3byNpOORj7I5LFGc6XBpDco2LXCO\r\n# Mcg1KL3jtIckw+DJj361VI/c+gVVmG1oO5pGve2krnopN6zL64NF50ZuyjLVwIYw\r\n# XE8s4mKyzbnijYjklqwBSru+cakXW2dg3viSkR4dPf0gz3N9QZpGdc3EXzTdEonW\r\n# /aUgfX782Z5F37ZyL9t9X4C626p+Nuw2TPYrbqgSUei/BQOj0XOmTTd0lBw0gg/w\r\n# EPK3Rxjtp+iZfD9M269ewvPV2HM9Q07BMzlMjgK8QmguEOqEUUbi0b1qGFphAXPK\r\n# Z6Je1yh2AuIzGHLXpyDwwvoSCtdjbwzJNmSLW6CmgyFdXzB0kZSU2LlQ+QuJYfM2\r\n# BjUYhEfb3BvR/bLUHMVr9lxSUV0S2yW6r1AFemzFER1y7435UsSFF5PAPBXbGjfH\r\n# CBUYP3irRbb1Hode2o+eFnJpxq57t7c+auIurQIDAQABo4IB3TCCAdkwEgYJKwYB\r\n# BAGCNxUBBAUCAwEAATAjBgkrBgEEAYI3FQIEFgQUKqdS/mTEmr6CkTxGNSnPEP8v\r\n# BO4wHQYDVR0OBBYEFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMFwGA1UdIARVMFMwUQYM\r\n# KwYBBAGCN0yDfQEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0\r\n# LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTATBgNVHSUEDDAKBggrBgEF\r\n# BQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD\r\n# VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvXzpoYxDBW\r\n# BgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny\r\n# bC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYIKwYBBQUH\r\n# AQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp\r\n# L2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDANBgkqhkiG9w0BAQsF\r\n# AAOCAgEAnVV9/Cqt4SwfZwExJFvhnnJL/Klv6lwUtj5OR2R4sQaTlz0xM7U518Jx\r\n# Nj/aZGx80HU5bbsPMeTCj/ts0aGUGCLu6WZnOlNN3Zi6th542DYunKmCVgADsAW+\r\n# iehp4LoJ7nvfam++Kctu2D9IdQHZGN5tggz1bSNU5HhTdSRXud2f8449xvNo32X2\r\n# pFaq95W2KFUn0CS9QKC/GbYSEhFdPSfgQJY4rPf5KYnDvBewVIVCs/wMnosZiefw\r\n# C2qBwoEZQhlSdYo2wh3DYXMuLGt7bj8sCXgU6ZGyqVvfSaN0DLzskYDSPeZKPmY7\r\n# T7uG+jIa2Zb0j/aRAfbOxnT99kxybxCrdTDFNLB62FD+CljdQDzHVG2dY3RILLFO\r\n# Ry3BFARxv2T5JL5zbcqOCb2zAVdJVGTZc9d/HltEAY5aGZFrDZ+kKNxnGSgkujhL\r\n# mm77IVRrakURR6nxt67I6IleT53S0Ex2tVdUCbFpAUR+fKFhbHP+CrvsQWY9af3L\r\n# wUFJfn6Tvsv4O+S3Fb+0zj6lMVGEvL8CwYKiexcdFYmNcP7ntdAoGokLjzbaukz5\r\n# m/8K6TT4JDVnK+ANuOaMmdbhIurwJ0I9JZTmdHRbatGePu1+oDEzfbzL6Xu/OHBE\r\n# 0ZDxyKs6ijoIYn/ZcGNTTY3ugm2lBRDBcQZqELQdVTNYs6FwZvKhggLLMIICNAIB\r\n# ATCB+KGB0KSBzTCByjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x\r\n# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv\r\n# bjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEmMCQGA1UE\r\n# CxMdVGhhbGVzIFRTUyBFU046RUFDRS1FMzE2LUM5MUQxJTAjBgNVBAMTHE1pY3Jv\r\n# c29mdCBUaW1lLVN0YW1wIFNlcnZpY2WiIwoBATAHBgUrDgMCGgMVAAG6rjJ1Ampv\r\n# 5uzsdVL/xjbNY5rvoIGDMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldh\r\n# c2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBD\r\n# b3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIw\r\n# MTAwDQYJKoZIhvcNAQEFBQACBQDmaULZMCIYDzIwMjIwNzAxMTc1NDMzWhgPMjAy\r\n# MjA3MDIxNzU0MzNaMHQwOgYKKwYBBAGEWQoEATEsMCowCgIFAOZpQtkCAQAwBwIB\r\n# AAICBV0wBwIBAAICEd8wCgIFAOZqlFkCAQAwNgYKKwYBBAGEWQoEAjEoMCYwDAYK\r\n# KwYBBAGEWQoDAqAKMAgCAQACAwehIKEKMAgCAQACAwGGoDANBgkqhkiG9w0BAQUF\r\n# AAOBgQBE0fx25fV4T83pZxB4CQQfrko37LMB2A+I//kXKtd0XKnuTaaJ9YQIdTEd\r\n# 1QWiTcnM/TW+yNCfE5QNhZFzxVxS5WXksZaiA0wLTqJfA+jm2Mi0FfZefFr4L6DU\r\n# pyKjEWvhlLiUfperOIuvHm37XN0f3LDOHWx+6CbZ1xT+jNePMzGCBA0wggQJAgEB\r\n# MIGTMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH\r\n# EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNV\r\n# BAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAABmsB1osQhbT6F\r\n# AAEAAAGaMA0GCWCGSAFlAwQCAQUAoIIBSjAaBgkqhkiG9w0BCQMxDQYLKoZIhvcN\r\n# AQkQAQQwLwYJKoZIhvcNAQkEMSIEIF2O7hc1ZhwoL1uHKtS6plCa34qF+9dG3vi7\r\n# tPHcCrGRMIH6BgsqhkiG9w0BCRACLzGB6jCB5zCB5DCBvQQgAU5A4zgRFH2Z5YoC\r\n# Yi+d/S8fp7K/zRVU5yhV9N9IjWAwgZgwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEG\r\n# A1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWlj\r\n# cm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFt\r\n# cCBQQ0EgMjAxMAITMwAAAZrAdaLEIW0+hQABAAABmjAiBCDlYijfDa/nMtdfyLez\r\n# 76eMSHmBEDD3QIEOBB5OFeXcFjANBgkqhkiG9w0BAQsFAASCAgAJWWMLeusd6nZn\r\n# 4Q8YPFoh1x2D0C3ApP00erz4ctpJSw2NSvnCQgSKrGdzehx62PNh/yYbmUqYd6Gp\r\n# LP3ErMpA56cVVekiF0ECBa5llP4a1UTpEcO0eZnApz93o7UJ8g0RDspFydd459dS\r\n# 8389MfETeVGw4WiD3FV97IawqrZ2bpMzAn7nhD2s8oI36NZ6fhbykA68nzLGJXdj\r\n# HmmoG1DSJIIgHL0IR5u8OY7LarpcJQUGcMH09bN29J8J2Z2Uzrz52Q7t4LVGb9Oj\r\n# kT6LnOYe+zGtFZAPWm20xFHAHnDa6GkemWGGmm6kZHdBTsJSN7TmBbKEcT9k9AkJ\r\n# yv5N7grvD6YcpOE949BRaGzGQ26JKJDzUqjJ7VUycWyEq35+QZFTGj3LS4xlgeoA\r\n# 1en1N5dfxGEHVbhIgmfaLYrmq1L5mMZFnXrxQdaj6/6ew1ddxAnq/fcs2EIhZcWm\r\n# htBTC+qsi5WmUxoglCGjj2iFNGs61a9B5yDFVVQaZIk/Mi2hjGINj65XF0r0vuYd\r\n# XDklHpWC0UQe41KckrKEliYTmWQkIMjaraCubRxjpywXFwecO8TDDW6031xVwd0r\r\n# t77jQA1+tAVjzEg5jo3T3woTA73hLZ1qCRHGUZzrpe+wRFrAGZM5eZhTHwqhYTC0\r\n# ym9JZhmcOB5iC6VOR/jxKibZ3kyfgg==\r\n# SIG # End signature block\r\n"
  },
  {
    "path": "src/PowerShell/ExternalModules/PackageManagement/1.4.8.1/PackageManagement.format.ps1xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n\r\n<Configuration>\r\n  <!-- \r\n  *\r\n  * Copyright (c) Microsoft Corporation. All rights reserved.\r\n  * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n  * you may not use this file except in compliance with the License.\r\n  * You may obtain a copy of the License at\r\n  * http://www.apache.org/licenses/LICENSE-2.0\r\n  *\r\n  * Unless required by applicable law or agreed to in writing, software\r\n  * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n  * See the License for the specific language governing permissions and\r\n  * limitations under the License.\r\n  *\r\n  -->\r\n<ViewDefinitions>\r\n  <View>\r\n    <Name>package</Name>\r\n    <ViewSelectedBy>\r\n      <TypeName>Microsoft.PackageManagement.Packaging.SoftwareIdentity</TypeName>\r\n      <TypeName>Deserialized.Microsoft.PackageManagement.Packaging.SoftwareIdentity</TypeName>\r\n    </ViewSelectedBy>\r\n    <TableControl>\r\n      <TableHeaders>\r\n        <TableColumnHeader>\r\n          <Width>30</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n          <Width>16</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n          <Width>16</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n        </TableColumnHeader>\r\n      </TableHeaders>\r\n      <TableRowEntries>\r\n        <TableRowEntry>\r\n          <TableColumnItems>\r\n            <TableColumnItem>\r\n              <PropertyName>Name</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Version</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Source</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Summary</PropertyName>\r\n            </TableColumnItem>\r\n          </TableColumnItems>\r\n        </TableRowEntry>\r\n      </TableRowEntries>\r\n    </TableControl>\r\n  </View>\r\n\r\n  <View>\r\n    <Name>GetPackage</Name>\r\n    <ViewSelectedBy>\r\n      <TypeName>Microsoft.PackageManagement.Packaging.SoftwareIdentity#GetPackage</TypeName>\r\n      <TypeName>Deserialized.Microsoft.PackageManagement.Packaging.SoftwareIdentity#GetPackage</TypeName>\r\n    </ViewSelectedBy>\r\n    <TableControl>\r\n      <TableHeaders>\r\n        <TableColumnHeader>\r\n          <Width>30</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n          <Width>16</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n          <Width>32</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n        </TableColumnHeader>\r\n      </TableHeaders>\r\n      <TableRowEntries>\r\n        <TableRowEntry>\r\n          <TableColumnItems>\r\n            <TableColumnItem>\r\n              <PropertyName>Name</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Version</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Source</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>ProviderName</PropertyName>\r\n            </TableColumnItem>\r\n          </TableColumnItems>\r\n        </TableRowEntry>\r\n      </TableRowEntries>\r\n    </TableControl>\r\n  </View>\r\n\r\n   <View>\r\n    <Name>packageWithLongSourceName</Name>\r\n    <ViewSelectedBy>\r\n      <TypeName>Microsoft.PackageManagement.Packaging.SoftwareIdentity#DisplayLongSourceName</TypeName>\r\n      <TypeName>Deserialized.Microsoft.PackageManagement.Packaging.SoftwareIdentity#DisplayLongSourceName</TypeName>\r\n    </ViewSelectedBy>\r\n    <TableControl>\r\n      <TableHeaders>\r\n        <TableColumnHeader>\r\n          <Width>30</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n          <Width>16</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n          <Width>32</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n        </TableColumnHeader>\r\n      </TableHeaders>\r\n      <TableRowEntries>\r\n        <TableRowEntry>\r\n          <TableColumnItems>\r\n            <TableColumnItem>\r\n              <PropertyName>Name</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Version</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Source</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Summary</PropertyName>\r\n            </TableColumnItem>\r\n          </TableColumnItems>\r\n        </TableRowEntry>\r\n      </TableRowEntries>\r\n    </TableControl>\r\n  </View>\r\n\r\n  <View>\r\n    <Name>packageWithLongSourceNameAndCulture</Name>\r\n    <ViewSelectedBy>\r\n      <TypeName>Microsoft.PackageManagement.Packaging.SoftwareIdentity#DisplayLongSourceName#DisplayCulture</TypeName>\r\n      <TypeName>Deserialized.Microsoft.PackageManagement.Packaging.SoftwareIdentity#DisplayLongSourceName#DisplayCulture</TypeName>\r\n    </ViewSelectedBy>\r\n    <TableControl>\r\n      <TableHeaders>\r\n        <TableColumnHeader>\r\n          <Width>30</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n          <Width>16</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n          <Width>16</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n          <Width>32</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n        </TableColumnHeader>\r\n      </TableHeaders>\r\n      <TableRowEntries>\r\n        <TableRowEntry>\r\n          <TableColumnItems>\r\n            <TableColumnItem>\r\n              <PropertyName>Name</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Version</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Culture</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Source</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Summary</PropertyName>\r\n            </TableColumnItem>\r\n          </TableColumnItems>\r\n        </TableRowEntry>\r\n      </TableRowEntries>\r\n    </TableControl>\r\n  </View>\r\n\r\n  <View>\r\n    <Name>packageWithLongSourceNameAndName</Name>\r\n    <ViewSelectedBy>\r\n      <TypeName>Microsoft.PackageManagement.Packaging.SoftwareIdentity#DisplayLongSourceName#DisplayLongName</TypeName>\r\n      <TypeName>Deserialized.Microsoft.PackageManagement.Packaging.SoftwareIdentity#DisplayLongSourceName#DisplayLongName</TypeName>\r\n    </ViewSelectedBy>\r\n    <TableControl>\r\n      <TableHeaders>\r\n        <TableColumnHeader>\r\n          <Width>45</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n          <Width>16</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n          <Width>32</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n        </TableColumnHeader>\r\n      </TableHeaders>\r\n      <TableRowEntries>\r\n        <TableRowEntry>\r\n          <TableColumnItems>\r\n            <TableColumnItem>\r\n              <PropertyName>Name</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Version</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Source</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Summary</PropertyName>\r\n            </TableColumnItem>\r\n          </TableColumnItems>\r\n        </TableRowEntry>\r\n      </TableRowEntries>\r\n    </TableControl>\r\n  </View>\r\n  <View>\r\n    <Name>packageWithLongSourceNameAndCultureAndName</Name>\r\n    <ViewSelectedBy>\r\n      <TypeName>Microsoft.PackageManagement.Packaging.SoftwareIdentity#DisplayLongSourceName#DisplayCulture#DisplayLongName</TypeName>\r\n      <TypeName>Deserialized.Microsoft.PackageManagement.Packaging.SoftwareIdentity#DisplayLongSourceName#DisplayCulture#DisplayLongName</TypeName>\r\n    </ViewSelectedBy>\r\n    <TableControl>\r\n      <TableHeaders>\r\n        <TableColumnHeader>\r\n          <Width>42</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n          <Width>16</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n          <Width>16</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n          <Width>24</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n        </TableColumnHeader>\r\n      </TableHeaders>\r\n      <TableRowEntries>\r\n        <TableRowEntry>\r\n          <TableColumnItems>\r\n            <TableColumnItem>\r\n              <PropertyName>Name</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Version</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Culture</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Source</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Summary</PropertyName>\r\n            </TableColumnItem>\r\n          </TableColumnItems>\r\n        </TableRowEntry>\r\n      </TableRowEntries>\r\n    </TableControl>\r\n  </View>\r\n  \r\n  <View>\r\n    <Name>PackageWithCulture</Name>\r\n    <ViewSelectedBy>\r\n      <TypeName>Microsoft.PackageManagement.Packaging.SoftwareIdentity#DisplayCulture</TypeName>\r\n      <TypeName>Deserialized.Microsoft.PackageManagement.Packaging.SoftwareIdentity#DisplayCulture</TypeName>\r\n    </ViewSelectedBy>\r\n    <TableControl>\r\n      <TableHeaders>\r\n        <TableColumnHeader>\r\n          <Width>30</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n          <Width>16</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n          <Width>16</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n          <Width>16</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n        </TableColumnHeader>\r\n      </TableHeaders>\r\n      <TableRowEntries>\r\n        <TableRowEntry>\r\n          <TableColumnItems>\r\n            <TableColumnItem>\r\n              <PropertyName>Name</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Version</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Culture</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Source</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Summary</PropertyName>\r\n            </TableColumnItem>\r\n          </TableColumnItems>\r\n        </TableRowEntry>\r\n      </TableRowEntries>\r\n    </TableControl>\r\n  </View>\r\n  <View>\r\n    <Name>PackageWithLongName</Name>\r\n    <ViewSelectedBy>\r\n      <TypeName>Microsoft.PackageManagement.Packaging.SoftwareIdentity#DisplayLongName</TypeName>\r\n      <TypeName>Deserialized.Microsoft.PackageManagement.Packaging.SoftwareIdentity#DisplayLongName</TypeName>\r\n    </ViewSelectedBy>\r\n    <TableControl>\r\n      <TableHeaders>\r\n        <TableColumnHeader>\r\n          <Width>52</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n          <Width>16</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n          <Width>16</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n        </TableColumnHeader>\r\n      </TableHeaders>\r\n      <TableRowEntries>\r\n        <TableRowEntry>\r\n          <TableColumnItems>\r\n            <TableColumnItem>\r\n              <PropertyName>Name</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Version</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Source</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Summary</PropertyName>\r\n            </TableColumnItem>\r\n          </TableColumnItems>\r\n        </TableRowEntry>\r\n      </TableRowEntries>\r\n    </TableControl>\r\n  </View>\r\n  <View>\r\n    <Name>PackageWithCultureAndLongName</Name>\r\n    <ViewSelectedBy>\r\n      <TypeName>Microsoft.PackageManagement.Packaging.SoftwareIdentity#DisplayCulture#DisplayLongName</TypeName>\r\n      <TypeName>Deserialized.Microsoft.PackageManagement.Packaging.SoftwareIdentity#DisplayCulture#DisplayLongName</TypeName>\r\n    </ViewSelectedBy>\r\n    <TableControl>\r\n      <TableHeaders>\r\n        <TableColumnHeader>\r\n          <Width>52</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n          <Width>16</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n          <Width>16</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n          <Width>16</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n        </TableColumnHeader>\r\n      </TableHeaders>\r\n      <TableRowEntries>\r\n        <TableRowEntry>\r\n          <TableColumnItems>\r\n            <TableColumnItem>\r\n              <PropertyName>Name</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Version</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Culture</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Source</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Summary</PropertyName>\r\n            </TableColumnItem>\r\n          </TableColumnItems>\r\n        </TableRowEntry>\r\n      </TableRowEntries>\r\n    </TableControl>\r\n  </View>\r\n  <View>\r\n    <Name>PackageSource</Name>\r\n    <ViewSelectedBy>\r\n      <TypeName>Microsoft.PackageManagement.Packaging.PackageSource</TypeName>\r\n      <TypeName>Deserialized.Microsoft.PackageManagement.Packaging.PackageSource</TypeName>\r\n    </ViewSelectedBy>\r\n    <TableControl>\r\n      <TableHeaders>\r\n        <TableColumnHeader>\r\n          <Width>32</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n          <Width>16</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n          <Width>10</Width>\r\n        </TableColumnHeader>      \r\n        <TableColumnHeader>\r\n        </TableColumnHeader>\r\n        </TableHeaders>\r\n        <TableRowEntries>\r\n          <TableRowEntry>\r\n            <TableColumnItems>\r\n              <TableColumnItem>\r\n                <PropertyName>Name</PropertyName>\r\n              </TableColumnItem>\r\n              <TableColumnItem>\r\n                <PropertyName>ProviderName</PropertyName>\r\n              </TableColumnItem>\r\n              <TableColumnItem>\r\n                <PropertyName>IsTrusted</PropertyName>\r\n              </TableColumnItem>\r\n              <TableColumnItem>\r\n                <PropertyName>Location</PropertyName>\r\n              </TableColumnItem>\r\n            </TableColumnItems>\r\n          </TableRowEntry>\r\n        </TableRowEntries>\r\n      </TableControl>\r\n    </View>\r\n\r\n  <View>\r\n    <Name>PackageProvider</Name>\r\n    <ViewSelectedBy>\r\n      <TypeName>Microsoft.PackageManagement.Implementation.PackageProvider</TypeName>\r\n      <TypeName>Deserialized.Microsoft.PackageManagement.Implementation.PackageProvider</TypeName>\r\n    </ViewSelectedBy>\r\n    <TableControl>\r\n      <TableHeaders>\r\n        <TableColumnHeader>\r\n          <Width>24</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n          <Width>16</Width>\r\n        </TableColumnHeader>\r\n        <TableColumnHeader>\r\n\t  <Label>DynamicOptions</Label>\r\n        </TableColumnHeader>\r\n      </TableHeaders>\r\n      <TableRowEntries>\r\n        <TableRowEntry>         \r\n          <TableColumnItems>\r\n            <TableColumnItem>\r\n              <PropertyName>Name</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <PropertyName>Version</PropertyName>\r\n            </TableColumnItem>\r\n            <TableColumnItem>\r\n              <ScriptBlock>$options = $_.DynamicOptions.Name | select-object -unique; $options -join \", \"</ScriptBlock>\r\n            </TableColumnItem>\r\n          </TableColumnItems>\r\n        </TableRowEntry>\r\n      </TableRowEntries>\r\n    </TableControl>\r\n  </View>\r\n\r\n\r\n</ViewDefinitions>\r\n</Configuration>\r\n<!-- SIG # Begin signature block -->\r\n<!-- MIInsQYJKoZIhvcNAQcCoIInojCCJ54CAQExDzANBglghkgBZQMEAgEFADB5Bgor -->\r\n<!-- BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG -->\r\n<!-- KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDPNAbag0XHNsTX -->\r\n<!-- fSzELY7uw4DkrTl94u/UCF0hnuajK6CCDYUwggYDMIID66ADAgECAhMzAAACU+OD -->\r\n<!-- 3pbexW7MAAAAAAJTMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD -->\r\n<!-- VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy -->\r\n<!-- b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p -->\r\n<!-- bmcgUENBIDIwMTEwHhcNMjEwOTAyMTgzMzAwWhcNMjIwOTAxMTgzMzAwWjB0MQsw -->\r\n<!-- CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u -->\r\n<!-- ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy -->\r\n<!-- b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -->\r\n<!-- AQDLhxHwq3OhH+4J+SX4qS/VQG8HybccH7tnG+BUqrXubfGuDFYPZ29uCuHfQlO1 -->\r\n<!-- lygLgMpJ4Geh6/6poQ5VkDKfVssn6aA1PCzIh8iOPMQ9Mju3sLF9Sn+Pzuaie4BN -->\r\n<!-- rp0MuZLDEXgVYx2WNjmzqcxC7dY9SC3znOh5qUy2vnmWygC7b9kj0d3JrGtjc5q5 -->\r\n<!-- 0WfV3WLXAQHkeRROsJFBZfXFGoSvRljFFUAjU/zdhP92P+1JiRRRikVy/sqIhMDY -->\r\n<!-- +7tVdzlE2fwnKOv9LShgKeyEevgMl0B1Fq7E2YeBZKF6KlhmYi9CE1350cnTUoU4 -->\r\n<!-- YpQSnZo0YAnaenREDLfFGKTdAgMBAAGjggGCMIIBfjAfBgNVHSUEGDAWBgorBgEE -->\r\n<!-- AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUlZpLWIccXoxessA/DRbe26glhEMw -->\r\n<!-- VAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh -->\r\n<!-- dGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjMwMDEyKzQ2NzU5ODAfBgNVHSMEGDAW -->\r\n<!-- gBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8v -->\r\n<!-- d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIw -->\r\n<!-- MTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDov -->\r\n<!-- L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDEx -->\r\n<!-- XzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB -->\r\n<!-- AKVY+yKcJVVxf9W2vNkL5ufjOpqcvVOOOdVyjy1dmsO4O8khWhqrecdVZp09adOZ -->\r\n<!-- 8kcMtQ0U+oKx484Jg11cc4Ck0FyOBnp+YIFbOxYCqzaqMcaRAgy48n1tbz/EFYiF -->\r\n<!-- zJmMiGnlgWFCStONPvQOBD2y/Ej3qBRnGy9EZS1EDlRN/8l5Rs3HX2lZhd9WuukR -->\r\n<!-- bUk83U99TPJyo12cU0Mb3n1HJv/JZpwSyqb3O0o4HExVJSkwN1m42fSVIVtXVVSa -->\r\n<!-- YZiVpv32GoD/dyAS/gyplfR6FI3RnCOomzlycSqoz0zBCPFiCMhVhQ6qn+J0GhgR -->\r\n<!-- BJvGKizw+5lTfnBFoqKZJDROz+uGDl9tw6JvnVqAZKGrWv/CsYaegaPePFrAVSxA -->\r\n<!-- yUwOFTkAqtNC8uAee+rv2V5xLw8FfpKJ5yKiMKnCKrIaFQDr5AZ7f2ejGGDf+8Tz -->\r\n<!-- OiK1AgBvOW3iTEEa/at8Z4+s1CmnEAkAi0cLjB72CJedU1LAswdOCWM2MDIZVo9j -->\r\n<!-- 0T74OkJLTjPd3WNEyw0rBXTyhlbYQsYt7ElT2l2TTlF5EmpVixGtj4ChNjWoKr9y -->\r\n<!-- TAqtadd2Ym5FNB792GzwNwa631BPCgBJmcRpFKXt0VEQq7UXVNYBiBRd+x4yvjqq -->\r\n<!-- 5aF7XC5nXCgjbCk7IXwmOphNuNDNiRq83Ejjnc7mxrJGMIIHejCCBWKgAwIBAgIK -->\r\n<!-- YQ6Q0gAAAAAAAzANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNV -->\r\n<!-- BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv -->\r\n<!-- c29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlm -->\r\n<!-- aWNhdGUgQXV0aG9yaXR5IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEw -->\r\n<!-- OTA5WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE -->\r\n<!-- BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYD -->\r\n<!-- VQQDEx9NaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG -->\r\n<!-- 9w0BAQEFAAOCAg8AMIICCgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+la -->\r\n<!-- UKq4BjgaBEm6f8MMHt03a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc -->\r\n<!-- 6Whe0t+bU7IKLMOv2akrrnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4D -->\r\n<!-- dato88tt8zpcoRb0RrrgOGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+ -->\r\n<!-- lD3v++MrWhAfTVYoonpy4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nk -->\r\n<!-- kDstrjNYxbc+/jLTswM9sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6 -->\r\n<!-- A4aN91/w0FK/jJSHvMAhdCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmd -->\r\n<!-- X4jiJV3TIUs+UsS1Vz8kA/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL -->\r\n<!-- 5zmhD+kjSbwYuER8ReTBw3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zd -->\r\n<!-- sGbiwZeBe+3W7UvnSSmnEyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3 -->\r\n<!-- T8HhhUSJxAlMxdSlQy90lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS -->\r\n<!-- 4NaIjAsCAwEAAaOCAe0wggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRI -->\r\n<!-- bmTlUAXTgqoXNzcitW2oynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAL -->\r\n<!-- BgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBD -->\r\n<!-- uRQFTuHqp8cx0SOJNDBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jv -->\r\n<!-- c29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf -->\r\n<!-- MDNfMjIuY3JsMF4GCCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3 -->\r\n<!-- dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf -->\r\n<!-- MDNfMjIuY3J0MIGfBgNVHSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEF -->\r\n<!-- BQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1h -->\r\n<!-- cnljcHMuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkA -->\r\n<!-- YwB5AF8AcwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn -->\r\n<!-- 8oalmOBUeRou09h0ZyKbC5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7 -->\r\n<!-- v0epo/Np22O/IjWll11lhJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0b -->\r\n<!-- pdS1HXeUOeLpZMlEPXh6I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/ -->\r\n<!-- KmtYSWMfCWluWpiW5IP0wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvy -->\r\n<!-- CInWH8MyGOLwxS3OW560STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBp -->\r\n<!-- mLJZiWhub6e3dMNABQamASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJi -->\r\n<!-- hsMdYzaXht/a8/jyFqGaJ+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYb -->\r\n<!-- BL7fQccOKO7eZS/sl/ahXJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbS -->\r\n<!-- oqKfenoi+kiVH6v7RyOA9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sL -->\r\n<!-- gOppO6/8MO0ETI7f33VtY5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtX -->\r\n<!-- cVZOSEXAQsmbdlsKgEhr/Xmfwb1tbWrJUnMTDXpQzTGCGYIwghl+AgEBMIGVMH4x -->\r\n<!-- CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt -->\r\n<!-- b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p -->\r\n<!-- Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAAJT44Pelt7FbswAAAAA -->\r\n<!-- AlMwDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw -->\r\n<!-- HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEINz4 -->\r\n<!-- jGTwSIrypQ6y68jBIWu9n1aXp6rTDVBbE3XDkWX9MEIGCisGAQQBgjcCAQwxNDAy -->\r\n<!-- oBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5j -->\r\n<!-- b20wDQYJKoZIhvcNAQEBBQAEggEABobqAFSMr84oMI72vXmhCwnxO3QZcjKZvkc7 -->\r\n<!-- iDnjT1ZpKF3y2+g6lJdlOVM4RJpi6MmquQPF2bzbB8l/re2dOnfl6IpqefehIm6W -->\r\n<!-- ooE5J3wxolU75UxT7dC5oalWQFgA/lDetSdl1hvjlmeA1XW6AwCEPzh7wH0e7Lqn -->\r\n<!-- jlh9U77k+EHmElHF8grhYr7FaF5vdjH9XQ5V+p0rspn4HEDRsaoq+Da4zd7yr+ff -->\r\n<!-- UI5BaureXEncMIWxU/PWZ2CWk2JulbGRUK7X8/HNsYD/pCfc8Gu8kl/f508ABZsg -->\r\n<!-- agLywxEF80tF6/NxxOWXI/B4MiyVWny+udGGXfKx4gvCi8Cg8KGCFwwwghcIBgor -->\r\n<!-- BgEEAYI3AwMBMYIW+DCCFvQGCSqGSIb3DQEHAqCCFuUwghbhAgEDMQ8wDQYJYIZI -->\r\n<!-- AWUDBAIBBQAwggFVBgsqhkiG9w0BCRABBKCCAUQEggFAMIIBPAIBAQYKKwYBBAGE -->\r\n<!-- WQoDATAxMA0GCWCGSAFlAwQCAQUABCCTowV8zD+eLJHyKuqJ2lrfJMbbN0qGECR2 -->\r\n<!-- jVcqc3i5LAIGYrGiJBRnGBMyMDIyMDcwMTIxMDAwMS42MTJaMASAAgH0oIHUpIHR -->\r\n<!-- MIHOMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH -->\r\n<!-- UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSkwJwYDVQQL -->\r\n<!-- EyBNaWNyb3NvZnQgT3BlcmF0aW9ucyBQdWVydG8gUmljbzEmMCQGA1UECxMdVGhh -->\r\n<!-- bGVzIFRTUyBFU046NDYyRi1FMzE5LTNGMjAxJTAjBgNVBAMTHE1pY3Jvc29mdCBU -->\r\n<!-- aW1lLVN0YW1wIFNlcnZpY2WgghFfMIIHEDCCBPigAwIBAgITMwAAAaQHz+OPo7pv -->\r\n<!-- 1gABAAABpDANBgkqhkiG9w0BAQsFADB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMK -->\r\n<!-- V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0 -->\r\n<!-- IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0Eg -->\r\n<!-- MjAxMDAeFw0yMjAzMDIxODUxMThaFw0yMzA1MTExODUxMThaMIHOMQswCQYDVQQG -->\r\n<!-- EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG -->\r\n<!-- A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSkwJwYDVQQLEyBNaWNyb3NvZnQg -->\r\n<!-- T3BlcmF0aW9ucyBQdWVydG8gUmljbzEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046 -->\r\n<!-- NDYyRi1FMzE5LTNGMjAxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNl -->\r\n<!-- cnZpY2UwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDAR44A+hT8vNT1 -->\r\n<!-- IXDiFRoeGzkmqut+GPk41toTRfQZZ1sSyQhLjIlemBecemEzO09WSzOjZx9MIT8q -->\r\n<!-- Ys921WUZsIBsk1ESn1cjyfPUd1mmfxzL3ACWZwjIC/pjqcRPeIMECQ/6qPFKrjqw -->\r\n<!-- igmP33I3IcVfMjJHyKj+vR51n1tK2rZPiNhmRdiEhckbbxLsSb2nCBQxZEF49x/l -->\r\n<!-- 8vSB8zaqovoOeIkIzgDerN7OvJouq6r+vg/Qz1T4NXr+sKKyNxZWM6zywiLp7G7W -->\r\n<!-- Ld18N2hyjHwPkh/AleIqif3hGVD9bhSU+dDADzUJSMFhEWunHHElQeZjdmIB3/Mw -->\r\n<!-- 1KkFOJNvw1sPteIi5MK4DZX3Wd/Fd8ZsQvZmXPWJ8BXN9sYtHMz8zdeQvMImRCKg -->\r\n<!-- nXcW8IpnPtC7Tymp3UV5NoTH8INF6WWicQ3y04L2I1VOT104AddJoVgAP2KLIGwf -->\r\n<!-- Cs7wMVz56xJ2IN1y1pIAWfpTqx76orM5RQhkAvayj1RTwgrHst+elYX3F5b8ACWr -->\r\n<!-- gJO1dJy1U4MIv+SC8h33xLmWA568emvrJ6g0xy/2akbAeRx6tFwaP4uwVbjF50kl -->\r\n<!-- 5RQqNzp/CDpfCTikOAqyJa4valiWDMbEiArHKLYDg6GDjuJZl5bSjgdJdCAIRF8E -->\r\n<!-- kiiA+UAGvcE6SGoHmtoc4yOklGNVvwIDAQABo4IBNjCCATIwHQYDVR0OBBYEFOLQ -->\r\n<!-- E5+s+AgS9sWUHdI4zekp4yTCMB8GA1UdIwQYMBaAFJ+nFV0AXmJdg/Tl0mWnG1M1 -->\r\n<!-- GelyMF8GA1UdHwRYMFYwVKBSoFCGTmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9w -->\r\n<!-- a2lvcHMvY3JsL01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEp -->\r\n<!-- LmNybDBsBggrBgEFBQcBAQRgMF4wXAYIKwYBBQUHMAKGUGh0dHA6Ly93d3cubWlj -->\r\n<!-- cm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUy -->\r\n<!-- MFBDQSUyMDIwMTAoMSkuY3J0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYB -->\r\n<!-- BQUHAwgwDQYJKoZIhvcNAQELBQADggIBAAlWHFDRDJck7jwwRoYmdVOePLLBeido -->\r\n<!-- PUBJVhG9nGeHS9PuRvO9tf4IkbUz74MUIQxeayQoxxo/JxUqjhPH52M/b4G9mHJW -->\r\n<!-- B75KCllCTg8Y4VkvktOmS0f5w0vOR3gwA9BRnbgAPNEO7xs5Jylto8aDR02++CkB -->\r\n<!-- DFolCtTNjwzfniEj1z4T7nRlRi2yBAJNRqI+VY820LiyoZtk5OGttq5F5HhPfIMj -->\r\n<!-- aIx5QYR22+53sd8xgUwRpFbcLdrne6jdq3KbiYbCf7y/9F2C7cjpO3kkGXX8ntE0 -->\r\n<!-- 9f6o9fIklx7CFw4RzrkyqgYomraKOFJ8JO7hsjNJb9/Gba/mKWo0j/qdDxDER/UX -->\r\n<!-- X6ykZuGx1eQpjkyMwJnOPWGbeNIYZVcJQpRQODPs593Mi5hBsHzag+vd4Q+Vt73K -->\r\n<!-- Z4X98YWW1Vk1aSR9Qjxk5keMuVPZMcMrCvFZXwhUcGFGueuNCrICL9bSYRfS13pl -->\r\n<!-- iDxJ7sPSZ8x2d4ksOXW00l6fR5nTiSM7Dvv7Y0MGVgUhap2smhr92PMNSmIkCUvH -->\r\n<!-- CiYcJ4RoAT28mp/hOQ/U8mPXSpWdxYpLLcDOISmBhFJYN7amlhIpVsGvUmjXrTcY -->\r\n<!-- 0n4Goe/Nqs2400IcA4HOiX9OxdmpNGDJzSRR7AW9TT8O+3YZqPZIvL6yzgfvnehp -->\r\n<!-- tmf4w6QzkrLfMIIHcTCCBVmgAwIBAgITMwAAABXF52ueAptJmQAAAAAAFTANBgkq -->\r\n<!-- hkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x -->\r\n<!-- EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv -->\r\n<!-- bjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 -->\r\n<!-- IDIwMTAwHhcNMjEwOTMwMTgyMjI1WhcNMzAwOTMwMTgzMjI1WjB8MQswCQYDVQQG -->\r\n<!-- EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG -->\r\n<!-- A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQg -->\r\n<!-- VGltZS1TdGFtcCBQQ0EgMjAxMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC -->\r\n<!-- ggIBAOThpkzntHIhC3miy9ckeb0O1YLT/e6cBwfSqWxOdcjKNVf2AX9sSuDivbk+ -->\r\n<!-- F2Az/1xPx2b3lVNxWuJ+Slr+uDZnhUYjDLWNE893MsAQGOhgfWpSg0S3po5GawcU -->\r\n<!-- 88V29YZQ3MFEyHFcUTE3oAo4bo3t1w/YJlN8OWECesSq/XJprx2rrPY2vjUmZNqY -->\r\n<!-- O7oaezOtgFt+jBAcnVL+tuhiJdxqD89d9P6OU8/W7IVWTe/dvI2k45GPsjksUZzp -->\r\n<!-- cGkNyjYtcI4xyDUoveO0hyTD4MmPfrVUj9z6BVWYbWg7mka97aSueik3rMvrg0Xn -->\r\n<!-- Rm7KMtXAhjBcTyziYrLNueKNiOSWrAFKu75xqRdbZ2De+JKRHh09/SDPc31BmkZ1 -->\r\n<!-- zcRfNN0Sidb9pSB9fvzZnkXftnIv231fgLrbqn427DZM9ituqBJR6L8FA6PRc6ZN -->\r\n<!-- N3SUHDSCD/AQ8rdHGO2n6Jl8P0zbr17C89XYcz1DTsEzOUyOArxCaC4Q6oRRRuLR -->\r\n<!-- vWoYWmEBc8pnol7XKHYC4jMYctenIPDC+hIK12NvDMk2ZItboKaDIV1fMHSRlJTY -->\r\n<!-- uVD5C4lh8zYGNRiER9vcG9H9stQcxWv2XFJRXRLbJbqvUAV6bMURHXLvjflSxIUX -->\r\n<!-- k8A8FdsaN8cIFRg/eKtFtvUeh17aj54WcmnGrnu3tz5q4i6tAgMBAAGjggHdMIIB -->\r\n<!-- 2TASBgkrBgEEAYI3FQEEBQIDAQABMCMGCSsGAQQBgjcVAgQWBBQqp1L+ZMSavoKR -->\r\n<!-- PEY1Kc8Q/y8E7jAdBgNVHQ4EFgQUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXAYDVR0g -->\r\n<!-- BFUwUzBRBgwrBgEEAYI3TIN9AQEwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5t -->\r\n<!-- aWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMBMGA1UdJQQM -->\r\n<!-- MAoGCCsGAQUFBwMIMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQE -->\r\n<!-- AwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQ -->\r\n<!-- W9fOmhjEMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNv -->\r\n<!-- bS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBa -->\r\n<!-- BggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0 -->\r\n<!-- LmNvbS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MA0GCSqG -->\r\n<!-- SIb3DQEBCwUAA4ICAQCdVX38Kq3hLB9nATEkW+Geckv8qW/qXBS2Pk5HZHixBpOX -->\r\n<!-- PTEztTnXwnE2P9pkbHzQdTltuw8x5MKP+2zRoZQYIu7pZmc6U03dmLq2HnjYNi6c -->\r\n<!-- qYJWAAOwBb6J6Gngugnue99qb74py27YP0h1AdkY3m2CDPVtI1TkeFN1JFe53Z/z -->\r\n<!-- jj3G82jfZfakVqr3lbYoVSfQJL1AoL8ZthISEV09J+BAljis9/kpicO8F7BUhUKz -->\r\n<!-- /AyeixmJ5/ALaoHCgRlCGVJ1ijbCHcNhcy4sa3tuPywJeBTpkbKpW99Jo3QMvOyR -->\r\n<!-- gNI95ko+ZjtPu4b6MhrZlvSP9pEB9s7GdP32THJvEKt1MMU0sHrYUP4KWN1APMdU -->\r\n<!-- bZ1jdEgssU5HLcEUBHG/ZPkkvnNtyo4JvbMBV0lUZNlz138eW0QBjloZkWsNn6Qo -->\r\n<!-- 3GcZKCS6OEuabvshVGtqRRFHqfG3rsjoiV5PndLQTHa1V1QJsWkBRH58oWFsc/4K -->\r\n<!-- u+xBZj1p/cvBQUl+fpO+y/g75LcVv7TOPqUxUYS8vwLBgqJ7Fx0ViY1w/ue10Cga -->\r\n<!-- iQuPNtq6TPmb/wrpNPgkNWcr4A245oyZ1uEi6vAnQj0llOZ0dFtq0Z4+7X6gMTN9 -->\r\n<!-- vMvpe784cETRkPHIqzqKOghif9lwY1NNje6CbaUFEMFxBmoQtB1VM1izoXBm8qGC -->\r\n<!-- AtIwggI7AgEBMIH8oYHUpIHRMIHOMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz -->\r\n<!-- aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv -->\r\n<!-- cnBvcmF0aW9uMSkwJwYDVQQLEyBNaWNyb3NvZnQgT3BlcmF0aW9ucyBQdWVydG8g -->\r\n<!-- UmljbzEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046NDYyRi1FMzE5LTNGMjAxJTAj -->\r\n<!-- BgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2WiIwoBATAHBgUrDgMC -->\r\n<!-- GgMVADQcKOKTa3xC+g1aPrcPerxiby6foIGDMIGApH4wfDELMAkGA1UEBhMCVVMx -->\r\n<!-- EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT -->\r\n<!-- FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUt -->\r\n<!-- U3RhbXAgUENBIDIwMTAwDQYJKoZIhvcNAQEFBQACBQDmaU8/MCIYDzIwMjIwNzAx -->\r\n<!-- MTQ0NzI3WhgPMjAyMjA3MDIxNDQ3MjdaMHcwPQYKKwYBBAGEWQoEATEvMC0wCgIF -->\r\n<!-- AOZpTz8CAQAwCgIBAAICCNwCAf8wBwIBAAICEp4wCgIFAOZqoL8CAQAwNgYKKwYB -->\r\n<!-- BAGEWQoEAjEoMCYwDAYKKwYBBAGEWQoDAqAKMAgCAQACAwehIKEKMAgCAQACAwGG -->\r\n<!-- oDANBgkqhkiG9w0BAQUFAAOBgQChh1QY1GFw/ekl4Qr+s3lJOVBWDUpw+EfxjUrG -->\r\n<!-- H7ud+AMLNhAxbx7uEfNyNYsi5CnaaXgA2vO00zzDNvaugU/yTYxEm2j0wybQTDfb -->\r\n<!-- BMyUPQB6VhcFgCAOC4CQalIa1F5xOFEYV2P5/OY3Fza/pCGQKiBEDyRG6PfCbmAZ -->\r\n<!-- qvg7cTGCBA0wggQJAgEBMIGTMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo -->\r\n<!-- aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y -->\r\n<!-- cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw -->\r\n<!-- AhMzAAABpAfP44+jum/WAAEAAAGkMA0GCWCGSAFlAwQCAQUAoIIBSjAaBgkqhkiG -->\r\n<!-- 9w0BCQMxDQYLKoZIhvcNAQkQAQQwLwYJKoZIhvcNAQkEMSIEIA5vnFnk/bTzMG85 -->\r\n<!-- tX+eFNaVrpQ9jXrZFiSKizdgwcUtMIH6BgsqhkiG9w0BCRACLzGB6jCB5zCB5DCB -->\r\n<!-- vQQgBfzgoyEmcKTASfDCd1sDAhd6jmuWBxRuieLh42rqefgwgZgwgYCkfjB8MQsw -->\r\n<!-- CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u -->\r\n<!-- ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNy -->\r\n<!-- b3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAaQHz+OPo7pv1gABAAABpDAi -->\r\n<!-- BCBoSzA9nCaw+Pk/XGE5FyHMvYr0QOQne8MeefMn3+/YZjANBgkqhkiG9w0BAQsF -->\r\n<!-- AASCAgANgmStE19Zp4sQ/+2xHwOd+AjjxT+5AB44DJJM/f1yFoURiIt2TxoNY9ng -->\r\n<!-- q/RgPNowH5roTEPgaOVJMS8N5hVYUI0EsTPGQeEeyDcOpWXccskO/3c/nXRvai1S -->\r\n<!-- FiDGj3V7OQnhSldynaLcHmtbBFmxSKxRA/NEkdJnrwV0Gwi2TJ5nASZb7KyFR39F -->\r\n<!-- fTB4/Jferk4x3118yMYVFvVWvh5X83aPNriXMaGIhUWAlvs+1cP1sVJaU2ue01xI -->\r\n<!-- JFtoWdamBV/rpTAkpn/HkILOLlENQ44ti5K/j8vOEDR9ppsUTjtGg9YwnUCAGwgP -->\r\n<!-- t2X6J/2V3Aht/lJzLLUzQGecH8AWcH5iD2ZKmBiALoFjdAI2HYhYIN/T4yD50eO6 -->\r\n<!-- ye8NXmt8xwe5nz76lvsbWNRsFRIXiXZS97w7pIBdlgLuKH5x6P6BE6MaReSbazGc -->\r\n<!-- 4WcGN7Pm8qnRfGgr77p656Bs3RLo/QqJFefBeKg29IHLlVuJTWD/e0mK6/AERK8Z -->\r\n<!-- cjXVRnolfhVWeFnUhN5+uP27qF9eblaJ/Jc54eOJDG6I3L6Oxc2UgeAoutmEli6O -->\r\n<!-- 6j9PnRGJCw+8zH1Mh5CNkQIEHrg21pbRRWoDPrYN6IdrEFJLfSOqNIYhaFs+o0Bd -->\r\n<!-- El/gkr2obdbR2Ru/X/Uw3rw9y1y3Uv7NkzjaLYvHWrkg6dpbIQ== -->\r\n<!-- SIG # End signature block -->\r\n"
  },
  {
    "path": "src/PowerShell/ExternalModules/PackageManagement/1.4.8.1/PackageManagement.psd1",
    "content": "###\r\n# ==++==\r\n#\r\n# Copyright (c) Microsoft Corporation. All rights reserved.\r\n# Licensed under the Apache License, Version 2.0 (the \"License\");\r\n# you may not use this file except in compliance with the License.\r\n# You may obtain a copy of the License at\r\n# http://www.apache.org/licenses/LICENSE-2.0\r\n#\r\n# Unless required by applicable law or agreed to in writing, software\r\n# distributed under the License is distributed on an \"AS IS\" BASIS,\r\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n# See the License for the specific language governing permissions and\r\n# limitations under the License.\r\n#\r\n###\r\n@{\r\n    GUID = \"4ae9fd46-338a-459c-8186-07f910774cb8\"\r\n    Author = \"Microsoft Corporation\"\r\n    CompanyName = \"Microsoft Corporation\"\r\n    Copyright = \"(C) Microsoft Corporation. All rights reserved.\"\r\n    HelpInfoUri = \"https://go.microsoft.com/fwlink/?linkid=2113634\"\r\n    ModuleVersion = \"1.4.8.1\"\r\n    PowerShellVersion = \"3.0\"\r\n    ClrVersion = \"4.0\"\r\n    RootModule = \"PackageManagement.psm1\"\r\n\tDescription = 'PackageManagement (a.k.a. OneGet) is a new way to discover and install software packages from around the web.\r\n It is a manager or multiplexor of existing package managers (also called package providers) that unifies Windows package management with a single Windows PowerShell interface. With PackageManagement, you can do the following.\r\n  - Manage a list of software repositories in which packages can be searched, acquired and installed\r\n  - Discover software packages\r\n  - Seamlessly install, uninstall, and inventory packages from one or more software repositories'\r\n\r\n    CmdletsToExport = @(\r\n        'Find-Package',\r\n        'Get-Package',\r\n        'Get-PackageProvider',\r\n        'Get-PackageSource',\r\n        'Install-Package',\r\n        'Import-PackageProvider'\r\n        'Find-PackageProvider'\r\n        'Install-PackageProvider'\r\n        'Register-PackageSource',\r\n        'Set-PackageSource',\r\n        'Unregister-PackageSource',\r\n        'Uninstall-Package'\r\n        'Save-Package'\r\n\t)\r\n\r\n\tFormatsToProcess  = @('PackageManagement.format.ps1xml')\r\n\r\n\tPrivateData = @{\r\n        PSData = @{\r\n            Tags = @('PackageManagement', 'PSEdition_Core', 'PSEdition_Desktop', 'Linux', 'Mac')\r\n            ProjectUri = 'https://oneget.org'\r\n            ReleaseNotes = @'\r\n## 1.4.8.1\r\n- Update PackageManagement's strong name signing\r\n\r\n## 1.4.8\r\n- Add NuGet as a source when generating nuget.config file for user in the NuGet Provider\r\n\r\n## 1.4.7\r\n- Update security protocol to use TLS 1.2\r\n- Remove catalog file\r\n\r\n## 1.4.6\r\n- Update `HelpInfoUri` to point to the latest content\r\n\r\n## 1.4.5\r\n- Bug fix for deadlock when getting parameters in an event\r\n\r\n## 1.4.4\r\n- Bug fix when installing modules from private feeds\r\n\r\n ## 1.4.3\r\n- Another bug fix when registering repositories with PowerShellGet\r\n\r\n## 1.4.2\r\n- Bug fix for passing credentials from PowerShellGet when registering repositories\r\n\r\n## 1.4.1\r\n- Bug fix for using credential provider installed in Visual Studio\r\n\r\n## 1.4\r\n- Allow credential persistance for registering private repositories and finding or installing packages from those repositories\r\n\r\n## 1.3.2\r\n- Enable bootstrap on PSCore\r\n- Bug fix to run on .NET Core 3.0\r\n\r\n## 1.3.1\r\n- Targets net452 and netstandard2.0 instead of net451, netcoreapp2.0, and netstandard1.6\r\n            \r\n## Previous releases are not included in this Changelog\r\n'@\r\n        }\r\n    }\r\n}\r\n\r\n# SIG # Begin signature block\r\n# MIInoQYJKoZIhvcNAQcCoIInkjCCJ44CAQExDzANBglghkgBZQMEAgEFADB5Bgor\r\n# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG\r\n# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCANw97w1D+bi5LY\r\n# 8ZEuubcA0tI0Z0h+CImFRYop+IIqQaCCDYEwggX/MIID56ADAgECAhMzAAACUosz\r\n# qviV8znbAAAAAAJSMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD\r\n# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p\r\n# bmcgUENBIDIwMTEwHhcNMjEwOTAyMTgzMjU5WhcNMjIwOTAxMTgzMjU5WjB0MQsw\r\n# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u\r\n# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\r\n# AQDQ5M+Ps/X7BNuv5B/0I6uoDwj0NJOo1KrVQqO7ggRXccklyTrWL4xMShjIou2I\r\n# sbYnF67wXzVAq5Om4oe+LfzSDOzjcb6ms00gBo0OQaqwQ1BijyJ7NvDf80I1fW9O\r\n# L76Kt0Wpc2zrGhzcHdb7upPrvxvSNNUvxK3sgw7YTt31410vpEp8yfBEl/hd8ZzA\r\n# v47DCgJ5j1zm295s1RVZHNp6MoiQFVOECm4AwK2l28i+YER1JO4IplTH44uvzX9o\r\n# RnJHaMvWzZEpozPy4jNO2DDqbcNs4zh7AWMhE1PWFVA+CHI/En5nASvCvLmuR/t8\r\n# q4bc8XR8QIZJQSp+2U6m2ldNAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE\r\n# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUNZJaEUGL2Guwt7ZOAu4efEYXedEw\r\n# UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1\r\n# ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDY3NTk3MB8GA1UdIwQYMBaAFEhu\r\n# ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu\r\n# bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w\r\n# Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3\r\n# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx\r\n# MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAFkk3\r\n# uSxkTEBh1NtAl7BivIEsAWdgX1qZ+EdZMYbQKasY6IhSLXRMxF1B3OKdR9K/kccp\r\n# kvNcGl8D7YyYS4mhCUMBR+VLrg3f8PUj38A9V5aiY2/Jok7WZFOAmjPRNNGnyeg7\r\n# l0lTiThFqE+2aOs6+heegqAdelGgNJKRHLWRuhGKuLIw5lkgx9Ky+QvZrn/Ddi8u\r\n# TIgWKp+MGG8xY6PBvvjgt9jQShlnPrZ3UY8Bvwy6rynhXBaV0V0TTL0gEx7eh/K1\r\n# o8Miaru6s/7FyqOLeUS4vTHh9TgBL5DtxCYurXbSBVtL1Fj44+Od/6cmC9mmvrti\r\n# yG709Y3Rd3YdJj2f3GJq7Y7KdWq0QYhatKhBeg4fxjhg0yut2g6aM1mxjNPrE48z\r\n# 6HWCNGu9gMK5ZudldRw4a45Z06Aoktof0CqOyTErvq0YjoE4Xpa0+87T/PVUXNqf\r\n# 7Y+qSU7+9LtLQuMYR4w3cSPjuNusvLf9gBnch5RqM7kaDtYWDgLyB42EfsxeMqwK\r\n# WwA+TVi0HrWRqfSx2olbE56hJcEkMjOSKz3sRuupFCX3UroyYf52L+2iVTrda8XW\r\n# esPG62Mnn3T8AuLfzeJFuAbfOSERx7IFZO92UPoXE1uEjL5skl1yTZB3MubgOA4F\r\n# 8KoRNhviFAEST+nG8c8uIsbZeb08SeYQMqjVEmkwggd6MIIFYqADAgECAgphDpDS\r\n# AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK\r\n# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0\r\n# IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0\r\n# ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla\r\n# MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS\r\n# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT\r\n# H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB\r\n# AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG\r\n# OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S\r\n# 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz\r\n# y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7\r\n# 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u\r\n# M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33\r\n# X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl\r\n# XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP\r\n# 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB\r\n# l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF\r\n# RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM\r\n# CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ\r\n# BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud\r\n# DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO\r\n# 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0\r\n# LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p\r\n# Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB\r\n# FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw\r\n# cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA\r\n# XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY\r\n# 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj\r\n# 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd\r\n# d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ\r\n# Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf\r\n# wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ\r\n# aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j\r\n# NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B\r\n# xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96\r\n# eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7\r\n# r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I\r\n# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIZdjCCGXICAQEwgZUwfjELMAkG\r\n# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx\r\n# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z\r\n# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAlKLM6r4lfM52wAAAAACUjAN\r\n# BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor\r\n# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgiRM0SyHn\r\n# 1V4nqTIo3jXRvJycxDAVVlA2FtX6n3qWqfwwQgYKKwYBBAGCNwIBDDE0MDKgFIAS\r\n# AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN\r\n# BgkqhkiG9w0BAQEFAASCAQCPJRvOZr6CasCkw1WMLfBA6LopbQ7shmcqRwM1eDEa\r\n# 20F09jJVj45dL1xe5F1nEFixo3ejN83D6X9Tm96NfNf5vjqC4AfG8M+4/NGo4Vta\r\n# doFQs1KjdLELNAZZFY7i241P9+ayzDTh5ON5F6BehV4Sex00Kbg0mHB76GhBKUJL\r\n# PqfBbc4KIurIA/Rk1wtXWTuGKdL3+eOVn+DscOEv+0Jjlgzr5UvkFw7tVXhS2Y9z\r\n# dxL8TBqkugR60I+IHB0yiAQwePAqfnVHwPoX0EeldwdwN/B9Iidei1wOa6+ddWr7\r\n# jxz8J4fLzH7k3V3xRDF+z14+6BbOL7dnX3Q7TEDnTIJgoYIXADCCFvwGCisGAQQB\r\n# gjcDAwExghbsMIIW6AYJKoZIhvcNAQcCoIIW2TCCFtUCAQMxDzANBglghkgBZQME\r\n# AgEFADCCAVEGCyqGSIb3DQEJEAEEoIIBQASCATwwggE4AgEBBgorBgEEAYRZCgMB\r\n# MDEwDQYJYIZIAWUDBAIBBQAEIMfYTjqpmIZRLR5Dn8vRnb89EjdawUtU1A43DUFK\r\n# mjO1AgZitJ9dXI0YEzIwMjIwNzAxMjEwMDAwLjQ4N1owBIACAfSggdCkgc0wgcox\r\n# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt\r\n# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1p\r\n# Y3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJjAkBgNVBAsTHVRoYWxlcyBUU1Mg\r\n# RVNOOkU1QTYtRTI3Qy01OTJFMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFt\r\n# cCBTZXJ2aWNloIIRVzCCBwwwggT0oAMCAQICEzMAAAGVt/wN1uM3MSUAAQAAAZUw\r\n# DQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0\r\n# b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh\r\n# dGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwHhcN\r\n# MjExMjAyMTkwNTEyWhcNMjMwMjI4MTkwNTEyWjCByjELMAkGA1UEBhMCVVMxEzAR\r\n# BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p\r\n# Y3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2Eg\r\n# T3BlcmF0aW9uczEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046RTVBNi1FMjdDLTU5\r\n# MkUxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggIiMA0G\r\n# CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCfbUEMZ7ZLOz9aoRCeJL4hhT9Q8JZB\r\n# 2xaVlMNCt3bwhcTI5GLPrt2e93DAsmlqOzw1cFiPPg6S5sLCXz7LbbUQpLha8S4v\r\n# 2qccMtTokEaDQS+QJErnAsl6VSmRvAy0nlj+C/PaZuLb3OzY0ARw7UeCZLpyWPPH\r\n# +k5MdYj6NUDTNoXqbzQHCuPs+fgIoro5y3DHoO077g6Ir2THIx1yfVFEt5zDcFPO\r\n# YMg4yBi4A6Xc3hm9tZ6w849nBvVKwm5YALfH3y/f3n4LnN61b1wzAx3ZCZjf13UK\r\n# bpE7p6DYJrHRB/+pwFjG99TwHH6uXzDeZT6/r6qH7AABwn8fpYc1TmleFY8YRuVz\r\n# zjp9VkPHV8VzvzLL7QK2kteeXLL/Y4lvjL6hzyOmE+1LVD3lEbYho1zCt+F7bU+F\r\n# pjyBfTC4i/wHsptb218YlbkQt1i1B6llmJwVFwCLX7gxQ48QIGUacMy8kp1+zczY\r\n# +SxlpaEgNmQkfc1raPh9y5sMa6X48+x0K7B8OqDoXcTiECIjJetxwtuBlQseJ05H\r\n# RfisfgFm09kG7vdHEo3NbUuMMBFikc4boN9Ufm0iUhq/JtqV0Kwrv9Cv3ayDgdNw\r\n# EWiL2a65InEWSpRTYfsCQ03eqEh5A3rwV/KfUFcit+DrP+9VcDpjWRsCokZv4tgn\r\n# 5qAXNMtHa8NiqQIDAQABo4IBNjCCATIwHQYDVR0OBBYEFKuX02ICFFdXgrcCBmDJ\r\n# fH5v/KkXMB8GA1UdIwQYMBaAFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMF8GA1UdHwRY\r\n# MFYwVKBSoFCGTmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01p\r\n# Y3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNybDBsBggrBgEF\r\n# BQcBAQRgMF4wXAYIKwYBBQUHMAKGUGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9w\r\n# a2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAo\r\n# MSkuY3J0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwgwDQYJKoZI\r\n# hvcNAQELBQADggIBAOCzNt4fJ+jOvQuq0Itn37IZrYNBGswAi+IAFM3YGK/wGQlE\r\n# ncgjmNBuac95W2fAL6xtFVfMfkeqSLMLqoidVsU9Bm4DEBjaWNOT9uX/tcYiJSfF\r\n# QM0rDbrl8V4nM88RZF56G/qJW9g5dIqOSoimzKUt/Q7WH6VByW0sar5wGvgovK3q\r\n# FadwKShzRYcEqTkHH2zip5e73jezPHx2+taYqJG5xJzdDErZ1nMixRjaHs3Kpcsm\r\n# ZYuxsIRfBYOJvAFGymTGRv5PuwsNps9Ech1Aasq84H/Y/8xN3GQj4P3MiDn8izUB\r\n# DCuXIfHYk39bqnaAmFbUiCby+WWpuzdk4oDKz/sWwrnsoQ72uEGVEN7+kyw9+HSo\r\n# 5i8l8Zg1Ymj9tUgDpVUGjAduoLyHQ7XqknKmS9kJSBKk4okEDg0Id6LeKLQwH1e4\r\n# aVeTyUYwcBX3wg7pLJQWvR7na2SGrtl/23YGQTudmWOryhx9lnU7KBGV/aNvz0tT\r\n# pcsucsK+cZFKDEkWB/oUFVrtyun6ND5pYZNj0CgRup5grVACq/Agb+EOGLCD+zEt\r\n# GNop4tfKvsYb64257NJ9XrMHgpCib76WT34RPmCBByxLUkHxHq5zCyYNu0IFXAt1\r\n# AVicw14M+czLYIVM7NOyVpFdcB1B9MiJik7peSii0XTRdl5/V/KscTaCBFz3MIIH\r\n# cTCCBVmgAwIBAgITMwAAABXF52ueAptJmQAAAAAAFTANBgkqhkiG9w0BAQsFADCB\r\n# iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl\r\n# ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMp\r\n# TWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMjEw\r\n# OTMwMTgyMjI1WhcNMzAwOTMwMTgzMjI1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UE\r\n# CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z\r\n# b2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQ\r\n# Q0EgMjAxMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOThpkzntHIh\r\n# C3miy9ckeb0O1YLT/e6cBwfSqWxOdcjKNVf2AX9sSuDivbk+F2Az/1xPx2b3lVNx\r\n# WuJ+Slr+uDZnhUYjDLWNE893MsAQGOhgfWpSg0S3po5GawcU88V29YZQ3MFEyHFc\r\n# UTE3oAo4bo3t1w/YJlN8OWECesSq/XJprx2rrPY2vjUmZNqYO7oaezOtgFt+jBAc\r\n# nVL+tuhiJdxqD89d9P6OU8/W7IVWTe/dvI2k45GPsjksUZzpcGkNyjYtcI4xyDUo\r\n# veO0hyTD4MmPfrVUj9z6BVWYbWg7mka97aSueik3rMvrg0XnRm7KMtXAhjBcTyzi\r\n# YrLNueKNiOSWrAFKu75xqRdbZ2De+JKRHh09/SDPc31BmkZ1zcRfNN0Sidb9pSB9\r\n# fvzZnkXftnIv231fgLrbqn427DZM9ituqBJR6L8FA6PRc6ZNN3SUHDSCD/AQ8rdH\r\n# GO2n6Jl8P0zbr17C89XYcz1DTsEzOUyOArxCaC4Q6oRRRuLRvWoYWmEBc8pnol7X\r\n# KHYC4jMYctenIPDC+hIK12NvDMk2ZItboKaDIV1fMHSRlJTYuVD5C4lh8zYGNRiE\r\n# R9vcG9H9stQcxWv2XFJRXRLbJbqvUAV6bMURHXLvjflSxIUXk8A8FdsaN8cIFRg/\r\n# eKtFtvUeh17aj54WcmnGrnu3tz5q4i6tAgMBAAGjggHdMIIB2TASBgkrBgEEAYI3\r\n# FQEEBQIDAQABMCMGCSsGAQQBgjcVAgQWBBQqp1L+ZMSavoKRPEY1Kc8Q/y8E7jAd\r\n# BgNVHQ4EFgQUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXAYDVR0gBFUwUzBRBgwrBgEE\r\n# AYI3TIN9AQEwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29t\r\n# L3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMBMGA1UdJQQMMAoGCCsGAQUFBwMI\r\n# MBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMB\r\n# Af8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fOmhjEMFYGA1Ud\r\n# HwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3By\r\n# b2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggrBgEFBQcBAQRO\r\n# MEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2Vy\r\n# dHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MA0GCSqGSIb3DQEBCwUAA4IC\r\n# AQCdVX38Kq3hLB9nATEkW+Geckv8qW/qXBS2Pk5HZHixBpOXPTEztTnXwnE2P9pk\r\n# bHzQdTltuw8x5MKP+2zRoZQYIu7pZmc6U03dmLq2HnjYNi6cqYJWAAOwBb6J6Gng\r\n# ugnue99qb74py27YP0h1AdkY3m2CDPVtI1TkeFN1JFe53Z/zjj3G82jfZfakVqr3\r\n# lbYoVSfQJL1AoL8ZthISEV09J+BAljis9/kpicO8F7BUhUKz/AyeixmJ5/ALaoHC\r\n# gRlCGVJ1ijbCHcNhcy4sa3tuPywJeBTpkbKpW99Jo3QMvOyRgNI95ko+ZjtPu4b6\r\n# MhrZlvSP9pEB9s7GdP32THJvEKt1MMU0sHrYUP4KWN1APMdUbZ1jdEgssU5HLcEU\r\n# BHG/ZPkkvnNtyo4JvbMBV0lUZNlz138eW0QBjloZkWsNn6Qo3GcZKCS6OEuabvsh\r\n# VGtqRRFHqfG3rsjoiV5PndLQTHa1V1QJsWkBRH58oWFsc/4Ku+xBZj1p/cvBQUl+\r\n# fpO+y/g75LcVv7TOPqUxUYS8vwLBgqJ7Fx0ViY1w/ue10CgaiQuPNtq6TPmb/wrp\r\n# NPgkNWcr4A245oyZ1uEi6vAnQj0llOZ0dFtq0Z4+7X6gMTN9vMvpe784cETRkPHI\r\n# qzqKOghif9lwY1NNje6CbaUFEMFxBmoQtB1VM1izoXBm8qGCAs4wggI3AgEBMIH4\r\n# oYHQpIHNMIHKMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G\r\n# A1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUw\r\n# IwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMSYwJAYDVQQLEx1U\r\n# aGFsZXMgVFNTIEVTTjpFNUE2LUUyN0MtNTkyRTElMCMGA1UEAxMcTWljcm9zb2Z0\r\n# IFRpbWUtU3RhbXAgU2VydmljZaIjCgEBMAcGBSsOAwIaAxUA0Y+CyLezGgVHWFNm\r\n# KI1LuE/hY6uggYMwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu\r\n# Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv\r\n# cmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAN\r\n# BgkqhkiG9w0BAQUFAAIFAOZpqYQwIhgPMjAyMjA3MDIwMTEyMzZaGA8yMDIyMDcw\r\n# MzAxMTIzNlowdzA9BgorBgEEAYRZCgQBMS8wLTAKAgUA5mmphAIBADAKAgEAAgIe\r\n# WAIB/zAHAgEAAgIR3TAKAgUA5mr7BAIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgor\r\n# BgEEAYRZCgMCoAowCAIBAAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUA\r\n# A4GBAGizLxBkK6B2oQmB80+aM7sOfXuAgkYj93m3glu2ZQ242mTevtDINaDoV+qc\r\n# 7BhagNfrWoCVESVZEjaqCYrV/VVxnmuKU0VXJoUnLcNW0cmK3aTV1fENg1wMmi/r\r\n# TFKkd1udFGkqk+aoUxPKMtV19/TbRjUL/5qxCuVE0uACxjXOMYIEDTCCBAkCAQEw\r\n# gZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT\r\n# B1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UE\r\n# AxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAGVt/wN1uM3MSUA\r\n# AQAAAZUwDQYJYIZIAWUDBAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0B\r\n# CRABBDAvBgkqhkiG9w0BCQQxIgQg7wxBntfZfrgc+uuByghKGEFJWZuIL6DEXRVE\r\n# WWTTqNowgfoGCyqGSIb3DQEJEAIvMYHqMIHnMIHkMIG9BCBc5kvhjZALe2mhIz/Q\r\n# d7keVOmA/cC1dzKZT4ybLEkCxzCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYD\r\n# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1w\r\n# IFBDQSAyMDEwAhMzAAABlbf8DdbjNzElAAEAAAGVMCIEIKYVsiXt/OMHtVXLwf4B\r\n# pSdKHBzozlb2nRtmmiDl84fKMA0GCSqGSIb3DQEBCwUABIICAIVHstuzLLngbRuA\r\n# f6xugLOjcbg1MNZdn9l1UIHXSFSPGQWqiL2dK4o6sjWpDFkdt2muopWbZRGFBmGw\r\n# VIuZeYRztWON1VcW177otKa1hlV7WyF/VvEqytpXyjybORUwmCkKyLOxl9X6yzWi\r\n# INaJPOYk09kAQkUFt/MNYIsxr++dQX14DOoJxm9tpCEvIYl9mnUU+iQnE5B9AEMw\r\n# +nC4D7IMA1+6smM7fbSJa7o4BHfyje8PHB3w9GF223mZTG0EhBlultQkMSpV/c88\r\n# 9hsbwx16Cr5sY9M/lSRt4oC3qzSuTmYd6VYJ/ILt9ptrpOkaYCiXXRx8Cfz7w53w\r\n# Au/J8xJjNWvrKxkcc8XiUXPfGGTXujyiS2MqvztBkg6wCduFKqogmvOtQiiwQQxE\r\n# G6lU/rss27omoTUc41EawOr1km5y+fUS9aoYX9K8NNhFH6TSni3dp/+Hiyif1T7X\r\n# g0cBy4yHuYxMmRrFcmGeplW3KhXHfkJjbHaVs1QgnRfkgFuypwF5YoFWrW7Xgj+a\r\n# ZCDKSoYq45E4v0ryIvyu0shBoHQXREAzpBv3L9h5A9vEFQG4alCI57oSbdqJ1YIa\r\n# ggkTQHR2CWdB7FnQilCqqZjSnAtXYZh/RD+PX6fg1UyUUQf5ohnw951pQeKYTYHm\r\n# Fwut+RibzdbHEF/kLZr6SZsDupCv\r\n# SIG # End signature block\r\n"
  },
  {
    "path": "src/PowerShell/ExternalModules/PackageManagement/1.4.8.1/PackageManagement.psm1",
    "content": "﻿#\r\n# Script module for module 'PackageManagement'\r\n#\r\nSet-StrictMode -Version Latest\r\nMicrosoft.PowerShell.Utility\\Import-LocalizedData  LocalizedData -filename PackageManagement.Resources.psd1\r\n\r\n# Summary: PackageManagement is supported on Windows PowerShell 3.0 or later, Nano Server and PowerShellCore\r\n$isCore = ($PSVersionTable.Keys -contains \"PSEdition\") -and ($PSVersionTable.PSEdition -ne 'Desktop')\r\n$binarySubPath = ''\r\nif ($isCore)\r\n{\r\n    $binarySubPath = Join-Path -Path 'coreclr' -ChildPath 'netstandard2.0'\r\n} else {\r\n    $binarySubPath = 'fullclr'\r\n}\r\n\r\n# Set up some helper variables to make it easier to work with the module\r\n$script:PSModule = $ExecutionContext.SessionState.Module\r\n$script:PSModuleRoot = $script:PSModule.ModuleBase\r\n\r\n$script:PkgMgmt = 'Microsoft.PackageManagement.dll'\r\n$script:PSPkgMgmt = 'Microsoft.PowerShell.PackageManagement.dll'\r\n\r\n\r\n# Try to import the OneGet assemblies at the same directory regardless fullclr or coreclr\r\n$OneGetModulePath = Join-Path -Path $script:PSModuleRoot -ChildPath $script:PkgMgmt\r\n$binaryModuleRoot = $script:PSModuleRoot\r\n\r\n\r\nif(-not (Test-Path -Path $OneGetModulePath))\r\n{\r\n    # Import the appropriate nested binary module based on the current PowerShell version\r\n    $binaryModuleRoot = Join-Path -Path $script:PSModuleRoot -ChildPath $binarySubPath\r\n    $OneGetModulePath = Join-Path -Path $binaryModuleRoot -ChildPath $script:PkgMgmt\r\n}\r\n\r\n$PSOneGetModulePath = Join-Path -Path $binaryModuleRoot -ChildPath $script:PSPkgMgmt\r\n$OneGetModule = Import-Module -Name $OneGetModulePath -PassThru\r\n$PSOneGetModule = Import-Module -Name $PSOneGetModulePath -PassThru\r\n\r\n\r\n# When the module is unloaded, remove the nested binary module that was loaded with it\r\nif($OneGetModule)\r\n{\r\n    $script:PSModule.OnRemove = {\r\n        Remove-Module -ModuleInfo $OneGetModule\r\n    }\r\n}\r\n\r\nif($PSOneGetModule)\r\n{\r\n    $script:PSModule.OnRemove = {\r\n        Remove-Module -ModuleInfo $PSOneGetModule\r\n    }\r\n}\r\n# SIG # Begin signature block\r\n# MIInpQYJKoZIhvcNAQcCoIInljCCJ5ICAQExDzANBglghkgBZQMEAgEFADB5Bgor\r\n# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG\r\n# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAu+2bjkKZwIc24\r\n# sUnQmGnTVuZ6xttIA9Ea89zWbpdeVaCCDYUwggYDMIID66ADAgECAhMzAAACU+OD\r\n# 3pbexW7MAAAAAAJTMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD\r\n# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p\r\n# bmcgUENBIDIwMTEwHhcNMjEwOTAyMTgzMzAwWhcNMjIwOTAxMTgzMzAwWjB0MQsw\r\n# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u\r\n# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\r\n# AQDLhxHwq3OhH+4J+SX4qS/VQG8HybccH7tnG+BUqrXubfGuDFYPZ29uCuHfQlO1\r\n# lygLgMpJ4Geh6/6poQ5VkDKfVssn6aA1PCzIh8iOPMQ9Mju3sLF9Sn+Pzuaie4BN\r\n# rp0MuZLDEXgVYx2WNjmzqcxC7dY9SC3znOh5qUy2vnmWygC7b9kj0d3JrGtjc5q5\r\n# 0WfV3WLXAQHkeRROsJFBZfXFGoSvRljFFUAjU/zdhP92P+1JiRRRikVy/sqIhMDY\r\n# +7tVdzlE2fwnKOv9LShgKeyEevgMl0B1Fq7E2YeBZKF6KlhmYi9CE1350cnTUoU4\r\n# YpQSnZo0YAnaenREDLfFGKTdAgMBAAGjggGCMIIBfjAfBgNVHSUEGDAWBgorBgEE\r\n# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUlZpLWIccXoxessA/DRbe26glhEMw\r\n# VAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh\r\n# dGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjMwMDEyKzQ2NzU5ODAfBgNVHSMEGDAW\r\n# gBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8v\r\n# d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIw\r\n# MTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDov\r\n# L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDEx\r\n# XzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB\r\n# AKVY+yKcJVVxf9W2vNkL5ufjOpqcvVOOOdVyjy1dmsO4O8khWhqrecdVZp09adOZ\r\n# 8kcMtQ0U+oKx484Jg11cc4Ck0FyOBnp+YIFbOxYCqzaqMcaRAgy48n1tbz/EFYiF\r\n# zJmMiGnlgWFCStONPvQOBD2y/Ej3qBRnGy9EZS1EDlRN/8l5Rs3HX2lZhd9WuukR\r\n# bUk83U99TPJyo12cU0Mb3n1HJv/JZpwSyqb3O0o4HExVJSkwN1m42fSVIVtXVVSa\r\n# YZiVpv32GoD/dyAS/gyplfR6FI3RnCOomzlycSqoz0zBCPFiCMhVhQ6qn+J0GhgR\r\n# BJvGKizw+5lTfnBFoqKZJDROz+uGDl9tw6JvnVqAZKGrWv/CsYaegaPePFrAVSxA\r\n# yUwOFTkAqtNC8uAee+rv2V5xLw8FfpKJ5yKiMKnCKrIaFQDr5AZ7f2ejGGDf+8Tz\r\n# OiK1AgBvOW3iTEEa/at8Z4+s1CmnEAkAi0cLjB72CJedU1LAswdOCWM2MDIZVo9j\r\n# 0T74OkJLTjPd3WNEyw0rBXTyhlbYQsYt7ElT2l2TTlF5EmpVixGtj4ChNjWoKr9y\r\n# TAqtadd2Ym5FNB792GzwNwa631BPCgBJmcRpFKXt0VEQq7UXVNYBiBRd+x4yvjqq\r\n# 5aF7XC5nXCgjbCk7IXwmOphNuNDNiRq83Ejjnc7mxrJGMIIHejCCBWKgAwIBAgIK\r\n# YQ6Q0gAAAAAAAzANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNV\r\n# BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv\r\n# c29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlm\r\n# aWNhdGUgQXV0aG9yaXR5IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEw\r\n# OTA5WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE\r\n# BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYD\r\n# VQQDEx9NaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG\r\n# 9w0BAQEFAAOCAg8AMIICCgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+la\r\n# UKq4BjgaBEm6f8MMHt03a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc\r\n# 6Whe0t+bU7IKLMOv2akrrnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4D\r\n# dato88tt8zpcoRb0RrrgOGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+\r\n# lD3v++MrWhAfTVYoonpy4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nk\r\n# kDstrjNYxbc+/jLTswM9sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6\r\n# A4aN91/w0FK/jJSHvMAhdCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmd\r\n# X4jiJV3TIUs+UsS1Vz8kA/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL\r\n# 5zmhD+kjSbwYuER8ReTBw3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zd\r\n# sGbiwZeBe+3W7UvnSSmnEyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3\r\n# T8HhhUSJxAlMxdSlQy90lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS\r\n# 4NaIjAsCAwEAAaOCAe0wggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRI\r\n# bmTlUAXTgqoXNzcitW2oynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAL\r\n# BgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBD\r\n# uRQFTuHqp8cx0SOJNDBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jv\r\n# c29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf\r\n# MDNfMjIuY3JsMF4GCCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3\r\n# dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf\r\n# MDNfMjIuY3J0MIGfBgNVHSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEF\r\n# BQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1h\r\n# cnljcHMuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkA\r\n# YwB5AF8AcwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn\r\n# 8oalmOBUeRou09h0ZyKbC5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7\r\n# v0epo/Np22O/IjWll11lhJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0b\r\n# pdS1HXeUOeLpZMlEPXh6I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/\r\n# KmtYSWMfCWluWpiW5IP0wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvy\r\n# CInWH8MyGOLwxS3OW560STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBp\r\n# mLJZiWhub6e3dMNABQamASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJi\r\n# hsMdYzaXht/a8/jyFqGaJ+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYb\r\n# BL7fQccOKO7eZS/sl/ahXJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbS\r\n# oqKfenoi+kiVH6v7RyOA9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sL\r\n# gOppO6/8MO0ETI7f33VtY5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtX\r\n# cVZOSEXAQsmbdlsKgEhr/Xmfwb1tbWrJUnMTDXpQzTGCGXYwghlyAgEBMIGVMH4x\r\n# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt\r\n# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p\r\n# Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAAJT44Pelt7FbswAAAAA\r\n# AlMwDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw\r\n# HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIMQt\r\n# y3cqdLHMkORDousYFit1gZHgDA5G8ruNWC2M1yt8MEIGCisGAQQBgjcCAQwxNDAy\r\n# oBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5j\r\n# b20wDQYJKoZIhvcNAQEBBQAEggEACK1h1k5yJH9t/LbulIT8EoMZ45iY6fTsCiXj\r\n# iBdhKfo1OenarZN4LivqwI6cxXSZWNzvIQ2umswdxzfMJy+0aBwrQ5zc++MxF4p8\r\n# p04vI4uuwSnZpFgBSS57hdZd64NoBXkan+YMMz01THWrz0AFFBI4euN9ASE5lF5r\r\n# rZ1YvyTPhsgleGVXcV45YsM6Xp0sTnvtgdmHeyUknVefJwR4ZmaNp6EC3QKuHkna\r\n# B686mvfbKsMXtPvOMt6tN2MTMPCPrSJ/+D2aV+JKwjqk+MmIAZ0JeTXq7Oy3H4i3\r\n# eR66oB24MwbOPL57sgVN35CK3trEV9eSwJbks6fIplb+UZlW9aGCFwAwghb8Bgor\r\n# BgEEAYI3AwMBMYIW7DCCFugGCSqGSIb3DQEHAqCCFtkwghbVAgEDMQ8wDQYJYIZI\r\n# AWUDBAIBBQAwggFRBgsqhkiG9w0BCRABBKCCAUAEggE8MIIBOAIBAQYKKwYBBAGE\r\n# WQoDATAxMA0GCWCGSAFlAwQCAQUABCBu5SYV/TjMU+1To3jN1ZjWGQGhTTO1qrzJ\r\n# 2j1cR5AwHgIGYrTVw4J4GBMyMDIyMDcwMTIxMDAwMS4wODNaMASAAgH0oIHQpIHN\r\n# MIHKMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH\r\n# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQL\r\n# ExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMSYwJAYDVQQLEx1UaGFsZXMg\r\n# VFNTIEVTTjo4QTgyLUUzNEYtOUREQTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt\r\n# U3RhbXAgU2VydmljZaCCEVcwggcMMIIE9KADAgECAhMzAAABmciPr622fb6LAAEA\r\n# AAGZMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo\r\n# aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y\r\n# cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw\r\n# MB4XDTIxMTIwMjE5MDUxNloXDTIzMDIyODE5MDUxNlowgcoxCzAJBgNVBAYTAlVT\r\n# MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK\r\n# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVy\r\n# aWNhIE9wZXJhdGlvbnMxJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNOOjhBODItRTM0\r\n# Ri05RERBMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIIC\r\n# IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuBP5V1yjLMva1WtmvG0W9AK/\r\n# z4+PmyogIDICmsrwjBZ93XRqH/HlhYCVqeSXSo1o655lta/bR6XD9pBaY16dlHa4\r\n# +eY7eTWItTBEXKCKPhNvV7gsBQDCX7Rnb7Fnmvzk0DyBbGRFqhLXl3UZ3MlcHLec\r\n# RcwSAtSVgnZn3O0efUTCMr4FoyM/N+epsHqMJDrLTdX3udyiCfH5a2CCyEFrDUTD\r\n# k985wBsCG/ZMi+eAuo2YxcTkrrBmJlUPhq/6mUBC8NYqcfbOYzT9S0qTqX0xARbv\r\n# svSizQZjAQEZEj6UxZBhMhksBhoEnTougVOhTyvurq2fN9I60XpiuCZCCfbUIZRn\r\n# CIQI4XKmUrZ/t/JUY1b632wSORKSNjcJVSCtomxlu7FnkwM/8jTzSElG0IRgCbHv\r\n# zoBo/9as/x2vZqn2GfAR3ITcZ9PJ1pKsq46yonEMsbg/JgmrU61UmziWH0MmXR0f\r\n# WuL4MhnmRFwWEDQJSLgd+0AjgILP1Xg1PDOHXPyJa08gtLldUkuBpPM1fuV+Xkbv\r\n# lzkTfBVqsyOpP/cunFsDljCumlDdV6i3Ghf7Jva1/OHiltpYQ3Nwt9Vi46fFDnzh\r\n# 2Xz7ssueMX4pZ4YQj8uECifY4IKKqnnhIQhH4A2I8vjwclf3uRwwdsR3bZS/d8Jb\r\n# QJCN2gsaPOJFTwQmtDsCAwEAAaOCATYwggEyMB0GA1UdDgQWBBSNula4Ppxlr67y\r\n# IdHUDxKJxDUdEDAfBgNVHSMEGDAWgBSfpxVdAF5iXYP05dJlpxtTNRnpcjBfBgNV\r\n# HR8EWDBWMFSgUqBQhk5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2Ny\r\n# bC9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcmwwbAYI\r\n# KwYBBQUHAQEEYDBeMFwGCCsGAQUFBzAChlBodHRwOi8vd3d3Lm1pY3Jvc29mdC5j\r\n# b20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAy\r\n# MDEwKDEpLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMIMA0G\r\n# CSqGSIb3DQEBCwUAA4ICAQBxs1odvYmwTa6N57PBNxDhxrCwdRs5PdEhWFCgYpSL\r\n# uIw20e6m71zXfJ55f8+Q/SyoMN0/NY6subTIlqfqeI2AQZNz0cdckqi1H4ReWTFq\r\n# JUc1vnEGRl1d/IkpnQFBtAqUecdazHTyK03M1VBbDmBqppKFEP3UYlS+IgFySwjU\r\n# 4+Md2MCEHAj7dIoyVYpzyDAGMwPH/fQW3orJMiNARxgHdJBlF9iNv6bmJ5ckvLaA\r\n# ZwDY4dtcYLxLmmdnb0ar1pP4tVyJTuu2rv1wnjE714TziFJqvNFN9k4n8N0kogSk\r\n# 8oq+5qFh9Yux9quUAJ6wcbssv/2bA3wEQ1fwLZo+Y6+gE30Rw3VGp0KXqAUvospT\r\n# VOkQEbvIPkzArv2Z3WZq7PcPvIGpVCBoPhppTZNO31yefDnPqhaoDQLDZDIvnUsy\r\n# pFhgOP5JSRZ9F4nIVy/Preyjmslyhs0I2ugnbQo4rJ8kvIW7+DyoWnjLX+vMCVii\r\n# jrNLbdgCX2Aub0mx/XJPARo9nv8kFxGRLvPC+f3xyuV1JPyCl8d82i5MV00meNxG\r\n# v1il1QczGrB2dz5p8tJqBHpAF8dVISzTWL+Fbpt91Yq8Ugeq/xikMRUh7u8hX61k\r\n# KWMsgx9dfU5oQHnUvE9VWm6nbTuWT9hNeEyvNlcsct8RD3pTqOHUSJYZu12OpPQe\r\n# vDCCB3EwggVZoAMCAQICEzMAAAAVxedrngKbSZkAAAAAABUwDQYJKoZIhvcNAQEL\r\n# BQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH\r\n# EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNV\r\n# BAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDEwMB4X\r\n# DTIxMDkzMDE4MjIyNVoXDTMwMDkzMDE4MzIyNVowfDELMAkGA1UEBhMCVVMxEzAR\r\n# BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p\r\n# Y3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3Rh\r\n# bXAgUENBIDIwMTAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDk4aZM\r\n# 57RyIQt5osvXJHm9DtWC0/3unAcH0qlsTnXIyjVX9gF/bErg4r25PhdgM/9cT8dm\r\n# 95VTcVrifkpa/rg2Z4VGIwy1jRPPdzLAEBjoYH1qUoNEt6aORmsHFPPFdvWGUNzB\r\n# RMhxXFExN6AKOG6N7dcP2CZTfDlhAnrEqv1yaa8dq6z2Nr41JmTamDu6GnszrYBb\r\n# fowQHJ1S/rboYiXcag/PXfT+jlPP1uyFVk3v3byNpOORj7I5LFGc6XBpDco2LXCO\r\n# Mcg1KL3jtIckw+DJj361VI/c+gVVmG1oO5pGve2krnopN6zL64NF50ZuyjLVwIYw\r\n# XE8s4mKyzbnijYjklqwBSru+cakXW2dg3viSkR4dPf0gz3N9QZpGdc3EXzTdEonW\r\n# /aUgfX782Z5F37ZyL9t9X4C626p+Nuw2TPYrbqgSUei/BQOj0XOmTTd0lBw0gg/w\r\n# EPK3Rxjtp+iZfD9M269ewvPV2HM9Q07BMzlMjgK8QmguEOqEUUbi0b1qGFphAXPK\r\n# Z6Je1yh2AuIzGHLXpyDwwvoSCtdjbwzJNmSLW6CmgyFdXzB0kZSU2LlQ+QuJYfM2\r\n# BjUYhEfb3BvR/bLUHMVr9lxSUV0S2yW6r1AFemzFER1y7435UsSFF5PAPBXbGjfH\r\n# CBUYP3irRbb1Hode2o+eFnJpxq57t7c+auIurQIDAQABo4IB3TCCAdkwEgYJKwYB\r\n# BAGCNxUBBAUCAwEAATAjBgkrBgEEAYI3FQIEFgQUKqdS/mTEmr6CkTxGNSnPEP8v\r\n# BO4wHQYDVR0OBBYEFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMFwGA1UdIARVMFMwUQYM\r\n# KwYBBAGCN0yDfQEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0\r\n# LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTATBgNVHSUEDDAKBggrBgEF\r\n# BQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD\r\n# VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvXzpoYxDBW\r\n# BgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny\r\n# bC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYIKwYBBQUH\r\n# AQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp\r\n# L2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDANBgkqhkiG9w0BAQsF\r\n# AAOCAgEAnVV9/Cqt4SwfZwExJFvhnnJL/Klv6lwUtj5OR2R4sQaTlz0xM7U518Jx\r\n# Nj/aZGx80HU5bbsPMeTCj/ts0aGUGCLu6WZnOlNN3Zi6th542DYunKmCVgADsAW+\r\n# iehp4LoJ7nvfam++Kctu2D9IdQHZGN5tggz1bSNU5HhTdSRXud2f8449xvNo32X2\r\n# pFaq95W2KFUn0CS9QKC/GbYSEhFdPSfgQJY4rPf5KYnDvBewVIVCs/wMnosZiefw\r\n# C2qBwoEZQhlSdYo2wh3DYXMuLGt7bj8sCXgU6ZGyqVvfSaN0DLzskYDSPeZKPmY7\r\n# T7uG+jIa2Zb0j/aRAfbOxnT99kxybxCrdTDFNLB62FD+CljdQDzHVG2dY3RILLFO\r\n# Ry3BFARxv2T5JL5zbcqOCb2zAVdJVGTZc9d/HltEAY5aGZFrDZ+kKNxnGSgkujhL\r\n# mm77IVRrakURR6nxt67I6IleT53S0Ex2tVdUCbFpAUR+fKFhbHP+CrvsQWY9af3L\r\n# wUFJfn6Tvsv4O+S3Fb+0zj6lMVGEvL8CwYKiexcdFYmNcP7ntdAoGokLjzbaukz5\r\n# m/8K6TT4JDVnK+ANuOaMmdbhIurwJ0I9JZTmdHRbatGePu1+oDEzfbzL6Xu/OHBE\r\n# 0ZDxyKs6ijoIYn/ZcGNTTY3ugm2lBRDBcQZqELQdVTNYs6FwZvKhggLOMIICNwIB\r\n# ATCB+KGB0KSBzTCByjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x\r\n# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv\r\n# bjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEmMCQGA1UE\r\n# CxMdVGhhbGVzIFRTUyBFU046OEE4Mi1FMzRGLTlEREExJTAjBgNVBAMTHE1pY3Jv\r\n# c29mdCBUaW1lLVN0YW1wIFNlcnZpY2WiIwoBATAHBgUrDgMCGgMVAJLv82Lo56mq\r\n# TegSfTCeY7YA65TroIGDMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldh\r\n# c2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBD\r\n# b3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIw\r\n# MTAwDQYJKoZIhvcNAQEFBQACBQDmaTc9MCIYDzIwMjIwNzAxMTcwNTAxWhgPMjAy\r\n# MjA3MDIxNzA1MDFaMHcwPQYKKwYBBAGEWQoEATEvMC0wCgIFAOZpNz0CAQAwCgIB\r\n# AAICERUCAf8wBwIBAAICEbMwCgIFAOZqiL0CAQAwNgYKKwYBBAGEWQoEAjEoMCYw\r\n# DAYKKwYBBAGEWQoDAqAKMAgCAQACAwehIKEKMAgCAQACAwGGoDANBgkqhkiG9w0B\r\n# AQUFAAOBgQBT54+WmHojMQCYQgQt18iy8jWH/zrm88CORF+vITV/kwvO/zDL8aHA\r\n# IHzJNcy5CXpPKzy5Vhln9qHhkGMMjkNDjIw+WFOC55FYzdJdNu/r8E9kWn3OkSFh\r\n# YkGyBkUQRX1wxYMrjPe3VRH/CAkirEZQgoBQFfCTDXTQ+ybTfsRG+jGCBA0wggQJ\r\n# AgEBMIGTMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYD\r\n# VQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAk\r\n# BgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAABmciPr622\r\n# fb6LAAEAAAGZMA0GCWCGSAFlAwQCAQUAoIIBSjAaBgkqhkiG9w0BCQMxDQYLKoZI\r\n# hvcNAQkQAQQwLwYJKoZIhvcNAQkEMSIEIE7ONnfPZ+1TgSlm38TzyWp8xzS0ag8S\r\n# us6x6ktqqn9FMIH6BgsqhkiG9w0BCRACLzGB6jCB5zCB5DCBvQQgZn1p+fKije1l\r\n# qQU2Dq1DtQUgkpyjywvxu8AjiHNibH4wgZgwgYCkfjB8MQswCQYDVQQGEwJVUzET\r\n# MBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMV\r\n# TWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1T\r\n# dGFtcCBQQ0EgMjAxMAITMwAAAZnIj6+ttn2+iwABAAABmTAiBCC0Y+62+yZ1e93v\r\n# MC2z6glC0K3irTMXW68vE4DsYaOXnTANBgkqhkiG9w0BAQsFAASCAgBbNcmClGcW\r\n# 0/bHfTnMXyPfcg+udBEUubR+oR3GKng5bIH4LXzBiLXiGeChHgHzN81BtET8g+84\r\n# mgQKCHEKer9K1IVHhn5meD6PzDmknpB5U+ZvzmNXgRVL23iK81mDJdEq3RwrfwSJ\r\n# f86PUlrVmK3MdyRzfP92miVpeIzcqTPNQJzzOfFPgi07dyLVCZ2ZT11uAz+WksxW\r\n# XjrD+DGzxK0EQDbltXlfIxcrT+FIF+yYA3HVs/g4HUMgT2MsOFjzyGu3MD/rNbb6\r\n# 8p2wGoYB1WkVzuEvV3S4L/ZO/oTUB59aM4XnvFhi0tsQKNJYuqysTAdIdRaJWH3p\r\n# vp4OG/R0RTRXfmGueTwOUP6xbZXSluQa+a3PlHgGsnP8nwB6Mhty3tgzy46SSmdC\r\n# feHAd+MN+x5Qx9ujIaMLa9bqWf/Q9lCgwIHbxNOIsoC6O3N15IAI/t39U0qMBXe1\r\n# Cm7DBSk7ldHponGKcteZ27k/Aqc5R8blqt0zgruhMRq5G6Rp8+m3VwWAwZiDjlC8\r\n# hRUuIcE8AuGCrTtu0omm8tNyjDFd0ypl81x5HceIlHrpwCIUaVd5gTGNd1/dJyW3\r\n# CTgdG0/M7ELkTjNfLi16NGtEeS+i+UYe2Cm32pPxXwx+q+YJ0N9wojtS6450z19x\r\n# StE87RWDz8GuJ4o02QeRpwQQwVTHpnjaAA==\r\n# SIG # End signature block\r\n"
  },
  {
    "path": "src/PowerShell/ExternalModules/PackageManagement/1.4.8.1/PackageProviderFunctions.psm1",
    "content": "﻿###\r\n# ==++==\r\n#\r\n# Copyright (c) Microsoft Corporation. All rights reserved.\r\n# Licensed under the Apache License, Version 2.0 (the \"License\");\r\n# you may not use this file except in compliance with the License.\r\n# You may obtain a copy of the License at\r\n# http://www.apache.org/licenses/LICENSE-2.0\r\n#\r\n# Unless required by applicable law or agreed to in writing, software\r\n# distributed under the License is distributed on an \"AS IS\" BASIS,\r\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n# See the License for the specific language governing permissions and\r\n# limitations under the License.\r\n#\r\n###\r\n\r\n<#\r\n\tOverrides the default Write-Debug so that the output gets routed back thru the\r\n\t$request.Debug() function\r\n#>\r\nfunction Write-Debug {\r\n\tparam(\r\n\t[Parameter(Mandatory=$true)][string] $message,\r\n\t[parameter(ValueFromRemainingArguments=$true)]\r\n\t[object[]]\r\n\t $args= @()\r\n\t)\r\n\r\n\tif( -not $request  ) {\r\n\t\tif( -not $args  ) {\r\n\t\t\tMicrosoft.PowerShell.Utility\\write-verbose $message\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\t$msg = [system.string]::format($message, $args)\r\n\t\tMicrosoft.PowerShell.Utility\\write-verbose $msg\r\n\t\treturn\r\n\t}\r\n\r\n\tif( -not $args  ) {\r\n\t\t$null = $request.Debug($message);\r\n\t\treturn\r\n\t}\r\n\t$null = $request.Debug($message,$args);\r\n}\r\n\r\nfunction Write-Error {\r\n\tparam( \r\n\t\t[Parameter(Mandatory=$true)][string] $Message,\r\n\t\t[Parameter()][string] $Category,\r\n\t\t[Parameter()][string] $ErrorId,\r\n\t\t[Parameter()][string] $TargetObject\r\n\t)\r\n\r\n\t$null = $request.Warning($Message);\r\n}\r\n\r\n<#\r\n\tOverrides the default Write-Verbose so that the output gets routed back thru the\r\n\t$request.Verbose() function\r\n#>\r\n\r\nfunction Write-Progress {\r\n    param(\r\n        [CmdletBinding()]\r\n\r\n        [Parameter(Position=0)]\r\n        [string]\r\n        $Activity,\r\n\r\n        # This parameter is not supported by request object\r\n        [Parameter(Position=1)]\r\n        [ValidateNotNullOrEmpty()]\r\n        [string]\r\n        $Status,\r\n\r\n        [Parameter(Position=2)]\r\n        [ValidateRange(0,[int]::MaxValue)]\r\n        [int]\r\n        $Id,\r\n\r\n        [Parameter()]\r\n        [int]\r\n        $PercentComplete=-1,\r\n\r\n        # This parameter is not supported by request object\r\n        [Parameter()]\r\n        [int]\r\n        $SecondsRemaining=-1,\r\n\r\n        # This parameter is not supported by request object\r\n        [Parameter()]\r\n        [string]\r\n        $CurrentOperation,        \r\n\r\n        [Parameter()]\r\n        [ValidateRange(-1,[int]::MaxValue)]\r\n        [int]\r\n        $ParentID=-1,\r\n\r\n        [Parameter()]\r\n        [switch]\r\n        $Completed,\r\n\r\n        # This parameter is not supported by request object\r\n        [Parameter()]\r\n        [int]\r\n        $SourceID,\r\n\r\n\t    [object[]]\r\n        $args= @()\r\n    )\r\n\r\n    $params = @{}\r\n\r\n    if ($PSBoundParameters.ContainsKey(\"Activity\")) {\r\n        $params.Add(\"Activity\", $PSBoundParameters[\"Activity\"])\r\n    }\r\n\r\n    if ($PSBoundParameters.ContainsKey(\"Status\")) {\r\n        $params.Add(\"Status\", $PSBoundParameters[\"Status\"])\r\n    }\r\n\r\n    if ($PSBoundParameters.ContainsKey(\"PercentComplete\")) {\r\n        $params.Add(\"PercentComplete\", $PSBoundParameters[\"PercentComplete\"])\r\n    }\r\n\r\n    if ($PSBoundParameters.ContainsKey(\"Id\")) {\r\n        $params.Add(\"Id\", $PSBoundParameters[\"Id\"])\r\n    }\r\n\r\n    if ($PSBoundParameters.ContainsKey(\"ParentID\")) {\r\n        $params.Add(\"ParentID\", $PSBoundParameters[\"ParentID\"])\r\n    }\r\n\r\n    if ($PSBoundParameters.ContainsKey(\"Completed\")) {\r\n        $params.Add(\"Completed\", $PSBoundParameters[\"Completed\"])\r\n    }\r\n\r\n\tif( -not $request  ) {    \r\n\t\tif( -not $args  ) {\r\n\t\t\tMicrosoft.PowerShell.Utility\\Write-Progress @params\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\t$params[\"Activity\"] = [system.string]::format($Activity, $args)\r\n\t\tMicrosoft.PowerShell.Utility\\Write-Progress @params\r\n\t\treturn\r\n\t}\r\n\r\n\tif( -not $args  ) {\r\n        $request.Progress($Activity, $Status, $Id, $PercentComplete, $SecondsRemaining, $CurrentOperation, $ParentID, $Completed)\r\n\t}\r\n\r\n}\r\n\r\nfunction Write-Verbose{\r\n\tparam(\r\n\t[Parameter(Mandatory=$true)][string] $message,\r\n\t[parameter(ValueFromRemainingArguments=$true)]\r\n\t[object[]]\r\n\t $args= @()\r\n\t)\r\n\r\n\tif( -not $request ) {\r\n\t\tif( -not $args ) {\r\n\t\t\tMicrosoft.PowerShell.Utility\\write-verbose $message\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\t$msg = [system.string]::format($message, $args)\r\n\t\tMicrosoft.PowerShell.Utility\\write-verbose $msg\r\n\t\treturn\r\n\t}\r\n\r\n\tif( -not $args ) {\r\n\t\t$null = $request.Verbose($message);\r\n\t\treturn\r\n\t}\r\n\t$null = $request.Verbose($message,$args);\r\n}\r\n\r\n<#\r\n\tOverrides the default Write-Warning so that the output gets routed back thru the\r\n\t$request.Warning() function\r\n#>\r\n\r\nfunction Write-Warning{\r\n\tparam(\r\n\t[Parameter(Mandatory=$true)][string] $message,\r\n\t[parameter(ValueFromRemainingArguments=$true)]\r\n\t[object[]]\r\n\t $args= @()\r\n\t)\r\n\r\n\tif( -not $request ) {\r\n\t\tif( -not $args ) {\r\n\t\t\tMicrosoft.PowerShell.Utility\\write-warning $message\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\t$msg = [system.string]::format($message, $args)\r\n\t\tMicrosoft.PowerShell.Utility\\write-warning $msg\r\n\t\treturn\r\n\t}\r\n\r\n\tif( -not $args ) {\r\n\t\t$null = $request.Warning($message);\r\n\t\treturn\r\n\t}\r\n\t$null = $request.Warning($message,$args);\r\n}\r\n\r\n<#\r\n\tCreates a new instance of a PackageSource object\r\n#>\r\nfunction New-PackageSource {\r\n\tparam(\r\n\t\t[Parameter(Mandatory=$true)][string] $name,\r\n\t\t[Parameter(Mandatory=$true)][string] $location,\r\n\t\t[Parameter(Mandatory=$true)][bool] $trusted,\r\n\t\t[Parameter(Mandatory=$true)][bool] $registered,\r\n\t\t[bool] $valid = $false,\r\n\t\t[System.Collections.Hashtable] $details = $null\r\n\t)\r\n\r\n\treturn New-Object -TypeName Microsoft.PackageManagement.MetaProvider.PowerShell.PackageSource -ArgumentList $name,$location,$trusted,$registered,$valid,$details\r\n}\r\n\r\n<#\r\n\tCreates a new instance of a SoftwareIdentity object\r\n#>\r\nfunction New-SoftwareIdentity {\r\n\tparam(\r\n\t\t[Parameter(Mandatory=$true)][string] $fastPackageReference,\r\n\t\t[Parameter(Mandatory=$true)][string] $name,\r\n\t\t[Parameter(Mandatory=$true)][string] $version,\r\n\t\t[Parameter(Mandatory=$true)][string] $versionScheme,\r\n\t\t[Parameter(Mandatory=$true)][string] $source,\r\n\t\t[string] $summary,\r\n\t\t[string] $searchKey = $null,\r\n\t\t[string] $fullPath = $null,\r\n\t\t[string] $filename = $null,\r\n\t\t[System.Collections.Hashtable] $details = $null,\r\n\t\t[System.Collections.ArrayList] $entities = $null,\r\n\t\t[System.Collections.ArrayList] $links = $null,\r\n\t\t[bool] $fromTrustedSource = $false,\r\n\t\t[System.Collections.ArrayList] $dependencies = $null,\r\n\t\t[string] $tagId = $null,\r\n\t\t[string] $culture = $null,\r\n        [string] $destination = $null\r\n\t)\r\n\treturn New-Object -TypeName Microsoft.PackageManagement.MetaProvider.PowerShell.SoftwareIdentity -ArgumentList $fastPackageReference, $name, $version,  $versionScheme,  $source,  $summary,  $searchKey, $fullPath, $filename , $details , $entities, $links, $fromTrustedSource, $dependencies, $tagId, $culture, $destination\r\n}\r\n\r\n<#\r\n\tCreates a new instance of a SoftwareIdentity object based on an xml string\r\n#>\r\nfunction New-SoftwareIdentityFromXml {\r\n    param(\r\n        [Parameter(Mandatory=$true)][string] $xmlSwidtag,\r\n        [bool] $commitImmediately = $false\r\n    )\r\n\r\n    return New-Object -TypeName Microsoft.PackageManagement.MetaProvider.PowerShell.SoftwareIdentity -ArgumentList $xmlSwidtag, $commitImmediately\r\n}\r\n\r\n<#\r\n\tCreates a new instance of a DyamicOption object\r\n#>\r\nfunction New-DynamicOption {\r\n\tparam(\r\n\t\t[Parameter(Mandatory=$true)][Microsoft.PackageManagement.MetaProvider.PowerShell.OptionCategory] $category,\r\n\t\t[Parameter(Mandatory=$true)][string] $name,\r\n\t\t[Parameter(Mandatory=$true)][Microsoft.PackageManagement.MetaProvider.PowerShell.OptionType] $expectedType,\r\n\t\t[Parameter(Mandatory=$true)][bool] $isRequired,\r\n\t\t[System.Collections.ArrayList] $permittedValues = $null\r\n\t)\r\n\r\n\tif( -not $permittedValues ) {\r\n\t\treturn New-Object -TypeName Microsoft.PackageManagement.MetaProvider.PowerShell.DynamicOption -ArgumentList $category,$name,  $expectedType, $isRequired\r\n\t}\r\n\treturn New-Object -TypeName Microsoft.PackageManagement.MetaProvider.PowerShell.DynamicOption -ArgumentList $category,$name,  $expectedType, $isRequired, $permittedValues.ToArray()\r\n}\r\n\r\n<#\r\n\tCreates a new instance of a Feature object\r\n#>\r\nfunction New-Feature {\r\n\tparam(\r\n\t\t[Parameter(Mandatory=$true)][string] $name,\r\n\t\t[System.Collections.ArrayList] $values = $null\r\n\t)\r\n\r\n\tif( -not $values ) {\r\n\t\treturn New-Object -TypeName Microsoft.PackageManagement.MetaProvider.PowerShell.Feature -ArgumentList $name\r\n\t}\r\n\treturn New-Object -TypeName Microsoft.PackageManagement.MetaProvider.PowerShell.Feature -ArgumentList $name, $values.ToArray()\r\n}\r\n\r\n<#\r\n\tDuplicates the $request object and overrides the client-supplied data with the specified values.\r\n#>\r\nfunction New-Request {\r\n\tparam(\r\n\t\t[System.Collections.Hashtable] $options = $null,\r\n\t\t[System.Collections.ArrayList] $sources = $null,\r\n\t\t[PSCredential] $credential = $null\r\n\t)\r\n\r\n\treturn $request.CloneRequest( $options, $sources, $credential )\r\n}\r\n\r\nfunction New-Entity {\r\n\tparam(\r\n\t\t[Parameter(Mandatory=$true)][string] $name,\r\n\t\t[Parameter(Mandatory=$true,ParameterSetName=\"role\")][string] $role,\r\n\t\t[Parameter(Mandatory=$true,ParameterSetName=\"roles\")][System.Collections.ArrayList]$roles,\r\n        [string] $regId = $null,\r\n        [string] $thumbprint= $null\r\n\t)\r\n\r\n\t$o = New-Object -TypeName Microsoft.PackageManagement.MetaProvider.PowerShell.Entity\r\n\t$o.Name = $name\r\n\r\n\t# support role as a NMTOKENS string or an array of strings\r\n\tif( $role ) {\r\n\t\t$o.Role = $role\r\n\t} \r\n\tif( $roles )  {\r\n\t\t$o.Roles = $roles\r\n\t}\r\n\r\n\t$o.regId = $regId\r\n\t$o.thumbprint = $thumbprint\r\n\treturn $o\r\n}\r\n\r\nfunction New-Link {\r\n\tparam(\r\n\t\t[Parameter(Mandatory=$true)][string] $HRef,\r\n\t\t[Parameter(Mandatory=$true)][string] $relationship,\r\n\t\t[string] $mediaType = $null,\r\n\t\t[string] $ownership = $null,\r\n\t\t[string] $use= $null,\r\n\t\t[string] $appliesToMedia= $null,\r\n\t\t[string] $artifact = $null\r\n\t)\r\n\r\n\t$o = New-Object -TypeName Microsoft.PackageManagement.MetaProvider.PowerShell.Link\r\n\r\n\t$o.HRef = $HRef\r\n\t$o.Relationship =$relationship\r\n\t$o.MediaType =$mediaType\r\n\t$o.Ownership =$ownership\r\n\t$o.Use = $use\r\n\t$o.AppliesToMedia = $appliesToMedia\r\n\t$o.Artifact = $artifact\r\n\r\n\treturn $o\r\n}\r\n\r\nfunction New-Dependency {\r\n\tparam(\r\n\t\t[Parameter(Mandatory=$true)][string] $providerName,\r\n\t\t[Parameter(Mandatory=$true)][string] $packageName,\r\n\t\t[string] $version= $null,\r\n\t\t[string] $source = $null,\r\n\t\t[string] $appliesTo = $null\r\n\t)\r\n\r\n\t$o = New-Object -TypeName Microsoft.PackageManagement.MetaProvider.PowerShell.Dependency\r\n\r\n\t$o.ProviderName = $providerName\r\n\t$o.PackageName =$packageName\r\n\t$o.Version =$version\r\n\t$o.Source =$source\r\n\t$o.AppliesTo = $appliesTo\r\n\r\n\treturn $o\r\n}\r\n# SIG # Begin signature block\r\n# MIInsQYJKoZIhvcNAQcCoIInojCCJ54CAQExDzANBglghkgBZQMEAgEFADB5Bgor\r\n# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG\r\n# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDs5FoY/w7B0Miq\r\n# Kfi0Wb7Z3JGNbdfm1vY/fLsAXNclnKCCDYUwggYDMIID66ADAgECAhMzAAACU+OD\r\n# 3pbexW7MAAAAAAJTMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD\r\n# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p\r\n# bmcgUENBIDIwMTEwHhcNMjEwOTAyMTgzMzAwWhcNMjIwOTAxMTgzMzAwWjB0MQsw\r\n# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u\r\n# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\r\n# AQDLhxHwq3OhH+4J+SX4qS/VQG8HybccH7tnG+BUqrXubfGuDFYPZ29uCuHfQlO1\r\n# lygLgMpJ4Geh6/6poQ5VkDKfVssn6aA1PCzIh8iOPMQ9Mju3sLF9Sn+Pzuaie4BN\r\n# rp0MuZLDEXgVYx2WNjmzqcxC7dY9SC3znOh5qUy2vnmWygC7b9kj0d3JrGtjc5q5\r\n# 0WfV3WLXAQHkeRROsJFBZfXFGoSvRljFFUAjU/zdhP92P+1JiRRRikVy/sqIhMDY\r\n# +7tVdzlE2fwnKOv9LShgKeyEevgMl0B1Fq7E2YeBZKF6KlhmYi9CE1350cnTUoU4\r\n# YpQSnZo0YAnaenREDLfFGKTdAgMBAAGjggGCMIIBfjAfBgNVHSUEGDAWBgorBgEE\r\n# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUlZpLWIccXoxessA/DRbe26glhEMw\r\n# VAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh\r\n# dGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjMwMDEyKzQ2NzU5ODAfBgNVHSMEGDAW\r\n# gBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8v\r\n# d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIw\r\n# MTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDov\r\n# L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDEx\r\n# XzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB\r\n# AKVY+yKcJVVxf9W2vNkL5ufjOpqcvVOOOdVyjy1dmsO4O8khWhqrecdVZp09adOZ\r\n# 8kcMtQ0U+oKx484Jg11cc4Ck0FyOBnp+YIFbOxYCqzaqMcaRAgy48n1tbz/EFYiF\r\n# zJmMiGnlgWFCStONPvQOBD2y/Ej3qBRnGy9EZS1EDlRN/8l5Rs3HX2lZhd9WuukR\r\n# bUk83U99TPJyo12cU0Mb3n1HJv/JZpwSyqb3O0o4HExVJSkwN1m42fSVIVtXVVSa\r\n# YZiVpv32GoD/dyAS/gyplfR6FI3RnCOomzlycSqoz0zBCPFiCMhVhQ6qn+J0GhgR\r\n# BJvGKizw+5lTfnBFoqKZJDROz+uGDl9tw6JvnVqAZKGrWv/CsYaegaPePFrAVSxA\r\n# yUwOFTkAqtNC8uAee+rv2V5xLw8FfpKJ5yKiMKnCKrIaFQDr5AZ7f2ejGGDf+8Tz\r\n# OiK1AgBvOW3iTEEa/at8Z4+s1CmnEAkAi0cLjB72CJedU1LAswdOCWM2MDIZVo9j\r\n# 0T74OkJLTjPd3WNEyw0rBXTyhlbYQsYt7ElT2l2TTlF5EmpVixGtj4ChNjWoKr9y\r\n# TAqtadd2Ym5FNB792GzwNwa631BPCgBJmcRpFKXt0VEQq7UXVNYBiBRd+x4yvjqq\r\n# 5aF7XC5nXCgjbCk7IXwmOphNuNDNiRq83Ejjnc7mxrJGMIIHejCCBWKgAwIBAgIK\r\n# YQ6Q0gAAAAAAAzANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNV\r\n# BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv\r\n# c29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlm\r\n# aWNhdGUgQXV0aG9yaXR5IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEw\r\n# OTA5WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE\r\n# BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYD\r\n# VQQDEx9NaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG\r\n# 9w0BAQEFAAOCAg8AMIICCgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+la\r\n# UKq4BjgaBEm6f8MMHt03a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc\r\n# 6Whe0t+bU7IKLMOv2akrrnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4D\r\n# dato88tt8zpcoRb0RrrgOGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+\r\n# lD3v++MrWhAfTVYoonpy4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nk\r\n# kDstrjNYxbc+/jLTswM9sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6\r\n# A4aN91/w0FK/jJSHvMAhdCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmd\r\n# X4jiJV3TIUs+UsS1Vz8kA/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL\r\n# 5zmhD+kjSbwYuER8ReTBw3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zd\r\n# sGbiwZeBe+3W7UvnSSmnEyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3\r\n# T8HhhUSJxAlMxdSlQy90lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS\r\n# 4NaIjAsCAwEAAaOCAe0wggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRI\r\n# bmTlUAXTgqoXNzcitW2oynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAL\r\n# BgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBD\r\n# uRQFTuHqp8cx0SOJNDBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jv\r\n# c29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf\r\n# MDNfMjIuY3JsMF4GCCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3\r\n# dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf\r\n# MDNfMjIuY3J0MIGfBgNVHSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEF\r\n# BQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1h\r\n# cnljcHMuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkA\r\n# YwB5AF8AcwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn\r\n# 8oalmOBUeRou09h0ZyKbC5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7\r\n# v0epo/Np22O/IjWll11lhJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0b\r\n# pdS1HXeUOeLpZMlEPXh6I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/\r\n# KmtYSWMfCWluWpiW5IP0wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvy\r\n# CInWH8MyGOLwxS3OW560STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBp\r\n# mLJZiWhub6e3dMNABQamASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJi\r\n# hsMdYzaXht/a8/jyFqGaJ+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYb\r\n# BL7fQccOKO7eZS/sl/ahXJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbS\r\n# oqKfenoi+kiVH6v7RyOA9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sL\r\n# gOppO6/8MO0ETI7f33VtY5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtX\r\n# cVZOSEXAQsmbdlsKgEhr/Xmfwb1tbWrJUnMTDXpQzTGCGYIwghl+AgEBMIGVMH4x\r\n# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt\r\n# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p\r\n# Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAAJT44Pelt7FbswAAAAA\r\n# AlMwDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw\r\n# HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIFtW\r\n# lCf/wF6GbazDLehu9mS8WGiUm3tcu/5KpjXCCIesMEIGCisGAQQBgjcCAQwxNDAy\r\n# oBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5j\r\n# b20wDQYJKoZIhvcNAQEBBQAEggEAwETHSA6ffhhSRTPNmFZi9dFIoroMG7jii7/9\r\n# LMoCAZgwSeSzaZs3vo1EaRFFZvaKoQkPITRK9rBjINt9jLGalSs2jrwdM/E5wa8k\r\n# bKFY4VEB/aJffdDIGiAsMu+gOWxCOFS8xdYzlZfRlFe9f6VVRtCyubOok3BSZRrq\r\n# cCFpCprCa34w/J8erd7FF54qJ2IrO3bEd4w+23w3qg1BwtPr/vqLchKyIEBjzpcL\r\n# 78/CJEUpFbtz/VuvyLfeVoSEnj6Ctf0tFDvRDNXGPqp1ZJSitKDsrQseb2K5/pZO\r\n# nyykNPzpxJmIaLHDgBjtGlXuiHUEuJAFV96oucoIydX1dqQal6GCFwwwghcIBgor\r\n# BgEEAYI3AwMBMYIW+DCCFvQGCSqGSIb3DQEHAqCCFuUwghbhAgEDMQ8wDQYJYIZI\r\n# AWUDBAIBBQAwggFVBgsqhkiG9w0BCRABBKCCAUQEggFAMIIBPAIBAQYKKwYBBAGE\r\n# WQoDATAxMA0GCWCGSAFlAwQCAQUABCCmK+qErRnVeAaOr2etmjZMIBNv7JyifxQE\r\n# HuWjeTnqvAIGYrGiJBRoGBMyMDIyMDcwMTIxMDAwMS42ODRaMASAAgH0oIHUpIHR\r\n# MIHOMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH\r\n# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSkwJwYDVQQL\r\n# EyBNaWNyb3NvZnQgT3BlcmF0aW9ucyBQdWVydG8gUmljbzEmMCQGA1UECxMdVGhh\r\n# bGVzIFRTUyBFU046NDYyRi1FMzE5LTNGMjAxJTAjBgNVBAMTHE1pY3Jvc29mdCBU\r\n# aW1lLVN0YW1wIFNlcnZpY2WgghFfMIIHEDCCBPigAwIBAgITMwAAAaQHz+OPo7pv\r\n# 1gABAAABpDANBgkqhkiG9w0BAQsFADB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMK\r\n# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0\r\n# IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0Eg\r\n# MjAxMDAeFw0yMjAzMDIxODUxMThaFw0yMzA1MTExODUxMThaMIHOMQswCQYDVQQG\r\n# EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG\r\n# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSkwJwYDVQQLEyBNaWNyb3NvZnQg\r\n# T3BlcmF0aW9ucyBQdWVydG8gUmljbzEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046\r\n# NDYyRi1FMzE5LTNGMjAxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNl\r\n# cnZpY2UwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDAR44A+hT8vNT1\r\n# IXDiFRoeGzkmqut+GPk41toTRfQZZ1sSyQhLjIlemBecemEzO09WSzOjZx9MIT8q\r\n# Ys921WUZsIBsk1ESn1cjyfPUd1mmfxzL3ACWZwjIC/pjqcRPeIMECQ/6qPFKrjqw\r\n# igmP33I3IcVfMjJHyKj+vR51n1tK2rZPiNhmRdiEhckbbxLsSb2nCBQxZEF49x/l\r\n# 8vSB8zaqovoOeIkIzgDerN7OvJouq6r+vg/Qz1T4NXr+sKKyNxZWM6zywiLp7G7W\r\n# Ld18N2hyjHwPkh/AleIqif3hGVD9bhSU+dDADzUJSMFhEWunHHElQeZjdmIB3/Mw\r\n# 1KkFOJNvw1sPteIi5MK4DZX3Wd/Fd8ZsQvZmXPWJ8BXN9sYtHMz8zdeQvMImRCKg\r\n# nXcW8IpnPtC7Tymp3UV5NoTH8INF6WWicQ3y04L2I1VOT104AddJoVgAP2KLIGwf\r\n# Cs7wMVz56xJ2IN1y1pIAWfpTqx76orM5RQhkAvayj1RTwgrHst+elYX3F5b8ACWr\r\n# gJO1dJy1U4MIv+SC8h33xLmWA568emvrJ6g0xy/2akbAeRx6tFwaP4uwVbjF50kl\r\n# 5RQqNzp/CDpfCTikOAqyJa4valiWDMbEiArHKLYDg6GDjuJZl5bSjgdJdCAIRF8E\r\n# kiiA+UAGvcE6SGoHmtoc4yOklGNVvwIDAQABo4IBNjCCATIwHQYDVR0OBBYEFOLQ\r\n# E5+s+AgS9sWUHdI4zekp4yTCMB8GA1UdIwQYMBaAFJ+nFV0AXmJdg/Tl0mWnG1M1\r\n# GelyMF8GA1UdHwRYMFYwVKBSoFCGTmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9w\r\n# a2lvcHMvY3JsL01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEp\r\n# LmNybDBsBggrBgEFBQcBAQRgMF4wXAYIKwYBBQUHMAKGUGh0dHA6Ly93d3cubWlj\r\n# cm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUy\r\n# MFBDQSUyMDIwMTAoMSkuY3J0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYB\r\n# BQUHAwgwDQYJKoZIhvcNAQELBQADggIBAAlWHFDRDJck7jwwRoYmdVOePLLBeido\r\n# PUBJVhG9nGeHS9PuRvO9tf4IkbUz74MUIQxeayQoxxo/JxUqjhPH52M/b4G9mHJW\r\n# B75KCllCTg8Y4VkvktOmS0f5w0vOR3gwA9BRnbgAPNEO7xs5Jylto8aDR02++CkB\r\n# DFolCtTNjwzfniEj1z4T7nRlRi2yBAJNRqI+VY820LiyoZtk5OGttq5F5HhPfIMj\r\n# aIx5QYR22+53sd8xgUwRpFbcLdrne6jdq3KbiYbCf7y/9F2C7cjpO3kkGXX8ntE0\r\n# 9f6o9fIklx7CFw4RzrkyqgYomraKOFJ8JO7hsjNJb9/Gba/mKWo0j/qdDxDER/UX\r\n# X6ykZuGx1eQpjkyMwJnOPWGbeNIYZVcJQpRQODPs593Mi5hBsHzag+vd4Q+Vt73K\r\n# Z4X98YWW1Vk1aSR9Qjxk5keMuVPZMcMrCvFZXwhUcGFGueuNCrICL9bSYRfS13pl\r\n# iDxJ7sPSZ8x2d4ksOXW00l6fR5nTiSM7Dvv7Y0MGVgUhap2smhr92PMNSmIkCUvH\r\n# CiYcJ4RoAT28mp/hOQ/U8mPXSpWdxYpLLcDOISmBhFJYN7amlhIpVsGvUmjXrTcY\r\n# 0n4Goe/Nqs2400IcA4HOiX9OxdmpNGDJzSRR7AW9TT8O+3YZqPZIvL6yzgfvnehp\r\n# tmf4w6QzkrLfMIIHcTCCBVmgAwIBAgITMwAAABXF52ueAptJmQAAAAAAFTANBgkq\r\n# hkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x\r\n# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv\r\n# bjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5\r\n# IDIwMTAwHhcNMjEwOTMwMTgyMjI1WhcNMzAwOTMwMTgzMjI1WjB8MQswCQYDVQQG\r\n# EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG\r\n# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQg\r\n# VGltZS1TdGFtcCBQQ0EgMjAxMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC\r\n# ggIBAOThpkzntHIhC3miy9ckeb0O1YLT/e6cBwfSqWxOdcjKNVf2AX9sSuDivbk+\r\n# F2Az/1xPx2b3lVNxWuJ+Slr+uDZnhUYjDLWNE893MsAQGOhgfWpSg0S3po5GawcU\r\n# 88V29YZQ3MFEyHFcUTE3oAo4bo3t1w/YJlN8OWECesSq/XJprx2rrPY2vjUmZNqY\r\n# O7oaezOtgFt+jBAcnVL+tuhiJdxqD89d9P6OU8/W7IVWTe/dvI2k45GPsjksUZzp\r\n# cGkNyjYtcI4xyDUoveO0hyTD4MmPfrVUj9z6BVWYbWg7mka97aSueik3rMvrg0Xn\r\n# Rm7KMtXAhjBcTyziYrLNueKNiOSWrAFKu75xqRdbZ2De+JKRHh09/SDPc31BmkZ1\r\n# zcRfNN0Sidb9pSB9fvzZnkXftnIv231fgLrbqn427DZM9ituqBJR6L8FA6PRc6ZN\r\n# N3SUHDSCD/AQ8rdHGO2n6Jl8P0zbr17C89XYcz1DTsEzOUyOArxCaC4Q6oRRRuLR\r\n# vWoYWmEBc8pnol7XKHYC4jMYctenIPDC+hIK12NvDMk2ZItboKaDIV1fMHSRlJTY\r\n# uVD5C4lh8zYGNRiER9vcG9H9stQcxWv2XFJRXRLbJbqvUAV6bMURHXLvjflSxIUX\r\n# k8A8FdsaN8cIFRg/eKtFtvUeh17aj54WcmnGrnu3tz5q4i6tAgMBAAGjggHdMIIB\r\n# 2TASBgkrBgEEAYI3FQEEBQIDAQABMCMGCSsGAQQBgjcVAgQWBBQqp1L+ZMSavoKR\r\n# PEY1Kc8Q/y8E7jAdBgNVHQ4EFgQUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXAYDVR0g\r\n# BFUwUzBRBgwrBgEEAYI3TIN9AQEwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5t\r\n# aWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMBMGA1UdJQQM\r\n# MAoGCCsGAQUFBwMIMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQE\r\n# AwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQ\r\n# W9fOmhjEMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNv\r\n# bS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBa\r\n# BggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0\r\n# LmNvbS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MA0GCSqG\r\n# SIb3DQEBCwUAA4ICAQCdVX38Kq3hLB9nATEkW+Geckv8qW/qXBS2Pk5HZHixBpOX\r\n# PTEztTnXwnE2P9pkbHzQdTltuw8x5MKP+2zRoZQYIu7pZmc6U03dmLq2HnjYNi6c\r\n# qYJWAAOwBb6J6Gngugnue99qb74py27YP0h1AdkY3m2CDPVtI1TkeFN1JFe53Z/z\r\n# jj3G82jfZfakVqr3lbYoVSfQJL1AoL8ZthISEV09J+BAljis9/kpicO8F7BUhUKz\r\n# /AyeixmJ5/ALaoHCgRlCGVJ1ijbCHcNhcy4sa3tuPywJeBTpkbKpW99Jo3QMvOyR\r\n# gNI95ko+ZjtPu4b6MhrZlvSP9pEB9s7GdP32THJvEKt1MMU0sHrYUP4KWN1APMdU\r\n# bZ1jdEgssU5HLcEUBHG/ZPkkvnNtyo4JvbMBV0lUZNlz138eW0QBjloZkWsNn6Qo\r\n# 3GcZKCS6OEuabvshVGtqRRFHqfG3rsjoiV5PndLQTHa1V1QJsWkBRH58oWFsc/4K\r\n# u+xBZj1p/cvBQUl+fpO+y/g75LcVv7TOPqUxUYS8vwLBgqJ7Fx0ViY1w/ue10Cga\r\n# iQuPNtq6TPmb/wrpNPgkNWcr4A245oyZ1uEi6vAnQj0llOZ0dFtq0Z4+7X6gMTN9\r\n# vMvpe784cETRkPHIqzqKOghif9lwY1NNje6CbaUFEMFxBmoQtB1VM1izoXBm8qGC\r\n# AtIwggI7AgEBMIH8oYHUpIHRMIHOMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz\r\n# aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv\r\n# cnBvcmF0aW9uMSkwJwYDVQQLEyBNaWNyb3NvZnQgT3BlcmF0aW9ucyBQdWVydG8g\r\n# UmljbzEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046NDYyRi1FMzE5LTNGMjAxJTAj\r\n# BgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2WiIwoBATAHBgUrDgMC\r\n# GgMVADQcKOKTa3xC+g1aPrcPerxiby6foIGDMIGApH4wfDELMAkGA1UEBhMCVVMx\r\n# EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT\r\n# FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUt\r\n# U3RhbXAgUENBIDIwMTAwDQYJKoZIhvcNAQEFBQACBQDmaU8/MCIYDzIwMjIwNzAx\r\n# MTQ0NzI3WhgPMjAyMjA3MDIxNDQ3MjdaMHcwPQYKKwYBBAGEWQoEATEvMC0wCgIF\r\n# AOZpTz8CAQAwCgIBAAICCNwCAf8wBwIBAAICEp4wCgIFAOZqoL8CAQAwNgYKKwYB\r\n# BAGEWQoEAjEoMCYwDAYKKwYBBAGEWQoDAqAKMAgCAQACAwehIKEKMAgCAQACAwGG\r\n# oDANBgkqhkiG9w0BAQUFAAOBgQChh1QY1GFw/ekl4Qr+s3lJOVBWDUpw+EfxjUrG\r\n# H7ud+AMLNhAxbx7uEfNyNYsi5CnaaXgA2vO00zzDNvaugU/yTYxEm2j0wybQTDfb\r\n# BMyUPQB6VhcFgCAOC4CQalIa1F5xOFEYV2P5/OY3Fza/pCGQKiBEDyRG6PfCbmAZ\r\n# qvg7cTGCBA0wggQJAgEBMIGTMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo\r\n# aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y\r\n# cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw\r\n# AhMzAAABpAfP44+jum/WAAEAAAGkMA0GCWCGSAFlAwQCAQUAoIIBSjAaBgkqhkiG\r\n# 9w0BCQMxDQYLKoZIhvcNAQkQAQQwLwYJKoZIhvcNAQkEMSIEIADlNEKhG3BnRkhq\r\n# cXD/tb/UR5BXxdcKHp5Lt8yia4ZxMIH6BgsqhkiG9w0BCRACLzGB6jCB5zCB5DCB\r\n# vQQgBfzgoyEmcKTASfDCd1sDAhd6jmuWBxRuieLh42rqefgwgZgwgYCkfjB8MQsw\r\n# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u\r\n# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNy\r\n# b3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAaQHz+OPo7pv1gABAAABpDAi\r\n# BCBoSzA9nCaw+Pk/XGE5FyHMvYr0QOQne8MeefMn3+/YZjANBgkqhkiG9w0BAQsF\r\n# AASCAgAVCHZ4zg4+oaqb2mTbyBn1iELiCCLutlG+ij8/By/6KzRjhS79sCiJwxuR\r\n# 0X6tVul89m21uZwJPqhV7v4FkoAC9phxUr5T7YxGrPXzHpJitYLWCG9GewR2PfPr\r\n# y7JhUCPAN4hNHR4Z8GLJFTXv1eQyKkeDlSxivC29GWn1X7eTfAKCwtDyjkWeoe4c\r\n# hrHzgdREjT7p7z0UKXn5zT4CYsdCYYePTcrtcPQ8YKRZfQhVhAcHPzo1f2r5bRdr\r\n# EkAmFHpx0hhKEPRke/dszJ14ykLOqEgRMAqyzgE9WUGc87TGdhGrsB7kZHPgnDLn\r\n# MyP5FReopTZDLlmEg++XN1/FCfVr1aUVXwlr8U5BQLMhhz/L14pX7Rpho15O13WR\r\n# FpuqsPpy+Age70j5efz9BiSnT4jyUzkFdKSbUf0512UrfhVsqw7POXkuvd+VSqH0\r\n# i3VpF6E7MlPUw/xWBE8xyfGISmMM4awoQBjOs4ir60ktDowkvckkmoSGgf9YLFXt\r\n# jwnh65g7XvREpcLsJpOx6PvMKxWQ0ePPy1kl1uKWWpSe7kNwdMywl60FBFC1hWVi\r\n# ktBE98W2j6B4MwGSL2F7hWz7LNs1ROI8YAPaj6+2gK7oYEQvd0wVvsNyzDQ6oIiJ\r\n# VU2Rt5sblCaZvMF4XMba1eIRpNOrm45iPMmRsypgZdBSy4wtOw==\r\n# SIG # End signature block\r\n"
  },
  {
    "path": "src/PowerShell/ExternalModules/PowerShellGet/2.2.5/DscResources/MSFT_PSModule/MSFT_PSModule.psm1",
    "content": "#\r\n# Copyright (c) Microsoft Corporation.\r\n#\r\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n# THE SOFTWARE.\r\n#\r\n\r\n$resourceModuleRoot = Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent\r\n\r\n# Import localization helper functions.\r\n$helperName = 'PowerShellGet.LocalizationHelper'\r\n$dscResourcesFolderFilePath = Join-Path -Path $resourceModuleRoot -ChildPath \"Modules\\$helperName\\$helperName.psm1\"\r\nImport-Module -Name $dscResourcesFolderFilePath\r\n\r\n$script:localizedData = Get-LocalizedData -ResourceName 'MSFT_PSModule' -ScriptRoot $PSScriptRoot\r\n\r\n# Import resource helper functions.\r\n$helperName = 'PowerShellGet.ResourceHelper'\r\n$dscResourcesFolderFilePath = Join-Path -Path $resourceModuleRoot -ChildPath \"Modules\\$helperName\\$helperName.psm1\"\r\nImport-Module -Name $dscResourcesFolderFilePath\r\n\r\n<#\r\n    .SYNOPSIS\r\n        This DSC resource provides a mechanism to download PowerShell modules from the PowerShell\r\n        Gallery and install it on your computer.\r\n\r\n        Get-TargetResource returns the current state of the resource.\r\n\r\n    .PARAMETER Name\r\n        Specifies the name of the PowerShell module to be installed or uninstalled.\r\n\r\n    .PARAMETER Repository\r\n        Specifies the name of the module source repository where the module can be found.\r\n\r\n    .PARAMETER RequiredVersion\r\n        Provides the version of the module you want to install or uninstall.\r\n\r\n    .PARAMETER MaximumVersion\r\n        Provides the maximum version of the module you want to install or uninstall.\r\n\r\n    .PARAMETER MinimumVersion\r\n        Provides the minimum version of the module you want to install or uninstall.\r\n\r\n    .PARAMETER Force\r\n        Forces the installation of modules. If a module of the same name and version already exists on the computer,\r\n        this parameter overwrites the existing module with one of the same name that was found by the command.\r\n\r\n    .PARAMETER AllowClobber\r\n        Allows the installation of modules regardless of if other existing module on the computer have cmdlets\r\n        of the same name.\r\n\r\n    .PARAMETER SkipPublisherCheck\r\n        Allows the installation of modules that have not been catalog signed.\r\n#>\r\nfunction Get-TargetResource {\r\n    <#\r\n        These suppressions are added because this repository have other Visual Studio Code workspace\r\n        settings than those in DscResource.Tests DSC test framework.\r\n        Only those suppression that contradict this repository guideline is added here.\r\n    #>\r\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\\Measure-ForEachStatement', '')]\r\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\\Measure-FunctionBlockBraces', '')]\r\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\\Measure-IfStatement', '')]\r\n    [CmdletBinding()]\r\n    [OutputType([System.Collections.Hashtable])]\r\n    param\r\n    (\r\n        [Parameter(Mandatory = $true)]\r\n        [System.String]\r\n        $Name,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $Repository = 'PSGallery',\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $RequiredVersion,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $MaximumVersion,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $MinimumVersion,\r\n\r\n        [Parameter()]\r\n        [System.Boolean]\r\n        $Force,\r\n\r\n        [Parameter()]\r\n        [System.Boolean]\r\n        $AllowClobber,\r\n\r\n        [Parameter()]\r\n        [System.Boolean]\r\n        $SkipPublisherCheck\r\n    )\r\n\r\n    $returnValue = @{\r\n        Ensure             = 'Absent'\r\n        Name               = $Name\r\n        Repository         = $Repository\r\n        Description        = $null\r\n        Guid               = $null\r\n        ModuleBase         = $null\r\n        ModuleType         = $null\r\n        Author             = $null\r\n        InstalledVersion   = $null\r\n        RequiredVersion    = $RequiredVersion\r\n        MinimumVersion     = $MinimumVersion\r\n        MaximumVersion     = $MaximumVersion\r\n        Force              = $Force\r\n        AllowClobber       = $AllowClobber\r\n        SkipPublisherCheck = $SkipPublisherCheck\r\n        InstallationPolicy = $null\r\n    }\r\n\r\n    Write-Verbose -Message ($localizedData.GetTargetResourceMessage -f $Name)\r\n\r\n    $extractedArguments = New-SplatParameterHashTable -FunctionBoundParameters $PSBoundParameters `\r\n        -ArgumentNames ('Name', 'Repository', 'MinimumVersion', 'MaximumVersion', 'RequiredVersion')\r\n\r\n    # Get the module with the right version and repository properties.\r\n    $modules = Get-RightModule @extractedArguments -ErrorAction SilentlyContinue -WarningAction SilentlyContinue\r\n\r\n    # If the module is found, the count > 0\r\n    if ($modules.Count -gt 0) {\r\n        Write-Verbose -Message ($localizedData.ModuleFound -f $Name)\r\n\r\n        # Find a module with the latest version and return its properties.\r\n        $latestModule = $modules[0]\r\n\r\n        foreach ($module in $modules) {\r\n            if ($module.Version -gt $latestModule.Version) {\r\n                $latestModule = $module\r\n            }\r\n        }\r\n\r\n        # Check if the repository matches.\r\n        $repositoryName = Get-ModuleRepositoryName -Module $latestModule -ErrorAction SilentlyContinue -WarningAction SilentlyContinue\r\n\r\n        if ($repositoryName) {\r\n            $installationPolicy = Get-InstallationPolicy -RepositoryName $repositoryName -ErrorAction SilentlyContinue -WarningAction SilentlyContinue\r\n        }\r\n\r\n        if ($installationPolicy) {\r\n            $installationPolicyReturnValue = 'Trusted'\r\n        }\r\n        else {\r\n            $installationPolicyReturnValue = 'Untrusted'\r\n        }\r\n\r\n        $returnValue.Ensure = 'Present'\r\n        $returnValue.Repository = $repositoryName\r\n        $returnValue.Description = $latestModule.Description\r\n        $returnValue.Guid = $latestModule.Guid\r\n        $returnValue.ModuleBase = $latestModule.ModuleBase\r\n        $returnValue.ModuleType = $latestModule.ModuleType\r\n        $returnValue.Author = $latestModule.Author\r\n        $returnValue.InstalledVersion = $latestModule.Version\r\n        $returnValue.InstallationPolicy = $installationPolicyReturnValue\r\n    }\r\n    else {\r\n        Write-Verbose -Message ($localizedData.ModuleNotFound -f $Name)\r\n    }\r\n\r\n    return $returnValue\r\n}\r\n\r\n<#\r\n    .SYNOPSIS\r\n        This DSC resource provides a mechanism to download PowerShell modules from the PowerShell\r\n        Gallery and install it on your computer.\r\n\r\n        Test-TargetResource validates whether the resource is currently in the desired state.\r\n\r\n    .PARAMETER Ensure\r\n        Determines whether the module to be installed or uninstalled.\r\n\r\n    .PARAMETER Name\r\n        Specifies the name of the PowerShell module to be installed or uninstalled.\r\n\r\n    .PARAMETER Repository\r\n        Specifies the name of the module source repository where the module can be found.\r\n\r\n    .PARAMETER InstallationPolicy\r\n        Determines whether you trust the source repository where the module resides.\r\n\r\n    .PARAMETER RequiredVersion\r\n        Provides the version of the module you want to install or uninstall.\r\n\r\n    .PARAMETER MaximumVersion\r\n        Provides the maximum version of the module you want to install or uninstall.\r\n\r\n    .PARAMETER MinimumVersion\r\n        Provides the minimum version of the module you want to install or uninstall.\r\n\r\n    .PARAMETER Force\r\n        Forces the installation of modules. If a module of the same name and version already exists on the computer,\r\n        this parameter overwrites the existing module with one of the same name that was found by the command.\r\n\r\n    .PARAMETER AllowClobber\r\n        Allows the installation of modules regardless of if other existing module on the computer have cmdlets\r\n        of the same name.\r\n\r\n    .PARAMETER SkipPublisherCheck\r\n        Allows the installation of modules that have not been catalog signed.\r\n#>\r\nfunction Test-TargetResource {\r\n    <#\r\n        These suppressions are added because this repository have other Visual Studio Code workspace\r\n        settings than those in DscResource.Tests DSC test framework.\r\n        Only those suppression that contradict this repository guideline is added here.\r\n    #>\r\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\\Measure-FunctionBlockBraces', '')]\r\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\\Measure-IfStatement', '')]\r\n    [CmdletBinding()]\r\n    [OutputType([System.Boolean])]\r\n    param\r\n    (\r\n        [Parameter()]\r\n        [ValidateSet('Present', 'Absent')]\r\n        [System.String]\r\n        $Ensure = 'Present',\r\n\r\n        [Parameter(Mandatory = $true)]\r\n        [System.String]\r\n        $Name,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $Repository = 'PSGallery',\r\n\r\n        [Parameter()]\r\n        [ValidateSet('Trusted', 'Untrusted')]\r\n        [System.String]\r\n        $InstallationPolicy = 'Untrusted',\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $RequiredVersion,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $MaximumVersion,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $MinimumVersion,\r\n\r\n        [Parameter()]\r\n        [System.Boolean]\r\n        $Force,\r\n\r\n        [Parameter()]\r\n        [System.Boolean]\r\n        $AllowClobber,\r\n\r\n        [Parameter()]\r\n        [System.Boolean]\r\n        $SkipPublisherCheck\r\n    )\r\n\r\n    Write-Verbose -Message ($localizedData.TestTargetResourceMessage -f $Name)\r\n\r\n    $extractedArguments = New-SplatParameterHashTable -FunctionBoundParameters $PSBoundParameters `\r\n        -ArgumentNames ('Name', 'Repository', 'MinimumVersion', 'MaximumVersion', 'RequiredVersion')\r\n\r\n    $status = Get-TargetResource @extractedArguments\r\n\r\n    # The ensure returned from Get-TargetResource is not equal to the desired $Ensure.\r\n    if ($status.Ensure -ieq $Ensure) {\r\n        Write-Verbose -Message ($localizedData.InDesiredState -f $Name)\r\n        return $true\r\n    }\r\n    else {\r\n        Write-Verbose -Message ($localizedData.NotInDesiredState -f $Name)\r\n        return $false\r\n    }\r\n}\r\n\r\n<#\r\n    .SYNOPSIS\r\n        This DSC resource provides a mechanism to download PowerShell modules from the PowerShell\r\n        Gallery and install it on your computer.\r\n\r\n        Set-TargetResource sets the resource to the desired state. \"Make it so\".\r\n\r\n    .PARAMETER Ensure\r\n        Determines whether the module to be installed or uninstalled.\r\n\r\n    .PARAMETER Name\r\n        Specifies the name of the PowerShell module to be installed or uninstalled.\r\n\r\n    .PARAMETER Repository\r\n        Specifies the name of the module source repository where the module can be found.\r\n\r\n    .PARAMETER InstallationPolicy\r\n        Determines whether you trust the source repository where the module resides.\r\n\r\n    .PARAMETER RequiredVersion\r\n        Provides the version of the module you want to install or uninstall.\r\n\r\n    .PARAMETER MaximumVersion\r\n        Provides the maximum version of the module you want to install or uninstall.\r\n\r\n    .PARAMETER MinimumVersion\r\n        Provides the minimum version of the module you want to install or uninstall.\r\n\r\n    .PARAMETER Force\r\n        Forces the installation of modules. If a module of the same name and version already exists on the computer,\r\n        this parameter overwrites the existing module with one of the same name that was found by the command.\r\n\r\n    .PARAMETER AllowClobber\r\n        Allows the installation of modules regardless of if other existing module on the computer have cmdlets\r\n        of the same name.\r\n\r\n    .PARAMETER SkipPublisherCheck\r\n        Allows the installation of modules that have not been catalog signed.\r\n#>\r\nfunction Set-TargetResource {\r\n    <#\r\n        These suppressions are added because this repository have other Visual Studio Code workspace\r\n        settings than those in DscResource.Tests DSC test framework.\r\n        Only those suppression that contradict this repository guideline is added here.\r\n    #>\r\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\\Measure-ForEachStatement', '')]\r\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\\Measure-FunctionBlockBraces', '')]\r\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\\Measure-IfStatement', '')]\r\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\\Measure-TryStatement', '')]\r\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\\Measure-CatchClause', '')]\r\n    [CmdletBinding()]\r\n    param\r\n    (\r\n        [Parameter()]\r\n        [ValidateSet('Present', 'Absent')]\r\n        [System.String]\r\n        $Ensure = 'Present',\r\n\r\n        [Parameter(Mandatory = $true)]\r\n        [System.String]\r\n        $Name,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $Repository = 'PSGallery',\r\n\r\n        [Parameter()]\r\n        [ValidateSet('Trusted', 'Untrusted')]\r\n        [System.String]\r\n        $InstallationPolicy = 'Untrusted',\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $RequiredVersion,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $MaximumVersion,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $MinimumVersion,\r\n\r\n        [Parameter()]\r\n        [System.Boolean]\r\n        $Force,\r\n\r\n        [Parameter()]\r\n        [System.Boolean]\r\n        $AllowClobber,\r\n\r\n        [Parameter()]\r\n        [System.Boolean]\r\n        $SkipPublisherCheck\r\n    )\r\n\r\n    # Validate the repository argument\r\n    if ($PSBoundParameters.ContainsKey('Repository')) {\r\n        Test-ParameterValue -Value $Repository -Type 'PackageSource' -ProviderName 'PowerShellGet' -Verbose\r\n    }\r\n\r\n    if ($Ensure -ieq 'Present') {\r\n        # Version check\r\n        $extractedArguments = New-SplatParameterHashTable -FunctionBoundParameters $PSBoundParameters `\r\n            -ArgumentNames ('MinimumVersion', 'MaximumVersion', 'RequiredVersion')\r\n\r\n        $null = Test-VersionParameter @extractedArguments\r\n\r\n        try {\r\n            $extractedArguments = New-SplatParameterHashTable -FunctionBoundParameters $PSBoundParameters `\r\n                -ArgumentNames ('Name', 'Repository', 'MinimumVersion', 'MaximumVersion', 'RequiredVersion')\r\n\r\n            Write-Verbose -Message ($localizedData.StartFindModule -f $Name)\r\n\r\n            $modules = Find-Module @extractedArguments -ErrorVariable ev\r\n        }\r\n        catch {\r\n            $errorMessage = $script:localizedData.ModuleNotFoundInRepository -f $Name\r\n            New-InvalidOperationException -Message $errorMessage -ErrorRecord $_\r\n        }\r\n\r\n        $trusted = $null\r\n        $moduleFound = $null\r\n\r\n        foreach ($m in $modules) {\r\n            # Check for the installation policy.\r\n            $trusted = Get-InstallationPolicy -RepositoryName $m.Repository -ErrorAction SilentlyContinue -WarningAction SilentlyContinue\r\n\r\n            # Stop the loop if found a trusted repository.\r\n            if ($trusted) {\r\n                $moduleFound = $m\r\n                break;\r\n            }\r\n        }\r\n\r\n        try {\r\n            # The repository is trusted, so we install it.\r\n            if ($trusted) {\r\n                Write-Verbose -Message ($localizedData.StartInstallModule -f $Name, $moduleFound.Version.toString(), $moduleFound.Repository)\r\n\r\n                # Extract the installation options.\r\n                $extractedSwitches = New-SplatParameterHashTable -FunctionBoundParameters $PSBoundParameters -ArgumentNames ('Force', 'AllowClobber', 'SkipPublisherCheck')\r\n\r\n                $moduleFound | Install-Module @extractedSwitches 2>&1 | out-string | Write-Verbose\r\n            }\r\n            # The repository is untrusted but user's installation policy is trusted, so we install it with a warning.\r\n            elseif ($InstallationPolicy -ieq 'Trusted') {\r\n                Write-Warning -Message ($localizedData.InstallationPolicyWarning -f $Name, $modules[0].Repository, $InstallationPolicy)\r\n\r\n                # Extract installation options (Force implied by InstallationPolicy).\r\n                $extractedSwitches = New-SplatParameterHashTable -FunctionBoundParameters $PSBoundParameters -ArgumentNames ('AllowClobber', 'SkipPublisherCheck')\r\n\r\n                # If all the repositories are untrusted, we choose the first one.\r\n                $modules[0] | Install-Module @extractedSwitches -Force 2>&1 | out-string | Write-Verbose\r\n            }\r\n            # Both user and repository is untrusted\r\n            else {\r\n                $errorMessage = $script:localizedData.InstallationPolicyFailed -f $InstallationPolicy, 'Untrusted'\r\n                New-InvalidOperationException -Message $errorMessage\r\n            }\r\n\r\n            Write-Verbose -Message ($localizedData.InstalledSuccess -f $Name)\r\n        }\r\n        catch {\r\n            $errorMessage = $script:localizedData.FailToInstall -f $Name\r\n            New-InvalidOperationException -Message $errorMessage -ErrorRecord $_\r\n        }\r\n    }\r\n    # Ensure=Absent\r\n    else {\r\n\r\n        $extractedArguments = New-SplatParameterHashTable -FunctionBoundParameters $PSBoundParameters `\r\n            -ArgumentNames ('Name', 'Repository', 'MinimumVersion', 'MaximumVersion', 'RequiredVersion')\r\n\r\n        # Get the module with the right version and repository properties.\r\n        $modules = Get-RightModule @extractedArguments\r\n\r\n        if (-not $modules) {\r\n            $errorMessage = $script:localizedData.ModuleWithRightPropertyNotFound -f $Name\r\n            New-InvalidOperationException -Message $errorMessage\r\n        }\r\n\r\n        foreach ($module in $modules) {\r\n            # Get the path where the module is installed.\r\n            $path = $module.ModuleBase\r\n\r\n            Write-Verbose -Message ($localizedData.StartUnInstallModule -f $Name)\r\n\r\n            try {\r\n                <#\r\n                    There is no Uninstall-Module cmdlet for Windows PowerShell 4.0,\r\n                    so we will remove the ModuleBase folder as an uninstall operation.\r\n                #>\r\n                Microsoft.PowerShell.Management\\Remove-Item -Path $path -Force -Recurse\r\n\r\n                Write-Verbose -Message ($localizedData.UnInstalledSuccess -f $module.Name)\r\n            }\r\n            catch {\r\n                $errorMessage = $script:localizedData.FailToUninstall -f $module.Name\r\n                New-InvalidOperationException -Message $errorMessage -ErrorRecord $_\r\n            }\r\n        } # foreach\r\n    } # Ensure=Absent\r\n}\r\n\r\n<#\r\n    .SYNOPSIS\r\n        This is a helper function. It returns the modules that meet the specified versions and the repository requirements.\r\n\r\n    .PARAMETER Name\r\n        Specifies the name of the PowerShell module.\r\n\r\n    .PARAMETER RequiredVersion\r\n        Provides the version of the module you want to install or uninstall.\r\n\r\n    .PARAMETER MaximumVersion\r\n        Provides the maximum version of the module you want to install or uninstall.\r\n\r\n    .PARAMETER MinimumVersion\r\n        Provides the minimum version of the module you want to install or uninstall.\r\n\r\n    .PARAMETER Repository\r\n        Specifies the name of the module source repository where the module can be found.\r\n#>\r\nfunction Get-RightModule {\r\n    <#\r\n        These suppressions are added because this repository have other Visual Studio Code workspace\r\n        settings than those in DscResource.Tests DSC test framework.\r\n        Only those suppression that contradict this repository guideline is added here.\r\n    #>\r\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\\Measure-ForEachStatement', '')]\r\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\\Measure-FunctionBlockBraces', '')]\r\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\\Measure-IfStatement', '')]\r\n    [CmdletBinding()]\r\n    param\r\n    (\r\n        [Parameter(Mandatory = $true)]\r\n        [ValidateNotNullOrEmpty()]\r\n        [System.String]\r\n        $Name,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $RequiredVersion,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $MinimumVersion,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $MaximumVersion,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $Repository\r\n    )\r\n\r\n    Write-Verbose -Message ($localizedData.StartGetModule -f $($Name))\r\n\r\n    $modules = Microsoft.PowerShell.Core\\Get-Module -Name $Name -ListAvailable -ErrorAction SilentlyContinue -WarningAction SilentlyContinue\r\n\r\n    if (-not $modules) {\r\n        return $null\r\n    }\r\n\r\n    <#\r\n        As Get-Module does not take RequiredVersion, MinimumVersion, MaximumVersion, or Repository,\r\n        below we need to check whether the modules are containing the right version and repository\r\n        location.\r\n    #>\r\n\r\n    $extractedArguments = New-SplatParameterHashTable -FunctionBoundParameters $PSBoundParameters `\r\n        -ArgumentNames ('MaximumVersion', 'MinimumVersion', 'RequiredVersion')\r\n    $returnVal = @()\r\n\r\n    foreach ($m in $modules) {\r\n        $versionMatch = $false\r\n        $installedVersion = $m.Version\r\n\r\n        # Case 1 - a user provides none of RequiredVersion, MinimumVersion, MaximumVersion\r\n        if ($extractedArguments.Count -eq 0) {\r\n            $versionMatch = $true\r\n        }\r\n\r\n        # Case 2 - a user provides RequiredVersion\r\n        elseif ($extractedArguments.ContainsKey('RequiredVersion')) {\r\n            # Check if it matches with the installed version\r\n            $versionMatch = ($installedVersion -eq [System.Version] $RequiredVersion)\r\n        }\r\n        else {\r\n\r\n            # Case 3 - a user provides MinimumVersion\r\n            if ($extractedArguments.ContainsKey('MinimumVersion')) {\r\n                $versionMatch = ($installedVersion -ge [System.Version] $extractedArguments['MinimumVersion'])\r\n            }\r\n\r\n            # Case 4 - a user provides MaximumVersion\r\n            if ($extractedArguments.ContainsKey('MaximumVersion')) {\r\n                $isLessThanMax = ($installedVersion -le [System.Version] $extractedArguments['MaximumVersion'])\r\n\r\n                if ($extractedArguments.ContainsKey('MinimumVersion')) {\r\n                    $versionMatch = $versionMatch -and $isLessThanMax\r\n                }\r\n                else {\r\n                    $versionMatch = $isLessThanMax\r\n                }\r\n            }\r\n\r\n            # Case 5 - Both MinimumVersion and MaximumVersion are provided. It's covered by the above.\r\n            # Do not return $false yet to allow the foreach to continue\r\n            if (-not $versionMatch) {\r\n                Write-Verbose -Message ($localizedData.VersionMismatch -f $Name, $installedVersion)\r\n                $versionMatch = $false\r\n            }\r\n        }\r\n\r\n        # Case 6 - Version matches but need to check if the module is from the right repository.\r\n        if ($versionMatch) {\r\n            # A user does not provide Repository, we are good\r\n            if (-not $PSBoundParameters.ContainsKey('Repository')) {\r\n                Write-Verbose -Message ($localizedData.ModuleFound -f \"$Name $installedVersion\")\r\n                $returnVal += $m\r\n            }\r\n            else {\r\n                # Check if the Repository matches\r\n                $sourceName = Get-ModuleRepositoryName -Module $m\r\n\r\n                if ($Repository -ieq $sourceName) {\r\n                    Write-Verbose -Message ($localizedData.ModuleFound -f \"$Name $installedVersion\")\r\n                    $returnVal += $m\r\n                }\r\n                else {\r\n                    Write-Verbose -Message ($localizedData.RepositoryMismatch -f $($Name), $($sourceName))\r\n                }\r\n            }\r\n        }\r\n    } # foreach\r\n\r\n    return $returnVal\r\n}\r\n\r\n<#\r\n    .SYNOPSIS\r\n        This is a helper function that returns the module's repository name.\r\n\r\n    .PARAMETER Module\r\n        Specifies the name of the PowerShell module.\r\n#>\r\nfunction Get-ModuleRepositoryName {\r\n    <#\r\n        These suppressions are added because this repository have other Visual Studio Code workspace\r\n        settings than those in DscResource.Tests DSC test framework.\r\n        Only those suppression that contradict this repository guideline is added here.\r\n    #>\r\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\\Measure-FunctionBlockBraces', '')]\r\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\\Measure-IfStatement', '')]\r\n    [CmdletBinding()]\r\n    param\r\n    (\r\n        [Parameter(Mandatory = $true)]\r\n        [ValidateNotNullOrEmpty()]\r\n        [System.Object]\r\n        $Module\r\n    )\r\n\r\n    <#\r\n        RepositorySourceLocation property is supported in PS V5 only. To work with the earlier\r\n        PowerShell version, we need to do a different way. PSGetModuleInfo.xml exists for any\r\n        PowerShell modules downloaded through PSModule provider.\r\n    #>\r\n    $psGetModuleInfoFileName = 'PSGetModuleInfo.xml'\r\n    $psGetModuleInfoPath = Microsoft.PowerShell.Management\\Join-Path -Path $Module.ModuleBase -ChildPath $psGetModuleInfoFileName\r\n\r\n    Write-Verbose -Message ($localizedData.FoundModulePath -f $psGetModuleInfoPath)\r\n\r\n    if (Microsoft.PowerShell.Management\\Test-path -Path $psGetModuleInfoPath) {\r\n        $psGetModuleInfo = Microsoft.PowerShell.Utility\\Import-Clixml -Path $psGetModuleInfoPath\r\n\r\n        return $psGetModuleInfo.Repository\r\n    }\r\n}\r\n\r\n# SIG # Begin signature block\r\n# MIIjkgYJKoZIhvcNAQcCoIIjgzCCI38CAQExDzANBglghkgBZQMEAgEFADB5Bgor\r\n# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG\r\n# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCig4H1kVMWxA7U\r\n# uX1JaRBJmDsHSZHmuBUTkDBwWHafCqCCDYEwggX/MIID56ADAgECAhMzAAABh3IX\r\n# chVZQMcJAAAAAAGHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD\r\n# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p\r\n# bmcgUENBIDIwMTEwHhcNMjAwMzA0MTgzOTQ3WhcNMjEwMzAzMTgzOTQ3WjB0MQsw\r\n# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u\r\n# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\r\n# AQDOt8kLc7P3T7MKIhouYHewMFmnq8Ayu7FOhZCQabVwBp2VS4WyB2Qe4TQBT8aB\r\n# znANDEPjHKNdPT8Xz5cNali6XHefS8i/WXtF0vSsP8NEv6mBHuA2p1fw2wB/F0dH\r\n# sJ3GfZ5c0sPJjklsiYqPw59xJ54kM91IOgiO2OUzjNAljPibjCWfH7UzQ1TPHc4d\r\n# weils8GEIrbBRb7IWwiObL12jWT4Yh71NQgvJ9Fn6+UhD9x2uk3dLj84vwt1NuFQ\r\n# itKJxIV0fVsRNR3abQVOLqpDugbr0SzNL6o8xzOHL5OXiGGwg6ekiXA1/2XXY7yV\r\n# Fc39tledDtZjSjNbex1zzwSXAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE\r\n# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUhov4ZyO96axkJdMjpzu2zVXOJcsw\r\n# UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1\r\n# ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDU4Mzg1MB8GA1UdIwQYMBaAFEhu\r\n# ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu\r\n# bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w\r\n# Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3\r\n# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx\r\n# MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAixmy\r\n# S6E6vprWD9KFNIB9G5zyMuIjZAOuUJ1EK/Vlg6Fb3ZHXjjUwATKIcXbFuFC6Wr4K\r\n# NrU4DY/sBVqmab5AC/je3bpUpjtxpEyqUqtPc30wEg/rO9vmKmqKoLPT37svc2NV\r\n# BmGNl+85qO4fV/w7Cx7J0Bbqk19KcRNdjt6eKoTnTPHBHlVHQIHZpMxacbFOAkJr\r\n# qAVkYZdz7ikNXTxV+GRb36tC4ByMNxE2DF7vFdvaiZP0CVZ5ByJ2gAhXMdK9+usx\r\n# zVk913qKde1OAuWdv+rndqkAIm8fUlRnr4saSCg7cIbUwCCf116wUJ7EuJDg0vHe\r\n# yhnCeHnBbyH3RZkHEi2ofmfgnFISJZDdMAeVZGVOh20Jp50XBzqokpPzeZ6zc1/g\r\n# yILNyiVgE+RPkjnUQshd1f1PMgn3tns2Cz7bJiVUaqEO3n9qRFgy5JuLae6UweGf\r\n# AeOo3dgLZxikKzYs3hDMaEtJq8IP71cX7QXe6lnMmXU/Hdfz2p897Zd+kU+vZvKI\r\n# 3cwLfuVQgK2RZ2z+Kc3K3dRPz2rXycK5XCuRZmvGab/WbrZiC7wJQapgBodltMI5\r\n# GMdFrBg9IeF7/rP4EqVQXeKtevTlZXjpuNhhjuR+2DMt/dWufjXpiW91bo3aH6Ea\r\n# jOALXmoxgltCp1K7hrS6gmsvj94cLRf50QQ4U8Qwggd6MIIFYqADAgECAgphDpDS\r\n# AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK\r\n# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0\r\n# IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0\r\n# ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla\r\n# MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS\r\n# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT\r\n# H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB\r\n# AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG\r\n# OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S\r\n# 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz\r\n# y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7\r\n# 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u\r\n# M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33\r\n# X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl\r\n# XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP\r\n# 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB\r\n# l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF\r\n# RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM\r\n# CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ\r\n# BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud\r\n# DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO\r\n# 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0\r\n# LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p\r\n# Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB\r\n# FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw\r\n# cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA\r\n# XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY\r\n# 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj\r\n# 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd\r\n# d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ\r\n# Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf\r\n# wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ\r\n# aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j\r\n# NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B\r\n# xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96\r\n# eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7\r\n# r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I\r\n# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVZzCCFWMCAQEwgZUwfjELMAkG\r\n# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx\r\n# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z\r\n# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAYdyF3IVWUDHCQAAAAABhzAN\r\n# BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor\r\n# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQg2t+ikpO2\r\n# 0WdDEf/JRKsEEOWFz2O6CEnKmWwPbrvPFuIwQgYKKwYBBAGCNwIBDDE0MDKgFIAS\r\n# AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN\r\n# BgkqhkiG9w0BAQEFAASCAQBaj/JIwAbud/IMJN3SHVwenJwEjzrmM3cPznYlvkyE\r\n# rnB6RiDYnohm+72wkCmVWobuualV9Xw8OGA9w7MvJjZuEnFP9TwDjlWinR4FpdVl\r\n# YX49u4g50iMR2isaKTxMA2nA2LbyFpTLMqi6ynPLnv251xTdumj/XRLZjHdpr4Pt\r\n# p6HQz45/jMWRtlh8x3piJPrgpINuJtmO91tnMQnykF++QgteDqKSboXOu2Wg0oCn\r\n# Ao0eOifIujyUp2ez9Cqx2hzkMOqNa5jZD4JetiDTWBTkN8XHRbsfCVwyEQzxrpXn\r\n# wAFT7jMzuI8o8xdCuCvuDokIzcnm+rKZJIy6Rwp6Cn11oYIS8TCCEu0GCisGAQQB\r\n# gjcDAwExghLdMIIS2QYJKoZIhvcNAQcCoIISyjCCEsYCAQMxDzANBglghkgBZQME\r\n# AgEFADCCAVUGCyqGSIb3DQEJEAEEoIIBRASCAUAwggE8AgEBBgorBgEEAYRZCgMB\r\n# MDEwDQYJYIZIAWUDBAIBBQAEIL/3GmTbcOXlRJe8Pu+1/QVBo0Mk83o/PGK7iApB\r\n# aAutAgZfYQoJ7SUYEzIwMjAwOTIyMjIxOTUxLjg4NlowBIACAfSggdSkgdEwgc4x\r\n# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt\r\n# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1p\r\n# Y3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMg\r\n# VFNTIEVTTjo4OTdBLUUzNTYtMTcwMTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt\r\n# U3RhbXAgU2VydmljZaCCDkQwggT1MIID3aADAgECAhMzAAABLCKvRZd1+RvuAAAA\r\n# AAEsMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo\r\n# aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y\r\n# cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw\r\n# MB4XDTE5MTIxOTAxMTUwM1oXDTIxMDMxNzAxMTUwM1owgc4xCzAJBgNVBAYTAlVT\r\n# MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK\r\n# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVy\r\n# YXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo4OTdB\r\n# LUUzNTYtMTcwMTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vydmlj\r\n# ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPK1zgSSq+MxAYo3qpCt\r\n# QDxSMPPJy6mm/wfEJNjNUnYtLFBwl1BUS5trEk/t41ldxITKehs+ABxYqo4Qxsg3\r\n# Gy1ugKiwHAnYiiekfC+ZhptNFgtnDZIn45zC0AlVr/6UfLtsLcHCh1XElLUHfEC0\r\n# nBuQcM/SpYo9e3l1qY5NdMgDGxCsmCKdiZfYXIu+U0UYIBhdzmSHnB3fxZOBVcr5\r\n# htFHEBBNt/rFJlm/A4yb8oBsp+Uf0p5QwmO/bCcdqB15JpylOhZmWs0sUfJKlK9E\r\n# rAhBwGki2eIRFKsQBdkXS9PWpF1w2gIJRvSkDEaCf+lbGTPdSzHSbfREWOF9wY3i\r\n# Yj8CAwEAAaOCARswggEXMB0GA1UdDgQWBBRRahZSGfrCQhCyIyGH9DkiaW7L0zAf\r\n# BgNVHSMEGDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8ETzBNMEugSaBH\r\n# hkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNU\r\n# aW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUF\r\n# BzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1RpbVN0\r\n# YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsG\r\n# AQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IBAQBPFxHIwi4vAH49w9Svmz6K3tM55RlW\r\n# 5pPeULXdut2Rqy6Ys0+VpZsbuaEoxs6Z1C3hMbkiqZFxxyltxJpuHTyGTg61zfNI\r\n# F5n6RsYF3s7IElDXNfZznF1/2iWc6uRPZK8rxxUJ/7emYXZCYwuUY0XjsCpP9pbR\r\n# RKeJi6r5arSyI+NfKxvgoM21JNt1BcdlXuAecdd/k8UjxCscffanoK2n6LFw1PcZ\r\n# lEO7NId7o+soM2C0QY5BYdghpn7uqopB6ixyFIIkDXFub+1E7GmAEwfU6VwEHL7y\r\n# 9rNE8bd+JrQs+yAtkkHy9FmXg/PsGq1daVzX1So7CJ6nyphpuHSN3VfTMIIGcTCC\r\n# BFmgAwIBAgIKYQmBKgAAAAAAAjANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMC\r\n# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV\r\n# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJv\r\n# b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMTAwNzAxMjEzNjU1WhcN\r\n# MjUwNzAxMjE0NjU1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv\r\n# bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0\r\n# aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCASIw\r\n# DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkdDbx3EYo6IOz8E5f1+n9plGt0\r\n# VBDVpQoAgoX77XxoSyxfxcPlYcJ2tz5mK1vwFVMnBDEfQRsalR3OCROOfGEwWbEw\r\n# RA/xYIiEVEMM1024OAizQt2TrNZzMFcmgqNFDdDq9UeBzb8kYDJYYEbyWEeGMoQe\r\n# dGFnkV+BVLHPk0ySwcSmXdFhE24oxhr5hoC732H8RsEnHSRnEnIaIYqvS2SJUGKx\r\n# Xf13Hz3wV3WsvYpCTUBR0Q+cBj5nf/VmwAOWRH7v0Ev9buWayrGo8noqCjHw2k4G\r\n# kbaICDXoeByw6ZnNPOcvRLqn9NxkvaQBwSAJk3jN/LzAyURdXhacAQVPIk0CAwEA\r\n# AaOCAeYwggHiMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBTVYzpcijGQ80N7\r\n# fEYbxTNoWoVtVTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMC\r\n# AYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvX\r\n# zpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20v\r\n# cGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYI\r\n# KwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5j\r\n# b20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDCBoAYDVR0g\r\n# AQH/BIGVMIGSMIGPBgkrBgEEAYI3LgMwgYEwPQYIKwYBBQUHAgEWMWh0dHA6Ly93\r\n# d3cubWljcm9zb2Z0LmNvbS9QS0kvZG9jcy9DUFMvZGVmYXVsdC5odG0wQAYIKwYB\r\n# BQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AUABvAGwAaQBjAHkAXwBTAHQAYQB0AGUA\r\n# bQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAAfmiFEN4sbgmD+BcQM9naOh\r\n# IW+z66bM9TG+zwXiqf76V20ZMLPCxWbJat/15/B4vceoniXj+bzta1RXCCtRgkQS\r\n# +7lTjMz0YBKKdsxAQEGb3FwX/1z5Xhc1mCRWS3TvQhDIr79/xn/yN31aPxzymXlK\r\n# kVIArzgPF/UveYFl2am1a+THzvbKegBvSzBEJCI8z+0DpZaPWSm8tv0E4XCfMkon\r\n# /VWvL/625Y4zu2JfmttXQOnxzplmkIz/amJ/3cVKC5Em4jnsGUpxY517IW3DnKOi\r\n# PPp/fZZqkHimbdLhnPkd/DjYlPTGpQqWhqS9nhquBEKDuLWAmyI4ILUl5WTs9/S/\r\n# fmNZJQ96LjlXdqJxqgaKD4kWumGnEcua2A5HmoDF0M2n0O99g/DhO3EJ3110mCII\r\n# YdqwUB5vvfHhAN/nMQekkzr3ZUd46PioSKv33nJ+YWtvd6mBy6cJrDm77MbL2IK0\r\n# cs0d9LiFAR6A+xuJKlQ5slvayA1VmXqHczsI5pgt6o3gMy4SKfXAL1QnIffIrE7a\r\n# KLixqduWsqdCosnPGUFN4Ib5KpqjEWYw07t0MkvfY3v1mYovG8chr1m1rtxEPJdQ\r\n# cdeh0sVV42neV8HR3jDA/czmTfsNv11P6Z0eGTgvvM9YBS7vDaBQNdrvCScc1bN+\r\n# NR4Iuto229Nfj950iEkSoYIC0jCCAjsCAQEwgfyhgdSkgdEwgc4xCzAJBgNVBAYT\r\n# AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD\r\n# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBP\r\n# cGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo4\r\n# OTdBLUUzNTYtMTcwMTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy\r\n# dmljZaIjCgEBMAcGBSsOAwIaAxUADE5OKSMoNx/mYxYWap1RTOohbJ2ggYMwgYCk\r\n# fjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH\r\n# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD\r\n# Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIF\r\n# AOMUwsMwIhgPMjAyMDA5MjIyMjM2NTFaGA8yMDIwMDkyMzIyMzY1MVowdzA9Bgor\r\n# BgEEAYRZCgQBMS8wLTAKAgUA4xTCwwIBADAKAgEAAgIlfwIB/zAHAgEAAgIRzTAK\r\n# AgUA4xYUQwIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIB\r\n# AAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAEmZCk5PsMA6oG40\r\n# YulPUpxDtQA+JAuXyNrLI4wJcdmv34Bzmj9gk3gv6ZxQZxlvZjA1O1P3lcKGIYco\r\n# 9UkRdAeP6Zzfim6U3UoiUz1AHKuSm6iLux7Z/hNtgEs2ZpYXxOK5JZ/9Pa2I5mg0\r\n# VxsGdXBxl6TOZqbB6aGNG1ZKytRWMYIDDTCCAwkCAQEwgZMwfDELMAkGA1UEBhMC\r\n# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV\r\n# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRp\r\n# bWUtU3RhbXAgUENBIDIwMTACEzMAAAEsIq9Fl3X5G+4AAAAAASwwDQYJYIZIAWUD\r\n# BAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0B\r\n# CQQxIgQgioHn9SQtTXybUUTzgPmt61UPBGskDV9AErEC62Y8+H4wgfoGCyqGSIb3\r\n# DQEJEAIvMYHqMIHnMIHkMIG9BCBbn/0uFFh42hTM5XOoKdXevBaiSxmYK9Ilcn9n\r\n# u5ZH4TCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u\r\n# MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp\r\n# b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB\r\n# LCKvRZd1+RvuAAAAAAEsMCIEIJmkMFyuUW5yiXAemMCWHyk8T1EMMlB1cEiVD4/E\r\n# +vhqMA0GCSqGSIb3DQEBCwUABIIBAOyFm0zpO+VogyMfTuCFeJjMyyDnAJRy/KhW\r\n# jtq11pPg3e11HU0LuNa+ZpCrJXbSWlF+tLkU9eQXPpGPzO7ITGhxhnq5wyhfzA8a\r\n# 9TRGlDMUNHp+6WhH6BZ86zUqMpcYx5zN0H9TaJTpC8JJ7HrNTW8zp032ocr6IXVr\r\n# M6mOa0MUZsE366+OXRpCCm0fokT50uvXWbcRdngS9ZT5xmz134T1iS4Fds7ZOC5W\r\n# m0VofKEuaTYbTc5aF0WN/OGMvowHRxlJhG7zhMX8ZuXGvbgzANq/o7tZu0HmGFTN\r\n# rPs5smC3VEWVpNWgOTfrO3bfaWkAdsuBeLVXZUog+M4wmTDFSPs=\r\n# SIG # End signature block\r\n"
  },
  {
    "path": "src/PowerShell/ExternalModules/PowerShellGet/2.2.5/DscResources/MSFT_PSModule/MSFT_PSModule.schema.mfl",
    "content": "#pragma namespace(\"\\\\\\\\.\\\\root\\\\default\")\r\ninstance of __namespace{ name=\"MS_409\";};\r\n#pragma namespace(\"\\\\\\\\.\\\\root\\\\default\\\\MS_409\")\r\n\r\n[AMENDMENT, LOCALE(\"MS_409\")] \r\nclass MSFT_PSModule : OMI_BaseResource\r\n{\r\n  [Key,Description(\"Name of the module\\n\") : Amended] String Name;\r\n  [Description(\"Whether the module is to be installed or uninstalled.\\nPresent {default}  \\nAbsent   \\n\") : Amended] String Ensure;\r\n  [Description(\"The name of the module source where the module can be found.\\n\") : Amended] String Repository;\r\n  [Description(\"Whether the package is trusted or untrusted.\\nTrusted {default}  \\nUntrusted   \\n\") : Amended] String InstallationPolicy;\r\n  [Description(\"The required version of the module.\\n\") : Amended] String RequiredVersion;\r\n  [Description(\"The minimum version of the module.\\n\") : Amended] String MinimumVersion;\r\n  [Description(\"The maximum version of the module.\\n\") : Amended] String MaximumVersion;\r\n  [Description(\"Forces the installation of the module.\\n\" : Amended] Boolean Force;\r\n  [Description(\"Allows installation when existing cmdlets of the same name exist.\\n\" : Amended] Boolean AllowClobber;\r\n  [Description(\"Allows installation when module is not signed.\\n\" : Amended] Boolean SkipPublisherCheck;\r\n  [Description(\"The brief description of the module.\\n\") : Amended] string Description;\r\n  [Description(\"The version of the module that is installed.\\n\") : Amended] String InstalledVersion;\r\n  [Description(\"The identifier of the module.\\n\") : Amended] String Guid;\r\n  [Description(\"The base location where the module is installed.\\n\") : Amended] String ModuleBase;\r\n  [Description(\"The type of the module.\\n\") : Amended] String ModuleType;\r\n  [Description(\"The author of the module.\\n\") : Amended] String Author;\r\n};\r\n"
  },
  {
    "path": "src/PowerShell/ExternalModules/PowerShellGet/2.2.5/DscResources/MSFT_PSModule/MSFT_PSModule.schema.mof",
    "content": "\r\n[ClassVersion(\"1.0.0.0\"),FriendlyName(\"PSModule\")] \r\nclass MSFT_PSModule : OMI_BaseResource\r\n{\r\n  [Key] String Name;\r\n  [Write,ValueMap{\"Present\", \"Absent\"},Values{\"Present\", \"Absent\"}] String Ensure;\r\n  [Write] String Repository;\r\n  [Write,ValueMap{\"Trusted\", \"Untrusted\"},Values{\"Trusted\", \"Untrusted\"}] String InstallationPolicy;\r\n  [Write] String RequiredVersion;\r\n  [Write] String MaximumVersion;\r\n  [Write] String MinimumVersion;\r\n  [Write] Boolean Force;\r\n  [Write] Boolean AllowClobber;\r\n  [Write] Boolean SkipPublisherCheck;\r\n  [Read] string Description;\r\n  [Read] String InstalledVersion;\r\n  [Read] String Guid;\r\n  [Read] String ModuleBase;\r\n  [Read] String ModuleType;\r\n  [Read] String Author;\r\n};\r\n\r\n/* SIG # Begin signature block */\r\n/* MIIjjwYJKoZIhvcNAQcCoIIjgDCCI3wCAQExDzANBglghkgBZQMEAgEFADB5Bgor */\r\n/* BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG */\r\n/* KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCaI9+NOjQE85sM */\r\n/* /KcWYxUhOUYZXXI8vIpWzKiXV2ZNwqCCDYEwggX/MIID56ADAgECAhMzAAABh3IX */\r\n/* chVZQMcJAAAAAAGHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD */\r\n/* VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy */\r\n/* b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p */\r\n/* bmcgUENBIDIwMTEwHhcNMjAwMzA0MTgzOTQ3WhcNMjEwMzAzMTgzOTQ3WjB0MQsw */\r\n/* CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u */\r\n/* ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy */\r\n/* b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB */\r\n/* AQDOt8kLc7P3T7MKIhouYHewMFmnq8Ayu7FOhZCQabVwBp2VS4WyB2Qe4TQBT8aB */\r\n/* znANDEPjHKNdPT8Xz5cNali6XHefS8i/WXtF0vSsP8NEv6mBHuA2p1fw2wB/F0dH */\r\n/* sJ3GfZ5c0sPJjklsiYqPw59xJ54kM91IOgiO2OUzjNAljPibjCWfH7UzQ1TPHc4d */\r\n/* weils8GEIrbBRb7IWwiObL12jWT4Yh71NQgvJ9Fn6+UhD9x2uk3dLj84vwt1NuFQ */\r\n/* itKJxIV0fVsRNR3abQVOLqpDugbr0SzNL6o8xzOHL5OXiGGwg6ekiXA1/2XXY7yV */\r\n/* Fc39tledDtZjSjNbex1zzwSXAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE */\r\n/* AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUhov4ZyO96axkJdMjpzu2zVXOJcsw */\r\n/* UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1 */\r\n/* ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDU4Mzg1MB8GA1UdIwQYMBaAFEhu */\r\n/* ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu */\r\n/* bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w */\r\n/* Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3 */\r\n/* Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx */\r\n/* MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAixmy */\r\n/* S6E6vprWD9KFNIB9G5zyMuIjZAOuUJ1EK/Vlg6Fb3ZHXjjUwATKIcXbFuFC6Wr4K */\r\n/* NrU4DY/sBVqmab5AC/je3bpUpjtxpEyqUqtPc30wEg/rO9vmKmqKoLPT37svc2NV */\r\n/* BmGNl+85qO4fV/w7Cx7J0Bbqk19KcRNdjt6eKoTnTPHBHlVHQIHZpMxacbFOAkJr */\r\n/* qAVkYZdz7ikNXTxV+GRb36tC4ByMNxE2DF7vFdvaiZP0CVZ5ByJ2gAhXMdK9+usx */\r\n/* zVk913qKde1OAuWdv+rndqkAIm8fUlRnr4saSCg7cIbUwCCf116wUJ7EuJDg0vHe */\r\n/* yhnCeHnBbyH3RZkHEi2ofmfgnFISJZDdMAeVZGVOh20Jp50XBzqokpPzeZ6zc1/g */\r\n/* yILNyiVgE+RPkjnUQshd1f1PMgn3tns2Cz7bJiVUaqEO3n9qRFgy5JuLae6UweGf */\r\n/* AeOo3dgLZxikKzYs3hDMaEtJq8IP71cX7QXe6lnMmXU/Hdfz2p897Zd+kU+vZvKI */\r\n/* 3cwLfuVQgK2RZ2z+Kc3K3dRPz2rXycK5XCuRZmvGab/WbrZiC7wJQapgBodltMI5 */\r\n/* GMdFrBg9IeF7/rP4EqVQXeKtevTlZXjpuNhhjuR+2DMt/dWufjXpiW91bo3aH6Ea */\r\n/* jOALXmoxgltCp1K7hrS6gmsvj94cLRf50QQ4U8Qwggd6MIIFYqADAgECAgphDpDS */\r\n/* AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK */\r\n/* V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0 */\r\n/* IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0 */\r\n/* ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla */\r\n/* MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS */\r\n/* ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT */\r\n/* H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB */\r\n/* AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG */\r\n/* OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S */\r\n/* 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz */\r\n/* y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7 */\r\n/* 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u */\r\n/* M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33 */\r\n/* X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl */\r\n/* XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP */\r\n/* 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB */\r\n/* l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF */\r\n/* RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM */\r\n/* CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ */\r\n/* BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud */\r\n/* DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO */\r\n/* 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0 */\r\n/* LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y */\r\n/* Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p */\r\n/* Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y */\r\n/* Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB */\r\n/* FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw */\r\n/* cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA */\r\n/* XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY */\r\n/* 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj */\r\n/* 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd */\r\n/* d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ */\r\n/* Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf */\r\n/* wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ */\r\n/* aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j */\r\n/* NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B */\r\n/* xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96 */\r\n/* eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7 */\r\n/* r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I */\r\n/* RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVZDCCFWACAQEwgZUwfjELMAkG */\r\n/* A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx */\r\n/* HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z */\r\n/* b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAYdyF3IVWUDHCQAAAAABhzAN */\r\n/* BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor */\r\n/* BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgbSsvKN6e */\r\n/* SGOiJuBXioZwDwxnu8TBuBkBb03bbCVXW+owQgYKKwYBBAGCNwIBDDE0MDKgFIAS */\r\n/* AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN */\r\n/* BgkqhkiG9w0BAQEFAASCAQBSFT3/XsOM9n4ZVz3k681dMHXA/TGCr6vmQTOG0Cp6 */\r\n/* Djy4e61zDfO7lsVtGoDqeKYpSUFXc8FZfmegYDcOXrylItYtw3g9iva1sT0zTvCn */\r\n/* OOZZKJMqa9ZLfxiS9kTOXR0WWbypJmpfgRgqVPdrg5Heh8vfo3NmWhWXwMqX6iUL */\r\n/* u5HZcE20KAqgiyOqFasvdF+cMut2RzS0UypvroI9LVboBhmQLdTT4ELi65MtvwdH */\r\n/* gpJ25Mi3uHvhQ9R2TH/Oh8qCsPJqwiEy+CnvArN4TKJ+q1T23NqMEo5R8zLBhUsa */\r\n/* FcMjYglszXUbCSUSj07/CAOF5adQ1AZoPNdOOuMeLnJOoYIS7jCCEuoGCisGAQQB */\r\n/* gjcDAwExghLaMIIS1gYJKoZIhvcNAQcCoIISxzCCEsMCAQMxDzANBglghkgBZQME */\r\n/* AgEFADCCAVUGCyqGSIb3DQEJEAEEoIIBRASCAUAwggE8AgEBBgorBgEEAYRZCgMB */\r\n/* MDEwDQYJYIZIAWUDBAIBBQAEILnfg6zi07buNel3T6pFx+y5i6dvEoPLGn0OX8/q */\r\n/* AfPcAgZfYQkjShsYEzIwMjAwOTIyMjIxOTUxLjA4NlowBIACAfSggdSkgdEwgc4x */\r\n/* CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt */\r\n/* b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1p */\r\n/* Y3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMg */\r\n/* VFNTIEVTTjpGNzdGLUUzNTYtNUJBRTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt */\r\n/* U3RhbXAgU2VydmljZaCCDkEwggT1MIID3aADAgECAhMzAAABKugXlviGp++jAAAA */\r\n/* AAEqMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo */\r\n/* aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y */\r\n/* cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw */\r\n/* MB4XDTE5MTIxOTAxMTUwMloXDTIxMDMxNzAxMTUwMlowgc4xCzAJBgNVBAYTAlVT */\r\n/* MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK */\r\n/* ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVy */\r\n/* YXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjpGNzdG */\r\n/* LUUzNTYtNUJBRTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vydmlj */\r\n/* ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ/flYGkhdJtxSsHBu9l */\r\n/* mXF/UXxPF7L45nEhmtd01KDosWbY8y54BN7+k9DMvzqToP39v8/Z+NtEzKj8Bf5E */\r\n/* QoG1/pJfpzCJe80HZqyqMo0oQ9EugVY6YNVNa2T1u51d96q1hFmu1dgxt8uD2g7I */\r\n/* pBQdhS2tpc3j3HEzKvV/vwEr7/BcTuwqUHqrrBgHc971epVR4o5bNKsjikawmMw9 */\r\n/* D/tyrTciy3F9Gq9pEgk8EqJfOdAabkanuAWTjlmBhZtRiO9W1qFpwnu9G5qVvdNK */\r\n/* RKxQdtxMC04pWGfnxzDac7+jIql532IEC5QSnvY84szEpxw31QW/LafSiDmAtYWH */\r\n/* pm8CAwEAAaOCARswggEXMB0GA1UdDgQWBBRw9MUtdCs/rhN2y9EkE6ZI9O8TaTAf */\r\n/* BgNVHSMEGDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8ETzBNMEugSaBH */\r\n/* hkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNU */\r\n/* aW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUF */\r\n/* BzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1RpbVN0 */\r\n/* YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsG */\r\n/* AQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IBAQCKwDT0CnHVo46OWyUbrPIj8QIcf+PT */\r\n/* jBVYpKg1K2D15Z6xEuvmf+is6N8gj9f1nkFIALvh+iGkx8GgGa/oA9IhXNEFYPNF */\r\n/* aHwHan/UEw1P6Tjdaqy3cvLC8f8zE1CR1LhXNofq6xfoT9HLGFSg9skPLM1TQ+RA */\r\n/* QX9MigEm8FFlhhsQ1iGB1399x8d92h9KspqGDnO96Z9Aj7ObDtdU6RoZrsZkiRQN */\r\n/* nXmnX1I+RuwtLu8MN8XhJLSl5wqqHM3rqaaMvSAISVtKySpzJC5Zh+5kJlqFdSiI */\r\n/* HW8Q+8R6EWG8ILb9Pf+w/PydyK3ZTkVXUpFA+JhWjcyzphVGw9ffj0YKMIIGcTCC */\r\n/* BFmgAwIBAgIKYQmBKgAAAAAAAjANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMC */\r\n/* VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV */\r\n/* BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJv */\r\n/* b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMTAwNzAxMjEzNjU1WhcN */\r\n/* MjUwNzAxMjE0NjU1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv */\r\n/* bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0 */\r\n/* aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCASIw */\r\n/* DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkdDbx3EYo6IOz8E5f1+n9plGt0 */\r\n/* VBDVpQoAgoX77XxoSyxfxcPlYcJ2tz5mK1vwFVMnBDEfQRsalR3OCROOfGEwWbEw */\r\n/* RA/xYIiEVEMM1024OAizQt2TrNZzMFcmgqNFDdDq9UeBzb8kYDJYYEbyWEeGMoQe */\r\n/* dGFnkV+BVLHPk0ySwcSmXdFhE24oxhr5hoC732H8RsEnHSRnEnIaIYqvS2SJUGKx */\r\n/* Xf13Hz3wV3WsvYpCTUBR0Q+cBj5nf/VmwAOWRH7v0Ev9buWayrGo8noqCjHw2k4G */\r\n/* kbaICDXoeByw6ZnNPOcvRLqn9NxkvaQBwSAJk3jN/LzAyURdXhacAQVPIk0CAwEA */\r\n/* AaOCAeYwggHiMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBTVYzpcijGQ80N7 */\r\n/* fEYbxTNoWoVtVTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMC */\r\n/* AYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvX */\r\n/* zpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20v */\r\n/* cGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYI */\r\n/* KwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5j */\r\n/* b20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDCBoAYDVR0g */\r\n/* AQH/BIGVMIGSMIGPBgkrBgEEAYI3LgMwgYEwPQYIKwYBBQUHAgEWMWh0dHA6Ly93 */\r\n/* d3cubWljcm9zb2Z0LmNvbS9QS0kvZG9jcy9DUFMvZGVmYXVsdC5odG0wQAYIKwYB */\r\n/* BQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AUABvAGwAaQBjAHkAXwBTAHQAYQB0AGUA */\r\n/* bQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAAfmiFEN4sbgmD+BcQM9naOh */\r\n/* IW+z66bM9TG+zwXiqf76V20ZMLPCxWbJat/15/B4vceoniXj+bzta1RXCCtRgkQS */\r\n/* +7lTjMz0YBKKdsxAQEGb3FwX/1z5Xhc1mCRWS3TvQhDIr79/xn/yN31aPxzymXlK */\r\n/* kVIArzgPF/UveYFl2am1a+THzvbKegBvSzBEJCI8z+0DpZaPWSm8tv0E4XCfMkon */\r\n/* /VWvL/625Y4zu2JfmttXQOnxzplmkIz/amJ/3cVKC5Em4jnsGUpxY517IW3DnKOi */\r\n/* PPp/fZZqkHimbdLhnPkd/DjYlPTGpQqWhqS9nhquBEKDuLWAmyI4ILUl5WTs9/S/ */\r\n/* fmNZJQ96LjlXdqJxqgaKD4kWumGnEcua2A5HmoDF0M2n0O99g/DhO3EJ3110mCII */\r\n/* YdqwUB5vvfHhAN/nMQekkzr3ZUd46PioSKv33nJ+YWtvd6mBy6cJrDm77MbL2IK0 */\r\n/* cs0d9LiFAR6A+xuJKlQ5slvayA1VmXqHczsI5pgt6o3gMy4SKfXAL1QnIffIrE7a */\r\n/* KLixqduWsqdCosnPGUFN4Ib5KpqjEWYw07t0MkvfY3v1mYovG8chr1m1rtxEPJdQ */\r\n/* cdeh0sVV42neV8HR3jDA/czmTfsNv11P6Z0eGTgvvM9YBS7vDaBQNdrvCScc1bN+ */\r\n/* NR4Iuto229Nfj950iEkSoYICzzCCAjgCAQEwgfyhgdSkgdEwgc4xCzAJBgNVBAYT */\r\n/* AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD */\r\n/* VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBP */\r\n/* cGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjpG */\r\n/* NzdGLUUzNTYtNUJBRTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy */\r\n/* dmljZaIjCgEBMAcGBSsOAwIaAxUA6rLmrKHyIMP76ePl321xKUJ3YX+ggYMwgYCk */\r\n/* fjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH */\r\n/* UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD */\r\n/* Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIF */\r\n/* AOMUwdcwIhgPMjAyMDA5MjIyMjMyNTVaGA8yMDIwMDkyMzIyMzI1NVowdDA6Bgor */\r\n/* BgEEAYRZCgQBMSwwKjAKAgUA4xTB1wIBADAHAgEAAgIOXDAHAgEAAgIRhjAKAgUA */\r\n/* 4xYTVwIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAID */\r\n/* B6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAFJC6fwWgNxSFO+SkoKy */\r\n/* mrM+JaRXiSnNavdEe/YjzI5HVrpNB8zCRPz/pvX9TbuSnQ2/WN4ZPI2AoBMGQpWk */\r\n/* aG1jl9uC0QwsFTL8Bz97Tpk7GmS9yzjX0+srsaxIVCGg9geXr7A4IoUp0WVxR8JR */\r\n/* MNinkAYlZ0lpKG2lFOA0GBPWMYIDDTCCAwkCAQEwgZMwfDELMAkGA1UEBhMCVVMx */\r\n/* EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT */\r\n/* FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUt */\r\n/* U3RhbXAgUENBIDIwMTACEzMAAAEq6BeW+Ian76MAAAAAASowDQYJYIZIAWUDBAIB */\r\n/* BQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQx */\r\n/* IgQgFyTxUrHDtuJBsfu1xDMA0kEsv2/5h+RllgO7I/JdUFowgfoGCyqGSIb3DQEJ */\r\n/* EAIvMYHqMIHnMIHkMIG9BCBDmDWEWvc6fhs5t4Woo5Q+FMFCcaIgV4yUP4CpuBmL */\r\n/* mTCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw */\r\n/* DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x */\r\n/* JjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAABKugX */\r\n/* lviGp++jAAAAAAEqMCIEIPYicL/1lyN2zZsc2WZ8NPhhliGEGAUOVDFr1il2rjsl */\r\n/* MA0GCSqGSIb3DQEBCwUABIIBAAXT1QnIHmDbDzSQJOywe0TeYzVPNHWyEx/vc0nu */\r\n/* EaUOByznS0km1nwRtIdc9btdG7R7Y5O4sHdlVemnnCRChyie8tQQXYpBsDYZ3x9r */\r\n/* cZEdyjgqJg5LUf4F9BBLLA1kTgP63a/tDOkF1KqImsHXog+nTECkzC1RxCauEFvn */\r\n/* pMuCOa8D1dBptSXhUxaDRBYtSXlT76E+7RtoTLLojBl+a/h+MIpSvzg9Tj8rWD5O */\r\n/* lBq8D1cFSDYk8wGti6d+LbDIokFmh8UB25pmQ6dFqAL3seIOZ0bA3bXOqDo7qZ0x */\r\n/* Mday0m5Qc9ghm0X1Pgls3bGM9fu08AmUKJXNpcIMg75MNgA= */\r\n/* SIG # End signature block */\r\n"
  },
  {
    "path": "src/PowerShell/ExternalModules/PowerShellGet/2.2.5/DscResources/MSFT_PSModule/en-US/MSFT_PSModule.strings.psd1",
    "content": "#\r\n# Copyright (c) Microsoft Corporation.\r\n#\r\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n# THE SOFTWARE.\r\n#\r\n# culture = \"en-US\"\r\nConvertFrom-StringData -StringData @'\r\n    FailToUninstall                 = Failed to uninstall the module '{0}'.\r\n    FailToInstall                   = Failed to install the module '{0}'.\r\n    InDesiredState                  = Resource '{0}' is in the desired state.\r\n    NotInDesiredState               = Resource '{0}' is not in the desired state.\r\n    ModuleFound                     = Module '{0}' is found on the node.\r\n    ModuleNotFound                  = Module '{0}' is not found on the node.\r\n    ModuleWithRightPropertyNotFound = Module '{0}' with the right version or other properties not found in the node.\r\n    ModuleNotFoundInRepository      = Module '{0}' with the right version or other properties not found in the repository.\r\n    StartGetModule                  = Begin invoking Get-Module '{0}'.\r\n    StartFindModule                 = Begin invoking Find-Module '{0}'.\r\n    StartInstallModule              = Begin invoking Install-Module '{0}' version '{1}' from '{2}' repository.\r\n    StartUnInstallModule            = Begin invoking Remove-Item to remove the module '{0}' from the file system.\r\n    InstalledSuccess                = Successfully installed the module '{0}'\r\n    UnInstalledSuccess              = Successfully uninstalled the module '{0}'\r\n    VersionMismatch                 = The installed module '{0}' has the version: '{1}'\r\n    RepositoryMismatch              = The installed module '{0}' is from the '{1}' repository.\r\n    FoundModulePath                 = Found the module path: '{0}'.\r\n    InstallationPolicyWarning       = The module '{0}' was installed from the untrusted repository' {1}'. The InstallationPolicy is set to '{2}' to override the repository installation policy. If you trust the repository, set the repository installation policy to 'Trusted', that will also remove this warning.\r\n    InstallationPolicyFailed        = The current installation policy do not allow installation from this repository. Your current installation policy is '{0}' and the repository installation policy is '{1}'. If you trust the repository, either change the repository installation policy, or set the parameter InstallationPolicy to 'Trusted' to override the repository installation policy.\r\n    GetTargetResourceMessage        = Getting the current state of the module '{0}'.\r\n    TestTargetResourceMessage       = Determining if the module '{0}' is in the desired state.\r\n'@\r\n\r\n# SIG # Begin signature block\r\n# MIIjjwYJKoZIhvcNAQcCoIIjgDCCI3wCAQExDzANBglghkgBZQMEAgEFADB5Bgor\r\n# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG\r\n# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCD3aU/LXFNAmh3o\r\n# ImcuJKT1RWLilph3AMcVu5/5cons4KCCDYEwggX/MIID56ADAgECAhMzAAABh3IX\r\n# chVZQMcJAAAAAAGHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD\r\n# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p\r\n# bmcgUENBIDIwMTEwHhcNMjAwMzA0MTgzOTQ3WhcNMjEwMzAzMTgzOTQ3WjB0MQsw\r\n# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u\r\n# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\r\n# AQDOt8kLc7P3T7MKIhouYHewMFmnq8Ayu7FOhZCQabVwBp2VS4WyB2Qe4TQBT8aB\r\n# znANDEPjHKNdPT8Xz5cNali6XHefS8i/WXtF0vSsP8NEv6mBHuA2p1fw2wB/F0dH\r\n# sJ3GfZ5c0sPJjklsiYqPw59xJ54kM91IOgiO2OUzjNAljPibjCWfH7UzQ1TPHc4d\r\n# weils8GEIrbBRb7IWwiObL12jWT4Yh71NQgvJ9Fn6+UhD9x2uk3dLj84vwt1NuFQ\r\n# itKJxIV0fVsRNR3abQVOLqpDugbr0SzNL6o8xzOHL5OXiGGwg6ekiXA1/2XXY7yV\r\n# Fc39tledDtZjSjNbex1zzwSXAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE\r\n# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUhov4ZyO96axkJdMjpzu2zVXOJcsw\r\n# UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1\r\n# ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDU4Mzg1MB8GA1UdIwQYMBaAFEhu\r\n# ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu\r\n# bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w\r\n# Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3\r\n# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx\r\n# MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAixmy\r\n# S6E6vprWD9KFNIB9G5zyMuIjZAOuUJ1EK/Vlg6Fb3ZHXjjUwATKIcXbFuFC6Wr4K\r\n# NrU4DY/sBVqmab5AC/je3bpUpjtxpEyqUqtPc30wEg/rO9vmKmqKoLPT37svc2NV\r\n# BmGNl+85qO4fV/w7Cx7J0Bbqk19KcRNdjt6eKoTnTPHBHlVHQIHZpMxacbFOAkJr\r\n# qAVkYZdz7ikNXTxV+GRb36tC4ByMNxE2DF7vFdvaiZP0CVZ5ByJ2gAhXMdK9+usx\r\n# zVk913qKde1OAuWdv+rndqkAIm8fUlRnr4saSCg7cIbUwCCf116wUJ7EuJDg0vHe\r\n# yhnCeHnBbyH3RZkHEi2ofmfgnFISJZDdMAeVZGVOh20Jp50XBzqokpPzeZ6zc1/g\r\n# yILNyiVgE+RPkjnUQshd1f1PMgn3tns2Cz7bJiVUaqEO3n9qRFgy5JuLae6UweGf\r\n# AeOo3dgLZxikKzYs3hDMaEtJq8IP71cX7QXe6lnMmXU/Hdfz2p897Zd+kU+vZvKI\r\n# 3cwLfuVQgK2RZ2z+Kc3K3dRPz2rXycK5XCuRZmvGab/WbrZiC7wJQapgBodltMI5\r\n# GMdFrBg9IeF7/rP4EqVQXeKtevTlZXjpuNhhjuR+2DMt/dWufjXpiW91bo3aH6Ea\r\n# jOALXmoxgltCp1K7hrS6gmsvj94cLRf50QQ4U8Qwggd6MIIFYqADAgECAgphDpDS\r\n# AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK\r\n# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0\r\n# IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0\r\n# ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla\r\n# MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS\r\n# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT\r\n# H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB\r\n# AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG\r\n# OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S\r\n# 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz\r\n# y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7\r\n# 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u\r\n# M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33\r\n# X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl\r\n# XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP\r\n# 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB\r\n# l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF\r\n# RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM\r\n# CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ\r\n# BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud\r\n# DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO\r\n# 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0\r\n# LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p\r\n# Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB\r\n# FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw\r\n# cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA\r\n# XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY\r\n# 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj\r\n# 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd\r\n# d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ\r\n# Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf\r\n# wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ\r\n# aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j\r\n# NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B\r\n# xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96\r\n# eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7\r\n# r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I\r\n# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVZDCCFWACAQEwgZUwfjELMAkG\r\n# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx\r\n# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z\r\n# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAYdyF3IVWUDHCQAAAAABhzAN\r\n# BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor\r\n# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQggnuHAoEc\r\n# 77NUAlz1iYFplyTNHrObqDxEEH6I0sx83rwwQgYKKwYBBAGCNwIBDDE0MDKgFIAS\r\n# AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN\r\n# BgkqhkiG9w0BAQEFAASCAQDHiQmHNyxnMkjG/Ta0iocARMREpmraxXw0YVRwVDWu\r\n# 7Fwk6AHjvaq4lG4wBThP2nMw1pepa8wp9vvq+p0v6/HneS0RTMpnKOnioidAvbtx\r\n# zYcqGW4OBzW7TP2pPJc1pLP5CcpndQKxuWPuop//9GT3qH/yw5MqKfV+NEE/13Dd\r\n# zGEL7MVwjq8YWr7hoc77YdIw7A/xmY7gCTn15q0pWMmoBMOllKdBWTRB8QY186SL\r\n# B4SCrN4XLUQlxTx81UkQG4mYCkCEvyRk4ljM4mcGlL391r0pl+MoFgp3EnePeieZ\r\n# ihN3IHuyg1SkqmUKcFv7b4C5XxfSZxyNE49bx2rfSADAoYIS7jCCEuoGCisGAQQB\r\n# gjcDAwExghLaMIIS1gYJKoZIhvcNAQcCoIISxzCCEsMCAQMxDzANBglghkgBZQME\r\n# AgEFADCCAVUGCyqGSIb3DQEJEAEEoIIBRASCAUAwggE8AgEBBgorBgEEAYRZCgMB\r\n# MDEwDQYJYIZIAWUDBAIBBQAEIB/oVtJoO9r6dLRNmcUzxfDW4EtVcph4CRbFLdpd\r\n# e6cDAgZfYPebj+4YEzIwMjAwOTIyMjIxOTUyLjMzMVowBIACAfSggdSkgdEwgc4x\r\n# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt\r\n# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1p\r\n# Y3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMg\r\n# VFNTIEVTTjo2MEJDLUUzODMtMjYzNTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt\r\n# U3RhbXAgU2VydmljZaCCDkEwggT1MIID3aADAgECAhMzAAABJt+6SyK5goIHAAAA\r\n# AAEmMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo\r\n# aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y\r\n# cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw\r\n# MB4XDTE5MTIxOTAxMTQ1OVoXDTIxMDMxNzAxMTQ1OVowgc4xCzAJBgNVBAYTAlVT\r\n# MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK\r\n# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVy\r\n# YXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo2MEJD\r\n# LUUzODMtMjYzNTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vydmlj\r\n# ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ4wvoacTvMNlXQTtfF/\r\n# Cx5Ol3X0fcjUNMvjLgTmO5+WHYJFbp725P3+qvFKDRQHWEI1Sz0gB24urVDIjXjB\r\n# h5NVNJVMQJI2tltv7M4/4IbhZJb3xzQW7LolEoZYUZanBTUuyly9osCg4o5joViT\r\n# 2GtmyxK+Fv5kC20l2opeaeptd/E7ceDAFRM87hiNCsK/KHyC+8+swnlg4gTOey6z\r\n# QqhzgNsG6HrjLBuDtDs9izAMwS2yWT0T52QA9h3Q+B1C9ps2fMKMe+DHpG+0c61D\r\n# 94Yh6cV2XHib4SBCnwIFZAeZE2UJ4qPANSYozI8PH+E5rCT3SVqYvHou97HsXvP2\r\n# I3MCAwEAAaOCARswggEXMB0GA1UdDgQWBBRJq6wfF7B+mEKN0VimX8ajNA5hQTAf\r\n# BgNVHSMEGDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8ETzBNMEugSaBH\r\n# hkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNU\r\n# aW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUF\r\n# BzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1RpbVN0\r\n# YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsG\r\n# AQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IBAQBAlvudaOlv9Cfzv56bnX41czF6tLtH\r\n# LB46l6XUch+qNN45ZmOTFwLot3JjwSrn4oycQ9qTET1TFDYd1QND0LiXmKz9OqBX\r\n# ai6S8XdyCQEZvfL82jIAs9pwsAQ6XvV9jNybPStRgF/sOAM/Deyfmej9Tg9FcRwX\r\n# ank2qgzdZZNb8GoEze7f1orcTF0Q89IUXWIlmwEwQFYF1wjn87N4ZxL9Z/xA2m/R\r\n# 1zizFylWP/mpamCnVfZZLkafFLNUNVmcvc+9gM7vceJs37d3ydabk4wR6ObR34sW\r\n# aLppmyPlsI1Qq5Lu6bJCWoXzYuWpkoK6oEep1gML6SRC3HKVS3UscZhtMIIGcTCC\r\n# BFmgAwIBAgIKYQmBKgAAAAAAAjANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMC\r\n# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV\r\n# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJv\r\n# b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMTAwNzAxMjEzNjU1WhcN\r\n# MjUwNzAxMjE0NjU1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv\r\n# bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0\r\n# aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCASIw\r\n# DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkdDbx3EYo6IOz8E5f1+n9plGt0\r\n# VBDVpQoAgoX77XxoSyxfxcPlYcJ2tz5mK1vwFVMnBDEfQRsalR3OCROOfGEwWbEw\r\n# RA/xYIiEVEMM1024OAizQt2TrNZzMFcmgqNFDdDq9UeBzb8kYDJYYEbyWEeGMoQe\r\n# dGFnkV+BVLHPk0ySwcSmXdFhE24oxhr5hoC732H8RsEnHSRnEnIaIYqvS2SJUGKx\r\n# Xf13Hz3wV3WsvYpCTUBR0Q+cBj5nf/VmwAOWRH7v0Ev9buWayrGo8noqCjHw2k4G\r\n# kbaICDXoeByw6ZnNPOcvRLqn9NxkvaQBwSAJk3jN/LzAyURdXhacAQVPIk0CAwEA\r\n# AaOCAeYwggHiMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBTVYzpcijGQ80N7\r\n# fEYbxTNoWoVtVTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMC\r\n# AYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvX\r\n# zpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20v\r\n# cGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYI\r\n# KwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5j\r\n# b20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDCBoAYDVR0g\r\n# AQH/BIGVMIGSMIGPBgkrBgEEAYI3LgMwgYEwPQYIKwYBBQUHAgEWMWh0dHA6Ly93\r\n# d3cubWljcm9zb2Z0LmNvbS9QS0kvZG9jcy9DUFMvZGVmYXVsdC5odG0wQAYIKwYB\r\n# BQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AUABvAGwAaQBjAHkAXwBTAHQAYQB0AGUA\r\n# bQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAAfmiFEN4sbgmD+BcQM9naOh\r\n# IW+z66bM9TG+zwXiqf76V20ZMLPCxWbJat/15/B4vceoniXj+bzta1RXCCtRgkQS\r\n# +7lTjMz0YBKKdsxAQEGb3FwX/1z5Xhc1mCRWS3TvQhDIr79/xn/yN31aPxzymXlK\r\n# kVIArzgPF/UveYFl2am1a+THzvbKegBvSzBEJCI8z+0DpZaPWSm8tv0E4XCfMkon\r\n# /VWvL/625Y4zu2JfmttXQOnxzplmkIz/amJ/3cVKC5Em4jnsGUpxY517IW3DnKOi\r\n# PPp/fZZqkHimbdLhnPkd/DjYlPTGpQqWhqS9nhquBEKDuLWAmyI4ILUl5WTs9/S/\r\n# fmNZJQ96LjlXdqJxqgaKD4kWumGnEcua2A5HmoDF0M2n0O99g/DhO3EJ3110mCII\r\n# YdqwUB5vvfHhAN/nMQekkzr3ZUd46PioSKv33nJ+YWtvd6mBy6cJrDm77MbL2IK0\r\n# cs0d9LiFAR6A+xuJKlQ5slvayA1VmXqHczsI5pgt6o3gMy4SKfXAL1QnIffIrE7a\r\n# KLixqduWsqdCosnPGUFN4Ib5KpqjEWYw07t0MkvfY3v1mYovG8chr1m1rtxEPJdQ\r\n# cdeh0sVV42neV8HR3jDA/czmTfsNv11P6Z0eGTgvvM9YBS7vDaBQNdrvCScc1bN+\r\n# NR4Iuto229Nfj950iEkSoYICzzCCAjgCAQEwgfyhgdSkgdEwgc4xCzAJBgNVBAYT\r\n# AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD\r\n# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBP\r\n# cGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo2\r\n# MEJDLUUzODMtMjYzNTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy\r\n# dmljZaIjCgEBMAcGBSsOAwIaAxUACmcyOWmZxErpq06B8dy6oMZ6//yggYMwgYCk\r\n# fjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH\r\n# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD\r\n# Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIF\r\n# AOMUsDowIhgPMjAyMDA5MjIyMTE3NDZaGA8yMDIwMDkyMzIxMTc0NlowdDA6Bgor\r\n# BgEEAYRZCgQBMSwwKjAKAgUA4xSwOgIBADAHAgEAAgII+zAHAgEAAgIRDTAKAgUA\r\n# 4xYBugIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAID\r\n# B6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAGFtTfLVXgP5nTlAW4+t\r\n# qfeH51GOeG4NIbJTmRivKyHJM/AjTJCfaazyngryVGsVed/19YBgxoB07IS1Jlmm\r\n# KNq9XofCcAXBUcoBsPLnGHr8vBVOpAPDLDYgr7ME8Qgofa5CjOmCQMYZyjsW2q5j\r\n# 2OkaGPVN1YtLAZq82zgDGI+QMYIDDTCCAwkCAQEwgZMwfDELMAkGA1UEBhMCVVMx\r\n# EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT\r\n# FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUt\r\n# U3RhbXAgUENBIDIwMTACEzMAAAEm37pLIrmCggcAAAAAASYwDQYJYIZIAWUDBAIB\r\n# BQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQx\r\n# IgQg4R9WsNqSRA41TdlwJ+Gl9iyX+HsrWWraUjisH0d+K7IwgfoGCyqGSIb3DQEJ\r\n# EAIvMYHqMIHnMIHkMIG9BCA2/c/vnr1ecAzvapOWZ2xGfAkzrkfpGcrvMW07CQl1\r\n# DzCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw\r\n# DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x\r\n# JjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAABJt+6\r\n# SyK5goIHAAAAAAEmMCIEILioZM02FaPhX5O1/7sR3BeH9w6NUS1x/c+Q88996cSH\r\n# MA0GCSqGSIb3DQEBCwUABIIBAJe/stVSoax/AYbLjdRsdlN60oiL97/W3FU+joo2\r\n# WRwoqLTFscKwlFxQSK5dRXEnn0gU1IQCMsWTeiRrLPV8gtaiUxtczpdK4QvuXJnd\r\n# 8sdla5oQNu3vuEVSjnFLl8w6pFBai4ztvz76ZGEJlUfiXF8aCMDHoiA9kqhu3iSm\r\n# Ky46sAfmEYRDjfIH14LzEbL+KRr3bM5G74fv125+4DyCbRcphNAHQ++gQ1WJkXF4\r\n# 8BUAbKTWLjIDQAgq15jE0JSeBJ4RxuTVt+Ha8NAnvmDpC1fUWvldymt4TZKd3EE9\r\n# iujPnESHGHysaE+G1MZfl/BrpYKq9o3khCHwUBdWzUtSDHw=\r\n# SIG # End signature block\r\n"
  },
  {
    "path": "src/PowerShell/ExternalModules/PowerShellGet/2.2.5/DscResources/MSFT_PSRepository/MSFT_PSRepository.psm1",
    "content": "$resourceModuleRoot = Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent\r\n\r\n# Import localization helper functions.\r\n$helperName = 'PowerShellGet.LocalizationHelper'\r\n$dscResourcesFolderFilePath = Join-Path -Path $resourceModuleRoot -ChildPath \"Modules\\$helperName\\$helperName.psm1\"\r\nImport-Module -Name $dscResourcesFolderFilePath\r\n\r\n$script:localizedData = Get-LocalizedData -ResourceName 'MSFT_PSRepository' -ScriptRoot $PSScriptRoot\r\n\r\n# Import resource helper functions.\r\n$helperName = 'PowerShellGet.ResourceHelper'\r\n$dscResourcesFolderFilePath = Join-Path -Path $resourceModuleRoot -ChildPath \"Modules\\$helperName\\$helperName.psm1\"\r\nImport-Module -Name $dscResourcesFolderFilePath\r\n\r\n<#\r\n    .SYNOPSIS\r\n        Returns the current state of the repository.\r\n\r\n    .PARAMETER Name\r\n        Specifies the name of the repository to manage.\r\n#>\r\nfunction Get-TargetResource {\r\n    <#\r\n        These suppressions are added because this repository have other Visual Studio Code workspace\r\n        settings than those in DscResource.Tests DSC test framework.\r\n        Only those suppression that contradict this repository guideline is added here.\r\n    #>\r\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\\Measure-FunctionBlockBraces', '')]\r\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\\Measure-IfStatement', '')]\r\n    [CmdletBinding()]\r\n    [OutputType([System.Collections.Hashtable])]\r\n    param\r\n    (\r\n        [Parameter(Mandatory = $true)]\r\n        [System.String]\r\n        $Name\r\n    )\r\n\r\n    $returnValue = @{\r\n        Ensure                    = 'Absent'\r\n        Name                      = $Name\r\n        SourceLocation            = $null\r\n        ScriptSourceLocation      = $null\r\n        PublishLocation           = $null\r\n        ScriptPublishLocation     = $null\r\n        InstallationPolicy        = $null\r\n        PackageManagementProvider = $null\r\n        Trusted                   = $false\r\n        Registered                = $false\r\n    }\r\n\r\n    Write-Verbose -Message ($localizedData.GetTargetResourceMessage -f $Name)\r\n\r\n    $repository = Get-PSRepository -Name $Name -ErrorAction 'SilentlyContinue'\r\n\r\n    if ($repository) {\r\n        $returnValue.Ensure = 'Present'\r\n        $returnValue.SourceLocation = $repository.SourceLocation\r\n        $returnValue.ScriptSourceLocation = $repository.ScriptSourceLocation\r\n        $returnValue.PublishLocation = $repository.PublishLocation\r\n        $returnValue.ScriptPublishLocation = $repository.ScriptPublishLocation\r\n        $returnValue.InstallationPolicy = $repository.InstallationPolicy\r\n        $returnValue.PackageManagementProvider = $repository.PackageManagementProvider\r\n        $returnValue.Trusted = $repository.Trusted\r\n        $returnValue.Registered = $repository.Registered\r\n    }\r\n    else {\r\n        Write-Verbose -Message ($localizedData.RepositoryNotFound -f $Name)\r\n    }\r\n\r\n    return $returnValue\r\n}\r\n\r\n<#\r\n    .SYNOPSIS\r\n        Determines if the repository is in the desired state.\r\n\r\n    .PARAMETER Ensure\r\n        If the repository should be present or absent on the server\r\n        being configured. Default values is 'Present'.\r\n\r\n    .PARAMETER Name\r\n        Specifies the name of the repository to manage.\r\n\r\n    .PARAMETER SourceLocation\r\n        Specifies the URI for discovering and installing modules from\r\n        this repository. A URI can be a NuGet server feed, HTTP, HTTPS,\r\n        FTP or file location.\r\n\r\n    .PARAMETER ScriptSourceLocation\r\n        Specifies the URI for the script source location.\r\n\r\n    .PARAMETER PublishLocation\r\n        Specifies the URI of the publish location. For example, for\r\n        NuGet-based repositories, the publish location is similar\r\n        to http://someNuGetUrl.com/api/v2/Packages.\r\n\r\n    .PARAMETER ScriptPublishLocation\r\n        Specifies the URI for the script publish location.\r\n\r\n    .PARAMETER InstallationPolicy\r\n        Specifies the installation policy. Valid values are  'Trusted'\r\n        or 'Untrusted'. The default value is 'Untrusted'.\r\n\r\n    .PARAMETER PackageManagementProvider\r\n        Specifies a OneGet package provider. Default value is 'NuGet'.\r\n#>\r\nfunction Test-TargetResource {\r\n    <#\r\n        These suppressions are added because this repository have other Visual Studio Code workspace\r\n        settings than those in DscResource.Tests DSC test framework.\r\n        Only those suppression that contradict this repository guideline is added here.\r\n    #>\r\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\\Measure-FunctionBlockBraces', '')]\r\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\\Measure-IfStatement', '')]\r\n    [CmdletBinding()]\r\n    [OutputType([System.Boolean])]\r\n    param\r\n    (\r\n        [Parameter()]\r\n        [ValidateSet('Present', 'Absent')]\r\n        [System.String]\r\n        $Ensure = 'Present',\r\n\r\n        [Parameter(Mandatory = $true)]\r\n        [System.String]\r\n        $Name,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $SourceLocation,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $ScriptSourceLocation,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $PublishLocation,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $ScriptPublishLocation,\r\n\r\n        [Parameter()]\r\n        [ValidateSet('Trusted', 'Untrusted')]\r\n        [System.String]\r\n        $InstallationPolicy = 'Untrusted',\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $PackageManagementProvider = 'NuGet'\r\n    )\r\n\r\n    Write-Verbose -Message ($localizedData.TestTargetResourceMessage -f $Name)\r\n\r\n    $returnValue = $false\r\n\r\n    $getTargetResourceResult = Get-TargetResource -Name $Name\r\n\r\n    if ($Ensure -eq $getTargetResourceResult.Ensure) {\r\n        if ($getTargetResourceResult.Ensure -eq 'Present' ) {\r\n            $returnValue = Test-DscParameterState `\r\n                -CurrentValues $getTargetResourceResult `\r\n                -DesiredValues $PSBoundParameters `\r\n                -ValuesToCheck @(\r\n                'SourceLocation'\r\n                'ScriptSourceLocation'\r\n                'PublishLocation'\r\n                'ScriptPublishLocation'\r\n                'InstallationPolicy'\r\n                'PackageManagementProvider'\r\n            )\r\n        }\r\n        else {\r\n            $returnValue = $true\r\n        }\r\n    }\r\n\r\n    if ($returnValue) {\r\n        Write-Verbose -Message ($localizedData.InDesiredState -f $Name)\r\n    }\r\n    else {\r\n        Write-Verbose -Message ($localizedData.NotInDesiredState -f $Name)\r\n    }\r\n\r\n    return $returnValue\r\n}\r\n\r\n<#\r\n    .SYNOPSIS\r\n        Creates, removes or updates the repository.\r\n\r\n    .PARAMETER Ensure\r\n        If the repository should be present or absent on the server\r\n        being configured. Default values is 'Present'.\r\n\r\n    .PARAMETER Name\r\n        Specifies the name of the repository to manage.\r\n\r\n    .PARAMETER SourceLocation\r\n        Specifies the URI for discovering and installing modules from\r\n        this repository. A URI can be a NuGet server feed, HTTP, HTTPS,\r\n        FTP or file location.\r\n\r\n    .PARAMETER ScriptSourceLocation\r\n        Specifies the URI for the script source location.\r\n\r\n    .PARAMETER PublishLocation\r\n        Specifies the URI of the publish location. For example, for\r\n        NuGet-based repositories, the publish location is similar\r\n        to http://someNuGetUrl.com/api/v2/Packages.\r\n\r\n    .PARAMETER ScriptPublishLocation\r\n        Specifies the URI for the script publish location.\r\n\r\n    .PARAMETER InstallationPolicy\r\n        Specifies the installation policy. Valid values are  'Trusted'\r\n        or 'Untrusted'. The default value is 'Untrusted'.\r\n\r\n    .PARAMETER PackageManagementProvider\r\n        Specifies a OneGet package provider. Default value is 'NuGet'.\r\n#>\r\nfunction Set-TargetResource {\r\n    <#\r\n        These suppressions are added because this repository have other Visual Studio Code workspace\r\n        settings than those in DscResource.Tests DSC test framework.\r\n        Only those suppression that contradict this repository guideline is added here.\r\n    #>\r\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\\Measure-FunctionBlockBraces', '')]\r\n    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\\Measure-IfStatement', '')]\r\n    [CmdletBinding()]\r\n    param\r\n    (\r\n        [Parameter()]\r\n        [ValidateSet('Present', 'Absent')]\r\n        [System.String]\r\n        $Ensure = 'Present',\r\n\r\n        [Parameter(Mandatory = $true)]\r\n        [System.String]\r\n        $Name,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $SourceLocation,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $ScriptSourceLocation,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $PublishLocation,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $ScriptPublishLocation,\r\n\r\n        [Parameter()]\r\n        [ValidateSet('Trusted', 'Untrusted')]\r\n        [System.String]\r\n        $InstallationPolicy = 'Untrusted',\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $PackageManagementProvider = 'NuGet'\r\n    )\r\n\r\n    $getTargetResourceResult = Get-TargetResource -Name $Name\r\n\r\n    # Determine if the repository should be present or absent.\r\n    if ($Ensure -eq 'Present') {\r\n        $repositoryParameters = New-SplatParameterHashTable `\r\n            -FunctionBoundParameters $PSBoundParameters `\r\n            -ArgumentNames @(\r\n            'Name'\r\n            'SourceLocation'\r\n            'ScriptSourceLocation'\r\n            'PublishLocation'\r\n            'ScriptPublishLocation'\r\n            'InstallationPolicy'\r\n            'PackageManagementProvider'\r\n        )\r\n\r\n        # Determine if the repository is already present.\r\n        if ($getTargetResourceResult.Ensure -eq 'Present') {\r\n            Write-Verbose -Message ($localizedData.RepositoryExist -f $Name)\r\n\r\n            # Repository exist, update the properties.\r\n            Set-PSRepository @repositoryParameters -ErrorAction 'Stop'\r\n        }\r\n        else {\r\n            Write-Verbose -Message ($localizedData.RepositoryDoesNotExist -f $Name)\r\n\r\n            # Repository did not exist, create the repository.\r\n            Register-PSRepository @repositoryParameters -ErrorAction 'Stop'\r\n        }\r\n    }\r\n    else {\r\n        if ($getTargetResourceResult.Ensure -eq 'Present') {\r\n            Write-Verbose -Message ($localizedData.RemoveExistingRepository -f $Name)\r\n\r\n            # Repository did exist, remove the repository.\r\n            Unregister-PSRepository -Name $Name -ErrorAction 'Stop'\r\n        }\r\n    }\r\n}\r\n\r\n# SIG # Begin signature block\r\n# MIIjjgYJKoZIhvcNAQcCoIIjfzCCI3sCAQExDzANBglghkgBZQMEAgEFADB5Bgor\r\n# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG\r\n# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBlZKKmsIDI2MiW\r\n# t2Bt6XXxjORDDSKWDjB5NwOM5+2tUaCCDYEwggX/MIID56ADAgECAhMzAAABh3IX\r\n# chVZQMcJAAAAAAGHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD\r\n# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p\r\n# bmcgUENBIDIwMTEwHhcNMjAwMzA0MTgzOTQ3WhcNMjEwMzAzMTgzOTQ3WjB0MQsw\r\n# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u\r\n# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\r\n# AQDOt8kLc7P3T7MKIhouYHewMFmnq8Ayu7FOhZCQabVwBp2VS4WyB2Qe4TQBT8aB\r\n# znANDEPjHKNdPT8Xz5cNali6XHefS8i/WXtF0vSsP8NEv6mBHuA2p1fw2wB/F0dH\r\n# sJ3GfZ5c0sPJjklsiYqPw59xJ54kM91IOgiO2OUzjNAljPibjCWfH7UzQ1TPHc4d\r\n# weils8GEIrbBRb7IWwiObL12jWT4Yh71NQgvJ9Fn6+UhD9x2uk3dLj84vwt1NuFQ\r\n# itKJxIV0fVsRNR3abQVOLqpDugbr0SzNL6o8xzOHL5OXiGGwg6ekiXA1/2XXY7yV\r\n# Fc39tledDtZjSjNbex1zzwSXAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE\r\n# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUhov4ZyO96axkJdMjpzu2zVXOJcsw\r\n# UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1\r\n# ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDU4Mzg1MB8GA1UdIwQYMBaAFEhu\r\n# ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu\r\n# bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w\r\n# Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3\r\n# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx\r\n# MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAixmy\r\n# S6E6vprWD9KFNIB9G5zyMuIjZAOuUJ1EK/Vlg6Fb3ZHXjjUwATKIcXbFuFC6Wr4K\r\n# NrU4DY/sBVqmab5AC/je3bpUpjtxpEyqUqtPc30wEg/rO9vmKmqKoLPT37svc2NV\r\n# BmGNl+85qO4fV/w7Cx7J0Bbqk19KcRNdjt6eKoTnTPHBHlVHQIHZpMxacbFOAkJr\r\n# qAVkYZdz7ikNXTxV+GRb36tC4ByMNxE2DF7vFdvaiZP0CVZ5ByJ2gAhXMdK9+usx\r\n# zVk913qKde1OAuWdv+rndqkAIm8fUlRnr4saSCg7cIbUwCCf116wUJ7EuJDg0vHe\r\n# yhnCeHnBbyH3RZkHEi2ofmfgnFISJZDdMAeVZGVOh20Jp50XBzqokpPzeZ6zc1/g\r\n# yILNyiVgE+RPkjnUQshd1f1PMgn3tns2Cz7bJiVUaqEO3n9qRFgy5JuLae6UweGf\r\n# AeOo3dgLZxikKzYs3hDMaEtJq8IP71cX7QXe6lnMmXU/Hdfz2p897Zd+kU+vZvKI\r\n# 3cwLfuVQgK2RZ2z+Kc3K3dRPz2rXycK5XCuRZmvGab/WbrZiC7wJQapgBodltMI5\r\n# GMdFrBg9IeF7/rP4EqVQXeKtevTlZXjpuNhhjuR+2DMt/dWufjXpiW91bo3aH6Ea\r\n# jOALXmoxgltCp1K7hrS6gmsvj94cLRf50QQ4U8Qwggd6MIIFYqADAgECAgphDpDS\r\n# AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK\r\n# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0\r\n# IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0\r\n# ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla\r\n# MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS\r\n# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT\r\n# H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB\r\n# AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG\r\n# OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S\r\n# 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz\r\n# y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7\r\n# 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u\r\n# M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33\r\n# X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl\r\n# XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP\r\n# 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB\r\n# l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF\r\n# RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM\r\n# CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ\r\n# BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud\r\n# DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO\r\n# 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0\r\n# LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p\r\n# Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB\r\n# FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw\r\n# cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA\r\n# XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY\r\n# 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj\r\n# 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd\r\n# d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ\r\n# Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf\r\n# wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ\r\n# aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j\r\n# NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B\r\n# xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96\r\n# eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7\r\n# r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I\r\n# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVYzCCFV8CAQEwgZUwfjELMAkG\r\n# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx\r\n# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z\r\n# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAYdyF3IVWUDHCQAAAAABhzAN\r\n# BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor\r\n# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgs+RU2J5w\r\n# NacSfRVCp+ToPyznw3pclb/0hPnXb8LPCq4wQgYKKwYBBAGCNwIBDDE0MDKgFIAS\r\n# AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN\r\n# BgkqhkiG9w0BAQEFAASCAQA8PvaOO0+Ef6lk0kKMSevhLul270IbDPTD4V/sXD20\r\n# rOpGDeRISfE2EWaZD3nv9H3icTFeFOTguBphXaQNh2PImj+7qzf3/lKP2ETu0xvI\r\n# ZJii75+Pe25WL3ozwCd2eKaAG5ceSmAuCXCcEyw1BR0OW1mWTA25ya0tIa5v1466\r\n# sbykvU3vNEC4eN6dO56w6Y2WmziZx9YFn5feMjCSdJigMxN6SONXkVMTTe9x0s2+\r\n# I2Sjc8I+MPxDHfjwOtA7pHNk6KEve4UE3pWzVYJBe0JdXHIaxBUwcti2bue7DDDN\r\n# xa0QnEzVd+eD55gR8rudUbiD30fQQzDzl+KvHmgrgdAVoYIS7TCCEukGCisGAQQB\r\n# gjcDAwExghLZMIIS1QYJKoZIhvcNAQcCoIISxjCCEsICAQMxDzANBglghkgBZQME\r\n# AgEFADCCAVQGCyqGSIb3DQEJEAEEoIIBQwSCAT8wggE7AgEBBgorBgEEAYRZCgMB\r\n# MDEwDQYJYIZIAWUDBAIBBQAEINsdx97zcSFVxkNkK+d8VvGiJ0Fsuev3S05KAcoZ\r\n# Uxj9AgZfYQkjSiYYEjIwMjAwOTIyMjIxOTUxLjM2WjAEgAIB9KCB1KSB0TCBzjEL\r\n# MAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1v\r\n# bmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEpMCcGA1UECxMgTWlj\r\n# cm9zb2Z0IE9wZXJhdGlvbnMgUHVlcnRvIFJpY28xJjAkBgNVBAsTHVRoYWxlcyBU\r\n# U1MgRVNOOkY3N0YtRTM1Ni01QkFFMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1T\r\n# dGFtcCBTZXJ2aWNloIIOQTCCBPUwggPdoAMCAQICEzMAAAEq6BeW+Ian76MAAAAA\r\n# ASowDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp\r\n# bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw\r\n# b3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAw\r\n# HhcNMTkxMjE5MDExNTAyWhcNMjEwMzE3MDExNTAyWjCBzjELMAkGA1UEBhMCVVMx\r\n# EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT\r\n# FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEpMCcGA1UECxMgTWljcm9zb2Z0IE9wZXJh\r\n# dGlvbnMgUHVlcnRvIFJpY28xJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNOOkY3N0Yt\r\n# RTM1Ni01QkFFMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNl\r\n# MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn9+VgaSF0m3FKwcG72WZ\r\n# cX9RfE8XsvjmcSGa13TUoOixZtjzLngE3v6T0My/OpOg/f2/z9n420TMqPwF/kRC\r\n# gbX+kl+nMIl7zQdmrKoyjShD0S6BVjpg1U1rZPW7nV33qrWEWa7V2DG3y4PaDsik\r\n# FB2FLa2lzePccTMq9X+/ASvv8FxO7CpQequsGAdz3vV6lVHijls0qyOKRrCYzD0P\r\n# +3KtNyLLcX0ar2kSCTwSol850BpuRqe4BZOOWYGFm1GI71bWoWnCe70bmpW900pE\r\n# rFB23EwLTilYZ+fHMNpzv6MiqXnfYgQLlBKe9jzizMSnHDfVBb8tp9KIOYC1hYem\r\n# bwIDAQABo4IBGzCCARcwHQYDVR0OBBYEFHD0xS10Kz+uE3bL0SQTpkj07xNpMB8G\r\n# A1UdIwQYMBaAFNVjOlyKMZDzQ3t8RhvFM2hahW1VMFYGA1UdHwRPME0wS6BJoEeG\r\n# RWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Rp\r\n# bVN0YVBDQV8yMDEwLTA3LTAxLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUH\r\n# MAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljVGltU3Rh\r\n# UENBXzIwMTAtMDctMDEuY3J0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYB\r\n# BQUHAwgwDQYJKoZIhvcNAQELBQADggEBAIrANPQKcdWjjo5bJRus8iPxAhx/49OM\r\n# FVikqDUrYPXlnrES6+Z/6Kzo3yCP1/WeQUgAu+H6IaTHwaAZr+gD0iFc0QVg80Vo\r\n# fAdqf9QTDU/pON1qrLdy8sLx/zMTUJHUuFc2h+rrF+hP0csYVKD2yQ8szVND5EBB\r\n# f0yKASbwUWWGGxDWIYHXf33Hx33aH0qymoYOc73pn0CPs5sO11TpGhmuxmSJFA2d\r\n# eadfUj5G7C0u7ww3xeEktKXnCqoczeuppoy9IAhJW0rJKnMkLlmH7mQmWoV1KIgd\r\n# bxD7xHoRYbwgtv09/7D8/J3IrdlORVdSkUD4mFaNzLOmFUbD19+PRgowggZxMIIE\r\n# WaADAgECAgphCYEqAAAAAAACMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJV\r\n# UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE\r\n# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9v\r\n# dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAxMDAeFw0xMDA3MDEyMTM2NTVaFw0y\r\n# NTA3MDEyMTQ2NTVaMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u\r\n# MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp\r\n# b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMIIBIjAN\r\n# BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqR0NvHcRijog7PwTl/X6f2mUa3RU\r\n# ENWlCgCChfvtfGhLLF/Fw+Vhwna3PmYrW/AVUycEMR9BGxqVHc4JE458YTBZsTBE\r\n# D/FgiIRUQwzXTbg4CLNC3ZOs1nMwVyaCo0UN0Or1R4HNvyRgMlhgRvJYR4YyhB50\r\n# YWeRX4FUsc+TTJLBxKZd0WETbijGGvmGgLvfYfxGwScdJGcSchohiq9LZIlQYrFd\r\n# /XcfPfBXday9ikJNQFHRD5wGPmd/9WbAA5ZEfu/QS/1u5ZrKsajyeioKMfDaTgaR\r\n# togINeh4HLDpmc085y9Euqf03GS9pAHBIAmTeM38vMDJRF1eFpwBBU8iTQIDAQAB\r\n# o4IB5jCCAeIwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFNVjOlyKMZDzQ3t8\r\n# RhvFM2hahW1VMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIB\r\n# hjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fO\r\n# mhjEMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9w\r\n# a2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggr\r\n# BgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNv\r\n# bS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MIGgBgNVHSAB\r\n# Af8EgZUwgZIwgY8GCSsGAQQBgjcuAzCBgTA9BggrBgEFBQcCARYxaHR0cDovL3d3\r\n# dy5taWNyb3NvZnQuY29tL1BLSS9kb2NzL0NQUy9kZWZhdWx0Lmh0bTBABggrBgEF\r\n# BQcCAjA0HjIgHQBMAGUAZwBhAGwAXwBQAG8AbABpAGMAeQBfAFMAdABhAHQAZQBt\r\n# AGUAbgB0AC4gHTANBgkqhkiG9w0BAQsFAAOCAgEAB+aIUQ3ixuCYP4FxAz2do6Eh\r\n# b7Prpsz1Mb7PBeKp/vpXbRkws8LFZslq3/Xn8Hi9x6ieJeP5vO1rVFcIK1GCRBL7\r\n# uVOMzPRgEop2zEBAQZvcXBf/XPleFzWYJFZLdO9CEMivv3/Gf/I3fVo/HPKZeUqR\r\n# UgCvOA8X9S95gWXZqbVr5MfO9sp6AG9LMEQkIjzP7QOllo9ZKby2/QThcJ8ySif9\r\n# Va8v/rbljjO7Yl+a21dA6fHOmWaQjP9qYn/dxUoLkSbiOewZSnFjnXshbcOco6I8\r\n# +n99lmqQeKZt0uGc+R38ONiU9MalCpaGpL2eGq4EQoO4tYCbIjggtSXlZOz39L9+\r\n# Y1klD3ouOVd2onGqBooPiRa6YacRy5rYDkeagMXQzafQ732D8OE7cQnfXXSYIghh\r\n# 2rBQHm+98eEA3+cxB6STOvdlR3jo+KhIq/fecn5ha293qYHLpwmsObvsxsvYgrRy\r\n# zR30uIUBHoD7G4kqVDmyW9rIDVWZeodzOwjmmC3qjeAzLhIp9cAvVCch98isTtoo\r\n# uLGp25ayp0Kiyc8ZQU3ghvkqmqMRZjDTu3QyS99je/WZii8bxyGvWbWu3EQ8l1Bx\r\n# 16HSxVXjad5XwdHeMMD9zOZN+w2/XU/pnR4ZOC+8z1gFLu8NoFA12u8JJxzVs341\r\n# Hgi62jbb01+P3nSISRKhggLPMIICOAIBATCB/KGB1KSB0TCBzjELMAkGA1UEBhMC\r\n# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV\r\n# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEpMCcGA1UECxMgTWljcm9zb2Z0IE9w\r\n# ZXJhdGlvbnMgUHVlcnRvIFJpY28xJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNOOkY3\r\n# N0YtRTM1Ni01QkFFMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2\r\n# aWNloiMKAQEwBwYFKw4DAhoDFQDqsuasofIgw/vp4+XfbXEpQndhf6CBgzCBgKR+\r\n# MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS\r\n# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMT\r\n# HU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMA0GCSqGSIb3DQEBBQUAAgUA\r\n# 4xTB1zAiGA8yMDIwMDkyMjIyMzI1NVoYDzIwMjAwOTIzMjIzMjU1WjB0MDoGCisG\r\n# AQQBhFkKBAExLDAqMAoCBQDjFMHXAgEAMAcCAQACAg5cMAcCAQACAhGGMAoCBQDj\r\n# FhNXAgEAMDYGCisGAQQBhFkKBAIxKDAmMAwGCisGAQQBhFkKAwKgCjAIAgEAAgMH\r\n# oSChCjAIAgEAAgMBhqAwDQYJKoZIhvcNAQEFBQADgYEAUkLp/BaA3FIU75KSgrKa\r\n# sz4lpFeJKc1q90R79iPMjkdWuk0HzMJE/P+m9f1Nu5KdDb9Y3hk8jYCgEwZClaRo\r\n# bWOX24LRDCwVMvwHP3tOmTsaZL3LONfT6yuxrEhUIaD2B5evsDgihSnRZXFHwlEw\r\n# 2KeQBiVnSWkobaUU4DQYE9YxggMNMIIDCQIBATCBkzB8MQswCQYDVQQGEwJVUzET\r\n# MBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMV\r\n# TWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1T\r\n# dGFtcCBQQ0EgMjAxMAITMwAAASroF5b4hqfvowAAAAABKjANBglghkgBZQMEAgEF\r\n# AKCCAUowGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMC8GCSqGSIb3DQEJBDEi\r\n# BCAOGPARROnr2oqQEu2OY1Bf2p1llcPXBS/KQIsljnOGKjCB+gYLKoZIhvcNAQkQ\r\n# Ai8xgeowgecwgeQwgb0EIEOYNYRa9zp+Gzm3haijlD4UwUJxoiBXjJQ/gKm4GYuZ\r\n# MIGYMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO\r\n# BgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEm\r\n# MCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAEq6BeW\r\n# +Ian76MAAAAAASowIgQg9iJwv/WXI3bNmxzZZnw0+GGWIYQYBQ5UMWvWKXauOyUw\r\n# DQYJKoZIhvcNAQELBQAEggEAQmz84vhytrXC6N3xTngSm+jXmE60CX4FWbIY7/sc\r\n# aLR29t/ayGUM7tb48SpnUgk8Ogt32xMS02zZjvjGqGraktCUIeD+P5lDz1x9ouBd\r\n# Oe4yHI6FV7Do6jIz7aje8R66z7TKkSSX/5z5i51aRuOOGmp31ZVSW58MtAkNy3WR\r\n# 4i9F7OEqt0uZaokblXF2Cl3gMAYqMScQyAWDwc2IxLH3JbNTUAB2Vtdp0MUTJKqo\r\n# RUoIlB3ZJd77W+kHkJk/kLLCWUy7Xr6T7ZFw3AfoXDfsdKOpci3YRpZci4zg95R8\r\n# Pf6al6GKk9Ge7Rus7feYG7PItce08fWvT3SWOT+HNUNwKg==\r\n# SIG # End signature block\r\n"
  },
  {
    "path": "src/PowerShell/ExternalModules/PowerShellGet/2.2.5/DscResources/MSFT_PSRepository/MSFT_PSRepository.schema.mfl",
    "content": "#pragma namespace(\"\\\\\\\\.\\\\root\\\\default\")\r\ninstance of __namespace{ name=\"MS_409\";};\r\n#pragma namespace(\"\\\\\\\\.\\\\root\\\\default\\\\MS_409\")\r\n\r\n[AMENDMENT, LOCALE(\"MS_409\")]\r\nclass MSFT_PSModule : OMI_BaseResource\r\n{\r\n  [Key, Description(\"Specifies the name of the repository to manage.\") : Amended] String Name;\r\n  [Description(\"If the repository should be present or absent on the server being configured. Default values is 'Present'.\") : Amended] String Ensure;\r\n  [Description(\"Specifies the URI for discovering and installing modules from this repository. A URI can be a NuGet server feed, HTTP, HTTPS, FTP or file location.\") : Amended] String SourceLocation;\r\n  [Description(\"Specifies the URI for the script source location.\") : Amended] String ScriptSourceLocation;\r\n  [Description(\"Specifies the URI of the publish location. For example, for NuGet-based repositories, the publish location is similar to http://someNuGetUrl.com/api/v2/Packages.\") : Amended] String PublishLocation;\r\n  [Description(\"Specifies the URI for the script publish location.\") : Amended] String ScriptPublishLocation;\r\n  [Description(\"Specifies the installation policy. Valid values are 'Trusted' or 'Untrusted'. The default value is 'Untrusted'.\") : Amended] String InstallationPolicy;\r\n  [Description(\"Specifies a OneGet package provider. Default value is 'NuGet'.\") : Amended] String PackageManagementProvider;\r\n  [Description(\"Specifies if the repository is trusted.\") : Amended] Boolean Trusted;\r\n  [Description(\"Specifies if the repository is registered.\") : Amended] Boolean Registered;\r\n};\r\n"
  },
  {
    "path": "src/PowerShell/ExternalModules/PowerShellGet/2.2.5/DscResources/MSFT_PSRepository/MSFT_PSRepository.schema.mof",
    "content": "[ClassVersion(\"1.0.0.0\"),FriendlyName(\"PSRepository\")]\r\nclass MSFT_PSRepository : OMI_BaseResource\r\n{\r\n    [Key] String Name;\r\n    [Write, ValueMap{\"Present\",\"Absent\"}, Values{\"Present\",\"Absent\"}] String Ensure;\r\n    [Write] String SourceLocation;\r\n    [Write] String ScriptSourceLocation;\r\n    [Write] String PublishLocation;\r\n    [Write] String ScriptPublishLocation;\r\n    [Write, ValueMap{\"Trusted\",\"Untrusted\"}, Values{\"Trusted\",\"Untrusted\"}] String InstallationPolicy;\r\n    [Write] String PackageManagementProvider;\r\n    [Read] Boolean Trusted;\r\n    [Read] Boolean Registered;\r\n};\r\n\r\n/* SIG # Begin signature block */\r\n/* MIIjkgYJKoZIhvcNAQcCoIIjgzCCI38CAQExDzANBglghkgBZQMEAgEFADB5Bgor */\r\n/* BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG */\r\n/* KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAUB2bP/4Ied6bW */\r\n/* IFA1D31XybyRSF4DCKxuisoZB3v8laCCDYEwggX/MIID56ADAgECAhMzAAABh3IX */\r\n/* chVZQMcJAAAAAAGHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD */\r\n/* VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy */\r\n/* b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p */\r\n/* bmcgUENBIDIwMTEwHhcNMjAwMzA0MTgzOTQ3WhcNMjEwMzAzMTgzOTQ3WjB0MQsw */\r\n/* CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u */\r\n/* ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy */\r\n/* b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB */\r\n/* AQDOt8kLc7P3T7MKIhouYHewMFmnq8Ayu7FOhZCQabVwBp2VS4WyB2Qe4TQBT8aB */\r\n/* znANDEPjHKNdPT8Xz5cNali6XHefS8i/WXtF0vSsP8NEv6mBHuA2p1fw2wB/F0dH */\r\n/* sJ3GfZ5c0sPJjklsiYqPw59xJ54kM91IOgiO2OUzjNAljPibjCWfH7UzQ1TPHc4d */\r\n/* weils8GEIrbBRb7IWwiObL12jWT4Yh71NQgvJ9Fn6+UhD9x2uk3dLj84vwt1NuFQ */\r\n/* itKJxIV0fVsRNR3abQVOLqpDugbr0SzNL6o8xzOHL5OXiGGwg6ekiXA1/2XXY7yV */\r\n/* Fc39tledDtZjSjNbex1zzwSXAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE */\r\n/* AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUhov4ZyO96axkJdMjpzu2zVXOJcsw */\r\n/* UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1 */\r\n/* ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDU4Mzg1MB8GA1UdIwQYMBaAFEhu */\r\n/* ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu */\r\n/* bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w */\r\n/* Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3 */\r\n/* Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx */\r\n/* MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAixmy */\r\n/* S6E6vprWD9KFNIB9G5zyMuIjZAOuUJ1EK/Vlg6Fb3ZHXjjUwATKIcXbFuFC6Wr4K */\r\n/* NrU4DY/sBVqmab5AC/je3bpUpjtxpEyqUqtPc30wEg/rO9vmKmqKoLPT37svc2NV */\r\n/* BmGNl+85qO4fV/w7Cx7J0Bbqk19KcRNdjt6eKoTnTPHBHlVHQIHZpMxacbFOAkJr */\r\n/* qAVkYZdz7ikNXTxV+GRb36tC4ByMNxE2DF7vFdvaiZP0CVZ5ByJ2gAhXMdK9+usx */\r\n/* zVk913qKde1OAuWdv+rndqkAIm8fUlRnr4saSCg7cIbUwCCf116wUJ7EuJDg0vHe */\r\n/* yhnCeHnBbyH3RZkHEi2ofmfgnFISJZDdMAeVZGVOh20Jp50XBzqokpPzeZ6zc1/g */\r\n/* yILNyiVgE+RPkjnUQshd1f1PMgn3tns2Cz7bJiVUaqEO3n9qRFgy5JuLae6UweGf */\r\n/* AeOo3dgLZxikKzYs3hDMaEtJq8IP71cX7QXe6lnMmXU/Hdfz2p897Zd+kU+vZvKI */\r\n/* 3cwLfuVQgK2RZ2z+Kc3K3dRPz2rXycK5XCuRZmvGab/WbrZiC7wJQapgBodltMI5 */\r\n/* GMdFrBg9IeF7/rP4EqVQXeKtevTlZXjpuNhhjuR+2DMt/dWufjXpiW91bo3aH6Ea */\r\n/* jOALXmoxgltCp1K7hrS6gmsvj94cLRf50QQ4U8Qwggd6MIIFYqADAgECAgphDpDS */\r\n/* AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK */\r\n/* V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0 */\r\n/* IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0 */\r\n/* ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla */\r\n/* MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS */\r\n/* ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT */\r\n/* H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB */\r\n/* AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG */\r\n/* OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S */\r\n/* 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz */\r\n/* y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7 */\r\n/* 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u */\r\n/* M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33 */\r\n/* X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl */\r\n/* XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP */\r\n/* 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB */\r\n/* l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF */\r\n/* RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM */\r\n/* CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ */\r\n/* BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud */\r\n/* DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO */\r\n/* 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0 */\r\n/* LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y */\r\n/* Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p */\r\n/* Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y */\r\n/* Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB */\r\n/* FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw */\r\n/* cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA */\r\n/* XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY */\r\n/* 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj */\r\n/* 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd */\r\n/* d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ */\r\n/* Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf */\r\n/* wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ */\r\n/* aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j */\r\n/* NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B */\r\n/* xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96 */\r\n/* eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7 */\r\n/* r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I */\r\n/* RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVZzCCFWMCAQEwgZUwfjELMAkG */\r\n/* A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx */\r\n/* HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z */\r\n/* b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAYdyF3IVWUDHCQAAAAABhzAN */\r\n/* BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor */\r\n/* BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgMC/orGY1 */\r\n/* gfB1hsQjG1lyTu9MAGbhJ+T22w7TA3J3lU8wQgYKKwYBBAGCNwIBDDE0MDKgFIAS */\r\n/* AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN */\r\n/* BgkqhkiG9w0BAQEFAASCAQCjrMwnWdiDhFgDpoWhqWMJ473gHqjSpuGt18jSbPyW */\r\n/* whPOmBvwYOb/CAiQ/kX32DaYn7EQJOKdReWwiZrqtf2TqrAXYeaoC2qCqkZOqqMC */\r\n/* c+79Ov9NQ4MsxTFiRa023+eWg5KE266QIh/WJaQaBSPpoXbIcHcEnQ8lHdb/DO9v */\r\n/* yZ/Zp/t8PuXOap+Go6jkSeD/zU4B8FswbqSJXWrLCzEWSjAQUksoZXYVsiUvb6+w */\r\n/* 9t79CK4ugNLJS6ILDxn5ncOQfHv47d1e4H2Y+OWOP/Z45kcD1fl4QRnM+WQEa859 */\r\n/* spOcWWk9pnTuvfCo5X86LOP+jdQa304GVxDeAhJjtvquoYIS8TCCEu0GCisGAQQB */\r\n/* gjcDAwExghLdMIIS2QYJKoZIhvcNAQcCoIISyjCCEsYCAQMxDzANBglghkgBZQME */\r\n/* AgEFADCCAVUGCyqGSIb3DQEJEAEEoIIBRASCAUAwggE8AgEBBgorBgEEAYRZCgMB */\r\n/* MDEwDQYJYIZIAWUDBAIBBQAEIBPLNFthVEbZ8wwcxOxfPOwIYuIklub6TutRWTzR */\r\n/* A5CWAgZfYPphXqQYEzIwMjAwOTIyMjIxOTUxLjI0OVowBIACAfSggdSkgdEwgc4x */\r\n/* CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt */\r\n/* b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1p */\r\n/* Y3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMg */\r\n/* VFNTIEVTTjowQTU2LUUzMjktNEQ0RDElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt */\r\n/* U3RhbXAgU2VydmljZaCCDkQwggT1MIID3aADAgECAhMzAAABJy9uo++RqBmoAAAA */\r\n/* AAEnMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo */\r\n/* aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y */\r\n/* cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw */\r\n/* MB4XDTE5MTIxOTAxMTQ1OVoXDTIxMDMxNzAxMTQ1OVowgc4xCzAJBgNVBAYTAlVT */\r\n/* MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK */\r\n/* ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVy */\r\n/* YXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjowQTU2 */\r\n/* LUUzMjktNEQ0RDElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vydmlj */\r\n/* ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPgB3nERnk6fS40vvWeD */\r\n/* 3HCgM9Ep4xTIQiPnJXE9E+HkZVtTsPemoOyhfNAyF95E/rUvXOVTUcJFL7Xb16jT */\r\n/* KPXONsCWY8DCixSDIiid6xa30TiEWVcIZRwiDlcx29D467OTav5rA1G6TwAEY5rQ */\r\n/* jhUHLrOoJgfJfakZq6IHjd+slI0/qlys7QIGakFk2OB6mh/ln/nS8G4kNRK6Do4g */\r\n/* xDtnBSFLNfhsSZlRSMDJwFvrZ2FCkaoexd7rKlUNOAAScY411IEqQeI1PwfRm3aW */\r\n/* bS8IvAfJPC2Ah2LrtP8sKn5faaU8epexje7vZfcZif/cbxgUKStJzqbdvTBNc93n */\r\n/* /Z8CAwEAAaOCARswggEXMB0GA1UdDgQWBBTl9JZVgF85MSRbYlOJXbhY022V8jAf */\r\n/* BgNVHSMEGDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8ETzBNMEugSaBH */\r\n/* hkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNU */\r\n/* aW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUF */\r\n/* BzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1RpbVN0 */\r\n/* YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsG */\r\n/* AQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IBAQAKyo180VXHBqVnjZwQy7NlzXbo2+W5 */\r\n/* qfHxR7ANV5RBkRkdGamkwUcDNL+DpHObFPJHa0oTeYKE0Zbl1MvvfS8RtGGdhGYG */\r\n/* CJf+BPd/gBCs4+dkZdjvOzNyuVuDPGlqQ5f7HS7iuQ/cCyGHcHYJ0nXVewF2Lk+J */\r\n/* lrWykHpTlLwPXmCpNR+gieItPi/UMF2RYTGwojW+yIVwNyMYnjFGUxEX5/DtJjRZ */\r\n/* mg7PBHMrENN2DgO6wBelp4ptyH2KK2EsWT+8jFCuoKv+eJby0QD55LN5f8SrUPRn */\r\n/* K86fh7aVOfCglQofo5ABZIGiDIrg4JsV4k6p0oBSIFOAcqRAhiH+1spCMIIGcTCC */\r\n/* BFmgAwIBAgIKYQmBKgAAAAAAAjANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMC */\r\n/* VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV */\r\n/* BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJv */\r\n/* b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMTAwNzAxMjEzNjU1WhcN */\r\n/* MjUwNzAxMjE0NjU1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv */\r\n/* bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0 */\r\n/* aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCASIw */\r\n/* DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkdDbx3EYo6IOz8E5f1+n9plGt0 */\r\n/* VBDVpQoAgoX77XxoSyxfxcPlYcJ2tz5mK1vwFVMnBDEfQRsalR3OCROOfGEwWbEw */\r\n/* RA/xYIiEVEMM1024OAizQt2TrNZzMFcmgqNFDdDq9UeBzb8kYDJYYEbyWEeGMoQe */\r\n/* dGFnkV+BVLHPk0ySwcSmXdFhE24oxhr5hoC732H8RsEnHSRnEnIaIYqvS2SJUGKx */\r\n/* Xf13Hz3wV3WsvYpCTUBR0Q+cBj5nf/VmwAOWRH7v0Ev9buWayrGo8noqCjHw2k4G */\r\n/* kbaICDXoeByw6ZnNPOcvRLqn9NxkvaQBwSAJk3jN/LzAyURdXhacAQVPIk0CAwEA */\r\n/* AaOCAeYwggHiMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBTVYzpcijGQ80N7 */\r\n/* fEYbxTNoWoVtVTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMC */\r\n/* AYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvX */\r\n/* zpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20v */\r\n/* cGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYI */\r\n/* KwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5j */\r\n/* b20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDCBoAYDVR0g */\r\n/* AQH/BIGVMIGSMIGPBgkrBgEEAYI3LgMwgYEwPQYIKwYBBQUHAgEWMWh0dHA6Ly93 */\r\n/* d3cubWljcm9zb2Z0LmNvbS9QS0kvZG9jcy9DUFMvZGVmYXVsdC5odG0wQAYIKwYB */\r\n/* BQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AUABvAGwAaQBjAHkAXwBTAHQAYQB0AGUA */\r\n/* bQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAAfmiFEN4sbgmD+BcQM9naOh */\r\n/* IW+z66bM9TG+zwXiqf76V20ZMLPCxWbJat/15/B4vceoniXj+bzta1RXCCtRgkQS */\r\n/* +7lTjMz0YBKKdsxAQEGb3FwX/1z5Xhc1mCRWS3TvQhDIr79/xn/yN31aPxzymXlK */\r\n/* kVIArzgPF/UveYFl2am1a+THzvbKegBvSzBEJCI8z+0DpZaPWSm8tv0E4XCfMkon */\r\n/* /VWvL/625Y4zu2JfmttXQOnxzplmkIz/amJ/3cVKC5Em4jnsGUpxY517IW3DnKOi */\r\n/* PPp/fZZqkHimbdLhnPkd/DjYlPTGpQqWhqS9nhquBEKDuLWAmyI4ILUl5WTs9/S/ */\r\n/* fmNZJQ96LjlXdqJxqgaKD4kWumGnEcua2A5HmoDF0M2n0O99g/DhO3EJ3110mCII */\r\n/* YdqwUB5vvfHhAN/nMQekkzr3ZUd46PioSKv33nJ+YWtvd6mBy6cJrDm77MbL2IK0 */\r\n/* cs0d9LiFAR6A+xuJKlQ5slvayA1VmXqHczsI5pgt6o3gMy4SKfXAL1QnIffIrE7a */\r\n/* KLixqduWsqdCosnPGUFN4Ib5KpqjEWYw07t0MkvfY3v1mYovG8chr1m1rtxEPJdQ */\r\n/* cdeh0sVV42neV8HR3jDA/czmTfsNv11P6Z0eGTgvvM9YBS7vDaBQNdrvCScc1bN+ */\r\n/* NR4Iuto229Nfj950iEkSoYIC0jCCAjsCAQEwgfyhgdSkgdEwgc4xCzAJBgNVBAYT */\r\n/* AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD */\r\n/* VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBP */\r\n/* cGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjow */\r\n/* QTU2LUUzMjktNEQ0RDElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy */\r\n/* dmljZaIjCgEBMAcGBSsOAwIaAxUAs5W4TmyDHMRM7iz6mgGojqvXHzOggYMwgYCk */\r\n/* fjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH */\r\n/* UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD */\r\n/* Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIF */\r\n/* AOMUsu8wIhgPMjAyMDA5MjIyMTI5MTlaGA8yMDIwMDkyMzIxMjkxOVowdzA9Bgor */\r\n/* BgEEAYRZCgQBMS8wLTAKAgUA4xSy7wIBADAKAgEAAgIVPgIB/zAHAgEAAgIRtjAK */\r\n/* AgUA4xYEbwIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIB */\r\n/* AAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAEMD4esQRMLwQdhk */\r\n/* Co1zgvmclcwl3lYYpk1oMh1ndsU3+97Rt6FV3adS4Hezc/K94oQKjcxtMVzLzQhG */\r\n/* agM6XlqB31VD8n2nxVuaWD1yp2jm/0IvfL9nFMHJRhgANMiBdHqvqNrd86c/Kryq */\r\n/* sI0Ch0sOx9wg3BozzqQhmdNjf9c6MYIDDTCCAwkCAQEwgZMwfDELMAkGA1UEBhMC */\r\n/* VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV */\r\n/* BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRp */\r\n/* bWUtU3RhbXAgUENBIDIwMTACEzMAAAEnL26j75GoGagAAAAAAScwDQYJYIZIAWUD */\r\n/* BAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0B */\r\n/* CQQxIgQg/U1ThwYjl65L4baBOXDEDb7//jQrQlYA0cYE9FlfO3swgfoGCyqGSIb3 */\r\n/* DQEJEAIvMYHqMIHnMIHkMIG9BCAbkuhLEoYdahb/BUyVszO2VDi6kB3MSaof/+8u */\r\n/* 7SM+IjCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u */\r\n/* MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp */\r\n/* b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB */\r\n/* Jy9uo++RqBmoAAAAAAEnMCIEIK4r6N3NISekswMCG1kSBJCCCePrlLDQWbMKz0wt */\r\n/* Lj6CMA0GCSqGSIb3DQEBCwUABIIBACDLuq6BoGBriDoXannpgEinZyZN3Q033i3n */\r\n/* dqST50fVElRabEBHd70IaqgBBovB75obPAEecVLMP24ti411wt2k4gs/zor+3I34 */\r\n/* r/hFZRQEJbMESNsRDpCDFVm5fT55uwFUTg6esiQgsMXcvYlpkypKmq8fr4I2GT4V */\r\n/* leW9JafateqTA7f4oQeLvSq+Y/QrMVQIf08db1vXi3J0crsIFeVRmAB34kW9rrqT */\r\n/* pvQKpJHm8SKqBQMMfQXxyomEbwDeJ8Eu/9/FwL+NfvzdsNwxWzjA05IgZdEelwun */\r\n/* f6B4E0kWDJvgeedsXIvsQ92hAoQubWQ2F9pYDygONBjoxnqijzs= */\r\n/* SIG # End signature block */\r\n"
  },
  {
    "path": "src/PowerShell/ExternalModules/PowerShellGet/2.2.5/DscResources/MSFT_PSRepository/en-US/MSFT_PSRepository.strings.psd1",
    "content": "#\r\n# Copyright (c) Microsoft Corporation.\r\n#\r\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n# THE SOFTWARE.\r\n#\r\n# culture = \"en-US\"\r\nConvertFrom-StringData -StringData @'\r\n    GetTargetResourceMessage  = Return the current state of the repository '{0}'.\r\n    RepositoryNotFound        = The repository '{0}' was not found.\r\n    TestTargetResourceMessage = Determining if the repository '{0}' is in the desired state.\r\n    InDesiredState            = Repository '{0}' is in the desired state.\r\n    NotInDesiredState         = Repository '{0}' is not in the desired state.\r\n    RepositoryExist           = Updating the properties of the repository '{0}'.\r\n    RepositoryDoesNotExist    = Creating the repository '{0}'.\r\n    RemoveExistingRepository  = Removing the repository '{0}'.\r\n'@\r\n\r\n# SIG # Begin signature block\r\n# MIIjjwYJKoZIhvcNAQcCoIIjgDCCI3wCAQExDzANBglghkgBZQMEAgEFADB5Bgor\r\n# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG\r\n# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDIsy85n1MNq+kW\r\n# xzRs7tzuriysf98xKvvABEQcTZkh4aCCDYEwggX/MIID56ADAgECAhMzAAABh3IX\r\n# chVZQMcJAAAAAAGHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD\r\n# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p\r\n# bmcgUENBIDIwMTEwHhcNMjAwMzA0MTgzOTQ3WhcNMjEwMzAzMTgzOTQ3WjB0MQsw\r\n# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u\r\n# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\r\n# AQDOt8kLc7P3T7MKIhouYHewMFmnq8Ayu7FOhZCQabVwBp2VS4WyB2Qe4TQBT8aB\r\n# znANDEPjHKNdPT8Xz5cNali6XHefS8i/WXtF0vSsP8NEv6mBHuA2p1fw2wB/F0dH\r\n# sJ3GfZ5c0sPJjklsiYqPw59xJ54kM91IOgiO2OUzjNAljPibjCWfH7UzQ1TPHc4d\r\n# weils8GEIrbBRb7IWwiObL12jWT4Yh71NQgvJ9Fn6+UhD9x2uk3dLj84vwt1NuFQ\r\n# itKJxIV0fVsRNR3abQVOLqpDugbr0SzNL6o8xzOHL5OXiGGwg6ekiXA1/2XXY7yV\r\n# Fc39tledDtZjSjNbex1zzwSXAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE\r\n# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUhov4ZyO96axkJdMjpzu2zVXOJcsw\r\n# UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1\r\n# ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDU4Mzg1MB8GA1UdIwQYMBaAFEhu\r\n# ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu\r\n# bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w\r\n# Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3\r\n# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx\r\n# MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAixmy\r\n# S6E6vprWD9KFNIB9G5zyMuIjZAOuUJ1EK/Vlg6Fb3ZHXjjUwATKIcXbFuFC6Wr4K\r\n# NrU4DY/sBVqmab5AC/je3bpUpjtxpEyqUqtPc30wEg/rO9vmKmqKoLPT37svc2NV\r\n# BmGNl+85qO4fV/w7Cx7J0Bbqk19KcRNdjt6eKoTnTPHBHlVHQIHZpMxacbFOAkJr\r\n# qAVkYZdz7ikNXTxV+GRb36tC4ByMNxE2DF7vFdvaiZP0CVZ5ByJ2gAhXMdK9+usx\r\n# zVk913qKde1OAuWdv+rndqkAIm8fUlRnr4saSCg7cIbUwCCf116wUJ7EuJDg0vHe\r\n# yhnCeHnBbyH3RZkHEi2ofmfgnFISJZDdMAeVZGVOh20Jp50XBzqokpPzeZ6zc1/g\r\n# yILNyiVgE+RPkjnUQshd1f1PMgn3tns2Cz7bJiVUaqEO3n9qRFgy5JuLae6UweGf\r\n# AeOo3dgLZxikKzYs3hDMaEtJq8IP71cX7QXe6lnMmXU/Hdfz2p897Zd+kU+vZvKI\r\n# 3cwLfuVQgK2RZ2z+Kc3K3dRPz2rXycK5XCuRZmvGab/WbrZiC7wJQapgBodltMI5\r\n# GMdFrBg9IeF7/rP4EqVQXeKtevTlZXjpuNhhjuR+2DMt/dWufjXpiW91bo3aH6Ea\r\n# jOALXmoxgltCp1K7hrS6gmsvj94cLRf50QQ4U8Qwggd6MIIFYqADAgECAgphDpDS\r\n# AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK\r\n# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0\r\n# IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0\r\n# ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla\r\n# MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS\r\n# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT\r\n# H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB\r\n# AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG\r\n# OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S\r\n# 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz\r\n# y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7\r\n# 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u\r\n# M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33\r\n# X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl\r\n# XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP\r\n# 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB\r\n# l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF\r\n# RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM\r\n# CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ\r\n# BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud\r\n# DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO\r\n# 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0\r\n# LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p\r\n# Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB\r\n# FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw\r\n# cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA\r\n# XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY\r\n# 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj\r\n# 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd\r\n# d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ\r\n# Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf\r\n# wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ\r\n# aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j\r\n# NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B\r\n# xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96\r\n# eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7\r\n# r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I\r\n# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVZDCCFWACAQEwgZUwfjELMAkG\r\n# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx\r\n# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z\r\n# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAYdyF3IVWUDHCQAAAAABhzAN\r\n# BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor\r\n# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgmA+n9QXz\r\n# 8dT2ub5mX+3kqHOkIOPzbPjen0qPL4vqih4wQgYKKwYBBAGCNwIBDDE0MDKgFIAS\r\n# AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN\r\n# BgkqhkiG9w0BAQEFAASCAQBPossKE/JJRgLki6udUal6kKvvd+cj8yT23YFiJ+GG\r\n# 7YvWIt/u67qqWA+PSN0PCH8bY1HCUkMGat4UTqKJ/dALKx5oOlfsbUSACyX1BU9x\r\n# mXDPzak96AnHy+oQICcENAWYBT4deS8jrFv1InsRT6lg4pEGQvCx+fZbdAe5HRp5\r\n# cAlIVYapHXxDBQvAbpMoMMi0TertRaBx9t3bWWLGguBUR92ra8a3HFOt7KHT04Xa\r\n# 7JgLsQoTUTlavt67fWUABX5pSVwP25v9IXUSclgz5l1xXrBHTmZPGRsjBu881s+M\r\n# 168vsc6P9RW8JjsKwDajs2oWkRY3F68wb7xLa2ZQ4X5koYIS7jCCEuoGCisGAQQB\r\n# gjcDAwExghLaMIIS1gYJKoZIhvcNAQcCoIISxzCCEsMCAQMxDzANBglghkgBZQME\r\n# AgEFADCCAVUGCyqGSIb3DQEJEAEEoIIBRASCAUAwggE8AgEBBgorBgEEAYRZCgMB\r\n# MDEwDQYJYIZIAWUDBAIBBQAEIHikZhYxRsySx5WAopqolokj5LdR1qw/Qj19bR6x\r\n# FpA5AgZfYPebj+kYEzIwMjAwOTIyMjIxOTUxLjQ1NVowBIACAfSggdSkgdEwgc4x\r\n# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt\r\n# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1p\r\n# Y3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMg\r\n# VFNTIEVTTjo2MEJDLUUzODMtMjYzNTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt\r\n# U3RhbXAgU2VydmljZaCCDkEwggT1MIID3aADAgECAhMzAAABJt+6SyK5goIHAAAA\r\n# AAEmMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo\r\n# aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y\r\n# cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw\r\n# MB4XDTE5MTIxOTAxMTQ1OVoXDTIxMDMxNzAxMTQ1OVowgc4xCzAJBgNVBAYTAlVT\r\n# MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK\r\n# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVy\r\n# YXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo2MEJD\r\n# LUUzODMtMjYzNTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vydmlj\r\n# ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ4wvoacTvMNlXQTtfF/\r\n# Cx5Ol3X0fcjUNMvjLgTmO5+WHYJFbp725P3+qvFKDRQHWEI1Sz0gB24urVDIjXjB\r\n# h5NVNJVMQJI2tltv7M4/4IbhZJb3xzQW7LolEoZYUZanBTUuyly9osCg4o5joViT\r\n# 2GtmyxK+Fv5kC20l2opeaeptd/E7ceDAFRM87hiNCsK/KHyC+8+swnlg4gTOey6z\r\n# QqhzgNsG6HrjLBuDtDs9izAMwS2yWT0T52QA9h3Q+B1C9ps2fMKMe+DHpG+0c61D\r\n# 94Yh6cV2XHib4SBCnwIFZAeZE2UJ4qPANSYozI8PH+E5rCT3SVqYvHou97HsXvP2\r\n# I3MCAwEAAaOCARswggEXMB0GA1UdDgQWBBRJq6wfF7B+mEKN0VimX8ajNA5hQTAf\r\n# BgNVHSMEGDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8ETzBNMEugSaBH\r\n# hkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNU\r\n# aW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUF\r\n# BzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1RpbVN0\r\n# YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsG\r\n# AQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IBAQBAlvudaOlv9Cfzv56bnX41czF6tLtH\r\n# LB46l6XUch+qNN45ZmOTFwLot3JjwSrn4oycQ9qTET1TFDYd1QND0LiXmKz9OqBX\r\n# ai6S8XdyCQEZvfL82jIAs9pwsAQ6XvV9jNybPStRgF/sOAM/Deyfmej9Tg9FcRwX\r\n# ank2qgzdZZNb8GoEze7f1orcTF0Q89IUXWIlmwEwQFYF1wjn87N4ZxL9Z/xA2m/R\r\n# 1zizFylWP/mpamCnVfZZLkafFLNUNVmcvc+9gM7vceJs37d3ydabk4wR6ObR34sW\r\n# aLppmyPlsI1Qq5Lu6bJCWoXzYuWpkoK6oEep1gML6SRC3HKVS3UscZhtMIIGcTCC\r\n# BFmgAwIBAgIKYQmBKgAAAAAAAjANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMC\r\n# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV\r\n# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJv\r\n# b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMTAwNzAxMjEzNjU1WhcN\r\n# MjUwNzAxMjE0NjU1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv\r\n# bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0\r\n# aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCASIw\r\n# DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkdDbx3EYo6IOz8E5f1+n9plGt0\r\n# VBDVpQoAgoX77XxoSyxfxcPlYcJ2tz5mK1vwFVMnBDEfQRsalR3OCROOfGEwWbEw\r\n# RA/xYIiEVEMM1024OAizQt2TrNZzMFcmgqNFDdDq9UeBzb8kYDJYYEbyWEeGMoQe\r\n# dGFnkV+BVLHPk0ySwcSmXdFhE24oxhr5hoC732H8RsEnHSRnEnIaIYqvS2SJUGKx\r\n# Xf13Hz3wV3WsvYpCTUBR0Q+cBj5nf/VmwAOWRH7v0Ev9buWayrGo8noqCjHw2k4G\r\n# kbaICDXoeByw6ZnNPOcvRLqn9NxkvaQBwSAJk3jN/LzAyURdXhacAQVPIk0CAwEA\r\n# AaOCAeYwggHiMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBTVYzpcijGQ80N7\r\n# fEYbxTNoWoVtVTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMC\r\n# AYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvX\r\n# zpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20v\r\n# cGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYI\r\n# KwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5j\r\n# b20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDCBoAYDVR0g\r\n# AQH/BIGVMIGSMIGPBgkrBgEEAYI3LgMwgYEwPQYIKwYBBQUHAgEWMWh0dHA6Ly93\r\n# d3cubWljcm9zb2Z0LmNvbS9QS0kvZG9jcy9DUFMvZGVmYXVsdC5odG0wQAYIKwYB\r\n# BQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AUABvAGwAaQBjAHkAXwBTAHQAYQB0AGUA\r\n# bQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAAfmiFEN4sbgmD+BcQM9naOh\r\n# IW+z66bM9TG+zwXiqf76V20ZMLPCxWbJat/15/B4vceoniXj+bzta1RXCCtRgkQS\r\n# +7lTjMz0YBKKdsxAQEGb3FwX/1z5Xhc1mCRWS3TvQhDIr79/xn/yN31aPxzymXlK\r\n# kVIArzgPF/UveYFl2am1a+THzvbKegBvSzBEJCI8z+0DpZaPWSm8tv0E4XCfMkon\r\n# /VWvL/625Y4zu2JfmttXQOnxzplmkIz/amJ/3cVKC5Em4jnsGUpxY517IW3DnKOi\r\n# PPp/fZZqkHimbdLhnPkd/DjYlPTGpQqWhqS9nhquBEKDuLWAmyI4ILUl5WTs9/S/\r\n# fmNZJQ96LjlXdqJxqgaKD4kWumGnEcua2A5HmoDF0M2n0O99g/DhO3EJ3110mCII\r\n# YdqwUB5vvfHhAN/nMQekkzr3ZUd46PioSKv33nJ+YWtvd6mBy6cJrDm77MbL2IK0\r\n# cs0d9LiFAR6A+xuJKlQ5slvayA1VmXqHczsI5pgt6o3gMy4SKfXAL1QnIffIrE7a\r\n# KLixqduWsqdCosnPGUFN4Ib5KpqjEWYw07t0MkvfY3v1mYovG8chr1m1rtxEPJdQ\r\n# cdeh0sVV42neV8HR3jDA/czmTfsNv11P6Z0eGTgvvM9YBS7vDaBQNdrvCScc1bN+\r\n# NR4Iuto229Nfj950iEkSoYICzzCCAjgCAQEwgfyhgdSkgdEwgc4xCzAJBgNVBAYT\r\n# AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD\r\n# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBP\r\n# cGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo2\r\n# MEJDLUUzODMtMjYzNTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy\r\n# dmljZaIjCgEBMAcGBSsOAwIaAxUACmcyOWmZxErpq06B8dy6oMZ6//yggYMwgYCk\r\n# fjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH\r\n# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD\r\n# Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIF\r\n# AOMUsDowIhgPMjAyMDA5MjIyMTE3NDZaGA8yMDIwMDkyMzIxMTc0NlowdDA6Bgor\r\n# BgEEAYRZCgQBMSwwKjAKAgUA4xSwOgIBADAHAgEAAgII+zAHAgEAAgIRDTAKAgUA\r\n# 4xYBugIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAID\r\n# B6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAGFtTfLVXgP5nTlAW4+t\r\n# qfeH51GOeG4NIbJTmRivKyHJM/AjTJCfaazyngryVGsVed/19YBgxoB07IS1Jlmm\r\n# KNq9XofCcAXBUcoBsPLnGHr8vBVOpAPDLDYgr7ME8Qgofa5CjOmCQMYZyjsW2q5j\r\n# 2OkaGPVN1YtLAZq82zgDGI+QMYIDDTCCAwkCAQEwgZMwfDELMAkGA1UEBhMCVVMx\r\n# EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT\r\n# FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUt\r\n# U3RhbXAgUENBIDIwMTACEzMAAAEm37pLIrmCggcAAAAAASYwDQYJYIZIAWUDBAIB\r\n# BQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQx\r\n# IgQgTg7YbUxqwEPryPvBnm6tKeHXdMGcW0dFqzF8v32xEgQwgfoGCyqGSIb3DQEJ\r\n# EAIvMYHqMIHnMIHkMIG9BCA2/c/vnr1ecAzvapOWZ2xGfAkzrkfpGcrvMW07CQl1\r\n# DzCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw\r\n# DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x\r\n# JjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAABJt+6\r\n# SyK5goIHAAAAAAEmMCIEILioZM02FaPhX5O1/7sR3BeH9w6NUS1x/c+Q88996cSH\r\n# MA0GCSqGSIb3DQEBCwUABIIBAEZEbtwLgdlFNIt4umG1gw1nrQVpGXIkyojlPtcb\r\n# hQu757SIEuY7tS0MmwFimKjHmCbeVS12PJ1PHjxXs8YmpOusFH9wtCgPPHHm3IEx\r\n# naynU0x6jl4MXGtmTIF5E8iHA1y0YeSoeeinaez2Lc78G+jHN6uzf+TJozwpqkle\r\n# aZIVhuqPAqJZvfVDT3Bd7N4J2j4D6H0lxJ+yn/ENLkNEl4jVMutEMDQuDSikB8/V\r\n# hpcMRx83R4M8gEIrFIORJVwqT5axQI5C9HQuWFB9xyTvU5Q/OaU4ybRj5jUTPNZs\r\n# 3/emFZ3aTnt8arfvfztIvFw2NbnM6rIPVjm4YDT9YUD2xNM=\r\n# SIG # End signature block\r\n"
  },
  {
    "path": "src/PowerShell/ExternalModules/PowerShellGet/2.2.5/Modules/PowerShellGet.LocalizationHelper/PowerShellGet.LocalizationHelper.psm1",
    "content": "<#\r\n    .SYNOPSIS\r\n        Creates and throws an invalid argument exception.\r\n\r\n    .PARAMETER Message\r\n        The message explaining why this error is being thrown.\r\n\r\n    .PARAMETER ArgumentName\r\n        The name of the invalid argument that is causing this error to be thrown.\r\n#>\r\nfunction New-InvalidArgumentException {\r\n    [CmdletBinding()]\r\n    param\r\n    (\r\n        [Parameter(Mandatory = $true)]\r\n        [ValidateNotNullOrEmpty()]\r\n        [System.String]\r\n        $Message,\r\n\r\n        [Parameter(Mandatory = $true)]\r\n        [ValidateNotNullOrEmpty()]\r\n        [System.String]\r\n        $ArgumentName\r\n    )\r\n\r\n    $argumentException = New-Object -TypeName 'ArgumentException' `\r\n        -ArgumentList @($Message, $ArgumentName)\r\n\r\n    $newObjectParameters = @{\r\n        TypeName     = 'System.Management.Automation.ErrorRecord'\r\n        ArgumentList = @($argumentException, $ArgumentName, 'InvalidArgument', $null)\r\n    }\r\n\r\n    $errorRecord = New-Object @newObjectParameters\r\n\r\n    throw $errorRecord\r\n}\r\n\r\n<#\r\n    .SYNOPSIS\r\n        Creates and throws an invalid operation exception.\r\n\r\n    .PARAMETER Message\r\n        The message explaining why this error is being thrown.\r\n\r\n    .PARAMETER ErrorRecord\r\n        The error record containing the exception that is causing this terminating error.\r\n#>\r\nfunction New-InvalidOperationException {\r\n    [CmdletBinding()]\r\n    param\r\n    (\r\n        [Parameter(Mandatory = $true)]\r\n        [ValidateNotNullOrEmpty()]\r\n        [System.String]\r\n        $Message,\r\n\r\n        [Parameter()]\r\n        [ValidateNotNull()]\r\n        [System.Management.Automation.ErrorRecord]\r\n        $ErrorRecord\r\n    )\r\n\r\n    if ($null -eq $ErrorRecord) {\r\n        $invalidOperationException = New-Object -TypeName 'InvalidOperationException' `\r\n            -ArgumentList @($Message)\r\n    }\r\n    else {\r\n        $invalidOperationException = New-Object -TypeName 'InvalidOperationException' `\r\n            -ArgumentList @($Message, $ErrorRecord.Exception)\r\n    }\r\n\r\n    $newObjectParameters = @{\r\n        TypeName     = 'System.Management.Automation.ErrorRecord'\r\n        ArgumentList = @(\r\n            $invalidOperationException.ToString(),\r\n            'MachineStateIncorrect',\r\n            'InvalidOperation',\r\n            $null\r\n        )\r\n    }\r\n\r\n    $errorRecordToThrow = New-Object @newObjectParameters\r\n\r\n    throw $errorRecordToThrow\r\n}\r\n\r\n<#\r\n    .SYNOPSIS\r\n        Creates and throws an object not found exception.\r\n\r\n    .PARAMETER Message\r\n        The message explaining why this error is being thrown.\r\n\r\n    .PARAMETER ErrorRecord\r\n        The error record containing the exception that is causing this terminating error.\r\n#>\r\nfunction New-ObjectNotFoundException {\r\n    [CmdletBinding()]\r\n    param\r\n    (\r\n        [Parameter(Mandatory = $true)]\r\n        [ValidateNotNullOrEmpty()]\r\n        [System.String]\r\n        $Message,\r\n\r\n        [Parameter()]\r\n        [ValidateNotNull()]\r\n        [System.Management.Automation.ErrorRecord]\r\n        $ErrorRecord\r\n    )\r\n\r\n    if ($null -eq $ErrorRecord) {\r\n        $exception = New-Object -TypeName 'System.Exception' `\r\n            -ArgumentList @($Message)\r\n    }\r\n    else {\r\n        $exception = New-Object -TypeName 'System.Exception' `\r\n            -ArgumentList @($Message, $ErrorRecord.Exception)\r\n    }\r\n\r\n    $newObjectParameters = @{\r\n        TypeName     = 'System.Management.Automation.ErrorRecord'\r\n        ArgumentList = @(\r\n            $exception.ToString(),\r\n            'MachineStateIncorrect',\r\n            'ObjectNotFound',\r\n            $null\r\n        )\r\n    }\r\n\r\n    $errorRecordToThrow = New-Object @newObjectParameters\r\n\r\n    throw $errorRecordToThrow\r\n}\r\n\r\n<#\r\n    .SYNOPSIS\r\n        Creates and throws an invalid result exception.\r\n\r\n    .PARAMETER Message\r\n        The message explaining why this error is being thrown.\r\n\r\n    .PARAMETER ErrorRecord\r\n        The error record containing the exception that is causing this terminating error.\r\n#>\r\nfunction New-InvalidResultException {\r\n    [CmdletBinding()]\r\n    param\r\n    (\r\n        [Parameter(Mandatory = $true)]\r\n        [ValidateNotNullOrEmpty()]\r\n        [System.String]\r\n        $Message,\r\n\r\n        [Parameter()]\r\n        [ValidateNotNull()]\r\n        [System.Management.Automation.ErrorRecord]\r\n        $ErrorRecord\r\n    )\r\n\r\n    if ($null -eq $ErrorRecord) {\r\n        $exception = New-Object -TypeName 'System.Exception' `\r\n            -ArgumentList @($Message)\r\n    }\r\n    else {\r\n        $exception = New-Object -TypeName 'System.Exception' `\r\n            -ArgumentList @($Message, $ErrorRecord.Exception)\r\n    }\r\n\r\n    $newObjectParameters = @{\r\n        TypeName     = 'System.Management.Automation.ErrorRecord'\r\n        ArgumentList = @(\r\n            $exception.ToString(),\r\n            'MachineStateIncorrect',\r\n            'InvalidResult',\r\n            $null\r\n        )\r\n    }\r\n\r\n    $errorRecordToThrow = New-Object @newObjectParameters\r\n\r\n    throw $errorRecordToThrow\r\n}\r\n\r\n<#\r\n    .SYNOPSIS\r\n        Retrieves the localized string data based on the machine's culture.\r\n        Falls back to en-US strings if the machine's culture is not supported.\r\n\r\n    .PARAMETER ResourceName\r\n        The name of the resource as it appears before '.strings.psd1' of the localized string file.\r\n        For example:\r\n            For WindowsOptionalFeature: MSFT_WindowsOptionalFeature\r\n            For Service: MSFT_ServiceResource\r\n            For Registry: MSFT_RegistryResource\r\n            For Helper: SqlServerDscHelper\r\n\r\n    .PARAMETER ScriptRoot\r\n        Optional. The root path where to expect to find the culture folder. This is only needed\r\n        for localization in helper modules. This should not normally be used for resources.\r\n#>\r\nfunction Get-LocalizedData {\r\n    [CmdletBinding()]\r\n    param\r\n    (\r\n        [Parameter(Mandatory = $true)]\r\n        [ValidateNotNullOrEmpty()]\r\n        [System.String]\r\n        $ResourceName,\r\n\r\n        [Parameter()]\r\n        [ValidateNotNullOrEmpty()]\r\n        [System.String]\r\n        $ScriptRoot\r\n    )\r\n\r\n    if ( -not $ScriptRoot ) {\r\n        $resourceDirectory = Join-Path -Path $PSScriptRoot -ChildPath $ResourceName\r\n        $localizedStringFileLocation = Join-Path -Path $resourceDirectory -ChildPath $PSUICulture\r\n    }\r\n    else {\r\n        $localizedStringFileLocation = Join-Path -Path $ScriptRoot -ChildPath $PSUICulture\r\n    }\r\n\r\n    if (-not (Test-Path -Path $localizedStringFileLocation)) {\r\n        # Fallback to en-US\r\n        if ( -not $ScriptRoot ) {\r\n            $localizedStringFileLocation = Join-Path -Path $resourceDirectory -ChildPath 'en-US'\r\n        }\r\n        else {\r\n            $localizedStringFileLocation = Join-Path -Path $ScriptRoot -ChildPath 'en-US'\r\n        }\r\n    }\r\n\r\n    Import-LocalizedData `\r\n        -BindingVariable 'localizedData' `\r\n        -FileName \"$ResourceName.strings.psd1\" `\r\n        -BaseDirectory $localizedStringFileLocation\r\n\r\n    return $localizedData\r\n}\r\n\r\nExport-ModuleMember -Function @(\r\n    'New-InvalidArgumentException',\r\n    'New-InvalidOperationException',\r\n    'New-ObjectNotFoundException',\r\n    'New-InvalidResultException',\r\n    'Get-LocalizedData'\r\n)\r\n\r\n# SIG # Begin signature block\r\n# MIIjkgYJKoZIhvcNAQcCoIIjgzCCI38CAQExDzANBglghkgBZQMEAgEFADB5Bgor\r\n# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG\r\n# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCjPo12DZaAMOkK\r\n# EoYmV1li2n5EmeiwcqQzHkVYm5pRSqCCDYEwggX/MIID56ADAgECAhMzAAABh3IX\r\n# chVZQMcJAAAAAAGHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD\r\n# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p\r\n# bmcgUENBIDIwMTEwHhcNMjAwMzA0MTgzOTQ3WhcNMjEwMzAzMTgzOTQ3WjB0MQsw\r\n# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u\r\n# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\r\n# AQDOt8kLc7P3T7MKIhouYHewMFmnq8Ayu7FOhZCQabVwBp2VS4WyB2Qe4TQBT8aB\r\n# znANDEPjHKNdPT8Xz5cNali6XHefS8i/WXtF0vSsP8NEv6mBHuA2p1fw2wB/F0dH\r\n# sJ3GfZ5c0sPJjklsiYqPw59xJ54kM91IOgiO2OUzjNAljPibjCWfH7UzQ1TPHc4d\r\n# weils8GEIrbBRb7IWwiObL12jWT4Yh71NQgvJ9Fn6+UhD9x2uk3dLj84vwt1NuFQ\r\n# itKJxIV0fVsRNR3abQVOLqpDugbr0SzNL6o8xzOHL5OXiGGwg6ekiXA1/2XXY7yV\r\n# Fc39tledDtZjSjNbex1zzwSXAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE\r\n# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUhov4ZyO96axkJdMjpzu2zVXOJcsw\r\n# UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1\r\n# ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDU4Mzg1MB8GA1UdIwQYMBaAFEhu\r\n# ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu\r\n# bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w\r\n# Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3\r\n# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx\r\n# MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAixmy\r\n# S6E6vprWD9KFNIB9G5zyMuIjZAOuUJ1EK/Vlg6Fb3ZHXjjUwATKIcXbFuFC6Wr4K\r\n# NrU4DY/sBVqmab5AC/je3bpUpjtxpEyqUqtPc30wEg/rO9vmKmqKoLPT37svc2NV\r\n# BmGNl+85qO4fV/w7Cx7J0Bbqk19KcRNdjt6eKoTnTPHBHlVHQIHZpMxacbFOAkJr\r\n# qAVkYZdz7ikNXTxV+GRb36tC4ByMNxE2DF7vFdvaiZP0CVZ5ByJ2gAhXMdK9+usx\r\n# zVk913qKde1OAuWdv+rndqkAIm8fUlRnr4saSCg7cIbUwCCf116wUJ7EuJDg0vHe\r\n# yhnCeHnBbyH3RZkHEi2ofmfgnFISJZDdMAeVZGVOh20Jp50XBzqokpPzeZ6zc1/g\r\n# yILNyiVgE+RPkjnUQshd1f1PMgn3tns2Cz7bJiVUaqEO3n9qRFgy5JuLae6UweGf\r\n# AeOo3dgLZxikKzYs3hDMaEtJq8IP71cX7QXe6lnMmXU/Hdfz2p897Zd+kU+vZvKI\r\n# 3cwLfuVQgK2RZ2z+Kc3K3dRPz2rXycK5XCuRZmvGab/WbrZiC7wJQapgBodltMI5\r\n# GMdFrBg9IeF7/rP4EqVQXeKtevTlZXjpuNhhjuR+2DMt/dWufjXpiW91bo3aH6Ea\r\n# jOALXmoxgltCp1K7hrS6gmsvj94cLRf50QQ4U8Qwggd6MIIFYqADAgECAgphDpDS\r\n# AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK\r\n# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0\r\n# IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0\r\n# ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla\r\n# MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS\r\n# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT\r\n# H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB\r\n# AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG\r\n# OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S\r\n# 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz\r\n# y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7\r\n# 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u\r\n# M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33\r\n# X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl\r\n# XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP\r\n# 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB\r\n# l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF\r\n# RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM\r\n# CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ\r\n# BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud\r\n# DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO\r\n# 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0\r\n# LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p\r\n# Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB\r\n# FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw\r\n# cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA\r\n# XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY\r\n# 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj\r\n# 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd\r\n# d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ\r\n# Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf\r\n# wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ\r\n# aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j\r\n# NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B\r\n# xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96\r\n# eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7\r\n# r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I\r\n# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVZzCCFWMCAQEwgZUwfjELMAkG\r\n# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx\r\n# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z\r\n# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAYdyF3IVWUDHCQAAAAABhzAN\r\n# BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor\r\n# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQg2UNl19jp\r\n# ZkbG4N4XLYPrxRhH3aoWga/DT446FyrX8kUwQgYKKwYBBAGCNwIBDDE0MDKgFIAS\r\n# AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN\r\n# BgkqhkiG9w0BAQEFAASCAQBRCB3fJQ7H+bgUBGyRzfnLylN75t/0j3IsTW+XQtm1\r\n# d/Sjzt0SMKSEo5OHh910EmAVWdld50KeAHRY3uQ1mWTBHRUaHNTxJg5kDfPPhMGy\r\n# q2PxhW6oQStS1SYUacVtJByF4XWHFSXezrJ7NJn0S9mRiC0dA8pSY4eQ+NuAIpMU\r\n# VvXeeb1/OrBXeghR6oagGfVlfEnH2HR6W9RQi8+9qzXFNZRfx9YewEcNsV21iA85\r\n# QK1J9X/StSqGw1T9Zj5g8bDYLY6x876yrOGNV22NkLVh12bpifZ550iO4LPdEm/e\r\n# 29md4h0srONw1+Ov/I68VDm8tEuMPtkbUIamCfFmmUB7oYIS8TCCEu0GCisGAQQB\r\n# gjcDAwExghLdMIIS2QYJKoZIhvcNAQcCoIISyjCCEsYCAQMxDzANBglghkgBZQME\r\n# AgEFADCCAVUGCyqGSIb3DQEJEAEEoIIBRASCAUAwggE8AgEBBgorBgEEAYRZCgMB\r\n# MDEwDQYJYIZIAWUDBAIBBQAEINFMLSXQQ6FisqDCVPG1elrJ+Eq+frhsWlbuloDJ\r\n# TRWiAgZfYPq2eAgYEzIwMjAwOTIyMjIxOTUxLjA0OFowBIACAfSggdSkgdEwgc4x\r\n# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt\r\n# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1p\r\n# Y3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMg\r\n# VFNTIEVTTjo3ODgwLUUzOTAtODAxNDElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt\r\n# U3RhbXAgU2VydmljZaCCDkQwggT1MIID3aADAgECAhMzAAABKKAOgeE21U/CAAAA\r\n# AAEoMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo\r\n# aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y\r\n# cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw\r\n# MB4XDTE5MTIxOTAxMTUwMFoXDTIxMDMxNzAxMTUwMFowgc4xCzAJBgNVBAYTAlVT\r\n# MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK\r\n# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVy\r\n# YXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo3ODgw\r\n# LUUzOTAtODAxNDElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vydmlj\r\n# ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ2Rsdb3VNuGPs2/Dgpc\r\n# 9gt77LG0JPkD4VWTlEJLkqznTJl+RoZfiOwN6iWfPu4k/kj8nwY7pvLs1OsBy494\r\n# yusg4rHLwHNUJPtw1Tc54MOLgdcosA4Nxki73fDyqWwDtjOdk6H7kNczBPqADD6B\r\n# 98ot77/wSACBJIxm9qAUudquS5fczCF0++aWUavDu46U3cv6HEjIdV2ZdJTUKg4W\r\n# UIdTYMQXI082+qSs45WBZjcK98/tIfx8uq8q8ksWF9+zUjGTFiMaKHhn7cSCoEj7\r\n# E1tVmW08ISpS678WFP2+A0OQwaWcJKNACK+J+La7Lz2bGupCidOGz5XDewc1lD9n\r\n# LPcCAwEAAaOCARswggEXMB0GA1UdDgQWBBSE4vKD8X61N5vUAcNOdH9QBMum8jAf\r\n# BgNVHSMEGDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8ETzBNMEugSaBH\r\n# hkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNU\r\n# aW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUF\r\n# BzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1RpbVN0\r\n# YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsG\r\n# AQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IBAQCLX2ZHGIULgDk/iccHWUywjDyAsBHl\r\n# hkmtmBp4lldwL3dNo0bXZZHiSZB+c2KzvPqY64BlECjS/Pqur2m9UaT1N0BeUowR\r\n# HQT88wdzd94gYqKXmLDbVR8yeVgBkcP/JiVWbXdQzcz1ETHgWrh+uzA8BwUgAaHJ\r\n# w+nXYccIuDgPJM1UTeNl9R5Ovf+6zR2E5ZI4DrIqvS4jH4QsoMPTn27AjN7VZt4a\r\n# moRxMLEcQAS7vPT1JUUaRFpFHmkUYVln1YMsw///6968aRvy3cmClS44uxkkaILb\r\n# hh1h09ejZjHhrEn+k9McVkWiuY724jJ/57tylM7A/jzIWNj1F8VlhkyyMIIGcTCC\r\n# BFmgAwIBAgIKYQmBKgAAAAAAAjANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMC\r\n# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV\r\n# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJv\r\n# b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMTAwNzAxMjEzNjU1WhcN\r\n# MjUwNzAxMjE0NjU1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv\r\n# bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0\r\n# aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCASIw\r\n# DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkdDbx3EYo6IOz8E5f1+n9plGt0\r\n# VBDVpQoAgoX77XxoSyxfxcPlYcJ2tz5mK1vwFVMnBDEfQRsalR3OCROOfGEwWbEw\r\n# RA/xYIiEVEMM1024OAizQt2TrNZzMFcmgqNFDdDq9UeBzb8kYDJYYEbyWEeGMoQe\r\n# dGFnkV+BVLHPk0ySwcSmXdFhE24oxhr5hoC732H8RsEnHSRnEnIaIYqvS2SJUGKx\r\n# Xf13Hz3wV3WsvYpCTUBR0Q+cBj5nf/VmwAOWRH7v0Ev9buWayrGo8noqCjHw2k4G\r\n# kbaICDXoeByw6ZnNPOcvRLqn9NxkvaQBwSAJk3jN/LzAyURdXhacAQVPIk0CAwEA\r\n# AaOCAeYwggHiMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBTVYzpcijGQ80N7\r\n# fEYbxTNoWoVtVTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMC\r\n# AYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvX\r\n# zpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20v\r\n# cGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYI\r\n# KwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5j\r\n# b20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDCBoAYDVR0g\r\n# AQH/BIGVMIGSMIGPBgkrBgEEAYI3LgMwgYEwPQYIKwYBBQUHAgEWMWh0dHA6Ly93\r\n# d3cubWljcm9zb2Z0LmNvbS9QS0kvZG9jcy9DUFMvZGVmYXVsdC5odG0wQAYIKwYB\r\n# BQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AUABvAGwAaQBjAHkAXwBTAHQAYQB0AGUA\r\n# bQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAAfmiFEN4sbgmD+BcQM9naOh\r\n# IW+z66bM9TG+zwXiqf76V20ZMLPCxWbJat/15/B4vceoniXj+bzta1RXCCtRgkQS\r\n# +7lTjMz0YBKKdsxAQEGb3FwX/1z5Xhc1mCRWS3TvQhDIr79/xn/yN31aPxzymXlK\r\n# kVIArzgPF/UveYFl2am1a+THzvbKegBvSzBEJCI8z+0DpZaPWSm8tv0E4XCfMkon\r\n# /VWvL/625Y4zu2JfmttXQOnxzplmkIz/amJ/3cVKC5Em4jnsGUpxY517IW3DnKOi\r\n# PPp/fZZqkHimbdLhnPkd/DjYlPTGpQqWhqS9nhquBEKDuLWAmyI4ILUl5WTs9/S/\r\n# fmNZJQ96LjlXdqJxqgaKD4kWumGnEcua2A5HmoDF0M2n0O99g/DhO3EJ3110mCII\r\n# YdqwUB5vvfHhAN/nMQekkzr3ZUd46PioSKv33nJ+YWtvd6mBy6cJrDm77MbL2IK0\r\n# cs0d9LiFAR6A+xuJKlQ5slvayA1VmXqHczsI5pgt6o3gMy4SKfXAL1QnIffIrE7a\r\n# KLixqduWsqdCosnPGUFN4Ib5KpqjEWYw07t0MkvfY3v1mYovG8chr1m1rtxEPJdQ\r\n# cdeh0sVV42neV8HR3jDA/czmTfsNv11P6Z0eGTgvvM9YBS7vDaBQNdrvCScc1bN+\r\n# NR4Iuto229Nfj950iEkSoYIC0jCCAjsCAQEwgfyhgdSkgdEwgc4xCzAJBgNVBAYT\r\n# AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD\r\n# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBP\r\n# cGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo3\r\n# ODgwLUUzOTAtODAxNDElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy\r\n# dmljZaIjCgEBMAcGBSsOAwIaAxUAMT1LG/KAEj0XsiL9n7mxmX1afZuggYMwgYCk\r\n# fjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH\r\n# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD\r\n# Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIF\r\n# AOMUs1YwIhgPMjAyMDA5MjIyMTMxMDJaGA8yMDIwMDkyMzIxMzEwMlowdzA9Bgor\r\n# BgEEAYRZCgQBMS8wLTAKAgUA4xSzVgIBADAKAgEAAgIhfwIB/zAHAgEAAgIRnTAK\r\n# AgUA4xYE1gIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIB\r\n# AAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBACCIjMz039kePvi0\r\n# +QSEAAGe16AJMB2ZvhrAKxWUoyZpnRrWDZizu7wON92D59Wr+LVSvcGrHYflMWt0\r\n# KGA+A/i0fhPG8HWUfiRkGSg5MY5jl8DyE6MMkbWEDwmvZkzuIiQ3/4IsaRgc7vLI\r\n# DM10XS4g59T/1aPBaVnQCn2i8+D+MYIDDTCCAwkCAQEwgZMwfDELMAkGA1UEBhMC\r\n# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV\r\n# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRp\r\n# bWUtU3RhbXAgUENBIDIwMTACEzMAAAEooA6B4TbVT8IAAAAAASgwDQYJYIZIAWUD\r\n# BAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0B\r\n# CQQxIgQgEnw4Ge50R6cM9Hq5+HXFUxJ9mTDd+r571wbhdC3OQJkwgfoGCyqGSIb3\r\n# DQEJEAIvMYHqMIHnMIHkMIG9BCC8RWqLrwVSd+/cGxDfBqS4b1tPXhoPFrC615vV\r\n# 1ugU2jCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u\r\n# MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp\r\n# b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB\r\n# KKAOgeE21U/CAAAAAAEoMCIEIETuk5SkV1/sElaASDGqqK9PNF5z7kvwZ0c4bkPK\r\n# DQQkMA0GCSqGSIb3DQEBCwUABIIBAJnsZe3Pa/JdSEJL3mXUC7341+wXLrKreqxn\r\n# K1RdfgfUitNX5Kv7kxzUrm81hN3TMIjQwj7o2sqdGuQIThRoTCWIBaw4oPafeFsV\r\n# LWaz9BvhRgRjsu36ofO57eS2JlwzZi/zMIWF3G9931glwdTYRhmcDqrOXwVTyno5\r\n# dWqxg36RI3B2DIqNMGDrVBwHbwKQmfRXuZqvw+efCFlQyktjCo0j4ngZLNw2v9J3\r\n# 6S0AXqHMk7M/Wipf/qbp/A11CcUqZ4LnAtiF2vBVyFqrvTGWfKtG+xb7A8aP+rSq\r\n# YpqvL27egErpjjIS1YaF0UF5voxrJqp4POcWLJJ/y88oQgBMoiY=\r\n# SIG # End signature block\r\n"
  },
  {
    "path": "src/PowerShell/ExternalModules/PowerShellGet/2.2.5/Modules/PowerShellGet.ResourceHelper/PowerShellGet.ResourceHelper.psm1",
    "content": "#\r\n# Copyright (c) Microsoft Corporation.\r\n#\r\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n# THE SOFTWARE.\r\n#\r\n\r\n<#\r\n    Helper functions for PowerShellGet DSC Resources.\r\n#>\r\n\r\n# Import localization helper functions.\r\n$helperName = 'PowerShellGet.LocalizationHelper'\r\n$resourceModuleRoot = Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent\r\n$dscResourcesFolderFilePath = Join-Path -Path $resourceModuleRoot -ChildPath \"Modules\\$helperName\\$helperName.psm1\"\r\nImport-Module -Name $dscResourcesFolderFilePath\r\n\r\n# Import Localization Strings\r\n$script:localizedData = Get-LocalizedData -ResourceName 'PowerShellGet.ResourceHelper' -ScriptRoot $PSScriptRoot\r\n\r\n<#\r\n    .SYNOPSIS\r\n        This is a helper function that extract the parameters from a given table.\r\n\r\n    .PARAMETER FunctionBoundParameters\r\n        Specifies the hash table containing a set of parameters to be extracted.\r\n\r\n    .PARAMETER ArgumentNames\r\n        Specifies a list of arguments you want to extract.\r\n#>\r\nfunction New-SplatParameterHashTable {\r\n    [CmdletBinding()]\r\n    [OutputType([System.Collections.Hashtable])]\r\n    param\r\n    (\r\n        [Parameter(Mandatory = $true)]\r\n        [System.Collections.Hashtable]\r\n        $FunctionBoundParameters,\r\n\r\n        [Parameter(Mandatory = $true)]\r\n        [System.String[]]\r\n        $ArgumentNames\r\n    )\r\n\r\n    Write-Verbose -Message ($script:localizedData.CallingFunction -f $($MyInvocation.MyCommand))\r\n\r\n    $returnValue = @{}\r\n\r\n    foreach ($arg in $ArgumentNames) {\r\n        if ($FunctionBoundParameters.ContainsKey($arg)) {\r\n            # Found an argument we are looking for, so we add it to return collection.\r\n            $returnValue.Add($arg, $FunctionBoundParameters[$arg])\r\n        }\r\n    }\r\n\r\n    return $returnValue\r\n}\r\n\r\n<#\r\n    .SYNOPSIS\r\n        This is a helper function that validate that a value is correct and used correctly.\r\n\r\n    .PARAMETER Value\r\n        Specifies the value to be validated.\r\n\r\n    .PARAMETER Type\r\n        Specifies the type of argument.\r\n\r\n    .PARAMETER Type\r\n        Specifies the name of the provider.\r\n\r\n    .OUTPUTS\r\n        None. Throws an error if the test fails.\r\n#>\r\nfunction Test-ParameterValue {\r\n    [CmdletBinding()]\r\n    param\r\n    (\r\n        [Parameter(Mandatory = $true)]\r\n        [ValidateNotNullOrEmpty()]\r\n        [System.String]\r\n        $Value,\r\n\r\n        [Parameter(Mandatory = $true)]\r\n        [ValidateNotNullOrEmpty()]\r\n        [System.String]\r\n        $Type,\r\n\r\n        [Parameter(Mandatory = $true)]\r\n        [ValidateNotNullOrEmpty()]\r\n        [System.String]\r\n        $ProviderName\r\n    )\r\n\r\n    Write-Verbose -Message ($script:localizedData.CallingFunction -f $($MyInvocation.MyCommand))\r\n\r\n    switch ($Type) {\r\n        'SourceUri' {\r\n            # Checks whether given URI represents specific scheme\r\n            # Most common schemes: file, http, https, ftp\r\n            $scheme = @('http', 'https', 'file', 'ftp')\r\n\r\n            $newUri = $Value -as [System.URI]\r\n            $returnValue = ($newUri -and $newUri.AbsoluteURI -and ($scheme -icontains $newUri.Scheme))\r\n\r\n            if ($returnValue -eq $false) {\r\n                $errorMessage = $script:localizedData.InValidUri -f $Value\r\n                New-InvalidArgumentException -ArgumentName $Type -Message $errorMessage\r\n            }\r\n        }\r\n\r\n        'DestinationPath' {\r\n            $returnValue = Test-Path -Path $Value\r\n\r\n            if ($returnValue -eq $false) {\r\n                $errorMessage = $script:localizedData.PathDoesNotExist -f $Value\r\n                New-InvalidArgumentException -ArgumentName $Type -Message $errorMessage\r\n            }\r\n        }\r\n\r\n        'PackageSource' {\r\n            # Value can be either the package source Name or source Uri.\r\n\r\n            # Check if the source is a Uri.\r\n            $uri = $Value -as [System.URI]\r\n\r\n            if ($uri -and $uri.AbsoluteURI) {\r\n                # Check if it's a valid Uri.\r\n                Test-ParameterValue -Value $Value -Type 'SourceUri' -ProviderName $ProviderName\r\n            }\r\n            else {\r\n                # Check if it's a registered package source name.\r\n                $source = PackageManagement\\Get-PackageSource -Name $Value -ProviderName $ProviderName -ErrorVariable ev\r\n\r\n                if ((-not $source) -or $ev) {\r\n                    # We do not need to throw error here as Get-PackageSource does already.\r\n                    Write-Verbose -Message ($script:localizedData.SourceNotFound -f $source)\r\n                }\r\n            }\r\n        }\r\n\r\n        default {\r\n            $errorMessage = $script:localizedData.UnexpectedArgument -f $Type\r\n            New-InvalidArgumentException -ArgumentName $Type -Message $errorMessage\r\n        }\r\n    }\r\n}\r\n\r\n<#\r\n    .SYNOPSIS\r\n        This is a helper function that does the version validation.\r\n\r\n    .PARAMETER RequiredVersion\r\n        Provides the required version.\r\n\r\n    .PARAMETER MaximumVersion\r\n        Provides the maximum version.\r\n\r\n    .PARAMETER MinimumVersion\r\n        Provides the minimum version.\r\n#>\r\nfunction Test-VersionParameter {\r\n    [CmdletBinding()]\r\n    param\r\n    (\r\n        [Parameter()]\r\n        [System.String]\r\n        $RequiredVersion,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $MinimumVersion,\r\n\r\n        [Parameter()]\r\n        [System.String]\r\n        $MaximumVersion\r\n    )\r\n\r\n    Write-Verbose -Message ($localizedData.CallingFunction -f $($MyInvocation.MyCommand))\r\n\r\n    $isValid = $false\r\n\r\n    # Case 1: No further check required if a user provides either none or one of these: minimumVersion, maximumVersion, and requiredVersion.\r\n    if ($PSBoundParameters.Count -le 1) {\r\n        return $true\r\n    }\r\n\r\n    # Case 2: #If no RequiredVersion is provided.\r\n    if (-not $PSBoundParameters.ContainsKey('RequiredVersion')) {\r\n        # If no RequiredVersion, both MinimumVersion and MaximumVersion are provided. Otherwise fall into the Case #1.\r\n        $isValid = $PSBoundParameters['MinimumVersion'] -le $PSBoundParameters['MaximumVersion']\r\n    }\r\n\r\n    # Case 3: RequiredVersion is provided.\r\n    #        In this case  MinimumVersion and/or MaximumVersion also are provided. Otherwise fall in to Case #1.\r\n    #        This is an invalid case. When RequiredVersion is provided, others are not allowed. so $isValid is false, which is already set in the init.\r\n\r\n    if ($isValid -eq $false) {\r\n        $errorMessage = $script:localizedData.VersionError\r\n        New-InvalidArgumentException `\r\n            -ArgumentName 'RequiredVersion, MinimumVersion or MaximumVersion' `\r\n            -Message $errorMessage\r\n    }\r\n}\r\n\r\n<#\r\n    .SYNOPSIS\r\n        This is a helper function that retrieves the InstallationPolicy from the given repository.\r\n\r\n    .PARAMETER RepositoryName\r\n        Provides the repository Name.\r\n#>\r\nfunction Get-InstallationPolicy {\r\n    [CmdletBinding()]\r\n    param\r\n    (\r\n        [Parameter(Mandatory = $true)]\r\n        [ValidateNotNullOrEmpty()]\r\n        [System.String] $RepositoryName\r\n    )\r\n\r\n    Write-Verbose -Message ($LocalizedData.CallingFunction -f $($MyInvocation.MyCommand))\r\n\r\n    $repositoryObject = PackageManagement\\Get-PackageSource -Name $RepositoryName -ErrorAction SilentlyContinue -WarningAction SilentlyContinue\r\n\r\n    if ($repositoryObject) {\r\n        return $repositoryObject.IsTrusted\r\n    }\r\n}\r\n\r\n<#\r\n    .SYNOPSIS\r\n        This method is used to compare current and desired values for any DSC resource.\r\n\r\n    .PARAMETER CurrentValues\r\n        This is hash table of the current values that are applied to the resource.\r\n\r\n    .PARAMETER DesiredValues\r\n        This is a PSBoundParametersDictionary of the desired values for the resource.\r\n\r\n    .PARAMETER ValuesToCheck\r\n        This is a list of which properties in the desired values list should be checked.\r\n        If this is empty then all values in DesiredValues are checked.\r\n#>\r\nfunction Test-DscParameterState {\r\n    [CmdletBinding()]\r\n    param\r\n    (\r\n        [Parameter(Mandatory = $true)]\r\n        [System.Collections.Hashtable]\r\n        $CurrentValues,\r\n\r\n        [Parameter(Mandatory = $true)]\r\n        [System.Object]\r\n        $DesiredValues,\r\n\r\n        [Parameter()]\r\n        [System.Array]\r\n        $ValuesToCheck\r\n    )\r\n\r\n    $returnValue = $true\r\n\r\n    if (($DesiredValues.GetType().Name -ne 'HashTable') `\r\n            -and ($DesiredValues.GetType().Name -ne 'CimInstance') `\r\n            -and ($DesiredValues.GetType().Name -ne 'PSBoundParametersDictionary')) {\r\n        $errorMessage = $script:localizedData.PropertyTypeInvalidForDesiredValues -f $($DesiredValues.GetType().Name)\r\n        New-InvalidArgumentException -ArgumentName 'DesiredValues' -Message $errorMessage\r\n    }\r\n\r\n    if (($DesiredValues.GetType().Name -eq 'CimInstance') -and ($null -eq $ValuesToCheck)) {\r\n        $errorMessage = $script:localizedData.PropertyTypeInvalidForValuesToCheck\r\n        New-InvalidArgumentException -ArgumentName 'ValuesToCheck' -Message $errorMessage\r\n    }\r\n\r\n    if (($null -eq $ValuesToCheck) -or ($ValuesToCheck.Count -lt 1)) {\r\n        $keyList = $DesiredValues.Keys\r\n    }\r\n    else {\r\n        $keyList = $ValuesToCheck\r\n    }\r\n\r\n    $keyList | ForEach-Object -Process {\r\n        if (($_ -ne 'Verbose')) {\r\n            if (($CurrentValues.ContainsKey($_) -eq $false) `\r\n                    -or ($CurrentValues.$_ -ne $DesiredValues.$_) `\r\n                    -or (($DesiredValues.GetType().Name -ne 'CimInstance' -and $DesiredValues.ContainsKey($_) -eq $true) -and ($null -ne $DesiredValues.$_ -and $DesiredValues.$_.GetType().IsArray))) {\r\n                if ($DesiredValues.GetType().Name -eq 'HashTable' -or `\r\n                        $DesiredValues.GetType().Name -eq 'PSBoundParametersDictionary') {\r\n                    $checkDesiredValue = $DesiredValues.ContainsKey($_)\r\n                }\r\n                else {\r\n                    # If DesiredValue is a CimInstance.\r\n                    $checkDesiredValue = $false\r\n                    if (([System.Boolean]($DesiredValues.PSObject.Properties.Name -contains $_)) -eq $true) {\r\n                        if ($null -ne $DesiredValues.$_) {\r\n                            $checkDesiredValue = $true\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if ($checkDesiredValue) {\r\n                    $desiredType = $DesiredValues.$_.GetType()\r\n                    $fieldName = $_\r\n                    if ($desiredType.IsArray -eq $true) {\r\n                        if (($CurrentValues.ContainsKey($fieldName) -eq $false) `\r\n                                -or ($null -eq $CurrentValues.$fieldName)) {\r\n                            Write-Verbose -Message ($script:localizedData.PropertyValidationError -f $fieldName) -Verbose\r\n\r\n                            $returnValue = $false\r\n                        }\r\n                        else {\r\n                            $arrayCompare = Compare-Object -ReferenceObject $CurrentValues.$fieldName `\r\n                                -DifferenceObject $DesiredValues.$fieldName\r\n                            if ($null -ne $arrayCompare) {\r\n                                Write-Verbose -Message ($script:localizedData.PropertiesDoesNotMatch -f $fieldName) -Verbose\r\n\r\n                                $arrayCompare | ForEach-Object -Process {\r\n                                    Write-Verbose -Message ($script:localizedData.PropertyThatDoesNotMatch -f $_.InputObject, $_.SideIndicator) -Verbose\r\n                                }\r\n\r\n                                $returnValue = $false\r\n                            }\r\n                        }\r\n                    }\r\n                    else {\r\n                        switch ($desiredType.Name) {\r\n                            'String' {\r\n                                if (-not [System.String]::IsNullOrEmpty($CurrentValues.$fieldName) -or `\r\n                                        -not [System.String]::IsNullOrEmpty($DesiredValues.$fieldName)) {\r\n                                    Write-Verbose -Message ($script:localizedData.ValueOfTypeDoesNotMatch `\r\n                                            -f $desiredType.Name, $fieldName, $($CurrentValues.$fieldName), $($DesiredValues.$fieldName)) -Verbose\r\n\r\n                                    $returnValue = $false\r\n                                }\r\n                            }\r\n\r\n                            'Int32' {\r\n                                if (-not ($DesiredValues.$fieldName -eq 0) -or `\r\n                                        -not ($null -eq $CurrentValues.$fieldName)) {\r\n                                    Write-Verbose -Message ($script:localizedData.ValueOfTypeDoesNotMatch `\r\n                                            -f $desiredType.Name, $fieldName, $($CurrentValues.$fieldName), $($DesiredValues.$fieldName)) -Verbose\r\n\r\n                                    $returnValue = $false\r\n                                }\r\n                            }\r\n\r\n                            { $_ -eq 'Int16' -or $_ -eq 'UInt16'} {\r\n                                if (-not ($DesiredValues.$fieldName -eq 0) -or `\r\n                                        -not ($null -eq $CurrentValues.$fieldName)) {\r\n                                    Write-Verbose -Message ($script:localizedData.ValueOfTypeDoesNotMatch `\r\n                                            -f $desiredType.Name, $fieldName, $($CurrentValues.$fieldName), $($DesiredValues.$fieldName)) -Verbose\r\n\r\n                                    $returnValue = $false\r\n                                }\r\n                            }\r\n\r\n                            default {\r\n                                Write-Warning -Message ($script:localizedData.UnableToCompareProperty `\r\n                                        -f $fieldName, $desiredType.Name)\r\n\r\n                                $returnValue = $false\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    return $returnValue\r\n}\r\n\r\n# SIG # Begin signature block\r\n# MIIjkgYJKoZIhvcNAQcCoIIjgzCCI38CAQExDzANBglghkgBZQMEAgEFADB5Bgor\r\n# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG\r\n# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBH3QB1YDOZOOwJ\r\n# V+KQVBF6PeRCZ7EOOlwmL67tD15ypKCCDYEwggX/MIID56ADAgECAhMzAAABh3IX\r\n# chVZQMcJAAAAAAGHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD\r\n# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p\r\n# bmcgUENBIDIwMTEwHhcNMjAwMzA0MTgzOTQ3WhcNMjEwMzAzMTgzOTQ3WjB0MQsw\r\n# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u\r\n# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\r\n# AQDOt8kLc7P3T7MKIhouYHewMFmnq8Ayu7FOhZCQabVwBp2VS4WyB2Qe4TQBT8aB\r\n# znANDEPjHKNdPT8Xz5cNali6XHefS8i/WXtF0vSsP8NEv6mBHuA2p1fw2wB/F0dH\r\n# sJ3GfZ5c0sPJjklsiYqPw59xJ54kM91IOgiO2OUzjNAljPibjCWfH7UzQ1TPHc4d\r\n# weils8GEIrbBRb7IWwiObL12jWT4Yh71NQgvJ9Fn6+UhD9x2uk3dLj84vwt1NuFQ\r\n# itKJxIV0fVsRNR3abQVOLqpDugbr0SzNL6o8xzOHL5OXiGGwg6ekiXA1/2XXY7yV\r\n# Fc39tledDtZjSjNbex1zzwSXAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE\r\n# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUhov4ZyO96axkJdMjpzu2zVXOJcsw\r\n# UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1\r\n# ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDU4Mzg1MB8GA1UdIwQYMBaAFEhu\r\n# ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu\r\n# bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w\r\n# Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3\r\n# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx\r\n# MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAixmy\r\n# S6E6vprWD9KFNIB9G5zyMuIjZAOuUJ1EK/Vlg6Fb3ZHXjjUwATKIcXbFuFC6Wr4K\r\n# NrU4DY/sBVqmab5AC/je3bpUpjtxpEyqUqtPc30wEg/rO9vmKmqKoLPT37svc2NV\r\n# BmGNl+85qO4fV/w7Cx7J0Bbqk19KcRNdjt6eKoTnTPHBHlVHQIHZpMxacbFOAkJr\r\n# qAVkYZdz7ikNXTxV+GRb36tC4ByMNxE2DF7vFdvaiZP0CVZ5ByJ2gAhXMdK9+usx\r\n# zVk913qKde1OAuWdv+rndqkAIm8fUlRnr4saSCg7cIbUwCCf116wUJ7EuJDg0vHe\r\n# yhnCeHnBbyH3RZkHEi2ofmfgnFISJZDdMAeVZGVOh20Jp50XBzqokpPzeZ6zc1/g\r\n# yILNyiVgE+RPkjnUQshd1f1PMgn3tns2Cz7bJiVUaqEO3n9qRFgy5JuLae6UweGf\r\n# AeOo3dgLZxikKzYs3hDMaEtJq8IP71cX7QXe6lnMmXU/Hdfz2p897Zd+kU+vZvKI\r\n# 3cwLfuVQgK2RZ2z+Kc3K3dRPz2rXycK5XCuRZmvGab/WbrZiC7wJQapgBodltMI5\r\n# GMdFrBg9IeF7/rP4EqVQXeKtevTlZXjpuNhhjuR+2DMt/dWufjXpiW91bo3aH6Ea\r\n# jOALXmoxgltCp1K7hrS6gmsvj94cLRf50QQ4U8Qwggd6MIIFYqADAgECAgphDpDS\r\n# AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK\r\n# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0\r\n# IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0\r\n# ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla\r\n# MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS\r\n# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT\r\n# H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB\r\n# AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG\r\n# OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S\r\n# 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz\r\n# y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7\r\n# 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u\r\n# M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33\r\n# X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl\r\n# XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP\r\n# 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB\r\n# l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF\r\n# RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM\r\n# CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ\r\n# BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud\r\n# DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO\r\n# 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0\r\n# LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p\r\n# Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB\r\n# FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw\r\n# cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA\r\n# XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY\r\n# 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj\r\n# 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd\r\n# d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ\r\n# Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf\r\n# wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ\r\n# aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j\r\n# NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B\r\n# xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96\r\n# eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7\r\n# r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I\r\n# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVZzCCFWMCAQEwgZUwfjELMAkG\r\n# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx\r\n# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z\r\n# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAYdyF3IVWUDHCQAAAAABhzAN\r\n# BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor\r\n# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgAchP/Cco\r\n# Y2JAjut9Hy3IC65/Rf67ea66bxFJosTcn0EwQgYKKwYBBAGCNwIBDDE0MDKgFIAS\r\n# AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN\r\n# BgkqhkiG9w0BAQEFAASCAQCA7tKfqWfEy22S/6wr4OyvRkvECIOlgOTLpZGyP7iT\r\n# 16UqNis22r/tHfj0nQMVembrz5WOUvHZPrU72+fJAZqMdCB5H0wHmeBOmie166xn\r\n# CDvlSHtJr5sPZeRDNQFeJN2nN+I47eFwThr5ndx6Gp548DoyDWBnFQz2tgvVpIWA\r\n# TBFrWf8ZulTYcMH3QhzlgEmmgEsU2vT5nbBmmK2QICDzcWA3tIzHSQ7jQxqL+9Oj\r\n# 9EVvuJTf0e81f05xNUmunrwWuoHzIYOF7LmpZqWFp4m8rg5Davtum5Rq60TcofSH\r\n# gKzh10SD1+hAHm7/aqz640BMXsMJCBHofYDzXY0Un7sWoYIS8TCCEu0GCisGAQQB\r\n# gjcDAwExghLdMIIS2QYJKoZIhvcNAQcCoIISyjCCEsYCAQMxDzANBglghkgBZQME\r\n# AgEFADCCAVUGCyqGSIb3DQEJEAEEoIIBRASCAUAwggE8AgEBBgorBgEEAYRZCgMB\r\n# MDEwDQYJYIZIAWUDBAIBBQAEIJeyBGsDoIyvzKdclhGjO92lMFh4eXEiupSWXMgA\r\n# yrYhAgZfYQdYOoMYEzIwMjAwOTIyMjIxOTUwLjk4M1owBIACAfSggdSkgdEwgc4x\r\n# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt\r\n# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1p\r\n# Y3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMg\r\n# VFNTIEVTTjpGODdBLUUzNzQtRDdCOTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt\r\n# U3RhbXAgU2VydmljZaCCDkQwggT1MIID3aADAgECAhMzAAABL7GnF3lWlBeHAAAA\r\n# AAEvMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo\r\n# aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y\r\n# cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw\r\n# MB4XDTE5MTIxOTAxMTUwNloXDTIxMDMxNzAxMTUwNlowgc4xCzAJBgNVBAYTAlVT\r\n# MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK\r\n# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVy\r\n# YXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjpGODdB\r\n# LUUzNzQtRDdCOTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vydmlj\r\n# ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKh8VkvVIwXD8sn0zT2n\r\n# EdyEZ9UNHY7ACbOZA4obAHvD1hauw9K1Z2lRWG+m8Ars9l35GoMXdPgshM3hZKQW\r\n# fhrLnF9/GDZoilhc2LhMqNPXs06rAJ8YODB6i0Cg1CFCYnyOYvywXKY3xGJN09Dg\r\n# PXWfczEm2P/a3rmrXMrK5EFc3ahxrC51c+UuAMKV9xJyzJVLShPwPBJl+CjdMDPJ\r\n# f24DZXIYec3gCN2xean1DFCI0gaqJprMeL4Om1KY2AZMIgBPEkoY1N7AI5e7ybkI\r\n# L8+Mz3inijb4rDTkXk86ztUwy4bdc1MyKe2j2odT+QIDA2+M8cMTIGlKn7EyD2NN\r\n# XU8CAwEAAaOCARswggEXMB0GA1UdDgQWBBSml/VRpBNFkAMDiqcoqWi85j/qljAf\r\n# BgNVHSMEGDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8ETzBNMEugSaBH\r\n# hkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNU\r\n# aW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUF\r\n# BzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1RpbVN0\r\n# YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsG\r\n# AQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IBAQB4q6ilv2SlGvJD/7dbfoIKZBO2i6YA\r\n# wckw57TpCrt2+SAx2dcF7JvRMCPhLCSgqjyNcJRs40cEXPbLdzZMJHzcv73AF7L6\r\n# mWZXg2aBjG1Sc5qM4jjE/nwIX+C6/odm5/asU4JIlFCuUZjzqdir18HkRVQve2Hw\r\n# V0lCXHQs+V3m9DyyA9b6LSIk3GOFZu7F11Wyx/5dVXisPPTPwh9JXfMD9W173M1+\r\n# ZZycmO03lUc4G1FilgpxWNdgWn/DO9ZhoW5yN6+BUddnJ4cCcCjcg8sB5rktPP8p\r\n# VZAQ7aUqkAeqo+FuCkAUAdJRESCpR5wgSPtVvFPMjONE36DbKtfzkfiHMIIGcTCC\r\n# BFmgAwIBAgIKYQmBKgAAAAAAAjANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMC\r\n# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV\r\n# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJv\r\n# b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMTAwNzAxMjEzNjU1WhcN\r\n# MjUwNzAxMjE0NjU1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv\r\n# bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0\r\n# aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCASIw\r\n# DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkdDbx3EYo6IOz8E5f1+n9plGt0\r\n# VBDVpQoAgoX77XxoSyxfxcPlYcJ2tz5mK1vwFVMnBDEfQRsalR3OCROOfGEwWbEw\r\n# RA/xYIiEVEMM1024OAizQt2TrNZzMFcmgqNFDdDq9UeBzb8kYDJYYEbyWEeGMoQe\r\n# dGFnkV+BVLHPk0ySwcSmXdFhE24oxhr5hoC732H8RsEnHSRnEnIaIYqvS2SJUGKx\r\n# Xf13Hz3wV3WsvYpCTUBR0Q+cBj5nf/VmwAOWRH7v0Ev9buWayrGo8noqCjHw2k4G\r\n# kbaICDXoeByw6ZnNPOcvRLqn9NxkvaQBwSAJk3jN/LzAyURdXhacAQVPIk0CAwEA\r\n# AaOCAeYwggHiMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBTVYzpcijGQ80N7\r\n# fEYbxTNoWoVtVTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMC\r\n# AYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvX\r\n# zpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20v\r\n# cGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYI\r\n# KwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5j\r\n# b20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDCBoAYDVR0g\r\n# AQH/BIGVMIGSMIGPBgkrBgEEAYI3LgMwgYEwPQYIKwYBBQUHAgEWMWh0dHA6Ly93\r\n# d3cubWljcm9zb2Z0LmNvbS9QS0kvZG9jcy9DUFMvZGVmYXVsdC5odG0wQAYIKwYB\r\n# BQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AUABvAGwAaQBjAHkAXwBTAHQAYQB0AGUA\r\n# bQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAAfmiFEN4sbgmD+BcQM9naOh\r\n# IW+z66bM9TG+zwXiqf76V20ZMLPCxWbJat/15/B4vceoniXj+bzta1RXCCtRgkQS\r\n# +7lTjMz0YBKKdsxAQEGb3FwX/1z5Xhc1mCRWS3TvQhDIr79/xn/yN31aPxzymXlK\r\n# kVIArzgPF/UveYFl2am1a+THzvbKegBvSzBEJCI8z+0DpZaPWSm8tv0E4XCfMkon\r\n# /VWvL/625Y4zu2JfmttXQOnxzplmkIz/amJ/3cVKC5Em4jnsGUpxY517IW3DnKOi\r\n# PPp/fZZqkHimbdLhnPkd/DjYlPTGpQqWhqS9nhquBEKDuLWAmyI4ILUl5WTs9/S/\r\n# fmNZJQ96LjlXdqJxqgaKD4kWumGnEcua2A5HmoDF0M2n0O99g/DhO3EJ3110mCII\r\n# YdqwUB5vvfHhAN/nMQekkzr3ZUd46PioSKv33nJ+YWtvd6mBy6cJrDm77MbL2IK0\r\n# cs0d9LiFAR6A+xuJKlQ5slvayA1VmXqHczsI5pgt6o3gMy4SKfXAL1QnIffIrE7a\r\n# KLixqduWsqdCosnPGUFN4Ib5KpqjEWYw07t0MkvfY3v1mYovG8chr1m1rtxEPJdQ\r\n# cdeh0sVV42neV8HR3jDA/czmTfsNv11P6Z0eGTgvvM9YBS7vDaBQNdrvCScc1bN+\r\n# NR4Iuto229Nfj950iEkSoYIC0jCCAjsCAQEwgfyhgdSkgdEwgc4xCzAJBgNVBAYT\r\n# AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD\r\n# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBP\r\n# cGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjpG\r\n# ODdBLUUzNzQtRDdCOTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy\r\n# dmljZaIjCgEBMAcGBSsOAwIaAxUAM/CZCUpclQ9qfr/r3y9osIIPSmSggYMwgYCk\r\n# fjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH\r\n# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD\r\n# Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIF\r\n# AOMUwAMwIhgPMjAyMDA5MjIyMjI1MDdaGA8yMDIwMDkyMzIyMjUwN1owdzA9Bgor\r\n# BgEEAYRZCgQBMS8wLTAKAgUA4xTAAwIBADAKAgEAAgIeewIB/zAHAgEAAgIQ0jAK\r\n# AgUA4xYRgwIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIB\r\n# AAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAB7Ib0ORN4cnD/0V\r\n# iEDrzl7vxjx6981A8Z/8I+X0n7qQHdeGFJcXGEEO5pDD62VMfd28ZrxPWgMd0Chx\r\n# mj5EdvR3U6+gRYzyYY5Vi5srADcWf3pMoYsEQhZuYeohtFQuYFJt2t26GskSlEy3\r\n# qXFkFqIoBCjz1SsmfA5nTtE2zXHSMYIDDTCCAwkCAQEwgZMwfDELMAkGA1UEBhMC\r\n# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV\r\n# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRp\r\n# bWUtU3RhbXAgUENBIDIwMTACEzMAAAEvsacXeVaUF4cAAAAAAS8wDQYJYIZIAWUD\r\n# BAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0B\r\n# CQQxIgQgDY7vkk/uubZSKGprOnZ2WnFZqhRkEJ7KVJ5R6hogo/AwgfoGCyqGSIb3\r\n# DQEJEAIvMYHqMIHnMIHkMIG9BCBC5RecGZvugnvVXg80zlrGv1uV35LNk+H9dBj3\r\n# ChFPvTCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u\r\n# MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp\r\n# b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB\r\n# L7GnF3lWlBeHAAAAAAEvMCIEIAt7o8jjQ4zf04GvFGrnuSSwfsToGMPMzYw+3a3k\r\n# vP0dMA0GCSqGSIb3DQEBCwUABIIBABIE9hcJhxcSYL9zQrK7AunfYI2qZBNrD9dB\r\n# FIYwBnLNOYAPgpjC5Nxrp/4fSrWPyWFkXzwB6rjofda3zWpOywWKMc4lK0yHRYrO\r\n# 7r0FmXd9zxdaJKpbHpc8xG2vb6pI9dh/eXFGNS8KRu+oKZFX2/l5IxRAz4QRMxq6\r\n# /heHcZpWjeIknMhP+bMAqaMV9h3jEojCli0hdwawbTpq8Oyvo6wlwNqLvmtBc7Xs\r\n# 8of9f6I/zTCn6yhbyDEVXxPhn3qjrQzi790XXe3xvmAKkkEW/NO2ZOS/2EpfjFms\r\n# wYhh6tKYg2k2j6mfCGmwvx2cx32zR/m4/ieGClCeKPiRlPvgip0=\r\n# SIG # End signature block\r\n"
  },
  {
    "path": "src/PowerShell/ExternalModules/PowerShellGet/2.2.5/Modules/PowerShellGet.ResourceHelper/en-US/PowerShellGet.ResourceHelper.strings.psd1",
    "content": "#\r\n# Copyright (c) Microsoft Corporation.\r\n#\r\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n# THE SOFTWARE.\r\n#\r\n# culture = \"en-US\"\r\nConvertFrom-StringData -StringData @'\r\n###PSLOC\r\n    InValidUri         = InValid Uri: '{0}'. A sample valid uri: https://www.powershellgallery.com/api/v2/.\r\n    PathDoesNotExist   = Path: '{0}' does not exist.\r\n    VersionError       = MinimumVersion should be less than the MaximumVersion. The MinimumVersion or MaximumVersion cannot be used with the RequiredVersion in the same command.\r\n    UnexpectedArgument = Unexpected argument type: '{0}'.\r\n    SourceNotFound     = Source '{0}' not found. Please make sure you register it.\r\n    CallingFunction    = Calling function '{0}'.\r\n    PropertyTypeInvalidForDesiredValues = Property 'DesiredValues' must be either a [System.Collections.Hashtable], [CimInstance] or [PSBoundParametersDictionary]. The type detected was {0}.\r\n    PropertyTypeInvalidForValuesToCheck = If 'DesiredValues' is a CimInstance, then property 'ValuesToCheck' must contain a value.\r\n    PropertyValidationError = Expected to find an array value for property {0} in the current values, but it was either not present or was null. This has caused the test method to return false.\r\n    PropertiesDoesNotMatch = Found an array for property {0} in the current values, but this array does not match the desired state. Details of the changes are below.\r\n    PropertyThatDoesNotMatch = {0} - {1}\r\n    ValueOfTypeDoesNotMatch = {0} value for property {1} does not match. Current state is '{2}' and desired state is '{3}'.\r\n    UnableToCompareProperty = Unable to compare property {0} as the type {1} is not handled by the Test-SQLDSCParameterState cmdlet.\r\n###PSLOC\r\n'@\r\n\r\n# SIG # Begin signature block\r\n# MIIjkgYJKoZIhvcNAQcCoIIjgzCCI38CAQExDzANBglghkgBZQMEAgEFADB5Bgor\r\n# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG\r\n# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBIoCdfhdi5Cjss\r\n# ngqx6qsfpPMDALYWOvgm/jaEU9DaSKCCDYEwggX/MIID56ADAgECAhMzAAABh3IX\r\n# chVZQMcJAAAAAAGHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD\r\n# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p\r\n# bmcgUENBIDIwMTEwHhcNMjAwMzA0MTgzOTQ3WhcNMjEwMzAzMTgzOTQ3WjB0MQsw\r\n# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u\r\n# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\r\n# AQDOt8kLc7P3T7MKIhouYHewMFmnq8Ayu7FOhZCQabVwBp2VS4WyB2Qe4TQBT8aB\r\n# znANDEPjHKNdPT8Xz5cNali6XHefS8i/WXtF0vSsP8NEv6mBHuA2p1fw2wB/F0dH\r\n# sJ3GfZ5c0sPJjklsiYqPw59xJ54kM91IOgiO2OUzjNAljPibjCWfH7UzQ1TPHc4d\r\n# weils8GEIrbBRb7IWwiObL12jWT4Yh71NQgvJ9Fn6+UhD9x2uk3dLj84vwt1NuFQ\r\n# itKJxIV0fVsRNR3abQVOLqpDugbr0SzNL6o8xzOHL5OXiGGwg6ekiXA1/2XXY7yV\r\n# Fc39tledDtZjSjNbex1zzwSXAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE\r\n# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUhov4ZyO96axkJdMjpzu2zVXOJcsw\r\n# UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1\r\n# ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDU4Mzg1MB8GA1UdIwQYMBaAFEhu\r\n# ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu\r\n# bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w\r\n# Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3\r\n# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx\r\n# MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAixmy\r\n# S6E6vprWD9KFNIB9G5zyMuIjZAOuUJ1EK/Vlg6Fb3ZHXjjUwATKIcXbFuFC6Wr4K\r\n# NrU4DY/sBVqmab5AC/je3bpUpjtxpEyqUqtPc30wEg/rO9vmKmqKoLPT37svc2NV\r\n# BmGNl+85qO4fV/w7Cx7J0Bbqk19KcRNdjt6eKoTnTPHBHlVHQIHZpMxacbFOAkJr\r\n# qAVkYZdz7ikNXTxV+GRb36tC4ByMNxE2DF7vFdvaiZP0CVZ5ByJ2gAhXMdK9+usx\r\n# zVk913qKde1OAuWdv+rndqkAIm8fUlRnr4saSCg7cIbUwCCf116wUJ7EuJDg0vHe\r\n# yhnCeHnBbyH3RZkHEi2ofmfgnFISJZDdMAeVZGVOh20Jp50XBzqokpPzeZ6zc1/g\r\n# yILNyiVgE+RPkjnUQshd1f1PMgn3tns2Cz7bJiVUaqEO3n9qRFgy5JuLae6UweGf\r\n# AeOo3dgLZxikKzYs3hDMaEtJq8IP71cX7QXe6lnMmXU/Hdfz2p897Zd+kU+vZvKI\r\n# 3cwLfuVQgK2RZ2z+Kc3K3dRPz2rXycK5XCuRZmvGab/WbrZiC7wJQapgBodltMI5\r\n# GMdFrBg9IeF7/rP4EqVQXeKtevTlZXjpuNhhjuR+2DMt/dWufjXpiW91bo3aH6Ea\r\n# jOALXmoxgltCp1K7hrS6gmsvj94cLRf50QQ4U8Qwggd6MIIFYqADAgECAgphDpDS\r\n# AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK\r\n# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0\r\n# IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0\r\n# ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla\r\n# MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS\r\n# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT\r\n# H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB\r\n# AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG\r\n# OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S\r\n# 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz\r\n# y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7\r\n# 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u\r\n# M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33\r\n# X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl\r\n# XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP\r\n# 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB\r\n# l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF\r\n# RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM\r\n# CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ\r\n# BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud\r\n# DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO\r\n# 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0\r\n# LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p\r\n# Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB\r\n# FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw\r\n# cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA\r\n# XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY\r\n# 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj\r\n# 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd\r\n# d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ\r\n# Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf\r\n# wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ\r\n# aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j\r\n# NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B\r\n# xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96\r\n# eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7\r\n# r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I\r\n# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVZzCCFWMCAQEwgZUwfjELMAkG\r\n# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx\r\n# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z\r\n# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAYdyF3IVWUDHCQAAAAABhzAN\r\n# BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor\r\n# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgRtNNlbVF\r\n# dlkMIAy8Jt0BeSlkgxnR3ktF5+8UaxbiK1gwQgYKKwYBBAGCNwIBDDE0MDKgFIAS\r\n# AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN\r\n# BgkqhkiG9w0BAQEFAASCAQBikiCJbAZhOZ7PLbYTjUnSEz9oaiBq80NUlYUDz8p+\r\n# uGQfC0LU5aqPrFJ2lwmhVkhLmfAaP3OseRq1JdSHe3xxBndAN9Oh2HTlXm47fL5H\r\n# zJmnEdFq5YaXoWBoUn1O7sE4zMWU+JQm3I9YtgHVSgGzxX9ao/BjFW2s3wtfcXmp\r\n# 3zhN+cbAfBY/8u6J4Zui1mYzlMplYSwb66ikLo6kkSs3OnKN9frtB0McoazPtOxn\r\n# M4bae/0xVVJyt7vT3Vru3bDBIFOmEHnYPAhdz+QDxS8wLXCnKNWgMizg3s/iFVDO\r\n# G1VtPErpnu9oraXqkmHOMy8naFl85xuR/hhRpkiooEfKoYIS8TCCEu0GCisGAQQB\r\n# gjcDAwExghLdMIIS2QYJKoZIhvcNAQcCoIISyjCCEsYCAQMxDzANBglghkgBZQME\r\n# AgEFADCCAVUGCyqGSIb3DQEJEAEEoIIBRASCAUAwggE8AgEBBgorBgEEAYRZCgMB\r\n# MDEwDQYJYIZIAWUDBAIBBQAEIMtX3JJD1gPDRiGuV8rCirgOBq8Lt6eGHeZdjPKC\r\n# pH3qAgZfYRqWlCoYEzIwMjAwOTIyMjIxOTUyLjU2NlowBIACAfSggdSkgdEwgc4x\r\n# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt\r\n# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1p\r\n# Y3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMg\r\n# VFNTIEVTTjo0NjJGLUUzMTktM0YyMDElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt\r\n# U3RhbXAgU2VydmljZaCCDkQwggT1MIID3aADAgECAhMzAAABJMvNAqEXcFyaAAAA\r\n# AAEkMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo\r\n# aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y\r\n# cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw\r\n# MB4XDTE5MTIxOTAxMTQ1N1oXDTIxMDMxNzAxMTQ1N1owgc4xCzAJBgNVBAYTAlVT\r\n# MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK\r\n# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVy\r\n# YXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo0NjJG\r\n# LUUzMTktM0YyMDElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vydmlj\r\n# ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJCbKjgNnhjvMlnRNAtx\r\n# 7X3N5ZZkSfUFULyWsVJ1pnyMsSITimg1q3OQ1Ikf0/3gg8UG5TIRm7wH8sjBtoB3\r\n# nuzFz11CegIFcanYnt050JvnrUTKeAPUR5pLpTeP3QEgL+CWOc4lTg/XxjnQv01F\r\n# D7TTn9DEuO3kp0GQ87Mjd5ssxK0K1q4IWNFAyRpx5n8Vm3Vm1iiVL5FMDUKsl5G/\r\n# SqQdiEDn8cqYbqWMVzWH94PdKdw1mIHToBRCNsR9BHHWzNkSS+R0WRipBSSorKT7\r\n# cuLlEBYhDo8AY3uMGlv0kLRLHASZ+sz2nfkpW2CVt+bHhVmM6/5qiu2f7eYoTYJu\r\n# cFECAwEAAaOCARswggEXMB0GA1UdDgQWBBS7HdFyrGKIhDxvypLA1lD/wGRSsDAf\r\n# BgNVHSMEGDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8ETzBNMEugSaBH\r\n# hkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNU\r\n# aW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUF\r\n# BzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1RpbVN0\r\n# YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsG\r\n# AQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IBAQBo3QzNuNRgzdflwA4U7f3e2CcGlwdg\r\n# 6ii498cBiSrTpWKO3qqz5pvgHAk4hh6y/FLY80R59inLwcVuyD24S3JEdSie4y1t\r\n# C5JptweR1qlxRJCRM4vG7nPtIC4eAMKcXgovu0mTFv7xpFAVpRuvuepR91gIde32\r\n# 8lv1HTTJCV/LBBk83Xi7nCGPF59FxeIrcE32xt4YJgEpEAikeMqvWCTMyPqlmvx9\r\n# J92fxU3cQcw2j2EWwqOD5T3Nz2HWfPV80sihD1A6Y5HhjpS9taDPs7CI58I211F3\r\n# ysegNyOesG3MTrSJHyPMLKYFDxcG1neV0liktv+TW927sUOVczcSUhQLMIIGcTCC\r\n# BFmgAwIBAgIKYQmBKgAAAAAAAjANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMC\r\n# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV\r\n# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJv\r\n# b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMTAwNzAxMjEzNjU1WhcN\r\n# MjUwNzAxMjE0NjU1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv\r\n# bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0\r\n# aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCASIw\r\n# DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkdDbx3EYo6IOz8E5f1+n9plGt0\r\n# VBDVpQoAgoX77XxoSyxfxcPlYcJ2tz5mK1vwFVMnBDEfQRsalR3OCROOfGEwWbEw\r\n# RA/xYIiEVEMM1024OAizQt2TrNZzMFcmgqNFDdDq9UeBzb8kYDJYYEbyWEeGMoQe\r\n# dGFnkV+BVLHPk0ySwcSmXdFhE24oxhr5hoC732H8RsEnHSRnEnIaIYqvS2SJUGKx\r\n# Xf13Hz3wV3WsvYpCTUBR0Q+cBj5nf/VmwAOWRH7v0Ev9buWayrGo8noqCjHw2k4G\r\n# kbaICDXoeByw6ZnNPOcvRLqn9NxkvaQBwSAJk3jN/LzAyURdXhacAQVPIk0CAwEA\r\n# AaOCAeYwggHiMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBTVYzpcijGQ80N7\r\n# fEYbxTNoWoVtVTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMC\r\n# AYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvX\r\n# zpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20v\r\n# cGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYI\r\n# KwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5j\r\n# b20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDCBoAYDVR0g\r\n# AQH/BIGVMIGSMIGPBgkrBgEEAYI3LgMwgYEwPQYIKwYBBQUHAgEWMWh0dHA6Ly93\r\n# d3cubWljcm9zb2Z0LmNvbS9QS0kvZG9jcy9DUFMvZGVmYXVsdC5odG0wQAYIKwYB\r\n# BQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AUABvAGwAaQBjAHkAXwBTAHQAYQB0AGUA\r\n# bQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAAfmiFEN4sbgmD+BcQM9naOh\r\n# IW+z66bM9TG+zwXiqf76V20ZMLPCxWbJat/15/B4vceoniXj+bzta1RXCCtRgkQS\r\n# +7lTjMz0YBKKdsxAQEGb3FwX/1z5Xhc1mCRWS3TvQhDIr79/xn/yN31aPxzymXlK\r\n# kVIArzgPF/UveYFl2am1a+THzvbKegBvSzBEJCI8z+0DpZaPWSm8tv0E4XCfMkon\r\n# /VWvL/625Y4zu2JfmttXQOnxzplmkIz/amJ/3cVKC5Em4jnsGUpxY517IW3DnKOi\r\n# PPp/fZZqkHimbdLhnPkd/DjYlPTGpQqWhqS9nhquBEKDuLWAmyI4ILUl5WTs9/S/\r\n# fmNZJQ96LjlXdqJxqgaKD4kWumGnEcua2A5HmoDF0M2n0O99g/DhO3EJ3110mCII\r\n# YdqwUB5vvfHhAN/nMQekkzr3ZUd46PioSKv33nJ+YWtvd6mBy6cJrDm77MbL2IK0\r\n# cs0d9LiFAR6A+xuJKlQ5slvayA1VmXqHczsI5pgt6o3gMy4SKfXAL1QnIffIrE7a\r\n# KLixqduWsqdCosnPGUFN4Ib5KpqjEWYw07t0MkvfY3v1mYovG8chr1m1rtxEPJdQ\r\n# cdeh0sVV42neV8HR3jDA/czmTfsNv11P6Z0eGTgvvM9YBS7vDaBQNdrvCScc1bN+\r\n# NR4Iuto229Nfj950iEkSoYIC0jCCAjsCAQEwgfyhgdSkgdEwgc4xCzAJBgNVBAYT\r\n# AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD\r\n# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBP\r\n# cGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo0\r\n# NjJGLUUzMTktM0YyMDElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy\r\n# dmljZaIjCgEBMAcGBSsOAwIaAxUAlwPlNCq+Un54UfxLe/wKS1Xc4nqggYMwgYCk\r\n# fjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH\r\n# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD\r\n# Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIF\r\n# AOMU004wIhgPMjAyMDA5MjIyMzQ3MjZaGA8yMDIwMDkyMzIzNDcyNlowdzA9Bgor\r\n# BgEEAYRZCgQBMS8wLTAKAgUA4xTTTgIBADAKAgEAAgIgZwIB/zAHAgEAAgIS3TAK\r\n# AgUA4xYkzgIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIB\r\n# AAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAJQEuwCens9exo3y\r\n# oRx0EpWssZYEoYGDA5Vo9cCDxGOjhqFjMJu/dmJcoeWqqCmHy66EAonaDmopQyNg\r\n# lRRfmDjEiQhc8am2i9RlvZac+vEFY6AP1GPEj+toN+LsaPXRU53/6LK/MR3BkTCm\r\n# iOD4gr6KZBDzEEjT2HA2pS7pSHevMYIDDTCCAwkCAQEwgZMwfDELMAkGA1UEBhMC\r\n# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV\r\n# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRp\r\n# bWUtU3RhbXAgUENBIDIwMTACEzMAAAEky80CoRdwXJoAAAAAASQwDQYJYIZIAWUD\r\n# BAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0B\r\n# CQQxIgQgjlF6gXuuf73GPP9MP86hJ0HAK3FFZWGekdUUKTNpWjkwgfoGCyqGSIb3\r\n# DQEJEAIvMYHqMIHnMIHkMIG9BCBiOOHoohqL+X7Xa/25jp1wTrQxYlYGLszis/nA\r\n# TirjIDCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u\r\n# MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp\r\n# b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB\r\n# JMvNAqEXcFyaAAAAAAEkMCIEINH5vtu0jUcUjiR+HX2ME9dlInYB6kXi3msE3oBJ\r\n# sB5sMA0GCSqGSIb3DQEBCwUABIIBABh16uxHs4RlKV2M0xneFNXFfIQNS8R1n2eb\r\n# YRGKKZ9fTl1xaJvd7S6pCc5Rb8aBCmnXOpz5f/fB1EJgfhR4BIBZmDwWE8tppqVL\r\n# 1nEM7CZkWPmo001AQrX19vPIQ3ukJk/Wn/9cD83zxWGBLAw3+YIm7zfYZOPoif5p\r\n# r04h63L9MtLQI99OF9XQM+T7o5bz5jTOt6Bcw3vRPCY41l1SGTrWjL1QQXDbkuDv\r\n# 3VmM//FceCvjkqFcxYwC24sCKjnig2x9ujnG5C4IiB+pTsUdmrC+tneCXXQkOT6V\r\n# M5UZDs3GY4Yqt/1aFcr4EZE0VaZoSuZn8hKlyXxXJLM7UlCPLxc=\r\n# SIG # End signature block\r\n"
  },
  {
    "path": "src/PowerShell/ExternalModules/PowerShellGet/2.2.5/PSGet.Format.ps1xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n<Configuration>\r\n    <ViewDefinitions>\r\n        <View>\r\n            <Name>PSRepositoryItemInfo</Name>\r\n            <ViewSelectedBy>\r\n                <TypeName>Microsoft.PowerShell.Commands.PSRepositoryItemInfo</TypeName>\r\n            </ViewSelectedBy>\r\n            <TableControl>\r\n                <TableHeaders>\r\n                    <TableColumnHeader>\r\n                        <Width>20</Width>\r\n                    </TableColumnHeader>\r\n                    <TableColumnHeader>\r\n                        <Width>35</Width>\r\n                    </TableColumnHeader>\r\n                    <TableColumnHeader>\r\n                        <Width>20</Width>\r\n                    </TableColumnHeader>\r\n                    <TableColumnHeader />\r\n                </TableHeaders>\r\n                <TableRowEntries>\r\n                    <TableRowEntry>\r\n                        <TableColumnItems>\r\n                            <TableColumnItem>\r\n                                <PropertyName>Version</PropertyName>\r\n                            </TableColumnItem>\r\n                            <TableColumnItem>\r\n                                <PropertyName>Name</PropertyName>\r\n                            </TableColumnItem>\r\n                            <TableColumnItem>\r\n                                <PropertyName>Repository</PropertyName>\r\n                            </TableColumnItem>\r\n                            <TableColumnItem>\r\n                                <PropertyName>Description</PropertyName>\r\n                            </TableColumnItem>\r\n                        </TableColumnItems>\r\n                    </TableRowEntry>\r\n                </TableRowEntries>\r\n            </TableControl>\r\n        </View>\r\n        <View>\r\n            <Name>PSRepository</Name>\r\n            <ViewSelectedBy>\r\n                <TypeName>Microsoft.PowerShell.Commands.PSRepository</TypeName>\r\n            </ViewSelectedBy>\r\n            <TableControl>\r\n                <TableHeaders>\r\n                    <TableColumnHeader>\r\n                        <Width>25</Width>\r\n                    </TableColumnHeader>\r\n                    <TableColumnHeader>\r\n                        <Width>20</Width>\r\n                    </TableColumnHeader>\r\n                    <TableColumnHeader />\r\n                </TableHeaders>\r\n                <TableRowEntries>\r\n                    <TableRowEntry>\r\n                        <TableColumnItems>\r\n                            <TableColumnItem>\r\n                                <PropertyName>Name</PropertyName>\r\n                            </TableColumnItem>\r\n                            <TableColumnItem>\r\n                                <PropertyName>InstallationPolicy</PropertyName>\r\n                            </TableColumnItem>\r\n                            <TableColumnItem>\r\n                                <PropertyName>SourceLocation</PropertyName>\r\n                            </TableColumnItem>\r\n                        </TableColumnItems>\r\n                    </TableRowEntry>\r\n                </TableRowEntries>\r\n            </TableControl>\r\n        </View>\r\n        <View>\r\n            <Name>PSScriptInfo</Name>\r\n            <ViewSelectedBy>\r\n                <TypeName>Microsoft.PowerShell.Commands.PSScriptInfo</TypeName>\r\n            </ViewSelectedBy>\r\n            <TableControl>\r\n                <TableHeaders>\r\n                    <TableColumnHeader>\r\n                        <Width>20</Width>\r\n                    </TableColumnHeader>\r\n                    <TableColumnHeader>\r\n                        <Width>25</Width>\r\n                    </TableColumnHeader>\r\n                    <TableColumnHeader>\r\n                        <Width>20</Width>\r\n                    </TableColumnHeader>\r\n                    <TableColumnHeader />\r\n                </TableHeaders>\r\n                <TableRowEntries>\r\n                    <TableRowEntry>\r\n                        <TableColumnItems>\r\n                            <TableColumnItem>\r\n                                <PropertyName>Version</PropertyName>\r\n                            </TableColumnItem>\r\n                            <TableColumnItem>\r\n                                <PropertyName>Name</PropertyName>\r\n                            </TableColumnItem>\r\n                            <TableColumnItem>\r\n                                <PropertyName>Author</PropertyName>\r\n                            </TableColumnItem>\r\n                            <TableColumnItem>\r\n                                <PropertyName>Description</PropertyName>\r\n                            </TableColumnItem>\r\n                        </TableColumnItems>\r\n                    </TableRowEntry>\r\n                </TableRowEntries>\r\n            </TableControl>\r\n        </View>\r\n        <View>\r\n            <Name>PSGetDscResourceInfo</Name>\r\n            <ViewSelectedBy>\r\n                <TypeName>Microsoft.PowerShell.Commands.PSGetCommandInfo</TypeName>\r\n                <TypeName>Microsoft.PowerShell.Commands.PSGetDscResourceInfo</TypeName>\r\n            </ViewSelectedBy>\r\n            <TableControl>\r\n                <TableHeaders>\r\n                    <TableColumnHeader>\r\n                        <Width>35</Width>\r\n                    </TableColumnHeader>\r\n                    <TableColumnHeader>\r\n                        <Width>10</Width>\r\n                    </TableColumnHeader>\r\n                    <TableColumnHeader>\r\n                        <Width>35</Width>\r\n                    </TableColumnHeader>\r\n                    <TableColumnHeader />\r\n                </TableHeaders>\r\n                <TableRowEntries>\r\n                    <TableRowEntry>\r\n                        <TableColumnItems>\r\n                            <TableColumnItem>\r\n                                <PropertyName>Name</PropertyName>\r\n                            </TableColumnItem>\r\n                            <TableColumnItem>\r\n                                <PropertyName>Version</PropertyName>\r\n                            </TableColumnItem>\r\n                            <TableColumnItem>\r\n                                <PropertyName>ModuleName</PropertyName>\r\n                            </TableColumnItem>\r\n                            <TableColumnItem>\r\n                                <PropertyName>Repository</PropertyName>\r\n                            </TableColumnItem>\r\n                        </TableColumnItems>\r\n                    </TableRowEntry>\r\n                </TableRowEntries>\r\n            </TableControl>\r\n        </View>\r\n        <View>\r\n            <Name>PSGetRoleCapabilityInfo</Name>\r\n            <ViewSelectedBy>\r\n                <TypeName>Microsoft.PowerShell.Commands.PSGetRoleCapabilityInfo</TypeName>\r\n            </ViewSelectedBy>\r\n            <TableControl>\r\n                <TableHeaders>\r\n                    <TableColumnHeader>\r\n                        <Width>35</Width>\r\n                    </TableColumnHeader>\r\n                    <TableColumnHeader>\r\n                        <Width>10</Width>\r\n                    </TableColumnHeader>\r\n                    <TableColumnHeader>\r\n                        <Width>35</Width>\r\n                    </TableColumnHeader>\r\n                    <TableColumnHeader />\r\n                </TableHeaders>\r\n                <TableRowEntries>\r\n                    <TableRowEntry>\r\n                        <TableColumnItems>\r\n                            <TableColumnItem>\r\n                                <PropertyName>Name</PropertyName>\r\n                            </TableColumnItem>\r\n                            <TableColumnItem>\r\n                                <PropertyName>Version</PropertyName>\r\n                            </TableColumnItem>\r\n                            <TableColumnItem>\r\n                                <PropertyName>ModuleName</PropertyName>\r\n                            </TableColumnItem>\r\n                            <TableColumnItem>\r\n                                <PropertyName>Repository</PropertyName>\r\n                            </TableColumnItem>\r\n                        </TableColumnItems>\r\n                    </TableRowEntry>\r\n                </TableRowEntries>\r\n            </TableControl>\r\n        </View>\r\n        <View>\r\n            <Name>PSGetPath</Name>\r\n            <ViewSelectedBy>\r\n                <TypeName>Microsoft.PowerShell.Commands.PSGetPath</TypeName>\r\n            </ViewSelectedBy>\r\n            <ListControl>\r\n                <ListEntries>\r\n                    <ListEntry>\r\n                        <ListItems>\r\n                            <ListItem>\r\n                                <PropertyName>AllUsersModules</PropertyName>\r\n                            </ListItem>\r\n                            <ListItem>\r\n                                <PropertyName>AllUsersScripts</PropertyName>\r\n                            </ListItem>\r\n                            <ListItem>\r\n                                <PropertyName>CurrentUserModules</PropertyName>\r\n                            </ListItem>\r\n                            <ListItem>\r\n                                <PropertyName>CurrentUserScripts</PropertyName>\r\n                            </ListItem>\r\n                        </ListItems>\r\n                    </ListEntry>\r\n                </ListEntries>\r\n            </ListControl>\r\n        </View>\r\n    </ViewDefinitions>\r\n</Configuration>\r\n\r\n<!-- SIG # Begin signature block -->\r\n<!-- MIIjkQYJKoZIhvcNAQcCoIIjgjCCI34CAQExDzANBglghkgBZQMEAgEFADB5Bgor -->\r\n<!-- BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG -->\r\n<!-- KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCOVRYEIZDcCnlr -->\r\n<!-- xj0MUHVDOqEjGmX6YDZrfL0NYHg3m6CCDYEwggX/MIID56ADAgECAhMzAAABh3IX -->\r\n<!-- chVZQMcJAAAAAAGHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD -->\r\n<!-- VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy -->\r\n<!-- b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p -->\r\n<!-- bmcgUENBIDIwMTEwHhcNMjAwMzA0MTgzOTQ3WhcNMjEwMzAzMTgzOTQ3WjB0MQsw -->\r\n<!-- CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u -->\r\n<!-- ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy -->\r\n<!-- b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -->\r\n<!-- AQDOt8kLc7P3T7MKIhouYHewMFmnq8Ayu7FOhZCQabVwBp2VS4WyB2Qe4TQBT8aB -->\r\n<!-- znANDEPjHKNdPT8Xz5cNali6XHefS8i/WXtF0vSsP8NEv6mBHuA2p1fw2wB/F0dH -->\r\n<!-- sJ3GfZ5c0sPJjklsiYqPw59xJ54kM91IOgiO2OUzjNAljPibjCWfH7UzQ1TPHc4d -->\r\n<!-- weils8GEIrbBRb7IWwiObL12jWT4Yh71NQgvJ9Fn6+UhD9x2uk3dLj84vwt1NuFQ -->\r\n<!-- itKJxIV0fVsRNR3abQVOLqpDugbr0SzNL6o8xzOHL5OXiGGwg6ekiXA1/2XXY7yV -->\r\n<!-- Fc39tledDtZjSjNbex1zzwSXAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE -->\r\n<!-- AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUhov4ZyO96axkJdMjpzu2zVXOJcsw -->\r\n<!-- UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1 -->\r\n<!-- ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDU4Mzg1MB8GA1UdIwQYMBaAFEhu -->\r\n<!-- ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu -->\r\n<!-- bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w -->\r\n<!-- Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3 -->\r\n<!-- Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx -->\r\n<!-- MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAixmy -->\r\n<!-- S6E6vprWD9KFNIB9G5zyMuIjZAOuUJ1EK/Vlg6Fb3ZHXjjUwATKIcXbFuFC6Wr4K -->\r\n<!-- NrU4DY/sBVqmab5AC/je3bpUpjtxpEyqUqtPc30wEg/rO9vmKmqKoLPT37svc2NV -->\r\n<!-- BmGNl+85qO4fV/w7Cx7J0Bbqk19KcRNdjt6eKoTnTPHBHlVHQIHZpMxacbFOAkJr -->\r\n<!-- qAVkYZdz7ikNXTxV+GRb36tC4ByMNxE2DF7vFdvaiZP0CVZ5ByJ2gAhXMdK9+usx -->\r\n<!-- zVk913qKde1OAuWdv+rndqkAIm8fUlRnr4saSCg7cIbUwCCf116wUJ7EuJDg0vHe -->\r\n<!-- yhnCeHnBbyH3RZkHEi2ofmfgnFISJZDdMAeVZGVOh20Jp50XBzqokpPzeZ6zc1/g -->\r\n<!-- yILNyiVgE+RPkjnUQshd1f1PMgn3tns2Cz7bJiVUaqEO3n9qRFgy5JuLae6UweGf -->\r\n<!-- AeOo3dgLZxikKzYs3hDMaEtJq8IP71cX7QXe6lnMmXU/Hdfz2p897Zd+kU+vZvKI -->\r\n<!-- 3cwLfuVQgK2RZ2z+Kc3K3dRPz2rXycK5XCuRZmvGab/WbrZiC7wJQapgBodltMI5 -->\r\n<!-- GMdFrBg9IeF7/rP4EqVQXeKtevTlZXjpuNhhjuR+2DMt/dWufjXpiW91bo3aH6Ea -->\r\n<!-- jOALXmoxgltCp1K7hrS6gmsvj94cLRf50QQ4U8Qwggd6MIIFYqADAgECAgphDpDS -->\r\n<!-- AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK -->\r\n<!-- V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0 -->\r\n<!-- IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0 -->\r\n<!-- ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla -->\r\n<!-- MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS -->\r\n<!-- ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT -->\r\n<!-- H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB -->\r\n<!-- AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG -->\r\n<!-- OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S -->\r\n<!-- 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz -->\r\n<!-- y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7 -->\r\n<!-- 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u -->\r\n<!-- M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33 -->\r\n<!-- X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl -->\r\n<!-- XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP -->\r\n<!-- 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB -->\r\n<!-- l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF -->\r\n<!-- RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM -->\r\n<!-- CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ -->\r\n<!-- BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud -->\r\n<!-- DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO -->\r\n<!-- 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0 -->\r\n<!-- LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y -->\r\n<!-- Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p -->\r\n<!-- Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y -->\r\n<!-- Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB -->\r\n<!-- FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw -->\r\n<!-- cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA -->\r\n<!-- XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY -->\r\n<!-- 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj -->\r\n<!-- 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd -->\r\n<!-- d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ -->\r\n<!-- Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf -->\r\n<!-- wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ -->\r\n<!-- aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j -->\r\n<!-- NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B -->\r\n<!-- xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96 -->\r\n<!-- eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7 -->\r\n<!-- r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I -->\r\n<!-- RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVZjCCFWICAQEwgZUwfjELMAkG -->\r\n<!-- A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx -->\r\n<!-- HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z -->\r\n<!-- b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAYdyF3IVWUDHCQAAAAABhzAN -->\r\n<!-- BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor -->\r\n<!-- BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQg1dUCNDeV -->\r\n<!-- 4NiSkRioeiyXG4ISNEaD73JLwEZVkdhDFNUwQgYKKwYBBAGCNwIBDDE0MDKgFIAS -->\r\n<!-- AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN -->\r\n<!-- BgkqhkiG9w0BAQEFAASCAQA6ROUjVzqD7iMIJcb+gvmP8P+O7xOSpAzwE5NgSh6n -->\r\n<!-- Y5IOoQpzRILyc3GlbIoqKdPhbQaG12yCNZ7x2LItwa2/iUjKUHJ2a4ImCJ/4xxox -->\r\n<!-- fDr6npp3e8s5HyDi3olZMcGSy7I9VwfqOEUswh3uGyUrPPhvLAli5rEXBe7iFrbh -->\r\n<!-- BwGIhjPHd3avx4cCFgWAlpOh6V9XFbPpcZRMbjZ9oLKh1hZ2/sfdRiM17iNJaveP -->\r\n<!-- xvAX4pDtZ1w0xP7f9sDNZwYNVJHVhRaHCa7gkDKpCDo80uzF7kSFrvElB4EYXVlC -->\r\n<!-- J52LCaUDmAu+gr92UpF/L2p0a4gyKFSMjPbZ2Faxb7eooYIS8DCCEuwGCisGAQQB -->\r\n<!-- gjcDAwExghLcMIIS2AYJKoZIhvcNAQcCoIISyTCCEsUCAQMxDzANBglghkgBZQME -->\r\n<!-- AgEFADCCAVQGCyqGSIb3DQEJEAEEoIIBQwSCAT8wggE7AgEBBgorBgEEAYRZCgMB -->\r\n<!-- MDEwDQYJYIZIAWUDBAIBBQAEIBzUMRs3npiqSIsVAxe913Hhl8J6lavyeEUy/qSf -->\r\n<!-- QSyqAgZfYQoJ7SMYEjIwMjAwOTIyMjIxOTUxLjU0WjAEgAIB9KCB1KSB0TCBzjEL -->\r\n<!-- MAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1v -->\r\n<!-- bmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEpMCcGA1UECxMgTWlj -->\r\n<!-- cm9zb2Z0IE9wZXJhdGlvbnMgUHVlcnRvIFJpY28xJjAkBgNVBAsTHVRoYWxlcyBU -->\r\n<!-- U1MgRVNOOjg5N0EtRTM1Ni0xNzAxMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1T -->\r\n<!-- dGFtcCBTZXJ2aWNloIIORDCCBPUwggPdoAMCAQICEzMAAAEsIq9Fl3X5G+4AAAAA -->\r\n<!-- ASwwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp -->\r\n<!-- bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw -->\r\n<!-- b3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAw -->\r\n<!-- HhcNMTkxMjE5MDExNTAzWhcNMjEwMzE3MDExNTAzWjCBzjELMAkGA1UEBhMCVVMx -->\r\n<!-- EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT -->\r\n<!-- FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEpMCcGA1UECxMgTWljcm9zb2Z0IE9wZXJh -->\r\n<!-- dGlvbnMgUHVlcnRvIFJpY28xJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNOOjg5N0Et -->\r\n<!-- RTM1Ni0xNzAxMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNl -->\r\n<!-- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8rXOBJKr4zEBijeqkK1A -->\r\n<!-- PFIw88nLqab/B8Qk2M1Sdi0sUHCXUFRLm2sST+3jWV3EhMp6Gz4AHFiqjhDGyDcb -->\r\n<!-- LW6AqLAcCdiKJ6R8L5mGm00WC2cNkifjnMLQCVWv/pR8u2wtwcKHVcSUtQd8QLSc -->\r\n<!-- G5Bwz9Klij17eXWpjk10yAMbEKyYIp2Jl9hci75TRRggGF3OZIecHd/Fk4FVyvmG -->\r\n<!-- 0UcQEE23+sUmWb8DjJvygGyn5R/SnlDCY79sJx2oHXkmnKU6FmZazSxR8kqUr0Ss -->\r\n<!-- CEHAaSLZ4hEUqxAF2RdL09akXXDaAglG9KQMRoJ/6VsZM91LMdJt9ERY4X3BjeJi -->\r\n<!-- PwIDAQABo4IBGzCCARcwHQYDVR0OBBYEFFFqFlIZ+sJCELIjIYf0OSJpbsvTMB8G -->\r\n<!-- A1UdIwQYMBaAFNVjOlyKMZDzQ3t8RhvFM2hahW1VMFYGA1UdHwRPME0wS6BJoEeG -->\r\n<!-- RWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Rp -->\r\n<!-- bVN0YVBDQV8yMDEwLTA3LTAxLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUH -->\r\n<!-- MAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljVGltU3Rh -->\r\n<!-- UENBXzIwMTAtMDctMDEuY3J0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYB -->\r\n<!-- BQUHAwgwDQYJKoZIhvcNAQELBQADggEBAE8XEcjCLi8Afj3D1K+bPore0znlGVbm -->\r\n<!-- k95Qtd263ZGrLpizT5Wlmxu5oSjGzpnULeExuSKpkXHHKW3Emm4dPIZODrXN80gX -->\r\n<!-- mfpGxgXezsgSUNc19nOcXX/aJZzq5E9kryvHFQn/t6ZhdkJjC5RjReOwKk/2ltFE -->\r\n<!-- p4mLqvlqtLIj418rG+CgzbUk23UFx2Ve4B5x13+TxSPEKxx99qegrafosXDU9xmU -->\r\n<!-- Q7s0h3uj6ygzYLRBjkFh2CGmfu6qikHqLHIUgiQNcW5v7UTsaYATB9TpXAQcvvL2 -->\r\n<!-- s0Txt34mtCz7IC2SQfL0WZeD8+warV1pXNfVKjsInqfKmGm4dI3dV9MwggZxMIIE -->\r\n<!-- WaADAgECAgphCYEqAAAAAAACMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJV -->\r\n<!-- UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE -->\r\n<!-- ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9v -->\r\n<!-- dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAxMDAeFw0xMDA3MDEyMTM2NTVaFw0y -->\r\n<!-- NTA3MDEyMTQ2NTVaMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u -->\r\n<!-- MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp -->\r\n<!-- b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMIIBIjAN -->\r\n<!-- BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqR0NvHcRijog7PwTl/X6f2mUa3RU -->\r\n<!-- ENWlCgCChfvtfGhLLF/Fw+Vhwna3PmYrW/AVUycEMR9BGxqVHc4JE458YTBZsTBE -->\r\n<!-- D/FgiIRUQwzXTbg4CLNC3ZOs1nMwVyaCo0UN0Or1R4HNvyRgMlhgRvJYR4YyhB50 -->\r\n<!-- YWeRX4FUsc+TTJLBxKZd0WETbijGGvmGgLvfYfxGwScdJGcSchohiq9LZIlQYrFd -->\r\n<!-- /XcfPfBXday9ikJNQFHRD5wGPmd/9WbAA5ZEfu/QS/1u5ZrKsajyeioKMfDaTgaR -->\r\n<!-- togINeh4HLDpmc085y9Euqf03GS9pAHBIAmTeM38vMDJRF1eFpwBBU8iTQIDAQAB -->\r\n<!-- o4IB5jCCAeIwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFNVjOlyKMZDzQ3t8 -->\r\n<!-- RhvFM2hahW1VMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIB -->\r\n<!-- hjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fO -->\r\n<!-- mhjEMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9w -->\r\n<!-- a2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggr -->\r\n<!-- BgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNv -->\r\n<!-- bS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MIGgBgNVHSAB -->\r\n<!-- Af8EgZUwgZIwgY8GCSsGAQQBgjcuAzCBgTA9BggrBgEFBQcCARYxaHR0cDovL3d3 -->\r\n<!-- dy5taWNyb3NvZnQuY29tL1BLSS9kb2NzL0NQUy9kZWZhdWx0Lmh0bTBABggrBgEF -->\r\n<!-- BQcCAjA0HjIgHQBMAGUAZwBhAGwAXwBQAG8AbABpAGMAeQBfAFMAdABhAHQAZQBt -->\r\n<!-- AGUAbgB0AC4gHTANBgkqhkiG9w0BAQsFAAOCAgEAB+aIUQ3ixuCYP4FxAz2do6Eh -->\r\n<!-- b7Prpsz1Mb7PBeKp/vpXbRkws8LFZslq3/Xn8Hi9x6ieJeP5vO1rVFcIK1GCRBL7 -->\r\n<!-- uVOMzPRgEop2zEBAQZvcXBf/XPleFzWYJFZLdO9CEMivv3/Gf/I3fVo/HPKZeUqR -->\r\n<!-- UgCvOA8X9S95gWXZqbVr5MfO9sp6AG9LMEQkIjzP7QOllo9ZKby2/QThcJ8ySif9 -->\r\n<!-- Va8v/rbljjO7Yl+a21dA6fHOmWaQjP9qYn/dxUoLkSbiOewZSnFjnXshbcOco6I8 -->\r\n<!-- +n99lmqQeKZt0uGc+R38ONiU9MalCpaGpL2eGq4EQoO4tYCbIjggtSXlZOz39L9+ -->\r\n<!-- Y1klD3ouOVd2onGqBooPiRa6YacRy5rYDkeagMXQzafQ732D8OE7cQnfXXSYIghh -->\r\n<!-- 2rBQHm+98eEA3+cxB6STOvdlR3jo+KhIq/fecn5ha293qYHLpwmsObvsxsvYgrRy -->\r\n<!-- zR30uIUBHoD7G4kqVDmyW9rIDVWZeodzOwjmmC3qjeAzLhIp9cAvVCch98isTtoo -->\r\n<!-- uLGp25ayp0Kiyc8ZQU3ghvkqmqMRZjDTu3QyS99je/WZii8bxyGvWbWu3EQ8l1Bx -->\r\n<!-- 16HSxVXjad5XwdHeMMD9zOZN+w2/XU/pnR4ZOC+8z1gFLu8NoFA12u8JJxzVs341 -->\r\n<!-- Hgi62jbb01+P3nSISRKhggLSMIICOwIBATCB/KGB1KSB0TCBzjELMAkGA1UEBhMC -->\r\n<!-- VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV -->\r\n<!-- BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEpMCcGA1UECxMgTWljcm9zb2Z0IE9w -->\r\n<!-- ZXJhdGlvbnMgUHVlcnRvIFJpY28xJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNOOjg5 -->\r\n<!-- N0EtRTM1Ni0xNzAxMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2 -->\r\n<!-- aWNloiMKAQEwBwYFKw4DAhoDFQAMTk4pIyg3H+ZjFhZqnVFM6iFsnaCBgzCBgKR+ -->\r\n<!-- MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS -->\r\n<!-- ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMT -->\r\n<!-- HU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMA0GCSqGSIb3DQEBBQUAAgUA -->\r\n<!-- 4xTCwzAiGA8yMDIwMDkyMjIyMzY1MVoYDzIwMjAwOTIzMjIzNjUxWjB3MD0GCisG -->\r\n<!-- AQQBhFkKBAExLzAtMAoCBQDjFMLDAgEAMAoCAQACAiV/AgH/MAcCAQACAhHNMAoC -->\r\n<!-- BQDjFhRDAgEAMDYGCisGAQQBhFkKBAIxKDAmMAwGCisGAQQBhFkKAwKgCjAIAgEA -->\r\n<!-- AgMHoSChCjAIAgEAAgMBhqAwDQYJKoZIhvcNAQEFBQADgYEASZkKTk+wwDqgbjRi -->\r\n<!-- 6U9SnEO1AD4kC5fI2ssjjAlx2a/fgHOaP2CTeC/pnFBnGW9mMDU7U/eVwoYhhyj1 -->\r\n<!-- SRF0B4/pnN+KbpTdSiJTPUAcq5KbqIu7Htn+E22ASzZmlhfE4rkln/09rYjmaDRX -->\r\n<!-- GwZ1cHGXpM5mpsHpoY0bVkrK1FYxggMNMIIDCQIBATCBkzB8MQswCQYDVQQGEwJV -->\r\n<!-- UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE -->\r\n<!-- ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGlt -->\r\n<!-- ZS1TdGFtcCBQQ0EgMjAxMAITMwAAASwir0WXdfkb7gAAAAABLDANBglghkgBZQME -->\r\n<!-- AgEFAKCCAUowGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMC8GCSqGSIb3DQEJ -->\r\n<!-- BDEiBCB6nhIAPSybxCPtX8/nxclicqgydzgLbY7nl9LswdDjiDCB+gYLKoZIhvcN -->\r\n<!-- AQkQAi8xgeowgecwgeQwgb0EIFuf/S4UWHjaFMzlc6gp1d68FqJLGZgr0iVyf2e7 -->\r\n<!-- lkfhMIGYMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x -->\r\n<!-- EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv -->\r\n<!-- bjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAEs -->\r\n<!-- Iq9Fl3X5G+4AAAAAASwwIgQgmaQwXK5RbnKJcB6YwJYfKTxPUQwyUHVwSJUPj8T6 -->\r\n<!-- +GowDQYJKoZIhvcNAQELBQAEggEAlL75xRPc4tptUv06J+L/DMEHjupdUsCNIN2T -->\r\n<!-- ZblaNZQgtyEHE7sX5TSEHx/BQW5+NxmdejTN/98nwVSVnNfderyCb1lrZ4I0NRJU -->\r\n<!-- 1uyPLYbAO+wh3xp0/uW2dA8yq/1DtmYiym8P+0XcWui0I/msRrghVkxUUsrT1IOA -->\r\n<!-- rK80qwaTPMtN2AvDaQXhEVwdSAvxI+ysS61vUH4lcK9z4wtU+0h+giPtDGuTBzP0 -->\r\n<!-- 7eJOk2rj0ZL6aaIw78SWGpux6hT3r300edgJDbAA9HXn/YC1lwmIpjWl0KW7c1cM -->\r\n<!-- hhTk3Os3TjuPSiNft6TYZL7DBmia4Cjf8PJwCHgIwtnNeIli8w== -->\r\n<!-- SIG # End signature block -->\r\n"
  },
  {
    "path": "src/PowerShell/ExternalModules/PowerShellGet/2.2.5/PSGet.Resource.psd1",
    "content": "﻿#########################################################################################\r\n#\r\n# Copyright (c) Microsoft Corporation. All rights reserved.\r\n#\r\n# Localized PSGet.Resource.psd1\r\n#\r\n#########################################################################################\r\n\r\nConvertFrom-StringData @'\r\n###PSLOC\r\n        InstallModulewhatIfMessage=Version '{1}' of module '{0}'\r\n        InstallScriptwhatIfMessage=Version '{1}' of script '{0}'\r\n        UpdateModulewhatIfMessage=Version '__OLDVERSION__' of module '{0}', updating to version '{1}'\r\n        UpdateScriptwhatIfMessage=Version '__OLDVERSION__' of script '{0}', updating to version '{1}'\r\n        PublishModulewhatIfMessage=Version '{0}' of module '{1}'\r\n        PublishScriptwhatIfMessage=Version '{0}' of script '{1}'\r\n        NewScriptFileInfowhatIfMessage=Creating the '{0}' PowerShell Script file\r\n        UpdateScriptFileInfowhatIfMessage=Updating the '{0}' PowerShell Script file\r\n        NameShouldNotContainWildcardCharacters=The specified name '{0}' should not contain any wildcard characters, please correct it and try again.\r\n        AllVersionsCannotBeUsedWithOtherVersionParameters=You cannot use the parameter AllVersions with RequiredVersion, MinimumVersion or MaximumVersion in the same command.\r\n        VersionRangeAndRequiredVersionCannotBeSpecifiedTogether=You cannot use the parameters RequiredVersion and either MinimumVersion or MaximumVersion in the same command. Specify only one of these parameters in your command.\r\n        RequiredVersionAllowedOnlyWithSingleModuleName=The RequiredVersion parameter is allowed only when a single module name is specified as the value of the Name parameter, without any wildcard characters.\r\n        MinimumVersionIsGreaterThanMaximumVersion=The specified MinimumVersion '{0}' is greater than the specified MaximumVersion '{1}'.\r\n        AllowPrereleaseRequiredToUsePrereleaseStringInVersion=The '-AllowPrerelease' parameter must be specified when using the Prerelease string in MinimumVersion, MaximumVersion, or RequiredVersion.\r\n        UpdateModuleAdminPrivilegeRequiredForAllUsersScope=Administrator rights are required to update modules in '{0}'. Log on to the computer with an account that has Administrator rights, and then try again, or update '{1}' by adding \"-Scope CurrentUser\" to your command. You can also try running the Windows PowerShell session with elevated rights (Run as Administrator).\r\n        InstallModuleAdminPrivilegeRequiredForAllUsersScope=Administrator rights are required to install modules in '{0}'. Log on to the computer with an account that has Administrator rights, and then try again, or install '{1}' by adding \"-Scope CurrentUser\" to your command. You can also try running the Windows PowerShell session with elevated rights (Run as Administrator).\r\n        InstallScriptAdminPrivilegeRequiredForAllUsersScope=Administrator rights are required to install scripts in '{0}'. Log on to the computer with an account that has Administrator rights, and then try again, or install '{1}' by adding \"-Scope CurrentUser\" to your command. You can also try running the Windows PowerShell session with elevated rights (Run as Administrator).\r\n        AdministratorRightsNeededOrSpecifyCurrentUserScope=Administrator rights are required to install or update. Log on to the computer with an account that has Administrator rights, and then try again, or install by adding \"-Scope CurrentUser\" to your command. You can also try running the Windows PowerShell session with elevated rights (Run as Administrator).\r\n        VersionParametersAreAllowedOnlyWithSingleName=The RequiredVersion, MinimumVersion, MaximumVersion, AllVersions or AllowPrerelease parameters are allowed only when you specify a single name as the value of the Name parameter, without any wildcard characters.\r\n        PathIsNotADirectory=The specified path '{0}' is not a valid directory.\r\n        ModuleAlreadyInstalled=Version '{0}' of module '{1}' is already installed at '{2}'. To delete version '{3}' and install version '{4}', run Install-Module, and add the -Force parameter.\r\n        ScriptAlreadyInstalled=Version '{0}' of script '{1}' is already installed at '{2}'. To delete version '{3}' and install version '{4}', run Install-Script, and add the -Force parameter.\r\n        CommandAlreadyAvailable=A command with name '{0}' is already available on this system. This script '{0}' may override the existing command. If you still want to install this script '{0}', use -Force parameter.\r\n        ModuleAlreadyInstalledSxS=Version '{0}' of module '{1}' is already installed at '{2}'. To install version '{3}', run Install-Module and add the -Force parameter, this command will install version '{5}' side-by-side with version '{4}'.\r\n        ModuleAlreadyInstalledVerbose=Version '{0}' of module '{1}' is already installed at '{2}'.\r\n        ScriptAlreadyInstalledVerbose=Version '{0}' of script '{1}' is already installed at '{2}'.\r\n        ModuleWithRequiredVersionAlreadyInstalled=Version '{0}' of module '{1}' is already installed at '{2}'. To reinstall this version '{3}', run Install-Module or Updated-Module cmdlet with the -Force parameter.\r\n        InvalidPSModule=The module '{0}' cannot be installed or updated because it is not a properly-formed module.\r\n        InvalidPowerShellScriptFile=The script '{0}' cannot be installed or updated because it is not a properly-formed script.\r\n        InvalidAuthenticodeSignature=The module '{0}' cannot be installed or updated because the Authenticode signature for the file '{1}' is not valid.\r\n        ModuleNotInstalledOnThisMachine=Module '{0}' was not updated because no valid module was found in the module directory. Verify that the module is located in the folder specified by $env:PSModulePath.\r\n        ScriptNotInstalledOnThisMachine=Script '{0}' was not updated because no valid script was found in the script directories '{1}' and '{2}'.\r\n        AdminPrivilegesRequiredForUpdate=Module '{0}' (installed at '{1}') cannot be updated because Administrator rights are required to change that directory. Log on to the computer with an account that has Administrator rights, and then try again. You can also try running the Windows PowerShell session with elevated rights (Run as Administrator).\r\n        AdminPrivilegesRequiredForScriptUpdate=Script '{0}' (installed at '{1}') cannot be updated because Administrator rights are required to change that script. Log on to the computer with an account that has Administrator rights, and then try again. You can also try running the Windows PowerShell session with elevated rights (Run as Administrator).\r\n        ModuleNotInstalledUsingPowerShellGet=Module '{0}' was not installed by using Install-Module, so it cannot be updated.\r\n        ScriptNotInstalledUsingPowerShellGet=Script '{0}' was not installed by using Install-Script, so it cannot be updated.\r\n        DownloadingModuleFromGallery=Downloading module '{0}' with version '{1}' from the repository '{2}'.\r\n        DownloadingScriptFromGallery=Downloading script '{0}' with version '{1}' from the repository '{2}'.\r\n        NoUpdateAvailable=No updates were found for module '{0}'.\r\n        NoScriptUpdateAvailable=No updates were found for script '{0}'.\r\n        FoundModuleUpdate=An update for the module '{0}' was found with version '{1}'.\r\n        FoundScriptUpdate=An update for the script '{0}' was found with version '{1}'.\r\n        InvalidPSModuleDuringUpdate= Module '{0}' was not updated because the module in the repository '{1}' is not a valid Windows PowerShell module.\r\n        ModuleGotUpdated=Module '{0}' has been updated successfully.\r\n        TestingModuleInUse=Testing if the module to update is in use.\r\n        ModuleDestination= The specified module will be installed in '{0}'.\r\n        ScriptDestination= The specified script will be installed in '{0}' and its dependent modules will be installed in '{1}'.\r\n        ModuleIsInUse=Module '{0}' is in currently in use or you don't have the required permissions.\r\n        ModuleInstalledSuccessfully=Module '{0}' was installed successfully to path '{1}'.\r\n        ModuleSavedSuccessfully=Module '{0}' was saved successfully to path '{1}'.\r\n        ScriptInstalledSuccessfully=Script '{0}' was installed successfully to path '{1}'.\r\n        ScriptSavedSuccessfully=Script '{0}' was saved successfully to path '{1}'.\r\n        CheckingForModuleUpdate= Checking for updates for module '{0}'.\r\n        CheckingForScriptUpdate= Checking for updates for script '{0}'.\r\n        ModuleInUseWithProcessDetails=The version '{0}' of module '{1}' is currently in use. Retry the operation after closing the following applications: '{2}'.\r\n        ModuleVersionInUse=The version '{0}' of module '{1}' is currently in use. Retry the operation after closing the applications.\r\n        ModuleNotAvailableLocally=The specified module '{0}' was not published because no module with that name was found in any module directory.\r\n        InvalidModulePathToPublish=The specified module with path '{0}' was not published because no valid module was found with that path.\r\n        ModuleWithRequiredVersionNotAvailableLocally= The specified module '{0}' with version '{1}' was not published because no module with that name and version was found in any module directory.\r\n        AmbiguousModuleName=Modules with the name '{0}' are available under multiple paths. Add the -RequiredVersion parameter or the -Path parameter to specify the module to publish.\r\n        AmbiguousModulePath=Multiple versions are available under the specified module path '{0}'. Specify the full path to the module to be published.\r\n        PublishModuleLocation=Module '{0}' was found in '{1}'.\r\n        InvalidModuleToPublish=Module '{0}' cannot be published because it does not have a module manifest file. Run New-ModuleManifest -Path <PathName> to create a module manifest with metadata before publishing.\r\n        MissingRequiredManifestKeys=Module '{0}' cannot be published because it is missing required metadata. Verify that the module manifest specifies Description and Author.\r\n        InvalidCharactersInPrereleaseString=The Prerelease string '{0}' contains invalid characters. Please ensure that only characters 'a-zA-Z0-9' and possibly hyphen ('-') at the beginning are in the Prerelease string.\r\n        IncorrectVersionPartsCountForPrereleaseStringUsage=Version '{0}' must have exactly 3 parts for a Prerelease string to be used.\r\n        ModuleVersionShouldBeGreaterThanGalleryVersion=Module '{0}' with version '{1}' cannot be published. The version must exceed the current version '{2}' that exists in the repository '{3}', or you must specify -Force.\r\n        ModuleVersionIsAlreadyAvailableInTheGallery=The module '{0}' with version '{1}' cannot be published as the current version '{2}' is already available in the repository '{3}'.\r\n        CouldNotInstallNuGetProvider=NuGet provider is required to interact with NuGet-based repositories. Please ensure that '{0}' or newer version of NuGet provider is installed.\r\n        CouldNotInstallNuGetExe=NuGet.exe version '{0}' or newer, or dotnet command version '{1}' or newer is required to interact with NuGet-based repositories. Please ensure that NuGet.exe or dotnet command is available under one of the paths specified in PATH environment variable value.\r\n        CouldNotUpgradeNuGetExe=NuGet.exe version '{0}' or newer, or dotnet command version '{1}' or newer is required to interact with NuGet-based repositories. Please ensure that required version of NuGet.exe or dotnet command is available under one of the paths specified in PATH environment variable value.\r\n        CouldNotFindDotnetCommand=For publish operations, dotnet command version '{0}' or newer is required to interact with the NuGet-based repositories. Please ensure that dotnet command version '{0}' or newer is installed and available under one of the paths specified in PATH environment variable value. You can also install the dotnet command by following the instructions specified at '{1}'.\r\n        CouldNotInstallNuGetBinaries2=PowerShellGet requires NuGet.exe (or dotnet command) and NuGet provider version '{0}' or newer to interact with the NuGet-based repositories. Please ensure that '{0}' or newer version of NuGet provider is installed and NuGet.exe (or dotnet command) is available under one of the paths specified in PATH environment variable value.\r\n        InstallNugetBinariesUpgradeShouldContinueQuery=This version of PowerShellGet requires minimum version '{0}' of NuGet.exe and minimum version '{1}' of NuGet provider to publish an item to NuGet-based repositories. The NuGet provider must be available in '{2}' or '{3}'. You can also install the NuGet provider by running 'Install-PackageProvider -Name NuGet -MinimumVersion {0} -Force'. NuGet.exe must be available in '{4}' or '{5}', or under one of the paths specified in PATH environment variable value. NuGet.exe can be downloaded from https://aka.ms/psget-nugetexe. For more information, see https://go.microsoft.com/fwlink/?linkid=875534. Do you want PowerShellGet to upgrade NuGet.exe to the latest version and install the NuGet provider now?\r\n        InstallNuGetBinariesShouldContinueQuery=This version of PowerShellGet requires minimum version '{0}' of NuGet.exe and minimum version '{1}' of NuGet provider to publish an item to NuGet-based repositories. The NuGet provider must be available in '{3}' or '{3}'. You can also install the NuGet provider by running 'Install-PackageProvider -Name NuGet -MinimumVersion {0} -Force'. NuGet.exe must be available in '{4}' or '{5}', or under one of the paths specified in PATH environment variable value. NuGet.exe can be downloaded from https://aka.ms/psget-nugetexe. For more information, see https://go.microsoft.com/fwlink/?linkid=875534. Do you want PowerShellGet to install both the latest NuGet.exe and NuGet provider now?\r\n        InstallNugetExeUpgradeShouldContinueQuery=This version of PowerShellGet requires minimum version '{0}' of NuGet.exe to publish an item to the NuGet-based repositories. NuGet.exe must be available in '{1}' or '{2}', or under one of the paths specified in PATH environment variable value. NuGet.exe can be downloaded from https://aka.ms/psget-nugetexe. For more information, see https://aka.ms/installing-powershellget . Do you want PowerShellGet to upgrade to the latest version of NuGet.exe now?\r\n        InstallNuGetExeShouldContinueQuery=This version of PowerShellGet requires minimum version '{0}' of NuGet.exe to publish an item to the NuGet-based repositories. NuGet.exe must be available in '{1}' or '{2}', or under one of the paths specified in PATH environment variable value. NuGet.exe can be downloaded from https://aka.ms/psget-nugetexe. For more information, see https://aka.ms/installing-powershellget . Do you want PowerShellGet to install the latest version of NuGet.exe now?\r\n        InstallNuGetProviderShouldContinueQuery=This version of PowerShellGet requires minimum version '{0}' of NuGet provider to publish an item to NuGet-based repositories. The NuGet provider must be available in '{1}' or '{2}'. You can also install the NuGet provider by running 'Install-PackageProvider -Name NuGet -MinimumVersion {0} -Force'. Do you want PowerShellGet to install and import the NuGet provider now?\r\n        InstallNuGetBinariesUpgradeShouldContinueCaption=NuGet.exe upgrade and NuGet provider installation are required to continue\r\n        InstallNuGetBinariesShouldContinueCaption=NuGet.exe and NuGet provider installation are required to continue\r\n        InstallNuGetExeUpgradeShouldContinueCaption=NuGet.exe upgrade is required to continue\r\n        InstallNuGetExeShouldContinueCaption=NuGet.exe is required to continue\r\n        InstallNuGetProviderShouldContinueCaption=NuGet provider is required to continue\r\n        DownloadingNugetExe=Installing NuGet.exe.\r\n        DownloadingNugetProvider=Installing NuGet provider.\r\n        ModuleNotFound=Module '{0}' was not found.\r\n        NoMatchFound=No match was found for the specified search criteria and module names '{0}'.\r\n        NoMatchFoundForScriptName=No match was found for the specified search criteria and script names '{0}'.\r\n        MatchInvalidType=The name '{0}' is a {1} not a {2}.\r\n        FailedToCreateCompressedModule=Failed to generate the compressed file for module '{0}'.\r\n        FailedToPublish=Failed to publish module '{0}': '{1}'.\r\n        PublishedSuccessfully=Successfully published module '{0}' to the module publish location '{1}'. Please allow few minutes for '{2}' to show up in the search results.\r\n        InvalidWebUri=The specified Uri '{0}' for parameter '{1}' is an invalid Web Uri. Please ensure that it meets the Web Uri requirements.\r\n        RepositoryAlreadyRegistered=The repository could not be registered because there exists a registered repository with Name '{0}' and SourceLocation '{1}'. To register another repository with Name '{2}', please unregister the existing repository using the Unregister-PSRepository cmdlet.\r\n        RepositoryToBeUnregisteredNotFound=The repository '{0}' was not removed because no repository was found with that name. Please run Get-PSRepository and ensure that a repository of that name is present.\r\n        RepositoryCannotBeUnregistered=The specified repository '{0}' cannot be unregistered.\r\n        RepositoryNotFound=No repository with the name '{0}' was found.\r\n        PSGalleryNotFound=Unable to find repository '{0}'. Use Get-PSRepository to see all available repositories. Try again after specifying a valid repository name. You can use 'Register-PSRepository -Default' to register the PSGallery repository.\r\n        ParameterIsNotAllowedWithPSGallery=The PSGallery repository has pre-defined locations. The '{0}' parameter is not allowed, try again after removing the '{0}' parameter.\r\n        UseDefaultParameterSetOnRegisterPSRepository=Use 'Register-PSRepository -Default' to register the PSGallery repository.\r\n        RepositoryNameContainsWildCards=The repository name '{0}' should not have wildcards, correct it and try again.\r\n        InvalidRepository=The specified repository '{0}' is not a valid registered repository name. Please ensure that '{1}' is a registered repository.\r\n        RepositoryCannotBeRegistered=The specified repository '{0}' is unauthorized and cannot be registered. Try running with -Credential.\r\n        RepositoryRegistered=Successfully registered the repository '{0}' with source location '{1}'.\r\n        RepositoryUnregistered=Successfully unregistered the repository '{0}'.\r\n        PSGalleryPublishLocationIsMissing=The specified repository '{0}' does not have a valid PublishLocation. Retry after setting the PublishLocation for repository '{1}' to a valid NuGet publishing endpoint using the Set-PSRepository cmdlet.\r\n        PSRepositoryScriptPublishLocationIsMissing=The specified repository '{0}' does not have a valid ScriptPublishLocation. Retry after setting the ScriptPublishLocation for repository '{1}' to a valid NuGet publishing endpoint using the Set-PSRepository cmdlet.\r\n        ScriptSourceLocationIsMissing=The specified repository '{0}' does not have a valid ScriptSourceLocation. Retry after setting the ScriptSourceLocation for repository '{0}' to a valid NuGet endpoint for scripts using the Set-PSRepository cmdlet.\r\n        PublishModuleSupportsOnlyNuGetBasedPublishLocations=Publish-Module only supports the NuGet-based publish locations. The PublishLocation '{0}' of the repository '{1}' is not a NuGet-based publish location. Retry after setting the PublishLocation for repository '{1}' to a valid NuGet publishing endpoint using the Set-PSRepository cmdlet.\r\n        PublishScriptSupportsOnlyNuGetBasedPublishLocations=Publish-Script only supports the NuGet-based publish locations. The ScriptPublishLocation '{0}' of the repository '{1}' is not a NuGet-based publish location. Retry after setting the ScriptPublishLocation for repository '{1}' to a valid NuGet publishing endpoint using the Set-PSRepository cmdlet.\r\n        DynamicParameterHelpMessage=The dynamic parameter '{0}' is required for Find-Module and Install-Module when using the PackageManagement provider '{1}' and source location '{2}'. Please enter your value for the '{3}' dynamic parameter:\r\n        ProviderApiDebugMessage=In PowerShellGet Provider - '{0}'.\r\n        ModuleUninstallNotSupported=Module uninstallation is not supported. To remove a module, please delete the module folder.\r\n        FastPackageReference=The FastPackageReference is '{0}'.\r\n        PackageManagementProviderIsNotAvailable=The specified PackageManagement provider '{0}' is not available.\r\n        SpecifiedSourceName=Using the specified source names : '{0}'.\r\n        SpecifiedLocationAndOGP=The specified Location is '{0}' and PackageManagementProvider is '{1}'.\r\n        NoSourceNameIsSpecified=The -Repository parameter was not specified.  PowerShellGet will use all of the registered repositories.\r\n        GettingPackageManagementProviderObject=Getting the provider object for the PackageManagement Provider '{0}'.\r\n        InvalidInputObjectValue=Invalid value is specified for InputObject parameter.\r\n        SpecifiedInstallationScope=The installation scope is specified to be '{0}'.\r\n        SourceLocationValueForPSGalleryCannotBeChanged=The SourceLocation value for the PSGallery repository can not be changed.\r\n        PublishLocationValueForPSGalleryCannotBeChanged=The PublishLocation value for the PSGallery repository can not be changed.\r\n        SpecifiedProviderName=The specified PackageManagement provider name '{0}'.\r\n        ProviderNameNotSpecified=User did not specify the PackageManagement provider name, trying with the provider name '{0}'.\r\n        SpecifiedProviderNotAvailable=The specified PackageManagement provider '{0}' is not available.\r\n        SpecifiedProviderDoesnotSupportPSModules=The specified PackageManagement Provider '{0}' does not support PowerShell Modules. PackageManagement Providers must support the 'supports-powershell-modules' feature.\r\n        PollingPackageManagementProvidersForLocation=Polling available PackageManagement Providers to find one that can support the specified source location '{0}'.\r\n        PollingSingleProviderForLocation=Resolving the source location '{0}' with PackageManagement Provider '{1}'.\r\n        FoundProviderForLocation=The PackageManagement provider '{0}' supports the source location '{1}'.\r\n        SpecifiedLocationCannotBeRegistered=The specified location '{0}' cannot be registered.\r\n        RepositoryDetails=Repository details, Name = '{0}', Location = '{1}'; IsTrusted = '{2}'; IsRegistered = '{3}'.\r\n        NotSupportedPowerShellGetFormatVersion=The specified module '{0}' with PowerShellGetFormatVersion '{1}' is not supported by the current version of PowerShellGet. Get the latest version of the PowerShellGet module to install this module, '{2}'.\r\n        NotSupportedPowerShellGetFormatVersionScripts=The specified script '{0}' with PowerShellGetFormatVersion '{1}' is not supported by the current version of PowerShellGet. Get the latest version of the PowerShellGet module to install this script, '{2}'.\r\n        PathNotFound=Cannot find the path '{0}' because it does not exist.\r\n        ModuleIsNotTrusted=Untrusted module '{0}'.\r\n        ScriptIsNotTrusted=Untrusted script '{0}'.\r\n        SkippedModuleDependency=Because dependent module '{0}' was skipped in the module dependencies list, users might not know how to install it.\r\n        MissingExternallyManagedModuleDependency=The externally managed, dependent module '{0}' is not installed on this computer. To use the current module '{1}', ensure that its dependent module '{2}' is installed.\r\n        ExternallyManagedModuleDependencyIsInstalled=The externally managed, dependent module '{0}' is already installed on this computer.\r\n        ScriptMissingExternallyManagedModuleDependency=The externally managed, dependent module '{0}' is not installed on this computer. To use the current script '{1}', ensure that its dependent module '{2}' is installed.\r\n        ScriptMissingExternallyManagedScriptDependency=The externally managed, dependent module '{0}' is not installed on this computer. To use the current script '{1}', ensure that its dependent script '{2}' is installed.\r\n        ScriptExternallyManagedScriptDependencyIsInstalled=The externally managed, dependent script '{0}' is already installed on this computer.\r\n        UnableToResolveModuleDependency=PowerShellGet cannot resolve the module dependency '{0}' of the module '{1}' on the repository '{2}'. Verify that the dependent module '{3}' is available in the repository '{4}'. If this dependent module '{5}' is managed externally, add it to the ExternalModuleDependencies entry in the PSData section of the module manifest.\r\n        FindingModuleDependencies=Finding module dependencies for version '{1}' of the module '{0}' from repository '{2}'.\r\n        InstallingDependencyModule=Installing the dependency module '{0}' with version '{1}' for the module '{2}'.\r\n        InstallingDependencyScript=Installing the dependency script '{0}' with version '{1}' for the script '{2}'.\r\n        SavingDependencyModule=Saving the dependency module '{0}' with version '{1}' for the module '{2}'.\r\n        SavingDependencyScript=Saving the dependency script '{0}' with version '{1}' for the script '{2}'.\r\n        ModuleUninstallationSucceeded=Successfully uninstalled the module '{0}' from module base '{1}'.\r\n        ScriptUninstallationSucceeded=Successfully uninstalled the script '{0}' from script base '{1}'.\r\n        AdminPrivilegesRequiredForUninstall=You cannot uninstall the module '{0}' from '{1}' because Administrator rights are required to uninstall from that folder. Log on to the computer with an account that has Administrator rights, and then try again. You can also try running the Windows PowerShell session with elevated rights (Run as Administrator).\r\n        AdminPrivilegesRequiredForScriptUninstall=You cannot uninstall the script '{0}' from '{1}' because Administrator rights are required to uninstall from that folder. Log on to the computer with an account that has Administrator rights, and then try again. You can also try running the Windows PowerShell session with elevated rights (Run as Administrator).\r\n        ModuleUninstallationNotPossibleAsItIsNotInstalledUsingPowerShellGet=Module '{0}' was not installed on this computer by using either the PowerShellGet cmdlets or the PowerShellGet provider, so it cannot be uninstalled.\r\n        ScriptUninstallationNotPossibleAsItIsNotInstalledUsingPowerShellGet=Script '{0}' was not installed on this computer by using either the PowerShellGet cmdlets or the PowerShellGet provider, so it cannot be uninstalled.\r\n        UnableToUninstallModuleVersion=The module '{0}' of version '{1}' in module base folder '{2}' was installed without side-by-side version support. Some versions are installed in this module base with side-by-side version support. Uninstall other versions of this module before uninstalling the most current version.\r\n        UnableToUninstallAsOtherModulesNeedThisModule=The module '{0}' of version '{1}' in module base folder '{2}' cannot be uninstalled, because one or more other modules '{3}' are dependent on this module. Uninstall the modules that depend on this module before uninstalling module '{4}'.\r\n        UnableToUninstallAsOtherScriptsNeedThisScript=The script '{0}' of version '{1}' in script base folder '{2}' cannot be uninstalled, because one or more other scripts '{3}' are dependent on this script. Uninstall the scripts that depend on this script before uninstalling script '{4}'.\r\n        RepositoryIsNotTrusted=Untrusted repository\r\n        QueryInstallUntrustedPackage=You are installing the modules from an untrusted repository. If you trust this repository, change its InstallationPolicy value by running the Set-PSRepository cmdlet. Are you sure you want to install the modules from '{1}'?\r\n        QueryInstallUntrustedScriptPackage=You are installing the scripts from an untrusted repository. If you trust this repository, change its InstallationPolicy value by running the Set-PSRepository cmdlet. Are you sure you want to install the scripts from '{1}'?\r\n        QuerySaveUntrustedPackage=You are downloading the modules from an untrusted repository. If you trust this repository, change its InstallationPolicy value by running the Set-PSRepository cmdlet. Are you sure you want to download the modules from '{1}'?\r\n        QuerySaveUntrustedScriptPackage=You are downloading the scripts from an untrusted repository. If you trust this repository, change its InstallationPolicy value by running the Set-PSRepository cmdlet. Are you sure you want to download the scripts from '{1}'?\r\n        SourceNotFound=Unable to find repository '{0}'. Use Get-PSRepository to see all available repositories.\r\n        PSGalleryApiV2Deprecated=PowerShell Gallery v2 has been deprecated.  Please run 'Update-Module -Name PowerShellGet' to update to PowerShell Gallery v3.  For more information, please visit our website at 'https://www.powershellgallery.com'.\r\n        PSGalleryApiV2Discontinued=PowerShell Gallery v2 has been discontinued.  Please run 'Update-Module -Name PowerShellGet' to update to PowerShell Gallery v3.  For more information, please visit our website at 'https://www.powershellgallery.com'.\r\n        PowerShellGalleryUnavailable=PowerShell Gallery is currently unavailable.  Please try again later.\r\n        PowerShellGetModuleIsNotInstalledProperly=The PowerShellGet module was not installed properly. Be sure that only one instance or version of the PowerShellGet module is installed in the path '{0}'.\r\n        PowerShelLGetModuleGotUpdated=The PowerShellGet module was updated successfully. Restart the process to use the updated version of the PowerShellGet module.\r\n        TagsShouldBeIncludedInManifestFile=Tags are now supported in the module manifest file (.psd1). Update the module manifest file of module '{0}' in '{1}' with the newest tag changes. You can run Update-ModuleManifest -Tags to update the manifest with tags.\r\n        ReleaseNotesShouldBeIncludedInManifestFile=ReleaseNotes is now supported in the module manifest file (.psd1). Update the module manifest file of module '{0}' in '{1}' with the newest ReleaseNotes changes. You can run Update-ModuleManifest -ReleaseNotes to update the manifest with ReleaseNotes.\r\n        LicenseUriShouldBeIncludedInManifestFile=LicenseUri is now supported in the module manifest file (.psd1). Update the module manifest file of module '{0}' with the newest LicenseUri changes. You can run Update-ModuleManifest -LicenseUri to update the manifest with LicenseUri.\r\n        IconUriShouldBeIncludedInManifestFile=IconUri is now supported in the module manifest file (.psd1). Update the module manifest file of module '{0}' in '{1}' with the newest IconUri changes. You can run Update-ModuleManifest -IconUri to update the manifest with IconUri.\r\n        ProjectUriShouldBeIncludedInManifestFile=ProjectUri is now supported in the module manifest file (.psd1). Update the module manifest file of module '{0}' in '{1}' with the newest ProjectUri changes. You can run Update-ModuleManifest -ProjectUri to update the manifest with ProjectUri.\r\n        ShouldIncludeFunctionsToExport=This module '{0}' has exported functions. As a best practice, include exported functions in the module manifest file(.psd1). You can run Update-ModuleManifest -FunctionsToExport to update the manifest with ExportedFunctions field.\r\n        ShouldIncludeCmdletsToExport=This module '{0}' has exported cmdlets. As a best practice, include exported cmdlets in the module manifest file(.psd1). You can run Update-ModuleManifest -CmdletsToExport to update the manifest with ExportedCmdlets field.\r\n        ShouldIncludeDscResourcesToExport=This module '{0}' has exported DscResources. As a best practice, include exported DSC resources in the module manifest file(.psd1). If your PowerShell version is higher than 5.0, run Update-ModuleManifest -DscResourcesToExport to update the manifest with ExportedDscResources field.\r\n        UpdateModuleManifestPathCannotFound=Cannot load the manifest file '{0}' properly. Please specify the correct manifest path.\r\n        UpdatedModuleManifestNotValid=Cannot update the manifest file '{0}' because the manifest is not valid. Verify that the manifest file is valid, and then try again.'{1}'\r\n        ExportedDscResourcesNotSupportedOnLowerPowerShellVersion=The ExportedDscResources property is not supported in module manifests on PowerShell versions that are older than 5.0. Remove the value for the parameter 'DscResourcesToExport', and then try again.\r\n        CompatiblePSEditionsNotSupportedOnLowerPowerShellVersion=The CompatiblePSEditions property is not supported in module manifests on PowerShell versions that are older than 5.1. Remove the value for the parameter 'CompatiblePSEditions', and then try again.\r\n        ExternalModuleDependenciesNotSpecifiedInRequiredOrNestedModules='{0}' is listed in ExternalModuleDependencies, but it is not found in either the RequiredModules or NestedModules properties. Verify that this module is required for ExternalModuleDependencies, and then add it to NestedModules or RequiredModules.\r\n        TestModuleManifestFail=Cannot update the manifest properly. '{0}'\r\n        PackageManagementProvidersNotInModuleBaseFolder=PackageManagementProvider '{0}' is not found in the module base '{1}'. Verify that the PackageManagementProvider specified is within the module base.\r\n        UpdateManifestContentMessage=Update manifest file with new contents:\r\n        InvalidPackageManagementProviderValue=The PackageManagementProvider value cannot be '{0}'. Valid values for provider names include '{1}', and the default value for this parameter is '{2}'.\r\n        PowerShellGetUpdateIsNotSupportedOnLowerPSVersions=Self update of the PowerShellGet module is supported only in PowerShell 5.0 and newer releases. It is not supported in PowerShell 3.0 or 4.0.\r\n        ScriptVersionShouldBeGreaterThanGalleryVersion=Script '{0}' with version '{1}' cannot be published. The version must exceed the current version '{2}' that exists in the repository '{3}', or you must specify -Force.\r\n        ScriptVersionIsAlreadyAvailableInTheGallery=The script '{0}' with version '{1}' cannot be published as the current version '{2}' is already available in the repository '{3}'.\r\n        ScriptPrereleaseStringShouldBeGreaterThanGalleryPrereleaseString=Script '{0}' with version '{1}' and prerelease '{2}' cannot be published. The prerelease string must exceed the current prerelease string '{3}' that exists in the repository '{4}', or you must specify -Force.\r\n        ScriptParseError=The specified script file '{0}' has parse errors, try again after fixing the parse errors.\r\n        InvalidScriptToPublish=Script file '{0}' cannot be published because it does not have the required script metadata. Run Update-ScriptFileInfo -Path '{1}' to add the script metadata.\r\n        FailedToCreateCompressedScript=Failed to generate the compressed file for script '{0}'.\r\n        FailedToPublishScript=Failed to publish script '{0}': '{1}'.\r\n        PublishedScriptSuccessfully=Successfully published script '{0}' to the publish location '{1}'. Please allow few minutes for '{2}' to show up in the search results.\r\n        UnableToResolveScriptDependency=PowerShellGet cannot resolve the {0} dependency '{1}' of the script '{2}' on the repository '{3}'. Verify that the dependent {0} '{1}' is available in the repository '{3}'. If this dependent {0} '{1}' is managed externally, add it to the '{4}' entry in the script metadata.\r\n        InvalidVersion=Cannot convert value '{0}' to type 'System.Version'.\r\n        InvalidGuid=Cannot convert value '{0}' to type 'System.Guid'.\r\n        InvalidParameterValue=The specified value '{0}' for the parameter '{1}' is invalid. Ensure that it does not contain '<#' or '#>'.\r\n        MissingPSScriptInfo=PSScriptInfo is not specified in the script file '{0}'. You can use the Update-ScriptFileInfo with -Force or New-ScriptFileInfo cmdlet to add the PSScriptInfo to the script file.\r\n        MissingRequiredPSScriptInfoProperties=Script '{0}' is missing required metadata properties. Verify that the script file has Version, Guid, Description and Author properties. You can use the Update-ScriptFileInfo or New-ScriptFileInfo cmdlet to add or update the PSScriptInfo to the script file.\r\n        SkippedScriptDependency=Because dependent script '{0}' was skipped in the script dependencies list, users might not know how to install it.\r\n        SourceLocationPathsForModulesAndScriptsShouldBeEqual=SourceLocation '{0}' and ScriptSourceLocation '{1}' should be same for SMB Share or Local directory based repositories.\r\n        PublishLocationPathsForModulesAndScriptsShouldBeEqual=PublishLocation '{0}' and ScriptPublishLocation '{1}' should be same for SMB Share or Local directory based repositories.\r\n        SpecifiedNameIsAlearyUsed=The specified name '{0}' is already used for a different item on the specified repository '{1}'. Run '{2} -Name {0} -Repository {1}' to check whether the specified name '{0}' is already taken.\r\n        InvalidScriptFilePath=The script file path '{0}' is not valid. The value of the Path argument must resolve to a single file that has a '.ps1' extension. Change the value of the Path argument to point to a valid ps1 file, and then try again.\r\n        NuGetApiKeyIsRequiredForNuGetBasedGalleryService=NuGetApiKey is required for publishing a module or script file to the specified repository '{0}' whose publish location is '{1}'. Try again after specifying a valid value for the NuGetApiKey parameter. To get your API key, view your profile page.\r\n        ScriptFileExist=The specified script file '{0}' already exists.\r\n        InvalidEnvironmentVariableName=The specified environment variable name '{0}' exceeded the allowed limit of '{1}' characters.\r\n        PublishLocation=Publish Location:'{0}'.\r\n        ScriptPATHPromptCaption=PATH Environment Variable Change\r\n        ScriptPATHPromptQuery=Your system has not been configured with a default script installation path yet, which means you can only run a script by specifying the full path to the script file. This action places the script into the folder '{0}', and adds that folder to your PATH environment variable. Do you want to add the script installation path '{0}' to the PATH environment variable?\r\n        AddedScopePathToProcessSpecificPATHVariable=Added scripts installation location '{0}' for '{1}' scope to process specific PATH environment variable.\r\n        AddedScopePathToPATHVariable=Added scripts installation location '{0}' for '{1}' scope to PATH environment variable.\r\n        FilePathInFileListNotWithinModuleBase=Path '{0}' defined in FileList is not within module base '{1}'. Provide the correct FileList parameters and then try again.\r\n        ManifestFileReadWritePermissionDenied=The current user does not have read-write permissions for the file:'{0}'. Check the file permissions and then try again.\r\n        MissingTheRequiredPathOrPassThruParameter=The Path or PassThru parameter is required for creating the script file info. A new script file will be created with the script file info when the Path parameter is specified. Script file info will be returned if the PassThru parameter is specified. Try again after specifying the required parameter.\r\n        DescriptionParameterIsMissingForAddingTheScriptFileInfo=Description parameter is missing for adding the metadata to the script file. Try again after specifying the description.\r\n        UnableToAddPSScriptInfo=Unable to add PSScriptInfo to the script file '{0}'. You can use the New-ScriptFileInfo cmdlet to add the metadata to the existing script file.\r\n        RegisterVSTSFeedAsNuGetPackageSource=Publishing to a VSTS package management feed '{0}' requires it to be registered as a NuGet package source. Retry after adding this source '{0}' as NuGet package source by following the instructions specified at '{1}'\r\n        InvalidModuleAuthenticodeSignature=The module '{0}' cannot be installed or updated because the authenticode signature of the file '{1}' is not valid.\r\n        InvalidCatalogSignature=The module '{0}' cannot be installed because the catalog signature in '{1}' does not match the hash generated from the module.\r\n        AuthenticodeIssuerMismatch=Authenticode issuer '{0}' of the new module '{1}' with version '{2}' from root certificate authority '{3}' is not matching with the authenticode issuer '{4}' of the previously-installed module '{5}' with version '{6}' from root certificate authority '{7}'. If you still want to install or update, use -SkipPublisherCheck parameter.\r\n        ModuleCommandAlreadyAvailable=The following commands are already available on this system:'{0}'. This module '{1}' may override the existing commands. If you still want to install this module '{1}', use -AllowClobber parameter.\r\n        CatalogFileFound=Found the catalog file '{0}' in the module '{1}' contents.\r\n        CatalogFileNotFoundInAvailableModule=Catalog file '{0}' is not found in the contents of the previously-installed module '{1}' with the same name.\r\n        CatalogFileNotFoundInNewModule=Catalog file '{0}' is not found in the contents of the module '{1}' being installed.\r\n        ValidAuthenticodeSignature=Valid authenticode signature found in the catalog file '{0}' for the module '{1}'.\r\n        ValidAuthenticodeSignatureInFile=Valid authenticode signature found in the file '{0}' for the module '{1}'.\r\n        ValidatingCatalogSignature=Validating the '{0}' module files for catalog signing using the catalog file '{1}'.\r\n        AuthenticodeIssuerMatch=Authenticode issuer '{0}' of the new module '{1}' with version '{2}' matches with the authenticode issuer '{3}' of the previously-installed module '{4}' with version '{5}'.\r\n        ValidCatalogSignature=The catalog signature in '{0}' of the module '{1}' is valid and matches with the hash generated from the module contents.\r\n        SkippingPublisherCheck=Skipping the Publisher check for the version '{0}' of module '{1}'.\r\n        SourceModuleDetailsForPublisherValidation=For publisher validation, using the previously-installed module '{0}' with version '{1}' under '{2}' with publisher name '{3}' from root certificate authority '{4}'. Is this module signed by Microsoft: '{5}'.\r\n        NewModuleVersionDetailsForPublisherValidation=For publisher validation, current module '{0}' with version '{1}' with publisher name '{2}' from root certificate authority '{3}'. Is this module signed by Microsoft: '{4}'.\r\n        PublishersMatch=Publisher '{0}' of the new module '{1}' with version '{2}' matches with the publisher '{3}' of the previously-installed module '{4}' with version '{5}'. Both versions are signed with a Microsoft root certificate.\r\n        PublishersMismatch=A Microsoft-signed module named '{0}' with version '{1}' that was previously installed conflicts with the new module '{2}' from publisher '{3}' with version '{4}'. Installing the new module may result in system instability. If you still want to install or update, use -SkipPublisherCheck parameter.\r\n        ModuleIsNotCatalogSigned=The version '{0}' of the module '{1}' being installed is not catalog signed. Ensure that the version '{0}' of the module '{1}' has the catalog file '{2}' and signed with the same publisher '{3}' as the previously-installed module '{1}' with version '{4}' under the directory '{5}'. If you still want to install or update, use -SkipPublisherCheck parameter.\r\n        SentEnvironmentVariableChangeMessage=Successfully broadcasted the Environment variable changes.\r\n        UnableToSendEnvironmentVariableChangeMessage=Error in broadcasting the Environment variable changes.\r\n        LicenseUriNotSpecified='LicenseUri' is not specified. 'LicenseUri' must be provided when user license acceptance is required.\r\n        LicenseTxtNotFound=License.txt not Found. License.txt must be provided when user license acceptance is required.\r\n        LicenseTxtEmpty=License.txt is empty.\r\n        requireLicenseAcceptanceNotSupported=Require License Acceptance is not supported on Format version '{0}'.\r\n        AcceptanceLicenseQuery=Do you accept the license terms for module '{0}'.\r\n        ForceAcceptLicense=License Acceptance is required for module '{0}'. Please specify '-AcceptLicense' to perform this operation.\r\n        InvalidValueBoolean=The specified value '{0}' for the parameter '{1}' is invalid. It should be $true or $false.\r\n        UserDeclinedLicenseAcceptance=User declined license acceptance.\r\n        AcceptLicense=License Acceptance\r\n        RequiredScriptVersion=REQUIREDSCRIPTS: Required version of script '{0}' is '{1}'.\r\n        RequiredScriptVersoinFormat=<ScriptName>, <ScriptName>:<MinimumVersion>, <ScriptName>:[<RequiredVersion>], <ScriptName>:[<MinimumVersion>,<MaximumVersion>], <ScriptName>:[,<MaximumVersion>]\r\n        FailedToParseRequiredScripts=Cannot parse REQUIREDSCRIPTS '{0}'. Acceptable formats are: '{1}'.\r\n        FailedToParseRequiredScriptsVersion=Version format error: {0}, '{1}'. Acceptable formats are: '{2}'.\r\n        PublishersMismatchAsWarning=Module '{0}' version '{1}' published by '{2}' will be superceded by version '{3}' published by '{4}'. If you do not trust the new publisher, uninstall the module.\r\n        UnableToDownloadThePackage=The PackageManagement provider '{0}' is unable to download the package '{1}' version '{2}' to '{3}' path.\r\n        ValidatingTheModule=Validating the '{0}' module contents under '{1}' path.\r\n        ModuleValidationFailed=Unable to validate the '{0}' module contents under '{1}' path.\r\n        ValidatedModuleManifestFile=Test-ModuleManifest successfully validated the module manifest file '{0}'.\r\n        ValidateModuleAuthenticodeSignature=Validating the authenticode signature and publisher of the catalog file or module manifest file of the module '{0}'.\r\n        ValidateModuleCommandAlreadyAvailable=Checking for possible command collisions for the module '{0}' commands.\r\n        UnauthorizedAccessError=Access to the path '{0}' is denied.\r\n###PSLOC\r\n'@\r\n\r\n# SIG # Begin signature block\r\n# MIIjkgYJKoZIhvcNAQcCoIIjgzCCI38CAQExDzANBglghkgBZQMEAgEFADB5Bgor\r\n# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG\r\n# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAUMj4wb0r0V933\r\n# Kxwf6eV800i5N8GnGMPseytvd1lnEKCCDYEwggX/MIID56ADAgECAhMzAAABh3IX\r\n# chVZQMcJAAAAAAGHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD\r\n# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p\r\n# bmcgUENBIDIwMTEwHhcNMjAwMzA0MTgzOTQ3WhcNMjEwMzAzMTgzOTQ3WjB0MQsw\r\n# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u\r\n# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\r\n# AQDOt8kLc7P3T7MKIhouYHewMFmnq8Ayu7FOhZCQabVwBp2VS4WyB2Qe4TQBT8aB\r\n# znANDEPjHKNdPT8Xz5cNali6XHefS8i/WXtF0vSsP8NEv6mBHuA2p1fw2wB/F0dH\r\n# sJ3GfZ5c0sPJjklsiYqPw59xJ54kM91IOgiO2OUzjNAljPibjCWfH7UzQ1TPHc4d\r\n# weils8GEIrbBRb7IWwiObL12jWT4Yh71NQgvJ9Fn6+UhD9x2uk3dLj84vwt1NuFQ\r\n# itKJxIV0fVsRNR3abQVOLqpDugbr0SzNL6o8xzOHL5OXiGGwg6ekiXA1/2XXY7yV\r\n# Fc39tledDtZjSjNbex1zzwSXAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE\r\n# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUhov4ZyO96axkJdMjpzu2zVXOJcsw\r\n# UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1\r\n# ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDU4Mzg1MB8GA1UdIwQYMBaAFEhu\r\n# ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu\r\n# bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w\r\n# Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3\r\n# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx\r\n# MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAixmy\r\n# S6E6vprWD9KFNIB9G5zyMuIjZAOuUJ1EK/Vlg6Fb3ZHXjjUwATKIcXbFuFC6Wr4K\r\n# NrU4DY/sBVqmab5AC/je3bpUpjtxpEyqUqtPc30wEg/rO9vmKmqKoLPT37svc2NV\r\n# BmGNl+85qO4fV/w7Cx7J0Bbqk19KcRNdjt6eKoTnTPHBHlVHQIHZpMxacbFOAkJr\r\n# qAVkYZdz7ikNXTxV+GRb36tC4ByMNxE2DF7vFdvaiZP0CVZ5ByJ2gAhXMdK9+usx\r\n# zVk913qKde1OAuWdv+rndqkAIm8fUlRnr4saSCg7cIbUwCCf116wUJ7EuJDg0vHe\r\n# yhnCeHnBbyH3RZkHEi2ofmfgnFISJZDdMAeVZGVOh20Jp50XBzqokpPzeZ6zc1/g\r\n# yILNyiVgE+RPkjnUQshd1f1PMgn3tns2Cz7bJiVUaqEO3n9qRFgy5JuLae6UweGf\r\n# AeOo3dgLZxikKzYs3hDMaEtJq8IP71cX7QXe6lnMmXU/Hdfz2p897Zd+kU+vZvKI\r\n# 3cwLfuVQgK2RZ2z+Kc3K3dRPz2rXycK5XCuRZmvGab/WbrZiC7wJQapgBodltMI5\r\n# GMdFrBg9IeF7/rP4EqVQXeKtevTlZXjpuNhhjuR+2DMt/dWufjXpiW91bo3aH6Ea\r\n# jOALXmoxgltCp1K7hrS6gmsvj94cLRf50QQ4U8Qwggd6MIIFYqADAgECAgphDpDS\r\n# AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK\r\n# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0\r\n# IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0\r\n# ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla\r\n# MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS\r\n# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT\r\n# H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB\r\n# AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG\r\n# OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S\r\n# 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz\r\n# y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7\r\n# 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u\r\n# M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33\r\n# X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl\r\n# XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP\r\n# 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB\r\n# l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF\r\n# RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM\r\n# CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ\r\n# BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud\r\n# DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO\r\n# 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0\r\n# LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p\r\n# Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB\r\n# FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw\r\n# cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA\r\n# XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY\r\n# 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj\r\n# 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd\r\n# d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ\r\n# Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf\r\n# wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ\r\n# aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j\r\n# NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B\r\n# xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96\r\n# eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7\r\n# r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I\r\n# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVZzCCFWMCAQEwgZUwfjELMAkG\r\n# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx\r\n# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z\r\n# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAYdyF3IVWUDHCQAAAAABhzAN\r\n# BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor\r\n# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgLIu7f8le\r\n# gQ0ndTd8gyAEe0fnNBrhCsEUfHD+upEyb7owQgYKKwYBBAGCNwIBDDE0MDKgFIAS\r\n# AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN\r\n# BgkqhkiG9w0BAQEFAASCAQCWjkfbjU+QuaidvjCSfT9ZWmVRt7eVzD7wasyZEXwC\r\n# uPWX5GwoR4xPMYzA/ohAElfSdrP6HWH9R+2sdXnUCJK+7w6N9wbB+S9Da0r3UcHj\r\n# acV7JEftJK6ZwZ9EyebTgHv6Oa0xhuaRh/BINH4OhfIZEy3A2Lg4KhvNMjGKHTi2\r\n# agmGkKLUqySkyv48c/HCApLbZ3ugNqI06C284kostGCqpuSg6HRDcGPDzZSkT6l4\r\n# u1veNMmcpeGzd3NTNy5fkt8jQt3OUQ9NmfYN5nxh1BgDB1kyDm5lWMiZqFqlLS9T\r\n# sG/jgYnqnprYVqTa8rYsSdmn8y1idSkQ1M715PQlOYNuoYIS8TCCEu0GCisGAQQB\r\n# gjcDAwExghLdMIIS2QYJKoZIhvcNAQcCoIISyjCCEsYCAQMxDzANBglghkgBZQME\r\n# AgEFADCCAVUGCyqGSIb3DQEJEAEEoIIBRASCAUAwggE8AgEBBgorBgEEAYRZCgMB\r\n# MDEwDQYJYIZIAWUDBAIBBQAEIOjiV1RbUVB0CleqHpkpsACXwys4XtATfTNyD7Bu\r\n# Zv+1AgZfYPphXsEYEzIwMjAwOTIyMjIxOTUxLjg2N1owBIACAfSggdSkgdEwgc4x\r\n# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt\r\n# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1p\r\n# Y3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMg\r\n# VFNTIEVTTjowQTU2LUUzMjktNEQ0RDElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt\r\n# U3RhbXAgU2VydmljZaCCDkQwggT1MIID3aADAgECAhMzAAABJy9uo++RqBmoAAAA\r\n# AAEnMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo\r\n# aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y\r\n# cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw\r\n# MB4XDTE5MTIxOTAxMTQ1OVoXDTIxMDMxNzAxMTQ1OVowgc4xCzAJBgNVBAYTAlVT\r\n# MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK\r\n# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVy\r\n# YXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjowQTU2\r\n# LUUzMjktNEQ0RDElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vydmlj\r\n# ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPgB3nERnk6fS40vvWeD\r\n# 3HCgM9Ep4xTIQiPnJXE9E+HkZVtTsPemoOyhfNAyF95E/rUvXOVTUcJFL7Xb16jT\r\n# KPXONsCWY8DCixSDIiid6xa30TiEWVcIZRwiDlcx29D467OTav5rA1G6TwAEY5rQ\r\n# jhUHLrOoJgfJfakZq6IHjd+slI0/qlys7QIGakFk2OB6mh/ln/nS8G4kNRK6Do4g\r\n# xDtnBSFLNfhsSZlRSMDJwFvrZ2FCkaoexd7rKlUNOAAScY411IEqQeI1PwfRm3aW\r\n# bS8IvAfJPC2Ah2LrtP8sKn5faaU8epexje7vZfcZif/cbxgUKStJzqbdvTBNc93n\r\n# /Z8CAwEAAaOCARswggEXMB0GA1UdDgQWBBTl9JZVgF85MSRbYlOJXbhY022V8jAf\r\n# BgNVHSMEGDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8ETzBNMEugSaBH\r\n# hkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNU\r\n# aW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUF\r\n# BzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1RpbVN0\r\n# YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsG\r\n# AQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IBAQAKyo180VXHBqVnjZwQy7NlzXbo2+W5\r\n# qfHxR7ANV5RBkRkdGamkwUcDNL+DpHObFPJHa0oTeYKE0Zbl1MvvfS8RtGGdhGYG\r\n# CJf+BPd/gBCs4+dkZdjvOzNyuVuDPGlqQ5f7HS7iuQ/cCyGHcHYJ0nXVewF2Lk+J\r\n# lrWykHpTlLwPXmCpNR+gieItPi/UMF2RYTGwojW+yIVwNyMYnjFGUxEX5/DtJjRZ\r\n# mg7PBHMrENN2DgO6wBelp4ptyH2KK2EsWT+8jFCuoKv+eJby0QD55LN5f8SrUPRn\r\n# K86fh7aVOfCglQofo5ABZIGiDIrg4JsV4k6p0oBSIFOAcqRAhiH+1spCMIIGcTCC\r\n# BFmgAwIBAgIKYQmBKgAAAAAAAjANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMC\r\n# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV\r\n# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJv\r\n# b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMTAwNzAxMjEzNjU1WhcN\r\n# MjUwNzAxMjE0NjU1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv\r\n# bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0\r\n# aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCASIw\r\n# DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkdDbx3EYo6IOz8E5f1+n9plGt0\r\n# VBDVpQoAgoX77XxoSyxfxcPlYcJ2tz5mK1vwFVMnBDEfQRsalR3OCROOfGEwWbEw\r\n# RA/xYIiEVEMM1024OAizQt2TrNZzMFcmgqNFDdDq9UeBzb8kYDJYYEbyWEeGMoQe\r\n# dGFnkV+BVLHPk0ySwcSmXdFhE24oxhr5hoC732H8RsEnHSRnEnIaIYqvS2SJUGKx\r\n# Xf13Hz3wV3WsvYpCTUBR0Q+cBj5nf/VmwAOWRH7v0Ev9buWayrGo8noqCjHw2k4G\r\n# kbaICDXoeByw6ZnNPOcvRLqn9NxkvaQBwSAJk3jN/LzAyURdXhacAQVPIk0CAwEA\r\n# AaOCAeYwggHiMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBTVYzpcijGQ80N7\r\n# fEYbxTNoWoVtVTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMC\r\n# AYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvX\r\n# zpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20v\r\n# cGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYI\r\n# KwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5j\r\n# b20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDCBoAYDVR0g\r\n# AQH/BIGVMIGSMIGPBgkrBgEEAYI3LgMwgYEwPQYIKwYBBQUHAgEWMWh0dHA6Ly93\r\n# d3cubWljcm9zb2Z0LmNvbS9QS0kvZG9jcy9DUFMvZGVmYXVsdC5odG0wQAYIKwYB\r\n# BQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AUABvAGwAaQBjAHkAXwBTAHQAYQB0AGUA\r\n# bQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAAfmiFEN4sbgmD+BcQM9naOh\r\n# IW+z66bM9TG+zwXiqf76V20ZMLPCxWbJat/15/B4vceoniXj+bzta1RXCCtRgkQS\r\n# +7lTjMz0YBKKdsxAQEGb3FwX/1z5Xhc1mCRWS3TvQhDIr79/xn/yN31aPxzymXlK\r\n# kVIArzgPF/UveYFl2am1a+THzvbKegBvSzBEJCI8z+0DpZaPWSm8tv0E4XCfMkon\r\n# /VWvL/625Y4zu2JfmttXQOnxzplmkIz/amJ/3cVKC5Em4jnsGUpxY517IW3DnKOi\r\n# PPp/fZZqkHimbdLhnPkd/DjYlPTGpQqWhqS9nhquBEKDuLWAmyI4ILUl5WTs9/S/\r\n# fmNZJQ96LjlXdqJxqgaKD4kWumGnEcua2A5HmoDF0M2n0O99g/DhO3EJ3110mCII\r\n# YdqwUB5vvfHhAN/nMQekkzr3ZUd46PioSKv33nJ+YWtvd6mBy6cJrDm77MbL2IK0\r\n# cs0d9LiFAR6A+xuJKlQ5slvayA1VmXqHczsI5pgt6o3gMy4SKfXAL1QnIffIrE7a\r\n# KLixqduWsqdCosnPGUFN4Ib5KpqjEWYw07t0MkvfY3v1mYovG8chr1m1rtxEPJdQ\r\n# cdeh0sVV42neV8HR3jDA/czmTfsNv11P6Z0eGTgvvM9YBS7vDaBQNdrvCScc1bN+\r\n# NR4Iuto229Nfj950iEkSoYIC0jCCAjsCAQEwgfyhgdSkgdEwgc4xCzAJBgNVBAYT\r\n# AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD\r\n# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBP\r\n# cGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjow\r\n# QTU2LUUzMjktNEQ0RDElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy\r\n# dmljZaIjCgEBMAcGBSsOAwIaAxUAs5W4TmyDHMRM7iz6mgGojqvXHzOggYMwgYCk\r\n# fjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH\r\n# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD\r\n# Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIF\r\n# AOMUsu8wIhgPMjAyMDA5MjIyMTI5MTlaGA8yMDIwMDkyMzIxMjkxOVowdzA9Bgor\r\n# BgEEAYRZCgQBMS8wLTAKAgUA4xSy7wIBADAKAgEAAgIVPgIB/zAHAgEAAgIRtjAK\r\n# AgUA4xYEbwIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIB\r\n# AAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAEMD4esQRMLwQdhk\r\n# Co1zgvmclcwl3lYYpk1oMh1ndsU3+97Rt6FV3adS4Hezc/K94oQKjcxtMVzLzQhG\r\n# agM6XlqB31VD8n2nxVuaWD1yp2jm/0IvfL9nFMHJRhgANMiBdHqvqNrd86c/Kryq\r\n# sI0Ch0sOx9wg3BozzqQhmdNjf9c6MYIDDTCCAwkCAQEwgZMwfDELMAkGA1UEBhMC\r\n# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV\r\n# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRp\r\n# bWUtU3RhbXAgUENBIDIwMTACEzMAAAEnL26j75GoGagAAAAAAScwDQYJYIZIAWUD\r\n# BAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0B\r\n# CQQxIgQg6wLE4god37E/zRxYUqM58DbGQBLJxEvt6c6xU1jsZqYwgfoGCyqGSIb3\r\n# DQEJEAIvMYHqMIHnMIHkMIG9BCAbkuhLEoYdahb/BUyVszO2VDi6kB3MSaof/+8u\r\n# 7SM+IjCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u\r\n# MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp\r\n# b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB\r\n# Jy9uo++RqBmoAAAAAAEnMCIEIK4r6N3NISekswMCG1kSBJCCCePrlLDQWbMKz0wt\r\n# Lj6CMA0GCSqGSIb3DQEBCwUABIIBACY3cZHtQ2k6zfVG4NotND24Zp0mlZAFe4A+\r\n# BFDISaaIXS86mO142Y9Hkm9rAMBCIJbKB/Yj1yf1gbygqNCoJDHFxZbdmx5XbShg\r\n# PVfAQl00TuyQ86VYnFJtvdDODUnwuxErAFR1zyiGGBKYtQWhXNRmbhb1kRkWp5Fg\r\n# s9mwzZUoGI2UzXDtYb6HkjNIOMxCbWW/27YfCBnOkiP2tJMIU79R4xY4vwQeWkKW\r\n# dgtyHv+d7eBOd1aOi8HvqCstH6x06RC3DsYfZ/NbYSGuZpjSaSDDC7A1KvdPo6ti\r\n# UYayEGi9iXfqnAv4Iyzo3OWIN2M2iqepP2xwL8Ne2q1ImLpiZF0=\r\n# SIG # End signature block\r\n"
  },
  {
    "path": "src/PowerShell/ExternalModules/PowerShellGet/2.2.5/PSGetModuleInfo.xml",
    "content": "<Objs Version=\"1.1.0.1\" xmlns=\"http://schemas.microsoft.com/powershell/2004/04\">\r\n  <Obj RefId=\"0\">\r\n    <TN RefId=\"0\">\r\n      <T>Microsoft.PowerShell.Commands.PSRepositoryItemInfo</T>\r\n      <T>System.Management.Automation.PSCustomObject</T>\r\n      <T>System.Object</T>\r\n    </TN>\r\n    <MS>\r\n      <S N=\"Name\">PowerShellGet</S>\r\n      <S N=\"Version\">2.2.5</S>\r\n      <S N=\"Type\">Module</S>\r\n      <S N=\"Description\">PowerShell module with commands for discovering, installing, updating and publishing the PowerShell artifacts like Modules, DSC Resources, Role Capabilities and Scripts.</S>\r\n      <S N=\"Author\">Microsoft Corporation</S>\r\n      <Obj N=\"CompanyName\" RefId=\"1\">\r\n        <TN RefId=\"1\">\r\n          <T>System.Object[]</T>\r\n          <T>System.Array</T>\r\n          <T>System.Object</T>\r\n        </TN>\r\n        <LST>\r\n          <S>PowerShellTeam</S>\r\n          <S>alerickson</S>\r\n          <S>anamnavi</S>\r\n        </LST>\r\n      </Obj>\r\n      <S N=\"Copyright\">(c) Microsoft Corporation. All rights reserved.</S>\r\n      <DT N=\"PublishedDate\">2020-09-22T22:42:00-07:00</DT>\r\n      <Nil N=\"InstalledDate\" />\r\n      <Nil N=\"UpdatedDate\" />\r\n      <URI N=\"LicenseUri\">https://go.microsoft.com/fwlink/?LinkId=829061</URI>\r\n      <URI N=\"ProjectUri\">https://go.microsoft.com/fwlink/?LinkId=828955</URI>\r\n      <Nil N=\"IconUri\" />\r\n      <Obj N=\"Tags\" RefId=\"2\">\r\n        <TNRef RefId=\"1\" />\r\n        <LST>\r\n          <S>Packagemanagement</S>\r\n          <S>Provider</S>\r\n          <S>PSEdition_Desktop</S>\r\n          <S>PSEdition_Core</S>\r\n          <S>Linux</S>\r\n          <S>Mac</S>\r\n          <S>PSModule</S>\r\n        </LST>\r\n      </Obj>\r\n      <Obj N=\"Includes\" RefId=\"3\">\r\n        <TN RefId=\"2\">\r\n          <T>System.Collections.Hashtable</T>\r\n          <T>System.Object</T>\r\n        </TN>\r\n        <DCT>\r\n          <En>\r\n            <S N=\"Key\">Command</S>\r\n            <Obj N=\"Value\" RefId=\"4\">\r\n              <TNRef RefId=\"1\" />\r\n              <LST>\r\n                <S>Find-Command</S>\r\n                <S>Find-DSCResource</S>\r\n                <S>Find-Module</S>\r\n                <S>Find-RoleCapability</S>\r\n                <S>Find-Script</S>\r\n                <S>Get-CredsFromCredentialProvider</S>\r\n                <S>Get-InstalledModule</S>\r\n                <S>Get-InstalledScript</S>\r\n                <S>Get-PSRepository</S>\r\n                <S>Install-Module</S>\r\n                <S>Install-Script</S>\r\n                <S>New-ScriptFileInfo</S>\r\n                <S>Publish-Module</S>\r\n                <S>Publish-Script</S>\r\n                <S>Register-PSRepository</S>\r\n                <S>Save-Module</S>\r\n                <S>Save-Script</S>\r\n                <S>Set-PSRepository</S>\r\n                <S>Test-ScriptFileInfo</S>\r\n                <S>Uninstall-Module</S>\r\n                <S>Uninstall-Script</S>\r\n                <S>Unregister-PSRepository</S>\r\n                <S>Update-Module</S>\r\n                <S>Update-ModuleManifest</S>\r\n                <S>Update-Script</S>\r\n                <S>Update-ScriptFileInfo</S>\r\n              </LST>\r\n            </Obj>\r\n          </En>\r\n          <En>\r\n            <S N=\"Key\">Function</S>\r\n            <Obj N=\"Value\" RefId=\"5\">\r\n              <TNRef RefId=\"1\" />\r\n              <LST>\r\n                <S>Find-Command</S>\r\n                <S>Find-DSCResource</S>\r\n                <S>Find-Module</S>\r\n                <S>Find-RoleCapability</S>\r\n                <S>Find-Script</S>\r\n                <S>Get-CredsFromCredentialProvider</S>\r\n                <S>Get-InstalledModule</S>\r\n                <S>Get-InstalledScript</S>\r\n                <S>Get-PSRepository</S>\r\n                <S>Install-Module</S>\r\n                <S>Install-Script</S>\r\n                <S>New-ScriptFileInfo</S>\r\n                <S>Publish-Module</S>\r\n                <S>Publish-Script</S>\r\n                <S>Register-PSRepository</S>\r\n                <S>Save-Module</S>\r\n                <S>Save-Script</S>\r\n                <S>Set-PSRepository</S>\r\n                <S>Test-ScriptFileInfo</S>\r\n                <S>Uninstall-Module</S>\r\n                <S>Uninstall-Script</S>\r\n                <S>Unregister-PSRepository</S>\r\n                <S>Update-Module</S>\r\n                <S>Update-ModuleManifest</S>\r\n                <S>Update-Script</S>\r\n                <S>Update-ScriptFileInfo</S>\r\n              </LST>\r\n            </Obj>\r\n          </En>\r\n          <En>\r\n            <S N=\"Key\">Cmdlet</S>\r\n            <Obj N=\"Value\" RefId=\"6\">\r\n              <TNRef RefId=\"1\" />\r\n              <LST />\r\n            </Obj>\r\n          </En>\r\n          <En>\r\n            <S N=\"Key\">DscResource</S>\r\n            <Obj N=\"Value\" RefId=\"7\">\r\n              <TNRef RefId=\"1\" />\r\n              <LST>\r\n                <S>PSModule</S>\r\n                <S>PSRepository</S>\r\n              </LST>\r\n            </Obj>\r\n          </En>\r\n          <En>\r\n            <S N=\"Key\">Workflow</S>\r\n            <Ref N=\"Value\" RefId=\"6\" />\r\n          </En>\r\n          <En>\r\n            <S N=\"Key\">RoleCapability</S>\r\n            <Ref N=\"Value\" RefId=\"6\" />\r\n          </En>\r\n        </DCT>\r\n      </Obj>\r\n      <Nil N=\"PowerShellGetFormatVersion\" />\r\n      <S N=\"ReleaseNotes\">### 2.2.5_x000D__x000A_- Security patch for code injection bug_x000D__x000A__x000D__x000A_### 2.2.4.1_x000D__x000A_- Remove catalog file_x000D__x000A__x000D__x000A_### 2.2.3_x000D__x000A_- Update `HelpInfoUri` to point to the latest content (#560)_x000D__x000A_- Improve discovery of usable nuget.exe binary (Thanks bwright86!) (#558)_x000D__x000A__x000D__x000A_### 2.2.2_x000D__x000A_Bug Fix_x000D__x000A__x000D__x000A_- Update casing of DscResources output_x000D__x000A__x000D__x000A_### 2.2.1_x000D__x000A_Bug Fix_x000D__x000A__x000D__x000A_- Allow DscResources to work on case sensitive platforms (#521)_x000D__x000A_- Fix for failure to return credential provider when using private feeds (#521)_x000D__x000A__x000D__x000A_## 2.2_x000D__x000A_Bug Fix_x000D__x000A__x000D__x000A_- Fix for prompting for credentials when passing in -Credential parameter when using Register-PSRepository_x000D__x000A__x000D__x000A_## 2.1.5_x000D__x000A_New Features_x000D__x000A__x000D__x000A_- Add and remove nuget based repositories as a nuget source when nuget client tool is installed (#498)_x000D__x000A__x000D__x000A_Bug Fix_x000D__x000A__x000D__x000A_- Fix for 'Failed to publish module' error thrown when publishing modules (#497)_x000D__x000A__x000D__x000A_## 2.1.4_x000D__x000A_- Fixed hang while publishing some packages (#478)_x000D__x000A__x000D__x000A_## 2.1.3_x000D__x000A_New Features_x000D__x000A__x000D__x000A_- Added -Scope parameter to Update-Module (Thanks @lwajswaj!) (#471)_x000D__x000A_- Added -Exclude parameter to Publish-Module (Thanks @Benny1007!) (#191)_x000D__x000A_- Added -SkipAutomaticTags parameter to Publish-Module (Thanks @awickham10!) (#452)_x000D__x000A__x000D__x000A_Bug Fix_x000D__x000A__x000D__x000A_- Fixed issue with finding modules using macOS and .NET Core 3.0_x000D__x000A__x000D__x000A_## 2.1.2_x000D__x000A__x000D__x000A_New Feature_x000D__x000A__x000D__x000A_- Added support for registering repositories with special characters_x000D__x000A__x000D__x000A_## 2.1.1_x000D__x000A__x000D__x000A_- Fix DSC resource folder structure_x000D__x000A__x000D__x000A_## 2.1.0_x000D__x000A__x000D__x000A_Breaking Change_x000D__x000A__x000D__x000A_- Default installation scope for Update-Module and Update-Script has changed to match Install-Module and Install-Script. For Windows PowerShell (version 5.1 or below), the default scope is AllUsers when running in an elevated session, and CurrentUser at all other times._x000D__x000A_  For PowerShell version 6.0.0 and above, the default installation scope is always CurrentUser. (#421)_x000D__x000A__x000D__x000A_Bug Fixes_x000D__x000A__x000D__x000A_- Update-ModuleManifest no longer clears FunctionsToExport, AliasesToExport, nor NestModules (#415 &amp; #425) (Thanks @pougetat and @tnieto88!)_x000D__x000A_- Update-Module no longer changes repository URL (#407)_x000D__x000A_- Update-ModuleManifest no longer preprends 'PSGet_' to module name (#403) (Thanks @ThePoShWolf)_x000D__x000A_- Update-ModuleManifest now throws error and fails to update when provided invalid entries (#398) (Thanks @pougetat!)_x000D__x000A_- Ignore files no longer being included when uploading modules (#396)_x000D__x000A__x000D__x000A_New Features_x000D__x000A__x000D__x000A_- New DSC resource, PSRepository (#426) (Thanks @johlju!)_x000D__x000A_- Piping of PS respositories (#420)_x000D__x000A_- utf8 support for .nuspec (#419)_x000D__x000A__x000D__x000A_## 2.0.4_x000D__x000A__x000D__x000A_Bug Fix_x000D__x000A_* Remove PSGallery availability checks (#374)_x000D__x000A__x000D__x000A_## 2.0.3_x000D__x000A__x000D__x000A_Bug fixes and Improvements_x000D__x000A_* Fix CommandAlreadyAvailable error for PackageManagement module (#333)_x000D__x000A_* Remove trailing whitespace when value is not provided for Get-PSScriptInfoString (#337) (Thanks @thomasrayner)_x000D__x000A_* Expanded aliases for improved readability (#338) (Thanks @lazywinadmin)_x000D__x000A_* Improvements for Catalog tests (#343)_x000D__x000A_* Fix Update-ScriptInfoFile to preserve PrivateData (#346) (Thanks @tnieto88)_x000D__x000A_* Import modules with many commands faster (#351)_x000D__x000A__x000D__x000A_New Features_x000D__x000A_* Tab completion for -Repository parameter (#339) and for Publish-Module -Name (#359) (Thanks @matt9ucci)_x000D__x000A__x000D__x000A_## 2.0.1_x000D__x000A__x000D__x000A_Bug fixes_x000D__x000A_- Resolved Publish-Module doesn't report error but fails to publish module (#316)_x000D__x000A_- Resolved CommandAlreadyAvailable error while installing the latest version of PackageManagement module (#333)_x000D__x000A__x000D__x000A_## 2.0.0_x000D__x000A__x000D__x000A_Breaking Change_x000D__x000A_- Default installation scope for Install-Module, Install-Script, and Install-Package has changed. For Windows PowerShell (version 5.1 or below), the default scope is AllUsers when running in an elevated session, and CurrentUser at all other times._x000D__x000A_  For PowerShell version 6.0.0 and above, the default installation scope is always CurrentUser._x000D__x000A__x000D__x000A_## 1.6.7_x000D__x000A__x000D__x000A_Bug fixes_x000D__x000A_- Resolved Install/Save-Module error in PSCore 6.1.0-preview.4 on Ubuntu 18.04 OS (WSL/Azure) (#313)_x000D__x000A_- Updated error message in Save-Module cmdlet when the specified path is not accessible (#313)_x000D__x000A_- Added few additional verbose messages (#313)_x000D__x000A__x000D__x000A_## 1.6.6_x000D__x000A__x000D__x000A_Dependency Updates_x000D__x000A_* Add dependency on version 4.1.0 or newer of NuGet.exe_x000D__x000A_* Update NuGet.exe bootstrap URL to https://aka.ms/psget-nugetexe_x000D__x000A__x000D__x000A_Build and Code Cleanup Improvements_x000D__x000A_* Improved error handling in network connectivity tests._x000D__x000A__x000D__x000A_Bug fixes_x000D__x000A_- Change Update-ModuleManifest so that prefix is not added to CmdletsToExport._x000D__x000A_- Change Update-ModuleManifest so that parameters will not reset to default values._x000D__x000A_- Specify AllowPrereleseVersions provider option only when AllowPrerelease is specified on the PowerShellGet cmdlets._x000D__x000A__x000D__x000A_## 1.6.5_x000D__x000A__x000D__x000A_New features_x000D__x000A_* Allow Pester/PSReadline installation when signed by non-Microsoft certificate (#258)_x000D__x000A_  - Whitelist installation of non-Microsoft signed Pester and PSReadline over Microsoft signed Pester and PSReadline._x000D__x000A__x000D__x000A_Build and Code Cleanup Improvements_x000D__x000A_* Splitting of functions (#229) (Thanks @Benny1007)_x000D__x000A_  - Moves private functions into respective private folder._x000D__x000A_  - Moves public functions as defined in PSModule.psd1 into respective public folder._x000D__x000A_  - Removes all functions from PSModule.psm1 file._x000D__x000A_  - Dot sources the functions from PSModule.psm1 file._x000D__x000A_  - Uses Export-ModuleMember to export the public functions from PSModule.psm1 file._x000D__x000A__x000D__x000A_* Add build step to construct a single .psm1 file (#242) (Thanks @Benny1007)_x000D__x000A_  - Merged public and private functions into one .psm1 file to increase load time performance._x000D__x000A__x000D__x000A_Bug fixes_x000D__x000A_- Fix null parameter error caused by MinimumVersion in Publish-PackageUtility (#201)_x000D__x000A_- Change .ExternalHelp link from PSGet.psm1-help.xml to PSModule-help.xml in PSModule.psm1 file (#215)_x000D__x000A_- Change Publish-* to allow version comparison instead of string comparison (#219)_x000D__x000A_- Ensure Get-InstalledScript -RequiredVersion works when versions have a leading 0 (#260)_x000D__x000A_- Add positional path to Save-Module and Save-Script (#264, #266)_x000D__x000A_- Ensure that Get-AuthenticodePublisher verifies publisher and that installing or updating a module checks for approprite catalog signature (#272)_x000D__x000A_- Update HelpInfoURI to 'http://go.microsoft.com/fwlink/?linkid=855963' (#274)_x000D__x000A__x000D__x000A__x000D__x000A_## 1.6.0_x000D__x000A__x000D__x000A_New features_x000D__x000A_* Prerelease Version Support (#185)_x000D__x000A_  - Implemented prerelease versions functionality in PowerShellGet cmdlets._x000D__x000A_  - Enables publishing, discovering, and installing the prerelease versions of modules and scripts from the PowerShell Gallery._x000D__x000A_  - [Documentation](https://docs.microsoft.com/en-us/powershell/gallery/psget/module/PrereleaseModule)_x000D__x000A__x000D__x000A_* Enabled publish cmdlets on PWSH and Nano Server (#196)_x000D__x000A_  - Dotnet command version 2.0.0 or newer should be installed by the user prior to using the publish cmdlets on PWSH and Windows Nano Server._x000D__x000A_  - Users can install the dotnet command by following the instructions specified at https://aka.ms/dotnet-install-script._x000D__x000A_  - On Windows, users can install the dotnet command by running *Invoke-WebRequest -Uri 'https://dot.net/v1/dotnet-install.ps1' -OutFile '.\\dotnet-install.ps1'; &amp; '.\\dotnet-install.ps1' -Channel Current -Version '2.0.0'*_x000D__x000A_  - Publish cmdlets on Windows PowerShell supports using the dotnet command for publishing operations._x000D__x000A__x000D__x000A_Breaking Change_x000D__x000A_- PWSH: Changed the installation location of AllUsers scope to the parent of $PSHOME instead of $PSHOME. It is the SHARED_MODULES folder on PWSH._x000D__x000A__x000D__x000A_Bug fixes_x000D__x000A_- Update HelpInfoURI to 'https://go.microsoft.com/fwlink/?linkid=855963' (#195)_x000D__x000A_- Ensure MyDocumentsPSPath path is correct (#179) (Thanks @lwsrbrts)_x000D__x000A__x000D__x000A__x000D__x000A_## 1.5.0.0_x000D__x000A__x000D__x000A_New features_x000D__x000A_* Added support for modules requiring license acceptance (#150)_x000D__x000A_  - [Documentation](https://docs.microsoft.com/en-us/powershell/gallery/psget/module/RequireLicenseAcceptance)_x000D__x000A__x000D__x000A_* Added version for REQUIREDSCRIPTS (#162)_x000D__x000A_  - Enabled following scenarios for REQUIREDSCRIPTS_x000D__x000A_    - [1.0] - RequiredVersion_x000D__x000A_    - [1.0,2.0] - Min and Max Version_x000D__x000A_    - (,1.0] - Max Version_x000D__x000A_    - 1.0 - Min Version_x000D__x000A__x000D__x000A_Bug fixes_x000D__x000A_* Fixed empty version value in nuspec (#157)_x000D__x000A__x000D__x000A__x000D__x000A_## 1.1.3.2_x000D__x000A_* Disabled PowerShellGet Telemetry on PS Core as PowerShell Telemetry APIs got removed in PowerShell Core beta builds. (#153)_x000D__x000A_* Fixed for DateTime format serialization issue. (#141)_x000D__x000A_* Update-ModuleManifest should add ExternalModuleDependencies value as a collection. (#129)_x000D__x000A__x000D__x000A_## 1.1.3.1_x000D__x000A__x000D__x000A_New features_x000D__x000A_* Added `PrivateData` field to ScriptFileInfo. (#119)_x000D__x000A__x000D__x000A_Bug fixes_x000D__x000A__x000D__x000A_## 1.1.2.0_x000D__x000A__x000D__x000A_Bug fixes_x000D__x000A__x000D__x000A_## 1.1.1.0_x000D__x000A__x000D__x000A_Bug fixes_x000D__x000A__x000D__x000A_## 1.1.0.0_x000D__x000A__x000D__x000A_* Initial release from GitHub._x000D__x000A_* PowerShellCore support._x000D__x000A__x000D__x000A_## For full history of release notes see changelog:_x000D__x000A_https://github.com/PowerShell/PowerShellGet/blob/master/CHANGELOG.md</S>\r\n      <Obj N=\"Dependencies\" RefId=\"8\">\r\n        <TNRef RefId=\"1\" />\r\n        <LST>\r\n          <Obj RefId=\"9\">\r\n            <TN RefId=\"3\">\r\n              <T>System.Collections.Specialized.OrderedDictionary</T>\r\n              <T>System.Object</T>\r\n            </TN>\r\n            <DCT>\r\n              <En>\r\n                <S N=\"Key\">Name</S>\r\n                <S N=\"Value\">PackageManagement</S>\r\n              </En>\r\n              <En>\r\n                <S N=\"Key\">MinimumVersion</S>\r\n                <S N=\"Value\">1.4.4</S>\r\n              </En>\r\n              <En>\r\n                <S N=\"Key\">CanonicalId</S>\r\n                <S N=\"Value\">nuget:PackageManagement/1.4.4</S>\r\n              </En>\r\n            </DCT>\r\n          </Obj>\r\n        </LST>\r\n      </Obj>\r\n      <S N=\"RepositorySourceLocation\">https://www.powershellgallery.com/api/v2</S>\r\n      <S N=\"Repository\">PSGallery</S>\r\n      <S N=\"PackageManagementProvider\">NuGet</S>\r\n      <Obj N=\"AdditionalMetadata\" RefId=\"10\">\r\n        <TN RefId=\"4\">\r\n          <T>System.Management.Automation.PSCustomObject</T>\r\n          <T>System.Object</T>\r\n        </TN>\r\n        <MS>\r\n          <S N=\"copyright\">(c) Microsoft Corporation. All rights reserved.</S>\r\n          <S N=\"description\">PowerShell module with commands for discovering, installing, updating and publishing the PowerShell artifacts like Modules, DSC Resources, Role Capabilities and Scripts.</S>\r\n          <S N=\"requireLicenseAcceptance\">False</S>\r\n          <S N=\"releaseNotes\">### 2.2.5_x000D__x000A_- Security patch for code injection bug_x000D__x000A__x000D__x000A_### 2.2.4.1_x000D__x000A_- Remove catalog file_x000D__x000A__x000D__x000A_### 2.2.3_x000D__x000A_- Update `HelpInfoUri` to point to the latest content (#560)_x000D__x000A_- Improve discovery of usable nuget.exe binary (Thanks bwright86!) (#558)_x000D__x000A__x000D__x000A_### 2.2.2_x000D__x000A_Bug Fix_x000D__x000A__x000D__x000A_- Update casing of DscResources output_x000D__x000A__x000D__x000A_### 2.2.1_x000D__x000A_Bug Fix_x000D__x000A__x000D__x000A_- Allow DscResources to work on case sensitive platforms (#521)_x000D__x000A_- Fix for failure to return credential provider when using private feeds (#521)_x000D__x000A__x000D__x000A_## 2.2_x000D__x000A_Bug Fix_x000D__x000A__x000D__x000A_- Fix for prompting for credentials when passing in -Credential parameter when using Register-PSRepository_x000D__x000A__x000D__x000A_## 2.1.5_x000D__x000A_New Features_x000D__x000A__x000D__x000A_- Add and remove nuget based repositories as a nuget source when nuget client tool is installed (#498)_x000D__x000A__x000D__x000A_Bug Fix_x000D__x000A__x000D__x000A_- Fix for 'Failed to publish module' error thrown when publishing modules (#497)_x000D__x000A__x000D__x000A_## 2.1.4_x000D__x000A_- Fixed hang while publishing some packages (#478)_x000D__x000A__x000D__x000A_## 2.1.3_x000D__x000A_New Features_x000D__x000A__x000D__x000A_- Added -Scope parameter to Update-Module (Thanks @lwajswaj!) (#471)_x000D__x000A_- Added -Exclude parameter to Publish-Module (Thanks @Benny1007!) (#191)_x000D__x000A_- Added -SkipAutomaticTags parameter to Publish-Module (Thanks @awickham10!) (#452)_x000D__x000A__x000D__x000A_Bug Fix_x000D__x000A__x000D__x000A_- Fixed issue with finding modules using macOS and .NET Core 3.0_x000D__x000A__x000D__x000A_## 2.1.2_x000D__x000A__x000D__x000A_New Feature_x000D__x000A__x000D__x000A_- Added support for registering repositories with special characters_x000D__x000A__x000D__x000A_## 2.1.1_x000D__x000A__x000D__x000A_- Fix DSC resource folder structure_x000D__x000A__x000D__x000A_## 2.1.0_x000D__x000A__x000D__x000A_Breaking Change_x000D__x000A__x000D__x000A_- Default installation scope for Update-Module and Update-Script has changed to match Install-Module and Install-Script. For Windows PowerShell (version 5.1 or below), the default scope is AllUsers when running in an elevated session, and CurrentUser at all other times._x000D__x000A_  For PowerShell version 6.0.0 and above, the default installation scope is always CurrentUser. (#421)_x000D__x000A__x000D__x000A_Bug Fixes_x000D__x000A__x000D__x000A_- Update-ModuleManifest no longer clears FunctionsToExport, AliasesToExport, nor NestModules (#415 &amp; #425) (Thanks @pougetat and @tnieto88!)_x000D__x000A_- Update-Module no longer changes repository URL (#407)_x000D__x000A_- Update-ModuleManifest no longer preprends 'PSGet_' to module name (#403) (Thanks @ThePoShWolf)_x000D__x000A_- Update-ModuleManifest now throws error and fails to update when provided invalid entries (#398) (Thanks @pougetat!)_x000D__x000A_- Ignore files no longer being included when uploading modules (#396)_x000D__x000A__x000D__x000A_New Features_x000D__x000A__x000D__x000A_- New DSC resource, PSRepository (#426) (Thanks @johlju!)_x000D__x000A_- Piping of PS respositories (#420)_x000D__x000A_- utf8 support for .nuspec (#419)_x000D__x000A__x000D__x000A_## 2.0.4_x000D__x000A__x000D__x000A_Bug Fix_x000D__x000A_* Remove PSGallery availability checks (#374)_x000D__x000A__x000D__x000A_## 2.0.3_x000D__x000A__x000D__x000A_Bug fixes and Improvements_x000D__x000A_* Fix CommandAlreadyAvailable error for PackageManagement module (#333)_x000D__x000A_* Remove trailing whitespace when value is not provided for Get-PSScriptInfoString (#337) (Thanks @thomasrayner)_x000D__x000A_* Expanded aliases for improved readability (#338) (Thanks @lazywinadmin)_x000D__x000A_* Improvements for Catalog tests (#343)_x000D__x000A_* Fix Update-ScriptInfoFile to preserve PrivateData (#346) (Thanks @tnieto88)_x000D__x000A_* Import modules with many commands faster (#351)_x000D__x000A__x000D__x000A_New Features_x000D__x000A_* Tab completion for -Repository parameter (#339) and for Publish-Module -Name (#359) (Thanks @matt9ucci)_x000D__x000A__x000D__x000A_## 2.0.1_x000D__x000A__x000D__x000A_Bug fixes_x000D__x000A_- Resolved Publish-Module doesn't report error but fails to publish module (#316)_x000D__x000A_- Resolved CommandAlreadyAvailable error while installing the latest version of PackageManagement module (#333)_x000D__x000A__x000D__x000A_## 2.0.0_x000D__x000A__x000D__x000A_Breaking Change_x000D__x000A_- Default installation scope for Install-Module, Install-Script, and Install-Package has changed. For Windows PowerShell (version 5.1 or below), the default scope is AllUsers when running in an elevated session, and CurrentUser at all other times._x000D__x000A_  For PowerShell version 6.0.0 and above, the default installation scope is always CurrentUser._x000D__x000A__x000D__x000A_## 1.6.7_x000D__x000A__x000D__x000A_Bug fixes_x000D__x000A_- Resolved Install/Save-Module error in PSCore 6.1.0-preview.4 on Ubuntu 18.04 OS (WSL/Azure) (#313)_x000D__x000A_- Updated error message in Save-Module cmdlet when the specified path is not accessible (#313)_x000D__x000A_- Added few additional verbose messages (#313)_x000D__x000A__x000D__x000A_## 1.6.6_x000D__x000A__x000D__x000A_Dependency Updates_x000D__x000A_* Add dependency on version 4.1.0 or newer of NuGet.exe_x000D__x000A_* Update NuGet.exe bootstrap URL to https://aka.ms/psget-nugetexe_x000D__x000A__x000D__x000A_Build and Code Cleanup Improvements_x000D__x000A_* Improved error handling in network connectivity tests._x000D__x000A__x000D__x000A_Bug fixes_x000D__x000A_- Change Update-ModuleManifest so that prefix is not added to CmdletsToExport._x000D__x000A_- Change Update-ModuleManifest so that parameters will not reset to default values._x000D__x000A_- Specify AllowPrereleseVersions provider option only when AllowPrerelease is specified on the PowerShellGet cmdlets._x000D__x000A__x000D__x000A_## 1.6.5_x000D__x000A__x000D__x000A_New features_x000D__x000A_* Allow Pester/PSReadline installation when signed by non-Microsoft certificate (#258)_x000D__x000A_  - Whitelist installation of non-Microsoft signed Pester and PSReadline over Microsoft signed Pester and PSReadline._x000D__x000A__x000D__x000A_Build and Code Cleanup Improvements_x000D__x000A_* Splitting of functions (#229) (Thanks @Benny1007)_x000D__x000A_  - Moves private functions into respective private folder._x000D__x000A_  - Moves public functions as defined in PSModule.psd1 into respective public folder._x000D__x000A_  - Removes all functions from PSModule.psm1 file._x000D__x000A_  - Dot sources the functions from PSModule.psm1 file._x000D__x000A_  - Uses Export-ModuleMember to export the public functions from PSModule.psm1 file._x000D__x000A__x000D__x000A_* Add build step to construct a single .psm1 file (#242) (Thanks @Benny1007)_x000D__x000A_  - Merged public and private functions into one .psm1 file to increase load time performance._x000D__x000A__x000D__x000A_Bug fixes_x000D__x000A_- Fix null parameter error caused by MinimumVersion in Publish-PackageUtility (#201)_x000D__x000A_- Change .ExternalHelp link from PSGet.psm1-help.xml to PSModule-help.xml in PSModule.psm1 file (#215)_x000D__x000A_- Change Publish-* to allow version comparison instead of string comparison (#219)_x000D__x000A_- Ensure Get-InstalledScript -RequiredVersion works when versions have a leading 0 (#260)_x000D__x000A_- Add positional path to Save-Module and Save-Script (#264, #266)_x000D__x000A_- Ensure that Get-AuthenticodePublisher verifies publisher and that installing or updating a module checks for approprite catalog signature (#272)_x000D__x000A_- Update HelpInfoURI to 'http://go.microsoft.com/fwlink/?linkid=855963' (#274)_x000D__x000A__x000D__x000A__x000D__x000A_## 1.6.0_x000D__x000A__x000D__x000A_New features_x000D__x000A_* Prerelease Version Support (#185)_x000D__x000A_  - Implemented prerelease versions functionality in PowerShellGet cmdlets._x000D__x000A_  - Enables publishing, discovering, and installing the prerelease versions of modules and scripts from the PowerShell Gallery._x000D__x000A_  - [Documentation](https://docs.microsoft.com/en-us/powershell/gallery/psget/module/PrereleaseModule)_x000D__x000A__x000D__x000A_* Enabled publish cmdlets on PWSH and Nano Server (#196)_x000D__x000A_  - Dotnet command version 2.0.0 or newer should be installed by the user prior to using the publish cmdlets on PWSH and Windows Nano Server._x000D__x000A_  - Users can install the dotnet command by following the instructions specified at https://aka.ms/dotnet-install-script._x000D__x000A_  - On Windows, users can install the dotnet command by running *Invoke-WebRequest -Uri 'https://dot.net/v1/dotnet-install.ps1' -OutFile '.\\dotnet-install.ps1'; &amp; '.\\dotnet-install.ps1' -Channel Current -Version '2.0.0'*_x000D__x000A_  - Publish cmdlets on Windows PowerShell supports using the dotnet command for publishing operations._x000D__x000A__x000D__x000A_Breaking Change_x000D__x000A_- PWSH: Changed the installation location of AllUsers scope to the parent of $PSHOME instead of $PSHOME. It is the SHARED_MODULES folder on PWSH._x000D__x000A__x000D__x000A_Bug fixes_x000D__x000A_- Update HelpInfoURI to 'https://go.microsoft.com/fwlink/?linkid=855963' (#195)_x000D__x000A_- Ensure MyDocumentsPSPath path is correct (#179) (Thanks @lwsrbrts)_x000D__x000A__x000D__x000A__x000D__x000A_## 1.5.0.0_x000D__x000A__x000D__x000A_New features_x000D__x000A_* Added support for modules requiring license acceptance (#150)_x000D__x000A_  - [Documentation](https://docs.microsoft.com/en-us/powershell/gallery/psget/module/RequireLicenseAcceptance)_x000D__x000A__x000D__x000A_* Added version for REQUIREDSCRIPTS (#162)_x000D__x000A_  - Enabled following scenarios for REQUIREDSCRIPTS_x000D__x000A_    - [1.0] - RequiredVersion_x000D__x000A_    - [1.0,2.0] - Min and Max Version_x000D__x000A_    - (,1.0] - Max Version_x000D__x000A_    - 1.0 - Min Version_x000D__x000A__x000D__x000A_Bug fixes_x000D__x000A_* Fixed empty version value in nuspec (#157)_x000D__x000A__x000D__x000A__x000D__x000A_## 1.1.3.2_x000D__x000A_* Disabled PowerShellGet Telemetry on PS Core as PowerShell Telemetry APIs got removed in PowerShell Core beta builds. (#153)_x000D__x000A_* Fixed for DateTime format serialization issue. (#141)_x000D__x000A_* Update-ModuleManifest should add ExternalModuleDependencies value as a collection. (#129)_x000D__x000A__x000D__x000A_## 1.1.3.1_x000D__x000A__x000D__x000A_New features_x000D__x000A_* Added `PrivateData` field to ScriptFileInfo. (#119)_x000D__x000A__x000D__x000A_Bug fixes_x000D__x000A__x000D__x000A_## 1.1.2.0_x000D__x000A__x000D__x000A_Bug fixes_x000D__x000A__x000D__x000A_## 1.1.1.0_x000D__x000A__x000D__x000A_Bug fixes_x000D__x000A__x000D__x000A_## 1.1.0.0_x000D__x000A__x000D__x000A_* Initial release from GitHub._x000D__x000A_* PowerShellCore support._x000D__x000A__x000D__x000A_## For full history of release notes see changelog:_x000D__x000A_https://github.com/PowerShell/PowerShellGet/blob/master/CHANGELOG.md</S>\r\n          <S N=\"isLatestVersion\">True</S>\r\n          <S N=\"isAbsoluteLatestVersion\">False</S>\r\n          <S N=\"versionDownloadCount\">65804037</S>\r\n          <S N=\"downloadCount\">114539696</S>\r\n          <S N=\"packageSize\">270249</S>\r\n          <S N=\"published\">9/22/2020 10:42:00 PM -07:00</S>\r\n          <S N=\"created\">9/22/2020 10:42:00 PM -07:00</S>\r\n          <S N=\"lastUpdated\">3/21/2023 6:34:18 PM -07:00</S>\r\n          <S N=\"tags\">Packagemanagement Provider PSEdition_Desktop PSEdition_Core Linux Mac PSModule</S>\r\n          <S N=\"developmentDependency\">False</S>\r\n          <S N=\"updated\">2023-03-21T18:34:18Z</S>\r\n          <S N=\"NormalizedVersion\">2.2.5</S>\r\n          <S N=\"Authors\">Microsoft Corporation</S>\r\n          <S N=\"IsPrerelease\">false</S>\r\n          <S N=\"ItemType\">Module</S>\r\n          <S N=\"FileList\">PowerShellGet.nuspec|PowerShellGet.psd1|PSGet.Format.ps1xml|PSGet.Resource.psd1|PSModule.psm1|DscResources\\MSFT_PSModule\\MSFT_PSModule.psm1|DscResources\\MSFT_PSModule\\MSFT_PSModule.schema.mfl|DscResources\\MSFT_PSModule\\MSFT_PSModule.schema.mof|DscResources\\MSFT_PSModule\\en-US\\MSFT_PSModule.strings.psd1|DscResources\\MSFT_PSRepository\\MSFT_PSRepository.psm1|DscResources\\MSFT_PSRepository\\MSFT_PSRepository.schema.mfl|DscResources\\MSFT_PSRepository\\MSFT_PSRepository.schema.mof|DscResources\\MSFT_PSRepository\\en-US\\MSFT_PSRepository.strings.psd1|en-US\\PSGet.Resource.psd1|Modules\\PowerShellGet.LocalizationHelper\\PowerShellGet.LocalizationHelper.psm1|Modules\\PowerShellGet.ResourceHelper\\PowerShellGet.ResourceHelper.psm1|Modules\\PowerShellGet.ResourceHelper\\en-US\\PowerShellGet.ResourceHelper.strings.psd1</S>\r\n          <S N=\"Functions\">Find-Command Find-DSCResource Find-Module Find-RoleCapability Find-Script Get-CredsFromCredentialProvider Get-InstalledModule Get-InstalledScript Get-PSRepository Install-Module Install-Script New-ScriptFileInfo Publish-Module Publish-Script Register-PSRepository Save-Module Save-Script Set-PSRepository Test-ScriptFileInfo Uninstall-Module Uninstall-Script Unregister-PSRepository Update-Module Update-ModuleManifest Update-Script Update-ScriptFileInfo</S>\r\n          <S N=\"DscResources\">PSModule PSRepository</S>\r\n          <S N=\"GUID\">1d73a601-4a6c-43c5-ba3f-619b18bbb404</S>\r\n          <S N=\"PowerShellVersion\">3.0</S>\r\n          <S N=\"CompanyName\">Microsoft Corporation</S>\r\n        </MS>\r\n      </Obj>\r\n      <S N=\"InstalledLocation\">D:\\mspkg\\src\\PowerShell\\ExternalModules\\PowerShellGet\\2.2.5</S>\r\n    </MS>\r\n  </Obj>\r\n</Objs>\r\n"
  },
  {
    "path": "src/PowerShell/ExternalModules/PowerShellGet/2.2.5/PowerShellGet.psd1",
    "content": "@{\r\n    RootModule        = 'PSModule.psm1'\r\n    ModuleVersion     = '2.2.5'\r\n    GUID              = '1d73a601-4a6c-43c5-ba3f-619b18bbb404'\r\n    Author            = 'Microsoft Corporation'\r\n    CompanyName       = 'Microsoft Corporation'\r\n    Copyright         = '(c) Microsoft Corporation. All rights reserved.'\r\n    Description       = 'PowerShell module with commands for discovering, installing, updating and publishing the PowerShell artifacts like Modules, DSC Resources, Role Capabilities and Scripts.'\r\n    PowerShellVersion = '3.0'\r\n    FormatsToProcess  = 'PSGet.Format.ps1xml'\r\nFunctionsToExport = @(\n\t'Find-Command',\n\t'Find-DSCResource',\n\t'Find-Module',\n\t'Find-RoleCapability',\n\t'Find-Script',\n\t'Get-CredsFromCredentialProvider',\n\t'Get-InstalledModule',\n\t'Get-InstalledScript',\n\t'Get-PSRepository',\n\t'Install-Module',\n\t'Install-Script',\n\t'New-ScriptFileInfo',\n\t'Publish-Module',\n\t'Publish-Script',\n\t'Register-PSRepository',\n\t'Save-Module',\n\t'Save-Script',\n\t'Set-PSRepository',\n\t'Test-ScriptFileInfo',\n\t'Uninstall-Module',\n\t'Uninstall-Script',\n\t'Unregister-PSRepository',\n\t'Update-Module',\n\t'Update-ModuleManifest',\n\t'Update-Script',\n\t'Update-ScriptFileInfo')\n\r\n    VariablesToExport = 'PSGetPath'\r\n    AliasesToExport   = @('inmo', 'fimo', 'upmo', 'pumo')\r\n    FileList          = @('PSModule.psm1',\r\n        'PSGet.Format.ps1xml',\r\n        'PSGet.Resource.psd1')\r\n    RequiredModules   = @(@{ModuleName = 'PackageManagement'; ModuleVersion = '1.4.4' })\r\n    PrivateData       = @{\r\n        \"PackageManagementProviders\"           = 'PSModule.psm1'\r\n        \"SupportedPowerShellGetFormatVersions\" = @('1.x', '2.x')\r\n        PSData                                 = @{\r\n            Tags         = @('Packagemanagement',\r\n                'Provider',\r\n                'PSEdition_Desktop',\r\n                'PSEdition_Core',\r\n                'Linux',\r\n                'Mac')\r\n            ProjectUri   = 'https://go.microsoft.com/fwlink/?LinkId=828955'\r\n            LicenseUri   = 'https://go.microsoft.com/fwlink/?LinkId=829061'\r\n            ReleaseNotes = @'\r\n### 2.2.5\r\n- Security patch for code injection bug\r\n\r\n### 2.2.4.1\r\n- Remove catalog file\r\n\r\n### 2.2.3\r\n- Update `HelpInfoUri` to point to the latest content (#560)\r\n- Improve discovery of usable nuget.exe binary (Thanks bwright86!) (#558)\r\n\r\n### 2.2.2\r\nBug Fix\r\n\r\n- Update casing of DscResources output\r\n\r\n### 2.2.1\r\nBug Fix\r\n\r\n- Allow DscResources to work on case sensitive platforms (#521)\r\n- Fix for failure to return credential provider when using private feeds (#521)\r\n\r\n## 2.2\r\nBug Fix\r\n\r\n- Fix for prompting for credentials when passing in -Credential parameter when using Register-PSRepository\r\n\r\n## 2.1.5\r\nNew Features\r\n\r\n- Add and remove nuget based repositories as a nuget source when nuget client tool is installed (#498)\r\n\r\nBug Fix\r\n\r\n- Fix for 'Failed to publish module' error thrown when publishing modules (#497)\r\n\r\n## 2.1.4\r\n- Fixed hang while publishing some packages (#478)\r\n\r\n## 2.1.3\r\nNew Features\r\n\r\n- Added -Scope parameter to Update-Module (Thanks @lwajswaj!) (#471)\r\n- Added -Exclude parameter to Publish-Module (Thanks @Benny1007!) (#191)\r\n- Added -SkipAutomaticTags parameter to Publish-Module (Thanks @awickham10!) (#452)\r\n\r\nBug Fix\r\n\r\n- Fixed issue with finding modules using macOS and .NET Core 3.0\r\n\r\n## 2.1.2\r\n\r\nNew Feature\r\n\r\n- Added support for registering repositories with special characters\r\n\r\n## 2.1.1\r\n\r\n- Fix DSC resource folder structure\r\n\r\n## 2.1.0\r\n\r\nBreaking Change\r\n\r\n- Default installation scope for Update-Module and Update-Script has changed to match Install-Module and Install-Script. For Windows PowerShell (version 5.1 or below), the default scope is AllUsers when running in an elevated session, and CurrentUser at all other times.\r\n  For PowerShell version 6.0.0 and above, the default installation scope is always CurrentUser. (#421)\r\n\r\nBug Fixes\r\n\r\n- Update-ModuleManifest no longer clears FunctionsToExport, AliasesToExport, nor NestModules (#415 & #425) (Thanks @pougetat and @tnieto88!)\r\n- Update-Module no longer changes repository URL (#407)\r\n- Update-ModuleManifest no longer preprends 'PSGet_' to module name (#403) (Thanks @ThePoShWolf)\r\n- Update-ModuleManifest now throws error and fails to update when provided invalid entries (#398) (Thanks @pougetat!)\r\n- Ignore files no longer being included when uploading modules (#396)\r\n\r\nNew Features\r\n\r\n- New DSC resource, PSRepository (#426) (Thanks @johlju!)\r\n- Piping of PS respositories (#420)\r\n- utf8 support for .nuspec (#419)\r\n\r\n## 2.0.4\r\n\r\nBug Fix\r\n* Remove PSGallery availability checks (#374)\r\n\r\n## 2.0.3\r\n\r\nBug fixes and Improvements\r\n* Fix CommandAlreadyAvailable error for PackageManagement module (#333)\r\n* Remove trailing whitespace when value is not provided for Get-PSScriptInfoString (#337) (Thanks @thomasrayner)\r\n* Expanded aliases for improved readability (#338) (Thanks @lazywinadmin)\r\n* Improvements for Catalog tests (#343)\r\n* Fix Update-ScriptInfoFile to preserve PrivateData (#346) (Thanks @tnieto88)\r\n* Import modules with many commands faster (#351)\r\n\r\nNew Features\r\n* Tab completion for -Repository parameter (#339) and for Publish-Module -Name (#359) (Thanks @matt9ucci)\r\n\r\n## 2.0.1\r\n\r\nBug fixes\r\n- Resolved Publish-Module doesn't report error but fails to publish module (#316)\r\n- Resolved CommandAlreadyAvailable error while installing the latest version of PackageManagement module (#333)\r\n\r\n## 2.0.0\r\n\r\nBreaking Change\r\n- Default installation scope for Install-Module, Install-Script, and Install-Package has changed. For Windows PowerShell (version 5.1 or below), the default scope is AllUsers when running in an elevated session, and CurrentUser at all other times.\r\n  For PowerShell version 6.0.0 and above, the default installation scope is always CurrentUser.\r\n\r\n## 1.6.7\r\n\r\nBug fixes\r\n- Resolved Install/Save-Module error in PSCore 6.1.0-preview.4 on Ubuntu 18.04 OS (WSL/Azure) (#313)\r\n- Updated error message in Save-Module cmdlet when the specified path is not accessible (#313)\r\n- Added few additional verbose messages (#313)\r\n\r\n## 1.6.6\r\n\r\nDependency Updates\r\n* Add dependency on version 4.1.0 or newer of NuGet.exe\r\n* Update NuGet.exe bootstrap URL to https://aka.ms/psget-nugetexe\r\n\r\nBuild and Code Cleanup Improvements\r\n* Improved error handling in network connectivity tests.\r\n\r\nBug fixes\r\n- Change Update-ModuleManifest so that prefix is not added to CmdletsToExport.\r\n- Change Update-ModuleManifest so that parameters will not reset to default values.\r\n- Specify AllowPrereleseVersions provider option only when AllowPrerelease is specified on the PowerShellGet cmdlets.\r\n\r\n## 1.6.5\r\n\r\nNew features\r\n* Allow Pester/PSReadline installation when signed by non-Microsoft certificate (#258)\r\n  - Whitelist installation of non-Microsoft signed Pester and PSReadline over Microsoft signed Pester and PSReadline.\r\n\r\nBuild and Code Cleanup Improvements\r\n* Splitting of functions (#229) (Thanks @Benny1007)\r\n  - Moves private functions into respective private folder.\r\n  - Moves public functions as defined in PSModule.psd1 into respective public folder.\r\n  - Removes all functions from PSModule.psm1 file.\r\n  - Dot sources the functions from PSModule.psm1 file.\r\n  - Uses Export-ModuleMember to export the public functions from PSModule.psm1 file.\r\n\r\n* Add build step to construct a single .psm1 file (#242) (Thanks @Benny1007)\r\n  - Merged public and private functions into one .psm1 file to increase load time performance.\r\n\r\nBug fixes\r\n- Fix null parameter error caused by MinimumVersion in Publish-PackageUtility (#201)\r\n- Change .ExternalHelp link from PSGet.psm1-help.xml to PSModule-help.xml in PSModule.psm1 file (#215)\r\n- Change Publish-* to allow version comparison instead of string comparison (#219)\r\n- Ensure Get-InstalledScript -RequiredVersion works when versions have a leading 0 (#260)\r\n- Add positional path to Save-Module and Save-Script (#264, #266)\r\n- Ensure that Get-AuthenticodePublisher verifies publisher and that installing or updating a module checks for approprite catalog signature (#272)\r\n- Update HelpInfoURI to 'http://go.microsoft.com/fwlink/?linkid=855963' (#274)\r\n\r\n\r\n## 1.6.0\r\n\r\nNew features\r\n* Prerelease Version Support (#185)\r\n  - Implemented prerelease versions functionality in PowerShellGet cmdlets.\r\n  - Enables publishing, discovering, and installing the prerelease versions of modules and scripts from the PowerShell Gallery.\r\n  - [Documentation](https://docs.microsoft.com/en-us/powershell/gallery/psget/module/PrereleaseModule)\r\n\r\n* Enabled publish cmdlets on PWSH and Nano Server (#196)\r\n  - Dotnet command version 2.0.0 or newer should be installed by the user prior to using the publish cmdlets on PWSH and Windows Nano Server.\r\n  - Users can install the dotnet command by following the instructions specified at https://aka.ms/dotnet-install-script.\r\n  - On Windows, users can install the dotnet command by running *Invoke-WebRequest -Uri 'https://dot.net/v1/dotnet-install.ps1' -OutFile '.\\dotnet-install.ps1'; & '.\\dotnet-install.ps1' -Channel Current -Version '2.0.0'*\r\n  - Publish cmdlets on Windows PowerShell supports using the dotnet command for publishing operations.\r\n\r\nBreaking Change\r\n- PWSH: Changed the installation location of AllUsers scope to the parent of $PSHOME instead of $PSHOME. It is the SHARED_MODULES folder on PWSH.\r\n\r\nBug fixes\r\n- Update HelpInfoURI to 'https://go.microsoft.com/fwlink/?linkid=855963' (#195)\r\n- Ensure MyDocumentsPSPath path is correct (#179) (Thanks @lwsrbrts)\r\n\r\n\r\n## 1.5.0.0\r\n\r\nNew features\r\n* Added support for modules requiring license acceptance (#150)\r\n  - [Documentation](https://docs.microsoft.com/en-us/powershell/gallery/psget/module/RequireLicenseAcceptance)\r\n\r\n* Added version for REQUIREDSCRIPTS (#162)\r\n  - Enabled following scenarios for REQUIREDSCRIPTS\r\n    - [1.0] - RequiredVersion\r\n    - [1.0,2.0] - Min and Max Version\r\n    - (,1.0] - Max Version\r\n    - 1.0 - Min Version\r\n\r\nBug fixes\r\n* Fixed empty version value in nuspec (#157)\r\n\r\n\r\n## 1.1.3.2\r\n* Disabled PowerShellGet Telemetry on PS Core as PowerShell Telemetry APIs got removed in PowerShell Core beta builds. (#153)\r\n* Fixed for DateTime format serialization issue. (#141)\r\n* Update-ModuleManifest should add ExternalModuleDependencies value as a collection. (#129)\r\n\r\n## 1.1.3.1\r\n\r\nNew features\r\n* Added `PrivateData` field to ScriptFileInfo. (#119)\r\n\r\nBug fixes\r\n\r\n## 1.1.2.0\r\n\r\nBug fixes\r\n\r\n## 1.1.1.0\r\n\r\nBug fixes\r\n\r\n## 1.1.0.0\r\n\r\n* Initial release from GitHub.\r\n* PowerShellCore support.\r\n\r\n## For full history of release notes see changelog:\r\nhttps://github.com/PowerShell/PowerShellGet/blob/master/CHANGELOG.md\r\n'@\r\n        }\r\n    }\r\n\r\n    HelpInfoURI       = 'http://go.microsoft.com/fwlink/?linkid=2113539'\r\n}\r\n\r\n\r\n# SIG # Begin signature block\r\n# MIIjkQYJKoZIhvcNAQcCoIIjgjCCI34CAQExDzANBglghkgBZQMEAgEFADB5Bgor\r\n# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG\r\n# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCRNShWem0qs5De\r\n# OoNTMpUMZmnlgRrJHCT4bl+44h9Jy6CCDYEwggX/MIID56ADAgECAhMzAAABh3IX\r\n# chVZQMcJAAAAAAGHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD\r\n# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p\r\n# bmcgUENBIDIwMTEwHhcNMjAwMzA0MTgzOTQ3WhcNMjEwMzAzMTgzOTQ3WjB0MQsw\r\n# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u\r\n# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\r\n# AQDOt8kLc7P3T7MKIhouYHewMFmnq8Ayu7FOhZCQabVwBp2VS4WyB2Qe4TQBT8aB\r\n# znANDEPjHKNdPT8Xz5cNali6XHefS8i/WXtF0vSsP8NEv6mBHuA2p1fw2wB/F0dH\r\n# sJ3GfZ5c0sPJjklsiYqPw59xJ54kM91IOgiO2OUzjNAljPibjCWfH7UzQ1TPHc4d\r\n# weils8GEIrbBRb7IWwiObL12jWT4Yh71NQgvJ9Fn6+UhD9x2uk3dLj84vwt1NuFQ\r\n# itKJxIV0fVsRNR3abQVOLqpDugbr0SzNL6o8xzOHL5OXiGGwg6ekiXA1/2XXY7yV\r\n# Fc39tledDtZjSjNbex1zzwSXAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE\r\n# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUhov4ZyO96axkJdMjpzu2zVXOJcsw\r\n# UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1\r\n# ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDU4Mzg1MB8GA1UdIwQYMBaAFEhu\r\n# ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu\r\n# bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w\r\n# Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3\r\n# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx\r\n# MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAixmy\r\n# S6E6vprWD9KFNIB9G5zyMuIjZAOuUJ1EK/Vlg6Fb3ZHXjjUwATKIcXbFuFC6Wr4K\r\n# NrU4DY/sBVqmab5AC/je3bpUpjtxpEyqUqtPc30wEg/rO9vmKmqKoLPT37svc2NV\r\n# BmGNl+85qO4fV/w7Cx7J0Bbqk19KcRNdjt6eKoTnTPHBHlVHQIHZpMxacbFOAkJr\r\n# qAVkYZdz7ikNXTxV+GRb36tC4ByMNxE2DF7vFdvaiZP0CVZ5ByJ2gAhXMdK9+usx\r\n# zVk913qKde1OAuWdv+rndqkAIm8fUlRnr4saSCg7cIbUwCCf116wUJ7EuJDg0vHe\r\n# yhnCeHnBbyH3RZkHEi2ofmfgnFISJZDdMAeVZGVOh20Jp50XBzqokpPzeZ6zc1/g\r\n# yILNyiVgE+RPkjnUQshd1f1PMgn3tns2Cz7bJiVUaqEO3n9qRFgy5JuLae6UweGf\r\n# AeOo3dgLZxikKzYs3hDMaEtJq8IP71cX7QXe6lnMmXU/Hdfz2p897Zd+kU+vZvKI\r\n# 3cwLfuVQgK2RZ2z+Kc3K3dRPz2rXycK5XCuRZmvGab/WbrZiC7wJQapgBodltMI5\r\n# GMdFrBg9IeF7/rP4EqVQXeKtevTlZXjpuNhhjuR+2DMt/dWufjXpiW91bo3aH6Ea\r\n# jOALXmoxgltCp1K7hrS6gmsvj94cLRf50QQ4U8Qwggd6MIIFYqADAgECAgphDpDS\r\n# AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK\r\n# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0\r\n# IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0\r\n# ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla\r\n# MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS\r\n# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT\r\n# H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB\r\n# AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG\r\n# OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S\r\n# 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz\r\n# y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7\r\n# 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u\r\n# M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33\r\n# X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl\r\n# XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP\r\n# 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB\r\n# l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF\r\n# RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM\r\n# CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ\r\n# BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud\r\n# DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO\r\n# 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0\r\n# LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p\r\n# Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB\r\n# FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw\r\n# cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA\r\n# XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY\r\n# 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj\r\n# 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd\r\n# d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ\r\n# Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf\r\n# wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ\r\n# aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j\r\n# NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B\r\n# xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96\r\n# eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7\r\n# r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I\r\n# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVZjCCFWICAQEwgZUwfjELMAkG\r\n# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx\r\n# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z\r\n# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAYdyF3IVWUDHCQAAAAABhzAN\r\n# BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor\r\n# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQg3TxELXso\r\n# oRSF8xKPexxNhyDHV3uwUf4mRHTftOyVvf4wQgYKKwYBBAGCNwIBDDE0MDKgFIAS\r\n# AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN\r\n# BgkqhkiG9w0BAQEFAASCAQC2MdGNwwt17U4YHP6Gn/7I/Z5/XKA08BGacJ6NSvXC\r\n# 7BK55Looz5q9JuOjKgY0J5Zv3s3cBCBiABOF/E+kfjMqCtK1x9xC0dz+ZXGjKyFb\r\n# MFuuzueIFHKnZWjLXueiAXmXuhQEV1lmw2X2Cv5lCV7fhoUyYP47yJvS+nHk5c2u\r\n# 8OSZ4iVgBTcazWLWZTDu4zbVKk2g2HawdlGEwsCBn21gwhyqIelNUa/Cs4ab+a30\r\n# Ach8Jd12YE/ZmrSsoUV1hVDFA+/Z7oeZfuENa2mUUlrZ7Y+uLpbw8GZ4vge7TO23\r\n# r2cFGEV5g6q1/ykxFisUUheyYfjfsWqPVhXe6+9Mvk94oYIS8DCCEuwGCisGAQQB\r\n# gjcDAwExghLcMIIS2AYJKoZIhvcNAQcCoIISyTCCEsUCAQMxDzANBglghkgBZQME\r\n# AgEFADCCAVQGCyqGSIb3DQEJEAEEoIIBQwSCAT8wggE7AgEBBgorBgEEAYRZCgMB\r\n# MDEwDQYJYIZIAWUDBAIBBQAEIFoqO98TuKz1Zz96t7blTSp0BuwKzzxkArukjb8S\r\n# 0+wRAgZfYPq2eAYYEjIwMjAwOTIyMjIxOTUwLjkzWjAEgAIB9KCB1KSB0TCBzjEL\r\n# MAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1v\r\n# bmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEpMCcGA1UECxMgTWlj\r\n# cm9zb2Z0IE9wZXJhdGlvbnMgUHVlcnRvIFJpY28xJjAkBgNVBAsTHVRoYWxlcyBU\r\n# U1MgRVNOOjc4ODAtRTM5MC04MDE0MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1T\r\n# dGFtcCBTZXJ2aWNloIIORDCCBPUwggPdoAMCAQICEzMAAAEooA6B4TbVT8IAAAAA\r\n# ASgwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp\r\n# bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw\r\n# b3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAw\r\n# HhcNMTkxMjE5MDExNTAwWhcNMjEwMzE3MDExNTAwWjCBzjELMAkGA1UEBhMCVVMx\r\n# EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT\r\n# FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEpMCcGA1UECxMgTWljcm9zb2Z0IE9wZXJh\r\n# dGlvbnMgUHVlcnRvIFJpY28xJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNOOjc4ODAt\r\n# RTM5MC04MDE0MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNl\r\n# MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnZGx1vdU24Y+zb8OClz2\r\n# C3vssbQk+QPhVZOUQkuSrOdMmX5Ghl+I7A3qJZ8+7iT+SPyfBjum8uzU6wHLj3jK\r\n# 6yDiscvAc1Qk+3DVNzngw4uB1yiwDg3GSLvd8PKpbAO2M52TofuQ1zME+oAMPoH3\r\n# yi3vv/BIAIEkjGb2oBS52q5Ll9zMIXT75pZRq8O7jpTdy/ocSMh1XZl0lNQqDhZQ\r\n# h1NgxBcjTzb6pKzjlYFmNwr3z+0h/Hy6ryrySxYX37NSMZMWIxooeGftxIKgSPsT\r\n# W1WZbTwhKlLrvxYU/b4DQ5DBpZwko0AIr4n4trsvPZsa6kKJ04bPlcN7BzWUP2cs\r\n# 9wIDAQABo4IBGzCCARcwHQYDVR0OBBYEFITi8oPxfrU3m9QBw050f1AEy6byMB8G\r\n# A1UdIwQYMBaAFNVjOlyKMZDzQ3t8RhvFM2hahW1VMFYGA1UdHwRPME0wS6BJoEeG\r\n# RWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Rp\r\n# bVN0YVBDQV8yMDEwLTA3LTAxLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUH\r\n# MAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljVGltU3Rh\r\n# UENBXzIwMTAtMDctMDEuY3J0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYB\r\n# BQUHAwgwDQYJKoZIhvcNAQELBQADggEBAItfZkcYhQuAOT+JxwdZTLCMPICwEeWG\r\n# Sa2YGniWV3Avd02jRtdlkeJJkH5zYrO8+pjrgGUQKNL8+q6vab1RpPU3QF5SjBEd\r\n# BPzzB3N33iBiopeYsNtVHzJ5WAGRw/8mJVZtd1DNzPURMeBauH67MDwHBSABocnD\r\n# 6ddhxwi4OA8kzVRN42X1Hk69/7rNHYTlkjgOsiq9LiMfhCygw9OfbsCM3tVm3hqa\r\n# hHEwsRxABLu89PUlRRpEWkUeaRRhWWfVgyzD///r3rxpG/LdyYKVLji7GSRogtuG\r\n# HWHT16NmMeGsSf6T0xxWRaK5jvbiMn/nu3KUzsD+PMhY2PUXxWWGTLIwggZxMIIE\r\n# WaADAgECAgphCYEqAAAAAAACMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJV\r\n# UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE\r\n# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9v\r\n# dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAxMDAeFw0xMDA3MDEyMTM2NTVaFw0y\r\n# NTA3MDEyMTQ2NTVaMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u\r\n# MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp\r\n# b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMIIBIjAN\r\n# BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqR0NvHcRijog7PwTl/X6f2mUa3RU\r\n# ENWlCgCChfvtfGhLLF/Fw+Vhwna3PmYrW/AVUycEMR9BGxqVHc4JE458YTBZsTBE\r\n# D/FgiIRUQwzXTbg4CLNC3ZOs1nMwVyaCo0UN0Or1R4HNvyRgMlhgRvJYR4YyhB50\r\n# YWeRX4FUsc+TTJLBxKZd0WETbijGGvmGgLvfYfxGwScdJGcSchohiq9LZIlQYrFd\r\n# /XcfPfBXday9ikJNQFHRD5wGPmd/9WbAA5ZEfu/QS/1u5ZrKsajyeioKMfDaTgaR\r\n# togINeh4HLDpmc085y9Euqf03GS9pAHBIAmTeM38vMDJRF1eFpwBBU8iTQIDAQAB\r\n# o4IB5jCCAeIwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFNVjOlyKMZDzQ3t8\r\n# RhvFM2hahW1VMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIB\r\n# hjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fO\r\n# mhjEMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9w\r\n# a2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggr\r\n# BgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNv\r\n# bS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MIGgBgNVHSAB\r\n# Af8EgZUwgZIwgY8GCSsGAQQBgjcuAzCBgTA9BggrBgEFBQcCARYxaHR0cDovL3d3\r\n# dy5taWNyb3NvZnQuY29tL1BLSS9kb2NzL0NQUy9kZWZhdWx0Lmh0bTBABggrBgEF\r\n# BQcCAjA0HjIgHQBMAGUAZwBhAGwAXwBQAG8AbABpAGMAeQBfAFMAdABhAHQAZQBt\r\n# AGUAbgB0AC4gHTANBgkqhkiG9w0BAQsFAAOCAgEAB+aIUQ3ixuCYP4FxAz2do6Eh\r\n# b7Prpsz1Mb7PBeKp/vpXbRkws8LFZslq3/Xn8Hi9x6ieJeP5vO1rVFcIK1GCRBL7\r\n# uVOMzPRgEop2zEBAQZvcXBf/XPleFzWYJFZLdO9CEMivv3/Gf/I3fVo/HPKZeUqR\r\n# UgCvOA8X9S95gWXZqbVr5MfO9sp6AG9LMEQkIjzP7QOllo9ZKby2/QThcJ8ySif9\r\n# Va8v/rbljjO7Yl+a21dA6fHOmWaQjP9qYn/dxUoLkSbiOewZSnFjnXshbcOco6I8\r\n# +n99lmqQeKZt0uGc+R38ONiU9MalCpaGpL2eGq4EQoO4tYCbIjggtSXlZOz39L9+\r\n# Y1klD3ouOVd2onGqBooPiRa6YacRy5rYDkeagMXQzafQ732D8OE7cQnfXXSYIghh\r\n# 2rBQHm+98eEA3+cxB6STOvdlR3jo+KhIq/fecn5ha293qYHLpwmsObvsxsvYgrRy\r\n# zR30uIUBHoD7G4kqVDmyW9rIDVWZeodzOwjmmC3qjeAzLhIp9cAvVCch98isTtoo\r\n# uLGp25ayp0Kiyc8ZQU3ghvkqmqMRZjDTu3QyS99je/WZii8bxyGvWbWu3EQ8l1Bx\r\n# 16HSxVXjad5XwdHeMMD9zOZN+w2/XU/pnR4ZOC+8z1gFLu8NoFA12u8JJxzVs341\r\n# Hgi62jbb01+P3nSISRKhggLSMIICOwIBATCB/KGB1KSB0TCBzjELMAkGA1UEBhMC\r\n# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV\r\n# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEpMCcGA1UECxMgTWljcm9zb2Z0IE9w\r\n# ZXJhdGlvbnMgUHVlcnRvIFJpY28xJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNOOjc4\r\n# ODAtRTM5MC04MDE0MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2\r\n# aWNloiMKAQEwBwYFKw4DAhoDFQAxPUsb8oASPReyIv2fubGZfVp9m6CBgzCBgKR+\r\n# MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS\r\n# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMT\r\n# HU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMA0GCSqGSIb3DQEBBQUAAgUA\r\n# 4xSzVjAiGA8yMDIwMDkyMjIxMzEwMloYDzIwMjAwOTIzMjEzMTAyWjB3MD0GCisG\r\n# AQQBhFkKBAExLzAtMAoCBQDjFLNWAgEAMAoCAQACAiF/AgH/MAcCAQACAhGdMAoC\r\n# BQDjFgTWAgEAMDYGCisGAQQBhFkKBAIxKDAmMAwGCisGAQQBhFkKAwKgCjAIAgEA\r\n# AgMHoSChCjAIAgEAAgMBhqAwDQYJKoZIhvcNAQEFBQADgYEAIIiMzPTf2R4++LT5\r\n# BIQAAZ7XoAkwHZm+GsArFZSjJmmdGtYNmLO7vA433YPn1av4tVK9wasdh+Uxa3Qo\r\n# YD4D+LR+E8bwdZR+JGQZKDkxjmOXwPITowyRtYQPCa9mTO4iJDf/gixpGBzu8sgM\r\n# zXRdLiDn1P/Vo8FpWdAKfaLz4P4xggMNMIIDCQIBATCBkzB8MQswCQYDVQQGEwJV\r\n# UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE\r\n# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGlt\r\n# ZS1TdGFtcCBQQ0EgMjAxMAITMwAAASigDoHhNtVPwgAAAAABKDANBglghkgBZQME\r\n# AgEFAKCCAUowGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMC8GCSqGSIb3DQEJ\r\n# BDEiBCDvMyofVUL0InlfJG07Yi8ZRMCLjc3rNDrU8nhvTqbq+DCB+gYLKoZIhvcN\r\n# AQkQAi8xgeowgecwgeQwgb0EILxFaouvBVJ379wbEN8GpLhvW09eGg8WsLrXm9XW\r\n# 6BTaMIGYMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x\r\n# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv\r\n# bjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAEo\r\n# oA6B4TbVT8IAAAAAASgwIgQgRO6TlKRXX+wSVoBIMaqor080XnPuS/BnRzhuQ8oN\r\n# BCQwDQYJKoZIhvcNAQELBQAEggEAZM529j3yYoEo0YZVvE7ZwiKlil8xSVU3JNZE\r\n# gHE391SCUFpeLu012jhMt3ikeJjApyUuhuQpyWkU1pkIMJHP78SOq4VejIMhm57l\r\n# iIUo1txBy4P6NZcNmIihQa/R484b4k1Zz1GP7jx+Wmvq65FHPv3SFlmJOs6GuE1R\r\n# lIhZdc8VNW7DsyGShMOIKx5lYb68+rsUES5bRExAxAj0ykGPpmiQt3QRmBNlDEgc\r\n# 7GF2FGWFD7ZdAn6+W66UmqxkU7MpBrVwggRi92YXMbZI2A6ts8UR8G8JeJZbaHRz\r\n# hnAaK3NPwhZhfD/2oRN172Rr7uRQtH9FesspG0TlfkjEe6P9zw==\r\n# SIG # End signature block\r\n"
  },
  {
    "path": "src/PowerShell/ExternalModules/PowerShellGet/2.2.5/en-US/PSGet.Resource.psd1",
    "content": "﻿#########################################################################################\r\n#\r\n# Copyright (c) Microsoft Corporation. All rights reserved.\r\n#\r\n# Localized PSGet.Resource.psd1\r\n#\r\n#########################################################################################\r\n\r\nConvertFrom-StringData @'\r\n###PSLOC\r\n        InstallModulewhatIfMessage=Version '{1}' of module '{0}'\r\n        InstallScriptwhatIfMessage=Version '{1}' of script '{0}'\r\n        UpdateModulewhatIfMessage=Version '__OLDVERSION__' of module '{0}', updating to version '{1}'\r\n        UpdateScriptwhatIfMessage=Version '__OLDVERSION__' of script '{0}', updating to version '{1}'\r\n        PublishModulewhatIfMessage=Version '{0}' of module '{1}'\r\n        PublishScriptwhatIfMessage=Version '{0}' of script '{1}'\r\n        NewScriptFileInfowhatIfMessage=Creating the '{0}' PowerShell Script file\r\n        UpdateScriptFileInfowhatIfMessage=Updating the '{0}' PowerShell Script file\r\n        NameShouldNotContainWildcardCharacters=The specified name '{0}' should not contain any wildcard characters, please correct it and try again.\r\n        AllVersionsCannotBeUsedWithOtherVersionParameters=You cannot use the parameter AllVersions with RequiredVersion, MinimumVersion or MaximumVersion in the same command.\r\n        VersionRangeAndRequiredVersionCannotBeSpecifiedTogether=You cannot use the parameters RequiredVersion and either MinimumVersion or MaximumVersion in the same command. Specify only one of these parameters in your command.\r\n        RequiredVersionAllowedOnlyWithSingleModuleName=The RequiredVersion parameter is allowed only when a single module name is specified as the value of the Name parameter, without any wildcard characters.\r\n        MinimumVersionIsGreaterThanMaximumVersion=The specified MinimumVersion '{0}' is greater than the specified MaximumVersion '{1}'.\r\n        AllowPrereleaseRequiredToUsePrereleaseStringInVersion=The '-AllowPrerelease' parameter must be specified when using the Prerelease string in MinimumVersion, MaximumVersion, or RequiredVersion.\r\n        UpdateModuleAdminPrivilegeRequiredForAllUsersScope=Administrator rights are required to update modules in '{0}'. Log on to the computer with an account that has Administrator rights, and then try again, or update '{1}' by adding \"-Scope CurrentUser\" to your command. You can also try running the Windows PowerShell session with elevated rights (Run as Administrator).\r\n        InstallModuleAdminPrivilegeRequiredForAllUsersScope=Administrator rights are required to install modules in '{0}'. Log on to the computer with an account that has Administrator rights, and then try again, or install '{1}' by adding \"-Scope CurrentUser\" to your command. You can also try running the Windows PowerShell session with elevated rights (Run as Administrator).\r\n        InstallScriptAdminPrivilegeRequiredForAllUsersScope=Administrator rights are required to install scripts in '{0}'. Log on to the computer with an account that has Administrator rights, and then try again, or install '{1}' by adding \"-Scope CurrentUser\" to your command. You can also try running the Windows PowerShell session with elevated rights (Run as Administrator).\r\n        AdministratorRightsNeededOrSpecifyCurrentUserScope=Administrator rights are required to install or update. Log on to the computer with an account that has Administrator rights, and then try again, or install by adding \"-Scope CurrentUser\" to your command. You can also try running the Windows PowerShell session with elevated rights (Run as Administrator).\r\n        VersionParametersAreAllowedOnlyWithSingleName=The RequiredVersion, MinimumVersion, MaximumVersion, AllVersions or AllowPrerelease parameters are allowed only when you specify a single name as the value of the Name parameter, without any wildcard characters.\r\n        PathIsNotADirectory=The specified path '{0}' is not a valid directory.\r\n        ModuleAlreadyInstalled=Version '{0}' of module '{1}' is already installed at '{2}'. To delete version '{3}' and install version '{4}', run Install-Module, and add the -Force parameter.\r\n        ScriptAlreadyInstalled=Version '{0}' of script '{1}' is already installed at '{2}'. To delete version '{3}' and install version '{4}', run Install-Script, and add the -Force parameter.\r\n        CommandAlreadyAvailable=A command with name '{0}' is already available on this system. This script '{0}' may override the existing command. If you still want to install this script '{0}', use -Force parameter.\r\n        ModuleAlreadyInstalledSxS=Version '{0}' of module '{1}' is already installed at '{2}'. To install version '{3}', run Install-Module and add the -Force parameter, this command will install version '{5}' side-by-side with version '{4}'.\r\n        ModuleAlreadyInstalledVerbose=Version '{0}' of module '{1}' is already installed at '{2}'.\r\n        ScriptAlreadyInstalledVerbose=Version '{0}' of script '{1}' is already installed at '{2}'.\r\n        ModuleWithRequiredVersionAlreadyInstalled=Version '{0}' of module '{1}' is already installed at '{2}'. To reinstall this version '{3}', run Install-Module or Updated-Module cmdlet with the -Force parameter.\r\n        InvalidPSModule=The module '{0}' cannot be installed or updated because it is not a properly-formed module.\r\n        InvalidPowerShellScriptFile=The script '{0}' cannot be installed or updated because it is not a properly-formed script.\r\n        InvalidAuthenticodeSignature=The module '{0}' cannot be installed or updated because the Authenticode signature for the file '{1}' is not valid.\r\n        ModuleNotInstalledOnThisMachine=Module '{0}' was not updated because no valid module was found in the module directory. Verify that the module is located in the folder specified by $env:PSModulePath.\r\n        ScriptNotInstalledOnThisMachine=Script '{0}' was not updated because no valid script was found in the script directories '{1}' and '{2}'.\r\n        AdminPrivilegesRequiredForUpdate=Module '{0}' (installed at '{1}') cannot be updated because Administrator rights are required to change that directory. Log on to the computer with an account that has Administrator rights, and then try again. You can also try running the Windows PowerShell session with elevated rights (Run as Administrator).\r\n        AdminPrivilegesRequiredForScriptUpdate=Script '{0}' (installed at '{1}') cannot be updated because Administrator rights are required to change that script. Log on to the computer with an account that has Administrator rights, and then try again. You can also try running the Windows PowerShell session with elevated rights (Run as Administrator).\r\n        ModuleNotInstalledUsingPowerShellGet=Module '{0}' was not installed by using Install-Module, so it cannot be updated.\r\n        ScriptNotInstalledUsingPowerShellGet=Script '{0}' was not installed by using Install-Script, so it cannot be updated.\r\n        DownloadingModuleFromGallery=Downloading module '{0}' with version '{1}' from the repository '{2}'.\r\n        DownloadingScriptFromGallery=Downloading script '{0}' with version '{1}' from the repository '{2}'.\r\n        NoUpdateAvailable=No updates were found for module '{0}'.\r\n        NoScriptUpdateAvailable=No updates were found for script '{0}'.\r\n        FoundModuleUpdate=An update for the module '{0}' was found with version '{1}'.\r\n        FoundScriptUpdate=An update for the script '{0}' was found with version '{1}'.\r\n        InvalidPSModuleDuringUpdate= Module '{0}' was not updated because the module in the repository '{1}' is not a valid Windows PowerShell module.\r\n        ModuleGotUpdated=Module '{0}' has been updated successfully.\r\n        TestingModuleInUse=Testing if the module to update is in use.\r\n        ModuleDestination= The specified module will be installed in '{0}'.\r\n        ScriptDestination= The specified script will be installed in '{0}' and its dependent modules will be installed in '{1}'.\r\n        ModuleIsInUse=Module '{0}' is in currently in use or you don't have the required permissions.\r\n        ModuleInstalledSuccessfully=Module '{0}' was installed successfully to path '{1}'.\r\n        ModuleSavedSuccessfully=Module '{0}' was saved successfully to path '{1}'.\r\n        ScriptInstalledSuccessfully=Script '{0}' was installed successfully to path '{1}'.\r\n        ScriptSavedSuccessfully=Script '{0}' was saved successfully to path '{1}'.\r\n        CheckingForModuleUpdate= Checking for updates for module '{0}'.\r\n        CheckingForScriptUpdate= Checking for updates for script '{0}'.\r\n        ModuleInUseWithProcessDetails=The version '{0}' of module '{1}' is currently in use. Retry the operation after closing the following applications: '{2}'.\r\n        ModuleVersionInUse=The version '{0}' of module '{1}' is currently in use. Retry the operation after closing the applications.\r\n        ModuleNotAvailableLocally=The specified module '{0}' was not published because no module with that name was found in any module directory.\r\n        InvalidModulePathToPublish=The specified module with path '{0}' was not published because no valid module was found with that path.\r\n        ModuleWithRequiredVersionNotAvailableLocally= The specified module '{0}' with version '{1}' was not published because no module with that name and version was found in any module directory.\r\n        AmbiguousModuleName=Modules with the name '{0}' are available under multiple paths. Add the -RequiredVersion parameter or the -Path parameter to specify the module to publish.\r\n        AmbiguousModulePath=Multiple versions are available under the specified module path '{0}'. Specify the full path to the module to be published.\r\n        PublishModuleLocation=Module '{0}' was found in '{1}'.\r\n        InvalidModuleToPublish=Module '{0}' cannot be published because it does not have a module manifest file. Run New-ModuleManifest -Path <PathName> to create a module manifest with metadata before publishing.\r\n        MissingRequiredManifestKeys=Module '{0}' cannot be published because it is missing required metadata. Verify that the module manifest specifies Description and Author.\r\n        InvalidCharactersInPrereleaseString=The Prerelease string '{0}' contains invalid characters. Please ensure that only characters 'a-zA-Z0-9' and possibly hyphen ('-') at the beginning are in the Prerelease string.\r\n        IncorrectVersionPartsCountForPrereleaseStringUsage=Version '{0}' must have exactly 3 parts for a Prerelease string to be used.\r\n        ModuleVersionShouldBeGreaterThanGalleryVersion=Module '{0}' with version '{1}' cannot be published. The version must exceed the current version '{2}' that exists in the repository '{3}', or you must specify -Force.\r\n        ModuleVersionIsAlreadyAvailableInTheGallery=The module '{0}' with version '{1}' cannot be published as the current version '{2}' is already available in the repository '{3}'.\r\n        CouldNotInstallNuGetProvider=NuGet provider is required to interact with NuGet-based repositories. Please ensure that '{0}' or newer version of NuGet provider is installed.\r\n        CouldNotInstallNuGetExe=NuGet.exe version '{0}' or newer, or dotnet command version '{1}' or newer is required to interact with NuGet-based repositories. Please ensure that NuGet.exe or dotnet command is available under one of the paths specified in PATH environment variable value.\r\n        CouldNotUpgradeNuGetExe=NuGet.exe version '{0}' or newer, or dotnet command version '{1}' or newer is required to interact with NuGet-based repositories. Please ensure that required version of NuGet.exe or dotnet command is available under one of the paths specified in PATH environment variable value.\r\n        CouldNotFindDotnetCommand=For publish operations, dotnet command version '{0}' or newer is required to interact with the NuGet-based repositories. Please ensure that dotnet command version '{0}' or newer is installed and available under one of the paths specified in PATH environment variable value. You can also install the dotnet command by following the instructions specified at '{1}'.\r\n        CouldNotInstallNuGetBinaries2=PowerShellGet requires NuGet.exe (or dotnet command) and NuGet provider version '{0}' or newer to interact with the NuGet-based repositories. Please ensure that '{0}' or newer version of NuGet provider is installed and NuGet.exe (or dotnet command) is available under one of the paths specified in PATH environment variable value.\r\n        InstallNugetBinariesUpgradeShouldContinueQuery=This version of PowerShellGet requires minimum version '{0}' of NuGet.exe and minimum version '{1}' of NuGet provider to publish an item to NuGet-based repositories. The NuGet provider must be available in '{2}' or '{3}'. You can also install the NuGet provider by running 'Install-PackageProvider -Name NuGet -MinimumVersion {0} -Force'. NuGet.exe must be available in '{4}' or '{5}', or under one of the paths specified in PATH environment variable value. NuGet.exe can be downloaded from https://aka.ms/psget-nugetexe. For more information, see https://go.microsoft.com/fwlink/?linkid=875534. Do you want PowerShellGet to upgrade NuGet.exe to the latest version and install the NuGet provider now?\r\n        InstallNuGetBinariesShouldContinueQuery=This version of PowerShellGet requires minimum version '{0}' of NuGet.exe and minimum version '{1}' of NuGet provider to publish an item to NuGet-based repositories. The NuGet provider must be available in '{3}' or '{3}'. You can also install the NuGet provider by running 'Install-PackageProvider -Name NuGet -MinimumVersion {0} -Force'. NuGet.exe must be available in '{4}' or '{5}', or under one of the paths specified in PATH environment variable value. NuGet.exe can be downloaded from https://aka.ms/psget-nugetexe. For more information, see https://go.microsoft.com/fwlink/?linkid=875534. Do you want PowerShellGet to install both the latest NuGet.exe and NuGet provider now?\r\n        InstallNugetExeUpgradeShouldContinueQuery=This version of PowerShellGet requires minimum version '{0}' of NuGet.exe to publish an item to the NuGet-based repositories. NuGet.exe must be available in '{1}' or '{2}', or under one of the paths specified in PATH environment variable value. NuGet.exe can be downloaded from https://aka.ms/psget-nugetexe. For more information, see https://aka.ms/installing-powershellget . Do you want PowerShellGet to upgrade to the latest version of NuGet.exe now?\r\n        InstallNuGetExeShouldContinueQuery=This version of PowerShellGet requires minimum version '{0}' of NuGet.exe to publish an item to the NuGet-based repositories. NuGet.exe must be available in '{1}' or '{2}', or under one of the paths specified in PATH environment variable value. NuGet.exe can be downloaded from https://aka.ms/psget-nugetexe. For more information, see https://aka.ms/installing-powershellget . Do you want PowerShellGet to install the latest version of NuGet.exe now?\r\n        InstallNuGetProviderShouldContinueQuery=This version of PowerShellGet requires minimum version '{0}' of NuGet provider to publish an item to NuGet-based repositories. The NuGet provider must be available in '{1}' or '{2}'. You can also install the NuGet provider by running 'Install-PackageProvider -Name NuGet -MinimumVersion {0} -Force'. Do you want PowerShellGet to install and import the NuGet provider now?\r\n        InstallNuGetBinariesUpgradeShouldContinueCaption=NuGet.exe upgrade and NuGet provider installation are required to continue\r\n        InstallNuGetBinariesShouldContinueCaption=NuGet.exe and NuGet provider installation are required to continue\r\n        InstallNuGetExeUpgradeShouldContinueCaption=NuGet.exe upgrade is required to continue\r\n        InstallNuGetExeShouldContinueCaption=NuGet.exe is required to continue\r\n        InstallNuGetProviderShouldContinueCaption=NuGet provider is required to continue\r\n        DownloadingNugetExe=Installing NuGet.exe.\r\n        DownloadingNugetProvider=Installing NuGet provider.\r\n        ModuleNotFound=Module '{0}' was not found.\r\n        NoMatchFound=No match was found for the specified search criteria and module names '{0}'.\r\n        NoMatchFoundForScriptName=No match was found for the specified search criteria and script names '{0}'.\r\n        MatchInvalidType=The name '{0}' is a {1} not a {2}.\r\n        FailedToCreateCompressedModule=Failed to generate the compressed file for module '{0}'.\r\n        FailedToPublish=Failed to publish module '{0}': '{1}'.\r\n        PublishedSuccessfully=Successfully published module '{0}' to the module publish location '{1}'. Please allow few minutes for '{2}' to show up in the search results.\r\n        InvalidWebUri=The specified Uri '{0}' for parameter '{1}' is an invalid Web Uri. Please ensure that it meets the Web Uri requirements.\r\n        RepositoryAlreadyRegistered=The repository could not be registered because there exists a registered repository with Name '{0}' and SourceLocation '{1}'. To register another repository with Name '{2}', please unregister the existing repository using the Unregister-PSRepository cmdlet.\r\n        RepositoryToBeUnregisteredNotFound=The repository '{0}' was not removed because no repository was found with that name. Please run Get-PSRepository and ensure that a repository of that name is present.\r\n        RepositoryCannotBeUnregistered=The specified repository '{0}' cannot be unregistered.\r\n        RepositoryNotFound=No repository with the name '{0}' was found.\r\n        PSGalleryNotFound=Unable to find repository '{0}'. Use Get-PSRepository to see all available repositories. Try again after specifying a valid repository name. You can use 'Register-PSRepository -Default' to register the PSGallery repository.\r\n        ParameterIsNotAllowedWithPSGallery=The PSGallery repository has pre-defined locations. The '{0}' parameter is not allowed, try again after removing the '{0}' parameter.\r\n        UseDefaultParameterSetOnRegisterPSRepository=Use 'Register-PSRepository -Default' to register the PSGallery repository.\r\n        RepositoryNameContainsWildCards=The repository name '{0}' should not have wildcards, correct it and try again.\r\n        InvalidRepository=The specified repository '{0}' is not a valid registered repository name. Please ensure that '{1}' is a registered repository.\r\n        RepositoryCannotBeRegistered=The specified repository '{0}' is unauthorized and cannot be registered. Try running with -Credential.\r\n        RepositoryRegistered=Successfully registered the repository '{0}' with source location '{1}'.\r\n        RepositoryUnregistered=Successfully unregistered the repository '{0}'.\r\n        PSGalleryPublishLocationIsMissing=The specified repository '{0}' does not have a valid PublishLocation. Retry after setting the PublishLocation for repository '{1}' to a valid NuGet publishing endpoint using the Set-PSRepository cmdlet.\r\n        PSRepositoryScriptPublishLocationIsMissing=The specified repository '{0}' does not have a valid ScriptPublishLocation. Retry after setting the ScriptPublishLocation for repository '{1}' to a valid NuGet publishing endpoint using the Set-PSRepository cmdlet.\r\n        ScriptSourceLocationIsMissing=The specified repository '{0}' does not have a valid ScriptSourceLocation. Retry after setting the ScriptSourceLocation for repository '{0}' to a valid NuGet endpoint for scripts using the Set-PSRepository cmdlet.\r\n        PublishModuleSupportsOnlyNuGetBasedPublishLocations=Publish-Module only supports the NuGet-based publish locations. The PublishLocation '{0}' of the repository '{1}' is not a NuGet-based publish location. Retry after setting the PublishLocation for repository '{1}' to a valid NuGet publishing endpoint using the Set-PSRepository cmdlet.\r\n        PublishScriptSupportsOnlyNuGetBasedPublishLocations=Publish-Script only supports the NuGet-based publish locations. The ScriptPublishLocation '{0}' of the repository '{1}' is not a NuGet-based publish location. Retry after setting the ScriptPublishLocation for repository '{1}' to a valid NuGet publishing endpoint using the Set-PSRepository cmdlet.\r\n        DynamicParameterHelpMessage=The dynamic parameter '{0}' is required for Find-Module and Install-Module when using the PackageManagement provider '{1}' and source location '{2}'. Please enter your value for the '{3}' dynamic parameter:\r\n        ProviderApiDebugMessage=In PowerShellGet Provider - '{0}'.\r\n        ModuleUninstallNotSupported=Module uninstallation is not supported. To remove a module, please delete the module folder.\r\n        FastPackageReference=The FastPackageReference is '{0}'.\r\n        PackageManagementProviderIsNotAvailable=The specified PackageManagement provider '{0}' is not available.\r\n        SpecifiedSourceName=Using the specified source names : '{0}'.\r\n        SpecifiedLocationAndOGP=The specified Location is '{0}' and PackageManagementProvider is '{1}'.\r\n        NoSourceNameIsSpecified=The -Repository parameter was not specified.  PowerShellGet will use all of the registered repositories.\r\n        GettingPackageManagementProviderObject=Getting the provider object for the PackageManagement Provider '{0}'.\r\n        InvalidInputObjectValue=Invalid value is specified for InputObject parameter.\r\n        SpecifiedInstallationScope=The installation scope is specified to be '{0}'.\r\n        SourceLocationValueForPSGalleryCannotBeChanged=The SourceLocation value for the PSGallery repository can not be changed.\r\n        PublishLocationValueForPSGalleryCannotBeChanged=The PublishLocation value for the PSGallery repository can not be changed.\r\n        SpecifiedProviderName=The specified PackageManagement provider name '{0}'.\r\n        ProviderNameNotSpecified=User did not specify the PackageManagement provider name, trying with the provider name '{0}'.\r\n        SpecifiedProviderNotAvailable=The specified PackageManagement provider '{0}' is not available.\r\n        SpecifiedProviderDoesnotSupportPSModules=The specified PackageManagement Provider '{0}' does not support PowerShell Modules. PackageManagement Providers must support the 'supports-powershell-modules' feature.\r\n        PollingPackageManagementProvidersForLocation=Polling available PackageManagement Providers to find one that can support the specified source location '{0}'.\r\n        PollingSingleProviderForLocation=Resolving the source location '{0}' with PackageManagement Provider '{1}'.\r\n        FoundProviderForLocation=The PackageManagement provider '{0}' supports the source location '{1}'.\r\n        SpecifiedLocationCannotBeRegistered=The specified location '{0}' cannot be registered.\r\n        RepositoryDetails=Repository details, Name = '{0}', Location = '{1}'; IsTrusted = '{2}'; IsRegistered = '{3}'.\r\n        NotSupportedPowerShellGetFormatVersion=The specified module '{0}' with PowerShellGetFormatVersion '{1}' is not supported by the current version of PowerShellGet. Get the latest version of the PowerShellGet module to install this module, '{2}'.\r\n        NotSupportedPowerShellGetFormatVersionScripts=The specified script '{0}' with PowerShellGetFormatVersion '{1}' is not supported by the current version of PowerShellGet. Get the latest version of the PowerShellGet module to install this script, '{2}'.\r\n        PathNotFound=Cannot find the path '{0}' because it does not exist.\r\n        ModuleIsNotTrusted=Untrusted module '{0}'.\r\n        ScriptIsNotTrusted=Untrusted script '{0}'.\r\n        SkippedModuleDependency=Because dependent module '{0}' was skipped in the module dependencies list, users might not know how to install it.\r\n        MissingExternallyManagedModuleDependency=The externally managed, dependent module '{0}' is not installed on this computer. To use the current module '{1}', ensure that its dependent module '{2}' is installed.\r\n        ExternallyManagedModuleDependencyIsInstalled=The externally managed, dependent module '{0}' is already installed on this computer.\r\n        ScriptMissingExternallyManagedModuleDependency=The externally managed, dependent module '{0}' is not installed on this computer. To use the current script '{1}', ensure that its dependent module '{2}' is installed.\r\n        ScriptMissingExternallyManagedScriptDependency=The externally managed, dependent module '{0}' is not installed on this computer. To use the current script '{1}', ensure that its dependent script '{2}' is installed.\r\n        ScriptExternallyManagedScriptDependencyIsInstalled=The externally managed, dependent script '{0}' is already installed on this computer.\r\n        UnableToResolveModuleDependency=PowerShellGet cannot resolve the module dependency '{0}' of the module '{1}' on the repository '{2}'. Verify that the dependent module '{3}' is available in the repository '{4}'. If this dependent module '{5}' is managed externally, add it to the ExternalModuleDependencies entry in the PSData section of the module manifest.\r\n        FindingModuleDependencies=Finding module dependencies for version '{1}' of the module '{0}' from repository '{2}'.\r\n        InstallingDependencyModule=Installing the dependency module '{0}' with version '{1}' for the module '{2}'.\r\n        InstallingDependencyScript=Installing the dependency script '{0}' with version '{1}' for the script '{2}'.\r\n        SavingDependencyModule=Saving the dependency module '{0}' with version '{1}' for the module '{2}'.\r\n        SavingDependencyScript=Saving the dependency script '{0}' with version '{1}' for the script '{2}'.\r\n        ModuleUninstallationSucceeded=Successfully uninstalled the module '{0}' from module base '{1}'.\r\n        ScriptUninstallationSucceeded=Successfully uninstalled the script '{0}' from script base '{1}'.\r\n        AdminPrivilegesRequiredForUninstall=You cannot uninstall the module '{0}' from '{1}' because Administrator rights are required to uninstall from that folder. Log on to the computer with an account that has Administrator rights, and then try again. You can also try running the Windows PowerShell session with elevated rights (Run as Administrator).\r\n        AdminPrivilegesRequiredForScriptUninstall=You cannot uninstall the script '{0}' from '{1}' because Administrator rights are required to uninstall from that folder. Log on to the computer with an account that has Administrator rights, and then try again. You can also try running the Windows PowerShell session with elevated rights (Run as Administrator).\r\n        ModuleUninstallationNotPossibleAsItIsNotInstalledUsingPowerShellGet=Module '{0}' was not installed on this computer by using either the PowerShellGet cmdlets or the PowerShellGet provider, so it cannot be uninstalled.\r\n        ScriptUninstallationNotPossibleAsItIsNotInstalledUsingPowerShellGet=Script '{0}' was not installed on this computer by using either the PowerShellGet cmdlets or the PowerShellGet provider, so it cannot be uninstalled.\r\n        UnableToUninstallModuleVersion=The module '{0}' of version '{1}' in module base folder '{2}' was installed without side-by-side version support. Some versions are installed in this module base with side-by-side version support. Uninstall other versions of this module before uninstalling the most current version.\r\n        UnableToUninstallAsOtherModulesNeedThisModule=The module '{0}' of version '{1}' in module base folder '{2}' cannot be uninstalled, because one or more other modules '{3}' are dependent on this module. Uninstall the modules that depend on this module before uninstalling module '{4}'.\r\n        UnableToUninstallAsOtherScriptsNeedThisScript=The script '{0}' of version '{1}' in script base folder '{2}' cannot be uninstalled, because one or more other scripts '{3}' are dependent on this script. Uninstall the scripts that depend on this script before uninstalling script '{4}'.\r\n        RepositoryIsNotTrusted=Untrusted repository\r\n        QueryInstallUntrustedPackage=You are installing the modules from an untrusted repository. If you trust this repository, change its InstallationPolicy value by running the Set-PSRepository cmdlet. Are you sure you want to install the modules from '{1}'?\r\n        QueryInstallUntrustedScriptPackage=You are installing the scripts from an untrusted repository. If you trust this repository, change its InstallationPolicy value by running the Set-PSRepository cmdlet. Are you sure you want to install the scripts from '{1}'?\r\n        QuerySaveUntrustedPackage=You are downloading the modules from an untrusted repository. If you trust this repository, change its InstallationPolicy value by running the Set-PSRepository cmdlet. Are you sure you want to download the modules from '{1}'?\r\n        QuerySaveUntrustedScriptPackage=You are downloading the scripts from an untrusted repository. If you trust this repository, change its InstallationPolicy value by running the Set-PSRepository cmdlet. Are you sure you want to download the scripts from '{1}'?\r\n        SourceNotFound=Unable to find repository '{0}'. Use Get-PSRepository to see all available repositories.\r\n        PSGalleryApiV2Deprecated=PowerShell Gallery v2 has been deprecated.  Please run 'Update-Module -Name PowerShellGet' to update to PowerShell Gallery v3.  For more information, please visit our website at 'https://www.powershellgallery.com'.\r\n        PSGalleryApiV2Discontinued=PowerShell Gallery v2 has been discontinued.  Please run 'Update-Module -Name PowerShellGet' to update to PowerShell Gallery v3.  For more information, please visit our website at 'https://www.powershellgallery.com'.\r\n        PowerShellGalleryUnavailable=PowerShell Gallery is currently unavailable.  Please try again later.\r\n        PowerShellGetModuleIsNotInstalledProperly=The PowerShellGet module was not installed properly. Be sure that only one instance or version of the PowerShellGet module is installed in the path '{0}'.\r\n        PowerShelLGetModuleGotUpdated=The PowerShellGet module was updated successfully. Restart the process to use the updated version of the PowerShellGet module.\r\n        TagsShouldBeIncludedInManifestFile=Tags are now supported in the module manifest file (.psd1). Update the module manifest file of module '{0}' in '{1}' with the newest tag changes. You can run Update-ModuleManifest -Tags to update the manifest with tags.\r\n        ReleaseNotesShouldBeIncludedInManifestFile=ReleaseNotes is now supported in the module manifest file (.psd1). Update the module manifest file of module '{0}' in '{1}' with the newest ReleaseNotes changes. You can run Update-ModuleManifest -ReleaseNotes to update the manifest with ReleaseNotes.\r\n        LicenseUriShouldBeIncludedInManifestFile=LicenseUri is now supported in the module manifest file (.psd1). Update the module manifest file of module '{0}' with the newest LicenseUri changes. You can run Update-ModuleManifest -LicenseUri to update the manifest with LicenseUri.\r\n        IconUriShouldBeIncludedInManifestFile=IconUri is now supported in the module manifest file (.psd1). Update the module manifest file of module '{0}' in '{1}' with the newest IconUri changes. You can run Update-ModuleManifest -IconUri to update the manifest with IconUri.\r\n        ProjectUriShouldBeIncludedInManifestFile=ProjectUri is now supported in the module manifest file (.psd1). Update the module manifest file of module '{0}' in '{1}' with the newest ProjectUri changes. You can run Update-ModuleManifest -ProjectUri to update the manifest with ProjectUri.\r\n        ShouldIncludeFunctionsToExport=This module '{0}' has exported functions. As a best practice, include exported functions in the module manifest file(.psd1). You can run Update-ModuleManifest -FunctionsToExport to update the manifest with ExportedFunctions field.\r\n        ShouldIncludeCmdletsToExport=This module '{0}' has exported cmdlets. As a best practice, include exported cmdlets in the module manifest file(.psd1). You can run Update-ModuleManifest -CmdletsToExport to update the manifest with ExportedCmdlets field.\r\n        ShouldIncludeDscResourcesToExport=This module '{0}' has exported DscResources. As a best practice, include exported DSC resources in the module manifest file(.psd1). If your PowerShell version is higher than 5.0, run Update-ModuleManifest -DscResourcesToExport to update the manifest with ExportedDscResources field.\r\n        UpdateModuleManifestPathCannotFound=Cannot load the manifest file '{0}' properly. Please specify the correct manifest path.\r\n        UpdatedModuleManifestNotValid=Cannot update the manifest file '{0}' because the manifest is not valid. Verify that the manifest file is valid, and then try again.'{1}'\r\n        ExportedDscResourcesNotSupportedOnLowerPowerShellVersion=The ExportedDscResources property is not supported in module manifests on PowerShell versions that are older than 5.0. Remove the value for the parameter 'DscResourcesToExport', and then try again.\r\n        CompatiblePSEditionsNotSupportedOnLowerPowerShellVersion=The CompatiblePSEditions property is not supported in module manifests on PowerShell versions that are older than 5.1. Remove the value for the parameter 'CompatiblePSEditions', and then try again.\r\n        ExternalModuleDependenciesNotSpecifiedInRequiredOrNestedModules='{0}' is listed in ExternalModuleDependencies, but it is not found in either the RequiredModules or NestedModules properties. Verify that this module is required for ExternalModuleDependencies, and then add it to NestedModules or RequiredModules.\r\n        TestModuleManifestFail=Cannot update the manifest properly. '{0}'\r\n        PackageManagementProvidersNotInModuleBaseFolder=PackageManagementProvider '{0}' is not found in the module base '{1}'. Verify that the PackageManagementProvider specified is within the module base.\r\n        UpdateManifestContentMessage=Update manifest file with new contents:\r\n        InvalidPackageManagementProviderValue=The PackageManagementProvider value cannot be '{0}'. Valid values for provider names include '{1}', and the default value for this parameter is '{2}'.\r\n        PowerShellGetUpdateIsNotSupportedOnLowerPSVersions=Self update of the PowerShellGet module is supported only in PowerShell 5.0 and newer releases. It is not supported in PowerShell 3.0 or 4.0.\r\n        ScriptVersionShouldBeGreaterThanGalleryVersion=Script '{0}' with version '{1}' cannot be published. The version must exceed the current version '{2}' that exists in the repository '{3}', or you must specify -Force.\r\n        ScriptVersionIsAlreadyAvailableInTheGallery=The script '{0}' with version '{1}' cannot be published as the current version '{2}' is already available in the repository '{3}'.\r\n        ScriptPrereleaseStringShouldBeGreaterThanGalleryPrereleaseString=Script '{0}' with version '{1}' and prerelease '{2}' cannot be published. The prerelease string must exceed the current prerelease string '{3}' that exists in the repository '{4}', or you must specify -Force.\r\n        ScriptParseError=The specified script file '{0}' has parse errors, try again after fixing the parse errors.\r\n        InvalidScriptToPublish=Script file '{0}' cannot be published because it does not have the required script metadata. Run Update-ScriptFileInfo -Path '{1}' to add the script metadata.\r\n        FailedToCreateCompressedScript=Failed to generate the compressed file for script '{0}'.\r\n        FailedToPublishScript=Failed to publish script '{0}': '{1}'.\r\n        PublishedScriptSuccessfully=Successfully published script '{0}' to the publish location '{1}'. Please allow few minutes for '{2}' to show up in the search results.\r\n        UnableToResolveScriptDependency=PowerShellGet cannot resolve the {0} dependency '{1}' of the script '{2}' on the repository '{3}'. Verify that the dependent {0} '{1}' is available in the repository '{3}'. If this dependent {0} '{1}' is managed externally, add it to the '{4}' entry in the script metadata.\r\n        InvalidVersion=Cannot convert value '{0}' to type 'System.Version'.\r\n        InvalidGuid=Cannot convert value '{0}' to type 'System.Guid'.\r\n        InvalidParameterValue=The specified value '{0}' for the parameter '{1}' is invalid. Ensure that it does not contain '<#' or '#>'.\r\n        MissingPSScriptInfo=PSScriptInfo is not specified in the script file '{0}'. You can use the Update-ScriptFileInfo with -Force or New-ScriptFileInfo cmdlet to add the PSScriptInfo to the script file.\r\n        MissingRequiredPSScriptInfoProperties=Script '{0}' is missing required metadata properties. Verify that the script file has Version, Guid, Description and Author properties. You can use the Update-ScriptFileInfo or New-ScriptFileInfo cmdlet to add or update the PSScriptInfo to the script file.\r\n        SkippedScriptDependency=Because dependent script '{0}' was skipped in the script dependencies list, users might not know how to install it.\r\n        SourceLocationPathsForModulesAndScriptsShouldBeEqual=SourceLocation '{0}' and ScriptSourceLocation '{1}' should be same for SMB Share or Local directory based repositories.\r\n        PublishLocationPathsForModulesAndScriptsShouldBeEqual=PublishLocation '{0}' and ScriptPublishLocation '{1}' should be same for SMB Share or Local directory based repositories.\r\n        SpecifiedNameIsAlearyUsed=The specified name '{0}' is already used for a different item on the specified repository '{1}'. Run '{2} -Name {0} -Repository {1}' to check whether the specified name '{0}' is already taken.\r\n        InvalidScriptFilePath=The script file path '{0}' is not valid. The value of the Path argument must resolve to a single file that has a '.ps1' extension. Change the value of the Path argument to point to a valid ps1 file, and then try again.\r\n        NuGetApiKeyIsRequiredForNuGetBasedGalleryService=NuGetApiKey is required for publishing a module or script file to the specified repository '{0}' whose publish location is '{1}'. Try again after specifying a valid value for the NuGetApiKey parameter. To get your API key, view your profile page.\r\n        ScriptFileExist=The specified script file '{0}' already exists.\r\n        InvalidEnvironmentVariableName=The specified environment variable name '{0}' exceeded the allowed limit of '{1}' characters.\r\n        PublishLocation=Publish Location:'{0}'.\r\n        ScriptPATHPromptCaption=PATH Environment Variable Change\r\n        ScriptPATHPromptQuery=Your system has not been configured with a default script installation path yet, which means you can only run a script by specifying the full path to the script file. This action places the script into the folder '{0}', and adds that folder to your PATH environment variable. Do you want to add the script installation path '{0}' to the PATH environment variable?\r\n        AddedScopePathToProcessSpecificPATHVariable=Added scripts installation location '{0}' for '{1}' scope to process specific PATH environment variable.\r\n        AddedScopePathToPATHVariable=Added scripts installation location '{0}' for '{1}' scope to PATH environment variable.\r\n        FilePathInFileListNotWithinModuleBase=Path '{0}' defined in FileList is not within module base '{1}'. Provide the correct FileList parameters and then try again.\r\n        ManifestFileReadWritePermissionDenied=The current user does not have read-write permissions for the file:'{0}'. Check the file permissions and then try again.\r\n        MissingTheRequiredPathOrPassThruParameter=The Path or PassThru parameter is required for creating the script file info. A new script file will be created with the script file info when the Path parameter is specified. Script file info will be returned if the PassThru parameter is specified. Try again after specifying the required parameter.\r\n        DescriptionParameterIsMissingForAddingTheScriptFileInfo=Description parameter is missing for adding the metadata to the script file. Try again after specifying the description.\r\n        UnableToAddPSScriptInfo=Unable to add PSScriptInfo to the script file '{0}'. You can use the New-ScriptFileInfo cmdlet to add the metadata to the existing script file.\r\n        RegisterVSTSFeedAsNuGetPackageSource=Publishing to a VSTS package management feed '{0}' requires it to be registered as a NuGet package source. Retry after adding this source '{0}' as NuGet package source by following the instructions specified at '{1}'\r\n        InvalidModuleAuthenticodeSignature=The module '{0}' cannot be installed or updated because the authenticode signature of the file '{1}' is not valid.\r\n        InvalidCatalogSignature=The module '{0}' cannot be installed because the catalog signature in '{1}' does not match the hash generated from the module.\r\n        AuthenticodeIssuerMismatch=Authenticode issuer '{0}' of the new module '{1}' with version '{2}' from root certificate authority '{3}' is not matching with the authenticode issuer '{4}' of the previously-installed module '{5}' with version '{6}' from root certificate authority '{7}'. If you still want to install or update, use -SkipPublisherCheck parameter.\r\n        ModuleCommandAlreadyAvailable=The following commands are already available on this system:'{0}'. This module '{1}' may override the existing commands. If you still want to install this module '{1}', use -AllowClobber parameter.\r\n        CatalogFileFound=Found the catalog file '{0}' in the module '{1}' contents.\r\n        CatalogFileNotFoundInAvailableModule=Catalog file '{0}' is not found in the contents of the previously-installed module '{1}' with the same name.\r\n        CatalogFileNotFoundInNewModule=Catalog file '{0}' is not found in the contents of the module '{1}' being installed.\r\n        ValidAuthenticodeSignature=Valid authenticode signature found in the catalog file '{0}' for the module '{1}'.\r\n        ValidAuthenticodeSignatureInFile=Valid authenticode signature found in the file '{0}' for the module '{1}'.\r\n        ValidatingCatalogSignature=Validating the '{0}' module files for catalog signing using the catalog file '{1}'.\r\n        AuthenticodeIssuerMatch=Authenticode issuer '{0}' of the new module '{1}' with version '{2}' matches with the authenticode issuer '{3}' of the previously-installed module '{4}' with version '{5}'.\r\n        ValidCatalogSignature=The catalog signature in '{0}' of the module '{1}' is valid and matches with the hash generated from the module contents.\r\n        SkippingPublisherCheck=Skipping the Publisher check for the version '{0}' of module '{1}'.\r\n        SourceModuleDetailsForPublisherValidation=For publisher validation, using the previously-installed module '{0}' with version '{1}' under '{2}' with publisher name '{3}' from root certificate authority '{4}'. Is this module signed by Microsoft: '{5}'.\r\n        NewModuleVersionDetailsForPublisherValidation=For publisher validation, current module '{0}' with version '{1}' with publisher name '{2}' from root certificate authority '{3}'. Is this module signed by Microsoft: '{4}'.\r\n        PublishersMatch=Publisher '{0}' of the new module '{1}' with version '{2}' matches with the publisher '{3}' of the previously-installed module '{4}' with version '{5}'. Both versions are signed with a Microsoft root certificate.\r\n        PublishersMismatch=A Microsoft-signed module named '{0}' with version '{1}' that was previously installed conflicts with the new module '{2}' from publisher '{3}' with version '{4}'. Installing the new module may result in system instability. If you still want to install or update, use -SkipPublisherCheck parameter.\r\n        ModuleIsNotCatalogSigned=The version '{0}' of the module '{1}' being installed is not catalog signed. Ensure that the version '{0}' of the module '{1}' has the catalog file '{2}' and signed with the same publisher '{3}' as the previously-installed module '{1}' with version '{4}' under the directory '{5}'. If you still want to install or update, use -SkipPublisherCheck parameter.\r\n        SentEnvironmentVariableChangeMessage=Successfully broadcasted the Environment variable changes.\r\n        UnableToSendEnvironmentVariableChangeMessage=Error in broadcasting the Environment variable changes.\r\n        LicenseUriNotSpecified='LicenseUri' is not specified. 'LicenseUri' must be provided when user license acceptance is required.\r\n        LicenseTxtNotFound=License.txt not Found. License.txt must be provided when user license acceptance is required.\r\n        LicenseTxtEmpty=License.txt is empty.\r\n        requireLicenseAcceptanceNotSupported=Require License Acceptance is not supported on Format version '{0}'.\r\n        AcceptanceLicenseQuery=Do you accept the license terms for module '{0}'.\r\n        ForceAcceptLicense=License Acceptance is required for module '{0}'. Please specify '-AcceptLicense' to perform this operation.\r\n        InvalidValueBoolean=The specified value '{0}' for the parameter '{1}' is invalid. It should be $true or $false.\r\n        UserDeclinedLicenseAcceptance=User declined license acceptance.\r\n        AcceptLicense=License Acceptance\r\n        RequiredScriptVersion=REQUIREDSCRIPTS: Required version of script '{0}' is '{1}'.\r\n        RequiredScriptVersoinFormat=<ScriptName>, <ScriptName>:<MinimumVersion>, <ScriptName>:[<RequiredVersion>], <ScriptName>:[<MinimumVersion>,<MaximumVersion>], <ScriptName>:[,<MaximumVersion>]\r\n        FailedToParseRequiredScripts=Cannot parse REQUIREDSCRIPTS '{0}'. Acceptable formats are: '{1}'.\r\n        FailedToParseRequiredScriptsVersion=Version format error: {0}, '{1}'. Acceptable formats are: '{2}'.\r\n        PublishersMismatchAsWarning=Module '{0}' version '{1}' published by '{2}' will be superceded by version '{3}' published by '{4}'. If you do not trust the new publisher, uninstall the module.\r\n        UnableToDownloadThePackage=The PackageManagement provider '{0}' is unable to download the package '{1}' version '{2}' to '{3}' path.\r\n        ValidatingTheModule=Validating the '{0}' module contents under '{1}' path.\r\n        ModuleValidationFailed=Unable to validate the '{0}' module contents under '{1}' path.\r\n        ValidatedModuleManifestFile=Test-ModuleManifest successfully validated the module manifest file '{0}'.\r\n        ValidateModuleAuthenticodeSignature=Validating the authenticode signature and publisher of the catalog file or module manifest file of the module '{0}'.\r\n        ValidateModuleCommandAlreadyAvailable=Checking for possible command collisions for the module '{0}' commands.\r\n        UnauthorizedAccessError=Access to the path '{0}' is denied.\r\n###PSLOC\r\n'@\r\n\r\n# SIG # Begin signature block\r\n# MIIjkgYJKoZIhvcNAQcCoIIjgzCCI38CAQExDzANBglghkgBZQMEAgEFADB5Bgor\r\n# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG\r\n# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAUMj4wb0r0V933\r\n# Kxwf6eV800i5N8GnGMPseytvd1lnEKCCDYEwggX/MIID56ADAgECAhMzAAABh3IX\r\n# chVZQMcJAAAAAAGHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD\r\n# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p\r\n# bmcgUENBIDIwMTEwHhcNMjAwMzA0MTgzOTQ3WhcNMjEwMzAzMTgzOTQ3WjB0MQsw\r\n# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u\r\n# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy\r\n# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\r\n# AQDOt8kLc7P3T7MKIhouYHewMFmnq8Ayu7FOhZCQabVwBp2VS4WyB2Qe4TQBT8aB\r\n# znANDEPjHKNdPT8Xz5cNali6XHefS8i/WXtF0vSsP8NEv6mBHuA2p1fw2wB/F0dH\r\n# sJ3GfZ5c0sPJjklsiYqPw59xJ54kM91IOgiO2OUzjNAljPibjCWfH7UzQ1TPHc4d\r\n# weils8GEIrbBRb7IWwiObL12jWT4Yh71NQgvJ9Fn6+UhD9x2uk3dLj84vwt1NuFQ\r\n# itKJxIV0fVsRNR3abQVOLqpDugbr0SzNL6o8xzOHL5OXiGGwg6ekiXA1/2XXY7yV\r\n# Fc39tledDtZjSjNbex1zzwSXAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE\r\n# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUhov4ZyO96axkJdMjpzu2zVXOJcsw\r\n# UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1\r\n# ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDU4Mzg1MB8GA1UdIwQYMBaAFEhu\r\n# ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu\r\n# bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w\r\n# Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3\r\n# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx\r\n# MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAixmy\r\n# S6E6vprWD9KFNIB9G5zyMuIjZAOuUJ1EK/Vlg6Fb3ZHXjjUwATKIcXbFuFC6Wr4K\r\n# NrU4DY/sBVqmab5AC/je3bpUpjtxpEyqUqtPc30wEg/rO9vmKmqKoLPT37svc2NV\r\n# BmGNl+85qO4fV/w7Cx7J0Bbqk19KcRNdjt6eKoTnTPHBHlVHQIHZpMxacbFOAkJr\r\n# qAVkYZdz7ikNXTxV+GRb36tC4ByMNxE2DF7vFdvaiZP0CVZ5ByJ2gAhXMdK9+usx\r\n# zVk913qKde1OAuWdv+rndqkAIm8fUlRnr4saSCg7cIbUwCCf116wUJ7EuJDg0vHe\r\n# yhnCeHnBbyH3RZkHEi2ofmfgnFISJZDdMAeVZGVOh20Jp50XBzqokpPzeZ6zc1/g\r\n# yILNyiVgE+RPkjnUQshd1f1PMgn3tns2Cz7bJiVUaqEO3n9qRFgy5JuLae6UweGf\r\n# AeOo3dgLZxikKzYs3hDMaEtJq8IP71cX7QXe6lnMmXU/Hdfz2p897Zd+kU+vZvKI\r\n# 3cwLfuVQgK2RZ2z+Kc3K3dRPz2rXycK5XCuRZmvGab/WbrZiC7wJQapgBodltMI5\r\n# GMdFrBg9IeF7/rP4EqVQXeKtevTlZXjpuNhhjuR+2DMt/dWufjXpiW91bo3aH6Ea\r\n# jOALXmoxgltCp1K7hrS6gmsvj94cLRf50QQ4U8Qwggd6MIIFYqADAgECAgphDpDS\r\n# AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK\r\n# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0\r\n# IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0\r\n# ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla\r\n# MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS\r\n# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT\r\n# H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB\r\n# AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG\r\n# OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S\r\n# 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz\r\n# y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7\r\n# 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u\r\n# M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33\r\n# X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl\r\n# XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP\r\n# 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB\r\n# l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF\r\n# RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM\r\n# CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ\r\n# BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud\r\n# DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO\r\n# 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0\r\n# LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p\r\n# Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y\r\n# Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB\r\n# FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw\r\n# cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA\r\n# XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY\r\n# 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj\r\n# 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd\r\n# d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ\r\n# Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf\r\n# wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ\r\n# aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j\r\n# NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B\r\n# xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96\r\n# eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7\r\n# r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I\r\n# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVZzCCFWMCAQEwgZUwfjELMAkG\r\n# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx\r\n# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z\r\n# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAYdyF3IVWUDHCQAAAAABhzAN\r\n# BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor\r\n# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgLIu7f8le\r\n# gQ0ndTd8gyAEe0fnNBrhCsEUfHD+upEyb7owQgYKKwYBBAGCNwIBDDE0MDKgFIAS\r\n# AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN\r\n# BgkqhkiG9w0BAQEFAASCAQCWjkfbjU+QuaidvjCSfT9ZWmVRt7eVzD7wasyZEXwC\r\n# uPWX5GwoR4xPMYzA/ohAElfSdrP6HWH9R+2sdXnUCJK+7w6N9wbB+S9Da0r3UcHj\r\n# acV7JEftJK6ZwZ9EyebTgHv6Oa0xhuaRh/BINH4OhfIZEy3A2Lg4KhvNMjGKHTi2\r\n# agmGkKLUqySkyv48c/HCApLbZ3ugNqI06C284kostGCqpuSg6HRDcGPDzZSkT6l4\r\n# u1veNMmcpeGzd3NTNy5fkt8jQt3OUQ9NmfYN5nxh1BgDB1kyDm5lWMiZqFqlLS9T\r\n# sG/jgYnqnprYVqTa8rYsSdmn8y1idSkQ1M715PQlOYNuoYIS8TCCEu0GCisGAQQB\r\n# gjcDAwExghLdMIIS2QYJKoZIhvcNAQcCoIISyjCCEsYCAQMxDzANBglghkgBZQME\r\n# AgEFADCCAVUGCyqGSIb3DQEJEAEEoIIBRASCAUAwggE8AgEBBgorBgEEAYRZCgMB\r\n# MDEwDQYJYIZIAWUDBAIBBQAEIOjiV1RbUVB0CleqHpkpsACXwys4XtATfTNyD7Bu\r\n# Zv+1AgZfYPphXsEYEzIwMjAwOTIyMjIxOTUxLjg2N1owBIACAfSggdSkgdEwgc4x\r\n# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt\r\n# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1p\r\n# Y3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMg\r\n# VFNTIEVTTjowQTU2LUUzMjktNEQ0RDElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt\r\n# U3RhbXAgU2VydmljZaCCDkQwggT1MIID3aADAgECAhMzAAABJy9uo++RqBmoAAAA\r\n# AAEnMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo\r\n# aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y\r\n# cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw\r\n# MB4XDTE5MTIxOTAxMTQ1OVoXDTIxMDMxNzAxMTQ1OVowgc4xCzAJBgNVBAYTAlVT\r\n# MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK\r\n# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVy\r\n# YXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjowQTU2\r\n# LUUzMjktNEQ0RDElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vydmlj\r\n# ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPgB3nERnk6fS40vvWeD\r\n# 3HCgM9Ep4xTIQiPnJXE9E+HkZVtTsPemoOyhfNAyF95E/rUvXOVTUcJFL7Xb16jT\r\n# KPXONsCWY8DCixSDIiid6xa30TiEWVcIZRwiDlcx29D467OTav5rA1G6TwAEY5rQ\r\n# jhUHLrOoJgfJfakZq6IHjd+slI0/qlys7QIGakFk2OB6mh/ln/nS8G4kNRK6Do4g\r\n# xDtnBSFLNfhsSZlRSMDJwFvrZ2FCkaoexd7rKlUNOAAScY411IEqQeI1PwfRm3aW\r\n# bS8IvAfJPC2Ah2LrtP8sKn5faaU8epexje7vZfcZif/cbxgUKStJzqbdvTBNc93n\r\n# /Z8CAwEAAaOCARswggEXMB0GA1UdDgQWBBTl9JZVgF85MSRbYlOJXbhY022V8jAf\r\n# BgNVHSMEGDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8ETzBNMEugSaBH\r\n# hkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNU\r\n# aW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUF\r\n# BzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1RpbVN0\r\n# YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsG\r\n# AQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IBAQAKyo180VXHBqVnjZwQy7NlzXbo2+W5\r\n# qfHxR7ANV5RBkRkdGamkwUcDNL+DpHObFPJHa0oTeYKE0Zbl1MvvfS8RtGGdhGYG\r\n# CJf+BPd/gBCs4+dkZdjvOzNyuVuDPGlqQ5f7HS7iuQ/cCyGHcHYJ0nXVewF2Lk+J\r\n# lrWykHpTlLwPXmCpNR+gieItPi/UMF2RYTGwojW+yIVwNyMYnjFGUxEX5/DtJjRZ\r\n# mg7PBHMrENN2DgO6wBelp4ptyH2KK2EsWT+8jFCuoKv+eJby0QD55LN5f8SrUPRn\r\n# K86fh7aVOfCglQofo5ABZIGiDIrg4JsV4k6p0oBSIFOAcqRAhiH+1spCMIIGcTCC\r\n# BFmgAwIBAgIKYQmBKgAAAAAAAjANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMC\r\n# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV\r\n# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJv\r\n# b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMTAwNzAxMjEzNjU1WhcN\r\n# MjUwNzAxMjE0NjU1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv\r\n# bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0\r\n# aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCASIw\r\n# DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkdDbx3EYo6IOz8E5f1+n9plGt0\r\n# VBDVpQoAgoX77XxoSyxfxcPlYcJ2tz5mK1vwFVMnBDEfQRsalR3OCROOfGEwWbEw\r\n# RA/xYIiEVEMM1024OAizQt2TrNZzMFcmgqNFDdDq9UeBzb8kYDJYYEbyWEeGMoQe\r\n# dGFnkV+BVLHPk0ySwcSmXdFhE24oxhr5hoC732H8RsEnHSRnEnIaIYqvS2SJUGKx\r\n# Xf13Hz3wV3WsvYpCTUBR0Q+cBj5nf/VmwAOWRH7v0Ev9buWayrGo8noqCjHw2k4G\r\n# kbaICDXoeByw6ZnNPOcvRLqn9NxkvaQBwSAJk3jN/LzAyURdXhacAQVPIk0CAwEA\r\n# AaOCAeYwggHiMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBTVYzpcijGQ80N7\r\n# fEYbxTNoWoVtVTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMC\r\n# AYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvX\r\n# zpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20v\r\n# cGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYI\r\n# KwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5j\r\n# b20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDCBoAYDVR0g\r\n# AQH/BIGVMIGSMIGPBgkrBgEEAYI3LgMwgYEwPQYIKwYBBQUHAgEWMWh0dHA6Ly93\r\n# d3cubWljcm9zb2Z0LmNvbS9QS0kvZG9jcy9DUFMvZGVmYXVsdC5odG0wQAYIKwYB\r\n# BQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AUABvAGwAaQBjAHkAXwBTAHQAYQB0AGUA\r\n# bQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAAfmiFEN4sbgmD+BcQM9naOh\r\n# IW+z66bM9TG+zwXiqf76V20ZMLPCxWbJat/15/B4vceoniXj+bzta1RXCCtRgkQS\r\n# +7lTjMz0YBKKdsxAQEGb3FwX/1z5Xhc1mCRWS3TvQhDIr79/xn/yN31aPxzymXlK\r\n# kVIArzgPF/UveYFl2am1a+THzvbKegBvSzBEJCI8z+0DpZaPWSm8tv0E4XCfMkon\r\n# /VWvL/625Y4zu2JfmttXQOnxzplmkIz/amJ/3cVKC5Em4jnsGUpxY517IW3DnKOi\r\n# PPp/fZZqkHimbdLhnPkd/DjYlPTGpQqWhqS9nhquBEKDuLWAmyI4ILUl5WTs9/S/\r\n# fmNZJQ96LjlXdqJxqgaKD4kWumGnEcua2A5HmoDF0M2n0O99g/DhO3EJ3110mCII\r\n# YdqwUB5vvfHhAN/nMQekkzr3ZUd46PioSKv33nJ+YWtvd6mBy6cJrDm77MbL2IK0\r\n# cs0d9LiFAR6A+xuJKlQ5slvayA1VmXqHczsI5pgt6o3gMy4SKfXAL1QnIffIrE7a\r\n# KLixqduWsqdCosnPGUFN4Ib5KpqjEWYw07t0MkvfY3v1mYovG8chr1m1rtxEPJdQ\r\n# cdeh0sVV42neV8HR3jDA/czmTfsNv11P6Z0eGTgvvM9YBS7vDaBQNdrvCScc1bN+\r\n# NR4Iuto229Nfj950iEkSoYIC0jCCAjsCAQEwgfyhgdSkgdEwgc4xCzAJBgNVBAYT\r\n# AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD\r\n# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBP\r\n# cGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjow\r\n# QTU2LUUzMjktNEQ0RDElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy\r\n# dmljZaIjCgEBMAcGBSsOAwIaAxUAs5W4TmyDHMRM7iz6mgGojqvXHzOggYMwgYCk\r\n# fjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH\r\n# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD\r\n# Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIF\r\n# AOMUsu8wIhgPMjAyMDA5MjIyMTI5MTlaGA8yMDIwMDkyMzIxMjkxOVowdzA9Bgor\r\n# BgEEAYRZCgQBMS8wLTAKAgUA4xSy7wIBADAKAgEAAgIVPgIB/zAHAgEAAgIRtjAK\r\n# AgUA4xYEbwIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIB\r\n# AAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAEMD4esQRMLwQdhk\r\n# Co1zgvmclcwl3lYYpk1oMh1ndsU3+97Rt6FV3adS4Hezc/K94oQKjcxtMVzLzQhG\r\n# agM6XlqB31VD8n2nxVuaWD1yp2jm/0IvfL9nFMHJRhgANMiBdHqvqNrd86c/Kryq\r\n# sI0Ch0sOx9wg3BozzqQhmdNjf9c6MYIDDTCCAwkCAQEwgZMwfDELMAkGA1UEBhMC\r\n# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV\r\n# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRp\r\n# bWUtU3RhbXAgUENBIDIwMTACEzMAAAEnL26j75GoGagAAAAAAScwDQYJYIZIAWUD\r\n# BAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0B\r\n# CQQxIgQg6wLE4god37E/zRxYUqM58DbGQBLJxEvt6c6xU1jsZqYwgfoGCyqGSIb3\r\n# DQEJEAIvMYHqMIHnMIHkMIG9BCAbkuhLEoYdahb/BUyVszO2VDi6kB3MSaof/+8u\r\n# 7SM+IjCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u\r\n# MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp\r\n# b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB\r\n# Jy9uo++RqBmoAAAAAAEnMCIEIK4r6N3NISekswMCG1kSBJCCCePrlLDQWbMKz0wt\r\n# Lj6CMA0GCSqGSIb3DQEBCwUABIIBACY3cZHtQ2k6zfVG4NotND24Zp0mlZAFe4A+\r\n# BFDISaaIXS86mO142Y9Hkm9rAMBCIJbKB/Yj1yf1gbygqNCoJDHFxZbdmx5XbShg\r\n# PVfAQl00TuyQ86VYnFJtvdDODUnwuxErAFR1zyiGGBKYtQWhXNRmbhb1kRkWp5Fg\r\n# s9mwzZUoGI2UzXDtYb6HkjNIOMxCbWW/27YfCBnOkiP2tJMIU79R4xY4vwQeWkKW\r\n# dgtyHv+d7eBOd1aOi8HvqCstH6x06RC3DsYfZ/NbYSGuZpjSaSDDC7A1KvdPo6ti\r\n# UYayEGi9iXfqnAv4Iyzo3OWIN2M2iqepP2xwL8Ne2q1ImLpiZF0=\r\n# SIG # End signature block\r\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.Client/Add-WinGetSource.md",
    "content": "﻿---\nexternal help file: Microsoft.WinGet.Client.Cmdlets.dll-Help.xml\nModule Name: Microsoft.WinGet.Client\nms.date: 08/01/2024\nonline version:\nschema: 2.0.0\ntitle: Add-WinGetSource\n---\n\n# Add-WinGetSource\n\n## SYNOPSIS\nAdds a new source.\n\n## SYNTAX\n\n```\nAdd-WinGetSource -Name <String> -Argument <String> [-Type <String>] [-TrustLevel {Default | None | Trusted}] [-Explicit] [<CommonParameters>]\n```\n\n## DESCRIPTION\n\nAdds a new source. A source provides the data for you to discover and install packages. Only add a\nnew source if you trust it as a secure location. This command must be executed with administrator permissions.\n\n## EXAMPLES\n\n### Example 1: Add new REST source named mysource\n\n```powershell\nAdd-WinGetSource -Name mysource -Argument https://contoso.com/ -Type Microsoft.Rest\n```\n\nThis example adds a new REST source to WinGet named `mysource` with the root URL\n`https://contoso.com/`. The source must respond with the WinGet REST source API.\n\n## PARAMETERS\n\n### -Argument\n\nThe URL or UNC of either a pre-indexed WinGet source or a WinGet REST source API.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName, ByValue)\nAccept wildcard characters: False\n```\n\n### -Name\n\nThe name used to identify the WinGet source.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName, ByValue)\nAccept wildcard characters: False\n```\n\n### -Explicit\n\nExcludes a source from discovery unless specified.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -TrustLevel\n\nSpecify the trust level of the WinGet source. The parameter accepts the following values:\n\n- `None`\n- `Trusted`\n\n```yaml\nType: Microsoft.WinGet.Client.PSObjects.PSSourceTrustLevel\nParameter Sets: (All)\nAliases:\nAccepted values: None, Trusted\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Type\n\nThe type of the WinGet source. Most sources are `Microsoft.Rest`. The WinGet community repository\nis `Microsoft.PreIndexed.Package`.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName, ByValue)\nAccept wildcard characters: False\n```\n\n### CommonParameters\n\nThis cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable,\n-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable,\n-ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see\n[about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).\n\n## INPUTS\n\n### System.String\n\n## OUTPUTS\n\n### System.Object\n\n## NOTES\n\n## RELATED LINKS\n\n[Remove-WinGetSource](Remove-WinGetSource.md)\n\n[Reset-WinGetSource](Reset-WinGetSource.md)\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.Client/Assert-WinGetPackageManager.md",
    "content": "﻿---\nexternal help file: Microsoft.WinGet.Client.Cmdlets.dll-Help.xml\nModule Name: Microsoft.WinGet.Client\nms.date: 08/01/2024\nonline version:\nschema: 2.0.0\ntitle: Assert-WinGetPackageManager\n---\n\n# Assert-WinGetPackageManager\n\n## SYNOPSIS\nVerifies that WinGet is installed properly.\n\n## SYNTAX\n\n### IntegrityVersionSet (Default)\n\n```\nAssert-WinGetPackageManager [-Version <String>] [<CommonParameters>]\n```\n\n### IntegrityLatestSet\n\n```\nAssert-WinGetPackageManager [-Latest] [-IncludePrerelease] [<CommonParameters>]\n```\n\n## DESCRIPTION\n\nVerifies that WinGet is installed properly.\n\n> [!NOTE]\n> The cmdlet doesn't ensure that the latest version of WinGet is installed. It just verifies that\n> the installed version of Winget is supported by installed version of the Microsoft.WinGet.Client\n> module.\n\n## EXAMPLES\n\n### Example 1: Default usage\n\n```powershell\nAssert-WinGetPackageManager\n```\n\nIf the current version of WinGet is installed correctly, the command returns without error.\n\n### Example 2: Check if latest stable version is installed\n\n```powershell\nAssert-WinGetPackageManager -Latest\n```\n\nIf the latest version of WinGet is compatible with the installed Microsoft.WinGet.Client module, the\ncommand returns without error.\n\n### Example 3: Check if latest preview version is installed\n\n```powershell\nAssert-WinGetPackageManager -IncludePreRelease\n```\n\nIf the prerelease version of WinGet is compatible with the installed Microsoft.WinGet.Client module,\nthe command returns without error.\n\n### Example 4: Check if specific version is installed\n\n```powershell\nAssert-WinGetPackageManager -Version v1.8.1911\n```\n\nIf the specified version of WinGet is compatible with the installed Microsoft.WinGet.Client module,\nthe command returns without error.\n\n## PARAMETERS\n\n### -IncludePreRelease\n\nInclude preview versions of WinGet.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: IntegrityLatestSet\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Latest\n\nVerify that the latest version of WinGet is compatible with the installed version of the\nMicrosoft.WinGet.Client module.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: IntegrityLatestSet\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Version\n\nVerify that a specific version of WinGet is installed correctly.\n\n```yaml\nType: System.String\nParameter Sets: IntegrityVersionSet\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### CommonParameters\n\nThis cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable,\n-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable,\n-ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see\n[about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).\n\n## INPUTS\n\n### System.String\n\n### System.Management.Automation.SwitchParameter\n\n## OUTPUTS\n\n### System.Object\n\n## NOTES\n\nWhen using the `-Latest` or `-Version` parameters, this cmdlet makes GitHub API requests to query\nrelease information. Unauthenticated requests are subject to\n[GitHub API rate limits](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api),\nwhich can cause failures in CI/CD pipelines. If the `GH_TOKEN` or `GITHUB_TOKEN` environment\nvariable is set, the cmdlet automatically uses it to authenticate requests, which significantly\nincreases the rate limit.\n\n`GH_TOKEN` takes precedence over `GITHUB_TOKEN`, matching\n[GitHub CLI behavior](https://cli.github.com/manual/gh_help_environment). In GitHub Actions,\nyou can make `GITHUB_TOKEN` available to the cmdlet by mapping it as an environment variable in\nyour workflow step (e.g., `env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}`).\n\nUse `-Verbose` to see which token source is being used.\n\n## RELATED LINKS\n\n[Get-WinGetVersion](Get-WinGetVersion.md)\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.Client/Disable-WinGetSetting.md",
    "content": "﻿---\nexternal help file: Microsoft.WinGet.Client.Cmdlets.dll-Help.xml\nModule Name: Microsoft.WinGet.Client\nms.date: 08/01/2024\nonline version:\nschema: 2.0.0\ntitle: Disable-WinGetSetting\n---\n\n# Disable-WinGetSetting\n\n## SYNOPSIS\nDisables an administrative setting.\n\n## SYNTAX\n\n```\nDisable-WinGetSetting [-Name] <String> [<CommonParameters>]\n```\n\n## DESCRIPTION\n\nThis command disables an administrative setting. The command must be run from an elevated session\nusing the **Run as Administrator** option.\n\nThis command support the following administrative settings:\n\n- LocalManifestFiles\n- BypassCertificatePinningForMicrosoftStore\n- InstallerHashOverride\n- LocalArchiveMalwareScanOverride\n- ProxyCommandLineOptions\n\nAdministrative settings are disabled by default. Administrative settings can also be managed using\nGroup Policy objects.\n\n## EXAMPLES\n\n### Example 1: Disable the use of local manifest files\n\n```powershell\nDisable-WinGetSetting -Name LocalManifestFiles\n```\n\nThis example shows how to disable the use of local manifest files.\n\n## PARAMETERS\n\n### -Name\n\nThe name of the WinGet administrative setting.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 0\nDefault value: None\nAccept pipeline input: True (ByPropertyName, ByValue)\nAccept wildcard characters: False\n```\n\n### CommonParameters\n\nThis cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable,\n-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable,\n-ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see\n[about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).\n\n## INPUTS\n\n### System.String\n\n## OUTPUTS\n\n### System.Object\n\n## NOTES\n\n## RELATED LINKS\n\n[Get-WinGetSetting](Get-WinGetSetting.md)\n\n[Set-WinGetUserSetting](Set-WinGetUserSetting.md)\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.Client/Enable-WinGetSetting.md",
    "content": "﻿---\nexternal help file: Microsoft.WinGet.Client.Cmdlets.dll-Help.xml\nModule Name: Microsoft.WinGet.Client\nms.date: 08/01/2024\nonline version:\nschema: 2.0.0\ntitle: Enable-WinGetSetting\n---\n\n# Enable-WinGetSetting\n\n## SYNOPSIS\n\nEnables WinGet administrative settings.\n\n## SYNTAX\n\n```\nEnable-WinGetSetting [-Name] <String> [<CommonParameters>]\n```\n\n## DESCRIPTION\n\nThis command enables an administrative setting. The command must be run from an elevated session\nusing the **Run as Administrator** option.\n\nThis command support the following administrative settings:\n\n- LocalManifestFiles\n- BypassCertificatePinningForMicrosoftStore\n- InstallerHashOverride\n- LocalArchiveMalwareScanOverride\n- ProxyCommandLineOptions\n\nAdministrative settings are disabled by default. Administrative settings can also be managed using\nGroup Policy objects.\n\n## EXAMPLES\n\n### Example 1\n\n```powershell\nEnable-WinGetSetting -Name LocalManifestFiles\n```\n\nThis example shows how to enable the use of local manifest files.\n\n## PARAMETERS\n\n### -Name\n\nThe name of the WinGet administrative setting.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: 0\nDefault value: None\nAccept pipeline input: True (ByPropertyName, ByValue)\nAccept wildcard characters: False\n```\n\n### CommonParameters\n\nThis cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable,\n-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable,\n-ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see\n[about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).\n\n## INPUTS\n\n### System.String\n\n## OUTPUTS\n\n### System.Object\n\n## NOTES\n\n## RELATED LINKS\n\n[Get-WinGetSetting](Get-WinGetSetting.md)\n\n[Disable-WinGetSetting](Disable-WinGetSetting.md)\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.Client/Export-WinGetPackage.md",
    "content": "﻿---\nexternal help file: Microsoft.WinGet.Client.Cmdlets.dll-Help.xml\nModule Name: Microsoft.WinGet.Client\nms.date: 08/01/2024\nonline version:\nschema: 2.0.0\ntitle: Export-WinGetPackage\n---\n\n# Export-WinGetPackage\n\n## SYNOPSIS\nDownloads a WinGet package and its dependencies.\n\n## SYNTAX\n\n### FoundSet (Default)\n\n```\nExport-WinGetPackage [-DownloadDirectory <String>] [-AllowHashMismatch]\n [-Architecture <PSProcessorArchitecture>] [-InstallerType <PSPackageInstallerType>] [-Locale <String>]\n [-Scope <PSPackageInstallScope>] [-SkipDependencies] [-Version <String>] [-Id <String>] [-Name <String>]\n [-Moniker <String>] [-Source <String>] [[-Query] <String[]>] [-MatchOption <PSPackageFieldMatchOption>]\n [-WhatIf] [-Confirm] [<CommonParameters>]\n```\n\n### GivenSet\n\n```\nExport-WinGetPackage [-DownloadDirectory <String>] [-AllowHashMismatch]\n [-Architecture <PSProcessorArchitecture>] [-InstallerType <PSPackageInstallerType>] [-Locale <String>]\n [-Scope <PSPackageInstallScope>] [-SkipDependencies] [[-PSCatalogPackage] <PSCatalogPackage>]\n [-Version <String>] [-WhatIf] [-Confirm] [<CommonParameters>]\n```\n\n## DESCRIPTION\n\nThis command downloads a WinGet package from a configured source. The command downloads the package,\nits manifest, as well as its dependencies and their manifests. By default, the packages are\ndownloaded to your `Downloads` folder. You can use the **DownloadDirectory** parameter to change\nthe location.\n\nFor Microsoft Azure users, if the package is coming from the Microsoft Store, the command also\ndownloads the package license file. The user needs to have one of the following Roles in Azure:\n\n- Global Administrator\n- User Administrator\n- License Administrator\n\n## EXAMPLES\n\n### Example 1: Download Microsoft.PowerShell to the default location\n\n```powershell\nExport-WinGetPackage -Id Microsoft.PowerShell\n```\n\n```Output\nId                   Name       Source Status ExtendedErrorCode CorrelationData\n--                   ----       ------ ------ ----------------- ---------------\nMicrosoft.PowerShell PowerShell winget Ok\n```\n\n```powershell\ndir ~\\Downloads\\Microsoft.PowerShell_7.4.4.0\n```\n\n```Output\n    Directory: C:\\Users\\user1\\Downloads\\Microsoft.PowerShell_7.4.4.0\n\nMode                 LastWriteTime         Length Name\n----                 -------------         ------ ----\n-a---            8/7/2024  2:05 PM      108404736 PowerShell_7.4.4.0_Machine_X64_wix_en-US.msi\n-a---            8/7/2024  2:05 PM           3838 PowerShell_7.4.4.0_Machine_X64_wix_en-US.yaml\n```\n\nThis example shows how to download a package for the current machine and scope. For this example,\nthe command downloads the latest version of the installer package and manifest for\nMicrosoft.PowerShell. The command puts the files a new folder in your `Downloads` location. The\nfolder name is created by concatenating the package identifier and version number.\n\n## PARAMETERS\n\n### -AllowHashMismatch\n\nAllows you to download package even when the SHA256 hash for an installer or a dependency does not\nmatch the SHA256 hash in the WinGet package manifest.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Architecture\n\nSpecify the processor architecture for the WinGet package installer.\n\n```yaml\nType: Microsoft.WinGet.Client.PSObjects.PSProcessorArchitecture\nParameter Sets: (All)\nAliases:\nAccepted values: Default, X86, Arm, X64, Arm64\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -DownloadDirectory\n\nSpecify the location where you want to store the downloaded files.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Id\n\nSpecify the WinGet package identifier\n\n```yaml\nType: System.String\nParameter Sets: FoundSet\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -InstallerType\n\nSpecify the type of installer package to download. This parameter accepts the following values:\n\n- `Default`\n- `Inno`\n- `Wix`\n- `Msi`\n- `Nullsoft`\n- `Zip`\n- `Msix`\n- `Exe`\n- `Burn`\n- `MSStore`\n- `Portable`\n\n> [!NOTE]\n> The installer type must be available in the WinGet package manifest.\n\n```yaml\nType: Microsoft.WinGet.Client.PSObjects.PSPackageInstallerType\nParameter Sets: (All)\nAliases:\nAccepted values: Default, Inno, Wix, Msi, Nullsoft, Zip, Msix, Exe, Burn, MSStore, Portable\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Locale\n\nSpecify the locale of the installer package. The locale must provided in the BCP 47 format, such as\n`en-US`. For more information, see\n[Standard locale names](/globalization/locale/standard-locale-names).\n\n> [!NOTE]\n> The locale must be available in the WinGet package manifest.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -MatchOption\n\nSpecify the match option for a WinGet package query. This parameter accepts the following values:\n\n- `Equals`\n- `EqualsCaseInsensitive`\n- `StartsWithCaseInsensitive`\n- `ContainsCaseInsensitive`\n\n```yaml\nType: Microsoft.WinGet.Client.PSObjects.PSPackageFieldMatchOption\nParameter Sets: FoundSet\nAliases:\nAccepted values: Equals, EqualsCaseInsensitive, StartsWithCaseInsensitive, ContainsCaseInsensitive\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Moniker\n\nSpecify the moniker of the WinGet package to download. For example, the moniker for the\nMicrosoft.PowerShell package is `pwsh`.\n\n```yaml\nType: System.String\nParameter Sets: FoundSet\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Name\n\nSpecify the name of the WinGet package.\n\n```yaml\nType: System.String\nParameter Sets: FoundSet\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -PSCatalogPackage\n\nProvide **PSCatalogPackage** object. You can get a **PSCatalogPackage** object by using the\n`Find-WinGetPackage` command.\n\n```yaml\nType: Microsoft.WinGet.Client.Engine.PSObjects.PSCatalogPackage\nParameter Sets: GivenSet\nAliases: InputObject\n\nRequired: False\nPosition: 0\nDefault value: None\nAccept pipeline input: True (ByPropertyName, ByValue)\nAccept wildcard characters: False\n```\n\n### -Query\n\nOne or more strings to search for in the WinGet package. The command searches for matching strings\nin the following properties of the package manifest:\n\n- `PackageName`\n- `PackageIdentifier`\n- `Moniker`\n- `Tags`\n\n```yaml\nType: System.String[]\nParameter Sets: FoundSet\nAliases:\n\nRequired: False\nPosition: 0\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Scope\n\nSpecify WinGet package installer scope. The parameter accepts the following values:\n\n- `Any`\n- `User`\n- `System`\n- `UserOrUnknown`\n- `SystemOrUnknown`\n\n> [!NOTE]\n> The installer scope must be available in the WinGet package manifest.\n\n```yaml\nType: Microsoft.WinGet.Client.PSObjects.PSPackageInstallScope\nParameter Sets: (All)\nAliases:\nAccepted values: Any, User, System, UserOrUnknown, SystemOrUnknown\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -SkipDependencies\n\nSpecifies that the command shouldn't download the WinGet package dependencies.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Source\n\nSpecifies WinGet source.\n\n```yaml\nType: System.String\nParameter Sets: FoundSet\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Version\n\nSpecifies the version of the WinGet package to download.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Confirm\n\nPrompts you for confirmation before running the cmdlet.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: (All)\nAliases: cf\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -WhatIf\n\nShows what would happen if the cmdlet runs. The cmdlet isn't run.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: (All)\nAliases: wi\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\n\nThis cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable,\n-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable,\n-ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see\n[about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).\n\n## INPUTS\n\n### System.String\n\n### System.Management.Automation.SwitchParameter\n\n### Microsoft.WinGet.Client.PSObjects.PSProcessorArchitecture\n\n### Microsoft.WinGet.Client.PSObjects.PSPackageInstallerType\n\n### Microsoft.WinGet.Client.PSObjects.PSPackageInstallScope\n\n### Microsoft.WinGet.Client.Engine.PSObjects.PSCatalogPackage\n\n### System.String[]\n\n### Microsoft.WinGet.Client.PSObjects.PSPackageFieldMatchOption\n\n## OUTPUTS\n\n### Microsoft.WinGet.Client.Engine.PSObjects.PSDownloadResult\n\n## NOTES\n\n## RELATED LINKS\n\n[Find-WinGetPackage](Find-WinGetPackage.md)\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.Client/Find-WinGetPackage.md",
    "content": "﻿---\nexternal help file: Microsoft.WinGet.Client.Cmdlets.dll-Help.xml\nModule Name: Microsoft.WinGet.Client\nms.date: 08/01/2024\nonline version:\nschema: 2.0.0\ntitle: Find-WinGetPackage\n---\n\n# Find-WinGetPackage\n\n## SYNOPSIS\nSearches for packages from configured sources.\n\n## SYNTAX\n\n```\nFind-WinGetPackage [-Tag <String>] [-Command <String>] [-Count <UInt32>] [-Id <String>] [-Name <String>]\n [-Moniker <String>] [-Source <String>] [[-Query] <String[]>] [-MatchOption <PSPackageFieldMatchOption>]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\n\nSearches for packages from configured sources.\n\n## EXAMPLES\n\n### Example 1: Search for PowerShell\n\n```powershell\nFind-WinGetPackage PowerShell\n```\n\nThis example shows how to search for packages related to PowerShell. By default, the command\nsearches all configured sources. The command compares the value provided to the following package\nmanifest properties:\n\n- `PackageIdentifier`\n- `PackageName`\n- `Moniker`\n- `Tags`\n\nThe command does a case-insensitive substring comparison of these properties.\n\n### Example 2: Search for Microsoft.PowerShell by id\n\n```powershell\nFind-WinGetPackage -Id Microsoft.PowerShell\n```\n\nThis example shows how to search for packages by package identifier. By default, the command\nsearches all configured sources. The command performs a case-insensitive substring match against the\n**PackageIdentifier** property of the packages.\n\n### Example 3: Search for Microsoft.PowerShell by exact id\n\n```powershell\nFind-WinGetPackage -Id Microsoft.PowerShell -MatchOption Equals\n```\n\nThis example shows how to search for packages by exact package identifier. By default, the command\nsearches all configured sources. The command performs a case-sensitive full text match against the\n**PackageIdentifier** property of the packages.\n\n## PARAMETERS\n\n### -Command\n\nSpecify the name of the command defined in the package manifest.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Count\n\nSpecify the maximum number of results to return.\n\n```yaml\nType: System.UInt32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Id\n\nSpecify the package identifier to search for. By default, the command does a case-insensitive substring match.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -MatchOption\n\nSpecify matching logic used for search. The parameter accepts the following values:\n\n- `Equals`\n- `EqualsCaseInsensitive`\n- `StartsWithCaseInsensitive`\n- `ContainsCaseInsensitive`\n\n```yaml\nType: Microsoft.WinGet.Client.PSObjects.PSPackageFieldMatchOption\nParameter Sets: (All)\nAliases:\nAccepted values: Equals, EqualsCaseInsensitive, StartsWithCaseInsensitive, ContainsCaseInsensitive\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Moniker\n\nSpecify the moniker of the package you are searching for.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Name\n\nSpecify the name of the package to search for.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Query\n\nSpecify one or more strings to search for. By default, the command searches all configured sources.\nThe command compares the value provided to the following package manifest properties:\n- `PackageIdentifier`\n- `PackageName`\n- `Moniker`\n- `Tags`\n\nThe command does a case-insensitive substring comparison of these properties.\n\n```yaml\nType: System.String[]\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 0\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Source\n\nSpecify the name of the WinGet source to search. The most common sources are `msstore` and `winget`.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Tag\n\nSpecify a package tag to search for.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### CommonParameters\n\nThis cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable,\n-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable,\n-ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see\n[about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).\n\n## INPUTS\n\n### System.String\n\n### System.UInt32\n\n### System.String[]\n\n### Microsoft.WinGet.Client.PSObjects.PSPackageFieldMatchOption\n\n## OUTPUTS\n\n### Microsoft.WinGet.Client.Engine.PSObjects.PSFoundCatalogPackage\n\n## NOTES\n\n## RELATED LINKS\n\n[Export-WinGetPackage](Export-WinGetPackage.md)\n\n[Install-WinGetPackage](Install-WinGetPackage.md)\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.Client/Get-WinGetPackage.md",
    "content": "﻿---\nexternal help file: Microsoft.WinGet.Client.Cmdlets.dll-Help.xml\nModule Name: Microsoft.WinGet.Client\nms.date: 08/01/2024\nonline version:\nschema: 2.0.0\ntitle: Get-WinGetPackage\n---\n\n# Get-WinGetPackage\n\n## SYNOPSIS\nLists installed packages.\n\n## SYNTAX\n\n```\nGet-WinGetPackage [-Tag <String>] [-Command <String>] [-Count <UInt32>] [-Id <String>] [-Name <String>]\n [-Moniker <String>] [-Source <String>] [[-Query] <String[]>] [-MatchOption <PSPackageFieldMatchOption>]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\n\nThis command lists all of the packages installed on your system. The output includes packages\ninstalled from WinGet sources and packages installed by other methods. Packages that have package\nidentifiers starting with `MSIX` or `ARP` could not be correlated to a WinGet source.\n\n## EXAMPLES\n\n### Example 1: Default example\n\n```powershell\nGet-WinGetPackage\n```\n\nThis example shows how to list all packages installed on your system.\n\n### Example 2: Get package by Id\n\n```powershell\nGet-WinGetPackage -Id \"Microsoft.PowerShell\"\n```\n\nThis example shows how to get an installed package by its package identifier.\n\n### Example 3: Get package(s) by name\n\n```powershell\nGet-WinGetPackage -Name \"PowerShell\"\n```\n\nThis example shows how to get installed packages that match a name value. The command does a substring comparison of the provided name with\ninstalled package names.\n\n### Example 4: List all packages with an available update\n\n```powershell\nGet-WinGetPackage | Where-Object IsUpdateAvailable\n```\n\nThis example shows how to list all packages that have an available upgrade from one of the configured sources.\n\n## PARAMETERS\n\n### -Command\n\nSpecify the name of the command defined in the package manifest.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Count\n\nLimits the number of items returned by the command.\n\n```yaml\nType: System.UInt32\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Id\n\nSpecify the package identifier for the package you want to list. By default, the command does a\ncase-insensitive substring comparison on the package identifier.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -MatchOption\n\nSpecify matching logic used for search. The parameter accepts the following values:\n\n- `Equals`\n- `EqualsCaseInsensitive`\n- `StartsWithCaseInsensitive`\n- `ContainsCaseInsensitive`\n\n```yaml\nType: Microsoft.WinGet.Client.PSObjects.PSPackageFieldMatchOption\nParameter Sets: (All)\nAliases:\nAccepted values: Equals, EqualsCaseInsensitive, StartsWithCaseInsensitive, ContainsCaseInsensitive\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Moniker\n\nSpecify the moniker of the package you want to list.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Name\n\nSpecify the name of the package to list. By default, the command does a case-insensitive comparison\nof the package name.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Query\n\nSpecify one or more strings to search for. By default, the command searches all configured sources.\nThe command compares the value provided to the following package manifest properties:\n\n- `PackageIdentifier`\n- `PackageName`\n- `Moniker`\n- `Tags`\n\nThe command does a case-insensitive substring comparison of these properties.\n\n```yaml\nType: System.String[]\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 0\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Source\n\nSpecify the name of the WinGet source of the package.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Tag\n\nSpecify a package tag to search for.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### CommonParameters\n\nThis cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable,\n-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable,\n-ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see\n[about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).\n\n## INPUTS\n\n### System.String\n\n### System.UInt32\n\n### System.String[]\n\n### Microsoft.WinGet.Client.PSObjects.PSPackageFieldMatchOption\n\n## OUTPUTS\n\n### Microsoft.WinGet.Client.Engine.PSObjects.PSInstalledCatalogPackage\n\n## NOTES\n\n## RELATED LINKS\n\n[Uninstall-WinGetPackage](Uninstall-WinGetPackage.md)\n\n[Update-WinGetPackage](Update-WinGetPackage.md)\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.Client/Get-WinGetSetting.md",
    "content": "﻿---\nexternal help file: Microsoft.WinGet.Client.Cmdlets.dll-Help.xml\nModule Name: Microsoft.WinGet.Client\nms.date: 08/01/2024\nonline version:\nschema: 2.0.0\ntitle: Get-WinGetSetting\n---\n\n# Get-WinGetSetting\n\n## SYNOPSIS\nGets WinGet configuration settings.\n\n## SYNTAX\n\n```\nGet-WinGetSetting [-AsPlainText] [<CommonParameters>]\n```\n\n## DESCRIPTION\n\nThis command gets the WinGet configuration settings. The settings include:\n- the schema\n- administrative settings\n- the location of the user settings file\nFor more information about WinGet settings, see\n[WinGet CLI Settings](https://aka.ms/winget-settings).\n\n## EXAMPLES\n\n### Example 1 - Display the WinGet configuration settings\n\n```powershell\nGet-WinGetSetting\n```\n\n```Output\n\nName              Value\n----              -----\n$schema           https://aka.ms/winget-settings-export.schema.json\nuserSettingsFile  C:\\Users\\user1\\AppData\\Local\\Packages\\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\\Local…\nadminSettings     {[ProxyCommandLineOptions, False], [LocalArchiveMalwareScanOverride, False], [InstallerH…\n```\n\n### Example 2 - Display the administrative settings in WinGet configuration\n\n```powershell\nGet-WinGetSetting | Select-Object -ExpandProperty adminSettings\n```\n\n```Output\nName                                      Value\n----                                      -----\nInstallerHashOverride                     False\nProxyCommandLineOptions                   False\nBypassCertificatePinningForMicrosoftStore False\nLocalArchiveMalwareScanOverride           False\nLocalManifestFiles                        True\n```\n\n## PARAMETERS\n\n### -AsPlainText\n\nOutput results as plain text\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### CommonParameters\n\nThis cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable,\n-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable,\n-ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see\n[about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).\n\n## INPUTS\n\n### System.Management.Automation.SwitchParameter\n\n## OUTPUTS\n\n### System.Object\n\n## NOTES\n\n## RELATED LINKS\n\n[Get-WinGetUserSetting](Get-WinGetUserSetting.md)\n\n[Set-WinGetUserSetting](Set-WinGetUserSetting.md)\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.Client/Get-WinGetSource.md",
    "content": "﻿---\nexternal help file: Microsoft.WinGet.Client.Cmdlets.dll-Help.xml\nModule Name: Microsoft.WinGet.Client\nms.date: 08/01/2024\nonline version:\nschema: 2.0.0\ntitle: Get-WinGetSource\n---\n\n# Get-WinGetSource\n\n## SYNOPSIS\nLists configured WinGet sources.\n\n## SYNTAX\n\n```\nGet-WinGetSource [[-Name] <String>] [<CommonParameters>]\n```\n\n## DESCRIPTION\n\nLists the configured WinGet sources.\n\n## EXAMPLES\n\n### Example 1: List all configured WinGet sources\n\n```powershell\nGet-WinGetSource\n```\n\n```Output\nName    Argument                                      Type\n----    --------                                      ----\nmsstore https://storeedgefd.dsx.mp.microsoft.com/v9.0 Microsoft.Rest\nwinget  https://cdn.winget.microsoft.com/cache        Microsoft.PreIndexed.Package\n```\n\n## PARAMETERS\n\n### -Name\n\nSpecify the name of the WinGet source to be displayed.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: 0\nDefault value: None\nAccept pipeline input: True (ByPropertyName, ByValue)\nAccept wildcard characters: False\n```\n\n### CommonParameters\n\nThis cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable,\n-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable,\n-ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see\n[about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).\n\n## INPUTS\n\n### System.String\n\n## OUTPUTS\n\n### Microsoft.WinGet.Client.Engine.PSObjects.PSSourceResult\n\n## NOTES\n\n## RELATED LINKS\n\n[Add-WinGetSource](Add-WinGetSource.md)\n\n[Remove-WinGetSource](Remove-WinGetSource.md)\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.Client/Get-WinGetUserSetting.md",
    "content": "﻿---\nexternal help file: Microsoft.WinGet.Client.Cmdlets.dll-Help.xml\nModule Name: Microsoft.WinGet.Client\nms.date: 08/01/2024\nonline version:\nschema: 2.0.0\ntitle: Get-WinGetUserSetting\n---\n\n# Get-WinGetUserSetting\n\n## SYNOPSIS\nGets user settings for WinGet.\n\n## SYNTAX\n\n```\nGet-WinGetUserSetting [<CommonParameters>]\n```\n\n## DESCRIPTION\n\nThis command displays the WinGet settings for the current user. The settings are stored in\n`$env:LOCALAPPDATA\\Packages\\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\\LocalState\\settings.json`.\nThis file only exists if you have changed a user setting, for example, using the `Set-WinGetUserSetting` command.\n\n## EXAMPLES\n\n### Example 1: Get the WinGet settings for the current user\n\n```powershell\nGet-WinGetUserSetting\n```\n\n## PARAMETERS\n\n### CommonParameters\n\nThis cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable,\n-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable,\n-ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see\n[about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).\n\n## INPUTS\n\n### None\n\n## OUTPUTS\n\n### System.Collections.Hashtable\n\n## NOTES\n\n## RELATED LINKS\n\n[Get-WinGetSetting](Get-WinGetSetting.md)\n\n[Set-WinGetUserSetting](Set-WinGetUserSetting.md)\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.Client/Get-WinGetVersion.md",
    "content": "﻿---\nexternal help file: Microsoft.WinGet.Client.Cmdlets.dll-Help.xml\nModule Name: Microsoft.WinGet.Client\nms.date: 08/01/2024\nonline version:\nschema: 2.0.0\ntitle: Get-WinGetVersion\n---\n\n# Get-WinGetVersion\n\n## SYNOPSIS\nGets the installed version of WinGet.\n\n## SYNTAX\n\n```\nGet-WinGetVersion [<CommonParameters>]\n```\n\n## DESCRIPTION\n\nGets the installed version of WinGet.\n\n## EXAMPLES\n\n### Example 1: Default example\n\n```powershell\nGet-WinGetVersion\n```\n\nGets the installed version of WinGet.\n\n## PARAMETERS\n\n### CommonParameters\n\nThis cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable,\n-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable,\n-ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see\n[about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).\n\n## INPUTS\n\n### None\n\n## OUTPUTS\n\n### System.String\n\n## NOTES\n\n## RELATED LINKS\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.Client/Install-WinGetPackage.md",
    "content": "﻿---\nexternal help file: Microsoft.WinGet.Client.Cmdlets.dll-Help.xml\nModule Name: Microsoft.WinGet.Client\nms.date: 08/01/2024\nonline version:\nschema: 2.0.0\ntitle: Install-WinGetPackage\n---\n\n# Install-WinGetPackage\n\n## SYNOPSIS\nInstalls a WinGet Package.\n\n## SYNTAX\n\n### FoundSet (Default)\n\n```\nInstall-WinGetPackage [-Mode <PSPackageInstallMode>] [-Override <String>] [-Custom <String>]\n [-Location <String>] [-Log <String>] [-Force] [-Header <String>] [-AllowHashMismatch]\n [-Architecture <PSProcessorArchitecture>] [-InstallerType <PSPackageInstallerType>] [-Locale <String>]\n [-Scope <PSPackageInstallScope>] [-SkipDependencies] [-Version <String>] [-Id <String>] [-Name <String>]\n [-Moniker <String>] [-Source <String>] [[-Query] <String[]>] [-MatchOption <PSPackageFieldMatchOption>]\n [-WhatIf] [-Confirm] [<CommonParameters>]\n```\n\n### GivenSet\n\n```\nInstall-WinGetPackage [-Mode <PSPackageInstallMode>] [-Override <String>] [-Custom <String>]\n [-Location <String>] [-Log <String>] [-Force] [-Header <String>] [-AllowHashMismatch]\n [-Architecture <PSProcessorArchitecture>] [-InstallerType <PSPackageInstallerType>] [-Locale <String>]\n [-Scope <PSPackageInstallScope>] [-SkipDependencies] [[-PSCatalogPackage] <PSCatalogPackage>]\n [-Version <String>] [-WhatIf] [-Confirm] [<CommonParameters>]\n```\n\n## DESCRIPTION\n\nThis command installs a WinGet package from a configured source. The command includes parameters\nto specify values used to search for packages in the configured sources. By default, the command\nsearches all sources. By default, all string-based searches are case-insensitive substring searches.\nWildcards are not supported. You can change the search behavior using the **MatchOption** parameter.\n\n## EXAMPLES\n\n### Example 1: Install a package using a query\n\n```powershell\nInstall-WinGetPackage Microsoft.PowerShell\n```\n\nThis example show how to install a package using a query. The **Query** parameter is positional, so\nyou don't need to include the parameter name before the query string.\n\n### Example 2: Install a package by Id\n\n```powershell\nInstall-WinGetPackage -Id Microsoft.PowerShell\n```\n\nThis example shows how to install a package by the specifying the package identifier.\nIf the package identifier is available from more than one source, you must provide additional search\ncriteria to select a specific instance of the package.\n\n> **If more than one source is configured with the same package identifier, the user must disambiguate**\n\n### Example 3: Install a package by Name\n\n```powershell\nInstall-WinGetPackage -Name \"PowerToys (Preview)\"\n```\n\nThis example shows how to install a package by specifying the package name.\n\n### Example 4: Install a specific version of a package\n\n```powershell\nInstall-WinGetPackage Microsoft.PowerShell -Version 7.4.4.0\n```\n\nThis example shows how to install a specific version of a package using a query. The command does a\nquery search for packages matching `Microsoft.PowerShell`. The results of the search a limited to\nmatches with the version of `7.4.4.0`.\n\n## PARAMETERS\n\n### -AllowHashMismatch\n\nAllows you to download package even when the SHA256 hash for an installer or a dependency does not\nmatch the SHA256 hash in the WinGet package manifest.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Architecture\n\nSpecify the processor architecture for the WinGet package installer.\n\n```yaml\nType: Microsoft.WinGet.Client.PSObjects.PSProcessorArchitecture\nParameter Sets: (All)\nAliases:\nAccepted values: Default, X86, Arm, X64, Arm64\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Custom\n\nUse this parameter to pass additional arguments to the installer. The parameter takes a single string value. To add multiple arguments, include the arguments in the string. The arguments must be provided in the format expected by the installer. If the string contains spaces, it must be enclosed in quotes. This string is added to the arguments defined in the package manifest.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Force\n\nForce the installer to run even when other checks WinGet would perform would prevent this action.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Header\n\nCustom value to be passed via HTTP header to WinGet REST sources.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Id\n\nSpecify the package identifier to search for. The command does a case-insensitive full text match,\nrather than a substring match.\n\n```yaml\nType: System.String\nParameter Sets: FoundSet\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -InstallerType\n\nA package may contain multiple installer types. Use this parameter to select the installer you want\nto use. The parameter accepts the following values:\n- `Default`\n- `Inno`\n- `Wix`\n- `Msi`\n- `Nullsoft`\n- `Zip`\n- `Msix`\n- `Exe`\n- `Burn`\n- `MSStore`\n- `Portable`\n\n```yaml\nType: Microsoft.WinGet.Client.PSObjects.PSPackageInstallerType\nParameter Sets: (All)\nAliases:\nAccepted values: Default, Inno, Wix, Msi, Nullsoft, Zip, Msix, Exe, Burn, MSStore, Portable\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Locale\n\nSpecify the locale of the installer package. The locale must provided in the BCP 47 format, such as\n`en-US`. For more information, see\n[Standard locale names](/globalization/locale/standard-locale-names).\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Location\n\nSpecify the file path where you want the packed to be installed. The installer must be able to\nsupport alternate install locations.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Log\n\nSpecify the location for the installer log. The value can be a fully-qualified or relative path and must include the file name. For example: `$env:TEMP\\package.log`.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -MatchOption\n\nSpecify the match option for a WinGet package query. This parameter accepts the following values:\n- `Equals`\n- `EqualsCaseInsensitive`\n- `StartsWithCaseInsensitive`\n- `ContainsCaseInsensitive`\n\n```yaml\nType: Microsoft.WinGet.Client.PSObjects.PSPackageFieldMatchOption\nParameter Sets: FoundSet\nAliases:\nAccepted values: Equals, EqualsCaseInsensitive, StartsWithCaseInsensitive, ContainsCaseInsensitive\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Mode\n\nSpecify the output mode for the installer. The parameter accepts the following values:\n- `Default`\n- `Silent`\n- `Interactive`\n\n```yaml\nType: Microsoft.WinGet.Client.PSObjects.PSPackageInstallMode\nParameter Sets: (All)\nAliases:\nAccepted values: Default, Silent, Interactive\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Moniker\n\nSpecify the moniker of the WinGet package to install. For example, the moniker for the\nMicrosoft.PowerShell package is `pwsh`.\n\n```yaml\nType: System.String\nParameter Sets: FoundSet\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Name\n\nSpecify the name of the package to be installed.\n\n```yaml\nType: System.String\nParameter Sets: FoundSet\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Override\n\nUse this parameter to override the existing arguments passed to the installer. The parameter takes a single string value. To add multiple arguments, include the arguments in the string. The arguments must be provided in the format expected by the installer. If the string contains spaces, it must be enclosed in quotes. This string overrides the arguments specified in the package manifest.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -PSCatalogPackage\n\nProvide **PSCatalogPackage** object. You can get a **PSCatalogPackage** object by using the\n`Find-WinGetPackage` command.\n\n```yaml\nType: Microsoft.WinGet.Client.Engine.PSObjects.PSCatalogPackage\nParameter Sets: GivenSet\nAliases: InputObject\n\nRequired: False\nPosition: 0\nDefault value: None\nAccept pipeline input: True (ByPropertyName, ByValue)\nAccept wildcard characters: False\n```\n\n### -Query\n\nSpecify one or more strings to search for. By default, the command searches all configured sources.\nThe command compares the value provided to the following package manifest properties:\n\t- `PackageIdentifier`\n\t- `PackageName`\n\t- `Moniker`\n\t- `Tags`\n\nThe command does a case-insensitive substring comparison of these properties.\n\n```yaml\nType: System.String[]\nParameter Sets: FoundSet\nAliases:\n\nRequired: False\nPosition: 0\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Scope\n\nSpecify WinGet package installer scope. The parameter accepts the following values:\n\n- `Any`\n- `User`\n- `System`\n- `UserOrUnknown`\n- `SystemOrUnknown`\n\n> [!NOTE]\n> The installer scope must be available in the WinGet package manifest.\n\n```yaml\nType: Microsoft.WinGet.Client.PSObjects.PSPackageInstallScope\nParameter Sets: (All)\nAliases:\nAccepted values: Any, User, System, UserOrUnknown, SystemOrUnknown\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -SkipDependencies\n\nSpecifies that the command shouldn't install the WinGet package dependencies.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Source\n\nSpecify the name of the WinGet source from which the package should be installed.\n\n```yaml\nType: System.String\nParameter Sets: FoundSet\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Version\n\nSpecify the version of the package.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Confirm\n\nPrompts you for confirmation before running the cmdlet.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: (All)\nAliases: cf\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -WhatIf\n\nShows what would happen if the cmdlet runs. The cmdlet isn't run.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: (All)\nAliases: wi\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\n\nThis cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable,\n-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable,\n-ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see\n[about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).\n\n## INPUTS\n\n### Microsoft.WinGet.Client.PSObjects.PSPackageInstallMode\n\n### System.String\n\n### System.Management.Automation.SwitchParameter\n\n### Microsoft.WinGet.Client.PSObjects.PSProcessorArchitecture\n\n### Microsoft.WinGet.Client.PSObjects.PSPackageInstallerType\n\n### Microsoft.WinGet.Client.PSObjects.PSPackageInstallScope\n\n### Microsoft.WinGet.Client.Engine.PSObjects.PSCatalogPackage\n\n### System.String[]\n\n### Microsoft.WinGet.Client.PSObjects.PSPackageFieldMatchOption\n\n## OUTPUTS\n\n### Microsoft.WinGet.Client.Engine.PSObjects.PSInstallResult\n\n## NOTES\n\n## RELATED LINKS\n\n[Find-WinGetPackage](Find-WinGetPackage.md)\n\n[Update-WinGetPackage](Update-WinGetPackage.md)\n\n[Uninstall-WinGetPackage](Uninstall-WinGetPackage.md)\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.Client/Microsoft.WinGet.Client.md",
    "content": "---\nModule Name: Microsoft.WinGet.Client\nms.date: 08/01/2024\nModule Guid: e11157e2-cd24-4250-83b8-c6654ea4926a\nDownload Help Link: \nHelp Version: 1.8.0\nLocale: en-US\ntitle: Microsoft.WinGet.Client Module\n---\n\n# Microsoft.WinGet.Client Module\n## Description\nMicrosoft WinGet Client Module for the Windows Package Manager\n\n## Microsoft.WinGet.Client Cmdlets\n### [Add-WinGetSource](Add-WinGetSource.md)\nAdds a new WinGet source.\n\n### [Assert-WinGetPackageManager](Assert-WinGetPackageManager.md)\nVerifies WinGet is installed properly.\n\n### [Disable-WinGetSetting](Disable-WinGetSetting.md)\nDisables an administrative setting.\n\n### [Enable-WinGetSetting](Enable-WinGetSetting.md)\nEnables WinGet administrative settings.\n\n### [Export-WinGetPackage](Export-WinGetPackage.md)\nDownloads a package.\n\n### [Find-WinGetPackage](Find-WinGetPackage.md)\nSearches configured sources for packages.\n\n### [Get-WinGetPackage](Get-WinGetPackage.md)\nGets installed packages.\n\n### [Get-WinGetSetting](Get-WinGetSetting.md)\nGets WinGet settings.\n\n### [Get-WinGetSource](Get-WinGetSource.md)\nGets configured WinGet sources.\n\n### [Get-WinGetUserSetting](Get-WinGetUserSetting.md)\nGets user settings for WinGet.\n\n### [Get-WinGetVersion](Get-WinGetVersion.md)\nGets the installed version of WinGet.\n\n### [Install-WinGetPackage](Install-WinGetPackage.md)\nInstall a WinGet Package.\n\n### [Remove-WinGetSource](Remove-WinGetSource.md)\nRemoves a configured source.\n\n### [Repair-WinGetPackage](Repair-WinGetPackage.md)\nRepairs a WinGet Package.\n\n### [Repair-WinGetPackageManager](Repair-WinGetPackageManager.md)\nRepairs the WinGet client.\n\n### [Reset-WinGetSource](Reset-WinGetSource.md)\nResets default WinGet sources.\n\n### [Set-WinGetUserSetting](Set-WinGetUserSetting.md)\nSets WinGet settings.\n\n### [Test-WinGetUserSetting](Test-WinGetUserSetting.md)\nTests WinGet settings.\n\n### [Uninstall-WinGetPackage](Uninstall-WinGetPackage.md)\nUninstalls a WinGet Package.\n\n### [Update-WinGetPackage](Update-WinGetPackage.md)\nUpdates a WinGet Package.\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.Client/Remove-WinGetSource.md",
    "content": "﻿---\nexternal help file: Microsoft.WinGet.Client.Cmdlets.dll-Help.xml\nModule Name: Microsoft.WinGet.Client\nms.date: 08/01/2024\nonline version:\nschema: 2.0.0\ntitle: Remove-WinGetSource\n---\n\n# Remove-WinGetSource\n\n## SYNOPSIS\nRemoves a configured source.\n\n## SYNTAX\n\n```\nRemove-WinGetSource -Name <String> [<CommonParameters>]\n```\n\n## DESCRIPTION\n\nThis command removes a configured WinGet source. By default, there are two sources registered:\n`msstore` and `winget`. You can add more sources using `Add-WinGetSource`. This command must be executed with administrator permissions.\n\n## EXAMPLES\n\n### Example 1: Remove a single source by name\n\n```powershell\nRemove-WinGetSource -Name msstore\n```\n\nThe example shows how to remove a WinGet source by name.\n\n## PARAMETERS\n\n### -Name\n\nSpecify the name of the source to be removed.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName, ByValue)\nAccept wildcard characters: False\n```\n\n### CommonParameters\n\nThis cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable,\n-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable,\n-ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see\n[about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).\n\n## INPUTS\n\n### System.String\n\n## OUTPUTS\n\n### System.Object\n\n## NOTES\n\n## RELATED LINKS\n\n[Add-WinGetSource](Add-WinGetSource.md)\n\n[Reset-WinGetSource](Reset-WinGetSource.md)\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.Client/Repair-WinGetPackage.md",
    "content": "---\r\nexternal help file: Microsoft.WinGet.Client.Cmdlets.dll-Help.xml\r\nModule Name: Microsoft.WinGet.Client\r\nms.date: 08/26/2024\r\nonline version:\r\nschema: 2.0.0\r\n---\r\n\r\n# Repair-WinGetPackage\r\n\r\n## SYNOPSIS\r\nRepairs a WinGet Package.\r\n\r\n## SYNTAX\r\n\r\n### FoundSet (Default)\r\n```\r\nRepair-WinGetPackage [-Mode <PSPackageRepairMode>] [-Log <String>] [-Version <String>] [-Id <String>]\r\n [-Name <String>] [-Moniker <String>] [-Source <String>] [[-Query] <String[]>]\r\n [-MatchOption <PSPackageFieldMatchOption>] [-ProgressAction <ActionPreference>] [-WhatIf] [-Confirm]\r\n [<CommonParameters>]\r\n```\r\n\r\n### GivenSet\r\n```\r\nRepair-WinGetPackage [-Mode <PSPackageRepairMode>] [-Log <String>] [[-PSCatalogPackage] <PSCatalogPackage>]\r\n [-Version <String>] [-ProgressAction <ActionPreference>] [-WhatIf] [-Confirm] [<CommonParameters>]\r\n```\r\n\r\n## DESCRIPTION\r\nThis command repairs a WinGet package from your computer, provided the package includes repair support.\r\nThe command includes parameters to specify values used to search for installed packages. By default,\r\nall string-based searches are case-insensitive substring searches. Wildcards are not supported.\r\nYou can change the search behavior using the **MatchOption** parameter.\r\n\r\n> **Note: Not all packages support repair.**\r\n\r\n## EXAMPLES\r\n\r\n### Example 1: Repair a package using a query\r\n```powershell\r\nRepair-WinGetPackage -Query \"Microsoft.GDK.2406\"\r\n```\r\nThis example  shows how to repair a package using a query. The **Query** parameter is positional, so you \r\ndon't need to include the parameter name before the query string.\r\n\r\n### Example 3 : Repair a package by Id\r\n```powershell\r\nRepair-WinGetPackage -Id \"Microsoft.GDK.2406\"\r\n```\r\nThis example shows how to repair a package by specifying the package identifier.\r\n\r\nIf the package identifier is available from more than one source, you must provide additional search\r\ncriteria to select a specific instance of the package.\r\n\r\n### Example 3: Repair a package using by Name\r\n```powershell\r\nRepair-WinGetPackage -Name \"Microsoft Game Development Kit - 240602 (June 2024 Update 2)\"\r\n```\r\nThis example shows how to repair a package using the package name. \r\n\r\n> **Note: Please note that the examples mentioned above are mainly reference examples for the repair cmdlet and may not be operational as is, since many installers don't support repair as a standard functionality. For the Microsoft.GDK.2406 example, the assumption is that Microsoft.GDK.2406 supports repair capability and the author of the installer has provided the necessary repair context/switches in the Package Manifest in the Package Source referenced by the WinGet Client.**\r\n\r\n## PARAMETERS\r\n\r\n### -Id\r\n\r\nSpecify the package identifier to search for. By default, the command does a case-insensitive\r\nsubstring match.\r\n\r\n```yaml\r\nType: System.String\r\nParameter Sets: FoundSet\r\nAliases:\r\n\r\nRequired: False\r\nPosition: Named\r\nDefault value: None\r\nAccept pipeline input: True (ByPropertyName)\r\nAccept wildcard characters: False\r\n```\r\n\r\n### -Log\r\n\r\nSpecify the location for the installer repair log. The value can be a fully-qualified or relative path and must include the file name. For example: `$env:TEMP\\package.log`.\r\n\r\n> **Note: Not all installers support this option.**\r\n\r\n```yaml\r\nType: System.String\r\nParameter Sets: (All)\r\nAliases:\r\n\r\nRequired: False\r\nPosition: Named\r\nDefault value: None\r\nAccept pipeline input: False\r\nAccept wildcard characters: False\r\n```\r\n\r\n### -MatchOption\r\n\r\nSpecify the match option for a WinGet package query. This parameter accepts the following values:\r\n\r\n```yaml\r\nType: Microsoft.WinGet.Client.PSObjects.PSPackageFieldMatchOption\r\nParameter Sets: FoundSet\r\nAliases:\r\nAccepted values: Equals, EqualsCaseInsensitive, StartsWithCaseInsensitive, ContainsCaseInsensitive\r\n\r\nRequired: False\r\nPosition: Named\r\nDefault value: None\r\nAccept pipeline input: True (ByPropertyName)\r\nAccept wildcard characters: False\r\n```\r\n\r\n### -Mode\r\n\r\nSpecify the output mode for the installer. The parameter accepts the following values:\r\n\r\n```yaml\r\nType: Microsoft.WinGet.Client.PSObjects.PSPackageRepairMode\r\nParameter Sets: (All)\r\nAliases:\r\nAccepted values: Default, Silent, Interactive\r\n\r\nRequired: False\r\nPosition: Named\r\nDefault value: None\r\nAccept pipeline input: True (ByPropertyName)\r\nAccept wildcard characters: False\r\n```\r\n\r\n### -Moniker\r\n\r\nSpecify the moniker of the WinGet package to repair. For example, the moniker for the\r\nMicrosoft.PowerShell package is `pwsh`.\r\n\r\n```yaml\r\nType: System.String\r\nParameter Sets: FoundSet\r\nAliases:\r\n\r\nRequired: False\r\nPosition: Named\r\nDefault value: None\r\nAccept pipeline input: True (ByPropertyName)\r\nAccept wildcard characters: False\r\n```\r\n\r\n### -Name\r\n\r\nSpecify the name of the WinGet package name. The name contains space, you must enclose the name in\r\nquotes.\r\n\r\n```yaml\r\nType: System.String\r\nParameter Sets: FoundSet\r\nAliases:\r\n\r\nRequired: False\r\nPosition: Named\r\nDefault value: None\r\nAccept pipeline input: True (ByPropertyName)\r\nAccept wildcard characters: False\r\n```\r\n\r\n### -PSCatalogPackage\r\nProvide **PSCatalogPackage** object. You can get a **PSCatalogPackage** object by using the\r\n`Find-WinGetPackage` or `Get-WingetPackage` commands.\r\n\r\n\r\n```yaml\r\nType: Microsoft.WinGet.Client.Engine.PSObjects.PSCatalogPackage\r\nParameter Sets: GivenSet\r\nAliases: InputObject\r\n\r\nRequired: False\r\nPosition: 0\r\nDefault value: None\r\nAccept pipeline input: True (ByPropertyName, ByValue)\r\nAccept wildcard characters: False\r\n```\r\n\r\n### -Query\r\n\r\nSpecify one or more strings to search for. By default, the command searches all configured sources.\r\nWildcards are not supported. The command compares the value provided to the following package\r\nmanifest properties:\r\n\r\n\t- `PackageIdentifier`\r\n\t- `PackageName`\r\n\t- `Moniker`\r\n\t- `Tags`\r\n\r\nThe command does a case-insensitive substring comparison of these properties.\r\n\r\n```yaml\r\nType: System.String[]\r\nParameter Sets: FoundSet\r\nAliases:\r\n\r\nRequired: False\r\nPosition: 0\r\nDefault value: None\r\nAccept pipeline input: True (ByPropertyName)\r\nAccept wildcard characters: False\r\n```\r\n\r\n### -Source\r\n\r\nSpecify the name of a configured WinGet source.\r\n\r\n```yaml\r\nType: System.String\r\nParameter Sets: FoundSet\r\nAliases:\r\n\r\nRequired: False\r\nPosition: Named\r\nDefault value: None\r\nAccept pipeline input: True (ByPropertyName)\r\nAccept wildcard characters: False\r\n```\r\n\r\n### -Version\r\n\r\nSpecify the version of the package to be repaired.\r\n\r\n```yaml\r\nType: System.String\r\nParameter Sets: (All)\r\nAliases:\r\n\r\nRequired: False\r\nPosition: Named\r\nDefault value: None\r\nAccept pipeline input: True (ByPropertyName)\r\nAccept wildcard characters: False\r\n```\r\n\r\n### -Confirm\r\n\r\nPrompts you for confirmation before running the cmdlet.\r\n\r\n```yaml\r\nType: System.Management.Automation.SwitchParameter\r\nParameter Sets: (All)\r\nAliases: cf\r\n\r\nRequired: False\r\nPosition: Named\r\nDefault value: None\r\nAccept pipeline input: False\r\nAccept wildcard characters: False\r\n```\r\n\r\n\r\n### -WhatIf\r\nShows what would happen if the cmdlet runs.\r\nThe cmdlet is not run.\r\n\r\n```yaml\r\nType: System.Management.Automation.SwitchParameter\r\nParameter Sets: (All)\r\nAliases: wi\r\n\r\nRequired: False\r\nPosition: Named\r\nDefault value: None\r\nAccept pipeline input: False\r\nAccept wildcard characters: False\r\n```\r\n\r\n### CommonParameters\r\nThis cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).\r\n\r\n## INPUTS\r\n\r\n### Microsoft.WinGet.Client.PSObjects.PSPackageRepairMode\r\n\r\n### Microsoft.WinGet.Client.Engine.PSObjects.PSCatalogPackage\r\n\r\n### System.String\r\n\r\n### System.String[]\r\n\r\n### Microsoft.WinGet.Client.PSObjects.PSPackageFieldMatchOption\r\n\r\n## OUTPUTS\r\n\r\n### Microsoft.WinGet.Client.Engine.PSObjects.PSRepairResult\r\n\r\n## NOTES\r\n\r\n## RELATED LINKS\r\n\r\n[Find-WinGetPackage](Find-WinGetPackage.md)\r\n\r\n[Install-WinGetPackage](Install-WinGetPackage.md)\r\n\r\n[Uninstall-WinGetPackage](Uninstall-WinGetPackage.md)\r\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.Client/Repair-WinGetPackageManager.md",
    "content": "﻿---\nexternal help file: Microsoft.WinGet.Client.Cmdlets.dll-Help.xml\nModule Name: Microsoft.WinGet.Client\nms.date: 08/01/2024\nonline version:\nschema: 2.0.0\ntitle: Repair-WinGetPackageManager\n---\n\n# Repair-WinGetPackageManager\n\n## SYNOPSIS\nRepairs the installation of the WinGet client on your computer.\n\n## SYNTAX\n\n### IntegrityVersionSet (Default)\n\n```\nRepair-WinGetPackageManager [-AllUsers] [-Force] [-Version <String>] [-IncludePreRelease] [<CommonParameters>]\n```\n\n### IntegrityLatestSet\n\n```\nRepair-WinGetPackageManager [-AllUsers] [-Force] [-Latest] [-IncludePreRelease]\n [<CommonParameters>]\n```\n\n## DESCRIPTION\n\nThis command repairs the installation of the WinGet client on your computer by installing the\nspecified version or the latest version of the client. This command can also install the WinGet \nclient if it is not already installed on your machine. It ensures that the client is installed \nin a working state.\n\n## EXAMPLES\n\n### Example 1: Repair the WinGet client\n\n```powershell\nRepair-WinGetPackageManager\n```\n\nEnsures that the current installed version of WinGet is functioning properly.\n\n### Example 2: Force install the latest version\n\n```powershell\nRepair-WinGetPackageManager -Latest -Force\n```\n\nThis example shows how to repair they WinGet client by installing the latest version and ensuring\nit functions properly. The **Force** parameter shuts down the version that is currently running so\nthat it can update the application files.\n\n### Example 3: Install a version with wildcards\n\n```powershell\nRepair-WinGetPackageManager -Version \"1.12.*\" -Force\n```\n\nThis example shows how to repair the WinGet client by installing a version that matches the\nspecified version pattern. The **Force** parameter shuts down the version that is currently running\nso that it can update the application files.\n\n## PARAMETERS\n\n### -AllUsers\n\nUse this parameter to repair the WinGet client for all user accounts on the computer. The command\nmust run the command with administrator permissions.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Force\n\nThe **Force** parameter shuts down the version that is currently running so that it can update the\napplication files.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -IncludePreRelease\n\nUse this parameter to include prerelease versions of the WinGet client.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: IntegrityLatestSet\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Latest\n\nUse this parameter to install the latest available version of the WinGet client.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: IntegrityLatestSet\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Version\nSpecifies the version of the WinGet client to install or repair. You can provide an exact version number or use wildcard characters (for example, `\"1.*.1*\"`) to match and install the latest version that fits the pattern.\n\n```yaml\nType: System.String\nParameter Sets: IntegrityVersionSet\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### CommonParameters\n\nThis cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable,\n-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable,\n-ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see\n[about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).\n\n## INPUTS\n\n### System.Management.Automation.SwitchParameter\n\n### System.String\n\n## OUTPUTS\n\n### System.Int32\n\n## NOTES\n\nThis cmdlet makes GitHub API requests to query release information. Unauthenticated requests are\nsubject to [GitHub API rate limits](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api),\nwhich can cause failures in CI/CD pipelines. If the `GH_TOKEN` or `GITHUB_TOKEN` environment\nvariable is set, the cmdlet automatically uses it to authenticate requests, which significantly\nincreases the rate limit.\n\n`GH_TOKEN` takes precedence over `GITHUB_TOKEN`, matching\n[GitHub CLI behavior](https://cli.github.com/manual/gh_help_environment). In GitHub Actions,\nyou can make `GITHUB_TOKEN` available to the cmdlet by mapping it as an environment variable in\nyour workflow step (e.g., `env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}`).\n\nUse `-Verbose` to see which token source is being used.\n\n## RELATED LINKS\n\n[Get-WinGetVersion](Get-WinGetVersion.md)\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.Client/Reset-WinGetSource.md",
    "content": "﻿---\nexternal help file: Microsoft.WinGet.Client.Cmdlets.dll-Help.xml\nModule Name: Microsoft.WinGet.Client\nms.date: 08/01/2024\nonline version:\nschema: 2.0.0\ntitle: Reset-WinGetSource\n---\n\n# Reset-WinGetSource\n\n## SYNOPSIS\nResets WinGet sources.\n\n## SYNTAX\n\n### DefaultSet (Default)\n\n```\nReset-WinGetSource -Name <String> [<CommonParameters>]\n```\n\n### OptionalSet\n\n```\nReset-WinGetSource -All [<CommonParameters>]\n```\n\n## DESCRIPTION\n\nResets a named WinGet source by removing the source configuration. You can reset all configured sources and add the default source configurations using the **All** switch parameter.\nThis command must be executed with administrator permissions.\n\n## EXAMPLES\n\n### Example 1: Reset the msstore source\n\n```powershell\nReset-WinGetSource -Name msstore\n```\n\nThis example resets the configured source named 'msstore' by removing it.\n\n### Example 2: Reset all sources\n\n```powershell\nReset-WinGetSource -All\n```\n\nThis example resets all configured sources and adds the default sources.\n\n## PARAMETERS\n\n### -All\n\nReset all sources and add the default sources.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: (OptionalSet)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Name\n\nThe name of the source.\n\n```yaml\nType: System.String\nParameter Sets: (DefaultSet)\nAliases:\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName, ByValue)\nAccept wildcard characters: False\n```\n\n### CommonParameters\n\nThis cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable,\n-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable,\n-ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see\n[about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).\n\n## INPUTS\n\n### System.String\n\n## OUTPUTS\n\n### System.Object\n\n## NOTES\n\n## RELATED LINKS\n\n[Add-WinGetSource](Add-WinGetSource.md)\n\n[Remove-WinGetSource](Remove-WinGetSource.md)\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.Client/Set-WinGetUserSetting.md",
    "content": "﻿---\nexternal help file: Microsoft.WinGet.Client.Cmdlets.dll-Help.xml\nModule Name: Microsoft.WinGet.Client\nms.date: 08/01/2024\nonline version:\nschema: 2.0.0\ntitle: Set-WinGetUserSetting\n---\n\n# Set-WinGetUserSetting\n\n## SYNOPSIS\nSets configuration settings of the WinGet client for the current user.\n\n## SYNTAX\n\n```\nSet-WinGetUserSetting -UserSettings <Hashtable> [-Merge] [<CommonParameters>]\n```\n\n## DESCRIPTION\n\nThis command sets configuration settings of the WinGet client for the current user. The user\nsettings file doesn't exist until you set a specific value. The file is stored in\n`$env:LOCALAPPDATA\\Packages\\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\\LocalState\\settings.json`.\nFor more information about WinGet settings, see\n[WinGet CLI Settings](https://aka.ms/winget-settings).\n\n## EXAMPLES\n\n### Example 1: Set progress bar theme\n\n```powershell\nSet-WinGetUserSetting -UserSettings @{\n    visual = @{\n        progressBar = 'rainbow'\n    }\n}\n```\n\nSets the theme of the progress bar to rainbow.\n\n### Example 2: Merge install behavior settings\n\n```powershell\nSet-WinGetUserSetting  -Merge -UserSettings @{\n    installBehavior = @{\n        preferences = @{\n            scope = 'user'\n        }\n    }\n}\n```\n\nAppends the user scope preference setting to the existing WinGet settings configuration.\n\n### Example 3: Change multiple settings\n\n```powershell\nSet-WinGetUserSetting -UserSettings @{\n    visual = @{\n        progressBar = 'rainbow'\n        anonymizeDisplayedPaths = $true\n    }\n}\n```\n\n## PARAMETERS\n\n### -Merge\n\nBy default, the command overwrites the current setting with the values provided. Use this parameter\nto append the new settings to the existing configuration.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -UserSettings\n\nA hashtable containing the key value pairs representing the WinGet settings.\n\n```yaml\nType: System.Collections.Hashtable\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### CommonParameters\n\nThis cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable,\n-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable,\n-ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see\n[about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).\n\n## INPUTS\n\n### System.Collections.Hashtable\n\n### System.Management.Automation.SwitchParameter\n\n## OUTPUTS\n\n### System.Collections.Hashtable\n\n## NOTES\n\n## RELATED LINKS\n\n[Get-WinGetUserSetting](Get-WinGetUserSetting.md)\n\n[Test-WinGetUserSetting](Test-WinGetUserSetting.md)\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.Client/Test-WinGetUserSetting.md",
    "content": "﻿---\nexternal help file: Microsoft.WinGet.Client.Cmdlets.dll-Help.xml\nModule Name: Microsoft.WinGet.Client\nms.date: 08/01/2024\nonline version:\nschema: 2.0.0\ntitle: Test-WinGetUserSetting\n---\n\n# Test-WinGetUserSetting\n\n## SYNOPSIS\nTests the current state of WinGet user settings.\n\n## SYNTAX\n\n```\nTest-WinGetUserSetting -UserSettings <Hashtable> [-IgnoreNotSet] [<CommonParameters>]\n```\n\n## DESCRIPTION\n\nThis command tests the current state of WinGet user settings against a provided set of values.\n\n## EXAMPLES\n\n### Example 1: Test for exact match\n\n```powershell\nTest-WinGetUserSetting -UserSettings @{\n    installBehavior = @{\n        preferences = @{\n            scope = 'user'\n        }\n    }\n}\n```\n\nThis example shows how to confirm that your current user settings match specific values. The\ncommand returns `$false` if it is not an exact match. \n\n### Example 2: Test only progress bar setting\n\n```powershell\nTest-WinGetUserSetting -IgnoreNotSet -UserSettings @{\n    visual = @{\n        progressBar = 'rainbow'\n    }\n}\n```\n\nThis examples tests whether the progress bar theme is set to `rainbow`. When you use the\n**IgnoreNotSet** parameter, the command only tests the provide values and doesn't include other\nWinGet settings in the comparison.\n\n## PARAMETERS\n\n### -IgnoreNotSet\n\nWhen you use the **IgnoreNotSet** parameter, the command only tests the provide values and doesn't\ninclude other WinGet settings in the comparison.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -UserSettings\n\nA hashtable containing the key value pairs representing the WinGet settings.\n\n```yaml\nType: System.Collections.Hashtable\nParameter Sets: (All)\nAliases:\n\nRequired: True\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### CommonParameters\n\nThis cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable,\n-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable,\n-ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see\n[about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).\n\n## INPUTS\n\n### System.Collections.Hashtable\n\n### System.Management.Automation.SwitchParameter\n\n## OUTPUTS\n\n### System.Boolean\n\n## NOTES\n\n## RELATED LINKS\n\n[Get-WinGetUserSetting](Get-WinGetUserSetting.md)\n\n[Set-WinGetUserSetting](Set-WinGetUserSetting.md)\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.Client/Uninstall-WinGetPackage.md",
    "content": "﻿---\nexternal help file: Microsoft.WinGet.Client.Cmdlets.dll-Help.xml\nModule Name: Microsoft.WinGet.Client\nms.date: 08/01/2024\nonline version:\nschema: 2.0.0\ntitle: Uninstall-WinGetPackage\n---\n\n# Uninstall-WinGetPackage\n\n## SYNOPSIS\nUninstalls a WinGet Package.\n\n## SYNTAX\n\n### FoundSet (Default)\n\n```\nUninstall-WinGetPackage [-Mode <PSPackageUninstallMode>] [-Force] [-Log <String>] [-Version <String>]\n [-Id <String>] [-Name <String>] [-Moniker <String>] [-Source <String>] [[-Query] <String[]>]\n [-MatchOption <PSPackageFieldMatchOption>] [-WhatIf] [-Confirm] [<CommonParameters>]\n```\n\n### GivenSet\n\n```\nUninstall-WinGetPackage [-Mode <PSPackageUninstallMode>] [-Force] [-Log <String>]\n [[-PSCatalogPackage] <PSCatalogPackage>] [-Version <String>] [-WhatIf]\n [-Confirm] [<CommonParameters>]\n```\n\n## DESCRIPTION\n\nThis command uninstalls a WinGet package from your computer. The command includes parameters to\nspecify values used to search for installed packages. By default, all string-based searches are\ncase-insensitive substring searches. Wildcards are not supported. You can change the search behavior\nusing the **MatchOption** parameter.\n\n## EXAMPLES\n\n### Example 1: Uninstall a package using a query\n\n```powershell\nUninstall-WinGetPackage Microsoft.PowerShell\n```\n\nThis example show how to uninstall a package using a query. The **Query** parameter is positional,\nso you don't need to include the parameter name before the query string.\n\n### Example 2: Uninstall a package by Id\n\n```powershell\nUninstall-WinGetPackage -Id Microsoft.PowerShell\n```\n\nThis example shows how to uninstall a package by the specifying the package identifier.\n\nIf the package identifier is available from more than one source, you must provide additional search\ncriteria to select a specific instance of the package.\n\n### Example 3: Uninstall a package by Name\n\n```powershell\nUninstall-WinGetPackage -Name \"PowerToys (Preview)\"\n```\n\nThis sample uninstalls the PowerToys package by the specifying the package name.\n\n### Example 4: Uninstall a specific version of a package\n\n```powershell\nUninstall-WinGetPackage Microsoft.PowerShell -Version 7.4.4.0\n```\n\nThis example shows how to uninstall a specific version of a package using a query. The command does\na query search for packages matching `Microsoft.PowerShell`. The results of the search a limited to\nmatches with the version of `7.4.4.0`.\n\n## PARAMETERS\n\n### -Force\n\nForce the uninstall to run.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Id\n\nSpecify the package identifier to search for. By default, the command does a case-insensitive\nsubstring match.\n\n```yaml\nType: System.String\nParameter Sets: FoundSet\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Log\n\nSpecify the location for the uninstaller log. The value can be a fully-qualified or relative path and must include the file name. For example: `$env:TEMP\\package.log`.\n\n> **Note: Not all uninstallers support this option.**\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -MatchOption\n\nSpecify the match option for a WinGet package query. This parameter accepts the following values:\n\n- `Equals`\n- `EqualsCaseInsensitive`\n- `StartsWithCaseInsensitive`\n- `ContainsCaseInsensitive`\n\n```yaml\nType: Microsoft.WinGet.Client.PSObjects.PSPackageFieldMatchOption\nParameter Sets: FoundSet\nAliases:\nAccepted values: Equals, EqualsCaseInsensitive, StartsWithCaseInsensitive, ContainsCaseInsensitive\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Mode\n\nSpecify the output mode for the installer. The parameter accepts the following values:\n\t\n- `Default`\n- `Silent`\n- `Interactive`\n\n> [!NOTE]\n> Not all uninstallers support all modes.\n\n```yaml\nType: Microsoft.WinGet.Client.PSObjects.PSPackageUninstallMode\nParameter Sets: (All)\nAliases:\nAccepted values: Default, Silent, Interactive\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Moniker\n\nSpecify the moniker of the WinGet package to download. For example, the moniker for the\nMicrosoft.PowerShell package is `pwsh`.\n\n```yaml\nType: System.String\nParameter Sets: FoundSet\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Name\n\nSpecify the name of the WinGet package name. The name contains space, you must enclose the name in\nquotes.\n\n```yaml\nType: System.String\nParameter Sets: FoundSet\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -PSCatalogPackage\n\nProvide **PSCatalogPackage** object. You can get a **PSCatalogPackage** object by using the\n`Find-WinGetPackage` or `Get-WingetPackage` commands.\n\n```yaml\nType: Microsoft.WinGet.Client.Engine.PSObjects.PSCatalogPackage\nParameter Sets: GivenSet\nAliases: InputObject\n\nRequired: False\nPosition: 0\nDefault value: None\nAccept pipeline input: True (ByPropertyName, ByValue)\nAccept wildcard characters: False\n```\n\n### -Query\n\nSpecify one or more strings to search for. By default, the command searches all configured sources.\nWildcards are not supported. The command compares the value provided to the following package\nmanifest properties:\n\n\t- `PackageIdentifier`\n\t- `PackageName`\n\t- `Moniker`\n\t- `Tags`\n\nThe command does a case-insensitive substring comparison of these properties.\n\n```yaml\nType: System.String[]\nParameter Sets: FoundSet\nAliases:\n\nRequired: False\nPosition: 0\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Source\n\nSpecify the name of a configured WinGet source.\n\n```yaml\nType: System.String\nParameter Sets: FoundSet\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Version\n\nSpecify the version of the package to be uninstalled.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Confirm\n\nPrompts you for confirmation before running the cmdlet.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: (All)\nAliases: cf\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -WhatIf\n\nShows what would happen if the cmdlet runs. The cmdlet isn't run.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: (All)\nAliases: wi\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\n\nThis cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable,\n-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable,\n-ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see\n[about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).\n\n## INPUTS\n\n### Microsoft.WinGet.Client.PSObjects.PSPackageUninstallMode\n\n### System.Management.Automation.SwitchParameter\n\n### System.String\n\n### Microsoft.WinGet.Client.Engine.PSObjects.PSCatalogPackage\n\n### System.String[]\n\n### Microsoft.WinGet.Client.PSObjects.PSPackageFieldMatchOption\n\n## OUTPUTS\n\n### Microsoft.WinGet.Client.Engine.PSObjects.PSUninstallResult\n\n## NOTES\n\n## RELATED LINKS\n\n[Get-WinGetPackage](Get-WinGetPackage.md)\n\n[Install-WinGetPackage](Install-WinGetPackage.md)\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.Client/Update-WinGetPackage.md",
    "content": "﻿---\nexternal help file: Microsoft.WinGet.Client.Cmdlets.dll-Help.xml\nModule Name: Microsoft.WinGet.Client\nms.date: 08/01/2024\nonline version:\nschema: 2.0.0\ntitle: Update-WinGetPackage\n---\n\n# Update-WinGetPackage\n\n## SYNOPSIS\nInstalls a newer version of a previously installed WinGet package.\n\n## SYNTAX\n\n### FoundSet (Default)\n\n```\nUpdate-WinGetPackage [-IncludeUnknown] [-Mode <PSPackageInstallMode>] [-Override <String>] [-Custom <String>]\n [-Location <String>] [-Log <String>] [-Force] [-Header <String>] [-AllowHashMismatch]\n [-Architecture <PSProcessorArchitecture>] [-InstallerType <PSPackageInstallerType>] [-Locale <String>]\n [-Scope <PSPackageInstallScope>] [-SkipDependencies] [-Version <String>] [-Id <String>] [-Name <String>]\n [-Moniker <String>] [-Source <String>] [[-Query] <String[]>] [-MatchOption <PSPackageFieldMatchOption>]\n [-WhatIf] [-Confirm] [<CommonParameters>]\n```\n\n### GivenSet\n\n```\nUpdate-WinGetPackage [-IncludeUnknown] [-Mode <PSPackageInstallMode>] [-Override <String>] [-Custom <String>]\n [-Location <String>] [-Log <String>] [-Force] [-Header <String>] [-AllowHashMismatch]\n [-Architecture <PSProcessorArchitecture>] [-InstallerType <PSPackageInstallerType>] [-Locale <String>]\n [-Scope <PSPackageInstallScope>] [-SkipDependencies] [[-PSCatalogPackage] <PSCatalogPackage>]\n [-Version <String>] [-WhatIf] [-Confirm] [<CommonParameters>]\n```\n\n## DESCRIPTION\n\nThis command searches the packages installed on your system and installs a newer version of the\nmatching WinGet package. The command includes parameters to specify values used to search for\npackages in the configured sources. By default, the command searches all sources. By default, all string-based searches are case-insensitive substring searches. Wildcards are not supported. You can change the search behavior using the **MatchOption** parameter.\n\n## EXAMPLES\n\n### Example 1: Update a package using a query\n\n```powershell\nUpdate-WinGetPackage Microsoft.PowerShell\n```\n\nThis example show how to update a package using a query. The **Query** parameter is positional, so\nyou don't need to include the parameter name before the query string.\n\n### Example 2: Update a package by Id\n\n```powershell\nUpdate-WinGetPackage -Id Microsoft.PowerShell\n```\n\nThis example shows how to update a package by the specifying the package identifier.\n\t\nIf the package identifier is available from more than one source, you must provide additional search\ncriteria to select a specific instance of the package.\n\n### Example 3: Update a package by Name\n\n```powershell\nUpdate-WinGetPackage -Name \"PowerToys (Preview)\"\n```\n\nThis sample updates the PowerToys package by the specifying the package name.\n\n### Example 4: Update to a specific version of a package\n\n```powershell\nUpdate-WinGetPackage Microsoft.PowerShell -Version 7.4.4.0\n```\n\nThis example shows how to update a specific version of a package using a query. The command does a\nquery search for packages matching `Microsoft.PowerShell`. The results of the search a limited to\nmatches with the version of `7.4.4.0`.\n\n### Example 5: Update all packages\n\n```powershell\nGet-WinGetPackage | Where-Object IsUpdateAvailable | Update-WinGetPackage\n```\n\nThis example shows how to update all packages that have an available upgrade from one of the configured sources.\n\n## PARAMETERS\n\n### -AllowHashMismatch\n\nAllows you to download package even when the SHA256 hash for an installer or a dependency does not\nmatch the SHA256 hash in the WinGet package manifest.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Architecture\n\nSpecify the processor architecture for the WinGet package installer. The parameter accepts the\nfollowing values:\n\n- `Default`\n- `X86`\n- `Arm`\n- `X64`\n- `Arm64`\n\n```yaml\nType: Microsoft.WinGet.Client.PSObjects.PSProcessorArchitecture\nParameter Sets: (All)\nAliases:\nAccepted values: Default, X86, Arm, X64, Arm64\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Custom\n\nUse this parameter to pass additional arguments to the installer. The parameter takes a single string value. To add multiple arguments, include the arguments in the string. The arguments must be provided in the format expected by the installer. If the string contains spaces, it must be enclosed in quotes. This string is added to the arguments defined in the package manifest.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Force\n\nForce the update to run the installer.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Header\n\nSpecify a custom value in the HTTP header to the REST source.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Id\n\nSpecify the package identifier to search for. By default, the command does a case-insensitive\nsubstring match.\n\n```yaml\nType: System.String\nParameter Sets: FoundSet\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -IncludeUnknown\n\nUse this parameter to upgrade the package when the installed version is not specified in the\nregistry.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -InstallerType\n\nA package may contain multiple installer types. Use this parameter to select the installer you want\nto use. The parameter accepts the following values:\n\t\n- `Default`\n- `Inno`\n- `Wix`\n- `Msi`\n- `Nullsoft`\n- `Zip`\n- `Msix`\n- `Exe`\n- `Burn`\n- `MSStore`\n- `Portable`\n\n```yaml\nType: Microsoft.WinGet.Client.PSObjects.PSPackageInstallerType\nParameter Sets: (All)\nAliases:\nAccepted values: Default, Inno, Wix, Msi, Nullsoft, Zip, Msix, Exe, Burn, MSStore, Portable\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Locale\n\nSpecify the locale of the installer package. The locale must provided in the BCP 47 format, such as\n`en-US`. For more information, see\n[Standard locale names](/globalization/locale/standard-locale-names).\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Location\n\nSpecify the file path where you want the packed to be installed. The installer must be able to\nsupport alternate install locations.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Log\n\nSpecify the location for the installer log. The value can be a fully-qualified or relative path and must include the file name. For example: `$env:TEMP\\package.log`.\n\n> **Note: Not all installers support this property.**\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -MatchOption\n\nSpecify the match option for a WinGet package query. This parameter accepts the following values:\n\n- `Equals`\n- `EqualsCaseInsensitive`\n- `StartsWithCaseInsensitive`\n- `ContainsCaseInsensitive`\n\n```yaml\nType: Microsoft.WinGet.Client.PSObjects.PSPackageFieldMatchOption\nParameter Sets: FoundSet\nAliases:\nAccepted values: Equals, EqualsCaseInsensitive, StartsWithCaseInsensitive, ContainsCaseInsensitive\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Mode\n\nSpecify the output mode for the installer. The parameter accepts the following values:\n\n- `Default`\n- `Silent`\n- `Interactive`\n\nNot all installers support all modes.\n\n```yaml\nType: Microsoft.WinGet.Client.PSObjects.PSPackageInstallMode\nParameter Sets: (All)\nAliases:\nAccepted values: Default, Silent, Interactive\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Moniker\n\nSpecify the moniker of the WinGet package to update. For example, the moniker for the\nMicrosoft.PowerShell package is `pwsh`.\n\n```yaml\nType: System.String\nParameter Sets: FoundSet\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Name\n\nSpecify the name of the package to be updated.\n\n```yaml\nType: System.String\nParameter Sets: FoundSet\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Override\n\nUse this parameter to override the existing arguments passed to the installer. The parameter takes a single string value. To add multiple arguments, include the arguments in the string. The arguments must be provided in the format expected by the installer. If the string contains spaces, it must be enclosed in quotes. This string overrides the arguments specified in the package manifest.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -PSCatalogPackage\n\nProvide **PSCatalogPackage** object. You can get a **PSCatalogPackage** object by using the\n`Find-WinGetPackage` or `Get-WinGetPackage` commands.\n\n```yaml\nType: Microsoft.WinGet.Client.Engine.PSObjects.PSCatalogPackage\nParameter Sets: GivenSet\nAliases: InputObject\n\nRequired: False\nPosition: 0\nDefault value: None\nAccept pipeline input: True (ByPropertyName, ByValue)\nAccept wildcard characters: False\n```\n\n### -Query\n\nSpecify one or more strings to search for. By default, the command searches all configured sources.\nWildcards are not supported. The command compares the value provided to the following package\nmanifest properties:\n\n\t- `PackageIdentifier`\n\t- `PackageName`\n\t- `Moniker`\n\t- `Tags`\n\nThe command does a case-insensitive substring comparison of these properties.\n\n```yaml\nType: System.String[]\nParameter Sets: FoundSet\nAliases:\n\nRequired: False\nPosition: 0\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Scope\n\nSpecify WinGet package installer scope. The parameter accepts the following values:\n\n- `Any`\n- `User`\n- `System`\n- `UserOrUnknown`\n- `SystemOrUnknown`\n\n> [!NOTE]\n> The installer scope must be available in the WinGet package manifest.\n\n```yaml\nType: Microsoft.WinGet.Client.PSObjects.PSPackageInstallScope\nParameter Sets: (All)\nAliases:\nAccepted values: Any, User, System, UserOrUnknown, SystemOrUnknown\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -SkipDependencies\n\nSpecifies that the command shouldn't install the WinGet package dependencies.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Source\n\nSpecify the name of a configured WinGet source.\n\n```yaml\nType: System.String\nParameter Sets: FoundSet\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Version\n\nSpecify package version.\n\n```yaml\nType: System.String\nParameter Sets: (All)\nAliases:\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: True (ByPropertyName)\nAccept wildcard characters: False\n```\n\n### -Confirm\n\nPrompts you for confirmation before running the cmdlet.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: (All)\nAliases: cf\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### -WhatIf\n\nShows what would happen if the cmdlet runs. The cmdlet isn't run.\n\n```yaml\nType: System.Management.Automation.SwitchParameter\nParameter Sets: (All)\nAliases: wi\n\nRequired: False\nPosition: Named\nDefault value: None\nAccept pipeline input: False\nAccept wildcard characters: False\n```\n\n### CommonParameters\n\nThis cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable,\n-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable,\n-ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see\n[about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).\n\n## INPUTS\n\n### System.Management.Automation.SwitchParameter\n\n### Microsoft.WinGet.Client.PSObjects.PSPackageInstallMode\n\n### System.String\n\n### Microsoft.WinGet.Client.PSObjects.PSProcessorArchitecture\n\n### Microsoft.WinGet.Client.PSObjects.PSPackageInstallerType\n\n### Microsoft.WinGet.Client.PSObjects.PSPackageInstallScope\n\n### Microsoft.WinGet.Client.Engine.PSObjects.PSCatalogPackage\n\n### System.String[]\n\n### Microsoft.WinGet.Client.PSObjects.PSPackageFieldMatchOption\n\n## OUTPUTS\n\n### Microsoft.WinGet.Client.Engine.PSObjects.PSInstallResult\n\n## NOTES\n\n## RELATED LINKS\n\n[Get-WinGetPackage](Get-WinGetPackage.md)\n\n[Uninstall-WinGetPackage](Uninstall-WinGetPackage.md)\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.DSC/WinGetAdminSettings.md",
    "content": "﻿---\nexternal help file: Microsoft.WinGet.DSC.psm1-Help.xml\nModule Name: Microsoft.WinGet.DSC\nms.date: 08/28/2024\nonline version:\nschema: 2.0.0\ntitle: WinGetAdminSettings\n---\n\n# WinGetAdminSettings\n\n## SYNOPSIS\nConfigures WinGet administrator settings.\n\n## DESCRIPTION\n\nAllows the administrator settings to be configured or retrieved. Setting administrator settings requires administrator privileges.\n\n## PARAMETERS\n\n**Parameter**|**Attribute**|**DataType**|**Description**|**Allowed Values**\n:-----|:-----|:-----|:-----|:-----\n`SID`|Key|String|The SID of the user to target, or an empty string to target the current user. **Only the empty string is currently supported.**|See [security identifiers](https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/understand-security-identifiers)\n`Settings`|Mandatory|Hashtable|The administrator settings as a hashtable.|Inspect the `adminSettings` property of the output from `Get-WinGetSettings`\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.DSC/WinGetPackage.md",
    "content": "﻿---\nexternal help file: Microsoft.WinGet.DSC.psm1-Help.xml\nModule Name: Microsoft.WinGet.DSC\nms.date: 08/28/2024\nonline version:\nschema: 2.0.0\ntitle: WinGetPackage\n---\n\n# WinGetPackage\n\n## SYNOPSIS\nConfigures packages through WinGet.\n\n## DESCRIPTION\n\nAllows WinGet package state to be configured.\n\n## PARAMETERS\n\n**Parameter**|**Attribute**|**DataType**|**Description**|**Allowed Values**\n:-----|:-----|:-----|:-----|:-----\n`Id`|Key, Mandatory|String|The identifier of a WinGet package.|Use `Find-WinGetPackage` to search for packages\n`Source`|Key|String|The name of the source that provides the package. If not provided, all configured sources will be searched for the `Id`.|Use the `WinGetSources` resource to configure a source or `Get-WinGetSource` to discover the default sources\n`Version`|Optional|String|The version of the package.|See the `AvailableVersions` property of output from `Find-WinGetPackage`\n`Ensure`|Optional|WinGetEnsure|Whether the package should be installed (`Present`) or not (`Absent`).|`Present` (default), `Absent`\n`MatchOption`|Optional|WinGetMatchOption|The method used to compare the `Id` parameter with available packages.|`Equals`, `EqualsCaseInsensitive` (default), `StartsWithCaseInsensitive`, `ContainsCaseInsensitive`\n`UseLatest`|Optional|Boolean|Whether the package should updated to the latest available version. If true, takes precedence over `Version`.|`True`, `False` (default)\n`InstallMode`|Optional|WinGetInstallMode|The interactivity level requested when installing.|`Default`, `Silent` (default), `Interactive`\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.DSC/WinGetPackageManager.md",
    "content": "﻿---\nexternal help file: Microsoft.WinGet.DSC.psm1-Help.xml\nModule Name: Microsoft.WinGet.DSC\nms.date: 08/28/2024\nonline version:\nschema: 2.0.0\ntitle: WinGetPackageManager\n---\n\n# WinGetPackageManager\n\n## SYNOPSIS\nConfigures the WinGet package manager package itself.\n\n## DESCRIPTION\n\nAllows the WinGet package manager package version to be configured. If multiple of the version targeting parameters are True/non-empty, they will take precedence in the following order: `UseLatest`, `UseLatestPreRelease`, `Version`.\n\n## PARAMETERS\n\n**Parameter**|**Attribute**|**DataType**|**Description**|**Allowed Values**\n:-----|:-----|:-----|:-----|:-----\n`SID`|Key|String|The SID of the user to target, or an empty string to target the current user. **Only the empty string is currently supported.**|See [security identifiers](https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/understand-security-identifiers)\n`Version`|Optional|String|A version of the WinGet package manager package.|See [the WinGet release tags](https://github.com/microsoft/winget-cli/releases)\n`UseLatest`|Optional|Boolean|The latest publicly available release should be used.|`True`, `False` (default)\n`UseLatestPreRelease`|Optional|Boolean|The latest preview release should be used.|`True`, `False` (default)\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.DSC/WinGetSource.md",
    "content": "﻿---\nexternal help file: Microsoft.WinGet.DSC.psm1-Help.xml\nModule Name: Microsoft.WinGet.DSC\nms.date: 08/28/2024\nonline version:\nschema: 2.0.0\ntitle: WinGetSource\n---\n\n# WinGetSource\n\n## SYNOPSIS\nConfigures a WinGet source.\n\n## DESCRIPTION\n\nAllows WinGet sources to be configured or retrieved.\n\n## PARAMETERS\n\n**Parameter**|**Attribute**|**DataType**|**Description**|**Allowed Values**\n:-----|:-----|:-----|:-----|:-----\n`Name`|Key, Mandatory|String|The name of the source.|Any string using valid characters for Windows file names\n`Argument`|Mandatory|String|The primary data defining the source; typically the URI prefix of the source.|Source type specific value\n`Type`|Optional|String|The type of the source.|`Microsoft.PreIndexed.Package`, `Microsoft.Rest`\n`TrustLevel`|Optional|WinGetTrustLevel|The trust level of the source, which determines how much scrutiny is placed on it when used. If undefined and the source needs to be configured, the default value is `None`.|`Undefined` (default), `None`, `Trusted`\n`Explicit`|Optional|WinGetOptionalBool|Whether the source is included (`False`) or not (`True`) in commands that do not specify a source. If undefined and the source needs to be configured, the default value is `False`.|`Undefined` (default), `False`, `True`\n`Ensure`|Optional|WinGetEnsure|Whether the source should exist (`Present`) or not (`Absent`).|`Present` (default), `Absent`\n"
  },
  {
    "path": "src/PowerShell/Help/Microsoft.WinGet.DSC/WinGetUserSettings.md",
    "content": "﻿---\nexternal help file: Microsoft.WinGet.DSC.psm1-Help.xml\nModule Name: Microsoft.WinGet.DSC\nms.date: 08/28/2024\nonline version:\nschema: 2.0.0\ntitle: WinGetUserSettings\n---\n\n# WinGetUserSettings\n\n## SYNOPSIS\nConfigures WinGet user settings.\n\n## DESCRIPTION\n\nAllows part or all of the user settings to be configured or retrieved.\n\n## PARAMETERS\n\n**Parameter**|**Attribute**|**DataType**|**Description**|**Allowed Values**\n:-----|:-----|:-----|:-----|:-----\n`SID`|Key|String|The SID of the user to target, or an empty string to target the current user. **Only the empty string is currently supported.**|See [security identifiers](https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/understand-security-identifiers)\n`Settings`|Mandatory|Hashtable|The user settings as a hashtable.|See [the schema](https://github.com/microsoft/winget-cli/blob/master/schemas/JSON/settings/settings.schema.0.2.json)\n`Action`|Optional|WinGetAction|Determines whether to overwrite (`Full`) or merge (`Partial`) the value provided in `Settings` with the current user settings.|`Full` (default), `Partial`\n"
  },
  {
    "path": "src/PowerShell/Help/markdownlint.yaml",
    "content": "docsmd.alert: true\ndocsmd.codesnippet: true\ndocsmd.column: true\ndocsmd.image: true\ndocsmd.moniker: true\ndocsmd.no-loc: true\ndocsmd.row: true\ndocsmd.securelinks: true\ndocsmd.syntax: true\ndocsmd.video: true\ndocsmd.xref: true\ndocsmd.zone: true\n\nMD001: true  # header-increment\n# MD002      # first-header-h1 - Superceded by MD041\nMD003:       # header-style\n  style: atx\nMD004:       # ul-style\n  style: dash\nMD005: true  # list-indent\n# MD006      # ul-start-left - Superceded by MD007's start_indented option\nMD007:       # ul-indent\n  indent: 2\n  start_indented: false\n# MD008      # Removed from linter; used to specify indentation for ul\nMD009:       # no-trailing-spaces\n  br_spaces: 2\n  strict: true\nMD010: true  # no-hard-tabs\nMD011: true  # no-reversed-links\nMD012: true  # no-multiple-blanks\nMD013:       # line-length\n  code_block_line_length: 90\n  code_blocks: true\n  heading_line_length: 100\n  headings: true\n  line_length: 100\n  stern: true\n  tables: false\nMD014: true  # commands-show-output\n# MD015      # \"Use of non-atx style headers\" - Removed from linter, replaced by MD003\n# MD016      # \"Use of non-closed-atx style headers\" - Removed from linter, replaced by MD003\n# MD017      # \"Use of non-setext style headers\" - Removed from linter, replaced by MD003\nMD018: true  # no-missing-space-atx\nMD019: true  # no-multiple-space-atx\nMD020: true  # no-missing-space-closed-atx\nMD021: true  # no-multiple-space-closed-atx\nMD022: true  # blanks-around-headers\nMD023: true  # header-start-left\nMD024:       # no-duplicate-header\n  siblings_only: true\nMD025:       # single-h1\n  front_matter_title: ''\n  level: 1\nMD026:       # no-trailing-punctuation\n  punctuation: '.,;:!。，；：！？'\nMD027: true  # no-multiple-space-blockquote\nMD028: true  # no-blanks-blockquote\nMD029:       # ol-prefix\n  style: one\nMD030: true  # list-marker-space\nMD031: true  # blanks-around-fences\nMD032: true  # blanks-around-lists\nMD033:       # no-inline-html\n  allowed_elements:\n    - a\n    - br\n    - code\n    - kbd\n    - li\n    - properties\n    - sup\n    - tags\n    - ul\nMD034: true  # no-bare-urls\nMD035:       # hr-style\n  style: '---'\nMD036: true  # no-emphasis-as-header\nMD037: true  # no-space-in-emphasis\nMD038: true  # no-space-in-code\nMD039: true  # no-space-in-links\nMD040: false # fenced-code-language\nMD041:       # first-line-h1\n  front_matter_title: ''\nMD042: true  # no-empty-links\nMD043: false # required-headers\nMD044:       # proper-names\n  code_blocks: false\n  names:\n    - PowerShell\n    - IntelliSense\n    - Authenticode\n    - CentOS\n    - Contoso\n    - CoreOS\n    - Debian\n    - Ubuntu\n    - openSUSE\n    - RHEL\n    - JavaScript\n    - .NET\n    - NuGet\n    - VS Code\n    - Newtonsoft\nMD045: true  # no-alt-text\nMD046:       # code-block-style\n  style: fenced\nMD047: true  # single-trailing-newline\nMD048:       # code-fence-style\n  style: backtick\nMD049:       # emphasis-style\n  style: underscore\nMD050:       # strong-style\n  style: asterisk\nMD051: true  # link-fragments\nMD052: true  # reference-links-images\nMD053: true  # link-image-reference-definitions\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client/Examples/Sample_AddRemoveSource.ps1",
    "content": "<#\r\n    .SYNOPSIS\r\n        Example for 'Get-WinGetSource', 'Add-WinGetSource', 'Remove-WinGetSource', and 'Reset-WinGetSource' cmdlet.\r\n        Cmdlets to allow you to manage sources for the Windows Package Manager.\r\n#>\r\n\r\n# TODO: Replace parameter with actual module name from PSGallery once module is released. \r\nParam (\r\n    [Parameter(Mandatory)]\r\n    $ModulePath\r\n)\r\n\r\nImport-Module -Name $ModulePath\r\n\r\n# List current sources.\r\nGet-WinGetSource\r\n\r\n# Add REST source\r\nAdd-WinGetSource -Name 'Contoso' -Argument 'https://www.contoso.com/cache' -Type 'Microsoft.Rest'\r\n\r\n# Remove source by name\r\nRemove-WinGetSource -Name 'Contoso'\r\n\r\n# Reset to default sources\r\nReset-WinGetSource"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client/Examples/Sample_EnableSettings.ps1",
    "content": "<#\r\n    .SYNOPSIS\r\n        Example for 'Enable-WinGetSetting' and 'Disable-WinGetSetting' cmdlets.\r\n        Cmdlet for enabling/disabling a specified WinGet setting. May require elevation.\r\n#>\r\n\r\n# TODO: Replace parameter with actual module name from PSGallery once module is released. \r\nParam (\r\n    [Parameter(Mandatory)]\r\n    $ModulePath\r\n)\r\n\r\nImport-Module -Name $ModulePath\r\n\r\n# Enables the 'LocalManifestFiles' setting.\r\nEnable-WinGetSetting -Name LocalManifestFiles\r\n\r\n# Disables the 'LocalManifestFiles' setting.\r\nDisable-WinGetSetting -Name LocalManifestFiles "
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client/Examples/Sample_FindPackage.ps1",
    "content": "<#\r\n    .SYNOPSIS\r\n        Example for 'Find-WinGetPackage' cmdlet.\r\n        Displays all applications available for installation.\r\n#>\r\n\r\n# TODO: Replace parameter with actual module name from PSGallery once module is released. \r\nParam (\r\n    [Parameter(Mandatory)]\r\n    $ModulePath\r\n)\r\n\r\nImport-Module -Name $ModulePath\r\n\r\n# Find all available packages\r\nFind-WinGetPackage\r\n\r\n# Find package by name\r\nFind-WinGetPackage -Name git\r\n\r\n# Find 10 packages by name\r\nFind-WinGetPackage -Name git -Count 10\r\n\r\n# Find package by package identifier\r\nFind-WinGetPackage -Id git.git\r\n\r\n# Find exact package from a specific source.\r\nFind-WinGetPackage -Id Git.Git -Source winget -Exact"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client/Examples/Sample_GetPackage.ps1",
    "content": "<#\r\n    .SYNOPSIS\r\n        Example for 'Get-WinGetPackage' cmdlet.\r\n        Displays a list of the applications currently installed on your computer.\r\n#>\r\n\r\n# TODO: Replace parameter with actual module name from PSGallery once module is released. \r\nParam (\r\n    [Parameter(Mandatory)]\r\n    $ModulePath\r\n)\r\n\r\nImport-Module -Name $ModulePath\r\n\r\n# List all installed packages\r\nGet-WinGetPackage\r\n\r\n# List installed package by name\r\nGet-WinGetPackage -Name git\r\n\r\n# List 10 packages by name\r\nGet-WinGetPackage -Name git -Count 10\r\n\r\n# List package by package identifier\r\nGet-WinGetPackage -Id git.git\r\n\r\n# List exact package from a specific source.\r\nGet-WinGetPackage -Id Git.Git -Source winget -Exact"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client/Examples/Sample_GetVersion.ps1",
    "content": "<#\r\n    .SYNOPSIS\r\n        Example for 'Get-WinGetVersion' cmdlet.\r\n        Prints the current client version.\r\n#>\r\n\r\n# TODO: Replace parameter with actual module name from PSGallery once module is released. \r\nParam (\r\n    [Parameter(Mandatory)]\r\n    $ModulePath\r\n)\r\n\r\nImport-Module -Name $ModulePath\r\n\r\n$version = Get-WinGetVersion\r\n\r\nWrite-Host($version);"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client/Examples/Sample_InstallPackage.ps1",
    "content": "<#\r\n    .SYNOPSIS\r\n        Example for 'Install-WinGetPackage' cmdlet.\r\n        Installs the specified application based on the provided arguments.\r\n#>\r\n\r\n# TODO: Replace parameter with actual module name from PSGallery once module is released. \r\nParam (\r\n    [Parameter(Mandatory)]\r\n    $ModulePath\r\n)\r\n\r\nImport-Module -Name $ModulePath\r\n\r\n# Install a package by name\r\nInstall-WinGetPackage -Name powertoys\r\n\r\n# Install a package by version and package identifier.\r\nInstall-WinGetPackage -Id Microsoft.PowerToys -Version 0.15.2\r\n\r\n# Install a package from a specific source\r\nInstall-WinGetPackage -Id Microsoft.PowerToys -Source winget\r\n\r\n# Install a package with a specific architecture and scope.\r\nInstall-WinGetPackage -Id Microsoft.PowerToys -Architecture X64 -Scope User\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client/Examples/Sample_RepairPackage.ps1",
    "content": "<#\r\n    .SYNOPSIS\r\n        Example for 'Repair-WinGetPackage' cmdlet.\r\n        Repairs the specified application.\r\n#>\r\n\r\n# TODO: Replace parameter with actual module name from PSGallery once module is released. \r\nParam (\r\n    [Parameter(Mandatory)]\r\n    $ModulePath\r\n)\r\n\r\nImport-Module -Name $ModulePath\r\n\r\n# Repair a package by name\r\nRepair-WinGetPackage -Name \"PowerToys FileLocksmith Context Menu\"\r\n\r\n# Repair a package by version and package identifier.\r\nRepair-WinGetPackage -Id \"MSIX\\Microsoft.PowerToys.FileLocksmithContextMenu_1.0.0.0_neutral__8wekyb3d8bbwe\"\r\n\r\n# Repair a package from a specific source\r\nRepair-WinGetPackage -Id \"MSIX\\Microsoft.PowerToys.FileLocksmithContextMenu_1.0.0.0_neutral__8wekyb3d8bbwe\" -Source winget\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client/Examples/Sample_UninstallPackage.ps1",
    "content": "<#\r\n    .SYNOPSIS\r\n        Example for 'Uninstall-WinGetPackage' cmdlet.\r\n        Uninstalls the specified application.\r\n#>\r\n\r\n# TODO: Replace parameter with actual module name from PSGallery once module is released. \r\nParam (\r\n    [Parameter(Mandatory)]\r\n    $ModulePath\r\n)\r\n\r\nImport-Module -Name $ModulePath\r\n\r\n# Uninstall a package by name\r\nUninstall-WinGetPackage -Name powertoys\r\n\r\n# Uninstall a package by version and package identifier.\r\nUninstall-WinGetPackage -Id Microsoft.PowerToys -Version 0.15.2\r\n\r\n# Uninstall a package from a specific source\r\nUninstall-WinGetPackage -Id Microsoft.PowerToys -Source winget\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client/Examples/Sample_UpdatePackage.ps1",
    "content": "<#\r\n    .SYNOPSIS\r\n        Example for 'Update-WinGetPackage' cmdlet.\r\n        Updates the specified application.\r\n#>\r\n\r\n# TODO: Replace parameter with actual module name from PSGallery once module is released. \r\nParam (\r\n    [Parameter(Mandatory)]\r\n    $ModulePath\r\n)\r\n\r\nImport-Module -Name $ModulePath\r\n\r\n# Update a package by name\r\nUpdate-WinGetPackage -Name powertoys\r\n\r\n# Update a package by version and package identifier.\r\nUpdate-WinGetPackage -Id Microsoft.PowerToys -Version 0.15.2\r\n\r\n# Update a package with silent mode\r\nUpdate-WinGetPackage -Id Microsoft.PowerToys -Mode Silent\r\n\r\n# Force update a package\r\nUpdate-WinGetPackage -Id Microsoft.PowerToys -Force"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client/ModuleFiles/Format.ps1xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<Configuration>\n  <ViewDefinitions>\n    <View>\n      <Name>Microsoft.WinGet.Client.Engine.PSObjects.PSFoundCatalogPackage</Name>\n      <ViewSelectedBy>\n        <TypeName>Microsoft.WinGet.Client.Engine.PSObjects.PSFoundCatalogPackage</TypeName>\n      </ViewSelectedBy>\n      <TableControl>\n        <TableHeaders>\n          <TableColumnHeader>\n            <Label>Name</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>Id</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>Version</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>Source</Label>\n          </TableColumnHeader>\n        </TableHeaders>\n        <TableRowEntries>\n          <TableRowEntry>\n            <TableColumnItems>\n              <TableColumnItem>\n                <ScriptBlock>$_.Name</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.Id</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.Version</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.Source</ScriptBlock>\n              </TableColumnItem>\n            </TableColumnItems>\n          </TableRowEntry>\n        </TableRowEntries>\n      </TableControl>\n    </View>\n    <View>\n      <Name>Microsoft.WinGet.Client.Engine.PSObjects.PSInstalledCatalogPackage</Name>\n      <ViewSelectedBy>\n        <TypeName>Microsoft.WinGet.Client.Engine.PSObjects.PSInstalledCatalogPackage</TypeName>\n      </ViewSelectedBy>\n      <TableControl>\n        <TableHeaders>\n          <TableColumnHeader>\n            <Label>Name</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>Id</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>Version</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>Available</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>Source</Label>\n          </TableColumnHeader>\n        </TableHeaders>\n        <TableRowEntries>\n          <TableRowEntry>\n            <TableColumnItems>\n              <TableColumnItem>\n                <ScriptBlock>$_.Name</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.Id</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.InstalledVersion</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>if ($_.IsUpdateAvailable) { $_.AvailableVersions[0] }</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.Source</ScriptBlock>\n              </TableColumnItem>\n            </TableColumnItems>\n          </TableRowEntry>\n        </TableRowEntries>\n      </TableControl>\n    </View>\n    <View>\n      <Name>Microsoft.WinGet.Client.Engine.PSObjects.PSInstallResult</Name>\n      <ViewSelectedBy>\n        <TypeName>Microsoft.WinGet.Client.Engine.PSObjects.PSInstallResult</TypeName>\n      </ViewSelectedBy>\n      <TableControl>\n        <TableHeaders>\n          <TableColumnHeader>\n            <Label>Id</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>Name</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>Source</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>InstallerErrorCode</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>Status</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>RebootRequired</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>ExtendedErrorCode</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>CorrelationData</Label>\n          </TableColumnHeader>\n        </TableHeaders>\n        <TableRowEntries>\n          <TableRowEntry>\n            <TableColumnItems>\n              <TableColumnItem>\n                <ScriptBlock>$_.Id</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.Name</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.Source</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.InstallerErrorCode</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.Status</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.RebootRequired</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.ExtendedErrorCode</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.CorrelationData</ScriptBlock>\n              </TableColumnItem>\n            </TableColumnItems>\n          </TableRowEntry>\n        </TableRowEntries>\n      </TableControl>\n    </View>\n    <View>\n      <Name>Microsoft.WinGet.Client.Engine.PSObjects.PSUninstallResult</Name>\n      <ViewSelectedBy>\n        <TypeName>Microsoft.WinGet.Client.Engine.PSObjects.PSUninstallResult</TypeName>\n      </ViewSelectedBy>\n      <TableControl>\n        <TableHeaders>\n          <TableColumnHeader>\n            <Label>Id</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>Name</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>Source</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>UninstallerErrorCode</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>Status</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>RebootRequired</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>ExtendedErrorCode</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>CorrelationData</Label>\n          </TableColumnHeader>          \n        </TableHeaders>\n        <TableRowEntries>\n          <TableRowEntry>\n            <TableColumnItems>\n              <TableColumnItem>\n                <ScriptBlock>$_.Id</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.Name</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.Source</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.UninstallerErrorCode</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.Status</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.RebootRequired</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.ExtendedErrorCode</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.CorrelationData</ScriptBlock>\n              </TableColumnItem>                \n            </TableColumnItems>\n          </TableRowEntry>\n        </TableRowEntries>\n      </TableControl>\n    </View>\n    <View>\n      <Name>Microsoft.WinGet.Client.Engine.PSObjects.PSDownloadResult</Name>\n      <ViewSelectedBy>\n        <TypeName>Microsoft.WinGet.Client.Engine.PSObjects.PSDownloadResult</TypeName>\n      </ViewSelectedBy>\n      <TableControl>\n        <TableHeaders>\n          <TableColumnHeader>\n            <Label>Id</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>Name</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>Source</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>Status</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>ExtendedErrorCode</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>CorrelationData</Label>\n          </TableColumnHeader>          \n        </TableHeaders>\n        <TableRowEntries>\n          <TableRowEntry>\n            <TableColumnItems>\n              <TableColumnItem>\n                <ScriptBlock>$_.Id</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.Name</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.Source</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.Status</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.ExtendedErrorCode</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.CorrelationData</ScriptBlock>\n              </TableColumnItem>                \n            </TableColumnItems>\n          </TableRowEntry>\n        </TableRowEntries>\n      </TableControl>\n    </View>\n    <View>\n      <Name>Microsoft.WinGet.Client.Engine.PSObjects.PSSourceResult</Name>\n      <ViewSelectedBy>\n        <TypeName>Microsoft.WinGet.Client.Engine.PSObjects.PSSourceResult</TypeName>\n      </ViewSelectedBy>\n      <TableControl>\n        <TableHeaders>\n          <TableColumnHeader>\n            <Label>Name</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>Argument</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>Type</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>TrustLevel</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>Explicit</Label>\n          </TableColumnHeader>          \n        </TableHeaders>\n        <TableRowEntries>\n          <TableRowEntry>\n            <TableColumnItems>\n              <TableColumnItem>\n                <ScriptBlock>$_.Name</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.Argument</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.Type</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.TrustLevel</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.Explicit</ScriptBlock>\n              </TableColumnItem>\n            </TableColumnItems>\n          </TableRowEntry>\n        </TableRowEntries>\n      </TableControl>\n    </View>\n    <View>\n      <Name>Microsoft.WinGet.Client.Engine.PSObjects.PSPackageVersionInfo</Name>\n      <ViewSelectedBy>\n        <TypeName>Microsoft.WinGet.Client.Engine.PSObjects.PSPackageVersionInfo</TypeName>\n      </ViewSelectedBy>\n      <TableControl>\n        <TableHeaders>\n          <TableColumnHeader>\n            <Label>DisplayName</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>Id</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>Publisher</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>Channel</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>PackageFamilyNames</Label>\n          </TableColumnHeader>\n          <TableColumnHeader>\n            <Label>ProductCodes</Label>\n          </TableColumnHeader>\n        </TableHeaders>\n        <TableRowEntries>\n          <TableRowEntry>\n            <TableColumnItems>\n              <TableColumnItem>\n                <ScriptBlock>$_.DisplayName</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.Id</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.Publisher</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.Channel</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.PackageFamilyNames</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.ProductCodes</ScriptBlock>\n              </TableColumnItem>\n            </TableColumnItems>\n          </TableRowEntry>\n        </TableRowEntries>\n      </TableControl>\n    </View>\r\n    <View>\r\n      <Name>Microsoft.WinGet.Client.Engine.PSObjects.PSRepairResult</Name>\r\n      <ViewSelectedBy>\r\n        <TypeName>Microsoft.WinGet.Client.Engine.PSObjects.PSRepairResult</TypeName>\n      </ViewSelectedBy>\r\n      <TableControl>\r\n        <TableHeaders>\r\n          <TableColumnHeader>\r\n            <Label>Id</Label>\r\n          </TableColumnHeader>\r\n          <TableColumnHeader>\r\n            <Label>Name</Label>\r\n          </TableColumnHeader>\r\n          <TableColumnHeader>\r\n            <Label>Source</Label>\r\n          </TableColumnHeader>\r\n          <TableColumnHeader>\r\n            <Label>RepairErrorCode</Label>\r\n          </TableColumnHeader>\r\n          <TableColumnHeader>\r\n            <Label>Status</Label>\r\n          </TableColumnHeader>\r\n          <TableColumnHeader>\r\n            <Label>RebootRequired</Label>\r\n          </TableColumnHeader>\r\n          <TableColumnHeader>\r\n            <Label>ExtendedErrorCode</Label>\r\n          </TableColumnHeader>\r\n          <TableColumnHeader>\r\n            <Label>CorrelationData</Label>\r\n          </TableColumnHeader>\r\n        </TableHeaders>\n        <TableRowEntries>\n          <TableRowEntry>\n            <TableColumnItems>\n              <TableColumnItem>\n                <ScriptBlock>$_.Id</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.Name</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.Source</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.RepairErrorCode</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.Status</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.RebootRequired</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.ExtendedErrorCode</ScriptBlock>\n              </TableColumnItem>\n              <TableColumnItem>\n                <ScriptBlock>$_.CorrelationData</ScriptBlock>\n              </TableColumnItem>\n            </TableColumnItems>\n          </TableRowEntry>\n        </TableRowEntries>\r\n      </TableControl>\n    </View>\n  </ViewDefinitions>\n</Configuration>\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client/ModuleFiles/Microsoft.WinGet.Client.psd1",
    "content": "#\n# Module manifest for module 'Microsoft.WinGet.Client'\n#\n# Created by: Microsoft Corporation\n#\n\n@{\n\n# Script module or binary module file associated with this manifest.\nRootModule = if ($PSEdition -like 'Core')\n{\n    \"net8.0-windows10.0.26100.0\\Microsoft.WinGet.Client.Cmdlets.dll\"\n}\nelse\n{\n    \"net48\\Microsoft.WinGet.Client.Cmdlets.dll\"\n}\n\n# Version number of this module.\nModuleVersion = '0.1.0'\n\n# Supported PSEditions\nCompatiblePSEditions = @('Desktop', 'Core')\n\n# ID used to uniquely identify this module\nGUID = 'e11157e2-cd24-4250-83b8-c6654ea4926a'\n\n# Author of this module\nAuthor = 'Microsoft Corporation'\n\n# Company or vendor of this module\nCompanyName = 'Microsoft Corporation'\n\n# Copyright statement for this module\nCopyright = '(c) Microsoft Corporation. All rights reserved.'\n\n# Description of the functionality provided by this module\nDescription = 'PowerShell Module for the Windows Package Manager Client.'\n\n# Minimum version of the PowerShell engine required by this module\nPowerShellVersion = '5.1.0'\n\n# Name of the PowerShell host required by this module\n# PowerShellHostName = ''\n\n# Minimum version of the PowerShell host required by this module\n# PowerShellHostVersion = ''\n\n# Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only.\n# DotNetFrameworkVersion = ''\n\n# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only.\n# ClrVersion = ''\n\n# Processor architecture (None, X86, Amd64) required by this module\n# ProcessorArchitecture = ''\n\n# Modules that must be imported into the global environment prior to importing this module\n# RequiredModules = @()\n\n# Assemblies that must be loaded prior to importing this module\n# RequiredAssemblies = @()\n\n# Script files (.ps1) that are run in the caller's environment prior to importing this module.\n# ScriptsToProcess = @()\n\n# Type files (.ps1xml) to be loaded when importing this module\n# TypesToProcess = @()\n\n# Format files (.ps1xml) to be loaded when importing this module\nFormatsToProcess = 'Format.ps1xml'\n\n# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.\nFunctionsToExport = @()\n\n# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.\nCmdletsToExport = @(\n    'Get-WinGetVersion'\n    'Find-WinGetPackage'\n    'Get-WinGetPackage'\n    'Get-WinGetSource'\n    'Install-WinGetPackage'\n    'Uninstall-WinGetPackage'\n    'Update-WinGetPackage'\n    'Get-WinGetUserSetting'\n    'Set-WinGetUserSetting'\n    'Test-WinGetUserSetting'\n    'Assert-WinGetPackageManager'\n    'Repair-WinGetPackageManager'\n    'Enable-WinGetSetting'\n    'Disable-WinGetSetting'\n    'Get-WinGetSetting'\n    'Add-WinGetSource'\n    'Remove-WinGetSource'\n    'Reset-WinGetSource'\n    'Export-WinGetPackage'\n    'Repair-WinGetPackage'\n)\n\n# Variables to export from this module\n# VariablesToExport = @()\n\n# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.\n    AliasesToExport  = @('awgs'\n        'awgpm'\n        'dwgs'\n        'ewgs'\n        'ewgp'\n        'fdwgp'\n        'gwgp'\n        'gwgse'\n        'gwgso'\n        'gwgus'\n        'gwgv'\n        'iswgp'\n        'rwgs'\n        'rpwgpm'\n        'rswgs'\n        'swgus'\n        'twgus'\n        'uswgp'\n        'udwgp',\n        'Get-WinGetSettings'\n        'Get-WinGetUserSettings'\n        'Set-WinGetUserSettings'\n        'Test-WinGetUserSettings')\n\n# DSC resources to export from this module\n# DscResourcesToExport = @()\n\n# List of all modules packaged with this module\n# ModuleList = @()\n\n# List of all files packaged with this module\n# FileList = @()\n\n# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.\nPrivateData = @{\n\n    PSData = @{\n\n        # Tags applied to this module. These help with module discovery in online galleries.\n        Tags = @(\n            'PSEdition_Desktop',\n            'PSEdition_Core',\n            'Windows',\n            'WindowsPackageManager',\n            'WinGet'\n        )\n\n        # A URL to the license for this module.\n        # LicenseUri = ''\n\n        # A URL to the main website for this project.\n        ProjectUri = 'https://github.com/microsoft/winget-cli'\n\n        # A URL to an icon representing this module.\n        IconUri = 'https://aka.ms/winget-icon'\n\n        # ReleaseNotes of this module\n        # ReleaseNotes = ''\n\n        # Prerelease string of this module\n        Prerelease = 'alpha'\n\n        # Flag to indicate whether the module requires explicit user acceptance for install/update/save\n        # RequireLicenseAcceptance = $false\n\n        # External dependent modules of this module\n        # ExternalModuleDependencies = @()\n\n    } # End of PSData hashtable\n\n} # End of PrivateData hashtable\n\n# HelpInfo URI of this module\n# HelpInfoURI = ''\n\n# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.\n# DefaultCommandPrefix = ''\n\n}\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client/README.md",
    "content": "# Windows Package Manager PowerShell Module\r\n\r\nThe Windows Package Manager PowerShell Module is made up on two components\r\n\r\n1. The `Microsoft.WinGet.Client.Cmdlets` project which contains cmdlet implementations.\r\n2. The `Microsoft.WinGet.Client.Engine` project which contain the real logic for the cmdlets.\r\n\r\n## Building the PowerShell Module Locally\r\n\r\nAfter building the Microsoft.WinGet.Client.Cmdlets project, the `Microsoft.WinGet.Client` PowerShell module can be found in the output directory in the `PowerShell` folder. For example if you built the project as x64 release, you should expect to find the module files in `$(SolutionDirectory)/src/x64/Release/PowerShell`.\r\n\r\nThis project has after build targets that will copy all the necessary files in the correct location.\r\n\r\n## Adding a new cmdlet\r\nIn order to avoid [assembly dependency conflicts](https://learn.microsoft.com/en-us/powershell/scripting/dev-cross-plat/resolving-dependency-conflicts?view=powershell-7.3) this project uses a custom `AssemblyLoadContext` that load all dependencies.\r\n\r\nMicrosoft.WinGet.Client.Cmdlets.dll is the binary that gets loaded when the module is imported. When Microsoft.WinGet.Client.Engine.dll is getting loaded the resolving handler use the custom ALC to load it. Then all the dependencies of that binary will be loaded using that custom context.\r\n\r\nThe dependencies are laid out in two directories: `DirectDependencies` and `SharedDependencies`. The resolving handler looks for binaries under `DirectDependencies` and uses the custom ALC to load them. The custom ALC load any binaries in `DirectDependencies` and `SharedDependencies`.\r\n\r\nException: WinRT.Runtime.dll doesn't support getting loaded in multiple times in the same process, because it affects static state in the CLR itself. We special case it to get loaded in by the default loader.\r\n\r\nIf the new cmdlet introduces a new dependency, please make sure to add it in the after build targets to copy it in the Dependencies directory.\r\n\r\n## Cmdlets\r\n- Assert-WinGetPackageManager\r\n- Find-WinGetPackage\r\n- Get-WinGetPackage\r\n- Get-WinGetSource\r\n- Get-WinGetUserSetting\r\n- Get-WinGetVersion\r\n- Install-WinGetPackage\r\n- Repair-WinGetPackageManager\r\n- Set-WinGetUserSetting\r\n- Test-WinGetUserSetting\r\n- Uninstall-WinGetPackage\r\n- Update-WinGetPackage\r\n- Add-WinGetSource\r\n- Disable-WinGetSetting\r\n- Enable-WinGetSetting\r\n- Get-WinGetSetting\r\n- Remove-WinGetSource\r\n- Reset-WinGetSource\r\n- Repair-WinGetPackage\r\n\r\n## Quick Start Guide\r\n\r\n**To run the module, make sure you are using the latest version of PowerShell (not Windows PowerShell)**. \r\n\r\n```\r\nwinget install --id Microsoft.Powershell\r\n```\r\n\r\nImport the module manifest (Microsoft.WinGet.Client.psd1) by running the following command:\r\n\r\n```\r\nImport-Module <Path to Microsoft.WinGet.Client.psd1>\r\n```\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/AddSourceCmdlet.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"AddSourceCmdlet.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Cmdlets.Cmdlets\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Cmdlets.PSObjects;\r\n    using Microsoft.WinGet.Client.Common;\r\n    using Microsoft.WinGet.Client.Engine.Commands;\r\n\r\n    /// <summary>\r\n    /// Adds a source. Requires admin.\r\n    /// </summary>\r\n    [Cmdlet(VerbsCommon.Add, Constants.WinGetNouns.Source)]\r\n    [Alias(\"awgs\")]\r\n    public sealed class AddSourceCmdlet : PSCmdlet\r\n    {\r\n        /// <summary>\r\n        /// Gets or sets the name of the source to add.\r\n        /// </summary>\r\n        [Parameter(\r\n            Mandatory = true,\r\n            ValueFromPipeline = true,\r\n            ValueFromPipelineByPropertyName = true)]\r\n        public string Name { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the argument of the source to add.\r\n        /// </summary>\r\n        [Parameter(\r\n            Mandatory = true,\r\n            ValueFromPipeline = true,\r\n            ValueFromPipelineByPropertyName = true)]\r\n        public string Argument { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the type of the source to add.\r\n        /// </summary>\r\n        [Parameter(\r\n            ValueFromPipeline = true,\r\n            ValueFromPipelineByPropertyName = true)]\r\n#if AICLI_DISABLE_TEST_HOOKS\r\n        [ValidateSet(\r\n            \"Microsoft.Rest\",\r\n            \"Microsoft.PreIndexed.Package\")]\r\n#else\r\n        [ValidateSet(\r\n            \"Microsoft.Rest\",\r\n            \"Microsoft.PreIndexed.Package\",\r\n            \"Microsoft.Test.Configurable\")]\r\n#endif\r\n        public string Type { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the trust level of the source to add.\r\n        /// </summary>\r\n        [Parameter(ValueFromPipelineByPropertyName = true)]\r\n        public PSSourceTrustLevel TrustLevel { get; set; } = PSSourceTrustLevel.Default;\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether the source to add is explicit.\r\n        /// </summary>\r\n        ///\r\n        [Parameter(ValueFromPipelineByPropertyName = true)]\r\n        public SwitchParameter Explicit { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating the priority of the source. Higher values are sorted first.\r\n        /// </summary>\r\n        ///\r\n        [Parameter(ValueFromPipelineByPropertyName = true)]\r\n        public int Priority { get; set; }\r\n\r\n        /// <summary>\r\n        /// Adds source.\r\n        /// </summary>\r\n        protected override void ProcessRecord()\r\n        {\r\n            var command = new CliCommand(this);\r\n            command.AddSource(this.Name, this.Argument, this.Type, this.ConvertPSSourceTrustLevelToString(this.TrustLevel), this.Explicit.ToBool(), this.Priority);\r\n        }\r\n\r\n        private string ConvertPSSourceTrustLevelToString(PSSourceTrustLevel trustLevel) => trustLevel switch\r\n        {\r\n            PSSourceTrustLevel.Default => string.Empty,\r\n            _ => trustLevel.ToString(),\r\n        };\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/AssertWinGetPackageManagerCmdlet.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"AssertWinGetPackageManagerCmdlet.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Commands\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Commands.Common;\r\n    using Microsoft.WinGet.Client.Common;\r\n    using Microsoft.WinGet.Client.Engine.Commands;\r\n\r\n    /// <summary>\r\n    /// Assert-WinGetPackageManager. Verifies winget is installed properly.\r\n    /// </summary>\r\n    [Cmdlet(\r\n        VerbsLifecycle.Assert,\r\n        Constants.WinGetNouns.WinGetPackageManager,\r\n        DefaultParameterSetName = Constants.IntegrityVersionSet)]\r\n    [Alias(\"awgpm\")]\r\n    public class AssertWinGetPackageManagerCmdlet : WinGetPackageManagerCmdlet\r\n    {\r\n        /// <summary>\r\n        /// Validates winget is installed correctly. If not, throws an exception\r\n        /// with the reason why, if any.\r\n        /// </summary>\r\n        protected override void ProcessRecord()\r\n        {\r\n            var command = new WinGetPackageManagerCommand(this);\r\n            if (this.ParameterSetName == Constants.IntegrityLatestSet)\r\n            {\r\n                command.AssertUsingLatest(this.IncludePrerelease.ToBool());\r\n            }\r\n            else\r\n            {\r\n                command.Assert(this.Version);\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/Common/FinderCmdlet.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"FinderCmdlet.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Commands.Common\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Common;\r\n    using Microsoft.WinGet.Client.PSObjects;\r\n\r\n    /// <summary>\r\n    /// This is the base class for all commands that might need to search for a package. It contains an initial\r\n    /// set of parameters that corresponds to the intersection of i.e., the \"install\" and \"search\" commands.\r\n    /// </summary>\r\n    public abstract class FinderCmdlet : PSCmdlet\r\n    {\r\n        /// <summary>\r\n        /// Gets or sets the field that is matched against the identifier of a package.\r\n        /// </summary>\r\n        [Parameter(\r\n            ParameterSetName = Constants.FoundSet,\r\n            ValueFromPipelineByPropertyName = true)]\r\n        public string Id { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the field that is matched against the name of a package.\r\n        /// </summary>\r\n        [Parameter(\r\n            ParameterSetName = Constants.FoundSet,\r\n            ValueFromPipelineByPropertyName = true)]\r\n        public string Name { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the field that is matched against the moniker of a package.\r\n        /// </summary>\r\n        [Parameter(\r\n            ParameterSetName = Constants.FoundSet,\r\n            ValueFromPipelineByPropertyName = true)]\r\n        public string Moniker { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the name of the source to search for packages. If null, then all sources are searched.\r\n        /// </summary>\r\n        [Parameter(\r\n            ParameterSetName = Constants.FoundSet,\r\n            ValueFromPipelineByPropertyName = true)]\r\n        public string Source { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the strings that match against every field of a package.\r\n        /// </summary>\r\n        [Parameter(\r\n            ParameterSetName = Constants.FoundSet,\r\n            Position = 0,\r\n            ValueFromPipelineByPropertyName = true,\r\n            ValueFromRemainingArguments = true)]\r\n        public string[] Query { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets how to match against package fields. Default ContainsCaseInsensitive.\r\n        /// </summary>\r\n        [Parameter(\r\n            ParameterSetName = Constants.FoundSet,\r\n            ValueFromPipelineByPropertyName = true)]\r\n        public PSPackageFieldMatchOption MatchOption { get; set; } = PSPackageFieldMatchOption.ContainsCaseInsensitive;\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/Common/FinderExtendedCmdlet.cs",
    "content": "﻿// -----------------------------------------------------------------------------\n// <copyright file=\"FinderExtendedCmdlet.cs\" company=\"Microsoft Corporation\">\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\n// </copyright>\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Commands.Common\n{\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Common;\r\n\r\n    /// <summary>\n    /// This is the base class for the commands whose sole purpose is to filter a list of packages i.e.,\r\n    /// the \"search\" and \"list\" commands. This class contains an extended set of parameters suited for\r\n    /// that purpose.\n    /// </summary>\n    public abstract class FinderExtendedCmdlet : FinderCmdlet\n    {\n        /// <summary>\n        /// Gets or sets the filter that is matched against the tags of the package.\n        /// </summary>\n        [Parameter(\n            ParameterSetName = Constants.FoundSet,\n            ValueFromPipelineByPropertyName = true)]\n        public string Tag { get; set; }\n\n        /// <summary>\n        /// Gets or sets the filter that is matched against the commands of the package.\n        /// </summary>\n        [Parameter(\n            ParameterSetName = Constants.FoundSet,\n            ValueFromPipelineByPropertyName = true)]\n        public string Command { get; set; }\n\n        /// <summary>\n        /// Gets or sets the maximum number of results returned.\n        /// </summary>\n        [ValidateRange(Constants.CountLowerBound, Constants.CountUpperBound)]\n        [Parameter(\n            ParameterSetName = Constants.FoundSet,\n            ValueFromPipelineByPropertyName = true)]\n        public uint Count { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/Common/InstallCmdlet.cs",
    "content": "﻿// -----------------------------------------------------------------------------\n// <copyright file=\"InstallCmdlet.cs\" company=\"Microsoft Corporation\">\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\n// </copyright>\n// -----------------------------------------------------------------------------\n\nnamespace Microsoft.WinGet.Client.Commands.Common\n{\r\n    using System.IO;\n    using System.Management.Automation;\n    using Microsoft.WinGet.Client.PSObjects;\r\n\n    /// <summary>\n    /// This is the base class for all commands that parse a FindPackagesOptions result\n    /// from the provided parameters i.e., the \"install\" and \"upgrade\" commands.\n    /// </summary>\n    public abstract class InstallCmdlet : InstallerSelectionCmdlet\n    {\n        private string location;\n\n        /// <summary>\n        /// Gets or sets the mode to manipulate the package with.\n        /// </summary>\n        [Parameter(ValueFromPipelineByPropertyName = true)]\n        public PSPackageInstallMode Mode { get; set; } = PSPackageInstallMode.Default;\n\n        /// <summary>\n        /// Gets or sets the override arguments to be passed on to the installer.\n        /// </summary>\n        [Parameter(ValueFromPipelineByPropertyName = true)]\n        public string Override { get; set; }\n\n        /// <summary>\n        /// Gets or sets the arguments to be passed on to the installer in addition to the defaults.\n        /// </summary>\n        [Parameter(ValueFromPipelineByPropertyName = true)]\n        public string Custom { get; set; }\n\n        /// <summary>\n        /// Gets or sets the installation location.\n        /// </summary>\n        [Parameter(ValueFromPipelineByPropertyName = true)]\n        public string Location\n        {\n            get => this.location;\n            set\n            {\n                this.location = Path.IsPathRooted(value)\n                    ? value\n                    : this.SessionState.Path.CurrentFileSystemLocation + @\"\\\" + value;\n            }\n        }\r\n\r\n        /// <summary>\n        /// Gets or sets the path to the logging file.\n        /// </summary>\n        [Parameter(ValueFromPipelineByPropertyName = true)]\n        public string Log { get; set; }\n\n        /// <summary>\n        /// Gets or sets a value indicating whether to continue upon non security related failures.\n        /// </summary>\n        [Parameter(ValueFromPipelineByPropertyName = true)]\n        public SwitchParameter Force { get; set; }\n\n        /// <summary>\n        /// Gets or sets the optional HTTP Header to pass on to the REST Source.\n        /// </summary>\n        [Parameter(ValueFromPipelineByPropertyName = true)]\n        public string Header { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/Common/PackageCmdlet.cs",
    "content": "﻿// -----------------------------------------------------------------------------\n// <copyright file=\"PackageCmdlet.cs\" company=\"Microsoft Corporation\">\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\n// </copyright>\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Commands.Common\n{\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Common;\r\n    using Microsoft.WinGet.Client.Engine.PSObjects;\r\n\r\n    /// <summary>\n    /// This is the base class for commands which operate on a specific package and version i.e.,\n    /// the \"install\", \"uninstall\", and \"upgrade\" commands.\n    /// </summary>\n    public abstract class PackageCmdlet : FinderCmdlet\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"PackageCmdlet\"/> class.\r\n        /// </summary>\n        public PackageCmdlet()\r\n        {\r\n            // The default match option for single package operations.\r\n            this.MatchOption = PSObjects.PSPackageFieldMatchOption.EqualsCaseInsensitive;\r\n        }\n\n        /// <summary>\n        /// Gets or sets the package to directly install.\n        /// </summary>\n        [Alias(\"InputObject\")]\n        [ValidateNotNull]\n        [Parameter(\n            ParameterSetName = Constants.GivenSet,\n            Position = 0,\n            ValueFromPipeline = true,\n            ValueFromPipelineByPropertyName = true)]\n        public PSCatalogPackage PSCatalogPackage { get; set; } = null;\n\n        /// <summary>\n        /// Gets or sets the version to install.\n        /// </summary>\n        [Parameter(ValueFromPipelineByPropertyName = true)]\n        public string Version { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/Common/WinGetPackageManagerCmdlet.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"WinGetPackageManagerCmdlet.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Commands.Common\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Common;\r\n\r\n    /// <summary>\r\n    /// Common parameters for Assert-WinGetPackageManager and Repair-WinGetPackageManager.\r\n    /// </summary>\r\n    public abstract class WinGetPackageManagerCmdlet : PSCmdlet\r\n    {\r\n        /// <summary>\r\n        /// Gets or sets the optional version.\r\n        /// </summary>\r\n        [Parameter(\r\n            ParameterSetName = Constants.IntegrityVersionSet,\r\n            ValueFromPipelineByPropertyName = true)]\r\n        public string Version { get; set; } = string.Empty;\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether to use latest.\r\n        /// </summary>\r\n        [Parameter(\r\n            ParameterSetName = Constants.IntegrityLatestSet,\r\n            ValueFromPipelineByPropertyName = true)]\r\n        public SwitchParameter Latest { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether to include prerelease winget versions.\r\n        /// </summary>\r\n        [Parameter(\r\n            ParameterSetName = Constants.IntegrityLatestSet,\r\n            ValueFromPipelineByPropertyName = true)]\r\n        [Parameter(\r\n            ParameterSetName = Constants.IntegrityVersionSet,\r\n            ValueFromPipelineByPropertyName = true)]\r\n        public SwitchParameter IncludePrerelease { get; set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/DisableSettingCmdlet.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"DisableSettingCmdlet.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Cmdlets.Cmdlets\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Common;\r\n    using Microsoft.WinGet.Client.Engine.Commands;\r\n\r\n    /// <summary>\r\n    /// Disables an admin setting. Requires admin.\r\n    /// </summary>\r\n    [Cmdlet(VerbsLifecycle.Disable, Constants.WinGetNouns.Setting)]\r\n    [Alias(\"dwgs\")]\r\n    public sealed class DisableSettingCmdlet : PSCmdlet\r\n    {\r\n        /// <summary>\r\n        /// Gets or sets the name of the setting to disable.\r\n        /// </summary>\r\n        [Parameter(\r\n            Position = 0,\r\n            Mandatory = true,\r\n            ValueFromPipeline = true,\r\n            ValueFromPipelineByPropertyName = true)]\r\n        [ValidateSet(\r\n            \"LocalManifestFiles\",\r\n            \"BypassCertificatePinningForMicrosoftStore\",\r\n            \"InstallerHashOverride\",\r\n            \"LocalArchiveMalwareScanOverride\",\r\n            \"ProxyCommandLineOptions\")]\r\n        public string Name { get; set; }\r\n\r\n        /// <summary>\r\n        /// Disables the admin setting.\r\n        /// </summary>\r\n        protected override void ProcessRecord()\r\n        {\r\n            var command = new CliCommand(this);\r\n            command.DisableSetting(this.Name);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/EnableSettingCmdlet.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"EnableSettingCmdlet.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Cmdlets.Cmdlets\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Common;\r\n    using Microsoft.WinGet.Client.Engine.Commands;\r\n\r\n    /// <summary>\r\n    /// Enables an admin setting. Requires admin.\r\n    /// </summary>\r\n    [Cmdlet(VerbsLifecycle.Enable, Constants.WinGetNouns.Setting)]\r\n    [Alias(\"ewgs\")]\r\n    public sealed class EnableSettingCmdlet : PSCmdlet\r\n    {\r\n        /// <summary>\r\n        /// Gets or sets the name of the setting to enable.\r\n        /// </summary>\r\n        [Parameter(\r\n            Position = 0,\r\n            Mandatory = true,\r\n            ValueFromPipeline = true,\r\n            ValueFromPipelineByPropertyName = true)]\r\n        [ValidateSet(\r\n            \"LocalManifestFiles\",\r\n            \"BypassCertificatePinningForMicrosoftStore\",\r\n            \"InstallerHashOverride\",\r\n            \"LocalArchiveMalwareScanOverride\",\r\n            \"ProxyCommandLineOptions\")]\r\n        public string Name { get; set; }\r\n\r\n        /// <summary>\r\n        /// Enables the admin setting.\r\n        /// </summary>\r\n        protected override void ProcessRecord()\r\n        {\r\n            var command = new CliCommand(this);\r\n            command.EnableSetting(this.Name);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/ExportPackageCmdlet.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ExportPackageCmdlet.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Commands\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Common;\r\n    using Microsoft.WinGet.Client.Engine.Commands;\r\n    using Microsoft.WinGet.Client.Engine.PSObjects;\r\n\r\n    /// <summary>\r\n    /// Downloads a package installer from the pipeline or from a configured source.\r\n    /// </summary>\r\n    [Cmdlet(\r\n        VerbsData.Export,\r\n        Constants.WinGetNouns.Package,\r\n        DefaultParameterSetName = Constants.FoundSet,\r\n        SupportsShouldProcess = true)]\r\n    [Alias(\"ewgp\")]\r\n    [OutputType(typeof(PSDownloadResult))]\r\n    public sealed class ExportPackageCmdlet : InstallerSelectionCmdlet\r\n    {\r\n        private DownloadCommand command = null;\r\n\r\n        /// <summary>\r\n        /// Gets or sets the directory where the installer will be downloaded to.\r\n        /// </summary>\r\n        [Parameter(ValueFromPipelineByPropertyName = true)]\r\n        public string DownloadDirectory { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether to skip acquiring the license from a Store package.\r\n        /// </summary>\r\n        [Parameter(ValueFromPipelineByPropertyName = true)]\r\n        public SwitchParameter SkipMicrosoftStoreLicense { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the platform to download the package for.\r\n        /// </summary>\r\n        [Parameter(ValueFromPipelineByPropertyName = true)]\r\n        public PSObjects.PSWindowsPlatform Platform { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the target OS version to download for.\r\n        /// </summary>\r\n        [Parameter(ValueFromPipelineByPropertyName = true)]\r\n        public string TargetOSVersion { get; set; }\r\n\r\n        /// <summary>\r\n        /// Installs a package from the pipeline or from a configured source.\r\n        /// </summary>\r\n        protected override void ProcessRecord()\r\n        {\r\n            this.command = new DownloadCommand(\r\n                        this,\r\n                        this.PSCatalogPackage,\r\n                        this.Version,\r\n                        this.Id,\r\n                        this.Name,\r\n                        this.Moniker,\r\n                        this.Source,\r\n                        this.Query,\r\n                        this.AllowHashMismatch.ToBool(),\r\n                        this.SkipDependencies.ToBool(),\r\n                        this.Locale);\r\n            this.command.Download(\r\n                this.DownloadDirectory,\r\n                this.MatchOption.ToString(),\r\n                this.Scope.ToString(),\r\n                this.Architecture.ToString(),\r\n                this.InstallerType.ToString(),\r\n                this.SkipMicrosoftStoreLicense.ToBool(),\r\n                this.Platform.ToString(),\r\n                this.TargetOSVersion);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Interrupts currently running code within the command.\r\n        /// </summary>\r\n        protected override void StopProcessing()\r\n        {\r\n            if (this.command != null)\r\n            {\r\n                this.command.Cancel();\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/FindPackageCmdlet.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"FindPackageCmdlet.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Commands\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Commands.Common;\r\n    using Microsoft.WinGet.Client.Common;\r\n    using Microsoft.WinGet.Client.Engine.Commands;\r\n    using Microsoft.WinGet.Client.Engine.PSObjects;\r\n\r\n    /// <summary>\r\n    /// Searches configured sources for packages.\r\n    /// </summary>\r\n    [Cmdlet(VerbsCommon.Find, Constants.WinGetNouns.Package)]\r\n    [Alias(\"fdwgp\")]\r\n    [OutputType(typeof(PSFoundCatalogPackage))]\r\n    public sealed class FindPackageCmdlet : FinderExtendedCmdlet\r\n    {\r\n        /// <summary>\r\n        /// Searches for configured sources for packages.\r\n        /// </summary>\r\n        protected override void ProcessRecord()\r\n        {\r\n            var command = new FinderPackageCommand(\r\n                this,\r\n                this.Id,\r\n                this.Name,\r\n                this.Moniker,\r\n                this.Source,\r\n                this.Query,\r\n                this.Tag,\r\n                this.Command,\r\n                this.Count);\r\n\r\n            command.Find(this.MatchOption.ToString());\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/GetPackageCmdlet.cs",
    "content": "﻿// -----------------------------------------------------------------------------\n// <copyright file=\"GetPackageCmdlet.cs\" company=\"Microsoft Corporation\">\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\n// </copyright>\n// -----------------------------------------------------------------------------\n\nnamespace Microsoft.WinGet.Client.Commands\n{\n    using System.Management.Automation;\n    using Microsoft.WinGet.Client.Commands.Common;\n    using Microsoft.WinGet.Client.Common;\n    using Microsoft.WinGet.Client.Engine.Commands;\n    using Microsoft.WinGet.Client.Engine.PSObjects;\n\n    /// <summary>\n    /// Searches configured sources for packages.\n    /// </summary>\n    [Cmdlet(VerbsCommon.Get, Constants.WinGetNouns.Package)]\n    [Alias(\"gwgp\")]\n    [OutputType(typeof(PSInstalledCatalogPackage))]\n    public sealed class GetPackageCmdlet : FinderExtendedCmdlet\n    {\n        /// <summary>\n        /// Searches for configured sources for packages.\n        /// </summary>\n        protected override void ProcessRecord()\n        {\n            var command = new FinderPackageCommand(\n                this,\n                this.Id,\n                this.Name,\n                this.Moniker,\n                this.Source,\n                this.Query,\n                this.Tag,\n                this.Command,\n                this.Count);\n\n            command.Get(this.MatchOption.ToString());\n        }\n    }\n}\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/GetSettingCmdlet.cs",
    "content": "// -----------------------------------------------------------------------------\n// <copyright file=\"GetSettingCmdlet.cs\" company=\"Microsoft Corporation\">\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\n// </copyright>\n// -----------------------------------------------------------------------------\n\nnamespace Microsoft.WinGet.Client.Cmdlets.Cmdlets\n{\n    using System.Management.Automation;\n    using Microsoft.WinGet.Client.Common;\n    using Microsoft.WinGet.Client.Engine.Commands;\n\n    /// <summary>\n    /// Gets winget settings.\n    /// </summary>\n    [Cmdlet(VerbsCommon.Get, Constants.WinGetNouns.Setting)]\n    [Alias(\"gwgse\", \"Get-WinGetSettings\")]\n    public sealed class GetSettingCmdlet : PSCmdlet\n    {\n        /// <summary>\n        /// Gets or sets a value indicating whether to output a string or a hashtable.\n        /// </summary>\n        [Parameter(ValueFromPipelineByPropertyName = true)]\n        public SwitchParameter AsPlainText { get; set; }\n\n        /// <summary>\n        /// Get settings.\n        /// </summary>\n        protected override void ProcessRecord()\n        {\n            var command = new CliCommand(this);\n            command.GetSettings(this.AsPlainText.ToBool());\n        }\n    }\n}\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/GetSourceCmdlet.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"GetSourceCmdlet.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Commands\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Common;\r\n    using Microsoft.WinGet.Client.Engine.Commands;\r\n    using Microsoft.WinGet.Client.Engine.PSObjects;\r\n\r\n    /// <summary>\r\n    /// Retrieves the list of configured sources.\r\n    /// </summary>\r\n    [Cmdlet(VerbsCommon.Get, Constants.WinGetNouns.Source)]\r\n    [Alias(\"gwgso\")]\r\n    [OutputType(typeof(PSSourceResult))]\r\n    public sealed class GetSourceCmdlet : PSCmdlet\r\n    {\r\n        /// <summary>\r\n        /// Gets or sets the name of the source to retrieve.\r\n        /// </summary>\r\n        [Parameter(\r\n            Position = 0,\r\n            ValueFromPipeline = true,\r\n            ValueFromPipelineByPropertyName = true)]\r\n        public string Name { get; set; }\r\n\r\n        /// <summary>\r\n        /// Returns the list of configured sources.\r\n        /// </summary>\r\n        protected override void ProcessRecord()\r\n        {\r\n            var command = new SourceCommand(this);\r\n            command.Get(this.Name);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/GetUserSettingCmdlet.cs",
    "content": "﻿// -----------------------------------------------------------------------------\n// <copyright file=\"GetUserSettingCmdlet.cs\" company=\"Microsoft Corporation\">\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\n// </copyright>\n// -----------------------------------------------------------------------------\n\nnamespace Microsoft.WinGet.Client.Commands\n{\n    using System.Collections;\n    using System.Management.Automation;\n    using Microsoft.WinGet.Client.Common;\n    using Microsoft.WinGet.Client.Engine.Commands;\n\n    /// <summary>\n    /// Gets winget's user settings.\n    /// </summary>\n    [Cmdlet(VerbsCommon.Get, Constants.WinGetNouns.UserSetting)]\n    [Alias(\"gwgus\", \"Get-WinGetUserSettings\")]\n    [OutputType(typeof(Hashtable))]\n    public sealed class GetUserSettingCmdlet : PSCmdlet\n    {\n        /// <summary>\n        /// Gets the settings file contents.\n        /// </summary>\n        protected override void ProcessRecord()\n        {\n            var command = new UserSettingsCommand(this);\n            command.Get();\n        }\n    }\n}\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/GetVersionCmdlet.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"GetVersionCmdlet.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Commands\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Common;\r\n    using Microsoft.WinGet.Client.Engine.Commands;\r\n\r\n    /// <summary>\r\n    /// Get-WinGetVersion. Gets the current version of winget.\r\n    /// </summary>\r\n    [Cmdlet(VerbsCommon.Get, Constants.WinGetNouns.Version)]\r\n    [Alias(\"gwgv\")]\r\n    [OutputType(typeof(string))]\r\n    public class GetVersionCmdlet : PSCmdlet\r\n    {\r\n        /// <summary>\r\n        /// Writes the winget version.\r\n        /// </summary>\r\n        protected override void ProcessRecord()\r\n        {\r\n            var command = new VersionCommand(this);\r\n            command.Get();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/InstallPackageCmdlet.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"InstallPackageCmdlet.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Commands\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Commands.Common;\r\n    using Microsoft.WinGet.Client.Common;\r\n    using Microsoft.WinGet.Client.Engine.Commands;\r\n    using Microsoft.WinGet.Client.Engine.PSObjects;\r\n\r\n    /// <summary>\r\n    /// Installs a package from the pipeline or from a configured source.\r\n    /// </summary>\r\n    [Cmdlet(\r\n        VerbsLifecycle.Install,\r\n        Constants.WinGetNouns.Package,\r\n        DefaultParameterSetName = Constants.FoundSet,\r\n        SupportsShouldProcess = true)]\r\n    [Alias(\"iswgp\")]\r\n    [OutputType(typeof(PSInstallResult))]\r\n    public sealed class InstallPackageCmdlet : InstallCmdlet\r\n    {\r\n        private InstallerPackageCommand command = null;\r\n\r\n        /// <summary>\r\n        /// Installs a package from the pipeline or from a configured source.\r\n        /// </summary>\r\n        protected override void ProcessRecord()\r\n        {\r\n            this.command = new InstallerPackageCommand(\r\n                        this,\r\n                        this.Override,\r\n                        this.Custom,\r\n                        this.Location,\r\n                        this.AllowHashMismatch.ToBool(),\r\n                        this.Force.ToBool(),\r\n                        this.Header,\r\n                        this.PSCatalogPackage,\r\n                        this.Version,\r\n                        this.Log,\r\n                        this.Id,\r\n                        this.Name,\r\n                        this.Moniker,\r\n                        this.Source,\r\n                        this.Query,\r\n                        this.SkipDependencies.ToBool());\r\n\r\n            this.command.Install(this.MatchOption.ToString(), this.Scope.ToString(), this.Architecture.ToString(), this.Mode.ToString(), this.InstallerType.ToString());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Interrupts currently running code within the command.\r\n        /// </summary>\r\n        protected override void StopProcessing()\r\n        {\r\n            if (this.command != null)\r\n            {\r\n                this.command.Cancel();\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/InstallerSelectionCmdlet.cs",
    "content": "﻿// -----------------------------------------------------------------------------\n// <copyright file=\"InstallerSelectionCmdlet.cs\" company=\"Microsoft Corporation\">\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\n// </copyright>\n// -----------------------------------------------------------------------------\n\nnamespace Microsoft.WinGet.Client.Commands\n{\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Commands.Common;\n    using Microsoft.WinGet.Client.PSObjects;\r\n\r\n    /// <summary>\n    /// This is the base class for all commands that select an installer from a given package.\n    /// Contains shared arguments for the install, update, and download commands.\n    /// </summary>\n    public abstract class InstallerSelectionCmdlet : PackageCmdlet\n    {\n        /// <summary>\n        /// Gets or sets a value indicating whether to skip the installer hash validation check.\n        /// </summary>\n        [Parameter(ValueFromPipelineByPropertyName = true)]\n        public SwitchParameter AllowHashMismatch { get; set; }\n\n        /// <summary>\n        /// Gets or sets the architecture of the installer to be downloaded.\n        /// </summary>\n        [Parameter(ValueFromPipelineByPropertyName = true)]\n        public PSProcessorArchitecture Architecture { get; set; } = PSProcessorArchitecture.Default;\r\n\r\n        /// <summary>\r\n        /// Gets or sets the installer type to be downloaded.\r\n        /// </summary>\r\n        [Parameter(ValueFromPipelineByPropertyName = true)]\n        public PSPackageInstallerType InstallerType { get; set; } = PSPackageInstallerType.Default;\r\n\n        /// <summary>\n        /// Gets or sets the locale of the installer to be downloaded.\n        /// </summary>\n        [Parameter(ValueFromPipelineByPropertyName = true)]\n        public string Locale { get; set; }\r\n\r\n        /// <summary>\n        /// Gets or sets the scope of the installer to be downloaded.\n        /// </summary>\n        [Parameter(ValueFromPipelineByPropertyName = true)]\n        public PSPackageInstallScope Scope { get; set; } = PSPackageInstallScope.Any;\r\n\r\n        /// <summary>\n        /// Gets or sets a value indicating whether skip dependencies.\n        /// </summary>\n        [Parameter(ValueFromPipelineByPropertyName = true)]\n        public SwitchParameter SkipDependencies { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/PSObjects/PSPackageFieldMatchOption.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"PSPackageFieldMatchOption.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.PSObjects\r\n{\r\n    /// <summary>\r\n    /// This should mimic Microsoft.Management.Deployment.PackageFileMatchOption.\r\n    /// </summary>\r\n    public enum PSPackageFieldMatchOption\r\n    {\r\n        /// <summary>\r\n        /// Equals.\r\n        /// </summary>\r\n        Equals,\r\n\r\n        /// <summary>\r\n        /// EqualsCaseInsensitive.\r\n        /// </summary>\r\n        EqualsCaseInsensitive,\r\n\r\n        /// <summary>\r\n        /// StartsWithCaseInsensitive.\r\n        /// </summary>\r\n        StartsWithCaseInsensitive,\r\n\r\n        /// <summary>\r\n        /// ContainsCaseInsensitive\r\n        /// </summary>\r\n        ContainsCaseInsensitive,\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/PSObjects/PSPackageInstallMode.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"PSPackageInstallMode.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.PSObjects\r\n{\r\n    /// <summary>\r\n    /// This should mimic Microsoft.Management.Deployment.PackageInstallMode.\r\n    /// </summary>\r\n    public enum PSPackageInstallMode\r\n    {\r\n        /// <summary>\r\n        /// Default,\r\n        /// </summary>\r\n        Default,\r\n\r\n        /// <summary>\r\n        /// Silent,\r\n        /// </summary>\r\n        Silent,\r\n\r\n        /// <summary>\r\n        /// Interactive,\r\n        /// </summary>\r\n        Interactive,\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/PSObjects/PSPackageInstallScope.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"PSPackageInstallScope.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.PSObjects\r\n{\r\n    /// <summary>\r\n    /// This must match Microsoft.Management.Deployment.PackageInstallScope.\r\n    /// </summary>\r\n    public enum PSPackageInstallScope\r\n    {\r\n        /// <summary>\r\n        /// Any.\r\n        /// </summary>\r\n        Any,\r\n\r\n        /// <summary>\r\n        /// User.\r\n        /// </summary>\r\n        User,\r\n\r\n        /// <summary>\r\n        /// System.\r\n        /// </summary>\r\n        System,\r\n\r\n        /// <summary>\r\n        /// User or unknown.\r\n        /// </summary>\r\n        UserOrUnknown,\r\n\r\n        /// <summary>\r\n        /// System or unknown.\r\n        /// </summary>\r\n        SystemOrUnknown,\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/PSObjects/PSPackageInstallerType.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"PSPackageInstallerType.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.PSObjects\r\n{\r\n    /// <summary>\r\n    /// The installer type of the package.\r\n    /// </summary>\r\n    public enum PSPackageInstallerType\r\n    {\r\n        /// <summary>\r\n        /// Let winget decide.\r\n        /// </summary>\r\n        Default,\r\n\r\n        /// <summary>\r\n        /// Inno,\r\n        /// </summary>\r\n        Inno,\r\n\r\n        /// <summary>\r\n        /// Wix.\r\n        /// </summary>\r\n        Wix,\r\n\r\n        /// <summary>\r\n        /// Msi.\r\n        /// </summary>\r\n        Msi,\r\n\r\n        /// <summary>\r\n        /// Nullsoft.\r\n        /// </summary>\r\n        Nullsoft,\r\n\r\n        /// <summary>\r\n        /// Zip.\r\n        /// </summary>\r\n        Zip,\r\n\r\n        /// <summary>\r\n        /// Msix.\r\n        /// </summary>\r\n        Msix,\r\n\r\n        /// <summary>\r\n        /// Exe.\r\n        /// </summary>\r\n        Exe,\r\n\r\n        /// <summary>\r\n        /// Burn.\r\n        /// </summary>\r\n        Burn,\r\n\r\n        /// <summary>\r\n        /// MSStore,\r\n        /// </summary>\r\n        MSStore,\r\n\r\n        /// <summary>\r\n        /// Portable.\r\n        /// </summary>\r\n        Portable,\r\n    }\r\n}"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/PSObjects/PSPackageRepairMode.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"PSPackageRepairMode.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.PSObjects\r\n{\r\n    /// <summary>\r\n    /// Must match Microsoft.Management.Deployment.PackageRepairMode.\r\n    /// </summary>\r\n    public enum PSPackageRepairMode\r\n    {\r\n        /// <summary>\r\n        /// Default.\r\n        /// </summary>\r\n        Default,\r\n\r\n        /// <summary>\r\n        /// Silent.\r\n        /// </summary>\r\n        Silent,\r\n\r\n        /// <summary>\r\n        /// Interactive.\r\n        /// </summary>\r\n        Interactive,\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/PSObjects/PSPackageUninstallMode.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"PSPackageUninstallMode.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.PSObjects\r\n{\r\n    /// <summary>\r\n    /// Must match Microsoft.Management.Deployment.PackageUninstallMode.\r\n    /// </summary>\r\n    public enum PSPackageUninstallMode\r\n    {\r\n        /// <summary>\r\n        /// Default.\r\n        /// </summary>\r\n        Default,\r\n\r\n        /// <summary>\r\n        /// Silent.\r\n        /// </summary>\r\n        Silent,\r\n\r\n        /// <summary>\r\n        /// Interactive.\r\n        /// </summary>\r\n        Interactive,\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/PSObjects/PSProcessorArchitecture.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"PSProcessorArchitecture.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.PSObjects\r\n{\r\n    /// <summary>\r\n    /// The processor architecture of the package to install.\r\n    /// </summary>\r\n    public enum PSProcessorArchitecture\r\n    {\r\n        /// <summary>\r\n        /// Let winget decide.\r\n        /// </summary>\r\n        Default,\r\n\r\n        /// <summary>\r\n        /// x86,\r\n        /// </summary>\r\n        X86,\r\n\r\n        /// <summary>\r\n        /// ARM.\r\n        /// </summary>\r\n        Arm,\r\n\r\n        /// <summary>\r\n        /// x64.\r\n        /// </summary>\r\n        X64,\r\n\r\n        /// <summary>\r\n        /// Arm64\r\n        /// </summary>\r\n        Arm64,\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/PSObjects/PSSourceTrustLevel.cs",
    "content": "// -----------------------------------------------------------------------------\n// <copyright file=\"PSSourceTrustLevel.cs\" company=\"Microsoft Corporation\">\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\n// </copyright>\n// -----------------------------------------------------------------------------\n\nnamespace Microsoft.WinGet.Client.Cmdlets.PSObjects\n{\n    /// <summary>\n    /// This is the powershell argument equivalent of AppInstaller::Repository::SourceTrustLevel.\n    /// </summary>\n    public enum PSSourceTrustLevel\n    {\n        /// <summary>\n        /// Let winget decide.\n        /// </summary>\n        Default,\n\n        /// <summary>\n        /// None.\n        /// </summary>\n        None,\n\n        /// <summary>\n        /// Trusted.\n        /// </summary>\n        Trusted,\n    }\n}\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/PSObjects/PSWindowsPlatform.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"PSWindowsPlatform.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.PSObjects\r\n{\r\n    /// <summary>\r\n    /// The Windows platform type.\r\n    /// </summary>\r\n    public enum PSWindowsPlatform\r\n    {\r\n        /// <summary>\r\n        /// Let winget decide.\r\n        /// </summary>\r\n        Default,\r\n\r\n        /// <summary>\r\n        /// Windows.Universal\r\n        /// </summary>\r\n        Universal,\r\n\r\n        /// <summary>\r\n        /// Windows.Desktop\r\n        /// </summary>\r\n        Desktop,\r\n\r\n        /// <summary>\r\n        /// Windows.IoT\r\n        /// </summary>\r\n        IoT,\r\n\r\n        /// <summary>\r\n        /// Windows.Team\r\n        /// </summary>\r\n        Team,\r\n\r\n        /// <summary>\r\n        /// Windows.Holographic\r\n        /// </summary>\r\n        Holographic,\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/RemoveSourceCmdlet.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"RemoveSourceCmdlet.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Cmdlets\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Common;\r\n    using Microsoft.WinGet.Client.Engine.Commands;\r\n\r\n    /// <summary>\r\n    /// Removes a source. Requires admin.\r\n    /// </summary>\r\n    [Cmdlet(VerbsCommon.Remove, Constants.WinGetNouns.Source)]\r\n    [Alias(\"rwgs\")]\r\n    public sealed class RemoveSourceCmdlet : PSCmdlet\r\n    {\r\n        /// <summary>\r\n        /// Gets or sets the name of the source to remove.\r\n        /// </summary>\r\n        [Parameter(\r\n            Position = 0,\r\n            Mandatory = true,\r\n            ValueFromPipeline = true,\r\n            ValueFromPipelineByPropertyName = true)]\r\n        public string Name { get; set; }\r\n\r\n        /// <summary>\r\n        /// Removes source.\r\n        /// </summary>\r\n        protected override void ProcessRecord()\r\n        {\r\n            var command = new CliCommand(this);\r\n            command.RemoveSource(this.Name);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/RepairPackageCmdlet.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"RepairPackageCmdlet.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Commands\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Commands.Common;\r\n    using Microsoft.WinGet.Client.Common;\r\n    using Microsoft.WinGet.Client.Engine.Commands;\r\n    using Microsoft.WinGet.Client.Engine.PSObjects;\r\n    using Microsoft.WinGet.Client.PSObjects;\r\n\r\n    /// <summary>\r\n    /// This class defines the repair package command.\r\n    /// </summary>\r\n    [Cmdlet(\r\n        VerbsDiagnostic.Repair,\r\n        Constants.WinGetNouns.Package,\r\n        DefaultParameterSetName = Constants.FoundSet,\r\n        SupportsShouldProcess = true)]\r\n    [OutputType(typeof(PSRepairResult))]\r\n    public sealed class RepairPackageCmdlet : PackageCmdlet\r\n    {\r\n        private RepairPackageCommand command = null;\r\n\r\n        /// <summary>\r\n        /// Gets or sets the desired mode for the repair process.\r\n        /// </summary>\r\n        [Parameter(ValueFromPipelineByPropertyName = true)]\r\n        public PSPackageRepairMode Mode { get; set; } = PSPackageRepairMode.Default;\r\n\r\n        /// <summary>\r\n        /// Gets or sets the path to the logging file.\r\n        /// </summary>\r\n        [Parameter]\r\n        public string Log { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether to skip the installer hash validation check.\r\n        /// </summary>\r\n        [Parameter(ValueFromPipelineByPropertyName = true)]\r\n        public SwitchParameter AllowHashMismatch { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether to continue upon non security related failures.\r\n        /// </summary>\r\n        [Parameter(ValueFromPipelineByPropertyName = true)]\r\n        public SwitchParameter Force { get; set; }\r\n\r\n        /// <summary>\r\n        /// Repairs a package from the local system.\r\n        /// </summary>\r\n        protected override void ProcessRecord()\r\n        {\r\n            this.command = new RepairPackageCommand(\r\n                        this,\r\n                        this.AllowHashMismatch.ToBool(),\r\n                        this.Force.ToBool(),\r\n                        this.PSCatalogPackage,\r\n                        this.Version,\r\n                        this.Log,\r\n                        this.Id,\r\n                        this.Name,\r\n                        this.Moniker,\r\n                        this.Source,\r\n                        this.Query);\r\n            this.command.Repair(this.MatchOption.ToString(), this.Mode.ToString());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Interrupts currently running code within the command.\r\n        /// </summary>\r\n        protected override void StopProcessing()\r\n        {\r\n            if (this.command != null)\r\n            {\r\n                this.command.Cancel();\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/RepairWinGetPackageManagerCmdlet.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"RepairWinGetPackageManagerCmdlet.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Commands\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Commands.Common;\r\n    using Microsoft.WinGet.Client.Common;\r\n    using Microsoft.WinGet.Client.Engine.Commands;\r\n\r\n    /// <summary>\r\n    /// Repair-WinGetPackageManager. Repairs winget if needed.\r\n    /// </summary>\r\n    [Cmdlet(\r\n        VerbsDiagnostic.Repair,\r\n        Constants.WinGetNouns.WinGetPackageManager,\r\n        DefaultParameterSetName = Constants.IntegrityVersionSet)]\r\n    [Alias(\"rpwgpm\")]\r\n    [OutputType(typeof(int))]\r\n    public class RepairWinGetPackageManagerCmdlet : WinGetPackageManagerCmdlet\r\n    {\r\n        private WinGetPackageManagerCommand command = null;\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether to repair for all users. Requires admin.\r\n        /// </summary>\r\n        [Parameter(ValueFromPipelineByPropertyName = true)]\r\n        public SwitchParameter AllUsers { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether to force application shutdown.\r\n        /// </summary>\r\n        [Parameter(ValueFromPipelineByPropertyName = true)]\r\n        public SwitchParameter Force { get; set; }\r\n\r\n        /// <summary>\r\n        /// Attempts to repair winget.\r\n        /// TODO: consider WhatIf and Confirm options.\r\n        /// </summary>\r\n        protected override void ProcessRecord()\r\n        {\r\n            this.command = new WinGetPackageManagerCommand(this);\r\n            if (this.ParameterSetName == Constants.IntegrityLatestSet)\r\n            {\r\n                this.command.RepairUsingLatest(this.IncludePrerelease.ToBool(), this.AllUsers.ToBool(), this.Force.ToBool());\r\n            }\r\n            else\r\n            {\r\n                this.command.Repair(this.Version, this.AllUsers.ToBool(), this.Force.ToBool(), this.IncludePrerelease.ToBool());\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Interrupts currently running code within the command.\r\n        /// </summary>\r\n        protected override void StopProcessing()\r\n        {\r\n            if (this.command != null)\r\n            {\r\n                this.command.Cancel();\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/ResetSourceCmdlet.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ResetSourceCmdlet.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Cmdlets.Cmdlets\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Common;\r\n    using Microsoft.WinGet.Client.Engine.Commands;\r\n\r\n    /// <summary>\r\n    /// Resets a source. Requires admin.\r\n    /// </summary>\r\n    [Cmdlet(VerbsCommon.Reset, Constants.WinGetNouns.Source, DefaultParameterSetName = Constants.DefaultSet)]\r\n    [Alias(\"rswgs\")]\r\n    public sealed class ResetSourceCmdlet : PSCmdlet\r\n    {\r\n        /// <summary>\r\n        /// Gets or sets the name of the source to reset.\r\n        /// </summary>\r\n        [Parameter(\r\n            Position = 0,\r\n            Mandatory = true,\r\n            ParameterSetName = Constants.DefaultSet,\r\n            ValueFromPipeline = true,\r\n            ValueFromPipelineByPropertyName = true)]\r\n        public string Name { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether to reset all sources.\r\n        /// </summary>\r\n        [Parameter(ParameterSetName = Constants.OptionalSet, ValueFromPipelineByPropertyName = true)]\r\n        public SwitchParameter All { get; set; }\r\n\r\n        /// <summary>\r\n        /// Resets source.\r\n        /// </summary>\r\n        protected override void ProcessRecord()\r\n        {\r\n            var command = new CliCommand(this);\r\n\r\n            if (!string.IsNullOrEmpty(this.Name))\r\n            {\r\n                command.ResetSourceByName(this.Name);\r\n            }\r\n            else if (this.All)\r\n            {\r\n                command.ResetAllSources();\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/SetUserSettingCmdlet.cs",
    "content": "﻿// -----------------------------------------------------------------------------\n// <copyright file=\"SetUserSettingCmdlet.cs\" company=\"Microsoft Corporation\">\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\n// </copyright>\n// -----------------------------------------------------------------------------\n\nnamespace Microsoft.WinGet.Client.Commands\n{\n    using System.Collections;\n    using System.Management.Automation;\n    using Microsoft.WinGet.Client.Common;\n    using Microsoft.WinGet.Client.Engine.Commands;\n\n    /// <summary>\n    /// Sets the specified user settings into the winget user settings. If the merge switch is on, merges current user\n    /// settings with the input settings. Otherwise, overwrites the input settings.\n    /// </summary>\n    [Cmdlet(VerbsCommon.Set, Constants.WinGetNouns.UserSetting)]\n    [Alias(\"swgus\", \"Set-WinGetUserSettings\")]\n    [OutputType(typeof(Hashtable))]\n    public sealed class SetUserSettingCmdlet : PSCmdlet\n    {\n        /// <summary>\n        /// Gets or sets the input user settings.\n        /// </summary>\n        [Parameter(\n            Mandatory = true,\n            ValueFromPipelineByPropertyName = true)]\n        public Hashtable UserSettings { get; set; }\n\n        /// <summary>\n        /// Gets or sets a value indicating whether to merge the current user settings and the input settings.\n        /// </summary>\n        [Parameter(ValueFromPipelineByPropertyName = true)]\n        public SwitchParameter Merge { get; set; }\n\n        /// <summary>\n        /// Process input of cmdlet.\n        /// </summary>\n        protected override void ProcessRecord()\n        {\n            var command = new UserSettingsCommand(this);\n            command.Set(this.UserSettings, this.Merge.ToBool());\n        }\n    }\n}\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/TestUserSettingCmdlet.cs",
    "content": "﻿// -----------------------------------------------------------------------------\n// <copyright file=\"TestUserSettingCmdlet.cs\" company=\"Microsoft Corporation\">\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\n// </copyright>\n// -----------------------------------------------------------------------------\n\nnamespace Microsoft.WinGet.Client.Commands\n{\n    using System.Collections;\n    using System.Management.Automation;\n    using Microsoft.WinGet.Client.Common;\n    using Microsoft.WinGet.Client.Engine.Commands;\n\n    /// <summary>\n    /// Compare the specified user settings with the winget user settings.\n    /// </summary>\n    [Cmdlet(VerbsDiagnostic.Test, Constants.WinGetNouns.UserSetting)]\n    [Alias(\"twgus\", \"Test-WinGetUserSettings\")]\n    [OutputType(typeof(bool))]\n    public sealed class TestUserSettingCmdlet : PSCmdlet\n    {\n        /// <summary>\n        /// Gets or sets the input user settings.\n        /// </summary>\n        [Parameter(\n            Mandatory = true,\n            ValueFromPipelineByPropertyName = true)]\n        public Hashtable UserSettings { get; set; }\n\n        /// <summary>\n        /// Gets or sets a value indicating whether to ignore comparing settings that are not part of the input.\n        /// </summary>\n        [Parameter(ValueFromPipelineByPropertyName = true)]\n        public SwitchParameter IgnoreNotSet { get; set; }\n\n        /// <summary>\n        /// Process the cmdlet and writes the result of the comparison.\n        /// </summary>\n        protected override void ProcessRecord()\n        {\n            var command = new UserSettingsCommand(this);\n            command.Test(this.UserSettings, this.IgnoreNotSet.ToBool());\n        }\n    }\n}\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/UninstallPackageCmdlet.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"UninstallPackageCmdlet.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Commands\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Commands.Common;\r\n    using Microsoft.WinGet.Client.Common;\r\n    using Microsoft.WinGet.Client.Engine.Commands;\r\n    using Microsoft.WinGet.Client.Engine.PSObjects;\r\n    using Microsoft.WinGet.Client.PSObjects;\r\n\r\n    /// <summary>\r\n    /// Uninstalls a package from the local system.\r\n    /// </summary>\r\n    [Cmdlet(\r\n        VerbsLifecycle.Uninstall,\r\n        Constants.WinGetNouns.Package,\r\n        DefaultParameterSetName = Constants.FoundSet,\r\n        SupportsShouldProcess = true)]\r\n    [Alias(\"uswgp\")]\r\n    [OutputType(typeof(PSUninstallResult))]\r\n    public sealed class UninstallPackageCmdlet : PackageCmdlet\r\n    {\r\n        private UninstallPackageCommand command = null;\r\n\r\n        /// <summary>\r\n        /// Gets or sets the desired mode for the uninstallation process.\r\n        /// </summary>\r\n        [Parameter(ValueFromPipelineByPropertyName = true)]\r\n        public PSPackageUninstallMode Mode { get; set; } = PSPackageUninstallMode.Default;\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether to continue upon non security related failures.\r\n        /// </summary>\r\n        [Parameter(ValueFromPipelineByPropertyName = true)]\r\n        public SwitchParameter Force { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the path to the logging file.\r\n        /// </summary>\r\n        [Parameter(ValueFromPipelineByPropertyName = true)]\r\n        public string Log { get; set; }\r\n\r\n        /// <summary>\r\n        /// Uninstalls a package from the local system.\r\n        /// </summary>\r\n        protected override void ProcessRecord()\r\n        {\r\n            this.command = new UninstallPackageCommand(\r\n                        this,\r\n                        this.PSCatalogPackage,\r\n                        this.Version,\r\n                        this.Log,\r\n                        this.Id,\r\n                        this.Name,\r\n                        this.Moniker,\r\n                        this.Source,\r\n                        this.Query);\r\n            this.command.Uninstall(this.MatchOption.ToString(), this.Mode.ToString(), this.Force.ToBool());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Interrupts currently running code within the command.\r\n        /// </summary>\r\n        protected override void StopProcessing()\r\n        {\r\n            if (this.command != null)\r\n            {\r\n                this.command.Cancel();\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Cmdlets/UpdatePackageCmdlet.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"UpdatePackageCmdlet.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Commands\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Commands.Common;\r\n    using Microsoft.WinGet.Client.Common;\r\n    using Microsoft.WinGet.Client.Engine.Commands;\r\n    using Microsoft.WinGet.Client.Engine.PSObjects;\r\n\r\n    /// <summary>\r\n    /// This commands updates a package from the pipeline or from the local system.\r\n    /// </summary>\r\n    [Cmdlet(\r\n        VerbsData.Update,\r\n        Constants.WinGetNouns.Package,\r\n        DefaultParameterSetName = Constants.FoundSet,\r\n        SupportsShouldProcess = true)]\r\n    [Alias(\"udwgp\")]\r\n    [OutputType(typeof(PSInstallResult))]\r\n    public sealed class UpdatePackageCmdlet : InstallCmdlet\r\n    {\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether updating to an unknown version is allowed.\r\n        /// </summary>\r\n        [Parameter(ValueFromPipelineByPropertyName = true)]\r\n        public SwitchParameter IncludeUnknown { get; set; }\r\n\r\n        /// <summary>\r\n        /// Updates a package from the pipeline or from the local system.\r\n        /// </summary>\r\n        protected override void ProcessRecord()\r\n        {\r\n            var command = new InstallerPackageCommand(\r\n                        this,\r\n                        this.Override,\r\n                        this.Custom,\r\n                        this.Location,\r\n                        this.AllowHashMismatch.ToBool(),\r\n                        this.Force.ToBool(),\r\n                        this.Header,\r\n                        this.PSCatalogPackage,\r\n                        this.Version,\r\n                        this.Log,\r\n                        this.Id,\r\n                        this.Name,\r\n                        this.Moniker,\r\n                        this.Source,\r\n                        this.Query,\r\n                        this.SkipDependencies);\r\n            command.Update(this.IncludeUnknown.ToBool(), this.MatchOption.ToString(), this.Scope.ToString(), this.Architecture.ToString(), this.Mode.ToString(), this.InstallerType.ToString());\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Common/Constants.cs",
    "content": "// -----------------------------------------------------------------------------\n// <copyright file=\"Constants.cs\" company=\"Microsoft Corporation\">\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\n// </copyright>\n// -----------------------------------------------------------------------------\n\nnamespace Microsoft.WinGet.Client.Common\n{\n    /// <summary>\n    /// This class contains all of the configurable constants for this project.\n    /// </summary>\n    internal static class Constants\n    {\n        /// <summary>\n        /// If a command allows the specification of the maximum number of results to return, this is the lower bound for that value.\n        /// </summary>\n        public const uint CountLowerBound = 1;\n\n        /// <summary>\n        /// If a command allows the specification of the maximum number of results to return, this is the upper bound for that value.\n        /// </summary>\n        public const uint CountUpperBound = 1000;\n\n        /// <summary>\n        /// This parameter set indicates that a package was provided via a parameter or the pipeline and it can be acted on directly.\n        /// </summary>\n        public const string GivenSet = \"GivenSet\";\n\n        /// <summary>\n        /// This parameter set indicates that a package was not provided via a parameter or the pipeline and it\n        /// needs to be found by searching a package source.\n        /// </summary>\n        public const string FoundSet = \"FoundSet\";\r\n\r\n        /// <summary>\r\n        /// This parameter set indicates the default parameters associated with a cmdlet.\r\n        /// </summary>\r\n        public const string DefaultSet = \"DefaultSet\";\r\n\r\n        /// <summary>\r\n        ///  This parameter set indicates the optional parameters associated with a cmdlet.\r\n        /// </summary>\r\n        public const string OptionalSet = \"OptionalSet\";\n\n        /// <summary>\n        /// Parameter set for an specific version parameter.\n        /// </summary>\n        public const string IntegrityVersionSet = \"IntegrityVersionSet\";\n\n        /// <summary>\n        /// Parameter set for an latest version with optional prerelease version.\n        /// </summary>\n        public const string IntegrityLatestSet = \"IntegrityLatestSet\";\n\n        /// <summary>\n        /// Nouns used for different cmdlets. Changing this will alter the names of the related commands.\n        /// </summary>\n        public static class WinGetNouns\n        {\n            /// <summary>\n            /// WinGet.\n            /// </summary>\n            public const string WinGetPackageManager = \"WinGetPackageManager\";\n\n            /// <summary>\n            /// WinGetPackage.\n            /// </summary>\n            public const string Package = \"WinGetPackage\";\n\n            /// <summary>\n            /// WinGetSource.\n            /// </summary>\n            public const string Source = \"WinGetSource\";\n\n            /// <summary>\n            /// The noun for any user settings cmdlet.\n            /// </summary>\n            public const string UserSetting = \"WinGetUserSetting\";\n\n            /// <summary>\n            /// The noun for winget version.\n            /// </summary>\n            public const string Version = \"WinGetVersion\";\n\n            /// <summary>\n            /// The noun for enable/disable winget admin settings.\n            /// </summary>\n            public const string Setting = \"WinGetSetting\";\n        }\n    }\n}\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Microsoft.WinGet.Client.Cmdlets.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <!-- If these target frameworks are updated, make sure to also update the .psd1 and .nuspec files.-->\r\n    <!-- Keep in sync with attributes in AssemblyInfo.cs -->\r\n    <CoreFramework>net8.0-windows10.0.26100.0</CoreFramework>\r\n    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>\r\n    <DesktopFramework>net48</DesktopFramework>\r\n    <Configurations>Debug;Release;ReleaseStatic</Configurations>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup>\r\n    <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>\r\n    <LangVersion>10</LangVersion>\r\n    <BuildOutputDirectory>$(SolutionDir)$(Platform)\\$(Configuration)\\</BuildOutputDirectory>\r\n    <OutputPath>$(BuildOutputDirectory)$(MSBuildProjectName)</OutputPath>\r\n    <TargetFrameworks>$(CoreFramework);$(DesktopFramework)</TargetFrameworks>\r\n    <DocumentationFile>$(OutputPath)\\Microsoft.WinGet.Client.Cmdlets.xml</DocumentationFile>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <AdditionalFiles Include=\"..\\..\\stylecop.json\" Link=\"stylecop.json\" />\r\n  </ItemGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Release'\">\r\n    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='ReleaseStatic'\">\r\n    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <Compile Include=\"..\\CommonFiles\\WinGetAssemblyLoadContext.cs\" Link=\"WinGetAssemblyLoadContext.cs\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <PackageReference Include=\"Newtonsoft.Json\" />\r\n    <PackageReference Include=\"PowerShellStandard.Library\" PrivateAssets=\"all\" />\r\n    <PackageReference Include=\"StyleCop.Analyzers\">\r\n      <PrivateAssets>all</PrivateAssets>\r\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\r\n    </PackageReference>\r\n  </ItemGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(TargetFramework)' == '$(DesktopFramework)'\">\r\n    <DefineConstants>POWERSHELL_WINDOWS</DefineConstants>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(TargetFramework)' == '$(CoreFramework)'\">\r\n    <RuntimeIdentifier>win</RuntimeIdentifier>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\Microsoft.WinGet.Client.Engine\\Microsoft.WinGet.Client.Engine.csproj\" />\r\n  </ItemGroup>\r\n\r\n  <Import Project=\"..\\..\\targets\\ReferenceEmbeddedCsWinRTProject.targets\" Condition=\"'$(TargetFramework)' == '$(CoreFramework)'\" />\r\n\r\n  <!-- This project doesn't reference CSWinRT, but specify this everywhere it will fail with NETSDK1130 and MSB3271. -->\r\n  <PropertyGroup>\r\n    <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>\r\n  </PropertyGroup>\r\n\r\n  <!-- Build PowerShell Module -->\r\n  <PropertyGroup>\r\n    <PowerShellModuleOutputDirectory>$(BuildOutputDirectory)PowerShell\\Microsoft.WinGet.Client</PowerShellModuleOutputDirectory>\r\n    <PowerShellModuleRuntimesDir>$(PowerShellModuleOutputDirectory)\\$(TargetFramework)</PowerShellModuleRuntimesDir>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup>\r\n    <PowerShellModuleSharedDependencies>$(PowerShellModuleRuntimesDir)\\SharedDependencies</PowerShellModuleSharedDependencies>\r\n    <PowerShellModuleDirectDependencies>$(PowerShellModuleRuntimesDir)\\DirectDependencies</PowerShellModuleDirectDependencies>\r\n  </PropertyGroup>\r\n\r\n  <!-- psd1 and ps1xml-->\r\n  <Target Name=\"CopyModuleFiles\" AfterTargets=\"AfterBuild\">\r\n    <ItemGroup>\r\n      <ModuleFiles Include=\"$(ProjectDir)\\..\\Microsoft.WinGet.Client\\ModuleFiles\\**\\*.*\" />\r\n    </ItemGroup>\r\n    <Message Importance=\"high\" Text=\"Copying PowerShell module files to '$(PowerShellModuleOutputDirectory)'\" />\r\n    <Copy SourceFiles=\"@(ModuleFiles)\" DestinationFiles=\"$(PowerShellModuleOutputDirectory)\\%(RecursiveDir)%(Filename)%(Extension)\" />\r\n  </Target>\r\n\r\n  <!-- Main binaries -->\r\n  <Target Name=\"CopyWinGetBinaries\" AfterTargets=\"AfterBuild\">\r\n    <ItemGroup>\r\n      <ModuleWinGetFile Include=\"$(OutputPath)Microsoft.WinGet.Client.Cmdlets.dll\" />\r\n      <ModuleWinGetFile Include=\"$(OutputPath)Microsoft.WinGet.Client.Cmdlets.pdb\" Condition=\"'$(Configuration)' == 'Debug'\" />\r\n    </ItemGroup>\r\n    <Message Importance=\"high\" Text=\"Copying CopyWinGetBinaries: '@(ModuleWinGetFile)'\" />\r\n    <Copy SourceFiles=\"@(ModuleWinGetFile)\" DestinationFolder=\"$(PowerShellModuleRuntimesDir)\" />\r\n  </Target>\r\n\r\n  <!-- Direct dependencies -->\r\n  <Target Name=\"CopyDirectDependencies\" AfterTargets=\"AfterBuild\">\r\n    <ItemGroup>\r\n      <ModuleDirectDependency Include=\"$(OutputPath)Microsoft.WinGet.Client.Engine.dll\" />\r\n      <ModuleDirectDependency Include=\"$(OutputPath)Microsoft.WinGet.Client.Engine.pdb\" Condition=\"'$(Configuration)' == 'Debug'\" />\r\n    </ItemGroup>\r\n    <Message Importance=\"high\" Text=\"Copying direct dependencies: '@(ModuleDirectDependency)'\" />\r\n    <Copy SourceFiles=\"@(ModuleDirectDependency)\" DestinationFolder=\"$(PowerShellModuleDirectDependencies)\" />\r\n  </Target>\r\n\r\n  <!-- Shared managed dependencies -->\r\n  <Target Name=\"CopyManagedDependencies\" AfterTargets=\"AfterBuild\">\r\n    <ItemGroup>\r\n      <ManagedDependency Include=\"$(OutputPath)Newtonsoft.Json.dll\" />\r\n      <ManagedDependency Include=\"$(OutputPath)Octokit.dll\" />\r\n      <ManagedDependency Include=\"$(OutputPath)Microsoft.WinGet.SharedLib.dll\" />\r\n      <ManagedDependency Include=\"$(OutputPath)Microsoft.Win32.Registry.dll\" Condition=\"'$(TargetFramework)' == '$(DesktopFramework)'\" />\r\n      <ManagedDependency Include=\"$(OutputPath)Semver.dll\" />\r\n    </ItemGroup>\r\n    <Message Importance=\"high\" Text=\"Copying managed shared dependencies: '@(ManagedDependency)'\" />\r\n    <Copy SourceFiles=\"@(ManagedDependency)\" DestinationFolder=\"$(PowerShellModuleSharedDependencies)\" />\r\n  </Target>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Properties/AssemblyInfo.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"AssemblyInfo.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\n#if NET\r\n\r\nusing System.Runtime.Versioning;\r\n\r\n// Forcibly set the target and supported platforms due to the internal build setup.\r\n// Keep in sync with project versions.\r\n[assembly: TargetPlatform(\"Windows10.0.26100.0\")]\r\n[assembly: SupportedOSPlatform(\"Windows10.0.18362.0\")]\r\n\r\n#endif\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Resolver/ModuleInit.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ModuleInit.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Resolver\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.Linq;\r\n    using System.Management.Automation;\r\n    using System.Runtime.InteropServices;\r\n\r\n#if !POWERSHELL_WINDOWS\r\n    using System.Runtime.Loader;\r\n#else\r\n    using Microsoft.WinGet.Client.Cmdlets.Resolver;\r\n#endif\r\n\r\n    /// <summary>\r\n    /// Initialization class for this module.\r\n    /// </summary>\r\n    public class ModuleInit : IModuleAssemblyInitializer, IModuleAssemblyCleanup\r\n    {\r\n        private static readonly IEnumerable<Architecture> ValidArchs = new Architecture[] { Architecture.X86, Architecture.X64, Architecture.Arm64 };\r\n\r\n        /// <inheritdoc/>\r\n        public void OnImport()\r\n        {\r\n            var arch = RuntimeInformation.ProcessArchitecture;\r\n            if (!ValidArchs.Contains(arch))\r\n            {\r\n                throw new NotSupportedException(arch.ToString());\r\n            }\r\n\r\n#if !POWERSHELL_WINDOWS\r\n            AssemblyLoadContext.Default.Resolving += WinGetAssemblyLoadContext.ResolvingHandler;\r\n#else\r\n            // If we really need to avoid dependency conflicts, we could create a custom domain and handle the serialization boundaries.\r\n            // PowerShell doesn't recommended because its complications.\r\n            AppDomain currentDomain = AppDomain.CurrentDomain;\r\n            currentDomain.AssemblyResolve += WinGetAppDomain.Handler;\r\n#endif\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public void OnRemove(PSModuleInfo module)\r\n        {\r\n#if !POWERSHELL_WINDOWS\r\n            AssemblyLoadContext.Default.Resolving -= WinGetAssemblyLoadContext.ResolvingHandler;\r\n#else\r\n            AppDomain currentDomain = AppDomain.CurrentDomain;\r\n            currentDomain.AssemblyResolve -= WinGetAppDomain.Handler;\r\n#endif\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Resolver/WinGetAppDomain.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"WinGetAppDomain.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n#if POWERSHELL_WINDOWS\r\n\r\nnamespace Microsoft.WinGet.Client.Cmdlets.Resolver\r\n{\r\n    using System;\r\n    using System.IO;\r\n    using System.Reflection;\r\n    using System.Runtime.InteropServices;\r\n\r\n    /// <summary>\r\n    /// Resolver for assemblies.\r\n    /// </summary>\r\n    internal static class WinGetAppDomain\r\n    {\r\n        private static readonly string SharedDependencyPath;\r\n        private static readonly string SharedArchDependencyPath;\r\n        private static readonly string DirectDependencyPath;\r\n\r\n        static WinGetAppDomain()\r\n        {\r\n            var self = typeof(WinGetAppDomain).Assembly;\r\n            SharedDependencyPath = Path.Combine(\r\n                Path.GetDirectoryName(self.Location),\r\n                \"SharedDependencies\");\r\n            SharedArchDependencyPath = Path.Combine(\r\n                SharedDependencyPath,\r\n                RuntimeInformation.ProcessArchitecture.ToString().ToLower());\r\n            DirectDependencyPath = Path.Combine(\r\n                Path.GetDirectoryName(self.Location),\r\n                \"DirectDependencies\");\r\n        }\r\n\r\n        /// <summary>\r\n        /// Handler to register in the AppDomain.\r\n        /// </summary>\r\n        /// <param name=\"source\">Source.</param>\r\n        /// <param name=\"args\">Event args.</param>\r\n        /// <returns>The assembly if found.</returns>\r\n        public static Assembly Handler(object source, ResolveEventArgs args)\r\n        {\r\n            string name = $\"{new AssemblyName(args.Name).Name}.dll\";\r\n            string path = Path.Combine(SharedDependencyPath, name);\r\n            if (File.Exists(path))\r\n            {\r\n                return Assembly.LoadFile(path);\r\n            }\r\n\r\n            path = Path.Combine(SharedArchDependencyPath, name);\r\n            if (File.Exists(path))\r\n            {\r\n                return Assembly.LoadFile(path);\r\n            }\r\n\r\n            path = Path.Combine(DirectDependencyPath, name);\r\n            if (File.Exists(path))\r\n            {\r\n                return Assembly.LoadFile(path);\r\n            }\r\n\r\n            return null;\r\n        }\r\n    }\r\n}\r\n#endif\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Attributes/FilterAttribute.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"FilterAttribute.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Attributes\r\n{\r\n    using System;\r\n    using Microsoft.Management.Deployment;\r\n\r\n    /// <summary>\r\n    /// A <see cref=\"FindPackagesOptions\" /> is constructed by introspecting on the inheritance tree and\r\n    /// looking for parameters that are marked with this attribute. Properties that are marked with this\r\n    /// attribute are added to the <see cref=\"FindPackagesOptions\" /> object.\r\n    /// </summary>\r\n    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]\r\n    internal class FilterAttribute : Attribute\r\n    {\r\n        /// <summary>\r\n        /// Gets or sets the field that the filter will be matching against.\r\n        /// </summary>\r\n        public PackageMatchField Field { get; set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Commands/CliCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"CliCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Commands\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Engine.Commands.Common;\r\n    using Microsoft.WinGet.Client.Engine.Common;\r\n    using Microsoft.WinGet.Client.Engine.Helpers;\r\n    using Microsoft.WinGet.Common.Command;\r\n\r\n    /// <summary>\r\n    /// Commands that just calls winget.exe underneath.\r\n    /// </summary>\r\n    public sealed class CliCommand : BaseCommand\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"CliCommand\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"psCmdlet\">PSCmdlet.</param>\r\n        public CliCommand(PSCmdlet psCmdlet)\r\n            : base(psCmdlet)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Enables admin setting.\r\n        /// </summary>\r\n        /// <param name=\"name\">Setting name.</param>\r\n        public void EnableSetting(string name)\r\n        {\r\n            Utilities.VerifyAdmin();\r\n            _ = this.Run(new WinGetCLICommandBuilder(\"settings\").AppendOption(\"enable\", name));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Disables admin setting.\r\n        /// </summary>\r\n        /// <param name=\"name\">Setting name.</param>\r\n        public void DisableSetting(string name)\r\n        {\r\n            Utilities.VerifyAdmin();\r\n            _ = this.Run(new WinGetCLICommandBuilder(\"settings\").AppendOption(\"disable\", name));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets winget settings.\r\n        /// </summary>\r\n        /// <param name=\"asPlainText\">Return as string.</param>\r\n        public void GetSettings(bool asPlainText)\r\n        {\r\n            var result = this.Run(new WinGetCLICommandBuilder(\"settings\").AppendSubCommand(\"export\"));\r\n\r\n            if (asPlainText)\r\n            {\r\n                this.Write(StreamType.Object, result.StdOut);\r\n            }\r\n            else\r\n            {\r\n                this.Write(StreamType.Object, Utilities.ConvertToHashtable(result.StdOut));\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Adds source.\r\n        /// </summary>\r\n        /// <param name=\"name\">Name of source.</param>\r\n        /// <param name=\"arg\">Arg of source.</param>\r\n        /// <param name=\"type\">Type of source.</param>\r\n        /// <param name=\"trustLevel\">Trust level of source.</param>\r\n        /// <param name=\"isExplicit\">Make source explicit.</param>\r\n        /// <param name=\"priority\">Set the priority if the source.</param>\r\n        public void AddSource(string name, string arg, string type, string trustLevel, bool isExplicit, int priority)\r\n        {\r\n            Utilities.VerifyAdmin();\r\n            var builder = new WinGetCLICommandBuilder(\"source\")\r\n                .AppendSubCommand(\"add\")\r\n                .AppendOption(\"name\", name)\r\n                .AppendOption(\"arg\", arg);\r\n\r\n            if (!string.IsNullOrEmpty(type))\r\n            {\r\n                builder.AppendOption(\"type\", type);\r\n            }\r\n\r\n            if (!string.IsNullOrEmpty(trustLevel))\r\n            {\r\n                builder.AppendOption(\"trust-level\", trustLevel);\r\n            }\r\n\r\n            if (isExplicit)\r\n            {\r\n                builder.AppendSwitch(\"explicit\");\r\n            }\r\n\r\n            if (priority != 0)\r\n            {\r\n                builder.AppendOption(\"priority\", priority.ToString());\r\n            }\r\n\r\n            _ = this.Run(builder, 300000);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Removes source.\r\n        /// </summary>\r\n        /// <param name=\"name\">Name of source.</param>\r\n        public void RemoveSource(string name)\r\n        {\r\n            Utilities.VerifyAdmin();\r\n            _ = this.Run(new WinGetCLICommandBuilder(\"source\").AppendSubCommand(\"remove\").AppendOption(\"name\", name));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Resets a source.\r\n        /// </summary>\r\n        /// <param name=\"name\">Name of source.</param>\r\n        public void ResetSourceByName(string name)\r\n        {\r\n            Utilities.VerifyAdmin();\r\n            _ = this.Run(new WinGetCLICommandBuilder(\"source\").AppendSubCommand(\"reset\").AppendOption(\"name\", name).AppendSwitch(\"force\"));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Resets all sources and adds the defaults.\r\n        /// </summary>\r\n        public void ResetAllSources()\r\n        {\r\n            Utilities.VerifyAdmin();\r\n            _ = this.Run(new WinGetCLICommandBuilder(\"source\").AppendSubCommand(\"reset\").AppendSwitch(\"force\"));\r\n        }\r\n\r\n        private WinGetCLICommandResult Run(WinGetCLICommandBuilder builder, int timeOut = 60000)\r\n        {\r\n            var wingetCliWrapper = new WingetCLIWrapper();\r\n            var result = wingetCliWrapper.RunCommand(this, builder, timeOut);\r\n            result.VerifyExitCode();\r\n\r\n            return result;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Commands/Common/BaseCommand.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"BaseCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Commands.Common\r\n{\r\n    using System.Collections.Generic;\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Common.Command;\r\n    using Microsoft.WinGet.SharedLib.PolicySettings;\r\n\r\n    /// <summary>\r\n    /// Base class for all Cmdlets.\r\n    /// </summary>\r\n    public abstract class BaseCommand : PowerShellCmdlet\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"BaseCommand\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"psCmdlet\">PSCmdlet.</param>\r\n        internal BaseCommand(PSCmdlet psCmdlet)\r\n            : base(psCmdlet, new HashSet<Policy> { Policy.WinGet, Policy.WinGetCommandLineInterfaces })\r\n        {\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Commands/Common/FinderCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"FinderCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Commands.Common\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.Linq;\r\n    using System.Management.Automation;\r\n    using System.Reflection;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.WinGet.Client.Engine.Attributes;\r\n    using Microsoft.WinGet.Client.Engine.Exceptions;\r\n    using Microsoft.WinGet.Client.Engine.Helpers;\r\n\r\n    /// <summary>\r\n    /// This is the base class for all commands that might need to search for a package. It contains an initial\r\n    /// set of parameters that corresponds to the intersection of i.e., the \"install\" and \"search\" commands.\r\n    /// </summary>\r\n    public abstract class FinderCommand : ManagementDeploymentCommand\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"FinderCommand\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"psCmdlet\">PSCmdlet.</param>\r\n        internal FinderCommand(PSCmdlet psCmdlet)\r\n            : base(psCmdlet)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the field that is matched against the identifier of a package.\r\n        /// </summary>\r\n        [Filter(Field = PackageMatchField.Id)]\r\n        protected string? Id { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the field that is matched against the name of a package.\r\n        /// </summary>\r\n        [Filter(Field = PackageMatchField.Name)]\r\n        protected string? Name { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the field that is matched against the moniker of a package.\r\n        /// </summary>\r\n        [Filter(Field = PackageMatchField.Moniker)]\r\n        protected string? Moniker { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the name of the source to search for packages. If null, then all sources are searched.\r\n        /// </summary>\r\n        protected string? Source { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets how to match against package fields.\r\n        /// </summary>\r\n#pragma warning disable SA1011 // Closing square brackets should be spaced correctly\r\n        protected string[]? Query { get; set; }\r\n#pragma warning restore SA1011 // Closing square brackets should be spaced correctly\r\n\r\n        private string? QueryAsJoinedString\r\n        {\r\n            get\r\n            {\r\n                return this.Query is null\r\n                    ? null\r\n                    : string.Join(\" \", this.Query);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Searches for packages based on the configured parameters.\r\n        /// </summary>\r\n        /// <param name=\"behavior\">The <see cref=\"CompositeSearchBehavior\" /> value.</param>\r\n        /// <param name=\"limit\">The limit on the number of matches returned.</param>\r\n        /// <param name=\"match\">The match option.</param>\r\n        /// <returns>A list of <see cref=\"MatchResult\" /> objects.</returns>\r\n        internal IReadOnlyList<MatchResult> FindPackages(\r\n            CompositeSearchBehavior behavior,\r\n            uint limit,\r\n            PackageFieldMatchOption match)\r\n        {\r\n            PackageCatalog catalog = this.GetPackageCatalog(behavior);\r\n            FindPackagesOptions options = this.GetFindPackagesOptions(limit, match);\r\n            return this.GetMatchResults(catalog, options);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Sets the find package options for a query input.\r\n        /// DO NOT pass PackageFieldMatchOption WinRT enum type in this method.\r\n        /// That will cause the type to attempt to be loaded in the construction\r\n        /// of this method and throw a different exception for Windows PowerShell.\r\n        /// </summary>\r\n        /// <param name=\"options\">The options object.</param>\r\n        /// <param name=\"match\">The match type as string.</param>\r\n        /// <param name=\"value\">The query value.</param>\r\n        internal virtual void SetQueryInFindPackagesOptions(\r\n            ref FindPackagesOptions options,\r\n            string match,\r\n            string? value)\r\n        {\r\n            var selector = ManagementDeploymentFactory.Instance.CreatePackageMatchFilter();\r\n            selector.Field = PackageMatchField.CatalogDefault;\r\n            selector.Value = value ?? string.Empty;\r\n            selector.Option = PSEnumHelpers.ToPackageFieldMatchOption(match);\r\n            options.Selectors.Add(selector);\r\n        }\r\n\r\n        private void AddFilterToFindPackagesOptionsIfNotNull(\r\n            ref FindPackagesOptions options,\r\n            PackageMatchField field,\r\n            PackageFieldMatchOption match,\r\n            string? value)\r\n        {\r\n            if (value != null)\r\n            {\r\n                var filter = ManagementDeploymentFactory.Instance.CreatePackageMatchFilter();\r\n                filter.Field = field;\r\n                filter.Value = value;\r\n                filter.Option = match;\r\n                options.Filters.Add(filter);\r\n            }\r\n        }\r\n\r\n        private IReadOnlyList<MatchResult> GetMatchResults(\r\n            PackageCatalog catalog,\r\n            FindPackagesOptions options)\r\n        {\r\n            FindPackagesResult result = catalog.FindPackages(options);\r\n            if (result.Status == FindPackagesResultStatus.Ok)\r\n            {\r\n                return result.Matches;\r\n            }\r\n            else\r\n            {\r\n                throw new FindPackagesException(result.Status);\r\n            }\r\n        }\r\n\r\n        private PackageCatalog GetPackageCatalog(CompositeSearchBehavior behavior)\r\n        {\r\n            PackageCatalogReference reference = this.GetPackageCatalogReference(behavior);\r\n            ConnectResult result = reference.Connect();\r\n            if (result.Status == ConnectResultStatus.Ok)\r\n            {\r\n                return result.PackageCatalog;\r\n            }\r\n            else\r\n            {\r\n                throw new CatalogConnectException(result.ExtendedErrorCode);\r\n            }\r\n        }\r\n\r\n        private PackageCatalogReference GetPackageCatalogReference(CompositeSearchBehavior behavior)\r\n        {\r\n            CreateCompositePackageCatalogOptions options = ManagementDeploymentFactory.Instance.CreateCreateCompositePackageCatalogOptions();\r\n            IReadOnlyList<PackageCatalogReference> references = this.GetPackageCatalogReferences(this.Source);\r\n            for (var i = 0; i < references.Count; i++)\r\n            {\r\n                var reference = references[i];\r\n                bool isExplicit = false;\r\n                try\r\n                {\r\n                    // Execute in try block to catch interface not implemented on older servers.\r\n                    isExplicit = reference.Info.Explicit;\r\n                }\r\n                catch\r\n                {\r\n                    // Assume that any failure other than the interface not implemented to get Explicit\r\n                    // will result in other failures shortly after this (like the server being gone).\r\n                }\r\n\r\n                if (!isExplicit)\r\n                {\r\n                    options.Catalogs.Add(reference);\r\n                }\r\n            }\r\n\r\n            options.CompositeSearchBehavior = behavior;\r\n            return PackageManagerWrapper.Instance.CreateCompositePackageCatalog(options);\r\n        }\r\n\r\n        private FindPackagesOptions GetFindPackagesOptions(uint limit, PackageFieldMatchOption match)\r\n        {\r\n            var options = ManagementDeploymentFactory.Instance.CreateFindPackagesOptions();\r\n            this.SetQueryInFindPackagesOptions(ref options, match.ToString(), this.QueryAsJoinedString);\r\n            this.AddAttributedFiltersToFindPackagesOptions(ref options, match);\r\n            options.ResultLimit = limit;\r\n            return options;\r\n        }\r\n\r\n        private void AddAttributedFiltersToFindPackagesOptions(\r\n            ref FindPackagesOptions options,\r\n            PackageFieldMatchOption match)\r\n        {\r\n            IEnumerable<PropertyInfo> properties = this.GetType()\r\n                .GetProperties(BindingFlags.NonPublic | BindingFlags.Instance)\r\n                .Where(property => Attribute.IsDefined(property, typeof(FilterAttribute)));\r\n\r\n            foreach (PropertyInfo info in properties)\r\n            {\r\n                if (info.GetCustomAttribute(typeof(FilterAttribute), true) is FilterAttribute attribute)\r\n                {\r\n                    PackageMatchField field = attribute.Field;\r\n                    string? value = info.GetValue(this, null) as string;\r\n                    this.AddFilterToFindPackagesOptionsIfNotNull(ref options, field, match, value);\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Commands/Common/FinderExtendedCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"FinderExtendedCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Commands.Common\r\n{\r\n    using System.Collections.Generic;\r\n    using System.Management.Automation;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.WinGet.Client.Engine.Attributes;\r\n\r\n    /// <summary>\r\n    /// This is the base class for the commands whose sole purpose is to filter a list of packages i.e.,\r\n    /// the \"search\" and \"list\" commands. This class contains an extended set of parameters suited for\r\n    /// that purpose.\r\n    /// </summary>\r\n    public abstract class FinderExtendedCommand : FinderCommand\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"FinderExtendedCommand\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"psCmdlet\">PSCmdlet.</param>\r\n        internal FinderExtendedCommand(PSCmdlet psCmdlet)\r\n            : base(psCmdlet)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the filter that is matched against the tags of the package.\r\n        /// </summary>\r\n        [Filter(Field = PackageMatchField.Tag)]\r\n        protected string? Tag { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the filter that is matched against the commands of the package.\r\n        /// </summary>\r\n        [Filter(Field = PackageMatchField.Command)]\r\n        protected string? Command { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the maximum number of results returned.\r\n        /// </summary>\r\n        protected uint Count { get; set; }\r\n\r\n        /// <summary>\r\n        /// Searches for packages from configured sources.\r\n        /// </summary>\r\n        /// <param name=\"behavior\">A <see cref=\"CompositeSearchBehavior\" /> value.</param>\r\n        /// <param name=\"match\">The match option.</param>\r\n        /// <returns>A list of <see cref=\"MatchResult\" /> objects.</returns>\r\n        internal IReadOnlyList<MatchResult> FindPackages(CompositeSearchBehavior behavior, PackageFieldMatchOption match)\r\n        {\r\n            return this.FindPackages(behavior, this.Count, match);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Commands/Common/InstallCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"InstallCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Commands.Common\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.WinGet.Client.Engine.Helpers;\r\n\r\n    /// <summary>\r\n    /// This is the base class for all commands that parse a <see cref=\"FindPackagesOptions\" /> result\r\n    /// from the provided parameters i.e., the \"install\" and \"upgrade\" commands.\r\n    /// </summary>\r\n    public abstract class InstallCommand : PackageCommand\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"InstallCommand\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"psCmdlet\">PSCmdlet.</param>\r\n        internal InstallCommand(PSCmdlet psCmdlet)\r\n            : base(psCmdlet)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether to skip the installer hash validation check.\r\n        /// </summary>\r\n        protected bool AllowHashMismatch { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether to skip dependencies.\r\n        /// </summary>\r\n        protected bool SkipDependencies { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the override arguments to be passed on to the installer.\r\n        /// </summary>\r\n        protected string? Override { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the arguments to be passed on to the installer in addition to the defaults.\r\n        /// </summary>\r\n        protected string? Custom { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the installation location.\r\n        /// </summary>\r\n        protected string? Location { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the path to the logging file.\r\n        /// </summary>\r\n        protected string? Log { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether to continue upon non security related failures.\r\n        /// </summary>\r\n        protected bool Force { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the optional HTTP Header to pass on to the REST Source.\r\n        /// </summary>\r\n        protected string? Header { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets the install options from the configured parameters.\r\n        /// DO NOT pass PackageInstallMode WinRT enum type in this method.\r\n        /// That will cause the type to attempt to be loaded in the construction\r\n        /// of this method and throw a different exception for Windows PowerShell.\r\n        /// </summary>\r\n        /// <param name=\"version\">The <see cref=\"PackageVersionId\" /> to install.</param>\r\n        /// <param name=\"mode\">Package install mode as string.</param>\r\n        /// <returns>An <see cref=\"InstallOptions\" /> instance.</returns>\r\n        internal virtual InstallOptions GetInstallOptions(PackageVersionId? version, string mode)\r\n        {\r\n            InstallOptions options = ManagementDeploymentFactory.Instance.CreateInstallOptions();\r\n            options.AllowHashMismatch = this.AllowHashMismatch;\r\n            options.SkipDependencies = this.SkipDependencies;\r\n            options.Force = this.Force;\r\n            options.PackageInstallMode = PSEnumHelpers.ToPackageInstallMode(mode);\r\n            if (version != null)\r\n            {\r\n                options.PackageVersionId = version;\r\n            }\r\n\r\n            if (this.Log != null)\r\n            {\r\n                options.LogOutputPath = this.Log;\r\n            }\r\n\r\n            if (this.Override != null)\r\n            {\r\n                options.ReplacementInstallerArguments = this.Override;\r\n            }\r\n\r\n            // Since these arguments are appended to the installer at runtime, it doesn't make sense to append them if they are whitespace\r\n            if (!string.IsNullOrWhiteSpace(this.Custom))\r\n            {\r\n                options.AdditionalInstallerArguments = this.Custom;\r\n            }\r\n\r\n            if (this.Location != null)\r\n            {\r\n                options.PreferredInstallLocation = this.Location;\r\n            }\r\n\r\n            if (this.Header != null)\r\n            {\r\n                options.AdditionalPackageCatalogArguments = this.Header;\r\n            }\r\n\r\n            return options;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Commands/Common/ManagementDeploymentCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ManagementDeploymentCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Commands.Common\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.Management.Automation;\r\n    using System.Threading.Tasks;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.WinGet.Client.Engine.Common;\r\n    using Microsoft.WinGet.Client.Engine.Exceptions;\r\n    using Microsoft.WinGet.Client.Engine.Helpers;\r\n\r\n    /// <summary>\r\n    /// This is the base class for all of the commands in this module that use the COM APIs.\r\n    /// </summary>\r\n    public abstract class ManagementDeploymentCommand : BaseCommand\r\n    {\r\n        static ManagementDeploymentCommand()\r\n        {\r\n            WinRTHelpers.Initialize();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"ManagementDeploymentCommand\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"psCmdlet\">psCmdlet.</param>\r\n        internal ManagementDeploymentCommand(PSCmdlet psCmdlet)\r\n            : base(psCmdlet)\r\n        {\r\n#if POWERSHELL_WINDOWS\r\n            if (Utilities.UsesInProcWinget)\r\n            {\r\n                throw new WindowsPowerShellNotSupported();\r\n            }\r\n#endif\r\n        }\r\n\r\n        /// <summary>\r\n        /// Retrieves the specified source or all sources if <paramref name=\"source\" /> is null.\r\n        /// </summary>\r\n        /// <returns>A list of <see cref=\"PackageCatalogReference\" /> instances.</returns>\r\n        /// <param name=\"source\">The name of the source to retrieve. If null, then all sources are returned.</param>\r\n        /// <exception cref=\"ArgumentException\">The source does not exist.</exception>\r\n        internal IReadOnlyList<PackageCatalogReference> GetPackageCatalogReferences(string? source)\r\n        {\r\n            if (string.IsNullOrEmpty(source))\r\n            {\r\n                return PackageManagerWrapper.Instance.GetPackageCatalogs();\r\n            }\r\n            else\r\n            {\r\n                return new List<PackageCatalogReference>()\r\n                {\r\n                    PackageManagerWrapper.Instance.GetPackageCatalogByName(source!)\r\n                        ?? throw new InvalidSourceException(source!),\r\n                };\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Executes the cmdlet. All cmdlets that uses the COM APIs and don't call async functions MUST use this method.\r\n        /// The inproc COM API may deadlock on an STA thread.\r\n        /// </summary>\r\n        /// <typeparam name=\"TResult\">The type of result of the cmdlet.</typeparam>\r\n        /// <param name=\"func\">Cmdlet function.</param>\r\n        /// <returns>The result of the cmdlet.</returns>\r\n        protected TResult Execute<TResult>(Func<TResult> func)\r\n        {\r\n            if (Utilities.UsesInProcWinget)\r\n            {\r\n                return this.RunOnMTA(func);\r\n            }\r\n\r\n            return func();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Executes the cmdlet in a different thread and waits for results.\r\n        /// </summary>\r\n        /// <typeparam name=\"TResult\">The type of result of the cmdlet.</typeparam>\r\n        /// <param name=\"func\">Cmdlet function.</param>\r\n        /// <returns>The result of the cmdlet.</returns>\r\n        protected TResult Execute<TResult>(Func<Task<TResult>> func)\r\n        {\r\n            var runningTask = this.RunOnMTA(\r\n                async () =>\r\n                {\r\n                    return await func();\r\n                });\r\n\r\n            this.Wait(runningTask);\r\n            return runningTask.Result;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Commands/Common/PackageCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"PackageCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Commands.Common\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.Management.Automation;\r\n    using System.Threading.Tasks;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.WinGet.Client.Engine.Exceptions;\r\n    using Microsoft.WinGet.Client.Engine.Extensions;\r\n    using Microsoft.WinGet.Client.Engine.Helpers;\r\n    using Microsoft.WinGet.Client.Engine.PSObjects;\r\n\r\n    /// <summary>\r\n    /// This is the base class for commands which operate on a specific package and version i.e.,\r\n    /// the \"install\", \"uninstall\", \"download\", and \"upgrade\" commands.\r\n    /// </summary>\r\n    public abstract class PackageCommand : FinderCommand\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"PackageCommand\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"psCmdlet\">PSCmdlet.</param>\r\n        internal PackageCommand(PSCmdlet psCmdlet)\r\n            : base(psCmdlet)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the package to directly install.\r\n        /// </summary>\r\n        /// <remarks>\r\n        /// Must match the name of the <see cref=\"CatalogPackage\" /> field on the <see cref=\"MatchResult\" /> class.\r\n        /// </remarks>\r\n        protected PSCatalogPackage? CatalogPackage { get; set; } = null;\r\n\r\n        /// <summary>\r\n        /// Gets or sets the version to install.\r\n        /// </summary>\r\n        protected string? Version { get; set; }\r\n\r\n        /// <summary>\r\n        /// Executes a command targeting a specific package version.\r\n        /// </summary>\r\n        /// <typeparam name=\"TResult\">Type of callback's result.</typeparam>\r\n        /// <param name=\"behavior\">The <see cref=\"CompositeSearchBehavior\" /> value.</param>\r\n        /// <param name=\"match\">The match option.</param>\r\n        /// <param name=\"callback\">The method to call after retrieving the package and version to operate upon.</param>\r\n        /// <returns>Result of the callback.</returns>\r\n        internal async Task<Tuple<TResult, CatalogPackage>?> GetPackageAndExecuteAsync<TResult>(\r\n            CompositeSearchBehavior behavior,\r\n            PackageFieldMatchOption match,\r\n            Func<CatalogPackage, PackageVersionId?, Task<TResult>> callback)\r\n            where TResult : class\r\n        {\r\n            CatalogPackage package = this.GetCatalogPackage(behavior, match);\r\n            PackageVersionId? version = this.GetPackageVersionId(package);\r\n            if (this.ShouldProcess(package.ToString(version)))\r\n            {\r\n                var result = await callback(package, version);\r\n                return new Tuple<TResult, CatalogPackage>(result, package);\r\n            }\r\n\r\n            return null;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Sets the find package options for a query input that is looking for a specific package.\r\n        /// DO NOT pass PackageFieldMatchOption WinRT enum type in this method.\r\n        /// That will cause the type to attempt to be loaded in the construction\r\n        /// of this method and throw a different exception for Windows PowerShell.\r\n        /// </summary>\r\n        /// <param name=\"options\">The options object.</param>\r\n        /// <param name=\"match\">The match type.</param>\r\n        /// <param name=\"value\">The query value.</param>\r\n        internal override void SetQueryInFindPackagesOptions(\r\n            ref FindPackagesOptions options,\r\n            string match,\r\n            string? value)\r\n        {\r\n            var matchOption = PSEnumHelpers.ToPackageFieldMatchOption(match);\r\n            foreach (PackageMatchField field in new PackageMatchField[] { PackageMatchField.Id, PackageMatchField.Name, PackageMatchField.Moniker })\r\n            {\r\n                var selector = ManagementDeploymentFactory.Instance.CreatePackageMatchFilter();\r\n                selector.Field = field;\r\n                selector.Value = value ?? string.Empty;\r\n                selector.Option = matchOption;\r\n                options.Selectors.Add(selector);\r\n            }\r\n        }\r\n\r\n        private CatalogPackage GetCatalogPackage(CompositeSearchBehavior behavior, PackageFieldMatchOption match)\r\n        {\r\n            if (this.CatalogPackage != null)\r\n            {\r\n                // The package was already provided via a parameter or the pipeline.\r\n                return this.CatalogPackage.CatalogPackageCOM;\r\n            }\r\n            else\r\n            {\r\n                IReadOnlyList<MatchResult> results = this.FindPackages(behavior, 0, match);\r\n                if (results.Count == 1)\r\n                {\r\n                    // Exactly one package matched, so we can just return it.\r\n                    return results[0].CatalogPackage;\r\n                }\r\n                else if (results.Count == 0)\r\n                {\r\n                    // No packages matched, we need to throw an error.\r\n                    throw new NoPackageFoundException();\r\n                }\r\n                else\r\n                {\r\n                    if (behavior != CompositeSearchBehavior.LocalCatalogs)\r\n                    {\r\n                        List<MatchResult> highestPriorityResults = new List<MatchResult>();\r\n                        int? highestPriority = null;\r\n\r\n                        for (int i = 0; i < results.Count; i++)\r\n                        {\r\n                            MatchResult result = results[i];\r\n                            int? priority = result.CatalogPackage.CatalogPriority;\r\n\r\n                            if ((highestPriority == null && priority != null) || highestPriority < priority)\r\n                            {\r\n                                // Current priority is higher; reset.\r\n                                highestPriority = priority;\r\n                                highestPriorityResults.Clear();\r\n                            }\r\n                            else if (highestPriority == priority)\r\n                            {\r\n                                // Priority is equal, add to the list.\r\n                            }\r\n                            else\r\n                            {\r\n                                // Current priority is lower, ignore the match.\r\n                                continue;\r\n                            }\r\n\r\n                            highestPriorityResults.Add(result);\r\n                        }\r\n\r\n                        if (highestPriorityResults.Count == 1)\r\n                        {\r\n                            return highestPriorityResults[0].CatalogPackage;\r\n                        }\r\n                        else\r\n                        {\r\n                            throw new VagueCriteriaException(highestPriorityResults);\r\n                        }\r\n                    }\r\n\r\n                    // Too many packages matched! The user needs to refine their input.\r\n                    throw new VagueCriteriaException(results);\r\n                }\r\n            }\r\n        }\r\n\r\n        private PackageVersionId? GetPackageVersionId(CatalogPackage package)\r\n        {\r\n            if (this.Version != null)\r\n            {\r\n                for (var i = 0; i < package.AvailableVersions.Count; i++)\r\n                {\r\n                    PackageVersionInfo versionInfo = package.GetPackageVersionInfo(package.AvailableVersions[i]);\r\n\r\n                    if (versionInfo != null && versionInfo.CompareToVersion(this.Version) == CompareResult.Equal)\r\n                    {\r\n                        return package.AvailableVersions[i];\r\n                    }\r\n                }\r\n\r\n                throw new InvalidVersionException(this.Version);\r\n            }\r\n            else\r\n            {\r\n                return null;\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Commands/DownloadCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"DownloadCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Commands\r\n{\r\n    using System.Management.Automation;\r\n    using System.Threading.Tasks;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.WinGet.Client.Engine.Commands.Common;\r\n    using Microsoft.WinGet.Client.Engine.Helpers;\r\n    using Microsoft.WinGet.Client.Engine.PSObjects;\r\n    using Microsoft.WinGet.Common.Command;\r\n    using Microsoft.WinGet.Resources;\r\n\r\n    /// <summary>\r\n    /// Downloads a package installer.\r\n    /// </summary>\r\n    public sealed class DownloadCommand : PackageCommand\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"DownloadCommand\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"psCmdlet\">Caller cmdlet.</param>\r\n        /// <param name=\"psCatalogPackage\">PSCatalogPackage.</param>\r\n        /// <param name=\"version\">Version to install.</param>\r\n        /// <param name=\"id\">Package identifier.</param>\r\n        /// <param name=\"name\">Name of package.</param>\r\n        /// <param name=\"moniker\">Moniker of package.</param>\r\n        /// <param name=\"source\">Source to search. If null, all are searched.</param>\r\n        /// <param name=\"query\">Match against any field of a package.</param>\r\n        /// <param name=\"allowHashMismatch\">To skip the installer hash validation check.</param>\r\n        /// <param name=\"skipDependencies\">To skip package dependencies.</param>\r\n        /// <param name=\"locale\">Locale of the package.</param>\r\n        public DownloadCommand(\r\n            PSCmdlet psCmdlet,\r\n            PSCatalogPackage psCatalogPackage,\r\n            string version,\r\n            string id,\r\n            string name,\r\n            string moniker,\r\n            string source,\r\n            string[] query,\r\n            bool allowHashMismatch,\r\n            bool skipDependencies,\r\n            string locale)\r\n            : base(psCmdlet)\r\n        {\r\n            // PackageCommand\r\n            if (psCatalogPackage != null)\r\n            {\r\n                this.CatalogPackage = psCatalogPackage;\r\n            }\r\n\r\n            this.Version = version;\r\n\r\n            // FinderCommand\r\n            this.Id = id;\r\n            this.Name = name;\r\n            this.Moniker = moniker;\r\n            this.Source = source;\r\n            this.Query = query;\r\n\r\n            // DownloadCommand\r\n            this.AllowHashMismatch = allowHashMismatch;\r\n            this.SkipDependencies = skipDependencies;\r\n            this.Locale = locale;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether to skip the installer hash validation check.\r\n        /// </summary>\r\n        private bool AllowHashMismatch { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether to skip dependencies.\r\n        /// </summary>\r\n        private bool SkipDependencies { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the locale to install.\r\n        /// </summary>\r\n        private string? Locale { get; set; }\r\n\r\n        /// <summary>\r\n        /// Process download package.\r\n        /// </summary>\r\n        /// <param name=\"downloadDirectory\">The target directory where the installer will be downloaded to.</param>\r\n        /// <param name=\"psPackageFieldMatchOption\">PSPackageFieldMatchOption.</param>\r\n        /// <param name=\"psPackageInstallScope\">PSPackageInstallScope.</param>\r\n        /// <param name=\"psProcessorArchitecture\">PSProcessorArchitecture.</param>\r\n        /// <param name=\"psPackageInstallerType\">PSPackageInstallerType.</param>\r\n        /// <param name=\"skipMicrosoftStoreLicense\">If true, skips downloading a Store license.</param>\r\n        /// <param name=\"psWindowsPlatform\">The platform to download the package for.</param>\r\n        /// <param name=\"targetOSVersion\">The target OS version to download for.</param>\r\n        public void Download(\r\n            string downloadDirectory,\r\n            string psPackageFieldMatchOption,\r\n            string psPackageInstallScope,\r\n            string psProcessorArchitecture,\r\n            string psPackageInstallerType,\r\n            bool skipMicrosoftStoreLicense,\r\n            string psWindowsPlatform,\r\n            string targetOSVersion)\r\n        {\r\n            var result = this.Execute(\r\n                async () => await this.GetPackageAndExecuteAsync(\r\n                    CompositeSearchBehavior.RemotePackagesFromRemoteCatalogs,\r\n                    PSEnumHelpers.ToPackageFieldMatchOption(psPackageFieldMatchOption),\r\n                    async (package, version) =>\r\n                    {\r\n                        DownloadOptions options = this.GetDownloadOptions(version);\r\n\r\n                        if (!string.IsNullOrEmpty(downloadDirectory))\r\n                        {\r\n                            options.DownloadDirectory = downloadDirectory;\r\n                        }\r\n\r\n                        if (!PSEnumHelpers.IsDefaultEnum(psProcessorArchitecture))\r\n                        {\r\n                            options.Architecture = PSEnumHelpers.ToProcessorArchitecture(psProcessorArchitecture);\r\n                        }\r\n\r\n                        if (!PSEnumHelpers.IsDefaultEnum(psPackageInstallerType))\r\n                        {\r\n                            options.InstallerType = PSEnumHelpers.ToPackageInstallerType(psPackageInstallerType);\r\n                        }\r\n\r\n                        options.Scope = PSEnumHelpers.ToPackageInstallScope(psPackageInstallScope);\r\n                        options.SkipMicrosoftStoreLicense = skipMicrosoftStoreLicense;\r\n\r\n                        if (!PSEnumHelpers.IsDefaultEnum(psWindowsPlatform))\r\n                        {\r\n                            options.Platform = PSEnumHelpers.ToWindowsPlatform(psWindowsPlatform);\r\n                        }\r\n\r\n                        if (!string.IsNullOrEmpty(targetOSVersion))\r\n                        {\r\n                            options.TargetOSVersion = targetOSVersion;\r\n                        }\r\n\r\n                        return await this.DownloadPackageAsync(package, options);\r\n                    }));\r\n\r\n            if (result != null)\r\n            {\r\n                this.Write(StreamType.Object, new PSDownloadResult(result.Item1, result.Item2));\r\n            }\r\n        }\r\n\r\n        private DownloadOptions GetDownloadOptions(PackageVersionId? version)\r\n        {\r\n            var options = ManagementDeploymentFactory.Instance.CreateDownloadOptions();\r\n            if (version != null)\r\n            {\r\n                options.PackageVersionId = version;\r\n            }\r\n\r\n            if (this.Locale != null)\r\n            {\r\n                options.Locale = this.Locale;\r\n            }\r\n\r\n            options.AllowHashMismatch = this.AllowHashMismatch;\r\n            options.SkipDependencies = this.SkipDependencies;\r\n\r\n            return options;\r\n        }\r\n\r\n        private async Task<DownloadResult> DownloadPackageAsync(\r\n            CatalogPackage package,\r\n            DownloadOptions options)\r\n        {\r\n            var activity = string.Format(Resources.ProgressRecordActivityExporting, package.Name);\r\n            var progressOperation = new DownloadOperationWithProgress(this, activity);\r\n            return await progressOperation.ExecuteAsync(\r\n                () => PackageManagerWrapper.Instance.DownloadPackageAsync(package, options));\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Commands/FinderPackageCommand.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"FinderPackageCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Commands\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.WinGet.Client.Engine.Commands.Common;\r\n    using Microsoft.WinGet.Client.Engine.Helpers;\r\n    using Microsoft.WinGet.Client.Engine.PSObjects;\r\n    using Microsoft.WinGet.Common.Command;\r\n\r\n    /// <summary>\r\n    /// Searches configured sources for packages.\r\n    /// </summary>\r\n    public sealed class FinderPackageCommand : FinderExtendedCommand\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"FinderPackageCommand\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"psCmdlet\">Caller cmdlet.</param>\r\n        /// <param name=\"id\">Package identifier.</param>\r\n        /// <param name=\"name\">Name of package.</param>\r\n        /// <param name=\"moniker\">Moniker of package.</param>\r\n        /// <param name=\"source\">Source to search. If null, all are searched.</param>\r\n        /// <param name=\"query\">Match against any field of a package.</param>\r\n        /// <param name=\"tag\">Tag of the package.</param>\r\n        /// <param name=\"command\">Command of the package.</param>\r\n        /// <param name=\"count\">Max results to return.</param>\r\n        public FinderPackageCommand(\r\n            PSCmdlet psCmdlet,\r\n            string id,\r\n            string name,\r\n            string moniker,\r\n            string source,\r\n            string[] query,\r\n            string tag,\r\n            string command,\r\n            uint count)\r\n            : base(psCmdlet)\r\n        {\r\n            // FinderCommand\r\n            this.Id = id;\r\n            this.Name = name;\r\n            this.Moniker = moniker;\r\n            this.Source = source;\r\n            this.Query = query;\r\n\r\n            // FinderExtendedCommand\r\n            this.Tag = tag;\r\n            this.Command = command;\r\n            this.Count = count;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Process find package command.\r\n        /// </summary>\r\n        /// <param name=\"psPackageFieldMatchOption\">PSPackageFieldMatchOption.</param>\r\n        public void Find(string psPackageFieldMatchOption)\r\n        {\r\n            var results = this.Execute(\r\n                () => this.FindPackages(\r\n                    CompositeSearchBehavior.RemotePackagesFromRemoteCatalogs,\r\n                    PSEnumHelpers.ToPackageFieldMatchOption(psPackageFieldMatchOption)));\r\n\r\n            for (var i = 0; i < results.Count; i++)\r\n            {\r\n                this.Write(StreamType.Object, new PSFoundCatalogPackage(results[i].CatalogPackage));\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Process get package command.\r\n        /// </summary>\r\n        /// <param name=\"psPackageFieldMatchOption\">PSPackageFieldMatchOption.</param>\r\n        public void Get(string psPackageFieldMatchOption)\r\n        {\r\n            var results = this.Execute(\r\n                () => this.FindPackages(\r\n                    CompositeSearchBehavior.LocalCatalogs,\r\n                    PSEnumHelpers.ToPackageFieldMatchOption(psPackageFieldMatchOption)));\r\n            for (var i = 0; i < results.Count; i++)\r\n            {\r\n                this.Write(StreamType.Object, new PSInstalledCatalogPackage(results[i].CatalogPackage));\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Commands/InstallerPackageCommand.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"InstallerPackageCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Commands\r\n{\r\n    using System.Management.Automation;\r\n    using System.Threading.Tasks;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.WinGet.Client.Engine.Commands.Common;\r\n    using Microsoft.WinGet.Client.Engine.Helpers;\r\n    using Microsoft.WinGet.Client.Engine.PSObjects;\r\n    using Microsoft.WinGet.Common.Command;\r\n    using Microsoft.WinGet.Resources;\r\n\r\n    /// <summary>\r\n    /// Installs or updates a package from the pipeline or from a configured source.\r\n    /// </summary>\r\n    public sealed class InstallerPackageCommand : InstallCommand\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"InstallerPackageCommand\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"psCmdlet\">Caller cmdlet.</param>\r\n        /// <param name=\"override\">Override arguments to be passed on to the installer.</param>\r\n        /// <param name=\"custom\">Additional arguments.</param>\r\n        /// <param name=\"location\">Installation location.</param>\r\n        /// <param name=\"allowHashMismatch\">To skip the installer hash validation check.</param>\r\n        /// <param name=\"force\">To continue upon non security related failures.</param>\r\n        /// <param name=\"header\">HTTP Header to pass on to the REST Source.</param>\r\n        /// <param name=\"psCatalogPackage\">PSCatalogPackage.</param>\r\n        /// <param name=\"version\">Version to install.</param>\r\n        /// <param name=\"log\">Logging file location.</param>\r\n        /// <param name=\"id\">Package identifier.</param>\r\n        /// <param name=\"name\">Name of package.</param>\r\n        /// <param name=\"moniker\">Moniker of package.</param>\r\n        /// <param name=\"source\">Source to search. If null, all are searched.</param>\r\n        /// <param name=\"query\">Match against any field of a package.</param>\r\n        /// <param name=\"skipDependencies\">To skip package dependencies.</param>\r\n        public InstallerPackageCommand(\r\n            PSCmdlet psCmdlet,\r\n            string @override,\r\n            string custom,\r\n            string location,\r\n            bool allowHashMismatch,\r\n            bool force,\r\n            string header,\r\n            PSCatalogPackage psCatalogPackage,\r\n            string version,\r\n            string log,\r\n            string id,\r\n            string name,\r\n            string moniker,\r\n            string source,\r\n            string[] query,\r\n            bool skipDependencies)\r\n            : base(psCmdlet)\r\n        {\r\n            // InstallCommand.\r\n            this.Override = @override;\r\n            this.Custom = custom;\r\n            this.Location = location;\r\n            this.Force = force;\r\n            this.Header = header;\r\n            this.AllowHashMismatch = allowHashMismatch;\r\n            this.SkipDependencies = skipDependencies;\r\n            this.Log = log;\r\n\r\n            // PackageCommand.\r\n            if (psCatalogPackage != null)\r\n            {\r\n                this.CatalogPackage = psCatalogPackage;\r\n            }\r\n\r\n            this.Version = version;\r\n\r\n            // FinderCommand\r\n            this.Id = id;\r\n            this.Name = name;\r\n            this.Moniker = moniker;\r\n            this.Source = source;\r\n            this.Query = query;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Process install package command.\r\n        /// </summary>\r\n        /// <param name=\"psPackageFieldMatchOption\">PSPackageFieldMatchOption.</param>\r\n        /// <param name=\"psPackageInstallScope\">PSPackageInstallScope.</param>\r\n        /// <param name=\"psProcessorArchitecture\">PSProcessorArchitecture.</param>\r\n        /// <param name=\"psPackageInstallMode\">PSPackageInstallMode.</param>\r\n        /// <param name=\"psPackageInstallerType\">PSPackageInstallerType.</param>\r\n        public void Install(\r\n            string psPackageFieldMatchOption,\r\n            string psPackageInstallScope,\r\n            string psProcessorArchitecture,\r\n            string psPackageInstallMode,\r\n            string psPackageInstallerType)\r\n        {\r\n            var result = this.Execute(\r\n                async () => await this.GetPackageAndExecuteAsync(\r\n                    CompositeSearchBehavior.RemotePackagesFromRemoteCatalogs,\r\n                    PSEnumHelpers.ToPackageFieldMatchOption(psPackageFieldMatchOption),\r\n                    async (package, version) =>\r\n                    {\r\n                        InstallOptions options = this.GetInstallOptions(version, psPackageInstallMode);\r\n                        if (!PSEnumHelpers.IsDefaultEnum(psProcessorArchitecture))\r\n                        {\r\n                            options.AllowedArchitectures.Clear();\r\n                            options.AllowedArchitectures.Add(PSEnumHelpers.ToProcessorArchitecture(psProcessorArchitecture));\r\n                        }\r\n\r\n                        if (!PSEnumHelpers.IsDefaultEnum(psPackageInstallerType))\r\n                        {\r\n                            options.InstallerType = PSEnumHelpers.ToPackageInstallerType(psPackageInstallerType);\r\n                        }\r\n\r\n                        options.PackageInstallScope = PSEnumHelpers.ToPackageInstallScope(psPackageInstallScope);\r\n\r\n                        return await this.InstallPackageAsync(package, options);\r\n                    }));\r\n\r\n            if (result != null)\r\n            {\r\n                this.Write(StreamType.Object, new PSInstallResult(result.Item1, result.Item2));\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Process update package command.\r\n        /// </summary>\r\n        /// <param name=\"includeUnknown\">If updating to an unknown version is allowed.</param>\r\n        /// <param name=\"psPackageFieldMatchOption\">PSPackageFieldMatchOption.</param>\r\n        /// <param name=\"psPackageInstallScope\">PSPackageInstallScope.</param>\r\n        /// <param name=\"psProcessorArchitecture\">PSProcessorArchitecture.</param>\r\n        /// <param name=\"psPackageInstallMode\">PSPackageInstallMode.</param>\r\n        /// <param name=\"psPackageInstallerType\">PSPackageInstallerType.</param>\r\n        public void Update(\r\n            bool includeUnknown,\r\n            string psPackageFieldMatchOption,\r\n            string psPackageInstallScope,\r\n            string psProcessorArchitecture,\r\n            string psPackageInstallMode,\r\n            string psPackageInstallerType)\r\n        {\r\n            var result = this.Execute(\r\n                async () => await this.GetPackageAndExecuteAsync(\r\n                    CompositeSearchBehavior.LocalCatalogs,\r\n                    PSEnumHelpers.ToPackageFieldMatchOption(psPackageFieldMatchOption),\r\n                    async (package, version) =>\r\n                    {\r\n                        InstallOptions options = this.GetInstallOptions(version, psPackageInstallMode);\r\n                        options.AllowUpgradeToUnknownVersion = includeUnknown;\r\n\r\n                        if (!PSEnumHelpers.IsDefaultEnum(psProcessorArchitecture))\r\n                        {\r\n                            options.AllowedArchitectures.Clear();\r\n                            options.AllowedArchitectures.Add(PSEnumHelpers.ToProcessorArchitecture(psProcessorArchitecture));\r\n                        }\r\n\r\n                        if (!PSEnumHelpers.IsDefaultEnum(psPackageInstallerType))\r\n                        {\r\n                            options.InstallerType = PSEnumHelpers.ToPackageInstallerType(psPackageInstallerType);\r\n                        }\r\n\r\n                        options.PackageInstallScope = PSEnumHelpers.ToPackageInstallScope(psPackageInstallScope);\r\n\r\n                        return await this.UpgradePackageAsync(package, options);\r\n                    }));\r\n\r\n            if (result != null)\r\n            {\r\n                this.Write(StreamType.Object, new PSInstallResult(result.Item1, result.Item2));\r\n            }\r\n        }\r\n\r\n        private async Task<InstallResult> InstallPackageAsync(\r\n            CatalogPackage package,\r\n            InstallOptions options)\r\n        {\r\n            var installOperation = new InstallOperationWithProgress(\r\n                this,\r\n                string.Format(Resources.ProgressRecordActivityInstalling, package.Name));\r\n            return await installOperation.ExecuteAsync(\r\n                    () => PackageManagerWrapper.Instance.InstallPackageAsync(package, options));\r\n        }\r\n\r\n        private async Task<InstallResult> UpgradePackageAsync(\r\n            CatalogPackage package,\r\n            InstallOptions options)\r\n        {\r\n            var installOperation = new InstallOperationWithProgress(\r\n                this,\r\n                string.Format(Resources.ProgressRecordActivityUpdating, package.Name));\r\n            return await installOperation.ExecuteAsync(\r\n                    () => PackageManagerWrapper.Instance.UpgradePackageAsync(package, options));\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Commands/RepairPackageCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"RepairPackageCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Commands\r\n{\r\n    using System;\r\n    using System.Management.Automation;\r\n    using System.Threading.Tasks;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.WinGet.Client.Engine.Commands.Common;\r\n    using Microsoft.WinGet.Client.Engine.Exceptions;\r\n    using Microsoft.WinGet.Client.Engine.Helpers;\r\n    using Microsoft.WinGet.Client.Engine.PSObjects;\r\n    using Microsoft.WinGet.Resources;\r\n\r\n    /// <summary>\r\n    /// This class defines the repair package command.\r\n    /// </summary>\r\n    public sealed class RepairPackageCommand : PackageCommand\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"RepairPackageCommand\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"psCmdlet\">Caller cmdlet.</param>\r\n        /// <param name=\"psCatalogPackage\">PSCatalogPackage.</param>\r\n        /// <param name=\"allowHashMismatch\">To skip the installer hash validation check.</param>\r\n        /// <param name=\"force\">To continue upon non security related failures.</param>\r\n        /// <param name=\"version\">Version to repair.</param>\r\n        /// <param name=\"log\">Logging file location.</param>\r\n        /// <param name=\"id\">Package identifier.</param>\r\n        /// <param name=\"name\">Name of package.</param>\r\n        /// <param name=\"moniker\">Moniker of package.</param>\r\n        /// <param name=\"source\">Source to search. if null, all are searched.</param>\r\n        /// <param name=\"query\">Match against any field of a package.</param>\r\n        public RepairPackageCommand(\r\n            PSCmdlet psCmdlet,\r\n            bool allowHashMismatch,\r\n            bool force,\r\n            PSCatalogPackage psCatalogPackage,\r\n            string version,\r\n            string log,\r\n            string id,\r\n            string name,\r\n            string moniker,\r\n            string source,\r\n            string[] query)\r\n            : base(psCmdlet)\r\n        {\r\n            this.Force = force;\r\n            this.AllowHashMismatch = allowHashMismatch;\r\n\r\n            if (psCatalogPackage != null)\r\n            {\r\n                this.CatalogPackage = psCatalogPackage;\r\n            }\r\n\r\n            this.Version = version;\r\n\r\n            this.Id = id;\r\n            this.Name = name;\r\n            this.Moniker = moniker;\r\n            this.Source = source;\r\n            this.Query = query;\r\n\r\n            this.Log = log;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the path to the logging file.\r\n        /// </summary>\r\n        private string? Log { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether to continue upon non security related failures.\r\n        /// </summary>\r\n        private bool Force { get; set; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets a value indicating whether to skip the installer hash validation check.\r\n        /// </summary>\r\n        private bool AllowHashMismatch { get; set; }\r\n\r\n        /// <summary>\r\n        /// Process repair package.\r\n        /// </summary>\r\n        /// <param name=\"psPackageFieldMatchOption\">PSPackageFieldMatchOption.</param>\r\n        /// <param name=\"psPackageRepairMode\">PSPackageRepairMode.</param>\r\n        public void Repair(\r\n            string psPackageFieldMatchOption,\r\n            string psPackageRepairMode)\r\n        {\r\n            var result = this.Execute(\r\n                async () => await this.GetPackageAndExecuteAsync(\r\n                    CompositeSearchBehavior.AllCatalogs,\r\n                    PSEnumHelpers.ToPackageFieldMatchOption(psPackageFieldMatchOption),\r\n                    async (package, version) =>\r\n                    {\r\n                        var repairOptions = this.GetRepairOptions(version, PSEnumHelpers.ToPackageRepairMode(psPackageRepairMode));\r\n                        return await this.RepairPackageAsync(package, repairOptions);\r\n                    }));\r\n\r\n            if (result != null)\r\n            {\r\n                if (result.Item1.Status == RepairResultStatus.RepairError\r\n                    && result.Item1.ExtendedErrorCode != null)\r\n                {\r\n                    if (result.Item1.ExtendedErrorCode.InnerException != null)\r\n                    {\r\n                        throw new WinGetRepairPackageException(result.Item1.ExtendedErrorCode.HResult, result.Item1.RepairerErrorCode, result.Item1.ExtendedErrorCode.InnerException);\r\n                    }\r\n\r\n                    throw new WinGetRepairPackageException(result.Item1.ExtendedErrorCode.HResult, result.Item1.RepairerErrorCode);\r\n                }\r\n\r\n                this.Write(WinGet.Common.Command.StreamType.Object, new PSRepairResult(result.Item1, result.Item2));\r\n            }\r\n        }\r\n\r\n        private RepairOptions GetRepairOptions(\r\n            PackageVersionId? version,\r\n            PackageRepairMode repairMode)\r\n        {\r\n            var options = ManagementDeploymentFactory.Instance.CreateRepairOptions();\r\n            options.AllowHashMismatch = this.AllowHashMismatch;\r\n            options.Force = this.Force;\r\n\r\n            if (this.Log != null)\r\n            {\r\n                options.LogOutputPath = this.Log;\r\n            }\r\n\r\n            options.PackageRepairMode = repairMode;\r\n\r\n            if (version != null)\r\n            {\r\n                options.PackageVersionId = version;\r\n            }\r\n\r\n            return options;\r\n        }\r\n\r\n        private async Task<RepairResult> RepairPackageAsync(\r\n            CatalogPackage catalogPackage,\r\n            RepairOptions repairOptions)\r\n        {\r\n            var progressOperation = new RepairOperationWithProgress(\r\n                this,\r\n                string.Format(Resources.ProgressRecordActivityRepairing, catalogPackage.Name));\r\n\r\n            return await progressOperation.ExecuteAsync(\r\n                () => PackageManagerWrapper.Instance.RepairPackageAsync(catalogPackage, repairOptions));\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Commands/SourceCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"SourceCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Commands\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Engine.Commands.Common;\r\n    using Microsoft.WinGet.Client.Engine.PSObjects;\r\n    using Microsoft.WinGet.Common.Command;\r\n\r\n    /// <summary>\r\n    /// Wrapper for source cmdlets.\r\n    /// </summary>\r\n    public sealed class SourceCommand : ManagementDeploymentCommand\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"SourceCommand\"/> class.\r\n        /// Wrapper for Source commands.\r\n        /// </summary>\r\n        /// <param name=\"psCmdlet\">Caller cmdlet.</param>\r\n        public SourceCommand(PSCmdlet psCmdlet)\r\n            : base(psCmdlet)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Get-WinGetSource.\r\n        /// </summary>\r\n        /// <param name=\"name\">Optional name.</param>\r\n        public void Get(string name)\r\n        {\r\n            var results = this.Execute(\r\n                () => this.GetPackageCatalogReferences(name));\r\n            for (var i = 0; i < results.Count; i++)\r\n            {\r\n                this.Write(StreamType.Object, new PSSourceResult(results[i]));\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Commands/UninstallPackageCommand.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"UninstallPackageCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Commands\r\n{\r\n    using System.Management.Automation;\r\n    using System.Threading.Tasks;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.WinGet.Client.Engine.Commands.Common;\r\n    using Microsoft.WinGet.Client.Engine.Helpers;\r\n    using Microsoft.WinGet.Client.Engine.PSObjects;\r\n    using Microsoft.WinGet.Common.Command;\r\n    using Microsoft.WinGet.Resources;\r\n\r\n    /// <summary>\r\n    /// Uninstalls a package from the local system.\r\n    /// </summary>\r\n    public sealed class UninstallPackageCommand : PackageCommand\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"UninstallPackageCommand\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"psCmdlet\">Caller cmdlet.</param>\r\n        /// <param name=\"psCatalogPackage\">PSCatalogPackage.</param>\r\n        /// <param name=\"version\">Version to install.</param>\r\n        /// <param name=\"log\">Logging file location.</param>\r\n        /// <param name=\"id\">Package identifier.</param>\r\n        /// <param name=\"name\">Name of package.</param>\r\n        /// <param name=\"moniker\">Moniker of package.</param>\r\n        /// <param name=\"source\">Source to search. If null, all are searched.</param>\r\n        /// <param name=\"query\">Match against any field of a package.</param>\r\n        public UninstallPackageCommand(\r\n            PSCmdlet psCmdlet,\r\n            PSCatalogPackage psCatalogPackage,\r\n            string version,\r\n            string log,\r\n            string id,\r\n            string name,\r\n            string moniker,\r\n            string source,\r\n            string[] query)\r\n            : base(psCmdlet)\r\n        {\r\n            // PackageCommand.\r\n            if (psCatalogPackage != null)\r\n            {\r\n                this.CatalogPackage = psCatalogPackage;\r\n            }\r\n\r\n            this.Version = version;\r\n\r\n            // FinderCommand\r\n            this.Id = id;\r\n            this.Name = name;\r\n            this.Moniker = moniker;\r\n            this.Source = source;\r\n            this.Query = query;\r\n\r\n            // UninstallPackageCommand\r\n            this.Log = log;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the path to the logging file.\r\n        /// </summary>\r\n        private string? Log { get; set; }\r\n\r\n        /// <summary>\r\n        /// Process uninstall package.\r\n        /// </summary>\r\n        /// <param name=\"psPackageFieldMatchOption\">PSPackageFieldMatchOption.</param>\r\n        /// <param name=\"psPackageUninstallMode\">PSPackageUninstallMode.</param>\r\n        /// <param name=\"force\">Force.</param>\r\n        public void Uninstall(\r\n            string psPackageFieldMatchOption,\r\n            string psPackageUninstallMode,\r\n            bool force)\r\n        {\r\n            var result = this.Execute(\r\n                async () => await this.GetPackageAndExecuteAsync(\r\n                    CompositeSearchBehavior.LocalCatalogs,\r\n                    PSEnumHelpers.ToPackageFieldMatchOption(psPackageFieldMatchOption),\r\n                    async (package, version) =>\r\n                    {\r\n                        UninstallOptions options = this.GetUninstallOptions(version, PSEnumHelpers.ToPackageUninstallMode(psPackageUninstallMode), force);\r\n                        return await this.UninstallPackageAsync(package, options);\r\n                    }));\r\n\r\n            if (result != null)\r\n            {\r\n                this.Write(StreamType.Object, new PSUninstallResult(result.Item1, result.Item2));\r\n            }\r\n        }\r\n\r\n        private UninstallOptions GetUninstallOptions(\r\n            PackageVersionId? version,\r\n            PackageUninstallMode packageUninstallMode,\r\n            bool force)\r\n        {\r\n            var options = ManagementDeploymentFactory.Instance.CreateUninstallOptions();\r\n            options.Force = force;\r\n            if (this.Log != null)\r\n            {\r\n                options.LogOutputPath = this.Log;\r\n            }\r\n\r\n            options.PackageUninstallMode = packageUninstallMode;\r\n\r\n            if (version != null)\r\n            {\r\n                options.PackageVersionId = version;\r\n            }\r\n\r\n            return options;\r\n        }\r\n\r\n        private async Task<UninstallResult> UninstallPackageAsync(\r\n            CatalogPackage package,\r\n            UninstallOptions options)\r\n        {\r\n            var progressOperation = new UninstallOperationWithProgress(\r\n                this,\r\n                string.Format(Resources.ProgressRecordActivityUninstalling, package.Name));\r\n            return await progressOperation.ExecuteAsync(\r\n                    () => PackageManagerWrapper.Instance.UninstallPackageAsync(package, options));\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Commands/UserSettingsCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"UserSettingsCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Commands\r\n{\r\n    using System;\r\n    using System.Collections;\r\n    using System.IO;\r\n    using System.Linq;\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Engine.Commands.Common;\r\n    using Microsoft.WinGet.Client.Engine.Common;\r\n    using Microsoft.WinGet.Client.Engine.Exceptions;\r\n    using Microsoft.WinGet.Client.Engine.Helpers;\r\n    using Microsoft.WinGet.Common.Command;\r\n    using Newtonsoft.Json;\r\n    using Newtonsoft.Json.Linq;\r\n\r\n    /// <summary>\r\n    /// Class used by the user settings cmdlets.\r\n    /// </summary>\r\n    public sealed class UserSettingsCommand : BaseCommand\r\n    {\r\n        private const string SchemaKey = \"$schema\";\r\n        private const string SchemaValue = \"https://aka.ms/winget-settings.schema.json\";\r\n\r\n        private static string? winGetSettingsFilePath;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"UserSettingsCommand\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"psCmdlet\">PSCmdlet.</param>\r\n        public UserSettingsCommand(PSCmdlet psCmdlet)\r\n            : base(psCmdlet)\r\n        {\r\n            // Doing it in the static constructor will show the user running in system context:\r\n            // The type initializer for 'Microsoft.WinGet.Client.Engine.Commands.UserSettingsCommand' threw an exception.\r\n            // Here would be \"The specified method is not supported.\"\r\n            if (winGetSettingsFilePath == null)\r\n            {\r\n                var wingetCliWrapper = new WingetCLIWrapper();\r\n                var settingsResult = wingetCliWrapper.RunCommand(this, new WinGetCLICommandBuilder(\"settings\").AppendSubCommand(\"export\"));\r\n\r\n                // Read the user settings file property.\r\n                var userSettingsFile = Utilities.ConvertToHashtable(settingsResult.StdOut)[\"userSettingsFile\"] ?? throw new ArgumentNullException(\"userSettingsFile\");\r\n                winGetSettingsFilePath = (string)userSettingsFile;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Get-WinGetUserSetting.\r\n        /// </summary>\r\n        public void Get()\r\n        {\r\n            this.Write(StreamType.Object, this.GetLocalSettingsAsHashtable());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Test-WinGetUserSetting.\r\n        /// </summary>\r\n        /// <param name=\"userSettings\">Input user settings.</param>\r\n        /// <param name=\"ignoreNotSet\">Ignore comparing settings that are not part of the input.</param>\r\n        public void Test(Hashtable userSettings, bool ignoreNotSet)\r\n        {\r\n            this.Write(StreamType.Object, this.CompareUserSettings(userSettings, ignoreNotSet));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Set-WinGetUserSetting.\r\n        /// </summary>\r\n        /// <param name=\"userSettings\">Input user settings.</param>\r\n        /// <param name=\"merge\">Merge the current user settings and the input settings.</param>\r\n        public void Set(Hashtable userSettings, bool merge)\r\n        {\r\n            var newSettings = HashtableToJObject(userSettings);\r\n\r\n            // Merge settings.\r\n            if (merge)\r\n            {\r\n                var currentSettings = this.LocalSettingsFileToJObject();\r\n\r\n                // To make the input settings triumph, they need to be merged into the existing settings.\r\n                currentSettings.Merge(newSettings, new JsonMergeSettings\r\n                {\r\n                    MergeArrayHandling = MergeArrayHandling.Union,\r\n                    MergeNullValueHandling = MergeNullValueHandling.Ignore,\r\n                });\r\n\r\n                newSettings = currentSettings;\r\n            }\r\n\r\n            // Add schema if not there.\r\n            if (!newSettings.ContainsKey(SchemaKey))\r\n            {\r\n                newSettings.Add(SchemaKey, SchemaValue);\r\n            }\r\n\r\n            var orderedSettings = this.CreateAlphabeticallyOrderedJObject(newSettings);\r\n\r\n            // Write settings.\r\n            var settingsJson = orderedSettings.ToString(Formatting.Indented);\r\n            File.WriteAllText(\r\n                winGetSettingsFilePath!,\r\n                settingsJson);\r\n\r\n            this.Write(StreamType.Object, Utilities.ConvertToHashtable(settingsJson));\r\n        }\r\n\r\n        private static JObject HashtableToJObject(Hashtable hashtable)\r\n        {\r\n            return (JObject)JToken.FromObject(hashtable);\r\n        }\r\n\r\n        private Hashtable GetLocalSettingsAsHashtable()\r\n        {\r\n            var content = File.Exists(winGetSettingsFilePath) ?\r\n                File.ReadAllText(winGetSettingsFilePath) :\r\n                string.Empty;\r\n\r\n            return Utilities.ConvertToHashtable(content);\r\n        }\r\n\r\n        private JObject LocalSettingsFileToJObject()\r\n        {\r\n            try\r\n            {\r\n                return File.Exists(winGetSettingsFilePath) ?\r\n                    JObject.Parse(File.ReadAllText(winGetSettingsFilePath)) :\r\n                    new JObject();\r\n            }\r\n            catch (JsonReaderException e)\r\n            {\r\n                this.Write(StreamType.Verbose, e.Message);\r\n                throw new UserSettingsReadException(e);\r\n            }\r\n        }\r\n\r\n        private bool CompareUserSettings(Hashtable userSettings, bool ignoreNotSet)\r\n        {\r\n            try\r\n            {\r\n                var currentSettings = this.LocalSettingsFileToJObject();\r\n                var newSettings = HashtableToJObject(userSettings);\r\n\r\n                // Don't fail because of the schema.\r\n                if (currentSettings.ContainsKey(SchemaKey))\r\n                {\r\n                    currentSettings.Remove(SchemaKey);\r\n                }\r\n\r\n                if (newSettings.ContainsKey(SchemaKey))\r\n                {\r\n                    newSettings.Remove(SchemaKey);\r\n                }\r\n\r\n                if (ignoreNotSet)\r\n                {\r\n                    return this.PartialDeepEquals(newSettings, currentSettings);\r\n                }\r\n\r\n                return JToken.DeepEquals(newSettings, currentSettings);\r\n            }\r\n            catch (Exception e)\r\n            {\r\n                this.Write(StreamType.Verbose, e.Message);\r\n                return false;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Partially compares json. All properties and values of json must exist and have the same value\r\n        /// as otherJson.\r\n        /// This doesn't support deep JArray object comparison, but we don't have arrays of type object so far :).\r\n        /// </summary>\r\n        /// <param name=\"json\">Main json.</param>\r\n        /// <param name=\"otherJson\">otherJson.</param>\r\n        /// <returns>True is otherJson partially contains json.</returns>\r\n        private bool PartialDeepEquals(JToken json, JToken? otherJson)\r\n        {\r\n            if (JToken.DeepEquals(json, otherJson))\r\n            {\r\n                return true;\r\n            }\r\n\r\n            if (otherJson == null)\r\n            {\r\n                return false;\r\n            }\r\n\r\n            // If they are a JValue (string, integer, date, etc) or they are a JArray and DeepEquals fails then not equal.\r\n            if ((json is JValue && otherJson is JValue) ||\r\n                (json is JArray && otherJson is JArray))\r\n            {\r\n                this.Write(\r\n                    StreamType.Verbose,\r\n                    $\"'{json.ToString(Formatting.None)}' != '{otherJson.ToString(Formatting.None)}'\");\r\n                return false;\r\n            }\r\n\r\n            // If its not the same type then don't bother.\r\n            if (json.Type != otherJson.Type)\r\n            {\r\n                this.Write(\r\n                    StreamType.Verbose,\r\n                    $\"Mismatch types '{json.ToString(Formatting.None)}' '{otherJson.ToString(Formatting.None)}'\");\r\n                return false;\r\n            }\r\n\r\n            // Look deeply.\r\n            if (json.Type == JTokenType.Object)\r\n            {\r\n                var jObject = (JObject)json;\r\n                var otherJObject = (JObject)otherJson;\r\n\r\n                var properties = jObject.Properties();\r\n                foreach (var property in properties)\r\n                {\r\n                    // If the property is not there then give up.\r\n                    if (!otherJObject.ContainsKey(property.Name))\r\n                    {\r\n                        this.Write(StreamType.Verbose, $\"{property.Name} not found.\");\r\n                        return false;\r\n                    }\r\n\r\n                    if (!this.PartialDeepEquals(property.Value, otherJObject.GetValue(property.Name)))\r\n                    {\r\n                        // Found inequality within a property. We are done.\r\n                        return false;\r\n                    }\r\n                }\r\n            }\r\n\r\n            return true;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Helper method to order alphabetically properties. Newtonsoft doesn't have a nice way\r\n        /// to do it via a custom JsonConverter.\r\n        /// </summary>\r\n        /// <param name=\"jObject\">JObject.</param>\r\n        /// <returns>New ordered JObject.</returns>\r\n        private JObject CreateAlphabeticallyOrderedJObject(JObject jObject)\r\n        {\r\n            JObject newJObject = new ();\r\n            var orderedProperties = jObject.Properties().OrderBy(p => p.Name, StringComparer.Ordinal);\r\n            foreach (var property in orderedProperties)\r\n            {\r\n                if (property.Value.Type == JTokenType.Object)\r\n                {\r\n                    newJObject.Add(\r\n                        property.Name,\r\n                        this.CreateAlphabeticallyOrderedJObject((JObject)property.Value));\r\n                }\r\n                else\r\n                {\r\n                    newJObject.Add(property);\r\n                }\r\n            }\r\n\r\n            return newJObject;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Commands/VersionCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"VersionCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Commands\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Engine.Commands.Common;\r\n    using Microsoft.WinGet.Client.Engine.Helpers;\r\n    using Microsoft.WinGet.Common.Command;\r\n\r\n    /// <summary>\r\n    /// Version commands.\r\n    /// </summary>\r\n    public sealed class VersionCommand : ManagementDeploymentCommand\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"VersionCommand\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"psCmdlet\">The caller cmdlet.</param>\r\n        public VersionCommand(PSCmdlet psCmdlet)\r\n            : base(psCmdlet)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Get-WinGetVersion. Gets the currently installed winget version.\r\n        /// </summary>\r\n        public void Get()\r\n        {\r\n            this.Write(StreamType.Object, this.Execute(() => WinGetVersion.InstalledWinGetVersion(this).TagVersion));\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Commands/WinGetPackageManagerCommand.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"WinGetPackageManagerCommand.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Commands\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.Management.Automation;\r\n    using System.Threading.Tasks;\r\n    using Microsoft.WinGet.Client.Engine.Commands.Common;\r\n    using Microsoft.WinGet.Client.Engine.Common;\r\n    using Microsoft.WinGet.Client.Engine.Exceptions;\r\n    using Microsoft.WinGet.Client.Engine.Helpers;\r\n    using Microsoft.WinGet.Common.Command;\r\n    using Microsoft.WinGet.Resources;\r\n    using static Microsoft.WinGet.Client.Engine.Common.Constants;\r\n\r\n    /// <summary>\r\n    /// Used by Repair-WinGetPackageManager and Assert-WinGetPackageManager.\r\n    /// </summary>\r\n    public sealed class WinGetPackageManagerCommand : ManagementDeploymentCommand\r\n    {\r\n        private const string EnvPath = \"env:PATH\";\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"WinGetPackageManagerCommand\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"psCmdlet\">Cmdlet being executed.</param>\r\n        public WinGetPackageManagerCommand(PSCmdlet psCmdlet)\r\n            : base(psCmdlet)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Asserts winget version is the latest version on winget-cli.\r\n        /// </summary>\r\n        /// <param name=\"preRelease\">Use prerelease version on GitHub.</param>\r\n        public void AssertUsingLatest(bool preRelease)\r\n        {\r\n            var runningTask = this.RunOnMTA(\r\n                async () =>\r\n                {\r\n                    var gitHubClient = new GitHubClient(RepositoryOwner.Microsoft, RepositoryName.WinGetCli, this);\r\n                    string expectedVersion = await gitHubClient.GetLatestReleaseTagNameAsync(preRelease);\r\n                    this.Assert(expectedVersion);\r\n                    return true;\r\n                });\r\n\r\n            this.Wait(runningTask);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Asserts the version installed is the specified.\r\n        /// </summary>\r\n        /// <param name=\"expectedVersion\">The expected version.</param>\r\n        public void Assert(string expectedVersion)\r\n        {\r\n            WinGetIntegrity.AssertWinGet(this, expectedVersion);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Repairs winget using the latest version on winget-cli.\r\n        /// </summary>\r\n        /// <param name=\"preRelease\">Use prerelease version on GitHub.</param>\r\n        /// <param name=\"allUsers\">Install for all users. Requires admin.</param>\r\n        /// <param name=\"force\">Force application shutdown.</param>\r\n        public void RepairUsingLatest(bool preRelease, bool allUsers, bool force)\r\n        {\r\n            this.ValidateWhenAllUsers(allUsers);\r\n            var runningTask = this.RunOnMTA(\r\n                async () =>\r\n                {\r\n                    var gitHubClient = new GitHubClient(RepositoryOwner.Microsoft, RepositoryName.WinGetCli, this);\r\n                    string expectedVersion = await gitHubClient.GetLatestReleaseTagNameAsync(preRelease);\r\n                    await this.RepairStateMachineAsync(expectedVersion, allUsers, force);\r\n                    return true;\r\n                });\r\n\r\n            this.Wait(runningTask);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Repairs winget if needed.\r\n        /// </summary>\r\n        /// <param name=\"expectedVersion\">The expected version, if any.</param>\r\n        /// <param name=\"allUsers\">Install for all users. Requires admin.</param>\r\n        /// <param name=\"force\">Force application shutdown.</param>\r\n        /// <param name=\"includePrerelease\">Include prerelease versions when matching version.</param>\r\n        public void Repair(string expectedVersion, bool allUsers, bool force, bool includePrerelease)\r\n        {\r\n            this.ValidateWhenAllUsers(allUsers);\r\n            var runningTask = this.RunOnMTA(\r\n                async () =>\r\n                {\r\n                    if (!string.IsNullOrWhiteSpace(expectedVersion))\r\n                    {\r\n                        this.Write(StreamType.Verbose, $\"Attempting to resolve version '{expectedVersion}'\");\r\n                        var gitHubClient = new GitHubClient(RepositoryOwner.Microsoft, RepositoryName.WinGetCli, this);\r\n                        try\r\n                        {\r\n                            var resolvedVersion = await gitHubClient.ResolveVersionAsync(expectedVersion, includePrerelease);\r\n                            if (!string.IsNullOrEmpty(resolvedVersion))\r\n                            {\r\n                                this.Write(StreamType.Verbose, $\"Matching version found: {resolvedVersion}\");\r\n                                expectedVersion = resolvedVersion!;\r\n                            }\r\n                            else\r\n                            {\r\n                                this.Write(StreamType.Warning, $\"No matching version found for {expectedVersion}\");\r\n                            }\r\n                        }\r\n                        catch (Exception ex)\r\n                        {\r\n                            this.Write(StreamType.Warning, $\"Could not resolve version '{expectedVersion}': {ex.Message}\");\r\n                        }\r\n                    }\r\n                    else\r\n                    {\r\n                        this.Write(StreamType.Verbose, \"No version specified.\");\r\n                    }\r\n\r\n                    await this.RepairStateMachineAsync(expectedVersion, allUsers, force);\r\n                    return true;\r\n                });\r\n            this.Wait(runningTask);\r\n        }\r\n\r\n        private async Task RepairStateMachineAsync(string expectedVersion, bool allUsers, bool force)\r\n        {\r\n            var seenCategories = new HashSet<IntegrityCategory>();\r\n            var cancellationToken = this.GetCancellationToken();\r\n\r\n            var currentCategory = IntegrityCategory.Unknown;\r\n            while (currentCategory != IntegrityCategory.Installed)\r\n            {\r\n                cancellationToken.ThrowIfCancellationRequested();\r\n\r\n                try\r\n                {\r\n                    WinGetIntegrity.AssertWinGet(this, expectedVersion);\r\n                    this.Write(StreamType.Verbose, $\"WinGet is in a good state.\");\r\n                    currentCategory = IntegrityCategory.Installed;\r\n                }\r\n                catch (WinGetIntegrityException e)\r\n                {\r\n                    currentCategory = e.Category;\r\n\r\n                    if (seenCategories.Contains(currentCategory))\r\n                    {\r\n                        this.Write(StreamType.Verbose, $\"{currentCategory} encountered previously\");\r\n                        throw;\r\n                    }\r\n\r\n                    this.Write(StreamType.Verbose, $\"Integrity category type: {currentCategory}\");\r\n                    seenCategories.Add(currentCategory);\r\n\r\n                    switch (currentCategory)\r\n                    {\r\n                        case IntegrityCategory.UnexpectedVersion:\r\n                            await this.InstallDifferentVersionAsync(new WinGetVersion(expectedVersion), e.InstalledVersion, allUsers, force);\r\n                            break;\r\n                        case IntegrityCategory.NotInPath:\r\n                            this.RepairEnvPath();\r\n                            break;\r\n                        case IntegrityCategory.AppInstallerNotRegistered:\r\n                            await this.RegisterAsync(expectedVersion, allUsers);\r\n                            break;\r\n                        case IntegrityCategory.AppInstallerNotInstalled:\r\n                        case IntegrityCategory.AppInstallerNotSupported:\r\n                        case IntegrityCategory.Failure:\r\n                            await this.InstallAsync(expectedVersion, allUsers, force);\r\n                            break;\r\n                        case IntegrityCategory.AppInstallerNoLicense:\r\n                            // This requires -AllUsers in admin mode.\r\n                            if (allUsers && Utilities.ExecutingAsAdministrator)\r\n                            {\r\n                                await this.InstallAsync(expectedVersion, allUsers, force);\r\n                            }\r\n                            else\r\n                            {\r\n                                throw new WinGetRepairException(e);\r\n                            }\r\n\r\n                            break;\r\n                        case IntegrityCategory.WinGetSourceNotInstalled:\r\n                            await this.InstallWinGetSourceAsync();\r\n                            break;\r\n                        case IntegrityCategory.AppExecutionAliasDisabled:\r\n                        case IntegrityCategory.Unknown:\r\n                            throw new WinGetRepairException(e);\r\n                        default:\r\n                            throw new NotSupportedException();\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        private async Task InstallDifferentVersionAsync(WinGetVersion toInstallVersion, WinGetVersion? installedVersion, bool allUsers, bool force)\r\n        {\r\n            if (installedVersion == null)\r\n            {\r\n                installedVersion = WinGetVersion.InstalledWinGetVersion(this);\r\n            }\r\n\r\n            bool isDowngrade = installedVersion.CompareAsDeployment(toInstallVersion) > 0;\r\n\r\n            string message = $\"Installed WinGet version '{installedVersion.TagVersion}' \" +\r\n                $\"Installing WinGet version '{toInstallVersion.TagVersion}' \" +\r\n                $\"Is downgrade {isDowngrade}\";\r\n            this.Write(\r\n                StreamType.Verbose,\r\n                message);\r\n            var appxModule = new AppxModuleHelper(this);\r\n            await appxModule.InstallFromGitHubReleaseAsync(toInstallVersion.TagVersion, allUsers, isDowngrade, force);\r\n        }\r\n\r\n        private async Task InstallAsync(string toInstallVersion, bool allUsers, bool force)\r\n        {\r\n            // If we are here and toInstallVersion is empty, it means that they just ran Repair-WinGetPackageManager.\r\n            // When there is not version specified, we don't want to assume an empty version means latest, but in\r\n            // this particular case we need to.\r\n            if (string.IsNullOrEmpty(toInstallVersion))\r\n            {\r\n                var gitHubClient = new GitHubClient(RepositoryOwner.Microsoft, RepositoryName.WinGetCli, this);\r\n                toInstallVersion = await gitHubClient.GetLatestReleaseTagNameAsync(false);\r\n            }\r\n\r\n            var appxModule = new AppxModuleHelper(this);\r\n            await appxModule.InstallFromGitHubReleaseAsync(toInstallVersion, allUsers, false, force);\r\n        }\r\n\r\n        private async Task InstallWinGetSourceAsync()\r\n        {\r\n            this.Write(StreamType.Verbose, \"Installing winget source\");\r\n            var appxModule = new AppxModuleHelper(this);\r\n            await appxModule.InstallWinGetSourceAsync();\r\n        }\r\n\r\n        private async Task RegisterAsync(string toRegisterVersion, bool allUsers)\r\n        {\r\n            var appxModule = new AppxModuleHelper(this);\r\n            await appxModule.RegisterAppInstallerAsync(toRegisterVersion, allUsers);\r\n        }\r\n\r\n        private void RepairEnvPath()\r\n        {\r\n            // Add windows app path to user PATH environment variable\r\n            Utilities.AddWindowsAppToPath();\r\n\r\n            // Update this sessions PowerShell environment so the user doesn't have to restart the terminal.\r\n            string? envPathUser = Environment.GetEnvironmentVariable(Constants.PathEnvVar, EnvironmentVariableTarget.User);\r\n            string? envPathMachine = Environment.GetEnvironmentVariable(Constants.PathEnvVar, EnvironmentVariableTarget.Machine);\r\n            string newPwshPathEnv = $\"{envPathMachine};{envPathUser}\";\r\n            this.SetVariable(EnvPath, newPwshPathEnv);\r\n\r\n            this.Write(StreamType.Verbose, $\"PATH environment variable updated\");\r\n        }\r\n\r\n        private void ValidateWhenAllUsers(bool allUsers)\r\n        {\r\n            if (allUsers)\r\n            {\r\n                if (Utilities.ExecutingAsSystem)\r\n                {\r\n                    throw new NotSupportedException();\r\n                }\r\n\r\n                if (!Utilities.ExecutingAsAdministrator)\r\n                {\r\n                    throw new WinGetRepairException(Resources.RepairAllUsersMessage);\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Common/Constants.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"Constants.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Common\r\n{\r\n    /// <summary>\r\n    /// This class contains all of the configurable constants for this project.\r\n    /// </summary>\r\n    internal static class Constants\r\n    {\r\n        /// <summary>\r\n        /// WinGet package family name.\r\n        /// </summary>\r\n#if USE_PROD_CLSIDS\r\n        public const string WingetPackageFamilyName = \"Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\";\r\n#else\r\n        public const string WingetPackageFamilyName = \"WinGetDevCLI_8wekyb3d8bbwe\";\r\n#endif\r\n\r\n        /// <summary>\r\n        /// Winget executable name.\r\n        /// </summary>\r\n#if USE_PROD_CLSIDS\r\n        public const string WinGetExe = \"winget.exe\";\r\n#else\r\n        public const string WinGetExe = \"wingetdev.exe\";\r\n#endif\r\n\r\n        /// <summary>\r\n        /// Name of PATH environment variable.\r\n        /// </summary>\r\n        public const string PathEnvVar = \"PATH\";\r\n\r\n        /// <summary>\r\n        /// One MB.\r\n        /// </summary>\r\n        public const int OneMB = 1024 * 1024;\r\n\r\n        /// <summary>\r\n        /// Repository owners.\r\n        /// </summary>\r\n        public class RepositoryOwner\r\n        {\r\n            /// <summary>\r\n            /// Microsoft org.\r\n            /// </summary>\r\n            public const string Microsoft = \"microsoft\";\r\n        }\r\n\r\n        /// <summary>\r\n        /// Repository names.\r\n        /// </summary>\r\n        public class RepositoryName\r\n        {\r\n            /// <summary>\r\n            /// https://github.com/microsoft/winget-cli .\r\n            /// </summary>\r\n            public const string WinGetCli = \"winget-cli\";\r\n\r\n            /// <summary>\r\n            /// https://github.com/microsoft/microsoft-ui-xaml .\r\n            /// </summary>\r\n            public const string UiXaml = \"microsoft-ui-xaml\";\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Common/ErrorCode.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ErrorCode.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Common\r\n{\r\n    /// <summary>\r\n    /// Error code constants.\r\n    /// </summary>\r\n    internal static class ErrorCode\r\n    {\r\n        /// <summary>\r\n        /// Error code for ERROR_FILE_NOT_FOUND.\r\n        /// </summary>\r\n        public const int FileNotFound = unchecked((int)0x80070002);\r\n\r\n        /// <summary>\r\n        /// Error code for RPC_S_SERVER_UNAVAILABLE.\r\n        /// </summary>\r\n        public const int RpcServerUnavailable = unchecked((int)0x800706BA);\r\n\r\n        /// <summary>\r\n        /// Error code for RPC_S_CALL_FAILED.\r\n        /// </summary>\r\n        public const int RpcCallFailed = unchecked((int)0x800706BE);\r\n\r\n        /// <summary>\r\n        /// Error code for ERROR_PACKAGE_NOT_REGISTERED_FOR_USER.\r\n        /// </summary>\r\n        public const int PackageNotRegisteredForUser = unchecked((int)0x80073D35);\r\n\r\n        /// <summary>\r\n        /// Error code for APPINSTALLER_CLI_ERROR_NO_REPAIR_INFO_FOUND.\r\n        /// </summary>\r\n        public const int NoRepairInfoFound = unchecked((int)0x8A150079);\r\n\r\n        /// <summary>\r\n        /// Error code for APPINSTALLER_CLI_ERROR_REPAIR_NOT_APPLICABLE.\r\n        /// </summary>\r\n        public const int RepairNotApplicable = unchecked((int)0x8A15007A);\r\n\r\n        /// <summary>\r\n        /// Error code for APPINSTALLER_CLI_ERROR_EXEC_REPAIR_FAILED .\r\n        /// </summary>\r\n        public const int RepairerFailure = unchecked((int)0x8A15007B);\r\n\r\n        /// <summary>\r\n        /// Error code for APPINSTALLER_CLI_ERROR_REPAIR_NOT_SUPPORTED.\r\n        /// </summary>\r\n        public const int RepairNotSupported = unchecked((int)0x8A15007C);\r\n\r\n        /// <summary>\r\n        /// Error code for APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED.\r\n        /// </summary>\r\n        public const int AdminContextRepairProhibited = unchecked((int)0x8A15007D);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Common/IntegrityCategory.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"IntegrityCategory.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Common\r\n{\r\n    /// <summary>\r\n    /// The type of the integrity check failure.\r\n    /// </summary>\r\n    public enum IntegrityCategory\r\n    {\r\n        /// <summary>\r\n        /// WinGet is correctly installed.\r\n        /// </summary>\r\n        Installed,\r\n\r\n        /// <summary>\r\n        /// The version installed is not what is expected.\r\n        /// </summary>\r\n        UnexpectedVersion,\r\n\r\n        /// <summary>\r\n        /// Unknown reason.\r\n        /// </summary>\r\n        Unknown,\r\n\r\n        /// <summary>\r\n        /// A failure resulted on a simple winget command that shouldn't happen.\r\n        /// </summary>\r\n        Failure,\r\n\r\n        /// <summary>\r\n        /// WindowsAppPath not in PATH environment variable.\r\n        /// </summary>\r\n        NotInPath,\r\n\r\n        /// <summary>\r\n        /// Winget's app execution alias disabled.\r\n        /// </summary>\r\n        AppExecutionAliasDisabled,\r\n\r\n        /// <summary>\r\n        /// Windows OS is not supported.\r\n        /// </summary>\r\n        OsNotSupported,\r\n\r\n        /// <summary>\r\n        /// AppInstaller package is not installed.\r\n        /// </summary>\r\n        AppInstallerNotInstalled,\r\n\r\n        /// <summary>\r\n        /// AppInstaller package is not registered.\r\n        /// </summary>\r\n        AppInstallerNotRegistered,\r\n\r\n        /// <summary>\r\n        /// Installed App Installer package is not supported.\r\n        /// </summary>\r\n        AppInstallerNotSupported,\r\n\r\n        /// <summary>\r\n        /// No applicable license found.\r\n        /// </summary>\r\n        AppInstallerNoLicense,\r\n\r\n        /// <summary>\r\n        /// WinGet source is not installed.\r\n        /// </summary>\r\n        WinGetSourceNotInstalled,\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Common/Utilities.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"Utilities.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Common\r\n{\r\n    using System;\r\n    using System.Collections;\r\n    using System.Collections.Generic;\r\n    using System.IO;\r\n    using System.Management.Automation;\r\n    using System.Security.Principal;\r\n    using System.Threading;\r\n    using Microsoft.WinGet.Resources;\r\n    using Newtonsoft.Json;\r\n    using Newtonsoft.Json.Linq;\r\n\r\n    /// <summary>\r\n    /// This class contains various helper methods for this project.\r\n    /// </summary>\r\n    internal static class Utilities\r\n    {\r\n        /// <summary>\r\n        /// Gets a value indicating whether the current assembly is executing in an administrative context.\r\n        /// </summary>\r\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"Interoperability\", \"CA1416:Validate platform compatibility\", Justification = \"Windows only API\")]\r\n        public static bool ExecutingAsAdministrator\r\n        {\r\n            get\r\n            {\r\n                WindowsIdentity identity = WindowsIdentity.GetCurrent();\r\n                WindowsPrincipal principal = new (identity);\r\n                return principal.IsInRole(WindowsBuiltInRole.Administrator);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets a value indicating whether the current assembly is executing as a SYSTEM user.\r\n        /// </summary>\r\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"Interoperability\", \"CA1416:Validate platform compatibility\", Justification = \"Windows only API\")]\r\n        public static bool ExecutingAsSystem\r\n        {\r\n            get\r\n            {\r\n                return WindowsIdentity.GetCurrent().IsSystem;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets a value indicating whether the current execution context will use in-proc winget.\r\n        /// </summary>\r\n        public static bool UsesInProcWinget\r\n        {\r\n            get\r\n            {\r\n                return ExecutingAsSystem;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets a value indicating whether the current thread is executing as STA.\r\n        /// </summary>\r\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"Interoperability\", \"CA1416:Validate platform compatibility\", Justification = \"Windows only API\")]\r\n        public static bool ThreadIsSTA\r\n        {\r\n            get\r\n            {\r\n                return Thread.CurrentThread.GetApartmentState() == ApartmentState.STA;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the windows app path for local app data.\r\n        /// </summary>\r\n        public static string LocalDataWindowsAppPath\r\n        {\r\n            get\r\n            {\r\n                return Environment.ExpandEnvironmentVariables(@\"%LOCALAPPDATA%\\Microsoft\\WindowsApps\");\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the windows app path for program files.\r\n        /// </summary>\r\n        public static string ProgramFilesWindowsAppPath\r\n        {\r\n            get\r\n            {\r\n                return Environment.ExpandEnvironmentVariables(@\"%PROGRAMFILES%\\WindowsApps\");\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Throws if not running as admin.\r\n        /// </summary>\r\n        public static void VerifyAdmin()\r\n        {\r\n            if (!Utilities.ExecutingAsAdministrator)\r\n            {\r\n                throw new PSNotSupportedException(Resources.RequiresAdminMessage);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Adds the WindowsApp local app data path to the user environment path.\r\n        /// </summary>\r\n        public static void AddWindowsAppToPath()\r\n        {\r\n            var scope = EnvironmentVariableTarget.User;\r\n            string? envPathValue = Environment.GetEnvironmentVariable(Constants.PathEnvVar, scope);\r\n            if (string.IsNullOrEmpty(envPathValue) || !envPathValue.Contains(Utilities.LocalDataWindowsAppPath))\r\n            {\r\n                Environment.SetEnvironmentVariable(\r\n                    Constants.PathEnvVar,\r\n                    $\"{envPathValue};{Utilities.LocalDataWindowsAppPath}\",\r\n                    scope);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// This is based of https://github.com/PowerShell/PowerShell/blob/master/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/JsonObject.cs.\r\n        /// So we can convert JSON to Hashtable for Windows PowerShell and PowerShell Core.\r\n        /// </summary>\r\n        /// <param name=\"content\">String content.</param>\r\n        /// <returns>The hashtable.</returns>\r\n        public static Hashtable ConvertToHashtable(string content)\r\n        {\r\n            if (string.IsNullOrEmpty(content))\r\n            {\r\n                return new Hashtable();\r\n            }\r\n\r\n            var obj = JsonConvert.DeserializeObject(\r\n                content,\r\n                new JsonSerializerSettings\r\n                {\r\n                    // This TypeNameHandling setting is required to be secure.\r\n                    TypeNameHandling = TypeNameHandling.None,\r\n                    MetadataPropertyHandling = MetadataPropertyHandling.Ignore,\r\n                    MaxDepth = 1024,\r\n                });\r\n\r\n            // It only makes sense that the deserialized object is a dictionary to start.\r\n            return obj switch\r\n            {\r\n                JObject dictionary => PopulateHashTableFromJDictionary(dictionary),\r\n                _ => throw new InvalidDataException()\r\n            };\r\n        }\r\n\r\n        private static Hashtable PopulateHashTableFromJDictionary(JObject entries)\r\n        {\r\n            Hashtable result = new (entries.Count);\r\n            foreach (var entry in entries)\r\n            {\r\n                switch (entry.Value)\r\n                {\r\n                    case JArray list:\r\n                        {\r\n                            // Array\r\n                            var listResult = PopulateHashTableFromJArray(list);\r\n                            result.Add(entry.Key, listResult);\r\n                            break;\r\n                        }\r\n\r\n                    case JObject dic:\r\n                        {\r\n                            // Dictionary\r\n                            var dicResult = PopulateHashTableFromJDictionary(dic);\r\n                            result.Add(entry.Key, dicResult);\r\n                            break;\r\n                        }\r\n\r\n                    case JValue value:\r\n                        {\r\n                            result.Add(entry.Key, value.Value);\r\n                            break;\r\n                        }\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        private static ICollection<object?> PopulateHashTableFromJArray(JArray list)\r\n        {\r\n            var result = new object?[list.Count];\r\n\r\n            for (var index = 0; index < list.Count; index++)\r\n            {\r\n                var element = list[index];\r\n\r\n                switch (element)\r\n                {\r\n                    case JArray array:\r\n                        {\r\n                            // Array\r\n                            var listResult = PopulateHashTableFromJArray(array);\r\n                            result[index] = listResult;\r\n                            break;\r\n                        }\r\n\r\n                    case JObject dic:\r\n                        {\r\n                            // Dictionary\r\n                            var dicResult = PopulateHashTableFromJDictionary(dic);\r\n                            result[index] = dicResult;\r\n                            break;\r\n                        }\r\n\r\n                    case JValue value:\r\n                        {\r\n                            result[index] = value.Value;\r\n                            break;\r\n                        }\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Common/WinGetIntegrity.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"WinGetIntegrity.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Common\r\n{\r\n    using System;\r\n    using System.ComponentModel;\r\n    using System.IO;\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Engine.Exceptions;\r\n    using Microsoft.WinGet.Client.Engine.Helpers;\r\n    using Microsoft.WinGet.Common.Command;\r\n    using Microsoft.WinGet.Resources;\r\n\r\n    /// <summary>\r\n    /// Validates winget runs correctly.\r\n    /// </summary>\r\n    internal static class WinGetIntegrity\r\n    {\r\n        /// <summary>\r\n        /// Verifies winget runs correctly. If it doesn't, tries to find the reason why it failed.\r\n        /// </summary>\r\n        /// <param name=\"pwshCmdlet\">The calling cmdlet.</param>\r\n        /// <param name=\"expectedVersion\">Expected version.</param>\r\n        public static void AssertWinGet(PowerShellCmdlet pwshCmdlet, string expectedVersion)\r\n        {\r\n            // In-proc shouldn't have other dependencies and thus should be ok.\r\n            if (Utilities.UsesInProcWinget)\r\n            {\r\n                // Only check the OS version support for in-proc\r\n                if (!IsSupportedOSVersion())\r\n                {\r\n                    throw new WinGetIntegrityException(IntegrityCategory.OsNotSupported);\r\n                }\r\n\r\n                return;\r\n            }\r\n\r\n            WinGetCLICommandResult? versionResult = null;\r\n\r\n            try\r\n            {\r\n                // Start by calling winget without its WindowsApp PFN path.\r\n                // If it succeeds and the exit code is 0 then we are good.\r\n                versionResult = WinGetVersion.RunWinGetVersionFromCLI(pwshCmdlet, false);\r\n                versionResult.VerifyExitCode();\r\n            }\r\n            catch (Win32Exception e)\r\n            {\r\n                pwshCmdlet.Write(StreamType.Verbose, $\"'winget.exe' Win32Exception {e.Message}\");\r\n                throw new WinGetIntegrityException(GetReason(pwshCmdlet));\r\n            }\r\n            catch (Exception e) when (e is WinGetCLIException || e is WinGetCLITimeoutException)\r\n            {\r\n                pwshCmdlet.Write(StreamType.Verbose, $\"'winget.exe' WinGetCLIException {e.Message}\");\r\n                throw new WinGetIntegrityException(IntegrityCategory.Failure, e);\r\n            }\r\n            catch (Exception e)\r\n            {\r\n                pwshCmdlet.Write(StreamType.Verbose, $\"'winget.exe' Exception {e.Message}\");\r\n                throw new WinGetIntegrityException(IntegrityCategory.Unknown, e);\r\n            }\r\n\r\n            // WinGet is installed. Verify version if needed.\r\n            if (!string.IsNullOrEmpty(expectedVersion))\r\n            {\r\n                // This assumes caller knows that the version exist.\r\n                WinGetVersion expectedWinGetVersion = new WinGetVersion(expectedVersion);\r\n                var installedVersion = WinGetVersion.InstalledWinGetVersion(pwshCmdlet, versionResult);\r\n                if (expectedWinGetVersion.CompareTo(installedVersion) != 0)\r\n                {\r\n                    throw new WinGetIntegrityException(\r\n                        IntegrityCategory.UnexpectedVersion,\r\n                        string.Format(\r\n                            Resources.IntegrityUnexpectedVersionMessage,\r\n                            installedVersion.TagVersion,\r\n                            expectedVersion))\r\n                    { InstalledVersion = installedVersion };\r\n                }\r\n            }\r\n\r\n            // Verify that the winget source is installed.\r\n            var appxModule = new AppxModuleHelper(pwshCmdlet);\r\n            if (!appxModule.IsWinGetSourceInstalled())\r\n            {\r\n                throw new WinGetIntegrityException(IntegrityCategory.WinGetSourceNotInstalled);\r\n            }\r\n        }\r\n\r\n        private static IntegrityCategory GetReason(PowerShellCmdlet pwshCmdlet)\r\n        {\r\n            // Ok, so you are here because calling winget --version failed. Lets try to figure out why.\r\n            var category = IntegrityCategory.Unknown;\r\n            pwshCmdlet.ExecuteInPowerShellThread(() =>\r\n            {\r\n                // When running winget.exe on PowerShell the message of the Win32Exception will distinguish between\r\n                // 'The system cannot find the file specified' and 'No applicable app licenses found' but of course\r\n                // the HRESULT is the same (E_FAIL).\r\n                // To not compare strings let Powershell handle it. If calling winget throws an\r\n                // ApplicationFailedException then is most likely that the license is not there.\r\n                try\r\n                {\r\n                    var ps = PowerShell.Create(RunspaceMode.CurrentRunspace);\r\n                    ps.AddCommand(\"winget\").Invoke();\r\n                }\r\n                catch (ApplicationFailedException e)\r\n                {\r\n                    pwshCmdlet.Write(StreamType.Verbose, e.Message);\r\n                    category = IntegrityCategory.AppInstallerNoLicense;\r\n                }\r\n                catch (Exception)\r\n                {\r\n                }\r\n            });\r\n\r\n            if (category != IntegrityCategory.Unknown)\r\n            {\r\n                return category;\r\n            }\r\n\r\n            // First lets check if the file is there, which means it is installed or someone is taking our place.\r\n            if (File.Exists(WingetCLIWrapper.WinGetFullPath))\r\n            {\r\n                // The file exists, but we couldn't call it... Well maybe winget's app execution alias is not enabled.\r\n                // The trick is knowing that a magical file appears under WindowsApp when its enabled.\r\n                string wingetAliasPath = Path.Combine(Utilities.LocalDataWindowsAppPath, Constants.WinGetExe);\r\n                if (File.Exists(wingetAliasPath))\r\n                {\r\n                    // App execution alias is enabled. Then maybe the path?\r\n                    string? envPath = Environment.GetEnvironmentVariable(Constants.PathEnvVar, EnvironmentVariableTarget.User);\r\n                    if (string.IsNullOrEmpty(envPath) ||\r\n                        !envPath.EndsWith(Utilities.LocalDataWindowsAppPath) ||\r\n                        !envPath.Contains($\"{Utilities.LocalDataWindowsAppPath};\"))\r\n                    {\r\n                        return IntegrityCategory.NotInPath;\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    return IntegrityCategory.AppExecutionAliasDisabled;\r\n                }\r\n            }\r\n\r\n            // Not under %LOCALAPPDATA%\\\\Microsoft\\\\WindowsApps\\PFN\\\r\n\r\n            // Check OS version\r\n            if (!IsSupportedOSVersion())\r\n            {\r\n                return IntegrityCategory.OsNotSupported;\r\n            }\r\n\r\n            // It could be that AppInstaller package is old or the package is not\r\n            // registered at this point. To know that, call Get-AppxPackage.\r\n            var appxModule = new AppxModuleHelper(pwshCmdlet);\r\n            string? version = appxModule.GetAppInstallerPropertyValue(\"Version\");\r\n            if (version is null)\r\n            {\r\n                // This can happen in Windows Sandbox.\r\n                return IntegrityCategory.AppInstallerNotInstalled;\r\n            }\r\n\r\n            // Now AppInstaller version has to be greater than 1.11.11451\r\n            var minAppInstallerVersion = new Version(1, 11, 11451);\r\n            var appInstallerVersion = new Version(version);\r\n            if (appInstallerVersion.CompareTo(minAppInstallerVersion) < 0)\r\n            {\r\n                return IntegrityCategory.AppInstallerNotSupported;\r\n            }\r\n\r\n            // If we get here, we know the package is in the machine but not registered for the user.\r\n            return IntegrityCategory.AppInstallerNotRegistered;\r\n        }\r\n\r\n        private static bool IsSupportedOSVersion()\r\n        {\r\n            // Windows version has to be equal or newer than 10.0.17763.0\r\n            var minWindowsVersion = new Version(10, 0, 17763, 0);\r\n            var osVersion = Environment.OSVersion.Version;\r\n            return osVersion.CompareTo(minWindowsVersion) >= 0;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Exceptions/CatalogConnectException.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"CatalogConnectException.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Exceptions\r\n{\r\n    using System;\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Resources;\r\n\r\n    /// <summary>\r\n    /// Failed connecting to catalog.\r\n    /// </summary>\r\n    [Serializable]\r\n    public class CatalogConnectException : RuntimeException\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"CatalogConnectException\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"inner\">The exception that lead to this one.</param>\r\n        public CatalogConnectException(Exception inner)\r\n            : base(Resources.CatalogConnectExceptionMessage, inner)\r\n        {\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Exceptions/FindPackagesException.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"FindPackagesException.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Exceptions\r\n{\r\n    using System;\r\n    using System.Management.Automation;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.WinGet.Resources;\r\n\r\n    /// <summary>\r\n    /// Raised when there is an error searching for packages.\r\n    /// </summary>\r\n    [Serializable]\r\n    internal class FindPackagesException : RuntimeException\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"FindPackagesException\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"status\">A <see cref=\"FindPackagesResultStatus\" /> value.</param>\r\n        public FindPackagesException(FindPackagesResultStatus status)\r\n            : base(string.Format(\r\n                Resources.FindPackagesExceptionMessage,\r\n                status.ToString()))\r\n        {\r\n            this.Status = status;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the error status.\r\n        /// </summary>\r\n        public FindPackagesResultStatus Status { get; private set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Exceptions/InvalidSourceException.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"InvalidSourceException.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Exceptions\r\n{\r\n    using System;\r\n    using Microsoft.WinGet.Resources;\r\n\r\n    /// <summary>\r\n    /// Invalid source.\r\n    /// </summary>\r\n    [Serializable]\r\n    public class InvalidSourceException : ArgumentException\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"InvalidSourceException\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"sourceName\">Source name.</param>\r\n        public InvalidSourceException(string sourceName)\r\n            : base(string.Format(Resources.InvalidSourceExceptionMessage, sourceName))\r\n        {\r\n            this.SourceName = sourceName;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the source name.\r\n        /// </summary>\r\n        public string SourceName { get; private set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Exceptions/InvalidVersionException.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"InvalidVersionException.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Exceptions\r\n{\r\n    using System;\r\n    using Microsoft.WinGet.Resources;\r\n\r\n    /// <summary>\r\n    /// Invalid version.\r\n    /// </summary>\r\n    [Serializable]\r\n    public class InvalidVersionException : ArgumentException\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"InvalidVersionException\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"version\">Version.</param>\r\n        public InvalidVersionException(string version)\r\n            : base(string.Format(Resources.InvalidVersionExceptionMessage, version))\r\n        {\r\n            this.Version = version;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the version.\r\n        /// </summary>\r\n        public string Version { get; private set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Exceptions/NoPackageFoundException.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"NoPackageFoundException.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Exceptions\r\n{\r\n    using System;\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Resources;\r\n\r\n    /// <summary>\r\n    /// No package found.\r\n    /// </summary>\r\n    [Serializable]\r\n    public class NoPackageFoundException : RuntimeException\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"NoPackageFoundException\"/> class.\r\n        /// </summary>\r\n        public NoPackageFoundException()\r\n            : base(Resources.NoPackageFoundExceptionMessage)\r\n        {\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Exceptions/SingleThreadedApartmentException.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"SingleThreadedApartmentException.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Exceptions\r\n{\r\n    using System;\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Resources;\r\n\r\n    /// <summary>\r\n    /// No package found.\r\n    /// </summary>\r\n    [Serializable]\r\n    public class SingleThreadedApartmentException : RuntimeException\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"SingleThreadedApartmentException\"/> class.\r\n        /// </summary>\r\n        public SingleThreadedApartmentException()\r\n            : base(Resources.SingleThreadedApartmentNotSupportedMessage)\r\n        {\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Exceptions/UserSettingsReadException.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"UserSettingsReadException.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Exceptions\r\n{\r\n    using System;\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Resources;\r\n\r\n    /// <summary>\r\n    /// Settings.json file is invalid.\r\n    /// </summary>\r\n    [Serializable]\r\n    public class UserSettingsReadException : RuntimeException\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"UserSettingsReadException\"/> class.\r\n        /// </summary>\r\n        public UserSettingsReadException()\r\n            : base(Resources.UserSettingsReadException)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"UserSettingsReadException\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"inner\">Inner exception.</param>\r\n        public UserSettingsReadException(Exception inner)\r\n            : base(Resources.UserSettingsReadException, inner)\r\n        {\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Exceptions/VagueCriteriaException.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"VagueCriteriaException.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Exceptions\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.Management.Automation;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.WinGet.Client.Engine.Extensions;\r\n    using Microsoft.WinGet.Resources;\r\n\r\n    /// <summary>\r\n    /// Raised when search criteria for installing or updating a package is too vague.\r\n    /// </summary>\r\n    [Serializable]\r\n    internal class VagueCriteriaException : RuntimeException\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"VagueCriteriaException\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"results\">The list of conflicting packages of length at least two.</param>\r\n        public VagueCriteriaException(IReadOnlyList<MatchResult> results)\r\n            : base(string.Format(\r\n                Resources.VagueCriteriaExceptionMessage,\r\n                results[0].CatalogPackage.ToString(null),\r\n                results[1].CatalogPackage.ToString(null),\r\n                results.Count - 2))\r\n        {\r\n            this.MatchResults = results;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the list of conflicting packages.\r\n        /// </summary>\r\n        public IReadOnlyList<MatchResult> MatchResults { get; private set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Exceptions/WinGetCLIException.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"WinGetCLIException.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Exceptions\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Resources;\r\n\r\n    /// <summary>\r\n    /// WinGet cli exception.\r\n    /// </summary>\r\n    public class WinGetCLIException : RuntimeException\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"WinGetCLIException\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"command\">Command.</param>\r\n        /// <param name=\"parameters\">Parameters.</param>\r\n        /// <param name=\"exitCode\">Exit code.</param>\r\n        /// <param name=\"stdOut\">Standard output.</param>\r\n        /// <param name=\"stdErr\">Standard error.</param>\r\n        public WinGetCLIException(string command, string? parameters, int exitCode, string stdOut, string stdErr)\r\n            : base(string.Format(Resources.WinGetCLIExceptionMessage, command, parameters, exitCode))\r\n        {\r\n            this.Command = command;\r\n            this.Parameters = parameters;\r\n            this.ExitCode = exitCode;\r\n            this.StdOut = stdOut;\r\n            this.StdErr = stdErr;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the command.\r\n        /// </summary>\r\n        public string Command { get; private set; }\r\n\r\n        /// <summary>\r\n        /// Gets the parameters.\r\n        /// </summary>\r\n        public string? Parameters { get; private set; }\r\n\r\n        /// <summary>\r\n        /// Gets the exit code.\r\n        /// </summary>\r\n        public int ExitCode { get; private set; }\r\n\r\n        /// <summary>\r\n        /// Gets the standard output.\r\n        /// </summary>\r\n        public string StdOut { get; private set; }\r\n\r\n        /// <summary>\r\n        /// Gets the standard error.\r\n        /// </summary>\r\n        public string StdErr { get; private set; }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Exceptions/WinGetCLITimeoutException.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"WinGetCLITimeoutException.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Exceptions\r\n{\r\n    using System;\r\n    using Microsoft.WinGet.Resources;\r\n\r\n    /// <summary>\r\n    /// Time out exception for a winget cli command.\r\n    /// </summary>\r\n    public class WinGetCLITimeoutException : TimeoutException\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"WinGetCLITimeoutException\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"command\">Command.</param>\r\n        /// <param name=\"parameters\">Parameters.</param>\r\n        public WinGetCLITimeoutException(string command, string? parameters)\r\n            : base(string.Format(Resources.WinGetCLITimeoutExceptionMessage, command, parameters))\r\n        {\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Exceptions/WinGetIntegrityException.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"WinGetIntegrityException.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Exceptions\r\n{\r\n    using System;\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Engine.Common;\r\n    using Microsoft.WinGet.Client.Engine.Helpers;\r\n    using Microsoft.WinGet.Resources;\r\n\r\n    /// <summary>\r\n    /// WinGet Integrity exception.\r\n    /// </summary>\r\n    public class WinGetIntegrityException : RuntimeException\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"WinGetIntegrityException\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"category\">Category failure.</param>\r\n        public WinGetIntegrityException(IntegrityCategory category)\r\n            : base(GetMessage(category))\r\n        {\r\n            this.Category = category;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"WinGetIntegrityException\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"category\">Category failure.</param>\r\n        /// <param name=\"inner\">Inner exception.</param>\r\n        public WinGetIntegrityException(IntegrityCategory category, Exception inner)\r\n            : base(GetMessage(category), inner)\r\n        {\r\n            this.Category = category;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"WinGetIntegrityException\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"category\">Category failure.</param>\r\n        /// <param name=\"message\">Message.</param>\r\n        public WinGetIntegrityException(IntegrityCategory category, string message)\r\n            : base(message)\r\n        {\r\n            this.Category = category;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the category of the integrity failure.\r\n        /// </summary>\r\n        public IntegrityCategory Category { get; }\r\n\r\n        /// <summary>\r\n        /// Gets or sets the installed version.\r\n        /// </summary>\r\n        internal WinGetVersion? InstalledVersion { get; set; }\r\n\r\n        private static string GetMessage(IntegrityCategory category) => category switch\r\n        {\r\n            IntegrityCategory.Failure => Resources.IntegrityFailureMessage,\r\n            IntegrityCategory.NotInPath => Resources.IntegrityNotInPathMessage,\r\n            IntegrityCategory.AppExecutionAliasDisabled => Resources.IntegrityAppExecutionAliasDisabledMessage,\r\n            IntegrityCategory.OsNotSupported => Resources.IntegrityOsNotSupportedMessage,\r\n            IntegrityCategory.AppInstallerNotInstalled => Resources.IntegrityAppInstallerNotInstalledMessage,\r\n            IntegrityCategory.AppInstallerNotRegistered => Resources.IntegrityAppInstallerNotRegisteredMessage,\r\n            IntegrityCategory.AppInstallerNotSupported => Resources.IntegrityAppInstallerNotSupportedMessage,\r\n            IntegrityCategory.AppInstallerNoLicense => Resources.IntegrityAppInstallerLicense,\r\n            _ => Resources.IntegrityUnknownMessage,\r\n        };\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Exceptions/WinGetRepairException.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"WinGetRepairException.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Exceptions\r\n{\r\n    using System;\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Engine.Common;\r\n    using Microsoft.WinGet.Resources;\r\n\r\n    /// <summary>\r\n    /// WinGet repair exception.\r\n    /// </summary>\r\n    [Serializable]\r\n    public class WinGetRepairException : RuntimeException\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"WinGetRepairException\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"ie\">Integrity exception.</param>\r\n        public WinGetRepairException(WinGetIntegrityException ie)\r\n            : base(GetMessage(ie), ie)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"WinGetRepairException\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"e\">Inner exception.</param>\r\n        public WinGetRepairException(Exception e)\r\n            : base(Resources.RepairFailureMessage, e)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"WinGetRepairException\"/> class.\r\n        /// </summary>\r\n        public WinGetRepairException()\r\n            : base(Resources.RepairFailureMessage)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"WinGetRepairException\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"message\">Message.</param>.\r\n        public WinGetRepairException(string message)\r\n            : base(message)\r\n        {\r\n        }\r\n\r\n        private static string GetMessage(WinGetIntegrityException ie)\r\n        {\r\n            string message = Resources.RepairFailureMessage;\r\n            if (ie.Category == IntegrityCategory.AppInstallerNoLicense)\r\n            {\r\n                message += $\" {Resources.RepairAllUsersHelpMessage}\";\r\n            }\r\n            else if (ie.Category == IntegrityCategory.AppExecutionAliasDisabled)\r\n            {\r\n                message += $\" {Resources.RepairAppExecutionAliasMessage}\";\r\n            }\r\n\r\n            return message;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Exceptions/WinGetRepairPackageException.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"WinGetRepairPackageException.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Exceptions\r\n{\r\n    using System;\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Client.Engine.Common;\r\n    using Microsoft.WinGet.Resources;\r\n\r\n    /// <summary>\r\n    /// WinGetRepairPackageException.\r\n    /// </summary>\r\n    [Serializable]\r\n    public class WinGetRepairPackageException : RuntimeException\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"WinGetRepairPackageException\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"hresult\">Repair operation ExtendedErrorCode Hresult.</param>\r\n        public WinGetRepairPackageException(int hresult)\r\n            : base(GetMessage(hresult))\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"WinGetRepairPackageException\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"hresult\">Repair operation ExtendedErrorCode Hresult.</param>\r\n        /// <param name=\"repairerExitCode\">Repairer exit code.</param>\r\n        public WinGetRepairPackageException(int hresult, uint repairerExitCode)\r\n            : base(GetMessage(hresult, repairerExitCode))\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"WinGetRepairPackageException\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"hresult\">Repair operation ExtendedErrorCode Hresult.</param>\r\n        /// <param name=\"innerException\">InnerException.</param>\r\n        public WinGetRepairPackageException(int hresult, Exception innerException)\r\n            : base(GetMessage(hresult), innerException)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"WinGetRepairPackageException\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"hresult\">Repair operation ExtendedErrorCode Hresult.</param>\r\n        /// <param name=\"repairerExitCode\">Repairer exit code.</param>\r\n        /// <param name=\"innerException\">InnerException.</param>\r\n        public WinGetRepairPackageException(int hresult, uint repairerExitCode, Exception innerException)\r\n            : base(GetMessage(hresult, repairerExitCode), innerException)\r\n        {\r\n        }\r\n\r\n        private static string GetMessage(int hresult, uint repairerExitCode = 0)\r\n        {\r\n            switch (hresult)\r\n            {\r\n                case ErrorCode.NoRepairInfoFound:\r\n                    return Resources.NoRepairInfoFound;\r\n                case ErrorCode.RepairerFailure:\r\n                    return string.Format(Resources.RepairerFailure, repairerExitCode);\r\n                case ErrorCode.RepairNotSupported:\r\n                    return Resources.RepairOperationNotSupported;\r\n                case ErrorCode.RepairNotApplicable:\r\n                    return Resources.RepairDifferentInstallTechnology;\r\n                case ErrorCode.AdminContextRepairProhibited:\r\n                    return Resources.NoAdminRepairForUserScopePackage;\r\n                default:\r\n                    return string.Format(Resources.UnknownRepairFailure, hresult);\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Exceptions/WindowsPowerShellNotSupported.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"WindowsPowerShellNotSupported.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Exceptions\r\n{\r\n    using System;\r\n    using System.Management.Automation;\r\n    using Microsoft.WinGet.Resources;\r\n\r\n    /// <summary>\r\n    /// Windows PowerShell is not supported.\r\n    /// </summary>\r\n    [Serializable]\r\n    public class WindowsPowerShellNotSupported : RuntimeException\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"WindowsPowerShellNotSupported\"/> class.\r\n        /// </summary>\r\n        public WindowsPowerShellNotSupported()\r\n            : base(Resources.WindowsPowerShellNotSupported)\r\n        {\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Extensions/CatalogPackageExtensions.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"CatalogPackageExtensions.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Extensions\r\n{\r\n    using Microsoft.Management.Deployment;\r\n\r\n    /// <summary>\r\n    /// Extensions for the <see cref=\"CatalogPackage\" /> class.\r\n    /// </summary>\r\n    internal static class CatalogPackageExtensions\r\n    {\r\n        /// <summary>\r\n        /// Converts a <see cref=\"CatalogPackage\" /> to a string previewing the specified version.\r\n        /// </summary>\r\n        /// <param name=\"package\">A <see cref=\"CatalogPackage\" /> instance.</param>\r\n        /// <param name=\"version\">A <see cref=\"PackageVersionId\" /> instance. If null, the latest available version is used.</param>\r\n        /// <returns>A <see cref=\"string\" /> instance.</returns>\r\n        public static string ToString(\r\n            this CatalogPackage package,\r\n            PackageVersionId? version)\r\n        {\r\n            if ((version != null) || (package.AvailableVersions.Count > 0))\r\n            {\r\n                string versionString = (version is null)\r\n                    ? package.AvailableVersions[0].Version\r\n                    : version.Version;\r\n                return $\"{package.Name} [{package.Id}] Version {versionString}\";\r\n            }\r\n            else\r\n            {\r\n                // There were no available versions!\r\n                return $\"{package.Name} [{package.Id}]\";\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the best effort source name of a <see cref=\"CatalogPackage\" /> that matches its Id.\r\n        /// This source name is used together with Id in operation output classes for display purposes.\r\n        /// </summary>\r\n        /// <param name=\"package\">A <see cref=\"CatalogPackage\" /> instance.</param>\r\n        /// <returns>The best effort source name of the package.</returns>\r\n        public static string? GetSourceName(this CatalogPackage package)\r\n        {\r\n            for (int i = 0; i < package.AvailableVersions.Count; ++i)\r\n            {\r\n                var versionInfo = package.GetPackageVersionInfo(package.AvailableVersions[i]);\r\n                if (versionInfo.Id == package.Id)\r\n                {\r\n                    return versionInfo.PackageCatalog.Info.Name;\r\n                }\r\n            }\r\n\r\n            return null;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Extensions/ReleaseExtensions.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ReleaseExtensions.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Extensions\r\n{\r\n    using System.Linq;\r\n    using Microsoft.WinGet.Client.Engine.Exceptions;\r\n    using Microsoft.WinGet.Resources;\r\n    using Octokit;\r\n\r\n    /// <summary>\r\n    /// Extension methods for Octokit.Release.\r\n    /// </summary>\r\n    internal static class ReleaseExtensions\r\n    {\r\n        /// <summary>\r\n        /// Gets the Asset.\r\n        /// </summary>\r\n        /// <param name=\"release\">GitHub release.</param>\r\n        /// <param name=\"name\">Name of asset.</param>\r\n        /// <returns>The asset.</returns>\r\n        public static ReleaseAsset GetAsset(this Release release, string name)\r\n        {\r\n            var asset = TryGetAsset(release, name);\r\n\r\n            if (asset != null)\r\n            {\r\n                return asset;\r\n            }\r\n\r\n            throw new WinGetRepairException(string.Format(Resources.ReleaseAssetNotFound, name));\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the Asset if present.\r\n        /// </summary>\r\n        /// <param name=\"release\">GitHub release.</param>\r\n        /// <param name=\"name\">Name of asset.</param>\r\n        /// <returns>The asset, or null if not found.</returns>\r\n        public static ReleaseAsset? TryGetAsset(this Release release, string name)\r\n        {\r\n            var assets = release.Assets.Where(a => a.Name == name);\r\n            return assets.Any() ? assets.First() : null;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the asset that ends with the string.\r\n        /// </summary>\r\n        /// <param name=\"release\">GitHub release.</param>\r\n        /// <param name=\"name\">Asset last part name.</param>\r\n        /// <returns>The asset.</returns>\r\n        public static ReleaseAsset GetAssetEndsWith(this Release release, string name)\r\n        {\r\n            var assets = release.Assets.Where(a => a.Name.EndsWith(name));\r\n\r\n            if (assets.Any())\r\n            {\r\n                return assets.First();\r\n            }\r\n\r\n            throw new WinGetRepairException(string.Format(Resources.ReleaseAssetNotFound, name));\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Helpers/AppxModuleHelper.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"AppxModuleHelper.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Helpers\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.Collections.ObjectModel;\r\n    using System.IO;\r\n    using System.IO.Compression;\r\n    using System.Linq;\r\n    using System.Management.Automation;\r\n    using System.Runtime.InteropServices;\r\n    using System.Threading.Tasks;\r\n    using Microsoft.WinGet.Client.Engine.Common;\r\n    using Microsoft.WinGet.Client.Engine.Extensions;\r\n    using Microsoft.WinGet.Common.Command;\r\n    using Newtonsoft.Json;\r\n    using Octokit;\r\n    using Semver;\r\n    using static Microsoft.WinGet.Client.Engine.Common.Constants;\r\n\r\n    /// <summary>\r\n    /// Helper to make calls to the Appx module.\r\n    /// </summary>\r\n    internal class AppxModuleHelper\r\n    {\r\n        // Cmdlets\r\n        private const string ImportModule = \"Import-Module\";\r\n        private const string GetAppxPackage = \"Get-AppxPackage\";\r\n        private const string AddAppxPackage = \"Add-AppxPackage\";\r\n        private const string AddAppxProvisionedPackage = \"Add-AppxProvisionedPackage\";\r\n        private const string GetCommand = \"Get-Command\";\r\n\r\n        // Parameters name\r\n        private const string Name = \"Name\";\r\n        private const string Path = \"Path\";\r\n        private const string ErrorAction = \"ErrorAction\";\r\n        private const string WarningAction = \"WarningAction\";\r\n        private const string PackagePath = \"PackagePath\";\r\n        private const string LicensePath = \"LicensePath\";\r\n        private const string Module = \"Module\";\r\n        private const string StubPackageOption = \"StubPackageOption\";\r\n        private const string PackageTypeFilter = \"PackageTypeFilter\";\r\n\r\n        // Parameter Values\r\n        private const string Appx = \"Appx\";\r\n        private const string Stop = \"Stop\";\r\n        private const string SilentlyContinue = \"SilentlyContinue\";\r\n        private const string Online = \"Online\";\r\n        private const string UsePreference = \"UsePreference\";\r\n        private const string Framework = \"Framework\";\r\n\r\n        // Options\r\n        private const string UseWindowsPowerShell = \"UseWindowsPowerShell\";\r\n        private const string ForceUpdateFromAnyVersion = \"ForceUpdateFromAnyVersion\";\r\n        private const string Register = \"Register\";\r\n        private const string DisableDevelopmentMode = \"DisableDevelopmentMode\";\r\n        private const string ForceTargetApplicationShutdown = \"ForceTargetApplicationShutdown\";\r\n        private const string AllUsers = \"AllUsers\";\r\n\r\n        private const string AppInstallerName = \"Microsoft.DesktopAppInstaller\";\r\n        private const string AppxManifest = \"AppxManifest.xml\";\r\n        private const string PackageFullName = \"PackageFullName\";\r\n        private const string Version = \"Version\";\r\n\r\n        private const string DependencyArchitectureEnvironmentVariable = \"WINGET_PACKAGE_MANAGER_REPAIR_DEPENDENCY_ARCHITECTURES\";\r\n\r\n        // Assets\r\n        private const string MsixBundleName = \"Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle\";\r\n        private const string DependenciesJsonName = \"DesktopAppInstaller_Dependencies.json\";\r\n        private const string DependenciesZipName = \"DesktopAppInstaller_Dependencies.zip\";\r\n        private const string License = \"License1.xml\";\r\n\r\n        // Format of a dependency package such as 'x64\\Microsoft.VCLibs.140.00.UWPDesktop_14.0.33728.0_x64.appx'\r\n        private const string ExtractedDependencyPath = \"{0}\\\\{1}_{2}_{0}.appx\";\r\n\r\n        // Dependencies\r\n        // VCLibs\r\n        private const string VCLibsUWPDesktop = \"Microsoft.VCLibs.140.00.UWPDesktop\";\r\n        private const string VCLibsUWPDesktopVersion = \"14.0.30704.0\";\r\n        private const string VCLibsUWPDesktopX64 = \"https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx\";\r\n        private const string VCLibsUWPDesktopX86 = \"https://aka.ms/Microsoft.VCLibs.x86.14.00.Desktop.appx\";\r\n        private const string VCLibsUWPDesktopArm64 = \"https://aka.ms/Microsoft.VCLibs.arm64.14.00.Desktop.appx\";\r\n\r\n        // Xaml\r\n        private const string XamlPackage28 = \"Microsoft.UI.Xaml.2.8\";\r\n        private const string XamlReleaseTag286 = \"v2.8.6\";\r\n        private const string MinimumWinGetReleaseTagForXaml28 = \"v1.7.10514\";\r\n\r\n        private const string XamlPackage27 = \"Microsoft.UI.Xaml.2.7\";\r\n        private const string XamlReleaseTag273 = \"v2.7.3\";\r\n\r\n        // WinGet Source\r\n        private const string WinGetSourceName = \"Microsoft.Winget.Source\";\r\n        private const string WinGetSourceMsixName = \"source2.msix\";\r\n        private const string WinGetSourceUrl = $\"https://cdn.winget.microsoft.com/cache/{WinGetSourceMsixName}\";\r\n\r\n        private readonly PowerShellCmdlet pwshCmdlet;\r\n        private readonly HttpClientHelper httpClientHelper;\r\n        private Lazy<HashSet<Architecture>> frameworkArchitectures;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"AppxModuleHelper\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"pwshCmdlet\">The calling cmdlet.</param>\r\n        public AppxModuleHelper(PowerShellCmdlet pwshCmdlet)\r\n        {\r\n            this.pwshCmdlet = pwshCmdlet;\r\n            this.httpClientHelper = new HttpClientHelper();\r\n            this.frameworkArchitectures = new Lazy<HashSet<Architecture>>(() => this.InitFrameworkArchitectures());\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls Get-AppxPackage Microsoft.DesktopAppInstaller.\r\n        /// </summary>\r\n        /// <param name=\"allUsers\">Whether to get for all users.</param>\r\n        /// <returns>Result of Get-AppxPackage.</returns>\r\n        public PSObject? GetAppInstallerObject(bool allUsers = false)\r\n        {\r\n            return this.GetAppxObject(AppInstallerName, allUsers);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls Get-AppxPackage Microsoft.Winget.Source.\r\n        /// </summary>\r\n        /// <returns>Result of Get-AppxPackage.</returns>\r\n        public PSObject? GetWinGetSourceObject()\r\n        {\r\n            return this.GetAppxObject(WinGetSourceName);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the string value a property from the Get-AppxPackage object of AppInstaller.\r\n        /// </summary>\r\n        /// <param name=\"propertyName\">Property name.</param>\r\n        /// <param name=\"allUsers\">Whether to get for all users.</param>\r\n        /// <returns>Value, null if doesn't exist.</returns>\r\n        public string? GetAppInstallerPropertyValue(string propertyName, bool allUsers = false)\r\n        {\r\n            string? result = null;\r\n            var packageObj = this.GetAppInstallerObject(allUsers);\r\n            if (packageObj is not null)\r\n            {\r\n                var property = packageObj.Properties.Where(p => p.Name == propertyName).FirstOrDefault();\r\n                if (property is not null)\r\n                {\r\n                    result = property.Value as string;\r\n                }\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Checks if winget source is installed.\r\n        /// </summary>\r\n        /// <returns>True if installed.</returns>\r\n        public bool IsWinGetSourceInstalled()\r\n        {\r\n            return this.GetWinGetSourceObject() is not null;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls Add-AppxPackage to register with AppInstaller's AppxManifest.xml.\r\n        /// </summary>\r\n        /// <param name=\"releaseTag\">Release tag of GitHub release.</param>\r\n        /// <param name=\"allUsers\">Whether to register for all users.</param>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous operation.</returns>\r\n        public async Task RegisterAppInstallerAsync(string releaseTag, bool allUsers)\r\n        {\r\n            if (string.IsNullOrEmpty(releaseTag))\r\n            {\r\n                string? versionFromLocalPackage = this.GetAppInstallerPropertyValue(Version, allUsers);\r\n\r\n                if (versionFromLocalPackage == null)\r\n                {\r\n                    throw new ArgumentNullException(Version);\r\n                }\r\n\r\n                var packageVersion = new Version(versionFromLocalPackage);\r\n                if (packageVersion.Major == 1 && packageVersion.Minor > 15 && packageVersion.Minor < 28)\r\n                {\r\n                    releaseTag = $\"v1.{packageVersion.Minor - 15}.{packageVersion.Build}\";\r\n                }\r\n                else\r\n                {\r\n                    releaseTag = $\"v{packageVersion.Major}.{packageVersion.Minor}.{packageVersion.Build}\";\r\n                }\r\n            }\r\n\r\n            // Ensure that all dependencies are present when attempting to register.\r\n            // If dependencies are missing, a provisioned package can appear to only need registration,\r\n            // but will fail to register. `InstallDependenciesAsync` checks for the packages before\r\n            // acting, so it should be mostly a no-op if they are already available.\r\n            await this.InstallDependenciesAsync(releaseTag);\r\n\r\n            this.RegisterAppInstallerInternal(allUsers);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Install AppInstaller's bundle from a GitHub release.\r\n        /// </summary>\r\n        /// <param name=\"releaseTag\">Release tag of GitHub release.</param>\r\n        /// <param name=\"allUsers\">If install for all users is needed.</param>\r\n        /// <param name=\"isDowngrade\">Is downgrade.</param>\r\n        /// <param name=\"force\">Force application shutdown.</param>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous operation.</returns>\r\n        public async Task InstallFromGitHubReleaseAsync(string releaseTag, bool allUsers, bool isDowngrade, bool force)\r\n        {\r\n            await this.InstallDependenciesAsync(releaseTag);\r\n\r\n            if (isDowngrade)\r\n            {\r\n                // Add-AppxProvisionedPackage doesn't support downgrade.\r\n                await this.AddAppInstallerBundleAsync(releaseTag, true, force);\r\n\r\n                if (allUsers)\r\n                {\r\n                    await this.AddProvisionPackageAsync(releaseTag);\r\n                }\r\n            }\r\n            else\r\n            {\r\n                if (allUsers)\r\n                {\r\n                    await this.AddProvisionPackageAsync(releaseTag);\r\n                }\r\n                else\r\n                {\r\n                    await this.AddAppInstallerBundleAsync(releaseTag, false, force);\r\n                }\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Installs the WinGet source by downloading and adding package.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous operation.</returns>\r\n        public async Task InstallWinGetSourceAsync()\r\n        {\r\n            await this.DownloadPackageAndAddAsync(WinGetSourceUrl, WinGetSourceMsixName, options: null);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the Xaml dependency package name and release tag based on the provided WinGet release tag.\r\n        /// </summary>\r\n        /// <param name=\"releaseTag\">WinGet release tag.</param>\r\n        /// <returns>A tuple in the format of (XamlPackageName, XamlReleaseTag).</returns>\r\n        private static Tuple<string, string> GetXamlDependencyVersionInfo(string releaseTag)\r\n        {\r\n            var targetVersion = SemVersion.Parse(releaseTag, SemVersionStyles.AllowLowerV);\r\n\r\n            if (targetVersion.CompareSortOrderTo(SemVersion.Parse(MinimumWinGetReleaseTagForXaml28, SemVersionStyles.AllowLowerV)) >= 0)\r\n            {\r\n                return Tuple.Create(XamlPackage28, XamlReleaseTag286);\r\n            }\r\n            else\r\n            {\r\n                return Tuple.Create(XamlPackage27, XamlReleaseTag273);\r\n            }\r\n        }\r\n\r\n        private async Task AddProvisionPackageAsync(string releaseTag)\r\n        {\r\n            var githubClient = new GitHubClient(RepositoryOwner.Microsoft, RepositoryName.WinGetCli, this.pwshCmdlet);\r\n            var release = await githubClient.GetReleaseAsync(releaseTag);\r\n\r\n            var bundleAsset = release.GetAsset(MsixBundleName);\r\n            using var bundleFile = new TempFile(fileName: MsixBundleName);\r\n            await this.httpClientHelper.DownloadUrlWithProgressAsync(\r\n                bundleAsset.BrowserDownloadUrl, bundleFile.FullPath, this.pwshCmdlet);\r\n\r\n            var licenseAsset = release.GetAssetEndsWith(License);\r\n            using var licenseFile = new TempFile(fileName: licenseAsset.Name);\r\n            await this.httpClientHelper.DownloadUrlWithProgressAsync(\r\n                licenseAsset.BrowserDownloadUrl, licenseFile.FullPath, this.pwshCmdlet);\r\n\r\n            try\r\n            {\r\n                this.pwshCmdlet.ExecuteInPowerShellThread(\r\n                    () =>\r\n                    {\r\n                        var ps = PowerShell.Create(RunspaceMode.CurrentRunspace);\r\n                        ps.AddCommand(AddAppxProvisionedPackage)\r\n                          .AddParameter(Online)\r\n                          .AddParameter(PackagePath, bundleFile.FullPath)\r\n                          .AddParameter(LicensePath, licenseFile.FullPath)\r\n                          .AddParameter(ErrorAction, Stop)\r\n                          .Invoke();\r\n                    });\r\n\r\n                // Register the package after provisioning so that it is\r\n                // available immediately.\r\n                this.RegisterAppInstallerInternal(allUsers: true);\r\n            }\r\n            catch (RuntimeException e)\r\n            {\r\n                this.pwshCmdlet.Write(StreamType.Verbose, $\"Failed installing bundle via Add-AppxProvisionedPackage {e}\");\r\n                throw;\r\n            }\r\n        }\r\n\r\n        private async Task AddAppInstallerBundleAsync(string releaseTag, bool downgrade, bool force)\r\n        {\r\n            var options = new List<string>();\r\n            if (downgrade)\r\n            {\r\n                options.Add(ForceUpdateFromAnyVersion);\r\n            }\r\n\r\n            if (force)\r\n            {\r\n                options.Add(ForceTargetApplicationShutdown);\r\n            }\r\n\r\n            var parameters = new Dictionary<string, object>();\r\n            if (this.IsStubPackageOptionPresent())\r\n            {\r\n                parameters.Add(StubPackageOption, UsePreference);\r\n            }\r\n\r\n            try\r\n            {\r\n                var githubClient = new GitHubClient(RepositoryOwner.Microsoft, RepositoryName.WinGetCli, this.pwshCmdlet);\r\n                var release = await githubClient.GetReleaseAsync(releaseTag);\r\n\r\n                var bundleAsset = release.GetAsset(MsixBundleName);\r\n                await this.AddAppxPackageAsUriAsync(bundleAsset.BrowserDownloadUrl, MsixBundleName, parameters, options);\r\n            }\r\n            catch (RuntimeException e)\r\n            {\r\n                this.pwshCmdlet.Write(StreamType.Verbose, $\"Failed installing bundle via Add-AppxPackage {e}\");\r\n                throw;\r\n            }\r\n        }\r\n\r\n        private PSObject? GetAppxObject(string packageName, bool allUsers = false)\r\n        {\r\n            var options = new List<string>();\r\n            if (allUsers)\r\n            {\r\n                options.Add(AllUsers);\r\n            }\r\n\r\n            return this.ExecuteAppxCmdlet(\r\n                GetAppxPackage,\r\n                new Dictionary<string, object>\r\n                {\r\n                    { Name, packageName },\r\n                },\r\n                options)\r\n                .FirstOrDefault();\r\n        }\r\n\r\n        private async Task InstallDependenciesAsync(string releaseTag)\r\n        {\r\n            bool result = await this.InstallDependenciesFromGitHubArchive(releaseTag);\r\n\r\n            if (!result)\r\n            {\r\n                // A better implementation would use Add-AppxPackage with -DependencyPath, but\r\n                // the Appx module needs to be remoted into Windows PowerShell. When the string[] parameter\r\n                // gets deserialized from Core the result is a single string which breaks Add-AppxPackage.\r\n                // Here we should: if we are in Windows Powershell then run Add-AppxPackage with -DependencyPath\r\n                // if we are in Core, then start powershell.exe and run the same command. Right now, we just\r\n                // do Add-AppxPackage for each one.\r\n                // This method no longer works for versions >1.9 as the vclibs url has been deprecated.\r\n                await this.InstallVCLibsDependenciesFromUriAsync();\r\n                await this.InstallUiXamlAsync(releaseTag);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Extracts all of the architectures used by framework packages.\r\n        /// </summary>\r\n        /// <returns>The set of architectures used by installed framework packages.</returns>\r\n        private HashSet<Architecture> InitFrameworkArchitectures()\r\n        {\r\n            HashSet<Architecture> architectures = new HashSet<Architecture>();\r\n\r\n            // Read the override from the environment variable if it exists.\r\n            string? environmentVariable = Environment.GetEnvironmentVariable(DependencyArchitectureEnvironmentVariable);\r\n            if (environmentVariable != null)\r\n            {\r\n                this.pwshCmdlet.Write(StreamType.Verbose, $\"Using environment variable {DependencyArchitectureEnvironmentVariable} for frameworks: {environmentVariable}\");\r\n\r\n                foreach (string architectureString in environmentVariable.Split(',', ';'))\r\n                {\r\n                    Architecture architecture;\r\n                    if (Enum.TryParse(architectureString, true, out architecture))\r\n                    {\r\n                        if (architectures.Add(architecture))\r\n                        {\r\n                            this.pwshCmdlet.Write(StreamType.Verbose, $\"Framework architecture from environment variable: {architectureString}\");\r\n                        }\r\n                    }\r\n                }\r\n\r\n                return architectures;\r\n            }\r\n\r\n            // If there are any framework packages already installed, use the same architecture as them.\r\n            var result = this.ExecuteAppxCmdlet(\r\n                GetAppxPackage,\r\n                new Dictionary<string, object>\r\n                {\r\n                    { PackageTypeFilter, Framework },\r\n                });\r\n\r\n            if (result != null &&\r\n                result.Count > 0)\r\n            {\r\n                foreach (dynamic psobject in result)\r\n                {\r\n                    string? architectureString = psobject?.Architecture?.ToString();\r\n                    if (architectureString == null)\r\n                    {\r\n                        continue;\r\n                    }\r\n\r\n                    Architecture architecture;\r\n                    if (Enum.TryParse(architectureString, true, out architecture))\r\n                    {\r\n                        if (architectures.Add(architecture))\r\n                        {\r\n                            this.pwshCmdlet.Write(StreamType.Verbose, $\"Found framework architecture: {architectureString}\");\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Fall back to guessing from the current OS architecture.\r\n            // This may have issues on ARM64 because RuntimeInformation.OSArchitecture seems to just lie sometimes.\r\n            // See https://github.com/microsoft/winget-cli/issues/5020\r\n            if (architectures.Count == 0)\r\n            {\r\n                var arch = RuntimeInformation.OSArchitecture;\r\n                this.pwshCmdlet.Write(StreamType.Verbose, $\"OS architecture: {arch.ToString()}\");\r\n\r\n                if (arch == Architecture.X64)\r\n                {\r\n                    architectures.Add(Architecture.X64);\r\n                }\r\n                else if (arch == Architecture.X86)\r\n                {\r\n                    architectures.Add(Architecture.X86);\r\n                }\r\n                else if (arch == Architecture.Arm64)\r\n                {\r\n                    // Let deployment figure it out\r\n                    architectures.Add(Architecture.Arm64);\r\n                    architectures.Add(Architecture.X64);\r\n                    architectures.Add(Architecture.X86);\r\n                }\r\n            }\r\n\r\n            return architectures;\r\n        }\r\n\r\n        private Dictionary<string, string> GetDependenciesByArch(PackageDependency dependencies)\r\n        {\r\n            Dictionary<string, string> appxPackages = new Dictionary<string, string>();\r\n\r\n            foreach (var architecture in this.frameworkArchitectures.Value)\r\n            {\r\n                switch (architecture)\r\n                {\r\n                    case Architecture.X86:\r\n                        appxPackages.Add(\"x86\", string.Format(ExtractedDependencyPath, \"x86\", dependencies.Name, dependencies.Version));\r\n                        break;\r\n                    case Architecture.X64:\r\n                        appxPackages.Add(\"x64\", string.Format(ExtractedDependencyPath, \"x64\", dependencies.Name, dependencies.Version));\r\n                        break;\r\n                    case Architecture.Arm64:\r\n                        appxPackages.Add(\"arm64\", string.Format(ExtractedDependencyPath, \"arm64\", dependencies.Name, dependencies.Version));\r\n                        break;\r\n                    default:\r\n                        this.pwshCmdlet.Write(StreamType.Verbose, $\"GetDependenciesByArch: Ignoring {architecture}\");\r\n                        break;\r\n                }\r\n            }\r\n\r\n            return appxPackages;\r\n        }\r\n\r\n        private void FindMissingDependencies(Dictionary<string, string> dependencies, string packageName, string requiredVersion)\r\n        {\r\n            var result = this.ExecuteAppxCmdlet(\r\n                GetAppxPackage,\r\n                new Dictionary<string, object>\r\n                {\r\n                    { Name, packageName },\r\n                });\r\n\r\n            Version minimumVersion = new Version(requiredVersion);\r\n\r\n            if (result != null &&\r\n                result.Count > 0)\r\n            {\r\n                foreach (dynamic psobject in result)\r\n                {\r\n                    string? versionString = psobject?.Version?.ToString();\r\n                    if (versionString == null)\r\n                    {\r\n                        continue;\r\n                    }\r\n\r\n                    Version packageVersion = new Version(versionString);\r\n\r\n                    if (packageVersion >= minimumVersion)\r\n                    {\r\n                        string? architectureString = psobject?.Architecture?.ToString();\r\n                        if (architectureString == null)\r\n                        {\r\n                            this.pwshCmdlet.Write(StreamType.Verbose, $\"{packageName} dependency has no architecture value: {psobject?.PackageFullName ?? \"<null>\"}\");\r\n                            continue;\r\n                        }\r\n\r\n                        architectureString = architectureString.ToLower();\r\n\r\n                        if (dependencies.ContainsKey(architectureString))\r\n                        {\r\n                            this.pwshCmdlet.Write(StreamType.Verbose, $\"{packageName} {architectureString} dependency satisfied by: {psobject?.PackageFullName ?? \"<null>\"}\");\r\n                            dependencies.Remove(architectureString);\r\n                        }\r\n                    }\r\n                    else\r\n                    {\r\n                        this.pwshCmdlet.Write(StreamType.Verbose, $\"{packageName} is lower than minimum required version [{minimumVersion}]: {psobject?.PackageFullName ?? \"<null>\"}\");\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        private async Task InstallVCLibsDependenciesFromUriAsync()\r\n        {\r\n            Dictionary<string, string> vcLibsDependencies = this.GetVCLibsDependencies();\r\n            this.FindMissingDependencies(vcLibsDependencies, VCLibsUWPDesktop, VCLibsUWPDesktopVersion);\r\n\r\n            if (vcLibsDependencies.Count != 0)\r\n            {\r\n                this.pwshCmdlet.Write(StreamType.Verbose, \"Couldn't find required VCLibs packages\");\r\n\r\n                foreach (var vclibPair in vcLibsDependencies)\r\n                {\r\n                    string vclib = vclibPair.Value;\r\n                    await this.AddAppxPackageAsUriAsync(vclib, vclib.Substring(vclib.LastIndexOf('/') + 1));\r\n                }\r\n            }\r\n            else\r\n            {\r\n                this.pwshCmdlet.Write(StreamType.Verbose, $\"VCLibs are updated.\");\r\n            }\r\n        }\r\n\r\n        // Returns a boolean value indicating whether dependencies were successfully installed from the GitHub release assets.\r\n        private async Task<bool> InstallDependenciesFromGitHubArchive(string releaseTag)\r\n        {\r\n            var githubClient = new GitHubClient(RepositoryOwner.Microsoft, RepositoryName.WinGetCli, this.pwshCmdlet);\r\n            var release = await githubClient.GetReleaseAsync(releaseTag);\r\n\r\n            ReleaseAsset? dependenciesJsonAsset = release.TryGetAsset(DependenciesJsonName);\r\n            if (dependenciesJsonAsset is null)\r\n            {\r\n                return false;\r\n            }\r\n\r\n            using var dependenciesJsonFile = new TempFile();\r\n            await this.httpClientHelper.DownloadUrlWithProgressAsync(dependenciesJsonAsset.BrowserDownloadUrl, dependenciesJsonFile.FullPath, this.pwshCmdlet);\r\n\r\n            using StreamReader r = new StreamReader(dependenciesJsonFile.FullPath);\r\n            string json = r.ReadToEnd();\r\n            WingetDependencies? wingetDependencies = JsonConvert.DeserializeObject<WingetDependencies>(json);\r\n\r\n            if (wingetDependencies is null)\r\n            {\r\n                this.pwshCmdlet.Write(StreamType.Verbose, $\"Failed to deserialize dependencies json file.\");\r\n                return false;\r\n            }\r\n\r\n            List<string> missingDependencies = new List<string>();\r\n            foreach (var dependency in wingetDependencies.Dependencies)\r\n            {\r\n                Dictionary<string, string> dependenciesByArch = this.GetDependenciesByArch(dependency);\r\n                this.FindMissingDependencies(dependenciesByArch, dependency.Name, dependency.Version);\r\n\r\n                foreach (var pair in dependenciesByArch)\r\n                {\r\n                    missingDependencies.Add(pair.Value);\r\n                }\r\n            }\r\n\r\n            if (missingDependencies.Count != 0)\r\n            {\r\n                using var dependenciesZipFile = new TempFile();\r\n                using var extractedDirectory = new TempDirectory();\r\n\r\n                ReleaseAsset? dependenciesZipAsset = release.TryGetAsset(DependenciesZipName);\r\n                if (dependenciesZipAsset is null)\r\n                {\r\n                    this.pwshCmdlet.Write(StreamType.Verbose, $\"Dependencies zip asset not found on GitHub asset.\");\r\n                    return false;\r\n                }\r\n\r\n                await this.httpClientHelper.DownloadUrlWithProgressAsync(dependenciesZipAsset.BrowserDownloadUrl, dependenciesZipFile.FullPath, this.pwshCmdlet);\r\n                ZipFile.ExtractToDirectory(dependenciesZipFile.FullPath, extractedDirectory.FullDirectoryPath);\r\n\r\n                foreach (var entry in missingDependencies)\r\n                {\r\n                    string fullPath = System.IO.Path.Combine(extractedDirectory.FullDirectoryPath, entry);\r\n                    if (!File.Exists(fullPath))\r\n                    {\r\n                        this.pwshCmdlet.Write(StreamType.Verbose, $\"Package dependency not found in archive: {fullPath}\");\r\n                        return false;\r\n                    }\r\n\r\n                    _ = this.ExecuteAppxCmdlet(\r\n                            AddAppxPackage,\r\n                            new Dictionary<string, object>\r\n                            {\r\n                            { Path, fullPath },\r\n                            { ErrorAction, Stop },\r\n                            });\r\n                }\r\n            }\r\n\r\n            return true;\r\n        }\r\n\r\n        private Dictionary<string, string> GetVCLibsDependencies()\r\n        {\r\n            Dictionary<string, string> vcLibsDependencies = new Dictionary<string, string>();\r\n\r\n            foreach (var architecture in this.frameworkArchitectures.Value)\r\n            {\r\n                switch (architecture)\r\n                {\r\n                    case Architecture.X86:\r\n                        vcLibsDependencies.Add(\"x86\", VCLibsUWPDesktopX86);\r\n                        break;\r\n                    case Architecture.X64:\r\n                        vcLibsDependencies.Add(\"x64\", VCLibsUWPDesktopX64);\r\n                        break;\r\n                    case Architecture.Arm64:\r\n                        vcLibsDependencies.Add(\"arm64\", VCLibsUWPDesktopArm64);\r\n                        break;\r\n                    default:\r\n                        this.pwshCmdlet.Write(StreamType.Verbose, $\"GetVCLibsDependencies: Ignoring {architecture}\");\r\n                        break;\r\n                }\r\n            }\r\n\r\n            return vcLibsDependencies;\r\n        }\r\n\r\n        private async Task InstallUiXamlAsync(string releaseTag)\r\n        {\r\n            (string xamlPackageName, string xamlReleaseTag) = GetXamlDependencyVersionInfo(releaseTag);\r\n            string xamlAssetX64 = string.Format(\"{0}.x64.appx\", xamlPackageName);\r\n            string xamlAssetX86 = string.Format(\"{0}.x86.appx\", xamlPackageName);\r\n            string xamlAssetArm64 = string.Format(\"{0}.arm64.appx\", xamlPackageName);\r\n\r\n            var uiXamlObjs = this.GetAppxObject(xamlPackageName);\r\n            if (uiXamlObjs is null)\r\n            {\r\n                var githubRelease = new GitHubClient(RepositoryOwner.Microsoft, RepositoryName.UiXaml, this.pwshCmdlet);\r\n\r\n                var xamlRelease = await githubRelease.GetReleaseAsync(xamlReleaseTag);\r\n\r\n                var packagesToInstall = new List<ReleaseAsset>();\r\n\r\n                foreach (var architecture in this.frameworkArchitectures.Value)\r\n                {\r\n                    switch (architecture)\r\n                    {\r\n                        case Architecture.X86:\r\n                            packagesToInstall.Add(xamlRelease.GetAsset(xamlAssetX86));\r\n                            break;\r\n                        case Architecture.X64:\r\n                            packagesToInstall.Add(xamlRelease.GetAsset(xamlAssetX64));\r\n                            break;\r\n                        case Architecture.Arm64:\r\n                            packagesToInstall.Add(xamlRelease.GetAsset(xamlAssetArm64));\r\n                            break;\r\n                        default:\r\n                            this.pwshCmdlet.Write(StreamType.Verbose, $\"InstallUiXamlAsync: Ignoring {architecture}\");\r\n                            break;\r\n                    }\r\n                }\r\n\r\n                foreach (var package in packagesToInstall)\r\n                {\r\n                    await this.AddAppxPackageAsUriAsync(package.BrowserDownloadUrl, package.Name);\r\n                }\r\n            }\r\n        }\r\n\r\n        private async Task AddAppxPackageAsUriAsync(string packageUri, string fileName, Dictionary<string, object>? parameters = null, IList<string>? options = null)\r\n        {\r\n            try\r\n            {\r\n                var thisParams = new Dictionary<string, object>\r\n                {\r\n                    { Path, packageUri },\r\n                    { ErrorAction, Stop },\r\n                };\r\n\r\n                if (parameters != null)\r\n                {\r\n                    foreach (var param in parameters)\r\n                    {\r\n                        thisParams.Add(param.Key, param.Value);\r\n                    }\r\n                }\r\n\r\n                _ = this.ExecuteAppxCmdlet(\r\n                        AddAppxPackage,\r\n                        thisParams,\r\n                        options);\r\n            }\r\n            catch (RuntimeException e)\r\n            {\r\n                // If we couldn't install it via URI, try download and install.\r\n                if (e.ErrorRecord.CategoryInfo.Category == ErrorCategory.OpenError)\r\n                {\r\n                    this.pwshCmdlet.Write(StreamType.Verbose, $\"Failed adding package [{packageUri}]. Retrying downloading it.\");\r\n                    await this.DownloadPackageAndAddAsync(packageUri, fileName, options);\r\n                }\r\n                else\r\n                {\r\n                    this.pwshCmdlet.Write(StreamType.Error, e.ErrorRecord);\r\n                    throw;\r\n                }\r\n            }\r\n        }\r\n\r\n        private async Task DownloadPackageAndAddAsync(string packageUrl, string fileName, IList<string>? options)\r\n        {\r\n            using var tempFile = new TempFile(fileName: fileName);\r\n\r\n            await this.httpClientHelper.DownloadUrlWithProgressAsync(packageUrl, tempFile.FullPath, this.pwshCmdlet);\r\n\r\n            _ = this.ExecuteAppxCmdlet(\r\n                    AddAppxPackage,\r\n                    new Dictionary<string, object>\r\n                    {\r\n                        { Path, tempFile.FullPath },\r\n                        { ErrorAction, Stop },\r\n                    },\r\n                    options);\r\n        }\r\n\r\n        private Collection<PSObject> ExecuteAppxCmdlet(string cmdlet, Dictionary<string, object>? parameters = null, IList<string>? options = null)\r\n        {\r\n            Collection<PSObject> result = new Collection<PSObject>();\r\n\r\n            this.pwshCmdlet.ExecuteInPowerShellThread(\r\n                () =>\r\n                {\r\n                    var ps = PowerShell.Create(RunspaceMode.CurrentRunspace);\r\n\r\n                    // There's a bug in the Appx Module that it can't be loaded from Core in pre 10.0.22453.0 builds without\r\n                    // the -UseWindowsPowerShell option. In post 10.0.22453.0 builds there's really no difference between\r\n                    // using or not -UseWindowsPowerShell as it will automatically get loaded using WinPSCompatSession remoting session.\r\n                    // https://github.com/PowerShell/PowerShell/issues/13138.\r\n                    // Set warning action to silently continue to avoid the console with\r\n                    // 'Module Appx is loaded in Windows PowerShell using WinPSCompatSession remoting session'\r\n#if !POWERSHELL_WINDOWS\r\n                    ps.AddCommand(ImportModule)\r\n                      .AddParameter(Name, Appx)\r\n                      .AddParameter(UseWindowsPowerShell)\r\n                      .AddParameter(WarningAction, SilentlyContinue)\r\n                      .AddStatement();\r\n#endif\r\n\r\n                    string cmd = cmdlet;\r\n                    ps.AddCommand(cmdlet);\r\n\r\n                    if (parameters != null)\r\n                    {\r\n                        foreach (var p in parameters)\r\n                        {\r\n                            cmd += $\" -{p.Key} {p.Value}\";\r\n                        }\r\n\r\n                        ps.AddParameters(parameters);\r\n                    }\r\n\r\n                    if (options != null)\r\n                    {\r\n                        foreach (var option in options)\r\n                        {\r\n                            cmd += $\" -{option}\";\r\n                            ps.AddParameter(option);\r\n                        }\r\n                    }\r\n\r\n                    this.pwshCmdlet.Write(StreamType.Verbose, $\"Executing Appx cmdlet {cmd}\");\r\n                    result = ps.Invoke();\r\n                });\r\n\r\n            return result;\r\n        }\r\n\r\n        private bool IsStubPackageOptionPresent()\r\n        {\r\n            bool result = false;\r\n            this.pwshCmdlet.ExecuteInPowerShellThread(\r\n                () =>\r\n                {\r\n                    var ps = PowerShell.Create(RunspaceMode.CurrentRunspace);\r\n\r\n#if !POWERSHELL_WINDOWS\r\n                    ps.AddCommand(ImportModule)\r\n                      .AddParameter(Name, Appx)\r\n                      .AddParameter(UseWindowsPowerShell)\r\n                      .AddParameter(WarningAction, SilentlyContinue)\r\n                      .AddStatement();\r\n#endif\r\n\r\n                    var cmdInfo = ps.AddCommand(GetCommand)\r\n                                    .AddParameter(Name, AddAppxPackage)\r\n                                    .AddParameter(Module, Appx)\r\n                                    .Invoke<CommandInfo>()\r\n                                    .FirstOrDefault();\r\n\r\n                    result = cmdInfo != null && cmdInfo.Parameters.ContainsKey(StubPackageOption);\r\n                });\r\n\r\n            return result;\r\n        }\r\n\r\n        private void RegisterAppInstallerInternal(bool allUsers = false)\r\n        {\r\n            string? packageFullName = this.GetAppInstallerPropertyValue(PackageFullName, allUsers);\r\n\r\n            if (packageFullName == null)\r\n            {\r\n                throw new ArgumentNullException(PackageFullName);\r\n            }\r\n\r\n            string appxManifestPath = System.IO.Path.Combine(\r\n                Utilities.ProgramFilesWindowsAppPath,\r\n                packageFullName,\r\n                AppxManifest);\r\n\r\n            _ = this.ExecuteAppxCmdlet(\r\n                AddAppxPackage,\r\n                new Dictionary<string, object>\r\n                {\r\n                    { Path, appxManifestPath },\r\n                },\r\n                new List<string>\r\n                {\r\n                    Register,\r\n                    DisableDevelopmentMode,\r\n                });\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Helpers/DownloadOperationWithProgress.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"DownloadOperationWithProgress.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Helpers\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.WinGet.Common.Command;\r\n    using Microsoft.WinGet.Resources;\r\n    using Windows.Foundation;\r\n\r\n    /// <summary>\r\n    /// Handler progress for package download.\r\n    /// </summary>\r\n    internal class DownloadOperationWithProgress : OperationWithProgressBase<DownloadResult, PackageDownloadProgress>\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"DownloadOperationWithProgress\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"pwshCmdlet\">A <see cref=\"PowerShellCmdlet\" /> instance.</param>\r\n        /// <param name=\"activity\">Activity.</param>\r\n        public DownloadOperationWithProgress(PowerShellCmdlet pwshCmdlet, string activity)\r\n            : base(pwshCmdlet, activity)\r\n        {\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public override void Progress(IAsyncOperationWithProgress<DownloadResult, PackageDownloadProgress> operation, PackageDownloadProgress progress)\r\n        {\r\n            ProgressRecord record = new (this.ActivityId, this.Activity, progress.State.ToString())\r\n            {\r\n                RecordType = ProgressRecordType.Processing,\r\n            };\r\n            record.StatusDescription = Resources.DownloadingMessage;\r\n            record.PercentComplete = (int)(progress.DownloadProgress * 100);\r\n            this.PwshCmdlet.Write(StreamType.Progress, record);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Helpers/GitHubClient.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"GitHubClient.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Helpers\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.Linq;\r\n    using System.Threading.Tasks;\r\n    using Microsoft.WinGet.Common.Command;\r\n    using Octokit;\r\n    using static Microsoft.WinGet.Client.Engine.Common.Constants;\r\n\r\n    /// <summary>\r\n    /// Handles GitHub interactions.\r\n    /// </summary>\r\n    internal class GitHubClient\r\n    {\r\n        private readonly string owner;\r\n        private readonly string repo;\r\n        private readonly IGitHubClient gitHubClient;\r\n        private readonly PowerShellCmdlet? pwshCmdlet;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"GitHubClient\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"owner\">Owner.</param>\r\n        /// <param name=\"repo\">Repository.</param>\r\n        /// <param name=\"pwshCmdlet\">Optional PowerShell cmdlet for logging.</param>\r\n        public GitHubClient(string owner, string repo, PowerShellCmdlet? pwshCmdlet = null)\r\n        {\r\n            this.pwshCmdlet = pwshCmdlet;\r\n            var octokitClient = new Octokit.GitHubClient(new ProductHeaderValue(HttpClientHelper.UserAgent));\r\n\r\n            string? token = ResolveGitHubToken(pwshCmdlet);\r\n            if (!string.IsNullOrWhiteSpace(token))\r\n            {\r\n                octokitClient.Credentials = new Credentials(token);\r\n            }\r\n\r\n            this.gitHubClient = octokitClient;\r\n            this.owner = owner;\r\n            this.repo = repo;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets a release.\r\n        /// </summary>\r\n        /// <param name=\"releaseTag\">Release tag.</param>\r\n        /// <returns>The Release.</returns>\r\n        public async Task<Release> GetReleaseAsync(string releaseTag)\r\n        {\r\n            return await this.gitHubClient.Repository.Release.Get(this.owner, this.repo, releaseTag);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the latest released and waits.\r\n        /// </summary>\r\n        /// <param name=\"includePrerelease\">Include prerelease.</param>\r\n        /// <returns>Latest version.</returns>\r\n        public async Task<string> GetLatestReleaseTagNameAsync(bool includePrerelease)\r\n        {\r\n            return (await this.GetLatestReleaseAsync(includePrerelease)).TagName;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the latest released version.\r\n        /// </summary>\r\n        /// <param name=\"includePrerelease\">Include prerelease.</param>\r\n        /// <returns>Latest version.</returns>\r\n        public async Task<Release> GetLatestReleaseAsync(bool includePrerelease)\r\n        {\r\n            var allReleases = await this.GetAllReleasesAsync();\r\n            allReleases = includePrerelease ? allReleases : allReleases.Where(r => !r.Prerelease).ToList();\r\n            return allReleases.Select(r => new { Release = r, WinGetVersion = new WinGetVersion(r.TagName) })\r\n                .OrderBy(rv => rv.WinGetVersion.Version)\r\n                .Last().Release;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets all releases.\r\n        /// </summary>\r\n        /// <returns>All releases.</returns>\r\n        public async Task<IReadOnlyList<Release>> GetAllReleasesAsync()\r\n        {\r\n            return await this.gitHubClient.Repository.Release.GetAll(this.owner, this.repo);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Resolve a version string to the latest matching version from GitHub releases.\r\n        /// </summary>\r\n        /// <param name=\"version\">Version string to resolve. Can include wildcards (*).</param>\r\n        /// <param name=\"includePrerelease\">Whether to include prerelease versions in the search.</param>\r\n        /// <returns>Resolved version string or null if no match found.</returns>\r\n        public async Task<string?> ResolveVersionAsync(string version, bool includePrerelease)\r\n        {\r\n            if (!WinGetVersion.VersionHasWildcard(version))\r\n            {\r\n                return version;\r\n            }\r\n\r\n            var allReleases = await this.GetAllReleasesAsync();\r\n            var allWinGetReleases = allReleases.Select(r => new WinGetVersion(r.TagName));\r\n            if (TryGetLatestMatchingVersion(allWinGetReleases, version, includePrerelease, out var latestVersion))\r\n            {\r\n                return latestVersion!.TagVersion;\r\n            }\r\n\r\n            return null;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Reads all known GitHub token environment variables, logs their presence,\r\n        /// and selects the one to use based on precedence.\r\n        /// GH_TOKEN takes precedence over GITHUB_TOKEN, matching GitHub CLI behavior.\r\n        /// See: https://cli.github.com/manual/gh_help_environment.\r\n        /// </summary>\r\n        /// <param name=\"pwshCmdlet\">Optional PowerShell cmdlet for logging.</param>\r\n        /// <returns>The selected token value, or null if none found.</returns>\r\n        internal static string? ResolveGitHubToken(PowerShellCmdlet? pwshCmdlet = null)\r\n        {\r\n            string? ghToken = Environment.GetEnvironmentVariable(\"GH_TOKEN\");\r\n            string? githubToken = Environment.GetEnvironmentVariable(\"GITHUB_TOKEN\");\r\n\r\n            bool hasGhToken = !string.IsNullOrWhiteSpace(ghToken);\r\n            bool hasGithubToken = !string.IsNullOrWhiteSpace(githubToken);\r\n\r\n            pwshCmdlet?.Write(StreamType.Verbose, $\"GH_TOKEN environment variable: {(hasGhToken ? \"found\" : \"not found\")}\");\r\n            pwshCmdlet?.Write(StreamType.Verbose, $\"GITHUB_TOKEN environment variable: {(hasGithubToken ? \"found\" : \"not found\")}\");\r\n\r\n            if (hasGhToken)\r\n            {\r\n                pwshCmdlet?.Write(StreamType.Verbose, \"Using authenticated GitHub API requests via GH_TOKEN environment variable.\");\r\n                return ghToken;\r\n            }\r\n            else if (hasGithubToken)\r\n            {\r\n                pwshCmdlet?.Write(StreamType.Verbose, \"Using authenticated GitHub API requests via GITHUB_TOKEN environment variable.\");\r\n                return githubToken;\r\n            }\r\n\r\n            pwshCmdlet?.Write(StreamType.Verbose, \"No GitHub token found. Using unauthenticated GitHub API requests.\");\r\n            return null;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Tries to get the latest version matching the pattern.\r\n        /// </summary>\r\n        /// <remarks>\r\n        /// Pattern only supports leading and trailing wildcards.\r\n        /// - For example, the pattern can be: 1.11.*, 1.11.3*, 1.11.*3\r\n        /// - But it cannot be: 1.*1*.1 or 1.1*1.1.\r\n        /// </remarks>\r\n        /// <param name=\"versions\">List of versions to match against.</param>\r\n        /// <param name=\"pattern\">Pattern to match.</param>\r\n        /// <param name=\"includePrerelease\">Include prerelease versions.</param>\r\n        /// <param name=\"result\">The resulting version.</param>\r\n        /// <returns>True if a matching version was found.</returns>\r\n        private static bool TryGetLatestMatchingVersion(IEnumerable<WinGetVersion> versions, string pattern, bool includePrerelease, out WinGetVersion? result)\r\n        {\r\n            pattern = string.IsNullOrWhiteSpace(pattern) ? \"*\" : pattern;\r\n\r\n            var parts = pattern.Split('.');\r\n            var major = parts.ElementAtOrDefault(0);\r\n            var minor = parts.ElementAtOrDefault(1);\r\n            var build = parts.ElementAtOrDefault(2);\r\n            var revision = parts.ElementAtOrDefault(3);\r\n\r\n            if (!includePrerelease)\r\n            {\r\n                versions = versions.Where(v => !v.IsPrerelease);\r\n            }\r\n\r\n            versions = versions\r\n                .Where(v =>\r\n                    VersionPartMatch(major, v.Version.Major) &&\r\n                    VersionPartMatch(minor, v.Version.Minor) &&\r\n                    VersionPartMatch(build, v.Version.Build) &&\r\n                    VersionPartMatch(revision, v.Version.Revision))\r\n                .OrderBy(f => f.Version);\r\n\r\n            if (!versions.Any())\r\n            {\r\n                result = null!;\r\n                return false;\r\n            }\r\n\r\n            result = versions.Last();\r\n            return true;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Checks if a version part matches a pattern.\r\n        /// </summary>\r\n        /// <param name=\"partPattern\">Version part pattern.</param>\r\n        /// <param name=\"partValue\">Version part value.</param>\r\n        /// <returns>True if the part matches the pattern.</returns>\r\n        private static bool VersionPartMatch(string? partPattern, int partValue)\r\n        {\r\n            if (string.IsNullOrWhiteSpace(partPattern))\r\n            {\r\n                return true;\r\n            }\r\n\r\n            if (partPattern!.StartsWith(\"*\"))\r\n            {\r\n                return partValue.ToString().EndsWith(partPattern.TrimStart('*'));\r\n            }\r\n\r\n            if (partPattern!.EndsWith(\"*\"))\r\n            {\r\n                return partValue.ToString().StartsWith(partPattern.TrimEnd('*'));\r\n            }\r\n\r\n            return partPattern == partValue.ToString();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Helpers/HttpClientHelper.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"HttpClientHelper.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Helpers\r\n{\r\n    using System;\r\n    using System.Diagnostics;\r\n    using System.IO;\r\n    using System.Management.Automation;\r\n    using System.Net.Http;\r\n    using System.Threading.Tasks;\r\n    using Microsoft.WinGet.Client.Engine.Common;\r\n    using Microsoft.WinGet.Common.Command;\r\n    using Microsoft.WinGet.Resources;\r\n\r\n    /// <summary>\r\n    /// Helper class for HttpClient calls.\r\n    /// </summary>\r\n    internal class HttpClientHelper\r\n    {\r\n        /// <summary>\r\n        /// The user agent of this module.\r\n        /// </summary>\r\n        public const string UserAgent = \"winget-powershell\";\r\n\r\n        private static readonly HttpClient Client;\r\n\r\n        static HttpClientHelper()\r\n        {\r\n            Client = new HttpClient();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Downloads a file from a url.\r\n        /// </summary>\r\n        /// <param name=\"url\">Url.</param>\r\n        /// <param name=\"fileName\">File name.</param>\r\n        /// /// <param name=\"pwshCmdlet\">PowershellCmdlet.</param>\r\n        /// <returns>A <see cref=\"Task\"/> representing the asynchronous operation.</returns>\r\n        public async Task DownloadUrlWithProgressAsync(string url, string fileName, PowerShellCmdlet pwshCmdlet)\r\n        {\r\n            pwshCmdlet.Write(StreamType.Verbose, $\"Downloading {url}\");\r\n            using var request = new HttpRequestMessage(HttpMethod.Get, url);\r\n            request.Headers.Add(\"User-Agent\", UserAgent);\r\n\r\n            var cancellationToken = pwshCmdlet.GetCancellationToken();\r\n            using var response = await Client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken);\r\n            response.EnsureSuccessStatusCode();\r\n\r\n            try\r\n            {\r\n                long? contentLength = response.Content.Headers.ContentLength;\r\n                var responseStream = await response.Content.ReadAsStreamAsync();\r\n\r\n                using var fileStream = File.Open(fileName, FileMode.OpenOrCreate);\r\n\r\n                if (contentLength.HasValue)\r\n                {\r\n                    pwshCmdlet.Write(StreamType.Verbose, $\"Size {contentLength} bytes\");\r\n\r\n                    byte[] buffer = new byte[Constants.OneMB];\r\n                    int bytesRead, totalBytes = 0;\r\n\r\n                    var activityId = pwshCmdlet.GetNewProgressActivityId();\r\n                    double lengthInMB = (double)contentLength.Value / Constants.OneMB;\r\n                    try\r\n                    {\r\n                        int maxPercentComplete = 0;\r\n                        while ((bytesRead = await responseStream.ReadAsync(buffer, 0, buffer.Length, cancellationToken)) > 0)\r\n                        {\r\n                            await fileStream.WriteAsync(buffer, 0, bytesRead, cancellationToken);\r\n                            totalBytes += bytesRead;\r\n\r\n                            int percentComplete = (int)((double)totalBytes / contentLength * 100);\r\n                            if (percentComplete > maxPercentComplete)\r\n                            {\r\n                                maxPercentComplete = percentComplete;\r\n                                ProgressRecord record = new (activityId, url, Resources.DownloadingMessage)\r\n                                {\r\n                                    RecordType = ProgressRecordType.Processing,\r\n                                };\r\n\r\n                                double progress = (double)totalBytes / Constants.OneMB;\r\n                                record.StatusDescription = $\"{progress:0.0} MB / {lengthInMB:0.0} MB\";\r\n                                record.PercentComplete = percentComplete;\r\n                                pwshCmdlet.Write(StreamType.Progress, record);\r\n                            }\r\n                        }\r\n                    }\r\n                    finally\r\n                    {\r\n                        pwshCmdlet.CompleteProgress(activityId, url, Resources.DownloadingMessage, true);\r\n                    }\r\n                }\r\n                else\r\n                {\r\n                    pwshCmdlet.Write(StreamType.Verbose, $\"Content-Length not found in response\");\r\n                    await responseStream.CopyToAsync(fileStream);\r\n                }\r\n            }\r\n            catch (Exception)\r\n            {\r\n                if (File.Exists(fileName))\r\n                {\r\n                    File.Delete(fileName);\r\n                }\r\n\r\n                throw;\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Helpers/InstallOperationWithProgress.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"InstallOperationWithProgress.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Helpers\r\n{\r\n    using System.Management.Automation;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.WinGet.Client.Engine.Common;\r\n    using Microsoft.WinGet.Common.Command;\r\n    using Windows.Foundation;\r\n\r\n    /// <summary>\r\n    /// Handlers install or update operations with progress.\r\n    /// </summary>\r\n    internal class InstallOperationWithProgress : OperationWithProgressBase<InstallResult, InstallProgress>\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"InstallOperationWithProgress\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"pwshCmdlet\">A <see cref=\"PowerShellCmdlet\" /> instance.</param>\r\n        /// <param name=\"activity\">Activity.</param>\r\n        public InstallOperationWithProgress(PowerShellCmdlet pwshCmdlet, string activity)\r\n            : base(pwshCmdlet, activity)\r\n        {\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public override void Progress(IAsyncOperationWithProgress<InstallResult, InstallProgress> operation, InstallProgress progress)\r\n        {\r\n            ProgressRecord record = new (this.ActivityId, this.Activity, progress.State.ToString())\r\n            {\r\n                RecordType = ProgressRecordType.Processing,\r\n            };\r\n\r\n            if (progress.State == PackageInstallProgressState.Downloading && progress.BytesRequired != 0)\r\n            {\r\n                double downloaded = (double)progress.BytesDownloaded / Constants.OneMB;\r\n                double total = (double)progress.BytesRequired / Constants.OneMB;\r\n                record.StatusDescription = $\"{downloaded:0.0} MB / {total:0.0} MB\";\r\n                record.PercentComplete = (int)(progress.DownloadProgress * 100);\r\n            }\r\n            else if (progress.State == PackageInstallProgressState.Installing)\r\n            {\r\n                record.PercentComplete = (int)(progress.InstallationProgress * 100);\r\n            }\r\n\r\n            this.PwshCmdlet.Write(StreamType.Progress, record);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Helpers/ManagementDeploymentFactory.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"ManagementDeploymentFactory.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Helpers\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.Runtime.InteropServices;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.WinGet.Client.Engine.Common;\r\n    using Microsoft.WinGet.Client.Engine.Exceptions;\r\n\r\n#if NET\r\n    using WinRT;\r\n#endif\r\n\r\n    /// <summary>\r\n    /// Constructs instances of classes from the <see cref=\"Management.Deployment\" /> namespace.\r\n    /// </summary>\r\n    internal sealed class ManagementDeploymentFactory\r\n    {\r\n#if USE_PROD_CLSIDS\r\n        private static readonly Guid PackageManagerClsid = Guid.Parse(\"C53A4F16-787E-42A4-B304-29EFFB4BF597\");\r\n        private static readonly Guid FindPackagesOptionsClsid = Guid.Parse(\"572DED96-9C60-4526-8F92-EE7D91D38C1A\");\r\n        private static readonly Guid CreateCompositePackageCatalogOptionsClsid = Guid.Parse(\"526534B8-7E46-47C8-8416-B1685C327D37\");\r\n        private static readonly Guid InstallOptionsClsid = Guid.Parse(\"1095F097-EB96-453B-B4E6-1613637F3B14\");\r\n        private static readonly Guid UninstallOptionsClsid = Guid.Parse(\"E1D9A11E-9F85-4D87-9C17-2B93143ADB8D\");\r\n        private static readonly Guid PackageMatchFilterClsid = Guid.Parse(\"D02C9DAF-99DC-429C-B503-4E504E4AB000\");\r\n        private static readonly Guid DownloadOptionsClsid = Guid.Parse(\"4CBABE76-7322-4BE4-9CEA-2589A80682DC\");\r\n        private static readonly Guid RepairOptionsClsid = Guid.Parse(\"0498F441-3097-455F-9CAF-148F28293865\");\r\n#else\r\n        private static readonly Guid PackageManagerClsid = Guid.Parse(\"74CB3139-B7C5-4B9E-9388-E6616DEA288C\");\r\n        private static readonly Guid FindPackagesOptionsClsid = Guid.Parse(\"1BD8FF3A-EC50-4F69-AEEE-DF4C9D3BAA96\");\r\n        private static readonly Guid CreateCompositePackageCatalogOptionsClsid = Guid.Parse(\"EE160901-B317-4EA7-9CC6-5355C6D7D8A7\");\r\n        private static readonly Guid InstallOptionsClsid = Guid.Parse(\"44FE0580-62F7-44D4-9E91-AA9614AB3E86\");\r\n        private static readonly Guid UninstallOptionsClsid = Guid.Parse(\"AA2A5C04-1AD9-46C4-B74F-6B334AD7EB8C\");\r\n        private static readonly Guid PackageMatchFilterClsid = Guid.Parse(\"3F85B9F4-487A-4C48-9035-2903F8A6D9E8\");\r\n        private static readonly Guid DownloadOptionsClsid = Guid.Parse(\"8EF324ED-367C-4880-83E5-BB2ABD0B72F6\");\r\n        private static readonly Guid RepairOptionsClsid = Guid.Parse(\"E62BB1E7-C7B2-4AEC-9E28-FB649B30FF03\");\r\n#endif\r\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"Interoperability\", \"CA1416:Validate platform compatibility\", Justification = \"COM only usage.\")]\r\n        private static readonly Type? PackageManagerType = Type.GetTypeFromCLSID(PackageManagerClsid);\r\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"Interoperability\", \"CA1416:Validate platform compatibility\", Justification = \"COM only usage.\")]\r\n        private static readonly Type? FindPackagesOptionsType = Type.GetTypeFromCLSID(FindPackagesOptionsClsid);\r\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"Interoperability\", \"CA1416:Validate platform compatibility\", Justification = \"COM only usage.\")]\r\n        private static readonly Type? CreateCompositePackageCatalogOptionsType = Type.GetTypeFromCLSID(CreateCompositePackageCatalogOptionsClsid);\r\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"Interoperability\", \"CA1416:Validate platform compatibility\", Justification = \"COM only usage.\")]\r\n        private static readonly Type? InstallOptionsType = Type.GetTypeFromCLSID(InstallOptionsClsid);\r\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"Interoperability\", \"CA1416:Validate platform compatibility\", Justification = \"COM only usage.\")]\r\n        private static readonly Type? UninstallOptionsType = Type.GetTypeFromCLSID(UninstallOptionsClsid);\r\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"Interoperability\", \"CA1416:Validate platform compatibility\", Justification = \"COM only usage.\")]\r\n        private static readonly Type? PackageMatchFilterType = Type.GetTypeFromCLSID(PackageMatchFilterClsid);\r\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"Interoperability\", \"CA1416:Validate platform compatibility\", Justification = \"COM only usage.\")]\r\n        private static readonly Type? DownloadOptionsType = Type.GetTypeFromCLSID(DownloadOptionsClsid);\r\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"Interoperability\", \"CA1416:Validate platform compatibility\", Justification = \"COM only usage.\")]\r\n        private static readonly Type? RepairOptionsType = Type.GetTypeFromCLSID(RepairOptionsClsid);\r\n\r\n        // These GUIDs correspond to the CSWinRT interface IIDs generated for Microsoft.Management.Deployment.Projection\r\n        // and are auto-generated by the WinRT tool.\r\n        private static readonly Guid PackageManagerIid = Guid.Parse(\"B375E3B9-F2E0-5C93-87A7-B67497F7E593\");\r\n        private static readonly Guid FindPackagesOptionsIid = Guid.Parse(\"A5270EDD-7DA7-57A3-BACE-F2593553561F\");\r\n        private static readonly Guid CreateCompositePackageCatalogOptionsIid = Guid.Parse(\"21ABAA76-089D-51C5-A745-C85EEFE70116\");\r\n        private static readonly Guid InstallOptionsIid = Guid.Parse(\"6EE9DB69-AB48-5E72-A474-33A924CD23B3\");\r\n        private static readonly Guid UninstallOptionsIid = Guid.Parse(\"3EBC67F0-8339-594B-8A42-F90B69D02BBE\");\r\n        private static readonly Guid PackageMatchFilterIid = Guid.Parse(\"D981ECA3-4DE5-5AD7-967A-698C7D60FC3B\");\r\n        private static readonly Guid DownloadOptionsIid = Guid.Parse(\"94C92C4B-43F5-5CA3-BBBE-9F432C9546BC\");\r\n        private static readonly Guid RepairOptionsIid = Guid.Parse(\"263F0546-2D7E-53A0-B8D1-75B74817FF18\");\r\n\r\n        private static readonly IEnumerable<Architecture> ValidArchs = new Architecture[] { Architecture.X86, Architecture.X64 };\r\n\r\n        private static readonly Lazy<ManagementDeploymentFactory> Lazy = new (() => new ManagementDeploymentFactory());\r\n\r\n        /// <summary>\r\n        /// Initializes static members of the <see cref=\"ManagementDeploymentFactory\"/> class.\r\n        /// </summary>\r\n        static ManagementDeploymentFactory()\r\n        {\r\n            if (Utilities.UsesInProcWinget)\r\n            {\r\n                PackageManagerSettings settings = new PackageManagerSettings();\r\n                settings.SetCallerIdentifier(\"PowerShellInProc\");\r\n            }\r\n        }\r\n\r\n        private ManagementDeploymentFactory()\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the instance object.\r\n        /// </summary>\r\n        public static ManagementDeploymentFactory Instance\r\n        {\r\n            get { return Lazy.Value; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates an instance of the <see cref=\"PackageManager\" /> class.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"PackageManager\" /> instance.</returns>\r\n        public PackageManager CreatePackageManager()\r\n        {\r\n            var result = Create<PackageManager>(PackageManagerType, PackageManagerIid);\r\n\r\n            if (!Utilities.UsesInProcWinget)\r\n            {\r\n                _ = CoAllowSetForegroundWindow(result, IntPtr.Zero);\r\n            }\r\n\r\n            return result;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates an instance of the <see cref=\"FindPackagesOptions\" /> class.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"FindPackagesOptions\" /> instance.</returns>\r\n        public FindPackagesOptions CreateFindPackagesOptions()\r\n        {\r\n            return Create<FindPackagesOptions>(FindPackagesOptionsType, FindPackagesOptionsIid);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates an instance of the <see cref=\"CreateCompositePackageCatalogOptions\" /> class.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"CreateCompositePackageCatalogOptions\" /> instance.</returns>\r\n        public CreateCompositePackageCatalogOptions CreateCreateCompositePackageCatalogOptions()\r\n        {\r\n            return Create<CreateCompositePackageCatalogOptions>(CreateCompositePackageCatalogOptionsType, CreateCompositePackageCatalogOptionsIid);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates an instance of the <see cref=\"InstallOptions\" /> class.\r\n        /// </summary>\r\n        /// <returns>An <see cref=\"InstallOptions\" /> instance.</returns>\r\n        public InstallOptions CreateInstallOptions()\r\n        {\r\n            return Create<InstallOptions>(InstallOptionsType, InstallOptionsIid);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates an instance of the <see cref=\"UninstallOptions\" /> class.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"UninstallOptions\" /> instance.</returns>\r\n        public UninstallOptions CreateUninstallOptions()\r\n        {\r\n            return Create<UninstallOptions>(UninstallOptionsType, UninstallOptionsIid);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates an instance of the <see cref=\"DownloadOptions\" /> class.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"DownloadOptions\" /> instance.</returns>\r\n        public DownloadOptions CreateDownloadOptions()\r\n        {\r\n            return Create<DownloadOptions>(DownloadOptionsType, DownloadOptionsIid);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates an instance of the <see cref=\"PackageMatchFilter\" /> class.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"PackageMatchFilter\" /> instance.</returns>\r\n        public PackageMatchFilter CreatePackageMatchFilter()\r\n        {\r\n            return Create<PackageMatchFilter>(PackageMatchFilterType, PackageMatchFilterIid);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates an instance of the <see cref=\"RepairOptions\" /> class.\r\n        /// </summary>\r\n        /// <returns>A <see cref=\"RepairOptions\" /> instance.</returns>\r\n        public RepairOptions CreateRepairOptions()\r\n        {\r\n            return Create<RepairOptions>(RepairOptionsType, RepairOptionsIid);\r\n        }\r\n\r\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"Interoperability\", \"CA1416:Validate platform compatibility\", Justification = \"COM only usage.\")]\r\n        private static T Create<T>(Type? type, in Guid iid)\r\n            where T : new()\r\n        {\r\n            if (type == null)\r\n            {\r\n                throw new ArgumentNullException(iid.ToString());\r\n            }\r\n\r\n            if (Utilities.UsesInProcWinget)\r\n            {\r\n                // This doesn't work on Windows PowerShell\r\n                // If we want to support it, we need something that loads the\r\n                // Microsoft.Management.Deployment.dll for .NET framework as CsWinRT\r\n                // does for .NET Core\r\n                return new T();\r\n            }\r\n\r\n            object? instance = null;\r\n\r\n            if (Utilities.ExecutingAsAdministrator)\r\n            {\r\n                int hr = WinRTHelpers.ManualActivation(type.GUID, iid, 0, out instance);\r\n\r\n                if (hr < 0)\r\n                {\r\n                    if (hr == ErrorCode.FileNotFound || hr == ErrorCode.PackageNotRegisteredForUser)\r\n                    {\r\n                        throw new WinGetIntegrityException(IntegrityCategory.AppInstallerNotInstalled);\r\n                    }\r\n                    else\r\n                    {\r\n                        throw new COMException($\"Failed to create instance: {hr}\", hr);\r\n                    }\r\n                }\r\n            }\r\n            else\r\n            {\r\n                instance = Activator.CreateInstance(type);\r\n            }\r\n\r\n            if (instance == null)\r\n            {\r\n                throw new ArgumentNullException();\r\n            }\r\n\r\n#if NET\r\n            IntPtr pointer = Marshal.GetIUnknownForObject(instance);\r\n            return MarshalInterface<T>.FromAbi(pointer);\r\n#else\r\n            return (T)instance;\r\n#endif\r\n        }\r\n\r\n        [DllImport(\"ole32.dll\", ExactSpelling = true, PreserveSig = true)]\r\n        private static extern int CoAllowSetForegroundWindow([MarshalAs(UnmanagedType.IUnknown)] object pUnk, IntPtr reserved);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Helpers/OperationWithProgressBase.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"OperationWithProgressBase.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Helpers\r\n{\r\n    using System;\r\n    using System.Runtime.InteropServices;\r\n    using System.Threading.Tasks;\r\n    using Microsoft.WinGet.Common.Command;\r\n    using Microsoft.WinGet.Resources;\r\n    using Windows.Foundation;\r\n\r\n    /// <summary>\r\n    /// Base class for async operations with progress.\r\n    /// </summary>\r\n    /// <typeparam name=\"TOperationResult\">The operation result.</typeparam>\r\n    /// <typeparam name=\"TProgressData\">Progress data.</typeparam>\r\n    internal abstract class OperationWithProgressBase<TOperationResult, TProgressData>\r\n    {\r\n        private static bool isProgressEnabled;\r\n\r\n        static OperationWithProgressBase()\r\n        {\r\n            // Progress on arm64 will produce an AV because there's an OS bug where marshaling structs over a certain size fail.\r\n            // Fix is in 10.0.26068.0, for build before that disable progress.\r\n            if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)\r\n            {\r\n                var minWindowsVersion = new Version(10, 0, 26068, 0);\r\n                var osVersion = Environment.OSVersion.Version;\r\n                isProgressEnabled = osVersion.CompareTo(minWindowsVersion) >= 0;\r\n            }\r\n            else\r\n            {\r\n                isProgressEnabled = true;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"OperationWithProgressBase{TOperationResult, TProgressData}\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"pwshCmdlet\">A <see cref=\"PowerShellCmdlet\" /> instance.</param>\r\n        /// <param name=\"activity\">Activity.</param>\r\n        public OperationWithProgressBase(\r\n            PowerShellCmdlet pwshCmdlet,\r\n            string activity)\r\n        {\r\n            this.PwshCmdlet = pwshCmdlet;\r\n            this.ActivityId = pwshCmdlet.GetNewProgressActivityId();\r\n            this.Activity = activity;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the PowerShellCmdlet.\r\n        /// </summary>\r\n        protected PowerShellCmdlet PwshCmdlet { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the progress activity id.\r\n        /// </summary>\r\n        protected int ActivityId { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the activity.\r\n        /// </summary>\r\n        protected string Activity { get; }\r\n\r\n        /// <summary>\r\n        /// Progress callback.\r\n        /// </summary>\r\n        /// <param name=\"operation\">Async operation in progress.</param>\r\n        /// <param name=\"progress\">Progress data.</param>\r\n        public abstract void Progress(IAsyncOperationWithProgress<TOperationResult, TProgressData> operation, TProgressData progress);\r\n\r\n        /// <summary>\r\n        /// Starts the operation and executes it as task.\r\n        /// Supports cancellation.\r\n        /// </summary>\r\n        /// <param name=\"func\">Lambda with operation.</param>\r\n        /// <returns>TOperationReturn.</returns>\r\n        public async Task<TOperationResult> ExecuteAsync(Func<IAsyncOperationWithProgress<TOperationResult, TProgressData>> func)\r\n        {\r\n            var operation = func();\r\n\r\n            if (isProgressEnabled)\r\n            {\r\n                operation.Progress = this.Progress;\r\n            }\r\n\r\n            try\r\n            {\r\n                return await operation.AsTask(this.PwshCmdlet.GetCancellationToken());\r\n            }\r\n            finally\r\n            {\r\n                this.Complete();\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Completes progress for this activity.\r\n        /// </summary>\r\n        protected virtual void Complete()\r\n        {\r\n            this.PwshCmdlet.CompleteProgress(this.ActivityId, this.Activity, Resources.Completed, true);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Helpers/PSEnumHelpers.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"PSEnumHelpers.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Helpers\r\n{\r\n    using System;\r\n    using Microsoft.Management.Deployment;\r\n    using Newtonsoft.Json.Linq;\r\n    using Windows.System;\r\n\r\n    /// <summary>\r\n    /// Extension methods for PS Enum wrappers for Microsoft.Management.Deployment enums.\r\n    /// </summary>\r\n    internal static class PSEnumHelpers\r\n    {\r\n        /// <summary>\r\n        /// Checks if the provided enum string value matches the 'Default' value for PS Enums.\r\n        /// </summary>\r\n        /// <param name=\"value\">Enum string value.</param>\r\n        /// <returns>Boolean value.</returns>\r\n        public static bool IsDefaultEnum(string value)\r\n        {\r\n            return string.Equals(value, \"Default\", StringComparison.OrdinalIgnoreCase);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Converts PSPackageInstallMode string value to PackageInstallMode.\r\n        /// </summary>\r\n        /// <param name=\"value\">PSPackageInstallMode to string value.</param>\r\n        /// <returns>PackageInstallMode.</returns>\r\n        public static PackageInstallMode ToPackageInstallMode(string value)\r\n        {\r\n            return value switch\r\n            {\r\n                \"Default\" => PackageInstallMode.Default,\r\n                \"Silent\" => PackageInstallMode.Silent,\r\n                \"Interactive\" => PackageInstallMode.Interactive,\r\n                _ => throw new InvalidOperationException(),\r\n            };\r\n        }\r\n\r\n        /// <summary>\r\n        /// Converts PSPackageInstallScope string value to PackageInstallScope.\r\n        /// </summary>\r\n        /// <param name=\"value\">PSPackageInstallScope to string value.</param>\r\n        /// <returns>PackageInstallScope.</returns>\r\n        public static PackageInstallScope ToPackageInstallScope(string value)\r\n        {\r\n            return value switch\r\n            {\r\n                \"Any\" => PackageInstallScope.Any,\r\n                \"User\" => PackageInstallScope.User,\r\n                \"System\" => PackageInstallScope.System,\r\n                \"UserOrUnknown\" => PackageInstallScope.UserOrUnknown,\r\n                \"SystemOrUnknown\" => PackageInstallScope.SystemOrUnknown,\r\n                _ => throw new InvalidOperationException(),\r\n            };\r\n        }\r\n\r\n        /// <summary>\r\n        /// Converts PSProcessorArchitecture string value to ProcessorArchitecture.\r\n        /// </summary>\r\n        /// <param name=\"value\">PSProcessorArchitecture to string value.</param>\r\n        /// <returns>ProcessorArchitecture.</returns>\r\n        public static ProcessorArchitecture ToProcessorArchitecture(string value)\r\n        {\r\n            return value switch\r\n            {\r\n                \"X86\" => ProcessorArchitecture.X86,\r\n                \"Arm\" => ProcessorArchitecture.Arm,\r\n                \"X64\" => ProcessorArchitecture.X64,\r\n                \"Arm64\" => ProcessorArchitecture.Arm64,\r\n                _ => throw new InvalidOperationException(),\r\n            };\r\n        }\r\n\r\n        /// <summary>\r\n        /// Converts PSPackageUninstallMode string value to PackageUninstallMode.\r\n        /// </summary>\r\n        /// <param name=\"value\">PSPackageUninstallMode string value.</param>\r\n        /// <returns>PackageUninstallMode.</returns>\r\n        public static PackageUninstallMode ToPackageUninstallMode(string value)\r\n        {\r\n            return value switch\r\n            {\r\n                \"Default\" => PackageUninstallMode.Default,\r\n                \"Silent\" => PackageUninstallMode.Silent,\r\n                \"Interactive\" => PackageUninstallMode.Interactive,\r\n                _ => throw new InvalidOperationException(),\r\n            };\r\n        }\r\n\r\n        /// <summary>\r\n        /// Converts PSPackageFieldMatchOption string value to PackageFieldMatchOption.\r\n        /// </summary>\r\n        /// <param name=\"value\">PSPackageFieldMatchOption string value.</param>\r\n        /// <returns>PackageFieldMatchOption.</returns>\r\n        public static PackageFieldMatchOption ToPackageFieldMatchOption(string value)\r\n        {\r\n            return value switch\r\n            {\r\n                \"Equals\" => PackageFieldMatchOption.Equals,\r\n                \"EqualsCaseInsensitive\" => PackageFieldMatchOption.EqualsCaseInsensitive,\r\n                \"StartsWithCaseInsensitive\" => PackageFieldMatchOption.StartsWithCaseInsensitive,\r\n                \"ContainsCaseInsensitive\" => PackageFieldMatchOption.ContainsCaseInsensitive,\r\n                _ => throw new InvalidOperationException(),\r\n            };\r\n        }\r\n\r\n        /// <summary>\r\n        /// Converts PSPackageInstallerType string value to PackageInstallerType.\r\n        /// </summary>\r\n        /// <param name=\"value\">PSPackageInstallerType string value.</param>\r\n        /// <returns>PackageInstallerType.</returns>\r\n        public static PackageInstallerType ToPackageInstallerType(string value)\r\n        {\r\n            return value switch\r\n            {\r\n                \"Unknown\" => PackageInstallerType.Unknown,\r\n                \"Inno\" => PackageInstallerType.Inno,\r\n                \"Wix\" => PackageInstallerType.Wix,\r\n                \"Msi\" => PackageInstallerType.Msi,\r\n                \"Nullsoft\" => PackageInstallerType.Nullsoft,\r\n                \"Zip\" => PackageInstallerType.Zip,\r\n                \"Msix\" => PackageInstallerType.Msix,\r\n                \"Exe\" => PackageInstallerType.Exe,\r\n                \"Burn\" => PackageInstallerType.Burn,\r\n                \"MSStore\" => PackageInstallerType.MSStore,\r\n                \"Portable\" => PackageInstallerType.Portable,\r\n                _ => throw new InvalidOperationException(),\r\n            };\r\n        }\r\n\r\n        /// <summary>\r\n        /// Converts PSPackageRepairMode string value to PackageRepairMode.\r\n        /// </summary>\r\n        /// <param name=\"value\">PSPackageRepairMode string value.</param>\r\n        /// <returns>PackageRepairMode.</returns>\r\n        public static PackageRepairMode ToPackageRepairMode(string value)\r\n        {\r\n            return value switch\r\n            {\r\n                \"Default\" => PackageRepairMode.Default,\r\n                \"Silent\" => PackageRepairMode.Silent,\r\n                \"Interactive\" => PackageRepairMode.Interactive,\r\n                _ => throw new InvalidOperationException(),\r\n            };\r\n        }\r\n\r\n        /// <summary>\r\n        /// Converts PSWindowsPlatform string value to WindowsPlatform.\r\n        /// </summary>\r\n        /// <param name=\"value\">PSWindowsPlatform string value.</param>\r\n        /// <returns>WindowsPlatform.</returns>\r\n        public static WindowsPlatform ToWindowsPlatform(string value)\r\n        {\r\n            return value switch\r\n            {\r\n                \"Default\" => WindowsPlatform.Unknown,\r\n                \"Universal\" => WindowsPlatform.Universal,\r\n                \"Desktop\" => WindowsPlatform.Desktop,\r\n                \"IoT\" => WindowsPlatform.IoT,\r\n                \"Team\" => WindowsPlatform.Team,\r\n                \"Holographic\" => WindowsPlatform.Holographic,\r\n                _ => throw new InvalidOperationException(),\r\n            };\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Helpers/PackageDependency.cs",
    "content": "// -----------------------------------------------------------------------------\n// <copyright file=\"PackageDependency.cs\" company=\"Microsoft Corporation\">\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\n// </copyright>\n// -----------------------------------------------------------------------------\nnamespace Microsoft.WinGet.Client.Engine.Helpers\n{\n    /// <summary>\n    /// A single package dependency.\n    /// </summary>\n    internal class PackageDependency\n    {\n        /// <summary>\n        /// Gets or sets the name of the dependency.\n        /// </summary>\n        public string Name { get; set; } = string.Empty;\n\n        /// <summary>\n        /// Gets or sets the version of the dependency.\n        /// </summary>\n        public string Version { get; set; } = string.Empty;\n    }\n}\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Helpers/PackageManagerWrapper.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"PackageManagerWrapper.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Helpers\r\n{\r\n    using System;\r\n    using System.Collections.Generic;\r\n    using System.Runtime.InteropServices;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.WinGet.Client.Engine.Common;\r\n    using Microsoft.WinGet.Client.Engine.Exceptions;\r\n    using Windows.Foundation;\r\n\r\n    /// <summary>\r\n    /// Wrapper for PackageManager that handles rpc disconnections.\r\n    /// The object is disconnected when the server is killed or on an update.\r\n    /// </summary>\r\n    internal sealed class PackageManagerWrapper\r\n    {\r\n        private static readonly Lazy<PackageManagerWrapper> Lazy = new (() => new PackageManagerWrapper());\r\n\r\n        private PackageManager packageManager = null!;\r\n\r\n        private PackageManagerWrapper()\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the instance object.\r\n        /// </summary>\r\n        public static PackageManagerWrapper Instance\r\n        {\r\n            get { return Lazy.Value; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Wrapper for InstallPackageAsync.\r\n        /// </summary>\r\n        /// <param name=\"package\">The package to install.</param>\r\n        /// <param name=\"options\">The install options.</param>\r\n        /// <returns>An async operation with progress.</returns>\r\n        public IAsyncOperationWithProgress<InstallResult, InstallProgress> InstallPackageAsync(CatalogPackage package, InstallOptions options)\r\n        {\r\n            return this.Execute(\r\n                () => this.packageManager.InstallPackageAsync(package, options),\r\n                false);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Wrapper for UpgradePackageAsync.\r\n        /// </summary>\r\n        /// <param name=\"package\">The package to upgrade.</param>\r\n        /// <param name=\"options\">The install options.</param>\r\n        /// <returns>An async operation with progress.</returns>\r\n        public IAsyncOperationWithProgress<InstallResult, InstallProgress> UpgradePackageAsync(CatalogPackage package, InstallOptions options)\r\n        {\r\n            return this.Execute(\r\n                () => this.packageManager.UpgradePackageAsync(package, options),\r\n                false);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Wrapper for UninstallPackageAsync.\r\n        /// </summary>\r\n        /// <param name=\"package\">The package to uninstall.</param>\r\n        /// <param name=\"options\">The uninstall options.</param>\r\n        /// <returns>An async operation with progress.</returns>\r\n        public IAsyncOperationWithProgress<UninstallResult, UninstallProgress> UninstallPackageAsync(CatalogPackage package, UninstallOptions options)\r\n        {\r\n            return this.Execute(\r\n                () => this.packageManager.UninstallPackageAsync(package, options),\r\n                false);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Wrapper for DownloadPackageAsync.\r\n        /// </summary>\r\n        /// <param name=\"package\">The package to download.</param>\r\n        /// <param name=\"options\">The download options.</param>\r\n        /// <returns>An async operation with progress.</returns>\r\n        public IAsyncOperationWithProgress<DownloadResult, PackageDownloadProgress> DownloadPackageAsync(CatalogPackage package, DownloadOptions options)\r\n        {\r\n            return this.Execute(\r\n                () => this.packageManager.DownloadPackageAsync(package, options),\r\n                false);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Wrapper for RepairPackagesAsync.\r\n        /// </summary>\r\n        /// <param name=\"package\">The package to repair.</param>\r\n        /// <param name=\"options\">The repair options.</param>\r\n        /// <returns>An async operation with progress.</returns>\r\n        public IAsyncOperationWithProgress<RepairResult, RepairProgress> RepairPackageAsync(CatalogPackage package, RepairOptions options)\r\n        {\r\n            return this.Execute(\r\n                () => this.packageManager.RepairPackageAsync(package, options),\r\n                false);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Wrapper for GetPackageCatalogs.\r\n        /// </summary>\r\n        /// <returns>A list of PackageCatalogReferences.</returns>\r\n        public IReadOnlyList<PackageCatalogReference> GetPackageCatalogs()\r\n        {\r\n            return this.Execute(\r\n                () => this.packageManager.GetPackageCatalogs(),\r\n                true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Wrapper for GetPackageCatalogByName.\r\n        /// </summary>\r\n        /// <param name=\"source\">The name of the source.</param>\r\n        /// <returns>A PackageCatalogReference.</returns>\r\n        public PackageCatalogReference GetPackageCatalogByName(string source)\r\n        {\r\n            return this.Execute(\r\n                () => this.packageManager.GetPackageCatalogByName(source),\r\n                true);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Wrapper for CreateCompositePackageCatalog.\r\n        /// </summary>\r\n        /// <param name=\"options\">CreateCompositePackageCatalogOptions.</param>\r\n        /// <returns>A PackageCatalogReference.</returns>\r\n        public PackageCatalogReference CreateCompositePackageCatalog(CreateCompositePackageCatalogOptions options)\r\n        {\r\n            return this.Execute(\r\n                () => this.packageManager.CreateCompositePackageCatalog(options),\r\n                false);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the version of the package manager that is running.\r\n        /// </summary>\r\n        /// <returns>The version string.</returns>\r\n        public string? GetVersion()\r\n        {\r\n            try\r\n            {\r\n                return this.Execute(() => this.packageManager.Version, true);\r\n            }\r\n            catch\r\n            {\r\n                return null;\r\n            }\r\n        }\r\n\r\n        private TReturn Execute<TReturn>(Func<TReturn> func, bool canRetry)\r\n        {\r\n            if (Utilities.UsesInProcWinget && Utilities.ThreadIsSTA)\r\n            {\r\n                // If you failed here, then you didn't wrap your call in ManagementDeploymentCommand.Execute\r\n                throw new SingleThreadedApartmentException();\r\n            }\r\n\r\n            bool stopRetry = false;\r\n            while (true)\r\n            {\r\n                if (this.packageManager == null)\r\n                {\r\n                    this.packageManager = ManagementDeploymentFactory.Instance.CreatePackageManager();\r\n                }\r\n\r\n                try\r\n                {\r\n                    return func();\r\n                }\r\n                catch (COMException ex) when (ex.HResult == ErrorCode.RpcServerUnavailable || ex.HResult == ErrorCode.RpcCallFailed)\r\n                {\r\n                    this.packageManager = null!;\r\n\r\n                    if (stopRetry || !canRetry)\r\n                    {\r\n                        throw;\r\n                    }\r\n\r\n                    stopRetry = true;\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Helpers/RepairOperationWithProgress.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"RepairOperationWithProgress.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Helpers\r\n{\r\n    using System;\r\n    using System.Management.Automation;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.WinGet.Common.Command;\r\n    using Microsoft.WinGet.Resources;\r\n    using Windows.Foundation;\r\n\r\n    /// <summary>\r\n    /// Handler for Repair Operation with Progress.\r\n    /// </summary>\r\n    internal class RepairOperationWithProgress : OperationWithProgressBase<RepairResult, RepairProgress>\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"RepairOperationWithProgress\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"pwshCmdlet\"> instance.</param>\r\n        /// <param name=\"activity\">Activity.</param>\r\n        public RepairOperationWithProgress(PowerShellCmdlet pwshCmdlet, string activity)\r\n            : base(pwshCmdlet, activity)\r\n        {\r\n        }\r\n\r\n        /// <inheritdoc/>\r\n        public override void Progress(IAsyncOperationWithProgress<RepairResult, RepairProgress> operation, RepairProgress progress)\r\n        {\r\n            ProgressRecord record = new (this.ActivityId, this.Activity, progress.State.ToString())\r\n            {\r\n                RecordType = ProgressRecordType.Processing,\r\n            };\r\n\r\n            record.StatusDescription = Resources.Repairing;\r\n            record.PercentComplete = (int)(progress.RepairCompletionProgress * 100);\r\n            this.PwshCmdlet.Write(StreamType.Progress, record);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Helpers/TempDirectory.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"TempDirectory.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Helpers\r\n{\r\n    using System;\r\n    using System.IO;\r\n\r\n    /// <summary>\r\n    /// Creates a temporary directory in the user's temporary directory.\r\n    /// </summary>\r\n    internal class TempDirectory : IDisposable\r\n    {\r\n        private readonly bool cleanup;\r\n        private bool disposed = false;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"TempDirectory\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"directoryName\">Optional directory name. If null, creates a random directory name.</param>\r\n        /// <param name=\"deleteIfExists\">Delete directory if already exists. Default true.</param>\r\n        /// <param name=\"cleanup\">Deletes directory at disposing time. Default true.</param>\r\n        public TempDirectory(\r\n            string? directoryName = null,\r\n            bool deleteIfExists = true,\r\n            bool cleanup = true)\r\n        {\r\n            if (directoryName is null)\r\n            {\r\n                this.DirectoryName = Path.GetRandomFileName();\r\n            }\r\n            else\r\n            {\r\n                this.DirectoryName = directoryName;\r\n            }\r\n\r\n            this.FullDirectoryPath = Path.Combine(Path.GetTempPath(), this.DirectoryName);\r\n\r\n            if (deleteIfExists && Directory.Exists(this.FullDirectoryPath))\r\n            {\r\n                Directory.Delete(this.FullDirectoryPath, true);\r\n            }\r\n\r\n            Directory.CreateDirectory(this.FullDirectoryPath);\r\n            this.cleanup = cleanup;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the directory name.\r\n        /// </summary>\r\n        public string DirectoryName { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the full directory name.\r\n        /// </summary>\r\n        public string FullDirectoryPath { get; }\r\n\r\n        /// <summary>\r\n        /// IDisposable.Dispose .\r\n        /// </summary>\r\n        public void Dispose()\r\n        {\r\n            this.Dispose(true);\r\n            GC.SuppressFinalize(this);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Copies all contents of a directory into this directory.\r\n        /// </summary>\r\n        /// <param name=\"sourceDir\">Source directory.</param>\r\n        public void CopyDirectory(string sourceDir)\r\n        {\r\n            this.CopyDirectory(sourceDir, this.FullDirectoryPath);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Protected disposed.\r\n        /// </summary>\r\n        /// <param name=\"disposing\">Disposing.</param>\r\n        protected virtual void Dispose(bool disposing)\r\n        {\r\n            if (!this.disposed)\r\n            {\r\n                if (this.cleanup && Directory.Exists(this.FullDirectoryPath))\r\n                {\r\n                    Directory.Delete(this.FullDirectoryPath, true);\r\n                }\r\n\r\n                this.disposed = true;\r\n            }\r\n        }\r\n\r\n        private void CopyDirectory(string sourceDir, string destinationDir)\r\n        {\r\n            var dir = new DirectoryInfo(sourceDir);\r\n\r\n            if (!dir.Exists)\r\n            {\r\n                throw new DirectoryNotFoundException(dir.FullName);\r\n            }\r\n\r\n            Directory.CreateDirectory(destinationDir);\r\n\r\n            foreach (FileInfo file in dir.GetFiles())\r\n            {\r\n                file.CopyTo(Path.Combine(destinationDir, file.Name));\r\n            }\r\n\r\n            foreach (DirectoryInfo subDir in dir.GetDirectories())\r\n            {\r\n                this.CopyDirectory(subDir.FullName, Path.Combine(destinationDir, subDir.Name));\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Helpers/TempFile.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"TempFile.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Helpers\r\n{\r\n    using System;\r\n    using System.IO;\r\n\r\n    /// <summary>\r\n    /// Creates a temporary file in the user's temporary directory.\r\n    /// </summary>\r\n    internal class TempFile : IDisposable\r\n    {\r\n        private readonly bool cleanup;\r\n\r\n        private bool disposed = false;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"TempFile\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"fileName\">Optional file name. If null, creates a random file name.</param>\r\n        /// <param name=\"deleteIfExists\">Delete file if already exists. Default true.</param>\r\n        /// <param name=\"content\">Optional content. If not null or empty, creates file and writes to it.</param>\r\n        /// <param name=\"cleanup\">Deletes file at disposing time. Default true.</param>\r\n        public TempFile(\r\n            string? fileName = null,\r\n            bool deleteIfExists = true,\r\n            string? content = null,\r\n            bool cleanup = true)\r\n        {\r\n            if (fileName is null)\r\n            {\r\n                this.FileName = Path.GetRandomFileName();\r\n                this.FullPath = Path.Combine(Path.GetTempPath(), this.FileName);\r\n            }\r\n            else\r\n            {\r\n                this.FileName = fileName;\r\n                var randomDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());\r\n                Directory.CreateDirectory(randomDir);\r\n                this.FullPath = Path.Combine(randomDir, this.FileName);\r\n            }\r\n\r\n            if (deleteIfExists && File.Exists(this.FullPath))\r\n            {\r\n                File.Delete(this.FullPath);\r\n            }\r\n\r\n            if (!string.IsNullOrWhiteSpace(content))\r\n            {\r\n                this.CreateFile(content);\r\n            }\r\n\r\n            this.cleanup = cleanup;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the file name.\r\n        /// </summary>\r\n        public string FileName { get; }\r\n\r\n        /// <summary>\r\n        /// Gets the full path.\r\n        /// </summary>\r\n        public string FullPath { get; }\r\n\r\n        /// <summary>\r\n        /// IDisposable.Dispose.\r\n        /// </summary>\r\n        public void Dispose()\r\n        {\r\n            this.Dispose(true);\r\n            GC.SuppressFinalize(this);\r\n        }\r\n\r\n        /// <summary>\r\n        /// Creates the file.\r\n        /// </summary>\r\n        /// <param name=\"content\">Content.</param>\r\n        public void CreateFile(string? content = null)\r\n        {\r\n            if (content is null)\r\n            {\r\n                using var fs = File.Create(this.FullPath);\r\n            }\r\n            else\r\n            {\r\n                File.WriteAllText(this.FullPath, content);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Protected disposed.\r\n        /// </summary>\r\n        /// <param name=\"disposing\">Disposing.</param>\r\n        protected virtual void Dispose(bool disposing)\r\n        {\r\n            if (!this.disposed)\r\n            {\r\n                if (this.cleanup && File.Exists(this.FullPath))\r\n                {\r\n                    File.Delete(this.FullPath);\r\n                }\r\n\r\n                this.disposed = true;\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Helpers/WinGetCLICommandBuilder.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"WinGetCLICommandBuilder.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Helpers\r\n{\r\n    using System.Collections.Generic;\r\n    using System.Text;\r\n\r\n    /// <summary>\r\n    /// Represents a builder for WinGet CLI commands.\r\n    /// </summary>\r\n    public class WinGetCLICommandBuilder\r\n    {\r\n        private readonly List<string> commands;\r\n        private readonly List<string> parameters;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"WinGetCLICommandBuilder\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"commands\">The commands to initialize the builder with.</param>\r\n        public WinGetCLICommandBuilder(params string[] commands)\r\n        {\r\n            this.commands = new (commands);\r\n            this.parameters = new ();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the main command (e.g. [empty], settings, source).\r\n        /// </summary>\r\n        public string Command => string.Join(\" \", this.commands);\r\n\r\n        /// <summary>\r\n        /// Gets the constructed parameters string.\r\n        /// </summary>\r\n        public string Parameters => string.Join(\" \", this.parameters);\r\n\r\n        /// <summary>\r\n        /// Appends a switch to the command.\r\n        /// </summary>\r\n        /// <param name=\"switchName\">The name of the switch to append.</param>\r\n        /// <returns>The current instance of <see cref=\"WinGetCLICommandBuilder\"/>.</returns>\r\n        public WinGetCLICommandBuilder AppendSwitch(string switchName)\r\n        {\r\n            this.parameters.Add($\"--{switchName}\");\r\n            return this;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Appends a sub-command to the command.\r\n        /// </summary>\r\n        /// <param name=\"subCommand\">The sub-command to append.</param>\r\n        /// <returns>The current instance of <see cref=\"WinGetCLICommandBuilder\"/>.</returns>\r\n        public WinGetCLICommandBuilder AppendSubCommand(string subCommand)\r\n        {\r\n            this.commands.Add(subCommand);\r\n            return this;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Appends an option with its value to the command.\r\n        /// </summary>\r\n        /// <param name=\"option\">The name of the option to append.</param>\r\n        /// <param name=\"value\">The value of the option to append.</param>\r\n        /// <returns>The current instance of <see cref=\"WinGetCLICommandBuilder\"/>.</returns>\r\n        public WinGetCLICommandBuilder AppendOption(string option, string? value)\r\n        {\r\n            if (value == null)\r\n            {\r\n                return this;\r\n            }\r\n\r\n            this.parameters.Add($\"--{option} {this.Escape(value)}\");\r\n            return this;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Converts the command builder to its string representation.\r\n        /// </summary>\r\n        /// <returns>The string representation of the command.</returns>\r\n        public override string ToString()\r\n        {\r\n            var parametersString = this.Parameters;\r\n            var commandString = this.Command;\r\n            if (string.IsNullOrEmpty(commandString))\r\n            {\r\n                return parametersString;\r\n            }\r\n\r\n            if (string.IsNullOrEmpty(parametersString))\r\n            {\r\n                return commandString;\r\n            }\r\n\r\n            return $\"{commandString} {parametersString}\";\r\n        }\r\n\r\n        /// <summary>\r\n        /// Escapes a command-line argument according to Windows command-line parsing rules.\r\n        /// References:\r\n        /// - https://devblogs.microsoft.com/oldnewthing/20100917-00/?p=12833\r\n        /// - https://learn.microsoft.com/en-us/cpp/c-language/parsing-c-command-line-arguments.\r\n        /// </summary>\r\n        /// <param name=\"arg\">The argument to escape.</param>\r\n        /// <returns>The escaped argument.</returns>\r\n        private string Escape(string arg)\r\n        {\r\n            if (string.IsNullOrEmpty(arg))\r\n            {\r\n                return \"\\\"\\\"\";\r\n            }\r\n\r\n            var sb = new StringBuilder(arg.Length + 2);\r\n            sb.Append('\"');\r\n\r\n            int bs = 0;\r\n            foreach (char c in arg)\r\n            {\r\n                if (c == '\\\\')\r\n                {\r\n                    bs++;\r\n                }\r\n                else if (c == '\"')\r\n                {\r\n                    sb.Append('\\\\', (bs * 2) + 1);\r\n                    sb.Append('\"');\r\n                    bs = 0;\r\n                }\r\n                else\r\n                {\r\n                    sb.Append('\\\\', bs);\r\n                    sb.Append(c);\r\n                    bs = 0;\r\n                }\r\n            }\r\n\r\n            if (bs > 0)\r\n            {\r\n                sb.Append('\\\\', bs * 2);\r\n            }\r\n\r\n            sb.Append('\"');\r\n            return sb.ToString();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Helpers/WinGetCLICommandResult.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"WinGetCLICommandResult.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Helpers\r\n{\r\n    using Microsoft.WinGet.Client.Engine.Exceptions;\r\n\r\n    /// <summary>\r\n    /// Winget cli command result.\r\n    /// </summary>\r\n    internal class WinGetCLICommandResult\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"WinGetCLICommandResult\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"command\">Command.</param>\r\n        /// <param name=\"parameters\">Parameters.</param>\r\n        /// <param name=\"exitCode\">Exit code.</param>\r\n        /// <param name=\"stdOut\">Standard output.</param>\r\n        /// <param name=\"stdErr\">Standard error.</param>\r\n        public WinGetCLICommandResult(string command, string? parameters, int exitCode, string stdOut, string stdErr)\r\n        {\r\n            this.Command = command;\r\n            this.Parameters = parameters;\r\n            this.ExitCode = exitCode;\r\n            this.StdOut = stdOut;\r\n            this.StdErr = stdErr;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the command.\r\n        /// </summary>\r\n        public string Command { get; private set; }\r\n\r\n        /// <summary>\r\n        /// Gets the parameters.\r\n        /// </summary>\r\n        public string? Parameters { get; private set; }\r\n\r\n        /// <summary>\r\n        /// Gets the exit code.\r\n        /// </summary>\r\n        public int ExitCode { get; private set; }\r\n\r\n        /// <summary>\r\n        /// Gets the standard output.\r\n        /// </summary>\r\n        public string StdOut { get; private set; }\r\n\r\n        /// <summary>\r\n        /// Gets the standard error.\r\n        /// </summary>\r\n        public string StdErr { get; private set; }\r\n\r\n        /// <summary>\r\n        /// Verifies exit code.\r\n        /// </summary>\r\n        /// <param name=\"exitCode\">Optional exit code.</param>\r\n        public void VerifyExitCode(int exitCode = 0)\r\n        {\r\n            if (this.ExitCode != exitCode)\r\n            {\r\n                throw new WinGetCLIException(\r\n                    this.Command,\r\n                    this.Parameters,\r\n                    this.ExitCode,\r\n                    this.StdOut,\r\n                    this.StdErr);\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Helpers/WinRTHelpers.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"WinRTHelpers.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Helpers\r\n{\r\n    using System;\r\n    using System.IO;\r\n    using System.Runtime.InteropServices;\r\n\r\n    /// <summary>\r\n    /// Helper class for winrtact.dll calls.\r\n    /// </summary>\r\n    internal static class WinRTHelpers\r\n    {\r\n#if POWERSHELL_WINDOWS\r\n        private static readonly string ArchDependencyPath;\r\n\r\n        static WinRTHelpers()\r\n        {\r\n            ArchDependencyPath = Path.Combine(\r\n                    Path.GetDirectoryName(\r\n                        Path.GetDirectoryName(typeof(WinRTHelpers).Assembly.Location)),\r\n                    \"SharedDependencies\",\r\n                    RuntimeInformation.ProcessArchitecture.ToString().ToLower());\r\n        }\r\n#endif\r\n\r\n        /// <summary>\r\n        /// Calls winrtact_Initialize.\r\n        /// </summary>\r\n        public static void Initialize()\r\n        {\r\n#if POWERSHELL_WINDOWS\r\n            SetDllDirectoryW(ArchDependencyPath);\r\n\r\n            try\r\n            {\r\n#endif\r\n                InitializeUndockedRegFreeWinRT();\r\n\r\n#if POWERSHELL_WINDOWS\r\n            }\r\n            finally\r\n            {\r\n                SetDllDirectoryW(null);\r\n            }\r\n#endif\r\n        }\r\n\r\n        /// <summary>\r\n        /// Calls WinGetServerManualActivation_CreateInstance.\r\n        /// </summary>\r\n        /// <param name=\"clsid\">Class id.</param>\r\n        /// <param name=\"iid\">IID.</param>\r\n        /// <param name=\"flags\">Flags.</param>\r\n        /// <param name=\"instance\">Out object.</param>\r\n        /// <returns>Result of WinGetServerManualActivation_CreateInstance.</returns>\r\n        public static int ManualActivation(Guid clsid, Guid iid, uint flags, out object instance)\r\n        {\r\n#if POWERSHELL_WINDOWS\r\n            SetDllDirectoryW(ArchDependencyPath);\r\n\r\n            try\r\n            {\r\n#endif\r\n                return WinGetServerManualActivation_CreateInstance(clsid, iid, flags, out instance);\r\n\r\n#if POWERSHELL_WINDOWS\r\n            }\r\n            finally\r\n            {\r\n                SetDllDirectoryW(null);\r\n            }\r\n#endif\r\n        }\r\n\r\n        [DllImport(\"winrtact.dll\", EntryPoint = \"winrtact_Initialize\", ExactSpelling = true, PreserveSig = true)]\r\n        private static extern void InitializeUndockedRegFreeWinRT();\r\n\r\n        [DllImport(\"winrtact.dll\", EntryPoint = \"WinGetServerManualActivation_CreateInstance\", ExactSpelling = true, PreserveSig = true)]\r\n        private static extern int WinGetServerManualActivation_CreateInstance(\r\n            [In, MarshalAs(UnmanagedType.LPStruct)] Guid clsid,\r\n            [In, MarshalAs(UnmanagedType.LPStruct)] Guid iid,\r\n            uint flags,\r\n            [Out, MarshalAs(UnmanagedType.IUnknown)] out object instance);\r\n\r\n        [DllImport(\"kernel32.dll\", SetLastError = true)]\r\n        [return: MarshalAs(UnmanagedType.Bool)]\r\n        private static extern bool SetDllDirectoryW([MarshalAs(UnmanagedType.LPWStr)] string? directory);\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Helpers/WingetCLIWrapper.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"WingetCLIWrapper.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.Helpers\r\n{\r\n    using System;\r\n    using System.Diagnostics;\r\n    using System.IO;\r\n    using Microsoft.WinGet.Client.Engine.Common;\r\n    using Microsoft.WinGet.Client.Engine.Exceptions;\r\n    using Microsoft.WinGet.Common.Command;\r\n\r\n    /// <summary>\r\n    /// Calls winget directly.\r\n    /// </summary>\r\n    internal class WingetCLIWrapper\r\n    {\r\n        /// <summary>\r\n        /// The file name to use in start info.\r\n        /// </summary>\r\n        private readonly string wingetPath;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"WingetCLIWrapper\"/> class.\r\n        /// When app execution alias is disabled the path of the exe is\r\n        /// in the package family name directory in the local app data windows app directory. If its enabled then there's\r\n        /// link in the windows app data directory. To avoid checking if its enabled or not, just look in the package\r\n        /// family name directory.\r\n        /// For test, point to the wingetdev executable.\r\n        /// </summary>\r\n        /// <param name=\"fullPath\">Use full path or not.</param>\r\n        public WingetCLIWrapper(bool fullPath = true)\r\n        {\r\n            if (Utilities.ExecutingAsSystem)\r\n            {\r\n                throw new NotSupportedException();\r\n            }\r\n\r\n            if (fullPath)\r\n            {\r\n                this.wingetPath = WinGetFullPath;\r\n            }\r\n            else\r\n            {\r\n                this.wingetPath = Constants.WinGetExe;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the full path of winget executable.\r\n        /// </summary>\r\n        public static string WinGetFullPath\r\n        {\r\n            get\r\n            {\r\n                return Path.Combine(\r\n                    Utilities.LocalDataWindowsAppPath,\r\n                    Constants.WingetPackageFamilyName,\r\n                    Constants.WinGetExe);\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Runs winget command with parameters.\r\n        /// </summary>\r\n        /// <param name=\"pwshCmdlet\">PowerShell cmdlet.</param>\r\n        /// <param name=\"builder\">The command builder.</param>\r\n        /// <param name=\"timeOut\">Time out.</param>\r\n        /// <returns>WinGetCommandResult.</returns>\r\n        internal WinGetCLICommandResult RunCommand(PowerShellCmdlet pwshCmdlet, WinGetCLICommandBuilder builder, int timeOut = 60000)\r\n        {\r\n            var args = builder.ToString();\r\n            pwshCmdlet.Write(StreamType.Verbose, $\"Running {this.wingetPath} with {args}\");\r\n\r\n            Process p = new ()\r\n            {\r\n                StartInfo = new (this.wingetPath, args)\r\n                {\r\n                    UseShellExecute = false,\r\n                    RedirectStandardOutput = true,\r\n                    RedirectStandardError = true,\r\n                },\r\n            };\r\n\r\n            p.Start();\r\n\r\n            if (p.WaitForExit(timeOut))\r\n            {\r\n                return new WinGetCLICommandResult(\r\n                    builder.Command,\r\n                    builder.Parameters,\r\n                    p.ExitCode,\r\n                    p.StandardOutput.ReadToEnd(),\r\n                    p.StandardError.ReadToEnd());\r\n            }\r\n\r\n            throw new WinGetCLITimeoutException(builder.Command, builder.Parameters);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Helpers/WingetDependencies.cs",
    "content": "// -----------------------------------------------------------------------------\n// <copyright file=\"WingetDependencies.cs\" company=\"Microsoft Corporation\">\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\n// </copyright>\n// -----------------------------------------------------------------------------\nnamespace Microsoft.WinGet.Client.Engine.Helpers\n{\n    using System.Collections.Generic;\n\n    /// <summary>\n    /// An object representation of the dependencies json.\n    /// </summary>\n    internal class WingetDependencies\n    {\n        /// <summary>\n        /// Gets or sets a list of required package dependencies.\n        /// </summary>\n        public List<PackageDependency> Dependencies { get; set; } = new List<PackageDependency>();\n    }\n}\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Microsoft.WinGet.Client.Engine.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <!-- If these target frameworks are updated, make sure to also update the .psd1 and .nuspec files.-->\r\n    <!-- Keep in sync with attributes in AssemblyInfo.cs -->\r\n    <TargetWindowsVersion>10.0.26100.0</TargetWindowsVersion>\r\n    <CoreFramework>net8.0-windows$(TargetWindowsVersion)</CoreFramework>\r\n    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>\r\n    <DesktopFramework>net48</DesktopFramework>\r\n    <Configurations>Debug;Release;ReleaseStatic</Configurations>\r\n    <CsWinRTCcwLookupTableGeneratorEnabled>false</CsWinRTCcwLookupTableGeneratorEnabled>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup>\r\n    <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>\r\n    <BuildOutputDirectory>$(SolutionDir)$(Platform)\\$(Configuration)\\</BuildOutputDirectory>\r\n    <OutputPath>$(BuildOutputDirectory)$(MSBuildProjectName)</OutputPath>\r\n    <TargetFrameworks>$(CoreFramework);$(DesktopFramework)</TargetFrameworks>\r\n    <DocumentationFile>$(OutputPath)\\Microsoft.WinGet.Client.Engine.xml</DocumentationFile>\r\n    <SupportedOSPlatformVersion>10.0.18362.0</SupportedOSPlatformVersion>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <AdditionalFiles Include=\"..\\..\\stylecop.json\" Link=\"stylecop.json\" />\r\n  </ItemGroup>\r\n\r\n  <PropertyGroup>\r\n    <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <Compile Include=\"..\\CommonFiles\\PowerShellCmdlet.cs\" Link=\"PowerShellCmdlet.cs\" />\r\n    <Compile Include=\"..\\CommonFiles\\StreamType.cs\" Link=\"StreamType.cs\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <PackageReference Include=\"Octokit\" />\r\n    <PackageReference Include=\"PowerShellStandard.Library\" PrivateAssets=\"all\" />\r\n    <PackageReference Include=\"Semver\" />\r\n    <PackageReference Include=\"StyleCop.Analyzers\">\r\n      <PrivateAssets>all</PrivateAssets>\r\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\r\n    </PackageReference>\r\n    <PackageReference Include=\"System.Security.Principal.Windows\" />\r\n    <PackageReference Include=\"Newtonsoft.Json\" />\r\n    <PackageReference Include=\"Microsoft.CSharp\" Condition=\"'$(TargetFramework)' == '$(DesktopFramework)'\" />\r\n    <PackageReference Include=\"Microsoft.Windows.CsWinRT\" Condition=\"'$(TargetFramework)' == '$(CoreFramework)'\" />\r\n    <PackageReference Include=\"Microsoft.Windows.SDK.Contracts\" PrivateAssets=\"all\" Condition=\"'$(TargetFramework)' == '$(DesktopFramework)'\" />\r\n    <PackageReference Include=\"System.Net.Http\" Condition=\"'$(TargetFramework)' == '$(DesktopFramework)'\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\..\\Microsoft.Management.Deployment\\Microsoft.Management.Deployment.vcxproj\">\r\n      <OutputItemType>Content</OutputItemType>\r\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\r\n    </ProjectReference>\r\n    <ProjectReference Include=\"..\\..\\Xlang\\UndockedRegFreeWinRT\\src\\UndockedRegFreeWinRT\\UndockedRegFreeWinRT\\UndockedRegFreeWinRT.vcxproj\">\r\n      <OutputItemType>Content</OutputItemType>\r\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\r\n    </ProjectReference>\r\n    <ProjectReference Include=\"..\\..\\Microsoft.Management.Deployment.InProc\\Microsoft.Management.Deployment.InProc.vcxproj\">\r\n      <OutputItemType>Content</OutputItemType>\r\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\r\n    </ProjectReference>\r\n    <ProjectReference Include=\"..\\..\\WindowsPackageManager\\WindowsPackageManager.vcxproj\">\r\n      <OutputItemType>Content</OutputItemType>\r\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\r\n    </ProjectReference>\r\n    <ProjectReference Include=\"..\\Microsoft.WinGet.SharedLib\\Microsoft.WinGet.SharedLib.csproj\" />\r\n  </ItemGroup>\r\n\r\n  <PropertyGroup>\r\n    <!-- Disable warning for CS1591 because auto generated Microsoft.Management.Deployment -->\r\n    <!-- For our code, we still have stylecops acting on it. -->\r\n    <NoWarn>1591</NoWarn>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='Release'\">\r\n    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)'=='ReleaseStatic'\">\r\n    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(TargetFramework)' == '$(CoreFramework)'\">\r\n    <RuntimeIdentifier>win</RuntimeIdentifier>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(TargetFramework)' == '$(DesktopFramework)'\">\r\n    <LangVersion>10</LangVersion>\r\n    <DefineConstants>$(DefineConstants);POWERSHELL_WINDOWS</DefineConstants>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <Compile Update=\"Properties\\Resources.Designer.cs\">\r\n      <DesignTime>True</DesignTime>\r\n      <AutoGen>True</AutoGen>\r\n      <DependentUpon>Resources.resx</DependentUpon>\r\n    </Compile>\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <EmbeddedResource Update=\"Properties\\Resources.resx\">\r\n      <Generator>ResXFileCodeGenerator</Generator>\r\n      <LastGenOutput>Resources.Designer.cs</LastGenOutput>\r\n      <CustomToolNamespace>Microsoft.WinGet.Resources</CustomToolNamespace>\r\n    </EmbeddedResource>\r\n  </ItemGroup>\r\n\r\n  <Import Project=\"..\\..\\targets\\EmbeddedCsWinRT.targets\" Condition=\"'$(TargetFramework)' == '$(CoreFramework)'\" />\r\n\r\n  <PropertyGroup Condition=\"'$(TargetFramework)' == '$(CoreFramework)'\">\r\n    <CsWinRTIncludes>\r\n      Microsoft.Management.Deployment;\r\n      Windows.Data.Text.TextSegmen;\r\n      Windows.Devices.Geolocation;\r\n      Windows.Foundation;\r\n      Windows.Globalization.DayOfWee;\r\n      Windows.Networking.Connectivity;\r\n      Windows.Networking.DomainNameTyp;\r\n      Windows.Networking.EndpointPai;\r\n      Windows.Networking.IEndpointPai;\r\n      Windows.Networking.HostNam;\r\n      Windows.Networking.IHostNam;\r\n      Windows.Security.Cryptography.Certificates;\r\n      Windows.Storage;\r\n      Windows.Storage.Provider.FileUpdateStatu;\r\n      Windows.System.ProcessorArchitectur;\r\n      Windows.System.Use;\r\n      Windows.System.IUse;\r\n    </CsWinRTIncludes>\r\n    <CsWinRTExcludes>\r\n      Windows.Foundation.PropertyType;\r\n      Windows.Storage.Provider;\r\n    </CsWinRTExcludes>\r\n    <CsWinRTWindowsMetadata>$(TargetWindowsVersion)</CsWinRTWindowsMetadata>\r\n    <!-- Ensure Support for Windows 10, Version 1809 -->\r\n    <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSCatalogPackage.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"PSCatalogPackage.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.PSObjects\r\n{\r\n    using System.Linq;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.WinGet.Client.Engine.Exceptions;\r\n    using Microsoft.WinGet.Client.Engine.Extensions;\r\n\r\n    /// <summary>\r\n    /// CatalogPackage wrapper object for displaying to PowerShell.\r\n    /// </summary>\r\n    public abstract class PSCatalogPackage\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"PSCatalogPackage\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"catalogPackage\">CatalogPackage COM object.</param>\r\n        internal PSCatalogPackage(Management.Deployment.CatalogPackage catalogPackage)\r\n        {\r\n            this.CatalogPackageCOM = catalogPackage;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the name of the catalog package.\r\n        /// </summary>\r\n        public string Name\r\n        {\r\n            get\r\n            {\r\n                return this.CatalogPackageCOM.Name;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the id of the catalog package.\r\n        /// </summary>\r\n        public string Id\r\n        {\r\n            get\r\n            {\r\n                return this.CatalogPackageCOM.Id;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets a value indicating whether an update is available.\r\n        /// </summary>\r\n        public bool IsUpdateAvailable\r\n        {\r\n            get\r\n            {\r\n                return this.CatalogPackageCOM.IsUpdateAvailable;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the source name of the catalog package.\r\n        /// </summary>\r\n        public string? Source\r\n        {\r\n            get\r\n            {\r\n                return this.CatalogPackageCOM.GetSourceName();\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets list of strings representing the available versions.\r\n        /// </summary>\r\n        public string[] AvailableVersions\r\n        {\r\n            get\r\n            {\r\n                return this.AvailablePackageVersionIds.Select(i => i.Version).ToArray();\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the catalog package COM object.\r\n        /// </summary>\r\n        internal CatalogPackage CatalogPackageCOM { get; private set; }\r\n\r\n        /// <summary>\r\n        /// Gets a list of available package version ids for the package.\r\n        /// </summary>\r\n        private PackageVersionId[] AvailablePackageVersionIds\r\n        {\r\n            get\r\n            {\r\n                return this.CatalogPackageCOM.AvailableVersions.ToArray();\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Checks the installed status of the catalog package.\r\n        /// </summary>\r\n        /// <returns>CheckInstalledStatus string.</returns>\r\n        public string CheckInstalledStatus()\r\n        {\r\n            return this.CatalogPackageCOM.CheckInstalledStatus().Status.ToString();\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the PackageVersionInfo PSObject that corresponds with the version string.\r\n        /// </summary>\r\n        /// <param name=\"version\">Version string.</param>\r\n        /// <returns>PackageVersionInfo PSObject.</returns>\r\n        /// <exception cref=\"NoPackageFoundException\">Throws an exception if no package is found.</exception>\r\n        public PSPackageVersionInfo GetPackageVersionInfo(string version)\r\n        {\r\n            // get specific version that matches\r\n            PackageVersionId? packageVersionId = this.AvailablePackageVersionIds.FirstOrDefault(x => x.Version == version);\r\n            if (packageVersionId != null)\r\n            {\r\n                return new PSPackageVersionInfo(this.CatalogPackageCOM.GetPackageVersionInfo(packageVersionId));\r\n            }\r\n            else\r\n            {\r\n                throw new NoPackageFoundException();\r\n            }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSCompareResult.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"PSCompareResult.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.PSObjects\r\n{\r\n    /// <summary>\r\n    /// Must match Microsoft.Management.Deployment.CompareResult.\r\n    /// </summary>\r\n    public enum PSCompareResult\r\n    {\r\n        /// <summary>\r\n        /// Unknown,\r\n        /// </summary>\r\n        Unknown,\r\n\r\n        /// <summary>\r\n        /// Lesser.\r\n        /// </summary>\r\n        Lesser,\r\n\r\n        /// <summary>\r\n        /// Equal,\r\n        /// </summary>\r\n        Equal,\r\n\r\n        /// <summary>\r\n        /// Greater,\r\n        /// </summary>\r\n        Greater,\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSDownloadResult.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"PSDownloadResult.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.PSObjects\r\n{\r\n    using System;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.WinGet.Client.Engine.Extensions;\r\n\r\n    /// <summary>\r\n    /// PSDownloadResult.\r\n    /// </summary>\r\n    public sealed class PSDownloadResult\r\n    {\r\n        private readonly DownloadResult downloadResult;\r\n        private readonly CatalogPackage catalogPackage;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"PSDownloadResult\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"downloadResult\">The download result COM object.</param>\r\n        /// <param name=\"catalogPackage\">The catalog package COM object.</param>\r\n        internal PSDownloadResult(DownloadResult downloadResult, CatalogPackage catalogPackage)\r\n        {\r\n            this.downloadResult = downloadResult;\r\n            this.catalogPackage = catalogPackage;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the id of the downloaded package.\r\n        /// </summary>\r\n        public string Id\r\n        {\r\n            get\r\n            {\r\n                return this.catalogPackage.Id;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the name of the downloaded package.\r\n        /// </summary>\r\n        public string Name\r\n        {\r\n            get\r\n            {\r\n                return this.catalogPackage.Name;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the source name of the downloaded package.\r\n        /// </summary>\r\n        public string? Source\r\n        {\r\n            get\r\n            {\r\n                return this.catalogPackage.GetSourceName();\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the correlation data of the downloaded result.\r\n        /// </summary>\r\n        public string CorrelationData\r\n        {\r\n            get\r\n            {\r\n                return this.downloadResult.CorrelationData;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the extended error code exception of the failed download result.\r\n        /// </summary>\r\n        public Exception ExtendedErrorCode\r\n        {\r\n            get\r\n            {\r\n                return this.downloadResult.ExtendedErrorCode;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the status of the download.\r\n        /// </summary>\r\n        public string Status\r\n        {\r\n            get\r\n            {\r\n                return this.downloadResult.Status.ToString();\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// If the download succeeded.\r\n        /// </summary>\r\n        /// <returns>True if installation succeeded.</returns>\r\n        public bool Succeeded()\r\n        {\r\n            return this.downloadResult.Status == DownloadResultStatus.Ok;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Message with error information.\r\n        /// </summary>\r\n        /// <returns>Error message.</returns>\r\n        public string ErrorMessage()\r\n        {\r\n            return $\"DownloadStatus '{this.Status}' ExtendedError '{this.ExtendedErrorCode.HResult}'\";\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSFoundCatalogPackage.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"PSFoundCatalogPackage.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.PSObjects\r\n{\r\n    using Microsoft.Management.Deployment;\r\n\r\n    /// <summary>\r\n    /// FoundCatalogPackage wrapper object for displaying to PowerShell.\r\n    /// </summary>\r\n    public sealed class PSFoundCatalogPackage : PSCatalogPackage\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"PSFoundCatalogPackage\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"catalogPackage\">The catalog package COM object.</param>\r\n        internal PSFoundCatalogPackage(CatalogPackage catalogPackage)\r\n            : base(catalogPackage)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the default install version of the catalog package.\r\n        /// </summary>\r\n        public string? Version\r\n        {\r\n            get { return this.CatalogPackageCOM.DefaultInstallVersion?.Version; }\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSInstalledCatalogPackage.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"PSInstalledCatalogPackage.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.PSObjects\r\n{\r\n    using System;\r\n    using Microsoft.Management.Deployment;\r\n\r\n    /// <summary>\r\n    /// InstalledCatalogPackage wrapper object for displaying to PowerShell.\r\n    /// </summary>\r\n    public sealed class PSInstalledCatalogPackage : PSCatalogPackage\r\n    {\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"PSInstalledCatalogPackage\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"catalogPackage\">The catalog package COM object.</param>\r\n        internal PSInstalledCatalogPackage(CatalogPackage catalogPackage)\r\n            : base(catalogPackage)\r\n        {\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the installed version of the catalog package.\r\n        /// </summary>\r\n        public string InstalledVersion\r\n        {\r\n            get { return this.CatalogPackageCOM.InstalledVersion.Version; }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Compares versions.\r\n        /// </summary>\r\n        /// <param name=\"version\">Version.</param>\r\n        /// <returns>PSCompareResult.</returns>\r\n        public PSCompareResult CompareToVersion(string version)\r\n        {\r\n            return this.CatalogPackageCOM.InstalledVersion.CompareToVersion(version) switch\r\n            {\r\n                CompareResult.Unknown => PSCompareResult.Unknown,\r\n                CompareResult.Lesser => PSCompareResult.Lesser,\r\n                CompareResult.Equal => PSCompareResult.Equal,\r\n                CompareResult.Greater => PSCompareResult.Greater,\r\n                _ => throw new InvalidOperationException(),\r\n            };\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSPackageVersionInfo.cs",
    "content": "﻿// -----------------------------------------------------------------------------\r\n// <copyright file=\"PSPackageVersionInfo.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.PSObjects\r\n{\r\n    using System.Linq;\r\n    using Microsoft.Management.Deployment;\r\n\r\n    /// <summary>\r\n    /// PackageVersionInfo wrapper object for displaying to PowerShell.\r\n    /// </summary>\r\n    public sealed class PSPackageVersionInfo\r\n    {\r\n        private PackageVersionInfo packageVersionInfo;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"PSPackageVersionInfo\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"packageVersionInfo\">PackageVersionInfo COM object.</param>\r\n        internal PSPackageVersionInfo(PackageVersionInfo packageVersionInfo)\r\n        {\r\n            this.packageVersionInfo = packageVersionInfo;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the name of the package version info.\r\n        /// </summary>\r\n        public string DisplayName\r\n        {\r\n            get\r\n            {\r\n                return this.packageVersionInfo.DisplayName;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the id of the package version info.\r\n        /// </summary>\r\n        public string Id\r\n        {\r\n            get\r\n            {\r\n                return this.packageVersionInfo.Id;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the publisher of the package version info.\r\n        /// </summary>\r\n        public string Publisher\r\n        {\r\n            get\r\n            {\r\n                return this.packageVersionInfo.Publisher;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the channel of the package version info.\r\n        /// </summary>\r\n        public string Channel\r\n        {\r\n            get\r\n            {\r\n                return this.packageVersionInfo.Channel;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the list of package family names of the package version info.\r\n        /// </summary>\r\n        public string[] PackageFamilyNames\r\n        {\r\n            get\r\n            {\r\n                return this.packageVersionInfo.PackageFamilyNames.ToArray();\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the list of product codes of the package version info.\r\n        /// </summary>\r\n        public string[] ProductCodes\r\n        {\r\n            get\r\n            {\r\n                return this.packageVersionInfo.ProductCodes.ToArray();\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Compares the version string with the package version info and returns the CompareResult.\r\n        /// </summary>\r\n        /// <param name=\"version\">Version string.</param>\r\n        /// <returns>CompareResult string.</returns>\r\n        public string CompareToVersion(string version)\r\n        {\r\n            return this.packageVersionInfo.CompareToVersion(version).ToString();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/PSObjects/PSUninstallResult.cs",
    "content": "// -----------------------------------------------------------------------------\r\n// <copyright file=\"PSUninstallResult.cs\" company=\"Microsoft Corporation\">\r\n//     Copyright (c) Microsoft Corporation. Licensed under the MIT License.\r\n// </copyright>\r\n// -----------------------------------------------------------------------------\r\n\r\nnamespace Microsoft.WinGet.Client.Engine.PSObjects\r\n{\r\n    using System;\r\n    using Microsoft.Management.Deployment;\r\n    using Microsoft.WinGet.Client.Engine.Extensions;\r\n\r\n    /// <summary>\r\n    /// UninstallResult wrapper object for displaying to PowerShell.\r\n    /// </summary>\r\n    public sealed class PSUninstallResult\r\n    {\r\n        private readonly UninstallResult uninstallResult;\r\n        private readonly CatalogPackage catalogPackage;\r\n\r\n        /// <summary>\r\n        /// Initializes a new instance of the <see cref=\"PSUninstallResult\"/> class.\r\n        /// </summary>\r\n        /// <param name=\"uninstallResult\">The uninstall result COM object.</param>\r\n        /// <param name=\"catalogPackage\">The catalog package COM object.</param>\r\n        internal PSUninstallResult(UninstallResult uninstallResult, CatalogPackage catalogPackage)\r\n        {\r\n            this.uninstallResult = uninstallResult;\r\n            this.catalogPackage = catalogPackage;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the id of the uninstalled package.\r\n        /// </summary>\r\n        public string Id\r\n        {\r\n            get\r\n            {\r\n                return this.catalogPackage.Id;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the name of the uninstalled package.\r\n        /// </summary>\r\n        public string Name\r\n        {\r\n            get\r\n            {\r\n                return this.catalogPackage.Name;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the source name of the uninstalled package.\r\n        /// </summary>\r\n        public string? Source\r\n        {\r\n            get\r\n            {\r\n                return this.catalogPackage.GetSourceName();\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the correlation data of the uninstall result.\r\n        /// </summary>\r\n        public string CorrelationData\r\n        {\r\n            get\r\n            {\r\n                return this.uninstallResult.CorrelationData;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the extended error code exception of the failed uninstall result.\r\n        /// </summary>\r\n        public Exception ExtendedErrorCode\r\n        {\r\n            get\r\n            {\r\n                return this.uninstallResult.ExtendedErrorCode;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets a value indicating whether a reboot is required.\r\n        /// </summary>\r\n        public bool RebootRequired\r\n        {\r\n            get\r\n            {\r\n                return this.uninstallResult.RebootRequired;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the status of the uninstall.\r\n        /// </summary>\r\n        public string Status\r\n        {\r\n            get\r\n            {\r\n                return this.uninstallResult.Status.ToString();\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// Gets the error code of an uninstall.\r\n        /// </summary>\r\n        public uint UninstallerErrorCode\r\n        {\r\n            get\r\n            {\r\n                return this.uninstallResult.UninstallerErrorCode;\r\n            }\r\n        }\r\n\r\n        /// <summary>\r\n        /// If the uninstall succeeded.\r\n        /// </summary>\r\n        /// <returns>True if uninstall succeeded.</returns>\r\n        public bool Succeeded()\r\n        {\r\n            return this.uninstallResult.Status == UninstallResultStatus.Ok;\r\n        }\r\n\r\n        /// <summary>\r\n        /// Message with error information.\r\n        /// </summary>\r\n        /// <returns>Error message.</returns>\r\n        public string ErrorMessage()\r\n        {\r\n            return $\"UninstallStatus '{this.Status}' UninstallerErrorCode '{this.UninstallerErrorCode}' ExtendedError '{this.ExtendedErrorCode.HResult}'\";\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Client.Engine/Properties/Resources.resx",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<root>\r\n  <!-- \r\n    Microsoft ResX Schema \r\n    \r\n    Version 2.0\r\n    \r\n    The primary goals of this format is to allow a simple XML format \r\n    that is mostly human readable. The generation and parsing of the \r\n    various data types are done through the TypeConverter classes \r\n    associated with the data types.\r\n    \r\n    Example:\r\n    \r\n    ... ado.net/XML headers & schema ...\r\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\r\n    <resheader name=\"version\">2.0</resheader>\r\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\r\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\r\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\r\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\r\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\r\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\r\n    </data>\r\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\r\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\r\n        <comment>This is a comment</comment>\r\n    </data>\r\n                \r\n    There are any number of \"resheader\" rows that contain simple \r\n    name/value pairs.\r\n    \r\n    Each data row contains a name, and value. The row also contains a \r\n    type or mimetype. Type corresponds to a .NET class that support \r\n    text/value conversion through the TypeConverter architecture. \r\n    Classes that don't support this are serialized and stored with the \r\n    mimetype set.\r\n    \r\n    The mimetype is used for serialized objects, and tells the \r\n    ResXResourceReader how to depersist the object. This is currently not \r\n    extensible. For a given mimetype the value must be set accordingly:\r\n    \r\n    Note - application/x-microsoft.net.object.binary.base64 is the format \r\n    that the ResXResourceWriter will generate, however the reader can \r\n    read any of the formats listed below.\r\n    \r\n    mimetype: application/x-microsoft.net.object.binary.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\r\n            : and then encoded with base64 encoding.\r\n    \r\n    mimetype: application/x-microsoft.net.object.soap.base64\r\n    value   : The object must be serialized with \r\n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\r\n            : and then encoded with base64 encoding.\r\n\r\n    mimetype: application/x-microsoft.net.object.bytearray.base64\r\n    value   : The object must be serialized into a byte array \r\n            : using a System.ComponentModel.TypeConverter\r\n            : and then encoded with base64 encoding.\r\n    -->\r\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\r\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\r\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\r\n      <xsd:complexType>\r\n        <xsd:choice maxOccurs=\"unbounded\">\r\n          <xsd:element name=\"metadata\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"assembly\">\r\n            <xsd:complexType>\r\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"data\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\r\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\r\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\r\n              <xsd:attribute ref=\"xml:space\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n          <xsd:element name=\"resheader\">\r\n            <xsd:complexType>\r\n              <xsd:sequence>\r\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\r\n              </xsd:sequence>\r\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\r\n            </xsd:complexType>\r\n          </xsd:element>\r\n        </xsd:choice>\r\n      </xsd:complexType>\r\n    </xsd:element>\r\n  </xsd:schema>\r\n  <resheader name=\"resmimetype\">\r\n    <value>text/microsoft-resx</value>\r\n  </resheader>\r\n  <resheader name=\"version\">\r\n    <value>2.0</value>\r\n  </resheader>\r\n  <resheader name=\"reader\">\r\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n  <resheader name=\"writer\">\r\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r\n  </resheader>\r\n  <data name=\"InvalidSourceExceptionMessage\" xml:space=\"preserve\">\r\n    <value>No source matches the given value: {0}</value>\r\n    <comment>{Locked=\"{0}\"} {0} - The name of the source that was not found.</comment>\r\n  </data>\r\n  <data name=\"FindPackagesExceptionMessage\" xml:space=\"preserve\">\r\n    <value>An error occurred while searching for packages: {0}</value>\r\n    <comment>{Locked=\"{0}\"} {0} - A string representation of the error status returned by the catalog.</comment>\r\n  </data>\r\n  <data name=\"ProgressRecordActivityInstalling\" xml:space=\"preserve\">\r\n    <value>Installing '{0}'</value>\r\n    <comment>{Locked=\"{0}\"} {0} - The name of the package being installed.</comment>\r\n  </data>\r\n  <data name=\"ProgressRecordActivityUninstalling\" xml:space=\"preserve\">\r\n    <value>Uninstalling '{0}'</value>\r\n    <comment>{Locked=\"{0}\"} {0} - The name of the package being uninstalled.</comment>\r\n  </data>\r\n  <data name=\"ProgressRecordActivityUpdating\" xml:space=\"preserve\">\r\n    <value>Updating '{0}'</value>\r\n    <comment>{Locked=\"{0}\"} {0} - The name of the package being updated.</comment>\r\n  </data>\r\n  <data name=\"CatalogConnectExceptionMessage\" xml:space=\"preserve\">\r\n    <value>An error occurred while connecting to the catalog.</value>\r\n  </data>\r\n  <data name=\"InvalidVersionExceptionMessage\" xml:space=\"preserve\">\r\n    <value>No versions matched the given value: {0}</value>\r\n    <comment>{Locked=\"{0}\"} {0} - The version string provided by the user.</comment>\r\n  </data>\r\n  <data name=\"NoPackageFoundExceptionMessage\" xml:space=\"preserve\">\r\n    <value>No packages matched the given input criteria.</value>\r\n  </data>\r\n  <data name=\"VagueCriteriaExceptionMessage\" xml:space=\"preserve\">\r\n    <value>{0}, {1}, and {2} other packages matched the input criteria. Please refine the input.</value>\r\n    <comment>{Locked=\"{0}\",\"{1}\",\"{2}\"} {0} - The first conflicting package as a string. {1} - The second conflicting package. {2} - The number of other packages that also matched the input criteria.</comment>\r\n  </data>\r\n  <data name=\"IntegrityUnknownMessage\" xml:space=\"preserve\">\r\n    <value>Unable to execute winget command.</value>\r\n  </data>\r\n  <data name=\"WinGetCLIExceptionMessage\" xml:space=\"preserve\">\r\n    <value>Winget command '{0}' with parameters '{1}' failed with exit code '{2}'.</value>\r\n    <comment>{Locked=\"{0}\",\"{1}\",\"{2}\"} {0} - The winget command executed. {1} - The parameters of the command. {2} - The exit code.</comment>\r\n  </data>\r\n  <data name=\"UserSettingsReadException\" xml:space=\"preserve\">\r\n    <value>User settings file is invalid.</value>\r\n  </data>\r\n  <data name=\"IntegrityAppExecutionAliasDisabledMessage\" xml:space=\"preserve\">\r\n    <value>The App Execution Alias for the Windows Package Manager is disabled.</value>\r\n  </data>\r\n  <data name=\"IntegrityAppInstallerNotInstalledMessage\" xml:space=\"preserve\">\r\n    <value>The App Installer is not installed.</value>\r\n  </data>\r\n  <data name=\"IntegrityAppInstallerNotSupportedMessage\" xml:space=\"preserve\">\r\n    <value>The App Installer does not contain the Windows Package Manager.</value>\r\n  </data>\r\n  <data name=\"IntegrityFailureMessage\" xml:space=\"preserve\">\r\n    <value>Windows Package Manager returned an unexcepted result.</value>\r\n  </data>\r\n  <data name=\"IntegrityNotInPathMessage\" xml:space=\"preserve\">\r\n    <value>The App Installer did not automatically add the PATH environment variable.</value>\r\n  </data>\r\n  <data name=\"IntegrityOsNotSupportedMessage\" xml:space=\"preserve\">\r\n    <value>The Windows Package Manager requires Windows Version 1809 (October 2018 Update) or later.</value>\r\n  </data>\r\n  <data name=\"WinGetCLITimeoutExceptionMessage\" xml:space=\"preserve\">\r\n    <value>Winget command timed out: {0} {1}</value>\r\n    <comment>{Locked=\"{0}\",\"{1}\"} {0} - The winget command executed. {1} - The parameters of the command.</comment>\r\n  </data>\r\n  <data name=\"IntegrityAppInstallerNotRegisteredMessage\" xml:space=\"preserve\">\r\n    <value>The App Installer is not registered.</value>\r\n  </data>\r\n  <data name=\"RepairAppExecutionAliasMessage\" xml:space=\"preserve\">\r\n    <value>The App Execution Alias for the Windows Package Manager is disabled. You should enable the App Execution Alias for the Windows Package Manager. Go to App execution aliases option in Apps &amp; features Settings to enable it.</value>\r\n  </data>\r\n  <data name=\"IntegrityUnexpectedVersionMessage\" xml:space=\"preserve\">\r\n    <value>The installed winget version doesn't match the expectation. Installer version '{0}' Expected version '{1}'</value>\r\n    <comment>{Locked=\"{0}\",\"{1}\"} {0} - The winget current installed winget version. {1} - The expected winget version.</comment>\r\n  </data>\r\n  <data name=\"SingleThreadedApartmentNotSupportedMessage\" xml:space=\"preserve\">\r\n    <value>Single threaded apartment (STA) is not currently supported in this context; run PowerShell in Multi-threaded apartment mode (MTA).</value>\r\n    <comment>{Locked=\"STA\",\"MTA\"}</comment>\r\n  </data>\r\n  <data name=\"WindowsPowerShellNotSupported\" xml:space=\"preserve\">\r\n    <value>This cmdlet is not supported in Windows PowerShell.</value>\r\n  </data>\r\n  <data name=\"IntegrityAppInstallerLicense\" xml:space=\"preserve\">\r\n    <value>No applicable license found.</value>\r\n  </data>\r\n  <data name=\"RepairAllUsersHelpMessage\" xml:space=\"preserve\">\r\n    <value>Try running with -AllUsers in administrator mode.</value>\r\n    <comment>{Locked=\"-AllUsers\"}</comment>\r\n  </data>\r\n  <data name=\"RepairAllUsersMessage\" xml:space=\"preserve\">\r\n    <value>-AllUsers requires administrator mode.</value>\r\n    <comment>{Locked=\"-AllUsers\"}</comment>\r\n  </data>\r\n  <data name=\"RepairFailureMessage\" xml:space=\"preserve\">\r\n    <value>Failed to repair winget.</value>\r\n  </data>\r\n  <data name=\"RequiresAdminMessage\" xml:space=\"preserve\">\r\n    <value>This cmdlet requires administrator privileges to execute.</value>\r\n  </data>\r\n  <data name=\"DebugNotSupported\" xml:space=\"preserve\">\r\n    <value>Debug parameter not supported</value>\r\n  </data>\r\n  <data name=\"DownloadingMessage\" xml:space=\"preserve\">\r\n    <value>Downloading</value>\r\n  </data>\r\n  <data name=\"Completed\" xml:space=\"preserve\">\r\n    <value>Completed</value>\r\n  </data>\r\n  <data name=\"Uninstalling\" xml:space=\"preserve\">\r\n    <value>Uninstalling</value>\r\n  </data>\r\n  <data name=\"ReleaseAssetNotFound\" xml:space=\"preserve\">\r\n    <value>Cannot find asset {0}</value>\r\n    <comment>{Locked=\"{0}\"} {0} - The asset name</comment>\r\n  </data>\r\n  <data name=\"ProgressRecordActivityExporting\" xml:space=\"preserve\">\r\n    <value>Exporting '{0}'</value>\r\n    <comment>{Locked=\"{0}\"} {0} - The name of the package being exported.</comment>\r\n  </data>\r\n  <data name=\"ProgressRecordActivityRepairing\" xml:space=\"preserve\">\r\n    <value>Repairing '{0}'</value>\r\n    <comment>{Locked=\"{0}\"} {0} - The name of the package being repaired.</comment>\r\n  </data>\r\n  <data name=\"Repairing\" xml:space=\"preserve\">\r\n    <value>Repairing</value>\r\n  </data>\r\n  <data name=\"NoRepairInfoFound\" xml:space=\"preserve\">\r\n    <value>The repair command for this package is not available in the Package Manifest. Please reach out to the package publisher for assistance.</value>\r\n  </data>\r\n  <data name=\"RepairDifferentInstallTechnology\" xml:space=\"preserve\">\r\n    <value>The installer technology in use does not match the version currently installed.</value>\r\n  </data>\r\n  <data name=\"RepairerFailure\" xml:space=\"preserve\">\r\n    <value>The repair operation was unsuccessful, exiting with Repairer error code: {0}.</value>\r\n     <comment>{Locked=\"{0}\"} {0} - The error code of the repairer.</comment>\r\n  </data>\r\n  <data name=\"RepairOperationNotSupported\" xml:space=\"preserve\">\r\n    <value>The current installer technology does not support repair. Please reach out to the package vendor for assistance.</value>\r\n  </data>\r\n  <data name=\"NoAdminRepairForUserScopePackage\" xml:space=\"preserve\">\r\n    <value>Repair operations involving administrator privileges are not permitted on packages installed within the user scope.</value>\r\n  </data>\r\n  <data name=\"UnknownRepairFailure\" xml:space=\"preserve\">\r\n    <value>An unexpected error happened while trying to repair the package. Error code:{0}</value>\r\n    <comment>{Locked=\"{0}\"} {0} - The error code from the repair operation.</comment>\r\n  </data>\r\n</root>\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Configuration/Examples/Sample_StartConfiguration.ps1",
    "content": "<#\r\n    .SYNOPSIS\r\n        Performs a WinGet Configuration asynchronously.\r\n        Use Start-WinGetConfiguration to perform a WinGet Configuration.\r\n#>\r\n\r\nparam (\r\n    [Parameter(Mandatory)]\r\n    $configFile\r\n)\r\n\r\nif (-not(Get-Module -Name Microsoft.WinGet.Configuration -ListAvailable))\r\n{\r\n    Install-Module Microsoft.WinGet.Configuration -AllowPrerelease\r\n}\r\n\r\nImport-Module Microsoft.WinGet.Configuration\r\n\r\n# Starts the configuration in the background\r\n$configJob = Get-WinGetConfiguration -File $configFile | Start-WinGetConfiguration\r\n\r\n# This will block until the configuration is completed. Or print the results if already done.\r\nComplete-WinGetConfiguration -ConfigurationJob $configJob\r\n"
  },
  {
    "path": "src/PowerShell/Microsoft.WinGet.Configuration/ModuleFiles/Microsoft.WinGet.Configuration.psd1",
    "content": "@{\r\n    RootModule = \"Microsoft.WinGet.Configuration.Cmdlets.dll\"\r\n    ModuleVersion = '0.0.1'\r\n    CompatiblePSEditions = 'Core'\r\n    GUID = '79b6b07b-7be5-4673-9cd1-fcbe3d79ba82'\r\n    Author = 'Microsoft Corporation'\r\n    CompanyName = 'Microsoft Corporation'\r\n    Copyright = '(c) Microsoft Corporation. All rights reserved.'\r\n    Description = 'PowerShell Module for the Windows Package Manager Configuration.'\r\n    PowerShellVersion = '7.4.6'\r\n\r\n    FunctionsToExport = @()\r\n    AliasesToExport      = @('cmpwgc', 'cnwgc', 'ctwgcy', 'gwgc', 'gwgcd', 'iwgc', 'rwgch', 'sawgc', 'spwgc','twgc')\r\n\r\n    CmdletsToExport = @(\r\n        \"Complete-WinGetConfiguration\"\r\n        \"Get-WinGetConfiguration\"\r\n        \"Get-WinGetConfigurationDetails\"\r\n        \"Invoke-WinGetConfiguration\"\r\n        \"Start-WinGetConfiguration\"\r\n        \"Test-WinGetConfiguration\"\r\n        \"Confirm-WinGetConfiguration\"\r\n        \"Stop-WinGetConfiguration\"\r\n        \"Remove-WinGetConfigurationHistory\"\r\n        \"ConvertTo-WinGetConfigurationYaml\"\r\n    )\r\n\r\n    PrivateData = @{\r\n        PSData = @{\r\n            Tags = @(\r\n                'WindowsPackageManager',\r\n                'WinGet'\r\n            )\r\n            ProjectUri = 'https://github.com/microsoft/winget-cli'\r\n            IconUri = 'https://aka.ms/winget-icon'\r\n            Prerelease = 'alpha'\r\n        }\r\n    }\r\n}\r\n\r\n"
  }
]